commit be2fc52601c082c27ecb1206a524bf1e7a34ccee Author: fly2x Date: Tue Oct 15 10:02:41 2024 +0800 openhitls repo init diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..cd0ce12d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.vscode +build +__pycache__ +*/build/* +testcode/framework/tls/lib/ +testcode/output/ +platform/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..19ce6a28 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "platform/Secure_C"] + path = platform/Secure_C + url = https://gitee.com/openeuler/libboundscheck.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..efe2747d --- /dev/null +++ b/CMakeLists.txt @@ -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) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..6469ee29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,125 @@ + 木兰宽松许可证, 第2版 + +木兰宽松许可证, 第2版 +2020年1月 http://license.coscl.org.cn/MulanPSL2 + +您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: + +0. 定义 + +“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 + +“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 + +“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 + +“法人实体” 是指提交贡献的机构及其“关联实体”。 + +“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 + +1. 授予版权许可 + +每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 + +2. 授予专利许可 + +每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 + +3. 无商标许可 + +“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 + +4. 分发限制 + +您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 + +5. 免责声明与责任限制 + +“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 + +6. 语言 + +“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 + +条款结束 + +如何将木兰宽松许可证,第2版,应用到您的软件 + +如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: + +1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; + +2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; + +3, 请将如下声明文本放入每个源文件的头部注释中。 + +Copyright (c) [Year] [name of copyright holder] +[Software Name] is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +Mulan Permissive Software License,Version 2 +Mulan Permissive Software License,Version 2 (Mulan PSL v2) + +January 2020 http://license.coscl.org.cn/MulanPSL2 + +Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: + +0. Definition + +Software means the program and related documents which are licensed under this License and comprise all Contribution(s). + +Contribution means the copyrightable work licensed by a particular Contributor under this License. + +Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. + +Legal Entity means the entity making a Contribution and all its Affiliates. + +Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. + +1. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. + +2. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. + +3. No Trademark License + +No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4. + +4. Distribution Restriction + +You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. + +5. Disclaimer of Warranty and Limitation of Liability + +THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +6. Language + +THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. + +END OF THE TERMS AND CONDITIONS + +How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software + +To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: + +Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; +Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package; +Attach the statement to the appropriate annotated syntax at the beginning of each source file. +Copyright (c) [Year] [name of copyright holder] +[Software Name] is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 00000000..95df60ac --- /dev/null +++ b/README-zh.md @@ -0,0 +1,100 @@ +[English](./README.md) | 简体中文 + +# openHiTLS +欢迎访问openHiTLS代码仓,该代码仓的项目官网是openHiTLS社区,openHiTLS的目标是提供高效、敏捷的全场景开源密码学开发套件。openHiTLS已支持通用的标准密码算法、(D)TLS、TLCP等安全通信协议,更多特性待规划。 + +## 概述 + +openHiTLS架构高度模块化,可通过模块和特性配置。RAM/ROM尺寸取决于所选的特性。openHiTLS为密码算法提供最佳性能优化。当前已支持4个组件和算法特性可按需配置,支持ARM、x86架构CPU上的算法性能优化,更多架构和特性待规划。 + +## 特性简介 + +1. 功能特性:TLS1.2、TLS1.3、DTLS1.2、TLCP;AES,SM4,Chacha20,RSA,DSA,ECDSA,ECDH,DH,SM2,DRBG,HKDF,SCRYPT,PBKDF2,SHA2,SHA3,MD5,SM3,HMAC;X509 +2. DFX特性:高度模块化特性按需配置的敏捷架构,ARM、x86上的算法性能优化,日志和错误堆栈功能的可维可测性 + +## 组件简介 + +目前,openHiTLS有4个组件,其中BSL组件需和其他组件一起使用。 +- BSL是Base Support Layer的缩写,提供基础C类标准的增强功能和OS适配器,需与其他模块一起使用 +- 密码算法组件(Crypto)提供了完整的密码功能,且性能较优。该组件既可以被TLS使用,也可与BSL一起使用 +- TLS是Transport Layer Security的缩写,涵盖了TLS1.3及之前的TLS版本,会与Crypto、BSL以及其他三方密码组件或PKI库一起使用 +- X509组件当前提供了能够支撑TLS协议建链的基础功能,后续逐步完善功能 + + +## 开发 + +### 依赖准备 + +openHiTLS依赖于Secure C,因此需将Secure C下载到${openHiTLS_dir}/platform/Secure_C,Secure C的一个官方Git库是 。 + +* 下载安全函数库 +```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 +``` + +### 致应用开发人员 + +正式版本的源码镜像尚未正式开放、还在规划当中。 + + +官方代码仓库托管在,您可以通过如下命令将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签署。 diff --git a/README.md b/README.md new file mode 100644 index 00000000..f998ff4a --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +[简体中文](./README-zh.md) | English + +# openHiTLS +Welcome to visit the openHiTLS Code Repository, which is under the openHiTLS community: . 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 . + +* 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 . 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. diff --git a/Third_Party_Open_Source_Software_Notice b/Third_Party_Open_Source_Software_Notice new file mode 100644 index 00000000..bb0a3a3f --- /dev/null +++ b/Third_Party_Open_Source_Software_Notice @@ -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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/bsl/asn1/include/bsl_asn1.h b/bsl/asn1/include/bsl_asn1.h new file mode 100644 index 00000000..91fb7eb1 --- /dev/null +++ b/bsl/asn1/include/bsl_asn1.h @@ -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 +#include +#include +#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 diff --git a/bsl/asn1/src/bsl_asn1.c b/bsl/asn1/src/bsl_asn1.c new file mode 100644 index 00000000..35dd8f9c --- /dev/null +++ b/bsl/asn1/src/bsl_asn1.c @@ -0,0 +1,1176 @@ +/* + * 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 +#include "securec.h" +#include "bsl_err.h" +#include "bsl_bytes.h" +#include "bsl_log_internal.h" +#include "bsl_binlog_id.h" +#include "bsl_asn1_local.h" +#include "bsl_sal.h" +#include "sal_time.h" +#include "bsl_asn1.h" + +#define BSL_ASN1_INDEFINITE_LENGTH 0x80 +#define BSL_ASN1_DEFINITE_MAX_CONTENT_OCTET_NUM 0x7F // 127 + +int32_t BSL_ASN1_DecodeLen(uint8_t **encode, uint32_t *encLen, bool completeLen, uint32_t *len) +{ + if (encode == NULL || encLen == NULL || len == NULL) { + return BSL_NULL_INPUT; + } + uint8_t *temp = *encode; + uint32_t tempLen = *encLen; + uint32_t parseLen = 0; + if (tempLen < 1) { + return BSL_ASN1_ERR_DECODE_LEN; + } + + if ((*temp & BSL_ASN1_INDEFINITE_LENGTH) == 0) { + parseLen = *temp; + temp++; + tempLen--; + parseLen += ((completeLen) ? 1 : 0); + } else { + uint32_t index = *temp - BSL_ASN1_INDEFINITE_LENGTH; + if (index > sizeof(int32_t)) { + return BSL_ASN1_ERR_MAX_LEN_NUM; + } + temp++; + tempLen--; + if (tempLen < index) { + return BSL_ASN1_ERR_BUFF_NOT_ENOUGH; + } + for (uint32_t iter = 0; iter < index; iter++) { + parseLen = (parseLen << 8) | *temp; // one byte = 8 bits + temp++; + tempLen--; + } + // anti-flip + if (parseLen >= ((((uint64_t)1 << 32) - 1) - index - 2)) { // 1<<32:U32_MAX; 2: Tag + length(0x8x) + return BSL_ASN1_ERR_MAX_LEN_NUM; + } + parseLen += ((completeLen) ? (index + 1) : 0); + } + uint32_t length = (completeLen) ? *encLen : tempLen; + /* The length supports a maximum of 4 bytes */ + if (parseLen > length) { + return BSL_ASN1_ERR_DECODE_LEN; + } + *len = parseLen; + *encode = temp; + *encLen = tempLen; + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_GetCompleteLen(uint8_t *data, uint32_t *dataLen) +{ + uint8_t *tmp = data; + uint32_t tmpLen = *dataLen; + uint32_t len = 0; + if (tmpLen < 1) { + return BSL_ASN1_ERR_BUFF_NOT_ENOUGH; + } + + tmp++; + tmpLen--; + int32_t ret = BSL_ASN1_DecodeLen(&tmp, &tmpLen, true, &len); + if (ret != BSL_SUCCESS) { + return ret; + } + *dataLen = len + 1; + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_DecodeTagLen(uint8_t tag, uint8_t **encode, uint32_t *encLen, uint32_t *valLen) +{ + if (encode == NULL || encLen == NULL || valLen == NULL) { + return BSL_NULL_INPUT; + } + uint8_t *temp = *encode; + uint32_t tempLen = *encLen; + if (tempLen < 1) { + return BSL_INVALID_ARG; + } + + if (tag != *temp) { + return BSL_ASN1_ERR_MISMATCH_TAG; + } + temp++; + tempLen--; + uint32_t len; + int32_t ret = BSL_ASN1_DecodeLen(&temp, &tempLen, false, &len); + if (ret != BSL_SUCCESS) { + return ret; + } + if (len > tempLen) { + return BSL_ASN1_ERR_BUFF_NOT_ENOUGH; + } + *valLen = len; + *encode = temp; + *encLen = tempLen; + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_DecodeItem(uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnItem) +{ + if (encode == NULL || encLen == NULL || asnItem == NULL) { + return BSL_NULL_INPUT; + } + uint8_t tag; + uint32_t len; + uint8_t *temp = *encode; + uint32_t tempLen = *encLen; + if (tempLen < 1) { + return BSL_INVALID_ARG; + } + tag = *temp; + temp++; + tempLen--; + int32_t ret = BSL_ASN1_DecodeLen(&temp, &tempLen, false, &len); + if (ret != BSL_SUCCESS) { + return ret; + } + asnItem->tag = tag; + asnItem->len = len; + asnItem->buff = temp; + temp += len; + tempLen -= len; + *encode = temp; + *encLen = tempLen; + return BSL_SUCCESS; +} + +static int32_t ParseBool(uint8_t *val, uint32_t len, bool *decodeData) +{ + if (len != 1) { + return BSL_ASN1_ERR_DECODE_BOOL; + } + *decodeData = (*val != 0) ? 1 : 0; + return BSL_SUCCESS; +} + +// The complement form supports negative numbers, so it cannot parse unsigned integers +static int32_t ParseInt(uint8_t *val, uint32_t len, int *decodeData) +{ + uint8_t *temp = val; + // Negative numbers not supported + if (len < 1 || (*val & 0x80) != 0 || len > sizeof(int)) { + return BSL_ASN1_ERR_DECODE_INT; + } + + *decodeData = 0; + for (uint32_t i = 0; i < len; i++) { + *decodeData = (*decodeData << 8) | *temp; + temp++; + } + return BSL_SUCCESS; +} + +static int32_t ParseBitString(uint8_t *val, uint32_t len, BSL_ASN1_BitString *decodeData) +{ + if (len < 1 || *val > BSL_ASN1_VAL_MAX_BIT_STRING_LEN) { + return BSL_ASN1_ERR_DECODE_BIT_STRING; + } + decodeData->unusedBits = *val; + decodeData->buff = val + 1; + decodeData->len = len - 1; + return BSL_SUCCESS; +} + +// len max support 4 +static uint32_t DecodeAsciiNum(uint8_t **encode, uint32_t len) +{ + uint32_t temp = 0; + uint8_t *data = *encode; + for (uint32_t i = 0; i < len; i++) { + temp *= 10; // 10: Process decimal numbers. + temp += (data[i] - '0'); + } + *encode += len; + return temp; +} + +static int32_t CheckTime(uint8_t *data, uint32_t len) +{ + for (uint32_t i = 0; i < len; i++) { + if (data[i] > '9' || data[i] < '0') { + return BSL_ASN1_ERR_DECODE_TIME; + } + } + return BSL_SUCCESS; +} + +// Support utcTime for YYMMDDHHMMSS[Z] and generalizedTime for YYYYMMDDHHMMSS[Z]. +static int32_t ParseTime(uint8_t tag, uint8_t *val, uint32_t len, BSL_TIME *decodeData) +{ + int32_t ret; + uint8_t *temp = val; + if (tag == BSL_ASN1_TAG_UTCTIME && (len != 12 && len != 13)) { // 12 YYMMDDHHMMSS, 13 YYMMDDHHMMSSZ + return BSL_ASN1_ERR_DECODE_UTC_TIME; + } + + if (tag == BSL_ASN1_TAG_GENERALIZEDTIME && (len != 14 && len != 15)) { // 14 YYYYMMDDHHMMSS, 15 YYYYMMDDHHMMSSZ + return BSL_ASN1_ERR_DECODE_GENERAL_TIME; + } + + // Check if the encoding is within the expected range and prepare for conversion + ret = tag == BSL_ASN1_TAG_UTCTIME ? CheckTime(val, 12) : CheckTime(val, 14); // 12|14: ignoring Z + if (ret != BSL_SUCCESS) { + return ret; + } + if (tag == BSL_ASN1_TAG_UTCTIME) { + decodeData->year = DecodeAsciiNum(&temp, 2); // 2: YY + decodeData->year += 2000; // Currently supported after 2000 year + } else { + decodeData->year = DecodeAsciiNum(&temp, 4); // 4: YYYY + } + decodeData->month = DecodeAsciiNum(&temp, 2); // 2:MM + decodeData->day = DecodeAsciiNum(&temp, 2); // 2: DD + decodeData->hour = DecodeAsciiNum(&temp, 2); // 2: HH + decodeData->minute = DecodeAsciiNum(&temp, 2); // 2: MM + decodeData->second = DecodeAsciiNum(&temp, 2); // 2: SS + return BSL_DateTimeCheck(decodeData) ? BSL_SUCCESS : BSL_ASN1_ERR_CHECK_TIME; +} + +static int32_t DecodeTwoLayerListInternal(uint32_t layer, BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn, + BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list) +{ + int32_t ret; + uint8_t tag; + uint32_t encLen; + uint8_t *buff = asn->buff; + uint32_t len = asn->len; + BSL_ASN1_Buffer item; + while (len > 0) { + if (*buff != param->expTag[layer - 1]) { + return BSL_ASN1_ERR_MISMATCH_TAG; + } + tag = *buff; + buff++; + len--; + ret = BSL_ASN1_DecodeLen(&buff, &len, false, &encLen); + if (ret != BSL_SUCCESS) { + return ret; + } + item.tag = tag; + item.len = encLen; + item.buff = buff; + ret = parseListItemCb(layer, &item, cbParam, list); + if (ret != BSL_SUCCESS) { + return ret; + } + buff += encLen; + len -= encLen; + } + return BSL_SUCCESS; +} + +static int32_t DecodeOneLayerList(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn, + BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list) +{ + return DecodeTwoLayerListInternal(1, param, asn, parseListItemCb, cbParam, list); +} + +static int32_t DecodeTwoLayerList(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn, + BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list) +{ + int32_t ret; + uint8_t tag; + uint32_t encLen; + uint8_t *buff = asn->buff; + uint32_t len = asn->len; + BSL_ASN1_Buffer item; + while (len > 0) { + if (*buff != param->expTag[0]) { + return BSL_ASN1_ERR_MISMATCH_TAG; + } + tag = *buff; + buff++; + len--; + ret = BSL_ASN1_DecodeLen(&buff, &len, false, &encLen); + if (ret != BSL_SUCCESS) { + return ret; + } + item.tag = tag; + item.len = encLen; + item.buff = buff; + ret = parseListItemCb(1, &item, cbParam, list); + if (ret != BSL_SUCCESS) { + return ret; + } + ret = DecodeTwoLayerListInternal(2, param, &item, parseListItemCb, cbParam, list); + if (ret != BSL_SUCCESS) { + return ret; + } + buff += encLen; + len -= encLen; + } + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_DecodeListItem(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn, + BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list) +{ + if (param == NULL || asn == NULL || parseListItemCb == NULL || list == NULL) { + return BSL_INVALID_ARG; + } + + // Currently, it supports a maximum of 2 layers + if (param->layer > BSL_ASN1_MAX_LIST_NEST_EPTH) { + return BSL_ASN1_ERR_EXCEED_LIST_DEPTH; + } + return param->layer == 1 ? DecodeOneLayerList(param, asn, parseListItemCb, cbParam, list) + : DecodeTwoLayerList(param, asn, parseListItemCb, cbParam, list); +} + +static int32_t ParseBMPString(const uint8_t *bmp, uint32_t bmpLen, BSL_ASN1_Buffer *decode) +{ + if (bmp == NULL || bmpLen == 0 || decode == NULL) { + return BSL_NULL_INPUT; + } + if (bmpLen % 2 != 0) { // multiple of 2 + return BSL_INVALID_ARG; + } + uint8_t *tmp = (uint8_t *)BSL_SAL_Malloc(bmpLen / 2); // decodeLen = bmpLen/2 + if (tmp == NULL) { + return BSL_MALLOC_FAIL; + } + for (uint32_t i = 0; i < bmpLen / 2; i++) { // decodeLen = bmpLen/2 + tmp[i] = bmp[i * 2 + 1]; + } + decode->buff = tmp; + decode->len = bmpLen / 2; // decodeLen = bmpLen/2 + return BSL_SUCCESS; +} + +int32_t EncodeBMPString(const uint8_t *in, uint32_t inLen, uint8_t *encode, uint32_t *offset) +{ + if (in == NULL || inLen == 0 || encode == NULL || offset == NULL) { + return BSL_NULL_INPUT; + } + uint8_t *tmp = (uint8_t *)BSL_SAL_Calloc(inLen * 2, 1); // encodeLen = 2 * inLen + if (tmp == NULL) { + return BSL_MALLOC_FAIL; + } + for (uint32_t i = 0; i < inLen; i++) { + if (in[i] > 127) { // max ascii 127. + BSL_SAL_FREE(tmp); + return BSL_INVALID_ARG; + } + tmp[2 * i + 1] = in[i]; // we need 2 space, [0,0] -> after encode = [0, data]; + } + (void)memcpy_s(encode + *offset, inLen * 2, tmp, inLen * 2); // encodeLen = 2 * inLen + BSL_SAL_FREE(tmp); + *offset += inLen * 2; // encodeLen = 2 * inLen + return BSL_SUCCESS; +} + +/** + * Big numbers do not need to call this interface, + * the filled leading 0 has no effect on the result of large numbers, big numbers can be directly used asn's buff. + * + * It has been ensured at parsing time that the content to which the buff points is security for length within asn'len + */ +int32_t BSL_ASN1_DecodePrimitiveItem(BSL_ASN1_Buffer *asn, void *decodeData) +{ + if (asn == NULL || decodeData == NULL) { + return BSL_NULL_INPUT; + } + switch (asn->tag) { + case BSL_ASN1_TAG_BOOLEAN: + return ParseBool(asn->buff, asn->len, decodeData); + case BSL_ASN1_TAG_INTEGER: + case BSL_ASN1_TAG_ENUMERATED: + return ParseInt(asn->buff, asn->len, decodeData); + case BSL_ASN1_TAG_BITSTRING: + return ParseBitString(asn->buff, asn->len, decodeData); + case BSL_ASN1_TAG_UTCTIME: + case BSL_ASN1_TAG_GENERALIZEDTIME: + return ParseTime(asn->tag, asn->buff, asn->len, decodeData); + case BSL_ASN1_TAG_BMPSTRING: + return ParseBMPString(asn->buff, asn->len, decodeData); + default: + break; + } + return BSL_ASN1_FAIL; +} + +static int32_t BSL_ASN1_AnyOrChoiceTagProcess(bool isAny, BSL_ASN1_AnyOrChoiceParam *tagCbinfo, uint8_t *tag) +{ + if (tagCbinfo->tagCb == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: callback is null", 0, 0, 0, 0); + return BSL_ASN1_ERR_NO_CALLBACK; + } + int32_t type = isAny == true ? BSL_ASN1_TYPE_GET_ANY_TAG : BSL_ASN1_TYPE_CHECK_CHOICE_TAG; + int32_t ret = tagCbinfo->tagCb(type, tagCbinfo->idx, tagCbinfo->previousAsnOrTag, tag); + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: callback is err %x", ret, 0, 0, 0); + } + return ret; +} + +static int32_t BSL_ASN1_ProcessWithoutDefOrOpt(BSL_ASN1_AnyOrChoiceParam *tagCbinfo, uint8_t realTag, uint8_t *expTag) +{ + int32_t ret; + uint8_t tag = *expTag; + // Any and choice will not have a coexistence scenario, which is meaningless. + if (tag == BSL_ASN1_TAG_CHOICE) { + tagCbinfo->previousAsnOrTag = &realTag; + ret = BSL_ASN1_AnyOrChoiceTagProcess(false, tagCbinfo, expTag); + if (ret != BSL_SUCCESS) { + return ret; + } + } else { // The tags of any and normal must be present + if (tag == BSL_ASN1_TAG_ANY) { + ret = BSL_ASN1_AnyOrChoiceTagProcess(true, tagCbinfo, &tag); + if (ret != BSL_SUCCESS) { + return ret; + } + } + if (tag != realTag) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: expected tag %x is not match %x", tag, realTag, 0, 0); + return BSL_ASN1_ERR_TAG_EXPECTED; + } + *expTag = realTag; + } + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_ProcessNormal(BSL_ASN1_AnyOrChoiceParam *tagCbinfo, + BSL_ASN1_TemplateItem *item, uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asn) +{ + uint32_t len; + int32_t ret; + uint8_t tag = item->tag; + uint8_t *temp = *encode; + uint32_t tempLen = *encLen; + + if (item->flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL) { // optional or default scene + if (tempLen < 1) { // optional or default scene is normal + asn->tag = 0; + asn->len = 0; + asn->buff = NULL; + return BSL_SUCCESS; + } + + if (tag == BSL_ASN1_TAG_ANY) { + ret = BSL_ASN1_AnyOrChoiceTagProcess(true, tagCbinfo, &tag); + if (ret != BSL_SUCCESS) { + return ret; + } + } + + if (tag == BSL_ASN1_TAG_CHOICE) { + tagCbinfo->previousAsnOrTag = temp; + ret = BSL_ASN1_AnyOrChoiceTagProcess(false, tagCbinfo, &tag); + if (ret != BSL_SUCCESS) { + return ret; + } + } + + if (tag != *temp) { // The optional or default scene is not encoded + asn->tag = 0; + asn->len = 0; + asn->buff = NULL; + return BSL_SUCCESS; + } + } else { + /* No optional or default scenes, tag must exist */ + if (tempLen < 1) { + return BSL_ASN1_ERR_DECODE_LEN; + } + ret = BSL_ASN1_ProcessWithoutDefOrOpt(tagCbinfo, *temp, &tag); + if (ret != BSL_SUCCESS) { + return ret; + } + } + + temp++; + tempLen--; + ret = BSL_ASN1_DecodeLen(&temp, &tempLen, false, &len); + if (ret != BSL_SUCCESS) { + return ret; + } + asn->tag = tag; + asn->len = len; + asn->buff = (tag == BSL_ASN1_TAG_NULL) ? NULL: temp; + if (item->tag & BSL_ASN1_TAG_CONSTRUCTED) { + /* struct type, headerOnly flag is set, only the whole is parsed, + otherwise the parsed content is traversed */ + if (item->flags & BSL_ASN1_FLAG_HEADERONLY) { + temp += len; + tempLen -= len; + } + } else { + temp += len; + tempLen -= len; + } + *encode = temp; + *encLen = tempLen; + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_SkipChildNode(int32_t idx, BSL_ASN1_TemplateItem *item, uint32_t count) +{ + size_t i = idx + 1; + for (; i < count; i++) { + if (item[i].depth <= item[idx].depth) { + break; + } + } + return i - idx; +} + +static bool BSL_ASN1_IsConstructItem(BSL_ASN1_TemplateItem *item) +{ + return item->tag & BSL_ASN1_TAG_CONSTRUCTED; +} + +static int32_t BSL_ASN1_FillConstructItemWithNull(BSL_ASN1_Template *templ, uint32_t *templIdx, + BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint32_t *arrIdx) +{ + // The construct type value is marked headeronly + if (templ->templItems[*templIdx].flags & BSL_ASN1_FLAG_HEADERONLY) { + if (*arrIdx >= arrNum) { + return BSL_ASN1_ERR_OVERFLOW; + } else { + asnArr[*arrIdx].tag = 0; + asnArr[*arrIdx].len = 0; + asnArr[*arrIdx].buff = 0; + (*arrIdx)++; + } + (*templIdx) += BSL_ASN1_SkipChildNode(*templIdx, templ->templItems, templ->templNum); + } else { + // This scenario does not record information about the parent node + (*templIdx)++; + } + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_SkipChildNodeAndFill(uint32_t *idx, BSL_ASN1_Template *templ, + BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint32_t *arrIndex) +{ + uint32_t arrIdx = *arrIndex; + uint32_t i = *idx; + for (; i < templ->templNum;) { + if (templ->templItems[i].depth <= templ->templItems[*idx].depth && i > *idx) { + break; + } + // There are also struct types under the processing parent + if (BSL_ASN1_IsConstructItem(&templ->templItems[i])) { + int32_t ret = BSL_ASN1_FillConstructItemWithNull(templ, &i, asnArr, arrNum, &arrIdx); + if (ret != BSL_SUCCESS) { + return ret; + } + } else { + asnArr[arrIdx].tag = 0; + asnArr[arrIdx].len = 0; + asnArr[arrIdx].buff = 0; + arrIdx++; + i++; + } + } + *arrIndex = arrIdx; + *idx = i; + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_ProcessConstructResult(BSL_ASN1_Template *templ, uint32_t *templIdx, BSL_ASN1_Buffer *asn, + BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint32_t *arrIdx) +{ + int32_t ret; + // Optional or default construct type, without any data to be parsed, need to skip all child nodes + if ((templ->templItems[*templIdx].flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL) && asn->tag == 0) { + ret = BSL_ASN1_SkipChildNodeAndFill(templIdx, templ, asnArr, arrNum, arrIdx); + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: skip and file node err %x, idx %d", ret, *templIdx, 0, 0); + return ret; + } + return BSL_SUCCESS; + } + + if (templ->templItems[*templIdx].flags & BSL_ASN1_FLAG_HEADERONLY) { + if (*arrIdx >= arrNum) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: array idx %d, overflow %d, templ %d", *arrIdx, arrNum, *templIdx, 0); + return BSL_ASN1_ERR_OVERFLOW; + } else { + // Shallow copy of structure + asnArr[*arrIdx].tag = asn->tag; + asnArr[*arrIdx].len = asn->len; + asnArr[*arrIdx].buff = asn->buff; + (*arrIdx)++; + } + (*templIdx) += BSL_ASN1_SkipChildNode(*templIdx, templ->templItems, templ->templNum); + } else { + (*templIdx)++; // Non header only flags, do not fill this parse + } + return BSL_SUCCESS; +} + +static inline bool IsInvalidTempl(BSL_ASN1_Template *templ) +{ + return templ == NULL || templ->templNum == 0 || templ->templItems == NULL; +} +static inline bool IsInvalidAsns(BSL_ASN1_Buffer *asnArr, uint32_t arrNum) +{ + return asnArr == NULL || arrNum == 0; +} + +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) +{ + int32_t ret; + if (IsInvalidTempl(templ) || encode == NULL || *encode == NULL || encLen == NULL || IsInvalidAsns(asnArr, arrNum)) { + return BSL_NULL_INPUT; + } + uint8_t *temp = *encode; + uint32_t tempLen = *encLen; + BSL_ASN1_Buffer asn = {0}; // temp var + uint32_t arrIdx = 0; + BSL_ASN1_Buffer previousAsn = {0}; + BSL_ASN1_AnyOrChoiceParam tagCbinfo = {0, NULL, decTemlCb}; + + for (uint32_t i = 0; i < templ->templNum;) { + if (templ->templItems[i].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) { + return BSL_ASN1_ERR_MAX_DEPTH; + } + tagCbinfo.previousAsnOrTag = &previousAsn; + tagCbinfo.idx = i; + if (BSL_ASN1_IsConstructItem(&templ->templItems[i])) { + ret = BSL_ASN1_ProcessNormal(&tagCbinfo, &templ->templItems[i], &temp, &tempLen, &asn); + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: parse construct item err %x, idx %d", ret, i, 0, 0); + return ret; + } + ret = BSL_ASN1_ProcessConstructResult(templ, &i, &asn, asnArr, arrNum, &arrIdx); + if (ret != BSL_SUCCESS) { + return ret; + } + } else { + ret = BSL_ASN1_ProcessNormal(&tagCbinfo, &templ->templItems[i], &temp, &tempLen, &asn); + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: parse primitive item err %x, idx %d", ret, i, 0, 0); + return ret; + } + // Process no construct result + if (arrIdx >= arrNum) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "asn1: array idx %d, overflow %d, templ %d", arrIdx, arrNum, i, 0); + return BSL_ASN1_ERR_OVERFLOW; + } else { + asnArr[arrIdx++] = asn; // Shallow copy of structure + } + i++; + } + previousAsn = asn; + } + + *encode = temp; + *encLen = tempLen; + return BSL_SUCCESS; +} + +/* Init the depth and flags of the items. */ +static int32_t EncodeInitItemFlag(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_TemplateItem *tItems, uint32_t eleNum) +{ + uint32_t stack[BSL_ASN1_MAX_TEMPLATE_DEPTH + 1] = {0}; // store the index of the items + int32_t peek = 0; + + /* Stack the first item */ + if (tItems[0].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) { + return BSL_ASN1_ERR_MAX_DEPTH; + } + eItems[0].depth = tItems[0].depth; + eItems[0].optional = tItems[0].flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL; + stack[peek] = 0; + + for (uint32_t i = 1; i < eleNum; i++) { + if (tItems[i].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) { + return BSL_ASN1_ERR_MAX_DEPTH; + } + eItems[i].depth = tItems[i].depth; + while (eItems[i].depth <= eItems[stack[peek]].depth) { + peek--; + } + /* After the above processing, the top of the stack is the parent node of the current node. */ + /* The null type only inherits the optional tag of the parent node. */ + eItems[i].optional = eItems[stack[peek]].optional; + if (tItems[i].tag != BSL_ASN1_TAG_NULL) { + eItems[i].optional |= (tItems[i].flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL); + } + eItems[i].skip = (eItems[stack[peek]].skip == 1) || (tItems[stack[peek]].flags & BSL_ASN1_FLAG_HEADERONLY); + stack[++peek] = i; + } + return BSL_SUCCESS; +} + +static inline bool IsAnyOrChoice(uint8_t tag) +{ + return tag == BSL_ASN1_TAG_ANY || tag == BSL_ASN1_TAG_CHOICE; +} + +static uint8_t GetOctetNumOfUint(uint64_t number) +{ + uint8_t cnt = 0; + for (uint64_t i = number; i; i >>= 8) { // one byte = 8 bits + cnt++; + } + return cnt; +} + +static uint8_t GetLenOctetNum(uint32_t contentOctetNum) +{ + return contentOctetNum <= BSL_ASN1_DEFINITE_MAX_CONTENT_OCTET_NUM ? 1 : 1 + GetOctetNumOfUint(contentOctetNum); +} + +static uint32_t GetContentLenOfInt(uint8_t *buff, uint32_t len) +{ + if (len == 0) { + return 0; + } + uint32_t res = len; + for (uint32_t i = 0; i < len; i++) { + if (*(buff + i) != 0) { + break; + } + res--; + } + if (res == 0) { // The current int value is 0 + return 1; + } + uint8_t high = *(buff + (len - res)) >> 7; + return res + (high == 1); +} + +static uint32_t GetContentLen(BSL_ASN1_Buffer *asn) +{ + switch (asn->tag) { + case BSL_ASN1_TAG_NULL: + return 0; + case BSL_ASN1_TAG_INTEGER: + case BSL_ASN1_TAG_ENUMERATED: + return GetContentLenOfInt(asn->buff, asn->len); + case BSL_ASN1_TAG_BITSTRING: + return ((BSL_ASN1_BitString *)asn->buff)->len + 1; + case BSL_ASN1_TAG_UTCTIME: + return BSL_ASN1_UTCTIME_LEN; + case BSL_ASN1_TAG_GENERALIZEDTIME: + return BSL_ASN1_GENERALIZEDTIME_LEN; + case BSL_ASN1_TAG_BMPSTRING: + return asn->len * 2; // encodeLen = 2 * asn->len + default: + return asn->len; + } +} + +static void ComputeOctetNum(bool optional, BSL_ASN1_EncodeItem *item, BSL_ASN1_Buffer *asn) +{ + if (optional && asn->len == 0 && (asn->tag != BSL_ASN1_TAG_NULL)) { + return; + } + uint32_t contentOctetNum = asn->len == 0 ? 0 : GetContentLen(asn); + item->lenOctetNum = GetLenOctetNum(contentOctetNum); + item->asnOctetNum = 1 + item->lenOctetNum + contentOctetNum; +} + +static void ComputeConstructAsnOctetNum(bool optional, BSL_ASN1_TemplateItem *templ, BSL_ASN1_EncodeItem *item, + uint32_t itemNum, uint32_t curIdx) +{ + uint8_t curDepth = templ[curIdx].depth; + uint32_t contentOctetNum = 0; + for (uint32_t i = curIdx + 1; i < itemNum && templ[i].depth != curDepth; i++) { + if (templ[i].depth - curDepth == 1) { + contentOctetNum += item[i].asnOctetNum; + } + } + if (contentOctetNum == 0 && optional) { + return; + } + item[curIdx].lenOctetNum = GetLenOctetNum(contentOctetNum); + item[curIdx].asnOctetNum = 1 + item[curIdx].lenOctetNum + contentOctetNum; +} + +static int32_t EncodeInitItemContent(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_TemplateItem *tItems, uint32_t itemNum, + BSL_ASN1_Buffer *asnArr, int32_t *asnNum) +{ + int32_t asnIdx = *asnNum - 1; + uint8_t lastDepth = 0; + + for (int32_t i = itemNum - 1; i >= 0; i--) { + if (eItems[i].skip == 1) { + continue; + } + if (tItems[i].depth < lastDepth) { + eItems[i].tag = tItems[i].tag; + ComputeConstructAsnOctetNum(eItems[i].optional, tItems, eItems, itemNum, i); + } else { + if (asnIdx < 0) { + return BSL_ASN1_ERR_ENCODE_ASN_LACK; + } + if (eItems[i].optional == false && asnArr[asnIdx].tag != tItems[i].tag && !IsAnyOrChoice(tItems[i].tag)) { + return BSL_ASN1_ERR_TAG_EXPECTED; + } + ComputeOctetNum(eItems[i].optional, eItems + i, asnArr + asnIdx); + eItems[i].tag = asnArr[asnIdx].tag; + eItems[i].asn = asnArr + asnIdx; // Shallow copy. + asnIdx--; + } + lastDepth = tItems[i].depth; + } + *asnNum = asnIdx + 1; + return BSL_SUCCESS; +} + +static void EncodeNumber(uint64_t data, uint32_t encodeLen, uint8_t *encode, uint32_t *offset) +{ + uint32_t tmp = data; + /* Encode from back to front. */ + uint32_t initOff = *offset + encodeLen - 1; + for (uint32_t i = 0; i < encodeLen; i++) { + *(encode + initOff - i) = (uint8_t)tmp; + tmp >>= 8; // one byte = 8 bits + } + *offset += encodeLen; +} + +static void EncodeLength(uint8_t lenOctetNum, uint32_t contentOctetNum, uint8_t *encode, uint32_t *offset) +{ + if (contentOctetNum <= BSL_ASN1_DEFINITE_MAX_CONTENT_OCTET_NUM) { + *(encode + *offset) = (uint8_t)contentOctetNum; + *offset += 1; + return; + } + + // the initial octet + *(encode + *offset) = BSL_ASN1_INDEFINITE_LENGTH | (lenOctetNum - 1); + *offset += 1; + // the subsequent octets + EncodeNumber(contentOctetNum, lenOctetNum - 1, encode, offset); +} + +static inline void EncodeBool(bool *data, uint8_t *encode, uint32_t *offset) +{ + *(encode + *offset) = *data == true ? 0xFF : 0x00; + *offset += 1; +} + +static void EncodeBitString(BSL_ASN1_BitString *data, uint32_t encodeLen, uint8_t *encode, uint32_t *offset) +{ + *(encode + *offset) = data->unusedBits; + + for (uint32_t i = 0; i < encodeLen - 1; i++) { + *(encode + *offset + i + 1) = *(data->buff + i); + } + // Last octet: Set unused bits to 0 + *(encode + *offset + encodeLen - 1) >>= data->unusedBits; + *(encode + *offset + encodeLen - 1) <<= data->unusedBits; + *offset += encodeLen; +} + +static void EncodeNum2Ascii(uint8_t *encode, uint32_t *offset, uint8_t encodeLen, uint16_t number) +{ + uint16_t tmp = number; + /* Encode from back to front. */ + uint32_t initOff = *offset + encodeLen - 1; + for (uint32_t i = 0; i < encodeLen; i++) { + *(encode + initOff - i) = tmp % 10 + '0'; // 10: Take the lowest digit of a decimal number. + tmp /= 10; // 10: Get the number in decimal except for the lowest bit. + } + *offset += encodeLen; +} + +static void EncodeTime(BSL_TIME *time, uint8_t tag, uint8_t *encode, uint32_t *offset) +{ + if (tag == BSL_ASN1_TAG_UTCTIME) { + EncodeNum2Ascii(encode, offset, 2, time->year % 100); // 2: YY, %100: Get the lower 2 digits of the number + } else { + EncodeNum2Ascii(encode, offset, 4, time->year); // 4: YYYY + } + EncodeNum2Ascii(encode, offset, 2, time->month); // 2: MM + EncodeNum2Ascii(encode, offset, 2, time->day); // 2: DD + EncodeNum2Ascii(encode, offset, 2, time->hour); // 2: HH + EncodeNum2Ascii(encode, offset, 2, time->minute); // 2: MM + EncodeNum2Ascii(encode, offset, 2, time->second); // 2: SS + *(encode + *offset) = 'Z'; + *offset += 1; +} + +static void EncodeInt(BSL_ASN1_Buffer *asn, uint32_t encodeLen, uint8_t *encode, uint32_t *offset) +{ + if (encodeLen < asn->len) { + /* Skip the copying of high-order octets with all zeros. */ + (void)memcpy_s(encode + *offset, encodeLen, asn->buff + (asn->len - encodeLen), encodeLen); + } else { + /* the high bit of positve number octet is 1 */ + (void)memcpy_s(encode + *offset + (encodeLen - asn->len), asn->len, asn->buff, asn->len); + } + *offset += encodeLen; +} + +static void EncodeContent(BSL_ASN1_Buffer *asn, uint32_t encodeLen, uint8_t *encode, uint32_t *offset) +{ + switch (asn->tag) { + case BSL_ASN1_TAG_BOOLEAN: + EncodeBool((bool *)asn->buff, encode, offset); + return; + case BSL_ASN1_TAG_INTEGER: + case BSL_ASN1_TAG_ENUMERATED: + EncodeInt(asn, encodeLen, encode, offset); + return; + case BSL_ASN1_TAG_BITSTRING: + EncodeBitString((BSL_ASN1_BitString *)asn->buff, encodeLen, encode, offset); + return; + case BSL_ASN1_TAG_UTCTIME: + case BSL_ASN1_TAG_GENERALIZEDTIME: + EncodeTime((BSL_TIME *)asn->buff, asn->tag, encode, offset); + return; + case BSL_ASN1_TAG_BMPSTRING: + EncodeBMPString(asn->buff, asn->len, encode, offset); + return; + default: + (void)memcpy_s(encode + *offset, encodeLen, asn->buff, encodeLen); + *offset += encodeLen; + return; + } +} + +static void EncodeItem(BSL_ASN1_EncodeItem *eItems, uint32_t itemNum, uint8_t *encode) +{ + uint8_t *temp = encode; + uint32_t offset = 0; + uint32_t contentOctetNum; + + for (uint32_t i = 0; i < itemNum; i++) { + if (eItems[i].asnOctetNum == 0) { + continue; + } + contentOctetNum = eItems[i].asnOctetNum - 1 - eItems[i].lenOctetNum; + + /* tag */ + *(temp + offset) = eItems[i].tag; + offset += 1; + /* length */ + EncodeLength(eItems[i].lenOctetNum, contentOctetNum, encode, &offset); + /* content */ + if (contentOctetNum != 0 && eItems[i].asn != NULL && eItems[i].asn->len != 0) { + EncodeContent(eItems[i].asn, contentOctetNum, encode, &offset); + } + } +} + +static int32_t CheckBslTime(BSL_ASN1_Buffer *asn) +{ + if (asn->len != sizeof(BSL_TIME)) { + return BSL_ASN1_ERR_CHECK_TIME; + } + BSL_TIME *time = (BSL_TIME *)asn->buff; + if (BSL_DateTimeCheck(time) == false) { + return BSL_ASN1_ERR_CHECK_TIME; + } + if (asn->tag == BSL_ASN1_TAG_UTCTIME && (time->year < 2000 || time->year > 2049)) { // Utc time range: [2000, 2049] + return BSL_ASN1_ERR_ENCODE_UTC_TIME; + } + if (asn->tag == BSL_ASN1_TAG_GENERALIZEDTIME && + time->year > 9999) { // 9999: The number of digits for year must be 4. + return BSL_ASN1_ERR_ENCODE_GENERALIZED_TIME; + } + return BSL_SUCCESS; +} + +static int32_t CheckAsn(BSL_ASN1_Buffer *asn) +{ + switch (asn->tag) { + case BSL_ASN1_TAG_BOOLEAN: + return asn->len != sizeof(bool) ? BSL_ASN1_ERR_ENCODE_BOOL : BSL_SUCCESS; + case BSL_ASN1_TAG_BITSTRING: + if (asn->len != sizeof(BSL_ASN1_BitString)) { + return BSL_ASN1_ERR_ENCODE_BIT_STRING; + } + BSL_ASN1_BitString *bs = (BSL_ASN1_BitString *)asn->buff; + return bs->unusedBits > BSL_ASN1_VAL_MAX_BIT_STRING_LEN ? BSL_ASN1_ERR_ENCODE_BIT_STRING : BSL_SUCCESS; + case BSL_ASN1_TAG_UTCTIME: + case BSL_ASN1_TAG_GENERALIZEDTIME: + return CheckBslTime(asn); + default: + return BSL_SUCCESS; + } +} + +static int32_t CheckAsnArr(BSL_ASN1_Buffer *asnArr, uint32_t arrNum) +{ + int32_t ret; + for (uint32_t i = 0; i < arrNum; i++) { + if (asnArr[i].buff != NULL) { + ret = CheckAsn(asnArr + i); + if (ret != BSL_SUCCESS) { + return ret; + } + } + } + return BSL_SUCCESS; +} + +static int32_t EncodeItemInit(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_TemplateItem *tItems, uint32_t itemNum, + BSL_ASN1_Buffer *asnArr, int32_t *arrNum) +{ + int32_t ret = EncodeInitItemFlag(eItems, tItems, itemNum); + if (ret != BSL_SUCCESS) { + return ret; + } + + return EncodeInitItemContent(eItems, tItems, itemNum, asnArr, arrNum); +} + +static int32_t EncodeInit(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr, + uint32_t arrNum, uint32_t *encodeLen) +{ + int32_t tempArrNum = (int32_t)arrNum; + uint32_t stBegin; + uint32_t stEnd = templ->templNum - 1; + int32_t ret; + for (int32_t i = templ->templNum - 1; i >= 0; i--) { + if (templ->templItems[i].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) { + return BSL_ASN1_ERR_MAX_DEPTH; + } + if (templ->templItems[i].depth != 0) { + continue; + } + stBegin = i; + ret = EncodeItemInit(eItems + stBegin, templ->templItems + stBegin, stEnd - stBegin + 1, asnArr, &tempArrNum); + if (ret != BSL_SUCCESS) { + return ret; + } + *encodeLen += (eItems + stBegin)->asnOctetNum; + stEnd = i - 1; + } + if (tempArrNum != 0) { + return BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH; + } + return ret; +} + +int32_t BSL_ASN1_EncodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint8_t **encode, + uint32_t *encLen) +{ + if (IsInvalidTempl(templ) || IsInvalidAsns(asnArr, arrNum) || encode == NULL || *encode != NULL || encLen == NULL) { + return BSL_INVALID_ARG; + } + int32_t ret = CheckAsnArr(asnArr, arrNum); + if (ret != BSL_SUCCESS) { + return ret; + } + + BSL_ASN1_EncodeItem *eItems = (BSL_ASN1_EncodeItem *)BSL_SAL_Calloc(templ->templNum, sizeof(BSL_ASN1_EncodeItem)); + if (eItems == NULL) { + return BSL_MALLOC_FAIL; + } + uint32_t encodeLen = 0; + ret = EncodeInit(eItems, templ, asnArr, arrNum, &encodeLen); + if (ret != BSL_SUCCESS) { + BSL_SAL_Free(eItems); + return ret; + } + + *encode = (uint8_t *)BSL_SAL_Calloc(1, encodeLen); + if (*encode == NULL) { + BSL_SAL_Free(eItems); + return BSL_MALLOC_FAIL; + } + EncodeItem(eItems, templ->templNum, *encode); + *encLen = encodeLen; + + BSL_SAL_Free(eItems); + return BSL_SUCCESS; +} + +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) +{ + if ((tag != BSL_ASN1_TAG_SEQUENCE && tag != BSL_ASN1_TAG_SET) || IsInvalidTempl(templ) || + IsInvalidAsns(asnArr, arrNum) || listSize == 0 || arrNum % listSize != 0 || out == NULL || out->buff != NULL) { + return BSL_INVALID_ARG; + } + int32_t ret = CheckAsnArr(asnArr, arrNum); + if (ret != BSL_SUCCESS) { + return ret; + } + + BSL_ASN1_EncodeItem *eItems = + (BSL_ASN1_EncodeItem *)BSL_SAL_Calloc(templ->templNum * listSize, sizeof(BSL_ASN1_EncodeItem)); + if (eItems == NULL) { + return BSL_MALLOC_FAIL; + } + uint32_t encodeLen = 0; + int32_t itemAsnNum; + for (uint32_t i = 0; i < listSize; i++) { + itemAsnNum = arrNum / listSize; + ret = EncodeItemInit( + eItems + i * templ->templNum, templ->templItems, templ->templNum, asnArr + i * itemAsnNum, &itemAsnNum); + if (ret != BSL_SUCCESS) { + BSL_SAL_Free(eItems); + return ret; + } + if (itemAsnNum != 0) { + BSL_SAL_Free(eItems); + return BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH; + } + encodeLen += (eItems + i * templ->templNum)->asnOctetNum; + } + + out->buff = (uint8_t *)BSL_SAL_Calloc(1, encodeLen); + if (out->buff == NULL) { + BSL_SAL_Free(eItems); + return BSL_MALLOC_FAIL; + } + uint8_t *encode = out->buff; + for (uint32_t i = 0; i < listSize; i++) { + EncodeItem(eItems + i * templ->templNum, templ->templNum, encode); + encode += (eItems + i * templ->templNum)->asnOctetNum; + } + + out->tag = tag | BSL_ASN1_TAG_CONSTRUCTED; + out->len = encodeLen; + + BSL_SAL_Free(eItems); + return BSL_SUCCESS; +} + +int32_t BSL_ASN1_EncodeLimb(uint8_t tag, uint64_t limb, BSL_ASN1_Buffer *asn) +{ + if ((tag != BSL_ASN1_TAG_INTEGER && tag != BSL_ASN1_TAG_ENUMERATED) || asn == NULL || asn->buff != NULL) { + return BSL_INVALID_ARG; + } + + asn->tag = tag; + asn->len = limb == 0 ? 1 : GetOctetNumOfUint(limb); + asn->buff = (uint8_t *)BSL_SAL_Calloc(1, asn->len); + if (asn->buff == NULL) { + return BSL_MALLOC_FAIL; + } + if (limb == 0) { + return BSL_SUCCESS; + } + uint32_t offset = 0; + EncodeNumber(limb, asn->len, asn->buff, &offset); + return BSL_SUCCESS; +} diff --git a/bsl/asn1/src/bsl_asn1_local.h b/bsl/asn1/src/bsl_asn1_local.h new file mode 100644 index 00000000..aead56ad --- /dev/null +++ b/bsl/asn1/src/bsl_asn1_local.h @@ -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 +#include +#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 diff --git a/bsl/base64/include/bsl_base64_internal.h b/bsl/base64/include/bsl_base64_internal.h new file mode 100644 index 00000000..bfc10720 --- /dev/null +++ b/bsl/base64/include/bsl_base64_internal.h @@ -0,0 +1,66 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef BSL_BASE64_INTERNAL_H +#define BSL_BASE64_INTERNAL_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_BASE64 + +#include "bsl_base64.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct BASE64_ControlBlock { + /* size of the unencoded block in the current buffer */ + uint32_t num; + /* + * Size of the block for internal encoding and decoding. + * The size of the coding block is set to 48, and the size of the decoding block is set to 64. + */ + uint32_t length; + /* see BSL_BASE64_FLAGS*, for example: BSL_BASE64_FLAGS_NO_NEWLINE, means process without '\n' */ + uint32_t flags; + uint32_t paddingCnt; + /* codec buffer */ + uint8_t buf[HITLS_BASE64_CTX_BUF_LENGTH]; +}; + +#define BASE64_ENCODE_BYTES 3 // encode 3 bytes at a time +#define BASE64_DECODE_BYTES 4 // decode 4 bytes at a time +#define BASE64_BLOCK_SIZE 1024 +#define BASE64_PAD_MAX 2 +#define BASE64_DECODE_BLOCKSIZE 64 +#define BASE64_CTX_BUF_SIZE HITLS_BASE64_ENCODE_LENGTH(BASE64_BLOCK_SIZE) + 10 +#define BSL_BASE64_ENC_ENOUGH_LEN(len) (((len) + 2) / 3 * 4 + 1) +#define BSL_BASE64_DEC_ENOUGH_LEN(len) (((len) + 3) / 4 * 3) + +/** + * @ingroup bsl_base64 + * @brief Obtain the remaining context buf and determine whether to invoke final(). + * @par Description: Obtains the remaining length "num" of the context buf. + * @param ctx [IN] Input context. + * @param num [OUT] Obtain the remaining length of the buf. + * @retval If it is success, BSL_SUCCESS is returned. Otherwise, a failure error code is returned. + */ +int32_t BSL_Base64GetNum(BSL_Base64Ctx *ctx, uint32_t *num); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* HITLS_BSL_BASE64 */ +#endif /* conditional include */ \ No newline at end of file diff --git a/bsl/base64/src/bsl_base64.c b/bsl/base64/src/bsl_base64.c new file mode 100644 index 00000000..1ef1da5a --- /dev/null +++ b/bsl/base64/src/bsl_base64.c @@ -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 +#include +#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 */ diff --git a/bsl/err/include/bsl_err_internal.h b/bsl/err/include/bsl_err_internal.h new file mode 100644 index 00000000..fc0a75cd --- /dev/null +++ b/bsl/err/include/bsl_err_internal.h @@ -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 +#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 diff --git a/bsl/err/src/avl.c b/bsl/err/src/avl.c new file mode 100644 index 00000000..c8e045db --- /dev/null +++ b/bsl/err/src/avl.c @@ -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 */ diff --git a/bsl/err/src/avl.h b/bsl/err/src/avl.h new file mode 100644 index 00000000..962df5e4 --- /dev/null +++ b/bsl/err/src/avl.h @@ -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 + +#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 \ No newline at end of file diff --git a/bsl/err/src/err.c b/bsl/err/src/err.c new file mode 100644 index 00000000..5b1d1dae --- /dev/null +++ b/bsl/err/src/err.c @@ -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 +#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 */ diff --git a/bsl/hash/include/bsl_hash.h b/bsl/hash/include/bsl_hash.h new file mode 100644 index 00000000..56fe1cbe --- /dev/null +++ b/bsl/hash/include/bsl_hash.h @@ -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 +#include +#include +#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 diff --git a/bsl/hash/include/bsl_hash_list.h b/bsl/hash/include/bsl_hash_list.h new file mode 100644 index 00000000..6e2021b4 --- /dev/null +++ b/bsl/hash/include/bsl_hash_list.h @@ -0,0 +1,349 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @defgroup bsl_list bidirectional linked list + * @ingroup bsl + */ + +#ifndef BSL_HASH_LIST_H +#define BSL_HASH_LIST_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_HASH + +#include +#include +#include + +#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 diff --git a/bsl/hash/include/list_base.h b/bsl/hash/include/list_base.h new file mode 100644 index 00000000..2a153b28 --- /dev/null +++ b/bsl/hash/include/list_base.h @@ -0,0 +1,300 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @defgroup list_base Raw bidirectional linked list + * @ingroup bsl + */ + +#ifndef LIST_BASE_H +#define LIST_BASE_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_HASH + +#include +#include +#include +#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 diff --git a/bsl/hash/src/bsl_hash.c b/bsl/hash/src/bsl_hash.c new file mode 100644 index 00000000..77f90cad --- /dev/null +++ b/bsl/hash/src/bsl_hash.c @@ -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 */ diff --git a/bsl/hash/src/bsl_hash_list.c b/bsl/hash/src/bsl_hash_list.c new file mode 100644 index 00000000..68fa2d45 --- /dev/null +++ b/bsl/hash/src/bsl_hash_list.c @@ -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 +#include +#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 */ diff --git a/bsl/hash/src/hash_local.c b/bsl/hash/src/hash_local.c new file mode 100644 index 00000000..98fb21e4 --- /dev/null +++ b/bsl/hash/src/hash_local.c @@ -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 */ diff --git a/bsl/hash/src/hash_local.h b/bsl/hash/src/hash_local.h new file mode 100644 index 00000000..28b6a0d6 --- /dev/null +++ b/bsl/hash/src/hash_local.h @@ -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 +#include +#include +#include + +#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 */ \ No newline at end of file diff --git a/bsl/hash/src/list_base.c b/bsl/hash/src/list_base.c new file mode 100644 index 00000000..d3ff6e22 --- /dev/null +++ b/bsl/hash/src/list_base.c @@ -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 +#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 */ diff --git a/bsl/include/bsl_binlog_id.h b/bsl/include/bsl_binlog_id.h new file mode 100644 index 00000000..1f94279a --- /dev/null +++ b/bsl/include/bsl_binlog_id.h @@ -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 diff --git a/bsl/include/bsl_bytes.h b/bsl/include/bsl_bytes.h new file mode 100644 index 00000000..8666c7d1 --- /dev/null +++ b/bsl/include/bsl_bytes.h @@ -0,0 +1,207 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef BSL_BYTES_H +#define BSL_BYTES_H + +#include + +#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 diff --git a/bsl/include/bsl_module_list.h b/bsl/include/bsl_module_list.h new file mode 100644 index 00000000..5d78640d --- /dev/null +++ b/bsl/include/bsl_module_list.h @@ -0,0 +1,118 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef BSL_MODULE_LIST_H +#define BSL_MODULE_LIST_H + +#include + +#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 \ No newline at end of file diff --git a/bsl/init/bsl_init.c b/bsl/init/bsl_init.c new file mode 100644 index 00000000..36fb5868 --- /dev/null +++ b/bsl/init/bsl_init.c @@ -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 */ diff --git a/bsl/list/include/bsl_list_internal.h b/bsl/list/include/bsl_list_internal.h new file mode 100644 index 00000000..2e1a5c69 --- /dev/null +++ b/bsl/list/include/bsl_list_internal.h @@ -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 diff --git a/bsl/list/src/bsl_list.c b/bsl/list/src/bsl_list.c new file mode 100644 index 00000000..0988f993 --- /dev/null +++ b/bsl/list/src/bsl_list.c @@ -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 */ diff --git a/bsl/list/src/bsl_list_ex.c b/bsl/list/src/bsl_list_ex.c new file mode 100644 index 00000000..d75cda21 --- /dev/null +++ b/bsl/list/src/bsl_list_ex.c @@ -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 */ diff --git a/bsl/list/src/bsl_list_internal.c b/bsl/list/src/bsl_list_internal.c new file mode 100644 index 00000000..c4e96748 --- /dev/null +++ b/bsl/list/src/bsl_list_internal.c @@ -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 +#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 */ diff --git a/bsl/log/include/bsl_log_internal.h b/bsl/log/include/bsl_log_internal.h new file mode 100644 index 00000000..db9d6891 --- /dev/null +++ b/bsl/log/include/bsl_log_internal.h @@ -0,0 +1,110 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef BSL_LOG_INTERNAL_H +#define BSL_LOG_INTERNAL_H + +#include +#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 diff --git a/bsl/log/src/log.c b/bsl/log/src/log.c new file mode 100644 index 00000000..5452e861 --- /dev/null +++ b/bsl/log/src/log.c @@ -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 +#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 */ diff --git a/bsl/obj/include/bsl_obj_internal.h b/bsl/obj/include/bsl_obj_internal.h new file mode 100644 index 00000000..a2b7f903 --- /dev/null +++ b/bsl/obj/include/bsl_obj_internal.h @@ -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 \ No newline at end of file diff --git a/bsl/obj/src/bsl_cid_op.c b/bsl/obj/src/bsl_cid_op.c new file mode 100644 index 00000000..15cf7eb9 --- /dev/null +++ b/bsl/obj/src/bsl_cid_op.c @@ -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 +#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 \ No newline at end of file diff --git a/bsl/obj/src/bsl_obj.c b/bsl/obj/src/bsl_obj.c new file mode 100644 index 00000000..41d2988b --- /dev/null +++ b/bsl/obj/src/bsl_obj.c @@ -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 +#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 diff --git a/bsl/pem/include/bsl_pem_internal.h b/bsl/pem/include/bsl_pem_internal.h new file mode 100644 index 00000000..a78b21d8 --- /dev/null +++ b/bsl/pem/include/bsl_pem_internal.h @@ -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 + +#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 */ \ No newline at end of file diff --git a/bsl/pem/src/bsl_pem.c b/bsl/pem/src/bsl_pem.c new file mode 100644 index 00000000..0f85dcbf --- /dev/null +++ b/bsl/pem/src/bsl_pem.c @@ -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 +#include +#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 */ diff --git a/bsl/pem/src/bsl_pem_local.h b/bsl/pem/src/bsl_pem_local.h new file mode 100644 index 00000000..55c83979 --- /dev/null +++ b/bsl/pem/src/bsl_pem_local.h @@ -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 + +#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 diff --git a/bsl/sal/include/sal_atomic.h b/bsl/sal/include/sal_atomic.h new file mode 100644 index 00000000..f893d92f --- /dev/null +++ b/bsl/sal/include/sal_atomic.h @@ -0,0 +1,135 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef SAL_ATOMIC_H +#define SAL_ATOMIC_H + +#include +#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 +#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 diff --git a/bsl/sal/include/sal_file.h b/bsl/sal/include/sal_file.h new file mode 100644 index 00000000..6770fa96 --- /dev/null +++ b/bsl/sal/include/sal_file.h @@ -0,0 +1,61 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef SAL_FILE_H +#define SAL_FILE_H + +#include + +#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 diff --git a/bsl/sal/include/sal_net.h b/bsl/sal/include/sal_net.h new file mode 100644 index 00000000..38c62123 --- /dev/null +++ b/bsl/sal/include/sal_net.h @@ -0,0 +1,53 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef SAL_NET_H +#define SAL_NET_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_SAL_NET + +#include +#include +#include + +#ifdef HITLS_BSL_SAL_LINUX +#include +#include +#endif + +#ifdef HITLS_BSL_UIO_SCTP +#include +#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 diff --git a/bsl/sal/include/sal_time.h b/bsl/sal/include/sal_time.h new file mode 100644 index 00000000..bc05691c --- /dev/null +++ b/bsl/sal/include/sal_time.h @@ -0,0 +1,100 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef SAL_TIME_H +#define SAL_TIME_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_SAL_TIME + +#include +#include +#include +#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 diff --git a/bsl/sal/src/linux/linux_sal_file.c b/bsl/sal/src/linux/linux_sal_file.c new file mode 100644 index 00000000..786aa9a8 --- /dev/null +++ b/bsl/sal/src/linux/linux_sal_file.c @@ -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 +#include +#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 diff --git a/bsl/sal/src/linux/linux_sal_lockimpl.c b/bsl/sal/src/linux/linux_sal_lockimpl.c new file mode 100644 index 00000000..ea449b0a --- /dev/null +++ b/bsl/sal/src/linux/linux_sal_lockimpl.c @@ -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 +#include +#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 diff --git a/bsl/sal/src/linux/linux_sal_mem.c b/bsl/sal/src/linux/linux_sal_mem.c new file mode 100644 index 00000000..40339fcb --- /dev/null +++ b/bsl/sal/src/linux/linux_sal_mem.c @@ -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 +#include + +void *SAL_MallocImpl(uint32_t size) +{ + return malloc(size); +} + +void SAL_FreeImpl(void *value) +{ + if (value == NULL) { + return; + } + free(value); +} + +#endif diff --git a/bsl/sal/src/linux/linux_sal_net.c b/bsl/sal/src/linux/linux_sal_net.c new file mode 100644 index 00000000..755ff333 --- /dev/null +++ b/bsl/sal/src/linux/linux_sal_net.c @@ -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 +#include +#include +#include + +#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 diff --git a/bsl/sal/src/linux/linux_sal_str.c b/bsl/sal/src/linux/linux_sal_str.c new file mode 100644 index 00000000..8fea8d4b --- /dev/null +++ b/bsl/sal/src/linux/linux_sal_str.c @@ -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 +#include +#include + +#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 diff --git a/bsl/sal/src/linux/linux_time_impl.c b/bsl/sal/src/linux/linux_time_impl.c new file mode 100644 index 00000000..2110c89c --- /dev/null +++ b/bsl/sal/src/linux/linux_time_impl.c @@ -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 +#include +#include +#include +#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 diff --git a/bsl/sal/src/sal_atomic.c b/bsl/sal/src/sal_atomic.c new file mode 100644 index 00000000..c39f9d52 --- /dev/null +++ b/bsl/sal/src/sal_atomic.c @@ -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); +} diff --git a/bsl/sal/src/sal_ctrl.c b/bsl/sal/src/sal_ctrl.c new file mode 100644 index 00000000..06ce4f64 --- /dev/null +++ b/bsl/sal/src/sal_ctrl.c @@ -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; + } +} diff --git a/bsl/sal/src/sal_file.c b/bsl/sal/src/sal_file.c new file mode 100644 index 00000000..afc68f99 --- /dev/null +++ b/bsl/sal/src/sal_file.c @@ -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 +#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 diff --git a/bsl/sal/src/sal_fileimpl.h b/bsl/sal/src/sal_fileimpl.h new file mode 100644 index 00000000..5070d397 --- /dev/null +++ b/bsl/sal/src/sal_fileimpl.h @@ -0,0 +1,52 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef SAL_FILEIMPL_H +#define SAL_FILEIMPL_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_SAL_FILE + +#include +#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 diff --git a/bsl/sal/src/sal_lockimpl.h b/bsl/sal/src/sal_lockimpl.h new file mode 100644 index 00000000..c3044e80 --- /dev/null +++ b/bsl/sal/src/sal_lockimpl.h @@ -0,0 +1,49 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef SAL_LOCKIMPL_H +#define SAL_LOCKIMPL_H + +#include +#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 diff --git a/bsl/sal/src/sal_mem.c b/bsl/sal/src/sal_mem.c new file mode 100644 index 00000000..a33ff868 --- /dev/null +++ b/bsl/sal/src/sal_mem.c @@ -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 +#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 diff --git a/bsl/sal/src/sal_memimpl.h b/bsl/sal/src/sal_memimpl.h new file mode 100644 index 00000000..1136427d --- /dev/null +++ b/bsl/sal/src/sal_memimpl.h @@ -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 + +#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 diff --git a/bsl/sal/src/sal_net.c b/bsl/sal/src/sal_net.c new file mode 100644 index 00000000..249d61a9 --- /dev/null +++ b/bsl/sal/src/sal_net.c @@ -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 +#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 diff --git a/bsl/sal/src/sal_netimpl.h b/bsl/sal/src/sal_netimpl.h new file mode 100644 index 00000000..5049fd42 --- /dev/null +++ b/bsl/sal/src/sal_netimpl.h @@ -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 +#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 diff --git a/bsl/sal/src/sal_threadlock.c b/bsl/sal/src/sal_threadlock.c new file mode 100644 index 00000000..07f71311 --- /dev/null +++ b/bsl/sal/src/sal_threadlock.c @@ -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 +#include + +#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; +} diff --git a/bsl/sal/src/sal_time.c b/bsl/sal/src/sal_time.c new file mode 100644 index 00000000..3bbfa68e --- /dev/null +++ b/bsl/sal/src/sal_time.c @@ -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 */ diff --git a/bsl/sal/src/sal_time_impl.h b/bsl/sal/src/sal_time_impl.h new file mode 100644 index 00000000..929f8489 --- /dev/null +++ b/bsl/sal/src/sal_time_impl.h @@ -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 +#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 + diff --git a/bsl/tlv/include/tlv.h b/bsl/tlv/include/tlv.h new file mode 100644 index 00000000..78ac740e --- /dev/null +++ b/bsl/tlv/include/tlv.h @@ -0,0 +1,90 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef TLV_H +#define TLV_H + +#include "hitls_build.h" +#ifdef HITLS_BSL_TLV + +#include + +#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 diff --git a/bsl/tlv/src/tlv.c b/bsl/tlv/src/tlv.c new file mode 100644 index 00000000..48aa48cb --- /dev/null +++ b/bsl/tlv/src/tlv.c @@ -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 +#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 */ diff --git a/bsl/uio/include/uio_base.h b/bsl/uio/include/uio_base.h new file mode 100644 index 00000000..d56a6904 --- /dev/null +++ b/bsl/uio/include/uio_base.h @@ -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 + diff --git a/bsl/uio/src/uio_abstraction.c b/bsl/uio/src/uio_abstraction.c new file mode 100644 index 00000000..09726fbd --- /dev/null +++ b/bsl/uio/src/uio_abstraction.c @@ -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 */ diff --git a/bsl/uio/src/uio_abstraction.h b/bsl/uio/src/uio_abstraction.h new file mode 100644 index 00000000..f13f24f4 --- /dev/null +++ b/bsl/uio/src/uio_abstraction.h @@ -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 + diff --git a/bsl/uio/src/uio_buffer.c b/bsl/uio/src/uio_buffer.c new file mode 100644 index 00000000..6a83faae --- /dev/null +++ b/bsl/uio/src/uio_buffer.c @@ -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 */ diff --git a/bsl/uio/src/uio_sctp.c b/bsl/uio/src/uio_sctp.c new file mode 100644 index 00000000..1f6e88c7 --- /dev/null +++ b/bsl/uio/src/uio_sctp.c @@ -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 +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "sal_net.h" +#include "uio_base.h" +#include "uio_abstraction.h" + +#define SCTP_DATA_CHUNK_TYPE 0x00 +#define SCTP_FORWARD_TSN_CHUNK_TYPE 0xc0 +#define SCTP_GAUTH_CHUNKS_SIZE 256u +#define SCTP_SHARED_AUTHKEY_LEN 64u +#define SCTP_SHARE_AUTHKEY_ID_MAX 65535 + +typedef struct { + bool peerAuthed; /* Whether auth is enabled at the peer end */ + /* Whether authkey is added: If authkey is added but not active, success is returned when authkey is added again. */ + bool isAddAuthkey; + bool reverse[2]; /* Four-byte alignment is reserved. */ + + uint16_t sendAppStreamId; /* ID of the stream sent by the user-specified app. */ + uint16_t prevShareKeyId; + uint16_t shareKeyId; + uint16_t reverse1; /* Four-byte alignment is reserved. */ + + int32_t fd; // Network socket + uint8_t ip[IP_ADDR_MAX_LEN]; + uint32_t ipLen; + bool isAppMsg; // whether the message sent is the app message +} SctpParameters; + +static int32_t SctpNew(BSL_UIO *uio) +{ + SctpParameters *parameters = (SctpParameters *)BSL_SAL_Calloc(1u, sizeof(SctpParameters)); + if (parameters == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05031, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: sctp param malloc fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + return BSL_UIO_FAIL; + } + parameters->fd = -1; + uio->ctx = parameters; + uio->ctxLen = sizeof(SctpParameters); + // Specifies whether to be closed by uio when setting fd. + // The default value of init is 0. Set the value of init to 1 after the fd is set. + return BSL_SUCCESS; +} + +static int32_t SctpDestroy(BSL_UIO *uio) +{ + if (uio == NULL) { + return BSL_SUCCESS; + } + SctpParameters *ctx = BSL_UIO_GetCtx(uio); + uio->init = 0; + if (ctx != NULL) { + if (BSL_UIO_GetIsUnderlyingClosedByUio(uio) && ctx->fd != -1) { + (void)BSL_SAL_SockClose(ctx->fd); + } + BSL_SAL_FREE(ctx); + BSL_UIO_SetCtx(uio, NULL); + } + return BSL_SUCCESS; +} + +static int32_t BslSctpGetSendStreamId(const BSL_UIO *uio, void *parg, int32_t larg) +{ + SctpParameters *parameters = uio->ctx; + if (larg != (int32_t)sizeof(uint16_t) || parg == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05046, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: Sctp input err.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT); + return BSL_NULL_INPUT; + } + uint16_t *sendStreamId = (uint16_t *)parg; + if (parameters->isAppMsg) { + *sendStreamId = parameters->sendAppStreamId; + } else { + *sendStreamId = 0; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05047, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: User Get SCTP send StreamId [%hu].", *sendStreamId, 0, 0, 0); + return BSL_SUCCESS; +} + +int32_t BslSctpSetAppStreamId(SctpParameters *parameters, const void *parg, int32_t larg) +{ + if (larg != (int32_t)sizeof(uint16_t) || parg == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05048, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: Sctp input err.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT); + return BSL_NULL_INPUT; + } + parameters->sendAppStreamId = *(const uint16_t *)parg; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05055, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: User set SCTP AppStreamId [%hu].", parameters->sendAppStreamId, 0, 0, 0); + return BSL_SUCCESS; +} + +static int32_t BslSctpSetPeerIpAddr(SctpParameters *parameters, const uint8_t *addr, uint32_t size) +{ + if (addr == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05049, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: NULL error.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT); + return BSL_NULL_INPUT; + } + + if (size != IP_ADDR_V4_LEN && size != IP_ADDR_V6_LEN) { + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05050, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: Set peer ip address input error.", 0, 0, 0, 0); + return BSL_UIO_FAIL; + } + + (void)memcpy_s(parameters->ip, sizeof(parameters->ip), addr, size); + parameters->ipLen = size; + return BSL_SUCCESS; +} + +static int32_t BslSctpGetPeerIpAddr(SctpParameters *parameters, void *parg, int32_t larg) +{ + BSL_UIO_CtrlGetPeerIpAddrParam *para = (BSL_UIO_CtrlGetPeerIpAddrParam *)parg; + if (parg == NULL || larg != (int32_t)sizeof(BSL_UIO_CtrlGetPeerIpAddrParam) || + para->addr == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05051, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: Get peer ip address input error.", 0, 0, 0, 0); + return BSL_NULL_INPUT; + } + + /* Check whether the IP address is set. */ + if (parameters->ipLen == 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05052, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: Ip address is already existed.", 0, 0, 0, 0); + return BSL_UIO_FAIL; + } + + if (para->size < parameters->ipLen) { + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05053, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: Ip address length err.", 0, 0, 0, 0); + return BSL_UIO_FAIL; + } + + (void)memcpy_s(para->addr, para->size, parameters->ip, parameters->ipLen); + para->size = parameters->ipLen; + return BSL_SUCCESS; +} + +static int32_t BslSctpSetFd(BSL_UIO *uio, int32_t size, const int32_t *fd) +{ + if (fd == NULL) { + BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT); + return BSL_NULL_INPUT; + } + if (size != (int32_t)sizeof(*fd)) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + return BSL_INVALID_ARG; + } + SctpParameters *sctpCtx = BSL_UIO_GetCtx(uio); + if (sctpCtx == NULL) { + BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT); + return BSL_NULL_INPUT; + } + if (sctpCtx->fd != -1) { + if (BSL_UIO_GetIsUnderlyingClosedByUio(uio)) { + (void)BSL_SAL_SockClose(sctpCtx->fd); + } + } + sctpCtx->fd = *fd; + uio->init = 1; + return BSL_SUCCESS; +} + +static int32_t BslSctpGetFd(SctpParameters *parameters, void *parg, int32_t larg) +{ + if (larg != (int32_t)sizeof(int32_t) || parg == NULL) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05054, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get fd handle invalid parameter.", 0, 0, 0, 0); + return BSL_INVALID_ARG; + } + *(int32_t *)parg = parameters->fd; + return BSL_SUCCESS; +} + +static int32_t BslSctpMaskAppMsg(SctpParameters *parameters, void *parg, int32_t larg) +{ + if (parg == NULL || larg != sizeof(bool)) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05030, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "mask app msg failed", 0, 0, 0, 0); + return BSL_INVALID_ARG; + } + parameters->isAppMsg = *(bool *)parg; + return BSL_SUCCESS; +} + +static bool BslSctpCheckPeerAuth(BSL_UIO *uio, void *parg, int32_t larg) +{ + if (parg == NULL || larg != sizeof(bool)) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05061, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check peer auth failed", 0, 0, 0, 0); + return BSL_INVALID_ARG; + } + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + + uint32_t optLen = sizeof(struct sctp_authchunks) + SCTP_GAUTH_CHUNKS_SIZE; + struct sctp_authchunks *auth = (struct sctp_authchunks*)BSL_SAL_Calloc(1u, optLen); + if (auth == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = BSL_SAL_GetSockopt(fd, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, auth, &optLen); + if (ret != BSL_SUCCESS) { + BSL_SAL_Free(auth); + BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_GETSOCKOPT); + return BSL_SAL_ERR_NET_GETSOCKOPT; + } + bool dataChunkFlag = false; + bool forwardTsnChunkFlag = false; + for (uint32_t i = 0; i < auth->gauth_number_of_chunks; i++) { + if (auth->gauth_chunks[i] == SCTP_DATA_CHUNK_TYPE) { + dataChunkFlag = true; + } else if (auth->gauth_chunks[i] == SCTP_FORWARD_TSN_CHUNK_TYPE) { + forwardTsnChunkFlag = true; + } + } + if (dataChunkFlag && forwardTsnChunkFlag) { + *(bool *)parg = true; + } + BSL_SAL_Free(auth); + return BSL_SUCCESS; +} + +static int32_t AddAuthKey(BSL_UIO *uio, SctpParameters *parameters, struct sctp_authkey *auth, socklen_t optLen, + uint16_t prevShareKeyId) +{ + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + parameters->shareKeyId = prevShareKeyId; + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + int32_t ret = BSL_SAL_SetSockopt(fd, IPPROTO_SCTP, SCTP_AUTH_KEY, auth, optLen); + if (ret != BSL_SUCCESS) { + parameters->shareKeyId = prevShareKeyId; + BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_SETSOCKOPT); + return BSL_SAL_ERR_NET_SETSOCKOPT; + } + parameters->isAddAuthkey = true; + parameters->prevShareKeyId = prevShareKeyId; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05035, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: SCTP Set auth key(id:%u) success.", parameters->shareKeyId, 0, 0, 0); + return BSL_SUCCESS; +} + +static int32_t BslSctpAddAuthKey(BSL_UIO *uio, void *parg, int32_t larg) +{ + if (parg == NULL || larg != sizeof(BSL_UIO_SctpAuthKey)) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05062, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "add auth key failed", 0, 0, 0, 0); + return BSL_INVALID_ARG; + } + BSL_UIO_SctpAuthKey *key = (BSL_UIO_SctpAuthKey *)parg; + SctpParameters *parameters = (SctpParameters *)BSL_UIO_GetCtx(uio); + + if (parameters->isAddAuthkey) { + return BSL_SUCCESS; + } + + uint16_t prevShareKeyId = parameters->shareKeyId; + if (parameters->shareKeyId >= SCTP_SHARE_AUTHKEY_ID_MAX) { + parameters->shareKeyId = 1; + } else { + parameters->shareKeyId++; + } + key->shareKeyId = parameters->shareKeyId; + const uint8_t *authKey = key->authKey; + uint16_t size = key->authKeySize; + if (size != SCTP_SHARED_AUTHKEY_LEN) { + parameters->shareKeyId = prevShareKeyId; + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + socklen_t optLen = sizeof(struct sctp_authkey) + SCTP_SHARED_AUTHKEY_LEN * sizeof(uint8_t); + struct sctp_authkey *auth = (struct sctp_authkey *)BSL_SAL_Calloc(1u, optLen); + if (auth == NULL) { + parameters->shareKeyId = prevShareKeyId; + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + auth->sca_keylength = SCTP_SHARED_AUTHKEY_LEN; + auth->sca_keynumber = key->shareKeyId; + (void)memcpy_s(&auth->sca_key[0], SCTP_SHARED_AUTHKEY_LEN, authKey, size); + int32_t ret = AddAuthKey(uio, parameters, auth, optLen, prevShareKeyId); + BSL_SAL_Free(auth); + return ret; +} + +static int32_t CheckArgsAvalid(const void *parg, int32_t larg) +{ + if (parg == NULL || larg != sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05063, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid args", 0, 0, 0, 0); + return BSL_INVALID_ARG; + } + return BSL_SUCCESS; +} + +static int32_t BslSctpActiveAuthKey(BSL_UIO *uio, void *parg, int32_t larg) +{ + int32_t ret = CheckArgsAvalid(parg, larg); + if (ret != BSL_SUCCESS) { + return ret; + } + SctpParameters *parameters = BSL_UIO_GetCtx(uio); + uint16_t shareKeyId = *(uint16_t*)parg; + /* Active shared key id */ + struct sctp_authkeyid authKeyId = {0}; + authKeyId.scact_keynumber = shareKeyId; + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + ret = BSL_SAL_SetSockopt(fd, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authKeyId, sizeof(struct sctp_authkeyid)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_SETSOCKOPT); + return BSL_SAL_ERR_NET_SETSOCKOPT; + } + parameters->isAddAuthkey = false; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05038, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Uio: SCTP active auth key(id:%u) success.", parameters->shareKeyId, 0, 0, 0); + + return BSL_SUCCESS; +} + +static int32_t BslSctpDelAuthKey(BSL_UIO *uio, void *parg, int32_t larg) +{ + int32_t ret = CheckArgsAvalid(parg, larg); + if (ret != BSL_SUCCESS) { + return ret; + } + uint16_t delShareKeyId = *(uint16_t*)parg; + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + /* Delete old sharekey */ + struct sctp_authkeyid authKeyId = {0}; + authKeyId.scact_keynumber = delShareKeyId; + ret = BSL_SAL_SetSockopt(fd, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, &authKeyId, sizeof(struct sctp_authkeyid)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_SETSOCKOPT); + return BSL_SAL_ERR_NET_SETSOCKOPT; + } + return BSL_SUCCESS; +} + +static int32_t BslSctpIsSndBuffEmpty(BSL_UIO *uio, void *parg, int32_t larg) +{ + if (parg == NULL || larg != sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05064, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sctp status failed", 0, 0, 0, 0); + return BSL_INVALID_ARG; + } + + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + + struct sctp_status status = {0}; + uint32_t statusLen = sizeof(status); + int32_t ret = BSL_SAL_GetSockopt(fd, IPPROTO_SCTP, SCTP_STATUS, &status, &statusLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_GETSOCKOPT); + return BSL_SAL_ERR_NET_GETSOCKOPT; + } + + uint8_t *isEmpty = (uint8_t *)parg; + *isEmpty = false; + + if (status.sstat_unackdata == 0) { + *isEmpty = true; + } + + return BSL_SUCCESS; +} + +int32_t SctpCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg) +{ + if (uio->ctx == NULL) { + return BSL_NULL_INPUT; + } + SctpParameters *parameters = BSL_UIO_GetCtx(uio); + switch (cmd) { + case BSL_UIO_SET_PEER_IP_ADDR: + return BslSctpSetPeerIpAddr(parameters, parg, (uint32_t)larg); + case BSL_UIO_GET_PEER_IP_ADDR: + return BslSctpGetPeerIpAddr(parameters, parg, larg); + case BSL_UIO_SCTP_GET_SEND_STREAM_ID: + return BslSctpGetSendStreamId(uio, parg, larg); + case BSL_UIO_SCTP_SET_APP_STREAM_ID: + return BslSctpSetAppStreamId(parameters, parg, larg); + case BSL_UIO_SET_FD: + return BslSctpSetFd(uio, larg, parg); + case BSL_UIO_GET_FD: + return BslSctpGetFd(parameters, parg, larg); + case BSL_UIO_SCTP_MARK_APP_MESSAGE: + return BslSctpMaskAppMsg(parameters, parg, larg); + case BSL_UIO_SCTP_CHECK_PEER_AUTH: + return BslSctpCheckPeerAuth(uio, parg, larg); + case BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY: + return BslSctpAddAuthKey(uio, parg, larg); + case BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY: + return BslSctpActiveAuthKey(uio, ¶meters->shareKeyId, sizeof(parameters->shareKeyId)); + case BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY: + return BslSctpDelAuthKey(uio, ¶meters->prevShareKeyId, sizeof(parameters->shareKeyId)); + case BSL_UIO_SCTP_SND_BUFF_IS_EMPTY: + return BslSctpIsSndBuffEmpty(uio, parg, larg); + default: + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + return BSL_UIO_FAIL; + } +} + +static int32_t SctpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + /* set flags */ + const uint32_t flags = SCTP_SACK_IMMEDIATELY; + uint16_t sendStreamId = 0; + int32_t ret = BSL_UIO_Ctrl(uio, BSL_UIO_SCTP_GET_SEND_STREAM_ID, sizeof(sendStreamId), &sendStreamId); + if (ret != BSL_SUCCESS) { + return ret; + } + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + ret = sctp_sendmsg(fd, buf, len, NULL, 0, 0, flags, sendStreamId, 0, 0); + if (ret <= 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + *writeLen = ret; + + return BSL_SUCCESS; +} + +static int32_t SctpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + *readLen = 0; + SctpParameters *parameters = BSL_UIO_GetCtx(uio); + if (parameters == NULL) { + BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT); + return BSL_NULL_INPUT; + } + + if (BSL_UIO_Ctrl(uio, BSL_UIO_SCTP_CHECK_PEER_AUTH, sizeof(parameters->peerAuthed), ¶meters->peerAuthed) != + BSL_SUCCESS || + parameters->peerAuthed == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05032, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Uio:Check SCTP Peer Auth ERROR.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + + struct sctp_sndrcvinfo sinfo; + int32_t flags = 0; + int32_t fd = BSL_UIO_GetFd(uio); + if (fd < 0) { + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + int32_t ret = sctp_recvmsg(fd, buf, len, NULL, NULL, &sinfo, &flags); + if (ret <= 0) { + if (UioIsNonFatalErr(errno) == true) { + return BSL_SUCCESS; + } + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + return BSL_UIO_IO_EXCEPTION; + } + + *readLen = ret; + return BSL_SUCCESS; +} + +const BSL_UIO_Method *BSL_UIO_SctpMethod(void) +{ + static const BSL_UIO_Method method = { + BSL_UIO_SCTP, + SctpWrite, + SctpRead, + SctpCtrl, + NULL, + NULL, + SctpNew, + SctpDestroy + }; + return &method; +} +#endif /* HITLS_BSL_UIO_SCTP */ diff --git a/bsl/uio/src/uio_sctp.h b/bsl/uio/src/uio_sctp.h new file mode 100644 index 00000000..96b874b3 --- /dev/null +++ b/bsl/uio/src/uio_sctp.h @@ -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 + diff --git a/bsl/uio/src/uio_tcp.c b/bsl/uio/src/uio_tcp.c new file mode 100644 index 00000000..79f963d8 --- /dev/null +++ b/bsl/uio/src/uio_tcp.c @@ -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 + +#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 */ diff --git a/bsl/uio/src/uio_tcp.h b/bsl/uio/src/uio_tcp.h new file mode 100644 index 00000000..79eadcc4 --- /dev/null +++ b/bsl/uio/src/uio_tcp.h @@ -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 diff --git a/bsl/usrdata/src/usr_data.c b/bsl/usrdata/src/usr_data.c new file mode 100644 index 00000000..baa61445 --- /dev/null +++ b/bsl/usrdata/src/usr_data.c @@ -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 +#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 */ diff --git a/config/json/compile.json b/config/json/compile.json new file mode 100644 index 00000000..acd51585 --- /dev/null +++ b/config/json/compile.json @@ -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": [] + } +} diff --git a/config/json/complete_options.json b/config/json/complete_options.json new file mode 100644 index 00000000..bc2c5e7b --- /dev/null +++ b/config/json/complete_options.json @@ -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" + ] + } +} diff --git a/config/json/feature.json b/config/json/feature.json new file mode 100644 index 00000000..c1aa32c6 --- /dev/null +++ b/config/json/feature.json @@ -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"] + } + } + } +} diff --git a/config/macro_config/hitls_build.h b/config/macro_config/hitls_build.h new file mode 100644 index 00000000..67ae12c4 --- /dev/null +++ b/config/macro_config/hitls_build.h @@ -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 */ diff --git a/config/macro_config/hitls_config_check.h b/config/macro_config/hitls_config_check.h new file mode 100644 index 00000000..d0cbaa75 --- /dev/null +++ b/config/macro_config/hitls_config_check.h @@ -0,0 +1,52 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +/* Check the dependency of the configuration features. The check rules are as follows: + * Non-deterministic feature dependency needs to be checked. + * For example, feature a depends on feature b or c: + * if feature a is defined, at least one of feature b and c must be defined. + */ + +#ifndef HITLS_CONFIG_CHECK_H +#define HITLS_CONFIG_CHECK_H + +#if defined(HITLS_BSL_SAL_MEM) || defined(HITLS_BSL_SAL_LOCK) || defined(HITLS_BSL_SAL_THREAD) || \ + defined(HITLS_BSL_SAL_TIME) || defined(HITLS_BSL_SAL_FILE) || defined(HITLS_BSL_SAL_NET) || \ + defined(HITLS_BSL_SAL_STR) + #ifndef HITLS_BSL_SAL_LINUX + #error "[HiTLS] sal_* only work with HITLS_BSL_SAL_LINUX." + #endif +#endif + +#if defined(HITLS_CRYPTO_HMAC) && !defined(HITLS_CRYPTO_MD) +#error "[HiTLS] The hmac must work with hash." +#endif + +#if defined(HITLS_CRYPTO_DRBG_HASH) && !defined(HITLS_CRYPTO_MD) +#error "[HiTLS] The drbg_hash must work with hash." +#endif + +#if defined(HITLS_CRYPTO_ENTROPY) && !defined(HITLS_CRYPTO_DRBG) +#error "[HiTLS] The entropy must work with at leaset one drbg algorithm." +#endif + +#if defined(HITLS_CRYPTO_PKEY) && !defined(HITLS_CRYPTO_MD) +#error "[HiTLS] The pkey must work with hash." +#endif + +#if defined(HITLS_CRYPTO_BN) && !(defined(HITLS_THIRTY_TWO_BITS) || defined(HITLS_SIXTY_FOUR_BITS)) +#error "[HiTLS] To use bn, the number of system bits must be specified first." +#endif + +#endif /* HITLS_CONFIG_CHECK_H */ diff --git a/config/macro_config/hitls_config_layer.h b/config/macro_config/hitls_config_layer.h new file mode 100644 index 00000000..9dea330b --- /dev/null +++ b/config/macro_config/hitls_config_layer.h @@ -0,0 +1,429 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +/* Derivation of configuration features. + * The derivation type (rule) and sequence are as follows: + * 1. Parent features derive child features. + * 2. Derive the features of dependencies. + * For example, if feature a depends on features b and c, you need to derive features b and c. + * 3. Child features derive parent features. + * The high-level interfaces of the crypto module is controlled by the parent feature macro, + * if there is no parent feature, such interfaces will be unavailable. + */ + +#ifndef HITLS_CONFIG_LAYER_H +#define HITLS_CONFIG_LAYER_H + +/* BSL_INIT */ +#if defined(HITLS_CRYPTO_EAL) && !defined(HITLS_BSL_INIT) + #define HITLS_BSL_INIT +#endif + +#if defined(HITLS_BSL_INIT) && !defined(HITLS_BSL_ERR) + #define HITLS_BSL_ERR +#endif + +/* BSL_UIO */ +/* Derive the child-features of uio. */ +#ifdef HITLS_BSL_UIO + #ifndef HITLS_BSL_UIO_PLT + #define HITLS_BSL_UIO_PLT + #endif + #ifndef HITLS_BSL_UIO_BUFFER + #define HITLS_BSL_UIO_BUFFER + #endif + #ifndef HITLS_BSL_UIO_SCTP + #define HITLS_BSL_UIO_SCTP + #endif + #ifndef HITLS_BSL_UIO_TCP + #define HITLS_BSL_UIO_TCP + #endif +#endif + +/* Derive the dependency features of uio_tcp and uio_sctp. */ +#if defined(HITLS_BSL_UIO_TCP) || defined(HITLS_BSL_UIO_SCTP) + #ifndef HITLS_BSL_SAL_NET + #define HITLS_BSL_SAL_NET + #endif +#endif + +/* Derive parent feature from child features. */ +#if defined(HITLS_BSL_UIO_BUFFER) || defined(HITLS_BSL_UIO_SCTP) || defined(HITLS_BSL_UIO_TCP) + #ifndef HITLS_BSL_UIO_PLT + #define HITLS_BSL_UIO_PLT + #endif +#endif + +/* KDF */ +#ifdef HITLS_CRYPTO_KDF + #ifndef HITLS_CRYPTO_PBKDF2 + #define HITLS_CRYPTO_PBKDF2 + #endif + #ifndef HITLS_CRYPTO_HKDF + #define HITLS_CRYPTO_HKDF + #endif + #ifndef HITLS_CRYPTO_KDFTLS12 + #define HITLS_CRYPTO_KDFTLS12 + #endif + #ifndef HITLS_CRYPTO_SCRYPT + #define HITLS_CRYPTO_SCRYPT + #endif +#endif + +#ifdef HITLS_CRYPTO_SCRYPT + #ifndef HITLS_CRYPTO_SHA256 + #define HITLS_CRYPTO_SHA256 + #endif + #ifndef HITLS_CRYPTO_PBKDF2 + #define HITLS_CRYPTO_PBKDF2 + #endif +#endif + +#if defined(HITLS_CRYPTO_PBKDF2) || defined(HITLS_CRYPTO_HKDF) || defined(HITLS_CRYPTO_KDFTLS12) || \ + defined(HITLS_CRYPTO_SCRYPT) + #ifndef HITLS_CRYPTO_KDF + #define HITLS_CRYPTO_KDF + #endif +#endif + +#if defined(HITLS_CRYPTO_KDF) && !defined(HITLS_CRYPTO_HMAC) + #define HITLS_CRYPTO_HMAC +#endif + +/* DRBG */ +#ifdef HITLS_CRYPTO_DRBG + #ifndef HITLS_CRYPTO_DRBG_HASH + #define HITLS_CRYPTO_DRBG_HASH + #endif + #ifndef HITLS_CRYPTO_DRBG_HMAC + #define HITLS_CRYPTO_DRBG_HMAC + #endif + #ifndef HITLS_CRYPTO_DRBG_CTR + #define HITLS_CRYPTO_DRBG_CTR + #endif +#endif + +#if defined(HITLS_CRYPTO_DRBG_HMAC) && !defined(HITLS_CRYPTO_HMAC) + #define HITLS_CRYPTO_HMAC +#endif + +#if defined(HITLS_CRYPTO_DRBG_CTR) && !defined(HITLS_CRYPTO_AES) + #define HITLS_CRYPTO_AES +#endif + +#if defined(HITLS_CRYPTO_DRBG_HASH) || defined(HITLS_CRYPTO_DRBG_HMAC) || defined(HITLS_CRYPTO_DRBG_CTR) + #ifndef HITLS_CRYPTO_DRBG + #define HITLS_CRYPTO_DRBG + #endif +#endif + +/* MAC */ +#ifdef HITLS_CRYPTO_MAC + #ifndef HITLS_CRYPTO_HMAC + #define HITLS_CRYPTO_HMAC + #endif +#endif + +#if defined(HITLS_CRYPTO_HMAC) + #ifndef HITLS_CRYPTO_MAC + #define HITLS_CRYPTO_MAC + #endif +#endif + +/* CIPHER */ +#ifdef HITLS_CRYPTO_CIPHER + #ifndef HITLS_CRYPTO_AES + #define HITLS_CRYPTO_AES + #endif + #ifndef HITLS_CRYPTO_SM4 + #define HITLS_CRYPTO_SM4 + #endif + #ifndef HITLS_CRYPTO_CHACHA20 + #define HITLS_CRYPTO_CHACHA20 + #endif +#endif + +#if defined(HITLS_CRYPTO_CHACHA20) && !defined(HITLS_CRYPTO_CHACHA20POLY1305) + #define HITLS_CRYPTO_CHACHA20POLY1305 +#endif + +#if defined(HITLS_CRYPTO_AES) || defined(HITLS_CRYPTO_SM4) || defined(HITLS_CRYPTO_CHACHA20) + #ifndef HITLS_CRYPTO_CIPHER + #define HITLS_CRYPTO_CIPHER + #endif +#endif + +/* MODES */ +#ifdef HITLS_CRYPTO_MODES + #ifndef HITLS_CRYPTO_CTR + #define HITLS_CRYPTO_CTR + #endif + #ifndef HITLS_CRYPTO_CBC + #define HITLS_CRYPTO_CBC + #endif + #ifndef HITLS_CRYPTO_GCM + #define HITLS_CRYPTO_GCM + #endif + #ifndef HITLS_CRYPTO_CCM + #define HITLS_CRYPTO_CCM + #endif + #ifndef HITLS_CRYPTO_XTS + #define HITLS_CRYPTO_XTS + #endif + #ifndef HITLS_CRYPTO_CFB + #define HITLS_CRYPTO_CFB + #endif + #ifndef HITLS_CRYPTO_OFB + #define HITLS_CRYPTO_OFB + #endif + #ifndef HITLS_CRYPTO_CHACHA20POLY1305 + #define HITLS_CRYPTO_CHACHA20POLY1305 + #endif +#endif + +#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_CBC) || defined(HITLS_CRYPTO_GCM) || \ + defined(HITLS_CRYPTO_CCM) || defined(HITLS_CRYPTO_XTS) || defined(HITLS_CRYPTO_CFB) || \ + defined(HITLS_CRYPTO_OFB) || defined(HITLS_CRYPTO_CHACHA20POLY1305) + #ifndef HITLS_CRYPTO_MODES + #define HITLS_CRYPTO_MODES + #endif +#endif + +/* PKEY */ +#ifdef HITLS_CRYPTO_PKEY + #ifndef HITLS_CRYPTO_ECC + #define HITLS_CRYPTO_ECC + #endif + #ifndef HITLS_CRYPTO_RSA + #define HITLS_CRYPTO_RSA + #endif + #ifndef HITLS_CRYPTO_DSA + #define HITLS_CRYPTO_DSA + #endif + #ifndef HITLS_CRYPTO_DH + #define HITLS_CRYPTO_DH + #endif + #ifndef HITLS_CRYPTO_ECDSA + #define HITLS_CRYPTO_ECDSA + #endif + #ifndef HITLS_CRYPTO_ECDH + #define HITLS_CRYPTO_ECDH + #endif + #ifndef HITLS_CRYPTO_SM2 + #define HITLS_CRYPTO_SM2 + #endif + #ifndef HITLS_CRYPTO_CURVE25519 + #define HITLS_CRYPTO_CURVE25519 + #endif + #ifndef HITLS_CRYPTO_PAILLIER + #define HITLS_CRYPTO_PAILLIER + #endif +#endif + +#ifdef HITLS_CRYPTO_ECC + #ifndef HITLS_CRYPTO_CURVE_NISTP224 + #define HITLS_CRYPTO_CURVE_NISTP224 + #endif + #ifndef HITLS_CRYPTO_CURVE_NISTP256 + #define HITLS_CRYPTO_CURVE_NISTP256 + #endif + #ifndef HITLS_CRYPTO_CURVE_NISTP384 + #define HITLS_CRYPTO_CURVE_NISTP384 + #endif + #ifndef HITLS_CRYPTO_CURVE_NISTP521 + #define HITLS_CRYPTO_CURVE_NISTP521 + #endif + #ifndef HITLS_CRYPTO_CURVE_BP256R1 + #define HITLS_CRYPTO_CURVE_BP256R1 + #endif + #ifndef HITLS_CRYPTO_CURVE_BP384R1 + #define HITLS_CRYPTO_CURVE_BP384R1 + #endif + #ifndef HITLS_CRYPTO_CURVE_BP512R1 + #define HITLS_CRYPTO_CURVE_BP512R1 + #endif + #ifndef HITLS_CRYPTO_CURVE_192WAPI + #define HITLS_CRYPTO_CURVE_192WAPI + #endif + #ifndef HITLS_CRYPTO_CURVE_SM2 + #define HITLS_CRYPTO_CURVE_SM2 + #endif + #ifndef HITLS_CRYPTO_CURVE_SM9 + #define HITLS_CRYPTO_CURVE_SM9 + #endif +#endif + +#if defined(HITLS_CRYPTO_CURVE_NISTP224) || defined(HITLS_CRYPTO_CURVE_NISTP256) || \ + defined(HITLS_CRYPTO_CURVE_NISTP384) || defined(HITLS_CRYPTO_CURVE_NISTP521) || \ + defined(HITLS_CRYPTO_CURVE_BP256R1) || defined(HITLS_CRYPTO_CURVE_BP384R1) || \ + defined(HITLS_CRYPTO_CURVE_BP512R1) || defined(HITLS_CRYPTO_CURVE_192WAPI) || \ + defined(HITLS_CRYPTO_CURVE_SM2) || defined(HITLS_CRYPTO_CURVE_SM9) + #ifndef HITLS_CRYPTO_ECC + #define HITLS_CRYPTO_ECC + #endif +#endif + +#ifdef HITLS_CRYPTO_CURVE25519 + #ifndef HITLS_CRYPTO_X25519 + #define HITLS_CRYPTO_X25519 + #endif + #ifndef HITLS_CRYPTO_ED25519 + #define HITLS_CRYPTO_ED25519 + #endif +#endif + +#if defined(HITLS_CRYPTO_ED25519) && !defined(HITLS_CRYPTO_SHA512) + #define HITLS_CRYPTO_SHA512 +#endif + +#if defined(HITLS_CRYPTO_X25519) || defined(HITLS_CRYPTO_ED25519) + #ifndef HITLS_CRYPTO_CURVE25519 + #define HITLS_CRYPTO_CURVE25519 + #endif +#endif + +#ifdef HITLS_CRYPTO_SM2 + #ifndef HITLS_CRYPTO_SM2_SIGN + #define HITLS_CRYPTO_SM2_SIGN + #endif + #ifndef HITLS_CRYPTO_SM2_CRYPT + #define HITLS_CRYPTO_SM2_CRYPT + #endif + #ifndef HITLS_CRYPTO_SM2_EXCH + #define HITLS_CRYPTO_SM2_EXCH + #endif +#endif + +#if defined(HITLS_CRYPTO_SM2_SIGN) || defined(HITLS_CRYPTO_SM2_CRYPT) || defined(HITLS_CRYPTO_SM2_EXCH) + #ifndef HITLS_CRYPTO_SM2 + #define HITLS_CRYPTO_SM2 + #endif +#endif + +#ifdef HITLS_CRYPTO_SM2 + #ifndef HITLS_CRYPTO_ENCODE + #define HITLS_CRYPTO_ENCODE + #endif + #ifndef HITLS_CRYPTO_SM3 + #define HITLS_CRYPTO_SM3 + #endif + #ifndef HITLS_CRYPTO_ECC + #define HITLS_CRYPTO_ECC + #endif +#endif + +#if defined(HITLS_CRYPTO_SM2) && !defined(HITLS_CRYPTO_CURVE_SM2) + #define HITLS_CRYPTO_CURVE_SM2 +#endif + +#if defined(HITLS_CRYPTO_ECDH) || defined(HITLS_CRYPTO_ECDSA) + #ifndef HITLS_CRYPTO_ECC + #define HITLS_CRYPTO_ECC + #endif +#endif + +#if defined(HITLS_CRYPTO_SM2) + #define HITLS_CRYPTO_CURVE_SM2 +#endif + +#if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_ECDSA) + #ifndef HITLS_CRYPTO_ENCODE + #define HITLS_CRYPTO_ENCODE + #endif +#endif + +#if defined(HITLS_CRYPTO_ECC) || defined(HITLS_CRYPTO_RSA) || defined(HITLS_CRYPTO_DSA)|| defined(HITLS_CRYPTO_DH) + #ifndef HITLS_CRYPTO_BN + #define HITLS_CRYPTO_BN + #endif +#endif + +#if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_CURVE25519) || defined(HITLS_CRYPTO_RSA) || \ + defined(HITLS_CRYPTO_DH) || defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_ECDH) || \ + defined(HITLS_CRYPTO_SM2) || defined(HITLS_CRYPTO_PAILLIER) + #ifndef HITLS_CRYPTO_PKEY + #define HITLS_CRYPTO_PKEY + #endif +#endif + +/* MD */ +#ifdef HITLS_CRYPTO_MD + #ifndef HITLS_CRYPTO_MD5 + #define HITLS_CRYPTO_MD5 + #endif + #ifndef HITLS_CRYPTO_SM3 + #define HITLS_CRYPTO_SM3 + #endif + #ifndef HITLS_CRYPTO_SHA1 + #define HITLS_CRYPTO_SHA1 + #endif + #ifndef HITLS_CRYPTO_SHA2 + #define HITLS_CRYPTO_SHA2 + #endif + #ifndef HITLS_CRYPTO_SHA3 + #define HITLS_CRYPTO_SHA3 + #endif +#endif + +#ifdef HITLS_CRYPTO_SHA2 + #ifndef HITLS_CRYPTO_SHA224 + #define HITLS_CRYPTO_SHA224 + #endif + #ifndef HITLS_CRYPTO_SHA256 + #define HITLS_CRYPTO_SHA256 + #endif + #ifndef HITLS_CRYPTO_SHA384 + #define HITLS_CRYPTO_SHA384 + #endif + #ifndef HITLS_CRYPTO_SHA512 + #define HITLS_CRYPTO_SHA512 + #endif +#endif + +#if defined(HITLS_CRYPTO_SHA224) && !defined(HITLS_CRYPTO_SHA256) + #define HITLS_CRYPTO_SHA256 +#endif +#if defined(HITLS_CRYPTO_SHA384) && !defined(HITLS_CRYPTO_SHA512) + #define HITLS_CRYPTO_SHA512 +#endif + +#if defined(HITLS_CRYPTO_SHA256) || defined(HITLS_CRYPTO_SHA512) + #ifndef HITLS_CRYPTO_SHA2 + #define HITLS_CRYPTO_SHA2 + #endif +#endif + +#if defined(HITLS_CRYPTO_MD5) || defined(HITLS_CRYPTO_SM3) || defined(HITLS_CRYPTO_SHA1) || \ + defined(HITLS_CRYPTO_SHA2) || defined(HITLS_CRYPTO_SHA3) + #ifndef HITLS_CRYPTO_MD + #define HITLS_CRYPTO_MD + #endif +#endif + +#if defined(HITLS_CRYPTO_MODES_X8664) +#define HITLS_CRYPTO_CHACHA20POLY1305_X8664 +#define HITLS_CRYPTO_GCM_X8664 +#endif + +#if defined(HITLS_CRYPTO_MODES_ARMV8) +#define HITLS_CRYPTO_CHACHA20POLY1305_ARMV8 +#define HITLS_CRYPTO_GCM_ARMV8 +#endif + +#if (defined(HITLS_CRYPTO_MODES_X8664) || defined(HITLS_CRYPTO_MODES_ARMV7) || defined(HITLS_CRYPTO_MODES_ARMV8)) && \ + !defined(HITLS_CRYPTO_MODES_ASM) +#define HITLS_CRYPTO_MODES_ASM +#endif + +#endif /* HITLS_CONFIG_LAYER_H */ diff --git a/configure.py b/configure.py new file mode 100644 index 00000000..4f96c6e9 --- /dev/null +++ b/configure.py @@ -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('$'.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) diff --git a/crypto/aes/include/crypt_aes.h b/crypto/aes/include/crypt_aes.h new file mode 100644 index 00000000..40e6402f --- /dev/null +++ b/crypto/aes/include/crypt_aes.h @@ -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 + +#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 diff --git a/crypto/aes/src/asm/crypt_aes_armv8.S b/crypto/aes/src/asm/crypt_aes_armv8.S new file mode 100644 index 00000000..1a1b0afe --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_armv8.S @@ -0,0 +1,428 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_AES + +#include "crypt_aes_macro_armv8.s" +.file "crypt_aes_armv8.S" +.text +.arch armv8-a+crypto + +KEY .req x0 +IN .req x1 +OUT .req x2 + +ROUNDS .req w6 + +RDK0 .req v17 +RDK1 .req v18 + +.section .rodata +.align 5 +.g_cron: +.long 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 +.align 5 + +/* + * In Return-oriented programming (ROP) and Jump-oriented programming (JOP), we explored features + * that Arm introduced to the Arm architecture to mitigate against JOP-style and ROP-style attacks. + * ... + * Whether the combined or NOP-compatible instructions are set depends on the architecture + * version that the code is built for. When building for Armv8.3-A, or later, the compiler will use + * the combined operations. When building for Armv8.2-A, or earlier, it will use the NOP compatible + * instructions. + * + * The paciasp and autiasp instructions are used for function pointer authentication. + * The pointer authentication feature is added in armv8.3 and is supported only by AArch64. + * The addition of pointer authentication features is described in Section A2.6.1 of + * DDI0487H_a_a-profile_architecture_reference_manual.pdf. + */ + +/* + * int32_t CRYPT_AES_Encrypt(const CRYPT_AES_Key *ctx, + * const uint8_t *in, + * uint8_t *out, + * uint32_t len); + */ +.text +.globl CRYPT_AES_Encrypt +.type CRYPT_AES_Encrypt, %function +.align 5 +CRYPT_AES_Encrypt: +.ecb_aesenc_start: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-16]! + add x29, sp, #0 + + ld1 {BLK0.16b}, [IN] + AES_ENC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + st1 {BLK0.16b}, [OUT] + + eor x0, x0, x0 + eor RDK0.16b, RDK0.16b, RDK0.16b + eor RDK1.16b, RDK1.16b, RDK1.16b + ldp x29, x30, [sp], #16 +.inst 0xd50323bf // autiasp + ret +.size CRYPT_AES_Encrypt, .-CRYPT_AES_Encrypt + +/* + * int32_t CRYPT_AES_Decrypt(const CRYPT_AES_Key *ctx, + * const uint8_t *in, + * uint8_t *out, + * uint32_t len); + */ +.globl CRYPT_AES_Decrypt +.type CRYPT_AES_Decrypt, %function +.align 5 +CRYPT_AES_Decrypt: +.ecb_aesdec_start: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-16]! + add x29, sp, #0 + + ld1 {BLK0.16b}, [IN] + AES_DEC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + st1 {BLK0.16b}, [OUT] + + eor x0, x0, x0 + eor RDK0.16b, RDK0.16b, RDK0.16b + eor RDK1.16b, RDK1.16b, RDK1.16b + ldp x29, x30, [sp], #16 +.inst 0xd50323bf // autiasp + ret +.size CRYPT_AES_Decrypt, .-CRYPT_AES_Decrypt + +/* + * void SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key); + * Generating extended keys. + * x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key + */ +.globl SetEncryptKey128 +.type SetEncryptKey128, %function +.align 5 +SetEncryptKey128: +.Lenc_key_128: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-64]! + add x29, sp, #0 + stp x25, x26, [sp, #16] + stp x23, x24, [sp, #32] + stp x21, x22, [sp, #48] // Register push stack completed. + + adrp x23, .g_cron + add x23, x23, :lo12:.g_cron // Round key start address. + mov x24, x0 // Copy key string address. The address increases by 16 bytes. + ld1 {v1.16b}, [x1] // Reads the 16-byte key of a user. + mov w26, #10 // Number of encryption rounds, which is filled + // with rounds in the structure. + st1 {v1.4s}, [x0], #16 // Save the first key. + eor v0.16b, v0.16b, v0.16b // Clear zeros in V0. + mov w25, #10 // loop for 10 times. +.Lenc_key_128_loop: + ldr w21, [x23], #4 // Obtains the round constant. + dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits). + ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR. + ext v1.16b, v1.16b, v1.16b, #1 // Byte loop. + dup v3.4s, w21 // Repeat four times to change w21 to v3 (128 bits). + aese v1.16b, v0.16b // Xor then shift then sbox (XOR operation with 0 is itself, + // equivalent to omitting the XOR operation). + subs w25, w25, #1 // Count of 10-round key extension. + eor v1.16b, v1.16b, v3.16b // Round constant XOR. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1). + ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2). + ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3). + ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4). + st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-bytes key data into the key string. + b.ne .Lenc_key_128_loop // Loop jump. + str w26, [x0, #64] // Fill in the number of rounds. + eor x24, x24, x24 // Clear sensitivity. + eor x0, x0, x0 + ldp x21, x22, [sp, #48] + ldp x23, x24, [sp, #32] + ldp x25, x26, [sp, #16] + ldp x29, x30, [sp], #64 // Pop stack completed. +.inst 0xd50323bf // autiasp + ret +.size SetEncryptKey128, .-SetEncryptKey128 + + +/* + * void SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key); + * Set a decryption key string. + * x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key + */ +.globl SetDecryptKey128 +.type SetDecryptKey128, %function +.align 5 +SetDecryptKey128: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-32]! + add x29, sp, #0 + stp x25, x28, [sp, #16] // Register push stack completed. + + mov x28, x0 + bl .Lenc_key_128 + ld1 {v0.4s}, [x28], #16 + SETDECKEY_LDR_9_BLOCK x28 + ld1 {v10.4s}, [x28] + mov x25, #-16 + SETDECKEY_INVMIX_9_BLOCK + st1 {v0.4s}, [x28], x25 + SETDECKEY_STR_9_BLOCK x28, x25 + st1 {v10.4s}, [x28] + eor x28, x28, x28 + eor x0, x0, x0 + ldp x25, x28, [sp, #16] + ldp x29, x30, [sp], #32 // Stacking completed. +.inst 0xd50323bf // autiasp + ret +.size SetDecryptKey128, .-SetDecryptKey128 + + +/* + * void SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key); + * Generating extended keys. + * x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key + */ +.globl SetEncryptKey192 +.type SetEncryptKey192, %function +.align 5 +SetEncryptKey192: +.Lenc_key_192: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-64]! + add x29, sp, #0 + stp x25, x26, [sp, #16] + stp x23, x24, [sp, #32] + stp x21, x22, [sp, #48] // Register push stack completed. + + mov x24, x0 // Copy key string address. The address increases by 16 bytes. + ld1 {v0.16b}, [x1], #16 // Obtain the first 128-bit key. + mov w26, #12 // Number of encryption rounds. + st1 {v0.4s}, [x0], #16 // Store the first 128-bit key. + ld1 {v1.8b}, [x1] // Obtains the last 64-bit key. + adrp x23, .g_cron + add x23, x23, :lo12:.g_cron // Round key start address. + st1 {v1.2s}, [x0], #8 // Store the last 64-bit key. + eor v0.16b, v0.16b, v0.16b // Clear zeros in V0. + mov w25, #8 // loop for 8 times. +.Lenc_key_192_loop: + dup v1.4s, v1.s[1] // Repeated four times,The last word of v1 is changed to v1 (128 bits). + subs w25, w25, #1 // Count of 8-round key extensions. + ext v1.16b, v1.16b, v1.16b, #1 // Byte cycle. + ldr w22, [x23], #4 // Obtains the round constant. + aese v1.16b, v0.16b // Shift and sbox (XOR operation with 0 is itself,equivalent to omitting the XOR operation). + dup v2.4s, w22 // Repeat 4 times. W22 becomes v2(128bit). + eor v1.16b, v1.16b, v2.16b // Round constant XOR. + ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1). + ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2). + ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3). + ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4). + st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string. + ld1 {v2.2s}, [x24], #8 // Loads 6 words for the last 2 words of XOR. + dup v1.2s, v1.s[3] // Repeated two times,The last word of v1 is changed to v1 (64bit). + eor v1.8b, v1.8b, v2.8b // 2 XOR operation (1). + ext v2.8b, v0.8b, v2.8b, #4 // 21->10. + eor v1.8b, v1.8b, v2.8b // 2 XOR operation (2). + st1 {v1.2s}, [x0], #8 // Stores the newly calculated 2-word key data into the key string. + b.ne .Lenc_key_192_loop // Loop jump. + str w26, [x0, #24] // Fill in the number of rounds. + eor x24, x24, x24 // Clear sensitivity. + eor x0, x0, x0 + ldp x21, x22, [sp, #48] + ldp x23, x24, [sp, #32] + ldp x25, x26, [sp, #16] + ldp x29, x30, [sp], #64 // Stacking completed. +.inst 0xd50323bf // autiasp + ret +.size SetEncryptKey192, .-SetEncryptKey192 + + +/* + * void SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key); + * Set a decryption key string. + * x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key + */ +.globl SetDecryptKey192 +.type SetDecryptKey192, %function +.align 5 +SetDecryptKey192: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-32]! + add x29, sp, #0 + stp x25, x28, [sp, #16] // Register is stacked. + + mov x28, x0 + bl .Lenc_key_192 + mov x25, #-16 + ld1 {v0.4s}, [x28], #16 + SETDECKEY_LDR_9_BLOCK x28 + ld1 {v10.4s}, [x28], #16 + ld1 {v11.4s}, [x28], #16 + ld1 {v12.4s}, [x28] + SETDECKEY_INVMIX_9_BLOCK + aesimc v10.16b, v10.16b + aesimc v11.16b, v11.16b + st1 {v0.4s}, [x28], x25 + SETDECKEY_STR_9_BLOCK x28, x25 + st1 {v10.4s}, [x28], x25 + st1 {v11.4s}, [x28], x25 + st1 {v12.4s}, [x28] + eor x28, x28, x28 + eor x0, x0, x0 + ldp x25, x28, [sp, #16] + ldp x29, x30, [sp], #32 // Stacking completed. +.inst 0xd50323bf // autiasp + ret +.size SetDecryptKey192, .-SetDecryptKey192 + +/* + * void SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key); + * Generating extended keys. + * x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key + */ +.globl SetEncryptKey256 +.type SetEncryptKey256, %function +.align 5 +SetEncryptKey256: +.Lenc_key_256: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-64]! + add x29, sp, #0 + stp x25, x26, [sp, #16] + stp x23, x24, [sp, #32] + stp x21, x22, [sp, #48] // Register is stacked. + + adrp x23, .g_cron + add x23, x23, :lo12:.g_cron // Round key start address. + ld1 {v0.16b}, [x1], #16 // Obtain the first 128-bit key. + mov x24, x0 // Copy key string address. The address increases by 16 bytes. + st1 {v0.4s}, [x0], #16 // Store the first 128-bit key. + ld1 {v1.16b}, [x1] // Obtain the last 128-bit key. + eor v0.16b, v0.16b, v0.16b // Clear zeros in V0. + st1 {v1.4s}, [x0], #16 // Store the last 128-bit key. + mov w26, #14 // Number of encryption rounds. + mov w25, #6 // Loop for 7-1 times. +.Lenc_key_256_loop: + dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits). + ldr w22, [x23], #4 // Obtains the round constant. + ext v1.16b, v1.16b, v1.16b, #1 // Byte cycle. + aese v1.16b, v0.16b // XOR then shift then sbox (XOR operation with 0 is itself, + // equivalent to omitting the XOR operation). + dup v2.4s, w22 // Repeat 4 times. w22 becomes v2. + eor v1.16b, v1.16b, v2.16b // Round constant XOR. + ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1). + ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2). + ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3). + ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4). + st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string. + subs w25, w25, #1 // Count of 7-1-round key extensions. + dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits). + ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR. + aese v1.16b, v0.16b // XOR then shift then sbox. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1). + ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2). + ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3). + ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4). + st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string. + b.ne .Lenc_key_256_loop // Loop jump. + + dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits). + ldr w22, [x23], #4 // Obtains the round constant. + ext v1.16b, v1.16b, v1.16b, #1 // Byte cycle. + aese v1.16b, v0.16b // XOR then shift then sbox. + dup v2.4s, w22 // Repeat 4 times. w22 becomes v2(128bit). + eor v1.16b, v1.16b, v2.16b // Round constant XOR. + ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1). + ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2). + ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3). + ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000. + eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4). + st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string. + str w26, [x0] // Fill in the number of rounds. + eor x24, x24, x24 // Clear sensitivity. + eor x0, x0, x0 + ldp x21, x22, [sp, #48] + ldp x23, x24, [sp, #32] + ldp x25, x26, [sp, #16] + ldp x29, x30, [sp], #64 // Stacking completed. +.inst 0xd50323bf // autiasp + ret +.size SetEncryptKey256, .-SetEncryptKey256 + +/* + * void SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key); + * Set a decryption key string. + * x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key + */ +.globl SetDecryptKey256 +.type SetDecryptKey256, %function +.align 5 +SetDecryptKey256: +.inst 0xd503233f // paciasp + stp x29, x30, [sp, #-32]! + add x29, sp, #0 + stp x25, x28, [sp, #16] + + mov x28, x0 + bl .Lenc_key_256 + mov x25, #-16 + ld1 {v0.4s}, [x28], #16 + SETDECKEY_LDR_9_BLOCK x28 + ld1 {v10.4s}, [x28], #16 + ld1 {v11.4s}, [x28], #16 + ld1 {v12.4s}, [x28], #16 + ld1 {v13.4s}, [x28], #16 + ld1 {v14.4s}, [x28] + SETDECKEY_INVMIX_9_BLOCK + aesimc v10.16b, v10.16b + aesimc v11.16b, v11.16b + aesimc v12.16b, v12.16b + aesimc v13.16b, v13.16b + st1 {v0.4s}, [x28], x25 + SETDECKEY_STR_9_BLOCK x28, x25 + st1 {v10.4s}, [x28], x25 + st1 {v11.4s}, [x28], x25 + st1 {v12.4s}, [x28], x25 + st1 {v13.4s}, [x28], x25 + st1 {v14.4s}, [x28] + eor x28, x28, x28 + eor x0, x0, x0 + ldp x25, x28, [sp, #16] + ldp x29, x30, [sp], #32 // Stack has been popped. +.inst 0xd50323bf // autiasp + ret +.size SetDecryptKey256, .-SetDecryptKey256 + +#endif diff --git a/crypto/aes/src/asm/crypt_aes_cbc_armv8.S b/crypto/aes/src/asm/crypt_aes_cbc_armv8.S new file mode 100644 index 00000000..066a8b80 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_cbc_armv8.S @@ -0,0 +1,482 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CBC) + +#include "crypt_aes_macro_armv8.s" + +.file "crypt_aes_cbc_armv8.S" +.text +.arch armv8-a+crypto + +KEY .req x0 +IN .req x1 +OUT .req x2 +LEN .req x3 +P_IV .req x4 + +KTMP .req x5 +ROUNDS .req w6 + +BLK0 .req v0 +BLK1 .req v1 +BLK2 .req v2 +BLK3 .req v3 +BLK4 .req v4 +BLK5 .req v5 +BLK6 .req v6 +BLK7 .req v7 + +KEY0_END .req v16 +KEY0 .req v17 +KEY1 .req v18 +KEY2 .req v19 +KEY3 .req v20 +KEY4 .req v21 +KEY5 .req v22 +KEY6 .req v23 +KEY7 .req v24 +KEY8 .req v25 +KEY9 .req v26 +KEY10 .req v27 +KEY11 .req v28 +KEY12 .req v29 +KEY13 .req v30 +KEY14 .req v31 + +IVENC .req v1 +IV0 .req v17 +IV1 .req v18 +IV2 .req v19 +IV3 .req v20 +IV4 .req v21 +IV5 .req v22 +IV6 .req v23 +IV7 .req v24 +IVT .req v25 + +RDK0 .req v26 +RDK1 .req v27 +RDK2 .req v28 + +/* + * One round of encryption process. + * block:input the plaintext. + * key: One round key. + */ +.macro ROUND block, key + aese \block, \key + aesmc \block, \block +.endm + +/* + * Eight blocks of decryption. + * block0_7:Input the ciphertext. + * rdk0: Round key. + * ktmp: Temporarily stores pointers to keys. + */ +.macro DEC8 rdk0s rdk0 blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7 ktmp + aesd \blk0, \rdk0 + aesimc \blk0, \blk0 + aesd \blk5, \rdk0 + aesimc \blk5, \blk5 + aesd \blk1, \rdk0 + aesimc \blk1, \blk1 + aesd \blk6, \rdk0 + aesimc \blk6, \blk6 + aesd \blk2, \rdk0 + aesimc \blk2, \blk2 + aesd \blk3, \rdk0 + aesimc \blk3, \blk3 + aesd \blk4, \rdk0 + aesimc \blk4, \blk4 + aesd \blk7, \rdk0 + aesimc \blk7, \blk7 + ld1 {\rdk0s}, [\ktmp], #16 +.endm + +/** + * Function description: AES encrypted assembly acceleration API in CBC mode. + * int32_t CRYPT_AES_CBC_Encrypt(const CRYPT_AES_Key *ctx, + * const uint8_t *in, + * uint8_t *out, + * uint32_t len, + * uint8_t *iv); + * Input register: + * x0:Pointer to the input key structure + * x1:points to the input data address + * x2:points to the output data address + * x3:Length of the input data, which must be a multiple of 16 + * x4:Points to the CBC mode mask address + * Change register:x5, x6, v0-v31 + * Output register:x0 + * Function/Macro Call: None + */ +.globl CRYPT_AES_CBC_Encrypt +.type CRYPT_AES_CBC_Encrypt, %function +CRYPT_AES_CBC_Encrypt: +.inst 0xd503233f // paciasp + ld1 {IVENC.16b}, [P_IV] // load IV + ldr w6, [KEY, #240] // load rounds + ld1 {BLK0.16b}, [IN], #16 // load in + ld1 {KEY0.4s, KEY1.4s}, [KEY], #32 // load keys + cmp w6, #12 + ld1 {KEY2.4s, KEY3.4s}, [KEY], #32 + ld1 {KEY4.4s, KEY5.4s}, [KEY], #32 + ld1 {KEY6.4s, KEY7.4s}, [KEY], #32 + ld1 {KEY8.4s, KEY9.4s}, [KEY], #32 + eor IVENC.16b, IVENC.16b, BLK0.16b // iv + in + b.lt .Laes_cbc_128_start + + ld1 {KEY10.4s, KEY11.4s}, [KEY], #32 + b.eq .Laes_cbc_192_start + ld1 {KEY12.4s, KEY13.4s}, [KEY], #32 + +.Laes_cbc_256_start: + ld1 {KEY14.4s}, [KEY] + ROUND IVENC.16b, KEY0.16b + eor KEY0_END.16b, KEY0.16b, KEY14.16b // key0 + keyEnd + b .Laes_cbc_256_round_loop + +.Laes_cbc_256_loop: + ROUND IVENC.16b, KEY0.16b + st1 {BLK0.16b}, [OUT], #16 + +.Laes_cbc_256_round_loop: + ROUND IVENC.16b, KEY1.16b + ROUND IVENC.16b, KEY2.16b + subs LEN, LEN, #16 + ROUND IVENC.16b, KEY3.16b + ROUND IVENC.16b, KEY4.16b + ROUND IVENC.16b, KEY5.16b + ld1 {KEY0.16b}, [IN], #16 // load IN + ROUND IVENC.16b, KEY6.16b + ROUND IVENC.16b, KEY7.16b + ROUND IVENC.16b, KEY8.16b + ROUND IVENC.16b, KEY9.16b + ROUND IVENC.16b, KEY10.16b + ROUND IVENC.16b, KEY11.16b + ROUND IVENC.16b, KEY12.16b + aese IVENC.16b, KEY13.16b + eor KEY0.16b, KEY0.16b, KEY0_END.16b // IN + KEY0 + KEYEND + eor BLK0.16b, IVENC.16b, KEY14.16b + b.gt .Laes_cbc_256_loop + b .Lescbcenc_finish + +.Laes_cbc_128_start: + ld1 {KEY10.4s}, [KEY] + ROUND IVENC.16b, KEY0.16b + eor KEY0_END.16b, KEY0.16b, KEY10.16b // key0 + keyEnd + b .Laes_cbc_128_round_loop + +.Laes_cbc_128_loop: + ROUND IVENC.16b, KEY0.16b + st1 {BLK0.16b}, [OUT], #16 + +.Laes_cbc_128_round_loop: + ROUND IVENC.16b, KEY1.16b + ROUND IVENC.16b, KEY2.16b + subs LEN, LEN, #16 + ROUND IVENC.16b, KEY3.16b + ROUND IVENC.16b, KEY4.16b + ROUND IVENC.16b, KEY5.16b + ld1 {KEY0.16b}, [IN], #16 // load IN + ROUND IVENC.16b, KEY6.16b + ROUND IVENC.16b, KEY7.16b + ROUND IVENC.16b, KEY8.16b + aese IVENC.16b, KEY9.16b + eor KEY0.16b, KEY0.16b, KEY0_END.16b // IN + KEY0 + KEYEND + eor BLK0.16b, IVENC.16b, KEY10.16b // enc OK + b.gt .Laes_cbc_128_loop + b .Lescbcenc_finish + +.Laes_cbc_192_start: + ld1 {KEY12.4s}, [KEY] + ROUND IVENC.16b, KEY0.16b + eor KEY0_END.16b, KEY0.16b, KEY12.16b // key0 + keyEnd + b .Laes_cbc_192_round_loop + +.Laes_cbc_192_loop: + ROUND IVENC.16b, KEY0.16b + st1 {BLK0.16b}, [OUT], #16 + +.Laes_cbc_192_round_loop: + ROUND IVENC.16b, KEY1.16b + ROUND IVENC.16b, KEY2.16b + subs LEN, LEN, #16 + ROUND IVENC.16b, KEY3.16b + ROUND IVENC.16b, KEY4.16b + ROUND IVENC.16b, KEY5.16b + ld1 {KEY0.16b}, [IN], #16 // load IN + ROUND IVENC.16b, KEY6.16b + ROUND IVENC.16b, KEY7.16b + ROUND IVENC.16b, KEY8.16b + ROUND IVENC.16b, KEY9.16b + ROUND IVENC.16b, KEY10.16b + aese IVENC.16b, KEY11.16b + eor KEY0.16b, KEY0.16b, KEY0_END.16b // IN + KEY0 + KEYEND + eor BLK0.16b, IVENC.16b, KEY12.16b + b.gt .Laes_cbc_192_loop + +.Lescbcenc_finish: + st1 {BLK0.16b}, [OUT], #16 + st1 {BLK0.16b}, [P_IV] + mov x0, #0 +.inst 0xd50323bf // autiasp + ret +.size CRYPT_AES_CBC_Encrypt, .-CRYPT_AES_CBC_Encrypt + +/** + * Function description: AES decryption and assembly acceleration API in CBC mode. + * int32_t CRYPT_AES_CBC_Decrypt(const CRYPT_AES_Key *ctx, + * const uint8_t *in, + * uint8_t *out, + * uint32_t len, + * uint8_t *iv); + * Input register: + * x0:pointer to the input key structure + * x1:points to the input data address + * x2:points to the output data address + * x3:Length of the input data, which must be a multiple of 16 + * x4:Points to the CBC mode mask address + * Change register:x5, x6, v0-v31 + * Output register:x0 + * Function/Macro Call: AES_DEC_8_BLKS, AES_DEC_1_BLK, AES_DEC_2_BLKS, AES_DEC_3_BLKS, + * AES_DEC_4_BLKS, AES_DEC_5_BLKS, AES_DEC_6_BLKS, AES_DEC_7_BLKS + */ +.globl CRYPT_AES_CBC_Decrypt +.type CRYPT_AES_CBC_Decrypt, %function +CRYPT_AES_CBC_Decrypt: +.inst 0xd503233f // paciasp + ld1 {IV0.16b}, [P_IV] +.Lcbc_aesdec_start: + cmp LEN, #64 + b.ge .Lcbc_dec_above_equal_4_blks + cmp LEN, #32 + b.ge .Lcbc_dec_above_equal_2_blks + cmp LEN, #0 + b.eq .Lcbc_aesdec_finish + b .Lcbc_dec_proc_1_blk + +.Lcbc_dec_above_equal_2_blks: + cmp LEN, #48 + b.lt .Lcbc_dec_proc_2_blks + b .Lcbc_dec_proc_3_blks + +.Lcbc_dec_above_equal_4_blks: + cmp LEN, #96 + b.ge .Lcbc_dec_above_equal_6_blks + cmp LEN, #80 + b.lt .Lcbc_dec_proc_4_blks + b .Lcbc_dec_proc_5_blks + +.Lcbc_dec_above_equal_6_blks: + cmp LEN, #112 + b.lt .Lcbc_dec_proc_6_blks + cmp LEN, #128 + b.lt .Lcbc_dec_proc_7_blks + +.align 4 +.Lcbc_aesdec_8_blks_loop: + ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64 + mov KTMP, KEY + ldr ROUNDS, [KEY, #240] + ld1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [IN], #64 + + mov IV1.16b, BLK0.16b + mov IV2.16b, BLK1.16b + mov IV3.16b, BLK2.16b + ld1 {RDK0.4s, RDK1.4s}, [KTMP], #32 + mov IV4.16b, BLK3.16b + mov IV5.16b, BLK4.16b + mov IV6.16b, BLK5.16b + mov IV7.16b, BLK6.16b + mov IVT.16b, BLK7.16b + + + DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + + cmp ROUNDS, #12 + b.lt .Ldec_8_blks_last + DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + b.eq .Ldec_8_blks_last + DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP + +.Ldec_8_blks_last: + ld1 {RDK2.4s}, [KTMP] + aesd BLK0.16b, RDK0.16b + aesimc BLK0.16b, BLK0.16b + aesd BLK1.16b, RDK0.16b + aesimc BLK1.16b, BLK1.16b + aesd BLK2.16b, RDK0.16b + aesimc BLK2.16b, BLK2.16b + eor IV0.16b, IV0.16b, RDK2.16b + aesd BLK3.16b, RDK0.16b + aesimc BLK3.16b, BLK3.16b + eor IV1.16b, IV1.16b, RDK2.16b + aesd BLK4.16b, RDK0.16b + aesimc BLK4.16b, BLK4.16b + eor IV2.16b, IV2.16b, RDK2.16b + aesd BLK5.16b, RDK0.16b + aesimc BLK5.16b, BLK5.16b + eor IV3.16b, IV3.16b, RDK2.16b + aesd BLK6.16b, RDK0.16b + aesimc BLK6.16b, BLK6.16b + eor IV4.16b, IV4.16b, RDK2.16b + aesd BLK7.16b, RDK0.16b + aesimc BLK7.16b, BLK7.16b + eor IV5.16b, IV5.16b, RDK2.16b + + aesd BLK0.16b, RDK1.16b + aesd BLK1.16b, RDK1.16b + eor IV6.16b, IV6.16b, RDK2.16b + aesd BLK2.16b, RDK1.16b + aesd BLK3.16b, RDK1.16b + eor IV7.16b, IV7.16b, RDK2.16b + aesd BLK4.16b, RDK1.16b + aesd BLK5.16b, RDK1.16b + aesd BLK6.16b, RDK1.16b + aesd BLK7.16b, RDK1.16b + + sub LEN, LEN, #128 + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + eor BLK2.16b, BLK2.16b, IV2.16b + eor BLK3.16b, BLK3.16b, IV3.16b + st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64 + eor BLK4.16b, BLK4.16b, IV4.16b + eor BLK5.16b, BLK5.16b, IV5.16b + cmp LEN, #0 + eor BLK6.16b, BLK6.16b, IV6.16b + eor BLK7.16b, BLK7.16b, IV7.16b + mov IV0.16b, IVT.16b + st1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [OUT], #64 + b.eq .Lcbc_aesdec_finish + cmp LEN, #128 + b.lt .Lcbc_aesdec_start + b .Lcbc_aesdec_8_blks_loop + +.Lcbc_dec_proc_1_blk: + ld1 {BLK0.16b}, [IN] + AES_DEC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b}, [OUT] + b .Lcbc_aesdec_finish + +.Lcbc_dec_proc_2_blks: + ld1 {BLK0.16b, BLK1.16b}, [IN] + ld1 {IV1.16b}, [IN], #16 + AES_DEC_2_BLKS KEY BLK0.16b BLK1.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b, BLK1.16b}, [OUT] + b .Lcbc_aesdec_finish + +.Lcbc_dec_proc_3_blks: + ld1 {BLK0.16b, BLK1.16b, BLK2.16b}, [IN] + ld1 {IV1.16b, IV2.16b}, [IN], #32 + AES_DEC_3_BLKS KEY BLK0.16b BLK1.16b BLK2.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + eor BLK2.16b, BLK2.16b, IV2.16b + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b, BLK1.16b, BLK2.16b}, [OUT] + b .Lcbc_aesdec_finish + +.Lcbc_dec_proc_4_blks: + ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN] + ld1 {IV1.16b, IV2.16b, IV3.16b}, [IN], #48 + AES_DEC_4_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + eor BLK2.16b, BLK2.16b, IV2.16b + eor BLK3.16b, BLK3.16b, IV3.16b + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT] + b .Lcbc_aesdec_finish + +.Lcbc_dec_proc_5_blks: + ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN] + ld1 {IV1.16b, IV2.16b, IV3.16b, IV4.16b}, [IN], #64 + ld1 {BLK4.16b}, [IN] + AES_DEC_5_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + eor BLK2.16b, BLK2.16b, IV2.16b + eor BLK3.16b, BLK3.16b, IV3.16b + eor BLK4.16b, BLK4.16b, IV4.16b + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64 + st1 {BLK4.16b}, [OUT] + b .Lcbc_aesdec_finish + +.Lcbc_dec_proc_6_blks: + ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN] + ld1 {IV1.16b, IV2.16b, IV3.16b, IV4.16b}, [IN], #64 + ld1 {BLK4.16b, BLK5.16b}, [IN] + ld1 {IV5.16b}, [IN], #16 + AES_DEC_6_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + eor BLK2.16b, BLK2.16b, IV2.16b + eor BLK3.16b, BLK3.16b, IV3.16b + eor BLK4.16b, BLK4.16b, IV4.16b + eor BLK5.16b, BLK5.16b, IV5.16b + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64 + st1 {BLK4.16b, BLK5.16b}, [OUT] + b .Lcbc_aesdec_finish + +.Lcbc_dec_proc_7_blks: + ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN] + ld1 {IV1.16b, IV2.16b, IV3.16b, IV4.16b}, [IN], #64 + ld1 {BLK4.16b, BLK5.16b, BLK6.16b}, [IN] + ld1 {IV5.16b, IV6.16b}, [IN], #32 + AES_DEC_7_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b BLK6.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS + eor BLK0.16b, BLK0.16b, IV0.16b + eor BLK1.16b, BLK1.16b, IV1.16b + eor BLK2.16b, BLK2.16b, IV2.16b + eor BLK3.16b, BLK3.16b, IV3.16b + eor BLK4.16b, BLK4.16b, IV4.16b + eor BLK5.16b, BLK5.16b, IV5.16b + eor BLK6.16b, BLK6.16b, IV6.16b + + ld1 {IV0.16b}, [IN] + st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64 + st1 {BLK4.16b, BLK5.16b, BLK6.16b}, [OUT] + +.Lcbc_aesdec_finish: + st1 {IV0.16b}, [P_IV] + mov x0, #0 + eor RDK0.16b, RDK0.16b, RDK0.16b + eor RDK1.16b, RDK1.16b, RDK1.16b + eor RDK2.16b, RDK2.16b, RDK2.16b +.inst 0xd50323bf // autiasp + ret +.size CRYPT_AES_CBC_Decrypt, .-CRYPT_AES_CBC_Decrypt + +#endif diff --git a/crypto/aes/src/asm/crypt_aes_cbc_x86_64.S b/crypto/aes/src/asm/crypt_aes_cbc_x86_64.S new file mode 100644 index 00000000..880bb7ed --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_cbc_x86_64.S @@ -0,0 +1,499 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CBC) + +#include "crypt_aes_macro_x86_64.s" + +.file "crypt_aes_cbc_x86_64.S" +.text + +.set ARG1, %rdi +.set ARG2, %rsi +.set ARG3, %rdx +.set ARG4, %ecx +.set ARG5, %r8 +.set ARG6, %r9 + +.set RDK, %xmm3 +.set KEY, %rdi +.set KTMP, %r9 +.set ROUNDS, %eax +.set RET, %eax + +.set BLK0, %xmm1 +.set BLK1, %xmm4 +.set BLK2, %xmm5 +.set BLK3, %xmm6 +.set BLK4, %xmm10 +.set BLK5, %xmm11 +.set BLK6, %xmm12 +.set BLK7, %xmm13 +.set IV0, %xmm0 +.set IV1, %xmm7 +.set IV2, %xmm8 +.set IV3, %xmm9 + +.set KEY1, %xmm4 +.set KEY2, %xmm5 +.set KEY3, %xmm6 +.set KEY4, %xmm10 +.set KEY5, %xmm11 +.set KEY6, %xmm12 +.set KEY7, %xmm13 +.set KEY8, %xmm14 +.set KEY9, %xmm15 +.set KEY10, %xmm2 +.set KEY11, %xmm7 +.set KEY12, %xmm8 +.set KEY13, %xmm9 +.set KEYTEMP, %xmm3 + +/** + * Function description:AES encrypted assembly acceleration API in CBC mode. + * Function prototype:int32_t CRYPT_AES_CBC_Encrypt(const CRYPT_AES_Key *ctx, + * const uint8_t *in, + * uint8_t *out, + * uint32_t len, + * uint8_t *iv); + * Input register: + * rdi:pointer to the input key structure + * rsi:points to the input data address + * rdx:points to the output data address + * rcx:Length of the input data, which must be a multiple of 16 + * r8: Points to the CBC mode mask address + * Change register:xmm0-xmm15 + * Output register:eax + * Function/Macro Call: None + */ + .globl CRYPT_AES_CBC_Encrypt + .type CRYPT_AES_CBC_Encrypt, @function +CRYPT_AES_CBC_Encrypt: + .cfi_startproc + .align 16 + cmpl $16, ARG4 + jb .Laescbcend_end + movl 240(KEY), ROUNDS + vmovdqu (ARG5), IV0 + vmovdqu (KEY), KEY1 + vmovdqu 16(KEY), KEY2 + vmovdqu 32(KEY), KEY3 + vmovdqu 48(KEY), KEY4 + vmovdqu 64(KEY), KEY5 + vmovdqu 80(KEY), KEY6 + vmovdqu 96(KEY), KEY7 + vmovdqu 112(KEY), KEY8 + vmovdqu 128(KEY), KEY9 + vmovdqu 144(KEY), KEY10 + vmovdqu 160(KEY), KEY11 + cmpl $12, ROUNDS + jb .Laes_128_cbc_start + je .Laes_192_cbc_start +.align 16 +.Laes_256_cbc_start: + vmovdqu 176(KEY), KEY12 + vmovdqu 192(KEY), KEY13 +.Laes_256_cbc_loop: + vpxor (ARG2), IV0, BLK0 + vmovdqu 208(KEY), KEYTEMP + vpxor BLK0, KEY1, BLK0 + aesenc KEY2, BLK0 + aesenc KEY3, BLK0 + aesenc KEY4, BLK0 + aesenc KEY5, BLK0 + aesenc KEY6, BLK0 + aesenc KEY7, BLK0 + aesenc KEY8, BLK0 + aesenc KEY9, BLK0 + aesenc KEY10, BLK0 + aesenc KEY11, BLK0 + aesenc KEY12, BLK0 + aesenc KEY13, BLK0 + aesenc KEYTEMP, BLK0 + vmovdqu 224(KEY), KEYTEMP + aesenclast KEYTEMP, BLK0 + leaq 16(ARG2), ARG2 + vmovdqu BLK0, (ARG3) + movdqa BLK0, IV0 + leaq 16(ARG3), ARG3 + subl $16, ARG4 + cmpl $16, ARG4 + jnb .Laes_256_cbc_loop // Special value processing + vpxor KEY12, KEY12, KEY12 + vpxor KEY13, KEY13, KEY13 + vpxor KEYTEMP, KEYTEMP, KEYTEMP + jmp .Laescbcenc_finish + +.align 16 +.Laes_192_cbc_start: + vmovdqu 176(KEY), KEY12 + vmovdqu 192(KEY), KEY13 +.Laes_192_cbc_loop: + vpxor (ARG2), IV0, BLK0 + vpxor BLK0, KEY1, BLK0 + aesenc KEY2, BLK0 + aesenc KEY3, BLK0 + aesenc KEY4, BLK0 + aesenc KEY5, BLK0 + aesenc KEY6, BLK0 + aesenc KEY7, BLK0 + aesenc KEY8, BLK0 + aesenc KEY9, BLK0 + aesenc KEY10, BLK0 + aesenc KEY11, BLK0 + aesenc KEY12, BLK0 + aesenclast KEY13, BLK0 + leaq 16(ARG2), ARG2 + vmovdqu BLK0, (ARG3) + movdqa BLK0, IV0 + leaq 16(ARG3), ARG3 + subl $16 , ARG4 + jnz .Laes_192_cbc_loop + vpxor KEY12, KEY12, KEY12 + vpxor KEY13, KEY13, KEY13 + jmp .Laescbcenc_finish + +.align 16 +.Laes_128_cbc_start: + vpxor (ARG2), IV0, BLK0 + vpxor BLK0, KEY1, BLK0 + aesenc KEY2, BLK0 + aesenc KEY3, BLK0 + aesenc KEY4, BLK0 + aesenc KEY5, BLK0 + aesenc KEY6, BLK0 + aesenc KEY7, BLK0 + aesenc KEY8, BLK0 + aesenc KEY9, BLK0 + aesenc KEY10, BLK0 + aesenclast KEY11, BLK0 + leaq 16(ARG2), ARG2 + vmovdqu BLK0, (ARG3) + movdqa BLK0, IV0 + leaq 16(ARG3), ARG3 + subl $16, ARG4 + jnz .Laes_128_cbc_start + jmp .Laescbcenc_finish + +.Laescbcenc_finish: + vmovdqu BLK0,(ARG5) + vpxor KEY1, KEY1, KEY1 + vpxor KEY2, KEY2, KEY2 + vpxor KEY3, KEY3, KEY3 + vpxor KEY4, KEY4, KEY4 + vpxor KEY5, KEY5, KEY5 + vpxor KEY6, KEY6, KEY6 + vpxor KEY7, KEY7, KEY7 + vpxor KEY8, KEY8, KEY8 + vpxor KEY9, KEY9, KEY9 + vpxor KEY10, KEY10, KEY10 + vpxor KEY11, KEY11, KEY11 +.Laescbcend_end: + movl $0, RET + ret + .cfi_endproc + .size CRYPT_AES_CBC_Encrypt, .-CRYPT_AES_CBC_Encrypt + +/** + * Function description: Sets the AES decryption and assembly accelerated implementation interface in CBC mode + * Function prototype:int32_t CRYPT_AES_CBC_Decrypt(const CRYPT_AES_Key *ctx, + * const uint8_t *in, + * uint8_t *out, + * uint32_t len, + * uint8_t *iv); + * Input register: + * rdi:pointer to the input key structure + * rsi:points to the input data address. + * rdx:points to the output data address. + * rcx:Length of the input data, which must be a multiple of 16 + * r8: Points to the CBC mode mask address + * Change register:xmm0-xmm13 + * Output register:eax + * Function/Macro Call: None + */ + .globl CRYPT_AES_CBC_Decrypt + .type CRYPT_AES_CBC_Decrypt, @function +CRYPT_AES_CBC_Decrypt: + .cfi_startproc +.align 16 + vmovdqu (ARG5), IV0 +.Laes_cbc_dec_start: + cmpl $64, ARG4 + jae .Labove_equal_4_blks + cmpl $32, ARG4 + jae .Labove_equal_2_blks + cmpl $0, ARG4 + je .Laes_cbc_dec_finish + jmp .Lproc_1_blk + +.Labove_equal_2_blks: + cmpl $48, ARG4 + jb .Lproc_2_blks + jmp .Lproc_3_blks + +.Labove_equal_4_blks: + cmpl $96, ARG4 + jae .Labove_equal_6_blks + cmpl $80, ARG4 + jb .Lproc_4_blks + jmp .Lproc_5_blks + +.Labove_equal_6_blks: + cmpl $112, ARG4 + jb .Lproc_6_blks + cmpl $128, ARG4 + jb .Lproc_7_blks + +.align 16 +.Lproc_8_blks: +.Laescbcdec_8_blks_loop: + vmovdqu (ARG2), BLK0 + vmovdqu 16(ARG2), BLK1 + vmovdqu 32(ARG2), BLK2 + movdqa BLK0, IV1 + movdqa BLK1, IV2 + movdqa BLK2, IV3 + movq KEY, KTMP + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + vpxor BLK0, RDK, BLK0 + vpxor BLK1, RDK, BLK1 + vpxor BLK2, RDK, BLK2 + vpxor 48(ARG2), RDK, BLK3 + vpxor 64(ARG2), RDK, BLK4 + vpxor 80(ARG2), RDK, BLK5 + vpxor 96(ARG2), RDK, BLK6 + vpxor 112(ARG2), RDK, BLK7 + decl ROUNDS + AES_DEC_8_BLKS KTMP ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 BLK7 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vpxor BLK2, IV2, BLK2 + vpxor BLK3, IV3, BLK3 + vpxor 48(ARG2), BLK4, BLK4 + vpxor 64(ARG2), BLK5, BLK5 + vpxor 80(ARG2), BLK6, BLK6 + vpxor 96(ARG2), BLK7, BLK7 + vmovdqu 112(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + vmovdqu BLK2, 32(ARG3) + vmovdqu BLK3, 48(ARG3) + vmovdqu BLK4, 64(ARG3) + vmovdqu BLK5, 80(ARG3) + vmovdqu BLK6, 96(ARG3) + vmovdqu BLK7, 112(ARG3) + subl $128, ARG4 + leaq 128(ARG2), ARG2 + leaq 128(ARG3), ARG3 + cmpl $128, ARG4 + jb .Laes_cbc_dec_start + jmp .Laescbcdec_8_blks_loop + +.align 16 +.Lproc_1_blk: + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + vpxor (ARG2), RDK, BLK0 + decl ROUNDS + AES_DEC_1_BLK KEY ROUNDS RDK BLK0 + vpxor BLK0, IV0, BLK0 + vmovdqu (ARG2), IV0 + vmovdqu BLK0, (ARG3) + jmp .Laes_cbc_dec_finish + +.align 16 +.Lproc_2_blks: + vmovdqu (ARG2), BLK0 + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + movdqa BLK0, IV1 + vpxor BLK0, RDK, BLK0 + vpxor 16(ARG2), RDK, BLK1 + decl ROUNDS + AES_DEC_2_BLKS KEY ROUNDS RDK BLK0 BLK1 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vmovdqu 16(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + jmp .Laes_cbc_dec_finish + +.align 16 +.Lproc_3_blks: + vmovdqu (ARG2), BLK0 + vmovdqu 16(ARG2), BLK1 + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + movdqa BLK0, IV1 + movdqa BLK1, IV2 + vpxor BLK0, RDK, BLK0 + vpxor BLK1, RDK, BLK1 + vpxor 32(ARG2), RDK, BLK2 + decl ROUNDS + AES_DEC_3_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vpxor BLK2, IV2, BLK2 + vmovdqu 32(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + vmovdqu BLK2, 32(ARG3) + jmp .Laes_cbc_dec_finish + +.align 16 +.Lproc_4_blks: + vmovdqu (ARG2), BLK0 + vmovdqu 16(ARG2), BLK1 + vmovdqu 32(ARG2), BLK2 + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + movdqa BLK0, IV1 + movdqa BLK1, IV2 + movdqa BLK2, IV3 + vpxor BLK0, RDK, BLK0 + vpxor BLK1, RDK, BLK1 + vpxor BLK2, RDK, BLK2 + vpxor 48(ARG2), RDK, BLK3 + decl ROUNDS + AES_DEC_4_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vpxor BLK2, IV2, BLK2 + vpxor BLK3, IV3, BLK3 + vmovdqu 48(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + vmovdqu BLK2, 32(ARG3) + vmovdqu BLK3, 48(ARG3) + jmp .Laes_cbc_dec_finish + +.align 16 +.Lproc_5_blks: + vmovdqu (ARG2), BLK0 + vmovdqu 16(ARG2), BLK1 + vmovdqu 32(ARG2), BLK2 + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + movdqa BLK0, IV1 + movdqa BLK1, IV2 + movdqa BLK2, IV3 + vpxor BLK0, RDK, BLK0 + vpxor BLK1, RDK, BLK1 + vpxor BLK2, RDK, BLK2 + vpxor 48(ARG2), RDK, BLK3 + vpxor 64(ARG2), RDK, BLK4 + decl ROUNDS + AES_DEC_5_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vpxor BLK2, IV2, BLK2 + vpxor BLK3, IV3, BLK3 + vpxor 48(ARG2), BLK4, BLK4 + vmovdqu 64(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + vmovdqu BLK2, 32(ARG3) + vmovdqu BLK3, 48(ARG3) + vmovdqu BLK4, 64(ARG3) + jmp .Laes_cbc_dec_finish + +.align 16 +.Lproc_6_blks: + vmovdqu (ARG2), BLK0 + vmovdqu 16(ARG2), BLK1 + vmovdqu 32(ARG2), BLK2 + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + movdqa BLK0, IV1 + movdqa BLK1, IV2 + movdqa BLK2, IV3 + vpxor (ARG2), RDK, BLK0 + vpxor 16(ARG2), RDK, BLK1 + vpxor 32(ARG2), RDK, BLK2 + vpxor 48(ARG2), RDK, BLK3 + vpxor 64(ARG2), RDK, BLK4 + vpxor 80(ARG2), RDK, BLK5 + decl ROUNDS + AES_DEC_6_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vpxor BLK2, IV2, BLK2 + vpxor BLK3, IV3, BLK3 + vpxor 48(ARG2), BLK4, BLK4 + vpxor 64(ARG2), BLK5, BLK5 + vmovdqu 80(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + vmovdqu BLK2, 32(ARG3) + vmovdqu BLK3, 48(ARG3) + vmovdqu BLK4, 64(ARG3) + vmovdqu BLK5, 80(ARG3) + jmp .Laes_cbc_dec_finish + +.align 16 +.Lproc_7_blks: + vmovdqu (ARG2), BLK0 + vmovdqu 16(ARG2), BLK1 + vmovdqu 32(ARG2), BLK2 + movl 240(KEY), ROUNDS + vmovdqu (KEY), RDK + movdqa BLK0, IV1 + movdqa BLK1, IV2 + movdqa BLK2, IV3 + vpxor (ARG2), RDK, BLK0 + vpxor 16(ARG2), RDK, BLK1 + vpxor 32(ARG2), RDK, BLK2 + vpxor 48(ARG2), RDK, BLK3 + vpxor 64(ARG2), RDK, BLK4 + vpxor 80(ARG2), RDK, BLK5 + vpxor 96(ARG2), RDK, BLK6 + decl ROUNDS + AES_DEC_7_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 + vpxor BLK0, IV0, BLK0 + vpxor BLK1, IV1, BLK1 + vpxor BLK2, IV2, BLK2 + vpxor BLK3, IV3, BLK3 + vpxor 48(ARG2), BLK4, BLK4 + vpxor 64(ARG2), BLK5, BLK5 + vpxor 80(ARG2), BLK6, BLK6 + vmovdqu 96(ARG2), IV0 + vmovdqu BLK0, (ARG3) + vmovdqu BLK1, 16(ARG3) + vmovdqu BLK2, 32(ARG3) + vmovdqu BLK3, 48(ARG3) + vmovdqu BLK4, 64(ARG3) + vmovdqu BLK5, 80(ARG3) + vmovdqu BLK6, 96(ARG3) + +.align 16 +.Laes_cbc_dec_finish: + vmovdqu IV0, (ARG5) + vpxor BLK0, BLK0, BLK0 + vpxor BLK1, BLK1, BLK1 + vpxor BLK2, BLK2, BLK2 + vpxor BLK3, BLK3, BLK3 + vpxor BLK4, BLK4, BLK4 + vpxor BLK5, BLK5, BLK5 + vpxor BLK6, BLK6, BLK6 + vpxor BLK7, BLK7, BLK7 + vpxor RDK, RDK, RDK + movl $0, RET + ret + .cfi_endproc + .size CRYPT_AES_CBC_Decrypt, .-CRYPT_AES_CBC_Decrypt + +#endif diff --git a/crypto/aes/src/asm/crypt_aes_cfb_armv8.S b/crypto/aes/src/asm/crypt_aes_cfb_armv8.S new file mode 100644 index 00000000..ec177957 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_cfb_armv8.S @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_common_aarch32.S b/crypto/aes/src/asm/crypt_aes_common_aarch32.S new file mode 100644 index 00000000..57f2f6b1 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_common_aarch32.S @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_ctr_armv8.S b/crypto/aes/src/asm/crypt_aes_ctr_armv8.S new file mode 100644 index 00000000..6beef9e2 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_ctr_armv8.S @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_ctr_x86_64.S b/crypto/aes/src/asm/crypt_aes_ctr_x86_64.S new file mode 100644 index 00000000..079beabe --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_ctr_x86_64.S @@ -0,0 +1,588 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CTR) + +.file "crypt_aes_ctr_x86_64.S" +.text + +.set KEY, %rdi +.set INPUT, %rsi +.set OUTPUT, %rdx +.set LEN, %ecx +.set CTR_IV, %r8 + +.set RDK, %xmm0 +.set RDK2, %xmm1 +.set KTMP, %r13 +.set ROUNDS, %eax +.set RET, %eax + +.set IV0, %xmm2 +.set IV1, %xmm3 +.set IV2, %xmm4 +.set IV3, %xmm5 +.set IV4, %xmm6 +.set IV5, %xmm7 +.set IV6, %xmm8 +.set IV7, %xmm9 +.set BLK0, %xmm10 +.set BLK1, %xmm11 +.set BLK2, %xmm12 +.set BLK3, %xmm13 +.set BLK4, %xmm14 +.set BLK5, %xmm15 + +/** + * Macro description: Eight IVs are encrypted. + * Input register: + * Key: Round key. + * block0-7: Encrypted IV. + * Modify the register: block0-7. + * Output register: + * block0-7: IV after a round of encryption. + */ +.macro ONE_ENC key block0 block1 block2 block3 block4 block5 block6 block7 + aesenc \key, \block0 + aesenc \key, \block1 + aesenc \key, \block2 + aesenc \key, \block3 + aesenc \key, \block4 + aesenc \key, \block5 + aesenc \key, \block6 + aesenc \key, \block7 +.endm + +/** + * Macro description: Obtains a new ctr and XORs it with the round key. + * input register: + * ctr32:Initialization vector. + * offset:Offset. + * temp:32-bit CTR temporary register. + * key32:32-bit round key. + * addrOffset:push stack address offset. + * addr:push stack address. + * Modify the register: Temp. + */ +.macro XOR_KEY ctr32 offset temp key32 addrOffset addr + leal \offset(\ctr32), \temp // XOR 32-bit ctr and key, push into the stack + bswapl \temp + xorl \key32, \temp + movl \temp, \addrOffset+12(\addr) +.endm + +/** + * Macro description: Obtain the round key, encrypt the IV, obtain the next round of ctr, and XOR the round key. + * Input register: + * Key: pointer to the key. + * Offset: round key offset. + * Temp: Temporary register for the round key. + * Ctr32: initialization vector. + * Offset2: Ctr offset. + * Temp2: 32-bit CTR temporary register. + * Key32: 32-bit round key. + * AddrOffset: Offest of entering the stack. + * Addr: Address for entering the stack. + * Modify register: Temp temp2 IV0-7. + * Output register: + * IV0-7: IV after a round of encryption. + */ +.macro ONE_ENC_XOR_KEY key offset temp ctr32 offset2 temp2 key32 addrOffset addr + vmovdqu \offset(\key), \temp + aesenc \temp, IV0 + leal \offset2(\ctr32), \temp2 // XOR 32-bit ctr and key, push stack. + aesenc \temp, IV1 + bswapl \temp2 + aesenc \temp, IV2 + aesenc \temp, IV3 + xorl \key32, \temp2 + aesenc \temp, IV4 + aesenc \temp, IV5 + movl \temp2, \addrOffset+12(\addr) + aesenc \temp, IV6 + aesenc \temp, IV7 + +.endm + +/** + * Macro description: Update the in and out pointer offsets and the remaining length of len. + * Input register: + * Input:pointer to the input memory. + * Output:pointer to the output memory. + * Len:remaining data length. + * Offset:indicates the offset. + * Modify the register: Input output len. + * Output register: + * Input output len + */ +.macro UPDATE_DATA input output len offset + leaq \offset(\input), \input + leaq \offset(\output), \output + subl $\offset, \len +.endm + +/** + * Function description:Sets the AES encrypted assembly acceleration API, ctr mode. + * Function prototype:int32_t CRYPT_AES_CTR_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, + * uint32_t len, uint8_t *iv); + * Input register: + * rdi:Pointer to the input key structure. + * rsi:Points to the 128-bit input data. + * rdx:Points to the 128-bit output data. + * rcx:Length of the data block, that is, 16 bytes. + * r8: 16-byte initialization vector. + * Change register:xmm1, xmm3, xmm4, xmm5, xmm6, xmm10, xmm11, xmm12, xmm13. + * Output register:rdx, r8. + */ +.globl CRYPT_AES_CTR_Encrypt + .type CRYPT_AES_CTR_Encrypt, @function +CRYPT_AES_CTR_Encrypt: + .cfi_startproc + pushq %r12 + pushq %r13 + pushq %r14 + mov %rsp, %r12 + subq $128, %rsp // Declare for 128-byte stack space. + andq $-16, %rsp + + vmovdqu (KEY), RDK + vpxor (CTR_IV), RDK, IV0 + vmovdqa IV0, 0(%rsp) + vmovdqa IV0, 16(%rsp) + vmovdqa IV0, 32(%rsp) + vmovdqa IV0, 48(%rsp) + vmovdqa IV0, 64(%rsp) + vmovdqa IV0, 80(%rsp) + vmovdqa IV0, 96(%rsp) + vmovdqa IV0, 112(%rsp) + + movl 12(CTR_IV), %r11d // Read 32-bit ctr. + movl 12(KEY), %r9d // Read 32-bit key. + bswap %r11d + + mov LEN, %r14d + shr $4, %r14d + and $7, %r14d + cmp $1, %r14d + je .Lctr_enc_proc_1_blk + cmp $2, %r14d + je .Lctr_enc_proc_2_blk + cmp $3, %r14d + je .Lctr_enc_proc_3_blk + cmp $4, %r14d + je .Lctr_enc_proc_4_blk + cmp $5, %r14d + je .Lctr_enc_proc_5_blk + cmp $6, %r14d + je .Lctr_enc_proc_6_blk + cmp $7, %r14d + je .Lctr_enc_proc_7_blk + +.Lctr_enc_proc_8_blk: + cmp $0, LEN + je .Lctr_aesenc_finish + XOR_KEY %r11d, 0, %r10d, %r9d, 0, %rsp + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp + XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp + XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp + XOR_KEY %r11d, 5, %r10d, %r9d, 80, %rsp + XOR_KEY %r11d, 6, %r10d, %r9d, 96, %rsp + XOR_KEY %r11d, 7, %r10d, %r9d, 112, %rsp + vmovdqa (%rsp), IV0 + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 + vmovdqa 48(%rsp), IV3 + vmovdqa 64(%rsp), IV4 + vmovdqa 80(%rsp), IV5 + vmovdqa 96(%rsp), IV6 + vmovdqa 112(%rsp), IV7 +.align 16 +.Lctr_aesenc_8_blks_enc_loop: + addl $8, %r11d // ctr+8 + movl 240(KEY), ROUNDS + ONE_ENC_XOR_KEY KEY, 16, RDK2, %r11d, 0, %r10d, %r9d, 0, %rsp // Round 1 encryption + ONE_ENC_XOR_KEY KEY, 32, RDK2, %r11d, 1, %r10d, %r9d, 16, %rsp // Round 2 encryption + ONE_ENC_XOR_KEY KEY, 48, RDK2, %r11d, 2, %r10d, %r9d, 32, %rsp // Round 3 encryption + ONE_ENC_XOR_KEY KEY, 64, RDK2, %r11d, 3, %r10d, %r9d, 48, %rsp // Round 4 encryption + ONE_ENC_XOR_KEY KEY, 80, RDK2, %r11d, 4, %r10d, %r9d, 64, %rsp // Round 5 encryption + ONE_ENC_XOR_KEY KEY, 96, RDK2, %r11d, 5, %r10d, %r9d, 80, %rsp // Round 6 encryption + ONE_ENC_XOR_KEY KEY, 112, RDK2, %r11d, 6, %r10d, %r9d, 96, %rsp // Round 7 encryption + ONE_ENC_XOR_KEY KEY, 128, RDK2, %r11d, 7, %r10d, %r9d, 112, %rsp // Round 8 encryption + + vmovdqu 144(KEY), RDK // Round 9 key Load + vmovdqu 160(KEY), RDK2 // Round 10 key Load + cmp $12, ROUNDS + jb .Lctr_aesenc_8_blks_enc_last + + ONE_ENC RDK, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 9 encryption + vmovdqu 176(KEY), RDK // Round 11 key Load + ONE_ENC RDK2, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 10 encryption + vmovdqu 192(KEY), RDK2 // Round 12 key Load + + je .Lctr_aesenc_8_blks_enc_last + + ONE_ENC RDK, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 11 encryption + vmovdqu 208(KEY), RDK // Round 13 key Load + ONE_ENC RDK2, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 12 encryption + vmovdqu 224(KEY), RDK2 // Round 14 key Load + +.align 16 +.Lctr_aesenc_8_blks_enc_last: + vpxor (INPUT), RDK2, BLK0 // Last round Key ^ Plaintext. + vpxor 16(INPUT), RDK2, BLK1 + vpxor 32(INPUT), RDK2, BLK2 + vpxor 48(INPUT), RDK2, BLK3 + + ONE_ENC RDK, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 + + aesenclast BLK0, IV0 // Last round of encryption. + aesenclast BLK1, IV1 + aesenclast BLK2, IV2 + aesenclast BLK3, IV3 + aesenclast RDK2, IV4 + aesenclast RDK2, IV5 + aesenclast RDK2, IV6 + aesenclast RDK2, IV7 + + vmovdqu IV0, (OUTPUT) // The first four ciphertexts are stored in out. + vmovdqu IV1, 16(OUTPUT) + vmovdqu IV2, 32(OUTPUT) + vmovdqu IV3, 48(OUTPUT) + vpxor 64(INPUT), IV4, BLK0 // Last Round Key ^ Plaintext. + vpxor 80(INPUT), IV5, BLK1 + vpxor 96(INPUT), IV6, BLK2 + vpxor 112(INPUT), IV7, BLK3 + + vmovdqu BLK0, 64(OUTPUT) + vmovdqu BLK1, 80(OUTPUT) + vmovdqu BLK2, 96(OUTPUT) // The last four ciphertexts are stored in out. + vmovdqu BLK3, 112(OUTPUT) + vmovdqa (%rsp), IV0 // Reads the next round of ctr from the stack. + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 + vmovdqa 48(%rsp), IV3 + vmovdqa 64(%rsp), IV4 + vmovdqa 80(%rsp), IV5 + vmovdqa 96(%rsp), IV6 + vmovdqa 112(%rsp), IV7 + UPDATE_DATA INPUT, OUTPUT, LEN, 128 + cmpl $0, LEN + jbe .Lctr_aesenc_finish + jmp .Lctr_aesenc_8_blks_enc_loop + +.Lctr_enc_proc_1_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS +.align 16 +.Laesenc_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + decl ROUNDS + jnz .Laesenc_loop // Loop the loop until the ROUNDS is 0. + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + addl $1, %r11d // Update ctr32. + vpxor (INPUT), IV0, BLK0 + vmovdqu BLK0, (OUTPUT) // Ciphertext stored in out. + UPDATE_DATA INPUT, OUTPUT, LEN, 16 + jmp .Lctr_enc_proc_8_blk +.Lctr_enc_proc_2_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + vmovdqa 16(%rsp), IV1 +.align 16 +.Laesenc_2_blks_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + aesenc RDK, IV1 + decl ROUNDS + jnz .Laesenc_2_blks_loop + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + aesenclast RDK, IV1 + + vpxor (INPUT), IV0, BLK0 + vpxor 16(INPUT), IV1, BLK1 + vmovdqu BLK0, (OUTPUT) + vmovdqu BLK1, 16(OUTPUT) + addl $2, %r11d + UPDATE_DATA INPUT, OUTPUT, LEN, 32 + jmp .Lctr_enc_proc_8_blk +.Lctr_enc_proc_3_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 +.align 16 +.Laesenc_3_blks_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + aesenc RDK, IV1 + aesenc RDK, IV2 + decl ROUNDS + jnz .Laesenc_3_blks_loop + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + aesenclast RDK, IV1 + aesenclast RDK, IV2 + + vpxor (INPUT), IV0, BLK0 + vpxor 16(INPUT), IV1, BLK1 + vpxor 32(INPUT), IV2, BLK2 + + vmovdqu BLK0, (OUTPUT) + vmovdqu BLK1, 16(OUTPUT) + vmovdqu BLK2, 32(OUTPUT) + addl $3, %r11d + UPDATE_DATA INPUT, OUTPUT, LEN, 48 + jmp .Lctr_enc_proc_8_blk +.Lctr_enc_proc_4_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp + XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 + vmovdqa 48(%rsp), IV3 +.align 16 +.Laesenc_4_blks_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + aesenc RDK, IV1 + aesenc RDK, IV2 + aesenc RDK, IV3 + decl ROUNDS + jnz .Laesenc_4_blks_loop + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + aesenclast RDK, IV1 + aesenclast RDK, IV2 + aesenclast RDK, IV3 + + vpxor (INPUT), IV0, BLK0 + vpxor 16(INPUT), IV1, BLK1 + vpxor 32(INPUT), IV2, BLK2 + vpxor 48(INPUT), IV3, BLK3 + + vmovdqu BLK0, (OUTPUT) + vmovdqu BLK1, 16(OUTPUT) + vmovdqu BLK2, 32(OUTPUT) + vmovdqu BLK3, 48(OUTPUT) + addl $4, %r11d + UPDATE_DATA INPUT, OUTPUT, LEN, 64 + jmp .Lctr_enc_proc_8_blk + +.Lctr_enc_proc_5_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp + XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp + XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 + vmovdqa 48(%rsp), IV3 + vmovdqa 64(%rsp), IV4 +.align 16 +.Laesenc_5_blks_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + aesenc RDK, IV1 + aesenc RDK, IV2 + aesenc RDK, IV3 + aesenc RDK, IV4 + decl ROUNDS + jnz .Laesenc_5_blks_loop + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + aesenclast RDK, IV1 + aesenclast RDK, IV2 + aesenclast RDK, IV3 + aesenclast RDK, IV4 + + vpxor (INPUT), IV0, BLK0 + vpxor 16(INPUT), IV1, BLK1 + vpxor 32(INPUT), IV2, BLK2 + vpxor 48(INPUT), IV3, BLK3 + vpxor 64(INPUT), IV4, BLK4 + vmovdqu BLK0, (OUTPUT) + vmovdqu BLK1, 16(OUTPUT) + vmovdqu BLK2, 32(OUTPUT) + vmovdqu BLK3, 48(OUTPUT) + vmovdqu BLK4, 64(OUTPUT) + addl $5, %r11d + UPDATE_DATA INPUT, OUTPUT, LEN, 80 + jmp .Lctr_enc_proc_8_blk +.Lctr_enc_proc_6_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp + XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp + XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp + XOR_KEY %r11d, 5, %r10d, %r9d, 80, %rsp + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 + vmovdqa 48(%rsp), IV3 + vmovdqa 64(%rsp), IV4 + vmovdqa 80(%rsp), IV5 +.align 16 +.Laesenc_6_blks_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + aesenc RDK, IV1 + aesenc RDK, IV2 + aesenc RDK, IV3 + aesenc RDK, IV4 + aesenc RDK, IV5 + decl ROUNDS + jnz .Laesenc_6_blks_loop + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + aesenclast RDK, IV1 + aesenclast RDK, IV2 + aesenclast RDK, IV3 + aesenclast RDK, IV4 + aesenclast RDK, IV5 + + vpxor (INPUT), IV0, BLK0 + vpxor 16(INPUT), IV1, BLK1 + vpxor 32(INPUT), IV2, BLK2 + vpxor 48(INPUT), IV3, BLK3 + vpxor 64(INPUT), IV4, BLK4 + vpxor 80(INPUT), IV5, BLK5 + vmovdqu BLK0, (OUTPUT) + vmovdqu BLK1, 16(OUTPUT) + vmovdqu BLK2, 32(OUTPUT) + vmovdqu BLK3, 48(OUTPUT) + vmovdqu BLK4, 64(OUTPUT) + vmovdqu BLK5, 80(OUTPUT) + addl $6, %r11d + UPDATE_DATA INPUT, OUTPUT, LEN, 96 + + jmp .Lctr_enc_proc_8_blk +.Lctr_enc_proc_7_blk: + movl 240(KEY), ROUNDS + movq KEY, KTMP + decl ROUNDS + XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp + XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp + XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp + XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp + XOR_KEY %r11d, 5, %r10d, %r9d, 80, %rsp + XOR_KEY %r11d, 6, %r10d, %r9d, 96, %rsp + vmovdqa 16(%rsp), IV1 + vmovdqa 32(%rsp), IV2 + vmovdqa 48(%rsp), IV3 + vmovdqa 64(%rsp), IV4 + vmovdqa 80(%rsp), IV5 + vmovdqa 96(%rsp), IV6 + +.align 16 +.Laesenc_7_blks_loop: + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenc RDK, IV0 + aesenc RDK, IV1 + aesenc RDK, IV2 + aesenc RDK, IV3 + aesenc RDK, IV4 + aesenc RDK, IV5 + aesenc RDK, IV6 + decl ROUNDS + jnz .Laesenc_7_blks_loop + leaq 16(KTMP), KTMP + vmovdqu (KTMP), RDK + aesenclast RDK, IV0 + aesenclast RDK, IV1 + aesenclast RDK, IV2 + aesenclast RDK, IV3 + aesenclast RDK, IV4 + aesenclast RDK, IV5 + aesenclast RDK, IV6 + vpxor (INPUT), IV0, BLK0 + vpxor 16(INPUT), IV1, BLK1 + vpxor 32(INPUT), IV2, BLK2 + vpxor 48(INPUT), IV3, BLK3 + vmovdqu BLK0, (OUTPUT) + vmovdqu BLK1, 16(OUTPUT) + vmovdqu BLK2, 32(OUTPUT) + vmovdqu BLK3, 48(OUTPUT) + vpxor 64(INPUT), IV4, BLK0 + vpxor 80(INPUT), IV5, BLK1 + vpxor 96(INPUT), IV6, BLK2 + vmovdqu BLK0, 64(OUTPUT) + vmovdqu BLK1, 80(OUTPUT) + vmovdqu BLK2, 96(OUTPUT) + addl $7, %r11d + UPDATE_DATA INPUT, OUTPUT, LEN, 112 + jmp .Lctr_enc_proc_8_blk + +.Lctr_aesenc_finish: + bswap %r11d + movl %r11d, 12(CTR_IV) + vpxor IV0, IV0, IV0 + vpxor IV1, IV1, IV1 + vpxor IV2, IV2, IV2 + vpxor IV3, IV3, IV3 + vpxor IV4, IV4, IV4 + vpxor IV5, IV5, IV5 + vpxor IV6, IV6, IV6 + vpxor IV7, IV7, IV7 + vpxor RDK, RDK, RDK + vmovdqa IV0, 0(%rsp) + vmovdqa IV0, 16(%rsp) + vmovdqa IV0, 32(%rsp) + vmovdqa IV0, 48(%rsp) + vmovdqa IV0, 64(%rsp) + vmovdqa IV0, 80(%rsp) + vmovdqa IV0, 96(%rsp) + vmovdqa IV0, 112(%rsp) + + movq %r12, %rsp + popq %r14 + popq %r13 + popq %r12 + + movl $0, RET + ret + .cfi_endproc + .size CRYPT_AES_CTR_Encrypt, .-CRYPT_AES_CTR_Encrypt + +#endif diff --git a/crypto/aes/src/asm/crypt_aes_ecb_armv8.S b/crypto/aes/src/asm/crypt_aes_ecb_armv8.S new file mode 100644 index 00000000..20e251b6 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_ecb_armv8.S @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_ecb_x86_64.S b/crypto/aes/src/asm/crypt_aes_ecb_x86_64.S new file mode 100644 index 00000000..a2913e47 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_ecb_x86_64.S @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_macro_armv8.s b/crypto/aes/src/asm/crypt_aes_macro_armv8.s new file mode 100644 index 00000000..65817baa --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_macro_armv8.s @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_macro_x86_64.s b/crypto/aes/src/asm/crypt_aes_macro_x86_64.s new file mode 100644 index 00000000..c5f816b3 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_macro_x86_64.s @@ -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 diff --git a/crypto/aes/src/asm/crypt_aes_x86_64.S b/crypto/aes/src/asm/crypt_aes_x86_64.S new file mode 100644 index 00000000..5f3681f3 --- /dev/null +++ b/crypto/aes/src/asm/crypt_aes_x86_64.S @@ -0,0 +1,1056 @@ +/* + * 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_x86_64.s" + + .file "crypt_aes_x86_64.S" + .text + +.set ARG1, %rdi +.set ARG2, %rsi +.set ARG3, %rdx +.set ARG4, %rcx +.set ARG5, %r8 +.set ARG6, %r9 +.set RET, %eax + +.set XM0, %xmm0 +.set XM1, %xmm1 +.set XM2, %xmm2 +.set XM3, %xmm3 +.set XM4, %xmm4 +.set XM5, %xmm5 + +/** + * aes128 macros for key extension processing. + */ +.macro KEY_EXPANSION_HELPER_128 xm0 xm1 xm2 + vpermilps $0xff, \xm1, \xm1 + vpslldq $4, \xm0, \xm2 + vpxor \xm2, \xm0, \xm0 + vpslldq $4, \xm2, \xm2 + vpxor \xm2, \xm0, \xm0 + vpslldq $4, \xm2, \xm2 + vpxor \xm2, \xm0, \xm0 + vpxor \xm1, \xm0, \xm0 +.endm + +/** + * aes192 macros for key extension processing. + */ +.macro KEY_EXPANSION_HELPER_192 xm1 xm3 + vpslldq $4, \xm1, \xm3 + vpxor \xm3, \xm1, \xm1 + vpslldq $4, \xm3, \xm3 + vpxor \xm3, \xm1, \xm1 + vpslldq $4, \xm3, \xm3 + vpxor \xm3, \xm1, \xm1 +.endm + +/** + * Function description: Sets the AES encryption key. Key length: 128 bits. + * Function prototype: void SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key); + * Input register: + * x0:Pointer to the output key structure. + * x1:Pointer to the input key. + * Change register:xmm0-xmm2. + * Output register:None. + * Function/Macro Call: None. + */ + .globl SetEncryptKey128 + .type SetEncryptKey128, @function +SetEncryptKey128: + .cfi_startproc + + movl $10, 240(%rdi) + movdqu (ARG2), XM0 + movdqu XM0, (ARG1) + + aeskeygenassist $0x01, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 16(ARG1) + + aeskeygenassist $0x02, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 32(ARG1) + + aeskeygenassist $0x04, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 48(ARG1) + + aeskeygenassist $0x08, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 64(ARG1) + + aeskeygenassist $0x10, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 80(ARG1) + + aeskeygenassist $0x20, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 96(ARG1) + + aeskeygenassist $0x40, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 112(ARG1) + + aeskeygenassist $0x80, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 128(ARG1) + + aeskeygenassist $0x1b, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 144(ARG1) + + aeskeygenassist $0x36, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0, 160(ARG1) + + vpxor XM0, XM0, XM0 + vpxor XM1, XM1, XM1 + vpxor XM2, XM2, XM2 + + ret + .cfi_endproc + .size SetEncryptKey128, .-SetEncryptKey128 + +/** + * Function description: Sets the AES decryption key. Key length: 128 bits. + * Function prototype: void SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key); + * Input register: + * x0:Pointer to the output key structure. + * x1:Pointer to the input key. + * Change register:xmm0-xmm3. + * Output register: None. + * Function/Macro Call: None. + */ + .globl SetDecryptKey128 + .type SetDecryptKey128, @function +SetDecryptKey128: + .cfi_startproc + + movl $10, 240(%rdi) + movdqu (ARG2), XM0 + movdqu XM0, 160(ARG1) + + aeskeygenassist $0x01, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 144(ARG1) + + aeskeygenassist $0x02, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 128(ARG1) + + aeskeygenassist $0x04, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 112(ARG1) + + aeskeygenassist $0x08, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 96(ARG1) + + aeskeygenassist $0x10, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 80(ARG1) + + aeskeygenassist $0x20, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 64(ARG1) + + aeskeygenassist $0x40, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 48(ARG1) + + aeskeygenassist $0x80, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 32(ARG1) + + aeskeygenassist $0x1b, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + aesimc XM0, XM3 + movdqu XM3, 16(ARG1) + + aeskeygenassist $0x36, XM0, XM1 + KEY_EXPANSION_HELPER_128 XM0, XM1, XM2 + movdqu XM0,(ARG1) + + vpxor XM0, XM0, XM0 + vpxor XM1, XM1, XM1 + vpxor XM2, XM2, XM2 + vpxor XM3, XM3, XM3 + + ret + .cfi_endproc + .size SetDecryptKey128, .-SetDecryptKey128 + +/** + * Function description: Sets the AES encryption key. Key length: 192 bits. + * Function prototype: void SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key); + * Input register: + * x0:Pointer to the output key structure. + * x1:Pointer to the input key. + * Change register: xmm0-xmm4. + * Output register: None. + * Function/Macro Call: None. + */ + .globl SetEncryptKey192 + .type SetEncryptKey192, @function +SetEncryptKey192: + .cfi_startproc + + movl $12, 240(ARG1) + movdqu (ARG2), XM0 + movdqu 8(ARG2), XM1 + movdqu XM0,(ARG1) + + vpxor XM4, XM4, XM4 + vshufps $0x40, XM0, XM4, XM2 + aeskeygenassist $0x01, XM1, XM0 + vshufps $0xf0, XM0, XM4, XM0 + vpslldq $0x04, XM2, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM0, XM0 + vshufps $0xee, XM0, XM1, XM0 + movdqu XM0, 16(ARG1) + + movdqu XM1, XM2 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpermilps $0xff, XM0, XM3 + vpxor XM3, XM2, XM2 + movdqu XM2, 32(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + aeskeygenassist $0x02, XM2, XM0 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM0, XM0 + vpxor XM1, XM0, XM0 + movdqu XM0, 48(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + vpslldq $8, XM1, XM2 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpermilps $0xff, XM0, XM3 + vpxor XM3, XM2, XM2 + aeskeygenassist $0x04, XM2, XM3 + vpermilps $0xff, XM3, XM3 + vpsrldq $8, XM1, XM4 + vpslldq $12, XM4, XM4 + vpxor XM4, XM1, XM1 + vpxor XM3, XM1, XM1 + vshufps $0xee, XM1, XM2, XM2 + movdqu XM2, 64(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM0 + vpxor XM1, XM0, XM0 + movdqu XM0, 80(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + aeskeygenassist $0x08, XM0, XM2 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM2 + vpxor XM1, XM2, XM2 + movdqu XM2, 96(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + vpslldq $8, XM1, XM0 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpermilps $0xff, XM2, XM3 + vpxor XM3, XM0, XM0 + aeskeygenassist $0x10, XM0, XM3 + vpermilps $0xff, XM3, XM3 + vpsrldq $8, XM1, XM4 + vpslldq $12, XM4, XM4 + vpxor XM4, XM1, XM1 + vpxor XM3, XM1, XM1 + vshufps $0xee, XM1, XM0, XM0 + movdqu XM0, 112(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM0, XM2 + vpxor XM1, XM2, XM2 + movdqu XM2, 128(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + aeskeygenassist $0x20, XM2, XM0 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM0, XM0 + vpxor XM1, XM0, XM0 + movdqu XM0, 144(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + vpslldq $8, XM1, XM2 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpermilps $0xff, XM0, XM3 + vpxor XM3, XM2, XM2 + aeskeygenassist $0x40, XM2, XM3 + vpermilps $0xff, XM3, XM3 + vpsrldq $8, XM1, XM4 + vpslldq $12, XM4, XM4 + vpxor XM4, XM1, XM1 + vpxor XM3, XM1, XM1 + vshufps $0xee, XM1, XM2, XM2 + movdqu XM2, 160(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM0 + vpxor XM1, XM0, XM0 + movdqu XM0, 176(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + aeskeygenassist $0x80, XM0, XM2 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM2 + vpxor XM1, XM2, XM2 + movdqu XM2, 192(ARG1) + + vpxor XM0, XM0, XM0 + vpxor XM1, XM1, XM1 + vpxor XM2, XM2, XM2 + vpxor XM3, XM3, XM3 + vpxor XM4, XM4, XM4 + + ret + .cfi_endproc + .size SetEncryptKey192, .-SetEncryptKey192 + +/** + * Function description: Sets the AES decryption key. Key length: 192 bits. + * Function prototype: void SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key); + * Input register: + * x0:Pointer to the output key structure. + * x1:Pointer to the input key. + * Change register: xmm0-xmm5 + * Output register: None. + * Function/Macro Call: None. + */ + .globl SetDecryptKey192 + .type SetDecryptKey192, @function +SetDecryptKey192: + .cfi_startproc + + movl $12, 240(ARG1) + movdqu (ARG2), XM0 + movdqu 8(ARG2), XM1 + movdqu XM0, 192(ARG1) + + vpxor XM4, XM4, XM4 + vshufps $0x40, XM0, XM4, XM2 + aeskeygenassist $0x01, XM1, XM0 + vshufps $0xf0, XM0, XM4, XM0 + vpslldq $0x04, XM2, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM0, XM0 + vshufps $0xee, XM0, XM1, XM0 + aesimc XM0, XM5 + movdqu XM5, 176(ARG1) + + movdqu XM1, XM2 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpermilps $0xff, XM0, XM3 + vpxor XM3, XM2, XM2 + aesimc XM2, XM5 + movdqu XM5, 160(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + aeskeygenassist $0x02, XM2, XM0 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM0, XM0 + vpxor XM1, XM0, XM0 + aesimc XM0, XM5 + movdqu XM5, 144(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + vpslldq $8, XM1, XM2 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpermilps $0xff, XM0, XM3 + vpxor XM3, XM2, XM2 + aeskeygenassist $0x04, XM2, XM3 + vpermilps $0xff, XM3, XM3 + vpsrldq $8, XM1, XM4 + vpslldq $12, XM4, XM4 + vpxor XM4, XM1, XM1 + vpxor XM3, XM1, XM1 + vshufps $0xee, XM1, XM2, XM2 + aesimc XM2, XM5 + movdqu XM5, 128(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM0 + vpxor XM1, XM0, XM0 + aesimc XM0, XM5 + movdqu XM5,112(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + aeskeygenassist $0x08, XM0, XM2 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM2 + vpxor XM1, XM2, XM2 + aesimc XM2, XM5 + movdqu XM5, 96(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + vpslldq $8, XM1, XM0 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpermilps $0xff, XM2, XM3 + vpxor XM3, XM0, XM0 + aeskeygenassist $0x10, XM0, XM3 + vpermilps $0xff, XM3, XM3 + vpsrldq $8, XM1, XM4 + vpslldq $12, XM4, XM4 + vpxor XM4, XM1, XM1 + vpxor XM3, XM1, XM1 + vshufps $0xee, XM1, XM0, XM0 + aesimc XM0, XM5 + movdqu XM5, 80(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM0, XM2 + vpxor XM1, XM2, XM2 + aesimc XM2, XM5 + movdqu XM5, 64(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + aeskeygenassist $0x20, XM2, XM0 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM0, XM0 + vpxor XM1, XM0, XM0 + aesimc XM0, XM5 + movdqu XM5, 48(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + vpslldq $8, XM1, XM2 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpermilps $0xff, XM0, XM3 + vpxor XM3, XM2, XM2 + aeskeygenassist $0x40, XM2, XM3 + vpermilps $0xff, XM3, XM3 + vpsrldq $8, XM1, XM4 + vpslldq $12, XM4, XM4 + vpxor XM4, XM1, XM1 + vpxor XM3, XM1, XM1 + vshufps $0xee, XM1, XM2, XM2 + aesimc XM2, XM5 + movdqu XM5, 32(ARG1) + + vshufps $0x4e, XM2, XM0, XM1 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM0 + vpxor XM1, XM0, XM0 + aesimc XM0, XM5 + movdqu XM5, 16(ARG1) + + vshufps $0x4e, XM0, XM2, XM1 + aeskeygenassist $0x80, XM0, XM2 + KEY_EXPANSION_HELPER_192 XM1, XM3 + vpermilps $0xff, XM2, XM2 + vpxor XM1, XM2, XM2 + movdqu XM2,(ARG1) + + vpxor XM0, XM0, XM0 + vpxor XM1, XM1, XM1 + vpxor XM2, XM2, XM2 + vpxor XM3, XM3, XM3 + vpxor XM4, XM4, XM4 + vpxor XM5, XM5, XM5 + + ret + .cfi_endproc + .size SetDecryptKey192, .-SetDecryptKey192 + +/** + * Function description: Sets the AES encryption key. Key length: 192 bits. + * Function prototype: void SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key); + * Input register: + * x0:Pointer to the output key structure. + * x1:Pointer to the input key. + * Change register: xmm0-xmm3. + * Output register: None. + * Function/Macro Call: None. + */ + .globl SetEncryptKey256 + .type SetEncryptKey256, @function +SetEncryptKey256: + .cfi_startproc + + movl $14, 240(ARG1) + movdqu (ARG2), XM0 + movdqu 16(ARG2), XM1 + movdqu XM0, (ARG1) + movdqu XM1, 16(ARG1) + + aeskeygenassist $0x01, XM1, XM2 + vpermilps $0xff, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + movdqu XM2, 32(ARG1) + + aeskeygenassist $0x01, XM2, XM0 + vpermilps $0xAA, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + movdqu XM0, 48(ARG1) + /*2*/ + aeskeygenassist $0x02, XM0, XM1 + vpermilps $0xff, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + movdqu XM1, 64(ARG1) + + aeskeygenassist $0x02, XM1, XM2 + vpermilps $0xAA, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + movdqu XM2, 80(ARG1) + /*3*/ + aeskeygenassist $0x04, XM2, XM0 + vpermilps $0xff, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + movdqu XM0, 96(ARG1) + + aeskeygenassist $0x04, XM0, XM1 + vpermilps $0xAA, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + movdqu XM1, 112(ARG1) + /*4*/ + aeskeygenassist $0x08, XM1, XM2 + vpermilps $0xff, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + movdqu XM2, 128(ARG1) + + aeskeygenassist $0x08, XM2, XM0 + vpermilps $0xAA, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + movdqu XM0, 144(ARG1) + /*5*/ + aeskeygenassist $0x10, XM0, XM1 + vpermilps $0xff, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + movdqu XM1, 160(ARG1) + + aeskeygenassist $0x10, XM1, XM2 + vpermilps $0xAA, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + movdqu XM2, 176(ARG1) + /*6*/ + aeskeygenassist $0x20, XM2, XM0 + vpermilps $0xff, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + movdqu XM0, 192(ARG1) + + aeskeygenassist $0x20, XM0, XM1 + vpermilps $0xAA, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + movdqu XM1, 208(ARG1) + /*7*/ + aeskeygenassist $0x40, XM1, XM2 + vpermilps $0xff, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + movdqu XM2, 224(ARG1) + + vpxor XM0, XM0, XM0 + vpxor XM1, XM1, XM1 + vpxor XM2, XM2, XM2 + vpxor XM3, XM3, XM3 + + ret + .cfi_endproc + .size SetEncryptKey256, .-SetEncryptKey256 + + + /** + * Function description: Sets the AES encryption key. Key length: 192 bits. + * Function prototype: void SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key); + * Input register: + * x0:Pointer to the output key structure. + * x1:Pointer to the input key. + * Change register: xmm0-xmm4. + * Output register: None. + * Function/Macro Call: None. + */ + .globl SetDecryptKey256 + .type SetDecryptKey256, @function +SetDecryptKey256: + .cfi_startproc + + movl $14, 240(ARG1) + movdqu (ARG2), XM0 + movdqu 16(ARG2), XM1 + movdqu XM0, 224(ARG1) + + aesimc XM1, XM4 + movdqu XM4, 208(ARG1) + + aeskeygenassist $0x01, XM1, XM2 + vpermilps $0xff, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + aesimc XM2, XM4 + movdqu XM4, 192(ARG1) + + aeskeygenassist $0x01, XM2, XM0 + vpermilps $0xAA, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + aesimc XM0, XM4 + movdqu XM4, 176(ARG1) + /*2*/ + aeskeygenassist $0x02, XM0, XM1 + vpermilps $0xff, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + aesimc XM1, XM4 + movdqu XM4, 160(ARG1) + + aeskeygenassist $0x02, XM1, XM2 + vpermilps $0xAA, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + aesimc XM2, XM4 + movdqu XM4, 144(ARG1) + /*3*/ + aeskeygenassist $0x04, XM2, XM0 + vpermilps $0xff, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + aesimc XM0, XM4 + movdqu XM4, 128(ARG1) + + aeskeygenassist $0x04, XM0, XM1 + vpermilps $0xAA, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + aesimc XM1, XM4 + movdqu XM4, 112(ARG1) + /*4*/ + aeskeygenassist $0x08, XM1, XM2 + vpermilps $0xff, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + aesimc XM2, XM4 + movdqu XM4, 96(ARG1) + + aeskeygenassist $0x08, XM2, XM0 + vpermilps $0xAA, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + aesimc XM0, XM4 + movdqu XM4, 80(ARG1) + /*5*/ + aeskeygenassist $0x10, XM0, XM1 + vpermilps $0xff, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + aesimc XM1, XM4 + movdqu XM4, 64(ARG1) + + aeskeygenassist $0x10, XM1, XM2 + vpermilps $0xAA, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + aesimc XM2, XM4 + movdqu XM4, 48(ARG1) + /*6*/ + aeskeygenassist $0x20, XM2, XM0 + vpermilps $0xff, XM0, XM0 + vpslldq $4, XM1, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpslldq $4, XM3, XM3 + vpxor XM3, XM1, XM1 + vpxor XM1, XM0, XM0 + aesimc XM0, XM4 + movdqu XM4, 32(ARG1) + + aeskeygenassist $0x20, XM0, XM1 + vpermilps $0xAA, XM1, XM1 + vpslldq $4, XM2, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpslldq $4, XM3, XM3 + vpxor XM3, XM2, XM2 + vpxor XM2, XM1, XM1 + aesimc XM1, XM4 + movdqu XM4, 16(ARG1) + /*7*/ + aeskeygenassist $0x40, XM1, XM2 + vpermilps $0xff, XM2, XM2 + vpslldq $4, XM0, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpslldq $4, XM3, XM3 + vpxor XM3, XM0, XM0 + vpxor XM0, XM2, XM2 + movdqu XM2, (ARG1) + + vpxor XM0, XM0, XM0 + vpxor XM1, XM1, XM1 + vpxor XM2, XM2, XM2 + vpxor XM3, XM3, XM3 + vpxor XM4, XM4, XM4 + + ret + .cfi_endproc + .size SetDecryptKey256, .-SetDecryptKey256 + +/** + * Function description: This API is used to set the AES encryption assembly acceleration. + * Function prototype: int32_t CRYPT_AES_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: xmm0-xmm1. + * Output register: eax. + * Function/Macro Call: None. + */ + .globl CRYPT_AES_Encrypt + .type CRYPT_AES_Encrypt, @function +CRYPT_AES_Encrypt: + .cfi_startproc + .set ROUNDS,%eax + + movdqu (ARG2), XM0 + movl 240(ARG1),ROUNDS + + vpxor (ARG1), XM0, XM0 + + movdqu 16(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 32(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 48(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 64(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 80(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 96(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 112(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 128(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 144(ARG1), XM1 + aesenc XM1, XM0 + + cmpl $10,ROUNDS + je .aesenc_128 + + movdqu 160(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 176(ARG1), XM1 + aesenc XM1, XM0 + + cmpl $12,ROUNDS + je .aesenc_192 + + movdqu 192(ARG1), XM1 + aesenc XM1, XM0 + + movdqu 208(ARG1), XM1 + aesenc XM1, XM0 + + cmpl $14,ROUNDS + je .aesenc_256 + +.aesenc_128: + movdqu 160(ARG1), XM1 + aesenclast XM1, XM0 + jmp .aesenc_end + +.aesenc_192: + movdqu 192(ARG1), XM1 + aesenclast XM1, XM0 + jmp .aesenc_end + +.aesenc_256: + movdqu 224(ARG1), XM1 + aesenclast XM1, XM0 + +.aesenc_end: + vpxor XM1, XM1, XM1 + movdqu XM0,(ARG3) + vpxor XM0, XM0, XM0 + movl $0,RET + ret + .cfi_endproc + .size CRYPT_AES_Encrypt, .-CRYPT_AES_Encrypt + +/** + * Function description: AES decryption and assembly acceleration API. + * Function prototype: int32_t CRYPT_AES_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: xmm0-xmm1. + * Output register: eax. + * Function/Macro Call: None. + */ + .globl CRYPT_AES_Decrypt + .type CRYPT_AES_Decrypt, @function +CRYPT_AES_Decrypt: + .cfi_startproc + .set ROUNDS,%eax + + movdqu (ARG2), XM0 + movl 240(ARG1),ROUNDS + vpxor (ARG1), XM0, XM0 + + movdqu 16(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 32(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 48(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 64(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 80(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 96(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 112(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 128(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 144(ARG1), XM1 + aesdec XM1, XM0 + + cmpl $10,ROUNDS + je .aesdec_128 + + movdqu 160(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 176(ARG1), XM1 + aesdec XM1, XM0 + + cmpl $12,ROUNDS + je .aesdec_192 + + movdqu 192(ARG1), XM1 + aesdec XM1, XM0 + + movdqu 208(ARG1), XM1 + aesdec XM1, XM0 + + cmpl $14,ROUNDS + je .aesdec_256 + +.aesdec_128: + movdqu 160(ARG1), XM1 + aesdeclast XM1, XM0 + jmp .aesdec_end + +.aesdec_192: + movdqu 192(ARG1), XM1 + aesdeclast XM1, XM0 + jmp .aesdec_end + +.aesdec_256: + movdqu 224(ARG1), XM1 + aesdeclast XM1, XM0 + +.aesdec_end: + + vpxor XM1, XM1, XM1 + movdqu XM0,(ARG3) + vpxor XM0, XM0, XM0 + movl $0,RET + + ret + .cfi_endproc + .size CRYPT_AES_Decrypt, .-CRYPT_AES_Decrypt + +#endif diff --git a/crypto/aes/src/crypt_aes.c b/crypto/aes/src/crypt_aes.c new file mode 100644 index 00000000..abd8ff9a --- /dev/null +++ b/crypto/aes/src/crypt_aes.c @@ -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 */ diff --git a/crypto/aes/src/crypt_aes_local.h b/crypto/aes/src/crypt_aes_local.h new file mode 100644 index 00000000..268e5995 --- /dev/null +++ b/crypto/aes/src/crypt_aes_local.h @@ -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 diff --git a/crypto/aes/src/crypt_aes_setkey.c b/crypto/aes/src/crypt_aes_setkey.c new file mode 100644 index 00000000..591b8c97 --- /dev/null +++ b/crypto/aes/src/crypt_aes_setkey.c @@ -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 */ diff --git a/crypto/bn/include/crypt_bn.h b/crypto/bn/include/crypt_bn.h new file mode 100644 index 00000000..2e208688 --- /dev/null +++ b/crypto/bn/include/crypt_bn.h @@ -0,0 +1,1109 @@ +/* + * 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_BN_H +#define CRYPT_BN_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(HITLS_SIXTY_FOUR_BITS) +#define BN_UINT uint64_t +#define BN_MASK (0xffffffffffffffffL) +#define BN_DEC_VAL (10000000000000000000ULL) +#elif defined(HITLS_THIRTY_TWO_BITS) +#define BN_UINT uint32_t +#define BN_MASK (0xffffffffL) +#define BN_DEC_VAL (1000000000L) +#else +#error BN_UINT MUST be defined first. +#endif + +#define BN_MAX_BITS (1u << 29) /* @note: BN_BigNum bits limitation 2^29 bits */ +#define BN_BITS_TO_BYTES(n) (((n) + 7) >> 3) /* @note: Calcute bytes form bits, bytes = (bits + 7) >> 3 */ +#define BN_BYTES_TO_BITS(n) ((n) << 3) /* bits = bytes * 8 = bytes << 3 */ + +/* Flag of BigNum. If a new number is added, the value increases by 0x01 0x02 0x04... */ +typedef enum { + CRYPT_BN_FLAG_OPTIMIZER = 0x01, /**< Flag of BigNum, indicating the BigNum obtained from the optimizer */ + CRYPT_BN_FLAG_CONSTTIME = 0x02, /**< Flag of BigNum, indicating the constant time execution. */ + CRYPT_BN_FLAG_ISNEGTIVE = 0x80000000, /**< Flag of BigNum, indicating the bignum is negtive. */ +} CRYPT_BN_FLAG; + +typedef struct BnMont BN_Mont; + +typedef struct BigNum BN_BigNum; + +typedef struct BnOptimizer BN_Optimizer; + +typedef struct BnCbCtx BN_CbCtx; + +typedef int32_t (*BN_CallBack)(BN_CbCtx *, int32_t, int32_t); + +/* If a is 0, all Fs are returned. If a is not 0, 0 is returned. */ +static inline BN_UINT BN_IsZeroUintConsttime(BN_UINT a) +{ + BN_UINT t = ~a & (a - 1); // The most significant bit of t is 1 only when a == 0. + // Shifting 3 bits to the left is equivalent to multiplying 8, convert the number of bytes into the number of bits. + return (BN_UINT)0 - (t >> (((uint32_t)sizeof(BN_UINT) << 3) - 1)); +} + +/** + * @ingroup bn + * @brief BigNum creation + * + * @param bits [IN] Number of bits + * + * @retval not-NULL Success + * @retval NULL fail + */ +BN_BigNum *BN_Create(uint32_t bits); + +/** + * @ingroup bn + * @brief BigNum Destruction + * + * @param a [IN] BigNum + * + * @retval none + */ +void BN_Destroy(BN_BigNum *a); + +/** + * @ingroup bn + * @brief BigNum callback creation + * + * @param none + * + * @retval not-NULL Success + * @retval NULL fail + */ +BN_CbCtx *BN_CbCtxCreate(void); + +/** + * @ingroup bn + * @brief BigNum callback configuration + * + * @param gencb [out] Callback + * @param callBack [in] Callback API + * @param arg [in] Callback parameters + * + * @retval none + */ +void BN_CbCtxSet(BN_CbCtx *gencb, BN_CallBack callBack, void *arg); + +/** + * @ingroup bn + * @brief Invoke the callback. + * + * @param callBack [out] Callback + * @param process [in] Parameter + * @param target [in] Parameter + + * @retval CRYPT_SUCCESS succeeded + * @retval other determined by the callback function + */ +int32_t BN_CbCtxCall(BN_CbCtx *callBack, int32_t process, int32_t target); + +/** + * @ingroup bn + * @brief Obtain the arg parameter in the callback. + * + * @param callBack [in] Callback + * @retval void* NULL or callback parameter. + */ +void *BN_CbCtxGetArg(BN_CbCtx *callBack); + +/** + * @ingroup bn + * @brief Callback release + * + * @param cb [in] Callback + * + * @retval none + */ +void BN_CbCtxDestroy(BN_CbCtx *cb); + +/** + * @ingroup bn + * @brief Set the symbol. + * + * @param a [IN] BigNum + * @param sign [IN] symbol. The value true indicates a negative number and the value false indicates a positive number. + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_BN_NO_NEGATOR_ZERO 0 cannot be set to a negative sign. + */ +int32_t BN_SetSign(BN_BigNum *a, bool sign); + +/** + * @ingroup bn + * @brief BigNum copy + * + * @param r [OUT] BigNum + * @param a [IN] BigNum, a != r. + * + * @retval CRYPT_SUCCESS succeeded. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_Copy(BN_BigNum *r, const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Generate a BigNum with the same content. + * + * @param a [IN] BigNum + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *BN_Dup(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Check whether the value of a BigNum is 0. + * + * @attention The input parameter cannot be null. + * @param a [IN] BigNum + * + * @retval true. The value of a BigNum is 0. + * @retval false. The value of a BigNum is not 0. + * @retval other: indicates that the input parameter is abnormal. + * + */ +bool BN_IsZero(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Check whether the value of a BigNum is 1. + * + * @attention The input parameter cannot be null. + * @param a [IN] BigNum + * + * @retval true. The value of a BigNum is 1. + * @retval false. The value of a BigNum is not 1. + * @retval other: indicates that the input parameter is abnormal. + * + */ +bool BN_IsOne(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Check whether a BigNum is a negative number. + * + * @attention The input parameter cannot be null. + * @param a [IN] BigNum + * + * @retval true. The value of a BigNum is a negative number. + * @retval false. The value of a BigNum is not a negative number. + * + */ +bool BN_IsNegative(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Check whether the value of a BigNum is an odd number. + * + * @attention The input parameter cannot be null. + * @param a [IN] BigNum + * + * @retval true. The value of a BigNum is an odd number. + * @retval false. The value of a BigNum is not an odd number. + * @retval other: indicates that the input parameter is abnormal. + * + */ +bool BN_IsOdd(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Check whether the flag of a BigNum meets the expected flag. + * + * @param a [IN] BigNum + * @param flag [IN] Flag. For example, BN_MARK_CONSTTIME indicates that the constant interface is used. + * + * @retval true, invalid null pointer + * @retval false, 0 cannot be set to a negative number. + * @retval other: indicates that the input parameter is abnormal. + */ +bool BN_IsFlag(const BN_BigNum *a, uint32_t flag); + +/** + * @ingroup bn + * @brief Set the value of a BigNum to 0. + * + * @param a [IN] BigNum + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval other: indicates that the input parameter is abnormal. + */ +int32_t BN_Zeroize(BN_BigNum *a); + +/** + * @ingroup bn + * @brief Compare whether the value of BigNum a is the target limb w. + * + * @attention The input parameter cannot be null. + * @param a [IN] BigNum + * @param w [IN] Limb + * + * @retval true: equal + * @retval false, not equal + * @retval other: indicates that the input parameter is abnormal. + */ +bool BN_IsLimb(const BN_BigNum *a, const BN_UINT w); + +/** + * @ingroup bn + * @brief Set a limb to the BigNum. + * + * @param a [IN] BigNum + * @param w [IN] Limb + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_SetLimb(BN_BigNum *r, BN_UINT w); + +/** + * @ingroup bn + * @brief Obtain the value of the bit corresponding to a BigNum. The value is 1 or 0. + * + * @attention The input parameter of a BigNum cannot be null. + * @param a [IN] BigNum + * @param n [IN] Number of bits + * + * @retval true. The corresponding bit is 1. + * @retval false. The corresponding bit is 0. + * + */ +bool BN_GetBit(const BN_BigNum *a, uint32_t n); + +/** + * @ingroup bn + * @brief Set the bit corresponding to the BigNum to 1. + * + * @param a [IN] BigNum + * @param n [IN] Number of bits + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_BN_SPACE_NOT_ENOUGH The space is insufficient. + */ +int32_t BN_SetBit(BN_BigNum *a, uint32_t n); + +/** + * @ingroup bn + * @brief Clear the bit corresponding to the BigNum to 0. + * + * @param a [IN] BigNum + * @param n [IN] Number of bits + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_BN_SPACE_NOT_ENOUGH The space is insufficient. + */ +int32_t BN_ClrBit(BN_BigNum *a, uint32_t n); + +/** + * @ingroup bn + * @brief Obtain the valid bit length of a BigNum. + * + * @attention The input parameter of a BigNum cannot be null. + * @param a [IN] BigNum + * + * @retval uint32_t, valid bit length + */ +uint32_t BN_Bits(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief Obtain the valid byte length of a BigNum. + * + * @attention The large input parameter cannot be a null pointer. + * @param a [IN] BigNum + * + * @retval uint32_t, valid byte length of a BigNum + */ +uint32_t BN_Bytes(const BN_BigNum *a); + +/** + * @ingroup bn + * @brief BigNum Calculate the greatest common divisor + * @par Description: gcd(a, b) (a, b!=0) + * + * @param r [OUT] greatest common divisor + * @param a [IN] BigNum + * @param b [IN] BigNum + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_GCD_NO_ZERO The greatest common divisor cannot be 0. + */ +int32_t BN_Gcd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum modulo inverse + * + * @param r [OUT] Result + * @param x [IN] BigNum + * @param m [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_NO_INVERSE Cannot calculate the module inverse. + */ +int32_t BN_ModInv(BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *m, BN_Optimizer *opt); +/** + * @ingroup bn + * @brief BigNum comparison + * + * @attention The input parameter of a BigNum cannot be null. + * @param a [IN] BigNum + * @param b [IN] BigNum + * + * @retval 0,a == b + * @retval 1,a > b + * @retval -1,a < b + */ +int32_t BN_Cmp(const BN_BigNum *a, const BN_BigNum *b); + +/** + * @ingroup bn + * @brief BigNum Addition + * + * @param r [OUT] and + * @param a [IN] Addendum + * @param b [IN] Addendum + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_Add(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b); + +/** + * @ingroup bn + * @brief BigNum plus limb + * + * @param r [OUT] and + * @param a [IN] Addendum + * @param w [IN] Addendum + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_AddLimb(BN_BigNum *r, const BN_BigNum *a, BN_UINT w); + +/** + * @ingroup bn + * @brief subtraction of large numbers + * + * @param r [OUT] difference + * @param a [IN] minuend + * @param b [IN] subtrahend + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_Sub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b); + +/** + * @ingroup bn + * @brief BigNum minus limb + * + * @param r [OUT] difference + * @param a [IN] minuend + * @param w [IN] subtrahend + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_SubLimb(BN_BigNum *r, const BN_BigNum *a, BN_UINT w); + +/** + * @ingroup bn + * @brief BigNum Multiplication + * + * @param r [OUT] product + * @param a [IN] multiplier + * @param b [IN] multiplier + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + */ +int32_t BN_Mul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum square + * + * @param r [OUT] product + * @param a [IN] multiplier + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_INVALID_ARG The addresses of q, r are identical, or both of them are null. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + */ +int32_t BN_Sqr(BN_BigNum *r, const BN_BigNum *a, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum Division + * + * @param q [OUT] quotient + * @param r [OUT] remainder + * @param x [IN] dividend + * @param y [IN] divisor + * @param opt [IN] optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO divisor cannot be 0. + */ +int32_t BN_Div(BN_BigNum *q, BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *y, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum Modular addition + * @par Description: r = (a + b) mod (mod) + * + * @param r [OUT] Modulus result + * @param a [IN] BigNum + * @param b [IN] BigNum + * @param mod [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO module cannot be 0. + */ +int32_t BN_ModAdd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_BigNum *mod, BN_Optimizer *opt); +/** + * @ingroup bn + * @brief BigNum Modular subtraction + * @par Description: r = (a - b) mod (mod) + * + * @param r [OUT] Modulo result + * @param a [IN] minuend + * @param b [IN] subtrahend + * @param mod [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO module cannot be 0. + */ +int32_t BN_ModSub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_BigNum *mod, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum Modular multiplication + * @par Description: r = (a * b) mod (mod) + * + * @param r [OUT] Modulus result + * @param a [IN] BigNum + * @param b [IN] BigNum + * @param mod [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO module cannot be 0. + */ +int32_t BN_ModMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_BigNum *mod, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum Modular squared + * @par Description: r = (a ^ 2) mod (mod) + * + * @param r [OUT] Modulus result + * @param a [IN] BigNum + * @param mod [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO module cannot be 0. + */ +int32_t BN_ModSqr(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum Modular power + * @par Description: r = (a ^ e) mod (mod) + * + * @param r [OUT] Modulus result + * @param a [IN] BigNum + * @param mod [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO module cannot be 0. + * @retval CRYPT_BN_ERR_EXP_NO_NEGATIVE exponent cannot be a negative number + */ +int32_t BN_ModExp(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, const BN_BigNum *m, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum modulo + * @par Description: r = a mod m + * + * @param r [OUT] Modulus result + * @param a [IN] BigNum + * @param m [IN] mod + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_ERR_DIVISOR_ZERO module cannot be 0. + */ +int32_t BN_Mod(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief generate BN prime + * + * @param r [OUT] Generate a prime number. + * @param bits [IN] Length of the generated prime number + * @param half [IN] Whether to generate a prime number greater than the maximum value of this prime number by 1/2: + * Yes: True, No: false + * @param opt [IN] Optimizer + * @param cb [IN] BigNum callback + * @retval CRYPT_SUCCESS The prime number is successfully generated. + * @retval CRYPT_NULL_INPUT Invalid null pointer. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_STACK_FULL The optimizer stack is full. + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_NOR_GEN_PRIME Failed to generate prime numbers. + * @retval CRYPT_BN_RAND_GEN_FAIL Failed to generate a random number. + */ +int32_t BN_GenPrime(BN_BigNum *r, uint32_t bits, bool half, BN_Optimizer *opt, BN_CbCtx *cb); + +/** + * @ingroup bn + * @brief check prime number + * + * @param bn [IN] Prime number to be checked + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS The check result is a prime number. + * @retval CRYPT_BN_NOR_CHECK_PRIME The check result is a non-prime number. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_BN_OPTIMIZER_STACK_FULL The optimizer stack is full. + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_RAND_GEN_FAIL Failed to generate a random number. + */ +int32_t BN_PrimeCheck(const BN_BigNum *bn, BN_Optimizer *opt); + +#define BN_RAND_TOP_NOBIT 0 /* Not set bits */ +#define BN_RAND_TOP_ONEBIT 1 /* Set the most significant bit to 1. */ +#define BN_RAND_TOP_TWOBIT 2 /* Set the highest two bits to 1 */ + +#define BN_RAND_BOTTOM_NOBIT 0 /* Not set bits */ +#define BN_RAND_BOTTOM_ONEBIT 1 /* Set the least significant bit to 1. */ +#define BN_RAND_BOTTOM_TWOBIT 2 /* Set the least significant two bits to 1. */ + +/** + * @ingroup bn + * @brief generate random BigNum + * + * @param r [OUT] Generate a random number. + * @param bits [IN] Length of the generated prime number + * @param top [IN] Generating the flag indicating whether to set the most significant bit of a random number + * @param bottom [IN] Generate the flag indicating whether to set the least significant bit of the random number. + * + * @retval CRYPT_SUCCESS A random number is generated successfully. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_ERR_RAND_TOP_BOTTOM The top or bottom is invalid during random number generation. + * @retval CRYPT_BN_RAND_GEN_FAIL Failed to generate a random number. + * @retval CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH The bit is too small during random number generation. + */ +int32_t BN_Rand(BN_BigNum *r, uint32_t bits, uint32_t top, uint32_t bottom); + +/** + * @ingroup bn + * @brief generate random BigNum + * + * @param r [OUT] Generate a random number. + * @param p [IN] Compare data so that the generated r < p + * + * @retval CRYPT_SUCCESS A random number is successfully generated. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_RAND_GEN_FAIL Failed to generate a random number. + * @retval CRYPT_BN_ERR_RAND_ZERO Generate a random number smaller than 0. + * @retval CRYPT_BN_ERR_RAND_NEGATE Generate a negative random number. + */ +int32_t BN_RandRange(BN_BigNum *r, const BN_BigNum *p); + +/** + * @ingroup bn + * @brief Binary to BigNum + * + * @param r [OUT] BigNum + * @param bin [IN] Data stream to be converted + * @param binLen [IN] Data stream length + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_Bin2Bn(BN_BigNum *r, const uint8_t *bin, uint32_t binLen); + +/** + * @ingroup bn + * @brief Convert BigNum to binary + * + * @param a [IN] BigNum + * @param bin [IN/OUT] Data stream to be converted -- The input pointer cannot be null. + * @param binLen [IN/OUT] Data stream length -- When input, binLen is also the length of the bin buffer. + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL An error occurred during the copy. + */ +int32_t BN_Bn2Bin(const BN_BigNum *a, uint8_t *bin, uint32_t *binLen); + +/** + * @ingroup bn + * @brief Convert BigNum to binary to obtain big-endian data with the length of binLen. + * The most significant bits are filled with 0. + * + * @param a [IN] BigNum + * @param bin [OUT] Data stream to be converted -- The input pointer cannot be null. + * @param binLen [IN] Data stream length -- When input, binLen is also the length of the bin buffer. + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_BN_BUFF_LEN_NOT_ENOUGH The space is insufficient. + */ +int32_t BN_Bn2BinFixZero(const BN_BigNum *a, uint8_t *bin, uint32_t binLen); + +/** + * @ingroup bn + * @brief Converting a 64-bit unsigned number array to a BigNum + * + * @param r [OUT] BigNum + * @param array [IN] Array to be converted + * @param len [IN] Number of elements in the array + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_U64Array2Bn(BN_BigNum *r, const uint64_t *array, uint32_t len); + +/** + * @ingroup bn + * @brief BigNum to 64-bit unsigned number array + * + * @param a [IN] BigNum + * @param array [IN/OUT] Array for storing results -- The input pointer cannot be null. + * @param len [IN/OUT] Length of the written array -- Number of writable elements when input + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A copy error occurs. + */ +int32_t BN_Bn2U64Array(const BN_BigNum *a, uint64_t *array, uint32_t *len); + +/** + * @ingroup bn + * @brief BigNum optimizer creation + * + * @param None + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_Optimizer *BN_OptimizerCreate(void); + +/** + * @ingroup bn + * @brief Destroy the BigNum optimizer. + * + * @param opt [IN] BigNum optimizer + * + * @retval none + */ +void BN_OptimizerDestroy(BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum Montgomery context creation and setting + * + * @param m [IN] Modulus m, which must be positive and odd + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_Mont *BN_MontCreate(const BN_BigNum *m); + +/** + * @ingroup bn + * @brief BigNum Montgomery modular exponentiation. + * Whether to use the constant API depends on the property of the BigNum. + * + * @param r [OUT] Modular exponentiation result + * @param a [IN] base + * @param e [IN] Index + * @param mont [IN] Montgomery context + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS calculated successfully. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_MONT_BASE_TOO_MAX Montgomery modulus exponentiation base is too large + * @retval CRYPT_BN_OPTIMIZER_STACK_FULL The optimizer stack is full. + * @retval CRYPT_BN_ERR_EXP_NO_NEGATE exponent cannot be a negative number + */ +int32_t BN_MontExp(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, BN_Mont *mont, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief Constant time BigNum Montgomery modular exponentiation + * + * @param r [OUT] Modular exponentiation result + * @param a [IN] base + * @param e [IN] exponent + * @param mont [IN] Montgomery context + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS calculated successfully. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_BN_OPTIMIZER_GET_FAIL Failed to apply for space from the optimizer. + * @retval CRYPT_BN_MONT_BASE_TOO_MAX Montgomery Modular exponentiation base is too large + * @retval CRYPT_BN_OPTIMIZER_STACK_FULL The optimizer stack is full. + * @retval CRYPT_BN_ERR_EXP_NO_NEGATE exponent cannot be a negative number + */ +int32_t BN_MontExpConsttime(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, BN_Mont *mont, BN_Optimizer *opt); + +/** + * @ingroup mont + * @brief BigNum Montgomery Context Destruction + * + * @param mont [IN] BigNum Montgomery context + * + * @retval none + */ +void BN_MontDestroy(BN_Mont *mont); + +/** + * @ingroup bn + * @brief shift a BigNum to the right + * + * @param r [OUT] Shift result + * @param a [IN] Source data + * @param n [IN] Shift bit num + * + * @retval CRYPT_SUCCESS succeeded. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL The security function returns an error. + */ +int32_t BN_Rshift(BN_BigNum *r, const BN_BigNum *a, uint32_t n); + +int32_t BN_MontExpMul(BN_BigNum *r, const BN_BigNum *a1, const BN_BigNum *e1, const BN_BigNum *a2, const BN_BigNum *e2, + BN_Mont *mont, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief Mould opening root + * @par Description: r^2 = a mod p; p-1=q*2^s. + * In the current implementation s=1 will take a special branch, and the calculation speed is faster. + * Currently, the s corresponding to the mod p of the EC nist224, 256, 384, and 521 is 96, 1, 1, and 1 respectively + * The branch with s=2 is not used. + * The root number is provided for the EC. + * @param r [OUT] Modular root result + * @param a [IN] Source data, 0 <= a <= p-1 + * @param p [IN] module, odd prime number + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS calculated successfully. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_BN_ERR_SQRT_PARA The input parameter is incorrect. + * @retval CRYPT_BN_ERR_LEGENDE_DATA: + * Failed to find the specific number of the Legendre sign (z|p) of z to p equal to -1 when calculating the square root. + * @retval CRYPT_BN_ERR_NO_SQUARE_ROOT The square root cannot be found. + */ +int32_t BN_ModSqrt(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief BigNum to BN_UINT array + * + * @param src [IN] BigNum + * @param dst [OUT] BN_UINT array for receiving the conversion result + * @param size [IN] Length of the dst buffer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL The security function returns an error. + */ +int32_t BN_BN2Array(const BN_BigNum *src, BN_UINT *dst, uint32_t size); + +/** + * @ingroup bn + * @brief BN_UINT array to BigNum + * + * @param dst [OUT] BigNum + * @param src [IN] BN_UINT array to be converted + * @param size [IN] Length of the src buffer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_Array2BN(BN_BigNum *dst, const BN_UINT *src, const uint32_t size); + +/** + * @ingroup bn + * @brief Copy with the mask. When the mask is set to (0), r = a; when the mask is set to (-1), r = b. + * + * @attention Data r, a, and b must have the same room. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param b [IN] Source data + * @param mask [IN] Mask data + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t BN_CopyWithMask(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_UINT mask); + +#ifdef HITLS_CRYPTO_ECC +/** + * @ingroup bn + * @brief Calculate r = (a - b) % mod + * + * @attention This API is invoked in the area where ECC point computing is intensive and is performance-sensitive. + * The user must ensure that a < mod, b < mod + * In addition, a->room and b->room are not less than mod->size. + * All data are non-negative + * The mod information cannot be 0. + * Otherwise, the interface may not be functional. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param b [IN] Source data + * @param mod [IN] Modular data + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t BN_ModSubQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, const BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief Calculate r = (a + b) % mod + * + * @attention This API is invoked in the area where ECC point computing is intensive and is performance-sensitive. + * The user must ensure that a < mod, b < mod + * In addition, a->room and b->room are not less than mod->size. + * All data are non-negative + * The mod information cannot be 0. + * Otherwise, the interface may not be functional. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param b [IN] Source data + * @param mod [IN] Modular data + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t BN_ModAddQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, const BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief Calculate r = (a * b) % mod + * + * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive. + * The user must ensure that a < mod, b < mod + * In addition, a->room and b->room are not less than mod->size. + * All data are non-negative + * The mod information can only be the parameter p of the curve of nistP224, nistP256, nistP384, and nistP521. + * Otherwise, the interface may not be functional. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param b [IN] Source data + * @param mod [IN] Modular data + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For other errors, see crypt_errno.h. + */ +int32_t BN_ModNistEccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_BigNum *mod, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief Calculate r = (a ^ 2) % mod + * + * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive. + * The user must guarantee a < mod + * In addition, a->room is not less than mod->size. + * All data are non-negative + * The mod information can only be the parameter p of the curve of nistP224, nistP256, nistP384, and nistP521. + * Otherwise, the interface may not be functional. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param mod [IN] Modular data + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t BN_ModNistEccSqr(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt); +#endif + +#ifdef HITLS_CRYPTO_SM2 +/** + * @ingroup ecc + * @brief sm2 curve: calculate r = (a*b) % mod + * + * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive. + * The user must guarantee a < mod, b < mod + * In addition, a->room and b->room are not less than mod->size. + * All data are non-negative + * The mod information can only be the parameter p of the curve of sm2. + * Otherwise, the interface may not be functional. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param b [IN] Source data + * @param mod [IN] Modular data + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t BN_ModSm2EccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt); + +/** + * @ingroup ecc + * @brief sm2 curve: calculate r = (a ^ 2) % mod + * + * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive. + * The user must guarantee a < mod + * In addition, a->room are not less than mod->size. + * All data are non-negative + * The mod information can only be the parameter p of the curve of sm2. + * Otherwise, the interface may not be functional. + * + * @param r [OUT] Output result + * @param a [IN] Source data + * @param mod [IN] Modular data + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t BN_ModSm2EccSqr( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt); + +/** + * @ingroup bn + * @brief Return the number of security bits provided by a specific algorithm and specific key size + * + * @param pubLen [IN] size of the public key + * @param prvlen [IN] size of the private key + * @retval [OUT] output the result + */ +int32_t BN_SecBit(int32_t publen, int32_t prvlen); +#endif + +#ifdef HITLS_CRYPTO_PAILLIER +/** + * @ingroup bn + * @brief BigNum Calculate the least common multiple + * @par Description: lcm(a, b) (a, b!=0) + * + * @param r [OUT] least common multiple + * @param a [IN] BigNum + * @param b [IN] BigNum + * @param opt [IN] Optimizer + * + * @retval CRYPT_SUCCESS + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + */ +int32_t BN_Lcm(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_BN + +#endif // CRYPT_BN_H diff --git a/crypto/bn/src/bn_basic.c b/crypto/bn/src/bn_basic.c new file mode 100644 index 00000000..3f6f4bbe --- /dev/null +++ b/crypto/bn/src/bn_basic.c @@ -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 */ diff --git a/crypto/bn/src/bn_basic.h b/crypto/bn/src/bn_basic.h new file mode 100644 index 00000000..478c9385 --- /dev/null +++ b/crypto/bn/src/bn_basic.h @@ -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 +#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 diff --git a/crypto/bn/src/bn_bincal.c b/crypto/bn/src/bn_bincal.c new file mode 100644 index 00000000..e5086fd9 --- /dev/null +++ b/crypto/bn/src/bn_bincal.c @@ -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 +#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 */ diff --git a/crypto/bn/src/bn_bincal.h b/crypto/bn/src/bn_bincal.h new file mode 100644 index 00000000..fd6dc551 --- /dev/null +++ b/crypto/bn/src/bn_bincal.h @@ -0,0 +1,319 @@ +/* + * 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_BINCAL_H +#define BN_BINCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include +#include "bn_basic.h" + +#ifdef __cplusplus +extern "c" { +#endif + +/* r = a + b, input 'carry' means carry */ +#define ADD_AB(carry, r, a, b) \ + do { \ + BN_UINT macroTmpT = (a) + (b); \ + (carry) = macroTmpT < (a) ? 1 : 0; \ + (r) = macroTmpT; \ + } while (0) + +/* r = a + b + c, input 'carry' means carry. Note that a and carry cannot be the same variable. */ +#define ADD_ABC(carry, r, a, b, c) \ + do { \ + BN_UINT macroTmpS = (b) + (c); \ + carry = (macroTmpS < (c)) ? 1 : 0; \ + (r) = macroTmpS + (a); \ + carry += ((r) < macroTmpS) ? 1 : 0; \ + } while (0) + +/* r = a - b, input 'borrow' means borrow digit */ +#define SUB_AB(borrow, r, a, b) \ + do { \ + BN_UINT macroTmpT = (a) - (b); \ + (borrow) = ((a) < (b)) ? 1 : 0; \ + (r) = macroTmpT; \ + } while (0) + +/* r = a - b - c, input 'borrow' means borrow digit */ +#define SUB_ABC(borrow, r, a, b, c) \ + do { \ + BN_UINT macroTmpS = (a) - (b); \ + BN_UINT macroTmpB = ((a) < (b)) ? 1 : 0; \ + macroTmpB += (macroTmpS < (c)) ? 1 : 0; \ + (r) = macroTmpS - (c); \ + borrow = macroTmpB; \ + } while (0) + +/* Takes the low bit and assigns it to the high bit. */ +#define BN_UINT_LO_TO_HI(t) ((t) << (BN_UINT_BITS >> 1)) + +/* Takes the high bit and assigns it to the high bit. */ +#define BN_UINT_HI_TO_HI(t) ((t) & ((BN_UINT)0 - ((BN_UINT)1 << (BN_UINT_BITS >> 1)))) + +/* Takes the low bit and assigns it to the low bit. */ +#define BN_UINT_LO(t) ((t) & (((BN_UINT)1 << (BN_UINT_BITS >> 1)) - 1)) + +/* Takes the high bit and assigns it to the low bit. */ +#define BN_UINT_HI(t) ((t) >> (BN_UINT_BITS >> 1)) + +/* carry value of the upper part */ +#define BN_UINT_HC ((BN_UINT)1 << (BN_UINT_BITS >> 1)) + +#define MUL_AB(wh, wl, u, v) \ + do { \ + BN_UINT macroTmpUl = BN_UINT_LO(u); \ + BN_UINT macroTmpUh = BN_UINT_HI(u); \ + BN_UINT macroTmpVl = BN_UINT_LO(v); \ + BN_UINT macroTmpVh = BN_UINT_HI(v); \ + \ + BN_UINT macroTmpX0 = macroTmpUl * macroTmpVl; \ + BN_UINT macroTmpX1 = macroTmpUl * macroTmpVh; \ + BN_UINT macroTmpX2 = macroTmpUh * macroTmpVl; \ + BN_UINT macroTmpX3 = macroTmpUh * macroTmpVh; \ + \ + macroTmpX1 += BN_UINT_HI(macroTmpX0); \ + macroTmpX1 += macroTmpX2; \ + if (macroTmpX1 < macroTmpX2) { macroTmpX3 += BN_UINT_HC; } \ + \ + (wh) = macroTmpX3 + BN_UINT_HI(macroTmpX1); \ + (wl) = (macroTmpX1 << (BN_UINT_BITS >> 1)) | BN_UINT_LO(macroTmpX0); \ + } while (0) + +#define SQR_A(wh, wl, u) \ + do { \ + BN_UINT macroTmpUl = BN_UINT_LO(u); \ + BN_UINT macroTmpUh = BN_UINT_HI(u); \ + \ + BN_UINT macroTmpX0 = macroTmpUl * macroTmpUl; \ + BN_UINT macroTmpX1 = macroTmpUl * macroTmpUh; \ + BN_UINT macroTmpX2 = macroTmpUh * macroTmpUh; \ + \ + BN_UINT macroTmpT = macroTmpX1 << 1; \ + macroTmpT += BN_UINT_HI(macroTmpX0); \ + if (macroTmpT < macroTmpX1) { macroTmpX2 += BN_UINT_HC; } \ + \ + (wh) = macroTmpX2 + BN_UINT_HI(macroTmpT); \ + (wl) = (macroTmpT << (BN_UINT_BITS >> 1)) | BN_UINT_LO(macroTmpX0); \ + } while (0) + +/* nh|nl / d = q...r */ +#define DIV_ND(q, r, nh, nl, d) \ + do { \ + BN_UINT macroTmpD1, macroTmpD0, macroTmpQ1, macroTmpQ0, macroTmpR1, macroTmpR0, macroTmpM; \ + \ + macroTmpD1 = BN_UINT_HI(d); \ + macroTmpD0 = BN_UINT_LO(d); \ + \ + macroTmpQ1 = (nh) / macroTmpD1; \ + macroTmpR1 = (nh) - macroTmpQ1 * macroTmpD1; \ + macroTmpM = macroTmpQ1 * macroTmpD0; \ + macroTmpR1 = (macroTmpR1 << (BN_UINT_BITS >> 1)) | BN_UINT_HI(nl); \ + if (macroTmpR1 < macroTmpM) { \ + macroTmpQ1--, macroTmpR1 += (d); \ + if (macroTmpR1 >= (d)) { \ + if (macroTmpR1 < macroTmpM) { \ + macroTmpQ1--; \ + macroTmpR1 += (d); \ + } \ + } \ + } \ + macroTmpR1 -= macroTmpM; \ + \ + macroTmpQ0 = macroTmpR1 / macroTmpD1; \ + macroTmpR0 = macroTmpR1 - macroTmpQ0 * macroTmpD1; \ + macroTmpM = macroTmpQ0 * macroTmpD0; \ + macroTmpR0 = (macroTmpR0 << (BN_UINT_BITS >> 1)) | BN_UINT_LO(nl); \ + if (macroTmpR0 < macroTmpM) { \ + macroTmpQ0--, macroTmpR0 += (d); \ + if (macroTmpR0 >= (d)) { \ + if (macroTmpR0 < macroTmpM) { \ + macroTmpQ0--; \ + macroTmpR0 += (d); \ + } \ + } \ + } \ + macroTmpR0 -= macroTmpM; \ + \ + (q) = (macroTmpQ1 << (BN_UINT_BITS >> 1)) | macroTmpQ0; \ + (r) = macroTmpR0; \ + } while (0) + +/* copy bytes, ensure that dstLen >= srcLen */ +#define BN_COPY_BYTES(dst, dstlen, src, srclen) \ + do { \ + uint32_t macroTmpI; \ + for (macroTmpI = 0; macroTmpI < (srclen); macroTmpI++) { (dst)[macroTmpI] = (src)[macroTmpI]; } \ + for (; macroTmpI < (dstlen); macroTmpI++) { (dst)[macroTmpI] = 0; } \ + } while (0) + +// Modular operation, satisfy d < (1 << (BN_UINT_BITS >> 1)) r = nh | nl % d +#define MOD_HALF(r, nh, nl, d) \ + do { \ + BN_UINT macroTmpD = (d); \ + (r) = (nh) % macroTmpD; \ + (r) = ((r) << (BN_UINT_BITS >> 1)) | BN_UINT_HI((nl)); \ + (r) = (r) % macroTmpD; \ + (r) = ((r) << (BN_UINT_BITS >> 1)) | BN_UINT_LO((nl)); \ + (r) = (r) % macroTmpD; \ + } while (0) + +/* r = a * b + r + c, where c is refreshed as the new carry value */ +#define MULADD_ABC(c, r, a, b) \ +do { \ + BN_UINT macroTmpAl = BN_UINT_LO(a); \ + BN_UINT macroTmpAh = BN_UINT_HI(a); \ + BN_UINT macroTmpBl = BN_UINT_LO(b); \ + BN_UINT macroTmpBh = BN_UINT_HI(b); \ + BN_UINT macroTmpX3 = macroTmpAh * macroTmpBh; \ + BN_UINT macroTmpX2 = macroTmpAh * macroTmpBl; \ + BN_UINT macroTmpX1 = macroTmpAl * macroTmpBh; \ + BN_UINT macroTmpX0 = macroTmpAl * macroTmpBl; \ + (r) += (c); \ + (c) = ((r) < (c)) ? 1 : 0; \ + macroTmpX1 += macroTmpX2; \ + (c) += (macroTmpX1 < macroTmpX2) ? BN_UINT_HC : 0; \ + macroTmpX2 = macroTmpX0; \ + macroTmpX0 += macroTmpX1 << (BN_UINT_BITS >> 1); \ + (c) += (macroTmpX0 < macroTmpX2) ? 1 : 0; \ + (c) += BN_UINT_HI(macroTmpX1); \ + (c) += macroTmpX3; \ + (r) += macroTmpX0; \ + (c) += ((r) < macroTmpX0) ? 1 : 0; \ +} while (0) + +/* h|m|l = h|m|l + u * v. Ensure that the value of h is not too large to avoid carry. */ +#define MULADD_AB(h, m, l, u, v) \ + do { \ + BN_UINT macroTmpUl = BN_UINT_LO(u); \ + BN_UINT macroTmpUh = BN_UINT_HI(u); \ + BN_UINT macroTmpVl = BN_UINT_LO(v); \ + BN_UINT macroTmpVh = BN_UINT_HI(v); \ + \ + BN_UINT macroTmpX3 = macroTmpUh * macroTmpVh; \ + BN_UINT macroTmpX2 = macroTmpUh * macroTmpVl; \ + BN_UINT macroTmpX1 = macroTmpUl * macroTmpVh; \ + BN_UINT macroTmpX0 = macroTmpUl * macroTmpVl; \ + macroTmpX1 += BN_UINT_HI(macroTmpX0); \ + macroTmpX0 = (u) * (v); \ + macroTmpX1 += macroTmpX2; \ + macroTmpX3 = macroTmpX3 + BN_UINT_HI(macroTmpX1); \ + \ + (l) += macroTmpX0; \ + \ + if (macroTmpX1 < macroTmpX2) { macroTmpX3 += BN_UINT_HC; } \ + if ((l) < macroTmpX0) { macroTmpX3 += 1; } \ + (m) += macroTmpX3; \ + if ((m) < macroTmpX3) { (h)++; } \ + } while (0) + +/* h|m|l = h|m|l + 2 * u * v. Ensure that the value of h is not too large to avoid carry. */ +#define MULADD_AB2(h, m, l, u, v) \ + do { \ + MULADD_AB((h), (m), (l), (u), (v)); \ + MULADD_AB((h), (m), (l), (u), (v)); \ + } while (0) + +/* h|m|l = h|m|l + v * v. Ensure that the value of h is not too large to avoid carry. */ +#define SQRADD_A(h, m, l, v) \ +do { \ + BN_UINT macroTmpVl = BN_UINT_LO(v); \ + BN_UINT macroTmpVh = BN_UINT_HI(v); \ + \ + BN_UINT macroTmpX3 = macroTmpVh * macroTmpVh; \ + BN_UINT macroTmpX2 = macroTmpVh * macroTmpVl; \ + BN_UINT macroTmpX1 = macroTmpX2; \ + BN_UINT macroTmpX0 = macroTmpVl * macroTmpVl; \ + macroTmpX1 += BN_UINT_HI(macroTmpX0); \ + macroTmpX0 = (v) * (v); \ + macroTmpX1 += macroTmpX2; \ + macroTmpX3 = macroTmpX3 + BN_UINT_HI(macroTmpX1); \ + \ + (l) += macroTmpX0; \ + \ + if (macroTmpX1 < macroTmpX2) { macroTmpX3 += BN_UINT_HC; } \ + if ((l) < macroTmpX0) { macroTmpX3 += 1; } \ + (m) += macroTmpX3; \ + if ((m) < macroTmpX3) { (h)++; } \ +} while (0) + +BN_UINT BinAdd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n); + +BN_UINT BinSub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n); + +BN_UINT BinInc(BN_UINT *r, const BN_UINT *a, uint32_t size, BN_UINT w); + +BN_UINT BinDec(BN_UINT *r, const BN_UINT *a, uint32_t n, BN_UINT w); + +uint32_t BinRshift(BN_UINT *r, const BN_UINT *a, uint32_t n, uint32_t bits); + +uint32_t BinLshift(BN_UINT *r, const BN_UINT *a, uint32_t n, uint32_t bits); + +BN_UINT BinMulAcc(BN_UINT *r, const BN_UINT *a, uint32_t aSize, BN_UINT b); + +uint32_t BinMul(BN_UINT *r, uint32_t rRoom, const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize); + +uint32_t BinSqr(BN_UINT *r, uint32_t rRoom, const BN_UINT *a, uint32_t aSize); + +uint32_t GetZeroBitsUint(BN_UINT x); + +uint32_t BinFixSize(const BN_UINT *data, uint32_t size); + +int32_t BinCmp(const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize); + +uint32_t BinBits(const BN_UINT *data, uint32_t size); + +uint32_t BinDiv(BN_UINT *q, uint32_t *qSize, BN_UINT *x, uint32_t xSize, BN_UINT *y, uint32_t ySize); + +uint32_t SpaceSize(uint32_t size); + +// Perform a multiplication calculation of 4 blocks of data, r = a^2, +// where the length of r is 8, and the length of a is 4. +void MulComba4(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); + +// Calculate the square of 4 blocks of data, r = a^2, where the length of r is 8, and the length of a is 4. +void SqrComba4(BN_UINT *r, const BN_UINT *a); + +// Perform a multiplication calculation of 6 blocks of data, r = a*b, +// where the length of r is 12, the length of a and b is 6. +void MulComba6(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); + +// Calculate the square of 6 blocks of data, r = a^2, where the length of r is 12, and the length of a is 6. +void SqrComba6(BN_UINT *r, const BN_UINT *a); + +void MulConquer(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t size, BN_UINT *space, bool consttime); + +void SqrConquer(BN_UINT *r, const BN_UINT *a, uint32_t size, BN_UINT *space, bool consttime); + +int32_t MontSqrBinCore(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime); + +int32_t MontMulBinCore(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, BN_Mont *mont, + BN_Optimizer *opt, bool consttime); + +int32_t MontEncBinCore(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime); + +void ReduceCore(BN_UINT *r, BN_UINT *x, const BN_UINT *m, uint32_t mSize, BN_UINT m0); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_BN + +#endif // BN_BINCAL_H diff --git a/crypto/bn/src/bn_comba.c b/crypto/bn/src/bn_comba.c new file mode 100644 index 00000000..492540bc --- /dev/null +++ b/crypto/bn/src/bn_comba.c @@ -0,0 +1,632 @@ +/* + * 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 +#include "bn_bincal.h" + +#define SQR_COMBA_BEGIN_1(r, a, h, m, l) do { \ + SQRADD_A((h), (m), (l), (a)[0]); \ + (r)[0] = (l); \ + (l) = 0; \ + MULADD_AB2((l), (h), (m), (a)[0], (a)[1]); \ + (r)[1] = (m); \ + (m) = 0; \ + MULADD_AB2((m), (l), (h), (a)[0], (a)[2]); \ + SQRADD_A((m), (l), (h), (a)[1]); \ + (r)[2] = (h); \ + (h) = 0; \ + MULADD_AB2((h), (m), (l), (a)[1], (a)[2]); \ + MULADD_AB2((h), (m), (l), (a)[0], (a)[3]); \ + (r)[3] = (l); \ + (l) = 0; \ +} while (0) + +#define SQR_COMBA_BEGIN_2(r, a, h, m, l) do { \ + MULADD_AB2((l), (h), (m), (a)[0], (a)[4]); \ + MULADD_AB2((l), (h), (m), (a)[1], (a)[3]); \ + SQRADD_A((l), (h), (m), (a)[2]); \ + (r)[4] = (m); \ + (m) = 0; \ + MULADD_AB2((m), (l), (h), (a)[2], (a)[3]); \ + MULADD_AB2((m), (l), (h), (a)[1], (a)[4]); \ + MULADD_AB2((m), (l), (h), (a)[0], (a)[5]); \ + (r)[5] = (h); \ + (h) = 0; \ +} while (0) + +#define MUL_COMBA_BEGIN_1(r, a, b, h, m, l) do { \ + MULADD_AB((h), (m), (l), (a)[0], (b)[0]); \ + (r)[0] = (l); \ + (l) = 0; \ + MULADD_AB((l), (h), (m), (a)[0], (b)[1]); \ + MULADD_AB((l), (h), (m), (a)[1], (b)[0]); \ + (r)[1] = (m); \ + (m) = 0; \ + MULADD_AB((m), (l), (h), (a)[2], (b)[0]); \ + MULADD_AB((m), (l), (h), (a)[1], (b)[1]); \ + MULADD_AB((m), (l), (h), (a)[0], (b)[2]); \ + (r)[2] = (h); \ + (h) = 0; \ + MULADD_AB((h), (m), (l), (a)[0], (b)[3]); \ + MULADD_AB((h), (m), (l), (a)[1], (b)[2]); \ + MULADD_AB((h), (m), (l), (a)[2], (b)[1]); \ + MULADD_AB((h), (m), (l), (a)[3], (b)[0]); \ + (r)[3] = (l); \ + (l) = 0; \ +} while (0) + +#define MUL_COMBA_BEGIN_2(r, a, b, h, m, l) do { \ + MULADD_AB((l), (h), (m), (a)[4], (b)[0]); \ + MULADD_AB((l), (h), (m), (a)[3], (b)[1]); \ + MULADD_AB((l), (h), (m), (a)[2], (b)[2]); \ + MULADD_AB((l), (h), (m), (a)[1], (b)[3]); \ + MULADD_AB((l), (h), (m), (a)[0], (b)[4]); \ + (r)[4] = (m); \ + (m) = 0; \ + MULADD_AB((m), (l), (h), (a)[0], (b)[5]); \ + MULADD_AB((m), (l), (h), (a)[1], (b)[4]); \ + MULADD_AB((m), (l), (h), (a)[2], (b)[3]); \ + MULADD_AB((m), (l), (h), (a)[3], (b)[2]); \ + MULADD_AB((m), (l), (h), (a)[4], (b)[1]); \ + MULADD_AB((m), (l), (h), (a)[5], (b)[0]); \ + (r)[5] = (h); \ + (h) = 0; \ +} while (0) + +#define MUL_COMBA_BEGIN_3(r, a, b, h, m, l) do { \ + MULADD_AB((h), (m), (l), (a)[6], (b)[0]); \ + MULADD_AB((h), (m), (l), (a)[5], (b)[1]); \ + MULADD_AB((h), (m), (l), (a)[4], (b)[2]); \ + MULADD_AB((h), (m), (l), (a)[3], (b)[3]); \ + MULADD_AB((h), (m), (l), (a)[2], (b)[4]); \ + MULADD_AB((h), (m), (l), (a)[1], (b)[5]); \ + MULADD_AB((h), (m), (l), (a)[0], (b)[6]); \ + (r)[6] = (l); \ + (l) = 0; \ + MULADD_AB((l), (h), (m), (a)[0], (b)[7]); \ + MULADD_AB((l), (h), (m), (a)[1], (b)[6]); \ + MULADD_AB((l), (h), (m), (a)[2], (b)[5]); \ + MULADD_AB((l), (h), (m), (a)[3], (b)[4]); \ + MULADD_AB((l), (h), (m), (a)[4], (b)[3]); \ + MULADD_AB((l), (h), (m), (a)[5], (b)[2]); \ + MULADD_AB((l), (h), (m), (a)[6], (b)[1]); \ + MULADD_AB((l), (h), (m), (a)[7], (b)[0]); \ + (r)[7] = (m); \ + (m) = 0; \ + MULADD_AB((m), (l), (h), (a)[7], (b)[1]); \ + MULADD_AB((m), (l), (h), (a)[6], (b)[2]); \ + MULADD_AB((m), (l), (h), (a)[5], (b)[3]); \ + MULADD_AB((m), (l), (h), (a)[4], (b)[4]); \ + MULADD_AB((m), (l), (h), (a)[3], (b)[5]); \ + MULADD_AB((m), (l), (h), (a)[2], (b)[6]); \ + MULADD_AB((m), (l), (h), (a)[1], (b)[7]); \ + (r)[8] = (h); \ + (h) = 0; \ +} while (0) + +static void SqrComba8(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + + SQR_COMBA_BEGIN_1(r, a, h, m, l); + SQR_COMBA_BEGIN_2(r, a, h, m, l); + + MULADD_AB2(h, m, l, a[0], a[6]); + MULADD_AB2(h, m, l, a[1], a[5]); + MULADD_AB2(h, m, l, a[2], a[4]); + SQRADD_A(h, m, l, a[3]); + r[6] = l; + l = 0; + + MULADD_AB2(l, h, m, a[3], a[4]); + MULADD_AB2(l, h, m, a[2], a[5]); + MULADD_AB2(l, h, m, a[1], a[6]); + MULADD_AB2(l, h, m, a[0], a[7]); + r[7] = m; + m = 0; + + MULADD_AB2(m, l, h, a[1], a[7]); + MULADD_AB2(m, l, h, a[2], a[6]); + MULADD_AB2(m, l, h, a[3], a[5]); + SQRADD_A(m, l, h, a[4]); + r[8] = h; + h = 0; + + MULADD_AB2(h, m, l, a[4], a[5]); + MULADD_AB2(h, m, l, a[3], a[6]); + MULADD_AB2(h, m, l, a[2], a[7]); + r[9] = l; + l = 0; + + MULADD_AB2(l, h, m, a[3], a[7]); + MULADD_AB2(l, h, m, a[4], a[6]); + SQRADD_A(l, h, m, a[5]); + r[10] = m; + m = 0; + + MULADD_AB2(m, l, h, a[5], a[6]); + MULADD_AB2(m, l, h, a[4], a[7]); + r[11] = h; + h = 0; + + MULADD_AB2(h, m, l, a[5], a[7]); + SQRADD_A(h, m, l, a[6]); + r[12] = l; + l = 0; + + MULADD_AB2(l, h, m, a[6], a[7]); + r[13] = m; + m = 0; + + SQRADD_A(m, l, h, a[7]); + r[14] = h; + r[15] = l; +} + +void SqrComba6(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + + SQR_COMBA_BEGIN_1(r, a, h, m, l); + SQR_COMBA_BEGIN_2(r, a, h, m, l); + + MULADD_AB2(h, m, l, a[1], a[5]); + MULADD_AB2(h, m, l, a[2], a[4]); + SQRADD_A(h, m, l, a[3]); + r[6] = l; + l = 0; + + MULADD_AB2(l, h, m, a[3], a[4]); + MULADD_AB2(l, h, m, a[2], a[5]); + r[7] = m; + m = 0; + + MULADD_AB2(m, l, h, a[3], a[5]); + SQRADD_A(m, l, h, a[4]); + r[8] = h; + h = 0; + + MULADD_AB2(h, m, l, a[4], a[5]); + r[9] = l; + l = 0; + + SQRADD_A(l, h, m, a[5]); + r[10] = m; + r[11] = h; +} + +void SqrComba4(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + + SQR_COMBA_BEGIN_1(r, a, h, m, l); + + MULADD_AB2(l, h, m, a[1], a[3]); + SQRADD_A(l, h, m, a[2]); + r[4] = m; + m = 0; + + MULADD_AB2(m, l, h, a[2], a[3]); + r[5] = h; + h = 0; + + SQRADD_A(h, m, l, a[3]); + r[6] = l; + r[7] = m; +} + +static void SqrComba(BN_UINT *r, const BN_UINT *a, uint32_t size) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + if (size == 3) { + SQRADD_A(h, m, l, a[0]); + r[0] = l; + l = 0; + + MULADD_AB2(l, h, m, a[0], a[1]); + r[1] = m; + m = 0; + + MULADD_AB2(m, l, h, a[0], a[2]); + SQRADD_A(m, l, h, a[1]); + r[2] = h; + h = 0; + + MULADD_AB2(h, m, l, a[1], a[2]); + r[3] = l; + l = 0; + + SQRADD_A(l, h, m, a[2]); + r[4] = m; + r[5] = h; + return; + } + if (size == 2) { + SQRADD_A(h, m, l, a[0]); + r[0] = l; + l = 0; + + MULADD_AB2(l, h, m, a[0], a[1]); + r[1] = m; + m = 0; + + SQRADD_A(m, l, h, a[1]); + r[2] = h; + r[3] = l; + return; + } + SQR_A(r[1], r[0], a[0]); +} + +static void MulComba8(BN_UINT *r, const BN_UINT *a, const BN_UINT *b) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + + MUL_COMBA_BEGIN_1(r, a, b, h, m, l); + MUL_COMBA_BEGIN_2(r, a, b, h, m, l); + MUL_COMBA_BEGIN_3(r, a, b, h, m, l); + + MULADD_AB(h, m, l, a[2], b[7]); + MULADD_AB(h, m, l, a[3], b[6]); + MULADD_AB(h, m, l, a[4], b[5]); + MULADD_AB(h, m, l, a[5], b[4]); + MULADD_AB(h, m, l, a[6], b[3]); + MULADD_AB(h, m, l, a[7], b[2]); + r[9] = l; + l = 0; + + MULADD_AB(l, h, m, a[7], b[3]); + MULADD_AB(l, h, m, a[6], b[4]); + MULADD_AB(l, h, m, a[5], b[5]); + MULADD_AB(l, h, m, a[4], b[6]); + MULADD_AB(l, h, m, a[3], b[7]); + r[10] = m; + m = 0; + + MULADD_AB(m, l, h, a[4], b[7]); + MULADD_AB(m, l, h, a[5], b[6]); + MULADD_AB(m, l, h, a[6], b[5]); + MULADD_AB(m, l, h, a[7], b[4]); + r[11] = h; + h = 0; + + MULADD_AB(h, m, l, a[7], b[5]); + MULADD_AB(h, m, l, a[6], b[6]); + MULADD_AB(h, m, l, a[5], b[7]); + r[12] = l; + l = 0; + + MULADD_AB(l, h, m, a[6], b[7]); + MULADD_AB(l, h, m, a[7], b[6]); + r[13] = m; + m = 0; + + MULADD_AB(m, l, h, a[7], b[7]); + r[14] = h; + r[15] = l; +} + +void MulComba6(BN_UINT *r, const BN_UINT *a, const BN_UINT *b) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + + MUL_COMBA_BEGIN_1(r, a, b, h, m, l); + MUL_COMBA_BEGIN_2(r, a, b, h, m, l); + + MULADD_AB(h, m, l, a[5], b[1]); + MULADD_AB(h, m, l, a[4], b[2]); + MULADD_AB(h, m, l, a[3], b[3]); + MULADD_AB(h, m, l, a[2], b[4]); + MULADD_AB(h, m, l, a[1], b[5]); + r[6] = l; + l = 0; + + MULADD_AB(l, h, m, a[2], b[5]); + MULADD_AB(l, h, m, a[3], b[4]); + MULADD_AB(l, h, m, a[4], b[3]); + MULADD_AB(l, h, m, a[5], b[2]); + r[7] = m; + m = 0; + + MULADD_AB(m, l, h, a[5], b[3]); + MULADD_AB(m, l, h, a[4], b[4]); + MULADD_AB(m, l, h, a[3], b[5]); + r[8] = h; + h = 0; + + MULADD_AB(h, m, l, a[4], b[5]); + MULADD_AB(h, m, l, a[5], b[4]); + r[9] = l; + l = 0; + + MULADD_AB(l, h, m, a[5], b[5]); + r[10] = m; + r[11] = h; +} + +void MulComba4(BN_UINT *r, const BN_UINT *a, const BN_UINT *b) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + + MUL_COMBA_BEGIN_1(r, a, b, h, m, l); + + MULADD_AB(l, h, m, a[3], b[1]); + MULADD_AB(l, h, m, a[2], b[2]); + MULADD_AB(l, h, m, a[1], b[3]); + r[4] = m; + m = 0; + + MULADD_AB(m, l, h, a[2], b[3]); + MULADD_AB(m, l, h, a[3], b[2]); + r[5] = h; + h = 0; + + MULADD_AB(h, m, l, a[3], b[3]); + r[6] = l; + r[7] = m; +} + +static void MulComba(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t size) +{ + BN_UINT h = 0; + BN_UINT m = 0; + BN_UINT l = 0; + if (size == 3) { + MULADD_AB(h, m, l, a[0], b[0]); + r[0] = l; + l = 0; + + MULADD_AB(l, h, m, a[0], b[1]); + MULADD_AB(l, h, m, a[1], b[0]); + r[1] = m; + m = 0; + + MULADD_AB(m, l, h, a[2], b[0]); + MULADD_AB(m, l, h, a[1], b[1]); + MULADD_AB(m, l, h, a[0], b[2]); + r[2] = h; + h = 0; + + MULADD_AB(h, m, l, a[1], b[2]); + MULADD_AB(h, m, l, a[2], b[1]); + r[3] = l; + l = 0; + + MULADD_AB(l, h, m, a[2], b[2]); + r[4] = m; + r[5] = h; + return; + } + if (size == 2) { + MULADD_AB(h, m, l, a[0], b[0]); + r[0] = l; + l = 0; + + MULADD_AB(l, h, m, a[0], b[1]); + MULADD_AB(l, h, m, a[1], b[0]); + r[1] = m; + m = 0; + + MULADD_AB(m, l, h, a[1], b[1]); + r[2] = h; + r[3] = l; + return; + } + MUL_AB(r[1], r[0], a[0], b[0]); +} + +uint32_t SpaceSize(uint32_t size) +{ + uint32_t base = 8; + while (size > base) { + base <<= 1; + } + return base * 4; +} + +/* r = ABS(a - b). Need to ensure that aSize == bSize + (0 || 1). */ +static uint32_t ABS_Sub(BN_UINT *t, const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize) +{ + int32_t ret; + do { + if (aSize > bSize) { + t[bSize] = a[bSize]; /* bSize = aSize - 1 */ + if (a[bSize] > 0) { + ret = 1; + break; + } + } + ret = BinCmp(a, bSize, b, bSize); + } while (0); + if (ret > 0) { + BN_UINT borrow = BinSub(t, a, b, bSize); + if (aSize > bSize) { /* When the length difference exists and a > b exists, the borrowing is processed. */ + t[bSize] -= borrow; + } + return 0; + } else { + BinSub(t, b, a, bSize); + return 1; + } +} + +/** Only aSize == bSize is supported. This interface will recurse. The recursion depth is O(deep) = log2(size) + * Ensure that space >= SpaceSize(size) + * (ah|al * bh|bl) = (((ah*bh) << 2) + (((ah*bh) + (al*bl) - (ah - al)(bh - bl)) << 1) + (al*bl)) + */ +void MulConquer(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t size, BN_UINT *space, bool consttime) +{ + if (!consttime) { + if (size == 8) { + MulComba8(r, a, b); + return; + } + if (size == 6) { + MulComba6(r, a, b); + return; + } + if (size == 4) { + MulComba4(r, a, b); + return; + } + if (size < 4) { + MulComba(r, a, b, size); + return; + } + } else if (size <= 8) { + BinMul(r, size << 1, a, size, b, size); + return; + } + /* truncates the length of the high bits of the BigNum, that is the length of ah bh. */ + const uint32_t sizeHi = (size + 1) >> 1; + /* truncates the length of the low bits of the BigNum, that is the length of al bl. */ + const uint32_t sizeLo = size >> 1; + const uint32_t shift1 = sizeLo; /* (((ah*bh) + (al*bl) - (ah - al)(bh - bl)) << 1) location */ + const uint32_t shift2 = shift1 << 1; /* ((ah*bh) << 2) location */ + + /* Split the input 'space'. The current function uses tmp1 and tmp2, + and the remaining newspace is used by the lower layer. */ + BN_UINT *tmp1 = space; + BN_UINT *tmp2 = tmp1 + (sizeHi << 1); + BN_UINT *newSpace = tmp2 + (sizeHi << 1); + + /* tmp2 is the upper bits of a minus the lower bits of a, (ah-al) */ + uint32_t sign = ABS_Sub(tmp2, a + shift1, sizeHi, a, sizeLo); + /* tmp2 + sizeHi is the upper bits of b minus the lower bits of b, (bh-bl) */ + sign ^= ABS_Sub(tmp2 + sizeHi, b + shift1, sizeHi, b, sizeLo); + + MulConquer(r, a, b, sizeLo, newSpace, consttime); /* calculate (al*bl) */ + MulConquer(r + shift2, a + shift1, b + shift1, sizeHi, newSpace, consttime); /* calculate (ah*bh) */ + MulConquer(tmp1, tmp2, tmp2 + sizeHi, sizeHi, newSpace, consttime); /* calculate (ah-al)(bh-bl) */ + /* At this time r has stored ((ah*bh) << 2) and (al*bl) */ + /* carry should be added in (r + shift1)[sizeHi * 2] */ + /* tmp2 is (ah*bh) + (al*bl), but the processing length here is sizeLo * 2 */ + BN_UINT carry = BinAdd(tmp2, r, r + shift2, sizeLo << 1); + if (sizeHi > sizeLo) { + /* If there is a length difference, the length of (ah*bh) is sizeLo * 2 + 2, + and the tail of (ah*bh) needs to be processed. */ + /* point to (r + shift2)[sizeLo * 2], the unprocessed tail of (ah*bh) */ + const uint32_t position = shift2 + (sizeLo << 1); + tmp2[sizeLo << 1] = r[position] + carry; + carry = (tmp2[sizeLo << 1] < carry) ? 1 : 0; + /* continue the processing */ + tmp2[(sizeLo << 1) + 1] = r[position + 1] + carry; + carry = (tmp2[(sizeLo << 1) + 1] < carry) ? 1 : 0; + } + /* tmp1 = (ah*bh) + (al*bl) - (ah-al)(bh-bl), tmp2 is (ah*bh) + (al*bl) */ + if (sign == 1) { + carry += BinAdd(tmp1, tmp2, tmp1, sizeHi << 1); + } else { + carry -= BinSub(tmp1, tmp2, tmp1, sizeHi << 1); + } + /* finally r adds tmp1, that is (ah*bh) + (al*bl) - (ah - al)(bh - bl) */ + carry += BinAdd(r + shift1, r + shift1, tmp1, sizeHi << 1); + + uint32_t i; + for (i = shift1 + (sizeHi << 1); i < (size << 1); i++) { + ADD_AB(carry, r[i], r[i], carry); + } +} + +/** This interface will recurse. The recursion depth is O(deep) = log2(size) + * Ensure that space >= SpaceSize(size) + * (x|y)^2 = ((x^2 << 2) + ((x^2 + y^2 - (x - y)^2)) << 1) + y^2) + */ +void SqrConquer(BN_UINT *r, const BN_UINT *a, uint32_t size, BN_UINT *space, bool consttime) +{ + if (!consttime) { + if (size == 8) { + SqrComba8(r, a); + return; + } + if (size == 6) { + SqrComba6(r, a); + return; + } + if (size == 4) { + SqrComba4(r, a); + return; + } + if (size < 4) { + SqrComba(r, a, size); + return; + } + } else if (size <= 8) { + BinSqr(r, size << 1, a, size); + return; + } + + /* truncates the length of the high bits of the BigNum, that is the length of x. */ + const uint32_t sizeHi = (size + 1) >> 1; + /* truncates the length of the low bits of the BigNum, that is the length of y. */ + const uint32_t sizeLo = size >> 1; + const uint32_t shift1 = sizeLo; /* ((x^2 + y^2 - (x - y)^2)) << 1) location */ + const uint32_t shift2 = shift1 << 1; /* ((x^2 << 2) location */ + + /* Split the input 'space'. The current function uses tmp1 and tmp2, + and the remaining newspace is used by the lower layer. */ + BN_UINT *tmp1 = space; + BN_UINT *tmp2 = tmp1 + (sizeHi << 1); + BN_UINT *newSpace = tmp2 + (sizeHi << 1); + + ABS_Sub(tmp2, a + shift1, sizeHi, a, sizeLo); /* tmp2 is the upper bits of num minus the lower bits of num, (x-y) */ + + SqrConquer(r, a, sizeLo, newSpace, consttime); /* calculate y^2 */ + SqrConquer(r + shift2, a + shift1, sizeHi, newSpace, consttime); /* calculate x^2 */ + SqrConquer(tmp1, tmp2, sizeHi, newSpace, consttime); /* calculate (x-y)^2 */ + + /* At this time r has stored (x^2 << 2) and y^2 */ + /* carry should be added in (r + shift1)[sizeHi * 2] */ + /* tmp2 = x^2 + y^2, but the processing length here is sizeLo * 2 */ + BN_UINT carry = BinAdd(tmp2, r, r + shift2, sizeLo << 1); + if (sizeHi > sizeLo) { + /* If there is a length difference, the length of x^2 is sizeLo * 2 + 2, + and the tail of x^2 needs to be processed. */ + /* point to (r + shift2)[sizeLo * 2], the unprocessed tail of x^2 */ + const uint32_t position = shift2 + (sizeLo << 1); + tmp2[sizeLo << 1] = r[position] + carry; + carry = (tmp2[sizeLo << 1] < carry) ? 1 : 0; + /* continue the processing */ + tmp2[(sizeLo << 1) + 1] = r[position + 1] + carry; + carry = (tmp2[(sizeLo << 1) + 1] < carry) ? 1 : 0; + } + /* tmp1 = x^2 + y^2 - (x-y)^2, tmp2 is x^2 + y^2 */ + carry -= BinSub(tmp1, tmp2, tmp1, sizeHi << 1); + /* finally r adds x^2 + y^2 - (x-y)^2 */ + carry += BinAdd(r + shift1, r + shift1, tmp1, sizeHi << 1); + + uint32_t i; + for (i = shift1 + (sizeHi << 1); i < (size << 1); i++) { + ADD_AB(carry, r[i], r[i], carry); + } +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_gcd.c b/crypto/bn/src/bn_gcd.c new file mode 100644 index 00000000..fbf382de --- /dev/null +++ b/crypto/bn/src/bn_gcd.c @@ -0,0 +1,267 @@ +/* + * 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 +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "bn_basic.h" +#include "bn_bincal.h" +#include "bn_optimizer.h" + + +/* Euclidean algorithm */ +static int32_t BnGcdDiv(BN_BigNum *r, BN_BigNum *max, BN_BigNum *min, BN_Optimizer *opt) +{ + int32_t ret = CRYPT_SUCCESS; + BN_BigNum *tmp = NULL; + BN_BigNum *big = max; + BN_BigNum *small = min; + do { + ret = BN_Div(NULL, big, big, small, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_IsOne(big)) { + return BN_Copy(r, big); + } + if (BN_IsZero(big)) { + return BN_Copy(r, small); + } + /* ensure that big > small in the next calculation of remainder */ + tmp = big; + big = small; + small = tmp; + } while (true); + return CRYPT_SUCCESS; +} + +int32_t BnGcdCheckInput( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_Optimizer *opt) +{ + bool invalidInput = (a == NULL || b == NULL || r == NULL || opt == NULL); + if (invalidInput) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + /* The GCD may be the minimum value between a and b. Ensure the r space before calculation. */ + uint32_t needSize = (a->size < b->size) ? a->size : b->size; + if (BnExtend(r, needSize) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + // a and b cannot be 0 + if (BN_IsZero(a) || BN_IsZero(b)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_GCD_NO_ZERO); + return CRYPT_BN_ERR_GCD_NO_ZERO; + } + return CRYPT_SUCCESS; +} + +int32_t BN_Gcd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt) +{ + int32_t ret = BnGcdCheckInput(r, a, b, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = BinCmp(a->data, a->size, b->data, b->size); + if (ret == 0) { // For example, a == b is the greatest common divisor of itself + ret = BN_Copy(r, a); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_CLRNEG(r->flag); // the greatest common divisor is a positive integer + return CRYPT_SUCCESS; + } + const BN_BigNum *bigNum = (ret > 0) ? a : b; + const BN_BigNum *smallNum = (ret > 0) ? b : a; + ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* Apply for temporary space of BN objects a and b. */ + BN_BigNum *max = OptimizerGetBn(opt, bigNum->size); + BN_BigNum *min = OptimizerGetBn(opt, smallNum->size); + if (max == NULL || min == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + ret = BN_Copy(max, bigNum); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Copy(min, smallNum); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // obtain the GCD, ensure that input parameter max > min + ret = BnGcdDiv(r, max, min, opt); + if (ret == CRYPT_SUCCESS) { + BN_CLRNEG(r->flag); // The GCD is a positive integer + } + OptimizerEnd(opt); // release occupation from the optimizer + return ret; +} + +static int32_t InverseReady(BN_BigNum *a, BN_BigNum *b, const BN_BigNum *x, + const BN_BigNum *m, BN_Optimizer *opt) +{ + int32_t ret = BN_Copy(a, m); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_CLRNEG(a->flag); + ret = BN_Mod(b, x, m, opt); // b must be a positive number and do not need to convert symbols. + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_IsZero(b)) { // does not satisfy x and m interprime, so it cannot obtain the inverse module. + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_NO_INVERSE); + return CRYPT_BN_ERR_NO_INVERSE; + } + return CRYPT_SUCCESS; +} + +static int32_t InverseCore(BN_BigNum *r, BN_BigNum *x, BN_BigNum *y, uint32_t mSize, BN_Optimizer *opt) +{ + BN_BigNum *a = x; + BN_BigNum *b = y; + BN_BigNum *c = OptimizerGetBn(opt, mSize); // One more bit is reserved for addition and subtraction. + BN_BigNum *d = OptimizerGetBn(opt, mSize); + BN_BigNum *e = OptimizerGetBn(opt, mSize * 2); // multiplication of c requires 2x space + BN_BigNum *t = OptimizerGetBn(opt, mSize); + if (c == NULL || d == NULL || e == NULL || t == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + (void)BN_SetBit(d, 0); // can ignore the return value + do { + int32_t ret = BN_Div(t, a, a, b, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_IsZero(a)) { + if (BN_IsOne(b)) { // b is 1 + return BN_SetLimb(r, 1); // obtains the inverse modulus value 1 + } + break; // Failed to obtain the inverse modulus value. + } + t->flag ^= CRYPT_BN_FLAG_ISNEGTIVE; + ret = BN_Mul(e, t, d, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Add(c, c, e); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_IsOne(a)) { + return BN_Copy(r, c); // Obtain the module inverse. + } + // Switch a b + BN_BigNum *tmp = a; + a = b; + b = tmp; + // Switch c d + tmp = c; + c = d; + d = tmp; + } while (true); + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_NO_INVERSE); + return CRYPT_BN_ERR_NO_INVERSE; +} + +int32_t InverseInputCheck( + BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *m, const BN_Optimizer *opt) +{ + bool invalidInput = (r == NULL || x == NULL || m == NULL || opt == NULL); + if (invalidInput) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + /* cannot be 0 */ + if (BN_IsZero(x) || BN_IsZero(m)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO); + return CRYPT_BN_ERR_DIVISOR_ZERO; + } + if (BnExtend(r, m->size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t BN_ModInv( + BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *m, BN_Optimizer *opt) +{ + int32_t ret = InverseInputCheck(r, x, m, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = OptimizerStart(opt); // use the optimizer + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *a = OptimizerGetBn(opt, m->size); + BN_BigNum *b = OptimizerGetBn(opt, m->size); + BN_BigNum *t = OptimizerGetBn(opt, m->size); + bool invalidInput = (a == NULL || b == NULL || t == NULL); + if (invalidInput) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + goto ERR; + } + /* Take positive numbers a and b first. */ + ret = InverseReady(a, b, x, m, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* Extended Euclidean algorithm */ + ret = InverseCore(t, a, b, m->size, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // Prevent the negative number. + ret = BN_Mod(r, t, m, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR: + OptimizerEnd(opt); // Release occupation from the optimizer. + return ret; +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_lcm.c b/crypto/bn/src/bn_lcm.c new file mode 100644 index 00000000..bb37760b --- /dev/null +++ b/crypto/bn/src/bn_lcm.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "bn_basic.h" +#include "bn_bincal.h" +#include "bn_optimizer.h" + +int32_t BN_Lcm(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || b == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + BN_BigNum *gcd = BN_Create(BN_Bits(r)); + if (gcd == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = BN_Gcd(gcd, a, b, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BN_Destroy(gcd); + return ret; + } + if(BN_IsOne(gcd) == false) { + ret = BN_Div(r, NULL, a, gcd, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BN_Destroy(gcd); + return ret; + } + } + ret = BN_Mul(r, r, b, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_Destroy(gcd); + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_BN */ \ No newline at end of file diff --git a/crypto/bn/src/bn_mont.c b/crypto/bn/src/bn_mont.c new file mode 100644 index 00000000..703e7929 --- /dev/null +++ b/crypto/bn/src/bn_mont.c @@ -0,0 +1,744 @@ +/* + * 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 +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "bn_bincal.h" +#include "bn_optimizer.h" +#include "crypt_utils.h" +#include "bn_montbin.h" + +// The mont contains 4 BN_UINT* fields and 2 common fields. +#define MAX_MONT_SIZE ((BITS_TO_BN_UNIT(BN_MAX_BITS) * 4 + 2) * sizeof(BN_UINT)) + +static void CopyConsttime(BN_UINT *dst, const BN_UINT *a, const BN_UINT *b, + uint32_t len, BN_UINT mask) +{ + BN_UINT rmask = ~mask; + for (uint32_t i = 0; i < len; i++) { + dst[i] = (a[i] & mask) ^ (b[i] & rmask); + } +} + +/* reduce(r) */ +static void MontDecBin(BN_UINT *r, BN_Mont *mont) +{ + uint32_t mSize = mont->mSize; + BN_UINT *x = mont->t; + BN_COPY_BYTES(x, mSize << 1, r, mSize); + Reduce(r, x, mont->mod, mSize, mont->k0); +} + +/* Return value is (r - m0)' mod r */ +static BN_UINT Inverse(BN_UINT m0) +{ + BN_UINT x = 2; + BN_UINT y = 1; + BN_UINT mask = 1; + uint32_t i; + for (i = 1; i < BN_UINT_BITS; i++, x <<= 1) { + BN_UINT rH, rL; + mask = (mask << 1) | 1; + MUL_AB(rH, rL, m0, y); + if (x < (rL & mask)) { + y += x; + } + (void)rH; + } + return (BN_UINT)(0 - y); +} + +/* Pre-computation */ +static int32_t MontExpReady(BN_BigNum *table[], uint32_t num, BN_Mont *mont, + BN_Optimizer *opt, bool consttime) +{ + BN_UINT *b = mont->b; + uint32_t i; + for (i = 1; i < num; i++) { /* Request num - 1 data blocks */ + table[i] = OptimizerGetBn(opt, mont->mSize); + if (table[i] == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + } + table[0] = table[1]; + BN_COPY_BYTES(table[1]->data, mont->mSize, b, mont->mSize); + + for (i = 2; i < num; i++) { /* precompute num - 2 data blocks */ + int32_t ret = MontMulBin(table[i]->data, table[0]->data, table[i - 1]->data, + mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + return CRYPT_SUCCESS; +} + +static uint32_t GetELimb(const BN_UINT *e, BN_UINT *eLimb, uint32_t base, uint32_t bits) +{ + if (bits > base) { /* Required data */ + (*eLimb) = e[0] & (((1) << base) - 1); + return base; + } + (*eLimb) = 0; + uint32_t i; + for (i = 0; i < bits; i++) { + uint32_t bit = base - i - 1; + uint32_t nw = bit / BN_UINT_BITS; /* shift words */ + uint32_t nb = bit % BN_UINT_BITS; /* shift bits */ + (*eLimb) <<= 1; + (*eLimb) |= ((e[nw] >> nb) & 1); + } + return bits; +} + +static uint32_t GetReadySize(uint32_t bits) +{ + if (bits > 512) { + return 6; + } + if (bits > 256) { + return 5; + } + if (bits > 128) { + return 4; + } + if (bits > 64) { + return 3; + } + if (bits > 32) { + return 2; + } + return 1; +} + +/* r = r ^ e mod mont */ +static int32_t MontExpBin(BN_UINT *r, const BN_UINT *e, uint32_t eSize, BN_Mont *mont, + BN_Optimizer *opt, bool consttime) +{ + BN_BigNum *table[64] = { 0 }; /* 0 -- 2^6 that is 0 -- 64 */ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BN_COPY_BYTES(mont->b, mont->mSize, r, mont->mSize); + uint32_t base = BinBits(e, eSize) - 1; + uint32_t perSize = GetReadySize(base); + const uint32_t readySize = 1 << perSize; + ret = MontExpReady(table, readySize, mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + return ret; + } + do { + BN_UINT eLimb; + uint32_t bit = GetELimb(e, &eLimb, base, perSize); + for (uint32_t i = 0; i < bit; i++) { + ret = MontSqrBin(r, mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + return ret; + } + } + if (consttime == true) { + BN_UINT *x = mont->t; + BN_UINT mask = ~BN_IsZeroUintConsttime(eLimb); + ret = MontMulBin(x, r, table[eLimb]->data, mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + return ret; + } + CopyConsttime(r, x, r, mont->mSize, mask); + } else if (eLimb != 0) { + ret = MontMulBin(r, r, table[eLimb]->data, mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + return ret; + } + } + base -= bit; + } while (base != 0); + OptimizerEnd(opt); + return CRYPT_SUCCESS; +} + +static int32_t MontParaCheck(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, + const BN_Mont *mont, const BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || e == NULL || mont == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_ISNEG(a->flag)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_EXP_NO_NEGATIVE); + return CRYPT_BN_ERR_EXP_NO_NEGATIVE; + } + if (BnExtend(r, mont->mSize) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +static const BN_BigNum *DealBaseNum(const BN_BigNum *a, BN_Mont *mont, BN_Optimizer *opt, + int32_t *ret) +{ + const BN_BigNum *aTmp = NULL; + if (BinCmp(a->data, a->size, mont->mod, mont->mSize) >= 0) { + BN_BigNum *tmpval = + OptimizerGetBn(opt, a->size + 2); // BinDiv need a->room >= a->size + 2 + if (tmpval == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + *ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + return NULL; + } + *ret = BN_Copy(tmpval, a); + if (*ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(*ret); + return NULL; + } + tmpval->size = BinDiv(NULL, NULL, tmpval->data, tmpval->size, mont->mod, mont->mSize); + aTmp = tmpval; + return aTmp; + } + return a; +} + +static const BN_UINT *TmpValueHandle( + BN_BigNum *r, const BN_BigNum *e, const BN_BigNum *a, BN_Optimizer *opt) +{ + const BN_UINT *te = e->data; + uint32_t esize = e->size; + if (e == r) { + BN_BigNum *ee = OptimizerGetBn(opt, esize); + if (ee == NULL) { + return NULL; + } + BN_COPY_BYTES(ee->data, esize, e->data, esize); + te = ee->data; + } + BN_COPY_BYTES(r->data, r->room, a->data, a->size); + return te; +} + +/* must satisfy the absolute value x < mod */ +static int32_t MontExpCore(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, + BN_Mont *mont, BN_Optimizer *opt, bool consttime) +{ + if ((BinBits(e->data, e->size) == 0)) { + if (mont->mSize != 1) { + return BN_SetLimb(r, 1); + } + return (mont->mod[0] == 1) ? BN_Zeroize(r) : BN_SetLimb(r, 1); + } + if (a->size == 0) { + return BN_Zeroize(r); + } + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + /* if a >= mod */ + const BN_BigNum *aTmp = DealBaseNum(a, mont, opt, &ret); + if (aTmp == NULL) { + OptimizerEnd(opt); + return ret; + } + const BN_UINT *te = TmpValueHandle(r, e, aTmp, opt); + if (te == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + /* field conversion */ + ret = MontEncBin(r->data, mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + return ret; + } + /* modular exponentiation */ + ret = MontExpBin(r->data, te, e->size, mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + return ret; + } + /* field conversion */ + MontDecBin(r->data, mont); + + /* negative number processing */ + r->size = BinFixSize(r->data, mont->mSize); + if (BN_ISNEG(aTmp->flag) && ((te[0] & 0x1) == 1) && r->size != 0) { + BinSub(r->data, mont->mod, r->data, mont->mSize); + r->size = BinFixSize(r->data, mont->mSize); + } + BN_CLRNEG(r->flag); + OptimizerEnd(opt); + return CRYPT_SUCCESS; +} + +int32_t BN_MontExp(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, BN_Mont *mont, + BN_Optimizer *opt) +{ + int32_t ret = MontParaCheck(r, a, e, mont, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (BN_IsFlag(a, CRYPT_BN_FLAG_CONSTTIME) != 0 || BN_IsFlag(e, CRYPT_BN_FLAG_CONSTTIME) != 0) { + return MontExpCore(r, a, e, mont, opt, true); + } + return MontExpCore(r, a, e, mont, opt, false); +} + +/* must satisfy the absolute value x < mod */ +int32_t BN_MontExpConsttime(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, + BN_Mont *mont, BN_Optimizer *opt) +{ + int32_t ret = MontParaCheck(r, a, e, mont, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + return MontExpCore(r, a, e, mont, opt, true); +} + +static uint32_t MontSize(uint32_t room) +{ + uint32_t size = (uint32_t)(sizeof(BN_Mont) + sizeof(BN_UINT)); + /* Requires 5 * room + 1 space. mod(1) + montRR(1) + b(1) + t(2) = 5. + In addition, one more room is required when the modulus is set later. */ + size += (room * 5 + 1) * ((uint32_t)sizeof(BN_UINT)); + return size; +} + +void BN_MontDestroy(BN_Mont *mont) +{ + if (mont == NULL) { + return; + } + memset_s(mont, MontSize(mont->mSize), 0, MontSize(mont->mSize)); + BSL_SAL_FREE(mont); +} + +/* set the modulus */ +static void SetMod(BN_Mont *mont, const BN_BigNum *mod) +{ + uint32_t mSize = mod->size; + BN_COPY_BYTES(mont->mod, mSize, mod->data, mSize); + + mont->k0 = Inverse(mod->data[0]); + memset_s(mont->montRR, mSize * 2 * sizeof(BN_UINT), 0, mSize * 2 * sizeof(BN_UINT)); /* 2^2n */ + mont->montRR[mSize * 2] = 1; /* 2^2n */ + mont->montRR[mSize * 2 + 1] = 0; /* 2 more rooms are provided to ensure the division does not exceed the limit */ + mont->montRR[mSize * 2 + 2] = 0; /* 2 more rooms are provided to ensure the division does not exceed the limit */ + + // The size of the space required for calculating the montRR is 2 * mSize + 1 + BinDiv(NULL, NULL, mont->montRR, 2 * mSize + 1, mod->data, mSize); +} + +/* create a Montgomery structure, where m is a modulo */ +BN_Mont *BN_MontCreate(const BN_BigNum *m) +{ + if (m == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + if (!BN_GetBit(m, 0) || BN_ISNEG(m->flag)) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return NULL; + } + uint32_t mSize = m->size; + uint32_t montSize = MontSize(mSize); + if (montSize > MAX_MONT_SIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_TOO_MAX); + return NULL; + } + BN_Mont *mont = BSL_SAL_Malloc(montSize); + if (mont == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + BN_UINT *base = AlignedPointer((uint8_t *)mont + sizeof(BN_Mont), sizeof(BN_UINT)); + mont->mSize = mSize; + mont->mod = base; + mont->montRR = (base += mSize); + mont->b = (base += mSize); + mont->t = base + mSize; + SetMod(mont, m); + return mont; +} + +int32_t MontSqrBinCore(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime) +{ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t mSize = mont->mSize; + BN_UINT *x = mont->t; + uint32_t size = SpaceSize(mSize); + BN_BigNum *bnSpace = OptimizerGetBn(opt, size); + if (bnSpace == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + SqrConquer(x, r, mSize, bnSpace->data, consttime); + + Reduce(r, x, mont->mod, mSize, mont->k0); + + OptimizerEnd(opt); + return CRYPT_SUCCESS; +} + +/* reduce(a)= (a * R') mod N) */ +void ReduceCore(BN_UINT *r, BN_UINT *x, const BN_UINT *m, uint32_t mSize, BN_UINT m0) +{ + BN_UINT carry = 0; + uint32_t n = 0; + /* Cyclic shift, obtain r = (x / R) mod N */ + do { + BN_UINT q = x[n] * m0; /* q = (s[0] + x[i]) * m0 */ + BN_UINT tmp = BinMulAcc(x + n, m, mSize, q); /* (s + qm) mod m == s. Refresh s[0] to x[0] */ + /* Add carry to tmp and update carry flag. */ + tmp = tmp + carry; + carry = (tmp < carry) ? 1 : 0; + /* Add tmp to x[mSize + n] and update the carry flag. */ + x[mSize + n] += tmp; + carry = (x[mSize + n] < tmp) ? 1 : carry; + if (n + 1 == mSize) { + break; + } + n++; + } while (true); + /* If x < 2m, the carry value is 0 or -1. */ + carry -= BinSub(r, x + mSize, m, mSize); + CopyConsttime(r, x + mSize, r, mSize, carry); +} + +/* reduce(r * RR) */ +int32_t MontEncBinCore(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime) +{ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t mSize = mont->mSize; + BN_UINT *x = mont->t; + uint32_t size = SpaceSize(mSize); + BN_BigNum *bnSpace = OptimizerGetBn(opt, size); + if (bnSpace == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + MulConquer(x, r, mont->montRR, mSize, bnSpace->data, consttime); + Reduce(r, x, mont->mod, mSize, mont->k0); + + OptimizerEnd(opt); + return CRYPT_SUCCESS; +} + +/* reduce(r * b) */ +int32_t MontMulBinCore(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, BN_Mont *mont, + BN_Optimizer *opt, bool consttime) +{ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t mSize = mont->mSize; + BN_UINT *x = mont->t; + uint32_t size = SpaceSize(mSize); + BN_BigNum *bnSpace = OptimizerGetBn(opt, size); + if (bnSpace == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + MulConquer(x, a, b, mSize, bnSpace->data, consttime); + Reduce(r, x, mont->mod, mSize, mont->k0); + + OptimizerEnd(opt); + return CRYPT_SUCCESS; +} + +static int32_t GetFirstData(BN_UINT *r, uint32_t base1, uint32_t base2, + BN_BigNum *table1[], BN_BigNum *table2[], BN_Mont *mont, + BN_Optimizer *opt) +{ + bool consttime = false; + if (base1 == base2) { + return MontMulBin(r, table1[0]->data, table2[0]->data, mont, opt, consttime); + } else if (base1 > base2) { + BN_COPY_BYTES(r, mont->mSize, table1[0]->data, mont->mSize); + } else { + BN_COPY_BYTES(r, mont->mSize, table2[0]->data, mont->mSize); + } + return CRYPT_SUCCESS; +} + +/* Precalculate odd multiples of data. The data in the table is b^1, b^3, b^5...b^(2*num - 1) */ +static int32_t MontExpOddReady(BN_BigNum *table[], uint32_t num, BN_Mont *mont, + BN_Optimizer *opt, bool consttime) +{ + BN_UINT *b = mont->b; + uint32_t i; + for (i = 0; i < num; i++) { /* Request num - 1 data blocks */ + table[i] = OptimizerGetBn(opt, mont->mSize); + if (table[i] == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + } + BN_COPY_BYTES(table[0]->data, mont->mSize, b, mont->mSize); + if (num == 1) { + // When num is 1, pre-computation is not need. + return CRYPT_SUCCESS; + } + int32_t ret = MontSqrBin(table[0]->data, // b^2 + mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = MontMulBin(table[1]->data, table[0]->data, mont->b, // b^3 + mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + return ret; + } + for (i = 2; i < num; i++) { /* precompute num - 2 data blocks */ + // b^(2*i + 1) + ret = MontMulBin(table[i]->data, table[0]->data, table[i - 1]->data, + mont, opt, consttime); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + BN_COPY_BYTES(table[0]->data, mont->mSize, b, mont->mSize); + return CRYPT_SUCCESS; +} + +// Obtain the data with the length of bits from the start position of the base to the eLimb, +// ignore the high-order 0 data, and obtain an odd number or 0. +uint32_t GetOddLimbBin(const BN_UINT *e, uint32_t eSize, BN_UINT *eLimb, uint32_t base, uint32_t bits) +{ + (*eLimb) = 0; + if (base == 0) { + return 0; + } + uint32_t loc = base; + uint32_t retBits = 0; + // Offset from current. Check whether non-zero data exists. + while (true) { + loc--; + uint32_t nw = loc / BN_UINT_BITS; /* shift words */ + uint32_t nb = loc % BN_UINT_BITS; /* shift retBits */ + if (nw < eSize && ((e[nw] >> nb) & 1) != 0) { + // Exit the loop when the bit is 1. + break; + } + retBits++; + if (loc == 0) { + // If no valid bit is encountered until the end, the subsequent bits are returned. + return retBits; + } + } + // Obtain valid data from the loc location. + uint32_t i; + for (i = 0; i < bits; i++) { + uint32_t nw = loc / BN_UINT_BITS; /* shift words */ + uint32_t nb = loc % BN_UINT_BITS; /* shift retBits */ + (*eLimb) <<= 1; + (*eLimb) |= ((e[nw] >> nb) & 1); + retBits++; + if (loc == 0) { + // The remaining data is insufficient and the system exits early. + break; + } + loc--; + } + // The data must be 0 or an odd number. + while ((*eLimb) != 0 && ((*eLimb) & 1) == 0) { + // If eLimb is not 0 and is an even number, shift the eLimb to right. + (*eLimb) >>= 1; + retBits--; + } + return retBits; +} + +/* r = (a1 ^ e1) * (a2 ^ e2) mod mont */ +static int32_t MontExpMul(BN_UINT *r, const BN_BigNum *a1, const BN_BigNum *e1, + const BN_BigNum *a2, const BN_BigNum *e2, BN_Mont *mont, BN_Optimizer *opt) +{ + bool consttime = false; + BN_UINT eLimb1, eLimb2; + uint32_t bit1 = 0; + uint32_t bit2 = 0; + // The window retains only the values whose exponent is an odd number, reduce storage in half. + BN_BigNum *table1[32] = { 0 }; /* 0 -- (2^6 >> 1), that is 0 -- 32 */ + BN_BigNum *table2[32] = { 0 }; /* 0 -- (2^6 >> 1), that is 0 -- 32 */ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t base1 = BinBits(e1->data, e1->size); + uint32_t base2 = BinBits(e2->data, e2->size); + uint32_t base = (base1 > base2) ? base1 : base2; + + uint32_t perSize1 = GetReadySize(base1); + uint32_t perSize2 = GetReadySize(base2); + const uint32_t readySize1 = 1 << (perSize1 - 1); + const uint32_t readySize2 = 1 << (perSize2 - 1); + + // Generate the pre-computation table. + BN_COPY_BYTES(mont->b, mont->mSize, a1->data, mont->mSize); + GOTO_ERR_IF(MontExpOddReady(table1, readySize1, mont, opt, consttime), ret); + BN_COPY_BYTES(mont->b, mont->mSize, a2->data, mont->mSize); + GOTO_ERR_IF(MontExpOddReady(table2, readySize2, mont, opt, consttime), ret); + // Obtain the first data. + GOTO_ERR_IF(GetFirstData(r, base1, base2, table1, table2, mont, opt), ret); + base--; + + while (base != 0) { + bit1 = (bit1 == 0) ? GetOddLimbBin(e1->data, e1->size, &eLimb1, base, perSize1) : bit1; + bit2 = (bit2 == 0) ? GetOddLimbBin(e2->data, e2->size, &eLimb2, base, perSize2) : bit2; + uint32_t bit = (bit1 < bit2) ? bit1 : bit2; + uint32_t i = 0; + for (i = 0; i < bit; i++) { + GOTO_ERR_IF(MontSqrBin(r, mont, opt, consttime), ret); + } + if (bit == bit1 && eLimb1 != 0) { + GOTO_ERR_IF(MontMulBin(r, r, table1[(eLimb1 - 1) >> 1]->data, mont, opt, consttime), ret); + } + if (bit == bit2 && eLimb2 != 0) { + GOTO_ERR_IF(MontMulBin(r, r, table2[(eLimb2 - 1) >> 1]->data, mont, opt, consttime), ret); + } + bit1 -= bit; + bit2 -= bit; + base -= bit; + }; +ERR: + OptimizerEnd(opt); + return ret; +} + +static int32_t MontExpMulParaCheck(BN_BigNum *r, const BN_BigNum *a1, + const BN_BigNum *e1, const BN_BigNum *a2, const BN_BigNum *e2, const BN_Mont *mont, + const BN_Optimizer *opt) +{ + if (r == NULL || a1 == NULL || e1 == NULL || a2 == NULL || + e2 == NULL || mont == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_ISNEG(e1->flag | e2->flag)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_EXP_NO_NEGATIVE); + return CRYPT_BN_ERR_EXP_NO_NEGATIVE; + } + if (BnExtend(r, mont->mSize) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +typedef struct { + BN_BigNum *a1; + BN_BigNum *a2; + BN_BigNum *e1; + BN_BigNum *e2; +} MontsMulFactor; + +static int32_t MontsFactorGetByOptThenCopy(MontsMulFactor *dst, const MontsMulFactor *src, + uint32_t mSize, BN_Optimizer *opt) +{ + dst->a1 = OptimizerGetBn(opt, mSize); + dst->a2 = OptimizerGetBn(opt, mSize); + dst->e1 = OptimizerGetBn(opt, mSize); + dst->e2 = OptimizerGetBn(opt, mSize); + if (dst->a1 == NULL || dst->a2 == NULL || dst->e1 == NULL || dst->e2 == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + int32_t ret = BN_Copy(dst->a1, src->a1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = BN_Copy(dst->a2, src->a2); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = BN_Copy(dst->e1, src->e1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = BN_Copy(dst->e2, src->e2); + return ret; +} + +/* r = (a1 ^ e1) * (a2 ^ e2) mod mont */ +int32_t BN_MontExpMul(BN_BigNum *r, const BN_BigNum *a1, const BN_BigNum *e1, + const BN_BigNum *a2, const BN_BigNum *e2, BN_Mont *mont, BN_Optimizer *opt) +{ + int32_t ret = MontExpMulParaCheck(r, a1, e1, a2, e2, mont, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (BinCmp(a2->data, a2->size, mont->mod, mont->mSize) >= 0 || + BinCmp(a1->data, a1->size, mont->mod, mont->mSize) >= 0) { + /* a1 >= mod || a2 >= mod */ + BSL_ERR_PUSH_ERROR(CRYPT_BN_MONT_BASE_TOO_MAX); + return CRYPT_BN_MONT_BASE_TOO_MAX; + } + if (BN_IsZero(a1) || BN_IsZero(a2)) { + return BN_Zeroize(r); + } + if (BN_IsZero(e1)) { + return MontExpCore(r, a2, e2, mont, opt, false); + } + if (BN_IsZero(e2)) { + return MontExpCore(r, a1, e1, mont, opt, false); + } + ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + MontsMulFactor factor; + const MontsMulFactor srcFactor = {(BN_BigNum *)(uintptr_t)a1, (BN_BigNum *)(uintptr_t)a2, + (BN_BigNum *)(uintptr_t)e1, (BN_BigNum *)(uintptr_t)e2}; + GOTO_ERR_IF_EX(MontsFactorGetByOptThenCopy(&factor, &srcFactor, mont->mSize, opt), ret); + /* field conversion */ + GOTO_ERR_IF(MontEncBin(factor.a1->data, mont, opt, false), ret); + GOTO_ERR_IF(MontEncBin(factor.a2->data, mont, opt, false), ret); + /* modular exponentiation */ + GOTO_ERR_IF_EX(MontExpMul(r->data, factor.a1, factor.e1, factor.a2, factor.e2, mont, opt), ret); + /* field conversion */ + MontDecBin(r->data, mont); + r->size = BinFixSize(r->data, mont->mSize); + BN_CLRNEG(r->flag); +ERR: + OptimizerEnd(opt); + return ret; +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_montbin.h b/crypto/bn/src/bn_montbin.h new file mode 100644 index 00000000..64e7681e --- /dev/null +++ b/crypto/bn/src/bn_montbin.h @@ -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 BN_MONTBIN_H +#define BN_MONTBIN_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include +#include "crypt_bn.h" + +#ifdef __cplusplus +extern "c" { +#endif + +/* r = reduce(r * r) mod mont */ +int32_t MontSqrBin(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime); + +/* r = reduce(a * b) mod mont */ +int32_t MontMulBin(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, BN_Mont *mont, + BN_Optimizer *opt, bool consttime); + +/* r = reduce(r * montRR) mod mont */ +int32_t MontEncBin(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime); + +/* r = reduce(x * 1) mod m = (x * R') mod m */ +void Reduce(BN_UINT *r, BN_UINT *x, const BN_UINT *m, uint32_t mSize, BN_UINT m0); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_BN + +#endif // BN_MONTBIN_H diff --git a/crypto/bn/src/bn_nistmod.c b/crypto/bn/src/bn_nistmod.c new file mode 100644 index 00000000..c23692ad --- /dev/null +++ b/crypto/bn/src/bn_nistmod.c @@ -0,0 +1,1082 @@ +/* + * 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_BN) && defined(HITLS_CRYPTO_ECC) + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "bn_bincal.h" + +// Refresh the valid length of the BigNum r. The maximum length is modSize. +static void UpdateSize(BN_BigNum *r, uint32_t modSize) +{ + uint32_t size = modSize; + while (size > 0) { + if (r->data[size - 1] != 0) { + break; + } + size--; + } + if (r->size > modSize) { + // Clear the high bits. + uint32_t i = 0; + for (i = modSize; i < r->size; i++) { + r->data[i] = 0; + } + } + r->size = size; + BN_CLRNEG(r->flag); +} + +#define P521SIZE SIZE_OF_BNUINT(521) +#define P256SIZE SIZE_OF_BNUINT(256) +#define SIZE_OF_BNUINT(bits) (((bits) + BN_UINT_BITS - 1) / BN_UINT_BITS) // 1byte = 8bit + + +#if defined(HITLS_SIXTY_FOUR_BITS) +#define P224SIZE SIZE_OF_BNUINT(224) +#define P384SIZE SIZE_OF_BNUINT(384) + +BN_UINT g_modDataP224[][P224SIZE] = { + { // 1p + 0x0000000000000001UL, 0xffffffff00000000UL, + 0xffffffffffffffffUL, 0x00000000ffffffffUL + }, + { // 2p + 0x0000000000000002UL, 0xfffffffe00000000UL, + 0xffffffffffffffffUL, 0x00000001ffffffffUL + } +}; + +BN_UINT g_modDataP256[][P256SIZE] = { + { // p + 0xffffffffffffffffUL, 0x00000000ffffffffUL, + 0x0000000000000000UL, 0xffffffff00000001UL + }, + { // 2p + 0xfffffffffffffffeUL, 0x00000001ffffffffUL, + 0x0000000000000000UL, 0xfffffffe00000002UL + }, + { // 3p + 0xfffffffffffffffdUL, 0x00000002ffffffffUL, + 0x0000000000000000UL, 0xfffffffd00000003UL + }, + { // 4p + 0xfffffffffffffffcUL, 0x00000003ffffffffUL, + 0x0000000000000000UL, 0xfffffffc00000004UL + }, + { // 5p + 0xfffffffffffffffbUL, 0x00000004ffffffffUL, + 0x0000000000000000UL, 0xfffffffb00000005UL + }, +}; +#ifdef HITLS_CRYPTO_SM2 +const BN_UINT MODDATASM2P256[][P256SIZE] = { + { // p + 0xffffffffffffffffUL, 0xffffffff00000000UL, + 0xffffffffffffffffUL, 0xfffffffeffffffffUL + }, + { // 2p + 0xfffffffffffffffeUL, 0xfffffffe00000001UL, + 0xffffffffffffffffUL, 0xfffffffdffffffffUL + }, + { // 3p + 0xfffffffffffffffdUL, 0xfffffffd00000002UL, + 0xffffffffffffffffUL, 0xfffffffcffffffffUL + }, + { // 4p + 0xfffffffffffffffcUL, 0xfffffffc00000003UL, + 0xffffffffffffffffUL, 0xfffffffbffffffffUL + }, + { // 5p + 0xfffffffffffffffbUL, 0xfffffffb00000004UL, + 0xffffffffffffffffUL, 0xfffffffaffffffffUL + }, + { // 6p + 0xfffffffffffffffaUL, 0xfffffffa00000005UL, + 0xffffffffffffffffUL, 0xfffffff9ffffffffUL + }, + { // 7p + 0xfffffffffffffff9UL, 0xfffffff900000006UL, + 0xffffffffffffffffUL, 0xfffffff8ffffffffUL + }, + { // 8p + 0xfffffffffffffff8UL, 0xfffffff800000007UL, + 0xffffffffffffffffUL, 0xfffffff7ffffffffUL + }, + { // 9p + 0xfffffffffffffff7UL, 0xfffffff700000008UL, + 0xffffffffffffffffUL, 0xfffffff6ffffffffUL + }, + { // 10p + 0xfffffffffffffff6UL, 0xfffffff600000009UL, + 0xffffffffffffffffUL, 0xfffffff5ffffffffUL + }, + { // 11p + 0xfffffffffffffff5UL, 0xfffffff50000000aUL, + 0xffffffffffffffffUL, 0xfffffff4ffffffffUL + }, + { // 12p + 0xfffffffffffffff4UL, 0xfffffff40000000bUL, + 0xffffffffffffffffUL, 0xfffffff3ffffffffUL + }, + { // 13p + 0xfffffffffffffff3UL, 0xfffffff30000000cUL, + 0xffffffffffffffffUL, 0xfffffff2ffffffffUL + }, +}; +#endif + +const BN_UINT MOD_DATA_P384[][P384SIZE] = { + { + 0x00000000ffffffffUL, 0xffffffff00000000UL, 0xfffffffffffffffeUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL + }, + { + 0x00000001fffffffeUL, 0xfffffffe00000000UL, 0xfffffffffffffffdUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL + }, + { + 0x00000002fffffffdUL, 0xfffffffd00000000UL, 0xfffffffffffffffcUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL + }, + { + 0x00000003fffffffcUL, 0xfffffffc00000000UL, 0xfffffffffffffffbUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL + }, + { + 0x00000004fffffffbUL, 0xfffffffb00000000UL, 0xfffffffffffffffaUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL + }, +}; + +const BN_UINT MOD_DATA_P521[P521SIZE] = { + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, + 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0x00000000000001ffUL +}; + +static BN_UINT NistP384Add(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n) +{ + (void)n; + BN_UINT carry = 0; + ADD_ABC(carry, r[0], a[0], b[0], carry); + ADD_ABC(carry, r[1], a[1], b[1], carry); + ADD_ABC(carry, r[2], a[2], b[2], carry); + ADD_ABC(carry, r[3], a[3], b[3], carry); + ADD_ABC(carry, r[4], a[4], b[4], carry); + ADD_ABC(carry, r[5], a[5], b[5], carry); + return carry; +} + +static BN_UINT NistP384Sub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n) +{ + (void)n; + BN_UINT borrow = 0; + SUB_ABC(borrow, r[0], a[0], b[0], borrow); + SUB_ABC(borrow, r[1], a[1], b[1], borrow); + SUB_ABC(borrow, r[2], a[2], b[2], borrow); + SUB_ABC(borrow, r[3], a[3], b[3], borrow); + SUB_ABC(borrow, r[4], a[4], b[4], borrow); + SUB_ABC(borrow, r[5], a[5], b[5], borrow); + return borrow; +} + +/** + * Reduction item: 2^128 + 2^96 - 2^32+ 2^0 + * + * Reduction list 11 10 9 8 7 6 5 4 3 2 1 0 + * a12 00, 00, 00, 00, 00, 00, 00, 01, 01, 00, -1, 01, + * a13 00, 00, 00, 00, 00, 00, 01, 01, 00, -1, 01, 00, + * a14 00, 00, 00, 00, 00, 01, 01, 00, -1, 01, 00, 00, + * a15 00, 00, 00, 00, 01, 01, 00, -1, 01, 00, 00, 00, + * a16 00, 00, 00, 01, 01, 00, -1, 01, 00, 00, 00, 00, + * a17 00, 00, 01, 01, 00, -1, 01, 00, 00, 00, 00, 00, + * a18 00, 01, 01, 00, -1, 01, 00, 00, 00, 00, 00, 00, + * a19 01, 01, 00, -1, 01, 00, 00, 00, 00, 00, 00, 00, + * a20 01, 00, -1, 01, 00, 00, 00, 01, 01, 00, -1, 01, + * a21 00, -1, 01, 00, 00, 00, 01, 02, 01, -1, 00, 01, + * a22 -1, 01, 00, 00, 00, 01, 02, 01, -1, 00, 01, 00, + * a23 01, 00, 00, 00, 01, 02, 01, -2, -1, 01, 01, -1 + * + * Reduction chain + * Coefficient 11 10 9 8 7 6 5 4 3 2 1 0 + * 1 a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 + * 1 a20 a19 a18 a17 a16 a15 a14 a13 a12 a23 a22 a21 + * 1 a19 a18 a17 a16 a15 a14 a13 a12 a20 a23 a20 + * 1 a23 a22 a21 a20 a21 + * 1 a23 a22 + * 2 a23 a22 a21 + * -1 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a23 + * -1 a23 a22 a21 a20 + * -1 a23 a23 + */ +int8_t ReduceNistP384(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT list[P384SIZE]; + BN_UINT t[P384SIZE]; + // 0 + list[5] = a[11]; // offset 5 a23|a22 == ah[11]|al[11] + list[4] = a[10]; // offset 4 a21|a20 == ah[10]|al[10] + list[3] = a[9]; // offset 3 a19|a18 == ah[9]|al[9] + list[2] = a[8]; // offset 2 a17|a16 == ah[8]|al[8] + list[1] = a[7]; // offset 1 a15|a14 == ah[7]|al[7] + list[0] = a[6]; // offset 0 a13|a12 == ah[6]|al[6] + // 1 + t[5] = BN_UINT_LO_TO_HI(a[10]) | BN_UINT_HI(a[9]); // offset 5 a20|a19 == al[10]|ah[9] + t[4] = BN_UINT_LO_TO_HI(a[9]) | BN_UINT_HI(a[8]); // offset 4 a18|a17 == al[9]|ah[8] + t[3] = BN_UINT_LO_TO_HI(a[8]) | BN_UINT_HI(a[7]); // offset 3 a16|a15 == al[8]|ah[7] + t[2] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]); // offset 2 a14|a13 == al[7]|ah[6] + t[1] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[11]); // offset 1 a12|a23 == al[6]|ah[11] + t[0] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]); // offset 0 a22|a21 == al[11]|ah[10] + int8_t carry = (int8_t)NistP384Add(t, list, t, P384SIZE); + // 2 + list[5] = a[9]; // offset 5 a19|a18 == ah[9]|al[9] + list[4] = a[8]; // offset 4 a17|a16 == ah[8]|al[8] + list[3] = a[7]; // offset 3 a15|a14 == ah[7]|al[7] + list[2] = a[6]; // offset 2 a13|a12 == ah[6]|al[6] + list[1] = BN_UINT_LO_TO_HI(a[10]); // offset 1 a20|0 == al[10]| 0 + list[0] = BN_UINT_HI_TO_HI(a[11]) | BN_UINT_LO(a[10]); // offset 0 a23|a20 == ah[11]|al[10] + carry += (int8_t)NistP384Add(t, list, t, P384SIZE); + // 3 + list[5] = 0; // offset 5 0 + list[4] = 0; // offset 4 0 + list[3] = a[11]; // offset 3 a23|a22 == ah[11]|al[11] + list[2] = a[10]; // offset 2 a21|a20 == ah[10]|al[10] + list[1] = BN_UINT_HI_TO_HI(a[10]); // offset 1 a21|0 == ah[10]|0 + list[0] = 0; // offset 0 0 + carry += (int8_t)NistP384Add(t, list, t, P384SIZE); + // 4 + list[5] = 0; // offset 5 0 + list[4] = 0; // offset 4 0 + list[3] = 0; // offset 3 0 + list[2] = a[11]; // offset 2 a23|a22 == ah[11]|al[11] + list[1] = 0; // offset 1 0 + list[0] = 0; // offset 0 0 + carry += (int8_t)NistP384Add(t, list, t, P384SIZE); + // 5 + list[5] = 0; // offset 5 0 + list[4] = 0; // offset 4 0 + list[3] = BN_UINT_HI(a[11]); // offset 3 0|a23 == 0|ah[11] + list[2] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]); // offset 2 a22|a21 == al[11]|ah[10] + list[1] = 0; // offset 1 0 + list[0] = 0; // offset 0 0 + // double 5 + // list[3] is left-shifted by 1 bit and the most significant bit of list[2] is added. + list[3] = (list[2] >> (BN_UINT_BITS - 1)) | (list[3] << 1); + list[2] = list[2] << 1; // list[2] left-shifted by 1bit + carry += (int8_t)NistP384Add(t, list, t, P384SIZE); + // 6 + list[5] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]); // offset 5 a22|a21 == al[11]|ah[10] + list[4] = BN_UINT_LO_TO_HI(a[10]) | BN_UINT_HI(a[9]); // offset 4 a20|a19 == al[10]|ah[9] + list[3] = BN_UINT_LO_TO_HI(a[9]) | BN_UINT_HI(a[8]); // offset 3 a18|a17 == al[9]|ah[8] + list[2] = BN_UINT_LO_TO_HI(a[8]) | BN_UINT_HI(a[7]); // offset 2 a16|a15 == al[8]|ah[7] + list[1] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]); // offset 1 a14|a13 == al[7]|ah[6] + list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[11]); // offset 0 a12|a23 == al[6]|ah[11] + carry -= (int8_t)NistP384Sub(t, t, list, P384SIZE); + // 7 + list[5] = 0; // offset 5 0 + list[4] = 0; // offset 4 0 + list[3] = 0; // offset 3 0 + list[2] = BN_UINT_HI(a[11]); // offset 2 0|a23 == 0|ah[11] + list[1] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]); // offset 1 a22|a21 == al[11]|ah[10] + list[0] = BN_UINT_LO_TO_HI(a[10]); // offset 0 a20|0 == al[10]|0 + carry -= (int8_t)NistP384Sub(t, t, list, P384SIZE); + // 8 + list[5] = 0; // offset 5 0 + list[4] = 0; // offset 4 0 + list[3] = 0; // offset 3 0 + list[2] = BN_UINT_HI(a[11]); // offset 2 0|a23 == 0|ah[11] + list[1] = BN_UINT_HI_TO_HI(a[11]); // offset 1 a23|0 == ah[11]|0 + list[0] = 0; // offset 0 + carry -= (int8_t)NistP384Sub(t, t, list, P384SIZE); + carry += (int8_t)NistP384Add(r, t, a, P384SIZE); + + return carry; +} + +// The size of a is 2*P384SIZE, and the size of r is P384SIZE +int32_t ModNistP384( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + (void)opt; + (void)m; + const BN_UINT *mod = MOD_DATA_P384[0]; + int8_t carry = ReduceNistP384(r->data, a->data); + if (carry > 0) { + carry = (int8_t)1 - (int8_t)BinSub(r->data, r->data, MOD_DATA_P384[carry - 1], P384SIZE); + } else if (carry < 0) { + carry = (int8_t)1 - (int8_t)BinAdd(r->data, r->data, MOD_DATA_P384[-carry - 1], P384SIZE); + carry = -carry; + } + if (carry > 0 || BinCmp(r->data, P384SIZE, mod, P384SIZE) >= 0) { + BinSub(r->data, r->data, mod, P384SIZE); + } else if (carry < 0) { + BinAdd(r->data, r->data, mod, P384SIZE); + } + UpdateSize(r, P384SIZE); + return 0; +} + +// Reduction item: 2^0 +int8_t ReduceNistP521(BN_UINT *r, const BN_UINT *a) +{ + #define P521LEFTBITS (521 % (sizeof(BN_UINT) * 8)) + #define P521RIGHTBITS ((sizeof(BN_UINT) * 8) - P521LEFTBITS) + BN_UINT t[P521SIZE]; + uint32_t base = P521SIZE - 1; + uint32_t i; + for (i = 0; i < P521SIZE - 1; i++) { + t[i] = (a[i + base] >> P521LEFTBITS) | (a[i + base + 1] << P521RIGHTBITS); + r[i] = a[i]; + } + r[i] = a[i] & (((BN_UINT)1 << (P521LEFTBITS)) - 1); + t[i] = (a[i + base] >> P521LEFTBITS); + BinAdd(r, t, r, P521SIZE); + return 0; +} + +// The size of a is 2*P521SIZE-1, and the size of r is P521SIZE +int32_t ModNistP521( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + (void)opt; + (void)m; + const BN_UINT *mod = MOD_DATA_P521; + ReduceNistP521(r->data, a->data); + + if (BinCmp(r->data, P521SIZE, mod, P521SIZE) >= 0) { + BinSub(r->data, r->data, mod, P521SIZE); + } + UpdateSize(r, P521SIZE); + + return 0; +} + +static inline int8_t P256SUB(BN_UINT *rr, const BN_UINT *aa, const BN_UINT *bb) +{ + BN_UINT borrow; + SUB_AB(borrow, rr[0], aa[0], bb[0]); + 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); + return (int8_t)borrow; +} + +static inline int8_t P256ADD(BN_UINT *rr, const BN_UINT *aa, const BN_UINT *bb) +{ + BN_UINT carry; + ADD_AB(carry, rr[0], aa[0], bb[0]); + 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); + return (int8_t)carry; +} + +/** + * NIST_P256 curve reduction calculation for parameter P + * Reduction item: 2^224 - 2^192 - 2^96 + 2^0 + * + * Reduction list: + * 7 6 5 4 3 2 1 0 + * a8 01, -1, 00, 00, -1, 00, 00, 01, + * a9 00, -1, 00, -1, -1, 00, 01, 01, + * a10 -1, 00, -1, -1, 00, 01, 01, 00, + * a11 -1, 00, -1, 00, 02, 01, 00, -1, + * a12 -1, 00, 00, 02, 02, 00, -1, -1, + * a13 -1, 01, 02, 02, 01, -1, -1, -1, + * a14 00, 03, 02, 01, 00, -1, -1, -1, + * a15 03, 02, 01, 00, -1, -1, -1, 00 + * + * Reduction chain + * Coefficient 7 6 5 4 3 2 1 0 + * 2 a15 a14 a13 a12 a12 0 0 0 + * 2 a15 a14 a13 a11 + * 1 a15 a14 a15 a14 a13 a11 a9 a8 + * 1 a8 a13 a10 a10 a9 + * -1 a13 a9 a11 a10 a15 a14 a15 a14 + * -1 a12 a8 a10 a9 a8 a13 a14 a13 + * -1 a11 a9 a15 a13 a12 + * -1 a10 a12 a11 + */ +static int8_t ReduceNistP256(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT list[P256SIZE]; + BN_UINT t[P256SIZE]; + // Reduction chain 0 + list[3] = a[7]; // offset 3 a15|a14 == ah[7]|al[7] + list[2] = a[6]; // offset 2 a13|a12 == ah[6]|al[6] + list[1] = BN_UINT_LO_TO_HI(a[6]); // offset 1 a12|0 == al[6]|0 + list[0] = 0; // offset 0 0 + // Reduction chain 1 + t[3] = BN_UINT_HI(a[7]); // offset 3 0|a15 == 0|ah[7] + t[2] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]); // offset 2 a14|a13 == al[7]|ah[6] + t[1] = BN_UINT_HI_TO_HI(a[5]); // offset 1 a11|0 == ah[5]|0 + t[0] = 0; // offset 0 0 + int8_t carry = P256ADD(t, t, list); + // carry multiplied by 2 and padded with the most significant bit of t[3] + carry = (carry * 2) + (int8_t)(t[3] >> (BN_UINT_BITS - 1)); + t[3] = (t[3] << 1) | (t[2] >> (BN_UINT_BITS - 1)); // t[3] is shifted left by 1 bit and the MSB of t[2] is added. + t[2] = (t[2] << 1) | (t[1] >> (BN_UINT_BITS - 1)); // t[2] is shifted left by 1 bit and the MSB of t[1] is added. + t[1] = (t[1] << 1) | (t[0] >> (BN_UINT_BITS - 1)); // t[1] is shifted left by 1 bit and the MSB of t[0] is added. + t[0] <<= 1; + // 2 + list[3] = a[7]; // offset 3 a15|a14 == ah[7]|al[7] + list[2] = a[7]; // offset 2 a15|a14 == ah[7]|al[7] + list[1] = BN_UINT_HI_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 1 a13|a11 == ah[6]|ah[5] + list[0] = a[4]; // offset 0 a9|a8 == ah[4]|al[4] + carry += (int8_t)P256ADD(t, t, list); + // 3 + list[3] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[6]); // offset 3 a8|a13 == al[4]|ah[6] + list[2] = 0; // offset 2 0 + list[1] = BN_UINT_LO(a[5]); // offset 1 0|a10 == 0|al[5] + list[0] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]); // offset 0 a10|a9 == al[5]|ah[4] + carry += (int8_t)P256ADD(t, t, list); + // 4 + list[3] = BN_UINT_HI_TO_HI(a[6]) | BN_UINT_HI(a[4]); // offset 3 a13|a9 == ah[6]|ah[4] + list[2] = a[5]; // offset 2 a11|a10 == ah[5]|al[5] + list[1] = a[7]; // offset 1 a15|a14 == ah[7]|al[7] + list[0] = a[7]; // offset 0 a15|a14 == ah[7]|al[7] + carry -= (int8_t)P256SUB(t, t, list); + // 5 + list[3] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_LO(a[4]); // offset 3 a12|a8 == al[6]|al[4] + list[2] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]); // offset 2 a10|a9 == al[5]|ah[4] + list[1] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[6]); // offset 1 a8|a13 == al[4]|ah[6] + list[0] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]); // offset 0 a14|a13 == al[7]|ah[6] + carry -= (int8_t)P256SUB(t, t, list); + // 6 + list[3] = BN_UINT_HI_TO_HI(a[5]); // offset 3 a11|0 == ah[5]|0 + list[2] = 0; // offset 2 0 + list[1] = BN_UINT_HI_TO_HI(a[4]) | BN_UINT_HI(a[7]); // offset 1 a9|a15 == ah[4]|ah[7] + list[0] = a[6]; // offset 0 a13|a12 == ah[6]|al[6] + carry -= (int8_t)P256SUB(t, t, list); + // 7 + list[3] = BN_UINT_LO_TO_HI(a[5]); // offset 3 a10|0 == al[5]|0 + list[2] = 0; // offset 2 0 + list[1] = 0; // offset 1 0 + list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 0 a12|a11 == al[6]|ah[5] + carry -= (int8_t)P256SUB(t, t, list); + carry += (int8_t)P256ADD(r, t, a); + return carry; +} + +// For the NIST_P256 curve, perform modulo operation on parameter P. +// The size of a is 2*P256SIZE, and the size of r is P256SIZE +int32_t ModNistP256( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + (void)opt; + (void)m; + const BN_UINT *mod = g_modDataP256[0]; + int8_t carry = ReduceNistP256(r->data, a->data); + if (carry > 0) { + carry = (int8_t)1 - (int8_t)P256SUB(r->data, r->data, g_modDataP256[carry - 1]); + } else if (carry < 0) { + carry = (int8_t)1 - (int8_t)P256ADD(r->data, r->data, g_modDataP256[-carry - 1]); + carry = -carry; + } + if (carry > 0 || BinCmp(r->data, P256SIZE, mod, P256SIZE) >= 0) { + P256SUB(r->data, r->data, mod); + } else if (carry < 0) { + P256ADD(r->data, r->data, mod); + } + UpdateSize(r, P256SIZE); + return 0; +} + +/** + * NIST_P224 curve reduction calculation for parameter P + * Reduction item: 2^96 - 2^0 + * + * Reduction list: + * 6 5 4 3 2 1 0 + * a7 00, 00, 00, 01, 00, 00, -1 + * a8 00, 00, 01, 00, 00, -1, 00 + * a9 00, 01, 00, 00, -1, 00, 00 + * a10 01, 00, 00, -1, 00, 00, 00 + * a11 00, 00, -1, 01, 00, 00, -1 + * a12 00, -1, 01, 00, 00, -1, 00 + * a13 -1, 01, 00, 00, -1, 00, 00 + * + * Reduction chain + * Coefficient 6 5 4 3 2 1 0 + * 1 a10 a9 a8 a7 + * 1 a13 a12 a11 + * -1 a13 a12 a11 a10 a9 a8 a7 + * -1 a13 a12 a11 + */ +static int8_t ReduceNistP224(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT list[P224SIZE]; + BN_UINT t[P224SIZE]; + // 1 + list[3] = BN_UINT_LO(a[5]); // offset 3 0|a10 == 0|al[5] + list[2] = a[4]; // offset 2 a9|a8 == ah[4]|al[4] + list[1] = BN_UINT_HI_TO_HI(a[3]); // offset 1 a7|0 == ah[3]|0 + list[0] = 0; // offset 0 0 + // 2 + t[3] = 0; // offset 3 0 + t[2] = a[6]; // offset 2 a13|a12 == ah[6]|al[6] + t[1] = BN_UINT_HI_TO_HI(a[5]); // offset 1 a11|0 == ah[5]|0 + t[0] = 0; // offset 0 0 + P256ADD(t, t, list); + // 3 + list[3] = BN_UINT_HI(a[6]); // offset 3 0|a13 == 0|ah[6] + list[2] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 2 a12|a11 == al[6]|ah[5] + list[1] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]); // offset 1 a10|a9 == al[5]|ah[4] + list[0] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[3]); // offset 0 a8|a7 == al[4]|ah[3] + P256SUB(t, t, list); + // 4 + list[3] = 0; // offset 3 0 + list[2] = 0; // offset 2 0 + list[1] = BN_UINT_HI(a[6]); // offset 1 0|a13 == 0|ah[6] + list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 0 a12|a11 == al[6]|ah[5] + P256SUB(t, t, list); + + r[3] = BN_UINT_LO(a[3]); // Take lower 32 bits of a[3] + r[2] = a[2]; // Take a[2] + r[1] = a[1]; + r[0] = a[0]; + P256ADD(r, r, t); + + return 0; +} + +// NIST_P224 curve reduction calculation for parameter P. The size of a is 2*P224SIZE-1, and the size of r is P224SIZE +int32_t ModNistP224( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + (void)opt; + (void)m; + const BN_UINT *mod = g_modDataP224[0]; + ReduceNistP224(r->data, a->data); + // Obtain the high-order data of r[3] as carry information + int8_t carry = (int8_t)((uint8_t)(BN_UINT_HI(r->data[3]) & 0xFF)); + if (carry > 0) { + P256SUB(r->data, r->data, g_modDataP224[carry - 1]); + } else if (carry < 0) { + P256ADD(r->data, r->data, g_modDataP224[-carry - 1]); + } + // Obtain the high-order data of r[3] as carry information + carry = (int8_t)((uint8_t)(BN_UINT_HI(r->data[3]) & 0xFF)); + if (carry > 0 || BinCmp(r->data, P256SIZE, mod, P256SIZE) >= 0) { + P256SUB(r->data, r->data, mod); + } else if (carry < 0) { + P256ADD(r->data, r->data, mod); + } + UpdateSize(r, P224SIZE); + return 0; +} + +/** + * Reduction item: 2^224 + 2^96 - 2^64 + 2^0 + * 7 6 5 4 3 2 1 0 + * a8 01, 00, 00, 00, 01, -1, 00, 01, + * a9 01, 00, 00, 01, 00, -1, 01, 01, + * a10 01, 00, 01, 00, 00, 00, 01, 01, + * a11 01, 01, 00, 00, 01, 00, 01, 01, + * a12 02, 00, 00, 01, 01, 00, 01, 01, + * a13 02, 00, 01, 01, 02, -1, 01, 02, + * a14 02, 01, 01, 02, 01, -1, 02, 02, + * a15 03, 01, 02, 01, 01, 00, 02, 02, + + + * Reduction chain + * The last two reduction chain can be combined into the third to last chain for calculation. + * Coefficient 7 6 5 4 3 2 1 0 + * 2 a15 a14 a15 a14 a13 0 a15 a14 + * 2 a14 0 0 0 0 0 a14 a13 + * 2 a13 0 a13 a12 a11 0 a12 a11 + * 2 a12 a11 a10 a9 0 0 a9 a8 + * 1 a15 0 0 a15 a14 0 a13 a12 + * 1 a11 0 0 0 a8 0 0 a15 + * 1 a10 0 0 0 a15 0 a11 a10 + * 1 a9 a10 a9 + * 1 a8 a15 a14 a13 a12 a15 + * -1 a14 a13 a12 a11 a13 a12 a11 + * -1 a11 a10 a9 0 a14 a9 a8 + * -1 a8 + * -1 a9 + */ +#ifdef HITLS_CRYPTO_SM2 +static int8_t ReduceSm2P256(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT list[P256SIZE]; + BN_UINT t[P256SIZE]; + + // Reduction chain 0, Coefficient 2 + list[3] = a[7]; // offset 3 a15|a14 == ah[7]|al[7] + list[2] = a[7]; // offset 2 a15|a14 == ah[7]|al[7] + list[1] = BN_UINT_HI_TO_HI(a[6]); // offset 1 a13|0 == ah[6]|0 + list[0] = a[7]; // offset 0 a15|a14 == ah[7]|al[7] + + // Reduction chain 1, Coefficient 2 + t[3] = BN_UINT_LO_TO_HI(a[7]); // offset 3 a14|0 == al[7]|0 + t[2] = 0; // offset 2 0 + t[1] = 0; // offset 1 0 + t[0] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]); // offset 0 a14|a13 = al[7]|ah[6] + int8_t carry = P256ADD(t, t, list); + + // Reduction chain 2, Coefficient 2 + list[3] = BN_UINT_HI_TO_HI(a[6]); // offset 3 a13|0 == ah[6]|0 + list[2] = a[6]; // offset 2 a13|a12 == ah[6]|al[6] + list[1] = BN_UINT_HI_TO_HI(a[5]); // offset 1 a11|0 == ah[5]|0 + list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 0 a12|a11 == al[6]|ah[5] + carry += (int8_t)P256ADD(t, t, list); + + // Reduction chain 3, Coefficient 2 + list[3] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 3 a12|a11 == al[6]|ah[5] + list[2] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]); // offset 2 a10|a9 == al[5]|ah[4] + list[1] = 0; // offset 1 0 + list[0] = a[4]; // offset 0 a9|a8 == ah[4]|al[4] + carry += (int8_t)P256ADD(t, t, list); + + // carry multiplied by 2 and padded with the most significant bit of t[3] + carry = (carry * 2) + (int8_t)(t[3] >> (BN_UINT_BITS - 1)); + t[3] = (t[3] << 1) | (t[2] >> (BN_UINT_BITS - 1)); // t[3] is shifted left by 1 bit and the MSB of t[2] is added. + t[2] = (t[2] << 1) | (t[1] >> (BN_UINT_BITS - 1)); // t[2] is shifted left by 1 bit and the MSB of t[1] is added. + t[1] = (t[1] << 1) | (t[0] >> (BN_UINT_BITS - 1)); // t[1] is shifted left by 1 bit and the MSB of t[0] is added. + t[0] <<= 1; + + // Reduction chain 4, Coefficient 1 + list[3] = BN_UINT_HI_TO_HI(a[7]); // offset 3 a15|0 == ah[7]|0 + list[2] = BN_UINT_HI(a[7]); // offset 2 0|a15 == 0|ah[7] + list[1] = BN_UINT_LO_TO_HI(a[7]); // offset 1 a14|0 == al[7]|0 + list[0] = a[6]; // offset 0 a13|a12 == ah[6]|al[6] + carry += (int8_t)P256ADD(t, t, list); + + // Reduction chain 5, Coefficient 1 + list[3] = BN_UINT_HI_TO_HI(a[5]); // offset 3 a11|0 == ah[5]|0 + list[2] = 0; // offset 2 0 + list[1] = BN_UINT_LO_TO_HI(a[4]); // offset 1 a8|0 == al[4]|0 + list[0] = BN_UINT_HI(a[7]); // offset 0 0|a15 == 0|ah[7] + carry += (int8_t)P256ADD(t, t, list); + + // Reduction chain 6, Coefficient 1 + list[3] = BN_UINT_LO_TO_HI(a[5]); // offset 3 a10|0 == al[5]|0 + list[2] = 0; // offset 2 0 + list[1] = BN_UINT_HI_TO_HI(a[7]); // offset 1 a15|0 == ah[7]|0 + list[0] = a[5]; // offset 0 a11|a10 == ah[5]|al[5] + carry += (int8_t)P256ADD(t, t, list); + + // Reduction chain 7, Coefficient 1 + list[3] = BN_UINT_HI_TO_HI(a[4]); // offset 3 a9|0 == ah[4]|0 + list[2] = 0; // offset 2 0 + list[1] = 0; // offset 1 0 + list[0] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]); // offset 0 a10|a9 == al[5]|ah[4] + carry += (int8_t)P256ADD(t, t, list); + + // Reduction chain 8, Coefficient 1 + list[3] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[7]); // offset 3 a8|a15 == al[4]|ah[7] + list[2] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]); // offset 2 a14|a13 = al[7]|ah[6] + list[1] = BN_UINT_LO_TO_HI(a[6]); // offset 1 a12|0 == al[6]|0 + list[0] = BN_UINT_HI(a[7]); // offset 0 0|a15 == 0|ah[7] + carry += (int8_t)P256ADD(t, t, list); + + // Reduction chain 9, Coefficient -1 + list[3] = BN_UINT_LO(a[7]); // offset 3 0|a14 == 0|al[7] + list[2] = a[6]; // offset 2 a13|a12 == ah[6]|al[6] + list[1] = BN_UINT_HI_TO_HI(a[5]) | BN_UINT_HI(a[6]); // offset 1 a11|a13 == ah[5]|ah[6] + list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]); // offset 0 a12|a11 == al[6]|ah[5] + carry -= (int8_t)P256SUB(t, t, list); + + // Reduction chain 10, Coefficient -1 + list[3] = BN_UINT_HI(a[5]); // offset 3 0|a11 == 0|ah[5] + list[2] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]); // offset 2 a10|a9 == al[5]|ah[4] + // offset 1 0|a14 == 0|al[7]. Add the values of the last two chains. + list[1] = BN_UINT_LO(a[7]) + BN_UINT_HI(a[4]) + BN_UINT_LO(a[4]); + list[0] = a[4]; // offset 0 a9|a8 == ah[4]|al[4] + carry -= (int8_t)P256SUB(t, t, list); + + carry += (int8_t)P256ADD(r, t, a); + return carry; +} + +// SM2_P256 curve modulo parameter P. The size of a is 2*P256SIZE, and the size of r is P256SIZE +int32_t ModSm2P256( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + (void)opt; + (void)m; + const BN_UINT *mod = MODDATASM2P256[0]; + int8_t carry = ReduceSm2P256(r->data, a->data); + if (carry < 0) { + carry = (int8_t)1 - (int8_t)P256ADD(r->data, r->data, MODDATASM2P256[-carry - 1]); + carry = -carry; + } else if (carry > 0) { + carry = (int8_t)1 - (int8_t)P256SUB(r->data, r->data, MODDATASM2P256[carry - 1]); + } + if (carry > 0 || BinCmp(r->data, P256SIZE, mod, P256SIZE) >= 0) { + P256SUB(r->data, r->data, mod); + } else if (carry < 0) { + P256ADD(r->data, r->data, mod); + } + UpdateSize(r, P256SIZE); + return 0; +} +#endif + +static uint32_t MulNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize, + const BN_UINT *b, uint32_t bSize) +{ + (void)rSize; + (void)aSize; + (void)bSize; + + MulComba4(r, a, b); + uint32_t size = P224SIZE << 1; // in 64-bit environment, P224SIZE = P256SIZE + while (size > 0) { + if (r[size - 1] != 0) { + break; + } + size--; + } + return size; +} + +static uint32_t SqrNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize) +{ + (void)rSize; + (void)aSize; + + SqrComba4(r, a); + uint32_t size = P224SIZE << 1; // in 64-bit environment, P224SIZE = P256SIZE + while (size > 0) { + if (r[size - 1] != 0) { + break; + } + size--; + } + return size; +} + +static uint32_t MulNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize, + const BN_UINT *b, uint32_t bSize) +{ + (void)rSize; + (void)aSize; + (void)bSize; + + MulComba6(r, a, b); + uint32_t size = P384SIZE << 1; + while (size > 0) { + if (r[size - 1] != 0) { + break; + } + size--; + } + return size; +} + +static uint32_t SqrNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize) +{ + (void)rSize; + (void)aSize; + + SqrComba6(r, a); + uint32_t size = P384SIZE << 1; + while (size > 0) { + if (r[size - 1] != 0) { + break; + } + size--; + } + return size; +} + +#elif defined(HITLS_THIRTY_TWO_BITS) + +int32_t ModNistP224( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + return BN_Mod(r, a, m, opt); +} + +int32_t ModNistP256( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + return BN_Mod(r, a, m, opt); +} + +#ifdef HITLS_CRYPTO_SM2 +int32_t ModSm2P256( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + return BN_Mod(r, a, m, opt); +} +#endif + +int32_t ModNistP384( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + return BN_Mod(r, a, m, opt); +} + +int32_t ModNistP521( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + return BN_Mod(r, a, m, opt); +} + +static uint32_t MulNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize, + const BN_UINT *b, uint32_t bSize) +{ + return BinMul(r, rSize, a, aSize, b, bSize); +} + +static uint32_t SqrNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize) +{ + return BinSqr(r, rSize, a, aSize); +} + +static uint32_t MulNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize, + const BN_UINT *b, uint32_t bSize) +{ + return BinMul(r, rSize, a, aSize, b, bSize); +} + +static uint32_t SqrNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize) +{ + return BinSqr(r, rSize, a, aSize); +} + +#endif // HITLS_THIRTY_TWO_BITS + +static inline int32_t ModCalParaCheck(BN_BigNum *r, const BN_BigNum *a, + const BN_BigNum *b, const BN_BigNum *mod) +{ + if (r == NULL || a == NULL || b == NULL || mod == NULL) { + return CRYPT_NULL_INPUT; + } + if ((mod->size > a->room) || (mod->size > b->room)) { + return CRYPT_BN_SPACE_NOT_ENOUGH; + } + if (BnExtend(r, mod->size) != CRYPT_SUCCESS) { + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +// The user must ensure that a < m, and a->room & b->room are not less than mod->size. +// All the data must be not negative number, otherwise the API may be not functional. +int32_t BN_ModAddQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, const BN_Optimizer *opt) +{ + int32_t ret = ModCalParaCheck(r, a, b, mod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + (void)opt; + BN_UINT carry = BinAdd(r->data, a->data, b->data, mod->size); + if (carry > 0 || BinCmp(r->data, mod->size, mod->data, mod->size) >= 0) { + BinSub(r->data, r->data, mod->data, mod->size); + } + UpdateSize(r, mod->size); + return CRYPT_SUCCESS; +} + +// The user must ensure that a < m, and a->room & b->room are not less than mod->size. +// All the data must be not negative number, otherwise the API may be not functional. +int32_t BN_ModSubQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, const BN_Optimizer *opt) +{ + int32_t ret = ModCalParaCheck(r, a, b, mod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + (void)opt; + int32_t res = BinCmp(a->data, a->size, b->data, b->size); + if (res < 0) { + /* Apply for the temporary space of the BN object. */ + BinSub(r->data, a->data, b->data, mod->size); + BinAdd(r->data, r->data, mod->data, mod->size); + } else { + BinSub(r->data, a->data, b->data, mod->size); + } + UpdateSize(r, mod->size); + return CRYPT_SUCCESS; +} + +static inline int32_t ModEccMulParaCheck(BN_BigNum *r, const BN_BigNum *a, + const BN_BigNum *b, const BN_BigNum *mod, const BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || b == NULL || mod == NULL || opt == NULL) { + return CRYPT_NULL_INPUT; + } + // Ensure that no out-of-bounds access occurs. + if ((mod->size > b->room) || (mod->size > a->room)) { + return CRYPT_BN_SPACE_NOT_ENOUGH; + } + if (BnExtend(r, mod->size) != CRYPT_SUCCESS) { + return CRYPT_MEM_ALLOC_FAIL; + } + + return CRYPT_SUCCESS; +} + +// The user must ensure that a < m, and a->room & b->room are not less than mod->size. +// All the data must be not negative number, otherwise the API may be not functional. +int32_t BN_ModNistEccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret = ModEccMulParaCheck(r, a, b, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (b->size == 0 || a->size == 0) { + return BN_Zeroize(r); + } + BN_UINT tData[P521SIZE << 1] = { 0 }; + BN_BigNum rMul = { + .data = tData, + .size = 0, + .room = P521SIZE << 1 + }; + uint32_t size = mod->size << 1; + uint32_t bits = BN_Bits(mod); + if (bits == 224) { + rMul.size = MulNistP256P224(rMul.data, size, a->data, mod->size, b->data, mod->size); + ModNistP224(r, &rMul, mod, opt); + } else if (bits == 256) { + rMul.size = MulNistP256P224(rMul.data, size, a->data, mod->size, b->data, mod->size); + ModNistP256(r, &rMul, mod, opt); + } else if (bits == 384) { + rMul.size = MulNistP384(rMul.data, size, a->data, mod->size, b->data, mod->size); + ModNistP384(r, &rMul, mod, opt); + } else if (bits == 521) { + rMul.size = BinMul(rMul.data, size, a->data, mod->size, b->data, mod->size); + ModNistP521(r, &rMul, mod, opt); + } else { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_QUICK_MODDATA); + return CRYPT_BN_ERR_QUICK_MODDATA; + } + return CRYPT_SUCCESS; +} + +static int32_t ModEccSqrParaCheck( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, const BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || mod == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // Ensure that no out-of-bounds access occurs. + if (mod->size > a->room) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH); + return CRYPT_BN_SPACE_NOT_ENOUGH; + } + if (BnExtend(r, mod->size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +// The user must ensure that a < m, and a->room & b->room are not less than mod->size. +// All the data must be not negative number, otherwise the API may be not functional. +int32_t BN_ModNistEccSqr( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret = ModEccSqrParaCheck(r, a, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (a->size == 0) { + return BN_Zeroize(r); + } + BN_UINT tData[P521SIZE << 1] = { 0 }; + BN_BigNum rSqr = { + .data = tData, + .size = 0, + .room = P521SIZE << 1 + }; + uint32_t size = mod->size << 1; + uint32_t bits = BN_Bits(mod); + if (bits == 224) { + rSqr.size = SqrNistP256P224(rSqr.data, size, a->data, mod->size); + ModNistP224(r, &rSqr, mod, opt); + } else if (bits == 256) { + rSqr.size = SqrNistP256P224(rSqr.data, size, a->data, mod->size); + ModNistP256(r, &rSqr, mod, opt); + } else if (bits == 384) { + rSqr.size = SqrNistP384(rSqr.data, size, a->data, mod->size); + ModNistP384(r, &rSqr, mod, opt); + } else if (bits == 521) { + rSqr.size = BinSqr(rSqr.data, size, a->data, mod->size); + ModNistP521(r, &rSqr, mod, opt); + } else { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_QUICK_MODDATA); + return CRYPT_BN_ERR_QUICK_MODDATA; + } + return CRYPT_SUCCESS; +} + +#ifdef HITLS_CRYPTO_SM2 +// The user must ensure that a < m, and a->room & b->room are not less than mod->size. +// All the data must be not negative number, otherwise the API may be not functional. +int32_t BN_ModSm2EccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret = ModEccMulParaCheck(r, a, b, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (a->size == 0 || b->size == 0) { + return BN_Zeroize(r); + } + BN_UINT tData[P256SIZE << 1] = { 0 }; + BN_BigNum rMul = { + .data = tData, + .size = 0, + .room = P256SIZE << 1 + }; + uint32_t size = mod->size << 1; + rMul.size = MulNistP256P224(rMul.data, size, a->data, mod->size, b->data, mod->size); + ModSm2P256(r, &rMul, mod, opt); + + return CRYPT_SUCCESS; +} + +// The user must ensure that a < m, and a->room & b->room are not less than mod->size. +// All the data must be not negative number, otherwise the API may be not functional. +int32_t BN_ModSm2EccSqr( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret = ModEccSqrParaCheck(r, a, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (a->size == 0) { + return BN_Zeroize(r); + } + BN_UINT tData[P256SIZE << 1] = { 0 }; + BN_BigNum rSqr = { + .data = tData, + .size = 0, + .room = P256SIZE << 1 + }; + uint32_t size = mod->size << 1; + rSqr.size = SqrNistP256P224(rSqr.data, size, a->data, mod->size); + ModSm2P256(r, &rSqr, mod, opt); + + return CRYPT_SUCCESS; +} +#endif +#endif diff --git a/crypto/bn/src/bn_operation.c b/crypto/bn/src/bn_operation.c new file mode 100644 index 00000000..0e94fbfd --- /dev/null +++ b/crypto/bn/src/bn_operation.c @@ -0,0 +1,836 @@ +/* + * 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 "crypt_utils.h" +#include "bn_basic.h" +#include "bn_bincal.h" +#include "bn_ucal.h" +#include "bn_optimizer.h" + +int32_t BN_Cmp(const BN_BigNum *a, const BN_BigNum *b) +{ + if (a == NULL || b == NULL) { + if (a != NULL) { + return -1; + } + if (b != NULL) { + return 1; + } + return 0; + } + if (BN_ISNEG(a->flag ^ b->flag)) { + return BN_ISNEG(a->flag) ? -1 : 1; + } + if (BN_ISNEG(a->flag)) { + return BinCmp(b->data, b->size, a->data, a->size); + } + return BinCmp(a->data, a->size, b->data, b->size); +} + +int32_t BN_Add(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b) +{ + if (r == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // Ensure that r is sufficient to carry the sum. + uint32_t aBits = BN_Bits(a); + uint32_t bBits = BN_Bits(b); + uint32_t maxbits = (aBits >= bBits) ? aBits : bBits; + uint32_t tmpFlag = 0; + if (!BN_ISNEG(a->flag ^ b->flag)) { + maxbits += 1; + } + if (BnExtend(r, BITS_TO_BN_UNIT(maxbits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (!BN_ISNEG(a->flag ^ b->flag)) { + tmpFlag = BN_GETNEG(a->flag); + UAdd(r, a, b); + goto END; + } + // compare absolute value + int32_t res = BinCmp(a->data, a->size, b->data, b->size); + if (res > 0) { + tmpFlag = BN_GETNEG(a->flag); + USub(r, a, b); + goto END; + } else if (res < 0) { + tmpFlag = BN_GETNEG(b->flag); + USub(r, b, a); + goto END; + } else { + return BN_Zeroize(r); + } +END: + BN_CLRNEG(r->flag); + r->flag |= tmpFlag; + return CRYPT_SUCCESS; +} + +int32_t BN_AddLimb(BN_BigNum *r, const BN_BigNum *a, BN_UINT w) +{ + if (r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_IsZero(a)) { + return BN_SetLimb(r, w); + } + uint32_t needBits = BN_Bits(a); + // process where the size of a is equal to 1 and the actual value of a is less than w + if (a->size == 1 && a->data[0] < w) { + needBits = BN_UINT_BITS - GetZeroBitsUint(w); + } + if (!BN_ISNEG(a->flag)) { + needBits += 1; + } + if (BnExtend(r, BITS_TO_BN_UNIT(needBits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (!BN_ISNEG(a->flag)) { // a is positive + BN_CLRNEG(r->flag); + UInc(r, a, w); + return CRYPT_SUCCESS; + } + + if (a->size == 1) { + if (a->data[0] > w) { + BN_SETNEG(r->flag); + r->data[0] = a->data[0] - w; + r->size = 1; + } else if (a->data[0] == w) { + BN_CLRNEG(r->flag); + r->data[0] = 0; + r->size = 0; + } else { + BN_CLRNEG(r->flag); + r->data[0] = w - a->data[0]; + r->size = 1; + } + return CRYPT_SUCCESS; + } + BN_SETNEG(r->flag); + UDec(r, a, w); + return CRYPT_SUCCESS; +} + +int32_t BN_Sub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b) +{ + if (r == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // Ensure that r is sufficient to carry the maximum value of the subtraction between num with different sign bits. + uint32_t aBits = BN_Bits(a); + uint32_t bBits = BN_Bits(b); + uint32_t maxbits = (aBits >= bBits) ? aBits : bBits; + uint32_t tmpFlag = 0; + if (BN_ISNEG(a->flag ^ b->flag)) { + maxbits += 1; + } + if (BnExtend(r, BITS_TO_BN_UNIT(maxbits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (BN_ISNEG(a->flag ^ b->flag)) { + tmpFlag = BN_GETNEG(a->flag); + BN_CLRNEG(r->flag); + r->flag |= tmpFlag; + UAdd(r, a, b); + return CRYPT_SUCCESS; + } + // compare absolute value + int32_t res = BinCmp(a->data, a->size, b->data, b->size); + if (res == 0) { + return BN_Zeroize(r); + } else if (res > 0) { + tmpFlag = BN_GETNEG(a->flag); + BN_CLRNEG(r->flag); + r->flag |= tmpFlag; + USub(r, a, b); + return CRYPT_SUCCESS; + } + tmpFlag = BN_GETNEG(b->flag) ^ CRYPT_BN_FLAG_ISNEGTIVE; + BN_CLRNEG(r->flag); + r->flag |= tmpFlag; + USub(r, b, a); + return CRYPT_SUCCESS; +} + +int32_t BN_SubLimb(BN_BigNum *r, const BN_BigNum *a, BN_UINT w) +{ + if (r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_IsZero(a)) { + if (BN_SetLimb(r, w) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (w == 0) { + BN_CLRNEG(r->flag); + } else { + BN_SETNEG(r->flag); + } + return CRYPT_SUCCESS; + } + uint32_t needBits = BN_Bits(a); + // process where the size of a is less than or equal to 1 and the actual value of a is less than w + if (a->size == 1 && a->data[0] < w) { + needBits = BN_UINT_BITS - GetZeroBitsUint(w); + } + if (BN_ISNEG(a->flag)) { + needBits += 1; + } + if (BnExtend(r, BITS_TO_BN_UNIT(needBits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (BN_ISNEG(a->flag)) { + BN_SETNEG(r->flag); + UInc(r, a, w); + return CRYPT_SUCCESS; + } + if (a->size == 1) { + if (a->data[0] >= w) { + r->data[0] = a->data[0] - w; + r->size = BinFixSize(r->data, 1); + } else { + BN_SETNEG(r->flag); + r->data[0] = w - a->data[0]; + r->size = 1; + } + return CRYPT_SUCCESS; + } + BN_CLRNEG(r->flag); + UDec(r, a, w); + return CRYPT_SUCCESS; +} + +int32_t BN_Mul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || b == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (BN_Bits(a) == 0 || BN_Bits(b) == 0) { + return BN_Zeroize(r); + } + uint32_t bits = BN_Bits(a) + BN_Bits(b); + if (BnExtend(r, BITS_TO_BN_UNIT(bits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + BN_BigNum *t = NULL; + if (r == a || r == b) { + int32_t ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + t = OptimizerGetBn(opt, r->room); // apply for a BN object + if (t == NULL) { + OptimizerEnd(opt); // release occupation from the optimizer + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + } else { + t = r; + } + if (BN_ISNEG(a->flag ^ b->flag)) { + BN_SETNEG(t->flag); + } else { + BN_CLRNEG(t->flag); + } + t->size = BinMul(t->data, t->room, a->data, a->size, b->data, b->size); + if (r != t) { + int32_t ret = BN_Copy(r, t); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); // release occupation from the optimizer + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + OptimizerEnd(opt); // release occupation from the optimizer + } + return CRYPT_SUCCESS; +} + +int32_t BN_Sqr(BN_BigNum *r, const BN_BigNum *a, BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t bits = BN_Bits(a) * 2; // The maximum bit required for mul is 2x that of a. + if (BnExtend(r, BITS_TO_BN_UNIT(bits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + if (a->size == 0) { + BN_Zeroize(r); + return CRYPT_SUCCESS; + } + int32_t ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // Apply for a temporary BN object. The size is 1 + twice the size of a. + BN_BigNum *t = OptimizerGetBn(opt, (a->size * 2) + 1); + if (t == NULL) { + OptimizerEnd(opt); // release occupation from the optimizer + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + t->size = BinSqr(t->data, t->room, a->data, a->size); + (void)BN_Copy(r, t); // The preceding verification has been performed. The return value can be ignored. + OptimizerEnd(opt); // release occupation from the optimizer + BN_CLRNEG(r->flag); // The square must be positive. + return CRYPT_SUCCESS; +} + +int32_t DivInputCheck(const BN_BigNum *q, const BN_BigNum *r, const BN_BigNum *x, + const BN_BigNum *y, const BN_Optimizer *opt) +{ + if (x == NULL || y == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (q == r) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + // The divisor cannot be 0. + if (BN_Bits(y) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO); + return CRYPT_BN_ERR_DIVISOR_ZERO; + } + return CRYPT_SUCCESS; +} + +// If x <= y, perform special processing. +int32_t DivSimple(BN_BigNum *q, BN_BigNum *r, const BN_BigNum *x, + const BN_BigNum *y, int32_t flag) +{ + int32_t ret = CRYPT_SUCCESS; + if (flag < 0) { + if (r != NULL) { + ret = BN_Copy(r, x); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + if (q != NULL) { + ret = BN_Zeroize(q); + } + } else { + if (q != NULL) { + uint32_t tmpFlag = BN_GETNEG(x->flag ^ y->flag); + ret = BN_SetLimb(q, 1); + if (ret != 0) { + return ret; + } + BN_CLRNEG(q->flag); + q->flag |= tmpFlag; + } + if (r != NULL) { + ret = BN_Zeroize(r); + } + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t BN_Div(BN_BigNum *q, BN_BigNum *r, const BN_BigNum *x, + const BN_BigNum *y, BN_Optimizer *opt) +{ + int32_t ret = DivInputCheck(q, r, x, y, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BinCmp(x->data, x->size, y->data, y->size); + if (ret <= 0) { // simple processing when dividend <= divisor + return DivSimple(q, r, x, y, ret); + } + + ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* Apply for temporary space for the q and r of the BN. */ + BN_BigNum *qTmp = + OptimizerGetBn(opt, x->size + 2); // BinDiv:x->room >= xSize + 2 + BN_BigNum *rTmp = + OptimizerGetBn(opt, x->size + 2); // BinDiv:x->room >= xSize + 2 + if (qTmp == NULL || rTmp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + goto ERR; + } + + ret = BN_Copy(rTmp, x); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + + qTmp->size = qTmp->room; + rTmp->size = BinDiv(qTmp->data, &(qTmp->size), rTmp->data, rTmp->size, y->data, y->size); + if (rTmp->size == 0) { + BN_CLRNEG(rTmp->flag); + } + if (qTmp->size != 0 && BN_ISNEG(x->flag ^ y->flag)) { + BN_SETNEG(qTmp->flag); + } + + if (q != NULL) { + ret = BN_Copy(q, qTmp); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + } + if (r != NULL) { + ret = BN_Copy(r, rTmp); + } +ERR: + OptimizerEnd(opt); // release occupation from the optimizer + return ret; +} + +int32_t BN_Mod(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt) +{ + // check input parameters + if (r == NULL || a == NULL || m == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (m->size == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO); + return CRYPT_BN_ERR_DIVISOR_ZERO; + } + if (BnExtend(r, m->size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *t = OptimizerGetBn(opt, m->size); + if (t == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + ret = BN_Div(NULL, t, a, m, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + OptimizerEnd(opt); + return ret; + } + // t is a positive number + if (!BN_ISNEG(t->flag)) { + ret = BN_Copy(r, t); + OptimizerEnd(opt); + return ret; + } + // When t is a negative number, the modulo operation result must be positive. + if (BN_ISNEG(m->flag)) { // m is a negative number + ret = BN_Sub(r, t, m); + } else { // m is a positive number + ret = BN_Add(r, t, m); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + OptimizerEnd(opt); + return ret; +} + +// Check the input parameters of basic operations such as modulo addition, subtraction, and multiplication. +int32_t ModBaseInputCheck(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, const BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || b == NULL || mod == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BnExtend(r, mod->size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + // mod cannot be 0 + if (BN_IsZero(mod)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO); + return CRYPT_BN_ERR_DIVISOR_ZERO; + } + + return CRYPT_SUCCESS; +} + +int32_t BN_ModSub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret; + ret = ModBaseInputCheck(r, a, b, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + return ret; + } + /* Difference: Apply for the temporary space of the BN object. */ + uint32_t subTmpSize = (a->size > b ->size) ? a->size : b->size; + BN_BigNum *t = OptimizerGetBn(opt, subTmpSize); + if (t == NULL) { + ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Sub(t, a, b); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mod(r, t, mod, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + OptimizerEnd(opt); // release occupation from the optimizer + return ret; +} + +int32_t BN_ModAdd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret; + ret = ModBaseInputCheck(r, a, b, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + return ret; + } + /* Difference: Apply for the temporary space of the BN object. */ + uint32_t addTmpSize = (a->size > b ->size) ? a->size : b->size; + BN_BigNum *t = OptimizerGetBn(opt, addTmpSize); + if (t == NULL) { + ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Add(t, a, b); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mod(r, t, mod, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + OptimizerEnd(opt); // release occupation from the optimizer + return ret; +} + +int32_t BN_ModMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt) +{ + int32_t ret; + + ret = ModBaseInputCheck(r, a, b, mod, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + return ret; + } + /* Apply for the temporary space of the BN object. */ + BN_BigNum *t = OptimizerGetBn(opt, a->size + b->size + 1); + if (t == NULL) { + ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mul(t, a, b, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mod(r, t, mod, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + OptimizerEnd(opt); // release occupation from the optimizer + return ret; +} + +int32_t BN_ModSqr( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt) +{ + bool invalidInput = (r == NULL || a == NULL || mod == NULL || opt == NULL); + if (invalidInput) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // mod cannot be 0 + if (BN_IsZero(mod)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO); + return CRYPT_BN_ERR_DIVISOR_ZERO; + } + + if (BnExtend(r, mod->size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + int32_t ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* Apply for the temporary space of the BN object. */ + BN_BigNum *t = OptimizerGetBn(opt, (a->size << 1) + 1); + if (t == NULL) { + ret = CRYPT_BN_OPTIMIZER_GET_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Sqr(t, a, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mod(r, t, mod, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + OptimizerEnd(opt); // release occupation from the optimizer + return ret; +} + +int32_t ModExpInputCheck(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, + const BN_BigNum *m, const BN_Optimizer *opt) +{ + bool invalidInput = (r == NULL || a == NULL || e == NULL || m == NULL || opt == NULL); + if (invalidInput) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // mod cannot be 0 + if (BN_IsZero(m)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO); + return CRYPT_BN_ERR_DIVISOR_ZERO; + } + // the power cannot be negative + if (BN_ISNEG(e->flag)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_EXP_NO_NEGATIVE); + return CRYPT_BN_ERR_EXP_NO_NEGATIVE; + } + if (BnExtend(r, m->size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t ModExpCore(BN_BigNum *x, BN_BigNum *y, const BN_BigNum *e, + const BN_BigNum *m, BN_Optimizer *opt) +{ + int32_t ret; + if (BN_GetBit(e, 0) == 1) { + (void)BN_Copy(x, y); // ignores the returned value, we can ensure that no error occurs when applying memory + } else { // set the value to 1 + (void)BN_SetLimb(x, 1); // ignores the returned value, we can ensure that no error occurs when applying memory + } + + uint32_t bits = BN_Bits(e); + for (uint32_t i = 1; i < bits; i++) { + ret = BN_ModSqr(y, y, m, opt); // y is a temporary variable, which is multiplied by x + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_GetBit(e, i) == 1) { + ret = BN_ModMul(x, x, y, m, opt); // x^1101 = x^1 * x^100 * x^1000 + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + } + return CRYPT_SUCCESS; +} + +static int32_t SwitchMont(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, + const BN_BigNum *m, BN_Optimizer *opt) +{ + BN_Mont *mont = BN_MontCreate(m); + if (mont == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = BN_MontExp(r, a, e, mont, opt); + BN_MontDestroy(mont); + return ret; +} + +int32_t BN_ModExp(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, + const BN_BigNum *m, BN_Optimizer *opt) +{ + int32_t ret = ModExpInputCheck(r, a, e, m, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + // When m = 1 or -1 + if (m->size == 1 && m->data[0] == 1) { + return BN_Zeroize(r); + } + if (BN_IsOdd(m) && !BN_IsNegative(m)) { + return SwitchMont(r, a, e, m, opt); + } + + ret = OptimizerStart(opt); // using the Optimizer + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + /* Apply for the temporary space of the BN object. */ + BN_BigNum *x = OptimizerGetBn(opt, m->size); + BN_BigNum *y = OptimizerGetBn(opt, m->size); + if (x == NULL || y == NULL) { + OptimizerEnd(opt); // release occupation from the optimizer + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + // step 1: Obtain the modulus once, and then determine the power and remainder. + ret = BN_Mod(y, a, m, opt); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // step2: check the power. Any number to the power of 0 is 1. (0 to the power of 0 to the power of 0) + if (BN_IsZero(e) || BN_IsOne(y)) { + OptimizerEnd(opt); + return BN_SetLimb(r, 1); + } + // step3: The remainder is 0 and the result must be 0. + if (BN_IsZero(y)) { + OptimizerEnd(opt); // release occupation from the optimizer + return BN_Zeroize(r); + } + /* Power factorization: e binary x^1101 = x^1 * x^100 * x^1000 + e Decimal x^13 = x^1 * x^4 * x^8 */ + ret = ModExpCore(x, y, e, m, opt); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Copy(r, x); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + OptimizerEnd(opt); // release occupation from the optimizer + + return ret; +} + +int32_t BN_Rshift(BN_BigNum *r, const BN_BigNum *a, uint32_t n) +{ + if (r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_Bits(a) <= n) { + return BN_Zeroize(r); + } + if (BnExtend(r, BITS_TO_BN_UNIT(BN_Bits(a) - n)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + uint32_t tmpFlag = BN_GETNEG(a->flag); + uint32_t size = BinRshift(r->data, a->data, a->size, n); + if (size < r->size) { + if (memset_s(r->data + size, (r->room - size) * sizeof(BN_UINT), 0, + (r->size - size) * sizeof(BN_UINT)) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + } + BN_CLRNEG(r->flag); + r->flag |= tmpFlag; + r->size = size; + return CRYPT_SUCCESS; +} + +// '~mask' is the mask of a and 'mask' is the mask of b. +int32_t BN_CopyWithMask(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + BN_UINT mask) +{ + if (r == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((a->room != r->room) || (b->room != r->room)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_MASKCOPY_LEN); + return CRYPT_BN_ERR_MASKCOPY_LEN; + } + BN_UINT rmask = ~mask; + uint32_t len = r->room; + BN_UINT *dst = r->data; + BN_UINT *srcA = a->data; + BN_UINT *srcB = b->data; + uint32_t tmpFlag = (mask != 0) ? (a->flag) : (b->flag); + for (uint32_t i = 0; i < len; i++) { + dst[i] = (srcA[i] & rmask) ^ (srcB[i] & mask); + } + BN_CLRNEG(r->flag); + r->flag |= BN_GETNEG(tmpFlag); + r->size = (a->size & (uint32_t)rmask) ^ (b->size & (uint32_t)mask); + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_optimizer.c b/crypto/bn/src/bn_optimizer.c new file mode 100644 index 00000000..24295f20 --- /dev/null +++ b/crypto/bn/src/bn_optimizer.c @@ -0,0 +1,145 @@ +/* + * 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 +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "bn_optimizer.h" + +static Chunk *NewChunk(void) +{ + Chunk *chunk = BSL_SAL_Malloc(sizeof(Chunk)); + if (chunk == NULL) { + return NULL; + } + memset_s(chunk, sizeof(Chunk), 0, sizeof(Chunk)); + return chunk; +} + +BN_Optimizer *BN_OptimizerCreate(void) +{ + BN_Optimizer *opt = BSL_SAL_Malloc(sizeof(BN_Optimizer)); + if (opt == NULL) { + return NULL; + } + memset_s(opt, sizeof(BN_Optimizer), 0, sizeof(BN_Optimizer)); + opt->chunk = NewChunk(); + if (opt->chunk == NULL) { + BSL_SAL_FREE(opt); + return NULL; + } + return opt; +} + +void BN_OptimizerDestroy(BN_Optimizer *opt) +{ + if (opt == NULL) { + return; + } + Chunk *head = opt->chunk; + while (head != NULL) { + for (uint32_t i = 0; i < CRYPT_OPTIMIZER_BN_NUM; i++) { + BSL_SAL_CleanseData((void *)(head->bigNums[i].data), head->bigNums[i].size * sizeof(BN_UINT)); + BSL_SAL_FREE(head->bigNums[i].data); + } + opt->chunk = opt->chunk->prev; + BSL_SAL_FREE(head); + head = opt->chunk; + } + BSL_SAL_FREE(opt); +} + +int32_t OptimizerStart(BN_Optimizer *opt) +{ + if (opt->deep != CRYPT_OPTIMIZER_MAXDEEP) { + opt->deep++; + return CRYPT_SUCCESS; + } + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_STACK_FULL); + return CRYPT_BN_OPTIMIZER_STACK_FULL; +} + +/* create a new room that has not been initialized */ +BN_BigNum *GetPresetBn(BN_Optimizer *opt) +{ + if (opt->deep == 0) { + return NULL; + } + if ((opt->used[opt->deep - 1] + 1) < opt->used[opt->deep - 1]) { + // reverse + return NULL; + } + Chunk *chunk = opt->chunk; + if (chunk->size >= CRYPT_OPTIMIZER_BN_NUM) { /* expand it if it's not enough */ + Chunk *newChunk = NewChunk(); /* create a chunk and use this chunk as the header of opt->chunk linked list */ + if (newChunk == NULL) { + return NULL; + } + newChunk->prev = chunk; + chunk = newChunk; + opt->chunk = chunk; + } + chunk->size++; + opt->used[opt->deep - 1]++; + + return &chunk->bigNums[chunk->size - 1]; +} + +static BN_BigNum *BnMake(BN_BigNum *r, uint32_t room) +{ + if (BnExtend(r, room) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + memset_s(r->data, r->room * sizeof(BN_UINT), 0, r->room * sizeof(BN_UINT)); + r->size = 0; + BN_CLRNEG(r->flag); + r->flag |= CRYPT_BN_FLAG_OPTIMIZER; + return r; +} + +/* create a BigNum and initialize to 0 */ +BN_BigNum *OptimizerGetBn(BN_Optimizer *opt, uint32_t room) +{ + BN_BigNum *tmp = GetPresetBn(opt); + if (tmp == NULL) { + return NULL; + } + return BnMake(tmp, room); +} + +void OptimizerEnd(BN_Optimizer *opt) +{ + if (opt->deep == 0) { + return; + } + opt->deep--; + uint32_t used = opt->used[opt->deep]; + opt->used[opt->deep] = 0; + Chunk *chunk = opt->chunk; + + if (chunk->size >= used) { + opt->chunk->size -= used; + return; + } + opt->chunk->size = 0; + return; +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_optimizer.h b/crypto/bn/src/bn_optimizer.h new file mode 100644 index 00000000..dc1007b4 --- /dev/null +++ b/crypto/bn/src/bn_optimizer.h @@ -0,0 +1,56 @@ +/* + * 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_OPTIMIZER_H +#define BN_OPTIMIZER_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include "bn_basic.h" + +#ifdef __cplusplus +extern "c" { +#endif + +#define CRYPT_OPTIMIZER_MAXDEEP 10 +#define CRYPT_OPTIMIZER_BN_NUM 16 + +typedef struct ChunkStruct { + uint32_t size; /** < offset of used chunk */ + BN_BigNum bigNums[CRYPT_OPTIMIZER_BN_NUM]; /** < preset BN_BigNums */ + struct ChunkStruct *prev; /** < prev optimizer node */ +} Chunk; + +struct BnOptimizer { + uint32_t deep; /* depth of stack */ + uint32_t used[CRYPT_OPTIMIZER_MAXDEEP]; /* size of the used stack */ + Chunk *chunk; /** < chunk, the last point*/ +}; + +int32_t OptimizerStart(BN_Optimizer *opt); + +/* match OptimizerStart */ +void OptimizerEnd(BN_Optimizer *opt); +/* create a BigNum and initialize to 0 */ +BN_BigNum *OptimizerGetBn(BN_Optimizer *opt, uint32_t room); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_BN + +#endif // BN_OPTIMIZER_H diff --git a/crypto/bn/src/bn_prime.c b/crypto/bn/src/bn_prime.c new file mode 100644 index 00000000..1baa73ab --- /dev/null +++ b/crypto/bn/src/bn_prime.c @@ -0,0 +1,518 @@ +/* + * 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 +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "bn_bincal.h" +#include "bn_optimizer.h" + + +// small prime number table +static BN_UINT g_primesTable[2048]; +static BN_UINT PrimeLimbGen(BN_UINT base, int32_t len) +{ + BN_UINT n = base; + int32_t i; + do { + n += 2; /* Ensure that n is an odd number by adding 2 each time. */ + for (i = 1; i < len; i++) { + if ((n % g_primesTable[i]) == 0) { + break; + } + if (i == len - 1) { // end and exit + return n; + } + } + } while (true); + return n; +} + +static void PrimeTableGen(void) +{ + static bool gen = false; + if (gen) { + return; + } + g_primesTable[0] = 2; + g_primesTable[1] = 3; + int32_t i; + for (i = 2; i < 2048; i++) { + g_primesTable[i] = PrimeLimbGen(g_primesTable[i - 1], i); + } + gen = true; +} + +// Minimum times of checking for Miller-Rabin. +// The probability of errors in a check is one quarter. After 64 rounds of check, the error rate is 2 ^ - 128. +static uint32_t MinChecks(uint32_t bits) +{ + if (bits >= 2048) { + return 128; + } + return 64; +} + +// Try division, divided by the number of prime numbers. +static uint32_t DivisorsCnt(uint32_t bits) +{ + if (bits <= 512) { + return 256; + } + if (bits <= 1024) { + return 512; + } + if (bits <= 2048) { + return 1024; + } + return 2048; +} + +/* A BigNum mod a limb, limb < (1 << (BN_UINT_BITS >> 1)) */ +static BN_UINT ModLimbHalf(const BN_BigNum *a, BN_UINT w) +{ + BN_UINT rem = 0; + uint32_t i; + for (i = a->size; i > 0; i--) { + MOD_HALF(rem, rem, a->data[i - 1], w); + } + return rem; +} + +static int32_t LimbCheck(const BN_BigNum *bn) +{ + uint32_t i; + uint32_t bits = BN_Bits(bn); + uint32_t cnt = DivisorsCnt(bits); + int32_t ret = CRYPT_SUCCESS; + + for (i = 0; i < cnt; i++) { + // Try division. Large prime numbers do not divide small prime numbers. + BN_UINT mod = ModLimbHalf(bn, g_primesTable[i]); + if (mod == 0) { + if (BN_IsLimb(bn, g_primesTable[i]) == false) { // small prime judgement + ret = CRYPT_BN_NOR_CHECK_PRIME; + } + break; + } + } + return ret; +} + +/* The random number increases by 2 each time, and added for n times, + so that it is mutually primed to all data in the prime table. */ +static int32_t FillUp(BN_BigNum *rnd, const BN_UINT *mods, uint32_t modsLen) +{ + uint32_t i; + uint32_t complete = 0; + uint32_t bits = BN_Bits(rnd); + uint32_t cnt = modsLen; + BN_UINT inc = 0; + while (complete == 0) { + for (i = 1; i < cnt; i++) { + if ((mods[i] + inc) % g_primesTable[i] == 0) { + inc += 2; + break; + } + if (i == cnt - 1) { // end and exit + complete = 1; + } + } + if (inc + 2 == 0) { // inc increases by 2 each time. Check whether the inc may overflow. + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; + } + } + int32_t ret = BN_AddLimb(rnd, rnd, inc); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // If the random number length of a prime number is incorrect, generate a new random number. + if (BN_Bits(rnd) != bits) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; + } + return CRYPT_SUCCESS; +} + +/* Generate random numbers that can be mutually primed with the data in the small prime number table. */ +static int32_t ProbablePrime(BN_BigNum *rnd, uint32_t bits, bool half, BN_Optimizer *opt) +{ + const int32_t maxCnt = 100; + int32_t tryCnt = 0; + uint32_t i; + int32_t ret; + uint32_t cnt = DivisorsCnt(bits); + ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BN_BigNum *mods = OptimizerGetBn(opt, cnt); + if (mods == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + + uint32_t top = ((half == true) ? BN_RAND_TOP_TWOBIT : BN_RAND_TOP_ONEBIT); + do { + tryCnt++; + if (tryCnt > maxCnt) { + /* If it cannot be generated after loop 100 times, a failure message is returned. */ + OptimizerEnd(opt); + /* In this case, the random number may be incorrect. Keep the error information. */ + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_GEN_PRIME); + return CRYPT_BN_NOR_GEN_PRIME; + } + // 'top' can control whether to set the most two significant bits to 1. + // RSA key generation usually focuses on this parameter to ensure the length of p*q. + ret = BN_Rand(rnd, bits, top, BN_RAND_BOTTOM_ONEBIT); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + OptimizerEnd(opt); + return ret; + } + // Random number rnd divided by the prime number in the table of small prime numbers, modulo mods. + for (i = 1; i < cnt; i++) { + mods->data[i] = ModLimbHalf(rnd, g_primesTable[i]); + } + // Check the mods and supplement the rnd. + ret = FillUp(rnd, mods->data, cnt); + if (ret != CRYPT_BN_NOR_CHECK_PRIME && ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + OptimizerEnd(opt); + return ret; + } + } while (ret == CRYPT_BN_NOR_CHECK_PRIME); + OptimizerEnd(opt); + return ret; +} + +static int32_t BnCheck(const BN_BigNum *bnSubOne, const BN_BigNum *bnSubThree, + const BN_BigNum *divisor, const BN_BigNum *rnd, const BN_Mont *mont) +{ + bool isNull = (bnSubOne == NULL || bnSubThree == NULL || divisor == NULL || rnd == NULL); + if (isNull) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + if (mont == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +static int32_t GenRnd(BN_BigNum *rnd, const BN_BigNum *bnSubThree) +{ + int32_t ret = BN_RandRange(rnd, bnSubThree); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return BN_AddLimb(rnd, rnd, 2); /* bn - 3 + 2 = bn - 1 */ +} + +static bool SumCorrect(BN_BigNum *sum, const BN_BigNum *bnSubOne) +{ + if (BN_IsOne(sum) || BN_Cmp(sum, bnSubOne) == 0) { + (void)BN_SetLimb(sum, 1); + return true; + } + return false; +} + +int32_t MillerRabinCheckCore(const BN_BigNum *bn, BN_Mont *mont, BN_BigNum *rnd, + const BN_BigNum *divisor, const BN_BigNum *bnSubOne, const BN_BigNum *bnSubThree, + uint32_t p, BN_Optimizer *opt) +{ + uint32_t i, j; + int32_t ret = CRYPT_SUCCESS; + uint32_t checks = MinChecks(BN_Bits(bn)); + BN_BigNum *sum = rnd; + for (i = 0; i < checks; i++) { + // 3.1 Generate a random number rnd, 2 < rnd < n-1 + ret = GenRnd(rnd, bnSubThree); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // 3.2 Calculate base = rnd^divisor mod bn + ret = BN_MontExp(sum, rnd, divisor, mont, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + for (j = 0; j < p; j++) { + // If sum is equal to 1 or bn-1, the modulus square result must be 1. Exit directly. + if (SumCorrect(sum, bnSubOne)) { + break; + } + ret = BN_ModSqr(sum, sum, bn, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // Inverse negation of Miller Rabin's theorem, if equal to 1, bn is not a prime number. + if (BN_IsOne(sum)) { + ret = CRYPT_BN_NOR_CHECK_PRIME; + return ret; + } + } + // 3.4 Fermat's little theorem inverse negation if sum = rnd^(bn -1) != 1 mod bn, bn is not a prime number. + if (!BN_IsOne(sum)) { + ret = CRYPT_BN_NOR_CHECK_PRIME; + return ret; + } + } + return ret; +} + +static int32_t BnSubGet(BN_BigNum *bnSubOne, BN_BigNum *bnSubThree, const BN_BigNum *bn) +{ + int32_t ret = BN_SubLimb(bnSubOne, bn, 1); /* bn - 1 */ + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_SubLimb(bnSubThree, bn, 3); /* bn - 3 */ + return ret; +} + +static int32_t PrimeLimbCheck(const BN_BigNum *bn) +{ + if (BN_IsLimb(bn, 2) || BN_IsLimb(bn, 3)) { /* 2 and 3 directly determine that the number is a prime number. */ + return CRYPT_SUCCESS; + } + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; +} + +static uint32_t GetP(const BN_BigNum *bn) +{ + uint32_t p = 0; + while (!BN_GetBit(bn, p)) { + p++; + } + return p; +} + +// CRYPT_SUCCESS is returned for a prime number, +// and CRYPT_BN_NOR_CHECK_PRIME is returned for a non-prime number. Other error codes are returned. +static int32_t MillerRabinPrimeVerify(const BN_BigNum *bn, BN_Optimizer *opt) +{ + int32_t ret = CRYPT_SUCCESS; + uint32_t p; + if (PrimeLimbCheck(bn) == CRYPT_SUCCESS) { /* 2 and 3 directly determine that the number is a prime number. */ + return CRYPT_SUCCESS; + } + if (!BN_GetBit(bn, 0)) { // even + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; + } + ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BN_BigNum *bnSubOne = OptimizerGetBn(opt, bn->size); // bnSubOne = bn - 1 + BN_BigNum *bnSubThree = OptimizerGetBn(opt, bn->size); // bnSubThree = bn - 3 + BN_BigNum *divisor = OptimizerGetBn(opt, bn->size); // divisor = bnSubOne / 2^p + BN_BigNum *rnd = OptimizerGetBn(opt, bn->size); // rnd to verify bn + BN_Mont *mont = BN_MontCreate(bn); + + ret = BnCheck(bnSubOne, bnSubThree, divisor, rnd, mont); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BnSubGet(bnSubOne, bnSubThree, bn); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // 1. Extract the power p of factor 2 in bnSubOne. + p = GetP(bnSubOne); + // 2. Number after factor 2 is extracted by bnSubOne. divisor = (bn - 1) / 2^p + ret = BN_Rshift(divisor, bnSubOne, p); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = MillerRabinCheckCore(bn, mont, rnd, divisor, bnSubOne, bnSubThree, p, opt); +ERR: + BN_MontDestroy(mont); + OptimizerEnd(opt); + return ret; +} + +// CRYPT_SUCCESS is returned for a prime number, +// and CRYPT_BN_NOR_CHECK_PRIME is returned for a non-prime number. Other error codes are returned. +int32_t BN_PrimeCheck(const BN_BigNum *bn, BN_Optimizer *opt) +{ + if (bn == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + // Check whether the value is 0 or 1. + if (BN_IsZero(bn) || BN_IsOne(bn)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; + } + // Check whether the number is negative. + if (BN_ISNEG(bn->flag)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; + } + PrimeTableGen(); // Generate a small prime number table. + ret = LimbCheck(bn); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = MillerRabinPrimeVerify(bn, opt); + return ret; +} + +static int32_t GenPrimeLimb(BN_BigNum *bn, uint32_t bits, bool half, BN_Optimizer *opt) +{ + const BN_UINT baseAll[13] = {0, 2, 4, 6, 11, 18, 31, 54, 97, 172, 309, 564, 1028}; + const BN_UINT cntAll[13] = {2, 2, 2, 5, 7, 13, 23, 43, 75, 137, 255, 464, 872}; + const BN_UINT baseHalf[13] = {1, 3, 5, 9, 15, 24, 43, 76, 135, 242, 439, 801, 1469}; + const BN_UINT cntHalf[13] = {1, 1, 1, 2, 3, 7, 11, 21, 37, 67, 125, 227, 431}; + const BN_UINT *base = baseAll; + const BN_UINT *cnt = cntAll; + if (half == true) { + base = baseHalf; + cnt = cntHalf; + } + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *bnCnt = OptimizerGetBn(opt, BITS_TO_BN_UNIT(bits)); + BN_BigNum *bnRnd = OptimizerGetBn(opt, BITS_TO_BN_UNIT(bits)); + if (bnCnt == NULL || bnRnd == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + (void)BN_SetLimb(bnCnt, cnt[bits - 2]); /* offset, the minimum bit of the interface is 2. */ + ret = BN_RandRange(bnRnd, bnCnt); + if (ret != CRYPT_SUCCESS) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_UINT rnd = bnRnd->data[0] + base[bits - 2]; /* offset, the minimum bit of the interface is 2. */ + OptimizerEnd(opt); + return BN_SetLimb(bn, g_primesTable[rnd]); +} + +static int32_t GenCheck(BN_BigNum *bn, uint32_t bits, const BN_Optimizer *opt) +{ + if (bn == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (bits < 2) { // The number of bits less than 2 can only be 0 or 1. The prime number cannot be generated. + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_CHECK_PRIME); + return CRYPT_BN_NOR_CHECK_PRIME; + } + if (BnExtend(bn, BITS_TO_BN_UNIT(bits)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +// Create a new optimizer to prevent optimizer from using too much memory. +static int32_t PrimeVerifyGenPrime(const BN_BigNum *bn) +{ + BN_Optimizer *opt = BN_OptimizerCreate(); + if (opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + int32_t ret = MillerRabinPrimeVerify(bn, opt); + BN_OptimizerDestroy(opt); + return ret; +} + +// If the prime number r is generated successfully, CRYPT_SUCCESS is returned. +// If the prime number r fails to be generated, CRYPT_BN_NOR_GEN_PRIME is returned. Other error codes are returned. +// If half is 1, the prime number whose two most significant bits are 1 is generated. +int32_t BN_GenPrime(BN_BigNum *r, uint32_t bits, bool half, BN_Optimizer *opt, BN_CbCtx *cb) +{ + int32_t time = 0; + int32_t maxTime = 256; // if cb == NULL, The maximum number of cycles is 256. + int32_t ret = GenCheck(r, bits, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + PrimeTableGen(); // Generate a small prime number table. + if (bits <= 14) { // The number within 14 bits is less than 17863 and can be obtained from the small prime table. + return GenPrimeLimb(r, bits, half, opt); + } + ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* To preventing insufficient space in addition operations when the rnd is constructed. */ + BN_BigNum *rnd = OptimizerGetBn(opt, BITS_TO_BN_UNIT(bits) + 1); + if (rnd == NULL) { + OptimizerEnd(opt); + BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_GET_FAIL); + return CRYPT_BN_OPTIMIZER_GET_FAIL; + } + do { + if (cb == NULL && maxTime == time) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_GEN_PRIME); + OptimizerEnd(opt); + return CRYPT_BN_NOR_GEN_PRIME; + } + if (BN_CbCtxCall(cb, time, 0) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_NOR_GEN_PRIME); + OptimizerEnd(opt); + return CRYPT_BN_NOR_GEN_PRIME; + } + // Generate a random number bn that may be a prime. + ret = ProbablePrime(rnd, bits, half, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + OptimizerEnd(opt); + return ret; + } + ret = PrimeVerifyGenPrime(rnd); + time++; + } while (ret != CRYPT_SUCCESS); + + OptimizerEnd(opt); + return BN_Copy(r, rnd); +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_rand.c b/crypto/bn/src/bn_rand.c new file mode 100644 index 00000000..fa6b09eb --- /dev/null +++ b/crypto/bn/src/bn_rand.c @@ -0,0 +1,172 @@ +/* + * 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 +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "bn_basic.h" +#include "bn_bincal.h" +#include "crypt_util_rand.h" + +static int32_t RandGenerate(BN_BigNum *r, uint32_t bits) +{ + int32_t ret; + uint32_t room = BITS_TO_BN_UNIT(bits); + BN_UINT mask; + uint32_t bufSize = BITS_TO_BYTES(bits); // bits < (1u << 29), hence bits + 7 will not exceed the upper limit. + uint8_t *buf = BSL_SAL_Malloc(bufSize); + if (buf == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + ret = CRYPT_Rand(buf, bufSize); + if (ret == CRYPT_NO_REGIST_RAND) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (ret != CRYPT_SUCCESS) { + ret = CRYPT_BN_RAND_GEN_FAIL; + BSL_ERR_PUSH_ERROR(CRYPT_BN_RAND_GEN_FAIL); + goto ERR; + } + ret = BN_Bin2Bn(r, buf, bufSize); + BSL_SAL_CleanseData((void *)buf, bufSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + mask = (BN_UINT)(-1) >> ((BN_UINT_BITS - bits % BN_UINT_BITS) % BN_UINT_BITS); + r->data[room - 1] &= mask; + r->size = BinFixSize(r->data, room); +ERR: + BSL_SAL_FREE(buf); + return ret; +} + +static int32_t CheckTopAndBottom(uint32_t bits, uint32_t top, uint32_t bottom) +{ + if (top > BN_RAND_TOP_TWOBIT) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_RAND_TOP_BOTTOM); + return CRYPT_BN_ERR_RAND_TOP_BOTTOM; + } + if (bottom > BN_RAND_BOTTOM_TWOBIT) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_RAND_TOP_BOTTOM); + return CRYPT_BN_ERR_RAND_TOP_BOTTOM; + } + if (top > bits || bottom > bits) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH); + return CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH; + } + return CRYPT_SUCCESS; +} + +int32_t BN_Rand(BN_BigNum *r, uint32_t bits, uint32_t top, uint32_t bottom) +{ + if (r == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = CheckTopAndBottom(bits, top, bottom); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (bits == 0) { + return BN_Zeroize(r); + } + + if (bits > BN_MAX_BITS) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_TOO_MAX); + return CRYPT_BN_BITS_TOO_MAX; + } + ret = RandGenerate(r, bits); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + r->data[0] |= (bottom == BN_RAND_BOTTOM_TWOBIT) ? 0x3 : (BN_UINT)bottom; // CheckTopAndBottom ensure that bottom>0 + if (top == BN_RAND_TOP_ONEBIT) { + BN_SetBit(r, bits - 1); + } else if (top == BN_RAND_TOP_TWOBIT) { + BN_SetBit(r, bits - 1); + BN_SetBit(r, bits - 2); /* the most significant 2 bits are 1 */ + } + r->size = BinFixSize(r->data, r->room); + return ret; +} + +static int32_t InputCheck(const BN_BigNum *r, const BN_BigNum *p) +{ + if (r == NULL || p == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (BN_IsZero(p)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_RAND_ZERO); + return CRYPT_BN_ERR_RAND_ZERO; + } + if (BN_ISNEG(p->flag)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_RAND_NEGATIVE); + return CRYPT_BN_ERR_RAND_NEGATIVE; + } + return CRYPT_SUCCESS; +} + +int32_t BN_RandRange(BN_BigNum *r, const BN_BigNum *p) +{ + const int32_t maxCnt = 100; /* try 100 times */ + int32_t tryCnt = 0; + int32_t ret; + + ret = InputCheck(r, p); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Zeroize(r); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (BN_IsOne(p)) { + return CRYPT_SUCCESS; + } + + uint32_t bits = BN_Bits(p); + do { + tryCnt++; + if (tryCnt > maxCnt) { + /* The success rate is more than 50%. */ + /* Return a failure if failed to generated after try 100 times */ + BSL_ERR_PUSH_ERROR(CRYPT_BN_RAND_GEN_FAIL); + return CRYPT_BN_RAND_GEN_FAIL; + } + ret = RandGenerate(r, bits); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } while (BinCmp(r->data, r->size, p->data, p->size) >= 0); + + return ret; +} + +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_sqrt.c b/crypto/bn/src/bn_sqrt.c new file mode 100644 index 00000000..369b0bce --- /dev/null +++ b/crypto/bn/src/bn_sqrt.c @@ -0,0 +1,376 @@ +/* + * 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 +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bn_optimizer.h" +#include "crypt_bn.h" + + +static uint32_t GetExp(const BN_BigNum *bn) +{ + uint32_t s = 0; + while (!BN_GetBit(bn, s)) { + s++; + } + return s; +} + +// p does not perform prime number check, but performs parity check. +static int32_t CheckParam(const BN_BigNum *a, const BN_BigNum *p) +{ + if (BN_IsZero(p) || BN_IsOne(p)) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_SQRT_PARA); + return CRYPT_BN_ERR_SQRT_PARA; + } + if (!BN_GetBit(p, 0)) { // p must be odd prime + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_SQRT_PARA); + return CRYPT_BN_ERR_SQRT_PARA; + } + if (BN_ISNEG(p->flag | a->flag)) { // p, a must be positive + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_SQRT_PARA); + return CRYPT_BN_ERR_SQRT_PARA; + } + if (BN_Cmp(p, a) <= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_SQRT_PARA); + return CRYPT_BN_ERR_SQRT_PARA; + } + return CRYPT_SUCCESS; +} + +// r = +- a^((p + 1)/4) +static int32_t CalculationRoot(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, + BN_Mont *mont, BN_Optimizer *opt) +{ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *temp = OptimizerGetBn(opt, p->size); + if (temp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + GOTO_ERR_IF_EX(BN_AddLimb(temp, p, 1), ret); // p + 1 + GOTO_ERR_IF_EX(BN_Rshift(temp, temp, 2), ret); // (p + 1) / 4 = (p + 1) >> 2 + GOTO_ERR_IF(BN_MontExp(r, a, temp, mont, opt), ret); +ERR: + OptimizerEnd(opt); + return ret; +} + +static int32_t LegendreFastTempDataCheck(const BN_BigNum *a, const BN_BigNum *pp) +{ + if (a == NULL || pp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t LegendreFast(BN_BigNum *z, const BN_BigNum *p, int32_t *legendre, BN_Optimizer *opt) +{ + int32_t l = 1; + BN_BigNum *temp = NULL; + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *a = OptimizerGetBn(opt, p->size); // The variable has been checked for NULL in BN_Copy. + BN_BigNum *pp = OptimizerGetBn(opt, p->size); + GOTO_ERR_IF(LegendreFastTempDataCheck(a, pp), ret); + if (BN_IsOne(z)) { + *legendre = 1; + goto ERR; + } + if (BN_IsZero(z)) { + *legendre = 0; + goto ERR; + } + GOTO_ERR_IF_EX(BN_Copy(a, z), ret); + GOTO_ERR_IF_EX(BN_Copy(pp, p), ret); + while (true) { + if (BN_IsZero(a)) { + *legendre = BN_IsOne(pp) ? l : 0; + break; + } + // Theorem: p is an odd prime number, a and b are numbers that are not divisible by p. (a|p)(b|p) = (ab|p) + // a = aa * 2^exp + // (a|pp) = (2|pp)^exp * (aa|pp) + // If exp is an even number, (a|pp) = (aa|pp) + uint32_t exp = GetExp(a); + GOTO_ERR_IF_EX(BN_Rshift(a, a, exp), ret); + if ((exp & 1) != 0) { + // pp = +- 1 mod 8, 2 is its quadratic remainder. pp = +-3 mod 8, 2 is its non-quadric remainder. + if ((pp->data[0] & 1) != 0) { + // pp->data[0] % 8 = pp->data[0] & 7 + // pp = +- 1 mod 8 = 7 or 1 mod + l = ((pp->data[0] & 7) == 1 || (pp->data[0] & 7) == 7) ? l : -l; + } else { + l = 0; + } + } + // pp->data[0] % 4 = pp->data[0] & 3 + // K(a|pp) = K(pp|a) * (-1)^((a-1)*(pp-1)/4) + // (a-1)*(pp-1)/4 is an even number only when at least one of A and P mod 4 = 1; + // if both A and P mod 4 = 3, (a-1)*(pp-1)/4 is an odd number. + if (((pp->data[0] & 3) == 3) && ((a->data[0] & 3) == 3)) { + l = -l; + } + // K(pp|a) = K(pp%a|a), swap(a,pp) + GOTO_ERR_IF_EX(BN_Div(NULL, pp, pp, a, opt), ret); + temp = a; + a = pp; + pp = temp; + } + ret = CRYPT_SUCCESS; +ERR: + OptimizerEnd(opt); + return ret; +} + +// Find z so that legendre(z / p) = z^((p-1)/2) mod p != 1 +static int32_t GetLegendreZ(BN_BigNum *z, const BN_BigNum *p, BN_Optimizer *opt) +{ + uint32_t maxCnt = 50; // A random number can be generated cyclically for a maximum of 50 times. + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + int32_t legendre; + BN_BigNum *exp = OptimizerGetBn(opt, p->size); // exp = (p - 1) / 2 + if (exp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + GOTO_ERR_IF_EX(BN_SubLimb(exp, p, 1), ret); + GOTO_ERR_IF_EX(BN_Rshift(exp, exp, 1), ret); + + while (maxCnt > 0) { + GOTO_ERR_IF_EX(BN_RandRange(z, p), ret); + + maxCnt--; + if (BN_IsZero(z)) { + continue; + } + + GOTO_ERR_IF_EX(LegendreFast(z, p, &legendre, opt), ret); + if (legendre == -1) { + ret = CRYPT_SUCCESS; + goto ERR; + } + } + ret = CRYPT_BN_ERR_LEGENDE_DATA; +ERR: + OptimizerEnd(opt); + return ret; +} + +static int32_t SetParaR( + BN_BigNum *r, BN_BigNum *q, const BN_BigNum *a, BN_Mont *mont, BN_Optimizer *opt) +{ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *temp = OptimizerGetBn(opt, q->size); + if (temp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + GOTO_ERR_IF_EX(BN_AddLimb(temp, q, 1), ret); // q + 1 + GOTO_ERR_IF_EX(BN_Rshift(temp, temp, 1), ret); // (p + 1) / 2 + GOTO_ERR_IF(BN_MontExp(r, a, temp, mont, opt), ret); // r = a^((q+1)/2) mod p +ERR: + OptimizerEnd(opt); + return ret; +} + +static int32_t TonelliShanksCalculation(BN_BigNum *r, BN_BigNum *c, BN_BigNum *t, + uint32_t s, const BN_BigNum *p, BN_Optimizer *opt) +{ + uint32_t m = s; + uint32_t i, j; + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *b = OptimizerGetBn(opt, p->size); + BN_BigNum *tempT = OptimizerGetBn(opt, p->size); + if (b == NULL || tempT == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + while (!BN_IsOne(t)) { + // Find an i (0 < i < s) so that t^(2^i) = 1 + i = 1; + // repeat modulus square + GOTO_ERR_IF_EX(BN_ModSqr(tempT, t, p, opt), ret); + while (!BN_IsOne(tempT)) { + i++; + if (i >= m) { + ret = CRYPT_BN_ERR_NO_SQUARE_ROOT; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF_EX(BN_ModSqr(tempT, tempT, p, opt), ret); + } + + // b = c^(2^(m-i-1)), if m-i-1 == 0, b = c + GOTO_ERR_IF_EX(BN_Copy(b, c), ret); + for (j = m - i - 1; j > 0; j--) { + GOTO_ERR_IF_EX(BN_ModSqr(b, b, p, opt), ret); + } + GOTO_ERR_IF_EX(BN_ModMul(r, r, b, p, opt), ret); // r = r * b + GOTO_ERR_IF_EX(BN_ModSqr(c, b, p, opt), ret); // c = b*b + GOTO_ERR_IF_EX(BN_ModMul(t, t, c, p, opt), ret); // t = t * b * b = t * c + m = i; + } + ret = CRYPT_SUCCESS; +ERR: + OptimizerEnd(opt); + return ret; +} + +static int32_t SqrtVerify( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt) +{ + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_BigNum *square = OptimizerGetBn(opt, p->size); + if (square == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + + GOTO_ERR_IF_EX(BN_ModSqr(square, r, p, opt), ret); + + if (BN_Cmp(square, a) != 0) { + ret = CRYPT_BN_ERR_NO_SQUARE_ROOT; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR: + OptimizerEnd(opt); + return ret; +} + +static int32_t BN_ModSqrtTempDataCheck(const BN_BigNum *pSubOne, const BN_BigNum *q, + const BN_BigNum *z, const BN_BigNum *c, const BN_BigNum *t) +{ + if (pSubOne == NULL || q == NULL || z == NULL || c == NULL || t == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +/* 1. Input parameters a and p. p is an odd prime number, and a is an integer (0 <= a <= p-1) +2. For P-1 processing, let p-1 = q * 2^s +3. If s=1, r = a^((p + 1)/4) +4. Randomly select z (1<= z <= p-1) so that the Legendre symbol of z to p equals -1. (z, p) = 1, (z/p) = a^((p-1)/2) +5. Setting c = z^q, r = a^((q+1)/2), t = a^q, m = s +6. Circulation + 1) If t = 1, return r. + 2) Find an i (0 < i < m) so that t^(2^i) = 1. + 3) b = c^(2^(m-i-1)), r = r * b, t = t*b*b, c = b*b, m = i +7. Verification */ +int32_t BN_ModSqrt( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt) +{ + if (r == NULL || a == NULL || p == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = OptimizerStart(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t s = 0; + BN_Mont *mont = NULL; + BN_BigNum *pSubOne = OptimizerGetBn(opt, p->size); + BN_BigNum *q = OptimizerGetBn(opt, p->size); + BN_BigNum *z = OptimizerGetBn(opt, p->size); + BN_BigNum *c = OptimizerGetBn(opt, p->size); + BN_BigNum *t = OptimizerGetBn(opt, p->size); + GOTO_ERR_IF(BN_ModSqrtTempDataCheck(pSubOne, q, z, c, t), ret); + + GOTO_ERR_IF_EX(CheckParam(a, p), ret); + + if (BN_IsZero(a) || BN_IsOne(a)) { + GOTO_ERR_IF_EX(BN_Copy(r, a), ret); + goto VERIFY; + } + + mont = BN_MontCreate(p); + if (mont == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF_EX(BN_SubLimb(pSubOne, p, 1), ret); + + s = GetExp(pSubOne); // Obtains the power s of factor 2 in p-1. + GOTO_ERR_IF_EX(BN_Rshift(q, pSubOne, s), ret); // p - 1 = q * 2^s + if (s == 1) { + // s==1, r = +- n^((p + 1)/4) + GOTO_ERR_IF_EX(CalculationRoot(r, a, p, mont, opt), ret); + goto VERIFY; + } + // Randomly select z(1<= z <= p-1), so that the Legendre symbol of z to p equals -1. (z, p) = 1, (z/p) = a^((p-1)/2) + GOTO_ERR_IF(GetLegendreZ(z, p, opt), ret); + + GOTO_ERR_IF(BN_MontExp(c, z, q, mont, opt), ret); // c = z^q mod p + GOTO_ERR_IF(BN_MontExp(t, a, q, mont, opt), ret); // t = a^q mod p + GOTO_ERR_IF_EX(SetParaR(r, q, a, mont, opt), ret); // r = a^((q+1)/2) mod p + + // Circulation + // 1) If t = 1, return r. + // 2) Find an i (0 < i < m) so that t^(2^i) = 1 + // 3) b = c^(2^(m-i-1)), r = r * b, t = t*b*b, c = b*b, m = i + GOTO_ERR_IF_EX(TonelliShanksCalculation(r, c, t, s, p, opt), ret); + +VERIFY: + GOTO_ERR_IF_EX(SqrtVerify(r, a, p, opt), ret); + +ERR: + OptimizerEnd(opt); + BN_MontDestroy(mont); + return ret; +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_ucal.c b/crypto/bn/src/bn_ucal.c new file mode 100644 index 00000000..7992b001 --- /dev/null +++ b/crypto/bn/src/bn_ucal.c @@ -0,0 +1,103 @@ +/* + * 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 "bn_bincal.h" + +/* the user should guaranteed a.size >= b.size */ +void USub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b) +{ + uint32_t maxSize = a->size; + uint32_t minSize = b->size; + + BN_UINT *rr = r->data; + const BN_UINT *aa = a->data; + const BN_UINT *bb = b->data; + + BN_UINT borrow = BinSub(rr, aa, bb, minSize); + rr += minSize; + aa += minSize; + + uint32_t diff = maxSize - minSize; + while (diff > 0) { + BN_UINT t = *aa; + aa++; + *rr = t - borrow; + rr++; + borrow = t < borrow; + diff--; + } + while (maxSize != 0) { + rr--; + if (*rr != 0) { + break; + } + maxSize--; + } + r->size = maxSize; +} + +void UInc(BN_BigNum *r, const BN_BigNum *a, BN_UINT w) +{ + uint32_t size = a->size; + + BN_UINT carry = BinInc(r->data, a->data, size, w); + if (carry != 0) { + r->data[size++] = carry; + } + r->size = size; +} + +void UDec(BN_BigNum *r, const BN_BigNum *a, BN_UINT w) +{ + uint32_t size = a->size; + + // the user should guaranteed size > 1, the return value must be 0 thus the return value is ignored + (void)BinDec(r->data, a->data, size, w); + r->size = BinFixSize(r->data, size); +} + +void UAdd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b) +{ + const BN_BigNum *max = (a->size < b->size) ? b : a; + const BN_BigNum *min = (a->size < b->size) ? a : b; + uint32_t maxSize = max->size; + uint32_t minSize = min->size; + + r->size = maxSize; + BN_UINT *rr = r->data; + const BN_UINT *aa = max->data; + const BN_UINT *bb = min->data; + + BN_UINT carry = BinAdd(rr, aa, bb, minSize); + rr += minSize; + aa += minSize; + + uint32_t diff = maxSize - minSize; + while (diff > 0) { + ADD_AB(carry, *rr, *aa, carry); + aa++, rr++, diff--; + } + if (carry != 0) { + *rr = carry; + r->size += 1; + } + (void)memset_s(r->data + r->size, (r->room - r->size) * sizeof(BN_UINT), 0, + (r->room - r->size) * sizeof(BN_UINT)); +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/bn_ucal.h b/crypto/bn/src/bn_ucal.h new file mode 100644 index 00000000..dae1e41a --- /dev/null +++ b/crypto/bn/src/bn_ucal.h @@ -0,0 +1,46 @@ +/* + * 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_UCAL_H +#define BN_UCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include "bn_basic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* unsigned BigNum subtraction, caution: The input parameter validity must be ensured during external invoking. */ +void USub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b); + +/* unsigned BigNum sub fraction, caution: The input parameter validity must be ensured during external invoking. */ +void UInc(BN_BigNum *r, const BN_BigNum *a, BN_UINT w); + +/* unsigned BigNum add fraction, caution: The input parameter validity must be ensured during external invoking. */ +void UDec(BN_BigNum *r, const BN_BigNum *a, BN_UINT w); + +/* unsigned BigNum addition, caution: The input parameter validity must be ensured during external invoking. */ +void UAdd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_BN + +#endif // BN_UCAL_H diff --git a/crypto/bn/src/bn_utils.c b/crypto/bn/src/bn_utils.c new file mode 100644 index 00000000..faa6f12e --- /dev/null +++ b/crypto/bn/src/bn_utils.c @@ -0,0 +1,257 @@ +/* + * 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_err_internal.h" +#include "crypt_errno.h" +#include "bn_basic.h" +#include "bn_bincal.h" +#include "bsl_sal.h" + +#define BITS_OF_NUM 4 +#define BITS_OF_BYTE 8 + +int32_t BN_Bin2Bn(BN_BigNum *r, const uint8_t *bin, uint32_t binLen) +{ + if (r == NULL || bin == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)BN_Zeroize(r); + uint32_t zeroNum = 0; + for (; zeroNum < binLen; zeroNum++) { + if (bin[zeroNum] != 0) { + break; + } + } + if (zeroNum == binLen) { + // All data is 0. + return CRYPT_SUCCESS; + } + const uint8_t *base = bin + zeroNum; + uint32_t left = binLen - zeroNum; + uint32_t needRooms = (left % sizeof(BN_UINT) == 0) ? left / sizeof(BN_UINT) + : (left / sizeof(BN_UINT)) + 1; + if (BnExtend(r, needRooms) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + uint32_t offset = 0; + while (left > 0) { + BN_UINT num = 0; // single number + uint32_t m = (left >= sizeof(BN_UINT)) ? sizeof(BN_UINT) : left; + uint32_t i; + for (i = m; i > 0; i--) { // big-endian + num = (num << 8) | base[left - i]; + } + r->data[offset++] = num; + left -= m; + } + r->size = BinFixSize(r->data, offset); + return CRYPT_SUCCESS; +} + +/* convert BN_UINT to bin */ +static inline void Limb2Bin(uint8_t *bin, BN_UINT num) +{ + // convert BN_UINT to bin: buff[0] is the most significant bit. + uint32_t i; + for (i = 0; i < sizeof(BN_UINT); i++) { // big-endian + bin[sizeof(BN_UINT) - i - 1] = (uint8_t)(num >> (8 * i)); + } +} + +int32_t BN_Bn2Bin(const BN_BigNum *a, uint8_t *bin, uint32_t *binLen) +{ + if (a == NULL || bin == NULL || binLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t bytes = BN_Bytes(a); + bytes = (bytes == 0) ? 1 : bytes; // If bytes is 0, 1 byte 0 data needs to be output. + if (*binLen < bytes) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + return CRYPT_BN_BUFF_LEN_NOT_ENOUGH; + } + int32_t ret = BN_Bn2BinFixZero(a, bin, bytes); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *binLen = bytes; + return ret; +} + +// Padded 0s before bin to obtain the output data whose length is binLen. +int32_t BN_Bn2BinFixZero(const BN_BigNum *a, uint8_t *bin, uint32_t binLen) +{ + if (a == NULL || bin == NULL || binLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t bytes = BN_Bytes(a); + if (binLen < bytes) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + return CRYPT_BN_BUFF_LEN_NOT_ENOUGH; + } + uint32_t fixLen = binLen - bytes; + uint8_t *base = bin + fixLen; + (void)memset_s(bin, binLen, 0, fixLen); + if (bytes == 0) { + return CRYPT_SUCCESS; + } + + uint32_t index = a->size - 1; + uint32_t left = bytes % sizeof(BN_UINT); // High-order non-integrated data + uint32_t offset = 0; + while (left != 0) { + base[offset] = (uint8_t)((a->data[index] >> (8 * (left - 1))) & 0xFF); // 1byte = 8bit + left--; + offset++; + } + if (offset != 0) { + index--; + } + uint32_t num = bytes / sizeof(BN_UINT); // High-order non-integrated data + + // Cyclically parse the entire data block. + for (uint32_t i = 0; i < num; i++) { + Limb2Bin(base + offset, a->data[index]); + index--; + offset += sizeof(BN_UINT); + } + + return CRYPT_SUCCESS; +} + +/* Convert BigNum to a 64-bit array in little-endian order. */ +int32_t BN_Bn2U64Array(const BN_BigNum *a, uint64_t *array, uint32_t *len) +{ + if (a == NULL || array == NULL || len == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // Number of BN_UINTs that can be accommodated + const uint64_t capacity = ((uint64_t)(*len)) * (sizeof(uint64_t) / sizeof(BN_UINT)); + if (a->size > capacity || *len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH); + return CRYPT_BN_SPACE_NOT_ENOUGH; + } + if (BN_IsZero(a)) { + *len = 1; + array[0] = 0; + return CRYPT_SUCCESS; + } + // BN_UINT is 64-bit or 32-bit. Select one during compilation. + if (sizeof(BN_UINT) == sizeof(uint64_t)) { + uint32_t i = 0; + for (; i < a->size; i++) { + array[i] = a->data[i]; + } + *len = i; + } + if (sizeof(BN_UINT) == sizeof(uint32_t)) { + uint32_t i = 0; + uint32_t j = 0; + for (; i < a->size - 1; i += 2) { // processes 2 BN_UINT each time. Here, a->size >= 1 + array[j] = a->data[i]; + array[j] |= ((uint64_t)a->data[i + 1]) << 32; // in the upper 32 bits + j++; + } + // When a->size is an odd number, process the tail. + if (i < a->size) { + array[j++] = a->data[i]; + } + *len = j; + } + return CRYPT_SUCCESS; +} + +/* Convert a 64-bit array in little-endian order to a BigNum. */ +int32_t BN_U64Array2Bn(BN_BigNum *r, const uint64_t *array, uint32_t len) +{ + const uint64_t needRoom = ((uint64_t)len) * sizeof(uint64_t) / sizeof(BN_UINT); + if (r == NULL || array == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (needRoom > UINT32_MAX) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_TOO_MAX); + return CRYPT_BN_BITS_TOO_MAX; + } + if (BnExtend(r, (uint32_t)needRoom) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + (void)BN_Zeroize(r); + // BN_UINT is 64-bit or 32-bit. Select one during compilation. + if (sizeof(BN_UINT) == sizeof(uint64_t)) { + for (uint32_t i = 0; i < needRoom; i++) { + r->data[i] = array[i]; + } + } + if (sizeof(BN_UINT) == sizeof(uint32_t)) { + for (uint64_t i = 0; i < len; i++) { + r->data[i * 2] = (BN_UINT)array[i]; // uint64_t is twice the width of uint32_t. + // obtain the upper 32 bits, uint64_t is twice the width of uint32_t. + r->data[i * 2 + 1] = (BN_UINT)(array[i] >> 32); + } + } + // can be forcibly converted to 32 bits because needRoom <= r->room + r->size = BinFixSize(r->data, (uint32_t)needRoom); + return CRYPT_SUCCESS; +} + +int32_t BN_BN2Array(const BN_BigNum *src, BN_UINT *dst, uint32_t size) +{ + if (src == NULL || dst == NULL || size == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (size < src->size) { + BSL_ERR_PUSH_ERROR(CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + return CRYPT_BN_BUFF_LEN_NOT_ENOUGH; + } + + (void)memset_s(dst, size * sizeof(BN_UINT), 0, size * sizeof(BN_UINT)); + for (uint32_t i = 0; i < src->size; i++) { + dst[i] = src->data[i]; + } + return CRYPT_SUCCESS; +} + +int32_t BN_Array2BN(BN_BigNum *dst, const BN_UINT *src, const uint32_t size) +{ + if (dst == NULL || src == NULL || size == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BnExtend(dst, size) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + // No error code is returned because the src has been checked NULL. + (void)BN_Zeroize(dst); + for (uint32_t i = 0; i < size; i++) { + dst->data[i] = src[i]; + } + dst->size = BinFixSize(dst->data, size); + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/bn/src/noasm_bn_mont.c b/crypto/bn/src/noasm_bn_mont.c new file mode 100644 index 00000000..75099e5d --- /dev/null +++ b/crypto/bn/src/noasm_bn_mont.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_BN + +#include +#include +#include "bn_bincal.h" + +/* reduce(r * r) */ +int32_t MontSqrBin(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime) +{ + return MontSqrBinCore(r, mont, opt, consttime); +} + +int32_t MontMulBin(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, BN_Mont *mont, + BN_Optimizer *opt, bool consttime) +{ + return MontMulBinCore(r, a, b, mont, opt, consttime); +} + +int32_t MontEncBin(BN_UINT *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime) +{ + return MontEncBinCore(r, mont, opt, consttime); +} + +void Reduce(BN_UINT *r, BN_UINT *x, const BN_UINT *m, uint32_t mSize, BN_UINT m0) +{ + ReduceCore(r, x, m, mSize, m0); +} +#endif /* HITLS_CRYPTO_BN */ diff --git a/crypto/chacha20/include/crypt_chacha20.h b/crypto/chacha20/include/crypt_chacha20.h new file mode 100644 index 00000000..374c40bc --- /dev/null +++ b/crypto/chacha20/include/crypt_chacha20.h @@ -0,0 +1,58 @@ +/* + * 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_CHACHA20_H +#define CRYPT_CHACHA20_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CHACHA20 + +#include +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define CHACHA20_STATESIZE 16 +#define CHACHA20_STATEBYTES (CHACHA20_STATESIZE * sizeof(uint32_t)) +#define CHACHA20_KEYLEN 32 +#define CHACHA20_NONCELEN 12 + +typedef struct { + uint32_t state[CHACHA20_STATESIZE]; // state RFC 7539 + union { + uint32_t c[CHACHA20_STATESIZE]; + uint8_t u[CHACHA20_STATEBYTES]; + } last; // save the last data + uint32_t lastLen; // remaining length of the last data in bytes + uint8_t set; // indicates whether the key and nonce are set +} CRYPT_CHACHA20_Ctx; + +int32_t CRYPT_CHACHA20_SetKey(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *key, uint32_t keyLen); + +int32_t CRYPT_CHACHA20_Update(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *in, + uint8_t *out, uint32_t len); + +int32_t CRYPT_CHACHA20_Ctrl(CRYPT_CHACHA20_Ctx *ctx, CRYPT_CipherCtrl opt, + void *val, uint32_t len); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CHACHA20 + +#endif // CRYPT_CHACHA20_H diff --git a/crypto/chacha20/src/chacha20.c b/crypto/chacha20/src/chacha20.c new file mode 100644 index 00000000..94195670 --- /dev/null +++ b/crypto/chacha20/src/chacha20.c @@ -0,0 +1,245 @@ +/* + * 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_CHACHA20 + +#include "bsl_err_internal.h" +#include "securec.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_chacha20.h" +#include "chacha20_local.h" + + +#define KEYSET 0x01 +#define NONCESET 0x02 + +// RFC7539-2.1 +#define QUARTER(a, b, c, d) \ + do { \ + (a) += (b); (d) ^= (a); (d) = ROTL32((d), 16); \ + (c) += (d); (b) ^= (c); (b) = ROTL32((b), 12); \ + (a) += (b); (d) ^= (a); (d) = ROTL32((d), 8); \ + (c) += (d); (b) ^= (c); (b) = ROTL32((b), 7); \ + } while (0) + +#define QUARTERROUND(state, a, b, c, d) QUARTER((state)[(a)], (state)[(b)], (state)[(c)], (state)[(d)]) + +int32_t CRYPT_CHACHA20_SetKey(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *key, uint32_t keyLen) +{ + if (ctx == NULL || key == NULL || keyLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (keyLen != CHACHA20_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CHACHA20_KEYLEN_ERROR); + return CRYPT_CHACHA20_KEYLEN_ERROR; + } + /** + * RFC7539-2.3 + * cccccccc cccccccc cccccccc cccccccc + * kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk + * kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk + * bbbbbbbb nnnnnnnn nnnnnnnn nnnnnnnn + */ + // The first four words (0-3) are constants: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + ctx->state[0] = 0x61707865; + ctx->state[1] = 0x3320646e; + ctx->state[2] = 0x79622d32; + ctx->state[3] = 0x6b206574; + /** + * The next eight words (4-11) are taken from the 256-bit key by + * reading the bytes in little-endian order, in 4-byte chunks. + */ + ctx->state[4] = GET_UINT32_LE(key, 0); + ctx->state[5] = GET_UINT32_LE(key, 4); + ctx->state[6] = GET_UINT32_LE(key, 8); + ctx->state[7] = GET_UINT32_LE(key, 12); + ctx->state[8] = GET_UINT32_LE(key, 16); + ctx->state[9] = GET_UINT32_LE(key, 20); + ctx->state[10] = GET_UINT32_LE(key, 24); + ctx->state[11] = GET_UINT32_LE(key, 28); + // Word 12 is a block counter + // RFC7539-2.4: It makes sense to use one if we use the zero block + ctx->state[12] = 1; + ctx->set |= KEYSET; + ctx->lastLen = 0; + return CRYPT_SUCCESS; +} + +static int32_t CRYPT_CHACHA20_SetNonce(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *nonce, uint32_t nonceLen) +{ + // RFC7539-2.3 + if (ctx == NULL || nonce == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (nonceLen != CHACHA20_NONCELEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CHACHA20_NONCELEN_ERROR); + return CRYPT_CHACHA20_NONCELEN_ERROR; + } + /** + * Words 13-15 are a nonce, which should not be repeated for the same + * key. The 13th word is the first 32 bits of the input nonce taken + * as a little-endian integer, while the 15th word is the last 32 + * bits. + */ + ctx->state[13] = GET_UINT32_LE(nonce, 0); + ctx->state[14] = GET_UINT32_LE(nonce, 4); + ctx->state[15] = GET_UINT32_LE(nonce, 8); + ctx->set |= NONCESET; + ctx->lastLen = 0; + return CRYPT_SUCCESS; +} + +// Little-endian data input +static int32_t CRYPT_CHACHA20_SetCount(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *cnt, uint32_t cntLen) +{ + if (ctx == NULL || cnt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (cntLen != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_CHACHA20_COUNTLEN_ERROR); + return CRYPT_CHACHA20_COUNTLEN_ERROR; + } + /** + * RFC7539-2.4 + * This can be set to any number, but will + * usually be zero or one. It makes sense to use one if we use the + * zero block for something else, such as generating a one-time + * authenticator key as part of an AEAD algorithm + */ + ctx->state[12] = GET_UINT32_LE((uintptr_t)cnt, 0); + ctx->lastLen = 0; + return CRYPT_SUCCESS; +} + +void CHACHA20_Block(CRYPT_CHACHA20_Ctx *ctx) +{ + uint32_t i; + // The length defined by ctx->last.c is the same as that defined by ctx->state. + // Therefore, the returned value is not out of range. + (void)memcpy_s(ctx->last.c, CHACHA20_STATEBYTES, ctx->state, sizeof(ctx->state)); + /* RFC7539-2.3 These are 20 round in this function */ + for (i = 0; i < 10; i++) { + /* column round */ + QUARTERROUND(ctx->last.c, 0, 4, 8, 12); + QUARTERROUND(ctx->last.c, 1, 5, 9, 13); + QUARTERROUND(ctx->last.c, 2, 6, 10, 14); + QUARTERROUND(ctx->last.c, 3, 7, 11, 15); + /* diagonal round */ + QUARTERROUND(ctx->last.c, 0, 5, 10, 15); + QUARTERROUND(ctx->last.c, 1, 6, 11, 12); + QUARTERROUND(ctx->last.c, 2, 7, 8, 13); + QUARTERROUND(ctx->last.c, 3, 4, 9, 14); + } + /* Reference from rfc 7539, At the end of 20 rounds (or 10 iterations of the above list), + * we add the original input words to the output words + */ + for (i = 0; i < CHACHA20_STATESIZE; i++) { + ctx->last.c[i] += ctx->state[i]; + } + ctx->last.c[0] = CRYPT_HTOLE32(ctx->last.c[0]); + ctx->last.c[1] = CRYPT_HTOLE32(ctx->last.c[1]); + ctx->last.c[2] = CRYPT_HTOLE32(ctx->last.c[2]); + ctx->last.c[3] = CRYPT_HTOLE32(ctx->last.c[3]); + ctx->last.c[4] = CRYPT_HTOLE32(ctx->last.c[4]); + ctx->last.c[5] = CRYPT_HTOLE32(ctx->last.c[5]); + ctx->last.c[6] = CRYPT_HTOLE32(ctx->last.c[6]); + ctx->last.c[7] = CRYPT_HTOLE32(ctx->last.c[7]); + ctx->last.c[8] = CRYPT_HTOLE32(ctx->last.c[8]); + ctx->last.c[9] = CRYPT_HTOLE32(ctx->last.c[9]); + ctx->last.c[10] = CRYPT_HTOLE32(ctx->last.c[10]); + ctx->last.c[11] = CRYPT_HTOLE32(ctx->last.c[11]); + ctx->last.c[12] = CRYPT_HTOLE32(ctx->last.c[12]); + ctx->last.c[13] = CRYPT_HTOLE32(ctx->last.c[13]); + ctx->last.c[14] = CRYPT_HTOLE32(ctx->last.c[14]); + ctx->last.c[15] = CRYPT_HTOLE32(ctx->last.c[15]); + ctx->state[12]++; +} + +int32_t CRYPT_CHACHA20_Update(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *in, + uint8_t *out, uint32_t len) +{ + if (ctx == NULL || out == NULL || in == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((ctx->set & KEYSET) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CHACHA20_NO_KEYINFO); + return CRYPT_CHACHA20_NO_KEYINFO; + } + if ((ctx->set & NONCESET) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CHACHA20_NO_NONCEINFO); + return CRYPT_CHACHA20_NO_NONCEINFO; + } + uint32_t i; + const uint8_t *offIn = in; + uint8_t *offOut = out; + uint32_t tLen = len; + if (ctx->lastLen != 0) { // has remaining data during the last processing + uint32_t num = (tLen < ctx->lastLen) ? tLen : ctx->lastLen; + uint8_t *tLast = ctx->last.u + CHACHA20_STATEBYTES - ctx->lastLen; // offset + for (i = 0; i < num; i++) { + offOut[i] = tLast[i] ^ offIn[i]; + } + offIn += num; + offOut += num; + tLen -= num; + ctx->lastLen -= num; + } + if (tLen >= CHACHA20_STATEBYTES) { // which is greater than or equal to an integer multiple of 64 bytes + CHACHA20_Update(ctx, offIn, offOut, tLen); // processes data that is an integer multiple of 64 bytes + uint32_t vLen = tLen - (tLen & 0x3f); // 0x3f = %CHACHA20_STATEBYTES + offIn += vLen; + offOut += vLen; + tLen -= vLen; + } + // Process the remaining data + if (tLen > 0) { + CHACHA20_Block(ctx); + uint32_t t = tLen & 0xf8; // processing length is a multiple of 8 + if (t != 0) { + DATA64_XOR(ctx->last.u, offIn, offOut, t); + } + for (i = t; i < tLen; i++) { + offOut[i] = ctx->last.u[i] ^ offIn[i]; + } + ctx->lastLen = CHACHA20_STATEBYTES - tLen; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CHACHA20_Ctrl(CRYPT_CHACHA20_Ctx *ctx, CRYPT_CipherCtrl opt, + void *val, uint32_t len) +{ + switch (opt) { + case CRYPT_CTRL_SET_IV: // in chacha20_poly1305 mode, the configured IV is the nonce of chacha20. + /** + * RFC_7539-2.8.1 + * chacha20_aead_encrypt(aad, key, iv, constant, plaintext): + * nonce = constant | iv + */ + return CRYPT_CHACHA20_SetNonce(ctx, val, len); + case CRYPT_CTRL_SET_COUNT: + return CRYPT_CHACHA20_SetCount(ctx, val, len); + default: + BSL_ERR_PUSH_ERROR(CRYPT_CHACHA20_CTRLTYPE_ERROR); + return CRYPT_CHACHA20_CTRLTYPE_ERROR; + } +} +#endif // HITLS_CRYPTO_CHACHA20 diff --git a/crypto/chacha20/src/chacha20_local.h b/crypto/chacha20/src/chacha20_local.h new file mode 100644 index 00000000..c5215d5c --- /dev/null +++ b/crypto/chacha20/src/chacha20_local.h @@ -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. + */ + +#ifndef CHACHA20_LOCAL_H +#define CHACHA20_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CHACHA20 + +#include "crypt_chacha20.h" + +void CHACHA20_Block(CRYPT_CHACHA20_Ctx *ctx); + +void CHACHA20_Update(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *in, + uint8_t *out, uint32_t len); + +#endif // HITLS_CRYPTO_CHACHA20 + +#endif // CHACHA20_LOCAL_H diff --git a/crypto/chacha20/src/chacha20block.c b/crypto/chacha20/src/chacha20block.c new file mode 100644 index 00000000..44a55cad --- /dev/null +++ b/crypto/chacha20/src/chacha20block.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CHACHA20 + +#include "crypt_utils.h" +#include "chacha20_local.h" + +void CHACHA20_Update(CRYPT_CHACHA20_Ctx *ctx, const uint8_t *in, + uint8_t *out, uint32_t len) +{ + const uint8_t *offIn = in; + uint8_t *offOut = out; + uint32_t tLen = len; + // one block is processed each time + while (tLen >= CHACHA20_STATEBYTES) { + CHACHA20_Block(ctx); + // Process 64 bits at a time + DATA64_XOR(ctx->last.u, offIn, offOut, CHACHA20_STATEBYTES); + offIn += CHACHA20_STATEBYTES; + offOut += CHACHA20_STATEBYTES; + tLen -= CHACHA20_STATEBYTES; + } +} +#endif // HITLS_CRYPTO_CHACHA20 diff --git a/crypto/curve25519/include/crypt_curve25519.h b/crypto/curve25519/include/crypt_curve25519.h new file mode 100644 index 00000000..aa59988d --- /dev/null +++ b/crypto/curve25519/include/crypt_curve25519.h @@ -0,0 +1,272 @@ +/* + * 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_CURVE25519_H +#define CRYPT_CURVE25519_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CURVE25519 + +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CRYPT_CURVE25519_KEYLEN 32 +#define CRYPT_CURVE25519_SIGNLEN 64 + +typedef struct CryptCurve25519Ctx CRYPT_CURVE25519_Ctx; + +/** + * @ingroup curve25519 + * @brief curve25519 Create a key pair structure and allocate memory space. + * + * @retval (CRYPT_CURVE25519_Ctx *) Pointer to the key pair structure + * @retval NULL Invalid null pointer + */ +CRYPT_CURVE25519_Ctx *CRYPT_CURVE25519_NewCtx(void); + +/** + * @ingroup curve25519 + * @brief Copy the curve25519 context. The memory management of the return value is handed over to the caller. + * + * @param ctx [IN] Source curve25519 context. The CTX is set NULL by the invoker. + * + * @return CRYPT_CURVE25519_Ctx curve25519 Context pointer + * If the operation fails, null is returned. + */ +CRYPT_CURVE25519_Ctx *CRYPT_CURVE25519_DupCtx(CRYPT_CURVE25519_Ctx *ctx); + +/** + * @ingroup curve25519 + * @brief Clear the curve25519 key pair data and releases memory. + * + * @param pkey [IN] curve25519 Key pair structure. The pkey is set NULL by the invoker. + */ +void CRYPT_CURVE25519_FreeCtx(CRYPT_CURVE25519_Ctx *pkey); + +/** + * @ingroup curve25519 + * @brief curve25519 Control interface + * + * @param pkey [IN/OUT] curve25519 Key pair structure + * @param val [IN] Hash method, which must be SHA512. + * @param opt [IN] Operation mode + * @param len [IN] val length + * + * @retval CRYPT_SUCCESS set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval CRYPT_CURVE25519_UNSUPPORTED_CTRL_OPTION The opt mode is not supported. + * @retval CRYPT_CURVE25519_HASH_METH_ERROR The hash method is not SHA512 + */ +int32_t CRYPT_CURVE25519_Ctrl(CRYPT_CURVE25519_Ctx *pkey, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +/** + * @ingroup curve25519 + * @brief curve25519 Set the public key. + * + * @param pkey [IN] curve25519 Key pair structure + * @param pub [IN] Public key + * + * @retval CRYPT_SUCCESS set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval CRYPT_CURVE25519_KEYLEN_ERROR pubKeyLen is not equal to curve25519 public key length + */ +int32_t CRYPT_CURVE25519_SetPubKey(CRYPT_CURVE25519_Ctx *pkey, const CRYPT_Curve25519Pub *pub); + +/** + * @ingroup curve25519 +* @brief curve25519 Obtain the public key. + * + * @param pkey [IN] curve25519 Key pair structure + * @param pub [OUT] Public key + * + * @retval CRYPT_SUCCESS set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval CRYPT_CURVE25519_NO_PUBKEY The key pair has no public key. + * @retval CRYPT_CURVE25519_KEYLEN_ERROR pubKeyLen is less than curve25519 public key length. + */ +int32_t CRYPT_CURVE25519_GetPubKey(const CRYPT_CURVE25519_Ctx *pkey, CRYPT_Curve25519Pub *pub); + +/** + * @ingroup curve25519 + * @brief curve25519 Set the private key. + * + * @param pkey [IN] curve25519 Key pair structure + * @param prv [IN] Private key + * + * @retval CRYPT_SUCCESS set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval CRYPT_CURVE25519_KEYLEN_ERROR prvKeyLen is not equal to curve25519 private key length + */ +int32_t CRYPT_CURVE25519_SetPrvKey(CRYPT_CURVE25519_Ctx *pkey, const CRYPT_Curve25519Prv *prv); + +/** + * @ingroup curve25519 +* @brief curve25519 Obtain the private key. + * + * @param pkey [IN] curve25519 Key pair structure + * @param prv [OUT] private key + * + * @retval CRYPT_SUCCESS successfully set. + * @retval CRYPT_NULL_INPUT Any input parameter is empty. + * @retval CRYPT_CURVE25519_NO_PRVKEY The key pair has no private key. + * @retval CRYPT_CURVE25519_KEYLEN_ERROR prvKeyLen is less than the private key length of curve25519. + */ +int32_t CRYPT_CURVE25519_GetPrvKey(const CRYPT_CURVE25519_Ctx *pkey, CRYPT_Curve25519Prv *prv); + +/** + * @ingroup curve25519 + * @brief curve25519 Obtain the key length, in bits. + * + * @param pkey [IN] curve25519 Key pair structure + * + * @retval Key length + */ +int32_t CRYPT_CURVE25519_GetBits(const CRYPT_CURVE25519_Ctx *pkey); + +#ifdef HITLS_CRYPTO_ED25519 +/** + * @ingroup curve25519 + * @brief curve25519 Sign + * + * @param pkey [IN/OUT] curve25519 Key pair structure. A private key is required for signature. + * After signature, a public key is generated. + * @param msg [IN] Data to be signed + * @param msgLen [IN] Data length: 0 <= msgLen <= (2^125 - 64) bytes + * @param hashMethod [IN] SHA512 method + * @param sign [OUT] Signature + * @param signLen [IN/OUT] Length of the signature buffer (must be greater than 64 bytes)/Length of the signature + * + * @retval CRYPT_SUCCESS generated successfully. + * @retval CRYPT_CURVE25519_NO_PRVKEY The key pair has no private key. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval Error code of the hash module. An error occurs in the sha512 operation. + * @retval CRYPT_CURVE25519_NO_HASH_METHOD No hash method is set. + * @retval CRYPT_CURVE25519_SIGNLEN_ERROR signLen is less than the signature length of curve25519. + */ +int32_t CRYPT_CURVE25519_Sign(CRYPT_CURVE25519_Ctx *pkey, const uint8_t *msg, + uint32_t msgLen, uint8_t *sign, uint32_t *signLen); + +/** + * @ingroup curve25519 + * @brief curve25519 Obtain the signature length, in bytes. + * + * @param pkey [IN] curve25519 Key pair structure + * + * @retval Signature length + */ +int32_t CRYPT_CURVE25519_GetSignLen(const CRYPT_CURVE25519_Ctx *pkey); + +/** + * @ingroup curve25519 + * @brief curve25519 Verification + * + * @param pkey [IN] curve25519 Key pair structure. A public key is required for signature verification. + * @param msg [IN] Data + * @param msgLen [IN] Data length: 0 <= msgLen <= (2^125 - 64) bytes + * @param sign [IN] Signature + * @param signLen [IN] Signature length, which must be 64 bytes + * + * @retval CRYPT_SUCCESS The signature verification is successful. + * @retval CRYPT_CURVE25519_NO_PUBKEY The key pair has no public key. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval Error code of the hash module. An error occurs in the sha512 operation. + * @retval CRYPT_CURVE25519_VERIFY_FAIL Failed to verify the signature. + * @retval CRYPT_CURVE25519_INVALID_PUBKEY Invalid public key. + * @retval CRYPT_CURVE25519_SIGNLEN_ERROR signLen is not equal to curve25519 signature length + * @retval CRYPT_CURVE25519_NO_HASH_METHOD No hash method is set. + */ +int32_t CRYPT_CURVE25519_Verify(const CRYPT_CURVE25519_Ctx *pkey, const uint8_t *msg, + uint32_t msgLen, const uint8_t *sign, uint32_t signLen); + +/** + * @ingroup curve25519 + * @brief ed25519 Generate a key pair (public and private keys). + * + * @param pkey [IN/OUT] curve25519 Key pair structure/Key pair structure containing public and private keys + * + * @retval CRYPT_SUCCESS generated successfully. + * @retval CRYPT_NO_REGIST_RAND Unregistered random number + * @retval Error code of the hash module. An error occurs during the SHA512 operation. + * @retval Error code of the registered random number module. Failed to obtain the random number. + * @retval CRYPT_CURVE25519_NO_HASH_METHOD No hash method is set. + * @retval CRYPT_NULL_INPUT The input parameter is empty. + */ +int32_t CRYPT_ED25519_GenKey(CRYPT_CURVE25519_Ctx *pkey); +#endif + +#ifdef HITLS_CRYPTO_X25519 +/** + * @ingroup curve25519 + * @brief x25519 Calculate the shared key based on the private key of the local end and the public key of the peer end. + * + * @param prvKey [IN] curve25519 Key pair structure, local private key + * @param pubKey [IN] curve25519 Key pair structure, peer public key + * @param sharedKey [OUT] Shared key + * @param shareKeyLen [IN/OUT] Shared key length + * + * @retval CRYPT_SUCCESS generated successfully. + * @retval CRYPT_CURVE25519_KEY_COMPUTE_FAILED Failed to generate the shared key. + */ +int32_t CRYPT_CURVE25519_ComputeSharedKey(CRYPT_CURVE25519_Ctx *prvKey, CRYPT_CURVE25519_Ctx *pubKey, + uint8_t *sharedKey, uint32_t *shareKeyLen); + +/** + * @ingroup curve25519 + * @brief x25519 Generate a key pair (public and private keys). + * + * @param pkey [IN/OUT] curve25519 Key pair structure/Key pair structure containing public and private keys + * + * @retval CRYPT_SUCCESS generated successfully. + * @retval CRYPT_NO_REGIST_RAND Unregistered random number callback + * @retval Error code of the registered random number module. Failed to obtain the random number. + * @retval CRYPT_NULL_INPUT The input parameter is empty. + */ +int32_t CRYPT_X25519_GenKey(CRYPT_CURVE25519_Ctx *pkey); +#endif /* HITLS_CRYPTO_X25519 */ + +/** + * @ingroup curve25519 + * @brief curve25519 Public key comparison + * + * @param a [IN] curve25519 Context structure + * @param b [IN] curve25519 Context structure + * + * @retval CRYPT_SUCCESS is the same + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_CURVE25519_PUBKEY_NOT_EQUAL Public Keys are not equal + */ +int32_t CRYPT_CURVE25519_Cmp(const CRYPT_CURVE25519_Ctx *a, const CRYPT_CURVE25519_Ctx *b); + +/** + * @ingroup curve25519 + * @brief curve25519 get security bits + * + * @param ctx [IN] curve25519 Context structure + * + * @retval security bits + */ +int32_t CRYPT_CURVE25519_GetSecBits(const CRYPT_CURVE25519_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_CURVE25519 + +#endif // CRYPT_CURVE25519_H diff --git a/crypto/curve25519/src/asm/x25519_armv8.S b/crypto/curve25519/src/asm/x25519_armv8.S new file mode 100644 index 00000000..89987c31 --- /dev/null +++ b/crypto/curve25519/src/asm/x25519_armv8.S @@ -0,0 +1,433 @@ +/* + * 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_X25519 + +.file "x25519_armv8.S" +.text + +.macro push_stack + /* 保存寄存器,以下寄存器需要由被调用者保存,并在函数退出时恢复 */ + stp x19, x20, [sp, #-16]! + stp x21, x22, [sp, #-16]! + sub sp, sp, #32 +.endm + +.macro pop_stack + add sp, sp, #32 + /* 恢复寄存器 */ + ldp x21, x22, [sp], #16 + ldp x19, x20, [sp], #16 +.endm + +.macro u64mul oper1, oper2 + mul x19, \oper1, \oper2 + umulh x2, \oper1, \oper2 +.endm + +.macro u51mul cur, low, high + u64mul x3, \cur + adds \low, \low, x19 + adc \high, \high, x2 +.endm + +.macro reduce + /* 保留最后 51 位 */ + mov x8, #0x7ffffffffffff + + /* 计算 h2' */ + mov x3, x9 + lsr x9, x9, #51 // carry(h2-low) + lsl x10, x10, #13 // (h2-high) << 13 + + /* 计算 h0' */ + mov x1, x4 + lsr x4, x4, #51 // carry(h1-low) + lsl x5, x5, #13 // (h1-high) << 13 + + /* 计算 h2' */ + and x3, x3, x8 // h2' = rax = h2 & (2^51 - 1) = r12 & (2^51 - 1) 清空h2-low的高13位 - x3 + orr x10, x10, x9 // r13 = (h2 >> 51) h2的carry:h2-low的高13位 +->h2-high + adds x11, x11, x10 // h3 += (h2 >> 51) h2-high +->h3-low + adc x12, x12, XZR // h3-high 进位 + + /* 计算 h0' */ + and x1, x1, x8 // h0' = rsi = h0 & (2^51 - 1) = r8 & (2^51 - 1) 清空h0-low的高13位 -x1 + orr x5, x5, x4 // r9 = (h0 >> 51) 计算h0-high + adds x6, x6, x5 // h1 += (h0 >> 51) h0-high +->h1-low + adc x7, x7, XZR // h1-high 进位 + + /* 计算 h3' */ + mov x4, x11 // h3-low -> x4 + lsr x11, x11, #51 // h3->low >> 51 + lsl x12, x12, #13 // h3-high << 13 + and x4, x4, x8 // h3' = r8 = h3 & (2^51 - 1) = r14 & (2^51 - 1) 清空h3-low的高13位 -x4 + orr x12, x12, x11 // r15 = (h3 >> 51) 计算h3-high + adds x13, x13, x12 // h4 += (h3 >> 51) h3-high +->h4-low + adc x14, x14, XZR // h4-high 进位 + + /* 计算 h1' */ + mov x2, x6 // h1-low -> x2 + lsr x6, x6, #51 // h1->low >> 51 + lsl x7, x7, #13 // h1-high << 13 + and x2, x2, x8 // h1' = rdx = h1 & (2^51 - 1) = r10 & (2^51 - 1) 清空h1-low的高13位 -x2 + orr x7, x7, x6 // r11 = (h1 >> 51) 计算h1-high + adds x3, x3, x7 // h2 += (h1 >> 51) h1-high +->h2-low + + /* 计算 h4' */ + mov x5, x13 // h4-low -> x5 + lsr x13, x13, #51 // h4->low >> 51 + lsl x14, x14, #13 // h4-high << 13 + and x5, x5, x8 // h4' = r9 = h4 & (2^51 - 1) = rbx & (2^51 - 1) 清空h4-low的高13位 -x5 + orr x14, x14, x13 // rcx = (h4 >> 51) 计算h4-high + + /* out[0] = out[0] + 19 * carry */ + lsl x6, x14, #3 + adds x6, x6, x14 // h4-high * 8 + h4-high -> x6 (9 * h4-high) + adds x14, x14, x6, lsl #1 // x6 *2 + x14 => x6 --- h4-high * 9 * 2 + h4-high + adds x1, x1, x14 // h4-high * 19 +->h0-low + + /* h2 剩余 */ + mov x6, x3 // h2-low -> x6 + and x3, x8, x3 // h2 &= (2^51 - 1) 清空h2-low的高13位 - x3 + lsr x6, x6, #51 // h2-low << 51 (进位) + adds x4, x4, x6 // h2-low << 51 -> h3-low + + /* out[1] += out[0] >> 51 */ + mov x6, x1 // h0-low -> x6 + + /* out[0] &= (2^51 - 1) */ + and x1, x1, x8 // 清空h0-low的高13位 + lsr x6, x6, #51 // h0-low << 51 (进位) + adds x2, x2, x6 // h0-low << 51 -> h1-low + + /* 存储结果 */ + str x1, [x0] // h0' + str x2, [x0, #8] // h1' + str x3, [x0, #16] // h2' + str x4, [x0, #24] // h3' + str x5, [x0, #32] // h4' +.endm + +############################################################# +# void Fp51Mul (Fp51 *out, const Fp51 *f, const Fp51 *g); +############################################################# + +.globl Fp51Mul +.type Fp51Mul, @function +.align 6 +Fp51Mul: +.cfi_startproc + /* 保存寄存器 */ + push_stack + + /* 出入参由寄存器 x0, x1, x2 传递 + * x0: out; x1: f; x2: g; fp51 是 [u64; 5] 的数组 + * x2 在后续计算中会被覆盖,所以需要预先 load x2 中数据 + */ + ldr x3, [x1] // f0 + ldr x13, [x2] // g0 + ldp x11, x12, [x2, #8] // g1, g2, 存储 g0-g3,将 g3 存储在不受影响的寄存器 + ldp x15, x14, [x2, #24] // g3, g4 + + /* 存储 out 指针,解放 x0, 使得 x0 在后续计算可以使用,存储 19 * g4 */ + str x0, [sp, #24] + /* x13, x11, x12 在后续计算都会被覆盖,存储 g0 - g2,为了性能,存储 + * 动作将会散布在计算代码中 + */ + mov x8, #19 + /* h0 = f0g0 + 19f1g4 + 19f2g3 + 19f3g2 + 19f4g1; 存储于 x4(low), x5(high)*/ + mul x4, x3, x13 // (x4, x5) = f0 * g0 + umulh x5, x3, x13 + str x13, [sp, #16] // g0 + + /* h1 = f0g1 + f1g0 + 19f2g4 + 19f3g3 + 19f4g2; 存储于 x6, x7 */ + mul x6, x3, x11 // (x6, x7) = f0 * g1 + umulh x7, x3, x11 + lsl x13, x14, #3 + add x13, x13, x14 // g4 * 8 + g4 = g4 * 9 + str x11, [sp, #8] // g1 + + /* h2 = f0g2 + f1g1 + f2g0 + 19f3g4 + 19f4g3; 存储于 x9, x10 */ + mul x9, x3, x12 // (x9, x10) = f0 * g2 + umulh x10, x3, x12 + lsl x0, x13, #1 + add x0, x0, x14 // rdi = 2 * (9 * g4) + g4, 在 rcx 被覆盖之前,将 19 * g4 存储至 rdi + str x12, [sp] // g2 + + /* h3 = f0g3 + f1g2 + f2g1 + f3g0 + 19f4g4; 存储于 x11, x12 */ + mul x11, x3, x15 // (x11, x12) = f0 * g3 + umulh x12, x3, x15 + + /* h4 = f0g4 + f1g3 + f2g2 + f3g1 + f4g0; 存储于 x13, x14 */ + mul x13, x3, x14 // (x13, x14) = f0 * g4 + umulh x14, x3, x14 + ldr x3, [x1, #8] // f1 + + /* 计算 19 * g4 相关 */ + u51mul x0, x4, x5 // (x4, x5) = 19 * f1 * g4; load f2 + ldr x3, [x1, #16] + u51mul x0, x6, x7 // (x6, x7) = 19 * f2 * g4; load f3 + ldr x3, [x1, #24] + u51mul x0, x9, x10 // (x9, x10) = 19 * f3 * g4; load f4 + ldr x3, [x1, #32] + u51mul x0, x11, x12 // (x11, x12) = 19 * f3 * g4; load f4 + ldr x3, [x1, #8] + mul x0, x15, x8 // 19 * g3 + + /* 计算 g3 相关 */ + u64mul x3, x15 // (x13, x14) = f1 * g3 + ldr x15, [sp] // g2 + adds x13, x13, x19 + ldr x3, [x1, #16] // f2 + adc x14, x14, x2 + + u51mul x0, x4, x5 // (x4, x5) = 19 * f2 * g3; load f3 + ldr x3, [x1, #24] + u51mul x0, x6, x7 // (x6, x7) = 19 * f3 * g3; load f4 + ldr x3, [x1, #32] + + u64mul x3, x0 // (rax, rdx) = 19 * f4 * g3 + mul x0, x15, x8 // 19 * g2 + adds x9, x9, x19 + ldr x3, [x1, #8] // f1 + adc x10, x10, x2 + + /* 计算 g2 相关 */ + u51mul x15, x11, x12 // (x11, x12) = f1 * g2; load f2 + ldr x3, [x1, #16] + + u64mul x3, x15 // (rax, rdx) = f2 * g2 + ldr x15, [sp, #8] // g1 + adds x13, x13, x19 + ldr x3, [x1, #24] // f3 + adc x14, x14, x2 + + u51mul x0, x4, x5 // (x4, x5) = 19 * f3 * g2; load f4 + ldr x3, [x1, #32] + u51mul x0, x6, x7 // (x6, x7) = 19 * f4 * g2; load f2 + ldr x3, [x1, #8] + + /* 计算 g1 相关 */ + u64mul x3, x15 // (x19, x2) = f1 * g1 + mul x0, x15, x8 // 19 * g1 + adds x9, x9, x19 + ldr x3, [x1, #16] // f2 + adc x10, x10, x2 + + u51mul x15, x11, x12 // (x11, x12) += f2 * g1; load f3 + ldr x3, [x1, #24] + + u64mul x3, x15 // (x19, x2) = f3 * g1 + ldr x15, [sp, #16] // g0 + adds x13, x13, x19 + ldr x3, [x1, #32] // f4 + adc x14, x14, x2 + + u51mul x0, x4, x5 // (x4, x5) += 19 * f4 * g1; load f1 + ldr x3, [x1, #8] + + /* 计算 g0 相关 */ + u51mul x15, x6, x7 // (x6, x7) += f1 * g0; load f2 + ldr x3, [x1, #16] + u51mul x15, x9, x10 // (x9, x10) += f2 * g0; load f3 + ldr x3, [x1, #24] + u51mul x15, x11, x12 // (x11, x12) = f3 * g0; load f4 + ldr x3, [x1, #32] + + u64mul x3, x15 // (x13, x14) += f4 * g0 + adds x13, x13, x19 + adc x14, x14, x2 + + /* 恢复栈指针 */ + ldr x0, [sp, #24] + + reduce + + /* 恢复寄存器 */ + pop_stack + ret +.cfi_endproc +.size Fp51Mul,.-Fp51Mul + +############################################################# +# void Fp51Square(Fp51 *out, const Fp51 *f); +############################################################# + +.globl Fp51Square +.type Fp51Square, @function +.align 6 +Fp51Square: +.cfi_startproc + /* 保存寄存器 */ + push_stack + + /* 出入参由寄存器 x0, x1 传递 + * x0: out; x1: f; fp51 是 [u64; 5] 的数组 + * 只加载其中不相邻的数据,空出寄存器用于存储计算 + */ + + ldr x3, [x1] // f0 + ldr x12, [x1, #16] // f2 + ldr x14, [x1, #32] // f4 + mov x8, #19 + /* 开栈,存储以下必要内容,和 Fp51Mul 保持一致 + * 存储 out 指针,解放 rdi,使得 rdi 在后续计算可以使用,存储 19 * f4 + */ + lsl x2, x3, #1 // 2 * f0 + str x0, [sp, #24] + + /* h0 = f0^2 + 38f1f4 + 38f2f3; 存储于 x4, x5 */ + mul x4, x3, x3 // (x4, x5) = f0^2 + umulh x5, x3, x3 + ldr x3, [x1, #8] // f1 + + /* h1 = 19f3^2 + 2f0f1 + 38f2g4; 存储于 x6, x7 */ + mul x6, x3, x2 // (x6, x7) = 2f0 * f1 + umulh x7, x3, x2 + str x12, [sp, #16] // 存储 f2 + + /* h2 = f1^2 + 2f0f2 + 38f3g4; 存储于 x9, x10 */ + mul x9, x12, x2 // (x9, x10) = 2f0 * f2 + umulh x10, x12, x2 + ldr x3, [x1, #24] // f3 + + mul x0, x14, x8 // 19 * f4 + + /* h3 = 19f4^2 + 2f0f3 + 2f1f2; 存储于 r14, r15 */ + mul x11, x3, x2 // (x11, x12) = 2f0 * f3 + umulh x12, x3, x2 + mov x3, x14 // f4 + + /* h4 = f2^2 + 2f0f4 + 2f1f3; 存储于 x13, x14 */ + mul x13, x3, x2 // (x13, x14) = 2f0 * f4 + umulh x14, x3, x2 + + /* 计算 19 * f4 相关 + * h3 + */ + u51mul x0, x11, x12 // (x11, x12) += 19 * f4^2; load f1 + ldr x3, [x1, #8] + + /* 计算 f1 相关 + * h2 + */ + lsl x15, x3, #1 // 2 * f1 + u51mul x3, x9, x10 // (x9, x10) += f1^2; load f2 + ldr x3, [sp, #16] + + /* h3 */ + u51mul x15, x11, x12 // (x11, x12) += 2 * f1 * f2; load f3 + ldr x3, [x1, #24] + + /* h4 */ + u51mul x15, x13, x14 // (x13, x14) = 2 * f1 * f3; load 2 * f1 + mov x3, x15 + + ldr x1, [x1, #24] // f3 + mul x15, x1, x8 // 19 * f3 + + /* h0 */ + u64mul x3, x0 + lsl x3, x1, #1 // 2 * f3 + adds x4, x4, x19 // (x4, x5) += 2 * f1 * 19 * f4 + adc x5, x5, x2 + + /* 计算 f3 相关 + * h2 + */ + u51mul x0, x9, x10 // (x9, x10) += f3 * 2 * 19 * f4; load f3 + mov x3, x1 + /* h1 */ + u51mul x15, x6, x7 // (x6, x7) += 19 * f3 * f3; load f2 + ldr x3, [sp, #16] + + /* 计算 f2 相关 + * h4 + */ + lsl x1, x3, #1 // 2 * f2 + u51mul x3, x13, x14 // (x13, x14) += f2 * f2; load 19 * f3 + mov x3, x15 + /* h0 */ + u51mul x1, x4, x5 // (x4, x5) = 2 * f2 * 19 * f3; load 2 * f2 + mov x3, x1 + /* h1 */ + u64mul x3, x0 // (x6, x7) += 2 * f2 * 19 * f4 + adds x6, x19, x6 + adc x7, x2, x7 + + /* 恢复寄存器 */ + ldr x0, [sp, #24] + + reduce + + /* 恢复寄存器 */ + pop_stack + ret +.cfi_endproc +.size Fp51Square,.-Fp51Square + +############################################################# +# void Fp51MulScalar(Fp51 *out, const Fp51 *in); +############################################################# + +.globl Fp51MulScalar +.type Fp51MulScalar, @function +.align 6 +Fp51MulScalar: +.cfi_startproc + /* 出入参由寄存器 x0, x1 传递 + * x0: out; x1: in; fp51 是 [u64; 5] 的数组 + * 开栈,和 Fp51Mul 保持一致 + */ + + /* mov 121666 */ + mov x3, #0xDB42 + movk x3, #0x1, lsl #16 + + /* ldr f0, f1 */ + ldp x2, x8, [x1] + + /* h0 */ + mul x4, x2, x3 // f0 * 121666 + umulh x5, x2, x3 + + /* h1 */ + mul x6, x8, x3 // f1 * 121666 + umulh x7, x8, x3 + + /* ldr f2, f3 */ + ldp x2, x8, [x1, #16] + /* h2 */ + mul x9, x2, x3 // f2 * 121666 + umulh x10, x2, x3 + + /* h3 */ + mul x11, x8, x3 // f3 * 121666 + umulh x12, x8, x3 + + /* ldr f4 */ + ldr x8, [x1, #32] + /* h4 */ + mul x13, x3, x8 // f4 * 121666 + umulh x14, x3, x8 + + reduce + ret +.cfi_endproc +.size Fp51MulScalar,.-Fp51MulScalar + +#endif diff --git a/crypto/curve25519/src/asm/x25519_x86_64.S b/crypto/curve25519/src/asm/x25519_x86_64.S new file mode 100644 index 00000000..01e38d48 --- /dev/null +++ b/crypto/curve25519/src/asm/x25519_x86_64.S @@ -0,0 +1,450 @@ +/* + * 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_X25519 + +.file "x25519_x86_64.S" +.text + +.macro push_stack + /* Save register. The following registers need to be saved by the caller and restored when the function exits. */ + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + /* Allocate stack space and store the following necessary content: */ + leaq -32(%rsp), %rsp +.endm + +.macro pop_stack + /* Recovery register */ + movq 32(%rsp),%r15 + movq 40(%rsp),%r14 + movq 48(%rsp),%r13 + movq 56(%rsp),%r12 + movq 64(%rsp),%rbp + movq 72(%rsp),%rbx + + /* Restore stack pointer. The stack is opened with 32 bytes and 6 registers are restored. + The total number is 80 bytes. */ + leaq 80(%rsp), %rsp +.endm + +.macro u51mul cur, low, high, next + mulq \cur + addq %rax, \low + movq \next, %rax + adcq %rdx, \high +.endm + +.macro reduce + /* Retain the last 51 digits. */ + movq $0x7ffffffffffff, %rbp + + /* Calculate h2' */ + movq %r12, %rax + shrq $51, %r12 + shlq $13, %r13 + + /* Calculate h0' */ + movq %r8, %rsi + shrq $51, %r8 + shlq $13, %r9 + + /* Calculate h2' */ + andq %rbp, %rax // h2' = rax = h2 & (2^51 - 1) = r12 & (2^51 - 1) + orq %r12, %r13 // r13 = (h2 >> 51) + addq %r13, %r14 // h3 += (h2 >> 51) + adcq $0, %r15 + + /* Calculate h0' */ + andq %rbp, %rsi // h0' = rsi = h0 & (2^51 - 1) = r8 & (2^51 - 1) + orq %r8, %r9 // r9 = (h0 >> 51) + addq %r9, %r10 // h1 += (h0 >> 51) + adcq $0, %r11 + + /* Calculate h3' */ + movq %r14, %r8 + shrq $51, %r14 + shlq $13, %r15 + andq %rbp, %r8 // h3' = r8 = h3 & (2^51 - 1) = r14 & (2^51 - 1) + orq %r14, %r15 // r15 = (h3 >> 51) + addq %r15, %rbx // h4 += (h3 >> 51) + adcq $0, %rcx + + /* Calculate h1' */ + movq %r10, %rdx + shrq $51, %r10 + shlq $13, %r11 + andq %rbp, %rdx // h1' = rdx = h1 & (2^51 - 1) = r10 & (2^51 - 1) + orq %r10, %r11 // r11 = (h1 >> 51) + addq %r11, %rax // h2 += (h1 >> 51) + + /* Calculate h4' */ + movq %rbx, %r9 + shrq $51, %rbx + shlq $13, %rcx + andq %rbp, %r9 // h4' = r9 = h4 & (2^51 - 1) = rbx & (2^51 - 1) + orq %rbx, %rcx // rcx = (h4 >> 51) + + /* out[0] = out[0] + 19 * carry */ + leaq (%rcx, %rcx, 8), %r10 // r10 = 8 * rcx + leaq (%rcx, %r10, 2), %rcx // rcx = 2 * (8 * rcx) + rcx = 19 * rcx + addq %rcx, %rsi + + /* h2 remaining */ + movq %rax, %r10 + andq %rbp, %rax // h2 &= (2^51 - 1) + shrq $51, %r10 + addq %r10, %r8 + + /* out[1] += out[0] >> 51 */ + movq %rsi, %r10 + + /* out[0] &= (2^51 - 1) */ + andq %rbp, %rsi + shrq $51, %r10 + addq %r10, %rdx + + /* Storing Results */ + movq %rsi, (%rdi) // h0' + movq %rdx, 8(%rdi) // h1' + movq %rax, 16(%rdi) // h2' + movq %r8, 24(%rdi) // h3' + movq %r9, 32(%rdi) // h4' +.endm + +############################################################# +# void Fp51Mul (Fp51 *out, const Fp51 *f, const Fp51 *g); +############################################################# + +.globl Fp51Mul +.type Fp51Mul, @function +.align 32 +Fp51Mul: +.cfi_startproc + /* Save Register */ + push_stack + + /* The input and output parameters are transferred by registers rdi, rsi, and rdx. + * rdi: out; rsi: f; rdx: g; fp51 is an array of [u64; 5] + * rdx will be overwritten in subsequent calculation. + * Therefore, you need to load the data in the rdx variable in advance. + */ + movq (%rsi), %rax // f0 + movq (%rdx), %rbx // g0 + movq 8(%rdx), %r14 // g1 + movq 16(%rdx), %r15 // g2 + movq 24(%rdx), %rbp // g3, Store g0-g3, store g3 in unaffected registers + movq 32(%rdx), %rcx // g4 + + /* Stores the out pointer and frees the rdi so that the rdi can be used in subsequent calculations. Stores 19 * g4. */ + movq %rdi, 24(%rsp) + movq %rax, %rdi // f0 + /* r14, r15, rbx, and rcx will be overwritten in subsequent calculations. g0 to g2 will be stored. + * Storage actions will be scattered in the calculation code for performance purposes. + */ + + /* h0 = f0g0 + 19f1g4 + 19f2g3 + 19f3g2 + 19f4g1; Stored in r8, r9 */ + mulq %rbx // (rax, rdx) = f0 * g0, in le + movq %rax, %r8 + movq %rdi, %rax // f0 + movq %rbx, 16(%rsp) // g0 + movq %rdx, %r9 + + /* h1 = f0g1 + f1g0 + 19f2g4 + 19f3g3 + 19f4g2; Stored in r10, r11 */ + mulq %r14 // (rax, rdx) = f0 * g1 + movq %rax, %r10 + movq %rdi, %rax // f0 + leaq (%rcx, %rcx, 8), %rbx // g4 * 8 + g4 = g4 * 9 + movq %r14, 8(%rsp) // g1 + movq %rdx, %r11 + + /* h2 = f0g2 + f1g1 + f2g0 + 19f3g4 + 19f4g3; Stored in r12, r13 */ + mulq %r15 // (rax, rdx) = f0 * g2 + movq %rax, %r12 + movq %rdi, %rax // f0 + leaq (%rcx, %rbx, 2), %rdi // rdi = 2 * (9 * g4) + g4, Store 19 * g4 to rdi before rcx is overwritten + movq %r15, (%rsp) // g2 + movq %rdx, %r13 + + /* h3 = f0g3 + f1g2 + f2g1 + f3g0 + 19f4g4; Stored in r14, r15 */ + mulq %rbp // (rax, rdx) = f0 * g3 + movq %rax, %r14 + movq (%rsi), %rax // f0 + movq %rdx, %r15 + + /* h4 = f0g4 + f1g3 + f2g2 + f3g1 + f4g0; Stored in rbx, rcx */ + mulq %rcx // (rax, rdx) = f0 * g4 + movq %rax, %rbx + movq 8(%rsi), %rax // f1 + movq %rdx, %rcx + + /* Calculate 19 * g4 related */ + u51mul %rdi, %r8, %r9, 16(%rsi) // (rax, rdx) = 19 * f1 * g4; load f2 + u51mul %rdi, %r10, %r11, 24(%rsi) // (rax, rdx) = 19 * f2 * g4; load f3 + u51mul %rdi, %r12, %r13, 32(%rsi) // (rax, rdx) = 19 * f3 * g4; load f4 + + mulq %rdi // (rax, rdx) = 19 * f4 * g4 + imulq $19, %rbp, %rdi // 19 * g3 + addq %rax, %r14 + movq 8(%rsi), %rax // f1 + adcq %rdx, %r15 + + /* Calculate g3 related */ + mulq %rbp // (rax, rdx) = f1 * g3 + movq (%rsp), %rbp // g2 + addq %rax, %rbx + movq 16(%rsi), %rax // f2 + adcq %rdx, %rcx + + u51mul %rdi, %r8, %r9, 24(%rsi) // (rax, rdx) = 19 * f2 * g3; load f3 + u51mul %rdi, %r10, %r11, 32(%rsi) // (rax, rdx) = 19 * f3 * g3; load f4 + + mulq %rdi // (rax, rdx) = 19 * f4 * g3 + imulq $19, %rbp, %rdi // 19 * g2 + addq %rax, %r12 + movq 8(%rsi), %rax // f1 + adcq %rdx, %r13 + + /* Calculate g2 related */ + u51mul %rbp, %r14, %r15, 16(%rsi) // (rax, rdx) = f1 * g2; load f2 + + mulq %rbp // (rax, rdx) = f2 * g2 + movq 8(%rsp), %rbp // g1 + addq %rax, %rbx + movq 24(%rsi), %rax // f3 + adcq %rdx, %rcx + + u51mul %rdi, %r8, %r9, 32(%rsi) // (rax, rdx) = 19 * f3 * g2; load f4 + u51mul %rdi, %r10, %r11, 8(%rsi) // (rax, rdx) = 19 * f4 * g2; load f2 + + /* Calculate g1 related */ + mulq %rbp // (rax, rdx) = f1 * g1 + imulq $19, %rbp, %rdi // 19 * g1 + addq %rax, %r12 + movq 16(%rsi), %rax // f2 + adcq %rdx, %r13 + + u51mul %rbp, %r14, %r15, 24(%rsi) // (rax, rdx) = f2 * g1; load f3 + + mulq %rbp // (rax, rdx) = f3 * g1 + movq 16(%rsp), %rbp // g0 + addq %rax, %rbx + movq 32(%rsi), %rax // f4 + adcq %rdx, %rcx + + u51mul %rdi, %r8, %r9, 8(%rsi) // (rax, rdx) = 19 * f4 * g1; load f1 + + /* Calculate g0 related */ + u51mul %rbp, %r10, %r11, 16(%rsi) // (rax, rdx) = f1 * g0; load f2 + u51mul %rbp, %r12, %r13, 24(%rsi) // (rax, rdx) = f2 * g0; load f3 + u51mul %rbp, %r14, %r15, 32(%rsi) // (rax, rdx) = f3 * g0; load f4 + + mulq %rbp // (rax, rdx) = f4 * g0 + addq %rax, %rbx + adcq %rdx, %rcx + + /* Restore the stack pointer. */ + movq 24(%rsp), %rdi + + reduce + + /* Recovery register */ + pop_stack + ret +.cfi_endproc +.size Fp51Mul,.-Fp51Mul + +############################################################# +# void Fp51Square(Fp51 *out, const Fp51 *f); +############################################################# + +.globl Fp51Square +.type Fp51Square, @function +.align 32 +Fp51Square: +.cfi_startproc + /* Save Register */ + push_stack + + /* The input and output parameters are transferred by registers rdi and rsi. + * rdi: out; rsi: f; fp51 is an array of [u64; 5] + * Loads only non-adjacent data, vacating registers for storage calculations + */ + movq (%rsi), %rax // f0 + movq 16(%rsi), %r15 // f2 + movq 32(%rsi), %rcx // f4 + + /* Open the stack and store the following necessary content, which is consistent with the Fp51Mul. + * Stores the out pointer, frees the rdi, + * so that the rdi can be used in subsequent calculations, and stores 19 * f4. + */ + leaq (%rax, %rax, 1), %rbp // 2 * f0 + movq %rdi, 24(%rsp) + + /* h0 = f0^2 + 38f1f4 + 38f2f3; Stored in r8, r9 */ + mulq %rax // (rax, rdx) = f0^2 + movq %rax, %r8 + movq 8(%rsi), %rax // f1 + movq %rdx, %r9 + + /* h1 = 19f3^2 + 2f0f1 + 38f2g4; Stored in r10, r11 */ + mulq %rbp // (rax, rdx) = 2f0 * f1 + movq %rax, %r10 + movq %r15, %rax // f2 + movq %r15, 16(%rsp) // Store f2 for later use of rsi + movq %rdx, %r11 + + /* h2 = f1^2 + 2f0f2 + 38f3g4; Stored in r12, r13 */ + mulq %rbp // (rax, rdx) = 2f0 * f2 + movq %rax, %r12 + movq 24(%rsi), %rax // f3 + movq %rdx, %r13 + + imulq $19, %rcx, %rdi // Store 19 * f4 to rdi before rcx is overwritten + + /* h3 = 19f4^2 + 2f0f3 + 2f1f2; Stored in r14, r15 */ + mulq %rbp // (rax, rdx) = 2f0 * f3 + movq %rax, %r14 + movq %rcx, %rax // f4 + movq %rdx, %r15 + + /* h4 = f2^2 + 2f0f4 + 2f1f3; Stored in rbx, rcx */ + mulq %rbp // (rax, rdx) = 2f0 * f4 + movq %rax, %rbx + movq %rcx, %rax // f4 + movq %rdx, %rcx + + /* Calculate 19 * f4 related + * h3 + */ + u51mul %rdi, %r14, %r15, 8(%rsi) // (rax, rdx) = 19 * f4^2; load f1 + + movq 24(%rsi), %rsi // f3 + + /* Calculate f1 related + * h2 + */ + leaq (%rax, %rax, 1), %rbp // 2 * f1 + u51mul %rax, %r12, %r13, 16(%rsp) // (rax, rdx) = f1^2; load f2 + + /* h3 */ + u51mul %rbp, %r14, %r15, %rsi // (rax, rdx) = 2 * f1 * f2; load f3 + + /* h4 */ + u51mul %rbp, %rbx, %rcx, %rbp // (rax, rdx) = 2 * f1 * f3; load 2 * f1 + + imulq $19, %rsi, %rbp // 19 * f3 + + /* h0 */ + mulq %rdi // (rax, rdx) = 2 * f1 * 19 * f4 + addq %rax, %r8 + leaq (%rsi, %rsi, 1), %rax // 2 * f3 + adcq %rdx, %r9 + + /* Calculate f3 related + * h2 + */ + u51mul %rdi, %r12, %r13, %rsi // (rax, rdx) = f3 * 2 * 19 * f4; load f3 + + /* h1 */ + u51mul %rbp, %r10, %r11, 16(%rsp) // (rax, rdx) = 19 * f3^2; load f2 + + /* Calculate f2 related + * h4 + */ + leaq (%rax, %rax, 1), %rsi // 2 * f2 + u51mul %rax, %rbx, %rcx, %rbp // (rax, rdx) = f2^2; load 19 * f3 + + /* h0 */ + u51mul %rsi, %r8, %r9, %rsi // (rax, rdx) = 2 * f2 * 19 * f3; load 2 * f2 + + /* h1 */ + mulq %rdi // (rax, rdx) = 2 * f2 * 19 * f4 + addq %rax, %r10 + adcq %rdx, %r11 + + /* Recovery register */ + movq 24(%rsp), %rdi + + reduce + + /* Recovery register */ + pop_stack + ret +.cfi_endproc +.size Fp51Square,.-Fp51Square + +############################################################# +# void Fp51MulScalar(Fp51 *out, const Fp51 *in); +############################################################# + +.globl Fp51MulScalar +.type Fp51MulScalar, @function +.align 32 +Fp51MulScalar: +.cfi_startproc + /* Save Register */ + push_stack + + /*The input and output parameters are transferred by registers rdi, rsi, and rdx. + * rdi: out; rsi: in; rdx: scalar; fp51 Is an array of [u64; 5] + * Open stack, consistent with Fp51Mul + */ + + /* h0 */ + movl $121666, %eax + mulq (%rsi) // f0 * 121666 + movq %rax, %r8 + movl $121666, %eax // Modify the rax immediately after the rax is vacated. + movq %rdx, %r9 + + /* h1 */ + mulq 8(%rsi) // f1 * 121666 + movq %rax, %r10 + movl $121666, %eax + movq %rdx, %r11 + + /* h2 */ + mulq 16(%rsi) // f2 * 121666 + movq %rax, %r12 + movl $121666, %eax + movq %rdx, %r13 + + /* h3 */ + mulq 24(%rsi) // f3 * 121666 + movq %rax, %r14 + movl $121666, %eax + movq %rdx, %r15 + + /* h4 */ + mulq 32(%rsi) // f4 * 121666 + movq %rax, %rbx + movq %rdx, %rcx + + reduce + + /* Recovery register */ + pop_stack + ret +.cfi_endproc +.size Fp51MulScalar,.-Fp51MulScalar + +#endif diff --git a/crypto/curve25519/src/curve25519.c b/crypto/curve25519/src/curve25519.c new file mode 100644 index 00000000..d09160ce --- /dev/null +++ b/crypto/curve25519/src/curve25519.c @@ -0,0 +1,693 @@ +/* + * 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_CURVE25519 + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "curve25519_local.h" +#include "crypt_util_rand.h" +#include "crypt_types.h" + + +CRYPT_CURVE25519_Ctx *CRYPT_CURVE25519_NewCtx(void) +{ + CRYPT_CURVE25519_Ctx *ctx = NULL; + ctx = (CRYPT_CURVE25519_Ctx *)BSL_SAL_Malloc(sizeof(CRYPT_CURVE25519_Ctx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)memset_s(ctx, sizeof(CRYPT_CURVE25519_Ctx), 0, sizeof(CRYPT_CURVE25519_Ctx)); + + ctx->keyType = CURVE25519_NOKEY; + ctx->hashMethod = NULL; + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +CRYPT_CURVE25519_Ctx *CRYPT_CURVE25519_DupCtx(CRYPT_CURVE25519_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + + CRYPT_CURVE25519_Ctx *newCtx = NULL; + newCtx = (CRYPT_CURVE25519_Ctx *)BSL_SAL_Malloc(sizeof(CRYPT_CURVE25519_Ctx)); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memcpy_s(newCtx, sizeof(CRYPT_CURVE25519_Ctx), ctx, sizeof(CRYPT_CURVE25519_Ctx)); + BSL_SAL_ReferencesInit(&(newCtx->references)); + return newCtx; +} + +int32_t CRYPT_CURVE25519_Ctrl(CRYPT_CURVE25519_Ctx *pkey, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + if (pkey == NULL || val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (opt == CRYPT_CTRL_UP_REFERENCES && len == (uint32_t)sizeof(int)) { + return BSL_SAL_AtomicUpReferences(&(pkey->references), (int *)val); + } + + if (opt == CRYPT_CTRL_SET_ED25519_HASH_METHOD && len == sizeof(EAL_MdMethod)) { + const EAL_MdMethod *hashMethod = (const EAL_MdMethod *)val; + // SHA512 digest size is 64, no other hash has 64 md size + if (hashMethod->mdSize != 64) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_HASH_METH_ERROR); + return CRYPT_CURVE25519_HASH_METH_ERROR; + } + pkey->hashMethod = (const EAL_MdMethod *)hashMethod; + return CRYPT_SUCCESS; + } + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_UNSUPPORTED_CTRL_OPTION); + return CRYPT_CURVE25519_UNSUPPORTED_CTRL_OPTION; +} + +void CRYPT_CURVE25519_FreeCtx(CRYPT_CURVE25519_Ctx *pkey) +{ + if (pkey == NULL) { + return; + } + int ret = 0; + BSL_SAL_AtomicDownReferences(&(pkey->references), &ret); + if (ret > 0) { + return; + } + BSL_SAL_ReferencesFree(&(pkey->references)); + BSL_SAL_CleanseData((void *)(pkey), sizeof(CRYPT_CURVE25519_Ctx)); + BSL_SAL_FREE(pkey); +} + +int32_t CRYPT_CURVE25519_SetPubKey(CRYPT_CURVE25519_Ctx *pkey, const CRYPT_Curve25519Pub *pub) +{ + if (pkey == NULL || pub == NULL || pub->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pub->len != CRYPT_CURVE25519_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_KEYLEN_ERROR); + return CRYPT_CURVE25519_KEYLEN_ERROR; + } + + /* The keyLen has been checked and does not have the overlong problem. + The pkey memory is dynamically allocated and does not overlap with the pubkey memory. */ + /* There is no failure case for memcpy_s. */ + (void)memcpy_s(pkey->pubKey, CRYPT_CURVE25519_KEYLEN, pub->data, pub->len); + pkey->keyType |= CURVE25519_PUBKEY; + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CURVE25519_SetPrvKey(CRYPT_CURVE25519_Ctx *pkey, const CRYPT_Curve25519Prv *prv) +{ + if (pkey == NULL || prv == NULL || prv->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (prv->len != CRYPT_CURVE25519_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_KEYLEN_ERROR); + return CRYPT_CURVE25519_KEYLEN_ERROR; + } + + /* The keyLen has been checked and does not have the overlong problem. + The pkey memory is dynamically allocated and does not overlap with the pubkey memory. */ + /* There is no failure case for memcpy_s. */ + (void)memcpy_s(pkey->prvKey, CRYPT_CURVE25519_KEYLEN, prv->data, prv->len); + pkey->keyType |= CURVE25519_PRVKEY; + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CURVE25519_GetPubKey(const CRYPT_CURVE25519_Ctx *pkey, CRYPT_Curve25519Pub *pub) +{ + if (pkey == NULL || pub == NULL || pub->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (pub->len < CRYPT_CURVE25519_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_KEYLEN_ERROR); + return CRYPT_CURVE25519_KEYLEN_ERROR; + } + + if ((pkey->keyType & CURVE25519_PUBKEY) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_PUBKEY); + return CRYPT_CURVE25519_NO_PUBKEY; + } + + /* The keyLen has been checked and does not have the overlong problem. + The pkey memory is dynamically allocated and does not overlap with the pubkey memory. */ + /* There is no failure case for memcpy_s. */ + (void)memcpy_s(pub->data, pub->len, pkey->pubKey, CRYPT_CURVE25519_KEYLEN); + + pub->len = CRYPT_CURVE25519_KEYLEN; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CURVE25519_GetPrvKey(const CRYPT_CURVE25519_Ctx *pkey, CRYPT_Curve25519Prv *prv) +{ + if (pkey == NULL || prv == NULL || prv->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (prv->len < CRYPT_CURVE25519_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_KEYLEN_ERROR); + return CRYPT_CURVE25519_KEYLEN_ERROR; + } + + if ((pkey->keyType & CURVE25519_PRVKEY) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_PRVKEY); + return CRYPT_CURVE25519_NO_PRVKEY; + } + + /* The keyLen has been checked and does not have the overlong problem. + The pkey memory is dynamically allocated and does not overlap with the pubkey memory. */ + /* There is no failure case for memcpy_s. */ + (void)memcpy_s(prv->data, prv->len, pkey->prvKey, CRYPT_CURVE25519_KEYLEN); + + prv->len = CRYPT_CURVE25519_KEYLEN; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CURVE25519_GetBits(const CRYPT_CURVE25519_Ctx *pkey) +{ + (void)pkey; + return CRYPT_CURVE25519_KEYLEN * 8; // bits = 8 * bytes +} + +#ifdef HITLS_CRYPTO_ED25519 +static int32_t PrvKeyHash(const uint8_t *prvKey, uint32_t prvKeyLen, uint8_t *prvKeyHash, uint32_t prvHashLen, + const EAL_MdMethod *hashMethod) +{ + void *mdCtx = NULL; + int32_t ret; + uint32_t hashLen = prvHashLen; + + mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = hashMethod->init(mdCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->update(mdCtx, prvKey, prvKeyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->final(mdCtx, prvKeyHash, &hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + +END: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +static int32_t GetRHash(uint8_t r[CRYPT_CURVE25519_SIGNLEN], const uint8_t prefix[CRYPT_CURVE25519_KEYLEN], + const uint8_t *msg, uint32_t msgLen, const EAL_MdMethod *hashMethod) +{ + void *mdCtx = NULL; + int32_t ret; + uint32_t hashLen = CRYPT_CURVE25519_SIGNLEN; + + mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = hashMethod->init(mdCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->update(mdCtx, prefix, CRYPT_CURVE25519_KEYLEN); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->update(mdCtx, msg, msgLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->final(mdCtx, r, &hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + +END: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +static int32_t GetKHash(uint8_t k[CRYPT_CURVE25519_SIGNLEN], const uint8_t r[CRYPT_CURVE25519_KEYLEN], + const uint8_t pubKey[CRYPT_CURVE25519_KEYLEN], const uint8_t *msg, uint32_t msgLen, + const EAL_MdMethod *hashMethod) +{ + void *mdCtx = NULL; + int32_t ret; + uint32_t hashLen = CRYPT_CURVE25519_SIGNLEN; + + mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = hashMethod->init(mdCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->update(mdCtx, r, CRYPT_CURVE25519_KEYLEN); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->update(mdCtx, pubKey, CRYPT_CURVE25519_KEYLEN); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->update(mdCtx, msg, msgLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = hashMethod->final(mdCtx, k, &hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + +END: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +static int32_t SignInputCheck(const CRYPT_CURVE25519_Ctx *pkey, const uint8_t *msg, + uint32_t msgLen, const uint8_t *sign, const uint32_t *signLen) +{ + if (pkey == NULL || (msg == NULL && msgLen != 0) || sign == NULL || signLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((pkey->keyType & CURVE25519_PRVKEY) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_PRVKEY); + return CRYPT_CURVE25519_NO_PRVKEY; + } + if (*signLen < CRYPT_CURVE25519_SIGNLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_SIGNLEN_ERROR); + return CRYPT_CURVE25519_SIGNLEN_ERROR; + } + if (pkey->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_HASH_METHOD); + return CRYPT_CURVE25519_NO_HASH_METHOD; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CURVE25519_Sign(CRYPT_CURVE25519_Ctx *pkey, const uint8_t *msg, + uint32_t msgLen, uint8_t *sign, uint32_t *signLen) +{ + int32_t ret; + uint8_t prvKeyHash[CRYPT_CURVE25519_SIGNLEN]; + uint8_t r[CRYPT_CURVE25519_SIGNLEN]; + uint8_t k[CRYPT_CURVE25519_SIGNLEN]; + uint8_t outSign[CRYPT_CURVE25519_SIGNLEN]; + GeE geTmp; + + ret = SignInputCheck(pkey, msg, msgLen, sign, signLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = PrvKeyHash(pkey->prvKey, CRYPT_CURVE25519_KEYLEN, prvKeyHash, CRYPT_CURVE25519_SIGNLEN, pkey->hashMethod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + prvKeyHash[0] &= 0xf8; + // on block 31, clear the highest bit + prvKeyHash[31] &= 0x7f; + // on block 31, set second highest bit to 1 + prvKeyHash[31] |= 0x40; + + // if ctx has no public key, generate public key and store it in ctx + if ((pkey->keyType & CURVE25519_PUBKEY) == 0) { + ScalarMultiBase(&geTmp, prvKeyHash); + PointEncoding(&geTmp, pkey->pubKey, CRYPT_CURVE25519_KEYLEN); + pkey->keyType |= CURVE25519_PUBKEY; + } + + ret = GetRHash(r, prvKeyHash + CRYPT_CURVE25519_KEYLEN, msg, msgLen, pkey->hashMethod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ModuloL(r); + ScalarMultiBase(&geTmp, r); + PointEncoding(&geTmp, outSign, CRYPT_CURVE25519_SIGNLEN); + + ret = GetKHash(k, outSign, pkey->pubKey, msg, msgLen, pkey->hashMethod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ModuloL(k); + ScalarMulAdd(outSign + CRYPT_CURVE25519_KEYLEN, k, prvKeyHash, r); + + // The value of *signLen has been checked in SignInputCheck to ensure that + // the value is greater than or equal to CRYPT_CURVE25519_SIGNLEN. + // The sign memory is input from outside the function. The outSign memory is allocated within the function. + // Memory overlap does not exist. There is no failure case for memcpy_s. + (void)memcpy_s(sign, *signLen, outSign, CRYPT_CURVE25519_SIGNLEN); + *signLen = CRYPT_CURVE25519_SIGNLEN; + +END: + BSL_SAL_CleanseData(prvKeyHash, sizeof(prvKeyHash)); + BSL_SAL_CleanseData(r, sizeof(r)); + BSL_SAL_CleanseData(k, sizeof(k)); + return ret; +} + +int32_t CRYPT_CURVE25519_GetSignLen(const CRYPT_CURVE25519_Ctx *pkey) +{ + (void)pkey; + return CRYPT_CURVE25519_SIGNLEN; +} + +static int32_t VerifyInputCheck(const CRYPT_CURVE25519_Ctx *pkey, const uint8_t *msg, + uint32_t msgLen, const uint8_t *sign, uint32_t signLen) +{ + if (pkey == NULL || (msg == NULL && msgLen != 0) || sign == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((pkey->keyType & CURVE25519_PUBKEY) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_PUBKEY); + return CRYPT_CURVE25519_NO_PUBKEY; + } + if (signLen != CRYPT_CURVE25519_SIGNLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_SIGNLEN_ERROR); + return CRYPT_CURVE25519_SIGNLEN_ERROR; + } + if (pkey->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_HASH_METHOD); + return CRYPT_CURVE25519_NO_HASH_METHOD; + } + return CRYPT_SUCCESS; +} + +/* check 0 <= s < l, l = 2^252 + 27742317777372353535851937790883648493 */ +static bool VerifyCheckSValid(const uint8_t s[CRYPT_CURVE25519_KEYLEN]) +{ + const uint8_t l[CRYPT_CURVE25519_KEYLEN] = { + 0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 + }; + + int32_t i; + // start from highest block 31 + for (i = 31; i >= 0; i--) { + if (s[i] > l[i]) { + return false; + } else if (s[i] < l[i]) { + return true; + } + } + // s = l is invalid + return false; +} + +int32_t CRYPT_CURVE25519_Verify(const CRYPT_CURVE25519_Ctx *pkey, const uint8_t *msg, + uint32_t msgLen, const uint8_t *sign, uint32_t signLen) +{ + int32_t ret; + GeE geA, sG; + uint8_t kHash[CRYPT_CURVE25519_SIGNLEN]; + uint8_t localR[CRYPT_CURVE25519_KEYLEN]; + + const uint8_t *r = NULL; + const uint8_t *s = NULL; + ret = VerifyInputCheck(pkey, msg, msgLen, sign, signLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + // r is first half of sign, length 32 + r = sign; + // s is second half of the sign, length 32 + s = sign + 32; + + if (!VerifyCheckSValid(s)) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_VERIFY_FAIL); + ret = CRYPT_CURVE25519_VERIFY_FAIL; + goto END; + } + + if (PointDecoding(&geA, pkey->pubKey) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_VERIFY_FAIL); + ret = CRYPT_CURVE25519_INVALID_PUBKEY; + goto END; + } + + ret = GetKHash(kHash, r, pkey->pubKey, msg, msgLen, pkey->hashMethod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + CURVE25519_FP_NEGATE(geA.x.data, geA.x.data); + CURVE25519_FP_NEGATE(geA.t.data, geA.t.data); + + ModuloL(kHash); + KAMulPlusMulBase(&sG, kHash, &geA, s); + PointEncoding(&sG, localR, CRYPT_CURVE25519_KEYLEN); + + if (memcmp(localR, r, CRYPT_CURVE25519_KEYLEN) == 0) { + ret = CRYPT_SUCCESS; + } else { + ret = CRYPT_CURVE25519_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } + +END: + return ret; +} + +int32_t CRYPT_ED25519_GenKey(CRYPT_CURVE25519_Ctx *pkey) +{ + if (pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // SHA512 digest size is 64, no other hash has 64 md size + if (pkey->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_HASH_METHOD); + return CRYPT_CURVE25519_NO_HASH_METHOD; + } + int32_t ret; + uint8_t prvKey[CRYPT_CURVE25519_KEYLEN]; + uint8_t prvKeyHash[CRYPT_CURVE25519_SIGNLEN]; + GeE tmp; + + ret = CRYPT_Rand(prvKey, sizeof(prvKey)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = PrvKeyHash(prvKey, CRYPT_CURVE25519_KEYLEN, prvKeyHash, CRYPT_CURVE25519_SIGNLEN, pkey->hashMethod); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + prvKeyHash[0] &= 0xf8; + // on block 31, clear the highest bit + prvKeyHash[31] &= 0x7f; + // on block 31, set second highest bit to 1 + prvKeyHash[31] |= 0x40; + + ScalarMultiBase(&tmp, prvKeyHash); + PointEncoding(&tmp, pkey->pubKey, CRYPT_CURVE25519_KEYLEN); + + // The pkey is not empty. The length of the prvKey is CRYPT_CURVE25519_KEYLEN, + // which is the same as the length of local prvKey. + // The pkey->prvKey memory is input outside the function. The local prvKey memory is allocated within the function. + // Memory overlap does not exist. No failure case exists for memcpy_s. + (void)memcpy_s(pkey->prvKey, CRYPT_CURVE25519_KEYLEN, prvKey, CRYPT_CURVE25519_KEYLEN); + pkey->keyType = CURVE25519_PRVKEY | CURVE25519_PUBKEY; + +END: + BSL_SAL_CleanseData(prvKey, sizeof(prvKey)); + BSL_SAL_CleanseData(prvKeyHash, sizeof(prvKeyHash)); + return ret; +} +#endif /* HITLS_CRYPTO_ED25519 */ + +#ifdef HITLS_CRYPTO_X25519 +/* Calculate the shared key based on the local private key and peer public key + * Shared12 = prv1 * Pub2 = prv1 * (prv2 * G) = prv1 * prv2 * G + */ +int32_t CRYPT_CURVE25519_ComputeSharedKey(CRYPT_CURVE25519_Ctx *prvKey, CRYPT_CURVE25519_Ctx *pubKey, + uint8_t *sharedKey, uint32_t *shareKeyLen) +{ + if (prvKey == NULL || pubKey == NULL || sharedKey == NULL || shareKeyLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (*shareKeyLen < CRYPT_CURVE25519_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_KEYLEN_ERROR); + return CRYPT_CURVE25519_KEYLEN_ERROR; + } + if ((prvKey->keyType & CURVE25519_PRVKEY) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_PRVKEY); + return CRYPT_CURVE25519_NO_PRVKEY; + } + if ((pubKey->keyType & CURVE25519_PUBKEY) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_NO_PUBKEY); + return CRYPT_CURVE25519_NO_PUBKEY; + } + + uint32_t tmpLen = *shareKeyLen; + ScalarMultiPoint(sharedKey, prvKey->prvKey, pubKey->pubKey); + + int32_t i; + uint8_t checkValid = 0; + for (i = 0; i < CRYPT_CURVE25519_KEYLEN; i++) { + checkValid |= sharedKey[i]; + } + if (checkValid == 0) { + *shareKeyLen = tmpLen; + BSL_ERR_PUSH_ERROR(CRYPT_CURVE25519_KEY_COMPUTE_FAILED); + return CRYPT_CURVE25519_KEY_COMPUTE_FAILED; + } else { + *shareKeyLen = CRYPT_CURVE25519_KEYLEN; + return CRYPT_SUCCESS; + } +} + +/** + * @brief x25519 Calculate the public key based on the private key. + * + * @param privateKey [IN] Private key + * @param publicKey [OUT] Public key + * + */ +void CRYPT_X25519_PublicFromPrivate(const uint8_t privateKey[CRYPT_CURVE25519_KEYLEN], + uint8_t publicKey[CRYPT_CURVE25519_KEYLEN]) +{ + uint8_t privateCopy[CRYPT_CURVE25519_KEYLEN]; + GeE out; + Fp25 zPlusY, zMinusY, zMinusYInvert; + + (void)memcpy_s(privateCopy, sizeof(privateCopy), privateKey, sizeof(privateCopy)); + + privateCopy[0] &= 0xf8; /* decodeScalar25519(k): k_list[0] &= 0xf8 */ + privateCopy[31] &= 0x7f; /* decodeScalar25519(k): k_list[31] &= 0x7f */ + privateCopy[31] |= 0x40; /* decodeScalar25519(k): k_list[31] |= 0x40 */ + + ScalarMultiBase(&out, privateCopy); + + CURVE25519_FP_ADD(zPlusY.data, out.z.data, out.y.data); + CURVE25519_FP_SUB(zMinusY.data, out.z.data, out.y.data); + FpInvert(&zMinusYInvert, &zMinusY); + FpMul(&zPlusY, &zPlusY, &zMinusYInvert); + PolynomialToData(publicKey, &zPlusY); + + /* cleanup tmp private key */ + BSL_SAL_CleanseData(privateCopy, sizeof(privateCopy)); +} + +int32_t CRYPT_X25519_GenKey(CRYPT_CURVE25519_Ctx *pkey) +{ + if (pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret = CRYPT_Rand(pkey->prvKey, sizeof(pkey->prvKey)); + if (ret != CRYPT_SUCCESS) { + pkey->keyType = 0; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + CRYPT_X25519_PublicFromPrivate(pkey->prvKey, pkey->pubKey); + + pkey->keyType = CURVE25519_PRVKEY | CURVE25519_PUBKEY; + + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_X25519 */ + +int32_t CRYPT_CURVE25519_Cmp(const CRYPT_CURVE25519_Ctx *a, const CRYPT_CURVE25519_Ctx *b) +{ + RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT); + + RETURN_RET_IF((a->keyType & CURVE25519_PUBKEY) == 0 || (b->keyType & CURVE25519_PUBKEY) == 0, + CRYPT_CURVE25519_NO_PUBKEY); + + RETURN_RET_IF(memcmp(a->pubKey, b->pubKey, CRYPT_CURVE25519_KEYLEN) != 0, CRYPT_CURVE25519_PUBKEY_NOT_EQUAL); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_CURVE25519_GetSecBits(const CRYPT_CURVE25519_Ctx *ctx) +{ + (void) ctx; + return 128; +} +#endif /* HITLS_CRYPTO_CURVE25519 */ diff --git a/crypto/curve25519/src/curve25519_local.h b/crypto/curve25519/src/curve25519_local.h new file mode 100644 index 00000000..0425a8a5 --- /dev/null +++ b/crypto/curve25519/src/curve25519_local.h @@ -0,0 +1,441 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CURVE25519_LOCAL_H +#define CURVE25519_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CURVE25519 + +#include "crypt_curve25519.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CURVE25519_NOKEY 0 +#define CURVE25519_PRVKEY 0x1 +#define CURVE25519_PUBKEY 0x10 + +#define UINT8_32_21BITS_BLOCKNUM 12 +#define UINT8_64_21BITS_BLOCKNUM 24 + +struct CryptCurve25519Ctx { + uint8_t keyType; /* specify the key type */ + const EAL_MdMethod *hashMethod; + uint8_t pubKey[CRYPT_CURVE25519_KEYLEN]; + uint8_t prvKey[CRYPT_CURVE25519_KEYLEN]; + BSL_SAL_RefCount references; +}; + +typedef struct Fp25 { + int32_t data[10]; +} Fp25; + +typedef struct Fp51 { + uint64_t data[5]; +} Fp51; + +typedef struct H19 { + int64_t data[19]; +} H19; + +// group element in Projective Coordinate, x = X / Z, y = Y / Z +typedef struct GeP { + Fp25 x; + Fp25 y; + Fp25 z; +} GeP; + +// group element in Extended Coordinate, x = X / Z, y = Y / Z, T = XY / Z which leads to XY = ZT +typedef struct GeE { + Fp25 x; + Fp25 y; + Fp25 t; + Fp25 z; +} GeE; + +// group element in Completed Coordinate, x = X / Z, y = Y / T +typedef struct GeC { + Fp25 x; + Fp25 y; + Fp25 t; + Fp25 z; +} GeC; + +typedef struct GePre { + Fp25 yplusx; + Fp25 yminusx; + Fp25 xy2d; +} GePre; + +typedef struct GeEPre { + Fp25 yplusx; + Fp25 yminusx; + Fp25 t2z; + Fp25 z; +} GeEPre; + +/* Get High x bits for 64bits block */ +#define MASK_HIGH64(x) (0xFFFFFFFFFFFFFFFFLL << (64 - (x))) +/* Get low x bits for 32bits block */ +#define MASK_LOW32(x) (0xFFFFFFFF >> (32 - (x))) +/* Get high x bits for 32bits block */ +#define MASK_HIGH32(x) (0xFFFFFFFF << (32 - (x))) + +/* low 21 bits for 64bits block */ +#define MASK_64_LOW21 0x1fffffLL + +#define CURVE25519_MASK_HIGH_38 MASK_HIGH64(38) +#define CURVE25519_MASK_HIGH_39 MASK_HIGH64(39) + +/* process carry from h0_ to h1_, h0_ boundary restrictions is bits */ +#define PROCESS_CARRY(h0_, h1_, signMask_, over_, bits) \ + do { \ + (over_) = (h0_) + (1 << (bits)); \ + (signMask_) = MASK_HIGH64((bits) + 1) & (-((over_) >> 63)); \ + (h1_) += ((over_) >> ((bits) + 1)) | (signMask_); \ + (h0_) -= MASK_HIGH64(64 - ((bits) + 1)) & (over_); \ + } while (0) + +/* process carry from h0_ to h1_, h is int64_t type */ +#define PROCESS_CARRY_INT64(h0_, h1_, signMask_, over_, bits) \ + do { \ + (over_) = (uint64_t)(h0_) + (1 << (bits)); \ + (signMask_) = MASK_HIGH64((bits) + 1) & (-((over_) >> 63)); \ + (h1_) += (int64_t)(((over_) >> ((bits) + 1)) | (signMask_)); \ + (h0_) -= (int64_t)(MASK_HIGH64(64 - ((bits) + 1)) & (over_)); \ + } while (0) + +/* process carry from h0_ to h1_ ignoring sign, h0_ boundary restrictions is bits */ +#define PROCESS_CARRY_UNSIGN(h0_, h1_, signMask_, over_, bits) \ + do { \ + (signMask_) = MASK_HIGH64((bits)) & (-((h0_) >> 63)); \ + (over_) = ((h0_) >> (bits)) | (signMask_); \ + (h1_) += (over_); \ + (h0_) -= (over_) * (1 << (bits)); \ + } while (0) + +/* l = 2^252 + 27742317777372353535851937790883648493, let l0 = 27742317777372353535851937790883648493 */ +/* -l0 = 666643 * 2^0 + 470296 * 2^21 + 654183 * 2^(2*21) - 997805 * 2^(3*21) + 136657 * 2^(4*21) - 683901 * 2^(5*21) */ +#define CURVE25519_MULTI_BY_L0(src, pos) \ + do { \ + (src)[0 + (pos)] += (src)[12 + (pos)] * 666643; \ + (src)[1 + (pos)] += (src)[12 + (pos)] * 470296; \ + (src)[2 + (pos)] += (src)[12 + (pos)] * 654183; \ + (src)[3 + (pos)] -= (src)[12 + (pos)] * 997805; \ + (src)[4 + (pos)] += (src)[12 + (pos)] * 136657; \ + (src)[5 + (pos)] -= (src)[12 + (pos)] * 683901; \ + (src)[12 + (pos)] = 0; \ + } while (0) + +/* Compute multiplications by 19 */ +#define CURVE25519_MULTI_BY_19(dst, src, t1_, t2_, t16_) \ + do { \ + (t1_) = (uint64_t)(src); \ + (t2_) = (t1_) << 1; \ + (t16_) = (t1_) << 4; \ + (dst) += (int64_t)((t1_) + (t2_) + (t16_)); \ + } while (0) + +/* Set this parameter to value, */ +#define CURVE25519_FP_SET(dst, value) \ + do { \ + (dst)[0] = (value); \ + (dst)[1] = 0; \ + (dst)[2] = 0; \ + (dst)[3] = 0; \ + (dst)[4] = 0; \ + (dst)[5] = 0; \ + (dst)[6] = 0; \ + (dst)[7] = 0; \ + (dst)[8] = 0; \ + (dst)[9] = 0; \ + } while (0) + +#define CURVE25519_FP51_SET(dst, value) \ + do { \ + (dst)[0] = (value); \ + (dst)[1] = 0; \ + (dst)[2] = 0; \ + (dst)[3] = 0; \ + (dst)[4] = 0; \ + } while (0) + +/* Copy */ +#define CURVE25519_FP_COPY(dst, src) \ + do { \ + (dst)[0] = (src)[0]; \ + (dst)[1] = (src)[1]; \ + (dst)[2] = (src)[2]; \ + (dst)[3] = (src)[3]; \ + (dst)[4] = (src)[4]; \ + (dst)[5] = (src)[5]; \ + (dst)[6] = (src)[6]; \ + (dst)[7] = (src)[7]; \ + (dst)[8] = (src)[8]; \ + (dst)[9] = (src)[9]; \ + } while (0) + +#define CURVE25519_FP51_COPY(dst, src) \ + do { \ + (dst)[0] = (src)[0]; \ + (dst)[1] = (src)[1]; \ + (dst)[2] = (src)[2]; \ + (dst)[3] = (src)[3]; \ + (dst)[4] = (src)[4]; \ + } while (0) + +/* Negate */ +#define CURVE25519_FP_NEGATE(dst, src) \ + do { \ + (dst)[0] = -(src)[0]; \ + (dst)[1] = -(src)[1]; \ + (dst)[2] = -(src)[2]; \ + (dst)[3] = -(src)[3]; \ + (dst)[4] = -(src)[4]; \ + (dst)[5] = -(src)[5]; \ + (dst)[6] = -(src)[6]; \ + (dst)[7] = -(src)[7]; \ + (dst)[8] = -(src)[8]; \ + (dst)[9] = -(src)[9]; \ + } while (0) + +/* Basic operation */ +#define CURVE25519_FP_OP(dst, src1, src2, op) \ + do { \ + (dst)[0] = (src1)[0] op (src2)[0]; \ + (dst)[1] = (src1)[1] op (src2)[1]; \ + (dst)[2] = (src1)[2] op (src2)[2]; \ + (dst)[3] = (src1)[3] op (src2)[3]; \ + (dst)[4] = (src1)[4] op (src2)[4]; \ + (dst)[5] = (src1)[5] op (src2)[5]; \ + (dst)[6] = (src1)[6] op (src2)[6]; \ + (dst)[7] = (src1)[7] op (src2)[7]; \ + (dst)[8] = (src1)[8] op (src2)[8]; \ + (dst)[9] = (src1)[9] op (src2)[9]; \ + } while (0) + +/* Basic operation */ +#define CURVE25519_FP51_ADD(dst, src1, src2) \ + do { \ + (dst)[0] = (src1)[0] + (src2)[0]; \ + (dst)[1] = (src1)[1] + (src2)[1]; \ + (dst)[2] = (src1)[2] + (src2)[2]; \ + (dst)[3] = (src1)[3] + (src2)[3]; \ + (dst)[4] = (src1)[4] + (src2)[4]; \ + } while (0) + +#define CURVE25519_FP51_SUB(dst, src1, src2) \ + do { \ + (dst)[0] = ((src1)[0] + 0xfffffffffffda) - (src2)[0]; \ + (dst)[1] = ((src1)[1] + 0xffffffffffffe) - (src2)[1]; \ + (dst)[2] = ((src1)[2] + 0xffffffffffffe) - (src2)[2]; \ + (dst)[3] = ((src1)[3] + 0xffffffffffffe) - (src2)[3]; \ + (dst)[4] = ((src1)[4] + 0xffffffffffffe) - (src2)[4]; \ + } while (0) + +#define CURVE25519_GE_COPY(dst, src) \ + do { \ + CURVE25519_FP_COPY((dst).x.data, (src).x.data); \ + CURVE25519_FP_COPY((dst).y.data, (src).y.data); \ + CURVE25519_FP_COPY((dst).z.data, (src).z.data); \ + CURVE25519_FP_COPY((dst).t.data, (src).t.data); \ + } while (0) + +/* Add */ +#define CURVE25519_FP_ADD(dst, src1, src2) CURVE25519_FP_OP(dst, src1, src2, +) +/* Subtract */ +#define CURVE25519_FP_SUB(dst, src1, src2) CURVE25519_FP_OP(dst, src1, src2, -) + +/* dst = dst * bit, bit = 0 or 1 */ +#define CURVE25519_FP_MUL_BIT(dst, bit) \ + do { \ + int ii; \ + for (ii = 0; ii < 10; ii++) { \ + (dst)[ii] = (dst)[ii] * (bit); \ + } \ + } while (0) + +/* dst[i] = src[i] * scalar */ +#define CURVE25519_FP_MUL_SCALAR(dst, src, scalar) \ + do { \ + uint32_t ii; \ + for (ii = 0; ii < 10; ii++) { \ + (dst)[ii] = (uint64_t)((src)[ii] * (scalar)); \ + } \ + } while (0) + +#define CURVE25519_BYTES3_LOAD_PADDING(dst, bits, src) \ + do { \ + uint64_t valMacro = ((uint64_t)*((src) + 0)) << 0; \ + valMacro |= ((uint64_t)*((src) + 1)) << 8; \ + valMacro |= ((uint64_t)*((src) + 2)) << 16; \ + *(dst) = (uint64_t)(valMacro<< (bits)); \ + } while (0) + +#define CURVE25519_BYTES3_LOAD(dst, src) \ + do { \ + *(dst) = ((uint64_t)*((src) + 0)) << 0; \ + *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ + *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ + } while (0) + +#define CURVE25519_BYTES4_LOAD(dst, src) \ + do { \ + *(dst) = ((uint64_t)*((src) + 0)) << 0; \ + *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ + *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ + *(dst) |= ((uint64_t)*((src) + 3)) << 24; \ + } while (0) + +#define CURVE25519_BYTES6_LOAD(dst, src) \ + do { \ + *(dst) = (uint64_t)*(src); \ + *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ + *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ + *(dst) |= ((uint64_t)*((src) + 3)) << 24; \ + *(dst) |= ((uint64_t)*((src) + 4)) << 32; \ + *(dst) |= ((uint64_t)*((src) + 5)) << 40; \ + } while (0) + +#define CURVE25519_BYTES7_LOAD(dst, src) \ + do { \ + *(dst) = (uint64_t)*(src); \ + *(dst) |= ((uint64_t)*((src) + 1)) << 8; \ + *(dst) |= ((uint64_t)*((src) + 2)) << 16; \ + *(dst) |= ((uint64_t)*((src) + 3)) << 24; \ + *(dst) |= ((uint64_t)*((src) + 4)) << 32; \ + *(dst) |= ((uint64_t)*((src) + 5)) << 40; \ + *(dst) |= ((uint64_t)*((src) + 6)) << 48; \ + } while (0) + +#define CURVE25519_BYTES3_PADDING_UNLOAD(dst, bits1, bits2, src) \ + do { \ + const uint32_t posMacro = 8 - (bits1); \ + uint32_t valMacro = (uint32_t)(*(src)); \ + uint32_t signMaskMacro= -(valMacro >> 31); \ + uint32_t expand =( (uint32_t)(*((src) + 1))) << (bits2); \ + *((dst) + 0) = (uint8_t)(valMacro >> (0 + posMacro) | (signMaskMacro>> (0 + posMacro))); \ + *((dst) + 1) = (uint8_t)(valMacro >> (8 + posMacro) | (signMaskMacro>> (8 + posMacro))); \ + *((dst) + 2) = (uint8_t)(expand | ((valMacro >> (16 + posMacro)) | (signMaskMacro>> (16 + posMacro)))); \ + } while (0) + +#define CURVE25519_BYTES3_UNLOAD(dst, bits, src) \ + do { \ + const uint32_t posMacro = 8 - (bits); \ + uint32_t valMacro = (uint32_t)(*(src)); \ + uint32_t signMaskMacro= -(valMacro >> 31); \ + *((dst) + 0) = (uint8_t)((valMacro >> (0 + posMacro)) | (signMaskMacro>> (0 + posMacro))); \ + *((dst) + 1) = (uint8_t)((valMacro >> (8 + posMacro)) | (signMaskMacro>> (8 + posMacro))); \ + *((dst) + 2) = (uint8_t)((valMacro >> (16 + posMacro)) | (signMaskMacro>> (16 + posMacro))); \ + } while (0) + +#define CURVE25519_BYTES4_PADDING_UNLOAD(dst, bits, src) \ + do { \ + uint32_t valMacro = (uint32_t)(*(src)); \ + uint32_t signMaskMacro= -(valMacro >> 31); \ + uint32_t expand = ((uint32_t)(*((src) + 1))) << (bits); \ + *((dst) + 0) = (uint8_t)((valMacro >> 0) | (signMaskMacro>> 0)); \ + *((dst) + 1) = (uint8_t)((valMacro >> 8) | (signMaskMacro>> 8)); \ + *((dst) + 2) = (uint8_t)((valMacro >> 16) | (signMaskMacro>> 16)); \ + *((dst) + 3) = (uint8_t)(expand | ((valMacro >> 24) | (signMaskMacro>> 24))); \ + } while (0) + +/** + * Reference RFC 7748 section 5: For X25519, in order to decode 32 random bytes as an integer scalar, + * set the three least significant bits of the first byte and the most significant bit of the last to zero, + * set the second most significant bit of the last byte to 1 and, finally, decode as little-endian. +*/ +#define CURVE25519_DECODE_LITTLE_ENDIAN(dst, src) \ + do { \ + uint32_t ii; \ + for (ii = 0; ii < 32; ii++) { \ + (dst)[ii] = (src)[ii]; \ + } \ + (dst)[0] &= 248; \ + (dst)[31] &= 127; \ + (dst)[31] |= 64; \ + } while (0) + +#define CURVE25519_FP_CSWAP(s, a, b) \ + do { \ + uint32_t tt; \ + const uint32_t tsMacro = 0 - (s); \ + for (uint32_t ii = 0; ii < 10; ii++) { \ + tt = tsMacro & (((uint32_t)(a)[ii]) ^ ((uint32_t)(b)[ii])); \ + (a)[ii] = (int32_t)((uint32_t)(a)[ii] ^ tt); \ + (b)[ii] = (int32_t)((uint32_t)(b)[ii] ^ tt); \ + } \ + } while (0) + +#define CURVE25519_FP51_CSWAP(s, a, b) \ + do { \ + uint64_t tt; \ + const uint64_t tsMacro = 0 - (uint64_t)(s); \ + for (uint32_t ii = 0; ii < 5; ii++) { \ + tt = tsMacro & ((a)[ii] ^ (b)[ii]); \ + (a)[ii] = (a)[ii] ^ tt; \ + (b)[ii] = (b)[ii] ^ tt; \ + } \ + } while (0) + +void TableLookup(GePre *preCompute, int32_t pos, int8_t e); + +void ConditionalMove(GePre *preCompute, const GePre *tableElement, uint32_t indicator); + +void ScalarMultiBase(GeE *out, const uint8_t in[CRYPT_CURVE25519_KEYLEN]); + +#ifdef HITLS_CRYPTO_ED25519 +void PointEncoding(const GeE *point, uint8_t *output, uint32_t outputLen); + +int32_t PointDecoding(GeE *point, const uint8_t in[CRYPT_CURVE25519_KEYLEN]); + +void ScalarMulAdd(uint8_t s[CRYPT_CURVE25519_KEYLEN], const uint8_t a[CRYPT_CURVE25519_KEYLEN], + const uint8_t b[CRYPT_CURVE25519_KEYLEN], const uint8_t c[CRYPT_CURVE25519_KEYLEN]); + +void ModuloL(uint8_t s[CRYPT_CURVE25519_SIGNLEN]); + +void KAMulPlusMulBase(GeE *out, const uint8_t hash[CRYPT_CURVE25519_KEYLEN], + const GeE *p, const uint8_t s[CRYPT_CURVE25519_KEYLEN]); +#endif + +#ifdef HITLS_CRYPTO_X25519 +void ScalarMultiPoint(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]); +#endif + +void FpInvert(Fp25 *out, const Fp25 *a); + +void FpMul(Fp25 *out, const Fp25 *f, const Fp25 *g); + +void FpSquare(Fp25 *out, const Fp25 *in); + +void PolynomialToData(uint8_t out[32], const Fp25 *polynomial); + +void DataToPolynomial(Fp25 *out, const uint8_t data[32]); + +#ifdef HITLS_CRYPTO_X25519 +void CRYPT_X25519_PublicFromPrivate(const uint8_t privateKey[CRYPT_CURVE25519_KEYLEN], + uint8_t publicKey[CRYPT_CURVE25519_KEYLEN]); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_CURVE25519 + +#endif // CURVE25519_LOCAL_H diff --git a/crypto/curve25519/src/curve25519_op.c b/crypto/curve25519/src/curve25519_op.c new file mode 100644 index 00000000..4fee14f9 --- /dev/null +++ b/crypto/curve25519/src/curve25519_op.c @@ -0,0 +1,1644 @@ +/* + * 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. + */ +/* Some of these codes are adapted from https://ed25519.cr.yp.to/software.html */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CURVE25519 + +#include +#include "securec.h" +#include "curve25519_local.h" +#include "bsl_sal.h" + +#define CRYPT_CURVE25519_OPTLEN 32 + +#define CONDITION_COPY(dst, src, indicate) \ + (int32_t)((uint32_t)(dst) ^ (((uint32_t)(dst) ^ (uint32_t)(src)) & (indicate))) + +// process Fp multiplication carry +#define FP_PROCESS_CARRY(h) \ +do { \ + uint64_t carry; \ + uint64_t mask; \ + PROCESS_CARRY_INT64(h##0, h##1, mask, carry, 25); \ + PROCESS_CARRY_INT64(h##5, h##6, mask, carry, 24); \ + \ + PROCESS_CARRY_INT64(h##1, h##2, mask, carry, 24); \ + PROCESS_CARRY_INT64(h##6, h##7, mask, carry, 25); \ + \ + PROCESS_CARRY_INT64(h##2, h##3, mask, carry, 25); \ + PROCESS_CARRY_INT64(h##7, h##8, mask, carry, 24); \ + \ + PROCESS_CARRY_INT64(h##3, h##4, mask, carry, 24); \ + PROCESS_CARRY_INT64(h##8, h##9, mask, carry, 25); \ + \ + PROCESS_CARRY_INT64(h##4, h##5, mask, carry, 25); \ + \ + carry = (uint64_t)h##9 + (1 << 24); \ + mask = MASK_HIGH64(25) & (-(carry >> 63)); \ + h##0 += (int64_t)(19 * ((carry >> 25) | mask)); \ + h##9 -= (int64_t)(MASK_HIGH64(39) & carry); \ + \ + PROCESS_CARRY_INT64(h##5, h##6, mask, carry, 24); \ + PROCESS_CARRY_INT64(h##0, h##1, mask, carry, 25); \ +} while (0) + +// h0...h9 to Fp25 +#define INT64_2_FP25(h, out) \ +do { \ + (out)->data[0] = (int32_t)h##0; \ + (out)->data[1] = (int32_t)h##1; \ + (out)->data[2] = (int32_t)h##2; \ + (out)->data[3] = (int32_t)h##3; \ + (out)->data[4] = (int32_t)h##4; \ + (out)->data[5] = (int32_t)h##5; \ + (out)->data[6] = (int32_t)h##6; \ + (out)->data[7] = (int32_t)h##7; \ + (out)->data[8] = (int32_t)h##8; \ + (out)->data[9] = (int32_t)h##9; \ +} while (0) + +#define FP25_2_INT32(in, out) \ +do { \ + out##0 = (in)->data[0]; \ + out##1 = (in)->data[1]; \ + out##2 = (in)->data[2]; \ + out##3 = (in)->data[3]; \ + out##4 = (in)->data[4]; \ + out##5 = (in)->data[5]; \ + out##6 = (in)->data[6]; \ + out##7 = (in)->data[7]; \ + out##8 = (in)->data[8]; \ + out##9 = (in)->data[9]; \ +} while (0) + +/* out = f * g */ +void FpMul(Fp25 *out, const Fp25 *f, const Fp25 *g) +{ + int32_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; + int32_t g0, g1, g2, g3, g4, g5, g6, g7, g8, g9; + int64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9; + + FP25_2_INT32(f, f); + FP25_2_INT32(g, g); + + int32_t f1_2 = f1 * 2; + int32_t f3_2 = f3 * 2; + int32_t f5_2 = f5 * 2; + int32_t f7_2 = f7 * 2; + int32_t f9_2 = f9 * 2; + + int32_t g1_19 = g1 * 19; + int32_t g2_19 = g2 * 19; + int32_t g3_19 = g3 * 19; + int32_t g4_19 = g4 * 19; + int32_t g5_19 = g5 * 19; + int32_t g6_19 = g6 * 19; + int32_t g7_19 = g7 * 19; + int32_t g8_19 = g8 * 19; + int32_t g9_19 = g9 * 19; + + /* h0 = f0g0 + 38f1g9 + 19f2g8 + 38f3g7 + 19f4g6 + 38f5g5 + 19f6g4 + 38f7g3 + 19f8g2 + 38f9g1 + h1 = f0g1 + f1g0 + 19f2g9 + 19f3g8 + 19f4g7 + 19f5g6 + 19f6g5 + 19f7g4 + 19f8g3 + 19f9g2 + h2 = f0g2 + 2f1g1 + f2g0 + 38f3g9 + 19f4g8 + 38f5g7 + 19f6g6 + 38f7g5 + 19f8g4 + 38f9g2 + h3 = f0g3 + f1g2 + f2g1 + f3g0 + 19f4g9 + 19f5g8 + 19f6g7 + 19f7g6 + 19f8g5 + 19f9g4 + h4 = f0g4 + 2f1g3 + f2g2 + 2f3g1 + f4g0 + 38f5g9 + 19f6g8 + 38f7g7 + 19f8g6 + 38f9g5 + h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + 19f6g9 + 19f7g8 + 19f8g7 + 19f9g6 + h6 = f0g6 + 2f1g5 + f2g4 + 2f3g3 + f4g2 + 2f5g1 + f6g0 + 38f7g9 + 19f8g8 + 38f9g7 + h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + 19f8g9 + 19f9g8 + h8 = f0g8 + 2f1g7 + f2g6 + 2f3g5 + f4g4 + 2f5g3 + f6g2 + 2f7g1 + f8g0 + 38f9g9 + h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 + The calculation is performed by column. */ + + h0 = (int64_t)f0 * g0; + h1 = (int64_t)f0 * g1; + h2 = (int64_t)f0 * g2; + h3 = (int64_t)f0 * g3; + h4 = (int64_t)f0 * g4; + h5 = (int64_t)f0 * g5; + h6 = (int64_t)f0 * g6; + h7 = (int64_t)f0 * g7; + h8 = (int64_t)f0 * g8; + h9 = (int64_t)f0 * g9; + + h0 += (int64_t)f1_2 * g9_19; + h1 += (int64_t)f1 * g0; + h2 += (int64_t)f1_2 * g1; + h3 += (int64_t)f1 * g2; + h4 += (int64_t)f1_2 * g3; + h5 += (int64_t)f1 * g4; + h6 += (int64_t)f1_2 * g5; + h7 += (int64_t)f1 * g6; + h8 += (int64_t)f1_2 * g7; + h9 += (int64_t)f1 * g8; + + h0 += (int64_t)f2 * g8_19; + h1 += (int64_t)f2 * g9_19; + h2 += (int64_t)f2 * g0; + h3 += (int64_t)f2 * g1; + h4 += (int64_t)f2 * g2; + h5 += (int64_t)f2 * g3; + h6 += (int64_t)f2 * g4; + h7 += (int64_t)f2 * g5; + h8 += (int64_t)f2 * g6; + h9 += (int64_t)f2 * g7; + + h0 += (int64_t)f3_2 * g7_19; + h1 += (int64_t)f3 * g8_19; + h2 += (int64_t)f3_2 * g9_19; + h3 += (int64_t)f3 * g0; + h4 += (int64_t)f3_2 * g1; + h5 += (int64_t)f3 * g2; + h6 += (int64_t)f3_2 * g3; + h7 += (int64_t)f3 * g4; + h8 += (int64_t)f3_2 * g5; + h9 += (int64_t)f3 * g6; + + h0 += (int64_t)f4 * g6_19; + h1 += (int64_t)f4 * g7_19; + h2 += (int64_t)f4 * g8_19; + h3 += (int64_t)f4 * g9_19; + h4 += (int64_t)f4 * g0; + h5 += (int64_t)f4 * g1; + h6 += (int64_t)f4 * g2; + h7 += (int64_t)f4 * g3; + h8 += (int64_t)f4 * g4; + h9 += (int64_t)f4 * g5; + + h0 += (int64_t)f5_2 * g5_19; + h1 += (int64_t)f5 * g6_19; + h2 += (int64_t)f5_2 * g7_19; + h3 += (int64_t)f5 * g8_19; + h4 += (int64_t)f5_2 * g9_19; + h5 += (int64_t)f5 * g0; + h6 += (int64_t)f5_2 * g1; + h7 += (int64_t)f5 * g2; + h8 += (int64_t)f5_2 * g3; + h9 += (int64_t)f5 * g4; + + h0 += (int64_t)f6 * g4_19; + h1 += (int64_t)f6 * g5_19; + h2 += (int64_t)f6 * g6_19; + h3 += (int64_t)f6 * g7_19; + h4 += (int64_t)f6 * g8_19; + h5 += (int64_t)f6 * g9_19; + h6 += (int64_t)f6 * g0; + h7 += (int64_t)f6 * g1; + h8 += (int64_t)f6 * g2; + h9 += (int64_t)f6 * g3; + + h0 += (int64_t)f7_2 * g3_19; + h1 += (int64_t)f7 * g4_19; + h2 += (int64_t)f7_2 * g5_19; + h3 += (int64_t)f7 * g6_19; + h4 += (int64_t)f7_2 * g7_19; + h5 += (int64_t)f7 * g8_19; + h6 += (int64_t)f7_2 * g9_19; + h7 += (int64_t)f7 * g0; + h8 += (int64_t)f7_2 * g1; + h9 += (int64_t)f7 * g2; + + h0 += (int64_t)f8 * g2_19; + h1 += (int64_t)f8 * g3_19; + h2 += (int64_t)f8 * g4_19; + h3 += (int64_t)f8 * g5_19; + h4 += (int64_t)f8 * g6_19; + h5 += (int64_t)f8 * g7_19; + h6 += (int64_t)f8 * g8_19; + h7 += (int64_t)f8 * g9_19; + h8 += (int64_t)f8 * g0; + h9 += (int64_t)f8 * g1; + + h0 += (int64_t)f9_2 * g1_19; + h1 += (int64_t)f9 * g2_19; + h2 += (int64_t)f9_2 * g3_19; + h3 += (int64_t)f9 * g4_19; + h4 += (int64_t)f9_2 * g5_19; + h5 += (int64_t)f9 * g6_19; + h6 += (int64_t)f9_2 * g7_19; + h7 += (int64_t)f9 * g8_19; + h8 += (int64_t)f9_2 * g9_19; + h9 += (int64_t)f9 * g0; + + FP_PROCESS_CARRY(h); + + INT64_2_FP25(h, out); +} + +static void FpSquareDoubleCore(Fp25 *out, const Fp25 *in, bool doDouble) +{ + int64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9; + int32_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; + + FP25_2_INT32(in, f); + + int32_t f0_2 = f0 * 2; + int32_t f1_2 = f1 * 2; + int32_t f2_2 = f2 * 2; + int32_t f3_2 = f3 * 2; + int32_t f4_2 = f4 * 2; + int32_t f5_2 = f5 * 2; + int32_t f6_2 = f6 * 2; + int32_t f7_2 = f7 * 2; + + int32_t f9_38 = f9 * 38; + int32_t f8_19 = f8 * 19; + int32_t f7_38 = f7 * 38; + int32_t f6_19 = f6 * 19; + int32_t f5_19 = f5 * 19; + + h0 = (int64_t)f0 * f0; + h1 = (int64_t)f0_2 * f1; + h2 = (int64_t)f0_2 * f2; + h3 = (int64_t)f0_2 * f3; + h4 = (int64_t)f0_2 * f4; + h5 = (int64_t)f0_2 * f5; + h6 = (int64_t)f0_2 * f6; + h7 = (int64_t)f0_2 * f7; + h8 = (int64_t)f0_2 * f8; + h9 = (int64_t)f0_2 * f9; + + h0 += (int64_t)f1_2 * f9_38; + h1 += (int64_t)f2 * f9_38; + h2 += (int64_t)f1_2 * f1; + h3 += (int64_t)f1_2 * f2; + h4 += (int64_t)f1_2 * f3_2; + h5 += (int64_t)f1_2 * f4; + h6 += (int64_t)f1_2 * f5_2; + h7 += (int64_t)f1_2 * f6; + h8 += (int64_t)f1_2 * f7_2; + h9 += (int64_t)f1_2 * f8; + + h0 += (int64_t)f2_2 * f8_19; + h1 += (int64_t)f3_2 * f8_19; + h2 += (int64_t)f3_2 * f9_38; + h3 += (int64_t)f4 * f9_38; + h4 += (int64_t)f2 * f2; + h5 += (int64_t)f2_2 * f3; + h6 += (int64_t)f2_2 * f4; + h7 += (int64_t)f2_2 * f5; + h8 += (int64_t)f2_2 * f6; + h9 += (int64_t)f2_2 * f7; + + h0 += (int64_t)f3_2 * f7_38; + h1 += (int64_t)f4 * f7_38; + h2 += (int64_t)f4_2 * f8_19; + h3 += (int64_t)f5_2 * f8_19; + h4 += (int64_t)f5_2 * f9_38; + h5 += (int64_t)f6 * f9_38; + h6 += (int64_t)f3_2 * f3; + h7 += (int64_t)f3_2 * f4; + h8 += (int64_t)f3_2 * f5_2; + h9 += (int64_t)f3_2 * f6; + + h0 += (int64_t)f4_2 * f6_19; + h1 += (int64_t)f5_2 * f6_19; + h2 += (int64_t)f5_2 * f7_38; + h3 += (int64_t)f6 * f7_38; + h4 += (int64_t)f6_2 * f8_19; + h5 += (int64_t)f7_2 * f8_19; + h6 += (int64_t)f7_2 * f9_38; + h7 += (int64_t)f8 * f9_38; + h8 += (int64_t)f4 * f4; + h9 += (int64_t)f4_2 * f5; + + h0 += (int64_t)f5_2 * f5_19; + h2 += (int64_t)f6 * f6_19; + h4 += (int64_t)f7 * f7_38; + h6 += (int64_t)f8 * f8_19; + h8 += (int64_t)f9 * f9_38; + + if (doDouble) { + h0 *= 2; + h1 *= 2; + h2 *= 2; + h3 *= 2; + h4 *= 2; + h5 *= 2; + h6 *= 2; + h7 *= 2; + h8 *= 2; + h9 *= 2; + } + + FP_PROCESS_CARRY(h); + + INT64_2_FP25(h, out); +} + +/* out = in ^ 2 * 2 */ +static void FpSquareDouble(Fp25 *out, const Fp25 *in) +{ + FpSquareDoubleCore(out, in, true); +} + +/* out = in ^ 2 */ +void FpSquare(Fp25 *out, const Fp25 *in) +{ + FpSquareDoubleCore(out, in, false); +} + +/* out = in1 ^ (4 * 2 ^ (2 * times)) * in2 */ +static void FpMultiSquare(Fp25 *in1, Fp25 *in2, Fp25 *out, int32_t times) +{ + int32_t i; + Fp25 temp1, temp2; + FpSquare(&temp1, in1); + FpSquare(&temp2, &temp1); + for (i = 0; i < times; i++) { + FpSquare(&temp1, &temp2); + FpSquare(&temp2, &temp1); + } + FpMul(out, in2, &temp2); +} + +/* out = a ^ -1 */ +void FpInvert(Fp25 *out, const Fp25 *a) +{ + int32_t i; + Fp25 a0; /* save a^1 */ + Fp25 a1; /* save a^2 */ + Fp25 a2; /* save a^11 */ + Fp25 a3; /* save a^(2^5-1) */ + Fp25 a4; /* save a^(2^10-1) */ + Fp25 a5; /* save a^(2^20-1) */ + Fp25 a6; /* save a^(2^40-1) */ + Fp25 a7; /* save a^(2^50-1) */ + Fp25 a8; /* save a^(2^100-1) */ + Fp25 a9; /* save a^(2^200-1) */ + Fp25 a10; /* save a^(2^250-1) */ + Fp25 temp1, temp2; + + /* We know a×b=1(mod p), then a and b are inverses of mod p, i.e. a=b^(-1), b=a^(-1); + * According to Fermat's little theorem a^(p-1)=1(mod p), so a*a^(p-2)=1(mod p); + * So the inverse element of a is a^(-1) = a^(p-2)(mod p) + * Here it is, p=2^255-19, thus we need to compute a^(2^255-21)(mod(2^255-19)) + */ + + /* a^1 */ + CURVE25519_FP_COPY(a0.data, a->data); + + /* a^2 */ + FpSquare(&a1, &a0); + + /* a^4 */ + FpSquare(&temp1, &a1); + + /* a^8 */ + FpSquare(&temp2, &temp1); + + /* a^9 */ + FpMul(&temp1, &a0, &temp2); + + /* a^11 */ + FpMul(&a2, &a1, &temp1); + + /* a^22 */ + FpSquare(&temp2, &a2); + + /* a^(2^5-1) = a^(9+22) */ + FpMul(&a3, &temp1, &temp2); + + /* a^(2^10-1) = a^(2^10-2^5) * a^(2^5-1) */ + FpSquare(&temp1, &a3); + for (i = 0; i < 2; i++) { // (2 * 2)^2 + FpSquare(&temp2, &temp1); + FpSquare(&temp1, &temp2); + } + FpMul(&a4, &a3, &temp1); + + /* a^(2^20-1) = a^(2^20-2^10) * a^(2^10-1) */ + FpMultiSquare(&a4, &a4, &a5, 4); // (2 * 2) ^ 4 + + /* a^(2^40-1) = a^(2^40-2^20) * a^(2^20-1) */ + FpMultiSquare(&a5, &a5, &a6, 9); // (2 * 2) ^ 9 + + /* a^(2^50-1) = a^(2^50-2^10) * a^(2^10-1) */ + FpMultiSquare(&a6, &a4, &a7, 4); // (2 * 2) ^ 4 + + /* a^(2^100-1) = a^(2^100-2^50) * a^(2^50-1) */ + FpMultiSquare(&a7, &a7, &a8, 24); // (2 * 2) ^ 24 + + /* a^(2^200-1) = a^(2^200-2^100) * a^(2^100-1) */ + FpMultiSquare(&a8, &a8, &a9, 49); // (2 * 2) ^ 49 + + /* a^(2^250-1) = a^(2^250-2^50) * a^(2^50-1) */ + FpMultiSquare(&a9, &a7, &a10, 24); // (2 * 2) ^ 24 + + /* a^(2^5*(2^250-1)) = (a^(2^250-1))^5 */ + FpSquare(&temp1, &a10); + FpSquare(&temp2, &temp1); + FpSquare(&temp1, &temp2); + FpSquare(&temp2, &temp1); + FpSquare(&temp1, &temp2); + + /* The output: a^(2^255-21) = a(2^5*(2^250-1)+11) = a^(2^5*(2^250-1)) * a^11 */ + FpMul(out, &a2, &temp1); +} + +#ifdef HITLS_CRYPTO_ED25519 +/* out = in ^ ((q - 5) / 8) */ +static void FpPowq58(Fp25 *out, Fp25 *in) +{ + Fp25 a, b, c; + int32_t i; + FpSquare(&a, in); + FpSquare(&b, &a); + FpSquare(&b, &b); + FpMul(&b, in, &b); + FpMul(&a, &a, &b); + FpSquare(&a, &a); + FpMul(&a, &b, &a); + FpSquare(&b, &a); + // b = a ^ (2^5) + for (i = 1; i < 5; i++) { + FpSquare(&b, &b); + } + FpMul(&a, &b, &a); + FpSquare(&b, &a); + // b = a ^ (2^10) + for (i = 1; i < 10; i++) { + FpSquare(&b, &b); + } + FpMul(&b, &b, &a); + FpSquare(&c, &b); + + // c = b ^ (2^20) + for (i = 1; i < 20; i++) { + FpSquare(&c, &c); + } + FpMul(&b, &c, &b); + + // b = b ^ (2^10) + for (i = 0; i < 10; i++) { + FpSquare(&b, &b); + } + + FpMul(&a, &b, &a); + FpSquare(&b, &a); + + // b = a ^ (2^50) + for (i = 1; i < 50; i++) { + FpSquare(&b, &b); + } + FpMul(&b, &b, &a); + FpSquare(&c, &b); + + // c = b ^ (2 ^ 100) + for (i = 1; i < 100; i++) { + FpSquare(&c, &c); + } + FpMul(&b, &c, &b); + + // b = b ^ (2^50) + for (i = 0; i < 50; i++) { + FpSquare(&b, &b); + } + FpMul(&a, &b, &a); + FpSquare(&a, &a); + FpSquare(&a, &a); + FpMul(out, &a, in); +} +#endif + +static void PaddingUnload(uint8_t out[32], Fp25 *pFp25) +{ + int32_t *p = pFp25->data; + + /* Take a polynomial form number into a 32-byte array */ + CURVE25519_BYTES4_PADDING_UNLOAD(out, 2, p); /* p0 unload 4 bytes on out[0] expand 2 */ + CURVE25519_BYTES3_PADDING_UNLOAD(out + 4, 2, 3, p + 1); /* p1 unload 3 bytes on out[4] shift 2 expand 3 */ + CURVE25519_BYTES3_PADDING_UNLOAD(out + 7, 3, 5, p + 2); /* p2 unload 3 bytes on out[7] shift 3 expand 5 */ + CURVE25519_BYTES3_PADDING_UNLOAD(out + 10, 5, 6, p + 3); /* p3 unload 3 bytes on out[10] shift 5 expand 6 */ + CURVE25519_BYTES3_UNLOAD(out + 13, 6, p + 4); /* p4 unload 3 bytes on out[13] shift 6 */ + + CURVE25519_BYTES4_PADDING_UNLOAD(out + 16, 1, p + 5); /* p5 unload 4 bytes on out[16] expand 1 */ + CURVE25519_BYTES3_PADDING_UNLOAD(out + 20, 1, 3, p + 6); /* p6 unload 3 bytes on out[20] shift 1 expand 3 */ + CURVE25519_BYTES3_PADDING_UNLOAD(out + 23, 3, 4, p + 7); /* p7 unload 3 bytes on out[23] shift 3 expand 4 */ + CURVE25519_BYTES3_PADDING_UNLOAD(out + 26, 4, 6, p + 8); /* p8 unload 3 bytes on out[26] shift 4 expand 6 */ + CURVE25519_BYTES3_UNLOAD(out + 29, 6, p + 9); /* p9 unload 3 bytes on out[29] shift 6 */ +} + +void PolynomialToData(uint8_t out[32], const Fp25 *polynomial) +{ + Fp25 pFp25; + int32_t *p = pFp25.data; + uint32_t pos; + uint32_t over; + uint32_t mul19; + uint32_t signMask; + + CURVE25519_FP_COPY(p, polynomial->data); + + /* First process, all the carry transport to p[0] */ + mul19 = (uint32_t)p[9] * 19; // mul 19 for mod + over = mul19 + (1 << 24); // plus 1 << 24 for carry + // restricted to 25 bits, shift 31 for sign + signMask = (-(over >> 31)) & MASK_HIGH32(25); + over = (over >> 25) | signMask; // 25 bits + pos = 0; + do { + over = (uint32_t)p[pos] + over; + // first carry is restricted to 25 bits, shift 31 for sign + signMask = (-(over >> 31)) & MASK_HIGH32(25); + over = (over >> 25) | signMask; // 25 bits + pos++; + + over = (uint32_t)p[pos] + over; + // second carry is restricted to 26 bits, shift 31 for sign + signMask = (-(over >> 31)) & MASK_HIGH32(26); + over = (over >> 26) | signMask; // 26 bits + pos++; + } while (pos < 10); // process from 0 to 9, pos < 10 + mul19 = over * 19; // mul 19 for mod + p[0] += (int32_t)mul19; + + /* We subtracted 2^255-19 and get the result + * all polynomial[i] is restricted to 25 bits or 26 bits + */ + pos = 0; + do { + // first polynomial is restricted to 26 bits, shift 31 for sign + signMask = (-((uint32_t)p[pos] >> 31)) & MASK_HIGH32(26); + over = ((uint32_t)p[pos] >> 26) | signMask; // 26 bits + p[pos] = (int32_t)((uint32_t)p[pos] & MASK_LOW32(26)); // 26 bits + pos++; + p[pos] += (int32_t)over; + + // second polynomial is restricted to 25 bits, shift 31 for sign + signMask = (-((uint32_t)p[pos] >> 31)) & MASK_HIGH32(25); + over = ((uint32_t)p[pos] >> 25) | signMask; // 25 bits + p[pos] = (int32_t)((uint32_t)p[pos] & MASK_LOW32(25)); + pos++; + p[pos] += (int32_t)over; + } while (pos < 8); // process form 0 to 7, pos < 8 + + // process p[8], restricted to 26 bits, shift 31 for sign + signMask = (-((uint32_t)p[pos] >> 31)) & MASK_HIGH32(26); + over = ((uint32_t)p[pos] >> 26) | signMask; // 26 bits + p[pos] = (int32_t)((uint32_t)p[pos] & MASK_LOW32(26)); // 26 bits + pos++; + // process p[9] + p[pos] += (int32_t)over; + p[pos] = (int32_t)((uint32_t)p[pos] & MASK_LOW32(25)); // p[9] is restricted to 25 bits + + PaddingUnload(out, &pFp25); +} + +/* unified addition in Extended twist Edwards Coordinate */ +/* out = out + tableElement */ +static void GeAdd(GeE *out, const GePre *tableElement) +{ + Fp25 a; + Fp25 b; + Fp25 c; + Fp25 d; + Fp25 e; + Fp25 f; + Fp25 g; + Fp25 h; + /* a = (Y1 − X1) * (Y2 − X2), b = (Y1 + X1) * (Y2 + X2) + * c = 2 * d * T1 * X2 * Y2, d = 2 * Z1 + * e = b − a, f = d − c, g = d + c, h = b + a + * X3 = e * f, Y3 = g * h, T3 = e * h, Z3 = f * g + */ + CURVE25519_FP_ADD(e.data, out->y.data, out->x.data); + CURVE25519_FP_SUB(f.data, out->y.data, out->x.data); + FpMul(&b, &e, &(tableElement->yplusx)); + FpMul(&a, &f, &(tableElement->yminusx)); + FpMul(&c, &(out->t), &(tableElement->xy2d)); + CURVE25519_FP_ADD(d.data, out->z.data, out->z.data); + CURVE25519_FP_SUB(e.data, b.data, a.data); + CURVE25519_FP_SUB(f.data, d.data, c.data); + CURVE25519_FP_ADD(g.data, d.data, c.data); + CURVE25519_FP_ADD(h.data, b.data, a.data); + FpMul(&(out->x), &e, &f); + FpMul(&(out->y), &h, &g); + FpMul(&(out->z), &g, &f); + FpMul(&(out->t), &e, &h); +} + +#ifdef HITLS_CRYPTO_ED25519 +/* out = out - tableElement */ +static void GeSub(GeE *out, const GePre *tableElement) +{ + Fp25 a; + Fp25 b; + Fp25 c; + Fp25 d; + Fp25 e; + Fp25 f; + Fp25 g; + Fp25 h; + + CURVE25519_FP_ADD(e.data, out->y.data, out->x.data); + CURVE25519_FP_SUB(f.data, out->y.data, out->x.data); + FpMul(&b, &e, &(tableElement->yminusx)); + FpMul(&a, &f, &(tableElement->yplusx)); + FpMul(&c, &(out->t), &(tableElement->xy2d)); + CURVE25519_FP_ADD(d.data, out->z.data, out->z.data); + CURVE25519_FP_SUB(e.data, b.data, a.data); + CURVE25519_FP_ADD(f.data, d.data, c.data); + CURVE25519_FP_SUB(g.data, d.data, c.data); + CURVE25519_FP_ADD(h.data, b.data, a.data); + FpMul(&(out->x), &e, &f); + FpMul(&(out->y), &h, &g); + FpMul(&(out->z), &g, &f); + FpMul(&(out->t), &e, &h); +} +#endif + +/* double in Projective twist Edwards Coordinate */ +static void ProjectiveDouble(GeC *complete, const GeP *projective) +{ + Fp25 tmp; + FpSquare(&(complete->x), &(projective->x)); + FpSquare(&(complete->z), &(projective->y)); + // T = 2 * Z^2 + FpSquareDouble(&(complete->t), &(projective->z)); + CURVE25519_FP_ADD(complete->y.data, projective->x.data, projective->y.data); + FpSquare(&tmp, &(complete->y)); + // tmp = (X1 + Y1) ^ 2, T = 2 * Z^2, X = X1 ^ 2, Y = Z1 ^ 2, Z = Y1 ^ 2 + CURVE25519_FP_ADD(complete->y.data, complete->z.data, complete->x.data); + CURVE25519_FP_SUB(complete->z.data, complete->z.data, complete->x.data); + CURVE25519_FP_SUB(complete->x.data, tmp.data, complete->y.data); + CURVE25519_FP_SUB(complete->t.data, complete->t.data, complete->z.data); +} + +/* Convert complete coordinate to projective coordinate */ +static void GeCompleteToProjective(GeP *out, const GeC *complete) +{ + FpMul(&out->x, &complete->t, &complete->x); + FpMul(&out->y, &complete->z, &complete->y); + FpMul(&out->z, &complete->t, &complete->z); +} + +/* p1 = 16 * p1 */ +static void P1DoubleFourTimes(GeE *p1) +{ + GeP p; + GeC c; + // From extended coordinate to projective coordinate, just ignore T + CURVE25519_FP_COPY(p.x.data, p1->x.data); + CURVE25519_FP_COPY(p.y.data, p1->y.data); + CURVE25519_FP_COPY(p.z.data, p1->z.data); + // double 4 times to get 16p1 + ProjectiveDouble(&c, &p); + GeCompleteToProjective(&p, &c); + ProjectiveDouble(&c, &p); + GeCompleteToProjective(&p, &c); + ProjectiveDouble(&c, &p); + GeCompleteToProjective(&p, &c); + ProjectiveDouble(&c, &p); + FpMul(&p1->x, &c.x, &c.t); + FpMul(&p1->y, &c.y, &c.z); + FpMul(&p1->z, &c.z, &c.t); + FpMul(&p1->t, &c.x, &c.y); +} + +static void SetExtendedBasePoint(GeE *out) +{ + CURVE25519_FP_SET(out->x.data, 0); + CURVE25519_FP_SET(out->y.data, 1); + CURVE25519_FP_SET(out->t.data, 0); + CURVE25519_FP_SET(out->z.data, 1); +} + +/* Multiple with Base point, see paper: High-speed high-security signatures */ +void ScalarMultiBase(GeE *out, const uint8_t in[CRYPT_CURVE25519_KEYLEN]) +{ + uint8_t carry; + // inLen is always 32, buffer needs 32 * 2 = 64 + uint8_t privateKey[64]; + int32_t i; + GePre preCompute; + + // split 32 8bits input into 64 4bits-based number + for (i = 0; i < 32; i++) { + privateKey[i * 2] = in[i] & 15; // and 15 to get low 4 bits, stored in 2i + privateKey[i * 2 + 1] = (in[i] >> 4) & 15; // shift 4 then and 15 to get upper 4 bits, stored in 2i+1 + } + carry = 0; + /** + * change from 0 - 15 to -8 - 7, if privateKey[i] >= 8, carry = 1, privateKey[i] -= 16 + * if privateKey[i] < 8, privateKey[i] = privateKey[i] + */ + for (i = 0; i < 63; i++) { // 0 to 63 + privateKey[i] += carry; + carry = (privateKey[i] + 8) >> 4; // plus 8 then shit 4 to get carry + privateKey[i] -= carry << 4; // left shift 4 + } + // never overflow since we set first bit to 0 of private key + privateKey[63] += carry; // last one is 63 + // set base point X:Y:T:Z -> 0:1:0:1 + SetExtendedBasePoint(out); + for (i = 1; i < 64; i += 2) { // form 1 to 63, process all odd element, increment by 2, i < 64 + TableLookup(&preCompute, i / 2, (int8_t)privateKey[i]); // position goes from 0 to 31, i / 2 = pos + // Fit with paper: Twisted Edwards Curves Revisited + GeAdd(out, &preCompute); + } + // now we have P1, double it four times we have 16P1, P1 is in Extended now, we do double in projective coordinate + P1DoubleFourTimes(out); + // Add P0 with precomute + for (i = 0; i < 64; i += 2) { // form 0 to 62, process all even element, increment by 2, i < 64 + TableLookup(&preCompute, i / 2, (int8_t)privateKey[i]); // position goes from 0 to 31, i / 2 = pos + GeAdd(out, &preCompute); + } + // clean up private key information + BSL_SAL_CleanseData(privateKey, sizeof(privateKey)); +} + +#ifdef HITLS_CRYPTO_ED25519 +void PointEncoding(const GeE *point, uint8_t *output, uint32_t outputLen) +{ + Fp25 zInvert; + Fp25 x; + Fp25 y; + uint8_t xData[CRYPT_CURVE25519_KEYLEN]; + /* x = X / Z, y = Y / Z */ + (void)outputLen; + FpInvert(&zInvert, &point->z); + FpMul(&x, &point->x, &zInvert); + FpMul(&y, &point->y, &zInvert); + PolynomialToData(output, &y); + PolynomialToData(xData, &x); + // PointEcoding writes only 32 bytes data, therefore output[31] is the last one + output[31] ^= (xData[0] & 0x1) << 7; // last one is output[31], get only last bit then shift 7 +} +#endif + +static void FeCmove(Fp25 *dst, const Fp25 *src, const uint32_t indicator) +{ + // if indicator = 1, now it will be 111111111111b.... + const uint32_t indicate = 0 - indicator; + /* des become source if dst->data[i] ^ src->data[i] is in 1111....b, or it does not change if + (dst->data[i] ^ src->data[i]) & indicate is all 0 */ + dst->data[0] = CONDITION_COPY(dst->data[0], src->data[0], indicate); + dst->data[1] = CONDITION_COPY(dst->data[1], src->data[1], indicate); + dst->data[2] = CONDITION_COPY(dst->data[2], src->data[2], indicate); + dst->data[3] = CONDITION_COPY(dst->data[3], src->data[3], indicate); + dst->data[4] = CONDITION_COPY(dst->data[4], src->data[4], indicate); + dst->data[5] = CONDITION_COPY(dst->data[5], src->data[5], indicate); + dst->data[6] = CONDITION_COPY(dst->data[6], src->data[6], indicate); + dst->data[7] = CONDITION_COPY(dst->data[7], src->data[7], indicate); + dst->data[8] = CONDITION_COPY(dst->data[8], src->data[8], indicate); + dst->data[9] = CONDITION_COPY(dst->data[9], src->data[9], indicate); +} + +void ConditionalMove(GePre *preCompute, const GePre *tableElement, uint32_t indicator) +{ + FeCmove(&(preCompute->yplusx), &(tableElement->yplusx), indicator); + FeCmove(&(preCompute->yminusx), &(tableElement->yminusx), indicator); + FeCmove(&(preCompute->xy2d), &(tableElement->xy2d), indicator); +} + +void DataToPolynomial(Fp25 *out, const uint8_t data[32]) +{ + const uint8_t *t = data; + uint64_t p[10]; + uint64_t over; + int32_t i; + uint64_t signMask; + + /* f0, load 32 bits */ + CURVE25519_BYTES4_LOAD(p, t); + /* f1, load 24 bits from t4, shift bits: 26 - 24 - (8 - x) = 0 -> x = 6 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 1, 6, t + 4); + /* f2, load 24 bits from t7, shift bits: 51 - 48 - (8 - x) = 0 -> x = 5 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 2, 5, t + 7); + /* f3, load 24 bits from t10, shift bits: 77 - 72 - (8 - x) = 0 -> x = 3 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 3, 3, t + 10); + /* f4, load 24 bits from t13, shift bits: 102 - 96 - (8 - x) = 0 -> x = 2 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 4, 2, t + 13); + /* f5, load 32 bits from t16 */ + CURVE25519_BYTES4_LOAD(p + 5, t + 16); + /* f6, load 24 bits from t20, shift bits: 153 - 152 - (8 - x) = 0 -> x = 7 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 6, 7, t + 20); + /* f7, load 24 bits from t23, shift bits: 179 - 176 - (8 - x) = 0 -> x = 5 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 7, 5, t + 23); + /* f8, load 24 bits from t26, shift bits: 204 - 200 - (8 - x) = 0 -> x = 4 */ + CURVE25519_BYTES3_LOAD_PADDING(p + 8, 4, t + 26); + /* f9, load 24 bits from t29, shift bits: 230 - 224 - (8 - x) = 0 -> x = 2 */ + CURVE25519_BYTES3_LOAD(p + 9, t + 29); + p[9] = (p[9] & 0x7fffff) << 2; /* p9 is 25 bits, left shift 2 */ + + /* Limiting the number of bits, exchange 2^1 to 2^25.5, turn into polynomial representation */ + /* f9->f0, shift 24 for carry */ + over = p[9] + (1 << 24); + signMask = MASK_HIGH64(25) & (-((over) >> 63)); // shift 63 bits for sign, mask 25 bits + p[0] += ((over >> 25) | signMask) * 19; // 24 bits plus sign is 25, mul 19 for mod + p[9] -= MASK_HIGH64(39) & over; // 64 - 25 = 39 bits mask + + /* f1->f2, restricted to 24 bits */ + PROCESS_CARRY(p[1], p[2], signMask, over, 24); + /* f3->f4, restricted to 24 bits */ + PROCESS_CARRY(p[3], p[4], signMask, over, 24); + /* f5->f6, restricted to 24 bits */ + PROCESS_CARRY(p[5], p[6], signMask, over, 24); + /* f7->f8, restricted to 24 bits */ + PROCESS_CARRY(p[7], p[8], signMask, over, 24); + + /* f0->f1, restricted to 25 bits */ + PROCESS_CARRY(p[0], p[1], signMask, over, 25); + /* f2->f3, restricted to 25 bits */ + PROCESS_CARRY(p[2], p[3], signMask, over, 25); + /* f4->f5, restricted to 25 bits */ + PROCESS_CARRY(p[4], p[5], signMask, over, 25); + /* f6->f7, restricted to 25 bits */ + PROCESS_CARRY(p[6], p[7], signMask, over, 25); + /* f8->f9, restricted to 25 bits */ + PROCESS_CARRY(p[8], p[9], signMask, over, 25); + + /* After process carry, polynomial every term would not exceed 32 bits, convert form 0 to 9, i < 10 */ + for (i = 0; i < 10; i++) { + out->data[i] = (int32_t)p[i]; + } +} + +#ifdef HITLS_CRYPTO_ED25519 +static bool CheckZero(Fp25 *x) +{ + uint8_t tmp[32]; + const uint8_t zero[32] = {0}; + PolynomialToData(tmp, x); + if (memcmp(tmp, zero, sizeof(zero)) == 0) { + return true; + } else { + return false; + } +} + +static uint8_t GetXBit(Fp25 *in) +{ + uint8_t tmp[32]; + PolynomialToData(tmp, in); + + return tmp[0] & 0x1; +} + +static const Fp25 SQRTM1 = {{-32595792, -7943725, 9377950, 3500415, 12389472, -272473, + -25146209, -2005654, 326686, 11406482}}; +static const Fp25 D = {{-10913610, 13857413, -15372611, 6949391, 114729, -8787816, + -6275908, -3247719, -18696448, -12055116}}; + +int32_t PointDecoding(GeE *point, const uint8_t in[CRYPT_CURVE25519_KEYLEN]) +{ + Fp25 u, v, v3, x2, result; + // get the last block (31), shift 7 for first bit + uint8_t x0 = in[31] >> 7; + DataToPolynomial(&(point->y), in); + + CURVE25519_FP_SET(point->z.data, 1); + FpSquare(&u, &(point->y)); + FpMul(&v, &u, &D); + CURVE25519_FP_SUB(u.data, u.data, point->z.data); + CURVE25519_FP_ADD(v.data, v.data, point->z.data); + + FpSquare(&v3, &v); + FpMul(&v3, &v3, &v); + FpSquare(&(point->x), &v3); + FpMul(&(point->x), &(point->x), &v); + FpMul(&(point->x), &(point->x), &u); + + /* x = x ^ ((q - 5) / 8) */ + FpPowq58(&(point->x), &(point->x)); + + FpMul(&(point->x), &(point->x), &v3); + FpMul(&(point->x), &(point->x), &u); + FpSquare(&x2, &(point->x)); + FpMul(&x2, &x2, &v); + CURVE25519_FP_SUB(result.data, x2.data, u.data); + + if (CheckZero(&result) == false) { + CURVE25519_FP_ADD(result.data, x2.data, u.data); + if (CheckZero(&result) == false) { + return 1; + } + FpMul(&(point->x), &(point->x), &SQRTM1); + } + uint8_t bit = GetXBit(&(point->x)); + if (bit != x0) { + CURVE25519_FP_NEGATE(point->x.data, point->x.data); + } + FpMul(&(point->t), &(point->x), &(point->y)); + + return 0; +} + +static void ScalarMulAddPreLoad(const uint8_t in[CRYPT_CURVE25519_KEYLEN], + uint64_t out[UINT8_32_21BITS_BLOCKNUM]) +{ + CURVE25519_BYTES3_LOAD(&out[0], in); + out[0] = out[0] & MASK_64_LOW21; + + CURVE25519_BYTES4_LOAD(&out[1], in + 2); // 1: load 4 bytes form position 2 + out[1] = MASK_64_LOW21 & (out[1] >> 5); // 1: 8 - ((3 * 8) mod 21) mod 8 = 5 + + CURVE25519_BYTES3_LOAD(&out[2], in + 5); // 2: load 3 bytes form position 5 + out[2] = MASK_64_LOW21 & (out[2] >> 2); // 2: 8 - ((6 * 8) mod 21) mod 8 = 2 + + CURVE25519_BYTES4_LOAD(&out[3], in + 7); // 3: load 4 bytes form position 7 + out[3] = MASK_64_LOW21 & (out[3] >> 7); // 3: 8 - ((8 * 8) mod 21) mod 8 = 7 + + CURVE25519_BYTES4_LOAD(&out[4], in + 10); // 4: load 4 bytes form position 10 + out[4] = MASK_64_LOW21 & (out[4] >> 4); // 4: 8 - ((11 * 8) mod 21) mod 8 = 4 + + CURVE25519_BYTES3_LOAD(&out[5], in + 13); // 5: load 3 bytes form position 13 + out[5] = MASK_64_LOW21 & (out[5] >> 1); // 5: 8 - ((14 * 8) mod 21) mod 8 = 1 + + CURVE25519_BYTES4_LOAD(&out[6], in + 15); // 6: load 4 bytes form position 15 + out[6] = MASK_64_LOW21 & (out[6] >> 6); // 6: 8 - ((16 * 8) mod 21) mod 8 = 6 + + CURVE25519_BYTES3_LOAD(&out[7], in + 18); // 7: load 3 bytes form position 18 + out[7] = MASK_64_LOW21 & (out[7] >> 3); // 7: 8 - ((19 * 8) mod 21) mod 8 = 3 + + CURVE25519_BYTES3_LOAD(&out[8], in + 21); // 8: load 3 bytes form position 21 + out[8] = MASK_64_LOW21 & out[8]; // 8: ((22 * 8) mod 21) mod 8 = 0 + + CURVE25519_BYTES4_LOAD(&out[9], in + 23); // 9: load 4 bytes form position 23 + out[9] = MASK_64_LOW21 & (out[9] >> 5); // 9: 8 - ((24 * 8) mod 21) mod 8 = 5 + + CURVE25519_BYTES3_LOAD(&out[10], in + 26); // 10: load 3 bytes form position 26 + out[10] = MASK_64_LOW21 & (out[10] >> 2); // 10: 8 - ((27 * 8) mod 21) mod 8 = 2 + + CURVE25519_BYTES4_LOAD(&out[11], in + 28); // 11: load 4 bytes form position 28 + out[11] = (out[11] >> 7); // 11: 8 - ((29 * 8) mod 21) mod 8 = 7 +} + +static void ModuloLPreLoad(const uint8_t s[CRYPT_CURVE25519_SIGNLEN], uint64_t s21Bits[UINT8_64_21BITS_BLOCKNUM]) +{ + CURVE25519_BYTES3_LOAD(&s21Bits[0], s); + s21Bits[0] = s21Bits[0] & MASK_64_LOW21; + + CURVE25519_BYTES4_LOAD(&s21Bits[1], s + 2); // 1: load 4 bytes form position 2 + s21Bits[1] = MASK_64_LOW21 & (s21Bits[1] >> 5); // 1: 8 - ((3 * 8) mod 21) mod 8 = 5 + + CURVE25519_BYTES3_LOAD(&s21Bits[2], s + 5); // 2: load 3 bytes form position 5 + s21Bits[2] = MASK_64_LOW21 & (s21Bits[2] >> 2); // 2: 8 - ((6 * 8) mod 21) mod 8 = 2 + + CURVE25519_BYTES4_LOAD(&s21Bits[3], s + 7); // 3: load 4 bytes form position 7 + s21Bits[3] = MASK_64_LOW21 & (s21Bits[3] >> 7); // 3: 8 - ((8 * 8) mod 21) mod 8 = 7 + + CURVE25519_BYTES4_LOAD(&s21Bits[4], s + 10); // 4: load 4 bytes form position 10 + s21Bits[4] = MASK_64_LOW21 & (s21Bits[4] >> 4); // 4: 8 - ((11 * 8) mod 21) mod 8 = 4 + + CURVE25519_BYTES3_LOAD(&s21Bits[5], s + 13); // 5: load 3 bytes form position 13 + s21Bits[5] = MASK_64_LOW21 & (s21Bits[5] >> 1); // 5: 8 - ((14 * 8) mod 21) mod 8 = 1 + + CURVE25519_BYTES4_LOAD(&s21Bits[6], s + 15); // 6: load 4 bytes form position 15 + s21Bits[6] = MASK_64_LOW21 & (s21Bits[6] >> 6); // 6: 8 - ((16 * 8) mod 21) mod 8 = 6 + + CURVE25519_BYTES3_LOAD(&s21Bits[7], s + 18); // 7: load 3 bytes form position 18 + s21Bits[7] = MASK_64_LOW21 & (s21Bits[7] >> 3); // 7: 8 - ((19 * 8) mod 21) mod 8 = 3 + + CURVE25519_BYTES3_LOAD(&s21Bits[8], s + 21); // 8: load 3 bytes form position 21 + s21Bits[8] = MASK_64_LOW21 & s21Bits[8]; // 8: ((22 * 8) mod 21) mod 8 = 0 + + CURVE25519_BYTES4_LOAD(&s21Bits[9], s + 23); // 9: load 4 bytes form position 23 + s21Bits[9] = MASK_64_LOW21 & (s21Bits[9] >> 5); // 9: 8 - ((24 * 8) mod 21) mod 8 = 5 + + CURVE25519_BYTES3_LOAD(&s21Bits[10], s + 26); // 10: load 3 bytes form position 26 + s21Bits[10] = MASK_64_LOW21 & (s21Bits[10] >> 2); // 10: 8 - ((27 * 8) mod 21) mod 8 = 2 + + CURVE25519_BYTES4_LOAD(&s21Bits[11], s + 28); // 11: load 4 bytes form position 28 + s21Bits[11] = MASK_64_LOW21 & (s21Bits[11] >> 7); // 11: 8 - ((29 * 8) mod 21) mod 8 = 7 + + CURVE25519_BYTES4_LOAD(&s21Bits[12], s + 31); // 12: load 4 bytes form position 31 + s21Bits[12] = MASK_64_LOW21 & (s21Bits[12] >> 4); // 12: 8 - ((32 * 8) mod 21) mod 8 = 4 + + CURVE25519_BYTES3_LOAD(&s21Bits[13], s + 34); // 13: load 3 bytes form position 34 + s21Bits[13] = MASK_64_LOW21 & (s21Bits[13] >> 1); // 13: 8 - ((35 * 8) mod 21) mod 8 = 1 + + CURVE25519_BYTES4_LOAD(&s21Bits[14], s + 36); // 14: load 4 bytes form position 36 + s21Bits[14] = MASK_64_LOW21 & (s21Bits[14] >> 6); // 14: 8 - ((37 * 8) mod 21) mod 8 = 6 + + CURVE25519_BYTES3_LOAD(&s21Bits[15], s + 39); // 15: load 3 bytes form position 39 + s21Bits[15] = MASK_64_LOW21 & (s21Bits[15] >> 3); // 15: 8 - ((40 * 8) mod 21) mod 8 = 3 + + CURVE25519_BYTES3_LOAD(&s21Bits[16], s + 42); // 16: load 3 bytes form position 42 + s21Bits[16] = MASK_64_LOW21 & s21Bits[16]; // 16: ((43 * 8) mod 21) mod 8 = 0 + + CURVE25519_BYTES4_LOAD(&s21Bits[17], s + 44); // 17: load 4 bytes form position 44 + s21Bits[17] = MASK_64_LOW21 & (s21Bits[17] >> 5); // 17: 8 - ((45 * 8) mod 21) mod 8 = 5 + + CURVE25519_BYTES3_LOAD(&s21Bits[18], s + 47); // 18: load 3 bytes form position 47 + s21Bits[18] = MASK_64_LOW21 & (s21Bits[18] >> 2); // 18: 8 - ((48 * 8) mod 21) mod 8 = 2 + + CURVE25519_BYTES4_LOAD(&s21Bits[19], s + 49); // 19: load 4 bytes form position 49 + s21Bits[19] = MASK_64_LOW21 & (s21Bits[19] >> 7); // 19: 8 - ((50 * 8) mod 21) mod 8 = 7 + + CURVE25519_BYTES4_LOAD(&s21Bits[20], s + 52); // 20: load 4 bytes form position 52 + s21Bits[20] = MASK_64_LOW21 & (s21Bits[20] >> 4); // 20: 8 - ((53 * 8) mod 21) mod 8 = 4 + + CURVE25519_BYTES3_LOAD(&s21Bits[21], s + 55); // 21: load 3 bytes form position 55 + s21Bits[21] = MASK_64_LOW21 & (s21Bits[21] >> 1); // 21: 8 - ((56 * 8) mod 21) mod 8 = 1 + + CURVE25519_BYTES4_LOAD(&s21Bits[22], s + 57); // 22: load 4 bytes form position 57 + s21Bits[22] = MASK_64_LOW21 & (s21Bits[22] >> 6); // 22: 8 - ((58 * 8) mod 21) mod 8 = 6 + + CURVE25519_BYTES4_LOAD(&s21Bits[23], s + 60); // 23: load 4 bytes form position 60 + s21Bits[23] = s21Bits[23] >> 3; // 23: 8 - ((61 * 8) mod 21) mod 8 = 3 +} + +static void UnloadTo8Bits(uint8_t s8Bits[CRYPT_CURVE25519_OPTLEN], uint64_t s21Bits[UINT8_64_21BITS_BLOCKNUM]) +{ + s8Bits[0] = (uint8_t)s21Bits[0]; + + // 1: load from 8 on block 0 + s8Bits[1] = (uint8_t)(s21Bits[0] >> 8); + + // 2: load from (16 + 1) to 21 on block 0 and 1 to 3 on block 1, 8 - 3 = 5 + s8Bits[2] = (uint8_t)((s21Bits[0] >> 16) | (s21Bits[1] << 5)); + + // 3: load from (3 + 1) on block 1 + s8Bits[3] = (uint8_t)(s21Bits[1] >> 3); + + // 4: load from (11 + 1) on block 1 + s8Bits[4] = (uint8_t)(s21Bits[1] >> 11); + + // 5: load from (19 + 1) to 21 on block 1 and 1 to 6 on block 2, 8 - 6 = 2 + s8Bits[5] = (uint8_t)((s21Bits[1] >> 19) | (s21Bits[2] << 2)); + + // 6: load from (6 + 1) on block 2 + s8Bits[6] = (uint8_t)(s21Bits[2] >> 6); + + // 7: load from (14 + 1) to 21 on block 2 and 1 on block 3, 8 - 7 = 1 + s8Bits[7] = (uint8_t)((s21Bits[2] >> 14) | (s21Bits[3] << 7)); + + // 8: load from (1 + 1) on block 3 + s8Bits[8] = (uint8_t)(s21Bits[3] >> 1); + + // 9: load from (9 + 1) on block 3 + s8Bits[9] = (uint8_t)(s21Bits[3] >> 9); + + // 10: load from (17 + 1) to 21 on block 3 and 1 to 4 on block 4, 8 - 4 = 4 + s8Bits[10] = (uint8_t)((s21Bits[3] >> 17) | (s21Bits[4] << 4)); + + // 11: load from (4 + 1) on block 4 + s8Bits[11] = (uint8_t)(s21Bits[4] >> 4); + + // 12: load from (12 + 1) on block 4 + s8Bits[12] = (uint8_t)(s21Bits[4] >> 12); + + // 13: load from (20 + 1) on block 4 and 1 to 7 on block 5, 8 - 7 = 1 + s8Bits[13] = (uint8_t)((s21Bits[4] >> 20) | (s21Bits[5] << 1)); + + // 14: load from (7 + 1) on block 5 + s8Bits[14] = (uint8_t)(s21Bits[5] >> 7); + + // 15: load from (15 + 1) to 21 on block 5 and 1 to 2 on block 6, 8 - 2 = 6 + s8Bits[15] = (uint8_t)((s21Bits[5] >> 15) | (s21Bits[6] << 6)); + + // 16: load from (2 + 1) on block 6 + s8Bits[16] = (uint8_t)(s21Bits[6] >> 2); + + // 17: load from (10 + 1) on block 6 + s8Bits[17] = (uint8_t)(s21Bits[6] >> 10); + + // 18: load from (18 + 1) to 21 on block 6 and 1 to 5 on block 7, 8 - 5 = 3 + s8Bits[18] = (uint8_t)((s21Bits[6] >> 18) | (s21Bits[7] << 3)); + + // 19: load from (5 + 1) on block 7 + s8Bits[19] = (uint8_t)(s21Bits[7] >> 5); + + // 20: load from (13 + 1) on block 7 + s8Bits[20] = (uint8_t)(s21Bits[7] >> 13); + + // 21: load 8bits on block 8 + s8Bits[21] = (uint8_t)s21Bits[8]; + + // 22: load from (8 + 1) on block 8 + s8Bits[22] = (uint8_t)(s21Bits[8] >> 8); + + // 23: load from (16 + 1) to 21 on block 8 and 1 to 3 on block 9, 8 - 3 = 5 + s8Bits[23] = (uint8_t)((s21Bits[8] >> 16) | (s21Bits[9] << 5)); + + // 24: load from (3 + 1) on block 9 + s8Bits[24] = (uint8_t)(s21Bits[9] >> 3); + + // 25: load from (11 + 1) on block 9 + s8Bits[25] = (uint8_t)(s21Bits[9] >> 11); + + // 26: load from (19 + 1) to 21 on block 9 and 1 to 6 on block 10, 8 - 6 = 2 + s8Bits[26] = (uint8_t)((s21Bits[9] >> 19) | (s21Bits[10] << 2)); + + // 27: load from (6 + 1) on block 10 + s8Bits[27] = (uint8_t)(s21Bits[10] >> 6); + + // 28: load from (14 + 1) to 21 on block 10 and 1 on block 11, 8 - 7 = 1 + s8Bits[28] = (uint8_t)((s21Bits[10] >> 14) | (s21Bits[11] << 7)); + + // 29: load from (1 + 1) on block 11 + s8Bits[29] = (uint8_t)(s21Bits[11] >> 1); + + // 30: load from (9 + 1) on block 11 + s8Bits[30] = (uint8_t)(s21Bits[11] >> 9); + + // 31: load from (17 + 1) on block 11 + s8Bits[31] = (uint8_t)(s21Bits[11] >> 17); +} + +static void ModuloLCore(uint64_t s21Bits[UINT8_64_21BITS_BLOCKNUM]) +{ + int32_t i; + uint64_t signMask1, signMask2; + uint64_t carry1, carry2; + + // multiply by l0, start with {11, 12, 13, 14, 15, 16} to {6, 7, 8, 9, 10, 11, 12} + CURVE25519_MULTI_BY_L0(s21Bits, 11); + CURVE25519_MULTI_BY_L0(s21Bits, 10); + CURVE25519_MULTI_BY_L0(s21Bits, 9); + CURVE25519_MULTI_BY_L0(s21Bits, 8); + CURVE25519_MULTI_BY_L0(s21Bits, 7); + CURVE25519_MULTI_BY_L0(s21Bits, 6); + + // need to process carry to prevent overflow, process carry from 6->7, 8->9 ... 16->17, increment by 2 + for (i = 6; i <= 16; i += 2) { + // 21 bits minus sign is 20 bits + PROCESS_CARRY(s21Bits[i], s21Bits[i + 1], signMask1, carry1, 20); + } + + // process carry from 7->8, 9->10 ... 15->16, increment by 2 + for (i = 7; i <= 15; i += 2) { + // 21 bits minus sign bit is 20 bits + PROCESS_CARRY(s21Bits[i], s21Bits[i + 1], signMask2, carry2, 20); + } + + // {5, 6, 7, 8, 9, 10} to {0, 1, 2, 3, 4, 5, 6} + CURVE25519_MULTI_BY_L0(s21Bits, 5); + CURVE25519_MULTI_BY_L0(s21Bits, 4); + CURVE25519_MULTI_BY_L0(s21Bits, 3); + CURVE25519_MULTI_BY_L0(s21Bits, 2); + CURVE25519_MULTI_BY_L0(s21Bits, 1); + CURVE25519_MULTI_BY_L0(s21Bits, 0); + + // process carry again, from 0->1, 2->3 ... 10->11, increment by 2 + for (i = 0; i <= 10; i += 2) { + // 21 bits minus sign bit is 20 bits + PROCESS_CARRY(s21Bits[i], s21Bits[i + 1], signMask1, carry1, 20); + } + + // from 1->2, 3->4 ... 11->12, increment by 2 + for (i = 1; i <= 11; i += 2) { + // 21 bits minus sign is 20 bits + PROCESS_CARRY(s21Bits[i], s21Bits[i + 1], signMask2, carry2, 20); + } + + CURVE25519_MULTI_BY_L0(s21Bits, 0); + + // process carry from 0 to 11 + for (i = 0; i <= 11; i++) { + PROCESS_CARRY_UNSIGN(s21Bits[i], s21Bits[i + 1], signMask1, carry1, 21); // s21Bits is 21 bits + } + + CURVE25519_MULTI_BY_L0(s21Bits, 0); + + // from 0 to 10 + for (i = 0; i <= 10; i++) { + PROCESS_CARRY_UNSIGN(s21Bits[i], s21Bits[i + 1], signMask1, carry1, 21); // s21Bits is 21 bits + } +} + +void ModuloL(uint8_t s[CRYPT_CURVE25519_SIGNLEN]) +{ + // 24 of 21 bits block + uint64_t s21Bits[UINT8_64_21BITS_BLOCKNUM] = {0}; + + ModuloLPreLoad(s, s21Bits); + + ModuloLCore(s21Bits); + + UnloadTo8Bits(s, s21Bits); +} + +static void MulAdd(uint64_t s21Bits[UINT8_64_21BITS_BLOCKNUM], const uint64_t a21Bits[UINT8_32_21BITS_BLOCKNUM], + const uint64_t b21Bits[UINT8_32_21BITS_BLOCKNUM], const uint64_t c21Bits[UINT8_32_21BITS_BLOCKNUM]) +{ + // s0 = c0 + a0b0 + s21Bits[0] = c21Bits[0] + a21Bits[0] * b21Bits[0]; + + // s1 = c1 + a0b1 + a1b0 + s21Bits[1] = c21Bits[1] + a21Bits[0] * b21Bits[1] + a21Bits[1] * b21Bits[0]; + + // s2 = c2 + a0b2 + b1a1 + a2b0 + s21Bits[2] = c21Bits[2] + a21Bits[0] * b21Bits[2] + a21Bits[1] * b21Bits[1] + a21Bits[2] * b21Bits[0]; + + // s3 = c3 + a0b3 + a1b2 + a2b1 + a3b0 + s21Bits[3] = c21Bits[3] + a21Bits[0] * b21Bits[3] + a21Bits[1] * b21Bits[2] + + a21Bits[2] * b21Bits[1] + a21Bits[3] * b21Bits[0]; // a2b1 + a3b0 + + // s4 = c4 + a0b4 +a1b3 + a2b2 + a3b1 + a4b0 + s21Bits[4] = c21Bits[4] + a21Bits[0] * b21Bits[4] + a21Bits[1] * b21Bits[3] + + a21Bits[2] * b21Bits[2] + a21Bits[3] * b21Bits[1] + a21Bits[4] * b21Bits[0]; // a2b2 + a3b1 + a4b0 + + // s5 = c5 + a0b5 + a1b4 + a2b3 + a3b2 + a4b1 + a5b0 + s21Bits[5] = c21Bits[5] + a21Bits[0] * b21Bits[5] + a21Bits[1] * b21Bits[4] + a21Bits[2] * b21Bits[3] + + a21Bits[3] * b21Bits[2] + a21Bits[4] * b21Bits[1] + a21Bits[5] * b21Bits[0]; // a3b2 + a4b1 + a5b0 + + // s6 = c6 + a0b6 + a1b5 + a2b4 + a3b3 + a2b4 + a5b1 + a6b0 + s21Bits[6] = c21Bits[6] + a21Bits[0] * b21Bits[6] + a21Bits[1] * b21Bits[5] + a21Bits[2] * b21Bits[4] + + a21Bits[3] * b21Bits[3] + a21Bits[4] * b21Bits[2] + a21Bits[5] * b21Bits[1] + // a3b3 + a2b4 + a5b1 + a21Bits[6] * b21Bits[0]; // a6b0 + + // s7 = c7 + a0b7 + a1b6 + a2b5 + a3b4 + a4b3 + a5b2 + a6b1 + a7b0 + s21Bits[7] = c21Bits[7] + a21Bits[0] * b21Bits[7] + a21Bits[1] * b21Bits[6] + a21Bits[2] * b21Bits[5] + + a21Bits[3] * b21Bits[4] + a21Bits[4] * b21Bits[3] + a21Bits[5] * b21Bits[2] + // a3b4 + a4b3 + a5b2 + a21Bits[6] * b21Bits[1] + a21Bits[7] * b21Bits[0]; // a6b1 + a7b0 + + // s8 = c8 + a0b8 + a1b7 + a2b6 + a3b5 + a4b4 + a5b3 + a6b2 + a7b1 + a8b0 + s21Bits[8] = c21Bits[8] + a21Bits[0] * b21Bits[8] + a21Bits[1] * b21Bits[7] + a21Bits[2] * b21Bits[6] + + a21Bits[3] * b21Bits[5] + a21Bits[4] * b21Bits[4] + a21Bits[5] * b21Bits[3] + // a3b5 + a4b4 + a5b3 + a21Bits[6] * b21Bits[2] + a21Bits[7] * b21Bits[1] + a21Bits[8] * b21Bits[0]; // a6b2 + a7b1 + a8b0 + + // s9 = c9 + a0b9 + a1b8 + a2b7 + a3b6 + a4b5 + a5b4 + a6b3 + a7b2 + a8b1 + a9b0 + s21Bits[9] = c21Bits[9] + a21Bits[0] * b21Bits[9] + a21Bits[1] * b21Bits[8] + a21Bits[2] * b21Bits[7] + + a21Bits[3] * b21Bits[6] + a21Bits[4] * b21Bits[5] + a21Bits[5] * b21Bits[4] + // a3b6 + a4b5 + a5b4 + a21Bits[6] * b21Bits[3] + a21Bits[7] * b21Bits[2] + a21Bits[8] * b21Bits[1] + // a6b3 + a7b2 + a8b1 + a21Bits[9] * b21Bits[0]; // a9b0 + + // s10 = c10 + a0b10 + a1b9 + a2b8 + a3b7 + a4b6 + a5b5 + a6b4 + a7b3 + a8b2 + a9b1 + a10b0 + s21Bits[10] = c21Bits[10] + a21Bits[0] * b21Bits[10] + a21Bits[1] * b21Bits[9] + a21Bits[2] * b21Bits[8] + + a21Bits[3] * b21Bits[7] + a21Bits[4] * b21Bits[6] + a21Bits[5] * b21Bits[5] + // a3b7 + a4b6 + a5b5 + a21Bits[6] * b21Bits[4] + a21Bits[7] * b21Bits[3] + a21Bits[8] * b21Bits[2] + // a6b4 + a7b3 + a8b2 + a21Bits[9] * b21Bits[1] + a21Bits[10] * b21Bits[0]; // a9b1 + a10b0 + + // s11 = c11 + a0b11 + a1b10 + a2b9 + a3b8 + a4b7 + a5b6 + a6b5 + a7b4 + a8b3 + a9b2 + a10b1 + a11b0 + s21Bits[11] = c21Bits[11] + a21Bits[0] * b21Bits[11] + a21Bits[1] * b21Bits[10] + a21Bits[2] * b21Bits[9] + + a21Bits[3] * b21Bits[8] + a21Bits[4] * b21Bits[7] + a21Bits[5] * b21Bits[6] + // a3b8 + a4b7 + a5b6 + a21Bits[6] * b21Bits[5] + a21Bits[7] * b21Bits[4] + a21Bits[8] * b21Bits[3] + // a6b5 + a7b4 + a8b3 + a21Bits[9] * b21Bits[2] + a21Bits[10] * b21Bits[1] + a21Bits[11] * b21Bits[0]; // a9b2 + a10b1 + a11b0 + + // s12 = a1b11 + a2b10 + a3b9 + a4b8 + a5b7 + a6b6 + a7b5 + a8b4 + a9b3 + a10b2 + a11b1 + s21Bits[12] = a21Bits[1] * b21Bits[11] + a21Bits[2] * b21Bits[10] + a21Bits[3] * b21Bits[9] + + a21Bits[4] * b21Bits[8] + a21Bits[5] * b21Bits[7] + a21Bits[6] * b21Bits[6] + // a4b8 + a5b7 + a6b6 + a21Bits[7] * b21Bits[5] + a21Bits[8] * b21Bits[4] + a21Bits[9] * b21Bits[3] + // a7b5 + a8b4 + a9b3 + a21Bits[10] * b21Bits[2] + a21Bits[11] * b21Bits[1]; // a10b2 + a11b1 + + // s13 = a2b11 + a3b10 + a4b9 + a5b8 + a6b7 + a7b6 + a8b5 + a9b4 + a10b3 + a11b2 + s21Bits[13] = a21Bits[2] * b21Bits[11] + a21Bits[3] * b21Bits[10] + a21Bits[4] * b21Bits[9] + + a21Bits[5] * b21Bits[8] + a21Bits[6] * b21Bits[7] + a21Bits[7] * b21Bits[6] + // a5b8 + a6b7 + a7b6 + a21Bits[8] * b21Bits[5] + a21Bits[9] * b21Bits[4] + a21Bits[10] * b21Bits[3] + // a8b5 + a9b4 + a10b3 + a21Bits[11] * b21Bits[2]; // a11b2 + + // s14 = a3b11 + a4b10 + a5b9 + a6b8 + a7b7 + a8b6 + a9b5 + a10b4 + a11b3 + s21Bits[14] = a21Bits[3] * b21Bits[11] + a21Bits[4] * b21Bits[10] + a21Bits[5] * b21Bits[9] + + a21Bits[6] * b21Bits[8] + a21Bits[7] * b21Bits[7] + a21Bits[8] * b21Bits[6] + // a6b8 + a7b7 + a8b6 + a21Bits[9] * b21Bits[5] + a21Bits[10] * b21Bits[4] + a21Bits[11] * b21Bits[3]; // a9b5 + a10b4 + a11b3 + + // s15 = a4b11 + a5b10 + a6b9 + a7b8 + a8b7 + a9b6 + a10b5 + a11b4 + s21Bits[15] = a21Bits[4] * b21Bits[11] + a21Bits[5] * b21Bits[10] + a21Bits[6] * b21Bits[9] + + a21Bits[7] * b21Bits[8] + a21Bits[8] * b21Bits[7] + a21Bits[9] * b21Bits[6] + // a7b8 + a8b7 + a9b6 + a21Bits[10] * b21Bits[5] + a21Bits[11] * b21Bits[4]; // a10b5 + a11b4 + + // s16 = a5b11 + a6b10 + a7b9 + a8b8 + a9b7 + a10b6 + a11b5 + s21Bits[16] = a21Bits[5] * b21Bits[11] + a21Bits[6] * b21Bits[10] + a21Bits[7] * b21Bits[9] + + a21Bits[8] * b21Bits[8] + a21Bits[9] * b21Bits[7] + a21Bits[10] * b21Bits[6] + // a8b8 + a9b7 + a10b6 + a21Bits[11] * b21Bits[5]; // a11b5 + + // s17 = a6b11 + a7b10 + a8b9 + a9b8 + a10b7 + a11b6 + s21Bits[17] = a21Bits[6] * b21Bits[11] + a21Bits[7] * b21Bits[10] + a21Bits[8] * b21Bits[9] + + a21Bits[9] * b21Bits[8] + a21Bits[10] * b21Bits[7] + a21Bits[11] * b21Bits[6]; // a9b8 + a10b7 + a11b6 + + // s18 = a7b11 + a8b10 + a9b9 + a10b8 + a11b7 + s21Bits[18] = a21Bits[7] * b21Bits[11] + a21Bits[8] * b21Bits[10] + a21Bits[9] * b21Bits[9] + + a21Bits[10] * b21Bits[8] + a21Bits[11] * b21Bits[7]; // a10b8 + a11b7 + + // s19 = a8b11 + a9b10 + a10b9 + a11b8 + s21Bits[19] = a21Bits[8] * b21Bits[11] + a21Bits[9] * b21Bits[10] + a21Bits[10] * b21Bits[9] + + a21Bits[11] * b21Bits[8]; // a11b8 + + // s20 = a9b11 + a10b10 + a11b9 + s21Bits[20] = a21Bits[9] * b21Bits[11] + a21Bits[10] * b21Bits[10] + a21Bits[11] * b21Bits[9]; + + // s21 = a10b11 + a11b10 + s21Bits[21] = a21Bits[10] * b21Bits[11] + a21Bits[11] * b21Bits[10]; + + // s22 = a11b11 + s21Bits[22] = a21Bits[11] * b21Bits[11]; + + // s23 = 0 + s21Bits[23] = 0; +} + +void ScalarMulAdd(uint8_t s[CRYPT_CURVE25519_KEYLEN], const uint8_t a[CRYPT_CURVE25519_KEYLEN], + const uint8_t b[CRYPT_CURVE25519_KEYLEN], const uint8_t c[CRYPT_CURVE25519_KEYLEN]) +{ + uint64_t a21Bits[UINT8_32_21BITS_BLOCKNUM]; + uint64_t b21Bits[UINT8_32_21BITS_BLOCKNUM]; + uint64_t c21Bits[UINT8_32_21BITS_BLOCKNUM]; + + ScalarMulAddPreLoad(a, a21Bits); + ScalarMulAddPreLoad(b, b21Bits); + ScalarMulAddPreLoad(c, c21Bits); + + uint64_t s21Bits[UINT8_64_21BITS_BLOCKNUM]; + + MulAdd(s21Bits, a21Bits, b21Bits, c21Bits); + + int32_t i; + uint64_t signMask1, signMask2; + uint64_t carryA, carryB; + + // process carry 0->1, 2->3 ... 22->23 + for (i = 0; i <= 22; i += 2) { + // 21 bits minus sign bit is 20 bits + PROCESS_CARRY(s21Bits[i], s21Bits[i + 1], signMask1, carryA, 20); + } + + // process carry 1->2, 3->4 ... 21->22 + for (i = 1; i <= 21; i += 2) { + // 21 bits minus sign bit is 20 bits + PROCESS_CARRY(s21Bits[i], s21Bits[i + 1], signMask2, carryB, 20); + } + + ModuloLCore(s21Bits); + + UnloadTo8Bits(s, s21Bits); +} + +/* RFC8032, out = a + b */ +static void PointAdd(GeE *out, GeE *greA, GeE *greB) +{ + const Fp25 d2 = {{-21827239, -5839606, -30745221, 13898782, 229458, + 15978800, -12551817, -6495438, 29715968, 9444199}}; + Fp25 a, b, c, d, e, f, g, h; + CURVE25519_FP_SUB(e.data, greA->y.data, greA->x.data); + CURVE25519_FP_SUB(f.data, greB->y.data, greB->x.data); + CURVE25519_FP_ADD(g.data, greA->y.data, greA->x.data); + CURVE25519_FP_ADD(h.data, greB->y.data, greB->x.data); + FpMul(&a, &e, &f); + FpMul(&b, &g, &h); + FpMul(&c, &(greA->t), &(greB->t)); + FpMul(&c, &c, &d2); + FpMul(&d, &(greA->z), &(greB->z)); + CURVE25519_FP_ADD(d.data, d.data, d.data); + CURVE25519_FP_SUB(e.data, b.data, a.data); + CURVE25519_FP_SUB(f.data, d.data, c.data); + CURVE25519_FP_ADD(g.data, d.data, c.data); + CURVE25519_FP_ADD(h.data, b.data, a.data); + FpMul(&(out->x), &e, &f); + FpMul(&(out->y), &g, &h); + FpMul(&(out->z), &f, &g); + FpMul(&(out->t), &e, &h); +} + +static void PointAddPrecompute(GeE *out, GeE *greA, GeEPre *greB) +{ + Fp25 a, b, c, d, e, f, g, h; + CURVE25519_FP_SUB(e.data, greA->y.data, greA->x.data); + CURVE25519_FP_ADD(g.data, greA->y.data, greA->x.data); + FpMul(&a, &e, &(greB->yminusx)); + FpMul(&b, &g, &(greB->yplusx)); + FpMul(&c, &(greA->t), &(greB->t2z)); + FpMul(&d, &(greA->z), &(greB->z)); + CURVE25519_FP_ADD(d.data, d.data, d.data); + CURVE25519_FP_SUB(e.data, b.data, a.data); + CURVE25519_FP_SUB(f.data, d.data, c.data); + CURVE25519_FP_ADD(g.data, d.data, c.data); + CURVE25519_FP_ADD(h.data, b.data, a.data); + FpMul(&(out->x), &e, &f); + FpMul(&(out->y), &g, &h); + FpMul(&(out->z), &f, &g); + FpMul(&(out->t), &e, &h); +} + +static void PointSubPrecompute(GeE *out, GeE *greA, GeEPre *greB) +{ + Fp25 a, b, c, d, e, f, g, h; + CURVE25519_FP_SUB(e.data, greA->y.data, greA->x.data); + CURVE25519_FP_ADD(g.data, greA->y.data, greA->x.data); + FpMul(&a, &e, &(greB->yplusx)); + FpMul(&b, &g, &(greB->yminusx)); + FpMul(&c, &(greA->t), &(greB->t2z)); + FpMul(&d, &(greA->z), &(greB->z)); + CURVE25519_FP_ADD(d.data, d.data, d.data); + CURVE25519_FP_SUB(e.data, b.data, a.data); + CURVE25519_FP_ADD(f.data, d.data, c.data); + CURVE25519_FP_SUB(g.data, d.data, c.data); + CURVE25519_FP_ADD(h.data, b.data, a.data); + FpMul(&(out->x), &e, &f); + FpMul(&(out->y), &g, &h); + FpMul(&(out->z), &f, &g); + FpMul(&(out->t), &e, &h); +} + +static void P1DoubleN(GeE *p1, int32_t n) +{ + GeP p; + GeC c; + int32_t i; + // From extended coordinate to projective coordinate, just ignore T + CURVE25519_FP_COPY(p.x.data, p1->x.data); + CURVE25519_FP_COPY(p.y.data, p1->y.data); + CURVE25519_FP_COPY(p.z.data, p1->z.data); + + ProjectiveDouble(&c, &p); + for (i = 1; i < n; i++) { + GeCompleteToProjective(&p, &c); + ProjectiveDouble(&c, &p); + } + + FpMul(&p1->x, &c.t, &c.x); + FpMul(&p1->y, &c.z, &c.y); + FpMul(&p1->z, &c.t, &c.z); + FpMul(&p1->t, &c.y, &c.x); +} + +static void PointToPrecompute(GeEPre *out, GeE *in) +{ + const Fp25 d2 = {{-21827239, -5839606, -30745221, 13898782, 229458, + 15978800, -12551817, -6495438, 29715968, 9444199}}; + + CURVE25519_FP_ADD(out->yplusx.data, in->y.data, in->x.data); + CURVE25519_FP_SUB(out->yminusx.data, in->y.data, in->x.data); + CURVE25519_FP_COPY(out->z.data, in->z.data); + FpMul(&(out->t2z), &(in->t), &d2); +} + +static void FlipK(int8_t slide[256], uint32_t start) +{ + uint32_t k; + for (k = start; k < 256; k++) { + if (slide[k] == 0) { + slide[k] = 1; + break; + } else { + slide[k] = 0; + } + } +} + +static void SlideReduce(int8_t *out, uint32_t outLen, const uint8_t *in, uint32_t inLen) +{ + uint32_t i, j; + int8_t tmp; + (void)outLen; + (void)inLen; + // 32 * 8 = 256 + for (i = 0; i < 256; i++) { + // turn 32 8bits to 256 1bit, block: in[i >> 3], bit: (i & 7) + out[i] = (int8_t)((in[i >> 3] >> (i & 7)) & 1); + } + // 32 * 8 = 256 + for (i = 0; i < 256; i++) { + if (out[i] == 0) { + continue; + } + for (j = 1; j <= 6 && (i + j) < 256; j++) { // check next 6 since 2^6 - 2^5 = 16 > 15, 256 is array length + if (out[i + j] == 0) { + continue; + } + // range 15 to -15 + tmp = (int8_t)((uint8_t)(out[i + j]) << j); + if (out[i] + tmp <= 15) { // max 15, 0x1, 0x1, 0x1, 0x1 , 0 -> 0x1111, 0, 0, 0, 0 + out[i] += tmp; + out[i + j] = 0; + } else if (out[i] - tmp >= -15) { // min -15, 0x1111, 0, 0, 0, 1, 1 -> -1, 0, 0, 0, 0, 1 + out[i] -= tmp; + FlipK(out, i + j); + } else { + break; + } + } + } +} + +// Base on article "High-speed high-security signatures" +// stores B, 3B, 5B, 7B, 9B, 11B, 13B, 15B, with B as ed25519 base point +static const GePre g_precomputedB[8] = { + { + {{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, + -11754271, -6079156, 2047605}}, + {{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, + 5043384, 19500929, -15469378}}, + {{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, + 11864899, -24514362, -4438546}}, + }, + { + {{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, + -14772189, 28944400, -1550024}}, + {{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, + -11775962, 7689662, 11199574}}, + {{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, + 10017326, -17749093, -9920357}}, + }, + { + {{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, + 14515107, -15438304, 10819380}}, + {{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, + 12483688, -12668491, 5581306}}, + {{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, + 13850243, -23678021, -15815942}}, + }, + { + {{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, + 5230134, -23952439, -15175766}}, + {{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, + 16520125, 30598449, 7715701}}, + {{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, + 1370708, 29794553, -1409300}}, + }, + { + {{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, + -1361450, -13062696, 13821877}}, + {{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, + -7212327, 18853322, -14220951}}, + {{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, + -10431137, 2207753, -3209784}}, + }, + { + {{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, + -663000, -31111463, -16132436}}, + {{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, + 15725684, 171356, 6466918}}, + {{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, + -14088058, -30714912, 16193877}}, + }, + { + {{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, + 4729455, -18074513, 9256800}}, + {{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, + 9761698, -19827198, 630305}}, + {{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, + -15960994, -2449256, -14291300}}, + }, + { + {{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, + 15033784, 25105118, -7894876}}, + {{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, + 1573892, -2625887, 2198790, -15804619}}, + {{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, + -16236442, -32461234, -12290683}}, + }, +}; + +/* out = hash * p + s * B */ +void KAMulPlusMulBase(GeE *out, const uint8_t hash[CRYPT_CURVE25519_KEYLEN], + const GeE *p, const uint8_t s[CRYPT_CURVE25519_KEYLEN]) +{ + SetExtendedBasePoint(out); + GeE tmpP[8]; // stores p, 3p, 5p, 7p, 9p, 11p, 13p, 15p + GeE doubleP; + GeEPre preComputedP[8]; // stores p, 3p, 5p, 7p, 9p, 11p, 13p, 15p + int8_t slideP[256]; + int8_t slideS[256]; + int32_t i; + + SlideReduce(slideP, 256, hash, CRYPT_CURVE25519_KEYLEN); + SlideReduce(slideS, 256, s, CRYPT_CURVE25519_KEYLEN); + + CURVE25519_GE_COPY(tmpP[0], *p); + CURVE25519_GE_COPY(doubleP, *p); + + PointToPrecompute(&preComputedP[0], &tmpP[0]); + P1DoubleN(&doubleP, 1); + + for (i = 1; i < 8; i += 1) { // p, 3p, ....., 13p, 15p, total 8 + PointAdd(&tmpP[i], &tmpP[i - 1], &doubleP); + PointToPrecompute(&preComputedP[i], &tmpP[i]); + } + + int32_t zeroCount = 0; + i = 255; // 255 to 0 + while (i >= 0 && slideP[i] == 0 && slideS[i] == 0) { + i--; + } + for (; i >= 0; i--) { + while (i >= 0 && slideP[i] == 0 && slideS[i] == 0) { + zeroCount++; + i--; + } + if (i < 0) { + P1DoubleN(out, zeroCount); + break; + } else { + P1DoubleN(out, zeroCount + 1); + } + zeroCount = 0; + if (slideP[i] > 0) { + PointAddPrecompute(out, out, &preComputedP[slideP[i] / 2]); // preComputedP[i] = (i * 2 + 1)P + } else if (slideP[i] < 0) { + PointSubPrecompute(out, out, &preComputedP[(-slideP[i]) / 2]); // preComputedP[i] = (i * 2 + 1)P + } + if (slideS[i] > 0) { + GeAdd(out, &g_precomputedB[slideS[i] / 2]); // g_precomputedB[i] = (i * 2 + 1)P + } else if (slideS[i] < 0) { + GeSub(out, &g_precomputedB[(-slideS[i]) / 2]); // g_precomputedB[i] = (i * 2 + 1)P + } + } +} +#endif /* HITLS_CRYPTO_ED25519 */ + +#endif /* HITLS_CRYPTO_CURVE25519 */ diff --git a/crypto/curve25519/src/curve25519_table.c b/crypto/curve25519/src/curve25519_table.c new file mode 100644 index 00000000..55d9797b --- /dev/null +++ b/crypto/curve25519/src/curve25519_table.c @@ -0,0 +1,1404 @@ +/* + * 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. + */ +/* Some of these codes are adapted from https://ed25519.cr.yp.to/software.html */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CURVE25519 + +#include "curve25519_local.h" + +/* lookup table that computing y-x, y+x and 2dxy, with 512 ^ n B, n starts from 0 */ +/* table is generated base on article "High-speed high-security signatures" */ +static const GePre CURVE25519PRE_COMPUTE[32][8] = { + { + { + {{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}}, + {{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}}, + {{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}}, + }, + { + {{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303}}, + {{-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081}}, + {{26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697}}, + }, + { + {{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}}, + {{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}}, + {{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}}, + }, + { + {{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540}}, + {{23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397}}, + {{7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325}}, + }, + { + {{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}}, + {{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}}, + {{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}}, + }, + { + {{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777}}, + {{-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737}}, + {{-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652}}, + }, + { + {{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}}, + {{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}}, + {{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}}, + }, + { + {{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726}}, + {{-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955}}, + {{27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425}}, + }, + }, + { + { + {{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171}}, + {{27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510}}, + {{17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660}}, + }, + { + {{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639}}, + {{29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963}}, + {{5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950}}, + }, + { + {{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568}}, + {{12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335}}, + {{25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628}}, + }, + { + {{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007}}, + {{-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772}}, + {{-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653}}, + }, + { + {{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567}}, + {{13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686}}, + {{21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372}}, + }, + { + {{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887}}, + {{-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954}}, + {{-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953}}, + }, + { + {{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833}}, + {{-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532}}, + {{-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876}}, + }, + { + {{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268}}, + {{33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214}}, + {{1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038}}, + }, + }, + { + { + {{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800}}, + {{4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645}}, + {{-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664}}, + }, + { + {{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933}}, + {{-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182}}, + {{-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222}}, + }, + { + {{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991}}, + {{20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880}}, + {{9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092}}, + }, + { + {{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295}}, + {{19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788}}, + {{8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553}}, + }, + { + {{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026}}, + {{11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347}}, + {{-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033}}, + }, + { + {{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395}}, + {{-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278}}, + {{1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890}}, + }, + { + {{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995}}, + {{-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596}}, + {{-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891}}, + }, + { + {{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060}}, + {{11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608}}, + {{-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606}}, + }, + }, + { + { + {{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389}}, + {{-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016}}, + {{-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341}}, + }, + { + {{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505}}, + {{14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553}}, + {{-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655}}, + }, + { + {{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220}}, + {{12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631}}, + {{-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099}}, + }, + { + {{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556}}, + {{14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749}}, + {{236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930}}, + }, + { + {{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391}}, + {{5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253}}, + {{20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066}}, + }, + { + {{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958}}, + {{-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082}}, + {{-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383}}, + }, + { + {{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521}}, + {{-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807}}, + {{23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948}}, + }, + { + {{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134}}, + {{-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455}}, + {{27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629}}, + }, + }, + { + { + {{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069}}, + {{-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746}}, + {{24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919}}, + }, + { + {{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837}}, + {{8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906}}, + {{-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771}}, + }, + { + {{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817}}, + {{10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098}}, + {{10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409}}, + }, + { + {{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504}}, + {{-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727}}, + {{28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420}}, + }, + { + {{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003}}, + {{-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605}}, + {{-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384}}, + }, + { + {{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701}}, + {{-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683}}, + {{29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708}}, + }, + { + {{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563}}, + {{-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260}}, + {{-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387}}, + }, + { + {{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, + -27444329, -15000531, -5996870, 15664672}}, + {{23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686}}, + {{-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665}}, + }, + }, + { + { + {{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182}}, + {{-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277}}, + {{14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628}}, + }, + { + {{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474}}, + {{-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539}}, + {{-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822}}, + }, + { + {{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970}}, + {{19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756}}, + {{-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508}}, + }, + { + {{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683}}, + {{-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655}}, + {{-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158}}, + }, + { + {{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125}}, + {{-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839}}, + {{-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664}}, + }, + { + {{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294}}, + {{-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899}}, + {{-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070}}, + }, + { + {{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294}}, + {{-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949}}, + {{-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083}}, + }, + { + {{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420}}, + {{-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940}}, + {{29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396}}, + }, + }, + { + { + {{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567}}, + {{20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127}}, + {{-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294}}, + }, + { + {{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887}}, + {{22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964}}, + {{16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195}}, + }, + { + {{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244}}, + {{24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999}}, + {{-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762}}, + }, + { + {{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274}}, + {{-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236}}, + {{-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605}}, + }, + { + {{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761}}, + {{-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884}}, + {{-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482}}, + }, + { + {{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638}}, + {{-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490}}, + {{-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170}}, + }, + { + {{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736}}, + {{10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124}}, + {{-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392}}, + }, + { + {{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029}}, + {{6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048}}, + {{28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958}}, + }, + }, + { + { + {{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593}}, + {{26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071}}, + {{-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692}}, + }, + { + {{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687}}, + {{-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441}}, + {{-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001}}, + }, + { + {{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460}}, + {{-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007}}, + {{-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762}}, + }, + { + {{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005}}, + {{-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674}}, + {{4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035}}, + }, + { + {{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590}}, + {{-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957}}, + {{-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812}}, + }, + { + {{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740}}, + {{-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122}}, + {{-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158}}, + }, + { + {{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885}}, + {{26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140}}, + {{19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857}}, + }, + { + {{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155}}, + {{19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260}}, + {{19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483}}, + }, + }, + { + { + {{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677}}, + {{32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815}}, + {{22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751}}, + }, + { + {{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203}}, + {{-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208}}, + {{1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230}}, + }, + { + {{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850}}, + {{-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389}}, + {{-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968}}, + }, + { + {{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689}}, + {{14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880}}, + {{5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304}}, + }, + { + {{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632}}, + {{-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412}}, + {{20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566}}, + }, + { + {{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038}}, + {{-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232}}, + {{-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943}}, + }, + { + {{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856}}, + {{23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738}}, + {{15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971}}, + }, + { + {{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718}}, + {{-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697}}, + {{-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883}}, + }, + }, + { + { + {{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912}}, + {{-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358}}, + {{3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849}}, + }, + { + {{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307}}, + {{-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977}}, + {{-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335}}, + }, + { + {{-29265967, -14186805, -13538216, -12117373, -19457059, + -10655384, -31462369, -2948985, 24018831, 15026644}}, + {{-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616}}, + {{-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735}}, + }, + { + {{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099}}, + {{29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341}}, + {{-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336}}, + }, + { + {{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646}}, + {{31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425}}, + {{-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388}}, + }, + { + {{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743}}, + {{-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822}}, + {{-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462}}, + }, + { + {{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985}}, + {{9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702}}, + {{-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797}}, + }, + { + {{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293}}, + {{27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100}}, + {{19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688}}, + }, + }, + { + { + {{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186}}, + {{2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610}}, + {{-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707}}, + }, + { + {{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220}}, + {{915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025}}, + {{32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044}}, + }, + { + {{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992}}, + {{-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027}}, + {{21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197}}, + }, + { + {{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901}}, + {{31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952}}, + {{19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878}}, + }, + { + {{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390}}, + {{32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730}}, + {{2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730}}, + }, + { + {{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180}}, + {{-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272}}, + {{-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715}}, + }, + { + {{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970}}, + {{-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772}}, + {{-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865}}, + }, + { + {{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750}}, + {{20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373}}, + {{32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348}}, + }, + }, + { + { + {{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144}}, + {{-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195}}, + {{5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086}}, + }, + { + {{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684}}, + {{-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518}}, + {{-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233}}, + }, + { + {{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793}}, + {{-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794}}, + {{580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435}}, + }, + { + {{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921}}, + {{13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518}}, + {{2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563}}, + }, + { + {{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278}}, + {{-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024}}, + {{4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030}}, + }, + { + {{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783}}, + {{27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717}}, + {{6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844}}, + }, + { + {{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333}}, + {{16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048}}, + {{22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760}}, + }, + { + {{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760}}, + {{-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757}}, + {{-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112}}, + }, + }, + { + { + {{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468}}, + {{3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184}}, + {{10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289}}, + }, + { + {{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066}}, + {{24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882}}, + {{13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226}}, + }, + { + {{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101}}, + {{29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279}}, + {{-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811}}, + }, + { + {{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709}}, + {{20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714}}, + {{-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121}}, + }, + { + {{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464}}, + {{12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847}}, + {{13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400}}, + }, + { + {{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414}}, + {{-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158}}, + {{17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045}}, + }, + { + {{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415}}, + {{-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459}}, + {{-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079}}, + }, + { + {{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412}}, + {{-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743}}, + {{-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836}}, + }, + }, + { + { + {{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022}}, + {{18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429}}, + {{-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065}}, + }, + { + {{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861}}, + {{10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000}}, + {{-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101}}, + }, + { + {{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815}}, + {{29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642}}, + {{10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966}}, + }, + { + {{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574}}, + {{-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742}}, + {{-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689}}, + }, + { + {{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020}}, + {{-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772}}, + {{3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982}}, + }, + { + {{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953}}, + {{-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218}}, + {{-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265}}, + }, + { + {{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073}}, + {{-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325}}, + {{-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798}}, + }, + { + {{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870}}, + {{-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863}}, + {{-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927}}, + }, + }, + { + { + {{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267}}, + {{-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663}}, + {{22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862}}, + }, + { + {{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673}}, + {{15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943}}, + {{15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020}}, + }, + { + {{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238}}, + {{11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064}}, + {{14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795}}, + }, + { + {{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052}}, + {{-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904}}, + {{29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531}}, + }, + { + {{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979}}, + {{-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841}}, + {{10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431}}, + }, + { + {{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324}}, + {{-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940}}, + {{10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320}}, + }, + { + {{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184}}, + {{14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114}}, + {{30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878}}, + }, + { + {{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784}}, + {{-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091}}, + {{-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585}}, + }, + }, + { + { + {{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208}}, + {{10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864}}, + {{17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661}}, + }, + { + {{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233}}, + {{26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212}}, + {{-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525}}, + }, + { + {{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068}}, + {{9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397}}, + {{-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988}}, + }, + { + {{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889}}, + {{32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038}}, + {{14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697}}, + }, + { + {{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875}}, + {{-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905}}, + {{-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656}}, + }, + { + {{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818}}, + {{27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714}}, + {{10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203}}, + }, + { + {{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931}}, + {{-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024}}, + {{-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084}}, + }, + { + {{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204}}, + {{20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817}}, + {{27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667}}, + }, + }, + { + { + {{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504}}, + {{-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768}}, + {{-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255}}, + }, + { + {{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790}}, + {{1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438}}, + {{-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333}}, + }, + { + {{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971}}, + {{31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905}}, + {{29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409}}, + }, + { + {{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409}}, + {{6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499}}, + {{-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363}}, + }, + { + {{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664}}, + {{-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324}}, + {{-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940}}, + }, + { + {{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990}}, + {{-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914}}, + {{-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290}}, + }, + { + {{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257}}, + {{-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433}}, + {{-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236}}, + }, + { + {{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045}}, + {{11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093}}, + {{-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347}}, + }, + }, + { + { + {{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191}}, + {{-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507}}, + {{-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906}}, + }, + { + {{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018}}, + {{-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109}}, + {{-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926}}, + }, + { + {{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528}}, + {{8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625}}, + {{-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286}}, + }, + { + {{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033}}, + {{27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866}}, + {{21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896}}, + }, + { + {{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075}}, + {{26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347}}, + {{-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437}}, + }, + { + {{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165}}, + {{-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588}}, + {{-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193}}, + }, + { + {{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017}}, + {{-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883}}, + {{21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961}}, + }, + { + {{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043}}, + {{29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663}}, + {{-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362}}, + }, + }, + { + { + {{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860}}, + {{2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466}}, + {{-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063}}, + }, + { + {{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997}}, + {{-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295}}, + {{-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369}}, + }, + { + {{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385}}, + {{18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109}}, + {{2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906}}, + }, + { + {{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424}}, + {{-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185}}, + {{7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962}}, + }, + { + {{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325}}, + {{10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593}}, + {{696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404}}, + }, + { + {{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644}}, + {{17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801}}, + {{26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804}}, + }, + { + {{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884}}, + {{-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577}}, + {{-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849}}, + }, + { + {{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473}}, + {{-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644}}, + {{-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319}}, + }, + }, + { + { + {{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599}}, + {{-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768}}, + {{-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084}}, + }, + { + {{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328}}, + {{-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369}}, + {{20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920}}, + }, + { + {{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815}}, + {{-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025}}, + {{-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397}}, + }, + { + {{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448}}, + {{6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981}}, + {{30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165}}, + }, + { + {{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501}}, + {{17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073}}, + {{-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861}}, + }, + { + {{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845}}, + {{-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211}}, + {{18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870}}, + }, + { + {{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096}}, + {{33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803}}, + {{-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168}}, + }, + { + {{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965}}, + {{-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505}}, + {{18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598}}, + }, + }, + { + { + {{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782}}, + {{5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900}}, + {{-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479}}, + }, + { + {{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208}}, + {{8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232}}, + {{17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719}}, + }, + { + {{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271}}, + {{-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326}}, + {{-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132}}, + }, + { + {{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300}}, + {{8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570}}, + {{15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670}}, + }, + { + {{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994}}, + {{-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913}}, + {{31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317}}, + }, + { + {{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730}}, + {{842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096}}, + {{-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078}}, + }, + { + {{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411}}, + {{-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905}}, + {{-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654}}, + }, + { + {{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870}}, + {{-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498}}, + {{12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579}}, + }, + }, + { + { + {{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677}}, + {{10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647}}, + {{-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743}}, + }, + { + {{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, + 10993114, -12850837, -17620701, -9408468}}, + {{21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375}}, + {{-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155}}, + }, + { + {{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725}}, + {{-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612}}, + {{-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943}}, + }, + { + {{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944}}, + {{30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928}}, + {{9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406}}, + }, + { + {{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139}}, + {{-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963}}, + {{-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693}}, + }, + { + {{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734}}, + {{-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680}}, + {{-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410}}, + }, + { + {{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931}}, + {{-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654}}, + {{22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710}}, + }, + { + {{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180}}, + {{-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684}}, + {{-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895}}, + }, + }, + { + { + {{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501}}, + {{-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413}}, + {{6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880}}, + }, + { + {{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874}}, + {{22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962}}, + {{-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899}}, + }, + { + {{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152}}, + {{9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063}}, + {{7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080}}, + }, + { + {{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146}}, + {{-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183}}, + {{-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133}}, + }, + { + {{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421}}, + {{-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622}}, + {{-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197}}, + }, + { + {{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663}}, + {{31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753}}, + {{4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755}}, + }, + { + {{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862}}, + {{-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118}}, + {{26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171}}, + }, + { + {{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380}}, + {{16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824}}, + {{28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270}}, + }, + }, + { + { + {{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438}}, + {{-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584}}, + {{-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562}}, + }, + { + {{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471}}, + {{18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610}}, + {{19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269}}, + }, + { + {{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650}}, + {{14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369}}, + {{19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461}}, + }, + { + {{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462}}, + {{-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793}}, + {{-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218}}, + }, + { + {{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226}}, + {{18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019}}, + {{-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037}}, + }, + { + {{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171}}, + {{-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132}}, + {{-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841}}, + }, + { + {{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181}}, + {{-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210}}, + {{-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040}}, + }, + { + {{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935}}, + {{24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105}}, + {{-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814}}, + }, + }, + { + { + {{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852}}, + {{5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581}}, + {{-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646}}, + }, + { + {{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844}}, + {{10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025}}, + {{27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453}}, + }, + { + {{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068}}, + {{4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192}}, + {{-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921}}, + }, + { + {{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259}}, + {{-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426}}, + {{-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072}}, + }, + { + {{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305}}, + {{13669248, -16095482, -12481974, -10203039, -14569770, + -11893198, -24995986, 11293807, -28588204, -9421832}}, + {{28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943}}, + }, + { + {{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011}}, + {{24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447}}, + {{17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494}}, + }, + { + {{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245}}, + {{-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859}}, + {{28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915}}, + }, + { + {{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707}}, + {{10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848}}, + {{-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224}}, + }, + }, + { + { + {{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391}}, + {{15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215}}, + {{-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101}}, + }, + { + {{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713}}, + {{21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849}}, + {{-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930}}, + }, + { + {{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940}}, + {{-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031}}, + {{-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404}}, + }, + { + {{-25817338, -3107312, -13494599, -3182506, 30896459, + -13921729, -32251644, -12707869, -19464434, -3340243}}, + {{-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116}}, + {{-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525}}, + }, + { + {{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509}}, + {{-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883}}, + {{15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865}}, + }, + { + {{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660}}, + {{4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273}}, + {{-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138}}, + }, + { + {{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560}}, + {{-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135}}, + {{2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941}}, + }, + { + {{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739}}, + {{18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756}}, + {{-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819}}, + }, + }, + { + { + {{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347}}, + {{-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028}}, + {{21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075}}, + }, + { + {{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799}}, + {{-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609}}, + {{-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817}}, + }, + { + {{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989}}, + {{-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523}}, + {{4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278}}, + }, + { + {{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045}}, + {{19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377}}, + {{24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480}}, + }, + { + {{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016}}, + {{510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426}}, + {{18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525}}, + }, + { + {{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396}}, + {{9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080}}, + {{12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892}}, + }, + { + {{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275}}, + {{11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074}}, + {{20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140}}, + }, + { + {{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717}}, + {{-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101}}, + {{24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127}}, + }, + }, + { + { + {{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632}}, + {{-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415}}, + {{-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160}}, + }, + { + {{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876}}, + {{22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625}}, + {{-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478}}, + }, + { + {{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164}}, + {{26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595}}, + {{-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248}}, + }, + { + {{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858}}, + {{15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193}}, + {{8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184}}, + }, + { + {{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942}}, + {{-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635}}, + {{21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948}}, + }, + { + {{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935}}, + {{-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415}}, + {{-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416}}, + }, + { + {{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018}}, + {{4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778}}, + {{366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659}}, + }, + { + {{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385}}, + {{18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503}}, + {{476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329}}, + }, + }, + { + { + {{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056}}, + {{-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838}}, + {{24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948}}, + }, + { + {{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691}}, + {{-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118}}, + {{-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517}}, + }, + { + {{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269}}, + {{-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904}}, + {{-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589}}, + }, + { + {{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193}}, + {{-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910}}, + {{-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930}}, + }, + { + {{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667}}, + {{25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481}}, + {{-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876}}, + }, + { + {{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640}}, + {{-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278}}, + {{-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112}}, + }, + { + {{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272}}, + {{17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012}}, + {{-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221}}, + }, + { + {{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046}}, + {{13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345}}, + {{-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310}}, + }, + }, + { + { + {{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937}}, + {{31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636}}, + {{-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008}}, + }, + { + {{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429}}, + {{-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576}}, + {{31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066}}, + }, + { + {{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490}}, + {{-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104}}, + {{33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053}}, + }, + { + {{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275}}, + {{-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511}}, + {{22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095}}, + }, + { + {{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439}}, + {{23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939}}, + {{-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424}}, + }, + { + {{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310}}, + {{3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608}}, + {{-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079}}, + }, + { + {{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101}}, + {{21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418}}, + {{18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576}}, + }, + { + {{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356}}, + {{9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996}}, + {{-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099}}, + }, + }, + { + { + {{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728}}, + {{-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658}}, + {{-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242}}, + }, + { + {{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001}}, + {{-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766}}, + {{18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373}}, + }, + { + {{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458}}, + {{-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628}}, + {{-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657}}, + }, + { + {{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062}}, + {{25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616}}, + {{31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014}}, + }, + { + {{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383}}, + {{-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814}}, + {{-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718}}, + }, + { + {{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417}}, + {{2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222}}, + {{33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444}}, + }, + { + {{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597}}, + {{23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970}}, + {{1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799}}, + }, + { + {{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647}}, + {{13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511}}, + {{-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032}}, + }, + }, + { + { + {{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834}}, + {{-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461}}, + {{29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062}}, + }, + { + {{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516}}, + {{-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547}}, + {{-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240}}, + }, + { + {{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038}}, + {{-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741}}, + {{16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103}}, + }, + { + {{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747}}, + {{-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323}}, + {{31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016}}, + }, + { + {{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373}}, + {{15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228}}, + {{-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141}}, + }, + { + {{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399}}, + {{11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831}}, + {{-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376}}, + }, + { + {{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313}}, + {{-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958}}, + {{-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577}}, + }, + { + {{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743}}, + {{29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684}}, + {{-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476}}, + }, + }, +}; + +void TableLookup(GePre *preCompute, int32_t pos, int8_t e) +{ + GePre negate; + // Prevent side-channel attack: Do not use conditional statements to ensure that the execution time is constant. + // -negative = 11111111 if e is negative, or 0 if e is not + // (-negative & e) << 1 = 2e if e is negative, or 0 if e is positive + // absolute value = e - 2e (e negative) or e (e positive) + uint8_t negative = (uint8_t)e >> 7; // shift 7 to check negative + // range of e is -7 to 8, left shift won't cause sign change + uint8_t abs = (uint8_t)(e - ((uint8_t)(-negative & (uint8_t)e) << 1)); + // set base result + CURVE25519_FP_SET(preCompute->yplusx.data, 1); + CURVE25519_FP_SET(preCompute->yminusx.data, 1); + CURVE25519_FP_SET(preCompute->xy2d.data, 0); + // only copy the corrsponding position + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][0], abs == 1); // 1 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][1], abs == 2); // 2 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][2], abs == 3); // 3 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][3], abs == 4); // 4 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][4], abs == 5); // 5 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][5], abs == 6); // 6 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][6], abs == 7); // 7 of 8 + ConditionalMove(preCompute, &CURVE25519PRE_COMPUTE[pos][7], abs == 8); // 8 of 8 + CURVE25519_FP_COPY(negate.yminusx.data, preCompute->yplusx.data); + CURVE25519_FP_COPY(negate.yplusx.data, preCompute->yminusx.data); + CURVE25519_FP_NEGATE(negate.xy2d.data, preCompute->xy2d.data); + ConditionalMove(preCompute, &negate, negative); +} +#endif /* HITLS_CRYPTO_CURVE25519 */ diff --git a/crypto/curve25519/src/noasm_curve25519_fp51_ops.c b/crypto/curve25519/src/noasm_curve25519_fp51_ops.c new file mode 100644 index 00000000..b5d6f2a2 --- /dev/null +++ b/crypto/curve25519/src/noasm_curve25519_fp51_ops.c @@ -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_CRYPTO_X25519 + +#include "securec.h" +#include "curve25519_local.h" + +// X25519 alternative implementation, faster but require int128 +#if (defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16)) +#define CURVE25519_51BITS_MASK 0x7ffffffffffff +#define CURVE25519_51BITS 51 + +static void Fp51DataToPoly(Fp51 *out, const uint8_t in[32]) +{ + uint64_t h[5]; + + CURVE25519_BYTES7_LOAD(h, in); + + CURVE25519_BYTES6_LOAD(h + 1, in + 7); + h[1] <<= 5; + + CURVE25519_BYTES7_LOAD(h + 2, in + 13); + h[2] <<= 2; + + CURVE25519_BYTES6_LOAD(h + 3, in + 20); + h[3] <<= 7; + + CURVE25519_BYTES6_LOAD(h + 4, in + 26); + h[4] &= 0x7fffffffffff; // 41 bits mask = 0x7fffffffffff + h[4] <<= 4; + + h[1] |= h[0] >> CURVE25519_51BITS; + h[0] &= CURVE25519_51BITS_MASK; + + h[2] |= h[1] >> CURVE25519_51BITS; + h[1] &= CURVE25519_51BITS_MASK; + + h[3] |= h[2] >> CURVE25519_51BITS; + h[2] &= CURVE25519_51BITS_MASK; + + h[4] |= h[3] >> CURVE25519_51BITS; + h[3] &= CURVE25519_51BITS_MASK; + + out->data[0] = h[0]; + out->data[1] = h[1]; + out->data[2] = h[2]; + out->data[3] = h[3]; + out->data[4] = h[4]; +} + +static void Fp51UnloadTo8Bits(uint8_t out[32], uint64_t h[5]) +{ + // load from uint64 to uint8, load 8 bits at a time + out[0] = (uint8_t)h[0]; + out[1] = (uint8_t)(h[0] >> 8); + out[2] = (uint8_t)(h[0] >> 16); + out[3] = (uint8_t)(h[0] >> 24); + out[4] = (uint8_t)(h[0] >> 32); + out[5] = (uint8_t)(h[0] >> 40); + // load from position 48 from h[1] and (8-5)=3 bits from h[1] to out[6] + out[6] = (uint8_t)((h[0] >> 48) | (uint8_t)(h[1] << 3)); + out[7] = (uint8_t)(h[1] >> 5); + out[8] = (uint8_t)(h[1] >> 13); + out[9] = (uint8_t)(h[1] >> 21); + out[10] = (uint8_t)(h[1] >> 29); + out[11] = (uint8_t)(h[1] >> 37); + // load from position 45 from h[1] and (8-2)=6 bits from h[2] to out[12] + out[12] = (uint8_t)((h[1] >> 45) | (uint8_t)(h[2] << 6)); + out[13] = (uint8_t)(h[2] >> 2); + out[14] = (uint8_t)(h[2] >> 10); + out[15] = (uint8_t)(h[2] >> 18); + out[16] = (uint8_t)(h[2] >> 26); + out[17] = (uint8_t)(h[2] >> 34); + out[18] = (uint8_t)(h[2] >> 42); + // load from position 50 from h[2] and (8-1)=7 bits from h[3] to out[19] + out[19] = (uint8_t)((h[2] >> 50) | (uint8_t)(h[3] << 1)); + out[20] = (uint8_t)(h[3] >> 7); + out[21] = (uint8_t)(h[3] >> 15); + out[22] = (uint8_t)(h[3] >> 23); + out[23] = (uint8_t)(h[3] >> 31); + out[24] = (uint8_t)(h[3] >> 39); + // load from position 47 from h[3] and (4-4)=4 bits from h[4] to out[25] + out[25] = (uint8_t)((h[3] >> 47) | (uint8_t)(h[4] << 4)); + out[26] = (uint8_t)(h[4] >> 4); + out[27] = (uint8_t)(h[4] >> 12); + out[28] = (uint8_t)(h[4] >> 20); + out[29] = (uint8_t)(h[4] >> 28); + out[30] = (uint8_t)(h[4] >> 36); + out[31] = (uint8_t)(h[4] >> 44); +} + +static void Fp51PolyToData(const Fp51 *in, uint8_t out[32]) +{ + uint64_t h[5]; + h[0] = in->data[0]; + h[1] = in->data[1]; + h[2] = in->data[2]; + h[3] = in->data[3]; + h[4] = in->data[4]; + uint64_t carry; + + carry = (h[0] + 19) >> CURVE25519_51BITS; // plus 19 then calculate carry + carry = (h[1] + carry) >> CURVE25519_51BITS; + carry = (h[2] + carry) >> CURVE25519_51BITS; + carry = (h[3] + carry) >> CURVE25519_51BITS; + carry = (h[4] + carry) >> CURVE25519_51BITS; + + h[0] += 19 * carry; // process carry h[4] -> h[0], h[0] += 19 * carry + h[1] += h[0] >> CURVE25519_51BITS; + h[0] &= CURVE25519_51BITS_MASK; + h[2] += h[1] >> CURVE25519_51BITS; + h[1] &= CURVE25519_51BITS_MASK; + h[3] += h[2] >> CURVE25519_51BITS; + h[2] &= CURVE25519_51BITS_MASK; + h[4] += h[3] >> CURVE25519_51BITS; + h[3] &= CURVE25519_51BITS_MASK; + h[4] &= CURVE25519_51BITS_MASK; + + Fp51UnloadTo8Bits(out, h); +} + +void Fp51ProcessCarry(__uint128_t in[5]) +{ + in[1] += (uint64_t)(in[0] >> CURVE25519_51BITS); + in[0] = (uint64_t)in[0] & CURVE25519_51BITS_MASK; + + in[2] += (uint64_t)(in[1] >> CURVE25519_51BITS); + in[1] = (uint64_t)in[1] & CURVE25519_51BITS_MASK; + + in[3] += (uint64_t)(in[2] >> CURVE25519_51BITS); + in[2] = (uint64_t)in[2] & CURVE25519_51BITS_MASK; + + in[4] += (uint64_t)(in[3] >> CURVE25519_51BITS); + in[3] = (uint64_t)in[3] & CURVE25519_51BITS_MASK; + + in[0] += (uint64_t)(in[4] >> CURVE25519_51BITS) * 19; + in[4] = (uint64_t)in[4] & CURVE25519_51BITS_MASK; + + in[1] += in[0] >> CURVE25519_51BITS; + in[0] &= CURVE25519_51BITS_MASK; +} + +void Fp51Mul(Fp51 *out, const Fp51 *f, const Fp51 *g) +{ + __uint128_t h[5]; + // h[0] = f0g0 + 19*f1g4 + 19*f2g3 + 19*f3g2 + 19*f4g1 + h[0] = (__uint128_t)f->data[0] * g->data[0] + (__uint128_t)f->data[1] * g->data[4] * 19 + + (__uint128_t)f->data[2] * g->data[3] * 19 + (__uint128_t)f->data[3] * g->data[2] * 19 + // 19*f2g3 + 19*f3g2 + (__uint128_t)f->data[4] * g->data[1] * 19; // 19*f4g1 + // h[1] = f0g1 + f1g0 + 19*f2g4 + 19*f3g3 + 19*f4g2 + h[1] = (__uint128_t)f->data[0] * g->data[1] + (__uint128_t)f->data[1] * g->data[0] + + (__uint128_t)f->data[2] * g->data[4] * 19 + (__uint128_t)f->data[3] * g->data[3] * 19 + // 19*f2g4 + 19*f3g3 + (__uint128_t)f->data[4] * g->data[2] * 19; // 19*f4g2 + // h[2] = f0g2 + f1g1 + f2g0 + 19*f3g4 + 19*f4g3 + h[2] = (__uint128_t)f->data[0] * g->data[2] + (__uint128_t)f->data[1] * g->data[1] + + (__uint128_t)f->data[2] * g->data[0] + (__uint128_t)f->data[3] * g->data[4] * 19 + // f2g0 + 19*f3g4 + (__uint128_t)f->data[4] * g->data[3] * 19; // 19*f4g3 + // h[3] = f0g3 + f1g2 + f2g1 + f3g0 + 19*f4g4 + h[3] = (__uint128_t)f->data[0] * g->data[3] + (__uint128_t)f->data[1] * g->data[2] + + (__uint128_t)f->data[2] * g->data[1] + (__uint128_t)f->data[3] * g->data[0] + // f2g1 + f3g0 + (__uint128_t)f->data[4] * g->data[4] * 19; // 19*f4g4 + // h[4] = f0g4 + f1g3 + f2g2 + f3g1 + f4g0 + h[4] = (__uint128_t)f->data[0] * g->data[4] + (__uint128_t)f->data[1] * g->data[3] + + (__uint128_t)f->data[2] * g->data[2] + (__uint128_t)f->data[3] * g->data[1] + // f2g2 + f3g1 + (__uint128_t)f->data[4] * g->data[0]; // f4g0 + + Fp51ProcessCarry(h); + + out->data[0] = (uint64_t)h[0]; + out->data[1] = (uint64_t)h[1]; + out->data[2] = (uint64_t)h[2]; + out->data[3] = (uint64_t)h[3]; + out->data[4] = (uint64_t)h[4]; +} + +void Fp51Square(Fp51 *out, const Fp51 *in) +{ + __uint128_t h[5]; + uint64_t in0mul2 = in->data[0] * 2; + uint64_t in1mul2 = in->data[1] * 2; + uint64_t in2mul2 = in->data[2] * 2; + uint64_t in3mul19 = in->data[3] * 19; + uint64_t in4mul19 = in->data[4] * 19; + + // h0 = in0^2 + 38 * in1 * in4 + 38 * in2 * in3 + h[0] = (__uint128_t)in->data[0] * in->data[0] + (__uint128_t)in1mul2 * in4mul19 + + (__uint128_t)in2mul2 * in3mul19; + // h1 = 2 * in0 * in1 + 19 * in3^2 + 38 * in2 * in4 + h[1] = (__uint128_t)in0mul2 * in->data[1] + (__uint128_t)in->data[3] * in3mul19 + + (__uint128_t)in2mul2 * in4mul19; + // h2 = 2 * in0 * in2 + in1^2 + 38 * in3 * in4 + h[2] = (__uint128_t)in0mul2 * in->data[2] + (__uint128_t)in->data[1] * in->data[1] + + (__uint128_t)(in->data[3] * 2) * in4mul19; // 2 * 19 * in3 * in4 + // h3 = 2 * in0 * in3 + 19 * in4^2 + 2 * in1 * in2 + h[3] = (__uint128_t)in0mul2 * in->data[3] + (__uint128_t)in->data[4] * in4mul19 + + (__uint128_t)in1mul2 * in->data[2]; // 2 * in1 * in2 + // h4 = 2 * in0 * in4 + 2 * in1 * in3 + in2^2 + h[4] = (__uint128_t)in0mul2 * in->data[4] + (__uint128_t)in1mul2 * in->data[3] + + (__uint128_t)in->data[2] * in->data[2]; // in2^2 + + Fp51ProcessCarry(h); + + out->data[0] = (uint64_t)h[0]; + out->data[1] = (uint64_t)h[1]; + out->data[2] = (uint64_t)h[2]; + out->data[3] = (uint64_t)h[3]; + out->data[4] = (uint64_t)h[4]; +} + +void Fp51MulScalar(Fp51 *out, const Fp51 *in, const uint32_t scalar) +{ + __uint128_t h[5]; + h[0] = in->data[0] * (__uint128_t)scalar; + h[1] = in->data[1] * (__uint128_t)scalar; + h[2] = in->data[2] * (__uint128_t)scalar; + h[3] = in->data[3] * (__uint128_t)scalar; + h[4] = in->data[4] * (__uint128_t)scalar; + + Fp51ProcessCarry(h); + + out->data[0] = (uint64_t)h[0]; + out->data[1] = (uint64_t)h[1]; + out->data[2] = (uint64_t)h[2]; + out->data[3] = (uint64_t)h[3]; + out->data[4] = (uint64_t)h[4]; +} + +/* out = in1 ^ (4 * 2 ^ (2 * times)) * in2 */ +static inline void Fp51MultiSquare(Fp51 *in1, Fp51 *in2, Fp51 *out, int32_t times) +{ + int32_t i; + Fp51 temp1, temp2; + Fp51Square(&temp1, in1); + Fp51Square(&temp2, &temp1); + for (i = 0; i < times; i++) { + Fp51Square(&temp1, &temp2); + Fp51Square(&temp2, &temp1); + } + Fp51Mul(out, in2, &temp2); +} + +/* out = a ^ -1 */ +static void Fp51Invert(Fp51 *out, const Fp51 *a) +{ + Fp51 a0; /* save a^1 */ + Fp51 a1; /* save a^2 */ + Fp51 a2; /* save a^11 */ + Fp51 a3; /* save a^(2^5-1) */ + Fp51 a4; /* save a^(2^10-1) */ + Fp51 a5; /* save a^(2^20-1) */ + Fp51 a6; /* save a^(2^40-1) */ + Fp51 a7; /* save a^(2^50-1) */ + Fp51 a8; /* save a^(2^100-1) */ + Fp51 a9; /* save a^(2^200-1) */ + Fp51 a10; /* save a^(2^250-1) */ + Fp51 temp1, temp2; + + /* We know a×b=1(mod p), then a and b are inverses of mod p, i.e. a=b^(-1), b=a^(-1); + * According to Fermat's little theorem a^(p-1)=1(mod p), so a*a^(p-2)=1(mod p); + * So the inverse element of a is a^(-1) = a^(p-2)(mod p) + * Here it is, p=2^255-19, thus we need to compute a^(2^255-21)(mod(2^255-19)) + */ + + /* a^1 */ + CURVE25519_FP51_COPY(a0.data, a->data); + + /* a^2 */ + Fp51Square(&a1, &a0); + + /* a^4 */ + Fp51Square(&temp1, &a1); + + /* a^8 */ + Fp51Square(&temp2, &temp1); + + /* a^9 */ + Fp51Mul(&temp1, &a0, &temp2); + + /* a^11 */ + Fp51Mul(&a2, &a1, &temp1); + + /* a^22 */ + Fp51Square(&temp2, &a2); + + /* a^(2^5-1) = a^(9+22) */ + Fp51Mul(&a3, &temp1, &temp2); + + /* a^(2^10-1) = a^(2^10-2^5) * a^(2^5-1) */ + Fp51Square(&temp1, &a3); + Fp51Square(&temp2, &temp1); + Fp51Square(&temp1, &temp2); + Fp51Square(&temp2, &temp1); + Fp51Square(&temp1, &temp2); + Fp51Mul(&a4, &a3, &temp1); + + /* a^(2^20-1) = a^(2^20-2^10) * a^(2^10-1) */ + Fp51MultiSquare(&a4, &a4, &a5, 4); // (2 * 2) ^ 4 + + /* a^(2^40-1) = a^(2^40-2^20) * a^(2^20-1) */ + Fp51MultiSquare(&a5, &a5, &a6, 9); // (2 * 2) ^ 9 + + /* a^(2^50-1) = a^(2^50-2^10) * a^(2^10-1) */ + Fp51MultiSquare(&a6, &a4, &a7, 4); // (2 * 2) ^ 4 + + /* a^(2^100-1) = a^(2^100-2^50) * a^(2^50-1) */ + Fp51MultiSquare(&a7, &a7, &a8, 24); // (2 * 2) ^ 24 + + /* a^(2^200-1) = a^(2^200-2^100) * a^(2^100-1) */ + Fp51MultiSquare(&a8, &a8, &a9, 49); // (2 * 2) ^ 49 + + /* a^(2^250-1) = a^(2^250-2^50) * a^(2^50-1) */ + Fp51MultiSquare(&a9, &a7, &a10, 24); // (2 * 2) ^ 24 + + /* a^(2^5*(2^250-1)) = (a^(2^250-1))^5 */ + Fp51Square(&temp1, &a10); + Fp51Square(&temp2, &temp1); + Fp51Square(&temp1, &temp2); + Fp51Square(&temp2, &temp1); + Fp51Square(&temp1, &temp2); + + /* The output: a^(2^255-21) = a(2^5*(2^250-1)+11) = a^(2^5*(2^250-1)) * a^11 */ + Fp51Mul(out, &a2, &temp1); +} + +void ScalarMultiPoint(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) +{ + uint8_t k[32]; + const uint8_t *u = point; + int32_t t; + uint32_t swap; + uint32_t kTemp; + Fp51 x1, x2, x3; + Fp51 z2, z3; + Fp51 t1, t2; + + /* Decord the scalar into k */ + CURVE25519_DECODE_LITTLE_ENDIAN(k, scalar); + + /* Reference RFC 7748 section 5: The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519 */ + Fp51DataToPoly(&x1, u); + CURVE25519_FP51_SET(x2.data, 1); + CURVE25519_FP51_SET(z2.data, 0); + CURVE25519_FP51_COPY(x3.data, x1.data); + CURVE25519_FP51_SET(z3.data, 1); + swap = 0; + + /* "bits" parameter set to 255 for x25519 */ /* For t = bits-1(254) down to 0: */ + for (t = 254; t >= 0; t--) { + /* t >> 3: calculation the index of bit; t & 7: Obtains the corresponding bit in the byte */ + kTemp = (k[(uint32_t)t >> 3] >> ((uint32_t)t & 7)) & 1; /* kTemp = (k >> t) & 1 */ + swap ^= kTemp; /* swap ^= kTemp */ + CURVE25519_FP51_CSWAP(swap, x2.data, x3.data); /* (x_2, x_3) = cswap(swap, x_2, x_3) */ + CURVE25519_FP51_CSWAP(swap, z2.data, z3.data); /* (z_2, z_3) = cswap(swap, z_2, z_3) */ + swap = kTemp; /* swap = kTemp */ + CURVE25519_FP51_SUB(t1.data, x3.data, z3.data); /* x3 = D */ + CURVE25519_FP51_SUB(t2.data, x2.data, z2.data); /* t2 = B */ + CURVE25519_FP51_ADD(x2.data, x2.data, z2.data); /* t1 = A */ + CURVE25519_FP51_ADD(z2.data, x3.data, z3.data); /* x2 = C */ + + Fp51Mul(&z3, &t1, &x2); + Fp51Mul(&z2, &z2, &t2); + Fp51Square(&t1, &t2); + Fp51Square(&t2, &x2); + + CURVE25519_FP51_ADD(x3.data, z3.data, z2.data); + CURVE25519_FP51_SUB(z2.data, z3.data, z2.data); + Fp51Mul(&x2, &t2, &t1); + CURVE25519_FP51_SUB(t2.data, t2.data, t1.data); + Fp51Square(&z2, &z2); + Fp51MulScalar(&z3, &t2, 121666); // z2 *= 121665 + 1 = 121666 + Fp51Square(&x3, &x3); + CURVE25519_FP51_ADD(t1.data, t1.data, z3.data); + Fp51Mul(&z3, &x1, &z2); + Fp51Mul(&z2, &t2, &t1); + } + + CURVE25519_FP51_CSWAP(swap, x2.data, x3.data); + CURVE25519_FP51_CSWAP(swap, z2.data, z3.data); + /* Return x2 * (z2 ^ (p - 2)) */ + Fp51Invert(&t1, &z2); + Fp51Mul(&t2, &x2, &t1); + Fp51PolyToData(&t2, out); + BSL_SAL_CleanseData(k, sizeof(k)); +} + +#else + +void FpMulScalar(Fp25 *out, const Fp25 *p, const int32_t scalar) +{ + int64_t s = (int64_t)scalar; + uint64_t over; + uint64_t result[10]; + uint64_t mul19; + uint64_t t1; + uint64_t signMask1; + uint64_t signMask2; + + /* Could be more than 32 bits but not be more than 64 bits */ + CURVE25519_FP_MUL_SCALAR(result, p->data, s); + + /* Process Carry */ + /* the radix 2^25.5 representation: + * f0+2^26*f1+2^51*f2+2^77*f3+2^102*f4+2^128*f5+2^153*f6+2^179*f7+2^204*f8+2^230*f9 */ + over = result[9] + (1 << 24); /* carry chain: index 9->0; 2^25 progressiv, left shift by 24 bits */ + signMask1 = MASK_HIGH64(25) & (-((over) >> 63)); /* 2^25 progressiv, shift 63 for sign */ + t1 = (over >> 25) | signMask1; + mul19 = (t1 + (t1 << 1) + (t1 << 4)); /* 19 = 1 + 2^1 + 2^4 */ + result[0] += mul19; /* carry chain: index 9->0 */ + result[9] -= CURVE25519_MASK_HIGH_39 & over; + + /* carry chain: index 1->2; 2^25 progressiv(26->51) */ + /* carry chain: index 1->2; 2^25 progressiv, left shift by 24 bits */ + PROCESS_CARRY(result[1], result[2], signMask1, over, 24); + + /* carry chain: index 3->4; 2^25 progressiv(77->102) */ + /* carry chain: index 3->4; 2^25 progressiv, left shift by 24 bits */ + PROCESS_CARRY(result[3], result[4], signMask1, over, 24); + + /* carry chain: index 5->6; 2^25 progressiv(128->153) */ + /* carry chain: index 5->6; 2^25 progressiv, left shift by 24 bits */ + PROCESS_CARRY(result[5], result[6], signMask1, over, 24); + + /* carry chain: index 7->8; 2^25 progressiv(179->204) */ + /* carry chain: index 7->8; 2^25 progressiv, left shift by 24 bits */ + PROCESS_CARRY(result[7], result[8], signMask1, over, 24); + + /* carry chain: index 0->1; 2^26 progressiv(0->26) */ + /* carry chain: index 0->1; 2^26 progressiv, left shift by 25 bits */ + PROCESS_CARRY(result[0], result[1], signMask2, over, 25); + + /* carry chain: index 2->3; 2^26 progressiv(51->77) */ + /* carry chain: index 2->3; 2^26 progressiv, left shift by 25 bits */ + PROCESS_CARRY(result[2], result[3], signMask2, over, 25); + + /* carry chain: index 4->5; 2^26 progressiv(102->128) */ + /* carry chain: index 4->5; 2^26 progressiv, left shift by 25 bits */ + PROCESS_CARRY(result[4], result[5], signMask2, over, 25); + + /* carry chain: index 6->7; 2^26 progressiv(153->179) */ + /* carry chain: index 6->7; 2^26 progressiv, left shift by 25 bits */ + PROCESS_CARRY(result[6], result[7], signMask2, over, 25); + + /* carry chain: index 8->9; 2^26 progressiv(204->230) */ + /* carry chain: index 8->9; 2^26 progressiv, left shift by 25 bits */ + PROCESS_CARRY(result[8], result[9], signMask2, over, 25); + + /* The result would not be more than 32 bits */ + out->data[0] = (int32_t)result[0]; + out->data[1] = (int32_t)result[1]; + out->data[2] = (int32_t)result[2]; + out->data[3] = (int32_t)result[3]; + out->data[4] = (int32_t)result[4]; + out->data[5] = (int32_t)result[5]; + out->data[6] = (int32_t)result[6]; + out->data[7] = (int32_t)result[7]; + out->data[8] = (int32_t)result[8]; + out->data[9] = (int32_t)result[9]; + + (void)memset_s(result, sizeof(result), 0, sizeof(result)); +} + +void ScalarMultiPoint(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) +{ + uint8_t k[32]; + const uint8_t *u = point; + int32_t t; + uint32_t swap; + uint32_t kTemp; + Fp25 x1, x2, x3, z2, z3, t1, t2, t3; + + /* Decord the scalar into k */ + CURVE25519_DECODE_LITTLE_ENDIAN(k, scalar); + + /* Reference RFC 7748 section 5: The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519 */ + DataToPolynomial(&x1, u); + CURVE25519_FP_SET(x2.data, 1); + CURVE25519_FP_SET(z2.data, 0); + CURVE25519_FP_COPY(x3.data, x1.data); + CURVE25519_FP_SET(z3.data, 1); + swap = 0; + + /* "bits" parameter set to 255 for x25519 */ /* For t = bits-1(254) down to 0: */ + for (t = 254; t >= 0; t--) { + /* t >> 3: calculation the index of bit; t & 7: Obtains the corresponding bit in the byte */ + kTemp = (k[(uint32_t)t >> 3] >> ((uint32_t)t & 7)) & 1; /* kTemp = (k >> t) & 1 */ + swap ^= kTemp; /* swap ^= kTemp */ + CURVE25519_FP_CSWAP(swap, x2.data, x3.data); /* (x_2, x_3) = cswap(swap, x_2, x_3) */ + CURVE25519_FP_CSWAP(swap, z2.data, z3.data); /* (z_2, z_3) = cswap(swap, z_2, z_3) */ + swap = kTemp; /* swap = kTemp */ + CURVE25519_FP_ADD(t1.data, x2.data, z2.data); /* t1 = A */ + CURVE25519_FP_SUB(t2.data, x2.data, z2.data); /* t2 = B */ + CURVE25519_FP_ADD(x2.data, x3.data, z3.data); /* x2 = C */ + CURVE25519_FP_SUB(x3.data, x3.data, z3.data); /* x3 = D */ + FpMul(&z2, &x3, &t1); /* z2 = DA */ + FpMul(&z3, &x2, &t2); /* z3 = CB */ + FpSquare(&t1, &t1); /* t1 = AA */ + FpSquare(&t2, &t2); /* t2 = BB */ + CURVE25519_FP_SUB(t3.data, t1.data, t2.data); /* t3 = E = AA - BB */ + CURVE25519_FP_ADD(x3.data, z2.data, z3.data); /* x3 = DA + CB */ + FpSquare(&x3, &x3); /* x3 = (DA + CB)^2 */ + CURVE25519_FP_SUB(z3.data, z2.data, z3.data); /* z3 = DA - CB */ + FpSquare(&z3, &z3); /* z3 = (DA - CB)^2 */ + FpMul(&z3, &x1, &z3); /* z3 = x1 * (DA - CB)^2 */ + FpMul(&x2, &t1, &t2); /* x2 = AA * BB */ + FpMul(&t1, &t3, &t1); /* t1 = E * AA */ + FpSquare(&z2, &t3); /* z2 = E^2 */ + /* Reference RFC 7748 section 5: The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519 */ + FpMulScalar(&z2, &z2, 121665); /* z2 = a24 * E^2 */ + CURVE25519_FP_ADD(z2.data, t1.data, z2.data); /* z2 = E * (AA + a24 * E) */ + } + + CURVE25519_FP_CSWAP(swap, x2.data, x3.data); + CURVE25519_FP_CSWAP(swap, z2.data, z3.data); + /* Return x2 * (z2 ^ (p - 2)) */ + FpInvert(&t1, &z2); + FpMul(&t2, &x2, &t1); + PolynomialToData(out, &t2); +} +#endif // uint128 +#endif /* HITLS_CRYPTO_X25519 */ diff --git a/crypto/curve25519/src/x25519_asm.h b/crypto/curve25519/src/x25519_asm.h new file mode 100644 index 00000000..10c948b9 --- /dev/null +++ b/crypto/curve25519/src/x25519_asm.h @@ -0,0 +1,71 @@ +/* + * 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 X25519_ASM_H +#define X25519_ASM_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_X25519 + +#include "curve25519_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Function description: out = f * g (mod p), p = 2 ^ 255 - 19, which is the modulus of curve25519 field. + * Function prototype: void Fp51Mul(Fp51 *out, const Fp51 *f, const Fp51 *g); + * Input register: rdi: out; rsi: f; rdx: g; fp51 is an array of [u64; 5]. + * rdi: out, array pointer of output parameter fp51. + * rsi: pointer f of the input source data fp51 array. + * rdi: pointer g of the input source data fp51 array. + * Modify the register as follows: rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, r8-r15. + * Output register: None + * Function/Macro Call: None + */ +void Fp51Mul(Fp51 *out, const Fp51 *f, const Fp51 *g); + +/** + * Function description: out = f ^ 2 (mod p), p = 2 ^ 255 - 19, which is the modulus of curve25519 field. + * Function prototype: void Fp51Square(Fp51 *out, const Fp51 *f); + * Input register: rdi: out; rsi: f; fp51 is an array of [u64; 5] + * rdi: out, array pointer of output parameter fp51. + * rsi: pointer f of the input source data fp51 array. + * Modify the register as follows: rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, r8-r15. + * Output register: None + * Function/Macro Call: None + */ +void Fp51Square(Fp51 *out, const Fp51 *f); + +/** + * Function description: out = f * 121666 (mod p), p = 2 ^ 255 - 19, which is the modulus of curve25519 field. + * Function prototype: void Fp51MulScalar(Fp51 *out, const Fp51 *f, const uint32_t scalar); + * Input register: rdi: out; rsi: f; fp51 is an array of [u64; 5] + * rdi: out, array pointer of output parameter fp51. + * rsi: pointer f of the input source data fp51 array. + * Modify the register as follows: rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, r8-r15. + * Output register: None + * Function/Macro Call: None + */ +void Fp51MulScalar(Fp51 *out, const Fp51 *in); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_CURVE25519 + +#endif // X25519_ASM_H diff --git a/crypto/dh/include/crypt_dh.h b/crypto/dh/include/crypt_dh.h new file mode 100644 index 00000000..7660d8d4 --- /dev/null +++ b/crypto/dh/include/crypt_dh.h @@ -0,0 +1,301 @@ +/* + * 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_DH_H +#define CRYPT_DH_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_DH + +#include +#include "crypt_types.h" +#include "crypt_algid.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#ifndef CRYPT_DH_TRY_CNT_MAX +#define CRYPT_DH_TRY_CNT_MAX 100 +#endif + +/* DH key parameter */ +typedef struct DH_Para CRYPT_DH_Para; + +/* DH key context */ +typedef struct DH_Ctx CRYPT_DH_Ctx; + +/** + * @ingroup dh + * @brief dh Allocate the context of dh. + * + * @retval (CRYPT_DH_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_DH_Ctx *CRYPT_DH_NewCtx(void); + +/** + * @ingroup dh + * @brief Copy the DH context. After the duplicated context is used up, call CRYPT_DH_FreeCtx to release the memory. + * + * @param ctx [IN] Source DH context + * + * @return CRYPT_DH_Ctx DH context pointer + * If the operation fails, null is returned. + */ +CRYPT_DH_Ctx *CRYPT_DH_DupCtx(CRYPT_DH_Ctx *ctx); + +/** + * @ingroup dh + * @brief dh Release context structure of dh key + * + * @param ctx [IN] Indicates the pointer to the context structure to be released. The ctx is set NULL by the invoker. + */ +void CRYPT_DH_FreeCtx(CRYPT_DH_Ctx *ctx); + +/** + * @ingroup dh + * @brief dh Allocate key parameter structure space + * + * @param para [IN] DH External parameter + * + * @retval (CRYPT_DH_Para *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_DH_Para *CRYPT_DH_NewPara(const CRYPT_DhPara *para); + +/** + * @ingroup dh + * @brief Release dh key parameter structure + * + * @param para [IN] Pointer to the key parameter structure to be released. The parameter is set NULL by the invoker. + */ +void CRYPT_DH_FreePara(CRYPT_DH_Para *dhPara); + +/** + * @ingroup dh + * @brief Set the data of the key parameter structure to the key structure. + * + * @param ctx [IN] Key structure for setting related parameters. The key specification is 1024-8192 bits. + * @param para [IN] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DH_PARA_ERROR The key parameter data is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Internal Memory Allocation Error + * @retval BN error code: An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DH_SetPara(CRYPT_DH_Ctx *ctx, const CRYPT_DH_Para *para); + +/** + * @ingroup dh + * @brief Obtain the key structure parameters. + * + * @param ctx [IN] Key structure + * @param para [OUT] Obtained key parameter. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DH_PARA_ERROR The key parameter data is incorrect. + * @retval BN error code: An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DH_GetPara(const CRYPT_DH_Ctx *ctx, CRYPT_DhPara *para); + +/** + * @ingroup dh + * @brief Set a parameter based on the parameter ID. + * + * @param id [IN] Parameter ID + * + * @retval (CRYPT_DH_Para *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_DH_Para *CRYPT_DH_NewParaById(CRYPT_PKEY_ParaId id); + +/** + * @ingroup dh + * @brief Obtain the parameter ID. + * + * @param ctx [IN] Key structure + * + * @retval ID. If the context is invalid, CRYPT_PKEY_PARAID_MAX is returned. + */ +CRYPT_PKEY_ParaId CRYPT_DH_GetParaId(const CRYPT_DH_Ctx *ctx); + +/** + * @ingroup dh + * @brief Obtain the valid length of the key. + * + * @param ctx [IN] Structure from which the key length is expected to be obtained + * + * @retval 0 The input is incorrect or the corresponding key structure does not have a valid key length. + * @retval uint32_t Valid key length + */ +uint32_t CRYPT_DH_GetBits(const CRYPT_DH_Ctx *ctx); + +/** + * @ingroup dh + * @brief Generate the DH key pair. + * + * @param ctx [IN] dh Context structure + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_DH_PARA_ERROR The key parameter data is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_DH_RAND_GENRATE_ERROR Unable to generate results within the specified number of attempts + * @retval BN error code: An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_DH_Gen(CRYPT_DH_Ctx *ctx); + +/** + * @ingroup dh + * @brief DH key exchange + * + * @param ctx [IN] dh Context structure + * @param pubKey [IN] Public key data + * @param shareKey [OUT] Shared key + * @param shareKeyLen [IN/OUT] The input parameter is the length of the shareKey, + * and the output parameter is the valid length of the shareKey. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_DH_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval CRYPT_DH_KEYINFO_ERROR The key information is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Key exchange succeeded. + */ +int32_t CRYPT_DH_ComputeShareKey(const CRYPT_DH_Ctx *ctx, const CRYPT_DH_Ctx *pubKey, + uint8_t *shareKey, uint32_t *shareKeyLen); + +/** + * @ingroup dh + * @brief DH Set the private key. + * + * @param ctx [OUT] dh Context structure + * @param prv [IN] Private key + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_DH_PARA_ERROR The key parameter is incorrect. + * @retval CRYPT_DH_KEYINFO_ERROR The key information is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DH_SetPrvKey(CRYPT_DH_Ctx *ctx, const CRYPT_DhPrv *prv); + +/** + * @ingroup dh + * @brief DH Set the public key data. + * + * @param ctx [OUT] dh Context structure + * @param pub [IN] Public key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_DH_PARA_ERROR The key parameter data is incorrect. + * @retval CRYPT_DH_KEYINFO_ERROR The key information is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DH_SetPubKey(CRYPT_DH_Ctx *ctx, const CRYPT_DhPub *pub); + +/** + * @ingroup dh + * @brief DH Obtain the private key data. + * + * @param ctx [IN] dh Context structure + * @param prv [OUT] Private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_DH_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval CRYPT_DH_KEYINFO_ERROR The key information is incorrect. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS obtained successfully. + */ +int32_t CRYPT_DH_GetPrvKey(const CRYPT_DH_Ctx *ctx, CRYPT_DhPrv *prv); + +/** + * @ingroup dh + * @brief DH Obtain the public key data. + * + * @param ctx [IN] dh Context structure + * @param pub [OUT] Public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_DH_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval CRYPT_DH_KEYINFO_ERROR The key information is incorrect. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_DH_GetPubKey(const CRYPT_DH_Ctx *ctx, CRYPT_DhPub *pub); + +/** + * @ingroup dh + * @brief Check the key pair consistency. + * + * @param ctx [IN] dh Context structure + * + * @return CRYPT_SUCCESS succeeded. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_DH_Check(const CRYPT_DH_Ctx *ctx); + +/** + * @ingroup dh + * @brief dh Compare public keys and parameters + * + * @param a [IN] dh Context structure + * @param b [IN] dh Context structure + * + * @return CRYPT_SUCCESS is the same + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_DH_KEYINFO_ERROR The key information is incorrect. + * @retval CRYPT_DH_PUBKEY_NOT_EQUAL Public Keys are not equal + * @retval CRYPT_DH_PARA_ERROR The parameter data is incorrect. + * @retval CRYPT_DH_PARA_NOT_EQUAL The parameters are not equal. + */ +int32_t CRYPT_DH_Cmp(const CRYPT_DH_Ctx *a, const CRYPT_DH_Ctx *b); + +/** + * @ingroup dh + * @brief DH control interface + * + * @param ctx [IN] dh Context structure + * @param opt [IN] Operation mode + * @param val [IN] Parameter + * @param len [IN] val length + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_SUCCESS obtained successfully. + */ +int32_t CRYPT_DH_Ctrl(CRYPT_DH_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +/** + * @ingroup dh + * @brief dh get security bits + * + * @param ctx [IN] dh Context structure + * + * @retval security bits + */ +int32_t CRYPT_DH_GetSecBits(const CRYPT_DH_Ctx *ctx); +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_DH + +#endif // CRYPT_DH_H diff --git a/crypto/dh/src/dh_core.c b/crypto/dh/src/dh_core.c new file mode 100644 index 00000000..4aeb5451 --- /dev/null +++ b/crypto/dh/src/dh_core.c @@ -0,0 +1,824 @@ +/* + * 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_DH + +#include "crypt_errno.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_utils.h" +#include "crypt_dh.h" +#include "dh_local.h" +#include "sal_atomic.h" + +CRYPT_DH_Ctx *CRYPT_DH_NewCtx(void) +{ + CRYPT_DH_Ctx *ctx = BSL_SAL_Malloc(sizeof(CRYPT_DH_Ctx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)memset_s(ctx, sizeof(CRYPT_DH_Ctx), 0, sizeof(CRYPT_DH_Ctx)); + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +static CRYPT_DH_Para *ParaMemGet(uint32_t bits) +{ + CRYPT_DH_Para *para = BSL_SAL_Calloc(1u, sizeof(CRYPT_DH_Para)); + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + para->p = BN_Create(bits); + para->g = BN_Create(bits); + para->id = CRYPT_PKEY_PARAID_MAX; + if (para->p == NULL || para->g == NULL) { + CRYPT_DH_FreePara(para); + BSL_ERR_PUSH_ERROR(CRYPT_DH_CREATE_PARA_FAIL); + return NULL; + } + return para; +} + +static int32_t NewParaCheck(const CRYPT_DhPara *para) +{ + if (para == NULL || para->p == NULL || para->g == NULL || + para->pLen == 0 || para->gLen == 0 || (para->q == NULL && + para->qLen != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->pLen > BN_BITS_TO_BYTES(DH_MAX_PBITS)) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + if (para->gLen > para->pLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + if (para->q == NULL) { + return CRYPT_SUCCESS; + } + if (para->qLen > para->pLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + return CRYPT_SUCCESS; +} + +CRYPT_DH_Para *CRYPT_DH_NewPara(const CRYPT_DhPara *para) +{ + if (NewParaCheck(para) != CRYPT_SUCCESS) { + return NULL; + } + uint32_t modBits = BN_BYTES_TO_BITS(para->pLen); + CRYPT_DH_Para *retPara = ParaMemGet(modBits); + if (retPara == NULL) { + return NULL; + } + + int32_t ret = BN_Bin2Bn(retPara->p, para->p, para->pLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Bin2Bn(retPara->g, para->g, para->gLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (para->q == NULL) { + return retPara; // The parameter q does not exist, this function is ended early. + } + retPara->q = BN_Create(modBits); + if (retPara->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_CREATE_PARA_FAIL); + goto ERR; + } + ret = BN_Bin2Bn(retPara->q, para->q, para->qLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + retPara->id = CRYPT_PKEY_PARAID_MAX; // No ID is passed in this function. Assign a invalid ID temporarily. + return retPara; +ERR: + CRYPT_DH_FreePara(retPara); + return NULL; +} + +void CRYPT_DH_FreePara(CRYPT_DH_Para *dhPara) +{ + if (dhPara == NULL) { + return; + } + BN_Destroy(dhPara->p); + BN_Destroy(dhPara->q); + BN_Destroy(dhPara->g); + BSL_SAL_FREE(dhPara); +} + +void CRYPT_DH_FreeCtx(CRYPT_DH_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + int val = 0; + BSL_SAL_AtomicDownReferences(&(ctx->references), &val); + if (val > 0) { + return; + } + CRYPT_DH_FreePara(ctx->para); + BN_Destroy(ctx->x); + BN_Destroy(ctx->y); + BSL_SAL_ReferencesFree(&(ctx->references)); + BSL_SAL_FREE(ctx); +} + +static int32_t ParaQCheck(BN_BigNum *q, BN_BigNum *r) +{ + // 1. Determine the length. + if (BN_Bits(q) < DH_MIN_QBITS) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + // 2. Parity and even judgment + if (BN_GetBit(q, 0) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + // 3. Compare q and r. + if (BN_Cmp(q, r) >= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + + // 4. Check the pq multiple relationship. + BN_Optimizer *opt = BN_OptimizerCreate(); + if (opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = BN_Div(NULL, r, r, q, opt); + BN_OptimizerDestroy(opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // (p - 1) % q == 0 + if (!BN_IsZero(r)) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + return CRYPT_SUCCESS; +} + +static int32_t ParaDataCheck(const CRYPT_DH_Para *para) +{ + int32_t ret; + const BN_BigNum *p = para->p; + const BN_BigNum *g = para->g; + // 1. Determine the length. + uint32_t pBits = BN_Bits(p); + if (pBits < DH_MIN_PBITS || pBits > DH_MAX_PBITS) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + // 2. P parity and g value judgment + // p is an odd number + if (BN_GetBit(p, 0) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + // g != 0 && g != 1 + if (BN_IsZero(g) || BN_IsOne(g)) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + + BN_BigNum *r = BN_Create(pBits + 1); + if (r == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // r = p - 1 + ret = BN_SubLimb(r, p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // g < p - 1 + if (BN_Cmp(g, r) >= 0) { + ret = CRYPT_DH_PARA_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (para->q != NULL) { + ret = ParaQCheck(para->q, r); + } +ERR: + BN_Destroy(r); + return ret; +} + +static CRYPT_DH_Para *ParaDup(const CRYPT_DH_Para *para) +{ + CRYPT_DH_Para *ret = BSL_SAL_Malloc(sizeof(CRYPT_DH_Para)); + if (ret == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + ret->p = BN_Dup(para->p); + ret->q = BN_Dup(para->q); + ret->g = BN_Dup(para->g); + ret->id = para->id; + if (ret->p == NULL || ret->g == NULL) { + CRYPT_DH_FreePara(ret); + BSL_ERR_PUSH_ERROR(CRYPT_DH_CREATE_PARA_FAIL); + return NULL; + } + if (para->q != NULL && ret->q == NULL) { + CRYPT_DH_FreePara(ret); + BSL_ERR_PUSH_ERROR(CRYPT_DH_CREATE_PARA_FAIL); + return NULL; + } + return ret; +} + +CRYPT_DH_Ctx *CRYPT_DH_DupCtx(CRYPT_DH_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + CRYPT_DH_Ctx *newKeyCtx = BSL_SAL_Calloc(1, sizeof(CRYPT_DH_Ctx)); + if (newKeyCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + // If x, y and para is not empty, copy the value. + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->x, ctx->x, BN_Dup(ctx->x), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->y, ctx->y, BN_Dup(ctx->y), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->para, ctx->para, ParaDup(ctx->para), CRYPT_MEM_ALLOC_FAIL); + BSL_SAL_ReferencesInit(&(newKeyCtx->references)); + return newKeyCtx; + +ERR : + CRYPT_DH_FreeCtx(newKeyCtx); + return NULL; +} + +int32_t CRYPT_DH_SetPara(CRYPT_DH_Ctx *ctx, const CRYPT_DH_Para *para) +{ + if (ctx == NULL || para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = ParaDataCheck(para); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BN_Destroy(ctx->x); + BN_Destroy(ctx->y); + CRYPT_DH_FreePara(ctx->para); + ctx->x = NULL; + ctx->y = NULL; + ctx->para = ParaDup(para); + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_DH_GetPara(const CRYPT_DH_Ctx *ctx, CRYPT_DhPara *para) +{ + int32_t ret; + + if (ctx == NULL || para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + ret = BN_Bn2Bin(ctx->para->p, para->p, &(para->pLen)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (ctx->para->q == NULL) { + para->q = NULL; + para->qLen = 0; + } else { + ret = BN_Bn2Bin(ctx->para->q, para->q, &(para->qLen)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + ret = BN_Bn2Bin(ctx->para->g, para->g, &(para->gLen)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +/** + y != 0 + y != 1 + y < p - 1 + (y ^ q) mod p == 1 +*/ +static int32_t PubCheck(const BN_BigNum *y, const BN_BigNum *minP, + const BN_BigNum *q, BN_Mont *montP, BN_Optimizer *opt) +{ + // y != 0, y != 1 + if (BN_IsZero(y) || BN_IsOne(y)) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + // y < p - 1 + if (BN_Cmp(y, minP) >= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + if (q == NULL) { + return CRYPT_SUCCESS; // The parameter q does not exist, this function is ended early. + } + // Verify q. + BN_BigNum *r = BN_Create(BN_Bits(minP)); + if (r == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = BN_MontExp(r, y, q, montP, opt); + if (ret != CRYPT_SUCCESS) { + BN_Destroy(r); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (!BN_IsOne(r)) { + BN_Destroy(r); + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + BN_Destroy(r); + return CRYPT_SUCCESS; +} + +// Get p-2 or q-1 +static int32_t GetXLimb(BN_BigNum *xLimb, const BN_BigNum *p, const BN_BigNum *q) +{ + if (q != NULL) { + // xLimb = q - 1 + return BN_SubLimb(xLimb, q, 1); + } + // xLimb = p - 2 + return BN_SubLimb(xLimb, p, 2); +} + +static void RefreshCtx(CRYPT_DH_Ctx *dhCtx, BN_BigNum *x, BN_BigNum *y, int32_t ret) +{ + if (ret == CRYPT_SUCCESS) { + BN_Destroy(dhCtx->x); + BN_Destroy(dhCtx->y); + dhCtx->x = x; + dhCtx->y = y; + } else { + BN_Destroy(x); + BN_Destroy(y); + } +} + +int32_t CRYPT_DH_Gen(CRYPT_DH_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + int32_t ret; + int32_t cnt; + BN_BigNum *x = BN_Create(BN_Bits(ctx->para->p) + 1); + BN_BigNum *y = BN_Create(BN_Bits(ctx->para->p)); + BN_BigNum *minP = BN_Create(BN_Bits(ctx->para->p) + 1); + BN_BigNum *xLimb = BN_Create(BN_Bits(ctx->para->p) + 1); + BN_Mont *mont = BN_MontCreate(ctx->para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + if (x == NULL || y == NULL || minP == NULL || xLimb == NULL || mont == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_SubLimb(minP, ctx->para->p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = GetXLimb(xLimb, ctx->para->p, ctx->para->q); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (cnt = 0; cnt < CRYPT_DH_TRY_CNT_MAX; cnt++) { + /* Generate private key x for [1, q-1] or [1, p-2] */ + ret = BN_RandRange(x, xLimb); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_AddLimb(x, x, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* Calculate the public key y. */ + ret = BN_MontExpConsttime(y, ctx->para->g, x, mont, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* Check whether the public key meets the requirements. If not, try to generate the key again. */ + // y != 0, y != 1, y < p - 1 + if (BN_IsZero(y) || BN_IsOne(y) || BN_Cmp(y, minP) >= 0) { + continue; + } + goto ERR; // The function exits successfully. + } + ret = CRYPT_DH_RAND_GENERATE_ERROR; + BSL_ERR_PUSH_ERROR(ret); +ERR: + RefreshCtx(ctx, x, y, ret); + BN_Destroy(minP); + BN_Destroy(xLimb); + BN_MontDestroy(mont); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t ComputeShareKeyInputCheck(const CRYPT_DH_Ctx *ctx, const CRYPT_DH_Ctx *pubKey, + const uint8_t *shareKey, const uint32_t *shareKeyLen) +{ + if (ctx == NULL || pubKey == NULL || shareKey == NULL || shareKeyLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + if (ctx->x == NULL || pubKey->y == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + if (BN_Bytes(ctx->para->p) > *shareKeyLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DH_BUFF_LEN_NOT_ENOUGH; + } + return CRYPT_SUCCESS; +} + +static void CheckAndFillZero(uint8_t *shareKey, uint32_t *shareKeyLen, uint32_t bytes) +{ + int32_t i; + if (*shareKeyLen == bytes) { // (*shareKeyLen > bytes) is not possible + return; + } + uint32_t fill = bytes - *shareKeyLen; + for (i = (int32_t)*shareKeyLen - 1; i >= 0; i--) { + shareKey[i + (int32_t)fill] = shareKey[i]; + } + for (i = 0; i < (int32_t)fill; i++) { + shareKey[i] = 0; + } + *shareKeyLen = bytes; +} + +int32_t CRYPT_DH_ComputeShareKey(const CRYPT_DH_Ctx *ctx, const CRYPT_DH_Ctx *pubKey, + uint8_t *shareKey, uint32_t *shareKeyLen) +{ + uint32_t bytes = 0; + int32_t ret = ComputeShareKeyInputCheck(ctx, pubKey, shareKey, shareKeyLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BN_BigNum *minP = BN_Create(BN_Bits(ctx->para->p) + 1); + BN_BigNum *r = BN_Create(BN_Bits(ctx->para->p)); + BN_Mont *mont = BN_MontCreate(ctx->para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + if (minP == NULL || r == NULL || mont == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_SubLimb(minP, ctx->para->p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* Check whether the public key meets the requirements. */ + ret = PubCheck(pubKey->y, minP, ctx->para->q, mont, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_MontExpConsttime(r, pubKey->y, ctx->x, mont, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Bn2Bin(r, shareKey, shareKeyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + bytes = BN_Bytes(ctx->para->p); + CheckAndFillZero(shareKey, shareKeyLen, bytes); + +ERR: + BN_Destroy(minP); + BN_Destroy(r); + BN_MontDestroy(mont); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t PrvLenCheck(const CRYPT_DH_Ctx *ctx, const CRYPT_DhPrv *prv) +{ + if (ctx->para->q != NULL) { + if (BN_Bytes(ctx->para->q) < prv->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + } else { + if (BN_Bytes(ctx->para->p) < prv->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_DH_SetPrvKey(CRYPT_DH_Ctx *ctx, const CRYPT_DhPrv *prv) +{ + if (ctx == NULL || prv == NULL || prv->data == NULL || prv->len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_PARA_ERROR); + return CRYPT_DH_PARA_ERROR; + } + int32_t ret = PrvLenCheck(ctx, prv); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BN_BigNum *bnX = BN_Create(BN_BYTES_TO_BITS(prv->len)); + BN_BigNum *xLimb = BN_Create(BN_Bits(ctx->para->p) + 1); + if (bnX == NULL || xLimb == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = GetXLimb(xLimb, ctx->para->p, ctx->para->q); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Bin2Bn(bnX, prv->data, prv->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // Satisfy x <= q - 1 or x <= p - 2 + if (BN_Cmp(bnX, xLimb) > 0) { + ret = CRYPT_DH_KEYINFO_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // x != 0 + if (BN_IsZero(bnX)) { + ret = CRYPT_DH_KEYINFO_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + BN_Destroy(xLimb); + BN_Destroy(ctx->x); + ctx->x = bnX; + return ret; +ERR: + BN_Destroy(bnX); + BN_Destroy(xLimb); + return ret; +} + +// No parameter information is required for setting the public key. +// Therefore, the validity of the public key is not checked during the setting. +// The validity of the public key is checked during the calculation of the shared key. +int32_t CRYPT_DH_SetPubKey(CRYPT_DH_Ctx *ctx, const CRYPT_DhPub *pub) +{ + if (ctx == NULL || pub == NULL || pub->data == NULL || pub->len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pub->len > BN_BITS_TO_BYTES(DH_MAX_PBITS)) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + BN_BigNum *bnY = BN_Create(BN_BYTES_TO_BITS(pub->len)); + if (bnY == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = BN_Bin2Bn(bnY, pub->data, pub->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + BN_Destroy(ctx->y); + ctx->y = bnY; + return ret; +ERR: + BN_Destroy(bnY); + return ret; +} + +int32_t CRYPT_DH_GetPrvKey(const CRYPT_DH_Ctx *ctx, CRYPT_DhPrv *prv) +{ + if (ctx == NULL || prv == NULL || prv->data == NULL || prv->len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->x == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + if (ctx->para->q != NULL) { + if (BN_Bytes(ctx->para->q) > prv->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DH_BUFF_LEN_NOT_ENOUGH; + } + } else { + if (BN_Bytes(ctx->para->p) > prv->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DH_BUFF_LEN_NOT_ENOUGH; + } + } + int32_t ret = BN_Bn2Bin(ctx->x, prv->data, &(prv->len)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_DH_GetPubKey(const CRYPT_DH_Ctx *ctx, CRYPT_DhPub *pub) +{ + if (ctx == NULL || pub == NULL || pub->data == NULL || pub->len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->y == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + if (BN_Bytes(ctx->y) > pub->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DH_BUFF_LEN_NOT_ENOUGH; + } + int32_t ret = BN_Bn2Bin(ctx->y, pub->data, &(pub->len)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +uint32_t CRYPT_DH_GetBits(const CRYPT_DH_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return BN_Bits(ctx->para->p); +} + +int32_t CRYPT_DH_Check(const CRYPT_DH_Ctx *ctx) +{ + int32_t ret; + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->x == NULL || ctx->y == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_KEYINFO_ERROR); + return CRYPT_DH_KEYINFO_ERROR; + } + BN_Mont *mont = BN_MontCreate(ctx->para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *y = BN_Create(BN_Bits(ctx->para->p)); + if (y == NULL || mont == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // SP800-56A R3 Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency + ret = BN_MontExpConsttime(y, ctx->para->g, ctx->x, mont, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (BN_Cmp(y, ctx->y) != 0) { + ret = CRYPT_DH_PAIRWISE_CHECK_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + BN_Destroy(y); + BN_MontDestroy(mont); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t CRYPT_DH_Cmp(const CRYPT_DH_Ctx *a, const CRYPT_DH_Ctx *b) +{ + RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT); + + RETURN_RET_IF(a->y == NULL || b->y == NULL, CRYPT_DH_KEYINFO_ERROR); + RETURN_RET_IF(BN_Cmp(a->y, b->y) != 0, CRYPT_DH_PUBKEY_NOT_EQUAL); + + // para must be both null and non-null. + RETURN_RET_IF((a->para == NULL) != (b->para == NULL), CRYPT_DH_PARA_ERROR); + if (a->para != NULL) { + RETURN_RET_IF(BN_Cmp(a->para->p, b->para->p) != 0 || + BN_Cmp(a->para->q, b->para->q) != 0 || + BN_Cmp(a->para->g, b->para->g) != 0, + CRYPT_DH_PARA_NOT_EQUAL); + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_DH_Ctrl(CRYPT_DH_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL || val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len == (uint32_t)sizeof(int) && opt == CRYPT_CTRL_UP_REFERENCES) { + return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val); + } + BSL_ERR_PUSH_ERROR(CRYPT_DH_UNSUPPORTED_CTRL_OPTION); + return CRYPT_DH_UNSUPPORTED_CTRL_OPTION; +} + +/** + * @ingroup dh + * @brief dh get security bits + * + * @param ctx [IN] dh Context structure + * + * @retval security bits + */ +int32_t CRYPT_DH_GetSecBits(const CRYPT_DH_Ctx *ctx) +{ + if (ctx == NULL || ctx->para == NULL || ctx->para->p == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + if (ctx->para->q == NULL) { + return BN_SecBit(BN_Bits(ctx->para->p), -1); + } + return BN_SecBit(BN_Bits(ctx->para->p), BN_Bits(ctx->para->q)); +} + +#endif /* HITLS_CRYPTO_DH */ diff --git a/crypto/dh/src/dh_local.h b/crypto/dh/src/dh_local.h new file mode 100644 index 00000000..806bec98 --- /dev/null +++ b/crypto/dh/src/dh_local.h @@ -0,0 +1,56 @@ +/* + * 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 DH_LOCAL_H +#define DH_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_DH + +#include "crypt_bn.h" +#include "crypt_dh.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define DH_MIN_PBITS 768 // Minimum DH specification: 768 bits +#define DH_MAX_PBITS 8192 // Maximum DH specification: 8192 bits +#define DH_MIN_QBITS 160 // Minimum specification of DH parameter Q: 160 bits + +/* DH key parameter */ +struct DH_Para { + BN_BigNum *p; + BN_BigNum *q; + BN_BigNum *g; + CRYPT_PKEY_ParaId id; +}; + +/* DH key context */ +struct DH_Ctx { + BN_BigNum *x; // Private key + BN_BigNum *y; // Public key + CRYPT_DH_Para *para; // key parameter + BSL_SAL_RefCount references; +}; + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_DH + +#endif // CRYPT_DH_H diff --git a/crypto/dh/src/dh_para.c b/crypto/dh/src/dh_para.c new file mode 100644 index 00000000..ee10bfcc --- /dev/null +++ b/crypto/dh/src/dh_para.c @@ -0,0 +1,910 @@ +/* + * 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_DH + +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_errno.h" +#include "crypt_types.h" +#include "dh_local.h" +#include "crypt_dh.h" + +static uint8_t g_rfc3526_2409_primeG[] = { 0x02 }; + +static uint8_t g_rfc7919G[] = { 0x02 }; + +static uint8_t g_rfc2409_prime768P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static uint8_t g_rfc2409_prime1024P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static uint8_t g_rfc3526_prime1536P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static uint8_t g_rfc3526_prime2048P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static uint8_t g_rfc3526_prime3072P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static uint8_t g_rfc3526_prime4096P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static uint8_t g_rfc3526_prime6144P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; +static uint8_t g_rfc3526_prime8192P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, + 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, + 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, + 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, + 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, + 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, + 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, + 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, + 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, + 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, + 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, + 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, + 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, + 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, + 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, + 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, + 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe2048P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe2048Q[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, + 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, + 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, + 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, + 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, + 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, + 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, + 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, + 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, + 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, + 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, + 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, + 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, + 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, + 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, + 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe3072P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe3072Q[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, + 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, + 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, + 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, + 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, + 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, + 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, + 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, + 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, + 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, + 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, + 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, + 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, + 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, + 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, + 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, + 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, + 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, + 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, + 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, + 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, + 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, + 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, + 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe4096P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe4096Q[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, + 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, + 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, + 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, + 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, + 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, + 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, + 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, + 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, + 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, + 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, + 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, + 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, + 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, + 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, + 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, + 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, + 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, + 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, + 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, + 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, + 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, + 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, + 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78, 0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D, + 0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB, 0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C, + 0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02, 0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D, + 0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5, 0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19, + 0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62, 0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C, + 0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD, 0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E, + 0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66, 0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7, + 0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35, 0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70, + 0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe6144P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, + 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, + 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, + 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, + 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, + 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, + 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, + 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, + 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, + 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, + 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, + 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, + 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, + 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, + 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, + 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, + 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe6144Q[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, + 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, + 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, + 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, + 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, + 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, + 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, + 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, + 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, + 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, + 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, + 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, + 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, + 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, + 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, + 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, + 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, + 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, + 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, + 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, + 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, + 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, + 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, + 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78, 0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D, + 0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB, 0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C, + 0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02, 0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D, + 0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5, 0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19, + 0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62, 0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C, + 0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD, 0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E, + 0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66, 0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7, + 0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35, 0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70, + 0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81, 0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D, + 0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D, 0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53, + 0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64, 0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6, + 0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D, 0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38, + 0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F, 0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B, + 0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88, 0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C, + 0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1, 0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37, + 0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1, 0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA, + 0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0, 0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9, + 0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB, 0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41, + 0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F, 0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6, + 0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF, 0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23, + 0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5, 0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B, + 0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01, 0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82, + 0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B, 0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34, + 0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0, 0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A, + 0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe8192P[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, + 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, + 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, + 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, + 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, + 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, + 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, + 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, + 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, + 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, + 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, + 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, + 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, + 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, + 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, + 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, + 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, + 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, + 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, + 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, + 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, + 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, + 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, + 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, + 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, + 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, + 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, + 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, + 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, + 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, + 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, + 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, + 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static uint8_t g_rfc7919_ffdhe8192Q[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, + 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, + 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, + 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, + 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, + 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, + 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, + 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, + 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, + 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, + 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, + 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, + 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, + 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, + 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, + 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, + 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, + 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, + 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, + 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, + 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, + 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, + 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, + 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78, 0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D, + 0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB, 0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C, + 0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02, 0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D, + 0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5, 0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19, + 0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62, 0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C, + 0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD, 0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E, + 0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66, 0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7, + 0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35, 0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70, + 0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81, 0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D, + 0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D, 0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53, + 0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64, 0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6, + 0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D, 0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38, + 0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F, 0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B, + 0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88, 0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C, + 0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1, 0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37, + 0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1, 0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA, + 0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0, 0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9, + 0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB, 0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41, + 0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F, 0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6, + 0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF, 0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23, + 0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5, 0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B, + 0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01, 0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82, + 0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B, 0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34, + 0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0, 0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A, + 0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55, 0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C, + 0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32, 0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1, + 0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F, 0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77, + 0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14, 0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32, + 0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81, 0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2, + 0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41, 0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE, + 0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28, 0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11, + 0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A, 0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7, + 0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96, 0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E, + 0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD, 0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC, + 0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50, 0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18, + 0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B, 0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4, + 0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37, 0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18, + 0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F, 0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F, + 0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86, 0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E, + 0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7, 0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46, + 0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +typedef struct { + CRYPT_PKEY_ParaId id; + const CRYPT_Data *p; + const CRYPT_Data *q; + const CRYPT_Data *g; +} DH_PARA_VECTOR; + +static const CRYPT_Data G_VECTOR_RFC_3526_2409 = { + .data = (uint8_t *)g_rfc3526_2409_primeG, + .len = sizeof(g_rfc3526_2409_primeG) +}; + +static const CRYPT_Data G_VECTOR_RFC_7919 = { + .data = (uint8_t *)g_rfc7919G, + .len = sizeof(g_rfc7919G) +}; + +static const CRYPT_Data Q_VECTOR_RFC_3526_2409 = { + .data = NULL, + .len = 0 +}; + +static const CRYPT_Data Q_VECTOR_RFC_7919_2048 = { + .data = (uint8_t *)g_rfc7919_ffdhe2048Q, + .len = sizeof(g_rfc7919_ffdhe2048Q) +}; + +static const CRYPT_Data Q_VECTOR_RFC_7919_3072 = { + .data = (uint8_t *)g_rfc7919_ffdhe3072Q, + .len = sizeof(g_rfc7919_ffdhe3072Q) +}; + +static const CRYPT_Data Q_VECTOR_RFC_7919_4096 = { + .data = (uint8_t *)g_rfc7919_ffdhe4096Q, + .len = sizeof(g_rfc7919_ffdhe4096Q) +}; + +static const CRYPT_Data Q_VECTOR_RFC_7919_6144 = { + .data = (uint8_t *)g_rfc7919_ffdhe6144Q, + .len = sizeof(g_rfc7919_ffdhe6144Q) +}; + +static const CRYPT_Data Q_VECTOR_RFC_7919_8192 = { + .data = (uint8_t *)g_rfc7919_ffdhe8192Q, + .len = sizeof(g_rfc7919_ffdhe8192Q) +}; + +static const CRYPT_Data P_VECTORS_RFC2409_768 = { + .data = (uint8_t *)g_rfc2409_prime768P, + .len = sizeof(g_rfc2409_prime768P) +}; +static const CRYPT_Data P_VECTORS_RFC2409_1024 = { + .data = (uint8_t *)g_rfc2409_prime1024P, + .len = sizeof(g_rfc2409_prime1024P) +}; +static const CRYPT_Data P_VECTORS_RFC3526_1536 = { + .data = (uint8_t *)g_rfc3526_prime1536P, + .len = sizeof(g_rfc3526_prime1536P) +}; +static const CRYPT_Data P_VECTORS_RFC3526_2048 = { + .data = (uint8_t *)g_rfc3526_prime2048P, + .len = sizeof(g_rfc3526_prime2048P) +}; +static const CRYPT_Data P_VECTORS_RFC3526_3072 = { + .data = (uint8_t *)g_rfc3526_prime3072P, + .len = sizeof(g_rfc3526_prime3072P) +}; +static const CRYPT_Data P_VECTORS_RFC3526_4096 = { + .data = (uint8_t *)g_rfc3526_prime4096P, + .len = sizeof(g_rfc3526_prime4096P) +}; +static const CRYPT_Data P_VECTORS_RFC3526_6144 = { + .data = (uint8_t *)g_rfc3526_prime6144P, + .len = sizeof(g_rfc3526_prime6144P) +}; +static const CRYPT_Data P_VECTORS_RFC3526_8192 = { + .data = (uint8_t *)g_rfc3526_prime8192P, + .len = sizeof(g_rfc3526_prime8192P) +}; +static const CRYPT_Data P_VECTORS_RFC7919_2048 = { + .data = (uint8_t *)g_rfc7919_ffdhe2048P, + .len = sizeof(g_rfc7919_ffdhe2048P) +}; +static const CRYPT_Data P_VECTORS_RFC7919_3072 = { + .data = (uint8_t *)g_rfc7919_ffdhe3072P, + .len = sizeof(g_rfc7919_ffdhe3072P) +}; +static const CRYPT_Data P_VECTORS_RFC7919_4096 = { + .data = (uint8_t *)g_rfc7919_ffdhe4096P, + .len = sizeof(g_rfc7919_ffdhe4096P) +}; +static const CRYPT_Data P_VECTORS_RFC7919_6144 = { + .data = (uint8_t *)g_rfc7919_ffdhe6144P, + .len = sizeof(g_rfc7919_ffdhe6144P) +}; +static const CRYPT_Data P_VECTORS_RFC7919_8192 = { + .data = (uint8_t *)g_rfc7919_ffdhe8192P, + .len = sizeof(g_rfc7919_ffdhe8192P) +}; + +static const DH_PARA_VECTOR DH_PARA_VECTORS[] = { + { + .id = CRYPT_DH_RFC2409_768, + .p = &P_VECTORS_RFC2409_768, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC2409_1024, + .p = &P_VECTORS_RFC2409_1024, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC3526_1536, + .p = &P_VECTORS_RFC3526_1536, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC3526_2048, + .p = &P_VECTORS_RFC3526_2048, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC3526_3072, + .p = &P_VECTORS_RFC3526_3072, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC3526_4096, + .p = &P_VECTORS_RFC3526_4096, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC3526_6144, + .p = &P_VECTORS_RFC3526_6144, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC3526_8192, + .p = &P_VECTORS_RFC3526_8192, + .g = &G_VECTOR_RFC_3526_2409, + .q = &Q_VECTOR_RFC_3526_2409, + }, + { + .id = CRYPT_DH_RFC7919_2048, + .p = &P_VECTORS_RFC7919_2048, + .g = &G_VECTOR_RFC_7919, + .q = &Q_VECTOR_RFC_7919_2048, + }, + { + .id = CRYPT_DH_RFC7919_3072, + .p = &P_VECTORS_RFC7919_3072, + .g = &G_VECTOR_RFC_7919, + .q = &Q_VECTOR_RFC_7919_3072, + }, + { + .id = CRYPT_DH_RFC7919_4096, + .p = &P_VECTORS_RFC7919_4096, + .g = &G_VECTOR_RFC_7919, + .q = &Q_VECTOR_RFC_7919_4096, + }, + { + .id = CRYPT_DH_RFC7919_6144, + .p = &P_VECTORS_RFC7919_6144, + .g = &G_VECTOR_RFC_7919, + .q = &Q_VECTOR_RFC_7919_6144, + }, + { + .id = CRYPT_DH_RFC7919_8192, + .p = &P_VECTORS_RFC7919_8192, + .g = &G_VECTOR_RFC_7919, + .q = &Q_VECTOR_RFC_7919_8192, + } +}; + +static const DH_PARA_VECTOR *DhIdIsVaild(uint32_t id) +{ + for (uint32_t i = 0; i < sizeof(DH_PARA_VECTORS) / sizeof(DH_PARA_VECTORS[0]); i++) { + if (id == DH_PARA_VECTORS[i].id) { + return &DH_PARA_VECTORS[i]; + } + } + return NULL; +} + +CRYPT_DH_Para *CRYPT_DH_NewParaById(CRYPT_PKEY_ParaId id) +{ + CRYPT_DH_Para *retPara = NULL; + const DH_PARA_VECTOR *vector = DhIdIsVaild(id); + if (vector == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return NULL; + } + CRYPT_DhPara para; + para.p = vector->p->data; + para.pLen = vector->p->len; + para.q = vector->q->data; + para.qLen = vector->q->len; + para.g = vector->g->data; + para.gLen = vector->g->len; + + retPara = CRYPT_DH_NewPara(¶); + if (retPara == NULL) { + goto ERR; + } + retPara->id = id; + static const uint32_t list[] = { + CRYPT_DH_RFC3526_1536, CRYPT_DH_RFC3526_2048, CRYPT_DH_RFC3526_3072, + CRYPT_DH_RFC3526_4096, CRYPT_DH_RFC3526_6144, CRYPT_DH_RFC3526_8192, + }; + + for (uint32_t i = 0; i < sizeof(list) / sizeof(list[0]); i++) { + if (id == list[i]) { + /** + * NIST.SP.800-56Ar3 + * Appendix D + * Finite Field Cryptography Groups for Key Establishment: The following safe-prime + * groups are defined in RFC 3526 and RFC 7919 for use with key-agreement schemes that + * employ either the FFC DH or FFC MQV primitives. + * The domain parameters for these groups have the form ( p, q = (p − 1)/2, g = 2 ); the explicit + * values for p are provided in the RFCs + */ + retPara->q = BN_Dup(retPara->p); + if (retPara->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_CREATE_PARA_FAIL); + goto ERR; + } + // Shift to the right by 1 bit: q = (p-1)/2 + if (BN_Rshift(retPara->q, retPara->q, 1) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_DH_CREATE_PARA_FAIL); + goto ERR; + } + break; + } + } + return retPara; +ERR: + CRYPT_DH_FreePara(retPara); + return NULL; +} + +CRYPT_PKEY_ParaId CRYPT_DH_GetParaId(const CRYPT_DH_Ctx *ctx) +{ + if (ctx == NULL || ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_PKEY_PARAID_MAX); + return CRYPT_PKEY_PARAID_MAX; + } + return ctx->para->id; +} +#endif /* HITLS_CRYPTO_DH */ diff --git a/crypto/drbg/include/crypt_drbg.h b/crypto/drbg/include/crypt_drbg.h new file mode 100644 index 00000000..298c36e1 --- /dev/null +++ b/crypto/drbg/include/crypt_drbg.h @@ -0,0 +1,185 @@ +/* + * 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_DRBG_H +#define CRYPT_DRBG_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_DRBG + +#include +#include +#include "crypt_types.h" +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// hlcheck : health testing +// pr : prediction_resistance + +typedef struct DrbgCtx DRBG_Ctx; + +#define DRBG_MAX_LEN (0x7ffffff0) +#define DRBG_MAX_REQUEST (1 << 16) + +#ifndef DRBG_MAX_RESEED_INTERVAL +#define DRBG_MAX_RESEED_INTERVAL (10000) +#endif + +#define DRBG_HASH_MAX_MDSIZE (64) + +#ifdef HITLS_CRYPTO_DRBG_HASH +/** + * @ingroup drbg + * @brief Apply for a context for the Hash_DRBG. + * @brief This API does not support multiple threads. + * + * @param md HASH method + * @param seedMeth DRBG seed hook + * @param seedCtx DRBG seed context + * + * @retval DRBG_Ctx* Success + * @retval NULL failure + */ +DRBG_Ctx *DRBG_NewHashCtx(const EAL_MdMethod *md, const CRYPT_RandSeedMethod *seedMeth, void *seedCtx); +#endif + +#ifdef HITLS_CRYPTO_DRBG_HMAC +/** + * @ingroup drbg + * @brief Apply for a context for the HMAC_DRBG. + * @brief This API does not support multiple threads. + * + * @param hmacMeth HMAC method + * @param mdMeth hash method + * @param seedMeth DRBG seed hook + * @param seedCtx DRBG seed context + * + * @retval DRBG_Ctx* Success + * @retval NULL failure + */ +DRBG_Ctx *DRBG_NewHmacCtx(const EAL_MacMethod *hmacMeth, const EAL_MdMethod *mdMeth, + const CRYPT_RandSeedMethod *seedMeth, void *seedCtx); +#endif + +#ifdef HITLS_CRYPTO_DRBG_CTR +/** + * @ingroup drbg + * @brief Apply for a context for the CTR_DRBG. + * @brief This API does not support multiple threads. + * + * @param ciphMeth AES method + * @param keyLen Key length + * @param isUsedDf Indicates whether to use derivation function. + * @param seedMeth DRBG seed hook + * @param seedCtx DRBG seed context + * + * @retval DRBG_Ctx* Success + * @retval NULL failure + */ +DRBG_Ctx *DRBG_NewCtrCtx(const EAL_CipherMethod *ciphMeth, const uint32_t keyLen, const bool isUsedDf, + const CRYPT_RandSeedMethod *seedMeth, void *seedCtx); +#endif + +/** + * @ingroup drbg + * @brief Release the DRBG context. + * @brief This API does not support multiple threads. + * + * @param ctx DRBG context + * + * @retval None + */ +void DRBG_Free(DRBG_Ctx *ctx); + +/** + * @ingroup drbg + * @brief Instantiating a DRBG based on personalization string. + * @brief This API does not support multiple threads. + * + * @param ctx DRBG context + * @param person Personalization string. The personalization string can be NULL. + * @param persLen Personalization string length + * + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_DRBG_ERR_STATE The DRBG status is incorrect. + * @retval CRYPT_DRBG_FAIL_GET_ENTROPY Failed to obtain the entropy. + * @retval CRYPT_DRBG_FAIL_GET_NONCE Failed to obtain the nonce. + * @retval Hash function error code: Failed to invoke the hash function. + */ +int32_t DRBG_Instantiate(DRBG_Ctx *ctx, const uint8_t *person, uint32_t persLen); + +/** + * @ingroup drbg + * @brief Reseeding the DRBG. + * @brief The additional input can be NULL. This API does not support multiple threads. + * + * @param ctx DRBG context + * @param adin Additional input. The data can be NULL. + * @param adinLen Additional input length + * + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_DRBG_ERR_STATE The DRBG status is incorrect. + * @retval CRYPT_DRBG_FAIL_GET_ENTROPY Failed to obtain the entropy. + * @retval Hash function error code: Failed to invoke the hash function. + */ +int32_t DRBG_Reseed(DRBG_Ctx *ctx, const uint8_t *adin, uint32_t adinLen); + +/** + * @ingroup drbg + * @brief Generating pseudorandom bits using a DRBG. + * @brief The additional input can be null. The user specifies the additional obfuscation data. + * This API does not support multiple threads. + * @brief External invoking must have a recovery mechanism after the status is abnormal. + * + * @param ctx DRBG context + * @param out Output BUF + * @param outLen Output length + * @param adin Additional input. The data can be empty. + * @param adinLen Additional input length + * @param pr Predicted resistance. If this parameter is set to true, reseed is executed each time. + * + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_NULL_INPUT Invalid null pointer + * @retval CRYPT_DRBG_ERR_STATE The DRBG status is incorrect. + * @retval Hash function error code: Failed to invoke the hash function. + */ +int32_t DRBG_Generate(DRBG_Ctx *ctx, + uint8_t *out, uint32_t outLen, + const uint8_t *adin, uint32_t adinLen, bool pr); + +/** + * @ingroup drbg + * @brief Remove the DRBG instantiation + * @brief This API does not support multiple threads. + * + * @param ctx DRBG context + * + * @retval CRYPT_SUCCESS Removed successfully. + * @retval CRYPT_NULL_INPUT Invalid null pointer + */ +int32_t DRBG_Uninstantiate(DRBG_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_DRBG + +#endif // CRYPT_DRBG_H diff --git a/crypto/drbg/src/drbg.c b/crypto/drbg/src/drbg.c new file mode 100644 index 00000000..6aff262a --- /dev/null +++ b/crypto/drbg/src/drbg.c @@ -0,0 +1,355 @@ +/* + * 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_DRBG + +#include +#include +#include "crypt_types.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "drbg_local.h" + + +#define DRBG_NONCE_FROM_ENTROPY (2) + +// According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL +static void DRBG_CleanEntropy(DRBG_Ctx *ctx, CRYPT_Data *entropy) +{ + CRYPT_RandSeedMethod *seedMeth = NULL; + + if (ctx == NULL || CRYPT_IsDataNull(entropy)) { + return; + } + + seedMeth = &ctx->seedMeth; + + if (seedMeth->cleanEntropy != NULL) { + seedMeth->cleanEntropy(ctx->seedCtx, entropy); + } + + entropy->data = NULL; + entropy->len = 0; + + return; +} + +// According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL +static int32_t DRBG_GetEntropy(DRBG_Ctx *ctx, CRYPT_Data *entropy, bool addEntropy) +{ + int32_t ret; + CRYPT_RandSeedMethod *seedMeth = NULL; + CRYPT_Range entropyRange = ctx->entropyRange; + uint32_t strength = ctx->strength; + + seedMeth = &ctx->seedMeth; + + if (addEntropy) { + strength += strength / DRBG_NONCE_FROM_ENTROPY; + entropyRange.min += ctx->nonceRange.min; + entropyRange.max += ctx->nonceRange.max; + } + + if (seedMeth->getEntropy == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY); + return CRYPT_DRBG_FAIL_GET_ENTROPY; + } + + // CPRNG is implemented by hooks, in DRBG, the CPRNG is not verified, + // but only the entropy source pointer and its length are verified. + ret = seedMeth->getEntropy(ctx->seedCtx, entropy, strength, &entropyRange); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY); + return CRYPT_DRBG_FAIL_GET_ENTROPY; + } + + if (CRYPT_CHECK_DATA_INVALID(entropy)) { + goto ERR; + } + + if (!CRYPT_IN_RANGE(entropy->len, &entropyRange)) { + goto ERR; + } + return CRYPT_SUCCESS; + +ERR: + DRBG_CleanEntropy(ctx, entropy); + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY); + return CRYPT_DRBG_FAIL_GET_ENTROPY; +} + +// According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL +static void DRBG_CleanNonce(DRBG_Ctx *ctx, CRYPT_Data *nonce) +{ + CRYPT_RandSeedMethod *seedMeth = NULL; + + if (ctx == NULL || CRYPT_IsDataNull(nonce)) { + return; + } + + seedMeth = &ctx->seedMeth; + + if (seedMeth->cleanNonce != NULL) { + seedMeth->cleanNonce(ctx->seedCtx, nonce); + } + nonce->data = NULL; + nonce->len = 0; + return; +} + +// According to the definition of DRBG_Ctx, ctx->seedMeth is not NULL +static int32_t DRBG_GetNonce(DRBG_Ctx *ctx, CRYPT_Data *nonce, bool *addEntropy) +{ + int32_t ret; + CRYPT_RandSeedMethod *seedMeth = NULL; + + seedMeth = &ctx->seedMeth; + + // Allowed nonce which entered by the user can be NULL. + // In this case, set *addEntropy to true to obtain the nonce from the entropy. + if (seedMeth->getNonce == NULL || ctx->nonceRange.max == 0) { + if (ctx->nonceRange.min > 0) { + *addEntropy = true; + } + return CRYPT_SUCCESS; + } + + ret = seedMeth->getNonce(ctx->seedCtx, nonce, ctx->strength, &ctx->nonceRange); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_NONCE); + return CRYPT_DRBG_FAIL_GET_NONCE; + } + + if (CRYPT_CHECK_DATA_INVALID(nonce)) { + goto ERR; + } + + if (!CRYPT_IN_RANGE(nonce->len, &ctx->nonceRange)) { + goto ERR; + } + + return CRYPT_SUCCESS; + +ERR: + DRBG_CleanNonce(ctx, nonce); + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_NONCE); + return CRYPT_DRBG_FAIL_GET_NONCE; +} + +void DRBG_Free(DRBG_Ctx *ctx) +{ + if (ctx == NULL || ctx->meth == NULL || ctx->meth->free == NULL) { + return; + } + + void (*ctxFree)(DRBG_Ctx *ctx) = ctx->meth->free; + + DRBG_Uninstantiate(ctx); + ctxFree(ctx); + + return; +} + +int32_t DRBG_Instantiate(DRBG_Ctx *ctx, const uint8_t *person, uint32_t persLen) +{ + int32_t ret; + CRYPT_Data entropy = {NULL, 0}; + CRYPT_Data nonce = {NULL, 0}; + CRYPT_Data pers = {(uint8_t *)(uintptr_t)person, persLen}; + bool addEntropy = false; + + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (CRYPT_CHECK_DATA_INVALID(&pers)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (persLen > ctx->maxPersLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_INVALID_LEN); + return CRYPT_DRBG_INVALID_LEN; + } + + if (ctx->state != DRBG_STATE_UNINITIALISED) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ERR_STATE); + return CRYPT_DRBG_ERR_STATE; + } + + ctx->state = DRBG_STATE_ERROR; + + ret = DRBG_GetNonce(ctx, &nonce, &addEntropy); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR_NONCE; + } + + ret = DRBG_GetEntropy(ctx, &entropy, addEntropy); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR_ENTROPY; + } + + ret = ctx->meth->instantiate(ctx, &entropy, &nonce, &pers); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR_ENTROPY; + } + + ctx->state = DRBG_STATE_READY; + ctx->reseedCtr = 1; + +ERR_ENTROPY: + DRBG_CleanEntropy(ctx, &entropy); +ERR_NONCE: + DRBG_CleanNonce(ctx, &nonce); + + return ret; +} + +static inline bool DRBG_IsNeedReseed(const DRBG_Ctx *ctx, bool pr) +{ + if (pr) { + return true; + } + + if (ctx->reseedCtr > ctx->reseedInterval) { + return true; + } + return false; +} + +int32_t DRBG_Reseed(DRBG_Ctx *ctx, const uint8_t *adin, uint32_t adinLen) +{ + int32_t ret; + CRYPT_Data entropy = {NULL, 0}; + CRYPT_Data adinData = {(uint8_t*)(uintptr_t)adin, adinLen}; + + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (CRYPT_CHECK_BUF_INVALID(adin, adinLen)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (adinLen > ctx->maxAdinLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_INVALID_LEN); + return CRYPT_DRBG_INVALID_LEN; + } + + if (ctx->state != DRBG_STATE_READY) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ERR_STATE); + return CRYPT_DRBG_ERR_STATE; + } + + ctx->state = DRBG_STATE_ERROR; + + ret = DRBG_GetEntropy(ctx, &entropy, false); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = ctx->meth->reseed(ctx, &entropy, &adinData); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ctx->reseedCtr = 1; + ctx->state = DRBG_STATE_READY; + +ERR: + DRBG_CleanEntropy(ctx, &entropy); + + return ret; +} + +int32_t DRBG_Generate(DRBG_Ctx *ctx, + uint8_t *out, uint32_t outLen, + const uint8_t *adin, uint32_t adinLen, + bool pr) +{ + int32_t ret; + CRYPT_Data adinData = {(uint8_t*)(uintptr_t)adin, adinLen}; + + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (out == NULL || outLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (CRYPT_CHECK_BUF_INVALID(adin, adinLen)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (outLen > ctx->maxRequest || adinLen > ctx->maxAdinLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_INVALID_LEN); + return CRYPT_DRBG_INVALID_LEN; + } + + if (ctx->state != DRBG_STATE_READY) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ERR_STATE); + return CRYPT_DRBG_ERR_STATE; + } + + if (DRBG_IsNeedReseed(ctx, pr)) { + ret = DRBG_Reseed(ctx, adin, adinLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + adinData.data = NULL; + adinData.len = 0; + } + + ret = ctx->meth->generate(ctx, out, outLen, &adinData); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ctx->reseedCtr++; + + return ret; +} + +int32_t DRBG_Uninstantiate(DRBG_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + ctx->meth->uninstantiate(ctx); + + ctx->reseedCtr = 0; + ctx->state = DRBG_STATE_UNINITIALISED; + + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_DRBG */ diff --git a/crypto/drbg/src/drbg_ctr.c b/crypto/drbg/src/drbg_ctr.c new file mode 100644 index 00000000..080e4815 --- /dev/null +++ b/crypto/drbg/src/drbg_ctr.c @@ -0,0 +1,651 @@ +/* + * 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_DRBG_CTR + +#include +#include +#include "crypt_errno.h" +#include "crypt_local_types.h" +#include "crypt_utils.h" +#include "bsl_sal.h" +#include "crypt_types.h" +#include "bsl_err_internal.h" +#include "drbg_local.h" + + +#define DRBG_CTR_MAX_KEYLEN (32) +#define AES_BLOCK_LEN (16) +#define DRBG_CTR_MAX_SEEDLEN (48) + +typedef struct { + uint8_t k[DRBG_CTR_MAX_KEYLEN]; // DRBG_CTR_MAX_KEYLEN 32 + uint8_t v[AES_BLOCK_LEN]; // AES_BLOCK_LEN 16 (blockLen) + uint8_t kx[DRBG_CTR_MAX_SEEDLEN]; // DRBG_CTR_MAX_SEEDLEN 48 + uint32_t keyLen; + uint32_t seedLen; + const EAL_CipherMethod *ciphMeth; + void *ctrCtx; + void *dfCtx; + bool isUsedDf; +} DRBG_CtrCtx; + +static void DRBG_CtrXor(CRYPT_Data *dst, const CRYPT_Data *src) +{ + uint32_t xorlen; + + if (CRYPT_IsDataNull(dst) || CRYPT_IsDataNull(src)) { + return; + } + + xorlen = (dst->len > src->len) ? src->len : dst->len; + + DATA_XOR(dst->data, src->data, dst->data, xorlen); +} + +static void DRBG_CtrInc(uint8_t *v, uint32_t len) +{ + uint32_t i; + uint8_t *p = v + len - 1; + for (i = 0; i < len; i++, p--) { + (*p)++; + if (*p != 0) { + break; + } + } +} + +int32_t DRBG_CtrUpdate(DRBG_Ctx *drbg, const CRYPT_Data *in1, const CRYPT_Data *in2) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + const EAL_CipherMethod *ciphMeth = ctx->ciphMeth; + int32_t ret; + uint8_t tempData[DRBG_CTR_MAX_SEEDLEN]; + CRYPT_Data temp; + uint32_t offset; + + if ((ret = ciphMeth->setEncryptKey(ctx->ctrCtx, ctx->k, ctx->keyLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + /** + While (len (temp) < seedlen) do + If ctr_len < blocklen + inc = (rightmost (V, ctr_len) + 1) mod 2ctr_len . + V = leftmost (V, blocklen-ctr_len) || inc. + Else V = (V+1) mod 2blocklen . + output_block = Block_Encrypt (Key, V). + temp = temp || output_block. + */ + for (offset = 0; offset < ctx->seedLen; offset += AES_BLOCK_LEN) { + DRBG_CtrInc(ctx->v, AES_BLOCK_LEN); + if ((ret = ciphMeth->encrypt(ctx->ctrCtx, ctx->v, tempData + offset, AES_BLOCK_LEN)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } + + // temp = temp ⊕ provided_data + temp.data = tempData; + temp.len = ctx->seedLen; + DRBG_CtrXor(&temp, in1); + DRBG_CtrXor(&temp, in2); + + // Key = leftmost (temp, keylen). V = rightmost (temp, blocklen). + if (memcpy_s(ctx->k, DRBG_CTR_MAX_KEYLEN, temp.data, ctx->keyLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + ret = CRYPT_SECUREC_FAIL; + goto ERR; + } + // The length to be copied of ctx->V is AES_BLOCK_LEN, which is also the array length. + // The lower bits of temp.data are used for ctx->K, and the upper bits are used for ctx->V. + (void)memcpy_s(ctx->v, AES_BLOCK_LEN, temp.data + ctx->keyLen, AES_BLOCK_LEN); +ERR: + ciphMeth->clean(ctx->ctrCtx); + return ret; +} + +// BCC implementation, BCC is CBC-MAC: CBC encryption + IV(0) + last ciphertext returned. +static int32_t DRBG_CtrBCCUpdateBlock(DRBG_Ctx *drbg, const uint8_t *in, uint8_t *out, uint32_t len) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + int32_t ret; + /** + 4. For i = 1 to n do + 4.1 input_block = chaining_value ⊕ blocki. + 4.2 chaining_value = Block_Encrypt (Key, input_block). + */ + DATA_XOR(out, in, out, len); + if ((ret = ctx->ciphMeth->encrypt(ctx->dfCtx, out, out, AES_BLOCK_LEN)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + ctx->ciphMeth->clean(ctx->dfCtx); + return ret; + } + + return ret; +} + +static int32_t DRBG_CtrBCCInit(DRBG_Ctx *drbg) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + uint8_t *out = ctx->kx; + int32_t ret = CRYPT_SUCCESS; + uint8_t in[16] = { 0 }; + uint32_t offset = 0; + + while (offset < ctx->seedLen) { + if ((ret = DRBG_CtrBCCUpdateBlock(drbg, in, out + offset, AES_BLOCK_LEN)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + in[3]++; // Each cycle is incremented by 1 at the 3rd position. + offset += AES_BLOCK_LEN; + } + + return ret; +} + +static int32_t DRBG_CtrBCCUpdateKX(DRBG_Ctx *drbg, const uint8_t *in) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + uint8_t *out = ctx->kx; + int32_t ret = CRYPT_SUCCESS; + uint32_t offset = 0; + + while (offset < ctx->seedLen) { + if ((ret = DRBG_CtrBCCUpdateBlock(drbg, in, out + offset, AES_BLOCK_LEN)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + offset += AES_BLOCK_LEN; + } + + return ret; +} + +// Temporary block storage used by ctr_df +static int32_t DRBG_CtrBCCUpdate(DRBG_Ctx *drbg, const CRYPT_Data *in, uint8_t temp[16], uint32_t *tempLen) +{ + uint32_t dataLeft; + uint32_t offset = 0; + uint32_t tempPos = *tempLen; + int32_t ret = CRYPT_SUCCESS; + + if (CRYPT_IsDataNull(in) || in->len == 0) { + return ret; + } + + dataLeft = in->len; + + do { + const uint32_t left = AES_BLOCK_LEN - tempPos; + const uint32_t cpyLen = (left > dataLeft) ? dataLeft : left; + if (memcpy_s(temp + tempPos, left, in->data + offset, cpyLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + + if (left == cpyLen) { + if ((ret = DRBG_CtrBCCUpdateKX(drbg, temp)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + tempPos = 0; + } else { + tempPos += cpyLen; + } + + dataLeft -= cpyLen; + offset += cpyLen; + } while (dataLeft > 0); + + *tempLen = tempPos; + + return ret; +} + +static int32_t DRBG_CtrBCCFinal(DRBG_Ctx *drbg, uint8_t temp[16], uint32_t tempLen) +{ + int32_t ret; + uint32_t i; + + for (i = tempLen; i < AES_BLOCK_LEN; i++) { + temp[i] = 0; + } + + if ((ret = DRBG_CtrBCCUpdateKX(drbg, temp)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +static int32_t BlockCipherDfCal(DRBG_Ctx *drbg, CRYPT_Data *out) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + const EAL_CipherMethod *ciphMeth = ctx->ciphMeth; + int32_t ret; + uint32_t kOffset = 0; + uint32_t vOffset = ctx->keyLen; + + /* Set up key K */ + if ((ret = ciphMeth->setEncryptKey(ctx->ctrCtx, ctx->kx, ctx->keyLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + while (kOffset < ctx->seedLen) { + ret = ciphMeth->encrypt(ctx->ctrCtx, ctx->kx + vOffset, ctx->kx + kOffset, AES_BLOCK_LEN); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + vOffset = kOffset; + kOffset += AES_BLOCK_LEN; + } + + out->data = ctx->kx; + out->len = ctx->seedLen; + +ERR: + ciphMeth->clean(ctx->ctrCtx); + return ret; +} + +static int32_t BlockCipherDf(DRBG_Ctx *drbg, const CRYPT_Data *in1, const CRYPT_Data *in2, + const CRYPT_Data *in3, CRYPT_Data *out) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + int32_t ret; + uint32_t tempLen = 8; + uint8_t temp[16] = { 0 }; + uint32_t l; + + BSL_SAL_CleanseData(ctx->kx, sizeof(ctx->kx)); + + if ((ret = DRBG_CtrBCCInit(drbg)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + /** + 2. L = len (input_string)/8. + 3. N = number_of_bits_to_return/8. + 4. S = L || N || input_string || 0x80. + 5. While (len (S) mod outlen) ≠ 0, do + S = S || 0x00. + 6. temp = the Null string. + 9. While len (temp) < keylen + outlen, do + 9.1 IV = i || 0^(outlen - len (i)) + 9.2 temp = temp || BCC (K, (IV || S)). + 9.3 i = i + 1. + */ + + l = (in1 ? in1->len : 0) + (in2 ? in2->len : 0) + (in3 ? in3->len : 0); + + temp[0] = (uint8_t)((l >> 24) & 0xff); + temp[1] = (uint8_t)((l >> 16) & 0xff); + temp[2] = (uint8_t)((l >> 8) & 0xff); + temp[3] = (uint8_t)(l & 0xff); + temp[4] = 0; + temp[5] = 0; + temp[6] = 0; + temp[7] = (uint8_t)ctx->seedLen; + + if ((ret = DRBG_CtrBCCUpdate(drbg, in1, temp, &tempLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if ((ret = DRBG_CtrBCCUpdate(drbg, in2, temp, &tempLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if ((ret = DRBG_CtrBCCUpdate(drbg, in3, temp, &tempLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + temp[tempLen++] = 0x80; + if ((ret = DRBG_CtrBCCFinal(drbg, temp, tempLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + /** + 13. While len (temp) < number_of_bits_to_return, do + 13.1 X = Block_Encrypt (K, X). + 13.2 temp = temp || X. + */ + if ((ret = BlockCipherDfCal(drbg, out)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +static int32_t DRBG_CtrSetDfKey(DRBG_Ctx *drbg) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + const EAL_CipherMethod *ciphMeth = ctx->ciphMeth; + int32_t ret = CRYPT_SUCCESS; + + BSL_SAL_CleanseData(ctx->ctrCtx, ciphMeth->ctxSize); + + if (ctx->isUsedDf) { + /* df initialisation */ + const uint8_t dfKey[32] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + + BSL_SAL_CleanseData(ctx->dfCtx, ciphMeth->ctxSize); + + /* Set key schedule for dfKey */ + if ((ret = ctx->ciphMeth->setEncryptKey(ctx->dfCtx, dfKey, ctx->keyLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + return ret; +} + +int32_t DRBG_CtrInstantiate(DRBG_Ctx *drbg, const CRYPT_Data *entropy, const CRYPT_Data *nonce, const CRYPT_Data *pers) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + CRYPT_Data seedMaterial; + int32_t ret; + + if ((ret = DRBG_CtrSetDfKey(drbg)) != CRYPT_SUCCESS) { + return ret; + } + /** + * 4. Key = 0(keylen) + * 5. V = 0(blocklen) + */ + BSL_SAL_CleanseData(ctx->k, sizeof(ctx->k)); + BSL_SAL_CleanseData(ctx->v, sizeof(ctx->v)); + + /* seed_material = entropy_input ⊕ personalization_string. + (Key, V) = CTR_DRBG_Update (seed_material, Key, V). + */ + if (!ctx->isUsedDf) { + if ((ret = DRBG_CtrUpdate(drbg, entropy, pers)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; + } + // seed_material = entropy_input || nonce || personalization_string. + if ((ret = BlockCipherDf(drbg, entropy, nonce, pers, &seedMaterial)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + ctx->ciphMeth->clean(ctx->dfCtx); + return ret; + } + + if ((ret = DRBG_CtrUpdate(drbg, &seedMaterial, NULL)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +int32_t DRBG_CtrReseed(DRBG_Ctx *drbg, const CRYPT_Data *entropy, const CRYPT_Data *adin) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + CRYPT_Data seedMaterial; + int32_t ret; + + if (!ctx->isUsedDf) { + if ((ret = DRBG_CtrUpdate(drbg, entropy, adin)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; + } + + // seed_material = entropy_input || additional_input. + if ((ret = BlockCipherDf(drbg, entropy, adin, NULL, &seedMaterial)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if ((ret = DRBG_CtrUpdate(drbg, &seedMaterial, NULL)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +static int32_t DRBG_CtrGenerateBlock(DRBG_Ctx *drbg, uint8_t *out, uint32_t outLen) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + int32_t ret; + + DRBG_CtrInc(ctx->v, outLen); + + if ((ret = ctx->ciphMeth->encrypt(ctx->ctrCtx, ctx->v, out, outLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + ctx->ciphMeth->clean(ctx->ctrCtx); + } + return ret; +} + +static int32_t DRBG_CtrGenerateBlocks(DRBG_Ctx *drbg, uint8_t *out, uint32_t outLen) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + uint32_t offset = 0; + uint32_t tmpOutLen = outLen; + int32_t ret; + + if ((ret = ctx->ciphMeth->setEncryptKey(ctx->ctrCtx, ctx->k, ctx->keyLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + while (tmpOutLen >= AES_BLOCK_LEN) { + if ((ret = DRBG_CtrGenerateBlock(drbg, out + offset, AES_BLOCK_LEN)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + tmpOutLen -= AES_BLOCK_LEN; + offset += AES_BLOCK_LEN; + } + + if (tmpOutLen > 0) { + uint8_t temp[AES_BLOCK_LEN]; + if ((ret = DRBG_CtrGenerateBlock(drbg, temp, AES_BLOCK_LEN)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // tmpOutLen indicates the length of the out remaining. In the last part of DRBG generation, + // truncate the length of tmpOutLen and assign it to the out remaining. + (void)memcpy_s(out + offset, tmpOutLen, temp, tmpOutLen); + } + + return ret; +} + +int32_t DRBG_CtrGenerate(DRBG_Ctx *drbg, uint8_t *out, uint32_t outLen, const CRYPT_Data *adin) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx *)drbg->ctx; + int32_t ret; + /** + If (additional_input ≠ Null), then + temp = len (additional_input) + If (temp < seedlen), then + additional_input = additional_input || 0^(seedlen - temp). + (Key, V) = CTR_DRBG_Update (additional_input, Key, V) + Else additional_input = 0seedlen. + */ + if (adin != NULL && adin->data != NULL && adin->len != 0) { + if (!ctx->isUsedDf) { + if ((ret = DRBG_CtrUpdate(drbg, adin, NULL)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } else { + // additional_input = Block_Cipher_df (additional_input, seedlen). + if ((ret = BlockCipherDf(drbg, adin, NULL, NULL, (CRYPT_Data *)(uintptr_t)adin)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if ((ret = DRBG_CtrUpdate(drbg, adin, NULL)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + } + + /** + 3. temp = Null. + 4. While (len (temp) < requested_number_of_bits) do: + 4.1 If ctr_len < blocklen + 4.1.1 inc = (rightmost (V, ctr_len) + 1) mod 2ctr_len . + 4.1.2 V = leftmost (V, blocklen-ctr_len) || inc. + Else V = (V+1) mod 2blocklen . + 4.2 output_block = Block_Encrypt (Key, V). + 4.3 temp = temp || output_block. + 5. returned_bits = leftmost (temp, requested_number_of_bits). + */ + + if ((ret = DRBG_CtrGenerateBlocks(drbg, out, outLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // (Key, V) = CTR_DRBG_Update (additional_input, Key, V). + if ((ret = DRBG_CtrUpdate(drbg, adin, NULL)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +void DRBG_CtrUnInstantiate(DRBG_Ctx *drbg) +{ + DRBG_CtrCtx *ctx = (DRBG_CtrCtx*)drbg->ctx; + + ctx->ciphMeth->clean(ctx->ctrCtx); + ctx->ciphMeth->clean(ctx->dfCtx); + BSL_SAL_CleanseData((void *)(ctx->k), sizeof(ctx->k)); + BSL_SAL_CleanseData((void *)(ctx->v), sizeof(ctx->v)); + BSL_SAL_CleanseData((void *)(ctx->kx), sizeof(ctx->kx)); +} + +DRBG_Ctx *DRBG_CtrDup(DRBG_Ctx *drbg) +{ + DRBG_CtrCtx *ctx = NULL; + + if (drbg == NULL) { + return NULL; + } + + ctx = (DRBG_CtrCtx*)drbg->ctx; + return DRBG_NewCtrCtx(ctx->ciphMeth, ctx->keyLen, ctx->isUsedDf, &(drbg->seedMeth), drbg->seedCtx); +} + +void DRBG_CtrFree(DRBG_Ctx *drbg) +{ + if (drbg == NULL) { + return; + } + + DRBG_CtrUnInstantiate(drbg); + DRBG_CtrCtx *ctx = (DRBG_CtrCtx*)drbg->ctx; + BSL_SAL_FREE(ctx->dfCtx); + BSL_SAL_FREE(drbg); + return; +} + +DRBG_Ctx *DRBG_NewCtrCtx(const EAL_CipherMethod *ciphMeth, const uint32_t keyLen, const bool isUsedDf, + const CRYPT_RandSeedMethod *seedMeth, void *seedCtx) +{ + static DRBG_Method meth = { + DRBG_CtrInstantiate, + DRBG_CtrGenerate, + DRBG_CtrReseed, + DRBG_CtrUnInstantiate, + DRBG_CtrDup, + DRBG_CtrFree + }; + + if (ciphMeth == NULL || keyLen == 0 || seedMeth == NULL) { + return NULL; + } + + DRBG_Ctx *drbg = (DRBG_Ctx*)BSL_SAL_Malloc(sizeof(DRBG_Ctx) + sizeof(DRBG_CtrCtx) + ciphMeth->ctxSize); + if (drbg == NULL) { + return NULL; + } + void *dfCtx = (void*)BSL_SAL_Malloc(ciphMeth->ctxSize); // have 2 contexts + if (dfCtx == NULL) { + BSL_SAL_FREE(drbg); + return NULL; + } + + DRBG_CtrCtx *ctx = (DRBG_CtrCtx*)(drbg + 1); + ctx->ctrCtx = (void*)(ctx + 1); + ctx->dfCtx = dfCtx; + + ctx->ciphMeth = ciphMeth; + + drbg->state = DRBG_STATE_UNINITIALISED; + drbg->reseedInterval = DRBG_MAX_RESEED_INTERVAL; + + ctx->keyLen = keyLen; + ctx->seedLen = AES_BLOCK_LEN + keyLen; + ctx->isUsedDf = isUsedDf; + drbg->meth = &meth; + drbg->ctx = ctx; + drbg->seedMeth = *seedMeth; + drbg->seedCtx = seedCtx; + + drbg->strength = keyLen * 8; + drbg->maxRequest = DRBG_MAX_REQUEST; + // NIST.SP.800-90Ar1, Section 10.3.1 Table 3 defined those initial value. + if (isUsedDf) { + drbg->entropyRange.min = keyLen; + drbg->entropyRange.max = DRBG_MAX_LEN; + drbg->maxPersLen = DRBG_MAX_LEN; + drbg->maxAdinLen = DRBG_MAX_LEN; + + // NIST.SP.800-90Ar1, Section 8.6.7 defined, a nonce needs (security_strength/2) bits of entropy at least. + drbg->nonceRange.min = drbg->entropyRange.min / DRBG_NONCE_FROM_ENTROPY; + drbg->nonceRange.max = DRBG_MAX_LEN; + } else { + drbg->entropyRange.min = ctx->seedLen; + drbg->entropyRange.max = ctx->seedLen; + drbg->maxPersLen = ctx->seedLen; + drbg->maxAdinLen = ctx->seedLen; + + drbg->nonceRange.min = 0; + drbg->nonceRange.max = 0; + } + + return drbg; +} +#endif diff --git a/crypto/drbg/src/drbg_hash.c b/crypto/drbg/src/drbg_hash.c new file mode 100644 index 00000000..db799629 --- /dev/null +++ b/crypto/drbg/src/drbg_hash.c @@ -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_CRYPTO_DRBG_HASH + +#include +#include +#include "crypt_errno.h" +#include "crypt_local_types.h" +#include "crypt_utils.h" +#include "bsl_sal.h" +#include "crypt_types.h" +#include "bsl_err_internal.h" +#include "drbg_local.h" + +#define DRBG_HASH_MAX_SEEDLEN (111) + +typedef enum { + DRBG_SHA1MDSIZE = 20, + DRBG_SHA224MDSIZE = 28, + DRBG_SHA256MDSIZE = 32, + DRBG_SHA384MDSIZE = 48, + DRBG_SHA512MDSIZE = 64, +} DRBG_MdSize; + +typedef struct { + uint8_t v[DRBG_HASH_MAX_SEEDLEN]; + uint8_t c[DRBG_HASH_MAX_SEEDLEN]; + uint32_t seedLen; + const EAL_MdMethod *md; + void *mdCtx; +} DRBG_HashCtx; + +// This function performs the ctx->V += xxx operation. +static void DRBG_HashAddV(uint8_t *v, uint32_t vLen, uint8_t *src, uint32_t srcLen) +{ + uint8_t *d = v + vLen - 1; + uint8_t *s = src + srcLen - 1; + uint8_t c = 0; + uint32_t r; + + while (s >= src) { + r = (uint32_t)(*d) + (*s) + c; + *d = (uint8_t)(r & 0xff); + c = (r > 0xff) ? 1 : 0; + d--; + s--; + } + + while (d >= v && c > 0) { + r = (uint32_t)(*d) + c; + *d = (uint8_t)(r & 0xff); + c = (r > 0xff) ? 1 : 0; + d--; + } + return; +} + +static int32_t DRBG_UpdateDataInHashDf(DRBG_HashCtx *ctx, + const CRYPT_Data *in1, const CRYPT_Data *in2, + const CRYPT_Data *in3, const CRYPT_Data *in4) +{ + const EAL_MdMethod *meth = ctx->md; + void *mdCtx = ctx->mdCtx; + int32_t ret = CRYPT_SUCCESS; + + if (!CRYPT_IsDataNull(in1)) { + ret = meth->update(mdCtx, in1->data, in1->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + if (!CRYPT_IsDataNull(in2)) { + ret = meth->update(mdCtx, in2->data, in2->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + if (!CRYPT_IsDataNull(in3)) { + ret = meth->update(mdCtx, in3->data, in3->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + if (!CRYPT_IsDataNull(in4)) { + ret = meth->update(mdCtx, in4->data, in4->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + return ret; +} + +static void DRBG_HashDfValuesAssig(uint8_t values[5], uint32_t len) +{ + // The value of values is the same as that of counter || no_of_bits_to_return in Hash_df Process + // in section 10.3.1 in NIST 800-90a. + values[0] = 0x1; + // len is shifted leftward by 3, then byte-to-bit. Shift rightwards by 24 bits to get the highest 8 bits. + values[1] = (uint8_t)(((len << 3) >> 24) & 0xff); + // 2nd, len is shifted leftward by 3, then byte-to-bit. Shift rightwards by 16 bits to get the second 8 bits. + values[2] = (uint8_t)(((len << 3) >> 16) & 0xff); + // 3rd, len is shifted leftward by 3, then byte-to-bit. Shift rightwards by 8 bits to get the third 8 bits. + values[3] = (uint8_t)(((len << 3) >> 8) & 0xff); + values[4] = (uint8_t)((len << 3) & 0xff); // 4th, len is shifted leftward by 3, then byte-to-bit. +} + +static int32_t DRBG_HashDf(DRBG_HashCtx *ctx, uint8_t *out, uint32_t outLen, const CRYPT_Data *in1, + const CRYPT_Data *in2, const CRYPT_Data *in3, const CRYPT_Data *in4) +{ + const EAL_MdMethod *meth = ctx->md; + void *mdCtx = ctx->mdCtx; + uint32_t mdSize = meth->mdSize; + uint8_t *buf = out; + uint32_t len = outLen; + int32_t ret; + // The temp is the same as that of counter || no_of_bits_to_return in Hash_df Process + // in section 10.3.1 in NIST 800-90a. + uint8_t temp[5]; + // len = floor(no_of_bits_to_return / outlen) + DRBG_HashDfValuesAssig(temp, len); + + do { + // temp = temp || Hash (counter || no_of_bits_to_return || input_string). + if ((ret = meth->init(mdCtx)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // 5 indicates the maximum length of temp. For details, see the temp statement. + if ((ret = meth->update(mdCtx, temp, 5)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + if ((ret = DRBG_UpdateDataInHashDf(ctx, in1, in2, in3, in4)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + uint8_t tmpOut[DRBG_HASH_MAX_MDSIZE]; + uint32_t tmpOutLen = DRBG_HASH_MAX_MDSIZE; + if (len < mdSize) { + if ((ret = meth->final(mdCtx, tmpOut, &tmpOutLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // tmpOutLen is the maximum supported MD length, + // and len is the actual length, which must be smaller than tmpOutLen. + // Only the len length needs to be truncated as the output. + (void)memcpy_s(buf, len, tmpOut, len); + break; + } + if ((ret = meth->final(mdCtx, buf, &tmpOutLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + buf += mdSize; + len -= mdSize; + temp[0]++; + } while (len > 0); + +ERR: + meth->deinit(mdCtx); + return ret; +} + +static int32_t DRBG_Hashgen(DRBG_HashCtx *ctx, uint8_t *out, uint32_t outLen) +{ + uint8_t data[DRBG_HASH_MAX_SEEDLEN]; + const EAL_MdMethod *md = ctx->md; + void *mdCtx = ctx->mdCtx; + int32_t ret = CRYPT_SUCCESS; + uint32_t mdSize = md->mdSize; + uint32_t tmpLen = mdSize; + uint32_t len = outLen; + uint8_t *buf = out; + + // The length of the V array is the longest seedLen. Therefore, there is no failure. + (void)memcpy_s(data, sizeof(data), ctx->v, ctx->seedLen); + + while (len > 0) { + uint8_t n = 1; + if ((ret = md->init(mdCtx)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if ((ret = md->update(mdCtx, data, ctx->seedLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + if (len >= mdSize) { + if ((ret = md->final(mdCtx, buf, &tmpLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } else { + uint8_t temp[DRBG_HASH_MAX_SEEDLEN]; + uint32_t tempLen = DRBG_HASH_MAX_SEEDLEN; + if ((ret = md->final(mdCtx, temp, &tempLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + (void)memcpy_s(buf, len, temp, len); + break; + } + buf += mdSize; + len -= mdSize; + + DRBG_HashAddV(data, ctx->seedLen, &n, 1); + } + +ERR: + // Clear MD data. + md->deinit(mdCtx); + return ret; +} + +int32_t DRBG_HashInstantiate(DRBG_Ctx *drbg, const CRYPT_Data *entropy, + const CRYPT_Data *nonce, const CRYPT_Data *pers) +{ + DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx; + CRYPT_Data seed = {ctx->v, (uint32_t)(ctx->seedLen)}; + int32_t ret; + uint8_t c = 0; + CRYPT_Data temp = {&c, 1}; + + /** + 1. seed_material = entropy || nonce || pers + 2. seed = Hash_df(seed_material) + 3. V = seed + 4. C = Hash_df(0x00 || V) + */ + ret = DRBG_HashDf(ctx, ctx->v, ctx->seedLen, entropy, nonce, pers, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, &seed, NULL, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return CRYPT_SUCCESS; +} + +static int32_t DRBG_HashAdinInHashGenerate(DRBG_HashCtx *ctx, const CRYPT_Data *adin) +{ + void *mdCtx = ctx->mdCtx; + const EAL_MdMethod *md = ctx->md; + uint32_t mdSize = md->mdSize; + int32_t ret; + uint8_t temp = 0x2; + uint8_t w[DRBG_HASH_MAX_MDSIZE]; + uint32_t wLen = DRBG_HASH_MAX_MDSIZE; + + ret = md->init(mdCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = md->update(mdCtx, &temp, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = md->update(mdCtx, ctx->v, ctx->seedLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = md->update(mdCtx, adin->data, adin->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = md->final(mdCtx, w, &wLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + DRBG_HashAddV(ctx->v, ctx->seedLen, w, mdSize); + +ERR: + // Clear MD data. + md->deinit(mdCtx); + return ret; +} + +int32_t DRBG_HashGenerate(DRBG_Ctx *drbg, uint8_t *out, uint32_t outLen, const CRYPT_Data *adin) +{ + DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx; + const EAL_MdMethod *md = ctx->md; + void *mdCtx = ctx->mdCtx; + uint32_t mdSize = md->mdSize; + uint8_t h[DRBG_HASH_MAX_MDSIZE]; + uint32_t len = outLen; + int32_t ret; + uint32_t reseedCtrBe; + + /* if adin : + w = HASH(0x02 || V || adin) + V = (V + w) mod 2^seedLen + */ + if (!CRYPT_IsDataNull(adin)) { + ret = DRBG_HashAdinInHashGenerate(ctx, adin); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + // Hashgen(V, out, len) + ret = DRBG_Hashgen(ctx, out, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // H = HASH(0x03 || V) + uint8_t temp = 0x3; + + ret = md->init(mdCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = md->update(mdCtx, &temp, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = md->update(mdCtx, ctx->v, ctx->seedLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = md->final(mdCtx, h, &mdSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // V = (V + H + C + reseed_counter) mod 2^seedlen + DRBG_HashAddV(ctx->v, ctx->seedLen, h, mdSize); + DRBG_HashAddV(ctx->v, ctx->seedLen, ctx->c, ctx->seedLen); + reseedCtrBe = CRYPT_HTONL((uint32_t)(drbg->reseedCtr)); + DRBG_HashAddV(ctx->v, ctx->seedLen, (uint8_t*)&reseedCtrBe, sizeof(reseedCtrBe)); + +ERR : + // Clear MD data. + md->deinit(mdCtx); + return ret; +} + +int32_t DRBG_HashReseed(DRBG_Ctx *drbg, const CRYPT_Data *entropy, const CRYPT_Data *adin) +{ + int32_t ret; + DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx; + CRYPT_Data v = {ctx->v, ctx->seedLen}; + uint8_t c; + CRYPT_Data temp = {&c, 1}; + + /** + seed_material = 0x01 || V || entropy_input || additional_input. + seed = Hash_Df(seed_material) // The memory of C is reused. + V = seed + C = Hash_Df(0x00 || V) + */ + c = 0x1; + ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, &v, entropy, adin); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // The length of the C array is the longest seedLen. Therefore, there is no failure. + (void)memcpy_s(ctx->v, sizeof(ctx->v), ctx->c, ctx->seedLen); + + c = 0x0; + ret = DRBG_HashDf(ctx, ctx->c, ctx->seedLen, &temp, &v, NULL, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return CRYPT_SUCCESS; +} + +void DRBG_HashUnInstantiate(DRBG_Ctx *drbg) +{ + DRBG_HashCtx *ctx = (DRBG_HashCtx*)drbg->ctx; + + ctx->md->deinit(ctx->mdCtx); + BSL_SAL_CleanseData((void *)(ctx->c), sizeof(ctx->c)); + BSL_SAL_CleanseData((void *)(ctx->v), sizeof(ctx->v)); +} + +DRBG_Ctx *DRBG_HashDup(DRBG_Ctx *drbg) +{ + DRBG_HashCtx *ctx = NULL; + DRBG_Ctx *newDrbg = NULL; + + if (drbg == NULL) { + return NULL; + } + + ctx = (DRBG_HashCtx*)drbg->ctx; + newDrbg = DRBG_NewHashCtx(ctx->md, &(drbg->seedMeth), drbg->seedCtx); + + return newDrbg; +} + +void DRBG_HashFree(DRBG_Ctx *drbg) +{ + if (drbg == NULL) { + return; + } + + DRBG_HashUnInstantiate(drbg); + BSL_SAL_FREE(drbg); + return; +} + +static int32_t DRBG_NewHashCtxBase(uint32_t mdSize, DRBG_Ctx *drbg, DRBG_HashCtx *ctx) +{ + switch (mdSize) { + case DRBG_SHA1MDSIZE: + drbg->strength = 128; // 128 is the standard content length of nist 800-90a. + ctx->seedLen = 55; // 55 is the standard content length of nist 800-90a. + return CRYPT_SUCCESS; + case DRBG_SHA224MDSIZE: + drbg->strength = 192; // 192 is the standard content length of nist 800-90a. + ctx->seedLen = 55; // 55 is the standard content length of nist 800-90a. + return CRYPT_SUCCESS; + case DRBG_SHA256MDSIZE: + drbg->strength = 256; // 256 is the standard content length of nist 800-90a. + ctx->seedLen = 55; // 55 is the standard content length of nist 800-90a. + return CRYPT_SUCCESS; + case DRBG_SHA384MDSIZE: + case DRBG_SHA512MDSIZE: + drbg->strength = 256; // 256 is the standard content length of nist 800-90a. + ctx->seedLen = 111; // 111 is the standard content length of nist 800-90a. + return CRYPT_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ALG_NOT_SUPPORT); + return CRYPT_DRBG_ALG_NOT_SUPPORT; + } +} + +DRBG_Ctx *DRBG_NewHashCtx(const EAL_MdMethod *md, const CRYPT_RandSeedMethod *seedMeth, void *seedCtx) +{ + DRBG_Ctx *drbg = NULL; + DRBG_HashCtx *ctx = NULL; + static DRBG_Method meth = { + DRBG_HashInstantiate, + DRBG_HashGenerate, + DRBG_HashReseed, + DRBG_HashUnInstantiate, + DRBG_HashDup, + DRBG_HashFree + }; + + if (md == NULL || seedMeth == NULL) { + return NULL; + } + + drbg = (DRBG_Ctx*)BSL_SAL_Malloc(sizeof(DRBG_Ctx) + sizeof(DRBG_HashCtx) + md->ctxSize); + if (drbg == NULL) { + return NULL; + } + + ctx = (DRBG_HashCtx*)(drbg + 1); + ctx->md = md; + ctx->mdCtx = (void*)(ctx + 1); + + if (DRBG_NewHashCtxBase(md->mdSize, drbg, ctx) != CRYPT_SUCCESS) { + BSL_SAL_FREE(drbg); + return NULL; + } + + drbg->state = DRBG_STATE_UNINITIALISED; + drbg->reseedInterval = DRBG_MAX_RESEED_INTERVAL; + + drbg->meth = &meth; + drbg->ctx = ctx; + drbg->seedMeth = *seedMeth; + drbg->seedCtx = seedCtx; + + // Shift right by 3, from bit length to byte length + drbg->entropyRange.min = drbg->strength >> 3; + drbg->entropyRange.max = DRBG_MAX_LEN; + + drbg->nonceRange.min = drbg->entropyRange.min / DRBG_NONCE_FROM_ENTROPY; + drbg->nonceRange.max = DRBG_MAX_LEN; + + drbg->maxPersLen = DRBG_MAX_LEN; + drbg->maxAdinLen = DRBG_MAX_LEN; + drbg->maxRequest = DRBG_MAX_REQUEST; + + return drbg; +} +#endif diff --git a/crypto/drbg/src/drbg_hmac.c b/crypto/drbg/src/drbg_hmac.c new file mode 100644 index 00000000..ff24afbb --- /dev/null +++ b/crypto/drbg/src/drbg_hmac.c @@ -0,0 +1,368 @@ +/* + * 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_DRBG_HMAC + +#include +#include +#include "crypt_errno.h" +#include "crypt_local_types.h" +#include "crypt_utils.h" +#include "bsl_sal.h" +#include "crypt_types.h" +#include "bsl_err_internal.h" +#include "drbg_local.h" + +#define DRBG_HMAC_MAX_MDLEN (64) + +typedef enum { + DRBG_HMAC_SHA1SIZE = 20, + DRBG_HMAC_SHA224SIZE = 28, + DRBG_HMAC_SHA256SIZE = 32, + DRBG_HMAC_SHA384SIZE = 48, + DRBG_HMAC_SHA512SIZE = 64, +} DRBG_HmacSize; + +typedef struct { + uint8_t k[DRBG_HMAC_MAX_MDLEN]; + uint8_t v[DRBG_HMAC_MAX_MDLEN]; + uint32_t blockLen; + const EAL_MacMethod *hmacMeth; + const EAL_MdMethod *mdMeth; + void *hmacCtx; +} DRBG_HmacCtx; + +static int32_t Hmac(DRBG_HmacCtx *ctx, uint8_t mark, const CRYPT_Data *provData[], int32_t provDataLen) +{ + int32_t ret; + uint32_t ctxKLen = sizeof(ctx->k); + uint32_t ctxVLen = sizeof(ctx->v); + // K = HMAC (K, V || mark || provided_data). mark can be 0x00 or 0x01, + // provided_data = in1 || in2 || in3, private_data can be NULL + if ((ret = ctx->hmacMeth->init(ctx->hmacCtx, ctx->k, ctx->blockLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if ((ret = ctx->hmacMeth->update(ctx->hmacCtx, ctx->v, ctx->blockLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if ((ret = ctx->hmacMeth->update(ctx->hmacCtx, &mark, 1)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (int32_t i = 0; i < provDataLen; i++) { + if ((ret = ctx->hmacMeth->update(ctx->hmacCtx, provData[i]->data, provData[i]->len)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } + if ((ret = ctx->hmacMeth->final(ctx->hmacCtx, ctx->k, &ctxKLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // V = HMAC (K, V). + if ((ret = ctx->hmacMeth->init(ctx->hmacCtx, ctx->k, ctx->blockLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if ((ret = ctx->hmacMeth->update(ctx->hmacCtx, ctx->v, ctx->blockLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if ((ret = ctx->hmacMeth->final(ctx->hmacCtx, ctx->v, &ctxVLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR : + // clear hmacCtx + ctx->hmacMeth->deinit(ctx->hmacCtx); + return ret; +} + +/** + * Ref: NIST.SP.800-90Ar1 https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-90ar1.pdf + * Section: 10.1.2.2 HMAC_DRBG Update Process + */ +static int32_t DRBG_HmacUpdate(DRBG_Ctx *drbg, const CRYPT_Data *provData[], int32_t provDataLen) +{ + DRBG_HmacCtx *ctx = (DRBG_HmacCtx *)drbg->ctx; + int32_t ret; + // K = HMAC (K, V || 0x00 || provided_data). V = HMAC (K, V), provided_data have 3 input + ret = Hmac(ctx, 0x00, provData, provDataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // If (provided_data = Null), then return K and V. It's not an error, it's algorithmic. + if (provDataLen == 0) { + return ret; + } + // K = HMAC (K, V || 0x01 || provided_data). V = HMAC (K, V) + ret = Hmac(ctx, 0x01, provData, provDataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +/** + * Ref: NIST.SP.800-90Ar1 https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-90ar1.pdf + * Section: 10.1.2.3 Instantiation of HMAC_DRBG + */ +int32_t DRBG_HmacInstantiate(DRBG_Ctx *drbg, const CRYPT_Data *entropyInput, const CRYPT_Data *nonce, + const CRYPT_Data *perstr) +{ + DRBG_HmacCtx *ctx = (DRBG_HmacCtx *)drbg->ctx; + int32_t ret; + const CRYPT_Data *provData[3] = {0}; // We only need 3 at most. + int32_t index = 0; + if (!CRYPT_IsDataNull(entropyInput)) { + provData[index++] = entropyInput; + } + if (!CRYPT_IsDataNull(nonce)) { + provData[index++] = nonce; + } + if (!CRYPT_IsDataNull(perstr)) { + provData[index++] = perstr; + } + + // Key = 0x00 00...00. + (void)memset_s(ctx->k, sizeof(ctx->k), 0, ctx->blockLen); + + // V = 0x01 01...01. + (void)memset_s(ctx->v, sizeof(ctx->v), 1, ctx->blockLen); + + // seed_material = entropy_input || nonce || personalization_string. + // (Key, V) = HMAC_DRBG_Update (seed_material, Key, V). + ret = DRBG_HmacUpdate(drbg, provData, index); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +/** + * Ref: NIST.SP.800-90Ar1 https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-90ar1.pdf + * Section: 10.1.2.4 HMAC_DRBG Reseed Process + */ +int32_t DRBG_HmacReseed(DRBG_Ctx *drbg, const CRYPT_Data *entropyInput, const CRYPT_Data *adin) +{ + int32_t ret; + // seed_material = entropy_input || additional_input. + const CRYPT_Data *seedMaterial[2] = {0}; // This stage only needs 2 at most. + int32_t index = 0; + if (!CRYPT_IsDataNull(entropyInput)) { + seedMaterial[index++] = entropyInput; + } + if (!CRYPT_IsDataNull(adin)) { + seedMaterial[index++] = adin; + } + // (Key, V) = HMAC_DRBG_Update (seed_material, Key, V). + ret = DRBG_HmacUpdate(drbg, seedMaterial, index); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +/** + * Ref: NIST.SP.800-90Ar1 https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-90ar1.pdf + * Section: 10.1.2.5 HMAC_DRBG Generate Process + */ +int32_t DRBG_HmacGenerate(DRBG_Ctx *drbg, uint8_t *out, uint32_t outLen, const CRYPT_Data *adin) +{ + DRBG_HmacCtx *ctx = (DRBG_HmacCtx *)drbg->ctx; + const EAL_MacMethod *hmacMeth = ctx->hmacMeth; + const uint8_t *temp = ctx->v; + uint32_t tmpLen = ctx->blockLen; + uint32_t len = outLen; + uint8_t *buf = out; + int32_t ret; + uint32_t ctxVLen; + int32_t hasAdin = CRYPT_IsDataNull(adin) ? 0 : 1; + // If additional_input ≠ Null, then (Key, V) = HMAC_DRBG_Update (additional_input, Key, V). + if (hasAdin == 1) { + if ((ret = DRBG_HmacUpdate(drbg, &adin, hasAdin)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + /** + While (len (temp) < requested_number_of_bits) do: + V = HMAC (Key, V). + temp = temp || V. + */ + while (len > 0) { + if ((ret = hmacMeth->init(ctx->hmacCtx, ctx->k, ctx->blockLen)) != CRYPT_SUCCESS || + (ret = hmacMeth->update(ctx->hmacCtx, temp, ctx->blockLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (len <= ctx->blockLen) { + break; + } + if ((ret = hmacMeth->final(ctx->hmacCtx, buf, &tmpLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + temp = buf; + buf += ctx->blockLen; + len -= ctx->blockLen; + } + + ctxVLen = sizeof(ctx->v); + if ((ret = hmacMeth->final(ctx->hmacCtx, ctx->v, &ctxVLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // Intercepts the len-length V-value as an output, and because of len <= blockLen, + // length of V is always greater than blockLen,Therefore, this problem does not exist. + (void)memcpy_s(buf, len, ctx->v, len); + + // (Key, V) = HMAC_DRBG_Update (additional_input, Key, V). + if ((ret = DRBG_HmacUpdate(drbg, &adin, hasAdin)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR: + // clear hmacCtx + hmacMeth->deinit(ctx->hmacCtx); + return ret; +} + +void DRBG_HmacUnInstantiate(DRBG_Ctx *drbg) +{ + DRBG_HmacCtx *ctx = (DRBG_HmacCtx*)drbg->ctx; + ctx->hmacMeth->deinit(ctx->hmacCtx); + BSL_SAL_CleanseData((void *)(ctx->k), sizeof(ctx->k)); + BSL_SAL_CleanseData((void *)(ctx->v), sizeof(ctx->v)); +} + +DRBG_Ctx *DRBG_HmacDup(DRBG_Ctx *drbg) +{ + DRBG_HmacCtx *ctx = NULL; + + if (drbg == NULL) { + return NULL; + } + + ctx = (DRBG_HmacCtx*)drbg->ctx; + + return DRBG_NewHmacCtx(ctx->hmacMeth, ctx->mdMeth, &(drbg->seedMeth), drbg->seedCtx); +} + +void DRBG_HmacFree(DRBG_Ctx *drbg) +{ + if (drbg == NULL) { + return; + } + + DRBG_HmacUnInstantiate(drbg); + DRBG_HmacCtx *ctx = (DRBG_HmacCtx*)drbg->ctx; + ctx->hmacMeth->deinitCtx(ctx->hmacCtx); + BSL_SAL_FREE(drbg); + return; +} + +static int32_t DRBG_NewHmacCtxBase(uint32_t hmacSize, DRBG_Ctx *drbg) +{ + switch (hmacSize) { + case DRBG_HMAC_SHA1SIZE: + drbg->strength = 128; // nist 800-90a specified the length must be 128 + return CRYPT_SUCCESS; + case DRBG_HMAC_SHA224SIZE: + drbg->strength = 192; // nist 800-90a specified the length must be 192 + return CRYPT_SUCCESS; + case DRBG_HMAC_SHA256SIZE: + case DRBG_HMAC_SHA384SIZE: + case DRBG_HMAC_SHA512SIZE: + drbg->strength = 256; // nist 800-90a specified the length must be 256 + return CRYPT_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ALG_NOT_SUPPORT); + return CRYPT_DRBG_ALG_NOT_SUPPORT; + } +} + +DRBG_Ctx *DRBG_NewHmacCtx(const EAL_MacMethod *hmacMeth, const EAL_MdMethod *mdMeth, + const CRYPT_RandSeedMethod *seedMeth, void *seedCtx) +{ + DRBG_Ctx *drbg = NULL; + DRBG_HmacCtx *ctx = NULL; + static DRBG_Method meth = { + DRBG_HmacInstantiate, + DRBG_HmacGenerate, + DRBG_HmacReseed, + DRBG_HmacUnInstantiate, + DRBG_HmacDup, + DRBG_HmacFree + }; + + if (hmacMeth == NULL || mdMeth == NULL || seedMeth == NULL) { + return NULL; + } + + drbg = (DRBG_Ctx*)BSL_SAL_Malloc(sizeof(DRBG_Ctx) + sizeof(DRBG_HmacCtx) + hmacMeth->ctxSize); + if (drbg == NULL) { + return NULL; + } + + ctx = (DRBG_HmacCtx*)(drbg + 1); + ctx->hmacMeth = hmacMeth; + ctx->mdMeth = mdMeth; + ctx->hmacCtx = (void*)(ctx + 1); + + if (hmacMeth->initCtx(ctx->hmacCtx, mdMeth) != CRYPT_SUCCESS) { + BSL_SAL_FREE(drbg); + return NULL; + } + + ctx->blockLen = hmacMeth->getLen(ctx->hmacCtx); + + if (DRBG_NewHmacCtxBase(ctx->blockLen, drbg) != CRYPT_SUCCESS) { + BSL_SAL_FREE(drbg); + return NULL; + } + + drbg->state = DRBG_STATE_UNINITIALISED; + drbg->reseedInterval = DRBG_MAX_RESEED_INTERVAL; + + drbg->meth = &meth; + drbg->ctx = ctx; + drbg->seedMeth = *seedMeth; + drbg->seedCtx = seedCtx; + + // shift rightwards by 3, converting from bit length to byte length + drbg->entropyRange.min = drbg->strength >> 3; + drbg->entropyRange.max = DRBG_MAX_LEN; + + drbg->nonceRange.min = drbg->entropyRange.min / DRBG_NONCE_FROM_ENTROPY; + drbg->nonceRange.max = DRBG_MAX_LEN; + + drbg->maxPersLen = DRBG_MAX_LEN; + drbg->maxAdinLen = DRBG_MAX_LEN; + drbg->maxRequest = DRBG_MAX_REQUEST; + + return drbg; +} +#endif diff --git a/crypto/drbg/src/drbg_local.h b/crypto/drbg/src/drbg_local.h new file mode 100644 index 00000000..cb07c51f --- /dev/null +++ b/crypto/drbg/src/drbg_local.h @@ -0,0 +1,78 @@ +/* + * 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 DRBG_LOCAL_H +#define DRBG_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_DRBG + +#include +#include "crypt_drbg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Relationship between the number of NONCE and ENTROPY +#define DRBG_NONCE_FROM_ENTROPY (2) + +typedef enum { + DRBG_STATE_UNINITIALISED, + DRBG_STATE_READY, + DRBG_STATE_ERROR, +} DRBG_State; + +typedef struct { + int32_t (*instantiate)(DRBG_Ctx *ctx, const CRYPT_Data *entropy, + const CRYPT_Data *nonce, const CRYPT_Data *pers); + int32_t (*generate)(DRBG_Ctx *ctx, uint8_t *out, uint32_t outLen, const CRYPT_Data *adin); + int32_t (*reseed)(DRBG_Ctx *ctx, const CRYPT_Data *entropy, const CRYPT_Data *adin); + void (*uninstantiate)(DRBG_Ctx *ctx); + DRBG_Ctx* (*dup)(DRBG_Ctx *ctx); + void (*free)(DRBG_Ctx *ctx); +} DRBG_Method; + +struct DrbgCtx { + DRBG_State state; /* DRBG state */ + + uint32_t reseedCtr; /* reseed counter */ + uint32_t reseedInterval; /* reseed interval times */ + + uint32_t strength; /* Algorithm strength */ + uint32_t maxRequest; /* Maximum number of bytes per request, which is determined by the algorithm. */ + + CRYPT_Range entropyRange; /* entropy size range */ + CRYPT_Range nonceRange; /* nonce size range */ + + uint32_t maxPersLen; /* Maximum private data length */ + uint32_t maxAdinLen; /* Maximum additional data length */ + + DRBG_Method *meth; /* Internal different mode method */ + void *ctx; /* Mode Context */ + + /* seed function, which is related to the entropy source and DRBG generation. + When seedMeth and seedCtx are empty, the default entropy source is used. */ + CRYPT_RandSeedMethod seedMeth; + void *seedCtx; /* Seed context */ +}; + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_DRBG + +#endif // DRBG_LOCAL_H diff --git a/crypto/dsa/include/crypt_dsa.h b/crypto/dsa/include/crypt_dsa.h new file mode 100644 index 00000000..889c7af7 --- /dev/null +++ b/crypto/dsa/include/crypt_dsa.h @@ -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. + */ + +#ifndef CRYPT_DSA_H +#define CRYPT_DSA_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_DSA + +#include +#include "crypt_bn.h" +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#ifndef CRYPT_DSA_TRY_MAX_CNT +#define CRYPT_DSA_TRY_MAX_CNT 100 // Maximum number of attempts to generate keys and signatures +#endif +/* DSA key parameters */ +typedef struct DSA_Para CRYPT_DSA_Para; + +/* DSA key context */ +typedef struct DSA_Ctx CRYPT_DSA_Ctx; + +/** + * @ingroup dsa + * @brief dsa Allocates context memory space. + * + * @retval (CRYPT_DSA_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_DSA_Ctx *CRYPT_DSA_NewCtx(void); + +/** + * @ingroup dsa + * @brief Copy the DSA context. After the duplication is complete, invoke the CRYPT_DSA_FreeCtx to release the memory. + * + * @param ctx [IN] Source DSA context + * + * @return CRYPT_DSA_Ctx Dsa context pointer + * If the operation fails, null is returned. + */ +CRYPT_DSA_Ctx *CRYPT_DSA_DupCtx(CRYPT_DSA_Ctx *dsaCtx); + +/** + * @ingroup dsa + * @brief dsa Release the key context structure + * + * @param ctx [IN] Indicates the pointer to the context structure to be released. The ctx is set NULL by the invoker. + */ +void CRYPT_DSA_FreeCtx(CRYPT_DSA_Ctx *ctx); + +/** + * @ingroup dsa + * @brief dsa generate key parameter structure + * + * @param para [IN] dsa external parameter + * + * @retval (CRYPT_DSA_Para *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_DSA_Para *CRYPT_DSA_NewPara(const CRYPT_DsaPara *para); + +/** + * @ingroup dsa + * @brief Release the key parameter structure of DSA. + * + * @param para [IN] Pointer to the key parameter structure to be released. para is set NULL by the invoker. + */ +void CRYPT_DSA_FreePara(CRYPT_DSA_Para *para); + +/** + * @ingroup dsa + * @brief Set the data of the key parameter structure to the key structure. + * + * @param ctx [IN] Key structure for setting related parameters. The key specification is 1024-3072 bits. + * @param para [IN] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_ERR_KEY_PARA The key parameter data is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL internal memory allocation error + * @retval BN error code. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DSA_SetPara(CRYPT_DSA_Ctx *ctx, const CRYPT_DSA_Para *para); + +/** + * @ingroup dsa + * @brief Set the parameter data in the key structure to the key parameter structure. + * + * @param ctx [IN] Key structure for setting related parameters. The key specification is 1024-3072 bits. + * @param para [OUT] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_PARA_ERROR The key parameter data is incorrect. + * @retval BN error code. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Get successfully. + */ +int32_t CRYPT_DSA_GetPara(const CRYPT_DSA_Ctx *ctx, CRYPT_DsaPara *para); + +/** + * @ingroup dsa + * @brief dsa Obtain the key length. + * + * @param ctx [IN] DSA context structure + * + * @retval 0 The input is incorrect or the corresponding key structure does not contain valid key length. + * @retval uint32_t Valid key length + */ +uint32_t CRYPT_DSA_GetBits(const CRYPT_DSA_Ctx *ctx); + +/** + * @ingroup dsa + * @brief dsa Obtain the required length of the signature. + * + * @param ctx [IN] DSA context structure + * + * @retval 0 The input is incorrect or the corresponding key structure does not contain valid parameter data. + * @retval uint32_t Length required for valid signature data + */ +uint32_t CRYPT_DSA_GetSignLen(const CRYPT_DSA_Ctx *ctx); +/** + * @ingroup dsa + * @brief Generate a DSA key pair. + * + * @param ctx [IN/OUT] DSA context structure + * + * @retval CRYPT_NULL_INPUT Error null pointer input. + * @retval CRYPT_DSA_ERR_KEY_PARA The key parameter data is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure. + * @retval CRYPT_DSA_ERR_TRY_CNT Unable to generate results within the specified number of attempts. + * @retval BN error code. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_DSA_Gen(CRYPT_DSA_Ctx *ctx); + +/** + * @ingroup dsa + * @brief DSA Signature + * + * @param ctx [IN] DSA context structure + * @param data [IN] Data to be signed + * @param dataLen [IN] Length of the data to be signed + * @param sign [OUT] Signature data + * @param signLen [IN/OUT] The input parameter is the space length of the sign, + * and the output parameter is the valid length of the sign. + * The required space can be obtained by calling CRYPT_DSA_GetSignLen. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval CRYPT_DSA_ERR_TRY_CNT Unable to generate results within the specified number of attempts. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure. + * @retval BN error An error occurred in the internal BigNum operation. + * @retval CRYPT_SUCCESS Signed successfully. + */ +int32_t CRYPT_DSA_Sign(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen); + +/** + * @ingroup dsa + * @brief DSA verification + * + * @param ctx [IN] DSA context structure + * @param data [IN] Data to be signed + * @param dataLen [IN] Length of the data to be signed + * @param sign [IN] Signature data + * @param signLen [IN] Valid length of the sign + * + * @retval CRYPT_NULL_INPUT Error null pointer input. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure. + * @retval CRYPT_DSA_DECODE_FAIL Signature Data Decoding Failure. + * @retval CRYPT_DSA_VERIFY_FAIL Failed to verify the signature. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The signature is verified successfully. + */ +int32_t CRYPT_DSA_Verify(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen); + +/** + * @ingroup dsa + * @brief Set the private key data for the DSA. + * + * @param ctx [IN] DSA context structure + * @param prv [IN] External private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_ERR_KEY_PARA The key parameter data is incorrect. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DSA_SetPrvKey(CRYPT_DSA_Ctx *ctx, const CRYPT_DsaPrv *prv); + +/** + * @ingroup dsa + * @brief Set the public key data for the DSA. + * + * @param ctx [IN] DSA context structure + * @param pub [IN] External public key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input. + * @retval CRYPT_DSA_ERR_KEY_PARA The key parameter data is incorrect. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_DSA_SetPubKey(CRYPT_DSA_Ctx *ctx, const CRYPT_DsaPub *pub); + +/** + * @ingroup dsa + * @brief Obtain the private key data of the DSA. + * + * @param ctx [IN] DSA context structure + * @param prv [OUT] External private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval BN error. An error occurs in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_DSA_GetPrvKey(const CRYPT_DSA_Ctx *ctx, CRYPT_DsaPrv *prv); + +/** + * @ingroup dsa + * @brief Obtain the public key data of the DSA. + * + * @param ctx [IN] DSA context structure + * @param pub [OUT] External public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval BN error. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_DSA_GetPubKey(const CRYPT_DSA_Ctx *ctx, CRYPT_DsaPub *pub); + +/** + * @ingroup dsa + * @brief dsa Compare public keys and parameters + * + * @param a [IN] DSA context structure + * @param b [IN] DSA context structure + * + * @retval CRYPT_SUCCESS is the same + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_DSA_ERR_KEY_INFO The key information is incorrect. + * @retval CRYPT_DSA_PUBKEY_NOT_EQUAL Public keys are not equal. + * @retval CRYPT_DSA_PARA_ERROR The parameter information is incorrect. + * @retval CRYPT_DSA_PARA_NOT_EQUAL The parameters are not equal. + */ +int32_t CRYPT_DSA_Cmp(const CRYPT_DSA_Ctx *a, const CRYPT_DSA_Ctx *b); + +/** + * @ingroup dsa + * @brief DSA control interface + * + * @param ctx [IN] DSA context structure + * @param opt [IN] Operation mode + * @param val [IN] Parameter + * @param len [IN] val length + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_SUCCESS obtained successfully. + */ +int32_t CRYPT_DSA_Ctrl(CRYPT_DSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + + +/** + * @ingroup DSA + * @brief DSA get security bits + * + * @param ctx [IN] DSA Context structure + * + * @retval security bits + */ +int32_t CRYPT_DSA_GetSecBits(const CRYPT_DSA_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_DSA + +#endif // CRYPT_DSA_H diff --git a/crypto/dsa/src/dsa_core.c b/crypto/dsa/src/dsa_core.c new file mode 100644 index 00000000..fdd028cb --- /dev/null +++ b/crypto/dsa/src/dsa_core.c @@ -0,0 +1,894 @@ +/* + * 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_DSA + +#include "crypt_errno.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_encode.h" +#include "dsa_local.h" +#include "crypt_dsa.h" + +CRYPT_DSA_Ctx *CRYPT_DSA_NewCtx(void) +{ + CRYPT_DSA_Ctx *ctx = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Ctx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)memset_s(ctx, sizeof(CRYPT_DSA_Ctx), 0, sizeof(CRYPT_DSA_Ctx)); + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +static bool InputBufferCheck(const uint8_t *buffer, uint32_t bufferLen) +{ + if (buffer == NULL || bufferLen == 0) { + return true; + } + return false; +} + +static int32_t NewParaCheck(const CRYPT_DsaPara *para) +{ + bool invalidInput = (para == NULL) || + InputBufferCheck(para->p, para->pLen) || + InputBufferCheck(para->q, para->qLen) || + InputBufferCheck(para->g, para->gLen); + if (invalidInput) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->pLen > BN_BITS_TO_BYTES(DSA_MAX_PBITS)) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (para->qLen > para->pLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (para->gLen > para->pLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + return CRYPT_SUCCESS; +} + +static CRYPT_DSA_Para *ParaMemGet(uint32_t bits) +{ + CRYPT_DSA_Para *para = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Para)); + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + para->p = BN_Create(bits); + para->q = BN_Create(bits); + para->g = BN_Create(bits); + if (para->p == NULL || para->q == NULL || para->g == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + CRYPT_DSA_FreePara(para); + return NULL; + } + return para; +} + +CRYPT_DSA_Para *CRYPT_DSA_NewPara(const CRYPT_DsaPara *para) +{ + if (NewParaCheck(para) != CRYPT_SUCCESS) { + return NULL; + } + CRYPT_DSA_Para *retPara = ParaMemGet(para->pLen * 8); + if (retPara == NULL) { + return NULL; + } + + int32_t ret = BN_Bin2Bn(retPara->p, para->p, para->pLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Bin2Bn(retPara->q, para->q, para->qLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Bin2Bn(retPara->g, para->g, para->gLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + return retPara; +ERR: + CRYPT_DSA_FreePara(retPara); + return NULL; +} + +void CRYPT_DSA_FreePara(CRYPT_DSA_Para *para) +{ + if (para == NULL) { + return; + } + BN_Destroy(para->p); + BN_Destroy(para->q); + BN_Destroy(para->g); + BSL_SAL_FREE(para); +} + +void CRYPT_DSA_FreeCtx(CRYPT_DSA_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + int ref = 0; + BSL_SAL_AtomicDownReferences(&(ctx->references), &ref); + if (ref > 0) { + return; + } + BSL_SAL_ReferencesFree(&(ctx->references)); + CRYPT_DSA_FreePara(ctx->para); + BN_Destroy(ctx->x); + BN_Destroy(ctx->y); + BSL_SAL_FREE(ctx); +} + +static int32_t ParaPQGCheck(const BN_BigNum *p, const BN_BigNum *q, const BN_BigNum *g) +{ + uint32_t pBits = BN_Bits(p); + BN_BigNum *r = BN_Create(pBits + 1); + BN_Optimizer *opt = BN_OptimizerCreate(); + int32_t ret; + if (r == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // judgment of numeric values + // r = p - 1 + ret = BN_SubLimb(r, p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // q < p - 1 + if (BN_Cmp(q, r) >= 0) { + ret = CRYPT_DSA_ERR_KEY_PARA; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // g < p - 1 + if (BN_Cmp(g, r) >= 0) { + ret = CRYPT_DSA_ERR_KEY_PARA; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // judgment of multiple relationship about p & q + ret = BN_Div(NULL, r, r, q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // (p - 1) % q == 0 + if (!BN_IsZero(r)) { + ret = CRYPT_DSA_ERR_KEY_PARA; + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + BN_Destroy(r); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t ParaDataCheck(const CRYPT_DSA_Para *para) +{ + const BN_BigNum *p = para->p; + const BN_BigNum *q = para->q; + const BN_BigNum *g = para->g; + // 1. judge validity of length + uint32_t pBits = BN_Bits(p); + if (pBits < DSA_MIN_PBITS || pBits > DSA_MAX_PBITS) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (BN_Bits(q) < DSA_MIN_QBITS) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + // 2. parity judgment of p & q and value judgment of g + // p is an odd number && q is an odd number + if (BN_GetBit(p, 0) == 0 || BN_GetBit(q, 0) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + // g != 1 && g != 0 + if (BN_IsOne(g) || BN_IsZero(g)) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + // This interface is invoked only here, and pushErr is performed internally. + // If this interface fails, pushErr does not need to be invoked. + return ParaPQGCheck(p, q, g); +} + +static CRYPT_DSA_Para *ParaDup(const CRYPT_DSA_Para *para) +{ + CRYPT_DSA_Para *ret = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Para)); + if (ret == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + ret->p = BN_Dup(para->p); + ret->q = BN_Dup(para->q); + ret->g = BN_Dup(para->g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + CRYPT_DSA_FreePara(ret); + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return NULL; + } + return ret; +} + +int32_t CRYPT_DSA_SetPara(CRYPT_DSA_Ctx *ctx, const CRYPT_DSA_Para *para) +{ + if (ctx == NULL || para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = ParaDataCheck(para); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + BN_Destroy(ctx->x); + BN_Destroy(ctx->y); + CRYPT_DSA_FreePara(ctx->para); + ctx->x = NULL; + ctx->y = NULL; + ctx->para = ParaDup(para); + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_DSA_GetPara(const CRYPT_DSA_Ctx *ctx, CRYPT_DsaPara *para) +{ + int32_t ret; + + if (ctx == NULL || para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_PARA_ERROR); + return CRYPT_DSA_PARA_ERROR; + } + + ret = BN_Bn2Bin(ctx->para->p, para->p, &(para->pLen)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(ctx->para->q, para->q, &(para->qLen)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(ctx->para->g, para->g, &(para->gLen)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +CRYPT_DSA_Ctx *CRYPT_DSA_DupCtx(CRYPT_DSA_Ctx *dsaCtx) +{ + if (dsaCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + + CRYPT_DSA_Ctx *dsaNewCtx = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Ctx)); + if (dsaNewCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(dsaNewCtx, sizeof(CRYPT_DSA_Ctx), 0, sizeof(CRYPT_DSA_Ctx)); + + GOTO_ERR_IF_SRC_NOT_NULL(dsaNewCtx->x, dsaCtx->x, BN_Dup(dsaCtx->x), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(dsaNewCtx->y, dsaCtx->y, BN_Dup(dsaCtx->y), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(dsaNewCtx->para, dsaCtx->para, ParaDup(dsaCtx->para), CRYPT_MEM_ALLOC_FAIL); + BSL_SAL_ReferencesInit(&(dsaNewCtx->references)); + return dsaNewCtx; + +ERR: + CRYPT_DSA_FreeCtx(dsaNewCtx); + return NULL; +} + +uint32_t CRYPT_DSA_GetBits(const CRYPT_DSA_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return 0; + } + return BN_Bits(ctx->para->p); +} + +uint32_t CRYPT_DSA_GetSignLen(const CRYPT_DSA_Ctx *ctx) +{ + if (ctx == NULL || ctx->para == NULL) { + return 0; + } + uint32_t qLen = ASN1_SignStringLenOfBn(ctx->para->q); + return ASN1_SignEnCodeLen(qLen, qLen); +} + +/* x != 0 && x < q */ +int32_t CRYPT_DSA_SetPrvKey(CRYPT_DSA_Ctx *ctx, const CRYPT_DsaPrv *prv) +{ + if (ctx == NULL || prv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (InputBufferCheck(prv->data, prv->len)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (BN_Bytes(ctx->para->q) < prv->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO); + return CRYPT_DSA_ERR_KEY_INFO; + } + BN_BigNum *bnX = BN_Create(prv->len * 8); + if (bnX == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = BN_Bin2Bn(bnX, prv->data, prv->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // x < q + if (BN_Cmp(bnX, ctx->para->q) >= 0) { + ret = CRYPT_DSA_ERR_KEY_INFO; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // x != 0 + if (BN_IsZero(bnX)) { + ret = CRYPT_DSA_ERR_KEY_INFO; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + BN_Destroy(ctx->x); + ctx->x = bnX; + return ret; +ERR: + BN_Destroy(bnX); + return ret; +} + +/* y != 0 && y != 1 && y < p */ +int32_t CRYPT_DSA_SetPubKey(CRYPT_DSA_Ctx *ctx, const CRYPT_DsaPub *pub) +{ + if (ctx == NULL || pub == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (InputBufferCheck(pub->data, pub->len)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (BN_Bytes(ctx->para->p) < pub->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO); + return CRYPT_DSA_ERR_KEY_INFO; + } + BN_BigNum *bnY = BN_Create(pub->len * 8); + if (bnY == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = BN_Bin2Bn(bnY, pub->data, pub->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // y < p + if (BN_Cmp(bnY, ctx->para->p) >= 0) { + ret = CRYPT_DSA_ERR_KEY_INFO; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // y != 0 && y != 1 + if (BN_IsZero(bnY) || BN_IsOne(bnY)) { + ret = CRYPT_DSA_ERR_KEY_INFO; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + BN_Destroy(ctx->y); + ctx->y = bnY; + return CRYPT_SUCCESS; +ERR: + BN_Destroy(bnY); + return ret; +} + +int32_t CRYPT_DSA_GetPrvKey(const CRYPT_DSA_Ctx *ctx, CRYPT_DsaPrv *prv) +{ + if (ctx == NULL || prv == NULL || prv->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (ctx->x == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO); + return CRYPT_DSA_ERR_KEY_INFO; + } + if (BN_Bytes(ctx->para->q) > prv->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH; + } + int32_t ret = BN_Bn2Bin(ctx->x, prv->data, &(prv->len)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_DSA_GetPubKey(const CRYPT_DSA_Ctx *ctx, CRYPT_DsaPub *pub) +{ + if (ctx == NULL || pub == NULL || pub->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->y == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO); + return CRYPT_DSA_ERR_KEY_INFO; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (BN_Bytes(ctx->para->p) > pub->len) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH; + } + int32_t ret = BN_Bn2Bin(ctx->y, pub->data, &(pub->len)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t RandRangeQ(BN_BigNum *r, const BN_BigNum *q) +{ + int32_t cnt = 0; + for (cnt = 0; cnt < CRYPT_DSA_TRY_MAX_CNT; cnt++) { + int32_t ret = BN_RandRange(r, q); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_IsZero(r)) { + continue; + } + return CRYPT_SUCCESS; // if succeed then exit + } + /* If the key fails to be generated after try CRYPT_DSA_TRI_MAX_CNT times, then failed and exit. */ + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_TRY_CNT); + return CRYPT_DSA_ERR_TRY_CNT; +} + +static void RefreshCtx(CRYPT_DSA_Ctx *ctx, BN_BigNum *x, BN_BigNum *y, int32_t ret) +{ + if (ret == CRYPT_SUCCESS) { + BN_Destroy(ctx->x); + BN_Destroy(ctx->y); + ctx->x = x; + ctx->y = y; + } else { + BN_Destroy(x); + BN_Destroy(y); + } +} + +int32_t CRYPT_DSA_Gen(CRYPT_DSA_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + int32_t ret = CRYPT_SUCCESS; + int32_t cnt; + BN_BigNum *x = BN_Create(BN_Bits(ctx->para->q)); + BN_BigNum *y = BN_Create(BN_Bits(ctx->para->p)); + BN_Mont *mont = BN_MontCreate(ctx->para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + if (x == NULL || y == NULL || opt == NULL || mont == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (cnt = 0; cnt < CRYPT_DSA_TRY_MAX_CNT; cnt++) { + /* Generate the private key x of [1, q-1], see RFC6979-2.2. */ + ret = RandRangeQ(x, ctx->para->q); + if (ret != CRYPT_SUCCESS) { + // Internal API, the BSL_ERR_PUSH_ERROR info is already exists when failed. + goto ERR; + } + /* Calculate the public key y. */ + ret = BN_MontExpConsttime(y, ctx->para->g, x, mont, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* y != 0 && y != 1 */ + if (BN_IsZero(y) || BN_IsOne(y)) { + continue; + } + goto ERR; // If succeed then exit. + } + /* If the key fails to be generated after try CRYPT_DSA_TRY_MAX_CNT times, then failed and exit. */ + ret = CRYPT_DSA_ERR_TRY_CNT; + BSL_ERR_PUSH_ERROR(ret); +ERR: + RefreshCtx(ctx, x, y, ret); + BN_MontDestroy(mont); + BN_OptimizerDestroy(opt); + return ret; +} + +static void SignFree(DSA_Sign *sign) +{ + if (sign == NULL) { + return; + } + BN_Destroy(sign->r); + BN_Destroy(sign->s); + BSL_SAL_FREE(sign); +} + +static DSA_Sign *SignNew(const CRYPT_DSA_Ctx *ctx) +{ + DSA_Sign *sign = BSL_SAL_Malloc(sizeof(DSA_Sign)); + if (sign == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + sign->r = BN_Create(BN_Bits(ctx->para->p)); + sign->s = BN_Create(BN_Bits(ctx->para->q)); + if (sign->r == NULL || sign->s == NULL) { + SignFree(sign); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + return sign; +} + +// Get the input hash data, see RFC6979-2.4.1 and RFC6979-2.3.2 +static BN_BigNum *DSA_Bits2Int(BN_BigNum *q, const uint8_t *data, uint32_t dataLen) +{ + BN_BigNum *d = BN_Create(BN_Bits(q)); // 1 byte = 8 bits + if (d == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + if (data != NULL) { + uint32_t qLen = BN_Bytes(q); + uint32_t dLen = (dataLen < qLen) ? dataLen : qLen; + // The input parameters of the function have been verified, and no failure exists. + (void)BN_Bin2Bn(d, data, dLen); + } + return d; +} + +// s = (h+x*sign->r)/k mod q +static int32_t CalcSValue(const CRYPT_DSA_Ctx *ctx, DSA_Sign *sign, BN_BigNum *k, + BN_BigNum *d, BN_Optimizer *opt) +{ + int32_t ret = BN_ModMul(sign->s, ctx->x, sign->r, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_ModAdd(sign->s, d, sign->s, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_ModInv(k, k, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return BN_ModMul(sign->s, sign->s, k, ctx->para->q, opt); +} + +static int32_t SignCore(const CRYPT_DSA_Ctx *ctx, BN_BigNum *d, BN_BigNum *r, + BN_BigNum *s) +{ + int32_t cnt = 0; + int32_t ret = CRYPT_SUCCESS; + BN_BigNum *k = BN_Create(BN_Bits(ctx->para->q)); + BN_Mont *montP = BN_MontCreate(ctx->para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + if (k == NULL || montP == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (cnt = 0; cnt < CRYPT_DSA_TRY_MAX_CNT; cnt++) { + // Generate random number k of [1, q-1], see RFC6979-2.4.2 */ + ret = RandRangeQ(k, ctx->para->q); + if (ret != CRYPT_SUCCESS) { + // Internal function. The BSL_ERR_PUSH_ERROR information exists when the failure occurs. + goto ERR; + } + // Compute r = g^k mod p mod q, see RFC6979-2.4.3 */ + ret = BN_MontExpConsttime(r, ctx->para->g, k, montP, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mod(r, r, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (BN_IsZero(r)) { + continue; + } + // Compute s = (h+x*sign->r)/k mod q, see RFC6979-2.4.4 */ + DSA_Sign sign = { r, s }; + ret = CalcSValue(ctx, &sign, k, d, opt); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + if (BN_IsZero(s)) { + continue; + } + goto ERR; // The signature generation meets the requirements and exits successfully. + } + ret = CRYPT_DSA_ERR_TRY_CNT; + BSL_ERR_PUSH_ERROR(ret); +ERR: + BN_Destroy(k); + BN_MontDestroy(montP); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t CryptDsaSign(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, BN_BigNum **r, + BN_BigNum **s) +{ + int32_t rc = CRYPT_SUCCESS; + BN_BigNum *signR = NULL; + BN_BigNum *signS = NULL; + BN_BigNum *d = DSA_Bits2Int(ctx->para->q, data, dataLen); + if (d == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + rc = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + signR = BN_Create(BN_Bits(ctx->para->p)); + signS = BN_Create(BN_Bits(ctx->para->q)); + if ((signR == NULL) || (signS == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + rc = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + GOTO_ERR_IF_EX(SignCore(ctx, d, signR, signS), rc); + + *r = signR; + *s = signS; + goto OK; +ERR: + BN_Destroy(signR); + BN_Destroy(signS); +OK: + BN_Destroy(d); + return rc; +} + +// Data with a value of 0 can also be signed. +int32_t CRYPT_DSA_Sign(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen) +{ + if (ctx == NULL || sign == NULL || signLen == NULL || (data == NULL && dataLen != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA); + return CRYPT_DSA_ERR_KEY_PARA; + } + if (ctx->x == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO); + return CRYPT_DSA_ERR_KEY_INFO; + } + if (*signLen < CRYPT_DSA_GetSignLen(ctx)) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH; + } + int32_t ret; + BN_BigNum *r = NULL; + BN_BigNum *s = NULL; + ret = CryptDsaSign(ctx, data, dataLen, &r, &s); + if (ret != CRYPT_SUCCESS) { + return ret; + } + DSA_Sign dsaSign = { r, s }; + ret = ASN1_SignDataEncode(&dsaSign, sign, signLen); + BN_Destroy(r); + BN_Destroy(s); + return ret; +} + +static int32_t VerifyCore(const CRYPT_DSA_Ctx *ctx, BN_BigNum *d, const DSA_Sign *sign) +{ + int32_t ret = CRYPT_MEM_ALLOC_FAIL; + BN_BigNum *u1 = BN_Create(BN_Bits(ctx->para->p)); + BN_BigNum *u2 = BN_Create(BN_Bits(ctx->para->p)); + BN_BigNum *w = BN_Create(BN_Bits(ctx->para->q)); + BN_Mont *montP = BN_MontCreate(ctx->para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + if (u1 == NULL || u2 == NULL || w == NULL || montP == NULL || opt == NULL) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* Calculate w = 1/s mod q + * u1 = (d * w) mod q + * u2 = (r * w) mod q + * u1 = (g ^ u1) mod p + * u2 = (y ^ u2) mod p + * v = (u1 * u2) mod p + * v = v mod q + * If v == r, sign verification is succeeded. + */ + ret = BN_ModInv(w, sign->s, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_ModMul(u1, d, w, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_ModMul(u2, sign->r, w, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_MontExpMul(u1, ctx->para->g, u1, ctx->y, u2, montP, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mod(u1, u1, ctx->para->q, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Cmp(u1, sign->r); + if (ret != 0) { + BSL_ERR_PUSH_ERROR(ret); + ret = CRYPT_DSA_VERIFY_FAIL; + } +ERR: + BN_Destroy(u1); + BN_Destroy(u2); + BN_Destroy(w); + BN_MontDestroy(montP); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t CRYPT_DSA_Verify(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen) +{ + if (ctx == NULL || sign == NULL || signLen == 0 || (data == NULL && dataLen != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->para == NULL || ctx->y == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO); + return CRYPT_DSA_ERR_KEY_INFO; + } + int32_t ret; + DSA_Sign *s = SignNew(ctx); + BN_BigNum *d = DSA_Bits2Int(ctx->para->q, data, dataLen); + if (s == NULL || d == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + ret = ASN1_SignDataDecode(s, sign, signLen); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + ret = VerifyCore(ctx, d, s); +ERR: + SignFree(s); + BN_Destroy(d); + return ret; +} + +int32_t CRYPT_DSA_Cmp(const CRYPT_DSA_Ctx *a, const CRYPT_DSA_Ctx *b) +{ + RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT); + + RETURN_RET_IF(a->y == NULL || b->y == NULL, CRYPT_DSA_ERR_KEY_INFO); + RETURN_RET_IF(BN_Cmp(a->y, b->y) != 0, CRYPT_DSA_PUBKEY_NOT_EQUAL); + + // para must be both NULL and non-NULL. + RETURN_RET_IF((a->para == NULL) != (b->para == NULL), CRYPT_DSA_PARA_ERROR); + if (a->para != NULL) { + RETURN_RET_IF(BN_Cmp(a->para->p, b->para->p) != 0 || + BN_Cmp(a->para->q, b->para->q) != 0 || + BN_Cmp(a->para->g, b->para->g) != 0, + CRYPT_DSA_PARA_NOT_EQUAL); + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_DSA_Ctrl(CRYPT_DSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL || val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (opt == CRYPT_CTRL_UP_REFERENCES && len == (uint32_t)sizeof(int)) { + return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val); + } + BSL_ERR_PUSH_ERROR(CRYPT_DSA_UNSUPPORTED_CTRL_OPTION); + return CRYPT_DSA_UNSUPPORTED_CTRL_OPTION; +} + +int32_t CRYPT_DSA_GetSecBits(const CRYPT_DSA_Ctx *ctx) +{ + if (ctx == NULL || ctx->para == NULL || ctx->para->p == NULL || ctx->para->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return BN_SecBit(BN_Bits(ctx->para->p), BN_Bits(ctx->para->q)); +} +#endif /* HITLS_CRYPTO_DSA */ diff --git a/crypto/dsa/src/dsa_local.h b/crypto/dsa/src/dsa_local.h new file mode 100644 index 00000000..f07dc798 --- /dev/null +++ b/crypto/dsa/src/dsa_local.h @@ -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 DSA_LOCAL_H +#define DSA_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_DSA + +#include "crypt_bn.h" +#include "crypt_dsa.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define DSA_MIN_PBITS 1024 // The minimum specification of DSA: 1024 bits +#define DSA_MAX_PBITS 3072 // The maximum specification of DSA: 3072 bits +#define DSA_MIN_QBITS 160 // The minimum specification of parameter q of DSA + +/* DSA key parameters */ +struct DSA_Para { + BN_BigNum *p; + BN_BigNum *q; + BN_BigNum *g; +}; + +/* DSA key ctx */ +struct DSA_Ctx { + BN_BigNum *x; // private key + BN_BigNum *y; // public key + CRYPT_DSA_Para *para; // key parameter + BSL_SAL_RefCount references; +}; + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_DSA + +#endif // DSA_LOCAL_H diff --git a/crypto/eal/src/eal_cipher.c b/crypto/eal/src/eal_cipher.c new file mode 100644 index 00000000..6e64b88a --- /dev/null +++ b/crypto/eal/src/eal_cipher.c @@ -0,0 +1,912 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_CIPHER) + +#include "securec.h" +#include "crypt_algid.h" +#include "crypt_eal_cipher.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "eal_cipher_local.h" +#include "eal_common.h" +#include "crypt_method.h" +#include "crypt_utils.h" +#include "crypt_ealinit.h" + +// Block encryption or not +#define EAL_IS_BLOCKCIPHER(blockSize) ((blockSize) != 1) // 1: stream encryption +#define MODE_XTS_BLOCKSIZE 16 + +int32_t ProcessUpdateCache(CRYPT_EAL_CipherCtx *ctx, const uint8_t **in, uint32_t *inLen, uint8_t **out, + uint32_t *outLen); +int32_t CheckUpdateParam(const CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, const uint8_t *out, + const uint32_t *outLen); +int32_t CheckFinalParam(const CRYPT_EAL_CipherCtx *ctx, const uint8_t *out, const uint32_t *outLen); +int32_t Padding(CRYPT_EAL_CipherCtx *ctx); +int32_t Unpadding(const uint8_t *pad, uint32_t padLen, uint32_t *dataLen, CRYPT_PaddingType type); +int32_t UnpaddingISO7816(const uint8_t *pad, uint32_t padLen, uint32_t *finLen); +int32_t UnpaddingX923(const uint8_t *pad, uint32_t padLen, uint32_t *finLen); +int32_t UnpaddingPkcs(const uint8_t *pad, uint32_t padLen, uint32_t *finLen); + +static CRYPT_EAL_CipherCtx *CipherNewDefaultCtx(CRYPT_CIPHER_AlgId id) +{ + int32_t ret; + EAL_Cipher m; + ret = EAL_FindCipher(id, &m); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_EAL_ERR_ALGID); + return NULL; + } + + CRYPT_EAL_CipherCtx *ctx = + (CRYPT_EAL_CipherCtx *)BSL_SAL_Calloc(1u, sizeof(struct CryptEalCipherCtx) + m.modeMethod->ctxSize); + + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + // Assign the value to modeCtx. + void *modeCtx = ctx + 1; + + // Use keymothod as the input parameter to initialize modeCtx. + // If init fails, this memory will be processed by init, and does not need to be processed at the EAL layer. + ret = m.modeMethod->initCtx(modeCtx, m.ciphMeth); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, ret); + BSL_SAL_FREE(ctx); + return NULL; + } + uint32_t blockSize; + ret = CRYPT_EAL_CipherGetInfo(id, CRYPT_INFO_BLOCK_LEN, &blockSize); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, ret); + BSL_SAL_FREE(ctx); + return NULL; + } + + // Assign these values to eal ctx + ctx->blockSize = blockSize; + ctx->id = id; + ctx->method = m.modeMethod; + ctx->ctx = modeCtx; + ctx->states = EAL_CIPHER_STATE_NEW; + + return ctx; +} + +CRYPT_EAL_CipherCtx *CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AlgId id) +{ +#ifdef HITLS_CRYPTO_ASM_CHECK + if (CRYPT_ASMCAP_Cipher(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return NULL; + } +#endif + return CipherNewDefaultCtx(id); +} + +void CRYPT_EAL_CipherFreeCtx(CRYPT_EAL_CipherCtx *ctx) +{ + if (ctx == NULL) { + // If the input parameter is NULL, it is not considered as an error. + return; + } + if (ctx->method == NULL || ctx->method->deinitCtx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + BSL_SAL_FREE(ctx); + return; + } + // Clear cache and sensitive information before free. + CRYPT_EAL_CipherDeinit(ctx); + + (void)ctx->method->deinitCtx(ctx->ctx); + // Free the memory eal ctx and mode ctx at the EAL layer. + BSL_SAL_FREE(ctx); +} + +static const uint32_t CIPHER_NO_IV[] = { +}; + +static const uint32_t CIPHER_NO_PADDING[] = { + CRYPT_CIPHER_AES128_CTR, + CRYPT_CIPHER_AES192_CTR, + CRYPT_CIPHER_AES256_CTR, + CRYPT_CIPHER_SM4_CTR, + CRYPT_CIPHER_SM4_XTS, +}; + +static const uint32_t CIPHER_IS_AEAD[] = { + CRYPT_CIPHER_AES128_CCM, + CRYPT_CIPHER_AES192_CCM, + CRYPT_CIPHER_AES256_CCM, + CRYPT_CIPHER_AES128_GCM, + CRYPT_CIPHER_AES192_GCM, + CRYPT_CIPHER_AES256_GCM, + CRYPT_CIPHER_CHACHA20_POLY1305, + CRYPT_CIPHER_SM4_GCM, +}; + +int32_t CRYPT_EAL_CipherInit(CRYPT_EAL_CipherCtx *ctx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv, + uint32_t ivLen, bool enc) +{ + int32_t ret; + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->method == NULL || ctx->method->setEncryptKey == NULL || ctx->method->setDecryptKey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + // Clear the cache and sensitive information before initialization. + CRYPT_EAL_CipherDeinit(ctx); + + ctx->enc = enc; + // Set the key. Check the validity of the key in each mode. + if (enc) { + ret = ctx->method->setEncryptKey(ctx->ctx, key, keyLen); + } else { + ret = ctx->method->setDecryptKey(ctx->ctx, key, keyLen); + } + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret); + return ret; + } + + // The IV parameter is not set in ECB mode. + if (!ParamIdIsValid(ctx->id, CIPHER_NO_IV, sizeof(CIPHER_NO_IV) / sizeof(CIPHER_NO_IV[0]))) { + // Set the IV. The ctrl function of each mode checks the validity of parameters. The upper layer does not check. + ret = ctx->method->ctrl(ctx->ctx, CRYPT_CTRL_SET_IV, (uint8_t *)(uintptr_t)iv, ivLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret); + return ret; + } + } + EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS); + // Initialize the pad and states. + ctx->pad = CRYPT_PADDING_NONE; + ctx->states = EAL_CIPHER_STATE_INIT; + return CRYPT_SUCCESS; +} + +static bool IsNoNeedIsoAuth(CRYPT_CIPHER_AlgId id) +{ + // The ISO19790 authentication is not required. + switch (id) { + case CRYPT_CIPHER_AES128_CBC: + case CRYPT_CIPHER_AES192_CBC: + case CRYPT_CIPHER_AES256_CBC: + case CRYPT_CIPHER_AES128_CTR: + case CRYPT_CIPHER_AES192_CTR: + case CRYPT_CIPHER_AES256_CTR: + case CRYPT_CIPHER_AES128_CCM: + case CRYPT_CIPHER_AES192_CCM: + case CRYPT_CIPHER_AES256_CCM: + case CRYPT_CIPHER_AES128_GCM: + case CRYPT_CIPHER_AES192_GCM: + case CRYPT_CIPHER_AES256_GCM: + case CRYPT_CIPHER_CHACHA20_POLY1305: + case CRYPT_CIPHER_AES128_CFB: + case CRYPT_CIPHER_AES192_CFB: + case CRYPT_CIPHER_AES256_CFB: + case CRYPT_CIPHER_AES128_OFB: + case CRYPT_CIPHER_AES192_OFB: + case CRYPT_CIPHER_AES256_OFB: + return false; + default: + return true; + } +} + +void CRYPT_EAL_CipherDeinit(CRYPT_EAL_CipherCtx *ctx) +{ + if (ctx == NULL) { + // If the ctx is NULL during deinit, it is not considered as an error. + return; + } + if (ctx->method == NULL || ctx->method->clean == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return; + } + EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS); + // Initialize the pad. + ctx->pad = CRYPT_PADDING_NONE; + // Clear cache data. + if (IsNoNeedIsoAuth(ctx->id)) { + (void)memset_s(ctx->data, EAL_MAX_BLOCK_LENGTH, 0, EAL_MAX_BLOCK_LENGTH); + } else { + // ISO19790 certification requires that the secure function library cannot be directly invoked. + BSL_SAL_CleanseData((void *)(ctx->data), EAL_MAX_BLOCK_LENGTH); + } + ctx->dataLen = 0; + // Clear keys and sensitive information. + ctx->method->clean(ctx->ctx); + // Restore the state to the state after the new is successful. + ctx->states = EAL_CIPHER_STATE_NEW; +} + +int32_t CRYPT_EAL_CipherReinit(CRYPT_EAL_CipherCtx *ctx, uint8_t *iv, uint32_t ivLen) +{ + int32_t ret; + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + // Without init, reinit cannot be invoked directly. + if (ctx->states == EAL_CIPHER_STATE_NEW) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + + // Clear cache data. + (void)memset_s(ctx->data, EAL_MAX_BLOCK_LENGTH, 0, EAL_MAX_BLOCK_LENGTH); + ctx->dataLen = 0; + + // The IV parameter is not set in ECB mode. + if (!ParamIdIsValid(ctx->id, CIPHER_NO_IV, sizeof(CIPHER_NO_IV) / sizeof (CIPHER_NO_IV[0]))) { + // Reset the IV. In this case, reset the IV is not restricted by the states. + if (ctx->method == NULL || ctx->method->ctrl == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = ctx->method->ctrl(ctx->ctx, CRYPT_CTRL_SET_IV, (uint8_t *)iv, ivLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret); + return ret; + } + } + // Reset the states. + ctx->states = EAL_CIPHER_STATE_INIT; + EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +} + +static bool IsPartialOverLap(const void *out, const void *in, uint32_t len) +{ + uintptr_t diff; + if ((uintptr_t)out > (uintptr_t)in) { + diff = (uintptr_t)out - (uintptr_t)in; + return diff < (uintptr_t)len; + } + // If in >= out, this case is valid. + return false; +} + +int32_t CheckUpdateParam(const CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, const uint8_t *out, + const uint32_t *outLen) +{ + if (ctx == NULL || out == NULL || outLen == NULL || (in == NULL && inLen != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((in != NULL && inLen != 0) && IsPartialOverLap(out, in, inLen)) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_PART_OVERLAP); + return CRYPT_EAL_ERR_PART_OVERLAP; + } + // If the state is not init or update, the state is regarded as an error. + // If the state is final or new, update cannot be directly invoked. + if (!(ctx->states == EAL_CIPHER_STATE_INIT || ctx->states == EAL_CIPHER_STATE_UPDATE)) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + if (ctx->blockSize == 1) { // processing stream encryption + if ((*outLen) < inLen) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_NOT_ENOUGH); + return CRYPT_EAL_BUFF_LEN_NOT_ENOUGH; + } + return CRYPT_SUCCESS; + } + uint8_t blockSize = ctx->blockSize; + // If it's block encryption and the outLen is insufficient for the output result, an error is returned. + if (inLen + ctx->dataLen < inLen) { + // In this case, the outLen must be insufficient. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_NOT_ENOUGH); + return CRYPT_EAL_BUFF_LEN_NOT_ENOUGH; + } + if ((*outLen) < ((inLen + ctx->dataLen) / blockSize * blockSize)) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_NOT_ENOUGH); + return CRYPT_EAL_BUFF_LEN_NOT_ENOUGH; + } + if (ctx->method == NULL || ctx->method->encrypt == NULL || ctx->method->decrypt == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + return CRYPT_SUCCESS; +} + +int32_t ProcessUpdateCache(CRYPT_EAL_CipherCtx *ctx, const uint8_t **in, uint32_t *inLen, uint8_t **out, + uint32_t *outLen) +{ + int32_t ret; + uint8_t blockSize = ctx->blockSize; + // Process the cache. If there is cached data, the cache data is padded into a block first. + if (ctx->dataLen > 0) { + uint8_t padding = blockSize - ctx->dataLen; + padding = (*inLen) > (padding) ? padding : (uint8_t)(*inLen); + if (padding != 0) { + if (memcpy_s(ctx->data + ctx->dataLen, (EAL_MAX_BLOCK_LENGTH - ctx->dataLen), (*in), padding) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + (*inLen) -= padding; + (*in) += padding; + ctx->dataLen += padding; + } + } + // No block is formed, return. + if (ctx->dataLen != blockSize) { + return CRYPT_SUCCESS; + } + + // If the block is padded, perform operations on this block first. + if (ctx->enc) { + ret = ctx->method->encrypt(ctx->ctx, ctx->data, *out, blockSize); + } else { + // If it's decryption and the cached data + input data is equal to blockSize, + // may be it's the last piece of data with padding, the data is cached in the ctx and left for final processing. + if ((*inLen) == 0 && (ctx->pad != CRYPT_PADDING_NONE)) { + (*outLen) = 0; + return CRYPT_SUCCESS; + } + ret = ctx->method->decrypt(ctx->ctx, ctx->data, *out, blockSize); + } + + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ctx->dataLen = 0; + (*outLen) = blockSize; + (*out) += blockSize; + + return CRYPT_SUCCESS; +} + +static int32_t ProcessStream(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out, + uint32_t *outLen) +{ + if (inLen == 0) { + ctx->states = EAL_CIPHER_STATE_UPDATE; + return CRYPT_SUCCESS; + } + int32_t ret; + if (ctx->enc) { + ret = ctx->method->encrypt(ctx->ctx, in, out, inLen); + } else { + ret = ctx->method->decrypt(ctx->ctx, in, out, inLen); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + (*outLen) = inLen; + ctx->states = EAL_CIPHER_STATE_UPDATE; + return CRYPT_SUCCESS; +} + +static int32_t CipherUpdate(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out, + uint32_t *outLen) +{ + int32_t ret; + uint32_t tmpLen = inLen; + const uint8_t *tmpIn = in; + uint8_t *tmpOut = (uint8_t *)out; + + // After verifying that the outLen value is valid, the value of outLen is initialized to 0. + *outLen = 0; + uint8_t blockSize = ctx->blockSize; + // If block encryption is not used, no data is cached. Therefore, the cache does not need to be processed. + if (blockSize == 1) { // Process stream encryption + return ProcessStream(ctx, in, inLen, out, outLen); + } + ret = ProcessUpdateCache(ctx, &tmpIn, &tmpLen, &tmpOut, outLen); + if (ret != CRYPT_SUCCESS) { + // ProcessUpdateCache has a push error that can locate the only error location. No need to add push error here. + return ret; + } + + // If the length of input data plus the length of cached data <= blockSize, return success. + if (tmpLen == 0) { + ctx->states = EAL_CIPHER_STATE_UPDATE; + return CRYPT_SUCCESS; + } + + // In this case, tmpLen is the length which minus the buffer length in the original ctx. + uint8_t left = tmpLen % blockSize; + uint32_t len = tmpLen - left; + + if (len > 0) { + if (ctx->enc) { + ret = ctx->method->encrypt(ctx->ctx, tmpIn, tmpOut, len); + } else { + // If it's block decryption and left is 0, a complete block must be left for final processing. + // If left is not 0, subsequent update data exists. + // In addition, the sum of the cached data and the subsequent update data + // must be an integer multiple of blockSize. Otherwise, an error is reported in the final. + if ((ctx->pad != CRYPT_PADDING_NONE) && left == 0) { + left = blockSize; + len -= blockSize; + } + if (len > 0) { + ret = ctx->method->decrypt(ctx->ctx, tmpIn, tmpOut, len); + } + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + // Process the new cache. + if (left > 0 && (memcpy_s(ctx->data, blockSize, tmpIn + len, left) != EOK)) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + ctx->dataLen = left; + + // The encryption/decryption is successful. OutLen is updated. + (*outLen) += len; + + ctx->states = EAL_CIPHER_STATE_UPDATE; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_CipherUpdate(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out, + uint32_t *outLen) +{ + int32_t ret = CheckUpdateParam(ctx, in, inLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + // The push error in CheckUpdateParam can be locate the only error location. No need to add the push error here. + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, (ctx == NULL) ? CRYPT_CIPHER_MAX : ctx->id, ret); + return ret; + } + ret = CipherUpdate(ctx, in, inLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret); + } + return ret; +} + +int32_t CheckFinalParam(const CRYPT_EAL_CipherCtx *ctx, const uint8_t *out, const uint32_t *outLen) +{ + if (ctx == NULL || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // If the state is not init or update, the state is regarded as an error. + // If the state is final or new, update cannot be directly invoked. + if (!(ctx->states == EAL_CIPHER_STATE_UPDATE || ctx->states == EAL_CIPHER_STATE_INIT)) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + uint8_t blockSize = ctx->blockSize; + // The output buffer is not enough. + if (ctx->pad != CRYPT_PADDING_NONE && (*outLen) < blockSize) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_BUFF_LEN_NOT_ENOUGH); + return CRYPT_EAL_BUFF_LEN_NOT_ENOUGH; + } + if (ctx->method == NULL || ctx->method->encrypt == NULL || ctx->method->decrypt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + return CRYPT_SUCCESS; +} + +int32_t FinalEncrypt(CRYPT_EAL_CipherCtx *ctx, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + ret = Padding(ctx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ctx->dataLen == 0) { + return CRYPT_SUCCESS; + } + ret = ctx->method->encrypt(ctx->ctx, ctx->data, out, ctx->dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + (*outLen) = ctx->dataLen; + return CRYPT_SUCCESS; +} + +int32_t FinalDecrypt(CRYPT_EAL_CipherCtx *ctx, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + uint8_t blockSize = ctx->blockSize; + uint32_t dataLen; + + if (ctx->dataLen == 0) { + return CRYPT_SUCCESS; + } + ret = ctx->method->decrypt(ctx->ctx, ctx->data, out, ctx->dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + dataLen = ctx->dataLen; + ret = Unpadding(out, blockSize, &dataLen, ctx->pad); + if (ret != CRYPT_SUCCESS) { + return ret; + } + *outLen = dataLen; + return CRYPT_SUCCESS; +} + +// Check whether the algorithm is the AEAD algorithm. If yes, true is returned. Otherwise, false is returned. +static bool IsAeadAlg(CRYPT_CIPHER_AlgId id) +{ + if (ParamIdIsValid(id, CIPHER_IS_AEAD, sizeof(CIPHER_IS_AEAD) / sizeof(CIPHER_IS_AEAD[0]))) { + return true; + } + return false; +} + +int32_t CRYPT_EAL_CipherFinal(CRYPT_EAL_CipherCtx *ctx, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + ret = CheckFinalParam(ctx, out, outLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, (ctx == NULL) ? CRYPT_CIPHER_MAX : ctx->id, ret); + return ret; + } + // The AEAD algorithm uses GetTag to end the encryption process. + if (IsAeadAlg(ctx->id)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_CIPHER_FIANL_WITH_AEAD_ERROR); + return CRYPT_EAL_CIPHER_FIANL_WITH_AEAD_ERROR; + } + // After checking the validity of the outLen, the outLen can be initialized to 0. + *outLen = 0; + + if (ctx->enc) { + ret = FinalEncrypt(ctx, out, outLen); + } else { + ret = FinalDecrypt(ctx, out, outLen); + } + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret); + return ret; + } + + ctx->dataLen = 0; + ctx->states = EAL_CIPHER_STATE_FINAL; + EAL_EventReport((ctx->enc) ? CRYPT_EVENT_ENC : CRYPT_EVENT_DEC, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +} + +static bool IfXts(CRYPT_CIPHER_AlgId id) +{ + CRYPT_CIPHER_AlgId XTS_list[] = { + CRYPT_CIPHER_SM4_XTS, + }; + for (uint32_t i = 0; i < sizeof(XTS_list) / sizeof(XTS_list[0]); i++) { + if (id == XTS_list[i]) { + return true; + } + } + return false; +} + +// For performance reasons, it is not recommended that the padding code be split if the padding code is not complex. +int32_t Padding(CRYPT_EAL_CipherCtx *ctx) +{ + uint8_t *pad = ctx-> data + ctx->dataLen; + uint8_t padLen = ctx->blockSize - ctx->dataLen; + uint8_t i; + uint8_t len = ctx->dataLen; + ctx->dataLen += padLen; + switch (ctx->pad) { + case CRYPT_PADDING_NONE: + ctx->dataLen = len; + if (len % (ctx->blockSize) != 0) { + return IfXts(ctx->id) ? CRYPT_SUCCESS : CRYPT_MODE_ERR_INPUT_LEN; + } + break; + case CRYPT_PADDING_ZEROS: + for (i = 0; i < padLen; i++) { + pad[i] = 0x00L; + } + break; + case CRYPT_PADDING_ISO7816: + pad[0] = 0x80; + for (i = 1; i < padLen; i++) { + pad[i] = 0x00L; + } + break; + case CRYPT_PADDING_X923: + for (i = 0; i < padLen - 1; i++) { + pad[i] = 0x00L; + } + pad[padLen - 1] = padLen; + break; + case CRYPT_PADDING_PKCS5: + case CRYPT_PADDING_PKCS7: + for (i = 0; i < padLen; i++) { + pad[i] = padLen; + } + break; + default: + ctx->dataLen = len; + break; + } + return CRYPT_SUCCESS; +} + +int32_t UnpaddingISO7816(const uint8_t *pad, uint32_t padLen, uint32_t *finLen) +{ + uint32_t len; + const uint8_t *p = pad; + len = padLen - 1; + while (*(p + len) == 0 && len > 0) { + len--; + } + len = (*(p + len) == 0x80) ? len : padLen; + + if (len == padLen) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_CIPHER_DATA_ERROR); + return CRYPT_EAL_CIPHER_DATA_ERROR; + } + (*finLen) = len; + return CRYPT_SUCCESS; +} + +int32_t UnpaddingX923(const uint8_t *pad, uint32_t padLen, uint32_t *finLen) +{ + uint32_t len, pos, i; + uint32_t check = 0; + len = pad[padLen - 1]; + + check |= (uint32_t)(len > padLen); + + pos = padLen - len; + for (i = 0; i < padLen - 1; i++) { + check |= (pad[i] * (uint32_t)(i >= pos)); + } + + if (check != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_CIPHER_DATA_ERROR); + return CRYPT_EAL_CIPHER_DATA_ERROR; + } + + (*finLen) = padLen - len; + return CRYPT_SUCCESS; +} + +int32_t UnpaddingPkcs(const uint8_t *pad, uint32_t padLen, uint32_t *finLen) +{ + uint32_t len, pos, i; + uint32_t check = 0; + + len = pad[padLen - 1]; + check |= (uint32_t)((len == 0) || (len > padLen)); + + pos = padLen - len; + for (i = 0; i < padLen; i++) { + check |= ((pad[i] ^ len) * (uint32_t)(i >= pos)); + } + + if (check != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_CIPHER_DATA_ERROR); + return CRYPT_EAL_CIPHER_DATA_ERROR; + } + + (*finLen) = padLen - len; + return CRYPT_SUCCESS; +} + +int32_t Unpadding(const uint8_t *pad, uint32_t padLen, uint32_t *dataLen, CRYPT_PaddingType type) +{ + int32_t ret = 0; + uint32_t len = *dataLen; + switch (type) { + case CRYPT_PADDING_ISO7816: + ret = UnpaddingISO7816(pad, padLen, &len); + break; + case CRYPT_PADDING_X923: + ret = UnpaddingX923(pad, padLen, &len); + break; + case CRYPT_PADDING_PKCS5: + case CRYPT_PADDING_PKCS7: + ret = UnpaddingPkcs(pad, padLen, &len); + break; + default: + break; + } + + *dataLen = len; + return ret; +} + +// Check whether the operation is write operation. New write operations need to be added here +// to prevent them from being modified during calculation. +static bool CipherCtrlIsCanSet(const CRYPT_EAL_CipherCtx *ctx, int32_t type) +{ + if (type == CRYPT_CTRL_DES_NOKEYCHECK || type == CRYPT_CTRL_RC2_SETEFFLEN) { + return true; + } + if (ctx->states == EAL_CIPHER_STATE_NEW) { + return false; + } + if (ctx->states == EAL_CIPHER_STATE_FINAL) { + return false; + } + if ((ctx->states == EAL_CIPHER_STATE_UPDATE) && + (type == CRYPT_CTRL_SET_COUNT || type == CRYPT_CTRL_SET_TAGLEN || + type == CRYPT_CTRL_SET_MSGLEN || type == CRYPT_CTRL_SET_AAD)) { + return false; + } + return true; +} + +static void ReportCtrlEvent(CRYPT_EAL_CipherCtx *ctx, int32_t type, int32_t ret) +{ + if (ret != CRYPT_SUCCESS) { // report abnormal events + EAL_EventReport(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret); + return; + } + if (type == CRYPT_CTRL_GET_TAG) { // report the encryption/decryption service is executed + EAL_EventReport((ctx->enc) ? CRYPT_EVENT_ENC : CRYPT_EVENT_DEC, CRYPT_ALGO_CIPHER, ctx->id, ret); + return; + } + if (type == CRYPT_CTRL_SET_IV) { // report the sensitive information is added + EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_CIPHER, ctx->id, ret); + return; + } + if (type == CRYPT_CTRL_GET_IV) { // report sensitive information is accessed + EAL_EventReport(CRYPT_EVENT_GETSSP, CRYPT_ALGO_CIPHER, ctx->id, ret); + return; + } + return; +} + +int32_t CRYPT_EAL_CipherCtrl(CRYPT_EAL_CipherCtx *ctx, int32_t type, void *data, uint32_t len) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + // The IV cannot be set through the Ctrl. You need to set the IV through the init and reinit. + if (type == CRYPT_CTRL_SET_IV) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_CIPHER_CTRL_ERROR); + return CRYPT_EAL_CIPHER_CTRL_ERROR; + } + + // If the algorithm is running in the intermediate state, write operations are not allowed. + if (!CipherCtrlIsCanSet(ctx, type)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + // Setting AAD indicates that the encryption operation has started and no more write operations are allowed. + if (type == CRYPT_CTRL_SET_AAD) { + ctx->states = EAL_CIPHER_STATE_UPDATE; + } + // After getTag the system enters the final state. + if (type == CRYPT_CTRL_GET_TAG) { + ctx->states = EAL_CIPHER_STATE_FINAL; + } + if (type == CRYPT_CTRL_GET_BLOCKSIZE) { + if (data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + *(uint32_t *)data = (uint32_t)ctx->blockSize; + return CRYPT_SUCCESS; + } + if (ctx->method == NULL || ctx->method->ctrl == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + int32_t ret = ctx->method->ctrl(ctx->ctx, type, data, len); + ReportCtrlEvent(ctx, type, ret); + return ret; +} + +int32_t CRYPT_EAL_CipherSetPadding(CRYPT_EAL_CipherCtx *ctx, CRYPT_PaddingType type) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->blockSize == 1) { // blockSize == 1, no pad is required. + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_PADDING_NOT_SUPPORT); + return CRYPT_EAL_PADDING_NOT_SUPPORT; + } + + // The algorithm does not support invalid padding types. + if (type < 0 || type >= CRYPT_PADDING_MAX_COUNT) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_PADDING_NOT_SUPPORT); + return CRYPT_EAL_PADDING_NOT_SUPPORT; + } + // XTS and CTR do not support padding. + if (ParamIdIsValid(ctx->id, CIPHER_NO_PADDING, sizeof(CIPHER_NO_PADDING) / sizeof(CIPHER_NO_PADDING[0]))) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_PADDING_NOT_SUPPORT); + return CRYPT_EAL_PADDING_NOT_SUPPORT; + } + uint8_t blockSize = ctx->blockSize; + // The non-block encryption algorithm does not support padding. During decryption, padding 0 cannot be set + // because it cannot be determined whether 0 is user data or padding data and users need to determine it. + if (!EAL_IS_BLOCKCIPHER(blockSize) || (!ctx->enc && ctx->pad == CRYPT_PADDING_ZEROS)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_PADDING_NOT_SUPPORT); + return CRYPT_EAL_PADDING_NOT_SUPPORT; + } + ctx->pad = type; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_CipherGetPadding(CRYPT_EAL_CipherCtx *ctx) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ctx->pad; +} + +bool CRYPT_EAL_CipherIsValidAlgId(CRYPT_CIPHER_AlgId id) +{ + EAL_Cipher m; + return EAL_FindCipher(id, &m) == CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AlgId id, int32_t type, uint32_t *infoValue) +{ + if (infoValue == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + CRYPT_CipherInfo info = {0}; + if (EAL_GetCipherInfo(id, &info) != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + + switch (type) { + case CRYPT_INFO_IS_AEAD: + (*infoValue) = IsAeadAlg(id) ? 1 : 0; + break; + case CRYPT_INFO_IS_STREAM: + (*infoValue) = (uint32_t)!EAL_IS_BLOCKCIPHER(info.blockSize); + break; + case CRYPT_INFO_IV_LEN: + (*infoValue) = info.ivLen; + break; + case CRYPT_INFO_KEY_LEN: + (*infoValue) = info.keyLen; + break; + case CRYPT_INFO_BLOCK_LEN: + (*infoValue) = (uint32_t)info.blockSize; + break; + default: + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_EAL_INTO_TYPE_NOT_SUPPORT); + return CRYPT_EAL_INTO_TYPE_NOT_SUPPORT; + } + + return CRYPT_SUCCESS; +} +#endif diff --git a/crypto/eal/src/eal_cipher_local.h b/crypto/eal/src/eal_cipher_local.h new file mode 100644 index 00000000..0614e404 --- /dev/null +++ b/crypto/eal/src/eal_cipher_local.h @@ -0,0 +1,151 @@ +/* + * 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 EAL_CIPHER_LOCAL_H +#define EAL_CIPHER_LOCAL_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_CIPHER) + +#include "crypt_modes.h" +#include "crypt_algid.h" +#include "crypt_eal_cipher.h" +#include "crypt_local_types.h" +#ifdef HITLS_CRYPTO_GCM +#include "crypt_modes_gcm.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define EAL_MAX_BLOCK_LENGTH 32 + +/** + * @ingroup crypt_cipherstates + * Symmetry encryption/decryption status */ +typedef enum { + EAL_CIPHER_STATE_NEW, + EAL_CIPHER_STATE_INIT, + EAL_CIPHER_STATE_UPDATE, + EAL_CIPHER_STATE_FINAL +} EAL_CipherStates; + +/** + * @ingroup alg map + * Symmetric encryption/decryption mode and ID of the encryption algorithm. + */ +typedef struct { + uint32_t id; + CRYPT_MODE_AlgId modeId; + CRYPT_SYM_AlgId symId; +} EAL_SymAlgMap; + +/** +* @ingroup EAL +* +* EAL_Cipher is used for mode and algorithm combination. +*/ +typedef struct { + const EAL_CipherMethod *ciphMeth; + const EAL_CipherMethod *modeMethod; +} EAL_Cipher; + +typedef struct { + uint32_t id; + const EAL_Cipher *symMeth; +} EAL_SymAlgMapAsm; + +/** +* @ingroup EAL +* +* CRYPT_CipherInfo: User search algorithm information. Currently, only blockSize is available. +*/ +typedef struct { + CRYPT_CIPHER_AlgId id; + uint8_t blockSize; + uint32_t keyLen; + uint32_t ivLen; +} CRYPT_CipherInfo; + +/** + * @ingroup crypt_eal_cipherctx + * Asymmetric algorithm data type */ +struct CryptEalCipherCtx { + CRYPT_CIPHER_AlgId id; + uint8_t data[EAL_MAX_BLOCK_LENGTH]; /**< last data block that may not be processed */ + bool enc; /**< whether encrypted or decrypted */ + uint8_t dataLen; /**< size of the last data block that may not be processed. */ + uint8_t blockSize; /**< blockSize corresponding to the algorithm */ + CRYPT_PaddingType pad; /**< padding type */ + EAL_CipherStates states; /**< record status */ + void *ctx; /**< handle of the mode */ + const EAL_CipherMethod *method; /**< method corresponding to the encryption/decryption mode */ +}; + +/** + * @brief Obtain the EAL_Cipher based on the algorithm ID. + * + * @param id [IN] Symmetric encryption/decryption algorithm ID. + * @param m [IN/OUT] EAL_Cipher Pointer + * @return If it's successful, the system returns CRYPT_SUCCESS and assigns the value to the method in m. + * If it's failed, returns CRYPT_EAL_ERR_ALGID: ID of the unsupported algorithm. + */ +int32_t EAL_FindCipher(CRYPT_CIPHER_AlgId id, EAL_Cipher *m); + +/** + * @brief Obtain the method of the symmetric algorithm based on the algorithm ID. + * + * @param id [IN] Symmetric algorithm ID. + * @return If it's successful, the method of the symmetric algorithm is returned. + * If it's failed, NULL is returned. + */ +const EAL_CipherMethod *EAL_FindSymMethod(CRYPT_SYM_AlgId id); + +/** + * @brief Obtain keyLen/ivLen/blockSize based on the algorithm ID. + * + * @param id [IN] Symmetric algorithm ID. + * @param id [OUT] Assign the obtained keyLen/ivLen/blockSize to the variable corresponding to info. + * + * @return Success: CRYPT_SUCCESS + * Failure: CRYPT_ERR_ALGID + */ +int32_t EAL_GetCipherInfo(CRYPT_CIPHER_AlgId id, CRYPT_CipherInfo *info); + +/** + * @brief Obtain mode method based on the algorithm ID + * + * @param id [IN] Symmetric encryption/decryption algorithm ID. + * @return If the operation is successful, the combination of ciphers is returned. + * If the operation fails, NULL is returned. + */ +const EAL_CipherMethod *EAL_FindModeMethod(CRYPT_MODE_AlgId id); + +#ifdef HITLS_CRYPTO_GCM +typedef struct { + MODES_GCM_Ctx mode; + int32_t (*encBlock)(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + int32_t (*decBlock)(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +} EAL_GCM_Ctx; +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CIPHER + +#endif // EAL_CIPHER_LOCAL_H diff --git a/crypto/eal/src/eal_cipher_method.c b/crypto/eal/src/eal_cipher_method.c new file mode 100644 index 00000000..4e9260ed --- /dev/null +++ b/crypto/eal/src/eal_cipher_method.c @@ -0,0 +1,873 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_CIPHER) + +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "eal_cipher_local.h" +#include "crypt_modes.h" +#ifdef HITLS_CRYPTO_CTR +#include "crypt_modes_ctr.h" +#endif +#ifdef HITLS_CRYPTO_CBC +#include "crypt_modes_cbc.h" +#endif +#ifdef HITLS_CRYPTO_GCM +#include "crypt_modes_gcm.h" +#endif +#ifdef HITLS_CRYPTO_CCM +#include "crypt_modes_ccm.h" +#endif +#ifdef HITLS_CRYPTO_XTS +#include "crypt_modes_xts.h" +#endif +#ifdef HITLS_CRYPTO_AES +#include "crypt_aes.h" +#endif +#ifdef HITLS_CRYPTO_CHACHA20POLY1305 +#include "crypt_modes_chacha20poly1305.h" +#endif +#ifdef HITLS_CRYPTO_CHACHA20 +#include "crypt_chacha20.h" +#endif +#ifdef HITLS_CRYPTO_SM4 +#include "crypt_sm4.h" +#endif +#ifdef HITLS_CRYPTO_CFB +#include "crypt_modes_cfb.h" +#endif +#ifdef HITLS_CRYPTO_OFB +#include "crypt_modes_ofb.h" +#endif +#include "eal_common.h" +#include "bsl_sal.h" + +typedef int32_t (*InitCtx)(void *ctx, const struct EAL_CipherMethod *m); +typedef void (*DeinitCtx)(void *ctx); +typedef void (*Clean)(void *ctx); +typedef int32_t (*SetEncryptKey)(void *ctx, const uint8_t *key, uint32_t len); +typedef int32_t (*SetDecryptKey)(void *ctx, const uint8_t *key, uint32_t len); +typedef int32_t (*Encrypt)(void *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +typedef int32_t (*Decrypt)(void *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +typedef int32_t (*Ctrl)(void *ctx, uint32_t opt, void *val, uint32_t len); + +#ifdef HITLS_CRYPTO_AES +static const EAL_CipherMethod AES128_METHOD = { + NULL, + NULL, + (Clean)CRYPT_AES_Clean, + (SetEncryptKey)CRYPT_AES_SetEncryptKey128, + (SetDecryptKey)CRYPT_AES_SetDecryptKey128, + (Encrypt)CRYPT_AES_Encrypt, + (Decrypt)CRYPT_AES_Decrypt, + NULL, + 16, + sizeof(CRYPT_AES_Key), + CRYPT_SYM_AES128 +}; + +static const EAL_CipherMethod AES192_METHOD = { + NULL, + NULL, + (Clean)CRYPT_AES_Clean, + (SetEncryptKey)CRYPT_AES_SetEncryptKey192, + (SetDecryptKey)CRYPT_AES_SetDecryptKey192, + (Encrypt)CRYPT_AES_Encrypt, + (Decrypt)CRYPT_AES_Decrypt, + NULL, + 16, + sizeof(CRYPT_AES_Key), + CRYPT_SYM_AES192 +}; + +static const EAL_CipherMethod AES256_METHOD = { + NULL, + NULL, + (Clean)CRYPT_AES_Clean, + (SetEncryptKey)CRYPT_AES_SetEncryptKey256, + (SetDecryptKey)CRYPT_AES_SetDecryptKey256, + (Encrypt)CRYPT_AES_Encrypt, + (Decrypt)CRYPT_AES_Decrypt, + NULL, + 16, + sizeof(CRYPT_AES_Key), + CRYPT_SYM_AES256 +}; + +#ifdef HITLS_CRYPTO_GCM +static const EAL_CipherMethod AES_GCM_METHOD = { + (InitCtx)MODES_GCM_InitCtx, + (DeinitCtx)MODES_GCM_DeinitCtx, + (Clean)MODES_GCM_Clean, + (SetEncryptKey)MODES_GCM_SetKey, + (SetDecryptKey)MODES_GCM_SetKey, + (Encrypt)AES_GCM_EncryptBlock, + (Decrypt)AES_GCM_DecryptBlock, + (Ctrl)MODES_GCM_Ctrl, + 1, + sizeof(EAL_GCM_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CCM +static const EAL_CipherMethod AES_CCM_METHOD = { + (InitCtx)MODES_CCM_InitCtx, + (DeinitCtx)MODES_CCM_DeinitCtx, + (Clean)MODES_CCM_Clean, + (SetEncryptKey)MODES_CCM_SetKey, + (SetDecryptKey)MODES_CCM_SetKey, + (Encrypt)MODES_CCM_Encrypt, + (Decrypt)MODES_CCM_Decrypt, + (Ctrl)MODES_CCM_Ctrl, + 1, + sizeof(MODES_CCM_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CBC +static const EAL_CipherMethod AES_CBC_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_CBC_Clean, + (SetEncryptKey)MODE_SetEncryptKey, + (SetDecryptKey)MODE_SetDecryptKey, + (Encrypt)AES_CBC_EncryptBlock, + (Decrypt)AES_CBC_DecryptBlock, + (Ctrl)MODE_Ctrl, + 16, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CTR +static const EAL_CipherMethod AES_CTR_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_CTR_Clean, + (SetEncryptKey)MODE_SetEncryptKey, + (SetDecryptKey)MODE_SetEncryptKey, + (Encrypt)AES_CTR_EncryptBlock, + (Decrypt)AES_CTR_DecryptBlock, + (Ctrl)MODE_Ctrl, + 1, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CFB +static const EAL_CipherMethod AES_CFB_METHOD = { + (InitCtx)MODE_CFB_InitCtx, + (DeinitCtx)MODE_CFB_DeInitCtx, + (Clean)MODE_CFB_Clean, + (SetEncryptKey)MODE_CFB_SetEncryptKey, + (SetDecryptKey)MODE_CFB_SetEncryptKey, + (Encrypt)MODE_CFB_Encrypt, + (Decrypt)MODE_AES_CFB_Decrypt, + (Ctrl)MODE_CFB_Ctrl, + 1, + sizeof(MODE_CFB_Ctx), + 0 +}; +#endif + +#endif // HITLS_CRYPTO_AES + +#ifdef HITLS_CRYPTO_CHACHA20 +static const EAL_CipherMethod CHACHA20_METHOD = { + NULL, + NULL, + NULL, + (SetEncryptKey)CRYPT_CHACHA20_SetKey, + (SetDecryptKey)CRYPT_CHACHA20_SetKey, + (Encrypt)CRYPT_CHACHA20_Update, + (Decrypt)CRYPT_CHACHA20_Update, + (Ctrl)CRYPT_CHACHA20_Ctrl, + 1, + sizeof(CRYPT_CHACHA20_Ctx), + CRYPT_SYM_CHACHA20 +}; +#endif + +#ifdef HITLS_CRYPTO_SM4 +static const EAL_CipherMethod SM4_METHOD = { + (InitCtx)NULL, + (DeinitCtx)NULL, + (Clean)CRYPT_SM4_Clean, + (SetEncryptKey)CRYPT_SM4_SetKey, + (SetDecryptKey)CRYPT_SM4_SetKey, + (Encrypt)CRYPT_SM4_Encrypt, + (Decrypt)CRYPT_SM4_Decrypt, + NULL, + 16, + sizeof(CRYPT_SM4_Ctx), + CRYPT_SYM_SM4 +}; + +#ifdef HITLS_CRYPTO_CBC +static const EAL_CipherMethod SM4_CBC_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_CBC_Clean, + (SetEncryptKey)MODES_SM4_SetEncryptKey, + (SetDecryptKey)MODES_SM4_SetDecryptKey, + (Encrypt)MODE_SM4_CBC_Encrypt, + (Decrypt)MODE_SM4_CBC_Decrypt, + (Ctrl)MODE_Ctrl, + 16, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_XTS +static const EAL_CipherMethod SM4_XTS_METHOD = { + (InitCtx)MODE_XTS_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODES_SM4_XTS_Clean, + (SetEncryptKey)MODES_SM4_XTS_SetEncryptKey, + (SetDecryptKey)MODES_SM4_XTS_SetDecryptKey, + (Encrypt)MODES_SM4_XTS_Encrypt, + (Decrypt)MODES_SM4_XTS_Decrypt, + (Ctrl)MODE_XTS_Ctrl, + 1, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CFB +static const EAL_CipherMethod SM4_CFB_METHOD = { + (InitCtx)MODE_CFB_InitCtx, + (DeinitCtx)MODE_CFB_DeInitCtx, + (Clean)MODE_CFB_Clean, + (SetEncryptKey)MODES_SM4_CFB_SetEncryptKey, + (SetDecryptKey)MODES_SM4_CFB_SetEncryptKey, + (Encrypt)MODE_SM4_CFB_Encrypt, + (Decrypt)MODE_SM4_CFB_Decrypt, + (Ctrl)MODE_CFB_Ctrl, + 1, + sizeof(MODE_CFB_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_OFB +static const EAL_CipherMethod SM4_OFB_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_Clean, + (SetEncryptKey)MODES_SM4_SetEncryptKey, + (SetDecryptKey)MODES_SM4_SetEncryptKey, + (Encrypt)MODE_SM4_OFB_Encrypt, + (Decrypt)MODE_SM4_OFB_Decrypt, + (Ctrl)MODE_Ctrl, + 1, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_GCM +static const EAL_CipherMethod SM4_GCM_METHOD = { + (InitCtx)MODES_GCM_InitCtx, + (DeinitCtx)MODES_GCM_DeinitCtx, + (Clean)MODES_GCM_Clean, + (SetEncryptKey)MODES_SM4_GCM_SetKey, + (SetDecryptKey)MODES_SM4_GCM_SetKey, + (Encrypt)MODES_SM4_GCM_EncryptBlock, + (Decrypt)MODES_SM4_GCM_DecryptBlock, + (Ctrl)MODES_GCM_Ctrl, + 1, + sizeof(EAL_GCM_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CTR +static const EAL_CipherMethod SM4_CTR_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_CTR_Clean, + (SetEncryptKey)MODES_SM4_SetEncryptKey, + (SetDecryptKey)MODES_SM4_SetEncryptKey, + (Encrypt)MODE_SM4_CTR_Encrypt, + (Decrypt)MODE_SM4_CTR_Decrypt, + (Ctrl)MODE_Ctrl, + 1, + sizeof(MODE_CipherCtx), + 0 +}; +#endif +#endif // HITLS_CRYPTO_SM4 + +#ifdef HITLS_CRYPTO_CTR +static const EAL_CipherMethod CTR_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_CTR_Clean, + (SetEncryptKey)MODE_SetEncryptKey, + (SetDecryptKey)MODE_SetEncryptKey, + (Encrypt)MODE_CTR_Crypt, + (Decrypt)MODE_CTR_Crypt, + (Ctrl)MODE_Ctrl, + 1, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CBC +static const EAL_CipherMethod CBC_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_CBC_Clean, + (SetEncryptKey)MODE_SetEncryptKey, + (SetDecryptKey)MODE_SetDecryptKey, + (Encrypt)MODE_CBC_Encrypt, + (Decrypt)MODE_CBC_Decrypt, + (Ctrl)MODE_Ctrl, + 0, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CCM +static const EAL_CipherMethod CCM_METHOD = { + (InitCtx)MODES_CCM_InitCtx, + (DeinitCtx)MODES_CCM_DeinitCtx, + (Clean)MODES_CCM_Clean, + (SetEncryptKey)MODES_CCM_SetKey, + (SetDecryptKey)MODES_CCM_SetKey, + (Encrypt)MODES_CCM_Encrypt, + (Decrypt)MODES_CCM_Decrypt, + (Ctrl)MODES_CCM_Ctrl, + 1, + sizeof(MODES_CCM_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_GCM +static const EAL_CipherMethod GCM_METHOD = { + (InitCtx)MODES_GCM_InitCtx, + (DeinitCtx)MODES_GCM_DeinitCtx, + (Clean)MODES_GCM_Clean, + (SetEncryptKey)MODES_GCM_SetKey, + (SetDecryptKey)MODES_GCM_SetKey, + (Encrypt)MODES_GCM_Encrypt, + (Decrypt)MODES_GCM_Decrypt, + (Ctrl)MODES_GCM_Ctrl, + 1, + sizeof(MODES_GCM_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CHACHA20POLY1305 +static const EAL_CipherMethod CHACHA20_POLY1305_METHOD = { + (InitCtx)MODES_CHACHA20POLY1305_InitCtx, + (DeinitCtx)MODES_CHACHA20POLY1305_DeinitCtx, + (Clean)MODES_CHACHA20POLY1305_Clean, + (SetEncryptKey)MODES_CHACHA20POLY1305_SetEncryptKey, + (SetDecryptKey)MODES_CHACHA20POLY1305_SetDecryptKey, + (Encrypt)MODES_CHACHA20POLY1305_Encrypt, + (Decrypt)MODES_CHACHA20POLY1305_Decrypt, + (Ctrl)MODES_CHACHA20POLY1305_Ctrl, + 1, + sizeof(MODES_CHACHA20POLY1305_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_CFB +static const EAL_CipherMethod CFB_METHOD = { + (InitCtx)MODE_CFB_InitCtx, + (DeinitCtx)MODE_CFB_DeInitCtx, + (Clean)MODE_CFB_Clean, + (SetEncryptKey)MODE_CFB_SetEncryptKey, + (SetDecryptKey)MODE_CFB_SetEncryptKey, + (Encrypt)MODE_CFB_Encrypt, + (Decrypt)MODE_CFB_Decrypt, + (Ctrl)MODE_CFB_Ctrl, + 1, + sizeof(MODE_CFB_Ctx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_OFB +static const EAL_CipherMethod OFB_METHOD = { + (InitCtx)MODE_InitCtx, + (DeinitCtx)MODE_DeInitCtx, + (Clean)MODE_Clean, + (SetEncryptKey)MODE_SetEncryptKey, + (SetDecryptKey)MODE_SetEncryptKey, + (Encrypt)MODE_OFB_Crypt, + (Decrypt)MODE_OFB_Crypt, + (Ctrl)MODE_Ctrl, + 1, + sizeof(MODE_CipherCtx), + 0 +}; +#endif + +#ifdef HITLS_CRYPTO_AES +#ifdef HITLS_CRYPTO_GCM +static const EAL_Cipher g_aes128Gcm = { + &AES128_METHOD, + &AES_GCM_METHOD +}; +static const EAL_Cipher g_aes192Gcm = { + &AES192_METHOD, + &AES_GCM_METHOD +}; +static const EAL_Cipher g_aes256Gcm = { + &AES256_METHOD, + &AES_GCM_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CTR +static const EAL_Cipher g_aes128Ctr = { + &AES128_METHOD, + &AES_CTR_METHOD +}; +static const EAL_Cipher g_aes192Ctr = { + &AES192_METHOD, + &AES_CTR_METHOD +}; +static const EAL_Cipher g_aes256Ctr = { + &AES256_METHOD, + &AES_CTR_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CBC +static const EAL_Cipher AES128_CBC = { + &AES128_METHOD, + &AES_CBC_METHOD +}; +static const EAL_Cipher AES192_CBC = { + &AES192_METHOD, + &AES_CBC_METHOD +}; +static const EAL_Cipher AES256_CBC = { + &AES256_METHOD, + &AES_CBC_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CFB +static const EAL_Cipher AES128_CFB = { + &AES128_METHOD, + &AES_CFB_METHOD +}; +static const EAL_Cipher AES192_CFB = { + &AES192_METHOD, + &AES_CFB_METHOD +}; +static const EAL_Cipher AES256_CFB = { + &AES256_METHOD, + &AES_CFB_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CCM +static const EAL_Cipher AES128_CCM = { + &AES128_METHOD, + &AES_CCM_METHOD +}; +static const EAL_Cipher AES192_CCM = { + &AES192_METHOD, + &AES_CCM_METHOD +}; +static const EAL_Cipher AES256_CCM = { + &AES256_METHOD, + &AES_CCM_METHOD +}; +#endif +#endif // HITLS_CRYPTO_AES + +#ifdef HITLS_CRYPTO_SM4 +#ifdef HITLS_CRYPTO_XTS +static const EAL_Cipher g_sm4Xts = { + &SM4_METHOD, + &SM4_XTS_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CBC +static const EAL_Cipher g_sm4Cbc = { + &SM4_METHOD, + &SM4_CBC_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CFB +static const EAL_Cipher g_sm4Cfb = { + &SM4_METHOD, + &SM4_CFB_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_OFB +static const EAL_Cipher g_sm4Ofb = { + &SM4_METHOD, + &SM4_OFB_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_CTR +static const EAL_Cipher g_sm4Ctr = { + &SM4_METHOD, + &SM4_CTR_METHOD +}; +#endif + +#ifdef HITLS_CRYPTO_GCM +static const EAL_Cipher g_sm4Gcm = { + &SM4_METHOD, + &SM4_GCM_METHOD +}; +#endif +#endif // HITLS_CRYPTO_SM4 + +/** + * 1. Mode and algorithm combination acceleration table (hash table) + * (There is a hash mapping relationship based on CRYPT_CIPHER_AlgId. Pay attention to the synchronization.) + * 2. This table saves the assembly acceleration of the mode and algorithm, for example, aes-gcm and aes-cbc. + * 3. If the assembly acceleration is not implemented, set the value to NULL. + * If the value is NULL, the original C-Language logic is used. + */ +static const EAL_SymAlgMapAsm EAL_CIPHER_METHOD_ASM[] = { +#ifdef HITLS_CRYPTO_AES +#ifdef HITLS_CRYPTO_CBC + { .id = CRYPT_CIPHER_AES128_CBC, &AES128_CBC }, + { .id = CRYPT_CIPHER_AES192_CBC, &AES192_CBC }, + { .id = CRYPT_CIPHER_AES256_CBC, &AES256_CBC }, +#endif + +#ifdef HITLS_CRYPTO_CTR + { .id = CRYPT_CIPHER_AES128_CTR, &g_aes128Ctr }, + { .id = CRYPT_CIPHER_AES192_CTR, &g_aes192Ctr }, + { .id = CRYPT_CIPHER_AES256_CTR, &g_aes256Ctr }, +#endif + +#ifdef HITLS_CRYPTO_CCM + { .id = CRYPT_CIPHER_AES128_CCM, &AES128_CCM }, + { .id = CRYPT_CIPHER_AES192_CCM, &AES192_CCM }, + { .id = CRYPT_CIPHER_AES256_CCM, &AES256_CCM }, +#endif + +#ifdef HITLS_CRYPTO_GCM + { .id = CRYPT_CIPHER_AES128_GCM, &g_aes128Gcm }, + { .id = CRYPT_CIPHER_AES192_GCM, &g_aes192Gcm }, + { .id = CRYPT_CIPHER_AES256_GCM, &g_aes256Gcm }, +#endif + +#ifdef HITLS_CRYPTO_CFB + { .id = CRYPT_CIPHER_AES128_CFB, &AES128_CFB }, + { .id = CRYPT_CIPHER_AES192_CFB, &AES192_CFB }, + { .id = CRYPT_CIPHER_AES256_CFB, &AES256_CFB }, +#endif + +#ifdef HITLS_CRYPTO_OFB + { .id = CRYPT_CIPHER_AES128_OFB, NULL }, + { .id = CRYPT_CIPHER_AES192_OFB, NULL }, + { .id = CRYPT_CIPHER_AES256_OFB, NULL }, +#endif +#endif // HITLS_CRYPTO_AES + +#ifdef HITLS_CRYPTO_CHACHA20 + { .id = CRYPT_CIPHER_CHACHA20_POLY1305, NULL }, +#endif + +#ifdef HITLS_CRYPTO_SM4 +#ifdef HITLS_CRYPTO_XTS + { .id = CRYPT_CIPHER_SM4_XTS, &g_sm4Xts }, +#endif +#ifdef HITLS_CRYPTO_CBC + { .id = CRYPT_CIPHER_SM4_CBC, &g_sm4Cbc }, +#endif +#ifdef HITLS_CRYPTO_CTR + { .id = CRYPT_CIPHER_SM4_CTR, &g_sm4Ctr }, +#endif +#ifdef HITLS_CRYPTO_GCM + { .id = CRYPT_CIPHER_SM4_GCM, &g_sm4Gcm }, +#endif +#ifdef HITLS_CRYPTO_CFB + { .id = CRYPT_CIPHER_SM4_CFB, &g_sm4Cfb }, +#endif +#ifdef HITLS_CRYPTO_OFB + { .id = CRYPT_CIPHER_SM4_OFB, &g_sm4Ofb }, +#endif +#endif // HITLS_CRYPTO_SM4 +}; + +/** + * g_symMethod[id] + * The content of g_symMethod has a hash mapping relationship with CRYPT_SYM_AlgId. Change the value accordingly. + */ +static const EAL_CipherMethod *g_symMethod[CRYPT_SYM_MAX] = { +#ifdef HITLS_CRYPTO_AES + &AES128_METHOD, + &AES192_METHOD, + &AES256_METHOD, +#else + NULL, + NULL, + NULL, +#endif + +#ifdef HITLS_CRYPTO_CHACHA20 + &CHACHA20_METHOD, +#else + NULL, +#endif + +#ifdef HITLS_CRYPTO_SM4 + &SM4_METHOD, +#else + NULL, +#endif + +}; + +/** + * g_modeMethod[id] + * The content of g_modeMethod has a hash mapping relationship with CRYPT_MODE_AlgId. Change the value accordingly. +*/ +static const EAL_CipherMethod *g_modeMethod[CRYPT_MODE_MAX] = { +#ifdef HITLS_CRYPTO_CBC + &CBC_METHOD, +#else + NULL, +#endif +#ifdef HITLS_CRYPTO_CTR + &CTR_METHOD, +#else + NULL, +#endif + NULL, + NULL, +#ifdef HITLS_CRYPTO_CCM + &CCM_METHOD, +#else + NULL, +#endif +#ifdef HITLS_CRYPTO_GCM + &GCM_METHOD, +#else + NULL, +#endif +#ifdef HITLS_CRYPTO_CHACHA20POLY1305 + &CHACHA20_POLY1305_METHOD, +#else + NULL, +#endif +#ifdef HITLS_CRYPTO_CFB + &CFB_METHOD, +#else + NULL, +#endif +#ifdef HITLS_CRYPTO_OFB + &OFB_METHOD +#else + NULL +#endif +}; + +const EAL_CipherMethod *EAL_FindSymMethod(CRYPT_SYM_AlgId id) +{ + if (id < 0 || id >= CRYPT_SYM_MAX) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return NULL; + } + return g_symMethod[id]; +} + +const EAL_CipherMethod *EAL_FindModeMethod(CRYPT_MODE_AlgId id) +{ + if (id < 0 || id >= CRYPT_MODE_MAX) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return NULL; + } + return g_modeMethod[id]; +} + +static const EAL_SymAlgMap SYM_ID_MAP[] = { +#ifdef HITLS_CRYPTO_AES + {.id = CRYPT_CIPHER_AES128_CBC, .modeId = CRYPT_MODE_CBC, .symId = CRYPT_SYM_AES128 }, + {.id = CRYPT_CIPHER_AES192_CBC, .modeId = CRYPT_MODE_CBC, .symId = CRYPT_SYM_AES192 }, + {.id = CRYPT_CIPHER_AES256_CBC, .modeId = CRYPT_MODE_CBC, .symId = CRYPT_SYM_AES256 }, + {.id = CRYPT_CIPHER_AES128_CTR, .modeId = CRYPT_MODE_CTR, .symId = CRYPT_SYM_AES128 }, + {.id = CRYPT_CIPHER_AES192_CTR, .modeId = CRYPT_MODE_CTR, .symId = CRYPT_SYM_AES192 }, + {.id = CRYPT_CIPHER_AES256_CTR, .modeId = CRYPT_MODE_CTR, .symId = CRYPT_SYM_AES256 }, + {.id = CRYPT_CIPHER_AES128_CCM, .modeId = CRYPT_MODE_CCM, .symId = CRYPT_SYM_AES128 }, + {.id = CRYPT_CIPHER_AES192_CCM, .modeId = CRYPT_MODE_CCM, .symId = CRYPT_SYM_AES192 }, + {.id = CRYPT_CIPHER_AES256_CCM, .modeId = CRYPT_MODE_CCM, .symId = CRYPT_SYM_AES256 }, + {.id = CRYPT_CIPHER_AES128_GCM, .modeId = CRYPT_MODE_GCM, .symId = CRYPT_SYM_AES128 }, + {.id = CRYPT_CIPHER_AES192_GCM, .modeId = CRYPT_MODE_GCM, .symId = CRYPT_SYM_AES192 }, + {.id = CRYPT_CIPHER_AES256_GCM, .modeId = CRYPT_MODE_GCM, .symId = CRYPT_SYM_AES256 }, + {.id = CRYPT_CIPHER_AES128_CFB, .modeId = CRYPT_MODE_CFB, .symId = CRYPT_SYM_AES128 }, + {.id = CRYPT_CIPHER_AES192_CFB, .modeId = CRYPT_MODE_CFB, .symId = CRYPT_SYM_AES192 }, + {.id = CRYPT_CIPHER_AES256_CFB, .modeId = CRYPT_MODE_CFB, .symId = CRYPT_SYM_AES256 }, + {.id = CRYPT_CIPHER_AES128_OFB, .modeId = CRYPT_MODE_OFB, .symId = CRYPT_SYM_AES128 }, + {.id = CRYPT_CIPHER_AES192_OFB, .modeId = CRYPT_MODE_OFB, .symId = CRYPT_SYM_AES192 }, + {.id = CRYPT_CIPHER_AES256_OFB, .modeId = CRYPT_MODE_OFB, .symId = CRYPT_SYM_AES256 }, +#endif +#ifdef HITLS_CRYPTO_CHACHA20 + {.id = CRYPT_CIPHER_CHACHA20_POLY1305, .modeId = CRYPT_MODE_CHACHA20_POLY1305, .symId = CRYPT_SYM_CHACHA20 }, +#endif +#ifdef HITLS_CRYPTO_SM4 + {.id = CRYPT_CIPHER_SM4_XTS, .modeId = CRYPT_MODE_XTS, .symId = CRYPT_SYM_SM4 }, + {.id = CRYPT_CIPHER_SM4_CBC, .modeId = CRYPT_MODE_CBC, .symId = CRYPT_SYM_SM4 }, + {.id = CRYPT_CIPHER_SM4_CTR, .modeId = CRYPT_MODE_CTR, .symId = CRYPT_SYM_SM4 }, + {.id = CRYPT_CIPHER_SM4_GCM, .modeId = CRYPT_MODE_GCM, .symId = CRYPT_SYM_SM4 }, + {.id = CRYPT_CIPHER_SM4_CFB, .modeId = CRYPT_MODE_CFB, .symId = CRYPT_SYM_SM4 }, + {.id = CRYPT_CIPHER_SM4_OFB, .modeId = CRYPT_MODE_OFB, .symId = CRYPT_SYM_SM4 }, +#endif +}; + +/** + * Search mode + algorithm + * symMap[id] + * It has hash mapping relationship between the input ID and g_ealCipherMethod and CRYPT_CIPHER_AlgId. + * The corresponding information must be synchronized in the symMap. + * The symMap content .modeId and .symId are dependent on the CRYPT_SYM_AlgId and CRYPT_MODE_AlgId. + * The corresponding information must be synchronized. + */ +static int32_t FindCipher(CRYPT_CIPHER_AlgId id, EAL_Cipher *m) +{ + uint32_t num = sizeof(SYM_ID_MAP) / sizeof(SYM_ID_MAP[0]); + const EAL_SymAlgMap *symAlgMap = NULL; + + for (uint32_t i = 0; i < num; i++) { + if (SYM_ID_MAP[i].id == id) { + symAlgMap = &SYM_ID_MAP[i]; + break; + } + } + + if (symAlgMap == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + m->modeMethod = EAL_FindModeMethod(symAlgMap->modeId); + if (m->modeMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + m->ciphMeth = EAL_FindSymMethod(symAlgMap->symId); + if (m->ciphMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + return CRYPT_SUCCESS; +} + +static CRYPT_CipherInfo g_cipherInfo[] = { +#ifdef HITLS_CRYPTO_AES + {.id = CRYPT_CIPHER_AES128_CBC, .blockSize = 16, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES192_CBC, .blockSize = 16, .keyLen = 24, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES256_CBC, .blockSize = 16, .keyLen = 32, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES128_CTR, .blockSize = 1, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES192_CTR, .blockSize = 1, .keyLen = 24, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES256_CTR, .blockSize = 1, .keyLen = 32, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES128_CCM, .blockSize = 1, .keyLen = 16, .ivLen = 12}, + {.id = CRYPT_CIPHER_AES192_CCM, .blockSize = 1, .keyLen = 24, .ivLen = 12}, + {.id = CRYPT_CIPHER_AES256_CCM, .blockSize = 1, .keyLen = 32, .ivLen = 12}, + {.id = CRYPT_CIPHER_AES128_GCM, .blockSize = 1, .keyLen = 16, .ivLen = 12}, + {.id = CRYPT_CIPHER_AES192_GCM, .blockSize = 1, .keyLen = 24, .ivLen = 12}, + {.id = CRYPT_CIPHER_AES256_GCM, .blockSize = 1, .keyLen = 32, .ivLen = 12}, + {.id = CRYPT_CIPHER_AES128_CFB, .blockSize = 1, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES192_CFB, .blockSize = 1, .keyLen = 24, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES256_CFB, .blockSize = 1, .keyLen = 32, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES128_OFB, .blockSize = 1, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES192_OFB, .blockSize = 1, .keyLen = 24, .ivLen = 16}, + {.id = CRYPT_CIPHER_AES256_OFB, .blockSize = 1, .keyLen = 32, .ivLen = 16}, +#endif +#ifdef HITLS_CRYPTO_CHACHA20 + {.id = CRYPT_CIPHER_CHACHA20_POLY1305, .blockSize = 1, .keyLen = 32, .ivLen = 12}, +#endif +#ifdef HITLS_CRYPTO_SM4 + {.id = CRYPT_CIPHER_SM4_XTS, .blockSize = 1, .keyLen = 32, .ivLen = 16}, + {.id = CRYPT_CIPHER_SM4_CBC, .blockSize = 16, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_SM4_CTR, .blockSize = 1, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_SM4_GCM, .blockSize = 1, .keyLen = 16, .ivLen = 12}, + {.id = CRYPT_CIPHER_SM4_CFB, .blockSize = 1, .keyLen = 16, .ivLen = 16}, + {.id = CRYPT_CIPHER_SM4_OFB, .blockSize = 1, .keyLen = 16, .ivLen = 16}, +#endif +}; + +/** + * Search for the lengths of the block, key, and IV of algorithm. If ID in g_cipherInfo is changed, + * synchronize the value of the SDV_CRYPTO_CIPHER_FUN_TC008 test case. + * The input ID has a mapping relationship with g_ealCipherMethod and CRYPT_CIPHER_AlgId. + * The corresponding information must be synchronized to symMap. + * The symMap and CRYPT_SYM_AlgId, CRYPT_MODE_AlgId depend on each other. Synchronize the corresponding information. + */ +int32_t EAL_GetCipherInfo(CRYPT_CIPHER_AlgId id, CRYPT_CipherInfo *info) +{ + uint32_t num = sizeof(g_cipherInfo) / sizeof(g_cipherInfo[0]); + const CRYPT_CipherInfo *cipherInfoGet = NULL; + + for (uint32_t i = 0; i < num; i++) { + if (g_cipherInfo[i].id == id) { + cipherInfoGet = &g_cipherInfo[i]; + break; + } + } + + if (cipherInfoGet == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + + info->blockSize = cipherInfoGet->blockSize; + info->ivLen = cipherInfoGet->ivLen; + info->keyLen = cipherInfoGet->keyLen; + return CRYPT_SUCCESS; +} + +int32_t EAL_FindCipher(CRYPT_CIPHER_AlgId id, EAL_Cipher *m) +{ + uint32_t num = sizeof(EAL_CIPHER_METHOD_ASM) / sizeof(EAL_CIPHER_METHOD_ASM[0]); + const EAL_SymAlgMapAsm *symAlgMapAsm = NULL; + + for (uint32_t i = 0; i < num; i++) { + if (EAL_CIPHER_METHOD_ASM[i].id == id) { + symAlgMapAsm = &EAL_CIPHER_METHOD_ASM[i]; + break; + } + } + + if (symAlgMapAsm == NULL || symAlgMapAsm->symMeth == NULL) { + return FindCipher(id, m); + } + + m->modeMethod = symAlgMapAsm->symMeth->modeMethod; + m->ciphMeth = symAlgMapAsm->symMeth->ciphMeth; + return CRYPT_SUCCESS; +} +#endif diff --git a/crypto/eal/src/eal_common.c b/crypto/eal/src/eal_common.c new file mode 100644 index 00000000..9ef02e07 --- /dev/null +++ b/crypto/eal/src/eal_common.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) + +#include +#include "crypt_types.h" +#include "crypt_eal_md.h" +#include "crypt_eal_mac.h" +#include "crypt_method.h" +#include "eal_cipher_local.h" +#include "eal_pkey_local.h" +#include "eal_md_local.h" +#include "eal_mac_local.h" +#include "bsl_err_internal.h" +#include "eal_common.h" + +EventReport g_eventReportFunc = NULL; +void CRYPT_EAL_RegEventReport(EventReport func) +{ + g_eventReportFunc = func; +} + +void EAL_EventReport(CRYPT_EVENT_TYPE oper, CRYPT_ALGO_TYPE type, int32_t id, int32_t err) +{ + if (g_eventReportFunc == NULL) { + return; + } + g_eventReportFunc(oper, type, id, err); +} +#endif diff --git a/crypto/eal/src/eal_common.h b/crypto/eal/src/eal_common.h new file mode 100644 index 00000000..4972b746 --- /dev/null +++ b/crypto/eal/src/eal_common.h @@ -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 EAL_COMMON_H +#define EAL_COMMON_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) + +#include +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define EAL_ERR_REPORT(oper, type, id, err) \ + do { \ + EAL_EventReport((oper), (type), (id), (err)); \ + BSL_ERR_PUSH_ERROR((err)); \ + } while (0) + +void EAL_EventReport(CRYPT_EVENT_TYPE oper, CRYPT_ALGO_TYPE type, int32_t id, int32_t err); + + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_EAL + +#endif // EAL_COMMON_H diff --git a/crypto/eal/src/eal_drbg_local.h b/crypto/eal/src/eal_drbg_local.h new file mode 100644 index 00000000..1ece5d6b --- /dev/null +++ b/crypto/eal/src/eal_drbg_local.h @@ -0,0 +1,95 @@ +/* + * 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 EAL_DRBG_LOCAL_H +#define EAL_DRBG_LOCAL_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_DRBG) + +#include +#include "bsl_sal.h" + +#include "crypt_eal_rand.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef union { + uintptr_t ptr; +} CRYPT_RndParam; + +typedef struct { + /** + * @brief Memory application and initialization of DRBG context. If it is not registered, the input ctx is null. + */ + void* (*newCtx)(CRYPT_RndParam *param); + /** + * @brief Free the DRBG context memory. If it is not registered, this interface is not invoked in the deinit. + */ + void (*freeCtx)(void *ctx); + /** + * @brief Generate random numbers.This hook must be implemented otherwise it will fail at initialization. + * (The internal initialization is specified by default.) + */ + int32_t (*rand)(void *ctx, uint8_t *bytes, uint32_t len, const uint8_t *addin, uint32_t adinLen); + /** + * @brief DRBG seed interface. If it is not registered internally, the seed and seedwithAdin directly fail, + * but the DRBG generation is not affected because it's specified by default during internal initialization. + */ + int32_t (*seed)(void *ctx, const uint8_t *addin, uint32_t adinLen); +} EalRndMeth; + +struct EAL_RndCtx { + CRYPT_RAND_AlgId id; + EalRndMeth meth; + void *ctx; + bool working; // whether the system is in the working state + BSL_SAL_ThreadLockHandle lock; // thread lock +}; + +/** + * @brief Set the method for global random number + * + * @param meth meth method + * @return Success: CRYPT_SUCCESS + * For other error codes, see crypt_errno.h. + */ +int32_t EAL_RandSetMeth(EalRndMeth *meth, CRYPT_EAL_RndCtx *ctx); + +/** + * @brief Global DRBG initialization. After initialization is complete, + * call CRYPT_RAND_Deinit before initialization is performed again. + * + * @return Success: CRYPT_SUCCESS + * For other error codes, see crypt_errno.h. + */ +int32_t EAL_RandInit(CRYPT_RndParam *param, CRYPT_EAL_RndCtx *ctx); + +/** + * @brief Global random deinitialization + * + * @param ctx handle of ctx + */ +void CRYPT_RandDeinit(CRYPT_EAL_RndCtx *ctx); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_DRBG + +#endif // EAL_DRBG_LOCAL_H diff --git a/crypto/eal/src/eal_entropy.c b/crypto/eal/src/eal_entropy.c new file mode 100644 index 00000000..edcd75ca --- /dev/null +++ b/crypto/eal/src/eal_entropy.c @@ -0,0 +1,108 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_ENTROPY) + +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "entropy.h" +#include "eal_entropy.h" + +#define DEV_RAND_MIN_ENTROPY 7.0 + +static uint32_t GetEntropyInputLen(uint32_t strength, CRYPT_Range *lenRange) +{ + // Calculate the required length based on the strength and the average entropy. + double cSize = (double)strength / DEV_RAND_MIN_ENTROPY; + uint32_t len = (uint32_t)cSize; + if (cSize > (double)len) { // Ensure that the decimal carries 1. + len++; + } + // '<' indicates that the data with a length of len can provide sufficient bit entropy. + if (len < lenRange->min) { + len = lenRange->min; + } + return len; +} + +static int32_t GetEntropy(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + bool needFullEntropy = (lenRange->max == lenRange->min) ? true : false; + uint32_t len = (needFullEntropy) ? lenRange->min : GetEntropyInputLen(strength, lenRange); + // '>' indicates that data with a length of lenRange->max cannot provide sufficient bit entropy. + // Only data with a length of len can provide sufficient bit entropy. + if (len > lenRange->max) { + BSL_ERR_PUSH_ERROR(CRYPT_ENTROPY_RANGE_ERROR); + return CRYPT_ENTROPY_RANGE_ERROR; + } + uint8_t *data = (uint8_t *)BSL_SAL_Malloc(len); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret; + if (needFullEntropy) { + ret = ENTROPY_GetFullEntropyInput(ctx, data, len); + } else { + ret = ENTROPY_GetRandom(data, len); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(data); + return ret; + } + entropy->data = data; + entropy->len = len; + return CRYPT_SUCCESS; +} + +static void CleanEntropy(void *ctx, CRYPT_Data *entropy) +{ + (void)ctx; + BSL_SAL_CleanseData(entropy->data, entropy->len); + BSL_SAL_FREE(entropy->data); +} + +static int32_t GetNonce(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange) +{ + return GetEntropy(ctx, nonce, strength, lenRange); +} + +static void CleanNonce(void *ctx, CRYPT_Data *nonce) +{ + CleanEntropy(ctx, nonce); +} + +int32_t EAL_SetDefaultEntropyMeth(CRYPT_RandSeedMethod *meth, void **seedCtx) +{ + if (meth == NULL || seedCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + *seedCtx = ENTROPY_GetCtx(EAL_EntropyGetECF(CRYPT_MAC_HMAC_SHA256), CRYPT_MAC_HMAC_SHA224); + if (*seedCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + meth->getEntropy = GetEntropy; + meth->cleanEntropy = CleanEntropy; + meth->cleanNonce = CleanNonce; + meth->getNonce = GetNonce; + return CRYPT_SUCCESS; +} + +#endif diff --git a/crypto/eal/src/eal_entropy.h b/crypto/eal/src/eal_entropy.h new file mode 100644 index 00000000..701128fa --- /dev/null +++ b/crypto/eal/src/eal_entropy.h @@ -0,0 +1,51 @@ +/* + * 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 EAL_ENTROPY_H +#define EAL_ENTROPY_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_ENTROPY) + +#include "crypt_types.h" +#include "entropy.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief Set the random number method that uses the default system entropy source. + * + * @param meth meth method + * @param seedCtx Handle of seedCtx + * @return Success: CRYPT_SUCCESS + */ +int32_t EAL_SetDefaultEntropyMeth(CRYPT_RandSeedMethod *meth, void **seedCtx); + +/** + * @brief Obtain the conditioning function of the corresponding algorithm. + * + * @param algId algId + * @return ExternalConditioningFunction + */ +ExternalConditioningFunction EAL_EntropyGetECF(uint32_t algId); +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_ENTROPY + +#endif // EAL_ENTROPY_H diff --git a/crypto/eal/src/eal_entropy_ecf.c b/crypto/eal/src/eal_entropy_ecf.c new file mode 100644 index 00000000..ada1972e --- /dev/null +++ b/crypto/eal/src/eal_entropy_ecf.c @@ -0,0 +1,81 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_ENTROPY) + +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "eal_entropy.h" +#include "entropy.h" +#include "crypt_eal_mac.h" +#include "crypt_eal_md.h" +#include "securec.h" + +#define ECF_ALG_KEY_LEN_128 16 + +#ifdef HITLS_CRYPTO_MAC +static int32_t ECFMac(uint32_t algId, uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ENTROPY_CONDITION_FAILURE); + return CRYPT_ENTROPY_CONDITION_FAILURE; + } + uint32_t keyLen = ECF_ALG_KEY_LEN_128; + uint8_t *ecfKey = (uint8_t *)BSL_SAL_Malloc(keyLen); + if (ecfKey == NULL) { + CRYPT_EAL_MacFreeCtx(ctx); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + /* reference nist-800 90c-3pd section 3.3.1.1 + * Unlike other cryptographic applications, keys used in these external conditioning functions do not require + * secrecy to accomplish their purpose so may be hard-coded, fixed, or all zeros. + */ + (void)memset_s(ecfKey, keyLen, 0, keyLen); + int32_t ret = CRYPT_EAL_MacInit(ctx, ecfKey, keyLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MacFreeCtx(ctx); + BSL_SAL_FREE(ecfKey); + return ret; + } + ret = CRYPT_EAL_MacUpdate(ctx, in, inLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MacFreeCtx(ctx); + BSL_SAL_FREE(ecfKey); + return ret; + } + ret = CRYPT_EAL_MacFinal(ctx, out, outLen); + CRYPT_EAL_MacFreeCtx(ctx); + BSL_SAL_FREE(ecfKey); + if (ret != CRYPT_SUCCESS) { + return ret; + } + return CRYPT_SUCCESS; +} +#endif + +ExternalConditioningFunction EAL_EntropyGetECF(uint32_t algId) +{ + (void)algId; +#ifdef HITLS_CRYPTO_MAC + return ECFMac; +#else + return NULL; +#endif +} +#endif diff --git a/crypto/eal/src/eal_kdf.c b/crypto/eal/src/eal_kdf.c new file mode 100644 index 00000000..74103516 --- /dev/null +++ b/crypto/eal/src/eal_kdf.c @@ -0,0 +1,351 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_KDF) + +#include +#include "crypt_eal_kdf.h" +#include "securec.h" +#include "bsl_err_internal.h" +#include "crypt_local_types.h" +#include "crypt_eal_mac.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "eal_mac_local.h" +#ifdef HITLS_CRYPTO_HMAC +#include "crypt_hmac.h" +#endif +#ifdef HITLS_CRYPTO_PBKDF2 +#include "crypt_pbkdf2.h" +#endif +#ifdef HITLS_CRYPTO_HKDF +#include "crypt_hkdf.h" +#endif +#ifdef HITLS_CRYPTO_KDFTLS12 +#include "crypt_kdf_tls12.h" +#endif +#ifdef HITLS_CRYPTO_SCRYPT +#include "crypt_scrypt.h" +#endif +#include "eal_common.h" +#include "crypt_utils.h" +#include "crypt_ealinit.h" + +#ifdef HITLS_CRYPTO_PBKDF2 +static const uint32_t PBKDF_ID_LIST[] = { + CRYPT_MAC_HMAC_MD5, + CRYPT_MAC_HMAC_SHA1, + CRYPT_MAC_HMAC_SHA224, + CRYPT_MAC_HMAC_SHA256, + CRYPT_MAC_HMAC_SHA384, + CRYPT_MAC_HMAC_SHA512, + CRYPT_MAC_HMAC_SM3, + CRYPT_MAC_HMAC_SHA3_224, + CRYPT_MAC_HMAC_SHA3_256, + CRYPT_MAC_HMAC_SHA3_384, + CRYPT_MAC_HMAC_SHA3_512, +}; +#endif + +#ifdef HITLS_CRYPTO_HKDF +static const uint32_t HKDF_ID_LIST[] = { + CRYPT_MAC_HMAC_MD5, + CRYPT_MAC_HMAC_SHA1, + CRYPT_MAC_HMAC_SHA224, + CRYPT_MAC_HMAC_SHA256, + CRYPT_MAC_HMAC_SHA384, + CRYPT_MAC_HMAC_SHA512, +}; +#endif + +#ifdef HITLS_CRYPTO_KDFTLS12 +static const uint32_t KDFTLS12_ID_LIST[] = { + CRYPT_MAC_HMAC_SHA256, + CRYPT_MAC_HMAC_SHA384, + CRYPT_MAC_HMAC_SHA512, +}; +#endif + +bool CRYPT_EAL_HkdfIsValidAlgId(CRYPT_MAC_AlgId id) +{ +#ifdef HITLS_CRYPTO_HKDF + return ParamIdIsValid(id, HKDF_ID_LIST, sizeof(HKDF_ID_LIST) / sizeof(HKDF_ID_LIST[0])); +#else + (void)id; + return false; +#endif +} + +bool CRYPT_EAL_Pbkdf2IsValidAlgId(CRYPT_MAC_AlgId id) +{ +#ifdef HITLS_CRYPTO_PBKDF2 + return ParamIdIsValid(id, PBKDF_ID_LIST, sizeof(PBKDF_ID_LIST) / sizeof(PBKDF_ID_LIST[0])); +#else + (void)id; + return false; +#endif +} + +bool CRYPT_EAL_Kdftls12IsValidAlgId(CRYPT_MAC_AlgId id) +{ +#ifdef HITLS_CRYPTO_KDFTLS12 + return ParamIdIsValid(id, KDFTLS12_ID_LIST, sizeof(KDFTLS12_ID_LIST) / sizeof(KDFTLS12_ID_LIST[0])); +#else + (void)id; + return false; +#endif +} + +int32_t CRYPT_EAL_Pbkdf2(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *salt, + uint32_t saltLen, uint32_t it, uint8_t *out, uint32_t len) +{ +#ifdef HITLS_CRYPTO_PBKDF2 +#ifdef HITLS_CRYPTO_ASM_CHECK + if (CRYPT_ASMCAP_Mac(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + if (!ParamIdIsValid(id, PBKDF_ID_LIST, sizeof(PBKDF_ID_LIST) / sizeof(PBKDF_ID_LIST[0]))) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_PBKDF2, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + /* According to GM/T 0091-2020, the salt length of pbkdf2-hmac-sm3 cannot be less than 64 bits (8 bytes) + and the number of iterations cannot be less than 1024. */ + if (id == CRYPT_MAC_HMAC_SM3 && (saltLen < 8 || it < 1024)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_PBKDF2, CRYPT_PBKDF2_PARAM_ERROR); + return CRYPT_PBKDF2_PARAM_ERROR; + } + + EAL_MacMethLookup method; + int32_t ret = EAL_MacFindMethod(id, &method); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + ret = CRYPT_PBKDF2_HMAC(method.macMethod, method.md, key, keyLen, salt, saltLen, it, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_PBKDF2, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_KEYDERIVE, CRYPT_ALGO_KDF, CRYPT_KDF_PBKDF2, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +#else + (void)id; + (void)key; + (void)keyLen; + (void)salt; + (void)saltLen; + (void)it; + (void)out; + (void)len; + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_PBKDF2, CRYPT_PBKDF2_NOT_SUPPORTED); + return CRYPT_PBKDF2_NOT_SUPPORTED; +#endif +} + +int32_t CRYPT_EAL_HkdfExtract(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, uint8_t *out, uint32_t *len) +{ +#ifdef HITLS_CRYPTO_HKDF + if (!ParamIdIsValid(id, HKDF_ID_LIST, sizeof(HKDF_ID_LIST) / sizeof(HKDF_ID_LIST[0]))) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + EAL_MacMethLookup method; + if (EAL_MacFindMethod(id, &method) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + int ret = CRYPT_HKDF_Extract(method.macMethod, method.md, key, keyLen, salt, saltLen, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_KEYDERIVE, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +#else + (void)id; + (void)key; + (void)keyLen; + (void)salt; + (void)saltLen; + (void)out; + (void)len; + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_HKDF_NOT_SUPPORTED); + return CRYPT_HKDF_NOT_SUPPORTED; +#endif +} + +int32_t CRYPT_EAL_HkdfExpand(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, + const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len) +{ +#ifdef HITLS_CRYPTO_HKDF + EAL_MacMethLookup method; + if (!ParamIdIsValid(id, HKDF_ID_LIST, sizeof(HKDF_ID_LIST) / sizeof(HKDF_ID_LIST[0]))) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + int32_t ret = EAL_MacFindMethod(id, &method); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + ret = CRYPT_HKDF_Expand(method.macMethod, method.md, key, keyLen, info, infoLen, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_KEYDERIVE, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +#else + (void)id; + (void)key; + (void)keyLen; + (void)info; + (void)infoLen; + (void)out; + (void)len; + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_HKDF_NOT_SUPPORTED); + return CRYPT_HKDF_NOT_SUPPORTED; +#endif +} + +int32_t CRYPT_EAL_Hkdf(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, + const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len) +{ +#ifdef HITLS_CRYPTO_HKDF +#ifdef HITLS_CRYPTO_ASM_CHECK + if (CRYPT_ASMCAP_Mac(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + if (!ParamIdIsValid(id, HKDF_ID_LIST, sizeof(HKDF_ID_LIST) / sizeof(HKDF_ID_LIST[0]))) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + EAL_MacMethLookup method; + int32_t ret = EAL_MacFindMethod(id, &method); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + ret = CRYPT_HKDF(method.macMethod, method.md, key, keyLen, salt, saltLen, info, infoLen, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_KEYDERIVE, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +#else + (void)id; + (void)key; + (void)keyLen; + (void)info; + (void)infoLen; + (void)salt; + (void)saltLen; + (void)out; + (void)len; + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_HKDF, CRYPT_HKDF_NOT_SUPPORTED); + return CRYPT_HKDF_NOT_SUPPORTED; +#endif +} + +int32_t CRYPT_EAL_KdfTls12(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *label, + uint32_t labelLen, const uint8_t *seed, uint32_t seedLen, uint8_t *out, uint32_t len) +{ +#ifdef HITLS_CRYPTO_KDFTLS12 +#ifdef HITLS_CRYPTO_ASM_CHECK + if (CRYPT_ASMCAP_Mac(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + // For KDF-TLS1.2, only HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 can be used. + if (!ParamIdIsValid(id, KDFTLS12_ID_LIST, sizeof(KDFTLS12_ID_LIST) / sizeof(KDFTLS12_ID_LIST[0]))) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_KDFTLS12, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + int32_t ret; + EAL_MacMethLookup method; + ret = EAL_MacFindMethod(id, &method); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + ret = CRYPT_KDF_TLS12(method.macMethod, method.md, key, keyLen, label, labelLen, seed, seedLen, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_KDFTLS12, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_KEYDERIVE, CRYPT_ALGO_KDF, CRYPT_KDF_KDFTLS12, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +#else + (void)id; + (void)key; + (void)keyLen; + (void)label; + (void)labelLen; + (void)seed; + (void)seedLen; + (void)out; + (void)len; + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_KDFTLS12, CRYPT_KDFTLS12_NOT_SUPPORTED); + return CRYPT_KDFTLS12_NOT_SUPPORTED; +#endif +} + +int32_t CRYPT_EAL_Scrypt(const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint32_t n, + uint32_t r, uint32_t p, uint8_t *out, uint32_t len) +{ +#ifdef HITLS_CRYPTO_SCRYPT + EAL_MacMethLookup method; + int32_t ret = EAL_MacFindMethod(CRYPT_MAC_HMAC_SHA256, &method); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + ret = CRYPT_SCRYPT(CRYPT_PBKDF2_HMAC, method.macMethod, method.md, key, keyLen, salt, saltLen, n, r, p, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_SCRYPT, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_KEYDERIVE, CRYPT_ALGO_KDF, CRYPT_KDF_SCRYPT, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +#else + (void)key; + (void)keyLen; + (void)salt; + (void)saltLen; + (void)n; + (void)r; + (void)p; + (void)out; + (void)len; + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_KDF, CRYPT_KDF_SCRYPT, CRYPT_SCRYPT_NOT_SUPPORTED); + return CRYPT_SCRYPT_NOT_SUPPORTED; +#endif +} +#endif diff --git a/crypto/eal/src/eal_mac.c b/crypto/eal/src/eal_mac.c new file mode 100644 index 00000000..7c6a5839 --- /dev/null +++ b/crypto/eal/src/eal_mac.c @@ -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" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_MAC) + +#include +#include +#include "crypt_eal_mac.h" +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_local_types.h" +#include "crypt_eal_mac.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_ealinit.h" +#include "eal_mac_local.h" +#include "eal_common.h" + +#define NOT_CHECK_PARAM 0xff +#define MAC_TYPE_INVALID 0 + +CRYPT_EAL_MacCtx *MacNewDefaultCtx(CRYPT_MAC_AlgId id) +{ + int32_t ret; + EAL_MacMethLookup method; + ret = EAL_MacFindMethod(id, &method); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_EAL_ERR_ALGID); + return NULL; + } + + CRYPT_EAL_MacCtx *macCtx = NULL; + + macCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MacCtx) + method.macMethod->ctxSize); + if (macCtx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + macCtx->id = id; + macCtx->state = CRYPT_MAC_STATE_NEW; + macCtx->macMeth = method.macMethod; + macCtx->ctx = (void *)(macCtx + 1); + + ret = method.macMethod->initCtx(macCtx->ctx, method.depMeth); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, ret); + BSL_SAL_FREE(macCtx); + return NULL; + } + + return macCtx; +} + +CRYPT_EAL_MacCtx *CRYPT_EAL_MacNewCtx(CRYPT_MAC_AlgId id) +{ +#if defined(HITLS_CRYPTO_ASM_CHECK) + if (CRYPT_ASMCAP_Mac(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return NULL; + } +#endif + return MacNewDefaultCtx(id); +} + +void CRYPT_EAL_MacFreeCtx(CRYPT_EAL_MacCtx *ctx) +{ + if (ctx == NULL) { + return; + } + + if (ctx->masMeth == NULL) { + BSL_SAL_FREE(ctx); + return; + } + + EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_MAC, ctx->id, CRYPT_SUCCESS); + + if (ctx->macMeth == NULL || ctx->macMeth->deinitCtx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + BSL_SAL_FREE(ctx); + return; + } + ctx->macMeth->deinitCtx(ctx->ctx); + + BSL_SAL_FREE(ctx); + return; +} + +int32_t CRYPT_EAL_MacInit(CRYPT_EAL_MacCtx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->masMeth == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret = CRYPT_EAL_ALG_NOT_SUPPORT; + + if (ctx->macMeth == NULL || ctx->macMeth->init == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + ret = ctx->macMeth->init(ctx->ctx, key, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_MAC, ctx->id, ret); + ctx->state = CRYPT_MAC_STATE_INIT; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_MacUpdate(CRYPT_EAL_MacCtx *ctx, const uint8_t *in, uint32_t len) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->masMeth == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if ((ctx->state == CRYPT_MAC_STATE_FINAL) || (ctx->state == CRYPT_MAC_STATE_NEW)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + + int32_t ret = CRYPT_EAL_ALG_NOT_SUPPORT; + + if (ctx->macMeth == NULL || ctx->macMeth->update == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + ret = ctx->macMeth->update(ctx->ctx, in, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, ret); + return ret; + } + ctx->state = CRYPT_MAC_STATE_UPDATE; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_MacFinal(CRYPT_EAL_MacCtx *ctx, uint8_t *out, uint32_t *len) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->masMeth == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if ((ctx->state == CRYPT_MAC_STATE_NEW) || (ctx->state == CRYPT_MAC_STATE_FINAL)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + + int32_t ret = CRYPT_EAL_ALG_NOT_SUPPORT; + + if (ctx->macMeth == NULL || ctx->macMeth->final == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + ret = ctx->macMeth->final(ctx->ctx, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, ret); + return ret; + } + ctx->state = CRYPT_MAC_STATE_FINAL; + EAL_EventReport(CRYPT_EVENT_MAC, CRYPT_ALGO_MAC, ctx->id, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +} + +void CRYPT_EAL_MacDeinit(CRYPT_EAL_MacCtx *ctx) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT); + return; + } + if (ctx->masMeth == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT); + return; + } + + if (ctx->macMeth == NULL || ctx->macMeth->deinit == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return; + } + ctx->macMeth->deinit(ctx->ctx); + + ctx->state = CRYPT_MAC_STATE_NEW; +} + +int32_t CRYPT_EAL_MacReinit(CRYPT_EAL_MacCtx *ctx) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->masMeth == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->state == CRYPT_MAC_STATE_NEW) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + + if (ctx->macMeth == NULL || ctx->macMeth->reinit == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ctx->macMeth->reinit(ctx->ctx); + ctx->state = CRYPT_MAC_STATE_INIT; + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_EAL_GetMacLen(const CRYPT_EAL_MacCtx *ctx) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT); + return 0; + } + if (ctx->masMeth == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT); + return 0; + } + + if (ctx->macMeth == NULL || ctx->macMeth->getLen == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return 0; + } + return ctx->macMeth->getLen(ctx->ctx); +} + +bool CRYPT_EAL_MacIsValidAlgId(CRYPT_MAC_AlgId id) +{ + EAL_MacMethLookup method; + return EAL_MacFindMethod(id, &method) == CRYPT_SUCCESS; +} +#endif diff --git a/crypto/eal/src/eal_mac_local.h b/crypto/eal/src/eal_mac_local.h new file mode 100644 index 00000000..c288d5e2 --- /dev/null +++ b/crypto/eal/src/eal_mac_local.h @@ -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 EAL_MAC_LOCAL_H +#define EAL_MAC_LOCAL_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_MAC) + +#include +#include "crypt_algid.h" +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum { + CRYPT_MAC_STATE_NEW = 0, + CRYPT_MAC_STATE_INIT, + CRYPT_MAC_STATE_UPDATE, + CRYPT_MAC_STATE_FINAL +} CRYPT_MAC_WORKSTATE; + +typedef enum { + CRYPT_MAC_HMAC = 0, + CRYPT_MAC_INVALID +} CRYPT_MAC_ID; + +struct EAL_MacCtx { + union { + const EAL_MacMethod *macMeth; // combined algorithm + const EAL_CipherMethod *modeMeth; + const void *masMeth; + }; + void *ctx; // MAC context + CRYPT_MAC_AlgId id; + CRYPT_MAC_WORKSTATE state; +}; + +typedef struct { + uint32_t id; + CRYPT_MAC_ID macId; + union { + CRYPT_MD_AlgId mdId; + CRYPT_SYM_AlgId symId; + }; +} EAL_MacAlgMap; + +int32_t EAL_MacFindMethod(CRYPT_MAC_AlgId id, EAL_MacMethLookup *lu); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_MAC + +#endif // EAL_MAC_LOCAL_H diff --git a/crypto/eal/src/eal_mac_method.c b/crypto/eal/src/eal_mac_method.c new file mode 100644 index 00000000..645c7848 --- /dev/null +++ b/crypto/eal/src/eal_mac_method.c @@ -0,0 +1,121 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_MAC) + +#include +#include "securec.h" +#include "crypt_local_types.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "eal_mac_local.h" +#include "eal_cipher_local.h" +#include "eal_md_local.h" +#ifdef HITLS_CRYPTO_HMAC +#include "crypt_hmac.h" +#endif +#include "bsl_err_internal.h" +#include "eal_common.h" + +#define CRYPT_MAC_IMPL_METHOD_DECLARE(name) \ + EAL_MacMethod g_macMethod_##name = { \ + (MacInitCtx)CRYPT_##name##_InitCtx, (MacInit)CRYPT_##name##_Init, \ + (MacUpdate)CRYPT_##name##_Update, (MacFinal)CRYPT_##name##_Final, \ + (MacDeinit)CRYPT_##name##_Deinit, (MacDeinitCtx)CRYPT_##name##_DeinitCtx, \ + (MacReinit)CRYPT_##name##_Reinit, (MacGetMacLen)CRYPT_##name##_GetMacLen, \ + sizeof(CRYPT_##name##_Ctx) \ + } + +#ifdef HITLS_CRYPTO_HMAC +CRYPT_MAC_IMPL_METHOD_DECLARE(HMAC); +#endif + +static const EAL_MacMethod *g_macMethods[] = { +#ifdef HITLS_CRYPTO_HMAC + &g_macMethod_HMAC, // HMAC +#else + NULL, +#endif + NULL, + NULL, +}; + +static const EAL_MacAlgMap CID_MAC_ALG_MAP[] = { +#ifdef HITLS_CRYPTO_HMAC + {.id = CRYPT_MAC_HMAC_MD5, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_MD5}, + {.id = CRYPT_MAC_HMAC_SHA1, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA1}, + {.id = CRYPT_MAC_HMAC_SHA224, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA224}, + {.id = CRYPT_MAC_HMAC_SHA256, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA256}, + {.id = CRYPT_MAC_HMAC_SHA384, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA384}, + {.id = CRYPT_MAC_HMAC_SHA512, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA512}, + {.id = CRYPT_MAC_HMAC_SHA3_224, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA3_224}, + {.id = CRYPT_MAC_HMAC_SHA3_256, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA3_256}, + {.id = CRYPT_MAC_HMAC_SHA3_384, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA3_384}, + {.id = CRYPT_MAC_HMAC_SHA3_512, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SHA3_512}, + {.id = CRYPT_MAC_HMAC_SM3, .macId = CRYPT_MAC_HMAC, .mdId = CRYPT_MD_SM3}, +#endif +}; + +static const EAL_MacAlgMap *EAL_FindMacAlgMap(CRYPT_MAC_AlgId id) +{ + uint32_t num = sizeof(CID_MAC_ALG_MAP) / sizeof(CID_MAC_ALG_MAP[0]); + const EAL_MacAlgMap *macAlgMap = NULL; + + for (uint32_t i = 0; i < num; i++) { + if (CID_MAC_ALG_MAP[i].id == id) { + macAlgMap = &CID_MAC_ALG_MAP[i]; + break; + } + } + return macAlgMap; +} + +int32_t EAL_MacFindMethod(CRYPT_MAC_AlgId id, EAL_MacMethLookup *lu) +{ + if (lu == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + const EAL_MacAlgMap *macAlgMap = EAL_FindMacAlgMap(id); + if (macAlgMap == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + CRYPT_MAC_ID macId = macAlgMap->macId; + switch (macId) { +#ifdef HITLS_CRYPTO_MD + case CRYPT_MAC_HMAC: + lu->macMethod = g_macMethods[macId]; + // Obtain the ID of the combined algorithm from the map and search for the method based on the ID. + lu->md = EAL_MdFindMethod(macAlgMap->mdId); + break; +#endif + default: + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + if (lu->masMeth == NULL || lu->depMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + return CRYPT_SUCCESS; +} +#endif diff --git a/crypto/eal/src/eal_md.c b/crypto/eal/src/eal_md.c new file mode 100644 index 00000000..506fd8c4 --- /dev/null +++ b/crypto/eal/src/eal_md.c @@ -0,0 +1,303 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_MD) + +#include +#include +#include "crypt_eal_md.h" +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_local_types.h" +#include "crypt_eal_md.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "eal_md_local.h" +#include "eal_common.h" +#include "crypt_ealinit.h" + +static CRYPT_EAL_MdCTX *MdAllocCtx(CRYPT_MD_AlgId id, const EAL_MdMethod *method) +{ + CRYPT_EAL_MdCTX *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX)); + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + void *data = BSL_SAL_Calloc(1u, method->ctxSize); + if (data == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_MEM_ALLOC_FAIL); + BSL_SAL_FREE(ctx); + return NULL; + } + ctx->data = data; + return ctx; +} + +static CRYPT_EAL_MdCTX *MdNewDefaultCtx(CRYPT_MD_AlgId id) +{ + const EAL_MdMethod *method = EAL_MdFindMethod(id); + if (method == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_EAL_ERR_ALGID); + return NULL; + } + + CRYPT_EAL_MdCTX *ctx = MdAllocCtx(id, method); + if (ctx == NULL) { + return NULL; + } + + ctx->id = id; + ctx->state = CRYPT_MD_STATE_NEW; + ctx->method = method; + return ctx; +} + +CRYPT_EAL_MdCTX *CRYPT_EAL_MdNewCtx(CRYPT_MD_AlgId id) +{ +#ifdef HITLS_CRYPTO_ASM_CHECK + if (CRYPT_ASMCAP_Md(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return NULL; + } +#endif + return MdNewDefaultCtx(id); +} + +bool CRYPT_EAL_MdIsValidAlgId(CRYPT_MD_AlgId id) +{ + return EAL_MdFindMethod(id) != NULL; +} + +CRYPT_MD_AlgId CRYPT_EAL_MdGetId(CRYPT_EAL_MdCTX *ctx) +{ + if (ctx == NULL) { + return CRYPT_MD_MAX; + } + return ctx->id; +} + +static void EalMdCopyCtx(CRYPT_EAL_MdCTX *to, const CRYPT_EAL_MdCTX *from) +{ + void *tmpData = to->data; + (void)memcpy_s(to, sizeof(CRYPT_EAL_MdCTX), from, sizeof(CRYPT_EAL_MdCTX)); + to->data = tmpData; + (void)memcpy_s(to->data, from->method->ctxSize, from->data, from->method->ctxSize); +} + +int32_t CRYPT_EAL_MdCopyCtx(CRYPT_EAL_MdCTX *to, const CRYPT_EAL_MdCTX *from) +{ + if (to == NULL || from == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (to->data != NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + if (from->method == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + void *data = BSL_SAL_Calloc(1u, from->method->ctxSize); + if (data == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, from->id, CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + to->data = data; + + EalMdCopyCtx(to, from); + return CRYPT_SUCCESS; +} + +CRYPT_EAL_MdCTX *CRYPT_EAL_MdDupCtx(const CRYPT_EAL_MdCTX *ctx) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return NULL; + } + if (ctx->method == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_NULL_INPUT); + return NULL; + } + CRYPT_EAL_MdCTX *newCtx = MdAllocCtx(ctx->id, ctx->method); + if (newCtx == NULL) { + return NULL; + } + EalMdCopyCtx(newCtx, ctx); + return newCtx; +} + +void CRYPT_EAL_MdFreeCtx(CRYPT_EAL_MdCTX *ctx) +{ + if (ctx == NULL) { + return; + } + EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_MD, ctx->id, CRYPT_SUCCESS); + ctx->method->deinit(ctx->data); + BSL_SAL_FREE(ctx->data); + BSL_SAL_FREE(ctx); + return; +} + +int32_t CRYPT_EAL_MdInit(CRYPT_EAL_MdCTX *ctx) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->method == NULL || ctx->method->init == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + int32_t ret = ctx->method->init(ctx->data); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret); + return ret; + } + ctx->state = CRYPT_MD_STATE_INIT; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_MdUpdate(CRYPT_EAL_MdCTX *ctx, const uint8_t *data, uint32_t len) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->method == NULL || ctx->method->update == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + if ((ctx->state == CRYPT_MD_STATE_FINAL) || (ctx->state == CRYPT_MD_STATE_NEW)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + + int32_t ret = ctx->method->update(ctx->data, data, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret); + return ret; + } + ctx->state = CRYPT_MD_STATE_UPDATE; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_MdFinal(CRYPT_EAL_MdCTX *ctx, uint8_t *out, uint32_t *len) +{ + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->method == NULL || ctx->method->final == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + if ((ctx->state == CRYPT_MD_STATE_NEW) || (ctx->state == CRYPT_MD_STATE_FINAL)) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ERR_STATE); + return CRYPT_EAL_ERR_STATE; + } + + // The validity of the buffer length that carries the output result (len > ctx->method->mdSize) + // is determined by the algorithm bottom layer and is not verified here. + int32_t ret = ctx->method->final(ctx->data, out, len); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret); + return ret; + } + ctx->state = CRYPT_MD_STATE_FINAL; + EAL_EventReport(CRYPT_EVENT_MD, CRYPT_ALGO_MD, ctx->id, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_EAL_MdDeinit(CRYPT_EAL_MdCTX *ctx) +{ + if (ctx == NULL || ctx->method == NULL || ctx->method->deinit == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + ctx->method->deinit(ctx->data); + ctx->state = CRYPT_MD_STATE_NEW; + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_EAL_MdGetDigestSize(CRYPT_MD_AlgId id) +{ + const EAL_MdMethod *method = EAL_MdFindMethod(id); + if (method == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_EAL_ERR_ALGID); + return 0; + } + + return method->mdSize; +} + +int32_t CRYPT_EAL_Md(CRYPT_MD_AlgId id, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + if (out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (in == NULL && inLen != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + const EAL_MdMethod *method = EAL_MdFindMethod(id); + if (method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + void *data = BSL_SAL_Malloc(method->ctxSize); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)memset_s(data, method->ctxSize, 0, method->ctxSize); + + ret = method->init(data); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(data); + return ret; + } + if (inLen != 0) { + ret = method->update(data, in, inLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } + + ret = method->final(data, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + *outLen = method->mdSize; + +ERR: + method->deinit(data); + BSL_SAL_FREE(data); + return ret; +} +#endif diff --git a/crypto/eal/src/eal_md_local.h b/crypto/eal/src/eal_md_local.h new file mode 100644 index 00000000..a9b3d51b --- /dev/null +++ b/crypto/eal/src/eal_md_local.h @@ -0,0 +1,61 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef EAL_MD_LOCAL_H +#define EAL_MD_LOCAL_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_MD) + +#include +#include "crypt_algid.h" +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum { + CRYPT_MD_STATE_NEW = 0, + CRYPT_MD_STATE_INIT, + CRYPT_MD_STATE_UPDATE, + CRYPT_MD_STATE_FINAL +} CRYPT_MD_WORKSTATE; + +struct EAL_MdCtx { + const EAL_MdMethod *method; /* algorithm operation entity */ + void *data; /* Algorithm ctx, mainly context */ + uint32_t state; + CRYPT_MD_AlgId id; +}; + +/** + * @ingroup eal + * @brief Method for generating the hash algorithm + * + * @param id [IN] Algorithm ID + * + * @return Pointer to CRYPT_MD_Method + * For other error codes, see crypt_errno.h. + */ +const EAL_MdMethod *EAL_MdFindMethod(CRYPT_MD_AlgId id); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_MD + +#endif // EAL_MD_LOCAL_H diff --git a/crypto/eal/src/eal_md_method.c b/crypto/eal/src/eal_md_method.c new file mode 100644 index 00000000..5bc705d3 --- /dev/null +++ b/crypto/eal/src/eal_md_method.c @@ -0,0 +1,126 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_MD) + +#include "crypt_local_types.h" +#include "crypt_algid.h" +#ifdef HITLS_CRYPTO_SHA2 +#include "crypt_sha2.h" +#endif +#ifdef HITLS_CRYPTO_SHA1 +#include "crypt_sha1.h" +#endif +#ifdef HITLS_CRYPTO_SM3 +#include "crypt_sm3.h" +#endif +#ifdef HITLS_CRYPTO_SHA3 +#include "crypt_sha3.h" +#endif +#ifdef HITLS_CRYPTO_MD5 +#include "crypt_md5.h" +#endif +#include "bsl_err_internal.h" +#include "eal_common.h" +#include "bsl_sal.h" + +#define CRYPT_MD_IMPL_METHOD_DECLARE(name) \ + EAL_MdMethod g_mdMethod_##name = { \ + CRYPT_##name##_BLOCKSIZE, CRYPT_##name##_DIGESTSIZE, \ + sizeof(CRYPT_##name##_Ctx), (MdInit)CRYPT_##name##_Init, \ + (MdUpdate)CRYPT_##name##_Update, (MdFinal)CRYPT_##name##_Final, \ + (MdDeinit)CRYPT_##name##_Deinit, (MdCopyCtx)CRYPT_##name##_CopyCtx \ + } + +#ifdef HITLS_CRYPTO_MD5 +CRYPT_MD_IMPL_METHOD_DECLARE(MD5); +#endif +#ifdef HITLS_CRYPTO_SHA1 +CRYPT_MD_IMPL_METHOD_DECLARE(SHA1); +#endif +#ifdef HITLS_CRYPTO_SHA224 +CRYPT_MD_IMPL_METHOD_DECLARE(SHA2_224); +#endif +#ifdef HITLS_CRYPTO_SHA256 +CRYPT_MD_IMPL_METHOD_DECLARE(SHA2_256); +#endif +#ifdef HITLS_CRYPTO_SHA384 +CRYPT_MD_IMPL_METHOD_DECLARE(SHA2_384); +#endif +#ifdef HITLS_CRYPTO_SHA512 +CRYPT_MD_IMPL_METHOD_DECLARE(SHA2_512); +#endif +#ifdef HITLS_CRYPTO_SHA3 +CRYPT_MD_IMPL_METHOD_DECLARE(SHA3_224); +CRYPT_MD_IMPL_METHOD_DECLARE(SHA3_256); +CRYPT_MD_IMPL_METHOD_DECLARE(SHA3_384); +CRYPT_MD_IMPL_METHOD_DECLARE(SHA3_512); +CRYPT_MD_IMPL_METHOD_DECLARE(SHAKE128); +CRYPT_MD_IMPL_METHOD_DECLARE(SHAKE256); +#endif +#ifdef HITLS_CRYPTO_SM3 +CRYPT_MD_IMPL_METHOD_DECLARE(SM3); +#endif + +static const EAL_CidToMdMeth ID_TO_MD_METH_TABLE[] = { + {CRYPT_MD_MD4, NULL}, +#ifdef HITLS_CRYPTO_MD5 + {CRYPT_MD_MD5, &g_mdMethod_MD5}, +#endif +#ifdef HITLS_CRYPTO_SHA1 + {CRYPT_MD_SHA1, &g_mdMethod_SHA1}, +#endif +#ifdef HITLS_CRYPTO_SHA224 + {CRYPT_MD_SHA224, &g_mdMethod_SHA2_224}, +#endif +#ifdef HITLS_CRYPTO_SHA256 + {CRYPT_MD_SHA256, &g_mdMethod_SHA2_256}, +#endif +#ifdef HITLS_CRYPTO_SHA384 + {CRYPT_MD_SHA384, &g_mdMethod_SHA2_384}, +#endif +#ifdef HITLS_CRYPTO_SHA512 + {CRYPT_MD_SHA512, &g_mdMethod_SHA2_512}, +#endif +#ifdef HITLS_CRYPTO_SHA3 + {CRYPT_MD_SHA3_224, &g_mdMethod_SHA3_224}, + {CRYPT_MD_SHA3_256, &g_mdMethod_SHA3_256}, + {CRYPT_MD_SHA3_384, &g_mdMethod_SHA3_384}, + {CRYPT_MD_SHA3_512, &g_mdMethod_SHA3_512}, + {CRYPT_MD_SHAKE128, &g_mdMethod_SHAKE128}, + {CRYPT_MD_SHAKE256, &g_mdMethod_SHAKE256}, +#endif +#ifdef HITLS_CRYPTO_SM3 + {CRYPT_MD_SM3, &g_mdMethod_SM3}, // SM3 +#endif + {CRYPT_MD_MAX, NULL} +}; + +const EAL_MdMethod *EAL_MdFindMethod(CRYPT_MD_AlgId id) +{ + EAL_MdMethod *pMdMeth = NULL; + uint32_t num = sizeof(ID_TO_MD_METH_TABLE) / sizeof(ID_TO_MD_METH_TABLE[0]); + + for (uint32_t i = 0; i < num; i++) { + if (ID_TO_MD_METH_TABLE[i].id == id) { + pMdMeth = ID_TO_MD_METH_TABLE[i].mdMeth; + return pMdMeth; + } + } + + return NULL; +} +#endif diff --git a/crypto/eal/src/eal_pkey_computesharekey.c b/crypto/eal/src/eal_pkey_computesharekey.c new file mode 100644 index 00000000..069cfe18 --- /dev/null +++ b/crypto/eal/src/eal_pkey_computesharekey.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_PKEY) + +#include +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "bsl_err_internal.h" +#include "eal_pkey_local.h" +#include "crypt_eal_pkey.h" +#include "eal_common.h" + +int32_t CRYPT_EAL_PkeyComputeShareKey(const CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyCtx *pubKey, + uint8_t *share, uint32_t *shareLen) +{ + if (pkey == NULL || pubKey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->id != pubKey->id) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + if (pkey->method == NULL || pkey->method->computeShareKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + int32_t ret = pkey->method->computeShareKey(pkey->key, pubKey->key, share, shareLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + EAL_EventReport(CRYPT_EVENT_KEYAGGREMENT, CRYPT_ALGO_PKEY, pkey->id, CRYPT_SUCCESS); + return ret; +} +#endif diff --git a/crypto/eal/src/eal_pkey_crypt.c b/crypto/eal/src/eal_pkey_crypt.c new file mode 100644 index 00000000..af5b3d00 --- /dev/null +++ b/crypto/eal/src/eal_pkey_crypt.c @@ -0,0 +1,131 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_PKEY) + +#include +#include +#include "bsl_sal.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "eal_pkey_local.h" +#include "crypt_algid.h" +#include "bsl_err_internal.h" +#include "eal_common.h" + +int32_t CRYPT_EAL_PkeyEncrypt(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->encrypt == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + return pkey->method->encrypt(pkey->key, data, dataLen, out, outLen); +} + +int32_t CRYPT_EAL_PkeyDecrypt(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->decrypt == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + return pkey->method->decrypt(pkey->key, data, dataLen, out, outLen); +} + +static int32_t CryptRsaEmsaPairSet(CRYPT_EAL_PkeyCtx *pubKey, CRYPT_EAL_PkeyCtx *prvKey, CRYPT_MD_AlgId hashId) +{ + CRYPT_RSA_PkcsV15Para pkcsv15 = {hashId}; + int32_t ret = CRYPT_EAL_PkeyCtrl(pubKey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, sizeof(CRYPT_RSA_PkcsV15Para)); + if (ret != CRYPT_SUCCESS) { + return ret; + } + return CRYPT_EAL_PkeyCtrl(prvKey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, sizeof(CRYPT_RSA_PkcsV15Para)); +} + +int32_t CRYPT_EAL_PkeyPairCheck(CRYPT_EAL_PkeyCtx *pubKey, CRYPT_EAL_PkeyCtx *prvKey) +{ + if ((pubKey == NULL) || (prvKey == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret = CRYPT_SUCCESS; + uint8_t *signedData = NULL; + CRYPT_EAL_PkeyCtx *tempPubKey = CRYPT_EAL_PkeyDupCtx(pubKey); + CRYPT_EAL_PkeyCtx *tempPrivKey = CRYPT_EAL_PkeyDupCtx(prvKey); + if (tempPubKey == NULL || tempPrivKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + CRYPT_MD_AlgId hashId; + CRYPT_PKEY_AlgId algId = CRYPT_EAL_PkeyGetId(tempPubKey); + switch (algId) { + case CRYPT_PKEY_DSA: + case CRYPT_PKEY_ED25519: + case CRYPT_PKEY_ECDSA: + /* RFC8032 5.1.6: ECDSA supports only sha512 as the hash algorithm for signatures. + * Other signature algorithms support sha512. Therefore, sha512 is always used here. */ + hashId = CRYPT_MD_SHA512; + break; + case CRYPT_PKEY_RSA: + hashId = CRYPT_MD_SHA512; + ret = CryptRsaEmsaPairSet(tempPubKey, tempPrivKey, hashId); + break; + case CRYPT_PKEY_SM2: + hashId = CRYPT_MD_SM3; + break; + default: + ret = CRYPT_NOT_SUPPORT; + break; + } + + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + uint8_t toBeSig[] = {1}; + uint32_t signedLen = CRYPT_EAL_PkeyGetSignLen(tempPrivKey); + if (signedLen == 0) { + ret = CRYPT_ECC_PKEY_ERR_SIGN_LEN; + goto ERR; + } + signedData = BSL_SAL_Malloc(signedLen); + if (signedData == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + ret = CRYPT_EAL_PkeySign(tempPrivKey, hashId, toBeSig, sizeof(toBeSig), signedData, &signedLen); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + ret = CRYPT_EAL_PkeyVerify(tempPubKey, hashId, toBeSig, sizeof(toBeSig), signedData, signedLen); +ERR: + BSL_SAL_FREE(signedData); + CRYPT_EAL_PkeyFreeCtx(tempPubKey); + CRYPT_EAL_PkeyFreeCtx(tempPrivKey); + return ret; +} +#endif diff --git a/crypto/eal/src/eal_pkey_gen.c b/crypto/eal/src/eal_pkey_gen.c new file mode 100644 index 00000000..0b31c069 --- /dev/null +++ b/crypto/eal/src/eal_pkey_gen.c @@ -0,0 +1,653 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_PKEY) + +#include +#include +#include "securec.h" +#include "eal_pkey_local.h" +#include "crypt_eal_pkey.h" +#include "crypt_method.h" +#include "crypt_errno.h" +#include "crypt_algid.h" +#include "crypt_local_types.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "eal_md_local.h" +#include "eal_common.h" +#include "crypt_method.h" + +typedef struct { + CRYPT_PKEY_AlgId pkeyId; + CRYPT_PkeyCtrl ctrOpt; + CRYPT_MD_AlgId mdId; +} PkeyNewOpt; + +static const PkeyNewOpt NEW_OPT[] = { + {CRYPT_PKEY_SM2, CRYPT_CTRL_SET_SM2_HASH_METHOD, CRYPT_MD_SM3}, + {CRYPT_PKEY_ED25519, CRYPT_CTRL_SET_ED25519_HASH_METHOD, CRYPT_MD_SHA512} +}; + +static const PkeyNewOpt *PkeyGetOpt(CRYPT_PKEY_AlgId id) +{ + const uint32_t cnt = sizeof(NEW_OPT) / sizeof(PkeyNewOpt); + for (uint32_t i = 0; i < cnt; i++) { + if (id == NEW_OPT[i].pkeyId) { + return &(NEW_OPT[i]); + } + } + return NULL; +} + +CRYPT_EAL_PkeyCtx *PkeyNewDefaultCtx(CRYPT_PKEY_AlgId id) +{ + /* Obtain the method based on the algorithm ID. */ + const EAL_PkeyMethod *method = CRYPT_EAL_PkeyFindMethod(id); + if (method == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, id, CRYPT_EAL_ERR_ALGID); + return NULL; + } + + /* Resource application and initialization */ + CRYPT_EAL_PkeyCtx *pkey = BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_PkeyCtx)); + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, id, CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + const PkeyNewOpt *opt = PkeyGetOpt(id); + pkey->key = method->newCtx(); + if (pkey->key == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, id, CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + pkey->method = method; + pkey->id = id; + BSL_SAL_ReferencesInit(&(pkey->references)); + if (opt != NULL) { + // The algorithm needs to register the specified hash method for calculation. + const EAL_MdMethod *mdMethod = EAL_MdFindMethod(opt->mdId); + if (mdMethod == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, id, CRYPT_EAL_ALG_NOT_SUPPORT); + goto ERR; + } + int32_t ret = pkey->method->ctrl(pkey->key, opt->ctrOpt, + (EAL_MdMethod *)(uintptr_t)mdMethod, sizeof(EAL_MdMethod)); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, id, ret); + goto ERR; + } + } + return pkey; +ERR: + CRYPT_EAL_PkeyFreeCtx(pkey); + return NULL; +} + +CRYPT_EAL_PkeyCtx *CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_AlgId id) +{ + return PkeyNewDefaultCtx(id); +} + +static int32_t PkeyCopyCtx(CRYPT_EAL_PkeyCtx *to, const CRYPT_EAL_PkeyCtx *from) +{ + if (from->method->dupCtx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, from->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + (void)memcpy_s(to, sizeof(CRYPT_EAL_PkeyCtx), from, sizeof(CRYPT_EAL_PkeyCtx)); + to->key = from->method->dupCtx(from->key); + if (to->key == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, from->id, CRYPT_EAL_PKEY_DUP_ERROR); + return CRYPT_EAL_PKEY_DUP_ERROR; + } + BSL_SAL_ReferencesInit(&(to->references)); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_PkeyCopyCtx(CRYPT_EAL_PkeyCtx *to, const CRYPT_EAL_PkeyCtx *from) +{ + if (to == NULL || from == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (to->key != NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + return PkeyCopyCtx(to, from); +} + +CRYPT_EAL_PkeyCtx *CRYPT_EAL_PkeyDupCtx(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return NULL; + } + + CRYPT_EAL_PkeyCtx *newPkey = BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_PkeyCtx)); + if (newPkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + if (PkeyCopyCtx(newPkey, pkey) != CRYPT_SUCCESS) { + BSL_SAL_FREE(newPkey); + return NULL; + } + return newPkey; +} + +void CRYPT_EAL_PkeyFreeCtx(CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + return; + } + int ref = 0; + BSL_SAL_AtomicDownReferences(&(pkey->references), &ref); + if (ref > 0) { + return; + } + BSL_SAL_ReferencesFree(&(pkey->references)); + if (pkey->method != NULL) { + if (pkey->method->freeCtx != NULL) { + pkey->method->freeCtx(pkey->key); + } + } + EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_PKEY, pkey->id, CRYPT_SUCCESS); + BSL_SAL_FREE(pkey); + return; +} + +static int32_t ParaIsVaild(const CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPara *para) +{ + bool isInputValid = (pkey == NULL) || (para == NULL); + if (isInputValid) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (pkey->id != para->id) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_PkeySetPara(CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPara *para) +{ + int32_t ret; + ret = ParaIsVaild(pkey, para); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return ret; + } + + if (pkey->method == NULL || pkey->method->newPara == NULL || + pkey->method->setPara == NULL || pkey->method->freePara == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + void *pkeyPara = pkey->method->newPara(&(para->para.dsaPara)); + if (pkeyPara == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ERR_NEW_PARA_FAIL); + return CRYPT_EAL_ERR_NEW_PARA_FAIL; + } + ret = pkey->method->setPara(pkey->key, pkeyPara); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + } + pkey->method->freePara(pkeyPara); + return ret; +} + +int32_t CRYPT_EAL_PkeyGetPara(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_PkeyPara *para) +{ + int32_t ret; + ret = ParaIsVaild(pkey, para); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return ret; + } + + if (pkey->method == NULL || pkey->method->getPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = pkey->method->getPara(pkey->key, &(para->para.dsaPara)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_EAL_PkeySetParaById(CRYPT_EAL_PkeyCtx *pkey, CRYPT_PKEY_ParaId id) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->newParaById == NULL || + pkey->method->setPara == NULL || pkey->method->freePara == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + void *pkeyPara = pkey->method->newParaById(id); + if (pkeyPara == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ERR_NEW_PARA_FAIL); + return CRYPT_EAL_ERR_NEW_PARA_FAIL; + } + int32_t ret = pkey->method->setPara(pkey->key, pkeyPara); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + } + pkey->method->freePara(pkeyPara); + return ret; +} + +int32_t CRYPT_EAL_PkeyGen(CRYPT_EAL_PkeyCtx *pkey) +{ + int32_t ret; + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->gen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + // If it's the ED25519 algorithm, hash method needs to be registered. + if (pkey->id == CRYPT_PKEY_ED25519) { + const EAL_MdMethod *mdMethod = EAL_MdFindMethod(CRYPT_MD_SHA512); + if (pkey->method->ctrl == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = pkey->method->ctrl(pkey->key, CRYPT_CTRL_SET_ED25519_HASH_METHOD, (EAL_MdMethod *)(uintptr_t)mdMethod, + sizeof(EAL_MdMethod)); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; + } + } + /* Invoke the algorithm entity to generate a key pair. */ + ret = pkey->method->gen(pkey->key); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; + } + + EAL_EventReport(CRYPT_EVENT_GEN, CRYPT_ALGO_PKEY, pkey->id, CRYPT_SUCCESS); + return CRYPT_SUCCESS; +} + +static int32_t PriAndPubParamIsValid(const CRYPT_EAL_PkeyCtx *pkey, const void *key, bool isPriKey) +{ + bool isInputValid = (pkey == NULL) || (key == NULL); + if (isInputValid) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + // false indicates the public key path, and true indicates the private key path + if (isPriKey == false) { + CRYPT_EAL_PkeyPub *keyParam = (CRYPT_EAL_PkeyPub *)(uintptr_t)key; + if (keyParam->id != pkey->id) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + } else { + CRYPT_EAL_PkeyPrv *keyParam = (CRYPT_EAL_PkeyPrv *)(uintptr_t)key; + if (keyParam->id != pkey->id) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_PkeySetPub(CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPub *key) +{ + int32_t ret = PriAndPubParamIsValid(pkey, key, false); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, (pkey == NULL) ? CRYPT_PKEY_MAX : pkey->id, ret); + return ret; + } + if (pkey->method == NULL || pkey->method->setPub == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = pkey->method->setPub(pkey->key, &(key->key.rsaPub)); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_SETSSP : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +int32_t CRYPT_EAL_PkeySetPrv(CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPrv *key) +{ + int32_t ret = PriAndPubParamIsValid(pkey, key, true); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, (pkey == NULL) ? CRYPT_PKEY_MAX : pkey->id, ret); + return ret; + } + if (pkey->method == NULL || pkey->method->setPrv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = pkey->method->setPrv(pkey->key, &(key->key.rsaPrv)); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_SETSSP : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +int32_t CRYPT_EAL_PkeyGetPub(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_PkeyPub *key) +{ + int32_t ret = PriAndPubParamIsValid(pkey, key, false); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, (pkey == NULL) ? CRYPT_PKEY_MAX : pkey->id, ret); + return ret; + } + if (pkey->method == NULL || pkey->method->getPub == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = pkey->method->getPub(pkey->key, &(key->key.rsaPub)); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_GETSSP : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +int32_t CRYPT_EAL_PkeyGetPrv(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_PkeyPrv *key) +{ + int32_t ret = PriAndPubParamIsValid(pkey, key, true); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, (pkey == NULL) ? CRYPT_PKEY_MAX : pkey->id, ret); + return ret; + } + if (pkey->method == NULL || pkey->method->getPrv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + ret = pkey->method->getPrv(pkey->key, &(key->key.rsaPrv)); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_GETSSP : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +uint32_t CRYPT_EAL_PkeyGetSignLen(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return 0; + } + if (pkey->method == NULL || pkey->method->signLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return 0; + } + return pkey->method->signLen(pkey->key); +} + +uint32_t CRYPT_EAL_PkeyGetKeyLen(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return 0; + } + if (pkey->method == NULL || pkey->method->bits == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return 0; + } + uint32_t keyBytes = (pkey->method->bits(pkey->key) + 7) >> 3; // bytes = (bits + 7) >> 3 + return keyBytes; +} + +static int32_t MdIdCheckSha1Sha2(CRYPT_MD_AlgId id) +{ + if (id < CRYPT_MD_MD5 || id > CRYPT_MD_SHA512) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_EAL_PkeyGetKeyBits(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return 0; + } + if (pkey->method == NULL || pkey->method->bits == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return 0; + } + return pkey->method->bits(pkey->key); +} + +uint32_t CRYPT_EAL_PkeyGetSecurityBits(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return 0; + } + if (pkey->method == NULL || pkey->method->getSecBits == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT); + return 0; + } + + return (uint32_t) pkey->method->getSecBits(pkey->key); +} + +static int32_t SetOaep(CRYPT_EAL_PkeyCtx *pkey, const void *val, uint32_t len) +{ + RSA_PadingPara padPara; + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + const CRYPT_RSA_OaepPara *opad = val; + if (len != sizeof(CRYPT_RSA_OaepPara)) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_PKEY_CTRL_ERROR); + return CRYPT_EAL_PKEY_CTRL_ERROR; + } + int32_t ret = MdIdCheckSha1Sha2(opad->mdId); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = MdIdCheckSha1Sha2(opad->mgfId); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + padPara.mdId = opad->mdId; + padPara.mgfId = opad->mgfId; + padPara.mdMeth = EAL_MdFindMethod(opad->mdId); + padPara.mgfMeth = EAL_MdFindMethod(opad->mgfId); + if (padPara.mdMeth == NULL || padPara.mgfMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + return pkey->method->ctrl(pkey->key, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &padPara, + sizeof(RSA_PadingPara)); +} + +static int32_t SetPss(CRYPT_EAL_PkeyCtx *pkey, void *val, uint32_t len) +{ + RSA_PadingPara padPara; + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + CRYPT_RSA_PssPara *pad = val; + if (len != sizeof(CRYPT_RSA_PssPara)) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_PKEY_CTRL_ERROR); + return CRYPT_EAL_PKEY_CTRL_ERROR; + } + int32_t ret = MdIdCheckSha1Sha2(pad->mdId); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = MdIdCheckSha1Sha2(pad->mgfId); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + padPara.saltLen = pad->saltLen; + padPara.mdId = pad->mdId; + padPara.mgfId = pad->mgfId; + padPara.mdMeth = EAL_MdFindMethod(pad->mdId); + padPara.mgfMeth = EAL_MdFindMethod(pad->mgfId); + if (padPara.mdMeth == NULL || padPara.mgfMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + return pkey->method->ctrl(pkey->key, CRYPT_CTRL_SET_RSA_EMSA_PSS, &padPara, + sizeof(RSA_PadingPara)); +} + +int32_t CRYPT_EAL_PkeyCtrl(CRYPT_EAL_PkeyCtx *pkey, int32_t opt, void *val, uint32_t len) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->ctrl == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + if (opt == CRYPT_CTRL_SET_ED25519_HASH_METHOD || opt == CRYPT_CTRL_SET_SM9_HASH_METHOD + || opt == CRYPT_CTRL_SET_SM2_HASH_METHOD) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + int32_t ret; + switch (opt) { + case CRYPT_CTRL_SET_RSA_EMSA_PSS: + ret = SetPss(pkey, val, len); + break; + case CRYPT_CTRL_SET_RSA_RSAES_OAEP: + ret = SetOaep(pkey, val, len); + break; + default: + ret = pkey->method->ctrl(pkey->key, opt, val, len); + break; + } + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + } + return ret; +} + +CRYPT_PKEY_AlgId CRYPT_EAL_PkeyGetId(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + return CRYPT_PKEY_MAX; + } + return pkey->id; +} + +CRYPT_PKEY_ParaId CRYPT_EAL_PkeyGetParaId(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + return CRYPT_PKEY_PARAID_MAX; + } + if (pkey->method == NULL || pkey->method->getParaId == NULL) { + return CRYPT_PKEY_PARAID_MAX; + } + return pkey->method->getParaId(pkey->key); +} + +int32_t CRYPT_EAL_PkeyCheck(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (pkey->method == NULL || pkey->method->check == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + return pkey->method->check(pkey->key); +} + +int32_t CRYPT_EAL_PkeyCmp(const CRYPT_EAL_PkeyCtx *a, const CRYPT_EAL_PkeyCtx *b) +{ + if (a == NULL || b == NULL) { + if (a == b) { + return CRYPT_SUCCESS; + } + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (a->id != b->id) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE); + return CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE; + } + if (a->method == NULL || b->method == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (a->method->id != b->method->id) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE); + return CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE; + } + if (a->method->cmp == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, a->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + return a->method->cmp(a->key, b->key); +} + +// Set the user's personal data. The life cycle is processed by the user. The value of data can be NULL, +// which is used to release the personal data and is set NULL. +int32_t CRYPT_EAL_PkeySetExtData(CRYPT_EAL_PkeyCtx *pkey, void *data) +{ + if (pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + pkey->extData = data; + return CRYPT_SUCCESS; +} + +// Obtain user's personal data. +void *CRYPT_EAL_PkeyGetExtData(const CRYPT_EAL_PkeyCtx *pkey) +{ + if (pkey == NULL) { + return NULL; + } + return pkey->extData; +} + +bool CRYPT_EAL_PkeyIsValidAlgId(CRYPT_PKEY_AlgId id) +{ + return CRYPT_EAL_PkeyFindMethod(id) != NULL; +} + +int32_t CRYPT_EAL_PkeyUpRef(CRYPT_EAL_PkeyCtx *pkey) +{ + int i = 0; + if (pkey == NULL) { + return CRYPT_NULL_INPUT; + } + return BSL_SAL_AtomicUpReferences(&(pkey->references), &i); +} +#endif diff --git a/crypto/eal/src/eal_pkey_local.h b/crypto/eal/src/eal_pkey_local.h new file mode 100644 index 00000000..37ee442e --- /dev/null +++ b/crypto/eal/src/eal_pkey_local.h @@ -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. + */ + +#ifndef EAL_PKEY_LOCAL_H +#define EAL_PKEY_LOCAL_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_PKEY) + +#include +#include "crypt_algid.h" +#include "crypt_local_types.h" +#include "crypt_eal_pkey.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** +* @ingroup EAL +* +* Pkey session structure +*/ +struct EAL_PkeyCtx { + const EAL_PkeyMethod *method; + void *key; + void *extData; + CRYPT_PKEY_AlgId id; + BSL_SAL_RefCount references; +}; + +/** + * @ingroup crypt_method + * @brief Generate the default method of the signature algorithm. + * + * @param id [IN] Algorithm ID. + * + * @return success: Pointer to EAL_PkeyMethod + * For other error codes, see crypt_errno.h. + */ +const EAL_PkeyMethod *CRYPT_EAL_PkeyFindMethod(CRYPT_PKEY_AlgId id); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_PKEY + +#endif // EAL_PKEY_LOCAL_H diff --git a/crypto/eal/src/eal_pkey_method.c b/crypto/eal/src/eal_pkey_method.c new file mode 100644 index 00000000..bc98fdcd --- /dev/null +++ b/crypto/eal/src/eal_pkey_method.c @@ -0,0 +1,368 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_PKEY) + +#include "securec.h" +#include "crypt_method.h" +#include "crypt_local_types.h" +#include "crypt_algid.h" +#include "eal_pkey_local.h" +#ifdef HITLS_CRYPTO_RSA +#include "crypt_rsa.h" +#endif +#ifdef HITLS_CRYPTO_DSA +#include "crypt_dsa.h" +#endif +#ifdef HITLS_CRYPTO_CURVE25519 +#include "crypt_curve25519.h" +#endif +#ifdef HITLS_CRYPTO_DH +#include "crypt_dh.h" +#endif +#ifdef HITLS_CRYPTO_ECDH +#include "crypt_ecdh.h" +#endif +#ifdef HITLS_CRYPTO_ECDSA +#include "crypt_ecdsa.h" +#endif +#ifdef HITLS_CRYPTO_SM2 +#include "crypt_sm2.h" +#endif +#ifdef HITLS_CRYPTO_PAILLIER +#include "crypt_paillier.h" +#endif +#include "bsl_err_internal.h" +#include "crypt_types.h" +#include "eal_common.h" +#include "bsl_sal.h" + +#define EAL_PKEY_METHOD_DEFINE(id, newCtx, dupCtx, freeCtx, setPara, getPara, gen, bits, signLen, ctrl, newParaById, \ + getParaId, freePara, newPara, setPub, setPrv, getPub, getPrv, sign, verify, computeShareKey, encrypt, \ + decrypt, check, cmp, getSecBits) { \ + id, (PkeyNew)(newCtx), (PkeyDup)(dupCtx), (PkeyFree)(freeCtx), (PkeySetPara)(setPara), (PkeyGetPara)(getPara), \ + (PkeyGen)(gen), (PkeyBits)(bits), (PkeyGetSignLen)(signLen), (PkeyCtrl)(ctrl), (PkeyNewParaById)(newParaById), \ + (PkeyGetParaId)(getParaId), (PkeyFreePara)(freePara), (PkeyNewPara)(newPara), (PkeySetPub)(setPub), \ + (PkeySetPrv)(setPrv), (PkeyGetPub)(getPub), (PkeyGetPrv)(getPrv), (PkeySign)(sign), \ + (PkeyVerify)(verify), (PkeyComputeShareKey)(computeShareKey), (PkeyCrypt)(encrypt), \ + (PkeyCrypt)(decrypt), (PkeyCheck)(check), (PkeyCmp)(cmp), (PkeyGetSecBits)(getSecBits)} + +static const EAL_PkeyMethod METHODS[] = { +#ifdef HITLS_CRYPTO_DSA + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_DSA, + CRYPT_DSA_NewCtx, + CRYPT_DSA_DupCtx, + CRYPT_DSA_FreeCtx, + CRYPT_DSA_SetPara, + CRYPT_DSA_GetPara, + CRYPT_DSA_Gen, + CRYPT_DSA_GetBits, + CRYPT_DSA_GetSignLen, + CRYPT_DSA_Ctrl, + NULL, // newParaById + NULL, // getParaId + CRYPT_DSA_FreePara, + CRYPT_DSA_NewPara, + CRYPT_DSA_SetPubKey, + CRYPT_DSA_SetPrvKey, + CRYPT_DSA_GetPubKey, + CRYPT_DSA_GetPrvKey, + CRYPT_DSA_Sign, + CRYPT_DSA_Verify, + NULL, + NULL, + NULL, + NULL, + CRYPT_DSA_Cmp, + CRYPT_DSA_GetSecBits + ), // CRYPT_PKEY_DSA +#endif +#ifdef HITLS_CRYPTO_ED25519 + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_ED25519, + CRYPT_CURVE25519_NewCtx, + CRYPT_CURVE25519_DupCtx, + CRYPT_CURVE25519_FreeCtx, + NULL, + NULL, + CRYPT_ED25519_GenKey, + CRYPT_CURVE25519_GetBits, + CRYPT_CURVE25519_GetSignLen, + CRYPT_CURVE25519_Ctrl, + NULL, // newParaById + NULL, // getParaId + NULL, + NULL, + CRYPT_CURVE25519_SetPubKey, + CRYPT_CURVE25519_SetPrvKey, + CRYPT_CURVE25519_GetPubKey, + CRYPT_CURVE25519_GetPrvKey, + CRYPT_CURVE25519_Sign, + CRYPT_CURVE25519_Verify, + NULL, + NULL, + NULL, + NULL, + CRYPT_CURVE25519_Cmp, + CRYPT_CURVE25519_GetSecBits + ), // CRYPT_PKEY_ED25519 +#endif +#ifdef HITLS_CRYPTO_X25519 + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_X25519, + CRYPT_CURVE25519_NewCtx, + CRYPT_CURVE25519_DupCtx, + CRYPT_CURVE25519_FreeCtx, + NULL, + NULL, + CRYPT_X25519_GenKey, + CRYPT_CURVE25519_GetBits, + NULL, + CRYPT_CURVE25519_Ctrl, + NULL, // newParaById + NULL, // getParaId + NULL, + NULL, + CRYPT_CURVE25519_SetPubKey, + CRYPT_CURVE25519_SetPrvKey, + CRYPT_CURVE25519_GetPubKey, + CRYPT_CURVE25519_GetPrvKey, + NULL, + NULL, + CRYPT_CURVE25519_ComputeSharedKey, + NULL, + NULL, + NULL, + CRYPT_CURVE25519_Cmp, + CRYPT_CURVE25519_GetSecBits + ), // CRYPT_PKEY_X25519 +#endif +#ifdef HITLS_CRYPTO_RSA + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_RSA, + CRYPT_RSA_NewCtx, + CRYPT_RSA_DupCtx, + CRYPT_RSA_FreeCtx, + CRYPT_RSA_SetPara, + NULL, + CRYPT_RSA_Gen, + CRYPT_RSA_GetBits, + CRYPT_RSA_GetSignLen, + CRYPT_RSA_Ctrl, + NULL, // newParaById + NULL, // getParaId + CRYPT_RSA_FreePara, + CRYPT_RSA_NewPara, + CRYPT_RSA_SetPubKey, + CRYPT_RSA_SetPrvKey, + CRYPT_RSA_GetPubKey, + CRYPT_RSA_GetPrvKey, + CRYPT_RSA_Sign, + CRYPT_RSA_Verify, + NULL, + CRYPT_RSA_Encrypt, + CRYPT_RSA_Decrypt, + NULL, + CRYPT_RSA_Cmp, + CRYPT_RSA_GetSecBits + ), // CRYPT_PKEY_RSA +#endif +#ifdef HITLS_CRYPTO_DH + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_DH, + CRYPT_DH_NewCtx, + CRYPT_DH_DupCtx, + CRYPT_DH_FreeCtx, + CRYPT_DH_SetPara, + CRYPT_DH_GetPara, + CRYPT_DH_Gen, + CRYPT_DH_GetBits, + NULL, + CRYPT_DH_Ctrl, + CRYPT_DH_NewParaById, + CRYPT_DH_GetParaId, + CRYPT_DH_FreePara, + CRYPT_DH_NewPara, + CRYPT_DH_SetPubKey, + CRYPT_DH_SetPrvKey, + CRYPT_DH_GetPubKey, + CRYPT_DH_GetPrvKey, + NULL, + NULL, + CRYPT_DH_ComputeShareKey, + NULL, + NULL, + CRYPT_DH_Check, + CRYPT_DH_Cmp, + CRYPT_DH_GetSecBits + ), // CRYPT_PKEY_DH +#endif +#ifdef HITLS_CRYPTO_ECDSA + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_ECDSA, + CRYPT_ECDSA_NewCtx, + CRYPT_ECDSA_DupCtx, + CRYPT_ECDSA_FreeCtx, + CRYPT_ECDSA_SetPara, + CRYPT_ECDSA_GetPara, + CRYPT_ECDSA_Gen, + CRYPT_ECDSA_GetBits, + CRYPT_ECDSA_GetSignLen, + CRYPT_ECDSA_Ctrl, + CRYPT_ECDSA_NewParaById, + CRYPT_ECDSA_GetParaId, + CRYPT_ECDSA_FreePara, + CRYPT_ECDSA_NewPara, + CRYPT_ECDSA_SetPubKey, + CRYPT_ECDSA_SetPrvKey, + CRYPT_ECDSA_GetPubKey, + CRYPT_ECDSA_GetPrvKey, + CRYPT_ECDSA_Sign, + CRYPT_ECDSA_Verify, + NULL, // compute share key + NULL, // encrypt + NULL, // decrypt + NULL, + CRYPT_ECDSA_Cmp, + CRYPT_ECDSA_GetSecBits + ), // CRYPT_PKEY_ECDSA +#endif +#ifdef HITLS_CRYPTO_ECDH + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_ECDH, + CRYPT_ECDH_NewCtx, + CRYPT_ECDH_DupCtx, + CRYPT_ECDH_FreeCtx, + CRYPT_ECDH_SetPara, + CRYPT_ECDH_GetPara, + CRYPT_ECDH_Gen, + CRYPT_ECDH_GetBits, + NULL, // get sign len + CRYPT_ECDH_Ctrl, + CRYPT_ECDH_NewParaById, + CRYPT_ECDH_GetParaId, + CRYPT_ECDH_FreePara, + CRYPT_ECDH_NewPara, + CRYPT_ECDH_SetPubKey, + CRYPT_ECDH_SetPrvKey, + CRYPT_ECDH_GetPubKey, + CRYPT_ECDH_GetPrvKey, + NULL, // sign + NULL, // verify + CRYPT_ECDH_ComputeShareKey, + NULL, // encrypt + NULL, // decrypt + NULL, + CRYPT_ECDH_Cmp, + CRYPT_ECDH_GetSecBits + ), // CRYPT_PKEY_ECDH +#endif +#ifdef HITLS_CRYPTO_SM2 + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_SM2, + CRYPT_SM2_NewCtx, + CRYPT_SM2_DupCtx, + CRYPT_SM2_FreeCtx, + NULL, + NULL, + CRYPT_SM2_Gen, + CRYPT_SM2_GetBits, +#ifdef HITLS_CRYPTO_SM2_SIGN + CRYPT_SM2_GetSignLen, +#else + NULL, +#endif + CRYPT_SM2_Ctrl, + NULL, + NULL, + NULL, + NULL, + CRYPT_SM2_SetPubKey, + CRYPT_SM2_SetPrvKey, + CRYPT_SM2_GetPubKey, + CRYPT_SM2_GetPrvKey, +#ifdef HITLS_CRYPTO_SM2_SIGN + CRYPT_SM2_Sign, + CRYPT_SM2_Verify, +#else + NULL, + NULL, +#endif +#ifdef HITLS_CRYPTO_SM2_EXCH + CRYPT_SM2_KapComputeKey, // compute share key +#else + NULL, +#endif +#ifdef HITLS_CRYPTO_SM2_CRYPT + CRYPT_SM2_Encrypt, // encrypt + CRYPT_SM2_Decrypt, // decrypt +#else + NULL, + NULL, +#endif + NULL, + CRYPT_SM2_Cmp, + CRYPT_SM2_GetSecBits + ), // CRYPT_PKEY_SM2 +#endif +#ifdef HITLS_CRYPTO_PAILLIER + EAL_PKEY_METHOD_DEFINE( + CRYPT_PKEY_PAILLIER, + CRYPT_PAILLIER_NewCtx, + CRYPT_PAILLIER_DupCtx, + CRYPT_PAILLIER_FreeCtx, + CRYPT_PAILLIER_SetPara, + NULL, + CRYPT_PAILLIER_Gen, + CRYPT_PAILLIER_GetBits, + NULL, + NULL, // ctrl, + NULL, + NULL, + CRYPT_PAILLIER_FreePara, + CRYPT_PAILLIER_NewPara, + CRYPT_PAILLIER_SetPubKey, + CRYPT_PAILLIER_SetPrvKey, + CRYPT_PAILLIER_GetPubKey, + CRYPT_PAILLIER_GetPrvKey, + NULL, + NULL, + NULL, + CRYPT_PAILLIER_Encrypt, + CRYPT_PAILLIER_Decrypt, + NULL, + NULL, // cmp + CRYPT_PAILLIER_GetSecBits + ), // CRYPT_PKEY_PAILLIER +#endif +}; + +const EAL_PkeyMethod *CRYPT_EAL_PkeyFindMethod(CRYPT_PKEY_AlgId id) +{ + uint32_t num = sizeof(METHODS) / sizeof(METHODS[0]); + const EAL_PkeyMethod *pkeyMeth = NULL; + + for (uint32_t i = 0; i < num; i++) { + if (METHODS[i].id == id) { + pkeyMeth = &METHODS[i]; + return pkeyMeth; + } + } + + return NULL; +} +#endif diff --git a/crypto/eal/src/eal_pkey_sign.c b/crypto/eal/src/eal_pkey_sign.c new file mode 100644 index 00000000..ad97122d --- /dev/null +++ b/crypto/eal/src/eal_pkey_sign.c @@ -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_CRYPTO_EAL) && defined(HITLS_CRYPTO_PKEY) + +#include +#include +#include "bsl_sal.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_md.h" +#include "crypt_errno.h" +#include "eal_md_local.h" +#include "eal_pkey_local.h" +#include "crypt_eal_rand.h" +#include "crypt_algid.h" +#include "bsl_err_internal.h" +#include "eal_common.h" +#include "crypt_utils.h" + +#define VERIFY_MAXDIGESTSIZE 64 // Maximum signature length + +static const uint32_t SIGN_MD_ID_LIST[] = { + CRYPT_MD_MD5, + CRYPT_MD_SHA1, + CRYPT_MD_SHA224, + CRYPT_MD_SHA256, + CRYPT_MD_SHA384, + CRYPT_MD_SHA512, + CRYPT_MD_SM3 +}; + +int32_t SignVerifySimpleHash(CRYPT_MD_AlgId id, const uint8_t *data, + uint32_t dataLen, uint8_t *hash, uint32_t *hashLen) +{ + if (ParamIdIsValid(id, SIGN_MD_ID_LIST, sizeof(SIGN_MD_ID_LIST) / sizeof(SIGN_MD_ID_LIST[0])) == false) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + int32_t ret = CRYPT_EAL_Md(id, data, dataLen, hash, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_EAL_PkeySignData(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *hash, + uint32_t hashLen, uint8_t *sign, uint32_t *signLen) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->sign == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + // ed25519/sm2/sm9 does not support signing hash data + if (pkey->id == CRYPT_PKEY_ED25519 || pkey->id == CRYPT_PKEY_SM2) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + // There is no 0-length hash data. ed25519 signs the plaintext instead of the hash data. + if (hash == NULL || hashLen == 0) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = pkey->method->sign(pkey->key, hash, hashLen, sign, signLen); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_SIGN : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +static int32_t PkeySignCore(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, + const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen) +{ + int32_t ret; + // ed25519 directly sign the plaintext data. + if (pkey->id == CRYPT_PKEY_ED25519) { + if (id != CRYPT_MD_SHA512) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_CURVE25519_HASH_METH_ERROR); + return CRYPT_CURVE25519_HASH_METH_ERROR; + } + ret = pkey->method->sign(pkey->key, data, dataLen, sign, signLen); + } else if (pkey->id == CRYPT_PKEY_SM2) { // sm2: directly verify the plaintext data. + if (id != CRYPT_MD_SM3) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + ret = pkey->method->sign(pkey->key, data, dataLen, sign, signLen); + } else { // For others, hash then sign the plaintext data. + uint8_t hash[VERIFY_MAXDIGESTSIZE]; + uint32_t hashLen = VERIFY_MAXDIGESTSIZE; + ret = SignVerifySimpleHash(id, data, dataLen, hash, &hashLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; + } + // Sign the hash. + ret = pkey->method->sign(pkey->key, hash, hashLen, sign, signLen); + } + return ret; +} + +int32_t CRYPT_EAL_PkeySign(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, + const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen) +{ + // 1. Check the input parameter + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->sign == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + + int32_t ret = PkeySignCore(pkey, id, data, dataLen, sign, signLen); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_SIGN : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +static int32_t PkeyVerifyCore(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, + const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen) +{ + // ed25519/sm2: directly verify the plaintext data. + int32_t ret; + if (pkey->id == CRYPT_PKEY_ED25519) { + if (id != CRYPT_MD_SHA512) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_CURVE25519_HASH_METH_ERROR); + return CRYPT_CURVE25519_HASH_METH_ERROR; + } + ret = pkey->method->verify(pkey->key, data, dataLen, sign, signLen); + } else if (pkey->id == CRYPT_PKEY_SM2) { // sm2: directly verify the plaintext. + if (id != CRYPT_MD_SM3) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + ret = pkey->method->verify(pkey->key, data, dataLen, sign, signLen); + } else { // Hash the plaintext data and verify the hash value. + uint8_t hash[VERIFY_MAXDIGESTSIZE]; + uint32_t hashLen = VERIFY_MAXDIGESTSIZE; + ret = SignVerifySimpleHash(id, data, dataLen, hash, &hashLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; + } + ret = pkey->method->verify(pkey->key, hash, hashLen, sign, signLen); + } + return ret; +} + +int32_t CRYPT_EAL_PkeyVerify(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, + const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen) +{ + // 1. Check the input parameter + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->verify == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + // 2. Hash the plaintext data and verify the hash value. + int32_t ret = PkeyVerifyCore(pkey, id, data, dataLen, sign, signLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; + } + EAL_EventReport(CRYPT_EVENT_VERIFY, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} + +int32_t CRYPT_EAL_PkeyVerifyData(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *hash, + uint32_t hashLen, const uint8_t *sign, uint32_t signLen) +{ + if (pkey == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->method == NULL || pkey->method->verify == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + // ed25519: does not support signing hash data + if (pkey->id == CRYPT_PKEY_ED25519) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT); + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + if (hash == NULL || hashLen == 0) { // Hash data with length 0 does not exist + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // 3. Verify the hash value. + int32_t ret = pkey->method->verify(pkey->key, hash, hashLen, sign, signLen); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_VERIFY : CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, ret); + return ret; +} +#endif diff --git a/crypto/eal/src/eal_rand.c b/crypto/eal/src/eal_rand.c new file mode 100644 index 00000000..483c5aab --- /dev/null +++ b/crypto/eal/src/eal_rand.c @@ -0,0 +1,547 @@ +/* + * 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_EAL) && defined(HITLS_CRYPTO_DRBG) + +#include +#include +#include "crypt_eal_rand.h" +#include "crypt_errno.h" +#include "bsl_errno.h" +#include "bsl_sal.h" +#include "crypt_algid.h" +#include "crypt_ealinit.h" +#include "crypt_drbg.h" +#ifdef HITLS_CRYPTO_MD +#include "eal_md_local.h" +#endif +#ifdef HITLS_CRYPTO_MAC +#include "eal_mac_local.h" +#endif +#ifdef HITLS_CRYPTO_CIPHER +#include "eal_cipher_local.h" +#endif +#include "eal_drbg_local.h" +#include "bsl_err_internal.h" +#include "crypt_types.h" +#include "crypt_util_rand.h" +#include "eal_common.h" +#include "eal_entropy.h" + +typedef enum { + RAND_AES128_KEYLEN = 16, + RAND_AES192_KEYLEN = 24, + RAND_AES256_KEYLEN = 32, +} RAND_AES_KeyLen; + +typedef struct { + CRYPT_RAND_AlgId id; + CRYPT_RandSeedMethod *seedMeth; + void *seedCtx; + const uint8_t *pers; + uint32_t persLen; +} CRYPT_RAND_DrbgParam; + +static CRYPT_EAL_RndCtx *g_globalRndCtx = NULL; + +#define RETURN_RAND_LOCK(ctx, ret) \ + do { \ + (ret) = BSL_SAL_ThreadWriteLock(((ctx)->lock)); \ + if ((ret) != BSL_SUCCESS) { \ + BSL_ERR_PUSH_ERROR((ret)); \ + return (ret); \ + } \ + } while (0) + +#define RAND_UNLOCK(ctx) (void)BSL_SAL_ThreadUnlock(((ctx)->lock)) + + +int32_t EAL_RandSetMeth(EalRndMeth *meth, CRYPT_EAL_RndCtx *ctx) +{ + if (meth == NULL || ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (meth->rand == NULL || meth->seed == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + if (meth->newCtx != NULL && meth->freeCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER); + return CRYPT_EAL_ERR_METH_NULL_NUMBER; + } + + if (ctx->working == true) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_RAND_WORKING); + return CRYPT_EAL_ERR_RAND_WORKING; + } + + (void)memcpy_s(&ctx->meth, sizeof(EalRndMeth), meth, sizeof(EalRndMeth)); + + return CRYPT_SUCCESS; +} + +/* Initialize the global DRBG. */ +int32_t EAL_RandInit(CRYPT_RndParam *param, CRYPT_EAL_RndCtx *ctx) +{ + if (param == NULL || ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->working == true) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_RAND_WORKING); + return CRYPT_EAL_ERR_RAND_WORKING; + } + + EalRndMeth *meth = &ctx->meth; + if (meth->rand == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (meth->newCtx == NULL) { + ctx->working = true; + ctx->ctx = NULL; + return CRYPT_SUCCESS; + } + + ctx->ctx = meth->newCtx(param); + if (ctx->ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_DRBG_INIT_FAIL); + return CRYPT_EAL_ERR_DRBG_INIT_FAIL; + } + + ctx->working = true; + + return CRYPT_SUCCESS; +} + +static void MethFreeCtx(CRYPT_EAL_RndCtx *ctx) +{ + EalRndMeth *meth = &ctx->meth; + if (ctx->ctx != NULL && meth->freeCtx != NULL) { + meth->freeCtx(ctx->ctx); + } + return; +} + +void CRYPT_RandDeinit(CRYPT_EAL_RndCtx *ctx) +{ + if (ctx == NULL) { + return; + } + + BSL_SAL_ThreadLockHandle lock = ctx->lock; + ctx->lock = NULL; + + if (BSL_SAL_ThreadWriteLock(lock) != CRYPT_SUCCESS) { // write lock + MethFreeCtx(ctx); + BSL_SAL_ThreadLockFree(lock); + BSL_SAL_FREE(ctx); + return; + } + + ctx->working = false; + EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_RAND, ctx->id, CRYPT_SUCCESS); + MethFreeCtx(ctx); + (void)BSL_SAL_ThreadUnlock(lock); + BSL_SAL_ThreadLockFree(lock); // free the lock resource + BSL_SAL_FREE(ctx); + return; +} + +// Check whether the state of CTX is available. +static int32_t CheckRndCtxState(CRYPT_EAL_RndCtx *ctx) +{ + if (ctx->working == false) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, ctx->id, CRYPT_EAL_ERR_RAND_NO_WORKING); + return CRYPT_EAL_ERR_RAND_NO_WORKING; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_RandbytesWithAdin(uint8_t *byte, uint32_t len, uint8_t *addin, uint32_t addinLen) +{ + if (g_globalRndCtx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, CRYPT_RAND_ALGID_MAX, CRYPT_EAL_ERR_GLOBAL_DRBG_NULL); + return CRYPT_EAL_ERR_GLOBAL_DRBG_NULL; + } + return CRYPT_EAL_DrbgbytesWithAdin(g_globalRndCtx, byte, len, addin, addinLen); +} + +int32_t CRYPT_EAL_Randbytes(uint8_t *byte, uint32_t len) +{ + return CRYPT_EAL_RandbytesWithAdin(byte, len, NULL, 0); +} + +int32_t CRYPT_EAL_RandSeedWithAdin(uint8_t *addin, uint32_t addinLen) +{ + if (g_globalRndCtx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, CRYPT_RAND_ALGID_MAX, CRYPT_EAL_ERR_GLOBAL_DRBG_NULL); + return CRYPT_EAL_ERR_GLOBAL_DRBG_NULL; + } + return CRYPT_EAL_DrbgSeedWithAdin(g_globalRndCtx, addin, addinLen); +} + +int32_t CRYPT_EAL_RandSeed(void) +{ + return CRYPT_EAL_RandSeedWithAdin(NULL, 0); +} + +int32_t CRYPT_EAL_DrbgbytesWithAdin(CRYPT_EAL_RndCtx *ctx, uint8_t *byte, uint32_t len, uint8_t *addin, + uint32_t addinLen) +{ + int32_t ret; + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, CRYPT_RAND_ALGID_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + RETURN_RAND_LOCK(ctx, ret); // write lock + ret = CheckRndCtxState(ctx); + if (ret != CRYPT_SUCCESS) { + RAND_UNLOCK(ctx); + return ret; + } + + EalRndMeth *meth = &ctx->meth; + ret = meth->rand(ctx->ctx, byte, len, addin, addinLen); + EAL_EventReport((ret == CRYPT_SUCCESS) ? CRYPT_EVENT_RANDGEN : CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, ctx->id, ret); + RAND_UNLOCK(ctx); + return ret; +} + +int32_t CRYPT_EAL_Drbgbytes(CRYPT_EAL_RndCtx *ctx, uint8_t *byte, uint32_t len) +{ + return CRYPT_EAL_DrbgbytesWithAdin(ctx, byte, len, NULL, 0); +} + +int32_t CRYPT_EAL_DrbgSeedWithAdin(CRYPT_EAL_RndCtx *ctx, uint8_t *addin, uint32_t addinLen) +{ + int32_t ret; + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, CRYPT_RAND_ALGID_MAX, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + RETURN_RAND_LOCK(ctx, ret); // write lock + ret = CheckRndCtxState(ctx); + if (ret != CRYPT_SUCCESS) { + RAND_UNLOCK(ctx); + return ret; + } + + EalRndMeth *meth = &ctx->meth; + ret = meth->seed(ctx->ctx, addin, addinLen); + if (ret != CRYPT_SUCCESS) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, ctx->id, ret); + } + RAND_UNLOCK(ctx); + return ret; +} + +int32_t CRYPT_EAL_DrbgSeed(CRYPT_EAL_RndCtx *ctx) +{ + return CRYPT_EAL_DrbgSeedWithAdin(ctx, NULL, 0); +} + +void EAL_RandDrbgFree(void *ctx) +{ + if (ctx == NULL) { + return; + } + DRBG_Ctx *drbg = (DRBG_Ctx *)ctx; + + DRBG_Free(drbg); + return; +} + +#define RAND_TYPE_MD 1 +#define RAND_TYPE_MAC 2 +#define RAND_TYPE_AES 3 +#define RAND_TYPE_AES_DF 4 + +typedef struct { + CRYPT_RAND_AlgId drbgId; + uint32_t depId; + uint32_t type; +} DrbgIdMap; + +/* Mapping between RAND and specific random number generation algorithms */ +static const DrbgIdMap DRBG_METHOD_MAP[] = { +#ifdef HITLS_CRYPTO_DRBG_HASH + { CRYPT_RAND_SHA1, CRYPT_MD_SHA1, RAND_TYPE_MD }, + { CRYPT_RAND_SHA224, CRYPT_MD_SHA224, RAND_TYPE_MD }, + { CRYPT_RAND_SHA256, CRYPT_MD_SHA256, RAND_TYPE_MD }, + { CRYPT_RAND_SHA384, CRYPT_MD_SHA384, RAND_TYPE_MD }, + { CRYPT_RAND_SHA512, CRYPT_MD_SHA512, RAND_TYPE_MD }, +#endif +#ifdef HITLS_CRYPTO_DRBG_HMAC + { CRYPT_RAND_HMAC_SHA1, CRYPT_MAC_HMAC_SHA1, RAND_TYPE_MAC }, + { CRYPT_RAND_HMAC_SHA224, CRYPT_MAC_HMAC_SHA224, RAND_TYPE_MAC }, + { CRYPT_RAND_HMAC_SHA256, CRYPT_MAC_HMAC_SHA256, RAND_TYPE_MAC }, + { CRYPT_RAND_HMAC_SHA384, CRYPT_MAC_HMAC_SHA384, RAND_TYPE_MAC }, + { CRYPT_RAND_HMAC_SHA512, CRYPT_MAC_HMAC_SHA512, RAND_TYPE_MAC }, +#endif +#ifdef HITLS_CRYPTO_DRBG_CTR + { CRYPT_RAND_AES128_CTR, CRYPT_SYM_AES128, RAND_TYPE_AES }, + { CRYPT_RAND_AES192_CTR, CRYPT_SYM_AES192, RAND_TYPE_AES }, + { CRYPT_RAND_AES256_CTR, CRYPT_SYM_AES256, RAND_TYPE_AES }, + { CRYPT_RAND_AES128_CTR_DF, CRYPT_SYM_AES128, RAND_TYPE_AES_DF }, + { CRYPT_RAND_AES192_CTR_DF, CRYPT_SYM_AES192, RAND_TYPE_AES_DF }, + { CRYPT_RAND_AES256_CTR_DF, CRYPT_SYM_AES256, RAND_TYPE_AES_DF } +#endif +}; + +#ifdef HITLS_CRYPTO_DRBG_CTR +static uint32_t GetAesKeyLen(CRYPT_SYM_AlgId id, uint32_t *keyLen) +{ + switch (id) { + case CRYPT_SYM_AES128: + *keyLen = RAND_AES128_KEYLEN; + break; + case CRYPT_SYM_AES192: + *keyLen = RAND_AES192_KEYLEN; + break; + case CRYPT_SYM_AES256: + *keyLen = RAND_AES256_KEYLEN; + break; + default: + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_ALG_NOT_SUPPORT); + return CRYPT_DRBG_ALG_NOT_SUPPORT; + } + return CRYPT_SUCCESS; +} +#endif + +static const DrbgIdMap *GetDrbgIdMap(CRYPT_RAND_AlgId id) +{ + uint32_t num = sizeof(DRBG_METHOD_MAP) / sizeof(DRBG_METHOD_MAP[0]); + for (uint32_t i = 0; i < num; i++) { + if (DRBG_METHOD_MAP[i].drbgId == id) { + return &DRBG_METHOD_MAP[i]; + } + } + + return NULL; +} + +void* EAL_RandDrbgNew(CRYPT_RndParam *param) +{ + if (param == NULL) { + return NULL; + } + CRYPT_RAND_DrbgParam *p = (CRYPT_RAND_DrbgParam*)(param->ptr); + DRBG_Ctx *drbg = NULL; + + const DrbgIdMap *map = GetDrbgIdMap(p->id); + if (map == NULL) { + return NULL; + } +#ifdef HITLS_CRYPTO_DRBG_HASH + if (map->type == RAND_TYPE_MD) { + const EAL_MdMethod *md = EAL_MdFindMethod(map->depId); + if (md == NULL) { + return NULL; + } + drbg = DRBG_NewHashCtx(md, p->seedMeth, p->seedCtx); + } +#endif +#ifdef HITLS_CRYPTO_DRBG_HMAC + if (map->type == RAND_TYPE_MAC) { + EAL_MacMethLookup hmac; + if (EAL_MacFindMethod(map->depId, &hmac) != CRYPT_SUCCESS) { + return NULL; + } + drbg = DRBG_NewHmacCtx(hmac.macMethod, hmac.md, p->seedMeth, p->seedCtx); + } +#endif +#ifdef HITLS_CRYPTO_DRBG_CTR + if (map->type == RAND_TYPE_AES || map->type == RAND_TYPE_AES_DF) { + bool isUsedDF = (map->type == RAND_TYPE_AES_DF) ? true : false; + uint32_t keyLen; + if (GetAesKeyLen(map->depId, &keyLen) != CRYPT_SUCCESS) { + return NULL; + } + const EAL_CipherMethod *ciphMeth = EAL_FindSymMethod(map->depId); + if (ciphMeth == NULL) { + return NULL; + } + drbg = DRBG_NewCtrCtx(ciphMeth, keyLen, isUsedDF, p->seedMeth, p->seedCtx); + } +#endif + if (DRBG_Instantiate(drbg, p->pers, p->persLen) != CRYPT_SUCCESS) { + EAL_RandDrbgFree(drbg); + return NULL; + } + return drbg; +} + +int32_t EAL_RandDrbgGenerate(void *ctx, uint8_t *bytes, uint32_t len, const uint8_t *adin, uint32_t adinLen) +{ + return DRBG_Generate((DRBG_Ctx *)ctx, bytes, len, adin, adinLen, false); +} + +int32_t EAL_RandDrbgReseed(void *ctx, const uint8_t *adin, uint32_t adinLen) +{ + return DRBG_Reseed((DRBG_Ctx *)ctx, adin, adinLen); +} + +static int32_t DrbgParaIsValid(CRYPT_RAND_AlgId id, const CRYPT_RandSeedMethod *seedMeth, const void *seedCtx, + const uint8_t *pers, const uint32_t persLen) +{ + if (GetDrbgIdMap(id) == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } + + if (seedMeth == NULL && seedCtx != NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, id, CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (pers == NULL && persLen != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SUCCESS; +} + +static CRYPT_EAL_RndCtx *EAL_RandInitDrbg(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, + void *seedCtx, const uint8_t *pers, uint32_t persLen) +{ +#ifdef HITLS_CRYPTO_ASM_CHECK + if (CRYPT_ASMCAP_Drbg(id) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return NULL; + } +#endif + CRYPT_RandSeedMethod seedMethTmp = {0}; + CRYPT_RandSeedMethod *seedMethond = seedMeth; + int32_t ret = DrbgParaIsValid(id, seedMeth, seedCtx, pers, persLen); + if (ret != CRYPT_SUCCESS) { + return NULL; + } + if (seedMeth == NULL) { +#ifdef HITLS_CRYPTO_ENTROPY + ret = EAL_SetDefaultEntropyMeth(&seedMethTmp, &seedCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + seedMethond = &seedMethTmp; +#else + (void) seedMethTmp; + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; +#endif + } + CRYPT_EAL_RndCtx *randCtx = BSL_SAL_Malloc(sizeof(CRYPT_EAL_RndCtx)); + if (randCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + // Apply for lock resources. + ret = BSL_SAL_ThreadLockNew(&(randCtx->lock)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(randCtx); + return NULL; + } + + randCtx->working = false; + randCtx->id = id; + + EalRndMeth meth = { + .newCtx = EAL_RandDrbgNew, + .freeCtx = EAL_RandDrbgFree, + .rand = EAL_RandDrbgGenerate, + .seed = EAL_RandDrbgReseed + }; + CRYPT_RAND_DrbgParam drbgParam = { + .id = id, + .seedMeth = seedMethond, + .seedCtx = seedCtx, + .pers = pers, + .persLen = persLen + }; + CRYPT_RndParam param; + param.ptr = (uintptr_t)&drbgParam; + + ret = EAL_RandSetMeth(&meth, randCtx); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_ThreadLockFree(randCtx->lock); // free the lock resource + BSL_SAL_FREE(randCtx); + return NULL; + } + + ret = EAL_RandInit(¶m, randCtx); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_ThreadLockFree(randCtx->lock); // free the lock resource + BSL_SAL_FREE(randCtx); + return NULL; + } + + return randCtx; +} + +int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, + const uint8_t *pers, uint32_t persLen) +{ + CRYPT_EAL_RndCtx *ctx = NULL; + if (g_globalRndCtx != NULL) { // Prevent DRBG repeated Init + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_DRBG_REPEAT_INIT); + return CRYPT_EAL_ERR_DRBG_REPEAT_INIT; + } + + ctx = EAL_RandInitDrbg(id, seedMeth, seedCtx, pers, persLen); + if (ctx == NULL) { + EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_RAND, id, CRYPT_EAL_ERR_DRBG_INIT_FAIL); + return CRYPT_EAL_ERR_DRBG_INIT_FAIL; + } + CRYPT_RandRegist(CRYPT_EAL_Randbytes); // provide a random number generation function for BigNum. + g_globalRndCtx = ctx; + return CRYPT_SUCCESS; +} + +CRYPT_EAL_RndCtx *CRYPT_EAL_DrbgInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, + const uint8_t *pers, uint32_t persLen) +{ + return EAL_RandInitDrbg(id, seedMeth, seedCtx, pers, persLen); +} + +void CRYPT_EAL_RandDeinit(void) +{ + CRYPT_RandDeinit(g_globalRndCtx); + g_globalRndCtx = NULL; + return; +} + +void CRYPT_EAL_DrbgDeinit(CRYPT_EAL_RndCtx *ctx) +{ + CRYPT_RandDeinit(ctx); + return; +} + +bool CRYPT_EAL_RandIsValidAlgId(CRYPT_RAND_AlgId id) +{ + return (GetDrbgIdMap(id) != NULL); +} +#endif diff --git a/crypto/ealinit/include/crypt_ealinit.h b/crypto/ealinit/include/crypt_ealinit.h new file mode 100644 index 00000000..f59f57c5 --- /dev/null +++ b/crypto/ealinit/include/crypt_ealinit.h @@ -0,0 +1,83 @@ +/* + * 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_EALINIT_H +#define CRYPT_EALINIT_H + +#include "hitls_build.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + +#ifdef HITLS_CRYPTO_ASM_CHECK +/** + * @ingroup crypt_asmcap + * @brief Check cpu capability for assembly implementation + * + * @param id [IN] algorithm id + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_EAL_ALG_ASM_NOT_SUPPORT CPU is not supported for assembly implementation +*/ +int32_t CRYPT_ASMCAP_Cipher(CRYPT_CIPHER_AlgId id); + +/** + * @ingroup crypt_asmcap + * @brief Check cpu capability for assembly implementation + * + * @param id [IN] algorithm id + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_EAL_ALG_ASM_NOT_SUPPORT CPU is not supported for assembly implementation +*/ +int32_t CRYPT_ASMCAP_Md(CRYPT_MD_AlgId id); + +/** + * @ingroup crypt_asmcap + * @brief Check cpu capability for assembly implementation + * + * @param id [IN] algorithm id + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_EAL_ALG_ASM_NOT_SUPPORT CPU is not supported for assembly implementation +*/ +int32_t CRYPT_ASMCAP_Pkey(CRYPT_PKEY_AlgId id); + +/** + * @ingroup crypt_asmcap + * @brief Check cpu capability for assembly implementation + * + * @param id [IN] algorithm id + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_EAL_ALG_ASM_NOT_SUPPORT CPU is not supported for assembly implementation +*/ +int32_t CRYPT_ASMCAP_Mac(CRYPT_MAC_AlgId id); + +/** + * @ingroup crypt_asmcap + * @brief Check cpu capability for assembly implementation + * + * @param id [IN] algorithm id + * @retval CRYPT_SUCCESS Instantiation succeeded. + * @retval CRYPT_EAL_ALG_ASM_NOT_SUPPORT CPU is not supported for assembly implementation +*/ +int32_t CRYPT_ASMCAP_Drbg(CRYPT_RAND_AlgId id); + +#endif // HITLS_CRYPTO_ASM_CHECK + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // CRYPT_EALINIT_H \ No newline at end of file diff --git a/crypto/ealinit/src/asmcap_alg_asm.c b/crypto/ealinit/src/asmcap_alg_asm.c new file mode 100644 index 00000000..a649a372 --- /dev/null +++ b/crypto/ealinit/src/asmcap_alg_asm.c @@ -0,0 +1,167 @@ +/* + * 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_ASM_CHECK + +#ifdef __cplusplus +extern "c" { +#endif + +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "asmcap_local.h" + +#if defined(HITLS_CRYPTO_CIPHER) +#if defined(HITLS_CRYPTO_AES_ASM) +int32_t CRYPT_AES_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_AES_X8664) + if (!IsSupportAVX() || !IsOSSupportAVX() || + !IsSupportAES() || !IsSupportSSE2()) { + // SetEncryptKey256 uses AVX and SSE2. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#elif defined(HITLS_CRYPTO_AES_ARMV8) + if (!IsSupportPMULL() || !IsSupportAES()) { + // ARMV8 should support the PMULL instruction sets. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_AES_ASM +#if defined(HITLS_CRYPTO_SM4_ASM) +int32_t CRYPT_SM4_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_SM4_X8664) + if ((!IsSupportAVX()) || !IsOSSupportAVX() || !IsSupportAVX2() || + (!IsSupportAES()) || (!IsSupportMOVBE())) { + // The AES instruction is used for the SBOX assembly in the XTS. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#elif (HITLS_CRYPTO_SM4_ARMV8) + if (!IsSupportAES()) { + // sbox uses the AES instruction. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_SM4 + +#if defined(HITLS_CRYPTO_GCM_ASM) +int32_t CRYPT_GHASH_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_GCM_X8664) + if (!IsSupportAVX() || !IsOSSupportAVX()) { + // GcmTableGen4bit uses the AVX. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#elif defined(HITLS_CRYPTO_GCM_ARMV8) + if (!IsSupportPMULL()) { + // In ARMV8, GHASH_BLOCK must support the PMULL instruction set. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_GCM + +#endif // HITLS_CRYPTO_CIPHER + +#if defined(HITLS_CRYPTO_MD) +#if defined(HITLS_CRYPTO_MD5_ASM) +int32_t CRYPT_MD5_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_MD5_X8664) + if (!IsSupportBMI1()) { // MD5_Compress uses the BMI1 instruction set. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_MD5 + +#if defined(HITLS_CRYPTO_SHA1_ASM) +int32_t CRYPT_SHA1_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_SHA1_X8664) + if (!IsSupportAVX() || !IsOSSupportAVX() || !IsSupportAVX2() || !IsSupportBMI1() || !IsSupportBMI2()) { + // The SHA1_Step function uses the AVX, AVX2, BMI1, and BMI2 instruction sets. + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_SHA1 + +#if defined(HITLS_CRYPTO_SHA2_ASM) +int32_t CRYPT_SHA2_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_SHA2_X8664) + if (!IsSupportAVX() || !IsOSSupportAVX() || !IsSupportAVX2() || !IsSupportBMI1() || !IsSupportBMI2()) { + // The SHA*CompressMultiBlocks_Asm function uses the AVX, AVX2, BMI1, and BMI2 instruction sets. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_SHA2 + +#if defined(HITLS_CRYPTO_SM3_ASM) +int32_t CRYPT_SM3_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_SM3_X8664) + if (!IsSupportMOVBE()) { + // MOVBE is used in the SM3_CompressAsm function. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_SM3 +#endif // HITLS_CRYPTO_MD + +#if defined(HITLS_CRYPTO_PKEY) +#if defined(HITLS_CRYPTO_ECC_ASM) +int32_t CRYPT_ECP256_AsmCheck(void) +{ +#if defined(HITLS_CRYPTO_ECC_X8664) + if (!IsSupportAVX() || !IsOSSupportAVX()) { // ECP256_OrdSqr uses AVX. + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } +#endif + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_ECC + +#endif // HITLS_CRYPTO_PKEY + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ASM_CHECK \ No newline at end of file diff --git a/crypto/ealinit/src/asmcap_local.h b/crypto/ealinit/src/asmcap_local.h new file mode 100644 index 00000000..9a80b2f5 --- /dev/null +++ b/crypto/ealinit/src/asmcap_local.h @@ -0,0 +1,77 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef ASMCAP_LOCAL_H +#define ASMCAP_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ASM_CHECK +#include "crypt_ealinit.h" + +#ifdef __cplusplus +extern "c" { +#endif + +#if defined(HITLS_CRYPTO_CIPHER) +#if defined(HITLS_CRYPTO_AES_ASM) + +int32_t CRYPT_AES_AsmCheck(void); +#endif // HITLS_CRYPTO_AES_ASM + +#if defined(HITLS_CRYPTO_SM4_ASM) +int32_t CRYPT_SM4_AsmCheck(void); +#endif // HITLS_CRYPTO_SM4 + +#if defined(HITLS_CRYPTO_GCM_ASM) +int32_t CRYPT_GHASH_AsmCheck(void); +#endif // HITLS_CRYPTO_GCM + +#endif // HITLS_CRYPTO_CIPHER + +#if defined(HITLS_CRYPTO_MD) +#if defined(HITLS_CRYPTO_MD5_ASM) +int32_t CRYPT_MD5_AsmCheck(void); +#endif // HITLS_CRYPTO_MD5 +#if defined(HITLS_CRYPTO_SHA1_ASM) +int32_t CRYPT_SHA1_AsmCheck(void); +#endif // HITLS_CRYPTO_SHA1 + +#if defined(HITLS_CRYPTO_SHA2_ASM) +int32_t CRYPT_SHA2_AsmCheck(void); +#endif // HITLS_CRYPTO_SHA2 + +#if defined(HITLS_CRYPTO_SM3_ASM) +int32_t CRYPT_SM3_AsmCheck(void); +#endif // HITLS_CRYPTO_SM3 +#endif // HITLS_CRYPTO_MD + + +#if defined(HITLS_CRYPTO_PKEY) + +#if defined(HITLS_CRYPTO_BN_ASM) +int32_t CRYPT_BN_AsmCheck(void); +#endif // HITLS_CRYPTO_BN + +#if defined(HITLS_CRYPTO_ECC_ASM) +int32_t CRYPT_ECP256_AsmCheck(void); +#endif // HITLS_CRYPTO_ECC + +#endif // HITLS_CRYPTO_PKEY +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ASM_CHECK +#endif // ASMCAP_LOCAL_H \ No newline at end of file diff --git a/crypto/ealinit/src/cpucap.c b/crypto/ealinit/src/cpucap.c new file mode 100644 index 00000000..af587cd2 --- /dev/null +++ b/crypto/ealinit/src/cpucap.c @@ -0,0 +1,273 @@ +/* + * 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 "crypt_utils.h" +#ifdef __x86_64__ + +#include +#include "securec.h" + + +CpuInstrSupportState g_cpuState = {0}; + +/* Obtain whether the CPU supports the SIMD instruction set through the cpuid instruction. */ +void GetCpuId(uint32_t eax, uint32_t ecx, uint32_t cpuId[CPU_ID_OUT_U32_CNT]) +{ + uint32_t eaxOut, ebxOut, ecxOut, edxOut; + + __asm("cpuid": "=a"(eaxOut), "=b"(ebxOut), "=c"(ecxOut), "=d"(edxOut): "a"(eax), "c"(ecx):); + + cpuId[EAX_OUT_IDX] = eaxOut; + cpuId[EBX_OUT_IDX] = ebxOut; + cpuId[ECX_OUT_IDX] = ecxOut; + cpuId[EDX_OUT_IDX] = edxOut; +} + +/* Obtain whether the OS supports the SIMD instruction set by using the xgetbv instruction. */ +static uint32_t GetExCtl(uint32_t ecx) +{ + uint32_t ret = 0; + + __asm("xgetbv": "=a"(ret): "c"(ecx):); + + return ret; +} + + +bool IsSupportBMI1(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_BMI; +} + +bool IsSupportMOVBE(void) +{ + return g_cpuState.code1Out[ECX_OUT_IDX] & bit_MOVBE; +} + +bool IsSupportBMI2(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_BMI2; +} + +bool IsSupportSSE(void) +{ + return g_cpuState.code1Out[EDX_OUT_IDX] & bit_SSE; +} + +bool IsSupportSSE2(void) +{ + return g_cpuState.code1Out[EDX_OUT_IDX] & bit_SSE2; +} + +bool IsSupportAVX(void) +{ + return g_cpuState.code1Out[ECX_OUT_IDX] & bit_AVX; +} + +bool IsSupportAES(void) +{ + return g_cpuState.code1Out[ECX_OUT_IDX] & bit_AES; +} + +bool IsSupportSSE3(void) +{ + return g_cpuState.code1Out[ECX_OUT_IDX] & bit_SSE3; +} + +bool IsSupportAVX2(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_AVX2; +} + +bool IsSupportAVX512F(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_AVX512F; +} + +bool IsSupportAVX512DQ(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_AVX512DQ; +} + +bool IsSupportAVX512VL(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_AVX512VL; +} + +bool IsSupportAVX512BW(void) +{ + return g_cpuState.code7Out[EBX_OUT_IDX] & bit_AVX512BW; +} + +bool IsSupportXSAVE(void) +{ + return g_cpuState.code1Out[ECX_OUT_IDX] & bit_XSAVE; +} + +bool IsSupportOSXSAVE(void) +{ + return g_cpuState.code1Out[ECX_OUT_IDX] & bit_OSXSAVE; +} + +bool IsOSSupportAVX(void) +{ + return g_cpuState.osSupportAVX; +} + +bool IsOSSupportAVX512(void) +{ + return g_cpuState.osSupportAVX512; +} + + +/* ARM */ +#elif defined(__arm__) || defined (__arm) || defined(__aarch64__) + +#include +#include "crypt_arm.h" + +uint32_t g_cryptArmCpuInfo = 0; + +static bool g_supportNEON = {0}; + +bool IsSupportAES(void) +{ + return g_cryptArmCpuInfo & CRYPT_ARM_AES; +} + +bool IsSupportPMULL(void) +{ + return g_cryptArmCpuInfo & CRYPT_ARM_PMULL; +} + +bool IsSupportSHA1(void) +{ + return g_cryptArmCpuInfo & CRYPT_ARM_SHA1; +} + +bool IsSupportSHA256(void) +{ + return g_cryptArmCpuInfo & CRYPT_ARM_SHA256; +} + +bool IsSupportNEON(void) +{ + return g_supportNEON; +} + +#if defined(__aarch64__) +bool IsSupportSHA512(void) +{ + return g_cryptArmCpuInfo & CRYPT_ARM_SHA512; +} +#endif // __aarch64__ + +#if defined(HITLS_CRYPTO_NO_AUXVAL) +#include +#include + +static jmp_buf g_jump_buffer; + +void signal_handler(int sig) +{ + (void)sig; + longjmp(g_jump_buffer, 1); +} + +void getarmcap(void) +{ + struct sigaction sa, old_sa; + + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGILL, &sa, &old_sa); + + // NEON + if (setjmp(g_jump_buffer) == 0) { + __asm__ volatile ("ORR v0.16b, v0.16b, v0.16b" : : : "v0"); + g_cryptArmCpuInfo |= CRYPT_ARM_NEON; +#if defined(__aarch64__) + // AES + if (setjmp(g_jump_buffer) == 0) { + __asm__ volatile ("aese v0.16b, v0.16b" : : : "v0"); + g_cryptArmCpuInfo |= CRYPT_ARM_AES; + } + // PMULL + if (setjmp(g_jump_buffer) == 0) { + __asm__ volatile ("pmull v0.1q, v0.1d, v0.1d" : : : "v0"); + g_cryptArmCpuInfo |= CRYPT_ARM_PMULL; + } + // SHA1 + if (setjmp(g_jump_buffer) == 0) { + __asm__ volatile ("sha1h s0, s0" : : : "s0"); + g_cryptArmCpuInfo |= CRYPT_ARM_SHA1; + } + // SHA256 + if (setjmp(g_jump_buffer) == 0) { + __asm__ volatile ("sha256su0 v0.4s, v0.4s" : : : "v0"); + g_cryptArmCpuInfo |= CRYPT_ARM_SHA256; + } + // SHA512 + if (setjmp(g_jump_buffer) == 0) { + __asm__ volatile ("sha512su0 v0.2d, v0.2d" : : : "v0"); + g_cryptArmCpuInfo |= CRYPT_ARM_SHA512; + } + } +#endif + + sigaction(SIGILL, &old_sa, NULL); +} + +#endif // HITLS_CRYPTO_NO_AUXVAL +#endif // x86_64 || __arm__ || __arm || __aarch64__ + +void GetCpuInstrSupportState(void) +{ +#ifdef __x86_64__ + uint32_t cpuId[CPU_ID_OUT_U32_CNT]; + uint64_t xcr0; + + /* SIMD CPU support */ + GetCpuId(0x1, 0, cpuId); + (void)memcpy_s(g_cpuState.code1Out, CPU_ID_OUT_U32_CNT * sizeof(uint32_t), cpuId, + CPU_ID_OUT_U32_CNT * sizeof(uint32_t)); + + GetCpuId(0x7, 0, cpuId); + (void)memcpy_s(g_cpuState.code7Out, CPU_ID_OUT_U32_CNT * sizeof(uint32_t), cpuId, + CPU_ID_OUT_U32_CNT * sizeof(uint32_t)); + + /* SIMD OS support */ + if (IsSupportXSAVE() && IsSupportOSXSAVE()) { + xcr0 = GetExCtl(0); + bool sse = xcr0 & XCR0_BIT_SSE; + bool avx = xcr0 & XCR0_BIT_AVX; + g_cpuState.osSupportAVX = sse && avx; + bool opmask = xcr0 & XCR0_BIT_OPMASK; + bool zmmLow = xcr0 & XCR0_BIT_ZMM_LOW; + bool zmmHigh = xcr0 & XCR0_BIT_ZMM_HIGH; + g_cpuState.osSupportAVX512 = opmask && zmmLow && zmmHigh; + } +#elif defined(__arm__) || defined (__arm) || defined(__aarch64__) +#if defined(HITLS_CRYPTO_NO_AUXVAL) + getarmcap(); +#else // HITLS_CRYPTO_NO_AUXVAL + g_supportNEON = getauxval(CRYPT_CAP) & CRYPT_ARM_NEON; + if (g_supportNEON) { + g_cryptArmCpuInfo = getauxval(CRYPT_CE); + } +#endif // HITLS_CRYPTO_NO_AUXVAL +#endif // defined(__arm__) || defined (__arm) || defined(__aarch64__) +} \ No newline at end of file diff --git a/crypto/ealinit/src/crypt_arm.h b/crypto/ealinit/src/crypt_arm.h new file mode 100644 index 00000000..146863f2 --- /dev/null +++ b/crypto/ealinit/src/crypt_arm.h @@ -0,0 +1,50 @@ +/* + * 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_ARM_H +#define CRYPT_ARM_H + +#ifndef CRYPT_VAL +#define CRYPT_VAL 16 +#endif +#ifndef CRYPT_VAL2 +#define CRYPT_VAL2 26 +#endif +#if defined(__arm__) || defined (__arm) +#define CRYPT_CAP CRYPT_VAL +#define CRYPT_CE CRYPT_VAL2 +#define CRYPT_ARM_NEON (1 << 12) +#define CRYPT_ARM_AES (1 << 0) +#define CRYPT_ARM_PMULL (1 << 1) +#define CRYPT_ARM_SHA1 (1 << 2) +#define CRYPT_ARM_SHA256 (1 << 3) +#elif defined(__aarch64__) +#define CRYPT_CAP CRYPT_VAL +#define CRYPT_CE CRYPT_VAL +#define CRYPT_ARM_NEON (1 << 1) +#define CRYPT_ARM_AES (1 << 3) +#define CRYPT_ARM_PMULL (1 << 4) +#define CRYPT_ARM_SHA1 (1 << 5) +#define CRYPT_ARM_SHA256 (1 << 6) +#define CRYPT_ARM_SM3 (1 << 18) +#define CRYPT_ARM_SM4 (1 << 19) +#define CRYPT_ARM_SHA512 (1 << 21) +#endif + +#ifndef __ASSEMBLER__ +extern uint32_t g_cryptArmCpuInfo; +#endif + +#endif \ No newline at end of file diff --git a/crypto/ealinit/src/crypt_asmcap.c b/crypto/ealinit/src/crypt_asmcap.c new file mode 100644 index 00000000..540f1ad0 --- /dev/null +++ b/crypto/ealinit/src/crypt_asmcap.c @@ -0,0 +1,270 @@ +/* + * 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 "bsl_init.h" +#include "bsl_err_internal.h" +#include "crypt_method.h" +#include "crypt_local_types.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" +#include "crypt_utils.h" +#include "asmcap_local.h" +#include "crypt_ealinit.h" + +static bool g_trigger = false; + +#define CRYPT_INIT_ABILITY_CPU_POS 0 +#define CRYPT_INIT_ABILITY_BSL_POS 1 +#define CRYPT_INIT_ABILITY_RAND_POS 2 + +#define CRYPT_INIT_ABILITY_BITMAP(value, pos) (((value) >> (pos)) & 0x1) +#define CRYPT_INIT_SUPPORT_ABILITY(cap, pos) (CRYPT_INIT_ABILITY_BITMAP(cap, pos) != 0) + +#if defined(HITLS_EAL_INIT_OPTS) +__attribute__((constructor(102))) int32_t CRYPT_EAL_Init(uint64_t opts) +#else +int32_t CRYPT_EAL_Init(uint64_t opts) +#endif +{ + if (g_trigger) { + return CRYPT_SUCCESS; + } + int32_t ret = CRYPT_SUCCESS; + uint64_t initopt = opts; +#if defined(HITLS_EAL_INIT_OPTS) + initopt = HITLS_EAL_INIT_OPTS; +#endif + +#if defined(HITLS_CRYPTO_INIT_RAND_ALG) + int32_t alg = HITLS_CRYPTO_INIT_RAND_ALG; +#else + int32_t alg = CRYPT_RAND_SHA256; +#endif + + if (CRYPT_INIT_SUPPORT_ABILITY(initopt, CRYPT_INIT_ABILITY_CPU_POS)) { + GetCpuInstrSupportState(); + } + + if (CRYPT_INIT_SUPPORT_ABILITY(initopt, CRYPT_INIT_ABILITY_BSL_POS)) { +#ifdef HITLS_BSL_INIT + ret = BSL_GLOBAL_Init(); + if (ret != CRYPT_SUCCESS) { + return ret; + } +#else + BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT); + return CRYPT_NOT_SUPPORT; + +#endif + } + + if (CRYPT_INIT_SUPPORT_ABILITY(initopt, CRYPT_INIT_ABILITY_RAND_POS)) { + ret = CRYPT_EAL_RandInit(alg, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + if (CRYPT_INIT_SUPPORT_ABILITY(initopt, CRYPT_INIT_ABILITY_BSL_POS)) { + BSL_GLOBAL_DeInit(); + } + return ret; + } + } + g_trigger = true; + return ret; +} + +#if defined(HITLS_EAL_INIT_OPTS) +__attribute__((destructor(101))) void CRYPT_EAL_Cleanup(uint64_t opts) +#else +void CRYPT_EAL_Cleanup(uint64_t opts) +#endif +{ + uint64_t initopt = opts; +#if defined(HITLS_EAL_INIT_OPTS) + initopt = HITLS_EAL_INIT_OPTS; +#endif + if (CRYPT_INIT_SUPPORT_ABILITY(initopt, CRYPT_INIT_ABILITY_RAND_POS)) { + CRYPT_EAL_RandDeinit(); + } + + if (CRYPT_INIT_SUPPORT_ABILITY(initopt, CRYPT_INIT_ABILITY_BSL_POS)) { +#ifdef HITLS_BSL_INIT + BSL_GLOBAL_DeInit(); +#endif + } +} + +#ifdef HITLS_CRYPTO_ASM_CHECK +typedef int (*HITLS_ASM_CHECK_CALLBACK)(void); + +typedef struct EAL_CheckAsm { + uint32_t id; + HITLS_ASM_CHECK_CALLBACK callback[2]; +} EAL_CheckAsm; + +static int32_t CryptCheckCapId(const BslCid id, const EAL_CheckAsm asmlist[], uint32_t len) +{ + for (uint32_t i = 0; i < len; i++) { + if (asmlist[i].id != id) { + continue; + } + for (uint32_t j = 0; j < 2; j++) { // 2 means Alg and Method + if (asmlist[i].callback[j] != NULL && asmlist[i].callback[j]() != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT); + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; + } + } + } + return CRYPT_SUCCESS; +} + +static const EAL_CheckAsm HITLS_ASM_SYM_ALG_CHECK[] = { + /* symmetric encryption/decryption combination algorithm ID */ +#if defined(HITLS_CRYPTO_AES_ASM) + {.id = CRYPT_CIPHER_AES128_CBC, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES192_CBC, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES256_CBC, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES128_CTR, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES192_CTR, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES256_CTR, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES128_CCM, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES192_CCM, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES256_CCM, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES128_CFB, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES192_CFB, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES256_CFB, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES128_OFB, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES192_OFB, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_AES256_OFB, .callback = {CRYPT_AES_AsmCheck, NULL}}, +#endif // HITLS_CRYPTO_AES_ASM +#if defined(HITLS_CRYPTO_SM4_ASM) + {.id = CRYPT_CIPHER_SM4_XTS, .callback = {CRYPT_SM4_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_SM4_CBC, .callback = {CRYPT_SM4_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_SM4_CTR, .callback = {CRYPT_SM4_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_SM4_CFB, .callback = {CRYPT_SM4_AsmCheck, NULL}}, + {.id = CRYPT_CIPHER_SM4_OFB, .callback = {CRYPT_SM4_AsmCheck, NULL}}, +#endif // HITLS_CRYPTO_SM4 +}; + +int32_t CRYPT_ASMCAP_Cipher(CRYPT_CIPHER_AlgId id) +{ + return CryptCheckCapId((BslCid)id, HITLS_ASM_SYM_ALG_CHECK, + sizeof(HITLS_ASM_SYM_ALG_CHECK) / sizeof(HITLS_ASM_SYM_ALG_CHECK[0])); +} + +#if defined(HITLS_CRYPTO_MD) +static const EAL_CheckAsm HITLS_ASM_MD_ALG_CHECK[] = { + /* hash algorithm ID */ + #if defined(HITLS_CRYPTO_MD5_ASM) + {.id = CRYPT_MD_MD5, .callback = {CRYPT_MD5_AsmCheck, NULL}}, + #endif + #if defined(HITLS_CRYPTO_SHA1_ASM) + {.id = CRYPT_MD_SHA1, .callback = {CRYPT_SHA1_AsmCheck, NULL}}, + #endif + #if defined(HITLS_CRYPTO_SHA2_ASM) + {.id = CRYPT_MD_SHA224, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_MD_SHA256, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_MD_SHA384, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_MD_SHA512, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + #endif + #if defined(HITLS_CRYPTO_SM3_ASM) + {.id = CRYPT_MD_SM3, .callback = {CRYPT_SM3_AsmCheck, NULL}}, + #endif +}; +#endif + +int32_t CRYPT_ASMCAP_Md(CRYPT_MD_AlgId id) +{ + return CryptCheckCapId((BslCid)id, HITLS_ASM_MD_ALG_CHECK, + sizeof(HITLS_ASM_MD_ALG_CHECK) / sizeof(HITLS_ASM_MD_ALG_CHECK[0])); +} + +#if defined(HITLS_CRYPTO_PKEY) +static const EAL_CheckAsm HITLS_ASM_PKEY_ALG_CHECK[] = { + /* Asymmetric algorithm ID */ +#if defined(HITLS_CRYPTO_ECC_ASM) + {.id = CRYPT_PKEY_ECDSA, .callback = {NULL, CRYPT_ECP256_AsmCheck}}, + {.id = CRYPT_PKEY_ECDH, .callback = {NULL, CRYPT_ECP256_AsmCheck}}, +#endif +}; + +int32_t CRYPT_ASMCAP_Pkey(CRYPT_PKEY_AlgId id) +{ + return CryptCheckCapId((BslCid)id, HITLS_ASM_PKEY_ALG_CHECK, + sizeof(HITLS_ASM_PKEY_ALG_CHECK) / sizeof(HITLS_ASM_PKEY_ALG_CHECK[0])); +} +#endif // HITLS_CRYPTO_PKEY + +#if defined(HITLS_CRYPTO_DRBG) +static const EAL_CheckAsm HITLS_ASM_DRBG_ALG_CHECK[] = { + /* RAND algorithm ID */ + #if defined(HITLS_CRYPTO_SHA1_ASM) + {.id = CRYPT_RAND_SHA1, .callback = {CRYPT_SHA1_AsmCheck, NULL}}, + {.id = CRYPT_RAND_HMAC_SHA1, .callback = {CRYPT_SHA1_AsmCheck, NULL}}, + #endif + #if defined(HITLS_CRYPTO_SHA2_ASM) + {.id = CRYPT_RAND_SHA224, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_SHA256, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_SHA384, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_SHA512, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_HMAC_SHA224, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_HMAC_SHA256, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_HMAC_SHA384, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_RAND_HMAC_SHA512, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + #endif + #if defined(HITLS_CRYPTO_AES_ASM) + {.id = CRYPT_RAND_AES128_CTR, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_RAND_AES192_CTR, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_RAND_AES256_CTR, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_RAND_AES128_CTR_DF, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_RAND_AES192_CTR_DF, .callback = {CRYPT_AES_AsmCheck, NULL}}, + {.id = CRYPT_RAND_AES256_CTR_DF, .callback = {CRYPT_AES_AsmCheck, NULL}}, + #endif +}; + +int32_t CRYPT_ASMCAP_Drbg(CRYPT_RAND_AlgId id) +{ + return CryptCheckCapId((BslCid)id, HITLS_ASM_DRBG_ALG_CHECK, + sizeof(HITLS_ASM_DRBG_ALG_CHECK) / sizeof(HITLS_ASM_DRBG_ALG_CHECK[0])); +} +#endif // HITLS_CRYPTO_DRBG + +#if defined(HITLS_CRYPTO_MAC) +static const EAL_CheckAsm HITLS_ASM_MAC_ALG_CHECK[] = { + /* MAC algorithm ID */ +#if defined(HITLS_CRYPTO_MD5_ASM) + {.id = CRYPT_MAC_HMAC_MD5, .callback = {CRYPT_MD5_AsmCheck, NULL}}, +#endif +#if defined(HITLS_CRYPTO_SHA1_ASM) + {.id = CRYPT_MAC_HMAC_SHA1, .callback = {CRYPT_SHA1_AsmCheck, NULL}}, +#endif +#if defined(HITLS_CRYPTO_SHA2_ASM) + {.id = CRYPT_MAC_HMAC_SHA224, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_MAC_HMAC_SHA256, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_MAC_HMAC_SHA384, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, + {.id = CRYPT_MAC_HMAC_SHA512, .callback = {CRYPT_SHA2_AsmCheck, NULL}}, +#endif +#if defined(HITLS_CRYPTO_SM3_ASM) + {.id = CRYPT_MAC_HMAC_SM3, .callback = {CRYPT_SM3_AsmCheck, NULL}}, +#endif +}; + +int32_t CRYPT_ASMCAP_Mac(CRYPT_MAC_AlgId id) +{ + return CryptCheckCapId((BslCid)id, HITLS_ASM_MAC_ALG_CHECK, + sizeof(HITLS_ASM_MAC_ALG_CHECK) / sizeof(HITLS_ASM_MAC_ALG_CHECK[0])); +} + +#endif // HITLS_CRYPTO_MAC +#endif /* HITLS_CRYPTO_ASM_CHECK */ diff --git a/crypto/ecc/include/crypt_ecc.h b/crypto/ecc/include/crypt_ecc.h new file mode 100644 index 00000000..f322fdcf --- /dev/null +++ b/crypto/ecc/include/crypt_ecc.h @@ -0,0 +1,414 @@ +/* + * 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_ECC_H +#define CRYPT_ECC_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECC + +#include "crypt_bn.h" +#include "crypt_algid.h" +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Elliptic Curve Point Information + */ +typedef struct EccPointInfo ECC_Point; + +/** + * Elliptic Curve Parameter Information + */ +typedef struct EccPara ECC_Para; + +/** + * Point information of elliptic curve scalar after recoding + */ +typedef struct { + int8_t *num; + uint32_t *wide; + uint32_t size; + uint32_t baseBits; // Indicates the offset start address of the first block. + uint32_t offset; +} ReCodeData; + +/** + * @ingroup ecc + * @brief Creating curve parameters + * + * @param id [IN] Curve enumeration + * + * @retval Not NULL Success + * @retval NULL failure + */ +ECC_Para *ECC_NewPara(CRYPT_PKEY_ParaId id); + +/** + * @ingroup ecc + * @brief Curve parameter release + * + * @param para [IN] Curve parameter information. The para is set NULL by the invoker. + * + * @retval None + */ +void ECC_FreePara(ECC_Para *para); + +/** + * @ingroup ecc + * @brief Read the curve parameter ID. + * + * @param para [IN] Curve parameter information + * + * @retval Curve ID + */ +CRYPT_PKEY_ParaId ECC_GetParaId(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain the curve parameter ID based on the curve parameter information. + * + * @param eccpara [IN] Curve parameter information + * + * @retval Curve ID + */ +CRYPT_PKEY_ParaId ECC_GetCurveId(const CRYPT_EccPara *eccPara); + +/** + * @ingroup ecc + * @brief Point creation + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +ECC_Point *ECC_NewPoint(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Point Release + * + * @param pt [IN] Point data, pt is set to null by the invoker. + * + * @retval none + */ +void ECC_FreePoint(ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Point copy + * + * @param dst [OUT] The copied point information + * @param src [IN] Input + * + * @retval Not NULL Success + * @retval NULL failure + */ +int32_t ECC_CopyPoint(ECC_Point *dst, const ECC_Point *src); + +/** + * @ingroup ecc + * @brief Generate a point data with the same content. + * + * @param pt [IN] Input point information + * + * @retval Not NULL Success + * @retval NULL failure + */ +ECC_Point *ECC_DupPoint(const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Check if a and b are the same point + * + * @param para [IN] Curve parameter information + * @param a [IN] Point a in Jacobian coordinate + * @param b [IN] Point b in Jacobian coordinate + * + * @retval CRYPT_SUCCESS The two points are the same. + * @retval CRYPT_ECC_POINT_NOT_EQUAL The two points are different. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b); + +/** + * @ingroup ecc + * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and get coordinates. + * + * @param para [IN] Curve parameter information + * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) + * @param x [OUT] x/z^2 + * @param y [OUT] y/z^3 + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_GetPoint(const ECC_Para *para, ECC_Point *pt, CRYPT_Data *x, CRYPT_Data *y); + +/** + * @ingroup ecc + * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and get x/z^2 + * + * @param para [IN] Curve parameter information + * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) + * @param x [OUT] x/z^2 + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_GetPointDataX(const ECC_Para *para, ECC_Point *pt, BN_BigNum *x); + +/** + * @ingroup ecc + * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G, where G is the generator + * The pre-computation table under the para parameter will be updated. + * + * @param para [IN] Curve parameter information + * @param r [OUT] Scalar multiplication + * @param k [IN] Scalar + * @param pt [IN] Point data, which can be NULL. + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_PointMul(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Calculate r = k1 * G + k2 * pt, where G is the generator. + * + * @param para [IN] Curve parameter information + * @param r [OUT] Point k1 * G + k2 * pt + * @param k1 [IN] Scalar k1 + * @param k2 [IN] Scalar k2 + * @param pt [IN] Point pt + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_PointMulAdd(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Convert the Jacobian coordinate point (x, y, z) to affine coordinate (x/z^2, y/z^3, 1) and encode point. + * + * @param para [IN] Curve parameter information + * @param pt [IN/OUT] Point (x, y, z) -> (x/z^2, y/z^3, 1) + * @param data [OUT] Data stream + * @param dataLen [IN/OUT] The input is the buff length of data and the output is the valid length of data. + * @param format [IN] Encoding format + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen, + CRYPT_PKEY_PointFormat format); + +/** + * @ingroup ecc + * @brief Encode the data stream into point information. + * + * @param para [IN] Curve parameter information + * @param pt [OUT] Point in affine coordinate(z=1) + * @param data [IN] Data stream + * @param dataLen [IN] Data stream length + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen); + +/** + * @ingroup ecc + * @brief Obtain the parameter value h based on the curve parameter. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *ECC_GetParaH(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain the parameter value n based on the curve parameter. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *ECC_GetParaN(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain the coefficient a based on curve parameters. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *ECC_GetParaA(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain the coefficient b based on curve parameters. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *ECC_GetParaB(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain the coordinate x of the base point G based on curve parameters. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *ECC_GetParaX(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain the coordinate y of the base point G based on curve parameters. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +BN_BigNum *ECC_GetParaY(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Obtain bit length of parameter p based on the curve parameter. + * + * @param para [IN] Curve parameter information + * + * @retval Return the specification unit of the curve parameter is bits. 0 is returned when an error occurs. + */ +uint32_t ECC_ParaBits(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Generate a curve parameter with the same content. + * + * @param para [IN] Curve parameter information + * + * @retval Not NULL Success + * @retval NULL failure + */ +ECC_Para *ECC_DupPara(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Check whether the point is valid. + * + * @param pt [IN] Point information + * + * @retval CRYPT_SUCCESS This point is valid. + * @retval CRYPT_ECC_POINT_AT_INFINITY The point is an infinite point (0 point). + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_PointCheck(const ECC_Point *pt); + + +/** + * @ingroup ecc + * @brief Obtain the generator(with z=1) based on curve parameters. + * + * @param para [IN] Curve parameters + * + * @retval Not NULL Success + * @retval NULL failure + */ +ECC_Point *ECC_GetGFromPara(const ECC_Para *para); + +/** + * @ingroup ecc + * @brief Scalar re-encoding to obtain the encoded data whose window is the 'window'. + * + * @param k [IN] Curve parameters + * @param window [IN] Window size + * + * @retval Not NULL Success + * @retval NULL failure + */ +ReCodeData *ECC_ReCodeK(const BN_BigNum *k, uint32_t window); + +/** + * @ingroup ecc + * @brief Release the encoded data. + * + * @param code [IN/OUT] Data to be released. The code is set NULL by the invoker. + * + * @retval None + */ +void ECC_ReCodeFree(ReCodeData *code); + +/** + * @brief Calculate r = 1/a mod para->n + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output modulus inverse value + * @param a [IN] Input BigNum that needs to be inverted. + * + * @retval CRYPT_SUCCESS set successfully. + * @retval For details about other errors, see crypt_errno.h. + */ +int32_t ECC_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); + +/** + * @ingroup ecc + * @brief Calculate addition r = a + b + * + * @param para [IN] Curve parameter + * @param r [OUT] Point r = a + b + * @param a [IN] Point a + * @param b [IN] Point b + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For other errors, see crypt_errno.h. + */ +int32_t ECC_PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); + +/** + * @ingroup ecc + * @brief ecc get security bits + * + * @param para [IN] ecc Context structure + * + * @retval security bits + */ +int32_t ECC_GetSecBits(const ECC_Para *para); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ECC + +#endif // CRYPT_ECC_H diff --git a/crypto/ecc/include/crypt_ecc_pkey.h b/crypto/ecc/include/crypt_ecc_pkey.h new file mode 100644 index 00000000..ad6149b5 --- /dev/null +++ b/crypto/ecc/include/crypt_ecc_pkey.h @@ -0,0 +1,218 @@ +/* + * 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_ECC_PKEY_H +#define CRYPT_ECC_PKEY_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECC + +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "crypt_algid.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CRYPT_ECC_TRY_MAX_CNT +#define CRYPT_ECC_TRY_MAX_CNT 100 // Maximum number of attempts to generate keys and signatures +#endif + +/* ECC key context */ +typedef struct ECC_PkeyCtx { + BN_BigNum *prvkey; // Private key + ECC_Point *pubkey; // Public key + ECC_Para *para; // Key parameter + CRYPT_PKEY_PointFormat pointFormat; // Public key point format + uint32_t useCofactorMode; // Indicates whether to use the cofactor mode. 1 indicates yes, and 0 indicates no. + BSL_SAL_RefCount references; +} ECC_Pkey; + +/** + * @ingroup ecc + * @brief After the copied ECC context is used up, call the ECC_FreeCtx to release the memory. + * + * @param ctx [IN] Source ECC context + * + * @return ECC_Pkey ECC context pointer + * If the operation fails, null is returned. + */ +ECC_Pkey *ECC_DupCtx(ECC_Pkey *ctx); + +/** + * @ingroup ecc + * @brief ecc Release the key context structure + * + * @param ctx [IN] Pointer to the context structure to be released. The ctx is set NULL by the invoker. + */ +void ECC_FreeCtx(ECC_Pkey *ctx); + +/** + * @ingroup ecc + * @brief Obtain the valid length of the key, which is used before obtaining the private key. + * + * @param ctx [IN] Structure from which the key length is expected to be obtained + * + * @retval 0 The input is incorrect or the corresponding key structure does not have a valid key length. + * @retval uint32_t Valid key length greater than 0 + */ +uint32_t ECC_PkeyGetBits(const ECC_Pkey *ctx); + +/** + * @ingroup ecc + * @brief Obtain curve parameters. + * + * @param pkey [IN] Curve parameter information + * @param eccPara [OUT] Curve parameter information + * + * @retval CRYPT_SUCCESS + * @retval Other failure + */ +int32_t ECC_GetPara(const ECC_Pkey *pkey, CRYPT_EccPara *eccPara); + +/** + * @ingroup ecc + * @brief Generate a public key from the public key. + * + * @param ctx [IN] ECC key context structure + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error code. Internal ECC calculation error + * @retval BN error code. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS The public key is successfully generated. + */ +int32_t ECC_GenPublicKey(ECC_Pkey *ctx); + +/** + * @ingroup ecc + * @brief Generate the ECC key pair. + * + * @param ctx [IN] dh Context structure + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error code. Internal ECC calculation error + * @retval BN error code. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t ECC_PkeyGen(ECC_Pkey *ctx); + +/** + * @ingroup ecc + * @brief ECC Set the private key data. + * + * @param ctx [OUT] ECC context structure + * @param prv [IN] Private key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t ECC_PkeySetPrvKey(ECC_Pkey *ctx, const CRYPT_EccPrv *prv); + +/** + * @ingroup ecc + * @brief ECC Set the public key data. + * + * @param ctx [OUT] ECC context structure + * @param pub [IN] Public key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t ECC_PkeySetPubKey(ECC_Pkey *ctx, const CRYPT_EccPub *pub); +/** + * @ingroup ecc + * @brief ECC Obtain the private key data. + * + * @param ctx [IN] ECC context structure + * @param prv [OUT] Private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval ECC_Pkey_KEYINFO_ERROR The key information is incorrect. + * @retval BN error. An error occurred in the internal BigNum calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t ECC_PkeyGetPrvKey(const ECC_Pkey *ctx, CRYPT_EccPrv *prv); + +/** + * @ingroup ecc + * @brief ECC Obtain the public key data. + * + * @param ctx [IN] ECC context structure + * @param pub [OUT] Public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval ECC_Pkey_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval ECC_Pkey_KEYINFO_ERROR The key information is incorrect. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t ECC_PkeyGetPubKey(const ECC_Pkey *ctx, CRYPT_EccPub *pub); + +/** + * @ingroup ecc + * @brief ECC control interface + * + * @param ctx [IN/OUT] ECC context structure + * @param opt [IN] Operation mode. For details, see ECC_CtrlType. + * @param val [IN] Input parameter + * @param len [IN] val Length + * + * @retval CRYPT_SUCCESS Set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval ECC_Pkey_ERR_UNSUPPORTED_CTRL_OPTION opt mode not supported + */ +int32_t ECC_PkeyCtrl(ECC_Pkey *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +/** + * @ingroup ecc + * @brief ecc Create a context. + * + * @param id [IN] elliptic curve ID + * @return ECC_Pkey ECC context pointer + * If the operation fails, null is returned. + */ +ECC_Pkey *ECC_PkeyNewCtx(CRYPT_PKEY_ParaId id); + +/** + * @ingroup ecc + * @brief ecc Compare public keys and parameters + * + * @param a [IN] ECC Context structure + * @param b [IN] ECC context structure + * + * @retval CRYPT_SUCCESS is the same + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL Public keys are not equal + * @retval CRYPT_ECC_POINT_ERR_CURVE_ID Parameter curve IDs are not equal. + * @retval CRYPT_ECC_ERR_POINT_FORMAT Point compression formats are not equal + * @retval For other error codes, see crypt_errno.h. + */ +int32_t ECC_PkeyCmp(const ECC_Pkey *a, const ECC_Pkey *b); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ECC + +#endif // CRYPT_ECC_PKEY_H diff --git a/crypto/ecc/src/asm/ecp256_armv8.S b/crypto/ecc/src/asm/ecp256_armv8.S new file mode 100644 index 00000000..8b83420a --- /dev/null +++ b/crypto/ecc/src/asm/ecp256_armv8.S @@ -0,0 +1,2122 @@ +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include "ecp256_pre_comp_table.s" + +.arch armv8-a+crypto +.file "ecp256_armv8.S" +.text + +.align 4 +.Lpoly: // P +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +.Lone_mont: // R mod P, R = 2^256, = 2^256 - P +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +.Lord: // Order, n +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +.LordK: // (2^64 - ord[0]) * ordK = 1 // LordK * Lord, the lower 64 bits are all Fs. + // LordK * Lord, The lower 64 bits are all Fs, coincidence? +.quad 0xccd1c8aaee00bc4f +.Lone: +.quad 1, 0, 0, 0 +/* +Initial z is not set to 1 +0000000300000000, 00000001FFFFFFFE, FFFFFFFD00000002, FFFFFFFE00000003 +*/ + +.globl ECP256_GetPreCompTable +.type ECP256_GetPreCompTable,%function +.align 4 +ECP256_GetPreCompTable: +.inst 0xd503233f + adrp x0, g_preCompTable + add x0, x0, :lo12:g_preCompTable + ret +.inst 0xd50323bf +.size ECP256_GetPreCompTable,.-ECP256_GetPreCompTable + +.globl ECP256_FromMont +.type ECP256_FromMont,%function +.align 4 +ECP256_FromMont: + .inst 0xd503233f + stp x29, x30, [sp, #-32]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + + ldp x4 , x5 , [x1] + ldp x6 , x7 , [x1, #16] + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + adrp x2, .Lone // &bp[0] + add x2, x2, :lo12:.Lone + + bl ECP256_MulCore + + ldp x19, x20, [sp , #16] + ldp x29, x30, [sp], #32 + .inst 0xd50323bf + ret +.size ECP256_FromMont,.-ECP256_FromMont + +.globl ECP256_Add +.type ECP256_Add,%function +.align 4 +ECP256_Add: + .inst 0xd503233f + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + ldp x14, x15, [x1] + ldp x16, x17, [x1, #16] + ldp x8 , x9 , [x2] + ldp x10, x11, [x2, #16] + ldr x12, .Lpoly+8 // x12 = 0x00000000ffffffff + ldr x13, .Lpoly+24 // x13 = 0xffffffff00000001 + + bl ECP256_AddCore + + ldp x29, x30, [sp], #16 + .inst 0xd50323bf + ret +.size ECP256_Add,.-ECP256_Add + +.type ECP256_AddCore,%function +.align 4 +ECP256_AddCore: + adds x14, x14, x8 // ret = a+b + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x1 , xzr, xzr + + // r -= p, p = 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 + adds x8 , x14, #1 // x8 = x14 - 0xffffffffffffffff = x14 + 1 + sbcs x9 , x15, x12 // x9 = x15 - 0x00000000ffffffff + sbcs x10, x16, xzr // x10 = x16 - 0 + sbcs x11, x17, x13 // x11 = x17 - 0xffffffff00000001 + sbcs xzr, x1 , xzr // Determine whether r-p has borrowing + + // r = r < p ? r : r-p + // x8~x11 saves r-p, x14~x17 saves r + csel x14, x14, x8 , lo + csel x15, x15, x9 , lo + csel x16, x16, x10, lo + csel x17, x17, x11, lo + + stp x14, x15, [x0] + stp x16, x17, [x0, #16] + + ret +.size ECP256_AddCore,.-ECP256_AddCore + +.globl ECP256_Sub +.type ECP256_Sub,%function +.align 4 +ECP256_Sub: + .inst 0xd503233f + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + ldp x14, x15, [x1] + ldp x16, x17, [x1, #16] + ldp x8 , x9 , [x2] + ldp x10, x11, [x2, #16] + ldr x12, .Lpoly+8 // x12 = 0x00000000ffffffff + ldr x13, .Lpoly+24 // x13 = 0xffffffff00000001 + + bl ECP256_SubCore1 + + ldp x29, x30, [sp], #16 + .inst 0xd50323bf + ret +.size ECP256_Sub,.-ECP256_Sub + +/////////////////////////////////////// +// x14~x17 = a[0~3], x8~x11 = b[0~3] // +/////////////////////////////////////// +.type ECP256_SubCore1,%function +.align 4 +ECP256_SubCore1: + subs x14, x14, x8 + sbcs x15, x15, x9 + sbcs x16, x16, x10 + sbcs x17, x17, x11 + sbc x1 , xzr, xzr // x1 = CF + + // r += p + subs x8 , x14, #1 // x8 = x14 + 0xffffffffffffffff = x14 - 1 + adcs x9 , x15, x12 // x9 = x15 + 0x00000000ffffffff + adcs x10, x16, xzr // x10 = x16 + 0 + adc x11, x17, x13 // x11 = x17 + 0xffffffff00000001 + cmp x1 , xzr + + // r = borrow==0 ? r : r+p + csel x14, x14, x8 , eq + csel x15, x15, x9 , eq + csel x16, x16, x10, eq + csel x17, x17, x11, eq + stp x14, x15, [x0] + stp x16, x17, [x0, #16] + + ret +.size ECP256_SubCore1,.-ECP256_SubCore1 + +.type ECP256_SubCore2,%function +.align 4 +ECP256_SubCore2: + subs x14, x8 , x14 + sbcs x15, x9 , x15 + sbcs x16, x10, x16 + sbcs x17, x11, x17 + sbc x1 , xzr, xzr // x1 = CF + + // r += p + subs x8 , x14, #1 // x8 = x14 + 0xffffffffffffffff = x14 - 1 + adcs x9 , x15, x12 // x9 = x15 + 0x00000000ffffffff + adcs x10, x16, xzr // x10 = x16 + 0 + adc x11, x17, x13 // x11 = x17 + 0xffffffff00000001 + cmp x1 , xzr + + // r = borrow==0 ? r : r+p + csel x14, x14, x8 , eq + csel x15, x15, x9 , eq + csel x16, x16, x10, eq + csel x17, x17, x11, eq + stp x14, x15, [x0] + stp x16, x17, [x0, #16] + + ret +.size ECP256_SubCore2,.-ECP256_SubCore2 + +.globl ECP256_DivBy2 +.type ECP256_DivBy2,%function +.align 4 +ECP256_DivBy2: + .inst 0xd503233f + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + ldp x14, x15, [x1] + ldp x16, x17, [x1, #16] + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + + bl ECP256_DivBy2Core + + ldp x29, x30, [sp], #16 + .inst 0xd50323bf + ret +.size ECP256_DivBy2,.-ECP256_DivBy2 + +.type ECP256_DivBy2Core,%function +.align 4 +ECP256_DivBy2Core: + // a+p + subs x8 , x14, #1 // x8 = x14 + 0xffffffffffffffff = x14 - 1 + adcs x9 , x15, x12 // x9 = x15 + 0x00000000ffffffff + adcs x10, x16, xzr // x10 = x16 + 0 + adcs x11, x17, x13 // x11 = x17 + 0xffffffff00000001 + adc x1 , xzr, xzr // x1 = CF + tst x14, #1 // Check whether a is an even number. eq indicates that a is an even number. + + // a = a Is an even number ? a : a+p + csel x14, x14, x8 , eq + csel x15, x15, x9 , eq + csel x16, x16, x10, eq + csel x17, x17, x11, eq + csel x1 , xzr, x1 , eq // If a is still a, then x1, which holds the carry, is set to 0. + + lsr x14, x14, #1 // r >>= 1, Divided by 2. + orr x14, x14, x15, lsl#63 // x15 is shifted leftward by 63 bits. The lower 63 bits become 0. + // The most significant bit is the least significant bit before the shift. + lsr x15, x15, #1 // The most significant bit of x14 is changed to the least significant bit of x15 + // to achieve cyclic right shift. + orr x15, x15, x16, lsl#63 + lsr x16, x16, #1 + orr x16, x16, x17, lsl#63 + lsr x17, x17, #1 + orr x17, x17, x1 , lsl#63 // The most significant bit of the highest block is x1. + stp x14, x15, [x0] + stp x16, x17, [x0, #16] + ret +.size ECP256_DivBy2Core,.-ECP256_DivBy2Core + +.globl ECP256_Neg +.type ECP256_Neg,%function +.align 4 +ECP256_Neg: + .inst 0xd503233f // Paciasp. + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + ldp x14, x15, [x1] + ldp x16, x17, [x1, #16] + + mov x8 , xzr + mov x9 , xzr + mov x10, xzr + mov x11, xzr + + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + // -a = 0 - a + bl ECP256_SubCore2 + + ldp x29, x30, [sp], #16 + .inst 0xd50323bf // Autiasp. + ret +.size ECP256_Neg,.-ECP256_Neg + +.globl ECP256_MulBy2 +.type ECP256_MulBy2,%function +.align 4 +ECP256_MulBy2: + .inst 0xd503233f + stp x29, x30, [sp,#-16]! + add x29, sp , #0 + + ldp x14, x15, [x1] + ldp x16, x17, [x1,#16] + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + + bl ECP256_AddCore // ret = a+a // 2*a + + ldp x29, x30, [sp], #16 + .inst 0xd50323bf + ret +.size ECP256_MulBy2,.-ECP256_MulBy2 + +.globl ECP256_MulBy3 +.type ECP256_MulBy3,%function +.align 4 +ECP256_MulBy3: + .inst 0xd503233f + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + ldp x14, x15, [x1] + ldp x16, x17, [x1, #16] + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + // Backup, used for the second addition, to reduce the number of reads from the memory. + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + + // x14~x17 + x8~x11 + bl ECP256_AddCore // 2*a = a + a + + mov x8 , x4 + mov x9 , x5 + mov x10, x6 + mov x11, x7 + + // x14~x17 + x8~x11 + bl ECP256_AddCore // 3*a = 2*a + a + + ldp x29, x30, [sp], #16 + .inst 0xd50323bf + ret +.size ECP256_MulBy3,.-ECP256_MulBy3 + +.type ECP256_MulCore,%function +.align 4 +ECP256_MulCore: + ldr x3 , [x2] // b[0] + + mul x14, x4 , x3 + umulh x8 , x4 , x3 + mul x15, x5 , x3 + umulh x9 , x5 , x3 + mul x16, x6 , x3 + umulh x10, x6 , x3 + mul x17, x7 , x3 + umulh x11, x7 , x3 + + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adc x19, xzr, x11 // x19 = x11 + CF + mov x20, xzr + + lsl x8 , x14, #32 // In this case, x14 stores the lower 32 bits of the lo(a[0]*b[i]), x8 = lo(a[0]*b[i]). + // The lower 32 bits are shifted to the left by 32 bits, and 0s are padded to the lower bits. + lsr x9 , x14, #32 // x9 = The most significant 32 bits of lo(a[0]*b[i]) are shifted rightward by 32 bits + // and 0s are padded to the most significant bits. + subs x10, x14, x8 + sbc x11, x14, x9 + + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adcs x17, x19, x11 + adc x19, x20, xzr + + ldr x3 , [x2, #8] // b[1] + + // lo(a[0~3] * b[i]) + mul x8 , x4 , x3 + mul x9 , x5 , x3 + mul x10, x6 , x3 + mul x11, x7 , x3 + + adds x14, x14, x8 + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x19, x19, xzr + + // hi(a[0~3] * b[i]) + umulh x8 , x4 , x3 + umulh x9 , x5 , x3 + umulh x10, x6 , x3 + umulh x11, x7 , x3 + + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adcs x19, x19, x11 + adc x20, xzr, xzr + + lsl x8 , x14, #32 // In this case, x14 stores the lower 32 bits of the lo(a[0]*b[i]), + // x8 = lo(a[0]*b[i]). The lower 32 bits are shifted to the left by 32 bits, + // and 0s are padded to the lower bits. + lsr x9 , x14, #32 // x9 = The most significant 32 bits of lo(a[0]*b[i]) are shifted rightward + // by 32 bits and 0s are padded to the most significant bits. + subs x10, x14, x8 + sbc x11, x14, x9 + + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adcs x17, x19, x11 + adc x19, x20, xzr + + ldr x3 , [x2, #8*2] // b[2] + + // lo(a[0~3] * b[i]) + mul x8 , x4 , x3 + mul x9 , x5 , x3 + mul x10, x6 , x3 + mul x11, x7 , x3 + + adds x14, x14, x8 + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x19, x19, xzr + + // hi(a[0~3] * b[i]) + umulh x8 , x4 , x3 + umulh x9 , x5 , x3 + umulh x10, x6 , x3 + umulh x11, x7 , x3 + + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adcs x19, x19, x11 + adc x20, xzr, xzr + + lsl x8 , x14, #32 // x8 = lq<<32 + lsr x9 , x14, #32 // x9 = hq + subs x10, x14, x8 // x10 = q - lq<<32 + sbc x11, x14, x9 // x11 = q - hq + + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adcs x17, x19, x11 + adc x19, x20, xzr + + ldr x3 , [x2, #8*3] // b[3] + + // lo(a[0~3] * b[i]) + mul x8 , x4 , x3 + mul x9 , x5 , x3 + mul x10, x6 , x3 + mul x11, x7 , x3 + + adds x14, x14, x8 + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x19, x19, xzr + + // hi(a[0~3] * b[i]) + umulh x8 , x4 , x3 + umulh x9 , x5 , x3 + umulh x10, x6 , x3 + umulh x11, x7 , x3 + + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adcs x19, x19, x11 + adc x20, xzr, xzr + + // last reduction + lsl x8 , x14, #32 // In this case, x14 stores the lower 32 bits of the lo(a[0]*b[i]), + // x8 = The lower 32 bits of (lo(a[0]*b[i])) are shifted to the left by 32 bits, + // and 0s are padded to the lower bits. + lsr x9 , x14, #32 // x9 = The most significant 32 bits of (lo(a[0]*b[i])) are shifted rightward + // by 32 bits and 0s are padded to the most significant bits. + subs x10, x14, x8 + sbc x11, x14, x9 + + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adcs x17, x19, x11 + adc x19, x20, xzr + + // x8~x11 = r - p (r may be greater than p) + adds x8 , x14, #1 // x8 = x14 - 0xffffffffffffffff = x14 + 1 + sbcs x9 , x15, x12 // x9 = x15 - 0x00000000ffffffff + sbcs x10, x16, xzr // x10 = x16 - 0 + sbcs x11, x17, x13 // x11 = x17 - 0xffffffff00000001 + sbcs xzr, x19, xzr // Determine whether to borrow + + csel x14, x14, x8 , lo + csel x15, x15, x9 , lo + csel x16, x16, x10, lo + csel x17, x17, x11, lo + + stp x14, x15, [x0] + stp x16, x17, [x0, #8*2] + + ret +.size ECP256_MulCore, .-ECP256_MulCore + + +.type ECP256_SqrCore,%function +.align 4 +ECP256_SqrCore: +/****************************************** + x7 x1 x20 x19 x17 x16 x15 x14 + h0*1 l0*1 + h0*2 l0*2 + h0*3 l0*3 + h1*2 l1*2 + h1*3 l1*3 + h2*3 l2*3 + h3*3 l3*3 h2*2 l2*2 h1*1 l1*1 h0*0 l0*0 +*******************************************/ + + // a[1~3] * a[0] + mul x15, x5 , x4 // lo(a[1] * a[0]) + umulh x8 , x5 , x4 // hi(a[1] * a[0]) + mul x16, x6 , x4 // lo(a[2] * a[0]) + umulh x9 , x6 , x4 // hi(a[2] * a[0]) + mul x17, x7 , x4 // lo(a[3] * a[0]) + umulh x19, x7 , x4 // hi(a[3] * a[0]) + + adds x16, x16, x8 + adcs x17, x17, x9 + adc x19, x19, xzr // There will be no more carry. + + // a[2~3] * a[1] + mul x8 , x6 , x5 // lo(a[2] * a[1]) + umulh x9 , x6 , x5 // hi(a[2] * a[1]) + mul x10, x7 , x5 // lo(a[3] * a[1]) + umulh x11, x7 , x5 // hi(a[3] * a[1]) + + // a[3] * a[2] + mul x20, x7 , x6 + umulh x1 , x7 , x6 + + // Add the results of the current round, and then add the acc (register in the note above). + adds x9 , x10, x9 + adc x10, x11, xzr + + adds x17, x17, x8 + adcs x19, x19, x9 + adcs x20, x20, x10 + adc x1 , x1 , xzr // a[0-3] has been saved in x4 to x7. + + // a[0~3] ^ 2 + mul x14, x4 , x4 + umulh x4 , x4 , x4 + mul x8 , x5 , x5 + umulh x5 , x5 , x5 + mul x9 , x6 , x6 + umulh x6 , x6 , x6 + mul x10, x7 , x7 + umulh x7 , x7 , x7 + + // acc[1~6] << 1 + adds x15, x15, x15 + adcs x16, x16, x16 + adcs x17, x17, x17 + adcs x19, x19, x19 + adcs x20, x20, x20 + adcs x1 , x1 , x1 + adc x2 , xzr, xzr + + // acc[] += a[] ^ 2 + adds x15, x15, x4 + adcs x16, x16, x8 + adcs x17, x17, x5 + adcs x19, x19, x9 + adcs x20, x20, x6 + adcs x1 , x1 , x10 + adc x7 , x7 , x2 + + // Four rounds of reduce. + lsl x8 , x14, #32 + lsr x9 , x14, #32 + subs x10, x14, x8 + sbc x11, x14, x9 + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adc x17, x11, xzr + + lsl x8 , x14, #32 + lsr x9 , x14, #32 + subs x10, x14, x8 + sbc x11, x14, x9 + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adc x17, x11, xzr + + lsl x8 , x14, #32 + lsr x9 , x14, #32 + subs x10, x14, x8 + sbc x11, x14, x9 + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adc x17, x11, xzr + + lsl x8 , x14, #32 + lsr x9 , x14, #32 + subs x10, x14, x8 + sbc x11, x14, x9 + adds x14, x15, x8 + adcs x15, x16, x9 + adcs x16, x17, x10 + adc x17, x11, xzr + + // Add acc[4-7]. x14~x19 is the current calculation result r. + adds x14, x14, x19 + adcs x15, x15, x20 + adcs x16, x16, x1 + adcs x17, x17, x7 + adc x19, xzr, xzr + + // r -= p + adds x8 , x14, #1 // subs x8,x14,#-1 + sbcs x9 , x15, x12 + sbcs x10, x16, xzr + sbcs x11, x17, x13 + sbcs xzr, x19, xzr // The set CF is used to determine the size relationship between r and p. + + // r = r-p < 0 ? r : r-p + csel x14, x14, x8 , lo + csel x15, x15, x9 , lo + csel x16, x16, x10, lo + csel x17, x17, x11, lo + + stp x14, x15, [x0] + stp x16, x17, [x0, #16] + + ret +.size ECP256_SqrCore,.-ECP256_SqrCore + +.globl ECP256_Mul +.type ECP256_Mul,%function +.align 4 +ECP256_Mul: + .inst 0xd503233f + stp x29, x30, [sp, #-32]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + + ldp x4 , x5 , [x1] + ldp x6 , x7 , [x1,#16] + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + + bl ECP256_MulCore + + ldp x19, x20, [sp , #16] + ldp x29, x30, [sp], #32 + .inst 0xd50323bf + ret +.size ECP256_Mul,.-ECP256_Mul + +.globl ECP256_Sqr +.type ECP256_Sqr,%function +.align 4 +ECP256_Sqr: + .inst 0xd503233f + stp x29, x30, [sp, #-32]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + + ldp x4 , x5 , [x1] + ldp x6 , x7 , [x1, #16] + ldr x12, .Lpoly+8 + ldr x13, .Lpoly+24 + + bl ECP256_SqrCore + + ldp x19, x20, [sp , #16] + ldp x29, x30, [sp], #32 + .inst 0xd50323bf + ret +.size ECP256_Sqr,.-ECP256_Sqr + +.globl ECP256_AddAffine +.type ECP256_AddAffine,%function +.align 5 +ECP256_AddAffine: + .inst 0xd503233f // paciasp + + stp x29, x30, [sp, #-80]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp x25, x26, [sp, #64] + sub sp , sp , #32*10 // Each coordinate is 256 bits, that is, 32 bytes, and a space of 10 coordinates is applied for. + // Based on C implementation, z1sqr and S2 lifecycles do not overlap. + // You can share one piece of memory and save an extra piece of memory. + + // x0 to x2 will be used to invoke the interface to transfer parameters. + // Therefore, the initial input parameters are saved to x21 to x23. + // Obtains the structure members based on the address offset. Each member is 256 bits, that is, 32 bytes. + mov x21, x0 // CRYPT_P256_Point *r + mov x22, x1 // CRYPT_P256_Point *a + mov x23, x2 // CRYPT_P256_AffinePoint *b + + ldr x12, .Lpoly+8 // p[1] + ldr x13, .Lpoly+24 // p[3] + + + ldp x4, x5, [x1, #64] // x1+64 = &(a->z[0]), a->z[0] is marked as z1[0] + ldp x6, x7, [x1, #64+16] // x1+64+16 = &(a->z[2]) + + orr x24, x4 , x5 // x24 = z1[0] | z1[1] + orr x24, x24, x6 // x24 |= z1[2] + orr x24, x24, x7 // x24 |= z1[3] + cmp x24, #0 + csetm x24, ne // x24 = x24!=0 ? -1 : 0, it means ~iszero(z1), + // determine whether point a is (x, y, 0) + + ldp x8 , x9 , [x2] // x2 = &(b->x[0]), b->x[0] is marked as x2[0] + ldp x10, x11, [x2, #16] // x2+16 = &(b->x[2]) + ldp x14, x15, [x2, 32] // x2+32 = &(b->y[0]) + ldp x16, x17, [x2, #32+16] // x2+32+16 = &(b->y[2]) + + // x25 = x2[0] | x2[1] | x2[2] | x2[3] | y2[0] | y2[1] | y2[2] | y2[3] + orr x25, x8 , x9 + orr x25, x25, x10 + orr x25, x25, x11 + orr x25, x25, x14 + orr x25, x25, x15 + orr x25, x25, x16 + orr x25, x25, x17 + cmp x25, #0 + csetm x25, ne // x25 = x25!=0 ? -1 : 0, it means ~iszero(x2|y2), + // Check whether point b is (0, 0). + + add x0 , sp , #32*3 // zsqr = sp[32*3] + // x4~x7 = z1[0~3] (the value has been assigned.) + bl ECP256_SqrCore // zsqr = z1^2 + // x14~x17 also temporarily stored results + + // The next calculation requires the zsqr calculation result as the input. + // The calculation result is stored in x4 to x7 in advance to prevent x14 to x17 from being overwritten + // by the next calculation. Therefore, the calculation result needs to be read from the memory. + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + + add x0 , sp , #32*4 // u2 = sp[32*4] + add x2 , x23, #0 // x2 points to b->x. + // x4~x7 * [x2] + bl ECP256_MulCore // u2 = z1^2 * x2 + // x14~x17 also temporarily stored results. + + ldp x8 , x9 , [x22] // a->x + ldp x10, x11, [x22, #16] + add x0 , sp , #32*5 // h = sp[32*5] + // x14~x17 - x8~x11 + bl ECP256_SubCore1 // h = u2 - x1 + + ldp x4 , x5 , [sp, #32*3] // zsqr = sp[32*3] + ldp x6 , x7 , [sp, #32*3+16] + add x2 , x22, #64 // x2 points to a->z + add x0 , sp , #32*3 // s2 = sp[32*3], zsqr will not be used later. + // You can use this block memory to store and calculate s2. + bl ECP256_MulCore // s2 = zsqr * z1 = z1^3 + + ldp x4 , x5 , [sp, #32*5] // x4~x7 = h = sp[32*5] + ldp x6 , x7 , [sp, #32*5+16] + add x2 , x22, #64 + add x0 , sp , #32*2 // x0 points to res_z. + bl ECP256_MulCore // res_z = h * z1 + + ldp x4 , x5 , [sp, #32*3] // x4~x7 = s2 = sp[32*3] + ldp x6 , x7 , [sp, #32*3+16] + add x2 , x23, #32 // x2 points to b->y. + add x0 , sp , #32*3 // s2 = sp[32*3] + bl ECP256_MulCore // s2 = s2 * y2 = y2 * z1^3 + + ldp x8 , x9 , [x22, #32] + ldp x10, x11, [x22, #32+16] + add x0 , sp , #32*6 // R = sp[32*6] + // x14~x17 - x8~x11 + bl ECP256_SubCore1 // R = s2 - y1 + + // Rsqr = R^2 and hsqr = h^2 are independent of each other. The sequence can be adjusted. + // If Rsqr is calculated first, the memory can be read less once. (The pipeline bubble needs to be optimized.) + // In addition, the calculated hsqr can read less memory in hcub = hsqr x h. + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x0 , sp , #32*7 // Rsqr = sp[32*7] + bl ECP256_SqrCore // Rsqr = R^2 + + ldp x4 , x5 , [sp, #32*5] // h = sp[32*5] + ldp x6 , x7 , [sp, #32*5+16] + add x0 , sp , #32*8 // hsqr = sp[32*8] + bl ECP256_SqrCore // hsqr = h^2 + + // x14 to x17 stores the hsqr results and does not need to be read from the memory. + // (The pipeline bubble exists and needs to be optimized.) + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , sp , #32*5 // h = sp[32*5] + add x0 , sp , #32*9 // hcub = sp[32*9] + bl ECP256_MulCore // hcub = hsqr * h = h^3 + + // Because the multiplication involves too many registers, the preceding hsqr cannot be backed up. + // If the registers after x19 are used, the hsqr needs to be pushed and popped at the beginning + // and end of the stack, which outweighs the gain. Therefore, the hsqr can only be read from the memory. + ldp x4 , x5 , [sp, #32*8] // hsqr = sp[32*8] + ldp x6 , x7 , [sp, #32*8+16] + add x2 , x22, #0 // x2 points to a->x + add x0 , sp , #32*4 // u2 = sp[32*4] + bl ECP256_MulCore // u2 = hsqr * x1 + + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + add x0 , sp , #32*8 // hsqr = sp[32*8] + // x14~x17 + x8~x11 + bl ECP256_AddCore // hsqr = 2 * u2 + + // x14~x17 saves hsqr, so sub_morf is called. + ldp x8 , x9 , [sp, #32*7] // Rsqr = sp[32*7] + ldp x10, x11, [sp, #32*7+16] + // x8~x11 - x14~x17 + add x0 , sp , #0 // x0 points to res_x + bl ECP256_SubCore2 // res_x = Rsqr - hsqr + + // x14~x17 save res_x, so call sub_from + ldp x8 , x9 , [sp, #32*9] // hcub = sp[32*9] + ldp x10, x11, [sp, #32*9+16] + // x14~x17 - x8~x11 + bl ECP256_SubCore1 // res_x = res_x - hcub + + // x14~x17 save res_x, so call sub_morf + ldp x8 , x9 , [sp, #32*4] // u2 = sp[32*4] + ldp x10, x11, [sp, #32*4+16] + add x0 , sp , #32*1 + bl ECP256_SubCore2 // res_y = u2 - res_x + + ldp x4 , x5 , [sp, #32*9] // hcub = sp[32*9] + ldp x6 , x7 , [sp, #32*9+16] + add x2 , x22, #32 // y1 = a->y + add x0 , sp , #32*3 // s2 = sp[32*3] + bl ECP256_MulCore // s2 = y1 * hcub + + add x2 , sp , #32*6 // R = sp[32*6] + add x0 , sp , #32*1 // res_y = sp[32*1] + ldp x4 , x5 , [x0] + ldp x6 , x7 , [x0, #16] + bl ECP256_MulCore // res_y = res_y * R + + // x14–x17 stores res_y, and x0 is still res_y. No value needs to be assigned again. + ldp x8 , x9 , [sp, #32*3] // s2 = sp[32*3] + ldp x10, x11, [sp, #32*3+16] + // x14~x17 - x8~x11 + bl ECP256_SubCore1 // res_y = res_y - s2 + + + // Four memory blocks are not read. (The pipeline bubble exists and needs to be optimized.) + // x14-x17 stores res_y. Therefore, res_y is judged and assigned a value. + // copy y + ldp x4 , x5 , [x23, #32] // in2_y, b->y + ldp x6 , x7 , [x23, #32+16] + ldp x8 , x9 , [x22, #32] // in1_y, a->y + ldp x10, x11, [x22, #32+16] + + // res_y = in1infty == 0 ? res_y : in2_y + cmp x24, #0 // x24 = ~in1infty + csel x14, x14, x4 , ne + csel x15, x15, x5 , ne + csel x16, x16, x6 , ne + csel x17, x17, x7 , ne + // res_y = in2infty == 0 ? res_y : in1_y + cmp x25, #0 // x25 = ~in2infty + csel x14, x14, x8 , ne + csel x15, x15, x9 , ne + csel x16, x16, x10, ne + csel x17, x17, x11, ne + + stp x14, x15, [x21, #32] + stp x16, x17, [x21, #32+16] + + // copy x + ldp x4 , x5 , [x23] // in2_x, b->x + ldp x6 , x7 , [x23, #16] + ldp x8 , x9 , [x22] // in1_x, a->x + ldp x10, x11, [x22, #16] + ldp x14, x15, [sp] // res_x + ldp x16, x17, [sp , #16] + + // res_x = in1infty == 0 ? res_x : in2_x + cmp x24, #0 // x24 = ~in1infty + csel x14, x14, x4 , ne + csel x15, x15, x5 , ne + csel x16, x16, x6 , ne + csel x17, x17, x7 , ne + // res_x = in2infty == 0 ? res_x : in1_x + cmp x25, #0 // x25 = ~in2infty + csel x14, x14, x8 , ne + csel x15, x15, x9 , ne + csel x16, x16, x10, ne + csel x17, x17, x11, ne + + stp x14, x15, [x21] + stp x16, x17, [x21, #16] + + // copy z + adrp x23, .Lone_mont + add x23, x23, :lo12:.Lone_mont + ldp x4 , x5 , [x23] // one_mont, 1 * RR * R' = R (mod p) + ldp x6 , x7 , [x23, #16] + ldp x8 , x9 , [x22, #64] // in1_z, a->z + ldp x10, x11, [x22, #64+16] + ldp x14, x15, [sp , #64] // res_z + ldp x16, x17, [sp , #64+16] + + // res_z = in1infty == 0 ? res_z : ONE + cmp x24, #0 // x24 = ~in1infty + csel x14, x14, x4 , ne + csel x15, x15, x5 , ne + csel x16, x16, x6 , ne + csel x17, x17, x7 , ne + // res_z = in2infty == 0 ? res_z : in1_z + cmp x25, #0 // x25 = ~in2infty + csel x14, x14, x8 , ne + csel x15, x15, x9 , ne + csel x16, x16, x10, ne + csel x17, x17, x11, ne + + stp x14, x15, [x21, #64] + stp x16, x17, [x21, #64+16] + + add sp , x29, #0 + ldp x19, x20, [x29, #16] + ldp x21, x22, [x29, #32] + ldp x23, x24, [x29, #48] + ldp x25, x26, [x29, #64] + ldp x29, x30, [sp], #80 + .inst 0xd50323bf // autiasp + ret +.size ECP256_AddAffine,.-ECP256_AddAffine + +.globl ECP256_PointAdd +.type ECP256_PointAdd,%function +.align 5 +ECP256_PointAdd: + .inst 0xd503233f // paciasp + stp x29, x30, [sp, #-96]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp x25, x26, [sp, #64] + stp x27, x28, [sp, #80] + sub sp , sp , #32*12 // Each coordinate is 256 bits, that is, 32 bytes, + // and a space of 10 coordinates is applied for. + + ldr x12, .Lpoly+8 // p[1] = 0x00000000ffffffff, p[0] = -1, no need to read + ldr x13, .Lpoly+24 // p[3] = 0xffffffff00000001, p[2] = 0 , no need to read + + // Pointer to the initial backup input parameter. + // x0 to x2 are used to transfer parameters when the interface is invoked. + mov x21, x0 + mov x22, x1 + mov x23, x2 + + ldp x4 , x5 , [x22, #64] // z1 + ldp x6 , x7 , [x22, #64+16] + // x24 = z1[0] | z1[1] | z1[2] | z1[3] + orr x24, x4 , x5 + orr x24, x24, x6 + orr x24, x24, x7 // x24 = ~in1infty + cmp x24, #0 + csetm x24, ne // x24 = (x24 != 0) ? -1 : 0, that is ~iszero(z1), + // Determine whether point a is(x, y, 0) + + // Because x4 to x7 exactly hold z1, z1^2 can be calculated first. + add x0 , sp , #0 // z1sqr = sp[32*0] + bl ECP256_SqrCore // z1sqr = z1^2 + + // x14 to x17 exactly save the z1sqr result (the pipeline bubble exists and needs to be optimized). + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , x22, #64 // x2 points to z1, that is a->z + add x0 , sp , #32*1 // s2 = sp[32*1] + bl ECP256_MulCore // s2 = z1^3 + + // x14 to x17 exactly save the result of s2. (The pipeline bubble exists and needs to be optimized.) + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , x23, #32 // x2 points to y2, that is b->y + // add x0 , sp , #32*1 // s2 = sp[32*1], x0 It is exactly s2 and does not need to be set. + // (There are pipeline bubbles to be optimized.) + bl ECP256_MulCore // s2 = y2 * z1^3 + + ldp x4 , x5 , [x23, #64] // z2 + ldp x6 , x7 , [x23, #64+16] + // x25 = z2[0] | z2[1] | z2[2] | z2[3] + orr x25, x4 , x5 + orr x25, x25, x6 + orr x25, x25, x7 // x25 = ~in2infty + cmp x25, #0 + csetm x25, ne // x25 = (x25 != 0) ? -1 : 0, that is ~iszero(z2), + // Check whether point b is(x, y, 0) + + // Because x4~x7 happens to hold z2, z2^2 can be calculated + add x0 , sp , #32*2 // z2sqr = sp[32*2] + bl ECP256_SqrCore // z2sqr = z2^2 + + // x14 to x17 exactly save the z2sqr result. (There are pipeline bubbles to be optimized.) + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , x23, #64 // x2 points to z2, that is b->z + add x0 , sp , #32*3 // s1 = sp[32*3] + bl ECP256_MulCore // s1 = z2^3 + + // x14 to x17 exactly save the result of s2. (The pipeline bubble exists and needs to be optimized.) + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , x22, #32 // x2 points to y1, that is a->y + // add x0 , sp , #32*3 // s1 = sp[32*3], x0 is exactly s1 and does not need to be set. + // (There are pipeline bubbles to be optimized.) + bl ECP256_MulCore // s1 = y1 * z2^3 + + + // x14 to x17 save the result of s1. Therefore, the sub_morf interface is selected. + ldp x8 , x9 , [sp, #32*1] // s2 = sp[32*1] + ldp x10, x11, [sp, #32*1+16] + // x8~x11 - x14~x17 + add x0 , sp , #32*4 // R = sp[32*4] + bl ECP256_SubCore2 // R = s2 - s1 + + // x14 to x17 save the result of R, (R==0) <==> (s2 == s1) + orr x26, x14, x15 + orr x26, x26, x16 + orr x26, x26, x17 // x26 = ~(s1 == s2), The data of R is not read from the memory in advance. + + ldp x4 , x5 , [x22] // Take x1, that is a->x + ldp x6 , x7 , [x22, #16] + add x2 , sp , #32*2 // z2sqr = sp[32*2] + add x0 , sp , #32*5 // u1 = sp[32*5] + bl ECP256_MulCore // u1 = x1 * z2sqr + + ldp x4 , x5 , [x23] // Take x2, that is b->x + ldp x6 , x7 , [x23, #16] + add x2 , sp , #0 // z1sqr = sp[32*0] + add x0 , sp , #32*6 // u2 = sp[32*6] + bl ECP256_MulCore // u2 = x2 * z1sqr + + // x14 to x17 save the result of u2. Therefore, the sub_from interface is selected. + ldp x8 , x9 , [sp, #32*5] // u1 = sp[32*5] + ldp x10, x11, [sp, #32*5+16] + // x14~x17 - x8~x11 + add x0 , sp , #32*7 // h = sp[32*7] + bl ECP256_SubCore1 // h = u2 - u1 + + // x14 to x17 save the result of h, (h==0) <==> (u2 == u1) + orr x14, x14, x15 + orr x14, x14, x16 + orr x14, x14, x17 // x14 = ~(u1 == u2), It is used for subsequent judgment. + // The data of h does not need to be read from the memory in advance. + + // x24 = ~in2infty + // x25 = ~in1infty + // x26 = ~(s1 == s2) = ~is_equal(S1, S2) + // x14 = ~(u1 == u2) = ~is_equal(U1, U2) + // if(is_equal(U1, U2) & ~in1infty & ~in2infty & is_equal(S1, S2)) + // 将(is_equal(U1, U2) & ~in1infty & ~in2infty & is_equal(S1, S2))记为flag + // <==> + // if ((~is_equal(U1, U2) | in1infty | in2infty | ~is_equal(S1, S2)) == 0) + // if (flag == 0) + + mvn x27, x24 // x27 = in1infty + mvn x28, x25 // x28 = in2infty + + orr x14, x14, x26 + orr x14, x14, x27 + orr x14, x14, x28 + cbnz x14, .Lpoint_add // flag != 0, Continue calculation by C implementation + +.Ladd_double: + mov x0 , x21 // x0 = r + mov x1 , x22 // x1 = a + ldp x23, x24, [x29, #48] // The double function uses only x19 to x22, and only x19 to x22 + // is popped at the end. Therefore, x23 to x28 is popped in advance. + ldp x25, x26, [x29, #64] + ldp x27, x28, [x29, #80] + add sp , sp , #32*(12-4) // The size of the stack space used varies. The double function + // only releases 32 x 4. Therefore, you need to release part of the stack space in advance. + b .Lpoint_double + +.align 4 +.Lpoint_add: + ldp x4 , x5 , [sp, #32*4] // R = sp[32*4] + ldp x6 , x7 , [sp, #32*4+16] + add x0 , sp , #0 // Rsqr = sp[0], Because z1sqr will not be used later, + // this memory can be used to save Rsqr. + bl ECP256_SqrCore // Rsqr = R^2 + + ldp x4 , x5 , [sp, #32*7] // h = sp[32*7] + ldp x6 , x7 , [sp, #32*7+16] + add x2 , x22, #64 // x2 points to z1 + add x0 , sp , #32*11 // res_z = sp[32*11] + bl ECP256_MulCore // res_z = h * z1 + + // The res_z result is stored in x14 to x17. (The pipeline bubble needs to be optimized.) + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , x23, #64 // x2 points to z2 + // x0 is still res_z and does not need to be reassigned. + // add x0 , sp , #32*11 // res_z = sp[32*11] + bl ECP256_MulCore // res_z = res_z * z2 + + ldp x4 , x5 , [sp, #32*7] // h = sp[32*7] + ldp x6 , x7 , [sp, #32*7+16] + add x0 , sp , #32*2 // hsqr = sp[32*2], Because z2sqr will not be used later, + // you can use this memory to save hsqr. + bl ECP256_SqrCore + + // The hsqr result is stored in x14 to x17. (The pipeline bubble needs to be optimized.) + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , sp , #32*7 // h = sp[32*7] + add x0 , sp , #32*8 // hcub = sp[32*8] + bl ECP256_MulCore // hcub = hsqr * h + + ldp x4 , x5 , [sp, #32*5] // u1 = sp[32*5] + ldp x6 , x7 , [sp, #32*5+16] + add x2 , sp , #32*2 // hsqr = sp[32*2] + add x0 , sp , #32*6 // u2 = sp[32*6] + bl ECP256_MulCore // u2 = u1 * hsqr + + // x14~x17 exactly save the result of u2. + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + // add x0 , sp , #32*2 // hsqr = sp[32*2] + // The previous operation x2 also saves the address of hsqr. + mov x0 , x2 + // x14~x17 + x8~x11 + bl ECP256_AddCore // hsqr = 2 * u2 + + // x14 to x17 save the hsqr result. Therefore, sub_morf is called. + ldp x8 , x9 , [sp] // Rsqr = sp[0] + ldp x10, x11, [sp, #16] + // x8~x11 - x14~x17 + add x0 , sp , #32*9 // res_x = sp[32*9] + bl ECP256_SubCore2 // res_x = Rsqr - hsqr + + // x14 to x17 exactly save the result of res_x, so sub_from is called. + ldp x8 , x9 , [sp, #32*8] // hcub = sp[32*8] + ldp x10, x11, [sp, #32*8+16] + // x14~x17 - x8~11 + // The previous operation x0 also stores the address of res_x. + bl ECP256_SubCore1 // res_x = res_x - hcub + + // x14 to x17 exactly save the result of res_x. Therefore, sub_morf is called. + ldp x8 , x9 , [sp, #32*6] // u2 = sp[0] + ldp x10, x11, [sp, #32*6+16] + // x8~x11 - x14~x17 + add x0 , sp , #32*10 + bl ECP256_SubCore2 // res_y = u2 - res_x + + ldp x4 , x5 , [sp, #32*3] // s1 = sp[32*3] + ldp x6 , x7 , [sp, #32*3+16] + add x2 , sp , #32*8 // hcub = sp[32*8] + add x0 , sp , #32*1 // s2 = sp[32*1] + bl ECP256_MulCore // s2 = s1 * hcub + + add x2 , sp , #32*4 // R = sp[32*4] + add x0 , sp , #32*10 // res_y = sp[32*10] + ldp x4 , x5 , [x0] // res_y = sp[32*10], Borrowing x0 address without offset + ldp x6 , x7 , [x0, #16] + bl ECP256_MulCore // res_y = res_y * R + + // x14 to x17 exactly save the result of res_y. Therefore, sub_from is called. + ldp x8 , x9 , [sp, #32] // s2 = sp[32*1] + ldp x10, x11, [sp, #32+16] + // x14~x17 - x8~x11 + // The previous operation x0 also stores the address of res_y. + bl ECP256_SubCore1 // res_y = res_y - s2 + + // Four memory blocks are not read. (The pipeline bubble exists and needs to be optimized.) + // x14-x17 stores res_y. Therefore, res_y is judged and assigned a value. + // copy y + ldp x4 , x5 , [x23, #32] // in2_y, b->y + ldp x6 , x7 , [x23, #32+16] + ldp x8 , x9 , [x22, #32] // in1_y, a->y + ldp x10, x11, [x22, #32+16] + + // res_y = in1infty == 0 ? res_y : in2_y + cmp x24, #0 // x24 = ~in1infty + csel x14, x14, x4 , ne + csel x15, x15, x5 , ne + csel x16, x16, x6 , ne + csel x17, x17, x7 , ne + // res_y = in2infty == 0 ? res_y : in1_y + cmp x25, #0 // x25 = ~in2infty + csel x14, x14, x8 , ne + csel x15, x15, x9 , ne + csel x16, x16, x10, ne + csel x17, x17, x11, ne + + stp x14, x15, [x21, #32] + stp x16, x17, [x21, #32+16] + + // copy x + ldp x4 , x5 , [x23] // in2_x, b->x + ldp x6 , x7 , [x23, #16] + ldp x8 , x9 , [x22] // in1_x, a->x + ldp x10, x11, [x22, #16] + ldp x14, x15, [sp , #32*9] // res_x + ldp x16, x17, [sp , #32*9+16] + + // res_x = in1infty == 0 ? res_x : in2_x + cmp x24, #0 // x24 = ~in1infty + csel x14, x14, x4 , ne + csel x15, x15, x5 , ne + csel x16, x16, x6 , ne + csel x17, x17, x7 , ne + // res_x = in2infty == 0 ? res_x : in1_x + cmp x25, #0 // x25 = ~in2infty + csel x14, x14, x8 , ne + csel x15, x15, x9 , ne + csel x16, x16, x10, ne + csel x17, x17, x11, ne + + stp x14, x15, [x21] + stp x16, x17, [x21, #16] + + // copy z + ldp x4 , x5 , [x23, #64] // in2_z, b->z + ldp x6 , x7 , [x23, #64+16] + ldp x8 , x9 , [x22, #64] // in1_z, a->z + ldp x10, x11, [x22, #64+16] + ldp x14, x15, [sp , #32*11] // res_z + ldp x16, x17, [sp , #32*11+16] + + // res_z = in1infty == 0 ? res_z : in2_z + cmp x24, #0 // x24 = ~in1infty + csel x14, x14, x4 , ne + csel x15, x15, x5 , ne + csel x16, x16, x6 , ne + csel x17, x17, x7 , ne + // res_z = in2infty == 0 ? res_z : in1_z + cmp x25, #0 // x25 = ~in2infty + csel x14, x14, x8 , ne + csel x15, x15, x9 , ne + csel x16, x16, x10, ne + csel x17, x17, x11, ne + + stp x14, x15, [x21, #64] + stp x16, x17, [x21, #64+16] + + add sp , x29, #0 // Free temporary variable + ldp x19, x20, [x29, #16] + ldp x21, x22, [x29, #32] + ldp x23, x24, [x29, #48] + ldp x25, x26, [x29, #64] + ldp x27, x28, [x29, #80] + ldp x29, x30, [sp], #96 + .inst 0xd50323bf // Autiasp + ret +.size ECP256_PointAdd,.-ECP256_PointAdd + +.globl ECP256_PointDouble +.type ECP256_PointDouble,%function +.align 5 +ECP256_PointDouble: + .inst 0xd503233f // Paciasp + stp x29, x30, [sp, #-96]! // Why is 96 space given here? Only x19~x22 is stacked. Theoretically, only [sp, #-48] is required. + add x29, sp , #0 // Whether it is related to the Lpoint_double jump of the ecp_nistz256_point_add interface + stp x19, x20, [sp, #16] + stp x21, x22, [sp, #32] + sub sp , sp , #32*4 + +.Lpoint_double: + ldp x14, x15, [x1 , #32] // a->y + ldp x16, x17, [x1 , #32+16] + ldr x12 , .Lpoly+8 // p[1] + ldr x13 , .Lpoly+24 // p[3] + + // Back up the initial input parameter pointer r, a. + mov x21, x0 + mov x22, x1 + + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + add x0 , sp , #0 // s = sp[0] + bl ECP256_AddCore // s = 2 * a->y + + // x14 to x17 save the result of s. Calculate s^2 first. + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x0 , sp , #0 // s = sp[0] + bl ECP256_SqrCore // s = s^2 + + ldp x4 , x5 , [x22, #64] // a->z + ldp x6 , x7 , [x22, #64+16] + add x0 , sp , #32 // zsqr = sp[32*1] + bl ECP256_SqrCore // zsqr = (a->z)^2 + + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + ldp x8 , x9 , [x22] // a->x + ldp x10, x11, [x22, #16] + add x0 , sp , #64 // m = sp[32*2] + bl ECP256_AddCore // m = a->x + zsqr + + mov x14, x4 + mov x15, x5 + mov x16, x6 + mov x17, x7 + ldp x8 , x9 , [x22] // a->x + ldp x10, x11, [x22, #16] + add x0 , sp , #32 + bl ECP256_SubCore2 // zsqr = a->x - zsqr + + ldp x4 , x5 , [x22, #64] // a->z + ldp x6 , x7 , [x22, #64+16] + add x2 , x22, #32 // a->y + add x0 , x21, #64 // res_z + bl ECP256_MulCore // res_z = a->z * a->y + + // x14 to x17 save the result of res_z. + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + add x0 , x21, #64 // res_z + bl ECP256_AddCore // res_z = 2 * res_z + + ldp x4 , x5 , [sp] // s = sp[0] + ldp x6 , x7 , [sp, #16] + add x0 , x21, #32 // x0 points to res_y, that is r->y + bl ECP256_SqrCore // res_y = s^2 + + add x0 , x21, #32 + bl ECP256_DivBy2Core // res_y = res_y / 2 + + ldp x4 , x5 , [sp] // s = sp[0] + ldp x6 , x7 , [sp, #16] + add x2 , x22, #0 // a->x + add x0 , sp , #0 // s = sp[0] + bl ECP256_MulCore // s = s * a->x + + // x14~x17 exactly saves the result of s + mov x8 , x14 + mov x9 , x15 + mov x10, x16 + mov x11, x17 + add x0 , sp , #96 // tmp = sp[96] + bl ECP256_AddCore // tmp = 2 * s + + ldp x4 , x5 , [sp, #64] // m = sp[64] + ldp x6 , x7 , [sp, #64+16] + add x2 , sp , #32 // zsqr = sp[32] + add x0 , sp , #64 + bl ECP256_MulCore // m = m * zsqr + + // x14–x17 saves the result of m. Save an extra copy to x4–x7. + mov x8 , x14 + mov x4 , x14 + mov x9 , x15 + mov x5 , x15 + mov x10, x16 + mov x6 , x16 + mov x11, x17 + mov x7 , x17 + add x0 , sp , #64 + bl ECP256_AddCore // m = 2 * m + mov x8 , x4 + mov x9 , x5 + mov x10, x6 + mov x11, x7 + bl ECP256_AddCore // m = 3 * m + + // x14~x17 exactly saves the result of m. + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x0 , x21, #0 // res_x = r->x + bl ECP256_SqrCore // res_x = m^2 + + // x14~x17 exactly saves the result of res_x. + ldp x8 , x9 , [sp, #96] // tmp = sp[96] + ldp x10, x11, [sp, #96+16] + bl ECP256_SubCore1 // res_x = res_x - tmp + + // x14~x17 exactly saves the result of res_x, Therefore, sub_morf is invoked. + ldp x8 , x9 , [sp] // s = sp[0] + ldp x10, x11, [sp, #16] + add x0 , sp , #0 + bl ECP256_SubCore2 // s = s - res_x + + // x14~x17 exactly saves the result of s, x0 still points to s. + mov x4 , x14 + mov x5 , x15 + mov x6 , x16 + mov x7 , x17 + add x2 , sp , #64 // m = sp[64] + bl ECP256_MulCore // s = s * m + + // x14 to x17 just save the result of s, so call sub_from. + add x0 , x21, #32 // x0 points to res_y + ldp x8 , x9 , [x0] // res_y + ldp x10, x11, [x0, #16] + bl ECP256_SubCore1 // res_y = s - res_y + + add sp , x29, #0 // Free temporary variable + ldp x19, x20, [x29, #16] + ldp x21, x22, [x29, #32] + ldp x29, x30, [sp], #96 + .inst 0xd50323bf // Autiasp + ret +.size ECP256_PointDouble,.-ECP256_PointDouble + +.globl ECP256_OrdMul +.type ECP256_OrdMul,%function +.align 4 +ECP256_OrdMul: + stp x29, x30, [sp, #-64]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + + adrp x23, .Lord + add x23, x23, :lo12:.Lord // x23 = &n + ldp x12, x13, [x23] // n[0~3] + ldp x21, x22, [x23, #16] + ldr x23, [x23, #32] // x23 = LordK + + ldp x4 , x5 , [x1] // a[0~3] + ldp x6 , x7 , [x1, #16] + + ldr x3 , [x2] // x3 = b[0] + + mul x14, x4 , x3 // a[0~3] * b[0] + umulh x8 , x4 , x3 + mul x15, x5 , x3 + umulh x9 , x5 , x3 + mul x16, x6 , x3 + umulh x10, x6 , x3 + mul x17, x7 , x3 + umulh x11, x7 , x3 + + // a[0-3] * b[0] is stored in x14~x17, x19, x20. + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adc x19, xzr, x11 // x19 = x11 + CF + mov x20, xzr + + // reduce + // n[0] = 0xf3b9cac2fc632551 + // n[1] = 0xbce6faada7179e84 + // n[2] = 0xffffffffffffffff, lo(q*n[2]) = -q , hi(q*n[2]) = q + // n[3] = 0xffffffff00000000, lo(q*n[3]) = -lq<<32, hi(q*n[3]) = q-hq + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), Equivalent to q in Montgomery + // modular multiplication + + lsl x8 , x24, #32 // lq << 32 + lsr x9 , x24, #32 // hq + subs x16, x16, x24 // x16 = x16 + lo(q*n[2]) = x16 - q + sbcs x17, x17, x8 // x17 = x17 + lo(q*n[3]) = x17 - lq<<32 + sbcs x19, x19, x9 // x19 = x19 - hq, Should have added q-hq, here first subtract hq, then add q. + sbc x20, x20, xzr // x20 = x20 - CF + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + // First calculate the value to be added to the same accumulator. + subs xzr, x14, #1 // CF = (x14 < 1)? + adcs x10, x10, x9 // x10 = hi(q*n[0]) + lo(q*n[1]) + adc x11, x11, xzr // x11 = hi(q*n[1]) + CF + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adcs x17, x19, x24 // x17 = x19 + q, hq has been subtracted from x19 in front, + // so here x17 = hi(q*n[3]) + adc x19, x20, xzr // x19 = x20 + CF + + ldr x3 , [x2, #8] // b[1] + + mul x8 , x4 , x3 + mul x9 , x5 , x3 + mul x10, x6 , x3 + mul x11, x7 , x3 + + // add lo(a[0~3] * b[i]) + adds x14, x14, x8 + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x19, x19, xzr + + umulh x8 , x4 , x3 + umulh x9 , x5 , x3 + umulh x10, x6 , x3 + umulh x11, x7 , x3 + // add hi(a[0~3] * b[i]) + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adcs x19, x19, x11 + adc x20, xzr, xzr + + // reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q + // in Montgomery modular multiplication + + lsl x8 , x24, #32 + lsr x9 , x24, #32 + subs x16, x16, x24 + sbcs x17, x17, x8 + sbcs x19, x19, x9 + sbc x20, x20, xzr + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + subs xzr, x14, #1 + adcs x10, x10, x9 + adc x11, x11, xzr + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adcs x17, x19, x24 // x17 = x19 + q, hq has been subtracted from x19 in front, + // so here x17 = hi(q*n[3]) + adc x19, x20, xzr // x19 = x20 + CF + + ldr x3 , [x2, #16] // b[2] + + mul x8 , x4 , x3 + mul x9 , x5 , x3 + mul x10, x6 , x3 + mul x11, x7 , x3 + + // adds lo(a[0~3] * b[i]) + adds x14, x14, x8 + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x19, x19, xzr + + umulh x8 , x4 , x3 + umulh x9 , x5 , x3 + umulh x10, x6 , x3 + umulh x11, x7 , x3 + // adds hi(a[0~3] * b[i]) + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adcs x19, x19, x11 + adc x20, xzr, xzr + + // reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q in Montgomery + // modular multiplication + + lsl x8 , x24, #32 + lsr x9 , x24, #32 + subs x16, x16, x24 + sbcs x17, x17, x8 + sbcs x19, x19, x9 + sbc x20, x20, xzr + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + subs xzr, x14, #1 + adcs x10, x10, x9 + adc x11, x11, xzr + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adcs x17, x19, x24 // x17 = x19 + q, hq has been subtracted from x19 in front, + // so here x17 = hi(q*n[3]) + adc x19, x20, xzr // x19 = x20 + CF + + ldr x3 , [x2, #24] // b[3] + + mul x8 , x4 , x3 + mul x9 , x5 , x3 + mul x10, x6 , x3 + mul x11, x7 , x3 + + // add lo(a[0~3] * b[i]) + adds x14, x14, x8 + adcs x15, x15, x9 + adcs x16, x16, x10 + adcs x17, x17, x11 + adc x19, x19, xzr + + umulh x8 , x4 , x3 + umulh x9 , x5 , x3 + umulh x10, x6 , x3 + umulh x11, x7 , x3 + // add hi(a[0~3] * b[i]) + adds x15, x15, x8 + adcs x16, x16, x9 + adcs x17, x17, x10 + adcs x19, x19, x11 + adc x20, xzr, xzr + + // reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q in Montgomery + // modular multiplication. + + lsl x8 , x24, #32 + lsr x9 , x24, #32 + subs x16, x16, x24 + sbcs x17, x17, x8 + sbcs x19, x19, x9 + sbc x20, x20, xzr + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + subs xzr, x14, #1 + adcs x10, x10, x9 + adc x11, x11, xzr + + // S /= r, Accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adcs x17, x19, x24 // x17 = x19 + q, hq has been subtracted from x19 in front, so here x17 = hi(q*n[3]) + adc x19, x20, xzr // x19 = x20 + CF + + // So far, x14 to x17, and x19 retain the calculation results. + // x8~x11 save r -= n + subs x8 , x14, x12 + sbcs x9 , x15, x13 + sbcs x10, x16, x21 + sbcs x11, x17, x22 + sbcs xzr, x19, xzr // Finally, the CF bit is set to indicate whether r-n needs to be borrowed. + + // r = r-n < 0 ? r : r-n + csel x14, x14, x8 , lo + csel x15, x15, x9 , lo + csel x16, x16, x10, lo + csel x17, x17, x11, lo + + stp x14, x15, [x0] // Write the result to r + stp x16, x17, [x0, #16] + + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldr x29, [sp], #64 + ret +.size ECP256_OrdMul,.-ECP256_OrdMul + +.globl ECP256_OrdSqr +.type ECP256_OrdSqr,%function +.align 4 +ECP256_OrdSqr: + stp x29, x30, [sp, #-64]! + add x29, sp , #0 + stp x19, x20, [sp, #16] + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + + adrp x23, .Lord + add x23, x23, :lo12:.Lord // x23 = &n + ldp x12, x13, [x23] // n[0~3] + ldp x21, x22, [x23, #16] + ldr x23, [x23, #32] // x23 = LordK + + ldp x4 , x5 , [x1] // x4~x7 = a[0~3] + ldp x6 , x7 , [x1, #16] + +.align 4 +.Lord_sqr: + sub x2 , x2 , #1 +/****************************************** + x7 x1 x20 x19 x17 x16 x15 x14 + h0*1 l0*1 + h0*2 l0*2 + h0*3 l0*3 + h1*2 l1*2 + h1*3 l1*3 + h2*3 l2*3 + h3*3 l3*3 h2*2 l2*2 h1*1 l1*1 h0*0 l0*0 +*******************************************/ + + // a[1~3] * a[0] + mul x15, x5 , x4 // lo(a[1] * a[0]) + umulh x8 , x5 , x4 // hi(a[1] * a[0]) + mul x16, x6 , x4 // lo(a[2] * a[0]) + umulh x9 , x6 , x4 // hi(a[2] * a[0]) + mul x17, x7 , x4 // lo(a[3] * a[0]) + umulh x19, x7 , x4 // hi(a[3] * a[0]) + + adds x16, x16, x8 + adcs x17, x17, x9 + adc x19, x19, xzr // No more carry + + // a[2~3] * a[1] + mul x8 , x6 , x5 // lo(a[2] * a[1]) + umulh x9 , x6 , x5 // hi(a[2] * a[1]) + mul x10, x7 , x5 // lo(a[3] * a[1]) + umulh x11, x7 , x5 // hi(a[3] * a[1]) + + // a[3] * a[2] + mul x20, x7 , x6 + umulh x1 , x7 , x6 + + // Add the calculation result of the current round, + // and then add the calculation result with the acc (register in the preceding note). + adds x9 , x10, x9 + adc x10, x11, xzr + + adds x17, x17, x8 + adcs x19, x19, x9 + adcs x20, x20, x10 + adc x1 , x1 , xzr // a[0-3] has been saved in x4 to x7. + + // a[0~3] ^ 2 + mul x14, x4 , x4 + umulh x4 , x4 , x4 + mul x8 , x5 , x5 + umulh x5 , x5 , x5 + mul x9 , x6 , x6 + umulh x6 , x6 , x6 + mul x10, x7 , x7 + umulh x7 , x7 , x7 + + // acc[1~6] << 1 + adds x15, x15, x15 + adcs x16, x16, x16 + adcs x17, x17, x17 + adcs x19, x19, x19 + adcs x20, x20, x20 + adcs x1 , x1 , x1 + adc x3 , xzr, xzr + + // acc[] += a[] ^ 2 + adds x15, x15, x4 + adcs x16, x16, x8 + adcs x17, x17, x5 + adcs x19, x19, x9 + adcs x20, x20, x6 + adcs x1 , x1 , x10 + adc x7 , x7 , x3 + + // Four rounds of reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q in Montgomery + // modular multiplication + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + // First calculate the value to be added to the same accumulator. + subs xzr, x14, #1 // CF = (x14 < 1) + adcs x10, x10, x9 // x10 = hi(q*n[0]) + lo(q*n[1]) + adc x11, x11, xzr // x11 = hi(q*n[1]) + CF + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adc x17, xzr, x24 // x17 += q, Supposed to be add hi(q*n[3]) = q-hq, hq will be subtracted later. + + lsl x8 , x24, #32 // lq << 32 + lsr x9 , x24, #32 // hq + + subs x15, x15, x24 // x15 = x15 + lo(q*n[2]) = x15 - q + sbcs x16, x16, x8 // x16 = x16 + lo(q*n[3]) = x16 - lq<<32 + sbc x17, x17, x9 // x17 = x17 - hq, (remaining part of hi(q*n[3])) + + // Round 2 reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q in Montgomery + // modular multiplication + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + // First calculate the value to be added to the same accumulator. + subs xzr, x14, #1 // CF = (x14 < 1) + adcs x10, x10, x9 // x10 = hi(q*n[0]) + lo(q*n[1]) + adc x11, x11, xzr // x11 = hi(q*n[1]) + CF + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adc x17, xzr, x24 // x17 += q, Supposed to be add hi(q*n[3]) = q-hq, hq will be subtracted later. + + lsl x8 , x24, #32 // lq << 32 + lsr x9 , x24, #32 // hq + + subs x15, x15, x24 // x15 = x15 + lo(q*n[2]) = x15 - q + sbcs x16, x16, x8 // x16 = x16 + lo(q*n[3]) = x16 - lq<<32 + sbc x17, x17, x9 // x17 = x17 - hq, (The remainder of the hi(q*n[3])) + + // Round 3 reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q in Montgomery + // modular multiplication + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + // First calculate the value to be added to the same accumulator. + subs xzr, x14, #1 // CF = (x14 < 1) + adcs x10, x10, x9 // x10 = hi(q*n[0]) + lo(q*n[1]) + adc x11, x11, xzr // x11 = hi(q*n[1]) + CF + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adc x17, xzr, x24 // x17 += q, Supposed to be add hi(q*n[3]) = q-hq, hq will be subtracted later. + + lsl x8 , x24, #32 // lq << 32 + lsr x9 , x24, #32 // hq + + subs x15, x15, x24 // x15 = x15 + lo(q*n[2]) = x15 - q + sbcs x16, x16, x8 // x16 = x16 + lo(q*n[3]) = x16 - lq<<32 + sbc x17, x17, x9 // x17 = x17 - hq, (Remaining part of hi(q*n[3])) + + // Round 4 reduce + mul x24, x14, x23 // x24 = lo(a[0]*b[0]*ordk), equivalent to q in Montgomery + // modular multiplication + + umulh x9 , x12, x24 // hi(q*n[0]) + mul x10, x13, x24 // lo(q*n[1]) + umulh x11, x13, x24 // hi(q*n[1]) + + // First calculate the value to be added to the same accumulator. + subs xzr, x14, #1 // CF = (x14 < 1) + adcs x10, x10, x9 // x10 = hi(q*n[0]) + lo(q*n[1]) + adc x11, x11, xzr // x11 = hi(q*n[1]) + CF + + // S /= r, accumulation of staggered blocks + adds x14, x15, x10 // x14 = x15 + hi(q*n[0]) + lo(q*n[1]) + adcs x15, x16, x11 // x15 = x16 + hi(q*n[1]) + adcs x16, x17, x24 // x16 = x17 + hi(q*n[2]) + adc x17, xzr, x24 // x17 += q, Supposed to be add hi(q*n[3]) = q-hq, hq will be subtracted later. + + lsl x8 , x24, #32 // lq << 32 + lsr x9 , x24, #32 // hq + + subs x15, x15, x24 // x15 = x15 + lo(q*n[2]) = x15 - q + sbcs x16, x16, x8 // x16 = x16 + lo(q*n[3]) = x16 - lq<<32 + sbc x17, x17, x9 // x17 = x17 - hq, (Remaining part of hi(q*n[3])) + + // add acc[4-7], x14~x19 is the current calculation result r + adds x14, x14, x19 + adcs x15, x15, x20 + adcs x16, x16, x1 + adcs x17, x17, x7 + adc x19, xzr, xzr + + // r -= p + subs x8 , x14, x12 + sbcs x9 , x15, x13 + sbcs x10, x16, x21 + sbcs x11, x17, x22 + sbcs xzr, x19, xzr // The set CF is used to determine the relationship between r and p. + + // r = r-p < 0 ? r : r-p + // Use x4 to x7 to save the result. You can perform the square operation cyclically. + csel x4 , x14, x8 , lo + csel x5 , x15, x9 , lo + csel x6 , x16, x10, lo + csel x7 , x17, x11, lo + + cbnz x2 , .Lord_sqr // Number of square operations, that is a^(2^rep) + + stp x4 , x5 , [x0] + stp x6 , x7 , [x0, #16] + + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldr x29, [sp], #64 + ret +.size ECP256_OrdSqr,.-ECP256_OrdSqr + +.globl ECP256_Scatterw5 +.type ECP256_Scatterw5,%function +.align 4 +ECP256_Scatterw5: + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + add x0 , x0 , x2 , lsl#3 // Needs x0 = x0 + (x2-1)*8 = x0 + x2*8 - 8 + // The action of -8 is placed in the str instruction. + + ldp x4 , x5 , [x1] // x + ldp x6 , x7 , [x1, #16] + + str x4 , [x0, #128*0-8] // 8*16*0 + str x5 , [x0, #128*1-8] // 8*16*1 + str x6 , [x0, #128*2-8] // 8*16*2 + str x7 , [x0, #128*3-8] // 8*16*3 + + add x0 , x0 , #64*8 + + ldp x4 , x5 , [x1, #32] // y + ldp x6 , x7 , [x1, #32+16] + + str x4 , [x0, #128*0-8] // 8*16*0 + str x5 , [x0, #128*1-8] // 8*16*1 + str x6 , [x0, #128*2-8] // 8*16*2 + str x7 , [x0, #128*3-8] // 8*16*3 + + add x0 , x0 , #64*8 + + ldp x4 , x5 , [x1, #64] // z + ldp x6 , x7 , [x1, #64+16] + + str x4 , [x0, #128*0-8] // 8*16*0 + str x5 , [x0, #128*1-8] // 8*16*1 + str x6 , [x0, #128*2-8] // 8*16*2 + str x7 , [x0, #128*3-8] // 8*16*3 + + ldr x29, [sp], #16 + ret +.size ECP256_Scatterw5,.-ECP256_Scatterw5 + +.globl ECP256_Gatherw5 +.type ECP256_Gatherw5,%function +.align 4 +ECP256_Gatherw5: + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + cmp x2 , xzr + csetm x3 , ne // x3 = (x2 == 0) ? 0 : -1 + add x2 , x2 , x3 // x2 += x3, if x2 != 0, then x2 = x2 - 1, if not x2 = 0 + + add x1 , x1 , x2 , lsl#3 // x1 += x2*8, offset + + ldr x4 , [x1, #128*0] + ldr x5 , [x1, #128*1] + ldr x6 , [x1, #128*2] + ldr x7 , [x1, #128*3] + + csel x4 , x4 , xzr, ne // If x2 = 0, Then return to 0. Otherwise, returns the read point coordinates + csel x5 , x5 , xzr, ne + csel x6 , x6 , xzr, ne + csel x7 , x7 , xzr, ne + + stp x4 , x5 , [x0] // r->x + stp x6 , x7 , [x0, #16] + + add x1 , x1 , #64*8 + + ldr x4 , [x1, #128*0] + ldr x5 , [x1, #128*1] + ldr x6 , [x1, #128*2] + ldr x7 , [x1, #128*3] + + csel x4 , x4 , xzr, ne // If x2 = 0, return 0. Otherwise, returns the read point coordinates + csel x5 , x5 , xzr, ne + csel x6 , x6 , xzr, ne + csel x7 , x7 , xzr, ne + + stp x4 , x5 , [x0, #32] // r->y + stp x6 , x7 , [x0, #48] + + add x1 , x1 , #64*8 + + ldr x4 , [x1, #128*0] + ldr x5 , [x1, #128*1] + ldr x6 , [x1, #128*2] + ldr x7 , [x1, #128*3] + + csel x4 , x4 , xzr, ne // If x2 = 0, return 0. Otherwise, returns the read point coordinates + csel x5 , x5 , xzr, ne + csel x6 , x6 , xzr, ne + csel x7 , x7 , xzr, ne + + stp x4 , x5 , [x0, #64] // r->z + stp x6 , x7 , [x0, #80] + + ldr x29, [sp], #16 + ret +.size ECP256_Gatherw5,.-ECP256_Gatherw5 + +.globl ECP256_Scatterw7 +.type ECP256_Scatterw7,%function +.align 4 +ECP256_Scatterw7: + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + // add x0 , x0 , x2 + sub x2 , x2 , #63 // x2 = x2 - 63 + sub x0 , x0 , x2 // x0 = x0 - (x2(original) - 63) = x0 + (63 - x2(original)) + mov x2 , #8 // Loop count +.Lscatter_w7: + ldr x3 , [x1], #8 + subs x2 , x2 , #1 + + strb w3 , [x0, #64*0] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*1] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*2] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*3] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*4] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*5] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*6] + lsr x3 , x3 , #8 + strb w3 , [x0, #64*7] + add x0 , x0 , #64*8 + b.ne .Lscatter_w7 + + ldr x29, [sp], #16 + ret +.size ECP256_Scatterw7,.-ECP256_Scatterw7 + +// The anti-cache attack solution can be used together with ECP256_Scatterw7. +.globl ECP256_Gatherw7 +.type ECP256_Gatherw7,%function +.align 4 +ECP256_Gatherw7: + stp x29, x30, [sp, #-16]! + add x29, sp , #0 + + cmp x2 , xzr + csetm x3 , ne // x3 = (x2 == 0) ? 0 : -1 + add x2 , x2 , x3 // x2 = (x2 == 0) ? 0 : (x2 - 1) (offset) + sub x2 , x2 , #63 // x2 = x2 - 63 + sub x1 , x1 , x2 // x0 = x0 - (x2(original) - 63) = x0 + (63 - x2(original)) + mov x2 , #8 // Indicates the number of cycles. The x and y coordinates contain 64 bytes in total, + // and 8 bytes are obtained at a time. Therefore, eight cycles are required. + nop +.Lgather_w7: + + ldrb w4 , [x1, #64*0] + ldrb w5 , [x1, #64*1] + ldrb w6 , [x1, #64*2] + ldrb w7 , [x1, #64*3] + ldrb w8 , [x1, #64*4] + ldrb w9 , [x1, #64*5] + ldrb w10, [x1, #64*6] + ldrb w11, [x1, #64*7] + + // x4 = x4 | x5 << 8 + // x6 = x6 | x7 << 8 + // x4 = x4 | x6 << 16 + // x4 = [x7][x6][x5][x4] + orr x4 , x4 , x5 , lsl#8 + orr x6 , x6 , x7 , lsl#8 + orr x4 , x4 , x6 , lsl#16 + + // x8 = x8 | x9 << 8 + // x10 = x10 | x11 << 8 + // x8 = x8 | x10 << 16 + // x8 = [x11][x10][x9][x8] + orr x8 , x8 , x9 , lsl#8 + orr x10, x10, x11, lsl#8 + orr x8 , x8 , x10, lsl#16 + + // x4 = x4 | x8 << 32 + // x4 = [x11][x10][x9][x8] + orr x4 , x4 , x8 , lsl#32 + + and x4 , x4 , x3 + str x4 , [x0], #8 + + add x1 , x1 , #64*8 + subs x2 , x2, #1 + b.ne .Lgather_w7 + + ldr x29,[sp],#16 + ret +.size ECP256_Gatherw7,.-ECP256_Gatherw7 + +#endif diff --git a/crypto/ecc/src/asm/ecp256_pre_comp_table.s b/crypto/ecc/src/asm/ecp256_pre_comp_table.s new file mode 100644 index 00000000..d9f99ba0 --- /dev/null +++ b/crypto/ecc/src/asm/ecp256_pre_comp_table.s @@ -0,0 +1,2400 @@ +/* + * 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_ECC + +/* + * Base point pre-computation table, which contains 37 subtables of point multiplication results of each window. + * The size of each subtable is 64 x 64 bytes. + * Coordinates (x, y) of points in the subtable. Each column contains 32 bytes and is arranged in little-endian mode + * from top to bottom. + * The columns from right to left are the point multiplication results of window values starting from 1 and increasing. + */ +.section .rodata +.type g_preCompTable,%object +.balign 4096 +g_preCompTable: +.byte 0x80,0xe5,0x91,0xcc,0x19,0x8e,0xf0,0x28,0x14,0x83,0x53,0x8d,0x04,0xc9,0x1a,0xd3,0x12,0x97,0xd9,0xbf,0x7c,0x06,0x01,0x91,0x3e,0x42,0xee,0xb5,0xb7,0xf5,0xd3,0x34,0xd8,0x89,0x43,0x32,0x1f,0xb4,0x08,0x9f,0x19,0x68,0x76,0x08,0x31,0xe8,0x7a,0x9d,0x80,0x5b,0x4a,0x09,0x68,0x04,0xc8,0xe8,0x8f,0x4f,0x4a,0xf5,0xcc,0x27,0x4d,0x3c +.byte 0x8b,0x1f,0x2f,0x04,0x6e,0xaa,0x82,0xca,0x7a,0x56,0xcf,0x4d,0x59,0x64,0x17,0xac,0xc6,0x60,0x90,0x79,0x89,0x7d,0xad,0x2e,0x9f,0xc1,0xc0,0x08,0x9b,0x7e,0x3c,0x45,0xa3,0xff,0xb3,0xe1,0xcd,0xfe,0x80,0x87,0x28,0x50,0x30,0xb2,0x7a,0x9a,0xa9,0x5c,0xfb,0x05,0x66,0xd7,0x77,0xe4,0x1e,0x20,0xa7,0x3b,0x66,0x61,0x8d,0xc1,0xd6,0x14 +.byte 0x96,0xf9,0x96,0x4c,0x8a,0x46,0xea,0xca,0x8d,0x30,0x12,0x6c,0x44,0x3f,0x8c,0xf6,0xad,0xa7,0xee,0xcd,0x5a,0x8a,0x2b,0xd2,0x2e,0x59,0x63,0xce,0x21,0xc6,0xa2,0x66,0xe3,0x55,0x98,0x66,0x2c,0xe2,0x1f,0x37,0xd0,0xe4,0x6f,0x35,0x33,0x65,0xad,0x3c,0xc6,0x60,0xcf,0x2e,0x69,0x45,0xc2,0x4e,0x99,0x17,0x77,0x5c,0x91,0xeb,0xdd,0xa9 +.byte 0x05,0x9f,0xa1,0x7f,0xed,0x5c,0xa7,0x7a,0x7e,0xe7,0xb2,0x54,0x83,0x3b,0x48,0x1f,0x77,0xca,0x49,0xd5,0xd5,0x24,0xed,0x2e,0xb8,0xa0,0x4d,0x8c,0xa8,0xde,0x7c,0x0f,0xc5,0x67,0x32,0xcb,0x17,0x97,0xed,0xd8,0x15,0x2d,0x2f,0xc1,0xd2,0xa5,0x56,0xd5,0x0b,0xbc,0xb0,0x4b,0xd2,0x62,0x9d,0x26,0x94,0xa0,0x3e,0xc4,0x46,0x4e,0x10,0x18 +.byte 0xf3,0x31,0x75,0x1a,0x28,0xd6,0xe8,0xe7,0x40,0xf9,0x8e,0x38,0x6e,0x1c,0xd0,0x42,0x30,0x13,0xb1,0xcc,0x1f,0xfd,0xcf,0x49,0x1d,0x88,0xca,0xc5,0xd6,0x7f,0x14,0x56,0xcf,0x69,0xb1,0x6a,0xb7,0xf4,0x32,0xac,0xb2,0x53,0x35,0xec,0x29,0xba,0xc8,0xcb,0x65,0xb7,0x5b,0x63,0xa7,0x0a,0xd1,0x8f,0xd1,0x4e,0x37,0xae,0x0d,0x90,0xd4,0xd4 +.byte 0x96,0xd9,0xf1,0xeb,0x68,0x4e,0x00,0x32,0x41,0xbb,0x5b,0x96,0xf3,0xec,0xc2,0x0b,0x41,0x75,0xb5,0x26,0x7c,0x3f,0x5c,0x60,0x68,0x94,0xc3,0x7b,0x58,0x84,0x20,0x14,0xfc,0x3c,0x1c,0xb4,0x3e,0x2a,0xad,0x19,0x83,0x76,0x11,0x4c,0x91,0x12,0x51,0x1d,0x0b,0xd8,0xa3,0x25,0x1a,0x26,0xdb,0x6e,0x4c,0x35,0x47,0x8a,0xb5,0x3f,0x46,0x30 +.byte 0x6d,0xd3,0x35,0x67,0x1e,0xd4,0x6c,0xc8,0xc4,0x8b,0x42,0x35,0x92,0x8c,0xb9,0x95,0x34,0x3c,0x75,0xe4,0xfd,0xf2,0xb3,0x4d,0xd7,0xd8,0x2c,0x46,0x5e,0x16,0xab,0x15,0xc5,0xf7,0x24,0x5d,0x52,0x2c,0xe4,0xa3,0x38,0xf8,0xc6,0x2e,0x97,0xa9,0x3e,0x09,0x8b,0xbc,0x42,0xc4,0xb7,0x7d,0x18,0xc9,0xf1,0x46,0x39,0x1b,0xb0,0xac,0x00,0xe7 +.byte 0xdb,0xb8,0xe5,0x36,0xdc,0x69,0xf2,0x3e,0x8f,0x25,0xa0,0x97,0x26,0x50,0x0f,0x21,0x6b,0x28,0x40,0x1e,0xec,0x4f,0x5f,0x62,0xe4,0xa9,0x8a,0x00,0x3d,0xfd,0xb6,0x87,0xd8,0xe2,0xb4,0x5e,0x4b,0x04,0x61,0xa4,0x6d,0xf4,0x0f,0x56,0x8a,0xfe,0x5f,0x97,0x80,0x72,0xa2,0xcc,0x04,0xea,0x2c,0x75,0x27,0x07,0x40,0xbe,0x74,0xff,0x85,0x79 +.byte 0xb9,0xed,0xa7,0x84,0xc7,0xd1,0xaf,0x29,0x6a,0xe6,0x5f,0x79,0xc0,0x3f,0x78,0x09,0xa0,0x06,0xba,0x18,0xfb,0xfa,0xc7,0x22,0x3c,0x46,0xce,0x55,0x7f,0xb7,0x9d,0x03,0xbf,0xe6,0xa1,0x80,0x92,0x13,0x38,0xb0,0x35,0x6e,0x9a,0x7d,0xdc,0x6e,0x3e,0x7b,0x6b,0x4b,0xe3,0x0d,0x33,0xe0,0x39,0x41,0x55,0xf7,0x3e,0x7d,0x73,0xfb,0x7d,0x01 +.byte 0x73,0x8e,0xf5,0x4f,0xd9,0x63,0x9a,0x5b,0xf3,0x5b,0x7c,0x46,0xf9,0xdf,0x52,0x69,0x03,0x39,0x9e,0x6e,0x10,0x73,0xa5,0x28,0xe1,0x93,0x48,0x8d,0xc5,0x76,0x84,0xf1,0xdf,0x17,0x65,0x58,0xa8,0x73,0x75,0x67,0x9a,0x1f,0x2a,0xf4,0x2b,0xa1,0x40,0x17,0x2e,0x7e,0x07,0xd3,0x5a,0xdf,0x81,0xa8,0x34,0x00,0xee,0x53,0xc1,0x81,0x82,0xb6 +.byte 0x9f,0x51,0x58,0x40,0x89,0xd0,0x29,0x38,0x56,0xef,0x55,0xf2,0x45,0x5e,0x68,0xdc,0xd8,0xc8,0x6e,0x6c,0x91,0x88,0xa6,0x07,0x25,0x0b,0xe9,0x17,0x06,0x3e,0x91,0x68,0x79,0x30,0x4f,0x92,0xa6,0xbf,0xb1,0x6b,0xdd,0x2e,0x91,0x83,0x86,0xe1,0x8b,0x0a,0xfe,0xe2,0x97,0x6f,0x34,0x7f,0xcf,0xa7,0x9b,0x3c,0x6c,0xb9,0x23,0x7d,0x33,0xed +.byte 0x08,0xf0,0xed,0xa9,0x41,0xa8,0xe4,0xc7,0x95,0x07,0xf8,0x92,0xaf,0x1e,0x13,0x53,0xbb,0x36,0xa0,0x94,0xb2,0x87,0x1d,0x6f,0xdf,0xff,0x0f,0x7f,0x1b,0x23,0xa3,0x4b,0x40,0x47,0xb4,0x0d,0x30,0xae,0xd8,0xed,0x40,0x9e,0xe3,0x47,0x0f,0x25,0x8f,0xac,0x3f,0x56,0x7f,0x85,0xca,0x6e,0x0f,0x59,0x6f,0xd2,0x34,0x94,0xc6,0x08,0xa4,0x5f +.byte 0x13,0x00,0x61,0x21,0x36,0xd3,0x0d,0x57,0xca,0xbf,0x2e,0xc4,0x69,0xba,0xaa,0x84,0x29,0xa9,0x9a,0x0b,0xab,0xb4,0xe3,0xb5,0x0b,0x14,0x17,0x8c,0xbd,0x64,0xc6,0x7c,0x4c,0xe7,0x49,0x3a,0x28,0xd7,0x7a,0x9e,0x50,0xe8,0x23,0x65,0x8f,0xba,0x4d,0xb6,0x75,0xee,0xf7,0x69,0xf5,0x95,0x8a,0xed,0xc5,0x13,0x4f,0x9a,0xed,0x4a,0xc1,0xfc +.byte 0x09,0x48,0xe0,0x66,0x23,0xd5,0xc8,0xea,0xf3,0xa5,0x51,0x3f,0xc4,0xc0,0xfb,0x04,0x65,0x4f,0x33,0x94,0x94,0xbf,0xcb,0xe0,0x0f,0xe7,0x31,0x45,0xd0,0xe4,0xa5,0xae,0x90,0xf7,0x4e,0x96,0xcb,0x42,0x26,0xb4,0x75,0xa7,0xfa,0xb2,0x86,0x3a,0x96,0x24,0xe0,0x23,0x48,0x67,0xde,0x07,0x86,0xbf,0xb5,0x02,0x74,0x64,0xa6,0xf8,0xe3,0x95 +.byte 0x0a,0x9c,0xd7,0x55,0xfc,0x00,0xca,0xfe,0x1f,0xee,0x2e,0x9c,0x0e,0x0b,0x8b,0xe7,0x49,0x62,0x5c,0x32,0x91,0xc5,0x55,0xdf,0x20,0x5a,0x23,0x36,0x91,0x2e,0xa7,0xce,0xfd,0x3c,0xa1,0xbe,0x23,0x6a,0xc9,0xc1,0x0d,0xc7,0x9f,0xe1,0x16,0x36,0xfc,0x76,0x82,0xcc,0x6e,0x35,0xde,0xe4,0xf9,0xe6,0x2a,0xd2,0xae,0xec,0x50,0x27,0x6a,0xba +.byte 0x38,0x03,0x6e,0x59,0x33,0x21,0x99,0x1b,0xbb,0x31,0x4f,0x5f,0x2e,0xe2,0xa7,0xff,0xa7,0x0a,0x78,0x00,0x00,0x80,0xa1,0x6f,0x83,0x6f,0x51,0xb6,0xc6,0x74,0xca,0x85,0xbe,0xdd,0xa3,0xf1,0x73,0xd3,0xe6,0x6f,0x6d,0x37,0xc9,0x74,0x59,0x68,0x4a,0xf1,0x58,0x03,0x12,0x0e,0xab,0x9d,0x98,0xab,0x46,0x2b,0x55,0x90,0x46,0xb0,0xaa,0x75 +.byte 0x01,0x26,0x33,0x0a,0xbc,0x36,0xe1,0x38,0x44,0xc1,0x6c,0xd9,0xb7,0xd4,0x6a,0x27,0xbd,0xc7,0xe0,0x58,0xb0,0x81,0x8f,0x71,0x80,0x64,0x3b,0x06,0x6e,0xc8,0x94,0xb9,0x97,0x0d,0xcd,0xe2,0xeb,0xd7,0xfb,0xaf,0x9f,0x69,0x3d,0x30,0xba,0xac,0x79,0xff,0x49,0x70,0x60,0x11,0x5e,0xb5,0x49,0x00,0x6b,0x08,0xad,0x0c,0xf2,0x98,0xd9,0x10 +.byte 0x1e,0xcb,0xa2,0xb5,0x39,0x7c,0x8b,0xaf,0x00,0x14,0xd5,0xac,0x28,0x18,0xfa,0x61,0x05,0xf2,0x25,0x7f,0xd3,0x59,0x2f,0x22,0x72,0x36,0xf3,0xd8,0x57,0xb4,0x8d,0x8a,0x01,0x60,0x7a,0xb9,0x53,0xfd,0xf6,0xf3,0x46,0x40,0xba,0x3b,0x83,0x41,0x29,0x2d,0xf5,0x93,0x26,0x98,0x38,0x1a,0x0b,0xeb,0xfc,0xbb,0xa3,0xc2,0x0a,0xbc,0x90,0x25 +.byte 0xc6,0x82,0x89,0xce,0x1c,0xd1,0xd7,0x1e,0x60,0xc8,0xc4,0xc8,0x75,0x43,0xb1,0x76,0x88,0x5a,0xf8,0x47,0x81,0x74,0xa9,0xce,0xf2,0xfb,0x2e,0x77,0x57,0xc2,0x67,0x57,0xad,0xf7,0xc7,0x17,0xe1,0x4f,0x7f,0xf1,0x2b,0x58,0xf8,0x3f,0xd2,0x2c,0x2e,0xfe,0x83,0x81,0x83,0x9e,0x37,0xac,0x25,0xc8,0x2c,0x23,0x17,0x76,0x10,0xcb,0x14,0x62 +.byte 0xc2,0x91,0x20,0x7e,0x67,0xa2,0x7e,0xfd,0x14,0x46,0x25,0xa8,0xc6,0x2f,0xd5,0x28,0x6d,0x71,0xab,0x57,0xe3,0x05,0x30,0x39,0x66,0x16,0x22,0xa6,0xd2,0xef,0x75,0x65,0xfe,0x3c,0x3a,0x03,0xcf,0x08,0x85,0x32,0x1d,0xa3,0xd2,0x5a,0x5d,0x75,0x41,0x2c,0x2c,0xe4,0xc6,0x55,0xee,0x8d,0x48,0x44,0xf0,0x0c,0x5b,0xd0,0xe8,0x87,0x8d,0x77 +.byte 0x83,0x32,0xc0,0x53,0xe2,0xea,0xb6,0xe3,0x85,0x4a,0xf9,0xed,0x01,0x85,0x68,0xb2,0xa7,0xec,0x5b,0xe0,0x46,0x90,0x4c,0x15,0x4c,0x7d,0x85,0xae,0x10,0x34,0xa3,0xae,0x58,0x9d,0xcd,0x27,0xc0,0xeb,0xeb,0x33,0xf9,0xa2,0x85,0x6c,0xd9,0x77,0xab,0x75,0x7c,0x24,0x54,0x3f,0x9d,0x15,0xd6,0x04,0x2a,0xb5,0x1a,0xaa,0xac,0xdd,0x03,0x2b +.byte 0x0b,0x76,0xa4,0xf6,0x8f,0x27,0xe3,0x12,0x43,0x0e,0x6f,0x8b,0x32,0xeb,0xe2,0xd0,0xaa,0xaf,0x0d,0x8a,0x20,0xad,0x59,0x11,0x98,0x23,0xfd,0x8b,0xcb,0x41,0x73,0xc4,0x6a,0x68,0xd6,0x70,0x2e,0xc9,0xc5,0x99,0xcb,0x5f,0x06,0x50,0x99,0x22,0x47,0x39,0x2f,0x74,0xbf,0xd4,0xd2,0xa4,0x2c,0x9c,0xf0,0xaa,0x96,0xb5,0xac,0x77,0x05,0x73 +.byte 0xa7,0xc3,0x7a,0xcd,0x6f,0x97,0x6f,0x82,0x84,0xeb,0x28,0x2e,0x5a,0x1d,0xfb,0x4c,0x1b,0x20,0x03,0x1e,0x0e,0xd9,0xe2,0xca,0x09,0x8f,0x63,0x74,0xe4,0x8e,0x06,0x09,0x6d,0xf5,0xf4,0x4a,0x08,0xd2,0xc7,0x95,0xd7,0x82,0x0b,0x2a,0x80,0x84,0xf2,0xf1,0xef,0x33,0x17,0xbc,0x09,0xf3,0x7d,0xc0,0x90,0x3e,0x0a,0x1c,0xda,0xad,0x22,0xfb +.byte 0x7d,0x95,0x17,0x71,0x02,0xcb,0xd6,0x06,0x6a,0x0d,0xc1,0x91,0x90,0xda,0xed,0xff,0x1a,0x6b,0xa1,0x1b,0x5f,0xb7,0xc2,0xee,0x89,0x06,0x74,0xc5,0x0a,0x0b,0x5b,0xac,0xbc,0x8e,0xc5,0x94,0x97,0x49,0x1a,0xe3,0x61,0xd0,0x6a,0x6d,0x04,0xb8,0xa6,0xb0,0xd5,0xee,0x17,0xbc,0x24,0x1f,0x73,0x2c,0x8f,0xf4,0xd5,0x94,0x0c,0x66,0x73,0x79 +.byte 0xc7,0x8d,0x13,0xfa,0x15,0xb7,0xcd,0xcc,0x63,0xdd,0x51,0xb0,0x42,0x43,0xa7,0x2b,0xad,0xfd,0xdc,0x78,0x91,0x94,0x43,0x4f,0x27,0xac,0x6c,0xeb,0xc3,0x21,0x64,0x0c,0xa4,0xb4,0x3c,0x48,0x97,0x6a,0x10,0x2e,0x15,0x42,0xa4,0xfc,0x4e,0xfc,0xda,0x4e,0x23,0x09,0x2e,0x59,0x56,0x73,0x8f,0x6b,0x0d,0x03,0x73,0xc8,0x6b,0x7e,0x3b,0xc6 +.byte 0x38,0x56,0xb4,0x35,0x99,0x53,0x02,0x8c,0xae,0x30,0xc8,0x34,0xe5,0xa4,0xab,0xdb,0x43,0x8b,0x31,0x32,0xd2,0x19,0xfe,0x61,0x32,0x86,0x3d,0x94,0x3d,0xe5,0x3e,0xb1,0x32,0x87,0xfc,0x3d,0xdb,0xc7,0xfb,0x2a,0x31,0xbf,0x58,0x62,0xfb,0xc3,0xeb,0x57,0xb7,0xda,0xc7,0xb7,0xe1,0x90,0x42,0xe1,0x23,0x3e,0x36,0x23,0x17,0x74,0x3a,0x55 +.byte 0x9b,0xfc,0x39,0x83,0x6f,0xdd,0x8d,0xcf,0x51,0xb7,0x26,0x66,0xe5,0x3f,0x7e,0xb7,0x03,0xa7,0x29,0x82,0x8d,0xb0,0xfa,0x01,0xf7,0x31,0x60,0xa3,0x4a,0xa3,0x30,0x44,0x55,0xfc,0xb6,0x60,0xaa,0xf7,0xf2,0x43,0xfc,0x27,0x33,0x67,0x5b,0x97,0x80,0x7a,0x03,0xd3,0x12,0x95,0x83,0x9c,0xb3,0xc4,0x65,0x12,0x21,0x05,0xb0,0xff,0xcf,0x37 +.byte 0x56,0x82,0xe5,0x9b,0xbc,0x8a,0x64,0x6a,0x74,0xa7,0xee,0x30,0xd0,0x5c,0x2b,0x4f,0x47,0xeb,0xa4,0x6d,0xa9,0x3d,0x5b,0xdb,0x75,0x36,0x7c,0xdf,0xd5,0x42,0xdd,0xf0,0x69,0xb1,0x52,0x48,0xf2,0x2e,0x55,0x65,0x2e,0x17,0xe9,0xc1,0xfe,0x28,0x6f,0x6c,0x91,0x0a,0xfd,0x53,0xcb,0x64,0x24,0xf0,0xb2,0xc3,0x54,0x89,0x41,0xb6,0x3d,0xa5 +.byte 0x94,0x34,0x3a,0xa6,0xcd,0x1b,0x5f,0x30,0x4a,0x49,0xea,0x8d,0x34,0x0d,0xdb,0x08,0x02,0x74,0xc3,0x34,0xf6,0xdb,0xce,0x4f,0x00,0xc4,0xdc,0x87,0x6c,0x86,0xd4,0x68,0x77,0xf8,0xb5,0x59,0x6a,0x4b,0xa8,0xeb,0x2f,0x7c,0xe8,0xf4,0xb6,0x28,0x1b,0x0a,0x80,0x43,0x32,0xac,0x77,0xf1,0x47,0x80,0x1e,0x19,0x59,0x05,0xf5,0x3f,0xe4,0x76 +.byte 0x83,0xa4,0xb0,0x44,0x4c,0xab,0x72,0x98,0x0c,0x84,0x0f,0x31,0x7f,0xbe,0xb8,0xe6,0x39,0x99,0x84,0x7d,0x25,0x85,0x89,0x0a,0x7b,0xe4,0xc7,0xa3,0x65,0x0b,0xdd,0x68,0x70,0xc4,0x8c,0xf9,0x6b,0xa5,0xaa,0x42,0x23,0xea,0x77,0xd9,0xee,0x5c,0xbd,0x5c,0x3c,0x0e,0x73,0x77,0xdf,0x90,0xc9,0x30,0x89,0x51,0x4b,0x96,0x62,0x6a,0x32,0x5f +.byte 0xfb,0x63,0xbc,0x4a,0x0c,0x2b,0x5f,0x32,0x3f,0xee,0x8a,0x3a,0xf7,0x0e,0xce,0xdb,0x40,0x96,0xc6,0x4f,0x34,0x9c,0x9c,0x10,0x2d,0x53,0xf0,0x63,0x69,0x64,0x82,0xec,0x22,0x8d,0x28,0x66,0x7f,0x8a,0x4b,0x67,0x7b,0x2c,0xc7,0xea,0xd1,0x54,0x5a,0xa3,0xd6,0xaa,0xae,0x84,0xe1,0x70,0x61,0x5b,0x63,0xba,0x07,0x07,0x73,0x93,0xbb,0x90 +.byte 0x95,0x07,0x0d,0x99,0xd4,0x4c,0x30,0xc1,0xba,0x5c,0xbb,0xec,0x88,0xd2,0x0d,0xab,0xc8,0x4b,0xce,0xe9,0x5f,0x17,0x64,0x98,0x46,0x58,0xad,0x27,0x35,0xca,0xc9,0x33,0x39,0x94,0xd0,0xe2,0xe9,0x9f,0x99,0x96,0xf9,0xaf,0xfd,0xec,0xe2,0xfe,0x67,0xc1,0x54,0xe2,0xfa,0x73,0x4e,0x3e,0xcc,0xe0,0xb7,0x13,0x13,0xc9,0x57,0x26,0xf6,0x18 +.byte 0x2f,0xba,0x8e,0x69,0xca,0x04,0x1b,0x59,0x2a,0xde,0x7e,0x64,0x7c,0xa3,0x10,0xe8,0xf1,0x0e,0x63,0x1a,0xda,0x6c,0x7a,0x8f,0x98,0x98,0xe5,0xb6,0x3a,0xa9,0x71,0xf1,0xf5,0x99,0xbc,0x99,0xa1,0x70,0x18,0x28,0xc7,0xa9,0x04,0xb9,0x5d,0x6b,0x1d,0x87,0x9b,0x5d,0x6b,0x7f,0x43,0x88,0x76,0x14,0x77,0x4d,0x4b,0x10,0xa6,0xeb,0xa5,0x0a +.byte 0xfe,0x76,0xe3,0x9b,0x75,0x67,0xb2,0x9e,0xf3,0x2b,0x10,0xb2,0x68,0x1e,0xb7,0x09,0xdf,0xd6,0x6e,0xa2,0x50,0x96,0x25,0x62,0x17,0x2f,0x65,0xeb,0xa0,0x6a,0xf9,0xc1,0x42,0x32,0x0a,0x88,0x3d,0x5e,0x80,0x62,0xcb,0x85,0x5f,0xe5,0x00,0x69,0x5a,0x99,0x3f,0xc4,0x58,0xe1,0x5b,0x4e,0x9e,0x33,0x49,0x9d,0xe4,0x4f,0xab,0xa7,0xe1,0x56 +.byte 0xed,0x3e,0x32,0xeb,0x0e,0x42,0x3f,0xac,0x9a,0x18,0xd6,0x1c,0x64,0x24,0xe2,0x11,0x5a,0x21,0x58,0x2b,0x0d,0xa6,0xff,0x5c,0x65,0xc5,0x77,0x3c,0xcd,0xeb,0xb6,0x8e,0xef,0xa5,0x04,0x20,0xa8,0x89,0x24,0x96,0x4b,0x47,0x41,0x86,0x84,0x4c,0x48,0xe7,0xa2,0x83,0x5d,0x0e,0xbb,0x94,0xdd,0x5f,0x2d,0x5b,0x77,0xba,0xcb,0x83,0xbe,0x95 +.byte 0x80,0x38,0xbb,0xdb,0xf8,0x15,0x62,0x2a,0x1f,0xa0,0xe7,0xc3,0x58,0x73,0x9a,0x5e,0x17,0xd9,0xc1,0x78,0x73,0x61,0xe9,0xa3,0xf2,0x63,0xfe,0x7d,0x94,0x8c,0x5d,0x3a,0xdb,0x4e,0x1c,0x5c,0xd1,0x09,0x1d,0xb4,0xb2,0x9e,0x35,0xe2,0x78,0xdc,0x5e,0x93,0x52,0x63,0x99,0xc0,0x1c,0x2b,0x80,0xa4,0x53,0x3f,0xd3,0xe7,0xe4,0xc9,0x61,0xce +.byte 0x12,0xd5,0x4e,0x19,0xbb,0x0c,0xc4,0xdb,0x5b,0xc5,0xd2,0x41,0x29,0xa7,0x89,0x28,0x66,0xcc,0xc9,0x96,0x87,0x62,0x7d,0xa2,0x88,0x23,0x3b,0x8a,0xbd,0x90,0x0b,0x2b,0x6d,0x81,0x2f,0x73,0x3e,0xba,0xe1,0xfe,0x50,0xfb,0xbb,0xb2,0x41,0xe7,0x72,0x46,0xd6,0x4f,0xb7,0x90,0xd9,0x61,0x78,0x7a,0xa9,0x30,0x20,0x4a,0x4c,0x1f,0xd3,0x57 +.byte 0x65,0x04,0x42,0xf8,0x35,0xe9,0x1b,0xf2,0xc2,0x95,0x70,0x7f,0x8d,0x4e,0x80,0x92,0x9f,0x55,0x62,0xcb,0x66,0xb0,0x66,0xda,0xa1,0x7d,0x2d,0x44,0xae,0x01,0x00,0x83,0x3e,0xfe,0x8c,0x66,0x39,0xb7,0x14,0xc9,0xd7,0xa4,0x87,0xd4,0x1c,0xe9,0xbd,0x31,0x1b,0x52,0x2d,0x2b,0x12,0x85,0x40,0x77,0xa3,0xd0,0x62,0x9b,0xf2,0x5c,0x48,0x53 +.byte 0x3c,0x7c,0xdc,0xfa,0xa1,0x84,0xed,0x09,0xca,0xb4,0x8f,0x16,0x7a,0x0b,0x9e,0x7c,0xf5,0x07,0xab,0x47,0xa0,0x41,0x58,0xb0,0x0b,0xd8,0xc3,0x2b,0xeb,0x3a,0x7b,0xc4,0xe2,0xe9,0xcc,0xdb,0x3d,0x00,0xcf,0x8d,0x51,0x60,0xa7,0x9d,0xef,0x36,0xa2,0x7d,0xf1,0xb8,0xb5,0x75,0xac,0x76,0x2b,0xb7,0x9d,0x47,0xd3,0x30,0x96,0x4c,0x36,0xf2 +.byte 0x9a,0x70,0xe3,0xd7,0xaf,0xa0,0x33,0xb9,0xdf,0xea,0xc2,0x80,0xf6,0x37,0xbf,0x83,0x39,0x22,0x42,0xc7,0xbf,0xba,0xd1,0xb6,0xd9,0xe2,0x0e,0xa1,0xe5,0x65,0xfd,0x6a,0x09,0xd9,0xd5,0x98,0x1d,0x92,0x84,0x4b,0xa5,0x03,0x94,0xf2,0x82,0x2d,0x66,0x22,0xf2,0x40,0x27,0x35,0x0c,0x1a,0x0c,0x1e,0xf5,0x28,0x93,0xeb,0x2d,0xb0,0x2f,0xdd +.byte 0x82,0x97,0x1e,0x0d,0x2c,0xea,0xad,0x2a,0x4b,0xb4,0xaa,0xf2,0x62,0x65,0x96,0x5a,0xb7,0x13,0x2b,0xa5,0x7f,0xa8,0xae,0x47,0x34,0x76,0x09,0x50,0x13,0xd5,0x92,0xef,0x08,0x28,0x4a,0xa3,0x68,0x58,0x08,0x50,0x56,0x4a,0xa4,0x61,0xae,0xc5,0x3c,0x0e,0x87,0x25,0xc2,0xe3,0x37,0xc8,0x08,0xe3,0x15,0xdd,0xb5,0x2b,0x47,0x1a,0xf8,0x5c +.byte 0xaf,0x81,0x70,0x35,0xff,0xeb,0x19,0x78,0x21,0xa6,0x65,0x13,0x35,0x5f,0x9c,0x5b,0xc5,0xca,0x3f,0x33,0x3b,0xe5,0x50,0x9a,0x1c,0x88,0x04,0xd8,0xfe,0x52,0x6f,0xd5,0x99,0x60,0x9b,0x18,0x2a,0xfb,0xc5,0x39,0xe3,0x9f,0xfe,0x3c,0xcb,0x77,0x0b,0xb8,0x65,0x1b,0x37,0xd2,0x56,0x61,0xbe,0x45,0xba,0x7b,0x14,0x88,0xf4,0xfe,0x6f,0xe4 +.byte 0xae,0x4e,0x06,0xd4,0xad,0x37,0x63,0x61,0xf2,0x27,0x62,0x21,0xdf,0x1a,0x44,0x64,0xd8,0xae,0xb4,0x2b,0x08,0xdc,0x2c,0x7e,0xab,0x82,0x38,0x20,0x2b,0x78,0x87,0x47,0x0a,0xeb,0xbf,0xfb,0x4b,0xb7,0x8a,0xf4,0xa1,0x29,0x23,0xbb,0xff,0xa9,0x4f,0x9c,0x0b,0xa4,0x22,0x2e,0x89,0x7f,0x3f,0x5d,0x9e,0xa6,0xff,0xeb,0xd6,0x61,0x23,0x19 +.byte 0x8f,0x82,0x68,0xee,0x22,0xa8,0x7a,0xb6,0xb1,0x9e,0xe7,0x52,0x22,0x5e,0xa4,0xf4,0xb7,0x7b,0x5a,0xf7,0x4b,0xea,0xf3,0xc8,0x36,0x81,0xbf,0x6f,0x16,0x54,0x6f,0x58,0x48,0x98,0x06,0xa2,0x80,0xdd,0x62,0x43,0x88,0x27,0x4d,0x83,0xff,0xfb,0x8f,0xe8,0x4b,0x42,0x83,0x74,0xca,0xe5,0x38,0xce,0xcf,0x5d,0xad,0xe5,0xfa,0x08,0xeb,0xba +.byte 0xb9,0x30,0xef,0x80,0xa0,0xd3,0x3e,0x0d,0x86,0x87,0x44,0x6f,0xae,0x1c,0xe6,0x27,0xfb,0x10,0x66,0x69,0x6c,0x52,0x11,0x2e,0x8c,0x66,0x59,0x3e,0xd3,0x0c,0x1f,0x28,0x64,0xa2,0x1e,0x47,0xc7,0x6f,0x8b,0x12,0x49,0x9c,0x6a,0xc0,0x17,0x4a,0xaf,0x30,0x19,0x54,0x9e,0x90,0xf6,0x9e,0x91,0xed,0x7d,0xf2,0x53,0xef,0x71,0xad,0xcb,0xe4 +.byte 0x6b,0xb9,0xe5,0x56,0x51,0xfc,0x53,0x06,0xdb,0x9f,0xc4,0x2f,0x2e,0x51,0x7a,0x7d,0xd7,0x4e,0x1d,0x44,0x44,0xd0,0x96,0x4d,0xe1,0xa7,0xb3,0xda,0x82,0x30,0xcb,0xd1,0x9b,0x1c,0x51,0x24,0xf9,0xc6,0x89,0x63,0x49,0xa4,0x2d,0xad,0xec,0x24,0x5c,0xbf,0xc3,0x35,0x56,0x83,0xd2,0x93,0x89,0x7b,0x32,0xf2,0x2b,0x68,0x84,0x47,0xd7,0xb8 +.byte 0x72,0x98,0x72,0x3c,0xc6,0x8a,0x70,0x48,0xe0,0x75,0xe0,0xb8,0xb9,0xf1,0xde,0x14,0x26,0x94,0x43,0x25,0x23,0x82,0x35,0xf9,0xc6,0xc4,0xaa,0xad,0x4e,0x3c,0xa2,0x09,0x44,0x92,0x75,0x47,0xa7,0xd0,0x39,0xcc,0xea,0xfd,0x0c,0x0f,0xd4,0x06,0x2a,0x75,0x70,0x66,0x29,0x74,0x0e,0x0f,0x3a,0xaf,0xe3,0x42,0x9c,0xc5,0x62,0x3e,0x2c,0x4a +.byte 0x8f,0xac,0x64,0x47,0x12,0x77,0xfa,0x57,0x01,0xee,0x7e,0x3d,0x23,0x61,0xef,0x26,0x0b,0x9b,0x45,0xc5,0x04,0x4d,0x9b,0xb6,0x74,0x2e,0xcc,0xe7,0x93,0x31,0xbb,0x55,0x7e,0x2d,0xb6,0x90,0xa6,0x3b,0x5a,0x96,0x11,0xe5,0x64,0x1b,0xa2,0x58,0x4b,0x05,0x36,0xd7,0xbe,0x68,0x17,0x25,0xc4,0x56,0x21,0x67,0x29,0x73,0x17,0x58,0x15,0x8b +.byte 0xf8,0xe0,0xee,0xa2,0x96,0xf8,0x3e,0x01,0xac,0xca,0xb1,0x97,0x9e,0x62,0x46,0xd8,0xe3,0xd4,0x5d,0x81,0x17,0x18,0xcf,0xce,0x59,0x1c,0x9c,0x2c,0xc6,0xf7,0x26,0x74,0x40,0xfc,0x41,0x9f,0x1e,0xbb,0xf5,0xee,0x01,0x71,0xb5,0xa4,0x66,0xc1,0xba,0xbb,0x9e,0x97,0xdb,0xc1,0x66,0x3d,0xd2,0x1a,0xf0,0x95,0x11,0x68,0x2e,0x8e,0xbe,0x25 +.byte 0x4b,0x0d,0xe9,0xbb,0xad,0x77,0xfb,0x7a,0x96,0x18,0x36,0xe1,0xc3,0x1c,0x3a,0x8e,0x75,0x93,0x83,0x0c,0x34,0xa3,0x14,0xd9,0x43,0x7b,0x31,0x46,0xa0,0x7a,0x94,0x15,0x2e,0x03,0xa4,0x61,0xb7,0x4c,0x44,0x31,0x75,0x2f,0x35,0x29,0x5e,0x08,0x7b,0x83,0x0e,0x47,0xe7,0x5b,0x6d,0x64,0xe5,0x2f,0xbb,0x41,0x9f,0x1f,0xd2,0xe9,0x2d,0xf3 +.byte 0x42,0x23,0x4b,0x44,0x51,0xe4,0x5f,0x9b,0xb5,0xe5,0x19,0xaf,0xbe,0x68,0x14,0x81,0x9d,0xed,0xf7,0xf8,0x9d,0xe6,0x60,0x57,0xf5,0x4e,0x59,0x58,0x51,0x23,0x56,0x3f,0x9a,0x98,0x3a,0x7c,0x0c,0xeb,0xa9,0xb7,0xcb,0xac,0x3a,0xac,0xa9,0x95,0x84,0x18,0x58,0x8a,0x65,0x1f,0xde,0xad,0x9b,0xb1,0x60,0xc9,0x63,0x7a,0xdd,0x2e,0x04,0x21 +.byte 0x78,0x91,0x81,0xda,0x4f,0x7c,0xbe,0xc7,0xa4,0x80,0x1d,0xdc,0x9b,0x82,0xcc,0xf7,0x52,0x5d,0x55,0xc7,0xd6,0xa5,0x90,0x1d,0x5e,0xe1,0x8e,0x15,0xe2,0x6b,0x3c,0x76,0xad,0x0c,0x9b,0x77,0x2d,0x78,0x5f,0xc9,0x93,0x71,0x15,0x7f,0x8a,0xe3,0x1b,0x0d,0xb1,0x77,0x2a,0xbd,0x8a,0x1e,0x77,0x88,0xbe,0x77,0xef,0x7e,0xe5,0x1a,0x92,0xdd +.byte 0xa0,0x8f,0x98,0x66,0xbd,0x01,0x2d,0x32,0xc2,0x68,0xa4,0xd2,0x4b,0x3d,0x6b,0x92,0xce,0x51,0xc0,0xde,0x7d,0x3b,0x0b,0x59,0xa3,0xfa,0xd6,0xe5,0xba,0x12,0xa3,0x4f,0x1a,0xfd,0x37,0x39,0x48,0x08,0x7b,0x59,0x31,0x13,0xda,0x3e,0x3f,0x9b,0x7f,0x7f,0x3b,0xde,0x3e,0x22,0xfa,0x89,0x65,0x9a,0x84,0xdc,0x4c,0x87,0xde,0x31,0x0e,0x88 +.byte 0xa4,0x7c,0xff,0x84,0x04,0xf7,0x56,0x26,0x5b,0x6a,0x77,0xbc,0x01,0xe2,0x71,0xf5,0xf5,0x9d,0xb2,0xf6,0x24,0xcd,0xb2,0x32,0x6e,0x64,0x84,0xbc,0xc0,0xab,0x32,0x60,0x9c,0xed,0xda,0x69,0x8b,0xd1,0xe9,0x88,0xf0,0x8e,0x17,0x02,0xc5,0x5e,0x92,0x24,0x62,0xa6,0x19,0x64,0x8c,0xaa,0x2d,0x01,0x7b,0x3b,0xd4,0xa9,0x36,0x08,0xfb,0x86 +.byte 0x10,0xbf,0x47,0x65,0x0a,0x51,0xab,0xab,0x9a,0xcf,0xf2,0x55,0x27,0xa5,0xb7,0x78,0x75,0x81,0xc8,0x2e,0x7a,0x91,0x00,0x77,0x25,0xb8,0xaa,0x3e,0x0a,0xe4,0x73,0x09,0x96,0xec,0x67,0x96,0x68,0x97,0xfd,0x06,0x69,0x06,0xe9,0x75,0x61,0x66,0x26,0x4e,0xc4,0xef,0xe4,0xd0,0x22,0x0d,0x7d,0x6e,0x3c,0x93,0x24,0x40,0x6c,0x82,0xa8,0xe8 +.byte 0x80,0x92,0xdd,0xb6,0xc4,0x66,0x17,0xc5,0x4e,0xc2,0x3d,0xb1,0x5c,0x99,0x43,0x4d,0xa8,0x04,0x57,0x77,0x39,0x9e,0x4b,0xc6,0xab,0x47,0xbd,0xf6,0x45,0x24,0xc7,0xf9,0x7b,0xfa,0xd6,0x8a,0x4a,0x2d,0x14,0x12,0x76,0x48,0x9d,0x7a,0x91,0x85,0x26,0x2f,0x55,0x64,0xe8,0x7c,0x28,0x0c,0x5f,0x2b,0x12,0xef,0xf4,0x35,0x6b,0x78,0x19,0xd2 +.byte 0x70,0x70,0x09,0xf3,0x32,0x8b,0x41,0x26,0x08,0xf4,0xeb,0x83,0x8d,0x2d,0x13,0x36,0xc2,0x27,0x65,0xb5,0x2a,0xa0,0x3d,0x7b,0x2f,0x08,0x4d,0xa8,0x26,0xf8,0xf8,0xc4,0xa4,0x45,0x72,0x1b,0x78,0x31,0xc7,0x68,0x8a,0x6f,0x74,0xa3,0xd0,0x7b,0x4d,0xd0,0x20,0xf4,0xbb,0x97,0xca,0x8e,0xb5,0x9b,0x76,0x67,0x5f,0x16,0x63,0x07,0x3b,0x85 +.byte 0x49,0x9b,0xe0,0xdb,0xe8,0x7a,0x47,0x76,0x2c,0xf3,0x95,0x52,0x0f,0x4c,0x8c,0xfa,0x5c,0xfd,0xf8,0xe6,0xa4,0xdd,0x7d,0x4a,0x70,0x24,0xc3,0x88,0xa5,0x7a,0x74,0x63,0xc2,0x47,0x1f,0xe2,0x52,0xde,0x5a,0x99,0x7b,0x66,0xd0,0x7f,0xe0,0x59,0x39,0xc3,0xe2,0xad,0x1b,0xb7,0x8a,0xb8,0x4a,0x5f,0xdf,0x08,0xf7,0xe9,0xb8,0xcc,0x8a,0x5d +.byte 0x84,0x95,0xac,0x2b,0xe4,0xfb,0x67,0x01,0x6c,0x4c,0x95,0x46,0x0f,0xf5,0x62,0x47,0x32,0xdd,0xb7,0xd9,0x7b,0xb2,0xbc,0x88,0xaa,0x19,0x80,0x00,0x6d,0xb4,0x0d,0x2f,0x91,0x7b,0x60,0x3b,0x58,0x4b,0x2e,0xf7,0x73,0x77,0x5c,0x47,0xfe,0x12,0x02,0x74,0xef,0x79,0xaa,0xe7,0x23,0x25,0x3b,0x83,0x06,0x24,0x07,0xd1,0x5a,0x87,0x5b,0x88 +.byte 0x0e,0x40,0x35,0x87,0xbb,0x46,0x56,0x00,0x02,0xf1,0xea,0x43,0x9c,0xa2,0xc3,0xf2,0x41,0x6d,0xc1,0x2c,0x38,0x95,0x89,0x03,0xd1,0x69,0x9c,0x62,0xdd,0x8b,0x57,0xc3,0x95,0x4d,0x51,0x2a,0x40,0xd8,0xd1,0x56,0xca,0x90,0x5d,0xc9,0xc5,0x6d,0x05,0x32,0x01,0x70,0x2e,0xc9,0x53,0xe1,0xeb,0xfd,0x77,0x6e,0x4a,0x2d,0x4c,0xe5,0x0a,0x25 +.byte 0x44,0x01,0xff,0x80,0x09,0x98,0x94,0xc6,0x81,0x3f,0x3f,0x59,0x26,0x83,0x94,0x7e,0xe9,0x6e,0x38,0xfe,0x90,0x4f,0xe3,0xec,0x12,0xe5,0x80,0x43,0x11,0x62,0x0c,0x03,0x92,0x91,0xce,0x2a,0x5f,0x68,0x30,0xc3,0x5e,0x7b,0x07,0xf1,0xe1,0x25,0xd9,0x26,0xb2,0x0a,0xdc,0x69,0x95,0x23,0x54,0xcd,0xf2,0x15,0x6d,0xbb,0x39,0x29,0x51,0x18 +.byte 0x20,0x6a,0xcf,0xc7,0x01,0x49,0x49,0xc6,0x76,0x01,0x6e,0xda,0xf2,0xe3,0x41,0x07,0xc7,0xf8,0xa3,0xcb,0x9f,0x5f,0xcf,0xfe,0x66,0xc0,0xc2,0x61,0x9e,0x01,0x10,0x43,0xd7,0xe8,0x45,0x14,0xcc,0x10,0x80,0x8d,0xc5,0x68,0x8d,0xd5,0x04,0xee,0xc7,0x12,0xf7,0x17,0x06,0x87,0x7c,0x00,0x9a,0x59,0x12,0xd9,0x91,0x76,0x4c,0x6a,0x77,0xff +.byte 0x67,0x87,0x60,0x1b,0x82,0x62,0x37,0x44,0x92,0xe8,0x55,0xa1,0xf2,0x31,0xd3,0x94,0xef,0xbf,0x3d,0x3a,0x62,0x79,0xa8,0x0b,0x46,0x0b,0xa4,0xb3,0x0b,0xa9,0x59,0x6c,0x31,0x8a,0x0d,0x98,0xb4,0x43,0x17,0x94,0x5d,0xd0,0x3e,0x86,0xe1,0x20,0x6f,0xd5,0xed,0x42,0x27,0xc0,0xf5,0x93,0x71,0x66,0xec,0xed,0xc9,0xa0,0xb1,0xf0,0xc5,0x71 +.byte 0x29,0x90,0x6b,0x0d,0x04,0xa0,0x06,0xda,0x83,0x25,0x1a,0xfb,0x7e,0xd7,0xd7,0xd3,0x85,0x9b,0x03,0xd7,0xeb,0x47,0xf3,0xf7,0x03,0x0c,0xd9,0x58,0x48,0x2b,0xa1,0xb1,0x62,0xf3,0x46,0x37,0xa9,0x2d,0xed,0x7b,0x59,0x83,0x79,0xc0,0x5e,0xf7,0x6c,0xeb,0x64,0x20,0x15,0xfb,0x7f,0x68,0x78,0x08,0x56,0xea,0xa4,0x73,0x84,0xd5,0x78,0x85 +.byte 0xd5,0x40,0xba,0x98,0xc0,0x69,0x7b,0xf9,0x7d,0x36,0xc1,0x9d,0xcf,0xaa,0xdd,0x22,0x50,0x59,0xd1,0x60,0x61,0xa7,0x76,0xba,0xc9,0x25,0x11,0xae,0x88,0x65,0x17,0x20,0xa2,0xc7,0x70,0x17,0xd7,0x31,0x1a,0x80,0xd3,0x00,0x94,0x62,0x83,0x2a,0x59,0x0c,0xb8,0x0a,0x08,0xe3,0xf1,0xdf,0x90,0x2c,0xdd,0x4f,0x17,0xe9,0x96,0xcd,0xfc,0x2a +.byte 0x21,0x3a,0xdb,0x12,0x4f,0x8e,0x1f,0xc3,0x0d,0x3d,0x76,0x1c,0xc5,0xd7,0x4b,0x57,0xea,0xe7,0x3e,0x06,0xa6,0xdb,0xbc,0x0e,0xed,0x52,0x35,0x90,0x64,0xb0,0x96,0xa8,0x35,0xc5,0x87,0x09,0xf2,0x6e,0x93,0x9a,0xd7,0x51,0x21,0xac,0xc0,0x84,0x33,0x54,0x26,0x04,0x61,0x8e,0xaf,0x84,0x9a,0x04,0x3a,0x3f,0x37,0x7d,0x92,0x93,0x46,0xd6 +.byte 0xd7,0x54,0xee,0xbf,0xeb,0x5b,0xc7,0xea,0xef,0xef,0x5b,0x0c,0xa3,0x74,0x77,0x6c,0xc5,0x13,0xb0,0x81,0x04,0x53,0x61,0xe2,0xdf,0xbc,0x80,0x00,0xd9,0xe4,0xcd,0x8e,0x4b,0x72,0xc1,0xcc,0xef,0xf0,0x26,0xc6,0xe5,0x8c,0x84,0x3b,0x39,0xeb,0x92,0x63,0x79,0x74,0xa8,0x78,0xd7,0x89,0x36,0xa8,0xcc,0x91,0x4c,0xda,0x94,0xc2,0x69,0x2a +.byte 0xd5,0x16,0x39,0x97,0xac,0xea,0x31,0x00,0x3c,0x12,0xeb,0x76,0xd8,0xd1,0x83,0x77,0xc5,0xb9,0x94,0x31,0x6c,0xad,0xdf,0x9f,0x83,0xc1,0x19,0x09,0xe9,0xf8,0xbc,0x6a,0xab,0xa6,0xdc,0x09,0xd4,0x8b,0x17,0x0a,0x91,0xe9,0x39,0x80,0x63,0x46,0xd5,0x60,0xeb,0x5f,0x74,0xf1,0x8b,0x16,0x08,0x82,0x44,0x08,0xed,0xc2,0x39,0x6e,0x69,0x7a +.byte 0x62,0xc7,0x4d,0x06,0xee,0x1f,0x9c,0xc9,0x3b,0xca,0xcc,0x8b,0x57,0xb2,0x0f,0xc5,0xa1,0x14,0x69,0x81,0x4d,0x1b,0xd3,0xc2,0xf9,0x08,0xc7,0xec,0x4f,0x4b,0x33,0x2c,0xe5,0xf2,0x2e,0xac,0x9b,0xde,0xe2,0x27,0xe8,0x5c,0x09,0xf5,0x13,0xb0,0xe5,0xec,0xb9,0xc3,0xd4,0x04,0xf3,0x4b,0x5c,0x88,0xe1,0x20,0x3e,0x5b,0x10,0x6d,0xfa,0x81 +.byte 0x98,0x09,0x63,0x5e,0xf1,0x25,0x6a,0xcc,0x53,0x79,0xdd,0x22,0xe3,0x47,0xe8,0x8e,0xbf,0xd0,0xbd,0xec,0x32,0x34,0x36,0x96,0x2c,0x04,0xbd,0x41,0x04,0xae,0xcd,0xdf,0xb0,0x72,0x75,0x64,0xd6,0xf1,0x4e,0x2e,0x7f,0x5a,0x61,0x08,0xd6,0x30,0xf1,0x67,0x24,0xd4,0x58,0x9e,0x6b,0x33,0x38,0x36,0x81,0x68,0xa5,0xfb,0x81,0x49,0x8f,0xcb +.byte 0x00,0x21,0xd3,0xcc,0x81,0x72,0x2f,0x07,0x52,0x1e,0x38,0xd9,0x26,0x7b,0xfe,0xdb,0xcf,0xfc,0x35,0x38,0x70,0x3f,0x07,0x7a,0xae,0xed,0x33,0x2e,0x2d,0xb3,0x03,0xd1,0x72,0x70,0x5c,0x50,0x32,0xcc,0xd0,0x22,0x02,0xa6,0x10,0x91,0x1b,0x39,0xcb,0x5c,0x2b,0x2d,0x4a,0x66,0x15,0xef,0xb2,0x21,0x70,0x52,0xd6,0x30,0xe3,0x0a,0x6d,0xc5 +.byte 0x80,0xe2,0x21,0xef,0x5d,0xf7,0x20,0xa4,0xe6,0x42,0x9c,0x37,0x57,0x4b,0x5d,0xc7,0x84,0xa6,0x84,0x14,0xa3,0x8a,0xe4,0x40,0x29,0xa4,0xc0,0x30,0x46,0xec,0xc5,0x17,0x67,0xb8,0x3a,0x06,0x7b,0xdf,0x41,0xf4,0x32,0xb4,0xc5,0x43,0xb3,0xe3,0xe8,0x73,0x3d,0xac,0x0c,0x07,0xb3,0x8c,0x33,0xe5,0x4f,0xf2,0x35,0xb8,0x44,0x38,0x48,0x63 +.byte 0x82,0x6c,0x6d,0x9e,0x42,0xbc,0x5c,0x48,0x81,0xde,0xb4,0xda,0x13,0x04,0x85,0x0c,0x81,0x93,0x46,0x43,0x17,0x5a,0xdb,0xd3,0x1a,0x6d,0xbe,0x30,0xc1,0x2b,0xa3,0x54,0xcf,0xe2,0xa5,0xfd,0x0f,0x01,0xfd,0xf6,0x78,0x5a,0x95,0x5f,0x01,0x6d,0xb0,0x8f,0x09,0x57,0x90,0xa2,0x46,0x38,0xf8,0x98,0xcf,0x95,0xa3,0xbe,0xb5,0xf5,0x6d,0x54 +.byte 0xa1,0x3c,0xa4,0x63,0x0f,0x5f,0xfe,0x47,0x43,0xa5,0x0a,0x18,0x2b,0x5d,0x44,0x29,0x06,0xde,0xc5,0x40,0x6d,0x62,0x8c,0x5a,0x63,0x22,0xc3,0x68,0xa0,0x02,0x30,0xc2,0xaa,0xc5,0xc3,0x40,0xb6,0x39,0xec,0x54,0x76,0x0f,0x52,0xd4,0x47,0xe5,0x9f,0xcb,0x55,0xc9,0x5d,0x38,0xb1,0x96,0xb4,0x82,0x82,0x3d,0xd2,0xd3,0xb1,0x51,0xa5,0xff +.byte 0xd3,0xde,0x55,0x9d,0x6f,0xb7,0x6f,0xed,0xbb,0x7e,0xfc,0x5c,0xbb,0xa1,0x73,0x5f,0x96,0xf4,0x4c,0x4b,0x37,0x7b,0x77,0x2a,0x87,0x19,0x88,0xb0,0x82,0x53,0x77,0x2c,0xee,0x53,0x25,0x85,0x88,0x38,0x60,0x1e,0xa0,0xdd,0xd0,0x9b,0xb6,0xda,0x9b,0xf9,0xbe,0xea,0x4c,0x69,0x81,0x87,0x0e,0x27,0xbe,0xc9,0x0e,0xf8,0x1d,0x70,0xcb,0x62 +.byte 0x5b,0xfe,0x04,0x21,0x5e,0xc5,0x29,0xe2,0x2b,0x3e,0x26,0x9b,0x2a,0xf3,0x85,0x2b,0x67,0x8f,0x63,0xde,0x5e,0x83,0x3f,0xe5,0x8d,0x27,0x88,0xed,0x81,0x2e,0xba,0xf2,0xf5,0x0d,0x88,0xc6,0x42,0xdd,0x36,0xf5,0x73,0x2d,0x49,0x37,0xdf,0x7b,0x53,0xe5,0xcd,0xfc,0xee,0xa8,0x1d,0x33,0x19,0xcd,0x87,0xea,0x3d,0x0f,0x36,0x8e,0xb9,0xac +.byte 0xa3,0x36,0x68,0x30,0x02,0xbd,0xa3,0x80,0x18,0x6c,0x85,0x11,0xc3,0xe8,0x02,0x62,0x4c,0x86,0xe3,0x07,0xb6,0xcc,0xc0,0xbb,0x34,0xdb,0x3b,0xcc,0x2e,0xc4,0xe4,0x3b,0x01,0xc8,0x2f,0x29,0x71,0x44,0xc8,0x25,0x17,0x1d,0x3e,0x1d,0x55,0x9a,0x9d,0xc2,0xb3,0x71,0x8f,0xaf,0xcb,0x17,0x9b,0xaf,0xd6,0x61,0xcf,0xdf,0x7b,0xa7,0xd8,0xb9 +.byte 0x57,0xfd,0x2e,0x67,0x60,0xb3,0x5a,0x62,0x7b,0xc3,0x52,0xbb,0xec,0xd8,0x16,0x7e,0xf1,0x47,0x1d,0x65,0xd3,0x69,0x19,0x68,0x71,0x46,0x7b,0xa0,0xd5,0x34,0xed,0x0d,0x60,0x11,0x1f,0x37,0x67,0x8f,0xb2,0x6d,0x7d,0x87,0x35,0xd9,0x81,0x4a,0xea,0x59,0x8c,0xeb,0x8a,0x27,0xe4,0xce,0xc5,0xcf,0xa1,0xed,0x40,0x43,0x82,0xbd,0xc6,0xb6 +.byte 0x33,0xca,0xcd,0xdb,0x25,0xec,0xf9,0x5f,0x4f,0xe3,0x6f,0xef,0x97,0x72,0x13,0x46,0xba,0xda,0xad,0xfa,0x10,0xc2,0xa6,0x71,0x43,0xb9,0xf9,0x78,0x53,0xa8,0x5d,0xb5,0x8b,0xcb,0xaf,0xc5,0xae,0xdf,0xbb,0x09,0x4b,0xec,0xe2,0x7d,0xff,0x84,0x0c,0xb2,0xf8,0x9a,0x04,0x4f,0x5e,0x1d,0x90,0x31,0xff,0x20,0x82,0xe6,0x63,0x3d,0xfb,0xf2 +.byte 0x0c,0x9a,0x35,0xcb,0x36,0xae,0x01,0x83,0xd9,0x9e,0x74,0xc7,0x11,0x40,0x63,0xdc,0xd3,0x53,0xd9,0x9d,0x97,0x8e,0x13,0xf2,0xf8,0xd0,0xa9,0x22,0x4b,0x07,0x36,0xb2,0x1d,0xea,0x4b,0x27,0x88,0x1f,0x0b,0x34,0xf1,0x6c,0xb7,0x0b,0x39,0x8e,0xdb,0x50,0xbf,0x40,0xf8,0xc1,0x1b,0xe8,0x29,0xd9,0xd5,0xea,0x9f,0xd0,0x5b,0x73,0x50,0x7e +.byte 0xa4,0x14,0x0c,0x6f,0xc8,0xe5,0xa3,0x0d,0x00,0xf7,0x9f,0xc5,0xdd,0xed,0xa9,0xa9,0x42,0xe1,0xca,0x73,0x57,0x89,0x8f,0x89,0xd2,0x43,0x5e,0x90,0xe9,0x96,0x86,0x26,0x80,0x32,0xed,0x71,0x23,0xd2,0x18,0x91,0x61,0x8b,0xe0,0x81,0xab,0xfc,0x98,0xab,0x0b,0x23,0x80,0xc0,0x15,0xf0,0x80,0x40,0x72,0x6c,0xa5,0x41,0xf5,0x0a,0x15,0xb5 +.byte 0xcd,0xe6,0xeb,0x8c,0x70,0xf0,0xc3,0x8e,0xf5,0x36,0x26,0xdb,0x88,0x07,0x69,0x25,0x09,0x68,0x20,0x02,0xe3,0x11,0xa2,0x9d,0xc8,0x2d,0xd0,0x96,0xe9,0xed,0x07,0x14,0x95,0x59,0x53,0x76,0xe7,0xe7,0x8e,0xa5,0xdd,0xe7,0x2e,0xc5,0x04,0xfd,0x9b,0xc6,0x64,0xec,0x4c,0x01,0xa9,0x20,0xac,0xa7,0x64,0xb2,0x3a,0x96,0xaf,0x14,0x5a,0x9d +.byte 0xa2,0x24,0xd7,0x1e,0x13,0x7f,0xce,0xc9,0x80,0xff,0x2c,0xf6,0xae,0xfa,0x4a,0xf4,0xd5,0x20,0xe4,0x3e,0x44,0xe3,0x6e,0x1d,0x29,0x8d,0xc6,0xc9,0x91,0x92,0xdb,0x29,0x5b,0x43,0xb1,0x22,0xa1,0x17,0x81,0xff,0xdf,0xa2,0xb4,0x63,0x96,0xf7,0x85,0x99,0xdd,0xc4,0x6d,0x3a,0x28,0x37,0x8e,0x97,0xdd,0xa6,0x54,0x8a,0x6e,0x49,0xf3,0xad +.byte 0x7a,0x68,0xf9,0xb8,0x75,0x88,0x53,0x1c,0x0e,0xcd,0xd6,0x19,0x31,0xd6,0x91,0x4f,0x0d,0xc3,0x00,0xcc,0x30,0x3a,0xc5,0xbf,0x74,0x75,0x85,0xfb,0x03,0x86,0x5d,0xb7,0x79,0xff,0x21,0xef,0x37,0x50,0x24,0x8f,0xc0,0x9b,0xef,0xca,0xe2,0x13,0x49,0x3f,0xe4,0x55,0xe8,0xe9,0xd6,0x26,0xc6,0xf5,0x0e,0x6c,0xe5,0x18,0x20,0xb8,0x90,0xb3 +.byte 0x3b,0x52,0x65,0x16,0xd7,0x31,0x14,0x47,0xbe,0xb5,0x50,0xc8,0x7f,0x7f,0xae,0x70,0x03,0x79,0xfc,0xd8,0xf0,0x82,0xa4,0xb3,0x11,0x62,0xbc,0x32,0xd3,0xb3,0x55,0xba,0xe4,0x9d,0x74,0x8e,0xb4,0xad,0xe5,0xcb,0xb3,0x7f,0x5c,0x27,0xd2,0x9e,0xcf,0x9a,0xaf,0x82,0x24,0x34,0x41,0x9c,0x45,0xe0,0x6c,0xb4,0x05,0xba,0xed,0x8d,0x3e,0xa4 +.byte 0xa8,0x68,0xfe,0xc1,0xd6,0x33,0x60,0xc3,0x52,0x98,0x3a,0x1b,0x7f,0xd4,0x24,0x7e,0x84,0x6d,0x23,0x15,0x98,0x27,0x21,0x0a,0x17,0xcd,0xae,0x59,0xdd,0x00,0x63,0x6c,0x7c,0xc2,0x3f,0x4c,0x61,0x5c,0x6d,0x48,0x97,0x0b,0x1d,0xe8,0x88,0x3a,0x34,0x4f,0x99,0xd7,0xc9,0xa3,0xac,0x94,0x61,0x0a,0x0b,0x38,0x4d,0x77,0x23,0x38,0x42,0xbb +.byte 0xf3,0x20,0xca,0x09,0x67,0xca,0xc0,0x54,0x87,0x81,0xa6,0x0d,0x0d,0xb7,0xb5,0x29,0x39,0x61,0xf4,0xb5,0x8c,0x1a,0xd9,0xb6,0x57,0x9e,0x68,0x02,0xb6,0xd3,0x8c,0x85,0x8f,0xda,0xd6,0x2d,0x94,0x77,0xef,0xa6,0x84,0x1f,0x8c,0x51,0x33,0xef,0x5b,0x73,0xf3,0xba,0xc7,0x47,0xa1,0xe6,0x9a,0x9a,0x89,0xed,0x0d,0xee,0x53,0x7e,0x3d,0x49 +.byte 0x27,0xfb,0xc8,0xd0,0x4b,0x1a,0x5f,0xcc,0x83,0xe4,0x52,0x7f,0x6c,0xee,0xa1,0xd4,0x26,0x14,0x2c,0x10,0xed,0xd7,0x6d,0x43,0xaf,0x10,0x3d,0x1d,0x84,0x1c,0x79,0x03,0x72,0x22,0xeb,0x0d,0x15,0x10,0xa6,0x00,0xf8,0x25,0xfc,0xd6,0x7c,0x34,0x0c,0xb8,0xd0,0x4f,0xe3,0x8b,0x7b,0xf6,0x81,0x06,0x89,0x51,0x8c,0x31,0x3e,0x03,0x7e,0x37 +.byte 0x85,0xa0,0x3e,0xe5,0x89,0x31,0x45,0xeb,0xfb,0x28,0x21,0x5b,0xfe,0xb1,0xd7,0x72,0x63,0x2e,0xdd,0xb2,0x1c,0x20,0xb4,0x7a,0x72,0x9b,0xeb,0xda,0x09,0xec,0xbc,0x39,0xda,0x3c,0x23,0x04,0x8c,0xef,0x87,0x7f,0x48,0x5f,0x1c,0x4f,0x42,0x76,0xc6,0x85,0x45,0xec,0x60,0x08,0x9e,0xec,0x14,0x7c,0x63,0xb0,0xb4,0x02,0x90,0xf6,0x2c,0x17 +.byte 0x30,0xdc,0xfb,0xe2,0x05,0xa1,0x8a,0x72,0x9b,0x22,0x86,0x90,0x3e,0xaf,0x00,0xbb,0xa6,0x35,0x96,0xcf,0x70,0x61,0x47,0x72,0x92,0x75,0x19,0x68,0x1a,0x14,0xd3,0xee,0x81,0x69,0x47,0x5a,0xae,0x1e,0x78,0x52,0x4f,0x2a,0x81,0x10,0x04,0xa1,0x3c,0xbc,0xed,0x76,0x1e,0x68,0x69,0xcb,0xa0,0x10,0x78,0x27,0xb4,0xd5,0x42,0xdb,0x96,0xa6 +.byte 0xf8,0x25,0xce,0x7c,0xe8,0xf0,0x49,0xb5,0x9c,0xb8,0x45,0xe6,0xbb,0xbd,0xe3,0xf7,0x16,0xdf,0x30,0xd8,0x22,0xe9,0xa6,0x0e,0x6d,0x51,0x39,0x0d,0x74,0xee,0x9c,0xf5,0xfb,0x08,0xf6,0x78,0x0a,0xd1,0xd5,0xb6,0x8c,0x3a,0xce,0x9c,0xb1,0x6c,0x40,0xa7,0x76,0x7b,0x6a,0x36,0x89,0x93,0xc4,0x59,0xd1,0x43,0x33,0xf6,0x1f,0x46,0xdd,0xd5 +.byte 0xf6,0xda,0x00,0x1a,0x03,0x19,0x5f,0xdc,0x9e,0xc6,0x99,0x07,0xfd,0xed,0xd4,0x0c,0x47,0xcc,0xa0,0x28,0x64,0x55,0x2f,0x71,0x14,0x27,0x19,0xb8,0xb1,0x61,0xfc,0x04,0x41,0x44,0xb2,0xa1,0x57,0x58,0xe7,0x69,0x2a,0xce,0x08,0x50,0xa6,0x63,0xa4,0xa3,0x2f,0x8a,0x05,0xd9,0xfd,0xf5,0x2e,0xeb,0x3e,0xea,0xdd,0xbc,0xc2,0x59,0xc0,0x46 +.byte 0x4e,0xa9,0x9e,0xe3,0x98,0xff,0x37,0x37,0x88,0x67,0x55,0x4b,0x1a,0xf9,0xaf,0xc1,0x9c,0x64,0x80,0xdd,0xbe,0xa3,0x33,0xef,0x67,0x5a,0x9d,0xd2,0x48,0x92,0x0e,0xae,0x2a,0x9d,0x47,0x80,0x89,0x97,0x51,0xdc,0xc0,0x34,0xeb,0xf6,0x4b,0x82,0x56,0xd5,0x30,0x61,0xde,0x38,0x9c,0xaf,0x62,0xf3,0x1a,0xbc,0xfb,0xaa,0xd2,0xb0,0x95,0x2c +.byte 0xe7,0x44,0xce,0xdd,0xb6,0x49,0x12,0x99,0x24,0xf9,0x9c,0x38,0x0d,0x9f,0xff,0x24,0x83,0xd6,0x6d,0x66,0xeb,0xf9,0x24,0x51,0x58,0x48,0x8a,0xfb,0x7b,0xf7,0x20,0x26,0xed,0xb9,0x3e,0x9f,0x47,0xa5,0xcc,0xac,0xee,0x84,0x84,0x75,0x08,0x8f,0x3c,0x13,0xe1,0xed,0x89,0x74,0x8f,0xfe,0x6d,0xb3,0x6e,0xdc,0xbb,0xa3,0x70,0x32,0xa1,0x1f +.byte 0x8a,0x45,0xa3,0xff,0x08,0x5d,0x99,0x96,0x6e,0xf4,0x04,0x75,0xb2,0x2b,0xc2,0xe9,0xb7,0x87,0xd2,0x60,0x64,0xb4,0xa5,0x5c,0xd1,0xc8,0xb8,0x32,0xab,0xa6,0xc3,0xfd,0x20,0xbd,0x38,0x3a,0x3d,0xc3,0x21,0x87,0xc2,0x4a,0x48,0x5d,0x19,0x76,0x58,0xcc,0x5f,0x59,0xc8,0x62,0x3a,0x56,0x78,0xdb,0xa2,0x62,0xd5,0x8a,0x23,0x4b,0x3d,0x31 +.byte 0xb5,0x2a,0xbd,0xa3,0x26,0xbe,0xeb,0x0e,0x8e,0xaf,0x60,0x48,0x15,0x6f,0xeb,0x4b,0xe4,0xb1,0xee,0x1b,0xc3,0x8f,0x76,0xe4,0x18,0x75,0xc3,0x0c,0x80,0x16,0xa6,0x87,0x4a,0x37,0xa2,0xd2,0x1f,0xdf,0xe4,0x4e,0xf7,0x22,0xe0,0x5c,0x1e,0xb3,0x5e,0xf8,0x3c,0xb3,0x28,0xff,0x8f,0x5c,0x7a,0x0a,0xad,0x86,0x45,0x4e,0x94,0xee,0x7c,0xad +.byte 0x6b,0x06,0xa4,0xba,0x01,0x6f,0x87,0xcb,0x6a,0x7e,0x9e,0x86,0x39,0x8a,0xa5,0x31,0xc0,0x59,0xd2,0xbd,0x1c,0xcf,0x5d,0x21,0xb7,0x7a,0xe3,0xc1,0x7f,0xed,0xfd,0xba,0xe6,0x0f,0x9a,0x59,0xda,0x10,0xe6,0xb4,0x21,0x6f,0x0e,0x08,0xef,0x1c,0xb7,0x59,0x3d,0x60,0x40,0x65,0xe7,0x84,0x8d,0xb8,0xaa,0xaa,0x8e,0x0f,0xa1,0xd1,0x8b,0x6d +.byte 0xad,0x0b,0xf7,0xd3,0x83,0x64,0xba,0xc9,0xca,0xdb,0x7c,0xcd,0x40,0xfe,0x46,0x21,0x6d,0x0b,0x09,0xfe,0xd6,0x75,0xdc,0x42,0x9b,0x17,0x0e,0xa6,0x31,0x49,0x5e,0xe4,0x01,0xc2,0xd1,0x03,0x71,0xff,0x7b,0xcc,0xe6,0xc4,0xf4,0xc3,0x47,0xe6,0x85,0x76,0xfb,0x4a,0xa0,0x59,0x8b,0x8c,0x3a,0x8e,0x3c,0x2a,0xd2,0x11,0x85,0x68,0x5d,0x3b +.byte 0x6d,0xd6,0x9c,0x14,0x26,0xc8,0x91,0x30,0xca,0x7a,0x2f,0xa8,0x58,0x60,0xfa,0x89,0xde,0xc9,0xdb,0x9e,0x33,0x98,0x5b,0x9b,0x76,0xe4,0x8b,0x41,0xd3,0x86,0xe3,0xbe,0xec,0x99,0x46,0x65,0x98,0xec,0xa8,0x85,0x56,0xf5,0x19,0x2d,0xcd,0x09,0x81,0x21,0x64,0x6f,0x14,0x2a,0x74,0xe5,0xac,0xaa,0x48,0x5d,0x7f,0x49,0xd9,0xe3,0xfd,0xff +.byte 0x2e,0x91,0x2c,0xa9,0x05,0xe5,0x5d,0x8f,0x16,0xc4,0x3c,0x3b,0x70,0x37,0x7c,0xa1,0xe7,0x1d,0xa4,0x9c,0x77,0xff,0xac,0x09,0x69,0x9c,0xc4,0xf3,0x27,0x6a,0xe5,0x02,0x4f,0x28,0x26,0x52,0x7f,0xb1,0xbe,0xe2,0x37,0x25,0x74,0x1f,0xec,0x4e,0xd4,0xc5,0x37,0xed,0xb2,0xca,0xa0,0xfd,0x20,0x5e,0x63,0x72,0x13,0x9a,0xe0,0xca,0x3c,0xc2 +.byte 0x81,0x62,0x60,0xaa,0xfc,0xaa,0x5e,0xe8,0x97,0xd0,0x82,0xaa,0x26,0x15,0xb7,0xae,0x94,0x50,0xe7,0x91,0x51,0x23,0x91,0x76,0xcf,0x49,0x48,0xda,0xd4,0xc6,0x2c,0xcc,0xd4,0xb6,0x0a,0x28,0xc0,0xa0,0x08,0x37,0xf4,0x61,0x81,0x38,0xc0,0xe0,0x2d,0x05,0xf4,0x26,0x2e,0xd8,0xc9,0x01,0xbe,0x1e,0x15,0x5c,0x73,0x32,0x2e,0xa9,0xb0,0x87 +.byte 0x1a,0x52,0x7a,0xba,0xd2,0x13,0x93,0xc8,0x16,0x9d,0x8f,0x0b,0xaa,0x16,0x3d,0xc5,0xf7,0xb6,0x0b,0x45,0x5d,0xf8,0x18,0x52,0x3e,0x5f,0x07,0x46,0x15,0x63,0xfb,0x96,0x5c,0x2f,0x62,0x95,0x18,0xc8,0xd2,0xe0,0x73,0x7f,0x5d,0xc7,0x54,0xf4,0x1a,0xb3,0x62,0x49,0x66,0x85,0xb9,0x56,0xad,0x95,0x27,0x29,0xcc,0x65,0xaf,0xfd,0xfd,0x80 +.byte 0x91,0x98,0xc1,0x3f,0xc0,0x2c,0x9a,0x16,0x75,0xe1,0xf4,0xc5,0x06,0xc5,0xc9,0x5d,0xf1,0xaf,0xf6,0xb0,0x7f,0x4a,0x59,0xca,0x05,0xb7,0x30,0x91,0x0e,0x10,0x0f,0xb6,0x68,0xe6,0xbf,0xc5,0x91,0xc9,0x27,0x75,0x55,0x82,0xf7,0x5f,0xcf,0x21,0xfc,0xc1,0x35,0x74,0xe2,0x09,0x29,0xff,0xfa,0x3e,0x6f,0xaf,0x04,0xfb,0xca,0xc4,0x73,0x7a +.byte 0x2a,0x25,0xdd,0xc5,0xcf,0x58,0xae,0x1b,0xc9,0x15,0xe7,0xc7,0xcd,0x18,0x52,0x0d,0xd5,0xf7,0xd7,0xd3,0x34,0x80,0x23,0xdf,0x83,0xb0,0x2d,0xd7,0xec,0x8f,0x06,0x9c,0x9f,0xf6,0xe7,0x98,0x86,0x6e,0xf1,0x05,0xaa,0x26,0xf1,0x7d,0x17,0x28,0x11,0x80,0x6f,0x12,0x57,0x7a,0x73,0x8b,0x33,0x98,0x27,0x6d,0xfa,0xf9,0xf2,0xb1,0xe6,0xb7 +.byte 0x5b,0x45,0x73,0xee,0x12,0x80,0x19,0x61,0xd9,0xfa,0xf3,0xe0,0x47,0x13,0x50,0x92,0xce,0x26,0xf7,0xf4,0xc3,0x9b,0x01,0x59,0x82,0x3d,0xc1,0xa0,0x1e,0x14,0xc1,0xd6,0xad,0x24,0xfd,0xad,0x78,0x49,0x82,0x52,0x48,0xc0,0x41,0xbe,0x30,0xdc,0x87,0x54,0x2d,0xe3,0x47,0xb3,0x1f,0x14,0x30,0x78,0xfd,0xda,0xfd,0x20,0x6d,0xf3,0xa5,0xff +.byte 0x6c,0x35,0x87,0x85,0x92,0x99,0x4a,0x46,0x1a,0x7d,0x5c,0x5d,0x97,0x6c,0x3b,0xc9,0xa7,0x1b,0x22,0x1f,0x26,0x2a,0xdc,0xa1,0xab,0x0c,0x46,0x68,0x67,0x3e,0xa1,0x0f,0x50,0xce,0x3f,0xac,0xe2,0x05,0xd6,0xcf,0xb9,0x5e,0xc2,0x54,0xfb,0xcd,0x17,0x2a,0xb6,0x2d,0x03,0xb9,0x62,0xb3,0x2d,0x8e,0x77,0xdc,0x3f,0xb2,0x84,0xb2,0xfc,0x34 +.byte 0x3d,0x75,0xcb,0xdf,0x30,0xe1,0x56,0x3c,0x53,0x2e,0x7d,0x90,0xdc,0x6c,0x65,0x05,0x2a,0xaa,0x06,0x1c,0xa8,0x44,0xc7,0x57,0x79,0xc1,0xa7,0xef,0x64,0x9f,0x55,0x82,0xff,0x7e,0xc8,0xa1,0x35,0x40,0xcd,0xdd,0x25,0x54,0x95,0x84,0x5d,0xc7,0x52,0xc1,0x51,0x91,0xe1,0xe9,0x2e,0xcc,0xba,0xb4,0x60,0x52,0x3b,0xd6,0x39,0xb0,0x9d,0x78 +.byte 0xf4,0x28,0x7b,0x88,0x40,0x20,0x0b,0x37,0x38,0x03,0x91,0xc2,0xa7,0xf0,0x21,0xa7,0x62,0x7d,0x96,0xa2,0xce,0x5d,0xba,0x25,0xc4,0x79,0x07,0x1b,0x1a,0x86,0x55,0x06,0xa7,0x44,0x03,0x74,0xf6,0x28,0xb1,0x50,0x18,0x48,0xa9,0xd9,0x4a,0xa0,0x6e,0x4e,0x31,0x4b,0x37,0xd6,0xa9,0x2e,0x5a,0x11,0x2f,0x8e,0xc7,0x2d,0x72,0xfd,0x88,0x36 +.byte 0x51,0xe9,0xe4,0x0f,0x39,0xe8,0x81,0x75,0xd8,0x23,0x43,0xfb,0x69,0xbf,0x1f,0xe3,0xd4,0x43,0x9d,0xdf,0xb9,0x57,0x72,0x7c,0x56,0x1e,0x7c,0x39,0xdb,0xfe,0x5b,0x04,0xcc,0x12,0xec,0x01,0x78,0xcc,0xd3,0xe4,0x40,0xdc,0x62,0xbf,0x85,0xa1,0x7e,0xd4,0x18,0x7f,0x98,0x42,0x95,0x17,0x81,0xb5,0xd9,0x2f,0xef,0xf6,0x4b,0xb0,0xc2,0xf3 +.byte 0x60,0x7b,0x2e,0x50,0x3d,0x12,0x62,0xae,0x49,0x9b,0x90,0x40,0xc9,0xe6,0x16,0xa8,0xf4,0xe9,0x56,0x4b,0x44,0x4f,0x1a,0x40,0xb8,0x1a,0xbc,0xa1,0x1d,0xfc,0xe2,0x18,0xdd,0xd5,0x44,0xad,0xda,0xd6,0x75,0x89,0xa2,0xbe,0xc1,0xa7,0x33,0xc3,0xbc,0x64,0xf3,0x8d,0x8e,0x55,0x1c,0x41,0x17,0xa8,0x4c,0x75,0xc6,0x17,0xc6,0xa7,0xb7,0xea +.byte 0x28,0x1b,0x57,0x6d,0x94,0xaa,0xac,0x06,0x6c,0x69,0xd9,0xce,0x77,0x96,0xe6,0xf8,0xd0,0x70,0x7f,0x5d,0x56,0x22,0x4a,0xc6,0x5e,0xa6,0x06,0x0b,0xfc,0xcd,0xa4,0x12,0xd7,0x35,0xcb,0x09,0xfb,0x6e,0xa4,0x80,0x13,0x22,0x0a,0xfa,0x69,0x4d,0x3f,0x53,0x5a,0x1e,0xc4,0x9a,0x39,0xe2,0xa2,0x63,0x92,0xd2,0x2a,0x83,0x2c,0x01,0x04,0x6f +.byte 0xde,0x28,0x01,0x83,0xa6,0xdb,0xc6,0xa6,0x86,0x45,0x6b,0xb0,0x22,0x7a,0x71,0x8b,0x5c,0x81,0xf4,0x42,0xd5,0x23,0xff,0x8d,0xc5,0x4f,0x75,0xae,0x8d,0xfb,0x99,0x53,0x3e,0x35,0x56,0xfa,0x35,0xee,0x16,0x18,0xc0,0x6a,0x5b,0x20,0x89,0x41,0xc9,0xfe,0x7b,0xe2,0xe8,0x3d,0x1d,0x74,0x31,0xe6,0xe6,0xba,0x86,0xd1,0x19,0x50,0x07,0xb4 +.byte 0xd8,0x27,0xdf,0x51,0xc2,0x94,0x69,0xab,0xe1,0x6a,0x69,0x52,0x15,0x71,0x0a,0xc5,0xec,0x84,0x29,0xd3,0x48,0x79,0x53,0x95,0xb2,0xd7,0xf3,0x3a,0x92,0xec,0x51,0x85,0xfd,0xe3,0xf1,0x5c,0xac,0x73,0xf7,0x19,0x72,0xdc,0x46,0x31,0xf6,0xcd,0x8b,0xfe,0xf3,0x59,0x8a,0xe8,0x37,0x78,0x65,0xc5,0x3c,0xcc,0xf2,0x5a,0xf8,0x6e,0xaa,0x38 +.byte 0xc4,0x3b,0x48,0x07,0xe1,0xbd,0x4e,0x2c,0xad,0x02,0xf4,0x19,0xd8,0xd0,0x58,0x5a,0xfe,0x0a,0xc7,0x07,0x55,0x26,0x84,0x58,0xf4,0xfc,0x57,0x4b,0x5b,0xb3,0x37,0xe9,0x97,0x7c,0xe9,0xbf,0x1d,0x8d,0x63,0xf7,0x85,0x5c,0x56,0xb0,0xf9,0x5f,0x5b,0x45,0xe5,0x5a,0x74,0x72,0xa8,0x8a,0xf5,0xf2,0x6e,0xda,0x1e,0xea,0x12,0xc4,0x05,0xb1 +.byte 0x96,0xf1,0x75,0xee,0xd0,0xab,0xd4,0x50,0x51,0xae,0x01,0x23,0x55,0xa2,0xbc,0x30,0xac,0x0c,0x96,0x76,0xa2,0xc6,0xdf,0x03,0xb0,0x67,0x6d,0x77,0x9c,0xa7,0x0b,0x12,0x2d,0x57,0x6b,0x55,0x54,0x4f,0x9b,0x0f,0x87,0xbb,0xc5,0x17,0xda,0x94,0x10,0x13,0x9c,0x70,0xac,0xf9,0x10,0x9a,0xa4,0x03,0x46,0x17,0xf5,0xc3,0x63,0x3a,0x23,0xd6 +.byte 0xf9,0x90,0x8c,0x66,0x1f,0xf7,0x3b,0x35,0x71,0x1f,0x87,0x7a,0x78,0x0e,0xa4,0x7a,0x59,0x70,0x72,0xd5,0x55,0xec,0x62,0x91,0x21,0xa1,0x6e,0x8d,0xd4,0x00,0xf7,0x02,0x0c,0xff,0x4f,0x0b,0xe1,0x1b,0x43,0x87,0x63,0xb1,0xc4,0xa5,0x47,0x54,0x05,0x68,0xd7,0xfc,0x80,0x4c,0x4d,0x4c,0xdb,0x8a,0x0a,0x0b,0x31,0x52,0xae,0x2e,0xf5,0x75 +.byte 0x41,0x1a,0x01,0x1b,0xc2,0x1a,0x1c,0x9b,0x39,0x8b,0xa8,0x73,0x87,0x10,0x57,0x64,0xf1,0xd8,0xd7,0x19,0xad,0x9e,0x61,0x35,0x1c,0x00,0x7c,0x63,0x5f,0xc1,0x75,0x69,0x64,0x88,0xc9,0x29,0x41,0xae,0x84,0xa8,0x45,0xa0,0xbb,0xee,0xfb,0x37,0x58,0x5e,0xc7,0x59,0x62,0x0b,0x21,0x61,0x42,0x0d,0x98,0x21,0xf5,0x41,0x47,0x74,0x1f,0x6d +.byte 0xcc,0x7b,0x2b,0xc7,0x90,0xf3,0xe8,0x68,0xe2,0x0c,0x17,0x06,0x95,0x04,0xfc,0xb0,0xf3,0xbd,0x5f,0xaf,0xe0,0x3b,0xe2,0x83,0x79,0xd3,0x43,0xa5,0x5d,0x97,0x53,0xc2,0xd2,0x6b,0x67,0x5a,0x36,0x7b,0xb6,0xc9,0xb3,0x5f,0x21,0x4b,0x23,0x94,0xa0,0x04,0x0b,0x5a,0x28,0xb8,0x6b,0x1b,0x27,0xcc,0xfe,0xe7,0xf9,0xed,0x8f,0x93,0x58,0x26 +.byte 0xdc,0x66,0x2b,0x8d,0x2a,0x40,0x8f,0xaa,0x17,0x68,0x13,0x84,0xa6,0x7a,0x74,0xa0,0x95,0xe3,0x92,0xe5,0xc6,0x4d,0x05,0xad,0xf7,0x62,0x48,0xb8,0xcc,0xfb,0xd9,0xdf,0x0f,0xdc,0x72,0x2d,0x8f,0xad,0xb1,0x96,0x03,0xae,0x09,0x37,0xd0,0x37,0xe7,0x87,0xbd,0x57,0x74,0x3e,0x1e,0xf0,0x9d,0x31,0xa7,0x10,0x3f,0x3c,0x0b,0xf5,0xce,0xaa +.byte 0x4b,0xec,0xa9,0xd9,0x19,0x8f,0x8a,0x47,0xc9,0x40,0xeb,0x70,0xbc,0x4d,0x35,0x73,0x52,0xc8,0xe5,0x5f,0x80,0x1c,0x99,0x0e,0x5e,0xc0,0xfc,0xc6,0x93,0x2c,0x11,0xa5,0x46,0xfb,0xaf,0x08,0x73,0xb5,0x9d,0xaa,0x1c,0x25,0x12,0x95,0x69,0xd5,0x47,0xbd,0xd5,0xe2,0x87,0xc2,0xe5,0xbc,0x20,0x16,0x05,0x22,0x40,0x7e,0x7c,0x6d,0xf6,0xf8 +.byte 0x4e,0xb4,0xe3,0xfd,0x76,0x63,0x45,0x4f,0x07,0x4d,0xe0,0x26,0x2a,0xce,0x53,0xa8,0x07,0xfa,0x15,0x84,0xa7,0xb1,0x5f,0x32,0x25,0xa8,0x1a,0xd7,0x31,0xf1,0xf6,0x09,0xf9,0xf2,0xe9,0x84,0x5f,0xb9,0xb6,0x69,0x84,0x8f,0x97,0xac,0x59,0xf1,0xc8,0x7f,0x0f,0x0e,0xf2,0xfd,0x35,0x68,0xbb,0xe2,0x1f,0x32,0xa2,0x4a,0x08,0x56,0x53,0x88 +.byte 0xe2,0x2e,0x00,0x16,0xdc,0x76,0x1d,0xb6,0xc4,0xbf,0x9f,0xde,0xb3,0xa5,0x12,0x77,0x06,0xbd,0x27,0x10,0x20,0xdd,0x26,0xdc,0x15,0x0f,0xa9,0xa4,0xa3,0xc2,0x1b,0x9a,0xf4,0x75,0xb5,0x80,0xe4,0xaa,0x13,0xe3,0x41,0xb9,0xcf,0x92,0xd9,0x5f,0x60,0x89,0x89,0xbc,0x06,0x72,0xb4,0x98,0x0f,0x71,0x2d,0x82,0xf5,0x9c,0x01,0xe6,0x5e,0x81 +.byte 0xe1,0x0e,0x46,0x45,0xf1,0xfc,0xd1,0x9b,0x37,0x0d,0x44,0x43,0x88,0xe2,0xbc,0x8c,0x3e,0x82,0xca,0x48,0x42,0xe7,0x3b,0x55,0x49,0x0f,0xea,0x0b,0x74,0x30,0x0e,0x0f,0x82,0x05,0x6b,0x9b,0xda,0x0a,0xf1,0xc7,0x3a,0xb9,0x33,0x26,0x91,0x55,0x82,0x2f,0x66,0x2d,0x6b,0xdf,0x47,0x4c,0xaa,0xe2,0x90,0x1e,0x73,0x57,0x62,0xb3,0x4d,0x00 +.byte 0x0a,0x94,0xa8,0x71,0x37,0x1d,0x9d,0x4d,0x60,0x55,0x9a,0xcf,0x51,0x0b,0xe1,0x9a,0x95,0x64,0x26,0x54,0x84,0xa0,0xe6,0x9c,0x3d,0x75,0xcf,0x88,0x36,0x71,0x16,0x16,0xeb,0x19,0xc0,0x41,0xc0,0xe0,0xf0,0x1f,0x65,0xfc,0x8d,0x64,0x7d,0xb3,0xdb,0x58,0xec,0xed,0x18,0x4f,0x49,0x54,0x55,0x11,0xb1,0xd5,0xbc,0x7d,0x96,0x39,0x91,0xec +.byte 0xc0,0xff,0x09,0x05,0x13,0xa8,0x7f,0xae,0xc1,0x48,0xed,0x62,0x38,0x9b,0xdd,0x4e,0x52,0x5f,0x26,0xf7,0x1d,0xfb,0xdf,0x57,0xba,0x4c,0x87,0xbd,0x3d,0x3c,0x4a,0xfa,0x26,0xbd,0x7b,0x67,0x3a,0x1d,0xdb,0xd8,0xea,0x2f,0xc2,0xb1,0x0b,0xef,0x58,0xb1,0x20,0xde,0x22,0xbb,0x3a,0x5e,0xe3,0x1e,0xb0,0x12,0xfc,0x14,0x91,0xf2,0xeb,0x20 +.byte 0x2e,0x3a,0xd3,0x70,0xf1,0xf5,0x46,0x14,0x6e,0x7a,0xe2,0xa2,0xa2,0x4e,0x15,0xca,0x35,0x34,0xdb,0x73,0x64,0x22,0x45,0xb9,0x56,0x87,0x15,0x07,0xd5,0x9b,0x35,0x7f,0x14,0x93,0xfd,0x1c,0xb1,0xf1,0xb3,0x6c,0x2b,0x68,0x20,0xb9,0x84,0x6e,0x4d,0xfe,0x6b,0xd4,0x40,0x33,0xf5,0xe3,0xe9,0xc1,0x94,0x79,0xe0,0x6a,0x1f,0x75,0x49,0xd3 +.byte 0x31,0xa8,0x2f,0x3d,0x09,0x13,0x8b,0x90,0x01,0x34,0x3f,0x12,0x9e,0x91,0x90,0xc9,0x93,0x8d,0xf2,0xf7,0xa7,0xda,0xc0,0x9d,0x59,0xf3,0xd7,0xf3,0x95,0xa4,0x57,0x6f,0x24,0x66,0x2d,0x0f,0x94,0xb4,0x59,0xa5,0x47,0x93,0x35,0x36,0x22,0x1b,0x4d,0x8e,0xaf,0xf1,0xc2,0x1c,0x55,0x33,0x2c,0x77,0xc7,0x7f,0xd5,0x29,0xc6,0xf6,0x9d,0x38 +.byte 0xe7,0x33,0x73,0x5a,0xb2,0x1f,0x7c,0xf8,0x2d,0x5a,0xbd,0xa9,0x89,0xa1,0xc0,0x00,0x8d,0x6e,0xef,0xbb,0x0a,0x91,0x3a,0x0a,0xaa,0x4d,0x5b,0x1c,0xc9,0xce,0x0a,0x66,0x3a,0x72,0x8b,0xa4,0x67,0x61,0x53,0x74,0xa0,0xd6,0x71,0xf0,0x92,0x15,0x7b,0x7f,0xfd,0x72,0xf1,0x5c,0xd2,0xa2,0xdb,0x75,0xf1,0xa3,0x34,0x0d,0x7d,0x4a,0x39,0xfa +.byte 0x20,0x0d,0xdd,0xb6,0x6e,0x78,0xe0,0x57,0xdd,0xf2,0xd7,0xe1,0xba,0x49,0x92,0x71,0x5b,0x76,0xc2,0x26,0x79,0xef,0x52,0x54,0x18,0x66,0x44,0xcf,0x40,0x28,0x50,0xc7,0x02,0x7a,0x76,0x8f,0x77,0xe6,0x26,0x2c,0x2e,0x68,0xf9,0x2d,0x65,0xb3,0x95,0x98,0x5a,0xd5,0xaa,0x63,0xf3,0x7b,0x97,0xf8,0xc1,0x30,0x69,0x81,0xe3,0xd4,0xfd,0xb3 +.byte 0x5e,0x83,0x8b,0xe2,0xa4,0xac,0x15,0xa7,0xf1,0xc4,0x65,0x56,0x1c,0x31,0x7d,0xd6,0x6f,0xef,0x4d,0x2d,0xcd,0x61,0x4c,0x06,0x48,0x0e,0x64,0x9a,0xab,0x04,0x7c,0xf6,0x38,0x86,0x16,0xd9,0x3d,0x1f,0xe3,0x74,0xf8,0x46,0xd3,0x84,0x5a,0x56,0x73,0x81,0x19,0xd2,0x8b,0xef,0x2a,0xb1,0xe2,0x24,0x41,0x9f,0x6b,0x65,0x9e,0x34,0xf9,0x85 +.byte 0x4c,0x38,0xe4,0x6d,0x63,0xcb,0x7c,0x13,0x88,0xb3,0x62,0xfd,0xa7,0x91,0x16,0x4f,0x77,0xcc,0xb5,0x68,0x58,0x1f,0xd6,0xfc,0x63,0x0f,0xa0,0x55,0x7e,0xfb,0x0f,0x84,0x76,0x24,0xa7,0xe0,0x53,0x4c,0x3a,0x36,0x0c,0x30,0x46,0x58,0x14,0x31,0x88,0x96,0xf7,0xaf,0x39,0x6d,0x7a,0x6e,0xcf,0x62,0xa3,0x2e,0x2e,0x94,0x77,0x2e,0x36,0x64 +.byte 0x58,0x13,0x66,0x39,0x59,0x70,0x4c,0x81,0x4d,0x56,0x46,0x00,0x96,0x1b,0x60,0xfd,0xbf,0xfe,0x7f,0xe5,0x59,0xc1,0x09,0xd1,0x38,0x74,0xbe,0x98,0x97,0x61,0x6f,0xcf,0xbd,0x49,0x60,0x7e,0xe3,0x6c,0x65,0xbc,0x6b,0xa1,0x79,0x65,0x59,0xc3,0xa1,0xdd,0x77,0x3d,0x32,0xed,0xbe,0x51,0x12,0x19,0x61,0x84,0x52,0x8d,0xe3,0xf7,0x3b,0x6e +.byte 0x6a,0x16,0x24,0x0f,0xc8,0xa7,0x17,0xb9,0xda,0xe9,0x81,0xa7,0x56,0x46,0xa9,0xd6,0x5a,0x82,0x73,0xfe,0xd3,0xd4,0x8b,0x1a,0x61,0x2f,0x63,0xb8,0x8d,0x47,0x8b,0x4e,0xa9,0xce,0x10,0x86,0x07,0xe0,0xad,0xe8,0xb3,0x39,0x27,0xbe,0x39,0xac,0xdd,0xa5,0x09,0x4a,0x22,0x56,0x1d,0xab,0x4b,0xd4,0x03,0xf9,0xe5,0x1b,0xfc,0x3a,0x62,0xe7 +.byte 0x74,0x79,0x8c,0x37,0x48,0x35,0x54,0x5b,0x66,0xdb,0x0f,0x00,0x5b,0x6c,0x22,0xd6,0x3c,0xb6,0xdf,0xb7,0xcd,0x12,0xc0,0xf2,0x22,0x1f,0xa1,0x2f,0x08,0x56,0x8c,0xed,0x6a,0xe1,0x18,0xea,0x8c,0x47,0x39,0x53,0x90,0xdc,0x93,0x74,0x33,0x71,0xe1,0xaa,0x77,0xf4,0x07,0xfd,0x8b,0xa3,0x1b,0x44,0x89,0xab,0x77,0x85,0x65,0xc3,0xfe,0x12 +.byte 0xa8,0xf5,0xff,0x09,0x9f,0xce,0x10,0xd0,0xd0,0xc8,0x27,0x4c,0x59,0x99,0xc2,0x87,0xe5,0x61,0xe1,0x68,0xd5,0x6e,0x53,0xc8,0xc5,0xc7,0x7a,0x49,0x64,0x19,0xa2,0x6c,0x40,0xdb,0xfc,0x5f,0xe0,0x4f,0x12,0x53,0x8e,0x65,0x28,0xb9,0x61,0x01,0xac,0xb4,0xbf,0xee,0x6e,0x13,0x9b,0x06,0x20,0x8c,0x17,0x7c,0x3a,0x22,0x01,0x15,0xb0,0xd1 +.byte 0xa7,0xa5,0x00,0xa0,0xe8,0x1c,0xf0,0x82,0xaa,0x63,0x99,0x8d,0x10,0x7b,0x24,0xef,0x2c,0xb9,0x9a,0x1d,0xd5,0x14,0x59,0x2c,0x2c,0x70,0xb6,0x5d,0x91,0xfc,0xfb,0xd1,0xed,0xe4,0x61,0xfe,0x26,0xcf,0x87,0x27,0xe5,0xa3,0xfe,0x30,0x3d,0xa5,0xec,0x5c,0xfa,0x57,0x76,0x98,0xbd,0x7e,0x48,0x8e,0x36,0x8a,0xda,0x73,0x0f,0xf6,0x79,0xf8 +.byte 0x35,0xca,0x8e,0xbd,0xc7,0x58,0x32,0xe4,0xea,0xcc,0xf0,0x18,0xb7,0xda,0x8c,0x0e,0x05,0x92,0x49,0x7c,0x14,0x9e,0x49,0x73,0x0b,0xcc,0xf2,0x50,0x90,0xd4,0x6d,0x43,0xa1,0x17,0xd1,0x64,0x99,0x79,0x43,0x90,0xe7,0x06,0x73,0xa6,0x37,0x2e,0xde,0x6c,0x8f,0xd8,0x31,0x6c,0x72,0x2b,0xe5,0x9d,0x42,0xaf,0x18,0x12,0x9e,0x35,0xc0,0xf8 +.byte 0x70,0x3f,0xd7,0xc7,0x61,0x39,0x7c,0x85,0x5d,0x77,0xad,0x7c,0xde,0x02,0xf1,0xa1,0x7b,0x6d,0x36,0xf8,0x31,0xe7,0x97,0x9d,0x2e,0x23,0xb6,0x9b,0xb3,0x24,0xcc,0x0f,0x3d,0x49,0x8a,0x18,0x1c,0xbb,0xbb,0xed,0xb5,0x96,0x22,0xd0,0x63,0x17,0x65,0x3a,0x83,0x98,0xa0,0x10,0x4a,0x37,0x74,0x07,0x61,0x83,0x6c,0xa0,0x5d,0xec,0x9f,0x52 +.byte 0xdc,0x12,0xcc,0xec,0x9e,0xb2,0x27,0x98,0xd3,0x41,0xf7,0x52,0xca,0x4e,0x29,0xda,0x35,0xba,0x96,0xc7,0x37,0x83,0xdf,0x26,0x4c,0x6b,0x24,0xb7,0x60,0xe6,0x4d,0x09,0x30,0xb8,0x6a,0xf6,0x34,0x8b,0x4c,0xa0,0x15,0xf8,0x47,0xf3,0x40,0x80,0x2a,0x41,0xeb,0xed,0xfc,0x53,0xb7,0xc7,0x2f,0x4d,0xfd,0xab,0xcd,0xf4,0x49,0x0e,0xe1,0x1c +.byte 0xb9,0xd2,0x11,0xf0,0xa9,0xf6,0x3a,0x8a,0x7a,0x90,0x4d,0xf9,0xfd,0x3a,0x75,0xc2,0x60,0x8b,0x25,0xae,0x1d,0x3a,0xf5,0x81,0xb4,0x2b,0xf7,0x4d,0x27,0xbe,0x85,0x2d,0x65,0x60,0xf6,0xdb,0x2e,0x29,0xa7,0xee,0x26,0x07,0x07,0x17,0xfa,0x4a,0x93,0x72,0xad,0x97,0x5c,0x7d,0x4f,0xd2,0x29,0x37,0x0c,0x5e,0xbb,0xbd,0xbd,0x11,0xfd,0x77 +.byte 0xa1,0x6b,0xf9,0x4b,0x75,0x9b,0x02,0xb4,0x65,0xcf,0xe2,0x92,0xb2,0xef,0xf8,0x7e,0x71,0xf5,0x1b,0x6f,0xb5,0x54,0x9f,0x63,0xf4,0x6b,0xb2,0x2e,0xb6,0x4a,0xb8,0x9c,0xa0,0xb0,0xa8,0x4b,0x6a,0x1a,0x2a,0x7e,0x46,0x85,0x24,0x64,0x68,0xea,0x36,0x52,0x67,0xe5,0x42,0x82,0xa9,0x6f,0x9c,0x95,0x60,0xbf,0xc3,0x33,0x9d,0x40,0x23,0xdb +.byte 0x4e,0x8a,0xf2,0x3d,0xb8,0x8e,0xfb,0xd2,0xf1,0x99,0x6f,0x96,0x38,0xe2,0xd6,0x68,0x40,0x11,0x39,0xf7,0xa1,0x07,0xe4,0xc9,0x14,0x61,0x5b,0x8c,0xc5,0x95,0xa2,0xfb,0x86,0x51,0xd1,0xd3,0x2e,0x1f,0xf7,0x42,0xd2,0xc8,0xbd,0x8c,0xc3,0x24,0x0f,0x1c,0x61,0xfa,0xee,0x64,0xca,0xc0,0x12,0xab,0xdc,0xd4,0x08,0x31,0x7f,0xea,0x3b,0x24 +.byte 0x7e,0x4b,0x14,0x58,0x8a,0x48,0x9b,0xf2,0x04,0x7a,0x5b,0xec,0x49,0xaa,0xf9,0x33,0x72,0x8e,0x3e,0x06,0x80,0xe1,0xb5,0x1c,0x18,0x5c,0xe9,0x01,0xf4,0x78,0xeb,0x61,0x14,0x5f,0x52,0x1a,0x22,0x7e,0xbc,0x8f,0x38,0xa9,0x32,0xdf,0x9b,0x9d,0x96,0x13,0xc8,0xd1,0x5f,0xcf,0x51,0xbe,0xee,0xa4,0x04,0x31,0xc9,0xd1,0x0e,0xd9,0x54,0x3e +.byte 0x26,0x6d,0x25,0x98,0x65,0x83,0x53,0x4e,0xc6,0x01,0xb1,0x02,0x94,0x36,0x62,0xa2,0x6f,0x8b,0x1f,0x52,0x35,0x9c,0xa1,0xc7,0x50,0x54,0x27,0x96,0x51,0x4d,0xa8,0x85,0xc2,0xbd,0xe8,0x20,0xd7,0x55,0x14,0x89,0x64,0xe4,0xe1,0x70,0xcd,0xf0,0x40,0xfa,0x8e,0x35,0x20,0x53,0xec,0x73,0x3e,0x75,0x36,0xa3,0x69,0xf0,0xe0,0x0b,0x26,0x4d +.byte 0x9b,0xf8,0x03,0x72,0xb4,0x11,0x5f,0x5f,0x67,0xc1,0x7f,0xe1,0x71,0x94,0x14,0x96,0x7a,0xc4,0x81,0xab,0x26,0x15,0x7d,0xf9,0xa3,0xd7,0xab,0xaa,0x53,0xfd,0x42,0xb4,0xc4,0x79,0x1e,0xd4,0xed,0x14,0x83,0x00,0x5a,0x8d,0x86,0x6d,0xa0,0xef,0x29,0x03,0x2d,0xb1,0xf2,0xc1,0x97,0xa6,0xe8,0x23,0x6c,0x6a,0x56,0xe0,0x7a,0x4e,0xef,0x6d +.byte 0x8c,0x46,0x06,0x06,0x17,0xb0,0xcf,0x86,0xca,0x0f,0x8f,0x42,0x84,0xe5,0xb1,0xeb,0x3f,0x75,0x50,0x51,0x57,0xca,0x5f,0x49,0xdb,0x8b,0xc8,0x66,0xd5,0x86,0x86,0x9d,0x2e,0x9a,0x23,0x31,0xc4,0x5a,0xc0,0x7b,0x14,0x22,0xae,0xe4,0x52,0x8e,0x55,0xd9,0x01,0xf9,0x9c,0x7a,0x96,0x6d,0x74,0xf1,0x31,0x2a,0xfd,0xda,0x4e,0xa3,0x82,0x2f +.byte 0x54,0xc5,0x25,0x1d,0x85,0x6c,0xdc,0xa7,0x78,0x01,0x73,0x3e,0xcd,0x2d,0x53,0xc0,0xbf,0x23,0x05,0x19,0x93,0xbf,0x73,0x7f,0xdf,0x0a,0x38,0x9f,0x0d,0xae,0xb7,0x23,0xe6,0xb0,0x17,0xc0,0x2d,0xd4,0xd4,0x47,0x9c,0xc7,0xb6,0x42,0x8a,0xdc,0xa9,0x36,0x4f,0x07,0x02,0x1f,0x87,0x89,0xe8,0x48,0x33,0x7f,0x24,0x84,0x28,0xde,0x84,0x4a +.byte 0xb9,0xf9,0xe1,0xe5,0x4b,0xd7,0xf9,0x1a,0x44,0x4d,0xf9,0x4a,0xfc,0x97,0x03,0x03,0x71,0x2b,0xfe,0x04,0xfa,0x6c,0x52,0x07,0x54,0xb4,0xd2,0x60,0x34,0xb8,0x36,0x6f,0xc7,0x3c,0x64,0x37,0x8d,0x30,0x20,0x3e,0x66,0xac,0x1e,0x75,0x2d,0x76,0x3a,0x95,0xbb,0x23,0x7a,0x43,0x63,0xba,0xc9,0x7d,0x85,0x01,0xd9,0x65,0x20,0xc1,0x95,0x68 +.byte 0xcf,0x8a,0x4f,0x57,0x87,0x70,0x8e,0xe5,0x20,0xdb,0xd3,0x37,0x4c,0x03,0xc0,0x44,0x17,0x4c,0x2a,0x30,0x91,0xd9,0xb8,0x04,0xaa,0xcb,0xe9,0x8f,0x8f,0xe0,0x9a,0x79,0x1e,0x40,0x65,0x47,0x3d,0x4f,0x0e,0x7e,0xfc,0x8f,0x0c,0x20,0xe3,0xc6,0x5c,0x90,0xa8,0x09,0x41,0xbd,0x4b,0x55,0x4e,0xcc,0xeb,0xba,0x48,0x69,0xa2,0x5b,0xa0,0x41 +.byte 0x15,0xa6,0x1f,0x6b,0x6f,0xa0,0x26,0x2b,0x07,0xbd,0xb2,0x49,0xda,0xa0,0x97,0x22,0x37,0xcc,0xc3,0x05,0x4c,0x73,0x8f,0xb2,0x81,0xcf,0xe3,0xa4,0x23,0x96,0xe8,0x3d,0x29,0x00,0xbd,0xfe,0xec,0x97,0x65,0x94,0xf8,0x89,0x51,0x35,0x1b,0x72,0xff,0x6a,0x85,0x8c,0x53,0x35,0x7a,0x4f,0x11,0x5e,0x95,0xcf,0x9e,0x0f,0xef,0xbc,0x64,0xee +.byte 0x3a,0x6e,0xa1,0x4f,0x29,0x41,0x99,0x33,0xdc,0x7b,0x33,0xc4,0x82,0x8a,0x23,0x62,0x59,0x2c,0x2e,0x11,0x6e,0xec,0x6a,0xfb,0xe1,0x28,0x20,0xf4,0x38,0x48,0xf8,0x69,0xae,0x53,0x2b,0xd8,0x60,0x3b,0x37,0xf4,0xb1,0xa4,0xeb,0x80,0xd1,0x1f,0x11,0xd4,0x12,0x62,0x9f,0x1a,0x93,0xf7,0xfe,0x08,0x22,0x72,0x1b,0x51,0xa4,0x12,0x6e,0xe3 +.byte 0x59,0x23,0xeb,0xf4,0x6e,0x03,0xe6,0x1e,0x7e,0x94,0xfe,0x21,0xa2,0xb6,0x41,0x75,0xb2,0x8f,0x24,0x41,0xa3,0x08,0x33,0xec,0xf7,0x45,0x3c,0x55,0xd2,0xb9,0x5f,0x7e,0x61,0x37,0x17,0x45,0x9d,0xf9,0x87,0x26,0x07,0x65,0xee,0x7c,0x82,0x4e,0x96,0x53,0xea,0x50,0xa4,0x99,0xb9,0xe4,0xe1,0x79,0x02,0xd2,0x1f,0xa3,0x1f,0x1c,0x13,0x48 +.byte 0xf3,0x36,0x56,0x84,0x56,0x58,0xbd,0x52,0x06,0x21,0x95,0x0a,0xe1,0x45,0x43,0xe6,0x9f,0xfa,0xbd,0x1a,0x60,0x3f,0x6b,0x93,0x8c,0x22,0x17,0x4f,0xc9,0x13,0xdf,0x94,0x3e,0xd8,0x1f,0x22,0xf8,0xc4,0xaf,0xe3,0xcb,0x03,0x67,0x23,0x90,0xee,0x36,0x8e,0x3f,0xc6,0x0d,0xaf,0xd5,0x0f,0x41,0xd8,0x22,0xe3,0xf7,0x6d,0x19,0x99,0x25,0x51 +.byte 0x12,0x8d,0xa1,0x19,0xc6,0x26,0xa3,0x1a,0xce,0x9b,0x0f,0xae,0xbf,0xd5,0x80,0x9b,0x4a,0x6c,0xc9,0xa7,0xd7,0x65,0x67,0xb7,0x71,0x77,0xae,0xa1,0x31,0x8b,0x3a,0x0d,0x33,0x43,0xb1,0x08,0x6c,0x97,0xd4,0x41,0xe1,0x83,0x50,0xc8,0xc5,0x44,0x5a,0x6d,0xab,0xa5,0x89,0x5f,0x87,0xb4,0xfc,0x5a,0x29,0xa0,0xb3,0x6c,0x62,0x46,0x58,0x55 +.byte 0xd0,0x60,0x3f,0x6b,0x1b,0x1b,0x47,0x0d,0x02,0x2c,0xd7,0x92,0x37,0xc6,0x80,0xf1,0x0c,0xf8,0x91,0xb5,0x20,0x49,0xdd,0x56,0x59,0xb2,0xd6,0x00,0x1d,0x1c,0x87,0xbd,0x99,0x17,0xab,0x5f,0x47,0xaf,0x0e,0x87,0xf1,0xca,0x59,0xec,0xa1,0x3d,0x1e,0x60,0x3e,0xcb,0x23,0xe6,0x26,0x9e,0xc5,0xf6,0xaf,0xab,0x4b,0x9f,0xac,0xae,0x09,0xd9 +.byte 0x4b,0xfa,0x24,0x55,0xfc,0xae,0x02,0x29,0xba,0xbb,0xd6,0x13,0x0d,0x4e,0xef,0x8b,0x44,0xe2,0x84,0xd4,0xef,0x5b,0x9a,0xca,0xe7,0x2a,0xdd,0x49,0xdb,0xc9,0xf6,0x77,0xdf,0xff,0x3b,0x79,0x7c,0x0b,0x11,0x30,0x36,0x84,0xf0,0xe4,0x97,0x5e,0x7c,0x48,0x9a,0xd6,0x40,0x63,0xec,0x8e,0x92,0x1b,0x44,0x83,0xaa,0x3c,0x47,0x49,0x9b,0x21 +.byte 0x35,0x73,0x41,0x78,0xdc,0x06,0xa5,0x18,0xe0,0x0b,0xb9,0xab,0xf3,0x0d,0xdc,0x84,0x1c,0x52,0xef,0xc1,0x4d,0xad,0xdb,0x71,0xf0,0x33,0x4e,0xaf,0xc3,0x0c,0x8e,0x28,0x92,0xf8,0xbd,0xae,0x8f,0x2d,0x36,0x8a,0xda,0xff,0xc5,0x7f,0x27,0xdc,0xb0,0xd3,0x03,0xae,0xb8,0xdd,0x20,0xf8,0x5c,0x31,0xac,0xbc,0x36,0x71,0xde,0xc9,0x71,0x7d +.byte 0x21,0x68,0xcd,0xb0,0xfc,0x9d,0x96,0x6b,0xfa,0xb0,0x3a,0xfb,0x05,0xc7,0x89,0xd1,0x50,0x7a,0x50,0x52,0x53,0x29,0xb6,0x25,0x8f,0x96,0x75,0xb3,0x66,0xac,0x1c,0xf9,0x04,0xe0,0xe7,0x9f,0x0d,0x1d,0x65,0x84,0xb2,0x47,0x08,0xfe,0x7b,0xaa,0x15,0xf0,0x35,0x4a,0x68,0x74,0x9d,0xfe,0x05,0x4d,0xe4,0x0a,0x4e,0xc1,0xba,0x84,0x37,0x95 +.byte 0x6e,0xd3,0x22,0xd6,0xc4,0x6c,0x57,0xb7,0x0d,0xf9,0x55,0x76,0xec,0x4e,0x4d,0x32,0xd2,0x7f,0xd4,0xec,0x8c,0xff,0x32,0xe9,0xd5,0x83,0x13,0x43,0x85,0x67,0x0c,0x36,0x2a,0x3f,0x6d,0xf4,0xfe,0x4a,0xf8,0xd8,0xd8,0x23,0x77,0x51,0x87,0x0c,0x82,0x70,0x88,0xd8,0x8c,0xe2,0x9a,0x4a,0x9b,0xf0,0xbd,0x56,0xc6,0xa7,0x64,0x65,0xf6,0x61 +.byte 0x5e,0xc1,0x8a,0x03,0x36,0xda,0x9f,0x22,0xa1,0xac,0x48,0x91,0x98,0x28,0x33,0x76,0x87,0x0d,0x5b,0x58,0xa3,0x09,0xb3,0xdd,0xcf,0xff,0x12,0x19,0x35,0x66,0x07,0xa7,0x62,0xdb,0x0d,0xd5,0xbd,0x17,0x3d,0x8a,0xb0,0x3e,0x77,0x72,0xf6,0xe6,0xc5,0xb2,0xd6,0x09,0xa8,0xf1,0x7c,0xbb,0x89,0x56,0x3d,0x27,0x37,0x03,0x45,0x68,0x23,0x71 +.byte 0x6e,0x13,0xc6,0x12,0xef,0x52,0x69,0x83,0xe4,0x11,0xdb,0x18,0x4a,0x54,0xce,0xf4,0x40,0x33,0x89,0x9a,0x5b,0x6e,0xa4,0xf7,0xa8,0x9a,0x74,0x39,0xff,0x32,0xe4,0xee,0xe0,0xdb,0xf8,0x0c,0x05,0x53,0x55,0x46,0x4d,0xa3,0x9e,0x9a,0x25,0x8f,0x24,0xbc,0xc2,0x91,0xa8,0x80,0x14,0xb0,0xcf,0xb2,0x69,0x75,0x7d,0x1a,0x8e,0x42,0x2e,0x6c +.byte 0x93,0x6d,0xe4,0x49,0x6d,0x8c,0x72,0x16,0xf4,0x36,0x94,0xb6,0x30,0x1d,0x83,0x5f,0x53,0x56,0xb3,0xcf,0x84,0x94,0x1a,0xd8,0x07,0xc9,0x0f,0x0d,0xf5,0xf8,0xd2,0x50,0x8e,0xa9,0x47,0xa4,0x66,0xbf,0xa5,0x2a,0x4c,0x23,0x02,0xac,0xdb,0x1d,0xa5,0xa3,0x04,0xa6,0xaa,0x78,0xf0,0x66,0xc8,0x02,0xef,0x6b,0x8d,0x38,0x8e,0xb9,0x14,0x2a +.byte 0x8f,0x43,0x83,0xb6,0x90,0x64,0x15,0x35,0x36,0x17,0x1e,0xb7,0x98,0x39,0x43,0x73,0xb0,0xfe,0x1e,0x75,0xf5,0xda,0x51,0x7a,0xb5,0x5a,0x6e,0xa4,0x68,0xbc,0x84,0x19,0x7a,0x6f,0xe3,0xf4,0x05,0x1f,0x3c,0x4a,0x18,0x7d,0x97,0x9a,0xcb,0x9b,0xe1,0x53,0x90,0xaa,0x37,0xcc,0xf5,0x1d,0x39,0xa6,0x7e,0x3a,0x47,0x75,0x70,0x97,0xa1,0xb1 +.byte 0x8c,0x8d,0xb2,0xb0,0xa3,0xdd,0x4f,0x44,0xaf,0x47,0xc2,0x44,0x06,0x61,0x2a,0x40,0x87,0x9e,0x98,0x0f,0x2f,0xe7,0xb4,0xf9,0xd3,0x02,0x71,0x15,0x50,0x43,0x64,0x2c,0xbb,0x55,0xc8,0xc7,0x1d,0xc5,0xb5,0xd7,0xd9,0xea,0x12,0x5e,0xf5,0x97,0xf0,0xa0,0x30,0x88,0x73,0x44,0x6e,0xe6,0x3a,0xbd,0x1c,0x0e,0xee,0xe4,0xc4,0x8c,0xb6,0xcd +.byte 0x6a,0x95,0xf4,0x93,0xa1,0x30,0xe8,0x10,0x76,0x8d,0xc8,0xba,0x1b,0xd0,0xba,0xe9,0xe1,0x0a,0x67,0x99,0x0a,0xbd,0xa0,0xa3,0x14,0xd9,0x20,0xdf,0x9e,0x12,0x71,0x29,0x9d,0xd8,0x88,0x91,0xb6,0x30,0xe7,0x38,0xdb,0x77,0xcd,0xcb,0x9b,0xa6,0x58,0x64,0xf8,0xc7,0x41,0x3c,0x4f,0xc8,0x64,0x1c,0x5d,0x87,0xdf,0x38,0x2a,0xd3,0x96,0x83 +.byte 0xcc,0xe4,0x8d,0xdd,0x27,0xfb,0x9d,0x23,0x1c,0xbc,0x2a,0xf1,0xce,0xb2,0x63,0xf8,0x52,0xd3,0xfc,0x8f,0xe4,0x72,0x88,0xd6,0xdb,0x27,0x10,0x96,0xd6,0x05,0xc3,0xd9,0x0c,0x94,0x6f,0xb2,0x9a,0x3b,0x6f,0x3c,0xda,0xfb,0xc8,0x34,0x81,0xf8,0x9b,0x75,0x24,0x1b,0x50,0xfa,0xe4,0xbe,0x7a,0xbf,0xfc,0x33,0xdb,0x7f,0x31,0x95,0xd5,0x12 +.byte 0x31,0x76,0xe5,0xdb,0x52,0x01,0x83,0x8a,0xeb,0x70,0xc7,0x26,0x71,0xd2,0xec,0xd0,0x05,0x94,0x7e,0x48,0x88,0x1b,0x8b,0xbe,0x0c,0x91,0x43,0x24,0x5a,0x18,0xd3,0xb4,0xd8,0x78,0xde,0x0f,0xe5,0x00,0xd8,0x70,0xd5,0xf6,0xe2,0x91,0x7a,0x6e,0x8c,0x8c,0x5d,0x07,0x27,0x3f,0x73,0x75,0x47,0x20,0x8a,0xb8,0x4f,0xe9,0xe6,0xad,0xcf,0x63 +.byte 0xdf,0xcd,0xa4,0x27,0xde,0xb7,0x8b,0x30,0xec,0x29,0x2c,0x87,0xe1,0xf3,0xd9,0x05,0x44,0xfd,0x36,0xf3,0x70,0xe3,0x55,0x9a,0xf9,0x04,0x8c,0xc2,0x3a,0x9f,0xbb,0x07,0x7f,0xed,0x6f,0xdb,0x1f,0x7a,0xd2,0x6c,0x54,0xa5,0x18,0xe5,0x83,0x00,0xd4,0x51,0xee,0x67,0xbc,0xf6,0x17,0x2d,0x4e,0xe2,0x89,0x94,0x5a,0x5b,0x90,0x13,0x14,0x19 +.byte 0xdc,0xaf,0x3f,0x09,0x45,0xd1,0x6b,0x40,0x48,0x6f,0xee,0x1c,0x9b,0x92,0xa0,0xf1,0x32,0x34,0xd5,0xd5,0x7f,0xf2,0x55,0xbd,0xd8,0x3b,0xc2,0xc5,0x06,0x37,0x29,0xb3,0xdb,0xbf,0xc3,0x92,0x1f,0x25,0x38,0xa2,0x76,0xcd,0x5e,0x71,0x49,0x26,0xb8,0xef,0x5e,0x03,0xf4,0x81,0x00,0x0b,0xc9,0x69,0xa1,0xf5,0xa0,0x34,0xdf,0x62,0x0b,0x64 +.byte 0x41,0x80,0x78,0x7b,0x89,0x9f,0x19,0x28,0x8f,0x75,0xbb,0x49,0xf7,0x4e,0x2b,0x31,0x4c,0xf9,0x50,0xd0,0x17,0xa4,0xcc,0xe3,0xda,0xe3,0x95,0xf7,0x6b,0x01,0x41,0x11,0xae,0x2f,0x9c,0xdd,0x55,0xb2,0xd5,0x7b,0x99,0x71,0x30,0x5d,0x02,0x8d,0xdf,0xca,0xe9,0xcb,0x84,0x69,0x69,0x30,0x3c,0x2c,0x4f,0x50,0xf7,0x33,0x9a,0x75,0xac,0xe1 +.byte 0xc2,0xb0,0x39,0x68,0x41,0xfb,0x30,0xf2,0x3f,0x7d,0xc0,0xde,0xbd,0x11,0xf9,0x09,0x62,0x51,0x05,0x82,0x78,0x80,0xd5,0x4d,0x0b,0x63,0xc0,0x20,0xff,0x01,0x41,0xdc,0x01,0x41,0xd9,0x0d,0xa8,0x68,0xd5,0xa1,0x3d,0x2a,0xf9,0x04,0x09,0x78,0x90,0x86,0xff,0xe6,0xb3,0x25,0x0c,0x29,0x96,0x61,0x4f,0x9f,0x93,0x82,0x1e,0x5c,0x5a,0x50 +.byte 0xb5,0x8f,0x8b,0x15,0x62,0x52,0x7a,0xa3,0xaf,0xac,0xbd,0xf1,0x21,0xfe,0x5c,0xc0,0x21,0x54,0x3a,0xba,0xbd,0xee,0xdb,0x92,0xc5,0x2b,0xff,0x4c,0xda,0xa0,0x0d,0x56,0x6c,0x23,0x9b,0x73,0x86,0xee,0xab,0x9b,0xf9,0x67,0xbb,0xf0,0xde,0x97,0xf5,0x1a,0x13,0xaf,0x0e,0x7c,0xe9,0xef,0x78,0xf9,0xd1,0x6b,0x01,0x85,0xa7,0x4e,0x33,0x2e +.byte 0x04,0x21,0x59,0x34,0x57,0x2c,0xe5,0x96,0x92,0x08,0x8d,0xe9,0x44,0xd6,0x37,0x13,0xc8,0x6b,0x28,0x1f,0xbd,0x3b,0x52,0x3f,0x8e,0xa0,0x2e,0x84,0xfc,0xb7,0x8f,0x43,0xbc,0x69,0x47,0xc1,0xf6,0x91,0x0d,0xa9,0xd5,0x7d,0x5c,0x34,0xd8,0x1c,0x6b,0xb7,0x76,0xa9,0xad,0x6b,0x12,0xb4,0xfe,0x42,0x05,0xa2,0xbc,0x22,0xfb,0x1a,0xc6,0x82 +.byte 0x4d,0xc2,0x98,0x34,0x5f,0xa0,0xc1,0x18,0x22,0xbe,0xc3,0xaa,0x14,0xd5,0xe9,0x6e,0x7c,0x24,0x19,0x95,0x40,0xeb,0x87,0x9d,0x47,0xd4,0xc8,0x46,0x35,0xf8,0x31,0x75,0xd3,0x21,0x75,0xd9,0x9d,0x09,0xb0,0x05,0x18,0x25,0x09,0x09,0xd1,0x8a,0x85,0x54,0x4b,0x57,0x64,0x42,0xf4,0xa4,0x9e,0x17,0x68,0xae,0xc8,0xa4,0x25,0x56,0xaa,0xa8 +.byte 0xf8,0xd9,0xc2,0x3a,0xe9,0x4c,0x25,0x86,0x4b,0x4c,0x5a,0xd7,0x69,0xc5,0xc8,0x3e,0xbf,0x8d,0x7e,0x11,0xbb,0xf9,0x78,0xc1,0xbd,0x14,0x79,0xa4,0x14,0xad,0x78,0x17,0x2e,0x26,0x58,0x69,0xea,0x94,0x8c,0x3e,0xbb,0xac,0x61,0xbb,0x4f,0x90,0x06,0x82,0x6e,0xea,0xd3,0x1a,0xbc,0xbd,0xf0,0xee,0x89,0xc6,0x75,0x1b,0x57,0x09,0xa6,0x3f +.byte 0x8a,0xd4,0x78,0x9b,0x9f,0x99,0xc8,0x9d,0x99,0x1a,0x79,0xb4,0x2d,0x69,0xce,0x3a,0xb7,0x2d,0xed,0xf4,0xe5,0xeb,0x09,0xe6,0x57,0xd3,0x66,0xb2,0xf3,0xfb,0xfb,0xda,0xdc,0xfa,0x1c,0x2e,0xa9,0xd8,0x68,0x5e,0x3d,0x2f,0x2c,0x11,0x2a,0x60,0xb4,0x08,0xa9,0x2d,0x9e,0x41,0x8a,0x02,0x82,0x73,0x58,0x25,0xba,0xca,0x4f,0x46,0x5e,0xbf +.byte 0x86,0xb5,0x09,0xa9,0xde,0x86,0x91,0x47,0x8c,0xa2,0x8f,0xc0,0xc1,0xff,0xc0,0x18,0xdb,0x00,0x5c,0xab,0x20,0xe4,0xbd,0x00,0xaa,0x19,0x32,0x4c,0xf0,0xa7,0x0b,0x8e,0xec,0x91,0x50,0x87,0x8c,0x73,0x68,0xe4,0x47,0xd3,0xd9,0x4e,0x5f,0xc0,0x62,0xd0,0xa4,0x01,0x2f,0xe0,0x1e,0x5a,0x63,0x6b,0xca,0xd0,0xdf,0xda,0x9f,0x89,0xd5,0x73 +.byte 0xfb,0x3f,0x98,0x20,0x6c,0x30,0x5a,0xd9,0xa6,0x41,0x47,0x82,0xde,0x2d,0x74,0x3f,0xcd,0x6a,0xe7,0x95,0x99,0x8c,0x52,0xa8,0xf9,0x45,0x29,0x40,0xbf,0x8a,0x3b,0x87,0x74,0x92,0x69,0x69,0x8d,0x41,0x84,0xa9,0x7d,0x44,0xd6,0x1d,0x0e,0xee,0x56,0xef,0x3e,0xac,0xa9,0x20,0x16,0xaa,0xf8,0xd0,0x21,0xf6,0x16,0x7d,0x4b,0x7f,0x1d,0xcc +.byte 0x5e,0xad,0x25,0xec,0xd9,0x56,0x8a,0x1e,0xc8,0xd5,0x40,0xb5,0x21,0x48,0xbe,0xfe,0xfa,0x4e,0x3c,0x88,0x7f,0x59,0xcd,0x40,0xe5,0xd8,0xac,0x98,0xde,0xba,0xd9,0x6a,0xbe,0x7b,0x07,0xd7,0xfb,0x0f,0xd3,0xb9,0x14,0x6a,0x85,0xcb,0x99,0x6f,0xd9,0xb5,0x22,0x78,0xab,0xa4,0x42,0x6b,0x33,0x4f,0x3c,0xfd,0xcd,0xe1,0x68,0x73,0x08,0x66 +.byte 0x34,0xe8,0xa5,0x51,0xfd,0x6f,0xdc,0x84,0x77,0x67,0x2e,0x07,0x1b,0xb4,0xc8,0xda,0x22,0x24,0xab,0x61,0x85,0x17,0xd8,0xa1,0x50,0x28,0xd0,0x3b,0xd6,0xb3,0x6a,0x7a,0x08,0xba,0x34,0x49,0x47,0x1c,0x1a,0x4a,0xd1,0x7e,0x6b,0xdb,0x74,0x26,0x9c,0x0a,0xbd,0x3d,0x29,0x93,0x81,0x02,0xd3,0x08,0x20,0xb5,0x56,0x0b,0x3d,0xf2,0xf3,0x31 +.byte 0x6f,0x28,0xe2,0x61,0x81,0x17,0xbc,0xcd,0x7b,0xaa,0x49,0xb9,0x74,0xb5,0x88,0x6a,0xce,0xe3,0x6b,0xbe,0xa8,0x08,0x9c,0xf4,0xe2,0xe7,0xf4,0xfa,0x5b,0x89,0x9c,0xaa,0x12,0xdb,0xd0,0x54,0x1e,0xb7,0xa3,0x66,0x56,0xf8,0x58,0xb5,0xe7,0x5b,0x04,0xb4,0x12,0xb4,0x85,0xfd,0x22,0xde,0x8f,0xc8,0x60,0x1d,0x84,0xc7,0xae,0xae,0xbd,0x63 +.byte 0x0a,0x17,0xae,0x64,0x1e,0x31,0xaa,0xdd,0xd7,0xf4,0xe4,0xf7,0x3b,0x00,0x42,0xde,0xa6,0xc6,0x77,0x75,0xa7,0xbd,0x3b,0x92,0x97,0x10,0xad,0x5a,0x9a,0x40,0xa3,0xbb,0x5a,0xe0,0x4e,0x10,0x94,0xa7,0xbd,0x6f,0x0f,0xbe,0xc2,0xd9,0x7d,0xf9,0x5e,0x8c,0xfe,0x1b,0x6f,0xb9,0xd0,0xa8,0xfd,0x8f,0x21,0x69,0x1e,0xc5,0x55,0xa4,0xe8,0x4b +.byte 0x99,0x5c,0x35,0xba,0xc9,0x93,0xf0,0x59,0x9e,0xd9,0x1b,0x1d,0xcd,0x0f,0x8b,0xcc,0x55,0x34,0x2e,0xee,0x06,0xaa,0xb4,0xce,0xc1,0xc3,0xb3,0xa3,0x54,0x9b,0x21,0xdf,0xc3,0x3b,0xe5,0x4e,0x89,0x0a,0x81,0xfa,0x3e,0x08,0x66,0xe5,0x2a,0x08,0x60,0xba,0xdf,0xe1,0x81,0x98,0x7b,0xba,0xd3,0x00,0x00,0x3d,0xbc,0x3c,0x5f,0x94,0xa0,0x25 +.byte 0x63,0x66,0x52,0x0d,0x20,0x06,0x6e,0x59,0xbf,0x06,0x0a,0xf9,0xd0,0xbe,0xfb,0x31,0x41,0x22,0x36,0x27,0x4f,0xd1,0x16,0x8d,0x29,0xc8,0x2e,0x76,0xae,0xc6,0x26,0xa5,0x35,0x56,0x78,0x75,0x84,0x5b,0xcf,0xc1,0x0a,0x69,0xe4,0x53,0x62,0x6e,0xc7,0xb3,0x0c,0xdf,0xe0,0xb6,0x38,0x8b,0x6f,0x76,0x05,0x80,0x84,0xf8,0xe9,0x9e,0x86,0xf6 +.byte 0xcb,0xe0,0xdd,0x7c,0xde,0xab,0xe6,0xbf,0x9d,0x44,0x55,0x3a,0x71,0xc5,0x91,0x07,0xef,0x50,0x23,0x14,0x5d,0x80,0x6b,0x07,0x55,0xba,0x76,0x77,0x31,0x85,0xf7,0x8a,0x1f,0x34,0xba,0x87,0x10,0x53,0xb6,0xec,0x09,0x7a,0x30,0x91,0x1b,0x4e,0x82,0x5d,0x53,0x51,0x88,0xfe,0x2a,0x40,0x63,0xd1,0x0b,0x14,0x51,0x0f,0x15,0xb6,0x2a,0x38 +.byte 0x62,0x72,0x27,0x18,0x80,0x6b,0x7f,0x73,0x4c,0xcf,0xde,0xaa,0x5f,0x33,0x43,0x12,0x37,0x8c,0xc5,0xab,0xf0,0x7e,0x69,0xaf,0xc8,0x84,0x7a,0x1b,0x13,0xce,0x17,0xb0,0x67,0xb2,0x83,0xdb,0x1b,0x71,0x67,0xd6,0x86,0x3d,0xa5,0xfc,0x51,0xc9,0xcf,0x94,0x9a,0xaa,0x8a,0xf8,0xff,0x44,0x9c,0x80,0x73,0x35,0xd1,0x8c,0xb4,0x78,0xc1,0xcc +.byte 0xb9,0xd5,0x02,0x28,0x44,0x85,0x8b,0x4b,0x74,0xc2,0x2b,0x60,0xa1,0xbf,0x5d,0xe5,0x98,0xec,0x24,0x8a,0x68,0xf3,0xa2,0x37,0x0b,0xbc,0xbb,0x5d,0xe0,0x87,0xe9,0xec,0x9f,0x9f,0x6e,0x62,0x7f,0x0a,0x11,0x41,0xa4,0x1d,0x1e,0xde,0x45,0xe8,0x3e,0x05,0x73,0xd7,0xe3,0x53,0xb6,0x7f,0x94,0x13,0xef,0x33,0xfa,0x91,0x94,0x1c,0x3d,0xe8 +.byte 0xb9,0xb3,0x0e,0xff,0xda,0x17,0x49,0x15,0x51,0x59,0x05,0xef,0x16,0xf5,0x10,0xcf,0x88,0xdd,0x1f,0x6d,0xe9,0x53,0xc2,0x13,0xe4,0xb3,0x01,0xff,0x75,0xe6,0xa9,0x4d,0x46,0x0c,0x79,0x76,0x4a,0xa2,0xf0,0x38,0xa0,0x89,0xda,0x92,0x79,0x22,0xa3,0x46,0xb6,0x7f,0x04,0xae,0xfc,0xa0,0xdc,0xf1,0x40,0xe6,0x46,0x0b,0x1e,0x37,0x00,0xae +.byte 0x61,0x4d,0xb5,0x7f,0x7e,0x00,0x6c,0x94,0xea,0x89,0x94,0x30,0x8b,0xa5,0x2f,0x6a,0xcb,0x0d,0x08,0xd4,0x50,0xf4,0xa0,0x1e,0xf8,0x83,0xd3,0x25,0xb7,0xcd,0xc2,0x29,0x1a,0xc0,0x34,0x1d,0xeb,0xc9,0xcc,0x9a,0x8d,0x66,0x36,0x05,0xa0,0xc2,0xee,0x0e,0xe5,0x8c,0x41,0xc0,0x55,0xfd,0x2a,0x9f,0x30,0x09,0x08,0x94,0xb1,0xc6,0x79,0xae +.byte 0x4e,0xbe,0x84,0xdb,0xe4,0x81,0xce,0x0c,0x44,0xb6,0x33,0x6c,0xcd,0x6f,0x91,0x36,0x28,0x5b,0xe3,0x60,0x3e,0xfe,0xc5,0x4d,0xee,0x89,0x70,0x57,0xf0,0xba,0x74,0xcb,0xcb,0xb8,0xf3,0x91,0x74,0x97,0xe3,0x2d,0x8c,0x75,0x6c,0xa9,0xa5,0x27,0x36,0x90,0x2e,0x41,0x19,0xdd,0x37,0xbe,0x2b,0xef,0x1f,0x75,0x8f,0x14,0xcc,0x94,0x9d,0xa7 +.byte 0xef,0x1e,0x62,0x93,0xdb,0x2b,0xa8,0xef,0xf5,0xe8,0xbd,0x11,0x2e,0x59,0xd6,0x81,0x42,0x2b,0x90,0xe0,0xcc,0xb5,0x0b,0xf4,0xb6,0xcb,0xc9,0xc7,0xe5,0xc4,0x9d,0x70,0x40,0xa8,0xf0,0x24,0xb8,0x57,0xcf,0x4a,0xfa,0xf8,0xc0,0x97,0x0f,0x84,0xd0,0x59,0x5c,0x86,0x9e,0xfd,0x39,0x54,0x13,0x00,0x0d,0xb7,0xb0,0x8b,0xf7,0x75,0xb8,0xef +.byte 0x6f,0xcf,0xc1,0xec,0x5a,0x3d,0xf4,0x0d,0x74,0xa3,0x81,0x7e,0x71,0xe1,0x67,0xf3,0x5a,0xde,0xe8,0xea,0xe3,0x18,0x7f,0x85,0x4d,0x0f,0x2c,0xbe,0x59,0xfa,0x97,0x1c,0xd5,0x6c,0x97,0x8a,0xfe,0x97,0x7c,0x47,0x2a,0x8f,0x8a,0x8d,0x84,0x61,0x0d,0x5c,0x8f,0x72,0x2e,0x89,0x50,0xff,0x85,0x40,0x6f,0x03,0x1f,0x15,0x47,0xf5,0x5f,0x3a +.byte 0x52,0x26,0xbd,0x04,0x82,0x8c,0xee,0x22,0x23,0x84,0x6b,0x7d,0x35,0x28,0x2d,0xa9,0xaf,0x89,0x30,0xc3,0x8a,0x8c,0xbf,0xc3,0xa5,0x34,0x73,0xbe,0xaf,0x29,0x3c,0x26,0xed,0xa9,0x53,0x5e,0x1c,0x54,0x51,0xd5,0x20,0x34,0x4a,0x93,0x0d,0xd3,0xaa,0x26,0x37,0xce,0x5d,0x12,0xb7,0xea,0x80,0x38,0x5d,0x46,0x0b,0x72,0x63,0x5a,0x0f,0x08 +.byte 0x9a,0x65,0xdf,0xa4,0xb7,0xe5,0x24,0x8f,0x08,0xb1,0xed,0x5a,0x0d,0x78,0x2c,0xa9,0xf3,0xee,0x6a,0xf8,0x73,0x39,0x61,0x6d,0x50,0x61,0x23,0x88,0x82,0x28,0x91,0xdb,0xbb,0xae,0x9c,0x39,0xe2,0xc2,0xe7,0x42,0xef,0xf9,0xdb,0xa7,0x32,0x19,0x98,0x0d,0xbb,0x67,0x68,0xe9,0x68,0x17,0xb2,0x54,0xf7,0xec,0x0c,0x35,0x05,0x76,0x73,0x26 +.byte 0x79,0xb5,0x6d,0xc6,0xc8,0x84,0x80,0x84,0xf9,0xbb,0x95,0xfb,0x39,0xf9,0xaf,0x2d,0xb5,0xd6,0x72,0xad,0x77,0x35,0x09,0x32,0xaf,0xcc,0xc3,0x62,0xd9,0x02,0x33,0x1c,0x9f,0xc0,0xf1,0x18,0x54,0xdf,0xaf,0x0b,0x94,0x52,0xab,0xac,0x7e,0x62,0xab,0x07,0x11,0x83,0xe5,0x7b,0x1e,0xb5,0x3d,0xa3,0x8a,0xdc,0x43,0xf4,0x9c,0x39,0x3a,0x72 +.byte 0x01,0x94,0xe5,0xfd,0x0a,0x3d,0x64,0x73,0x56,0x37,0x14,0xc6,0x7b,0x1d,0x81,0xd2,0x62,0x8f,0xe9,0x5f,0x8e,0xb8,0xb4,0xfa,0xfb,0x36,0xa1,0x63,0xe6,0x89,0x87,0x0c,0x87,0x2b,0xa9,0x5f,0x97,0x29,0x0c,0xd2,0x19,0x91,0x83,0x46,0x1f,0x93,0xdb,0x89,0x2c,0xf6,0x32,0x46,0x8b,0x47,0x52,0xad,0x86,0x74,0xda,0x26,0x71,0x6c,0xf4,0x25 +.byte 0xa6,0x57,0x89,0xa4,0xd5,0xd8,0x67,0xf7,0x49,0x2a,0xd8,0x6b,0xb9,0xd7,0x97,0xf7,0x66,0xfd,0xf8,0xc2,0x39,0x5f,0xac,0xd3,0xab,0x84,0xac,0x1b,0x6c,0x04,0x00,0xe6,0x0b,0x5e,0xe8,0xc0,0xa3,0x5e,0xe5,0x83,0xb2,0x6a,0x97,0x0e,0xb0,0xa6,0x13,0x77,0xb2,0xc4,0xbb,0x2c,0x27,0x3c,0xca,0x41,0xc4,0x43,0xda,0x92,0xa8,0x0d,0xc8,0x09 +.byte 0x8e,0x84,0x46,0x9a,0xd5,0x88,0x3c,0x85,0x3a,0xcd,0x27,0xd3,0x0c,0xaa,0x29,0x74,0xeb,0x3d,0x7d,0x10,0x03,0xc4,0xa7,0x95,0x90,0xb6,0x95,0xf2,0xe4,0xc4,0x35,0x3c,0x9f,0x1b,0x6d,0xd4,0x4e,0xdd,0x44,0xb3,0x59,0x5a,0x75,0xc7,0x2b,0x82,0x3e,0x71,0x34,0x97,0x16,0x86,0x83,0x26,0x2c,0x23,0xc8,0x92,0x3c,0xfe,0xaf,0xcf,0x7c,0x8f +.byte 0x0d,0xe7,0x8a,0xa2,0x55,0x56,0x20,0xa3,0xdf,0x5b,0x77,0x08,0xbe,0x3d,0x5c,0x07,0xfe,0xb9,0x14,0xd7,0xec,0x30,0x41,0xcc,0x17,0x4f,0x63,0x34,0xad,0x7d,0xe7,0xac,0x36,0xb6,0x1c,0xc7,0x10,0xc0,0x5a,0x18,0xe0,0xc1,0x50,0x6b,0xb0,0x91,0x11,0xa7,0x02,0x4c,0xdf,0x1f,0x62,0x0e,0xa3,0x3e,0xd0,0xc3,0xbf,0x27,0x6a,0xe3,0xde,0x36 +.byte 0x19,0x06,0x4f,0x53,0x5d,0xd3,0x94,0xac,0x4b,0x28,0x72,0x46,0xd8,0x17,0xd8,0xf1,0x47,0xcb,0xd7,0x8d,0xdd,0x85,0x57,0x23,0xf6,0x9d,0x53,0x8f,0x67,0x02,0x68,0x9b,0xf2,0x8e,0x23,0xce,0x27,0xbe,0xef,0xc0,0xd1,0x0d,0x49,0xae,0x4d,0xd3,0xa1,0xc6,0x54,0xfa,0x38,0xc0,0xf7,0xc2,0xb0,0x5c,0xd9,0x6c,0x92,0xb8,0x37,0x91,0xfc,0xf6 +.byte 0x52,0x2d,0x3a,0x48,0x92,0xdb,0xcd,0x8e,0x7b,0xa6,0xe7,0xe0,0x27,0x77,0xda,0x0d,0x34,0xff,0x33,0xe2,0x26,0xc2,0xfa,0xea,0x50,0xdd,0x13,0x05,0x7c,0x79,0x40,0x05,0x69,0x31,0x4e,0x32,0x73,0x67,0x21,0x5f,0x18,0xc1,0x18,0x1b,0xea,0x19,0x24,0xc7,0xa3,0x55,0x44,0xcc,0xd3,0x5e,0x83,0x4e,0xea,0x3f,0xc6,0x58,0x9f,0x0b,0x0e,0xc6 +.byte 0x29,0x00,0x98,0x99,0xc8,0x71,0xab,0x55,0x77,0x1f,0xdc,0xd0,0xab,0x78,0xd7,0x9b,0x37,0x8f,0x35,0xc0,0x64,0x41,0x6b,0x2c,0x07,0x43,0x0a,0xc3,0x4d,0x8f,0xdc,0xa2,0x18,0x94,0xe3,0xd0,0xc3,0xb2,0xd2,0x84,0xe3,0x12,0x4b,0x31,0x20,0xcb,0x10,0x8b,0x74,0x57,0xf5,0x30,0x29,0x5e,0x37,0x8c,0xc7,0xb7,0xda,0x47,0xc7,0xca,0x59,0xf5 +.byte 0x6d,0x61,0x32,0x90,0xb3,0x85,0x2f,0xf8,0x1d,0x5d,0x82,0x2d,0x4a,0x93,0xb9,0x8a,0xbb,0x84,0xce,0x19,0xa4,0x8a,0xa5,0xfc,0x4e,0xa4,0x4c,0xa7,0x54,0x79,0x3a,0x7c,0x9d,0x32,0x74,0x80,0x63,0x98,0xdc,0x78,0x8a,0x0e,0xe8,0x79,0xa3,0x51,0x7b,0x1c,0x4c,0x5a,0xe6,0x3d,0x3f,0x68,0xd4,0x9b,0xc8,0xc2,0x96,0x82,0x5f,0x3c,0xab,0x1c +.byte 0xb8,0x09,0xfe,0xa1,0x2d,0x95,0x8c,0xf3,0x74,0xa4,0xb6,0x6d,0x96,0xa8,0x81,0xcc,0x0a,0x46,0xaf,0xce,0xfb,0xb3,0x6a,0x18,0x68,0xc0,0x73,0xc8,0xe7,0x3b,0x3f,0x55,0xda,0xde,0x69,0x1f,0x8d,0x2b,0xd4,0x9f,0x63,0xed,0xde,0xe5,0x6d,0xae,0xa1,0xdd,0xed,0xbe,0x58,0xc7,0x30,0x30,0x50,0x04,0x45,0x54,0x3a,0x5d,0xbc,0xac,0x33,0x13 +.byte 0x41,0x0f,0x07,0x1e,0xec,0x4c,0xf2,0x16,0x80,0x49,0x43,0x5a,0xbd,0xb5,0xc4,0x78,0x61,0x86,0xff,0xa2,0xef,0xbf,0x37,0x1f,0x6b,0xf3,0xaa,0x74,0x3e,0x77,0x63,0x47,0x86,0xd5,0x73,0x44,0xe6,0xf6,0x9c,0xef,0x69,0x5d,0xb6,0xe4,0x64,0x94,0x9b,0x4e,0xdd,0x0b,0x69,0xe9,0x7a,0xfd,0x8a,0x89,0xff,0x2d,0x0e,0x5b,0xdc,0xcd,0x3c,0xdb +.byte 0xec,0xb8,0x0c,0xe0,0x22,0x09,0x63,0xd7,0x50,0xec,0x42,0xa1,0x2b,0x1c,0xd9,0xa6,0xb5,0xd9,0x16,0x38,0x63,0xa8,0x59,0xda,0xe7,0xbb,0x27,0xca,0xbf,0x39,0x61,0xd9,0xae,0x8f,0xbd,0x27,0xa3,0xfc,0x7c,0x10,0x3b,0x5e,0xbc,0xb0,0xc3,0xf1,0x46,0x8e,0x66,0x7d,0xe0,0x5e,0xad,0x48,0x9f,0xfc,0x5c,0xc0,0x85,0xab,0xd2,0x3a,0x6f,0x60 +.byte 0x0c,0x5c,0x1b,0xd8,0x66,0xf5,0x87,0xda,0x0f,0xdc,0x39,0xee,0xdf,0x85,0xf7,0xb8,0xfa,0xd3,0xe2,0xbe,0x7a,0x06,0xda,0xf4,0x55,0xb9,0x10,0xfd,0xb6,0xe9,0xe8,0x94,0xf0,0x66,0x17,0xf2,0x87,0x55,0x99,0xa8,0x65,0x23,0x0f,0xf0,0x41,0xe1,0x9d,0xf2,0x03,0xf4,0xa9,0xc8,0x31,0xa4,0x88,0xa9,0x32,0xcf,0x02,0xd3,0x8a,0xdb,0x9b,0x12 +.byte 0xa2,0x41,0xea,0x19,0xff,0x2a,0x18,0x53,0xba,0x51,0xb2,0xe3,0x01,0xbf,0xc0,0x45,0xce,0x16,0xb5,0x66,0xd0,0x61,0x4a,0x1d,0xdf,0x8e,0x35,0x9d,0xeb,0x40,0xcc,0xcd,0x0f,0x4f,0x57,0xd3,0xbc,0x44,0x73,0xf9,0x2a,0xf1,0x85,0x1c,0x06,0x5c,0xde,0xa1,0x2d,0xe4,0x68,0xf4,0xc7,0x79,0x5c,0xf4,0xd7,0x33,0x47,0xdf,0xcd,0xa2,0xe8,0x13 +.byte 0x7c,0x0f,0xcb,0x81,0x42,0xa6,0x35,0xf9,0x60,0xcb,0xf3,0x6a,0xf8,0x3c,0x8d,0xff,0xb1,0xdf,0x40,0x22,0x86,0xdb,0xd1,0x59,0x05,0x2a,0xbc,0x04,0x87,0xad,0xe9,0xcd,0x45,0x7e,0xa9,0x5b,0x9a,0xad,0x24,0xf0,0x10,0xac,0xdc,0x16,0xa3,0x4c,0x3a,0x17,0x5d,0x79,0xc6,0xc7,0xcb,0xa0,0x6f,0x34,0xb0,0x9c,0x6a,0xc1,0xd3,0x50,0x0b,0xac +.byte 0x2a,0xb1,0xb8,0x96,0xb6,0x82,0xc8,0x71,0xf7,0x34,0x10,0xa3,0x64,0x6f,0x3e,0x2c,0x5c,0x7a,0xec,0x50,0x6e,0xdc,0x65,0x7d,0xb0,0x7d,0xd5,0x9e,0xd0,0x6e,0x78,0xfd,0x6f,0xb8,0x8f,0x07,0xdb,0xf2,0x40,0x9d,0x90,0x7d,0x67,0xf7,0x89,0xa7,0x2d,0x1f,0xf2,0xa9,0xeb,0x3e,0x3e,0x31,0xd1,0xcf,0xec,0xd9,0x32,0x94,0x0c,0x3b,0x24,0xf7 +.byte 0xff,0xdc,0x3c,0xe8,0x8b,0x06,0xae,0xc4,0x8b,0x96,0x86,0x97,0xef,0x64,0x53,0xc3,0xf3,0xa4,0xf1,0xfe,0x7f,0xf5,0xb7,0xa3,0x76,0x3b,0x6b,0x91,0x8b,0xbe,0xa2,0xb1,0x76,0xe4,0x50,0x86,0x09,0x2d,0x85,0xba,0x69,0x47,0x9e,0x02,0x13,0x07,0x46,0x9e,0xc5,0x98,0xc5,0xb8,0xd0,0x06,0x97,0x17,0x81,0x6c,0xac,0x90,0x75,0x95,0x03,0xb4 +.byte 0x7f,0x76,0x87,0xd7,0x6b,0x76,0xbb,0x93,0xf3,0xe2,0x75,0x8f,0xc3,0x01,0x08,0xbd,0x19,0x1d,0x2f,0x4c,0xee,0x35,0x02,0xd0,0xf1,0x38,0x5e,0xea,0x3d,0x38,0x38,0x9d,0x56,0x38,0xf1,0xcb,0x41,0xc7,0xde,0xbd,0x2f,0xda,0x60,0x58,0x82,0xbf,0xc0,0x46,0xee,0xb2,0xcd,0x6a,0x57,0xf9,0x48,0x9f,0xcc,0xf2,0x15,0x53,0xcb,0xcb,0xad,0xfa +.byte 0xb2,0x65,0x62,0xf1,0x41,0x19,0xac,0xb0,0xc3,0x64,0x4e,0xeb,0x65,0x94,0xae,0x22,0x0e,0x24,0x99,0x9c,0x9c,0xa6,0x45,0xdc,0xa7,0x2e,0xd6,0x1b,0x76,0x37,0x42,0x98,0x59,0xb1,0x16,0x7a,0xd7,0xa5,0xd1,0x53,0x58,0xec,0x6e,0xbe,0x5d,0x98,0x37,0x06,0xda,0x5d,0xf7,0xbe,0xa9,0x78,0xb3,0x5a,0x96,0x44,0xa5,0x3a,0x9f,0x08,0x29,0x3b +.byte 0xff,0xc5,0x74,0xab,0xe7,0x7e,0x87,0x34,0x71,0x3b,0x45,0xa3,0x1a,0xc5,0x34,0xe7,0xe6,0xff,0xb7,0x27,0xe7,0xf9,0x91,0x9a,0x6d,0x0e,0xb5,0xfd,0xba,0x33,0xa9,0xd5,0xd7,0x2a,0xd2,0xb3,0x51,0x43,0x86,0x37,0xeb,0x06,0x23,0x31,0xfa,0x85,0x8b,0x4f,0x68,0x81,0xaf,0xf4,0x9c,0x6f,0x04,0x35,0x19,0x78,0xf0,0xd2,0xdb,0x2f,0xf5,0x35 +.byte 0x62,0xe5,0x31,0xfc,0xfc,0xff,0x0f,0x7b,0x1d,0xde,0xb8,0xb0,0x8c,0x83,0x8a,0xc2,0x9d,0x0e,0x50,0x2a,0x58,0xe8,0xeb,0xbf,0x51,0x50,0xf1,0xec,0xb9,0xad,0x07,0x1b,0x51,0xa3,0xe1,0x68,0x33,0x4d,0xfd,0xaf,0xd5,0x3c,0x25,0xc6,0x95,0x8f,0xf4,0x5f,0xa9,0xde,0x5a,0xa6,0x5a,0x5f,0x3e,0xeb,0x47,0x91,0x1c,0x5d,0x3f,0x8f,0x23,0xeb +.byte 0x30,0x89,0x2b,0x3c,0x48,0x4f,0xa8,0xab,0x09,0x6a,0x8a,0x75,0x3e,0xb0,0x83,0xd9,0x44,0x60,0xb5,0xd4,0x2e,0x21,0x7f,0x24,0xec,0xfc,0xd2,0x6d,0xd6,0x90,0xf4,0x1b,0x52,0x03,0xd9,0x7a,0x48,0x0b,0x32,0x40,0x70,0xc3,0x63,0x8d,0x6d,0xc7,0x23,0xea,0xf9,0x17,0x49,0x1f,0xfe,0xe5,0x50,0xbe,0xab,0x82,0xc9,0x31,0x30,0x28,0xc8,0x40 +.byte 0x37,0xfe,0x9f,0x37,0xdc,0x7c,0x54,0xc7,0x02,0xf1,0xa4,0x1e,0xdd,0x52,0x11,0xa5,0xb9,0x71,0xfd,0xb8,0x41,0xed,0x82,0x1e,0xc7,0x57,0xed,0xf8,0x80,0x5d,0x92,0x49,0xfc,0x0b,0x24,0xdb,0xa7,0x97,0xbb,0xf9,0x4a,0x06,0xd8,0x4d,0x3d,0xbc,0x8d,0xe0,0x42,0x7d,0x5f,0xf9,0xa7,0x46,0xe8,0x10,0xed,0x89,0xe4,0x68,0x8e,0x1a,0xdb,0x29 +.byte 0x9d,0x59,0x22,0x2d,0xe3,0x40,0x8d,0x4b,0x5b,0x6e,0x72,0xde,0xd1,0xd3,0x83,0x02,0x0e,0x7a,0x53,0xe1,0xd2,0x98,0x15,0x6e,0xdd,0x52,0xeb,0x91,0x12,0x0a,0x12,0xb1,0xd0,0xef,0xa1,0x92,0x4d,0x53,0x84,0xfd,0xf8,0x00,0xc6,0xee,0x8e,0xf1,0x07,0x78,0x31,0xdc,0x13,0x3c,0x97,0x63,0xf2,0xfe,0x24,0x3f,0x25,0x3d,0xb0,0xcf,0xa5,0xe8 +.byte 0xf1,0x92,0x93,0x13,0xd7,0x9a,0x9d,0x64,0x62,0xb8,0x7d,0x83,0x6e,0xc6,0x1d,0x72,0x7f,0xd4,0xe9,0x24,0x32,0xe4,0xad,0x0d,0x2d,0x77,0x3d,0x19,0xc6,0x4c,0xb2,0xd8,0xe8,0xd0,0xda,0xef,0x13,0xa7,0x9b,0x1d,0xf5,0xea,0x36,0xdb,0xcd,0xcb,0x5c,0xdb,0xb6,0x77,0x8b,0x3e,0xbc,0x9e,0xf5,0x91,0x18,0x77,0x8c,0x62,0x18,0x43,0xbe,0xee +.byte 0x79,0xff,0x2d,0x4e,0x69,0xe3,0xf2,0x19,0x9b,0x26,0x85,0x1c,0x71,0x50,0x31,0x33,0x15,0x0a,0xa1,0x0e,0xff,0xca,0xe6,0x32,0x7a,0x5b,0x22,0x8e,0x4d,0xf3,0x2a,0xa3,0x2b,0x73,0xda,0xaf,0x60,0x48,0xa0,0x13,0x09,0xb2,0x93,0xbd,0x8f,0x22,0x7c,0xfb,0x67,0xc1,0x37,0x4e,0x41,0xa7,0x08,0x6c,0x61,0xd1,0xab,0x66,0x44,0xcf,0x98,0x37 +.byte 0xe5,0x82,0xdc,0x0d,0x8c,0x77,0xe0,0x69,0x0f,0xa7,0x84,0xcc,0xd1,0xcf,0x08,0xf5,0x14,0xa0,0x87,0x30,0x59,0x37,0xbe,0x53,0xbb,0x1c,0x24,0x8d,0x2d,0xbc,0x9d,0x08,0xc0,0x17,0x61,0xdd,0xe3,0xbe,0xdc,0xfc,0xf7,0x32,0xd9,0x6f,0x48,0xf2,0x37,0x2a,0x68,0x59,0x45,0x1c,0x0c,0xb1,0x78,0x0e,0xf3,0x95,0x49,0x7a,0x2f,0x2c,0xfe,0x80 +.byte 0x32,0x69,0xed,0xa5,0x99,0x70,0x96,0xe0,0xd5,0x94,0xce,0x14,0x91,0x30,0xcb,0xb5,0xdb,0x54,0x3b,0xb5,0x04,0x71,0x97,0x00,0x53,0x62,0x9e,0x68,0x38,0xf6,0x1b,0x01,0xd8,0x45,0x23,0x64,0x24,0xe6,0x3a,0xdc,0x39,0x87,0x31,0xdc,0x97,0x58,0xe5,0x24,0x10,0xa6,0xa6,0x3c,0xd5,0x90,0x6e,0x1e,0x55,0xdd,0x4f,0xe3,0x05,0x58,0x9a,0x88 +.byte 0x1b,0xbb,0x8d,0x21,0xd6,0xb2,0x2c,0x30,0x33,0x0c,0x43,0x98,0x72,0xad,0xc4,0x71,0xf8,0x97,0x61,0x7b,0x9b,0x70,0x1e,0x71,0x55,0xad,0x53,0xf2,0xfe,0x23,0x3c,0xda,0x84,0x37,0x11,0x47,0xa7,0x70,0xb5,0x0b,0x97,0xbe,0xd8,0x9b,0x69,0x71,0x52,0xfc,0x60,0xec,0x94,0x7a,0xc0,0xa7,0xdb,0x31,0x5d,0x19,0xde,0xc0,0xff,0x14,0xb7,0xc7 +.byte 0x74,0x8b,0x65,0x33,0x31,0x4c,0x63,0xf5,0x96,0x08,0xc2,0xf5,0x56,0x3b,0x15,0xbf,0x39,0x1b,0x6b,0x59,0xe5,0x39,0x56,0xb6,0x57,0x7a,0x2b,0xcd,0x46,0x9c,0xd1,0x0e,0x49,0xe1,0x9f,0x07,0x0f,0xea,0xd5,0xb9,0x27,0x76,0x04,0x09,0x92,0x6d,0x37,0x78,0x36,0xd7,0xf8,0xa0,0x96,0x88,0x8c,0x3f,0xff,0x88,0x95,0x85,0x14,0x24,0x82,0x85 +.byte 0x47,0x68,0x58,0x11,0xd0,0x21,0x5e,0x1a,0x61,0xe3,0x0f,0x3f,0xd3,0xea,0x14,0xb9,0xd6,0x98,0x10,0x7f,0x38,0x00,0xf5,0xd1,0x73,0xc0,0x71,0x7e,0x75,0xbb,0x5c,0xcc,0xf0,0x83,0x48,0x89,0x16,0xbf,0xd1,0x82,0x36,0x13,0x5d,0x05,0x43,0x18,0xb9,0xf1,0xd4,0xa3,0xcf,0xb3,0x24,0xe8,0x74,0x91,0xee,0x27,0x7c,0xe0,0x20,0xa8,0xde,0x4e +.byte 0x7d,0x26,0xef,0x61,0xae,0xe3,0xa9,0xd3,0xde,0xfb,0x37,0xc2,0x06,0xbc,0x1e,0x4d,0xbf,0x3b,0x56,0xca,0x03,0x9f,0x82,0x44,0xfa,0x7c,0x1d,0xa6,0xbd,0xd8,0xcf,0x2f,0x08,0xc9,0x73,0xf3,0x0b,0xf3,0xd8,0xb7,0x93,0xd3,0xd4,0x8b,0xc1,0xce,0x4e,0x88,0xb6,0xd0,0x7e,0xbe,0x7f,0x9f,0x8e,0x98,0xa0,0xf4,0xc1,0x9a,0x65,0xe9,0xe5,0xf2 +.byte 0xb5,0xbc,0x64,0xa8,0xdc,0xf0,0x00,0x59,0xc9,0x83,0xbf,0x33,0x54,0x6b,0x12,0xfc,0x61,0xc3,0x2d,0x53,0xfa,0x24,0x39,0x83,0x3a,0x8f,0xaa,0xf8,0xbd,0xff,0x74,0x15,0x10,0x3a,0x3b,0xc7,0x72,0x20,0xed,0x1a,0x79,0x0c,0x12,0xaf,0xb6,0x00,0x54,0x05,0xd7,0xde,0xe2,0x00,0x4f,0x96,0x9c,0xab,0x77,0x71,0x65,0xe1,0x2d,0xee,0x2f,0xbd +.byte 0x4e,0x9a,0x0f,0xe9,0xca,0x4f,0x4c,0xdd,0xb8,0x22,0xdb,0x1c,0x5f,0x49,0x8e,0x69,0x3c,0x70,0x79,0xc1,0x20,0xd8,0xda,0x61,0x55,0x0a,0x0e,0xd0,0xb5,0xfb,0x1c,0x56,0xd2,0x85,0x82,0x7b,0xb0,0x58,0xdc,0xf0,0x8b,0x0c,0xfa,0x0c,0xce,0xe3,0x15,0x8b,0x68,0x49,0x09,0x0c,0x9b,0x80,0x17,0x92,0x19,0x08,0xe2,0x7b,0x3e,0x60,0x96,0xc3 +.byte 0x81,0x5b,0x4d,0x63,0x04,0x47,0x0e,0xff,0x43,0xb1,0x71,0xb0,0x6c,0x02,0x85,0x2f,0x5b,0xdf,0xba,0xb7,0xe5,0x34,0xb6,0x7e,0xa3,0x74,0xec,0x44,0xe8,0x35,0xc7,0x10,0xa6,0xe6,0x31,0x50,0x29,0x69,0x11,0x91,0x3c,0x31,0x3b,0xb2,0x17,0x21,0xdd,0x92,0x2c,0x71,0x0a,0x45,0xe7,0x7d,0xf0,0x38,0x41,0xa6,0x09,0x72,0xcf,0xbc,0x56,0xff +.byte 0x81,0x79,0xaf,0x68,0x80,0xc5,0xa6,0xb1,0xb7,0x3d,0x0d,0xc5,0x9c,0xb2,0x32,0x7f,0xcc,0x66,0x8d,0x86,0x84,0x38,0xa5,0x66,0x7c,0x4d,0x4c,0xdf,0xa7,0x1a,0x7e,0x66,0x95,0xf7,0x5e,0xe9,0x4c,0x61,0x7a,0x05,0x66,0x78,0xae,0x2b,0xef,0x6b,0x6a,0xc5,0x6d,0xbb,0x35,0xef,0x9f,0x0c,0x1c,0x00,0x45,0x2a,0xad,0x79,0x84,0x8b,0x28,0x81 +.byte 0x0d,0xe8,0xef,0x49,0xaf,0x59,0xb0,0x9f,0xec,0x58,0x32,0xc9,0x49,0xb2,0xf8,0xc5,0xae,0x92,0xb8,0xde,0xec,0xc2,0xc4,0xf9,0xc8,0x28,0x99,0x07,0x39,0x71,0xed,0x06,0xcc,0x46,0x14,0xd1,0xf4,0xad,0x8d,0x72,0xa4,0x3f,0xea,0x35,0x6f,0x84,0xa8,0xc7,0xcd,0xfd,0x16,0xf8,0x66,0x16,0xb9,0xd2,0x31,0x57,0x1b,0x5c,0x50,0xec,0x8f,0x15 +.byte 0xf8,0x4f,0x65,0xd0,0xdb,0x0f,0x29,0x3d,0x03,0xba,0x7b,0x56,0x95,0xfe,0x97,0x95,0xff,0x8f,0x87,0x3c,0xc5,0x70,0xbb,0x96,0x37,0x69,0xd4,0xe6,0xbd,0xd1,0x93,0x95,0x7e,0x1a,0x80,0xde,0x9f,0x2a,0x00,0x18,0x5d,0xcf,0x8d,0xcc,0x31,0x3b,0xe3,0xc9,0x07,0x20,0xf3,0x87,0xc4,0x62,0x6a,0xc2,0xbe,0x09,0xb0,0x57,0xf7,0x8d,0x56,0x4c +.byte 0x6b,0xb1,0xa8,0x65,0x3c,0xff,0xfa,0x95,0x20,0xed,0xca,0x36,0x3f,0xba,0x5f,0xe1,0x03,0x6e,0xe1,0xbd,0xce,0xa0,0x68,0xaf,0x51,0x65,0x65,0x10,0xfe,0xdd,0xb4,0x33,0x49,0x57,0x69,0x60,0xad,0x8f,0x84,0x88,0xeb,0x0d,0x46,0xf2,0x2b,0x5d,0x79,0x1e,0x42,0xc5,0x9d,0x3e,0xef,0xb9,0x60,0xa9,0xc6,0x34,0x81,0xb5,0x09,0x42,0xf3,0xa8 +.byte 0xf0,0x8f,0xc7,0xbc,0x05,0xc8,0xe9,0xa7,0x47,0x15,0xf7,0x41,0xe2,0xe8,0x0a,0x01,0x67,0x18,0xfb,0x63,0x5a,0x37,0xf4,0x45,0xc2,0x2d,0xcf,0xd0,0x28,0xd3,0xc1,0x2b,0x1c,0x8a,0x40,0x64,0xee,0xf6,0x2c,0x2a,0x37,0x26,0xe2,0x3d,0x76,0x27,0xa2,0x92,0x29,0xd3,0x17,0x4c,0x67,0x1b,0x1d,0xe9,0x38,0x1c,0x38,0x36,0xd5,0xa0,0x91,0xc5 +.byte 0xae,0x67,0x0c,0xa3,0x1d,0x34,0x11,0xda,0xe7,0x93,0xe0,0xaa,0xa8,0xa1,0x00,0x5d,0x21,0x34,0x90,0x7d,0xff,0x25,0x46,0x64,0x55,0x56,0x1d,0x58,0xf2,0x49,0xa4,0x19,0x1a,0xe7,0x63,0x75,0xac,0x37,0xb3,0xf1,0x3c,0x14,0x46,0xd6,0x33,0x11,0xfb,0x35,0x84,0x34,0xf7,0x0d,0x99,0x49,0x21,0x8c,0x20,0xf0,0x7b,0x0d,0x4e,0x9a,0xc5,0xc3 +.byte 0x16,0x1e,0x73,0x06,0xd8,0x1b,0xe0,0x08,0x5d,0x5a,0x78,0x6f,0x5b,0x18,0x85,0x76,0x41,0xdf,0xa1,0x70,0xea,0xab,0xb5,0xa0,0x4d,0x07,0x66,0x0b,0xb8,0x19,0xf1,0xe7,0x3a,0x68,0xac,0xb9,0x06,0x9e,0x74,0x6a,0x20,0xa6,0x47,0x72,0xd9,0x2d,0x80,0x15,0x0c,0xfb,0x58,0x00,0x3d,0x41,0x48,0x3e,0x72,0xf6,0x08,0xdf,0x14,0x72,0x60,0xf5 +.byte 0xd4,0x34,0x7d,0x61,0x42,0xa6,0x40,0xdf,0x54,0xc8,0x37,0xa4,0x39,0x4f,0x1e,0x4c,0x1d,0xae,0x0a,0xb3,0xc8,0x8f,0xed,0x42,0xfc,0xce,0x1d,0x4b,0x31,0x49,0x48,0xe6,0xa0,0x2e,0xd5,0x50,0x13,0xdd,0xc8,0x11,0x4d,0x53,0xce,0x5a,0x41,0x30,0xa7,0xfd,0x09,0xd4,0x1e,0xb3,0xd8,0xd4,0x52,0xc1,0xc5,0x65,0x64,0x96,0xf8,0x02,0xdb,0xcb +.byte 0x0e,0xf5,0x28,0xde,0x01,0x34,0x7f,0xe0,0x12,0xdd,0xfa,0x1d,0xda,0xfd,0xdc,0xd3,0xd4,0x87,0x27,0x0f,0x9a,0xb5,0x59,0xe0,0x3f,0xc2,0x38,0xdf,0x13,0xfb,0xdc,0x37,0x54,0xf4,0xf0,0xc8,0xcf,0xd2,0xd1,0xf2,0xf1,0x45,0xf8,0x50,0xb8,0xa6,0xae,0xa0,0x4f,0xaa,0x20,0xc2,0x81,0x2f,0x4e,0xdc,0xc4,0xf3,0x54,0x33,0xf0,0x9f,0x0a,0x75 +.byte 0x2d,0xd4,0x43,0x0c,0x1b,0x9f,0xf1,0x82,0x75,0x2b,0x9a,0x6c,0xfd,0xf9,0xa7,0xda,0xa4,0xdc,0xe1,0xd3,0x93,0x14,0x26,0x7c,0x5f,0x20,0x83,0x85,0x38,0xfc,0x87,0xf0,0xbd,0xbd,0xd8,0x80,0xd0,0x10,0x6b,0x23,0xfd,0x52,0x25,0x4d,0xfc,0xfb,0x13,0xb7,0xf7,0xb2,0xed,0xe2,0xd7,0xf9,0x87,0x7b,0x85,0x0c,0xe4,0x6a,0xbd,0xc7,0x59,0xff +.byte 0x7a,0xb5,0xfe,0x8c,0x80,0x16,0x2e,0x43,0xb4,0x90,0xff,0xa9,0x71,0x3c,0xee,0xb6,0xa5,0xaa,0x2e,0xa8,0x97,0x9f,0x0c,0xcc,0x31,0xe8,0x2a,0xd9,0xab,0x60,0x88,0xc2,0x29,0xc3,0x4d,0xc5,0x2d,0xf4,0x40,0xc8,0xfd,0x3c,0xe4,0xf7,0x67,0x35,0xf0,0xb6,0xa8,0x4c,0xec,0x30,0xfd,0x54,0xd8,0x25,0x50,0x8e,0x24,0x61,0x7e,0x54,0x0c,0x5b +.byte 0x88,0xb9,0x70,0xef,0xc6,0xa7,0x23,0xd7,0xb2,0xec,0x3f,0x51,0xce,0x29,0x74,0x35,0xc2,0x32,0xda,0x1e,0x13,0xc2,0x20,0x3a,0x35,0xee,0x40,0xf4,0x00,0x3a,0xf1,0xa4,0xf3,0xd1,0x58,0x57,0xa6,0x83,0xb1,0x01,0x2d,0x15,0x1e,0x08,0xf8,0x9b,0xb5,0x35,0xee,0x33,0xba,0x5b,0x8d,0x26,0x00,0xee,0x95,0xaf,0xca,0x7e,0x98,0xd5,0x58,0x40 +.byte 0xb5,0xa2,0x7d,0x8e,0x0e,0x1b,0x72,0x88,0x1c,0x4b,0x52,0x65,0x6e,0x60,0x62,0x46,0x1c,0x41,0x81,0xd2,0x83,0xc0,0x2d,0xbc,0x5d,0x58,0xc7,0xf8,0x43,0xd9,0x11,0x05,0x50,0x6d,0xc2,0x81,0x29,0xac,0xe8,0x44,0xfb,0x2d,0xf3,0xf4,0x17,0x9b,0x01,0xae,0xb1,0x8a,0x61,0xbf,0x20,0x75,0x12,0x3b,0xb4,0xf5,0xc5,0xff,0x5b,0xf5,0xa8,0x6f +.byte 0xec,0x7d,0x04,0x9f,0x63,0xbc,0xb7,0xcc,0xce,0x96,0x7b,0x31,0x09,0x06,0x25,0x90,0x4e,0xd2,0xf5,0x60,0xa3,0x61,0x61,0x8d,0x3e,0x97,0x54,0x24,0x1c,0x25,0x3a,0x2e,0x6c,0xa9,0x97,0xa4,0x69,0xe5,0xdd,0xc1,0xdb,0xb2,0xf5,0xc4,0x8b,0x23,0x20,0xe5,0x68,0x85,0x78,0x08,0x2c,0x95,0x85,0xc5,0x4b,0xf1,0xfa,0xb1,0xf2,0x32,0x28,0x4e +.byte 0x1c,0x7b,0x3d,0xfc,0x59,0x52,0x15,0xd5,0x74,0x86,0xea,0xde,0xd5,0x1c,0x5d,0xcb,0x22,0x4a,0x2e,0xbd,0xb4,0x5f,0x59,0xd6,0xaf,0x49,0x7b,0x0c,0xce,0x78,0x4b,0xc9,0xd2,0x2e,0x22,0x7d,0xe2,0x7b,0x05,0x0d,0xa1,0xca,0x24,0x91,0x11,0xa0,0xf2,0xbd,0x77,0x60,0xe9,0xfe,0x5d,0x5c,0xea,0x88,0xf9,0xbf,0xe1,0x26,0xd3,0x65,0x4a,0xa1 +.byte 0xb0,0xbe,0x72,0x49,0xfc,0x96,0xd1,0x4b,0xc9,0xb3,0xe0,0x74,0x0e,0xff,0xb6,0x3f,0xed,0xe1,0xdc,0x92,0xe3,0x65,0xaa,0x14,0x2a,0xb9,0x2f,0xc5,0x7c,0x4b,0x30,0x1a,0xc5,0x85,0xc7,0xa4,0x8c,0xba,0xff,0xf3,0xdc,0xf8,0x75,0x4b,0x35,0x36,0x6c,0x91,0x04,0x28,0x3c,0x94,0xc3,0x23,0xd5,0x89,0xbf,0x88,0x3c,0xc8,0xf2,0xec,0x14,0x3f +.byte 0x5f,0xf3,0x0c,0x6c,0x89,0x10,0xe1,0x6f,0xef,0xcc,0xd1,0x20,0x32,0xe7,0x59,0xd1,0xab,0xe8,0xe2,0x5f,0xa4,0xc3,0xe6,0x85,0x44,0x31,0xed,0x34,0xa7,0xef,0xff,0xb4,0x28,0x07,0x2f,0xc2,0x75,0x7d,0x72,0x80,0xa9,0x56,0xc1,0x6d,0x7e,0x5c,0xb7,0xdb,0x14,0x1d,0x27,0x0b,0xc7,0x5c,0xd4,0x97,0x35,0x29,0x58,0xb3,0xf0,0xd5,0x4a,0xc8 +.byte 0x73,0x01,0xbc,0x86,0xb1,0xff,0xc0,0x5c,0x9d,0xc1,0x19,0xbf,0xeb,0x6d,0x60,0x0b,0x8f,0x2c,0xf4,0x90,0x10,0x43,0xe7,0x2d,0x46,0x95,0x1a,0xf8,0x09,0xc8,0x30,0xff,0x98,0xf2,0xd8,0xee,0x42,0xfb,0x44,0x1b,0xd8,0xa7,0x04,0x87,0x83,0xe2,0x5b,0x5b,0x75,0xf3,0xec,0xa0,0x92,0x64,0x48,0x2d,0x53,0xa5,0x3e,0xeb,0x3b,0x1c,0xc7,0xe8 +.byte 0x09,0x66,0xae,0xaf,0x94,0x2b,0xf6,0x16,0x9f,0x07,0x01,0x46,0xcf,0xd2,0x0c,0x7e,0x7f,0x0d,0x02,0xac,0x03,0xd0,0xb8,0xa0,0xe8,0xbf,0x5f,0x57,0x07,0x09,0x38,0xde,0xab,0xac,0xe3,0xae,0x59,0x70,0x5d,0xa5,0x32,0x31,0x80,0xb9,0xbb,0x5f,0x8b,0xcc,0xe2,0x2c,0x2e,0x1a,0x78,0xa6,0xf9,0x1b,0x2d,0x7f,0xd4,0xa1,0xf4,0xd8,0x1f,0x35 +.byte 0x5b,0x05,0xc9,0x41,0x8e,0x44,0x32,0x00,0xef,0x01,0x42,0x8f,0x16,0xf8,0xc0,0x8c,0x53,0xba,0x95,0xab,0x85,0xa7,0xe0,0x5b,0x28,0x2d,0xee,0xae,0xac,0x68,0xb6,0x2e,0x51,0x60,0x31,0xb3,0x2b,0xec,0x2f,0xe3,0x9b,0x20,0xb7,0x2d,0x21,0x40,0xab,0x64,0xe4,0x0f,0x2e,0x52,0xb3,0x7b,0x0a,0x3a,0x82,0x50,0xa6,0x53,0x37,0x5f,0x4c,0xca +.byte 0x1f,0x68,0x26,0x51,0x2c,0x35,0x4e,0xc9,0x32,0x83,0x7d,0x6c,0xdd,0xd4,0x75,0x58,0xd9,0x6e,0x2a,0x54,0x98,0x94,0xe8,0x5a,0xff,0xcc,0xa5,0x01,0xce,0xc9,0x7c,0xc6,0xd2,0x84,0x74,0x87,0xa9,0x3e,0xb3,0xfb,0x8f,0x7a,0xc3,0x9b,0x48,0xd9,0x91,0x18,0xae,0xa4,0xbe,0xef,0x5c,0xce,0x84,0x14,0xa0,0x8e,0x97,0xd4,0xd8,0xe1,0x3f,0xe0 +.byte 0x06,0x3d,0x2d,0x7f,0x76,0x58,0xb0,0x18,0xbd,0x25,0x8c,0x75,0x66,0x9e,0x50,0x3a,0x1a,0x94,0xf8,0x9a,0x9d,0xa1,0x19,0x0b,0x95,0xe0,0xdd,0xbf,0x37,0xa8,0x93,0xf6,0xd0,0x63,0xee,0xc5,0x66,0xec,0xe2,0x2d,0xd4,0x82,0x62,0x22,0xd2,0x05,0x28,0xff,0x62,0x4a,0x93,0x24,0x54,0xa3,0xf9,0xba,0xe2,0x5e,0xad,0x0a,0x54,0x82,0x20,0x95 +.byte 0xc6,0xa1,0xd9,0xff,0xaf,0x83,0x14,0x4a,0x00,0xb6,0x05,0x1f,0xca,0x4e,0xb9,0x76,0x87,0x19,0xef,0x7b,0x8f,0x09,0xac,0x28,0x64,0x6e,0xd6,0xa0,0xf3,0xa0,0x58,0xc2,0x51,0xf1,0x9c,0x82,0xb7,0x36,0xfc,0xfb,0x77,0x77,0xad,0x9e,0x9f,0xdf,0xf0,0x12,0xfe,0xa2,0xd6,0x92,0xae,0xbe,0xe6,0xcd,0xc8,0xe7,0x6e,0x14,0xa3,0xcf,0xb3,0x02 +.byte 0xaa,0xe2,0x39,0x0e,0x34,0xb7,0x62,0xd5,0x6a,0xcf,0xcb,0x7b,0x2b,0x9e,0xce,0x53,0x86,0xfc,0xe4,0xb6,0xa2,0xd6,0x20,0xe4,0x49,0xa5,0xa5,0x56,0x56,0xff,0x3c,0xc2,0x7c,0xb9,0xee,0x7f,0x92,0x45,0xcd,0x77,0xf0,0xd1,0x8f,0x73,0x2f,0x5d,0x14,0x5e,0x89,0xef,0xae,0xaa,0x7c,0xae,0x1e,0x9a,0xa6,0xea,0x18,0x85,0xcf,0x3a,0x98,0x0f +.byte 0xca,0x59,0xa5,0x35,0x99,0x23,0x2c,0x92,0x4f,0xea,0xf8,0x6e,0xa9,0x1e,0xea,0x12,0x81,0xcb,0x30,0xff,0xfb,0x26,0xfe,0x09,0x11,0x5c,0x3f,0xef,0x7e,0x3c,0x5a,0xf6,0x08,0x49,0xcf,0x4e,0xdb,0xb6,0xf2,0x8f,0xcf,0x10,0x6d,0x84,0x55,0xb3,0xba,0x48,0x7e,0x73,0x2c,0x33,0x4f,0xc5,0xd4,0xe8,0xd8,0x57,0xb3,0x94,0x71,0x30,0x24,0x1c +.byte 0x41,0xda,0xef,0x66,0x0e,0x54,0xec,0xa3,0x4a,0xf4,0x97,0x86,0x7b,0xc8,0x9b,0x75,0x5a,0x47,0x65,0xe7,0x15,0x59,0x3d,0xa1,0xb9,0xe9,0xea,0x76,0x24,0x23,0x8c,0x05,0xc0,0x06,0x6f,0x0b,0xc5,0x6b,0x25,0x24,0x40,0xee,0xa1,0xe1,0x92,0xbe,0x17,0x2c,0x5f,0x68,0xec,0xc1,0xf6,0x4c,0x76,0x7c,0x4a,0xb3,0x7c,0x5b,0xad,0x72,0x66,0x1d +.byte 0x16,0x98,0x92,0x20,0x12,0xa2,0xaa,0xea,0x77,0x78,0xb9,0x3b,0xbe,0x39,0xec,0x61,0x0d,0x8a,0x01,0x98,0x91,0xdc,0xd8,0x4e,0x61,0x73,0x0b,0xe9,0x6a,0x24,0x35,0x11,0x32,0xa1,0x27,0x3f,0x96,0x63,0x2e,0xde,0xab,0x03,0xac,0x1c,0x4b,0xd8,0xe6,0xb4,0x4b,0x3b,0x47,0x32,0x8b,0xf4,0x40,0x92,0x89,0x4e,0xe1,0x63,0x86,0xa6,0x3b,0xb8 +.byte 0x94,0x47,0x3c,0x34,0xc0,0x18,0x9a,0x53,0xaa,0x3a,0x64,0x96,0x1f,0x98,0x93,0x13,0x1e,0x44,0x9e,0xcb,0x92,0xc3,0x25,0x17,0xb7,0xe1,0x3e,0x91,0xbd,0x14,0x42,0x33,0xb0,0xf2,0x2f,0xcc,0x40,0x7d,0xac,0x45,0x3d,0xe1,0xe1,0xfa,0x03,0x05,0x0b,0xe7,0x9a,0x26,0x4f,0xab,0xb4,0xe8,0x42,0x9f,0x38,0x81,0xef,0x59,0xfa,0xd1,0x3b,0x27 +.byte 0x87,0x23,0x17,0xd0,0xcd,0x25,0xda,0xc9,0x5e,0x21,0x26,0x2f,0x0c,0x33,0x46,0xd1,0xb2,0xf1,0x89,0xad,0xbe,0xe8,0x71,0x37,0xc7,0x27,0x5c,0xaa,0xdd,0x1f,0xd7,0x34,0x31,0x46,0x00,0xd7,0xb5,0x29,0xc2,0x35,0x58,0x07,0x74,0xb0,0x44,0xde,0x08,0x8e,0x51,0x52,0x97,0x8d,0x01,0xe7,0x13,0x18,0x6a,0xd3,0x82,0x2a,0x76,0x67,0x70,0x14 +.byte 0x5d,0x1d,0x6b,0xd5,0x8b,0x3a,0x28,0xbd,0x3b,0x13,0xb0,0x43,0xde,0xf3,0x3c,0xc6,0x0f,0x32,0x77,0x7e,0xab,0x28,0xdd,0x8b,0x57,0xab,0xb7,0x65,0x56,0x5c,0x2e,0x05,0x8a,0x3f,0x4b,0xdb,0x22,0xcd,0xfb,0x99,0x06,0x38,0x6e,0x4f,0x7e,0x23,0x54,0xca,0x47,0x2f,0x33,0x18,0x79,0xdf,0x69,0xe9,0x63,0xfb,0x6e,0x9f,0x1a,0xa0,0xc2,0x15 +.byte 0xc3,0x5f,0xe8,0xc1,0x35,0x5a,0x60,0xb7,0xd4,0xd4,0x5c,0xc0,0x4f,0x28,0x6d,0xea,0xe9,0xe0,0xa7,0x4a,0xfb,0x66,0x75,0x04,0xae,0xd7,0x30,0x42,0x9b,0x9b,0x0e,0xe8,0x67,0x40,0x8f,0x8e,0x0c,0x39,0xd6,0xa1,0x13,0x69,0x58,0xf3,0x09,0xdf,0x43,0x6a,0x41,0x6c,0x03,0x0d,0xc2,0x38,0x55,0x87,0x7f,0x88,0xed,0x01,0xa6,0x5f,0x1a,0x20 +.byte 0xa7,0x7b,0x3a,0x59,0x1f,0x26,0xcc,0x62,0x42,0x48,0xa3,0x60,0x49,0xb0,0x62,0x8f,0xe0,0x66,0x2a,0xa1,0x21,0x6e,0x6b,0x93,0xdd,0x7b,0x89,0x65,0xf0,0xc4,0xf6,0xba,0xf5,0x8d,0x3b,0xd9,0x09,0xc0,0xe0,0xf6,0xf3,0x58,0x9d,0x47,0x0a,0x69,0x09,0x61,0x02,0x8d,0xda,0xf2,0x63,0x82,0x5b,0x50,0x36,0x6e,0x29,0xc2,0x8d,0x5d,0x7a,0x4f +.byte 0xd3,0x8d,0xd3,0xfc,0x30,0x94,0xe1,0x7b,0xf7,0x0a,0xe5,0x7b,0x89,0x69,0x17,0x6b,0x07,0x90,0x28,0xa1,0xb1,0x01,0xbc,0xf9,0x3f,0x50,0xf5,0x4c,0xa2,0x9a,0x46,0x0c,0x7c,0xf0,0x68,0xdc,0x75,0x13,0x4c,0x22,0x02,0xe8,0x6f,0xcc,0x0a,0xcf,0x66,0xb7,0x86,0xb8,0x5b,0xe2,0x11,0x26,0x26,0x7b,0x07,0xc0,0xa2,0xf8,0xc6,0x5f,0x10,0x82 +.byte 0xe6,0x6c,0x2a,0xb5,0x3f,0xf8,0x1e,0xe0,0x26,0x7f,0x88,0x5d,0x75,0xc1,0x0f,0x4c,0x8f,0x9d,0x87,0xab,0xe6,0x2b,0x07,0xc7,0xa2,0x28,0xef,0x05,0x02,0x55,0xee,0x79,0x7b,0x37,0x29,0x3f,0x90,0xb8,0x09,0x7c,0x62,0xae,0xad,0x0b,0xe1,0xd6,0x5c,0x6a,0x28,0xa9,0x2c,0x78,0x4b,0x37,0x6c,0xfe,0x4f,0x2a,0x59,0xdf,0xd5,0x91,0x37,0x99 +.byte 0x0e,0x20,0xf2,0x74,0xe6,0xd6,0x17,0xd9,0x21,0x8f,0xdb,0xd6,0xff,0x5d,0x6b,0x2b,0xa1,0x21,0xd2,0xc9,0xb2,0x37,0x1c,0x69,0xbb,0x9e,0x4f,0x28,0xae,0x4a,0x41,0x7d,0x87,0xcb,0x6a,0xfa,0xbf,0x9f,0x23,0xd2,0x68,0x8f,0xb2,0xa4,0x15,0x60,0xf9,0x6e,0x20,0xb6,0xd7,0x5e,0xa1,0x21,0x05,0x81,0x4c,0x34,0x58,0x7b,0x55,0xae,0x85,0x7f +.byte 0xe5,0x3a,0xe3,0xe0,0xf8,0x43,0x73,0xdd,0x85,0xdb,0x2e,0x2f,0x20,0x65,0xea,0x76,0xa1,0x6a,0xde,0xcf,0x76,0x22,0x8d,0x1c,0x22,0x7b,0x93,0x42,0xf3,0x2b,0x93,0x85,0x20,0xc7,0x20,0x53,0xd4,0xd9,0x51,0xba,0x2e,0xc7,0x84,0x09,0x65,0xa0,0x1c,0x58,0xf0,0xa8,0x46,0xef,0xf3,0x4b,0xc7,0x27,0xcb,0x93,0x4e,0x74,0xdc,0x0c,0xb5,0x06 +.byte 0xba,0x25,0xf0,0x15,0x47,0x3d,0xf5,0x86,0x9b,0xec,0xc7,0x44,0xec,0x0f,0x7b,0x3c,0xfc,0xec,0x3c,0x71,0x00,0x75,0x42,0xae,0x25,0x5b,0x1c,0xfe,0x1c,0xdf,0x74,0x95,0xb6,0xc0,0xfc,0xd7,0x67,0xa5,0xf5,0x71,0x62,0xcc,0x04,0xab,0x46,0x39,0xfe,0x03,0x72,0x7c,0x01,0x85,0x8b,0x9d,0x9d,0xda,0xd5,0xa4,0xaf,0xbc,0x54,0x96,0x57,0x02 +.byte 0x56,0xc2,0x9f,0xe2,0x9d,0x30,0x51,0xc0,0xa5,0x4b,0x86,0xb5,0xb6,0xe9,0xed,0x81,0xa7,0xb2,0x3f,0x2e,0x33,0x0a,0xa0,0x78,0x93,0x94,0x49,0x5e,0x2f,0x54,0x06,0x2c,0x98,0x0e,0xf4,0xcc,0xc2,0xbd,0x5f,0xd6,0x7c,0x81,0xb8,0xb1,0x85,0x93,0xf2,0xb4,0xb3,0x0d,0xa7,0xb8,0x9b,0xb7,0x04,0x2d,0x76,0x35,0xeb,0x4f,0x15,0x68,0xc8,0x43 +.byte 0x03,0x4c,0xa7,0x67,0x0a,0xc6,0xc2,0x5b,0xdf,0xc0,0x86,0xde,0xe5,0x72,0x37,0x0e,0xbb,0xe8,0xd0,0x52,0xe1,0xb6,0x87,0xb1,0x1b,0x63,0x94,0x03,0x8a,0x3e,0x40,0x3d,0x39,0x1a,0x41,0xc6,0xb7,0x05,0x81,0x24,0x43,0x4e,0x67,0x1f,0x19,0x00,0x7b,0xd7,0x26,0x55,0x27,0xf4,0x89,0x2b,0x91,0xf4,0x0e,0x5c,0x65,0xcb,0xca,0x96,0x6b,0x92 +.byte 0x58,0xba,0xa5,0xf6,0x99,0x99,0x1a,0xf2,0x66,0x6d,0xf1,0xa3,0xbe,0x1d,0x27,0x9c,0x80,0xb8,0x8f,0x01,0xfb,0x67,0x97,0x9a,0xf2,0x55,0xe2,0x04,0xac,0x1a,0x45,0xa0,0xae,0x43,0x7a,0x87,0xaa,0x6e,0xa1,0x36,0xa0,0x27,0xad,0xc8,0x86,0xa2,0xa5,0x39,0xac,0x44,0xae,0xd0,0xe0,0x15,0x04,0x5c,0xb7,0x84,0xe3,0xb3,0x1d,0x7f,0xd8,0xb6 +.byte 0x65,0x45,0x1e,0xe9,0x9e,0x77,0xfe,0x6f,0x07,0x80,0x0b,0xe7,0x1a,0xc1,0xd6,0x3f,0x2b,0x32,0xda,0x75,0x50,0xd6,0xbc,0x98,0x42,0xa5,0x2f,0x83,0xb5,0xbe,0x10,0x25,0x01,0xfc,0x0d,0xbb,0x42,0xe1,0x37,0xcc,0x0d,0x53,0x83,0x0c,0x0a,0x7d,0xbf,0x0b,0x1e,0xb9,0x16,0x8e,0x36,0x7e,0x85,0x37,0x3f,0x4a,0x38,0x5b,0x44,0xb5,0x58,0x28 +.byte 0x2e,0x46,0xe4,0x12,0x68,0x81,0x52,0x0f,0x4a,0x35,0x4c,0xeb,0x8a,0x7e,0xe7,0x7e,0xfd,0xb6,0x0e,0x8e,0x18,0xa0,0xc6,0x5a,0x53,0x19,0xb8,0xb1,0x39,0x44,0x3f,0xe7,0x03,0xb8,0x20,0x60,0xde,0xc7,0x80,0x01,0xb1,0x86,0x88,0x76,0x3d,0xd1,0x25,0xd1,0x98,0xd1,0xb5,0x96,0x92,0x41,0xe0,0x17,0x94,0xcd,0xf3,0xce,0x8b,0x34,0x92,0x68 +.byte 0x04,0x79,0xe8,0xf7,0x07,0xcf,0x53,0x9f,0x05,0x20,0x5d,0xdd,0xbf,0xb0,0xf0,0xa6,0x00,0x1d,0xe2,0x92,0x28,0x07,0xb4,0xbf,0x34,0x7c,0x0b,0xa4,0x13,0xc4,0x57,0xc8,0xd5,0x94,0xc2,0x46,0x2c,0x8e,0x73,0xab,0x05,0xa3,0x48,0xb4,0xcb,0x66,0x52,0x97,0xd0,0x14,0x5d,0xe3,0xfd,0xea,0xe8,0xdb,0x9f,0x02,0x16,0xb3,0x59,0x41,0xb4,0x20 +.byte 0xfd,0x08,0x10,0xe6,0x3a,0x96,0xf4,0x77,0x45,0xf5,0x3e,0xa2,0x6c,0xb1,0x6d,0xb9,0xb5,0x78,0x31,0x83,0x15,0xe2,0x9d,0x6b,0xa3,0x27,0xbb,0xc7,0x0d,0x91,0x04,0xed,0x96,0x2f,0xcc,0x4f,0x93,0x96,0x9c,0x8e,0xc8,0x84,0xdb,0xe3,0x26,0x23,0xfa,0x0d,0xc8,0x09,0x21,0x0f,0x0a,0x2d,0x0a,0x04,0x8b,0xcd,0xae,0xdd,0x9c,0xac,0xd1,0x57 +.byte 0x22,0x9e,0x0c,0x00,0xd4,0x56,0x97,0xee,0xfd,0x87,0xd5,0x69,0xdb,0x1e,0x22,0xf4,0x67,0x2f,0x7d,0x4f,0x00,0x4e,0x6b,0x1d,0x4a,0x98,0x62,0xde,0xff,0x18,0xc3,0xf5,0xb3,0x14,0x8a,0xb6,0xd6,0x4b,0x11,0xc2,0x7b,0x5b,0x3d,0xbf,0x48,0x39,0x98,0xeb,0xeb,0x17,0xf9,0x57,0xda,0xcf,0xe2,0x59,0x8b,0xbb,0x67,0x73,0x27,0xda,0xcc,0x23 +.byte 0x33,0x38,0x0d,0x02,0x43,0x9e,0xa9,0x5e,0x6b,0x85,0x82,0xff,0xe1,0xab,0x5b,0xe1,0xcd,0xa1,0xb0,0x2e,0x89,0x34,0xeb,0x4f,0x6d,0xfc,0xaf,0x39,0x9d,0xa4,0x54,0xd8,0x0f,0x32,0x33,0xe6,0xb0,0x10,0xef,0x69,0x6a,0x83,0x9c,0x73,0x7d,0x69,0x7d,0x5f,0x85,0xc4,0x0e,0x14,0xc6,0xe7,0xba,0x0a,0xb6,0xf1,0xad,0x91,0x3b,0x8e,0xda,0x11 +.byte 0x64,0x58,0xdd,0x86,0x4f,0x61,0x3f,0x65,0x12,0x5d,0xa6,0x7d,0x87,0xfa,0xb7,0x3f,0x95,0xfd,0x50,0x3a,0x97,0x0a,0xfd,0x56,0x55,0xaa,0x89,0x96,0x83,0xed,0x9d,0xcd,0xc0,0xc3,0x3a,0x21,0x5a,0x0d,0x6b,0xa1,0x07,0x6f,0x36,0xa2,0xd6,0x0a,0x5c,0x1e,0xa7,0x1f,0x21,0x73,0xcb,0x76,0xc9,0xcf,0xa8,0x54,0x5e,0x8a,0x77,0xa4,0xbc,0xe1 +.byte 0x8d,0xff,0x25,0xbd,0x2f,0x71,0x6e,0xff,0x36,0x99,0x62,0x07,0xfb,0x4a,0xc7,0x7c,0x27,0xd4,0xbb,0x27,0xec,0x1b,0x52,0x58,0xfe,0xa1,0x7a,0xe6,0xc7,0x04,0xff,0x76,0xc5,0xe3,0x7a,0x20,0xed,0x7c,0xbb,0x77,0x0f,0xf2,0xc7,0x93,0x11,0x85,0xe2,0x77,0xca,0xfc,0x81,0x8e,0xec,0x1c,0xf5,0x96,0xba,0xde,0x87,0x68,0xb9,0xd6,0xde,0xd7 +.byte 0x69,0xd8,0xd7,0x0c,0x9e,0x04,0x23,0xcc,0x5e,0x4a,0x9b,0x53,0x78,0x3b,0x58,0x71,0x7f,0x0f,0x75,0xe7,0x81,0x75,0xce,0x90,0x80,0xf0,0x37,0xb0,0x69,0xd7,0x54,0xc4,0x57,0x14,0xf4,0x08,0xf9,0x79,0xb1,0x28,0xaa,0x0f,0xa2,0x09,0xe2,0xc9,0x04,0xd3,0xa7,0x85,0x52,0x56,0x91,0x1f,0x29,0xd8,0x10,0x89,0x13,0x7f,0x23,0x56,0x14,0x97 +.byte 0x59,0x17,0xd2,0x52,0x68,0x0a,0xff,0xd1,0x0d,0xd3,0x3d,0xa2,0x22,0x7f,0x17,0x82,0x38,0x0d,0x7e,0xed,0x35,0x05,0x7e,0xfa,0x9c,0x43,0xac,0x87,0xb5,0xaa,0xe1,0xc5,0x42,0x85,0x3a,0xe9,0x18,0x34,0x73,0xfa,0x9a,0xc3,0x8a,0xca,0xd8,0xca,0xc0,0x87,0xd4,0x0c,0x70,0xc0,0xb0,0x64,0x13,0xf7,0x35,0xfa,0xd3,0x90,0x99,0x36,0xdf,0x90 +.byte 0x9f,0xd5,0x01,0xfd,0x1f,0x51,0xf8,0x09,0x9d,0xec,0xea,0x79,0x70,0xae,0xc5,0x39,0x20,0xff,0x6a,0xea,0x09,0xcf,0x50,0x49,0xfd,0x6b,0xd8,0x68,0xf2,0x13,0xb1,0x58,0x73,0xbb,0xcf,0x9a,0xba,0x28,0xda,0x63,0xbf,0x02,0x75,0x8f,0x88,0x9f,0xc5,0x16,0xa9,0x58,0x34,0x46,0x42,0x59,0x13,0x22,0xb0,0xe8,0x0c,0xea,0xd3,0xbd,0x57,0xaa +.byte 0x67,0x88,0xf9,0x88,0x04,0x7b,0x5f,0xf1,0x8f,0x71,0x31,0x22,0x8f,0x8a,0x3b,0x0e,0xf7,0x65,0xe4,0xd3,0xf5,0xec,0x32,0x4e,0x61,0x91,0x9f,0xa5,0x3d,0x88,0x02,0x1d,0xa6,0x7a,0x75,0x3f,0xd9,0x10,0xba,0x76,0x43,0xd4,0x31,0x3c,0x39,0x6d,0x60,0x7a,0xe9,0x19,0xe5,0x21,0x97,0xcc,0xb4,0xe6,0x1f,0x4c,0xb4,0x39,0xfc,0x36,0x29,0xec +.byte 0x19,0x72,0x28,0x25,0x09,0x30,0x9d,0x7d,0x8a,0x3a,0xd4,0x31,0x65,0x53,0x61,0x05,0x07,0xd2,0x9d,0xbb,0x77,0xde,0x54,0xde,0xbb,0x5b,0xe4,0xae,0xa4,0xc7,0x75,0xfe,0x72,0x2a,0x89,0xfb,0x60,0x15,0x06,0x83,0x4e,0x38,0xfd,0x21,0x28,0x6a,0xaf,0xa2,0x58,0xd5,0x38,0x05,0xd2,0xcf,0xcd,0x48,0x7a,0xed,0x0b,0x54,0x9e,0x74,0x85,0x14 +.byte 0xa6,0x84,0x2d,0xa2,0x92,0x5e,0x74,0xef,0x4f,0x6d,0x2a,0xcf,0xed,0x17,0x91,0xd8,0x97,0x25,0x37,0xe3,0xff,0x8b,0xc9,0x1f,0x25,0xa5,0x85,0x52,0xe9,0xb5,0x3a,0xa9,0xe6,0x0d,0x12,0x6b,0x46,0x51,0xf5,0xb0,0x8f,0x3d,0x9a,0x0b,0x9d,0x7c,0x9a,0x65,0xdf,0xc6,0x9c,0x17,0xd1,0x0b,0xdc,0xe3,0xd0,0x75,0xef,0xa7,0xbf,0x1d,0xae,0xe4 +.byte 0x50,0x9f,0x03,0x3e,0x90,0x3a,0xa5,0x5b,0x38,0x9f,0x0b,0x02,0x35,0x5f,0x1f,0x26,0xd3,0x2a,0x6f,0x1c,0x75,0x11,0xb2,0xd3,0x65,0x3a,0x96,0x3d,0xfe,0x5e,0x8d,0xef,0x04,0xe8,0xe7,0xb3,0x6e,0x7c,0xee,0x2e,0x8f,0x0d,0x9f,0xf7,0x0b,0xed,0x01,0x82,0xdb,0x54,0x0c,0x01,0x5a,0xea,0xd9,0xeb,0x9e,0x25,0x54,0x95,0x36,0xfc,0xc4,0x09 +.byte 0x15,0xee,0x88,0xb4,0x16,0xf6,0xc9,0x79,0xd7,0x79,0xf4,0x94,0x7a,0x5e,0x28,0x19,0xe7,0x2d,0x94,0xd1,0xed,0x48,0x12,0x15,0xba,0xbd,0x90,0xad,0x64,0xec,0x6a,0x52,0xa0,0x33,0xfb,0x13,0xa6,0xe7,0x30,0x04,0xfb,0x7b,0x69,0x07,0x6e,0xfc,0x1c,0xe4,0x0d,0x8b,0x8f,0x38,0x6f,0x59,0xe8,0x5a,0x0a,0x67,0x28,0xd3,0x3c,0xe4,0xd7,0xf2 +.byte 0xae,0x0d,0x90,0xac,0x2a,0x9f,0xb6,0x5f,0xfb,0x30,0x5e,0x6d,0xad,0x19,0x86,0x58,0xa4,0x4c,0x2a,0x10,0xdd,0x9a,0x65,0x6e,0x07,0x4f,0x14,0xf6,0xe8,0x7b,0x43,0xb9,0x18,0x2c,0xa4,0xa7,0x2a,0xa2,0xc4,0xf9,0x4e,0x43,0x4e,0xfe,0xf6,0x57,0xbf,0x50,0xc5,0x36,0x7a,0x63,0xac,0x30,0xb3,0x7c,0x78,0x63,0xd2,0xd0,0x1d,0xe3,0x68,0xa2 +.byte 0x79,0xa2,0xf3,0x29,0x54,0x04,0x31,0x47,0xf8,0x8c,0x60,0xa5,0x47,0x70,0xa8,0x86,0x89,0xfb,0x7e,0x7e,0xb1,0xc0,0xa5,0xec,0x39,0x3b,0xb5,0xb8,0xb9,0x92,0xd0,0x06,0xfb,0xed,0x39,0x56,0xa6,0x11,0xf6,0x5e,0xe9,0x04,0xb7,0xe4,0x9a,0xf0,0x61,0x3e,0x53,0xda,0xf1,0x61,0x1d,0x1e,0xc8,0xe5,0x46,0x1d,0x73,0xd3,0x33,0xc1,0xab,0xf9 +.byte 0x93,0x4f,0x31,0x02,0x4d,0xab,0xd8,0x45,0xa1,0x4d,0x9b,0x37,0xc4,0xd9,0x40,0x58,0x5b,0x56,0x0b,0x46,0x69,0x0e,0xfc,0x27,0xa0,0x44,0xd7,0xf4,0xb0,0xcd,0x2a,0xd1,0xf9,0xf3,0x65,0x8a,0x3b,0xcc,0xdc,0x92,0x25,0xb6,0x8a,0x13,0xb3,0xbc,0x35,0xc8,0xd9,0xc1,0xbf,0x31,0xbb,0x27,0x96,0xa0,0xc2,0x34,0x1c,0x6c,0x33,0xda,0x24,0xac +.byte 0x1e,0x0a,0x9e,0x2e,0x07,0xc7,0xc2,0xcc,0xcc,0xf6,0xd0,0x0a,0xf2,0x40,0xe0,0x20,0xce,0xf1,0xcf,0xf0,0x05,0x46,0x06,0xfc,0x33,0x8f,0x19,0x13,0x4e,0x34,0x21,0xa9,0x51,0x6c,0xcf,0x7f,0x6a,0x80,0x4a,0x32,0x6d,0x3d,0xb1,0x63,0xa8,0x2c,0x74,0x13,0x8f,0xf7,0xa1,0xfe,0x6e,0xbd,0xb4,0x80,0xc2,0x2b,0xc7,0x1c,0x99,0x26,0xd0,0x56 +.byte 0x98,0x77,0x83,0xc8,0xa7,0x3e,0xe2,0x02,0xfc,0xa8,0x45,0x0d,0xcc,0xe6,0x8c,0x6f,0x07,0x03,0x93,0xdc,0x51,0xce,0xbd,0xe7,0x89,0xc8,0x7f,0x8a,0x06,0x8a,0x81,0x13,0x88,0x12,0x7f,0xd4,0xa9,0x63,0x10,0x0b,0xc2,0x82,0xbe,0x51,0x5c,0x66,0x14,0xb3,0x0f,0x3c,0x6d,0x8a,0xf7,0xec,0xe6,0x3c,0x9f,0x20,0xc8,0x02,0xe3,0xbb,0x59,0x53 +.byte 0xc9,0x97,0x29,0xf0,0xa0,0xb1,0x50,0xf7,0x63,0x95,0x96,0x35,0xd0,0x81,0xb3,0xf0,0x44,0x5a,0xf5,0x55,0x10,0x3d,0xe8,0x76,0x21,0x62,0x49,0x1a,0xbb,0x8c,0x1a,0xff,0x75,0x39,0x3c,0x26,0x9e,0xee,0xef,0xaa,0x3d,0xa1,0x21,0xb0,0x47,0xb5,0x15,0x54,0x59,0x11,0x47,0x0c,0x1c,0x53,0x4e,0x0e,0x54,0x38,0xa5,0xed,0x8d,0x1f,0x4e,0x91 +.byte 0xfc,0xd7,0x78,0xff,0x9c,0xfe,0xe3,0x86,0xd5,0x8d,0xc6,0xf2,0x03,0x01,0xbb,0xf7,0x89,0x25,0x19,0xb9,0xab,0xd8,0xd0,0x72,0xff,0x69,0x04,0x97,0x77,0xe4,0x43,0x0e,0xe8,0xb6,0xc3,0x57,0xab,0x96,0xe3,0x53,0xfa,0x5c,0x5e,0xfd,0xbd,0xf0,0xba,0xc9,0xfd,0xd5,0x12,0x4f,0xa9,0x72,0xfb,0xf4,0x6d,0xd2,0x74,0xef,0x29,0xd8,0x73,0x27 +.byte 0x62,0xd8,0xe1,0x4c,0xd5,0xb0,0x1d,0xfa,0xf5,0x67,0x02,0xed,0x38,0xbe,0xa7,0x0c,0x3f,0xe1,0xad,0xc3,0x8f,0x4e,0x81,0x73,0xe1,0x65,0x7b,0xcc,0x41,0x16,0x2d,0x5b,0xeb,0xaf,0x14,0x96,0x7b,0x53,0x7b,0xcf,0xb7,0x98,0x28,0x92,0x88,0xc5,0x17,0xfe,0xcc,0xce,0x4e,0xe2,0x53,0xfd,0x38,0xd3,0x15,0xfb,0x31,0xd6,0x8e,0x69,0xd4,0xda +.byte 0xae,0x72,0x71,0xe1,0x93,0xf9,0x2e,0x28,0x80,0x2a,0xc2,0x8a,0xaa,0x5c,0xba,0x64,0xad,0x2e,0x64,0x2a,0xb1,0x3d,0x71,0x03,0x10,0x2e,0x9a,0x93,0xca,0x85,0xaa,0x77,0xd8,0x80,0x1c,0xe0,0xf9,0x5a,0xfe,0xa3,0xc9,0x8a,0x2d,0xb9,0x45,0xc8,0x9f,0xa9,0x61,0x85,0x81,0xe7,0x1d,0x7d,0xf8,0x11,0x14,0x57,0x51,0xc4,0x84,0xf8,0xb5,0xc9 +.byte 0xb9,0xa0,0x3f,0xd1,0xa2,0xcd,0x87,0xaa,0x76,0x2a,0xba,0xab,0xd4,0xb0,0x9d,0xf3,0x83,0x4e,0xcb,0x44,0xf0,0x4b,0xd9,0xce,0xb0,0x2b,0xca,0x92,0xf8,0x3c,0x4a,0x5c,0x8b,0x20,0xc3,0xfc,0x4b,0xca,0xe4,0x2f,0x35,0xfc,0xfc,0xcd,0xf9,0xc5,0x6f,0x75,0x63,0x07,0xf4,0xe1,0xe6,0x4c,0x5f,0x10,0x05,0xe3,0xb5,0xec,0x4c,0x4f,0xd8,0xda +.byte 0x64,0xeb,0x7b,0x9c,0xae,0xe4,0x7c,0x3f,0x31,0x1b,0x71,0x8b,0x48,0x52,0x88,0x99,0x8f,0x5f,0x31,0xf3,0x7c,0x6e,0x15,0x4c,0x38,0x96,0xab,0xfb,0x4f,0xeb,0xee,0x3c,0xff,0x8d,0xce,0xab,0xb2,0x96,0x00,0x3b,0x8a,0xb3,0x10,0x3b,0xa5,0xc3,0x5e,0x8f,0x9d,0x2b,0x78,0x18,0x80,0x62,0x8c,0xa6,0x3c,0xeb,0x4c,0x92,0x2d,0x67,0x7e,0xdb +.byte 0xc6,0x26,0x58,0x73,0x65,0x0c,0x03,0x07,0x28,0x0d,0xe7,0x9a,0x03,0x3d,0x81,0xc2,0x32,0x76,0x1d,0x27,0xef,0x6e,0xea,0x02,0x7b,0xca,0x3f,0x07,0x63,0x69,0xed,0x30,0x44,0xde,0x2b,0x7f,0x32,0x42,0x28,0x7a,0xc5,0x24,0xf9,0xb6,0x0b,0x24,0xca,0x61,0x17,0x8f,0x80,0xda,0xe7,0x86,0xf0,0xc5,0xca,0xd9,0x6a,0x9a,0x56,0xd4,0x80,0xe3 +.byte 0x34,0x9e,0xae,0x9e,0x80,0xf9,0xe4,0x1f,0xa9,0x0d,0x66,0x0d,0x7c,0x31,0xad,0xeb,0x61,0xf1,0xef,0xe5,0xcf,0xfc,0x46,0xbf,0x11,0xb0,0xd1,0x4d,0x9f,0x66,0x11,0xb9,0xba,0x3a,0x32,0x9a,0x0e,0x87,0x56,0x9d,0x03,0x03,0x42,0x19,0xb8,0x4f,0x6e,0x1f,0xc9,0x70,0x69,0x78,0x1e,0x61,0xcc,0x05,0x81,0xea,0xad,0x33,0x7f,0x33,0xcc,0xfe +.byte 0x29,0x42,0x02,0xc6,0xc6,0x8f,0x0c,0x02,0x80,0x11,0x1b,0x7b,0x9a,0x43,0xdc,0x66,0x22,0x6a,0x76,0xd5,0x9c,0xd2,0xbb,0xd6,0x52,0x0d,0x7a,0x93,0x24,0x54,0x6f,0x57,0x99,0x55,0xbe,0x1a,0xb6,0xa3,0x06,0xc4,0xff,0xbe,0x8c,0x2b,0x77,0xba,0x4f,0x0d,0xe6,0x34,0xc1,0xea,0x1f,0xca,0xe8,0xb7,0x77,0x84,0x69,0x77,0xa2,0x6c,0x95,0x1e +.byte 0x6d,0xbf,0x45,0x59,0x8a,0x9d,0x1e,0x0f,0xf2,0xf2,0x6a,0x03,0x81,0x26,0xbd,0x2a,0x6c,0xe9,0x1e,0xd3,0xa8,0x99,0xc6,0x89,0xaa,0xce,0x1a,0x4c,0xfd,0x4b,0x88,0xe0,0x5d,0xe3,0xc7,0x0b,0xe3,0xce,0x0a,0x71,0x96,0x03,0x31,0x0c,0xc0,0xdc,0xb0,0x31,0x44,0x5a,0x33,0xde,0xd3,0x4f,0x41,0x8d,0x60,0xa9,0x7f,0x6a,0xa1,0xb2,0xc4,0x00 +.byte 0x31,0x1d,0xb4,0x62,0x45,0x17,0xd9,0x05,0x55,0x7d,0x3a,0x76,0x38,0x62,0x65,0x16,0x94,0xf2,0x4f,0x7d,0x31,0x6d,0x17,0x79,0x54,0xd4,0x0a,0x5d,0x12,0x12,0xab,0xba,0xc6,0x60,0x9b,0xb2,0x42,0x55,0x2c,0x5b,0x93,0xc9,0x8a,0x11,0x66,0xd8,0x34,0x47,0x6b,0x33,0x13,0xff,0x12,0x25,0xeb,0x21,0x31,0x1a,0x70,0xb0,0x77,0xec,0xc8,0xb7 +.byte 0xd6,0xc9,0x91,0x4b,0xfe,0x71,0x40,0x09,0x50,0x9d,0xf0,0xf2,0xb3,0xbd,0x4b,0x02,0x5b,0x6a,0x9e,0x30,0xed,0x31,0xd3,0x6d,0xb6,0xa8,0xed,0x9e,0x28,0xc8,0xb3,0x42,0xe4,0xbe,0x79,0x01,0x96,0x86,0x9a,0xeb,0xfb,0x7e,0x51,0x4b,0x79,0x8d,0xf9,0x8f,0x62,0xf6,0x66,0x75,0xa4,0x2e,0x9a,0x93,0x3f,0x4d,0x29,0xf9,0x8e,0xd3,0x40,0x34 +.byte 0xd3,0x60,0xf6,0x68,0x61,0xe9,0x62,0xe6,0xca,0x8c,0x15,0xc3,0xac,0xde,0x40,0x61,0x02,0xcd,0x1a,0x96,0x3c,0xa6,0x4d,0x08,0x66,0x9d,0x35,0x15,0x5a,0x7a,0x38,0x24,0x64,0xb6,0xb6,0xed,0x03,0x4c,0xdd,0x7b,0xe5,0x2f,0x84,0x48,0x6b,0x31,0xc2,0x2e,0xe9,0x70,0xe1,0xaa,0x10,0x55,0x5a,0x18,0x95,0x0b,0xcd,0xa9,0xdb,0x9e,0x87,0x07 +.byte 0xae,0x73,0x0c,0x87,0xd0,0xd5,0xc5,0x92,0x48,0xc5,0xa1,0x13,0x80,0xf5,0xe0,0xdc,0xa0,0x61,0x7b,0xba,0x95,0x43,0x38,0x64,0xc0,0x13,0x1b,0x3f,0x14,0x1b,0xcd,0x24,0x1e,0xf7,0x7e,0x9e,0x5d,0x05,0xeb,0xb2,0xe0,0xb8,0x34,0x8c,0xe0,0x25,0xde,0xcc,0x72,0x06,0xc1,0x4c,0x41,0x2f,0xfc,0xb1,0xc2,0x60,0x01,0x09,0xcf,0x44,0x5f,0x7e +.byte 0xeb,0x79,0x15,0x89,0x8c,0xaf,0xcb,0xc6,0xcf,0x3f,0xc4,0xae,0xcc,0x82,0x1f,0x08,0x3b,0x97,0x9c,0x74,0x09,0x4c,0x24,0x79,0xea,0x4f,0xd6,0x29,0x9a,0xec,0xb7,0xbd,0xb7,0x09,0x23,0x37,0xd5,0x7d,0x3e,0x7f,0xce,0x33,0xc3,0xe2,0x6c,0xff,0x1e,0xe0,0xcf,0x88,0xca,0x51,0x77,0x9c,0xc6,0xc3,0x13,0xa0,0x7e,0x4a,0x70,0xe8,0xb3,0xe2 +.byte 0x65,0x82,0x61,0xb9,0x00,0x96,0xf5,0xa8,0x78,0xba,0x4d,0x5c,0xce,0x1f,0x67,0x1e,0xc1,0xbc,0x60,0xf4,0x40,0x04,0xb6,0xd9,0xe6,0x6c,0x6e,0xbc,0x68,0xf8,0x0e,0x0c,0x93,0x2b,0xf6,0x4a,0x9b,0xfa,0x04,0xe2,0x94,0x4a,0x40,0xe3,0xc2,0x69,0xcb,0xd0,0x64,0x3f,0x4b,0x8a,0xcf,0x6e,0x50,0xde,0x54,0x6e,0xf8,0xc6,0xab,0x03,0xb9,0x88 +.byte 0x4e,0xaf,0xfc,0xcc,0x90,0xfa,0x74,0x8f,0xb5,0x8f,0x8f,0xc6,0x17,0xf3,0xc9,0x7a,0x06,0x68,0x2d,0x77,0x91,0xcf,0x52,0xcd,0xf2,0x8d,0xc8,0xac,0x6f,0x4d,0x4a,0xb7,0xfd,0x7e,0x46,0xb7,0x4d,0x4d,0x92,0x05,0xc3,0x68,0xcf,0xf2,0x27,0x2b,0x9a,0x57,0xeb,0xcc,0x4d,0x5d,0xef,0x86,0xe0,0xfe,0xd9,0x43,0x66,0x88,0xb8,0x42,0x1d,0xb2 +.byte 0x5e,0x80,0xbe,0x96,0x00,0x9a,0x69,0x7f,0x27,0xcf,0x15,0x44,0x6e,0x5d,0x8b,0x76,0xf9,0xd0,0xb6,0xfd,0xeb,0x56,0x39,0x4c,0x94,0x1b,0x3e,0x09,0xf8,0x59,0x03,0xc9,0x7d,0x1c,0x66,0x4e,0x7c,0xd5,0x87,0xd1,0xeb,0xcf,0x53,0xaa,0xda,0x08,0x26,0x65,0x22,0x15,0x42,0x7c,0x13,0x4d,0xfa,0x50,0xd8,0x52,0xe9,0x71,0x57,0xd9,0x29,0xd2 +.byte 0x02,0xb3,0xbd,0x1c,0x1b,0x06,0x77,0x68,0xb2,0xd5,0x3a,0x7c,0x9e,0x54,0x3a,0x75,0xc7,0xa8,0x9d,0x0e,0x5f,0x89,0x20,0x46,0x20,0xdd,0x21,0xb1,0xac,0x96,0xa6,0xd4,0xdf,0x9f,0xe9,0xd4,0x06,0x52,0xc3,0x34,0x43,0x61,0xdc,0x5f,0x85,0x75,0xa1,0xc5,0x10,0x67,0x6f,0xf2,0xba,0xcd,0x64,0x9e,0x69,0x44,0xdd,0x15,0xea,0x05,0x5a,0xbb +.byte 0xb3,0xa3,0x8d,0xe6,0xbf,0x4d,0xb0,0x29,0x81,0x81,0x56,0x95,0xc8,0x81,0xcd,0xc1,0x63,0x7b,0x9c,0xa1,0xf8,0x89,0xea,0xf0,0x19,0x05,0x1e,0xe9,0xbe,0xf8,0x9e,0x58,0xae,0xaa,0xf4,0xca,0x45,0x68,0x81,0x18,0x38,0xd7,0x27,0x81,0x14,0xcb,0x68,0x81,0x61,0x37,0x38,0x67,0xc3,0x4e,0xb7,0x30,0x2c,0x9f,0x00,0x6b,0x55,0x87,0xdd,0xb5 +.byte 0x54,0x00,0x65,0x85,0x33,0xf6,0xde,0xe6,0x0b,0xee,0x2c,0x64,0xc7,0x14,0xbc,0xf2,0x95,0x31,0x8c,0x63,0x51,0x9d,0x41,0x72,0x14,0x3f,0x60,0x50,0xb7,0x15,0xd4,0xf4,0x8e,0x50,0x9e,0xe9,0x6a,0x94,0x3a,0x0e,0x7e,0x36,0x74,0xcb,0xdb,0xe8,0xe3,0xba,0xd9,0xe2,0x5b,0xdb,0x87,0xf8,0x17,0xd9,0x5e,0x5c,0x4d,0xca,0xc8,0x13,0xae,0xfa +.byte 0x24,0x72,0xef,0xda,0x10,0xf6,0xf9,0xe9,0xe0,0xde,0xfe,0xc6,0x9b,0x76,0xfe,0x52,0xc7,0xe0,0xe1,0xf7,0x31,0xa9,0x54,0x5a,0x8e,0xb9,0x6b,0x2c,0x3a,0x18,0x57,0xe9,0x4b,0x39,0x11,0x30,0x4e,0xb5,0x85,0xb6,0xa7,0xee,0x37,0x1a,0xfe,0x60,0x64,0xf5,0x7f,0x46,0x9e,0x82,0x2d,0xcb,0x74,0x4e,0x95,0xc3,0xa0,0x87,0x94,0x85,0x84,0x54 +.byte 0x28,0xe3,0x14,0x93,0xb6,0xa2,0x28,0x2c,0x14,0x68,0x8c,0x88,0x82,0xc5,0x75,0x1b,0x25,0x8e,0x50,0xf0,0xad,0xb7,0xfb,0x31,0xb2,0x24,0xf1,0x29,0x5e,0x65,0x58,0x9a,0x8c,0x2b,0x9b,0x6d,0xa4,0x07,0x08,0x0d,0x60,0x7d,0xd9,0xb4,0xe0,0x01,0x93,0x07,0xf3,0x8f,0xde,0x70,0x76,0x10,0x80,0x1d,0xe3,0x1b,0x21,0x58,0xba,0x4a,0xbe,0x9c +.byte 0x04,0xdc,0x53,0x64,0x6d,0x12,0x37,0xea,0xa5,0xdf,0xa7,0x1a,0x1d,0x13,0x53,0x87,0xb0,0x98,0xa6,0x1f,0x48,0x5f,0xc2,0x56,0xf2,0x98,0x76,0xd1,0x5f,0x78,0x5e,0xb8,0x6b,0xf0,0x29,0x66,0xa6,0xb2,0x91,0x57,0xde,0xbf,0xc1,0xf1,0xd5,0x8c,0xa4,0x62,0x88,0x2c,0x40,0x53,0x0d,0x46,0x20,0x5c,0x82,0x75,0x03,0x91,0x79,0x6f,0x95,0xd0 +.byte 0x95,0xda,0xab,0xd0,0x8a,0x20,0x1c,0x36,0x94,0x7c,0x12,0xe7,0xbe,0x9e,0x1f,0x99,0x7b,0x4b,0x79,0x6e,0xed,0x3e,0x7d,0x77,0x32,0x0b,0x0c,0x54,0xd3,0x22,0xe8,0xcd,0xe7,0x10,0xd7,0xe9,0xd4,0x4a,0xb5,0x68,0x61,0x29,0x1b,0x9f,0x0f,0x72,0xdd,0xaf,0xb2,0xc7,0x57,0x50,0x45,0x8d,0x45,0x6d,0xd2,0x70,0x7b,0x89,0x78,0xeb,0xb9,0x2d +.byte 0xf9,0x82,0xb3,0xa3,0xc0,0x9d,0x96,0xf0,0x29,0x0c,0x4d,0xc2,0x03,0x3a,0xee,0x59,0x4e,0x26,0xe7,0x6a,0x88,0xae,0x4e,0x47,0x0d,0x18,0xce,0x71,0x01,0x79,0xf7,0xa3,0x04,0x64,0x54,0x53,0x7e,0x1f,0xb3,0x4f,0x83,0x9f,0x39,0xb8,0xfe,0x1e,0x0c,0x3e,0x9e,0x50,0xc8,0x6f,0xdf,0xf6,0x00,0x4d,0x7b,0xa3,0x0b,0x44,0x6f,0xbe,0x4f,0xf6 +.byte 0x47,0x50,0xe5,0x02,0x58,0x5e,0x87,0x9a,0x18,0xc0,0xa0,0x89,0x8b,0x33,0x57,0x1a,0x31,0xab,0x6d,0xd0,0x87,0x54,0xee,0x66,0xca,0xf7,0xb9,0xe6,0x27,0x9c,0xbd,0x48,0x98,0x58,0xa5,0xcc,0x9e,0xe7,0xce,0x88,0x95,0x0e,0x1a,0x35,0x3a,0xee,0xe4,0x0c,0x7e,0xfa,0x87,0x86,0xb4,0x09,0xd7,0x10,0xdc,0x39,0x47,0x68,0xae,0x8b,0xf8,0xc4 +.byte 0xf6,0x91,0x6e,0xbb,0x95,0xbf,0xba,0x41,0xd9,0xe3,0xb3,0x40,0x6b,0x3b,0xa3,0x0e,0x8f,0x6b,0xad,0x4b,0x1b,0x44,0x0d,0x35,0x7d,0xdf,0xfc,0x65,0xec,0xa7,0x73,0x14,0x2a,0xf9,0x26,0x24,0x5b,0x22,0x6e,0x97,0x65,0xdf,0x78,0x59,0xd3,0xb3,0xd9,0x68,0xbb,0x0c,0x4e,0x4d,0x4b,0x77,0xc3,0x4a,0xfa,0x0a,0xe4,0x99,0x9d,0x53,0x60,0x0f +.byte 0x09,0x1c,0xcd,0x5d,0x74,0xd0,0x50,0x71,0xaa,0x2b,0x15,0xb4,0x73,0xe0,0xf9,0x66,0x54,0x7d,0x9b,0x74,0x9f,0x7f,0xf7,0x9c,0xa2,0x9c,0x91,0xeb,0xaf,0xc6,0xb7,0xb7,0x2f,0x7f,0x7a,0x25,0x6c,0xc4,0xad,0x08,0xde,0x01,0xe0,0x90,0x90,0x23,0x32,0xf9,0x3e,0x48,0x27,0xa4,0x37,0x96,0x53,0xf1,0x00,0xfe,0x6f,0xc2,0xdb,0xde,0xb3,0x63 +.byte 0xab,0x6a,0xa5,0x2d,0x29,0x00,0x7d,0xbd,0x10,0xa4,0xf7,0x88,0x46,0x23,0xfb,0x05,0x5f,0x92,0x43,0x5d,0x3c,0x7c,0xbc,0x90,0x66,0x77,0xda,0x08,0x9b,0x87,0xd2,0x69,0xba,0x84,0x7b,0x7b,0x66,0x97,0x22,0xd6,0xce,0x5a,0x9d,0xc6,0xd2,0x7c,0x13,0x25,0x86,0x1b,0x4c,0x36,0x1f,0x73,0x09,0xdc,0xb3,0x96,0xd9,0x10,0xdc,0xcc,0x80,0x4c +.byte 0xd9,0x72,0xed,0xa5,0x44,0x65,0x10,0x80,0xee,0x5e,0xfa,0x24,0x7a,0x23,0xb3,0xc7,0x61,0x93,0x6b,0xe4,0x0b,0x4a,0x4b,0x4a,0xa5,0xd8,0x51,0x76,0xf1,0xd9,0x92,0x2b,0x17,0x20,0x0c,0x9a,0xba,0xc3,0x4a,0x29,0x27,0x5c,0x34,0x5b,0xcf,0x44,0x17,0x16,0x61,0x52,0x41,0x3b,0x6e,0x99,0x14,0x94,0xa9,0x5f,0x9b,0x2b,0x1e,0xcf,0xdd,0xcc +.byte 0xff,0xc0,0x7a,0xce,0x0a,0x1c,0xf5,0x33,0xaf,0xcb,0xde,0x92,0x56,0x36,0x81,0x98,0xa6,0x70,0x4c,0x49,0x4a,0xd8,0x88,0x0a,0xb8,0x5d,0x5a,0xbe,0x03,0x98,0xba,0xe1,0xf2,0x11,0x44,0x65,0x02,0xd8,0xef,0x8c,0x84,0x0f,0x48,0xa1,0xf1,0x61,0xff,0xef,0x18,0xf1,0x29,0x4a,0x7b,0x8b,0xb2,0xb2,0xa1,0x50,0x26,0xa9,0x86,0x2a,0x06,0x8a +.byte 0x33,0x05,0x9f,0x20,0x5b,0x06,0xc3,0x50,0x79,0x20,0x34,0xe5,0x88,0xc0,0xfc,0xff,0xb6,0xa0,0x7c,0x0a,0xe2,0x43,0xc1,0xd2,0xf4,0xb2,0xdf,0xa6,0x51,0x98,0x67,0x6f,0x3e,0xc0,0xae,0xd3,0x35,0xd2,0x5f,0x73,0x71,0x2b,0x3e,0xa7,0x0d,0x8a,0x4c,0xa3,0xba,0xe4,0xac,0xc2,0xfe,0xb4,0x82,0x0e,0xe5,0x76,0x82,0x0f,0x9a,0xd3,0x54,0x24 +.byte 0x21,0x01,0x34,0x4c,0xa1,0x0c,0x6e,0x80,0xe0,0x99,0xb1,0x4b,0x40,0xce,0x29,0x33,0xe3,0x5a,0x9c,0x15,0x33,0x06,0x1c,0xdf,0xea,0x01,0x3f,0x2f,0x9a,0x9a,0x34,0x07,0x53,0xc6,0x7c,0x0f,0xbd,0x17,0x06,0xa3,0x47,0x44,0x0f,0xd4,0xb4,0x96,0xf7,0xc5,0x71,0x4c,0xe0,0xc1,0xb7,0x42,0x0f,0x30,0xbb,0x09,0x17,0xc3,0xc4,0xaf,0x30,0x22 +.byte 0x45,0x13,0x91,0x55,0x5e,0xde,0x31,0x19,0x0c,0xfc,0x85,0xd7,0x08,0x99,0x0b,0x30,0xbf,0xa7,0x15,0x26,0x2f,0x09,0x2d,0x2d,0xe0,0x60,0x7d,0x88,0x71,0xf4,0x97,0xa7,0x65,0x8d,0x5b,0x59,0x71,0x4d,0xc2,0xf0,0x46,0x2a,0x58,0xe1,0x23,0x78,0x33,0xd6,0x85,0xdd,0x1a,0x02,0x60,0x12,0xdd,0x45,0x8d,0xab,0xdb,0xe6,0x26,0x67,0xbe,0x12 +.byte 0xb2,0xff,0xcb,0x20,0x79,0x09,0x5a,0x44,0x92,0x93,0xae,0x74,0x59,0x9d,0x20,0x96,0x81,0xe1,0x53,0x2d,0xf8,0x10,0xc8,0x69,0x4d,0xc8,0xe4,0x60,0x32,0x46,0xf1,0xba,0x6d,0x73,0x8d,0x70,0x8e,0x24,0xf1,0xb7,0x80,0x1b,0x77,0x70,0x3e,0x16,0xa1,0x15,0xb7,0x25,0xd2,0x11,0x41,0x7d,0xd8,0x7d,0x42,0xa0,0x81,0x02,0x61,0xd0,0x6d,0x3a +.byte 0xb9,0xc2,0x97,0xda,0x0f,0xf0,0x20,0x23,0x45,0xd4,0xe9,0xf5,0xf4,0x15,0x4c,0x84,0x47,0x2e,0x97,0xce,0x57,0xec,0xcf,0xc3,0x6a,0x54,0x87,0xeb,0xee,0x7c,0x5b,0x9e,0x9f,0xde,0x25,0x5d,0x60,0x7d,0xbe,0xd9,0xb4,0xb9,0x41,0x57,0x9b,0xe2,0xeb,0x21,0x09,0x60,0xb5,0xb0,0x55,0xaa,0xb0,0x15,0xa4,0x0b,0x83,0x98,0xee,0x81,0x7a,0x08 +.byte 0xfb,0xe6,0xf1,0xd8,0x02,0x87,0x85,0x15,0x59,0x4b,0xc7,0x6d,0x73,0x4f,0xac,0xf8,0x18,0x9e,0xd8,0x00,0xff,0x3b,0xec,0x44,0xaa,0x4a,0x1d,0x85,0x4b,0x52,0xd6,0xdd,0x88,0x6c,0xc1,0xb0,0x67,0x78,0xcd,0xa3,0xda,0xa1,0x30,0x18,0x7d,0xa6,0x14,0xc8,0x51,0xc1,0x03,0xeb,0x97,0x0b,0x03,0x94,0xcc,0x73,0x95,0xbd,0xea,0x44,0xe2,0xb2 +.byte 0x20,0xa4,0x20,0x9a,0x58,0x44,0x75,0x92,0x1f,0xac,0x75,0xf3,0x61,0xea,0xc1,0x9c,0xf7,0x7c,0xf7,0x6b,0x79,0x41,0xb4,0x53,0x32,0x8a,0xb0,0xfe,0x06,0xef,0xb0,0xf9,0x87,0xdb,0x31,0x9a,0xa0,0x84,0xe3,0xa3,0x8b,0x36,0xcb,0xe7,0xb4,0x1e,0xf2,0x21,0x3d,0x06,0x37,0x1a,0xb2,0x96,0xc6,0x94,0x67,0xc5,0x50,0x84,0x06,0xcf,0x57,0x66 +.byte 0x1a,0x7d,0x84,0xd6,0xa9,0xed,0x04,0xb3,0x83,0xa3,0xd4,0x55,0x4a,0x71,0x87,0x76,0x79,0xa4,0x9a,0x70,0x50,0x10,0x53,0x66,0x0e,0x7c,0xca,0xcb,0xac,0xcd,0x54,0x37,0x2e,0xe0,0x75,0x2d,0x75,0x06,0x92,0x50,0x0f,0x77,0xaf,0x87,0x71,0x1a,0x13,0x92,0xf9,0x7c,0x19,0x1c,0x3f,0x40,0xcb,0x14,0xbd,0x2e,0xe5,0x27,0x0d,0x1c,0x19,0xe3 +.byte 0x0f,0xda,0xca,0xc4,0x58,0xc6,0x98,0x14,0x89,0xc7,0xb2,0x6d,0x21,0x32,0x1d,0x17,0xd2,0x5d,0x40,0x04,0x56,0xd1,0x47,0xa6,0xc6,0x89,0xc9,0x28,0x0e,0x33,0x09,0x15,0xca,0x70,0x2b,0x7f,0xde,0x83,0x5b,0x32,0x83,0x99,0xa9,0xac,0xe9,0xb3,0xb8,0x07,0xc8,0xdf,0xd3,0x16,0x0a,0x42,0x03,0x9c,0x26,0x5e,0x97,0x55,0x4f,0xf7,0x5d,0x64 +.byte 0x83,0x8d,0x8f,0x14,0x89,0xed,0xd2,0xd3,0x67,0x92,0x1b,0x71,0x1f,0xef,0x17,0xcf,0xe6,0xa7,0xd7,0x3f,0xf2,0xab,0x5d,0x81,0x4b,0xfb,0x55,0x13,0xf5,0x56,0xf7,0xae,0xc3,0xae,0x40,0xbb,0xb4,0x70,0xfd,0xbc,0x6e,0xcf,0x17,0xea,0x94,0x07,0xec,0xba,0xd0,0xf9,0xc2,0x1c,0x40,0x48,0xf1,0x16,0x31,0x09,0x25,0x9a,0xe1,0xe1,0xdd,0x32 +.byte 0xf1,0x9f,0x00,0x6e,0xd7,0xac,0x14,0x7a,0xa0,0xf7,0xd0,0xcc,0x0e,0x25,0x9f,0xfa,0x1d,0x4b,0xc0,0x36,0x3f,0x68,0x01,0xd3,0xca,0x48,0x93,0xfb,0xc6,0x7b,0xdb,0xcb,0xe4,0x13,0x41,0x0c,0x24,0x45,0x7d,0x5a,0x9b,0x17,0xc2,0x7a,0x73,0x7c,0x03,0x9d,0x5c,0x71,0x54,0x68,0x9a,0x5d,0xf9,0x6e,0x5f,0x13,0x79,0x6d,0x65,0xca,0x7f,0xef +.byte 0xb2,0xa9,0x5a,0x77,0xc8,0x4a,0x4a,0x91,0x17,0xb1,0xb1,0x8c,0x28,0x22,0xe0,0xff,0xcb,0x00,0xa3,0xb6,0xe2,0x36,0xc2,0x5f,0xd9,0x7f,0x5f,0x85,0xef,0xe7,0x46,0x00,0xc7,0x08,0x8b,0xf3,0x1f,0x63,0x0f,0x23,0xff,0xe3,0x21,0x58,0x73,0xf7,0xaa,0xff,0x2d,0x9a,0x02,0xe5,0x18,0x66,0x34,0x65,0xfd,0x68,0xbf,0xd9,0x3b,0xfc,0xdc,0xc0 +.byte 0xa8,0xf7,0x2b,0xc2,0x37,0x01,0x7e,0x3d,0x6e,0x44,0x73,0xc8,0x6b,0x53,0xc3,0x19,0x51,0x84,0x3a,0x28,0xbe,0x5f,0x5a,0x1c,0xcf,0xd3,0xfb,0x25,0x43,0x99,0x9b,0x24,0x58,0xdb,0xc0,0x27,0xf4,0xfc,0xe6,0x2f,0x17,0x48,0xbb,0xf3,0x33,0xc1,0x0a,0x3e,0xb2,0x41,0x9b,0x24,0x16,0xcb,0x0c,0x2a,0x87,0x7f,0x34,0x70,0x4f,0xf0,0xb7,0x6e +.byte 0x39,0x18,0x3b,0xca,0x8f,0xcb,0x2c,0x51,0x68,0x5b,0x60,0xeb,0xeb,0x05,0xeb,0x96,0x77,0xca,0x60,0x0c,0x9c,0x88,0xc8,0x09,0x68,0x0d,0x7a,0x89,0x52,0xd7,0x8c,0x3f,0x71,0x71,0x21,0x89,0x4e,0xef,0x77,0x0a,0xdf,0xb7,0xfd,0x08,0x59,0x54,0x24,0x99,0x48,0x1f,0x27,0xca,0x7d,0x1b,0x46,0x2b,0x81,0x56,0xae,0x5a,0x02,0xd8,0x8e,0x1f +.byte 0x2a,0xc1,0xd8,0x9b,0xb5,0xeb,0xfd,0xae,0xe5,0x35,0x0d,0x33,0x3d,0x49,0x9e,0x0a,0x62,0x01,0xfb,0xd0,0x25,0xd6,0x9f,0x7d,0x70,0xd9,0x6e,0xda,0x19,0x97,0x5d,0x46,0x67,0x8c,0x21,0xd3,0xe5,0xe5,0x50,0xaf,0x47,0x16,0xb3,0xea,0x21,0xe1,0xee,0x1c,0x93,0x14,0xd0,0x4a,0x1e,0xfb,0x19,0xa9,0x26,0x71,0x53,0x9b,0x17,0xda,0x8f,0x28 +.byte 0xf5,0x35,0xf6,0x59,0x75,0xb1,0xeb,0xec,0x5a,0x92,0xc0,0xed,0xc1,0x48,0xaa,0xd8,0xb6,0x54,0x32,0x96,0x58,0x34,0x09,0x75,0x5e,0x0c,0x58,0x8d,0xc1,0x42,0xf1,0xfb,0x41,0xe1,0x23,0x84,0x25,0x3a,0x83,0x4c,0x13,0x0e,0x67,0x33,0xf9,0xfb,0x5b,0xa8,0xbb,0xbb,0x92,0x0a,0xca,0x5c,0x9e,0x7a,0x58,0xab,0x51,0x16,0xfc,0xf2,0x4d,0xee +.byte 0xa1,0x2d,0xaa,0x2d,0xb6,0xaf,0x30,0xca,0x4a,0xec,0x63,0xd6,0xf0,0xee,0x81,0xfd,0x9e,0xe7,0x71,0xb1,0x5f,0x3a,0x8e,0xa0,0xd1,0xa9,0xe0,0x61,0xdc,0x9e,0x78,0xbd,0x2b,0xaf,0x93,0xf9,0x61,0xf7,0x70,0x5e,0x9a,0xe9,0x9a,0x31,0x9c,0x81,0x66,0x5d,0x33,0xe4,0xc9,0xf0,0x28,0xfb,0xd7,0xa4,0x10,0x31,0x38,0x83,0x9b,0x96,0x7d,0xfd +.byte 0xd5,0x0e,0x23,0x62,0xa4,0x3b,0x6f,0x63,0xb7,0xbc,0x28,0xca,0xca,0xc5,0x14,0x1b,0xc5,0x3d,0x00,0x58,0xeb,0xf8,0x65,0x09,0x7f,0x0e,0x89,0xcf,0x6a,0x7d,0x0e,0x17,0xdc,0x74,0xde,0x8c,0xfd,0xe4,0x26,0x44,0xe4,0xce,0x2f,0x47,0x66,0x57,0x6f,0x4b,0x86,0x91,0xca,0x36,0xe3,0xeb,0x18,0xd3,0x48,0x63,0x5f,0x3f,0xc6,0xb5,0x38,0x5a +.byte 0x7d,0x20,0xe8,0xc1,0x9b,0xb4,0xc0,0x4e,0xe8,0x93,0x5e,0xd0,0x34,0xa3,0x30,0xf6,0xd6,0x51,0x0c,0x46,0x27,0x2c,0xac,0x91,0x01,0x10,0x8f,0xed,0xcb,0x16,0xf3,0x28,0xfb,0x44,0x55,0xac,0x5e,0xdd,0xf0,0xf6,0xe8,0xbf,0x7f,0xdb,0x14,0x7e,0x40,0x5e,0xa7,0x14,0x52,0x69,0xea,0xd6,0x03,0x76,0x3a,0x10,0x64,0xea,0xe8,0x0c,0x76,0x04 +.byte 0xc9,0x18,0x5e,0x22,0xe8,0x1c,0x19,0x2f,0xbe,0x72,0x61,0xe6,0xdc,0xbe,0x95,0x0b,0x95,0x39,0x3d,0x5a,0x34,0x43,0xca,0xb6,0x4b,0xa6,0xf5,0xd3,0x22,0xcc,0xa0,0x35,0x0d,0x06,0x89,0xd1,0xde,0x96,0x49,0x06,0x7e,0x62,0xa1,0x18,0xbd,0x78,0x65,0x2c,0x84,0x22,0xc0,0xea,0x9b,0x7c,0x5c,0xdd,0x97,0x20,0x60,0xc4,0xf1,0xdd,0x68,0xb7 +.byte 0x4b,0x30,0x17,0xcb,0xb7,0xbd,0x3c,0xb5,0x66,0xa7,0xad,0xc2,0x9a,0x31,0x79,0x09,0xff,0x4d,0xd5,0xd6,0x35,0x02,0xa6,0x0b,0x8a,0x8a,0xbb,0x54,0xe1,0xea,0xc8,0xa9,0x67,0xfc,0x1a,0x23,0x8d,0xdb,0xc5,0xe5,0x8d,0x1b,0x6f,0x20,0x57,0xbb,0xbb,0xda,0xfa,0x5b,0x07,0x3e,0x3e,0x84,0x2e,0x00,0x36,0x06,0x5c,0x85,0xa3,0x08,0x4a,0x59 +.byte 0x48,0x4c,0x7c,0xcc,0x63,0x49,0xde,0xb0,0x59,0xa2,0xb9,0x26,0x8c,0xb2,0x91,0xf8,0xf8,0x07,0xb8,0xba,0x16,0xdb,0xc7,0x6c,0x66,0x5f,0x91,0xc1,0xb8,0x24,0x97,0x1a,0xfb,0x95,0xf6,0x40,0xb0,0x5d,0xd7,0x55,0x40,0x8d,0x75,0x35,0xbf,0xd6,0xcf,0xe4,0xe8,0x6d,0x33,0x10,0xd7,0x8b,0xf3,0xc0,0x00,0x47,0xbb,0x90,0x51,0xd2,0xf5,0x56 +.byte 0xf8,0x82,0xb6,0x50,0xea,0x88,0x44,0x0b,0x46,0x53,0xc4,0x10,0x80,0x03,0xfa,0x63,0xa7,0x92,0x38,0x7c,0x62,0xbe,0x90,0xea,0x9d,0x0d,0x09,0x6e,0x08,0x34,0x61,0x41,0x7f,0xe7,0xaf,0x45,0x3f,0xa5,0xbf,0x7a,0xae,0xc0,0xa8,0xfc,0x64,0x4a,0x73,0x85,0x08,0xce,0xf3,0x7b,0xcc,0x0d,0xf8,0xa4,0xa0,0x9f,0x48,0x28,0x81,0xf9,0xe4,0xb5 +.byte 0xdd,0x6c,0x32,0xbb,0x1a,0x36,0xe6,0x78,0x8d,0x85,0x4a,0x8b,0xfb,0xf1,0x14,0xfe,0xde,0x15,0x92,0x8b,0xd6,0xee,0x73,0x43,0xc0,0x83,0x37,0xf2,0x0a,0xb7,0xc9,0x3b,0x25,0x2b,0x08,0x7a,0x54,0x49,0x21,0x5f,0xd4,0x78,0xc1,0x30,0x10,0x1c,0xad,0xfd,0xbd,0xb4,0xb1,0x6c,0xd8,0xd1,0x17,0x3e,0x61,0x2b,0x80,0x82,0x63,0x93,0x2d,0x0b +.byte 0x0e,0xcc,0xaf,0xa9,0xc3,0x2d,0xb7,0xc7,0x25,0x37,0x5f,0x3e,0x61,0x94,0xe1,0x2c,0xd3,0x31,0x84,0x9f,0x48,0x9c,0xb2,0x73,0x7d,0xd5,0x84,0xba,0xb8,0x1c,0xa4,0x88,0x4c,0x9e,0x14,0x89,0x09,0x25,0xf1,0x47,0xc1,0x20,0x45,0xfd,0x1a,0x1f,0x25,0x33,0xeb,0x9f,0xa8,0x17,0x93,0xd4,0x41,0x24,0xbd,0xd2,0x08,0x90,0x68,0xad,0x76,0x43 +.byte 0xa4,0xd9,0x35,0x68,0x0f,0x28,0xd4,0x2d,0x1e,0xcd,0x52,0x0d,0xf5,0x70,0x92,0x42,0x58,0xbb,0xa6,0xec,0xe9,0x71,0x04,0x66,0xf2,0x16,0x0d,0x3a,0xc0,0x6b,0x85,0x67,0x84,0x12,0x2d,0x02,0xa4,0x17,0x34,0x33,0x91,0x0b,0xa2,0x04,0x0c,0xe3,0xa4,0x80,0x5a,0x83,0xef,0x76,0xe7,0x9a,0xa8,0xa6,0xb8,0x41,0xe3,0x06,0xa7,0x9a,0xc7,0xe6 +.byte 0x56,0xa0,0x21,0x53,0x0c,0x5c,0x38,0xad,0xa2,0x87,0x3d,0x7d,0x38,0x50,0xe1,0x49,0xb7,0x56,0xf7,0xfc,0xc4,0x60,0x9e,0xb9,0x4a,0x68,0x18,0x1b,0x84,0xea,0x9a,0x30,0x01,0x53,0xf8,0xd3,0x25,0xb1,0xd0,0x3d,0x23,0x71,0x21,0x19,0xdf,0xe0,0xe4,0xdb,0xba,0xcc,0x92,0xe8,0x97,0x56,0xba,0x4f,0x63,0x77,0xaf,0xbb,0xe9,0x30,0x09,0x40 +.byte 0xbf,0x3c,0xf4,0xb6,0x0c,0x8b,0x1f,0x22,0x73,0x6e,0x49,0x1e,0x29,0x4f,0x92,0xa1,0x90,0xf7,0x2a,0x55,0xee,0xb3,0x36,0xe8,0x69,0x2c,0xc0,0x60,0xaa,0x1c,0xa6,0x84,0x0a,0x90,0xfa,0x5e,0x48,0x14,0x3a,0xf7,0x1e,0xe2,0x24,0xe7,0xae,0x2e,0x1f,0xdb,0xa6,0xc6,0xcb,0x6e,0x4b,0xae,0x88,0x4e,0x66,0xa9,0x96,0x23,0xa8,0xd7,0x94,0x3a +.byte 0xae,0xa5,0xdc,0xdd,0xfb,0xbd,0x1c,0xbf,0xa6,0xe0,0x29,0xe2,0xd1,0xa5,0x1b,0xd9,0x6d,0x38,0xd1,0x84,0x6f,0xf7,0x46,0x72,0xf0,0x89,0x72,0x4f,0x7f,0xb6,0xf3,0xf9,0x91,0x61,0x68,0x12,0x48,0xfb,0x1b,0x74,0xc7,0x7a,0x6b,0x4c,0x5d,0xbd,0x4b,0x89,0xfb,0x43,0xa7,0xd7,0xd0,0xc2,0x88,0x86,0x9b,0xcf,0x0e,0x94,0xc3,0x49,0x47,0x82 +.byte 0xd6,0x06,0x54,0xa4,0xb4,0x81,0xdb,0x07,0x38,0x5e,0x9e,0xc6,0x39,0x57,0x05,0x14,0x18,0xf9,0x68,0x6c,0x27,0x32,0xcf,0x90,0xd9,0xc8,0x7c,0xc4,0x1b,0xab,0xa8,0xc0,0x75,0x34,0x35,0x32,0xde,0x8e,0x20,0x09,0x6a,0x90,0x2a,0x67,0x86,0x61,0x08,0x9a,0x53,0xfc,0x6a,0x9a,0x0d,0x87,0x8b,0xa2,0xa3,0x72,0x6f,0xfa,0xc3,0xd0,0x9c,0x7a +.byte 0xc6,0x9e,0x1e,0xb4,0x2e,0xaf,0x4a,0x39,0x95,0x07,0x4f,0xbb,0xb4,0x52,0x7f,0xea,0x54,0x21,0x79,0x7e,0x2b,0x7a,0xea,0xec,0xcd,0xa5,0xdc,0xfd,0x8c,0x3c,0x9b,0x1d,0x7d,0x15,0x5b,0x05,0x95,0x7a,0x14,0xa8,0x3c,0xdd,0x91,0x0e,0x25,0xfc,0xa6,0x91,0xd8,0x2d,0xa5,0xf7,0xcc,0x26,0x77,0x2e,0x08,0xda,0x56,0xb9,0xc8,0x0e,0x78,0x79 +.byte 0xda,0x1d,0x56,0x41,0x1f,0x17,0x36,0x68,0x1c,0x16,0xcf,0x36,0xdf,0xb3,0x53,0xf9,0xf7,0x34,0x92,0x86,0x03,0xfe,0x67,0x8b,0x8b,0x4c,0xc3,0xfd,0xd0,0x44,0xce,0x91,0x57,0x3b,0x96,0x42,0x22,0xae,0xfc,0xf5,0xd7,0xcd,0x22,0x3e,0x91,0x05,0xf6,0x28,0xa7,0x6b,0xc7,0x0f,0xb8,0x67,0x26,0x84,0xa8,0x73,0x44,0xa5,0xd4,0x58,0x07,0x0a +.byte 0xcc,0xaa,0xd6,0x49,0xff,0x1a,0xce,0x30,0x14,0x62,0x9a,0xcc,0x6e,0x98,0xb5,0x6d,0xb4,0xa4,0x5d,0x71,0x10,0xd1,0x64,0x84,0x70,0x51,0xb5,0xe1,0xfc,0x78,0xe4,0x70,0x88,0x2a,0xcf,0x41,0xcc,0x45,0x34,0xa2,0xef,0x9b,0xf0,0x8b,0x27,0x11,0x81,0x89,0xee,0x5d,0x37,0x8e,0x6d,0xe3,0x72,0x89,0x65,0x23,0x88,0x97,0x03,0xab,0xb3,0x90 +.byte 0x76,0xf1,0x27,0x1b,0xa7,0xf0,0x5d,0xe4,0x83,0xda,0x4e,0x5b,0xbc,0x95,0xec,0x6f,0xdf,0x00,0xbf,0x2d,0xda,0xda,0x50,0x80,0xba,0xef,0x99,0x2b,0x6d,0xf7,0x61,0x01,0xcf,0xdb,0x9e,0x3d,0x65,0x22,0x03,0x5b,0x1d,0x0c,0x4a,0x08,0x83,0x78,0xd0,0x2b,0xe5,0x92,0x0d,0x53,0x50,0x0d,0xc0,0xdb,0x2d,0x8a,0x77,0xfe,0xb1,0x42,0x99,0xe1 +.byte 0xcb,0x1e,0x07,0x51,0x39,0x7e,0x75,0xa1,0xf2,0x73,0xea,0x0e,0x5e,0x1d,0xe9,0x60,0xc1,0x18,0xe7,0x5f,0xc6,0x37,0x49,0xb0,0xd5,0xc0,0xfb,0x0b,0xbd,0xa7,0x0f,0xe1,0x07,0xea,0x99,0xad,0x98,0xee,0xa1,0xa3,0xfd,0x4b,0x94,0x35,0xd3,0xe9,0x16,0xbf,0xf3,0x91,0x80,0xc2,0x9b,0x22,0xdc,0x47,0xef,0xad,0x15,0x12,0x2c,0x3d,0x5d,0x04 +.byte 0x7a,0xcc,0x43,0xf1,0xe6,0xb8,0x1a,0xe8,0xc1,0x81,0x1d,0x84,0x3a,0x42,0x92,0xc3,0xb6,0x76,0x07,0x89,0x2b,0x78,0xd0,0x0e,0xca,0xef,0xaa,0x7d,0xd1,0xe8,0x66,0xed,0xbf,0x5c,0x5e,0x2d,0x8d,0x3e,0xc2,0xbb,0xb9,0x53,0x27,0x98,0x0b,0xa1,0x5d,0x9e,0x7d,0x65,0x25,0x1f,0x3c,0xb1,0x37,0x6c,0xde,0x5e,0x02,0xbe,0x75,0x26,0x5b,0x2a +.byte 0x25,0x21,0xa1,0x4f,0x95,0xda,0x29,0x61,0x1c,0xff,0x2b,0xc5,0xdc,0x2d,0x8f,0x54,0x4b,0x19,0x06,0x0c,0xb6,0x6c,0xe7,0xd4,0xc3,0x4b,0xa5,0xf5,0xc3,0xe2,0x42,0x90,0x36,0x61,0xb1,0x57,0x19,0xb7,0xca,0x7d,0xcb,0x31,0xbe,0x8d,0xb7,0x5a,0x9d,0x81,0xf2,0xf0,0x18,0x45,0xc8,0xcb,0x3c,0x71,0x42,0xe5,0x6a,0xfe,0x00,0x9f,0x4d,0x59 +.byte 0x32,0xaa,0x0b,0x2c,0xed,0x1c,0xfe,0xe7,0xbd,0xce,0xc3,0x2c,0xb2,0x3e,0xdf,0xb3,0x0e,0x96,0xbe,0xe9,0xd1,0xf0,0xe2,0x31,0xf6,0xeb,0xa9,0x7b,0x32,0xbe,0x42,0x55,0xf3,0x80,0x71,0xfb,0x1f,0x6e,0x5f,0xd3,0xc8,0xdf,0x64,0x7b,0x3e,0xf2,0x00,0x60,0x7f,0x49,0x5a,0x97,0xa9,0xf1,0x8f,0x82,0x6d,0x33,0xbf,0x2f,0x34,0xc7,0xbe,0x24 +.byte 0x27,0xe8,0xe2,0x88,0xfb,0x3b,0xe3,0xaa,0x86,0x90,0x8d,0x69,0x0e,0xb4,0x83,0xea,0xdc,0xc8,0xce,0x8c,0x53,0xb0,0xcc,0xcc,0x2a,0xe6,0xb0,0xee,0xde,0xe6,0x0c,0x7f,0xce,0x73,0x6f,0xa9,0xa2,0x3e,0xf6,0x66,0xc5,0x83,0xfe,0xa1,0xab,0x80,0x90,0xd5,0x58,0x98,0x22,0xb0,0x4c,0x21,0x27,0xb7,0x19,0x68,0xa7,0x18,0x6b,0xb4,0x82,0x76 +.byte 0xff,0xb1,0xb1,0xa5,0x14,0x06,0x5b,0xfe,0xe4,0xd2,0xb8,0x4f,0x21,0x2a,0x74,0x17,0x01,0x78,0x74,0xf3,0x2a,0xa0,0xec,0x36,0x5c,0x9e,0xae,0x7f,0x27,0x2f,0x79,0xb1,0x2a,0x70,0x27,0x82,0xdf,0xf1,0x52,0x00,0xfe,0xce,0x04,0x47,0xda,0x8e,0x2c,0xa4,0x71,0x65,0x54,0xb3,0x81,0xbd,0x0f,0x9f,0x6b,0x5a,0x0e,0x91,0xb3,0x07,0x36,0x65 +.byte 0x86,0x75,0x75,0xfb,0x96,0x10,0x8f,0xd7,0x96,0xf5,0x0d,0xa7,0x4d,0x41,0x0c,0x8f,0x28,0xbc,0xda,0xf9,0xe7,0x41,0xcd,0xfd,0xb9,0x2c,0x44,0x13,0xe4,0xde,0xa6,0xd4,0x5e,0x4c,0x17,0xfa,0x0e,0x11,0x45,0xf4,0xbb,0xad,0x58,0x0d,0xec,0x2f,0xf8,0x14,0xca,0x18,0x2d,0x04,0x38,0xdf,0x1c,0x47,0x63,0xa4,0x31,0xb9,0x18,0xf7,0x79,0xee +.byte 0x15,0x4a,0xd1,0x6e,0x61,0xe7,0x05,0x5d,0x0e,0x99,0xa5,0x7d,0xfe,0x67,0x29,0x21,0x2b,0x07,0xaa,0xed,0xf0,0x54,0x37,0x79,0x5b,0xe7,0x38,0x21,0x0b,0x29,0x6e,0x34,0xe4,0xdb,0xe9,0xe3,0x6e,0xea,0x34,0x6a,0xbb,0x39,0x2a,0x5d,0x34,0x7b,0xee,0x5d,0x68,0x62,0x34,0x66,0xcf,0x3f,0x1c,0x61,0x94,0x7b,0x69,0x71,0x92,0x23,0x6e,0xc9 +.byte 0xec,0x34,0xe4,0xb4,0xa3,0xc4,0x3c,0x62,0x4f,0x4c,0xc8,0x5e,0xb1,0x9c,0xcc,0x0d,0x6b,0x62,0x55,0x1b,0xdd,0xa9,0xa2,0x0a,0x69,0x79,0x1d,0x2d,0x4e,0xf1,0xb3,0xbb,0x50,0x9e,0x48,0xf2,0x71,0x1e,0x09,0x63,0x57,0x54,0xc6,0xa9,0x9f,0x1f,0xe8,0x21,0x96,0xd3,0x37,0x09,0xae,0x68,0xe9,0xd7,0x4f,0xf4,0x8c,0x49,0x13,0xb1,0x56,0x4a +.byte 0x36,0x43,0x5e,0x19,0xf5,0x7a,0x2a,0xe9,0xcf,0x3e,0x01,0x44,0xb1,0xa4,0xb2,0x77,0xf5,0x53,0x00,0xe3,0x51,0x57,0x63,0x48,0xba,0xb6,0x0f,0xbd,0xec,0x2b,0xaa,0xf5,0x52,0xa1,0xd2,0x0e,0x37,0x06,0x9e,0x6e,0x06,0xb0,0x65,0x56,0x5b,0x97,0x4f,0x2b,0x87,0xd9,0x0c,0x98,0x7a,0x3c,0x1b,0xd7,0x04,0xd5,0x68,0x60,0x46,0x1b,0x0c,0x9d +.byte 0x4d,0x41,0x9d,0xff,0x80,0xf3,0xb2,0x3b,0x2e,0xb0,0x1f,0x92,0x85,0x65,0xb1,0xcf,0x5c,0xa2,0xa5,0x0b,0x83,0xa1,0x1b,0xbd,0xd2,0x8e,0x8a,0x33,0x9d,0xb4,0x06,0x62,0x24,0x49,0x4e,0x00,0x8a,0xa4,0x9a,0x2c,0x84,0x3f,0xe4,0x03,0x3d,0xf2,0x30,0x90,0x1c,0x37,0x38,0xf8,0xd4,0x04,0xd2,0xdf,0x69,0xd0,0xb5,0xda,0xbc,0x41,0x38,0xe0 +.byte 0xaf,0x32,0x87,0xe1,0x98,0x21,0xb7,0x1b,0x3b,0x2b,0x3e,0x92,0x74,0xe8,0x44,0xdb,0x5c,0x39,0x9a,0x5c,0x71,0x60,0x48,0x95,0x5c,0x47,0xa4,0xa8,0x12,0x3b,0xbf,0x75,0x22,0x0a,0xf1,0x73,0x42,0xbc,0x8a,0x54,0x19,0x04,0xad,0x7a,0xbc,0x9c,0x35,0x53,0x52,0x4b,0x13,0x94,0x5c,0xe7,0x10,0x12,0x49,0xa8,0xb3,0x85,0x02,0x09,0x25,0xcd +.byte 0xd1,0xdc,0xb5,0xe0,0xab,0x93,0x8c,0xf1,0x78,0xac,0x6c,0xa8,0x72,0x12,0x16,0x80,0x4d,0x76,0xcb,0x04,0xba,0x50,0x3a,0xf5,0x8f,0x5f,0x82,0xa8,0x83,0x6f,0x16,0xd2,0x85,0x67,0xe2,0x81,0xc7,0x5d,0x82,0x2c,0xea,0x6a,0xd7,0xc4,0xaf,0x9b,0x22,0x21,0x05,0x29,0x92,0xd7,0xe6,0x60,0xc6,0xdc,0x4c,0x15,0xde,0x46,0x4a,0xda,0xe3,0x4a +.byte 0x7d,0x9f,0x7d,0x45,0x51,0x81,0xa3,0x78,0xfc,0x34,0x91,0x93,0xae,0xa9,0xb0,0x34,0x56,0x12,0x8c,0xec,0xe7,0x75,0x14,0x43,0xa5,0x0d,0xe4,0x91,0x3c,0xbb,0x64,0xb8,0x3d,0xd3,0xf9,0x55,0x5f,0x1f,0x30,0x3e,0xf8,0x84,0x8f,0xa3,0x5c,0x91,0xaa,0xa4,0x1a,0x16,0xef,0xcf,0x45,0xd4,0xa0,0xf6,0x56,0x9d,0xd2,0x88,0x50,0x0e,0x40,0xa5 +.byte 0xde,0xbe,0x80,0x83,0x71,0xfc,0xfe,0xc7,0xe5,0xf7,0xda,0x51,0x86,0xc3,0xde,0xeb,0x54,0x17,0x7e,0xf6,0x20,0xd4,0x80,0xed,0xc0,0xc4,0x67,0xb5,0x26,0x03,0x98,0x26,0xa2,0xd2,0x0c,0x0a,0xf3,0xb0,0x65,0xd7,0x7e,0x26,0xf0,0x74,0x75,0xff,0x9e,0xfd,0x6f,0x1b,0xd2,0x49,0x4b,0x79,0xf7,0xb2,0x5d,0x02,0xfa,0x17,0x51,0x5e,0xc7,0x5e +.byte 0xf8,0x0e,0x99,0xc4,0x94,0x42,0x37,0x74,0x74,0xa6,0x04,0x4e,0xe1,0x1c,0x2a,0x79,0x1f,0x0a,0xba,0xd8,0x24,0xe2,0xed,0x65,0x33,0xdb,0xb6,0x2d,0x1d,0x30,0xec,0x18,0x7c,0x8f,0x82,0xf1,0xad,0x30,0x97,0xc5,0x9e,0xd8,0xa6,0x64,0x5f,0xcd,0xaa,0xd7,0xce,0xd0,0xd5,0x32,0xb6,0x4e,0xe0,0xe0,0xdd,0x03,0x04,0x63,0x76,0x83,0xda,0x4b +.byte 0x63,0x28,0x73,0x63,0x02,0x76,0x02,0xde,0x96,0x6a,0xea,0x21,0x00,0x25,0x5a,0xc8,0x52,0x0a,0xcb,0x5e,0x76,0xe9,0xd8,0x61,0xd3,0xda,0xdd,0x36,0x9c,0xa1,0x8e,0xf2,0x8d,0xc8,0xa1,0xe9,0xa2,0x1d,0xd3,0x53,0xb5,0x43,0x39,0x59,0x7e,0x12,0xd5,0x51,0x3b,0x71,0x66,0x6e,0x0d,0x6a,0x68,0x56,0x47,0x9c,0x95,0x7f,0xeb,0xff,0xf3,0x3f +.byte 0x88,0x13,0x36,0x43,0xff,0x56,0xc3,0x28,0xa8,0x10,0x70,0xd3,0x04,0x8a,0x45,0xb7,0xe4,0x71,0x79,0xa1,0x20,0x70,0xab,0x7c,0xc1,0x20,0xb7,0xaf,0x67,0x86,0x6f,0x1d,0x2e,0x84,0xca,0x68,0x97,0x42,0xa1,0x9b,0x1c,0x10,0xbd,0x76,0xed,0x54,0x46,0x50,0x13,0xa9,0x2d,0x43,0x43,0x82,0x84,0x2c,0xee,0x8f,0x42,0x2f,0x75,0xe1,0x37,0x46 +.byte 0xaa,0x6d,0xc4,0x03,0xb6,0x6c,0xd2,0xe7,0x3a,0x45,0x5d,0xe8,0x2e,0x99,0x11,0x7d,0x61,0x8f,0x10,0x37,0x45,0x49,0x29,0xa7,0x28,0xca,0x78,0x53,0xab,0xed,0x70,0xfa,0xd9,0x1b,0xf4,0x08,0x96,0x77,0xd8,0xd9,0xdb,0x03,0xff,0x9e,0xe3,0xd1,0x03,0xc3,0xd5,0x54,0xac,0x11,0xfc,0xd0,0x7c,0x9a,0x11,0x1d,0xc9,0xbc,0x7f,0xfd,0x2d,0xb6 +.byte 0x8e,0x2a,0xc7,0x35,0xde,0x5a,0x2c,0x4f,0xcd,0x29,0xb0,0x8b,0x06,0xd2,0xa7,0x20,0xc5,0x27,0xe8,0x2a,0x93,0x70,0x40,0x01,0xaa,0x9b,0x71,0x93,0x98,0xcb,0xc6,0xe1,0x2e,0x0e,0xc6,0x4c,0x4f,0xb5,0x7d,0x26,0x39,0x99,0x8d,0x9d,0x91,0x26,0xf2,0x6a,0xb9,0x8c,0x92,0x63,0x26,0x4b,0xd4,0x3b,0xf6,0xba,0x17,0x9c,0xc6,0x8c,0x60,0x52 +.byte 0x16,0x5a,0xcd,0xc4,0xdb,0x5c,0x17,0xf6,0x7a,0x32,0x3e,0x13,0x88,0x5d,0x2c,0x26,0x13,0x08,0x5e,0x51,0x8d,0x20,0x88,0xbf,0x70,0x4a,0x9a,0x56,0xff,0xf6,0x25,0x59,0x58,0xaa,0x7e,0xa5,0xc7,0x2c,0x89,0x3e,0x30,0x93,0x3b,0x6c,0x02,0x6e,0xe3,0x84,0xe4,0x05,0xc6,0x69,0x84,0xcb,0xe0,0x67,0x77,0xf3,0x4d,0x8e,0xfa,0x02,0xae,0xa7 +.byte 0x7c,0x75,0x5b,0xdf,0xdc,0x01,0xbe,0x70,0xfa,0x47,0x80,0x64,0x3b,0xd6,0x0c,0x6a,0x7f,0x8f,0xff,0x52,0x11,0x90,0x0b,0x40,0x78,0xf6,0xa5,0xa0,0x4e,0xcd,0xc2,0x0d,0x2f,0xb8,0x3c,0x3c,0xc3,0x15,0xf2,0xa3,0x5f,0xf3,0x40,0x96,0x6f,0x89,0x91,0x32,0xbe,0x0e,0x63,0x4f,0xea,0xa2,0xc0,0x5d,0x30,0xb9,0x6d,0x21,0xeb,0x34,0xe4,0x65 +.byte 0x64,0xa4,0xd5,0x29,0x68,0xa6,0x17,0x00,0x82,0x5c,0x65,0xf0,0xeb,0x74,0xa1,0x9b,0xdd,0x1a,0xf4,0xd8,0x00,0x1b,0xb0,0x0d,0xc7,0xe4,0x23,0x62,0xf6,0x81,0x9f,0xd8,0x81,0x3f,0xd8,0x0b,0xca,0x2e,0xd4,0x3c,0x10,0x44,0x14,0x66,0x1e,0xbc,0x1c,0xc8,0x0e,0xd5,0x0c,0x22,0x18,0xd1,0xec,0xf8,0x87,0x55,0x89,0x53,0x2a,0xf0,0x66,0xca +.byte 0x88,0x98,0x9c,0x1e,0xa8,0x56,0x2e,0x5e,0x24,0xd2,0xd8,0x8d,0x6e,0x0c,0x81,0x55,0xf0,0x8d,0xa5,0x8c,0x3a,0x27,0xbc,0x2e,0xab,0xdd,0x6e,0x55,0xce,0xd7,0x9a,0x6b,0x2b,0x03,0x18,0x6b,0xf7,0x78,0x79,0x6c,0x64,0xb1,0xaa,0xff,0xd4,0x34,0xac,0x61,0xfd,0x51,0x03,0x41,0xd8,0x4b,0xad,0xd7,0xd2,0xfc,0x17,0x91,0xd0,0x90,0x15,0xd3 +.byte 0xcf,0x3f,0x55,0x3d,0x8c,0x70,0x7a,0xda,0x0c,0x04,0x0a,0x29,0x5c,0x08,0x56,0xa8,0x60,0xea,0xd1,0xe7,0xff,0x53,0xc7,0x27,0xe3,0x21,0xe9,0xdc,0xb7,0x6c,0xc1,0x6a,0x4c,0x62,0xb2,0x67,0x79,0x24,0x8f,0x7d,0x96,0xd6,0x4c,0xa7,0x54,0xbe,0x07,0x85,0x53,0x9f,0xc9,0xbd,0x99,0x98,0x13,0x2a,0x49,0xcc,0xe5,0x70,0x56,0x90,0xbe,0xd3 +.byte 0xd5,0x17,0x44,0x2e,0x11,0x3e,0x96,0x0b,0xc1,0x66,0x0d,0x36,0x2d,0x28,0x68,0xbd,0x8c,0x46,0x71,0x39,0x8f,0xd5,0xe3,0xd1,0x74,0xde,0x85,0x26,0x3c,0x8e,0xde,0x79,0xbe,0xf4,0x20,0xfc,0x3c,0x8b,0x73,0x0d,0x82,0xc0,0xa8,0x48,0x9f,0x4e,0x9f,0xb8,0xcd,0xc2,0x70,0xa7,0x54,0xe5,0x22,0x86,0x3a,0xf1,0xf0,0xbc,0x8b,0x74,0xea,0x9e +.byte 0x45,0xbd,0xa5,0x54,0xc5,0x75,0x30,0xfa,0x5e,0x05,0x4b,0xc2,0xe3,0x09,0x4b,0x3d,0xfb,0x84,0x0c,0x96,0x36,0x2b,0xbf,0xcc,0xe2,0x15,0x39,0x6f,0xc8,0x91,0x56,0x0b,0xf8,0x4b,0x1b,0x61,0xa4,0x68,0xc0,0x06,0xaa,0xa9,0xef,0xea,0x69,0xdb,0xda,0x6a,0x50,0xa9,0x5a,0xb4,0x9b,0xf5,0xf0,0xbe,0x2f,0x34,0x20,0x96,0x84,0x70,0x0d,0xfe +.byte 0x00,0x16,0x77,0x45,0x5b,0xf4,0x29,0xf1,0x41,0xb5,0x71,0x3e,0x91,0x5d,0x96,0x21,0xb4,0xb2,0x61,0x23,0x96,0xcd,0x28,0xaf,0x23,0xf0,0x45,0xc7,0xaf,0xd3,0x9e,0xb4,0x29,0xd7,0x68,0x5b,0x01,0xaa,0x5f,0x06,0x78,0x61,0xc4,0x61,0x49,0x01,0x0a,0xcc,0x2d,0xe1,0x03,0x27,0x07,0x11,0x9b,0x46,0x7b,0x8f,0xe0,0xfd,0xd6,0x72,0x14,0x1e +.byte 0x0f,0xd0,0xbc,0x5d,0xd7,0xb5,0x86,0x86,0xd3,0x02,0xcc,0xd4,0x2a,0xaa,0x47,0x01,0x82,0x97,0x07,0x9b,0x11,0xb3,0xba,0x8d,0x40,0x6d,0x0b,0x71,0xe1,0xa0,0xd2,0x27,0x4c,0x04,0x4f,0x33,0x4b,0xe3,0xc4,0xb6,0x60,0x8d,0x0c,0x9b,0xbc,0xfb,0x21,0x8c,0x7a,0x59,0xf1,0xf5,0xfc,0x84,0x4c,0x98,0x97,0x36,0x6d,0x38,0x1c,0x2a,0x39,0x9d +.byte 0x0c,0x0c,0x4d,0xf1,0xba,0x24,0x3f,0x05,0x3b,0x9e,0x39,0xc4,0xd2,0xec,0xbe,0x31,0x6a,0x6b,0xc6,0xff,0xe8,0x75,0x1a,0xad,0x2f,0xbd,0xa5,0xf6,0x4b,0xbd,0xb9,0x26,0x89,0xb0,0x99,0x47,0xb9,0x10,0xcf,0x20,0x4a,0xfb,0xa4,0xeb,0x9d,0xbe,0x90,0x15,0xed,0xba,0x43,0xf3,0xcc,0x2e,0x68,0x09,0x39,0xb3,0x53,0xc6,0xac,0xe5,0x5c,0x97 +.byte 0x75,0x95,0x4d,0x49,0x84,0x2c,0x00,0xfc,0x1d,0x58,0x61,0x88,0x3c,0x0c,0x84,0x5d,0x60,0x6d,0x86,0x6c,0x2c,0x49,0xcc,0x6a,0xee,0xc3,0xb3,0x23,0x85,0xba,0x55,0x56,0x95,0x43,0x7b,0x74,0x22,0x9f,0x7c,0x91,0x2b,0xf6,0xeb,0x4c,0xc6,0x47,0x69,0x4a,0x41,0x80,0xee,0x81,0x8f,0xe8,0xd5,0x80,0x6c,0x0b,0x1b,0x0c,0x22,0x60,0x60,0x05 +.byte 0x0a,0x9f,0x53,0x6f,0xca,0xcf,0x82,0xf7,0xd4,0x3d,0x44,0x66,0x7a,0x99,0x34,0xf1,0xf2,0xec,0xfe,0x08,0x2d,0x24,0x5f,0x32,0x45,0xb9,0x43,0x97,0x58,0xf4,0x8d,0x15,0xaf,0x27,0x19,0xc4,0xdb,0x73,0xfe,0xee,0x87,0x02,0xb3,0xeb,0xb2,0x9f,0x8d,0x1b,0x13,0xaa,0x19,0xbf,0x76,0x8b,0x3f,0xce,0xea,0x84,0xe9,0xc0,0x59,0x02,0x03,0xc0 +.byte 0x88,0x54,0xa2,0x3e,0x90,0x45,0xcb,0x13,0xc3,0x8f,0x57,0xd7,0x29,0xd0,0xee,0x5e,0xe6,0xe2,0x76,0xf3,0xb3,0xd0,0x6c,0x98,0x80,0x8e,0x39,0xfb,0xd8,0x2b,0x6c,0x1a,0xab,0xba,0xb1,0x32,0x2a,0x9b,0xdd,0x30,0x6c,0xd9,0xb6,0xb7,0x75,0x90,0x05,0x7b,0x93,0xec,0x62,0x2b,0x90,0xd1,0xf4,0xc6,0x35,0x92,0x07,0x5b,0x45,0x9b,0x79,0x74 +.byte 0x64,0xb0,0x25,0x1f,0xd1,0x38,0x76,0x39,0xa0,0x59,0x9d,0x22,0x97,0x73,0x24,0x86,0x55,0xbf,0xbc,0x4c,0x15,0xb3,0xb7,0x77,0x14,0x03,0x15,0x60,0xea,0xaf,0x72,0x84,0xbf,0x38,0x3c,0x6d,0xe0,0xa9,0xc7,0x3e,0xef,0xf4,0x44,0x43,0x5e,0xda,0x2a,0x1d,0x3d,0xc9,0x1d,0xf0,0xb6,0xb0,0x6b,0x11,0x50,0xa6,0x2d,0xed,0x75,0xd3,0x50,0xd5 +.byte 0x7a,0xe5,0x96,0xf4,0x65,0x55,0x5a,0x89,0x69,0xf8,0xb8,0xa5,0x6f,0x68,0x7f,0xdf,0x1e,0x25,0xc7,0xe3,0xbe,0x50,0x5e,0x45,0x78,0x58,0xff,0xf5,0x45,0x6e,0xa5,0x10,0xfc,0xdc,0x0f,0x84,0x92,0x00,0xc2,0x01,0x50,0x66,0xfd,0x5c,0xfc,0x87,0xf9,0x80,0xfa,0x01,0xc1,0xc5,0x2e,0x5e,0xaf,0xbe,0xce,0xf2,0x11,0x7c,0xf2,0x67,0x10,0xf3 +.byte 0xcc,0x16,0x0c,0xd8,0xe0,0xdf,0x68,0x37,0xef,0x50,0xba,0x16,0x72,0x79,0x9f,0xa7,0xb5,0x82,0x7f,0x6b,0x36,0x47,0x56,0x9d,0xbd,0xb6,0xc9,0xcf,0x79,0x11,0x0a,0x27,0xaa,0x3a,0x1c,0x58,0xc7,0x69,0x23,0xf1,0xcc,0xeb,0xea,0x15,0x7b,0xb5,0x75,0x32,0xb8,0x7f,0x65,0x74,0xca,0x1e,0x92,0x29,0x5a,0x24,0x4f,0xdd,0x8d,0x69,0x89,0xa6 +.byte 0x83,0x75,0xa3,0x92,0x5c,0xba,0xa3,0x19,0xde,0x2c,0x8f,0xbd,0x97,0x80,0x2f,0xd7,0x57,0xde,0x95,0x0f,0x21,0x72,0xf8,0xe7,0xcf,0xc8,0xbc,0x3c,0x9d,0x8e,0xfb,0x34,0x41,0xee,0xe9,0x34,0x5b,0x25,0x48,0x3e,0x1b,0x64,0xd0,0x1a,0x6c,0x13,0xe3,0x69,0x49,0x51,0x97,0x81,0x62,0xef,0xa1,0xd9,0xef,0x7b,0xd6,0xc2,0x63,0x25,0x6c,0x50 +.byte 0x8e,0xd0,0xfe,0x07,0xe6,0xc3,0xbc,0x47,0x6b,0x3d,0x20,0x3a,0x83,0x40,0x90,0x53,0xfb,0xa5,0x9a,0x36,0x1d,0x5d,0xbf,0xf7,0x60,0x27,0xef,0x59,0xd4,0x3c,0xbf,0xb0,0x22,0x15,0xea,0x9e,0xa4,0x59,0x9d,0x74,0x52,0x21,0xe0,0x37,0xda,0x2d,0x66,0xa3,0x9d,0x8e,0x9d,0x45,0xb3,0x2f,0x0a,0x60,0x0b,0xfa,0x09,0x8f,0x3f,0x33,0xc9,0xe3 +.byte 0x54,0xfd,0xa2,0x7f,0x58,0xf9,0xcd,0xbf,0xa2,0xd6,0xe0,0x37,0x62,0x5d,0x0c,0xb5,0xf2,0x0a,0x2a,0xa3,0x29,0x96,0xb5,0x96,0x6b,0xba,0x53,0x3d,0xd4,0x11,0xe9,0x43,0x6b,0x44,0x43,0x9f,0xea,0x52,0x92,0xa4,0x13,0x91,0xc1,0x77,0xc3,0x31,0x25,0xe2,0xb5,0x53,0x82,0x7e,0x35,0x58,0x36,0x03,0x61,0x69,0xba,0x27,0x2b,0x65,0x42,0x40 +.byte 0x4e,0xd7,0xc2,0x90,0xad,0x52,0x0b,0x66,0x07,0xb1,0x5f,0x07,0x4a,0x67,0x4a,0x61,0x90,0xbd,0x50,0x39,0xf8,0x11,0x59,0xc3,0x41,0xfb,0x1a,0x7f,0xcb,0xf7,0x99,0xc2,0x27,0x33,0x28,0x37,0xa1,0xff,0x1b,0x23,0x46,0x96,0xc1,0x4e,0x03,0x41,0x77,0x27,0xa7,0x68,0x60,0xaf,0xb8,0x7a,0x80,0xb9,0xc2,0xa6,0x9e,0x61,0xa5,0x90,0xa1,0x6a +.byte 0xe3,0xb1,0xd1,0x28,0x9f,0x9f,0xf7,0xf7,0xc9,0xff,0x02,0x82,0xdc,0x81,0x96,0x3a,0x61,0xf4,0x37,0x91,0xc2,0x58,0x48,0x54,0xaf,0xd6,0x0c,0x2d,0x2e,0xbd,0xe9,0x13,0x07,0xf7,0xc5,0x71,0xe9,0xa9,0x9d,0x93,0xa4,0x61,0x29,0x10,0x29,0xfb,0x79,0x9e,0x2c,0x1a,0x3e,0xae,0x7d,0x0e,0xcf,0x52,0xaa,0xdc,0xf2,0xeb,0x5c,0xcc,0x9e,0x42 +.byte 0xcf,0x2f,0xf1,0xe8,0x91,0x6a,0x07,0x15,0xb8,0x78,0x6e,0x42,0xd5,0x5f,0x3e,0x53,0x70,0xd6,0x93,0xd4,0xc0,0x43,0x25,0x49,0x54,0xb0,0x13,0xa1,0xc1,0x68,0xdb,0xa6,0xdc,0xf4,0xa6,0x7c,0x8a,0x1c,0xc8,0xaf,0x34,0xc5,0x9f,0x30,0x7a,0xe9,0x4c,0xc9,0x27,0x41,0x7c,0xa5,0xd3,0x7f,0xee,0x17,0x9a,0x3b,0x82,0x15,0xef,0x85,0x3d,0x2b +.byte 0xba,0xc7,0xb8,0x8c,0x13,0xf6,0x0d,0x53,0x33,0x04,0x0a,0x6b,0x8c,0xe5,0xf3,0xc5,0x5f,0xf6,0x7b,0xdb,0x6d,0xa4,0x63,0xef,0xe3,0xcd,0x32,0xb2,0x11,0xab,0x0a,0x01,0x9b,0xc7,0x95,0x51,0x3d,0x34,0x25,0x51,0x2a,0x63,0x73,0x99,0xa7,0x62,0x6d,0x71,0x23,0x83,0xd5,0x25,0x02,0x96,0x26,0xbb,0x25,0x35,0xb9,0x20,0xb3,0x25,0x84,0x07 +.byte 0x39,0x9c,0x45,0x67,0xfb,0x89,0x61,0x38,0xb5,0xdf,0x0a,0x9d,0x9f,0xad,0x2f,0x80,0xe2,0x9c,0x6b,0x88,0x84,0xf3,0xea,0xbd,0x75,0x00,0x71,0x21,0x41,0xfe,0xdc,0x2c,0x7b,0xb1,0x3c,0x40,0x99,0xc3,0xf9,0x2b,0xab,0x40,0xf9,0x2e,0x3a,0x65,0x58,0xe5,0x42,0x30,0x5c,0x05,0xf4,0x89,0x2b,0x72,0x54,0x7c,0xce,0x1a,0xa7,0xd4,0xf0,0xc2 +.byte 0x05,0x63,0x1a,0x67,0x31,0xb3,0x55,0xdc,0x9f,0x07,0x99,0xa3,0xed,0x84,0x53,0x94,0x7c,0x5f,0x63,0x1d,0xdb,0x51,0xfa,0x92,0xc4,0x5d,0xb7,0x96,0xef,0x26,0x2a,0x09,0x8b,0x5a,0xa5,0xca,0x63,0x41,0x33,0x9e,0xd1,0x00,0x5e,0xaf,0x71,0xfe,0x3a,0x97,0xa4,0xaf,0xe8,0xae,0xce,0xfa,0x82,0x90,0x39,0x00,0x6f,0xd6,0xc4,0x54,0x84,0xf9 +.byte 0x0f,0x96,0xfc,0xe8,0x6e,0xce,0xc4,0x55,0xdf,0xcd,0xd3,0xfa,0x65,0xcd,0xc4,0x42,0xe3,0x9f,0xab,0xbd,0xcf,0xc7,0xd3,0xe2,0xa8,0xc4,0xc5,0x06,0xc2,0xf5,0xe7,0x86,0xa4,0xd0,0x7e,0xf6,0x1c,0xd0,0x3c,0x4d,0x15,0x30,0x50,0x43,0x02,0xce,0xd2,0xf1,0xc4,0x28,0xe6,0x54,0xfc,0x21,0x6a,0xd5,0xdd,0xc3,0x39,0xf8,0x57,0x79,0x36,0xec +.byte 0x11,0x24,0x30,0xa6,0xcb,0xa7,0xa4,0x18,0x2e,0x71,0xe5,0x2e,0x31,0xf0,0x0b,0xd1,0xa4,0x77,0x4d,0xbf,0x9f,0x8d,0xb6,0x53,0x49,0x62,0xb0,0xba,0x29,0xde,0xb9,0xc6,0xdd,0x62,0x09,0x0e,0x1e,0xe2,0x78,0xd1,0x3e,0xef,0x9d,0x5d,0x91,0xf1,0x1a,0xd9,0xb8,0x81,0x4b,0x3c,0xfd,0xe9,0x54,0x4a,0x80,0xc9,0x7c,0x37,0xde,0xca,0x92,0xe2 +.byte 0x0c,0x66,0xa5,0xfc,0xf1,0xe4,0x9c,0xb3,0xdb,0x15,0x11,0xb4,0xc2,0x21,0x5a,0x4e,0xb1,0x54,0xd1,0x0d,0x78,0x9c,0xaa,0xc2,0x8d,0x10,0xf7,0x24,0x3a,0xb7,0xef,0x2b,0x5b,0x1e,0xa6,0x13,0xcd,0xa9,0x06,0x48,0x98,0x80,0x61,0x67,0xca,0xef,0x76,0x10,0x83,0xe8,0x98,0x43,0xe2,0xa6,0x00,0x5a,0x3c,0xde,0x19,0x6a,0x71,0x21,0x16,0x8d +.byte 0x76,0xe7,0xa1,0x82,0x8b,0xb9,0x21,0x93,0x97,0xbd,0xe2,0xac,0xb9,0xa3,0x57,0x97,0x2a,0xcb,0x27,0xcc,0xcb,0x74,0x87,0xa2,0xa1,0x37,0x63,0xda,0xec,0x64,0x9c,0x56,0x62,0x8f,0xc9,0x5f,0xd3,0x26,0x4b,0xae,0x90,0xc1,0x1a,0xda,0x3c,0x59,0xf1,0xc0,0x47,0xf1,0xa3,0xba,0xd0,0xd5,0x30,0x97,0x3f,0xfc,0x2c,0x88,0x14,0x05,0x34,0x56 +.byte 0x8c,0x61,0x21,0xce,0x71,0xb5,0x60,0x62,0x1d,0x68,0x63,0x07,0x3a,0xee,0xf4,0x19,0x6c,0x59,0xdc,0xb8,0x0e,0x67,0xc0,0x74,0x58,0x13,0xe0,0x18,0xb1,0xf0,0x54,0x5c,0x83,0xdf,0xff,0x65,0x6c,0xa6,0xf7,0xff,0xc1,0x50,0x47,0x87,0xf0,0xea,0xa5,0x76,0x19,0x70,0x91,0xaa,0xc0,0x87,0x0f,0x31,0xbb,0xd6,0x7b,0x52,0xb2,0xd6,0x49,0xc1 +.byte 0x41,0xdd,0xec,0x9a,0x41,0x22,0xf6,0xc5,0x80,0x80,0xbb,0x2f,0xb9,0x45,0xbd,0x6e,0xef,0x14,0x48,0x96,0xfa,0x9c,0x87,0xb2,0x0b,0x68,0xbf,0xcb,0xe3,0xe3,0x97,0x13,0xf9,0x43,0x66,0x65,0xad,0x18,0x60,0x96,0xc5,0x70,0x91,0x29,0x0d,0x91,0x8c,0xcb,0xcb,0x03,0x6c,0xd2,0xfa,0xf6,0x96,0x19,0x18,0x20,0x15,0x8e,0x77,0x9b,0x74,0xa5 +.byte 0x3d,0x6e,0x76,0xc6,0x3c,0x8f,0x6f,0x72,0xe2,0x8b,0xcd,0xa6,0x17,0x26,0x00,0x36,0xac,0x91,0x19,0x1e,0x5c,0x17,0x55,0x6f,0xde,0x0c,0x31,0xe4,0xec,0xd1,0x90,0x1d,0xea,0xea,0x77,0x2f,0x8a,0xee,0x44,0xea,0x39,0xeb,0x00,0x1d,0xde,0xa6,0x37,0x40,0x3d,0x97,0xd2,0x88,0x0e,0xbc,0xbd,0x2c,0xef,0xda,0x3c,0x2e,0x8e,0x0d,0xf3,0xfc +.byte 0x88,0xcb,0x34,0x89,0x3f,0x86,0xec,0xfe,0xf0,0xcd,0x0b,0x80,0xd4,0x02,0xdb,0xd6,0x06,0xf3,0xbe,0x52,0x9a,0xf0,0x1b,0xe7,0x36,0x7d,0xcc,0x84,0xf5,0x02,0x11,0xf6,0xdf,0xb6,0x67,0x3f,0x8a,0xdd,0x5a,0x32,0x12,0xf0,0x3e,0x72,0x55,0xf6,0xac,0xae,0xe4,0x4b,0xbd,0xc5,0x90,0xba,0xfe,0xc0,0x39,0x17,0x24,0xad,0x8b,0xb3,0x93,0x4e +.byte 0x15,0xcc,0xd7,0xcc,0x5c,0x46,0x0e,0x61,0x7a,0x70,0x7f,0x01,0x23,0x7d,0x38,0xbc,0x27,0xb1,0x47,0x25,0x5b,0x9f,0x9c,0x53,0x95,0x40,0x94,0x33,0x16,0xfa,0x31,0xf1,0xb4,0xa3,0xb8,0x50,0x68,0x0d,0x47,0x1d,0x55,0xb3,0x26,0xfd,0xdc,0x4c,0xa8,0xc0,0x02,0xc1,0x53,0x56,0xd9,0x09,0xd8,0xdb,0xfa,0x4f,0xeb,0x33,0x00,0x57,0x28,0x34 +.byte 0xf1,0x43,0x5b,0x1d,0xd0,0x13,0xa1,0x90,0x87,0x96,0x97,0xb9,0x28,0xe1,0xa2,0xc0,0xcf,0xae,0xe0,0x7e,0x53,0x3d,0xe3,0xfe,0x35,0x33,0xa9,0x54,0x36,0xb3,0xfb,0x03,0xfc,0x76,0x23,0xf3,0xce,0x58,0x90,0x8a,0x90,0xa5,0x7c,0x99,0x06,0xfc,0x65,0x67,0x13,0xde,0x0c,0x6a,0x38,0x7a,0x9a,0xc1,0xc3,0x3a,0x66,0x99,0x4c,0xed,0x0a,0x15 +.byte 0xb1,0xf0,0x9e,0xd0,0x06,0x0e,0xce,0x84,0xe1,0xd7,0xa8,0xe3,0x12,0xb4,0x1a,0xb3,0x5d,0x86,0xda,0xcb,0xd7,0xd2,0x6c,0x1c,0xfa,0x2d,0x4e,0xc3,0x8d,0xe0,0x9d,0x8b,0xa3,0x9d,0xd7,0xf1,0xc5,0x29,0xa5,0x69,0x59,0xea,0x9d,0x85,0x78,0x05,0x14,0x31,0xed,0x91,0x8b,0x80,0xb6,0xd3,0xf5,0x9f,0x5f,0xa1,0x7b,0xe7,0x83,0x81,0xfa,0xa5 +.byte 0x4c,0x4d,0x2a,0xae,0xf0,0x09,0x87,0x4e,0x69,0x4f,0x12,0xf7,0xbf,0x0f,0xaf,0x1f,0x9d,0xdb,0x98,0xbf,0xed,0xfe,0xea,0x0a,0xe2,0x8c,0x7d,0x20,0x04,0x85,0x12,0x15,0xf2,0x05,0x93,0x88,0xa7,0x85,0x49,0xbe,0xdf,0x33,0x96,0xc0,0x4a,0x7a,0xfc,0x89,0x01,0xdb,0x09,0xdb,0xef,0xf3,0x43,0x48,0x5b,0x2f,0x41,0x6f,0x10,0x77,0x2f,0x5b +.byte 0xaa,0xaa,0x9c,0x51,0x69,0xf8,0x9b,0x6d,0x82,0xaa,0xaa,0x00,0x5d,0xfa,0xdf,0x74,0x35,0xcd,0xd1,0xf7,0xbe,0xcd,0x39,0xbf,0x94,0x5b,0x9a,0x22,0xd4,0x08,0x57,0x17,0xfa,0x89,0x40,0x44,0x9c,0x36,0x8d,0x0d,0xe5,0x1c,0x9c,0xc1,0xca,0x47,0x86,0xc2,0x3c,0xc3,0x93,0x75,0xcd,0x4c,0x3c,0xf5,0xb9,0xbe,0x2d,0x78,0x2c,0x08,0xaa,0xbf +.byte 0x4d,0x4c,0xac,0x64,0x89,0xfe,0xf3,0x41,0x4a,0xc3,0xec,0x3e,0x5f,0x1e,0x78,0x20,0x4e,0x49,0x9d,0xe5,0xa0,0x18,0xb6,0x00,0x0e,0x51,0x17,0x6e,0x56,0xc3,0x75,0xca,0x77,0x61,0xea,0x6e,0x52,0xa8,0x2c,0xdc,0xdd,0x8d,0x5f,0x2b,0xd5,0x30,0x0d,0x08,0x41,0x5c,0x8d,0x97,0xc9,0xee,0x7b,0xa2,0x10,0x5f,0x3c,0x57,0x68,0xa2,0x2c,0xc8 +.byte 0x3e,0xde,0x4b,0x10,0x68,0xaf,0x7d,0xd1,0xdc,0x30,0x33,0xf7,0xff,0x7a,0x23,0x66,0x86,0x56,0x24,0xc1,0x45,0xff,0x92,0x28,0xe4,0xd8,0xb0,0x18,0x63,0x1a,0x16,0xc2,0x59,0x32,0x7b,0x52,0x89,0xa5,0xac,0x71,0x61,0x28,0xc1,0xef,0xcb,0xcc,0x65,0xc3,0x4e,0x62,0xf0,0xed,0xef,0xdf,0x40,0x2b,0x69,0x62,0xe2,0xc4,0x31,0x4f,0x73,0xa8 +.byte 0xff,0x17,0x87,0xd2,0x45,0xc2,0x18,0x13,0xbe,0x7f,0x64,0x3e,0x6d,0x61,0xf2,0x18,0x16,0x5a,0x02,0x98,0xf1,0x47,0x5c,0xd4,0x76,0xcf,0x5b,0x29,0x0e,0x9d,0xf9,0x82,0x5b,0x46,0xf9,0x76,0x53,0xcd,0xa0,0xa4,0xf3,0xd8,0x33,0xb2,0xcb,0x3d,0x51,0xf2,0xce,0x07,0xea,0x7d,0x8b,0x65,0xba,0xe0,0xee,0x28,0x37,0x1a,0x31,0xbe,0x70,0x4a +.byte 0x69,0xac,0x35,0x32,0x4d,0xfa,0xb2,0x72,0x0d,0xde,0x26,0x1c,0x44,0xc0,0x20,0x54,0x73,0xce,0xa2,0x9d,0x9a,0xe2,0x13,0x8f,0xcd,0x5e,0x45,0x2c,0x32,0x2d,0x47,0x1d,0x4b,0x0f,0x78,0xa9,0xa2,0xe3,0xbb,0xcc,0x75,0x6f,0xbe,0xf6,0x76,0xfd,0xa2,0x58,0x44,0x31,0xe4,0xb3,0x9a,0xc4,0x82,0xeb,0x9a,0x73,0x0d,0x21,0x5d,0x0b,0x01,0xf1 +.byte 0xfc,0xc7,0x4e,0xfc,0x26,0xb8,0x2d,0x04,0x59,0x1a,0xc4,0x42,0x4a,0x7c,0x67,0xc4,0xe5,0x26,0x81,0x81,0xd6,0x28,0x3b,0x43,0xac,0xbb,0x5f,0x31,0x4d,0x14,0x68,0xb8,0x2c,0x3a,0xb3,0xe4,0x72,0x7d,0x07,0x80,0x22,0x80,0xaf,0x42,0xb4,0x0f,0x2b,0x79,0x7e,0xac,0x16,0xed,0x66,0x93,0x9c,0x90,0xe0,0xc1,0x33,0x51,0xd5,0x4a,0x16,0x4d +.byte 0x5f,0x55,0x7b,0x19,0x21,0x8e,0xe2,0x51,0x3d,0x94,0xf7,0x49,0x65,0x03,0x85,0xed,0x7c,0x3f,0xa9,0x28,0x96,0x20,0x95,0x44,0x62,0x8c,0xc8,0x88,0x59,0x40,0xf2,0x3e,0x05,0xa2,0x4d,0x7e,0xe5,0x9d,0xb8,0x01,0x9f,0x07,0x83,0x93,0x6d,0x0b,0x84,0xeb,0xe1,0x01,0xc0,0xc0,0xd1,0xb4,0x24,0xe4,0x43,0xdb,0x3f,0x2c,0x4b,0xe3,0x61,0x11 +.byte 0xb5,0x7a,0x6a,0xf0,0xe7,0xc6,0x96,0x78,0x51,0x4b,0x21,0xec,0xb5,0x20,0xec,0xc4,0x18,0x79,0x84,0x14,0x07,0x33,0x82,0x31,0x9f,0x9e,0xb3,0xe0,0x8f,0x7b,0x84,0x2d,0xef,0xb5,0x73,0x17,0xaa,0x81,0x07,0xd2,0x21,0xd6,0x85,0x7b,0x07,0x61,0x57,0xd3,0x27,0x6c,0x5b,0x8a,0x72,0x65,0xfe,0xbb,0x10,0x1a,0xd9,0xce,0xf0,0xf8,0x70,0x55 +.byte 0xe7,0xf5,0xd7,0xf7,0x4c,0xe1,0x5f,0xab,0x58,0xfd,0x8b,0x5f,0xe4,0x84,0x20,0xd9,0x6b,0x35,0x65,0xb2,0x9f,0x38,0xe7,0x6d,0xa5,0x69,0x64,0x64,0x6a,0x6e,0xf9,0x6c,0x42,0x0b,0x1f,0xbd,0xe3,0x0c,0xb4,0x62,0xf6,0x68,0x72,0x4b,0x58,0x24,0xd4,0x9d,0x91,0x66,0x9e,0x73,0x2b,0x69,0xe5,0xee,0xf5,0xb6,0x57,0x4c,0x24,0xef,0xc2,0xe5 +.byte 0x33,0xb1,0x96,0xb4,0xf9,0x53,0x25,0xb3,0x1c,0xe8,0x59,0x17,0xe4,0x85,0x24,0xd1,0x9e,0x13,0x35,0x47,0x8e,0x01,0x06,0x42,0x4f,0x8f,0xd0,0x2f,0x0d,0x5a,0x8b,0x96,0xd0,0xbd,0x8e,0x67,0xce,0x47,0x40,0x49,0x17,0x7c,0xe4,0x89,0xca,0x63,0x4e,0xef,0x99,0xf9,0xbc,0x20,0xf1,0xf0,0xca,0xe4,0xe2,0xb1,0x0c,0xfe,0x68,0xc1,0xe8,0xae +.byte 0x27,0x11,0x59,0x1b,0xd4,0x3e,0xb9,0xbe,0x6c,0x25,0x59,0x36,0xc1,0xf6,0x27,0x21,0x47,0x32,0xe8,0x05,0xec,0xc4,0x07,0x22,0xbd,0xcb,0x12,0x72,0x9f,0x1c,0xdd,0xc9,0xbe,0x2f,0xb4,0x84,0x2c,0xf3,0xfb,0x91,0xe4,0xe8,0x5b,0x96,0xe1,0xa1,0x7a,0xa6,0x6d,0xfe,0x94,0xd3,0x2a,0x94,0x86,0x7f,0xfc,0xa2,0x48,0xb3,0xc7,0x60,0xb2,0x97 +.byte 0x27,0x4d,0xe3,0xd2,0x2b,0x8e,0x44,0x96,0x57,0x11,0x8a,0x78,0xba,0x12,0x91,0x9d,0x3d,0x1e,0x87,0xcb,0xdc,0x79,0xef,0x9a,0x37,0xd8,0x62,0x52,0xd2,0x0b,0xb7,0x3e,0xf0,0x8c,0xac,0xd1,0xfb,0x9c,0x3a,0x63,0x4b,0x0f,0x92,0xf0,0x1e,0x56,0x33,0xb1,0xfb,0xc3,0x2b,0x51,0xbd,0x30,0x4c,0xc0,0x65,0x21,0xeb,0x98,0x71,0x64,0xa3,0x6b +.byte 0x31,0xe2,0xd9,0x52,0x53,0xc9,0x4c,0xc9,0x93,0x00,0xd0,0x26,0x57,0x3e,0x72,0x4a,0xb2,0x43,0x33,0x9d,0xb6,0xbc,0x68,0x9f,0x28,0xd7,0x00,0x77,0xcc,0x1c,0x0c,0xf1,0x91,0x91,0x77,0x63,0x1e,0xcf,0x8f,0x89,0x89,0xf5,0xe0,0x71,0xa3,0x59,0x49,0x79,0xad,0x7a,0x3d,0x1f,0xcc,0xc0,0x74,0x11,0x56,0x56,0x8d,0x04,0x1c,0xef,0xba,0xec +.byte 0x05,0x85,0x82,0x0c,0x67,0xae,0xa3,0x40,0x4e,0x79,0x65,0xcf,0x72,0xd4,0x79,0xcc,0x96,0x0f,0x89,0xea,0x9a,0xbf,0x52,0x25,0x76,0x08,0x6e,0xdc,0x51,0x92,0xb3,0x6d,0x75,0x01,0x7b,0x13,0xa2,0x62,0xff,0x56,0x1d,0xbb,0xf1,0x8e,0x37,0x35,0x23,0x08,0xb3,0x05,0xd4,0xcc,0x74,0x35,0x63,0xae,0x67,0x51,0x10,0xc2,0xb6,0xf6,0x7f,0xc5 +.byte 0x92,0x1a,0x11,0xb0,0x73,0x28,0x08,0xf0,0xee,0x32,0xab,0x3d,0x67,0xd5,0x96,0xc1,0x3a,0x55,0x3a,0x7a,0x59,0xf3,0x42,0x5e,0x8c,0xc6,0x8f,0x17,0xf6,0x30,0xdf,0x8f,0x06,0x6a,0xe3,0x92,0x02,0x20,0x69,0xc3,0x45,0x4b,0x04,0x7c,0x5f,0x5b,0x42,0x30,0x33,0xd5,0x11,0x66,0x57,0x76,0x24,0x7f,0xa7,0xa9,0x79,0x24,0x17,0x84,0x43,0xfd +.byte 0xbc,0x44,0xee,0xfc,0xe9,0xeb,0xeb,0x61,0x6b,0xdc,0x32,0x9b,0x6f,0xf0,0x5b,0x9e,0x00,0x02,0x18,0x9c,0xb8,0xe2,0x2e,0x23,0x6a,0xf8,0x28,0x99,0x6d,0x03,0x87,0x4a,0x71,0xdb,0x00,0x13,0x38,0x86,0x2d,0x77,0xb6,0xd5,0xaf,0xf2,0x62,0x3b,0xe6,0xfc,0x75,0x77,0x39,0xee,0xbc,0x1c,0xc7,0xcd,0x9f,0xbf,0xa1,0xb2,0x86,0x0c,0xcc,0x4d +.byte 0x47,0xbd,0xcd,0x3d,0x65,0xe4,0xd9,0x6e,0x2f,0xeb,0x1b,0x4f,0x49,0x05,0xd9,0x85,0x25,0xa1,0xdd,0xdd,0xc5,0x80,0x91,0x39,0x46,0x47,0x93,0x2a,0x31,0x56,0xe3,0xbf,0x7f,0x71,0x5b,0xc9,0x64,0x25,0x36,0x06,0xc8,0xf9,0xd6,0xad,0x5d,0x6f,0xe3,0x6d,0xbf,0xd5,0x68,0xb6,0x36,0x9a,0xae,0xa4,0x6c,0x65,0xc8,0x10,0xc0,0x04,0x88,0x4a +.byte 0xf1,0x9c,0x45,0x63,0xfb,0xc1,0xc6,0x7f,0x63,0x1d,0xe9,0xe4,0xa9,0x2e,0xd9,0x5b,0xab,0x89,0x31,0x70,0xa7,0xe2,0x08,0x23,0xcf,0x43,0x25,0x28,0x89,0x9b,0xb8,0x2a,0xe8,0xc9,0x02,0x9d,0x2b,0xf0,0x1e,0xe6,0x50,0xf7,0xb6,0x1e,0xe1,0xf1,0x65,0x22,0x86,0xa8,0x91,0xfd,0xc5,0x8b,0x0f,0xa0,0xd5,0x89,0xa4,0x9b,0xd1,0xb0,0x27,0x37 +.byte 0x46,0x77,0x00,0x64,0xfd,0x93,0x8c,0x44,0x84,0x3d,0xb3,0xc4,0xd1,0x68,0x2a,0x00,0x2c,0xc2,0x35,0xc7,0x31,0x96,0x73,0xef,0x05,0x8c,0x47,0x94,0x09,0x83,0xbc,0xc0,0x9f,0x5b,0x70,0x1d,0xe0,0xed,0x9d,0x1a,0x07,0xb2,0xa3,0x20,0xfd,0xa1,0x6b,0xa7,0xee,0xb2,0xd3,0x25,0x33,0x63,0x9e,0x12,0xce,0x00,0xb3,0xad,0xb6,0x56,0xc3,0xd4 +.byte 0x94,0xe7,0x3d,0x45,0x9d,0xcb,0x76,0x0c,0x74,0xf0,0x26,0x9f,0x56,0x10,0x58,0xf0,0xf7,0x6f,0x09,0xc8,0x9f,0x84,0x69,0x64,0x7b,0xdb,0xd9,0x89,0xe4,0xa3,0x9c,0x3b,0xc7,0x94,0x46,0x41,0x58,0xb0,0xa4,0x44,0xaa,0x27,0x11,0xfc,0x16,0x24,0x57,0x36,0xca,0xf7,0x55,0x76,0x0e,0x9f,0x72,0x37,0x61,0x46,0xe5,0xe5,0x9d,0x83,0xac,0x18 +.byte 0xdf,0x81,0xf1,0xa4,0xa3,0x3b,0x92,0x1d,0x33,0x9f,0x25,0xf0,0x6a,0x87,0x15,0x62,0x6d,0x4c,0x72,0x68,0xe0,0x0a,0x74,0x62,0x27,0x00,0xd6,0xee,0xdd,0x16,0xef,0xb4,0x4e,0x3f,0xad,0xe0,0x03,0xed,0x64,0xc4,0xbd,0x66,0x9d,0x3e,0xf4,0xec,0xd6,0x06,0x96,0x5d,0x11,0x0d,0x87,0x5e,0x62,0xba,0xdb,0xff,0x9c,0xb5,0x08,0x84,0xa3,0x54 +.byte 0x22,0x60,0x07,0x9e,0x45,0xa4,0x9f,0x8b,0xb3,0x3f,0x50,0x20,0x76,0x21,0x8a,0xc4,0xf1,0xb8,0x5c,0x1d,0xe2,0x88,0x0e,0xf6,0x8c,0x3e,0x75,0x85,0x8f,0xa1,0x71,0x72,0xf2,0x74,0x24,0x69,0x43,0x10,0xef,0x7b,0xb0,0x8d,0x1a,0x1f,0x1a,0x24,0xaa,0xdf,0xaa,0xbe,0x70,0x60,0x34,0xf0,0x91,0x03,0x72,0x20,0x19,0x8d,0xa5,0xaf,0xed,0xa8 +.byte 0xd7,0xe4,0x12,0xad,0x09,0x32,0x85,0x63,0x79,0x3a,0xf4,0x72,0xde,0x27,0x76,0xa1,0x8e,0x73,0xc8,0x04,0xf9,0xd0,0x09,0x03,0x44,0xbb,0xb8,0x5a,0x0f,0x36,0x51,0x8f,0x22,0xb4,0xaf,0xb0,0xc9,0xc0,0xcb,0x43,0x78,0xac,0x75,0x4a,0xf4,0x42,0x31,0x7e,0x25,0x92,0x73,0x10,0xfb,0x66,0x94,0xe9,0xd8,0xc6,0xcb,0xd2,0xc2,0xb1,0xa6,0x2c +.byte 0x34,0x86,0xb9,0x9a,0xb1,0xc5,0x86,0x0d,0xb7,0xbd,0xee,0x6b,0x94,0x94,0xc6,0x30,0x62,0xda,0x90,0xc7,0xef,0xbd,0xc7,0x3c,0x99,0x0a,0x0b,0xbf,0x7a,0xfa,0xa7,0xd7,0xca,0x4a,0xe7,0x33,0x6e,0xfa,0x81,0xb1,0xb9,0x3a,0xb9,0x9f,0x20,0x53,0xb7,0x62,0xe6,0x99,0xd7,0x17,0x09,0x64,0xe8,0x81,0xac,0x39,0xde,0x4f,0x03,0x24,0x8e,0x8f +.byte 0x24,0x0f,0x24,0x54,0xe8,0x1e,0xfb,0x31,0x36,0xdc,0x22,0x43,0xba,0x69,0x2c,0xf6,0x98,0xcf,0x1f,0xd4,0x45,0x17,0x92,0x50,0xda,0x85,0x59,0x7b,0x11,0x01,0x32,0x4b,0x73,0xd9,0xc8,0x4c,0x1b,0x22,0x96,0x27,0x4a,0x2f,0x26,0x9d,0xf5,0x8d,0x43,0xb3,0x2f,0x62,0x5a,0x1d,0x19,0x78,0x51,0xcf,0x65,0x09,0x88,0x7a,0x09,0x2b,0x81,0xc2 +.byte 0x5b,0x03,0xee,0x13,0x1b,0xb9,0x4f,0x6d,0x6d,0xb6,0x58,0xdf,0x87,0xc3,0x24,0x01,0x48,0x9d,0xe1,0xf0,0x6d,0x04,0x9e,0x88,0xab,0x11,0x4e,0x46,0x32,0xf3,0xfd,0xb3,0x9c,0x01,0x3d,0xd2,0x09,0x35,0x3e,0xf2,0xb0,0x97,0x65,0x47,0x9a,0x14,0x15,0xd0,0x90,0xf2,0x6c,0x66,0xb2,0x66,0xf5,0x97,0xe2,0x69,0x23,0xd8,0xdb,0xbe,0xcd,0x4c +.byte 0x88,0x78,0x1a,0x8f,0x5b,0xb6,0xcd,0xd0,0xd3,0x65,0x03,0x76,0x63,0x59,0xd1,0xdf,0xed,0x55,0x1b,0xae,0xd3,0xf6,0x59,0x41,0xb5,0x2c,0xf6,0x62,0x6c,0x48,0xc1,0x77,0xc8,0x78,0x94,0xd8,0xa7,0xf4,0xa3,0x8c,0x75,0x25,0xe7,0xf3,0xf4,0x5b,0xaf,0x6c,0xf6,0xb0,0x88,0xac,0x30,0x76,0x87,0x71,0x10,0x49,0x70,0x90,0x31,0x28,0x39,0x75 +.byte 0x7c,0x43,0x41,0x05,0x3b,0x51,0x35,0x2e,0xe6,0x9c,0xa9,0xcf,0x4a,0xfc,0xa8,0xc7,0xb5,0xd7,0x5a,0xa8,0x4b,0x51,0x75,0xab,0x40,0x19,0xc7,0xa0,0xbc,0x6d,0x3f,0xb0,0x1b,0x2b,0x85,0x51,0x04,0xae,0xb2,0x7a,0xbd,0x3b,0xd2,0x04,0xb5,0x2a,0x69,0xed,0x7d,0x24,0x15,0x76,0xca,0x25,0x15,0xd8,0x69,0x1c,0xd4,0xc3,0x3f,0x14,0x07,0x78 +.byte 0x6b,0xf6,0x5a,0x37,0xaf,0x4a,0x73,0x52,0xa2,0xe6,0x82,0xb6,0xc7,0xd2,0x6a,0x20,0x58,0xc4,0x2b,0x9b,0x95,0x81,0x5e,0xdf,0x37,0x9d,0xbc,0x76,0x9b,0xee,0x36,0x82,0x9f,0xe2,0x0a,0x7f,0xb5,0xb1,0xb4,0x2c,0x89,0xc1,0xe4,0x97,0x2d,0x01,0xc3,0x7e,0xe4,0x39,0x07,0xed,0x5a,0xa7,0x06,0x6d,0xce,0xe9,0xa8,0x2f,0x5d,0x16,0x2e,0x1f +.byte 0xfc,0x20,0x34,0x32,0x8b,0xd7,0xd0,0xd1,0xbc,0x3d,0x0a,0xa8,0x1e,0x7c,0xc8,0x68,0x37,0x3a,0xa5,0xcb,0xee,0x56,0xc3,0x9f,0xb1,0xb4,0x92,0x00,0x6a,0xd9,0x9b,0x0c,0x4a,0x6a,0xd0,0xdf,0x7d,0xa4,0x2f,0x96,0x85,0xe8,0x4a,0x2a,0x34,0x77,0xfe,0xc3,0xaa,0x35,0xb0,0xd1,0xf2,0x4d,0xeb,0x1c,0x9f,0x17,0x44,0xca,0x4e,0x53,0x2b,0xc4 +.byte 0xe6,0x8e,0x97,0xfb,0x2b,0xb2,0x50,0xba,0x9b,0x79,0x72,0x3a,0x52,0x3f,0x5c,0xf2,0xef,0xee,0xe2,0x13,0xdc,0x2a,0x9b,0x7f,0x48,0xec,0xad,0xf1,0xa2,0xcf,0x38,0x36,0xe6,0x67,0x16,0x2c,0x9d,0x13,0x33,0xc9,0x45,0x10,0x9a,0x70,0x7d,0xf9,0xcb,0x7b,0xe5,0x00,0x20,0xbd,0x7d,0xc0,0x6c,0xde,0xae,0x87,0xb9,0x3a,0x18,0xf5,0x9e,0xd3 +.byte 0x65,0x32,0x97,0x50,0x9c,0x47,0xb2,0x3f,0xe3,0xa4,0x76,0xfb,0xc8,0x4d,0x8b,0xf3,0x8c,0x19,0x1e,0x18,0xf1,0x3d,0x52,0x13,0xbf,0xfd,0x25,0x50,0xc5,0x07,0xc7,0x8f,0x9e,0x5e,0xac,0x0a,0xfa,0x35,0xfa,0x3b,0xd4,0x74,0x6d,0x42,0xb1,0x7b,0x98,0x6c,0xe4,0xe5,0x26,0xf3,0xf7,0x08,0x44,0xa8,0x2e,0x7d,0x11,0x05,0x72,0x63,0x39,0x27 +.byte 0x4f,0x60,0x2e,0xbf,0x78,0xa9,0x5e,0x41,0x33,0x36,0x01,0x55,0x8b,0xba,0x7f,0x6c,0x53,0x38,0xfe,0x98,0x9e,0x9f,0x0f,0x7f,0x01,0xda,0x62,0xc6,0x5c,0x11,0x3f,0x21,0xfa,0xf6,0x15,0xda,0xb1,0x41,0xe5,0xc8,0x9f,0x77,0xb2,0xa7,0xc5,0x4e,0xfe,0xce,0x40,0xc8,0x76,0xc1,0xa2,0x68,0x93,0x4a,0x81,0xd2,0x92,0xd1,0x21,0x81,0x42,0x9e +.byte 0x44,0x4a,0x45,0xa3,0x9f,0xbf,0xa1,0x8a,0x68,0x27,0xcf,0x27,0x60,0xcb,0x28,0xd0,0x56,0x97,0xd2,0x2b,0xf4,0x3c,0xb9,0x5e,0x9e,0xa8,0xdd,0x35,0xbe,0x0e,0x7f,0xf6,0x37,0x4d,0x8a,0xb5,0xd1,0x31,0xec,0x50,0xfd,0x54,0xc5,0xf8,0xc5,0x83,0xce,0xfb,0x35,0x79,0x37,0x1e,0x8f,0xaf,0x3f,0x7d,0x82,0x2d,0x01,0x8c,0x09,0x27,0xe9,0xcb +.byte 0x6a,0xfd,0x66,0x99,0x22,0x2d,0x8f,0xe2,0xb4,0x28,0x1d,0x17,0x23,0x85,0x2e,0x15,0x20,0x84,0x93,0xcc,0x3c,0x26,0x83,0x9e,0x5a,0x20,0x22,0xf4,0x9a,0x38,0x97,0xaf,0x7d,0xb9,0xb9,0x5e,0x06,0x30,0x67,0xc6,0x3b,0xf8,0x2e,0xe0,0x96,0xdc,0xa4,0x4e,0xb7,0xf5,0xe0,0x93,0xc3,0xcc,0x03,0xcf,0x69,0x18,0x0b,0x69,0x9c,0xb2,0xe2,0x71 +.byte 0xb5,0x58,0xde,0xf1,0xa9,0x43,0x30,0x62,0x98,0x75,0x29,0x48,0xca,0x84,0x72,0xdc,0xf8,0xfa,0x10,0x67,0x15,0x08,0xb6,0x5d,0x91,0xd6,0xfb,0xf2,0xe3,0x3c,0x0b,0xe4,0x96,0xe1,0xe8,0xe6,0x26,0x0d,0xc6,0x6a,0x82,0x65,0x66,0xbf,0x77,0xb7,0x3b,0xe3,0xb5,0xdd,0x10,0x6b,0xb4,0xb7,0xcc,0xc2,0x54,0xbd,0xec,0x18,0x19,0xb7,0xe6,0xa8 +.byte 0xdb,0xde,0xc7,0x97,0x1f,0xa5,0xee,0xc3,0x06,0x3e,0x45,0x10,0x97,0x0c,0xc4,0xe1,0xe0,0x22,0xbe,0x36,0x86,0x20,0x44,0x29,0x6e,0x75,0xbc,0xaf,0x6d,0xf9,0xb0,0xec,0x16,0x77,0x65,0xb0,0xf1,0xfc,0xa5,0x30,0x04,0x94,0x25,0x6f,0x7c,0x32,0x51,0xed,0x38,0x77,0xd7,0x3f,0x34,0x02,0x04,0x35,0x97,0xa8,0x06,0x0d,0x62,0x53,0x67,0x6e +.byte 0x94,0xe4,0x0e,0x34,0x3e,0x5b,0x16,0x56,0x52,0x70,0xf1,0x49,0x0f,0x75,0x60,0x4f,0xd2,0x32,0xf8,0xd2,0x33,0x08,0xd4,0x44,0xa6,0x7c,0x9b,0xa1,0xca,0x3f,0x6c,0x6f,0x53,0xdc,0xd1,0x46,0xa4,0x37,0x38,0xf6,0xd7,0x08,0xcb,0x08,0xa6,0xe5,0xa6,0xe9,0x3c,0xb1,0x98,0x7e,0x44,0x9e,0x8e,0x4e,0xca,0xa5,0xc5,0x24,0xb7,0xe3,0x05,0xf1 +.byte 0xc0,0x91,0x3b,0x97,0x6d,0x76,0x56,0x65,0x5f,0x1b,0x92,0x92,0x49,0x1e,0x3b,0xb2,0x86,0x23,0x67,0xfd,0x37,0x74,0x71,0x0a,0x16,0x19,0x7e,0x54,0x0b,0xa4,0x4d,0xc0,0x1d,0xb1,0x3f,0xe2,0x2f,0x98,0x85,0x97,0xad,0x10,0x76,0xf2,0x7e,0x42,0x78,0x81,0x98,0xab,0xd5,0xc9,0x3a,0x5b,0x69,0xc1,0xce,0x10,0xa4,0x9e,0x1c,0xd4,0xa9,0xc3 +.byte 0x68,0x5b,0x82,0x3b,0x90,0x65,0x80,0x6d,0x96,0xbb,0x03,0x33,0xbf,0xb9,0xd2,0x5e,0x42,0xc9,0x7b,0x4e,0x27,0x42,0xe4,0x20,0x9f,0xc4,0x69,0x16,0x23,0xa1,0x98,0x28,0x38,0xfe,0xdf,0x19,0x7c,0xf5,0xbf,0xa3,0x8e,0xe0,0x06,0xb2,0xa4,0x63,0x06,0x03,0x45,0x26,0x51,0xe9,0xcf,0x0c,0xe1,0x2f,0x67,0xb9,0x83,0xe9,0x5b,0xf1,0x7e,0x5a +.byte 0xea,0xa5,0x31,0xec,0x7d,0x2c,0x8a,0x6e,0xc0,0xb9,0x98,0x60,0xc2,0x71,0xbf,0x0f,0x1d,0xfd,0xb5,0x41,0xd6,0x6f,0xae,0xcd,0x04,0x29,0xcf,0xd9,0xf6,0x71,0xdd,0xab,0x52,0x9e,0x14,0x81,0x0d,0xb4,0x27,0xcc,0x68,0x65,0xc8,0x65,0x1f,0xfc,0xb7,0x44,0x31,0xaf,0x03,0xfe,0x9c,0xf4,0xf8,0x80,0x91,0x90,0xc5,0x0e,0xe0,0xe3,0x4f,0x46 +.byte 0x33,0x84,0x51,0xea,0x2a,0x50,0xb8,0x09,0x6e,0x0f,0x6b,0xd8,0x86,0x0a,0xf5,0xfc,0xda,0xc7,0x8c,0x8f,0xec,0x15,0x61,0x57,0x30,0xdd,0xda,0x40,0xb5,0x99,0xd6,0x0d,0x34,0xb0,0x55,0xab,0x90,0xc3,0x1e,0x7e,0xac,0x90,0x75,0x49,0x54,0xc4,0xa3,0x2e,0x9d,0xd0,0xac,0xcd,0x01,0x03,0x1d,0x3f,0xf4,0xf0,0xcb,0x36,0xc2,0xe4,0xb1,0x1a +.byte 0x62,0x91,0x08,0x4f,0xd2,0x91,0x22,0xf5,0x0e,0x37,0x18,0xcc,0xde,0xf4,0xbc,0x58,0x6a,0x52,0x91,0x1b,0x6a,0x22,0x5e,0xe8,0xd7,0xb4,0x87,0xfd,0xbe,0x9c,0xff,0x1a,0xb9,0x9c,0xba,0x20,0x75,0xcc,0xc7,0x3c,0x6a,0xd4,0x9a,0xfa,0xfe,0xb8,0xdc,0x7f,0x85,0x79,0x20,0x72,0x31,0x53,0xb1,0xb9,0x83,0xd9,0x2c,0x61,0x56,0x0c,0x97,0x7a +.byte 0x10,0x88,0xdf,0x2d,0xa3,0xdd,0x83,0x7e,0xd9,0x63,0xf3,0xd7,0x18,0x69,0x49,0x4c,0xd5,0x6b,0x26,0xee,0xf6,0xcb,0x1d,0x44,0x0d,0xeb,0xe3,0x9b,0xfd,0xa9,0x7c,0x9d,0x69,0x82,0x11,0x17,0x32,0x0f,0x17,0xb0,0x8a,0x96,0xd9,0x78,0x0c,0x90,0x43,0x0a,0x8b,0x64,0xa4,0x61,0xdc,0xe8,0xc8,0x3c,0xa0,0xda,0x97,0x66,0x7e,0xa0,0xb7,0x1c +.byte 0xd4,0xa2,0x05,0xbc,0xb8,0x60,0x10,0x5d,0xb8,0x83,0x4d,0x02,0xce,0xc4,0x30,0xf2,0x9f,0xfb,0xa7,0x15,0xed,0x2b,0x4a,0xb0,0x0e,0x6f,0x96,0xfb,0x06,0x58,0x8d,0xb4,0xde,0x96,0x88,0xfd,0xa2,0xf0,0xff,0xa4,0x4e,0xc5,0x92,0x60,0x81,0x52,0x19,0xdf,0xbc,0xd5,0x4d,0x74,0x54,0x04,0x05,0x33,0x39,0x64,0xfe,0x44,0x7e,0xb0,0x5c,0xd1 +.byte 0x68,0xde,0xdf,0x3e,0x05,0xea,0xab,0x45,0xf7,0x33,0x95,0xd4,0xa1,0xc6,0x1d,0x73,0x8a,0x19,0xff,0x20,0xd8,0x48,0x08,0xc6,0x1b,0x07,0x6d,0x78,0xe7,0xe3,0x2e,0xe7,0xcd,0xc9,0x1f,0x49,0x99,0x9c,0xab,0xa3,0x4a,0x77,0x48,0x91,0xea,0xe3,0xdb,0xf6,0x7a,0x91,0x3a,0xda,0x79,0xee,0x90,0x41,0x79,0x68,0xac,0xb9,0x56,0x46,0xae,0xf1 +.byte 0xd9,0xdf,0x58,0x09,0xfe,0x42,0xe7,0xe2,0x44,0xd4,0x63,0xf4,0x67,0x5d,0xeb,0x6b,0x0e,0xe4,0x56,0xfa,0x01,0xc8,0xc5,0x58,0xfa,0xb7,0xe8,0x3a,0xb1,0xa1,0xde,0x94,0x88,0x21,0x06,0xd3,0x5c,0xa7,0x89,0x68,0x7b,0x8e,0xb2,0x86,0xe3,0x9a,0x9e,0xca,0x63,0x78,0xcb,0xb6,0x1a,0x35,0x16,0x43,0x4b,0x09,0xd1,0xb4,0x71,0xef,0xb6,0xb2 +.byte 0x2e,0xa5,0x2b,0x4e,0x18,0xac,0x8f,0xc0,0xfe,0x86,0xcc,0x63,0xc6,0x0c,0x3c,0xee,0x22,0x92,0x7c,0xca,0xab,0x1a,0xbf,0x21,0x20,0xf2,0xd6,0xba,0x99,0x17,0xca,0x1e,0x00,0x39,0xa9,0xe4,0x65,0xa8,0xdd,0xae,0x2a,0x29,0xb1,0xa6,0xaf,0x22,0x2a,0x94,0x6c,0x68,0x66,0xb4,0x11,0x92,0x03,0x7c,0xf6,0x49,0x88,0xac,0x91,0x14,0xb7,0x1d +.byte 0x06,0x8c,0x82,0xf9,0x56,0x3c,0x54,0xa3,0x31,0xb1,0x56,0x69,0x09,0x7b,0xf1,0x9d,0x01,0x10,0x1a,0xaa,0x82,0x52,0x36,0x7d,0x28,0x6d,0xc1,0x18,0xdd,0xdb,0xc5,0x99,0x1c,0x69,0xd6,0x81,0xb8,0x1b,0x63,0x44,0xe9,0x5d,0xac,0x0e,0xd2,0xa4,0x4a,0x38,0x17,0xb5,0x41,0xca,0x81,0x96,0xe2,0x5b,0x2c,0xd2,0xd1,0xdc,0xbf,0x8a,0x57,0x46 +.byte 0x7d,0x48,0x1b,0xc0,0x11,0xce,0x09,0x23,0x06,0x73,0xd0,0x2f,0x8f,0x7f,0x4e,0xaf,0x92,0xff,0x5d,0x52,0x20,0xfc,0x12,0x7d,0x7f,0x6a,0xd0,0xf3,0x20,0xc2,0xf9,0x05,0x20,0x56,0x9f,0x97,0xa3,0x64,0x5c,0x4c,0x8d,0xab,0x76,0x84,0x2b,0x6b,0xea,0x3c,0x4f,0x2a,0x2c,0x0b,0x45,0x7c,0x7b,0x73,0x6d,0x91,0x7e,0x7c,0xc0,0x2d,0x32,0x5a +.byte 0xb7,0xa7,0x1e,0x15,0x17,0x18,0xfb,0xbc,0x64,0x67,0xd3,0x0c,0x28,0xc5,0xaf,0x9e,0xe5,0x89,0x36,0xdd,0x16,0xef,0x21,0x70,0xe9,0x26,0x95,0xab,0xdd,0x5b,0xce,0xd4,0x57,0xe9,0x49,0xb3,0x08,0x9b,0x19,0x74,0x70,0x3b,0x8f,0xf6,0x95,0x38,0x92,0x24,0xb1,0xf8,0x27,0xc1,0xa3,0xa3,0x87,0x71,0x42,0xca,0x95,0x05,0x0e,0x06,0x51,0x11 +.byte 0x2d,0x43,0x83,0x83,0x01,0xb3,0xcd,0xf9,0xb9,0xff,0xf6,0x5c,0x8d,0xc1,0xc9,0x05,0x49,0x77,0x93,0xff,0x66,0x79,0xf6,0x7c,0xea,0x11,0x5c,0x5e,0xd4,0x82,0x36,0x28,0xc7,0xbb,0x00,0x00,0xc3,0x90,0xda,0xa2,0xef,0x95,0x45,0x6c,0x74,0xbc,0xd8,0x11,0xe6,0x73,0x1f,0xb9,0xa7,0x2b,0x79,0x62,0xbf,0xc1,0xa2,0x5c,0x10,0xfd,0x3d,0x72 +.byte 0x00,0xc9,0xb6,0x05,0x9c,0xec,0x70,0x30,0x68,0x7b,0x46,0x86,0x47,0x19,0x95,0x07,0x1b,0x49,0xde,0x25,0x6b,0x34,0xea,0x75,0x28,0xdf,0xa7,0xf9,0x59,0xbc,0x79,0xab,0xaf,0x67,0x9f,0xa1,0xe0,0x39,0xe3,0xd8,0x6e,0xbd,0xfe,0x1d,0xd3,0xec,0x2d,0x3b,0x7b,0x21,0xde,0x06,0x72,0x63,0x61,0xf3,0xd0,0xdb,0xae,0x32,0xc9,0x73,0x90,0xa1 +.byte 0xb3,0xdc,0xc3,0xaf,0x2b,0x43,0x12,0x72,0x5a,0xef,0x5a,0x6a,0x44,0xbc,0x38,0x65,0x8c,0x25,0x32,0x96,0xe8,0x17,0xd3,0x96,0x4c,0xf2,0x95,0x29,0x90,0xd9,0x1c,0x6d,0x86,0x60,0xef,0x1a,0x25,0xdf,0x71,0xa1,0x8a,0x3d,0x08,0x08,0x01,0x01,0x6e,0x07,0xff,0x23,0x71,0x98,0x49,0xd6,0x3c,0xd4,0x3f,0x67,0xf1,0xe5,0xc4,0x4b,0x10,0x68 +.byte 0x58,0xa8,0xa5,0x33,0xbb,0x6e,0x51,0x80,0xa3,0xec,0x17,0xdf,0x18,0x6f,0xe1,0x33,0x70,0x25,0x65,0xbd,0x19,0x12,0x4f,0xf5,0x30,0x4b,0x2d,0x30,0xac,0xa8,0x64,0x70,0x9a,0x6c,0xbf,0xb3,0xdb,0xdf,0x1b,0xb3,0x75,0x19,0x1f,0x70,0x8d,0xd2,0xdb,0x1c,0xca,0x72,0xca,0xb5,0xe3,0x34,0x4f,0x16,0x72,0x3f,0x12,0x2f,0x61,0x57,0x9f,0x6c +.byte 0xbc,0x2e,0x2f,0x27,0x26,0xac,0x0d,0x54,0xfc,0x78,0x58,0xdf,0x86,0x9c,0xfc,0x8b,0xaf,0x99,0x04,0x17,0x19,0xbf,0x9a,0xf9,0x03,0xea,0x3c,0xd8,0x9d,0x2e,0xd7,0xd2,0x51,0x01,0xe0,0x1e,0xbf,0x3d,0x85,0xa0,0x73,0xa6,0xcc,0x20,0x56,0x42,0x16,0xb1,0x9d,0xa9,0x1a,0xfc,0x0d,0x20,0x8c,0x04,0x55,0xbe,0x33,0xd1,0x86,0xab,0x3c,0x95 +.byte 0x9b,0x86,0x84,0xf2,0x99,0xe6,0xab,0xee,0x34,0xd3,0xfd,0xf7,0xb8,0xe7,0x44,0x58,0x36,0xdb,0xc5,0xb5,0x81,0x31,0xbc,0x21,0xe0,0xd0,0x6e,0x2e,0xff,0x86,0xf5,0xb6,0x22,0x69,0x1f,0x23,0xb6,0x24,0x52,0x13,0xdd,0xc3,0xb9,0x76,0xef,0xda,0x22,0x5b,0xfb,0x68,0xfe,0xd2,0xc8,0xcc,0x9e,0x51,0xe3,0x93,0xd8,0x7c,0x6f,0xd5,0x4a,0xdd +.byte 0x71,0x23,0x14,0xf5,0x0c,0xce,0xd6,0x7a,0xfd,0xda,0x03,0x36,0x4b,0xa0,0x3f,0x0d,0xc9,0xd6,0x35,0x31,0x3a,0x68,0x15,0x85,0x31,0x12,0x72,0x15,0xb3,0xb4,0xbb,0x42,0xe9,0x54,0xcd,0x93,0x78,0x28,0x31,0xcd,0xb6,0x36,0xe7,0xac,0x1f,0x5d,0x64,0x60,0x93,0x67,0x82,0x02,0xda,0x46,0x74,0xa2,0x55,0x6a,0xae,0x66,0x07,0x08,0x45,0x67 +.byte 0x3e,0xa7,0x5c,0x6a,0x2a,0xe5,0x8a,0x3a,0x92,0x18,0x2f,0x63,0x36,0x49,0x37,0xa9,0x02,0x3c,0x24,0x3e,0x83,0x5c,0x7e,0xae,0x41,0x95,0x65,0x50,0x90,0x45,0xa1,0xc5,0xdd,0x8c,0x72,0xd2,0x24,0x74,0xfd,0x69,0x75,0x76,0x7a,0xd7,0x79,0xfb,0x02,0x7c,0x27,0x2b,0xdb,0x3b,0xa9,0x5f,0x32,0x03,0x25,0x8e,0x8b,0xe7,0xe7,0x64,0x85,0x47 +.byte 0x58,0xfc,0xce,0x40,0xa2,0xeb,0xab,0xfd,0x4e,0xda,0x58,0x87,0x40,0xb8,0x22,0x29,0xff,0xa7,0x02,0x8c,0xdb,0x90,0xf5,0x14,0x62,0xec,0x21,0xfa,0x4e,0x52,0x2e,0xfb,0xa8,0x56,0x8a,0x68,0xdf,0xb1,0xa0,0x78,0x43,0x99,0xd8,0x45,0x6e,0xd6,0x94,0x62,0x5a,0x19,0x0f,0x47,0xdd,0x5b,0x05,0x8e,0xe2,0x4c,0x2d,0x3b,0xd9,0xfd,0x24,0x98 +.byte 0x9d,0xc0,0x34,0x33,0x76,0xae,0xd9,0x82,0xcf,0x77,0x85,0x2a,0xb0,0xbd,0x98,0xc7,0xfa,0x2c,0xcd,0x91,0xb5,0x94,0x2b,0xb7,0xac,0xc9,0x7f,0xd7,0xcc,0xe0,0x77,0x18,0xce,0x44,0x7e,0x21,0x2e,0x86,0x0f,0xb5,0x3c,0xe4,0x07,0x86,0x33,0x8f,0x78,0x4a,0x6a,0x66,0x4b,0x6f,0xb8,0x54,0xfc,0x3c,0x44,0x76,0x36,0x4e,0x04,0x3f,0x37,0x46 +.byte 0xc4,0x9d,0xba,0x1f,0x7e,0xf2,0x24,0xae,0x40,0x56,0x55,0xc0,0xed,0x8e,0xbc,0x2e,0x4b,0xf1,0x74,0xb5,0x99,0x73,0x62,0xb2,0x6b,0x0c,0xd2,0x8a,0xcc,0x01,0x8f,0x16,0x35,0xc2,0xad,0x03,0xdb,0x07,0x68,0x56,0x5b,0x46,0x49,0x32,0x11,0xe3,0xd5,0x6a,0xa6,0x1f,0xf5,0xde,0xf6,0xac,0x53,0x43,0xf1,0xf4,0x25,0x97,0xbc,0x27,0xbc,0x3a +.byte 0x3d,0x84,0x3e,0xc6,0xe0,0x68,0x69,0x22,0x4d,0x99,0x11,0xb5,0xce,0xa4,0x0c,0xaf,0x2b,0x1c,0x26,0x8d,0xd2,0xc4,0xab,0x67,0x52,0x6b,0xac,0xc5,0x7c,0x22,0xee,0xa9,0xbd,0x61,0x79,0xbb,0x71,0x02,0xfa,0x52,0x72,0xb2,0x6a,0xb5,0x0f,0xa0,0x9f,0xba,0x35,0x8c,0xd8,0xa1,0x74,0x96,0x78,0xbf,0xc4,0xf5,0x83,0x21,0xba,0xd3,0x69,0xd1 +.byte 0x3d,0xb2,0x7e,0x06,0xc6,0x10,0x7a,0xa6,0x66,0xed,0xbe,0x3c,0x42,0x89,0x2f,0xc5,0xee,0x61,0x10,0x2d,0x51,0x8f,0x34,0x03,0x32,0x4f,0x01,0x77,0x02,0xfb,0x30,0xa3,0x95,0x74,0xb9,0x97,0xc2,0xc4,0xa7,0x1e,0x52,0x94,0x29,0x31,0x21,0x8b,0xb4,0x41,0x5f,0xb0,0xf2,0x89,0x54,0xb2,0x0a,0x9b,0x06,0xba,0xb4,0xb5,0x5b,0xc9,0xad,0xeb +.byte 0xdd,0x62,0x97,0xf2,0xfc,0xe9,0xc5,0xcf,0x4b,0x87,0x4e,0x46,0xfa,0x58,0x38,0x62,0x0f,0xa1,0x5e,0x32,0xa2,0x52,0x2c,0x8f,0xb7,0xc2,0x90,0xdd,0x29,0xfb,0xb2,0x8d,0x38,0x85,0x4b,0x9c,0xc2,0x94,0xfd,0x0a,0xf3,0xd2,0x73,0xda,0xc6,0xdc,0xd0,0xa5,0xa5,0x3b,0x79,0x5e,0xd0,0x72,0x9d,0x06,0x6d,0x6f,0x6c,0x97,0x08,0xd1,0xc9,0xf2 +.byte 0xe7,0xd7,0xfe,0x2a,0x39,0xe4,0xf6,0xa1,0x5a,0xc7,0xe3,0x2a,0x40,0x0f,0x9b,0x5b,0xf3,0x85,0xfc,0xc9,0x23,0xa2,0xdf,0x44,0x0a,0x20,0x3c,0xc1,0x7b,0xeb,0x95,0x22,0x04,0x37,0x0a,0x77,0x2c,0xa5,0xbd,0xad,0x4b,0xf5,0xef,0x00,0xa1,0x53,0x45,0x06,0xe5,0xbb,0x6e,0x18,0x43,0xef,0xbc,0x4d,0x6e,0xae,0x2a,0xa2,0x7b,0x41,0xd2,0x92 +.byte 0x68,0x92,0x98,0x0c,0xc7,0x63,0x61,0x9b,0x9c,0xaa,0x63,0x0a,0x78,0x6b,0xf2,0xde,0x60,0x2e,0xc0,0x5e,0x60,0xca,0x68,0x87,0x82,0x13,0x2c,0x9f,0x2d,0x70,0x1b,0xcb,0xe3,0xfd,0x12,0x4b,0x48,0x83,0x9c,0x7c,0xea,0xde,0x19,0xe6,0xa3,0x23,0x9b,0xcd,0xeb,0xef,0x74,0x85,0xb0,0x55,0x2d,0x3f,0xa9,0xac,0xef,0x1f,0xd6,0xbc,0xd8,0x33 +.byte 0x58,0xa9,0x73,0x7c,0x9a,0xee,0x08,0x06,0x3d,0x4b,0xa5,0xee,0x37,0x9f,0xf6,0x6e,0x61,0xc9,0x42,0x94,0x89,0x4d,0x36,0x8d,0x23,0x96,0x57,0x17,0x0f,0x91,0xb1,0xea,0x0d,0x33,0xc5,0x00,0xb8,0x02,0xab,0x9e,0x68,0x75,0xf0,0x80,0x79,0x78,0xae,0xe5,0x59,0x58,0x9b,0xd4,0x1a,0x62,0x37,0x7c,0x61,0xa0,0x43,0x76,0x6a,0x00,0x44,0xc7 +.byte 0x5e,0xf4,0x88,0x39,0x43,0x32,0xcb,0xd7,0x78,0x16,0xcf,0x12,0x1b,0x4e,0xae,0xb3,0x6a,0x0b,0xb1,0x52,0x4b,0x3c,0x4f,0xd5,0x44,0x95,0x3f,0x5c,0x84,0x15,0x25,0x1c,0x97,0x6b,0x5a,0x05,0x1b,0x45,0x7e,0x1d,0x28,0x24,0x8b,0x8a,0x6d,0xe9,0x11,0xe2,0xdc,0x83,0x3e,0xc4,0x7b,0xb0,0xd9,0x5a,0x0e,0x11,0x5c,0x3d,0xa9,0x78,0xcb,0xcd +.byte 0x3a,0x1f,0x5e,0x57,0x5e,0x59,0xae,0xc5,0xb6,0x37,0x80,0x2f,0x63,0x7c,0xef,0xc2,0x8e,0x81,0xbb,0x6f,0xf0,0x1b,0xbf,0xbc,0x71,0xa5,0x97,0x59,0x98,0x87,0xac,0x7d,0x55,0x79,0x4a,0x47,0x32,0x6c,0x9d,0x79,0x91,0x6b,0x22,0x9b,0xec,0xf7,0x9d,0xd4,0x87,0xd1,0x57,0xb6,0x13,0x91,0x54,0x8f,0x88,0x14,0x19,0x08,0x93,0xe7,0x29,0x26 +.byte 0x01,0x09,0x0d,0x44,0x16,0xc8,0x90,0x99,0x80,0x04,0x5b,0xbf,0x5a,0xa0,0x73,0xd3,0x85,0xdc,0x9c,0xa9,0xbb,0x8f,0x59,0x5e,0x28,0x01,0x6c,0x13,0xce,0x92,0xe8,0x10,0x85,0x81,0x5f,0xc8,0x5f,0x52,0x84,0x33,0x87,0x28,0x5f,0x52,0xc7,0x68,0xc6,0x49,0x9f,0xa6,0x4b,0x0e,0x11,0x7b,0x94,0xf7,0x87,0xd2,0x8e,0xdb,0x5e,0x6b,0x6b,0xe5 +.byte 0x40,0x12,0xc2,0xf1,0x57,0xa3,0x72,0x7a,0xbf,0x8b,0xee,0xe7,0xd2,0x84,0x53,0xae,0x06,0x7c,0xf8,0x85,0x3a,0x2a,0x0f,0x45,0xf9,0xe1,0x61,0x15,0x59,0xc7,0x2e,0x64,0xe1,0xbe,0x95,0xe1,0x64,0x1a,0xca,0xcd,0x2c,0xb9,0x71,0x63,0xa9,0xea,0xdb,0x49,0xcd,0xdb,0x36,0x1f,0x9e,0x1f,0x93,0x01,0xdd,0xe0,0x42,0xe7,0x59,0xe7,0x24,0xcd +.byte 0x57,0x4a,0x16,0xbd,0x91,0x4f,0xbf,0x05,0x54,0xea,0xed,0x9b,0xfd,0xd0,0xb8,0xcf,0xad,0x54,0xfc,0xac,0x0c,0x10,0x4f,0xbc,0x9e,0xe0,0xb5,0x79,0x0a,0x64,0xa9,0x41,0xc1,0x6c,0xd0,0x19,0x7e,0x45,0x76,0x3f,0x1f,0x58,0xab,0x6f,0xd5,0x85,0x70,0x89,0x1d,0x11,0xc7,0x93,0x31,0x5c,0x4f,0xae,0xa8,0xc6,0xde,0x81,0x04,0xe1,0x93,0x9c +.byte 0x82,0x44,0x23,0x5d,0x0e,0x23,0xf7,0x3a,0x94,0x01,0x3f,0xe2,0x69,0x3f,0xfc,0x72,0x37,0xd2,0x51,0x73,0xbb,0xd2,0x67,0xa9,0xac,0xb1,0xea,0xa5,0x09,0xdf,0x65,0x4e,0x08,0x6a,0xff,0x3f,0xdf,0x12,0xb8,0x65,0x04,0x2c,0xb4,0x91,0xd0,0x0b,0x4e,0x16,0xec,0x9c,0x7f,0xe6,0x1c,0xec,0x7d,0x83,0x68,0x63,0x0d,0x40,0xb9,0x38,0xda,0xa9 +.byte 0x8d,0x3c,0xfd,0xd2,0x54,0x26,0xa0,0x83,0x94,0x48,0xe1,0xb0,0x12,0x5d,0x1b,0x5c,0x66,0xad,0x6e,0xbc,0xf5,0x84,0x9e,0x13,0xb2,0x6b,0x1d,0x5f,0x8a,0xaf,0xf7,0x22,0x76,0x2b,0xf2,0x4b,0x37,0xb7,0x9d,0xea,0x10,0xb2,0x2d,0x01,0x5a,0x9a,0x11,0x29,0x7c,0xb2,0x6e,0x39,0x02,0xab,0x18,0x0d,0x47,0x15,0x13,0xfa,0x9f,0x35,0x38,0xc7 +.byte 0x1b,0x74,0x7d,0xe0,0xd8,0x4d,0xa4,0xc9,0x10,0x5e,0xd1,0x88,0x7d,0x14,0x40,0xda,0xd0,0x22,0x92,0x6a,0x44,0x0d,0x73,0xc1,0xb2,0xac,0x43,0xa9,0x0a,0x19,0xc6,0xf1,0x5e,0x8b,0xf0,0x9d,0xb4,0x93,0x71,0x5f,0x7a,0x2b,0xd7,0x3e,0x42,0x1f,0x5f,0x80,0x60,0x3a,0x40,0x04,0x3f,0x21,0x1b,0x07,0xd5,0xd8,0xc6,0x15,0x9a,0x31,0xac,0x81 +.byte 0x3c,0xa2,0x42,0xba,0x63,0xc4,0x84,0x15,0x0a,0x79,0xdb,0xd9,0x8b,0xde,0x6f,0x35,0x74,0x7c,0x06,0x66,0x9a,0xec,0x4d,0xd3,0x0c,0xaa,0x16,0xb3,0x68,0x02,0xb7,0xd8,0x93,0x7f,0xa2,0x86,0x05,0x3f,0x32,0xe0,0x29,0x86,0x32,0x6f,0xc3,0xd1,0x59,0x68,0xf5,0x6d,0x50,0x5b,0xc0,0xe8,0x0e,0xed,0xe4,0x4a,0x50,0xbd,0x24,0x50,0xcb,0x2b +.byte 0x9e,0xad,0x0d,0xbc,0x90,0x90,0xf7,0x23,0x32,0xfe,0x01,0xba,0x7c,0x27,0xc9,0x44,0xd3,0x25,0xc5,0xa0,0x74,0x9b,0xf3,0x22,0xb1,0xf9,0x22,0x62,0x10,0x2d,0x18,0xf5,0x35,0xe8,0xa7,0x4c,0x80,0xdb,0x27,0xb2,0x09,0x80,0x70,0x7d,0x25,0xd6,0x57,0xf6,0xdb,0x91,0x4b,0xfa,0x5c,0x33,0x80,0x4e,0x08,0x0a,0x60,0x06,0xdc,0x65,0xc8,0x29 +.byte 0x3c,0x0c,0xbd,0xca,0x6a,0x4c,0x0d,0x84,0x3a,0x73,0xd4,0x66,0xa4,0xab,0xa8,0x03,0x3f,0x9d,0xaf,0x61,0xae,0x2d,0xd7,0x91,0xad,0xef,0xa5,0x8f,0x84,0xb4,0x3a,0xd0,0x25,0x58,0x95,0x0c,0x9a,0x6a,0x3c,0x74,0xef,0xcd,0x81,0x2d,0x32,0x2a,0x4c,0x4a,0xfb,0xb0,0xfd,0xd4,0xed,0xbb,0xb4,0x7c,0xe5,0xda,0x0e,0xf2,0xfb,0xc5,0x77,0x22 +.byte 0x47,0xfa,0x9a,0x17,0x62,0x8b,0xc9,0x4b,0xfe,0x20,0x20,0x02,0x1e,0x11,0x9c,0xd5,0x67,0x8f,0x5a,0xf3,0x69,0xc1,0x9b,0xd9,0xfa,0xbb,0x2c,0x68,0xe0,0xe6,0xfc,0xb3,0xa9,0xf6,0xf1,0xe9,0x1b,0x8e,0x4b,0x5d,0x95,0x39,0x39,0x58,0xaf,0x82,0x19,0x07,0xd3,0x97,0x46,0xbd,0xce,0xc7,0x9d,0xbe,0x15,0x7f,0x5a,0xe6,0xea,0x37,0x1d,0xdc +.byte 0x17,0x13,0x83,0xd0,0x3a,0x3e,0x87,0x5f,0x01,0xad,0xa1,0x20,0x1f,0x01,0xac,0x19,0x77,0x45,0x6e,0x5b,0xeb,0xdf,0x66,0xce,0xff,0xc5,0x7e,0x46,0x47,0xca,0x4c,0xda,0xdf,0x50,0x74,0xef,0x82,0x43,0x76,0xa0,0xbe,0x39,0xea,0x48,0x38,0x56,0xdd,0x9d,0x5c,0x27,0x3f,0x40,0x54,0xe1,0xce,0xff,0x38,0x78,0x02,0x3b,0xc1,0x8b,0xa2,0x7f +.byte 0x31,0x11,0x8d,0x8e,0x35,0x88,0x9f,0xe8,0xe7,0x30,0x72,0xa2,0x76,0x83,0x56,0x8c,0x4c,0x3f,0x43,0xaa,0x35,0x64,0x83,0xbc,0xec,0x17,0x8b,0x50,0xd9,0x5b,0xb0,0x9f,0x67,0xd5,0xd1,0xb7,0x93,0x39,0xe2,0xc2,0xb1,0xb9,0xcd,0x0e,0x70,0xec,0x77,0x64,0x59,0x9e,0xd0,0x44,0xa7,0x79,0x82,0xa8,0x54,0xfa,0x42,0x99,0x26,0xfe,0x40,0x53 +.byte 0x21,0x58,0xe4,0x2e,0x06,0x96,0x84,0x8b,0x80,0xf4,0xe8,0xf0,0x94,0xc3,0xcf,0x86,0xce,0xea,0x1d,0x82,0x67,0xcf,0xf8,0x79,0x54,0x83,0x10,0xb9,0xa5,0xea,0xce,0xeb,0x82,0x62,0xcf,0x45,0x8a,0x9d,0xeb,0x9c,0xb1,0xa0,0xf3,0xe8,0xff,0x96,0x14,0x33,0x7c,0x51,0x75,0x4d,0x00,0x0a,0xe6,0x50,0x15,0x28,0xc8,0x31,0x75,0x71,0xb5,0x8e +.byte 0xab,0xe2,0x61,0x06,0xa3,0xf6,0x03,0x12,0xb2,0x73,0x67,0xd7,0x66,0xcc,0x24,0x45,0xfb,0x9b,0x22,0x42,0x3b,0xef,0x1d,0x42,0xcc,0xc9,0xd4,0xb0,0xa5,0x3c,0x66,0xcd,0x8b,0xb4,0xf1,0xcc,0x58,0xcd,0xea,0xa2,0x0a,0x88,0xc0,0x7c,0x1b,0x6d,0x72,0x35,0x57,0x90,0x7b,0xb8,0xd4,0x17,0xe8,0x83,0x15,0x30,0x5d,0x8c,0xb7,0x1a,0x42,0x98 +.byte 0xb6,0xea,0xc9,0x53,0x27,0x50,0x1d,0x2f,0x39,0xeb,0xd6,0xc1,0x62,0x8d,0x1e,0xe1,0xde,0xb1,0xae,0xac,0xde,0x46,0x7b,0x66,0xa4,0xa6,0x79,0x55,0x79,0xf0,0x89,0x41,0xa3,0x01,0xba,0xbb,0x19,0x0c,0xdc,0xff,0x86,0x23,0xe3,0xca,0x60,0x88,0xc2,0x50,0x32,0xe2,0xd8,0x7e,0x5a,0x41,0x68,0x0f,0x5e,0x80,0x6a,0x9f,0x0b,0x33,0x8e,0x91 +.byte 0x99,0xd8,0x3f,0x81,0xe9,0x8a,0xaf,0xa7,0x0a,0xe5,0xa9,0x23,0x1c,0xe0,0x19,0x7e,0x88,0xd6,0xbc,0x08,0x13,0xa5,0x49,0x07,0x86,0x5a,0xef,0x30,0x33,0xd8,0xcc,0x6e,0x2e,0x1b,0x17,0xa6,0x8c,0xff,0x08,0x7a,0xf3,0x99,0xab,0x64,0x69,0xf6,0x77,0xa8,0xeb,0x88,0x98,0xbe,0xea,0x9f,0x5e,0xe1,0xb6,0x8c,0x68,0xc1,0xdd,0x9b,0x91,0xd3 +.byte 0x7c,0x30,0x62,0xc2,0x61,0xa1,0xcf,0x66,0x1a,0x8e,0xe8,0x91,0x48,0x33,0x7a,0xe1,0x71,0x27,0x3f,0xbf,0x47,0x78,0x31,0x9e,0xf8,0x38,0xc4,0xff,0x92,0x2a,0x0a,0x0d,0x32,0x7f,0x9d,0xa1,0xcc,0xe9,0xf2,0xfd,0xa9,0xf0,0xdc,0xd6,0xbc,0xe5,0xec,0xe9,0x26,0x91,0x0b,0x34,0xcb,0x3a,0x16,0x76,0xb1,0x90,0x08,0x14,0xec,0x6b,0x01,0xa6 +.byte 0xa7,0x45,0x18,0x38,0x94,0x38,0x15,0x9a,0x4a,0x4d,0x16,0x03,0x17,0xfe,0x09,0x93,0x2d,0xbe,0xff,0x10,0xc5,0xad,0xb8,0x47,0x6e,0x5e,0x59,0x24,0x6a,0x55,0xef,0x86,0x57,0x1c,0xba,0x8a,0x0c,0xe3,0xe3,0xdc,0xc5,0x3a,0x2e,0xe8,0x89,0x6c,0xb4,0x85,0x22,0xf0,0x6d,0x6e,0x94,0x28,0xd8,0x06,0x72,0x1c,0xa7,0x9b,0x67,0x21,0x35,0x69 +.byte 0xa2,0x0a,0x22,0x09,0x55,0xe7,0x9c,0x17,0x56,0x15,0x76,0x7e,0x2e,0x29,0xf1,0x5f,0x4b,0x1f,0xff,0x58,0x58,0xeb,0xc1,0x42,0x47,0x40,0x98,0x5b,0x34,0x6c,0x4c,0xa3,0x0a,0x3e,0x01,0xf3,0xf1,0x61,0x57,0x91,0x23,0xc8,0x48,0x0f,0x66,0x9d,0x08,0xc8,0x3b,0x18,0xc3,0x78,0xc7,0xb4,0x9a,0x89,0xe7,0x49,0x72,0x26,0xd3,0x16,0xe4,0xcf +.byte 0xb0,0xde,0x5b,0x01,0xd9,0xb9,0xc7,0x83,0x1a,0x64,0x65,0xf8,0x0c,0x49,0xad,0x60,0xd5,0x2c,0x6b,0x75,0xe0,0x3f,0x8a,0x64,0x81,0xbb,0xee,0x7b,0xae,0x53,0x94,0x2b,0xc6,0x76,0x23,0x84,0xa2,0xb2,0x33,0xb3,0xae,0x02,0x1f,0xeb,0x3c,0x27,0x22,0xc0,0x54,0xdc,0x1c,0x18,0xa2,0x04,0x12,0x4f,0xd7,0x24,0xa9,0x49,0x44,0xd9,0xbf,0xd8 +.byte 0x0c,0xb9,0x49,0xe3,0x84,0x29,0x27,0xd0,0x8d,0xb1,0x52,0x27,0xfc,0x0e,0xd7,0x88,0x39,0x64,0x76,0x49,0xd0,0x43,0xc4,0x3c,0x87,0x65,0x5f,0x90,0x49,0xde,0x27,0xc0,0xd4,0x1b,0xd4,0xdb,0x3f,0xfd,0x66,0x73,0x19,0x30,0x0b,0x29,0x00,0x5e,0xbc,0xbf,0x5b,0xd4,0x5c,0x54,0x0a,0xbb,0xa9,0xc7,0x09,0xd5,0x2d,0x89,0x0d,0x1c,0x9b,0x76 +.byte 0xf2,0xea,0x5e,0x68,0x7f,0xdf,0xce,0xcd,0xdb,0x0e,0x93,0x98,0xa7,0xa3,0xc2,0xb1,0x66,0xa6,0xb8,0xfc,0xcd,0xf1,0x3b,0x7d,0x49,0x8f,0xc6,0x25,0x56,0x3c,0x04,0x46,0xb5,0x12,0x89,0xc1,0x0a,0xc3,0x70,0x42,0x4b,0x4c,0x5c,0x0c,0x7d,0x4d,0x9c,0x4b,0xfd,0x7f,0xa1,0xbc,0xb6,0x5a,0x5b,0xe1,0xa0,0x07,0xa8,0x57,0x95,0x73,0x4e,0x2d +.byte 0x88,0x41,0xba,0xcd,0xbe,0x20,0xfa,0x73,0x87,0x7c,0x66,0x8c,0x5f,0x73,0x8d,0xd5,0x6b,0x81,0xd3,0xed,0x4c,0xce,0x70,0x76,0x8d,0x98,0xb8,0xf1,0x31,0xa3,0x10,0x71,0xf8,0x5e,0x20,0xdb,0x9d,0xf4,0x1b,0x54,0xcf,0xe1,0x32,0x3b,0x74,0x91,0xf5,0x0f,0x35,0xca,0x2d,0x59,0x15,0x47,0x78,0xf8,0x2f,0x5f,0xb4,0x23,0xd6,0x8f,0x61,0x85 +.byte 0xf8,0x6b,0x6f,0xc6,0xe0,0x04,0x63,0xcc,0x05,0x8f,0x8d,0x8a,0xaa,0xbb,0x8a,0xa5,0x6a,0x04,0x55,0x1c,0x3d,0x73,0x06,0xf4,0x2f,0x07,0xd4,0x84,0x8a,0x6a,0x4c,0x1f,0x4e,0x1b,0xf2,0xfd,0x26,0x7a,0x5b,0xb0,0x5d,0xcb,0x86,0xb4,0xe8,0xb1,0x68,0x41,0xc9,0xb0,0x47,0x72,0xc0,0x2a,0x7f,0xda,0x30,0x79,0x08,0xd9,0xc0,0x38,0xc3,0x46 +.byte 0xc2,0xdf,0xb4,0xe8,0xe2,0x3f,0xc4,0xcd,0x32,0x10,0xe0,0x32,0x3d,0x40,0xbf,0x77,0xf5,0x14,0xfd,0x89,0x2c,0x7b,0x51,0x2d,0xdb,0x8f,0x40,0x9a,0xb2,0xa7,0x43,0x9b,0x80,0x1b,0x77,0xb2,0x2c,0xe0,0x56,0xb6,0x51,0xea,0xbb,0xe7,0x45,0x3c,0xdb,0xfc,0xc4,0x98,0x1f,0x9d,0x70,0xfd,0xbe,0x9d,0xac,0x4c,0xe5,0xa9,0x9d,0xbb,0x56,0x24 +.byte 0xb3,0x85,0xe7,0x37,0x26,0x2a,0x75,0x5d,0x3d,0xd8,0xb6,0x55,0xa2,0x24,0x44,0xee,0x50,0xb5,0xfd,0xd5,0x3e,0xc3,0x5d,0x78,0xb5,0xc1,0x8a,0x35,0xf9,0x4d,0x57,0xc5,0x77,0xea,0x7a,0x15,0x18,0x3c,0x33,0x1e,0x39,0x9b,0xb4,0x7b,0xc7,0xcd,0xd7,0x13,0x46,0xe3,0xf1,0x21,0xf4,0x8f,0x35,0x66,0xd6,0x0e,0xa1,0x72,0x17,0x0b,0x7a,0x43 +.byte 0xa3,0xcd,0x56,0x93,0x9b,0x2b,0xf6,0x7d,0xd5,0xec,0xa4,0x9c,0x6e,0xad,0x5f,0xc4,0xd2,0xe6,0xc2,0xdf,0x59,0x1e,0x92,0x27,0x87,0x39,0xb8,0x5e,0x84,0x3f,0xc9,0x72,0x79,0xcf,0x48,0xcb,0x22,0x4e,0xd8,0x09,0xf8,0x1f,0x76,0x63,0x9b,0x03,0xb4,0x21,0x06,0x86,0xa3,0xe5,0x67,0xf2,0x97,0x09,0x9d,0xba,0x99,0x8d,0x99,0x5d,0x70,0xff +.byte 0x48,0x0f,0xee,0xa9,0x3b,0xc6,0xf9,0xc7,0x36,0x84,0x8d,0x66,0xe1,0xa5,0x03,0x60,0xc9,0x07,0x48,0x1c,0xf2,0x62,0x3b,0xf2,0x2c,0x34,0x62,0x99,0xbc,0x6c,0xb3,0x6a,0xbf,0x93,0xfa,0x59,0x33,0x34,0x5b,0xb7,0xf0,0xe0,0xaf,0x17,0x05,0xfe,0xc5,0xe5,0x08,0x8e,0x3b,0x80,0x3e,0xe1,0xe2,0x08,0x43,0x57,0x29,0x46,0x39,0x82,0xfa,0xc5 +.byte 0x5c,0x5e,0x24,0xba,0x01,0xbf,0xbb,0x2f,0x14,0x08,0xbc,0x21,0x85,0xf4,0x98,0xaa,0xa8,0xed,0x31,0xd2,0xfd,0x1f,0x32,0x0c,0x4b,0x61,0xbd,0x2e,0x7d,0xcd,0xcb,0x67,0xe0,0x4b,0xd2,0x3b,0x0d,0x80,0x8c,0xdd,0xc4,0x6d,0x3b,0xf0,0x25,0xd3,0x95,0xb4,0x69,0x64,0x51,0x63,0x09,0x0d,0x0f,0x7d,0x63,0x12,0xb5,0x21,0x95,0xad,0xff,0xff +.byte 0xc0,0xc7,0x97,0x6b,0x5a,0x24,0x6a,0xa5,0x97,0x40,0xc6,0xb0,0xb2,0x35,0x10,0x2e,0x4f,0x5a,0xb8,0x04,0x80,0x81,0x9a,0x09,0xf3,0xcf,0xa2,0xe9,0xd7,0xc7,0x6a,0x43,0x2b,0x74,0x70,0x26,0x66,0x50,0x1e,0xcd,0x1d,0x9e,0x78,0x7a,0xb6,0x6c,0x4d,0xce,0x9b,0xae,0x9e,0xd1,0x14,0x8a,0x63,0xb0,0x9b,0xd1,0xf3,0xec,0x05,0xed,0x72,0xf3 +.byte 0x38,0xfb,0x96,0x31,0xfa,0x12,0xd5,0x97,0x10,0x71,0xc8,0x20,0x5a,0x21,0x62,0xc7,0xdd,0x70,0x41,0x7e,0xf5,0x40,0x5e,0x7c,0xdd,0x15,0xea,0x9c,0xce,0x9d,0x92,0x50,0xf6,0x4a,0x56,0x43,0xdd,0xeb,0xc3,0xfc,0x3f,0x3c,0x8a,0xac,0x70,0x06,0xd4,0x30,0xc4,0x1c,0xfd,0xcf,0x08,0x40,0xfc,0x19,0xb9,0xce,0x25,0x21,0x65,0x8d,0x50,0x24 +.byte 0xad,0x17,0xa7,0x42,0x9d,0x19,0x75,0xd0,0x70,0x6f,0xee,0x15,0xb4,0x8e,0xb2,0x70,0xef,0x59,0x20,0x6a,0x2f,0xd7,0x23,0x38,0xe7,0x25,0x0c,0x5c,0x70,0xd0,0x21,0xee,0x1a,0x9e,0x13,0x2e,0x0b,0x63,0x64,0x9a,0xb3,0xd7,0x55,0xf1,0xfb,0xac,0x47,0x4a,0x24,0xa9,0x0b,0x64,0xc5,0x24,0xf1,0xb9,0x82,0xf0,0x93,0x7a,0x32,0x73,0x66,0x17 +.byte 0x8c,0x6d,0xaa,0xc2,0xd1,0x08,0xd8,0xfa,0x47,0xfd,0x0e,0xc2,0x9e,0x47,0xce,0x9e,0xbd,0x10,0xb9,0x4c,0x47,0xa6,0x00,0x37,0xaf,0x6b,0x34,0x7e,0x86,0xb2,0x30,0xac,0x05,0x60,0x7b,0xfc,0x6d,0x47,0xab,0x45,0x66,0x81,0x59,0xb2,0x13,0x84,0xc2,0x07,0x64,0x17,0x64,0x20,0x9a,0x62,0xfa,0x0e,0x7b,0xf1,0x3d,0x87,0xa3,0x0d,0xaa,0x99 +.byte 0x08,0x96,0x01,0x5a,0x47,0x0c,0x70,0x01,0x5f,0x16,0xdf,0x79,0xfd,0xce,0x47,0x1e,0xe0,0xb6,0xbe,0x52,0x17,0x7f,0xd7,0x05,0x8b,0xa7,0x3c,0xb0,0xe8,0xfb,0x22,0xee,0x7c,0xfc,0xb2,0x33,0xb5,0xd4,0x7e,0x87,0xd3,0xcb,0x22,0x91,0x1b,0x59,0xe5,0xbf,0x79,0xb8,0x90,0xfc,0xf5,0xa1,0xc9,0x3b,0x71,0x47,0x84,0x52,0x32,0x18,0x2c,0x91 +.byte 0x81,0xa4,0xfe,0xdc,0x5e,0xf6,0x69,0xbf,0x2a,0x33,0x7b,0xc3,0xc3,0xdb,0xe7,0xe2,0xb4,0x4d,0xc5,0x47,0x62,0x74,0x84,0xb3,0xd5,0x41,0x95,0x94,0x26,0xc1,0x4a,0x27,0xd3,0x46,0xec,0x9f,0xb6,0x0e,0x79,0x1b,0x24,0x5f,0xa4,0xdf,0x33,0x2d,0x89,0xb5,0x96,0x2a,0xb9,0x2c,0x0a,0x1b,0xf2,0xd6,0x38,0xc4,0x73,0x58,0xb2,0xc4,0x9b,0x3e +.byte 0x2f,0x73,0xbc,0xdb,0x6f,0xb6,0x7f,0x7e,0x68,0x18,0xc4,0x49,0x41,0xcb,0xff,0x45,0x67,0x1d,0x41,0xa0,0xc3,0x17,0x5c,0x1e,0x4d,0xa7,0xdd,0x25,0x4b,0xe2,0xf7,0xfc,0x53,0x9f,0xf6,0xf9,0x1a,0x73,0xfc,0xc0,0xcd,0x93,0x38,0x4d,0x02,0x4e,0x33,0xf8,0x6f,0x0b,0x5b,0x33,0x52,0xff,0x20,0xe1,0xea,0x37,0x44,0x82,0x26,0xa8,0xf3,0x91 +.byte 0x33,0xa5,0x60,0x92,0xfc,0xe1,0x7e,0x14,0x8f,0xd1,0xd6,0xda,0xdb,0x3f,0x37,0xf1,0xf1,0xed,0x91,0x5b,0x60,0x2a,0x9d,0x31,0xd3,0xb5,0xd8,0xe8,0x78,0x8d,0x59,0x0b,0x85,0xdc,0x45,0x02,0x33,0x9a,0x5e,0x43,0x9b,0x54,0x09,0x4f,0xac,0x79,0x7e,0xa7,0x64,0xe1,0xbb,0x67,0x27,0xb7,0x34,0x0a,0xd3,0xa3,0x57,0x0b,0x8c,0x46,0x9a,0xc7 +.byte 0xe2,0x4e,0xb1,0xf5,0x2b,0x91,0xbf,0x5d,0xc2,0xf7,0x21,0xb6,0x74,0x42,0xf9,0xfb,0x01,0x97,0x0d,0x65,0x93,0x14,0x6f,0x60,0x5b,0x49,0x33,0x6e,0xb4,0x3b,0x1c,0x02,0x96,0x91,0x2e,0x32,0x29,0x66,0x44,0x52,0xc0,0xab,0x2f,0x27,0x27,0xa0,0x80,0xe6,0xc9,0x63,0x08,0x34,0x23,0x5e,0xb4,0x20,0x24,0x2b,0x84,0x94,0xbf,0x29,0xef,0x86 +.byte 0x8a,0xb2,0x1d,0xaf,0x98,0xc0,0xf6,0x81,0xd0,0x81,0x18,0xd1,0x2e,0x53,0xae,0xd2,0xe4,0xc6,0x7d,0x0b,0x13,0x62,0x83,0xe7,0xe5,0xc7,0x93,0x34,0xd3,0xd2,0x4c,0x0f,0x44,0x7f,0x20,0xf0,0x12,0x0d,0x71,0x26,0x45,0x97,0xda,0xee,0x9b,0x69,0x3d,0x32,0x41,0x7f,0x21,0x19,0x42,0xfc,0x8b,0x96,0xb6,0xdd,0xcb,0x7a,0x41,0x57,0x24,0xd6 +.byte 0xd6,0xd2,0x39,0xf4,0xad,0x4e,0xfb,0x0e,0x88,0x8e,0x8a,0xd5,0xb2,0xa3,0x7b,0x66,0x66,0xb9,0x47,0x55,0xd4,0xa2,0x4c,0x3e,0xe6,0x85,0x2e,0xaf,0x1b,0x6b,0x9b,0xb1,0xf9,0x66,0xfc,0xdd,0xb7,0xab,0x50,0x43,0xe4,0x5e,0x35,0x0f,0x59,0x8c,0x4f,0x5a,0xc2,0xe2,0xf6,0x65,0x8e,0x7c,0x8c,0x4b,0x0e,0x92,0x71,0x53,0x1d,0xde,0xd3,0xcb +.byte 0x6b,0x73,0x56,0xdb,0x7f,0xde,0x51,0x61,0xff,0xbd,0x07,0xdb,0xd4,0xbd,0x78,0x55,0xf3,0xe6,0x26,0x45,0x4a,0x55,0x8c,0xf0,0xc1,0x95,0x2e,0x20,0xc3,0x26,0x6f,0x2e,0x0b,0xba,0x7c,0x5e,0x64,0xc1,0x74,0xb7,0x5c,0x0a,0x84,0x76,0x95,0xe6,0x3f,0x00,0x67,0x08,0x82,0xb0,0x9a,0x24,0x32,0xa7,0x47,0x94,0xf3,0x0f,0xee,0xe0,0xef,0x39 +.byte 0x90,0x0a,0x29,0xac,0xe3,0xbb,0xac,0xa8,0xd8,0x5b,0xc1,0xf0,0x5b,0xcf,0xe8,0x29,0x65,0x2a,0xc7,0x2b,0x05,0x05,0xf4,0xce,0xed,0x01,0x75,0x53,0x1f,0x12,0x49,0x73,0xeb,0x43,0xdf,0x6d,0x2e,0x21,0xab,0x43,0x20,0x79,0x69,0xbb,0xc1,0x92,0x41,0x07,0xe8,0x65,0x77,0xde,0x78,0x92,0x3a,0x1d,0x4d,0x93,0xd0,0xa7,0x72,0xb0,0xa4,0x9c +.byte 0x7e,0xa7,0x3b,0x60,0x7d,0x6e,0xa9,0x3e,0x25,0xdb,0xfe,0x4f,0x4b,0xb5,0x45,0x2e,0x84,0x49,0x38,0x1e,0x97,0x4c,0xd3,0x2f,0x1f,0x16,0x52,0x9e,0xe4,0xed,0x8a,0x9e,0x98,0xa1,0x19,0x07,0xf3,0xe2,0x1d,0x51,0xb8,0xe9,0xc6,0xaa,0x44,0x4a,0x71,0x21,0xdf,0xab,0xe2,0x31,0x5e,0x6e,0x33,0xe5,0x2d,0xc7,0xf2,0x14,0x92,0x5b,0x2f,0x79 +.byte 0x1b,0xd1,0xa7,0xe0,0x00,0x12,0xa0,0x88,0x71,0xfa,0x27,0x86,0x23,0x47,0x35,0xe5,0x95,0xdd,0xae,0xfa,0x22,0xea,0x08,0x83,0x85,0xc4,0x35,0x37,0xdf,0xdf,0xc2,0x41,0xa9,0x44,0x5d,0x30,0x6e,0xa0,0xdb,0xd4,0x97,0x07,0x43,0x9e,0x7b,0x95,0x50,0xf5,0x88,0x9a,0x26,0x9c,0xf9,0x85,0x6d,0x4e,0x92,0x0c,0xbe,0x04,0xd6,0x1a,0x32,0xda +.byte 0x47,0x0c,0x04,0xab,0xdb,0xc4,0xd6,0x49,0x61,0xf9,0x4a,0x90,0x5b,0x75,0x98,0xb2,0x69,0xa3,0x01,0x47,0xf4,0x60,0x03,0xc5,0x55,0x71,0x26,0x0f,0xe3,0xc3,0xb7,0xae,0xe9,0x2a,0xe8,0x3b,0x0a,0x24,0xff,0x6b,0x3b,0x6d,0x53,0xf9,0x03,0xf5,0x12,0xd7,0xf8,0xb8,0xd2,0x33,0xfd,0xcc,0x61,0xd7,0x75,0x80,0xa9,0x30,0x38,0x6f,0x78,0x5e +.byte 0xa3,0x37,0xa0,0xc6,0xf5,0x84,0x12,0x56,0xdd,0x62,0x24,0xf7,0x8a,0xf6,0x31,0xf5,0xc0,0xd5,0x94,0xa5,0x92,0xfe,0xe5,0x19,0xe7,0x97,0x6d,0x4a,0xbc,0xb6,0xab,0x05,0xa1,0x36,0x9f,0xb5,0x2f,0xf3,0x0c,0x8e,0x61,0xab,0xdc,0xe5,0x2c,0xcc,0xc7,0xd4,0x49,0xf9,0x56,0xea,0xa0,0x93,0x4a,0x0c,0x66,0xfa,0xc5,0xa2,0xfa,0x75,0x31,0x1e +.byte 0x27,0x69,0x45,0x8e,0x15,0x8d,0x3c,0xde,0x86,0xd9,0x95,0xc7,0x95,0x7a,0xde,0x97,0xbe,0x8b,0x7a,0xa9,0x8b,0xc5,0x2d,0xea,0x96,0xde,0xf0,0xad,0x5c,0x7d,0xd0,0xfb,0x9a,0x34,0xbe,0x2f,0x35,0x48,0x79,0xd7,0xff,0x6b,0x10,0x28,0x08,0x9d,0xa6,0x7e,0x8b,0xdd,0xdd,0xcb,0xc5,0xc4,0xfe,0x29,0xd4,0x8e,0x36,0xa6,0x2a,0x16,0xbd,0xfc +.byte 0x8e,0x67,0x9b,0x9a,0x37,0xe3,0x08,0x11,0xbb,0x02,0x09,0x49,0x15,0x67,0xa3,0x23,0x3b,0xb3,0x2c,0xc0,0x3b,0x88,0x33,0xf7,0x06,0x83,0x86,0x65,0xc8,0xb2,0x2a,0x43,0xd5,0xd8,0xd1,0x65,0x7c,0x87,0xa6,0xb5,0x93,0x3a,0x44,0xc2,0xbd,0xd9,0x78,0x23,0xf6,0xa3,0xff,0x3b,0xbe,0x8b,0xf1,0x74,0x95,0xa0,0x1e,0xa9,0xe3,0xa8,0x27,0xd4 +.byte 0x0d,0xb2,0x18,0x90,0x61,0x4a,0xa3,0x8a,0x57,0x5a,0xc3,0x5f,0xf2,0x8a,0x86,0x03,0xa7,0x6e,0xd1,0x48,0xa0,0x1f,0x89,0x32,0x96,0xe6,0x85,0xbc,0xbc,0xd5,0x91,0x89,0xb0,0xb4,0x58,0x0c,0xfe,0x64,0x1c,0x55,0xba,0xcf,0x03,0x49,0x60,0x4f,0x4a,0x50,0x24,0xdb,0x02,0x2a,0x56,0xc1,0x57,0xa6,0x3b,0xbe,0xa6,0x21,0xff,0x8b,0xc3,0x63 +.byte 0xb2,0xca,0x47,0xfe,0xd1,0xdc,0x90,0xba,0x24,0x0c,0x15,0x23,0xec,0xf1,0x35,0x4a,0xab,0x3a,0xf3,0xf0,0xf0,0xb4,0x04,0x58,0x16,0x4f,0xf9,0xe3,0x06,0x9b,0x3f,0xd1,0x9f,0x95,0xc7,0xcf,0x0e,0x93,0x87,0x30,0x49,0x0a,0x18,0x8a,0xc4,0x58,0x10,0x07,0x93,0xa7,0x85,0xd5,0x2a,0xe7,0x4c,0xd0,0x54,0x1d,0x8b,0x40,0x3e,0xb9,0x94,0xc7 +.byte 0x3f,0xc5,0xad,0x38,0x5a,0xf4,0x87,0x60,0xda,0x5e,0x74,0x5d,0x3d,0x81,0x85,0xba,0x68,0xee,0x71,0xda,0x9e,0x4b,0x6b,0x8f,0x56,0x0d,0xe5,0x31,0x3a,0x03,0x73,0x28,0x4f,0x8b,0x50,0xf8,0x15,0x63,0x42,0x45,0x65,0xb3,0x7b,0x00,0x0f,0x24,0x01,0x09,0x4b,0x74,0x09,0x28,0xdf,0x02,0x36,0x58,0xec,0x15,0x18,0xba,0x45,0x30,0x33,0x95 +.byte 0xac,0xe2,0x8d,0x8c,0x20,0xdf,0xba,0x4d,0x8f,0x1d,0x1f,0x05,0x25,0x7e,0x8c,0xea,0xa3,0x92,0x8b,0x19,0xd9,0x51,0xa6,0x35,0x39,0x35,0xd4,0x8b,0x35,0x7d,0x1a,0xc0,0x84,0x3d,0x1b,0x21,0x28,0x3b,0x12,0x73,0x92,0xc7,0xf6,0xf4,0x86,0xc5,0xba,0x9e,0x2d,0x30,0xf0,0x9b,0xe7,0xf1,0x65,0x54,0x66,0x93,0xd2,0x1c,0x59,0x02,0x15,0xb5 +.byte 0x56,0x34,0xdd,0x6e,0x28,0xe1,0x54,0xe4,0x94,0x70,0x08,0x2f,0xda,0xa9,0x8b,0x44,0x5a,0x4b,0xca,0x94,0x4b,0x53,0xc0,0x30,0xd1,0x78,0x15,0x60,0x9e,0x92,0xed,0x19,0xe0,0xbc,0x0f,0xbb,0x10,0x64,0xf6,0x84,0xe2,0x4d,0x96,0x57,0x1a,0x28,0xd4,0x6f,0xe1,0x7b,0x4b,0x71,0xb7,0x01,0x7d,0x39,0x8f,0x4b,0x77,0x3f,0x04,0xf1,0x3d,0xdd +.byte 0x0d,0x21,0xd9,0x94,0x9e,0x85,0x64,0x6d,0x86,0x24,0x60,0xd8,0xa0,0x87,0xdb,0xde,0x21,0xb7,0xdb,0x36,0xf6,0x6c,0xef,0x51,0x5f,0xf5,0x46,0x26,0x9d,0xda,0x9c,0x2a,0x13,0x58,0x44,0x7b,0xd3,0x91,0xbf,0x7d,0x16,0x11,0x04,0xbb,0x01,0x17,0xbe,0x2b,0x20,0x72,0xb5,0xc6,0x5d,0x27,0x3a,0x10,0x46,0x1e,0x72,0x00,0x87,0xd4,0xb0,0x54 +.byte 0x4b,0x9f,0xb8,0xcb,0x52,0xf9,0xeb,0x7a,0x72,0x13,0x80,0xb2,0xdf,0x79,0x46,0xa7,0x0c,0x0b,0x70,0x32,0xf4,0x42,0x66,0x35,0x70,0xb5,0xb5,0x48,0x8a,0x43,0x65,0xaa,0xb8,0x29,0xe3,0xcf,0x39,0x62,0xf1,0xba,0xe6,0xee,0x08,0x13,0xcd,0x25,0x20,0xfa,0xdf,0x29,0xb1,0xe5,0x9e,0xc7,0xc7,0xa5,0xe3,0x74,0xdf,0x3c,0xea,0x33,0xda,0xed +.byte 0x6b,0x66,0xd5,0x16,0x89,0x2e,0xe7,0x7a,0x9f,0x60,0xcd,0x96,0x4e,0x81,0xcd,0x31,0x24,0xcc,0x5c,0x24,0x44,0x83,0xe5,0xd5,0x22,0xd0,0xca,0x7c,0x17,0x32,0xa5,0x13,0xaf,0xbd,0xd2,0x91,0x7b,0x3c,0x9b,0x54,0xaf,0x0b,0x51,0xf7,0x80,0x01,0x77,0x96,0x71,0x0c,0xa1,0x6a,0x15,0x91,0xe5,0x20,0xe1,0x0a,0x02,0x94,0xb3,0x2b,0x29,0x4f +.byte 0x13,0xbf,0x48,0x61,0x78,0x4f,0x6a,0x82,0x28,0x1b,0x82,0xa7,0xa0,0x28,0xfa,0x7e,0x7b,0x67,0x76,0x7c,0xc1,0x7e,0x89,0x91,0x5f,0x63,0xf7,0x26,0x60,0x10,0x01,0xff,0xe6,0xc7,0xea,0xed,0xce,0x6d,0xe6,0x15,0x4d,0x17,0x84,0x1c,0xc9,0xb1,0x76,0x80,0xa5,0x33,0x2c,0x9d,0xdf,0x20,0x55,0x46,0xbe,0xde,0xc6,0x76,0x7c,0x11,0x31,0xac +.byte 0xdb,0x06,0xd0,0xe5,0x29,0xdb,0x3d,0x6e,0x8f,0xbf,0x0b,0x6a,0x6e,0x83,0xcb,0x7b,0x09,0x9d,0x1f,0x53,0x17,0x67,0x99,0x34,0xb2,0x24,0xa8,0x12,0x09,0xf1,0xaf,0xf7,0x58,0xd0,0x0a,0x9e,0x50,0xa1,0x81,0xdb,0xce,0xf3,0x24,0x40,0x45,0xfc,0xa0,0x47,0xd8,0x09,0x8a,0x2b,0x7d,0x74,0x77,0x0f,0xcc,0xf8,0xd7,0xee,0xad,0x0c,0x71,0x0b +.byte 0x60,0x0b,0x0d,0x14,0x67,0x57,0xb2,0xde,0xbb,0x4d,0xdf,0x4e,0x60,0xbf,0xdb,0x93,0x87,0x60,0xb3,0x29,0x73,0x45,0xd3,0x3c,0x04,0x15,0x94,0x6b,0x29,0xf0,0x10,0x1c,0xd5,0x4b,0x2c,0xb4,0x43,0xda,0x9d,0x8f,0x41,0xb1,0xe4,0xe4,0x57,0x39,0x74,0xda,0x62,0xce,0x75,0xc8,0x2f,0xab,0xe8,0x93,0x73,0xf3,0xa7,0x4e,0x43,0xf3,0xf2,0xb8 +.byte 0x46,0x05,0xac,0xe5,0x1e,0x3f,0xae,0x70,0x8a,0xee,0xff,0x1e,0xe0,0xc2,0x21,0x56,0x14,0xb2,0xb5,0x36,0x1c,0xd6,0x0d,0x1d,0x03,0xd6,0xbf,0x0c,0x2e,0xb2,0xa9,0xf0,0x3f,0x1e,0xbf,0x4f,0xe0,0x82,0x60,0x08,0xc3,0x7a,0xc1,0x0b,0xe2,0xe6,0x28,0x21,0x6b,0x20,0x56,0x74,0x02,0x13,0x43,0x4c,0xe6,0x0c,0xd6,0x82,0x81,0xc6,0xd5,0x63 +.byte 0xb5,0xe7,0xbf,0x43,0x25,0xde,0xeb,0xa9,0x34,0xfd,0x8e,0xe5,0x67,0xc8,0xc6,0x5e,0x12,0xba,0xfa,0x66,0x50,0xed,0x61,0xe0,0x94,0x31,0xd6,0x71,0x30,0x2f,0x42,0x71,0x98,0xa0,0x5e,0x31,0x27,0x19,0xe9,0x81,0xd9,0x14,0x7c,0x09,0xa2,0x60,0x31,0x2f,0x9a,0x1c,0x77,0xee,0xf7,0x46,0x93,0x32,0x66,0x82,0xbb,0x50,0xce,0x32,0x81,0x6b +.byte 0xe4,0x46,0xc2,0xf9,0x78,0xdd,0x7a,0x19,0xbd,0x0e,0xf8,0x40,0x11,0x85,0xbb,0xe1,0x06,0x82,0xe9,0x88,0x45,0x25,0x35,0x80,0x60,0x0b,0xf0,0xf1,0x6e,0x99,0xab,0x32,0x04,0x90,0xc9,0x50,0x82,0x49,0xc9,0x75,0xf3,0xe4,0x7d,0x22,0x3e,0x48,0x70,0xa0,0xcb,0x33,0x91,0xe6,0x8f,0x2b,0x8c,0xd4,0x9a,0x13,0x0b,0x5d,0x66,0x62,0xf5,0x16 +.byte 0x8d,0x90,0x2e,0x84,0x8e,0xa1,0x90,0xfc,0x4b,0x62,0x2d,0xc3,0x1b,0x09,0x6f,0x61,0x90,0xee,0x43,0x2a,0x49,0x0b,0x16,0xea,0xa8,0x09,0x9a,0x4c,0xc1,0x73,0x8c,0xa1,0x98,0x3c,0x99,0x07,0x0c,0x55,0x4f,0x93,0xb6,0xde,0xbb,0xf0,0x26,0x92,0x43,0x63,0x83,0x7e,0xfe,0x8e,0xfe,0xbf,0xe7,0x27,0xb8,0x7d,0xbc,0xba,0xb6,0xfb,0x27,0xb5 +.byte 0xfd,0xde,0x3d,0xd7,0xe9,0x46,0x9a,0x17,0xd9,0xd7,0x84,0x9d,0x75,0x58,0x26,0x6c,0x96,0x70,0x74,0xb1,0x46,0x46,0xac,0x48,0xa2,0xce,0x6a,0x95,0xea,0xbe,0xd6,0x87,0xd6,0x48,0xc1,0x70,0x07,0xbc,0xd2,0x26,0xef,0xaf,0xdf,0x04,0xa0,0xe7,0x94,0xc8,0x94,0xcf,0x85,0xf2,0xc1,0x20,0x70,0xac,0xf2,0x0f,0x61,0x3c,0x6a,0xff,0x80,0x5f +.byte 0xa6,0x1e,0x7d,0x07,0x1a,0xd4,0xb9,0x5e,0x99,0x35,0x65,0x5c,0xef,0x45,0x59,0x45,0x18,0x6e,0x48,0x5c,0x18,0x96,0xd1,0xda,0xb0,0xfb,0xb7,0x71,0xa6,0x80,0x7b,0x88,0x65,0x73,0xab,0x2f,0xc1,0x8b,0x00,0x1e,0x16,0x9f,0x16,0x50,0x1d,0x7d,0x75,0xee,0x17,0x5f,0x52,0xba,0xca,0xc4,0xe9,0xfb,0xb5,0x1c,0x8f,0xf8,0x7e,0xd8,0xf4,0x7e +.byte 0x11,0xb6,0xf5,0x38,0x84,0x37,0x3a,0x24,0xb5,0x07,0x1c,0x7f,0x70,0xaf,0xe9,0x17,0x33,0x89,0x92,0xb1,0xb3,0xec,0x60,0x41,0x61,0xe1,0x0a,0xf9,0x11,0x7b,0xe0,0x7e,0xca,0x32,0x4e,0xa5,0xcd,0xf7,0x95,0x2c,0x6e,0x3d,0x3f,0xe4,0xa8,0x25,0xa6,0xb4,0x6d,0xb4,0xa3,0x5e,0xb1,0x9c,0x6b,0x19,0xc4,0xdc,0x02,0xec,0xfa,0x9d,0x42,0x69 +.byte 0x1e,0x48,0x3a,0xfa,0x51,0x43,0x5c,0x14,0xea,0x74,0xec,0xa6,0xf0,0xea,0x42,0xf5,0x32,0xfe,0x74,0x44,0x09,0xcb,0xa4,0xee,0xf8,0xc5,0x9a,0x66,0xbf,0xa0,0xc6,0x73,0xc0,0x29,0xfe,0xec,0x8a,0xa9,0x85,0xa5,0xa7,0x8e,0x54,0xfb,0x87,0x01,0x59,0x9c,0xb2,0x17,0x62,0xd0,0xea,0xe8,0x17,0x4d,0x67,0x82,0xa9,0xfc,0xc1,0x12,0x0c,0xfc +.byte 0x3a,0xe9,0xab,0x78,0x70,0x96,0x68,0xe4,0x10,0xd1,0x70,0x61,0xbb,0x07,0xe4,0xdc,0x8c,0xc4,0xae,0x07,0x90,0xd6,0xee,0xa5,0x43,0x0c,0xc5,0xc9,0x0a,0x55,0x42,0x90,0x70,0x18,0x31,0x13,0x3c,0x00,0x89,0xa0,0x30,0xaf,0xa1,0x91,0x33,0xe6,0xd0,0xe1,0xb4,0x99,0x2b,0x27,0xee,0x25,0x95,0x1f,0xfe,0x19,0x3a,0xdb,0x2e,0x59,0x2e,0xa0 +.byte 0x12,0xfb,0x34,0x20,0x72,0x34,0xa8,0x2b,0xeb,0xbe,0xdb,0xc3,0xab,0xdf,0x82,0x68,0x37,0x7f,0x76,0xcd,0x15,0xd5,0xf8,0x1c,0x6f,0x7a,0x33,0x51,0x86,0xf8,0x38,0x77,0x96,0x7b,0x15,0xa0,0x2a,0x6f,0xdb,0xad,0xfb,0x0a,0x86,0xac,0xee,0xc2,0xde,0xf3,0x81,0x6b,0xc3,0x09,0x93,0xaa,0x57,0x2d,0x6a,0xff,0xba,0xa0,0x93,0x75,0xc7,0x6e +.byte 0xef,0x59,0xaf,0x57,0x32,0xf6,0x0b,0x57,0x60,0x12,0x01,0x20,0xce,0xcb,0x1c,0x88,0xd1,0xe3,0x49,0x88,0xbe,0x5e,0xdf,0xc1,0x81,0x5b,0xf7,0x15,0xac,0xa8,0xc8,0x10,0x2d,0x98,0xae,0x75,0xef,0x4e,0x17,0x10,0x3c,0x95,0x92,0xf6,0xd6,0xd7,0xdd,0x0a,0xe2,0x42,0x40,0x28,0x68,0xc2,0x27,0xac,0xd3,0xca,0xa1,0xc0,0x64,0x05,0x17,0x64 +.byte 0x99,0x26,0xd3,0xb3,0xac,0x77,0xf4,0x40,0xd1,0x00,0xa9,0xc6,0x6d,0x45,0x47,0xa3,0x53,0xb7,0x13,0x61,0xc6,0x11,0xc0,0xa4,0xc9,0x2a,0x5a,0xa2,0x3a,0x27,0x0a,0x84,0xff,0xb5,0xb0,0x45,0xfe,0x38,0xb4,0xec,0x95,0x8b,0xd5,0x1a,0xf3,0xc6,0x0b,0x62,0xfa,0xeb,0xd1,0x90,0x11,0x7e,0x36,0xee,0x5c,0xe6,0xb6,0xf3,0x62,0xbf,0xe7,0xc9 +.byte 0x77,0x66,0x7b,0xb5,0x1c,0x9e,0x6b,0x21,0x84,0x8c,0x19,0xa7,0xf0,0x3b,0x9d,0xb0,0xfe,0xe6,0x0d,0x64,0xc5,0xdc,0xa2,0x4f,0x7c,0xcb,0x09,0x0a,0x2b,0x9f,0xd7,0x31,0xa5,0xc7,0xba,0x2a,0xc9,0x36,0x1f,0xc5,0x5b,0x8a,0x5b,0x9e,0x10,0x2f,0x2c,0x27,0x11,0x5c,0x9c,0x71,0x45,0x33,0x53,0xed,0x0e,0xdd,0xd0,0xb4,0x28,0x59,0x36,0xf1 +.byte 0xa3,0x97,0x20,0xf4,0x27,0x85,0x02,0x01,0x46,0xf4,0xd3,0xbc,0xf6,0xc9,0x33,0xa8,0xe1,0x13,0x99,0x2b,0x74,0x68,0x20,0xcf,0x0e,0xfb,0xba,0x0d,0xaa,0x1f,0x76,0x66,0x6e,0xa7,0x56,0x71,0x80,0x7f,0xe5,0x2d,0x60,0x53,0x5b,0x56,0x2d,0xf1,0x3b,0x95,0x95,0x94,0x8c,0x9d,0x37,0x90,0x60,0x9b,0x29,0x84,0x6e,0x93,0x22,0xb4,0x85,0xd0 +.byte 0xea,0x51,0x2d,0x80,0x7d,0xa0,0x50,0x57,0x8e,0xc3,0x58,0x37,0x75,0x05,0x37,0x4a,0xce,0x6e,0x10,0x9a,0x4c,0xce,0xfb,0x8e,0x82,0xed,0xb3,0x93,0x00,0xce,0x38,0x09,0xde,0xa1,0x92,0x23,0xd3,0xe1,0x33,0xc4,0xca,0xcb,0x42,0xc2,0x95,0x04,0x90,0xfd,0x32,0x43,0x6a,0x2c,0x8c,0x76,0xbf,0xca,0xe6,0x60,0xed,0x48,0x30,0x47,0xbc,0xba +.byte 0xff,0x00,0xfc,0xa8,0x53,0x17,0x45,0xc6,0xa2,0xc2,0xb3,0x3c,0xf1,0x1f,0x4c,0x95,0x73,0xc5,0xa3,0x6f,0x59,0xd0,0xb3,0x1e,0x12,0x27,0x0a,0xc7,0x70,0x27,0xfa,0x33,0x22,0x6a,0x25,0x3c,0x34,0x83,0x03,0x37,0xb8,0xdb,0xa9,0xc2,0xfb,0x64,0x3d,0x77,0x96,0x37,0x54,0xcf,0x18,0x31,0xce,0xe8,0xc1,0x19,0x85,0x81,0xd2,0x1b,0xcd,0x08 +.byte 0xdb,0x53,0xa2,0x61,0x18,0xf2,0xe7,0x33,0x1b,0xe3,0x21,0xd5,0x52,0x8d,0x51,0x2e,0x4d,0xf2,0x95,0x1b,0x5e,0x2f,0xcb,0xe7,0x12,0xc9,0x74,0xce,0x44,0x93,0x57,0x51,0x2b,0x9c,0x03,0x9e,0x20,0x17,0x75,0xf0,0x24,0xb3,0x1f,0x38,0x1b,0xef,0x12,0x8f,0x6f,0x79,0xbc,0xce,0x40,0xa5,0x6c,0x86,0xe9,0x92,0x90,0x53,0xd2,0x28,0x40,0x77 +.byte 0x44,0xa0,0x6f,0x11,0xf8,0x7b,0xf1,0xd8,0xd5,0x04,0x88,0x5a,0xf3,0xc6,0xa3,0xbc,0xcb,0xef,0x85,0x56,0x6d,0xa1,0x84,0x34,0xcf,0xaa,0x52,0xb1,0x76,0xed,0x2b,0x67,0x73,0xa7,0xc7,0x2b,0xfb,0x7a,0x9c,0xf9,0xdf,0xfa,0x92,0xd8,0x93,0xe9,0xd6,0xd1,0x66,0xe6,0xed,0x82,0x80,0x00,0xa3,0x40,0x3d,0xef,0xf4,0xf9,0x6c,0x6a,0xaa,0x73 +.byte 0x7c,0xc5,0xed,0x3d,0xf5,0xf5,0x9e,0x3f,0x1a,0x9a,0x29,0xd0,0xb4,0xac,0x96,0x55,0x61,0xca,0x37,0xc0,0x60,0xea,0xc5,0xc7,0x96,0x35,0xa0,0xa8,0xab,0xf7,0xeb,0x5e,0x3b,0x7e,0x54,0xb0,0x29,0x50,0xde,0x11,0x9f,0x71,0x3c,0xa5,0x32,0x32,0xe3,0xf8,0x1f,0x19,0x08,0x89,0xe6,0xc7,0x1b,0xb8,0xda,0xe3,0x98,0xd7,0xed,0x76,0x0f,0xa5 +.byte 0xc1,0x24,0x0d,0xea,0x10,0x13,0xcd,0x72,0xf4,0x44,0xb5,0x56,0xf6,0x4c,0xad,0xb7,0x43,0x6f,0x0a,0xc0,0x36,0x40,0x48,0xe1,0x4a,0x4c,0x9c,0x23,0xfd,0xde,0xaa,0x79,0x62,0xc0,0xec,0xfb,0x37,0x7f,0xbb,0xbc,0xfb,0x38,0xd0,0xaa,0x4a,0x5d,0x08,0x1c,0xa5,0x3d,0xb0,0x02,0xdc,0x5f,0xfc,0x9a,0x2a,0x6e,0x82,0x4d,0xf8,0x67,0x9d,0x2c +.byte 0x6a,0x01,0x55,0xad,0xf4,0x1d,0x02,0x3e,0xc8,0x55,0x42,0xc7,0x39,0x7b,0xcd,0xa8,0x0c,0xd2,0x46,0xc2,0x1a,0x78,0x4a,0xf1,0xb6,0xd8,0x38,0xbd,0x0a,0x9b,0x53,0xdb,0xd8,0xaa,0x1f,0x30,0x9f,0x97,0xf7,0xbf,0xff,0xf1,0x3d,0x1d,0xf2,0x3b,0xc1,0x7c,0x3a,0x63,0x5c,0xb3,0x67,0x02,0xcd,0x67,0x0a,0xf9,0x6e,0xf2,0x36,0x3b,0x36,0xa9 +.byte 0xce,0xf1,0x66,0x13,0xb7,0x8e,0xc8,0x36,0x30,0x34,0xde,0x32,0x68,0xc7,0x62,0x60,0x13,0x34,0x7d,0x66,0x32,0x69,0xe7,0x7a,0x0a,0x20,0x24,0x86,0x85,0x72,0x3c,0x7d,0x5f,0xea,0x6c,0xaf,0x70,0xde,0xfe,0x94,0xc2,0x6e,0xb3,0x0f,0xa1,0x2a,0x51,0x40,0xd5,0x5c,0xaf,0xdd,0xd9,0x7d,0x09,0x9b,0x31,0x45,0xae,0x48,0x67,0xfa,0x2d,0x11 +.byte 0x77,0xed,0x92,0x79,0x7e,0x27,0x27,0x3b,0x1c,0xa7,0xee,0x88,0xaf,0xfe,0x71,0xa7,0x0e,0x9e,0xa8,0xa5,0x11,0xd2,0x88,0x25,0x12,0x49,0x8a,0x89,0x19,0xc7,0xa8,0xa3,0xa9,0xc6,0x48,0x57,0x21,0x23,0x91,0x07,0xfe,0xb3,0x6e,0x0b,0x70,0x08,0x7b,0x1c,0xe4,0x15,0x13,0x3e,0x8a,0x43,0x80,0x1b,0xb6,0x72,0xd6,0x62,0xfe,0x3a,0x7a,0x5f +.byte 0xb9,0xd4,0x00,0xce,0x5b,0x05,0xa0,0x81,0xe5,0x9d,0x56,0x65,0xb6,0xa2,0xb7,0x2f,0xa8,0x95,0xed,0x15,0x70,0x3e,0xb4,0xbd,0x62,0xde,0xde,0x59,0x9d,0x99,0x07,0xe8,0x0b,0x83,0x2e,0x55,0x96,0x63,0x0a,0x06,0x2a,0xf4,0xcb,0xd2,0x72,0x28,0x71,0xc8,0xb3,0x22,0xa0,0x35,0xaa,0x9f,0x73,0x21,0x8b,0xd9,0x25,0x41,0x46,0xbd,0x65,0x74 +.byte 0x40,0xcb,0xf4,0x83,0xa1,0xf1,0x73,0x75,0xe0,0xe2,0xee,0x1d,0xc4,0x6a,0x11,0x55,0x50,0x18,0xdb,0x94,0x58,0xbc,0xaf,0x2a,0x18,0x20,0x44,0x15,0xff,0xbd,0x67,0x19,0x64,0x39,0xab,0x35,0x72,0x34,0x83,0x66,0xd5,0x5d,0xcc,0xc7,0x68,0x4f,0x6b,0x05,0x81,0xfc,0x47,0x0d,0xe8,0xbe,0x7c,0xdd,0x27,0xd7,0xc6,0x74,0x9a,0xc1,0x5a,0x28 +.byte 0x45,0x58,0x9f,0x52,0xc8,0x8f,0x7b,0x13,0xab,0x9e,0x72,0xda,0xdf,0x10,0x3a,0xe3,0x5f,0x9b,0xf8,0x59,0x2d,0xc5,0x40,0x31,0x12,0xe9,0xc4,0x1f,0x46,0xa0,0x8a,0x98,0xd7,0xbf,0x16,0xe5,0x2d,0xe8,0x51,0xc0,0x8b,0x40,0x9d,0xd6,0x5b,0x4c,0xa5,0x95,0xd2,0x18,0x1e,0x0b,0x7e,0xd2,0xfc,0x0c,0x8c,0x1a,0x8b,0x61,0x45,0x77,0xf4,0x96 +.byte 0xef,0xc8,0x13,0x0b,0x93,0x27,0x35,0x9b,0x4a,0xc4,0x86,0x13,0x8e,0x86,0xf0,0xde,0x2b,0x45,0x8f,0x9a,0x22,0x31,0x50,0xa5,0x3c,0x26,0xcb,0x86,0xc1,0x88,0x18,0xb2,0x82,0xe6,0x88,0x71,0x49,0x2a,0x5c,0x2f,0x96,0x49,0x1e,0xc0,0x86,0x8a,0xe9,0x84,0x16,0x74,0xf2,0x29,0x99,0xdc,0x26,0xc4,0x3b,0xc7,0x1d,0xdd,0xbb,0x3a,0xe6,0x7a +.byte 0xac,0x06,0xb9,0x91,0x23,0xae,0x46,0x2e,0x4f,0x36,0x42,0x7e,0x84,0xae,0xbd,0x0c,0x21,0x6b,0xa3,0xf0,0xd0,0x1e,0xb1,0xf4,0x38,0xde,0xa0,0x2e,0xd4,0x0d,0xdb,0x00,0x17,0xd4,0x01,0xe7,0x45,0x50,0x58,0x0d,0x0b,0x5a,0xf5,0x02,0x4b,0xeb,0x23,0xc2,0xbd,0x54,0xe8,0x2e,0x92,0xe3,0xc3,0xfe,0x32,0xa0,0xc0,0x09,0x85,0x97,0x74,0x96 +.byte 0x60,0x6c,0xd5,0x6a,0xf6,0xee,0xef,0xa5,0x25,0xa8,0x6e,0xb6,0x59,0xa7,0xf9,0xad,0xf5,0x9d,0x45,0x83,0x98,0x33,0x26,0x53,0x89,0xb4,0x6d,0x45,0xb2,0x25,0xb4,0xd1,0x35,0xe0,0x28,0x77,0xcb,0x45,0x5f,0xc4,0x9d,0x8d,0x43,0xbb,0x49,0x68,0x06,0x6e,0x3d,0x48,0x3c,0xdb,0xbc,0x6f,0xfe,0x90,0xdb,0xde,0xe9,0xfb,0xca,0x29,0x7f,0x86 +.byte 0xaf,0xdd,0x1f,0xcc,0x81,0x74,0x4f,0xe6,0x13,0x91,0x23,0x8b,0x99,0x04,0xec,0x73,0x7e,0x88,0x1e,0x0f,0x38,0xa6,0xd3,0x21,0xb7,0x22,0x70,0xf9,0xfd,0x28,0x65,0xda,0xa6,0x96,0x04,0x7c,0x62,0xb2,0x94,0xc9,0xe1,0x08,0xb8,0x1b,0xca,0xc7,0x07,0x1b,0x7f,0xc7,0x07,0xfd,0x3a,0x6e,0xb3,0x70,0x0b,0x29,0xa2,0xe4,0x9e,0x78,0xea,0x9a +.byte 0xa8,0xe4,0x87,0xe6,0x6f,0x03,0x7c,0x88,0x45,0xf4,0x92,0x11,0xa8,0xfc,0x3c,0xae,0x51,0x66,0x82,0x59,0xb1,0xa8,0x98,0xeb,0x9a,0xb6,0x63,0x9c,0xa5,0x5e,0x10,0xf5,0x63,0x1e,0xa8,0x16,0xbf,0x8d,0xc8,0xbb,0xf7,0xcb,0xd9,0xc1,0x5d,0x2e,0x0e,0x4e,0x65,0x3c,0x20,0x77,0xe7,0x85,0xfe,0x7d,0x84,0xbe,0x1d,0x4d,0x00,0x80,0xc4,0x58 +.byte 0x73,0x46,0x3e,0xc3,0x35,0xef,0x92,0xbb,0x8b,0xde,0x95,0xd9,0xf9,0x8a,0x3b,0x2d,0x59,0xab,0xd0,0x08,0x84,0x76,0x81,0xcd,0x5b,0xa0,0x98,0xf9,0xd6,0x12,0xc5,0x8e,0x91,0x18,0xfd,0x35,0x90,0x68,0x7d,0x30,0x5f,0xe9,0xdd,0x3a,0xe6,0xd3,0x94,0xdb,0xa7,0xdb,0xe7,0xb9,0x79,0xfb,0x2a,0x16,0xa3,0x8d,0x0b,0xd6,0x0d,0xb3,0xbf,0x79 +.byte 0x51,0x26,0x9b,0x56,0x74,0x04,0x8a,0x20,0x58,0x2c,0xb3,0x60,0xdd,0x1d,0xcb,0x44,0x7f,0x17,0x7a,0x3f,0xe1,0x98,0x73,0xaf,0x21,0x06,0x6f,0x2f,0xbd,0x67,0xc1,0xcb,0x61,0x18,0x87,0xda,0xf2,0xab,0xe6,0xa6,0xac,0xf4,0x81,0x06,0x40,0x5a,0xb7,0x98,0x96,0x1a,0xa7,0x4b,0x0e,0x16,0x9a,0x70,0x0f,0x9c,0x2b,0x22,0xbf,0x09,0x3b,0xf3 +.byte 0x49,0xde,0x71,0x07,0xc4,0xa3,0x9a,0x68,0x66,0x56,0x5b,0xad,0x53,0x4c,0xf0,0x03,0xd6,0x25,0x7f,0xbe,0xd1,0x96,0x29,0xe3,0x09,0x8c,0xcc,0xae,0x35,0x2b,0x62,0xfe,0x9f,0x8f,0x0f,0x1a,0x8d,0x91,0x0c,0xc0,0xbb,0xf1,0x85,0xaa,0xf1,0x86,0x9b,0x99,0x7f,0xad,0xbc,0xfe,0xfa,0x33,0xb3,0x59,0x42,0x31,0x83,0x53,0x50,0x07,0xb0,0x61 +.byte 0x78,0x38,0x1e,0x4f,0x1f,0xa9,0x32,0x92,0xec,0x2b,0xa6,0xfb,0xf0,0x9b,0x73,0x06,0x45,0x20,0xc3,0x34,0x50,0x73,0xbd,0xdf,0x61,0xb4,0xd3,0x6b,0xde,0x63,0xc4,0xb4,0xbc,0xcf,0x64,0x1d,0xcc,0xf8,0xa0,0x3f,0x42,0x2c,0x06,0xa2,0x2a,0xbd,0xc8,0xc5,0xf6,0xf5,0xdd,0x27,0x0b,0xf7,0x00,0xf6,0x50,0xcf,0x96,0x2b,0x9a,0xf7,0xbb,0x82 +.byte 0x71,0xc2,0x95,0x7f,0x2f,0xcf,0xfb,0xb3,0x1d,0x0e,0xf3,0xf6,0x6d,0x77,0x63,0x9f,0x33,0x8a,0xce,0x91,0x39,0x2a,0x08,0x42,0x2a,0x0b,0xfe,0xee,0xf7,0x5e,0x1c,0x97,0x43,0x0a,0x3f,0xbc,0x23,0x20,0xc5,0x59,0xe5,0x84,0xec,0x2f,0xb1,0x1b,0x23,0x4b,0x8b,0xa1,0x56,0x6a,0xd3,0x77,0x09,0xef,0xbc,0x70,0xf9,0x89,0x1d,0x7c,0xd2,0x2a +.byte 0xfe,0x2f,0x94,0x0a,0x22,0x2e,0x99,0x57,0x3f,0xe5,0x7c,0xa3,0xeb,0xd3,0x90,0x30,0xce,0x1c,0x94,0xc6,0xf6,0xd1,0x58,0x19,0xdf,0x6c,0xfa,0x3e,0xe5,0x4d,0x5f,0x42,0xb3,0xe5,0x06,0xe3,0xdd,0x65,0xb6,0x35,0x7c,0x9f,0x50,0x6a,0xa1,0xab,0x95,0xab,0x3b,0x6d,0x87,0x07,0xaf,0x4f,0x4c,0xcc,0xd8,0x4d,0xde,0xb8,0xc6,0x0b,0xa0,0x1c +.byte 0x7b,0xc5,0xda,0x29,0x92,0x8b,0x54,0x37,0xec,0xbf,0xbe,0xf6,0x99,0x64,0x61,0xce,0xdd,0xdd,0x20,0x97,0x31,0xc3,0x82,0x87,0x86,0x1e,0x6d,0xde,0x6b,0x1b,0x3b,0x82,0xf5,0x40,0xbe,0x63,0x2f,0x03,0x04,0x71,0x2b,0x04,0x78,0x19,0xe0,0xc1,0x90,0xaf,0x52,0xb7,0xb8,0xc3,0xa8,0xa4,0x61,0x88,0xb4,0xf9,0xb5,0xd0,0xfa,0xe6,0x16,0x39 +.byte 0x1b,0xfc,0x9c,0xcc,0x9b,0x67,0x58,0x84,0x5d,0x21,0x82,0x06,0x77,0xc8,0xe5,0xa2,0xaa,0x37,0xc8,0x83,0xf2,0x59,0x85,0x6f,0xb4,0x13,0x8d,0xe8,0x57,0xe6,0xe6,0x83,0x10,0x4e,0xca,0x4e,0x0e,0xd9,0x15,0x58,0x05,0xaa,0xb0,0x61,0xd1,0xfe,0x19,0xc1,0x2e,0xd8,0x32,0x9e,0x19,0xf5,0x30,0x35,0x2b,0x4a,0x4b,0x4e,0xb8,0xaf,0xc5,0x4d +.byte 0x48,0x9e,0x66,0xd7,0xb6,0xd3,0xd8,0x77,0x12,0x0d,0x90,0x48,0x5b,0xee,0x7d,0xb2,0xcc,0x48,0x9a,0xe3,0x0a,0x1f,0x3a,0xf5,0x4f,0x3d,0x40,0x38,0x14,0x20,0x7c,0x70,0x20,0x2a,0xea,0x55,0x97,0x45,0xca,0x7d,0x26,0xd4,0x00,0x67,0xeb,0x2c,0x92,0x9b,0xb1,0x1e,0x79,0xb0,0x57,0x68,0x2b,0x42,0x46,0x26,0x91,0x96,0xc8,0xac,0x2f,0x28 +.byte 0x74,0x1d,0xf9,0xfa,0x06,0xd4,0x64,0xba,0xe6,0x07,0xae,0x11,0x78,0x75,0x3b,0xc8,0x2f,0x10,0xc6,0xe2,0x93,0x27,0x6d,0x71,0x7a,0x17,0x77,0x45,0xd7,0xe2,0x91,0x6b,0xaf,0xdf,0x5f,0x47,0x56,0xc0,0xb9,0x09,0x22,0x44,0x43,0x0c,0xa7,0x6b,0xc2,0x05,0x50,0x5a,0xb9,0x2d,0x86,0xea,0x99,0x96,0xd5,0x4d,0x90,0x4e,0x7c,0xc1,0x92,0xbb +.byte 0xb6,0x06,0xe9,0xaf,0x38,0x6e,0x00,0xe9,0x19,0x4b,0x2d,0x2a,0x17,0x5f,0xb5,0xc8,0xec,0x65,0xb6,0x6d,0x67,0x42,0x79,0x92,0x13,0x17,0x76,0xa5,0x4e,0x3a,0x66,0x13,0x58,0xcf,0xa7,0x4b,0xb9,0x8e,0x84,0x66,0xb8,0x4b,0x66,0xd3,0x87,0x6a,0x65,0xd4,0x0a,0x97,0xe8,0x15,0x32,0x15,0xd4,0x2e,0x9a,0x80,0x40,0xfc,0x02,0x6d,0x4f,0x9e +.byte 0x68,0x3f,0x18,0x61,0x70,0x38,0xb7,0x5a,0xda,0xe1,0x74,0xdd,0x79,0x71,0x95,0x4b,0x50,0x19,0x0c,0x93,0xc9,0x1d,0x02,0x66,0xa2,0x35,0x88,0x91,0x9e,0x4b,0x62,0x5f,0xfe,0x65,0x09,0xf7,0x71,0x98,0xa3,0xcd,0xe1,0x2b,0xcf,0x2e,0x5f,0x38,0x41,0x47,0x1b,0x94,0x61,0x5d,0xce,0xbc,0x4b,0x69,0x70,0x7e,0xe7,0x74,0x8a,0x69,0x99,0xe8 +.byte 0x58,0xda,0xd4,0xb4,0xae,0x3c,0xae,0xa0,0x78,0xed,0x72,0x51,0xb7,0xc1,0x95,0x20,0x43,0x34,0x77,0x12,0xa2,0xc5,0xe9,0xad,0xb4,0x6d,0x15,0x0d,0x3c,0x1b,0x2e,0x45,0x42,0xd6,0x7a,0x4f,0xe9,0x0e,0xe3,0x70,0xbd,0xe8,0x10,0x31,0xa9,0x09,0xc7,0x32,0x0c,0xcb,0x3e,0x54,0x6d,0x52,0xc2,0xed,0x57,0xbf,0xd1,0xbb,0xfe,0xd8,0x34,0x08 +.byte 0x40,0xc1,0xb8,0x86,0xf7,0x0c,0xa8,0x3c,0x11,0xbf,0x96,0xc2,0x86,0x64,0x99,0x27,0x2a,0x68,0x3b,0x29,0xca,0xc2,0xd6,0x59,0xf7,0x77,0x66,0x91,0x26,0x96,0x87,0x84,0xf1,0x01,0xe4,0x04,0x82,0xd4,0xf0,0xe5,0x72,0x40,0x3a,0x5b,0x0b,0x65,0xa1,0x78,0x91,0x8a,0x7e,0x16,0x82,0x3c,0x00,0x07,0x19,0x14,0x3d,0x01,0xc6,0xa9,0x62,0x83 +.byte 0x65,0x6a,0x66,0x02,0x6c,0xa9,0x77,0xaa,0x91,0xe1,0xbc,0x85,0x73,0xad,0xeb,0xca,0x01,0x2f,0x40,0xeb,0x14,0xa5,0x3f,0x78,0xec,0x90,0x39,0xab,0xc2,0x9d,0xce,0x55,0xf2,0xaf,0xbc,0x45,0x56,0x92,0x18,0x2b,0x74,0x15,0x7d,0xbd,0x77,0xdc,0xa3,0x56,0x8f,0xa5,0xf1,0xe4,0x8a,0xb4,0xbd,0x8b,0xa9,0x73,0x23,0x93,0xe3,0x84,0x1a,0x15 +.byte 0xae,0x28,0x8d,0x9e,0xca,0x2d,0xd9,0xfd,0x40,0xd0,0x92,0x2f,0x51,0x76,0xde,0x59,0xb7,0xc8,0x88,0x16,0xc1,0x7c,0xb7,0x6f,0x07,0x95,0x53,0x38,0xf8,0x42,0xea,0x80,0x0a,0xd7,0x43,0xa2,0xbc,0xd1,0x39,0xf7,0x99,0xd5,0xb9,0x17,0x8d,0xbe,0x8f,0x6f,0x5b,0x66,0x52,0x8e,0x28,0xfd,0x21,0x4f,0x16,0xef,0x83,0x83,0x62,0x50,0x6c,0x63 +.byte 0xeb,0x27,0xf5,0x9c,0x59,0xe6,0xba,0xae,0xf0,0xcf,0xba,0xad,0xcc,0x04,0xba,0x7b,0x11,0x10,0xfb,0xc3,0x97,0x68,0x3c,0xff,0x9c,0x46,0x16,0x75,0x06,0x47,0x52,0x55,0x40,0x8a,0x2f,0xb6,0x88,0xc3,0x6f,0xef,0xce,0xc5,0x38,0x98,0xf8,0x65,0x64,0x5c,0xeb,0xa4,0x86,0x90,0x83,0xf9,0xd1,0xc5,0x0b,0x02,0x9c,0x76,0xe0,0x0a,0xc1,0x48 +.byte 0x1d,0x2b,0x6a,0x40,0x24,0xdf,0x67,0x6c,0xb1,0xf8,0x86,0x5c,0xc3,0x5d,0x8d,0xb2,0x68,0x54,0x76,0x42,0x77,0x71,0xdc,0x72,0xed,0x00,0xa0,0xc7,0x30,0x86,0xae,0x0e,0x2e,0xa9,0x39,0x19,0x02,0xb3,0x21,0xe6,0xd4,0xab,0x5a,0x1b,0x4e,0x8a,0x2f,0x3f,0x09,0xdf,0x4e,0x82,0x79,0xa5,0x98,0x94,0x1c,0xb8,0xb6,0xa1,0x25,0x86,0x5c,0xdd +.byte 0x4e,0x71,0x4b,0x6b,0x5a,0x24,0x7b,0x32,0x07,0x7e,0xcc,0xad,0x26,0x3c,0x85,0xfd,0x2a,0x7e,0x99,0x5a,0xa7,0x5f,0x51,0x23,0xa1,0x19,0x33,0x58,0xd9,0xbd,0x37,0x9d,0x0f,0xf0,0x9b,0xc7,0xb8,0xdf,0x35,0x32,0xe6,0xce,0xac,0x93,0x1e,0xef,0xa6,0x83,0x80,0x10,0xed,0x5e,0x86,0x7a,0xda,0x85,0x18,0xbd,0x1c,0x9e,0x7d,0x25,0x0d,0xbc +.byte 0x7d,0x08,0xa4,0xaf,0xee,0x2b,0xc5,0xd4,0x38,0xe0,0xa9,0xd3,0x8e,0x28,0x36,0x2e,0xdc,0x2e,0x0d,0xe0,0x62,0xcb,0xd1,0x78,0xff,0x22,0xa0,0xbd,0x36,0xed,0x44,0x9e,0xdf,0x1f,0xca,0x07,0xbc,0x04,0x00,0x0d,0xda,0x56,0x9d,0x31,0xcb,0xc4,0x5a,0x05,0x88,0x82,0xa4,0x2e,0xe0,0x09,0xa1,0x0d,0x68,0x02,0x76,0x26,0x03,0xc4,0x8b,0xca +.byte 0x86,0xfe,0x26,0x07,0x17,0xc4,0xee,0x93,0x67,0x4a,0xa8,0x84,0xa4,0x44,0x5c,0xe3,0x8b,0x02,0x59,0xba,0x7e,0x7b,0x19,0x1a,0x42,0xf9,0x6f,0x78,0xcb,0x6b,0xf2,0xd6,0x4b,0xbe,0x7a,0xaa,0x6e,0x9a,0x6c,0x86,0xf4,0xf1,0xb3,0x4a,0xe9,0x7b,0xe5,0x36,0x75,0x02,0xc4,0x6f,0xfb,0xe6,0xbf,0x0d,0x2a,0xed,0x5e,0x86,0xf5,0x8a,0x2c,0xed +.byte 0x8c,0x83,0xd4,0xa4,0x52,0xe5,0x08,0xe5,0x4a,0xac,0xa0,0xa7,0x17,0x91,0x9e,0x48,0x59,0x94,0x59,0x60,0xac,0x79,0x62,0xcb,0xd0,0xe6,0x72,0xd2,0xca,0xd1,0x05,0xc7,0x5f,0x31,0xd0,0x8d,0xe8,0x55,0x98,0x8c,0xd2,0xc6,0x4a,0xf5,0x2a,0x5d,0xc9,0x2d,0x16,0x06,0xe1,0x6d,0xa8,0xf0,0xc4,0x4d,0x41,0x33,0x3d,0xc4,0xbf,0xba,0xc6,0xf1 +.byte 0xc4,0x92,0x17,0xff,0xa8,0x3f,0x2d,0xf1,0x90,0x2a,0xae,0xf5,0x64,0x2a,0xa5,0x08,0xac,0xbe,0x48,0x6a,0x27,0x05,0x91,0x33,0x7b,0x6d,0x0b,0x58,0xca,0x9b,0x29,0xf1,0xa8,0x18,0x1a,0xe4,0x9a,0xcc,0xbd,0x2a,0x09,0x15,0xe3,0x72,0xdc,0x80,0x60,0x8d,0x4a,0xac,0x3e,0x35,0xc4,0x94,0x7e,0xc8,0x78,0x43,0x9b,0xfc,0xe5,0xe7,0x57,0x83 +.byte 0x21,0x49,0x74,0x9f,0x9c,0x10,0x77,0x3b,0xda,0x11,0xe8,0x13,0x88,0x71,0xb2,0xa5,0xf1,0xa8,0x6c,0x19,0xee,0xc6,0x8a,0x96,0xe2,0x34,0xec,0xbc,0x4c,0x7e,0x72,0xdc,0xde,0xbf,0x09,0x0a,0x1e,0xce,0xbc,0x10,0xbe,0xfd,0x8d,0x0c,0x5c,0x40,0x4f,0x30,0x82,0xe3,0x99,0x72,0x91,0x6f,0xc8,0x3c,0x1c,0xe2,0xd3,0xae,0xbf,0x09,0x3a,0xec +.byte 0x28,0x81,0x10,0x80,0xf6,0x2e,0xb9,0x29,0xde,0x00,0x2c,0xf6,0xd9,0x03,0x47,0xea,0x0f,0x3c,0x02,0x92,0x80,0x50,0x76,0x2b,0x60,0x0e,0x15,0xbd,0x69,0x10,0x7b,0xce,0xbf,0x40,0x15,0xd3,0xd9,0x4c,0xd2,0x6a,0x6e,0x10,0x18,0x00,0x34,0x55,0x8d,0x66,0xaf,0xf7,0x14,0x12,0xe8,0x67,0x4d,0xe7,0xfe,0x4d,0xc1,0xc5,0x05,0x6f,0xcf,0x16 +.byte 0x1b,0x65,0x32,0xab,0x89,0x86,0x3e,0xe5,0x3e,0xba,0x8a,0xc1,0x5e,0x41,0xbb,0x23,0x76,0x8c,0xea,0x77,0x6e,0x1f,0x3c,0x4c,0xe4,0x98,0x9c,0xe5,0x73,0x0c,0x08,0x48,0x83,0xb6,0x24,0x24,0xe6,0xac,0xc2,0x4e,0xe1,0x67,0x33,0x01,0x33,0x85,0x59,0x34,0x35,0xd7,0xdd,0xc4,0x04,0xff,0x53,0x78,0xd4,0xb5,0xe9,0x65,0x88,0xfc,0x41,0x6f +.byte 0x06,0xfb,0xfa,0x58,0x67,0xa1,0x1d,0x78,0xd9,0xad,0xf2,0x92,0x34,0x87,0x8c,0xd2,0x96,0x95,0x1d,0xc7,0x52,0xcb,0x64,0x5f,0xb2,0xe7,0x3c,0x31,0xe0,0x61,0xbb,0xab,0x34,0xef,0xd4,0x4f,0xe6,0x0b,0x3e,0x58,0x53,0x30,0x92,0xba,0x8c,0x72,0x88,0xb5,0xf5,0x8d,0xc2,0xa2,0xdf,0x86,0x7f,0x15,0xeb,0x8f,0xc1,0x62,0xe0,0x56,0x92,0x00 +.byte 0xea,0xf7,0x27,0x73,0xac,0x9f,0x1d,0x13,0xcd,0x33,0xb3,0xd5,0x31,0x29,0x42,0x1e,0x28,0xc2,0xfd,0xd1,0xec,0xb0,0x32,0x83,0xec,0x22,0xda,0xae,0xab,0x7b,0x4f,0x76,0xa9,0xa0,0x0f,0xc3,0x39,0xb1,0xfe,0x63,0x2e,0x72,0xb9,0x41,0x03,0xfd,0x7a,0x33,0xbd,0x1e,0x0e,0xe1,0xd3,0x2b,0xbc,0x68,0x8c,0xd9,0x12,0x02,0xf7,0x9e,0x7f,0xc8 +.byte 0x30,0xa2,0x60,0xc0,0x85,0x2a,0xae,0xfd,0xed,0xd0,0x88,0x66,0xef,0xfc,0xe8,0xaf,0x41,0xda,0xd1,0x99,0x8a,0x4e,0x7d,0xaa,0xf5,0x9a,0x56,0xac,0x18,0x14,0xf7,0x6e,0xea,0xad,0xcd,0xed,0x19,0xa6,0x28,0x41,0x2b,0x1d,0xcb,0xa5,0x84,0xfd,0x34,0x84,0x2a,0x05,0x8c,0x74,0x6a,0x43,0x34,0x28,0xf4,0x35,0x60,0x91,0x32,0xd2,0x66,0xc6 +.byte 0x3b,0xaa,0xde,0x8a,0xdc,0x73,0xab,0x98,0xeb,0xeb,0xe9,0x97,0xd6,0xe2,0xf4,0xbf,0xbf,0x45,0x62,0x75,0xb2,0xd3,0xad,0x38,0x62,0xdd,0x9b,0x63,0xe1,0x27,0x6a,0x25,0xbf,0xe9,0x26,0xc1,0x9f,0x0e,0x92,0xeb,0xb9,0xdb,0x72,0xea,0xcc,0x11,0x4f,0x4d,0x2a,0x2a,0x7f,0xfd,0xf5,0x2d,0xdc,0x53,0xdf,0x56,0xcf,0x3e,0xf6,0x48,0x1b,0x5d +.byte 0x51,0xb8,0x9d,0xc6,0xe3,0xd5,0xcb,0x0d,0x0b,0xb9,0x6e,0x34,0x07,0x90,0xdc,0xe7,0xd1,0x61,0x85,0x6b,0x58,0xd6,0xa2,0x58,0x5f,0xf4,0x6c,0xb9,0x3a,0x11,0x1e,0x2a,0x03,0x80,0x8d,0xc8,0x8c,0x24,0xd1,0xa2,0x53,0x63,0x50,0x66,0x01,0xed,0x0e,0xd3,0xfb,0x57,0x59,0x31,0xeb,0x2e,0x37,0xff,0xc0,0x28,0xfc,0xbb,0x6f,0x61,0xfd,0x69 +.byte 0x35,0x94,0xa9,0xed,0x5e,0xca,0xa6,0x37,0x5a,0x01,0xd9,0xcf,0xe4,0x91,0xb3,0x2e,0x2a,0x97,0x46,0x46,0x26,0xd9,0x85,0x01,0xfa,0xcb,0x93,0xdf,0xb4,0x2a,0x86,0x81,0x93,0x2f,0x1b,0x56,0x3f,0xe5,0xd9,0x90,0x2e,0x2b,0xe4,0xc8,0x76,0x96,0x1b,0x91,0x9c,0x6a,0x17,0x42,0x1b,0x63,0x74,0x55,0xbc,0xe0,0xed,0x2e,0x6c,0xd0,0x61,0x37 +.byte 0x5b,0xac,0x66,0x2e,0x2b,0x3d,0x47,0xa9,0x7a,0x7d,0xa6,0xfa,0xb4,0xa8,0x18,0x4b,0x65,0x31,0xbb,0xe3,0xe6,0x0e,0x76,0x91,0xe2,0x54,0xfd,0x4a,0xa5,0x35,0x70,0xe4,0xd0,0xbd,0x59,0x75,0xc8,0xca,0x46,0x58,0xf4,0xe5,0x57,0xd2,0x12,0x93,0x14,0x78,0x5f,0xe6,0xee,0x96,0x6e,0xe9,0xf6,0x10,0x41,0x61,0x38,0xf8,0x1e,0x5b,0x69,0x2c +.byte 0xc1,0x54,0x8e,0x12,0x23,0xa7,0xc0,0x42,0x18,0x3e,0x4c,0x7b,0x90,0x96,0x03,0x3e,0x4d,0x5c,0xac,0x4d,0xe6,0xed,0xcd,0xe2,0xf5,0x35,0x0c,0xde,0xf7,0x70,0x07,0xa9,0xb1,0xe8,0x0c,0xf3,0x64,0xec,0xf5,0x18,0x0f,0x5a,0x70,0x03,0xcf,0x38,0xe9,0x38,0x83,0x13,0xaa,0x9c,0x6b,0xcd,0x5f,0x4e,0x03,0x04,0x33,0x0c,0x27,0x8c,0x5e,0x3e +.byte 0x69,0x49,0xc7,0xc3,0x5f,0x1c,0x5f,0x78,0x55,0x2a,0x40,0xec,0xe9,0x80,0x66,0xb9,0x05,0x60,0xb6,0xa2,0xe1,0x29,0x36,0xe3,0xb7,0x87,0x09,0x3c,0x2f,0x42,0x12,0x53,0xf0,0x6f,0x4b,0xa3,0x05,0x35,0x8b,0xcd,0x18,0xbe,0xe7,0xa2,0xce,0xda,0xbc,0x83,0x0f,0x68,0xc0,0xdc,0xbb,0xa4,0x4a,0x7b,0xae,0x74,0x1f,0xe6,0x13,0x82,0x2f,0xa1 +.byte 0x88,0x4f,0x64,0x7e,0x16,0xad,0xbb,0x0d,0x41,0x1c,0xb8,0x3b,0xba,0xc2,0x7a,0xed,0x05,0x54,0x85,0x41,0xf0,0xeb,0xa4,0x0c,0xb7,0x51,0xf5,0x9c,0x36,0x0e,0xea,0x13,0x03,0x91,0x9a,0x60,0x68,0xac,0xc3,0x34,0xc6,0xf1,0xdf,0xb3,0x0f,0x76,0x88,0x9a,0x62,0x01,0xf3,0x15,0xf0,0xaf,0xd7,0x5a,0x66,0x83,0xa8,0x31,0xa5,0x5f,0x97,0x87 +.byte 0x10,0xe7,0xb9,0x4d,0xe5,0x87,0x64,0xb1,0x9d,0x9d,0x21,0xcb,0xab,0xeb,0x4b,0x3d,0x10,0x3d,0x9d,0x49,0xfe,0xc2,0x22,0x11,0x23,0x8a,0x0a,0x16,0x12,0xc5,0xed,0x24,0x16,0xbc,0x16,0xd3,0x03,0xa0,0x23,0xe1,0xa1,0x57,0x78,0x9d,0xb8,0x08,0xb9,0x41,0xeb,0xb9,0x8a,0xf6,0x1f,0x70,0xa1,0x99,0xe8,0x93,0x78,0x55,0x76,0xae,0x17,0x7a +.byte 0x87,0xb2,0x53,0xf2,0xe9,0xbb,0x4a,0x96,0x32,0x8d,0x59,0x23,0x86,0xb3,0xba,0xaa,0xa2,0x68,0x56,0x5d,0xc9,0x83,0x29,0xe8,0x24,0xf1,0xc4,0x02,0x87,0xcf,0x58,0xeb,0x08,0xaf,0xf1,0x00,0x56,0xa5,0xd6,0x97,0x34,0x49,0x9e,0x93,0x39,0x66,0xf9,0xd9,0xfc,0x0c,0x16,0x9b,0x1f,0xe4,0x7e,0xec,0x03,0x5e,0x53,0xdf,0x2f,0x55,0xa0,0x05 +.byte 0x36,0x7f,0x4a,0x4e,0x48,0x76,0xe5,0x5f,0xeb,0xe3,0x00,0x3e,0x25,0x23,0x12,0x44,0x92,0x01,0x44,0xb7,0xb3,0x46,0xb2,0xe4,0xcc,0xcb,0xa3,0x53,0xcd,0x64,0x10,0x65,0xc7,0x6c,0x92,0x07,0x39,0xf8,0x4c,0x6d,0x2c,0x33,0xb5,0x98,0x1b,0x74,0x35,0xad,0x2a,0x35,0x6c,0x51,0x47,0xee,0x1d,0xb5,0x70,0x36,0x2f,0xd4,0x23,0xdc,0xf5,0x4a +.byte 0x66,0xa4,0x83,0x50,0xc5,0xb7,0x59,0x96,0x22,0xec,0x5d,0x33,0x7e,0x9d,0xcd,0xe6,0xd4,0x01,0x61,0xaa,0xb0,0x47,0x05,0x11,0x6b,0x27,0xae,0xd2,0xf1,0xe6,0x49,0xe0,0x95,0xa1,0xfd,0x76,0xa2,0xdb,0xa4,0x9d,0x02,0xe6,0x42,0xe0,0x2e,0x36,0x84,0x0f,0x31,0x1e,0xb9,0x8d,0x11,0xc0,0xb8,0xd5,0xcf,0xc8,0x0d,0x97,0xc0,0x5e,0x0b,0xf0 +.byte 0x16,0xad,0xc0,0x9e,0x3e,0x38,0xd1,0xbf,0x47,0x77,0x9c,0xcd,0x6b,0xae,0x1c,0x8a,0x51,0x75,0xc4,0x74,0x78,0x5b,0x9d,0x16,0xec,0xc6,0x4b,0x1f,0x53,0xff,0x4e,0xb0,0x1b,0x03,0xdd,0xbf,0x32,0x32,0x55,0xe9,0xcc,0xe7,0xc0,0xde,0x01,0xbd,0x7d,0xb3,0x29,0xae,0xed,0xb8,0x5b,0xa0,0x96,0xc0,0x45,0xb2,0x5d,0xf7,0xa6,0x43,0xc7,0x56 +.byte 0x4a,0xc0,0x16,0xbf,0x0e,0xf0,0x77,0x94,0xd0,0x52,0x7e,0xb3,0x45,0xd2,0x16,0x30,0x11,0xc0,0xd6,0xd3,0x61,0xfe,0xdb,0xed,0xa6,0x16,0x4f,0x88,0xce,0x17,0x64,0x02,0xa0,0xc1,0x42,0x47,0x19,0x0b,0xc6,0xea,0x9b,0xf1,0xf0,0xab,0x7c,0xd5,0xf9,0x73,0x9b,0xcc,0xc4,0xce,0x69,0xaf,0xc1,0x48,0xbc,0x13,0xe9,0xad,0xdc,0x6b,0x15,0xb7 +.byte 0x3b,0x85,0x05,0x17,0x66,0x35,0x05,0xe6,0xf7,0x99,0xfd,0x04,0x0f,0xd3,0xbd,0xc5,0x0a,0x3f,0x7c,0x49,0x63,0xe5,0xe3,0xa7,0x7a,0x03,0xe3,0xb1,0x3c,0x7d,0x4b,0x04,0x2e,0x94,0x2d,0x9a,0x55,0x18,0xd1,0x7c,0xc5,0x06,0xbc,0xf2,0x68,0xa9,0x9a,0xd9,0xf5,0xb4,0x15,0x66,0x0a,0x8c,0x68,0xa3,0xb6,0x41,0xb1,0x57,0x55,0xac,0x5c,0x2a +.byte 0xff,0xb0,0x30,0x11,0x31,0x1f,0xe4,0x05,0x91,0xe3,0xf9,0x2d,0x9a,0xd6,0x2a,0x73,0xdf,0x34,0x1d,0xf0,0xbe,0x46,0x60,0xce,0xa7,0x81,0xf1,0x8b,0x52,0x42,0x1d,0xa7,0x97,0x8c,0x92,0xe2,0xe2,0x00,0x5a,0xce,0xc2,0x70,0x52,0x02,0xa4,0x35,0xb6,0xe8,0x3f,0x22,0x75,0x4e,0xf0,0xc8,0x08,0x54,0x1b,0x52,0x21,0xe2,0x26,0x11,0x92,0x98 +.byte 0xb1,0x26,0x23,0x58,0xeb,0xb8,0x97,0xcd,0xb3,0x2d,0x9b,0x4b,0x6e,0xcf,0x28,0xd5,0x0f,0x12,0x89,0x1f,0x90,0x7c,0x96,0x98,0xee,0xc0,0x29,0xed,0x6d,0xcb,0xca,0x07,0x10,0xe0,0x23,0xe4,0x28,0x97,0x8e,0x47,0x46,0x4a,0xde,0x6c,0x3b,0xff,0x75,0xfc,0x38,0x78,0xe8,0x27,0xba,0x5e,0xd2,0x9a,0xa4,0xf6,0xcd,0xef,0xf4,0x74,0x61,0x8f +.byte 0x20,0x99,0x60,0x2a,0x97,0x42,0x34,0xa8,0x70,0x5d,0xe7,0xa6,0xc9,0x80,0xc8,0x15,0x11,0x5b,0xf0,0x50,0x5f,0x44,0xa2,0x01,0x63,0x32,0x11,0x89,0xaa,0x36,0x38,0xc4,0xba,0x08,0xbf,0x2a,0x9c,0x69,0x2b,0x84,0x2c,0x14,0x97,0x60,0xc3,0x5d,0x04,0xe3,0x9d,0xcb,0x9a,0xa2,0x15,0x3f,0xa6,0x28,0x24,0xde,0x00,0xee,0x1e,0x11,0x95,0xb4 +.byte 0x12,0xb8,0xff,0x3e,0x31,0xf2,0xc4,0x06,0xf1,0x9c,0x44,0xc5,0x59,0xa5,0xf8,0xc0,0x33,0x59,0x97,0x2d,0x6d,0x97,0xdb,0x33,0xba,0x30,0xd2,0xa9,0xc2,0x1e,0xb6,0x8f,0x3d,0x83,0x4c,0x82,0x04,0xeb,0x50,0xdd,0x42,0x31,0x1d,0x3e,0x35,0xb4,0x32,0xaf,0x16,0x50,0xb3,0x05,0xbe,0x8a,0x80,0x14,0x8a,0x3f,0x2f,0x8d,0x70,0xc0,0x60,0xa6 +.byte 0x5d,0x8e,0x38,0x94,0x47,0xab,0x1b,0xf6,0x9e,0x9e,0xf1,0x84,0xa5,0xdb,0xab,0x6a,0x71,0xc5,0x36,0x86,0xe0,0xb5,0x7e,0xd5,0x7f,0x1b,0xdb,0xa0,0x9d,0x1a,0xe3,0x84,0xc9,0x59,0xac,0x24,0x2b,0xa5,0x18,0x70,0xf9,0xf0,0xe8,0x2c,0xad,0x54,0x62,0x99,0x2a,0x56,0xbf,0x76,0x89,0x0e,0x93,0x55,0xea,0x83,0xc7,0xa1,0x2d,0x6c,0x4d,0x00 +.byte 0x9f,0xa9,0x9d,0x97,0x4e,0x76,0x20,0x9d,0x09,0x24,0x97,0xfe,0xa6,0xd6,0xda,0x66,0x39,0x27,0x0a,0x05,0x52,0xee,0xc8,0x70,0x0a,0x65,0xea,0x0f,0xa3,0xe0,0x10,0xbb,0xe4,0x87,0xb1,0x18,0x75,0x72,0xe7,0x6b,0xd6,0x88,0x91,0x6c,0xd0,0x7c,0xda,0x10,0xdf,0xd6,0xc7,0xcd,0x33,0x7d,0x28,0x9d,0x6d,0x2c,0xc2,0x59,0xc3,0xf5,0xb4,0x55 +.byte 0xe2,0x8b,0x65,0x92,0x4b,0x49,0x62,0x3a,0x49,0x00,0x62,0x79,0x9c,0xbd,0x99,0x7a,0x7f,0x71,0x19,0x90,0x77,0x56,0x94,0x2d,0xce,0x93,0x69,0xa6,0x56,0xde,0x75,0xdb,0x43,0x0f,0xae,0x1a,0x93,0x79,0x6c,0x2c,0x03,0xe3,0xfc,0x7d,0x90,0xd6,0x10,0xca,0x97,0x53,0x63,0x9e,0x6c,0x13,0xcf,0x4b,0x1a,0x76,0xf4,0x5b,0x57,0x27,0x20,0x76 +.byte 0xe5,0xee,0xfc,0x5d,0x12,0x67,0x88,0x37,0xf4,0xb5,0xf5,0x39,0x23,0x90,0xf3,0x31,0xad,0x1d,0xc3,0x98,0xaf,0x49,0x64,0x2a,0x75,0x4d,0x34,0x8c,0xf1,0x50,0x82,0xda,0xe9,0x17,0x63,0xbb,0xe8,0x54,0x36,0xd4,0x38,0x57,0x4c,0xe3,0xfd,0x11,0x02,0xbc,0xc7,0xb6,0x65,0xe2,0xd7,0x84,0x38,0xbf,0xf1,0xea,0xac,0x23,0x89,0xa5,0x3d,0xa8 +.byte 0x4d,0x5b,0x97,0x01,0x23,0xcd,0x8d,0xfc,0x28,0xc9,0xc2,0x06,0x06,0x6c,0x0d,0x07,0x0f,0x7f,0x7d,0xcf,0xcf,0x67,0xc7,0xe0,0xe1,0x4d,0xe8,0xee,0x6d,0x9a,0x1c,0x92,0xa6,0x4f,0xaf,0x4c,0xc3,0xa0,0xe7,0x73,0xa2,0x7b,0x4a,0x43,0xc2,0x94,0x6c,0xc6,0xb0,0x87,0x36,0xa0,0x3e,0x31,0x6e,0x77,0xc2,0xc1,0x90,0xb1,0x78,0x2c,0x52,0x44 +.byte 0x9f,0xaf,0xc8,0x2e,0xca,0x90,0x60,0xc7,0xf8,0xa8,0xdd,0x91,0x42,0x1f,0x13,0x97,0x10,0x27,0xa1,0x74,0x51,0x71,0xeb,0xef,0xa6,0x83,0x7c,0xa0,0xd7,0x5f,0x59,0x54,0xf3,0xff,0xa2,0xfb,0x58,0xbc,0xbf,0x02,0xa8,0x44,0xca,0xf6,0x61,0xda,0x47,0xaa,0x02,0x3b,0xb4,0x2f,0xc4,0x12,0xbd,0xd7,0x24,0x56,0xe2,0x6e,0x51,0x34,0xdb,0x1c +.byte 0x3d,0xd1,0xc5,0x90,0xfc,0xfd,0xe0,0xf0,0x99,0x3c,0x75,0x58,0xeb,0xb0,0xb2,0x97,0x60,0x81,0xd5,0x79,0xce,0x20,0xd2,0x20,0x50,0x46,0x20,0x96,0x98,0xdc,0x38,0x7f,0x38,0x80,0x91,0xf1,0xa1,0x26,0xa0,0xc5,0x14,0x96,0xe0,0x1f,0x96,0xf5,0x91,0x09,0xac,0xab,0xad,0x5e,0x96,0xa3,0xcb,0xfb,0x4c,0xb9,0x5f,0x30,0x0a,0x24,0x1f,0x65 +.byte 0x23,0x23,0x58,0x02,0xaa,0xb0,0x2c,0xe8,0xca,0xf1,0x0d,0x7e,0xe2,0xc5,0xee,0x1a,0x19,0x94,0x48,0xeb,0xee,0x71,0xbc,0x67,0xf2,0x39,0x1e,0xff,0xb1,0x35,0x60,0x8d,0xb4,0x97,0x06,0x89,0xa6,0xca,0xee,0xb8,0x5c,0xdf,0x3e,0x52,0x5c,0xa4,0x91,0x08,0x66,0xdf,0x20,0xbf,0xbe,0xfa,0xe3,0x58,0xd0,0x47,0xeb,0x3f,0xa1,0xfd,0x07,0x68 +.byte 0x35,0x7d,0x5c,0x67,0x13,0x7e,0x28,0x51,0x69,0x20,0x60,0x20,0x9c,0xf3,0x3a,0x23,0x8c,0x7c,0x95,0x0e,0x18,0x43,0xdf,0xe8,0xb1,0x71,0x4a,0x58,0x71,0x22,0x04,0xa4,0xad,0xab,0x77,0xa3,0xe5,0x01,0xb4,0x4a,0x4f,0x2f,0x6c,0x74,0x67,0x48,0x22,0x15,0xb0,0x10,0x6f,0xc4,0x95,0x11,0x09,0xa6,0x1a,0x2e,0x40,0x58,0xcb,0x5e,0x37,0xce +.byte 0xbb,0xd3,0x5e,0xc8,0xcb,0xde,0x4e,0x1e,0x7a,0xb8,0xb4,0x27,0x45,0xb7,0x63,0xce,0x92,0xf8,0x31,0xd4,0xaf,0x3a,0x91,0x32,0x5f,0x27,0x67,0x94,0xf2,0x76,0xb7,0xd5,0x92,0xd2,0xe8,0x75,0xce,0x58,0x84,0xbb,0xf7,0xbb,0xa2,0x15,0x5a,0xd1,0x6e,0x83,0x5f,0x47,0xdb,0x73,0xdb,0x04,0xcd,0x55,0x15,0x6e,0x42,0xcf,0x8b,0x04,0x1b,0xfa +.byte 0x82,0xf9,0xb5,0x9b,0xa0,0x2b,0x6b,0x7d,0x31,0x12,0x63,0x2e,0x27,0xdb,0x87,0x88,0x95,0xb8,0xf5,0x16,0xec,0x16,0xac,0xf1,0xa4,0x7f,0x51,0x99,0xc5,0x8a,0xf2,0x5c,0xbe,0xe2,0xe9,0xe2,0x03,0x76,0xfc,0xdd,0xaf,0x69,0x61,0x92,0xef,0xf7,0x07,0x17,0x3f,0x48,0xfa,0x04,0x8e,0xb4,0x56,0xa1,0x07,0xec,0x98,0xad,0x72,0xd5,0x91,0x52 +.byte 0x4b,0xe4,0x0a,0x51,0x10,0x4f,0xad,0x99,0xfd,0x89,0xa1,0x19,0xe3,0x52,0x15,0xc8,0x8c,0x10,0xc6,0x9f,0x94,0x5b,0xf0,0xbd,0x67,0x20,0xcc,0xa1,0x9c,0x06,0x8c,0xa6,0x47,0x5d,0x1d,0x22,0x0b,0xa3,0x2c,0x59,0x18,0xfb,0x46,0xf2,0xa3,0x6a,0x3c,0x08,0xeb,0x42,0xad,0x3a,0x01,0xeb,0xfd,0x9b,0x54,0x4e,0x6e,0x60,0xee,0x94,0x04,0x42 +.byte 0x75,0x5e,0xdf,0x51,0x4f,0x92,0xac,0x2e,0x6d,0xaf,0x87,0x7f,0x0a,0xdc,0x7d,0x58,0x62,0xdb,0xc8,0x15,0x1f,0xef,0x8d,0xbf,0x9f,0x80,0xf9,0x3d,0x39,0x2c,0x63,0x94,0x36,0xf2,0xda,0xf5,0x63,0x5a,0x8e,0x1e,0x28,0x12,0xbc,0xa3,0x9e,0x31,0x34,0x11,0xca,0xd0,0xc0,0x67,0x58,0xcf,0xb6,0x1d,0x68,0xa4,0xae,0x2d,0x73,0x0d,0x7b,0x02 +.byte 0xc6,0x01,0xc5,0xa8,0x22,0xf0,0x7a,0x97,0x97,0x93,0xbe,0x52,0xb9,0xa2,0xdd,0x49,0x33,0x1a,0xab,0xc1,0x6e,0xc5,0x7f,0x71,0xdc,0xbf,0x1e,0x28,0x3d,0xf6,0x50,0xe2,0x66,0x01,0x21,0xc5,0x42,0xf2,0x3e,0x4e,0x8b,0x8a,0x07,0xfc,0x42,0xeb,0x78,0x0f,0xd0,0x0f,0x2a,0x4e,0x41,0x7c,0xa5,0x49,0x7b,0x0f,0x88,0x49,0x51,0x7c,0x0f,0x5e +.byte 0xcd,0x9b,0x8b,0xc8,0x13,0xfd,0x16,0xfd,0xa4,0x77,0xf2,0x5b,0x02,0x02,0x38,0x5c,0xf0,0x5a,0x49,0xd8,0x80,0x48,0x10,0xa4,0x3c,0xcd,0x3b,0x6c,0x38,0x53,0x63,0xba,0xbf,0xb2,0x80,0x68,0x96,0x47,0x44,0xf3,0xa0,0xe3,0x85,0xe2,0x17,0xbb,0xfc,0x0f,0xa2,0x67,0x04,0x28,0x79,0x7f,0x05,0x84,0x5b,0x62,0x80,0x09,0x2c,0xb6,0x6f,0x76 +.byte 0x18,0xba,0x83,0x39,0x82,0xa7,0x0b,0x63,0x34,0x87,0xa1,0xa1,0xa0,0xe1,0xda,0x0d,0x7b,0xe6,0xd7,0xcd,0xca,0x02,0x45,0x66,0xe5,0x30,0xc8,0xac,0x81,0xdf,0xfe,0x74,0xe5,0x45,0xd9,0x99,0x04,0xa6,0xcf,0x3c,0x10,0x73,0xfb,0xd7,0xe0,0xc0,0x44,0x54,0xda,0x9b,0x9a,0x64,0x90,0x6f,0x42,0x1a,0xda,0x65,0x24,0x3d,0xb6,0x70,0x8d,0xe1 +.byte 0x33,0xf9,0xb2,0xda,0xa4,0x2e,0x7d,0x90,0x2b,0x14,0x16,0xd1,0x13,0xd4,0x1a,0xe6,0x25,0xa8,0x66,0x0b,0xed,0xed,0xa0,0x62,0x9c,0xb4,0x24,0x03,0x6f,0x36,0x7a,0x93,0x42,0xbc,0xf7,0x23,0x6b,0x0e,0xee,0xdf,0x80,0xd3,0xc1,0xc4,0x8e,0x3f,0xd9,0x1a,0x6f,0x37,0xc9,0x71,0xf4,0x3f,0x7e,0xa8,0x7d,0xbe,0x8d,0x53,0x11,0x35,0x16,0x0b +.byte 0x63,0xdb,0x99,0xa5,0x3b,0x17,0x7b,0x97,0xdb,0x81,0x36,0x43,0x33,0xde,0x31,0xc1,0xc8,0xb2,0x99,0x86,0xd0,0x2f,0x57,0x89,0x91,0xd7,0x3b,0x1f,0x5b,0xd5,0xb4,0x42,0x77,0x66,0x9a,0xaa,0x65,0x9d,0x5c,0x12,0xbf,0xeb,0xa4,0xb3,0xc8,0x4c,0xdb,0xf2,0x4c,0xe5,0xe8,0xb6,0xaa,0xc1,0xe2,0xd7,0xd2,0x14,0x03,0x27,0x04,0x0a,0xf9,0x54 +.byte 0x07,0xcc,0x50,0xbb,0xd6,0xfc,0x68,0x01,0xc3,0x79,0xb2,0x0c,0x4c,0x8e,0x65,0x41,0x91,0x7d,0x91,0x33,0x64,0xfa,0xeb,0x1a,0xbc,0x08,0x29,0x14,0x61,0x08,0xc8,0xd4,0xbb,0x64,0xe7,0xb1,0x2d,0xe0,0x1d,0xc6,0xae,0x78,0x20,0x81,0x8f,0x8d,0x20,0xb7,0x9d,0x7e,0x55,0x6e,0xbe,0x39,0x72,0x6e,0xc9,0xd8,0x6c,0x5c,0xa6,0x4c,0x48,0x2b +.byte 0x4e,0x14,0x98,0x76,0x7b,0x6e,0x8b,0x1d,0x50,0xc8,0x30,0xa6,0x3a,0xe6,0xa4,0xf1,0x6c,0x67,0x7d,0x10,0x28,0x93,0x4d,0xe6,0x93,0x2c,0x1e,0xc1,0xbc,0x9a,0xff,0x21,0x00,0x66,0xeb,0x72,0xe1,0x57,0xe0,0x03,0x55,0x0f,0x56,0x27,0x36,0xbb,0x75,0x01,0x02,0xcd,0xad,0x6b,0xf2,0xa2,0xec,0x18,0x62,0xa3,0xd6,0x10,0x5e,0x2c,0xf6,0xa5 +.byte 0xec,0x67,0xcc,0xfe,0xe8,0xa2,0x9e,0x0d,0xf0,0x11,0xf1,0x32,0xd7,0x4e,0x3a,0xbd,0xea,0xec,0xa9,0x72,0x98,0x82,0x00,0xa4,0x49,0xe2,0xa8,0xfc,0xf3,0x3c,0x3c,0x0e,0x2d,0x2c,0xc9,0xf8,0x72,0x04,0x67,0x4b,0x00,0xf9,0xd4,0x77,0x90,0x8e,0xf8,0x62,0xdc,0x23,0xc1,0x7a,0x2d,0xb3,0x40,0x47,0x7b,0x0b,0xac,0x5f,0x2a,0x67,0x84,0xed +.byte 0xf4,0x75,0x9c,0xf4,0x20,0x83,0xa8,0xed,0x3e,0x14,0x28,0xbb,0xc5,0xb1,0x1f,0x25,0x46,0x32,0xd3,0x9f,0x1b,0xa8,0x2d,0xf7,0x07,0x9c,0x82,0x25,0x25,0x5c,0x75,0x03,0x32,0xce,0x6a,0x51,0x60,0xde,0xf7,0x54,0x10,0x97,0xdf,0x28,0x19,0x59,0xe9,0x62,0x81,0xd1,0x20,0xbe,0x9a,0x2d,0xf4,0x42,0xb3,0x2b,0x7c,0x5e,0x83,0xfe,0xd6,0xfc +.byte 0xac,0xe5,0x5d,0x27,0xb0,0x50,0xee,0xca,0x12,0xcd,0x3d,0xe9,0x24,0x77,0xee,0x61,0xec,0xb7,0x0e,0xd1,0x10,0x9a,0xa7,0x7d,0x8a,0x77,0x9f,0xc9,0x70,0x02,0x02,0xbf,0xc7,0x9c,0xcb,0xc2,0xff,0x77,0xd2,0x7a,0x37,0x3d,0xb4,0xad,0xb8,0x4e,0xc3,0x87,0x1d,0x93,0x77,0xb4,0xab,0x7f,0x6c,0xca,0x48,0xfd,0x31,0x88,0x05,0x2d,0xc4,0xe6 +.byte 0x97,0xe8,0xe7,0x39,0xab,0xe4,0xd5,0xd4,0xa8,0xc5,0x81,0xcc,0xe2,0xa3,0x48,0x49,0x9c,0x4e,0xb0,0x1c,0x80,0xbb,0xc3,0xfe,0xa2,0x04,0xcf,0xdd,0x01,0x26,0x25,0x78,0x65,0x51,0xb1,0x40,0x02,0x6e,0x58,0x90,0x59,0xad,0xe8,0x59,0xc3,0x1b,0x59,0xb1,0x34,0x38,0x32,0x66,0xd7,0x15,0xc3,0x50,0xe5,0xb1,0x54,0x23,0xd0,0xc7,0x92,0xa3 +.byte 0xb3,0x66,0x07,0x49,0xc5,0xdf,0x46,0x06,0x16,0xb4,0xe1,0xca,0xb5,0x15,0xa4,0x77,0xf0,0x4a,0xba,0xfe,0xd9,0xd9,0x9b,0x11,0xdb,0x71,0xe6,0x73,0xc3,0x9a,0xaa,0x96,0xb6,0xb8,0x8f,0x2a,0xcf,0x90,0xad,0x4e,0x7c,0x3c,0xe1,0x67,0x4a,0x97,0x1a,0xce,0x7d,0x0b,0xa8,0xb3,0x6a,0xa2,0x18,0x45,0xcc,0xa7,0xe6,0x3f,0x5e,0xb4,0x51,0xc7 +.byte 0xa7,0x78,0xc5,0x08,0x64,0xea,0x9d,0x1a,0x63,0x25,0x12,0x89,0xb3,0xde,0x3e,0x56,0x4a,0x9f,0x0f,0x6a,0x76,0xb0,0xa1,0xe2,0x47,0xb9,0x6a,0x2a,0xa8,0x80,0xcd,0x2a,0x30,0x75,0xd7,0x7c,0x07,0xfb,0xd3,0xf2,0xc9,0xf7,0x2a,0xb5,0x8d,0x99,0xf0,0xbd,0xbe,0xae,0x3a,0x54,0x22,0x5b,0xd9,0x21,0x3a,0x80,0xac,0x44,0xfb,0xe3,0x30,0xf5 +.byte 0x22,0x07,0xc3,0xe6,0x4b,0xba,0x95,0x0f,0xd6,0x94,0x0f,0x2d,0x0c,0x65,0x92,0x18,0x9a,0xec,0xb3,0x0d,0x72,0x3b,0xb0,0x50,0xa1,0x6b,0x7f,0xc3,0x4d,0x5e,0x04,0x90,0x95,0x67,0xa5,0xa6,0xe6,0xb4,0xaa,0x00,0x4a,0x16,0x6b,0x0e,0xc9,0x67,0xad,0x73,0x39,0x93,0xf5,0xe0,0x4d,0xe1,0x92,0xd1,0xeb,0x3a,0x97,0xe5,0xb2,0xf8,0xce,0x53 +.byte 0x3e,0x43,0x45,0x97,0x69,0xa2,0xd5,0xc2,0x49,0xb5,0x1e,0xad,0x76,0xc3,0x7e,0xbf,0xe7,0x36,0xa5,0x5a,0xb5,0x2d,0x0e,0xc5,0xa2,0x1b,0xdb,0x3d,0x3d,0xb1,0x9a,0x84,0x43,0x3e,0x5a,0xb9,0x36,0x68,0x28,0x6a,0x60,0x33,0x1b,0xff,0xde,0xd5,0x0a,0x1b,0xe8,0xb2,0xa7,0x1f,0x52,0x97,0xf8,0x8c,0x54,0xba,0x44,0x97,0x0d,0xd4,0x40,0x0d +.byte 0x40,0x18,0x06,0xc5,0xc7,0xcd,0x4b,0xb3,0x38,0xb1,0x23,0x85,0x19,0x0c,0xd5,0x6c,0xc7,0xed,0xbe,0xeb,0x66,0x10,0x1b,0x40,0x65,0x1d,0x3a,0x0b,0xb4,0x88,0x41,0x48,0xfb,0x63,0x45,0xbe,0xdc,0x97,0x73,0x10,0x18,0x55,0xac,0x54,0xfe,0x1d,0x16,0xe9,0x79,0x1c,0xc8,0x1e,0x58,0x9c,0x9c,0xaa,0x49,0xe8,0xb3,0xab,0x4f,0xdf,0xcd,0xeb +.byte 0xb6,0xdb,0x03,0xa7,0xee,0x4b,0x7f,0x22,0x54,0x58,0xa5,0x82,0x69,0xf6,0xaf,0x00,0x9b,0x6b,0xf8,0xfb,0x0f,0xfd,0xc3,0x6f,0x91,0xcb,0x47,0xee,0x79,0xdf,0x7c,0x01,0xb3,0xd8,0x0d,0x44,0x8c,0xbb,0xc7,0xa2,0x9c,0x74,0xcb,0xc7,0xc8,0x4b,0x3d,0x4e,0x83,0xe7,0x2c,0x7a,0xe9,0xca,0x71,0x30,0x05,0x33,0x71,0x3a,0x2e,0x9f,0xef,0xbd +.byte 0xa8,0xfc,0xc9,0x9a,0xc4,0x5b,0x43,0x1d,0xf9,0x36,0xd7,0xde,0x61,0x39,0xa2,0x75,0x8b,0xca,0xcd,0x83,0x2f,0x05,0x13,0x3f,0x51,0xad,0x8f,0x65,0x95,0x50,0x40,0x56,0xc1,0x13,0x1d,0xda,0xd9,0x6d,0xe7,0x3d,0x75,0x13,0x01,0x65,0x0c,0xfe,0x6b,0xaf,0x14,0x5e,0x09,0xa3,0xfa,0x28,0x39,0xdd,0xd4,0xec,0x17,0x43,0x04,0xe1,0x12,0x5f +.byte 0x5e,0xf9,0x3d,0x75,0x19,0x5e,0x08,0x17,0xe7,0xff,0x7a,0xf7,0x68,0x8e,0x05,0x37,0x65,0xb1,0x73,0xf1,0xb8,0xec,0x85,0x06,0xee,0x0a,0x43,0x2f,0xfb,0x93,0x51,0x50,0xb3,0xae,0xca,0xa2,0x8a,0xf0,0xd7,0x31,0x7f,0x1f,0x83,0x98,0x9e,0x06,0xce,0x12,0x32,0xb1,0xba,0x84,0x7d,0x8e,0xc9,0xe7,0x84,0x5b,0x52,0xe8,0x91,0x90,0x76,0xf4 +.byte 0x00,0xce,0x8a,0x94,0x84,0x18,0x24,0x07,0xb4,0x42,0x1d,0xe1,0x8c,0x3b,0xf7,0xc8,0xa1,0xbd,0x74,0xdc,0xfd,0xe5,0x5b,0xf2,0xd6,0x12,0xb9,0x41,0x8c,0xa6,0x26,0x9a,0x01,0x1f,0x8e,0x87,0xa9,0xf0,0xfd,0xcb,0x70,0xb5,0xc7,0x42,0x22,0x1f,0x77,0xf0,0x89,0x83,0x22,0xde,0x0d,0x8f,0x37,0x7a,0x42,0x96,0xb9,0x99,0x3b,0xf6,0x25,0xd5 +.byte 0xc4,0x81,0xbe,0xbf,0xc1,0x72,0x84,0x14,0x2d,0x40,0xe1,0x65,0xaf,0x46,0xd9,0x23,0x47,0x3b,0x13,0x15,0x83,0xe4,0x66,0x07,0x20,0x38,0xec,0xc8,0x62,0x81,0x9e,0x9c,0xcc,0xf7,0x3e,0x5d,0x2c,0xbc,0x67,0x0d,0x8c,0x3b,0xd5,0x46,0x37,0xef,0x0e,0x79,0x68,0x57,0xa3,0xa9,0x09,0xfc,0xe8,0xa4,0x75,0xd3,0x0a,0x8f,0xfd,0xb0,0xd7,0xbd +.byte 0x26,0xf7,0xb7,0x1f,0x18,0xbc,0xff,0x02,0xc3,0x1b,0x00,0xea,0x3b,0xf5,0x04,0x00,0x53,0x94,0xc6,0x09,0x08,0x20,0x37,0xcd,0x6c,0xa8,0x9d,0x79,0xcf,0xe9,0x27,0x5e,0x12,0x9a,0xa1,0xcd,0x7d,0x92,0x52,0x52,0xc4,0xbf,0x54,0x45,0xb8,0x99,0x20,0x0d,0xdb,0xb7,0x6c,0x25,0x00,0xa2,0xd3,0x1a,0x8e,0x3a,0x60,0x2f,0x5e,0x16,0x04,0xcb +.byte 0x04,0xc9,0x63,0xf9,0x3d,0x66,0xfd,0xb8,0x73,0x70,0x60,0xdd,0xfa,0x6b,0x96,0xfb,0xb1,0x6c,0x34,0xa2,0x76,0xea,0x40,0xa7,0x24,0xac,0x31,0xb6,0xef,0xe6,0xbb,0xfb,0xcf,0xfc,0xff,0x88,0xa4,0x79,0xdc,0xa7,0xe1,0x52,0xd7,0x6f,0x1c,0xf4,0x40,0x2b,0xcd,0xf7,0x95,0x3f,0x9c,0xbd,0xae,0xba,0xb3,0x9b,0xbe,0xf7,0x5f,0xc4,0x8b,0xe8 +.byte 0x85,0x74,0xdc,0x51,0xe5,0x7f,0x4f,0xd7,0x54,0x93,0x7b,0x4b,0x52,0x48,0x48,0x99,0x75,0x92,0x97,0x3c,0xf3,0x4e,0x37,0x9c,0x15,0xd5,0xc3,0xeb,0xec,0x8e,0xe5,0x26,0x85,0x5c,0x95,0x23,0x09,0x1d,0x98,0x4b,0x65,0x7c,0xac,0x84,0xb9,0xc5,0xad,0x07,0xad,0x8b,0x4d,0xd9,0xc2,0x54,0x64,0x24,0x4f,0xb3,0xb8,0x04,0xca,0x35,0x20,0x70 +.byte 0x92,0xe1,0x4b,0x0a,0x93,0x8e,0x25,0x68,0x78,0xcf,0xa1,0xbd,0x25,0x81,0x49,0x78,0x2f,0x78,0x67,0x40,0xef,0xa6,0x46,0x87,0x07,0xb2,0x56,0xbf,0x16,0xfd,0x64,0x24,0xf6,0x60,0xbf,0x54,0x66,0xc0,0xcc,0x99,0x6b,0x4e,0x39,0x9a,0x27,0x67,0xaf,0x1d,0x6e,0x46,0x6c,0x5c,0xd8,0xf4,0x8b,0xee,0x1b,0x3f,0xe8,0xe6,0xf8,0xbd,0xae,0x9a +.byte 0x96,0x12,0xb4,0xe9,0x47,0x4b,0xfe,0x32,0x9e,0x84,0x44,0x51,0x14,0xe6,0xea,0x03,0xaf,0x45,0xc5,0x2c,0xc3,0x1c,0xc6,0x76,0x81,0xaa,0x38,0x1c,0x37,0x02,0x35,0x36,0x72,0xc1,0xa5,0x9b,0xf5,0x17,0xaf,0xe4,0xdb,0x95,0x2a,0x6e,0xb4,0xb2,0xdd,0x6e,0x02,0xa9,0x74,0xd7,0x51,0xb9,0x21,0x8f,0x34,0x74,0xdf,0xd4,0x70,0x13,0x9c,0x33 +.byte 0x4e,0x9b,0x5d,0x6b,0x1c,0xd0,0x3c,0xd1,0x0d,0x47,0xc7,0xb3,0x8d,0x2c,0x40,0x3a,0x35,0xf2,0xab,0x83,0x4b,0x1a,0x04,0x29,0xd3,0xae,0x28,0x45,0x1f,0x85,0xf2,0x63,0x01,0x47,0x2b,0xe0,0xf5,0xc4,0xc3,0x11,0xa5,0x09,0x11,0x23,0xd2,0xfc,0xde,0xd4,0xf7,0x42,0x28,0x78,0x87,0x37,0xc0,0xe5,0x7b,0x79,0xb0,0xe4,0xed,0x4c,0x6f,0x13 +.byte 0xa6,0xda,0x66,0x69,0xef,0x42,0xe4,0x04,0x09,0xca,0xef,0x35,0x13,0x2d,0x33,0x2f,0x6f,0xe1,0x46,0x40,0x75,0x5f,0xbf,0x35,0xb1,0xbc,0x86,0x95,0x16,0x37,0xaa,0x92,0x86,0x6f,0xdd,0x96,0x1e,0x13,0x88,0x75,0xc5,0xeb,0x29,0x1a,0x91,0xae,0xd3,0x0b,0xa1,0x14,0x4a,0xad,0x39,0xa4,0xd2,0xf1,0x51,0x61,0x9e,0x54,0xc6,0x8d,0x36,0xdf +.byte 0x95,0x1d,0x9c,0xf7,0x73,0x64,0x71,0xca,0xd2,0x6b,0xde,0x8c,0xa1,0x0d,0x4a,0x07,0x79,0x35,0x5f,0x4b,0xde,0xeb,0xb6,0x36,0xd1,0xe0,0xb3,0x32,0x00,0x62,0x03,0x0a,0x01,0x4a,0x95,0xeb,0x1d,0x6a,0xcc,0x9b,0xec,0xaf,0x76,0x70,0x04,0xd3,0xbd,0x3b,0x11,0xc6,0xd6,0xf1,0xf5,0x0d,0x08,0xdd,0xaa,0x8d,0x40,0xb1,0xfd,0x09,0xda,0x01 +.byte 0x32,0x13,0xe0,0x5a,0x46,0x82,0x10,0x26,0x2e,0xe5,0xd8,0xed,0xbc,0x03,0x1d,0x0f,0xd2,0x45,0x5c,0xda,0xd7,0x7e,0xb2,0xde,0x68,0x7a,0x3a,0x5a,0x4d,0x37,0xcb,0xae,0x0b,0x4a,0x92,0x7d,0x47,0x6e,0x19,0x93,0x62,0x3e,0x09,0xfe,0x0b,0x78,0x22,0xcf,0x62,0xa3,0x03,0x9e,0xa5,0x05,0x7b,0x81,0x3d,0x86,0x2e,0x00,0x4f,0xb9,0xdc,0x5c +.byte 0x5e,0x38,0x37,0x98,0x9c,0x2c,0xf2,0xd4,0x2e,0xe3,0xc7,0x62,0x9f,0x62,0xbe,0xfa,0x6b,0xd6,0x2c,0x9f,0x89,0xed,0x2f,0xb0,0x50,0x29,0xa6,0x71,0x5c,0x92,0xea,0x6d,0xc7,0x77,0x36,0x43,0xbf,0x89,0x49,0xfe,0x3f,0x95,0x66,0xe6,0xfe,0x39,0xda,0x8b,0xda,0x5a,0x8f,0xf3,0x0b,0x5d,0xb0,0x2f,0x8c,0xb3,0xb4,0xbd,0x8c,0x18,0xb9,0xf8 +.byte 0x70,0x2a,0xa2,0x23,0xe6,0x6b,0x21,0x26,0x07,0x60,0x00,0xa7,0xf5,0xa8,0x2f,0x57,0x35,0x06,0xe2,0x42,0x40,0xbd,0x39,0xda,0xb9,0x13,0x1b,0x29,0x6e,0x9b,0x16,0x40,0x1d,0xe8,0x5e,0xc1,0xa0,0x01,0x4b,0x70,0x95,0x11,0xb9,0xc3,0x6c,0xd0,0xe1,0x2f,0x5e,0x44,0x92,0xb5,0x2d,0x2e,0xdd,0xe8,0xfa,0xfa,0x0f,0xff,0xcc,0x9e,0x6c,0x81 +.byte 0x56,0x75,0xc6,0xb8,0x92,0x58,0x83,0xd1,0x05,0x8d,0x5a,0x19,0xeb,0x43,0xbd,0xea,0xc4,0xac,0x8a,0x54,0xab,0x7c,0xc6,0x41,0x60,0x9f,0x36,0x9a,0x11,0xbe,0x10,0x0c,0x39,0x05,0xf0,0x7d,0xad,0xbe,0xcd,0x5d,0x14,0x24,0x4a,0x0f,0xa6,0x86,0x72,0x15,0xcc,0xd7,0xd3,0xc1,0x26,0xd7,0x90,0xb0,0xf7,0x62,0x31,0x73,0xa9,0xcb,0x85,0xeb +.byte 0xa4,0x03,0x41,0xcc,0x60,0x4b,0x46,0xf4,0x9f,0xe6,0xc0,0x0e,0x69,0xf8,0x4c,0x4a,0x51,0xe2,0x2a,0x42,0xc2,0x32,0xcd,0x57,0x81,0xfb,0x6a,0x6e,0x01,0x12,0xe6,0xe3,0x58,0xd2,0xaf,0x28,0x64,0x56,0xb8,0x27,0xa2,0x73,0xba,0xe4,0x83,0x57,0x0d,0x5d,0xd1,0x15,0xd0,0x62,0xb8,0x79,0x97,0xc9,0x0b,0xb4,0x42,0xe1,0x2d,0xb8,0x58,0x2c +.byte 0xa6,0x8a,0x68,0x78,0x05,0x6c,0x95,0x25,0x9d,0x8f,0x14,0x0c,0x76,0xe6,0xb4,0x0e,0x40,0xf7,0xb8,0xbe,0x5d,0xc6,0x08,0xe5,0x74,0x5b,0xb0,0xf7,0x68,0x0c,0x71,0xa9,0x1b,0x2f,0x39,0x64,0xf2,0xb9,0x2d,0xbc,0x38,0xdd,0x93,0x06,0xe9,0x23,0x31,0xe4,0xf4,0xdb,0x66,0x50,0x3a,0x23,0xce,0xee,0x69,0xfd,0x39,0xe5,0xb5,0x15,0xf0,0x14 +.byte 0x59,0xa3,0xa1,0x78,0xb5,0x51,0x96,0x07,0x29,0x15,0x48,0x36,0xf1,0xef,0xf4,0xeb,0x90,0xea,0x3d,0xdd,0x43,0x3c,0x6e,0x85,0x8c,0xe7,0x2f,0x68,0xc4,0x16,0x82,0xf4,0x22,0x45,0xf8,0xdb,0x23,0x2c,0xb0,0xa6,0x73,0xed,0x99,0x16,0xac,0x57,0xf4,0x9d,0x5f,0x3c,0x82,0x49,0xdd,0x57,0xba,0x36,0xec,0xfc,0xd7,0x6a,0x0b,0x8a,0x24,0x80 +.byte 0xbc,0x4a,0x0d,0x7b,0xae,0x54,0x76,0x70,0x93,0x5f,0x0b,0xff,0x8b,0x67,0xf1,0xb6,0x79,0xa8,0xf9,0x8e,0x06,0xb4,0x4d,0x3f,0x01,0x4e,0x17,0x97,0xeb,0xf2,0x65,0xec,0xee,0x42,0xd1,0x67,0x66,0x33,0x6a,0x6b,0xb1,0xdf,0x59,0xef,0x86,0xb5,0xda,0xaf,0x57,0x12,0x17,0x8f,0xbc,0xeb,0xcb,0x29,0x28,0x69,0x67,0x5e,0x5d,0x11,0x4d,0x18 +.byte 0xaa,0xd8,0xd6,0x27,0xb8,0x9f,0x41,0x37,0x8a,0xde,0x99,0x50,0xb1,0x58,0x45,0x22,0x95,0x84,0xec,0x73,0xb6,0xa6,0xc3,0xf8,0xe7,0xc1,0xe3,0x88,0x27,0x91,0x33,0xae,0x15,0xba,0x8b,0x04,0xf8,0x96,0x2e,0x8b,0x78,0x21,0x6b,0x86,0x23,0x82,0xde,0xd6,0xb2,0x86,0xfe,0xb5,0xfc,0x57,0x1b,0x45,0x69,0xd1,0x6a,0xb3,0x64,0x11,0xdc,0xf7 +.byte 0x22,0x25,0x50,0xc1,0xc7,0xc1,0x72,0x92,0xf9,0x27,0x1e,0x41,0x1a,0xd9,0x5b,0x42,0xac,0x8b,0x5c,0x32,0x03,0x2f,0x45,0xb5,0xb1,0xa5,0x13,0xd9,0x9c,0x47,0x18,0xdc,0xb9,0x46,0xd6,0x15,0xbc,0x8d,0xaa,0x91,0x0a,0xa7,0xf8,0xc5,0x0f,0xb5,0x76,0x17,0xf3,0xd6,0x51,0xd7,0x8a,0x3d,0x6f,0x03,0x2f,0xcf,0x38,0xd0,0xe4,0xac,0x0e,0x0f +.byte 0xbc,0xe2,0x12,0x52,0x6b,0xd5,0x3e,0x85,0x0a,0x19,0xd5,0x47,0xdd,0x17,0x7e,0x5a,0x5d,0x5f,0xf0,0x1a,0xac,0x21,0x96,0x3d,0x62,0xc7,0x6c,0x47,0x7e,0x25,0x77,0x6b,0x24,0x4d,0xf2,0x39,0xb6,0xb9,0xaa,0x92,0x94,0x79,0x81,0xd9,0x13,0x07,0x8f,0x51,0xe6,0x16,0x80,0x36,0x3b,0x97,0x8e,0x96,0x41,0xaf,0x28,0x2d,0x1f,0x41,0x00,0x7a +.byte 0x42,0x0c,0x1b,0x59,0xc1,0xee,0xae,0x1a,0xa2,0x3f,0x76,0x4e,0x25,0xb0,0x75,0xd2,0x65,0xdd,0xfb,0xcf,0xee,0x11,0xd7,0xac,0xff,0x62,0x00,0xd2,0x76,0x24,0x98,0x0c,0xdb,0x52,0x83,0xb8,0x5c,0xa2,0x3e,0xe8,0xad,0x45,0xd5,0xfa,0x12,0xcb,0xe8,0x64,0x3a,0x41,0x2c,0x34,0x04,0xe9,0x9b,0xea,0x6c,0xa6,0xcc,0x72,0x1d,0x28,0x79,0x43 +.byte 0x59,0x0c,0xdf,0xa7,0xf8,0x7e,0x2c,0xf2,0x6a,0xd5,0xe9,0x5f,0xdf,0x5a,0xcc,0x66,0x3a,0x99,0x68,0xec,0x5b,0xa9,0x1f,0xd8,0x80,0x7a,0x5a,0x8a,0xa1,0xf0,0x80,0x8d,0x17,0xfd,0xd7,0xab,0x9e,0x3a,0xc6,0x4b,0xc8,0x1d,0xf9,0xba,0x29,0x15,0xc2,0x73,0xa7,0xab,0x83,0x56,0x9d,0x5e,0x91,0x3a,0xce,0xe0,0x31,0x64,0x00,0x06,0x42,0x70 +.byte 0x5f,0x4d,0x08,0xe7,0xf0,0x5b,0x10,0x71,0x0c,0xf8,0x93,0x34,0x9b,0xef,0x4a,0x78,0xc3,0x24,0xa9,0xb5,0xe0,0x3a,0xf0,0xf3,0xf3,0xf1,0x7d,0xb2,0x1d,0x25,0xeb,0x51,0xa3,0xd3,0x26,0xcd,0xaa,0x41,0xd0,0x64,0xbc,0x14,0x99,0x24,0xb3,0x17,0x4b,0x6d,0xa7,0xa7,0x3c,0xff,0xe9,0xfb,0x60,0x24,0x86,0x9c,0x44,0x91,0xc9,0xf0,0x85,0xbd +.byte 0x4c,0x09,0xee,0x6e,0x43,0x49,0xb9,0xc3,0xf6,0xce,0xee,0x01,0x3e,0x44,0x76,0x76,0xa3,0xd3,0x41,0xf6,0xdf,0xcf,0x0f,0x5e,0xfa,0x83,0xdc,0x7f,0xa1,0x89,0xc4,0xbb,0x3b,0xa4,0xf9,0xbb,0x87,0x3a,0x04,0xfc,0x9d,0x21,0xa7,0xe0,0x1e,0xca,0x7c,0x61,0xf6,0x91,0xdb,0xa9,0x29,0xa2,0xed,0x81,0x23,0xd7,0x8d,0x48,0x8b,0x18,0xbf,0x74 +.byte 0x71,0x9e,0x65,0x65,0xca,0x2c,0x88,0xcb,0x3c,0xcf,0xda,0xc8,0xf5,0x02,0x83,0x5e,0xdd,0x6c,0xbe,0x1d,0x53,0xe3,0xe1,0xd2,0xb1,0xc5,0xf8,0xce,0x0e,0x67,0xb8,0x87,0xf0,0xee,0x86,0xde,0x06,0xc9,0xec,0xe0,0x81,0x98,0xde,0xb6,0x4d,0xb2,0x80,0x04,0xc8,0x68,0x34,0xf9,0x27,0xeb,0xd6,0x3b,0xb3,0x99,0x8d,0xa0,0xf5,0xa3,0xe6,0x87 +.byte 0x29,0xe0,0x9b,0x5b,0xa1,0x18,0x82,0x04,0xd3,0xb9,0xfd,0xe3,0xe6,0x9a,0xaf,0xde,0x69,0x93,0x3d,0x9a,0x6e,0x77,0xf1,0xa9,0xf5,0x00,0x59,0x20,0xba,0x25,0x84,0xd8,0xfd,0x6f,0x0d,0x61,0x0c,0x2f,0x6f,0xe5,0xe1,0x92,0xc9,0x62,0x0c,0xb3,0xef,0x52,0xcf,0x61,0x9b,0x74,0x39,0xb5,0x84,0xdc,0x96,0xb4,0x54,0xb2,0x96,0x98,0xf2,0x4e +.byte 0xb9,0x45,0x6f,0x39,0x3a,0x60,0x5d,0x42,0xc5,0x4a,0x68,0x86,0x55,0xd3,0x5f,0x3d,0x26,0xe0,0x7d,0x46,0xcd,0xb5,0x56,0x4e,0x03,0xaa,0x29,0xec,0x5e,0xb7,0x86,0xc0,0x9a,0xa0,0xaf,0xe1,0xb7,0x90,0xd4,0xd3,0x6b,0xb4,0x26,0x3f,0x93,0x32,0x49,0x73,0x40,0x8c,0xd1,0x6f,0x57,0xe9,0x4a,0x8b,0x04,0xd3,0x25,0x57,0x95,0xf5,0x64,0x4c +.byte 0xed,0xa5,0xdf,0xf5,0xf6,0xa1,0xff,0xba,0xb2,0x0d,0x63,0x6c,0x54,0x12,0xf7,0x6f,0xa3,0x57,0x3d,0xf0,0xcd,0x9b,0xb8,0x02,0x1e,0xf6,0x52,0x79,0x57,0x43,0x2e,0x9d,0xc4,0xc2,0xc1,0x3e,0x6c,0xa5,0x32,0x42,0x00,0x35,0xaa,0x6a,0xe4,0x1d,0xa5,0x5a,0x83,0x59,0xb4,0xe7,0x3a,0xca,0xeb,0xe5,0xcd,0xf8,0x24,0xc8,0x05,0xf4,0xea,0x6a +.byte 0x82,0xbb,0x89,0xa5,0xb2,0xdf,0x5d,0x69,0x9b,0x73,0x0d,0x26,0xd1,0x5d,0x8f,0xaa,0x4a,0x4e,0x7f,0xe1,0x25,0x07,0x67,0x9f,0x2c,0x59,0xa7,0x4d,0x4c,0x44,0x67,0x5b,0xff,0xac,0xaf,0x9a,0x1c,0xc8,0xa8,0x6c,0x34,0xd4,0xfe,0x90,0x2a,0x24,0xd5,0xbf,0xb4,0xa4,0xe3,0x51,0x94,0x38,0xf9,0xd0,0xad,0x3f,0xc5,0x1e,0x72,0x56,0xdf,0xda +.byte 0x31,0xbe,0xf0,0x8d,0x79,0xa9,0x96,0x23,0x27,0x0a,0x61,0x3a,0x6c,0xb5,0xd6,0x37,0x51,0xd0,0x5c,0xbb,0x33,0x34,0x36,0x81,0xcb,0x37,0xfb,0x89,0x00,0x97,0x0e,0x98,0xb8,0xe1,0x3a,0x83,0x40,0x98,0xff,0xaf,0x9c,0x3b,0xfa,0xda,0xa6,0x80,0x6d,0xb0,0xd5,0xe6,0xa2,0xaf,0xbc,0x15,0xc1,0xc3,0xad,0x2d,0x5d,0x76,0x11,0xf3,0x09,0x0b +.byte 0xfa,0x92,0x7f,0x92,0xd6,0x7a,0xf1,0xf8,0x75,0xa4,0x46,0x20,0xcb,0x4a,0x63,0x48,0x88,0x0e,0x1a,0x28,0xbc,0x3a,0xfe,0x62,0xf3,0x17,0x75,0x00,0x47,0x7a,0xea,0xcb,0x17,0x6d,0xfc,0xf1,0x17,0xfc,0x19,0xfd,0xd8,0xaa,0xc2,0x64,0x59,0x84,0x14,0x56,0x61,0xa4,0x6d,0xe8,0xae,0xe1,0x8a,0x15,0x10,0xe4,0x98,0x88,0x4e,0x89,0xdc,0xba +.byte 0xbd,0x8b,0x79,0xe0,0xec,0xcd,0x3d,0x7a,0x14,0x11,0xd1,0x71,0xf3,0xc1,0xb8,0xf8,0x2e,0x7e,0x83,0x42,0x62,0xea,0x01,0x6f,0xdd,0x2c,0xc6,0xc4,0x52,0x94,0x8d,0x52,0x59,0x41,0xb3,0x42,0xf2,0x15,0xc5,0x16,0xf6,0x1c,0xa8,0xd2,0x2e,0xa2,0x91,0x97,0x5e,0xc8,0x5c,0x29,0x3b,0xa2,0x91,0xaf,0x55,0xf1,0x42,0x5b,0xbc,0x2f,0x95,0x91 +.byte 0x68,0x00,0x48,0x7d,0xd5,0x4e,0x3e,0x1b,0xba,0x03,0x41,0x1f,0x0b,0xd8,0x9a,0x04,0x3c,0x3d,0x45,0xff,0xe8,0xd5,0x81,0x06,0xb1,0x96,0x27,0x46,0x14,0x31,0xe1,0x11,0xc6,0x46,0x59,0x97,0x24,0xd9,0x92,0x98,0x04,0x32,0xb1,0x2b,0x2b,0xe6,0x12,0xbd,0x9a,0x72,0xcc,0xff,0x26,0x8c,0x07,0x19,0x1c,0x1c,0xf1,0x66,0xf0,0x60,0x12,0x28 +.byte 0x61,0x64,0x73,0xdf,0x4e,0x95,0x14,0x46,0x32,0xb1,0x62,0xf2,0xcc,0xd2,0xcf,0xeb,0x50,0x05,0x3d,0x5a,0xf1,0x6b,0xfb,0xe2,0x7f,0xeb,0xbc,0x91,0x15,0x86,0x36,0x18,0xde,0x72,0x3a,0x9e,0x81,0xa4,0xcb,0x7a,0xdc,0x11,0x73,0xb4,0xf8,0x3d,0xa8,0xcb,0x87,0xcd,0xdc,0x18,0x51,0x64,0x90,0x29,0xbe,0xdc,0xcf,0x3c,0xc8,0xe0,0xe8,0xb3 +.byte 0x9a,0x15,0x38,0x00,0x22,0xd9,0x2d,0x18,0x9a,0xdd,0x69,0x3b,0x04,0x0b,0xa7,0xb6,0x5d,0x12,0xd2,0x4b,0xf2,0x8c,0x4d,0x6f,0xef,0x39,0x2d,0xe9,0xfe,0xec,0xb3,0x99,0x87,0x1e,0x54,0xa7,0xc9,0x99,0xa1,0x70,0x70,0x34,0x04,0xc8,0xa2,0x4c,0x6b,0x43,0x83,0x6f,0x60,0xf7,0xef,0x01,0xd8,0x9a,0x01,0x55,0xa7,0x3e,0x52,0xbf,0x3d,0x5f +.byte 0xba,0xc7,0x3d,0x4f,0xc9,0xad,0x47,0xf9,0x07,0x8a,0x88,0x13,0x80,0x69,0x4b,0xb8,0x41,0x9d,0xc7,0x93,0xc3,0xc0,0xc0,0x64,0xda,0x8f,0x9e,0xa7,0xb7,0x52,0x67,0x81,0x50,0x42,0x7c,0x2b,0x35,0x37,0x1f,0xfe,0x0a,0x15,0xa5,0xa0,0xe3,0xcd,0xe9,0x9d,0xbc,0xd7,0xcc,0xec,0x35,0x74,0xef,0x61,0xf9,0xb2,0x32,0x32,0x84,0x0c,0x6c,0x6e +.byte 0x52,0x84,0x01,0x45,0x05,0x84,0xd8,0x58,0x73,0x0a,0xda,0x1f,0x90,0x91,0x40,0xcd,0xdd,0x5d,0xa9,0xfc,0x03,0x2f,0xd0,0xa5,0xa7,0xa8,0x2c,0x3e,0x73,0xcc,0x58,0xc3,0xd0,0x2b,0xa9,0x20,0x14,0x11,0x63,0x13,0x84,0x60,0x05,0x76,0x89,0x1e,0x59,0x9b,0x0e,0xfa,0x4c,0x7f,0x29,0x79,0xda,0x83,0xfa,0xe1,0xbe,0x38,0xa0,0x7a,0xf2,0xd2 +.byte 0x41,0x72,0xe8,0xa4,0xa2,0x38,0x78,0xc8,0x4a,0xee,0x3d,0x5b,0xe8,0x63,0x0e,0xf1,0x53,0x30,0x87,0x0d,0x4f,0xe0,0x21,0xf4,0x91,0xc9,0xc2,0x5e,0x23,0x41,0xee,0x7b,0xd3,0x4e,0x7d,0x2d,0xa6,0x5f,0x3a,0x5c,0xb4,0xfa,0x25,0x32,0x3e,0x57,0x8d,0x99,0xa5,0xe5,0x10,0xe9,0x86,0x32,0xd5,0x94,0xb5,0xc3,0xc4,0xa8,0x98,0x17,0x9b,0x8b +.byte 0x10,0xa8,0x3f,0x4c,0x55,0xc7,0xa0,0x3f,0x77,0x4e,0x89,0x85,0x95,0x41,0xdf,0x2c,0x37,0xe4,0xc0,0x57,0x77,0x60,0x90,0xce,0xfc,0x86,0x87,0x9f,0x8c,0xfb,0x34,0xef,0xe4,0x33,0x7b,0x65,0xd4,0x56,0xe4,0xf1,0xa6,0x17,0x3b,0xda,0xf9,0xcb,0x7d,0xd5,0x41,0x77,0x0a,0x15,0x20,0xf6,0x0d,0x10,0x4b,0xc6,0x93,0x3d,0xe3,0x30,0x37,0xf1 +.byte 0x65,0x31,0x66,0x75,0xaf,0xec,0x76,0x31,0xcb,0xd1,0xc3,0xd4,0x49,0xb3,0x69,0x1a,0x37,0x76,0xa0,0x7f,0x21,0x39,0x53,0xc2,0xa8,0xd4,0xb2,0x7c,0xf6,0x82,0xf0,0x98,0x7b,0xf1,0xd2,0xc2,0x5f,0x07,0x78,0x67,0xb4,0xaa,0x55,0xb4,0x53,0xed,0x7a,0x5b,0xed,0x10,0x2e,0x13,0x93,0xf6,0xaa,0xec,0xe7,0x6c,0xa1,0x97,0xd2,0x7e,0x87,0xd2 +.byte 0xa6,0xad,0x1a,0x31,0xee,0xa8,0xa3,0x7d,0x02,0x3c,0xe7,0x10,0xef,0x3d,0x2f,0x59,0x13,0x00,0x69,0x9d,0x79,0xba,0xa2,0xb9,0x39,0xa1,0x7a,0x7d,0x6d,0xe8,0x01,0x68,0x59,0x16,0x81,0xd3,0x63,0x94,0xd1,0x55,0x57,0x55,0xaf,0x1e,0x38,0xff,0x07,0x3a,0xb1,0x91,0xd6,0xd3,0xce,0x76,0x41,0x40,0x67,0x9e,0xf5,0x13,0xa0,0x63,0x44,0xeb +.byte 0x16,0xe8,0x33,0xc2,0x56,0x03,0xc9,0xc0,0x32,0xa7,0x04,0xe1,0x5b,0x50,0xd6,0x15,0xa1,0xdd,0x8f,0x35,0x0f,0xe5,0xed,0xb2,0xb5,0xeb,0x22,0x45,0xce,0x0c,0xb6,0x18,0x46,0x38,0xcf,0x8d,0x89,0xc2,0x8d,0x14,0x25,0xb3,0x69,0x8e,0x23,0xb5,0xa4,0x83,0xac,0x21,0x5d,0x34,0xea,0xbb,0x49,0xa6,0x4e,0xfb,0x60,0xdd,0x4a,0xe3,0x1b,0xdb +.byte 0x22,0xf7,0x9c,0x09,0x0d,0xa4,0x00,0xc0,0x7e,0x6f,0xb2,0x7a,0x59,0xc9,0x8a,0x53,0xdf,0x4b,0xf2,0x31,0xdd,0xd7,0xe0,0x4a,0xea,0x1e,0xc1,0x71,0x3a,0x7c,0xef,0xad,0x7f,0xf5,0x3f,0xbb,0x81,0x52,0x67,0x60,0x46,0xaf,0x14,0xc9,0x77,0x63,0xa1,0xb0,0xc5,0xac,0x24,0x52,0x9f,0x32,0xf8,0x9e,0xc0,0x04,0x4d,0x6b,0xfd,0x7a,0xd4,0x1c +.byte 0x68,0xaa,0xc8,0xc1,0x8b,0x41,0x31,0x69,0xbd,0x9d,0x46,0x17,0xc1,0x8a,0xdf,0x3c,0x78,0xa2,0xca,0x28,0x1b,0xf8,0xab,0xe3,0x61,0x5e,0xb2,0x31,0xac,0xf2,0xd1,0x01,0xe7,0x24,0x46,0x96,0xa6,0x81,0xb3,0x4a,0xc0,0x0e,0x23,0x52,0x7f,0xa9,0x49,0x98,0xfa,0x6b,0xfd,0x0a,0x7b,0xb7,0xc5,0xcf,0x85,0x74,0xe1,0x3b,0xde,0x37,0xa9,0x22 +.byte 0x63,0xbb,0xfc,0xd3,0x02,0x90,0x87,0xb5,0x2d,0x71,0x69,0x25,0x9a,0x0c,0xaf,0x68,0x4f,0xf0,0x71,0x86,0xcc,0x1b,0xc6,0x2d,0xb5,0x6c,0x68,0x00,0x37,0x07,0xcf,0x62,0x00,0x00,0xee,0x7d,0x8e,0xf2,0x88,0xa5,0x21,0x2f,0x33,0xf8,0x7c,0xe9,0xb3,0xe3,0xd8,0xa4,0x21,0x1c,0x81,0x4b,0x62,0xcc,0x99,0xa4,0xc6,0xfe,0x49,0x65,0x35,0xd5 +.byte 0x92,0xe7,0x42,0xa2,0x8e,0xb3,0x02,0xba,0xc4,0x49,0x3a,0x26,0x4a,0x66,0xbd,0x4e,0x75,0x67,0x44,0x08,0x52,0x14,0x06,0xfa,0xf9,0x01,0xa2,0x03,0xbc,0x5c,0x41,0xe4,0x65,0x2f,0x5d,0xf9,0xd9,0xe4,0xc7,0x30,0xbd,0xe4,0xa4,0xcb,0x77,0x2f,0x2d,0x72,0x07,0x4f,0x0b,0x2f,0x6c,0x3f,0xfd,0x0b,0x5c,0x69,0x71,0xda,0x4f,0x13,0xf1,0xa9 +.byte 0xb6,0x97,0x5f,0x7a,0x4b,0x9b,0x26,0xe2,0xe8,0x52,0x6a,0x07,0x10,0xf7,0x12,0x2d,0x0b,0x1f,0x47,0xf0,0x45,0x90,0x8a,0x5f,0xf3,0xdf,0x71,0x38,0x5d,0xf2,0x13,0x9e,0x00,0x92,0xd2,0xe9,0xa9,0x21,0x3d,0xe1,0x60,0x18,0xd6,0x06,0x11,0xed,0x80,0xeb,0x3c,0x70,0x62,0x29,0xb0,0xff,0x67,0x6e,0xe1,0x6f,0xd0,0x73,0x10,0x61,0x6d,0x03 +.byte 0x03,0x6c,0xe9,0xf4,0xba,0xe2,0x31,0x50,0xc4,0x48,0x65,0x6a,0xa8,0xb0,0xc2,0x41,0x73,0xb9,0x71,0x35,0x21,0xc3,0xff,0x96,0x07,0x7a,0x75,0x62,0xfe,0x7e,0xbe,0xfb,0xed,0x8e,0x56,0xf7,0xaf,0x0f,0xcd,0xaa,0xde,0x4a,0xd7,0xfc,0xac,0x00,0xe7,0xf0,0xc8,0xe7,0xe1,0xb1,0x03,0xb8,0x0a,0x5b,0x78,0x1d,0xc8,0x1e,0x3a,0x47,0x6d,0xf1 +.byte 0x8d,0xb4,0x5d,0x71,0x15,0x7d,0xda,0x5a,0x4b,0x87,0xfa,0xaf,0x59,0x25,0x33,0x4f,0x46,0x27,0x54,0xe2,0x72,0xd2,0xe9,0x5d,0xb7,0xc3,0x1f,0x26,0xdf,0xff,0xed,0x8f,0xc1,0x91,0xa0,0x67,0xb8,0x69,0xe1,0xeb,0x6a,0xef,0x16,0xe5,0x63,0x39,0xa2,0x14,0x0c,0x20,0x1d,0xe2,0xfc,0x14,0xe4,0x6d,0xf6,0x96,0xd5,0x1a,0xfe,0x77,0x2c,0x26 +.byte 0x90,0xc4,0x7f,0xc9,0xe1,0xb1,0xc0,0xeb,0xed,0x54,0xcc,0x6a,0x94,0x4e,0x5f,0xfb,0x05,0xa5,0xd7,0x8b,0xca,0x6d,0x94,0x15,0xdd,0xb6,0xf6,0x7b,0xc3,0x66,0x33,0x16,0xa1,0xe5,0x90,0x3e,0x8f,0x72,0x5a,0x18,0x4c,0xe7,0x7d,0xd0,0x80,0xf5,0xb6,0x26,0xa6,0x6a,0xab,0xa8,0x9e,0x8f,0x2f,0xc8,0xba,0xe6,0xeb,0x8b,0x5b,0x09,0xb6,0x95 +.byte 0x46,0xb7,0x01,0x4e,0xbf,0x7f,0x6f,0x5d,0x64,0xfd,0x8b,0x5d,0xfe,0x2d,0xd6,0x6d,0x3f,0x34,0xc2,0xa1,0x97,0xf1,0x7a,0x1e,0x83,0x0a,0x06,0x09,0x75,0xc2,0x27,0x18,0x80,0x49,0xc9,0x7b,0xd2,0x40,0xfb,0x48,0x54,0xb4,0x22,0x30,0x7f,0xea,0x87,0x70,0x59,0xfb,0xa7,0xb6,0x63,0x33,0xb2,0x5a,0x3c,0x47,0x83,0x3c,0x81,0x34,0x50,0x2f +.byte 0x0e,0x95,0xb1,0xdc,0x44,0x67,0x94,0xf4,0x0c,0x1e,0x12,0xb8,0xfb,0xc6,0xd3,0x9f,0xaa,0xa8,0x77,0x80,0x71,0x4d,0xb0,0xb8,0x90,0x69,0x1b,0x45,0x88,0x7a,0x0f,0x60,0x7c,0x06,0x64,0x64,0x5e,0x2b,0x3a,0xf5,0xee,0x34,0x8a,0xbb,0x67,0x72,0x38,0x97,0xfd,0x8b,0x3d,0xe9,0x08,0x74,0x2e,0x9a,0xca,0xc8,0x74,0x5f,0x6f,0xd5,0xf7,0xfb +.byte 0xd8,0x3f,0x49,0x81,0x44,0x68,0xe0,0xbe,0x11,0xee,0x81,0x19,0xab,0x0e,0xe5,0x18,0x7a,0xbc,0x64,0xc9,0x88,0x4b,0xd1,0x72,0x7d,0xfa,0x57,0x5d,0x52,0xbe,0x36,0x85,0xb6,0x28,0xec,0xce,0xbd,0x68,0xa7,0xc0,0x43,0x15,0xcf,0x89,0xe9,0x13,0x72,0x23,0xa7,0x2e,0x12,0x03,0x87,0x0b,0xcd,0xe3,0x67,0xe6,0xbf,0x92,0x69,0x06,0xd1,0x51 +.byte 0x1d,0x0a,0xea,0x48,0xdb,0x27,0x95,0x55,0xa6,0xca,0x44,0x62,0x66,0xa5,0xaa,0x36,0xfa,0x42,0x7c,0x16,0xb9,0x8f,0x07,0x78,0x2f,0x03,0xf3,0x58,0x8a,0x15,0x82,0x35,0xb4,0xa9,0x2e,0x4e,0xb1,0x86,0xf2,0xc8,0xaf,0x94,0xdf,0x4a,0xf9,0xaf,0xa6,0x6c,0xf0,0x6d,0x32,0x9b,0x61,0xc5,0xa7,0x64,0xc3,0xf7,0x51,0xe0,0xc1,0x8b,0xd1,0x12 +.byte 0x43,0x3a,0xab,0x59,0x64,0xa4,0xa9,0xc9,0x6f,0xb7,0x30,0x1c,0x4b,0x77,0xa7,0x15,0x98,0x76,0xb5,0xf2,0x8f,0xba,0xce,0xb5,0x8e,0x2e,0x3f,0xe4,0xaa,0xdb,0xe3,0x10,0xb4,0x42,0xbb,0x3f,0x16,0x1c,0xec,0x10,0x68,0xcd,0xf8,0x16,0x19,0x80,0xb2,0xb4,0xfc,0x9d,0x52,0x48,0x09,0xda,0x94,0xb9,0xf1,0x00,0xfe,0x99,0xad,0x5c,0xae,0x5a +.byte 0xa9,0x65,0xb7,0x7d,0xaf,0xec,0xd1,0x09,0xa3,0x5e,0x77,0x01,0x86,0x78,0x79,0xaa,0x07,0x31,0x6b,0x13,0x11,0xec,0x73,0x02,0xf8,0x0c,0xa5,0x61,0xaa,0xe7,0x7c,0x4a,0xb2,0x6b,0xba,0xb5,0x5f,0xc8,0x8d,0x2b,0x2c,0xf4,0x75,0xdc,0xbc,0x84,0x01,0x4b,0x02,0x0e,0xea,0xcb,0xe1,0x87,0xb4,0xa5,0x1c,0x79,0x5e,0x3e,0xe1,0xab,0x33,0x74 +.byte 0x11,0xf6,0x9f,0x89,0x12,0x04,0x46,0xd2,0xf3,0xac,0x14,0xe8,0x32,0x54,0x26,0x78,0x61,0x8b,0x93,0xd0,0x3d,0x02,0xda,0x47,0xac,0x26,0x36,0x52,0xca,0xeb,0x9f,0xc9,0xa9,0xb4,0xcb,0xaf,0xea,0xdb,0x6e,0xfb,0x93,0x49,0x30,0x4d,0x26,0xff,0xe1,0x31,0x48,0x94,0x7a,0x81,0x69,0x0d,0x51,0x0e,0x0f,0x97,0x32,0x6d,0xd7,0xd2,0x99,0xd8 +.byte 0x40,0x68,0x97,0xf9,0xe7,0xb4,0x99,0x80,0x6f,0x3a,0x7c,0xba,0x8e,0x25,0x4e,0x22,0xb2,0x65,0x6c,0xde,0x46,0x04,0x6b,0xf7,0x18,0x44,0x68,0x73,0xab,0xbd,0x75,0xff,0xe2,0xc4,0xbc,0x95,0xfe,0x53,0x20,0xb0,0xf7,0x6f,0xea,0x63,0xf7,0xb4,0x0b,0x7f,0xf1,0x95,0x4b,0xbf,0x9f,0x58,0xf6,0xb5,0x05,0x55,0x50,0x00,0x66,0x83,0x64,0xf5 +.byte 0xb8,0x36,0xfa,0xe5,0x3f,0x58,0x71,0x0b,0x51,0xac,0x7b,0xba,0x1d,0xfb,0xd2,0xc3,0xb2,0xb8,0xa3,0x88,0x80,0x5d,0x38,0x27,0x5c,0x12,0xb4,0x9f,0x4d,0xa7,0x25,0x41,0x1f,0xf5,0x93,0xc0,0x6b,0xb8,0x2a,0x27,0xa2,0xa7,0x9e,0xcc,0xa0,0xb9,0xbf,0x18,0x31,0x62,0x31,0x4f,0x71,0xaf,0x6f,0xda,0xe4,0x75,0x08,0xcf,0x6b,0xfc,0x96,0xa9 +.byte 0xd9,0x7b,0xc5,0xc1,0x80,0x93,0xd8,0x47,0x1f,0x57,0x56,0x23,0x00,0x2c,0xc4,0x71,0x4e,0x17,0xc6,0xc1,0xff,0x8b,0x78,0xe1,0xcd,0x74,0xc1,0x42,0xc9,0x02,0x57,0xaa,0x04,0x4a,0xbe,0x1a,0xd3,0x2a,0x94,0x47,0xbd,0x0e,0x25,0x05,0x4e,0x1f,0xf2,0x19,0x1e,0x97,0xdb,0xfa,0xb1,0x4c,0x6c,0x6e,0x7d,0xf0,0x94,0x5a,0xd0,0x46,0x90,0xc7 +.byte 0x6c,0xa2,0xc6,0x20,0xd4,0x49,0x04,0xb0,0x56,0xda,0x86,0x2f,0x09,0xa7,0xc1,0xf5,0xaa,0x0f,0xbc,0x0b,0x6a,0xd5,0x41,0x5f,0x32,0xa3,0x27,0xe6,0xa1,0x03,0x58,0x28,0x06,0xb4,0xad,0x55,0x0a,0x2b,0x19,0x05,0x00,0x1c,0x98,0xbd,0xbf,0x5d,0x14,0x28,0xb0,0x7c,0x86,0x14,0xf9,0x73,0x33,0xc7,0xbc,0xd2,0x00,0x37,0x72,0xac,0x30,0x25 +.byte 0x30,0xeb,0xe2,0xb8,0xcd,0xf3,0x1e,0xad,0x93,0xf4,0xa3,0xac,0x03,0x37,0xe5,0x6d,0x73,0x80,0x4d,0x9e,0xc7,0xb4,0xad,0x7d,0xbe,0xe1,0x79,0x34,0x23,0x9f,0xbf,0x5c,0x02,0x6a,0x03,0x04,0xe3,0xd0,0x55,0x65,0x3d,0xc7,0x66,0xf3,0xfb,0xba,0x9c,0xed,0x88,0x9f,0xae,0xc4,0x83,0x69,0x99,0xd3,0x0f,0xac,0x46,0x22,0xcd,0x4e,0x56,0x27 +.byte 0x73,0x7c,0x10,0xcf,0xbe,0x34,0xe5,0x06,0xfb,0xa7,0xe4,0x28,0x59,0x0a,0x0d,0xba,0xf0,0x52,0xe9,0xf7,0xbb,0x00,0x58,0x65,0x77,0x3b,0x83,0x67,0xaf,0xd8,0x88,0x9e,0xe8,0xa8,0xda,0x76,0x4d,0xb8,0x8e,0x40,0x70,0xe3,0x95,0x3e,0xe8,0xf1,0xaf,0x5d,0x54,0x54,0x65,0x6e,0xc1,0x58,0x06,0xd0,0xc9,0x0f,0x5e,0x63,0x0a,0xfe,0x50,0xc7 +.byte 0xca,0x16,0x7d,0xd8,0x34,0xcc,0xf6,0xd2,0xb1,0x8d,0xf1,0xd9,0xe5,0xf7,0x3d,0x5f,0xe4,0x7f,0x64,0xb8,0xc3,0xba,0xc2,0x4f,0xd7,0x3a,0x78,0xed,0x8a,0x54,0xc9,0x72,0xf0,0xec,0x64,0x2e,0x20,0x27,0x97,0xea,0x8e,0x6b,0xaa,0xb2,0x52,0x13,0x67,0x66,0x89,0xc1,0x8c,0x5b,0x64,0x9f,0xd1,0x3c,0x9b,0x4f,0x9e,0x96,0x93,0xa2,0xf3,0xa8 +.byte 0x7c,0x94,0xd2,0xfa,0xd6,0xc3,0x48,0xca,0x1e,0x89,0x1a,0x62,0x52,0x92,0x01,0xc5,0x9e,0x2d,0x8b,0x4f,0xf5,0xd4,0x10,0x6b,0x33,0x0e,0x8b,0xfa,0x0c,0x80,0x05,0x50,0x0d,0x84,0x3b,0xb0,0xe4,0x27,0x63,0xc3,0x46,0x40,0xf0,0x2b,0x31,0x31,0xd3,0xf5,0x07,0xb8,0x7c,0xec,0x83,0xb8,0xff,0x9e,0x5a,0xb9,0x57,0x4a,0xe5,0x85,0xaf,0x47 +.byte 0x7c,0x36,0xb1,0x5e,0xe9,0xf6,0xe8,0x02,0xfb,0x33,0xb5,0xa5,0x6f,0x03,0x76,0x26,0x20,0x03,0x1f,0xac,0x26,0x7c,0x29,0xf2,0xbf,0xcf,0xf9,0x31,0xcc,0xa0,0xdb,0x8a,0xd1,0x06,0xc2,0x6b,0x57,0x8d,0x6a,0x02,0x02,0x37,0x84,0xa4,0xd0,0x4c,0x56,0x4c,0xfd,0x18,0x30,0x86,0x9e,0xb2,0x71,0xc2,0xc8,0xe8,0x4f,0xd7,0xeb,0xa7,0x6e,0x77 +.byte 0xeb,0x89,0xb4,0x6b,0x19,0x46,0x65,0xdf,0x74,0x10,0x82,0xe7,0xd2,0xbf,0x70,0x11,0x41,0x1a,0x87,0xc8,0xcb,0xc0,0xd8,0x2e,0xfd,0x36,0x24,0x92,0x91,0x67,0xb6,0x2d,0xc1,0x81,0xa0,0x6a,0xf9,0xb7,0x06,0x21,0x55,0x0d,0xa2,0x74,0xd9,0x24,0x35,0x00,0x42,0xd3,0x08,0xdb,0xcc,0x28,0x56,0xd4,0x9b,0x38,0x9c,0x2d,0x98,0xb1,0x56,0x96 +.byte 0x30,0xe9,0x7a,0xde,0x8a,0xbd,0x13,0xee,0x2b,0xb9,0x10,0x88,0x1a,0x7a,0x29,0x0e,0x9b,0x45,0x7b,0x37,0x14,0x7a,0xf4,0x40,0xe9,0x60,0x16,0x6c,0x0c,0x64,0x6c,0x15,0xd8,0xf8,0xc4,0xcd,0x9e,0x9a,0xa2,0xa7,0xf5,0xe3,0xd8,0xbb,0x40,0x31,0x75,0x34,0x98,0x85,0xed,0xe5,0xaf,0xfb,0x6a,0x64,0x32,0x75,0x25,0xba,0x35,0x79,0xcf,0x9e +.byte 0xb7,0x8f,0xde,0x18,0x97,0xe5,0x31,0x4f,0x52,0x69,0x50,0x05,0x94,0x8e,0xb6,0x56,0xb1,0x94,0xa6,0xa2,0x36,0x7e,0x17,0x3d,0x5e,0xb9,0xc7,0xee,0x0e,0x33,0xd4,0xeb,0x58,0xc9,0x6a,0xb8,0x3b,0x32,0x53,0xbf,0x61,0xf7,0x3f,0xec,0x7d,0x8d,0x20,0x4d,0xb4,0x38,0x68,0x3a,0x21,0x28,0x89,0x19,0x10,0xe3,0x2f,0xf5,0x74,0x77,0x39,0xe8 +.byte 0xb3,0x72,0xaf,0x50,0x30,0x36,0x1e,0xc7,0x57,0x66,0x31,0xe2,0x84,0xe1,0x05,0x94,0xd6,0xbf,0x91,0x97,0xe0,0x22,0x26,0xcf,0xeb,0x06,0x33,0x70,0x22,0x19,0x58,0xc7,0x80,0x0b,0xe8,0x26,0x35,0xbc,0x8d,0xc3,0xb0,0x97,0x7d,0x8d,0x70,0xf9,0x66,0x76,0x52,0x71,0x46,0x1b,0x6a,0x4e,0x9a,0xd1,0xa1,0xfd,0xda,0x6a,0x1b,0x6f,0x2e,0xff +.byte 0xd1,0xe4,0x23,0xd5,0xa9,0xc6,0x6a,0x5e,0x84,0x5c,0x2f,0x26,0x55,0x4b,0xbb,0xb1,0xf2,0x79,0xa5,0xfb,0xfb,0x29,0xcd,0x57,0xd2,0xef,0x45,0xbe,0x3f,0xc1,0x6c,0x4c,0xbc,0xca,0xe0,0x0b,0x6a,0x8e,0xb9,0x8a,0x2f,0x3b,0x86,0x42,0xb7,0xf5,0xa5,0x38,0x99,0x97,0xaa,0xf5,0x36,0x87,0x97,0x56,0xe1,0x03,0x76,0xb5,0xcc,0x84,0xad,0x31 +.byte 0x29,0xad,0xc4,0x93,0x47,0x07,0x00,0x91,0x47,0x0e,0x8a,0x32,0x43,0x9c,0xba,0x02,0x59,0xe5,0x62,0xc6,0xdd,0xd5,0xcf,0x0a,0xd7,0x33,0x6a,0x76,0x6a,0xa9,0x1d,0xfc,0xfc,0x0b,0x0a,0x4e,0x4e,0xed,0x8a,0xdf,0x8f,0x97,0x50,0xb2,0x1d,0xbe,0x31,0x04,0x6d,0x04,0x5c,0xf9,0x95,0x36,0xcc,0x7c,0xa2,0xaf,0x2a,0x6a,0x50,0xbc,0xf0,0xe5 +.byte 0xdd,0x1f,0xc2,0x90,0xc0,0xa0,0x33,0xcb,0x90,0x5c,0x02,0x87,0xf6,0xa1,0xf8,0xa6,0x03,0xca,0xfb,0x89,0x8e,0xff,0x82,0x6f,0x5c,0x16,0x25,0xa1,0x2c,0x0e,0xd6,0xa0,0xab,0x64,0xa0,0x4b,0x66,0x9b,0x08,0x64,0x97,0x93,0xa2,0xdb,0xf5,0xac,0x78,0x57,0x8d,0x32,0x16,0x44,0x3a,0xb9,0xd2,0xe6,0xc4,0xf3,0xb9,0x44,0x45,0x15,0x57,0x33 +.byte 0xfa,0x98,0x61,0x17,0x8b,0x7c,0x2f,0xd7,0x0c,0x14,0xf2,0xb4,0xe3,0xa7,0x50,0x71,0x57,0x1d,0xd0,0x9b,0xab,0x8d,0x4f,0x42,0x08,0x7c,0x54,0x58,0xc7,0xbf,0x17,0x15,0x64,0x91,0x7a,0xd4,0xaf,0xf6,0x6a,0x45,0xdc,0x2d,0xfc,0x80,0xd6,0x5d,0x4b,0xea,0xd7,0x45,0xe7,0xd4,0x20,0xa3,0x5f,0xda,0x73,0xa1,0x87,0x8b,0xf2,0x93,0x50,0x5c +.byte 0x20,0x89,0xbd,0xb2,0xe0,0x47,0xe6,0xf0,0x6c,0x42,0x2b,0xe1,0x1e,0xa0,0x2d,0x0f,0xf1,0x05,0x28,0xa2,0xd4,0x5d,0x12,0x95,0x0a,0x6e,0x62,0x11,0x34,0x56,0x29,0xe9,0x9d,0x45,0x5f,0x55,0xcb,0xaa,0x3a,0x59,0xe5,0x17,0xb3,0x12,0xcf,0x2a,0x10,0xa9,0x71,0x22,0x06,0xfa,0xec,0x99,0x6f,0x80,0xa3,0xfe,0x5c,0xc5,0x65,0xb9,0x34,0x19 +.byte 0xd3,0x62,0x58,0xce,0x33,0x47,0x03,0x44,0xc6,0xa0,0xd4,0x51,0x58,0xaf,0xbb,0xe1,0xaf,0x53,0xf5,0xe7,0xee,0x6f,0x70,0x7a,0x15,0xf6,0x96,0xbf,0x4a,0xbe,0x7a,0x5d,0xbb,0x54,0xe6,0x8a,0xeb,0x48,0xaa,0x96,0xad,0xde,0x1e,0x96,0xe0,0x2a,0x0a,0x09,0x01,0xfe,0x39,0xfe,0x1f,0x3a,0xef,0x2f,0xa9,0xfc,0x33,0xf1,0xec,0x05,0x24,0x5e +.byte 0xb3,0x35,0xd3,0x56,0x07,0x8b,0xe5,0xba,0xbd,0x2a,0x8c,0xf0,0x59,0xe0,0xef,0xd6,0x7c,0xe2,0x26,0xd8,0x2d,0x38,0x17,0x06,0x11,0x90,0xe1,0x01,0x14,0x7e,0xcb,0x0f,0x0f,0x60,0x01,0x26,0x4f,0x21,0x24,0xad,0x15,0xd0,0x69,0x85,0xe6,0xbc,0xe6,0x47,0x52,0x40,0xec,0xe3,0x14,0xf7,0x8c,0xcc,0x93,0x1d,0xef,0xb4,0xa5,0xa5,0x21,0x93 +.byte 0x37,0x09,0x86,0xac,0x28,0x45,0x1d,0x11,0xb8,0xaa,0xa8,0x5a,0x9f,0xb1,0x66,0x4b,0x57,0xa2,0xd9,0x22,0xcf,0xbf,0x69,0xa6,0x20,0x1f,0x7e,0x35,0x32,0x83,0x20,0x6d,0x2a,0x4b,0x14,0x71,0xd1,0x3b,0x11,0x9d,0xc8,0x7f,0x9d,0x2c,0xf6,0x75,0xd9,0x08,0xac,0xa4,0xd3,0x14,0x8b,0xf3,0x14,0xff,0x03,0x88,0xeb,0xb9,0xb9,0x9e,0x83,0x64 +.byte 0xfe,0x8a,0x97,0x0b,0xa1,0x7c,0x50,0x11,0x6b,0xc1,0x6e,0x77,0x56,0x25,0x6e,0x32,0xfc,0x54,0xc1,0x99,0xc0,0x31,0xef,0x65,0xb3,0x67,0xd0,0x7c,0x12,0x62,0xfd,0x8f,0x71,0x5c,0xfc,0xf9,0x26,0x29,0x2d,0x50,0x28,0xbd,0x26,0x40,0x63,0x43,0x79,0x78,0x07,0xa8,0xb4,0x19,0x06,0x25,0xd8,0xe5,0xad,0x75,0x6f,0xe0,0xb4,0xef,0x1f,0xe9 +.byte 0x5b,0xa0,0xf8,0x32,0xec,0xe5,0xc1,0x75,0x04,0x88,0x1f,0xad,0x30,0x16,0xe2,0x05,0x8c,0xee,0x81,0x80,0x9b,0x0c,0x8d,0xd1,0xfb,0x55,0x0b,0x8d,0xdf,0x67,0x91,0x05,0xb2,0xfc,0x1e,0x99,0x12,0xb3,0x7c,0x33,0x4a,0x39,0x5f,0xbb,0xd9,0xe8,0xbb,0x17,0xd9,0x4b,0x8b,0xd6,0x6d,0x90,0xa8,0xbf,0xb7,0xd8,0xe0,0x83,0x93,0x16,0x5b,0x0f +.byte 0x8b,0xc8,0x14,0x7d,0x24,0xf5,0xc7,0x33,0x21,0xa6,0xa0,0x1c,0x37,0xea,0xab,0x74,0x86,0xb8,0xe0,0xb7,0x57,0x4d,0x5e,0x2a,0x2c,0x4c,0xbb,0x06,0x0b,0x44,0xe4,0xab,0xb9,0xcd,0x94,0xa9,0x33,0x40,0xc6,0x20,0x90,0xe2,0x7b,0xf6,0x84,0x23,0x59,0x52,0x72,0x83,0x45,0x33,0x5d,0x91,0x93,0xa8,0x32,0xa1,0xe4,0x26,0x13,0xd8,0xf6,0x21 +.byte 0x85,0x02,0x66,0xad,0xbf,0x18,0x41,0x50,0xd3,0xda,0xa4,0xee,0x3b,0xd8,0xc1,0x2d,0xe6,0xa6,0x40,0x97,0xeb,0xd4,0x2f,0x7e,0x70,0x1a,0x7a,0xf1,0xc2,0x24,0xf8,0xef,0x43,0xef,0x0b,0xf9,0x87,0x6b,0xe7,0x10,0xa1,0x17,0x75,0x03,0x30,0x33,0xca,0xa4,0xb5,0x8d,0x70,0x7d,0xec,0x2c,0xe8,0x07,0x42,0x11,0x9d,0x29,0x23,0x31,0x8f,0x9d +.byte 0x83,0x71,0xeb,0x39,0x2d,0x80,0x15,0xd2,0xcf,0x42,0xc9,0x06,0x6d,0x90,0x73,0x8b,0xcb,0xeb,0x9d,0xb6,0xc8,0x61,0xcc,0x84,0x2d,0xa7,0xf2,0x35,0xbc,0xc8,0x14,0xe9,0x89,0xb5,0x47,0xe5,0x5c,0xdb,0x0c,0x98,0xc9,0xec,0x20,0x61,0x63,0x2c,0x58,0xbb,0x8e,0x46,0xb1,0xca,0x6a,0xbb,0x11,0x73,0xb6,0x5e,0x88,0x50,0xce,0xcf,0x14,0x60 +.byte 0x5c,0xc8,0x59,0x81,0xb2,0x8f,0xde,0x36,0x57,0x5a,0x18,0xf7,0xa5,0x57,0xf7,0x71,0xd3,0x92,0x5a,0xb5,0x41,0x4d,0xcc,0x74,0xe8,0xdb,0xfd,0x15,0x1b,0xb8,0x40,0x91,0x04,0x12,0x74,0x84,0xcb,0x1f,0x3c,0x13,0xa4,0xa2,0xde,0x52,0xaf,0xdd,0x3b,0x1e,0x88,0x6e,0x86,0xd0,0xe9,0xb7,0x10,0x3b,0x29,0xef,0xce,0xa3,0xf9,0x85,0x0d,0x27 +.byte 0x1d,0x21,0x74,0x0e,0x06,0x66,0xfa,0xcb,0xad,0x88,0x58,0x79,0xdb,0x3f,0x8a,0xbe,0x4d,0x56,0x4b,0x45,0xae,0x6f,0x0c,0x6a,0x8c,0x73,0x5b,0x61,0xde,0x41,0x03,0x9b,0xef,0xdd,0x35,0xde,0x57,0x96,0x11,0x8a,0x56,0x6b,0xa5,0x57,0x7e,0xb1,0xa7,0x12,0x4a,0x79,0xb9,0xc4,0x04,0xd5,0x7b,0x8c,0xad,0xf2,0x83,0xff,0x7d,0xdc,0xcf,0x22 +.byte 0x25,0x5d,0x6f,0xfc,0xd7,0x7b,0xac,0x53,0x80,0x1d,0x7e,0xff,0x89,0x95,0x48,0x38,0xc0,0x48,0xd8,0xb9,0x3b,0x5e,0xc3,0x99,0xc8,0xc6,0x6d,0xd2,0x0e,0xd8,0xc2,0x9e,0x3d,0x9e,0xf4,0xa7,0x5f,0xc4,0x9a,0xd1,0x0c,0x49,0xb8,0x5a,0x66,0x94,0x69,0x71,0x19,0xba,0x9b,0xe6,0x4f,0xa9,0xcf,0x70,0x7d,0xe2,0x60,0xea,0x06,0xd7,0x94,0xe1 +.byte 0xb6,0x23,0x7f,0x2c,0x2c,0xe4,0xf4,0xdf,0xcc,0x1a,0x25,0xfa,0x47,0xef,0xf2,0x37,0x32,0xd4,0xf2,0xdd,0xc9,0x13,0xb8,0x09,0x85,0x33,0x5c,0xa2,0xa2,0x20,0x11,0xd1,0x3b,0x6e,0x9d,0x11,0xb6,0xb8,0x75,0xf1,0x47,0x6f,0x93,0x35,0x55,0x55,0xa5,0x11,0x4d,0xbf,0xc1,0x0a,0x99,0x84,0x65,0x91,0x16,0xc1,0x64,0x1a,0xdb,0x15,0xcf,0x2f +.byte 0x93,0x0e,0x6b,0xe0,0x8c,0x70,0xfa,0x5e,0xa2,0x5c,0xd8,0x43,0x2f,0x93,0x22,0x9e,0xdc,0xad,0xf6,0x39,0x15,0x2b,0x50,0xa0,0xdb,0x51,0xfc,0x00,0xda,0x8b,0x7a,0xa9,0x14,0x07,0x79,0x25,0x8c,0x7d,0x71,0x3f,0x8d,0x51,0x20,0x81,0xdc,0x4a,0x92,0x71,0x4c,0xb2,0xc6,0x5c,0x8a,0x18,0xa1,0xaa,0xb0,0x2e,0x06,0xb4,0xd4,0x6a,0xd4,0xa8 +.byte 0xd1,0x31,0x81,0x22,0xe3,0x22,0xc9,0x75,0x84,0xc1,0x95,0xae,0xa6,0xa2,0xb4,0x93,0x4b,0x9c,0xea,0xc6,0x4c,0xdc,0x25,0xd9,0xeb,0x12,0x64,0xf9,0x42,0x8e,0x72,0x47,0xd9,0x89,0xd6,0xc4,0xf9,0xa7,0xc6,0x64,0x53,0x05,0x40,0xf5,0x9c,0xab,0x53,0x45,0xa4,0xe5,0x3e,0x2f,0xf7,0x69,0x06,0xc1,0x7e,0xb0,0xec,0x4c,0x22,0xfe,0x89,0x6c +.byte 0x4c,0x80,0x5d,0x51,0x0a,0x20,0xaa,0x71,0x68,0x9c,0x3e,0x29,0xf2,0x82,0xd4,0x81,0x6c,0x8b,0x11,0x42,0x00,0x86,0x70,0x74,0xe0,0x94,0xcf,0xee,0x2f,0xbd,0x8a,0xab,0xee,0xfc,0xd8,0x8e,0x87,0x2e,0xce,0x89,0xaf,0x29,0xc2,0x2b,0xcd,0xa3,0xc4,0x47,0xa2,0x1f,0x2e,0xc3,0x2d,0x9f,0x89,0xbb,0x57,0xa6,0x00,0xc3,0x4a,0x91,0x2e,0xfd +.byte 0xbf,0xbb,0x4a,0xb5,0x3c,0xa1,0x4d,0x96,0x2d,0x62,0xf6,0xda,0x9f,0x75,0xef,0x84,0x18,0x5c,0x31,0x31,0xcc,0xe4,0x82,0xd4,0xb6,0x7a,0xd7,0x6b,0x6e,0x32,0xb6,0xdb,0x90,0x16,0x5a,0xc0,0x4e,0xe4,0x48,0x69,0xd3,0xe3,0xf2,0xfa,0xed,0x17,0x4b,0x06,0xe0,0xd8,0x4d,0xa9,0xee,0x19,0x98,0x65,0xf5,0xb3,0x69,0xe2,0x23,0x23,0x04,0xca +.byte 0x52,0x7b,0x7b,0xaa,0xb9,0x03,0x71,0x1b,0x37,0x17,0x16,0xe0,0xb7,0x5a,0x75,0xa9,0x97,0xbe,0x44,0xa9,0xb2,0xef,0x5a,0x5c,0x17,0x31,0x77,0xe3,0x15,0x4f,0xb6,0x4c,0xff,0xf9,0x10,0xdd,0x41,0xab,0xfa,0xf0,0xed,0xe7,0xa6,0x74,0x6f,0x7e,0xc9,0x71,0x66,0x16,0xed,0x68,0xb0,0x74,0x85,0xeb,0xb2,0xc5,0x73,0xc1,0x00,0x33,0xb3,0x9d +.byte 0xd9,0x7f,0x0e,0x9d,0x17,0xf2,0x0b,0x55,0xb6,0x68,0x9b,0xe9,0xc9,0x46,0xa5,0x97,0xe3,0xe9,0xb6,0xc3,0xa3,0x10,0x57,0x11,0xd6,0xc1,0x7a,0xfe,0x05,0xa5,0xcb,0x15,0x75,0x92,0xd8,0x69,0xdd,0xe0,0x67,0x5a,0x8c,0x50,0x6d,0x66,0xd5,0x79,0xf6,0xb6,0x7e,0xf1,0x04,0x95,0x45,0x03,0x84,0x0e,0x8a,0xa6,0x27,0x87,0x9b,0x6b,0x58,0x46 +.byte 0x52,0xfb,0x36,0xd8,0x90,0x14,0xcd,0x68,0xa9,0xb7,0x51,0x2e,0xb5,0xc5,0x3b,0x4d,0xee,0x86,0x65,0x94,0xec,0x94,0x8e,0x26,0x01,0xe8,0xcd,0x0a,0xa0,0xb8,0x7c,0x76,0xe7,0xd7,0x65,0xa4,0x0c,0xe5,0x6f,0xfc,0x3d,0xad,0xc0,0x94,0x44,0xb4,0x98,0xc9,0x01,0x71,0x03,0x96,0x12,0x77,0x0d,0xbf,0xb7,0x05,0xe1,0x95,0xff,0x01,0x0c,0x26 +.byte 0x13,0xbe,0x09,0xf6,0x35,0xee,0x44,0x33,0x86,0xf4,0xb4,0x65,0x72,0xbd,0x66,0x1a,0xcf,0x89,0xa5,0xe0,0x3a,0xe7,0x1a,0x2a,0x1e,0x73,0xf0,0xef,0x74,0xdb,0xaf,0x02,0x4c,0xd4,0x0f,0xfd,0x5e,0x20,0x4f,0xd7,0x19,0x36,0xeb,0x00,0x2e,0xce,0x56,0xe7,0xba,0x6d,0xae,0x73,0x27,0x7e,0xc5,0x28,0x94,0xc6,0xbf,0x9b,0xca,0xb4,0x52,0x04 +.byte 0xd3,0xd1,0x4f,0x61,0x5b,0xcd,0x97,0x12,0x35,0xc0,0x10,0x12,0x15,0x05,0x02,0x1a,0xae,0x0e,0xf9,0xc7,0x5d,0xeb,0xea,0xcd,0x3c,0x10,0x51,0xf2,0x0c,0x48,0x6f,0x45,0xa2,0x50,0xa9,0x95,0x21,0x7c,0xd3,0x91,0x5f,0x72,0x59,0xa8,0x2b,0xfb,0xe8,0xb1,0xd9,0xdb,0x46,0x1e,0xe8,0x25,0x78,0x2c,0x01,0xbb,0x35,0x3f,0x95,0x04,0x84,0x96 +.byte 0x1f,0x55,0xa4,0x46,0x2a,0x8c,0x58,0xb6,0xfc,0x2e,0xfa,0xa4,0xb8,0x4d,0x5d,0x0b,0x5f,0xa4,0x93,0x06,0xae,0x62,0x6a,0x6a,0xce,0xa5,0xc7,0x06,0xf0,0x05,0xf8,0xd7,0x3a,0x0b,0xb8,0x80,0xa6,0x2f,0x73,0xbd,0xbc,0x31,0x33,0x96,0xf9,0x8b,0x52,0x7e,0x3f,0x64,0x48,0x1d,0xca,0x23,0x71,0xe6,0xf3,0x2b,0x03,0x20,0xa0,0x2b,0xec,0x5b +.byte 0xca,0x5e,0x31,0x7c,0x01,0xf4,0x58,0xdc,0x27,0x57,0x8e,0x41,0xfc,0xa6,0x10,0x09,0xc3,0xbd,0x89,0x7b,0xfb,0x09,0x85,0xa5,0xa3,0xbe,0x15,0x94,0x41,0x7a,0x86,0xfe,0xab,0x9d,0xcf,0x56,0x60,0xa1,0xb3,0xee,0x9a,0x69,0xf9,0x2f,0xb7,0x92,0x7a,0x7b,0xb6,0x23,0xf3,0xca,0x9c,0xbe,0xb6,0x51,0x04,0x3d,0x2a,0x17,0xdd,0x13,0x9b,0x9b +.byte 0x1c,0x50,0xe4,0x11,0x5b,0xce,0x0e,0x54,0x7c,0x25,0xdd,0xc1,0x91,0x90,0xe4,0xb5,0xa6,0x84,0x22,0x44,0x46,0x68,0x7b,0x16,0x23,0xc0,0x69,0x64,0xc4,0x12,0x03,0x8c,0x85,0xe2,0x4c,0x83,0xdb,0xb1,0xe3,0x35,0x15,0x6a,0xd3,0x56,0x73,0xa1,0x51,0xad,0xd2,0x15,0xc5,0xa9,0xb3,0x7e,0x81,0xa1,0x16,0x19,0xbe,0x8b,0x98,0x2f,0x31,0xaf +.byte 0x51,0x67,0x4c,0x09,0xae,0x4d,0x77,0xa4,0xcd,0x28,0xbf,0xd0,0x0e,0x17,0x57,0x15,0xcf,0x48,0x8b,0x90,0xb1,0xb5,0x59,0x43,0xac,0x34,0x34,0xa1,0x4b,0x36,0x20,0x0d,0x40,0x6d,0x81,0xa2,0x40,0x5e,0x7b,0xd8,0xf3,0xf5,0x33,0x3b,0x14,0x19,0x55,0x07,0xfc,0x53,0x22,0x7e,0x4f,0xe2,0xde,0xb7,0x8b,0x2d,0x10,0x0c,0xc1,0xc7,0x0d,0x3c +.byte 0xc0,0x8a,0x91,0xfa,0xf5,0x9b,0xcd,0x25,0xe8,0x8f,0x10,0x4b,0x9a,0x07,0x94,0xa9,0xc0,0xb4,0x18,0x6c,0x9a,0x88,0x94,0x4d,0x33,0xc7,0xf5,0x20,0x8c,0x02,0x9a,0xde,0x90,0x11,0xbd,0x90,0x14,0xb0,0x72,0xaf,0x8e,0xef,0x9c,0x22,0x2b,0x6a,0xd7,0x75,0xae,0x6e,0x97,0x46,0x3f,0xef,0xb3,0x4d,0x34,0x0b,0x41,0x35,0xc9,0xb4,0xaa,0x18 +.byte 0xfb,0x95,0x09,0x64,0xe0,0xff,0x51,0xa0,0xf4,0x8f,0xa9,0x5f,0x8f,0x51,0xa6,0x5b,0x86,0x0d,0x83,0x26,0x1e,0x00,0xab,0x6f,0x73,0xf6,0x98,0x24,0x4b,0xb2,0xe0,0xfe,0xbc,0x03,0x7f,0x6c,0x88,0xe8,0x36,0xea,0x10,0xe7,0x73,0xa0,0x96,0x88,0xad,0x0f,0x88,0xb6,0x9f,0xa7,0xe4,0x38,0x35,0xa3,0x29,0x9a,0x34,0xd1,0x00,0x1c,0x61,0x93 +.byte 0x90,0x12,0xc3,0xcb,0x72,0x62,0x0a,0xc8,0xad,0x9c,0x0d,0x19,0x6c,0xe2,0x53,0xf0,0xf0,0x2f,0x2c,0x72,0x0f,0xf1,0xb1,0xd1,0x56,0xd4,0x87,0xbc,0x73,0x63,0xfe,0x2c,0x7b,0x9b,0xaa,0x6c,0xa6,0x79,0xfd,0xfa,0x20,0x83,0xb2,0x6d,0x4e,0xe4,0xae,0x73,0xf8,0xb5,0x6c,0x1a,0x97,0x07,0x8a,0x6f,0xe8,0x33,0xc5,0xea,0x61,0x18,0x53,0x56 +.byte 0xa4,0x11,0x32,0xe1,0x8c,0xae,0x69,0xac,0xed,0x35,0xe0,0x6f,0x7d,0x97,0x8b,0xa3,0x12,0xa4,0x92,0x42,0xcf,0x43,0xef,0xc3,0x8e,0x99,0x12,0x0a,0xb6,0xa6,0xcc,0xae,0xca,0x1c,0xe3,0xa1,0x65,0x74,0x79,0x6a,0x5f,0xa2,0x3e,0x6d,0xb6,0x45,0xa5,0x40,0xc8,0x59,0xa0,0x31,0xa9,0x07,0x35,0x81,0xaf,0xee,0x35,0x07,0xa0,0xe3,0x26,0x4c +.byte 0x57,0x08,0xa0,0x01,0xc3,0x8b,0xd8,0x9a,0xba,0xe4,0x73,0x7f,0xcb,0xc4,0x0a,0x65,0xb3,0x16,0xf5,0x36,0x35,0xd3,0x2f,0x15,0x61,0xa6,0x90,0xa6,0xa5,0x4c,0xc6,0x57,0xd4,0xd0,0x80,0xfb,0x68,0x52,0xd4,0x09,0x24,0x39,0x29,0xa1,0x39,0xf2,0x3d,0xbc,0xc6,0x7c,0x95,0x3c,0xa4,0xe1,0xeb,0x33,0x94,0xfe,0xda,0x92,0x75,0x7f,0x76,0xe0 +.byte 0x61,0xa9,0x27,0x2d,0x43,0xf9,0x4f,0xd6,0x61,0x12,0x89,0x12,0x46,0x79,0xb6,0x6c,0xa1,0x6d,0xcb,0xcb,0x12,0x1b,0x82,0xa6,0x41,0xa8,0xf5,0x43,0x46,0xdd,0x8b,0x43,0x5f,0x5f,0xce,0x7b,0xc1,0xec,0x55,0x8d,0x37,0xe5,0x78,0x4c,0x2e,0x3a,0x64,0xcf,0xef,0x8c,0x76,0x04,0x75,0x42,0x0d,0xb5,0xaa,0x5f,0xd1,0x55,0xbc,0x54,0x26,0x9e +.byte 0xc6,0xa0,0x8c,0x36,0x39,0x23,0x54,0x66,0x34,0x83,0xed,0x1e,0xf4,0xca,0x7e,0x11,0xb4,0xd1,0x0c,0xcd,0x67,0xa6,0xbb,0x02,0x30,0x61,0xd9,0x3f,0xbf,0x83,0x5c,0x15,0x60,0xa4,0x1b,0x73,0x67,0xa0,0x54,0x07,0x2a,0xc4,0x11,0x4e,0xfb,0xe8,0x85,0xda,0x78,0xbb,0x91,0x98,0xb8,0xf4,0x7c,0x6c,0x0b,0x32,0xad,0x6d,0x1b,0x29,0x2a,0x2e +.byte 0x36,0xef,0xd8,0xdd,0xa3,0xdd,0x6d,0x45,0xf0,0x90,0xa9,0xf8,0xb5,0x1f,0x3b,0xaa,0xe2,0x88,0x97,0x46,0xc1,0x86,0x8e,0xb7,0x6b,0x01,0x5f,0xac,0xa4,0xfa,0x35,0xef,0xfb,0xa4,0x0a,0x31,0xaa,0x80,0x81,0x98,0x78,0xcf,0xe5,0x25,0xbf,0x4a,0x84,0xd1,0x11,0x92,0x0a,0xc6,0x98,0xd2,0x99,0xa8,0x42,0x46,0x20,0x04,0x95,0xa1,0xad,0xef +.byte 0x86,0x1f,0xe3,0x4d,0x6f,0xed,0x01,0xf4,0x42,0x54,0xe4,0x34,0xec,0x64,0x97,0x48,0x1f,0x41,0xe1,0x50,0x85,0x86,0xe3,0x85,0xdb,0xd0,0x8b,0xe4,0xc9,0x91,0xea,0xa4,0x5d,0x65,0xd2,0x98,0x52,0x0a,0x0d,0xde,0x71,0xb4,0x86,0xaa,0xfc,0xa7,0x1b,0x7b,0x1a,0xa1,0x1c,0x5a,0xea,0x82,0x97,0x03,0x43,0x88,0xcd,0x96,0xf6,0x55,0x87,0x6f +.byte 0xb9,0x85,0xed,0x9c,0x17,0x89,0x31,0x7e,0x72,0x96,0x0f,0x2f,0xb7,0xcb,0x45,0xe4,0x46,0x4d,0xf3,0x38,0xc2,0xe2,0x24,0xdb,0x7e,0x1e,0x1d,0xae,0x56,0x34,0x7e,0xf5,0xc7,0x17,0x08,0x22,0xab,0xb6,0x3c,0xf3,0x3f,0xe1,0xd6,0xd3,0x71,0xb5,0x58,0xad,0x88,0x41,0xab,0x1b,0x2c,0x90,0xd2,0x94,0x65,0x0c,0x02,0x7f,0x9c,0x01,0xbc,0x14 +.byte 0x89,0x4d,0xca,0x3e,0x57,0xc5,0x00,0xe7,0x61,0x81,0x5c,0x07,0x39,0x18,0xc9,0xaa,0xd9,0xa1,0x3d,0xa9,0x9e,0xe2,0xec,0xaa,0x15,0x34,0xf8,0xd5,0x7b,0x20,0xbb,0x19,0xe2,0xc8,0x95,0xbe,0x46,0xfa,0xa1,0xde,0x22,0x18,0xbc,0x28,0xf6,0x72,0x2a,0xc7,0x4a,0x26,0x4c,0xe2,0xdb,0xcf,0xc1,0xa2,0x41,0x9e,0xb8,0xfb,0x93,0x65,0x8f,0xc8 +.byte 0x38,0x6a,0x8a,0x4e,0xea,0x35,0xed,0xc6,0x1a,0xcd,0x77,0x4f,0xc1,0x7c,0x08,0xd3,0xc6,0x50,0xab,0x08,0x34,0x76,0xbc,0x65,0x8f,0x88,0xa8,0xa7,0x03,0x18,0x4a,0xdf,0x64,0x35,0xad,0xa0,0x1a,0x91,0xee,0x41,0x1e,0xe7,0x70,0x9f,0x6e,0x46,0xd5,0xc6,0xda,0x1b,0x17,0x5c,0x11,0x56,0x55,0x5c,0xdd,0x24,0xb7,0x15,0xc8,0xa6,0x02,0x33 +.byte 0xa6,0x10,0xd6,0x9b,0x67,0xc0,0x20,0x46,0x25,0xf8,0xd0,0xab,0x25,0xbb,0x00,0x3a,0xcc,0x00,0x30,0xad,0xa9,0x60,0x28,0xc9,0xfd,0x8c,0x0d,0x02,0x95,0x47,0xff,0x30,0xa5,0x52,0x91,0xc4,0xef,0x73,0x28,0x93,0x08,0x37,0xe7,0x81,0x8f,0xd5,0x0c,0xd8,0x6b,0xc6,0x73,0xe7,0xfe,0x3f,0xc8,0xe0,0xd8,0xa7,0x68,0xa2,0xa9,0xd8,0xa3,0xa3 +.byte 0x90,0x7e,0xa5,0x30,0x61,0xac,0xfc,0xe9,0x56,0x07,0x49,0xc6,0xf6,0x0d,0x21,0x86,0xa5,0xc8,0x7b,0x3a,0xfb,0xa7,0x59,0x3f,0xd0,0xe7,0x2b,0x90,0x40,0x71,0x76,0x06,0x34,0x03,0x32,0xb9,0x93,0x02,0xa4,0xa8,0x17,0x27,0xa3,0x47,0x40,0x79,0xed,0x8c,0x6f,0x12,0x7f,0x32,0x7d,0x9f,0x3a,0x39,0xfb,0xb6,0x75,0x66,0x60,0x66,0x6f,0x84 +.byte 0x79,0xd6,0xce,0x6a,0x78,0x55,0x60,0x6b,0x1d,0x81,0xed,0x29,0x48,0x56,0x62,0x21,0xe0,0x8e,0xf8,0x63,0xad,0x6a,0x08,0xcc,0x9d,0x25,0x77,0x50,0x57,0x87,0x7d,0x52,0x8b,0x85,0x27,0x1c,0x10,0x68,0xe5,0xb7,0xfa,0x75,0xd2,0xfe,0x7d,0x89,0x1a,0x17,0xb7,0x0b,0x6c,0xe8,0x50,0xcf,0x42,0x51,0x77,0x27,0x75,0x2b,0x15,0xdb,0xc8,0x10 +.byte 0x7a,0xd5,0x32,0x90,0x08,0x31,0x16,0x18,0x26,0x22,0xdb,0xfb,0x98,0xe1,0x49,0x71,0x7b,0x63,0x6f,0xb8,0x5e,0xd0,0x70,0x59,0xa0,0x26,0xd4,0xe0,0x01,0x0f,0xd2,0xb1,0x8a,0x94,0x94,0xa1,0x31,0x61,0xf8,0xbb,0x9a,0xe3,0x9b,0x3d,0xe8,0x55,0x4b,0x49,0xc0,0x71,0x57,0xfe,0x39,0xef,0x53,0x35,0xec,0x0c,0xf7,0x71,0x9f,0x18,0x66,0xe1 +.byte 0x46,0x29,0x2c,0xc6,0x74,0xd2,0x20,0xf5,0xb2,0x64,0xa2,0x20,0x99,0x19,0x43,0x36,0x33,0x7d,0x85,0xcb,0x09,0x65,0x18,0xc5,0x7c,0x9f,0xf9,0xae,0x0a,0x1a,0x47,0xf6,0x65,0x4a,0x43,0x13,0x4e,0xcf,0x2b,0x9f,0x0d,0x9b,0x8a,0x5e,0xc6,0xf8,0xc2,0x26,0x88,0xc1,0x4e,0xde,0xa2,0x08,0xdd,0x0e,0xeb,0x46,0x3d,0x93,0xae,0xeb,0xd8,0xc0 +.byte 0x29,0x2a,0x11,0x56,0x7c,0x97,0x10,0xae,0x6e,0x02,0xc9,0xc8,0xed,0x78,0x68,0x8d,0xa7,0x93,0x74,0x4c,0x7a,0x67,0xd4,0xb8,0x97,0x2d,0x0d,0xc0,0x33,0x96,0xb7,0xbc,0x4a,0x02,0x5f,0xa7,0xd7,0x1e,0x92,0xfd,0xf4,0x2f,0xd3,0x44,0x41,0x80,0x11,0x76,0x95,0x93,0x9d,0xf5,0xfb,0x98,0xc1,0xb6,0x11,0x3e,0x05,0x3b,0x7f,0x4a,0xa7,0xde +.byte 0x3a,0x8b,0xff,0x0c,0x13,0x5a,0x93,0xa8,0x34,0x64,0x85,0x6c,0x63,0x67,0x71,0x45,0x83,0xbb,0x27,0x9f,0xda,0xf7,0x66,0x92,0x7e,0xb7,0x1f,0xcf,0x23,0x38,0x1f,0xe4,0x7c,0x39,0xcc,0x30,0x34,0x14,0x3b,0x6f,0x02,0x52,0xd8,0xac,0xcf,0x72,0xb6,0x95,0xf7,0xc0,0x64,0x36,0x31,0x08,0x45,0x8d,0x17,0x17,0x9c,0x75,0xec,0x21,0x5c,0x87 +.byte 0x4f,0x94,0x64,0x24,0xb6,0x07,0x7f,0x13,0xee,0x62,0x67,0x62,0xab,0x2d,0xf1,0xfa,0x06,0x21,0x92,0xb8,0xa3,0x1e,0xc0,0x62,0x85,0x2e,0x3b,0xe5,0xbb,0x08,0xd5,0x18,0xb6,0x0c,0xd7,0x5d,0x2e,0xd6,0xfc,0xd4,0x05,0x49,0x82,0x19,0x17,0xdd,0xd0,0xd3,0xb6,0xc3,0x2e,0x72,0x59,0x2e,0x29,0xf0,0xf3,0x57,0xef,0x43,0xb6,0x1d,0x10,0x2a +.byte 0x34,0xd5,0x52,0x9d,0xdc,0x8f,0x14,0xf9,0x52,0x9c,0x30,0xd9,0x49,0x39,0xe1,0x20,0x0e,0x04,0x79,0x8a,0x4a,0x17,0xd9,0xa9,0xf7,0x66,0x73,0xbd,0x40,0x3f,0x1a,0xff,0x38,0x63,0xe7,0x9c,0xfe,0xf1,0xd8,0x30,0xbf,0x76,0x8f,0x43,0x8f,0x18,0x72,0xd2,0x1d,0x7d,0x4a,0x2d,0xee,0xcb,0x4d,0xc5,0x96,0x19,0x5e,0x23,0xdc,0x7a,0xb9,0x69 +.byte 0x94,0xe3,0xf6,0x8a,0x66,0xe6,0x68,0x1f,0x36,0x2f,0xca,0xb2,0xca,0x4a,0x3f,0xcd,0x7d,0x70,0xe1,0x0d,0x41,0x5f,0x46,0x26,0x5f,0xee,0xb9,0x78,0xaa,0xa2,0xd1,0xc1,0x27,0xb8,0x4d,0x3d,0x52,0xaa,0x1e,0x8b,0x3c,0xc0,0x4e,0x26,0xcc,0xa9,0x99,0x1b,0x0d,0x58,0xdd,0x6d,0xde,0x25,0x9e,0x3c,0x3b,0xab,0xcb,0x68,0x5d,0xfe,0x58,0xaa +.byte 0x98,0x37,0xe8,0xbf,0xc4,0x99,0x60,0xc7,0x96,0xf2,0xc7,0x2e,0x2f,0x61,0x14,0x28,0x4b,0x8e,0x05,0x0f,0x3b,0xb9,0x7a,0xa5,0xf8,0xbe,0x01,0x4a,0x68,0x44,0x7f,0xf8,0xc1,0xdf,0x18,0xe8,0x5a,0xc3,0x67,0xe0,0xf8,0x3b,0x17,0x51,0x03,0xfb,0xc1,0x6b,0xa8,0x65,0x4a,0x5f,0xe0,0xd2,0x69,0xa9,0x6c,0xb2,0xe8,0x2f,0xeb,0x90,0xab,0xe5 +.byte 0x6d,0xdb,0xb2,0x1d,0xda,0x58,0x76,0xa2,0xb7,0x76,0x6f,0xbf,0x96,0xe8,0x97,0x7b,0x49,0xa6,0x5f,0x29,0xdd,0x02,0x09,0x0f,0x2b,0x09,0xf3,0xbd,0xa0,0xca,0x2b,0xfa,0x82,0x52,0x42,0x93,0xb6,0x53,0x33,0xb7,0x4d,0xa8,0x91,0x81,0x5c,0x88,0x51,0xf6,0xcc,0x65,0x6e,0x76,0xd1,0x07,0xb5,0x19,0xc4,0x90,0x6f,0xd7,0x5a,0xf7,0x34,0x00 +.byte 0xba,0x0d,0x1f,0x64,0x66,0x87,0x25,0xcf,0xac,0xd0,0x60,0x44,0xdf,0x29,0x9b,0x84,0xf2,0x37,0xf5,0x17,0xaa,0x75,0xba,0x0a,0x5d,0x71,0xe4,0x50,0xaf,0x87,0x76,0x18,0x21,0x94,0xe1,0x0f,0x9a,0x2f,0xb1,0x10,0x8a,0x49,0x13,0x43,0x92,0xc6,0xf3,0xa3,0x68,0x2b,0x52,0x91,0x91,0x41,0xeb,0x33,0xfd,0x45,0xea,0x9c,0x6e,0x32,0x3b,0x9d +.byte 0x1e,0xe0,0x97,0xb7,0xa2,0x83,0xd1,0xf4,0x2f,0xb9,0xe8,0x5a,0x7d,0x5a,0xe1,0xc4,0xec,0x4b,0x1b,0x22,0xf5,0xc8,0x87,0x74,0xdd,0xe4,0xb5,0x8c,0x4e,0x69,0x33,0x50,0xe7,0x31,0x36,0xef,0xf7,0xb2,0x29,0xc6,0x31,0x1f,0xde,0xa7,0x7b,0xae,0xa8,0xae,0x57,0xf4,0x17,0xf9,0xbd,0x9e,0x1d,0x83,0x98,0x70,0x00,0x1f,0xb6,0x14,0xdb,0xb3 +.byte 0xc5,0x4d,0x7b,0xdd,0x36,0x4d,0x94,0xff,0xec,0x24,0x6b,0xb8,0xa7,0xaa,0x32,0x2d,0xff,0xcc,0x6c,0xdb,0x26,0x95,0x47,0x69,0xdf,0xf0,0xa2,0xc0,0xc3,0x98,0x30,0x29,0x40,0x97,0x45,0x84,0x3b,0x3b,0x4c,0x36,0x2c,0xdf,0xe7,0x8e,0x03,0x8b,0x60,0xc7,0xb5,0x24,0x19,0x56,0x98,0xd5,0x23,0xfa,0xce,0x30,0xb3,0x5f,0xef,0x74,0x3a,0xf7 +.byte 0x49,0x57,0x6d,0xad,0xb6,0x97,0x54,0xbb,0x85,0x80,0x52,0x5c,0x44,0x7e,0x2e,0x2c,0xd4,0xd5,0x05,0xd2,0xf1,0xd2,0xb1,0xc0,0xda,0xde,0xf3,0x46,0xe4,0xde,0x59,0x85,0x39,0xa8,0x5c,0xf0,0x10,0x9e,0xa0,0x99,0x68,0x5b,0x00,0xe7,0x2a,0x60,0x65,0xe7,0x69,0x24,0xb0,0xdc,0xd3,0x7d,0x98,0xd6,0x1f,0x75,0x37,0x5a,0x14,0x3c,0xe2,0x8d +.byte 0xe9,0xf4,0x73,0x5d,0xd7,0xde,0xf6,0x74,0xb0,0x07,0x51,0xee,0x5c,0x4c,0x72,0x72,0x16,0xf2,0xfb,0x44,0xac,0x26,0x20,0xaa,0xe8,0x96,0xc5,0xdc,0x5e,0xea,0xf9,0x62,0x76,0x96,0x1b,0xe3,0xc3,0x50,0xc0,0xc6,0xc4,0x07,0xc6,0x32,0x3c,0xc2,0x8e,0x4e,0xfc,0xcb,0xa2,0x22,0x24,0xa2,0x58,0x3c,0x0f,0xce,0x5b,0xb4,0x27,0xaf,0x67,0xed +.byte 0x81,0xf1,0x9c,0x26,0x38,0x80,0xc5,0xfc,0xfa,0xd1,0xae,0xfe,0x12,0xe7,0xb4,0x49,0x34,0x8f,0x52,0x5f,0x49,0xd7,0x0c,0x14,0x6e,0x93,0xc2,0x7e,0x3f,0x26,0x50,0x6d,0xc4,0xcb,0x55,0x76,0x52,0x95,0xd8,0x5b,0x81,0x0c,0x97,0x34,0xf0,0xaa,0x46,0x60,0x52,0x7a,0x53,0x99,0x74,0xf7,0xdc,0x3e,0xa4,0xbb,0xe2,0xca,0x5f,0x06,0x29,0x0d +.byte 0xde,0x28,0x8a,0x40,0x9a,0x7c,0x12,0x7b,0x7d,0x8d,0xd6,0x59,0xa3,0x7b,0x36,0x15,0x1e,0xdf,0x6e,0xed,0x90,0x4a,0xa5,0x0c,0xb6,0xb1,0x8c,0x84,0xd2,0x14,0xab,0x85,0xb3,0xaa,0xb5,0x48,0xa3,0x91,0xe4,0x6e,0x46,0x69,0x2e,0x55,0xf1,0xbb,0x1d,0xa9,0xfa,0xae,0xcd,0xfa,0xf4,0xf1,0xca,0x74,0x2d,0x1b,0x8d,0x29,0x99,0x15,0x58,0x01 +.byte 0xf2,0x8b,0x0d,0x2b,0x1b,0x27,0x91,0x48,0x26,0x50,0x1d,0xf0,0x72,0x3f,0xff,0xe3,0x1f,0x68,0x16,0x0c,0x4a,0xbd,0x35,0xa5,0x61,0xd0,0xd4,0xb2,0x21,0xc6,0x5a,0x49,0x4f,0x7c,0x0a,0x28,0x8f,0x57,0xc4,0xcf,0x74,0x42,0xdd,0x0a,0x7c,0x42,0x21,0x96,0x8a,0xcb,0xc4,0xc7,0x1d,0xc9,0xe0,0xc9,0x1f,0x62,0xfb,0x96,0x52,0xc4,0xbc,0xb5 +.byte 0xc2,0x32,0x08,0x66,0xbf,0x27,0x6b,0x60,0xdd,0x29,0x65,0x98,0x40,0x5f,0x0a,0x41,0xb7,0x7b,0x9e,0xd1,0xb8,0x99,0x46,0xc0,0xf4,0x89,0x4f,0xc9,0x2c,0x3c,0xaf,0xc9,0xe4,0x86,0xa6,0xf9,0xeb,0x13,0x99,0x62,0x26,0xec,0x75,0xc5,0x42,0x0f,0x64,0xf8,0x43,0x96,0x4a,0xe0,0x3c,0xb9,0x00,0x83,0x41,0x71,0xcf,0xdb,0x5d,0xa0,0xc0,0xa0 +.byte 0xe5,0x2c,0x75,0x6b,0xbe,0x87,0xbc,0xb3,0x1a,0xef,0x4c,0x65,0x34,0xc8,0x98,0x19,0xa2,0xed,0xf1,0xbe,0xe8,0x7c,0xd4,0xbd,0x5a,0x32,0x30,0x63,0xe0,0x86,0xef,0x63,0x98,0xa3,0x4a,0xfb,0xfe,0xd5,0x6e,0xe2,0x9c,0x54,0xc1,0xe9,0xd2,0x40,0xcf,0xc6,0x54,0x59,0xb4,0x8c,0x1a,0x11,0x7f,0x16,0xb4,0x1c,0x49,0x45,0x44,0x91,0xea,0xcf +.byte 0xa5,0xf4,0x7b,0x3a,0x83,0x05,0xc9,0xb6,0x69,0x3b,0xe1,0x5b,0x24,0x63,0x90,0x59,0x66,0x5c,0xe4,0x00,0x6b,0x4d,0xe3,0xa6,0x90,0xe1,0x3a,0xad,0x5d,0x4a,0xfb,0x32,0x87,0xed,0xd3,0xc1,0xab,0x22,0x3b,0x9c,0x0e,0x38,0xa1,0x67,0x66,0x33,0x7b,0x6d,0x7f,0x95,0x20,0xf7,0x07,0x82,0xa7,0xf8,0x57,0xdb,0xc8,0xb2,0x69,0xe5,0xcc,0x54 +.byte 0x6b,0xb5,0x70,0xbf,0x06,0xd0,0xa7,0x0c,0xb8,0x2a,0xe6,0xca,0x86,0xce,0x27,0x55,0xff,0xb2,0x25,0x88,0x4d,0xda,0x51,0xe3,0x50,0x73,0xfa,0x9c,0x15,0x2e,0x1b,0x5c,0x46,0x61,0x12,0x29,0x5a,0x04,0x39,0xf2,0x18,0xe8,0x50,0x69,0xcc,0x0f,0x69,0x27,0xae,0xdb,0x30,0xce,0xf4,0x61,0xc7,0x41,0xd3,0xbd,0x92,0xab,0x8e,0xf9,0x47,0xc8 +.byte 0x06,0xc1,0x94,0x05,0xcb,0xf5,0x71,0x68,0xf2,0x74,0xca,0x0f,0x8a,0xfe,0x92,0x1e,0x0e,0xd5,0x42,0x19,0x6a,0x69,0x7e,0xa9,0x79,0xfa,0x3b,0x43,0xe3,0xee,0x71,0x66,0xbe,0x39,0xb2,0x70,0x6c,0x74,0x12,0xcf,0x56,0xae,0x98,0xaa,0x19,0xf0,0x80,0xff,0xf1,0x8a,0x23,0x5e,0x86,0xc7,0xfc,0x5c,0x74,0x0d,0xfa,0x23,0x5d,0x65,0x44,0x80 +.byte 0xea,0x83,0xf1,0x2b,0xf5,0xe0,0xb0,0x16,0x3b,0x4c,0xdb,0x62,0xdd,0x50,0x05,0xd0,0x84,0xc0,0xda,0x14,0xd4,0xc7,0x5e,0x41,0xe3,0xb1,0x05,0xa2,0xbe,0xe6,0x7e,0x3f,0x77,0x8a,0x89,0x77,0xff,0x59,0xeb,0x43,0x57,0xe1,0x70,0xee,0x9c,0xb3,0x75,0x46,0x4d,0x33,0x26,0x8c,0x88,0xaf,0x49,0xad,0x97,0xa9,0x03,0x16,0xe9,0x55,0xae,0x1b +.byte 0xda,0x80,0xa4,0x52,0x7e,0xbc,0xef,0x17,0x27,0x94,0x09,0x94,0x05,0xab,0xdc,0x6d,0x24,0xa4,0xae,0x43,0x78,0x2e,0x18,0x0d,0xf5,0x85,0x43,0xba,0x3b,0x36,0x2a,0x43,0x3b,0xd6,0x2e,0xc9,0x97,0x29,0x87,0xf3,0x98,0x80,0xc5,0xe6,0xc3,0xa3,0xeb,0x36,0x0b,0x5a,0xc5,0x6c,0x0f,0x53,0xdf,0x7d,0xb9,0xc0,0xdb,0x57,0xde,0xbb,0x89,0x7b +.byte 0xb3,0x3b,0x9b,0x9b,0xe3,0x16,0x95,0xf1,0x44,0x0b,0x96,0x51,0x56,0x37,0x74,0xcb,0x6d,0x59,0x26,0x8b,0xb3,0xa8,0xdc,0xf4,0x7c,0x32,0xa7,0xcb,0x06,0x79,0xbf,0x09,0x5f,0xca,0xd5,0xa4,0x05,0x60,0xba,0xc1,0x2e,0xc7,0x35,0xc7,0xe4,0xe4,0x91,0xd1,0x4f,0x1b,0x1d,0x5e,0x3b,0x59,0x0e,0x7e,0xb6,0x5d,0xbb,0x99,0x20,0xc3,0xf5,0x28 +.byte 0xc7,0xc7,0xc5,0x8c,0x14,0xd0,0xea,0x9a,0x6c,0xb0,0x2f,0x40,0xfb,0xb3,0xd6,0x8c,0xc2,0x8f,0xcb,0x5b,0xb9,0xdf,0xd8,0xae,0x48,0x8e,0x1a,0x2a,0xdd,0x8b,0x2b,0x14,0xf8,0xff,0x51,0xd2,0x73,0xed,0xbe,0x14,0x09,0x9d,0x50,0x28,0x18,0xe6,0xc4,0xba,0x6a,0xf9,0xc3,0xb5,0x23,0x91,0x5a,0x10,0x5b,0xd6,0x69,0x99,0x76,0x1b,0x6a,0xea +.byte 0xc8,0x93,0x39,0x47,0xd0,0xc4,0x23,0xf7,0xb4,0xa2,0xc3,0x31,0xc3,0xca,0x13,0x12,0x7c,0x30,0x5c,0x73,0x32,0x6c,0xe2,0x48,0x6d,0xe5,0x9f,0xfc,0xd8,0x8b,0xef,0xf2,0xa7,0xc4,0x00,0xe7,0xc9,0x7b,0x93,0xb9,0x47,0x68,0xae,0xe6,0x6c,0xf2,0xfb,0x60,0xb4,0x51,0xa2,0x09,0x19,0x81,0x3e,0x34,0xb6,0xcd,0x41,0xd7,0xe2,0x4f,0xf5,0xf8 +.byte 0x08,0xe4,0x88,0xb1,0x0f,0x19,0x6e,0x9e,0xf2,0x88,0x9b,0x7e,0xfe,0x46,0x9e,0x27,0xb3,0xc7,0xaf,0x1d,0xb7,0xc3,0x31,0x9c,0x96,0x54,0x0a,0x10,0xd1,0x62,0x3f,0xa1,0x17,0x77,0xf5,0xbc,0xf5,0x53,0x87,0x68,0x18,0x17,0x32,0x62,0x7b,0x66,0x88,0x28,0xf9,0x60,0xba,0xbe,0xa8,0xe6,0xa7,0x9c,0x15,0x15,0xe8,0x3f,0x09,0xb4,0x7b,0xa0 +.byte 0x14,0x8f,0x5a,0xfe,0xbf,0xc2,0xc5,0xce,0x40,0x2e,0x23,0xae,0xa2,0xa9,0x88,0xea,0x0a,0xef,0x8a,0xa4,0x63,0x19,0x80,0x06,0x90,0x7e,0x5c,0x28,0x97,0x20,0x78,0xd6,0xf2,0xb0,0xea,0xb3,0xef,0x22,0x4c,0x35,0x46,0x44,0xa0,0x84,0xba,0x29,0xee,0xf5,0xa7,0x75,0x6a,0x9d,0xe8,0x67,0xbf,0xd9,0xf4,0x9e,0xa7,0x09,0x46,0x77,0x7c,0x76 +.byte 0xa6,0x1d,0x2c,0x1d,0xcb,0x95,0xa0,0x2c,0x45,0x50,0x6e,0x2c,0xdd,0xe2,0x9c,0xbc,0xa5,0xc1,0x72,0x48,0x19,0xdd,0xe0,0x21,0x90,0xf7,0x66,0xa7,0x43,0x94,0x32,0x6d,0x7d,0xe2,0x6f,0x6b,0x8f,0x38,0x97,0x4e,0xd0,0xbf,0x41,0xd2,0x24,0xba,0xd0,0xe7,0xd1,0x56,0x74,0x58,0x41,0xbc,0x7b,0xe7,0xbd,0x39,0x43,0xdb,0x2d,0x1a,0x66,0xb8 +.byte 0xc8,0xef,0x3f,0x6d,0xcd,0x5d,0x2d,0x1b,0xd7,0xb9,0x53,0x92,0x23,0xa2,0x5c,0x6f,0xd9,0x37,0xf4,0x43,0x6b,0x2d,0xb3,0xd5,0x7b,0x6c,0x87,0xb4,0xdd,0x05,0x39,0xa7,0x04,0x58,0xa9,0x7a,0xbe,0x08,0xf3,0x2e,0x79,0x7d,0x90,0xce,0x3d,0x2d,0x9d,0xf0,0xad,0xe6,0x28,0x44,0x7d,0x61,0x05,0xc1,0xc8,0x5e,0x2e,0x07,0x6c,0xd4,0x9c,0xbe +.byte 0x3f,0xd8,0xfc,0x46,0xe5,0xbe,0x7c,0x12,0x30,0x55,0xc9,0x6b,0xa0,0xac,0x17,0x0e,0xd0,0x65,0x70,0xc9,0xd6,0x5e,0xb3,0x97,0x58,0x43,0x8e,0xce,0x18,0x48,0xc7,0xa6,0xdc,0x0c,0x14,0xef,0xbf,0x1b,0xaf,0xca,0xbe,0x2a,0x96,0x27,0x82,0x3d,0xec,0x9b,0x0c,0xc8,0x40,0x7b,0x3f,0x03,0x93,0x70,0x87,0x50,0x24,0xc5,0x1b,0x10,0x91,0x66 +.byte 0x9f,0xbd,0xc2,0x9b,0xa0,0xee,0x5d,0xd3,0x65,0x17,0x03,0x4e,0x32,0xe3,0xb1,0x62,0xf7,0xe8,0x22,0x79,0x55,0xea,0xd9,0x3b,0x27,0x77,0x65,0x3d,0x44,0xde,0xbe,0x79,0x2d,0xfa,0x0b,0x59,0x08,0xf0,0x9b,0xc5,0xe0,0x78,0x6b,0x57,0x4f,0x75,0x32,0x92,0x6f,0xb1,0x4c,0x70,0x98,0x26,0xd1,0x07,0x2d,0xb7,0x8e,0x32,0x16,0x96,0xd7,0x0e +.byte 0xde,0x61,0x49,0x46,0x65,0x92,0xdd,0xb3,0xd0,0x98,0x1b,0xed,0x30,0x6f,0xfd,0x02,0x8e,0xf8,0x7f,0x84,0x95,0x6d,0xe9,0x25,0x01,0xef,0xc9,0x03,0x7b,0xe1,0xf9,0x4f,0xd9,0x19,0xbb,0xa6,0x46,0x89,0xdf,0x36,0x01,0x40,0x08,0xfa,0x0b,0x93,0x2e,0x4b,0xdd,0xd0,0x1d,0x37,0xb9,0x14,0x4c,0x09,0xf1,0x7a,0x95,0x6c,0xd7,0xde,0xdc,0xcd +.byte 0xd0,0xdc,0xeb,0x84,0x59,0x24,0xa1,0x1e,0xc2,0xa0,0x52,0x6b,0x74,0x2a,0x6b,0xef,0xe2,0x37,0x94,0xef,0x6e,0x3e,0x79,0x7c,0xba,0x90,0x3d,0xda,0x2d,0x96,0xf6,0x7b,0x59,0xa9,0x12,0xa2,0x90,0x72,0x18,0xde,0xbd,0xaf,0xa2,0x4a,0x1f,0x50,0x6c,0xb4,0x03,0xb8,0x29,0xa8,0x6e,0x07,0x7a,0xbe,0xee,0x79,0x6f,0x03,0x29,0x4b,0xf5,0x76 +.byte 0x06,0x41,0x5a,0x14,0xf6,0x9c,0xd4,0xa0,0xf2,0x86,0x34,0x10,0x0c,0x12,0x6e,0x3b,0x6f,0x3b,0xb2,0x29,0xde,0xa9,0xa1,0x3e,0x32,0xe9,0xd7,0x26,0x12,0x73,0x0d,0xcc,0x5e,0x4d,0x0d,0xdf,0xa7,0xe0,0x2c,0x16,0x78,0x3f,0x76,0x7a,0x90,0x98,0x95,0x7c,0x18,0x28,0x64,0x9e,0xcf,0x7f,0x02,0xa6,0xc2,0x57,0xdd,0xaf,0x81,0xa8,0x60,0x34 +.byte 0x8f,0x60,0x7e,0x62,0x6d,0xb1,0xb6,0x36,0x3e,0xb4,0xa9,0xad,0xfc,0x88,0x22,0x6b,0x50,0x26,0xd1,0xc4,0xa0,0xfc,0x58,0x30,0x1b,0xb3,0xec,0x0e,0x9a,0xd8,0x44,0x34,0xc5,0x63,0x74,0x28,0xe6,0x35,0x05,0xc0,0x0a,0x0e,0x3b,0x75,0x13,0x94,0xbf,0x21,0xb3,0xba,0x90,0xca,0xc2,0x0b,0xcd,0x39,0xe3,0xcb,0xf4,0x52,0x31,0xe4,0xb1,0x31 +.byte 0xf8,0x62,0x77,0x69,0x37,0x5c,0x45,0xc8,0xe7,0x14,0x35,0x45,0x41,0x03,0x5b,0x1e,0x81,0x6a,0x18,0xe9,0xc2,0x17,0xe5,0xbd,0x8a,0x33,0x29,0xe4,0x93,0x3a,0xa2,0x23,0xd4,0x5d,0xef,0x72,0x1c,0x6e,0x94,0x64,0x48,0xfc,0x53,0xd3,0x90,0x1a,0xd2,0xc8,0xa6,0x1f,0x83,0x3b,0x23,0x5d,0x7e,0x4a,0x89,0x4d,0x51,0xf6,0x1c,0x65,0x17,0xf5 +.byte 0xdf,0xfb,0x6c,0x61,0xaa,0x1d,0xfd,0xf3,0xe8,0x9e,0x05,0x87,0x1b,0x70,0xde,0x1a,0x19,0xce,0x21,0xf3,0x2a,0x21,0xd1,0x16,0x19,0xc8,0x7f,0x19,0xa1,0x30,0x9f,0xd3,0x39,0x54,0x21,0x06,0x08,0x7d,0x74,0x1d,0x1e,0x04,0xfd,0x96,0xef,0xf7,0x59,0x92,0x0e,0x71,0x31,0x1b,0x86,0x86,0x8b,0xdc,0x3a,0x43,0xfa,0x2e,0x62,0x9d,0xec,0xd7 +.byte 0x7a,0x96,0x1d,0xaa,0x30,0x92,0xf4,0xbf,0x05,0xa5,0xa9,0xff,0x42,0x7f,0xa7,0xae,0xe2,0x25,0x5d,0x79,0x5c,0xc2,0xbe,0xcf,0x6a,0x0e,0x08,0xa4,0x3b,0x30,0xe2,0x17,0x24,0x3d,0x4e,0xb8,0xd6,0xcd,0x03,0x01,0xaf,0xc0,0xcb,0x3f,0x32,0xb6,0x5b,0x2d,0xb4,0x66,0x51,0xe1,0x70,0x2a,0x2f,0x0e,0xda,0x68,0xe4,0x4e,0x32,0xa0,0x9a,0x50 +.byte 0x0a,0x8a,0xfe,0x9f,0x5e,0xb3,0x3c,0x7b,0xc9,0x71,0xff,0xab,0x39,0xa8,0x46,0x03,0x7f,0xce,0xb9,0x3f,0x70,0x23,0x81,0xc1,0xac,0x25,0xdb,0x83,0xd6,0xd1,0x15,0x4a,0x8d,0x89,0x7e,0x8f,0x49,0xff,0x39,0x29,0xb9,0x2c,0xfe,0x50,0x2e,0xcc,0x4e,0x82,0x35,0x90,0x09,0x47,0x7f,0x67,0x1a,0xd3,0xf3,0xe8,0x8d,0x5c,0xaa,0x1c,0xbc,0x49 +.byte 0xce,0x2f,0xdd,0x8f,0xe9,0x6f,0xb1,0x07,0xea,0x40,0x56,0xe9,0x86,0x04,0x4b,0xe1,0x4c,0xc6,0x6f,0x69,0x87,0x11,0x67,0xed,0x15,0xfc,0x23,0x26,0x70,0xaa,0xd2,0x0e,0x4d,0x22,0x67,0xa4,0xa2,0x6e,0x71,0xb8,0x1d,0x86,0xe8,0xc1,0x1c,0x23,0xf9,0xc1,0xae,0x0a,0xd9,0x15,0x28,0x25,0x01,0xb7,0x71,0xa8,0x5a,0x8e,0xc1,0x6a,0xad,0x39 +.byte 0x75,0xee,0x1a,0xdf,0xb3,0x4d,0x22,0x79,0x2e,0xbb,0x87,0xa1,0x43,0x2a,0xdb,0x54,0x32,0xeb,0x1d,0x4c,0xbd,0x77,0xa7,0xfd,0x16,0x11,0x90,0xe0,0x38,0xc5,0xef,0x72,0xe6,0x5e,0xb9,0x77,0xfc,0xd8,0x00,0xe2,0xa5,0x11,0xc2,0x84,0x94,0xa4,0xdd,0xa9,0xea,0xc1,0x5a,0xb7,0x9a,0x07,0x14,0xd0,0x74,0x2c,0x44,0x01,0x58,0x0a,0xca,0x8d +.byte 0x3b,0x27,0xda,0x02,0xeb,0x40,0x91,0x5f,0xd4,0x47,0x87,0xdf,0x5e,0x88,0xbe,0x8f,0x23,0xde,0x28,0x61,0xb5,0x93,0x74,0x47,0x14,0x1b,0x3e,0x03,0xa3,0x38,0x71,0x06,0xe8,0xf1,0x60,0xd8,0xc4,0x6d,0x91,0x42,0x72,0xdf,0xd7,0xe4,0xf8,0xce,0xdc,0xae,0x55,0xb6,0xee,0x2a,0x60,0xe7,0xc6,0x86,0x3c,0x6a,0xf4,0x05,0x09,0xf2,0xdd,0xb0 +.byte 0xf5,0x9d,0x4d,0x49,0xc2,0xc1,0xb6,0x6a,0x00,0xac,0x6c,0xf5,0xc1,0x03,0xb2,0x2c,0x16,0x9b,0x16,0xe3,0x98,0x3b,0x79,0x1a,0x07,0xed,0x55,0x9d,0x0a,0x48,0x7b,0x22,0x75,0x9a,0x20,0x98,0x3a,0x8c,0x93,0xdd,0xe4,0x9e,0x1b,0xc3,0xf1,0x1f,0x64,0x63,0xa5,0x37,0x51,0x7f,0xaf,0x10,0xb3,0x35,0x9b,0xba,0x7f,0x78,0xf1,0xd8,0x9f,0x65 +.byte 0x1c,0x8a,0x03,0x05,0x88,0x2d,0xd9,0x1c,0x8a,0xd3,0x52,0x71,0x20,0xf7,0xb7,0x47,0xef,0x9a,0xea,0xa4,0xd0,0x58,0x3f,0x4b,0x0e,0xe3,0xe4,0x88,0xb4,0xdc,0x75,0x31,0xa4,0xb6,0xf0,0x33,0x2f,0xc4,0xa2,0x0f,0x59,0x2e,0xa7,0x14,0x60,0x03,0x68,0xce,0x4f,0x41,0xf1,0x2c,0x49,0x18,0x34,0x70,0xbb,0x35,0xa7,0xcc,0x09,0x60,0x7b,0x0e +.byte 0xc1,0x4e,0xdb,0xb6,0xfe,0x19,0x7a,0xeb,0x9b,0x9d,0x9c,0x6e,0x21,0x69,0xa5,0x8c,0xc5,0x0e,0x27,0x13,0x52,0xa2,0xaa,0x83,0x72,0x73,0xac,0xc3,0xd3,0x8b,0x92,0xd0,0xdc,0x79,0x22,0xcd,0x81,0x94,0xc3,0xb1,0xd3,0xf0,0xbb,0x0a,0x43,0x33,0xdc,0xf5,0x8e,0xd7,0x48,0xfa,0xbb,0x3c,0x47,0xd4,0x95,0xad,0x25,0xf0,0x39,0xf0,0x69,0x3d +.byte 0xbb,0xf7,0xf3,0x0d,0x60,0x42,0x3e,0x50,0xff,0xa3,0xf3,0x54,0x4f,0xdb,0x5e,0xfa,0x3c,0x17,0xc8,0x4c,0xcf,0xe8,0x2d,0xcc,0xa7,0x73,0x15,0x6c,0xe6,0x5c,0x90,0xa1,0xce,0xef,0xc5,0xd5,0x1f,0x1f,0xc5,0xe0,0x6d,0xb2,0xd6,0xde,0x68,0x8f,0x73,0xa2,0x48,0x15,0xbf,0xd7,0x86,0x6a,0x11,0x36,0xde,0x60,0x69,0x86,0xb0,0x42,0xec,0xa6 +.byte 0xd5,0x5d,0xfc,0x51,0x20,0xd3,0x48,0xcf,0x22,0x2f,0x3c,0x87,0x07,0x57,0x44,0xec,0x63,0x2c,0xbd,0x14,0x21,0xa2,0x4f,0x2e,0xf2,0xce,0xb4,0x25,0xf8,0x66,0xd9,0xd5,0x16,0x10,0x1d,0x3f,0x00,0xfa,0x95,0xf8,0xb6,0xb3,0x67,0x23,0x2e,0xfb,0x65,0xfd,0x16,0x80,0x81,0xc0,0x62,0xbd,0x68,0x60,0x94,0xc1,0x49,0x50,0x63,0xe7,0xf5,0xc6 +.byte 0x87,0x6a,0xaf,0xbf,0x6f,0x88,0x7a,0xbb,0x9d,0x59,0xf0,0x94,0x1b,0xed,0x6e,0x52,0x52,0xd7,0xea,0x3a,0x89,0xa3,0x86,0xab,0xf2,0x32,0x28,0xf7,0xe3,0x50,0x6f,0xbe,0x9b,0xab,0x73,0x0f,0xe2,0x9c,0x0b,0xaa,0xba,0xb7,0xfb,0x99,0x09,0xe6,0x76,0xa5,0x4e,0x2a,0x56,0xdc,0x07,0xca,0x7c,0xfa,0xc5,0x36,0x89,0xe3,0xaf,0x9c,0x67,0x9f +.byte 0xbc,0x94,0x35,0xb8,0xee,0xf9,0xf5,0x04,0x20,0xe0,0xed,0xc2,0x3c,0x7a,0x4a,0xc0,0x9b,0x28,0xf0,0x14,0xd2,0x08,0x40,0x3a,0x6e,0xc3,0xce,0xcc,0x4f,0x8f,0x3d,0xd9,0xca,0x8b,0xf7,0x5d,0xe5,0x0f,0x7a,0x85,0xaf,0xa1,0x9d,0xbd,0x28,0x07,0xee,0x54,0x2e,0x23,0x18,0x1d,0xc9,0x6b,0x67,0x2b,0x12,0x33,0x0d,0x8b,0xf4,0x7f,0x34,0x47 +.byte 0xfb,0x2c,0x55,0x3c,0x66,0x32,0xe6,0xa0,0x97,0x3b,0x8a,0x1e,0xc8,0xcf,0xd3,0x72,0x76,0x87,0x8c,0x8e,0x0f,0xfa,0x3a,0x37,0x99,0x0f,0x2b,0xfd,0x1c,0x5c,0x4f,0x81,0x87,0x80,0x2d,0x02,0xb9,0xeb,0xe3,0x66,0xe3,0xa0,0x09,0x38,0x2c,0x48,0xbc,0x91,0x38,0x3a,0x7b,0x2a,0x63,0x0d,0x67,0x27,0xd8,0xde,0xe9,0xab,0x1a,0xf2,0x46,0x53 +.byte 0xcc,0x80,0x5a,0x02,0x61,0xd1,0x18,0xd6,0x05,0x66,0xec,0x48,0x51,0x5d,0x91,0xa8,0x55,0x52,0x8d,0x56,0xa6,0x89,0xf2,0xe5,0x99,0x87,0x09,0x59,0x70,0x1f,0x11,0x1d,0x0d,0x3d,0x67,0x8f,0x9a,0x82,0x4f,0x81,0x21,0x0f,0xe6,0xeb,0x52,0xd0,0x21,0xb1,0x55,0xeb,0x59,0xfa,0x49,0x1e,0xb7,0x03,0x5b,0xe0,0x50,0xd4,0xf9,0xfd,0x41,0xa9 +.byte 0x7a,0x5a,0xee,0xca,0x0b,0xdc,0xa1,0x32,0xd2,0x7f,0x72,0x1e,0xae,0x93,0x01,0xc0,0x34,0x79,0x32,0xaf,0x5f,0x60,0xba,0xc6,0x34,0xda,0xe3,0x85,0x0f,0xe1,0xe3,0x66,0xcd,0x3d,0xe4,0xfd,0xbc,0x1f,0x23,0x29,0x38,0x5e,0x8e,0x24,0xff,0x8d,0x23,0xaf,0x7d,0xd7,0x7f,0xd6,0xb2,0xca,0x1d,0xda,0x22,0xb1,0x2a,0x73,0x8e,0x3b,0xf3,0xee +.byte 0xbb,0x60,0x6f,0x7b,0xfd,0x84,0x2c,0x8c,0xcb,0x13,0x31,0x5c,0x7c,0x77,0x57,0x39,0x0f,0x03,0x12,0xc9,0xa1,0x2f,0x72,0x62,0x3f,0x0e,0x70,0xd2,0x62,0x40,0x60,0xb6,0x24,0xbc,0x12,0xa4,0x24,0xbb,0x77,0x94,0xce,0x0a,0xd5,0x4a,0xba,0x9b,0x5e,0xa2,0x04,0xcd,0xe5,0x3d,0x2b,0x3b,0xa0,0x76,0x0f,0xfd,0xe7,0x0a,0x46,0x2a,0x98,0x09 +.byte 0x9f,0x7c,0xd7,0xc3,0x33,0x4c,0x34,0xa4,0x2f,0x55,0x38,0x93,0xfb,0x9a,0xd5,0x75,0x22,0xdd,0x84,0x32,0x15,0xbe,0x43,0x73,0xa2,0xbe,0x23,0x1c,0x8e,0x3e,0xee,0xad,0xa7,0x54,0x8b,0xbe,0x9b,0xc8,0x6a,0x78,0x62,0xf1,0xb2,0x36,0x0e,0x00,0xfd,0xd0,0x9f,0x70,0xcc,0x2a,0x94,0x3e,0xe7,0x8c,0x60,0x4b,0xe6,0xc1,0x8c,0x65,0x0b,0x1a +.byte 0xe2,0xfd,0xfd,0xe8,0xa0,0x85,0x8f,0x1d,0x2c,0x5b,0x34,0x30,0x1a,0x6f,0xe6,0xe9,0x75,0xbc,0xcf,0xc4,0x6d,0x12,0xb5,0xff,0x3d,0x56,0x4a,0x08,0xbf,0xbd,0x8b,0xd1,0xfe,0x37,0x31,0x2b,0xe8,0x7d,0x6b,0x97,0x99,0x80,0xd9,0x22,0x2f,0x4c,0xc4,0xa6,0x98,0x24,0x42,0x07,0x4b,0xbc,0x4f,0x14,0x6b,0x15,0x90,0x27,0xf6,0x9f,0x2f,0x42 +.byte 0xfd,0xcc,0x51,0x1c,0xf0,0x8e,0x28,0xf6,0xea,0x3f,0xc0,0x65,0x17,0xc8,0xf7,0x90,0xf4,0x54,0x9d,0xc5,0x53,0x11,0x5c,0x90,0xcb,0xa8,0xe8,0xd2,0x0c,0x6b,0xb7,0x15,0x0d,0x2c,0x6d,0x7c,0x2e,0xb9,0xc9,0xde,0x31,0xec,0x85,0x74,0x93,0x95,0x06,0x1d,0x0c,0xed,0xd4,0x77,0x65,0x91,0x3f,0xa4,0xa5,0x90,0x63,0x63,0xcd,0x73,0x13,0xe7 +.byte 0xad,0x39,0x22,0x37,0x41,0x7b,0xf8,0x64,0x14,0xe6,0xe0,0x93,0xc2,0x91,0x4f,0x34,0x0b,0x01,0xef,0x9a,0x27,0x0e,0xe7,0xf5,0x0b,0x7e,0xb1,0x13,0xa5,0x24,0xcf,0xdb,0x54,0xf8,0x32,0xae,0x01,0x2e,0x61,0x0e,0x73,0x36,0x4a,0x17,0x6c,0xdb,0x9a,0x80,0x6e,0x91,0x54,0x7b,0xa9,0x85,0x27,0x08,0x75,0xb3,0x1f,0x82,0xa5,0x3d,0x67,0x99 +.byte 0x7b,0x38,0xb9,0x21,0x3f,0xa1,0x06,0x7d,0xde,0xc9,0xef,0x4d,0xca,0x8d,0xa2,0x5a,0xa1,0x85,0x03,0xe2,0x8b,0x8f,0x4f,0xc5,0x47,0x8d,0xb6,0x8d,0xd3,0x8d,0x0a,0x11,0xa5,0x45,0x7b,0x2e,0x38,0x1b,0xb6,0x23,0x17,0x89,0x06,0xe5,0x25,0x5c,0x5e,0x95,0x2f,0x61,0x48,0x5a,0x55,0x40,0x7e,0x0f,0x2b,0xd8,0x2b,0x7e,0xfb,0x3b,0xa9,0xf4 +.byte 0x26,0x65,0x70,0x46,0xdb,0x1f,0xa7,0x16,0xfa,0xd4,0x5e,0x6c,0xaa,0x7c,0x2e,0x69,0xf1,0x55,0xb2,0x99,0x1e,0xed,0x54,0x5e,0xb4,0x70,0x42,0xf1,0xa5,0x68,0xd4,0x02,0x59,0x07,0x82,0x35,0x67,0xe6,0x21,0x08,0xb6,0x23,0x2d,0xa0,0xe3,0xe5,0xef,0x4c,0xe0,0x7f,0xb0,0x30,0xa5,0xc1,0x5e,0xea,0x5d,0xeb,0xe3,0x97,0x9f,0x5c,0xf7,0x91 +.byte 0x8e,0x8d,0xac,0xe3,0xdc,0xd6,0x94,0x93,0x0f,0xaf,0x07,0x21,0x0c,0x20,0x0d,0x73,0xe2,0x0e,0x9f,0x77,0xb8,0xd5,0x0c,0xd8,0x64,0x49,0x34,0xe0,0xa1,0xe7,0x42,0xfb,0xfd,0x30,0x03,0x2e,0x2c,0xb7,0x9a,0x17,0xe5,0xa6,0x34,0x8d,0xe4,0xcf,0xf8,0x47,0xb7,0xf0,0xc1,0xb4,0xee,0x2b,0xbe,0x07,0x7c,0x99,0x48,0xb3,0x42,0xb6,0xf1,0x98 +.byte 0x45,0xd4,0x53,0xff,0x27,0x26,0x2e,0xa5,0x74,0xfc,0xa8,0x09,0x37,0x16,0xf6,0xb2,0xad,0x5b,0xee,0x51,0xcc,0x09,0x90,0x4e,0x5f,0xd0,0x72,0xd7,0xbb,0xd6,0x85,0xd6,0xe4,0xab,0xf8,0x7d,0x02,0xe0,0xc2,0x51,0xce,0xac,0x8b,0xf1,0x91,0x63,0xb4,0x2e,0xb5,0xe2,0x3a,0xac,0xf6,0xb0,0xd9,0x4a,0x90,0xef,0x66,0x19,0x2c,0xbd,0x87,0xae +.byte 0xa1,0xee,0x08,0x5e,0x88,0xde,0x1c,0x47,0xeb,0x07,0x20,0x95,0xb2,0xdf,0xfc,0xd7,0xe2,0x44,0x45,0xbc,0x56,0x48,0x46,0x26,0xef,0xce,0xf9,0x0f,0xf6,0xab,0x33,0xf0,0x35,0xc8,0x39,0xd6,0x91,0x9e,0x02,0xe7,0xc5,0x30,0x3a,0x1d,0x78,0x51,0xa7,0x48,0xc9,0xc9,0x7c,0x09,0x0e,0xa1,0x89,0x0b,0x54,0xbb,0xc6,0x65,0x16,0xb6,0xb1,0x82 +.byte 0xa6,0x53,0x8b,0x20,0x25,0xf2,0xfb,0x6d,0x4e,0x5e,0xf6,0x62,0xe9,0x14,0xbc,0x0a,0x68,0x09,0xa7,0x79,0xc1,0xad,0x9d,0x45,0x75,0xbd,0x96,0x3b,0x27,0x93,0x10,0x10,0x34,0x98,0x96,0xf6,0x0e,0x24,0x92,0x1f,0x00,0xf4,0x9e,0x55,0x08,0x76,0x83,0xef,0xd8,0xad,0xcb,0xcc,0x82,0x25,0xe3,0x7d,0xd3,0xb3,0xc5,0x35,0x8f,0x5d,0x9a,0x56 +.byte 0xe7,0x03,0xf2,0xa2,0x40,0x44,0x5c,0x1e,0xb6,0x53,0x1f,0xe1,0x65,0xa9,0xa1,0x06,0xa1,0x1b,0x96,0x2e,0xcc,0xce,0x99,0x11,0x26,0x2b,0x1b,0xd6,0x38,0x45,0x56,0x87,0x3d,0xf3,0x42,0xe2,0xa4,0x57,0x11,0x95,0x8c,0x07,0xd0,0xb0,0x82,0xcc,0x75,0x30,0x5c,0x61,0x72,0x5a,0x22,0xd7,0xa2,0xb3,0xa1,0x1c,0xa2,0xfa,0xaa,0x71,0x31,0xc2 +.byte 0xde,0xf5,0x3f,0x52,0x02,0x25,0x86,0x37,0x1c,0x1e,0x67,0x3f,0x8b,0x1a,0xe9,0x0a,0x5e,0xe5,0xef,0x14,0xe0,0x69,0x47,0x6d,0xb3,0xbd,0xd2,0x44,0xbf,0x1a,0xdc,0x71,0xe6,0xd8,0xf8,0x7a,0x1e,0xf6,0x67,0xdb,0x96,0x2f,0xab,0x8d,0xfa,0x4b,0x16,0x02,0xf9,0xdd,0x9a,0x5d,0xd3,0xf1,0x34,0x9f,0x78,0xf0,0x30,0xdd,0x5f,0x59,0x24,0x39 +.byte 0xa2,0x4b,0xc4,0x66,0xf5,0xc9,0xbd,0x4c,0x0e,0xd3,0x54,0x01,0x50,0x3a,0x12,0xd9,0xd9,0x25,0x56,0xf2,0x29,0x74,0xd8,0x3b,0x7d,0xf8,0x5d,0x60,0xc7,0x72,0x4b,0xb9,0xb0,0xb2,0xc9,0x5f,0xdf,0x4e,0x6d,0x6e,0x0f,0x97,0x19,0xe6,0xaf,0x1d,0xfb,0x70,0xc5,0x62,0xb9,0xb1,0xa4,0x4b,0x3d,0x26,0xe9,0xd2,0x3d,0x44,0x61,0x1d,0xbe,0xe0 +.byte 0x3e,0x7d,0xe4,0x77,0x41,0x37,0xa0,0x9b,0x60,0x57,0x62,0x05,0x4c,0x04,0x68,0xfb,0x47,0xcf,0x48,0x48,0xa0,0x86,0x22,0xea,0x9f,0x49,0x89,0xc3,0x7c,0x4c,0x5c,0xde,0x31,0xad,0x85,0xf7,0x99,0x00,0x4e,0x64,0xbd,0xd1,0x6e,0xa0,0xd8,0xfb,0x71,0x08,0x44,0x7d,0x22,0x75,0x78,0x5f,0xe4,0x6b,0xce,0x28,0xd8,0x47,0x9d,0xb1,0x31,0x68 +.byte 0x1a,0x91,0x4f,0x94,0x25,0x6d,0x9f,0xc8,0x21,0x77,0xaf,0x4e,0x98,0xc5,0x9d,0xf9,0x52,0x5f,0x0a,0x23,0x61,0x0e,0xda,0x11,0xad,0x43,0xae,0x82,0x07,0x5b,0xc8,0x1f,0xee,0x15,0x65,0xf0,0x30,0xb4,0x97,0x55,0xdd,0xbd,0xcf,0x01,0x37,0x14,0xd5,0x6e,0x12,0xe4,0xa5,0x20,0x38,0xea,0x4c,0x61,0x68,0x8c,0x47,0x68,0xfd,0xd5,0xda,0x36 +.byte 0x8c,0x18,0x31,0x7c,0x5a,0xde,0x03,0x1d,0xb3,0xe2,0x17,0xe8,0x5a,0x7b,0x9b,0x0f,0x2a,0xac,0x1d,0x79,0x8d,0xb4,0xbe,0x41,0x00,0x0a,0x8e,0x75,0xa6,0x69,0x7a,0x17,0xe7,0x29,0xd4,0xcd,0xd5,0xbc,0x5c,0x17,0x53,0x17,0x3c,0x58,0x4b,0x44,0x39,0xa8,0x6b,0x7b,0x01,0x05,0xe3,0x33,0xd8,0x8e,0xb8,0x25,0xe6,0xe5,0x15,0xe3,0x2d,0xb4 +.byte 0x75,0x2e,0x4e,0x7c,0xd5,0x19,0x56,0x9d,0x55,0xca,0xf7,0xd0,0x40,0x2d,0x98,0x4d,0x17,0x29,0xec,0x87,0x0e,0xb1,0x9b,0x80,0xb6,0x34,0xe6,0xe8,0xdf,0x2b,0x91,0x5a,0x4f,0x68,0x1e,0x2d,0x99,0x9f,0xf8,0x94,0xab,0x58,0xa8,0x02,0x99,0x52,0x42,0xf9,0xb0,0xe1,0x21,0x0d,0xb6,0xad,0x1f,0xce,0x77,0x53,0x1f,0x37,0x7b,0x19,0xf9,0x1c +.byte 0x84,0xfb,0x7a,0x81,0x37,0xd5,0xd7,0x28,0xfe,0x11,0x03,0x1b,0xd1,0x75,0x68,0x85,0x4a,0x59,0x42,0x8a,0xca,0x48,0x32,0x54,0x1b,0x5d,0x4d,0xa0,0x8f,0xc2,0x01,0xf5,0xab,0x53,0xb0,0xa2,0x64,0xfe,0x0f,0x82,0x0b,0xeb,0xdb,0xd5,0xfc,0xf1,0x8a,0xf8,0xf4,0x71,0x16,0xc4,0xe7,0x0f,0x61,0xe5,0x04,0xb1,0xdc,0x47,0xed,0x3e,0xe7,0x5d +.byte 0x22,0x65,0x4e,0xc9,0xd9,0x37,0x1d,0x0f,0xc9,0xee,0x86,0x47,0xa0,0x59,0x32,0x80,0x76,0xd1,0xf8,0x23,0x36,0xca,0x5d,0x26,0x6f,0x19,0x62,0x0c,0x23,0xaa,0xb3,0xa9,0x4f,0xc9,0x78,0x6d,0x1e,0xa6,0xf6,0xc2,0x88,0xbc,0x7e,0x38,0xaa,0x88,0x8f,0xad,0x95,0x13,0x80,0x5b,0x0a,0x95,0x5d,0x2d,0x2d,0xb0,0x81,0xf7,0x54,0x98,0xa8,0xfd +.byte 0x4b,0x67,0x66,0x96,0xc2,0x58,0x5f,0xef,0x7f,0xc2,0xa5,0x2d,0xf1,0xdc,0x6e,0xf3,0x70,0x23,0x2b,0xe6,0xad,0x9f,0x52,0x58,0xa0,0x68,0x44,0xdb,0xf8,0x8e,0x9e,0x74,0xe5,0x84,0xc2,0xfa,0xd6,0x0c,0x16,0x22,0x0c,0x7b,0xf1,0x33,0x29,0x9a,0x6c,0x19,0xab,0xe0,0x61,0x81,0x02,0x6c,0x3b,0xe6,0xb9,0x5d,0x8a,0xb3,0x85,0x88,0x95,0x17 +.byte 0x73,0x55,0x6a,0xd6,0xe4,0xa3,0xbc,0x36,0x7e,0x87,0x5f,0x63,0x6d,0x76,0x5f,0xba,0x29,0x20,0x98,0xc6,0x60,0x30,0xc3,0xa8,0x07,0x48,0xcf,0x0c,0x47,0x76,0x17,0xf3,0xa9,0x5b,0x3b,0xd7,0x57,0x3c,0xde,0x7f,0x00,0xd2,0x4f,0xba,0xdc,0x45,0xd1,0xbd,0xf4,0x6b,0x87,0xbd,0x48,0x4f,0xb4,0x7d,0x7a,0xd7,0xf7,0xda,0x96,0xd7,0xe0,0x7c +.byte 0x3c,0x6b,0x27,0x89,0x69,0x53,0x78,0x75,0xf6,0xb6,0x1b,0x92,0xd1,0x99,0x5c,0xdb,0xda,0xbf,0x48,0x59,0x7e,0x24,0xb6,0xa9,0x33,0xd9,0x8b,0x09,0xcb,0x15,0xe4,0xd8,0x72,0xcc,0xfb,0x1d,0x0b,0xc9,0x0a,0x78,0xec,0x2e,0xc1,0x58,0x0b,0xd2,0x78,0xa1,0xf0,0x1c,0x67,0x9f,0x9d,0xe2,0xce,0x04,0x33,0xa3,0x7e,0xc5,0x40,0x62,0x8b,0x8b +.byte 0x2f,0x72,0x66,0x8f,0x57,0x43,0xe5,0x06,0x28,0x43,0x24,0xdc,0xa1,0x12,0x07,0x27,0xfa,0xd2,0xb8,0x92,0xe8,0xc5,0x33,0x1e,0xa1,0x2c,0xf2,0x94,0x5b,0x9a,0x5f,0xbe,0x05,0x51,0xa8,0x6e,0x4a,0xa4,0x10,0x9d,0xa7,0x9e,0x97,0x97,0x1b,0x91,0x1c,0x85,0x8a,0x96,0x6e,0xc7,0x02,0x8e,0x59,0x38,0x8b,0xea,0xf7,0xc5,0xeb,0xa7,0xd2,0xfb +.byte 0xde,0xdd,0x47,0x61,0xbc,0x08,0x03,0xbe,0x48,0xcc,0xd4,0x11,0xe4,0x5a,0xd9,0x6a,0x58,0x0c,0x7e,0xd8,0x53,0x04,0xaa,0x27,0xfe,0x90,0x99,0x08,0x16,0x1e,0x88,0xf1,0x60,0x3b,0xba,0xfc,0xf2,0x04,0x14,0x4a,0x3d,0x57,0x40,0x56,0xc3,0x76,0x01,0xf5,0x8c,0x1a,0xde,0xd9,0x6e,0x1d,0x37,0xf7,0xa6,0xd6,0x57,0xcf,0xa1,0xea,0xf7,0x26 +.byte 0xdc,0x85,0x76,0x61,0x47,0xcc,0x4b,0xce,0x00,0x04,0x4b,0xbe,0xbd,0x17,0x61,0x49,0x17,0x18,0xb4,0x17,0xcd,0x19,0x03,0xb6,0x78,0x1d,0x8b,0xa6,0xf2,0xed,0xb2,0x38,0xf4,0xf1,0x7f,0x15,0xb3,0x3e,0x1e,0x5f,0xa0,0xe5,0x0b,0xf3,0xc3,0xb0,0xdd,0x0a,0xda,0x78,0x06,0xc6,0xe3,0x9c,0xee,0xaa,0xe3,0x93,0x08,0x9c,0x8f,0xc7,0x03,0x5f +.byte 0xad,0x66,0xc2,0xf3,0x9f,0xce,0x24,0x81,0x93,0xfa,0xc0,0x9f,0xda,0x5c,0x38,0xcf,0x69,0x0e,0x0d,0x9b,0x22,0xc7,0xa1,0x62,0x94,0xf1,0x7a,0xf6,0x54,0x14,0xcc,0xc1,0xa4,0xd6,0xd0,0xb6,0x12,0x94,0x97,0x96,0x4d,0xa6,0xce,0x84,0x7f,0x0f,0x19,0xf2,0x6d,0xba,0x3e,0xf2,0x50,0x06,0xc7,0x53,0x62,0xb4,0x9b,0xf4,0x82,0x48,0x85,0x2b +.byte 0xa6,0xab,0x65,0xff,0x18,0x4e,0x72,0x2f,0xfb,0x9f,0x73,0x08,0x80,0x12,0xe6,0x6b,0x81,0xf9,0x70,0x9d,0x38,0xbb,0x59,0x65,0x60,0xb6,0x89,0xbc,0xd5,0xf9,0xbd,0xbd,0xb5,0x17,0xcb,0x41,0xb8,0x29,0x87,0x11,0xd2,0xe5,0x06,0xfa,0x60,0x11,0x75,0xd8,0x83,0xcb,0x65,0x6c,0xb7,0xaf,0x86,0x41,0xb8,0x0d,0x4a,0x6c,0x48,0xf2,0x21,0x06 +.byte 0xab,0xd5,0xa5,0xef,0x62,0x51,0xbe,0x29,0xb0,0x02,0x77,0x0e,0xba,0xc8,0xac,0x77,0x97,0xeb,0x3f,0x83,0x17,0x54,0xa9,0xe6,0x1f,0xfd,0xc8,0xb2,0x64,0x89,0x78,0x39,0xe7,0xb9,0x4f,0xd4,0x6e,0x00,0xc3,0x8d,0x9a,0x11,0x4a,0x2a,0x3a,0x0d,0xa2,0x5a,0xe5,0xe3,0xf3,0xa3,0xa9,0x77,0x91,0xdd,0xa5,0x7d,0x1a,0xe9,0xa4,0xf1,0x78,0xaa +.byte 0x4e,0x93,0xb7,0x89,0x03,0x1a,0xba,0xa4,0x1b,0x2e,0xe6,0xfc,0xdf,0x3f,0x99,0xda,0x1d,0xa1,0xec,0x4a,0xc8,0x4b,0x28,0x24,0xb3,0xe5,0x1e,0xbf,0x85,0x74,0x8b,0xba,0xd5,0x5b,0x6c,0xd1,0x59,0x55,0x95,0xb3,0x6a,0x5f,0xd6,0xee,0x7a,0xf7,0x69,0xf5,0xb9,0xda,0xe6,0xdf,0x37,0xa3,0x61,0x4f,0x87,0xe8,0x13,0x1e,0x7a,0xab,0x98,0x79 +.byte 0xd2,0xd6,0x0b,0x1d,0x2a,0x9c,0xe4,0x09,0x82,0x75,0x0b,0x45,0xa1,0xf2,0xa9,0x01,0x51,0x71,0x32,0xf6,0x23,0xaf,0xd4,0xe6,0x69,0xf1,0x08,0x0f,0x68,0x1c,0x47,0xe1,0x34,0xb8,0xd4,0x9a,0x98,0xb5,0x5a,0x95,0x24,0x1f,0x78,0xaa,0x51,0x63,0x95,0x61,0xc2,0xd3,0xcd,0x88,0xfb,0x8a,0x8c,0x75,0x94,0x0d,0x34,0x3f,0x7e,0xb0,0x40,0xaf +.byte 0x45,0x65,0xe4,0x70,0xb9,0x86,0xf2,0x5d,0x4b,0x96,0xa4,0x0c,0x33,0xe0,0x6a,0x54,0x3a,0x21,0xae,0xd2,0x66,0x12,0x96,0x15,0x22,0xbb,0x08,0x3e,0xcf,0xd7,0x55,0x82,0x33,0x0a,0x6c,0x82,0xa1,0x2c,0x0d,0x08,0x96,0x7a,0xc4,0xc0,0x46,0x32,0x28,0xf3,0x59,0xbf,0xc7,0xfd,0x47,0xe7,0xc7,0x11,0x97,0x2b,0xa3,0xdf,0x44,0x30,0xe8,0x26 +.byte 0xa4,0xfe,0x90,0x21,0x31,0xb6,0xed,0xe0,0x39,0x1f,0xfb,0x0b,0x94,0x00,0x2c,0x30,0x80,0x89,0xde,0x36,0x8c,0x73,0x7b,0x96,0x03,0x27,0xe0,0x99,0x37,0x63,0xc6,0xc5,0x49,0xa9,0xe9,0xca,0x88,0x3e,0xcb,0x87,0x23,0x84,0xa5,0xc8,0xa7,0xf4,0x1c,0x45,0xae,0x63,0xf8,0xca,0x58,0x4e,0x5b,0xa1,0x02,0x9a,0xd5,0xc1,0xb4,0xa7,0x2f,0xe4 +.byte 0xab,0x54,0x3e,0x50,0x7d,0xcb,0x40,0x5d,0x13,0x8d,0x06,0xdf,0x1a,0xe9,0x35,0x32,0xac,0xa9,0x66,0x75,0x32,0x9b,0x4b,0x61,0x5d,0x3d,0x0a,0x8c,0xfe,0xfb,0x5f,0xc8,0xc0,0xcd,0xa8,0x81,0xd0,0xfb,0x45,0xb7,0x7b,0x86,0x58,0xb0,0x3d,0x77,0x27,0x76,0x1b,0x10,0x5f,0x8d,0xe0,0x54,0x89,0xab,0x51,0x41,0x11,0x9a,0x7b,0xe5,0xa5,0xee +.byte 0xa7,0xfe,0x31,0x63,0xf9,0x66,0xf6,0x83,0x20,0x2c,0xe9,0x25,0x2e,0x75,0xff,0x9e,0x1b,0x81,0xe0,0xdc,0x55,0xa2,0x34,0x9c,0xaa,0x1c,0x6e,0xfc,0x98,0x10,0x99,0xce,0x31,0xe1,0x5f,0xb6,0x0b,0xab,0xa4,0x7c,0xd0,0x48,0xfd,0xd1,0xd6,0xf3,0x6a,0x4c,0xfc,0xba,0x4a,0x70,0x19,0xe1,0x5a,0x9b,0x1d,0x93,0xf5,0x8f,0x32,0x83,0xbc,0x04 +.byte 0xe0,0x25,0xf8,0x41,0x16,0x10,0x88,0x30,0xa9,0x7a,0x47,0x40,0xad,0x88,0x43,0x20,0xe0,0x21,0x81,0xfb,0xbe,0xff,0xd2,0xad,0x37,0x9f,0xf7,0x5c,0xfb,0x89,0x46,0xc0,0x48,0xde,0x0a,0x06,0x94,0xec,0x2d,0xce,0x60,0xf0,0x58,0x62,0x55,0xf9,0x4b,0x61,0xff,0xc9,0x75,0x90,0x38,0x13,0x72,0xb4,0xd4,0x84,0x93,0x0b,0xff,0xfd,0x4d,0xbf +.byte 0xce,0x5c,0xac,0x31,0x78,0x1d,0x19,0x3e,0xf1,0xcc,0x28,0x14,0x40,0x19,0x0f,0x5f,0x77,0x13,0x11,0xa1,0x96,0x3a,0xe5,0xb6,0xec,0x4f,0x12,0x98,0x81,0x11,0x9e,0x8c,0xd5,0xa3,0xb6,0xa1,0x62,0x63,0x02,0x28,0xec,0x3c,0x4a,0x65,0x69,0xab,0xd6,0xc3,0xcf,0x73,0xa6,0xaa,0x9e,0xa1,0xb9,0x70,0x61,0xfe,0xd3,0x48,0x9f,0xe3,0xc2,0x8f +.byte 0x76,0x91,0xc1,0x7c,0xef,0x2e,0x3a,0x35,0x35,0xe4,0x6a,0x4c,0x94,0x11,0x92,0x72,0xde,0x7c,0xaa,0x76,0xa4,0x59,0x31,0xd7,0x83,0x12,0x67,0x45,0x0a,0x78,0xe5,0x90,0x06,0x4e,0x73,0x04,0x57,0x53,0x9b,0xa2,0x01,0x7c,0x54,0xfb,0xfe,0xb7,0xd2,0x46,0x3a,0x7f,0xc7,0x38,0xb2,0x94,0xcb,0x37,0x3a,0xd8,0x29,0x3b,0x02,0xfa,0x29,0xd7 +.byte 0x68,0xed,0x3a,0x8e,0x6e,0x28,0x6d,0x93,0x2d,0x72,0xd2,0xb0,0xf9,0x8c,0x55,0xf6,0x2e,0x87,0x2c,0xce,0x7d,0x8f,0xe5,0x45,0xf5,0x88,0x03,0x19,0xc4,0x1c,0x93,0x0a,0x92,0x60,0x02,0xf8,0x1b,0xc5,0xba,0xf3,0x01,0x55,0xfd,0xd3,0xc1,0xe0,0xb7,0x23,0x7e,0x06,0xb5,0xe2,0x2c,0xbb,0x09,0xba,0xc3,0x03,0xf9,0xa1,0xd1,0x84,0xfe,0xd0 +.byte 0xf6,0xac,0x99,0xff,0x08,0xe7,0x49,0x35,0x3a,0x06,0x33,0x15,0x2f,0xf6,0x4a,0xce,0xfe,0x4c,0xc4,0x8f,0x76,0xbf,0x86,0x49,0x3e,0xb0,0x93,0xa7,0x25,0xa3,0xc8,0x7b,0xfb,0x55,0x12,0x0c,0x36,0x93,0x3b,0x3d,0x04,0xd2,0xc3,0x85,0xb8,0xa5,0xa3,0x62,0x1e,0x74,0x1a,0xcb,0x81,0x89,0x38,0x59,0x06,0x8f,0x4a,0x71,0xd0,0x80,0xda,0x02 +.byte 0xaa,0xdb,0x88,0xc8,0xf3,0x33,0x52,0x30,0x29,0x15,0xd9,0xfb,0x19,0x9e,0x4e,0xcd,0x9c,0x7c,0x43,0x42,0xe1,0x24,0x37,0x55,0x75,0x5a,0x0a,0x64,0xf8,0x8b,0x9f,0x45,0x89,0x61,0x0a,0xc1,0xc8,0x3a,0x92,0x59,0x2c,0x9e,0xdc,0x69,0xe1,0xad,0xe0,0x67,0xd5,0x64,0x82,0x8c,0x76,0xf4,0x9c,0x57,0x06,0xe4,0xa9,0x05,0xb2,0xab,0x6d,0x20 +.byte 0x35,0x3d,0x85,0xf2,0x83,0xb6,0xc7,0xa8,0xb6,0xc2,0xc1,0x04,0xe9,0x56,0xde,0xb8,0x29,0xf9,0x4e,0x1f,0x7e,0xbe,0xbb,0xa2,0x07,0x7a,0xdd,0xfc,0xe5,0xf9,0x4a,0xfc,0x85,0x4b,0x94,0x84,0x22,0x1f,0x18,0xbc,0x61,0xb3,0x2d,0x4f,0xd8,0x64,0x9c,0x6e,0x07,0x35,0x0a,0x90,0xf8,0x54,0xf1,0x51,0x5f,0xa1,0xc0,0x0c,0x2b,0xfb,0x27,0x07 +.byte 0x9a,0x85,0x29,0x3e,0x9a,0x1c,0x6b,0xbb,0xd9,0x13,0x70,0x27,0x92,0xb4,0x17,0xba,0x27,0x7e,0x2a,0xfe,0xaf,0x4b,0x47,0x5f,0x78,0x03,0xe4,0xba,0x6f,0xb4,0xaf,0xe2,0x3a,0xc8,0xc8,0xd0,0x5c,0x5b,0x6e,0x1a,0xf1,0x55,0xb8,0x7a,0x82,0xf5,0x38,0x3f,0xda,0x29,0xa2,0xce,0xf0,0xe8,0x1f,0x61,0xf1,0x3a,0x1a,0x3c,0x2f,0x2f,0xeb,0xe3 +.byte 0x04,0x2e,0x88,0x4d,0x57,0x58,0xeb,0xa9,0xd2,0xb0,0x2c,0x99,0xfe,0x13,0xc0,0x0b,0x89,0xbb,0xaa,0x6d,0x45,0x76,0xf2,0xe3,0xea,0x9e,0x3d,0xed,0x4d,0x8e,0x99,0x41,0x55,0xc1,0xae,0xbb,0xd9,0x55,0xe8,0x64,0x5d,0x2e,0x53,0xd1,0x86,0x4c,0x67,0x4d,0xbc,0xa1,0xb5,0xaf,0x17,0xb7,0x4b,0x3a,0x26,0xb2,0xec,0x7b,0x6d,0x5b,0x64,0xb7 +.byte 0xaa,0xf2,0x93,0xfb,0x87,0x6c,0x4b,0x37,0x45,0x68,0x9e,0xc9,0x99,0xa1,0x73,0x6a,0xa9,0x3d,0xa4,0xb0,0x89,0x98,0x61,0xbf,0x0b,0xa0,0x23,0xdb,0xed,0x12,0xe2,0x38,0x83,0x52,0xa4,0x3f,0xc0,0x23,0xe7,0xf3,0x9f,0xf6,0x81,0x2e,0x41,0x54,0xec,0x77,0xcc,0x36,0xb0,0x35,0x3a,0x2f,0x74,0x42,0x93,0x08,0xa6,0x3a,0xaa,0x76,0x7a,0x4f +.byte 0xe5,0x12,0x8f,0x8e,0xb5,0x93,0x56,0x7e,0xd1,0x8d,0x68,0x13,0x50,0x63,0xd6,0x43,0xb0,0xc0,0xd1,0x0d,0x64,0xbd,0x69,0x99,0x9c,0xf7,0x4e,0x83,0xff,0x9b,0x3c,0x88,0x65,0x0a,0x55,0xa7,0xf9,0x39,0xbb,0x6a,0x10,0xa2,0x9e,0x13,0xc8,0x5b,0xd5,0x4e,0xc2,0x27,0x7c,0xba,0xd2,0x99,0xde,0xaa,0x6f,0xc5,0xda,0x4b,0x6c,0x53,0x1d,0xe8 +.byte 0xa9,0xa4,0xd6,0xad,0x94,0x9f,0x3b,0x0a,0x21,0xe0,0xf3,0xc2,0x96,0x63,0x4a,0x37,0x17,0x24,0x31,0x01,0x59,0x90,0xce,0x5e,0xed,0x06,0x22,0x80,0x67,0x73,0xcd,0xd4,0xcc,0x85,0x20,0x95,0x97,0xfe,0x99,0xd4,0x93,0x17,0x3d,0x15,0x15,0x4e,0x89,0x7c,0x6a,0x7b,0x2b,0xc4,0x8e,0x34,0xaa,0xf8,0x27,0xf6,0x0b,0xd5,0x64,0x21,0x96,0x37 +.byte 0x04,0xd9,0x01,0x13,0x6d,0xd6,0x2d,0x5b,0xef,0xc1,0xac,0x5f,0x96,0xdb,0x14,0x0f,0x1e,0xc7,0x2a,0x96,0x32,0x07,0xd3,0x98,0x5a,0xab,0x75,0xda,0x4f,0x13,0xf0,0x7f,0xf5,0x4e,0xe1,0x6c,0x1f,0x0e,0xe8,0x5b,0x04,0x64,0x50,0x1f,0x18,0xf9,0x72,0x25,0x5e,0x95,0xa5,0x22,0x13,0xd6,0x21,0xeb,0xbe,0xfa,0x5c,0xb3,0x2a,0x0d,0x54,0xa2 +.byte 0x0b,0x99,0xb5,0xa4,0xf4,0x5d,0x57,0x71,0x35,0x03,0xf5,0x1d,0x64,0x12,0xe4,0xba,0x2a,0x1d,0xd7,0x10,0xf1,0x5e,0xb5,0xc4,0x48,0x66,0x23,0xc4,0xcc,0x29,0x7f,0x18,0x70,0x8b,0xaa,0xb2,0xf0,0xe0,0x2b,0x8c,0xd1,0x07,0x49,0x1f,0x6e,0xd0,0x97,0xcb,0xe1,0x0e,0x3f,0x87,0xad,0x11,0xbe,0x09,0x14,0x47,0x3a,0xbe,0x5e,0xe5,0xcd,0x9c +.byte 0x7e,0xa7,0xd7,0x2d,0xf9,0xf1,0xd1,0xa1,0xde,0x3b,0xf4,0xa6,0x9f,0x90,0xe5,0x61,0x65,0x9f,0xa1,0x1c,0x89,0xbe,0xae,0xd9,0x03,0xc4,0x96,0x15,0x43,0x80,0xbb,0x9a,0xaa,0x57,0x34,0xa9,0x66,0x1f,0xef,0xc7,0x70,0xe1,0xd4,0x35,0x71,0xaf,0x8c,0x23,0x01,0xf5,0x7e,0x63,0x84,0x8f,0xc0,0x8b,0x28,0xf7,0xbc,0x2f,0x07,0x65,0x80,0x4c +.byte 0x84,0xbc,0x4c,0x95,0x5f,0xf9,0x08,0xc3,0x03,0xf3,0x31,0x35,0x4a,0x66,0xea,0x49,0x95,0xe4,0xce,0xcc,0x9c,0x9e,0x3f,0xf6,0x24,0x23,0xa5,0xf7,0xb0,0x4a,0x20,0x81,0xe5,0xc4,0xf0,0xe8,0xae,0xea,0xbf,0xcc,0x50,0xa2,0x9b,0xfe,0x97,0xfe,0x6b,0x1b,0xe0,0x56,0x90,0x0b,0x0e,0x47,0x6b,0x92,0x2e,0x49,0xed,0x99,0x1b,0x3d,0x42,0x3d +.byte 0x3e,0xf6,0x7d,0x6d,0x6c,0xc4,0xc6,0xae,0xa6,0x98,0xfd,0xeb,0xa5,0x57,0x05,0x00,0x44,0xbb,0xf3,0xa3,0x00,0x29,0x3d,0xcd,0x45,0xc1,0xa8,0x7d,0x34,0xaf,0x8b,0x53,0x49,0x5f,0x42,0x6e,0xcd,0x51,0x67,0x3d,0x75,0x82,0x17,0x65,0x1d,0x13,0xef,0x2d,0xc3,0xf2,0x87,0xbf,0x95,0x43,0x05,0xfb,0x3c,0x35,0xd7,0xbb,0x35,0x7f,0xbe,0x13 +.byte 0x10,0x06,0xdd,0x17,0xe7,0x39,0xa1,0x8f,0x8f,0xf2,0xba,0xe2,0x27,0x83,0x6e,0x86,0x01,0x8c,0x04,0xa3,0xc8,0x6e,0xf9,0x51,0x3f,0xf2,0x36,0xe6,0x0a,0x48,0xf3,0x72,0x56,0xb7,0xd7,0x8f,0x43,0x17,0x60,0x9b,0xaf,0xcf,0x74,0x43,0xc9,0x27,0x40,0x10,0x28,0x13,0x04,0x6a,0xb3,0xa4,0xf8,0x41,0xfe,0xd5,0xd2,0xcd,0xe7,0x12,0x1d,0x82 +.byte 0x91,0x6d,0x3e,0xce,0x30,0x74,0x39,0x2b,0xbb,0xed,0x46,0x3d,0x0b,0x98,0x6f,0x76,0x20,0x01,0xc0,0x50,0x25,0xa2,0x02,0x7b,0xbc,0x31,0x2b,0x2b,0xb5,0xd4,0xad,0x38,0xe2,0x20,0xdb,0x4d,0x8e,0x1e,0x21,0x3d,0x80,0x1b,0x77,0xc0,0x7d,0xfd,0x88,0xac,0x85,0xed,0xc9,0xfd,0xf0,0xa2,0x60,0xcd,0xc6,0x35,0x88,0x5d,0x22,0xfa,0x7f,0x0c +.byte 0xad,0x67,0xee,0xdf,0xd8,0xce,0x10,0x1e,0xb3,0x6f,0xe7,0xe0,0x5c,0x56,0xae,0x08,0xd1,0x65,0x68,0xc1,0xfd,0x17,0xaf,0xc0,0x89,0x77,0xb1,0x12,0x78,0x4e,0xb3,0x39,0x4a,0x95,0x74,0xcb,0x72,0xd9,0xee,0x0b,0x30,0x8f,0x02,0xb4,0x7f,0x15,0x9a,0x13,0x3f,0x02,0x1c,0xb0,0x80,0xaa,0xb0,0xa1,0x14,0x1a,0x93,0x69,0xde,0x83,0x89,0xa1 +.byte 0x83,0x48,0x27,0x5a,0x22,0xb8,0xd1,0xf6,0x25,0x81,0xb0,0xe9,0xb6,0x3f,0x17,0xa1,0xe1,0x37,0x46,0x6b,0xa5,0x5f,0x85,0xcc,0x39,0x19,0x45,0xe1,0x95,0x21,0xe9,0x5b,0x09,0xa6,0x9a,0xe0,0x11,0xed,0x10,0x20,0x40,0xb3,0xfd,0xd0,0x48,0x3a,0x9f,0x85,0x92,0x37,0x12,0xa8,0x44,0xa7,0x22,0x45,0x1c,0x57,0xe4,0x36,0x79,0xe0,0x08,0xd8 +.byte 0x40,0xa2,0x66,0x7b,0x2d,0xe7,0xb1,0x56,0x62,0xd6,0xaa,0x33,0xdd,0xbd,0x74,0x3f,0x26,0x04,0x0d,0xc1,0x45,0xf4,0xaa,0x70,0xbb,0x8a,0x24,0x4a,0x60,0x01,0x5b,0xc2,0x79,0xb1,0x0e,0x24,0x46,0x4b,0x15,0x02,0xda,0x9a,0x24,0x0e,0x1d,0xa1,0xb4,0xa3,0xc1,0x31,0xfb,0x3d,0x7b,0x69,0xd2,0x22,0x52,0x37,0x9f,0xc0,0xb8,0xd4,0x36,0x01 +.byte 0xe7,0xe2,0x99,0x93,0xec,0x96,0x0d,0x8c,0xbe,0xa9,0x92,0xa0,0x25,0xe3,0x66,0x26,0x2e,0xae,0x44,0xbf,0x9e,0xa0,0x20,0x97,0x41,0x2f,0x19,0x80,0xbc,0x78,0x19,0x8e,0x08,0xea,0x55,0x7f,0x88,0x74,0x4a,0x78,0xfb,0x6b,0x33,0x51,0x54,0xb4,0xa3,0x82,0x3b,0xa6,0xa7,0x5a,0x6d,0x01,0xa7,0x59,0x2f,0xf1,0xba,0x35,0x8e,0xbd,0xe4,0xb4 +.byte 0xc3,0x37,0xc7,0x1c,0xcf,0x5b,0x26,0x02,0x2d,0x64,0xe5,0xb4,0x61,0xea,0x56,0xcf,0x6a,0x53,0x7a,0x1b,0x8c,0xc7,0x4f,0x32,0x6d,0x57,0xd9,0xde,0xf1,0xd3,0x8f,0x95,0x52,0xc6,0xab,0x43,0xc3,0x57,0x3e,0x04,0xb3,0xf9,0x0c,0x66,0x82,0xf4,0x19,0xa5,0xd4,0xc5,0x3a,0xc1,0xe0,0x00,0x11,0x36,0x51,0x38,0x97,0x3a,0x62,0x10,0xd5,0x81 +.byte 0xec,0x16,0x34,0xd5,0xff,0x8a,0x01,0xb1,0x25,0x44,0xf6,0xcb,0xda,0x2d,0xbd,0x42,0xb5,0xd1,0x8a,0xf4,0xab,0xe4,0xae,0x18,0x72,0x66,0x93,0xef,0xfa,0x8d,0xdb,0x43,0x46,0xb3,0x68,0xa0,0x15,0x93,0xce,0x33,0xa9,0x29,0x12,0xf0,0x69,0x74,0x34,0x6a,0xea,0xfc,0x05,0x35,0x7a,0x0e,0xfe,0x89,0x73,0xb8,0x47,0x5b,0x6c,0x1b,0xd2,0x41 +.byte 0xaf,0xca,0xcd,0x67,0x00,0x44,0xf6,0xc9,0xcf,0x80,0x73,0xda,0x90,0x41,0xd1,0x35,0x75,0x67,0xfe,0x30,0x61,0x8f,0xa7,0x88,0x7f,0x1b,0x39,0x3d,0x41,0x41,0x8d,0xf8,0x04,0x0b,0x8c,0x25,0x2b,0xb6,0xd5,0xe3,0xb9,0xeb,0xd9,0xb1,0x99,0x0c,0x45,0x12,0x9f,0x19,0xce,0xc3,0xd6,0x02,0x3e,0x4c,0xdf,0xf9,0x61,0x41,0x50,0x7b,0x38,0x7e +.byte 0x40,0x43,0x90,0x2a,0xb0,0x2e,0x16,0x33,0x32,0xa2,0x34,0xb8,0xc5,0x76,0xdc,0xda,0x71,0x07,0x45,0x9b,0x1f,0x6b,0xd7,0x92,0x69,0x04,0x02,0xa2,0x50,0x55,0xd3,0x96,0x10,0xaa,0x22,0x1e,0xb7,0x6a,0x84,0x8b,0xc6,0x7a,0xdb,0xe5,0xc6,0x25,0x9a,0x7b,0xa4,0x3a,0x06,0xc9,0x2f,0x95,0xb2,0x9b,0xac,0xfc,0xbb,0xb2,0x9a,0x39,0x84,0x6d +.byte 0xce,0x56,0x62,0x34,0x61,0x48,0x34,0x31,0x6b,0x29,0xaa,0x5c,0xdd,0x52,0xae,0x8e,0x9f,0x36,0x3b,0xec,0xd9,0xc2,0x3d,0x13,0x61,0xc7,0x74,0x58,0xf9,0x2b,0x87,0x05,0x07,0x3c,0xd7,0x37,0x7f,0x59,0x54,0x32,0x95,0x19,0xc8,0x38,0x69,0x6e,0xc9,0x88,0x77,0x65,0x20,0x2c,0xf4,0xaf,0x57,0xc1,0x7d,0xe2,0xb4,0xdc,0x4e,0x74,0x77,0x92 +.byte 0x83,0xee,0x4a,0x7d,0x74,0x6f,0x19,0x74,0x8f,0xb5,0x76,0x5d,0x79,0x4a,0x16,0xb9,0xaf,0x2a,0x2d,0xd9,0xeb,0xd2,0xad,0x70,0x37,0x5d,0xff,0x96,0xfc,0xe2,0x9c,0xed,0x45,0x4f,0x56,0x59,0x9a,0xdb,0x81,0x3f,0x3f,0xc3,0x47,0x81,0x46,0x7d,0x14,0xdd,0x45,0xee,0x50,0x25,0xae,0xd4,0x61,0x8e,0x4d,0x58,0x35,0xf5,0x62,0xc0,0xa8,0x25 +.byte 0xb1,0xf1,0xd4,0x86,0xd5,0x67,0x8d,0x50,0xfc,0xfb,0x8d,0x18,0x82,0xc9,0x34,0xbe,0xe0,0x0b,0x6a,0xcb,0x2f,0xf0,0xd1,0x32,0x40,0x35,0xf9,0x4c,0xa8,0xd2,0x92,0x53,0x90,0xc1,0x44,0xb4,0x59,0xb2,0x8c,0xc7,0xb9,0xb7,0x5d,0xf9,0xa0,0x9b,0x8c,0xcd,0x32,0x36,0x72,0xce,0xa8,0x49,0xbe,0xba,0x46,0x5e,0x43,0xa0,0xd5,0xf3,0x81,0xa5 +.byte 0xbe,0xf4,0x37,0x22,0x27,0x5e,0x56,0x52,0x00,0x1b,0x79,0xf8,0x17,0xa5,0x61,0x92,0x7a,0xfb,0x0d,0xf9,0xaf,0x4a,0x9c,0x7c,0x09,0xda,0xab,0xda,0x8a,0xdb,0x6a,0x25,0xcc,0x60,0x79,0x48,0x11,0x3f,0xd9,0x0d,0x30,0x4b,0xaf,0xa3,0x48,0xb9,0x80,0x9b,0x43,0x94,0x1a,0x2d,0xdf,0x1d,0x74,0x1c,0x17,0x9f,0xbb,0x52,0xbc,0x9c,0x2f,0xaa +.byte 0x7a,0x0a,0x8d,0xc9,0x2c,0xbb,0x33,0xf0,0xc2,0x25,0x34,0x9d,0x1a,0x5c,0x11,0x38,0x95,0xeb,0x65,0xce,0x85,0xe6,0xa8,0xd1,0x20,0x7c,0x8f,0xd3,0xb6,0x42,0xb9,0x97,0x4f,0x94,0xc6,0xfe,0xcc,0x8b,0x90,0x9a,0x18,0x46,0xdb,0xdc,0x2e,0x45,0xd5,0xe4,0x11,0xb6,0xb0,0x9b,0xf6,0x0b,0x53,0x0e,0x44,0xf5,0x33,0x9a,0xdc,0xd3,0x36,0x52 +.byte 0x3f,0xe3,0x3e,0x3a,0xfc,0x6b,0xaf,0x31,0xf8,0x21,0x19,0x54,0x68,0x5e,0x37,0x95,0x9f,0xba,0x83,0x8c,0x53,0xa3,0xda,0x26,0x48,0x2a,0x4a,0xe0,0x73,0x82,0x51,0x68,0x1c,0x60,0x5e,0x3d,0x95,0x61,0x2b,0xb7,0x94,0x7a,0x94,0x03,0x50,0x4e,0xa2,0x3e,0xa7,0xc8,0x29,0x79,0x3a,0x12,0x82,0x71,0x7e,0x3c,0x35,0xed,0x24,0x9f,0x90,0xb1 +.byte 0x04,0xec,0x83,0xeb,0x4f,0x91,0x54,0x44,0x7c,0xb2,0x14,0x44,0xde,0x73,0x69,0x84,0x4b,0x9c,0x12,0x13,0x27,0xe8,0x1a,0x6b,0x39,0xce,0xad,0x56,0x17,0x99,0x1a,0x6c,0x54,0x21,0xe2,0x6f,0x0d,0xe6,0x2a,0xff,0x7d,0x22,0xfa,0xdf,0xa6,0x32,0xf0,0xfd,0xa7,0xa4,0xe9,0xaa,0x33,0x8e,0xd6,0x36,0x7f,0xfd,0xf8,0x13,0x7e,0xb5,0x16,0xdb +.byte 0xea,0x61,0xf3,0x18,0x36,0xfd,0xf3,0xa4,0x11,0x5d,0x93,0x86,0xfb,0xaa,0x86,0xd5,0xd6,0x24,0xfb,0x00,0x8a,0x8a,0x78,0x28,0xdf,0x8e,0x2a,0x51,0x65,0xd3,0xb2,0x6f,0x02,0xb8,0xa4,0x03,0x42,0xf5,0xf9,0x61,0x00,0x17,0x34,0x32,0x83,0x20,0x0c,0xee,0x2a,0xe7,0x04,0x65,0x52,0xe0,0x0c,0xaf,0x77,0xa7,0x72,0x44,0xa8,0xb1,0x85,0x73 +.byte 0x9f,0x8b,0x99,0x10,0xf9,0x5b,0x68,0xfc,0xe6,0xae,0xdb,0x65,0x99,0x09,0x01,0x4a,0x80,0xd6,0xe2,0xd6,0x86,0xb1,0xf0,0x5f,0xb3,0x12,0xf4,0xdd,0x53,0x0d,0x9c,0x61,0x6d,0x8a,0x68,0xca,0x36,0x65,0xf0,0x7d,0x71,0xa3,0x62,0xd6,0x15,0x73,0x5b,0x8b,0x84,0x29,0x1f,0xde,0x24,0x22,0x4f,0xe3,0xd3,0xee,0x68,0xb4,0xf0,0x0c,0xa8,0x33 +.byte 0xde,0x82,0x74,0x9b,0x65,0x7d,0x96,0xce,0x52,0x2f,0x41,0xe2,0xa9,0x2a,0x62,0xd1,0x2a,0xf4,0x52,0xa0,0xbc,0x0d,0x88,0xd4,0xbe,0x0d,0x7b,0x2d,0xf0,0x3c,0xc9,0x76,0x69,0x44,0x88,0x4f,0x75,0x73,0x77,0xd8,0xec,0x7d,0x01,0x95,0xab,0x2f,0x29,0x99,0xb8,0xdb,0xa3,0xf0,0xea,0x57,0x2b,0x91,0xf9,0x6c,0x4d,0x59,0xae,0x09,0x52,0x08 +.byte 0x89,0xa2,0x32,0x2b,0x7e,0xca,0xae,0x30,0x8e,0xa5,0x66,0x88,0x79,0x9e,0xb3,0xd4,0xe2,0xe2,0x0e,0x5d,0xf6,0x17,0x66,0x77,0x09,0x84,0xf3,0x00,0x59,0xfb,0xfc,0x5c,0xb0,0x0f,0x2f,0xa7,0x5a,0xbd,0xf7,0x7e,0x74,0xd1,0x86,0x9d,0x9c,0x7f,0x00,0x16,0xa1,0x2b,0x90,0xe7,0x3e,0x94,0xab,0x7e,0xf5,0x18,0x1c,0x77,0x8e,0xf8,0x4d,0x43 +.byte 0x6b,0xfd,0xa8,0x26,0xbb,0xb2,0x05,0x01,0xa2,0x95,0xcc,0x9a,0x54,0xad,0x5e,0xa2,0xc2,0xa8,0x82,0x5b,0x43,0xef,0xbf,0x87,0x61,0xcb,0x21,0x12,0x56,0xef,0x55,0x09,0xeb,0x22,0x49,0xf8,0x13,0x8d,0x1a,0x84,0x0c,0xf6,0xeb,0xbc,0xf3,0x09,0x5c,0xe7,0x61,0xcf,0xb4,0x84,0x8d,0x95,0x6f,0xa8,0x10,0xc7,0x99,0xd5,0x21,0x59,0x7e,0xe9 +.byte 0xd2,0x05,0xf6,0xab,0x40,0xe5,0x5b,0xb1,0xe1,0x64,0xdb,0x38,0x1e,0x9e,0xe2,0x0c,0xd7,0xe5,0xa2,0xe4,0x51,0x4b,0xff,0x8b,0x10,0x79,0x21,0xaf,0xa9,0xdd,0x40,0x43,0x56,0x57,0x01,0xa3,0xe0,0x40,0x94,0xe5,0x85,0x6c,0xa5,0x93,0x0f,0x28,0x97,0xaa,0x82,0x3c,0x01,0x77,0x1e,0x18,0x6c,0xdd,0xff,0x32,0x23,0x7b,0x0b,0x9c,0x95,0x66 +.byte 0x62,0xb8,0xa0,0x94,0xcb,0x0e,0xdc,0xed,0xb1,0x44,0x1f,0xa8,0xcd,0x1f,0xf7,0xb7,0x41,0x7b,0x0c,0x96,0x08,0x75,0x98,0xd2,0x6e,0xb4,0x8a,0x24,0xf1,0x21,0x18,0x0c,0x2b,0x9f,0xef,0xd9,0x7b,0x3a,0x46,0x05,0xac,0xe4,0x5f,0xad,0x1d,0x2d,0xd0,0x34,0x83,0xfb,0x2c,0xd9,0xaa,0x59,0x86,0x6d,0x06,0x07,0x2e,0x2d,0x61,0x78,0x85,0xba +.byte 0x7d,0x50,0xde,0x4f,0x55,0x83,0x4d,0xdf,0xfb,0x56,0x81,0xa7,0xf1,0x63,0x97,0xd0,0xf2,0x69,0x7d,0x14,0xf3,0x7b,0xc2,0xf5,0xcf,0x44,0x39,0x9e,0x3b,0x1c,0x65,0x09,0xfb,0xdb,0xa6,0xb8,0xe4,0x20,0xc5,0x21,0xc8,0xe7,0x51,0xe8,0xf9,0xd7,0x29,0xf8,0xee,0xfd,0xbd,0xff,0x15,0x91,0x7c,0x92,0xcd,0x89,0xe9,0x9e,0xde,0x24,0xdc,0x67 +.byte 0xcf,0x51,0x94,0xff,0xb0,0x21,0x30,0x8c,0xea,0x38,0x08,0xf8,0x02,0x31,0x5d,0x57,0x99,0x15,0x2f,0xf2,0xd5,0x7e,0xe5,0x87,0x5a,0xfa,0xee,0xa2,0x34,0x2e,0x24,0xcd,0x53,0xe7,0x89,0x51,0x9b,0x1c,0x88,0xd6,0x3c,0x12,0xe4,0xe0,0xf7,0xb6,0x39,0x3b,0x26,0x9a,0x0d,0xb7,0xfc,0x5e,0x74,0x58,0x74,0x78,0x3d,0x3b,0xc8,0xc0,0xb0,0xfe +.byte 0x82,0x15,0x1e,0x38,0x75,0x1d,0x85,0xd7,0x07,0xc2,0xc4,0x79,0x73,0xef,0x67,0xf0,0x56,0xf3,0x2f,0xce,0x8c,0x58,0x98,0x64,0x2b,0x7b,0x41,0xfa,0x32,0xba,0x6e,0x1c,0xa5,0xf4,0xc0,0x66,0x26,0x85,0x6d,0x65,0x7e,0x83,0x17,0xc4,0x8a,0x82,0xe2,0xc9,0x1d,0x5e,0x06,0xc7,0xbe,0xe5,0x49,0x66,0x9d,0x7f,0x75,0xa3,0x5d,0x02,0xb7,0x23 +.byte 0xc9,0x94,0x81,0xb5,0xe6,0x0c,0xf0,0x5e,0x70,0xbb,0x69,0xf2,0xd9,0xc5,0x96,0xe2,0x35,0x6b,0xf1,0xd4,0x42,0xfb,0x0f,0xc0,0x35,0x93,0xb1,0x73,0x3d,0xeb,0xdd,0x85,0x03,0xd5,0x8d,0x41,0x35,0x6f,0xf5,0x0f,0x7b,0xe0,0x03,0xc8,0x6d,0xae,0x1f,0x5d,0x58,0xf1,0xf1,0xc8,0x97,0x3a,0x1a,0x4a,0x0e,0x23,0xa3,0x72,0x3a,0xdd,0xf3,0x9d +.byte 0xd3,0x1b,0xcd,0x5f,0xb8,0x49,0x07,0x2d,0x49,0xc1,0xbb,0x40,0x32,0x86,0x00,0xe8,0x95,0xa0,0x34,0x25,0x1f,0xac,0x30,0x4e,0x41,0xde,0x6d,0x94,0xb6,0xb0,0xf9,0x9f,0x3a,0x12,0xf9,0x80,0xc4,0xf7,0x57,0x3d,0x53,0x38,0x0c,0x7f,0x80,0xfb,0xdd,0x5b,0x7c,0xe4,0x6f,0x47,0x30,0x16,0x56,0x37,0x01,0x49,0x9c,0xd9,0x89,0x34,0xa1,0x29 +.byte 0x20,0x57,0xb5,0x7c,0xbd,0xcc,0x90,0xec,0xb2,0xcc,0x39,0xad,0xc2,0xbe,0x06,0xd0,0x60,0x30,0xc0,0xe9,0x4c,0x7d,0x30,0x86,0x53,0x80,0x8b,0x35,0x70,0x2c,0x35,0x3d,0xb2,0x3a,0x9a,0xca,0x69,0x40,0x11,0x71,0x75,0x4b,0x68,0x5b,0x9c,0x03,0x48,0x4c,0x9c,0x68,0xce,0xe7,0x5a,0x65,0x98,0xed,0xa1,0xe5,0x20,0xe4,0x0f,0x54,0x0c,0x0e +.byte 0x50,0x97,0xa3,0xf2,0x67,0x97,0xea,0x74,0x93,0x73,0x82,0x60,0xa4,0x29,0xb6,0xa3,0x9d,0xc1,0x2f,0x31,0x30,0xb9,0x1f,0xfd,0xc3,0x4f,0xbe,0xa1,0xb1,0xc4,0xbc,0x88,0x78,0x27,0x85,0xb1,0xa1,0x91,0x3e,0x61,0x3b,0xd5,0x0f,0x8d,0x28,0x80,0xf1,0x4b,0x8e,0xdf,0x34,0x22,0x45,0x6b,0x62,0xb8,0xac,0xd9,0xe3,0xff,0xce,0xfc,0x2e,0x34 +.byte 0x81,0x70,0xc1,0xb8,0x51,0xa2,0xa2,0x1a,0x7a,0xbc,0xf0,0x56,0x12,0x7a,0xf4,0x3b,0x34,0xc7,0xcf,0x63,0x66,0xc9,0x36,0x77,0x52,0xfd,0xc5,0x87,0xa6,0x97,0x9a,0x39,0x7f,0x4c,0xdf,0x0d,0xfe,0x8f,0x57,0xbe,0x75,0x6b,0x79,0x86,0x57,0x40,0x88,0x7e,0x63,0xb6,0xe9,0x1a,0x07,0xa4,0xa0,0x15,0xee,0xb4,0xb6,0x18,0x23,0x7b,0x9f,0x2f +.byte 0xba,0x2c,0x8c,0x7f,0x7b,0xbf,0xab,0x21,0x5b,0x45,0xc7,0x61,0xd2,0xa5,0x0b,0x13,0x1a,0x63,0x6a,0x69,0x4f,0x06,0x78,0x22,0xe6,0x98,0xbc,0xaa,0xd1,0x67,0xc5,0x2c,0x05,0x38,0x57,0xfb,0x28,0xfd,0x09,0x29,0x02,0x12,0x0c,0xab,0x2a,0xd8,0xf1,0x6c,0x9d,0xdf,0x9c,0x76,0x4b,0xf8,0x18,0x80,0xa3,0xfc,0xbb,0x82,0xe2,0xb5,0x1d,0xcf +.byte 0x23,0xf9,0xe1,0x6d,0x97,0xe9,0x4d,0xfe,0xe7,0x8c,0x2f,0x05,0x1d,0x03,0xaf,0xcd,0x00,0x2c,0xe0,0xec,0x2a,0xa8,0x36,0x96,0xaf,0x5c,0xe3,0x70,0x37,0x2c,0xa5,0xf1,0x4e,0x3c,0x98,0x0f,0xcb,0xea,0x9b,0x2d,0xdd,0x56,0xfb,0x5f,0xa8,0xf5,0x92,0x4f,0x35,0x5b,0x1f,0x80,0xb5,0x86,0x05,0x90,0xac,0x53,0x5f,0xc4,0x67,0x41,0x9f,0x93 +.byte 0x9d,0x9e,0xe4,0x12,0x7b,0xee,0x6d,0x77,0xe6,0x47,0xf8,0x31,0xcb,0x21,0xc1,0x2e,0xd7,0xdc,0x28,0x98,0x27,0x91,0xbe,0x91,0xfd,0x99,0xae,0x54,0x28,0xfc,0x84,0x13,0xe7,0x8a,0xf0,0xc9,0xd8,0xd6,0xa5,0xfa,0x57,0x7a,0x84,0xee,0xf1,0xb1,0x90,0x19,0xc5,0x43,0x6b,0x35,0x48,0xd9,0xfe,0x49,0xdf,0xf9,0xc8,0x27,0xfb,0xea,0x08,0x60 +.byte 0xe2,0x38,0xca,0xc7,0x8e,0xc4,0x8c,0xc0,0x9c,0xf9,0x1e,0xa6,0xea,0xda,0x0f,0x61,0xdb,0x45,0x81,0xd1,0xed,0x07,0x61,0x2d,0x43,0x54,0x56,0xc4,0xbd,0x29,0x5a,0x8f,0x41,0xa3,0xc3,0x1b,0x7d,0x52,0xab,0x2b,0x5f,0xa3,0xff,0x9a,0xb0,0x9d,0xb2,0x18,0xdc,0x61,0xea,0x4c,0x25,0xd6,0xe5,0x2d,0xc7,0xbe,0x3c,0x0b,0x15,0xa9,0x46,0x07 +.byte 0x36,0x92,0x9e,0x43,0x8f,0xf9,0x5e,0x35,0x5c,0x3f,0xfe,0xae,0x87,0x91,0xdb,0xa8,0x4a,0x05,0x2e,0x51,0xdf,0x36,0xf5,0x39,0x03,0x50,0x8a,0xc3,0xd3,0x1b,0xa4,0x1e,0xe1,0xfb,0xbc,0x53,0x3b,0xd3,0x6b,0x22,0x72,0xd0,0x5c,0x67,0x61,0xca,0x85,0x37,0x17,0xa5,0x8e,0x10,0xd1,0x58,0xb1,0x8b,0x17,0x43,0xb0,0xc6,0xc5,0xdc,0xde,0x45 +.byte 0x1f,0x18,0x25,0x72,0x89,0x36,0x09,0xa5,0xd7,0x9e,0x8b,0x11,0xce,0xbf,0x31,0xee,0xee,0x6f,0x6d,0xf9,0x94,0x23,0x17,0x11,0xc5,0x53,0xb8,0xfc,0x8f,0xf4,0xdc,0x56,0x6c,0x7d,0x4d,0x42,0x32,0x30,0xb2,0xbb,0x8d,0x69,0xf8,0xb5,0x3b,0x77,0x38,0x04,0xcf,0x49,0x4f,0xec,0x40,0x61,0xbb,0x13,0x9c,0xc4,0xcc,0x7c,0xe8,0x90,0x27,0x91 +.byte 0x9e,0x95,0xf8,0x87,0x63,0x94,0xa9,0xc5,0x78,0x78,0x38,0xa1,0xf7,0x21,0x7a,0xec,0x91,0xaf,0x2f,0x2f,0xa4,0x52,0x16,0x5f,0x7f,0x27,0xea,0xce,0xb4,0x1f,0x38,0xe4,0xd9,0xb1,0x24,0xce,0xe5,0xd2,0xd1,0x09,0x2f,0x04,0x65,0xf3,0x54,0x1c,0xac,0xad,0x3d,0x97,0x21,0x83,0x12,0x9c,0x08,0xb8,0x2b,0xd6,0x7e,0x91,0xc5,0xdf,0xa7,0x13 +.byte 0x3f,0x4b,0x60,0x52,0xb8,0x1a,0x28,0x44,0x8d,0x8a,0x41,0x6f,0x02,0xf8,0x62,0x6a,0xe4,0xad,0xcc,0x81,0x48,0x44,0x9a,0xed,0x7a,0x87,0x60,0x3a,0x65,0x10,0x49,0x7b,0x90,0x60,0xd9,0xe7,0x67,0x8d,0xff,0xef,0xdf,0x7e,0x07,0x46,0x67,0xfc,0xcd,0xbc,0xae,0x3d,0x39,0xfb,0x5f,0xf9,0x36,0x7a,0xaa,0x80,0x48,0x9d,0x6d,0x98,0x82,0xf9 +.byte 0x76,0x08,0xe6,0x5c,0x2f,0xde,0x9d,0xd2,0xb6,0x18,0x4f,0x1f,0x98,0x23,0x91,0x41,0x89,0xcd,0xfa,0x8d,0x5d,0x50,0xcb,0x6a,0x57,0xf0,0x34,0x57,0x68,0x00,0xca,0x4b,0xe4,0xc6,0x1a,0x82,0x6c,0x57,0xad,0xfb,0x37,0xc0,0x2e,0x39,0xd7,0x8e,0x6f,0x36,0x28,0x82,0x99,0x3f,0x9a,0xeb,0xdc,0x1f,0x63,0x34,0xb1,0x14,0xad,0x33,0xdd,0xfc +.byte 0x92,0x4a,0x15,0xa8,0xb8,0x48,0x3f,0x11,0xef,0x58,0x17,0xa0,0xe6,0x7b,0x54,0x44,0xaa,0x7c,0x21,0x3e,0xfc,0x23,0x98,0xbb,0x18,0x28,0x37,0x00,0x31,0xb3,0xec,0x90,0x89,0x6f,0x5c,0xaa,0x3a,0x95,0x22,0x6c,0xb7,0x73,0x6d,0x2b,0x94,0xa5,0xda,0x37,0xb7,0x5f,0x0e,0x5a,0x51,0xee,0xec,0xde,0x80,0xeb,0xd7,0x84,0x4e,0x24,0xba,0x97 +.byte 0xf0,0x8e,0x6e,0x0c,0x51,0x94,0xb4,0x9b,0x2d,0xa3,0x93,0xf1,0x73,0x96,0xd4,0xf0,0x6a,0x42,0x83,0xde,0x72,0xc9,0x12,0x42,0x2d,0xab,0x2f,0xf5,0x9c,0x21,0x6f,0x6a,0xc3,0xfd,0x01,0x18,0xba,0x3d,0xb0,0x9e,0x64,0x4b,0xab,0xfa,0x2d,0xff,0x13,0x0a,0xab,0xd4,0x4b,0xaf,0x06,0x38,0x8b,0x79,0xd3,0xa6,0x03,0x38,0xa6,0xe2,0x39,0xa9 +.byte 0x0b,0xc1,0x83,0xd6,0x56,0x72,0xcd,0x10,0x35,0xbc,0xa3,0xe6,0x8c,0xf7,0x0e,0x70,0xbf,0xb8,0x4f,0xe2,0x37,0x88,0xf3,0x79,0x79,0x12,0xa5,0x4b,0x87,0x73,0x39,0x0b,0x25,0x4b,0x56,0x47,0x38,0x6d,0x03,0xa7,0xff,0x32,0x2a,0xd2,0x03,0x2c,0xe6,0xe0,0x73,0x1b,0x7c,0xeb,0x47,0xb5,0x4e,0x65,0x6c,0xd8,0x0f,0x08,0xbf,0x98,0xbf,0x5e +.byte 0xae,0x69,0x0e,0x13,0xc6,0xfd,0x33,0x78,0x58,0xe9,0xe7,0x52,0x4c,0xb1,0x68,0x46,0x35,0x8c,0x1f,0x10,0xf5,0xeb,0x2f,0xaa,0xf3,0xdb,0x1a,0x2c,0x54,0xe1,0x3d,0x49,0x65,0x90,0x80,0xce,0x55,0x19,0xab,0xf9,0x05,0x3f,0xa8,0xf9,0x40,0x11,0x2a,0x84,0x82,0xbc,0x6f,0x95,0xad,0x66,0xff,0x6c,0xc8,0x84,0xb9,0xc7,0x74,0xa8,0xf3,0x5b +.byte 0x48,0x8d,0x6a,0xef,0xec,0x58,0x5a,0x96,0x35,0xcd,0xc8,0xbf,0x6e,0xc3,0x23,0x81,0x0b,0x5d,0x80,0x98,0x4d,0xe7,0xf5,0xb5,0x4a,0x1e,0x0a,0xfd,0x04,0xc6,0x10,0x50,0x79,0x7a,0x34,0x72,0xfa,0xaf,0x2c,0xf2,0xfd,0xfb,0xc7,0xb1,0x46,0x8a,0x0f,0xc2,0xee,0xa9,0x54,0x83,0x5b,0x84,0x20,0x88,0x74,0x98,0xcc,0x8f,0x77,0x8a,0x1a,0xf4 +.byte 0x07,0x5c,0xf2,0x1b,0x1f,0xdc,0x03,0x76,0x96,0xf7,0x98,0xc9,0xbd,0x54,0xb1,0x61,0x46,0xbb,0x07,0xab,0xce,0x83,0x90,0xd9,0x3d,0x53,0x9b,0x65,0xa2,0x89,0x29,0x7b,0x75,0x1c,0x46,0x41,0x46,0x3d,0x83,0x2f,0x1d,0x67,0x32,0x0a,0xc6,0x4a,0x6c,0x8d,0x47,0x2a,0xc7,0xb7,0xe6,0xef,0x27,0x7a,0xff,0x86,0x1f,0xcc,0x8f,0xbb,0x48,0xda +.byte 0x70,0x49,0xbf,0xdd,0xf0,0x2c,0x30,0x9a,0x63,0xf8,0x1f,0xae,0xdd,0xb3,0x1f,0x50,0x75,0x15,0xf6,0x94,0x60,0x17,0xd4,0x99,0x82,0xef,0xb1,0x19,0xef,0x9a,0x3f,0x73,0x7e,0xb2,0x30,0x47,0x8e,0x3f,0xf3,0x78,0x53,0x72,0x2b,0xb5,0x34,0xcb,0xa4,0x8f,0xf0,0x1c,0x3f,0x3d,0xde,0x77,0x40,0x0b,0x14,0xb1,0x94,0x1e,0x72,0x94,0x24,0xdd +.byte 0x3a,0x5b,0x02,0xb8,0x88,0x8f,0x28,0x29,0x3f,0x3b,0x8d,0xc2,0xff,0x0d,0x74,0x77,0x6f,0x70,0x0e,0x92,0x32,0x2c,0x62,0xe7,0x16,0xf3,0x0b,0xdd,0x58,0xd7,0x7b,0x10,0x1a,0x73,0x49,0x57,0x37,0xcc,0x69,0xd6,0xd2,0xda,0xc8,0x85,0xd8,0x64,0x62,0xae,0x21,0x11,0x75,0xb6,0x39,0xa4,0x18,0x02,0x46,0x48,0x10,0x46,0x5c,0x4a,0x86,0xd7 +.byte 0x1d,0xbe,0x0e,0x4b,0x6d,0x4e,0xe2,0xbe,0x22,0xd7,0xd5,0x3d,0x1f,0x77,0x7d,0x30,0x13,0xac,0xf4,0x38,0x93,0x85,0x55,0x47,0xaf,0xa5,0x16,0x28,0xc4,0xd0,0xb9,0x04,0xa3,0x27,0xd0,0xdf,0x1d,0x77,0xdd,0xd5,0xf6,0x8f,0x35,0x56,0x47,0xc5,0xb6,0x21,0xf8,0xea,0x5e,0xe4,0xa4,0xbc,0x20,0xc3,0x73,0x30,0xc7,0x2f,0x92,0x89,0x65,0x8b +.byte 0x6b,0x12,0xa6,0xc7,0x14,0xa8,0xd8,0xfb,0x99,0xe0,0x1d,0x95,0x90,0xd2,0x66,0xc3,0xf4,0x9b,0x03,0x59,0x2f,0x96,0xbc,0xdc,0x17,0x82,0x56,0x4e,0xf6,0xe9,0x0a,0xe1,0x25,0xb3,0xa5,0x13,0x70,0xd7,0xc8,0xd3,0x12,0x67,0xa9,0xdc,0xde,0x1c,0x3e,0x18,0x26,0x70,0x24,0xf4,0x17,0xf6,0xed,0xa0,0xb3,0xa1,0x38,0x6f,0x95,0x34,0x79,0x43 +.byte 0x7e,0xc5,0x9e,0xb7,0x48,0x13,0x5c,0x8b,0x66,0x8e,0xad,0x69,0x02,0x00,0x3c,0xb6,0x76,0x37,0x0c,0x72,0x5a,0xe9,0xc3,0x94,0xc6,0xb5,0x1a,0x51,0x9f,0xb0,0xda,0x0c,0x57,0x5d,0x8d,0x99,0x1d,0xb3,0x12,0xd8,0x87,0x2f,0xbc,0x97,0xb5,0x76,0x30,0x11,0x29,0x59,0xa3,0x61,0xf7,0x61,0xcd,0x9a,0xc4,0xb6,0x2a,0x34,0x0f,0xc8,0x6a,0x08 +.byte 0x52,0x14,0x63,0xcf,0x54,0xdb,0xb9,0x7c,0xf2,0x8b,0xa8,0x04,0xef,0x7d,0x9a,0x4d,0x00,0x2e,0x17,0xa4,0x2d,0x83,0x33,0x00,0xa4,0x58,0xda,0x5b,0x95,0x22,0x32,0x69,0xc9,0x6c,0x44,0x19,0x92,0x4b,0xa4,0x24,0xfe,0xc2,0x46,0x88,0x3e,0x8d,0x54,0x88,0x11,0xeb,0x36,0x32,0x03,0x87,0x55,0x8b,0x95,0x35,0x9c,0x04,0xd2,0x07,0x35,0xe0 +.byte 0x7a,0x70,0x6c,0x18,0x56,0xaa,0x85,0xf1,0xa2,0x13,0xfb,0xef,0x12,0x0f,0xb9,0x42,0x7f,0xd5,0xa1,0xd0,0xdd,0x29,0x62,0x08,0xe1,0x4c,0x20,0xb6,0xee,0x44,0x45,0x61,0x0b,0xeb,0x40,0x6e,0xef,0xea,0x60,0xfc,0x55,0xa0,0x74,0x45,0x27,0x51,0x90,0x0d,0x1d,0xbc,0x62,0xfb,0xed,0xca,0x7f,0x88,0x85,0x8a,0xfa,0x5c,0x89,0xf6,0x79,0x5b +.byte 0xe3,0x3c,0xfd,0x19,0xa9,0xba,0x33,0xc4,0x7a,0x89,0x5b,0x11,0xe2,0xda,0x92,0xd1,0x3d,0x3e,0x9c,0x66,0xa5,0x1d,0xcb,0x9b,0x0a,0x46,0x84,0x93,0x3f,0xc4,0xbf,0x52,0x06,0x49,0xe2,0x46,0x0e,0x2b,0x39,0x67,0x1c,0x8f,0x4f,0xf3,0x53,0xce,0x2a,0x33,0x74,0xc4,0xe9,0x44,0x99,0x01,0xf0,0x55,0xcc,0x0a,0xed,0xa9,0xce,0x76,0x52,0x4d +.byte 0x85,0x52,0x26,0x82,0x75,0x3d,0x47,0xfb,0xb1,0xc4,0xfd,0x07,0xa6,0x79,0xff,0x3f,0xda,0xc2,0xa9,0xab,0xc7,0x88,0xa2,0xa1,0x5d,0xf2,0x03,0xe3,0xdc,0xbf,0xa6,0x90,0xfd,0xe0,0x43,0x69,0x88,0x78,0x50,0x99,0xb0,0x7d,0x18,0xca,0x4d,0xb5,0x04,0x8e,0x1a,0xbb,0x22,0xe5,0xc4,0xc6,0x85,0xe3,0x62,0xa9,0xce,0x50,0x83,0x9b,0xa0,0xf0 +.byte 0x1a,0x07,0x10,0x90,0x3a,0x31,0x74,0x11,0x69,0x23,0xd2,0x08,0xce,0xfe,0xb1,0x21,0x64,0x62,0x05,0x3b,0x4c,0x8d,0xe3,0x8b,0x42,0x27,0xbf,0x93,0x06,0xf1,0x99,0x00,0x20,0xdf,0xe3,0xd3,0x4b,0x8e,0xb2,0x12,0xb6,0x2c,0x63,0xd0,0x4e,0xd1,0x38,0x8c,0x49,0x69,0x60,0x83,0x02,0xbb,0x8c,0x96,0x0f,0xe9,0x24,0x46,0x85,0xc9,0xf9,0x3f +.byte 0x58,0x1b,0x7e,0x72,0x26,0x81,0xb9,0xfb,0xe4,0x41,0xbf,0xd8,0x1b,0xd8,0x36,0x16,0x92,0xf4,0x78,0x0e,0xd4,0x95,0x92,0x20,0x33,0x83,0x65,0x21,0x97,0x92,0x19,0x0f,0x12,0x1c,0x4e,0xd5,0x3c,0xb9,0x54,0xd4,0x6a,0x4d,0x6d,0x89,0x7b,0xf0,0x07,0xf4,0x50,0xb2,0xa1,0xd8,0x4a,0x9e,0xf3,0x3a,0x99,0x65,0x67,0x61,0x09,0xc2,0xf5,0xd5 +.byte 0x97,0x36,0xcb,0xe6,0x95,0xa0,0x19,0x2e,0xcf,0x4c,0xce,0xc9,0x4e,0x3b,0x55,0xd1,0xba,0x47,0x4f,0xb5,0xbd,0x29,0xa1,0x8c,0xcd,0xd8,0x9d,0xcf,0xf8,0x1c,0xa5,0x37,0x91,0x66,0x6d,0x3d,0xfc,0x03,0x8b,0x85,0xa9,0x51,0xaa,0x30,0xf7,0x0e,0x44,0x82,0x77,0x5f,0x84,0x60,0x6c,0xc2,0x95,0x4e,0xca,0x16,0x23,0xf2,0x66,0x97,0x45,0x05 +.byte 0x90,0xdb,0xb8,0xbf,0x8e,0xaa,0xc8,0x41,0x1e,0x23,0xd0,0xbe,0xc7,0x6c,0x5f,0x39,0x18,0x61,0x1d,0xa2,0x15,0xe5,0x15,0x58,0xd0,0x36,0x99,0xe7,0xdc,0x90,0x5e,0x9a,0x67,0xee,0x92,0xb1,0x61,0xbd,0xe9,0x70,0x04,0x00,0x07,0xc9,0xab,0x74,0x1e,0x0f,0x84,0x45,0x1f,0x49,0xbb,0x49,0xec,0x03,0x00,0x47,0x38,0xfd,0x09,0xbe,0x23,0x3e +.byte 0xa8,0x80,0x21,0xf9,0x92,0x5e,0xd6,0x51,0x91,0x7e,0x21,0x5d,0x1e,0xfc,0xbb,0x60,0x9a,0xf5,0x0a,0x3b,0x41,0x4a,0xfa,0xfa,0x26,0xb2,0x54,0x6a,0x61,0xe4,0x13,0x9e,0xc5,0x50,0x29,0xf1,0x29,0xa5,0x76,0xb7,0xce,0x2c,0xe6,0x98,0x88,0xb5,0x87,0xcf,0x49,0x6b,0xa4,0x54,0x94,0x34,0x73,0xec,0xde,0xe4,0x6c,0xe9,0x1e,0x07,0x60,0x8c +.byte 0xb4,0x47,0x87,0x82,0xb0,0x51,0xbc,0xb6,0xeb,0x5c,0xbc,0x78,0x94,0x8f,0xe9,0xd9,0xd1,0xc4,0xfe,0x51,0x57,0xdd,0x7b,0x4a,0x9b,0xbf,0xfb,0xe4,0x04,0x49,0xc4,0x29,0x1e,0xc3,0xf6,0xd5,0xf9,0x42,0xed,0x5d,0x57,0x8f,0x5d,0x1e,0x29,0x69,0xb6,0xf9,0x11,0x36,0x65,0x53,0x07,0xaf,0x8d,0xd3,0xa3,0xb4,0x75,0xeb,0x7a,0xbb,0xc0,0x35 +.byte 0xe5,0xfa,0x42,0xab,0xda,0xd8,0x83,0x65,0xc2,0x97,0x61,0x76,0xbb,0x96,0x8d,0x8f,0x8b,0xb0,0xa5,0x6f,0x3a,0x3c,0x19,0x84,0x7f,0x20,0x0e,0x97,0x2e,0xd9,0xee,0x2e,0xd6,0x29,0x01,0x94,0x67,0x0d,0x4d,0x43,0x24,0xe5,0xa6,0x92,0x77,0x85,0x49,0xdb,0xb9,0x62,0xb2,0xb8,0xd2,0x2f,0xc3,0x9a,0xe5,0xc0,0x23,0xac,0xd7,0x02,0xf9,0xf7 +.byte 0x8b,0x64,0x19,0x44,0xfc,0x2d,0x57,0x3f,0x3e,0x32,0x0d,0xdf,0x2c,0xc9,0x38,0x47,0xa2,0x24,0xab,0x30,0x53,0x7b,0x51,0xf2,0xc4,0xf3,0x18,0x4d,0x4b,0x0e,0xf2,0x09,0x0b,0x0f,0xa3,0x01,0x0a,0x92,0x71,0x2a,0x37,0xca,0x03,0x2e,0x17,0x17,0x64,0x40,0xdf,0x5d,0xdb,0xee,0x71,0xae,0xb8,0xbe,0x3b,0x06,0x03,0x66,0xa7,0x93,0x42,0x1e +.byte 0x15,0x1c,0x26,0x51,0x22,0x15,0x7f,0xab,0x2d,0x64,0xe6,0xde,0xb9,0x25,0x2b,0xa3,0xa7,0xbc,0x26,0xad,0x12,0x2c,0x36,0x12,0x7b,0x7d,0x5a,0x44,0x4e,0xe1,0x6b,0x26,0x8b,0x54,0xe8,0x8f,0x94,0x24,0x7e,0x3c,0xd9,0xe2,0x28,0x64,0x40,0xeb,0xaf,0xbf,0xe0,0xbc,0xd1,0xc2,0xfe,0xc3,0xc3,0x0f,0x0c,0x30,0x2d,0xf6,0xf2,0xc2,0x9a,0xe9 +.byte 0xdc,0x2c,0x63,0x9d,0x1a,0xc2,0xfc,0x94,0xe7,0xfa,0x6e,0x9f,0x3c,0xd5,0x51,0x18,0x62,0x46,0xcc,0xab,0xbd,0x26,0xe6,0x85,0x9b,0x4d,0x5d,0xf5,0x16,0xe1,0x5e,0xf0,0x40,0x44,0x90,0xf6,0x98,0x06,0x68,0xdc,0x7c,0xcb,0x26,0x78,0xde,0xe9,0xbd,0xa1,0xfd,0xe9,0x43,0x8c,0xcf,0xe0,0x8b,0xf3,0xca,0x65,0x19,0xc1,0x93,0x18,0x13,0x5d +.byte 0x0f,0xce,0x0b,0x2b,0x6f,0x68,0x38,0x82,0x79,0x68,0x82,0x0a,0x24,0x40,0x77,0xa5,0xcd,0x98,0x36,0xf5,0x0d,0x03,0xd1,0x0f,0xed,0xaa,0x24,0xe1,0xe2,0x8f,0x5a,0xf0,0x3c,0xce,0xbd,0x65,0x4e,0x40,0xd3,0xcc,0x89,0xd3,0xa8,0x5f,0xbf,0xcc,0x77,0x75,0x61,0x1e,0x78,0x70,0x3d,0x41,0xdf,0xb8,0x13,0x0d,0x58,0x37,0x94,0x67,0x89,0xc3 +.byte 0x52,0x19,0xb5,0x59,0x83,0xb4,0xf5,0x54,0x57,0x93,0x9a,0xc6,0x40,0x8c,0x85,0x7f,0xd2,0x42,0x6a,0xaf,0xb2,0xae,0xcf,0x57,0x99,0xbf,0x4d,0xa4,0xb0,0x1f,0x50,0x58,0x3a,0xc0,0xf1,0xdc,0x91,0x8c,0x67,0xc3,0x2a,0xce,0x46,0x4c,0x66,0x39,0xa9,0xd0,0xa7,0x5e,0xd8,0x0d,0x08,0x0f,0x9f,0xb0,0xd2,0x38,0x22,0xb5,0xdb,0xba,0x0f,0xcd +.byte 0x1a,0x62,0x73,0xc4,0xb6,0x6b,0xc5,0x0b,0x54,0xe6,0x83,0xae,0xb5,0x5e,0x73,0x1e,0xb2,0x4a,0xe5,0x2c,0xa6,0x6b,0x1b,0xe7,0x63,0xa3,0xa1,0xe9,0x7d,0xab,0xa9,0x87,0x6e,0xaa,0x43,0x55,0x6f,0x95,0xee,0x81,0xa0,0x45,0x1a,0x56,0xce,0x70,0xe6,0x1f,0x7f,0xd8,0x18,0x52,0x25,0x3b,0x58,0x65,0xbe,0xbf,0x90,0x35,0xee,0x76,0x8b,0x7c +.byte 0x1f,0x2f,0x9e,0x35,0xcf,0xc7,0x29,0xea,0x62,0x66,0x0b,0xe1,0xd0,0xcc,0x29,0xc6,0x6e,0xd4,0xbd,0x46,0x4b,0x02,0x96,0xd3,0x30,0xc3,0x71,0x60,0x73,0x06,0x3a,0x25,0x71,0x9b,0x63,0x82,0x3f,0xac,0xd4,0xdb,0x69,0xbc,0x7c,0x39,0xb7,0x71,0x98,0xa1,0x68,0x7c,0x0c,0x13,0xf7,0xef,0x5b,0xba,0xd9,0x45,0x3a,0x5e,0xa2,0x65,0x1a,0xbf +.byte 0x6e,0x5a,0xa3,0x2f,0x7c,0xf8,0xe4,0x43,0x3f,0xa3,0x53,0x26,0x05,0x2a,0x63,0x21,0x71,0x4f,0x40,0x9e,0xc9,0xd1,0xb1,0x9a,0x0b,0xf2,0x04,0xed,0xc8,0xb8,0x93,0x0f,0xa9,0xad,0x3f,0x30,0x39,0xc8,0x94,0xa3,0x9b,0x77,0x35,0x18,0xb3,0x82,0x1b,0xe5,0xab,0x86,0x9c,0x99,0xaf,0x52,0x6f,0x7a,0xf5,0x3b,0x8e,0x83,0x4a,0x8c,0xfc,0xa0 +.byte 0x72,0x10,0x1d,0xb4,0xd3,0xdb,0x38,0x82,0x11,0x5f,0x22,0xc1,0x9d,0x63,0xf2,0x50,0xc9,0x6d,0x1f,0xc4,0x57,0x52,0x53,0x79,0xb2,0x24,0x7b,0x38,0x43,0x26,0xe0,0xdc,0xeb,0x6a,0x5b,0xd2,0xff,0xfc,0xb5,0xd9,0x69,0xf2,0x80,0xaf,0x71,0x33,0xdf,0x33,0x35,0xb0,0xef,0x5f,0xdc,0x37,0xb6,0x36,0xe9,0xae,0x03,0xbc,0x4d,0xa8,0x40,0xc1 +.byte 0x7d,0x2c,0xf0,0xf4,0x3b,0x53,0x90,0xf7,0xcb,0xa1,0xd2,0x21,0x8f,0xff,0xfc,0x0c,0x61,0x85,0x53,0x04,0x30,0x0b,0x8c,0xf5,0x6b,0x60,0x73,0xff,0x88,0x29,0x5b,0xfc,0xeb,0xec,0x81,0x10,0xf0,0x56,0x00,0xd8,0x86,0xf0,0xbe,0xbd,0x50,0xf5,0xc9,0x27,0xa4,0x18,0x4c,0xd6,0x3a,0xe6,0x12,0x21,0x8c,0xe9,0x5e,0xba,0x30,0x03,0x4d,0x9e +.byte 0x16,0x60,0x77,0x9c,0x3f,0xa6,0xd5,0x0c,0x82,0x39,0xaf,0xfa,0x7e,0xcf,0x50,0xcb,0x87,0xe2,0x35,0xaf,0x24,0x96,0x2c,0x02,0x70,0xb9,0x21,0x00,0x2f,0xdb,0x3f,0xfd,0xe8,0xa5,0x40,0x87,0xfe,0xfc,0x7b,0x05,0xcf,0xa8,0xae,0x0d,0x71,0x22,0xd1,0xdc,0x7e,0x4f,0x2d,0xd3,0x0f,0x5d,0x0f,0xff,0xdf,0x4f,0xea,0x88,0x4c,0xe7,0x84,0xb6 +.byte 0x7d,0xb0,0x74,0x37,0xdb,0x75,0xfa,0x95,0xe7,0xee,0x58,0xb5,0xd4,0x1d,0xe7,0xcc,0x1f,0x3a,0xd0,0x59,0xb8,0x93,0xbf,0xe6,0x33,0x59,0x7b,0x96,0x80,0x77,0x06,0xf3,0xf7,0xab,0x91,0xcd,0x0a,0x4c,0x48,0xc0,0x35,0x07,0x3d,0x9a,0x32,0x90,0x50,0xde,0x22,0x1c,0x40,0x7b,0x19,0x7d,0x98,0x50,0x8a,0x0d,0x19,0xd1,0x97,0xcc,0x42,0xbf +.byte 0xb3,0x81,0x09,0x4f,0x14,0x8d,0xb2,0xfd,0x7d,0xee,0x76,0x97,0xb9,0x99,0x2c,0xbd,0x94,0xd2,0x29,0x6d,0x3c,0x91,0x29,0x64,0x2f,0x6c,0xdb,0x4e,0x26,0x55,0xef,0x55,0x6b,0xb6,0x34,0xf4,0xeb,0x13,0x96,0x5f,0xac,0xcf,0x31,0x72,0x6b,0x9f,0x06,0xb0,0x80,0xc4,0x56,0x33,0x75,0x57,0xdd,0x8e,0x07,0x82,0xe5,0x13,0x20,0xef,0xee,0x4d +.byte 0x8d,0x8b,0xc7,0x73,0x1d,0x7f,0x49,0xdf,0xa4,0x29,0xcf,0xe7,0x9f,0x40,0x8a,0x05,0xba,0x73,0x16,0xdc,0xe9,0x6f,0xdd,0xae,0x79,0xd9,0x44,0x59,0x26,0xd3,0x7c,0xa2,0xcd,0x57,0xc9,0x9d,0x90,0x38,0x73,0x65,0x82,0xc6,0x18,0x77,0xba,0xe2,0xbc,0xea,0x25,0x43,0xc5,0xf6,0xad,0x6c,0x95,0x4c,0x86,0x3f,0x50,0x56,0x28,0x79,0x3e,0x68 +.byte 0xf9,0xc3,0xb8,0x52,0x65,0x35,0x6c,0xd8,0x8e,0x06,0xaa,0xec,0x80,0x46,0xdb,0xa8,0xcd,0xbc,0x5b,0xe2,0x30,0x3a,0x3b,0xcb,0x2a,0xec,0xbc,0xe7,0x09,0x84,0xf7,0x9f,0x31,0xbc,0xef,0xdc,0xa9,0xb8,0x87,0x9d,0x4f,0xe1,0xd2,0x1b,0x9f,0x3f,0xd8,0xdc,0x2c,0xc7,0x73,0x08,0x2c,0xaa,0xbe,0x06,0x78,0x8f,0xb1,0x64,0x1b,0x3d,0xb5,0xad +.byte 0x62,0x60,0x7f,0xc4,0x64,0x43,0x18,0xd4,0x8d,0x27,0xb3,0x32,0xae,0x28,0x47,0xdd,0x5d,0xdf,0x08,0x0b,0x0e,0xfb,0xba,0x92,0x55,0x33,0x92,0x02,0xf6,0xc2,0x2e,0xd2,0x70,0xaa,0xfb,0x88,0x9c,0x5e,0x9b,0x26,0x32,0x98,0xf8,0xe6,0x98,0x5c,0xf9,0xd7,0x3f,0xb9,0x74,0x5b,0x10,0x51,0x01,0x6e,0x44,0x71,0x91,0x3e,0x2d,0x06,0x68,0x97 +.byte 0xe8,0xe3,0xf5,0xdd,0x46,0xc1,0x10,0x61,0xa9,0xa9,0x96,0x27,0x2a,0x25,0x7b,0x16,0x4a,0xbc,0x61,0x4b,0x32,0x6c,0x44,0x94,0x10,0x04,0x8e,0x0f,0xe6,0x8e,0x15,0xbc,0xb6,0x1b,0x66,0x19,0xff,0x2e,0x70,0x80,0xb2,0x9a,0x51,0x82,0x1a,0xc9,0x98,0x6b,0x7e,0x4f,0x4c,0xf9,0x93,0x2a,0x8e,0xb4,0x44,0x3b,0x75,0xc9,0x28,0xd1,0x63,0xd9 +.byte 0x13,0xc8,0x68,0x60,0xad,0x4a,0xbe,0x03,0x1f,0xe2,0xe3,0xe5,0x99,0x11,0x4f,0xc6,0xbe,0x32,0xfa,0xb8,0xde,0x69,0x28,0x4b,0x11,0x4e,0xdd,0x0e,0x45,0x6e,0x43,0xe1,0xe6,0x7c,0x8f,0x8c,0xee,0x57,0xef,0x29,0xb4,0xb9,0x3c,0x9e,0x3a,0xc7,0xe0,0x98,0xce,0x29,0x44,0x1c,0x72,0x68,0x33,0x04,0xd4,0x9a,0x42,0xe1,0x77,0xa0,0x5b,0x1f +.byte 0x11,0x5d,0x82,0x8c,0xb6,0xb1,0x3b,0xce,0x4e,0xa9,0xaa,0x05,0xf2,0x67,0x6c,0x0c,0xa3,0x08,0x9a,0xe0,0x14,0x92,0x82,0x51,0x98,0x7f,0x01,0x0a,0x77,0x35,0xa9,0xc0,0xbe,0x0a,0xde,0x13,0xf0,0x89,0xc9,0x54,0x9c,0x1e,0xc7,0x57,0xad,0x6b,0x36,0x8e,0x91,0x95,0x70,0x78,0x43,0x64,0x0e,0x0b,0x5c,0x97,0xc7,0xc5,0xc0,0xb6,0x4e,0x80 +.byte 0x6e,0x20,0xa6,0xe7,0xfb,0xd1,0xc1,0x57,0x86,0x81,0xd8,0x8f,0x59,0x8c,0xd4,0xa8,0x8b,0x8c,0x2b,0x50,0x6a,0x90,0xdf,0xef,0x14,0x53,0x18,0x2f,0xbc,0x39,0xf8,0x1f,0xa6,0xc3,0x23,0x0f,0x0f,0xcf,0x75,0x7a,0xad,0x12,0xfd,0x22,0x24,0x56,0x51,0xb5,0x94,0x90,0x08,0xb2,0x1c,0x01,0x09,0xa4,0xe3,0xa0,0x65,0x3a,0xda,0xd7,0xe5,0xf2 +.byte 0x78,0x4f,0xe6,0x55,0x37,0xc4,0x9c,0x9e,0xb0,0xb8,0xbe,0x89,0x61,0x7e,0x46,0xf3,0x51,0xdd,0x2c,0x87,0x48,0x0f,0x04,0xe7,0x96,0x3a,0xcb,0x4d,0x8b,0x9d,0xa0,0xfb,0x6c,0xe8,0xa4,0xc2,0x92,0x4c,0x97,0x05,0xd3,0x23,0x3f,0x07,0x3c,0xba,0x64,0xa8,0xdb,0x09,0x81,0x7d,0xea,0x66,0x1a,0x8e,0x7c,0x35,0x28,0xce,0xe3,0xce,0xbf,0x7c +.byte 0x02,0x4f,0x39,0xac,0x38,0xd8,0x34,0x71,0xe4,0xfa,0x26,0x6e,0xf1,0xd9,0x53,0xd6,0x50,0xce,0x21,0xeb,0x4c,0x98,0x97,0xeb,0x21,0x29,0x4f,0xd8,0x49,0x34,0xd1,0xc9,0x32,0x7c,0x82,0x53,0xc2,0xec,0x41,0x5d,0x42,0x39,0x11,0x17,0x41,0x54,0x3d,0x60,0x8b,0xb4,0x42,0x99,0x68,0x16,0xbd,0x50,0xb2,0x4a,0xba,0xca,0x42,0x59,0xb0,0x7e +.byte 0x88,0xab,0x18,0x6b,0x1d,0xe4,0x68,0x2e,0xeb,0x95,0xb5,0xc6,0x3b,0x64,0x38,0xbd,0x15,0x61,0xac,0x1a,0x79,0xd0,0x73,0xde,0x31,0xfc,0xd8,0x43,0x54,0xca,0x97,0xdb,0xa7,0x16,0xf8,0x34,0xa6,0x86,0xce,0x3f,0x82,0xbc,0x92,0xf9,0x82,0x8e,0xef,0xc5,0x6b,0xa4,0xa0,0x83,0x7f,0xe9,0xf5,0x1f,0xdd,0x24,0xdc,0x88,0x08,0xf2,0x93,0x36 +.byte 0x4a,0x9c,0xaa,0x8a,0x51,0xf7,0x10,0x03,0x35,0x9e,0x44,0x29,0x15,0x94,0x46,0x71,0xc7,0x2a,0x8a,0x14,0x48,0xde,0x11,0x67,0xb1,0x8b,0xb4,0x5a,0x0a,0x76,0xc7,0xd8,0x1c,0x17,0xee,0x78,0x12,0xcc,0x93,0x0f,0xab,0x17,0x9f,0xb0,0x90,0x31,0x46,0x76,0x10,0xb3,0x37,0x26,0xe8,0x60,0x21,0x9a,0xd6,0x63,0x41,0xbe,0x8c,0x51,0x96,0xb0 +.byte 0x0d,0x44,0x99,0x32,0xef,0x54,0xf7,0xf4,0xb2,0x65,0x3e,0x2c,0x39,0x72,0x06,0xd7,0x57,0x0b,0x61,0x12,0xe2,0x90,0xbf,0x45,0xe2,0xd6,0xd3,0x27,0x9f,0xbe,0x3f,0x83,0x58,0x6a,0xe7,0x03,0x3f,0xeb,0x82,0x9f,0xad,0xe3,0x12,0x9c,0x0b,0x65,0x32,0x28,0xee,0x93,0xf9,0x1a,0xd2,0xda,0xd0,0x41,0xad,0xb4,0x9d,0x37,0xc7,0xd5,0x44,0x9a +.byte 0x48,0x42,0x29,0x89,0x21,0xa5,0x2e,0xf9,0x92,0x55,0xa2,0x64,0xdf,0x63,0x23,0x7b,0x03,0xce,0xb7,0x4e,0x4d,0x84,0x83,0xf2,0x07,0x3e,0xf4,0x51,0x5c,0xb5,0xce,0x49,0xf4,0xff,0x66,0x1d,0xcc,0x3a,0x45,0x36,0x7a,0xae,0x00,0xfa,0x56,0x84,0x3c,0x3f,0x51,0xb0,0x16,0x79,0x0d,0xa5,0x02,0x25,0x3c,0xcd,0x22,0x2e,0x4c,0xde,0x5c,0xf0 +.byte 0xf3,0x44,0x4f,0xb3,0xbc,0x42,0x19,0x2f,0x9c,0xbd,0xd9,0x3f,0xa4,0xfe,0x21,0xab,0x82,0x97,0x76,0x16,0xed,0x20,0xa4,0x93,0x4b,0x21,0x70,0xed,0xc1,0x10,0x7a,0x27,0x1b,0xfc,0x99,0x52,0xa0,0x75,0xc6,0xb2,0x1d,0x97,0x83,0x73,0xe7,0x0b,0xa9,0x03,0xd5,0xba,0x51,0xb9,0x4f,0xa6,0x61,0xfc,0x45,0xff,0xe3,0x82,0xd6,0xab,0xc5,0x36 +.byte 0x1c,0x63,0xcb,0x09,0x14,0xee,0x5a,0x5a,0xe8,0x20,0xa2,0xde,0x4b,0x1a,0x8a,0xcf,0xb4,0xd8,0x6f,0x5c,0x98,0x21,0x66,0xfb,0x5d,0x8a,0xc1,0xbe,0xdd,0x69,0x9e,0x1e,0xeb,0xa0,0x81,0xea,0x8b,0x2a,0xb6,0x80,0xff,0xb9,0x32,0x0a,0xfc,0xb6,0xb7,0xd8,0xa2,0x5d,0xbf,0xc3,0xe1,0x73,0xba,0x4b,0xbc,0xaa,0x31,0x7e,0xc9,0xe7,0xd0,0x9e +.byte 0xde,0xdc,0xb5,0xfa,0x9d,0x9d,0x8c,0xed,0xe6,0x44,0x3a,0x81,0x37,0xd7,0x2c,0xee,0x3f,0xe4,0xed,0xc5,0x43,0xcc,0x2e,0x02,0xdd,0xfc,0xae,0xd1,0x2d,0xb3,0x75,0xdd,0x7c,0x85,0xfa,0x2d,0x8a,0xec,0x05,0xd3,0x45,0x8b,0x3a,0x6d,0x78,0x36,0x04,0x71,0xe2,0x10,0xb8,0x13,0xb2,0xbd,0xc6,0x0e,0xb7,0xda,0xfa,0xf8,0x47,0x9b,0x7d,0x14 +.byte 0xe2,0xaa,0x82,0xfc,0x23,0xd2,0xef,0xff,0xaa,0x94,0x67,0x82,0xf6,0x31,0xfa,0x5e,0xbd,0xd1,0x78,0xee,0x07,0xb2,0xcd,0x0f,0x73,0x36,0xeb,0xb3,0x7c,0x6e,0x66,0x73,0x85,0x5a,0x23,0x26,0x2d,0x5b,0xb0,0x6c,0x04,0x1f,0x70,0x0a,0x67,0xff,0x02,0x77,0x66,0x51,0xbf,0x0b,0xe2,0x90,0x96,0x79,0xe2,0xac,0x21,0xa4,0x58,0x51,0x7c,0xb2 +.byte 0x03,0xb1,0x64,0xb1,0x51,0x95,0xad,0x3e,0x4b,0x76,0xf1,0xb0,0x87,0x02,0x82,0x4b,0x18,0xb3,0x87,0xc1,0xc1,0x49,0xf3,0xd2,0x71,0x69,0x0a,0xef,0x5b,0x8d,0x89,0x80,0x98,0x9a,0xee,0xc5,0xab,0x9b,0x04,0x9b,0x1a,0x51,0x53,0xc6,0xaa,0x3f,0x84,0xe8,0x60,0xf4,0x15,0xff,0xb4,0xc8,0x1b,0xe1,0x8d,0x3f,0xe9,0x6c,0x79,0x74,0xc3,0xef +.byte 0x1a,0xb8,0xdd,0xb5,0x92,0xba,0xf9,0x29,0xa1,0x0c,0x0d,0x88,0x08,0xd8,0x8c,0xb9,0xad,0xdf,0x62,0x03,0x27,0x79,0x69,0xca,0x21,0x24,0x00,0x3f,0x9e,0xcd,0xc6,0x8f,0x66,0xee,0x0d,0x6f,0x29,0xa5,0xf7,0x51,0x7c,0xa8,0xfd,0xa9,0xce,0x75,0xcd,0xdb,0xa6,0x86,0x43,0x16,0xc7,0xf0,0xea,0xfd,0xf8,0x08,0xd4,0x4e,0x7b,0x10,0xd2,0x5b +.byte 0xcf,0x4f,0xf0,0x71,0x72,0xc4,0x31,0x90,0x93,0x09,0x69,0xfb,0xd6,0x1c,0x41,0x62,0x58,0x5c,0x60,0xbb,0x89,0x28,0xc1,0x57,0xa2,0x52,0x8d,0x48,0x98,0x0b,0xd8,0x7c,0xb1,0x7c,0x92,0x1c,0x2a,0xec,0x0a,0x61,0xa6,0x36,0x3b,0xf5,0x24,0xe4,0xb4,0xc3,0x09,0x99,0x89,0x8b,0x7a,0x9f,0x61,0x3c,0xc1,0x8b,0x1b,0xda,0xb2,0x44,0xab,0xbb +.byte 0x8a,0xad,0xcb,0x17,0xe5,0x2e,0x74,0x23,0x39,0x76,0x10,0x0f,0xd5,0xa8,0x4f,0xc2,0x14,0xa5,0xb6,0x47,0x48,0xfb,0xb2,0x52,0x9e,0x0a,0xfc,0x0f,0x95,0x04,0xa8,0x71,0xa7,0xca,0xb7,0x01,0x67,0x39,0xd1,0xc7,0xf6,0x15,0xc4,0x8b,0xe8,0xa5,0xb9,0x5c,0x7e,0x83,0x26,0xd5,0x37,0x4c,0x44,0xff,0x0b,0xa3,0x53,0x3b,0x6c,0xb7,0xbb,0x10 +.byte 0xbc,0x33,0xb8,0xd0,0x4c,0x00,0x3b,0x62,0x6b,0x43,0x4e,0x91,0x2f,0xa5,0x08,0x35,0x6f,0xc3,0x03,0xa1,0x10,0xbc,0xb1,0x31,0x8d,0x51,0x0f,0x2f,0x42,0xfb,0x45,0x55,0xac,0x1e,0x05,0x05,0xbc,0xc9,0xe8,0x23,0xd5,0xe8,0x68,0x32,0xa7,0x10,0xa0,0x7d,0x72,0x02,0xc1,0xcd,0x0a,0xdc,0x2f,0x4b,0xbc,0x34,0x94,0x25,0x9b,0xc8,0x25,0x4a +.byte 0xc7,0x1a,0xc6,0x62,0xeb,0xa5,0x4b,0x8b,0x0e,0x2b,0x93,0x88,0xbf,0xa6,0xb9,0x73,0xae,0x7f,0xa5,0x6d,0xce,0xc3,0xf5,0x9a,0xcb,0xed,0x69,0xc7,0x34,0x39,0xcf,0xde,0x86,0xf3,0xa8,0x0e,0x5d,0xdc,0x76,0x0d,0x60,0x96,0x62,0x2e,0x61,0xe6,0x69,0xc6,0xd8,0xb9,0x86,0xda,0x4f,0xa0,0x78,0x03,0xa7,0x1a,0x52,0xb4,0x1b,0xb8,0x57,0xca +.byte 0xed,0x92,0x6c,0xbc,0x3c,0x83,0xbd,0x8d,0xbd,0xe3,0xa9,0x08,0xe1,0x8a,0xab,0x30,0x39,0xc8,0x50,0xe8,0xda,0x6e,0xa6,0xc6,0xc4,0xe7,0x13,0x7d,0xa7,0x77,0xea,0x3b,0xe1,0xa3,0x4a,0x8e,0x48,0xf3,0x52,0xa7,0x82,0x40,0x76,0x99,0x3e,0x45,0x60,0x6e,0xf1,0x59,0xa5,0x22,0x7c,0x3d,0xac,0x72,0x00,0xbc,0xc6,0x37,0x62,0x58,0x63,0x63 +.byte 0xd8,0xe9,0x47,0x2f,0x1c,0x89,0xaf,0xc9,0x3b,0x73,0xdf,0xbe,0x6c,0x96,0x1a,0x87,0x20,0xd7,0xf7,0x1b,0xce,0xa6,0x08,0x46,0x44,0x0a,0x1a,0xe4,0x87,0x6b,0x94,0x1a,0x35,0x70,0xec,0x2b,0xdd,0xf9,0xbb,0xd3,0xd3,0x2a,0x63,0xd3,0x07,0x7e,0xab,0x18,0xa8,0x2f,0x64,0x00,0x7e,0x08,0xaf,0x46,0x39,0x8b,0x29,0xf2,0x50,0xd3,0xa9,0xf1 +.byte 0xf0,0xe0,0x38,0x32,0xe5,0x82,0x88,0x8d,0xa7,0x79,0x88,0x20,0x56,0x01,0xf5,0x6c,0x99,0xe6,0xbf,0x89,0xd7,0x1c,0xfa,0xfd,0xd1,0x86,0xfd,0x5d,0xdf,0x04,0x95,0xda,0xe6,0x99,0x64,0x80,0x68,0xda,0x36,0x97,0x65,0x81,0x1f,0xed,0xb4,0xba,0x21,0xb0,0x87,0x01,0x7c,0x96,0xe7,0x6f,0xea,0x36,0x20,0x65,0xa9,0x73,0x6c,0x03,0xa6,0x03 +.byte 0x9c,0x82,0xbb,0xbf,0x3b,0x3d,0x9e,0x0d,0x31,0x1a,0x08,0x46,0x02,0xb5,0x43,0xe7,0xa1,0xfe,0xdb,0x35,0x13,0x6f,0x28,0x87,0x14,0x53,0x38,0xdf,0xda,0x88,0x0e,0xd1,0xac,0xe3,0xd4,0xea,0xd3,0x09,0xb8,0xc6,0x6f,0x9b,0x51,0x82,0xa8,0xc5,0x18,0x1d,0x8d,0x9c,0xc8,0xde,0x98,0x57,0xa8,0x3f,0xaf,0x8d,0x09,0xeb,0xab,0xa9,0x63,0x98 +.byte 0x5a,0x6d,0x05,0x45,0xcc,0xb7,0x0c,0xb7,0xd0,0x59,0x11,0x25,0x51,0x63,0xba,0x61,0x4a,0x1a,0x86,0x68,0x3e,0xb1,0xfa,0xb9,0xab,0x9b,0x78,0xbe,0x8f,0xde,0x4e,0xf9,0x22,0x4b,0xaa,0x19,0x2c,0xad,0x17,0xa9,0xb2,0x9b,0x40,0x8c,0xeb,0xb6,0x42,0xbc,0x14,0xa8,0xa2,0xd2,0x21,0x6e,0x19,0xe8,0xd3,0x07,0x82,0x0a,0x22,0xd9,0xf3,0x09 +.byte 0x29,0x68,0x34,0xb0,0xbb,0xad,0x25,0x17,0x3d,0x3b,0xf9,0x29,0xe3,0x8e,0x30,0x9d,0xb4,0xb8,0x51,0xa9,0x67,0x6f,0xe9,0xca,0x05,0xf0,0xd5,0xc2,0xd0,0x73,0x83,0x61,0x97,0x50,0x90,0x4c,0x6f,0x95,0xe6,0x62,0xcf,0xc0,0xe5,0x2c,0x42,0x45,0xd6,0xc9,0x01,0x74,0x19,0xaa,0x7a,0x53,0x9f,0xb6,0xab,0xa9,0xd3,0x19,0x80,0x10,0xd7,0xe2 +.byte 0x68,0xaa,0x17,0x60,0x47,0x8b,0x64,0x1f,0x69,0x16,0x2b,0xd5,0x7d,0x04,0x1a,0x3c,0x25,0x68,0xb6,0x0b,0x85,0x1b,0x4b,0x8b,0x11,0xde,0x57,0x97,0x03,0xcb,0x91,0x03,0x65,0xc9,0x2d,0x0b,0x59,0xd0,0x8e,0x98,0x91,0x3a,0x00,0x83,0xd6,0x41,0xb1,0x3b,0x2c,0x34,0x84,0x57,0x0d,0xf0,0xc4,0x25,0xa6,0xf1,0xa6,0x41,0xdf,0x0e,0xad,0x06 +.byte 0x03,0x13,0xcb,0x63,0x68,0xf7,0x07,0x1e,0xec,0xe1,0x36,0x4a,0x4d,0x50,0xc1,0x48,0xc5,0x95,0x22,0x10,0xf8,0xb7,0x45,0xc7,0xa4,0x35,0x40,0x8e,0x7c,0x9f,0x8b,0xa2,0x22,0x6b,0x2d,0xbb,0x52,0x33,0x13,0xfc,0x08,0x59,0x13,0xd0,0x3c,0x0e,0x2b,0x80,0xab,0x02,0xc3,0x92,0x3f,0x94,0x41,0x86,0x47,0xf8,0x27,0xa2,0xf8,0x0b,0xf2,0x45 +.byte 0x33,0x23,0xfa,0xd0,0xf0,0xa1,0x74,0x02,0x60,0x4f,0x1b,0xdd,0xba,0x2d,0xbe,0xd6,0xf3,0x6b,0xbe,0x4d,0x6b,0x66,0xe2,0x4c,0x4e,0x03,0xc2,0xd9,0xe4,0x52,0xbd,0x4d,0xdd,0x0d,0x46,0x9c,0x97,0x68,0xdc,0xd6,0xfb,0xfe,0x19,0xdd,0x69,0xd1,0x6e,0xbb,0x8b,0x58,0x5c,0x5c,0x2c,0x4d,0x5c,0x63,0x6e,0x01,0x60,0xf3,0x9b,0xb1,0x63,0x70 +.byte 0x3e,0x55,0xeb,0xc0,0x5f,0x12,0x1f,0x06,0x6d,0xbb,0xed,0x53,0x5c,0x25,0x4f,0x5b,0x1d,0x84,0xb7,0xab,0xaa,0x11,0x75,0xc7,0xb0,0x66,0xd9,0x32,0xec,0xb4,0xe3,0x3d,0x8d,0x9f,0x44,0xa1,0x03,0xbc,0xf2,0x9d,0x62,0x7d,0xbd,0x80,0x0d,0xa1,0xfa,0xe8,0xd0,0x91,0xe2,0xd5,0x20,0xe1,0xb8,0xdb,0xd8,0xa8,0x15,0x47,0x09,0x00,0x7e,0x29 +.byte 0xf2,0x5c,0x93,0x04,0x79,0x81,0x7e,0x22,0xd0,0x86,0x1c,0xf3,0x42,0x11,0xff,0xdc,0x9a,0x35,0x4c,0x9f,0xa4,0x7f,0xf3,0x0a,0xe8,0x63,0xb9,0x79,0x59,0xcc,0x8d,0xfd,0x27,0xbb,0x2d,0x1b,0x72,0xd6,0xac,0x5f,0x6e,0x13,0xbc,0xc3,0xff,0x84,0xf5,0x58,0x00,0x8a,0x71,0xdb,0x69,0xf4,0xd4,0xc8,0xbc,0x12,0x84,0xf7,0x07,0x4d,0x5b,0xd0 +.byte 0x7d,0x6c,0xec,0x01,0xe6,0x39,0x07,0x15,0x1c,0xca,0x49,0x62,0xe2,0xe9,0xf7,0xd2,0x81,0xd8,0x13,0x9f,0xaf,0xb3,0x1f,0xf5,0xf1,0x8d,0x61,0xa1,0x02,0x03,0x21,0xce,0x07,0xe2,0xd5,0xec,0x8d,0xfc,0xd4,0x51,0xd6,0x7a,0xc5,0x50,0x38,0x9d,0x91,0x0e,0xfe,0x97,0x63,0x19,0xb8,0x43,0x75,0xd2,0xfb,0xde,0xbd,0x84,0x1d,0xb7,0xdf,0xab +.byte 0xa9,0x86,0x69,0x2d,0x11,0x18,0xec,0x00,0x88,0xf0,0x86,0xa2,0xd5,0x07,0x9d,0x60,0x52,0x39,0x6d,0xae,0x30,0x5d,0x01,0xa2,0xd8,0xc9,0xc3,0xf8,0xc7,0xbe,0x04,0xe1,0x80,0x4e,0x7a,0xaa,0x3d,0xd2,0xb3,0x2f,0x91,0x9a,0xa8,0xbf,0xef,0x6d,0x61,0xf6,0x33,0x3e,0xf4,0xe6,0x0e,0x82,0x88,0x6f,0xef,0x55,0x97,0xf2,0xda,0x52,0xf1,0x3b +.byte 0x46,0x5d,0x23,0xe5,0x7e,0x7c,0x8b,0x51,0x56,0x96,0xf4,0x77,0xc5,0xa0,0x3c,0x14,0x3d,0xc2,0x3a,0xc1,0xaf,0xfe,0x6d,0xec,0x80,0x79,0xba,0x19,0x5f,0x26,0x8c,0x7d,0xb6,0xd2,0x27,0xf0,0xcf,0xa4,0x04,0x31,0x7d,0x8c,0xf5,0xa0,0xcc,0x04,0xd5,0x6e,0x4f,0xe0,0x35,0x0f,0x20,0xec,0x53,0xad,0x02,0xb8,0xdb,0x4c,0x4e,0xda,0x73,0x5a +.byte 0xc5,0x46,0xe5,0x10,0xbd,0xa2,0xb5,0xbf,0x71,0xc1,0x3a,0x83,0x58,0x6c,0x74,0x32,0xed,0xd3,0xcc,0xa5,0x6d,0x65,0x5b,0x5c,0xfe,0xcd,0x68,0x02,0xad,0xcf,0x54,0x4c,0x1d,0xad,0xdf,0xeb,0xa0,0xda,0xb0,0x12,0x5c,0xba,0x7b,0xa2,0x5d,0x5e,0xf3,0x6f,0x42,0x2d,0x83,0xf3,0x28,0xaa,0xcf,0x6c,0x85,0x6a,0x6b,0x80,0xc0,0x28,0x2e,0x1b +.byte 0x68,0xfa,0xe7,0xdc,0x1e,0x97,0x8d,0xca,0x1b,0xed,0xca,0xde,0x8f,0x52,0x73,0x54,0x57,0xaf,0xf0,0xb8,0x91,0x08,0xec,0x01,0x42,0x97,0x26,0x27,0xdd,0xfc,0x53,0x81,0x4c,0xbe,0x95,0xb5,0x67,0x51,0x35,0xb2,0xa5,0x8f,0x62,0x10,0x7a,0x1a,0x0e,0xcc,0xf1,0x9c,0xc4,0xa3,0xff,0xda,0xe4,0x23,0x12,0xf9,0x73,0x6f,0xeb,0xb1,0x82,0x00 +.byte 0x5f,0x35,0xaf,0x2e,0x6e,0x88,0x31,0xc0,0xb9,0x1a,0xce,0x27,0x5f,0xbc,0xcf,0x6d,0x03,0x12,0xfb,0xe9,0xae,0x3e,0xff,0x1c,0xa5,0x28,0x9d,0x19,0xd3,0xfe,0xca,0xd0,0x3c,0x04,0xd1,0x64,0xea,0xdd,0x2d,0x4a,0x0f,0x23,0xcc,0xd4,0xe5,0xf9,0xad,0x95,0xe4,0x91,0xb0,0xaa,0xb7,0x1e,0x28,0x9f,0xac,0xbc,0x9f,0xa3,0x62,0xb0,0x37,0xaf +.byte 0xdd,0xe6,0xcd,0x65,0xb4,0xea,0x31,0xbe,0xca,0x44,0x93,0x16,0x74,0x46,0x5a,0x3d,0x78,0x8d,0x9d,0x01,0x6b,0xf6,0xa7,0xf3,0xdd,0x1b,0x92,0xc1,0x74,0xf0,0xe4,0x32,0x90,0xc5,0x4d,0xdb,0x3e,0xab,0x0d,0x4c,0x1e,0x82,0x2f,0x82,0xe2,0xf7,0xe6,0x13,0xa8,0x8c,0xd6,0xaa,0x59,0xee,0x5c,0xc6,0x1c,0x67,0xd6,0x6f,0xf8,0x92,0xce,0xf0 +.byte 0xfa,0xde,0x15,0xdb,0x86,0x79,0x6e,0xaf,0x03,0x10,0x91,0x3f,0x6b,0xc4,0x6a,0x23,0x2d,0x01,0x36,0xbf,0xb4,0xff,0x99,0x46,0x92,0x64,0x45,0xd5,0xb0,0x1d,0xaf,0x13,0xa0,0xe0,0xf4,0x21,0x5d,0x98,0x47,0x04,0xef,0x06,0x81,0xd1,0x7c,0xf1,0x1d,0x4d,0x6d,0x04,0x9f,0x3b,0xf7,0xf9,0x27,0x6c,0x91,0x15,0xf3,0xf0,0x48,0x63,0x9d,0x56 +.byte 0xb1,0x8a,0xdb,0x27,0xf4,0x83,0x4e,0xfa,0x4b,0x15,0xc5,0x38,0xdf,0x4b,0xd5,0xcc,0xd4,0x15,0x21,0xc0,0xd8,0xbe,0xda,0x9e,0xe6,0x35,0xa6,0x4e,0x76,0x27,0xc6,0x10,0x02,0xf4,0xa1,0x9d,0x71,0xe5,0x77,0xdc,0xcd,0xbd,0xda,0xdb,0x46,0xd7,0xc7,0xa0,0x71,0xd5,0x0e,0xfd,0x4e,0xe7,0xe0,0xb9,0x69,0x9b,0x31,0x12,0x16,0x04,0x71,0x0d +.byte 0xac,0x6e,0xb7,0x66,0x1e,0xfd,0x9b,0x0d,0x57,0xd9,0x8f,0xd6,0x2e,0x13,0xb4,0x5b,0xd4,0x6e,0xa3,0xeb,0x7a,0x10,0x62,0x21,0xdc,0x0f,0x5c,0x29,0x37,0xd0,0x81,0x0e,0x14,0xc2,0xb6,0x2f,0x26,0x8b,0x1b,0x2d,0x72,0xb4,0x85,0x28,0xad,0x90,0x29,0x44,0x4e,0x1c,0x0e,0x1e,0x31,0xf8,0x54,0x8b,0x54,0x35,0x36,0x1c,0x3c,0xc9,0x1f,0x0e +.byte 0xf8,0xee,0x35,0xec,0x04,0x65,0xf8,0x13,0xb3,0x5a,0x73,0xfc,0x12,0xd6,0x35,0x19,0x7a,0x20,0x91,0x86,0xef,0x26,0xae,0x8b,0x03,0x11,0xb1,0x3a,0xa0,0xfc,0xee,0x6d,0xf2,0xfc,0x46,0x34,0x60,0x16,0xeb,0x4a,0xdb,0xcc,0xfb,0xa5,0xf1,0xde,0x19,0x62,0x9a,0x07,0xee,0x88,0xfe,0xdc,0x2e,0xc6,0x96,0x72,0x83,0x62,0x60,0x75,0xb9,0x88 +.byte 0x96,0x18,0xd9,0x03,0x80,0xd0,0x24,0x80,0x1d,0x04,0x2d,0xee,0x63,0x96,0xd6,0xfc,0xc7,0x01,0x71,0xb1,0xfc,0x8b,0xc4,0x88,0xcf,0x01,0x25,0xa7,0x51,0xbc,0xe6,0xaa,0x48,0x77,0xbb,0x70,0xe6,0x8d,0xfe,0x83,0x33,0xae,0x29,0xd9,0x1d,0x44,0xff,0x18,0xcf,0x91,0xe8,0x0d,0xdc,0x8b,0xdd,0x6b,0xec,0x35,0x16,0xfc,0xe1,0x0b,0xb2,0x70 +.byte 0xad,0x4a,0xa4,0x2c,0x23,0xa7,0xb8,0x64,0x2f,0x4a,0x7d,0x13,0xf6,0xa6,0x57,0x26,0x4d,0x08,0x6c,0x39,0x72,0xbe,0xdb,0x59,0xa8,0xe1,0x60,0x00,0x03,0xa6,0x56,0xa3,0x89,0x56,0xf1,0xe9,0x81,0x31,0x32,0xfd,0xba,0xd6,0x5f,0x38,0x89,0x92,0x88,0xd6,0xf0,0xb5,0x3c,0x46,0xed,0xec,0x9d,0x5a,0x42,0xe0,0x9a,0x6e,0xed,0x98,0x6a,0xec +.byte 0x97,0x22,0x5b,0x93,0xba,0xa5,0xc4,0x71,0x86,0x1f,0x32,0xa0,0x2a,0x50,0xb3,0x56,0x7e,0x62,0xb2,0xe1,0x84,0x5a,0xbd,0xdb,0x2f,0x38,0xd0,0x12,0x79,0x57,0xe8,0xf7,0x45,0xd9,0x71,0x4e,0x1a,0x0a,0x08,0xa0,0xc7,0xea,0x9d,0x74,0xc7,0xa6,0xaa,0x62,0x17,0xa2,0xba,0x23,0x26,0x41,0x1a,0xe4,0x02,0x98,0xd1,0xbb,0x32,0xa2,0xa1,0xcf +.byte 0x55,0x3c,0x2d,0xef,0xa6,0x69,0x4f,0xed,0x15,0x43,0x34,0xfa,0x40,0x8c,0xa2,0x0c,0xcf,0x2c,0xda,0x4d,0x08,0x34,0x3e,0xae,0x98,0xbd,0x2c,0x75,0x40,0x77,0xd7,0x7e,0x6e,0x09,0x64,0x39,0x0a,0x84,0x79,0x5e,0xe7,0x72,0x96,0x9d,0xc2,0x17,0x0a,0x3c,0x6d,0x76,0xf0,0x4b,0x75,0x12,0x45,0x19,0x55,0x84,0x06,0x6b,0x27,0x44,0xe5,0xf4 +.byte 0x89,0xbc,0xd4,0x50,0x0e,0x89,0xfd,0x9f,0xd6,0x3b,0xfb,0xa5,0x88,0xef,0x1d,0xd2,0x58,0x2b,0xc7,0x6b,0x07,0xb8,0x6a,0x40,0xe9,0x29,0x5a,0x9d,0x20,0xad,0xfd,0x9b,0x36,0x7e,0x8d,0x1f,0x81,0xd9,0x06,0x03,0x47,0x70,0x3f,0x7d,0x89,0x03,0x57,0xa7,0x46,0xc4,0x4b,0x9a,0xc8,0x57,0x35,0x02,0x2d,0xe0,0x89,0x0a,0xd1,0x67,0xe1,0x7a +.byte 0xe2,0x2f,0xcd,0xe3,0x2e,0xbc,0x2a,0xf5,0x1a,0xb1,0x6c,0xc3,0x89,0x5c,0xda,0x63,0xc4,0xc6,0x8e,0xca,0x97,0xf4,0x5d,0x02,0xfc,0x37,0x46,0x72,0x07,0xca,0x3a,0x4a,0xa2,0xc4,0x90,0x14,0x0c,0x3c,0x9c,0x6d,0xb2,0x33,0xe8,0x94,0xfd,0x5e,0xb5,0x53,0x19,0xa5,0xfa,0x2a,0x99,0x26,0x8b,0x34,0x7e,0x8b,0xe3,0xc6,0x50,0x6c,0x3c,0x3f +.byte 0xda,0xe0,0xa4,0x50,0x34,0xa0,0x6a,0xdc,0x06,0xac,0xee,0x77,0x9a,0xa0,0xc1,0x8b,0x4f,0x82,0x71,0x1b,0x5e,0x3d,0xef,0xcd,0xcf,0x19,0x44,0x01,0x80,0x65,0x1a,0x1c,0xbd,0x5f,0x50,0x4a,0x6c,0xa2,0x7f,0x82,0x74,0xa6,0x59,0x39,0x46,0xc1,0x87,0x5b,0xcb,0x70,0x21,0x5e,0xcf,0x1e,0x61,0x73,0x01,0xe6,0x1b,0x0e,0x94,0xf9,0x16,0x91 +.byte 0x1b,0x42,0x99,0xee,0x62,0x62,0xc3,0x02,0xbb,0xaf,0x5f,0xcc,0x98,0x09,0xd5,0xd7,0xdf,0xb8,0xed,0xb9,0xb3,0xde,0x4a,0xfc,0x22,0x8b,0x47,0xc2,0x60,0x31,0x89,0x4f,0x6a,0xbb,0x88,0xc4,0x02,0x25,0x65,0x7b,0x7c,0x2b,0x47,0xf5,0x83,0x99,0x0e,0x0a,0xf5,0x49,0x8c,0x32,0xd5,0x04,0x05,0x7f,0xe0,0x59,0xd5,0xb8,0x9a,0xf7,0xa0,0x3d +.byte 0x67,0xed,0x1c,0xc1,0x62,0xb2,0x48,0x8a,0x64,0xa4,0x97,0x74,0x3b,0x9e,0xec,0x04,0xf9,0xa3,0x40,0x85,0xd4,0x39,0x37,0xe1,0x1a,0x64,0x6e,0x9d,0x2a,0xbb,0x6b,0xf5,0xb9,0x65,0xfd,0x1b,0x14,0x23,0x85,0xcc,0xfa,0x69,0x69,0xca,0x09,0xf1,0x64,0x11,0x3b,0x03,0x29,0x46,0x53,0x0b,0x06,0x29,0x29,0x86,0x03,0x40,0x5c,0xa8,0x5b,0xbe +.byte 0xd5,0xa6,0x04,0x2d,0x05,0x91,0x88,0xb5,0x85,0x37,0x37,0x26,0xed,0xf5,0xdd,0x58,0x98,0x53,0xf9,0x26,0x08,0x80,0xae,0x37,0x65,0x42,0xe1,0x4a,0x7b,0x75,0xeb,0x73,0x14,0x27,0x13,0xee,0x40,0xe0,0x39,0x62,0x09,0xaa,0x0a,0xe9,0x22,0x4a,0x6b,0x23,0x10,0x9a,0x60,0xc0,0x24,0x71,0xb5,0xb6,0x92,0xe5,0x2e,0x64,0x0f,0xae,0x23,0x6f +.byte 0x49,0x48,0x60,0x3b,0xe5,0xf7,0xdd,0xc2,0x01,0xb4,0xb0,0xf6,0xf9,0xfb,0x68,0x59,0x79,0x24,0xc3,0x4c,0x16,0xed,0x00,0xcc,0xa9,0x6f,0x83,0x43,0xf7,0x6c,0x1b,0x2e,0x9c,0x52,0xd3,0x0a,0x4a,0x10,0x5c,0xb8,0xbc,0xe9,0xe0,0xa0,0x69,0x1d,0x4c,0x5f,0x20,0xd8,0xba,0x16,0xc5,0x82,0xad,0x79,0x76,0x53,0x4c,0x4b,0x0e,0xb0,0x98,0xa6 +.byte 0xdd,0xd7,0x8b,0x1b,0x2f,0x9a,0xa5,0x6d,0x5b,0x11,0x97,0x3b,0x90,0x61,0xde,0x44,0x9a,0xe4,0xda,0xc7,0x15,0x32,0xea,0x0e,0x5e,0xc2,0x3c,0x88,0xb1,0x78,0x67,0xdb,0xb4,0x1a,0x65,0xa1,0x14,0x7c,0xb7,0xe6,0x7c,0x34,0xf4,0xb1,0xa0,0x1a,0xdf,0x8e,0x50,0x1e,0x6f,0x64,0x84,0xdb,0x91,0x3d,0x9f,0x03,0xa3,0x62,0xa8,0x05,0x48,0x32 +.byte 0xbd,0xee,0x64,0xde,0xd7,0xf4,0x65,0x30,0x48,0x6c,0x66,0x8f,0x31,0x93,0xc3,0x25,0xd4,0xe0,0x9e,0xd5,0x61,0xb7,0x6c,0xe5,0x8b,0x79,0x4b,0x5f,0x2b,0xa8,0x8f,0x17,0x31,0xef,0x1e,0x93,0x8f,0xcf,0x2b,0x49,0x01,0x6a,0x72,0xe8,0x83,0x95,0xc6,0x91,0xff,0x79,0x6f,0x50,0xeb,0xa5,0x69,0xe4,0x0e,0xcf,0x68,0x5d,0x19,0xc3,0xe4,0x73 +.byte 0xf4,0x08,0x5b,0x0d,0xd4,0x27,0xa7,0xc0,0x06,0xd8,0xa5,0x5e,0x56,0x1a,0xdd,0xf3,0x5e,0xd5,0x83,0x54,0x86,0xb4,0xbc,0x6c,0xc4,0xf4,0x34,0x6a,0x85,0xd9,0x29,0x67,0x90,0xaa,0xb4,0xaa,0x85,0xaf,0x04,0x90,0x3c,0x33,0xb7,0x7c,0x77,0xeb,0xcc,0xab,0xc0,0x4b,0xe0,0xd4,0xb6,0x40,0x24,0x7c,0x85,0x7c,0xd8,0xf3,0xfc,0x32,0xad,0xbd +.byte 0x43,0xcd,0x54,0xa9,0x94,0x51,0xba,0x0f,0x1e,0xbb,0x79,0xf5,0x31,0x29,0xf0,0x8e,0x20,0x62,0xd1,0x38,0x99,0x32,0x05,0x81,0x88,0x64,0x51,0x50,0x31,0xa4,0x38,0x55,0x31,0x86,0x77,0x0b,0x0f,0xcf,0x00,0xe4,0x50,0x9d,0x26,0x98,0xc1,0x3d,0x0c,0x7e,0xec,0x99,0xbe,0x18,0x38,0xf0,0xcd,0xc9,0x98,0x80,0x1c,0x56,0xb4,0xf9,0x15,0xb4 +.byte 0xdd,0x74,0xb5,0x37,0xd2,0x2b,0x24,0xb1,0x18,0xfd,0x40,0x48,0xba,0xa3,0x1a,0xec,0x71,0x01,0xcf,0xd9,0xe2,0x1c,0x4d,0x1f,0xad,0x91,0x1e,0x6f,0x15,0x99,0xe6,0xd3,0x40,0x92,0xa9,0xfd,0xb5,0x6e,0xf6,0xfc,0x0a,0xff,0x07,0x19,0x2f,0xd7,0x5f,0x1b,0x62,0xb7,0x66,0x5c,0x51,0xff,0x36,0x5d,0x97,0x23,0x51,0xa5,0x29,0x2c,0xe5,0xce +.byte 0x21,0xd4,0xa3,0xdc,0x31,0xaf,0xf0,0xfe,0xa0,0x71,0xc0,0xa3,0xeb,0xdc,0xd6,0x17,0x1d,0xa5,0xd0,0xc2,0xdd,0x21,0x9d,0x91,0x3f,0x9d,0xee,0xa2,0xe1,0x7e,0xfa,0x4c,0xe0,0x8b,0x13,0x3e,0x76,0x7e,0xc0,0x62,0xf5,0x6f,0x79,0x0e,0xda,0xc9,0xc6,0x74,0xd0,0xe1,0xae,0x03,0x51,0xe3,0x7b,0x46,0x65,0x7d,0x0e,0x7b,0xb4,0x18,0xf6,0x7e +.byte 0x28,0x0a,0xbd,0xc5,0xfd,0xb6,0xff,0x20,0x88,0xdb,0xa0,0x65,0x87,0xa6,0x0b,0x3d,0xb5,0xa3,0x36,0x9c,0x26,0x50,0x8d,0xad,0x7f,0x19,0x78,0xd3,0x4f,0x34,0x2b,0xae,0x09,0xb1,0xf5,0x1b,0x6d,0xa0,0xed,0x83,0x90,0xc2,0x52,0xfe,0x72,0x46,0xf2,0xca,0xd8,0x42,0x39,0x76,0xce,0x99,0xcd,0x68,0x8f,0xc8,0x3b,0x25,0x54,0x1d,0x32,0x4a +.byte 0xd5,0x93,0x01,0xbd,0x6d,0xa8,0xcc,0x66,0x49,0xc7,0x5d,0x8f,0xd3,0x85,0x08,0xcb,0xa8,0x70,0x2b,0xa9,0x8f,0xed,0xb9,0x9d,0xea,0xe5,0x75,0x9f,0x8f,0x1e,0x8f,0xff,0x4b,0x4f,0x00,0xd3,0x3a,0x2a,0xd4,0x68,0x15,0xae,0x6e,0xe5,0x5d,0x80,0x74,0x78,0x97,0x90,0x7b,0x1e,0x2a,0x9a,0x4b,0x53,0x07,0xe9,0x58,0x24,0x7f,0x42,0x9c,0xc8 +.byte 0xfc,0x0f,0x51,0xb7,0xbc,0xde,0x1e,0xf0,0x43,0xb0,0x48,0x61,0xd3,0x7f,0x89,0x3f,0x65,0x44,0x14,0x86,0xfe,0x24,0x5f,0xcd,0xf4,0xda,0xac,0x8d,0xc5,0xdb,0xa5,0x3d,0x9c,0x5d,0xa8,0xee,0x75,0xc0,0x0b,0x3d,0x93,0x2e,0x6b,0xd6,0x71,0xf7,0x8a,0x48,0xcf,0xbd,0xd5,0x38,0xb5,0x0b,0x8b,0x44,0x3f,0x86,0x59,0x07,0x25,0x2e,0x75,0xe6 +.byte 0x16,0xe7,0x78,0x5a,0x8a,0xfc,0x4f,0x48,0x27,0x30,0x2f,0x32,0x4a,0xf1,0xa6,0xe0,0x44,0x85,0xbc,0x50,0xbc,0x0e,0xab,0x1b,0xf7,0x64,0x1a,0xd2,0x25,0xe9,0xf7,0xaf,0x32,0x14,0x33,0xa7,0xbc,0xa5,0xd7,0xb0,0x3c,0xc8,0x42,0xdd,0x2d,0x91,0xde,0xed,0xdc,0x89,0x57,0x91,0xb1,0x9a,0x5b,0x7d,0x63,0xbb,0xcb,0x4b,0xe2,0x04,0xf2,0x32 +.byte 0x1a,0xdf,0xaf,0x96,0xc9,0xbc,0x50,0x51,0x57,0xcd,0xac,0x9e,0xa5,0x21,0x99,0x81,0xaa,0x2a,0x93,0xbc,0x79,0x7d,0x52,0x0c,0x5c,0x73,0x41,0x48,0x47,0x4b,0x9f,0x71,0xfe,0x8b,0xef,0x65,0xa4,0x18,0x8b,0xe9,0x42,0x62,0x09,0x9d,0x1d,0x4f,0x01,0x51,0xc4,0xfd,0x44,0xb0,0xf4,0x02,0x16,0x9a,0xef,0xa2,0xa8,0xa8,0x15,0xca,0xcf,0x55 +.byte 0x14,0x4a,0x7f,0x3a,0xc2,0x2d,0x46,0xcf,0xc7,0x5a,0xa1,0xeb,0x69,0x1a,0xbf,0xf7,0x54,0xa6,0x16,0xdf,0x4c,0xf2,0xf2,0xb0,0xa9,0xc2,0x2f,0xcd,0x64,0x50,0xac,0x4e,0x43,0x02,0xe1,0x4e,0xd4,0xdf,0x01,0x36,0xaa,0x2b,0xb2,0x05,0xcf,0x22,0xcc,0x3e,0x0a,0x7f,0x25,0x17,0xa3,0x12,0x72,0x94,0x51,0xe8,0x32,0x20,0x05,0x36,0xee,0x8f +.byte 0x19,0xf2,0xd6,0xe3,0x78,0x4c,0xa9,0x57,0xc0,0xa6,0xea,0xef,0xc4,0x25,0x65,0xb8,0x92,0x17,0x99,0xa9,0xa3,0x8f,0x60,0xb9,0x5b,0x65,0x1e,0x1d,0x6e,0x6c,0x11,0x6f,0x9f,0x49,0x97,0x15,0x5c,0xbf,0x9b,0x7e,0x6b,0x4d,0xdb,0x0b,0xb6,0xb8,0xf6,0xe0,0xd8,0x05,0x67,0x78,0xfc,0x27,0xf3,0x0b,0xf7,0x98,0xc1,0x2d,0x46,0x46,0x15,0x22 +.byte 0x66,0xff,0x9d,0x31,0x12,0x56,0xcb,0x5a,0xc1,0xed,0x2f,0x9f,0xc7,0xff,0xd6,0x46,0x64,0x70,0x7c,0xa7,0xd5,0x84,0xd5,0x8d,0x6a,0x02,0xc9,0x9d,0x76,0xb0,0x9c,0xe5,0xd2,0x66,0x07,0x1d,0x64,0xb5,0x21,0xb3,0x61,0x1d,0x3b,0x19,0x85,0xfa,0xe6,0xdb,0x81,0xa1,0x22,0xf2,0x23,0x7c,0x56,0x2a,0x4c,0x21,0xfd,0x3e,0x45,0x9e,0x86,0x9c +.byte 0x12,0xec,0x8a,0x13,0xa2,0xe1,0xf2,0xd5,0xd4,0x1f,0x35,0xdc,0xd9,0x48,0x8a,0xd1,0xa6,0x78,0xf6,0x7b,0xc7,0x69,0x23,0xec,0x3e,0x10,0xd6,0x31,0xf6,0xdf,0xfb,0x06,0xa3,0x5d,0x21,0x4e,0xe8,0xe6,0xcc,0x7a,0x60,0x12,0x87,0x03,0x1d,0x28,0xd5,0x1a,0xaf,0x79,0x30,0xbe,0x8c,0xdd,0x8c,0x32,0x49,0x8d,0xfd,0x54,0xc6,0x50,0xf8,0x9a +.byte 0x54,0xa6,0xc3,0x72,0x17,0x13,0x1c,0xe1,0x1a,0x93,0x57,0xc0,0x5a,0xd5,0x93,0x90,0x0e,0x74,0x82,0x2a,0xc4,0x8a,0x14,0xc1,0x77,0x23,0xf5,0xcd,0x62,0x86,0x86,0xf4,0x7c,0x0c,0xd7,0x82,0x21,0xe7,0x7e,0x49,0x4f,0x35,0xbc,0xdf,0xd7,0x28,0x2f,0xd7,0xd9,0x51,0x51,0x68,0xff,0x21,0x4f,0xea,0xd4,0x72,0x6b,0xc3,0xb2,0x5d,0xf1,0xa7 +.byte 0xa4,0x4e,0xf2,0xa6,0xe0,0xe9,0xa2,0xd1,0xd6,0x42,0xdf,0x87,0x38,0x78,0xa5,0xb6,0xee,0x15,0xaf,0xd6,0x84,0x0d,0xba,0x3c,0xdb,0x5a,0x18,0x90,0xdf,0xee,0xb1,0xa2,0x19,0xfd,0xa9,0x7c,0xdc,0x62,0x79,0xf2,0xc5,0x75,0x7b,0xb8,0x6d,0xc8,0x97,0x38,0xc0,0xaf,0x2d,0xbb,0xa7,0xaf,0x2a,0x9e,0x87,0x08,0xce,0xa0,0xd3,0xfc,0xe2,0xc4 +.byte 0xa5,0x77,0x4b,0xfe,0xbb,0x10,0x22,0x78,0x2c,0xb6,0x2c,0x57,0xef,0xb1,0xde,0x54,0xa0,0x08,0xc8,0xee,0xeb,0xd1,0x7c,0x58,0x62,0xd8,0xa4,0xa8,0xe6,0x99,0x9a,0xaa,0x97,0x66,0xac,0x6e,0xc4,0x24,0xfe,0x62,0xca,0xfb,0x61,0xac,0x7b,0x74,0x8b,0x30,0x80,0x8e,0x29,0xb3,0x5a,0xca,0x37,0x4b,0xfb,0xbc,0x99,0x7f,0x66,0xf6,0xa5,0xed +.byte 0xe5,0xb6,0x4c,0x7b,0x99,0x58,0x9f,0x95,0x8e,0xbd,0xfc,0x84,0x66,0x03,0xe2,0x7d,0x45,0x1d,0xc2,0x8b,0xd5,0xd6,0x48,0x8f,0x8b,0x95,0x98,0xf4,0x5f,0xe1,0x3e,0x5b,0x62,0xf0,0x5c,0xaa,0x88,0xa6,0x57,0x01,0x98,0xaa,0xbb,0xf9,0x52,0x13,0x1f,0xa1,0xb9,0xaf,0xc9,0x55,0xb9,0xb5,0x78,0x8c,0xa9,0x20,0x96,0x97,0xf8,0xbb,0xed,0x5a +.byte 0x13,0x4a,0xfc,0xe4,0x22,0x16,0x04,0xac,0x57,0xcb,0xcf,0xd1,0xf5,0xf1,0xc3,0xa3,0x85,0xb8,0x43,0xed,0x68,0x72,0xe4,0x55,0x50,0xe1,0x8d,0x49,0xcd,0xc7,0x60,0xc4,0x3d,0x06,0xe6,0x2c,0xd1,0xaa,0x31,0xaf,0x4a,0x39,0x5b,0x25,0xbf,0x14,0x9c,0xa5,0x0e,0x6e,0xb4,0xea,0xdf,0x46,0x7c,0x9c,0x24,0xa9,0xca,0x58,0x92,0x2e,0xf9,0xe2 +.byte 0xc6,0x37,0x33,0x33,0xe0,0x1f,0xf3,0xf2,0x81,0x0c,0xef,0xae,0xa4,0x0e,0xff,0x8b,0xdd,0x06,0x09,0x3a,0x26,0x3f,0x18,0x8c,0x09,0x76,0x27,0x90,0x5f,0x4c,0xb4,0x74,0x8a,0x00,0xbf,0x7d,0x57,0x5d,0x4d,0x8b,0x6f,0x0f,0x4c,0x02,0x37,0x7d,0xb3,0x6a,0x1b,0xb5,0x15,0x3f,0xc3,0x57,0x10,0x0c,0xeb,0x34,0x9b,0xf2,0xa4,0x09,0x3f,0x60 +.byte 0xcb,0xf9,0x23,0x79,0x7f,0x06,0xd4,0xb0,0xff,0x53,0xb6,0x4f,0x53,0xa2,0x59,0xe5,0x6a,0x56,0x72,0x51,0x8d,0xc9,0x67,0xb7,0xdc,0xbd,0xd9,0x8c,0xa3,0x59,0x12,0xef,0x4a,0x65,0x26,0x4a,0x64,0x60,0xfc,0x98,0x23,0x2d,0x89,0xf5,0x30,0x2d,0x2b,0x19,0x71,0xa7,0x21,0x6d,0x97,0xe7,0x37,0xcb,0x80,0x84,0x16,0xa1,0xdd,0x14,0xfb,0xc3 +.byte 0xb6,0x03,0xa4,0x33,0x72,0xa5,0x3a,0x30,0xf8,0x1a,0x19,0x7f,0x7d,0xb1,0xce,0x66,0x17,0x0f,0x39,0x59,0xf9,0xa6,0xbe,0x13,0xe3,0xaf,0xe6,0x37,0x8d,0x0d,0x52,0xa1,0xc6,0x7f,0xe7,0xc0,0x0d,0x86,0x4e,0xfb,0x22,0x50,0x3e,0xdc,0x18,0xc9,0xb9,0x0d,0x1f,0x99,0xb9,0x44,0xb1,0x07,0xcc,0xa7,0x70,0x58,0x33,0x88,0xde,0x93,0x9a,0xbf +.byte 0x7e,0x37,0x8b,0x97,0x6a,0xda,0x27,0xd8,0x67,0xb4,0xba,0xb8,0x49,0x93,0x68,0x59,0x77,0xc2,0x72,0x4a,0x5f,0xe6,0x94,0xf9,0x30,0xd5,0xdc,0x55,0x50,0x35,0x44,0x5e,0x46,0xfa,0x48,0xa9,0xa7,0xd4,0xd0,0x1d,0xbb,0xb2,0x53,0x3f,0x43,0xf7,0xf0,0xae,0x2c,0xc8,0x03,0xca,0x8a,0x5d,0x8e,0x98,0x85,0x3d,0x62,0x7a,0x7a,0xde,0x9b,0xb6 +.byte 0xe1,0x3f,0x49,0xe1,0x81,0x54,0x66,0x10,0x20,0x92,0x52,0xbc,0xf9,0xba,0x85,0xa3,0xdb,0x32,0x57,0x89,0x8b,0xe1,0xd7,0x0b,0xe8,0xb3,0x5a,0x38,0x65,0x7f,0x47,0xd8,0x4b,0x2b,0xca,0x54,0x47,0xbf,0x0f,0x82,0xfb,0x88,0xcc,0x29,0xfb,0xe4,0xf5,0x7a,0x89,0x9d,0xca,0x23,0x2b,0xe9,0xd1,0xaa,0xe2,0x32,0xd9,0x5e,0xc7,0x89,0x59,0xe9 +.byte 0xc1,0x58,0x0b,0xa7,0x0f,0x18,0x00,0xc1,0x75,0x73,0x09,0xb0,0xd4,0x17,0xe2,0x98,0xe5,0x52,0xf9,0x42,0xe3,0xbb,0xe1,0x38,0xb7,0x3a,0x0a,0x1b,0x40,0xf5,0x96,0x41,0x5a,0x2a,0x0d,0x06,0xf3,0xc7,0xa0,0xcd,0x5c,0xa1,0x86,0xb4,0x2b,0x90,0x73,0xda,0x96,0xef,0x81,0x4e,0xc4,0x33,0x20,0x5a,0x60,0xb4,0x49,0xe7,0x3b,0x0b,0x2e,0x8c +.byte 0x1c,0x45,0xb1,0x02,0x19,0xb3,0x77,0x4e,0x7d,0x25,0x7c,0x5f,0x10,0x7b,0xe7,0x5d,0x66,0xe5,0xd0,0x7a,0x65,0xea,0x13,0xa9,0x55,0x10,0xe1,0xb6,0xeb,0x79,0x14,0x06,0xd2,0xb2,0x07,0x90,0x8b,0x9e,0xea,0x47,0xbb,0x47,0x82,0x03,0xd7,0x97,0xc5,0xfb,0x54,0x16,0xd1,0x68,0x54,0xbe,0x66,0x5c,0xfd,0xc5,0xfb,0xd8,0x05,0x0c,0x5c,0x78 +.byte 0xa6,0x41,0xa1,0x64,0x33,0xd2,0x74,0xe6,0x44,0x35,0xb8,0xf4,0x68,0x57,0xe4,0x33,0x9b,0x1e,0xb9,0xd0,0x19,0x00,0x6e,0xda,0x76,0xa8,0x73,0xd8,0xca,0xab,0x6d,0x85,0x43,0xfb,0xc3,0xa2,0x38,0x6c,0xbd,0x66,0x00,0x59,0x30,0x2b,0x25,0xf5,0xd8,0xb5,0xb9,0x73,0xca,0x05,0x81,0x78,0x2a,0x37,0x0c,0x03,0xaa,0xd4,0x72,0x24,0x51,0x1a +.byte 0x7e,0x56,0x36,0x76,0x4f,0x0c,0x08,0x20,0x45,0x82,0xc0,0x29,0xb5,0xa6,0xde,0x17,0xc4,0x99,0x90,0x4b,0xd8,0xd8,0x3e,0xaf,0x31,0x38,0xfc,0x92,0x5c,0x50,0x70,0x32,0x77,0xc0,0x90,0xaa,0x7a,0x9a,0xf3,0xb1,0x68,0xa8,0xd8,0xe1,0xc7,0x34,0x08,0x41,0x0a,0xef,0x08,0x81,0x16,0x0c,0x0c,0xc4,0x8e,0x21,0xa6,0xb5,0x29,0x8e,0xf6,0x5a +.byte 0x49,0x6e,0xf7,0x2e,0x29,0xdf,0xe7,0xab,0x90,0xea,0x97,0x50,0x97,0x6b,0xc1,0x78,0x72,0x0d,0x39,0x31,0x7a,0xca,0x7c,0xc8,0x74,0x69,0x9d,0x7b,0x49,0x33,0x6b,0xae,0x24,0x50,0x72,0xa5,0x8b,0xbb,0x2b,0xdb,0x06,0x15,0x69,0xb0,0x78,0x98,0xe6,0x10,0x78,0x34,0x89,0xf4,0xcf,0xc4,0x57,0x81,0x48,0x62,0x2d,0xa1,0x78,0x42,0x17,0x07 +.byte 0x55,0x95,0x68,0x13,0xc2,0xf1,0x93,0x5a,0x50,0x46,0x68,0x1d,0x64,0x30,0x55,0xa2,0x66,0x75,0xf5,0x6d,0x1a,0x12,0x82,0xeb,0xcf,0xad,0x13,0xf3,0x8c,0x63,0x51,0x66,0xd0,0xd3,0x1c,0xd1,0x6b,0xb7,0xb2,0x7d,0xe9,0xbb,0xd9,0x5c,0xb5,0xb5,0x2c,0x77,0xc8,0x2c,0x38,0x86,0xb0,0x6d,0x6b,0x30,0x4d,0x93,0xd4,0x1f,0xea,0xbd,0xab,0x95 +.byte 0x1d,0x91,0x8e,0x6b,0xcc,0x6d,0x98,0x99,0x21,0x21,0x2d,0x6b,0x46,0x91,0x1b,0x8d,0xcb,0xb3,0x4c,0x3b,0x28,0x5d,0x14,0xba,0xd2,0xd1,0x48,0x48,0xdf,0xca,0xc5,0xfa,0xc4,0xda,0x39,0xb3,0xa8,0x72,0x8a,0x1a,0x59,0x18,0xc7,0x17,0x6d,0xd6,0x3f,0x8c,0xf2,0xe5,0x3d,0x9c,0x49,0x1f,0x3b,0x5f,0xfb,0x8e,0x86,0x96,0x3a,0x56,0xe0,0x51 +.byte 0x13,0x4f,0x4f,0xff,0x35,0x01,0x8e,0xd0,0x62,0xc8,0xf1,0x23,0x73,0x85,0xaa,0xcc,0x71,0xd7,0x04,0x7f,0x15,0xf7,0x6c,0xc0,0xf6,0x8d,0xd9,0xe9,0x65,0x79,0x76,0xfb,0x69,0xd7,0x7e,0x3f,0xed,0xfd,0x6f,0x33,0x0c,0x21,0x15,0x2e,0x1e,0xe2,0x37,0xdf,0x05,0xc0,0x16,0xae,0xa5,0x1e,0xff,0x10,0xed,0xaf,0xd2,0xc6,0x1a,0x72,0xc2,0x42 +.byte 0x33,0x86,0x27,0xf4,0x63,0xc0,0xbb,0x48,0x78,0x87,0x60,0x5f,0x89,0xad,0x60,0xfd,0x1b,0xab,0xba,0xf7,0x07,0xd5,0x24,0x43,0xfa,0x47,0x24,0x5b,0x89,0x30,0xa8,0x2c,0x84,0xdf,0x09,0x6f,0x86,0x46,0xb5,0xe6,0x0b,0x62,0x69,0xc5,0xb6,0x67,0x14,0xe0,0xb9,0x00,0x7c,0xb4,0x55,0x1c,0xac,0x75,0x7b,0xc0,0x04,0x7a,0xc1,0xf1,0x28,0xe6 +.byte 0xd5,0x50,0x2e,0x9f,0xbe,0xde,0xfd,0x9a,0x6f,0x0c,0xbc,0xfc,0x21,0xa0,0x63,0xbf,0x77,0x51,0x4a,0x82,0x11,0x17,0xef,0xd3,0x55,0xcb,0xc3,0x6b,0x62,0x4a,0x12,0xa9,0x33,0x96,0x2e,0x8f,0x13,0x89,0x72,0x60,0x74,0xfa,0x44,0x64,0xd7,0xe8,0x05,0xb7,0xdb,0x86,0x9a,0x7d,0x92,0xe2,0x45,0x0f,0xb8,0x9a,0x94,0x5c,0x4c,0x64,0x49,0xf4 +.byte 0xde,0x6d,0x4b,0x0d,0xc5,0x50,0xe5,0xcd,0xaa,0x8d,0x30,0xb1,0xa6,0x14,0xb3,0xc7,0x1d,0xd9,0x88,0xb5,0xce,0xf1,0xb5,0x69,0x03,0xd5,0x21,0xbd,0xa9,0x59,0xd4,0x7d,0xe4,0xad,0xe7,0x6e,0x60,0xfb,0x71,0xb9,0x77,0xf4,0xc2,0xbf,0xe5,0xc3,0xb8,0x18,0x92,0x8a,0x17,0xf2,0x06,0xf8,0xd8,0xc9,0xcd,0xbf,0xfa,0xed,0x1b,0xf0,0xa4,0x32 +.byte 0x7e,0x52,0x1d,0x44,0x45,0x3d,0xc6,0x29,0x05,0xd9,0xaa,0xc6,0x94,0xa2,0x7c,0xfb,0x42,0x32,0xf2,0x42,0xc6,0xac,0x26,0xf1,0x69,0xe3,0x43,0xe2,0xe1,0xff,0xa9,0xda,0xf7,0xf9,0x69,0x47,0xcd,0x24,0xa5,0x4c,0x9a,0xe0,0x15,0xa8,0xb3,0x08,0xfb,0xb3,0x07,0x81,0x18,0x62,0xb5,0x2f,0xd0,0xf1,0x59,0x8d,0xc2,0xf3,0x93,0xd2,0x4d,0x17 +.byte 0xaf,0x22,0x5f,0x98,0x47,0x83,0x14,0x77,0x05,0x05,0x9c,0x0b,0x04,0x6f,0x83,0x83,0x68,0x86,0x95,0x8e,0x03,0xe7,0x5d,0x54,0xdf,0x6e,0x05,0xb6,0x12,0x9a,0x69,0x3a,0x88,0xcc,0x66,0xff,0x0c,0xa1,0x4f,0x09,0x5a,0xfd,0x58,0xd0,0xbb,0xa8,0x00,0x26,0xa2,0xfe,0xaa,0x2a,0xc1,0x22,0x9b,0x5e,0xc2,0x93,0xa0,0x08,0x34,0x93,0x47,0x48 +.byte 0x9e,0x48,0xfd,0x0a,0x9f,0x3e,0xdb,0xe1,0xcf,0x4c,0xc4,0x07,0x74,0xf6,0xc8,0x30,0x39,0x35,0x23,0x8f,0x7c,0x9f,0xf8,0xd5,0xeb,0x93,0xb6,0x5d,0x50,0x14,0xcf,0xf5,0x3d,0x95,0x2e,0x41,0x06,0xb1,0x48,0x33,0x8f,0x0f,0x05,0xba,0x60,0xf9,0x14,0xd9,0x09,0x24,0x18,0x1b,0xe7,0xef,0xd9,0x57,0xd7,0xef,0xec,0x73,0xe7,0xf3,0xfd,0xa8 +.byte 0xd3,0x3f,0x48,0xbe,0x17,0xf2,0x1d,0x00,0x2f,0x98,0xc7,0x76,0xda,0x1c,0x97,0x28,0x07,0xfe,0xe8,0xcb,0xfc,0xa0,0x6e,0x61,0x6c,0xb3,0x28,0x72,0xa8,0xb6,0x5f,0x78,0xa1,0x24,0x46,0xb0,0xff,0x7f,0x56,0xad,0x9a,0x52,0x2d,0xc3,0x40,0xf4,0xd3,0x65,0x63,0x4e,0xa1,0xb9,0x48,0x33,0x75,0x50,0xbb,0x18,0x06,0x07,0xa3,0xa7,0xe4,0x56 +.byte 0x69,0xbc,0xa3,0xd8,0x20,0xa3,0xba,0x3e,0xc2,0x2f,0xe2,0x2c,0xe1,0xc9,0x74,0x75,0x56,0x2b,0xa8,0xde,0xc8,0x40,0x64,0x7f,0x60,0xfa,0x35,0x6f,0x2d,0x6f,0x14,0xb0,0xb3,0x45,0x3c,0x5d,0xcd,0x84,0x4f,0xb8,0xc6,0xbf,0xaa,0x49,0xfd,0xd4,0xbf,0x14,0xe2,0x1e,0x12,0xbf,0x67,0x78,0xf9,0xee,0x1e,0x75,0x96,0xe1,0x89,0x89,0xbe,0xc7 +.byte 0x2f,0x33,0x6c,0xa4,0x38,0xc2,0x2d,0x0f,0xc0,0xa5,0x4e,0xd4,0xf8,0x65,0xc6,0x5b,0xd8,0x4d,0x5a,0xbb,0x1b,0xfa,0x56,0x37,0x72,0x6f,0x4f,0xd9,0x0f,0x22,0xdf,0x98,0x2b,0x92,0x68,0x83,0xb7,0xe4,0x01,0x1e,0x4a,0x2e,0xa6,0xf6,0x8e,0x4f,0xdc,0x45,0xac,0x5b,0xc9,0x47,0xad,0x96,0x22,0xce,0x72,0x66,0xc0,0xe3,0x5e,0xcf,0x1c,0x9d +.byte 0x1b,0x96,0x99,0x08,0x6e,0x17,0x6c,0x46,0x77,0x4c,0x4e,0xe3,0x68,0xa5,0xf2,0x84,0xea,0x64,0xaf,0xe6,0x36,0x55,0xdd,0x0b,0xd6,0xe4,0x06,0x4d,0xc4,0x2b,0x34,0xbb,0x49,0xf9,0xac,0xe4,0xb2,0xbc,0xb3,0xa5,0x48,0x39,0xe5,0xc6,0x8e,0xc1,0xfb,0xe9,0x26,0x47,0x81,0x8c,0xcb,0xad,0xa0,0xbf,0xa9,0xf2,0xb3,0xfb,0xbb,0x14,0x52,0x7a +.byte 0xf1,0xa4,0x01,0x88,0x06,0x30,0x7e,0x69,0x1c,0x97,0xff,0xfc,0x1c,0x0d,0x2b,0x69,0xaf,0x93,0xa0,0x0f,0x04,0xa3,0x9c,0xf2,0xde,0x61,0xa7,0x45,0x1c,0xa6,0x9c,0x2f,0x58,0x35,0x59,0x95,0x3f,0xff,0xbd,0xbc,0xc9,0xe5,0x2c,0xe3,0x48,0x1e,0xdc,0x36,0xe1,0xbe,0x30,0xc2,0xcb,0x80,0x8f,0x17,0x90,0xcd,0x0f,0x2d,0x94,0x3b,0x44,0xb5 +.byte 0x6a,0x62,0xf1,0x93,0x2f,0xbd,0xf5,0x55,0xed,0xf6,0xfb,0xae,0x01,0x99,0x5a,0xc9,0xe3,0xed,0x78,0x39,0x65,0x81,0x06,0x5f,0xc3,0xb3,0x2e,0x8c,0xcf,0x59,0x47,0x75,0xbe,0x56,0x25,0x22,0x05,0xd8,0x0a,0x1b,0xbe,0x60,0xb2,0x8a,0xac,0x28,0xaf,0xb1,0x84,0x38,0x6e,0xba,0xc5,0x91,0x17,0x3a,0x63,0xa9,0xff,0x89,0x56,0xed,0x36,0x32 +.byte 0xde,0x12,0xa8,0x38,0x92,0xbb,0x51,0xdd,0x6b,0x5e,0x97,0x68,0x8d,0x27,0x10,0xd9,0x83,0x98,0x02,0xd2,0x8b,0x75,0x88,0xae,0xd0,0x22,0x69,0x95,0xc1,0x6d,0x2d,0xec,0x01,0xd9,0x06,0xc4,0xd0,0xa2,0x45,0xc9,0xd6,0x48,0x49,0xeb,0xdb,0xd5,0x83,0x7a,0x06,0xc5,0x88,0xd9,0x6f,0xb4,0xba,0xc2,0xbc,0x83,0x23,0x0a,0x9f,0xe1,0x4f,0x54 +.byte 0x34,0x80,0x78,0x2f,0x82,0xd2,0x86,0x20,0xa6,0x73,0xb7,0x4e,0x93,0x6c,0x8a,0xd4,0xe8,0x46,0xed,0xa8,0xe2,0xd5,0x1e,0xe3,0xb3,0xdb,0xde,0xbc,0x94,0x02,0xb7,0x37,0x10,0x94,0x1e,0x0b,0xc7,0xbd,0x60,0x38,0x04,0x29,0x92,0xef,0x01,0xe0,0x20,0x55,0xb3,0x0d,0x50,0xc9,0x0f,0x6a,0x46,0x5f,0x55,0x73,0xd5,0xec,0x2e,0x1e,0xa4,0x0f +.byte 0xf4,0x3c,0xbe,0x5c,0xb7,0x81,0x78,0x0c,0xf0,0x7d,0x38,0x32,0x6a,0x9c,0x43,0x19,0x0f,0x51,0xe6,0x2f,0xe6,0xcd,0x09,0x07,0x92,0x93,0xfd,0x22,0x1b,0xec,0x75,0xfe,0x3a,0xf4,0xbe,0x8b,0xb6,0x9c,0x58,0xca,0xf8,0x9f,0xe5,0x8f,0x47,0x37,0xfb,0x6e,0xc9,0xe2,0xd7,0xb4,0x78,0xcf,0x0c,0x06,0xa8,0x30,0xd0,0x54,0x2e,0x84,0x79,0x44 +.byte 0xc2,0x32,0xd3,0x8f,0x47,0xb6,0xa3,0x57,0x30,0xe5,0x72,0x44,0x54,0xd4,0xfb,0xe4,0x84,0xf8,0x4d,0x0e,0xbe,0xc8,0xf5,0xda,0xbb,0xb6,0x03,0xa2,0x47,0xaf,0xab,0x85,0xb2,0x3b,0x05,0x0b,0xb1,0x95,0x8c,0x3c,0x33,0x0e,0xee,0x5a,0x01,0x82,0x18,0x9b,0x8a,0x31,0x9e,0xde,0x75,0xed,0x0a,0x1e,0x0d,0x84,0x69,0x8a,0x51,0x57,0x12,0xc0 +.byte 0x73,0x9f,0x24,0x65,0xe6,0x73,0xdb,0x2a,0x10,0x2a,0x76,0xc6,0x82,0xd7,0x06,0x68,0x03,0x78,0x83,0xf1,0xcb,0x32,0x80,0xf8,0x48,0xdf,0x2e,0x37,0xee,0x35,0xe2,0xd9,0x62,0x18,0xf5,0x54,0xbe,0x75,0x94,0x59,0x2b,0xa4,0xae,0x74,0x2e,0xaf,0xdf,0xc2,0xec,0x9d,0xe0,0x60,0x27,0x4b,0xef,0xb3,0x0b,0xa1,0x88,0x20,0x17,0x4f,0x07,0x83 +.byte 0xfa,0x9a,0x30,0x3e,0x8a,0xc0,0xcf,0x4d,0x39,0xdd,0x92,0x46,0x62,0x9d,0x20,0x80,0x77,0x82,0x12,0x01,0x08,0x99,0x38,0xa8,0x92,0xa7,0xc0,0x61,0x75,0x6e,0x97,0xb4,0x4c,0x89,0x5a,0xf5,0x9f,0xee,0x08,0x56,0x66,0x0f,0x86,0xc3,0x49,0xee,0x3f,0x63,0x47,0x74,0xca,0x4c,0xc8,0x8a,0x8e,0x5a,0x70,0x80,0x65,0x10,0xb6,0x55,0x55,0x1f +.byte 0x75,0x6a,0xf5,0x3b,0xfb,0x43,0xf2,0x21,0xd7,0xa6,0x5d,0x84,0xc1,0x56,0x8e,0x03,0x99,0x32,0xbd,0xf2,0x98,0xc4,0xdd,0x0e,0xf8,0xf1,0x33,0xbf,0xfb,0x2c,0xff,0x48,0x1a,0xd9,0x03,0x14,0x0a,0x88,0x4f,0x74,0xc4,0x7f,0x54,0x1b,0xa4,0x7c,0x52,0x84,0x24,0x89,0x16,0xc3,0xd7,0x4c,0x02,0xd4,0x4c,0xab,0x0d,0x07,0xf8,0xd8,0xe8,0x28 +.byte 0xa3,0x04,0x14,0x5b,0xca,0xc3,0x72,0x86,0x0b,0x42,0x1b,0x5d,0x1a,0xbb,0x0d,0xa4,0xc6,0x0c,0x25,0xa2,0xdb,0x23,0x4b,0xa9,0x7c,0xdb,0xb5,0x09,0x08,0xed,0x23,0x01,0x3d,0x7b,0xa3,0xe2,0x24,0xa5,0xbd,0x56,0xe6,0xb5,0x13,0x32,0x0a,0x68,0xb3,0x14,0x0a,0xd6,0xf5,0xe6,0xc9,0x7a,0xb6,0xb6,0x31,0x47,0x15,0x66,0x7b,0x08,0xfb,0x20 +.byte 0xa4,0x3f,0xca,0xc9,0x02,0x3a,0x5a,0x4e,0x1f,0x30,0x50,0x5c,0xc6,0x20,0x50,0x02,0x1e,0xf3,0x5f,0x62,0x0c,0x70,0x72,0xa8,0x5c,0x51,0x47,0x88,0x0a,0x06,0x1a,0x5a,0xa6,0x4a,0xe3,0x05,0x99,0xc8,0x0e,0x26,0x32,0x22,0x78,0x58,0x36,0x84,0x42,0x71,0xb4,0x3e,0x26,0x7d,0xe1,0x3d,0x76,0xd4,0xde,0x54,0xd0,0x78,0x17,0xe7,0x01,0xd7 +.byte 0x93,0xae,0x58,0x77,0xde,0xc4,0xa6,0xfd,0x15,0xbf,0x21,0x59,0x19,0x8d,0xc4,0xf4,0xd5,0xf0,0x9a,0x22,0xe8,0x92,0x2f,0x9d,0x84,0x96,0x19,0xbb,0xc8,0xf4,0x76,0xfe,0xb4,0x43,0xa1,0xc9,0x87,0x65,0xf0,0x8d,0x95,0xeb,0x13,0xa3,0x9a,0xdc,0x42,0x8b,0xb6,0x2d,0xfa,0x94,0xb8,0xc1,0x51,0x75,0xdb,0xaa,0xe5,0x19,0xf3,0x05,0x66,0xf1 +.byte 0x24,0xa7,0xf8,0x56,0x49,0x6d,0xe0,0xbc,0x9f,0xf7,0x39,0x1d,0xcb,0xec,0x7e,0x39,0xda,0x73,0xee,0x50,0x0f,0x19,0x2e,0xc4,0x54,0x44,0x06,0x1a,0x9b,0x46,0x9a,0x68,0x96,0xdf,0x3e,0x3a,0x23,0x9f,0x5d,0xac,0x92,0x51,0x9d,0xe5,0xcf,0x5f,0x7f,0xb4,0xd8,0x93,0xe3,0xd8,0x80,0xe9,0x96,0xd2,0x04,0x94,0x37,0x6e,0x49,0x44,0xff,0xb3 +.byte 0xa5,0x97,0x35,0xb7,0x2e,0x04,0xae,0x2d,0xf2,0x77,0xc7,0x19,0x3a,0xd9,0x35,0x9a,0x91,0x18,0xe1,0xb9,0xb0,0x22,0x99,0x76,0xb7,0x69,0xe6,0xc6,0xf1,0xee,0xdf,0xce,0x35,0xd5,0xbe,0xc7,0x02,0x57,0x2b,0x4a,0x72,0x6a,0xe3,0xd7,0x75,0xab,0xa5,0x2a,0x6a,0xeb,0x76,0x92,0xab,0x37,0x41,0x64,0x4d,0x0a,0x99,0x82,0xc3,0xe1,0xab,0x70 +.byte 0x4c,0xaa,0x85,0x90,0xc2,0x2f,0x5a,0x91,0x31,0x93,0xeb,0x8e,0x1f,0xec,0x30,0x40,0xb3,0x95,0xc8,0xef,0x06,0x74,0xc5,0xb6,0x65,0xf9,0x10,0xe7,0xce,0x9b,0x12,0xee,0xe8,0x02,0x5f,0xa5,0x0b,0x42,0x34,0x38,0xb3,0x7b,0x89,0x30,0xac,0x25,0x81,0x2c,0x48,0x22,0xa6,0xa8,0x4e,0x6b,0x1a,0x53,0x2b,0x35,0xa9,0xbe,0x5d,0x4e,0x97,0xc6 +.byte 0xc2,0x9a,0x51,0xff,0xcc,0x21,0x42,0x98,0x85,0x64,0x37,0x79,0x3e,0x33,0x10,0xbc,0x26,0x0b,0x71,0xb0,0x15,0x01,0xc7,0x21,0x1f,0x62,0x55,0x8d,0x91,0x57,0x10,0x6d,0x3e,0x95,0xa8,0x38,0xb2,0x9d,0x8e,0x90,0x73,0x4a,0x2f,0x48,0x08,0x09,0xfb,0x76,0x24,0xc4,0x91,0x7d,0x56,0x60,0xd4,0x96,0x46,0x61,0xc9,0xc8,0x3e,0xd0,0xc4,0x51 +.byte 0xc5,0x03,0x2e,0xb6,0xec,0x64,0x56,0x54,0xbe,0x7a,0x77,0x19,0x0d,0xbc,0xdb,0x77,0x67,0x23,0xb2,0x32,0xd3,0x39,0xe8,0x9b,0xf0,0xe7,0xc0,0xf1,0x35,0x9a,0x9d,0x13,0x3f,0x10,0x0d,0xb6,0x89,0x49,0x93,0x64,0x9c,0x64,0x6f,0xdf,0x4d,0x6c,0x50,0x4a,0xfb,0x87,0x2f,0x58,0xcd,0xe7,0x12,0x89,0xe8,0x3d,0x14,0xf2,0xff,0xc3,0x51,0xe0 +.byte 0x33,0x8a,0x98,0x37,0xc2,0x71,0xea,0x61,0xde,0x64,0xa3,0xae,0xad,0xff,0x70,0xe9,0x7f,0x89,0x7a,0xee,0x3e,0xec,0x71,0xa2,0xd5,0xa2,0xa3,0x46,0xde,0x93,0x35,0x78,0x18,0x43,0xd5,0xa0,0x61,0x0b,0x82,0x4b,0x59,0x80,0xb7,0xc4,0x63,0xb2,0xf6,0x45,0xe3,0x4e,0x73,0x94,0xdb,0xdf,0x86,0xec,0x32,0x5a,0x0c,0x7d,0xc7,0xf1,0xda,0x35 +.byte 0xb8,0xdf,0x5b,0x31,0xfc,0x85,0x7b,0xcf,0xe6,0x19,0xc2,0x13,0xab,0xee,0x06,0x1f,0x30,0xa7,0x6f,0x50,0xfe,0x38,0x84,0x83,0xd5,0x08,0x2c,0x13,0x81,0x7d,0x5d,0x2d,0x7d,0xa5,0x9c,0x56,0x77,0xb8,0x0e,0xc0,0x4e,0x7e,0x16,0x0b,0x79,0xa5,0x87,0x64,0x9f,0x7c,0x8e,0x44,0x3f,0x6d,0x24,0x62,0x6c,0xc7,0x24,0x23,0x08,0x03,0x5f,0xd1 +.byte 0x7c,0x3e,0x63,0x69,0xff,0x7d,0xbf,0xe2,0xc7,0xc0,0xdf,0x77,0x9c,0x02,0x5d,0xaf,0xb9,0x80,0xaa,0x50,0x66,0xd7,0xb4,0x2b,0xc9,0xef,0x3f,0xbc,0xf5,0x35,0x92,0xc7,0xea,0xcc,0xf6,0x5a,0x4f,0xe6,0xcd,0x09,0x0f,0xb9,0x1f,0xe7,0x05,0xb1,0x2d,0xe3,0xc1,0x08,0xf7,0x59,0xe1,0x7c,0x74,0xad,0xbc,0x25,0x03,0x97,0xba,0x72,0xe8,0x0e +.byte 0x78,0x18,0xf1,0x42,0xc2,0x7e,0xbf,0x4e,0x89,0x07,0xe3,0x80,0xfa,0x25,0x09,0x0f,0x3f,0xac,0xce,0xea,0xe0,0xe5,0x15,0xff,0x7a,0xb4,0xc7,0x7f,0x58,0x17,0x89,0x55,0x7f,0x85,0xeb,0x07,0x38,0x92,0x68,0x03,0x6d,0x33,0x5c,0x2b,0xfd,0xd6,0x53,0x8d,0x1f,0xbc,0xac,0x82,0xda,0x88,0xc6,0xf3,0x1f,0xa3,0x25,0x0a,0xa4,0xae,0x94,0x91 +.byte 0x06,0xda,0xe7,0x04,0x9b,0x84,0x08,0x01,0x79,0xa0,0x79,0x20,0xf8,0x4b,0xd9,0x94,0x24,0xa8,0x59,0x59,0xd6,0xaf,0xe9,0xc1,0xcd,0xb4,0x8b,0xf0,0x49,0xda,0x13,0x9a,0x4e,0x53,0x31,0x74,0xbb,0x8c,0x51,0xfa,0x95,0x9a,0x27,0x73,0x0c,0xde,0x58,0x73,0x12,0x4b,0x3c,0xe6,0x69,0x48,0x9e,0x63,0xbf,0xe5,0x2e,0xf7,0x2e,0x6a,0xe3,0x05 +.byte 0x5f,0x70,0xa6,0xfa,0x29,0x9c,0x12,0x2d,0x2d,0xb1,0x32,0xc0,0x52,0xbd,0x1a,0x88,0xae,0x0d,0x92,0x4d,0x17,0xa8,0x02,0x81,0xf6,0xca,0x1a,0x46,0x70,0x58,0xc6,0x6f,0x45,0x50,0x64,0x9a,0x1b,0x36,0x3e,0x40,0x68,0x84,0x3a,0xb1,0xb7,0xc5,0xe9,0xb5,0x60,0xe4,0x75,0x4e,0x8c,0x27,0xc4,0xd3,0xcd,0xe5,0xa9,0x0c,0x23,0x85,0x3e,0x22 +.byte 0xcf,0xa6,0x62,0x29,0x82,0xd4,0x37,0x6e,0x98,0x67,0x43,0xc7,0x43,0x67,0xfd,0xa6,0x0c,0x7f,0x76,0xa8,0x18,0xf0,0xa9,0x76,0x69,0x9a,0x8f,0x1c,0x88,0x7e,0x22,0xce,0x1c,0x3e,0xf2,0x0b,0x3a,0xf1,0xd0,0xf6,0xcc,0xfe,0xf5,0x58,0xef,0x50,0x7c,0xe4,0x3f,0xef,0xb4,0x5b,0xce,0xbc,0x55,0x5b,0x9e,0x9e,0x49,0xa5,0x5d,0xd5,0x0b,0xe7 +.byte 0x71,0x0b,0xbf,0x7c,0x82,0xee,0x2c,0xd7,0x7e,0x97,0x75,0x9c,0xea,0x04,0x7c,0xde,0x16,0x96,0x0b,0x89,0x50,0x83,0xf2,0xd2,0x1d,0xba,0x2b,0x0d,0x4f,0x79,0x5f,0x29,0xb0,0xf5,0x07,0x68,0x19,0x5d,0x5d,0xc8,0x31,0x95,0xe8,0x50,0x15,0x76,0x7d,0xab,0x3b,0x9a,0xa8,0x8a,0xea,0x5b,0xaf,0xc6,0xfc,0x1a,0x2d,0x4d,0x14,0xee,0x7c,0x2b +.byte 0x6e,0xaa,0xe1,0xc4,0x0e,0x17,0x87,0x30,0x67,0xca,0x19,0xa5,0xb7,0xed,0x3b,0x8e,0xca,0x98,0xd0,0xa7,0x0b,0x0e,0x0f,0xd8,0x40,0x9b,0xb6,0x7c,0xef,0xd1,0x83,0xb7,0xaf,0x43,0x64,0x9e,0x66,0x9a,0xdf,0xb6,0x5c,0xf0,0x36,0xea,0xfb,0xea,0x0a,0x03,0x8e,0xde,0x3d,0x3f,0x69,0x3a,0x38,0x91,0x62,0x41,0x8e,0x70,0x11,0xd7,0x59,0x05 +.byte 0x3e,0x52,0x36,0x43,0x6e,0x09,0x67,0x35,0x8e,0x0c,0x6d,0x3b,0xb4,0x6b,0xc7,0x8f,0xe8,0x53,0x77,0x6d,0x4d,0xa9,0x0d,0x2a,0x96,0xd3,0x1b,0xe8,0x3a,0x8f,0xfa,0xd2,0x17,0xfd,0x1f,0xce,0x90,0x99,0xb0,0xda,0x15,0x1c,0xe0,0xe9,0xff,0xc8,0x8b,0x5a,0x1a,0x0d,0x83,0x1a,0x99,0xaa,0x73,0x43,0xb1,0x68,0x10,0xed,0xf5,0xbd,0x67,0xdb +.byte 0x1f,0x1c,0x12,0x9b,0xa2,0x91,0x3b,0xe6,0x72,0x9a,0xc8,0x55,0x23,0x5a,0x05,0x4b,0x7b,0x9c,0xa2,0x28,0xc6,0xcb,0x0a,0xac,0x59,0x25,0xb2,0x7a,0xb2,0x02,0xae,0xc4,0x61,0x7d,0x5c,0x90,0x1e,0xcd,0xce,0xd6,0x9f,0x6f,0x1b,0x93,0x6d,0xec,0xb6,0xa0,0xcf,0x6e,0xea,0x4e,0xfb,0x23,0xf2,0x39,0xab,0x7f,0x45,0x40,0x16,0x4f,0xf6,0x0e +.byte 0x09,0xf7,0x85,0x03,0xee,0x3c,0xaa,0xb1,0x0e,0x07,0x2b,0xee,0x65,0xca,0x9a,0xa9,0xc8,0x78,0x97,0x77,0x38,0xaf,0x32,0x97,0x0a,0x2f,0xd4,0x7a,0xf8,0x04,0xc7,0xcc,0xce,0xe6,0x9d,0x10,0xe7,0xf6,0xc1,0x4c,0x24,0xd1,0xcc,0x79,0x53,0x5a,0xc8,0xf9,0xfc,0x08,0x2a,0xe1,0xb4,0x51,0xc4,0x12,0x3e,0x50,0xf9,0x73,0x9d,0x42,0x85,0x4b +.byte 0x4e,0x68,0x7c,0x7b,0x8f,0xe1,0xc6,0xe2,0x07,0xa9,0xc1,0xca,0x35,0x56,0x58,0x40,0x8a,0xc7,0x6d,0x7f,0x9d,0x91,0xff,0x32,0xc3,0xc9,0x58,0x56,0x67,0xc5,0x51,0x2d,0x3f,0x98,0x16,0x4b,0x95,0x4e,0xed,0x83,0x7a,0xe5,0x6b,0x21,0x91,0x4a,0x8d,0xcc,0x26,0x21,0x59,0x4e,0xe6,0x05,0x6a,0xd2,0x83,0xba,0x6b,0x8a,0x4f,0xe5,0x03,0xd1 +.byte 0x81,0x5b,0x84,0x07,0x9a,0xe1,0xf5,0x55,0x5c,0xfa,0x9f,0xad,0x15,0x20,0x7f,0xc6,0xc8,0x3a,0x7e,0xd8,0x2e,0x56,0x96,0x38,0xc2,0xe8,0xae,0xfb,0x28,0x44,0x6e,0x23,0x64,0xdd,0xfd,0x2e,0x86,0xea,0x7a,0x97,0xa4,0x50,0xdb,0x1f,0xa5,0x8e,0xaa,0x54,0x56,0x41,0x51,0x91,0x47,0xf7,0x5b,0xb5,0x33,0x74,0x65,0x41,0x9c,0xc8,0x19,0xde +.byte 0x66,0x2d,0x18,0xb2,0x05,0xc6,0x24,0xd1,0xd5,0xd5,0x4e,0xba,0x25,0x8c,0x28,0x7d,0xf4,0xb5,0x2a,0xc4,0xef,0xac,0xa0,0x82,0x78,0x96,0xe3,0x7a,0x5f,0xca,0xd9,0xc4,0x38,0xa9,0xb8,0xfa,0x7e,0x04,0x16,0x5f,0x4e,0x02,0xf5,0x45,0x6c,0x7f,0xbe,0x8e,0x94,0x45,0xaa,0x85,0x5a,0x74,0x36,0x47,0xb7,0xc5,0x2b,0xfd,0xc3,0x70,0x4b,0x39 +.byte 0x66,0x9c,0x84,0x45,0x32,0xb9,0x32,0xd6,0x1f,0x72,0xdb,0x81,0x81,0x72,0x6d,0x54,0x55,0x0f,0x83,0x92,0xca,0x8e,0xd1,0xf9,0x18,0x4d,0x24,0xd0,0x9a,0xa6,0xc4,0xfb,0x36,0x34,0xe6,0x9a,0xac,0xe6,0x25,0xe5,0x28,0xf0,0x09,0xd7,0x10,0x41,0x66,0xd5,0xf3,0x43,0xa8,0x03,0xcb,0x8e,0x5a,0x1b,0x3a,0x70,0x9e,0x33,0x79,0x42,0xe3,0xea +.byte 0x74,0x45,0x44,0x64,0x89,0xa1,0xf9,0x0f,0xe8,0x8f,0x40,0xcb,0x60,0x63,0x0d,0x11,0xe3,0xda,0x37,0x94,0x4d,0x8f,0x84,0x89,0x92,0x46,0x4a,0xf3,0x9f,0xce,0xfc,0xaa,0x4c,0x0c,0xfc,0x8d,0xff,0x6f,0x73,0x91,0xce,0x55,0x47,0x4f,0x7c,0xcc,0x01,0x27,0xd1,0x4f,0xbe,0x70,0x05,0xbb,0xee,0xb4,0xdd,0x4f,0xf5,0xca,0xb3,0xab,0x7e,0x68 +.byte 0x8b,0x21,0x03,0x8a,0xfe,0x63,0x43,0xfd,0x06,0xf6,0x0a,0xa2,0xae,0x5b,0x88,0xed,0x4c,0xbd,0xa4,0xf7,0x84,0x0b,0x43,0xba,0xed,0xf1,0x58,0x7e,0xea,0x5c,0xc0,0x90,0x1c,0x50,0x60,0x6b,0x06,0x93,0xe5,0x3f,0xe1,0xec,0x5e,0x3e,0xd0,0x14,0x15,0x04,0x6a,0x13,0x4c,0x28,0xa7,0x7b,0x7b,0xeb,0xb0,0x59,0xa2,0x08,0x33,0x73,0xa2,0xc5 +.byte 0x57,0x51,0x8e,0xd3,0x8b,0xbd,0x83,0xe4,0xd3,0x5b,0x6f,0x6b,0x61,0xf7,0x7d,0x17,0xed,0x7f,0xea,0xcf,0x56,0x03,0x87,0x2f,0x50,0xbc,0x73,0xc8,0x84,0x7c,0xb1,0xfd,0xe6,0x6c,0x95,0x79,0x97,0x7f,0xd9,0x8d,0x0d,0x4e,0x21,0xde,0x82,0x5c,0xb7,0x96,0x22,0xff,0x2f,0xaa,0x85,0x25,0x62,0x65,0x8b,0xc1,0x3a,0xa9,0xa3,0xef,0xc6,0x27 +.byte 0x1f,0xfe,0xc5,0x5d,0x27,0xee,0xe0,0x5a,0x7b,0xa2,0xdc,0x6d,0xad,0xa1,0x60,0xcd,0xcc,0x8f,0x6e,0xa2,0xfd,0xaa,0x64,0x12,0x86,0x61,0x5a,0x61,0x93,0x3e,0x9c,0x0d,0xe5,0x1a,0x8a,0xb4,0x00,0xbb,0xc6,0x31,0x0f,0xb5,0x9b,0x1c,0x75,0x3e,0xdf,0x02,0x86,0x9c,0xf4,0x3e,0x10,0xf2,0x5e,0x47,0xb4,0x1f,0x73,0xb9,0x09,0xe4,0xcc,0x3d +.byte 0x45,0xe0,0xa7,0xa9,0x27,0xc9,0x26,0x13,0x81,0x81,0x94,0xed,0x16,0x16,0x44,0x22,0x74,0x9b,0x0c,0x98,0x8b,0xbc,0x88,0x01,0x26,0x0e,0x04,0xa4,0x74,0x85,0xa7,0x7e,0x65,0x1e,0x83,0xa5,0xb5,0x73,0xbb,0xa7,0xd8,0x54,0xf6,0xa7,0xc3,0xb7,0x75,0x7c,0x56,0x6b,0x26,0x11,0x2f,0x4f,0x14,0x56,0x39,0x58,0x2a,0xee,0xf1,0x33,0x9f,0x7b +.byte 0x76,0x9b,0xf6,0xcc,0xa6,0x3f,0xd7,0xc5,0x0a,0x3d,0xfa,0x20,0x5a,0x79,0xf5,0x1e,0x51,0xa6,0x5c,0xcf,0xab,0x41,0xbf,0x30,0x91,0x85,0xb2,0x84,0x8d,0xd8,0x69,0xa2,0x4e,0xd6,0x8d,0x57,0x2e,0xaa,0x6b,0x68,0x24,0xd7,0x4d,0xf7,0xb2,0x23,0x1b,0x37,0x4e,0x8e,0xc6,0xbb,0x00,0x95,0x06,0x84,0x99,0x10,0x15,0xa3,0xcc,0x33,0x6e,0x69 +.byte 0x5f,0x5b,0xb0,0x0f,0xd4,0x76,0x1f,0x5d,0xba,0x05,0x87,0x49,0xbd,0x35,0x11,0x8b,0x57,0x4d,0xa0,0x17,0x3d,0xc2,0xc3,0xde,0x61,0x0f,0x75,0x4a,0x92,0x44,0xc0,0x4b,0x6c,0xa0,0x78,0x95,0xa7,0xf5,0x0b,0x8b,0xf9,0x20,0xb1,0x01,0xdc,0x67,0x37,0x68,0xd7,0x41,0xb2,0xe7,0x9d,0x24,0x6f,0x14,0x36,0x74,0xe4,0x23,0x0b,0x9e,0xec,0xe0 +.byte 0xaa,0xa2,0x4a,0x1f,0x69,0x1a,0xac,0x52,0xf5,0x67,0x11,0x76,0x7b,0xed,0x07,0x73,0xd6,0x5d,0x94,0xd6,0xab,0x9e,0x85,0xdc,0xfc,0xa8,0xa6,0x40,0x15,0xa2,0x56,0xcf,0x74,0x22,0x25,0xcd,0xf5,0x9c,0x39,0x8c,0xf5,0x89,0xd9,0x2d,0x82,0x82,0x59,0x30,0x8c,0xe7,0x0b,0x85,0x93,0xad,0x42,0x6a,0x49,0x9a,0x19,0x54,0x12,0xcf,0xf8,0xb7 +.byte 0x33,0xc2,0x75,0xf7,0xcf,0x91,0xdb,0xda,0x8e,0x4e,0xc5,0xc0,0xe5,0xe6,0x52,0x03,0xdd,0x11,0x18,0x5b,0x21,0xa2,0x7e,0x6c,0x43,0xd3,0x38,0xa2,0x92,0x55,0x6f,0xd4,0xf6,0x8f,0x95,0xf1,0x70,0x1b,0xf3,0x86,0x53,0x5e,0xd7,0x17,0x5f,0x81,0x7f,0x58,0x53,0x35,0x53,0x40,0x95,0x0b,0x46,0x13,0x8e,0x9e,0x6e,0x4c,0xc4,0xe0,0x11,0x4d +.byte 0xb7,0xf8,0x68,0x89,0xfa,0xe5,0x60,0x33,0xe2,0xc3,0xf8,0x8e,0xcf,0xf9,0xc9,0xd8,0x06,0xd0,0x0b,0x25,0xcd,0x4d,0x2f,0xbe,0x5e,0x81,0xe0,0x02,0x74,0x93,0xd0,0x8a,0x33,0x77,0xab,0xe6,0x17,0xd5,0xb1,0x53,0x6b,0xfc,0x94,0x88,0x1f,0xc4,0xf3,0x42,0x3e,0x16,0x54,0xf6,0xa5,0x05,0x58,0xe4,0x91,0x79,0x51,0x9d,0x29,0xd1,0xd1,0x69 +.byte 0xa9,0xb5,0xd1,0x2c,0xe5,0x47,0xea,0x2d,0x67,0x59,0xea,0xa4,0x0e,0x1f,0xde,0xfb,0xe2,0x16,0xe1,0xc2,0xb2,0x36,0x3b,0x15,0x84,0x19,0xc1,0xee,0x37,0x49,0x8f,0x1c,0xf8,0x3d,0xc7,0x94,0x39,0xab,0xf2,0xdc,0x7c,0x53,0xc1,0xb4,0x89,0x65,0x73,0xe0,0x91,0x8a,0xa3,0xa7,0xb4,0x05,0x7d,0x18,0x9d,0x2d,0x13,0x76,0x9d,0xfc,0x9d,0xef +.byte 0x0b,0x02,0x61,0xc0,0x2d,0xa0,0x6e,0x2b,0x0b,0xbb,0x9f,0x53,0xc1,0x20,0xcc,0x58,0xbe,0xf3,0x56,0xb4,0x68,0x82,0x30,0xfc,0xb6,0x4f,0x7d,0x03,0x56,0x37,0x68,0x97,0xa8,0xea,0x9d,0x20,0x2b,0x46,0xd7,0xdc,0xce,0x8b,0x1a,0x29,0x5c,0xa0,0x35,0x34,0x86,0xcb,0xbb,0xdb,0x8b,0xc4,0x6b,0x2b,0x4f,0xab,0xc5,0x8b,0x34,0x92,0x5c,0xbd +.byte 0x2f,0xf4,0xd6,0x40,0xf8,0xc7,0x0e,0x4b,0x1e,0x8d,0xf6,0x45,0x2e,0xa9,0xb0,0xec,0xdb,0xe0,0x71,0x23,0xe4,0x89,0xa9,0x22,0x89,0x20,0x12,0x94,0xa0,0x00,0xca,0xb0,0xf3,0xac,0xda,0x27,0x4d,0xcf,0x76,0xd3,0xa9,0x2b,0xc4,0x0a,0x5d,0xd0,0x7f,0xf8,0x8f,0xa7,0xb3,0x5e,0xf6,0xb8,0x36,0xc0,0x50,0x6e,0x23,0xb8,0xb8,0x55,0x0e,0xf9 +.byte 0x3c,0xed,0x24,0xde,0xf0,0xb3,0x83,0x09,0xae,0xfa,0xed,0x71,0xb1,0xd8,0xd1,0x9e,0x35,0xf6,0x2c,0x83,0x89,0xc7,0x86,0x25,0xb1,0xc3,0xac,0x09,0xf9,0x52,0xe4,0xf1,0xc7,0x82,0x54,0x33,0xa4,0xbe,0xc6,0x92,0xa2,0x54,0x43,0x25,0x51,0x6a,0xa3,0x87,0x45,0x32,0x9f,0x46,0x37,0xf2,0x55,0xbd,0xb5,0x54,0x7b,0xcf,0xfb,0xf8,0x3e,0x80 +.byte 0x35,0xb6,0x76,0xc0,0x4c,0xe7,0xf7,0xd8,0x69,0x4c,0xa7,0x53,0xb5,0x5a,0xbf,0xa4,0x6d,0x99,0xc0,0x54,0x92,0x16,0x9b,0x89,0x57,0x32,0x20,0x71,0x31,0xa9,0x72,0xb8,0xca,0x69,0x0b,0x3f,0x82,0xaf,0x72,0xa6,0x99,0x08,0x17,0x02,0x9e,0xc1,0xa5,0x83,0x53,0xa7,0xea,0x11,0x17,0x23,0x1d,0xbf,0x82,0x29,0x93,0x49,0x15,0xe8,0x60,0xc6 +.byte 0xf2,0x04,0x9a,0xa3,0x34,0x1e,0xa2,0x4f,0xe1,0xa8,0x4d,0xd4,0xc2,0x92,0x84,0x6a,0xa9,0x15,0x68,0x91,0xd3,0x73,0x8f,0x6f,0xab,0x24,0x63,0x8a,0x9d,0x51,0x79,0x8f,0x90,0x74,0x4d,0x67,0xeb,0x21,0x12,0x07,0x6d,0xee,0x7f,0x9e,0x07,0xbb,0xfc,0xe6,0xad,0x02,0x69,0x85,0x02,0x48,0x44,0x32,0x39,0xf7,0xd5,0x1c,0xd9,0xb2,0xe7,0xdd +.byte 0x5a,0x92,0x42,0x3d,0x75,0x7f,0x06,0x14,0x18,0xda,0x1e,0x9d,0xa0,0x36,0x8b,0xe8,0xf3,0x69,0x1c,0x2a,0x93,0xc5,0x98,0x0c,0xd3,0xe0,0x5c,0x08,0xbb,0x21,0x02,0xfb,0xa9,0x5e,0xe8,0x18,0x44,0x01,0xb6,0x61,0x17,0x9c,0x2e,0xff,0x61,0xc1,0xe4,0xf6,0x08,0xbe,0x08,0xaa,0x74,0xaa,0x7d,0x8e,0x51,0x49,0xc4,0x52,0xd0,0xe7,0xc4,0xfc +.byte 0xf0,0x05,0x6f,0xff,0x47,0x64,0xda,0x13,0xcb,0x7f,0x74,0x45,0x35,0x67,0x3c,0xe4,0x2f,0xd3,0xd8,0x6c,0xc3,0xb9,0x71,0x9f,0xe0,0xc8,0x8c,0x21,0xb9,0x4f,0xdf,0x2f,0xfe,0x5b,0x26,0x0d,0x0e,0x9f,0xa5,0x38,0x1b,0x9a,0xc8,0xca,0x63,0x37,0xd1,0xf3,0x8e,0x78,0xcb,0x29,0x28,0xc2,0x24,0x67,0xb2,0xa9,0xc5,0xb0,0xc0,0xc0,0xb7,0xb9 +.byte 0xcb,0xb9,0x1d,0x31,0x76,0xc8,0x84,0x8e,0x99,0x0b,0xec,0x90,0x56,0x45,0xed,0xe7,0x11,0x2f,0x01,0x93,0x22,0x13,0x21,0x33,0x75,0x41,0xf3,0xf4,0x1d,0xb6,0x0d,0x60,0x65,0xe8,0xf2,0x0d,0x91,0x02,0x8c,0xa2,0x95,0xa8,0x82,0x65,0xd7,0x9b,0x7d,0xeb,0x6c,0x8a,0x77,0x04,0x79,0x6d,0x89,0x9d,0xf6,0x0e,0x47,0x10,0x1f,0x0d,0x8d,0x87 +.byte 0x47,0x72,0xce,0x3e,0x7e,0xa5,0xc4,0x67,0x46,0x18,0x67,0xc2,0xb6,0xee,0xe4,0xad,0xdd,0xb1,0x40,0x96,0xf0,0x5d,0x46,0x3f,0x23,0xc8,0xef,0x06,0x26,0xd2,0xf7,0x88,0x6f,0xb2,0x3d,0xf3,0xd7,0x9c,0x1b,0x11,0x65,0xf9,0xdd,0xbd,0x67,0x18,0x6c,0x2a,0x1f,0x00,0xef,0xf3,0x64,0x42,0x9e,0x96,0x5e,0x9e,0xe8,0xeb,0x39,0x5f,0x3f,0x87 +.byte 0xce,0xb7,0x1f,0x8f,0x3b,0xff,0xd8,0x93,0x9a,0xc7,0xbb,0xb4,0xc7,0xb5,0xa9,0xaa,0xcb,0x80,0x03,0x96,0x04,0xdd,0xce,0x60,0x28,0xe0,0x9d,0x74,0xf1,0x7f,0x8a,0x44,0xe4,0x10,0x42,0x12,0xd4,0xaa,0x7a,0x43,0x24,0x3b,0xaf,0x20,0x7f,0xaa,0x0f,0xda,0x00,0x14,0xe3,0x30,0x55,0x18,0xd0,0xcf,0x03,0x23,0xe2,0x56,0x94,0xa7,0xc3,0xca +.byte 0xde,0x1b,0x80,0xad,0x36,0x61,0x23,0xf1,0x2c,0xc3,0x05,0x18,0x82,0xb7,0x55,0x91,0xe7,0x51,0x92,0x6c,0xe5,0xdb,0x5f,0x1e,0xf3,0xfd,0x72,0x49,0xb4,0xe7,0xa4,0x03,0x21,0xfb,0xb5,0x75,0xe4,0xd2,0x9f,0x17,0x64,0x36,0x5b,0x8b,0x9a,0x33,0xeb,0x02,0xa7,0xfe,0xbd,0xb2,0x03,0x89,0xe7,0xba,0x65,0x96,0x56,0x9e,0x9f,0xde,0xbc,0xed +.byte 0xa5,0x4c,0x69,0xed,0x04,0x42,0x5b,0x1d,0x20,0x37,0x45,0x10,0xbd,0xf7,0x14,0x92,0x58,0x41,0xb5,0x87,0xf9,0x47,0xb5,0xa6,0xa8,0xc1,0x53,0x71,0x59,0xcb,0x9d,0xa4,0xa9,0x7d,0x42,0x64,0x2a,0x74,0xa9,0x64,0x1b,0x08,0xca,0x9a,0x30,0x92,0xfc,0x48,0xff,0x30,0x63,0x88,0x12,0xa7,0x48,0x03,0xb9,0x5a,0xf6,0xa1,0x51,0x4e,0x51,0xe1 +.byte 0x82,0xe3,0xe7,0x5d,0x6d,0xab,0x53,0x06,0xbd,0x85,0x43,0xb1,0x67,0x1a,0xf3,0x14,0xe7,0x0a,0x15,0x93,0x3a,0x0d,0xac,0x30,0x1d,0xe0,0x2c,0xae,0x54,0xef,0x60,0x0b,0xb0,0xee,0x20,0x14,0x71,0xc2,0x27,0x4e,0x08,0x6e,0x0f,0x32,0x53,0x2a,0xb0,0x22,0x15,0xe0,0x11,0xd1,0x76,0x65,0xbf,0x3c,0x9c,0x05,0x1e,0x00,0xba,0x58,0x2a,0xdc +.byte 0xac,0xb4,0x8c,0x12,0xe3,0x56,0xca,0xc1,0x6b,0x10,0x11,0x64,0x1c,0x58,0xfe,0xb5,0x6b,0x7f,0xb1,0x67,0x01,0xd8,0x38,0x3e,0x18,0x49,0x0d,0x04,0x9c,0xb4,0x9a,0x34,0xdd,0x18,0x87,0xfc,0x69,0x0d,0xe1,0x9b,0x5c,0x48,0xda,0xa6,0xa3,0x39,0x8a,0xc1,0x5d,0x7a,0x43,0xa2,0xad,0x83,0x6f,0x9c,0x4d,0x90,0xe7,0x87,0x10,0x35,0x39,0xb8 +.byte 0xa2,0x19,0xa5,0x42,0xb2,0x8f,0x50,0xf4,0x1e,0xa4,0x08,0x7b,0x16,0x99,0xa1,0xa5,0x07,0x52,0xc8,0x62,0xa5,0x2c,0xc1,0x10,0xb1,0x81,0xa9,0x50,0x4e,0x66,0x5e,0x65,0xca,0x28,0x9b,0x5a,0x3f,0xe9,0xc2,0x68,0xb9,0xc3,0x5f,0xe8,0x11,0x27,0xac,0x05,0xbf,0x1b,0x0b,0xcd,0x84,0xa3,0x73,0xdd,0x6f,0x70,0x5c,0xbe,0x54,0xc1,0xbd,0x03 +.byte 0x15,0xe2,0x5f,0x6b,0x12,0x6f,0xb0,0xa4,0x33,0xfc,0x32,0x14,0xcd,0xbc,0x39,0x17,0x68,0xc9,0x00,0x60,0xd4,0x6b,0xf6,0xc3,0x67,0x3e,0xd4,0x09,0xb7,0xf6,0x04,0x3c,0xc5,0x80,0xeb,0xca,0x1e,0xd2,0xc9,0x7c,0x36,0x10,0xc1,0x1e,0xe3,0x52,0x54,0x5d,0xe6,0x34,0x46,0x26,0x7c,0xdd,0x4d,0xa3,0xc2,0x6b,0x73,0x5e,0xa7,0xcf,0x91,0x34 +.byte 0xf7,0xea,0xa8,0x09,0xf3,0xd3,0x14,0x5b,0x0e,0x72,0x0f,0xb7,0xd5,0xfb,0xbd,0xe6,0x19,0x32,0x5d,0x58,0xe1,0x6e,0x5b,0xed,0x4b,0x3b,0x8f,0x94,0x29,0x6c,0x0f,0xac,0xd5,0x69,0x4e,0xa4,0x9d,0xf7,0xbf,0xe0,0x8d,0x5f,0x14,0x66,0x81,0x0b,0xa5,0x3e,0xc6,0xb3,0x90,0x84,0x0e,0xb3,0x40,0x89,0xa0,0x4c,0x7d,0x0b,0x4f,0x15,0x9a,0x1c +.byte 0xe3,0xcb,0x68,0xa5,0x94,0xae,0x67,0xab,0xcd,0x58,0xdf,0x32,0xc7,0x83,0x26,0x1a,0x38,0x7e,0x22,0xe6,0x21,0x7d,0x93,0x94,0xa3,0x20,0xdf,0x47,0x14,0x5d,0x1f,0x71,0x5f,0xb1,0xb6,0xf7,0xe6,0xaa,0xbe,0x09,0x29,0x37,0x06,0xa7,0xda,0x97,0x65,0x76,0xb8,0xaf,0xbc,0x38,0x74,0xea,0x0b,0x8d,0x53,0x27,0x72,0x8e,0x07,0x42,0x2f,0x98 +.byte 0xf8,0x50,0xc0,0x3e,0x68,0x15,0x89,0xb8,0x0e,0xf9,0x47,0xea,0xdd,0x0a,0x94,0x6b,0x88,0x15,0xed,0xc6,0xab,0xc5,0x5b,0x79,0x4f,0x78,0xb7,0x99,0x55,0x69,0x69,0xf0,0x91,0xc0,0xa8,0x32,0x42,0x36,0x4e,0x41,0xb1,0x02,0xdf,0xb8,0xa8,0x64,0x29,0x6b,0x52,0x3f,0x89,0x53,0x8e,0x2a,0x51,0xc9,0x05,0xca,0x9f,0x41,0xc4,0xc0,0x70,0x51 +.byte 0x8a,0x5a,0x2b,0x83,0xa5,0xc9,0x9b,0xf4,0xd2,0x5a,0xb1,0xa2,0xcc,0x51,0x2b,0x74,0x5d,0xc0,0xf2,0x23,0xcb,0x91,0x12,0x3e,0xb8,0x73,0xd3,0x62,0x53,0x25,0x0e,0x58,0x55,0x2f,0xdf,0x7b,0x0e,0x3c,0xbf,0xb6,0xe6,0xd2,0xad,0x20,0x1b,0xea,0xac,0xfc,0xdd,0xe9,0x35,0x49,0x5f,0x90,0x7d,0x4f,0x09,0xb0,0xc5,0x8a,0x11,0x2a,0x2d,0xa1 +.byte 0xf1,0x84,0xca,0x91,0xc9,0x9a,0x7a,0xe0,0x81,0x3e,0x92,0x07,0x32,0xb0,0x3f,0x59,0x1f,0xec,0x07,0x8e,0x8a,0x73,0x12,0x85,0x52,0x3a,0x7c,0xc3,0x1f,0xfe,0x27,0xd7,0x45,0x1a,0xf6,0x97,0x82,0x5a,0x97,0xdc,0x9e,0x70,0x37,0xe9,0xbe,0x35,0x76,0xae,0x15,0x0c,0x9a,0x66,0x69,0xb6,0xbd,0xcc,0x55,0xc9,0x44,0xb5,0x59,0x09,0xe9,0x0b +.byte 0x03,0xa0,0x5e,0x37,0xd1,0xff,0xd9,0xcb,0x5e,0x2a,0x97,0x6f,0x3a,0xee,0xb9,0xc4,0xc9,0xe0,0xb9,0xc8,0xc2,0x9e,0x66,0x0c,0xee,0x05,0x1e,0x12,0xa7,0x2c,0x61,0x7f,0x61,0x1c,0x90,0xbb,0x6a,0xb9,0xd9,0xf3,0x9a,0x5e,0xae,0xfc,0x18,0x15,0x46,0xa8,0x12,0xdd,0x81,0x66,0x44,0x91,0x84,0xbe,0xa8,0x20,0x9a,0x3c,0x0a,0x57,0x32,0xe1 +.byte 0x22,0x3f,0x5d,0xa7,0x11,0xa3,0xeb,0xdc,0xaf,0x93,0xbb,0x2e,0xae,0x64,0x6e,0xbb,0x08,0xa8,0x83,0xb8,0xc2,0xfe,0x25,0x22,0x99,0x08,0x68,0xa8,0x6e,0xda,0xee,0xb2,0x78,0xc9,0x59,0x6b,0xac,0x48,0x5d,0x2d,0x1d,0x8c,0xa8,0xd3,0x4b,0x2d,0x27,0x65,0x01,0x5a,0xe4,0x4b,0x90,0x7c,0xe7,0x23,0xbe,0x90,0xf7,0xf9,0x15,0x2f,0xc1,0x70 +.byte 0x41,0x80,0x54,0xbf,0xfe,0xb0,0x44,0xfa,0x0e,0x3b,0x07,0xa5,0x85,0x40,0x8e,0x21,0x72,0x1d,0x22,0x0c,0x78,0xcf,0x67,0xdb,0xb2,0xbb,0xec,0x78,0x6f,0xcf,0xcd,0x96,0x16,0xf4,0x82,0x56,0xd6,0xa0,0x0c,0x7f,0xb8,0x3b,0xa7,0x4d,0xc4,0x1c,0x6c,0x8f,0xa4,0xe7,0xd2,0x35,0x43,0x17,0xd0,0x0a,0x56,0xc3,0xa6,0xd6,0xf6,0x27,0x95,0xf1 +.byte 0xa6,0x9d,0x5c,0x9c,0xb4,0x41,0x36,0xb5,0x36,0xcc,0xcb,0xbf,0x89,0xbc,0x63,0x21,0x7e,0x08,0x9c,0xdb,0x3f,0x60,0x7d,0x00,0xd0,0xbd,0xb0,0x20,0x2e,0xca,0x82,0x05,0xf0,0xff,0x57,0x56,0xc4,0x4e,0x50,0x58,0x5b,0x54,0x43,0x30,0x90,0x9a,0xf5,0x37,0x34,0x08,0xd7,0x57,0xc8,0x17,0x03,0x42,0x0d,0x42,0x04,0xaa,0xdb,0xc7,0xa7,0xdc +.byte 0x7b,0x10,0xc3,0x87,0x6c,0x0d,0x8d,0x43,0x1b,0x50,0xfa,0x71,0x2e,0x76,0x5f,0x27,0x73,0x0b,0x7f,0x01,0x28,0xb4,0xea,0x3a,0x1e,0x04,0x74,0xb4,0x18,0xa0,0xdd,0x8d,0x41,0x1a,0x20,0x09,0x11,0x9e,0x02,0xe4,0x50,0x37,0xb0,0x20,0x49,0x69,0xfb,0x30,0x82,0xd5,0x03,0x88,0x9b,0x03,0xa0,0x92,0xb1,0x51,0x63,0xcb,0x6a,0x4f,0xa4,0x74 +.byte 0xc9,0x93,0xed,0x13,0x3c,0x6a,0xdc,0x43,0x57,0x87,0x56,0xb8,0xe3,0x30,0x4f,0x63,0x2d,0x7b,0x23,0x8e,0xe3,0x80,0x30,0x03,0x62,0x59,0x9b,0xbd,0xbe,0xc5,0xa9,0x40,0xbd,0x01,0xac,0x2f,0xbf,0x90,0x46,0x30,0x53,0x20,0x74,0x45,0xe4,0x21,0x17,0x72,0x54,0x7f,0x4d,0x90,0xd8,0x72,0x7f,0x7b,0x6c,0x83,0x5b,0x00,0xa6,0x17,0x7d,0x42 +.byte 0x60,0xb5,0xd1,0x0b,0xf2,0x57,0xb4,0x13,0x45,0x7d,0xe4,0x9b,0x29,0x12,0x1b,0x29,0x76,0xd0,0xc0,0x59,0x9f,0x1e,0xa2,0xd7,0x76,0x05,0xe5,0x42,0x73,0x65,0xd3,0xb0,0x58,0x18,0x7a,0x00,0x4c,0xdb,0x0f,0xb2,0xb0,0xb4,0x4c,0xef,0x59,0xfd,0x20,0xca,0x45,0x51,0x82,0xf6,0x4d,0x20,0x96,0x5c,0x11,0x7f,0x33,0x67,0x38,0xea,0x1b,0x1a +.byte 0x10,0x9f,0x60,0x6a,0xe1,0xd3,0x77,0x27,0x1d,0x5d,0x29,0x3c,0x55,0xc3,0x34,0x51,0x37,0x0d,0xe2,0x55,0xf9,0xc3,0xb9,0x7f,0x06,0x68,0x07,0x84,0x05,0x18,0x18,0x64,0xfb,0x44,0xc7,0x62,0x22,0xdb,0x23,0xb3,0x70,0x40,0x73,0xf7,0x3e,0xa7,0xd7,0xe5,0x40,0xad,0xa7,0x54,0x18,0x41,0x95,0x56,0xda,0x80,0xe4,0x5e,0xca,0x0b,0x15,0x6d +.byte 0xc1,0xf5,0xf6,0x30,0x08,0x30,0x21,0x81,0x1c,0x27,0x62,0x2e,0x1a,0xde,0xf9,0x2c,0xec,0x4f,0x70,0x3a,0x6b,0x63,0x1a,0xbb,0x99,0x1b,0xb4,0x82,0xc5,0x81,0xef,0xc3,0x6f,0x12,0xf4,0x22,0xc4,0x32,0x11,0x11,0xba,0x56,0x71,0x47,0x10,0xd7,0xf7,0xe8,0x5b,0x07,0xb6,0x2f,0xa9,0xa9,0xfd,0x4d,0x42,0xe8,0xb7,0x2a,0xbf,0x93,0xb1,0xef +.byte 0x09,0x8e,0xa3,0x6b,0x40,0xcc,0xb1,0x63,0x10,0xb7,0x8f,0x9e,0xd1,0x02,0x2b,0x86,0x86,0xbf,0x44,0x89,0x22,0xf9,0xe5,0xf7,0xad,0x10,0xda,0xd8,0xdf,0xef,0xa0,0x98,0x42,0xad,0x21,0xa8,0x42,0x6f,0x47,0x08,0xf2,0x62,0x9e,0x2b,0xaf,0xc2,0xac,0x71,0x3d,0xd6,0x43,0x65,0x85,0x60,0x17,0xc6,0xa2,0xa2,0x3a,0xd9,0x34,0xeb,0x0b,0x6d +.byte 0x04,0xf7,0x6f,0xa5,0x39,0xf5,0xfa,0x71,0x58,0x9d,0xe9,0xe5,0x44,0x8c,0xd3,0xf0,0x62,0x8a,0x2f,0x73,0xf6,0xab,0xf4,0x09,0xe1,0xd1,0x23,0x0f,0x7c,0x5c,0x63,0xa4,0x34,0x26,0xeb,0xca,0xe5,0x96,0x1c,0x31,0x61,0xcc,0xa1,0x1f,0x95,0x9c,0xd9,0xb5,0x2d,0x19,0x9e,0x9a,0x5d,0x99,0x4f,0x78,0xb7,0x7a,0x36,0xde,0x3c,0x77,0xe3,0xb8 +.byte 0x55,0xcc,0x27,0x14,0xc3,0x69,0xf9,0x23,0xea,0xc6,0x07,0x12,0x94,0xc9,0x1e,0x28,0xab,0xaa,0xf3,0x28,0x35,0x8c,0xb5,0xa4,0x8d,0x1d,0xa6,0xa3,0xb0,0xfe,0xca,0x8e,0x44,0xd1,0x96,0x47,0xf3,0x04,0x77,0xea,0x9e,0xbc,0xaf,0xda,0xed,0x77,0x6b,0x80,0x9d,0x32,0x4f,0xff,0xda,0xd6,0x61,0x1f,0x57,0x66,0xa7,0xfb,0x54,0x78,0x0a,0x43 +.byte 0xaf,0xf7,0x31,0x47,0xd9,0xf4,0x6e,0x70,0x9f,0x1c,0xe0,0x71,0xba,0x11,0x2a,0x0e,0x83,0xba,0xa2,0xc4,0x8b,0x64,0x1e,0xcf,0x17,0xfc,0xb5,0x72,0xa3,0x4e,0x03,0xc7,0x6f,0xa6,0xf6,0x6f,0xe7,0xb7,0x09,0x1a,0x6f,0x09,0xa6,0x45,0xd5,0x20,0x2f,0xbd,0x5a,0xc8,0xae,0x02,0xf3,0x00,0xf7,0xb4,0xd9,0x05,0x38,0x23,0x64,0x27,0x0b,0x27 +.byte 0xc3,0x54,0xea,0x6f,0x85,0x68,0x10,0xa8,0xcd,0xb6,0xf3,0xb6,0x7a,0x55,0xba,0x7e,0x5f,0x6d,0x0e,0x33,0xf3,0x98,0xef,0xd3,0x9b,0x30,0x5c,0x2b,0xd3,0x10,0x89,0xe7,0x34,0x95,0x4f,0x58,0xb5,0xe6,0x7f,0x84,0x3f,0x71,0x3b,0xae,0xc7,0xcd,0x2e,0x93,0xff,0x72,0x33,0x6f,0xf7,0x8b,0x25,0xd4,0x48,0xa4,0x66,0xe9,0xc1,0xe7,0x1a,0xf7 +.byte 0x2d,0x63,0x67,0x5e,0x6c,0x96,0x9c,0x93,0x52,0xe9,0x0f,0xf6,0x1a,0x78,0xa9,0xa0,0xa1,0x96,0x95,0x49,0x69,0xfd,0x78,0xf6,0x65,0x49,0xc6,0x1c,0x44,0x3d,0xbd,0xb5,0x04,0x5f,0xaf,0x69,0x1c,0x3e,0xc1,0xea,0x53,0x3b,0x2e,0x40,0x61,0xf2,0x66,0x24,0x90,0x4a,0x86,0xf0,0x74,0xec,0xdb,0x95,0x68,0x9e,0x83,0x11,0xfc,0x5a,0x51,0x66 +.byte 0x51,0x09,0x71,0x6c,0x32,0xbe,0x5d,0x1d,0x04,0xb2,0xba,0x90,0xfa,0xcb,0xd5,0xa4,0xa7,0x26,0x4e,0xe1,0x1e,0x32,0x7c,0x18,0x40,0x6d,0x40,0xed,0x8d,0xcc,0xa3,0x8a,0xc2,0x29,0x73,0x73,0x94,0x0b,0x09,0x43,0xd4,0x2c,0x0f,0xc5,0x92,0x3c,0x47,0x25,0x41,0x96,0xa6,0x2b,0xb0,0xae,0x98,0x82,0x72,0xd3,0x2f,0x7f,0xcc,0x2a,0x22,0x18 +.byte 0xaf,0x07,0xfc,0x64,0x9f,0x72,0x4d,0x61,0x88,0x59,0x6f,0xaa,0x27,0x8d,0x42,0x21,0x5f,0x25,0xbe,0xa3,0x29,0x4d,0x06,0x2d,0xd5,0xaa,0xb3,0xb5,0xbe,0xa5,0x6c,0x1e,0xdb,0x2e,0xb2,0xc0,0x9d,0x03,0x0f,0xce,0xfa,0xc6,0x45,0xff,0xac,0xc8,0x22,0xb6,0x90,0x40,0x88,0xae,0xc0,0x9e,0xcb,0xf2,0x2b,0xa3,0x74,0x34,0xe1,0xb0,0xe3,0xdb +.byte 0x46,0x88,0xb8,0x67,0x24,0x6b,0x53,0xf7,0x18,0x2e,0x52,0x44,0x24,0x23,0x4d,0x33,0x94,0x4d,0x58,0x47,0x0e,0xcc,0xae,0x46,0x56,0x49,0x76,0xfc,0x62,0x9e,0x3d,0x05,0x14,0xe7,0xaa,0x1a,0x44,0x8b,0x02,0x0c,0x8a,0x8b,0x9c,0x5b,0x8d,0x99,0x10,0xb3,0x4a,0x8d,0x9c,0x5f,0x9f,0xe9,0x35,0x10,0x67,0x1a,0xfe,0x1f,0xb9,0x5e,0x02,0xeb +.byte 0x05,0xe2,0xbe,0xa6,0xea,0x81,0x64,0x2d,0x8e,0x8b,0xf4,0xe5,0x02,0x98,0x21,0xa9,0x9d,0xc7,0xc1,0x4b,0x74,0x33,0x8a,0x1e,0x7b,0xbc,0x15,0x27,0xda,0xe8,0x35,0xa5,0x36,0xa5,0xe4,0xad,0x1c,0xa0,0x7c,0x1d,0xc9,0x1e,0x7e,0x88,0xa7,0x59,0x88,0x1c,0xb6,0x0a,0x07,0x94,0xbb,0x5d,0xa1,0x00,0xdd,0x85,0x70,0xac,0x60,0xcb,0xc8,0x70 +.byte 0x2c,0x8f,0x4e,0x2e,0x85,0xdf,0xf4,0x6d,0x78,0x16,0x03,0x50,0xed,0xe8,0x13,0x79,0x64,0x89,0xf7,0xf0,0x42,0xf6,0xc9,0x78,0xe6,0x23,0x36,0xdd,0xaf,0x13,0xee,0xc4,0x94,0x81,0xc3,0x68,0xe8,0x88,0xb3,0xd4,0x16,0x05,0x43,0x52,0xab,0x60,0x8f,0x04,0xee,0x9c,0xb3,0x22,0x63,0x25,0xe0,0x9d,0xd3,0xc0,0xa4,0x79,0x75,0xac,0xba,0x16 +.byte 0xea,0x43,0x18,0x9c,0x9a,0x9a,0x9b,0xbf,0x51,0xa0,0xd1,0xf2,0x64,0x0d,0x3c,0x8f,0xaa,0xb2,0x25,0x30,0x35,0xf9,0x87,0xf8,0x1d,0xc2,0xbd,0x3a,0xa1,0x28,0xb7,0xaa,0x55,0xc0,0x79,0xc8,0xb4,0x21,0x8e,0x44,0x7e,0xc1,0xd5,0x7f,0xe8,0x18,0xfc,0xab,0xff,0x22,0x6d,0xc8,0x25,0x8a,0xe0,0x96,0xa4,0xf2,0xde,0x49,0xf2,0x4c,0xfe,0x5b +.byte 0x56,0x3b,0xa0,0x35,0x5e,0xbe,0xf7,0x47,0x66,0xff,0x62,0xfb,0xe9,0x27,0xd6,0x0a,0x98,0x99,0xb7,0x76,0xe8,0x67,0x05,0x70,0xd5,0x43,0xcd,0x28,0x9b,0xf5,0x9f,0xa4,0x80,0x31,0x1a,0x02,0xd6,0x67,0x05,0x61,0xd0,0xcb,0x15,0xe0,0xec,0xe3,0x41,0x53,0xb0,0x0f,0x21,0x65,0x56,0x47,0x49,0x9f,0x16,0x29,0x1a,0xca,0xe0,0x50,0x54,0xd2 +.byte 0x46,0x9b,0xae,0x68,0x06,0x61,0x0b,0xd7,0x46,0x93,0x79,0x06,0x0a,0xc9,0xc5,0x8f,0x33,0xfe,0x63,0xf8,0x2d,0x87,0xa6,0x95,0x01,0x87,0x2c,0x15,0xd3,0xbc,0x03,0x02,0x7f,0x75,0xf1,0xbe,0x78,0xe2,0x8b,0x03,0x6a,0xea,0xb1,0x74,0xd3,0xc7,0xef,0x2e,0x8b,0xa2,0xd9,0xe3,0x8e,0xfd,0x6a,0x1a,0x6b,0xf5,0x9f,0x5b,0x9c,0x9b,0x78,0x58 +.byte 0x81,0xba,0xb0,0x63,0x5e,0xd4,0x36,0xe1,0xd4,0xb4,0x9d,0x90,0x77,0x08,0xc7,0xc8,0x09,0x64,0x54,0x35,0x16,0xc6,0x9c,0xe2,0xc2,0x40,0x39,0x00,0x65,0x8d,0x7d,0x90,0x9b,0xdb,0xb3,0xac,0xe8,0x17,0xe3,0x78,0x4a,0x26,0x42,0xf8,0xb8,0xb8,0x3b,0x55,0x7f,0x8d,0xed,0xee,0x88,0xaa,0xa7,0x05,0xa9,0x72,0xc1,0x58,0x21,0x1b,0x9e,0x6f +.byte 0xf2,0xf3,0x8d,0x72,0x8c,0x3a,0xab,0x21,0x8d,0xcb,0x33,0x53,0xa1,0x9c,0x6d,0x41,0xef,0xf8,0xae,0xcf,0x0c,0xf7,0xca,0x7f,0x38,0x17,0x28,0xa4,0xab,0xb5,0xf4,0x5d,0x96,0xf4,0x36,0x13,0x50,0xb6,0xe5,0x9a,0xeb,0x3f,0xe2,0x64,0x94,0xc0,0xd5,0x9c,0x60,0x87,0xff,0xf5,0x8a,0x60,0x83,0x3d,0x02,0xfc,0x7f,0xc0,0x20,0x24,0x4e,0x0c +.byte 0xf3,0x31,0x1d,0x07,0x67,0x90,0xa6,0xbd,0x1f,0x6e,0xb0,0xbd,0x24,0x53,0x31,0x50,0x72,0xdb,0xb1,0xdd,0xb2,0xfd,0x77,0x68,0x75,0x7a,0x7d,0x66,0x52,0x40,0xab,0x48,0x5a,0xf2,0x94,0xc6,0x54,0xcf,0xfe,0x2a,0xe7,0x80,0x67,0x34,0x93,0x72,0x85,0x6c,0x48,0x1c,0x00,0x62,0xf8,0x6f,0x2e,0xb1,0x85,0x42,0x5b,0x6b,0xe8,0xf5,0x69,0x05 +.byte 0xaf,0x59,0x1a,0x43,0x0a,0xfe,0x49,0x8c,0x35,0xbc,0xf7,0xb8,0x2d,0x9c,0x89,0x64,0x37,0x5e,0xfa,0x05,0x15,0x9d,0x3c,0x80,0xc4,0x41,0x5a,0x00,0xcb,0xdc,0x9c,0x60,0xfe,0x3a,0x2e,0x45,0x16,0xb3,0x4b,0x81,0xbb,0xed,0xfe,0x09,0x99,0x0b,0xb3,0x13,0xa4,0x36,0xe0,0xe0,0xaa,0x5f,0x7b,0x76,0x7c,0x64,0x54,0x85,0x53,0xf7,0x82,0x8c +.byte 0x8d,0xc6,0xf2,0x89,0xc6,0x26,0xa3,0x9b,0x26,0x2a,0xbe,0xed,0x39,0xcf,0x4a,0x16,0xec,0x75,0xca,0x08,0x3a,0x2a,0x1b,0x29,0x27,0x71,0x41,0xe2,0xd2,0x83,0xa0,0xd5,0x20,0x28,0x92,0xb8,0xbd,0xe5,0x3d,0x45,0x94,0x5f,0x83,0x70,0xb0,0x44,0x14,0x05,0xac,0xc3,0x88,0xad,0xe6,0x6a,0x95,0x7f,0x63,0x5d,0xb8,0x2d,0x0f,0x08,0x50,0x1e +.byte 0xc2,0x28,0x20,0xcf,0x35,0xd9,0x37,0x72,0x97,0x03,0x33,0x7a,0x28,0xf4,0x96,0x6d,0x77,0xb7,0x1d,0xd8,0x67,0xf4,0xce,0xd8,0x2c,0xd6,0x84,0xc0,0xcf,0x56,0xb4,0xe1,0xdd,0xbb,0xbc,0xf2,0x72,0xff,0x69,0x4c,0x16,0x45,0x58,0x99,0x82,0x69,0x7a,0x86,0xa3,0xe2,0xdd,0x16,0xd2,0x65,0x65,0x7f,0x7e,0x55,0x54,0x16,0xda,0xfe,0x3a,0x49 +.byte 0xfa,0x9e,0x0f,0xfa,0xdc,0x1c,0x25,0x46,0xa9,0xca,0x4f,0xf7,0x15,0x2c,0xd2,0xe2,0xf4,0x79,0x0f,0xb5,0x61,0x0a,0xb3,0xbb,0x2a,0x9e,0xa1,0xf7,0x9b,0x85,0xa7,0xb9,0xf3,0x36,0x29,0x4e,0x5d,0xee,0xab,0x46,0x9f,0xf8,0x4a,0xf7,0xbe,0x9b,0x51,0x1b,0x55,0x1b,0x91,0x78,0x06,0xbf,0x2c,0xec,0x3d,0xcc,0xe0,0x89,0x99,0xf9,0xea,0xc4 +.byte 0x94,0x92,0x12,0x1e,0xa9,0x1b,0x4f,0x7d,0xd0,0xd8,0xc1,0x6f,0xcd,0x6e,0x51,0x3a,0xb1,0xab,0x04,0x32,0xbe,0xa7,0x57,0xf3,0x5c,0x08,0x30,0xef,0x02,0x11,0x8e,0x55,0x9a,0x62,0x7a,0x4c,0x54,0x9e,0xc0,0x30,0x8e,0x24,0xc2,0x38,0x83,0x4d,0xd1,0x66,0x2a,0x86,0x40,0x70,0x7c,0xb3,0xf8,0x85,0x3b,0x3c,0x98,0xe3,0x7a,0x54,0xb8,0xf5 +.byte 0xf4,0xda,0x5e,0x43,0xfb,0x44,0x74,0xe7,0x81,0x82,0xfe,0xa6,0x2f,0xb0,0x18,0x3e,0x17,0xd3,0xfc,0xe7,0xbd,0x5e,0xf0,0x69,0x0f,0x70,0x78,0x95,0x18,0xcb,0xde,0x44,0xa3,0xf4,0xa2,0x05,0xac,0x70,0xcb,0x89,0xbc,0x24,0x53,0x1f,0xfe,0x0e,0xa7,0x4e,0x67,0xab,0x48,0x6d,0xbe,0x77,0xe0,0xa5,0x46,0xcb,0x06,0x70,0x99,0xa9,0x40,0xd7 +.byte 0x9e,0xd9,0xc3,0xff,0x86,0xca,0x0c,0x29,0x72,0x90,0x9b,0x72,0xc7,0xd3,0x51,0x23,0x8c,0xca,0xa2,0xdf,0x4f,0x01,0xb5,0x56,0xa4,0x99,0x6f,0xb2,0x57,0x5f,0x67,0x84,0x99,0xce,0xd9,0x86,0x25,0x82,0x53,0x15,0xb0,0x37,0x19,0xfa,0xad,0x9e,0x76,0x52,0xa0,0xb2,0xbd,0xc5,0x1f,0xee,0xdb,0x2d,0x0d,0xea,0x1d,0x3c,0xb4,0x5c,0xfe,0xfb +.byte 0x95,0xea,0x56,0x65,0x9f,0xca,0xa0,0xd6,0xe3,0x2c,0xb5,0xd1,0x12,0x38,0xca,0x53,0x09,0x76,0x1b,0x77,0xb0,0x0b,0x54,0x59,0x38,0xd5,0xe9,0x08,0xa9,0x17,0x1c,0x88,0xe8,0x7a,0xd6,0x03,0xee,0x7c,0x46,0x3e,0x3c,0xeb,0x2c,0xa6,0x16,0x7b,0x7d,0xd5,0x30,0xea,0x12,0xfc,0x16,0x5d,0xcd,0xa9,0x73,0xfb,0xba,0xac,0xc6,0x8d,0xe4,0x87 +.byte 0x3a,0x46,0x5f,0x35,0x4f,0x8f,0x53,0xe0,0x22,0xd3,0x7b,0x9a,0x2c,0x5e,0x06,0x05,0x1e,0xb1,0x87,0x80,0x75,0xa3,0x4d,0x32,0xc8,0xa0,0xd8,0x41,0x47,0xde,0x01,0x8a,0x56,0x0f,0xf8,0x3e,0x8a,0xde,0x1f,0x1f,0xd9,0xab,0xc2,0xcd,0x9a,0xd7,0xa5,0x2c,0x5c,0x42,0x9f,0x43,0x43,0x75,0x8d,0x1e,0x2b,0xe7,0x1a,0xaf,0x98,0xf4,0xc1,0xab +.byte 0xb4,0x1b,0x09,0x89,0x94,0xe3,0x42,0xd4,0xd0,0xdb,0x35,0xdf,0xce,0xb6,0x96,0xb8,0x2b,0xe2,0x51,0xa0,0xdc,0x92,0x3d,0x4c,0x6e,0x69,0xc1,0xe6,0xd5,0xec,0xda,0x51,0xe9,0x54,0x7e,0x56,0xe2,0x47,0xeb,0x37,0xce,0xce,0xbd,0xc2,0xf0,0x97,0x27,0x40,0x66,0x67,0xda,0xdf,0x86,0xcb,0xda,0x5e,0x03,0xe0,0x38,0x54,0x44,0x62,0xfe,0xb2 +.byte 0xfa,0xc3,0x6d,0xa5,0x8b,0x89,0xc5,0x84,0xbe,0x86,0x41,0x0c,0x52,0x0c,0x75,0x71,0xf5,0x74,0xed,0x2c,0x01,0xf2,0x55,0xef,0x85,0x14,0x84,0x3b,0x11,0x38,0xda,0xcd,0x59,0x15,0x80,0xd7,0x61,0xe9,0x89,0x3d,0xeb,0xad,0x43,0x44,0x30,0x14,0xe3,0x4d,0xbd,0xc9,0x80,0xdb,0x2d,0xd7,0x40,0x94,0xc7,0x56,0x35,0x62,0x23,0xfb,0x8f,0xe2 +.byte 0x87,0x9c,0xd9,0x07,0xc0,0x7e,0xc7,0x74,0x44,0x1d,0x98,0x3b,0xa1,0xa7,0xd1,0x05,0x66,0x69,0x59,0x58,0xc1,0x55,0x2a,0x6e,0x33,0x31,0xc1,0x3e,0xdf,0x03,0x4c,0x9a,0x9d,0xd1,0xff,0x43,0x6a,0x87,0x92,0xd0,0xdf,0x6b,0x51,0x22,0x68,0xa8,0xda,0xe8,0x8c,0xe0,0xb2,0xdc,0x61,0xdf,0x5d,0x08,0x27,0xe8,0xf9,0xdd,0xe8,0xe7,0xe5,0x2b +.byte 0x89,0xf3,0x03,0x44,0xe4,0x51,0x8b,0x5a,0x23,0xc2,0x3e,0xde,0x1d,0xa7,0x82,0x66,0xd6,0xb7,0xe6,0xa4,0xc8,0x8a,0x65,0x72,0xe8,0x30,0x77,0x55,0x52,0x78,0x1b,0x9d,0x39,0x2b,0xa0,0x27,0x70,0x39,0xff,0x66,0x49,0x43,0x37,0xd1,0xc1,0x1a,0x95,0xc3,0xa3,0x34,0xad,0xe9,0x34,0x08,0x14,0x5d,0x20,0xbc,0x96,0x7b,0x25,0x44,0xc3,0x5f +.byte 0xb8,0x4b,0x82,0x88,0xff,0x9e,0xee,0xec,0x4c,0xd4,0x06,0xb3,0x2f,0xc3,0xe6,0xae,0x0e,0xa8,0xa6,0xb1,0xef,0x16,0xc5,0x82,0x34,0x8e,0x51,0xd1,0xaf,0x9f,0xee,0x33,0x3c,0xa8,0x8c,0x42,0x2f,0xe7,0x40,0x1d,0xbc,0xb7,0x24,0xb0,0xd7,0xa5,0x42,0x7f,0x3f,0x1a,0xe3,0xf8,0x58,0x86,0xe3,0x0b,0x4a,0xe9,0xe3,0x5d,0x09,0x9a,0xb0,0x10 +.byte 0x8f,0x00,0xc3,0x5f,0xa2,0xce,0x77,0x01,0x0a,0xae,0x46,0x68,0x65,0xc0,0x2c,0x7e,0x79,0xb1,0x80,0x8a,0x24,0x1a,0x2c,0x34,0xbe,0xa6,0x30,0x41,0xee,0xf5,0xee,0xa0,0xfe,0x47,0x1f,0xf4,0xae,0xd8,0xb3,0xa5,0xdc,0x5a,0xab,0xf6,0xf9,0x64,0xa1,0xe6,0xc2,0x73,0xee,0xf9,0x33,0xdb,0xe4,0xc8,0xa2,0x23,0x48,0x68,0xe2,0x94,0xef,0xc5 +.byte 0xe4,0xc7,0x9a,0x18,0x88,0x42,0xed,0xa0,0x2d,0x3d,0x05,0x92,0xe4,0x71,0xf8,0x90,0xd9,0x9e,0xf3,0x74,0x0c,0xa5,0x66,0x4d,0x40,0x8a,0x22,0x8e,0x0d,0x0e,0xfb,0x18,0xc4,0x06,0xed,0x4e,0xcb,0x7b,0xd5,0x6e,0xf0,0xe6,0x0e,0x7e,0x2c,0xe8,0xf1,0xa8,0x41,0x83,0x02,0xf2,0xb2,0xfa,0x5f,0x21,0xb8,0x4e,0x20,0x81,0xbf,0xbe,0x0f,0xd4 +.byte 0xc2,0x6e,0x2c,0xfb,0x67,0xcc,0xe7,0x7f,0x24,0x36,0x0e,0xa2,0xf5,0xf5,0x4b,0x80,0xb6,0x7f,0x53,0x09,0x77,0xe1,0x51,0x16,0x92,0xc5,0xa8,0x22,0xa9,0x89,0x11,0xab,0x6b,0x90,0xeb,0x75,0x51,0xe4,0x9d,0x39,0xaa,0xab,0x98,0x21,0x1c,0xa9,0x3a,0x7f,0x04,0x3e,0xfd,0xa6,0xa3,0x91,0xa8,0x51,0xfe,0x30,0x26,0x2e,0x44,0xde,0x5d,0x41 +.byte 0x91,0x35,0x65,0x5d,0x17,0x1e,0x71,0xb5,0xc5,0xb9,0x3c,0x3a,0xcc,0x06,0xa2,0x2b,0xef,0x02,0xe4,0x0e,0x42,0x82,0x4d,0x2b,0x91,0x9a,0x38,0x49,0xc6,0xba,0x15,0x08,0x2c,0xe6,0x38,0x10,0x06,0xbe,0x59,0xa0,0xf7,0x78,0xbb,0xc3,0x4c,0x4b,0xe8,0x14,0x0f,0x7d,0x92,0x14,0x34,0x67,0x17,0x37,0x49,0xcf,0xf4,0x77,0xc2,0x41,0x47,0x16 +.byte 0x70,0x63,0x38,0x81,0xe0,0x2b,0x8b,0xfe,0x15,0x59,0x0b,0x3f,0xaa,0xf1,0x2d,0x21,0x66,0x85,0x03,0xb7,0x09,0x6f,0x28,0xfa,0xc8,0x09,0x26,0x93,0x0d,0x3b,0xa4,0x96,0xb2,0x87,0x44,0x21,0xb9,0xec,0x30,0xf4,0xb4,0x8a,0x7c,0x84,0x7c,0x47,0xf4,0x01,0x48,0x42,0xa0,0xd0,0xf7,0x52,0xb5,0xdb,0xf9,0x24,0x02,0x7b,0xa8,0x97,0x54,0x89 +.byte 0x6a,0x4d,0x5c,0xac,0xfc,0x61,0x69,0x4b,0x79,0x7a,0xae,0x72,0x9f,0x3f,0xea,0x09,0x50,0xd7,0x16,0x1f,0x0d,0x58,0x00,0x02,0x27,0xfd,0x2a,0x52,0x41,0x0d,0x1e,0xf3,0xe3,0x5f,0x93,0x01,0x51,0xc5,0xea,0x11,0x7b,0xd3,0x31,0x8b,0xcc,0x21,0xd7,0x17,0xb4,0x04,0xb8,0x30,0xc0,0xf7,0xf8,0x65,0x23,0x3f,0x8e,0x04,0x62,0x38,0x37,0x09 +.byte 0x06,0xde,0xe5,0xfb,0xa5,0x2a,0xc7,0xba,0x52,0x89,0xc6,0x9a,0xb2,0x0c,0xe4,0x89,0x3b,0xe8,0xc2,0x33,0xa4,0x48,0x8d,0x6d,0x35,0x3e,0xbf,0xef,0x15,0x9a,0x05,0x6c,0xdf,0x4f,0xa2,0x96,0xeb,0x75,0xc5,0x26,0x5b,0x9c,0xc8,0x22,0xab,0x8b,0xf9,0xbe,0x2e,0x8e,0x70,0xd2,0x60,0xf6,0x6f,0xa0,0x3f,0x24,0xe4,0x76,0x67,0xa5,0x5d,0x65 +.byte 0x9d,0xc7,0x7f,0xab,0x69,0xdd,0xd5,0x5d,0xcc,0xf7,0xab,0x60,0x57,0x18,0x1f,0x1c,0x79,0x2f,0x37,0x44,0x37,0x54,0x13,0xd5,0x7f,0x51,0x5b,0x59,0x1c,0x2b,0x0c,0x43,0xeb,0x05,0x25,0xf4,0xa8,0xbf,0x76,0x7a,0xb4,0xc8,0x54,0x3f,0xe5,0x1b,0xd4,0x85,0x9a,0x6e,0x52,0x49,0x68,0xcd,0x90,0xcc,0xa5,0x36,0x9d,0xa9,0xe8,0x4f,0xc3,0xbd +.byte 0x8a,0x83,0x65,0x57,0xe1,0x5f,0x09,0xdc,0xb3,0x06,0x61,0xe0,0x61,0x34,0xf7,0x72,0xaa,0xb2,0x14,0xfe,0xf7,0xae,0xb4,0x59,0x90,0x83,0x64,0xc0,0x64,0xe5,0x1d,0x35,0x7b,0x40,0xbb,0x20,0xaa,0x63,0xfe,0x7d,0xbb,0xed,0x26,0x93,0x95,0x8a,0x85,0x20,0x98,0x83,0x14,0xec,0xef,0x74,0xb8,0x1e,0x2c,0x6e,0x3d,0x34,0xdc,0x6a,0xd7,0x7f +.byte 0x7b,0xdb,0x57,0x15,0x28,0xb2,0xf3,0xa0,0x6b,0x26,0x5d,0xe6,0xd5,0x0d,0x07,0x4d,0xa6,0xc5,0x9b,0x5e,0xbe,0x48,0x0d,0x99,0x91,0x14,0x41,0x3a,0x4c,0xc9,0xef,0x37,0x6c,0x8f,0x4e,0xdc,0x93,0xae,0xb0,0x80,0x70,0x35,0x5e,0x7c,0xee,0x6e,0xb2,0xab,0xc1,0xed,0x30,0x4f,0x90,0x7b,0xfc,0xa3,0xf5,0x12,0x38,0xbf,0x8f,0x54,0x46,0x6d +.byte 0x13,0xf4,0x7f,0xcb,0x35,0xfd,0xd0,0xbb,0xe4,0x40,0xb2,0x9a,0x2a,0x5a,0x16,0xe0,0xbc,0x77,0x31,0xa0,0x04,0x71,0x6b,0x1a,0x37,0x7c,0xdf,0x68,0x02,0x43,0x73,0x8d,0x53,0xd4,0x58,0x6e,0x05,0x94,0x97,0x45,0xf9,0xb1,0x55,0x7a,0x6a,0x99,0x5c,0x8b,0xb0,0x8e,0x35,0x23,0x5a,0x2d,0xd0,0x3c,0xd1,0x16,0xb6,0x81,0xc3,0x88,0x6b,0x8e +.byte 0x2c,0x08,0xf8,0x90,0x6a,0x40,0x7b,0xf5,0x26,0xaa,0xdc,0xa2,0xdd,0x0f,0x38,0x68,0x0c,0xeb,0xe4,0x50,0xfd,0xc6,0x3a,0xd6,0x2b,0x3d,0x59,0x45,0xfb,0x64,0x5e,0x65,0x81,0x0e,0x66,0xed,0xbc,0x49,0x52,0x14,0x51,0x75,0x8c,0x47,0x88,0x76,0x95,0x0b,0x2e,0x02,0x3d,0xce,0x20,0x83,0x34,0x56,0xfe,0xf8,0x50,0x7d,0x9a,0x93,0xb5,0x0f +.byte 0x88,0x0a,0xea,0x7e,0x50,0x98,0xdf,0x93,0x5d,0xa9,0xba,0x1c,0x6f,0x58,0x8d,0xb0,0x7a,0x37,0x86,0xba,0x49,0x12,0x35,0x99,0x16,0x6a,0x1d,0x02,0x03,0xfc,0xef,0x7a,0x4a,0x8e,0x54,0x7b,0xc4,0xd4,0x6b,0x6c,0xe5,0x7c,0xc0,0xa9,0x20,0x26,0x6f,0x2e,0x71,0xb9,0x6b,0x3e,0x26,0x9e,0x02,0x7a,0xeb,0x87,0x6b,0xf2,0xc1,0x8e,0x8f,0xe8 +.byte 0x26,0x23,0x86,0xcd,0xdc,0x8f,0xbd,0xe9,0xeb,0x80,0x7f,0x0d,0xbd,0x8f,0x05,0x3c,0xa7,0xbc,0x0b,0x9c,0x03,0xb7,0x82,0xbd,0xc7,0x7a,0xd5,0x4d,0xb0,0x0d,0xd1,0xac,0xba,0x90,0x3e,0xa1,0xef,0x79,0xfc,0x50,0x7d,0xbf,0x8c,0x52,0x13,0x6c,0x91,0x9e,0xb4,0x2b,0xa8,0x96,0x95,0x04,0xe6,0x2e,0x17,0x43,0x43,0x23,0x91,0x63,0xd4,0x1a +.byte 0xe2,0xb7,0x16,0xdf,0x3a,0x39,0xca,0x80,0x92,0x0a,0x00,0x52,0x50,0x75,0xde,0x1c,0x2e,0x91,0x0a,0xf2,0x28,0xb8,0x94,0x16,0x2b,0x0c,0xc0,0x11,0xc4,0x47,0x35,0x4f,0x59,0x03,0x6f,0xcd,0x99,0x23,0xdc,0x24,0xe5,0x68,0x7f,0x82,0x0c,0x28,0xba,0x57,0xa7,0x7c,0x75,0xd9,0x0d,0x34,0x23,0x7e,0x53,0x61,0xad,0xef,0x63,0xdc,0xa4,0xb0 +.byte 0xa0,0xa7,0x54,0xec,0xc9,0xf8,0x80,0x13,0x2c,0xd9,0xc4,0x42,0xec,0xd3,0xd8,0xac,0x04,0xa1,0x61,0x5a,0xdd,0x3e,0xa5,0x29,0x70,0x8f,0xa3,0x44,0x04,0x14,0x7d,0x2b,0x34,0x38,0x89,0x53,0xf4,0x89,0x5a,0x9b,0xa2,0xf5,0x30,0x0b,0x17,0x0a,0xda,0x4e,0x9c,0xca,0xb6,0xa8,0xbb,0x0a,0x1b,0xa0,0x48,0x6d,0x85,0x48,0x70,0x7b,0x98,0xbd +.byte 0x82,0x09,0x1f,0xbf,0xf9,0xe7,0xe7,0x4a,0x9e,0xa6,0x9a,0xf4,0x61,0xd7,0xfa,0x45,0x3e,0xd6,0x29,0xf7,0x4c,0x23,0x32,0x76,0x56,0x2d,0xa7,0x88,0xc5,0x63,0xc0,0x99,0x69,0x85,0x69,0x98,0x1d,0xfb,0x8f,0x5a,0x2c,0x0d,0xd8,0x44,0xae,0x12,0xff,0x28,0xa2,0x12,0x12,0x05,0xe2,0xb9,0x06,0x38,0xfb,0x0b,0x1e,0x5f,0x38,0x04,0x37,0xe6 +.byte 0x1b,0x87,0xe2,0xaf,0x7a,0x01,0x34,0x72,0xc0,0xf6,0x36,0x6c,0x62,0x22,0x5f,0xdd,0x22,0xb9,0xef,0x15,0x51,0x76,0xaa,0x18,0xa9,0xba,0xc0,0x4d,0x5b,0x72,0x73,0xcd,0x25,0x79,0xc0,0x81,0xdd,0x38,0xab,0x75,0x9f,0x53,0xe6,0xfd,0xbe,0x94,0x99,0xac,0x93,0xb6,0x85,0x96,0x04,0xc2,0xf2,0x52,0xbc,0x3b,0x47,0x91,0xdd,0xa0,0x36,0xbe +.byte 0x63,0x70,0x72,0x55,0x61,0xc0,0x2c,0x09,0x16,0xa5,0xc9,0xaa,0x1f,0x0e,0x62,0xae,0x3c,0xf0,0xf2,0xa6,0xd2,0xd1,0xaa,0xdb,0xc1,0x75,0xfd,0x55,0x8c,0x99,0xd1,0x07,0xb7,0xd4,0x0e,0x24,0x89,0x0f,0xc8,0x05,0xe4,0x2e,0x20,0x8a,0x56,0x26,0xe0,0x24,0x0f,0xf8,0xc6,0xc5,0x17,0xcc,0xac,0x4e,0xbe,0x03,0x81,0xe2,0xd5,0x9c,0x33,0x5f +.byte 0x86,0xb2,0xc4,0x66,0x08,0x78,0xc2,0x41,0x91,0x1e,0xa2,0x66,0xfb,0x12,0x24,0x41,0x5f,0x34,0x73,0xc7,0x9d,0x4b,0xaa,0x19,0x8e,0x6b,0x42,0x17,0x97,0x96,0xef,0x2b,0xb6,0x33,0xaf,0xe4,0x86,0xd0,0x68,0x57,0xf3,0x75,0x65,0x72,0x90,0x36,0xb0,0x18,0xba,0xcf,0x98,0x25,0xe7,0x81,0x42,0xfc,0x1b,0x6a,0x34,0x08,0xa5,0x41,0xb6,0x22 +.byte 0x49,0x27,0x8f,0xd1,0xa1,0xda,0x01,0x88,0x9a,0x0c,0xd7,0x48,0xf4,0xbb,0xa0,0x79,0x91,0x6b,0x41,0x46,0x1c,0x2e,0xc7,0x4f,0x18,0xcc,0x11,0x20,0x84,0xc7,0xfe,0x2c,0x3a,0xf6,0x15,0xdf,0xcd,0x8b,0x69,0xda,0xd0,0xd8,0x2d,0xf6,0x7b,0x82,0x7b,0x65,0xcb,0x6a,0x3d,0x20,0x8b,0x35,0xe5,0x6f,0x69,0xa4,0x8d,0x76,0x96,0xe6,0x70,0x67 +.byte 0xa2,0xca,0x56,0x23,0x0e,0x3c,0x62,0x47,0x36,0xb4,0xd5,0x79,0xa4,0x4e,0x35,0xa8,0x1a,0x46,0x7a,0x78,0x6d,0x9a,0xd9,0xbc,0x90,0xff,0xa8,0xb0,0x13,0x1d,0x42,0xb2,0xf2,0xa9,0xc4,0x0c,0x8e,0x16,0x1c,0x60,0xcf,0x3d,0xfe,0x5e,0xbb,0x7c,0xe5,0xd5,0x3c,0xb3,0x32,0x86,0xcb,0xa4,0xff,0xe5,0x9b,0x26,0xf7,0xc2,0x5a,0x3f,0xa0,0x9d +.byte 0x2d,0x2d,0xb5,0x4a,0x08,0x80,0xf4,0x04,0xf8,0x85,0x0c,0xed,0x52,0x75,0xab,0xbb,0x4b,0x16,0xf7,0xa8,0x21,0xa9,0x47,0x80,0x9c,0x54,0xee,0x8f,0x77,0xb1,0x93,0xd4,0x11,0x52,0x3d,0xe7,0xa5,0x30,0x8d,0x9e,0xef,0x82,0x93,0x5e,0x62,0xdb,0x52,0x64,0x8c,0x3a,0x0f,0x9a,0xfa,0x0c,0x9c,0x54,0x5d,0x7c,0xd6,0xc3,0xf6,0xca,0xe6,0x60 +.byte 0x15,0xbd,0x97,0xac,0x0e,0x54,0x5e,0x9a,0x2c,0x58,0xd1,0x87,0xcd,0x36,0xef,0x0d,0x87,0xf8,0x57,0x3e,0x95,0x1c,0x9c,0xac,0x76,0xb9,0x63,0x17,0x6a,0x20,0x94,0xcf,0x2b,0xb2,0xa4,0x2c,0x67,0x31,0x92,0x31,0x76,0xc6,0x89,0xbd,0xd6,0xa5,0xd1,0x36,0x42,0xc7,0xb4,0x92,0x83,0xb1,0xb5,0xd8,0xa0,0x77,0xc8,0xd5,0x24,0x57,0x98,0xd8 +.byte 0x18,0x9a,0xe5,0x5c,0xfa,0xe0,0x29,0xfe,0x18,0x4d,0x67,0xaf,0x6b,0x51,0xdc,0xaa,0xc5,0x05,0x3d,0xe7,0xda,0x81,0x66,0xc1,0x93,0x78,0x70,0x9a,0x4a,0xbe,0x32,0x0d,0x92,0x28,0x5a,0x1e,0xf3,0x53,0x1c,0x1a,0x5c,0x08,0x42,0xe4,0xc0,0x83,0xb0,0x89,0x19,0xd9,0xeb,0xf8,0xf3,0x60,0x4c,0xce,0x78,0x2d,0x05,0x21,0xd3,0xea,0xdb,0xc4 +.byte 0x35,0xcb,0xe7,0x08,0x03,0xec,0x4c,0x32,0xcf,0x51,0xae,0x01,0x47,0xe9,0xaa,0x0d,0x69,0x9a,0xf0,0x5e,0x30,0x78,0xa5,0x49,0xdf,0x1e,0x4c,0xa5,0x86,0xb3,0x8a,0xf4,0x14,0x4a,0x9a,0xf7,0x22,0xd0,0x90,0x1f,0x1f,0xe3,0x57,0x6c,0xdb,0x83,0xea,0x74,0xd6,0xd3,0x62,0x19,0x02,0x93,0x6b,0x32,0x62,0x8b,0xd0,0xa5,0x21,0xaa,0x8f,0x7f +.byte 0x36,0xc4,0x9c,0x1f,0x61,0x3a,0xd8,0xab,0x92,0xd3,0x09,0xe3,0xad,0xcc,0xdc,0x0d,0x04,0xaf,0xa7,0x57,0xff,0x3a,0x5e,0x50,0x7d,0x96,0x6d,0xcf,0x87,0x17,0x0a,0xec,0x70,0x9a,0xb0,0x98,0xa8,0xe4,0xf5,0x32,0x09,0x76,0xf3,0x59,0x50,0x48,0x34,0x25,0x14,0xef,0x85,0x45,0x1e,0xb8,0x1f,0x66,0x6b,0x45,0x6a,0xfa,0xd4,0x48,0xd2,0x59 +.byte 0xd7,0x4c,0xf3,0x27,0x43,0x3d,0xf7,0x69,0x7f,0x64,0x8d,0xf3,0x55,0x82,0x05,0x5c,0xef,0x89,0x29,0x2c,0x35,0x22,0x8b,0xce,0x2f,0xcf,0xca,0x55,0x04,0x39,0xa0,0xda,0x37,0x3c,0xdd,0x32,0x99,0x8e,0xc7,0xcc,0x87,0x4a,0x47,0xd8,0xb2,0x9a,0x30,0x43,0x5c,0xe5,0xc7,0x44,0x87,0x9e,0x19,0x29,0xff,0xc8,0xea,0x43,0x87,0xf6,0xf3,0x3b +.byte 0x4e,0x1c,0xff,0xf3,0xd2,0x6b,0x04,0x03,0x52,0x83,0x97,0x59,0x4e,0x57,0x7b,0x8d,0x5d,0x8a,0xa7,0x7c,0xc1,0x88,0x52,0x7c,0x13,0xda,0x7e,0x80,0x64,0x03,0x30,0x83,0xbc,0xd1,0x3e,0x79,0xee,0xd4,0x23,0xc8,0xe5,0x5c,0xf1,0x3b,0xa5,0x1e,0xa4,0x0d,0x20,0x8f,0x8b,0x87,0x18,0x63,0x7e,0x6c,0x17,0x1b,0x01,0x0b,0xd5,0x47,0x89,0x43 +.byte 0x84,0x0d,0x2a,0x80,0x1e,0x54,0xab,0x8a,0x0c,0x94,0xa5,0x0b,0x24,0x5e,0xcd,0xde,0x1c,0x00,0x8f,0x2a,0x29,0x01,0xf5,0xcc,0xca,0x54,0xa1,0xce,0x37,0xef,0xe5,0x4e,0x53,0x8e,0xc1,0x13,0x1a,0x75,0xf7,0x8f,0xec,0xf8,0xe9,0x5c,0xc8,0xe6,0x28,0x89,0x6e,0xb8,0x4b,0x39,0x24,0x73,0x28,0x3d,0x56,0xaf,0x8b,0x3b,0x61,0x70,0xae,0x3b +.byte 0xc7,0xe8,0xab,0x47,0xe7,0x16,0xce,0xb8,0xac,0x82,0xac,0x51,0x0b,0x70,0xec,0x6e,0xda,0x0a,0x7e,0x9a,0x6f,0xe1,0xff,0x83,0xb4,0x89,0xec,0x49,0xda,0x48,0xb0,0x3e,0xdb,0x64,0xf6,0x7b,0xc5,0x33,0x02,0x7d,0xae,0x37,0xf1,0x3e,0x03,0x6d,0xf8,0xa3,0x86,0xb3,0xde,0x6a,0x57,0x1b,0xd8,0x85,0xbd,0x9c,0x07,0x84,0xea,0x17,0x4c,0x38 +.byte 0x27,0xfe,0x4e,0x2f,0x94,0x09,0xa8,0x7d,0xe0,0x51,0xea,0x6c,0x32,0x2a,0x54,0x2e,0xc1,0xc1,0x21,0x44,0x0b,0x8d,0xc5,0xbd,0x25,0xaf,0xdc,0x45,0x77,0x39,0xbf,0xea,0x60,0x0f,0xb8,0x30,0x74,0xdf,0xd4,0xd6,0x79,0xcf,0x6c,0x2d,0x23,0x21,0xce,0x68,0x16,0x4e,0x9c,0x47,0xc1,0xa7,0x77,0xb8,0x9e,0xe7,0x5c,0x72,0x73,0xab,0xd1,0x56 +.byte 0x6e,0x50,0x6d,0xe6,0xd6,0xd3,0x13,0x92,0xed,0x98,0x85,0x4a,0x7d,0xc8,0x9f,0x50,0xb6,0x42,0x9c,0x0a,0x8b,0xc1,0x23,0x46,0x20,0xa9,0xd9,0x20,0x2a,0x38,0x5e,0x39,0xfc,0x46,0x9e,0xbe,0x82,0x5c,0x73,0x33,0x7d,0x8a,0xfd,0x2c,0x1d,0x84,0xa9,0x5e,0x64,0xea,0x3f,0xbf,0x82,0xe4,0xd8,0x70,0xc9,0x7d,0x01,0xca,0x71,0xfb,0x63,0xe8 +.byte 0xd8,0x75,0x25,0xd0,0xa3,0x80,0x43,0x8c,0x2a,0x70,0x4f,0x7f,0x04,0x99,0x1d,0xe3,0x73,0x7d,0x6c,0x3f,0xf7,0xf7,0x2f,0xd8,0x0e,0xa4,0x60,0xf6,0x22,0xb1,0xf1,0x2f,0x5a,0x1f,0xd4,0xdb,0xae,0xdb,0x97,0x94,0x16,0xe6,0xd2,0xf2,0xc1,0x9f,0xb8,0xc5,0xb3,0xed,0x41,0x12,0x40,0xe1,0x09,0xaf,0xe3,0x52,0x97,0x63,0xa3,0x41,0x63,0x93 +.byte 0x6f,0x6e,0x07,0xa7,0x92,0xa9,0x94,0x60,0x38,0x60,0x1e,0xff,0x05,0x0c,0xed,0xdc,0x78,0xfb,0x6e,0xa4,0x08,0x21,0x31,0xaa,0xf9,0x6f,0xed,0xaf,0xc6,0x5d,0xfe,0xbe,0xab,0x76,0x4f,0x78,0xb9,0xaa,0x21,0x4d,0xdd,0xb2,0x14,0xf5,0x32,0x03,0xa2,0x6e,0x57,0xc6,0x54,0x65,0x81,0x1f,0xdc,0x1a,0xc5,0xba,0xee,0x26,0xa2,0x90,0xc8,0xb6 +.byte 0x47,0xc6,0xbb,0x9a,0xaa,0x19,0x72,0x8d,0x19,0xbc,0x21,0xe5,0x93,0x58,0xf8,0x1f,0x00,0x28,0x6f,0x66,0x45,0x5e,0x02,0xeb,0x44,0x69,0x87,0xd1,0x1b,0x73,0xb7,0xc7,0xc8,0xf6,0x20,0x30,0x85,0x77,0xc3,0x2d,0x0e,0x55,0x7d,0x80,0x14,0x50,0xff,0x5e,0x79,0x6b,0x1f,0xff,0x76,0x33,0x7d,0x7d,0x34,0x01,0xaf,0xfb,0x73,0x8a,0x89,0x6d +.byte 0x2f,0x0b,0xdb,0xc3,0xea,0x17,0x94,0x06,0x59,0x2e,0x0f,0x34,0x1c,0x75,0x42,0x42,0x83,0xb0,0x18,0xe5,0x6e,0x3c,0x22,0x59,0xce,0x45,0xb8,0x77,0x99,0x92,0x55,0x34,0x45,0x2e,0x04,0x1f,0xd4,0x4f,0x03,0x64,0x92,0x99,0x9c,0x8b,0xd8,0xd7,0x36,0x7c,0xdb,0x2a,0x30,0xb6,0x17,0xba,0x85,0x9d,0x1b,0xc4,0xc7,0x13,0x76,0xe4,0x0b,0xe6 +.byte 0x28,0x8a,0x3a,0x7f,0x96,0x27,0x1c,0xea,0x9e,0x06,0x29,0xe2,0x88,0x22,0xd4,0xda,0x0e,0x19,0x3e,0x42,0xea,0x55,0xf3,0x4d,0x3e,0xf6,0x0b,0xcd,0x05,0x0c,0x5d,0x8a,0x46,0x3e,0x7a,0x3c,0x95,0x55,0x42,0x83,0x32,0x4c,0x5f,0x91,0x4e,0x7d,0x0a,0x8a,0x90,0xbe,0x7d,0x01,0xd7,0x4f,0x21,0xe9,0x24,0x25,0xd3,0x76,0xe8,0x54,0x97,0x44 +.byte 0xdc,0x7e,0x89,0xe5,0x74,0xc4,0xfe,0x41,0x39,0x95,0x81,0x7e,0x3f,0x4c,0xca,0x84,0x7a,0xb8,0x24,0x3d,0x3c,0x86,0xa1,0x49,0x4c,0xec,0x55,0x59,0x11,0x7d,0x1a,0x2e,0xa3,0x36,0x70,0x36,0x9c,0x69,0x47,0x96,0xc1,0x85,0xb0,0xc5,0x9f,0x85,0x1a,0x5a,0x4e,0x77,0x64,0x91,0x73,0x19,0x41,0x59,0x6a,0xb6,0xae,0x37,0x65,0xa2,0x7d,0x2f +.byte 0xef,0x24,0xab,0x48,0xbc,0x20,0x4c,0x57,0x49,0x08,0xc6,0x2f,0x26,0x8c,0xb5,0xa0,0x55,0xf6,0x95,0xfc,0x14,0xb2,0xa3,0x28,0xf1,0x98,0x24,0x67,0xeb,0x7d,0x49,0x6d,0xf2,0x63,0x16,0x99,0xb3,0x67,0xdd,0xd2,0x7e,0xaf,0xcb,0x6c,0x76,0xcd,0x05,0xc8,0x8b,0xec,0x56,0x7d,0x00,0xf9,0x89,0x64,0x15,0xbb,0xa2,0xb8,0x8b,0xdb,0xd2,0x86 +.byte 0xaf,0xf7,0x85,0x0a,0x50,0x4c,0xca,0x65,0xc3,0x31,0xca,0xdc,0x81,0xea,0xd3,0x89,0xd8,0xb3,0x91,0x90,0x8c,0x7b,0xff,0x20,0x62,0xac,0xad,0x06,0x47,0xdd,0x22,0xa5,0xb9,0xd0,0x4f,0xee,0x30,0x69,0x51,0x7d,0x7d,0x32,0x4f,0xbb,0x03,0x43,0xec,0x39,0xac,0x8e,0xab,0xcf,0xc2,0x72,0x67,0x68,0x84,0x61,0x3b,0x4d,0x77,0x6b,0xab,0xe9 +.byte 0x04,0x9c,0x82,0x46,0xef,0x58,0x92,0x94,0x6c,0x33,0xfa,0x61,0x61,0x15,0xb2,0x4d,0xfc,0x49,0x91,0xad,0x67,0xb2,0x6a,0xa9,0x0c,0x06,0x20,0xc7,0x5e,0xc0,0xd3,0xb0,0x20,0x36,0xd7,0x76,0x7d,0x3c,0x1b,0x6a,0xfa,0xab,0x2d,0xb7,0x1f,0xad,0xb9,0x43,0x45,0x48,0x2b,0x09,0x29,0x80,0x14,0x2d,0x17,0x42,0x4e,0x1d,0x53,0x57,0x67,0xe3 +.byte 0xca,0xc7,0x92,0xd1,0x4d,0x07,0xac,0xcf,0x08,0x0e,0xd1,0xd2,0xd5,0xbf,0x18,0x01,0xd2,0x2f,0x79,0x3b,0xd2,0x51,0x7a,0xdc,0x69,0x40,0x51,0x3e,0x57,0xa2,0x3c,0x5f,0x55,0x9b,0xfc,0x0e,0x45,0x96,0xa3,0x8f,0xa2,0x3d,0x64,0x40,0x12,0x07,0x7e,0x0b,0x1d,0x33,0x4f,0xd8,0xd0,0x93,0x8c,0xd9,0x2e,0xd4,0xa9,0xb4,0x08,0x28,0x21,0x52 +.byte 0xda,0xd4,0x86,0x19,0x3b,0x71,0xe4,0x37,0x22,0x5b,0x2a,0x8f,0x83,0x9f,0xd6,0x42,0x85,0xc9,0x30,0x4c,0x5d,0xe4,0x14,0xa9,0xec,0x19,0x8e,0x0a,0x0a,0x29,0xe0,0x00,0x23,0x0b,0xbd,0xc2,0xd4,0xe8,0x6a,0xcb,0xf8,0xdf,0xd0,0x50,0x69,0x0d,0x40,0xe9,0x69,0x31,0xfb,0x64,0x4a,0x6b,0x47,0xba,0x24,0x46,0xf1,0x29,0x80,0x0b,0x75,0x92 +.byte 0x4e,0x9c,0x59,0xd5,0xf4,0x49,0x32,0x5f,0x92,0xdb,0x1e,0x76,0xa9,0x35,0xe3,0x94,0xcf,0xe8,0x1d,0x47,0x6f,0x82,0xe8,0x75,0xaa,0x41,0xd2,0xa0,0x26,0xfc,0x9d,0x0c,0x02,0x93,0xd5,0xd1,0x14,0x96,0x7c,0xa5,0x9d,0x44,0xec,0x8d,0xa6,0x02,0x17,0x12,0x32,0xb9,0xe4,0x8a,0x91,0xfd,0x23,0xc3,0x64,0x13,0xcd,0x57,0x84,0x8e,0x81,0xb5 +.byte 0xa0,0x36,0x22,0x88,0xc0,0x45,0xe5,0xbf,0xb2,0xa6,0xe6,0xa8,0x1c,0xe8,0x8b,0xc8,0x55,0x7f,0xbe,0x45,0x17,0x76,0xe3,0x87,0x67,0x3a,0xd6,0xa0,0x62,0xc1,0x54,0xef,0xaa,0x53,0xd0,0x6d,0x6c,0x33,0xdf,0x7f,0x03,0xa5,0xa3,0x36,0x7d,0xab,0x55,0xbf,0x04,0x43,0xa5,0x59,0xcc,0x6f,0x1c,0xaf,0xfc,0x0e,0x46,0x7f,0x23,0xda,0x89,0xf7 +.byte 0x4d,0xe7,0xfe,0x1e,0xb4,0x08,0x7a,0xea,0x61,0xf5,0xcd,0x1f,0xee,0x70,0xe2,0xfb,0xb1,0xe3,0xb1,0x57,0x65,0x29,0xa0,0xa9,0x11,0x20,0xba,0x29,0x2c,0x68,0x37,0x38,0x07,0x9b,0x58,0x20,0x81,0x4e,0x3c,0x07,0x91,0x93,0xf7,0x1c,0x28,0x59,0x72,0x55,0x50,0xe1,0x23,0xca,0x28,0x32,0xa4,0x5b,0xdf,0xc7,0xd2,0x6b,0x3e,0xdc,0x21,0xec +.byte 0xe3,0xb7,0xae,0x10,0x4d,0x86,0xa9,0xc7,0x43,0xc2,0x84,0xd8,0xb8,0x5e,0x2c,0x4b,0xf3,0xad,0x4f,0xd0,0x1e,0xe9,0xdd,0x4c,0xcc,0x7a,0x02,0xc2,0x43,0xd0,0x32,0x80,0xc5,0x97,0x05,0xaa,0xef,0x67,0xe2,0xde,0xaf,0xf4,0x41,0xa1,0x98,0xc6,0xe6,0xb6,0x03,0x06,0xec,0x56,0xe7,0x90,0x5e,0xba,0x67,0x4b,0xa1,0x52,0xb4,0xfd,0xa0,0x32 +.byte 0x19,0xb5,0x1c,0x8f,0x11,0xc7,0xa7,0xb6,0xa3,0x29,0x83,0x94,0x8f,0x41,0x6b,0xc2,0x60,0xa0,0x3d,0x61,0xe2,0x51,0x2d,0x1f,0xe3,0xa6,0x71,0x72,0x1b,0x3e,0x5b,0xdd,0x0f,0xc4,0xfc,0x3c,0xc1,0xfd,0x2b,0x7b,0x30,0x5c,0x73,0x95,0x53,0x12,0x68,0x22,0x4e,0x71,0xbf,0xbe,0x87,0x67,0xe0,0xc8,0x5d,0x7b,0xd3,0x3b,0xba,0x2a,0xd5,0x5c +.byte 0x61,0x92,0x04,0xd2,0x64,0x5b,0xd0,0x04,0x99,0xe3,0x38,0x0a,0x27,0x7b,0xe0,0xf0,0x04,0xa5,0x15,0x8b,0x4b,0x0e,0x20,0x6e,0x22,0x22,0xa6,0x02,0xf2,0x40,0x74,0x6e,0xce,0x8f,0x56,0x42,0xbc,0xd3,0x55,0x9b,0xbb,0xa2,0x8e,0x26,0x84,0xda,0xea,0xf9,0xf6,0xb1,0x1c,0x93,0xe5,0x65,0xb6,0x0c,0x69,0x28,0x83,0x58,0x05,0xc7,0x44,0x66 +.byte 0xbc,0x84,0x2a,0xc4,0x8c,0x78,0x80,0xa2,0x62,0x75,0x25,0x32,0x44,0xb8,0xd0,0x5e,0x76,0xc0,0x70,0x3d,0x18,0xb3,0x5c,0xe1,0x18,0xf6,0x08,0xef,0x13,0x97,0x02,0x6a,0x4c,0xac,0x86,0x57,0x0b,0xf2,0x7a,0xdb,0xc0,0xf5,0xf0,0xa1,0xfd,0x48,0x96,0x85,0xac,0x66,0x2d,0x49,0xeb,0x1c,0x56,0x46,0x2f,0x4b,0x01,0x98,0x1e,0xbc,0x74,0x57 +.byte 0x6e,0x2e,0x11,0x9a,0xa5,0x94,0x8f,0x02,0x89,0x21,0x52,0x73,0x9a,0x8d,0x0e,0xba,0x7c,0x7c,0x2a,0xbe,0x84,0x36,0x3d,0x4a,0x14,0xb3,0x63,0x71,0x66,0xb6,0xf6,0x1f,0x95,0x73,0xe2,0x4b,0xa9,0xdb,0xe3,0x91,0x06,0xc3,0xfe,0x42,0xa5,0xae,0x60,0x6b,0x59,0xf5,0x25,0x77,0xc1,0x27,0xc0,0xbf,0x48,0xc4,0xe5,0x48,0x44,0xee,0xd4,0x51 +.byte 0x25,0x56,0xf8,0x55,0x6a,0x8f,0x73,0xd4,0x9d,0xa1,0x12,0xfc,0x4e,0xb4,0x22,0x07,0x7c,0x90,0xa6,0x47,0x14,0xd0,0x42,0xec,0x74,0xb8,0xed,0x10,0xaf,0x85,0xb5,0x73,0xa2,0x70,0x97,0xee,0xfe,0xdd,0x49,0x65,0x62,0x8e,0x83,0x61,0xc7,0x37,0x79,0x84,0xa7,0x1f,0x2b,0xec,0x86,0x53,0xf0,0x78,0x06,0x96,0x42,0xb1,0xf8,0x07,0xf7,0x78 +.byte 0x8b,0x75,0x35,0x59,0xce,0xaf,0x89,0x47,0x3c,0x64,0xae,0xda,0x35,0x53,0xe2,0x73,0x0f,0x58,0x92,0x74,0x08,0x3e,0xfb,0x07,0xad,0x41,0xeb,0x47,0xc7,0x64,0xf7,0x62,0x52,0x34,0x36,0x23,0xba,0x2f,0x3d,0x57,0xf4,0x4b,0xad,0xb6,0x3a,0x94,0x9c,0x31,0x07,0xf4,0x1d,0xd7,0xf1,0x6e,0xbb,0x9c,0x42,0x4b,0x7a,0x87,0x10,0xe8,0x9b,0xdb +.byte 0x8b,0x7b,0x8b,0x16,0xd4,0x4c,0x5b,0xcb,0xe6,0x7e,0x0f,0xe1,0x64,0x14,0xc0,0xef,0x63,0x7c,0x71,0x92,0xc4,0x4f,0xd4,0x11,0x0e,0x26,0x08,0xb0,0xe9,0xdc,0xb6,0x75,0xe7,0x97,0xde,0x0e,0xed,0xe5,0x87,0xfb,0x59,0xeb,0x5c,0x70,0x02,0xad,0xfb,0x00,0x17,0x32,0x0d,0x15,0xfd,0xce,0xfe,0xa3,0x11,0x2f,0xf4,0xd1,0xbe,0xbf,0xee,0x50 +.byte 0xd7,0xaf,0x4c,0xe8,0x0f,0x2a,0xfd,0x59,0x5f,0x23,0xe3,0x8c,0x49,0x60,0xa4,0xe0,0x80,0x1a,0x2f,0xc0,0x38,0xb3,0x1b,0x3f,0xa5,0xc6,0xa4,0xb6,0x53,0x3b,0xe2,0xb0,0xc2,0x55,0xba,0x84,0xa2,0xe3,0x6e,0x16,0x6b,0x2f,0x11,0xea,0xdd,0x52,0x77,0xd7,0x25,0xfa,0x12,0x36,0xd5,0x72,0x94,0x5a,0xc0,0x56,0xdf,0xd3,0xef,0x77,0x2a,0x2f +.byte 0x87,0x02,0x06,0x9a,0x00,0x7e,0x80,0xf2,0x90,0xea,0xfd,0x93,0x6e,0x0c,0x0d,0xbd,0xe5,0x9d,0x8c,0x4e,0xdf,0x9c,0x87,0x89,0xf9,0xde,0xff,0xc4,0x49,0xc9,0xb6,0x3c,0xe1,0xcd,0xce,0xfb,0x59,0xd0,0x5a,0x97,0x67,0x62,0x63,0x19,0xcc,0x54,0x3c,0xf4,0x97,0x4e,0x77,0xb3,0xbc,0x42,0x15,0x95,0x27,0x54,0x41,0xad,0x21,0x25,0xc7,0x36 +.byte 0x07,0x58,0xa5,0xca,0x7c,0x27,0xa5,0x6a,0xc1,0x90,0xcc,0x06,0x39,0x10,0x1b,0x20,0x46,0x55,0xd6,0x3a,0xe7,0xec,0x6b,0xba,0x7f,0x99,0x8b,0xd3,0xab,0xaa,0x1a,0x4e,0x7c,0x5e,0x01,0x8e,0xa4,0x99,0x0b,0x41,0x22,0x1a,0x3a,0xeb,0x3b,0xe6,0xfb,0x0b,0x9c,0x65,0xe1,0xcb,0x61,0xf1,0xb0,0x18,0xee,0x52,0xb5,0xbb,0x46,0xf4,0xca,0xae +.byte 0xe9,0xa0,0xe3,0xe9,0xea,0x84,0x88,0x95,0x6d,0xd2,0xe9,0x82,0x0f,0x40,0x5f,0xeb,0xcb,0x51,0x34,0xf1,0x5c,0x1b,0xac,0x75,0xc3,0x0f,0x14,0x6b,0xc9,0xb3,0xa2,0x40,0xbb,0x0e,0x71,0x3b,0x7a,0xee,0xe8,0x25,0xf5,0x64,0xa0,0x3a,0x94,0xeb,0xfb,0x4d,0x9c,0x72,0xbb,0x85,0x22,0x44,0x53,0x19,0x0e,0xc7,0x68,0xa6,0x12,0x6d,0xaf,0xd7 +.byte 0x13,0x0d,0x02,0xd9,0xe8,0xd4,0x8c,0xc2,0x83,0x5b,0x68,0x42,0xbc,0x22,0x9a,0x2b,0x2a,0x4f,0x3e,0x1c,0x52,0x21,0x14,0x58,0x75,0x1e,0x31,0xcf,0xac,0xaa,0xa3,0xd7,0x31,0x0e,0x73,0x79,0x31,0xf6,0xbe,0x3d,0xe2,0x27,0x23,0x58,0xda,0xc2,0xb5,0xce,0xd8,0x91,0x76,0x97,0x3c,0x64,0x4b,0x95,0xce,0x93,0x52,0x32,0xfe,0x33,0x3b,0xef +.byte 0xa4,0xed,0xdf,0x81,0x18,0xc7,0x08,0x51,0x81,0xf2,0xfb,0xf8,0x2d,0xcf,0x69,0x21,0x05,0x15,0xed,0x9d,0xf7,0x87,0x64,0xeb,0x9b,0x0b,0x2c,0x9b,0xf3,0xbf,0x32,0x21,0x27,0x38,0x20,0xc3,0x5f,0xb8,0xfe,0x17,0xf5,0x8f,0x3f,0xac,0xda,0x49,0x3d,0x54,0x14,0x9e,0xd5,0x89,0xdb,0x20,0xda,0x43,0x67,0x84,0x4b,0xb7,0x11,0xd3,0x08,0x2f +.byte 0x56,0x8f,0x95,0x79,0x82,0x28,0xec,0x45,0x3c,0xc5,0xa7,0xd7,0xad,0xaa,0x82,0xda,0x87,0xb3,0x32,0x3e,0x27,0xf4,0x3d,0x27,0xcf,0x2d,0x04,0x00,0x22,0x13,0x36,0x57,0x8c,0x84,0x10,0x4a,0x7c,0xbb,0x57,0x13,0x1f,0x4d,0x64,0x60,0x14,0x64,0x85,0x9a,0x05,0x46,0xfc,0x10,0x6f,0x67,0x82,0x5a,0xb9,0x65,0xd5,0x00,0xfa,0x07,0xb3,0x70 +.byte 0x18,0x94,0x3a,0x4f,0xef,0x6e,0x4d,0x13,0xf3,0x63,0x5a,0xa1,0xe1,0x19,0xbf,0xc0,0x2e,0xf5,0x1f,0x53,0x7c,0x33,0xc3,0x5b,0xab,0xbd,0xdf,0x90,0xca,0x2d,0x20,0xb4,0x4e,0x6a,0xea,0xa5,0xad,0x62,0x20,0x8a,0xbf,0xf4,0xc4,0x90,0x5b,0xa8,0xe5,0xea,0xe9,0x53,0x42,0x33,0x29,0xce,0x46,0x69,0x4f,0x58,0x18,0xab,0x15,0xc2,0x5f,0x50 +.byte 0x6f,0x31,0xcf,0x09,0x23,0x2e,0xf5,0x29,0xef,0xad,0xcb,0x36,0x7c,0xf1,0x5d,0x0c,0xf6,0xfc,0xfb,0x17,0x08,0x31,0xa7,0xa9,0xc9,0x56,0x51,0xcf,0x27,0xea,0x25,0x15,0x89,0xe1,0xe4,0x1c,0x18,0x30,0x4c,0xd4,0x2a,0x0e,0x68,0xd6,0x07,0x19,0x51,0x95,0xdd,0x70,0x60,0x98,0x1d,0x21,0xab,0x59,0x36,0xb3,0x2c,0xc2,0xbf,0xdb,0x79,0xbe +.byte 0xd6,0x32,0xff,0x86,0xa0,0xfc,0xa9,0x7a,0xb7,0x08,0x40,0xb8,0x6d,0x44,0x78,0xe6,0xae,0x52,0x3d,0x60,0x48,0x0c,0xd3,0x72,0x30,0x1c,0x51,0x1e,0x5f,0x1d,0x34,0x7c,0xfb,0x08,0x04,0x1d,0xcc,0x6e,0xec,0x67,0xd8,0x65,0xae,0x63,0xba,0x7b,0xeb,0xd6,0x15,0xbe,0x69,0x41,0xdc,0x67,0x09,0x20,0x6e,0xa5,0x19,0xc7,0xc2,0xd2,0x12,0x74 +.byte 0x1e,0x27,0xed,0xc4,0x61,0x23,0xcc,0xb8,0xc0,0x1c,0xb9,0xb2,0xc4,0x4c,0x9b,0x04,0x4b,0x41,0x63,0x2a,0x04,0xef,0xe9,0x12,0x14,0x9f,0xbf,0x36,0x0f,0x73,0x68,0x14,0xdb,0x12,0x5c,0x27,0xcc,0xd3,0xb4,0x2a,0xa9,0x45,0xeb,0x7e,0x72,0xab,0x22,0x23,0x0f,0xa2,0x7c,0x67,0xa6,0x3e,0x74,0xb6,0x84,0xb0,0xab,0x65,0xe2,0x4e,0x31,0x5a +.byte 0xec,0x30,0x52,0x94,0x58,0x08,0x26,0x1f,0x7a,0x3c,0xed,0x38,0xcb,0x2d,0x3d,0x13,0xab,0x2c,0x37,0xb5,0x68,0x5a,0xb5,0x35,0xb6,0xc6,0xa5,0x20,0xdb,0x2f,0x66,0xb4,0xf3,0xae,0x3a,0xf8,0x22,0x86,0x6b,0x09,0x98,0xce,0x8f,0x2b,0x9c,0x1a,0xa2,0x47,0x05,0xbb,0xf1,0xf5,0x2d,0x5c,0xfb,0xc4,0x6e,0xeb,0x1f,0x4c,0x40,0x3d,0x97,0x1d +.byte 0x86,0xf0,0xf8,0x17,0xd6,0xd9,0x3f,0x65,0x33,0x30,0x85,0x37,0x5a,0xf6,0x7d,0x39,0xac,0x87,0x99,0xeb,0x76,0xcc,0x79,0xe2,0xda,0xe9,0xc4,0x62,0x4d,0x4a,0xbf,0x67,0x22,0x10,0x91,0xbe,0x25,0x8f,0xd7,0x28,0x75,0xbc,0x52,0x2c,0x66,0x3e,0xc0,0x35,0x4c,0x02,0x37,0x96,0x6b,0x90,0x00,0xaf,0x23,0x49,0x90,0x4d,0x97,0x90,0x9f,0x06 +.byte 0xde,0x9b,0x63,0x57,0x88,0x33,0x40,0xd5,0xd7,0xcc,0xf2,0xa8,0x9e,0x5f,0x40,0xb6,0x17,0xae,0xe5,0xda,0x4c,0x2f,0x9d,0xc7,0xfd,0x1a,0x62,0x8e,0x99,0x8e,0x47,0x96,0x31,0xc1,0xb9,0x72,0x73,0xd4,0x7f,0x31,0xa3,0xfb,0x67,0xed,0x3c,0x44,0x9b,0x9c,0x21,0x4b,0xaf,0x91,0x80,0xfc,0x8f,0x4a,0x6c,0x83,0x4f,0xb3,0xb0,0x2f,0x5c,0xee +.byte 0xeb,0x9b,0x8d,0xb0,0x18,0x46,0xcb,0xfc,0x0a,0x46,0x4a,0xe5,0x88,0xb0,0x08,0x75,0x78,0x61,0x2f,0x1a,0x26,0x70,0x43,0xcf,0x5a,0xbb,0xb4,0x1a,0x65,0x19,0xbb,0xe7,0xe1,0x23,0xd3,0x39,0x79,0x76,0xb7,0x1c,0xe2,0x05,0x90,0x43,0x8c,0xb6,0xa0,0xca,0x05,0x28,0xa5,0xd7,0x42,0x02,0x2f,0x2c,0xc1,0x6c,0x29,0xaf,0xfe,0x68,0x71,0x82 +.byte 0x43,0x9d,0x55,0xd6,0x6e,0x49,0xdb,0xf0,0x3c,0x7b,0x10,0x22,0x77,0x16,0xe7,0x75,0xe8,0x54,0x47,0x49,0xae,0x3b,0x4b,0xc8,0x97,0xa4,0xf2,0x63,0xff,0x2a,0xd1,0x01,0x18,0x24,0x13,0x18,0x27,0x02,0xfd,0xe2,0xf5,0xc7,0x21,0xb8,0x15,0x45,0x9a,0xb5,0x82,0xd6,0xde,0x08,0x44,0x4c,0xb2,0x4f,0xa0,0xd6,0x4f,0x84,0x04,0x83,0xe1,0xf5 +.byte 0xce,0xa5,0x6f,0xa8,0x24,0x91,0xf6,0x52,0x8b,0x5e,0x2f,0x66,0x58,0x74,0xbc,0xd3,0x91,0xe7,0x25,0x2d,0x2d,0x69,0xf3,0x6a,0xe9,0x96,0x18,0x64,0x59,0x7b,0x62,0x13,0x4b,0x3e,0x15,0xbd,0xe0,0xff,0xe3,0xa9,0x70,0x9a,0xba,0xcd,0x90,0xcd,0xf0,0x89,0x2b,0xa6,0x38,0x7b,0xe1,0x67,0x89,0x85,0x0c,0x2e,0x16,0xea,0x97,0x2d,0x6e,0x6f +.byte 0x1f,0x9c,0x0a,0xf3,0xe5,0x95,0x03,0xc2,0xe4,0x84,0xc8,0x0d,0x08,0xb7,0x59,0x25,0x5b,0x77,0x7f,0x7c,0x43,0x16,0xb7,0x27,0x38,0xf1,0x71,0x50,0x0d,0xed,0xa8,0xc6,0x27,0x36,0xf1,0xaa,0xa6,0x43,0x3f,0x1f,0xc1,0xa2,0xc5,0x23,0x46,0xf8,0x9c,0xe5,0x5f,0xb9,0x25,0x3b,0x71,0xb3,0xe2,0xc7,0xa5,0x7e,0x30,0xc5,0xe9,0x3b,0x4e,0xa1 +.byte 0xd6,0x33,0x3c,0x8b,0xb9,0x08,0x93,0x3c,0xc5,0x4c,0x7c,0x7c,0x8b,0xe9,0xa7,0x46,0xa8,0x9e,0x97,0xc5,0x71,0x7e,0x81,0xa6,0x22,0x49,0xb0,0x25,0xa8,0x74,0xba,0x7b,0xce,0xf8,0xd6,0xe8,0xf1,0xa1,0x0f,0x03,0xe6,0x8a,0x30,0x02,0xba,0xde,0xaa,0x16,0x0d,0x7a,0x4a,0x86,0xf8,0xd0,0x80,0xf6,0xde,0x9e,0x70,0xe2,0xa9,0x7c,0x98,0xde +.byte 0x6b,0x8b,0x04,0xa3,0xb4,0xa9,0xfb,0x15,0x5e,0x40,0x92,0xa0,0xb7,0x36,0xab,0x8d,0x02,0xb0,0x95,0x4c,0x3f,0x5d,0xa6,0x17,0xd3,0x98,0x41,0xe0,0xfb,0xf2,0x49,0x3b,0xf6,0xb5,0xfe,0xc7,0x8d,0x77,0xa7,0x1e,0xcb,0x10,0x32,0xf0,0x55,0x7e,0x44,0x6e,0xa8,0xc6,0x2c,0x52,0x09,0xda,0xe6,0x02,0x7c,0xc2,0xfe,0xe7,0x05,0xc8,0x37,0xc4 +.byte 0x90,0x5a,0xed,0x54,0xaa,0x29,0xbd,0x3c,0x22,0x34,0xd7,0x41,0x5b,0xf5,0x89,0x1e,0x22,0x87,0xc3,0x51,0x90,0xc4,0xe5,0x77,0x41,0x6b,0xcc,0x23,0x61,0x6c,0x89,0x55,0x79,0x15,0xdc,0x3b,0x3f,0x52,0x2f,0x67,0x8c,0x0f,0x56,0xbb,0x8b,0x06,0x72,0x62,0x76,0xf7,0xa2,0xe2,0x00,0x70,0x78,0x3f,0x52,0xc5,0xcb,0x10,0x22,0x59,0x44,0x81 +.byte 0x5d,0x05,0xd2,0x92,0x72,0x6e,0x8b,0x3e,0x52,0x54,0x06,0x5b,0x51,0x55,0x08,0x81,0x5a,0x1c,0x82,0x86,0x30,0x7c,0x0e,0x66,0xdd,0x17,0xad,0x1f,0x54,0x85,0xd6,0x4f,0x9b,0x4d,0x49,0x42,0xdf,0x6c,0xa1,0x6a,0x18,0x00,0x38,0xb6,0xf7,0x8d,0xbb,0xce,0x7a,0xbb,0xcb,0x59,0x03,0x2d,0x7e,0x56,0x33,0x54,0x5f,0x46,0x7a,0xba,0x24,0x17 +.byte 0x22,0x3b,0xb4,0x86,0x1d,0xa7,0x92,0xea,0x85,0x99,0x67,0x85,0x9a,0x45,0x53,0xce,0x9f,0x44,0xea,0xb2,0xac,0x24,0x8e,0x0c,0x0b,0x8c,0x21,0x00,0xe8,0xd5,0x08,0xe3,0xbe,0x1a,0xd5,0x3e,0xaa,0x62,0xf0,0xcd,0x5f,0xae,0x5b,0xef,0x89,0xf0,0xc0,0x48,0xa4,0xdc,0xd4,0x60,0xd3,0xd5,0x05,0x42,0x7f,0xb1,0xec,0x1d,0x62,0x0e,0xe8,0xe4 +.byte 0x4d,0x20,0x9e,0x25,0xc0,0xa5,0x7c,0xe4,0x5f,0xf7,0xfa,0xf1,0x50,0x3b,0x39,0x62,0x10,0x09,0x46,0x24,0x47,0x49,0x75,0xf7,0xae,0x2b,0x2c,0x79,0x23,0xfe,0xcd,0x81,0xdf,0x0b,0x94,0xe3,0x4d,0x2e,0xe8,0x4a,0x87,0x70,0xec,0xfe,0xa8,0xda,0x06,0x86,0x62,0x30,0x00,0x0c,0x76,0xa4,0xd1,0x48,0x6d,0xdb,0xa6,0xb5,0x65,0x35,0xcd,0xa2 +.byte 0xd7,0x95,0x9b,0x0e,0x3e,0x7d,0xe6,0xd3,0x3a,0x6b,0x26,0x9a,0x50,0xd6,0x12,0xe5,0x76,0xff,0xa6,0xfd,0xbf,0xb7,0xba,0xee,0x42,0x09,0xa4,0x2b,0x10,0x64,0xab,0x43,0xaa,0xe0,0x1d,0xe5,0x35,0xf4,0xc7,0xa3,0xb0,0xc4,0x1a,0xd3,0x8b,0x03,0x9f,0xd0,0x2b,0xa5,0x26,0x70,0x92,0x0d,0xe5,0x3b,0xb8,0x62,0x6b,0x4a,0xc5,0x93,0x6b,0xc8 +.byte 0xbe,0x66,0x51,0x0b,0x56,0xed,0xee,0x6c,0xf1,0xf3,0x05,0xc1,0x7a,0xae,0xf6,0x26,0xe5,0x4d,0x1e,0x0b,0xf9,0x29,0xc4,0xd7,0x80,0x75,0x3f,0x5c,0x60,0xa6,0x06,0x09,0x58,0x4b,0xfd,0xa3,0xc2,0x76,0xd8,0x43,0x66,0x04,0xdd,0x84,0x9f,0x5e,0x15,0x87,0xe8,0xf7,0xa4,0x56,0xf4,0x81,0x88,0x98,0x26,0xa4,0x24,0x3c,0xfb,0x7e,0xb6,0xbf +.byte 0xe8,0x0f,0x12,0x31,0xe5,0x84,0xa9,0x3b,0x73,0x48,0x03,0x7c,0x0b,0x8c,0x52,0x2d,0x6c,0xa3,0x66,0x1e,0x00,0xc7,0x1d,0xe2,0x41,0x68,0x04,0x0a,0x66,0x13,0xe9,0x17,0xca,0x16,0x79,0x44,0x17,0xaf,0x41,0x0e,0x50,0x4f,0x1f,0x28,0x3e,0x68,0x80,0xb1,0x62,0x20,0x9e,0x1c,0xaa,0x18,0xa8,0x1d,0x09,0xed,0xe2,0x97,0xc2,0x9c,0xec,0x99 +.byte 0xd6,0x12,0xde,0xd1,0x48,0x9c,0x1e,0xdf,0x0c,0xb5,0x6c,0x17,0x3d,0x59,0xe6,0xfc,0xe6,0xd5,0x1a,0x70,0x66,0x49,0xf5,0x09,0x30,0x11,0x5b,0x5d,0x1a,0xeb,0xc7,0xf8,0xe5,0x44,0xf5,0x3f,0x93,0xde,0xf5,0x2a,0x00,0x72,0x19,0xae,0xde,0xe9,0x7f,0xc7,0x30,0x9c,0x95,0x17,0x33,0xca,0x2c,0xd5,0x75,0xcf,0xb7,0x1b,0xd0,0x4d,0x58,0x1e +.byte 0x07,0x23,0xa8,0x8d,0x63,0x9d,0x95,0x92,0x8b,0xbd,0x77,0xe3,0xa0,0xd0,0xe0,0x43,0xeb,0x9d,0xdf,0x96,0xb2,0x4e,0xac,0x37,0x74,0xf3,0x54,0x9b,0x48,0x32,0x49,0x80,0x9d,0x68,0x7b,0x9f,0x2c,0x74,0xbb,0x31,0x22,0x71,0xf1,0x3c,0xaa,0xf3,0x07,0x64,0x4d,0x55,0xb9,0x18,0xb3,0xe5,0x02,0xce,0x07,0xec,0xfc,0x6d,0x73,0xc8,0x48,0xc8 +.byte 0xab,0x6b,0x3a,0x8a,0xa2,0x06,0x37,0x7d,0xf7,0x8f,0xc8,0x6f,0xc1,0xc0,0x28,0x0e,0x66,0x79,0xdf,0x76,0x51,0x48,0x3d,0x0d,0x94,0x48,0x0c,0xae,0x05,0xa6,0xf3,0x2b,0xa4,0x71,0x22,0xb0,0x38,0x81,0x45,0xc3,0x68,0x4b,0x0d,0xec,0x06,0xad,0xa8,0x5b,0x25,0x25,0x1c,0xda,0xfe,0xc2,0xe5,0x6a,0x81,0xd5,0xe2,0x3f,0x8d,0x9d,0xcb,0xb0 +.byte 0x5c,0xb4,0xdb,0x14,0xa9,0x61,0x3c,0x77,0xe6,0x1b,0xc8,0x18,0xfa,0xc7,0xf2,0x03,0x96,0xd0,0xcb,0xd8,0x38,0xfd,0xcf,0x3c,0xf0,0xc4,0xd6,0xe4,0xff,0x86,0x11,0x03,0x85,0x30,0xee,0x57,0xf7,0x53,0xf8,0xbe,0x81,0x88,0x54,0x4f,0x57,0x63,0x36,0x6b,0xbb,0x44,0x21,0x84,0xa1,0x5d,0x03,0x01,0xc4,0xca,0xe2,0x89,0xec,0x8e,0x55,0xe0 +.byte 0xb7,0x24,0x9a,0xd8,0x43,0x51,0xc3,0xe7,0xbe,0xa7,0x40,0xcb,0x35,0xa9,0x3c,0xa0,0x03,0x71,0x51,0x22,0x03,0x0f,0xc7,0x3e,0xcb,0x33,0xab,0xb5,0xfb,0x91,0x0e,0x21,0x51,0x0d,0x67,0x66,0x89,0xac,0xa8,0xd3,0xda,0x25,0x78,0xa4,0xd7,0x16,0x0e,0x48,0xee,0xc8,0x89,0xc4,0x4b,0x99,0xe2,0x55,0x0c,0x69,0x0c,0xc4,0xe8,0xd7,0xee,0x2d +.byte 0x5a,0x5f,0x56,0xf7,0x9a,0xad,0x61,0x32,0x9c,0x73,0x91,0x9a,0x60,0xb2,0xbe,0x36,0xfe,0xb1,0x54,0x89,0x6d,0x32,0x10,0x5b,0xc4,0x60,0xe1,0x9d,0xbb,0x12,0xf0,0xaa,0x73,0x69,0x2c,0x4d,0xb6,0xce,0x0a,0x47,0x5a,0x5c,0x4c,0x25,0x7e,0xb9,0x56,0x79,0x55,0x67,0x98,0x3e,0xc0,0xdd,0xe4,0x97,0xe7,0x6b,0x1a,0xa5,0x8d,0x26,0xfb,0x7e +.byte 0x85,0x7e,0x0a,0xa3,0x43,0xbc,0x99,0xa7,0x34,0x82,0xda,0xd9,0x92,0x58,0x79,0x8d,0x3b,0xa6,0x08,0x47,0xdd,0x18,0x33,0x68,0xdd,0x97,0x6b,0x14,0x9e,0xa4,0x7b,0x3e,0x48,0xf4,0x3f,0x44,0x18,0x07,0xc1,0xef,0x15,0xbb,0xba,0x5e,0x2d,0x92,0xdc,0x20,0xc9,0x87,0x06,0x8d,0x0b,0x69,0xed,0x94,0x98,0xe6,0x1a,0x5b,0x0c,0xb2,0xaf,0x54 +.byte 0x27,0x49,0x1e,0x9a,0xc3,0x5d,0xf7,0xc5,0x82,0x8c,0xa0,0xfd,0xf2,0xc3,0x68,0x60,0xf7,0x88,0xb9,0x04,0x6c,0xb2,0xeb,0x9a,0xcd,0x9f,0xe9,0xd8,0xfc,0xbd,0xed,0x72,0x11,0xf6,0xb4,0x7b,0xd8,0x64,0x5e,0x55,0xc7,0x19,0xcf,0xd7,0xb3,0x47,0xdd,0xb2,0x3e,0x18,0x7b,0xb2,0xc7,0x5c,0x9d,0x99,0x05,0x2d,0x22,0x94,0xc2,0x0e,0xab,0x0b +.byte 0x7f,0x1f,0xc4,0x3f,0x63,0xcf,0x52,0x43,0x2e,0x92,0x76,0xff,0x8a,0xce,0x61,0x4b,0xf3,0x44,0x91,0x7e,0x11,0x7d,0x73,0x06,0xda,0xde,0x54,0xad,0x7a,0x09,0x85,0xfd,0x58,0x24,0xee,0xae,0x0c,0x86,0xca,0x39,0x12,0xe2,0x5b,0xe6,0x65,0x0e,0x9e,0x94,0xe0,0xfa,0x41,0x56,0x9e,0x73,0x1a,0xd8,0x09,0xe4,0xb3,0xe9,0x8f,0xb0,0x35,0x69 +.byte 0x61,0x9f,0xe9,0x9f,0x19,0x11,0x1a,0x41,0x06,0xc3,0x6f,0xc1,0x73,0xb7,0x14,0x0b,0x31,0x4e,0xc5,0x54,0xd3,0xef,0x17,0x2b,0xad,0xe3,0xaa,0xcd,0x42,0xd9,0xe9,0xba,0x77,0x48,0xaf,0x86,0x68,0xaa,0x69,0x56,0xc2,0xfd,0x82,0xcc,0xd5,0xa1,0x98,0x17,0x5f,0x2d,0x5f,0xee,0x3b,0xb2,0x11,0x56,0x36,0xdb,0x88,0xd7,0xed,0x21,0x67,0x4d +.byte 0xe4,0x78,0x38,0xab,0x97,0xaa,0xd6,0x41,0x70,0x82,0x8e,0x65,0x3e,0xd2,0x6d,0xb3,0xad,0x6b,0xcc,0x0c,0x0e,0x2c,0x3d,0xdd,0xf9,0xaf,0x21,0xc9,0x65,0x2c,0x4c,0xd8,0x95,0xe2,0x35,0xa8,0xe1,0x67,0xd9,0x93,0x22,0xd4,0x37,0x5e,0x8b,0x15,0x5c,0x2e,0xa0,0x1f,0x10,0x58,0x58,0x84,0x87,0xb3,0x2a,0xd6,0x7c,0xcd,0x3e,0x9b,0x13,0x4f +.byte 0x16,0x19,0x5d,0x99,0xa0,0x0b,0x3b,0x7a,0x5e,0x5b,0xfa,0x64,0x7d,0x0c,0x2b,0xfb,0x32,0x76,0xc7,0x95,0x40,0x52,0x1d,0x5a,0x71,0xb5,0xfc,0xeb,0xc6,0x93,0x45,0x55,0x24,0xa8,0x9f,0x5d,0x5c,0x22,0xe4,0x1d,0xda,0x7c,0xcf,0x06,0x6d,0xcf,0x8b,0xd0,0x11,0x96,0xcd,0x57,0xb5,0xa9,0x3c,0xfe,0x6c,0xf2,0x1e,0xa3,0x22,0x5f,0x7c,0x62 +.byte 0xdd,0x01,0xe2,0x2e,0xb7,0xda,0x79,0x93,0x69,0xd5,0xf0,0x9e,0xeb,0xa3,0xf7,0x18,0xd6,0x92,0x13,0xfe,0x24,0xb3,0x83,0x65,0x07,0xe5,0x80,0x28,0x52,0xc0,0x3b,0x4e,0x99,0xcf,0x53,0x75,0xe9,0xd5,0xa3,0xea,0x79,0x69,0x54,0x71,0xd6,0x25,0x43,0x1d,0x36,0xc4,0x74,0xa6,0x20,0xa4,0x0b,0xd7,0x24,0xb2,0xc5,0xee,0x49,0xae,0x8e,0xe4 +.byte 0xc3,0x18,0x47,0xc0,0xb5,0x49,0x9a,0xf4,0x39,0x35,0xe4,0xb9,0xb0,0x5f,0xbb,0x81,0xf4,0xc7,0x1e,0x2b,0x24,0x93,0xae,0x5d,0xd9,0x13,0xea,0xa7,0xfd,0xdd,0x80,0xe7,0x90,0x70,0x4f,0x43,0xbe,0x72,0x32,0x73,0xb4,0x08,0x14,0x90,0x08,0xa4,0x1f,0x11,0x9b,0x80,0x1e,0x0e,0x5f,0x5c,0x46,0x9b,0xe9,0xe5,0x88,0x17,0x3b,0x7b,0xc3,0x9a +.byte 0xfb,0xf0,0x37,0x06,0xb9,0x18,0x5c,0x1f,0x07,0x84,0x1e,0x74,0x6c,0x94,0xa7,0x52,0xbc,0xf1,0x76,0xd3,0xfd,0xab,0x47,0xea,0x2d,0x58,0x51,0x4a,0x87,0xc4,0x5b,0xc0,0x93,0xb1,0x31,0x96,0xec,0xe5,0xe2,0xea,0xdd,0x84,0xb1,0xf7,0x5f,0x38,0x2e,0x98,0x52,0xdc,0xb8,0x3b,0x69,0xde,0x09,0xa3,0x24,0x65,0x2d,0x44,0x36,0x26,0xbe,0xcc +.byte 0xb2,0xaa,0x30,0x67,0xad,0x96,0x39,0xa7,0xe7,0x92,0x59,0x69,0x2a,0x46,0x51,0x48,0x25,0x11,0x81,0xe5,0xf8,0x59,0x77,0x14,0xc5,0x14,0x4e,0x93,0x75,0xc0,0xb5,0xf1,0xbb,0x90,0xf1,0xa9,0xd9,0x72,0x43,0x8f,0xfb,0xe8,0xbe,0x69,0x80,0xb7,0x51,0x71,0x9d,0x70,0xdd,0x01,0x95,0x84,0x78,0xd1,0xf0,0x86,0xc9,0x06,0xa8,0xaf,0x5d,0xbd +.byte 0xdd,0x68,0xbf,0x8a,0x4b,0x64,0xe6,0x1a,0x48,0xc4,0x34,0x3f,0xce,0x7b,0x04,0x2c,0xa4,0x12,0x62,0x69,0xfe,0x05,0x12,0x2d,0x16,0x49,0x2f,0xa1,0x69,0xd4,0x9e,0x95,0x61,0xa2,0x24,0x34,0xfc,0x51,0xb7,0x89,0x3a,0x2a,0x80,0xce,0x3b,0xe5,0x16,0x8f,0x6e,0x35,0x19,0x1d,0x78,0x27,0x1c,0x81,0x52,0xf3,0x93,0x83,0x83,0x94,0x95,0x5d +.byte 0xaa,0x94,0x28,0xc6,0xd5,0xec,0x38,0x95,0x50,0x12,0x9d,0xc2,0xc2,0x28,0x2c,0xf8,0x30,0xa5,0x79,0x19,0x79,0xf4,0x71,0xd3,0xc0,0xfd,0xc3,0x64,0x1a,0x95,0x5c,0x79,0xef,0x73,0x8d,0x66,0xbb,0x63,0x53,0x24,0x5d,0xb2,0xf9,0x94,0xe6,0xcc,0xf3,0xe9,0xf4,0x94,0xcf,0x77,0xbe,0x25,0x0e,0x2c,0x5e,0xed,0xdd,0x49,0x25,0xd3,0x15,0x54 +.byte 0x68,0x49,0x15,0x27,0x7d,0x1e,0xa2,0x95,0x8d,0xf7,0xea,0xe5,0x1c,0x33,0x90,0x4f,0x83,0x06,0x17,0xd4,0x5e,0x6e,0xe6,0x3a,0x90,0xda,0x4b,0x31,0x57,0x0e,0xab,0x98,0x1d,0x87,0x63,0x20,0x9e,0xd7,0x00,0xa0,0x1e,0x77,0xef,0x22,0xf4,0x4b,0xd2,0x58,0xaf,0xfd,0xe1,0xa2,0xb0,0xb9,0x9b,0x2a,0x75,0x6a,0xc7,0x51,0xe3,0x3b,0x66,0x83 +.byte 0x65,0x9c,0x87,0x09,0x56,0xd0,0x09,0xa8,0x6b,0x08,0x77,0x46,0x86,0x3f,0xe6,0x63,0x62,0xdc,0x82,0xd1,0x04,0xe5,0xa8,0x36,0x70,0xa8,0xe8,0xb3,0xb0,0x85,0xac,0x5a,0x11,0x54,0xd2,0x68,0x35,0xfa,0x4c,0x5e,0x15,0x64,0x77,0x6c,0x25,0xf4,0x19,0x8b,0x7e,0xe2,0xb1,0x7d,0x1d,0x63,0x5b,0x8c,0xa6,0x42,0x72,0x60,0x1e,0xe3,0x54,0x3a +.byte 0x5b,0x9c,0x8d,0x6c,0x4b,0x28,0x2d,0xf6,0xd2,0x80,0x66,0xbe,0x79,0x91,0x64,0x11,0xe6,0x3e,0x5c,0x3e,0x8b,0x71,0x40,0x06,0x7f,0x26,0x8d,0xf3,0xce,0xc9,0x6d,0x9c,0x94,0xf4,0x22,0xff,0xac,0xeb,0x5a,0xb2,0x99,0x86,0x66,0x66,0xb5,0xfd,0x62,0xcc,0xf6,0x20,0xca,0xb9,0xb5,0xc4,0xc7,0xe9,0xca,0x23,0x59,0x2b,0xa6,0xae,0x53,0x8e +.byte 0xdf,0xd5,0xc1,0x0e,0x52,0x8c,0x35,0x7c,0xb3,0x03,0x41,0x7c,0xdc,0x87,0x4a,0x59,0x56,0x5c,0x88,0x6c,0xa9,0x10,0x6b,0xd5,0x04,0x42,0x5d,0x60,0xef,0xc2,0xc1,0x28,0x36,0x91,0xd8,0xd0,0x62,0x30,0xa4,0xaf,0x5b,0x06,0xb0,0x86,0xc1,0xb2,0xff,0xc3,0x3d,0x41,0xb8,0xe9,0x12,0xde,0xab,0x4a,0xaf,0x57,0xfb,0xdf,0xb0,0x15,0xd1,0x1e +.byte 0xed,0x69,0xb5,0x79,0x5a,0x3d,0xeb,0xd3,0x3c,0x33,0x27,0x71,0x7a,0x7c,0xf2,0x28,0x50,0xe3,0x96,0x0d,0x6d,0x18,0x7d,0x7d,0xe2,0xb3,0x9b,0x9b,0x49,0x7f,0xe3,0xba,0xd1,0xf1,0xbc,0x9c,0xae,0x73,0xf8,0x35,0x71,0xbd,0xc1,0x4b,0xbc,0x36,0x08,0xf9,0x9e,0x78,0x57,0xc5,0xd0,0x52,0xc9,0x93,0xb4,0x7f,0x06,0x6b,0xc2,0x2e,0x8a,0x9b +.byte 0x8a,0x8b,0xf5,0x69,0xc4,0xaf,0x61,0xbb,0xc3,0x79,0x40,0xa2,0x8f,0xd6,0x76,0xcd,0x51,0x4b,0x91,0x75,0xfa,0x9f,0x19,0x8d,0x29,0xe2,0x25,0xae,0x8d,0x34,0x31,0xeb,0x26,0x42,0xca,0x69,0x1c,0xba,0x37,0xa0,0x6d,0x5f,0x60,0x04,0xc3,0x96,0xad,0xdc,0x8f,0xf0,0x51,0x54,0x89,0xc8,0x71,0xe6,0x9d,0x7b,0x11,0xad,0xc9,0xbe,0x38,0x40 +.byte 0x4f,0x90,0x7c,0x6c,0xa1,0x1f,0x2d,0x92,0x29,0xf1,0x37,0x8b,0x55,0x20,0xf0,0x85,0x93,0x93,0x6f,0x72,0x4a,0x11,0x60,0x06,0x4d,0xd9,0xf0,0x0e,0xf8,0xf8,0xea,0x2e,0x4a,0x31,0x48,0xa3,0x9c,0xf7,0xac,0x64,0x84,0x59,0x91,0x5f,0x0d,0xd5,0x54,0x05,0x01,0x63,0x89,0x4b,0x11,0x72,0x52,0x0f,0xa4,0x13,0x8e,0x3c,0xb9,0x25,0x2c,0xb6 +.byte 0x48,0x11,0xe7,0xe7,0xc1,0x5f,0xca,0x0c,0x2a,0xf0,0xe3,0xcf,0x29,0x5b,0x99,0xe0,0x05,0xae,0x59,0x14,0x97,0xba,0x31,0x1f,0xf4,0xc4,0x45,0xb0,0x89,0x22,0x68,0x29,0x97,0xf3,0xf9,0x2f,0x68,0x1a,0x3f,0xb3,0x6b,0x88,0xa9,0x8e,0x20,0x31,0xc5,0x63,0x13,0x6b,0x2d,0x52,0x18,0x98,0xc8,0x34,0x07,0x85,0x14,0xb2,0x6c,0xcc,0x78,0xdb +.byte 0xb5,0xee,0x08,0xb5,0xfa,0xb7,0x40,0x98,0x2d,0x1c,0x46,0xa7,0x2e,0x78,0xad,0x6f,0x95,0x02,0x57,0xbc,0xfd,0x5f,0xf4,0xe0,0xbd,0x7f,0xae,0x0e,0x52,0xf4,0x34,0x9b,0x6a,0xbe,0xba,0x6a,0x30,0x86,0x7a,0x47,0x60,0x86,0xa1,0x9a,0x48,0xe1,0xea,0xca,0xab,0x4d,0x2f,0xdf,0x84,0x1c,0x51,0x44,0xfa,0x8a,0xc2,0x59,0x0b,0x86,0xc0,0x73 +.byte 0xed,0x72,0xa2,0x22,0x73,0x93,0x69,0xfe,0x39,0x07,0x5f,0x75,0x6f,0xf8,0x30,0x7c,0xea,0xea,0xda,0x30,0xfd,0x22,0x31,0xf8,0xd9,0x68,0x3d,0x75,0x93,0xc0,0xb0,0x5a,0x1d,0xa1,0x62,0x35,0x43,0xab,0xdc,0x82,0x4b,0xa8,0x40,0x0d,0x7f,0xeb,0x02,0x90,0x55,0x10,0x47,0xfd,0xfc,0x2f,0xe7,0x8f,0xe0,0x48,0x41,0x14,0x1a,0xaa,0x51,0x25 +.byte 0xad,0x79,0x23,0x6c,0x08,0x44,0x31,0xff,0x0f,0x4a,0x57,0x58,0x76,0x08,0xa0,0x28,0x56,0x9e,0x70,0x3a,0x3a,0xd0,0x00,0xc6,0xa6,0x7f,0x5e,0xfd,0x88,0xcb,0x12,0x51,0x3b,0x97,0xb0,0xe9,0x8a,0x57,0x8f,0x4c,0x2e,0xba,0xc7,0x8f,0x47,0x05,0x4e,0xb0,0x98,0x22,0x85,0x80,0x43,0x09,0xc9,0xda,0x90,0x86,0x14,0xc3,0x5c,0x00,0x2f,0x39 +.byte 0x2f,0xc0,0xf9,0x37,0xe6,0xee,0x56,0xee,0xa2,0x05,0x14,0xe6,0x63,0xbd,0x6d,0x8f,0x21,0x46,0xbd,0x7f,0x67,0x0e,0x14,0xaa,0x11,0xf5,0x1b,0xfb,0x06,0x6b,0xbf,0x82,0x25,0xaa,0x8d,0x15,0xc3,0x86,0x1c,0xb5,0xcb,0xdf,0xa1,0x9d,0xd8,0xd6,0x0b,0x89,0x76,0x71,0xb8,0x5d,0x16,0xde,0x1d,0x04,0x17,0xb3,0x0f,0x26,0xc8,0xc5,0x95,0x35 +.byte 0xcf,0xf4,0x6b,0x71,0x38,0xa2,0x87,0xcf,0xca,0xda,0x67,0x2b,0x01,0x37,0xbc,0x35,0x33,0x0c,0xff,0xe2,0x1e,0x33,0x96,0xb4,0x10,0x7f,0x8f,0x9c,0x42,0x07,0x73,0x4c,0xfc,0x47,0xf4,0xa5,0x1a,0x8d,0xd8,0x65,0x97,0x16,0x89,0xb6,0x25,0x50,0xd2,0x40,0x31,0x56,0x9d,0x30,0xf6,0xe3,0xcc,0x79,0x83,0xcb,0xf6,0xf7,0xdb,0x8e,0xe0,0xc9 +.byte 0x6d,0xac,0xca,0x6c,0xfe,0x1c,0xc1,0xde,0x4e,0xa8,0xea,0x06,0x33,0x96,0x98,0x99,0xe1,0xe9,0x28,0xe0,0x0c,0x15,0xcd,0x75,0x1b,0x4c,0xc3,0x9b,0xea,0x86,0xd2,0xeb,0xd3,0x92,0x4e,0xdb,0xc5,0x41,0x20,0x52,0xf9,0x11,0xf8,0x17,0xb0,0x78,0x07,0xf3,0x99,0x53,0xee,0x24,0x05,0xc2,0xc7,0x44,0x66,0x8b,0xa0,0x5c,0x90,0x6a,0xc6,0xa6 +.byte 0xe8,0x95,0x88,0x60,0xf7,0x9f,0x5e,0x64,0x7c,0x24,0xbb,0x3f,0x51,0x61,0x7a,0xc0,0x89,0x6d,0x49,0xfe,0x41,0x95,0xee,0x13,0x80,0x2d,0xeb,0x5b,0x60,0xc4,0x3d,0xb2,0xce,0xd0,0x29,0x24,0xb4,0xc7,0xc5,0xa6,0x4b,0x2e,0x80,0x38,0x68,0x41,0x4c,0x72,0x71,0xc1,0x08,0xf8,0x72,0x93,0x28,0x1c,0x7d,0xb3,0xf5,0x41,0xd2,0x7d,0x3a,0xc4 +.byte 0x20,0x95,0x9c,0x52,0x7e,0x4f,0x5c,0x5e,0x72,0x2d,0x98,0xbc,0xd4,0x7a,0x31,0x30,0x1c,0x4d,0xe8,0x79,0xf6,0x65,0xcc,0x22,0xfe,0xc9,0xc7,0x61,0xcc,0xbe,0x21,0xd4,0xb4,0x18,0xde,0xaa,0xe5,0xc8,0x61,0x00,0xb5,0xc0,0x89,0xf2,0x19,0x88,0xb8,0xfe,0xe3,0x2b,0xb0,0xfa,0xf2,0x35,0x4e,0xf9,0xce,0x43,0xd4,0xc3,0xc3,0xf6,0xc5,0x60 +.byte 0x8f,0xd3,0x12,0x32,0xe9,0xbc,0x1e,0xbd,0x4f,0x4c,0xdf,0x2e,0xc4,0x4a,0xd9,0x28,0x81,0xca,0x17,0x36,0xc9,0xbd,0x21,0xea,0xf1,0xdf,0x73,0x91,0xbe,0x8c,0x24,0x3c,0x74,0xf4,0x42,0x0f,0x5c,0xa1,0x42,0x83,0x73,0x3c,0x01,0x09,0x80,0x06,0x2a,0x91,0x63,0x59,0x6f,0xf4,0x09,0xb0,0x94,0x8c,0xc3,0xcc,0x7d,0xb2,0xf7,0x0b,0xa4,0x29 +.byte 0x87,0x8b,0x9d,0x6c,0x8f,0x57,0x7d,0x45,0xee,0xc7,0x1b,0x4d,0x61,0xc5,0x66,0x7f,0x59,0xe5,0xbc,0x8f,0x45,0x33,0x05,0xc9,0xe6,0xf2,0xbb,0x5a,0x61,0xe6,0x5c,0x41,0x44,0x70,0x55,0xaf,0xb5,0xa0,0x3c,0xb5,0x4a,0xf2,0xe8,0x50,0x4e,0x94,0x01,0x56,0xc4,0x7f,0x08,0x7d,0x64,0x18,0x8b,0x14,0x15,0x15,0x54,0x23,0x49,0x4f,0x9b,0x48 +.byte 0x99,0x48,0x9f,0x57,0x48,0x58,0xd1,0xe9,0x07,0x5c,0xe2,0x98,0x90,0xd7,0xc0,0x09,0xd7,0x5c,0x6f,0x0c,0x68,0xf7,0x68,0x66,0x78,0x46,0x7d,0xf6,0xaf,0x86,0x87,0x0a,0x5e,0x47,0xb2,0x9a,0xe8,0x52,0x00,0x48,0x66,0x76,0xe0,0xf7,0xa8,0x9d,0xe1,0xff,0xad,0x77,0x31,0x3f,0x28,0x2f,0x08,0x26,0xd6,0x79,0x31,0x4a,0xac,0x58,0xa8,0x98 +.byte 0x56,0xd0,0x83,0x66,0x4f,0x05,0x20,0x43,0xe7,0x6b,0x1f,0x9c,0x90,0x79,0x6a,0x6c,0xb2,0xff,0xd3,0xee,0x51,0x32,0x57,0x34,0xdc,0x1b,0x61,0xf7,0x86,0xd2,0x78,0xdb,0xb1,0x91,0x6b,0xd7,0x8e,0x9a,0xab,0x71,0x8b,0x77,0x4b,0xda,0xe0,0x74,0xe4,0x80,0x47,0xad,0xd1,0x76,0x31,0xdc,0xfa,0xa9,0xb0,0xd8,0x0f,0x35,0xc1,0x06,0xdf,0x87 +.byte 0x5f,0x0c,0x02,0xef,0x38,0xe0,0x1b,0x4c,0xcd,0xc4,0x2a,0x20,0xd5,0xbe,0x59,0x5e,0x11,0xe4,0x71,0xa6,0x2c,0xdb,0x53,0x35,0xac,0x1f,0xae,0x45,0xa7,0x6c,0x58,0x62,0x5d,0xbe,0x5f,0x21,0x23,0x28,0x0e,0x2c,0xcd,0x7d,0xc2,0xdf,0xcb,0x0d,0xd4,0x7c,0xda,0x88,0x26,0x97,0x88,0x13,0x3c,0x51,0xcb,0x91,0x96,0xd6,0xf4,0x63,0x21,0xe1 +.byte 0x61,0x8e,0xbf,0x09,0x3f,0x00,0x1e,0xa4,0x2c,0x43,0x86,0x5f,0x5a,0x18,0xcb,0x66,0x8c,0x56,0x26,0xa4,0x5b,0x1d,0xf6,0x0d,0xd9,0x40,0xe8,0xef,0x13,0xcd,0x71,0xd1,0x4c,0x48,0xfc,0xb3,0xfe,0x20,0xb0,0x72,0x3e,0xd8,0x76,0xc5,0x87,0xb4,0xd6,0xfc,0xcc,0xf6,0x0f,0x3a,0xd5,0x98,0x1d,0x0f,0xa6,0xd7,0x63,0x32,0x1e,0xf9,0x1b,0x5a +.byte 0x7c,0xce,0x7f,0x90,0xd2,0x2d,0x2c,0xa9,0x9e,0x01,0x46,0x47,0x80,0x8c,0xf3,0x5e,0xfe,0x8e,0x41,0xdc,0x33,0xd5,0x11,0xf9,0xbc,0xc1,0x4a,0xbf,0xd9,0xc0,0xeb,0x43,0xe6,0x8e,0x04,0x5c,0xea,0xcb,0x53,0x2f,0x43,0x3f,0xe9,0xfe,0x04,0xaa,0x15,0xf1,0x38,0x46,0x70,0xbf,0x74,0x01,0xfa,0x5f,0x50,0xf3,0xb2,0x35,0x97,0x44,0x2a,0xad +.byte 0x49,0x1e,0x19,0x76,0x48,0x32,0x74,0xc2,0xc9,0x72,0x8b,0x44,0x2c,0x59,0x77,0xa9,0xf1,0x36,0x0a,0xa7,0xe7,0x69,0x6f,0x2b,0xcc,0x3f,0xa7,0x5c,0x39,0xc0,0x38,0xd2,0x85,0x02,0x6a,0x1f,0xdf,0x21,0x34,0x66,0xfe,0x56,0x2a,0xf8,0xac,0x4e,0xe1,0x1a,0x14,0x12,0xd5,0xc1,0x41,0x0b,0x1f,0x18,0xf3,0x0a,0x52,0x96,0xbb,0xaa,0x78,0x59 +.byte 0x16,0xe1,0xbf,0xa5,0x87,0x26,0x19,0x0d,0x68,0x0e,0xc0,0x4b,0xfd,0xd4,0xf8,0x60,0x9c,0xf4,0x6e,0x64,0xf2,0xbe,0x24,0x2a,0x3a,0x4e,0x05,0x01,0x26,0xe7,0x15,0xb5,0x14,0x06,0xeb,0x6e,0x21,0x88,0x4b,0x86,0x1b,0xcd,0xc5,0x29,0xaf,0x68,0xd1,0x94,0x25,0xbc,0x5c,0xf5,0xd3,0xd7,0x20,0x40,0x4e,0xad,0x9b,0x82,0xdf,0x46,0xe6,0x10 +.byte 0x35,0x3e,0xbc,0x53,0x60,0x5a,0x1e,0x91,0xa0,0xcb,0xd7,0x09,0xd9,0x54,0xf4,0x2e,0xc8,0x4d,0x1e,0x8f,0x76,0xc4,0x67,0xed,0xb6,0x00,0xe4,0x97,0xb2,0xf9,0x21,0x98,0x3a,0xea,0xb3,0x53,0x79,0x98,0xfd,0x32,0x9a,0x76,0xb9,0x3c,0x74,0x09,0x37,0x60,0xfd,0xf6,0x36,0x58,0x40,0x19,0x4f,0x73,0x5b,0x27,0xed,0x3a,0xa8,0x58,0x27,0xf0 +.byte 0xd0,0x11,0xee,0x20,0x94,0x0e,0x41,0x7d,0x47,0x85,0x27,0x45,0xae,0x3f,0x14,0x75,0xda,0x5d,0x8d,0xd9,0x31,0x58,0x99,0x40,0x9a,0xfe,0x1e,0x9c,0x7e,0x42,0x2f,0xe7,0xcd,0x43,0xb3,0x08,0xa9,0x71,0x5f,0x92,0x34,0x01,0xde,0x05,0x40,0xae,0x08,0xe3,0x62,0x36,0x71,0x7a,0xd4,0x75,0xf3,0xee,0x71,0x84,0x41,0xce,0xf3,0xca,0xa6,0x69 +.byte 0xc2,0x13,0x2c,0x75,0x85,0xb4,0x43,0x8c,0x08,0x6c,0x1b,0xfb,0x87,0x1a,0xe2,0x74,0x22,0x86,0x2e,0x9e,0x3e,0x85,0xaa,0x34,0xb3,0x5f,0x43,0xf2,0xe5,0x6b,0x87,0x84,0x1a,0xce,0x70,0x1e,0x08,0x24,0xd8,0x16,0xe0,0x1a,0x78,0xd5,0x93,0xf7,0xe5,0x7b,0x49,0xff,0x8c,0x14,0x44,0xa6,0x2c,0xab,0x58,0xe6,0x59,0xb7,0x56,0x00,0xcd,0x1e +.byte 0x53,0xd2,0xc2,0xa4,0x1a,0x56,0xbc,0x08,0x08,0xac,0xa7,0x95,0xbe,0xbb,0xdc,0xc8,0xdf,0xe3,0xa8,0x35,0x42,0x60,0x8a,0x1c,0xa6,0xf0,0xf3,0xa4,0xdc,0xcb,0x6b,0xb4,0x0a,0x6f,0x45,0xfa,0x6f,0x9c,0x92,0x15,0xe2,0x0b,0x0a,0xdd,0xb1,0xa9,0x68,0x54,0x3c,0x3b,0x9f,0xa3,0x9f,0x93,0x50,0xca,0xd4,0x8f,0xd5,0x09,0x0d,0xe8,0x94,0x18 +.byte 0xce,0x5b,0x28,0xd9,0xd1,0xce,0x3f,0xc7,0x3d,0x42,0x11,0xd7,0x47,0x2c,0x8b,0x6c,0x6b,0x43,0x52,0xd2,0xdf,0xbb,0xe9,0xb4,0x4c,0x39,0xc6,0xf8,0x9e,0xc8,0xa5,0xa8,0x70,0x92,0xea,0x83,0x78,0xf9,0x40,0x57,0x43,0x58,0x8c,0xe6,0x08,0x34,0x01,0xf8,0xc6,0x8c,0xa9,0x93,0x0f,0x2f,0x91,0x95,0x90,0xb9,0xe4,0xb8,0x4f,0x89,0xb2,0xfa +.byte 0x4e,0x30,0x4b,0x6e,0x91,0x69,0x80,0x0a,0xc5,0x2a,0x62,0x44,0x18,0x15,0xcf,0x93,0x9c,0x0f,0x55,0x44,0x4a,0x71,0xf2,0x72,0x87,0x88,0x38,0xff,0x79,0xc6,0xe9,0xe8,0xb6,0xd9,0xcb,0xd5,0x27,0x8b,0xc1,0x71,0xeb,0x42,0x12,0xbf,0x3b,0xeb,0x45,0x75,0xe1,0x80,0xcd,0xd4,0xdc,0xf6,0x2b,0x82,0x93,0x0c,0xad,0xc9,0x3a,0x31,0xb6,0xec +.byte 0x38,0xee,0x3e,0xc0,0x5c,0x98,0xf9,0xe3,0xf5,0x82,0xf9,0x83,0x57,0xbb,0xed,0x1d,0x7a,0x48,0x10,0x1d,0x18,0xd8,0xab,0x2c,0xfd,0xf6,0x67,0x61,0x26,0x37,0x74,0x33,0x0f,0x9e,0x82,0x8e,0xaf,0x22,0x7f,0x57,0x5d,0xf7,0x53,0x9e,0xf9,0x20,0x98,0xf5,0x1f,0xbe,0x60,0xd9,0x81,0x5f,0xba,0x9b,0x36,0x07,0x65,0x9e,0x65,0xb5,0x2f,0x3f +.byte 0x2b,0x0d,0xef,0x1a,0xf8,0xf7,0x6e,0x16,0x09,0x00,0xef,0xed,0x95,0x38,0xec,0x1b,0xf3,0xf6,0xa2,0x9f,0xb2,0x21,0x6a,0xc8,0x0f,0x59,0xf2,0xe8,0x6c,0x92,0x35,0x99,0x56,0x3f,0xa4,0xd9,0xcd,0x5c,0x72,0xfb,0x0a,0xea,0x3e,0xa2,0x58,0x33,0x85,0x48,0x53,0xcc,0xba,0x92,0x5e,0x81,0xa3,0x46,0xe3,0x1d,0xe8,0xc4,0x22,0x10,0x57,0x0a +.byte 0xa1,0xba,0x5a,0x4e,0xc8,0xfb,0x14,0x9a,0x36,0x9d,0x61,0x5b,0x0d,0x2e,0x25,0x46,0x18,0x38,0x8c,0x20,0x51,0xd7,0xd1,0xe0,0x73,0xdb,0x76,0xaa,0xb3,0xa8,0x54,0xdc,0xb5,0x38,0xf2,0x5a,0x75,0x66,0x28,0xd3,0x5d,0x4a,0x8f,0x02,0x40,0x7e,0x88,0xfe,0x80,0x83,0x44,0x11,0xad,0xe8,0x52,0x70,0xa3,0x50,0x3d,0x22,0xc2,0x8a,0x83,0xef +.byte 0xda,0xd7,0xae,0x04,0xb8,0x98,0x4e,0x9f,0xf6,0xb7,0x39,0xa5,0x72,0x29,0x61,0xbd,0xdf,0xd9,0xdc,0xe2,0x10,0x9b,0x8a,0x5f,0x42,0x4e,0x41,0x49,0x41,0x81,0xa2,0xc7,0x81,0x30,0xe9,0xfb,0x7f,0x10,0x1a,0x44,0xaa,0x79,0x70,0x1a,0x9d,0xe4,0xbd,0x98,0x25,0x75,0xff,0x45,0x5a,0x79,0x5d,0xe3,0x8d,0x58,0x87,0x2c,0x05,0xfd,0x34,0x98 +.byte 0x06,0x90,0x55,0x24,0x6d,0xde,0xed,0x38,0xd4,0xf2,0xfa,0x55,0x43,0x34,0x73,0x83,0x82,0x47,0x0c,0x4c,0x1a,0xff,0xf8,0x9a,0xd3,0x57,0x75,0x8d,0x1d,0xf3,0x8e,0xde,0x96,0x29,0xce,0xd1,0x73,0xb1,0xe4,0x1c,0x24,0x3b,0xdf,0xed,0xd8,0xef,0x4a,0x5f,0xdb,0xe5,0x42,0x55,0x58,0x86,0xb7,0x01,0x6d,0x14,0x40,0x2c,0xb8,0x08,0x9f,0x9a +.byte 0x46,0x9c,0xfd,0x85,0xcf,0x2d,0x5e,0x07,0x41,0xf9,0xb7,0x9f,0x6a,0xa8,0xaf,0x23,0xdc,0xdf,0x46,0x54,0xdb,0xd4,0xb0,0x03,0xef,0x82,0x26,0x8f,0x00,0x6e,0xf6,0x26,0x99,0xda,0xeb,0xab,0xc2,0x1e,0x49,0x8e,0x40,0x42,0x85,0x0b,0xc6,0x51,0xa9,0xe4,0x1f,0x63,0xf7,0x56,0x46,0xf4,0x4d,0x95,0x16,0x4a,0x38,0xc7,0x28,0x52,0x03,0xd6 +.byte 0x5e,0x90,0x09,0xaf,0x31,0xc0,0x5b,0x32,0x52,0x1d,0x6b,0xb7,0xf7,0x17,0x86,0x6d,0x90,0x1d,0x78,0xf3,0xae,0xf6,0x96,0xe3,0x02,0x6d,0xe3,0xd6,0xdf,0xb9,0xfc,0x7a,0xfd,0x04,0xa5,0xbe,0x42,0x19,0x5c,0xd9,0x44,0x60,0x1e,0xb5,0xca,0xd7,0x99,0xa9,0x98,0x52,0x4b,0x9a,0x2c,0x05,0x08,0x88,0x06,0x12,0x30,0xe2,0xca,0x14,0xb9,0x30 +.byte 0x7d,0x22,0xd8,0xaa,0x58,0x4c,0x80,0x10,0x39,0xa6,0x2b,0x7d,0x17,0xfe,0x72,0xe2,0x2f,0xa8,0x85,0x03,0x91,0xae,0xa0,0xe5,0xed,0xe0,0x02,0x40,0xf4,0x93,0x0c,0xf9,0x73,0xc7,0x8b,0x3e,0x26,0x1b,0xc6,0xf8,0x34,0x5d,0xda,0x74,0xf4,0x72,0xb2,0xcd,0x89,0xd2,0xdb,0xdc,0x60,0x84,0xa8,0xa5,0x40,0x9a,0x5e,0x6b,0x47,0x17,0x75,0x81 +.byte 0x89,0x1b,0xec,0x18,0xd2,0x09,0x2c,0x57,0x1d,0xce,0x41,0x6e,0x14,0x99,0x2f,0x52,0x43,0x77,0xf7,0xdd,0x72,0xeb,0x8b,0x39,0x72,0x4b,0xcb,0x92,0x92,0xfc,0x55,0xbd,0xfd,0xd1,0xd6,0xd3,0xbb,0xa1,0x23,0x21,0x5a,0x41,0x2b,0x4e,0xe6,0xcf,0x9b,0x33,0x1e,0x0b,0xab,0xa5,0x69,0x96,0x32,0x4c,0x40,0xbe,0xfa,0x48,0x40,0x0c,0xbf,0x2f +.byte 0x9d,0xd4,0xb0,0xfe,0x74,0x3e,0x9f,0xb6,0x08,0xb0,0x71,0x32,0xa6,0xeb,0x62,0x2a,0xbc,0xdd,0xca,0x68,0x41,0xe4,0xcd,0x52,0xfb,0x4f,0x09,0xdc,0xb8,0x26,0xad,0xfd,0x23,0x9d,0x65,0x80,0x00,0xd8,0xd2,0x27,0xfb,0x80,0xd0,0x06,0xfa,0xe8,0xbc,0x70,0x54,0x5a,0xb7,0x30,0x9a,0xec,0x38,0x02,0x76,0x0f,0xda,0x41,0x1e,0xfe,0xe9,0xa0 +.byte 0x77,0x6e,0xef,0xfb,0x2e,0xf9,0x35,0x5a,0xcb,0x2d,0xdf,0x57,0x68,0xc3,0xb5,0xd9,0xef,0x72,0xb2,0xac,0xcb,0x60,0x90,0x17,0x70,0x8f,0xe6,0x70,0x52,0x13,0xa1,0xb2,0xe8,0x80,0xee,0x77,0x87,0xf2,0x72,0xeb,0x53,0xf0,0xcc,0x37,0xc2,0xe5,0x8c,0x0a,0x50,0x00,0x67,0x9f,0xf0,0xa6,0x2c,0xde,0xe9,0xd6,0xde,0x8a,0x96,0x50,0x6c,0x9e +.byte 0xb0,0xd3,0x6a,0x8a,0xd0,0xd7,0x1d,0x53,0x63,0x58,0xef,0xfc,0xd3,0x74,0xe2,0x46,0x51,0xf7,0x78,0x69,0xb9,0x3e,0x6a,0xa3,0xdb,0x1b,0x7c,0x1c,0xc6,0x25,0xf7,0x36,0xba,0x27,0xd5,0x96,0x70,0x24,0x81,0xe1,0x7f,0x44,0x82,0x57,0xc7,0x37,0x71,0x00,0x6b,0xd1,0x99,0x12,0xb1,0x84,0xc9,0x65,0x03,0x3f,0x9b,0x36,0x4b,0x37,0x21,0x5d +.byte 0x12,0x96,0x5d,0x64,0xdf,0x2c,0xe4,0x7a,0x1a,0x1e,0xf3,0xdf,0xc3,0xbb,0xb9,0x35,0x36,0x5f,0x71,0xe5,0xca,0x76,0x02,0x95,0x8e,0x2d,0x87,0x32,0xf2,0x78,0x0e,0x01,0xe1,0xb2,0x4c,0x11,0x26,0x70,0x4d,0x9b,0x9f,0xa1,0x65,0x7d,0x9c,0x2f,0xa6,0x01,0x2b,0xdc,0x3f,0x72,0xd1,0xe8,0xb1,0xd2,0x04,0x6b,0x8b,0xbf,0x43,0xba,0xbb,0xb9 +.byte 0xec,0x86,0x2a,0x87,0xb5,0xee,0x82,0x40,0x96,0xde,0xd7,0xcc,0x07,0x66,0x38,0x90,0x70,0x20,0x03,0x51,0x5b,0xf2,0x54,0x87,0x5c,0x29,0x8c,0xb1,0xa1,0xf0,0x56,0x1f,0xb4,0x4c,0x69,0x3b,0x4e,0x6d,0x6a,0x39,0x0c,0xde,0x1b,0x32,0x15,0xbe,0xb0,0xc5,0x4c,0x9b,0x4b,0xf0,0x47,0x8a,0x30,0x6e,0xa9,0xbc,0xf1,0xa0,0x73,0x14,0x5c,0xea +.byte 0x73,0x7c,0x0d,0x80,0x02,0xed,0x74,0xe7,0x77,0x42,0x2b,0x4a,0xc6,0xdd,0x70,0xd7,0x5d,0x4c,0xe9,0xfd,0x62,0x41,0xc1,0x55,0xd7,0xee,0x81,0x81,0x16,0xb5,0x3f,0x9f,0x6c,0x8a,0xb9,0x90,0x1c,0xd3,0xba,0x32,0x6b,0xa7,0xa6,0xa7,0x8f,0xd9,0xfa,0x18,0xfd,0x25,0x91,0x6e,0xc4,0x35,0xde,0x07,0x89,0x92,0x4e,0xfe,0x4a,0xb7,0x09,0x66 +.byte 0xb0,0x58,0x32,0xe2,0xa3,0xa8,0x4e,0x7f,0x10,0xab,0xb8,0xe0,0x87,0xf1,0xaa,0x59,0x8e,0x71,0x62,0x47,0x93,0x19,0x82,0x8a,0xf9,0x0c,0x2d,0x9f,0x5d,0x6d,0xd2,0xa4,0x1f,0x96,0x36,0x3c,0x41,0x94,0xa2,0x87,0x68,0xcd,0x03,0x65,0x8c,0xbc,0x92,0xa9,0xa1,0xda,0x9c,0xcb,0x64,0x56,0xdd,0x06,0x82,0xc8,0xbb,0x20,0xb0,0xd3,0xf0,0x8e +.byte 0x47,0xb7,0x71,0xf8,0x7c,0xc3,0x74,0x54,0x38,0xd2,0xa6,0x3c,0x7e,0xcb,0x27,0xcb,0xef,0xe9,0x7b,0xda,0xca,0x08,0x47,0x4b,0x35,0x45,0xff,0x64,0xae,0x6c,0x37,0xe9,0x5d,0xf5,0x00,0x51,0x71,0xf4,0x30,0x60,0x8c,0x22,0x5c,0xae,0x8a,0x03,0xc7,0xd3,0x91,0x7d,0x0f,0xf9,0x91,0xb5,0x2d,0xdc,0x36,0x61,0x4a,0x94,0xf8,0xc0,0x12,0xcf +.byte 0x3e,0xf6,0xea,0x15,0x9c,0xe0,0x35,0x09,0xfb,0xca,0x1b,0x53,0x7e,0x4f,0x12,0xbc,0x2c,0xa8,0x1b,0x78,0x54,0xa1,0x7f,0x08,0x47,0xe3,0x0c,0x0e,0x84,0xd5,0x9e,0x49,0x91,0xf6,0x8d,0x30,0x5a,0x94,0xcf,0x50,0x62,0x26,0xc7,0x6b,0xad,0xa0,0x3a,0x45,0x12,0x0d,0x31,0xb1,0x64,0xcb,0xa1,0xda,0xc3,0x57,0x41,0x3b,0x03,0x43,0xe0,0xe9 +.byte 0xa5,0xc5,0x4c,0x56,0x82,0xef,0x9f,0x1b,0xb4,0xd7,0xb3,0xc9,0xf5,0xca,0x0e,0xfa,0xc5,0xf2,0x4c,0xf3,0x20,0x0b,0x95,0xe1,0xeb,0xcc,0xb1,0x96,0xd8,0x55,0x68,0x23,0xda,0x30,0x98,0xe3,0x85,0x45,0xa7,0xc0,0xa8,0xe1,0xd6,0x3f,0x4b,0x7e,0x71,0x4b,0xdc,0x46,0x66,0x90,0xd1,0x6d,0x04,0x6b,0xb5,0xa4,0x6f,0x81,0x2c,0x9e,0x20,0xb2 +.byte 0xad,0x80,0x57,0xd9,0x86,0x42,0xc2,0xab,0xfc,0x61,0x29,0x04,0x32,0xfc,0x77,0x12,0xa5,0xd8,0x58,0x97,0xf0,0x47,0xd2,0x60,0x51,0x86,0xcb,0xce,0x0a,0x2d,0x8b,0xdb,0xa3,0x38,0x32,0xc4,0xef,0xa1,0x7d,0xb8,0x56,0x72,0xd1,0xbc,0x1c,0xf7,0xfc,0xda,0xca,0x6b,0x61,0x13,0xb1,0x73,0x0c,0xb2,0x37,0xcb,0x68,0x69,0x19,0xcc,0xda,0x21 +.byte 0xf1,0x3a,0x63,0x50,0x3c,0xfd,0x24,0x6e,0x66,0xbb,0x0d,0xfa,0xf3,0xe8,0xfa,0xb1,0x81,0x8a,0x4b,0x00,0x98,0x32,0x56,0x5c,0xaa,0xd0,0x13,0xe4,0x37,0xe2,0x7a,0xdd,0x00,0x6b,0x5d,0xc8,0x6f,0x25,0xd8,0xd8,0x36,0x24,0xeb,0x20,0x60,0x8e,0xbf,0x41,0x4f,0xab,0xc1,0xfc,0xc8,0x38,0xd6,0xf8,0xd6,0x27,0x52,0xac,0x2a,0x9a,0xf0,0x00 +.byte 0x56,0xe8,0xdb,0xd1,0x14,0x68,0xb2,0xdc,0xbb,0x6f,0x18,0x93,0x52,0xe5,0x20,0x14,0x98,0x08,0x51,0xc8,0x89,0xee,0xaf,0x1e,0x78,0xcc,0x6a,0x92,0xcc,0x49,0xd4,0xfd,0xbe,0xa5,0x88,0x7b,0x07,0xcb,0x30,0x79,0x56,0xd6,0x0e,0x39,0x0b,0xc0,0x9e,0x1d,0xdf,0x5c,0x12,0x87,0x9d,0x9e,0x1f,0x0e,0xf1,0x6f,0xee,0x6d,0x71,0x18,0x63,0x72 +.byte 0x57,0x3c,0x01,0xb9,0x69,0xb2,0xf3,0x4f,0x2a,0x2d,0x69,0x39,0x52,0xcd,0xac,0x3d,0xd9,0x9d,0xdb,0x2c,0xa9,0x51,0x52,0xd0,0xc2,0x61,0x78,0x87,0xef,0x74,0xc9,0x70,0x6e,0x73,0x37,0xa4,0x15,0xcd,0xb0,0xd9,0xac,0x59,0xfc,0xf8,0xcb,0xb6,0x6c,0xa6,0xa6,0xfa,0xf4,0x0d,0x87,0xe1,0xe3,0x5a,0x72,0xfe,0xfa,0xa6,0xab,0x34,0xd0,0x24 +.byte 0xba,0xa8,0xa1,0x7e,0xbe,0xc0,0xec,0xd7,0x84,0x26,0x15,0xaf,0xf8,0xd6,0x73,0x61,0xa0,0xd8,0x2c,0x60,0x60,0xbe,0x34,0x1d,0x57,0x12,0xce,0x1b,0x24,0xea,0xca,0x8e,0x18,0x7f,0xe9,0x9e,0xc1,0x8b,0x09,0x11,0x9c,0x96,0x1c,0xf1,0xb3,0xa0,0x19,0x6a,0x17,0x42,0x32,0x46,0xc8,0x72,0xbc,0x6b,0x83,0x58,0x42,0xe9,0x87,0x0e,0x1b,0xeb +.byte 0xbb,0xea,0x5f,0xe4,0xcf,0xff,0xc3,0xf9,0x59,0xd5,0xc4,0x3c,0xfa,0x84,0xb2,0xa7,0x7b,0x49,0x9d,0xd8,0x68,0x45,0x07,0x0a,0x21,0x8a,0x75,0x80,0x94,0x2e,0xb9,0x36,0x01,0x0c,0xd0,0xde,0x88,0xed,0x62,0x55,0xc2,0x49,0x92,0xf5,0xa4,0x51,0x5b,0xcd,0x3a,0x56,0x0a,0x85,0x36,0x14,0xea,0x23,0x79,0x48,0xea,0x6e,0x67,0x20,0xcc,0x2b +.byte 0x2d,0xb8,0xfb,0x01,0x89,0xf3,0x9a,0x22,0x0c,0x6e,0xb9,0x47,0x3a,0x07,0xef,0x11,0x88,0xd4,0xc0,0xab,0x39,0x2e,0xee,0x8d,0x1f,0x44,0x0e,0x2c,0x32,0xba,0x54,0x60,0x03,0x70,0xed,0x11,0x01,0x2d,0x08,0x5a,0x69,0xea,0x62,0x46,0xdb,0xf5,0x99,0xa6,0x69,0x1c,0x43,0x95,0x4b,0xf6,0x02,0xb1,0xd1,0x38,0xe9,0xd3,0x96,0x7d,0xae,0x0f +.byte 0x46,0x0d,0x9c,0x73,0xe3,0x90,0x9a,0x23,0xc2,0x34,0xb0,0x53,0x04,0x88,0xd0,0x61,0x82,0x46,0xef,0xe1,0x54,0xca,0x54,0x32,0xc1,0xaa,0x1f,0x3d,0x9b,0xac,0x8c,0x78,0x0d,0x0d,0x53,0xba,0x81,0x48,0x7c,0xda,0x9c,0x49,0x07,0x38,0x0d,0xc0,0xa3,0xb2,0xc0,0x4a,0xae,0x29,0x3b,0x0a,0x78,0x0c,0x4b,0xf5,0x9e,0xb3,0x4c,0x42,0xa0,0x52 +.byte 0xb6,0x6f,0xc5,0x77,0xd8,0xed,0xae,0x4d,0x45,0x09,0xe5,0xc8,0xd2,0xbe,0x5b,0x12,0x1d,0x6f,0x5c,0x3a,0x7e,0x5f,0x7a,0x04,0xbf,0x67,0x4d,0x76,0xdf,0x00,0x42,0x18,0xcd,0x65,0x6d,0x64,0x97,0x85,0x09,0x80,0xb6,0x13,0xc0,0x9b,0x8c,0x25,0x52,0x6b,0x03,0x88,0x2f,0xba,0x4c,0xbe,0xab,0xf9,0x3a,0x3b,0x4a,0x87,0x42,0xc0,0xe5,0x61 +.byte 0x37,0x4b,0x1a,0xb9,0x68,0x1a,0x50,0xde,0xf2,0xaf,0xdd,0xf4,0xa4,0xa0,0x97,0xf6,0xec,0x70,0xbe,0x6e,0xe5,0x7a,0x14,0x8a,0xfe,0x49,0x54,0x18,0x21,0x30,0xc3,0x3e,0xa8,0xa0,0xbc,0xd0,0x32,0x48,0x8b,0x67,0x47,0x39,0x10,0x1b,0x5f,0x67,0xe1,0x3c,0xf2,0xfc,0xe5,0xb9,0x23,0x96,0xdd,0xeb,0xc5,0x76,0x5a,0xc9,0xee,0xe2,0x09,0x43 +.byte 0xfe,0x4b,0x6e,0x99,0x17,0x24,0xfc,0x30,0x02,0x2f,0x4c,0x3d,0x52,0xe7,0xdf,0xd5,0x20,0x5d,0x13,0x3b,0x4a,0xfd,0xb4,0x78,0x3b,0x91,0x58,0x52,0x2e,0x3c,0x8a,0xad,0xfc,0x64,0xb9,0xc2,0xcd,0xdd,0x58,0xf5,0xce,0x1f,0x50,0xdf,0xd9,0x8f,0x39,0x93,0x17,0xe4,0xac,0x7d,0x6b,0xf6,0x7f,0x72,0xd2,0x9e,0xa5,0x8c,0x4f,0x16,0x29,0xf8 +.byte 0xca,0xb2,0xf3,0xb2,0x94,0x08,0x91,0x74,0xf9,0x1a,0x01,0xa1,0x15,0xb4,0x79,0xb3,0xb9,0x18,0x91,0x34,0xa5,0x2b,0x45,0xd3,0xbf,0xf7,0x11,0x42,0xbd,0x63,0x08,0xf9,0x89,0xab,0xbe,0x02,0xab,0xda,0xfc,0xc6,0xba,0x57,0xd8,0x60,0x1d,0x03,0x12,0x57,0x01,0x9f,0x88,0xc1,0x3b,0xa5,0xa3,0x09,0xd5,0xb5,0x37,0x32,0x86,0xe6,0xf0,0x1d +.byte 0xf2,0x37,0x57,0xdd,0x05,0x56,0xfe,0x2d,0x7c,0x95,0x52,0x93,0x21,0x1c,0x8b,0xfe,0xda,0xea,0xee,0xd9,0xc4,0xec,0x54,0x2e,0x35,0xb3,0x64,0x72,0xf2,0x7a,0x4a,0x1c,0xc9,0x33,0x07,0xda,0xc9,0xd8,0x7d,0x5d,0xeb,0xef,0x23,0x91,0xb5,0x68,0x8e,0xf5,0x4e,0xb9,0xd3,0xff,0x7b,0x72,0x27,0xbf,0x9e,0xf7,0x16,0x8a,0x42,0x4f,0x3a,0x0a +.byte 0x09,0xfe,0x0b,0xf9,0x64,0xfd,0xa6,0xf2,0xaa,0x29,0x45,0xeb,0xe1,0x4c,0xf8,0x84,0x9d,0x19,0xf9,0x18,0xf6,0x72,0x9e,0x5f,0xf6,0x91,0xca,0xf7,0xda,0x88,0x0a,0x2c,0xb0,0xea,0x33,0x34,0xd0,0xa9,0x4c,0xd5,0x1f,0x91,0x08,0x74,0xc7,0x62,0x66,0xb4,0x60,0xdb,0x76,0x3e,0x17,0x43,0x73,0xdd,0x67,0x71,0xaa,0xc0,0x6c,0xe2,0x1c,0x54 +.byte 0xfe,0x97,0x5e,0xf9,0x1b,0xa7,0x61,0xf2,0x40,0x96,0xc1,0x06,0x14,0xc8,0x7f,0xe5,0xec,0x66,0x2d,0xca,0x53,0xd1,0xf8,0x49,0x59,0xce,0xfd,0x79,0x20,0xe0,0xd4,0x3d,0x4f,0x25,0x7e,0x43,0x51,0x58,0x84,0x7e,0x23,0x29,0x4d,0xc3,0x4f,0x60,0x11,0xbb,0xc4,0x7b,0x67,0x32,0xd4,0x33,0x70,0x65,0x16,0x02,0x0f,0xdd,0x19,0xde,0xc2,0x1c +.byte 0x69,0xd2,0x39,0x79,0xd0,0x81,0x91,0xc0,0x3d,0xb3,0xee,0x79,0xcc,0xdd,0x81,0x0a,0x7c,0x92,0x5f,0x23,0x4e,0x66,0xbc,0x0a,0xc4,0xab,0xf4,0xf4,0x31,0x74,0x46,0xd9,0x74,0x18,0xe3,0x68,0xc2,0xc9,0x04,0x73,0x5a,0xb4,0xd3,0x87,0xda,0x56,0xe7,0x60,0xb2,0x2b,0x1e,0xd3,0x20,0x72,0x33,0x40,0xa6,0x4b,0x26,0x6f,0xcc,0x05,0x57,0x62 +.byte 0x17,0x0d,0x7d,0x14,0x5d,0xe8,0x7c,0xa9,0x1e,0x2e,0xbb,0x6f,0xb4,0x2f,0x3e,0xec,0x3b,0x62,0x1c,0xae,0x9d,0x2d,0x6c,0x9f,0x1f,0xed,0xd0,0xb1,0x99,0x71,0xd0,0x79,0x0b,0x80,0x68,0x3b,0xeb,0x47,0xb0,0xf4,0xec,0x8a,0x1f,0x9f,0x55,0xb6,0xf4,0xfc,0xd0,0xb5,0x7d,0xa8,0xd0,0x70,0x73,0x32,0x87,0x5e,0xb9,0x61,0x5c,0xc1,0xdc,0x5d +.byte 0x2e,0x1f,0xfb,0x83,0x82,0xaf,0xfa,0xa9,0x6b,0x61,0x4b,0xe4,0x4a,0xa7,0x50,0x28,0x8d,0x7f,0x27,0x1b,0x8e,0xb1,0x81,0x1a,0x60,0xa5,0x1e,0x79,0x0a,0xcf,0xc6,0x4e,0x0e,0xdf,0x67,0xe2,0x08,0xb5,0xbb,0xa7,0xa2,0x5a,0xcf,0xa2,0xc2,0xd3,0xdf,0x7f,0xb8,0xbb,0x06,0x44,0xd9,0xfb,0xa9,0xa4,0x3b,0x8e,0x93,0x64,0xce,0x54,0x9c,0x6d +.byte 0xce,0x2d,0xca,0xb7,0xbf,0xb1,0x13,0x8c,0x53,0x25,0x7b,0xcb,0x4d,0x15,0x99,0xe8,0x3e,0xdd,0xf9,0x0a,0x64,0xd0,0x52,0xc1,0xd9,0x08,0xb7,0x6c,0x47,0xcb,0x76,0x9f,0xda,0x38,0x5c,0x8d,0x81,0xd2,0x74,0xc7,0xa5,0xb2,0x44,0x1d,0xa5,0x92,0xb8,0x0d,0x99,0x97,0xd7,0x16,0x30,0x22,0xaf,0xac,0xcf,0x5a,0x5f,0x32,0x0e,0x18,0xce,0xfa +.byte 0xec,0x52,0x36,0xa5,0x03,0x00,0xc6,0xe6,0x4e,0x7c,0x22,0x97,0xbb,0xbd,0x19,0x60,0xec,0xc7,0xb3,0xb4,0xee,0x74,0x9a,0x66,0x6b,0x19,0x6c,0x41,0x02,0xd7,0x15,0x68,0xf9,0x13,0x9f,0xa4,0xf4,0xf1,0x58,0x0d,0x9e,0xf5,0x00,0x2d,0xce,0x6d,0xbb,0x2b,0x0a,0xcc,0x52,0xcb,0x17,0x6f,0xfa,0x22,0xfd,0x5b,0x01,0x3a,0x5b,0xee,0x48,0x71 +.byte 0xbf,0xe8,0xad,0x7b,0x95,0xd8,0x6b,0x96,0x36,0x80,0x4b,0xf6,0x92,0x0d,0x86,0x8d,0xc3,0xeb,0x8f,0xe8,0x90,0x2f,0x21,0x16,0xb4,0x9b,0x89,0xbc,0x2d,0x72,0x7c,0x17,0xdb,0x35,0x07,0x0d,0x67,0x7e,0x99,0x04,0x89,0x14,0xcb,0x95,0xd7,0x35,0x58,0xbd,0x63,0x28,0x24,0x8c,0x05,0xea,0xab,0x75,0xd8,0xa9,0x14,0x2c,0xda,0xc8,0xcf,0x21 +.byte 0x1e,0xaf,0xa9,0x7a,0x39,0x7a,0xc6,0x26,0x27,0xa5,0x62,0x51,0xe6,0x51,0xf2,0x9b,0xe8,0x02,0xa7,0x97,0xb5,0x8f,0x2f,0xff,0xf0,0xf0,0x7e,0x93,0x8d,0xd1,0x0c,0x5f,0x01,0xb7,0xb9,0x36,0x89,0x47,0xd4,0x30,0x02,0xf2,0xaa,0x28,0x3c,0x8e,0x25,0x8e,0x19,0x8e,0xfa,0x54,0x25,0x57,0xf2,0x38,0xbc,0x06,0xa5,0xcd,0x93,0xf4,0x9e,0x77 +.byte 0x3d,0x58,0x8f,0x69,0x10,0xab,0xcc,0x38,0xb1,0xa8,0x2c,0x3e,0xde,0x80,0x6b,0xa6,0xd7,0x7e,0xbd,0x07,0xfe,0x8a,0x10,0xd8,0x1f,0x37,0x77,0xed,0x29,0x6c,0x45,0x6c,0x0d,0xb9,0xab,0xcf,0x4c,0x04,0x8c,0x0d,0xce,0x10,0x3a,0xfb,0x16,0xd3,0x89,0x53,0x5f,0x41,0xc0,0x18,0x6a,0x5e,0xd6,0xdd,0xc4,0x46,0x19,0x3b,0xbe,0x25,0xd5,0x03 +.byte 0x27,0xfe,0x00,0x76,0x45,0x95,0x89,0x19,0x9c,0x2f,0x70,0xa7,0xb6,0x87,0x85,0x5e,0xd0,0xe4,0x2f,0x48,0x0f,0x52,0x3d,0x25,0x3a,0x45,0x5d,0x0b,0x55,0xcb,0xec,0x6d,0x97,0xaa,0xe9,0x7e,0xae,0x70,0x72,0xe2,0xbd,0x06,0xd7,0x4c,0x1d,0x1d,0x56,0xa7,0x24,0x09,0x4b,0xcb,0x09,0xc6,0x65,0xf1,0x5e,0x3d,0xeb,0x0a,0xc1,0x9c,0xc7,0x12 +.byte 0xfd,0xd9,0xdb,0xe7,0xe2,0x52,0x5a,0x68,0x4f,0x90,0xf3,0xf8,0xa4,0xe1,0x46,0x30,0x47,0x31,0x54,0x67,0xbc,0xdc,0x77,0xd6,0x73,0xe7,0x55,0xc9,0x2e,0xbe,0xe9,0xb6,0x6f,0x7f,0x0f,0xd8,0x30,0x50,0x95,0x03,0x3e,0x8f,0x8a,0x3c,0x4c,0x86,0x63,0xb6,0x44,0xae,0x1b,0xbc,0x1d,0x90,0x1a,0x76,0x4e,0x92,0x98,0xba,0x59,0x73,0xf8,0xff +.byte 0x07,0xdb,0xc4,0x90,0x17,0x0d,0xf1,0x58,0x13,0x64,0x88,0xcc,0x16,0x30,0xec,0x70,0x87,0x20,0xfc,0x3e,0xf6,0x70,0x2e,0x92,0xcb,0x42,0x47,0x5b,0xb3,0xf1,0x89,0xf1,0xd7,0xf5,0x16,0x89,0xed,0xf5,0x04,0x1a,0x85,0x9e,0xe7,0x74,0x8c,0xd6,0x79,0x26,0x2c,0x21,0xcd,0xff,0x53,0xea,0xf9,0xff,0x69,0x82,0x35,0xdb,0xc1,0x2a,0x36,0xf6 +.byte 0xf6,0x98,0x08,0x7c,0xcd,0x31,0x32,0x8e,0xb3,0xf5,0xe9,0xe4,0x38,0xec,0x38,0x08,0xa8,0xbc,0x83,0x3f,0xfa,0xbe,0xb6,0xd6,0x20,0x10,0xaa,0x3e,0x5d,0x6c,0x96,0x4f,0x31,0x63,0xf2,0x90,0xce,0x0a,0x4c,0x94,0x63,0xb7,0xb5,0xd1,0x4a,0xcb,0xf1,0xd6,0x21,0x23,0x07,0x49,0x80,0x6c,0xe6,0x4a,0x6a,0xa4,0x9c,0x10,0x31,0x34,0xe3,0xf5 +.byte 0x3c,0x8c,0x53,0x7d,0x56,0x3e,0xc7,0x91,0x99,0x7c,0xd3,0x0a,0xa0,0x81,0x50,0x54,0x4c,0x8c,0x8f,0x53,0x6a,0xda,0x39,0x9e,0xc4,0xf5,0xa9,0x26,0xa0,0xc3,0x1f,0xb2,0x79,0x9b,0x51,0x0a,0x18,0x2a,0xe8,0xf5,0x94,0x30,0xa3,0x4e,0x27,0xc3,0xdb,0x8c,0xc6,0xa1,0x8f,0x4f,0xef,0x94,0x11,0x74,0xb6,0x05,0x9e,0xd8,0xc1,0x8f,0x8a,0x0f +.byte 0x38,0x36,0x70,0x68,0x66,0x56,0x14,0xf1,0xda,0xda,0xc2,0xe1,0xc8,0xaf,0x1f,0x85,0x95,0xa7,0xaf,0x17,0xdc,0x38,0x7e,0x05,0x23,0x1e,0x37,0x05,0x6c,0xde,0x1c,0x91,0x64,0x0d,0xd5,0x74,0xe7,0xef,0xee,0x01,0xac,0x85,0xbb,0xca,0x06,0x7c,0xab,0x8d,0xaa,0xb4,0xaa,0xd4,0xb8,0x0c,0xb8,0xcf,0x13,0x9b,0xd2,0x9d,0x22,0xa5,0x44,0x51 +.byte 0xd5,0x87,0xdf,0x74,0xe1,0x70,0x8b,0xef,0x24,0x04,0xe8,0x3a,0x74,0xf1,0x35,0x89,0xc3,0x20,0x81,0xc7,0xaa,0x1e,0x51,0x5f,0x28,0x42,0x37,0xbc,0xaf,0x81,0xe3,0x4d,0xc5,0x10,0xcc,0xb4,0x6d,0xf6,0x81,0x73,0x1f,0xc5,0x59,0x78,0x7d,0xce,0x7d,0xab,0x20,0x4f,0x86,0x06,0xb9,0xa3,0xc5,0x97,0x76,0x5d,0xeb,0xc4,0x9f,0x22,0xb8,0x7b +.byte 0xc1,0x35,0x6c,0xd6,0x4e,0x12,0x26,0xf1,0xda,0xae,0x15,0xab,0xab,0xbc,0xd5,0x07,0x5b,0xf1,0x9a,0xf0,0xbd,0x7f,0x08,0x15,0xd1,0x12,0x23,0x7f,0x78,0x9e,0x89,0x54,0xd8,0x16,0x96,0xa1,0x14,0x45,0x12,0xce,0xda,0xad,0x41,0xa4,0x70,0xdf,0xfc,0xa3,0xdc,0x27,0xc2,0xa3,0x11,0x8d,0x25,0x8b,0x6d,0xda,0xd7,0x03,0x7d,0x32,0x32,0x3c +.byte 0x8a,0x97,0x8f,0x10,0xcc,0x40,0x89,0x17,0x5e,0x30,0x2b,0xd1,0xb6,0x44,0xb4,0x6c,0x44,0xe7,0xe0,0xd1,0xfb,0xe1,0x68,0xf5,0xc9,0xa8,0x3c,0xa6,0x0b,0x30,0xb5,0x7a,0x0a,0x15,0x43,0x57,0xbd,0x0a,0xcc,0x02,0x05,0x47,0xfb,0x10,0x30,0x07,0x8b,0x9e,0xae,0xd8,0x03,0x18,0x06,0x26,0x35,0xa8,0xae,0x1e,0x51,0x71,0xa8,0x4d,0x27,0x6e +.byte 0x25,0x27,0x77,0xb5,0x79,0x43,0x03,0x04,0xaf,0x61,0x04,0xbc,0x29,0x3e,0x6e,0xfe,0x35,0xc9,0x41,0xfc,0x8a,0x3c,0xd8,0xe4,0xa3,0x34,0x40,0x49,0x36,0x9b,0x18,0x8c,0x6a,0x34,0xa6,0x4c,0xed,0x51,0x8f,0x3a,0xaa,0xa2,0x3f,0xc6,0xce,0xa8,0x53,0x5a,0xa8,0x4e,0xc1,0x84,0x5d,0x2a,0x0b,0x24,0xe5,0x46,0x8e,0xc4,0x55,0x52,0xf4,0xf3 +.byte 0x0c,0xa5,0x24,0x10,0x7e,0xfc,0xed,0x42,0x11,0x39,0xfd,0x3d,0x4a,0x07,0xaf,0x21,0x35,0x4a,0x51,0xcd,0xfb,0x98,0x9a,0x5f,0x15,0x3a,0xab,0xb0,0x56,0x39,0x17,0xcd,0xb9,0xa6,0x6d,0x73,0xbc,0x63,0x95,0xf8,0x78,0x65,0x6f,0x47,0xe9,0x5d,0x12,0x62,0x52,0xb6,0xb2,0x86,0x49,0x1b,0x53,0x3d,0x27,0xc4,0x17,0xa4,0x56,0xc9,0x85,0xbe +.byte 0xe1,0x54,0xed,0x72,0x03,0xd9,0x67,0x6f,0xd0,0xea,0xf7,0x5b,0x39,0x61,0x42,0x48,0xd5,0x8d,0xfb,0xe6,0x3b,0x93,0x16,0x42,0x29,0x0b,0x27,0x1d,0x1f,0xae,0x78,0x16,0x59,0xa6,0x33,0x36,0x86,0x8d,0x31,0x30,0x9e,0xa0,0x82,0xdd,0x02,0x1c,0xde,0x01,0x0f,0x87,0x85,0x2e,0xbb,0x68,0x46,0x8e,0xfc,0xfe,0x32,0x78,0xe4,0x27,0x4f,0xb2 +.byte 0x12,0x94,0x95,0x93,0xba,0x09,0xb4,0x58,0x5c,0x0e,0xa4,0x8a,0x6f,0x0a,0xfc,0xac,0x9f,0x99,0x8a,0x06,0xaa,0x9f,0x69,0x4f,0x3c,0xec,0xe5,0x52,0x60,0x60,0xb8,0xfe,0xf6,0x27,0x47,0xff,0xc9,0x2f,0xec,0xed,0x50,0x07,0xe5,0x3e,0x28,0x65,0xb3,0x36,0x52,0x5c,0xa9,0x4c,0x64,0x65,0x5f,0xfe,0xe3,0xe6,0x19,0x4b,0xdc,0xa0,0x3f,0xab +.byte 0xff,0xca,0x37,0x03,0x83,0xb1,0xe2,0x35,0x69,0x08,0x6d,0x08,0xe4,0xa8,0xc5,0x04,0xe0,0x00,0x66,0x70,0x96,0x16,0x21,0x07,0xe2,0xbc,0x92,0x30,0x31,0x6d,0x02,0xeb,0xbf,0x5a,0x8c,0x39,0x7a,0xd6,0xba,0x15,0x52,0xf6,0xf7,0x30,0x08,0x04,0x5a,0x84,0x56,0x7d,0x8c,0xf1,0x3b,0x87,0xc9,0xfd,0x76,0xd0,0x6d,0x28,0x93,0x4f,0x23,0x9b +.byte 0xf7,0x26,0x7a,0xfe,0xc2,0xde,0xf4,0xb6,0x9c,0x29,0xcc,0x45,0x1a,0x50,0x52,0xab,0xa2,0xef,0x38,0x69,0xe7,0x73,0x54,0xa1,0xf3,0xce,0x31,0xe6,0xa3,0x8a,0x26,0xa5,0x37,0x39,0x88,0xa4,0xf0,0x39,0xb5,0x52,0x2c,0x3d,0xc7,0x60,0xe0,0x9e,0xfe,0xa4,0x4e,0x00,0xf3,0x58,0x4b,0x8a,0xb0,0x9a,0xfc,0x31,0xc5,0x1a,0xd5,0x80,0x37,0x06 +.byte 0x35,0xc2,0x52,0xff,0xa3,0xff,0xd6,0xb5,0xbd,0x66,0x3b,0x61,0x00,0x1e,0x0a,0x9c,0xea,0x8b,0xb1,0x89,0x8a,0x5d,0xe2,0x4f,0x9a,0xf5,0x45,0xe8,0x76,0xa1,0xcf,0x12,0x57,0x74,0x00,0x8f,0xd4,0xc7,0x69,0xef,0x81,0x0e,0x87,0x0c,0xd9,0x54,0x59,0x73,0xed,0x37,0xb8,0xd6,0x90,0x6a,0xae,0x35,0x60,0x77,0x3f,0xd8,0xb6,0x07,0x6e,0x7a +.byte 0x80,0x6b,0x51,0x7a,0xbe,0xd3,0x7c,0xe3,0xaf,0x75,0xee,0x25,0x84,0x14,0x74,0x64,0xed,0xc1,0x06,0x44,0xf8,0x1d,0x92,0x95,0x3e,0xfa,0x7b,0x01,0x5c,0x07,0xda,0x3e,0xb1,0x25,0x25,0xf2,0xf9,0x4f,0x07,0x91,0x96,0xf9,0x22,0x39,0x79,0x4e,0x5b,0x82,0xb1,0xb1,0x4c,0x28,0xba,0x13,0x76,0xd1,0x74,0xda,0x52,0xf9,0x2b,0x08,0x05,0x81 +.byte 0x9b,0xa2,0xf1,0x17,0x96,0x23,0x37,0x37,0x4f,0xc4,0x81,0x30,0xff,0xfe,0xb2,0x3a,0xc3,0x73,0x91,0xd3,0x75,0xaf,0x99,0xc1,0x8e,0x18,0x9e,0x73,0xef,0xad,0x37,0xc4,0x1f,0xeb,0x67,0x3b,0xba,0x5d,0xc8,0x65,0x7a,0x8f,0xdf,0x1c,0x3e,0x6e,0xca,0xca,0x48,0x67,0x6b,0x10,0xad,0x43,0x06,0xe8,0xd5,0xfc,0xf5,0x5f,0x10,0x20,0x43,0x20 +.byte 0x5e,0x84,0x49,0x15,0x13,0x0d,0xf2,0x4e,0x9f,0xcf,0x66,0xab,0x6d,0x52,0x43,0x62,0xc3,0x84,0x8a,0xee,0x99,0x3f,0x2f,0xbf,0x05,0x72,0x0d,0xad,0x97,0x5e,0x58,0x09,0xe7,0x88,0xe6,0x79,0xe4,0x2e,0xa4,0x10,0x0f,0x1e,0x8e,0xb4,0x01,0x24,0xf0,0x3e,0x16,0xad,0xf4,0x77,0x87,0x86,0xff,0xb6,0x32,0xa3,0x98,0xc4,0xb3,0xd6,0x6e,0x55 +.byte 0xca,0x93,0x18,0x5d,0x55,0xd4,0x08,0x73,0x42,0x32,0xc0,0xa2,0x92,0x33,0xa8,0xdf,0x7e,0xd9,0x99,0x3d,0x4a,0x88,0xf6,0xff,0x78,0xbd,0x94,0xd5,0x70,0x11,0x29,0x00,0x89,0xe8,0x76,0xe2,0x98,0x53,0xaf,0x8e,0x30,0x63,0x43,0x35,0x68,0x96,0xbc,0xdd,0xb8,0xca,0xca,0x23,0x9b,0xb8,0x05,0xbe,0x63,0xa0,0x16,0x53,0xef,0x2d,0x8d,0x6c +.byte 0xaa,0xba,0x77,0xd1,0xcf,0xde,0x04,0xbb,0x8a,0xd2,0xc1,0x0e,0xbf,0x4e,0x21,0x8b,0xf3,0x25,0x2f,0xe3,0xef,0x3f,0xd6,0xd2,0x73,0xf1,0xb2,0x1c,0x82,0x19,0xd1,0xb0,0x71,0x5a,0x87,0xcc,0x67,0x22,0x7f,0x3f,0xeb,0xfe,0x9c,0x30,0x65,0x48,0xbd,0xe0,0x9b,0x10,0x22,0xe3,0x36,0xab,0xf4,0x69,0x62,0x24,0xb7,0xc7,0x51,0xe3,0x33,0x7e +.byte 0x1a,0x05,0xad,0x3a,0xf5,0x63,0x21,0xcb,0x87,0x30,0xa1,0xb4,0xf6,0xd1,0xfd,0x30,0x73,0x32,0x4a,0xf5,0x20,0xe8,0x29,0xa1,0x37,0xed,0x5e,0xcb,0xf8,0x3e,0x03,0x7f,0x2f,0x4c,0x56,0xaa,0x35,0xf3,0xd3,0x4b,0xda,0xe6,0x49,0xf3,0x3a,0x62,0x88,0x31,0x76,0x09,0x60,0xf8,0x22,0x0b,0x1c,0x2f,0x3a,0xf9,0x64,0xc4,0xce,0x68,0x41,0xc7 +.byte 0x85,0x25,0xdc,0x81,0xe7,0x60,0x36,0x48,0x44,0xdb,0x64,0x72,0x00,0xe4,0x98,0x53,0x2a,0x48,0x21,0xbe,0xb9,0x52,0xc8,0xc5,0xaa,0xb1,0x2b,0x0f,0xeb,0x24,0xd1,0x4f,0x0d,0x4e,0x52,0xf0,0x8f,0xa8,0x13,0x94,0x0d,0x01,0xea,0xdd,0xeb,0x4c,0xb8,0xcb,0x31,0x2e,0xe4,0x5d,0x1f,0x37,0x86,0xfd,0x52,0x10,0xf3,0x02,0xf6,0x32,0xf5,0x34 +.byte 0xb7,0xa9,0x87,0x43,0xf1,0x46,0x06,0x8e,0xa7,0x1c,0x8c,0x34,0x17,0xaa,0xf7,0x59,0x33,0x2f,0xdd,0x27,0x37,0x9e,0x44,0x65,0x81,0x29,0x86,0x44,0xa8,0xdf,0xc7,0x3d,0x67,0x9f,0x14,0x50,0xd7,0xe0,0x59,0x7f,0xd9,0xdb,0xdf,0x19,0xe9,0x03,0x81,0xae,0xf8,0xa9,0x36,0x3b,0x7c,0x3c,0x30,0x6a,0x4f,0x76,0x07,0xfb,0x0d,0xa8,0xaf,0x4d +.byte 0x97,0x2f,0x2c,0x0f,0x73,0x45,0xba,0x60,0xd0,0x50,0xf7,0xf7,0xba,0x04,0xf0,0x8c,0xdb,0x68,0x04,0xbb,0xa2,0xf5,0x6a,0x58,0xeb,0xec,0x7e,0x68,0x3e,0x6c,0x69,0x6f,0x32,0x9c,0x74,0xb6,0x4a,0x8f,0x34,0x3c,0x36,0xb2,0xfc,0xfb,0xbb,0x9b,0xd9,0xbc,0x00,0x31,0x59,0x0d,0x85,0x66,0x1c,0xfb,0x99,0x55,0x78,0xdd,0x0d,0x92,0xec,0x85 +.byte 0x97,0xc1,0x6f,0xf5,0x6b,0x25,0xed,0x6f,0x09,0xef,0x50,0xdd,0xc2,0x90,0xb1,0x7d,0xa0,0x27,0x7b,0xa8,0x5f,0x35,0x0c,0x51,0x54,0x6e,0x64,0x4f,0x5d,0xcf,0x2f,0x5f,0xe7,0x99,0xb5,0xc1,0x91,0x4c,0xc0,0x24,0x01,0x4b,0x44,0x95,0xfc,0xd1,0x9f,0xa5,0xd0,0xe1,0x4f,0xb0,0x56,0x99,0x8b,0x03,0x44,0xf9,0x5e,0xfe,0xbe,0xa2,0xcc,0x58 +.byte 0x3b,0x69,0xbf,0x44,0x67,0x8e,0xd1,0xb2,0x66,0x3c,0x8e,0x68,0x6b,0x1b,0x5c,0xfb,0xeb,0x84,0xf2,0x92,0x43,0x8d,0x7c,0x64,0x11,0xc8,0xf5,0xda,0xf5,0x4f,0xeb,0x8b,0x91,0xac,0x6b,0x47,0xe0,0xfc,0xaa,0x89,0xe8,0xd2,0xba,0x58,0x43,0xbb,0x9e,0x13,0x20,0xa1,0xfe,0xf7,0xa5,0x15,0x82,0x0d,0xbb,0xc3,0x60,0x40,0xf5,0x49,0xd5,0xea +.byte 0x71,0xad,0xd7,0x7d,0x8c,0x90,0xd2,0xe5,0x51,0x8a,0x01,0x3d,0xbf,0x59,0x00,0x41,0x59,0x65,0xba,0x18,0x30,0x86,0x2a,0xcb,0x41,0x24,0x9a,0x44,0x54,0xac,0x07,0xf2,0xcf,0xe9,0x3c,0xec,0xd0,0x7d,0x91,0x0e,0xb5,0xbd,0xed,0xc4,0xf2,0x90,0x27,0x2f,0x31,0x31,0x96,0xd2,0xfc,0xe2,0x6e,0x70,0x61,0x81,0x7b,0xc8,0x8d,0x78,0x41,0xb9 +.byte 0x56,0x64,0x01,0x37,0x86,0x54,0xec,0x2b,0xdb,0xd5,0xef,0xf7,0xf4,0x73,0x8d,0x84,0xdd,0x5c,0xd4,0x00,0x23,0x2b,0x4c,0x4c,0x04,0x4b,0x4b,0x61,0xd0,0x4b,0x38,0x8f,0x5e,0x56,0xb2,0xc5,0xc7,0x72,0x04,0x33,0xed,0xd7,0x91,0x99,0x22,0xee,0xdf,0xe5,0x65,0x55,0x9a,0xcb,0x32,0x22,0x48,0x6d,0x55,0xe8,0x9f,0xf9,0x95,0x62,0x45,0xdc +.byte 0x21,0x6e,0xc5,0xb2,0x8e,0x4d,0x9a,0xf2,0x2b,0x2e,0x6f,0x40,0xd1,0x2f,0x4d,0xda,0xbd,0x85,0xb1,0x6f,0x04,0x39,0x09,0xfa,0xa1,0x3b,0x86,0xe6,0xdb,0x3e,0x50,0x27,0x48,0x51,0x2c,0x1e,0xe5,0xf0,0x82,0xb6,0xfc,0xd7,0xc3,0x3f,0x3f,0x16,0xa6,0xbc,0x85,0x60,0x8f,0x6e,0xd9,0xd7,0xbd,0x93,0x33,0xf4,0xd2,0xb6,0xb4,0x9f,0x73,0xef +.byte 0xa5,0x59,0x32,0x4c,0x89,0x1f,0xb0,0x0b,0x71,0xf1,0xa1,0xa3,0xdb,0x4d,0xed,0xcc,0x59,0xfe,0xe9,0x6f,0x60,0x96,0xa3,0x11,0x46,0xc5,0x3d,0x60,0x53,0x39,0x3e,0x6c,0x87,0xbb,0x14,0x85,0xe6,0x0f,0x80,0x8c,0x7d,0x63,0xdc,0x34,0x20,0xc0,0x5d,0x7f,0xb4,0x19,0xdd,0xb2,0xe5,0x36,0x86,0xb9,0x88,0x7b,0x18,0x81,0x2e,0xc9,0xdd,0xf9 +.byte 0x8a,0xb8,0xc9,0x21,0x16,0x5f,0xd3,0x8c,0x49,0xdc,0xe0,0x65,0x9f,0x41,0xe4,0x5a,0x52,0x07,0x1e,0x35,0xbb,0x6f,0x06,0x42,0xc7,0x91,0x66,0xc8,0x93,0xe1,0x89,0x39,0x43,0x3a,0x76,0xdb,0x14,0x41,0x91,0x90,0xcf,0x55,0x78,0x36,0xbd,0x52,0x5f,0x23,0x9e,0x59,0x45,0xad,0x00,0xdf,0xac,0x50,0xc3,0xe1,0xa4,0xca,0x5b,0x3e,0xf7,0x7d +.byte 0x51,0x21,0xb0,0x61,0xc6,0x3d,0xca,0xc0,0x06,0x9d,0x16,0xd3,0x7c,0x08,0x56,0x5f,0xc6,0xf2,0x27,0xe6,0x60,0x39,0x8f,0xf7,0x41,0xd4,0x3c,0xb9,0x25,0x1c,0xa2,0xb8,0xc6,0x73,0x6e,0x71,0x92,0xb6,0x3d,0xed,0x9d,0x1c,0x76,0xd3,0x8d,0x56,0xd7,0xc6,0xd6,0x1f,0x6a,0x0d,0x3c,0x91,0xeb,0x3a,0x7b,0x38,0x6b,0x18,0xcb,0x91,0x56,0xc2 +.byte 0xf6,0xa6,0xb2,0x5f,0x36,0x31,0xa2,0xd9,0xdf,0x49,0xb3,0xeb,0xf5,0x60,0xbe,0x95,0x57,0xa1,0x22,0x3e,0xb5,0x81,0x0a,0x58,0xc7,0x65,0x3d,0xb8,0x89,0x5b,0x91,0x5d,0x21,0x29,0x87,0xa9,0x03,0xdb,0x4c,0x36,0x4c,0x4f,0xf0,0xe5,0x4a,0x73,0x34,0x97,0x62,0x40,0x4e,0x2b,0x66,0x71,0xfc,0x4f,0xa2,0x99,0xbb,0xe6,0x59,0x82,0xca,0x6d +.byte 0x61,0x35,0x6e,0xb3,0x2c,0x3c,0xb6,0xa0,0xb5,0x91,0xb2,0xe1,0x11,0x7d,0x8a,0xfd,0x32,0xff,0x67,0xbd,0xe7,0x98,0xcb,0x25,0x8a,0xea,0x03,0xbe,0xd0,0xf2,0x14,0x97,0x7a,0xc0,0x8a,0x4f,0x04,0x26,0x26,0x01,0x24,0xd4,0x50,0x57,0x73,0xdb,0xe9,0xc2,0xbc,0xc8,0x47,0x08,0x64,0x16,0x33,0xa1,0x5e,0xac,0x2c,0xa3,0x8e,0x88,0x88,0x66 +.byte 0x0a,0x3b,0x11,0x39,0x44,0x3c,0xab,0xb1,0x69,0xe0,0x42,0xc2,0xda,0xda,0x0d,0xdd,0x4d,0x66,0xc2,0xdf,0xb7,0xa1,0xa0,0xb3,0x82,0x95,0xe3,0x62,0x2e,0x29,0xb4,0x97,0x75,0x6a,0x3a,0x23,0x29,0x67,0x69,0x53,0xd5,0x9a,0xba,0xc8,0x42,0xfe,0x54,0xba,0xca,0x4f,0x8f,0xaa,0xb0,0x76,0x69,0x83,0x84,0x0d,0x3b,0xf8,0x15,0x37,0xbc,0x86 +.byte 0x15,0x98,0x89,0xc6,0x8c,0x40,0x52,0xf9,0xe7,0x87,0xdb,0x19,0x64,0xb7,0x1f,0x32,0xdb,0x41,0xe8,0x7a,0xcf,0x4c,0x98,0xc0,0xfb,0x33,0xbd,0x84,0x6d,0x9c,0xbd,0x1c,0xdb,0xba,0x1b,0x3b,0xb1,0x22,0x3e,0x6f,0x74,0x36,0xe2,0x54,0xb3,0x87,0x70,0x27,0x4c,0x5f,0xb9,0xe4,0x90,0x8b,0x63,0x0c,0x3d,0xed,0xa0,0xb0,0x36,0x2c,0x96,0xd6 +.byte 0xc7,0x49,0x3e,0x29,0xc7,0x62,0x5a,0x3b,0x57,0x9c,0x91,0x68,0x8f,0x4e,0x80,0x18,0x9c,0xba,0xd1,0xcc,0x5a,0xdf,0xa0,0x88,0xbc,0x8f,0x31,0xaa,0xbc,0xd0,0xde,0x43,0x57,0x20,0x12,0x3e,0x88,0x58,0x1f,0xd5,0x68,0xba,0x87,0x38,0x94,0x6f,0x24,0x03,0xf4,0xe0,0x34,0xab,0xab,0x35,0x71,0xad,0xb0,0xaf,0x0f,0x9a,0x29,0xfa,0xde,0x69 +.byte 0xe8,0xcc,0xcd,0xaa,0x28,0xfe,0x85,0xdd,0xba,0xcf,0xdf,0x71,0xdc,0x12,0x77,0x94,0x70,0xd7,0x27,0xe6,0xab,0xa9,0xb3,0x8a,0x73,0x58,0x90,0x86,0x9a,0x0e,0xe1,0xae,0x8e,0x3c,0x07,0x8f,0xb4,0x9d,0x87,0x8f,0xb2,0xa3,0x3b,0x49,0x76,0x63,0xbf,0x6b,0x75,0x52,0x54,0x66,0x4c,0xa8,0xa9,0xb2,0xd4,0x4f,0xb0,0xd0,0x9e,0xfd,0x26,0x23 +.byte 0x57,0x4f,0xa5,0x99,0x1c,0xbe,0x67,0xbb,0x26,0xd2,0xcb,0x1a,0x18,0xd6,0x5f,0xfa,0x91,0xfd,0x30,0x3b,0xf4,0x02,0xa2,0x36,0x0c,0xfe,0x30,0xb2,0xc8,0x96,0xe1,0xa9,0x75,0xad,0xf3,0xb7,0x20,0x9b,0x47,0xee,0x5c,0xae,0x7b,0xfe,0xbd,0x38,0x8b,0x2b,0x7d,0xb8,0x92,0x59,0xd7,0x3b,0x91,0x40,0x5e,0xa8,0x20,0x6f,0x45,0xd8,0xd4,0x5f +.byte 0x33,0x8f,0x6a,0xd3,0x67,0x9e,0x46,0x17,0xb8,0x02,0x31,0xc0,0xdc,0x5e,0x35,0xfa,0x22,0xb6,0x7e,0xbf,0xd6,0xc9,0x4e,0x66,0xa1,0xd2,0xd8,0x2a,0x84,0x2c,0xd6,0xb1,0x15,0xda,0xdb,0x3e,0xc4,0x61,0x93,0x08,0x64,0x8d,0xf0,0x61,0x9d,0xeb,0x12,0xcc,0xd1,0x3b,0xf7,0x9f,0x1a,0x18,0xe7,0xc8,0x00,0x6b,0xfd,0x84,0xd6,0xed,0xb5,0x40 +.byte 0x69,0x72,0xd3,0x19,0x7d,0x24,0x7b,0x19,0xf2,0x57,0x58,0x19,0x75,0xec,0x26,0xe7,0x90,0x9d,0xe5,0x9d,0x91,0xa6,0x64,0x2e,0x29,0x15,0xc6,0x7f,0x7c,0x05,0x35,0xd5,0xe5,0x8e,0x36,0xce,0x49,0xc7,0xcd,0x69,0xa2,0xf9,0x1b,0xd5,0x84,0x13,0x4b,0x4a,0xb1,0x6c,0x15,0x6e,0xf2,0xf1,0x47,0xef,0x8a,0x18,0x6f,0xbc,0x36,0xfe,0xc3,0x85 +.byte 0x2b,0x46,0x7b,0x1c,0x31,0xa6,0x41,0x33,0xaa,0x62,0x6f,0x17,0xae,0xd4,0x23,0x9b,0x93,0x79,0xdc,0xac,0x53,0x01,0x83,0x81,0x2b,0xef,0x5b,0x79,0x6a,0x8a,0x82,0xfe,0x9c,0xe3,0x08,0x06,0x57,0x2d,0xf0,0xc1,0x3a,0xa9,0x8c,0x57,0xa9,0xa6,0x13,0xf5,0xfc,0x2c,0xef,0x96,0xaa,0x3b,0xe9,0x5b,0xf0,0xb9,0x38,0x3d,0xe3,0x8c,0xa2,0xaa +.byte 0x2c,0x75,0xca,0xc5,0x0a,0x72,0x8b,0x48,0xc7,0x97,0xd3,0x06,0x38,0x13,0x52,0xde,0x38,0xed,0x20,0xd1,0x43,0x24,0xee,0xd7,0x97,0x56,0x2c,0x46,0x09,0x38,0x13,0xd9,0x0a,0xa3,0x45,0x01,0x29,0x2b,0xf4,0xff,0x8e,0x87,0x94,0x4e,0xaf,0x35,0xdb,0x17,0x49,0xa7,0x53,0x0e,0x0f,0x8f,0xee,0x08,0xa1,0xee,0x54,0x73,0x66,0x6f,0xd3,0x17 +.byte 0xec,0x72,0x51,0x54,0x5e,0x06,0xaa,0x10,0x1f,0x2c,0xe0,0x34,0xd9,0x4d,0x34,0x0f,0xbd,0x9e,0x18,0x33,0x83,0xdb,0xbe,0x9a,0x9d,0x44,0xd4,0xef,0x8e,0x9d,0x5e,0xe5,0x29,0x2b,0x98,0xfc,0xfc,0x7a,0xb4,0xd7,0x34,0x81,0x43,0xae,0x46,0x01,0x81,0xb9,0xb7,0x93,0x00,0x35,0x55,0x72,0x7a,0x54,0xc2,0x59,0xda,0xe7,0x14,0xee,0x9e,0x04 +.byte 0xe2,0x60,0x5a,0x71,0x58,0xb5,0xdc,0x98,0xf2,0xc7,0xce,0x37,0x7a,0x31,0xcf,0x5a,0x25,0x56,0x5c,0x1c,0x97,0x22,0x70,0xc2,0x91,0xf7,0xb2,0xff,0x69,0x8e,0x5b,0xaf,0xf8,0xd3,0x3e,0x35,0x0a,0x69,0x3c,0xd5,0x79,0xb6,0xef,0xbe,0xf8,0x47,0xe5,0xc5,0x82,0xca,0x12,0xde,0x86,0x1d,0xbe,0xbe,0xe1,0xc3,0x37,0xdd,0xb9,0x3e,0x6b,0xbf +.byte 0xe7,0x37,0xc2,0x6d,0xe5,0xa0,0x57,0xd8,0x5d,0x7e,0xff,0x9e,0x4b,0xb9,0x04,0x0c,0x3b,0x40,0x64,0xc8,0x50,0x68,0x7b,0x9d,0xbe,0x64,0x31,0x8f,0x8b,0x4d,0x74,0xa8,0x09,0xd3,0x36,0x0f,0x9e,0x56,0xdd,0xb7,0xee,0x81,0x88,0x06,0x12,0xf8,0xf6,0xca,0x7f,0x97,0x04,0xc8,0x23,0xea,0xc2,0x07,0x3e,0x22,0xca,0x2a,0xe2,0xf3,0x4f,0xfe +.byte 0x42,0x09,0x78,0x13,0xe5,0x4e,0x91,0xc7,0x33,0x5d,0xf4,0xf4,0x07,0x85,0x7b,0xd4,0x79,0x31,0xd1,0xcb,0xac,0xc9,0x54,0x53,0x39,0x37,0x82,0x6b,0x54,0xbe,0x30,0x7b,0x7d,0x8d,0xe7,0xc6,0x04,0xc2,0xa9,0x27,0x27,0x0c,0x38,0xd5,0x6d,0x32,0x6f,0xe1,0xa0,0xe2,0x41,0x6e,0x11,0x1e,0xe7,0x32,0x9d,0xa2,0x3e,0x16,0xaa,0x96,0xd9,0xd1 +.byte 0x78,0xde,0xd3,0x42,0xcf,0x27,0xba,0xea,0x82,0xdc,0xf8,0x32,0xa6,0xb9,0x19,0x6a,0x9a,0x0c,0x21,0xae,0xb2,0x0f,0x5c,0x5b,0x64,0x6f,0x29,0xcc,0x5c,0x59,0xc6,0x9d,0x42,0x9b,0x60,0xb0,0x64,0x5e,0xbe,0x22,0xa1,0x00,0xc1,0xc4,0x8f,0x5e,0x3c,0x2a,0x34,0x63,0x41,0x66,0xa7,0x38,0x50,0x57,0xd3,0xd4,0x88,0xb1,0x82,0xaf,0x48,0x29 +.byte 0x48,0x6d,0x31,0x21,0x76,0x71,0xfb,0xea,0x95,0xdd,0xe0,0xd6,0xa4,0xf9,0x3f,0x09,0xf0,0x8f,0x9c,0xdc,0x67,0x8d,0x11,0xf6,0xad,0x00,0x93,0x71,0x5d,0x2b,0xe1,0xb6,0x7a,0x1a,0x80,0xbd,0x1f,0x01,0xe7,0xd5,0xbb,0x9a,0x42,0x75,0x29,0x83,0xe4,0x4f,0x54,0x67,0xbf,0x16,0xf5,0x6c,0x67,0x5b,0x0d,0xb6,0x24,0xb6,0x36,0xa5,0x9c,0xfe +.byte 0xa5,0xfe,0x3e,0x72,0xf4,0x1b,0x3e,0x6d,0xd9,0xd7,0xe3,0xb4,0x44,0x36,0xc1,0x87,0x56,0xe2,0x77,0x61,0xea,0xc6,0xfe,0xf6,0xfb,0x48,0xd0,0xa4,0x99,0xf7,0x1a,0x85,0x4a,0xd1,0x6d,0xad,0x84,0xeb,0xd3,0x6d,0x1d,0xfd,0xaf,0x3f,0xde,0x3c,0x26,0xae,0x55,0xad,0x97,0x42,0xd5,0x6e,0xd7,0x7e,0x6b,0x42,0x7f,0x3a,0xa6,0xa8,0x27,0x0a +.byte 0x68,0xbf,0x6e,0x41,0x51,0x1d,0x01,0x1a,0x93,0x50,0xc5,0xd8,0x4f,0xbf,0x42,0xca,0x37,0x07,0x01,0xe8,0xd1,0xf1,0x2a,0x3a,0xa2,0xc3,0x2a,0xc8,0x4b,0xde,0x66,0xf4,0x38,0xc5,0x36,0x4e,0xe9,0x3b,0xad,0xcd,0x5f,0xe1,0x40,0xc3,0xea,0x93,0x7d,0x45,0xfb,0xab,0xde,0x52,0x9b,0x96,0x90,0xfe,0x67,0xf5,0x43,0x6e,0x1a,0x3f,0xf8,0x47 +.byte 0x68,0xf7,0x9e,0x08,0x70,0x45,0x4f,0xbc,0x5c,0x0b,0x4c,0x01,0xe8,0x96,0xfd,0xae,0xe4,0x41,0x75,0xe6,0xb0,0x66,0x68,0x2f,0x43,0xcd,0x55,0x20,0x99,0xd0,0x48,0x34,0x38,0x0b,0xb7,0x77,0x3a,0x4c,0x3e,0xb5,0x57,0xaa,0x11,0xbb,0xc9,0xcf,0x04,0x78,0xbb,0x49,0x41,0xee,0x6d,0x39,0xfa,0x09,0xe7,0x13,0xf3,0x23,0x41,0xdc,0x2e,0x93 +.byte 0x65,0xc8,0xda,0x1b,0x18,0x99,0x07,0xaf,0x67,0x6e,0xcd,0xf1,0x66,0xab,0x1f,0x89,0x4b,0x8f,0x2c,0x09,0x2f,0x87,0xe1,0xd0,0xb0,0x6d,0x2c,0xa4,0x16,0x6c,0x9e,0x9f,0x8f,0x92,0x0e,0x21,0xf1,0x06,0x67,0x93,0x53,0x51,0xd4,0xcb,0xa2,0x12,0xf4,0xd4,0x87,0x2e,0x12,0xd5,0x98,0xba,0x95,0xe3,0xd3,0xbe,0x3f,0x20,0x39,0xe5,0xbb,0x9e +.byte 0xaf,0xcc,0xa0,0x71,0xd8,0x8d,0x35,0x4b,0xf0,0x98,0x71,0x57,0x00,0xd3,0xb3,0xba,0xe3,0x04,0x24,0xb9,0xee,0x75,0x40,0x83,0xb4,0x11,0x0d,0x0d,0xf6,0xe0,0x10,0xf0,0x30,0x4c,0x45,0x71,0x5a,0x2e,0xd0,0xc8,0xcc,0xa9,0x5a,0xc8,0x10,0xb3,0x7c,0x07,0xf7,0x0b,0x8d,0x1e,0xe1,0xf1,0xa0,0x82,0xfd,0x1d,0xe4,0xad,0x8a,0x37,0xa3,0x81 +.byte 0xff,0x14,0x12,0x74,0x42,0x81,0x7f,0x5c,0x89,0x47,0xcc,0x3c,0x27,0x92,0xf9,0xfa,0x9f,0xb8,0x6f,0xfe,0x36,0x23,0x1d,0x94,0xf3,0x43,0x09,0x82,0x87,0x46,0x92,0x8c,0x6a,0xbb,0x41,0x42,0xef,0x4d,0xa5,0x55,0x8a,0x48,0x13,0xd8,0x86,0x03,0x5b,0x48,0x3a,0x2b,0xcf,0xfd,0x35,0xb2,0xd4,0xf8,0x61,0x9c,0x0b,0x70,0x65,0x67,0x54,0x46 +.byte 0x8d,0x2f,0xc6,0x97,0x12,0xff,0xfe,0xc9,0x23,0x64,0xcd,0xb7,0x14,0xa5,0x41,0x43,0xf3,0x0d,0x08,0xe4,0xf0,0x41,0x46,0x57,0x4b,0xdb,0x42,0xac,0xd5,0x0d,0xc8,0x33,0x84,0xa9,0x57,0x05,0x03,0xaf,0xbd,0x4f,0x48,0x5f,0xc2,0x3c,0xb9,0x07,0x79,0x47,0x2c,0x3c,0x71,0x1b,0x74,0xb9,0xc3,0x5a,0x65,0xc7,0xff,0x70,0xfb,0xc0,0x63,0x98 +.byte 0x81,0x3d,0xd0,0x57,0x42,0x79,0xa2,0xdb,0xe6,0x2a,0xe0,0x00,0x4e,0xdf,0x3d,0x9d,0xc9,0x40,0x09,0x01,0x30,0x0d,0xa8,0xce,0x40,0x55,0x95,0xaf,0x01,0x48,0x74,0x16,0x99,0xa3,0xdf,0x63,0xa6,0x56,0xd8,0xe8,0x1e,0x8a,0xa7,0x7d,0x18,0xe6,0x37,0xe0,0xf8,0xd9,0xf4,0xb6,0x3f,0x92,0x7b,0xe1,0x17,0x57,0x3c,0x26,0x33,0x1d,0xf2,0x9e +.byte 0xfc,0x26,0xd5,0x5a,0x34,0xcf,0xc4,0xaf,0x7b,0x11,0xe3,0x77,0x95,0x51,0x93,0x8a,0x56,0x68,0x80,0xf8,0x62,0x6c,0xc0,0x4e,0xe8,0x39,0x46,0x7f,0x56,0x27,0x26,0x25,0x2b,0x88,0xdb,0x38,0x62,0xa5,0xbc,0x96,0x16,0xed,0xd1,0xc7,0x0f,0x47,0xec,0x72,0x83,0xb0,0xbe,0xb0,0x46,0x54,0xab,0xa7,0x60,0xd4,0xb3,0x63,0xa9,0x3a,0x67,0x7f +.byte 0x68,0x94,0x8a,0x54,0xf0,0x79,0x38,0x2a,0x67,0x7f,0x29,0xb4,0x7b,0xdf,0x0f,0x24,0xfb,0x21,0x0e,0xf5,0xc5,0x47,0x41,0x93,0xb5,0xe3,0x85,0xff,0x84,0x34,0x2b,0x12,0x73,0x5f,0x37,0x32,0xb6,0xce,0x73,0x27,0xe6,0x5a,0x6e,0x62,0xdd,0x7f,0x49,0x59,0xe2,0x3d,0x80,0xda,0xc3,0x29,0x70,0x40,0x70,0x25,0x8b,0xa5,0xc0,0xb0,0x18,0xa2 +.byte 0xe0,0x5d,0xb6,0x52,0x14,0x8f,0xaa,0x17,0x68,0x80,0xa1,0x26,0xd2,0xbb,0xb4,0x2c,0x9a,0x41,0xfa,0x53,0x74,0xfb,0x7b,0x99,0x82,0xc1,0xff,0x77,0xa5,0xe0,0xea,0x64,0xb0,0x9c,0x48,0xce,0xb0,0x7a,0x05,0xa6,0x80,0x8d,0x92,0x92,0x47,0x1a,0x50,0xce,0x62,0xed,0xbd,0x41,0x59,0xe7,0xe6,0x3b,0xfb,0xe4,0xa4,0xb2,0xd4,0xb0,0x0b,0xe2 +.byte 0x82,0xff,0x4d,0xb3,0xa6,0x43,0x4b,0xbf,0x7a,0xf7,0xfa,0x3c,0x38,0xd5,0xb2,0xf1,0xce,0x71,0x07,0xa4,0x6a,0xe3,0x7a,0x78,0xdf,0x56,0x1c,0xa1,0xf6,0x5d,0xeb,0xcc,0xb4,0xa7,0xca,0xaf,0x19,0xd0,0xb8,0x11,0x85,0xc7,0xf3,0x8a,0x23,0x6e,0xb8,0x92,0xd0,0xfc,0x61,0x9b,0x38,0x28,0x7b,0xa4,0xff,0x0d,0x32,0xf5,0xc5,0x31,0x5b,0x69 +.byte 0xbd,0x6b,0xa5,0x46,0xd2,0x26,0x2c,0xe2,0x36,0xba,0x7c,0x42,0x8d,0xbe,0xfe,0x7c,0xbd,0x38,0x14,0x47,0x9a,0x6d,0xc7,0x20,0xda,0xd4,0x9d,0x05,0x31,0xdb,0xe7,0xda,0xac,0x27,0x14,0x7f,0xca,0x23,0xc1,0x5e,0x7e,0x26,0x04,0xf0,0xf3,0xb7,0xf7,0xdd,0xd4,0x05,0x7b,0xc5,0x7e,0x4a,0xeb,0x78,0x35,0x5e,0xb4,0xda,0xec,0xb5,0x46,0x96 +.byte 0x63,0x56,0x17,0x55,0xfa,0xe8,0x11,0xd0,0xac,0xfd,0x5c,0xc8,0x99,0x2d,0xf7,0x4a,0x76,0xed,0x06,0xa2,0x77,0xfc,0x0f,0x13,0xe6,0xbc,0x79,0xae,0x15,0x23,0x17,0x0d,0xc3,0x01,0xee,0x36,0xe4,0x21,0x33,0x22,0x03,0x56,0x51,0x81,0xb4,0x5b,0x70,0xc7,0x6e,0xc4,0x54,0x93,0xcc,0x46,0x60,0x76,0x0e,0xc6,0x10,0x8c,0x52,0x6b,0x75,0x6a +.byte 0xd9,0x27,0x04,0x0a,0x56,0x80,0x1b,0xfd,0x59,0x88,0xd5,0x03,0x99,0x01,0x5e,0xc6,0x2f,0x74,0xf0,0x90,0xae,0x10,0x9e,0x52,0x39,0xcd,0xa4,0x69,0x4d,0xb9,0x8d,0xbc,0xaa,0xf2,0xe4,0x25,0xdb,0x85,0x00,0x82,0x95,0xe3,0x8e,0x72,0xba,0xd0,0xf3,0xfe,0xb0,0x6e,0xb8,0xcd,0x2d,0x7c,0xae,0x95,0x62,0x1f,0xe9,0xf8,0x71,0x23,0xd5,0x3e +.byte 0x33,0x30,0xb8,0x2d,0xf6,0xf5,0x45,0x1a,0x1b,0xf6,0xf1,0x6a,0x9a,0x7d,0xd4,0x76,0x27,0x6e,0x29,0x57,0xe6,0x90,0x36,0x83,0x4c,0x6b,0x00,0x77,0xf0,0x3d,0xb5,0xfe,0x19,0xb8,0x6f,0x76,0x58,0x7a,0x6c,0x2c,0xd0,0x22,0x5f,0x23,0x46,0x15,0xaf,0xbb,0xa0,0x40,0x37,0xba,0xb2,0x7f,0x6d,0xe2,0xa8,0x79,0x65,0x7a,0xb7,0xb0,0x51,0x04 +.byte 0x77,0xec,0xed,0x58,0xd0,0x37,0x43,0xc4,0x95,0xe9,0xcb,0x82,0x8e,0x17,0xba,0x7a,0x8b,0xc0,0x71,0x6e,0x8a,0x5d,0x5d,0xe9,0xbd,0x28,0x0d,0xda,0xd9,0x4a,0xd6,0x71,0x58,0x3c,0x31,0x69,0x34,0x48,0x48,0xe1,0x50,0xc6,0x69,0x28,0x0d,0x24,0x45,0x15,0x13,0x1d,0x00,0xd6,0xd4,0x6b,0x05,0x56,0xf9,0xb7,0xf7,0xbc,0x26,0x37,0x51,0x65 +.byte 0x91,0xf3,0xc6,0x50,0x44,0xce,0xa6,0x35,0xd9,0x0a,0xb2,0xd8,0xf3,0x6c,0x60,0x63,0x20,0xa3,0x18,0x34,0x83,0x1f,0x0d,0xc9,0x97,0xab,0x1f,0xb5,0x1f,0x6d,0x28,0xd4,0x84,0x1d,0xd4,0x08,0x45,0x83,0xa2,0x18,0x26,0x98,0xf6,0x1a,0x1c,0x9c,0xd9,0x79,0x92,0xef,0xdb,0x86,0x7b,0xb2,0x7b,0x30,0x64,0xeb,0x9d,0x7c,0xf0,0xf0,0x22,0x1e +.byte 0x65,0x2d,0x22,0x11,0x0a,0x73,0x9b,0x82,0x21,0xb0,0x0f,0xa4,0xb4,0xdf,0x5d,0x72,0x61,0x56,0x60,0x27,0xab,0x84,0xe2,0xdc,0x63,0x74,0xd3,0xbf,0x45,0x93,0xc3,0x05,0x17,0x16,0x69,0xcd,0xfa,0xf7,0x5d,0xcb,0x29,0x04,0x88,0xf1,0x67,0x94,0xce,0x1d,0xa1,0x7f,0xc4,0xd1,0xca,0x09,0x39,0x54,0xf2,0x1d,0x32,0x99,0x49,0x89,0x95,0xe3 +.byte 0x8b,0xc6,0x4a,0x41,0xbc,0x13,0x60,0xbc,0xff,0x2a,0xa0,0xc8,0xb2,0xc0,0x42,0x52,0x7a,0x8f,0x77,0xcb,0xc8,0x79,0xfd,0x0f,0x08,0x40,0xd6,0x39,0x1e,0xcd,0x87,0x12,0x09,0x6e,0x9b,0xc9,0x5f,0xfa,0x79,0xd1,0x83,0x63,0xcb,0xa6,0x7b,0x0c,0x4d,0x41,0x9f,0x30,0x70,0x35,0x48,0x0a,0x64,0xdd,0x4f,0x4f,0x28,0x19,0x8a,0x29,0xff,0xa2 +.byte 0x5c,0xe9,0x1e,0x4c,0x68,0xdf,0x6a,0x3c,0x85,0x82,0x6b,0x0b,0x8a,0x63,0x6f,0x02,0x86,0x9f,0xe4,0x0a,0xf8,0xb5,0xae,0x65,0x64,0x55,0xb5,0x3f,0xb3,0xaa,0x0f,0xda,0x10,0xb0,0xeb,0xb5,0x5c,0x70,0x93,0xea,0x92,0x27,0x30,0x4e,0x73,0x4f,0x2d,0x25,0x88,0xa5,0x39,0x84,0xf7,0xf7,0x3a,0x4b,0x42,0x75,0xa1,0x87,0x75,0x9f,0xb0,0x08 +.byte 0xda,0xb4,0x45,0x62,0x20,0x65,0x40,0x37,0x79,0xc9,0xdb,0x1d,0xbe,0x79,0x32,0x62,0x37,0x48,0x3c,0xc5,0xbf,0xb6,0xe4,0xb9,0x71,0xdb,0x88,0x16,0x2a,0xd3,0xec,0x50,0x94,0x52,0x65,0x41,0x84,0x94,0x58,0x6c,0xe5,0x95,0x44,0x3f,0x79,0x5e,0x71,0xbd,0x22,0x14,0x7d,0x8a,0x7d,0xd5,0x63,0x2d,0xce,0xfb,0x63,0xfc,0x0c,0xe5,0x99,0xd0 +.byte 0x64,0xb5,0x00,0x80,0x26,0xa1,0xa1,0x40,0xa7,0x58,0xcc,0x32,0xc1,0xa5,0x27,0x16,0x9f,0x74,0xf2,0x01,0x59,0xf8,0x79,0x50,0x4f,0xef,0x0a,0xb9,0x79,0xf7,0x00,0xa4,0x9e,0x4f,0xa7,0x75,0x46,0x0e,0x25,0x5c,0x57,0x20,0xf2,0x08,0x57,0x82,0xc6,0xc3,0x57,0xdc,0xb4,0x65,0xdc,0x0f,0x17,0x17,0x36,0xef,0x49,0x05,0xf1,0x33,0xef,0x24 +.byte 0x28,0xba,0xce,0xbc,0x4e,0xfd,0x0b,0xd5,0xce,0xe0,0xcb,0x38,0x16,0xcf,0x89,0xbb,0xc3,0x34,0xd0,0x1b,0xf0,0x4a,0x63,0x8a,0xcb,0x7c,0x46,0x7a,0xca,0x9e,0x9e,0xc9,0x03,0xa6,0x25,0xd1,0x22,0xeb,0xe7,0x1a,0x16,0x04,0x20,0x33,0x2a,0xf8,0xbc,0xca,0xb4,0xfc,0xff,0x95,0x31,0xdf,0xaa,0x0a,0xf7,0x60,0xf7,0x72,0x1f,0x53,0xd8,0x0a +.byte 0x73,0xa6,0x27,0x55,0xdf,0x21,0xc8,0x41,0x1c,0x27,0xe3,0xe6,0x10,0x29,0xcf,0xd1,0x72,0x71,0x9b,0xcc,0xe6,0xf4,0x9f,0x2b,0xec,0x5d,0x6b,0xab,0xf6,0x09,0xff,0xd8,0x5e,0xf0,0x38,0x7a,0x67,0xb3,0xbe,0xa5,0x82,0xa5,0xc1,0x2e,0xa4,0xd6,0x42,0x07,0xc7,0x96,0x0d,0x11,0x2f,0x09,0x12,0x3c,0x81,0xaf,0xe6,0x52,0x31,0x2a,0x00,0x68 +.byte 0x24,0x6e,0x28,0xc5,0x6e,0x3a,0x93,0x6f,0x01,0x3d,0xbc,0xc0,0xc0,0xca,0x92,0xb8,0x99,0x77,0xde,0x1a,0x38,0x24,0xdd,0xe4,0x1e,0x8c,0xf2,0x73,0xad,0x0b,0x79,0x8d,0xce,0xfa,0xf4,0x50,0xb6,0x64,0xab,0xf5,0x93,0x3a,0x73,0xba,0xe0,0x50,0x56,0x49,0xf3,0x08,0xf2,0x9d,0xec,0xe0,0x50,0xf1,0x26,0x08,0x2f,0x66,0x09,0xa1,0x45,0xb7 +.byte 0x7b,0x3e,0xb4,0xfb,0xce,0xfe,0x69,0xfb,0x85,0x6d,0xc4,0x4b,0x15,0x87,0x8c,0x22,0x08,0x12,0x0f,0x46,0x9b,0xfa,0x32,0xae,0x7f,0xd1,0xa2,0x2c,0x65,0x0b,0xf0,0x62,0xa7,0x6a,0x8e,0xdc,0x10,0x56,0x86,0x84,0x14,0x77,0x6d,0x9f,0xd3,0x72,0x09,0xd9,0xdc,0x28,0xfe,0x15,0x9d,0xfb,0x10,0x0d,0xda,0x9e,0xbe,0x4b,0xcb,0xd9,0xf9,0x9c +.byte 0xff,0xd5,0x19,0x18,0x6e,0x4f,0x33,0x21,0xfb,0x50,0x05,0x3c,0xbf,0x69,0xb2,0x91,0x07,0x5b,0xdb,0x2e,0x99,0x6c,0x20,0xc9,0x68,0x51,0x25,0x90,0xb2,0xcc,0x45,0x50,0x11,0x09,0xca,0xe2,0x19,0x04,0x5b,0x0c,0x99,0x34,0x7b,0x1e,0xc6,0x22,0xec,0xc4,0x5e,0x46,0x28,0xd2,0x08,0xf9,0x33,0xb4,0x9f,0xd0,0x56,0x52,0x97,0xa7,0x88,0xcf +.byte 0x90,0xd7,0xe0,0xc4,0xcd,0xef,0xba,0x3f,0x56,0xb9,0x00,0x21,0x5b,0xc8,0xcd,0xc7,0x43,0x00,0xde,0x24,0xca,0x44,0xe5,0x9e,0xe5,0x7a,0x08,0xe5,0x7b,0x19,0x86,0x62,0xa1,0xff,0x8d,0x69,0xbf,0xea,0xee,0xae,0x7d,0x76,0x63,0x04,0xa7,0x56,0xb5,0x5d,0x08,0x98,0xd3,0x34,0x4c,0xa1,0x1f,0x26,0x41,0x8f,0xd5,0xd4,0x7f,0xb5,0x9d,0xce +.byte 0x70,0xf1,0xbf,0xc5,0xa2,0x44,0x3c,0x30,0x89,0xbf,0xba,0x04,0xb5,0x0e,0x7e,0xe1,0x1d,0x1c,0xbb,0x29,0x83,0xa8,0x16,0x98,0x7d,0x8c,0xb4,0x03,0xb5,0x85,0x85,0x3a,0xcb,0xc1,0x54,0xf0,0xda,0xa7,0x89,0x81,0xe6,0xd1,0xe0,0x95,0xb6,0x9e,0x30,0xf8,0x2b,0xd1,0xbc,0x7d,0xcd,0xab,0xa2,0x1b,0xc3,0x8d,0x1d,0x2c,0x83,0xf9,0xe1,0xa7 +.byte 0x92,0x94,0x9f,0x9e,0xdf,0xa7,0xe5,0x14,0x03,0x6a,0x6a,0x60,0x8b,0x01,0x02,0xae,0xea,0x1e,0x05,0xce,0xcd,0x2b,0x29,0xca,0x0f,0x94,0xf8,0xbd,0xc8,0x55,0x6d,0x4c,0x95,0x26,0x04,0x4f,0xf8,0x75,0xcb,0x43,0xab,0x76,0x0c,0x88,0x10,0x56,0xdf,0x66,0x16,0xcc,0xf1,0x1b,0x13,0xa9,0x93,0x9c,0xc4,0x63,0xac,0x44,0xf4,0x13,0xf3,0xdb +.byte 0xcf,0xff,0xef,0x9d,0x89,0x9f,0xef,0x5b,0xa4,0x84,0xb4,0x0d,0x92,0x3b,0x76,0x03,0x3f,0x1d,0xdd,0xb1,0x5f,0x24,0xd5,0xa9,0xa5,0xdc,0x44,0x3a,0x3b,0xef,0xf2,0x8b,0x27,0xfa,0x83,0xdc,0x2d,0x4c,0xd8,0xb0,0xf8,0x7f,0x1e,0xea,0x3f,0x90,0x81,0xe1,0xc0,0x97,0x7a,0xfc,0xe1,0x00,0xf3,0x11,0xfc,0xc1,0xc2,0xa7,0x1a,0xf0,0x2c,0x41 +.byte 0x49,0xc9,0x65,0xbe,0xe1,0x0f,0x54,0xdf,0xd5,0x39,0xe8,0x7a,0x48,0x81,0xdc,0x21,0x8f,0x8f,0xd2,0x16,0x6f,0xf4,0xfa,0x43,0xdd,0xfb,0x72,0xfb,0x5a,0xd7,0x62,0x0b,0x3e,0x92,0x82,0x2d,0x27,0x04,0x7d,0x5a,0x48,0x60,0x19,0x15,0x01,0x27,0x9d,0x05,0xf2,0x6c,0xaa,0x0c,0x7c,0x79,0x14,0xdc,0x3e,0x75,0x28,0xd2,0x9d,0x3b,0x28,0xc2 +.byte 0x35,0x6c,0x73,0x4c,0x77,0x5f,0x36,0x7e,0xf8,0x3e,0xaf,0x1d,0x55,0x80,0x29,0x14,0xa4,0x48,0x80,0x82,0xb2,0x82,0xb9,0x3e,0x02,0xd6,0xd1,0xae,0x6a,0x0d,0x3d,0xfd,0xc1,0x57,0xf4,0xe6,0x90,0x8b,0x57,0x0d,0xde,0xd8,0xb7,0x15,0x71,0x82,0xe9,0x18,0x76,0x23,0xcd,0x93,0x41,0x17,0x83,0x5e,0xcd,0x6a,0x31,0x52,0x8d,0xff,0xb1,0x98 +.byte 0x6d,0x47,0x96,0x6f,0x57,0x99,0xd7,0xe8,0x70,0xd2,0x68,0x8d,0x3e,0x26,0xfd,0x86,0x5c,0x64,0xb8,0x55,0x9b,0x4a,0xcf,0x75,0x39,0x97,0x73,0x77,0x30,0x06,0xea,0x55,0x2a,0x4f,0x3c,0x78,0x98,0x85,0x37,0x81,0x5b,0xc6,0x2c,0x90,0xaf,0xb3,0xc1,0xd5,0xf1,0x81,0xce,0x7d,0xe7,0xa5,0xee,0x74,0x3f,0x1e,0xec,0x2f,0xca,0x36,0x7c,0xd2 +.byte 0x0f,0xce,0x9f,0x81,0x45,0x26,0x05,0x0e,0xeb,0xfc,0x5d,0x81,0x6d,0x05,0x22,0x75,0xdf,0x45,0x38,0x1c,0x33,0x27,0x48,0xe3,0x7c,0x18,0x9d,0x6d,0x39,0x53,0x75,0x1b,0x8a,0xcf,0xc1,0xf6,0x95,0xa7,0x30,0x43,0x71,0x62,0xe1,0x23,0xd5,0xb1,0xf4,0x5c,0xda,0x71,0x26,0x47,0xd2,0x76,0xec,0x11,0x3e,0xa5,0x00,0xcd,0x85,0x0e,0x1a,0xa7 +.byte 0xe5,0x58,0x8e,0x67,0xc8,0x73,0x1d,0xd0,0xd9,0x0d,0x43,0x04,0x41,0x4a,0xde,0xbb,0x1a,0x75,0x0d,0xb3,0xa3,0xa2,0x20,0xf2,0x14,0xf2,0xe0,0x22,0xc0,0xec,0xd3,0x7b,0x8e,0x98,0x4e,0xf5,0xe9,0x88,0x64,0x6d,0xd6,0xeb,0xf9,0xb7,0xa1,0xd3,0x9f,0x3c,0xdd,0xdb,0x91,0xe0,0x92,0x52,0x3b,0x07,0xa4,0x40,0x47,0x04,0x11,0x95,0xdd,0xc9 +.byte 0x33,0x24,0xe2,0xd5,0xa5,0x99,0xd2,0x0b,0xb5,0xb7,0xb7,0x59,0x24,0x2c,0x3e,0xff,0xc0,0xbc,0x11,0x55,0xf6,0x27,0x8e,0xd4,0xa8,0x23,0xf0,0x68,0x0b,0xd7,0x15,0xb7,0xe4,0x7d,0xc3,0x5c,0x3d,0xef,0x95,0xb4,0xad,0xe9,0x14,0x63,0xf7,0x3a,0x55,0x5f,0x6a,0x10,0x4a,0x3e,0x27,0xd1,0x7c,0xfc,0x4a,0x1a,0xab,0x2f,0x8f,0x4d,0x28,0x4b +.byte 0xd4,0xe1,0x0b,0xeb,0xa1,0x85,0xea,0x68,0xd5,0x08,0x56,0x79,0x5f,0xbd,0x2a,0x7e,0xbf,0x44,0x05,0x05,0x10,0xf3,0x22,0x58,0xa5,0x0c,0x38,0x81,0xa4,0x95,0x19,0x51,0xf7,0x7c,0x4c,0x3f,0xcf,0x55,0xf7,0x90,0xbc,0xc5,0xec,0xd0,0x6a,0x22,0xf8,0xc9,0x1e,0x62,0x17,0x86,0x24,0x04,0x5e,0x50,0xb2,0xb5,0x94,0x18,0x48,0x96,0xb8,0x21 +.byte 0x5e,0x63,0xc9,0xd7,0x29,0xc6,0x74,0xf5,0x28,0x36,0xa1,0x56,0x45,0xd6,0x60,0x4d,0x84,0xd5,0x57,0xc2,0xb6,0x9d,0xbd,0x3f,0xb4,0xac,0xf1,0x53,0x1b,0x79,0x7d,0x73,0xf5,0x61,0x5e,0x2b,0x10,0x97,0x88,0xcc,0x7d,0xe4,0xa6,0x38,0x46,0x1c,0xc0,0xa8,0x58,0x1f,0x7b,0xf4,0xf5,0x52,0x8f,0x58,0x9a,0x17,0x49,0x5a,0xd2,0x38,0x3a,0xfd +.byte 0x66,0xcb,0xf5,0x4b,0x28,0x8b,0x8d,0x7c,0xb2,0x42,0x8e,0xa5,0x2a,0x08,0x72,0xfc,0x9b,0x85,0x0d,0xe6,0x85,0xf8,0x76,0xe2,0x73,0x6a,0x53,0xc2,0x3a,0x79,0x97,0x31,0xa9,0x52,0x70,0x75,0x3a,0xe3,0xfe,0xe5,0xbc,0x95,0x8e,0xf0,0xc9,0x97,0x17,0xdc,0x26,0x78,0x24,0xd1,0xe7,0x87,0x29,0x75,0x8e,0xd8,0x3f,0x56,0xde,0x46,0x97,0x7c +.byte 0xcd,0xd4,0x01,0x57,0x6f,0xb5,0xd7,0xe7,0xbb,0xd1,0x0d,0x6f,0x0e,0x1b,0xf1,0x34,0x2a,0xcf,0x93,0x79,0x4d,0x47,0x0b,0xd4,0x69,0x77,0xc6,0x72,0x78,0x65,0xc8,0xec,0xb1,0x21,0x8a,0xfd,0x71,0xa9,0xc5,0xd7,0x89,0xa9,0xb0,0x9c,0xed,0xb8,0xc6,0x99,0x57,0xe0,0x13,0x6f,0x0e,0x85,0xea,0xc8,0x08,0xa7,0x38,0xdf,0x87,0xb3,0x46,0x80 +.byte 0xfa,0xc6,0xe8,0x6a,0x45,0x71,0x13,0x20,0xd7,0xeb,0x6c,0x3a,0x43,0x56,0x36,0x1f,0xe2,0xf4,0x65,0x2f,0x04,0x7e,0x24,0x24,0xfe,0xe0,0x8f,0x1e,0x96,0x6e,0x01,0xfe,0x4e,0x11,0x9c,0x07,0x3e,0x5a,0x29,0x04,0x21,0x6a,0xe5,0x74,0x0b,0x93,0xa3,0xb2,0xe2,0x3e,0x0b,0x39,0x97,0xf6,0xdb,0x3d,0xb8,0x0e,0x8e,0xe2,0xd9,0xf0,0xbe,0x56 +.byte 0x6f,0x6c,0xb2,0x49,0xe0,0xe0,0xc4,0x02,0xe7,0xbc,0x40,0x03,0x3d,0x5d,0xd9,0x1b,0x06,0x08,0x7b,0x0c,0x8e,0x78,0x6d,0x17,0x06,0x87,0x46,0x1e,0xfd,0xcd,0xa3,0x83,0xdf,0x67,0x25,0x54,0x2a,0xc2,0xf4,0xf9,0x73,0xf5,0xd8,0xa5,0xe5,0xc0,0xd6,0x39,0x04,0x5b,0x0e,0xd1,0x71,0x47,0xed,0x7d,0x34,0x76,0x62,0x9a,0x7d,0x6f,0x26,0xba +.byte 0x69,0x0b,0x0e,0xb2,0xbe,0xad,0xa9,0x5f,0xdd,0xe8,0x05,0xbe,0xb5,0xa5,0x2e,0xba,0x2f,0x27,0x17,0x81,0xdb,0x9c,0x38,0xd2,0xf7,0xcd,0x77,0x75,0x41,0xda,0x65,0xd1,0xf6,0x0d,0xaa,0xc4,0x43,0x69,0x2a,0xd8,0x38,0x89,0x1b,0x77,0x16,0x26,0xa7,0xcd,0x46,0x68,0x7e,0x2a,0xbc,0xbb,0x8a,0xad,0xc0,0x7c,0xd8,0x14,0xc7,0x0f,0x76,0x97 +.byte 0x33,0x0e,0x30,0xd8,0x10,0x7f,0xd1,0x38,0x5a,0x86,0xf2,0xfa,0x13,0x7a,0xd3,0x04,0x35,0x92,0x0f,0xc7,0x85,0x91,0xaa,0xe1,0xd2,0xa5,0xde,0x9a,0x0a,0xf2,0x77,0x99,0x94,0x5e,0x9d,0x67,0xf3,0x0d,0xb8,0x39,0x70,0x96,0xea,0x6c,0x82,0x59,0xe1,0x4c,0xca,0xf7,0x8c,0x26,0x42,0x1d,0x06,0xd9,0x26,0x32,0x76,0xde,0xf2,0xd2,0x8d,0xb6 +.byte 0x6f,0x58,0x57,0x0e,0xcc,0x46,0x68,0x30,0x37,0xab,0x27,0xd9,0x84,0x52,0x7f,0x67,0x64,0xaa,0xa6,0x90,0x1e,0x36,0xbe,0x70,0x35,0xd3,0x3e,0xf6,0x4e,0xee,0xa1,0xa0,0x44,0x7c,0xb0,0x22,0x75,0x1f,0x83,0x67,0xc9,0x75,0x78,0x4c,0xe6,0x6c,0x08,0xab,0x01,0x74,0xfc,0x4c,0xff,0x4e,0x1c,0x9d,0xdd,0x24,0x6c,0x4f,0xad,0x8a,0xa0,0xe3 +.byte 0xb4,0x9b,0x2f,0xfa,0xd5,0x2b,0xa0,0xb2,0x32,0xa7,0x98,0x35,0xa0,0x58,0x26,0x22,0x4a,0x63,0xf5,0x3c,0x54,0x2c,0xbc,0xa6,0x7e,0xdb,0x1c,0xf1,0xd4,0x35,0xf6,0xb7,0x62,0xd4,0x84,0xbe,0xb8,0x59,0x32,0x33,0x8a,0x17,0xb9,0x59,0xa0,0x62,0xa7,0x00,0xfb,0x72,0xc4,0xe1,0x1e,0x6c,0xec,0x64,0xea,0x97,0xeb,0xf7,0x24,0x5f,0xb2,0xdb +.byte 0xfc,0x28,0x35,0x81,0x2b,0x5a,0x73,0xd1,0x0b,0x4b,0x68,0x5d,0xa2,0x55,0x41,0xb1,0x9e,0xdf,0x35,0xed,0x7e,0x39,0xd7,0xe6,0x45,0xe8,0xe2,0x4d,0xcd,0x82,0x26,0x72,0x0a,0xa6,0x4f,0x7b,0x27,0x55,0xc1,0x7c,0xee,0x83,0x2b,0x50,0x70,0xfa,0x6b,0xf5,0x2f,0x13,0xc1,0xf7,0xa4,0x79,0xac,0x1e,0x46,0x45,0x24,0xb2,0x61,0x58,0xd6,0xea +.byte 0x11,0x72,0x83,0xa8,0x76,0x62,0x49,0x42,0x1c,0x11,0x18,0x9e,0x32,0x20,0x4b,0xc1,0x09,0xe4,0x62,0x8e,0x19,0xc7,0xda,0xed,0x57,0x12,0x20,0x59,0x53,0xa0,0x7b,0x0e,0x1f,0xc5,0x7d,0x43,0x82,0xd8,0xbd,0x33,0x09,0xb4,0x33,0x9e,0x73,0xf7,0x8c,0xea,0x34,0xe4,0x84,0x9a,0x67,0x15,0x80,0x9d,0x3d,0x77,0x30,0x9f,0xc4,0xd7,0x08,0x64 +.byte 0xce,0x90,0xd5,0x81,0xda,0xbd,0x6d,0x4d,0x0c,0x57,0x73,0xba,0x90,0xa7,0x28,0x10,0xc1,0x53,0xf3,0xfe,0x94,0x43,0x90,0xaf,0xc2,0xd7,0xdc,0xe9,0x02,0xe2,0xe4,0x67,0x98,0xa7,0x5b,0x5e,0xe2,0x40,0xcd,0x0d,0xc7,0xbb,0x46,0xab,0xd2,0x75,0x24,0x47,0x85,0xa3,0x34,0x03,0x5c,0xc6,0x7c,0xb4,0xbd,0x07,0xc0,0xa7,0x60,0xb5,0xe7,0x45 +.byte 0xac,0xb7,0x6a,0xfe,0x56,0x5a,0x08,0xc0,0x86,0xf8,0x14,0x59,0xee,0x0e,0x68,0x8f,0xa1,0xd5,0x67,0x4d,0x08,0x19,0xc8,0x29,0xcf,0x72,0xf5,0x9a,0x9a,0xf3,0x0a,0xb7,0xeb,0x31,0xd0,0x6b,0x9f,0xc3,0x26,0x58,0x9e,0x69,0x9b,0x60,0x0b,0x7e,0x43,0x0b,0xed,0x7b,0xd2,0xc8,0x6d,0x22,0xf1,0xfb,0xc9,0x82,0x50,0xec,0xf0,0xb3,0x40,0x02 +.byte 0xfd,0xc8,0xac,0x46,0x5c,0x49,0x17,0x98,0x8b,0x07,0x7e,0x9c,0x6a,0xa4,0xcf,0x46,0x4d,0x01,0x4a,0x9f,0x7a,0x39,0x81,0xf7,0xef,0x7f,0x59,0x35,0xd3,0x1a,0x71,0x1f,0x84,0xa6,0xd0,0x1b,0x47,0x9c,0xea,0x1a,0x29,0x46,0xaa,0xe3,0xa3,0xfc,0xfd,0xd2,0x4d,0xda,0x10,0x5b,0xdc,0x56,0x81,0x31,0x4d,0x01,0xb1,0x5e,0x39,0x77,0x8d,0x78 +.byte 0x5b,0x61,0xb8,0xc2,0xd9,0xe4,0xe0,0xab,0xe8,0x3e,0xb7,0x0f,0xc5,0xf8,0xad,0x2a,0xe5,0x1a,0xa3,0x66,0x69,0x78,0x66,0x4b,0xc2,0xe3,0x44,0x04,0xe8,0x51,0x59,0x2b,0xbf,0x19,0xe9,0x36,0x13,0xfd,0x1b,0x1c,0x45,0x46,0x65,0x61,0xcb,0x9e,0x98,0x03,0x40,0xf7,0xc1,0x76,0xf4,0x47,0xd3,0x69,0xef,0x63,0x36,0x0c,0x30,0x91,0xaf,0x1c +.byte 0x69,0xd5,0x93,0x41,0x8a,0x47,0x61,0xe9,0x31,0xaa,0x12,0xa4,0x99,0xa9,0x0c,0x7c,0xce,0x72,0x7d,0x9b,0xc3,0xe4,0x2d,0xb2,0x5a,0xce,0xae,0x8e,0xa1,0x54,0x75,0x20,0xed,0x9b,0xd1,0x5e,0x5e,0x55,0x9c,0x02,0x5d,0x70,0x3c,0x63,0xf4,0x60,0xb3,0x3e,0x0a,0x4d,0x29,0xf4,0x1f,0x5b,0x08,0xce,0xa5,0x06,0xdc,0xb8,0x5f,0x4d,0x6b,0xef +.byte 0x60,0xda,0xb7,0x70,0xa8,0xcd,0x2a,0x77,0xaa,0xf2,0x0f,0x77,0xb1,0xec,0xc8,0xe9,0xc0,0xed,0xb9,0x26,0xa8,0xfe,0x5e,0x60,0x1b,0x8d,0xea,0x67,0x38,0x3d,0xa5,0x5f,0xf0,0x4d,0x9d,0x75,0xc8,0xb2,0x9e,0x40,0xf8,0x7d,0x25,0xc0,0xcc,0x89,0x94,0x93,0xd6,0x3e,0x3b,0xf6,0x58,0xbf,0x5b,0xf9,0x6f,0x64,0x69,0x97,0xf4,0x9f,0xf3,0xc5 +.byte 0x98,0xe6,0xb2,0x9c,0x1d,0xb8,0xd3,0x6d,0xdb,0xf4,0x49,0x75,0x67,0x0b,0x1f,0xac,0x89,0x6c,0x16,0xc1,0x4e,0xfe,0x8f,0x8b,0x61,0x4e,0x99,0x04,0x86,0xea,0x77,0x63,0x38,0x27,0x92,0xe0,0xcd,0xdd,0x33,0x7c,0xaf,0x41,0xce,0x37,0x21,0xd9,0x37,0x08,0x38,0x55,0xfc,0x04,0x2a,0x67,0x49,0xd0,0x6a,0x71,0xac,0xc8,0x95,0x01,0xb3,0x49 +.byte 0x7c,0x19,0x05,0xdb,0xd9,0xc3,0xe6,0x81,0x3e,0x0e,0x79,0x24,0xc3,0x3d,0x95,0x6a,0x1b,0xb4,0x38,0xfa,0xcb,0x16,0xd3,0x0c,0x00,0xf7,0x85,0x4c,0x38,0x4a,0x50,0xe1,0x64,0x45,0x38,0x54,0xfa,0x85,0x04,0xe6,0x5a,0x02,0x80,0x6a,0x04,0xc2,0x28,0xb8,0x18,0xa1,0x1d,0xa1,0x88,0x18,0x30,0x8b,0x4c,0xfa,0xda,0xdd,0xe0,0x3f,0xae,0x81 +.byte 0xaf,0xa6,0xcd,0xc3,0xe9,0x33,0x46,0xd3,0x17,0xab,0x74,0xf6,0xee,0x24,0xa7,0x8c,0xfa,0x5d,0x18,0xe0,0xa7,0x23,0x06,0x71,0x87,0x26,0x6a,0xd1,0xc7,0x1f,0x53,0xa8,0x53,0x7a,0xdb,0x83,0xfe,0x77,0x9c,0x68,0x84,0xe4,0xbf,0xa7,0x87,0x1e,0xd1,0xd7,0x44,0xb1,0x83,0x5b,0x20,0x69,0xe3,0xc9,0x8a,0x97,0x53,0x22,0x71,0xef,0x4d,0xb4 +.byte 0x52,0x64,0x89,0x05,0x14,0x1d,0x00,0xd2,0xc4,0x89,0x46,0xc1,0xf6,0x6f,0x08,0x10,0xe8,0x51,0x7c,0xc8,0xc0,0xaa,0xc3,0xd8,0xd4,0x0d,0xfa,0x7d,0x26,0xa4,0xc8,0x33,0x32,0x62,0x64,0x01,0xa9,0x72,0x86,0x62,0xe2,0xbf,0xb3,0x71,0xbf,0x6d,0x91,0xc1,0x96,0xb1,0x57,0x4b,0x7b,0x87,0xe8,0xa2,0x58,0xc3,0x77,0x7b,0x75,0x60,0xa1,0xcf +.byte 0xe2,0xf2,0x1f,0x48,0x22,0xd0,0x35,0x91,0x68,0x16,0xdd,0x71,0x2b,0xa5,0x2f,0xa6,0x54,0x0c,0xe1,0x8e,0x8c,0xb9,0x3f,0x94,0x48,0xc7,0x2f,0xfd,0xbe,0x4a,0x29,0x8b,0xdc,0x1a,0xef,0x95,0x1e,0xdf,0xa0,0x11,0x7e,0x74,0x22,0xf1,0xaf,0x6a,0xdd,0x65,0x0f,0x38,0x87,0x83,0x9b,0x03,0x6b,0xa0,0x9d,0xbe,0x94,0x1d,0x0b,0x97,0x1f,0xcd +.byte 0x0e,0x77,0xcf,0x56,0x2e,0xd2,0xda,0xd1,0xf5,0xc7,0xc3,0x17,0x43,0xee,0x42,0xb3,0xda,0x9c,0xf5,0x39,0xe1,0x01,0x55,0x4a,0x3f,0x28,0xdb,0x5f,0x80,0x32,0xbd,0xc8,0xba,0x51,0xf6,0xc5,0x56,0x74,0x9f,0xa6,0x28,0x14,0xcc,0x6c,0x81,0xd6,0xfe,0x31,0xf6,0xae,0xeb,0x19,0x70,0xfa,0xb5,0x77,0xf9,0xfd,0x43,0x49,0xd7,0x83,0x57,0xe8 +.byte 0x81,0x03,0xa2,0x91,0x15,0xfd,0x83,0x72,0xd1,0x5a,0xdb,0xcb,0x09,0xe3,0x63,0x36,0xbb,0x64,0x47,0x70,0x65,0xf1,0x3e,0x7f,0x93,0xfb,0x00,0x47,0x64,0x1e,0xe0,0xad,0x49,0xc8,0x4d,0x95,0xb8,0xc7,0x58,0x00,0xd1,0x92,0x84,0x59,0x79,0x45,0x6f,0xfa,0x8c,0x2a,0xf8,0x25,0x77,0xa6,0x03,0x6c,0xa2,0xd6,0xfb,0xab,0xe5,0xcf,0x72,0xdd +.byte 0x2c,0xa5,0xcc,0x09,0x74,0xfa,0x18,0xe5,0x02,0xaf,0x05,0x2b,0xc1,0xb3,0x99,0x50,0xfb,0x6c,0xf4,0x35,0x6e,0xd2,0x50,0x6a,0xb2,0xa0,0x05,0x5c,0x82,0x71,0x58,0x05,0x71,0x99,0x46,0xd9,0xfd,0x1c,0xdf,0x1f,0x1f,0x8c,0xf1,0x7a,0xe1,0x92,0x08,0x52,0x4a,0x1b,0x52,0x61,0x2c,0xd0,0x2d,0xb1,0x6c,0x48,0x23,0x7f,0x0f,0x45,0x98,0x04 +.byte 0xbb,0x91,0x40,0x28,0x3c,0xf9,0x01,0xd9,0xdf,0xd9,0x0c,0x31,0xec,0x58,0xe1,0xd0,0x55,0xcb,0x4a,0xb2,0xfe,0x09,0x97,0xaa,0xbe,0x01,0xd9,0xe9,0xf3,0x76,0x48,0xd9,0x75,0x0d,0xba,0x54,0xaa,0x2e,0x99,0x0a,0xbf,0x4c,0x5b,0xae,0xf0,0x27,0xd2,0xe5,0x1c,0x9d,0x74,0xf9,0x7f,0xc6,0x88,0x7c,0xa4,0x0f,0x96,0x2c,0xe7,0xc5,0xfd,0x26 +.byte 0x59,0xe5,0xcc,0x86,0xb2,0x93,0xae,0x17,0x59,0x39,0x3b,0xa6,0xf0,0xff,0x07,0xa0,0x6e,0xff,0x39,0x01,0x71,0x50,0x5f,0x4f,0x12,0x13,0xcf,0x44,0x85,0xe6,0xd8,0x89,0x4f,0xa6,0x21,0xb2,0x32,0xbd,0x37,0x9f,0x1d,0x35,0x9d,0x30,0x49,0x7d,0x29,0x60,0x07,0xdd,0x06,0x05,0x21,0x44,0x22,0xaf,0x1d,0xc9,0xc7,0x31,0x60,0x88,0x2d,0x4d +.byte 0x71,0x88,0x4d,0x5b,0x7c,0xc6,0x68,0x09,0x54,0x01,0xc0,0xe9,0xda,0xa0,0x08,0x75,0x6f,0x3c,0xdb,0xf7,0xa4,0x1c,0x9d,0x8d,0x49,0xb6,0x30,0x38,0x22,0xe6,0x08,0xf9,0x00,0xa5,0xaa,0xf2,0x83,0xd3,0xb1,0x37,0xdb,0x2a,0xd4,0x65,0x94,0x98,0xd6,0xe1,0xc9,0xf6,0xc0,0xd1,0xbe,0x28,0x92,0x6b,0x2f,0x13,0x8d,0xc6,0x62,0x82,0xf2,0x5a +.byte 0xe1,0x62,0x74,0x08,0x72,0x28,0xa4,0xca,0x83,0x84,0x42,0xca,0xc6,0x17,0xf4,0xa7,0xf5,0x4e,0x57,0x9e,0x50,0x9c,0x9b,0x96,0x88,0x28,0x39,0xb1,0x1d,0x71,0x6d,0x6a,0x41,0x1c,0x63,0x85,0xa0,0xf6,0x38,0x3b,0x74,0x5b,0xe9,0xfa,0x67,0x63,0xd2,0x54,0x1c,0x22,0x12,0x4c,0x1d,0x56,0xf2,0x29,0x55,0xfb,0x4a,0x18,0x50,0xb3,0x2f,0xa7 +.byte 0x0f,0x53,0x9b,0x2b,0x0e,0xae,0xfc,0xda,0xfc,0xa3,0x98,0x47,0x50,0x38,0x24,0xc0,0x3d,0xd6,0x4b,0x44,0x4f,0x9e,0xdb,0x0a,0xaf,0xc7,0x2c,0xc2,0x5e,0x7e,0x97,0x21,0xa5,0x62,0x07,0x5f,0x97,0xe9,0x95,0x41,0x88,0x13,0xe9,0x53,0x6a,0xd6,0x59,0x8b,0x69,0xe2,0x02,0x1b,0x73,0x5d,0xb8,0xa6,0xd3,0x9d,0x76,0x6c,0x86,0xc5,0x73,0xf0 +.byte 0x45,0x68,0x0c,0xc1,0x5b,0x38,0x3d,0x64,0x92,0xfc,0x1a,0x2a,0x28,0x85,0x2b,0xfc,0x6a,0xf0,0x66,0x6a,0x8c,0xdc,0x7c,0xd9,0x65,0xe0,0x68,0xa2,0x36,0x0e,0x5f,0xe8,0xbe,0x16,0x6b,0x72,0xa2,0xcc,0x3e,0xef,0x1f,0xbe,0x98,0x0f,0x49,0x22,0x6a,0x5e,0xbc,0x88,0x2f,0xd6,0x54,0x7f,0xff,0xb9,0xab,0xc9,0x68,0xd7,0xd5,0x2f,0xb1,0x6b +.byte 0x65,0x26,0x7c,0xd7,0x97,0x2c,0x6a,0x15,0x15,0x88,0x95,0x54,0x55,0x7b,0x56,0xab,0x16,0x6b,0xc7,0xa9,0xa3,0xbc,0xf2,0xaa,0xc3,0xff,0x11,0xb5,0xee,0x55,0x61,0x34,0x50,0x0c,0xe1,0xec,0xa6,0x5d,0x03,0x95,0x7d,0xca,0x00,0x80,0x02,0x44,0x8a,0x00,0x9b,0x16,0x02,0x7c,0x35,0xed,0xae,0x62,0xdd,0x20,0xfc,0x99,0x82,0x58,0x85,0x94 +.byte 0x7b,0x2b,0xfb,0x7b,0xdf,0x99,0x69,0x7f,0x7e,0xf0,0x96,0xc5,0x48,0x27,0x90,0x32,0x88,0x96,0x89,0x95,0x9c,0x45,0x0e,0x90,0x94,0x54,0xa6,0x94,0x36,0xf7,0xc1,0x01,0xee,0xcb,0xfb,0x4e,0x62,0xd0,0x34,0x95,0xd6,0xb5,0xa4,0xa6,0xae,0x2b,0x0e,0x1f,0x03,0x87,0x6c,0x54,0x77,0x7d,0xf7,0x22,0xd1,0x63,0xb2,0x57,0x05,0xd1,0x8d,0xaf +.byte 0x35,0xca,0x23,0x8d,0x66,0x79,0xa0,0xed,0x9a,0x4a,0xbc,0xd8,0x20,0xe6,0x44,0x3e,0x6f,0x1d,0xf7,0xf3,0x43,0x83,0x5b,0xb6,0xdf,0x43,0x12,0xef,0x5c,0xfa,0xd5,0x8d,0x94,0x48,0xf8,0x2b,0x9b,0xfe,0xd0,0xab,0x88,0xa4,0x7d,0xa7,0xed,0x1d,0x53,0xd1,0x28,0x64,0x92,0xca,0x21,0x47,0x8b,0x2d,0xcd,0xf2,0xfb,0x1a,0xd1,0x6b,0x10,0x38 +.byte 0x8b,0x23,0xa5,0x85,0x0c,0x8f,0x2d,0x8f,0xcd,0x64,0x21,0x2d,0xc9,0x69,0xad,0xe3,0x17,0xf7,0x36,0x94,0x13,0xd1,0x8c,0x66,0x2e,0x72,0xc1,0x12,0x0b,0x52,0xce,0xb5,0x1c,0x5e,0x93,0xb5,0x80,0x5d,0x95,0xe2,0x0c,0x2f,0x08,0x92,0x47,0xb3,0x90,0x19,0x44,0x8b,0x9b,0x3b,0xb7,0xa2,0xaf,0xf7,0xfa,0x6e,0x40,0xa4,0x50,0x11,0x87,0x15 +.byte 0x75,0x75,0xad,0x55,0xa9,0x34,0xd0,0x1f,0x0f,0x76,0x79,0x55,0x5b,0x1a,0x22,0x3c,0x20,0x50,0x70,0xeb,0x2f,0x9c,0xd2,0xb0,0x16,0xd3,0xa5,0xdd,0xec,0xbf,0x69,0x29,0xdf,0xcf,0xa2,0x2c,0x73,0xa8,0xd2,0xe9,0x99,0x81,0x19,0x07,0x0a,0x3e,0x34,0x90,0x34,0x5b,0x7b,0xd6,0x5b,0x03,0xc4,0xcc,0x1a,0x68,0xb4,0x6a,0xf7,0x13,0x00,0x6c +.byte 0xbe,0xbd,0x45,0xf1,0x70,0x29,0xc9,0x59,0xfb,0x88,0xb3,0x60,0x55,0x65,0xd1,0x97,0x24,0xfe,0x5d,0xb3,0x7a,0x13,0x2a,0x32,0xe6,0x68,0x74,0x47,0x8f,0x90,0x85,0x20,0x10,0x88,0x78,0x7d,0xb5,0x20,0x21,0x05,0x8b,0xd2,0xc6,0x1e,0xbe,0xad,0xd5,0xba,0x44,0x48,0xee,0xa5,0xcd,0x9b,0xf6,0x91,0xce,0x73,0x5d,0x3d,0xa7,0x9b,0xa7,0x7f +.byte 0xbe,0xa7,0x8c,0xd1,0x76,0x23,0xa4,0xab,0xc0,0x3f,0x3b,0x35,0xce,0x3f,0xe5,0x91,0x4a,0x93,0x21,0xcd,0x74,0xea,0xc5,0x0b,0x4d,0x21,0xd0,0xf6,0x8d,0x51,0xfe,0x8d,0x7d,0xab,0xd1,0x61,0x8b,0xda,0x8b,0x66,0x58,0x52,0xc1,0x63,0xc4,0xca,0x41,0x72,0x87,0x54,0x69,0x5d,0xa8,0xcf,0x38,0x5f,0xf8,0x52,0x99,0x5f,0x5e,0x4e,0x01,0x4d +.byte 0xdf,0x53,0xe3,0xac,0x5d,0x62,0xb9,0x4e,0xea,0x73,0x1b,0x4b,0xeb,0x7d,0x9c,0x6f,0xa4,0xbf,0xba,0xee,0x31,0x55,0x85,0xed,0x5a,0x28,0x34,0xca,0x8d,0xcd,0x0d,0xe6,0xc6,0xfb,0xb1,0x4b,0x0d,0x30,0xfa,0x12,0x46,0x1e,0x4e,0x5e,0xcf,0x73,0xd1,0x49,0x58,0x69,0x6f,0x41,0xf2,0x33,0xff,0x06,0xc3,0xac,0x86,0x0d,0xd7,0x8e,0xab,0x15 +.byte 0xf7,0xa4,0xfe,0x1f,0xfd,0x48,0xa1,0x39,0x2b,0x72,0x8b,0xa3,0x49,0xb6,0xfe,0x06,0x1c,0xe3,0x39,0x0c,0xf0,0xfb,0x3e,0xd9,0x7f,0xa6,0x49,0x85,0x18,0xbc,0x37,0xc2,0xba,0xf7,0xc6,0x84,0x9b,0xeb,0x85,0xfe,0xea,0xd5,0xcd,0x0f,0x86,0x4a,0xa9,0xdc,0xfd,0x57,0x3f,0xa5,0x2a,0xc6,0x95,0xcf,0x72,0xd6,0x5b,0xca,0x39,0x2f,0x87,0x27 +.byte 0x72,0x33,0x4d,0x2a,0x53,0x83,0x02,0x96,0x0a,0x4a,0x0a,0x16,0x07,0xd6,0xb4,0xbe,0xff,0xa0,0x72,0x31,0x8b,0xc7,0x9b,0xfd,0x4b,0xdc,0x95,0x00,0x82,0x2a,0x56,0x93,0x31,0x08,0xbf,0xb5,0x6f,0xc4,0xca,0x9c,0x13,0xe8,0x57,0xc9,0x22,0xe6,0x89,0x7a,0x81,0xaa,0xf4,0x7c,0x59,0xd6,0x8c,0x71,0x78,0xeb,0x0d,0xa0,0x64,0xef,0x7a,0xcc +.byte 0xea,0x45,0xcc,0xe9,0xfc,0xf5,0x83,0x38,0x3b,0x4f,0x2e,0x47,0x13,0xb5,0xb1,0x09,0xb5,0x94,0xb4,0x74,0x31,0x77,0xc3,0xdb,0xf3,0xfe,0xfe,0x3d,0x4d,0xc6,0xfa,0x5a,0xbc,0xee,0xaa,0x5f,0x03,0x09,0xdc,0x19,0x83,0x1f,0xe3,0x81,0xca,0xb9,0x59,0x4a,0x0d,0xde,0xda,0xf1,0xd0,0x21,0x7d,0x90,0x05,0x4e,0xee,0x63,0xc3,0x20,0x20,0x1f +.byte 0x9f,0xdf,0x99,0x09,0x5f,0x61,0xab,0xbb,0x47,0xd7,0x20,0x79,0x81,0x69,0xb2,0xfe,0xb7,0xc1,0x27,0xcb,0x07,0xce,0x47,0xb6,0x32,0x8f,0x8b,0x06,0x0f,0x3c,0x34,0xe5,0x27,0xdd,0x20,0x42,0x63,0xed,0x9d,0x5f,0x36,0x31,0xf6,0xdb,0xfe,0x2c,0x50,0x9a,0x9c,0x2e,0x42,0xa1,0x1d,0x37,0xc5,0x63,0xd4,0xf6,0xc5,0x53,0xba,0x21,0x88,0x5b +.byte 0xd6,0xc1,0x10,0xaf,0x22,0x21,0xeb,0x7f,0x1b,0x65,0x2b,0x0d,0x54,0xa8,0x0d,0x29,0xdf,0xbc,0x2f,0xd0,0xc0,0xa3,0x52,0x78,0x0c,0x76,0x56,0xf1,0x1f,0x22,0xa7,0x6f,0xb7,0xf7,0xd5,0xcf,0x0c,0xd3,0xbd,0x2f,0x84,0x53,0xae,0xef,0xb1,0xa3,0x38,0x0c,0x80,0x4b,0xef,0x88,0x59,0x2d,0x1f,0x79,0x92,0xfe,0xcc,0xd1,0x75,0x33,0x59,0xde +.byte 0x74,0xd2,0xec,0x7c,0xad,0x8e,0xc7,0x8d,0xb8,0x2a,0x46,0xe0,0xa6,0xb9,0x10,0xf4,0x88,0x58,0x0e,0x68,0xba,0x31,0xaf,0x7b,0x7c,0x00,0xc5,0x9f,0x48,0x16,0x3c,0x92,0xa1,0xa2,0x02,0xf5,0xfd,0xbb,0x3f,0x85,0x9a,0x96,0xc5,0x24,0x36,0xc1,0x18,0x2e,0x85,0x27,0xa0,0xa0,0x69,0x40,0x35,0xe9,0xee,0xdc,0xbf,0x25,0xb1,0x2f,0xa8,0x30 +.byte 0x7e,0x36,0x4d,0x74,0xb8,0x73,0xf9,0xaa,0xfd,0xf7,0xb3,0x4d,0x6b,0xbb,0x1b,0x5e,0xfd,0x45,0xca,0xc3,0xa6,0xe2,0x95,0xd3,0xba,0xcb,0x63,0x2a,0x1a,0xd3,0x50,0x1c,0x73,0x6c,0xb6,0x54,0x1c,0xf5,0xf7,0x8b,0x64,0x10,0x07,0x9c,0xc9,0x2a,0xfc,0x97,0x1c,0x21,0x2d,0x80,0xe7,0x5c,0x2d,0xcc,0x4e,0x0b,0x79,0x73,0xd0,0x1b,0xfe,0x92 +.byte 0x05,0x95,0x9a,0x93,0xb5,0xbf,0x2f,0x09,0xa6,0x22,0x73,0xf9,0xb6,0x76,0xf5,0x90,0x6a,0x04,0xd2,0x5f,0xc4,0xb5,0x07,0xfc,0x46,0xf4,0xf0,0xcd,0xef,0x80,0xc7,0xf8,0x3d,0x1e,0xf5,0x85,0xfa,0xd7,0x17,0x57,0xba,0x74,0x9d,0xc2,0x73,0x6c,0xf6,0xa6,0x10,0x8d,0x03,0x82,0xee,0xbe,0xe3,0x03,0x0c,0xa5,0x68,0x20,0xf3,0x1e,0xaa,0xcc +.byte 0x2b,0x8a,0xb4,0x76,0xb5,0x97,0x0b,0xa2,0xb0,0xf1,0xa5,0xfd,0xdf,0x0b,0xc2,0xce,0x93,0x75,0x46,0x28,0x53,0xf5,0x19,0x52,0xc6,0x7f,0xbd,0x1e,0x34,0xf8,0xbb,0x11,0x25,0xab,0x0f,0xed,0xd2,0x5e,0xdf,0x67,0x60,0xec,0x3c,0x5c,0x30,0xf0,0x42,0x21,0x97,0x47,0x09,0x77,0x58,0xf6,0x50,0x72,0xd9,0xc6,0xd6,0x71,0x8c,0xf9,0xaa,0x95 +.byte 0x45,0x79,0xc6,0x5f,0xae,0xc9,0x36,0x8e,0x48,0x7a,0x56,0x94,0x97,0xed,0x0d,0x51,0xa0,0x54,0xb7,0x64,0x3d,0x3d,0x28,0x31,0x74,0xe9,0x1a,0x11,0x9a,0x5d,0x74,0x40,0x28,0x3c,0x7a,0x12,0xa8,0xbd,0x34,0x13,0xae,0x4b,0xb8,0xba,0xfb,0x84,0xee,0xd7,0x7f,0x6a,0xe4,0x2c,0x77,0xe6,0xf0,0x2f,0x94,0x32,0xd3,0xc2,0x29,0x23,0x55,0x82 +.byte 0x17,0x2f,0x69,0x42,0xd2,0x8c,0xa4,0xc9,0xfc,0x6c,0x4d,0x30,0x85,0x23,0x1d,0x63,0xd4,0xc5,0x84,0x8c,0xcb,0xcb,0x68,0xb4,0x10,0x2d,0x44,0x33,0xd2,0xeb,0x45,0x6f,0x6e,0x7f,0x39,0xf3,0xbd,0xc1,0x63,0x49,0x43,0x51,0x64,0x40,0xf8,0xba,0x94,0x0f,0x6f,0x95,0x0d,0x51,0x64,0x68,0x44,0x73,0x3b,0xfc,0x8b,0x52,0x13,0xdd,0x07,0x4f +.byte 0x73,0x97,0xf0,0x9a,0xde,0x5e,0x4b,0x6a,0xe8,0x62,0x25,0x62,0x29,0x67,0x54,0x37,0x11,0xfd,0x3a,0xa1,0xec,0xf2,0xdd,0xd2,0x09,0xb0,0x6c,0x84,0x87,0x32,0xac,0x29,0x68,0x86,0x39,0xf9,0x64,0xa9,0xb6,0xb8,0xd5,0x64,0x8f,0x9c,0xf8,0xae,0x9d,0x84,0x45,0x85,0xf8,0x29,0xba,0xfd,0xb4,0xcb,0x62,0xfd,0xaa,0xb2,0xd0,0x17,0xf0,0x86 +.byte 0x92,0xbe,0x69,0x18,0xfa,0x56,0x94,0xbe,0x0f,0xa5,0x47,0x9c,0x6f,0x54,0xe4,0xa8,0x86,0x6a,0xf7,0x16,0x1d,0xd2,0xbd,0x8b,0xb2,0x03,0x01,0x23,0xa4,0x2b,0x91,0x8f,0x30,0xe7,0xc3,0x2a,0xbd,0x82,0xdd,0x2c,0x60,0xb8,0x9f,0x3f,0x03,0x91,0x47,0x37,0x8c,0x1e,0x83,0x23,0x4b,0xe9,0x17,0xf9,0xca,0x86,0x95,0xbe,0x21,0x2a,0x69,0x66 +.byte 0x7a,0x2f,0x7f,0xba,0x73,0xa7,0xc3,0xb9,0x6f,0x77,0x5d,0xa9,0x97,0x82,0xff,0xba,0x37,0x72,0xee,0x52,0xe5,0x27,0xeb,0x5e,0xf3,0x88,0x0a,0x29,0xe1,0x7e,0xec,0x2a,0xf2,0xce,0xbd,0x3e,0x55,0x5c,0x22,0x29,0xce,0x35,0x68,0x68,0x12,0x5f,0x0d,0x8f,0x4c,0xa5,0xde,0x49,0xc9,0xb7,0x52,0x85,0x1f,0x81,0x42,0x65,0x4d,0x24,0xf8,0xe9 +.byte 0x71,0x0f,0x37,0xdc,0xff,0x2f,0x07,0xf3,0x4c,0x15,0x66,0x24,0xf7,0xeb,0x13,0x25,0x24,0x33,0x47,0xbb,0x3e,0x45,0x31,0x61,0x6a,0x30,0x44,0xe2,0x43,0x2c,0xf1,0x46,0x1c,0x08,0x71,0x70,0xeb,0xa3,0xd1,0x03,0xcb,0x45,0x02,0xe8,0x46,0x5c,0x25,0x25,0x75,0x8f,0x0a,0x89,0x30,0x2e,0xbe,0x48,0xb4,0xb2,0x89,0xa2,0x56,0x87,0x32,0x19 +.byte 0x85,0xe5,0x5c,0x69,0x6d,0xee,0xaf,0x64,0x22,0x93,0xe4,0x61,0x84,0xaf,0x36,0xee,0x4c,0xae,0x26,0x37,0xda,0x6b,0x78,0x64,0x2c,0x1b,0x9a,0xd2,0x8f,0x40,0xb9,0xf1,0xd0,0xbd,0xd6,0x67,0x16,0x42,0x2b,0xc0,0xfd,0x77,0x9a,0x69,0x69,0x44,0xbf,0x2c,0xfb,0x81,0xf0,0x96,0x29,0x31,0x35,0xae,0x8b,0x87,0x22,0x2a,0xa7,0x56,0xc8,0x85 +.byte 0xd4,0xc8,0x32,0x3b,0xab,0x15,0x98,0x55,0xe3,0x13,0x77,0xd4,0x1b,0xa3,0xeb,0x89,0xe3,0x16,0xc4,0x0d,0xa8,0xde,0x54,0x0b,0x63,0xc5,0x77,0x1d,0x1a,0x0d,0xfb,0x15,0xb3,0x83,0x94,0xab,0x7a,0x7d,0xf3,0xf5,0xd5,0x4f,0x83,0xa2,0xf5,0xd9,0x09,0xa5,0xa7,0xb2,0x79,0xc4,0xbb,0xaf,0x66,0x09,0xd2,0xcd,0x05,0xe8,0xf3,0xcf,0xcc,0xd8 +.byte 0x40,0xdb,0x9e,0xc3,0xb4,0xf0,0x1e,0x08,0x0d,0x41,0x75,0xae,0x7c,0x6e,0x19,0x1a,0xf9,0x27,0x6c,0x86,0xc6,0x97,0x99,0xc6,0xc0,0x39,0xbb,0xee,0x85,0x49,0xb8,0x29,0xef,0x3b,0xa4,0x35,0x68,0x4b,0x85,0xaa,0xfd,0xa1,0x5f,0x60,0x9b,0xee,0xca,0x09,0xd2,0xc4,0xe7,0x03,0xd2,0x29,0x78,0x56,0xd0,0x24,0x1e,0xf7,0x57,0x80,0x91,0x0c +.byte 0x09,0xe8,0x03,0x36,0xaf,0x57,0xc5,0x94,0x04,0x13,0xa7,0x44,0x33,0x4e,0x27,0xe4,0xf0,0x05,0xb9,0xab,0x68,0x7d,0x4a,0x67,0x18,0x8f,0xdd,0x57,0x7b,0x83,0xb3,0x48,0x36,0x8a,0xbe,0x88,0xd8,0x86,0xe1,0x51,0x09,0x7e,0xd8,0x83,0x68,0x06,0x1a,0x4a,0x49,0x97,0x89,0x5b,0xc5,0x41,0x59,0xfc,0xb9,0xdc,0x3f,0x09,0x90,0x9d,0x94,0x86 +.byte 0xd8,0xcd,0x07,0x46,0x8c,0xb5,0x73,0xd1,0x0b,0x5f,0x67,0x71,0x6f,0xf5,0xc2,0xbd,0x9f,0x7b,0xcb,0x0d,0x7f,0x9c,0xc3,0x92,0xb6,0x23,0xd8,0x84,0xea,0x7f,0xba,0xd6,0x6c,0x3e,0x79,0x8b,0x9f,0x96,0xda,0x9d,0x6f,0x3b,0x05,0x33,0x83,0xf2,0x0a,0x6d,0xac,0x7c,0xce,0xa5,0xc7,0x62,0x43,0x24,0x02,0x79,0x0a,0xad,0x92,0xe8,0x5b,0x36 +.byte 0x4e,0x66,0xd6,0x1d,0x09,0x40,0x6f,0x3f,0x0e,0xb3,0x6c,0x9f,0x78,0x77,0xc0,0x78,0x59,0x93,0x70,0xa7,0xf9,0x16,0xf2,0x0b,0x53,0x96,0x89,0x4b,0x1e,0x32,0xbb,0x53,0x29,0xf8,0x55,0x46,0xa1,0x29,0x01,0x34,0x52,0xd1,0xc9,0x8f,0xb4,0x4a,0x49,0x5f,0x46,0x97,0x49,0xf4,0xd5,0x60,0xc7,0x78,0x14,0xde,0x5c,0x8e,0x8f,0xcf,0x28,0xee +.byte 0x8b,0x82,0x71,0xdc,0xbb,0x7c,0x3d,0xda,0x0f,0x01,0x31,0x74,0x9d,0x84,0xca,0x57,0x2b,0x5f,0x2a,0x02,0x52,0x9d,0xb1,0x26,0x7d,0xc3,0x58,0xc6,0x6c,0x8e,0xf2,0x2f,0x10,0x48,0xdf,0x7c,0xd3,0xdb,0x01,0x6d,0x45,0xe4,0xc2,0x62,0xfe,0x60,0x26,0x39,0xd6,0x29,0xe0,0x51,0xfd,0x1f,0xf0,0xd2,0x3f,0xc7,0xc8,0x65,0x14,0xa1,0xb0,0xe8 +.byte 0x36,0x61,0x0e,0x11,0xa3,0x37,0x48,0xa8,0xa9,0x35,0xb7,0x38,0x71,0xbe,0xd3,0xb0,0x8a,0xb2,0x96,0x13,0xb3,0xe0,0x44,0xa9,0xd4,0x8a,0x46,0x58,0xa7,0xf4,0x90,0xee,0xde,0x57,0x96,0xaf,0xeb,0x4c,0xd0,0x1b,0xed,0xe4,0xd1,0x8b,0x2e,0xd4,0x93,0xb3,0xc9,0x01,0x36,0xdc,0xdb,0x6d,0x23,0xfb,0xa1,0xdc,0xe8,0x2c,0x9e,0x49,0xaf,0x42 +.byte 0x14,0xf1,0xbb,0xf8,0x44,0x85,0x2a,0x0d,0x28,0xe1,0x6e,0x30,0xb6,0x50,0xbf,0x77,0x77,0x8e,0x3c,0x67,0xb7,0x3a,0x0c,0x45,0x6b,0x6c,0x6c,0x9c,0x3e,0x5b,0xe6,0x9e,0x1c,0xbd,0xd2,0x46,0x72,0xe8,0xb4,0x52,0x7f,0x1e,0xea,0x6c,0x24,0x48,0xc7,0x7c,0xb5,0x78,0xf5,0x6a,0x18,0xaf,0xe0,0xa5,0xb3,0x55,0xd6,0x3f,0xf2,0x6c,0xaf,0x6c +.byte 0x30,0x80,0x1f,0x57,0xe0,0xd3,0x6d,0xf6,0xb2,0xf8,0x9f,0x7a,0xcd,0x18,0xd8,0x3d,0x01,0x60,0x26,0x7f,0xdb,0xdd,0x86,0x42,0x1c,0xe7,0x65,0x86,0xe3,0x02,0x60,0x12,0x21,0x0d,0x4c,0x07,0xc0,0xdc,0xb7,0xb7,0x05,0x1e,0xca,0xe7,0x40,0x70,0x63,0xc4,0xa6,0x1c,0x27,0xcf,0x03,0xe8,0xba,0x07,0xd3,0xa1,0x8e,0xf5,0x27,0xc2,0xaa,0x89 +.byte 0xdd,0x36,0x46,0x39,0xaf,0x60,0xdd,0x99,0x7f,0x42,0xb1,0xfd,0x7d,0xe5,0x1e,0x5a,0x6b,0x97,0xa9,0xfc,0x58,0xcd,0xac,0x63,0x23,0x66,0xe8,0xf7,0x5e,0x41,0x6b,0x2b,0x77,0xf3,0xf1,0xa7,0x3b,0xa4,0xbc,0xe9,0x0a,0x80,0x57,0x2b,0x62,0xb9,0x02,0x26,0xa9,0xfa,0xb5,0xd5,0x2d,0x5e,0x19,0x77,0x63,0xcd,0x7f,0x4d,0xdf,0x71,0x5e,0x2d +.byte 0xce,0xfd,0x45,0x99,0x8c,0x46,0xc2,0x9d,0x89,0x3e,0xd0,0xac,0x39,0x0f,0x15,0x6b,0xfc,0x99,0x24,0x8c,0xcf,0xf9,0x55,0xf8,0x79,0xb3,0x8e,0xa9,0xf8,0xb6,0x81,0x49,0xda,0x95,0xda,0xce,0xdd,0x5f,0x94,0xb8,0x24,0x41,0xae,0xf3,0xc2,0x7c,0x6b,0xb8,0x7a,0xb9,0x0c,0xb2,0x34,0x2b,0x0e,0x90,0xc8,0x69,0xc3,0xd1,0x53,0x83,0x70,0xc2 +.byte 0x6f,0x72,0x3a,0x1a,0xd4,0x68,0x0d,0x8d,0xff,0xa4,0xc5,0xd4,0x04,0xd6,0xca,0x18,0x04,0x7d,0xd1,0xc5,0x02,0xae,0x58,0x07,0x22,0x30,0xf3,0x7e,0xd4,0x3c,0x04,0x61,0xc4,0x24,0xee,0x0e,0x8d,0x48,0x7a,0xc7,0x28,0xe7,0x33,0xed,0x3a,0xe9,0x52,0x52,0x13,0x7e,0x89,0xe3,0x2b,0x5e,0xe3,0x28,0x7b,0x8f,0x87,0x80,0xc8,0x9c,0x4c,0x13 +.byte 0x7a,0x2d,0xcd,0x68,0x60,0xcd,0xea,0x27,0x45,0x25,0xef,0x43,0xe7,0x65,0xc9,0xb4,0x81,0xeb,0xbc,0x71,0x0b,0xcf,0xbf,0xcf,0x6a,0xa8,0x70,0x4f,0x92,0xf4,0x8b,0xa2,0x82,0x8d,0x5c,0x73,0xdb,0x1f,0x9b,0xe3,0x81,0xe0,0x07,0x28,0x51,0x77,0x41,0xee,0x83,0xc5,0xcc,0x35,0x07,0x9a,0x20,0x13,0x2c,0x55,0x7c,0x97,0xc0,0xda,0x1e,0x41 +.byte 0x56,0x80,0x15,0x26,0x10,0x66,0x12,0xdc,0x82,0xdd,0x1a,0x3f,0xd2,0x72,0xe4,0x80,0xd7,0x47,0x2a,0xa9,0x50,0xa4,0xa4,0xf1,0x6c,0xbe,0x6e,0x69,0x61,0x46,0xae,0x17,0x72,0x96,0xc8,0xcb,0x1c,0x89,0x0b,0x9e,0x0c,0x24,0x90,0x93,0xf6,0xf6,0x9c,0x5c,0x0b,0xeb,0x39,0xde,0xa7,0x64,0x88,0x18,0xc3,0x32,0x92,0xd5,0x06,0x6d,0x88,0xfd +.byte 0xd0,0x99,0xe2,0x65,0x23,0xc3,0x24,0x16,0x2d,0x56,0x47,0x96,0x1c,0x8a,0x09,0xbf,0x23,0x1e,0x36,0x12,0x3b,0xba,0xac,0x13,0xf4,0x82,0xb2,0x0f,0xb4,0x73,0xf8,0x1e,0x96,0xaa,0x5a,0x31,0x48,0x70,0x4e,0x5a,0xf1,0x9b,0xf7,0xf5,0xd3,0x88,0xdd,0x35,0x7c,0xbe,0x85,0x62,0x8d,0x5d,0xc8,0x52,0x41,0x8a,0x24,0xe1,0xae,0x02,0xbe,0x4d +.byte 0xe6,0x15,0x70,0x43,0xed,0x01,0xcb,0xa7,0xf0,0x31,0x10,0x0c,0xc0,0x25,0x02,0x74,0xa9,0x2e,0x34,0xbd,0x77,0xd5,0x00,0x89,0x24,0xa4,0x30,0x36,0x52,0xe9,0x51,0x47,0xe8,0x79,0xe3,0x7a,0x2e,0xe6,0x43,0x6b,0xa4,0x48,0xd7,0x3f,0x75,0x6c,0x64,0x4f,0xc7,0xf9,0x90,0x17,0x8f,0xbc,0x52,0x67,0x34,0x16,0xad,0x35,0x64,0x2c,0xa0,0xf0 +.byte 0x67,0x4e,0x2b,0xf8,0x27,0xe0,0xa4,0x4a,0xba,0xe5,0xcb,0x17,0xd9,0x9f,0xc6,0x64,0x68,0xf4,0xe0,0xfc,0x0c,0x5c,0x3b,0xc7,0xc4,0xc0,0x88,0xa5,0x23,0xf3,0x48,0x7a,0x7e,0xa5,0x10,0x97,0x61,0xa2,0x45,0xf5,0xe8,0xe6,0xe9,0x48,0x25,0x78,0xcb,0x6b,0x42,0x5f,0x18,0x26,0xb3,0xb7,0xb1,0x34,0x57,0xf1,0xbc,0x13,0x7a,0xb4,0x01,0xda +.byte 0x9f,0x72,0x91,0xb3,0x4d,0x27,0xff,0x90,0x22,0x5c,0xb2,0xef,0xef,0xd6,0x9c,0x41,0xf3,0x29,0x8d,0x92,0xd9,0x03,0xbe,0x24,0x64,0x99,0xb0,0x8f,0xbb,0x85,0xd2,0x2c,0xda,0x9b,0xb1,0x81,0x52,0x5a,0x0b,0xdf,0x8d,0x70,0x94,0xec,0x72,0x2e,0x58,0x0a,0x38,0x78,0xa1,0x51,0x8a,0x72,0xaf,0x49,0x6e,0xdf,0x8d,0xbc,0xce,0xd2,0xab,0x13 +.byte 0x57,0x50,0x40,0xad,0xb8,0x3a,0x17,0x1c,0x61,0xb8,0x06,0xd3,0x2f,0x46,0xa6,0x57,0x4f,0x3a,0xe5,0xcb,0x96,0x48,0x37,0x9e,0xd9,0xb4,0x12,0xb3,0x15,0x10,0xe4,0x4a,0x36,0x6e,0xc5,0x4a,0xd8,0x6a,0xcb,0x96,0xfd,0xef,0xdd,0x1a,0xdb,0x80,0x92,0x93,0x5a,0xc4,0x2a,0x7b,0xe3,0x2d,0x6f,0x83,0x3e,0x50,0xb7,0x66,0xc5,0x66,0xca,0x42 +.byte 0x97,0x6e,0x32,0x81,0x31,0x18,0xb9,0xc5,0xfa,0xae,0xb8,0xdd,0x5c,0x91,0xa1,0xc6,0x69,0xa5,0x2a,0xe0,0x1f,0xa4,0xaf,0x0d,0x92,0x4e,0x12,0x60,0xe1,0x0f,0x92,0xcb,0x78,0x49,0xbc,0xcf,0x64,0x4c,0xd8,0xa0,0x2b,0x70,0x7c,0x8b,0xa6,0x64,0x97,0x1b,0x22,0x22,0x3c,0x82,0x8d,0x08,0xfa,0xc4,0x8c,0x18,0xe3,0x1b,0xe9,0xd0,0xd9,0x10 +.byte 0xca,0x9b,0x53,0x9c,0x3a,0xe2,0x1e,0xa8,0x00,0x4d,0xe1,0x58,0x55,0x6c,0xd9,0x88,0xda,0xb8,0x3c,0xbe,0x3c,0x65,0xfa,0x4d,0xdd,0x0b,0xde,0xf4,0xaf,0x50,0x9c,0xe4,0xa5,0xae,0xe3,0xc2,0x1a,0x53,0xfb,0x32,0xff,0x7e,0xf0,0x29,0x0c,0xac,0xa2,0xf5,0x68,0xc8,0xd8,0x04,0x7b,0x5f,0xe3,0xe0,0x57,0x0d,0x9e,0xcd,0x58,0xda,0x2a,0x44 +.byte 0x49,0x3b,0x1d,0xd9,0x75,0x6b,0x41,0xf7,0xe6,0x7e,0x0c,0x49,0x20,0xc0,0xb5,0x67,0xdf,0xc4,0x28,0xcf,0x21,0x0b,0xa0,0x8e,0xde,0xff,0x5c,0x9f,0x34,0xdf,0xab,0xb9,0x70,0xa0,0xfd,0x80,0x54,0xb6,0xaf,0xc9,0xc4,0x10,0x5c,0x0a,0xc8,0xe1,0x91,0x5d,0xfc,0x24,0xab,0x12,0xdc,0x48,0x45,0xd5,0xc4,0x95,0xbb,0xe0,0x83,0x3a,0x5d,0xb7 +.byte 0x8c,0xf1,0xf0,0xc6,0x56,0xed,0x3c,0x31,0x79,0xf2,0x75,0x81,0x3f,0xf0,0x4a,0x3f,0x44,0x99,0xdb,0x9a,0x48,0x44,0xaa,0x4c,0xff,0xea,0xfd,0xc0,0xd3,0xaf,0x46,0xad,0xd2,0x96,0xc5,0x6b,0xd7,0x2b,0x39,0xe5,0xef,0xc6,0xa6,0xe9,0x37,0x5a,0x25,0x0f,0x00,0x05,0x09,0x30,0xbd,0xb0,0x16,0x9f,0x1e,0x15,0x62,0x20,0xd1,0x01,0x4f,0xb7 +.byte 0x20,0xb8,0xd2,0x6b,0x2b,0x18,0x66,0x45,0xac,0xad,0x33,0x14,0x4a,0x7f,0x74,0x8b,0xfa,0xa6,0x20,0xef,0x2e,0xd7,0xf6,0x84,0x03,0xb8,0x20,0x76,0x01,0x2b,0x20,0xf9,0x17,0x59,0xc4,0x09,0xe1,0x8b,0x43,0xf1,0x32,0xf2,0xc9,0xe8,0x00,0x37,0x77,0x10,0xd0,0x4d,0x89,0xc4,0x69,0x14,0x24,0xf6,0x30,0xc2,0xfb,0xcc,0x6c,0x6c,0x1d,0xdb +.byte 0x7c,0xd7,0x32,0x1f,0x54,0x1b,0x50,0x39,0x2a,0xd3,0xb4,0x5e,0x0f,0xff,0x7a,0x04,0x5b,0xeb,0xf1,0xcb,0xea,0x5c,0xab,0xaa,0x73,0xb7,0x43,0xe5,0xf1,0xdc,0xc7,0xe4,0xb6,0x53,0x04,0xa5,0xb4,0xb2,0xf5,0xc6,0x93,0xa5,0x24,0x67,0xf3,0xd4,0xbb,0x3d,0x24,0xa2,0x30,0x4c,0x35,0x38,0x9c,0x5b,0x4b,0xba,0xfd,0x69,0x25,0xca,0xff,0x1a +.byte 0xf6,0xc1,0x9b,0xd4,0xd7,0x29,0x9e,0x1c,0x57,0xb5,0x7e,0xa8,0x23,0x0b,0x8f,0x54,0x12,0x36,0x07,0x83,0x15,0xde,0x08,0x17,0xf2,0x65,0xb2,0x36,0xa3,0x55,0x6b,0x2d,0x0b,0xc2,0xf9,0x7a,0xab,0x39,0x9e,0x24,0x31,0x94,0x31,0x21,0xe2,0x1c,0x46,0x69,0x07,0x15,0xd3,0x42,0x42,0x7a,0x60,0x75,0x7e,0x48,0x46,0xc8,0xa5,0xee,0x3f,0xea +.byte 0x97,0x5d,0xb1,0x80,0xbe,0x03,0x29,0xb5,0xf5,0xde,0xae,0xdb,0xf2,0x83,0x7f,0xc1,0x7f,0xb5,0xd5,0xb5,0x18,0x64,0xec,0x90,0xab,0x48,0xed,0xfb,0x75,0x30,0x13,0x2c,0x56,0xbc,0x2c,0xc3,0xc4,0x9d,0xf4,0x50,0xaa,0x08,0x59,0x9a,0x4b,0xc1,0x78,0x8f,0xe9,0xd4,0x3b,0x14,0x48,0x67,0x3e,0x78,0xf5,0xc8,0xba,0xbf,0x92,0xf3,0x23,0x94 +.byte 0x35,0x7b,0x0a,0x7d,0xdd,0x21,0xde,0x9d,0x36,0xed,0xb1,0x72,0x0a,0x3a,0x93,0xc7,0x66,0x91,0xf6,0xc1,0xe0,0xf3,0x53,0x5f,0xb5,0xfb,0xa2,0xb7,0x91,0x06,0xf3,0xba,0xb7,0xf9,0x41,0x58,0xc6,0x4b,0x8e,0x63,0x35,0xd1,0xb5,0x6d,0x86,0x3e,0xd9,0x66,0xe1,0x1c,0xb7,0x02,0xc9,0x19,0x82,0xaa,0xda,0x04,0xce,0xe0,0xd0,0xa4,0x7a,0xd3 +.byte 0xa2,0x3b,0x18,0x5b,0xfc,0x63,0xea,0xf5,0x8e,0xbb,0x57,0x9e,0x7c,0xe6,0x14,0x03,0xf7,0xe0,0xfe,0xf8,0xee,0x47,0x2a,0x3d,0x71,0x4b,0xe4,0x22,0x88,0x2f,0x7c,0x97,0x9c,0xb7,0x89,0x64,0xc4,0xc9,0xe9,0xa3,0xbd,0xbd,0xa4,0x73,0x98,0xd5,0x48,0x9f,0x2f,0x46,0x1a,0xc6,0xa1,0xce,0x84,0xb6,0x0a,0xb2,0xcb,0xbb,0xde,0x56,0xc3,0x1f +.byte 0x81,0x07,0x08,0xc3,0x50,0xd8,0xcf,0xe8,0x17,0x79,0x4d,0x82,0x09,0x90,0x8b,0xde,0xdb,0x71,0x49,0xb9,0xb0,0x6a,0x82,0x22,0x78,0xbc,0xcf,0x48,0x94,0x76,0xa1,0x6f,0x31,0xe9,0x8a,0x33,0xac,0x6b,0x9e,0xc4,0xa0,0x12,0x9c,0x38,0x82,0xe1,0x70,0xac,0xc8,0x2a,0x2b,0x13,0x87,0xf2,0xc1,0xd3,0xc4,0x5b,0x77,0x37,0x82,0x28,0x4a,0xa1 +.byte 0x7a,0x39,0xff,0x8a,0xdd,0x38,0x74,0xb0,0x88,0x83,0x71,0xe5,0x25,0xaf,0x04,0x19,0x99,0x1c,0x8d,0xa0,0x57,0x96,0x36,0xd5,0x28,0x83,0x30,0xd5,0x12,0x78,0x74,0x9f,0x9c,0xbf,0xee,0x68,0x95,0xec,0x56,0x67,0x77,0x54,0x35,0xb3,0xce,0xcf,0x29,0x2f,0xcf,0xec,0x14,0xa1,0x58,0x67,0x95,0xdd,0xc9,0x29,0xe4,0x0a,0xce,0x72,0x9a,0x5f +.byte 0x3d,0x21,0x96,0x0f,0xf3,0x97,0x3a,0x60,0x82,0x1d,0xc5,0xbd,0x45,0x9a,0xe5,0x45,0x71,0x92,0xa3,0x3d,0xb3,0x13,0xf4,0x2a,0x71,0xcd,0x4f,0x70,0xbc,0x16,0x8c,0x35,0xcd,0xaf,0xf9,0x98,0xef,0xa7,0xc4,0x36,0x4e,0x65,0x89,0xaa,0xfc,0x9b,0x58,0x51,0x63,0x8e,0xd3,0x22,0x5b,0xf2,0x5d,0x13,0x6f,0xc8,0xa8,0x67,0x9c,0x8f,0x34,0xfd +.byte 0xfe,0xf5,0xb7,0x84,0xcb,0x87,0x3d,0xb5,0x24,0xb8,0x19,0xa7,0x00,0x03,0x6d,0xc6,0x4f,0x1f,0xb9,0x57,0xff,0xdc,0x65,0xa4,0xe9,0x8e,0xc3,0x6b,0xfa,0x57,0x51,0x3d,0xf0,0x07,0x95,0xaa,0x00,0x31,0xdc,0x08,0x21,0xa1,0x73,0x9c,0xc9,0x46,0x3f,0xf4,0x0f,0xfd,0xec,0xcd,0xf2,0x76,0x73,0xa6,0xc2,0x15,0xeb,0x9b,0x9d,0xfb,0x6e,0xe5 +.byte 0xe2,0x6e,0xaa,0x1a,0x30,0x82,0x02,0xad,0x56,0x67,0x3f,0x50,0x76,0x2f,0x04,0x4f,0x79,0xd5,0xfd,0x50,0x39,0xc1,0xe1,0xd5,0x1d,0x6f,0xb8,0x15,0x25,0xa6,0x4c,0x97,0x90,0x93,0x0f,0x34,0x46,0xda,0x99,0x2f,0x0e,0x4e,0xf7,0x09,0x2d,0x30,0xa7,0x74,0x95,0x8c,0x84,0x69,0x60,0x93,0x17,0x66,0xa3,0xff,0x4b,0xed,0xc7,0x5b,0x16,0x51 +.byte 0x6a,0x39,0xc4,0x7f,0xd8,0x48,0x92,0xbd,0xc3,0x58,0xfd,0x87,0x8e,0x34,0xac,0xcc,0x2a,0xbb,0x40,0xd5,0x80,0x57,0x12,0x89,0x56,0x77,0x64,0xe3,0xf9,0x25,0x7d,0xd6,0xfe,0xd2,0xeb,0x9d,0x6c,0x20,0x12,0x7f,0xa4,0x19,0x45,0x27,0x36,0x22,0x3b,0x4c,0x1f,0x45,0xab,0x95,0xad,0xed,0x53,0xd8,0xce,0x84,0xde,0xbe,0xb7,0x93,0x6a,0x05 +.byte 0x09,0xe4,0x57,0x38,0xb1,0xa9,0x7a,0x34,0x3e,0x43,0x03,0xa6,0xdb,0x60,0x15,0xdf,0x6f,0x26,0xf1,0x41,0xf2,0x83,0x1b,0xc9,0x15,0xf3,0xab,0xfa,0x33,0x19,0x87,0xac,0x55,0x7b,0xb6,0xbd,0x0a,0xbc,0xa5,0x08,0xfa,0xf4,0x7e,0x89,0x49,0x06,0x21,0x6c,0x44,0x27,0xf5,0x7c,0x46,0x6e,0x95,0x50,0x93,0x81,0xae,0xef,0x93,0x50,0x1c,0x4e +.byte 0x7e,0x8c,0x3c,0xf4,0x41,0xbd,0x4a,0xfa,0x11,0x2e,0xed,0x6f,0x84,0x94,0xe1,0x0e,0xe4,0x5b,0x1f,0x0d,0xe0,0x2b,0xa1,0xa2,0xf8,0xa2,0x56,0x3b,0x52,0x41,0xf9,0x0a,0xe4,0x5b,0x82,0xa6,0xaa,0xd6,0x09,0x18,0x14,0x7a,0x36,0x66,0x01,0x47,0x7c,0x20,0xc6,0xf0,0xb3,0x24,0x29,0xb3,0x03,0x54,0x74,0x7d,0xee,0x28,0x6e,0xd8,0x4a,0x1a +.byte 0x02,0x1d,0x86,0x11,0x16,0x4b,0x0f,0x92,0x31,0x6e,0x7b,0x8b,0x47,0x73,0xd8,0x46,0xf6,0x7b,0x82,0xfe,0xcd,0xe8,0x01,0x49,0x32,0xb7,0xa3,0xf1,0xc0,0xb9,0x0a,0x86,0xf7,0x6d,0xee,0xf3,0xed,0x66,0x8a,0x35,0x73,0xfb,0xb7,0xfd,0xff,0x0d,0xd1,0xd5,0x1b,0x4e,0x59,0x1a,0x84,0x0f,0x73,0x9c,0xfd,0x36,0xb0,0x81,0x79,0xec,0x46,0x94 +.byte 0x32,0x1f,0x7a,0x98,0x1f,0xc7,0x99,0xc9,0x1d,0x54,0x8b,0xda,0x80,0x7a,0x38,0x38,0x8f,0x9e,0x2a,0xfc,0x24,0x2b,0x58,0x17,0xa6,0x2c,0x31,0x37,0xcd,0x14,0xb5,0x67,0xcb,0xdc,0x59,0x9b,0xd2,0x77,0x31,0xa1,0x6d,0xbe,0x09,0xd2,0x12,0x34,0x70,0x81,0xb0,0x19,0xbf,0xd6,0xb2,0x63,0x75,0xc1,0x1b,0xaa,0x8c,0xdc,0x59,0x79,0x12,0x5d +.byte 0x20,0x43,0xd8,0x1a,0x03,0x87,0xb3,0x8f,0x52,0x0b,0xdc,0x69,0xa5,0xf2,0x19,0x07,0x6d,0xe2,0xfd,0x52,0xc9,0x7b,0x9a,0x37,0x48,0x1b,0xb1,0xd2,0x6b,0xd9,0x4e,0x6c,0xfd,0xc1,0x94,0xf2,0x36,0x21,0x89,0x5e,0x89,0x5e,0x87,0x09,0xa1,0x9b,0x6b,0x67,0xd1,0xde,0x85,0x2f,0xd5,0x6c,0x19,0x78,0xe7,0x61,0xd3,0x53,0x6e,0xb5,0x1c,0x23 +.byte 0x5e,0x4d,0x32,0x73,0x25,0xa6,0x29,0xa2,0xb9,0x1b,0xc0,0x07,0x54,0x38,0x17,0xdf,0xc0,0xcc,0xb1,0x47,0xb9,0x07,0x1d,0xbd,0x8f,0x97,0xab,0x3f,0x7f,0x5b,0xff,0x34,0x01,0x3a,0x2c,0x6a,0x15,0x1d,0x77,0x36,0x32,0x55,0xf5,0x5c,0x84,0xfc,0xd6,0x54,0x22,0xfb,0x6a,0xce,0xb2,0x62,0x03,0x7f,0x96,0xf6,0x37,0xce,0xcc,0x08,0xcf,0x68 +.byte 0x66,0x42,0x27,0x80,0x27,0x99,0x3d,0xbd,0xf8,0x60,0x4e,0x49,0x06,0x8a,0xd2,0x6b,0x1d,0x80,0xe0,0xfe,0xe4,0x2a,0x75,0x8e,0xd1,0xdf,0x26,0x69,0x55,0xe5,0xbb,0xa8,0xf3,0x3d,0xdd,0x54,0x90,0x90,0xd8,0x5d,0x86,0x9c,0xdc,0x41,0x71,0xac,0xd4,0x48,0x8f,0x15,0xc6,0xca,0x7e,0x03,0x95,0x81,0x56,0xdb,0xb6,0xe5,0x27,0xb3,0x60,0x51 +.byte 0x93,0x21,0x9a,0x68,0x1e,0xb2,0x5c,0xf8,0xf1,0xdd,0x19,0x02,0xaa,0x5f,0x16,0xaa,0x13,0xa6,0xe7,0xcf,0xfb,0x7c,0xd4,0xe7,0x55,0x8a,0x5d,0xf3,0xec,0x3d,0xca,0xf8,0x34,0x32,0xaa,0xd8,0x47,0x11,0x25,0xe4,0xf1,0xbd,0x7a,0x1d,0xe9,0xa3,0xce,0x2e,0x44,0xe1,0xa4,0xbe,0x70,0x68,0x49,0xa4,0x14,0x7b,0xde,0xa6,0x9e,0xe1,0x32,0x01 +.byte 0xb3,0xed,0xc4,0x15,0x0c,0x84,0xb1,0xd4,0xef,0xa5,0xbc,0x2e,0xc8,0x79,0x6b,0xf1,0xf8,0x61,0xae,0x55,0xa3,0xd5,0x0e,0xf5,0xc0,0xb8,0x9c,0xdf,0x7f,0x12,0x19,0xc2,0x73,0x22,0xc2,0xc5,0x77,0x76,0xb0,0x36,0xe5,0x89,0x7e,0x5a,0x4a,0xb4,0xa0,0x4d,0x8e,0x1b,0xbe,0x52,0xd1,0xf5,0x3b,0x84,0xf8,0x44,0x76,0x26,0xbb,0x31,0x38,0xd1 +.byte 0x24,0xa7,0xb7,0xb5,0xcb,0xa6,0xa7,0x9c,0x15,0xeb,0x31,0x57,0x93,0x3f,0x1c,0x48,0xe9,0x3b,0x20,0x21,0x46,0xe9,0xe2,0xe1,0xd3,0xf4,0xd9,0xcb,0xe7,0xa1,0xa9,0x75,0x7e,0x70,0x95,0x33,0x43,0x86,0xb2,0xd1,0x01,0x8e,0xcb,0xb5,0x1c,0xc5,0xe8,0xcb,0xec,0x1d,0xf2,0xd1,0xe9,0x3b,0xf0,0x8f,0x1a,0x30,0x79,0x83,0x31,0xd6,0x29,0x18 +.byte 0xe7,0x80,0xaf,0xd3,0x1d,0x48,0x59,0x14,0x1e,0x94,0x4f,0x32,0xaa,0x8c,0x40,0x37,0xad,0xed,0x30,0xe3,0x5a,0xc5,0x2c,0xdf,0xf5,0xa4,0xcc,0x52,0xdb,0x48,0x90,0xc3,0xbb,0xff,0x65,0x9b,0x86,0xec,0x06,0xac,0xec,0x3c,0x67,0xdc,0x82,0x57,0xb5,0xd4,0x19,0x19,0x68,0x73,0xad,0xd7,0xa9,0x9c,0x3f,0x8e,0xe8,0x7c,0x92,0x4c,0x66,0xbe +.byte 0xe1,0xa6,0x9c,0x1c,0x85,0xcc,0xcf,0xfa,0x86,0xeb,0x34,0xe5,0xf1,0x14,0x09,0xa7,0xde,0xf5,0x2f,0xc0,0xc9,0xb4,0xab,0x92,0x8f,0x76,0xf0,0x78,0x02,0x8d,0x8d,0x44,0x3c,0x2c,0x57,0xfe,0x40,0xb5,0xd2,0xea,0x67,0x1c,0x30,0xb4,0x75,0xbb,0xeb,0xd4,0xf7,0x53,0x0a,0x09,0x29,0x0c,0x02,0x40,0x4b,0x22,0x98,0xe7,0x70,0xa7,0x6b,0xcf +.byte 0xf3,0xa1,0xed,0x50,0xec,0xbb,0xbc,0x24,0x48,0x20,0x03,0x64,0xac,0x03,0xf7,0x9a,0xb5,0x8e,0x16,0xee,0x36,0xb1,0xa7,0x82,0xf4,0x21,0x77,0x79,0xa8,0x07,0x57,0xb4,0xb5,0x59,0x84,0x62,0x29,0xcd,0xb4,0xb8,0x78,0x3c,0x20,0x96,0xe5,0x43,0x8f,0x21,0x38,0xff,0x32,0xa5,0x4f,0x23,0x4b,0xf4,0x5d,0x96,0xc4,0x74,0xe4,0xc1,0x9e,0x72 +.byte 0xb1,0x37,0x2a,0x7c,0xa7,0xd1,0xa9,0xf0,0x9e,0x90,0xdd,0xfa,0x3b,0x47,0x7d,0x31,0x08,0x7a,0xbd,0xe7,0x0b,0x0c,0x78,0x92,0x85,0xb4,0x7f,0x33,0xe0,0x7c,0x14,0x92,0x3f,0x3b,0x2e,0x6a,0x61,0x4a,0x81,0xf1,0x76,0x53,0x1f,0x24,0x95,0xe7,0xc2,0xd0,0x7d,0xb4,0x3c,0x59,0x85,0x55,0x0b,0x46,0xd0,0xc3,0x0b,0x0c,0xe1,0x34,0xd9,0x67 +.byte 0xfc,0x6b,0x98,0x67,0xdb,0x24,0x08,0xd3,0x15,0x9d,0xb5,0x31,0x22,0x7e,0xe7,0x77,0x7c,0x7e,0x49,0x48,0x6c,0x3e,0xd5,0xda,0x4f,0x46,0x94,0xf9,0x59,0x5d,0xb6,0x4e,0xec,0x76,0xfe,0x5e,0x10,0x63,0x92,0x89,0x3e,0x56,0x18,0x94,0x6c,0xac,0xc1,0x2d,0xba,0xf4,0x1f,0xd4,0x09,0xa0,0x00,0x39,0x8f,0x9e,0xfb,0x63,0xa0,0x34,0x71,0x23 +.byte 0xdf,0xaf,0x0d,0x88,0x75,0x37,0x92,0xd0,0x17,0xcb,0x20,0xad,0x94,0xa9,0x94,0x9f,0xce,0x1c,0x19,0xe2,0xdb,0x36,0xe0,0xa6,0x68,0xa4,0x1d,0x16,0xb6,0x16,0xb2,0xf4,0xe4,0x3e,0xfc,0x3b,0xda,0x10,0x57,0xc9,0x81,0x58,0x28,0x43,0xf8,0x45,0x38,0x5c,0xb1,0xd6,0x54,0x16,0x45,0x36,0x46,0xe2,0x60,0xa5,0x47,0x9a,0x29,0x85,0x54,0x45 +.byte 0xdc,0x1a,0x63,0xe6,0xae,0x3b,0xdf,0xa9,0xd4,0x10,0x63,0x19,0x91,0x81,0x8e,0x90,0xb4,0x1f,0x25,0x5a,0x46,0xff,0x41,0x1e,0x25,0x1f,0x98,0xb5,0x69,0x2b,0x5e,0x5d,0x7d,0x0a,0x27,0x13,0x3f,0x70,0xe8,0xae,0xa1,0x89,0xb7,0x4a,0x5c,0xef,0x03,0x08,0x7f,0x66,0xa4,0xa7,0x6a,0x27,0x27,0xfc,0x8c,0xe4,0x61,0x8e,0x9e,0x19,0x6d,0x98 +.byte 0x2f,0xd0,0x31,0xdf,0xb5,0x86,0xa5,0x23,0xe0,0x82,0x8c,0x26,0xf7,0x96,0x7f,0xca,0xab,0xba,0xcb,0x54,0x5e,0x05,0x9a,0x0a,0x75,0xbe,0xbf,0x25,0x80,0x18,0xac,0xd8,0x4e,0x9c,0xd3,0xb7,0x34,0x73,0xfa,0x73,0x17,0x89,0xc7,0xe2,0x94,0x59,0xc1,0xca,0x78,0x48,0x6d,0x63,0x2c,0xce,0x70,0x90,0x6a,0xbd,0x6b,0xb8,0xaa,0xac,0x5f,0x09 +.byte 0xf3,0x96,0xac,0x07,0xe0,0x12,0xdc,0xf7,0x12,0x61,0xa7,0x9d,0x7c,0x7b,0x63,0x02,0x59,0x43,0xd4,0xcb,0xa4,0x32,0x7e,0x3e,0x27,0xf5,0x37,0xf5,0x75,0x35,0xc4,0x17,0xa4,0x98,0xae,0x04,0xe8,0x28,0x18,0x84,0xf1,0x57,0xff,0x1a,0xa8,0xaa,0x31,0xc2,0x5f,0xd9,0x38,0x11,0xdc,0x49,0x59,0x28,0x8a,0x43,0x04,0xd2,0x83,0x96,0x66,0xe3 +.byte 0x26,0x56,0x5e,0x4a,0x8f,0x11,0xcc,0x30,0xd4,0x11,0x52,0xdf,0x95,0x46,0xb6,0x8a,0x9a,0x80,0xa5,0x9f,0xae,0xeb,0x06,0x38,0x14,0x7d,0x6a,0x25,0x7b,0xf8,0xf8,0xa1,0x2e,0xeb,0x84,0xc3,0x25,0x63,0xa4,0xe4,0xf8,0x9b,0x4b,0xfb,0xb1,0xb4,0x18,0x54,0xfa,0x74,0xc5,0x5a,0x59,0x79,0xf5,0x19,0x2a,0x51,0x4c,0xe0,0x30,0xe5,0x43,0x71 +.byte 0xda,0x37,0xb3,0xca,0x1c,0x6f,0xa3,0xf5,0xa1,0xd9,0x6c,0xaa,0xca,0xb5,0xae,0x9f,0x51,0xef,0x17,0xc3,0xaa,0x4c,0xe1,0x3b,0x2a,0x61,0x85,0xdf,0xb4,0x6b,0x18,0x9f,0x1e,0x0d,0x4a,0xe6,0xaf,0x72,0x4a,0xa0,0xad,0x5b,0x44,0xf5,0xa4,0x00,0x91,0x4a,0x33,0xf8,0x8d,0x83,0x51,0x83,0x6b,0x1d,0xca,0xcd,0x94,0x04,0x0b,0x5f,0x3d,0x60 +.byte 0x26,0xbf,0x9f,0xa5,0xac,0xaf,0x66,0x5c,0x2a,0x37,0xa6,0xfc,0x11,0x1b,0xa6,0x8b,0x02,0xe5,0x4e,0x0f,0x1f,0x7a,0x0d,0x49,0x22,0xb9,0x66,0x97,0xbd,0xee,0x82,0xc7,0x78,0xba,0x77,0x50,0x54,0x68,0xf6,0xc8,0xc9,0x73,0x82,0x93,0x1f,0xfe,0x6b,0x49,0x9b,0x63,0xad,0x6c,0xaa,0x78,0x07,0x9f,0xda,0x11,0xb2,0x36,0xb7,0xcb,0xea,0x27 +.byte 0x83,0x66,0xa3,0x20,0x20,0xf8,0x29,0x56,0xb8,0xcf,0x93,0xcd,0x40,0x94,0x94,0xef,0x3e,0xda,0x3d,0x4e,0xff,0xef,0xea,0x29,0xc3,0xd2,0x6e,0x2d,0x74,0x27,0xe4,0x31,0xd0,0xcb,0x76,0x48,0xf2,0x9b,0xf7,0x59,0x95,0x15,0x33,0xc1,0x2f,0x88,0xf3,0xa8,0xdf,0xc9,0x86,0xcf,0x37,0xf1,0x08,0xb9,0x76,0xe6,0x09,0x48,0x44,0x25,0x9b,0x98 +.byte 0xbe,0xab,0x20,0xa1,0x21,0xe9,0xf9,0x9b,0x31,0xf1,0xfd,0x49,0xaa,0xb5,0xf0,0xbf,0xec,0x8d,0x1c,0xf4,0xaa,0xa9,0x23,0xe5,0x0c,0x1b,0xd7,0xad,0xbd,0x97,0x16,0xdf,0x4f,0x7a,0xd4,0x68,0xd6,0xc2,0xba,0x92,0x17,0x5c,0x80,0xf6,0x4a,0xf1,0x26,0x50,0x58,0xd0,0x11,0xed,0x98,0x55,0x75,0x44,0xb2,0xb5,0x96,0x22,0xe6,0x4f,0xc8,0xba +.byte 0x97,0x3a,0x3e,0xce,0xc5,0x8c,0xf2,0x8c,0xf1,0x91,0xb6,0xb3,0xcd,0xae,0x2c,0x80,0x2a,0x15,0x7e,0x65,0x28,0x35,0x50,0xae,0x36,0x03,0x8b,0x38,0x8f,0x51,0x20,0x8d,0x38,0x19,0x68,0x6e,0x25,0x28,0xd7,0x2c,0x74,0x7f,0xac,0xa8,0x02,0xed,0x01,0x08,0x01,0x1a,0xc4,0x7d,0x18,0x6c,0xf5,0xce,0x25,0xea,0x1f,0xdc,0x85,0xf2,0x8c,0x56 +.byte 0x60,0xe6,0x5c,0x5f,0x08,0x2c,0x43,0xe2,0x53,0x5c,0xd0,0xa7,0x78,0xec,0x2a,0x75,0xb4,0x18,0x4f,0x80,0x19,0xca,0x30,0x13,0x67,0xcd,0x73,0xba,0xf9,0xba,0x54,0x39,0x0b,0x4b,0x03,0x7d,0xfd,0x21,0xac,0x14,0x54,0x56,0xba,0x6f,0x0b,0x59,0xbf,0x52,0x19,0xb2,0xb7,0x18,0x57,0xaa,0xaa,0xb2,0x07,0x6b,0xf7,0x13,0x37,0xe1,0xff,0x5a +.byte 0x1d,0x54,0xdf,0xf0,0x57,0xb4,0x14,0x93,0x03,0x31,0xe3,0xaa,0x53,0xa5,0x8e,0x39,0xbc,0x17,0x83,0xd1,0xc3,0x4d,0x5f,0x8d,0xa0,0x08,0x09,0xf2,0xde,0x5b,0x47,0x72,0xad,0x9f,0x22,0x59,0x8d,0x7c,0x8f,0x4b,0x78,0xd2,0x35,0x49,0x34,0x23,0x89,0xa4,0xa1,0x15,0xb0,0xed,0xc0,0x60,0x53,0x68,0xf6,0x3b,0x35,0xca,0x75,0xf6,0x04,0xde +.byte 0x2f,0x0c,0x8c,0xd8,0x75,0xd1,0x7c,0xa1,0x62,0x6b,0x2c,0x2d,0x10,0x1b,0x38,0x81,0x10,0x82,0xcb,0xb8,0x75,0xfa,0x3f,0xfd,0x41,0xd5,0x6d,0x88,0x12,0x5e,0xc5,0x23,0xb3,0x8e,0x37,0x01,0xd9,0xee,0x25,0x32,0xda,0x3c,0x3b,0x50,0xa7,0xef,0xe3,0xac,0xfd,0x50,0x4e,0x55,0x94,0x2d,0xcc,0x41,0x07,0x6e,0x3f,0x8f,0x1a,0x21,0x4d,0x79 +.byte 0x42,0x1c,0x8e,0x23,0x4c,0x43,0x02,0x5c,0xf8,0x59,0xc8,0x88,0x64,0x93,0x30,0x25,0xf7,0xea,0xeb,0x2c,0xe5,0x10,0x47,0x36,0xd8,0x32,0xe7,0xf3,0x5e,0x1b,0xcc,0x78,0xda,0xe7,0xc9,0xb6,0xf9,0x24,0x50,0x5a,0x6c,0xfb,0x30,0xc7,0x25,0xa4,0x54,0xdb,0xdc,0xc7,0xf3,0x64,0x9f,0x79,0xc5,0x6c,0xef,0xa2,0x12,0xb3,0x18,0xff,0x97,0xe8 +.byte 0x79,0xaa,0x33,0xf1,0xb2,0x69,0x48,0x61,0x71,0x4c,0x8b,0x87,0x50,0x00,0xc1,0x90,0xc4,0x16,0x2a,0x52,0xca,0xf3,0x30,0x51,0xd0,0x8b,0x19,0x46,0x1c,0xb1,0xa3,0x56,0x8a,0x18,0xd8,0x04,0x9f,0x4d,0x3e,0xd7,0xcb,0x15,0x07,0x08,0x45,0x29,0x0d,0xf1,0x94,0x35,0xea,0xc2,0x89,0x0d,0x32,0x01,0x53,0xe3,0x8b,0xba,0xbf,0x39,0x36,0xe4 +.byte 0x3a,0x9b,0x0b,0x8f,0x3b,0xbd,0x15,0x47,0x81,0x68,0x99,0xc3,0x40,0xc4,0xad,0x44,0x8f,0x02,0xe8,0x77,0x32,0x4d,0x8e,0xfe,0xf3,0xa0,0x95,0xef,0x8b,0x1b,0xd6,0xbc,0xac,0xe5,0x2b,0x05,0x5d,0xcd,0x1f,0xe6,0xac,0x80,0x62,0x91,0x54,0x6c,0x6f,0xcc,0xab,0x09,0x83,0x1d,0xcc,0xf2,0x40,0x91,0xc1,0x6b,0x41,0x19,0x33,0x36,0x8b,0x81 +.byte 0xfb,0x97,0x2b,0x6f,0x28,0xc7,0xc2,0x69,0x7e,0x36,0x60,0x5d,0x89,0x8c,0xee,0xe0,0x0a,0xbf,0x38,0x6e,0xc4,0x9b,0xe4,0x93,0x33,0x96,0x80,0xf4,0x56,0x00,0xf4,0xa5,0xe5,0x29,0x04,0x13,0x83,0x0d,0x5d,0xcb,0x6a,0x09,0x90,0xc9,0xb4,0xe9,0xa4,0x13,0x3a,0x0e,0x64,0x18,0x2d,0x33,0x19,0x67,0x5f,0x89,0xd1,0x86,0x3d,0x8f,0x9d,0xb3 +.byte 0x0c,0x7b,0x90,0x6e,0x9a,0x09,0xa2,0xb6,0x8a,0xc6,0x03,0x16,0xcf,0xe7,0xe0,0xe3,0x29,0xad,0x59,0x29,0x78,0xdd,0x26,0xcd,0x32,0xd7,0xb4,0x43,0xb8,0x18,0xa9,0x8f,0x79,0xe8,0xbc,0xe1,0x4d,0x16,0xa5,0x09,0x88,0x5c,0x37,0x50,0x88,0xee,0xcd,0x35,0x0d,0xd4,0xe4,0x14,0xd0,0x1b,0x9b,0x1f,0xd7,0x44,0x36,0x9a,0xe8,0x82,0x5b,0xb3 +.byte 0xb3,0xea,0xcf,0x05,0x78,0xd8,0x94,0xd4,0x63,0x7f,0x45,0x0e,0xb2,0x96,0x7b,0x97,0xf0,0xde,0x85,0x2a,0x70,0xc3,0xb1,0x17,0xd2,0xf0,0x3a,0xb7,0xde,0xa5,0x5f,0xbc,0xda,0xa5,0x93,0xd2,0xd8,0x2c,0x74,0xd3,0xad,0x25,0xbd,0xda,0x80,0xd9,0x13,0xff,0x07,0x3f,0x56,0xa7,0x27,0x72,0x45,0xa9,0x06,0x44,0x3f,0x28,0xc4,0xb6,0x20,0x9d +.byte 0xcd,0xb7,0xba,0x53,0xbc,0xe0,0xb6,0x91,0x8b,0x9d,0x2b,0x3d,0x0a,0x35,0xdb,0x9f,0xed,0x47,0x29,0x54,0xc1,0xbf,0x33,0xc2,0x69,0x0f,0x5b,0x7d,0xa1,0xe8,0x8b,0xd0,0x4f,0x69,0xf1,0x32,0x68,0x2a,0x2a,0x83,0xd0,0xe9,0xe3,0x73,0xbd,0xcd,0x6e,0x5c,0x33,0xab,0xf0,0xed,0xc3,0xf4,0x03,0xa2,0x8c,0xb8,0x53,0x91,0xb5,0x79,0x7a,0xfb +.byte 0xc4,0x99,0xb8,0x06,0xf1,0xdf,0x4e,0x65,0xf2,0x0c,0xc6,0xd2,0x3f,0xe6,0xc2,0x4c,0xb3,0xfd,0xa8,0x24,0x27,0x5c,0xae,0x16,0xf1,0x99,0x12,0x8b,0xc9,0xf0,0x96,0xb2,0xcf,0x13,0x92,0x62,0xfb,0xf6,0x66,0xf4,0x87,0x1a,0x8b,0x09,0x4c,0xac,0x1b,0x6b,0x8b,0xa8,0x9d,0x14,0x36,0x90,0xe1,0xdc,0x6e,0x14,0x2e,0xa0,0x81,0xeb,0xd9,0x2c +.byte 0xe0,0x2d,0x83,0x99,0x91,0xe5,0x79,0xca,0x61,0xfb,0x44,0x8e,0x63,0x52,0x85,0x27,0x1a,0x2e,0x63,0x34,0xdb,0x96,0xe7,0x39,0x0d,0x7e,0x64,0xc8,0x71,0x65,0xe0,0xb5,0x4a,0x03,0xe1,0x05,0xf0,0x23,0xf9,0x0a,0xc1,0xcb,0x8b,0x6f,0xee,0x47,0x99,0x63,0xac,0xb6,0x7b,0x12,0x68,0x45,0x8d,0x51,0x03,0xfa,0x3e,0x18,0xed,0xba,0x35,0x3a +.byte 0xd7,0x6d,0x32,0xca,0x04,0x04,0x24,0xba,0x95,0x52,0x97,0x35,0x91,0x1c,0x9f,0xf2,0x83,0x4d,0xe3,0x3f,0xcd,0x71,0xf8,0xc2,0xe0,0xbe,0xcb,0x32,0x1e,0xa3,0x00,0xf6,0x53,0x9d,0x22,0x33,0xb1,0x4c,0x2a,0x9f,0x03,0x98,0xba,0x72,0x63,0x6b,0xa3,0x3a,0xe4,0x27,0xc6,0xec,0xfb,0x6a,0x35,0xae,0x56,0x7e,0xf2,0x26,0x43,0xad,0x04,0x26 +.byte 0xc8,0xcd,0x3b,0xa7,0xf4,0xab,0xb4,0x8c,0xc3,0xde,0xd8,0xce,0x51,0xa8,0x35,0xc9,0x87,0x68,0x72,0x35,0xb7,0x87,0x37,0xe2,0x7f,0x02,0x06,0xce,0x32,0x0f,0xe7,0x7b,0x5f,0x41,0x58,0x6f,0xe6,0xef,0xd8,0x4f,0x45,0x9f,0x92,0xe2,0x8a,0x37,0xd0,0xdd,0xe5,0xa9,0x56,0x41,0xc2,0xea,0x93,0xfc,0x9f,0xfb,0x42,0x73,0x8b,0x9e,0xd4,0x4b +.byte 0xb4,0x3b,0x30,0x33,0x36,0x50,0x7a,0x0a,0xdd,0x9c,0x65,0x78,0x8f,0xb4,0x91,0x9f,0xc3,0x90,0x4b,0x7a,0xed,0x8a,0xe2,0xe6,0x63,0x8b,0x51,0x1d,0x3d,0xef,0x62,0x27,0x21,0xaa,0xc4,0x7a,0xc1,0xea,0x66,0xed,0xb6,0x73,0x4a,0x6e,0x0c,0xec,0xae,0xf7,0xd5,0x3e,0x63,0xb3,0xbc,0x04,0x3e,0x9e,0xa8,0x27,0xa4,0xb1,0x48,0x5b,0x56,0x0a +.byte 0x9d,0xfb,0xdb,0xd1,0x08,0x10,0xa5,0x46,0x80,0x03,0x7c,0x23,0x94,0x06,0x71,0xd0,0x47,0x45,0xe5,0x83,0x7f,0x06,0x94,0xdc,0xcb,0x0e,0xd0,0xd1,0xfb,0x04,0xa3,0x0c,0x30,0x07,0x37,0xc0,0x1d,0x90,0x6f,0xbc,0x71,0x4a,0xce,0x2d,0x9e,0x8c,0x2f,0x98,0x2c,0x31,0x73,0x67,0x68,0xdf,0x01,0xaa,0x49,0x40,0xfc,0x71,0xfd,0xbd,0x67,0xdf +.byte 0x6c,0xe6,0x37,0x64,0x88,0x8f,0x05,0x04,0x59,0x0c,0x16,0x4e,0x6f,0x0c,0xff,0x11,0xcb,0xac,0x9d,0x42,0xb7,0xfc,0xf4,0xda,0x77,0xdf,0x62,0xe7,0x80,0x9d,0x37,0x50,0x86,0x16,0xb2,0xf3,0x86,0x8f,0x04,0xe0,0xb7,0x2b,0x2d,0x82,0x9a,0xe5,0x34,0x31,0x9a,0x77,0x63,0x60,0x7a,0xfe,0x5b,0x9b,0x32,0xf9,0x4d,0x66,0x5e,0x01,0x05,0xd4 +.byte 0xc1,0x74,0xb5,0x41,0x3d,0x0c,0xab,0x98,0xdf,0xdd,0x42,0x62,0x78,0xb2,0x42,0x20,0x66,0x19,0x9e,0x83,0x9c,0xbf,0x32,0x4d,0x96,0x78,0x56,0x9b,0xa0,0xb6,0xce,0x67,0x3a,0xfc,0x34,0x92,0x39,0xe3,0x8f,0x8a,0x8a,0x81,0x1d,0x5b,0xf7,0xfb,0x15,0xba,0x2b,0x2e,0x20,0x3b,0x82,0xfb,0x59,0x90,0xb7,0x2f,0xd4,0x60,0x79,0x58,0x64,0xee +.byte 0xb8,0xcd,0x4e,0x1c,0xac,0x58,0x43,0xce,0x5c,0xc9,0xe7,0xce,0xb1,0xc8,0x78,0x85,0x19,0x02,0x5d,0x86,0x1b,0xed,0x0b,0x7a,0x27,0x24,0xc2,0x90,0xae,0x5e,0x66,0xad,0x3b,0xc6,0xb5,0xe4,0xaf,0xc5,0xf2,0x0d,0x87,0x63,0x7a,0xcd,0x32,0x77,0x24,0xf8,0x67,0x84,0xbb,0xc1,0x09,0xf1,0x1c,0x41,0x7b,0x4d,0xb3,0x6e,0x58,0x02,0xf0,0x2d +.byte 0x09,0x78,0x4b,0x86,0xd3,0xb2,0x3a,0x52,0x15,0x86,0xde,0x47,0xb0,0x85,0x1e,0x01,0xe8,0xe8,0xeb,0x71,0x96,0x23,0x4a,0xb9,0x32,0xc6,0x51,0x93,0x5d,0x60,0x40,0x5e,0xb8,0xb4,0x85,0x6b,0x0c,0xe6,0xfb,0x02,0x16,0xd8,0x4b,0xaf,0x7f,0xa2,0x48,0x0c,0x43,0x55,0x5a,0x9a,0xd0,0x24,0x88,0xbe,0xcf,0x97,0x4b,0x79,0xf3,0x7a,0xb8,0x3a +.byte 0x6d,0xcd,0x8d,0x84,0x72,0xd7,0xd8,0xb4,0x54,0x68,0xa9,0x3d,0x72,0x53,0x51,0x42,0xca,0x11,0x2e,0xc8,0xe1,0xce,0x40,0x65,0x3e,0x5f,0x34,0x37,0xa3,0xee,0x2d,0x8a,0x68,0xcb,0xf0,0x96,0xc9,0x34,0xe3,0x5b,0x5c,0x4b,0xd6,0x48,0xdb,0x0c,0x79,0xbb,0x26,0xe4,0xa5,0x60,0x5a,0x21,0xec,0x2a,0x2d,0x64,0xe8,0xef,0xd9,0x9d,0x6e,0x9c +.byte 0xdf,0xfe,0xbc,0x40,0x2d,0x6f,0xfe,0x55,0x7a,0x51,0x43,0x87,0xc8,0x03,0xd7,0x23,0x4f,0xf0,0xb9,0x31,0x70,0x9b,0xdb,0xf8,0x6c,0xad,0x45,0xe8,0x81,0x25,0x72,0x5d,0x6e,0xc1,0x68,0x9d,0xd7,0x5a,0x94,0xe3,0xab,0xa1,0x37,0x71,0xcb,0x2a,0x70,0x86,0x73,0x8b,0x52,0x1f,0x2d,0xe7,0xd3,0xc1,0xdd,0x7d,0x3a,0x32,0x0f,0x0c,0x0e,0x1f +.byte 0xd9,0xfb,0x11,0xbe,0x40,0x17,0x89,0x8f,0x24,0x23,0x19,0xa0,0x53,0x7d,0x90,0x6e,0xfb,0x11,0xfa,0xc7,0x05,0x02,0xca,0x42,0xcf,0x00,0x58,0xeb,0xfb,0x4d,0xe7,0x8a,0x75,0x84,0x41,0x50,0xf8,0x5d,0x47,0x23,0x45,0x45,0x2e,0x77,0x47,0xc4,0x59,0x6f,0x91,0x98,0xbc,0xdf,0x91,0xef,0x2a,0x7a,0xe7,0x48,0x02,0xc6,0x4d,0x4b,0x21,0xe6 +.byte 0xc8,0xcf,0x50,0x6a,0xe5,0xa4,0x6f,0x76,0x6f,0xb2,0xbe,0xb8,0x26,0xe8,0xea,0x8e,0x4e,0xf3,0xcc,0x09,0x29,0x5b,0x5a,0x4e,0xa0,0x0c,0x95,0xf2,0xf8,0x8d,0x07,0xa0,0x85,0x1d,0x2c,0x15,0x94,0xa6,0xdc,0x80,0x40,0x4a,0x95,0xfd,0x24,0x02,0x6b,0xf1,0xfc,0x55,0x51,0x45,0x5e,0x45,0x53,0x9c,0x45,0x84,0x7c,0x90,0xeb,0x84,0xf8,0x04 +.byte 0x07,0x86,0x75,0x74,0x88,0xd8,0x2a,0x43,0xd2,0x55,0xda,0xfe,0x78,0xb0,0xc5,0xd1,0x18,0x71,0x20,0x6a,0xc2,0x74,0xc5,0x17,0x1d,0x03,0xa4,0x2f,0x2c,0xba,0xbd,0xdf,0xd0,0x24,0x83,0xbb,0x75,0xa9,0xd4,0xb3,0xc7,0x1e,0xb2,0x20,0x6b,0xe7,0x66,0x41,0x1c,0x1f,0xc5,0xa5,0x00,0x97,0x49,0x55,0xe2,0xde,0x6b,0x90,0x9d,0x1e,0xb6,0x7d +.byte 0x42,0x9e,0x2d,0x76,0xa3,0x78,0x3a,0x46,0x96,0x99,0x25,0xb9,0x30,0xdb,0xe9,0x17,0xce,0x26,0x0e,0x90,0x5c,0x25,0x74,0xeb,0x0e,0xf4,0x7d,0x22,0x66,0xcd,0x48,0xe6,0x2e,0xa6,0xbd,0xff,0x46,0x19,0xb4,0x6d,0x6f,0xe1,0xc5,0x8b,0x18,0x13,0xde,0x22,0x9b,0xe2,0x98,0x97,0x4c,0xde,0x93,0xf4,0x3d,0xe8,0x8d,0xe5,0x0f,0x0d,0x8b,0xe9 +.byte 0x1a,0x5a,0xf4,0x32,0x5e,0xad,0x54,0xd2,0x4a,0xd5,0x15,0xb0,0xdc,0xdf,0xb1,0x5f,0xde,0x76,0x3b,0x10,0x2f,0x47,0xc4,0xd4,0x7c,0x8b,0x57,0xf9,0xf2,0x15,0x97,0x25,0x8b,0x59,0x92,0x78,0xb0,0x55,0x2a,0x98,0xfc,0x31,0x73,0x71,0xd4,0xe4,0x5b,0x05,0xf7,0xd1,0xc0,0x4c,0xb4,0x3c,0x4c,0xe2,0x1d,0xd0,0xa4,0x46,0x62,0x1e,0x8a,0x06 +.byte 0xba,0xe4,0x89,0x40,0x1c,0x91,0x4a,0x30,0xdb,0x2b,0x51,0x2b,0x28,0x4d,0x06,0xa6,0xd7,0x0c,0xb9,0xc7,0xdc,0x8d,0xea,0x4e,0x89,0xae,0x3d,0x98,0xb6,0x39,0x9a,0x46,0x74,0xac,0xd1,0x88,0xe5,0x86,0xa7,0x6e,0x7d,0x5c,0x0a,0xfc,0x77,0x3f,0xba,0xd4,0xef,0x51,0x93,0x4b,0x24,0xe5,0x57,0xd2,0xdd,0xdc,0x04,0x4e,0x4a,0xa0,0xe8,0x8d +.byte 0x40,0x11,0xcc,0x8b,0xaa,0x6d,0x26,0x68,0xb2,0x60,0x0c,0x7e,0x2d,0xd8,0x5a,0x56,0xaa,0x81,0xbe,0x7d,0x1e,0xb7,0x9b,0xe0,0x1f,0x8a,0xd7,0xd3,0xe8,0x5a,0xa9,0x21,0x5c,0x75,0xa0,0x6a,0x12,0x35,0xa3,0x60,0xb0,0x5a,0x04,0xe5,0xb3,0x11,0xf3,0xb8,0x52,0x8b,0xab,0xff,0x1b,0xf8,0x51,0xd9,0x81,0xef,0xb8,0x66,0x16,0xed,0xd5,0x72 +.byte 0x6d,0xf6,0x9b,0x03,0x3d,0x7c,0xc2,0xdf,0x00,0x13,0x24,0xb9,0x05,0xad,0x31,0x3c,0x0e,0x53,0x25,0xdb,0x86,0xbd,0xd9,0x0a,0xdd,0x0f,0x33,0x96,0x6a,0x72,0xd0,0x47,0xb2,0xee,0x1d,0xa4,0x92,0x3d,0xd8,0x33,0xed,0x2f,0xca,0xa1,0x9b,0x51,0xdd,0xbf,0x3f,0xfc,0x4b,0x6b,0xfe,0xd9,0xde,0x3a,0xa7,0x9b,0x3b,0xfb,0x94,0xc9,0xea,0x25 +.byte 0xc6,0x24,0xd1,0xe3,0x47,0x89,0xc7,0x12,0xd1,0x7c,0xc6,0x10,0x3a,0xaf,0xb6,0x68,0x11,0xef,0x1a,0x16,0xd8,0xd9,0x9f,0x48,0xbb,0xba,0x44,0x97,0x69,0x34,0xf1,0xf0,0x7c,0xe0,0x27,0x59,0x2b,0x8a,0x2d,0x69,0xca,0xdb,0xae,0x07,0x21,0xbe,0xb6,0xa7,0xc1,0xbb,0xe6,0x07,0xdc,0x46,0x46,0x77,0xe2,0x98,0x1c,0xf8,0x73,0xdf,0xd9,0x93 +.byte 0x52,0x70,0x09,0xf8,0xcc,0x2e,0x5e,0xff,0x87,0x0c,0xc6,0x9e,0x90,0x4b,0xfa,0x2b,0x49,0xb6,0xe6,0xb8,0xcb,0xfd,0xec,0x21,0xd6,0x04,0x9f,0xe4,0x90,0x11,0xa4,0x9c,0xd3,0x29,0xf6,0x9b,0x01,0xd3,0x7c,0xbc,0x00,0xb0,0x38,0x08,0x70,0x7c,0x6a,0x13,0xa7,0x2b,0x5f,0xd2,0x1f,0xf0,0x7b,0x9f,0xd6,0x48,0x43,0x66,0x6a,0x7e,0x9f,0x44 +.byte 0x1c,0x63,0xdd,0xeb,0xd5,0x4e,0xdd,0x7d,0x47,0x36,0x93,0xe2,0xdb,0x93,0x26,0x35,0x47,0x4a,0x25,0x51,0x19,0xce,0xcb,0xbb,0x31,0x90,0xbf,0xe5,0x94,0xb5,0x06,0x95,0xe5,0x88,0xbd,0x0a,0x65,0x8f,0x5c,0x1a,0x78,0x9c,0xd4,0xfd,0xd3,0xc4,0xb2,0xde,0x90,0x06,0xb1,0x34,0x81,0x65,0xb3,0xfc,0xeb,0x2b,0x76,0x1e,0xac,0x88,0xec,0x42 +.byte 0xf7,0xf4,0xbb,0x1a,0x21,0xee,0x68,0xd8,0x4e,0x02,0x54,0xae,0x49,0x66,0x83,0x2a,0xb3,0x8d,0x5f,0xfb,0xca,0x13,0x3b,0xaa,0xd8,0x3b,0x16,0x44,0xe8,0xb8,0xc0,0xdc,0x58,0xbf,0xe3,0x01,0xe2,0xae,0x45,0x9d,0xbf,0xfe,0x2e,0x7d,0xaa,0xee,0xbc,0xd8,0x9b,0x73,0xf9,0x01,0x0f,0x32,0x45,0x51,0x4b,0x60,0xfa,0xd4,0xdb,0x75,0x2d,0xbc +.byte 0x95,0x1c,0x74,0xd5,0x24,0x56,0x38,0x7e,0x4e,0xab,0x05,0xe8,0x98,0xfb,0xe2,0x1e,0x53,0xef,0xbb,0x8f,0xef,0x07,0xcf,0xcc,0xf5,0xb9,0x0c,0xca,0xaf,0xe1,0x89,0xfe,0x72,0xf2,0xe9,0x11,0x7a,0x8a,0x9f,0x2c,0x60,0x55,0x25,0xe7,0x82,0x64,0xe6,0x75,0xa4,0xdd,0x49,0x05,0xd2,0x04,0xd4,0x4b,0xdc,0xb2,0xa8,0x62,0x7b,0x51,0xf1,0xdf +.byte 0xd4,0xa6,0x3d,0xb4,0x19,0xf5,0x2a,0x19,0x77,0x0c,0x11,0x46,0x82,0x9d,0x19,0xa6,0xfc,0x17,0xff,0x77,0x3f,0x61,0xe5,0x91,0x51,0x2d,0x57,0x70,0x51,0xc0,0x09,0xfd,0x31,0x43,0x76,0x22,0x89,0xc4,0x77,0x8f,0x63,0x5d,0x9e,0xe8,0xe9,0x17,0x52,0x05,0x5c,0x16,0x2b,0x24,0x83,0xe1,0xb1,0x2f,0x78,0x45,0x16,0x80,0x92,0x62,0x0e,0x1a +.byte 0x6f,0x78,0xb4,0xb7,0x1b,0x0a,0x2c,0xf4,0x9d,0xb0,0xda,0x32,0x88,0xc4,0x0c,0x2e,0xdc,0xfa,0x3d,0x54,0x2c,0x74,0x4e,0x14,0xa6,0x3d,0x39,0x2c,0x6d,0x44,0x71,0x51,0xb0,0xc0,0x7a,0xff,0x26,0x07,0x09,0xad,0x2c,0x1e,0x0a,0xb9,0xe3,0xdd,0x1d,0x76,0x66,0x57,0x38,0xa1,0xcc,0xe7,0x2d,0xe8,0xf5,0x8c,0x1e,0xa3,0xc6,0x4b,0x07,0x8b +.byte 0xda,0x95,0x50,0x5d,0xac,0xac,0xb2,0xf7,0xd2,0x42,0xe2,0x4d,0xbb,0x72,0x55,0x94,0xf9,0xff,0x3d,0xfd,0x9a,0x52,0xc3,0x32,0x76,0xdc,0x63,0xb1,0x19,0xdc,0xd8,0x32,0xc4,0x85,0xb5,0x29,0x5d,0x27,0x8d,0x93,0xa3,0x29,0xcb,0x3d,0x93,0x39,0x3d,0x81,0x98,0xde,0x47,0x97,0x0c,0xe6,0xd8,0x1c,0xa0,0x87,0xe0,0x4e,0x03,0x21,0x6a,0x1b +.byte 0x64,0x22,0xa3,0x25,0x4c,0xe0,0xd9,0xd0,0x37,0x94,0x3b,0x2b,0xd2,0x07,0x6c,0xaa,0x32,0x3b,0x09,0xde,0x38,0xbf,0xc8,0x63,0x0c,0x5d,0xf2,0x31,0x3a,0x40,0xcb,0xca,0xc2,0xe1,0x11,0x01,0x75,0x85,0x9d,0x0e,0x72,0xcc,0x3b,0x70,0xa5,0xd7,0xdd,0xa1,0xb9,0xf3,0x8d,0xca,0xba,0xc7,0x9f,0xe8,0xe7,0x34,0x72,0x27,0x0f,0xb6,0x87,0x3a +.byte 0x52,0x50,0xdb,0x0a,0xc8,0x1d,0x39,0x0d,0x86,0xb6,0x1a,0xce,0x19,0xf7,0x20,0x5e,0xb6,0xe4,0xcc,0x06,0xaf,0x66,0xf3,0x19,0x23,0x5d,0xec,0x11,0x80,0x67,0x40,0x9f,0xcc,0xa5,0x89,0xe3,0xd6,0x06,0xd1,0x40,0xc9,0xf5,0x9d,0xa7,0xa2,0x3e,0x08,0x7a,0xef,0x8b,0xff,0x09,0x6f,0xd0,0x23,0x73,0x2c,0x46,0xd4,0x73,0x9e,0x69,0xcc,0x05 +.byte 0x27,0x3d,0x8a,0x22,0x9d,0x92,0x84,0x40,0x07,0x81,0x65,0x03,0x6a,0x59,0xe9,0x57,0x4c,0x93,0x1a,0xaf,0xc2,0x12,0x7d,0x23,0x1a,0xd8,0xad,0xcb,0x51,0x8b,0xce,0x28,0xc5,0x8e,0xb8,0xab,0xa4,0x50,0xc3,0xe7,0xb9,0x8f,0xc3,0x99,0xc2,0x7b,0x86,0x9f,0xb3,0x4e,0x4d,0x14,0x66,0xe4,0xdf,0x40,0xdf,0xd8,0xdd,0x05,0x9f,0x96,0x3b,0x7e +.byte 0x9f,0x72,0xc9,0x11,0x98,0x73,0x40,0x72,0x2e,0xbc,0x2c,0xc7,0x0c,0x70,0xcf,0xbc,0x3c,0x25,0x43,0xec,0x36,0x5f,0xb9,0x80,0x19,0x79,0xd3,0x29,0x6e,0xe8,0x35,0x0b,0x1a,0x75,0xfa,0x4a,0x08,0xda,0xaf,0x1d,0xb5,0x06,0x6b,0x44,0xe4,0xde,0xe7,0x16,0x59,0xe5,0xad,0x23,0xc1,0x8e,0x87,0x27,0x03,0xc2,0xad,0x20,0xf7,0xdd,0x05,0x39 +.byte 0x16,0xc8,0x6b,0x32,0x99,0x8b,0x39,0xb4,0x6e,0x16,0xa5,0x4e,0x5d,0xe1,0xf0,0x91,0xf2,0xfd,0x5e,0xbf,0x0a,0xf7,0x33,0x82,0xaf,0x8a,0xaa,0x99,0xac,0x24,0xdf,0x43,0x84,0x8f,0x82,0x56,0x8a,0xae,0xbd,0x2e,0x5b,0x1b,0x95,0x0f,0xc1,0x7c,0xa1,0x4e,0xda,0x11,0x21,0x0c,0x7e,0xa2,0x5b,0x30,0x89,0xbb,0x52,0x4a,0x8d,0x9f,0x95,0xd9 +.byte 0x0e,0x6b,0x74,0xb4,0x0b,0x2a,0x37,0x21,0x9e,0xb6,0x00,0x9f,0x09,0x71,0xf8,0xd2,0x98,0x47,0x65,0x33,0x88,0x16,0x6b,0x5a,0x61,0x8c,0xdf,0x4d,0xbe,0xb0,0xde,0xc9,0x35,0xa3,0xa8,0x9f,0xf6,0xe7,0x93,0x29,0x29,0x66,0x43,0x5e,0xcc,0x1e,0x8b,0xf7,0x8d,0x3c,0xc2,0xfa,0x52,0xfc,0x44,0x71,0x02,0xfc,0x54,0x74,0xc2,0x10,0x84,0xc1 +.byte 0xfb,0xd0,0x65,0x05,0x5c,0x16,0xd3,0x65,0x1a,0x8c,0xae,0x45,0xb8,0x70,0x8a,0x27,0x66,0xaf,0x7f,0x6b,0xcf,0x71,0x33,0x14,0xdd,0xe4,0xd7,0xdf,0x81,0xcb,0xd5,0x6b,0x67,0x82,0x52,0x6c,0xbc,0xb7,0xd8,0x19,0x24,0x74,0xdd,0x7f,0x06,0x04,0x76,0x36,0x5a,0x63,0x9e,0x6e,0x36,0xc3,0xc6,0xa7,0x4c,0xa8,0x1b,0x6c,0x45,0x14,0x4d,0x6e +.byte 0x62,0x88,0x27,0x6e,0xb8,0x00,0x11,0x93,0x6a,0xee,0xa6,0xcf,0xcb,0x6b,0x6a,0x2d,0x67,0x32,0x61,0x0b,0xea,0xb6,0xfd,0x9a,0x4a,0x34,0x02,0x79,0x80,0x0c,0x3d,0x3f,0x69,0x9f,0xb5,0xcf,0xda,0x6a,0xdf,0x4d,0xba,0xf4,0x63,0xf3,0x4f,0xc0,0x86,0x1c,0x41,0x3b,0xd6,0x43,0x35,0x1b,0xee,0xfc,0xac,0x6c,0x27,0x94,0xa9,0x98,0xe3,0x07 +.byte 0x83,0xb2,0x19,0x9e,0x75,0x84,0x1f,0x70,0xe0,0x3c,0x49,0x77,0x82,0xb5,0xc0,0x52,0x80,0x06,0xce,0xb7,0x1c,0x9b,0x08,0x47,0x5e,0x7f,0xe1,0x8e,0x90,0x4f,0x29,0xdc,0x50,0xbd,0x0e,0x64,0xfb,0x93,0xa6,0x5e,0x6d,0xa4,0x2d,0x36,0xf2,0xe1,0x65,0xed,0x13,0xbe,0xf4,0x8c,0x46,0x3b,0x24,0x96,0xaf,0x47,0xe1,0x13,0xe1,0x7b,0x4c,0xf7 +.byte 0x7d,0x8c,0x1c,0x41,0x6e,0xa7,0xcd,0x1e,0x0a,0x5c,0x44,0xc0,0xf7,0x1d,0x53,0xff,0x1f,0xe4,0x64,0x92,0xa7,0xe4,0x68,0x7b,0xaa,0xb0,0x76,0x88,0x21,0x1d,0x43,0x9b,0x9d,0x7c,0xdb,0x6e,0x91,0x90,0xd6,0xbe,0x9a,0xb8,0x2b,0x8e,0x73,0xe9,0x07,0x09,0x2f,0x85,0x7d,0x63,0x75,0x25,0x1d,0xb5,0x39,0xbc,0x1e,0x27,0xd7,0xf8,0x40,0xda +.byte 0xe5,0x45,0xb5,0x02,0x9c,0x7e,0x0a,0x4b,0x5e,0xb5,0x88,0xbb,0x86,0x3a,0x35,0xb8,0xb9,0x0b,0x39,0x85,0xbd,0x18,0xb7,0x58,0xcd,0x6b,0xdc,0x25,0x86,0xee,0x17,0x9d,0x3d,0xd8,0xb4,0x33,0x09,0x1c,0x57,0x52,0x7c,0x0e,0xb3,0x61,0x07,0x5c,0xea,0xf5,0x05,0x1b,0x43,0x20,0x14,0x87,0x15,0xfb,0x9c,0x3f,0x0d,0xa9,0xfc,0xf6,0xa7,0x66 +.byte 0x46,0x54,0x8c,0x2c,0x2d,0x22,0x72,0x8f,0x2d,0x00,0x1d,0x1b,0x0c,0x84,0xb4,0x21,0xd6,0x3f,0x3d,0x5f,0xfd,0x22,0xe3,0xd7,0x72,0xa7,0xd1,0x98,0x7f,0x53,0xf0,0xcf,0x6b,0xb9,0xe4,0x40,0x1c,0x23,0x94,0xa9,0x8e,0x9f,0x00,0x0e,0x65,0x59,0x2a,0xcf,0x2d,0xb6,0x15,0xa8,0x97,0x9a,0x75,0xac,0x88,0xf7,0xe7,0xe4,0x1e,0x56,0x38,0xc7 +.byte 0xb7,0x68,0xaf,0x15,0x48,0x9c,0xa6,0xca,0x3e,0x67,0x11,0xca,0x7f,0x3a,0x9c,0xc7,0x1a,0xff,0xcc,0x10,0x10,0x67,0x5f,0x62,0x72,0xca,0xd8,0xf2,0x4b,0x7a,0xc5,0xf0,0xc9,0x40,0x45,0xc9,0xe4,0xef,0x50,0x18,0xf8,0x38,0xca,0x93,0x68,0x74,0xdb,0x3e,0x92,0x77,0xf6,0xc1,0x81,0x33,0xaf,0x6f,0x62,0xb3,0x5e,0x67,0x66,0xca,0x53,0xe5 +.byte 0xc2,0x37,0x4e,0x97,0xa8,0xac,0x5e,0xf5,0x36,0x48,0xa5,0xb4,0x9e,0x07,0x38,0x7b,0x2a,0xb5,0xb6,0x3c,0xc6,0x04,0x90,0x38,0x52,0x07,0xc3,0x26,0xd2,0x08,0x55,0x6f,0x7d,0xda,0x53,0xf2,0x3e,0x09,0xa7,0x3e,0xe6,0x6b,0x31,0x72,0xc3,0xcb,0x30,0x3a,0x5b,0x0e,0xca,0x4c,0x94,0x7e,0x18,0x27,0xe3,0xb2,0x40,0x7b,0x68,0xa2,0xa7,0x2b +.byte 0x80,0xf1,0x36,0xc9,0xb0,0x52,0x71,0x59,0x1c,0x41,0xcd,0xe9,0x4b,0x3a,0x89,0x9e,0xc4,0x5c,0x0c,0xfe,0x96,0x02,0xbd,0x3c,0xbd,0xe9,0xf1,0x78,0xe3,0x89,0xab,0xe3,0x7d,0x8b,0xc8,0xc6,0x40,0x2c,0xd5,0xfe,0xc9,0x02,0x1a,0x69,0x72,0x50,0x49,0x16,0x8a,0x9a,0x79,0x25,0x69,0x84,0xc7,0xc0,0xae,0xd1,0x7d,0xd0,0x28,0x88,0x12,0xee +.byte 0x22,0x86,0xec,0xea,0xe2,0x74,0x19,0xae,0x54,0x78,0xd1,0xc1,0x64,0x90,0x04,0x6f,0x0a,0xa3,0x60,0x14,0x63,0xe3,0x6a,0xed,0x7e,0xd5,0x36,0x0a,0x3c,0x72,0x2c,0xde,0xbd,0x01,0xff,0x22,0xe8,0x4c,0x55,0xbf,0xa6,0x24,0x18,0xbe,0x23,0x12,0xfa,0x91,0x30,0xa6,0x09,0xcd,0xc2,0x43,0x59,0x0c,0xab,0xc0,0x99,0x20,0xf1,0xbc,0x5e,0xab +.byte 0x72,0x85,0x72,0x2f,0x1c,0x21,0xcc,0x38,0xa3,0xa2,0xbe,0x40,0x70,0xf1,0x80,0x4d,0x18,0x1d,0xb4,0x61,0x84,0x19,0xc1,0xd0,0xcd,0xae,0xa8,0x74,0x46,0xe3,0x4e,0x0e,0x54,0xc6,0xc3,0x80,0x17,0x32,0x62,0x80,0x9a,0x8c,0x7a,0x7b,0x94,0xb2,0x1a,0xa4,0xa5,0xcc,0x65,0x46,0xa9,0xe6,0x62,0xf7,0x04,0x43,0x75,0x0e,0x48,0xf6,0xdb,0xc7 +.byte 0xad,0x2f,0xad,0x0c,0x19,0xce,0xe6,0x03,0xcf,0x9b,0x33,0x99,0x90,0x8a,0x5f,0xf0,0x84,0xe6,0xe9,0xda,0xaa,0x6f,0x45,0xdc,0xab,0x9e,0xc6,0xd8,0x6f,0xc4,0xa2,0xea,0x17,0x8f,0xa7,0x0c,0xbf,0x79,0x2e,0x06,0xa7,0x84,0x41,0x80,0x85,0x25,0xdc,0x40,0xf9,0x11,0x45,0xfb,0x6d,0x43,0x3c,0x84,0x64,0xf4,0xa2,0xdc,0xa3,0x0d,0xa1,0x0a +.byte 0x49,0x34,0x10,0x63,0x3a,0xef,0xe7,0x08,0xe9,0xf4,0xff,0x0e,0x2d,0x3b,0xf6,0xa7,0x62,0x8e,0xe5,0x61,0x32,0x3d,0xaa,0x01,0xd0,0xa3,0x54,0xf1,0xdf,0x1f,0x8a,0x58,0xfd,0x2d,0x81,0x8b,0x3b,0xe8,0x95,0x2e,0x92,0x58,0x5c,0x23,0x95,0x29,0xe7,0x3c,0x3c,0x09,0xbb,0xdc,0x55,0x37,0xf4,0xa6,0x14,0xc8,0xff,0x6b,0xff,0x17,0xb8,0x81 +.byte 0xf7,0xa1,0x96,0xb6,0xd0,0xea,0x35,0x1b,0x3e,0x81,0xf4,0xf2,0x88,0x03,0x97,0xbf,0x1d,0x06,0xa1,0xa4,0xa9,0x9f,0x81,0xa3,0x36,0x3a,0x58,0x2c,0x9d,0x5c,0x44,0xcb,0x10,0x5e,0xa6,0x62,0x3e,0xb6,0xf9,0x1d,0x24,0xa4,0xb8,0xb8,0xa7,0x13,0x14,0x1f,0xab,0x29,0x64,0xaf,0xa8,0x48,0xa4,0xc9,0x31,0xb7,0x1d,0xb2,0xd0,0x88,0xe1,0x14 +.byte 0x87,0x26,0x65,0x47,0x61,0x4e,0xd2,0xf1,0x48,0x32,0x06,0xb4,0x39,0x49,0xed,0x68,0xa8,0x71,0x83,0xfd,0x77,0xdf,0x69,0x88,0x36,0x34,0x4a,0x11,0xfd,0xa0,0x11,0x87,0xe4,0xe7,0x02,0x52,0x34,0xfe,0xfe,0x77,0xbf,0x21,0x33,0x77,0x4d,0x85,0x57,0xd6,0xbb,0x07,0xdc,0x63,0xb1,0x53,0xc4,0x9f,0x7c,0x05,0x6f,0x23,0xe8,0xb7,0x49,0x1e +.byte 0xd9,0xdb,0xc7,0xff,0x99,0x2a,0xc1,0xef,0x93,0x09,0x3c,0x13,0xf7,0x49,0xdb,0x72,0x16,0x68,0xb2,0x37,0x39,0x43,0x43,0x4a,0x75,0xdb,0x77,0x3a,0x7c,0x8f,0x6f,0xe1,0x47,0x65,0xbe,0xe7,0x3e,0xec,0xf8,0xe9,0xff,0x6b,0x71,0x7c,0x3b,0x56,0x57,0xea,0x9e,0x51,0x13,0xe3,0xdc,0x59,0xa1,0x81,0x84,0xd0,0xfc,0x12,0xf4,0x2e,0x2b,0xba +.byte 0xed,0xb9,0x13,0x76,0x63,0xee,0x42,0x6f,0x74,0x71,0x06,0x26,0x7a,0x03,0x39,0x5f,0xb1,0x54,0x6a,0xf9,0xf0,0xdf,0x8f,0x9f,0xca,0x58,0x5e,0x4d,0x72,0xa8,0x76,0x2f,0xa1,0x9e,0xa3,0x0f,0x73,0x31,0x8c,0xe8,0x90,0x53,0xd6,0x2b,0xa1,0x35,0xd9,0x6a,0xae,0x56,0x5f,0xd4,0xfc,0x9b,0xae,0x1d,0xdc,0x21,0x50,0x39,0x7c,0xfe,0xd2,0x80 +.byte 0x7b,0x9e,0x20,0xde,0x30,0x79,0x5c,0xc6,0x8d,0x10,0xb4,0xb1,0x3c,0xf0,0x1d,0x48,0x6f,0x0f,0x2d,0xd7,0x0a,0x2f,0x62,0x1f,0xdc,0x24,0x7b,0x8b,0xe8,0xf2,0xb4,0x3f,0xd5,0xb3,0x69,0x87,0x65,0x38,0xff,0x63,0xc2,0xb0,0xc8,0x50,0x8f,0x1c,0x17,0xaa,0xd7,0x0f,0x14,0x27,0xb2,0xc5,0xf7,0xe0,0x18,0x9c,0x35,0xa7,0xe0,0xf9,0xad,0x74 +.byte 0xec,0xe0,0x0c,0xda,0x79,0x7f,0x58,0xa3,0xb9,0x07,0x76,0x1e,0x64,0x20,0x99,0x17,0x32,0xfd,0xe7,0x6a,0xd9,0xcb,0x7b,0x2f,0xd8,0x57,0xd4,0xfa,0x4e,0x3a,0xbc,0x0b,0xdd,0x90,0x04,0xdb,0x3d,0xc9,0x8a,0xb0,0x6a,0x72,0x42,0xff,0x0c,0x08,0x88,0xfc,0xa4,0x59,0x07,0x2a,0x32,0x2f,0x02,0xb1,0x78,0x13,0x1b,0x05,0x38,0x73,0xa5,0xf1 +.byte 0x98,0xee,0xd4,0x1f,0x83,0x63,0x90,0x9c,0x74,0xa5,0x3d,0x7d,0x32,0x29,0x08,0xa4,0x01,0x8a,0xc7,0x26,0x86,0x85,0xd2,0xa1,0x0b,0xaf,0x92,0x0a,0x28,0x8b,0x5f,0x90,0x99,0x56,0xec,0xe8,0x9b,0x0e,0x9a,0x4d,0xc2,0xdc,0xf4,0x27,0x04,0x1b,0xc5,0xe8,0x6d,0xa6,0x1f,0x94,0xa7,0xd1,0xbe,0xf7,0xe9,0xc0,0x39,0x0a,0x85,0xa4,0xbf,0x30 +.byte 0x43,0x4b,0xf8,0x28,0x6d,0x6d,0xb9,0xa2,0x7f,0x64,0x0d,0x04,0x8b,0xd3,0xc5,0xab,0xe9,0xb0,0xa1,0x4c,0x85,0xe6,0x3d,0x3e,0x37,0xad,0x3e,0x27,0x72,0xaf,0x60,0x5a,0xd3,0xa3,0xf0,0x6a,0x67,0xfb,0xda,0xc5,0x41,0x81,0x2e,0xcb,0x75,0x00,0xf7,0xdf,0xf5,0xef,0x19,0x03,0x81,0x4f,0x70,0xc9,0xa4,0x40,0xbf,0xeb,0x39,0xff,0x14,0xf5 +.byte 0xaf,0xcf,0x21,0x77,0x65,0x4e,0x96,0xf6,0xb3,0x9c,0x9a,0xb9,0xfe,0xe3,0x37,0x3f,0xf8,0x6e,0xc5,0x51,0x3f,0xd0,0xfa,0xef,0x7c,0x07,0x72,0xb6,0xca,0xcb,0xf8,0x20,0x94,0x74,0x8c,0xe9,0x0d,0x6b,0xfb,0x98,0x0a,0xec,0x90,0x05,0x33,0xc4,0x7d,0xfc,0x7b,0x95,0xd9,0xc3,0x67,0x0b,0xd7,0xdd,0xd8,0x67,0x3c,0xf1,0x84,0xf4,0x51,0x78 +.byte 0x29,0xff,0x51,0x86,0xc8,0x84,0x6e,0x31,0x3c,0x6d,0xaf,0x8b,0xe0,0x2d,0xb0,0xc7,0xf5,0x19,0x87,0xe6,0x76,0xc7,0x5b,0xb7,0xd3,0xe0,0xb6,0x4c,0x65,0x95,0x74,0xaf,0x6e,0x5f,0x9c,0x67,0x98,0x1f,0x7c,0xec,0xd5,0xf8,0x47,0x24,0x1d,0x95,0xbf,0x95,0x6e,0x64,0x89,0xad,0x42,0x0a,0xe5,0x7f,0xc0,0x2e,0xc5,0x93,0xc2,0x06,0x20,0xe7 +.byte 0xc2,0x3e,0x04,0x51,0x3b,0x61,0xce,0xda,0x84,0x95,0xba,0x59,0x2b,0x88,0x21,0x68,0xed,0x64,0xd7,0x13,0xb7,0x1b,0x5c,0xa2,0xbd,0xa6,0xd4,0x38,0x68,0xf3,0xd8,0x66,0x29,0x51,0x88,0x02,0xc7,0x87,0xa6,0x5b,0x29,0x5b,0x8e,0xb8,0xbf,0xff,0xc7,0x8c,0x98,0xe7,0xc5,0xc2,0x93,0x6a,0xc0,0xb4,0x04,0x8f,0x1a,0x2d,0xd4,0xea,0x1f,0x2a +.byte 0xfd,0xf3,0x30,0x50,0xda,0xbe,0x81,0x0a,0x76,0xad,0x73,0xfc,0xd1,0x7d,0x06,0x58,0xeb,0x77,0x55,0x3c,0x8e,0xef,0x25,0x4d,0x78,0x0e,0xda,0x00,0x8c,0x8b,0x94,0xed,0x65,0x3d,0x51,0xbe,0xd2,0xa0,0x3d,0x8c,0xde,0x2e,0xd0,0xe5,0x8b,0x7c,0x1f,0x15,0x35,0x27,0xe4,0x62,0xa5,0xcb,0x40,0x29,0x63,0x51,0x35,0xbe,0x6b,0x0c,0xec,0xdd +.byte 0xb8,0x35,0x89,0x03,0xdf,0x50,0x85,0xbc,0x93,0x34,0x83,0x65,0x7b,0xfc,0x34,0x7a,0x72,0x90,0x44,0xec,0x3e,0x6b,0xda,0x65,0x6a,0xaf,0x90,0xe3,0xcc,0x86,0xb4,0x1e,0x26,0x68,0x34,0x91,0xfd,0xcb,0x5d,0xac,0x04,0xff,0xdd,0x7a,0xe4,0x5c,0xd7,0x05,0x7b,0x4c,0xbc,0x26,0x31,0xb9,0xbc,0x9b,0xd0,0x0b,0x1e,0x1b,0x4b,0x0a,0x25,0x58 +.byte 0x9b,0x11,0x66,0x16,0x07,0x15,0xd1,0x3a,0x68,0xfc,0xdb,0x88,0xcc,0x91,0x4b,0x2e,0xd7,0xe6,0x9d,0x13,0x3c,0x8c,0x0c,0x35,0x4d,0xc9,0xfc,0xc7,0xb6,0x7e,0xaf,0x02,0x7c,0xd4,0x8c,0xf9,0xf4,0x63,0x87,0x2f,0x0a,0xd1,0xf7,0x1f,0xd9,0xa8,0xd6,0x5c,0x1e,0xee,0xe7,0xb6,0x3b,0xa2,0x93,0x9e,0xa7,0x5b,0x66,0x38,0xb6,0xd3,0x39,0x6a +.byte 0xb7,0xc4,0x34,0xf1,0x5d,0x50,0x45,0x32,0x59,0x90,0x5b,0x05,0xd8,0xed,0x6d,0x01,0xdb,0x1f,0x37,0x59,0x1b,0x42,0xc2,0x4c,0xc4,0x32,0xa1,0xc4,0xdf,0xa0,0x45,0x64,0x33,0x26,0x9b,0x6a,0x91,0x5f,0x8f,0x9a,0x21,0x8b,0xdc,0xed,0x5c,0xbb,0xcc,0xdc,0x75,0x21,0x14,0xbc,0x49,0x1a,0x3a,0xc7,0x5f,0xba,0x11,0xae,0x37,0x3f,0x9f,0x66 +.byte 0xd4,0xf9,0x25,0xb6,0x7b,0xa8,0x85,0x9b,0x27,0x6a,0x3b,0xcc,0x87,0x72,0xa1,0xf1,0x41,0x15,0x98,0x37,0xea,0x63,0xb9,0xd3,0x44,0x81,0x26,0xec,0x7a,0xaa,0x5b,0xe9,0xe1,0xe1,0xd3,0x6b,0x31,0x38,0x7f,0xc4,0xd3,0xb1,0xcf,0xc8,0x61,0x70,0x49,0xe1,0xac,0x08,0xd3,0x64,0x4a,0xbc,0x1a,0xe4,0x76,0xa5,0xf1,0x12,0x42,0xbb,0x97,0x52 +.byte 0x7d,0xf0,0x42,0xbb,0xc0,0x1c,0xda,0x40,0x04,0x98,0xa9,0x3f,0x0e,0xf2,0x6d,0x82,0x8e,0x52,0x7c,0xc1,0x91,0x54,0xe8,0xc0,0x69,0x09,0x25,0xc1,0xe8,0xea,0x57,0x8c,0x76,0x55,0x03,0xfc,0x39,0x1f,0x90,0x6b,0xb9,0x98,0xc3,0xc1,0x73,0x4f,0x4e,0xbf,0xc5,0x64,0x95,0x1e,0xba,0x7e,0x73,0x51,0x22,0xee,0x24,0xce,0x12,0x66,0x3e,0x84 +.byte 0x4a,0x27,0x2e,0x45,0xc6,0x3d,0x4a,0x3a,0xbe,0xf9,0xb6,0x14,0x0a,0xf0,0xa5,0x94,0x14,0x69,0x2d,0x25,0x7d,0x60,0x9b,0x77,0x79,0xc5,0xd2,0xfd,0x1f,0x66,0xc5,0xad,0x99,0x7f,0x42,0x08,0xe2,0xc6,0x40,0xa8,0x8c,0x07,0xd2,0xa9,0x10,0x30,0x8d,0x80,0x4c,0x41,0xc5,0x42,0x67,0x09,0xbe,0x60,0xbf,0x0d,0xba,0x94,0x4f,0xb0,0x78,0xed +.byte 0x60,0x91,0x26,0x99,0x9a,0x50,0x30,0x65,0xe3,0xa4,0x7b,0x76,0x32,0x85,0x29,0xeb,0x47,0x17,0x88,0xd4,0x05,0xf5,0xd9,0x6a,0xec,0x90,0x44,0x40,0x06,0xc7,0x77,0x45,0x9c,0x17,0xf8,0x25,0xcd,0x0f,0xeb,0xb3,0xcc,0x78,0x09,0x98,0xc5,0x68,0xb4,0xd8,0x9d,0x35,0xa6,0x33,0xf3,0xdd,0xee,0x8a,0xb5,0x3c,0x93,0xee,0x08,0xcf,0x1d,0xd1 +.byte 0xf1,0x96,0x81,0xc0,0x3a,0xa1,0x5a,0x2b,0x69,0x6d,0x6a,0x4d,0x8d,0x5a,0xed,0xb3,0xd1,0x7a,0x29,0x99,0xa2,0x65,0x05,0x33,0x95,0xd8,0x2e,0xd8,0x73,0x3b,0x4e,0xc2,0x94,0x80,0x77,0x34,0xcb,0x0b,0x92,0x01,0x1e,0xaa,0x2b,0x1d,0xe6,0x03,0xc0,0xb4,0xb7,0x1f,0xed,0xf1,0x4b,0xb2,0x82,0x65,0x13,0x9a,0x9e,0x35,0x8d,0xe5,0xb8,0xb0 +.byte 0xc8,0x93,0x04,0x1e,0x83,0xbb,0xcb,0x91,0x2b,0x8d,0x18,0x22,0xd0,0x73,0x4f,0xae,0x54,0x5f,0x8a,0x20,0x4a,0xa5,0x98,0x9e,0x37,0x68,0x5d,0xcc,0x41,0x86,0x2d,0xb3,0xe5,0x09,0xdb,0xbd,0xa1,0x27,0xbf,0x7a,0x69,0x05,0xb4,0xf2,0x06,0x11,0x80,0x57,0xbd,0x92,0xed,0xb5,0x26,0x3a,0x1a,0xea,0x70,0x99,0x04,0x90,0x07,0x4e,0xa7,0xc2 +.byte 0x78,0x49,0x70,0x80,0x97,0x10,0xb8,0xd7,0x45,0x8a,0x23,0x99,0x80,0xa3,0x1c,0x66,0x26,0xdb,0xdc,0x82,0x3a,0x09,0x0c,0x1e,0x61,0x78,0x70,0x68,0x81,0x85,0x91,0x82,0x68,0x8e,0xed,0xeb,0xad,0xd1,0x6b,0xe7,0x52,0x29,0xca,0x5f,0x3c,0xd3,0x55,0xeb,0x11,0x19,0x99,0xe0,0xf0,0x33,0xdc,0x9f,0x53,0x52,0xeb,0xda,0xfd,0x35,0x89,0xc3 +.byte 0xc8,0xa6,0x7c,0xd2,0xf3,0xab,0x8b,0xe1,0xbf,0xca,0xa7,0x24,0xd2,0xd4,0xa2,0xa5,0x94,0x2a,0x9e,0x90,0x82,0xb4,0xcd,0x9f,0xe8,0x1e,0x70,0xdb,0x67,0x60,0xb8,0x2b,0x3d,0x74,0x25,0x5c,0xd6,0xbd,0xc2,0x92,0xfb,0xdd,0x3f,0x1d,0x24,0xa0,0xbd,0xbe,0x42,0xc6,0x78,0xde,0xf7,0xa0,0x1a,0x6a,0x6a,0xd0,0x05,0xcc,0xec,0xf0,0x4c,0xa9 +.byte 0x52,0x68,0xb0,0x41,0x7e,0xd8,0x73,0xf0,0x45,0x65,0xa4,0x6e,0xf1,0x9c,0xdc,0xa8,0x22,0x7f,0x50,0x67,0xb8,0x90,0xd5,0x1b,0x57,0x36,0x4d,0x16,0x98,0xf3,0xef,0x03,0xd7,0x76,0x31,0x1b,0xd3,0x22,0x56,0x30,0xda,0xaf,0x72,0xa8,0xf1,0xa4,0x88,0xee,0xfd,0x0b,0x46,0x26,0x9b,0x37,0xa2,0xc6,0x1d,0x42,0xb1,0x86,0xe3,0xef,0xaf,0xe6 +.byte 0xfb,0xc9,0x90,0xbe,0x58,0xe1,0xea,0xe1,0xa6,0xd3,0xc0,0xf2,0xf3,0x31,0x09,0xc0,0x73,0x04,0xfb,0x96,0x53,0xb2,0xd5,0xb2,0x4a,0xeb,0xd2,0x7d,0xd3,0xcb,0x49,0xba,0xbd,0x1f,0xe6,0x00,0x16,0x84,0x4e,0xc0,0x63,0x00,0xe3,0xb5,0x47,0xa1,0x2c,0xda,0x72,0xb4,0x4b,0xc8,0x52,0x93,0x65,0x73,0xf0,0xce,0x84,0x6c,0x99,0xda,0x0a,0x00 +.byte 0x06,0x60,0xa2,0x9d,0x95,0xe0,0x44,0x05,0x02,0x57,0x65,0x5a,0xa7,0x4f,0x9d,0x3c,0x9f,0x58,0xbd,0x5e,0x70,0x05,0xaa,0x05,0x14,0xb0,0x10,0xe4,0x6f,0xfa,0xd6,0xff,0xde,0x5f,0x1b,0x71,0x3e,0x0c,0x75,0x20,0xd4,0xe3,0xfc,0x3b,0xc0,0x0d,0xb0,0xad,0x64,0xea,0x46,0x38,0x0a,0x93,0xf4,0xcb,0x5b,0x16,0xd4,0x17,0xbe,0x69,0x13,0x6e +.byte 0xe8,0x1d,0x6d,0xb0,0x2b,0x51,0xae,0x66,0xbb,0xf2,0xda,0x0a,0xea,0x21,0xba,0x01,0x41,0x51,0x00,0xe4,0x1a,0x72,0xf7,0x11,0xdf,0xc4,0x6d,0x9f,0x82,0xb6,0xde,0x3b,0xaa,0x32,0x8b,0x52,0x09,0x25,0x9d,0x84,0xc7,0xc2,0xa9,0xe4,0x8e,0x09,0x8f,0x38,0xf9,0x83,0xe7,0xa6,0xf2,0x88,0xbb,0x94,0x80,0xa1,0xce,0x7f,0x8e,0x91,0xfd,0xcb +.byte 0xae,0xf2,0x71,0x57,0xa9,0x22,0x82,0xe2,0xb6,0xc8,0x08,0x7b,0x9b,0x85,0x7f,0x51,0x2b,0x03,0xd0,0x94,0x2d,0x2f,0x89,0xef,0x91,0xaa,0x0d,0xde,0xcc,0x0d,0xe9,0xb8,0x6f,0xed,0xed,0x0d,0x43,0x41,0x9c,0x3b,0x6b,0x52,0x41,0x09,0x49,0xad,0xff,0xd7,0x93,0x15,0x2e,0xae,0x54,0x07,0x42,0x13,0x59,0xe6,0xed,0x3a,0x68,0x42,0x1e,0x4b +.byte 0xe8,0x5c,0xe3,0xa8,0x4f,0x1c,0x0e,0x7a,0xc8,0x62,0x5f,0x53,0x04,0x3c,0x86,0x3b,0xf7,0x8d,0x64,0xf6,0x1e,0x11,0x83,0x02,0x44,0xaa,0xf4,0xaa,0x5a,0xc8,0x57,0x98,0xd9,0xc2,0xc5,0xd7,0x06,0xc2,0xe7,0x56,0x9f,0xcd,0xa3,0x4a,0x8c,0xc1,0xb2,0xa3,0xc6,0x9f,0xd3,0x6c,0x4b,0x38,0xfd,0x23,0x98,0x42,0x78,0xca,0xd8,0x6c,0xfa,0x08 +.byte 0xb8,0x87,0x0e,0x34,0x9b,0xc5,0xe1,0x15,0x98,0xf7,0x06,0xd3,0xc7,0x25,0xe4,0x0d,0x44,0x2a,0xe4,0xdb,0x45,0xae,0x41,0x80,0xac,0x15,0x45,0x16,0x51,0x59,0xe5,0x98,0x68,0xbd,0x9d,0x0d,0x96,0x42,0xbb,0xb5,0x48,0x67,0x7c,0x79,0x3d,0xee,0x73,0xe6,0x4f,0x87,0xd5,0x34,0x91,0xdb,0x0e,0x7b,0xdb,0x2d,0xb5,0xea,0x5d,0xe3,0xf7,0x64 +.byte 0x47,0x41,0x95,0x75,0x3a,0x61,0x87,0x87,0xc6,0x51,0xeb,0x50,0xee,0x25,0x8d,0xc0,0xc5,0xb6,0x6f,0x67,0xca,0x45,0xb9,0xe0,0xad,0x2d,0x0c,0xe2,0x80,0xc2,0xf6,0xef,0xb7,0xa9,0xe3,0x44,0x76,0xe9,0x10,0x6f,0xc3,0x42,0xf5,0xa0,0x7b,0x15,0xd4,0x0f,0xde,0x72,0x1e,0x10,0x95,0xa0,0x03,0xbe,0x80,0xb0,0x24,0x06,0x84,0x24,0x1b,0x90 +.byte 0x8d,0xe5,0xb7,0xa9,0xab,0x69,0xdf,0x4a,0xf4,0x69,0x63,0x6a,0x9b,0x19,0x6d,0x47,0xe9,0xd1,0xe6,0xcd,0x2c,0xff,0x5b,0xf9,0x73,0xe8,0xd7,0xa3,0x3c,0xbd,0x42,0x47,0xf1,0xcf,0xf6,0xdd,0x58,0x09,0x81,0x7d,0x67,0x43,0x07,0x0d,0xb1,0x24,0x07,0xdf,0xc8,0x1d,0x0a,0xb3,0x97,0x37,0xef,0xc6,0x42,0xe9,0xf4,0x46,0xf6,0x35,0xfd,0x26 +.byte 0x11,0x0c,0xea,0x2f,0x34,0x96,0xe3,0x64,0x1a,0xca,0xaa,0x40,0x71,0xbe,0x00,0x43,0xd3,0x15,0x79,0x87,0x6a,0x78,0xfe,0x8b,0x20,0xd3,0x10,0xde,0xb1,0x49,0xf5,0xc6,0x14,0x4a,0x41,0xd0,0xf3,0xf1,0x61,0x00,0x0a,0xd6,0xf7,0x68,0x09,0x70,0xe9,0xd3,0xd2,0xf6,0x3c,0x0b,0x62,0x71,0xa4,0xd5,0x9d,0xfe,0xa1,0x7e,0x0c,0x52,0x44,0x1c +.byte 0x4f,0x5d,0x11,0x20,0xa1,0x9c,0x35,0x10,0xc1,0xab,0x22,0x94,0x95,0xe5,0xac,0x92,0x30,0x4b,0x59,0x30,0x33,0xbb,0x36,0xd0,0xd6,0xde,0x6b,0x89,0x58,0x25,0xbb,0x20,0x86,0x00,0x24,0x40,0x79,0x53,0xea,0x73,0xb1,0xa3,0x05,0x0f,0x88,0xe8,0x35,0x19,0xd3,0xca,0x42,0x68,0xe0,0x5e,0x6f,0x1e,0xe2,0x75,0x9b,0x65,0xa7,0xf8,0x21,0x41 +.byte 0x14,0x6e,0xf9,0xa5,0x28,0x12,0x8a,0xd4,0x75,0xfe,0x8d,0xef,0x0b,0x1f,0xd7,0x5e,0x9f,0x79,0xf9,0x8f,0xbb,0x78,0xf9,0xe6,0x5f,0x94,0x4b,0x5f,0xe7,0xdd,0xc9,0xa2,0x15,0x16,0xbf,0x47,0x45,0xd1,0x8c,0x05,0x59,0x7e,0xd9,0xf0,0x5a,0x70,0x52,0x01,0x72,0x90,0xef,0xe7,0x96,0xf5,0x0b,0xf3,0xa5,0x97,0xdc,0x3a,0xb8,0x9c,0x5c,0x57 +.byte 0x34,0x65,0x35,0xfb,0xe1,0xde,0x62,0x45,0x08,0xc2,0xc5,0x8a,0x7a,0x88,0x66,0xdd,0x66,0xee,0xc6,0xc0,0xab,0xf7,0x7e,0x63,0x91,0x51,0xd9,0xe9,0x00,0xba,0x7e,0xfa,0x9e,0x61,0x5b,0xb8,0x18,0x67,0x15,0x02,0x3e,0xf2,0x73,0xd5,0x3e,0x71,0xc7,0x6f,0x8c,0x74,0x1c,0xd6,0xb6,0x1c,0xc1,0x27,0x67,0xae,0x96,0xc6,0x57,0x80,0x52,0x3c +.byte 0x54,0x33,0xb5,0x14,0x05,0x68,0xe3,0x16,0x94,0xac,0x85,0x7a,0x57,0x76,0xe1,0xe5,0x49,0xe6,0xe0,0x56,0x5d,0xb2,0xf2,0x9e,0x01,0x7d,0x79,0xbe,0x83,0x9f,0x00,0x8a,0x69,0x68,0x8a,0xfd,0x5c,0x5d,0xea,0x87,0x1b,0x5f,0x55,0x36,0xf1,0x47,0xf3,0x5a,0x64,0xb2,0x13,0xd3,0xac,0x13,0xbb,0xfe,0xe3,0xb6,0x69,0xdf,0x25,0x1d,0x9e,0x00 +.byte 0x90,0xc2,0x21,0x96,0x2f,0x0f,0x9f,0xe6,0x37,0x23,0xd6,0xe0,0x00,0xbc,0xa5,0xb0,0x01,0x54,0xbd,0x70,0xbb,0x53,0xd7,0x80,0x38,0x6b,0xc0,0xa8,0x50,0x64,0x1f,0x94,0xf0,0xb4,0x67,0x62,0x62,0xad,0x91,0x0a,0x1e,0x5b,0x15,0xa8,0x65,0xea,0x8a,0xaf,0xf0,0xe7,0x76,0xce,0x36,0x16,0x97,0xf8,0x1c,0x5c,0x90,0x04,0xa3,0xbe,0x5a,0x64 +.byte 0x9f,0xd3,0x1d,0x7b,0x25,0x91,0x5b,0xbc,0xce,0xc3,0x15,0xf0,0x7f,0xe8,0xa2,0x6b,0x54,0xe4,0x61,0x88,0x18,0xee,0x5c,0x13,0xa8,0xae,0x16,0x94,0x48,0x1c,0x67,0x2c,0xc4,0x9f,0x5d,0x01,0x36,0x21,0x5f,0xf4,0x64,0x60,0x8e,0x1a,0xc5,0x61,0x18,0xea,0x44,0x6a,0xcc,0xd4,0xf2,0x2c,0xb0,0xa6,0x6b,0x54,0x3e,0xcd,0xa4,0x55,0x26,0x55 +.byte 0x94,0xa1,0x26,0xc1,0xb1,0x81,0xa1,0xcb,0xbe,0x74,0x1b,0x64,0x5b,0x91,0x73,0x94,0xc8,0xaa,0xfa,0xc0,0x22,0xc5,0xb0,0xc6,0x59,0x23,0xb2,0x95,0x41,0x04,0x62,0x98,0x9c,0x3a,0x6a,0x78,0xd2,0xc0,0x74,0xbf,0x65,0x15,0xac,0x66,0x0c,0x84,0xa2,0x66,0xdf,0xf7,0x69,0xd5,0x8b,0x79,0x87,0x5a,0x77,0xa1,0xe8,0x43,0x5d,0x01,0x1b,0x13 +.byte 0x2b,0x4e,0x69,0x5f,0x07,0xa4,0x3d,0xb7,0xc7,0xd0,0x6c,0xcc,0x2e,0xe0,0x87,0x9d,0x23,0xec,0x15,0xbe,0xe3,0xbe,0x53,0x21,0x2d,0x2e,0x22,0xa4,0x47,0x6e,0xff,0xc6,0x57,0xe6,0xe6,0x41,0xb3,0x08,0x02,0xa1,0x8c,0x6d,0xb1,0xd9,0x61,0xfe,0xc5,0x55,0xf5,0xf3,0xea,0x97,0x6d,0x7f,0xc7,0x36,0x6f,0x00,0xb7,0x80,0x9c,0xb3,0x04,0x55 +.byte 0xf5,0xf8,0x29,0xae,0x88,0x46,0x4f,0x78,0xb5,0x81,0x59,0x4b,0x33,0x98,0x19,0x08,0xc2,0xce,0x61,0x0f,0x66,0x45,0x07,0x2f,0x73,0xbd,0x10,0xa6,0x32,0x3c,0xdf,0x3a,0xa5,0x07,0x6e,0xf8,0xa8,0x0d,0xb8,0xb2,0x78,0xd1,0x9f,0x50,0x9e,0x35,0x1a,0x6e,0xcb,0xd9,0x76,0x40,0xb9,0x48,0xa4,0x8f,0x91,0x52,0x66,0xa3,0xc5,0x4f,0x69,0x07 +.byte 0xed,0xe0,0xd7,0xd8,0xc1,0x72,0x62,0x9a,0x52,0xbc,0x17,0x1e,0x26,0xdc,0x06,0xde,0xa2,0x04,0x4a,0x67,0x24,0x30,0xca,0xff,0x01,0x50,0x20,0xf1,0xfe,0xaf,0x70,0x8d,0xdf,0x86,0x0f,0x8e,0x94,0x92,0xa6,0x41,0x69,0x96,0x0f,0x20,0xd9,0xba,0xab,0x68,0x69,0x8a,0x7e,0x6f,0xda,0x48,0x7a,0xc8,0x53,0xb0,0x8f,0xe5,0x8f,0x6f,0x29,0xc2 +.byte 0x72,0xf1,0x6f,0x7f,0x41,0x1f,0xd3,0x8f,0x66,0xe1,0x17,0xe1,0x91,0xd8,0x60,0x7f,0x52,0xf0,0x50,0xa5,0xcd,0xa1,0x92,0x9a,0x8f,0x45,0x0f,0x84,0x6a,0x95,0x25,0x7e,0x22,0x2d,0xb0,0x74,0x2c,0x60,0x62,0x69,0x17,0x8b,0x08,0x41,0x5c,0xbf,0x4f,0x5c,0x7b,0x99,0x21,0xe0,0xcd,0x26,0x24,0xf4,0x4f,0x72,0xbf,0x9a,0x80,0x13,0x4b,0xcf +.byte 0x5a,0x60,0xd3,0x35,0x1c,0xf2,0x54,0xdd,0x99,0x12,0x8b,0xfa,0x6d,0xa2,0xf0,0xb3,0x02,0xac,0x1a,0xfc,0x2d,0xfe,0x35,0x5d,0x33,0xd4,0x41,0x2b,0x75,0xfb,0xbd,0x4a,0xd6,0x60,0x99,0xfb,0x8e,0xa5,0x4b,0x2a,0x38,0x6b,0x31,0x40,0xfe,0x38,0xc0,0xec,0xe1,0xf7,0x17,0x0b,0x13,0x61,0xda,0x9e,0x26,0xea,0x16,0x46,0x62,0x12,0xb6,0xa3 +.byte 0x01,0x2d,0x40,0x84,0x9b,0x91,0x42,0xed,0x04,0x2a,0xd8,0x90,0xbd,0xc3,0x8f,0xb4,0xfb,0x6f,0xa3,0xb8,0x76,0x77,0xe0,0xe7,0xa6,0x99,0xde,0x16,0x8a,0x0a,0x84,0x12,0xc6,0xd6,0xea,0xfa,0x7d,0x81,0x39,0xff,0xb8,0x70,0xa5,0x7e,0xda,0x19,0x6e,0xb7,0x94,0x57,0xa9,0xa3,0xea,0xf2,0x77,0x49,0xf6,0xb4,0x82,0x1b,0x58,0xa7,0x65,0xdb +.byte 0x27,0x00,0xb6,0x30,0xba,0x25,0xbe,0x07,0x5c,0x1a,0x66,0x4a,0xd3,0x5c,0xa2,0x31,0x4d,0x38,0xfe,0xf5,0xcb,0xef,0xa1,0x80,0xa0,0x53,0x8f,0x7b,0xae,0xe3,0xe0,0x2d,0x93,0x09,0xd0,0xc6,0x43,0x4d,0xe7,0x58,0x6c,0x45,0xa7,0x74,0x51,0xe9,0x57,0xd0,0xbf,0x11,0xcd,0x12,0x25,0xce,0x0c,0xaa,0xdd,0xa3,0xed,0x25,0x58,0xbb,0xdb,0x94 +.byte 0x21,0x06,0x08,0x78,0x80,0x5f,0x14,0xc4,0x4f,0x25,0xb2,0xa1,0x8e,0x58,0x9d,0xc7,0x63,0xf0,0xef,0x66,0xc8,0x03,0x74,0x3a,0x3a,0xea,0x65,0x5a,0xb6,0x02,0x88,0xbc,0xbe,0x60,0x57,0xdf,0x5c,0x72,0xc6,0x06,0xbd,0x4b,0x9b,0x90,0x78,0xc1,0x97,0xdf,0xf4,0xa4,0xe7,0x75,0xed,0x3f,0xf6,0x4a,0x33,0x31,0xd7,0xed,0xa3,0x1f,0xb9,0x52 +.byte 0x4e,0x59,0x03,0x66,0x89,0xee,0x9b,0xaa,0xfd,0x67,0xd0,0x3a,0xb4,0xfe,0x86,0xfe,0x14,0x7c,0x71,0x4a,0x2f,0xff,0x11,0x85,0x25,0x8e,0xc5,0x72,0xb9,0x8c,0x78,0x91,0x17,0x27,0xcf,0x0e,0xc0,0x46,0xaa,0x08,0x2d,0x49,0x84,0x4e,0xdf,0x9a,0xbc,0x50,0xa2,0x50,0x1f,0x52,0x0a,0x36,0x32,0x1f,0x1f,0x7d,0xf4,0x15,0x2b,0x01,0x34,0x50 +.byte 0xa8,0xa3,0x98,0xa6,0xd0,0x44,0x20,0x44,0x55,0x8f,0xf0,0x99,0xc1,0xaf,0x0f,0x54,0xee,0xea,0xb8,0xb6,0xf4,0x14,0xdb,0x4f,0x9d,0x31,0x66,0x7d,0x08,0x92,0xfb,0x20,0xda,0x3e,0x6e,0xfe,0xb9,0x57,0x41,0x63,0xb8,0x10,0x8e,0x7c,0x12,0x01,0xa3,0x0b,0x0c,0x19,0xce,0x14,0xc7,0x13,0xc6,0x72,0xf6,0x6f,0x4d,0x8d,0x2b,0xaf,0x96,0x1c +.byte 0xfc,0xcc,0x38,0x0b,0x7e,0xb7,0x44,0x1e,0x37,0xc6,0x2d,0x72,0xfb,0x20,0x40,0x07,0xa9,0x97,0xb3,0x17,0xc1,0x0a,0x65,0x75,0x57,0xda,0xc9,0xdc,0xcb,0x6a,0x3b,0xaa,0xd6,0x57,0x45,0xdb,0x22,0x9f,0x9c,0x0b,0x53,0xb3,0x08,0x9f,0xe3,0x79,0x0f,0xb1,0xa9,0x18,0xcc,0x96,0xf2,0xd0,0x8d,0xb0,0x4f,0x50,0x2d,0xec,0x03,0x26,0x8e,0x8b +.byte 0xeb,0x9b,0x52,0xa5,0xfc,0x2e,0xcc,0xcf,0x7b,0x1b,0x11,0x44,0x01,0x71,0x8b,0x03,0x5d,0x08,0x56,0x67,0x3a,0xe0,0x9d,0xb5,0xec,0x3f,0xce,0x7d,0x0f,0xb3,0x2b,0x1f,0xcc,0x0e,0xba,0xa8,0x69,0x22,0xa7,0x14,0x8a,0x7b,0x7c,0xa8,0x81,0x62,0x03,0x9c,0x3d,0x1e,0x27,0x09,0x4f,0xda,0x8b,0x0f,0x71,0xbc,0x87,0x9b,0xa9,0x48,0xed,0xa0 +.byte 0xf3,0x52,0xa1,0x4d,0xdd,0x57,0xa5,0x4f,0x38,0xdc,0x5a,0xd4,0x24,0x7a,0x9c,0x62,0xf3,0x51,0x54,0x28,0x1f,0xef,0x92,0x81,0x9c,0x80,0x1d,0xa3,0xe1,0xb8,0xb4,0xf4,0xb9,0xa1,0x43,0x27,0xc8,0x99,0x10,0x36,0x22,0xf8,0x7f,0x86,0xe2,0x5f,0x2f,0x21,0xe2,0x7e,0x16,0x9a,0xe7,0x29,0x3e,0x6b,0x03,0x32,0xcf,0x64,0x86,0xa1,0x8a,0x1e +.byte 0xce,0x15,0x12,0x8c,0xa9,0x71,0x2e,0x96,0x2b,0x70,0x94,0x51,0xeb,0xf9,0x59,0xa0,0x69,0xa7,0x1a,0xec,0x21,0x8b,0xea,0xa6,0xd5,0x8b,0x60,0x17,0x51,0x88,0xe5,0x5f,0xf5,0xc5,0x6c,0x0f,0xf3,0x32,0xef,0xab,0x5f,0x25,0x14,0x36,0x61,0x41,0x7d,0x7c,0x94,0x3a,0x3f,0xa5,0xbb,0xf1,0x52,0x2a,0xd1,0x9b,0xbe,0x5e,0x93,0xa1,0x9d,0xd3 +.byte 0xb7,0x19,0x7f,0x86,0x32,0x62,0xbc,0x5b,0x53,0x8a,0x41,0x0c,0x45,0x5b,0xc4,0xfd,0x78,0xfc,0xc2,0x6f,0x90,0xef,0xea,0xbd,0xd6,0x63,0x27,0xc8,0xcf,0x8a,0x7f,0xb1,0x04,0x10,0xe0,0x30,0xd9,0xba,0x57,0x24,0x6d,0x3d,0x9a,0x2a,0x90,0xfc,0x7e,0x49,0x28,0xda,0x89,0x89,0xcb,0xab,0x23,0xfb,0x85,0xbd,0x2c,0xca,0xf2,0x6b,0x59,0x7d +.byte 0x9c,0x06,0x88,0xd3,0xc5,0x5e,0xbd,0xa3,0xb5,0xbe,0x59,0xba,0xd9,0x73,0x43,0x99,0xf4,0xd1,0xf0,0x78,0x76,0xff,0x13,0x6b,0xc9,0x91,0x7e,0xad,0x4a,0x00,0xf3,0x05,0xa5,0x8d,0x17,0xf7,0xd8,0x5b,0xad,0x34,0x23,0x74,0xed,0xb6,0xa7,0x1a,0x0b,0x6a,0xf1,0xe8,0x8a,0xe5,0x81,0x0e,0xc2,0xe3,0xa0,0x8b,0x8e,0xca,0xed,0x50,0x03,0x8b +.byte 0xc0,0x0c,0xee,0x7c,0xde,0x3f,0xbc,0xd8,0x58,0x87,0x97,0x0c,0x12,0xed,0x08,0xa4,0xf0,0x12,0x6d,0xea,0xae,0x9f,0xc8,0x3e,0x7c,0xfa,0x7d,0x19,0x8d,0xad,0x38,0xdd,0x61,0x2e,0x58,0x05,0x23,0x92,0x83,0x63,0xe6,0x8e,0x86,0xbb,0xba,0xf3,0xe8,0x4b,0xf8,0xe6,0x6b,0xfd,0xeb,0x1d,0x6a,0xd5,0x8e,0x78,0x77,0x30,0xd5,0xb4,0x32,0x86 +.byte 0xd0,0xa6,0x26,0xf7,0xc6,0xd3,0xfc,0xd1,0x65,0x65,0xae,0xe2,0x2c,0x52,0xf7,0x36,0x4f,0xff,0xe2,0x6a,0x2a,0xd5,0x8c,0x85,0x5e,0xbf,0xbc,0xda,0x38,0x56,0xb2,0xc3,0x6c,0x5d,0x0f,0xdf,0xe4,0xb8,0x6a,0x43,0xd6,0x8b,0x55,0x5e,0xf5,0x38,0x46,0x26,0x25,0xe1,0x01,0x67,0x09,0xc8,0xc2,0xa7,0x23,0x30,0xf3,0x6d,0x25,0xf0,0x2e,0xa2 +.byte 0x51,0x2d,0x00,0x72,0x8d,0x47,0x0e,0xdd,0xa1,0xd8,0x88,0x06,0xbb,0x49,0x33,0xa1,0x07,0x62,0x3d,0xa5,0x31,0x9c,0x62,0x71,0xde,0x89,0xd2,0xcf,0xcf,0x53,0x24,0x54,0x86,0x52,0xae,0xdf,0x4a,0xff,0x5b,0x80,0x66,0xf5,0xd3,0xc0,0x56,0x76,0xc9,0xd0,0x53,0xd7,0xd8,0xd8,0x1d,0x39,0xfb,0xb3,0x06,0x89,0x07,0x5d,0x68,0xf0,0xc8,0x0b +.byte 0x90,0xbe,0x5b,0x95,0xac,0x3c,0x7d,0x81,0x6e,0x10,0xf6,0x77,0x35,0x72,0x31,0x12,0x5f,0x3b,0x2d,0xd5,0x7e,0x68,0x02,0xde,0x06,0xd9,0xa8,0xc5,0xb8,0x9b,0xa0,0xbd,0x24,0x3a,0xdc,0xea,0x3d,0xb7,0x44,0x87,0x70,0xe7,0x07,0x6d,0xf1,0xa4,0xe8,0xbd,0x1a,0xa9,0x12,0xf3,0xfa,0x62,0x6f,0x68,0x42,0xe5,0xbf,0x1f,0xb6,0x6e,0x35,0xa3 +.byte 0xc8,0xc3,0x11,0xb0,0x09,0x68,0xbe,0x99,0xf7,0x2e,0xac,0x2d,0x55,0x81,0x0d,0xbc,0xcc,0xec,0xbf,0x52,0x50,0x22,0xf2,0x7a,0x10,0x2d,0xe7,0x46,0xd6,0x9d,0xee,0xb7,0xa1,0xa0,0xaa,0xc9,0xa2,0x32,0x0c,0x99,0x6e,0x76,0x36,0x53,0x0e,0x0f,0x00,0x96,0x0b,0x5f,0x6b,0x80,0xc5,0xe2,0xcf,0x1d,0xe3,0x97,0x54,0x07,0x9b,0x3e,0xf3,0x74 +.byte 0xee,0x1e,0x93,0xaa,0x68,0xbd,0x7b,0x39,0x6e,0x4d,0x2c,0x67,0xe2,0x45,0xcb,0x35,0x3a,0x04,0x53,0x49,0x74,0xde,0xfb,0xfd,0x80,0xa1,0x0b,0x8d,0xb9,0x9e,0x9a,0x6f,0x4d,0x09,0x4b,0x4e,0x90,0x30,0xf4,0xe2,0x53,0x00,0xc3,0x33,0x59,0x0e,0x56,0x6c,0xd6,0xb9,0x4f,0xc1,0x44,0x6b,0x79,0x85,0x9e,0x2a,0x37,0x0f,0xc2,0xa7,0x63,0xca +.byte 0x6d,0x18,0x2e,0xd7,0x24,0xf3,0xc3,0x08,0xe9,0xf8,0x29,0x32,0x8a,0xb3,0x28,0x1a,0x93,0x7a,0x47,0xff,0xd0,0x9a,0xe4,0x97,0xef,0x4a,0x23,0xb5,0x61,0x1d,0x64,0x7c,0x69,0x90,0x5b,0xba,0x70,0x41,0xa6,0x51,0x08,0xf3,0x48,0x8e,0x0c,0xba,0x30,0x54,0x17,0x26,0xc7,0xd0,0x85,0x27,0x45,0x92,0x80,0xb1,0xe7,0xf2,0x1e,0xae,0x35,0x1e +.byte 0x29,0x61,0x74,0x2d,0x55,0x22,0x04,0xfd,0xa2,0xf0,0x7c,0x15,0x9a,0x3e,0xee,0x5a,0xa3,0x1b,0x83,0xc0,0x45,0x1e,0x49,0x81,0xb1,0xa1,0xff,0x78,0x69,0xcf,0x95,0xc8,0x8d,0x3b,0x0f,0xfe,0x2e,0xde,0x6e,0x57,0x69,0x87,0xaf,0x30,0x88,0xbc,0x70,0x8c,0x79,0x84,0x9f,0x52,0x46,0x9d,0x34,0x3a,0xe5,0xe4,0x98,0x9f,0x43,0x77,0x40,0x99 +.byte 0x58,0xae,0x60,0xfd,0xef,0xc9,0x62,0x9e,0x89,0x7f,0xe3,0x2f,0x4e,0xdc,0xb8,0xb8,0x8d,0xdf,0x31,0x5f,0x73,0xed,0x42,0xdf,0x58,0xd0,0xe1,0x50,0x60,0xf1,0x04,0xab,0x3c,0x5c,0xe4,0x5f,0xc1,0xa1,0xeb,0x51,0x61,0x5b,0xab,0x47,0x71,0xbb,0xcc,0x14,0x6c,0xeb,0x84,0x4f,0x87,0xde,0x11,0x7d,0xb7,0x37,0x99,0x35,0xdb,0x31,0x4f,0x0e +.byte 0xfe,0xbb,0x16,0x7b,0x9c,0x62,0x33,0x33,0x98,0xaf,0x86,0x29,0x69,0xe7,0xc9,0x64,0x87,0x81,0xff,0xf5,0xbd,0xf0,0xe2,0x41,0xf9,0x24,0xe3,0xd3,0x55,0xa5,0xdc,0xf3,0x35,0xb4,0x3d,0x55,0x31,0x51,0x77,0xbd,0x1c,0xe4,0x46,0xe8,0x2b,0x5c,0xc9,0x35,0x7f,0x84,0xde,0x25,0x8c,0x61,0xff,0x09,0xd4,0x5f,0xd8,0x3b,0xa8,0x8b,0xa5,0xa9 +.byte 0xe8,0xa8,0xe2,0xef,0x82,0x6d,0x60,0x3e,0xc6,0x48,0x73,0x03,0x04,0x81,0x11,0x10,0xee,0x41,0xdb,0xc3,0xb9,0x78,0xd9,0xf0,0x32,0xa1,0xcc,0xa5,0x4a,0x67,0xe7,0x6b,0x21,0x6c,0x64,0x06,0x2c,0x8c,0x52,0x53,0xaa,0xb5,0x28,0x4d,0xd6,0xc6,0xa5,0x09,0x43,0x37,0xd6,0x73,0xfc,0xe7,0xf6,0x88,0x50,0xbc,0x81,0x7b,0xa5,0x92,0xa7,0x0b +.byte 0x86,0x5d,0x20,0x0c,0xbf,0x4d,0x1f,0x47,0xd1,0xd6,0x48,0xf4,0x64,0x55,0x99,0x7c,0x74,0x15,0x21,0xa8,0xeb,0x35,0xf2,0x86,0xc1,0x5e,0xbf,0x80,0x34,0x4b,0x44,0x38,0x21,0xd2,0x01,0x7d,0xf7,0x51,0x0c,0x02,0x03,0xe9,0x60,0xdf,0x80,0x36,0x40,0xfc,0x0a,0x96,0xbc,0x2e,0x88,0x8e,0xa4,0xa7,0x1c,0xc8,0x42,0x34,0xb5,0xd9,0xda,0xd7 +.byte 0x74,0x19,0xf7,0xff,0x0f,0x56,0x2c,0x02,0x48,0x92,0x5c,0x82,0xb3,0x7d,0x1d,0xef,0xd1,0xec,0x86,0x9b,0x3f,0xa8,0xb7,0xfa,0x02,0x44,0xb5,0x19,0x0c,0xce,0xd8,0x66,0xc6,0x48,0xbe,0x97,0xbd,0x4c,0x65,0x3a,0x09,0x5a,0x79,0xb9,0xa1,0x48,0xb4,0x2a,0x5d,0x10,0x61,0xac,0x17,0xd3,0xf6,0x13,0x1d,0x71,0x08,0x86,0xc8,0x4e,0xab,0xb9 +.byte 0x0d,0x6f,0x7f,0x79,0xe8,0xf8,0x85,0x68,0x8f,0xac,0x98,0x93,0xbf,0xe5,0xf6,0x84,0x5e,0x47,0x9d,0xc4,0x21,0xb6,0xf8,0x17,0x1a,0xb9,0xff,0x8f,0xfd,0xd8,0xc1,0x6f,0xb8,0x74,0xb9,0xfa,0x55,0xd9,0x33,0x3e,0x98,0x3d,0x0e,0x3b,0xfa,0x2c,0x13,0xf4,0xcb,0x2a,0x4e,0x74,0x33,0x6a,0x50,0x49,0xeb,0xb6,0x87,0xb2,0x8d,0x24,0x38,0xc2 +.byte 0x01,0x80,0xf7,0x7c,0x4e,0x8d,0xa5,0x79,0xed,0x43,0xd6,0x82,0x6a,0x2e,0x0a,0x6c,0xe3,0x58,0x26,0x7a,0xc2,0x68,0x84,0x78,0x5c,0x67,0x33,0x97,0x97,0xd8,0x7e,0xeb,0x40,0x9d,0x61,0x25,0x6a,0x2f,0x63,0x9c,0xae,0x05,0xcf,0xb5,0x39,0x4e,0xb0,0xdb,0xc9,0x2e,0x14,0x3c,0x6b,0xda,0x02,0x6f,0xf8,0x73,0xab,0xe4,0x1e,0xaa,0x2c,0x62 +.byte 0x41,0x65,0x5f,0x2c,0x5b,0xcb,0x56,0x8e,0x61,0x6a,0x57,0x21,0x8d,0xe5,0x8e,0x44,0x4f,0xfb,0x69,0x45,0x46,0x62,0xe3,0x12,0xe6,0x36,0x00,0x82,0x6a,0xa5,0x5e,0xfd,0x01,0xde,0xd1,0x9e,0xd7,0x3c,0x88,0x44,0x66,0x5d,0x0c,0x9f,0x0a,0x03,0xc8,0x79,0x96,0x54,0xf3,0x33,0x69,0x1e,0x98,0xe9,0x85,0x4a,0x8a,0xf7,0x3a,0x5e,0x02,0xe7 +.byte 0x88,0x23,0x41,0x08,0x4f,0x4b,0xf5,0xde,0x3a,0xbc,0x0d,0xfa,0xec,0xf2,0x74,0x63,0x51,0x4a,0x49,0xae,0x82,0xc0,0x9b,0x08,0x96,0x99,0x6b,0x13,0xb8,0x47,0x55,0x63,0x80,0xc0,0x41,0x83,0xf3,0x77,0x6b,0x76,0x0d,0xd6,0x32,0xbb,0x6f,0xfb,0xa9,0xfa,0x86,0x6e,0xe2,0xa3,0x0d,0x34,0x3c,0x8a,0x0d,0x06,0xbb,0x34,0x98,0xf2,0xad,0x2c +.byte 0x81,0xb8,0xd5,0x8e,0x78,0xa6,0x63,0xbd,0x3c,0x9e,0xb5,0x3b,0x2e,0xf4,0x28,0x57,0x06,0xe0,0xcf,0xef,0x4b,0x3e,0xfd,0x2e,0x6f,0xb8,0xff,0x5b,0x78,0x2e,0xa2,0x05,0xa5,0xcd,0x43,0x6f,0xf5,0xfe,0xe9,0xcd,0xda,0x48,0xfd,0x8f,0x74,0x0e,0x60,0x47,0x04,0xed,0x17,0xd8,0x67,0x7a,0x65,0x7f,0x45,0x0c,0x5f,0xf0,0x3a,0x6a,0x88,0x14 +.byte 0xb2,0x04,0xf6,0x95,0x1b,0x20,0xf3,0x94,0x77,0xaa,0xf3,0x57,0x09,0xbf,0x7e,0x1f,0x51,0x08,0x7e,0x7f,0x7c,0x9f,0xfd,0x33,0x47,0xb1,0x94,0x36,0x67,0x54,0x8c,0x2b,0x6c,0xb0,0x32,0xc5,0xc3,0x9b,0x9f,0x5b,0x71,0x94,0x20,0x86,0xc9,0x16,0x82,0xa9,0xe7,0xe4,0x58,0x63,0x7a,0x6a,0x25,0x0e,0x9f,0x00,0xc8,0x65,0x14,0xbf,0xf0,0x4e +.byte 0x33,0x9f,0x0e,0xe7,0x10,0x61,0x21,0x6c,0x9c,0xf0,0x42,0x52,0xb6,0x5c,0xcd,0xbf,0xe6,0x20,0xe6,0xa7,0x20,0xe9,0x94,0x8b,0x29,0x1f,0x33,0x93,0x1a,0xc6,0x49,0xfb,0x1c,0xb6,0x2c,0x12,0x4a,0x2a,0x31,0xc7,0xc9,0xd1,0x73,0x53,0xbe,0x02,0x6d,0x58,0x9b,0x0e,0xfa,0x90,0x84,0x40,0x58,0x06,0x99,0x6b,0xfe,0x4d,0xbb,0xe2,0x9d,0x09 +.byte 0x74,0x4f,0xf8,0x5d,0x59,0xbf,0xac,0x39,0xe5,0xf0,0xa2,0x89,0xf3,0x78,0xbe,0xb1,0x85,0x48,0xd6,0x1c,0x92,0x2b,0x85,0x87,0xc4,0xa6,0x81,0x64,0xf0,0xd1,0xe0,0x40,0xc8,0xd9,0x66,0xb9,0x06,0x21,0x8e,0x02,0x27,0x93,0xac,0xc3,0x79,0x20,0x43,0x62,0xa8,0xe1,0xcd,0x52,0x19,0xe5,0xf1,0x10,0x7a,0xc5,0x3e,0xe0,0x20,0xd0,0xc8,0x5f +.byte 0x47,0x41,0x97,0xe4,0x65,0x6f,0x89,0xf6,0x51,0x4c,0xd6,0x1b,0x71,0xd2,0x9a,0x1c,0xca,0x5a,0x9a,0xf2,0x44,0xed,0x3f,0x50,0xf2,0xf6,0x11,0x48,0x23,0xf9,0x82,0x90,0x5c,0x65,0x1a,0x2a,0xfc,0x9e,0x8b,0x64,0xa6,0x46,0x16,0x80,0xd4,0xcc,0xe2,0xd0,0xcd,0x7f,0x30,0xfd,0xd2,0x11,0xa1,0x5c,0x6f,0x7e,0x4b,0x81,0x03,0x98,0x85,0x44 +.byte 0x54,0x8a,0x9d,0x1b,0x5c,0x6c,0xe4,0xe3,0x61,0xe5,0x85,0xa7,0xfe,0x03,0x34,0xe0,0xed,0xff,0x46,0xba,0x0f,0xac,0x79,0x6d,0x47,0x60,0x08,0xba,0x95,0x8c,0xe6,0x7d,0x33,0xca,0x82,0x8a,0xe6,0x1e,0x1f,0xb4,0xba,0x49,0x51,0x05,0x2b,0x18,0xb3,0x7c,0x5f,0x12,0xa2,0x2f,0x96,0x28,0xab,0xe8,0x16,0xac,0xfe,0xa0,0x83,0xbd,0x86,0x1b +.byte 0x53,0xc1,0xab,0xed,0x42,0x2a,0x8b,0xaa,0x90,0x3f,0xcd,0x20,0xd7,0x9e,0xb8,0x3b,0xcd,0x5a,0xc9,0xea,0xbe,0xb2,0x7b,0x38,0xe4,0x16,0x95,0xaa,0xee,0xf6,0x1e,0xbd,0x1a,0x0f,0x89,0x96,0x35,0x0b,0x61,0xa9,0x87,0xca,0x35,0x27,0x25,0x1a,0xd6,0x31,0x8f,0xc4,0x10,0xf6,0xb7,0xff,0x3a,0x6a,0xb0,0xb7,0x7f,0x44,0x4c,0x08,0xaf,0x17 +.byte 0xe4,0x4a,0x0a,0x52,0x83,0x3e,0x11,0x53,0x7f,0x86,0x09,0x23,0xc7,0x46,0x3c,0x6d,0x66,0x2b,0xd0,0x82,0x08,0x02,0xa3,0x41,0x21,0x29,0x5e,0x68,0xa3,0x11,0xa9,0x8f,0x91,0xb9,0x60,0x87,0x22,0x37,0xfe,0x04,0xea,0x09,0x9f,0x96,0x6c,0x1e,0x67,0x31,0x9f,0x81,0xa9,0xeb,0xb0,0x1f,0xe0,0xb0,0xf4,0xf4,0xb9,0xa1,0x3f,0xb8,0xc7,0x83 +.byte 0x53,0x74,0x34,0x7b,0xfb,0xcd,0xf2,0x6e,0xe6,0xa3,0x26,0x86,0x57,0xb7,0x57,0xa2,0x24,0x43,0xd2,0xdd,0x9e,0x30,0xeb,0x3f,0xf5,0xa2,0x84,0x97,0xc0,0x23,0x63,0xee,0x84,0x8e,0x01,0xa2,0x57,0xf2,0xa1,0x48,0x6f,0x0f,0x19,0x31,0xae,0x26,0x08,0x4a,0x13,0x7e,0xde,0x85,0xb8,0x72,0xea,0x69,0x17,0x51,0x94,0x17,0x96,0xc1,0xc6,0x93 +.byte 0x10,0x38,0x0c,0xba,0xd1,0x86,0x57,0x5e,0x39,0xd5,0x7f,0x50,0x0e,0x94,0x8b,0xc4,0x1b,0x3d,0x40,0x3c,0xfb,0x49,0x48,0xf9,0xf4,0xd8,0x0d,0xb2,0x3a,0xa9,0xd9,0x29,0x31,0x57,0xc7,0x65,0x1e,0x86,0x77,0x9d,0x53,0x8c,0x60,0x83,0xb0,0xea,0x19,0x76,0x8e,0x02,0x73,0x69,0x2c,0xd6,0x25,0xbd,0x83,0xd1,0xf3,0xfd,0xb7,0x51,0x95,0x07 +.byte 0x51,0xf8,0x36,0xc9,0x8d,0xc1,0xec,0x47,0x3f,0xfa,0x19,0x8c,0xd5,0x07,0x20,0xd1,0x9f,0xff,0xb2,0x25,0x2d,0xe0,0xe4,0xa2,0xa3,0x29,0xbd,0x81,0x34,0xbf,0x60,0x04,0x8c,0x80,0x68,0xce,0x8b,0xbf,0xfa,0x50,0x12,0xdf,0x26,0x6c,0x9c,0x90,0x68,0xd9,0xfd,0x3b,0xc5,0x10,0xb3,0xd2,0xdf,0x17,0xae,0xf8,0xb0,0xe5,0xf3,0x44,0x5f,0x01 +.byte 0xbc,0x86,0x11,0x74,0xda,0x06,0x4b,0xac,0x49,0x75,0x77,0x65,0x38,0x97,0x1c,0x7c,0x8c,0x69,0x5b,0x9e,0x17,0x30,0x14,0x4f,0xf0,0x2d,0xd5,0xd6,0x78,0x56,0x27,0x96,0xe4,0xb8,0x69,0x1f,0xd5,0xaa,0x27,0x50,0x80,0x09,0xed,0x14,0x8f,0x36,0x48,0x32,0xfd,0x66,0x47,0x10,0xd9,0x8c,0xcf,0xa6,0xe6,0xd5,0x21,0x6a,0xe3,0x40,0xaa,0x4c +.byte 0xa2,0x0a,0xd6,0x2c,0x6f,0x79,0x10,0x8b,0x06,0xb4,0x01,0x91,0xce,0x62,0xfc,0xa0,0x53,0x3a,0xa0,0x65,0xe5,0xd4,0xe9,0xd6,0x91,0x04,0x55,0xa7,0xa9,0x75,0xc7,0x9c,0x13,0x45,0x16,0xcb,0x13,0x88,0xf4,0x08,0xa6,0xe9,0x8e,0x8a,0x84,0xd6,0x8c,0x83,0x5b,0xc5,0xf9,0xbf,0x1d,0xae,0x44,0xd3,0x74,0xa7,0x5d,0x29,0x03,0xf2,0x01,0xad +.byte 0xdb,0x3d,0xa2,0xcd,0xf0,0xf9,0xa1,0x27,0xe1,0xbb,0xe6,0x22,0x97,0x0e,0xb4,0x3a,0x09,0xba,0xaf,0x41,0xd5,0x6b,0x67,0x67,0x42,0x1c,0x93,0x52,0x5e,0x79,0x85,0x9b,0x59,0xaf,0x98,0xbb,0x3e,0xbe,0x18,0x0f,0x2a,0x52,0xd1,0xc9,0xb5,0x21,0x04,0x9f,0xee,0xe9,0x30,0x97,0x74,0x7f,0x71,0xfd,0xec,0x0d,0xfa,0x0e,0x32,0x75,0x8f,0x31 +.byte 0x3a,0x90,0x90,0xe4,0x0a,0x4b,0xb9,0xfc,0x55,0x02,0xfa,0x1c,0xbc,0xd7,0x30,0x24,0x1a,0x72,0x30,0x22,0xe9,0x61,0xf0,0xdd,0x60,0x55,0x69,0x8d,0x97,0xc1,0xfe,0x81,0x6a,0x16,0x8f,0x46,0x0b,0x1d,0xf5,0xc1,0xf7,0xf2,0xb6,0xf1,0x12,0x23,0x59,0x19,0xbd,0x3a,0xcd,0x57,0x34,0xfe,0x3b,0x1d,0xce,0xe5,0xe5,0xb7,0x90,0x65,0x2f,0x81 +.byte 0xcc,0xae,0x07,0x0d,0xe6,0xfa,0x5d,0x7c,0x5f,0x4f,0x45,0xed,0x90,0x05,0xe5,0xfc,0x10,0xb9,0x4d,0x2a,0x03,0x09,0xf9,0x9c,0x7a,0xd6,0x20,0xf2,0xb2,0x87,0xc0,0xde,0xba,0xea,0x78,0x69,0x8f,0x4d,0x6a,0x5d,0xc1,0x20,0x59,0x39,0x8a,0x9f,0x9d,0x8e,0xc4,0xad,0x93,0x4e,0x4f,0x03,0x6e,0x79,0xf7,0x5a,0x21,0x7d,0xa0,0xd4,0xce,0xe3 +.byte 0x0e,0xea,0xbd,0xd2,0x0e,0x16,0x89,0x0e,0x7f,0xec,0xc3,0x2a,0x21,0x86,0xb3,0x4f,0xb7,0xc4,0x1b,0x60,0xda,0x18,0xdb,0x73,0xda,0xbc,0x79,0xab,0xea,0xef,0xab,0xa2,0x59,0x89,0x76,0xce,0x72,0x51,0x41,0xf8,0xfe,0xa0,0xbb,0x38,0xf8,0x99,0xcd,0x9d,0x58,0xb9,0x6a,0xb5,0x5f,0xb7,0xa1,0x69,0xe3,0xb9,0x1d,0xfb,0x7a,0x1c,0xc8,0x21 +.byte 0x4d,0x11,0x57,0x1d,0xc0,0x45,0x21,0xba,0xa2,0xa3,0xbb,0x1a,0x34,0x17,0xaa,0xa1,0x0b,0x81,0xa1,0xb9,0xf0,0xba,0xf8,0xbf,0xb8,0x6a,0x8a,0x3c,0x75,0xf9,0x48,0x66,0x34,0x29,0xc3,0xc5,0x77,0x58,0x2e,0xdd,0xc1,0xd3,0x38,0x23,0xe0,0x92,0xe6,0x77,0xe5,0xf8,0xf4,0x70,0xe9,0x81,0xad,0x94,0xd3,0xce,0x69,0x97,0x2c,0x4b,0xc1,0xcf +.byte 0x83,0xc6,0xfb,0x89,0x7f,0xa7,0x28,0xfa,0xce,0xa4,0x6e,0x24,0x15,0x80,0x3b,0x9b,0x14,0x0d,0xc4,0x82,0x3f,0xdf,0xe9,0x40,0x81,0x7f,0xcc,0xb1,0xbb,0xa4,0xdf,0xee,0x56,0x7e,0xf7,0xe3,0x34,0xb2,0xfd,0xed,0x58,0x48,0xcc,0x1e,0x05,0x21,0x9f,0x30,0xf3,0xa9,0x24,0xe6,0xc3,0xdb,0x2c,0x72,0xfb,0xd6,0x0b,0xd7,0x84,0x64,0xd4,0x9b +.byte 0xf5,0x55,0xe5,0xb1,0xdf,0x01,0x07,0x5f,0xb7,0xd7,0xde,0x99,0x63,0x55,0x90,0x02,0x5d,0xef,0x86,0x91,0xa8,0x70,0x87,0x58,0xde,0xe8,0xa8,0xf1,0xf4,0x09,0x2d,0x44,0x19,0x4e,0x45,0x30,0x72,0xf9,0xc3,0xaa,0xc9,0x12,0x71,0xa5,0x63,0xa0,0x38,0x0b,0x77,0xa5,0x0a,0xef,0xf5,0xbb,0xbc,0xec,0xfd,0xb8,0x75,0x9c,0xfb,0x70,0x2a,0xe8 +.byte 0x71,0x3f,0xf7,0x39,0x56,0x69,0xe0,0x37,0xf7,0x94,0xfe,0x3a,0x7b,0x78,0x49,0x35,0x11,0x99,0xa2,0x70,0x66,0xbe,0xae,0x21,0x26,0xff,0x75,0x03,0x87,0xc2,0x7c,0xd7,0x29,0x5a,0x36,0x3f,0x73,0xba,0xba,0x08,0x5d,0x4b,0xc0,0xe0,0x76,0xb6,0x15,0x1b,0x9f,0xbb,0x01,0x0a,0xf6,0xf7,0x98,0x8b,0x4b,0x0e,0xbc,0x71,0x7a,0xd2,0x69,0x87 +.byte 0xe3,0x45,0xa6,0x41,0xd9,0x9d,0x64,0x90,0x7c,0x9d,0x12,0xf8,0xf0,0xc9,0x52,0x50,0x11,0x18,0x6b,0x9f,0x94,0x31,0x14,0x70,0x59,0xc3,0xb3,0xad,0x73,0x01,0x70,0xa7,0xb3,0xc7,0xcc,0xae,0x8a,0xc1,0x4e,0x62,0x1e,0xb1,0x4b,0x34,0xc9,0x11,0x73,0xb1,0x3f,0xbf,0xe2,0xe3,0xed,0xf1,0xab,0x07,0x87,0x3a,0xfb,0x1f,0x32,0x75,0x74,0x39 +.byte 0xba,0x2a,0xa6,0x82,0x33,0x27,0x60,0x94,0xc1,0x91,0x4e,0xaa,0x4d,0x99,0xcb,0xb2,0x5e,0xfa,0xdd,0x2d,0xf7,0xc3,0xf1,0x66,0x7d,0x0a,0xc3,0x8e,0x10,0x56,0x2e,0xde,0xc7,0xca,0x48,0xe7,0xaa,0x90,0x11,0x4b,0x60,0x57,0x2f,0xae,0xa5,0xe3,0x95,0x16,0xe3,0xac,0xab,0xc5,0x68,0xd3,0x71,0x2c,0xe0,0xdc,0x9d,0x48,0xe7,0x73,0x25,0xc9 +.byte 0xf7,0x16,0x3c,0x7f,0x25,0x4b,0x75,0x21,0xe1,0x20,0x1b,0x95,0xde,0xf8,0xba,0xa9,0x51,0xe9,0xce,0xec,0xa1,0x44,0x66,0x05,0x46,0xeb,0x6d,0x48,0x32,0x1f,0x13,0x25,0x61,0x2d,0xfc,0xb9,0x4d,0x88,0x70,0xdc,0x37,0xaf,0x1f,0xb4,0xb2,0x14,0x28,0x06,0xf4,0x51,0xcf,0x09,0x25,0xef,0x7d,0x68,0xac,0xb0,0x47,0x30,0x0a,0x33,0x32,0x05 +.byte 0xd7,0xbc,0xae,0x4a,0x92,0x8f,0xc8,0xe2,0xd4,0xec,0x03,0xe5,0xa2,0x92,0x78,0xd3,0xe8,0x9a,0x4a,0x07,0xe9,0x46,0x02,0x42,0xbc,0x9d,0x0f,0x63,0xf3,0x5a,0xba,0xec,0x0d,0x21,0x29,0x35,0x29,0xa5,0xfa,0x10,0xb6,0x29,0xf3,0xf7,0xd2,0xd3,0xb0,0x41,0xba,0x08,0x3f,0x52,0x21,0x74,0xe2,0x32,0x16,0x92,0x77,0x2b,0xca,0xeb,0xbe,0xe2 +.byte 0x15,0xda,0x39,0x4d,0x8c,0x4b,0x0d,0xf9,0xa1,0xa5,0x0f,0x2b,0xbd,0x17,0xe9,0x5c,0x8a,0x87,0x60,0xae,0xdb,0x1c,0x39,0x49,0x80,0x03,0x1c,0xc3,0xcc,0xd7,0xad,0xf9,0x92,0x38,0x08,0xc8,0x0c,0x38,0xff,0x84,0x29,0x5c,0x75,0xb2,0xf6,0x64,0x00,0x07,0x6c,0xb1,0x62,0x40,0x21,0xfb,0x7e,0xa0,0xb5,0xb4,0xbd,0x47,0x22,0x07,0x4b,0xdf +.byte 0x42,0x94,0x43,0x5a,0xe9,0x5b,0x61,0x16,0xdc,0x1a,0xb8,0x35,0x51,0x17,0x87,0xf9,0xac,0xee,0x4b,0x2c,0x03,0x53,0xc0,0xb4,0xd6,0x13,0x11,0xb5,0x1b,0x10,0x0c,0x54,0x1b,0x74,0xd9,0xf8,0x15,0x1e,0xc5,0x92,0x6c,0x4c,0x30,0x67,0x78,0xef,0xb9,0xd8,0xd7,0x5a,0xf2,0x4b,0x87,0x3c,0x65,0xd9,0xfd,0xa1,0xb0,0x2b,0xaf,0x69,0xc4,0x8c +.byte 0xbc,0x79,0x10,0x10,0xa2,0x43,0xfe,0x0a,0x2d,0xb3,0x6b,0xc8,0x7d,0x5c,0x80,0xab,0x9e,0xfd,0x4c,0x9b,0x32,0x50,0x2a,0x78,0x2f,0xfb,0xdc,0xc0,0x2e,0x61,0xff,0xbb,0xad,0xb8,0xfc,0x2b,0x8a,0x92,0x7b,0xdc,0xb9,0x1c,0x7e,0x89,0x5c,0xf5,0x4f,0xd8,0x69,0xf5,0x4f,0xe9,0x8e,0x5d,0x6e,0x52,0xa3,0x63,0x00,0x52,0xb6,0xbd,0x68,0x8f +.byte 0x63,0xb2,0x8a,0xc7,0xc8,0x37,0xd0,0xed,0x36,0x4a,0x18,0xba,0xb8,0x6b,0x0e,0x93,0xf5,0xca,0x86,0xcd,0x99,0xe4,0x8e,0xe1,0x20,0x23,0xe0,0xc1,0x06,0x73,0xae,0x21,0x25,0x36,0xdd,0xb8,0x52,0xb6,0x69,0x12,0x01,0xad,0xc5,0x72,0x22,0xa1,0xe0,0xae,0x19,0x56,0x0e,0xb5,0xcb,0xeb,0xc9,0x8a,0xf3,0x28,0x8b,0x8c,0x09,0x86,0xa0,0x8c +.byte 0x86,0xef,0xeb,0x73,0xbd,0x57,0x20,0xa7,0xe2,0x1e,0xa2,0x62,0x0e,0xa8,0xdf,0x2a,0x03,0x6a,0xe2,0x48,0xea,0xd2,0x6a,0xb1,0xa1,0x85,0x51,0xc7,0xb0,0xb0,0x45,0x17,0x24,0xef,0x0a,0x72,0xfa,0xb9,0x89,0x10,0x9e,0x47,0x5d,0xce,0x62,0x54,0xca,0xae,0x77,0x95,0xf0,0x65,0xb9,0xcd,0x6f,0xd6,0x81,0xdd,0xf7,0x6f,0x76,0x22,0xa4,0x2e +.byte 0x6c,0x14,0x2f,0xb8,0x4f,0x2b,0x5b,0xa5,0x2f,0xa8,0x07,0x15,0x20,0xf5,0xcc,0x7d,0x6f,0x2d,0x3e,0x8b,0x15,0x90,0xcd,0x73,0x34,0xec,0xfd,0x81,0x9a,0x09,0xa6,0x67,0xa0,0x4f,0xd7,0xff,0x3b,0xbd,0x5d,0x39,0xde,0xbf,0x26,0xd8,0xc1,0x3b,0x32,0x78,0x71,0x56,0x73,0x43,0xa2,0x16,0x7a,0xbf,0xc6,0xb3,0xfa,0xfe,0x96,0xfa,0xd4,0xc9 +.byte 0xbf,0xda,0x2a,0x16,0x35,0xb4,0x3f,0x46,0x12,0xb5,0xc2,0x7f,0xae,0xee,0x4e,0x06,0x67,0xa0,0x00,0x0c,0xd0,0x2e,0xa7,0xbe,0xd5,0x28,0x6b,0x95,0x59,0x4c,0x3a,0x42,0xb6,0x39,0x49,0x26,0x43,0x1e,0xe9,0x46,0x1c,0x7d,0x7f,0x45,0x9b,0x4c,0x2f,0x9f,0xa4,0x48,0xb2,0x20,0xe4,0x76,0x4c,0x58,0x19,0x69,0xda,0x98,0x92,0xbd,0x78,0x52 +.byte 0x57,0xe3,0xcd,0x77,0xf3,0x57,0x6f,0x97,0x6d,0x63,0xd0,0xee,0xae,0x93,0x19,0xbc,0xff,0xe2,0x66,0x72,0xbc,0xd3,0x75,0x65,0x1f,0xe6,0xbc,0xad,0x92,0x37,0x8d,0xa6,0xb8,0xca,0xf0,0xee,0x1d,0xa0,0xc4,0x9c,0x3c,0xa3,0x45,0x87,0x14,0x1e,0x06,0xab,0x97,0xd6,0x8c,0x7a,0xae,0xcd,0x8b,0xa6,0x60,0x7b,0x0f,0x2a,0x30,0xbe,0x34,0x41 +.byte 0xfd,0xf2,0x1f,0xc1,0x1e,0x4e,0x52,0xbf,0x32,0x3b,0x55,0xbf,0x12,0xb3,0x24,0x79,0x63,0xc7,0x48,0x4c,0x87,0x04,0xed,0x3c,0xf2,0x1b,0x95,0x32,0x0f,0x1c,0x60,0xfe,0x5a,0xc7,0x6a,0xbb,0x29,0x36,0x57,0x22,0x3c,0x6f,0x74,0xac,0x6e,0x40,0x12,0x17,0x4c,0x47,0x27,0xc9,0x03,0xdb,0x08,0xc6,0x84,0x15,0x83,0x63,0xe1,0xc8,0x00,0x3f +.byte 0xfc,0xe6,0x9c,0x66,0x0f,0x0c,0x8e,0xae,0x0c,0x5d,0xde,0x9f,0xba,0x11,0x35,0xe3,0x0d,0xba,0x18,0xbe,0x0b,0xbc,0x39,0xc3,0x84,0xa0,0xfd,0xc9,0x79,0x65,0xde,0x2f,0x80,0x38,0x34,0x16,0xc0,0x29,0xfe,0xf6,0x9e,0x7e,0x97,0x47,0x6f,0xd7,0xa0,0x79,0x3a,0xa7,0x3f,0x12,0x7a,0x0c,0x99,0x41,0x3d,0x75,0xd2,0x0e,0x38,0x56,0xb8,0xe6 +.byte 0x1d,0x3c,0x32,0xe0,0xa2,0xb6,0xee,0xd6,0xf3,0xaf,0x5a,0xe3,0xf6,0x27,0x42,0x68,0xfb,0x99,0xbe,0xc9,0xab,0x2d,0x90,0x53,0xd8,0x28,0x3a,0x7b,0x5f,0xad,0x83,0xea,0x86,0x6a,0x9c,0x22,0x96,0x0c,0x13,0xb6,0xb0,0x38,0xbb,0x67,0x89,0xba,0x82,0x8e,0xa7,0xf7,0xeb,0x93,0xaa,0x8c,0xd4,0x00,0xb0,0x62,0x57,0x84,0xf1,0x46,0xdb,0x3d +.byte 0x1b,0xdc,0x74,0xc4,0x8e,0x86,0x5a,0xd5,0x5d,0xd2,0xdd,0x17,0xf8,0x4f,0xcc,0x8d,0x4a,0x43,0xe5,0xd6,0x58,0x14,0xa3,0x61,0xf3,0xc3,0x52,0xe2,0x6a,0xce,0xd8,0x44,0x60,0x67,0xf2,0xcd,0xa1,0xb2,0xf6,0xb9,0xe0,0xc9,0x88,0xd4,0x1a,0xa2,0xd0,0x1d,0xe6,0x7b,0x20,0x20,0x89,0x80,0xdb,0x39,0x20,0x3d,0x4f,0xc2,0x58,0x2b,0x3c,0xd4 +.byte 0x90,0x20,0xea,0x43,0x9b,0xe3,0x64,0x1a,0xd3,0xd3,0xdc,0x40,0xb4,0x88,0x4b,0xca,0x23,0x66,0x9c,0x08,0x1f,0x9f,0xfb,0xca,0x9d,0xa1,0x88,0xe1,0x4f,0xb5,0xaf,0x43,0x00,0x02,0x0b,0x42,0xc5,0xd5,0xaa,0x27,0xcf,0xa0,0xdb,0x0d,0x60,0xbc,0x99,0xfb,0xdc,0xa9,0xb9,0xe3,0x3a,0x6a,0x49,0x02,0x16,0x41,0x43,0xf0,0x75,0x63,0xca,0xad +.byte 0xd6,0x93,0xc7,0x28,0xb7,0xb6,0x5b,0xf4,0x7d,0x5a,0x24,0x5c,0xa9,0xd8,0x7d,0xd4,0x7d,0x1c,0x8d,0x6f,0xab,0x0f,0x7f,0x38,0x4e,0x0c,0x68,0xca,0x1e,0x88,0xed,0x11,0x8d,0xd4,0x37,0xfd,0xce,0x6d,0xb1,0x77,0x2b,0x49,0xc6,0x10,0xde,0x6f,0x93,0x28,0xf6,0x2b,0x50,0x1f,0xf5,0x56,0x35,0x0e,0x7c,0xc5,0x52,0xc5,0x75,0xc4,0x2e,0x30 +.byte 0x3d,0x17,0xa9,0x41,0x45,0x29,0x77,0x3f,0x33,0xd8,0x7f,0xb9,0xd2,0x82,0x25,0xe9,0x51,0x6c,0xba,0x03,0x83,0xd1,0x48,0x7c,0x81,0x03,0x26,0x8e,0xad,0x58,0x8b,0xd1,0xda,0x94,0x32,0x17,0x67,0x98,0xac,0x1e,0x7b,0x06,0xc8,0x9a,0x5c,0x83,0xbc,0xbe,0x4b,0x5c,0x7d,0xce,0x76,0x2a,0xa0,0x24,0x5c,0x4e,0x9c,0x16,0x62,0xac,0xe5,0xa9 +.byte 0x38,0x60,0xcc,0xc1,0x51,0xb2,0xca,0xaf,0xac,0x33,0xe3,0x58,0x35,0x65,0x17,0x18,0x55,0x3f,0xd6,0xbc,0xfc,0xa0,0x48,0x65,0x31,0x41,0x6a,0x70,0x63,0x0b,0xc2,0xdb,0x12,0xc4,0xb2,0x20,0xbc,0xde,0x53,0xc4,0x12,0xb5,0xa9,0x77,0x23,0x99,0xc8,0x9c,0xe8,0x2b,0xc6,0x46,0xc3,0x64,0xc0,0x10,0xee,0xc7,0x24,0xd1,0xfb,0xd2,0xc6,0x62 +.byte 0xd2,0x7a,0x2b,0x5b,0xbb,0xfd,0x71,0xf9,0xf7,0xa7,0xb3,0xf6,0xe1,0xef,0x71,0xfc,0x5e,0xd9,0x69,0xe5,0x64,0x05,0xb1,0xcd,0x1e,0xa3,0x10,0x52,0xa3,0x95,0xf1,0x19,0xc5,0x50,0x57,0x5e,0xc8,0x76,0xd0,0xa7,0xc8,0xe7,0xa6,0x74,0x02,0x01,0x07,0x7a,0x27,0x17,0x55,0x46,0xd3,0x39,0xd5,0xea,0x12,0xc4,0x8c,0xcc,0xb8,0x13,0x8f,0x94 +.byte 0xde,0x5b,0x97,0x5e,0x2a,0x75,0x6e,0x45,0x05,0x7f,0x1f,0xea,0xab,0x48,0x62,0x3e,0x75,0xd6,0x58,0x6c,0xeb,0x18,0xad,0xcd,0x1d,0x6e,0x4a,0x54,0xf1,0x49,0x05,0x4f,0x2a,0x86,0x20,0x66,0xc6,0xd5,0xfd,0xc5,0xef,0x66,0x06,0x2b,0xe6,0x19,0x81,0xb6,0xda,0xcc,0xed,0x10,0x0c,0x4f,0x05,0xcd,0x0b,0xe2,0xf7,0x89,0x73,0xc7,0x7c,0x72 +.byte 0xc3,0xa4,0xf6,0xbf,0x88,0x27,0xff,0x24,0xdf,0x37,0xfb,0x86,0x9c,0x5f,0xba,0x2a,0xc1,0x5d,0x0d,0x40,0x8a,0x23,0x09,0x76,0x34,0x8e,0x6d,0x48,0x50,0xaa,0x1f,0x8b,0xfd,0x48,0xee,0xa0,0x7c,0xcf,0x45,0x42,0x0d,0x1f,0x04,0x09,0x1f,0x4b,0xe2,0x33,0xd1,0x24,0x71,0xc9,0xdc,0xd6,0xac,0x4d,0x01,0xc7,0xab,0x62,0xc1,0x42,0x99,0x5a +.byte 0x7d,0xb5,0x76,0xb5,0xf2,0xac,0x10,0x92,0xdb,0x7a,0x91,0x0b,0xd9,0xba,0x09,0x41,0x8f,0x13,0xfb,0xbf,0xdc,0x5a,0xbc,0x19,0x8d,0x92,0xa0,0xf6,0x9a,0xdb,0xde,0xbc,0xc0,0x7c,0x50,0xd2,0x8a,0x8e,0x5a,0x48,0xf5,0xf4,0x8e,0x0d,0xbe,0xfc,0x12,0xda,0xc2,0x33,0x05,0xa8,0x28,0x64,0xc3,0x14,0xc5,0xc4,0x6d,0x7c,0xa8,0x02,0xd3,0xf0 +.byte 0x58,0xf6,0x80,0x7e,0xbf,0xde,0x0e,0xe9,0x96,0xac,0xd1,0x12,0xd6,0x19,0x01,0xbb,0x20,0xcb,0x4b,0x10,0x7e,0xee,0xf9,0x79,0xab,0x03,0x01,0x0d,0x51,0xa9,0x94,0x0d,0xf5,0x2c,0xe6,0xb1,0x2e,0xf9,0x58,0x44,0x12,0xe5,0xc9,0xe5,0x73,0xbf,0xdf,0x6e,0xe6,0xfa,0x76,0x07,0x8a,0x00,0x58,0x0d,0x63,0x5f,0x09,0x98,0xec,0xd6,0x04,0x80 +.byte 0xb5,0x8d,0x30,0xb9,0xbd,0x99,0x80,0xb2,0xc3,0xd1,0x7e,0x15,0xfa,0xbf,0xb9,0x80,0x7e,0x5b,0xff,0xaf,0x81,0x47,0x6a,0xdc,0x39,0xb9,0xcb,0x1b,0x62,0x6f,0xbd,0xfd,0xbc,0xf7,0x42,0xf8,0x5c,0x70,0xea,0xaa,0x2a,0x6b,0x4e,0x4e,0xf3,0x8f,0x41,0x13,0x13,0xbc,0x8e,0x39,0x94,0x34,0xf1,0xb1,0x2b,0xbc,0x98,0x2d,0xf7,0xaf,0xec,0xc9 +.byte 0xb4,0x2f,0x4c,0x17,0x45,0xfd,0x9f,0x3c,0x39,0xdd,0xa5,0xe0,0x65,0x7a,0x9b,0xec,0x4e,0xe1,0xc5,0x97,0xda,0xc5,0x8b,0x9a,0x1a,0xbd,0xd6,0x69,0x84,0x58,0xde,0x36,0x6a,0x66,0xce,0x70,0xe4,0x71,0x0f,0x4b,0x02,0x48,0x7f,0x37,0x98,0x93,0x4a,0x63,0x96,0x7d,0x2d,0xf6,0xb1,0x54,0x8f,0x21,0xdd,0xf7,0x45,0xaf,0x31,0x7a,0x6b,0x43 +.byte 0xfb,0x38,0x92,0x48,0x29,0x93,0xcb,0x62,0x76,0x86,0x2d,0xf9,0x9d,0x73,0x3d,0x58,0xdb,0x8d,0x68,0xa9,0x98,0xa0,0xcb,0x51,0x86,0x14,0x2b,0x42,0x8b,0x00,0x2e,0x45,0x84,0x5a,0x73,0x99,0x31,0xbf,0x21,0x4e,0x71,0x0d,0xd0,0x43,0xbe,0x32,0xc5,0x35,0x3d,0xf7,0x9a,0x4f,0xf9,0x44,0xdf,0xc1,0xb4,0x9f,0x75,0x88,0xe8,0x42,0xb1,0xb1 +.byte 0x49,0x2e,0x0b,0xac,0xfd,0x67,0x1d,0xc4,0x3b,0xc5,0x60,0xc7,0x61,0x44,0x0a,0x35,0xc2,0x28,0x8f,0xe8,0x95,0x44,0xf8,0xf4,0xa4,0x41,0x14,0xac,0xe0,0xf0,0x36,0x30,0xa4,0xab,0x0c,0x13,0xeb,0x86,0xdf,0x9e,0x10,0x2c,0x29,0x4a,0x7b,0xad,0xe8,0x31,0x37,0xe0,0xcb,0xcb,0x8a,0xb7,0xcb,0xee,0x68,0x32,0x1f,0x10,0xc3,0xda,0x1d,0xeb +.byte 0x3b,0x69,0x1b,0xd5,0x40,0xb4,0x3d,0x03,0x0c,0xfb,0x8d,0x1d,0x04,0xbd,0xe9,0x08,0x61,0x4c,0x0d,0x36,0x6d,0x2c,0x67,0x97,0x1c,0xc7,0x4d,0x9d,0x06,0x0e,0x3c,0x04,0x6c,0x26,0xf9,0x1e,0xde,0xb5,0x31,0x28,0x35,0xb7,0x64,0x27,0xd1,0x46,0x47,0x2e,0xff,0x15,0xf1,0x13,0x0d,0x02,0x42,0xba,0xba,0xbe,0x4b,0xf5,0x3c,0x17,0xea,0x62 +.byte 0x62,0x90,0xa5,0xc7,0xb7,0x29,0xde,0xaa,0x1c,0x14,0x0d,0x6f,0x7c,0xc6,0xe0,0x68,0x5d,0xbf,0x73,0x12,0xe5,0xe3,0xdb,0x39,0x4a,0xb0,0x97,0xbc,0xee,0x3a,0x41,0x91,0xd7,0x4e,0x90,0x32,0x51,0xd7,0x34,0xea,0x97,0x12,0x8b,0xc9,0x27,0x40,0x73,0x6c,0xe9,0x9d,0x09,0x6b,0x4f,0x6f,0x85,0xdc,0x1e,0xda,0xb3,0xcf,0x27,0x46,0xcf,0x68 +.byte 0x5f,0xfa,0x4c,0x95,0x5d,0x26,0xf6,0x56,0xdb,0x96,0x3e,0x4d,0x93,0x62,0xe1,0xa9,0x4b,0x7c,0xcf,0xff,0x67,0xb4,0x76,0x1f,0xaa,0x44,0xb3,0xb8,0xf1,0xf3,0x3e,0x7f,0x38,0x46,0xab,0x49,0x1c,0x2f,0x50,0x47,0xb3,0x94,0xaa,0x8b,0x18,0xbf,0x3f,0xa8,0xa6,0x27,0xb7,0x72,0xb0,0xfa,0xd6,0xb8,0xc5,0x9d,0xc0,0xe6,0x16,0x75,0xc5,0xe9 +.byte 0x62,0x40,0x5b,0x0c,0x18,0x71,0x9c,0xcf,0xb7,0x77,0x02,0x03,0x94,0x20,0x23,0x45,0x8a,0xab,0x00,0x10,0x3b,0x89,0x74,0x6e,0x19,0x91,0xb9,0xcd,0x65,0x15,0x59,0xec,0x21,0x3a,0x26,0x20,0x6e,0x2d,0x98,0xa9,0x79,0x35,0xec,0x60,0x47,0x86,0xef,0x71,0x59,0x86,0x95,0x6e,0x2a,0x28,0xed,0x8a,0x68,0xfa,0xf8,0x2d,0x33,0x5c,0x2b,0x06 +.byte 0x07,0x2d,0x2a,0x45,0xd7,0xcf,0x18,0xb3,0x03,0x40,0x76,0x4c,0x79,0xa4,0x13,0x96,0xf2,0x9d,0x57,0x3e,0x1d,0x39,0x9c,0xcd,0x5b,0x9e,0xad,0xdf,0x72,0x4e,0x13,0x29,0xac,0xce,0xa1,0x79,0xfb,0xc4,0x24,0xe9,0x48,0xb2,0x05,0x83,0xa8,0x37,0xb6,0xa3,0xd7,0x76,0x08,0xd4,0x90,0x05,0x87,0x05,0x66,0x60,0x8f,0x4c,0xf6,0xc9,0x8f,0x3b +.byte 0x8d,0xe0,0x4a,0x54,0xc4,0xea,0x62,0x5c,0xac,0xde,0x56,0xdd,0xa7,0x4c,0x57,0x40,0xce,0xab,0x0b,0x21,0x66,0x43,0x48,0x29,0xec,0x4e,0x89,0x0c,0x87,0x26,0x9d,0xaa,0xd8,0x26,0xea,0x29,0x44,0x12,0x0e,0xd9,0xb1,0xb8,0x7b,0x13,0x5b,0xf6,0x17,0x69,0x3c,0x97,0x09,0xd1,0xf4,0xca,0xb0,0x74,0x32,0xea,0x94,0xda,0x74,0xb7,0x2e,0xe5 +.byte 0xa0,0x15,0x81,0xaf,0x4a,0x47,0x11,0xbb,0xf5,0x25,0xb0,0x13,0x83,0xde,0xdd,0xb9,0x59,0x1d,0x21,0x2d,0xff,0x5a,0x38,0x7f,0xde,0xff,0xd2,0x3f,0x51,0xdc,0x62,0x50,0x51,0xb4,0x86,0xda,0xe2,0x0f,0xc1,0xa1,0x6c,0x42,0xe5,0xcf,0x9a,0xd3,0x51,0x70,0x19,0xb7,0xd1,0x30,0xa3,0xad,0xb3,0x0e,0xcd,0x2a,0x6f,0xcc,0x44,0x65,0xc8,0x54 +.byte 0x44,0x5e,0xb2,0xf8,0x81,0xec,0xb5,0xc5,0x12,0x29,0x8f,0x4f,0x66,0x98,0x1b,0x03,0x98,0x03,0x9f,0x42,0x9c,0x87,0x2c,0x7c,0x9d,0xa4,0xbf,0x3e,0x91,0x1d,0xd0,0x4b,0xea,0x6c,0x33,0x5c,0x93,0xcf,0x8c,0x9b,0xcd,0x62,0x05,0x3d,0xf4,0x42,0xba,0x0b,0x15,0x45,0x50,0x9f,0x86,0xbb,0xb6,0x60,0x03,0x5a,0xbf,0x2b,0x17,0x30,0x5b,0x39 +.byte 0xfd,0x3f,0x80,0xc0,0x6a,0xee,0x36,0x82,0x09,0x28,0x10,0xd8,0x4a,0x86,0x3b,0xd9,0xaa,0x83,0xb6,0x83,0x69,0x31,0x32,0xcc,0x80,0x8a,0x79,0x23,0x60,0xf5,0x8d,0x01,0xaf,0x4e,0xe0,0x12,0xba,0xcc,0x31,0x04,0x6c,0x6a,0x8d,0x60,0xca,0xa1,0x14,0x01,0xf1,0xa3,0x7c,0x8b,0xcf,0xfa,0x3f,0x5a,0xac,0x83,0x73,0x2a,0xe4,0x31,0xb0,0x4f +.byte 0x62,0x18,0x29,0xc5,0x9a,0xdd,0x53,0xd3,0xa9,0x2a,0xc0,0x38,0x9a,0x54,0x99,0x4f,0x0f,0xf0,0x35,0x94,0x53,0x81,0xd6,0x32,0x66,0x17,0x14,0x74,0x5e,0x40,0xaf,0x4d,0x43,0x41,0x7b,0xe5,0x56,0x7b,0x30,0xbc,0x21,0x80,0x7b,0x88,0x16,0xfc,0x0b,0xb7,0x2c,0xd3,0x69,0x99,0x2d,0xb6,0xd0,0xdd,0x5b,0x87,0x4c,0xf9,0x34,0xde,0xd2,0xb1 +.byte 0xb7,0xd3,0x3b,0x06,0x60,0xb2,0x73,0x7e,0xd4,0x24,0x20,0x30,0xf0,0x9c,0x15,0x05,0x03,0xf5,0xc1,0x24,0x58,0x34,0x38,0x39,0x93,0x4b,0x39,0x01,0x98,0x61,0x6e,0x01,0xd4,0xf8,0x08,0xbe,0xe1,0xbd,0x61,0xde,0x2f,0x94,0xea,0x83,0xa1,0x39,0x2f,0xe6,0x26,0x03,0x43,0xf4,0x00,0x0b,0x64,0xcc,0xcb,0xcb,0x13,0xf0,0x02,0xa3,0x93,0xf6 +.byte 0xe9,0x3d,0xef,0x84,0x84,0xc3,0xb1,0x56,0x9e,0x4a,0x9c,0xea,0x94,0xce,0xae,0xa6,0xaf,0xbb,0x37,0xc1,0x63,0x06,0xa5,0x3c,0x32,0x9a,0x86,0x54,0xae,0xf4,0x6d,0x06,0x4c,0x72,0x5a,0xc3,0x28,0x35,0x1d,0xc8,0xa8,0x85,0x72,0x9e,0xaa,0x70,0x36,0x44,0xd2,0x80,0x0d,0xa0,0x42,0xfc,0xf0,0x89,0x0b,0x45,0x4e,0x79,0xc4,0x17,0x47,0x2c +.byte 0x9d,0x64,0x61,0x31,0xc0,0xcb,0x6b,0x34,0x5c,0xe7,0x45,0xea,0x6f,0x61,0x5e,0x9b,0x34,0x3a,0x6d,0xbc,0x92,0x0c,0x52,0x7e,0x4d,0x7f,0xe9,0xec,0x93,0x2e,0x76,0xbb,0x34,0x2b,0x97,0x49,0x2e,0xfb,0x5f,0x83,0xf8,0x8e,0x78,0xc8,0x18,0xb6,0x81,0x67,0x63,0xe3,0x19,0xab,0x7f,0xd3,0x86,0xbb,0x4e,0x74,0x45,0xf6,0xc3,0xbf,0xf4,0x24 +.byte 0x5b,0xae,0x5b,0xa0,0x6f,0xc4,0x30,0x19,0x70,0xfb,0x71,0x37,0x8b,0x80,0xd5,0xb6,0xfc,0xb0,0x3a,0xeb,0x29,0xfd,0xcf,0xfb,0x7e,0x1f,0x94,0xdf,0x34,0xa6,0x6f,0xfe,0x45,0x96,0x7e,0xa5,0x1b,0x1c,0xd1,0x7f,0x04,0x74,0xb1,0xc3,0x85,0x26,0xea,0xa2,0x25,0x80,0x07,0x21,0x2a,0x4c,0xf6,0x21,0xf7,0xad,0x3d,0xfe,0xca,0x98,0x7f,0xad +.byte 0xd6,0x83,0xf5,0x3f,0x9d,0xf3,0x3e,0x18,0x4b,0xff,0x8c,0xd7,0x8c,0xeb,0x9b,0xf0,0xd4,0xfe,0x65,0xd3,0x0f,0x49,0xfe,0x9c,0x2f,0x09,0xfb,0xcc,0xca,0x5c,0x73,0x22,0x75,0x98,0x6e,0x94,0xb7,0xe6,0xef,0xe4,0xf8,0xc7,0x40,0xa6,0x0a,0xbc,0x0b,0x0f,0x70,0x34,0xcf,0x5e,0xb6,0x07,0x1c,0xaf,0x79,0xf5,0xf0,0x9e,0x89,0x98,0x51,0x75 +.byte 0xe4,0x78,0x78,0x1b,0x32,0x65,0x5a,0x31,0xea,0x0f,0x17,0x3d,0x77,0x75,0x8e,0x99,0xd6,0x23,0xf6,0x26,0x5c,0x19,0x20,0xde,0xf7,0x64,0xdb,0xce,0x80,0x8b,0x5e,0xfc,0x64,0xf9,0x26,0xee,0xf8,0x17,0x38,0xf9,0x92,0x35,0xf1,0x9d,0x1a,0x5c,0x26,0xd9,0x9b,0x72,0x07,0x98,0xac,0xc3,0x07,0x33,0x62,0x17,0xae,0x0f,0x79,0x23,0x3d,0x1d +.byte 0x3e,0xc8,0x2f,0xc9,0xc4,0xe9,0x2c,0x64,0x9d,0xfe,0x70,0x28,0x7a,0x89,0xb7,0xa4,0xbd,0xfe,0x61,0x7b,0x64,0x6b,0xa3,0x38,0x59,0x70,0x0b,0xe6,0x6a,0x1f,0x0a,0xb5,0xcb,0xf8,0x0e,0x7a,0xb9,0x87,0x1a,0x44,0xf7,0xcd,0x20,0xcd,0x7e,0xeb,0x22,0x44,0x3f,0x5a,0x42,0xe1,0x8a,0xe4,0x22,0x13,0x2a,0xf1,0x34,0x81,0xa7,0xf8,0x76,0xfe +.byte 0x4c,0xeb,0x54,0xe3,0xe9,0xfc,0xe4,0xc5,0x68,0xf0,0x00,0x36,0x8a,0xad,0x7d,0xe5,0x16,0x7f,0xda,0xe8,0x88,0x55,0x25,0x98,0x6b,0x3c,0x3e,0xdc,0xe7,0xf3,0xe2,0x1d,0x66,0xde,0xf9,0xd8,0x08,0x25,0x81,0x4d,0xdc,0x76,0x1c,0xec,0x8b,0x13,0x83,0x47,0x8c,0x6c,0xd4,0x4e,0xce,0x28,0xdd,0x16,0x6a,0x10,0xa8,0x9b,0x21,0xce,0x70,0xfa +.byte 0xf6,0x3b,0x0e,0x8f,0x30,0x34,0xad,0xc8,0xe1,0x93,0xf6,0x2b,0xa3,0xb6,0xec,0x8c,0x65,0x03,0x34,0x20,0xba,0xea,0xac,0xad,0x11,0x47,0xa5,0x98,0xf4,0xd3,0x7f,0x53,0xa5,0xc3,0xe3,0x9f,0x6a,0xd5,0xaa,0xe2,0xf8,0x67,0xfe,0xec,0x30,0x8e,0x24,0x01,0x89,0x95,0x42,0x34,0x5b,0xfc,0x7d,0xff,0xb1,0xd4,0x5e,0x5c,0x1a,0x07,0xff,0xd1 +.byte 0xd8,0x95,0x43,0x97,0xc9,0xff,0x19,0x21,0xde,0x71,0x91,0x3f,0xfa,0xde,0x00,0xe0,0x7e,0xcc,0x32,0x95,0xb5,0xcb,0x56,0x1f,0x85,0xba,0x02,0x43,0xa8,0xad,0xb2,0xfe,0xdc,0x09,0xee,0xe9,0xb4,0x5b,0x13,0xbb,0x94,0xd3,0xad,0xa2,0x6a,0x6a,0x31,0x64,0x11,0xe0,0x7c,0x36,0xb9,0x21,0x8e,0x24,0xf8,0x85,0xa3,0xe8,0xc3,0x58,0xc6,0x63 +.byte 0x4c,0x4a,0x60,0x73,0x99,0xd0,0x83,0x48,0x49,0x1c,0xe9,0x52,0x56,0x51,0x02,0x12,0xc9,0xb8,0x4b,0x7b,0x13,0x83,0xd8,0x64,0xe0,0x21,0xde,0xb5,0xd1,0xe1,0x38,0x25,0x41,0xb7,0xfb,0x04,0x77,0xa0,0x76,0xd6,0x37,0xed,0xe9,0xcb,0x7a,0xae,0xd4,0xcf,0xb3,0x06,0xce,0x52,0x56,0xb8,0x41,0x35,0xf4,0x48,0x34,0xcc,0xde,0x8a,0xc2,0x0d +.byte 0x64,0x71,0xa7,0xd4,0x46,0x96,0x23,0x96,0xe9,0x5d,0x17,0x36,0x07,0xb1,0xa6,0xb3,0xda,0xc5,0x0f,0xdd,0xf2,0x35,0x14,0x40,0xab,0x05,0x08,0xf1,0xd1,0xa8,0xc0,0x1b,0xc3,0xa6,0x20,0xa5,0xea,0xd6,0xd7,0x5a,0xa4,0xec,0xa9,0x4a,0xe3,0x4a,0x66,0xc1,0xa0,0xcb,0x35,0x5e,0xc7,0x5f,0xdd,0xb6,0x0e,0xbb,0xa4,0x06,0xf9,0x43,0x8d,0x7d +.byte 0xec,0x3b,0xbb,0xd6,0x87,0xb6,0x1c,0x4c,0xd2,0x70,0x84,0x5f,0xed,0x53,0x9e,0xf5,0x9b,0x40,0xda,0xe9,0xbd,0x3f,0x70,0xa6,0x0f,0x91,0xa3,0x56,0xb2,0x83,0xb1,0x1b,0x85,0x4c,0x88,0xb8,0x81,0x37,0x43,0xdc,0x44,0x2a,0x68,0xc0,0xd9,0xc2,0xd5,0xa5,0x7f,0x09,0xab,0xa2,0x00,0x5b,0xb6,0xaf,0x41,0x40,0x65,0xe0,0x83,0x4e,0x72,0x13 +.byte 0x92,0x76,0x06,0x31,0xae,0xf8,0xf6,0x31,0xcf,0x12,0xe3,0xa4,0xa3,0x25,0xc1,0xf1,0x4e,0x28,0x59,0x30,0x72,0xb8,0x33,0x69,0x47,0xd7,0x4b,0xbe,0xe8,0xc3,0x36,0xa4,0xc1,0x3d,0xfc,0x59,0xdc,0x4a,0x94,0x3d,0x63,0x08,0xe8,0x56,0xd9,0x08,0x0e,0xdb,0x74,0x57,0x38,0x58,0xcc,0x98,0x07,0x0e,0xf8,0xe5,0xf1,0x9b,0x2c,0x1b,0x35,0xe5 +.byte 0xc4,0xee,0xc0,0x61,0xd8,0xc9,0x36,0xea,0x72,0x5e,0x55,0xe2,0xec,0xb0,0x1d,0x13,0xd7,0xd1,0x3f,0x11,0x2b,0x58,0xf4,0xdd,0x25,0xba,0x95,0x27,0xfd,0xdc,0x49,0x7e,0xb6,0x87,0x34,0x72,0x7d,0x21,0x8a,0x4e,0x26,0x62,0x9a,0x8a,0xd6,0xe4,0x8c,0x56,0x3f,0x19,0x0d,0x80,0xbb,0x5d,0xc5,0x73,0x56,0xf4,0x1d,0x9f,0xb0,0x8e,0x87,0x64 +.byte 0x51,0xf6,0xab,0xa1,0xa5,0x8c,0xf8,0xf4,0x39,0x8e,0x34,0xbb,0x54,0x49,0x2b,0xca,0x9e,0x47,0xbe,0xb5,0xc4,0x70,0xca,0x59,0x10,0x9d,0x57,0xd5,0x7c,0x48,0xdf,0x46,0xa3,0xf0,0xfd,0x9a,0x99,0x3c,0x84,0x95,0x36,0x39,0xbb,0x41,0xd3,0xab,0x6f,0x18,0x65,0x4b,0x10,0xe6,0x80,0xd2,0xd6,0xce,0x6a,0xd7,0xf6,0xd3,0x73,0x7e,0x35,0x9f +.byte 0x7b,0xe7,0x89,0x00,0x17,0x71,0xfd,0x15,0xf2,0x85,0xa9,0x93,0xbb,0x77,0x13,0xb2,0xf4,0xbb,0x9e,0x37,0x0a,0x5d,0x4d,0x25,0x53,0x38,0xf3,0xee,0x92,0xa3,0x02,0x56,0x2a,0xb8,0x1a,0x54,0x06,0x7b,0x65,0x37,0x5c,0x90,0x39,0x3e,0x67,0x97,0x21,0xd1,0xac,0xd3,0xab,0x6e,0xa6,0x2a,0x19,0xc6,0x26,0xf8,0x12,0xc2,0xd5,0x9a,0x22,0xd8 +.byte 0x9d,0x42,0x32,0x4b,0xe1,0x22,0x8c,0x3c,0x2a,0xe8,0x81,0x0d,0x05,0x87,0xce,0xf0,0x30,0x05,0x57,0xf0,0xef,0x18,0x52,0x62,0x28,0xd5,0x89,0xed,0x54,0x64,0xa4,0x1d,0x62,0x75,0x09,0x85,0x48,0x95,0xfe,0x84,0x3c,0x85,0x4e,0xa7,0x27,0x38,0x3e,0x83,0x0e,0x0c,0xfe,0xa7,0x6d,0x1e,0x2f,0x3f,0x7b,0xa5,0x44,0xc7,0xd9,0x10,0xdc,0xa9 +.byte 0x27,0x16,0xda,0x75,0x49,0x12,0xde,0xa8,0x3e,0x3b,0x29,0x92,0x93,0xb1,0x0b,0xa7,0xc2,0x74,0xb4,0x0a,0x35,0xbc,0xac,0x29,0x87,0xde,0xd3,0x3f,0x73,0x4f,0xab,0x6a,0xd8,0x35,0x49,0x47,0xc7,0x07,0x85,0x53,0x48,0xe9,0x31,0xe3,0x4c,0x9f,0x64,0x5e,0xcd,0x01,0x82,0xbd,0x61,0xdc,0x47,0x82,0xc4,0x9b,0x4d,0xa4,0x6a,0xe4,0xc5,0x02 +.byte 0x90,0x3f,0xd6,0x42,0x58,0xe2,0x7a,0xed,0x23,0x47,0x3e,0x93,0x6c,0xa4,0xf9,0xb8,0x60,0x5b,0x35,0xe2,0x8a,0x4d,0xdd,0x18,0x75,0xee,0x0f,0xd7,0x47,0x6a,0x9b,0x32,0xda,0x62,0x90,0x12,0x77,0x9b,0x00,0x30,0x3a,0x78,0x3d,0x70,0x30,0xde,0x5d,0x3d,0xe4,0x4f,0xef,0x9d,0x06,0x97,0x93,0x1e,0xfe,0x10,0xf7,0xd6,0x23,0x93,0x2f,0x52 +.byte 0xd7,0x22,0xd0,0x45,0xe8,0x4d,0x28,0x9d,0x52,0x2f,0x11,0x64,0x0e,0x99,0xa3,0x40,0x93,0x3a,0x02,0xf9,0x4c,0xee,0xd9,0x59,0x33,0x0b,0x06,0xef,0xda,0x0c,0x35,0x74,0xfe,0x42,0x34,0xdd,0x64,0xf0,0x08,0x46,0x92,0xc4,0x40,0x12,0x58,0x3f,0xa9,0x2e,0x72,0x25,0x93,0xdf,0x39,0xe1,0x8d,0xb5,0x1a,0xf8,0xe0,0x70,0x8b,0x38,0x12,0xc0 +.byte 0xa2,0x2e,0xa2,0x4e,0x33,0x82,0x6f,0xe4,0xe0,0xf3,0x91,0x5c,0x79,0x23,0xf4,0x05,0x77,0x09,0x0b,0x78,0x29,0x85,0x1b,0x99,0xa4,0xc5,0x6c,0x90,0xb3,0x2c,0xb6,0x79,0xe7,0xa8,0xe5,0xa8,0x5a,0xd5,0x10,0xc7,0xca,0x12,0x84,0x18,0x37,0x83,0x79,0x5a,0xa2,0x9d,0xd4,0xe8,0xc0,0xd2,0x88,0xf9,0x24,0x87,0x18,0x0e,0x8c,0x28,0xd6,0x8f +.byte 0x58,0x50,0x10,0xcc,0x1d,0x20,0x76,0x8d,0x1a,0xf0,0x2a,0x99,0xa3,0x81,0xb6,0xa8,0x88,0x3d,0xcf,0xc0,0x60,0xc4,0x44,0xb7,0x04,0xb6,0x2a,0x18,0xf5,0xf4,0x63,0xf9,0x7d,0x64,0x93,0x98,0xcf,0x48,0x80,0xc6,0xdc,0xf6,0x39,0x0c,0x62,0x85,0x51,0xea,0xe2,0x4c,0x9f,0x82,0x5e,0x89,0x39,0xd7,0x97,0x72,0x34,0x36,0x98,0xad,0x79,0x65 +.byte 0x56,0x22,0x59,0xe9,0x9f,0x4d,0x05,0x04,0x6a,0xc7,0xde,0x2b,0x61,0xe1,0xe0,0x05,0x49,0xb8,0xc7,0x4c,0x08,0x92,0xf5,0xdc,0x2f,0xc0,0x66,0x40,0x35,0xdb,0xab,0x1a,0xfb,0xbb,0x5c,0xe1,0x83,0xc9,0x88,0x4c,0xa0,0x65,0x8f,0x25,0xb6,0x15,0x93,0x11,0xbc,0x32,0x45,0x22,0x52,0x62,0x4d,0xc0,0xc1,0xb1,0xc3,0x60,0x65,0xda,0xf9,0x09 +.byte 0x52,0xe7,0x9c,0xcf,0x75,0x28,0x37,0x30,0x06,0xdf,0x3b,0x63,0x30,0x06,0x27,0x28,0xea,0x48,0x76,0x10,0x9b,0x69,0x99,0x99,0xd5,0x9b,0x0b,0x01,0x57,0xdb,0xdb,0x50,0x6d,0x54,0xf3,0x52,0xf6,0x9b,0x02,0x2d,0x10,0x70,0x37,0x37,0xbe,0x07,0x44,0xc5,0xd0,0xa5,0x1b,0x3d,0x42,0xba,0xeb,0x4a,0x87,0xdf,0x36,0x1e,0xe3,0x9d,0x77,0x63 +.byte 0xc7,0xd5,0x97,0xdf,0x24,0x95,0x6f,0xf3,0x94,0xc6,0xb1,0xf1,0xc7,0x60,0x3e,0x98,0x74,0x63,0x24,0x9c,0xb9,0x5f,0x04,0x41,0xbf,0x7c,0xf4,0x6d,0x20,0x30,0x6b,0xde,0x1b,0x01,0x31,0x05,0x33,0x10,0xb1,0xec,0x9d,0x2f,0xfe,0xe9,0x8c,0x1a,0x04,0x24,0x14,0x71,0x11,0xcc,0x21,0x30,0x27,0x3e,0x9c,0x98,0x88,0xfa,0x7b,0xd5,0xe2,0x43 +.byte 0x1f,0x61,0xd7,0x57,0x66,0x0c,0x34,0x7a,0x1d,0x96,0x06,0x90,0x7b,0xca,0xf1,0x01,0x1e,0x20,0x6d,0x1e,0x19,0x1e,0x5f,0xde,0xe2,0xaa,0xfb,0x9c,0xd9,0x00,0x65,0x2b,0x90,0x02,0x9a,0x84,0x66,0xd7,0x7f,0x65,0x3f,0x03,0xf2,0x03,0xf3,0xd8,0x17,0xda,0xf9,0x04,0x82,0x11,0x72,0x90,0x0c,0x44,0x6d,0xde,0x51,0xae,0xa5,0xaf,0x19,0x50 +.byte 0xc5,0x41,0x5d,0x05,0xb4,0x9f,0x48,0x20,0xbe,0x7d,0x48,0xb7,0xda,0x1f,0x90,0x77,0xe3,0x53,0x25,0xc7,0xed,0x3b,0x85,0xa5,0x7e,0x4d,0xe8,0x1f,0xa3,0x6f,0x2f,0x72,0x92,0x1f,0xe5,0x7c,0x34,0xcb,0xbc,0xd7,0xbf,0x01,0x20,0x9d,0xc6,0x7e,0xec,0x6d,0x51,0xf7,0x6d,0xd8,0xe6,0xb8,0xbe,0x32,0x8e,0x65,0xaf,0xea,0xae,0xcb,0x03,0x74 +.byte 0x1f,0xb6,0x7a,0xdf,0xfc,0xcf,0x19,0xcf,0x75,0x3d,0xd6,0xda,0xee,0xf7,0xde,0xcf,0x1d,0xc2,0xbb,0x2e,0x30,0xf0,0x3d,0xda,0x18,0xaf,0xcd,0x7f,0x06,0x17,0xea,0x7f,0x4d,0xda,0x9b,0x9a,0xcb,0xcd,0x4d,0x3d,0x6b,0xb2,0x57,0x4e,0x8b,0x0e,0x5f,0x6b,0x58,0x13,0x6b,0xef,0x2e,0x66,0x26,0x0d,0x6b,0xd8,0xf8,0xbe,0x83,0xc9,0xd0,0x48 +.byte 0xed,0xe4,0x03,0x05,0x81,0x13,0x82,0x64,0x9e,0x5c,0xc9,0xaf,0x84,0x90,0xd5,0x4b,0xec,0x02,0x1c,0xcd,0x32,0x3f,0x0b,0xc6,0x39,0x2c,0xcf,0xf7,0x86,0xbd,0xc0,0x06,0xe8,0x75,0x4b,0x45,0xa8,0x47,0xfc,0x19,0x6b,0x93,0x87,0xb3,0x4a,0x80,0x18,0xcd,0xba,0x1e,0x05,0xf6,0x16,0xb5,0xae,0xbd,0x40,0xd0,0xf1,0xd5,0xe9,0x0c,0xf5,0x89 +.byte 0x0c,0x6f,0x9c,0x4e,0x75,0x72,0x48,0x7a,0x00,0x78,0xcb,0xf8,0xd7,0xce,0xb8,0x85,0xa6,0x62,0x6d,0x38,0x9c,0x83,0x64,0x03,0x4e,0xee,0xe6,0x62,0xe4,0x2a,0x40,0x86,0x99,0x62,0x76,0x0e,0x43,0x02,0x70,0x78,0x2d,0xa4,0xb5,0x6c,0x87,0x43,0xcc,0x04,0x4b,0xf5,0x46,0xdc,0x79,0x55,0x7e,0x27,0x0a,0x22,0x5a,0x2c,0x53,0xc3,0x23,0x48 +.byte 0x17,0x16,0x44,0xf0,0x1d,0x40,0xa2,0x10,0x13,0x5d,0x44,0x54,0x14,0x77,0x6f,0x04,0xa2,0xa7,0x08,0x92,0xaa,0xd5,0x82,0xb4,0x74,0xa7,0xe1,0xe4,0x17,0x5e,0x9c,0x9c,0x88,0xab,0x24,0x9e,0x60,0xe7,0xe8,0xb2,0xf3,0x11,0x28,0xa9,0x9e,0x5f,0x21,0x14,0xe3,0x4d,0xc3,0x29,0xd2,0xc6,0x84,0x17,0x1b,0xa3,0x65,0x6d,0x4e,0x93,0xc7,0x61 +.byte 0x30,0x53,0xd9,0x6b,0xc0,0x82,0xf4,0x7e,0xf4,0x79,0xff,0x59,0x06,0x6e,0xe1,0xea,0x45,0x3c,0x0f,0xfe,0x89,0x0d,0xa1,0x5e,0xbc,0x98,0x0c,0x0e,0xb9,0x21,0xc3,0xe8,0xd2,0xf1,0xd9,0x90,0x3c,0x9c,0xee,0x89,0xbd,0xb2,0xa6,0x21,0xfd,0xfc,0x1a,0xd2,0x3e,0x05,0xc5,0xb5,0x92,0xb1,0xb8,0xf2,0xab,0xb8,0x19,0x2b,0x83,0x80,0x8c,0xda +.byte 0x43,0xef,0x16,0xef,0xed,0x15,0xe4,0x62,0xab,0x31,0x55,0x29,0xd5,0x2b,0xad,0x3b,0xb6,0x5a,0xc3,0x72,0x25,0x0c,0xfd,0x54,0x9e,0x4e,0x34,0x6f,0x77,0x6c,0x80,0x85,0x4a,0x7c,0xe3,0xb0,0x36,0x59,0x6b,0x3c,0xd9,0xf9,0x44,0x65,0xb6,0x4f,0x99,0x54,0xa4,0x73,0xef,0x4a,0xa8,0x41,0xab,0x66,0x42,0xfb,0x0e,0x3d,0x6f,0x8d,0xed,0x98 +.byte 0x8f,0xdb,0xa1,0x51,0x5b,0xdc,0x16,0xc9,0x38,0xbf,0x07,0x1c,0x6d,0xb0,0x1f,0x23,0x3f,0xc5,0x9d,0xc4,0x6c,0xcf,0xd5,0xad,0x7d,0x8c,0xc6,0x59,0xe1,0x7d,0x65,0x0c,0x7c,0xd1,0x57,0x4b,0x92,0x30,0xe8,0xcd,0x81,0x4f,0xba,0x49,0xcc,0xb4,0x54,0xe8,0xc4,0x1e,0x73,0x3b,0x86,0x4f,0xfb,0x4d,0xcd,0xbc,0x13,0x8c,0x64,0x3d,0xdd,0xd5 +.byte 0xed,0xb0,0xd3,0xdd,0x4f,0x1b,0x53,0xeb,0xc7,0x20,0xac,0xcd,0x69,0xa6,0xf0,0xfd,0xe5,0xfc,0xe6,0x68,0x17,0xcc,0xa9,0x97,0x44,0xe4,0x56,0x14,0xc6,0xa3,0x89,0xc0,0x0e,0xaa,0x64,0xd0,0x6b,0xbb,0xd3,0xcc,0xca,0xf2,0xe0,0x13,0x1a,0x46,0x39,0x71,0x60,0x91,0xe1,0xda,0x63,0xb5,0xd3,0xd9,0x02,0xa1,0x4d,0xc0,0x4d,0xc6,0x25,0xf8 +.byte 0x8a,0xc5,0xf3,0x9c,0x64,0x74,0xb8,0xbf,0x31,0x4a,0xb6,0xbe,0xd3,0x63,0x5e,0x3f,0xce,0x57,0x37,0x43,0xff,0xb9,0x84,0xdc,0x6b,0x8d,0xfc,0xe3,0x7c,0x01,0x2a,0x81,0x2b,0x8c,0x78,0xf4,0x7e,0xe4,0x80,0x26,0xc5,0xd8,0x01,0x87,0x3f,0xe3,0x33,0x46,0x96,0x67,0xda,0x9c,0x2b,0x41,0x3e,0x9a,0x3e,0x51,0xef,0x63,0x73,0x36,0x4e,0x30 +.byte 0x65,0x37,0xd1,0xb2,0x50,0xad,0xa7,0xf1,0xca,0x5b,0x11,0xeb,0x56,0x23,0xee,0x65,0x1d,0x5d,0x08,0x68,0x0f,0xb9,0xcf,0xca,0x16,0x7b,0x02,0xf0,0x47,0xe5,0x99,0x14,0xa0,0x67,0xf3,0xfc,0x86,0xf9,0x82,0xdf,0x20,0xd4,0xf9,0x7c,0x4d,0x08,0x06,0x0f,0x1a,0x9d,0x11,0x08,0x13,0xfd,0xb5,0xc5,0x3f,0xff,0xce,0xcf,0x68,0x5f,0xe8,0xae +.byte 0x3e,0x9d,0x04,0x94,0xde,0xe2,0x49,0x45,0x6c,0xd7,0xb0,0x79,0xbd,0xc3,0xba,0xb8,0x58,0xbf,0x4f,0x0f,0x56,0xb5,0x39,0x92,0x36,0xd9,0x8e,0x7e,0xac,0x4d,0x9c,0xf9,0x30,0x97,0x71,0xcd,0x1b,0x40,0xf5,0xb8,0xb3,0xeb,0x33,0xf7,0xd9,0xde,0xb3,0x1c,0x7a,0xe1,0xda,0x00,0x43,0xe3,0x17,0x40,0x80,0x49,0x42,0x64,0xe9,0xf6,0x7e,0xe9 +.byte 0xeb,0xc7,0xcd,0xf2,0x5e,0xcf,0xfd,0x60,0x08,0xd4,0x13,0x48,0xa9,0x4d,0x38,0xc9,0x14,0x48,0x98,0xef,0x74,0x50,0xa0,0xe4,0x2c,0xdb,0xba,0xb3,0x9a,0xbc,0xd1,0xc6,0x36,0xc3,0x5e,0xa7,0x8e,0xec,0x38,0x8d,0x95,0x32,0x8c,0x90,0x48,0xe0,0x26,0x81,0xe9,0xe3,0xfb,0xdb,0xbf,0x61,0x4f,0xa4,0x69,0x2e,0x57,0x90,0x9b,0xb2,0x0a,0x91 +.byte 0x59,0x0b,0x83,0xed,0x15,0x3c,0xad,0xdf,0x99,0x59,0xc6,0x2f,0x8a,0xc6,0xcf,0xb4,0x3f,0xef,0x6e,0xe7,0x03,0x8a,0x95,0x34,0x32,0xbd,0xb4,0xda,0x23,0x64,0xae,0x5b,0xcf,0x95,0xa7,0x8d,0x55,0xd2,0x8c,0x3f,0x0a,0xcb,0x43,0x9f,0xf2,0xf2,0xa7,0x53,0xcd,0x7b,0xa7,0xa3,0x63,0x6d,0xae,0x87,0xec,0x01,0x19,0x6f,0x30,0x32,0x88,0xaf +.byte 0xda,0x33,0x09,0xc7,0xf3,0x04,0xed,0xb9,0xc4,0x26,0x5e,0x59,0x9a,0x36,0xc6,0xb0,0x48,0x3b,0x6f,0x47,0x77,0x9e,0xaa,0x65,0x4b,0x3b,0xad,0x61,0x83,0x9a,0x60,0xb0,0xd3,0x1a,0x3a,0x75,0x60,0x6a,0x97,0x48,0xb5,0xc4,0x52,0x7f,0x21,0xef,0x81,0x56,0xc8,0x5c,0x45,0x38,0x32,0xa9,0x01,0xc3,0xdb,0xc3,0x3a,0xcf,0xa6,0x0d,0xcd,0x8b +.byte 0x05,0xf8,0x8a,0x9b,0xca,0x54,0x5c,0x54,0x9b,0x34,0x04,0x79,0x22,0xdc,0xe4,0x02,0x8f,0x8c,0x90,0x62,0xd6,0x4e,0xb2,0x25,0xfd,0xab,0x73,0xcc,0xa8,0x4b,0x2a,0xf8,0x2f,0x95,0x94,0x53,0x1f,0xf4,0x7c,0x5a,0x47,0xaa,0x36,0xfa,0xba,0xcd,0x00,0x69,0xa1,0xdb,0x55,0xbd,0x2f,0xb9,0x2b,0x17,0x04,0x6b,0x54,0xe1,0x5d,0xa6,0x63,0x81 +.byte 0x2e,0x70,0x73,0xff,0x00,0xdf,0xa7,0x26,0x1d,0x7b,0x18,0xdb,0x49,0xbe,0xaa,0x87,0x91,0x0c,0xbb,0xed,0x87,0x8e,0x55,0x8b,0x3c,0x70,0x95,0x31,0xd2,0x1f,0x15,0x65,0xaa,0x5f,0xe0,0xb2,0x14,0x03,0x2f,0x99,0xff,0xaa,0xfe,0x83,0x5b,0x4c,0xdb,0xa9,0xce,0x28,0x78,0x71,0xf2,0x2e,0x1b,0x6f,0xa8,0x53,0x0b,0xa3,0x8f,0x9e,0xb0,0xd1 +.byte 0x94,0xed,0x24,0x0c,0x5d,0xa6,0xf8,0x06,0xd6,0xf1,0xb5,0x3d,0x59,0x4f,0x6a,0x87,0x23,0xc9,0x75,0xb5,0x84,0xee,0xb0,0x23,0x43,0x3e,0x77,0x66,0x73,0x7c,0x8f,0xe4,0x1d,0x79,0x34,0x6d,0x11,0xfa,0xd8,0xe3,0x28,0xa0,0x25,0x91,0x73,0x18,0xec,0xb7,0x67,0xa6,0x02,0xa0,0x3f,0xac,0x02,0x13,0x09,0xfa,0xca,0x7f,0xea,0x46,0xaf,0x10 +.byte 0x61,0x15,0xf2,0x53,0xec,0xe3,0xb3,0x8b,0x0b,0xac,0x4c,0xbb,0x57,0x28,0x40,0x7b,0xef,0xf6,0x40,0xf1,0x2b,0xaa,0xe7,0x28,0xad,0xf6,0x95,0xca,0x1f,0x10,0x0e,0x8e,0xc8,0x79,0xfb,0xa8,0x92,0x25,0xfd,0xdb,0x0e,0x23,0x11,0x56,0xa9,0x94,0x01,0xa6,0xa3,0x02,0x74,0xd3,0xdd,0x38,0x27,0x33,0x03,0xb6,0x60,0x10,0x37,0x31,0xa8,0xd7 +.byte 0x0b,0x01,0x9f,0xe4,0xbe,0x0e,0xb9,0x87,0xb5,0x91,0x6f,0xc7,0xd6,0x02,0x6f,0x8e,0xba,0x89,0x9a,0xd3,0x55,0x7c,0x04,0x10,0x92,0xa9,0xe4,0x50,0xfb,0x4a,0x60,0xca,0xc7,0x87,0x02,0x34,0x43,0xc3,0x14,0x98,0x62,0x3f,0xea,0x94,0x92,0x70,0xd8,0x91,0xe5,0xf7,0xdc,0x91,0x4b,0xb7,0xfc,0x6c,0x7f,0xb6,0x55,0xfb,0x91,0xdf,0x91,0x2e +.byte 0x22,0x89,0xbb,0xf3,0x5f,0xb3,0x15,0x33,0x1e,0x8f,0x0a,0x98,0x28,0x61,0x15,0x0a,0x3b,0x0a,0xd1,0x21,0x85,0xfd,0x60,0x9a,0x51,0x5a,0x05,0x4f,0x57,0x59,0xdf,0xda,0x9f,0x08,0xe4,0xe1,0x0e,0xee,0x7b,0x3a,0x71,0x05,0x0b,0xad,0xb0,0xd1,0xbb,0x5b,0xe3,0x05,0xe6,0x25,0x42,0xf4,0x82,0x4d,0x5f,0x1d,0x23,0xe6,0x16,0xc8,0x60,0x20 +.byte 0x37,0x27,0xca,0x65,0xe7,0x12,0xa8,0x0b,0xbc,0x37,0x93,0xe9,0xec,0xae,0x98,0x17,0xd1,0x96,0xe7,0xfe,0xf6,0xda,0x18,0x40,0xab,0x81,0x38,0x6e,0x83,0xcd,0x49,0x3c,0xe5,0xcc,0xf6,0x97,0x45,0xf9,0x4d,0x31,0x33,0x40,0xf2,0x07,0xef,0xae,0x9b,0x1f,0xab,0xde,0x07,0xb9,0xa1,0x43,0x86,0x80,0xd0,0x54,0xb1,0x44,0xce,0x91,0xaf,0x0c +.byte 0xdc,0xa7,0x83,0xda,0x73,0x44,0xb2,0x5c,0xe2,0xf0,0xf5,0x88,0x95,0xe1,0x36,0xcb,0x37,0x0a,0x61,0x6d,0x56,0x69,0xdf,0x95,0x79,0x97,0xb0,0x86,0x8b,0x96,0xbf,0xe8,0x89,0xfc,0x8f,0xc9,0x41,0xe3,0xe4,0xd3,0xf0,0xed,0xd1,0x97,0xd1,0x5e,0xa8,0xcf,0x71,0x4d,0xd5,0x72,0xd0,0x94,0x48,0x86,0xba,0x0d,0x6c,0xe0,0xf1,0x81,0x74,0x6a +.byte 0x0d,0x75,0xc8,0xd3,0xbc,0xd8,0x8d,0xa9,0xf5,0x44,0xc2,0x5f,0x45,0xa7,0xd1,0x9a,0xd1,0x5a,0xc7,0x39,0x9a,0x62,0x0d,0x85,0xba,0x25,0xa7,0xf4,0xcc,0x24,0xe0,0x02,0xdf,0x50,0xab,0xea,0x2f,0xc3,0x0d,0x7d,0xce,0x15,0x9d,0x8c,0x6c,0x16,0x4f,0xde,0x72,0xb2,0x40,0xef,0x9c,0x36,0xcf,0xeb,0x3b,0x17,0x88,0xd5,0xc1,0x3e,0x35,0x8b +.byte 0xa3,0xe6,0x38,0xfd,0xac,0x9b,0x15,0x3c,0x8c,0x34,0x31,0x7b,0x47,0x31,0x06,0x1f,0xfc,0x23,0x34,0xa9,0x2d,0x7b,0x0a,0xe6,0x17,0xbf,0x2c,0x1d,0xf6,0xd3,0xa4,0xcf,0x47,0x63,0x58,0x83,0x63,0xcf,0xc1,0x57,0x01,0xb7,0xe6,0x4c,0xe5,0x7b,0xc6,0x40,0xa9,0x18,0x1c,0xc0,0x3c,0xca,0x87,0xd5,0xf7,0x72,0xe5,0xc6,0x24,0x4b,0xc6,0x06 +.byte 0x60,0x50,0x5b,0x36,0x66,0x47,0x28,0xdc,0x4a,0xea,0x2d,0x6a,0x8f,0x1e,0xfe,0x26,0xdd,0x76,0xb4,0x33,0x20,0x90,0x3f,0x0c,0xa8,0xaa,0x12,0x80,0x72,0x0a,0x9c,0xe1,0x95,0xb1,0x9c,0xbb,0xdd,0x66,0x04,0xa9,0x3b,0xad,0xc4,0xaa,0xd0,0x38,0xb0,0x62,0x8b,0x12,0x60,0x7f,0x73,0x67,0x2e,0xb8,0x85,0xfd,0x61,0x37,0xa6,0xdf,0xa7,0x9e +.byte 0x3d,0x98,0xe2,0xc2,0x2d,0xff,0x56,0x4f,0x9b,0x96,0x2d,0x21,0xca,0xc8,0x4c,0x75,0x2d,0xac,0x3b,0x2d,0x73,0x2e,0xe3,0xe8,0x6a,0x98,0x86,0x39,0x25,0x7f,0x08,0x44,0x31,0x35,0x8c,0x43,0xbc,0xf7,0x12,0xd8,0x3e,0x3a,0x9e,0xe7,0x2a,0xf9,0x49,0x96,0x95,0x14,0xb2,0xa9,0xb3,0x85,0x46,0x43,0x3b,0x31,0x37,0xe9,0xf3,0x93,0x3e,0x7e +.byte 0xba,0x13,0x28,0x8a,0x67,0x16,0x8f,0x5e,0x4a,0xe5,0x52,0x67,0xdc,0x86,0xab,0x26,0x6d,0x23,0x25,0xb3,0xa3,0x46,0x29,0x73,0x72,0x38,0x7b,0x4a,0xe1,0xa7,0xeb,0x18,0xd1,0xdd,0xa1,0xe6,0xcd,0x00,0xdf,0x72,0x93,0xea,0xae,0xf2,0x27,0x49,0x01,0xdc,0x9d,0xc7,0xbd,0x4e,0xd5,0x7f,0x88,0x50,0xa8,0x3d,0xc3,0xb7,0x10,0xee,0x3f,0xe2 +.byte 0x87,0xc2,0x95,0x48,0xdb,0xf0,0x95,0x8e,0xac,0x9d,0xde,0x3e,0xe6,0x4a,0xc6,0xe5,0x42,0xab,0x10,0xc2,0xd9,0xc6,0x43,0x9b,0xeb,0xd9,0xa6,0x39,0x86,0xfb,0x9a,0x3b,0x33,0x31,0x19,0x7e,0x8b,0x77,0x2f,0x75,0x53,0x63,0xbd,0xa3,0x84,0x8a,0xb9,0x09,0xcd,0x2e,0x58,0x75,0xcb,0x40,0x87,0xc9,0x7f,0x66,0x30,0x9f,0x21,0xb5,0x42,0x44 +.byte 0x7f,0xcc,0x89,0x0b,0x01,0x8a,0x8f,0x5d,0x83,0x12,0x65,0x19,0x4f,0xd9,0x50,0x14,0x3a,0x42,0xaf,0xa2,0x75,0x91,0x6b,0xc5,0x15,0xb3,0x6f,0x3b,0x4f,0xdf,0xd9,0xe3,0x67,0xf0,0x0d,0x5b,0x0e,0x45,0x25,0xd3,0x01,0x7e,0x7f,0xc9,0x32,0x46,0xb6,0xd0,0x15,0x2e,0xfa,0xdf,0x5c,0xa4,0x2d,0x73,0x19,0x49,0xed,0xdb,0x09,0xde,0x7f,0x6b +.byte 0x2e,0xce,0xa5,0xeb,0x0b,0xc9,0xf6,0x03,0x6f,0x52,0x2e,0x01,0xab,0x09,0xd5,0x0c,0x74,0x2b,0x73,0x9a,0xf1,0xe7,0x3f,0x5d,0xdb,0x15,0x8e,0x36,0x1f,0x88,0x42,0xdb,0x49,0xd8,0xcf,0x0c,0x63,0x3a,0x60,0x0b,0x10,0xa2,0xbf,0xc1,0xb0,0x7c,0x91,0xf5,0x16,0x9b,0x66,0x3e,0x41,0x03,0x5e,0x5a,0x8e,0x0f,0x98,0x34,0x44,0x5b,0xde,0x1a +.byte 0x74,0xff,0x47,0xc8,0x27,0xdf,0x01,0xc2,0x94,0xce,0x38,0xbc,0x06,0xb9,0xef,0x93,0xd2,0x55,0x6e,0x4a,0x45,0xfb,0x42,0xd0,0xc1,0xac,0x0c,0xae,0xfb,0x76,0x2d,0xb4,0xcd,0x33,0x33,0x53,0xcc,0xd4,0x41,0xab,0x99,0xaf,0xbe,0x26,0x05,0x77,0x43,0xfc,0x3d,0xf2,0x70,0xea,0x44,0xf8,0x21,0x67,0xad,0x4b,0xfe,0xce,0xca,0x35,0x02,0x1c +.byte 0xd1,0xec,0xa5,0x5f,0xc6,0xe0,0x54,0xca,0xf7,0x8f,0xaf,0x8b,0xc1,0xe5,0x87,0x90,0x0e,0x6b,0x5f,0xf4,0x07,0xe9,0xb5,0x66,0xd8,0x89,0x12,0x32,0x9c,0x62,0x7d,0x4a,0x84,0x27,0xb1,0xd7,0x01,0x68,0x84,0x94,0x85,0xa4,0x9e,0xba,0x9c,0x29,0x5a,0x1c,0xb6,0x3c,0xeb,0x5b,0x82,0x2d,0xec,0x12,0x73,0x4f,0x1f,0x78,0xa2,0xc5,0x84,0xfb +.byte 0x1c,0xfa,0xdb,0x7d,0xd8,0x4e,0xd5,0x37,0xc5,0x70,0xe1,0x09,0x05,0xc7,0xfe,0x9d,0xe5,0x3d,0x64,0x9c,0xf9,0xce,0x74,0x4c,0xac,0xaf,0x35,0xd0,0x5e,0xac,0x3d,0x11,0x81,0x96,0x31,0x0b,0x46,0x66,0x1c,0x72,0xbf,0x7e,0x0d,0xc9,0xb6,0x61,0x06,0xd2,0x7e,0x23,0xfe,0xc1,0xaa,0x62,0x96,0x03,0x72,0x72,0x4b,0xca,0x9e,0x17,0xdc,0xdc +.byte 0x31,0xd7,0x68,0xaf,0xb9,0xc7,0xb7,0x4a,0x6c,0x15,0xca,0x1f,0x43,0x76,0xcf,0x1a,0xcd,0xbd,0x2e,0xf5,0xe7,0xd5,0x2e,0x0d,0x6e,0x59,0xf8,0xc8,0x35,0x78,0x23,0x82,0xbe,0x70,0x0f,0x40,0xc0,0x55,0x8a,0x08,0x81,0xf1,0x74,0xd2,0x37,0x5d,0xe9,0x22,0xff,0x18,0x1d,0x9f,0x2e,0x98,0xe0,0x97,0x09,0x18,0x62,0xe8,0x2a,0x10,0xfc,0x28 +.byte 0x7c,0x27,0xe9,0x0f,0x86,0xf6,0xc0,0xe5,0xeb,0x45,0x5a,0xd9,0x81,0x25,0x0d,0x06,0x54,0xdf,0xde,0x46,0xd3,0x6e,0x08,0x69,0xf9,0x76,0x63,0x66,0x9d,0xfb,0x9c,0xca,0xb2,0x32,0x08,0x96,0x7f,0xab,0xa0,0x65,0xf0,0xac,0x1e,0xce,0x74,0x63,0xaf,0x1b,0xf3,0xdc,0x12,0x0c,0x59,0x86,0xbe,0x74,0xc6,0x80,0x66,0x74,0x78,0x9c,0x0c,0x1e +.byte 0x6e,0xf6,0xdf,0x39,0x79,0xfb,0x8e,0x8c,0x28,0x85,0x6f,0xfc,0x16,0xb0,0x39,0xea,0x67,0xf6,0x1c,0x41,0x10,0x90,0x0f,0x80,0x63,0x84,0x04,0xaa,0x6e,0x8e,0xfa,0xe2,0x2b,0x5c,0xa7,0x52,0x43,0x93,0xa5,0x16,0xd6,0x6c,0x9c,0x07,0x25,0xd8,0xa3,0xd5,0xb0,0xba,0x2a,0xd3,0xea,0xdc,0x9b,0xb6,0xc1,0x07,0x7d,0xd0,0xb5,0x28,0x52,0xdc +.byte 0x1b,0xf7,0xeb,0xb0,0x5b,0xd2,0x20,0x0b,0xab,0xf5,0x96,0x83,0x3f,0x2b,0x7d,0xab,0x7e,0x61,0x13,0x7e,0xd8,0x07,0x2b,0xee,0xbe,0xe7,0x78,0x66,0xec,0x7d,0xc2,0xfd,0x41,0xd8,0x18,0x8b,0x8b,0x3b,0x46,0x9d,0xc8,0xd6,0xe7,0x75,0xc2,0x2d,0xf3,0xdb,0x20,0x2d,0x8c,0x8e,0x74,0xf4,0xe2,0x69,0xad,0xde,0x99,0x0b,0xf1,0xaa,0xa1,0x57 +.byte 0xb0,0xd9,0x4e,0x0e,0xf5,0xfc,0x8a,0xf2,0xff,0xf2,0xbc,0xdb,0xf4,0x8b,0xff,0xf0,0xd9,0x20,0x5f,0x0f,0x80,0x43,0xaa,0x1d,0x76,0x3c,0x7d,0xad,0xf3,0x93,0x6b,0xab,0xd3,0x8d,0x35,0x1c,0x03,0xe0,0x76,0x25,0xa8,0x1f,0xdb,0x19,0x48,0x8c,0x33,0x21,0xae,0x34,0xae,0x34,0x54,0xe2,0x42,0x66,0x67,0xdb,0x90,0x21,0x46,0x16,0x1a,0xac +.byte 0xf6,0x4f,0x77,0x66,0x50,0x52,0x68,0x80,0xeb,0x79,0x27,0xb1,0x24,0x81,0x75,0xde,0xe4,0x13,0x0c,0xff,0xd0,0xed,0x0a,0x98,0x04,0x70,0x05,0x2e,0xd9,0x67,0x4c,0x4e,0x93,0x49,0x08,0xb4,0x97,0x3e,0xc1,0x7c,0xc3,0xc1,0x42,0x40,0x69,0x53,0xd6,0x90,0xf5,0x85,0x39,0xa4,0x8d,0x8f,0xd2,0xf1,0x50,0x87,0x10,0x3e,0x5b,0x86,0xb3,0xd6 +.byte 0xee,0x60,0x05,0x4c,0x83,0x9f,0x27,0xa9,0xfc,0x1e,0x67,0xa5,0x68,0x02,0xc7,0xe0,0xc5,0x58,0x60,0x68,0x5f,0x59,0xb9,0x8f,0x91,0x5b,0xa0,0xe5,0xf8,0xca,0x95,0x69,0xeb,0x0a,0xdb,0x87,0xd5,0x61,0xca,0x48,0xa0,0x1a,0xdc,0x96,0x02,0xd1,0x86,0x41,0xce,0xe8,0xa8,0xcd,0x24,0x36,0x9a,0x31,0x0e,0x9f,0xbf,0xc1,0x9e,0x85,0x2f,0x64 +.byte 0xff,0xa8,0xb5,0xe1,0xef,0x16,0x1e,0xcd,0x93,0x7e,0x30,0x28,0x97,0x7d,0x59,0x30,0x4f,0x24,0x40,0x51,0x31,0x32,0xde,0x7b,0x1e,0x72,0x0e,0x91,0x95,0xa2,0x3f,0x87,0x49,0xb1,0x82,0xaf,0x66,0x0a,0x54,0x92,0xe9,0x5c,0x3d,0xfe,0x47,0xcf,0x27,0xf6,0x0d,0xd1,0x69,0x97,0x89,0x62,0xea,0xdb,0x44,0x39,0xf4,0x36,0x73,0x31,0x79,0xcb +.byte 0x73,0x16,0x80,0x2d,0x49,0x8a,0x97,0x87,0xda,0x38,0x64,0xd9,0xc3,0x6f,0x4f,0x9b,0xa3,0xf2,0x9a,0xcd,0x2f,0xca,0x7e,0x5f,0xf7,0xf7,0x66,0xc5,0xb7,0x25,0x8d,0x9f,0xf4,0x5a,0x96,0x97,0x7c,0xd3,0x15,0xd8,0x3b,0x12,0xbd,0x09,0xf0,0x0d,0xc9,0x05,0x28,0x6b,0x43,0x62,0x3e,0x58,0x2f,0x8f,0x97,0xe7,0x72,0x8b,0x94,0x62,0xd0,0x3a +.byte 0x64,0x30,0x2c,0x4d,0xd2,0xa7,0x12,0x90,0x27,0x17,0x57,0xf7,0xc8,0x8b,0x9d,0xb5,0x89,0x3e,0xb8,0x69,0x3c,0x68,0x21,0xc9,0xfa,0xed,0x83,0x22,0x89,0x70,0x64,0x0f,0xd5,0x3c,0x5c,0x9f,0xea,0x68,0x59,0xfc,0x18,0x56,0x6d,0x91,0xe7,0x8c,0xed,0x2a,0xa2,0x3a,0x21,0x5a,0x66,0x2b,0xeb,0x83,0xc0,0x79,0xf7,0x4f,0xdf,0xd2,0x62,0x88 +.byte 0xe0,0x18,0x33,0xb0,0x50,0x5d,0xf5,0x81,0x1c,0x6b,0xd2,0x44,0x24,0xc0,0x5d,0xfa,0x3d,0x1a,0x26,0xb5,0x92,0x31,0xd2,0xb7,0x2f,0x98,0xfd,0xbf,0x6e,0xaf,0x1b,0x12,0x46,0xa3,0x6c,0x76,0x5a,0x50,0xb2,0x81,0x55,0x3d,0x47,0x32,0x61,0x0b,0x1d,0x86,0x90,0x72,0x87,0x66,0x89,0x0e,0x64,0xdb,0xdb,0x3b,0xa3,0x4e,0x49,0xa6,0xbe,0x42 +.byte 0x73,0x0f,0x45,0x73,0x47,0x1c,0xb8,0x4a,0xb1,0x3f,0x98,0x15,0x8e,0x75,0xf5,0x33,0xc9,0x65,0x77,0x66,0xb8,0xd5,0x20,0x61,0x23,0xbe,0x40,0xd9,0xe7,0xbc,0xeb,0xff,0xcd,0xb6,0x2c,0x2b,0x76,0x3a,0xf1,0xef,0x38,0x6d,0xe3,0xcd,0x70,0x6e,0xe0,0x29,0xad,0xca,0x6d,0x03,0xfe,0x5a,0x1d,0x69,0x2f,0xf7,0xde,0xfd,0xf4,0x6b,0xb3,0xc5 +.byte 0xe5,0xac,0xf3,0xd2,0x95,0x02,0xf2,0x6a,0x58,0x4c,0x5b,0xeb,0x1f,0x0b,0x7f,0x9d,0x0a,0x0e,0xb3,0xf0,0x41,0x50,0x04,0x65,0xf3,0xc0,0x68,0xc9,0x1f,0x0b,0xdb,0xd0,0xd6,0x19,0x4b,0xa8,0x72,0xb2,0x60,0xf2,0x1c,0xbd,0x99,0xb5,0x7d,0xe0,0x1e,0xe3,0xfd,0x42,0x8a,0x62,0xe3,0x8f,0xd6,0xcf,0x45,0x16,0x94,0x76,0x73,0xb7,0xa1,0x2a +.byte 0x67,0x25,0x02,0x73,0x0e,0xf6,0x10,0xcf,0x57,0x0a,0x74,0xeb,0x5a,0x4d,0x07,0x04,0x7b,0x1c,0x7e,0xf4,0x55,0xda,0x39,0x76,0xeb,0x11,0xfb,0x04,0xf5,0x32,0xdf,0x63,0x58,0xd0,0xc4,0xa4,0x76,0x76,0xd8,0xaf,0xc6,0xe4,0x21,0x97,0x51,0x6a,0xc1,0xab,0x81,0xd8,0x65,0xac,0x28,0x54,0xcd,0x36,0xcb,0xba,0xfc,0x08,0x3f,0xb1,0x81,0x69 +.byte 0xbe,0x42,0x79,0x17,0x74,0x23,0x5f,0x28,0x59,0x60,0x84,0xa3,0x3c,0x57,0x9b,0xc9,0x77,0x24,0xe2,0xcf,0x51,0xb6,0x31,0x46,0xe2,0xd2,0x30,0xb9,0x76,0xcc,0xb4,0xca,0x8a,0xd5,0xa6,0x1c,0x3c,0xcc,0x39,0x1e,0xae,0x54,0x2a,0xde,0x0a,0x76,0x7e,0xaa,0x78,0xd2,0xaa,0xa0,0xe0,0xda,0x05,0x6d,0x1a,0x2a,0x44,0x8f,0x75,0x37,0x8f,0x4f +.byte 0x38,0xaa,0x9b,0x30,0x79,0x98,0x0a,0xe2,0x5d,0x4d,0x0a,0x91,0x18,0xb1,0x0e,0x3b,0xa6,0xd5,0x72,0x00,0xc4,0xbe,0x09,0x7e,0xd0,0xe5,0xf3,0x98,0x28,0x9c,0x34,0x44,0xdd,0x35,0x2c,0x7d,0x06,0x22,0x59,0x98,0x7b,0x50,0x7d,0xc6,0xb2,0xd4,0xa2,0xaa,0x4f,0xad,0x50,0x72,0xbb,0xbb,0xb5,0x79,0x25,0x40,0x8e,0x43,0x6a,0x09,0x3f,0x60 +.byte 0x28,0x67,0x47,0x8c,0xbd,0xc8,0x12,0x50,0x9b,0xdc,0xd4,0x03,0x99,0x3d,0x7c,0x08,0xd6,0xe3,0xfd,0xfa,0x5d,0xba,0x85,0xb4,0x0e,0xea,0xf6,0x70,0x82,0x18,0xc6,0x05,0xc6,0xb9,0x0d,0x81,0x6a,0xc0,0x40,0x7f,0x26,0xfc,0xe0,0x49,0x5e,0x1d,0x28,0xc5,0x91,0xd4,0xb5,0x6d,0x6c,0xe8,0x8a,0x59,0x30,0x1d,0x0a,0x8e,0xb2,0x6c,0x2b,0x03 +.byte 0xfb,0x20,0x60,0xb2,0x9d,0xd4,0xb0,0xe1,0xa4,0x9d,0xb0,0x84,0x3f,0xfd,0x82,0x1d,0xeb,0x93,0x66,0xa8,0x1d,0x94,0x69,0x99,0x8f,0x3e,0x16,0x1a,0x36,0x4c,0xc4,0x6f,0x14,0x04,0xa7,0xcf,0x0a,0x0b,0x6e,0xd6,0x29,0x49,0x8d,0x9d,0x11,0xa4,0xf7,0x58,0x25,0x39,0x6e,0x68,0x7a,0xca,0xf7,0x3b,0x6e,0x2b,0x1c,0xc3,0xef,0xca,0x97,0x83 +.byte 0x4b,0xf3,0x48,0x9a,0xc6,0x23,0x63,0x72,0x40,0x44,0x40,0xc3,0xf0,0x5b,0x80,0xff,0xd7,0x7e,0x37,0xc2,0x54,0xda,0xa4,0x2a,0xdd,0x65,0xc8,0x48,0x89,0x8c,0xea,0x5f,0xd2,0x46,0xfe,0xe9,0xbf,0xce,0x4a,0x80,0x3b,0xd0,0x51,0xcd,0x83,0x5f,0xfb,0x27,0xab,0x05,0x25,0x44,0xeb,0xe1,0x57,0x18,0x50,0xfc,0xb0,0x83,0x79,0xdc,0xa0,0xd3 +.byte 0xc4,0xfb,0xc1,0xef,0xd2,0x44,0x2f,0x87,0x4f,0xef,0xed,0x3a,0x55,0x07,0xe6,0x67,0xe0,0x22,0xa0,0xaf,0x9e,0xb9,0xef,0x32,0x2e,0x81,0xe6,0x30,0x25,0xe4,0x4d,0xa0,0x34,0x1e,0x7d,0x6b,0xb9,0x21,0x4d,0xae,0xfd,0x51,0xe0,0xee,0xf6,0xe2,0x0d,0x9c,0xf6,0x63,0x73,0x93,0xc0,0xbb,0x88,0x0c,0x06,0xb9,0xa0,0xf3,0xfc,0x26,0x64,0x91 +.byte 0x84,0xd1,0x77,0x21,0xf9,0xf1,0x4c,0x48,0x65,0x15,0x56,0xd7,0xd2,0x86,0x26,0x6f,0xf5,0xce,0x81,0x1d,0x9d,0xa7,0x83,0xd0,0x2a,0x4e,0x01,0x79,0xd6,0x1d,0xee,0x10,0x66,0x6f,0xf8,0x80,0x47,0x6c,0xed,0x18,0xc1,0xb5,0x39,0xec,0x2d,0x42,0xf1,0xd5,0x2c,0xd9,0x9c,0xd5,0xaa,0xbf,0xc1,0x67,0xf3,0xf9,0xd6,0xd2,0x44,0x20,0x27,0x7b +.byte 0x40,0x04,0x0c,0x77,0x64,0xef,0x5c,0x1b,0xc8,0x2c,0x25,0x3e,0x9d,0x63,0xbb,0x94,0x78,0x02,0x14,0x46,0xfc,0xa6,0x09,0x0e,0xc5,0x81,0x34,0x1b,0x11,0xdf,0xb4,0xb6,0x8e,0x40,0x0e,0xf3,0x05,0x0a,0xf5,0x28,0x58,0x5a,0x2a,0xb5,0x6c,0x9d,0xe5,0x50,0x0d,0x3e,0xcf,0xb6,0xc5,0x3b,0xc8,0x56,0x50,0x8c,0xda,0x83,0x8d,0x4d,0xce,0x22 +.byte 0xb9,0x5b,0x14,0x76,0x88,0x84,0xdf,0xa3,0x93,0x79,0x21,0x8c,0xfa,0x42,0x98,0xda,0x0d,0x2a,0x4e,0x43,0x41,0x0d,0xac,0xe6,0x9e,0x11,0x14,0x81,0xcc,0xcf,0x72,0x84,0xb5,0x8e,0x99,0x0e,0x64,0xad,0xbc,0x35,0x9d,0x04,0x56,0xae,0x33,0x8e,0x3a,0x2a,0x56,0x91,0xa7,0x9c,0xe4,0xba,0xfc,0xe9,0x65,0x14,0xbf,0x07,0xf8,0x85,0x45,0xe1 +.byte 0x1d,0x29,0x4c,0x10,0xde,0x5e,0x6c,0xb6,0x28,0xad,0x9a,0xb8,0x18,0xeb,0x77,0x2d,0x7b,0x6e,0x26,0x51,0xee,0x84,0x40,0x00,0x0f,0xed,0xb2,0x28,0x11,0x34,0xca,0xc7,0x33,0xf8,0x67,0x96,0xce,0x93,0x1d,0x4d,0x42,0x0f,0x55,0x5d,0x34,0x88,0x55,0xdd,0x8f,0x43,0xaa,0xfb,0xfe,0xea,0x53,0xee,0x69,0x10,0xcd,0xc3,0x94,0xab,0xe1,0xff +.byte 0x89,0xb1,0x35,0xd2,0x21,0x0d,0x3a,0xa3,0x85,0xfa,0x42,0xb7,0xb1,0x16,0x97,0xb8,0xe3,0x1a,0xfa,0xab,0x86,0x1b,0x9c,0x66,0xf8,0xe6,0xae,0x1e,0x68,0x84,0xf5,0xef,0xb6,0x5c,0x72,0x86,0xa3,0x27,0x9a,0x65,0xff,0x54,0xe7,0x83,0xfe,0xd7,0x00,0xe9,0x63,0x1e,0x05,0xe3,0xe1,0x10,0x7a,0x19,0xee,0xb3,0xc8,0xf0,0x1c,0x2e,0x3c,0x79 +.byte 0x05,0xf7,0x5e,0xcc,0x01,0x88,0xc8,0x1f,0x0b,0xbd,0xda,0x44,0xfd,0x97,0x53,0x58,0xa6,0xab,0xf7,0x89,0xb1,0x52,0x29,0x73,0xff,0xb1,0xfa,0x66,0x8a,0x56,0x22,0xe5,0x9c,0xbb,0xab,0x55,0x37,0x4a,0x3e,0xc3,0xeb,0x09,0xbe,0x40,0x77,0xcd,0xf9,0x0f,0xcf,0xa7,0x14,0x4b,0xe7,0x19,0x8c,0x12,0x31,0x2f,0x34,0x45,0x1d,0x1a,0x4f,0xf0 +.byte 0xc5,0x24,0x78,0x39,0x2e,0x96,0x13,0x5b,0x47,0xcc,0xb9,0xb3,0xa6,0x16,0x4f,0xa3,0x2b,0xca,0x79,0x98,0x0d,0x89,0xad,0x65,0xdb,0x1c,0xf8,0x61,0x18,0x28,0x21,0x47,0x28,0x11,0x77,0xb5,0x33,0xf5,0xbd,0x92,0xb8,0xa6,0xdc,0xfe,0x67,0x20,0x3c,0x05,0xe5,0x14,0xc9,0xb9,0x40,0xc3,0x15,0x8e,0xd9,0xbf,0xef,0xcb,0x4d,0x0a,0xf7,0xbd +.byte 0xc2,0x48,0x7c,0xdc,0x23,0x13,0xc2,0xc1,0x94,0x4a,0x8c,0xb8,0x62,0x2c,0xb5,0xd6,0x49,0x7e,0xaa,0x99,0x61,0xdc,0xae,0x18,0x5f,0xce,0xb4,0xe4,0x57,0xf1,0x48,0x7b,0xc3,0xc1,0x63,0x6b,0xa6,0xc3,0xbc,0xa8,0x93,0xd3,0x51,0xd7,0xfc,0x5a,0x89,0x73,0x4d,0xbe,0x48,0x75,0x51,0xaf,0x75,0x0d,0x48,0xf7,0x3c,0x34,0xdc,0xae,0xf5,0xf9 +.byte 0xc1,0xb0,0x53,0x50,0x85,0xcd,0xf9,0xa9,0x37,0x48,0x14,0x6c,0x7f,0x7b,0x9c,0xa1,0xf5,0xb2,0xf4,0x38,0xbf,0x4b,0x39,0x8e,0xb5,0x2b,0xb5,0x1e,0x22,0xa8,0x52,0xad,0x1b,0x57,0x69,0xdc,0xb1,0xca,0xb6,0x2a,0x0b,0x42,0x6e,0xde,0xc6,0xb2,0xec,0x30,0x05,0x00,0x87,0xeb,0x7e,0x77,0x14,0x07,0x35,0x6e,0x11,0x09,0xc0,0xd9,0xc4,0xaa +.byte 0x96,0xa4,0xa8,0xb6,0xd9,0x6d,0xf8,0xc5,0x52,0x7f,0x85,0x25,0xc2,0x81,0x1d,0x67,0x76,0x4a,0x45,0xa3,0xd5,0x40,0xaf,0x63,0x75,0xe5,0xcc,0xb0,0x46,0x0f,0xe6,0x7c,0xf8,0x5b,0x2e,0x09,0x98,0x89,0xc9,0x1b,0x8c,0x49,0x91,0xd9,0xcd,0x56,0x02,0x8d,0xcc,0x67,0x5c,0xa1,0x69,0x76,0x16,0x7a,0x93,0x44,0x04,0xb1,0x3b,0x19,0x28,0x15 +.byte 0x73,0x11,0x81,0x92,0x42,0x5a,0x91,0x10,0xf4,0x36,0xed,0x7a,0x90,0x5c,0x74,0xb8,0x96,0x97,0xde,0xd7,0x5e,0x1e,0x78,0xb1,0x33,0xbc,0x0f,0x66,0x65,0x0e,0x68,0xb1,0x47,0x16,0xdc,0x89,0xc8,0x80,0x9e,0x44,0xc0,0x85,0x86,0xed,0xc7,0x74,0xc8,0xf4,0x3f,0xbe,0x2e,0xe7,0xa5,0x85,0x6f,0xf7,0x08,0x0e,0x40,0xec,0xc5,0x15,0xcc,0x63 +.byte 0x13,0x91,0x75,0xc2,0x7b,0xbc,0xa4,0xf1,0xf6,0xa2,0xec,0xae,0x8b,0x60,0x08,0x2d,0xc0,0x17,0x3b,0x9e,0x34,0x15,0xe7,0x7c,0xb4,0x86,0xd3,0x69,0x7e,0xb0,0xa3,0x17,0x50,0x2d,0x64,0x7c,0x99,0x87,0x61,0x50,0x86,0x90,0x87,0x50,0xdd,0x5f,0x83,0x1f,0xc0,0x9c,0x14,0x44,0xed,0x96,0xce,0x41,0xe5,0xe6,0x38,0xc2,0xfb,0x5e,0xf1,0x3e +.byte 0x31,0x82,0xbb,0x4c,0x59,0x23,0x47,0x6f,0x3e,0x55,0x76,0x4b,0xb1,0x39,0x53,0x3e,0x16,0xaf,0xbd,0x33,0x9f,0x05,0x05,0xa4,0x9a,0x10,0x83,0xa1,0xfc,0xf1,0x45,0x29,0x30,0x91,0x0f,0xb6,0xc0,0x32,0x23,0xd0,0xd8,0xcc,0x91,0x63,0x70,0x39,0x9a,0x95,0x0b,0xb0,0x47,0x8b,0x47,0x57,0x53,0x33,0xb3,0x51,0x9c,0x3c,0xf0,0x71,0xd0,0xf6 +.byte 0x91,0x14,0xb4,0x05,0x2e,0x65,0x4d,0x1e,0xb6,0xce,0xf6,0xd2,0xb9,0x06,0x59,0xac,0x25,0xe7,0x9f,0x44,0x9d,0x53,0x3a,0x06,0xad,0x19,0xaf,0xb1,0xc3,0x6a,0x10,0xf7,0xc1,0xa1,0x31,0x7a,0x42,0x38,0x3f,0x81,0x22,0x8a,0x56,0xc6,0x68,0x0f,0x18,0x84,0xb9,0x5b,0xd1,0x6e,0x7f,0xae,0xa6,0xfe,0xb0,0x2d,0x91,0x20,0x49,0xb1,0xe2,0x19 +.byte 0x4b,0x91,0x5f,0x5e,0x77,0x8b,0xd5,0x47,0x0c,0x15,0x36,0x12,0x91,0x01,0xef,0xc8,0x3a,0x39,0x22,0x03,0x9f,0x49,0x93,0x00,0x11,0xda,0x4b,0x6f,0xcd,0x3c,0xb2,0xc0,0xe5,0x78,0xa0,0xeb,0x61,0x56,0x97,0x28,0x53,0x3b,0xec,0x04,0x83,0x7e,0x77,0x78,0x50,0xf6,0xe0,0x0c,0x1f,0x5c,0xd5,0x0c,0x5b,0x45,0xfa,0xee,0xd0,0x26,0x5b,0xfb +.byte 0x44,0x5e,0x49,0x04,0x17,0x97,0xbb,0xaa,0x69,0x1f,0x89,0xcb,0xc1,0xf2,0x53,0xaa,0x5f,0x4f,0x3e,0x49,0xca,0x74,0x51,0x60,0x0c,0x04,0xec,0x74,0xdb,0x58,0x18,0xc0,0x77,0xfd,0x26,0xe7,0x69,0x6d,0x44,0x93,0x89,0x32,0x89,0x88,0xde,0xe2,0x6d,0x9b,0x63,0xfc,0xe0,0xc1,0x92,0x0b,0x52,0xf9,0xef,0x17,0x0f,0x46,0xa0,0xa0,0x98,0x44 +.byte 0x58,0xbd,0xe1,0x88,0x45,0x3c,0xf1,0xd6,0x5e,0x5b,0xd1,0x94,0x6e,0xe4,0xac,0x98,0xc0,0x44,0x7c,0x21,0xac,0xd0,0xa4,0x13,0x2e,0x5a,0x6d,0x54,0x2f,0x07,0x2b,0xca,0xa1,0xeb,0x81,0x4f,0xee,0xa2,0x4e,0x09,0xdb,0x28,0x2d,0x67,0x87,0x00,0xf6,0x52,0xb0,0xbe,0xed,0xa5,0x54,0xff,0x7d,0x27,0xb0,0x1e,0x49,0x9d,0x98,0xc4,0xf3,0xf3 +.byte 0xd9,0x33,0xef,0x61,0x53,0x11,0xd3,0x8a,0x10,0x05,0xde,0xe3,0x39,0xf1,0x4a,0x17,0x9a,0xbd,0x76,0xbc,0xf6,0xd0,0x43,0xcb,0xe4,0xa7,0x26,0x29,0xc8,0x89,0x05,0xf2,0x26,0x19,0x4c,0x11,0x05,0xcb,0x73,0x3d,0x2d,0x2d,0x4a,0x7a,0x0b,0x87,0x23,0x86,0x18,0xd8,0x53,0x91,0xb4,0x73,0xea,0xa3,0xf4,0xb9,0x15,0x2c,0x36,0xba,0xc7,0xf1 +.byte 0x3f,0x92,0xd7,0xde,0xc5,0xfc,0xe5,0x91,0x29,0xa7,0x0c,0x1a,0xf7,0x09,0x49,0xad,0x88,0xde,0x47,0xf1,0x5d,0x01,0x08,0x2d,0x20,0xc6,0x39,0x08,0x9f,0x02,0x3f,0x20,0xe2,0x21,0x68,0xa0,0x0d,0x1b,0xcf,0xbf,0xb2,0x2f,0x13,0x5c,0x88,0xae,0xc1,0x29,0xa7,0x54,0x4f,0xa3,0x37,0xf1,0xa5,0x0b,0x4f,0x1b,0xa4,0x39,0x0b,0x99,0x0d,0x65 +.byte 0xfa,0xf1,0x43,0x46,0xc3,0xfd,0xcc,0x3b,0x7d,0x3c,0xd4,0x15,0x32,0x51,0xf4,0xbe,0xf8,0x46,0x01,0x62,0xa6,0xe2,0x44,0x1c,0x78,0x4c,0x57,0x13,0x2c,0x9d,0x8a,0xea,0xe0,0xfc,0x2e,0xe7,0x80,0x6f,0x90,0x67,0x00,0xf0,0x13,0xbb,0x05,0xe0,0xbd,0xf8,0x11,0x9d,0x7e,0x9d,0x01,0x61,0x3a,0x13,0x9a,0x02,0xfb,0x24,0xea,0x91,0x0c,0xe5 +.byte 0xeb,0xe3,0x80,0x22,0xb6,0xac,0xe1,0x13,0x95,0x65,0x22,0xeb,0xf7,0x91,0xa3,0xe6,0x4b,0x54,0x1e,0xf8,0x7b,0xcd,0x27,0x7c,0xca,0xb7,0x88,0x52,0xdf,0xba,0x9e,0xf6,0xed,0x03,0xb4,0xac,0xab,0x17,0xe7,0xb0,0x5e,0x1a,0x19,0xee,0x61,0xdf,0xa5,0x23,0x28,0xd6,0x63,0xe3,0x45,0xea,0x92,0x70,0x94,0x31,0x32,0x8f,0x47,0xad,0xee,0x9e +.byte 0x6a,0x2c,0x18,0x66,0x55,0xd1,0xd9,0xc6,0xd4,0x08,0x5a,0x7c,0xe8,0x09,0xcc,0x62,0x1e,0x24,0xed,0x2f,0x3e,0x1b,0x84,0x92,0x73,0x14,0x22,0xbc,0xb7,0xf0,0xed,0x3f,0x12,0x98,0x49,0x52,0xb5,0x29,0x5e,0x2d,0xca,0x23,0xeb,0x8a,0xb1,0xea,0x3c,0x6c,0x93,0x68,0x7f,0x84,0x4f,0x49,0x9c,0x9b,0xb8,0xc7,0xfd,0x6a,0xb7,0xf1,0xde,0xf9 +.byte 0xc1,0x72,0x26,0xd1,0xfb,0x40,0x72,0x78,0xb0,0xa3,0xce,0xa8,0xab,0x3b,0x0f,0x8c,0x2b,0x13,0xe2,0xe3,0x86,0x9a,0xa0,0x69,0x46,0x85,0xdf,0x50,0x5b,0x60,0x9a,0xb7,0x4f,0xa9,0x76,0x70,0xd6,0xeb,0xbb,0x97,0xb7,0x63,0xed,0xec,0xbe,0x93,0x9f,0x79,0xff,0xcf,0x2c,0x09,0x85,0x22,0x1f,0x0e,0xbd,0xd4,0xb7,0x7b,0x1e,0x0e,0xc3,0x99 +.byte 0x55,0x1b,0x50,0xc0,0xb9,0x68,0xe3,0xa9,0x59,0x73,0xa4,0xe6,0x86,0x6c,0xda,0xc5,0xba,0x76,0xab,0x56,0x94,0xa5,0x11,0xdf,0x1b,0x09,0x67,0xde,0x20,0x9f,0xf4,0xb8,0x6f,0x64,0xb1,0x9b,0xac,0x59,0xf9,0xcc,0xd8,0xc1,0x41,0xe9,0xdd,0x00,0xda,0x6a,0x11,0x3b,0xad,0x04,0x81,0x39,0x87,0x8e,0xf3,0x99,0xcf,0xde,0x29,0x7b,0x25,0x91 +.byte 0x6e,0x2e,0x1d,0x83,0x9c,0xb6,0xa7,0xff,0x65,0x88,0xe8,0xc1,0xe7,0xca,0x7e,0x46,0xf0,0xc0,0xe7,0x55,0x36,0x76,0xa7,0xc5,0x25,0x06,0xc4,0x77,0x7b,0xff,0x61,0x1d,0x5a,0x77,0xa0,0xbc,0xa5,0x6f,0xda,0x3d,0xfe,0x92,0xd3,0x8e,0xc4,0x95,0xea,0x13,0xbd,0x18,0xff,0x8f,0xcd,0x7c,0x18,0xe1,0x88,0xee,0x5d,0xcc,0x8d,0xea,0x9e,0x21 +.byte 0xe5,0x8f,0x8c,0x6b,0x51,0xbb,0xab,0x9d,0x64,0x53,0x70,0x5b,0x0b,0x5c,0xa0,0xde,0x4d,0x56,0x82,0xb0,0xa8,0x3b,0x91,0x0c,0xe6,0x8c,0x7b,0x24,0xdd,0x32,0xb9,0xf2,0x06,0xc0,0xce,0xcb,0x11,0x4f,0x5b,0x70,0xc3,0x09,0x37,0x5b,0xd9,0x69,0x97,0x0b,0x9b,0x37,0x14,0xb3,0x95,0x4f,0x5c,0x0a,0x3c,0x4f,0x79,0x65,0x22,0x07,0xd3,0xd6 +.byte 0xe9,0x55,0x42,0xfa,0x47,0xe8,0x7c,0x5c,0x63,0x24,0xe5,0xd0,0x91,0x28,0x87,0x0f,0xe0,0x21,0x79,0x85,0x7a,0x8b,0xb9,0x37,0xa0,0x86,0x7c,0xfc,0x52,0x04,0xb1,0x1b,0x62,0x9e,0xc3,0x18,0x59,0x87,0xb1,0x86,0x17,0xac,0x0d,0xb7,0xca,0xa9,0x37,0x18,0x30,0x67,0x76,0x90,0x84,0x78,0xcb,0x62,0x26,0x24,0xf6,0x1b,0xfe,0xb8,0xc0,0x1f +.byte 0xdc,0x1d,0x2f,0x52,0xe5,0x64,0xbc,0xd5,0x43,0x87,0xb9,0x66,0x2d,0xa9,0x5c,0x98,0x2c,0x2a,0xf9,0xf9,0x78,0xa7,0x0f,0x23,0xe0,0x11,0x36,0xa0,0x4e,0x40,0x2c,0x79,0xca,0x1c,0x44,0x76,0x3f,0x61,0x34,0x9e,0x01,0x8c,0x61,0x2f,0x84,0x52,0x15,0x22,0xb3,0x53,0x27,0x14,0x5f,0x54,0x09,0x24,0x83,0x47,0x90,0x43,0xc3,0xdf,0xad,0x66 +.byte 0x9c,0x7a,0xa1,0x4b,0x53,0xc1,0x91,0xc5,0x48,0xfa,0xc4,0x6b,0x4a,0xc9,0xdc,0x85,0xb4,0xe2,0x21,0x88,0xda,0x27,0xcd,0x54,0xac,0xcf,0xb4,0x09,0x1d,0x5a,0x7f,0x23,0x2c,0x23,0xa4,0x98,0x96,0x29,0xa8,0xc7,0x33,0x45,0x79,0xd4,0x35,0x9d,0x78,0xbb,0x00,0x5f,0xca,0xcc,0x62,0x65,0x47,0xa3,0x8b,0x3b,0xd1,0x6b,0x18,0xb3,0xf4,0x1d +.byte 0xac,0x9c,0x9b,0x90,0xbb,0xb0,0x0d,0x8a,0x7d,0x2e,0x3b,0xbd,0x52,0x35,0x11,0xfc,0xcd,0x59,0x76,0x2c,0x9d,0xf4,0x6b,0x29,0x6d,0x63,0x51,0xc9,0x3b,0x73,0x9b,0xcc,0x33,0x4f,0x0e,0xcd,0xf1,0x06,0xf0,0xe7,0xcf,0x93,0x66,0x51,0x34,0xb0,0x98,0x50,0x2f,0xa4,0xf8,0x37,0xdb,0x78,0xc2,0x36,0x20,0x9d,0x58,0xf1,0x52,0x35,0x7d,0x8a +.byte 0xd0,0x43,0xab,0x46,0x0d,0x59,0xdb,0xf2,0x8e,0xe7,0x79,0xbf,0xf5,0x00,0xc8,0xbe,0x1b,0x98,0xf8,0x1e,0x53,0x1b,0x17,0xa9,0x2d,0x7c,0x7a,0xef,0x14,0x33,0x70,0x65,0x7b,0x55,0x82,0xe1,0x63,0x8e,0xf0,0x15,0xf6,0xb4,0x2b,0x18,0xe2,0x40,0x30,0x96,0x74,0xf7,0x91,0x82,0x83,0xef,0x74,0x38,0x89,0xea,0xaf,0x6f,0xd6,0x89,0x80,0x1c +.byte 0x46,0xa2,0xaa,0xcd,0x60,0x84,0xa2,0x65,0x8a,0xc7,0x03,0x07,0xa0,0xc9,0x00,0xd7,0x34,0x54,0x33,0x08,0xba,0x1a,0xab,0x49,0x93,0x7f,0xd2,0x51,0xe4,0xcf,0x96,0x35,0x48,0xd0,0x91,0xa5,0x10,0x65,0x95,0xe2,0x01,0x3b,0x1c,0xa1,0x4b,0x8d,0x62,0x09,0x49,0xdf,0x67,0xde,0xe5,0x8e,0xcc,0xa6,0x99,0xc1,0x8b,0x6a,0x29,0xeb,0xa0,0xe4 +.byte 0xaa,0x2a,0xd4,0xe9,0x28,0xb5,0xd1,0x39,0x78,0xe1,0xae,0x0f,0xc5,0x05,0x64,0xc8,0x62,0x27,0xf6,0x67,0xb5,0x79,0x52,0xd6,0x0d,0xbd,0x42,0xbd,0xa2,0x5d,0x00,0xd9,0xbe,0x5b,0x26,0x4c,0x20,0xdc,0xa2,0x33,0x9c,0x8e,0xd5,0x3c,0x75,0x7f,0x25,0xa2,0x04,0x70,0xfb,0x2a,0xb2,0xc6,0xb3,0xc0,0x1d,0xc5,0x58,0xe7,0xc1,0xd9,0x67,0x8c +.byte 0x2c,0x30,0x93,0x97,0x84,0x72,0xdf,0x5f,0x49,0xac,0x9e,0x09,0x0a,0x35,0xfd,0x69,0x50,0xf4,0x45,0x34,0x8e,0x07,0x9f,0x09,0x4c,0x2d,0xd8,0x7d,0x47,0xc2,0x7b,0xd7,0x67,0xb7,0xcb,0x60,0x46,0x8b,0x4c,0xe1,0x81,0x88,0x56,0x8e,0x3d,0x32,0x10,0x77,0xb4,0x33,0xba,0x2c,0xcd,0x20,0x73,0x46,0xdb,0xfa,0x83,0x27,0x43,0x3e,0xc4,0xd4 +.byte 0xd3,0x86,0x26,0x67,0x9f,0x1e,0xc8,0x1d,0x3c,0x5d,0x5b,0xcb,0xef,0x1a,0xcf,0x79,0xfd,0xce,0x72,0x8e,0xb7,0xce,0xc8,0x02,0x5c,0xde,0xe3,0x1c,0x78,0xb6,0xc1,0xb1,0xcd,0xee,0xf7,0x5a,0x57,0xa9,0xa7,0x37,0xfa,0x71,0x41,0xdd,0x1c,0xcb,0xb3,0xde,0x6f,0xbb,0xbd,0x43,0xa1,0xcd,0xc8,0x23,0x30,0xb6,0x03,0x18,0xb5,0x6f,0x20,0xc6 +.byte 0xce,0x22,0x8a,0xf2,0x01,0x30,0x74,0x1c,0x27,0x9e,0x44,0xce,0xad,0x7d,0xbc,0x93,0x5c,0xaf,0xdc,0x05,0xda,0x41,0x92,0x7c,0x6b,0x47,0x62,0xb4,0x94,0xe4,0x2e,0x70,0x7e,0x86,0xdd,0xfd,0x61,0xbc,0xdd,0x9b,0xc6,0x8e,0xbb,0x7b,0x4f,0xd9,0x0a,0x74,0x8a,0xb7,0xb1,0x19,0x0b,0x37,0xbe,0xa6,0x7c,0x48,0x1b,0xcd,0x04,0x49,0x98,0x3b +.byte 0x48,0x93,0x0c,0x2d,0x34,0xf4,0xdc,0x1d,0xa8,0x29,0xd1,0x70,0x32,0x5f,0x38,0xf6,0x5d,0xde,0xee,0x96,0xf9,0x48,0x15,0xb3,0xbc,0x10,0x65,0x0b,0x95,0xd8,0xee,0xac,0xa4,0x32,0xa8,0x06,0xee,0xe9,0xce,0x6f,0x9a,0xef,0x4f,0xa1,0x16,0x25,0xc5,0x21,0x10,0x52,0x8f,0x95,0xbe,0xd3,0x53,0x21,0x14,0xca,0xf0,0xe2,0xb8,0xf5,0x61,0x88 +.byte 0x71,0xfe,0x2e,0xa7,0xf1,0xf7,0xfc,0xba,0xf4,0x09,0xbf,0xec,0x5d,0xb2,0xc1,0xa7,0x93,0x43,0x19,0xcd,0x09,0xf8,0x46,0x99,0x89,0x07,0x92,0xd8,0xb6,0x3d,0x7f,0x7d,0xc3,0xd9,0x53,0x4f,0xba,0x86,0x02,0xe6,0xd4,0x1f,0x43,0xd7,0xb3,0x35,0x59,0x7e,0x76,0x71,0xe5,0x02,0x74,0x95,0x7d,0x20,0xab,0x4b,0xfe,0x41,0x35,0xed,0x40,0x8c +.byte 0xeb,0x54,0x50,0xe4,0x1a,0xec,0xe5,0x2f,0xa9,0xba,0x7e,0x89,0x94,0xc4,0x72,0xec,0x20,0x46,0x3a,0xea,0xc3,0x1c,0xd6,0x27,0x9a,0xca,0xa6,0x05,0x48,0xef,0x6d,0xad,0x1c,0xde,0xcb,0x33,0x0a,0x02,0x8c,0x5c,0x54,0x8c,0xba,0x0e,0x94,0x6a,0xb3,0xa6,0x66,0x5b,0xfc,0xd8,0xe4,0xb9,0xc4,0xd4,0x03,0xf7,0xc0,0xd7,0x16,0xab,0x58,0x04 +.byte 0xe8,0x95,0xc4,0x25,0x79,0xe8,0x18,0xb5,0x54,0x32,0xd4,0x75,0xf6,0x80,0xda,0x35,0xac,0x09,0xbf,0x37,0x1b,0xed,0x6e,0xdb,0xa1,0x42,0x14,0x49,0x11,0x4c,0x7a,0xda,0xed,0xc9,0x9d,0xe1,0x21,0x04,0x37,0x7a,0xbd,0x26,0x2d,0x40,0xc8,0x88,0x69,0x4d,0xd2,0x52,0x93,0xa2,0x6d,0x9a,0xd4,0xb0,0xdf,0x9a,0xc1,0x84,0xc5,0x08,0x5a,0xd9 +.byte 0x1f,0xbe,0x57,0x97,0x81,0x38,0x46,0x32,0xce,0xe3,0x0b,0x93,0x25,0x04,0xe5,0x7b,0xac,0xfd,0x37,0xc6,0x48,0x91,0x3c,0xef,0x5d,0x09,0xea,0x29,0xa9,0xc7,0x50,0x4b,0x47,0xe6,0xba,0xbd,0x96,0xe3,0x8e,0x9a,0x0f,0x8c,0x49,0xf4,0xe6,0xdf,0x3c,0xbb,0x51,0x12,0x8f,0x90,0x5e,0x77,0xd1,0x2e,0xd4,0xea,0x1f,0x34,0xac,0x6d,0xcf,0x74 +.byte 0xb6,0xd4,0xaa,0x89,0xe0,0xa6,0x37,0x77,0x34,0xad,0x1a,0x7d,0x97,0x63,0x13,0x83,0x82,0x67,0x61,0xed,0xd6,0xbf,0xda,0x6a,0x09,0xce,0x0f,0x53,0xef,0x42,0x22,0x69,0x0f,0x8e,0xbb,0x6d,0xa5,0x57,0xcb,0xe3,0x3c,0xbe,0xd7,0x2e,0xc1,0x67,0x32,0xc0,0xa8,0xbf,0xbf,0x11,0xdd,0xdf,0xfd,0xc6,0x44,0xbb,0xca,0x4e,0xd1,0x2d,0x61,0x3c +.byte 0xef,0xb4,0x8b,0xcd,0x76,0xa6,0x00,0xe0,0xb8,0x66,0x0c,0xed,0xd6,0x20,0xd3,0x27,0x33,0xcb,0x5e,0x76,0x33,0xbe,0xb4,0x3c,0x77,0x8b,0x14,0xec,0x93,0x16,0x54,0x1d,0x87,0x7d,0xeb,0xca,0x49,0xd3,0x2b,0xa6,0xbd,0xa5,0xe7,0x1a,0x3a,0x94,0xd9,0xb9,0xe0,0xaa,0x23,0x83,0x7c,0xe5,0xff,0x17,0xfd,0x14,0x63,0x8f,0xb8,0xff,0x93,0x8f +.byte 0xc7,0xa7,0x7b,0x43,0x31,0xd4,0xa8,0xf4,0x6c,0xab,0x2c,0x44,0xd4,0x7d,0x80,0x79,0x33,0x4c,0x15,0x41,0x20,0x14,0x02,0x04,0xcd,0x3b,0x66,0xe7,0xd7,0x0f,0x87,0xda,0xb1,0x45,0x74,0x14,0xa6,0xc4,0xaa,0x19,0xa6,0x8d,0x7e,0x51,0xed,0x5a,0x42,0xa4,0xb9,0x7b,0x8c,0x87,0xfd,0xe1,0x4a,0x58,0x15,0xf5,0x1d,0xcf,0x59,0xe5,0xbc,0x11 +.byte 0x10,0x7c,0xba,0x6b,0x47,0x9a,0xef,0x69,0x40,0xaf,0x3f,0x06,0x53,0x9f,0x96,0x55,0x30,0x83,0x9b,0x6a,0xfb,0xd3,0x93,0xf0,0x38,0x43,0xcb,0x5b,0xe4,0x23,0x0d,0x2c,0x1e,0xa9,0xe6,0xaf,0xd9,0xa9,0x19,0xf1,0xda,0x57,0x4b,0xd7,0x31,0x23,0x60,0x00,0x1b,0x88,0x15,0x68,0xe4,0xf1,0x26,0x1b,0x65,0xf5,0x6d,0xc8,0xc8,0x32,0x0e,0x65 +.byte 0x2e,0x49,0xbd,0x88,0x5a,0xc2,0x05,0xf9,0xee,0x07,0xf2,0x27,0x9b,0xeb,0x54,0x23,0x8a,0x10,0xe6,0x7d,0x5a,0xeb,0xb4,0xc5,0x34,0x4e,0xdf,0xa8,0x05,0xf2,0x35,0x68,0x74,0x83,0xf3,0x90,0x36,0x2c,0x46,0xcd,0x6d,0x27,0xe5,0x40,0x07,0xb8,0x34,0x6f,0x80,0xcf,0x17,0x9b,0xae,0x68,0x59,0x25,0xed,0x70,0x9e,0xb9,0xfa,0x89,0x44,0x10 +.byte 0x4d,0x6e,0xef,0x22,0x08,0x99,0x5e,0x07,0x9b,0xb7,0x31,0xfe,0x89,0x1c,0x7e,0x0c,0x0e,0xdf,0x4e,0xdc,0x04,0x43,0x67,0x27,0xfb,0x1d,0xd9,0x97,0x75,0xad,0x1d,0x6d,0x14,0x90,0x33,0x64,0x8c,0xbb,0xa4,0x61,0xcf,0x00,0x93,0xf4,0x4c,0xc2,0x49,0xda,0xc1,0xcd,0x55,0xba,0x39,0xa8,0x82,0x93,0xc5,0x3a,0xc9,0x4a,0x68,0x31,0x00,0x1b +.byte 0xcf,0x7a,0xaf,0xff,0x0c,0x86,0x92,0x2a,0xda,0x71,0x55,0xcc,0xba,0x50,0x61,0x0c,0xb0,0x6e,0xe9,0xac,0x21,0x29,0x70,0x5c,0xbd,0xc6,0x4c,0x8f,0x96,0xa8,0x5f,0x51,0x8b,0xec,0x9d,0x32,0x13,0x09,0x7e,0x1b,0xa2,0xec,0x14,0x66,0x90,0xae,0x04,0xe8,0x90,0xe3,0x46,0x82,0x17,0x69,0xa5,0x22,0xb0,0x28,0x1a,0x24,0xe6,0x27,0xd6,0x8b +.byte 0x97,0x54,0xbd,0x49,0xfb,0xb7,0xa7,0x17,0x6f,0xdd,0x84,0x1d,0x10,0x1a,0x40,0x79,0x98,0x40,0x4e,0xa5,0xa6,0x17,0x0d,0xe9,0x48,0xfe,0x73,0x95,0x2e,0x3f,0xb5,0x23,0x59,0x87,0x66,0x8a,0xa7,0x6a,0x98,0x6f,0x49,0x05,0x02,0x5a,0x6b,0x5f,0x46,0xdd,0x89,0xd1,0x4a,0x11,0x10,0xcf,0x0d,0x76,0x2e,0x4c,0xa4,0x15,0xd6,0xbd,0x2a,0xaf +.byte 0xff,0xe0,0x9b,0xd8,0x35,0x46,0x15,0xa5,0xf8,0x92,0xe1,0x5f,0x05,0x2a,0x45,0xe0,0x51,0x47,0x41,0x36,0xaf,0xbf,0x33,0x1b,0x8d,0xd8,0xf2,0x83,0xfd,0x01,0x4d,0x10,0xe7,0x60,0xd8,0x94,0x1b,0x51,0xcc,0x87,0x80,0xe8,0x59,0x87,0x4f,0x03,0x2c,0xef,0xbf,0xd6,0x0a,0x23,0xe8,0xb5,0x24,0x4c,0xe7,0x97,0xf0,0x83,0x95,0x25,0x42,0x0f +.byte 0xda,0xb8,0xd6,0x88,0x63,0x61,0x69,0xb5,0x0f,0xf6,0x31,0x3d,0xc6,0xc6,0x82,0xd8,0xc4,0xe5,0xce,0x09,0x30,0x4c,0xc7,0x87,0x39,0x47,0xae,0x18,0x46,0x23,0x11,0x8c,0x58,0x15,0xa8,0x22,0x63,0x16,0x44,0xe3,0x68,0x92,0x9a,0xac,0xec,0xdd,0x6d,0x17,0xbe,0xdd,0x73,0x14,0x7d,0xb0,0x7e,0xdf,0x75,0xa5,0x96,0xfd,0x7d,0x4e,0xa6,0xee +.byte 0x35,0x21,0x9a,0x16,0x22,0x89,0x69,0xcd,0x26,0xfd,0xbb,0x1a,0x76,0xb8,0xed,0x33,0x38,0x41,0x13,0x3d,0xce,0xd3,0xdd,0x99,0xa9,0xc4,0x4d,0x5b,0xd4,0x76,0xd7,0xbb,0x6e,0x59,0x78,0x43,0x43,0xb2,0x32,0x0d,0x30,0xe7,0xa7,0x90,0x7d,0xb0,0x5a,0x5a,0x99,0x7b,0xb3,0x7d,0x43,0x91,0x91,0xbc,0x2f,0x55,0x3f,0x6e,0x69,0x87,0x29,0x89 +.byte 0xd8,0xe8,0x0c,0x65,0x3e,0xab,0x21,0xee,0x1c,0xe1,0xc0,0x9e,0x2a,0xc7,0x3e,0xa9,0x94,0x58,0xad,0x74,0xf4,0x61,0x1f,0xdd,0x24,0xba,0x39,0x46,0x7e,0x11,0x1b,0x88,0xe6,0x69,0x28,0xfe,0xd0,0x38,0x61,0xc6,0x74,0x8b,0x33,0x89,0x32,0xe4,0x71,0xa2,0xd0,0xac,0x15,0x62,0x51,0xb4,0x55,0xbf,0xa1,0x1f,0x17,0x42,0x10,0x14,0x77,0x38 +.byte 0x9f,0xb8,0x14,0x2b,0x2f,0xf5,0x11,0xfc,0x1e,0x9b,0xa9,0xee,0x03,0xc3,0xc9,0x06,0x42,0xa7,0xa0,0xe1,0x76,0x8e,0xc5,0x6c,0x2f,0xec,0xeb,0x6d,0xb4,0xd8,0x56,0xeb,0x99,0x04,0x0d,0x1a,0xae,0x54,0xe5,0x47,0x91,0xcc,0xaa,0xc4,0x26,0x77,0x1b,0x89,0x0d,0xe7,0x7f,0x25,0x42,0x14,0x55,0x87,0x17,0x75,0x53,0x64,0x6c,0xf3,0x52,0x71 +.byte 0x2d,0xd2,0x17,0x80,0xca,0x52,0xb3,0x93,0x58,0xac,0xa0,0x8e,0x2b,0x8a,0xe7,0xbd,0x29,0xd7,0xd0,0xfa,0x3a,0xcb,0xc2,0x61,0x8e,0x04,0xc6,0x63,0xff,0x9c,0x31,0x36,0xcf,0x51,0x95,0xe9,0xd0,0xfe,0x6f,0x8b,0xe0,0x9a,0x9e,0x70,0x4e,0x29,0x1e,0xd3,0xec,0xde,0x9c,0x85,0x82,0xca,0x36,0xd4,0xf1,0x58,0x0e,0x38,0xc7,0x9b,0x61,0x87 +.byte 0x24,0x05,0xc5,0xeb,0xe1,0xa7,0xa7,0x65,0x2d,0x73,0x10,0x85,0x90,0xe6,0x3c,0x18,0x22,0x9a,0x59,0x8e,0xdc,0xfd,0xc9,0x3f,0x76,0x7c,0xe5,0xb6,0x9d,0xd5,0x84,0x9a,0xcc,0x02,0xa8,0x94,0xf0,0xa5,0xff,0x16,0x4a,0xe1,0x9f,0x23,0x5d,0x6e,0xc7,0x4d,0x93,0xfa,0x5f,0xa4,0x76,0xa4,0x91,0x64,0x95,0x67,0x3c,0x47,0x8a,0xe0,0x5f,0x93 +.byte 0x6b,0xa7,0x3e,0x56,0xfa,0xf1,0x1e,0xeb,0x03,0x45,0x17,0x2a,0xa2,0x78,0xe9,0x6d,0x0e,0x77,0x71,0x6f,0x40,0x94,0xce,0x28,0x16,0xa3,0xa9,0x44,0xa3,0x87,0x56,0xb1,0xf7,0xa7,0x9c,0x4c,0x22,0x69,0x8d,0x89,0x89,0xdb,0x2c,0xed,0x23,0x19,0x40,0x29,0x71,0xcd,0xf7,0xfa,0x9d,0xfe,0x04,0xb5,0xc0,0x8d,0xb0,0xb5,0x19,0x31,0x0b,0x1e +.byte 0xeb,0x2d,0x1d,0x13,0xab,0xee,0x8b,0x9f,0x87,0x04,0xc8,0xe3,0xaa,0xf6,0xb3,0xf0,0x44,0xa1,0xb0,0x8b,0xea,0xde,0x8b,0xfb,0x6d,0x93,0xdd,0x49,0x6a,0xab,0x6f,0xae,0xad,0xf6,0x5e,0x2a,0xe8,0xb5,0xb3,0x03,0x3f,0x09,0xe8,0x69,0x38,0xc7,0xb9,0xf9,0x56,0x94,0x50,0x73,0x31,0x21,0x4b,0x6e,0xd3,0x0f,0x5e,0x8f,0xcb,0x6a,0x06,0x08 +.byte 0x80,0x5b,0xd0,0x5d,0x5f,0x09,0xa0,0x31,0x46,0x4d,0x79,0x49,0xfc,0x4e,0x89,0x83,0xbb,0x6c,0x6d,0xc5,0x69,0x8f,0xb6,0xa6,0x99,0x0b,0xe5,0x0d,0xb5,0xa9,0xa7,0xc9,0x15,0xde,0x52,0xb3,0xa4,0x3f,0x3e,0xb2,0xb7,0x0c,0xe6,0x84,0x66,0x67,0x4c,0xa6,0x1a,0xbf,0xff,0x31,0xfb,0x69,0xee,0xc4,0xab,0x95,0xb6,0x5f,0x49,0x21,0x62,0x09 +.byte 0x70,0xb9,0xa0,0x41,0xca,0x23,0xd2,0xc0,0xde,0x5d,0x2e,0x3e,0x41,0x33,0x7a,0xa8,0x23,0x3a,0x11,0xf9,0x2d,0x3f,0x86,0xe8,0x46,0xbb,0xc1,0xa6,0xb3,0x63,0xf9,0x9e,0xbc,0xbd,0x90,0xef,0x11,0x94,0xda,0xbd,0x92,0xba,0x36,0x96,0x27,0x66,0x87,0x12,0x13,0xe7,0x04,0x25,0x01,0xa8,0x20,0xcb,0x34,0xfd,0x6a,0x97,0x48,0x36,0xf4,0xa1 +.byte 0x2d,0x56,0x61,0x72,0x9f,0x59,0x61,0x30,0xb4,0xb1,0x94,0xa8,0x71,0x08,0xd2,0x0b,0xa5,0x9c,0x3d,0x70,0xa4,0x54,0x61,0x82,0x4d,0x00,0x2a,0x7c,0x10,0x61,0x64,0x8e,0xd9,0x96,0x7d,0xdb,0xa0,0xcc,0x34,0xb4,0x24,0xea,0x46,0x12,0x81,0x65,0x52,0x68,0xb4,0xa1,0x56,0xdd,0x51,0x8b,0x4d,0x15,0xd9,0x72,0x9b,0x87,0x89,0xf3,0x31,0x6d +.byte 0x83,0xb5,0xa6,0xb5,0x91,0xbe,0x9a,0xb8,0x1e,0x1e,0x5e,0xec,0xe0,0x6c,0xd7,0x3e,0xcc,0x0b,0x9d,0x5b,0x26,0xcc,0xb8,0xfe,0x17,0x14,0x68,0xa3,0xb5,0x6b,0x0d,0x68,0x75,0x06,0x14,0x22,0x3e,0xc8,0x28,0xa6,0x2c,0xc7,0xd4,0x08,0xe7,0xa5,0x8e,0xe5,0x76,0xb6,0x3c,0xce,0xb2,0x54,0xcb,0x27,0x39,0x9d,0x49,0xfc,0x1c,0x9d,0xf4,0xa3 +.byte 0x46,0x98,0xae,0xd8,0x9b,0xed,0x85,0x17,0xe0,0xa4,0xd4,0xad,0xd3,0xed,0x1b,0x43,0x04,0xc5,0x10,0x36,0x8f,0x5e,0x06,0xfb,0x17,0x96,0x95,0xe5,0x8c,0x11,0x8c,0xb4,0xb0,0x6a,0xdf,0x8a,0xf8,0x75,0xe8,0x03,0xce,0xc2,0x43,0x26,0x98,0x48,0x3a,0x77,0x0b,0x34,0x22,0x78,0xee,0xc1,0x13,0x29,0x71,0xdd,0xde,0xd3,0x65,0x35,0xc2,0x28 +.byte 0xe2,0x8f,0x21,0xde,0x45,0xa1,0x14,0xff,0x79,0x0b,0xad,0x7b,0x9a,0x57,0x2c,0x08,0x4d,0x09,0x62,0x85,0x01,0xf0,0x9f,0xc3,0xf2,0xbd,0xfc,0x1a,0x4d,0xaa,0x89,0xbf,0xe1,0xb1,0x72,0x27,0x04,0x2d,0x6b,0x7d,0x18,0x73,0x10,0xee,0x32,0xbe,0x4b,0x0d,0xe7,0xd6,0x2b,0x68,0x2f,0xda,0x46,0x0e,0x6d,0x07,0x3f,0xea,0x46,0x0e,0x57,0x58 +.byte 0x71,0xa0,0x23,0x78,0x21,0x2a,0x8b,0xcc,0x2c,0x6b,0xcc,0x90,0xf6,0xb0,0x3a,0x70,0xef,0x7c,0x89,0x71,0xcc,0xc2,0x0b,0xab,0x8b,0x10,0xa9,0xf9,0x8e,0xca,0xf8,0xbf,0xa1,0x6a,0x20,0xf8,0x87,0x34,0x63,0x57,0x5f,0x5c,0x3a,0x71,0x6e,0x91,0x5f,0x4b,0xf6,0xc6,0x75,0xa7,0x98,0xdf,0x6a,0x57,0xb7,0x8c,0xbc,0xc3,0x26,0x35,0xd0,0x93 +.byte 0x3b,0xb1,0x51,0x95,0x1a,0x6f,0xae,0x6a,0x5e,0x55,0x27,0xae,0xe4,0x99,0x5d,0xb2,0x73,0x35,0xc1,0x37,0xae,0xc7,0x68,0xf3,0x62,0xdd,0xca,0xa3,0x9f,0x39,0x02,0xc7,0xdf,0x3c,0x97,0x96,0x5a,0xd4,0xea,0xea,0xb7,0x6b,0xc3,0x08,0x49,0x93,0xdb,0x9b,0xe5,0x7f,0x7e,0xc0,0x0a,0xf3,0x35,0x9e,0xe4,0x40,0x72,0x27,0x0f,0xc1,0x7b,0x8c +.byte 0x23,0xa6,0x52,0xa3,0xac,0xd7,0x63,0x10,0x83,0x86,0x36,0x2e,0x99,0xf0,0x75,0x53,0xa2,0x2e,0x7f,0xaa,0x22,0x39,0xf9,0xe5,0x6a,0x9b,0x72,0xa9,0xa2,0xc3,0x7c,0xce,0xd6,0x1b,0x1e,0xfe,0xd1,0xd4,0x52,0x58,0xe5,0xad,0x7c,0xbd,0x67,0xf0,0xa9,0x1f,0x5a,0xed,0xf3,0x4f,0x29,0x17,0x12,0x2c,0xbe,0x01,0x54,0x88,0x3d,0x4d,0xb4,0xd7 +.byte 0xd0,0xad,0x46,0x9d,0xfa,0x62,0xab,0xf3,0x3d,0xcf,0x4a,0x89,0xd7,0x60,0xa8,0xde,0x73,0xfe,0xa6,0x2f,0xad,0xf7,0x4d,0x03,0xff,0xbc,0x3c,0xf7,0x3d,0x58,0xc2,0xf1,0xe5,0x80,0xd3,0xf0,0x7a,0x90,0x2c,0xd2,0xf3,0x85,0xb8,0x30,0xbd,0xc2,0x35,0xd0,0x30,0xe1,0xdd,0x6c,0x31,0x08,0xbf,0x75,0x61,0xe1,0x79,0x07,0xa9,0xe4,0x46,0x80 +.byte 0x0b,0xf8,0x74,0xbf,0x7a,0x71,0x95,0x87,0x4f,0xc3,0x7e,0x32,0x9a,0x41,0xb5,0xa6,0x46,0x3c,0x07,0x1a,0x84,0x6a,0xf2,0xf2,0xc4,0xb1,0x0d,0x01,0xb4,0x9f,0x48,0x13,0xa3,0x8b,0x4d,0xbf,0x64,0x00,0x01,0xec,0x9d,0x35,0x1d,0xdc,0x62,0x92,0x19,0x48,0x3c,0x97,0x8e,0xee,0x29,0x6d,0x63,0x6c,0xb2,0x84,0x9b,0x16,0x84,0x89,0x6f,0x97 +.byte 0xd3,0x3e,0x98,0xb8,0x93,0x5d,0xd4,0xdd,0xc5,0x7d,0x55,0x4c,0x53,0x4e,0xf7,0x4b,0x32,0xa3,0xae,0x67,0xdc,0xe9,0x7c,0x7d,0x9f,0x62,0x4e,0xf9,0x59,0xff,0xf8,0xd9,0x81,0x54,0x2f,0xaf,0xbc,0xad,0xbe,0xc4,0xf5,0x2f,0x71,0x34,0x1c,0x79,0x21,0xb4,0xaf,0x6c,0x1d,0xc8,0xb0,0xd3,0x8b,0x8d,0x04,0xcb,0xf1,0x35,0xa8,0xde,0xa5,0xfb +.byte 0x9d,0xe5,0x98,0x8b,0xd2,0xd2,0x99,0x10,0x23,0xf7,0x0c,0x94,0xfd,0x9a,0x8a,0x4d,0x39,0x7e,0x79,0x2b,0x4a,0xe1,0x81,0x22,0x0d,0xb7,0x44,0xb1,0x9f,0x7b,0xd5,0xa6,0x7e,0x62,0x5c,0x3d,0x0f,0x00,0xf8,0x82,0xd0,0x30,0x05,0x05,0xc8,0x6e,0xc3,0x5c,0xdd,0xf8,0x18,0x7d,0x44,0xaf,0x28,0x5d,0x84,0x21,0xd2,0x5a,0x78,0x52,0x65,0x15 +.byte 0x13,0xfb,0x25,0xb3,0xa4,0x7d,0x2f,0x5c,0xef,0xf6,0x6d,0xb4,0x9f,0xb6,0x21,0x9e,0xec,0xa5,0x15,0xc9,0xf0,0x92,0x92,0x36,0x49,0x46,0xea,0xe3,0x4b,0x38,0x5b,0xfa,0xc1,0x87,0x75,0x79,0x82,0xa0,0x37,0x30,0xca,0x0c,0xec,0x5b,0x5b,0xcd,0x1d,0x30,0xeb,0x63,0x11,0x66,0xb3,0x5f,0x81,0xfd,0x69,0x32,0x80,0x08,0x06,0xcf,0xbf,0xb0 +.byte 0x31,0xec,0xa9,0x8f,0x66,0x00,0x05,0x55,0x04,0x0d,0xcf,0xb9,0x3f,0xcc,0x5b,0x1a,0x11,0xb4,0x96,0x39,0x70,0x26,0xd2,0x4d,0x4e,0xac,0x2b,0x36,0x4c,0x77,0x0b,0xc2,0x9b,0xd0,0xc6,0x03,0xc6,0xec,0xdd,0x74,0x53,0xe5,0x8a,0x9c,0x17,0xe0,0x1b,0xe8,0x1e,0xfb,0x9a,0x11,0x61,0x68,0xe0,0xf5,0x3e,0xe2,0x3a,0x4a,0x20,0xa0,0xe1,0x40 +.byte 0xbe,0xdd,0xec,0x5e,0x1f,0x0f,0x87,0x9f,0x5d,0xc6,0x4b,0x2e,0x81,0x52,0x25,0x59,0x3e,0x3d,0xbb,0xb5,0x32,0x88,0xc0,0x3a,0x15,0x0d,0x77,0x9e,0x9e,0x31,0x26,0x61,0x24,0xa4,0xe6,0x35,0x50,0xca,0x61,0x55,0x8f,0x0a,0xaa,0x7c,0x3f,0x9e,0x30,0x04,0x03,0xa2,0x3c,0x2a,0x02,0xf4,0x70,0x9e,0xe7,0xa5,0x6e,0xb7,0x9b,0x4c,0x47,0xe5 +.byte 0x1b,0xa7,0x91,0x36,0x1c,0xed,0x84,0xab,0xf4,0x33,0x56,0xb6,0x94,0xb8,0xa0,0x68,0x34,0x15,0x87,0xc6,0x7b,0x36,0xea,0x51,0x94,0xeb,0xde,0x6e,0xfd,0xde,0xe1,0x3c,0x44,0x04,0x8e,0xb1,0x35,0x4b,0x8c,0x2b,0xd2,0x4b,0x63,0x48,0x0c,0xbd,0x92,0x61,0x39,0x4d,0xdd,0xc9,0xb9,0x1f,0xf6,0xc8,0x70,0xfd,0x9c,0xd2,0xef,0x71,0x6c,0x32 +.byte 0x99,0x2c,0xa5,0x8e,0xa9,0xb5,0x0f,0xeb,0x8d,0x9a,0xbc,0x2a,0x3f,0x11,0x68,0xb6,0xdf,0x93,0x4d,0xd3,0x6c,0x00,0x45,0xc3,0x5a,0xad,0xaa,0xe7,0x31,0x9c,0xad,0x9a,0xe4,0xf7,0xda,0xa0,0x5b,0x0b,0x23,0x78,0x40,0x92,0x12,0xe9,0x66,0x7c,0x04,0x60,0xbd,0xd2,0x74,0xcf,0xc9,0xd7,0xae,0x47,0x69,0x4b,0x5b,0x16,0x64,0x48,0xca,0x03 +.byte 0x27,0x30,0x4c,0x65,0x0c,0xbf,0x74,0x03,0x81,0xaf,0xa2,0xb4,0x45,0xfe,0x9e,0x66,0x3a,0xa2,0xc8,0xce,0xc3,0x5e,0x6b,0xc7,0x70,0x51,0xfa,0xe3,0xce,0xc3,0x18,0x7b,0x39,0xfc,0x6f,0xae,0x31,0x09,0x2d,0x63,0xb7,0xb8,0x43,0x5c,0x78,0xa9,0x35,0xae,0x87,0x2a,0xf0,0xbc,0xc1,0xd8,0x21,0x02,0x2e,0x11,0x6b,0x41,0xa9,0x21,0x8d,0x94 +.byte 0x70,0x85,0x08,0x22,0x9e,0xae,0x38,0x23,0x07,0x97,0x72,0xd5,0xa6,0x3c,0xb2,0xb9,0xaf,0x2e,0x8f,0xd3,0x25,0xaa,0xc4,0xee,0x77,0x72,0x17,0xe4,0xa8,0x4a,0xf4,0x79,0x8c,0x37,0xa1,0x80,0xbb,0x82,0x29,0x3a,0x7c,0x8a,0x6f,0x3a,0x83,0xaa,0x94,0xf3,0x95,0x66,0x0e,0xdd,0x51,0x09,0x12,0xf8,0x1d,0xb9,0xa8,0x83,0x2d,0x29,0x34,0xd5 +.byte 0x53,0xcd,0xeb,0x22,0x31,0x22,0xea,0x65,0xb4,0x8c,0x0c,0x1b,0xf7,0x72,0x54,0xed,0xd3,0x2e,0xd6,0xc2,0xed,0xe9,0x12,0x61,0x7a,0x51,0xc8,0x50,0x01,0xf9,0xe8,0x12,0x43,0x4e,0x58,0x29,0xec,0xeb,0xdb,0xcd,0x94,0xba,0xaa,0x87,0x4d,0xbf,0x20,0x3e,0x31,0x05,0x7b,0x5a,0xfa,0x9a,0x16,0x14,0x11,0x2c,0x9f,0x96,0xe6,0x38,0xff,0xfa +.byte 0x4e,0x05,0x3f,0xcb,0x13,0xdd,0x4e,0x70,0x41,0xce,0xb8,0xae,0xc2,0xf7,0x67,0xa0,0x68,0xb5,0x8d,0x03,0x72,0x4a,0x0e,0x27,0x99,0xef,0x09,0x32,0x3c,0x77,0xde,0x9c,0xfd,0x6c,0x65,0xcd,0x6b,0x10,0x42,0x08,0x12,0x30,0xa4,0x0c,0xdd,0xc9,0x86,0xc6,0xe8,0x84,0x6d,0x69,0x71,0x45,0x6b,0xb5,0xcb,0x74,0x81,0xe9,0x34,0xa5,0xf1,0x66 +.byte 0x2e,0x31,0xcb,0xf8,0xec,0x9e,0x97,0x7e,0x3d,0x16,0xd7,0xab,0x5b,0xc8,0xf7,0x4f,0x59,0xbe,0x1f,0x12,0xfa,0x0d,0xb1,0x76,0x2d,0xe4,0x00,0xd9,0x30,0x3e,0x73,0x0a,0xa7,0xf7,0x19,0x06,0xe7,0xd4,0x81,0x2f,0xf0,0x8b,0x44,0xa9,0xaf,0xc8,0x95,0xd8,0xbb,0x92,0xb8,0x2f,0xd3,0x2c,0xcb,0x3e,0x5f,0x4e,0x42,0x2f,0x98,0x88,0xbc,0xf4 +.byte 0x46,0x94,0x1d,0x5a,0x23,0xc8,0xb2,0x28,0x67,0xa7,0x26,0x1e,0x37,0x21,0x8a,0x7f,0xdc,0x8e,0x1c,0xa3,0x50,0x95,0x07,0xdf,0x8d,0x7b,0xab,0x29,0xc1,0x87,0x69,0x6a,0x8e,0xdf,0xcf,0x5f,0xb7,0x1b,0x8f,0xc7,0xc4,0x63,0x27,0x43,0x17,0x3d,0x29,0x94,0x71,0xa5,0xcc,0x1c,0xbf,0xc5,0x4a,0xd5,0x5e,0xe9,0x6d,0xa6,0x00,0x0b,0x41,0xe0 +.byte 0x91,0x73,0xc9,0x22,0xf3,0xb2,0x5b,0x95,0xc8,0x5c,0x43,0xe2,0x48,0x3a,0x7e,0x67,0xf1,0x95,0x49,0xd9,0x47,0x68,0xc5,0xbf,0x28,0x2e,0x8c,0xcf,0x26,0xc2,0x23,0xec,0xb2,0xef,0xff,0x29,0x3d,0x7f,0x3f,0x4c,0xfb,0x7a,0x0d,0x80,0x89,0x0c,0x6d,0x45,0xf8,0xb9,0x72,0xa9,0x5b,0xbe,0x51,0x46,0x3b,0xe2,0x08,0x73,0x87,0x72,0x3e,0x1b +.byte 0x7e,0x05,0x9d,0xce,0xc7,0x14,0xbe,0x36,0xa9,0xf8,0x5f,0x3e,0x3c,0x82,0x83,0x75,0xd7,0x96,0x9e,0x1b,0x6d,0x5b,0x2b,0x7d,0xdd,0xb9,0x42,0x19,0xbe,0x57,0xe3,0x9b,0xcc,0x3d,0x26,0x80,0xec,0x68,0x52,0x8f,0x85,0xd2,0x12,0x7b,0xe1,0x31,0x64,0xd6,0xde,0xe1,0xc1,0x8e,0x8c,0x66,0x8c,0x6b,0xb2,0x5f,0x75,0x9a,0x1b,0x96,0x78,0xb5 +.byte 0x79,0x53,0xbb,0x70,0x4c,0x5e,0x8e,0x60,0xfa,0x1e,0xee,0xde,0x8d,0xd1,0x33,0xf6,0x36,0x95,0x00,0x6f,0xba,0xc7,0xf4,0xd1,0x96,0x33,0xf8,0xa2,0x20,0x65,0xf3,0x97,0x7d,0x0b,0x68,0x23,0x3d,0x39,0x54,0x67,0xb5,0xfc,0xff,0x48,0x04,0xb0,0xd2,0xea,0x09,0x1b,0xff,0x41,0x00,0xff,0x2d,0xc6,0x9f,0x8b,0x37,0xc9,0x35,0x37,0x38,0xd7 +.byte 0x68,0x0e,0xa9,0x9b,0x19,0x25,0x17,0x94,0x55,0x0b,0x09,0x7f,0xc5,0x2f,0xb5,0x93,0x61,0x91,0x30,0xe5,0x46,0x09,0xff,0xf7,0x9d,0x7d,0x5e,0x9a,0x0e,0x5f,0xc1,0x2f,0xf3,0x09,0xc6,0xb2,0x86,0xca,0x0e,0x6f,0x3e,0x17,0x43,0x7d,0x4d,0x51,0x33,0x2b,0x57,0xf8,0xd0,0x1a,0x0e,0x8e,0xe6,0xc3,0x87,0x35,0xe4,0x53,0x3c,0xdf,0x9a,0xc9 +.byte 0x5a,0x5d,0x40,0x80,0x90,0x97,0x7f,0x8c,0x55,0xbe,0x19,0x57,0x96,0x55,0x2e,0x7b,0x27,0x79,0x19,0xeb,0x8e,0x7a,0x27,0xf0,0xc4,0x9a,0x16,0x12,0xc9,0x41,0xdd,0xec,0x12,0x58,0x95,0xca,0xc7,0x77,0xd8,0xd8,0x17,0xa5,0x9b,0x79,0x8c,0xcb,0x04,0x07,0x69,0x06,0xf2,0x71,0x33,0x5e,0x96,0x56,0x90,0x75,0xa3,0x1b,0x4b,0x1b,0x18,0x71 +.byte 0x18,0x25,0xc2,0x81,0x16,0xb6,0xd1,0x35,0x53,0x58,0x2f,0x49,0x4e,0xf0,0xab,0x23,0xa9,0xc8,0x28,0xc8,0x8a,0x2a,0x94,0x55,0x72,0xa2,0xf0,0x25,0x47,0x30,0x85,0x79,0xba,0x91,0x38,0xfe,0xbf,0x9d,0x05,0x8d,0xf7,0xd5,0x77,0x71,0x06,0x22,0x14,0x8b,0xb6,0x42,0x90,0x39,0xca,0x23,0x78,0xde,0x54,0x0e,0xe8,0xc5,0xb4,0xd6,0x07,0xf6 +.byte 0x4e,0xa9,0xb4,0x9a,0xa1,0x03,0x36,0x83,0xb9,0x69,0x29,0xf5,0xc6,0x98,0x9f,0x47,0x53,0x46,0x13,0xf3,0xe5,0x93,0x28,0x20,0x5d,0x1f,0x0f,0x6a,0xee,0xa8,0xc1,0x96,0x7f,0xcb,0xf4,0xc3,0x17,0x95,0x6a,0xe5,0xc7,0xb3,0x77,0x0e,0xa8,0x9f,0x91,0xfd,0xb2,0x4b,0x7d,0xf7,0x78,0x57,0x9e,0x87,0xd7,0xf4,0x3e,0x81,0xc4,0x91,0x71,0xd9 +.byte 0x6b,0x21,0x78,0x82,0x8a,0x03,0x5b,0x2e,0x89,0xc9,0xd4,0xca,0x5d,0x32,0x57,0x43,0xb0,0xe5,0xe3,0x9f,0x93,0xb5,0x4d,0x52,0xce,0xe6,0x46,0x05,0xe8,0x36,0x26,0x35,0x90,0x69,0x0c,0x8e,0xf0,0x65,0x03,0x65,0x32,0x10,0xae,0xdd,0x85,0xdd,0xef,0x84,0x0e,0xd1,0x03,0x51,0x02,0x0b,0x37,0x0f,0xdf,0x95,0xbb,0x5b,0xe2,0x25,0xda,0xd6 +.byte 0x0a,0x55,0x55,0x8a,0x3a,0x72,0xca,0xc3,0x6f,0x84,0xe9,0x09,0xad,0x2f,0x73,0x1b,0x99,0xa6,0x22,0xc4,0xc5,0xf2,0x40,0x44,0xd8,0x4b,0x7a,0x75,0x82,0x06,0x9c,0x0f,0x73,0x89,0xa3,0x57,0x3a,0xf7,0x36,0xcf,0x86,0x34,0x2f,0x37,0x01,0xcf,0x4b,0x4d,0x83,0xe4,0xe3,0x92,0x1c,0xe7,0x67,0x01,0x72,0xec,0x50,0xe0,0x9f,0x0a,0xa9,0x41 +.byte 0xe2,0x4d,0x43,0x01,0x14,0xe0,0xbc,0x11,0x4f,0xf8,0xdb,0xab,0x6f,0x07,0x5a,0x71,0x28,0xb9,0xaf,0x6e,0xd1,0x3d,0x3c,0x6e,0xd9,0xa9,0xe4,0xe2,0x71,0x40,0x31,0x9d,0x48,0xcb,0x76,0x3e,0x5d,0x0d,0xb4,0x11,0x0c,0x4d,0x89,0xba,0x16,0x8a,0xd6,0x43,0x99,0x65,0xec,0xbd,0xdd,0xae,0x4a,0xb4,0x6c,0x77,0x36,0x5b,0xef,0x51,0x33,0xcd +.byte 0x3f,0x55,0xc5,0x00,0x25,0x85,0x0b,0x83,0xd6,0x22,0x70,0xb5,0x32,0x7f,0xb0,0x02,0x7b,0x8d,0x8c,0x09,0x37,0xf6,0x26,0x95,0xe2,0xb2,0x4c,0x7f,0x18,0x50,0xe9,0x96,0x65,0xe8,0x1a,0x70,0xff,0xbb,0x1e,0x35,0xda,0x41,0xbd,0x89,0xa8,0x7f,0xb0,0x85,0x05,0xd7,0xd1,0x11,0x66,0x2f,0xf6,0x66,0x50,0x05,0x66,0x58,0xb2,0x2a,0x5d,0xad +.byte 0x42,0x60,0x14,0x7c,0xad,0xba,0x03,0xf8,0xce,0x29,0x6b,0x13,0xb3,0xdf,0xd1,0x5a,0x7a,0x11,0x8a,0x8b,0x6c,0x62,0x12,0xc3,0x77,0x28,0xcc,0x34,0x18,0x67,0x46,0xb5,0xda,0x87,0x1f,0x65,0x01,0xe7,0xe3,0x55,0x17,0xaf,0xd3,0x40,0x32,0x23,0x16,0x0a,0x57,0x86,0xab,0xdb,0xd8,0x18,0x71,0x96,0x11,0x1c,0xc1,0x87,0xaf,0xc9,0x7a,0xfa +.byte 0x07,0x2a,0xdc,0x95,0x08,0xff,0xea,0x78,0x84,0x63,0x18,0xd5,0x54,0x6e,0x85,0x8e,0xcd,0xd6,0xff,0xea,0x8c,0xad,0xc4,0xdb,0x4f,0x33,0xcb,0x5c,0x01,0x6c,0xc4,0x60,0x04,0x43,0x7b,0x53,0x29,0x99,0xff,0xcd,0x4c,0xf1,0x82,0x11,0x85,0x84,0xf4,0xe5,0x29,0x65,0x6c,0x9f,0xb1,0x2b,0xa5,0xb5,0xc1,0xd6,0x5f,0xb7,0x0c,0x7b,0xf6,0x17 +.byte 0xb7,0x80,0xaf,0xd2,0x9e,0x20,0x6e,0x01,0x5c,0x09,0x6b,0xd5,0xe3,0x4a,0x43,0x60,0x7e,0xc8,0xb4,0x1c,0x08,0x79,0x8e,0x48,0x71,0x22,0x81,0xd9,0x81,0x19,0x0a,0x04,0x29,0xce,0x09,0x70,0x82,0x49,0xc0,0xc0,0x3f,0xcc,0x9f,0x18,0x9a,0xd5,0x5e,0xde,0x70,0xdb,0x85,0xd8,0x53,0x71,0x7f,0x03,0xf1,0xf3,0x07,0x52,0x79,0x44,0xea,0xac +.byte 0xd9,0xf3,0x0c,0x1e,0xb5,0x57,0xf8,0xfb,0x41,0x69,0xf1,0xf5,0x40,0xc7,0xd7,0x94,0x06,0x95,0x3a,0x49,0x0c,0x09,0x84,0xa7,0x1c,0x42,0x52,0x65,0xb9,0xef,0x6f,0x9b,0x37,0x5e,0xc3,0x3e,0x6b,0x96,0x93,0x02,0x94,0x9a,0xdc,0x04,0xb2,0x85,0x3c,0xa9,0x5b,0xa0,0x55,0x2e,0xaa,0x06,0xfd,0xc6,0xbc,0x73,0x32,0x08,0x26,0x5b,0x0a,0xa2 +.byte 0x42,0xf2,0x61,0xb8,0x09,0xf0,0xaa,0xee,0xb7,0x35,0x63,0xe5,0xb2,0xfe,0xec,0xe7,0xae,0x62,0xf2,0x43,0x12,0xde,0xb4,0x8f,0xc1,0x06,0x72,0xde,0x7d,0x75,0x54,0x07,0x4a,0x99,0x83,0x39,0x97,0x9c,0x1e,0xd4,0xaf,0x2a,0x8c,0xb4,0x92,0xb5,0x9a,0xf7,0x87,0x8f,0x60,0xda,0xe5,0x01,0xca,0xc6,0x61,0x3d,0xb1,0xbe,0x33,0x58,0x2e,0xb1 +.byte 0x7e,0xa1,0x3b,0x93,0x8d,0x25,0xe3,0xb4,0xea,0x94,0x26,0xbe,0xa9,0xf9,0xa1,0x2f,0x61,0xf4,0x7c,0x32,0x31,0x2e,0x99,0xdb,0xa4,0x3f,0xbf,0xd9,0xdb,0xca,0xd8,0x3d,0xda,0x44,0xe0,0x14,0x39,0x18,0xff,0x3e,0x5b,0xd2,0xc9,0x91,0xe1,0xa1,0xea,0x3f,0x1b,0x0e,0xd6,0x82,0xa6,0xb1,0xa2,0x6f,0x85,0x51,0xfc,0xa8,0x47,0xd7,0x87,0x28 +.byte 0xc6,0x2f,0x2a,0x9f,0xad,0x7e,0xcc,0xd9,0xd2,0xfa,0x4c,0x28,0xca,0x66,0x55,0x1e,0x26,0x6d,0x19,0xe4,0x47,0x25,0x18,0x12,0xc5,0xe1,0x12,0x43,0x7c,0x96,0xb7,0x52,0xa6,0x07,0x04,0x83,0x44,0x82,0xcd,0x4e,0x79,0x07,0x0c,0x01,0xe4,0x81,0x25,0x98,0xce,0x2e,0x07,0x3c,0x76,0x39,0x37,0xc0,0xd0,0x54,0x14,0xaf,0x6c,0x87,0x99,0x1e +.byte 0xf2,0xa3,0xd6,0x32,0x40,0xd1,0xe4,0x8d,0x60,0x32,0xf7,0xb0,0xaf,0x05,0x10,0x04,0xaa,0x99,0xfa,0xea,0x39,0x58,0x5f,0x30,0x06,0x2b,0x6d,0xd6,0x68,0x1c,0x85,0xcf,0xda,0xa9,0xd6,0xc3,0x05,0xd7,0xe3,0x3b,0x8c,0xc1,0xfe,0xf8,0x58,0x1d,0x1f,0x7b,0x80,0xcc,0xf3,0x4b,0x6f,0x3c,0x52,0x62,0x97,0x15,0xeb,0x5b,0x0f,0xaa,0x77,0x6c +.byte 0x82,0x63,0x5e,0x84,0xbe,0xc5,0xb5,0x50,0x48,0x7c,0x56,0xbf,0x3a,0x8c,0xb4,0xbc,0x3e,0x8e,0xcf,0x2d,0xa2,0x26,0x3d,0xde,0x9d,0x4b,0xda,0xa4,0xd9,0x9b,0x6d,0xeb,0x35,0x44,0xa9,0x06,0x20,0x39,0x83,0xd5,0xeb,0x09,0xf0,0x45,0xdb,0xbb,0x9d,0x53,0x4d,0xbe,0xe3,0x3e,0x66,0xee,0xb2,0xce,0x3a,0xf0,0x75,0x92,0x58,0x79,0x5a,0xba +.byte 0x1b,0x75,0x6b,0x83,0x0a,0xb6,0xe0,0x52,0xd3,0x61,0x2a,0xc0,0xa9,0x41,0x15,0x8c,0xd9,0x6b,0x87,0x94,0xda,0x31,0x0c,0x14,0x3e,0x37,0xd2,0xed,0xf6,0x40,0x57,0x70,0xc5,0xf5,0x0e,0xc4,0x3b,0x51,0xdf,0x4c,0xd2,0x42,0xbc,0xa5,0x3b,0x88,0x78,0x85,0x16,0x6c,0xaf,0x19,0xcf,0xb0,0x6a,0x42,0x07,0x66,0xf6,0xa7,0x4a,0x77,0x87,0x5f +.byte 0x81,0x78,0x84,0xea,0x86,0xeb,0xe9,0x86,0xba,0x00,0xb4,0xe2,0xe7,0xd0,0x91,0x3d,0x9c,0x80,0xd6,0x37,0x86,0x96,0x80,0xcc,0xa0,0x8d,0xaa,0xc3,0x4f,0x79,0x9d,0xb8,0xa6,0xfb,0x0e,0x34,0x0d,0x54,0x1d,0xc1,0x51,0x62,0xb1,0x7b,0x8a,0x63,0x2c,0xbd,0xac,0xc7,0x6d,0x03,0xa2,0xdc,0xba,0xc9,0x70,0x9b,0x34,0x19,0x26,0x7f,0xd1,0x1e +.byte 0xf7,0x47,0x38,0x3c,0x50,0x28,0xf8,0xba,0x0e,0xa0,0xfb,0x03,0xa1,0xb4,0x5e,0xf7,0x77,0xec,0x5d,0x94,0x6e,0xe6,0x40,0x1d,0xe4,0x0d,0x23,0x9f,0xe1,0x8c,0x7f,0xfa,0x83,0xd9,0x39,0x67,0xbd,0x41,0x82,0x37,0x7c,0x6a,0xc5,0x74,0x0d,0x41,0x35,0x55,0x64,0x7f,0x4c,0x3e,0x13,0xfc,0x41,0x4f,0x5e,0x1b,0xd8,0x4d,0x02,0x28,0x29,0x20 +.byte 0x4c,0xcd,0x1b,0x5f,0xe7,0x51,0x68,0x2d,0x05,0xea,0x35,0x20,0xac,0x5b,0x44,0x70,0x02,0x55,0x20,0x17,0xcb,0xb5,0xd0,0xbf,0x79,0x33,0x02,0x69,0xa1,0xb0,0x24,0x10,0x62,0x0a,0x66,0x7c,0x0b,0xb2,0x50,0xa0,0xf6,0x94,0xf1,0x98,0xc7,0x8c,0x4a,0xef,0x03,0xb1,0x7e,0xe7,0x60,0xc0,0x38,0x7e,0xbf,0xbd,0x7a,0xa8,0x0b,0xe5,0x2d,0xed +.byte 0x68,0xb0,0x37,0xa2,0x9b,0x6e,0x20,0x06,0xd2,0x7c,0xf7,0x50,0x03,0x19,0x74,0xf5,0xc8,0x84,0x44,0xeb,0x63,0x3f,0x10,0x63,0x36,0x62,0x48,0x96,0x4d,0xde,0xf2,0x08,0xc6,0xf4,0x09,0xeb,0x37,0xe8,0x0f,0x29,0xb5,0x9f,0xe6,0x58,0x86,0xf5,0xeb,0x18,0xa8,0xe0,0x28,0xf4,0x79,0x1f,0x98,0x60,0x82,0x67,0x06,0xfd,0x21,0x04,0x4d,0x33 +.byte 0x17,0xc5,0x2f,0x3e,0x0d,0x8d,0x02,0x37,0x9b,0x66,0xb0,0x06,0x09,0xe0,0x92,0x10,0xb9,0x04,0x3a,0xc6,0x42,0x34,0x70,0xcb,0x51,0xd0,0x78,0xd3,0x0e,0x83,0x65,0x00,0xcf,0x95,0x83,0x51,0xca,0x62,0xfe,0x3e,0x3f,0xc4,0x7f,0x10,0x5b,0x85,0x00,0x5f,0x7d,0x38,0x93,0xf3,0xb7,0x33,0xbd,0x4c,0x1d,0xcd,0xc9,0xfa,0x05,0xb6,0x31,0x78 +.byte 0xc8,0xc8,0x51,0x34,0xd6,0xb5,0x1a,0xa2,0xdb,0x7f,0x3d,0x8a,0x1b,0x49,0x36,0xaf,0x49,0x99,0x10,0x65,0xbe,0x19,0xf9,0x9f,0xaa,0xd6,0xc6,0x69,0x52,0x42,0x79,0x6b,0x64,0x53,0x90,0xb7,0x7f,0x7f,0xd2,0xde,0xe2,0xda,0x5f,0x3e,0xa6,0x5d,0xf2,0xcc,0x8a,0x88,0x2f,0x44,0xcf,0x07,0x77,0x7b,0x20,0x55,0xcc,0xa4,0x48,0x7d,0x87,0x6a +.byte 0x25,0x35,0x07,0x7c,0x37,0x02,0xb5,0x7c,0x5f,0x2d,0xc2,0x92,0x1d,0xe5,0xb2,0x55,0x85,0xdd,0x58,0x24,0xc3,0x2a,0x11,0xca,0x02,0x36,0x44,0x96,0x7a,0xf3,0x42,0xfd,0x05,0xf8,0xe1,0xa0,0x06,0xd8,0x3f,0x37,0x4e,0x15,0xca,0x1c,0xe8,0x8d,0x20,0xed,0x83,0xa2,0x42,0x9a,0xe5,0x51,0xf0,0xae,0x43,0x9d,0xa8,0x76,0xb8,0xf6,0xca,0x06 +.byte 0x5d,0xa1,0x61,0x36,0x4c,0x13,0x75,0xe5,0xbf,0x5c,0x40,0x43,0xa0,0x50,0x4e,0xf7,0xea,0x35,0xa2,0x43,0x38,0x6b,0x20,0x3a,0x8b,0x05,0x28,0xbe,0x72,0x16,0x48,0x9c,0xbf,0x2d,0xff,0x1e,0x0f,0x08,0x3b,0xaa,0x49,0x42,0x72,0x92,0x3b,0x4f,0x28,0x8b,0xab,0x4e,0xa0,0xaf,0x36,0xba,0x7e,0x19,0xa7,0xc7,0xfd,0xd4,0xe2,0x80,0x33,0x2b +.byte 0xb9,0x2d,0x81,0x65,0x43,0xe1,0x3e,0xab,0xa5,0x36,0x00,0x68,0xb8,0xd8,0x27,0x64,0x85,0x10,0x67,0x68,0xd0,0x66,0xeb,0x2f,0xf2,0xa0,0x6e,0x6b,0xd5,0xc3,0x5f,0xa3,0x95,0xc8,0x5e,0x0f,0x3d,0x61,0xb3,0x12,0x99,0xd6,0x9a,0xe5,0x40,0x47,0xb4,0xcf,0x83,0xf2,0x79,0x31,0x18,0x54,0x6e,0x9c,0x32,0x63,0x2f,0x06,0x94,0x7a,0xd7,0x46 +.byte 0x5b,0xd4,0xe3,0x58,0xbf,0x54,0xeb,0x47,0x85,0x47,0xe1,0x47,0x11,0x08,0x20,0x75,0x33,0x5c,0xed,0x58,0x26,0x5b,0x0f,0x4e,0x0f,0x8c,0x25,0x8c,0x36,0x28,0x03,0x73,0x93,0xb0,0xc8,0x9f,0x5e,0xd7,0x9e,0x57,0x88,0x07,0x92,0x1a,0xa0,0xfe,0xd0,0xc6,0x1c,0x7c,0x48,0x34,0x52,0x10,0xd1,0x3a,0x82,0x8d,0xe9,0x52,0xa1,0xfe,0x87,0x0f +.byte 0x04,0x6a,0xb0,0x67,0xc6,0xd7,0x09,0x00,0x66,0x35,0x6a,0x67,0x12,0x92,0xf5,0xbb,0xc5,0x16,0x0d,0x20,0x71,0x52,0x30,0xbe,0x03,0xb2,0x36,0xcf,0x88,0x11,0xb0,0x93,0x4a,0x4f,0xb3,0xc5,0x7f,0xbe,0xff,0xc0,0x68,0xd7,0x44,0x6e,0x98,0x42,0x4b,0x21,0xbe,0xe3,0x33,0x30,0xa3,0xa5,0x3c,0x66,0x79,0xaf,0xe6,0x58,0x42,0x5e,0xc6,0xf9 +.byte 0x5e,0xea,0x0a,0x5f,0x08,0x2d,0x96,0xa3,0xcc,0x17,0xf6,0xac,0x67,0xba,0xc4,0xf7,0x40,0xca,0xc3,0x66,0x36,0x01,0x29,0xcf,0xc2,0x1e,0xfa,0xe2,0xba,0x44,0x36,0xda,0xf6,0xc5,0x53,0x35,0x64,0x74,0x0d,0x16,0x75,0x2a,0x82,0x3a,0x4e,0x5a,0x2c,0x62,0x23,0x2a,0x66,0x0f,0xad,0xdc,0x44,0x77,0x2f,0x78,0x74,0x82,0xe2,0xbf,0x3e,0x19 +.byte 0x00,0x58,0xb7,0x65,0xb0,0x24,0x87,0xc5,0xe0,0x7c,0xbd,0x3a,0x97,0x30,0xa7,0xd4,0x79,0x91,0x96,0x7e,0x7d,0x75,0xf5,0x9d,0xb3,0x0e,0x2a,0xde,0x08,0x96,0xb6,0xdc,0xa4,0xf6,0xf7,0xa4,0xde,0xb7,0x9b,0xc5,0x75,0xdf,0xa6,0xe1,0x6f,0x5a,0x9f,0xaf,0x1d,0x60,0xac,0xde,0x1a,0xb9,0x02,0x0b,0xc5,0x6e,0x24,0x59,0xf9,0xc8,0xdc,0x97 +.byte 0x53,0xf4,0x1b,0xf8,0x53,0x80,0x34,0xaa,0x53,0xaf,0x06,0x79,0xeb,0x39,0x72,0xd4,0x1d,0xf2,0xb7,0x26,0x41,0x8c,0xc5,0x6d,0x86,0xf8,0x34,0x98,0x98,0xa0,0x19,0x2e,0x9f,0xb0,0x0b,0xe8,0x3d,0xef,0xe1,0xb6,0x18,0xc3,0x63,0xc4,0x0e,0x6e,0x92,0x41,0x43,0x9a,0x2a,0xe3,0x3a,0x9f,0xac,0xac,0x0a,0xe8,0x6a,0xa4,0xa6,0x97,0x0e,0xd9 +.byte 0xbd,0x97,0x57,0x38,0x6c,0x2c,0xa4,0x62,0xdb,0xea,0xb6,0x90,0x4c,0x7c,0x29,0xd2,0x06,0x24,0x57,0x5d,0x2c,0x71,0xb4,0xa5,0x13,0x5e,0x6e,0xb5,0x42,0x7e,0xb5,0x3f,0xd0,0x49,0xa5,0xd2,0xf6,0xe5,0xc8,0x86,0xef,0xae,0xcc,0x98,0x5f,0x0d,0x43,0x20,0x2f,0xe4,0x90,0xd1,0x1d,0x66,0xc4,0x38,0x7f,0x63,0xea,0x39,0x8b,0x16,0xfa,0x19 +.byte 0x77,0x8c,0xbf,0x28,0x4c,0xce,0x6c,0x08,0x98,0x7b,0x6a,0xf8,0xb3,0xc9,0x41,0xb1,0xf4,0xf4,0x05,0xbd,0xdb,0xd9,0xf8,0x0d,0x74,0xfe,0x3a,0x07,0xe7,0x11,0xbd,0x33,0xc2,0xd6,0x59,0x62,0x4f,0x22,0x86,0xf6,0xf2,0x9a,0x19,0x81,0xe7,0x17,0xfb,0xe7,0xfa,0x7f,0x6a,0xcf,0xf1,0x71,0xe7,0xf0,0xbb,0x6b,0xe1,0xc1,0x26,0x6e,0x41,0xfd +.byte 0xa4,0x83,0xd9,0x68,0xcd,0xc4,0x7b,0x04,0x7a,0x3f,0x18,0xa9,0x73,0x21,0xa2,0x38,0xc2,0xf4,0x88,0x7e,0xa6,0x20,0xaf,0x60,0xb9,0xb9,0xf0,0x74,0x52,0x3a,0x09,0xe6,0x22,0xc8,0xa0,0x0f,0xf1,0xa4,0x02,0x2a,0x80,0x17,0x40,0x83,0x26,0x5e,0xe5,0x78,0xc3,0x78,0x5b,0x9d,0x74,0xf4,0x4f,0x58,0x5a,0xfc,0xde,0x11,0xf7,0xee,0xdc,0x68 +.byte 0x57,0x1a,0x54,0x0a,0xe3,0xf2,0x77,0xe1,0x36,0x4d,0xa4,0x9e,0xad,0x86,0x81,0x54,0xd9,0xa5,0x90,0x0e,0xa9,0xfb,0x95,0xaa,0x98,0xea,0x0d,0xc7,0x33,0x40,0x62,0x67,0xf2,0xdf,0x54,0x64,0x82,0xd0,0x21,0xd9,0x87,0xcb,0x47,0xff,0x3b,0xde,0x53,0x61,0x4f,0x33,0xb2,0x4a,0x76,0xd6,0xa2,0x66,0x93,0x39,0x8b,0xee,0xbc,0x0d,0x54,0x8e +.byte 0xe4,0xfe,0x4b,0xae,0x2f,0x05,0xcf,0xfc,0x0e,0xa7,0xc8,0x8d,0x43,0x66,0xc7,0xc8,0x64,0x49,0x57,0xca,0xe2,0x1a,0xac,0x11,0xc2,0x17,0xf2,0x6a,0xc5,0x97,0xb9,0x28,0xe0,0xe7,0x3b,0x6f,0x78,0x99,0x5c,0xec,0x30,0xb7,0x1c,0x9f,0x2f,0xac,0x4d,0x1d,0x90,0x8e,0x6a,0x0d,0x20,0xe6,0x43,0xf3,0x1e,0xa6,0xc8,0x00,0x0e,0x5e,0x62,0x9d +.byte 0xea,0x58,0x23,0x46,0x43,0x29,0xc6,0x1f,0x0c,0x9a,0x3e,0x19,0x53,0xf2,0x3f,0xd8,0x13,0x68,0x90,0x98,0xa3,0xcf,0x22,0x3c,0x55,0xfc,0x36,0x15,0x14,0x39,0x8b,0x32,0xa7,0x81,0x96,0xb1,0x3e,0xf2,0x2c,0xf8,0xea,0xf6,0x10,0xe5,0x89,0x30,0xa5,0xa4,0xc7,0x5b,0x41,0xfd,0x0c,0x39,0x60,0x9c,0x0d,0x49,0x36,0xa8,0xe6,0xe7,0x9c,0xbe +.byte 0x8e,0x23,0x7c,0xb2,0x86,0x6e,0x6b,0x0e,0xa7,0xa7,0xc5,0x42,0xcf,0x14,0xf1,0x88,0xb9,0x7b,0x1f,0xfd,0x5b,0xd6,0xbe,0xa7,0x19,0x15,0x29,0x34,0x44,0x40,0xc8,0xfa,0xde,0x69,0xde,0xec,0xa6,0x39,0xfe,0xce,0x44,0xa9,0x39,0x5d,0x6e,0xac,0x75,0x77,0x32,0xc5,0x28,0xfd,0x18,0xa0,0x2a,0x3e,0x1f,0x30,0x63,0x8e,0x46,0x15,0x49,0x49 +.byte 0x15,0xb4,0x1b,0x69,0x83,0x92,0xac,0x3b,0x76,0x75,0x52,0x18,0xbf,0x0c,0xc0,0x55,0x80,0xac,0xf0,0x4f,0x49,0x00,0x6e,0xd2,0x46,0xcc,0x9d,0x4b,0xb3,0x75,0x6a,0x4b,0x43,0x29,0xf4,0x8f,0x9f,0x61,0x51,0xd8,0x59,0x8e,0x9d,0x9c,0x95,0x69,0xdc,0xba,0x73,0x03,0x55,0x65,0x19,0xc1,0x94,0x31,0xde,0x5e,0x26,0xd7,0x3c,0xde,0xae,0xf6 +.byte 0xa0,0xf5,0xc4,0x9c,0x7c,0x3a,0x8d,0xe4,0x90,0x71,0xd6,0xc1,0x84,0xd9,0xb3,0x80,0xae,0x78,0x96,0xec,0x30,0x6d,0x2d,0x74,0x37,0x14,0x2b,0x6c,0x88,0x2c,0xcd,0xd3,0x50,0x15,0x38,0xf5,0xe2,0x85,0xaa,0x95,0xdd,0xed,0x8e,0xe4,0x6d,0xa5,0x6b,0x27,0xee,0x4b,0xaf,0x9e,0xbc,0xae,0xf9,0xc7,0x85,0x0e,0x30,0x30,0x10,0xde,0x9e,0xe5 +.byte 0x05,0xd8,0xd9,0xaa,0x3c,0x6c,0x59,0x7d,0xc2,0x59,0x33,0xb5,0x94,0xc1,0xa8,0x27,0xff,0x7d,0xdd,0x6e,0x8b,0xc5,0x09,0x52,0x04,0x72,0x72,0x81,0x6e,0xaf,0xe0,0x15,0x42,0x4a,0xb3,0x46,0xdc,0xfb,0x8c,0x5a,0xe4,0xcc,0xfb,0x94,0x47,0xd7,0xe3,0x8e,0x6a,0x73,0x23,0x12,0xdb,0x2e,0x2b,0x7e,0x7a,0x25,0x7c,0x75,0x0e,0xa2,0x7e,0x20 +.byte 0xdc,0xc9,0xc3,0xd5,0x63,0x96,0x19,0x25,0xb7,0xa4,0x8e,0x1a,0x5a,0x92,0x62,0xcb,0xa8,0x5b,0x80,0x61,0x26,0x1b,0x6d,0xab,0x1e,0x09,0xd4,0x06,0xd4,0x96,0xc9,0xc8,0x51,0xb9,0xfd,0x19,0xca,0xc6,0x65,0x74,0xf5,0x4d,0xee,0xc8,0x52,0xb4,0x17,0xff,0x63,0x46,0x45,0xdf,0x8f,0xd1,0x49,0x05,0xe3,0x36,0x76,0xdd,0x47,0x8a,0x7e,0x43 +.byte 0x6d,0x0a,0x11,0x78,0xbc,0x56,0x6d,0x5e,0x62,0x5e,0x6d,0xfc,0x03,0x9c,0x53,0x25,0x10,0xc4,0xd4,0x48,0xf9,0x67,0xa4,0xb5,0x71,0xe7,0x08,0x42,0x37,0x1b,0xe1,0x9c,0xe6,0xb5,0xbc,0xf5,0xc6,0x56,0xab,0xd1,0x45,0x93,0x2c,0xbe,0x87,0x52,0x27,0xa1,0xe3,0x38,0x1a,0x4d,0xae,0x98,0xb3,0xf8,0x4d,0x00,0x76,0xe3,0x31,0x62,0x83,0x04 +.byte 0xee,0x62,0x35,0x70,0xb4,0x98,0x4c,0x5a,0x0f,0xcf,0x94,0xf3,0x4f,0xab,0xd7,0xbc,0xa0,0x9f,0x5e,0xe7,0x58,0x40,0xb5,0x9f,0xf8,0xd3,0x86,0x25,0x13,0x12,0xb3,0x0a,0x72,0x1f,0xef,0x39,0x07,0xf4,0x1c,0x6c,0x38,0xb7,0xd5,0x5b,0xda,0x68,0xd5,0x68,0xc7,0xa6,0x2b,0x94,0x33,0x11,0xff,0x71,0x15,0x86,0x58,0xb5,0x62,0xdc,0x7a,0x1b +.byte 0xdb,0xc5,0x81,0x24,0xcb,0xcb,0xbd,0x03,0x15,0x8d,0xdb,0xdb,0x20,0x51,0x0e,0x2d,0xc3,0xa2,0x3d,0x3a,0x3d,0x00,0xdb,0xbd,0xf0,0xe4,0x82,0x8f,0x9c,0xf7,0xdb,0x82,0xac,0x50,0xe5,0x2b,0x35,0x65,0xee,0x7a,0x61,0x4d,0x29,0x32,0x60,0xd0,0x02,0x40,0x45,0x75,0xc7,0x48,0xa7,0x0f,0x1e,0x1c,0xb4,0xd9,0x06,0xd4,0x31,0x72,0x24,0x33 +.byte 0x57,0xe6,0xe6,0x3d,0x3a,0xde,0xbd,0xc0,0xbc,0xfd,0x78,0xe5,0x8c,0x8f,0x36,0x33,0xba,0x70,0xea,0x78,0x30,0x50,0xb6,0x79,0xb5,0x63,0x43,0xea,0x88,0x6c,0x8c,0x9a,0x42,0x44,0x15,0xb9,0xdc,0xdf,0xaa,0xfa,0xe7,0x76,0x26,0x32,0x98,0x96,0xdc,0x0c,0x3f,0xf9,0xff,0x9e,0x09,0xba,0x19,0xef,0x10,0x35,0x93,0x3c,0xb8,0x48,0x39,0x05 +.byte 0x98,0xaa,0x74,0x53,0xf3,0x2b,0x62,0xdd,0xa1,0x28,0xe8,0x0d,0x52,0x51,0x89,0x80,0x68,0x1d,0xb9,0x86,0x01,0x69,0x9b,0x53,0x5f,0xe8,0x05,0xe5,0x34,0x62,0xfa,0x70,0x9d,0xcd,0x00,0x74,0xf6,0xc3,0x68,0xb9,0x8d,0x7b,0xff,0x05,0x70,0xf9,0xa5,0xc8,0xa2,0x42,0xc0,0xc2,0x2e,0xb2,0xc1,0x33,0xfd,0x5c,0xf2,0x05,0x82,0xf2,0x29,0x0f +.byte 0xd1,0x05,0x13,0xba,0xe0,0xbd,0x00,0x89,0xbe,0x04,0xb3,0x09,0x1b,0xd5,0x3e,0x56,0x74,0xf9,0xb5,0xf5,0x46,0x13,0x1c,0x2f,0x90,0xd6,0x24,0xa1,0x5a,0x94,0x65,0x78,0x30,0x67,0x0e,0xe2,0xc9,0x9a,0x3f,0xe6,0xdc,0xdc,0xca,0x11,0xf4,0xd0,0x04,0xe4,0x14,0xef,0xc6,0x7b,0x11,0x14,0x29,0xc4,0xde,0xe7,0x25,0xeb,0x44,0x74,0x7e,0xdb +.byte 0x71,0x0b,0x58,0xdb,0x1f,0x15,0x85,0xb3,0x43,0x6d,0x3c,0xda,0x69,0x3c,0x84,0xf4,0x41,0x55,0xd0,0x99,0x4f,0x9b,0x8d,0x68,0x18,0x2c,0x2a,0x58,0xc8,0xc2,0xac,0xa5,0x30,0x37,0xa6,0x44,0xd0,0xd6,0x92,0xe4,0xa3,0x0d,0x2b,0xc4,0xa3,0x54,0xc2,0x3d,0xaa,0xf0,0x03,0x66,0x1e,0xac,0x05,0x5a,0xb5,0x46,0x96,0xc5,0x09,0x93,0xa7,0x98 +.byte 0x16,0x5a,0xb7,0xfb,0x9f,0x70,0xcc,0xe5,0x03,0x74,0x66,0x2c,0xac,0x7b,0x11,0xfd,0x9d,0xf3,0x2d,0xaa,0xf0,0xea,0x4f,0x00,0x9d,0x11,0x20,0xa4,0x2b,0x3e,0x8e,0x2f,0xcd,0xfd,0x8d,0xaf,0xbe,0x8b,0x72,0xc3,0xd7,0x18,0x2c,0x88,0xdd,0xae,0x2e,0xf6,0xd9,0xb9,0x9e,0x68,0xb7,0xe5,0xde,0x83,0xeb,0x16,0x19,0x43,0x21,0xbb,0x24,0x33 +.byte 0xc4,0xce,0xb2,0xb4,0x13,0x52,0xf5,0x62,0xfe,0xd1,0x37,0xf2,0xee,0xd4,0xa9,0x4b,0x35,0xf5,0xfd,0x7b,0xb0,0x85,0xee,0xb7,0x96,0x32,0x49,0x07,0x5f,0x98,0x8d,0x5e,0x16,0xdd,0xbb,0x88,0x82,0x1f,0x35,0x25,0x24,0x09,0x62,0x4d,0x82,0x09,0xa4,0x13,0x91,0x51,0xc9,0x85,0xae,0xee,0x2f,0x6a,0x9c,0xcc,0x73,0x8c,0x7c,0x61,0x05,0xc3 +.byte 0x18,0xa1,0xc1,0x7b,0x3d,0x85,0x0e,0x03,0x30,0xa5,0x5f,0x0b,0x33,0xd6,0xc8,0x1a,0x37,0xb0,0x3e,0xc7,0x7e,0x24,0x53,0x7f,0xfe,0x64,0x91,0x46,0xf9,0x6a,0x4a,0x87,0x92,0x0e,0x4d,0x62,0xb8,0x70,0xf9,0xa3,0x76,0x5e,0xc1,0x45,0x24,0x46,0xe9,0x0a,0xf0,0x50,0x21,0x3c,0x6a,0x3a,0x90,0x1b,0x36,0x5d,0xc6,0xd5,0x48,0x78,0x09,0xe0 +.byte 0x24,0xd8,0x16,0xc0,0xec,0x3a,0xb5,0x12,0x8c,0x7c,0xc0,0xb1,0xf7,0x00,0x63,0x96,0x37,0x44,0xc2,0x8f,0xad,0xdc,0xda,0xa4,0x3a,0x5c,0x04,0x14,0x60,0xc4,0xf5,0x64,0xdd,0xf1,0xd9,0x04,0x6f,0xc6,0x0b,0x3d,0x7d,0x40,0x32,0xcc,0x79,0xb5,0x2f,0x99,0xc3,0xf7,0x7b,0xd9,0x54,0x60,0x49,0x46,0x92,0xd8,0x71,0x3e,0xca,0xfe,0x8c,0xb3 +.byte 0x52,0x3b,0xbf,0x42,0xec,0xab,0x71,0x0d,0xa6,0xb9,0x53,0x37,0xed,0x01,0x58,0xbc,0x00,0x55,0x5d,0x0d,0x0d,0xb0,0x62,0x53,0xbf,0x76,0xba,0xfa,0x15,0xe7,0x22,0x69,0x9d,0x1c,0x23,0xfc,0x2d,0x65,0xa0,0x6d,0xba,0x39,0x3e,0x51,0x51,0x4b,0x50,0x10,0x59,0x04,0x82,0x92,0x75,0xa1,0x24,0x62,0xe3,0x5b,0x85,0xb1,0xfa,0xc4,0xc0,0xe9 +.byte 0x26,0x19,0x63,0x2e,0xa9,0x16,0xda,0xae,0x45,0x1c,0x84,0x4c,0x94,0x6a,0xd0,0xd1,0xd2,0xb0,0x6c,0xb0,0x3b,0x3a,0x90,0x9e,0x7a,0xa7,0xb6,0x1b,0x2c,0x1d,0x7d,0xfe,0xfe,0xc7,0x7d,0x4d,0xf2,0xdf,0x23,0x54,0xea,0xb1,0xcf,0xd0,0xd1,0x1d,0xaf,0x01,0x86,0x73,0x18,0x1a,0x66,0xc1,0x66,0x32,0xd9,0xf3,0x07,0x65,0x6d,0xe9,0xae,0xfd +.byte 0xb3,0x8e,0x18,0x7a,0xb4,0x5d,0x53,0xb0,0x26,0x51,0x08,0x40,0x42,0x8e,0xcc,0xdc,0xdf,0x39,0x36,0xa5,0xbe,0x91,0x41,0xe4,0x78,0x29,0x76,0x54,0x61,0x43,0xa4,0xb7,0x94,0x0e,0x17,0x7f,0x46,0xad,0x5a,0x3d,0x6b,0xfc,0xf9,0xa0,0x3a,0xe5,0x86,0x75,0xc3,0xff,0xab,0xbc,0x99,0xeb,0x9f,0x85,0xb8,0x0c,0x9c,0x9b,0x6f,0xd3,0x74,0xf6 +.byte 0x58,0x72,0x96,0x5c,0x49,0x31,0x4f,0x61,0x4f,0x78,0x8b,0x94,0x40,0x75,0xf4,0x66,0xcc,0xd9,0x27,0x9c,0x6d,0xac,0xef,0xa7,0x4e,0xd8,0xb7,0xf9,0x3a,0xf7,0x63,0xb5,0xec,0xc7,0xad,0xe5,0x2c,0x87,0xed,0xae,0x1e,0xdd,0x05,0x1b,0xf0,0x61,0x82,0xf3,0x40,0xc2,0x1b,0xe2,0xc7,0xce,0x2d,0x4c,0xbe,0x3a,0x51,0x63,0xef,0xe0,0xf2,0xae +.byte 0x0d,0xfd,0x6a,0x38,0x1f,0xc2,0xf1,0x91,0xc1,0x12,0x74,0x88,0x32,0x61,0xa7,0x65,0xea,0x30,0xfa,0x4c,0x93,0x61,0xef,0xa9,0x49,0x74,0xe7,0xfb,0x7a,0x3d,0xf9,0xbf,0xfe,0xdd,0x17,0x29,0xe5,0xdf,0xab,0x3a,0xf1,0xc2,0x1a,0x53,0x82,0xd0,0xe3,0x46,0x85,0x87,0x69,0xdf,0xb1,0x64,0xc3,0x39,0x24,0x27,0x29,0x16,0x66,0xb2,0x55,0xcf +.byte 0x2c,0xab,0x9e,0x35,0x4a,0x86,0x06,0x51,0x9d,0x1d,0x07,0x61,0x7f,0x71,0xa8,0x6f,0xef,0xf9,0x9d,0xf3,0x56,0xef,0x97,0x4a,0x6a,0x07,0x70,0xd7,0x80,0xcc,0x33,0x98,0x87,0x8e,0xa6,0xc3,0x18,0x58,0xfd,0xe9,0x4d,0x7d,0x07,0x8e,0x7d,0xae,0x30,0x1d,0x2d,0x1c,0x34,0x98,0x01,0xb9,0x13,0x86,0x13,0x26,0x55,0x15,0xe6,0x87,0x6f,0xc8 +.byte 0x3c,0x4d,0x1e,0x70,0xdc,0x44,0x40,0xb0,0x69,0xe7,0xb4,0xf5,0x81,0x66,0xef,0x70,0x15,0xee,0x6e,0xb4,0x44,0x9e,0xbb,0x40,0x6f,0x5b,0x36,0x96,0xd4,0x52,0x8d,0x9e,0x0f,0x9a,0x97,0xea,0xd1,0x37,0x7e,0x9a,0x30,0xb4,0xe9,0x1f,0x01,0x0d,0x26,0xa6,0xb1,0x74,0x90,0x6e,0xe1,0xe0,0x67,0x7c,0x76,0x6c,0xed,0xbd,0x62,0x61,0x8d,0x66 +.byte 0x7e,0x71,0x07,0x9a,0xcd,0x9e,0x7d,0xc7,0x78,0x39,0xaa,0xc8,0x83,0xdd,0xb7,0x28,0xb8,0xce,0x05,0x29,0x50,0x06,0xd0,0xe5,0xc2,0x01,0x31,0x7a,0x41,0x3a,0xdf,0x4f,0x7d,0xb3,0xa2,0x2a,0x5b,0x1e,0x39,0x1d,0xfd,0xbf,0x3c,0x9c,0xe3,0x17,0xfb,0x21,0x5d,0xdc,0x48,0x05,0xf1,0x36,0xac,0x98,0x9b,0xd2,0xb2,0xbd,0x97,0x2a,0x19,0x9b +.byte 0xfc,0x05,0x85,0x87,0x69,0x60,0x2c,0x83,0xfa,0x39,0xda,0x0e,0x3e,0x80,0xc9,0xf4,0x5a,0x6b,0xe3,0xda,0x72,0xed,0x42,0x39,0x67,0x00,0x38,0x7e,0x84,0xdd,0x5c,0x06,0x9c,0xee,0x4a,0xf3,0x75,0x32,0x6f,0x69,0x9a,0xa6,0x5e,0xb8,0x10,0x7d,0xe8,0x35,0x5e,0xa1,0x86,0x69,0x2a,0x48,0xa7,0x53,0xef,0xce,0x90,0x49,0xce,0x82,0x92,0x20 +.byte 0xfd,0x71,0xe7,0xb4,0xce,0x81,0x01,0xf9,0xaf,0x36,0xd9,0xe2,0x28,0xe9,0xd0,0x9f,0x0f,0xf0,0x2f,0xca,0xa4,0x2b,0x90,0xdd,0x21,0x66,0x1c,0xbc,0x3f,0x80,0x89,0xcc,0x53,0xe5,0x72,0x91,0x45,0x9f,0x62,0x57,0x70,0x29,0xb9,0x6d,0x41,0xa3,0x67,0xf3,0x99,0xac,0x0e,0x3c,0x43,0x1f,0x92,0xf0,0xd5,0xca,0x86,0xad,0x0a,0xd4,0x2b,0xf4 +.byte 0x3f,0x8f,0x90,0xcf,0x05,0x9f,0x07,0x07,0xac,0x36,0x5c,0x7d,0xb6,0xcb,0x9b,0x77,0x1a,0x11,0xed,0x0a,0x4e,0x1f,0x7b,0x68,0x39,0x88,0xb2,0x5d,0x8a,0x37,0x83,0x25,0xd6,0xc7,0x98,0x0a,0x1a,0x14,0x9a,0x1f,0x1e,0x66,0xd4,0x4f,0xd6,0x3f,0x88,0x7b,0x4a,0x18,0x06,0x27,0x79,0x40,0xc7,0xc8,0x54,0x8b,0xc8,0xc3,0x2e,0x56,0xf8,0x92 +.byte 0xda,0xac,0x74,0x5b,0xaf,0x02,0x0d,0xe7,0xc4,0xf4,0x72,0xab,0xb1,0x83,0x4b,0x7a,0xe0,0xe1,0xe2,0xac,0xe7,0x20,0xbd,0xc3,0xda,0xae,0x10,0x47,0x68,0x3b,0xd1,0xc5,0xd7,0x28,0x8e,0x31,0xcf,0xba,0xe3,0x33,0x56,0x5e,0x8c,0x44,0xe4,0x41,0x9b,0xbb,0x8a,0x80,0x98,0xb8,0xc6,0x66,0x2c,0xa1,0x26,0x42,0xb4,0x90,0x42,0xf9,0xc5,0x4b +.byte 0x7c,0xaa,0xf1,0x70,0x8a,0x00,0x80,0x31,0xf9,0x0b,0x5e,0xec,0x25,0x36,0x2a,0x98,0x0c,0x05,0x97,0x23,0xd3,0x9e,0xf6,0xa9,0x11,0x8e,0xee,0x0a,0xda,0x8e,0xd3,0x65,0xc7,0x50,0x55,0xba,0x08,0x7e,0x78,0x1a,0x04,0x91,0x43,0x3a,0x14,0xfb,0x88,0x65,0x59,0xfe,0xf3,0xa6,0xde,0x3f,0x98,0xc4,0x7e,0x67,0x05,0x79,0x1f,0x26,0xce,0x9d +.byte 0xee,0x2c,0x86,0x81,0xf9,0x35,0x47,0x52,0x7b,0x35,0x6d,0xda,0x5f,0xd8,0x91,0x59,0x9d,0x8d,0x91,0xe7,0x3f,0x79,0x0c,0xca,0xc5,0x08,0xfd,0x59,0x24,0xaf,0x6c,0x3a,0x2a,0xd9,0xb6,0xaa,0x46,0x1b,0x9d,0x2e,0x17,0x5a,0x94,0x56,0xd4,0xb8,0xc9,0xb3,0xa5,0x4b,0xc7,0xfa,0x2d,0xd0,0x37,0x83,0xf1,0x53,0x27,0x42,0x8d,0x98,0x02,0x73 +.byte 0x26,0x18,0x5d,0x32,0xf5,0xda,0xac,0x5d,0x45,0x10,0x58,0xec,0x0a,0xdd,0x8a,0xf0,0x65,0x03,0x6e,0x0f,0xd3,0x6d,0x83,0x2e,0x28,0x2c,0xd6,0x31,0x52,0x2b,0xb5,0x49,0x43,0x81,0xfd,0xd6,0x7c,0x72,0x19,0x9d,0x02,0x9f,0x15,0xca,0xfa,0x34,0xbe,0x10,0xf3,0x2d,0x93,0xcd,0xde,0x4f,0xb7,0xe9,0x74,0xb5,0x85,0xb6,0x1f,0xc5,0x14,0x1a +.byte 0x54,0x48,0x8d,0x0b,0x16,0x2c,0x62,0x15,0x64,0x55,0x7f,0x8e,0x59,0x10,0x53,0x98,0x2f,0x5d,0x92,0x7d,0x98,0x17,0x80,0x57,0x2d,0x5a,0x59,0x1b,0x97,0x46,0x59,0x1c,0x7c,0x3d,0x5b,0x4b,0x27,0x14,0xf3,0xfe,0x76,0x4e,0x1f,0xd6,0x2c,0x84,0x6e,0x8e,0xec,0xa7,0x0f,0x18,0x8f,0x96,0xd8,0xdf,0xba,0x1d,0x2d,0x41,0xd3,0xcf,0x2e,0xcc +.byte 0x52,0xdd,0xf9,0xd3,0x1b,0x6b,0xf9,0x4d,0x99,0xf9,0x19,0x58,0xc9,0x3f,0x4d,0xe9,0xad,0xd2,0xe8,0xd6,0x87,0x82,0xf0,0xcf,0x0d,0x17,0x30,0x85,0x9e,0x0e,0xca,0x15,0xa5,0x8e,0x88,0x27,0x7c,0xf7,0x3b,0xf3,0x43,0x5e,0xa6,0x3f,0x8d,0x86,0x5c,0x21,0x3b,0x20,0xf9,0xe4,0x55,0x37,0x8a,0x8c,0x41,0xcf,0x2c,0x8e,0xa9,0x17,0x96,0xaf +.byte 0x3a,0x8f,0x4b,0x3d,0x9d,0xb9,0x17,0xe9,0x46,0x2d,0xf5,0x4c,0xfd,0x0d,0xee,0xbe,0x25,0x84,0x75,0xda,0xaf,0x0c,0x87,0xb0,0x7a,0x29,0xd9,0x6a,0x0d,0x8a,0xad,0xb0,0xc5,0xac,0xf0,0xad,0x2c,0xec,0x2b,0x91,0x36,0xc5,0xbc,0xfe,0x92,0xa8,0x84,0xff,0xa5,0xf1,0x07,0xfc,0xeb,0xe4,0xd8,0x39,0x63,0x2e,0x4f,0xfd,0x46,0x64,0x3c,0xd1 +.byte 0x3a,0x8d,0xab,0x8c,0xa1,0xd8,0x46,0xc2,0xf4,0xcf,0xa1,0x75,0xc3,0x50,0x97,0x8b,0x7c,0xdb,0x45,0x36,0x8c,0x85,0x0f,0xb9,0xfc,0x37,0xdd,0x64,0x68,0xe2,0xa8,0x9e,0x03,0x02,0x30,0x43,0x9f,0xb1,0xfe,0xe8,0x95,0xbf,0xfb,0x34,0x14,0x62,0xbf,0x0a,0x20,0x56,0x52,0x69,0xd5,0x2e,0x2f,0xff,0x4d,0xe2,0x27,0x99,0x32,0xb6,0x49,0xe9 +.byte 0xa8,0xcf,0xe4,0x81,0xef,0x36,0x75,0x13,0x83,0x82,0x59,0x43,0x22,0x3c,0xfd,0xe7,0xf1,0x51,0x5d,0x1e,0x08,0xde,0xc6,0x6b,0x2d,0xd4,0x71,0xf8,0xe9,0xae,0x32,0x64,0x10,0x5d,0x96,0xf9,0xc2,0x2a,0x45,0x35,0x64,0x1e,0xdf,0xb9,0x24,0xf1,0x8d,0x75,0x95,0x2c,0x0b,0x9f,0x3f,0x12,0xe3,0x31,0xe4,0x8b,0x2d,0x1e,0xd2,0x9e,0xe7,0xde +.byte 0xc3,0x45,0x6f,0xe0,0xe0,0x7d,0xed,0x95,0xad,0xe7,0xca,0x27,0xee,0xc7,0x18,0x6d,0xcf,0x1d,0x2a,0x6c,0x37,0xc2,0xa6,0x82,0x26,0xb8,0x8e,0x6d,0x00,0x99,0x82,0x24,0xda,0xe3,0x9a,0x84,0x12,0x31,0xc3,0x3d,0x4b,0x44,0xde,0x8a,0x2b,0x64,0xc9,0xea,0xa9,0x73,0xd1,0xc6,0x75,0x3f,0x60,0xb9,0xdd,0x06,0x55,0xae,0x44,0x16,0x30,0xb8 +.byte 0x02,0x07,0xe9,0x4f,0x23,0x1b,0x02,0x4f,0x2e,0xaa,0x43,0x34,0x44,0xca,0xf5,0x68,0x85,0xcc,0x50,0xc3,0x43,0x71,0xc8,0x24,0x6a,0x30,0x48,0xee,0xeb,0xd2,0xf3,0x18,0x7f,0xb0,0x89,0x68,0x80,0xa3,0xbb,0x06,0xf9,0x04,0xaa,0xda,0xd0,0xfb,0x47,0xd7,0xea,0x3e,0xf8,0x61,0x57,0x8f,0x1e,0xb7,0xc1,0x9e,0x09,0x7e,0x49,0x08,0x2f,0x8a +.byte 0xdf,0x04,0x85,0x40,0x6f,0xfa,0xc1,0x0b,0x0d,0x60,0xc4,0x88,0x58,0x99,0xbc,0xcc,0x67,0xba,0xab,0x39,0xeb,0x32,0x6e,0xe8,0xb6,0x82,0x78,0x15,0xc3,0x51,0xda,0x53,0x32,0x70,0xc7,0x0f,0x56,0x31,0x71,0xac,0xc8,0x62,0x04,0x58,0x2e,0x9e,0xcb,0x0f,0xb1,0x05,0x82,0x50,0x53,0xdd,0xa2,0x03,0x78,0x1a,0x4e,0x70,0x57,0x24,0xfa,0xa2 +.byte 0x69,0xfa,0xd3,0x6c,0xd6,0x90,0x2b,0xed,0x7b,0x39,0xe8,0xed,0xa5,0x5d,0xf8,0xf2,0xbb,0xe5,0x09,0xa5,0x89,0x37,0x9a,0x3b,0xdc,0xae,0xd3,0xba,0x88,0xad,0x0b,0x41,0xf0,0x72,0x8a,0x40,0x32,0x98,0x77,0x3f,0x3a,0x37,0xa6,0x15,0x58,0xbd,0xf2,0x04,0x17,0x3d,0xcb,0x23,0x1f,0x49,0x19,0x62,0xc8,0x97,0x44,0xbd,0xf1,0x69,0x17,0x5f +.byte 0x08,0xee,0x0b,0x1c,0x71,0x46,0x5f,0x2a,0x40,0x74,0x0b,0xb0,0x8a,0xb3,0x15,0x8c,0xbc,0x8e,0x9c,0x53,0x8a,0x5f,0xd1,0x10,0xc7,0xbc,0x7a,0x85,0x6e,0x8a,0x35,0xd9,0x2c,0xf1,0xa2,0x16,0xdf,0xf0,0xaf,0x09,0x4b,0x9d,0xe6,0x22,0x5f,0xac,0x91,0x18,0x4b,0x3b,0x96,0xd8,0x2d,0x4e,0x03,0x81,0xe3,0xd8,0x8d,0x15,0x83,0x09,0xca,0xa7 +.byte 0x1b,0x4a,0x4e,0x36,0xbb,0x05,0x36,0xf2,0xb6,0x81,0x50,0xa4,0xaf,0x6c,0x5e,0xce,0x11,0x83,0x71,0x8e,0xcd,0x41,0x61,0x0e,0x27,0xaf,0xa4,0x9e,0xcd,0xe6,0xc8,0xb5,0x69,0x88,0xf7,0x9a,0xcb,0x7d,0xa2,0x30,0x20,0xdb,0xb6,0x5c,0x15,0xa2,0xf4,0x02,0x53,0x82,0x4a,0x6b,0x39,0xdb,0x3a,0x5e,0xa0,0x3d,0xbf,0xcf,0x1e,0x26,0x17,0xae +.byte 0x34,0x8c,0xd7,0x7e,0x45,0xbd,0x53,0xcf,0x0d,0xb3,0x47,0x6c,0xef,0x3b,0xde,0xf6,0x40,0x04,0x11,0x1d,0x1c,0x93,0x48,0xba,0xf1,0x13,0x9d,0x03,0x60,0xab,0x10,0x5f,0x72,0x00,0xf9,0x71,0x7c,0xe1,0xb7,0xd4,0xbf,0xb1,0x1e,0x7f,0x2b,0x99,0x54,0x81,0x56,0xfd,0x9f,0x60,0x81,0x3f,0x7e,0xbf,0xc0,0x01,0xb0,0x12,0x1b,0xca,0x9f,0x09 +.byte 0xc8,0x6d,0x44,0xdf,0xd3,0xbc,0xd3,0xb5,0xeb,0x09,0x24,0xec,0xde,0x50,0xe0,0xb2,0xc7,0x0b,0x3f,0x41,0xad,0x10,0xaa,0xc4,0xf0,0x79,0x25,0xc0,0x75,0x08,0x9f,0xe2,0xde,0xe3,0x12,0x20,0x0e,0x81,0x2c,0x27,0x68,0x53,0x40,0xa1,0xf1,0xf2,0x12,0x25,0x3c,0x16,0xe3,0x27,0x8a,0x18,0x1a,0x5b,0xfd,0xc5,0xd1,0x1e,0x4b,0x85,0xcb,0xd0 +.byte 0xbf,0x3e,0xd3,0x4e,0xfd,0x79,0xc9,0xb0,0xf3,0x88,0x24,0x38,0xe4,0xd5,0xe1,0xfd,0x92,0xe0,0x21,0xea,0x50,0x59,0x01,0xa3,0xfd,0x43,0xfb,0x3f,0xc3,0x24,0x0a,0x18,0x98,0x1f,0xc1,0x1e,0x9b,0xd5,0x80,0xa3,0xca,0x5f,0x49,0xf0,0x1b,0xe1,0x2a,0xa9,0xe0,0xca,0xf9,0x5e,0x15,0x0f,0x59,0x04,0x18,0x09,0x75,0xb7,0x33,0xf8,0x79,0xf1 +.byte 0x3b,0xb9,0xc5,0x60,0xcd,0x1d,0xb8,0xd0,0xc6,0x68,0x65,0xa9,0xdd,0x83,0x67,0x3c,0x21,0x8e,0x1f,0x4b,0xfd,0x4f,0x2f,0x31,0x63,0x5f,0xfc,0xb4,0x6b,0x7a,0x08,0x46,0x06,0x88,0x2d,0xf9,0x72,0xc4,0x59,0x13,0x80,0x0c,0xe1,0x74,0x82,0x48,0x0c,0xb3,0x04,0x37,0xd0,0xf7,0xe1,0x38,0x83,0xb9,0xd9,0x79,0x65,0xab,0x7f,0x9e,0xb8,0xc6 +.byte 0x72,0xf3,0xca,0x3f,0x46,0xe7,0x4a,0x6a,0xb2,0x3e,0xe2,0xf4,0xdb,0x60,0xc4,0x95,0x7e,0x9e,0xe8,0x1f,0x87,0x6c,0x20,0x46,0xfd,0x91,0xa0,0xd7,0x9a,0x64,0xa5,0xf0,0x28,0xe1,0x87,0xda,0x61,0xd5,0x1e,0x55,0x56,0x93,0x68,0x94,0xcb,0x64,0x79,0xa4,0xbf,0x75,0x3a,0x6a,0x3a,0x29,0x73,0xb7,0x87,0x8a,0x98,0x1a,0xa5,0xc7,0xe9,0xea +.byte 0x42,0x0a,0x9f,0x9c,0xcd,0xf5,0xcb,0xdd,0xad,0xe4,0xb2,0xdd,0xa5,0x8b,0xf8,0x4a,0x12,0x86,0xec,0x2d,0xe8,0xe9,0xa1,0x8b,0x95,0x51,0xfd,0x31,0x8e,0xf9,0xb3,0x30,0x5f,0xab,0xc8,0xf6,0xdd,0xec,0x7a,0x12,0x7c,0xcf,0xf4,0x6d,0x1b,0x5e,0xba,0x8a,0xa4,0xe4,0x79,0xa0,0x97,0xf6,0x44,0x46,0x81,0xcb,0xeb,0x1b,0x3a,0x06,0xe8,0xb5 +.byte 0xbf,0xc3,0xe3,0x64,0x9f,0xeb,0xef,0x88,0x6c,0xc0,0x35,0x8b,0x9b,0x0c,0x5b,0x3c,0x99,0xce,0x7b,0x34,0xe3,0x06,0xda,0x19,0xbb,0x81,0x1d,0xa2,0xa9,0xb8,0x1f,0xf1,0xc8,0x1f,0x8a,0x29,0xae,0xd6,0x82,0x9b,0xaf,0x68,0x27,0x01,0x14,0x1a,0x1f,0xfd,0xdc,0xcf,0xcd,0x95,0x6b,0x67,0xde,0x3c,0x75,0x11,0xbe,0x4f,0xa6,0x9d,0x83,0x5f +.byte 0x23,0xc6,0xfd,0x21,0x78,0x90,0x22,0x25,0xd5,0x48,0xef,0xf0,0x26,0x73,0x05,0xad,0x8b,0xa3,0x4c,0xdd,0xff,0xfb,0xa0,0xc2,0xc4,0x76,0xcc,0x9f,0x75,0x3e,0x16,0xe6,0x28,0x04,0xae,0x5d,0xb0,0x2f,0x19,0xa5,0x53,0x2d,0x30,0x45,0x1a,0x5c,0x09,0xa3,0xd3,0xbc,0x71,0xd4,0xa7,0xf2,0xb0,0x19,0xd7,0xf4,0x28,0xad,0xdf,0xf6,0xd7,0x37 +.byte 0xa0,0x73,0x8a,0x7b,0x33,0xdc,0xb4,0xb0,0x68,0xa7,0x78,0x76,0xde,0x53,0x6a,0xf8,0x12,0x9d,0x26,0xe4,0x9e,0x5a,0xd3,0x60,0xf9,0x44,0x99,0xd1,0x38,0x60,0x2b,0x69,0xec,0xec,0xd2,0x68,0xfc,0xdb,0x3d,0xed,0x4e,0xf8,0x85,0x84,0x48,0xb7,0xa3,0x05,0x9e,0x11,0xdd,0x42,0xa7,0x6e,0x09,0x93,0xa6,0x17,0x76,0x29,0x13,0xed,0xbc,0x14 +.byte 0x91,0x11,0x47,0x47,0xca,0x4e,0xc9,0xd5,0x6c,0x06,0x7d,0xcb,0xbf,0x87,0x56,0x36,0xe8,0x1f,0x57,0xe0,0xdf,0x21,0xd5,0xa2,0x46,0x12,0x54,0x04,0xc2,0x81,0x3a,0xb6,0xb1,0xaa,0x59,0x52,0xbf,0xb3,0x1c,0x8f,0x74,0xb1,0x9c,0x0a,0xda,0x69,0x8b,0xe6,0x68,0x6b,0xf5,0x1f,0x91,0x16,0x56,0x6b,0x13,0x06,0x51,0x0e,0x81,0x8f,0x5f,0xa5 +.byte 0x26,0x20,0xb8,0xfe,0x40,0x4e,0x31,0xdc,0x35,0xa0,0x76,0x3c,0x33,0x19,0xe2,0xda,0xb0,0xda,0xc4,0xe4,0xc4,0xe4,0xfb,0x66,0xef,0x28,0x69,0x0e,0x54,0x09,0x5b,0x8a,0x83,0x7f,0xc4,0x9d,0x5d,0xa1,0xa5,0xf1,0x75,0x05,0xda,0x8a,0xf5,0xa0,0x70,0xb4,0x62,0x99,0x54,0x3a,0x99,0x4d,0xa4,0xe4,0x3a,0xd5,0x46,0x5d,0x5d,0x13,0x14,0x7a +.byte 0x45,0xf4,0x91,0x2f,0xe0,0x96,0xaf,0xd0,0x76,0xa5,0xd7,0x49,0x61,0x0a,0x87,0x05,0xcc,0x6e,0xf5,0xc9,0x29,0xe9,0x5a,0x89,0x13,0xd2,0x69,0x9a,0xd5,0x75,0xf6,0x9c,0xc2,0x9e,0xc3,0xe4,0xd7,0xce,0x87,0x36,0xc6,0xb6,0xab,0x7d,0x81,0xb5,0x0f,0x3d,0xd5,0x5a,0x3a,0x87,0x89,0xa6,0x10,0xa6,0xca,0x1d,0x86,0x54,0x02,0x7d,0x6f,0x8f +.byte 0x14,0x16,0xbd,0xe5,0xce,0x08,0x34,0x11,0xf3,0xd7,0x6d,0x91,0xc5,0xdf,0x15,0x22,0x13,0xc3,0x55,0xeb,0x6b,0xc4,0xf2,0xfa,0x39,0xd8,0x64,0x29,0x4f,0x5c,0x3a,0xf8,0x7e,0xd9,0x73,0x27,0xf7,0x8f,0xb4,0x55,0xe0,0xcb,0xdf,0xcb,0x4f,0x42,0xc2,0x9b,0xd8,0x1b,0xfc,0x6d,0x4a,0x8d,0x83,0xa4,0x02,0x86,0x7f,0x07,0x9f,0xdc,0x5a,0x70 +.byte 0x2a,0xf3,0xbc,0x3f,0x78,0xf9,0x6b,0xac,0x73,0xbf,0x6f,0x89,0x60,0x67,0x4b,0xd9,0xe1,0x57,0x41,0x35,0x56,0xdf,0x74,0xab,0x89,0x1a,0x10,0xe8,0x24,0xd6,0x64,0x22,0x46,0xb8,0xca,0x33,0x9e,0x6f,0x15,0xf3,0x4a,0x42,0x2a,0x61,0x70,0x1a,0x78,0x5f,0x3a,0x74,0xd2,0x05,0xff,0x70,0xee,0x5d,0x15,0x98,0x38,0x4d,0xed,0x8a,0x14,0x60 +.byte 0x00,0x41,0x6d,0x6a,0x29,0xb6,0xb2,0xd1,0x2e,0x1f,0xd2,0xde,0x71,0x97,0x4b,0x26,0xd8,0x20,0x92,0x5e,0x0a,0x52,0x16,0x84,0x65,0x43,0xde,0x8b,0xf9,0x1e,0x5c,0xec,0xfb,0x71,0x42,0xcc,0xca,0x99,0xbc,0x34,0x07,0xa1,0x32,0x4d,0xc7,0x95,0xfd,0xe7,0x56,0x9c,0x35,0xd5,0xbb,0x96,0x41,0xbf,0x60,0xac,0xe2,0xe7,0xda,0x1f,0x8c,0xb5 +.byte 0x15,0x12,0x94,0xbf,0x8e,0x41,0x5c,0x67,0x51,0x02,0xc5,0x82,0x34,0x15,0xbe,0xd4,0x49,0x41,0x1b,0xfd,0x24,0x8a,0x11,0xff,0x01,0x86,0xab,0xbc,0x80,0xc6,0x7f,0xec,0x31,0xcf,0x06,0xc1,0xa2,0x02,0x3b,0x21,0x26,0xd3,0x1d,0xd3,0xe3,0x99,0xf6,0x29,0x6c,0x6c,0xf4,0xd3,0x6f,0x8e,0xf1,0x4e,0x87,0x57,0x7b,0x43,0xf8,0x03,0x3d,0x20 +.byte 0x3d,0x99,0x90,0x5d,0x9b,0xf2,0x19,0xb9,0x3b,0x98,0x09,0xd1,0xe3,0xcf,0x10,0xd1,0xa5,0xc3,0x74,0x64,0xbe,0x68,0xb0,0xc5,0x90,0xf0,0x42,0x84,0xdc,0x14,0xbe,0xa8,0x23,0x62,0xfa,0x5e,0x7c,0xfd,0x82,0xdc,0x05,0x17,0x22,0x17,0x12,0xfa,0xd7,0xb8,0x71,0xdf,0x84,0x8e,0x41,0x3e,0x6d,0x1e,0x66,0x57,0x40,0x51,0x0c,0x00,0xea,0x64 +.byte 0x99,0x39,0xb6,0x41,0xcd,0xd1,0xf9,0x52,0x39,0xce,0x49,0x08,0x9a,0x8e,0x41,0x1e,0x58,0xd2,0x78,0x4a,0x73,0x7f,0xa5,0x1f,0x40,0xbe,0xec,0x61,0x6d,0xb6,0x53,0xc5,0x7a,0x87,0xc6,0xd7,0x95,0x51,0x3f,0x95,0x4c,0x61,0xb0,0x89,0xb1,0x7f,0xad,0x93,0x7d,0x98,0xfa,0x4e,0x91,0xd2,0xb1,0x70,0xd2,0x3b,0x78,0x50,0x34,0x55,0x67,0x30 +.byte 0x51,0x72,0x4c,0x9f,0xd3,0x98,0xf0,0x75,0xf2,0xd1,0x5a,0x79,0x46,0x78,0x5b,0x92,0xed,0x7b,0x9a,0xc8,0xa8,0x66,0xba,0x1b,0x28,0xc9,0xd7,0x14,0x48,0x02,0xd8,0x13,0x50,0x24,0x23,0xda,0x34,0x27,0x39,0xd5,0xa3,0x37,0x27,0x16,0x69,0x24,0x7b,0xd4,0x00,0xdc,0x88,0x0b,0x12,0xc8,0x0f,0x16,0xd6,0xe1,0xe5,0xe1,0x38,0x1c,0xfb,0xfa +.byte 0xc0,0x42,0x54,0x2e,0x1c,0x89,0x95,0xf5,0x34,0x9a,0x65,0x1f,0x67,0x5d,0x6f,0xe8,0xcc,0x72,0x81,0xec,0x44,0x7c,0x61,0xa1,0xac,0xd5,0x69,0x53,0x1c,0xd1,0xba,0xb7,0x93,0xef,0x4e,0x2d,0xab,0x4a,0xe8,0xb2,0x17,0x48,0x34,0x53,0x72,0x15,0x94,0x58,0x62,0x88,0x80,0xdd,0x70,0x6a,0x77,0x7f,0x2b,0xc8,0xe1,0xac,0x83,0xce,0xe5,0xed +.byte 0xd0,0xc3,0x24,0x09,0x5e,0x4c,0x9c,0x95,0x4a,0x4b,0xdf,0xe6,0x69,0x8e,0xb0,0x2a,0x0c,0x5c,0x08,0x2c,0xe3,0xd5,0xc8,0x3f,0x48,0x40,0xf6,0xf5,0x72,0x83,0xb8,0xd2,0x1a,0x78,0x70,0x75,0x23,0x9a,0x6f,0x11,0x1f,0xdb,0x5c,0x42,0x4f,0xab,0xbc,0x0e,0x44,0xf6,0xfb,0x73,0x85,0x2e,0x2f,0x20,0xc4,0x28,0x0d,0x44,0xfa,0xb0,0x79,0x85 +.byte 0xf2,0xce,0x2f,0xc3,0xaa,0x93,0xbd,0xfc,0xe8,0x5b,0xc4,0x9f,0x3f,0xf8,0x9e,0xd2,0xec,0xf2,0xca,0xe0,0xd4,0x82,0xe2,0x9e,0x1e,0xee,0x22,0x74,0x81,0xb3,0x26,0x36,0x02,0x94,0xcf,0x04,0xee,0x7a,0x99,0x43,0xa1,0x3a,0x26,0xbc,0x05,0x9d,0x67,0x7c,0xe7,0x95,0xa7,0x73,0x7e,0x0a,0x54,0x7b,0x6a,0x53,0x95,0xce,0x9a,0x0c,0x20,0x4c +.byte 0x9c,0x61,0x91,0x6e,0x43,0x1c,0x4e,0xa0,0x99,0x98,0xcc,0x90,0x29,0xb1,0xc7,0x4f,0x40,0x1c,0xe5,0x7a,0xb8,0x9f,0x50,0x52,0x8b,0xde,0x5e,0x32,0xf1,0x52,0x9a,0xab,0x55,0x40,0xfb,0x75,0x45,0x87,0x49,0x43,0x9d,0x45,0x51,0x8a,0x5c,0x6d,0x86,0xdf,0x9c,0x74,0x7c,0xc1,0xe0,0xe7,0xe9,0x87,0x7d,0xae,0x06,0xe1,0xf3,0x23,0xa9,0x32 +.byte 0xda,0xcb,0x37,0xca,0x6c,0x51,0x78,0x53,0x74,0x36,0x13,0xc4,0x92,0x1c,0x40,0x4a,0xeb,0xab,0x95,0xb2,0x97,0xb0,0xef,0x11,0x35,0x11,0x29,0x55,0xff,0x71,0x8c,0xdb,0x2b,0xea,0x8c,0x15,0xaf,0x2c,0x0d,0x25,0xe4,0xc3,0x7b,0xd7,0x2e,0xaf,0xd3,0xf8,0xb9,0xdc,0x19,0x71,0xac,0x66,0x9d,0x22,0x56,0x8c,0x15,0x89,0x43,0xf7,0xa7,0xf7 +.byte 0x8c,0x5d,0xc4,0xbe,0x51,0xf8,0xa9,0xaf,0x41,0x6b,0x8f,0x81,0xdb,0xf5,0x23,0xf4,0x45,0x61,0x7c,0x8d,0x30,0x16,0xc9,0xf4,0xb5,0x7c,0x15,0x20,0xed,0xe2,0x2e,0x9c,0x14,0xe9,0x7e,0x98,0x11,0x4f,0xe1,0x99,0x14,0x8c,0xa9,0xae,0x7d,0x28,0x10,0x87,0x63,0x40,0xcf,0x16,0x42,0x30,0xd9,0xbe,0xdb,0xf9,0xd0,0xc5,0x69,0x8c,0x6b,0x5e +.byte 0x54,0xd9,0xe3,0xbd,0x28,0x8f,0x71,0xc9,0xd5,0x93,0x10,0x29,0xd8,0xee,0x69,0xe2,0x98,0xb0,0x21,0x1c,0x3e,0xf1,0x3e,0xb4,0x77,0x98,0x15,0x9b,0x4e,0x48,0xe7,0xd3,0xcf,0x26,0x5b,0x97,0x3d,0xad,0x32,0x57,0x56,0x2b,0xbd,0xef,0x85,0x7f,0x2e,0x12,0xb7,0xfc,0xc5,0xc6,0xa8,0x05,0x5e,0x91,0xae,0xd1,0xc6,0x7c,0x62,0x07,0x5e,0xda +.byte 0x84,0x34,0xc2,0x6b,0x7c,0xa5,0x07,0xb0,0x02,0xf7,0x02,0x7b,0x8e,0x90,0x34,0xa1,0x4f,0x15,0x79,0x87,0xd5,0x76,0xac,0xf2,0x94,0xed,0xb5,0x49,0x82,0xb8,0xea,0x0c,0x06,0xec,0xa6,0x8a,0x46,0xfe,0x3a,0xdf,0x14,0x67,0xc9,0x63,0xc3,0x53,0xee,0x3f,0xf5,0x4a,0x96,0x54,0x61,0x5c,0x53,0x52,0x96,0xdc,0x2b,0xe9,0x85,0xb6,0x72,0xf3 +.byte 0xe7,0x69,0x9a,0x25,0x88,0x0e,0x64,0xac,0x04,0xb7,0xb2,0xbc,0x8a,0xd4,0x24,0x2b,0xa4,0xf9,0x58,0xdb,0x36,0x0b,0x05,0x4a,0xba,0x84,0x7f,0x95,0x58,0x46,0x23,0x7b,0x3c,0xcf,0xaa,0xa6,0x77,0xe6,0x1f,0xc8,0x5a,0xd5,0x82,0x09,0x87,0x3a,0x36,0xb7,0xb5,0x4c,0xdc,0xa0,0x40,0x6e,0xd7,0x61,0x1f,0xed,0xf7,0x81,0x32,0xbf,0xaa,0xd4 +.byte 0xfa,0xc5,0xd7,0x62,0x9a,0x73,0x24,0x6c,0xb9,0x5b,0x5e,0x9b,0x8d,0xe1,0x4e,0x89,0x0d,0x1c,0xc9,0x7b,0xfe,0xcc,0x95,0x97,0xec,0xba,0x35,0x5d,0xbc,0x06,0x37,0xcf,0x8d,0x02,0x28,0xa1,0x0b,0xca,0xe9,0xee,0x23,0x65,0xd2,0x01,0xe2,0x49,0x2a,0x58,0x4c,0x12,0x4d,0x44,0x19,0x10,0x4c,0x4e,0xbb,0xb2,0xe9,0x43,0xa6,0x0b,0x70,0x87 +.byte 0x22,0xf0,0x1a,0x66,0x08,0xf1,0xb2,0x50,0x3c,0x36,0xfc,0x4f,0x39,0xa8,0xce,0x8e,0x9c,0xb1,0x29,0xd8,0x6d,0xce,0x5d,0x77,0x94,0xff,0x64,0x81,0x10,0x47,0xa3,0xa0,0x87,0x15,0x22,0x4f,0x88,0x72,0x3f,0x99,0x39,0x85,0x5c,0xe8,0x77,0x10,0xce,0xd0,0xa5,0xd7,0x47,0x14,0xd9,0x43,0x20,0x88,0x68,0xc4,0xe7,0xd9,0x22,0x05,0xeb,0x54 +.byte 0xbc,0x7c,0xb7,0x8c,0x78,0xa3,0xde,0x76,0xb8,0x85,0x0d,0x30,0xd8,0x7b,0x84,0x28,0x4b,0xad,0xb7,0x16,0x11,0x12,0x1a,0x36,0x12,0xe7,0x4f,0x12,0xaf,0x5a,0xce,0x4e,0x11,0xd4,0x7d,0xd7,0xdf,0x00,0x9a,0x74,0xab,0x60,0x40,0xa0,0x07,0x9c,0x07,0x5e,0x48,0x0c,0x72,0x82,0x3e,0x5a,0xc6,0xd1,0x64,0x10,0x63,0xd3,0x17,0x4d,0x1f,0x65 +.byte 0x2f,0x3c,0x87,0x23,0x39,0x86,0xd9,0x94,0xfd,0x81,0xe0,0x2e,0x94,0xec,0x2e,0x39,0xcd,0x4b,0x48,0x00,0x8d,0x03,0xc2,0xe4,0x31,0xba,0x37,0x4a,0x1b,0x69,0x52,0x27,0xcd,0xd2,0x1b,0x0b,0x32,0xbd,0x80,0x36,0x20,0xcc,0x01,0x51,0xf3,0x78,0x8e,0xae,0xab,0x49,0x42,0xa2,0x79,0x6b,0xc1,0x0d,0xf8,0x5f,0x14,0xf8,0x95,0x53,0x33,0x97 +.byte 0x50,0x5f,0x99,0x3a,0x89,0x21,0x5e,0x32,0x15,0xa9,0xa9,0x19,0x28,0x1a,0xa4,0xb0,0x25,0x2e,0xcf,0x60,0x7d,0xc7,0xc0,0x21,0x18,0xb2,0xca,0x8b,0x30,0xfe,0x2d,0x86,0xb4,0xc8,0xc7,0xd6,0xa1,0x71,0x0f,0xf1,0x54,0xe7,0x64,0x0a,0xfc,0x7c,0x73,0xb1,0xb8,0x26,0x01,0x37,0x94,0x9c,0x97,0x9b,0x6d,0x37,0x2e,0xe0,0x22,0x5b,0xe1,0x25 +.byte 0x82,0x91,0x12,0x7d,0x9f,0xb0,0xc4,0x01,0x32,0x16,0xea,0x38,0x22,0x3c,0xa9,0xb2,0xc6,0x20,0x7d,0x58,0x50,0xec,0x3f,0x3b,0x43,0xdd,0xb3,0xd2,0x31,0x37,0x30,0x6b,0x40,0x28,0x83,0x99,0xf4,0x41,0xc8,0x05,0x3b,0x87,0x45,0xb3,0x21,0xe7,0xac,0x4d,0xe7,0x5c,0x76,0xf1,0x85,0x8c,0xfc,0xbf,0x8e,0xad,0xa5,0xb8,0x10,0x3b,0x37,0x86 +.byte 0xa1,0x15,0xa2,0x48,0x1f,0x9d,0x61,0xbe,0xa8,0xa4,0xb6,0xb3,0x71,0xcb,0x71,0x80,0x12,0x39,0xcc,0x6f,0xe7,0x8a,0x06,0x79,0x6b,0x8d,0xfd,0xf9,0x00,0x6d,0x28,0x82,0x3f,0xf3,0x3c,0xfb,0x06,0x19,0x63,0xdd,0x36,0xfc,0x5c,0xd9,0x6f,0x34,0xfc,0xc3,0xdd,0x77,0x71,0x53,0xa4,0x9b,0xce,0xc2,0xb2,0x06,0xec,0xa4,0xfc,0x36,0xd8,0x0c +.byte 0x72,0x19,0x58,0xad,0xea,0x02,0x55,0x21,0x3a,0xb1,0x56,0x04,0xc7,0x58,0x5a,0xc1,0x18,0x9d,0xbb,0xc4,0x75,0x11,0x7c,0x30,0x94,0xd5,0xa3,0x80,0x57,0x6e,0xca,0xaf,0xec,0xdc,0x5e,0x58,0x5d,0xaa,0x2f,0x73,0x50,0x3e,0x2c,0x17,0xa4,0xa3,0x77,0xa0,0x5e,0x18,0x77,0x8b,0xf4,0xe5,0x09,0xa3,0x43,0xce,0x39,0xc5,0x70,0x16,0xf5,0xb5 +.byte 0xf5,0xe3,0xc0,0x70,0xdd,0xb2,0x03,0xc8,0x43,0x48,0xc6,0xc1,0xbb,0xcc,0x04,0xb1,0x87,0xf6,0xde,0xd7,0x78,0xc9,0x8b,0xc2,0xa6,0xaa,0xea,0x1a,0x00,0x91,0x56,0x09,0x91,0xb7,0x24,0xf6,0x81,0x06,0x80,0x3e,0x2f,0xde,0x22,0xd7,0xf2,0x23,0xc5,0xde,0xf5,0x1f,0x30,0x4e,0xd7,0xed,0x3f,0x97,0x48,0x5c,0x1b,0x62,0x41,0x0e,0x7d,0xdc +.byte 0xdf,0xfb,0xdd,0xea,0x99,0x26,0xf7,0x8d,0xbf,0xd0,0x0f,0x38,0x06,0xe0,0x35,0x74,0x58,0xec,0x5f,0x13,0x58,0xe6,0x33,0x8e,0x90,0x39,0xff,0x3a,0xaa,0xd8,0x81,0xf3,0x6a,0x6e,0xbd,0xa9,0x5c,0xcc,0x1c,0x61,0x41,0xcb,0xd7,0x0a,0x4f,0x10,0xcd,0x84,0xd2,0x84,0x0a,0x1b,0xd6,0xf5,0x48,0xdc,0x1a,0x7f,0x41,0x11,0xd5,0x13,0xf5,0xc0 +.byte 0xa9,0xe0,0xd9,0x58,0xc6,0x96,0x4a,0xf5,0x46,0xe1,0x1d,0x87,0xe4,0x91,0x01,0x01,0x64,0xad,0x7c,0x4b,0x2f,0xa9,0x9a,0x95,0xf9,0x71,0x06,0x76,0xa6,0x09,0x6d,0x80,0xe7,0x9a,0xb2,0xa3,0xc1,0x8d,0x6d,0x2c,0x72,0xd6,0xf8,0xfa,0xc8,0xb1,0x70,0xf7,0x73,0xec,0x55,0x0a,0x3e,0xc6,0xc4,0xe8,0x5b,0x8b,0x84,0x9b,0x3d,0xf1,0xcc,0x5b +.byte 0xbd,0x79,0xe3,0x29,0x59,0x18,0x24,0x3f,0x5f,0x25,0x63,0xed,0xc9,0x59,0xa2,0xa5,0xe0,0x4d,0x1c,0xa4,0xb2,0x04,0x6b,0x20,0x58,0xe9,0x84,0xc8,0x36,0xbb,0x4d,0x46,0x70,0x2f,0x41,0x47,0x23,0xdf,0x09,0xb1,0x63,0x7e,0x29,0x76,0xed,0xc9,0x34,0x68,0xc6,0x51,0xd2,0x76,0xe8,0xd3,0xb6,0x5a,0xfe,0xeb,0xa6,0xe9,0xd6,0x1e,0x80,0x2f +.byte 0xc0,0xc0,0x13,0xd8,0x00,0x50,0x31,0x25,0xb7,0x6c,0x84,0xc3,0x87,0x26,0xf9,0x9d,0x43,0x1b,0x09,0x42,0x6d,0xbf,0xaf,0x7c,0xda,0x93,0x8a,0xe2,0x81,0xa5,0x05,0x78,0xdf,0xc5,0xa0,0x70,0x89,0x38,0x61,0x3c,0xb7,0x27,0x36,0x57,0x10,0x7a,0xc9,0xc3,0x9e,0xe6,0xa2,0x81,0x30,0x52,0xd3,0x62,0x0e,0xd4,0xff,0x59,0x81,0xee,0x50,0x35 +.byte 0x72,0xa7,0x06,0x93,0xf7,0x5a,0xde,0x46,0xb1,0xe7,0x47,0x61,0x6a,0x31,0xb6,0x87,0x51,0xfe,0x49,0x39,0xea,0x33,0xc1,0xf3,0x19,0xa3,0xa8,0x58,0x68,0x5e,0x11,0xa3,0xc2,0x37,0xff,0xe4,0x36,0xa8,0x3d,0x2a,0x6e,0xaf,0xed,0x8b,0x36,0x77,0x0d,0xa0,0xda,0x4a,0x1d,0x9e,0x4d,0xae,0xf8,0xe8,0x40,0xef,0x2f,0xf9,0x6d,0x82,0x21,0x6c +.byte 0xb3,0xad,0x96,0x0d,0x68,0xb7,0x57,0x11,0x5d,0xbe,0xd9,0x5d,0xa2,0xad,0x6f,0xdc,0xf6,0x1d,0x51,0x7d,0x44,0xd1,0x79,0x40,0x18,0x1f,0x2d,0xc7,0xde,0x01,0xc4,0xde,0x53,0xa9,0x54,0x11,0xa4,0xea,0x0d,0x10,0xbb,0x4e,0x0a,0x42,0xfa,0xc2,0x47,0x91,0xef,0xaf,0xf7,0x3b,0xff,0xc9,0xb4,0x86,0xb2,0xe1,0x7f,0xc9,0x2e,0x9e,0x2e,0xa9 +.byte 0x58,0x1a,0xde,0x61,0x68,0xce,0xe8,0x6f,0x21,0x81,0xc0,0x3f,0xa3,0xc3,0x7b,0x93,0xce,0x4c,0xe0,0xa7,0xe1,0x09,0x47,0xe8,0xb4,0x6d,0x3f,0xde,0xdd,0x17,0x8d,0x72,0x75,0xb6,0x18,0x85,0x61,0xbe,0x75,0xac,0xfa,0x23,0xd5,0xd3,0x43,0xc9,0x82,0x9a,0xfa,0xfd,0x0c,0xf9,0xee,0xce,0x63,0x9b,0x79,0xa2,0x03,0x0e,0xcc,0x99,0xf7,0x32 +.byte 0x61,0xb0,0xd2,0x65,0x8e,0x02,0x7e,0xa0,0x63,0x3c,0xd8,0x78,0x2e,0x9f,0xd2,0x16,0x16,0xf1,0xf0,0xc3,0x43,0x34,0x2f,0x16,0x9a,0x3f,0xdf,0x4d,0x1c,0x0d,0x9a,0x0c,0x4e,0x85,0xd2,0x5f,0x0d,0x63,0x57,0x7d,0xc3,0x69,0xe8,0x7d,0x4f,0x12,0x27,0x85,0x8c,0xb4,0x4d,0xf9,0xf9,0xfc,0x5a,0x43,0x63,0x80,0x7c,0xfd,0xae,0xb4,0x7f,0x48 +.byte 0xb8,0xbd,0xac,0xf9,0xfa,0xd9,0x3a,0x31,0xaf,0x53,0xcd,0x47,0xf1,0x8c,0x15,0x66,0x55,0xa6,0x04,0x27,0x73,0x19,0x39,0x85,0xf9,0x96,0x48,0x2b,0x8c,0x64,0x14,0x7a,0xad,0xe3,0x34,0xd6,0xf5,0x4c,0x62,0x33,0x23,0x68,0x16,0x39,0x57,0x09,0x16,0x20,0x74,0xc3,0x98,0x24,0x69,0xc3,0x15,0xf7,0x05,0x45,0x30,0xf7,0x8f,0x7a,0x1d,0xb0 +.byte 0x71,0x96,0x5a,0xaa,0xd6,0xa6,0x2f,0x95,0x15,0xdd,0x58,0x9e,0xc6,0x6e,0xb4,0xab,0x0d,0x1c,0x74,0x97,0xe3,0xb4,0x03,0xa8,0xba,0x27,0xe4,0xe3,0xf7,0x9d,0x7d,0x83,0x81,0x89,0x88,0x86,0xb3,0x4b,0x14,0xc0,0xd6,0xf3,0x2c,0xc2,0x17,0xac,0xb6,0xa1,0x7f,0xa6,0x98,0x42,0x72,0xa5,0xaf,0x4e,0xbb,0x9f,0x85,0x62,0xa5,0xaa,0xe0,0x27 +.byte 0x9b,0x08,0x07,0xc8,0x37,0x37,0x33,0x30,0x1e,0x81,0xa0,0xbe,0x71,0x30,0xbf,0x70,0xf8,0x1b,0x28,0x91,0xc5,0xfc,0x37,0x0e,0x98,0x87,0x6a,0xdb,0xaa,0x26,0x31,0xcc,0x4e,0xd4,0xb9,0x5d,0xce,0x07,0x9e,0x48,0x15,0xf2,0xc0,0x56,0x44,0x36,0xe1,0xd0,0x56,0x3e,0x46,0xc0,0xec,0xd6,0x25,0x58,0x1b,0x66,0x3c,0xd2,0x5f,0xe0,0xca,0x69 +.byte 0x5f,0xe4,0x00,0x4a,0x77,0x91,0x87,0xb0,0xb6,0x13,0x93,0xed,0x86,0x9f,0xef,0x6b,0x99,0xe6,0x6f,0xb8,0x2d,0x82,0xc6,0x71,0x30,0x3d,0x10,0xd1,0x55,0xb4,0xa3,0xbf,0x48,0x0e,0x69,0x1f,0xc3,0x5a,0x28,0xd2,0x7b,0x19,0xb1,0xf3,0x35,0x02,0xde,0x9b,0xd1,0x39,0x53,0xa6,0x9e,0x30,0xd7,0x08,0x96,0xb4,0x67,0x90,0x9f,0x27,0xe4,0x8f +.byte 0x07,0x5f,0x69,0xb0,0x4b,0x2c,0x88,0x4d,0x9a,0x20,0x48,0x60,0x53,0xac,0x6f,0x81,0x53,0x1f,0xec,0x88,0x95,0x4d,0xc3,0xcf,0x52,0x13,0xa1,0x69,0x52,0x85,0xda,0x73,0x6e,0x6e,0xec,0x88,0xda,0xed,0xea,0xf5,0x9c,0x0b,0xc9,0xac,0x31,0x44,0x12,0x68,0xec,0x0d,0xc6,0x3c,0x05,0xef,0xec,0xff,0x6b,0x99,0xda,0xc9,0x3b,0x41,0x7d,0x4c +.byte 0xdd,0xd2,0x83,0xca,0x52,0xc8,0x0d,0xe5,0xf8,0x76,0x34,0x06,0x98,0xa0,0xcd,0x74,0xc1,0xd5,0x44,0x60,0xeb,0xd4,0x67,0x67,0xda,0xff,0xe9,0x41,0x39,0x22,0xde,0x9b,0x9d,0x36,0xfe,0x6d,0xb1,0xc8,0xfe,0x39,0xe4,0x80,0x5b,0x3d,0x34,0x51,0x3d,0x3c,0xbc,0x8e,0xaa,0x1e,0x80,0xa9,0x20,0x98,0xa2,0x86,0x91,0x13,0x9a,0x2c,0xa7,0xf9 +.byte 0x82,0x92,0xac,0x4c,0xf1,0x8b,0x9e,0xc2,0x27,0x4a,0xbd,0xb3,0xde,0x40,0x33,0x05,0x6d,0x6b,0xcd,0xfd,0x99,0x45,0x81,0xdc,0x98,0x69,0xc8,0xc3,0xc6,0x1d,0x4d,0x52,0x2e,0xf3,0x3b,0x5a,0x8f,0xce,0x89,0x77,0x74,0x0b,0x63,0x3a,0x70,0x7a,0x79,0x86,0x87,0x33,0x2a,0x67,0x9d,0xc0,0x1e,0xd8,0xa6,0xbd,0x7f,0x3e,0x7d,0x36,0x12,0xf2 +.byte 0x2b,0x04,0x6c,0x5e,0x60,0x74,0x2b,0x05,0xa1,0x7a,0x67,0x2d,0xd7,0x50,0x9d,0xe7,0xce,0xbd,0x26,0xda,0xe7,0xab,0x63,0xc5,0x41,0x85,0x33,0x30,0x59,0x0a,0xfd,0xd6,0x27,0xbe,0x96,0x4b,0xe8,0xc1,0x98,0xa7,0xe2,0x5c,0xd9,0x8d,0xfd,0x1d,0x2e,0xcc,0x08,0x7f,0x3a,0xcf,0x0c,0x4f,0xc0,0xdc,0x70,0x5b,0x74,0x28,0xe7,0x79,0x04,0x55 +.byte 0x59,0x91,0x8b,0xb1,0x6a,0x37,0x9e,0xf5,0xd4,0x61,0x4a,0xbe,0xd6,0x6e,0x23,0xc9,0xc9,0xcc,0xc2,0xbd,0xe6,0x85,0xc7,0xfc,0x58,0x81,0x90,0x0d,0x71,0xa1,0xfe,0x9d,0xb5,0x6b,0xa3,0x42,0x1d,0x34,0x7e,0x13,0xb1,0x17,0x75,0xff,0x99,0x25,0x67,0xb7,0x6b,0x43,0xb8,0x34,0x59,0x22,0x4f,0xa5,0xf0,0xd0,0x00,0xc9,0x25,0x2d,0xe6,0xba +.byte 0x3a,0x67,0x50,0x01,0x74,0x7f,0x6e,0xbd,0x59,0x0d,0x90,0xe9,0xf8,0x00,0xea,0xab,0x40,0x79,0x5a,0xbb,0x32,0xb3,0x99,0x21,0xc1,0xca,0x0a,0x21,0x93,0x56,0x62,0xfe,0x87,0x98,0x27,0xbc,0x29,0x59,0x16,0x4f,0x40,0x43,0xed,0x3f,0x78,0xbd,0x5e,0x88,0x1b,0x33,0x37,0x4b,0xba,0x7c,0xd2,0x90,0xf5,0xf9,0xa6,0x54,0x87,0xac,0x3e,0xe1 +.byte 0xf3,0x46,0xab,0xa1,0x93,0xe1,0xe1,0xbb,0xbe,0xa3,0x46,0x06,0x2d,0xed,0xeb,0x9b,0x13,0xb4,0x3b,0xc6,0x5f,0x8a,0xdf,0x0b,0xc4,0x3a,0x9b,0x12,0x82,0x81,0x86,0xbd,0x0f,0x94,0xd2,0xa4,0x52,0xd6,0x06,0x15,0xef,0xaf,0xa2,0x90,0x32,0xe5,0xa2,0x0d,0x38,0x1f,0xe9,0x78,0xac,0xec,0x95,0x71,0xca,0x93,0xd6,0xc8,0x6c,0x1d,0x24,0x8e +.byte 0xe0,0x8d,0x80,0x3f,0x6d,0x2f,0x09,0x59,0xaa,0xd2,0x68,0x0c,0xe4,0x5f,0x25,0x7e,0x57,0x90,0xf8,0xcf,0xc0,0x1a,0x22,0xfc,0x66,0x48,0x8f,0xaf,0x26,0x8d,0xa0,0xa8,0x83,0x9b,0x89,0xb8,0xaf,0xd6,0xed,0xcf,0xa0,0x9a,0xbe,0x29,0xf1,0xa7,0x36,0xb0,0x46,0x1e,0x6c,0x18,0x90,0xed,0x0c,0xde,0xb6,0xd5,0xd0,0xfb,0xb6,0xce,0xd9,0xd0 +.byte 0x2e,0x76,0x89,0xfb,0xa7,0x8c,0x49,0x22,0xda,0x4c,0x5c,0x8e,0xc7,0x2e,0xf8,0x41,0x21,0x30,0x0e,0x39,0xec,0xa3,0x0c,0x18,0x1b,0x72,0x85,0x33,0xaf,0x72,0x2b,0x02,0x4a,0xb8,0xcb,0x7d,0x79,0xbd,0x09,0x42,0x0a,0xe2,0x2f,0x1f,0x7a,0xec,0xda,0x65,0xc2,0xb5,0x9b,0x94,0xd1,0xed,0x1f,0x3d,0x39,0x13,0xe9,0x85,0xe0,0xb0,0x25,0xfa +.byte 0x03,0x82,0x6c,0x4b,0x2a,0x9f,0x60,0xdd,0x16,0x94,0xfd,0x7d,0xbc,0x6f,0x0a,0xdc,0x55,0xec,0x25,0x0d,0xe6,0x83,0xb3,0x57,0xfd,0x0f,0x58,0xa5,0x5b,0x6d,0x79,0x80,0x51,0xdd,0xa7,0xfa,0x21,0x03,0x39,0xaf,0x86,0xa6,0x55,0x49,0x58,0xc4,0x86,0x4d,0xf3,0xe7,0x8d,0xb9,0xb9,0x6c,0x12,0xee,0x6e,0x6d,0x78,0x70,0xeb,0x6c,0x90,0x45 +.byte 0x23,0x40,0x4f,0xe1,0x05,0x46,0xa0,0xe8,0xe8,0xb8,0x94,0xeb,0xf2,0x47,0x6c,0x80,0x66,0x45,0xea,0xd2,0x99,0x7b,0x5d,0x40,0x6b,0x60,0xad,0xba,0xc2,0xd2,0x5d,0xa8,0xff,0xdd,0x7d,0xbe,0xa1,0xbc,0x99,0xd2,0xb1,0x6d,0x24,0x94,0xdd,0x3e,0xf1,0x1f,0x78,0x53,0xf3,0xa9,0x79,0xc1,0xe7,0x58,0x8e,0x97,0xcb,0xdc,0x84,0xbb,0x44,0x4b +.byte 0x95,0xe7,0xf5,0x9d,0xba,0x80,0x56,0x26,0x07,0x39,0xf3,0xc0,0xb1,0xfb,0xaa,0x9c,0xd8,0x80,0xcf,0x6b,0x68,0x61,0x79,0x88,0x14,0x9a,0x71,0x78,0x8b,0x46,0xb5,0x63,0xc6,0xed,0xde,0x1a,0x1d,0xaa,0xe0,0x23,0x96,0x8b,0x6e,0x3d,0x16,0xf1,0xe0,0x3d,0xe1,0x60,0x5a,0xcd,0x1e,0x95,0x9a,0x20,0x32,0xe7,0xc9,0xae,0x63,0x91,0xdf,0x34 +.byte 0x35,0xc9,0xe7,0xf2,0x55,0x31,0xf4,0xad,0x0c,0x26,0x1a,0x3f,0x46,0x43,0x88,0xef,0x17,0x01,0xa6,0x46,0xdf,0x22,0x76,0x47,0x7c,0xfb,0xe2,0x53,0x74,0x51,0x3a,0x28,0xe5,0x70,0xaa,0x33,0x74,0x9e,0xe2,0xcb,0x44,0x89,0xc7,0xfa,0xa6,0x2a,0xae,0x1e,0xce,0x2b,0xc3,0xd2,0x58,0x83,0x94,0x40,0x0d,0xc9,0xe1,0xe7,0xea,0x90,0xac,0x99 +.byte 0x27,0x30,0x2b,0x30,0x5e,0xe9,0x10,0x27,0x1e,0x29,0x4e,0x61,0xe3,0x50,0xdb,0xdd,0x51,0xe4,0x32,0x01,0xf4,0x72,0xfe,0x16,0xc1,0xa5,0x45,0xa9,0xd2,0x6c,0x15,0xa2,0x93,0x9c,0x7a,0x2c,0x79,0xb4,0xc0,0x88,0x07,0x7c,0x90,0x97,0xd7,0x9c,0x6c,0xc1,0x97,0x83,0x1d,0xec,0xa4,0xf0,0x74,0x6c,0x6c,0xa4,0x43,0xfd,0x5c,0x0c,0x7c,0x6f +.byte 0x30,0xeb,0x84,0xf4,0x98,0xc2,0xd9,0x8f,0x54,0x41,0x3d,0x3e,0x3c,0x9d,0xae,0x81,0x8d,0x24,0xae,0x74,0xe5,0xa0,0x6f,0xd5,0x4f,0x89,0x46,0x74,0x3b,0xef,0x2a,0x8a,0x1c,0xe5,0x94,0xeb,0x05,0xec,0xc9,0x42,0xf5,0x1e,0x67,0x95,0x38,0x8b,0xaa,0x1c,0x44,0xfb,0xf9,0xbb,0xec,0x0f,0xd3,0x28,0x68,0x28,0x8d,0x04,0x23,0x92,0xff,0x99 +.byte 0x76,0x8a,0x87,0x9b,0x36,0x87,0x52,0x15,0x5d,0xc8,0x4a,0xda,0x2e,0xca,0x9c,0x45,0x13,0x80,0x88,0x1a,0xe9,0xfb,0xfe,0x08,0xab,0x8b,0x23,0xba,0x3a,0xfe,0xed,0x70,0xea,0x0d,0x99,0x69,0xea,0xa6,0xd5,0xbf,0x5c,0x1f,0x22,0x40,0xa4,0x09,0xd6,0x3a,0x69,0x39,0xe9,0x81,0x5f,0x19,0xdf,0x26,0x70,0x55,0xb0,0x2d,0x11,0x67,0x06,0x6a +.byte 0x32,0xcc,0xa4,0x9d,0xa5,0xa2,0x48,0x53,0x92,0x3a,0x52,0x6e,0xcf,0x23,0x96,0x82,0x4d,0x62,0xc5,0x72,0xd5,0x52,0x89,0xb7,0x08,0x86,0x14,0x54,0xc3,0xa7,0x44,0xb9,0x8e,0xe2,0xb1,0x10,0x20,0x15,0xc6,0xcf,0xa4,0x5e,0x66,0xa4,0x2d,0xca,0xf7,0x93,0xcb,0xd5,0x99,0x48,0x1e,0xde,0xec,0xc1,0xd3,0xd3,0xf5,0xcb,0x4a,0x24,0x31,0x5d +.byte 0x5a,0xaa,0x32,0x89,0x3e,0x1a,0x2f,0x1e,0xb6,0xc3,0x5f,0x09,0x50,0x7a,0x6f,0x46,0x01,0x0e,0xeb,0x10,0x23,0x1b,0x49,0x9e,0xa9,0x2b,0xed,0xf2,0x2d,0x34,0xe9,0x45,0x2a,0xdb,0xa9,0xc5,0xf7,0x84,0x8a,0xa1,0xe5,0xc7,0xd0,0x56,0x35,0xab,0x7a,0x55,0x66,0x14,0x28,0x38,0x6a,0x0f,0xb7,0xb1,0xc8,0x28,0xce,0xbe,0xe2,0xdf,0x5a,0x45 +.byte 0x50,0x87,0xc5,0x31,0x92,0x89,0x59,0x7e,0x18,0x97,0x22,0x2e,0x9d,0xea,0xce,0x29,0x07,0xef,0x06,0xc4,0xab,0xe8,0x85,0xe4,0x36,0x6f,0x0a,0x38,0xe5,0x54,0xc6,0x1d,0x19,0xdd,0x68,0xc9,0xfe,0x8a,0x50,0xe4,0xaf,0x4e,0xf1,0x4a,0xc8,0xf0,0xe0,0xa8,0x62,0x9e,0xbf,0xab,0x50,0xde,0x77,0x87,0x5f,0x7e,0xb5,0xdc,0x45,0x23,0xef,0xaa +.byte 0xc4,0x92,0x6b,0x65,0xed,0xbf,0xa9,0x39,0xa6,0x7a,0xdb,0x32,0x89,0xbe,0xd9,0x51,0x4e,0x25,0x1d,0x98,0x1f,0x58,0xa4,0xcf,0xbf,0xc0,0x1c,0xa4,0xb7,0x4c,0xbf,0xc9,0xc4,0xea,0xee,0x13,0xd2,0xde,0x56,0x32,0x66,0xb9,0x65,0xbf,0xe9,0xd3,0x80,0x0a,0x1e,0x61,0xc8,0xb2,0x1d,0x94,0xec,0x5f,0x89,0x1c,0x27,0x47,0x58,0x22,0x23,0xa8 +.byte 0x21,0x95,0x3d,0xc6,0x22,0xcd,0x77,0xfb,0x59,0xbe,0xa5,0x97,0xfc,0xe8,0x9a,0xa9,0xbc,0xa3,0x7a,0xbd,0x68,0xdd,0x33,0x1f,0x3c,0xc3,0x24,0x6e,0x57,0xc8,0x6a,0x54,0xdc,0x8c,0xdb,0xe8,0x8c,0xc2,0xd8,0xb6,0xbf,0x15,0xa3,0xff,0x57,0xca,0xd9,0xe7,0xe3,0xda,0x83,0x79,0x27,0x8f,0x72,0x17,0xcf,0x95,0x44,0x65,0x18,0x63,0xcd,0x8d +.byte 0xa7,0x74,0x66,0x5c,0xd3,0x71,0xd4,0x7f,0x06,0x6f,0xc1,0x3e,0x1d,0x06,0x7e,0x0d,0x45,0x9c,0x04,0x7a,0xbd,0x50,0x2d,0xc2,0x4c,0x27,0x32,0x3c,0x86,0x57,0xc1,0x9a,0x2a,0x74,0xe9,0x39,0x21,0x91,0xa0,0xc9,0x3f,0x47,0xf2,0xa5,0x4c,0xda,0x0f,0xe0,0x25,0x02,0xad,0x19,0x54,0xec,0xdb,0xb2,0x06,0xe0,0xc6,0x77,0xc1,0x8d,0xf7,0xcb +.byte 0xe1,0x43,0xad,0x0f,0xb1,0x0f,0x7e,0x5b,0xba,0x1c,0x02,0xfa,0x60,0x9c,0xdc,0x89,0xdb,0xb2,0xc5,0x74,0xc3,0x5f,0x82,0x55,0x0a,0xbc,0x08,0x13,0xdf,0xac,0x35,0x7a,0xcc,0xdb,0x9e,0xbf,0xd7,0xde,0xfc,0x64,0x58,0xfb,0x33,0xd7,0xc3,0x39,0x4d,0x38,0x65,0xe7,0x98,0x83,0xbe,0x12,0x6d,0xb0,0xda,0x23,0xc0,0x7d,0xa8,0x64,0x75,0x33 +.byte 0x7f,0xe9,0xa7,0xa1,0x41,0x85,0x50,0xcc,0xaa,0x3c,0xc1,0xd8,0xda,0xa1,0x53,0x0c,0xac,0xca,0x6a,0x8c,0xbd,0xb0,0x2b,0xd9,0x2f,0x4c,0x3d,0x3d,0xec,0x9d,0x70,0x6c,0x67,0xff,0x1d,0x95,0xb0,0xaa,0x46,0xaa,0xd6,0x6c,0x3c,0x4c,0x65,0x36,0x47,0xea,0x5e,0x46,0x25,0x38,0x8f,0xbe,0x7d,0x3d,0x80,0x39,0x0f,0x05,0x06,0x1e,0xbe,0xe1 +.byte 0x9f,0xd4,0xc8,0x7d,0x11,0x8d,0x78,0x0d,0x26,0xe7,0x9a,0x47,0x8f,0x63,0x5a,0xe5,0x91,0xc0,0x81,0xa1,0xe6,0xff,0xa5,0x1f,0x38,0x0b,0x46,0x5b,0xc8,0x31,0xf3,0x56,0x5a,0x40,0x68,0x43,0x45,0xe0,0x83,0xf3,0x9a,0xc2,0x2e,0x62,0x4e,0xf9,0xd4,0xe8,0x13,0xe0,0x16,0x2d,0xa7,0x33,0xae,0xb5,0xc9,0x77,0xd6,0x5f,0xb1,0x28,0xa8,0xf7 +.byte 0x40,0x03,0x1b,0xe1,0x2a,0x3d,0xd6,0xe5,0x60,0x64,0x5e,0xe2,0x59,0xbb,0xb1,0x36,0x0b,0xeb,0xf7,0x8e,0x60,0x5a,0x3a,0x4a,0x78,0x9c,0x2d,0xef,0xe6,0x9e,0x1c,0x4f,0x53,0xea,0xc3,0xab,0x88,0x36,0x8e,0x08,0x3e,0x18,0xcc,0xb4,0xa2,0x60,0x5c,0xae,0x64,0xf6,0x6c,0x3c,0xcf,0x34,0xa4,0x6d,0xfd,0xb5,0x2f,0xfa,0x93,0x8f,0xf7,0xc1 +.byte 0x96,0xfe,0xa9,0x8c,0x85,0xec,0x65,0xc1,0x26,0x86,0x4f,0x36,0x1b,0xda,0xe0,0x47,0xb6,0xe4,0x34,0xf6,0xaf,0xce,0x56,0xdd,0xcf,0xad,0x94,0x1b,0x78,0xd3,0x17,0x00,0xf4,0x66,0x8e,0x8a,0x1d,0x11,0x1b,0xa2,0x7e,0x31,0xfc,0xda,0xc5,0x39,0x8a,0xc4,0x7d,0xee,0x53,0xe0,0x39,0x2d,0x53,0x2a,0x63,0x6b,0x0a,0x76,0xd0,0x2e,0xde,0x8d +.byte 0xf7,0x79,0x78,0xea,0x25,0x75,0x23,0x7f,0x17,0x93,0xfc,0xd3,0xfb,0x0e,0x51,0x3f,0x84,0x49,0xd4,0xbd,0x73,0x21,0x30,0x56,0x58,0x63,0x7a,0x20,0xfd,0x59,0x00,0xfd,0x42,0x82,0x69,0xd4,0x8e,0x69,0x4f,0xc8,0xf4,0x45,0x6d,0x8a,0x5c,0xa2,0xba,0x7d,0x69,0xcd,0xb5,0xf2,0x24,0x85,0x03,0x10,0xb3,0x3f,0xa6,0x9a,0xeb,0xe3,0x0d,0x75 +.byte 0x82,0x8d,0xe7,0xfb,0x9f,0x9b,0x7b,0x5b,0x33,0x1d,0xba,0xe8,0xde,0x01,0xfd,0xd3,0x38,0x16,0xb4,0x65,0xb7,0x53,0xdd,0xd5,0x4b,0x13,0x3e,0x1a,0x87,0xbe,0x34,0xbb,0xe2,0xbb,0x03,0x0a,0xc9,0xdf,0x47,0xa8,0x10,0x5f,0x3e,0x74,0xab,0x1a,0x7d,0x98,0x26,0xd1,0xc9,0xb7,0x8e,0xb8,0x3b,0x71,0x10,0x90,0x0a,0x91,0x86,0xef,0x22,0xec +.byte 0x3e,0x70,0x3d,0x05,0x75,0xb8,0x91,0xf6,0x77,0x54,0x5b,0x91,0x13,0x58,0xf9,0x29,0xbb,0x94,0x50,0xe7,0x8a,0xb5,0x31,0xa5,0xe3,0x07,0x7d,0x53,0xc0,0xe5,0x58,0x38,0x27,0x84,0xf0,0x96,0x99,0xef,0x60,0x07,0x05,0xdd,0x46,0x64,0xed,0xa8,0xc4,0x3e,0xde,0xac,0x6a,0xfe,0x2c,0x1a,0x9d,0x47,0x88,0x37,0x16,0xf5,0xb2,0x9e,0x78,0x21 +.byte 0x6e,0xd4,0x81,0x00,0x29,0xa1,0xcb,0x03,0x32,0x1e,0x45,0xbd,0xc9,0x86,0x97,0x56,0x34,0x2e,0xe5,0x91,0x2b,0x8d,0xf0,0x22,0xe9,0x13,0x0a,0x31,0xd8,0x82,0xbc,0x1a,0x7e,0x97,0x08,0x71,0x08,0xb0,0x82,0x8c,0x24,0x90,0x43,0x09,0x28,0x2d,0xcd,0xf1,0x31,0x9c,0x70,0x54,0x2b,0x13,0x07,0x33,0x4d,0x29,0x1d,0xbd,0x37,0x7d,0x95,0x07 +.byte 0x7b,0x23,0x67,0x59,0x34,0x0c,0x85,0xae,0x55,0x94,0xe3,0xfe,0xbf,0xd2,0x38,0x0b,0x2f,0x4f,0xc7,0x4c,0xb7,0x1d,0xfe,0x97,0x2a,0x22,0xf1,0xa4,0x2d,0x02,0xb6,0xdf,0xc7,0x9b,0x0a,0xf5,0x6c,0xcf,0x91,0xee,0x44,0xd5,0x2a,0xe5,0xa7,0x64,0xf7,0x37,0x59,0x85,0x8e,0xef,0xa3,0x0d,0xfe,0xcc,0x80,0xb9,0x5c,0x8d,0x01,0x0f,0xbc,0x5d +.byte 0xd5,0x47,0xff,0xa0,0x32,0xc7,0xac,0xb8,0xf8,0x43,0x3f,0x6d,0x68,0xa8,0xed,0x20,0x04,0x3b,0xa6,0x70,0x7a,0x75,0x84,0x50,0x7a,0x5f,0xab,0xa0,0x98,0xdf,0xa1,0x45,0x82,0x22,0xe7,0xf4,0xf5,0xc9,0x85,0x43,0xda,0x3b,0x18,0x40,0x38,0xfb,0x66,0x14,0xa4,0x51,0x26,0xe3,0xd8,0x2e,0x05,0x9d,0xd2,0x38,0xd5,0xca,0xd2,0xd9,0x87,0x4a +.byte 0x06,0xb1,0x12,0xa3,0x16,0xa2,0xea,0x96,0x8c,0xee,0x78,0xc5,0x57,0x0c,0xbb,0x45,0x38,0xd3,0x9b,0xb3,0x66,0xe0,0x0d,0x00,0x48,0x4d,0xfc,0xa1,0x59,0x31,0x30,0x77,0xdc,0x26,0x3a,0xe0,0xc6,0x53,0x42,0x50,0xac,0x50,0xa3,0x4d,0xd8,0x70,0xcf,0xdc,0x3a,0xd0,0xcc,0xab,0x5d,0x1e,0xda,0x30,0x32,0x7c,0xf1,0x5a,0x15,0x6a,0x92,0xb3 +.byte 0x32,0xce,0x4b,0xf7,0xa4,0x8b,0x62,0xaa,0xad,0xa0,0x46,0xed,0x2a,0xb3,0x01,0xaf,0x9f,0x4a,0x5a,0xce,0xcf,0xb4,0xe6,0x34,0xd0,0xad,0xdc,0xce,0x2a,0x32,0xee,0x60,0x3d,0xb4,0xd3,0xc6,0x0e,0x72,0xdf,0xe5,0xea,0x15,0x58,0x19,0x72,0xfa,0x78,0x55,0x1d,0x57,0x62,0xe9,0xa0,0x13,0xbf,0x64,0x17,0xae,0x42,0xce,0xf7,0x70,0x2a,0xd0 +.byte 0xf2,0xd8,0x3e,0xef,0x25,0x2f,0xf8,0x93,0xc1,0xc3,0xf5,0x35,0x6d,0x43,0x49,0xfd,0xda,0x97,0x3b,0x6c,0x04,0xe2,0xe0,0xae,0x92,0x2b,0xc7,0x24,0x3c,0x76,0xc5,0x29,0xd2,0x3f,0x35,0x9a,0x5b,0xc2,0x16,0x6a,0x34,0x44,0x10,0x36,0x32,0xb1,0xcc,0xc0,0x42,0xff,0x1a,0x3d,0xaf,0x66,0x52,0xda,0xe5,0xf8,0x74,0xda,0x7a,0x1e,0x29,0x35 +.byte 0x47,0xc8,0xe1,0x8d,0x7a,0x2f,0x0d,0x1c,0x12,0x5e,0xe6,0x56,0x15,0x74,0x6e,0x85,0x68,0xf5,0x17,0xd3,0x21,0x04,0x85,0x01,0x02,0xe4,0xfa,0x3f,0x69,0x29,0xd7,0x39,0x86,0x94,0x6f,0x81,0xa1,0x81,0x04,0x29,0xde,0xe2,0x0a,0x9b,0xd7,0x57,0xdc,0x77,0x2e,0x77,0x93,0x59,0x54,0xd3,0xf1,0xd5,0x11,0x07,0xe0,0x01,0x71,0xb5,0xb3,0xc0 +.byte 0xdb,0x17,0x4b,0x5b,0x58,0xfc,0x32,0xf9,0x75,0x8e,0xdf,0x60,0x88,0x8f,0xf9,0xb0,0xe3,0x64,0x75,0xd5,0x5e,0xb1,0xec,0x57,0xa3,0xd4,0xe2,0x05,0xf1,0xf9,0xa9,0x51,0x6b,0x84,0xc3,0x78,0x74,0xe9,0x36,0xd0,0xb6,0x14,0xcd,0xa3,0x05,0xb6,0xa2,0x5c,0x2c,0x11,0x53,0x10,0x60,0x8c,0x2c,0xd8,0x7b,0xc0,0x00,0xf1,0x64,0x35,0xdc,0x7b +.byte 0xf5,0x9b,0xd0,0x82,0xa8,0x00,0xe6,0x17,0xb9,0x5a,0x80,0xe1,0xee,0xb0,0x0c,0x3d,0x9a,0xae,0xaf,0xd8,0x70,0x2e,0x85,0xf0,0x0e,0xb4,0x5e,0x92,0x96,0x33,0xa5,0xa9,0x07,0x12,0x95,0xf1,0x4b,0x67,0x25,0x51,0x40,0x91,0xda,0xb9,0x4d,0x5b,0x6b,0x07,0x7e,0x52,0xa8,0xa6,0xf9,0xd1,0xeb,0x8e,0x47,0xd0,0xf8,0x7a,0x17,0x6f,0x04,0x41 +.byte 0x2b,0x65,0x3c,0x3b,0x0f,0xbc,0xef,0x26,0xc1,0x63,0x24,0x33,0x40,0x40,0xf2,0x1f,0x34,0xaf,0xba,0x1d,0x94,0x72,0xd6,0x44,0xe2,0x6f,0x1b,0x83,0x87,0xd6,0x2c,0xc9,0x4c,0x2e,0xa3,0x98,0xc4,0x86,0x16,0xfe,0xc2,0xa3,0xdc,0xb4,0x86,0xfd,0x66,0xd2,0xc3,0x09,0xfd,0x8e,0xa7,0xb9,0xd2,0x5c,0x57,0x5e,0xd6,0x15,0xc4,0x12,0xa0,0xe3 +.byte 0x52,0x54,0x7c,0x26,0x93,0x28,0xdc,0x13,0x97,0xff,0x1e,0x79,0x2d,0x83,0xbb,0xf2,0x9c,0xf1,0x51,0xf9,0xd7,0x26,0x78,0x69,0xfe,0x9b,0x07,0x91,0x0d,0xef,0x29,0x28,0xf0,0xd5,0x94,0xed,0xb8,0x45,0xe2,0xe1,0xde,0xe9,0x9a,0x01,0xc5,0x00,0x77,0xdf,0x40,0x61,0x52,0xbe,0x9e,0x82,0x8c,0x04,0x0e,0x92,0xab,0x67,0x96,0xdf,0xc7,0xa7 +.byte 0x01,0x55,0x66,0x73,0x6c,0xaa,0x47,0x2e,0xb6,0x98,0x64,0x0d,0x7e,0x45,0xa2,0xda,0x34,0x2d,0x1a,0x7b,0x35,0x49,0xee,0xc5,0x91,0x05,0xe0,0x14,0x19,0xdd,0xb7,0x2b,0x43,0x07,0x5a,0xb5,0xb2,0x6a,0x6a,0x7d,0xf1,0x17,0x3a,0x26,0x95,0x3a,0xff,0x9c,0xa8,0x19,0xe0,0x03,0x11,0x26,0xb9,0x07,0xfc,0x01,0xe3,0xa2,0x4a,0xeb,0x92,0xc0 +.byte 0x26,0x0a,0x88,0xdf,0x5b,0x67,0xc6,0xca,0xe0,0x98,0x0a,0x94,0x1e,0x93,0x32,0x49,0x64,0x7b,0xe5,0x8d,0x39,0x7c,0xb7,0xf0,0x4b,0xf0,0x46,0x62,0x47,0xcb,0x09,0x6f,0x01,0x09,0xbb,0x13,0x89,0xb3,0xc5,0xa8,0xa0,0xbb,0x05,0x61,0x62,0x07,0xdb,0xd8,0x4f,0x6a,0xc0,0xdc,0xaf,0xfe,0x97,0xb3,0x38,0x74,0xe0,0xa6,0x13,0xa9,0xb0,0x27 +.byte 0x1d,0xb7,0x2d,0xb1,0xa3,0x7c,0x22,0x7f,0x99,0x67,0x5a,0x7e,0x1c,0xd9,0xf4,0x45,0xa1,0xfe,0x12,0xa7,0x9d,0x43,0x1d,0x1c,0x29,0xfe,0x95,0x33,0x79,0xe7,0xb9,0xa2,0x7e,0x50,0x50,0xa4,0x52,0x92,0xd0,0x44,0x2b,0x4c,0x78,0x77,0xfa,0xd8,0x6f,0x81,0xe8,0xfb,0x50,0x9c,0xfc,0x80,0x61,0x91,0x25,0x3d,0x66,0x11,0xd0,0xc3,0x77,0x83 +.byte 0x20,0xee,0xf9,0x38,0x24,0x2f,0x63,0x6b,0x9e,0xca,0xda,0x49,0xd2,0xba,0x10,0x80,0xfe,0x77,0xf6,0x79,0x1b,0x95,0x30,0x16,0xec,0x90,0xde,0x4a,0xb4,0x7d,0x35,0x20,0x4c,0xac,0x23,0xaf,0xe4,0xfb,0xbb,0x8f,0xe8,0xc6,0xf5,0xc5,0xf9,0x0f,0x74,0x25,0x7c,0x37,0x96,0x81,0x21,0x4f,0xe9,0x56,0x28,0x5c,0xd1,0xf2,0x94,0xb4,0xf6,0x6b +.byte 0x34,0x9e,0xd9,0x37,0x41,0xeb,0x9c,0x71,0x4e,0xeb,0xc6,0xd3,0x7b,0x5b,0xc7,0x3e,0x07,0x59,0xe1,0xc5,0x81,0x72,0x7e,0x30,0xdb,0x35,0xcf,0xce,0x47,0x9f,0x36,0x74,0x34,0x00,0xa1,0xde,0x9f,0xae,0xba,0xe9,0x16,0xf7,0xf3,0xa7,0x24,0xf5,0x81,0xfa,0x40,0x80,0x9b,0x48,0xcf,0x97,0xc4,0xde,0xeb,0x7a,0x07,0xbc,0xf5,0xeb,0x5c,0x38 +.byte 0x6d,0x64,0xaa,0xc3,0x81,0x66,0x41,0xc8,0x3b,0xaa,0x8b,0x69,0x22,0x0b,0x19,0x6d,0x0f,0xd8,0xcb,0xea,0x2a,0x98,0x03,0x4b,0x42,0x4c,0x0a,0x7b,0x92,0xdf,0x59,0xa0,0xfd,0x27,0x0e,0x0f,0x98,0xa6,0xc9,0x31,0xe1,0x8f,0x9c,0x57,0x29,0x07,0x01,0x0f,0x26,0xf3,0xc6,0x43,0xdf,0x1d,0xe4,0xa6,0xd6,0xb0,0x56,0xfd,0xf7,0x9c,0xc1,0x0b +.byte 0x2f,0x9b,0xc3,0xbe,0xc0,0x09,0x14,0x0f,0x19,0x70,0xd3,0x5a,0x7f,0xe1,0x64,0xbb,0x47,0x04,0xb9,0x2a,0xfc,0x49,0x68,0xba,0x14,0xfa,0x65,0xc9,0x9b,0x46,0xd1,0x0c,0x03,0x3b,0x20,0x36,0x47,0x05,0xb0,0x89,0xd9,0xc0,0x36,0xe8,0xe2,0xfa,0xb3,0x2a,0xf9,0x2f,0x23,0x40,0x26,0xf3,0xe0,0x61,0xdf,0x6d,0x47,0xc4,0xe2,0xb9,0xdd,0x44 +.byte 0x9a,0x34,0xcf,0x1f,0xdb,0x72,0x28,0x23,0xf0,0x56,0x65,0xcb,0x43,0xad,0x7d,0x42,0xa5,0x73,0x97,0x62,0x7c,0x2d,0x6e,0x51,0x8f,0x94,0x07,0xe9,0x14,0xa8,0x48,0xdd,0xc5,0x63,0x4b,0xfd,0x73,0x46,0xc3,0xe2,0x55,0x66,0xe2,0x58,0x32,0x00,0x68,0xaf,0x1c,0xd4,0xf3,0x8c,0x59,0x89,0x6f,0x08,0xc5,0xb3,0x47,0x09,0x56,0x90,0x05,0xd1 +.byte 0xf8,0xc6,0x20,0x4a,0xb8,0x69,0xd4,0x87,0x5d,0x3d,0x89,0x6d,0xf4,0x10,0xcd,0x5c,0xba,0x3f,0x48,0x7a,0x26,0xb8,0x4d,0x9a,0x0e,0x22,0x2e,0x9e,0x70,0x5d,0xff,0xf9,0xf2,0xec,0xe8,0xb0,0xfc,0xbb,0xcf,0xfe,0x8e,0xc9,0x8d,0x2f,0xda,0x25,0x46,0xcb,0xe4,0x6a,0x33,0xce,0xbb,0x02,0x72,0x58,0xee,0x6d,0x40,0x86,0xc9,0x8d,0x06,0x62 +.byte 0x8f,0x6b,0x81,0x60,0xeb,0x78,0x46,0x32,0xe8,0xc6,0xde,0x86,0x4f,0x11,0xa9,0xad,0x62,0xb0,0x15,0xb6,0x09,0xa9,0x3c,0xe1,0x6b,0x12,0xb0,0x39,0x59,0x26,0xde,0xc6,0x7a,0x95,0xaf,0x00,0xd6,0xb7,0xc5,0xe4,0x43,0xde,0xc6,0xcf,0x2f,0xa0,0x8d,0xfd,0x54,0xd7,0xc6,0xed,0x64,0x16,0xa1,0x9b,0x39,0xe3,0xc6,0x9c,0x1e,0x60,0x6c,0x03 +.byte 0x3f,0xac,0x24,0x99,0x59,0x5a,0x4e,0x95,0x01,0x5d,0x2e,0x03,0xd0,0xb5,0xdf,0x19,0x85,0x4a,0x5e,0x70,0x6d,0x46,0x00,0xfb,0xbb,0xf5,0xb1,0x35,0x11,0xcb,0xda,0x4b,0x31,0x1a,0x0b,0xa3,0x58,0x9c,0xcf,0x09,0x79,0xd7,0x31,0x4e,0x6c,0xbc,0x16,0x6f,0x14,0xa3,0xbf,0xcf,0x05,0xe4,0xf8,0x2f,0x3b,0x5f,0xb7,0xc4,0xa4,0xbf,0x80,0xac +.byte 0x53,0xb5,0xf8,0x7c,0xf5,0x16,0x7c,0x5e,0x16,0x47,0xd1,0x01,0x34,0xd6,0xb9,0x8a,0xc9,0xff,0xe3,0x7d,0x80,0xe4,0xcd,0x83,0xfe,0x8a,0x49,0x34,0xa5,0xc0,0xf3,0xe7,0xff,0x09,0xbd,0xf4,0x84,0x36,0x19,0xc6,0xc7,0x4d,0x50,0xd2,0x3f,0xa7,0xdb,0xea,0x3d,0x74,0x15,0x45,0xe3,0x0f,0x6c,0x6a,0xcc,0x2a,0x16,0x40,0xef,0xaf,0x64,0x2d +.byte 0x76,0xa0,0xdc,0x74,0xa9,0xb5,0x70,0x6f,0x27,0xf5,0x3c,0xd0,0xa1,0x46,0xfb,0x9d,0x4c,0xb3,0xda,0x01,0x02,0xc0,0xbd,0x9f,0x4a,0x21,0xb7,0xdb,0xd9,0x89,0xe9,0x90,0x62,0xfb,0x89,0xb8,0x84,0x4b,0x2b,0x1c,0x5e,0x67,0xde,0x9d,0x59,0x3a,0xd0,0x15,0xc0,0xba,0xdf,0x12,0xf2,0x9e,0x07,0x2f,0xb0,0x9c,0x7f,0xf3,0x73,0x89,0x84,0x26 +.byte 0xb8,0x7f,0x2d,0xad,0x18,0xf7,0x06,0x10,0x9d,0xe9,0x09,0x4f,0x7b,0xa5,0xa0,0x96,0x2f,0x3d,0x8e,0x65,0x0b,0xe4,0x65,0xa2,0x7a,0x10,0x81,0xb1,0xb9,0xc8,0x4c,0x27,0x53,0x70,0xc7,0x25,0x5f,0x2c,0x03,0x7f,0xe4,0xff,0xc3,0x20,0x89,0x2e,0x4d,0xe8,0xab,0x0a,0x27,0x26,0x0e,0xe4,0x35,0xb5,0x43,0x5e,0x80,0xdd,0x18,0x53,0x3a,0xb7 +.byte 0x17,0x6b,0xc5,0x68,0x2b,0x13,0x0e,0xa7,0x93,0x9e,0xfb,0x6c,0x48,0xe8,0x57,0xf5,0xd5,0x2a,0xd8,0x5d,0x56,0xb1,0x5b,0x5a,0x1f,0x6a,0xc0,0x7e,0x55,0x01,0x80,0xcb,0xa9,0xf3,0x20,0x06,0x74,0xa6,0x73,0xe5,0xcb,0x1e,0xc6,0xf4,0x81,0xf7,0x8d,0x8c,0x18,0xfc,0xa2,0x9b,0xe2,0xb6,0x1d,0xd6,0x5c,0xbe,0x82,0xda,0x2c,0xa7,0x08,0x8f +.byte 0x58,0x2f,0x32,0x99,0x9c,0xa0,0x8f,0x22,0xfd,0x00,0xcf,0xef,0x4b,0xc5,0x49,0x11,0xf3,0x0a,0xa0,0x67,0x3b,0xf5,0x6a,0x2e,0x18,0xd1,0x3d,0xd1,0xee,0xd2,0xc3,0xc0,0x4f,0xbd,0x6a,0xd3,0xab,0x7b,0x56,0x92,0xd7,0x63,0x9f,0x87,0x44,0x0d,0x2a,0x67,0x44,0x17,0x48,0xa1,0xb8,0x99,0x3d,0xa7,0x57,0x46,0x3d,0x65,0x04,0x58,0xb0,0x43 +.byte 0xa4,0x73,0x95,0xd4,0xb2,0xbb,0x8f,0x65,0xea,0x4d,0x55,0xcd,0xe5,0xb6,0xa2,0x15,0x0d,0x74,0x6c,0x3f,0xe5,0x06,0x9a,0x75,0xc3,0x51,0xa0,0x1a,0x66,0x36,0x30,0xff,0x7a,0xdf,0x27,0x22,0x70,0x02,0x20,0x2d,0x52,0x6f,0x6d,0x34,0xb5,0x74,0x3a,0x88,0xf6,0xec,0x7d,0x34,0x02,0x27,0x1e,0x58,0xcc,0x50,0x88,0x4a,0x13,0x98,0x97,0xf9 +.byte 0x8f,0x6e,0x38,0x3b,0xed,0x2f,0x17,0x2e,0x44,0xb3,0xb4,0x93,0x14,0xe0,0xda,0xfd,0x29,0x02,0xb6,0xc5,0x80,0xa0,0xe2,0x1d,0x89,0x57,0xec,0xe8,0x15,0x43,0x7c,0xca,0x8b,0xb6,0x19,0x32,0x1c,0xf7,0x75,0x07,0xf7,0x37,0x4b,0x03,0x84,0x75,0xab,0x64,0x7a,0xa7,0xae,0x52,0xcb,0xe9,0xb1,0xc9,0x36,0xe9,0x49,0x60,0x82,0xc8,0xb9,0xcd +.byte 0x37,0x1d,0x2a,0x9a,0x76,0x8a,0x4a,0x26,0xcd,0xff,0xac,0x48,0xc6,0x28,0x00,0xdb,0x2b,0x87,0x77,0x17,0xf7,0x57,0x93,0xb7,0x68,0xa8,0xf9,0xec,0x7b,0xaf,0xb0,0xad,0xe1,0x31,0x09,0x5b,0xf6,0x11,0x09,0x4e,0x96,0x53,0x3c,0x5a,0xb1,0x99,0x1d,0xfb,0x3f,0x25,0x1b,0xcf,0x61,0x08,0x2d,0x98,0xcb,0x76,0xa7,0xe9,0x77,0xc6,0x3d,0xe0 +.byte 0x0c,0xc7,0x2e,0x34,0x57,0x57,0x4f,0x0b,0xb3,0x66,0xb4,0x57,0x3d,0x66,0xe4,0x3d,0x86,0x8a,0x3c,0x4f,0x19,0x97,0x3a,0x28,0x74,0x1a,0xa0,0xef,0x0d,0x10,0x51,0x58,0xb7,0xe2,0x2d,0x6a,0x6f,0x75,0xc3,0x67,0x9d,0xaf,0x76,0x6d,0x89,0x5d,0xd0,0x78,0xcd,0x03,0x48,0xb4,0x50,0x0b,0x5b,0x94,0x78,0x7a,0xe3,0x52,0xf6,0x4f,0x70,0x4c +.byte 0xc3,0xe2,0x89,0xc9,0x33,0x75,0x83,0xc4,0x65,0x79,0x4d,0x8f,0xff,0x0e,0x11,0xb1,0x9e,0x87,0x9c,0xe4,0xd1,0x31,0x36,0xd4,0xef,0xa8,0x41,0x78,0xd7,0xad,0x47,0xbb,0x3d,0x0b,0xf5,0xd7,0x2a,0xf3,0xe5,0x3b,0x7c,0x90,0xa5,0xe6,0x71,0x89,0x55,0x88,0x5e,0x48,0x88,0x18,0xca,0xec,0x08,0x41,0x27,0xd5,0xe1,0x9f,0xb4,0x3c,0xdf,0x11 +.byte 0x57,0x9f,0x5a,0x54,0x4e,0xfb,0x6c,0xc9,0xb2,0x98,0x65,0xa3,0xe2,0xd5,0x91,0x52,0x4a,0x87,0x30,0xc8,0x9e,0xcb,0xe7,0x9e,0x00,0x78,0x9e,0x3f,0x9d,0xe1,0x46,0x5b,0xdd,0xf3,0x3e,0xf4,0x36,0x94,0x97,0x06,0x78,0x46,0x53,0xb9,0x0d,0x8f,0x94,0x42,0x60,0x76,0xc7,0xc3,0x4d,0x48,0x06,0xee,0xf1,0xb9,0x58,0xe4,0xe7,0x11,0x68,0x41 +.byte 0x51,0xd9,0x98,0xd1,0x26,0x3b,0xcb,0xd1,0x4f,0xce,0x89,0x20,0x76,0x1d,0x58,0x70,0xc7,0x0b,0xe4,0x70,0xf1,0xd0,0x33,0x1b,0x17,0x9a,0xda,0x47,0x7e,0xfc,0xec,0x34,0x0a,0xf8,0x24,0xf1,0xec,0x83,0xe4,0x0d,0x91,0x6d,0x46,0x82,0x33,0xf6,0x25,0xa3,0x26,0x7c,0x2a,0x78,0xef,0x7c,0x6c,0x0e,0x6a,0xd5,0x88,0x97,0xe4,0x76,0x4a,0x2c +.byte 0x36,0xa2,0xa0,0x06,0xe2,0x20,0x7c,0x94,0xe2,0x0a,0xee,0x5b,0xc7,0x21,0x4e,0x60,0x24,0x32,0x46,0x09,0x69,0x56,0x6c,0xf5,0x62,0xe7,0xab,0x0d,0x64,0x7e,0x6a,0xa2,0x1b,0x15,0x33,0xb8,0x41,0x0f,0x96,0x16,0x2f,0x7b,0x97,0xdd,0x14,0x6a,0xec,0xfb,0xbf,0xc8,0x3d,0x99,0x72,0xa7,0x14,0xaa,0xae,0xf2,0x10,0xd5,0x4a,0xaa,0xd0,0xb1 +.byte 0xb9,0xbb,0x5f,0xa9,0x51,0x96,0x91,0xc0,0x1a,0x31,0xad,0xa1,0x7e,0xb8,0x55,0x90,0x1a,0x17,0x37,0x4d,0x62,0x8c,0x75,0x19,0xfc,0x84,0x54,0x3d,0x5e,0x0a,0xaf,0x27,0xe0,0x5f,0xe2,0x76,0xad,0x9d,0xda,0x43,0xac,0x23,0x5c,0xb9,0xf7,0x2a,0xac,0x55,0xea,0x9b,0x07,0x4c,0x06,0x9a,0xba,0x4c,0x25,0x20,0xee,0x2a,0x37,0xb5,0x7d,0xa0 +.byte 0x4f,0x3a,0xb8,0xc7,0x7c,0x2b,0x0f,0xb7,0x1e,0x26,0xe1,0xc3,0x17,0xf2,0x60,0x2b,0x47,0x06,0x7f,0xa3,0x7b,0x80,0xd0,0x48,0xf1,0x8e,0x5a,0x3d,0xcd,0x6a,0x49,0x0f,0x60,0xe5,0x3a,0x7f,0xa8,0x10,0x4b,0x0e,0x29,0x74,0x4e,0xe8,0xe1,0xae,0xe3,0x46,0xa5,0x87,0x7d,0xe2,0xd3,0x98,0x63,0x1e,0xc4,0xba,0x31,0x7e,0xd5,0xe2,0xbf,0x95 +.byte 0x2d,0x8d,0x3b,0x1c,0xc8,0x5a,0xd3,0x42,0xe5,0x5e,0x26,0xfa,0xa3,0xcf,0x7b,0x68,0x43,0x5a,0xf6,0x86,0x06,0xd7,0x08,0xeb,0x70,0xa9,0x17,0xf6,0xcb,0xfc,0x9e,0xbe,0x82,0x69,0xe2,0x58,0xb3,0x5f,0x16,0xed,0xf1,0xea,0xaa,0xe4,0xbd,0x5c,0xcd,0x88,0xd6,0x48,0x18,0xfd,0x65,0xd1,0x44,0x77,0x06,0x8e,0x82,0x93,0x88,0x97,0x05,0xad +.byte 0xc5,0x62,0x1b,0x6f,0xcd,0x23,0x45,0x86,0xcd,0x19,0x9a,0x90,0x6f,0x54,0x33,0x1b,0x35,0x01,0x05,0x50,0x09,0x7d,0x61,0x4e,0xc3,0x79,0x27,0xe0,0xf7,0xf6,0xf3,0x8c,0x3f,0xd2,0x77,0x09,0xa7,0x9c,0xb4,0xb9,0x2b,0x2e,0x5a,0x34,0x2c,0x60,0xc5,0xcf,0xa6,0x5f,0xf9,0x16,0x8a,0xd8,0xd7,0xab,0x2d,0xe7,0x0b,0x90,0x97,0xb0,0x45,0xf1 +.byte 0xc5,0xe7,0xb2,0x50,0x5c,0x4f,0x3a,0xfe,0x7d,0x6b,0xbf,0xe7,0x8d,0x9d,0x9a,0x0d,0xaa,0x3f,0x58,0x09,0x7c,0x0f,0x3a,0xe5,0xff,0x05,0xa7,0x2f,0x78,0x0d,0x5f,0xa3,0x3e,0xf8,0xc5,0x51,0x98,0xc7,0x6b,0x98,0x53,0xe3,0xdd,0x69,0xa6,0x20,0x64,0x99,0x41,0xd7,0x78,0xcf,0x83,0x11,0xc4,0x9a,0x85,0x32,0x12,0xe7,0xff,0x8e,0x4e,0xce +.byte 0x17,0xe6,0xb4,0x33,0x24,0x1c,0x99,0xba,0x1e,0xf8,0x3c,0xf3,0xb8,0x2e,0x80,0x89,0xa1,0x26,0x55,0xfc,0x22,0xde,0x5b,0x66,0xbb,0xf2,0x3b,0xd7,0xad,0x11,0xd6,0x5e,0x67,0xb2,0x34,0x6f,0x0c,0x7b,0x09,0xa9,0x7f,0x6f,0x88,0xe3,0xef,0x11,0x85,0x76,0x23,0x32,0x78,0x0b,0xa7,0x81,0xc0,0xdd,0xb0,0xac,0x59,0xe8,0xc8,0xde,0x13,0xa5 +.byte 0x75,0x30,0xfb,0xac,0xaf,0x13,0x0f,0xb9,0x32,0xf9,0x41,0xfb,0x36,0x29,0x19,0x11,0xd3,0x6d,0xf5,0xd1,0xf0,0xf3,0x99,0x16,0xf5,0x04,0x01,0x41,0x94,0x8d,0x89,0xc6,0x9c,0xf2,0x39,0x9d,0x07,0x74,0x12,0x70,0x89,0xff,0x16,0xc1,0x79,0x30,0xf5,0x27,0x24,0x75,0x48,0x51,0xcd,0x81,0x15,0xcd,0x70,0x54,0x58,0x9b,0xe5,0x80,0x9c,0x2b +.byte 0xdc,0x99,0x69,0x8f,0x14,0xbe,0xee,0x21,0x96,0xa8,0xd4,0x6b,0xf5,0x60,0xa4,0x2c,0x11,0x01,0xff,0x07,0x99,0x72,0x4b,0x5b,0xca,0xb5,0x10,0xfc,0x32,0xdc,0xbc,0x56,0x91,0xe9,0xec,0xb5,0x51,0x0a,0xa1,0x46,0x2c,0x8e,0x74,0xd7,0x63,0x42,0x76,0x41,0x8e,0xc1,0x7d,0x5d,0x86,0xf9,0x8c,0xbe,0x9b,0x52,0xce,0xf1,0x5b,0x04,0x8c,0x62 +.byte 0x8c,0xb7,0x62,0x0e,0x62,0x46,0xaf,0xc0,0xb0,0x8c,0x94,0x8e,0xff,0x17,0x83,0x45,0x45,0x19,0x01,0x49,0xf5,0x97,0x13,0xb7,0x9c,0xe5,0x8d,0x62,0xc0,0x25,0x01,0xcb,0xcc,0x23,0xd1,0xfd,0xdb,0xc6,0x4d,0xca,0xe2,0x50,0x3c,0x77,0x1a,0x48,0xb2,0x3e,0x66,0x6b,0x80,0xff,0x7e,0x26,0x23,0x21,0x1b,0xa3,0x1e,0x17,0x3d,0x13,0x7f,0x43 +.byte 0x51,0x97,0xfc,0x56,0x1e,0xaf,0x79,0x43,0xd8,0x2a,0x32,0x4f,0x28,0x28,0xe2,0x34,0x19,0x2a,0x64,0x13,0xae,0xf8,0xaf,0x18,0xc7,0x97,0x5d,0xab,0xd4,0xa4,0x3d,0x1f,0xa1,0x13,0x60,0x17,0x63,0x8c,0xb7,0x6a,0x36,0x57,0xab,0x23,0xcb,0x87,0xad,0x4d,0x6b,0xce,0x7f,0xc2,0x65,0xf9,0x30,0xbc,0x22,0xb9,0x8a,0x6e,0x82,0xb9,0xcf,0xd5 +.byte 0xe6,0xa7,0x8d,0x6c,0x50,0x6f,0x98,0x15,0xe3,0x38,0x37,0x7a,0x23,0x47,0xed,0xac,0xb8,0xa3,0xa3,0xe7,0x5c,0x51,0x2f,0x9e,0x69,0x49,0xea,0xaf,0x9b,0x6d,0x6f,0x64,0x54,0xcc,0xa4,0x23,0x7b,0x5b,0xa0,0x30,0x5a,0xcd,0xb7,0xa4,0xe5,0x02,0x13,0x36,0x21,0x58,0x96,0xa2,0xfd,0xeb,0x00,0x78,0x5c,0x71,0x63,0x32,0x80,0x63,0x8c,0x67 +.byte 0xac,0xe7,0xe0,0x92,0x5b,0x27,0x49,0x9d,0xa6,0x84,0x64,0x2e,0x51,0x5d,0x87,0x83,0xbe,0xce,0xba,0x56,0x33,0x8f,0x5c,0xed,0xb6,0xc0,0x90,0x80,0x17,0x98,0x8a,0x7c,0xe5,0x51,0xaf,0x8d,0xc0,0x76,0x19,0x6b,0xc8,0x7e,0xa1,0x9d,0x94,0x18,0x25,0xd6,0xf4,0xc0,0x19,0x75,0x34,0xaa,0x83,0xfd,0x8c,0x8f,0xeb,0x08,0x63,0xcc,0x39,0xa8 +.byte 0xf7,0xe6,0x75,0x53,0x01,0xed,0xb0,0x43,0x8c,0x54,0x37,0xea,0x1d,0x55,0x88,0x38,0x46,0x30,0x37,0xa2,0x85,0x4d,0xf8,0xdf,0xd4,0x42,0xd1,0xb8,0xac,0x1b,0x23,0x4d,0x49,0xd8,0x07,0xe0,0x0f,0x8a,0x24,0x73,0xb7,0xd1,0x0a,0x2c,0x1c,0x72,0x19,0x5b,0x84,0xac,0xe9,0xcb,0xd5,0xa0,0x2f,0x5d,0x2f,0xca,0xe7,0x25,0x5e,0x22,0x3d,0x37 +.byte 0x22,0xfe,0x53,0xbb,0xb3,0xf3,0xc4,0x73,0x3a,0x43,0x1f,0xd7,0x73,0x82,0x5f,0x1d,0x94,0x54,0xfc,0xfc,0x7b,0xc5,0x27,0x6c,0x31,0x12,0x0c,0x20,0x59,0x43,0xd6,0xc2,0xeb,0xea,0x38,0x4e,0xa2,0xd8,0xe4,0x4a,0x07,0x36,0xe8,0x37,0x77,0xbd,0x14,0x5b,0xdb,0x7e,0x2b,0x77,0x08,0x4f,0x29,0x96,0xf9,0x11,0x80,0x6e,0x91,0x10,0xe6,0x9b +.byte 0xef,0x18,0xf9,0x73,0x16,0xbf,0xd4,0x18,0x8e,0x9e,0x29,0x6e,0xbf,0x38,0xea,0xa7,0x23,0xc2,0x85,0xe0,0x96,0xb5,0xd7,0x61,0x3b,0xfe,0xca,0xe6,0x03,0xdd,0xf2,0x67,0xfb,0x1f,0xb9,0x8b,0x73,0xca,0x1e,0xe7,0xd3,0xc4,0x5b,0xd2,0x35,0x01,0x77,0xfa,0x1e,0xea,0x6c,0x2a,0x8b,0xb3,0x9d,0x83,0x6d,0xef,0x1b,0x84,0x2b,0x7e,0xa4,0xc0 +.byte 0x64,0x4d,0xea,0x44,0xce,0x23,0x63,0x5d,0x98,0xe4,0xfe,0x86,0x8e,0xe3,0x35,0xb4,0x4d,0x18,0x53,0x15,0xbc,0xaa,0x23,0x0b,0x0d,0xe4,0xa9,0x83,0xae,0xbe,0x43,0x57,0x33,0xf6,0xa4,0x95,0xf4,0x68,0xba,0xc7,0xf3,0xfe,0x83,0x3b,0x32,0xd3,0x65,0xb7,0x02,0x16,0x8f,0xb4,0xc8,0x4a,0x6d,0xf5,0x9c,0x58,0xa4,0xdc,0xe2,0x6c,0xaf,0xc9 +.byte 0x7a,0x46,0xac,0x39,0x82,0x23,0x00,0xfd,0x49,0x2f,0x83,0xca,0x15,0xd6,0xfd,0x05,0xd4,0x50,0x9a,0xd3,0xee,0x31,0x78,0x7b,0x34,0xe1,0x96,0x83,0x22,0xaa,0xd8,0xc7,0xe4,0xee,0x76,0xb0,0x35,0x9e,0x26,0x97,0xb8,0x40,0xc2,0xe4,0x83,0x7b,0x3f,0x1c,0x01,0x6c,0x6d,0x0f,0x95,0x47,0x53,0x04,0x6d,0xa6,0x73,0xc0,0x8f,0x06,0xf8,0x86 +.byte 0x84,0x96,0xe2,0x3e,0x38,0x17,0x50,0xbe,0x60,0x35,0x80,0x3a,0xba,0x24,0x3b,0x38,0xdc,0x15,0x49,0xfd,0xef,0xbd,0x33,0xe2,0xf6,0x21,0xfd,0x15,0xc2,0x34,0xce,0xe2,0xf2,0xe5,0xfa,0x68,0x4c,0xf0,0x38,0xda,0x9f,0xcc,0x65,0x3a,0x1c,0xe4,0x30,0x1e,0x01,0x89,0x6e,0x96,0xd5,0x45,0x27,0xb5,0x82,0x98,0xaa,0xbb,0xee,0xcc,0xb5,0xe4 +.byte 0xbf,0xc6,0x7e,0x26,0x0a,0x7e,0x70,0x5c,0x52,0xc2,0x64,0xbc,0x49,0x37,0x50,0x78,0x81,0xdb,0xd9,0x80,0x68,0xad,0x1d,0x3e,0xa7,0xca,0x95,0x93,0x7c,0x18,0x0b,0xa9,0x92,0xd9,0xf8,0x8c,0xf4,0x58,0x40,0x4f,0x74,0xed,0xbc,0x0e,0x64,0x7c,0x8a,0x44,0x04,0x8e,0x33,0x27,0x46,0xa2,0x37,0xb3,0xce,0xff,0xc6,0x0b,0xb2,0x6c,0x41,0x01 +.byte 0xe6,0x0d,0x6c,0xbe,0x60,0xd1,0x1e,0xde,0xb0,0x81,0x57,0x4f,0xa2,0xf8,0x02,0x5b,0x00,0x3d,0xca,0x9c,0x43,0x4a,0xf7,0xbe,0xab,0x3b,0xc0,0xc9,0xaf,0xab,0x1e,0xa7,0xf2,0x10,0xb1,0xb7,0x73,0x6b,0x43,0xf2,0x75,0xe1,0x7c,0xc7,0xb8,0x91,0x5d,0xc6,0xb8,0xb4,0xd8,0x2b,0x95,0xf5,0x8b,0xe3,0x9e,0x3e,0x5a,0x7a,0x55,0x05,0x7f,0xd2 +.byte 0x83,0x36,0xb0,0xfc,0xc5,0x73,0x2a,0xa5,0x6c,0xcb,0x72,0xeb,0xae,0x38,0x38,0x05,0xdd,0xab,0xe2,0xa2,0x92,0x11,0xed,0xd5,0x2a,0x27,0x52,0x6b,0xba,0xae,0x56,0xf0,0x1b,0x60,0x53,0x9b,0x21,0xa6,0x62,0xfb,0x06,0x28,0xfe,0x94,0x26,0x38,0x72,0x80,0xed,0x76,0x61,0x5c,0x43,0xe2,0xee,0xfc,0x4f,0x37,0x52,0x00,0xc7,0xb6,0x51,0xcd +.byte 0xb4,0x9d,0x4f,0x28,0x31,0x44,0x14,0xba,0xe4,0x3b,0x79,0x63,0x8c,0x48,0x71,0x38,0xc2,0xeb,0x86,0x4f,0x5b,0x0a,0xc6,0x2e,0xbc,0x7a,0xea,0x09,0x11,0xc4,0x95,0x25,0x35,0x36,0x2a,0x08,0x2c,0xc5,0xc3,0xf0,0x94,0xaa,0xce,0xdc,0x48,0x42,0x7d,0xf6,0x36,0x21,0x58,0x89,0x5b,0x5f,0x11,0xaf,0x8d,0x5e,0x72,0x38,0x6b,0xda,0xe6,0xd6 +.byte 0xde,0x5c,0xfb,0x64,0xbb,0x9b,0xb6,0xe1,0x8d,0x25,0x00,0xa6,0x75,0x13,0x2d,0xa4,0xbe,0xf7,0xdf,0xe2,0x15,0x50,0xfa,0x11,0xe8,0xe7,0x85,0x92,0x3b,0xcd,0x10,0x2c,0x91,0xfa,0xb7,0x88,0xed,0x80,0x8f,0xec,0x91,0x15,0x70,0x51,0x2f,0x3d,0x52,0x01,0xd8,0xc8,0x76,0x9c,0x4c,0xdb,0x13,0x02,0x6c,0x30,0xcb,0x3f,0xea,0x3b,0xa6,0x26 +.byte 0x89,0x12,0x1f,0x34,0x04,0x46,0x05,0xff,0xa7,0x71,0x41,0xf7,0x88,0xa1,0x53,0x3e,0x2d,0x8e,0x5b,0xad,0xe6,0xab,0xb4,0x4d,0x0a,0x9d,0x40,0x6c,0x12,0xfc,0xd8,0x49,0xeb,0x7e,0x91,0xb9,0xca,0xac,0x60,0x93,0x28,0x44,0x91,0x6f,0x54,0xf6,0x7b,0x67,0x8c,0xed,0x43,0x2b,0x36,0x56,0x1e,0x91,0xc3,0x67,0xac,0xd6,0x51,0x00,0xcc,0x97 +.byte 0xfa,0xde,0x4d,0x74,0x1e,0x62,0xd6,0x8a,0x2a,0xb5,0xc3,0x53,0x81,0xcd,0x2a,0xb2,0xc8,0xb7,0x95,0x99,0xba,0x6c,0xb8,0xde,0xe1,0x93,0x39,0x6f,0xe8,0xb7,0x3f,0x6c,0x41,0x10,0x44,0xd9,0x9d,0x7e,0xe6,0x8d,0xdb,0xbb,0x70,0x4f,0xe8,0x44,0x8f,0x7d,0x1d,0x0f,0x8a,0xa4,0xb8,0xa7,0xdc,0x82,0x59,0xb6,0x23,0x16,0x26,0xf9,0xc1,0x92 +.byte 0xe0,0xbf,0x9c,0x38,0xc1,0x9f,0xd9,0x1e,0x07,0x74,0x8c,0x0d,0x93,0xdd,0x5d,0x25,0x2a,0xa9,0xbc,0x74,0x97,0x5f,0x39,0xc7,0x25,0x11,0x5c,0x89,0x78,0x39,0xa1,0xf1,0x11,0x16,0xca,0x08,0xcc,0x12,0x09,0x17,0x7f,0x1b,0x86,0x47,0xce,0x95,0xf3,0x0a,0x5e,0x75,0x52,0xed,0x5c,0x7c,0xae,0x1c,0x93,0x3e,0x44,0x1e,0x11,0xed,0x7b,0xff +.byte 0x92,0x27,0x30,0x1c,0xfe,0x33,0xa5,0x52,0x39,0x44,0x20,0x08,0x02,0x22,0x58,0x47,0xc4,0x63,0xec,0xd8,0xc4,0x29,0x04,0x44,0xa7,0x94,0xbc,0x8f,0xba,0x84,0xc8,0x16,0x85,0xe3,0xc3,0x58,0x9a,0xf6,0xdc,0x3e,0x15,0x58,0x06,0x04,0xc8,0x78,0xe6,0xb7,0x94,0x2c,0xce,0xb0,0x42,0x3c,0xbe,0x56,0xb4,0x82,0x84,0xb1,0xe7,0xb2,0xad,0x42 +.byte 0x58,0x48,0x6e,0xd5,0x94,0x78,0xc3,0x5e,0xd8,0xb0,0xd3,0xa5,0x4c,0xe0,0xaf,0x77,0x0f,0x93,0xa3,0x03,0xf5,0xa6,0x50,0x19,0xb4,0xef,0x9f,0x57,0x84,0x24,0x12,0xb0,0xec,0xb0,0xb0,0x9a,0x9d,0x51,0x69,0xcb,0xd0,0x04,0x13,0x1e,0xfb,0xc1,0xc9,0x66,0xe7,0xb2,0x4c,0x75,0x25,0xbb,0xef,0x21,0x7b,0x00,0x3d,0x3f,0x4c,0x44,0x42,0xbf +.byte 0x45,0xeb,0x42,0x28,0xbb,0x88,0x41,0xfc,0x9a,0xc8,0x04,0x1e,0xff,0x79,0xb0,0x12,0x7f,0xf6,0xb2,0xcd,0x34,0xaa,0xaa,0x83,0x8a,0xb1,0x1b,0x13,0xe2,0xb1,0x9e,0xcd,0xe7,0x87,0x4c,0x0e,0x14,0xd4,0x00,0x65,0x95,0x9c,0x5f,0x76,0x94,0x63,0xb6,0x1e,0x7c,0xe0,0x97,0xe9,0x87,0x6e,0x86,0x7a,0xba,0xa1,0xea,0x60,0x62,0xb1,0x93,0x7a +.byte 0x08,0xba,0x85,0x18,0x61,0x1e,0x9b,0x63,0x09,0xea,0xf5,0x06,0xb8,0xc6,0x1b,0x24,0x3d,0x86,0x70,0x4a,0x6d,0xfa,0xb9,0xf2,0xb0,0xc8,0x59,0xa2,0xa6,0xde,0x78,0xf5,0x55,0xd4,0x91,0x57,0x56,0x53,0x8f,0x0f,0x4f,0x76,0xf9,0x57,0xa8,0x66,0xde,0xd6,0x33,0x30,0xb8,0x0c,0xb5,0x0a,0xea,0x84,0x9a,0xe5,0xcd,0x03,0x57,0xcb,0x8b,0x47 +.byte 0xf5,0xe3,0x67,0xc1,0x69,0x42,0x7c,0xa3,0x91,0xa4,0x25,0x22,0x5a,0xf2,0x15,0x43,0xca,0x3a,0x62,0x2c,0xcd,0x9a,0x99,0xfb,0xb0,0xfc,0x2c,0x41,0xa6,0x84,0x51,0x93,0xc7,0x64,0xd8,0x95,0x8a,0xe7,0x0c,0xa4,0xd1,0x0d,0x57,0x4c,0x00,0xa6,0x55,0x3f,0x5b,0x9a,0x88,0xd3,0x39,0xf8,0xfe,0x30,0xf5,0xff,0xa7,0xcf,0x66,0x33,0xaa,0x20 +.byte 0x2f,0x20,0xc6,0x47,0x33,0x36,0xac,0xf8,0x8b,0xca,0x83,0xa3,0xc3,0x5f,0x97,0xe5,0x9f,0x88,0x27,0x34,0x90,0xa1,0xfc,0x94,0xdc,0x5c,0x20,0x13,0x92,0x7c,0x9b,0x8b,0xe5,0x76,0xc2,0xb0,0x42,0x31,0x7c,0x0c,0xdd,0xbc,0xc5,0xcb,0xcd,0x72,0xaa,0xfc,0x89,0xbf,0x9d,0x79,0x19,0x9c,0x1b,0xca,0x19,0xe5,0x57,0xb3,0xbd,0x54,0x92,0xd4 +.byte 0xbc,0x93,0x82,0x05,0x0b,0xc9,0x92,0x18,0x78,0xc1,0x23,0xff,0x65,0x7a,0x27,0x93,0xae,0xb6,0xf9,0x28,0x70,0x80,0xfe,0x97,0x73,0x06,0xe5,0x66,0x2b,0xb9,0xd9,0x20,0xe0,0x4a,0xf4,0xa6,0xa2,0xd1,0x6e,0x97,0x2b,0x90,0xa5,0x34,0x80,0x2c,0x25,0x3f,0x92,0xf2,0x41,0x50,0x5c,0x32,0x3d,0xe2,0xf0,0x6e,0x07,0x3c,0xc1,0x13,0x2d,0x04 +.byte 0x2e,0x39,0xc6,0x19,0x74,0xe4,0x1d,0x4e,0x85,0xc8,0x3b,0x91,0x44,0x01,0xbc,0x86,0xdb,0xcb,0x0f,0xe5,0x54,0x6d,0xec,0xac,0xa9,0xdf,0x34,0xa2,0x9c,0xa9,0x77,0xe8,0x84,0x7f,0x82,0x67,0xf8,0xd1,0xce,0x7d,0xc8,0xc0,0x29,0xf8,0x59,0x03,0xea,0x6d,0x7d,0x21,0x07,0xe4,0x7e,0xf0,0xb1,0x13,0x8d,0x20,0x6d,0xa0,0xe9,0x98,0x3f,0x73 +.byte 0xaf,0x8b,0x28,0x34,0xe9,0x12,0x57,0xaf,0x9a,0xd3,0xc7,0xb5,0xb0,0x60,0x26,0x72,0xae,0x39,0xf1,0x4a,0x38,0xa6,0xd5,0x07,0x7e,0xc1,0x37,0x1f,0x45,0x40,0x89,0x6f,0x1e,0x31,0x4d,0x6a,0x20,0x65,0x5e,0xd7,0x04,0x3d,0x9a,0x94,0x31,0x07,0xf7,0x20,0xef,0x1c,0xa6,0xcd,0xde,0x7e,0xcb,0x45,0x55,0x1e,0xe3,0x7f,0x3a,0x8f,0xf2,0xdf +.byte 0xa3,0x55,0xcb,0xfd,0xc2,0x51,0x49,0x07,0xda,0xb4,0x64,0xac,0x82,0xa3,0xb5,0x0f,0x87,0x6e,0xf6,0x6d,0xfd,0x9e,0x5f,0xf8,0xe5,0x74,0xa4,0xd4,0x61,0x6d,0x9e,0xea,0x41,0xc1,0xa7,0xa4,0x8d,0x13,0xdf,0x0c,0x8d,0x1d,0xe5,0x19,0xa3,0xd3,0xc1,0xf5,0xb5,0xe5,0x09,0xc7,0x52,0x2d,0x23,0x74,0x9e,0xa2,0xcd,0xe2,0x58,0x24,0x62,0xd8 +.byte 0xcd,0x60,0x24,0x1d,0xf6,0x84,0xec,0x35,0x35,0xfc,0x6e,0x78,0x96,0xea,0xfa,0x40,0xff,0x10,0x05,0x8e,0xfa,0x4c,0xae,0xe4,0x41,0x71,0xf2,0x4d,0x81,0x6c,0x2c,0xc3,0x60,0xcf,0x2f,0xaa,0xcf,0xda,0xe9,0x2d,0x58,0x2c,0xec,0x4f,0x04,0x03,0xa5,0xbe,0xb2,0x40,0x11,0x5c,0x85,0xae,0xf9,0x1a,0x43,0x62,0x90,0xd6,0xa1,0xdf,0x34,0x59 +.byte 0xf4,0x8e,0x1b,0x1e,0x89,0x8e,0xba,0x82,0xa5,0x3b,0x96,0xa7,0x4c,0x24,0x72,0x00,0x25,0x7a,0x36,0xa1,0x81,0x61,0x1d,0x62,0x57,0x7d,0x8b,0x32,0xe2,0xdb,0x31,0xe3,0x68,0xb4,0xb8,0xac,0x83,0x95,0x9a,0xbb,0x7a,0x54,0x42,0x08,0xd8,0x68,0xf6,0x97,0x9d,0x3a,0x94,0x7e,0x9b,0xa4,0x13,0x72,0x51,0x3d,0x90,0x32,0xa7,0x21,0x21,0x96 +.byte 0xc4,0x67,0x3d,0x0b,0x4e,0x7d,0x8b,0x58,0x6b,0x8d,0x0e,0xcf,0x6d,0xbb,0x6b,0xe8,0xc9,0x47,0xc8,0x3d,0x59,0xa5,0x48,0xc6,0x74,0x61,0xd9,0x98,0xa6,0xba,0xa6,0x75,0x19,0x02,0xb6,0x15,0xd9,0xe0,0xa2,0x4a,0x1b,0xe0,0xe0,0x83,0xb8,0xcb,0x7b,0xf2,0x54,0x02,0xc9,0xcd,0x77,0x51,0xd2,0xce,0x9f,0x47,0x4a,0x32,0x7a,0x85,0x91,0xab +.byte 0x24,0x46,0x5b,0x50,0xa1,0x7b,0x7f,0x28,0xd4,0x09,0x62,0xce,0x15,0x9b,0x71,0xed,0x54,0x32,0xc6,0xb0,0x5d,0x11,0xfc,0x79,0x2e,0xfa,0xba,0x63,0xf5,0x56,0xe7,0xfe,0x93,0xce,0xb3,0x41,0xd8,0x3e,0x55,0xcb,0xfd,0x67,0x02,0x82,0xf7,0xc8,0x5f,0xd4,0x5a,0xee,0x80,0xe4,0x6c,0x2a,0xfe,0x2c,0x27,0x33,0x82,0x88,0x40,0x59,0x78,0x8e +.byte 0xfe,0x46,0x57,0xd1,0xd6,0xe1,0x51,0xf3,0x26,0xb3,0x87,0xeb,0xbd,0xce,0x67,0x27,0x0a,0x6d,0x9f,0xdc,0x41,0xf9,0xf8,0xcb,0x8f,0x78,0xdc,0x9d,0x8e,0x62,0x31,0x78,0x4c,0x6b,0xef,0xec,0x1a,0xd0,0xfb,0xf9,0x9d,0xc1,0x84,0xd7,0xeb,0x68,0x7d,0x8b,0x01,0x7a,0xca,0xc9,0x25,0x40,0x9b,0x0b,0x2b,0xa6,0x93,0x7d,0xe2,0xa2,0x40,0x0e +.byte 0x4e,0x1e,0x12,0x5d,0x62,0x0b,0x92,0x72,0x06,0x04,0x7d,0xdf,0x68,0x64,0xf1,0x99,0x88,0x38,0x73,0x23,0xe3,0xf5,0xbf,0x06,0x88,0x65,0x9b,0xc2,0xee,0x66,0xf5,0x6e,0xa3,0x03,0x04,0x5c,0x2e,0x7a,0xac,0x3e,0x31,0x59,0x6c,0x9e,0x3b,0x09,0xb0,0x80,0x7f,0x05,0x6b,0x6a,0xc0,0xc4,0xfb,0x24,0x71,0x49,0xa2,0xdd,0x7c,0x88,0xb9,0x21 +.byte 0xcb,0xc0,0x86,0xf0,0x49,0xbd,0x46,0x06,0xbd,0x5d,0xd1,0x4c,0x64,0x9c,0x99,0x33,0x36,0xf3,0x23,0x74,0x85,0x75,0xc2,0xba,0x20,0x5f,0x20,0xbd,0x75,0x4f,0x83,0x28,0xae,0x91,0x68,0xb2,0xf2,0xc3,0x0f,0xd3,0xf8,0xaa,0x3b,0x42,0xfa,0x79,0xfb,0x7d,0x19,0xa5,0xbb,0x51,0xc1,0x91,0x5b,0x38,0xac,0x8c,0xd9,0x0f,0xe3,0x35,0x60,0xff +.byte 0x3d,0xa6,0x28,0x43,0x5d,0x7d,0xfe,0xb5,0xae,0xf3,0x47,0xc5,0xfa,0xe4,0x16,0x4b,0xb9,0xd2,0x51,0x39,0x9f,0x44,0xd8,0x50,0x70,0xab,0xe3,0xab,0xa8,0x63,0x31,0xe4,0xd3,0xeb,0x60,0x25,0x1d,0x67,0x8f,0x33,0x34,0xef,0x07,0xd4,0x92,0xce,0xbf,0x33,0xa8,0x3c,0x62,0x9a,0x09,0x22,0x42,0x12,0xba,0x80,0xb1,0x5b,0x98,0xec,0xbd,0x1b +.byte 0x84,0x3f,0x52,0x4f,0xc8,0x9f,0x85,0xc9,0x03,0x4e,0x34,0xa9,0x62,0xe6,0x0d,0x81,0x0e,0x01,0x14,0x3b,0x8b,0x3e,0x4f,0xf0,0xca,0xb5,0xbb,0x6d,0x0f,0x2c,0x43,0xb9,0x84,0x03,0x5a,0xee,0x5b,0x63,0xac,0xb9,0x55,0x96,0x3c,0x53,0xc4,0xd5,0xe6,0xe0,0xd4,0x51,0x1e,0x3c,0x86,0x92,0x9f,0x86,0xa4,0x74,0xd7,0x8e,0x6d,0x23,0x71,0xcf +.byte 0xaf,0xfe,0xf2,0x39,0x7b,0x41,0x9e,0x7e,0x1f,0x91,0xeb,0x7c,0xd0,0x18,0x67,0x7d,0xaf,0x24,0x87,0x40,0xab,0x0a,0x08,0xcc,0x00,0xee,0x3a,0xdc,0x02,0x70,0x94,0x74,0xdb,0x27,0x72,0xcd,0xff,0xf1,0x03,0xcf,0x00,0xc9,0x9b,0x56,0x3b,0x40,0x65,0xd5,0x80,0x9a,0xa7,0x17,0xb2,0x50,0x79,0x41,0x0d,0xe2,0x22,0x93,0xaf,0x7e,0xab,0x1b +.byte 0xa0,0x61,0x27,0x8a,0x67,0xae,0x56,0x96,0xd2,0x0d,0x49,0x02,0xe3,0x6b,0x13,0xe8,0x7d,0x53,0xd3,0x5a,0x19,0x68,0x07,0x1e,0x5c,0xaf,0x5e,0xa2,0x2f,0x14,0xbe,0xbd,0xa5,0x8d,0x90,0xf4,0x7a,0x86,0x06,0x03,0x68,0x82,0xb1,0xd3,0x69,0x7f,0xd1,0x23,0x24,0xf9,0xfa,0xde,0xfa,0x08,0x98,0x0b,0x23,0xf1,0xf7,0xdb,0xe0,0x58,0x6c,0xb7 +.byte 0xb1,0x5e,0x98,0xe6,0x15,0xc9,0xaf,0x86,0x64,0x95,0xab,0xb3,0x7e,0x07,0xd1,0x10,0x71,0x21,0xcc,0xef,0x27,0xc1,0x96,0xe5,0xf1,0xa8,0x35,0x57,0x10,0xe3,0xd4,0x1a,0x32,0x56,0x5e,0x1e,0xb3,0xdd,0xa5,0xe9,0x80,0x4d,0x84,0x43,0x04,0xf0,0x71,0xba,0xb6,0x2e,0xf3,0x5c,0x3d,0xbc,0xa9,0x50,0x24,0xc3,0xdf,0x5d,0xb4,0x2c,0x20,0x60 +.byte 0x10,0x1a,0x6e,0x44,0x0d,0x2b,0xa4,0x31,0xdc,0xd3,0x5d,0xa6,0x8d,0xde,0x48,0x99,0x0e,0xb4,0xc2,0x4a,0x1b,0x4f,0x45,0x54,0x9c,0x54,0x5b,0xd6,0x63,0xb2,0xb1,0x3a,0xa7,0x2a,0x42,0x70,0xfe,0xd8,0x33,0x1f,0x95,0xfc,0x26,0x82,0xc5,0x78,0x86,0xf5,0x93,0x07,0x31,0x31,0x74,0x5b,0x44,0xa4,0x5a,0xb2,0x8d,0xfc,0x38,0x99,0xde,0xbd +.byte 0xcd,0x26,0xe6,0xdf,0xd1,0x26,0x4e,0x9d,0x73,0xe7,0xa0,0x4e,0x31,0x3d,0x3e,0xea,0x4d,0xb9,0xc1,0x37,0xe3,0xba,0x32,0xd9,0xfd,0x3b,0x94,0x12,0xb0,0x84,0xd3,0xd9,0x73,0xe7,0xc3,0xc6,0xc4,0x2c,0xa2,0x21,0xeb,0xe7,0xd9,0xe5,0x53,0xe9,0xe7,0x4c,0x04,0xab,0xc4,0x70,0xd4,0xd4,0x11,0xba,0x18,0xf6,0xb4,0xcb,0xab,0xa0,0x6c,0x3f +.byte 0x9c,0x03,0xe8,0x97,0x68,0x22,0xa1,0x55,0xe8,0x3d,0x8d,0x44,0x5f,0x10,0x1e,0x57,0x9c,0xb1,0xca,0xf2,0xc7,0xce,0xea,0xe7,0x45,0x26,0xbc,0xd7,0x30,0x51,0x18,0xd7,0x70,0xa5,0xad,0xe4,0x7f,0x46,0xdd,0x8b,0xd8,0x0e,0x19,0x59,0x22,0xdc,0x89,0xd2,0xc4,0xbc,0x07,0xc1,0xab,0xaf,0x70,0xd5,0x55,0xe9,0x04,0x2c,0x28,0xd7,0x17,0xd7 +.byte 0xc1,0x6b,0x79,0x4d,0x7f,0x8c,0x14,0xd9,0x47,0x15,0x21,0xa5,0xac,0x55,0x52,0x3b,0xf5,0x64,0x50,0x0a,0x94,0x4d,0x1a,0x23,0xcf,0x29,0x53,0xaa,0x2d,0xf1,0xc2,0x1b,0x19,0xc6,0x46,0x5a,0xd0,0x9e,0x7a,0x01,0xb5,0xe8,0xc7,0x6f,0xee,0xbd,0x61,0x12,0x0b,0x25,0x13,0x94,0xee,0x35,0xc9,0x68,0xe3,0x6c,0x4c,0xcd,0xd9,0x81,0x63,0x8b +.byte 0x57,0x86,0xc7,0xb2,0x8a,0xfc,0xb0,0x19,0x8c,0x64,0x78,0x05,0x29,0xc6,0x00,0x4d,0xdd,0x4f,0x34,0x5e,0xc1,0xb1,0xa0,0x86,0xe3,0x13,0x65,0x5f,0xec,0x54,0xc0,0xe8,0xbb,0x6c,0xec,0x56,0x11,0x38,0x5b,0x7c,0x55,0x35,0x67,0xf1,0xae,0x86,0x93,0x69,0x59,0x7e,0x8c,0x84,0x8e,0x1d,0xdd,0x99,0x19,0x95,0xb0,0xd2,0x42,0xf2,0x0a,0x43 +.byte 0xb8,0x82,0x87,0x9e,0x6d,0x83,0x33,0xed,0x9f,0xef,0x10,0x8e,0x17,0x25,0x17,0xe9,0x84,0x56,0x16,0x55,0x28,0x07,0x40,0xf0,0xdc,0xff,0xc7,0x67,0x32,0xb9,0x32,0xe2,0xd5,0x20,0x82,0xee,0xfd,0x37,0xe8,0x54,0x8a,0xf7,0x76,0x42,0x78,0xde,0x53,0x4f,0xd5,0xfe,0x15,0x7a,0xf5,0xa6,0xe8,0x19,0x89,0xab,0x7f,0xc1,0x43,0xed,0xdd,0xa2 +.byte 0x53,0xc4,0xb5,0x0a,0x6c,0xa5,0x83,0x9d,0x09,0x55,0xde,0xbe,0xa5,0xc2,0x00,0x93,0x92,0x8e,0x6d,0xbb,0xfc,0x0c,0x80,0x1f,0x7c,0x16,0x77,0xf9,0xb1,0xde,0x82,0x0b,0xf9,0x98,0xbc,0x49,0x68,0x5f,0xcf,0xb0,0xde,0xe3,0xc9,0xa5,0x35,0xa6,0xe3,0x4a,0x61,0xa3,0x34,0x51,0x64,0x64,0x1a,0x05,0x51,0x87,0xfb,0x04,0xe5,0xcb,0x6b,0xa9 +.byte 0x04,0x4a,0xfe,0x19,0xcd,0xbd,0xad,0x9c,0x7e,0xe8,0x36,0x54,0x95,0xea,0x78,0x69,0xf5,0x3f,0xc5,0x11,0x42,0xc1,0x36,0xc3,0x72,0xe3,0xaa,0x15,0x30,0x40,0x73,0xae,0xc0,0x0f,0x3e,0xd8,0xe1,0xe6,0xb8,0xc6,0x81,0x79,0x72,0x2d,0xa2,0x1c,0x19,0x8a,0x31,0xcf,0x7a,0xfb,0x3b,0x51,0xee,0x25,0x50,0xea,0x43,0x0f,0xca,0x07,0xbc,0xde +.byte 0x3e,0x24,0xb1,0x57,0xb1,0xe2,0xc5,0xe3,0xc9,0x50,0x72,0x82,0xfc,0xf7,0xf6,0xfb,0x8c,0xd3,0x1a,0xa1,0xbb,0x71,0x40,0x71,0xf8,0xdc,0x14,0x8d,0x45,0xca,0x7b,0x5a,0xd7,0xfb,0x84,0x63,0xc3,0x60,0xf0,0xd1,0xca,0xdb,0x63,0xa2,0x74,0x75,0x42,0xaa,0x03,0x2b,0xc4,0xe8,0xc9,0xa8,0x95,0x8c,0x8f,0x06,0x6f,0x58,0x98,0x14,0x54,0xb4 +.byte 0x4d,0x2f,0x5e,0x67,0x57,0xbf,0xe5,0xdc,0x8e,0xb8,0x6b,0x8d,0xb6,0x92,0xad,0x45,0x6f,0xda,0xec,0x8c,0xbc,0x30,0xde,0xcf,0x07,0x90,0xef,0xfd,0x6a,0xb6,0x24,0x0a,0xcf,0x53,0x87,0x7d,0xf1,0x7a,0x75,0x6e,0x5b,0x35,0xc6,0x70,0x24,0x8f,0xac,0xcd,0x78,0xe3,0x2b,0xd8,0x6c,0x35,0x55,0x0e,0xb7,0xb6,0xe1,0x3a,0x1c,0x96,0x4d,0x11 +.byte 0x91,0x5c,0x40,0x87,0x02,0x91,0x12,0x6c,0x01,0x26,0x01,0xa7,0x9e,0x75,0xb7,0x22,0x31,0x81,0xa2,0x1e,0x6f,0xa1,0xd4,0x24,0x55,0xc9,0xc6,0x21,0xbc,0x94,0xe1,0xdd,0x6b,0xcf,0x27,0xfc,0xb0,0xd6,0xbd,0xa5,0x8d,0x7c,0xeb,0x04,0xcd,0x36,0x2b,0x09,0x6f,0x40,0x99,0x91,0x7b,0x30,0x4c,0x2b,0x84,0x62,0xeb,0xaf,0x0a,0x38,0xee,0x5d +.byte 0xeb,0xb8,0xe9,0xbf,0x24,0xc7,0x2f,0xde,0x4d,0x6f,0xaa,0x69,0xf6,0xae,0x01,0xb6,0x93,0x88,0x96,0xc4,0xaa,0x5b,0x80,0xfb,0xf1,0x08,0x93,0xbe,0x99,0x26,0x8b,0x27,0x56,0xd1,0x81,0x66,0x90,0x04,0x9f,0x09,0xda,0x93,0x22,0x65,0x98,0x4f,0x89,0x3b,0x2e,0xe1,0xbc,0x05,0x38,0xfe,0xb6,0xed,0xdd,0x48,0xa7,0x12,0x07,0x55,0x0c,0x1f +.byte 0xd1,0x45,0x03,0x06,0x72,0x2a,0xa6,0xb3,0x56,0x66,0x8b,0x4e,0x7d,0x72,0xe4,0x35,0xcf,0x83,0x12,0x99,0xe0,0x28,0x69,0xc5,0x1e,0x58,0xc0,0x94,0x58,0xa5,0xae,0x6e,0xfe,0x9e,0x05,0xca,0xae,0xfa,0x91,0x48,0x86,0x93,0x46,0x2f,0xe4,0x7c,0xac,0x16,0xb5,0xd2,0xbe,0xd9,0xf8,0x96,0x3b,0x57,0xfc,0x0b,0xd2,0x5c,0x50,0x0a,0xb2,0xcd +.byte 0xc9,0xcf,0x0c,0xca,0x9a,0x84,0xf2,0x2a,0xa8,0xe1,0x3d,0xab,0xc8,0x36,0x8f,0x8a,0x81,0x9b,0x52,0xd5,0x3b,0x1c,0x64,0xf2,0x74,0xc5,0x31,0x39,0xe1,0x84,0x7a,0xd0,0xd2,0xbe,0xb8,0x04,0x53,0x03,0x18,0xe6,0xa8,0x17,0x62,0xb5,0x8d,0x54,0xfc,0xd8,0x55,0x68,0x4a,0x8f,0x8e,0xf0,0x8b,0x17,0xce,0x83,0x8a,0xf4,0xb7,0x93,0xc9,0x95 +.byte 0xdd,0xdf,0x7b,0x78,0x5f,0x6b,0x32,0x5e,0xcd,0xbd,0x44,0x8a,0x1f,0xfc,0x97,0xff,0x15,0xca,0x6b,0x2a,0x84,0x89,0x4c,0x6e,0x8a,0x45,0x53,0x81,0xc3,0x51,0x61,0x7e,0xb8,0x57,0xb7,0x2a,0x5d,0xc1,0xe6,0x2f,0x5e,0x7b,0xb5,0xc2,0x15,0x25,0xa3,0xe4,0x3a,0x85,0x59,0x43,0x4e,0x38,0x0b,0xeb,0x4d,0x61,0x62,0xd2,0xe8,0x06,0x54,0x45 +.byte 0xeb,0x43,0xe7,0x22,0x61,0x27,0x85,0xdf,0x8c,0x19,0xd6,0xb8,0x52,0xa1,0xd4,0x34,0x52,0x3e,0xa5,0xf8,0x6c,0x3c,0xc3,0x53,0xec,0x77,0x80,0x53,0x1a,0xea,0x3b,0x00,0xfa,0xac,0x4c,0xfb,0x03,0xf0,0x03,0xcc,0x4d,0xfd,0x02,0x96,0x68,0x9e,0xab,0x8e,0xb0,0x9f,0x9f,0x0b,0x3d,0x27,0x21,0xd5,0x5a,0x5f,0x40,0x14,0xf2,0x21,0x2f,0x9d +.byte 0x1d,0x4b,0x48,0xec,0x59,0x68,0x9b,0x26,0xc6,0xab,0x10,0xd6,0xf6,0x83,0x5d,0x0d,0xf4,0x91,0xb4,0x3b,0x83,0xce,0xbf,0x84,0x4c,0xc1,0x0c,0x75,0x45,0x32,0xec,0xb8,0x82,0x17,0xc7,0x43,0x18,0x78,0x16,0x98,0x0b,0xdb,0xfa,0x3d,0x83,0x2a,0xa8,0x2e,0xad,0x9d,0x39,0x63,0xbf,0xc0,0xbb,0xc6,0x4c,0x81,0x60,0xe6,0x58,0xbe,0xc0,0x85 +.byte 0x77,0x68,0xb5,0xfe,0xd8,0x0d,0xd8,0xc2,0x92,0x49,0x76,0x74,0x91,0x62,0x1c,0x20,0xc1,0x93,0x3c,0x4b,0xdb,0x9e,0x5a,0x97,0x6b,0xc8,0xb6,0x4f,0x3f,0x3c,0x2a,0xe8,0xeb,0x0b,0x1f,0x05,0x04,0xb4,0xbf,0xac,0x2a,0xc5,0x04,0xf2,0xda,0xfb,0xba,0x08,0x9e,0xf6,0x78,0xd9,0xb1,0xde,0xce,0xfa,0x7d,0x8e,0x22,0x83,0x23,0x5b,0x2a,0x35 +.byte 0x62,0x2f,0x15,0x6f,0x4a,0x44,0x06,0x11,0xde,0xd4,0xea,0xb4,0x05,0xd0,0xd4,0x7f,0x3a,0x20,0x6e,0x01,0xa6,0x79,0xd6,0x67,0x19,0xec,0x76,0xfd,0xaa,0x00,0x28,0x6b,0xf3,0xef,0xdd,0xef,0xec,0xf4,0x99,0xc2,0x25,0xf8,0x3c,0x18,0xcf,0x65,0xf0,0xd3,0x30,0xd3,0xeb,0xc7,0x4c,0xa1,0x3e,0x3d,0xa4,0xe7,0x20,0x78,0xe0,0xbe,0x9f,0x48 +.byte 0xbb,0x51,0x30,0x62,0x16,0xe9,0x3a,0x4d,0x5c,0x6e,0xa5,0x4f,0xa8,0x77,0x92,0xd7,0x87,0x4e,0xf9,0xb9,0x43,0xeb,0x4e,0xd2,0x2f,0xc0,0x29,0x22,0xfe,0x37,0xc4,0x58,0x36,0x71,0x1c,0x18,0x05,0x44,0xd2,0x24,0x01,0x25,0x65,0x1b,0xc7,0xfd,0xd4,0xef,0x15,0xeb,0x91,0x06,0x26,0x74,0x2e,0x28,0xb2,0x46,0xb5,0xb5,0xaf,0xeb,0xaa,0x9a +.byte 0xc8,0x9a,0xd0,0x34,0xb9,0xf4,0xce,0x6e,0x7a,0xca,0x63,0xf0,0x46,0xad,0xfb,0x53,0xa8,0x2b,0xc4,0x2f,0xed,0x7c,0xab,0x63,0x1c,0xb6,0xfe,0xb7,0x53,0x53,0x3f,0x5a,0x5f,0x45,0xd9,0x50,0x79,0x43,0xa3,0x56,0x0a,0x9e,0x6e,0x22,0xf5,0x85,0x6f,0xe9,0x81,0x94,0xa6,0xc5,0x0d,0x8b,0xef,0x3e,0x0f,0x68,0xbf,0x20,0x86,0x0d,0xd8,0x32 +.byte 0xde,0xab,0xf0,0x0b,0x96,0xce,0xc2,0xad,0x8d,0xe1,0x3b,0x37,0xd1,0x06,0xec,0x38,0xec,0x42,0x06,0x3a,0xb1,0xc6,0xb8,0xc0,0xc5,0xea,0x8f,0xcb,0x5f,0xf0,0x15,0x1f,0x77,0x37,0x46,0x10,0xfb,0xc3,0x55,0x7d,0x53,0x41,0xb9,0xb6,0x31,0xe6,0xab,0x0d,0xeb,0x45,0xfe,0x45,0x65,0x46,0xa9,0xbc,0xd9,0xcd,0x3f,0x26,0xce,0x32,0xd2,0x0d +.byte 0x7b,0x8f,0xfd,0x6f,0x70,0x33,0x98,0xab,0x3e,0xdb,0x16,0x24,0x63,0x96,0x55,0x04,0x3e,0xb1,0x06,0x1b,0xf3,0xca,0x9e,0xb2,0x47,0x42,0x51,0x5c,0xdc,0xff,0x40,0x72,0x45,0x09,0xdf,0xeb,0x50,0x57,0xf5,0xcb,0xe8,0xb6,0x0c,0xe3,0x13,0xb1,0xdf,0x0e,0x40,0x90,0x6d,0x51,0xee,0xc7,0x0e,0x6e,0xa7,0x67,0xcd,0x59,0xef,0x09,0x3c,0x9c +.byte 0x81,0x66,0xf7,0xfb,0x4a,0x14,0x08,0x14,0xc4,0x72,0x79,0x55,0xaa,0x99,0xa5,0xe1,0xfe,0x12,0xf7,0x07,0x05,0x27,0xc7,0xf8,0x18,0xaa,0xf8,0x20,0xac,0xc7,0x23,0x28,0x58,0x38,0xc4,0x1d,0x88,0x8d,0x5a,0x33,0xa1,0x04,0xaa,0xb4,0x7e,0x9c,0xe5,0x60,0x25,0xb1,0xa4,0x75,0x61,0xba,0xa7,0xf5,0x9e,0x2a,0xc4,0x26,0x28,0x7f,0xb0,0x56 +.byte 0xaa,0x0a,0x6a,0xd8,0xab,0xfb,0x7a,0x30,0x3c,0x26,0xa9,0x38,0x21,0x9d,0x7d,0x3c,0xef,0x81,0xbf,0x50,0x5c,0x7e,0x1e,0x4a,0xa6,0xec,0x16,0x6b,0xac,0x74,0xf8,0xdb,0x8b,0x1b,0xa6,0xd8,0x48,0xc9,0x25,0x3e,0xa0,0x7b,0x39,0x52,0x17,0x17,0xc2,0xf3,0xc6,0xfa,0xcb,0x4d,0xdf,0xdc,0xf9,0x37,0x00,0x08,0xb6,0x5f,0x12,0x81,0xed,0x6e +.byte 0xc5,0x22,0xb3,0xcd,0x57,0x81,0xf7,0x72,0x32,0x9a,0x1c,0x5b,0x96,0xd5,0xb2,0x65,0x6a,0xbc,0x8a,0x6d,0xa4,0xe0,0x54,0x65,0x7e,0x82,0xce,0xa3,0xd9,0x59,0xb8,0x46,0xff,0x18,0x83,0xb0,0x40,0x17,0x84,0x39,0xea,0x32,0xaa,0x52,0xd7,0xb9,0xc1,0x92,0xe5,0xaf,0x42,0x7d,0xde,0xc7,0x71,0xa2,0x0e,0x02,0x04,0x7c,0x92,0x91,0x6e,0xbb +.byte 0x91,0xc7,0x38,0x36,0xe6,0xef,0x2f,0x87,0x73,0xe8,0xce,0x04,0x58,0xe4,0xc7,0x0f,0xfb,0x69,0x77,0xf6,0x01,0x41,0x13,0x1d,0xc9,0x59,0x7a,0xf3,0xc2,0x20,0xf7,0xd8,0xfd,0xd9,0xe7,0xd1,0x14,0xe1,0xf1,0x1a,0x35,0x1f,0x8e,0x3f,0x78,0x1e,0xe2,0x01,0x92,0x07,0x3f,0xf4,0x73,0x4f,0x36,0x48,0xb3,0x4c,0x51,0xbe,0xea,0x24,0x20,0x7d +.byte 0xaa,0x54,0xe0,0xea,0xf7,0xde,0xaa,0x43,0xa1,0x22,0x85,0xd4,0xf7,0x50,0x47,0x68,0xe9,0x92,0x41,0x84,0xe4,0xa9,0x1f,0x96,0x43,0xb5,0x3b,0x8b,0x23,0xdd,0x2f,0xd1,0xcc,0x5e,0xcb,0xf5,0x77,0xd8,0xc9,0xc0,0xfe,0x1e,0x6c,0xac,0xb3,0x6f,0xc1,0x6c,0x5a,0x33,0x35,0x7b,0x09,0xe7,0x4b,0x2e,0xbf,0x9f,0xb1,0x68,0x56,0xb5,0x17,0x2d +.byte 0x77,0xc6,0x76,0xbc,0x47,0xf4,0x41,0x3f,0x35,0xb3,0x41,0xff,0xb8,0xc6,0xe2,0x1e,0xfc,0x2f,0x3f,0x26,0x30,0x10,0xb9,0x37,0x8e,0xa9,0x59,0xff,0x7f,0x74,0x3d,0x99,0x0c,0x65,0x62,0xa4,0xc9,0xed,0xaf,0x72,0xb4,0x7a,0x17,0xab,0xbb,0x33,0xda,0x24,0xde,0x97,0xfb,0xa8,0x9d,0x10,0x6c,0x1e,0x9a,0x13,0xec,0x7e,0xb8,0xa5,0xe6,0x0d +.byte 0x92,0x96,0xbe,0x91,0x8c,0x69,0x07,0x78,0xe0,0x02,0x7e,0x97,0x61,0x2f,0xf8,0x0f,0x17,0x3d,0x7d,0x09,0x13,0xb9,0x1c,0xcf,0xd0,0x9e,0x85,0x35,0x3c,0xa3,0x06,0x82,0xb2,0xb2,0x1c,0x09,0xe3,0x91,0x43,0x13,0xff,0x9d,0xa7,0x05,0xd7,0x69,0x4a,0xe1,0xa7,0x1a,0xaa,0x57,0x1f,0xcf,0xcb,0x43,0xac,0x40,0x34,0xd2,0xb8,0xff,0xf8,0x0f +.byte 0x82,0xf7,0xa8,0x9d,0x5f,0x5f,0xb9,0xf9,0x78,0x89,0xe4,0x65,0xa8,0x54,0x5f,0x47,0xb4,0x53,0xe4,0x73,0x2a,0x29,0xe0,0xa0,0x70,0x79,0x22,0x51,0x3a,0x5a,0xc6,0x42,0x8c,0x74,0xdc,0xf7,0x85,0xce,0x1f,0x2a,0x1b,0x4d,0x83,0xcb,0xd2,0xce,0x5a,0x4f,0xde,0x18,0x48,0x64,0x4c,0xe8,0x17,0xb2,0x55,0xfe,0x6c,0x5f,0x31,0xa7,0x03,0x4a +.byte 0xae,0x8f,0x40,0x47,0x7e,0x92,0xa2,0x19,0x7c,0x53,0x32,0xaa,0x8c,0xc2,0x06,0x79,0xc3,0xc7,0x45,0x02,0x77,0x23,0x12,0x37,0x2b,0x8e,0x84,0xf5,0x8b,0x1a,0x4c,0xd3,0x10,0x0e,0xba,0x33,0x8f,0x2e,0x02,0x21,0x63,0xa8,0x3f,0x02,0x6e,0x42,0x49,0x0a,0x5a,0xf4,0xf0,0xe8,0xed,0x53,0x1f,0x99,0x73,0x65,0x88,0xe3,0xfc,0x60,0x34,0x4e +.byte 0x91,0xa5,0x0c,0xbe,0x1d,0xbb,0x95,0x57,0xff,0x7a,0xa1,0xec,0x34,0xe7,0xb6,0x63,0x8d,0xb2,0x3a,0x01,0xa3,0x31,0x50,0xaa,0x8a,0xef,0x97,0x9d,0xe5,0xd7,0xf9,0x8e,0xc1,0x5d,0xcb,0xd3,0x8d,0xc1,0x3e,0x05,0x95,0xfc,0x63,0x14,0xe4,0x44,0x58,0xee,0x3d,0x30,0x04,0x80,0x0c,0x63,0x1d,0x14,0xd2,0xc3,0xc1,0xe1,0x67,0x51,0x64,0x8a +.byte 0x23,0xaf,0x31,0x05,0x46,0x4f,0xf7,0x88,0x80,0xcb,0xba,0x47,0x31,0x40,0x3f,0xa0,0xfb,0xe7,0x8e,0x34,0xc1,0xe4,0x69,0xbd,0xb1,0x07,0x2b,0x55,0x27,0x0d,0x04,0xe8,0x74,0x93,0x04,0x15,0x62,0x1f,0x9a,0x66,0xe9,0x8d,0xa1,0xd6,0xc1,0x50,0xd8,0x8e,0x6a,0xe3,0x7c,0x9a,0xb7,0xa0,0x6f,0xf6,0xee,0x2e,0x03,0x67,0x1c,0x06,0x08,0x92 +.byte 0x83,0xf5,0x4f,0xa1,0xf7,0x23,0x01,0x1a,0xf8,0xda,0x80,0xca,0xce,0x2a,0x01,0x59,0xee,0xeb,0xbe,0xc4,0x95,0xf2,0xfd,0x7e,0x15,0xb6,0xbe,0x69,0x6b,0x4b,0x33,0x5b,0x83,0x89,0x1a,0x29,0xac,0x23,0x31,0x29,0xd8,0x29,0xea,0x87,0xf3,0x12,0x40,0x4b,0xcc,0xb6,0x07,0x0d,0xbf,0xf4,0x72,0x52,0x74,0x95,0xc9,0x15,0x0a,0x09,0x93,0xdf +.byte 0xd6,0x7e,0x4a,0x3c,0xd0,0xf6,0xfc,0xcf,0x75,0x7e,0x65,0x4e,0x5a,0x49,0x72,0xbd,0x46,0xbe,0x5e,0x26,0xc5,0x09,0xdb,0xea,0x5c,0x44,0xcc,0xaf,0x92,0x54,0x58,0x6b,0x5f,0xa8,0xf3,0xe6,0xed,0xb0,0x41,0x1c,0xb1,0x9b,0x1d,0x8b,0x3a,0x27,0x31,0x50,0xf0,0x76,0xaf,0xbf,0xd7,0x40,0x4f,0x23,0x59,0xcb,0x4e,0xa9,0x12,0xd9,0x16,0x5e +.byte 0x8d,0x70,0xb0,0x36,0xd7,0xf6,0xde,0xa0,0x62,0x4b,0x8b,0xea,0xf1,0x7c,0x82,0x05,0x80,0x17,0x8d,0x14,0xf3,0xb4,0x9a,0x42,0xa1,0xa2,0x64,0x28,0xf8,0x38,0x0e,0x8e,0xb6,0x0e,0xb9,0x6e,0xfa,0x77,0xf3,0xec,0x28,0x6f,0x56,0x93,0x13,0x1c,0x5e,0x01,0x31,0x8d,0x65,0x46,0xc9,0xff,0x46,0x5e,0xc3,0xbf,0x75,0x45,0x19,0xb4,0x8e,0x8e +.byte 0xf1,0x90,0xda,0x83,0x57,0x6c,0x30,0x49,0xf2,0x67,0x64,0x0a,0xf5,0xb5,0x51,0xac,0x91,0xa0,0x5a,0x9f,0x19,0xbd,0x02,0xb2,0x0d,0x5d,0x1f,0xbe,0xc2,0x76,0xf1,0xcb,0x59,0xf8,0xd1,0x90,0x67,0x17,0xda,0xd1,0xd8,0x9f,0x33,0x00,0x61,0x5d,0xd7,0x90,0xd6,0xd6,0xcd,0x16,0xf7,0x35,0xef,0xcb,0x2f,0xbb,0xc0,0x9e,0x2a,0xc8,0xf6,0x03 +.byte 0x7a,0x1d,0x4c,0xac,0xde,0xf1,0x25,0x9a,0x3e,0xb1,0xae,0xbb,0x59,0xab,0xe7,0x81,0xa5,0x3f,0x42,0x07,0x4f,0x66,0x8f,0x7c,0x93,0xf6,0xab,0x44,0x2e,0x9a,0x68,0x95,0x16,0xc8,0x59,0x5b,0x0e,0x00,0xdc,0xc8,0x2a,0x97,0x20,0xca,0xdf,0xb1,0x6c,0x1f,0x64,0xe4,0xed,0xd3,0xae,0xea,0x47,0x2a,0xfd,0x52,0x30,0x13,0x05,0xe6,0xc7,0xc6 +.byte 0xca,0xde,0xec,0xe3,0xe2,0x58,0x99,0xbf,0xaa,0xff,0x64,0xfc,0xda,0x55,0x3c,0x29,0x00,0xc6,0x60,0xde,0x33,0xbe,0xec,0xe0,0x14,0x2c,0xb6,0x30,0x9f,0xec,0x46,0x11,0x9a,0x36,0x64,0xab,0x2c,0xcb,0x39,0xe9,0x87,0x6a,0x73,0xe4,0xe8,0x6b,0x81,0x1b,0x61,0xc1,0x1a,0xbe,0x1e,0x66,0x76,0x6b,0xaf,0xab,0xb0,0xaf,0x59,0xa9,0xb9,0x54 +.byte 0x84,0xe0,0xca,0x10,0x5e,0xe1,0xc1,0x9d,0xed,0x23,0x5b,0xeb,0xa6,0x9f,0x7a,0x0c,0x94,0x97,0x21,0xf4,0xee,0xec,0x69,0x47,0x05,0xfc,0x21,0xbf,0x79,0x47,0x63,0x4e,0x78,0x99,0x07,0xf0,0x53,0xbc,0x3a,0xc3,0xcd,0x36,0xdf,0x33,0x7b,0xa0,0x91,0x39,0xdd,0x7f,0x49,0xaa,0xde,0xdd,0xa2,0x93,0x8f,0x36,0xca,0xaa,0xad,0xd2,0x3d,0xd1 +.byte 0x1a,0xdb,0x7e,0x97,0xce,0xe7,0xb3,0xda,0x3e,0x25,0x0d,0xc7,0x0d,0xdb,0x54,0x93,0x20,0xf1,0x10,0xdd,0xb5,0xc9,0x75,0x67,0x61,0xa3,0x24,0x41,0x42,0xb9,0x67,0x03,0x0c,0x52,0xe4,0xf1,0x68,0x07,0x90,0x7a,0xf9,0xe9,0x33,0x19,0x0e,0x11,0xb3,0xda,0xe8,0x5a,0x84,0xf3,0x41,0x77,0x43,0x6c,0xea,0x98,0x23,0xd8,0xae,0xf6,0xdd,0x5a +.byte 0xc7,0x4f,0xf4,0x06,0x80,0xd9,0x84,0x90,0x27,0xf5,0x0e,0x85,0x44,0xa8,0x2f,0x03,0x02,0xca,0xa6,0x8f,0x44,0x7a,0x3c,0xb8,0x2f,0x32,0xab,0x9d,0xd7,0xde,0xee,0x1c,0x33,0x91,0x95,0x96,0x66,0xb2,0x03,0xb3,0x95,0x8d,0x45,0x41,0xd3,0xb9,0x19,0xf1,0x93,0xc7,0xe8,0xce,0x16,0x8b,0x69,0xe0,0xdb,0x6b,0x2d,0x44,0xe3,0xff,0x92,0x8f +.byte 0x16,0x97,0x3e,0xc1,0x4d,0xc3,0x0b,0x5a,0xff,0x6e,0xe2,0x83,0x91,0x13,0xe5,0xc2,0xac,0x4a,0x97,0x81,0xd0,0x37,0x83,0x10,0x78,0xce,0xd9,0xed,0xe7,0x7f,0x74,0x23,0x22,0x42,0x72,0x12,0x50,0xf2,0xef,0x04,0xf5,0xf1,0x86,0xdd,0x7d,0x5c,0xea,0x81,0x7c,0xfb,0x66,0x2b,0x7e,0xfa,0x84,0xa7,0x4c,0x42,0x08,0x2d,0xa4,0x92,0xc5,0x21 +.byte 0xf3,0x1d,0x22,0x76,0x09,0x3f,0xba,0x1a,0x3d,0xaf,0x3d,0xae,0x33,0x8f,0xd7,0x52,0x18,0x7c,0x9e,0xcf,0x39,0xb1,0x84,0x0b,0xc6,0x26,0xc0,0x5b,0x6e,0xd2,0xae,0x6b,0xa4,0xe9,0x6f,0x74,0x51,0x47,0x17,0x1b,0x6e,0xdf,0xd0,0x6c,0xce,0x46,0x3f,0xda,0x9d,0xda,0xa3,0xdd,0x50,0x0d,0x94,0xa2,0x82,0x16,0x6b,0x1d,0x9e,0x39,0x69,0x96 +.byte 0x40,0x42,0x87,0xba,0xb6,0xae,0xe5,0x0c,0xee,0x9f,0xf5,0x8a,0x66,0x94,0x68,0x40,0xd3,0x76,0xea,0x27,0x5f,0xf8,0xe2,0x6e,0xb6,0xb2,0xf2,0xb6,0x46,0x9c,0xef,0x18,0xb4,0xd9,0x7f,0xa8,0x86,0xae,0xb1,0xd3,0xe9,0xc5,0xa9,0x18,0x36,0xdf,0x26,0x19,0x5e,0xa6,0x29,0x3a,0xc0,0x4c,0x1b,0x58,0x2d,0xc1,0x33,0xc7,0x06,0x4f,0x14,0x42 +.byte 0x17,0x2c,0x62,0x81,0x7e,0x76,0xd6,0xfc,0xa4,0x8e,0xeb,0x56,0x8f,0xac,0x57,0xa1,0x73,0xb2,0x53,0x18,0xa8,0x06,0x9a,0x20,0x33,0x8a,0xe8,0x40,0x68,0x45,0x31,0xc3,0xb8,0xc0,0xd8,0xf4,0x2e,0x11,0xd3,0xf3,0x7d,0xc7,0x45,0x2f,0x58,0xb7,0xce,0x52,0x9d,0x87,0x1a,0x45,0x1e,0x0b,0x17,0x55,0xb7,0x74,0xec,0x2c,0xb4,0xac,0x83,0xc9 +.byte 0xff,0x77,0xbd,0x39,0x99,0xce,0x12,0x44,0x80,0x84,0xcd,0x56,0x23,0x24,0x8a,0x77,0x45,0xd9,0x7c,0xdb,0x23,0xa4,0x72,0xd0,0xbf,0x4d,0x5e,0x37,0x21,0xe3,0xd4,0x48,0x2b,0xb9,0x73,0x49,0x82,0xa1,0x54,0x61,0x5d,0x8b,0xae,0x14,0x89,0x20,0x62,0x43,0x6d,0x16,0x34,0x9a,0x0e,0x73,0xf0,0x29,0x3c,0xa2,0xcb,0x66,0x15,0xcc,0xb4,0x49 +.byte 0xde,0x22,0x93,0xde,0xce,0x84,0x9c,0x19,0xda,0x16,0x62,0x62,0xca,0xae,0x71,0xde,0x36,0x7d,0x3f,0x9f,0x9a,0x51,0x2b,0x18,0x91,0xa3,0xf9,0x47,0x7f,0x8f,0x45,0x9a,0x12,0xe0,0xdb,0x20,0xa5,0x44,0x52,0x99,0x36,0xac,0xe9,0x1c,0x61,0x5e,0xd6,0x51,0xc1,0xbb,0x2b,0x75,0xd6,0x28,0xab,0x22,0x11,0x40,0x24,0x77,0x56,0x8d,0x62,0x8c +.byte 0x41,0x17,0x06,0x4d,0x2f,0x8b,0x0d,0x6c,0x44,0x00,0x62,0xee,0xfd,0x4b,0x61,0xb3,0xe6,0x40,0xa3,0x54,0x51,0x67,0x26,0x18,0x06,0x4f,0xd4,0x4b,0x73,0xbf,0xee,0x53,0x50,0x7a,0x6e,0xc2,0x42,0x7f,0x78,0x34,0xd6,0xcb,0xdf,0x49,0xe0,0x8e,0xef,0xd6,0x3c,0x19,0x77,0x8a,0xcd,0x48,0xdf,0x71,0x07,0x0e,0xf0,0xe8,0x09,0x91,0xe7,0xaf +.byte 0x2f,0xf7,0x17,0xb5,0x9e,0x3f,0xe1,0x37,0xbf,0xb1,0xa2,0x89,0xd2,0x08,0x9d,0x67,0xb2,0x1e,0xe6,0x18,0xc0,0xfc,0x91,0xdc,0x79,0x32,0x13,0x32,0xf4,0x07,0x1b,0xf9,0x7e,0x2c,0xa5,0xf8,0xbe,0x57,0xce,0xfd,0x84,0xdc,0x85,0x6c,0x42,0x32,0x20,0x6a,0x91,0xbd,0xba,0xf9,0x83,0x0a,0x53,0x0a,0x3e,0x58,0x36,0x80,0x1f,0xde,0x8b,0xee +.byte 0x95,0x2a,0x74,0xbb,0x6e,0x06,0x28,0x40,0xb3,0x3d,0xf5,0x1c,0x65,0x0d,0xf7,0xcc,0x5e,0x1a,0x01,0xfe,0xb2,0x39,0x92,0x49,0x32,0xad,0x5a,0x9a,0xbb,0x06,0x48,0x7b,0xb0,0x4f,0x16,0x10,0xf7,0x46,0x98,0xe5,0xe7,0xdc,0xf8,0x3c,0x3d,0xa6,0x96,0x4f,0x25,0x2e,0xa7,0x99,0x5a,0xe9,0x17,0x35,0x48,0x56,0x48,0x5d,0xea,0x3c,0x4f,0x9a +.byte 0x7a,0x0c,0x28,0xaf,0x64,0x56,0xb0,0x4a,0x34,0xa1,0xfc,0xef,0xb8,0x50,0xe5,0x71,0x3f,0x8d,0xda,0x3c,0x75,0xb8,0x22,0x8a,0x89,0x36,0xd5,0xea,0x2f,0xfd,0xfb,0xf3,0x94,0xf2,0xed,0xbc,0xde,0xee,0x6d,0xc0,0x65,0x47,0x8a,0x11,0x52,0xaf,0xf4,0xf0,0x89,0x4d,0x68,0xa5,0x90,0x6d,0x30,0x46,0x0d,0xc6,0x38,0x19,0xe2,0x2a,0x62,0xe9 +.byte 0xb3,0x68,0x9a,0x26,0x4b,0x01,0x83,0xbb,0x9d,0x6c,0x23,0x38,0xee,0xe1,0x72,0x60,0xb5,0x30,0xda,0x27,0xd6,0x12,0xe0,0xe4,0x65,0x01,0xc5,0x4b,0xc6,0xbf,0xee,0xe9,0x47,0xf4,0xa7,0x64,0xec,0x61,0x34,0xa9,0xda,0x16,0xa0,0xcc,0x0d,0xdc,0xa4,0xe8,0x8f,0xdc,0xcb,0x4e,0xe7,0xc9,0x7f,0x29,0xc4,0x89,0xbb,0xc2,0x83,0xc8,0x3e,0x28 +.byte 0x02,0x73,0x7e,0x63,0x9c,0x88,0xc6,0x35,0x51,0x54,0x17,0xed,0x81,0xbb,0x3a,0x29,0x07,0xe4,0xa6,0xa3,0x28,0x28,0x65,0x40,0x9d,0x86,0xad,0x02,0x7e,0x8b,0x26,0x54,0x32,0x79,0x38,0x24,0xef,0x4a,0xfc,0xaf,0xc0,0x6b,0xd2,0x11,0x86,0x40,0x54,0xe8,0x56,0x9c,0xd8,0xc4,0xab,0xab,0x86,0xd4,0x2d,0xef,0x58,0x22,0x10,0xe0,0xb3,0x89 +.byte 0xb7,0x44,0x35,0x5f,0x7f,0x6f,0xd3,0x11,0x66,0x75,0xd5,0x45,0x95,0x93,0x8c,0x05,0x32,0x97,0xad,0x92,0xe3,0xef,0x03,0xb0,0xae,0x28,0x00,0xca,0xac,0x4b,0x36,0xa5,0xa5,0x4a,0x70,0x69,0xe6,0xeb,0x61,0xfc,0xb8,0xc8,0xca,0x88,0x13,0x50,0x14,0xf6,0x5a,0x86,0x41,0x1d,0x84,0xd4,0x59,0x8c,0xae,0xbc,0x68,0xc0,0x33,0x4b,0x13,0x28 +.byte 0x89,0xb2,0x63,0x2d,0x85,0xc8,0x33,0x15,0x2e,0x9f,0xeb,0x3b,0xf8,0x26,0xd2,0x79,0x42,0xa9,0x70,0xb7,0x52,0x00,0xdf,0x1a,0x36,0xae,0x85,0x3b,0xf5,0x73,0x80,0xc1,0x7c,0xb4,0x7e,0xbf,0x6b,0xde,0xa1,0xc2,0x9f,0x85,0x86,0x3f,0xff,0x55,0x2d,0x4a,0x6f,0x2d,0x25,0x3c,0x01,0x54,0x92,0x3f,0x63,0x68,0x61,0x4a,0x8c,0xcf,0x34,0xd7 +.byte 0x3b,0xcc,0x5e,0x6f,0x80,0x38,0x2f,0xda,0xb3,0x70,0x60,0x35,0x8e,0x3d,0x92,0x4f,0xc8,0xaf,0x4e,0xcd,0x69,0xa8,0x0e,0x62,0xb7,0xbe,0x9b,0xa8,0x09,0x67,0x68,0x08,0xf0,0x39,0x00,0x5e,0x04,0x11,0x64,0x21,0x75,0xf4,0x2a,0xdd,0x3a,0x81,0x95,0xe1,0xa2,0x26,0x4e,0xc2,0x17,0x7e,0xe3,0x27,0x8b,0x80,0x01,0xdf,0xe6,0xfd,0x8e,0x24 +.byte 0xe6,0x0c,0xa4,0xdb,0x1e,0x8d,0x03,0x63,0x5a,0xa1,0x00,0x6b,0xcc,0x34,0x75,0x63,0x84,0x91,0x9d,0x4f,0x4f,0xfb,0xbb,0xa3,0x06,0x4c,0xad,0x32,0x62,0x34,0x3c,0x74,0x4a,0x19,0x2c,0x87,0x65,0xb6,0xbb,0x84,0x8f,0x06,0x4d,0x80,0x4e,0x54,0xc5,0xd6,0xe1,0xb3,0x5f,0xf7,0xa1,0xb7,0xb8,0x09,0x7d,0x72,0x36,0x9d,0x14,0x26,0x05,0x6e +.byte 0x9a,0x0f,0xfd,0x8a,0x81,0x83,0xa2,0x94,0xf9,0xee,0x5d,0xfe,0x08,0xd7,0xcc,0x8e,0x47,0x7c,0x07,0xbf,0xfe,0x14,0xf9,0x39,0x89,0x47,0x85,0x23,0xab,0x58,0x46,0x06,0x8b,0x81,0x37,0xe7,0x80,0x8c,0x72,0x51,0x3f,0x78,0xa5,0x88,0x41,0x4a,0x20,0x27,0x6d,0xd0,0x41,0xa2,0xb5,0xb1,0x78,0x48,0x39,0x8c,0x77,0xd8,0x77,0x94,0xd1,0x3d +.byte 0xa5,0x4f,0x14,0x5e,0x10,0x70,0xba,0x26,0x34,0x4e,0x4d,0xe1,0xee,0xe8,0x3b,0x0b,0xe5,0x58,0x7a,0x00,0x94,0x62,0x24,0xff,0x05,0x14,0xff,0xe4,0xa5,0x9c,0xe3,0x0e,0x4f,0xbf,0x7e,0xcc,0x60,0x74,0x8d,0xfa,0x44,0xaa,0xd9,0x66,0x79,0x24,0x6d,0x18,0x5b,0xcf,0xd3,0xa7,0x2f,0xd6,0x20,0xe4,0x5d,0xed,0x1f,0xe6,0xad,0x59,0xe4,0xa7 +.byte 0x44,0xb9,0x8e,0x4e,0xa2,0x41,0x73,0xb6,0x38,0x6b,0x7f,0x4e,0x15,0x0a,0x41,0x3c,0x57,0xa3,0x21,0xe2,0xbf,0x19,0xf9,0x43,0x61,0x11,0x7c,0xa9,0xdb,0x25,0xce,0x10,0x74,0x6f,0x35,0xfb,0xfc,0x9b,0x0e,0x2c,0xb7,0x42,0x25,0x97,0x07,0xb5,0xba,0x51,0xbc,0xc7,0x6e,0xa0,0x60,0x65,0x8d,0xcb,0x4a,0x94,0xbe,0x99,0x28,0x7b,0x9e,0x7a +.byte 0x0e,0x57,0xa2,0x74,0x68,0x76,0x75,0x7c,0x28,0xb5,0x1f,0xf4,0x5a,0x2f,0x00,0xae,0xbe,0xe8,0xc6,0xf6,0x9e,0x16,0x96,0x06,0xed,0xea,0x73,0xfb,0xd8,0x46,0xb3,0xb0,0xdd,0xc4,0x64,0x9b,0xd3,0xe0,0xd5,0x2b,0xbc,0xb6,0xd8,0x05,0xbf,0xf7,0x92,0x11,0x18,0xc6,0xe1,0x55,0x50,0x42,0x72,0x93,0x6e,0xf1,0x85,0x9e,0x0a,0x2e,0x2a,0xee +.byte 0x51,0xa7,0x44,0xe1,0x2a,0xdd,0x58,0x3b,0x00,0x72,0xaf,0xb3,0x14,0x11,0xcf,0xc9,0xcf,0xa5,0x7c,0x6c,0x8a,0x75,0x42,0x39,0x6e,0x99,0x3d,0xed,0xbe,0xd3,0x69,0xbb,0x7b,0xb1,0x00,0x6b,0xa9,0x84,0xdd,0x38,0x30,0xdf,0x20,0xed,0x50,0x78,0xc2,0xc7,0xae,0x47,0xdb,0x87,0x2a,0xe7,0x58,0x83,0x2b,0xc9,0xf1,0x34,0xbe,0x2d,0xfa,0x6c +.byte 0xf9,0x8c,0x73,0x58,0xb5,0x53,0x1b,0x8a,0xa0,0x86,0xa3,0x03,0x56,0xf8,0x35,0x00,0xd5,0xb7,0x5b,0xa5,0x4a,0x28,0x68,0xf6,0x3b,0x32,0xf4,0xdc,0xad,0xf0,0x24,0x0c,0xc9,0x5e,0xb4,0x32,0xdb,0xb8,0x4a,0x8d,0x19,0xec,0xf0,0x32,0x06,0xc9,0x84,0xc0,0x99,0x0b,0x14,0xf6,0x64,0x88,0x99,0xbc,0x4c,0x90,0x07,0x49,0x18,0x1b,0x05,0x15 +.byte 0x3f,0x43,0x42,0xf1,0x43,0x89,0xa3,0x14,0x78,0xdb,0xea,0xe9,0x90,0xde,0x3c,0x71,0x14,0x77,0xc1,0xab,0x29,0x1a,0x20,0x9e,0xd6,0xdd,0x73,0x32,0xf9,0xf7,0x2f,0x58,0x3f,0x59,0x80,0x36,0xe8,0xf7,0x79,0xa2,0xe8,0x38,0xdf,0xd9,0xb2,0xbf,0x97,0x95,0xf4,0x9c,0xec,0xc4,0x23,0x7d,0x5d,0x13,0x68,0x79,0x7e,0xe7,0x88,0xcb,0xd8,0x2b +.byte 0x14,0x2d,0x56,0xcf,0x36,0x59,0x67,0xb7,0x62,0xd5,0xb2,0x70,0x01,0x7c,0x96,0x8a,0x72,0xab,0x09,0x83,0xa2,0x4c,0xfe,0xe3,0xc0,0xbe,0x8a,0xa2,0xa5,0x35,0xc4,0xea,0xd6,0x56,0x50,0x43,0x09,0xf5,0x49,0xf3,0x7a,0x70,0x39,0x29,0xc1,0x47,0xcc,0x82,0xf5,0x96,0x0f,0x94,0xb0,0xa5,0x81,0x8f,0x79,0xa4,0xdc,0x65,0x3d,0x32,0x67,0xe7 +.byte 0xdc,0x67,0xb3,0x9a,0x44,0xa7,0xf6,0x61,0x97,0xa9,0x01,0xc7,0x0a,0xf2,0xd3,0xc2,0x16,0x12,0x18,0x18,0x67,0xca,0xc8,0x0c,0x04,0x70,0x7b,0x43,0xa9,0xea,0x15,0x11,0x08,0xe8,0x5b,0x2a,0xc8,0x2c,0xc7,0x17,0xb1,0x65,0x8d,0xe7,0xca,0x18,0x1e,0x10,0xbe,0xd0,0xa6,0xe6,0xcd,0x79,0xcd,0xef,0x4b,0x45,0x7c,0x4e,0x52,0x49,0x69,0xc2 +.byte 0x57,0x72,0xf6,0xa9,0x4e,0x1c,0xb1,0x91,0x87,0x45,0x5c,0xc0,0xa1,0xb5,0x11,0x40,0xc2,0x6c,0xa8,0x6e,0xb7,0xd5,0x59,0x64,0x2f,0x42,0x55,0x56,0xd7,0x3c,0x53,0x98,0x2f,0xfa,0xd1,0x8e,0x13,0x1b,0x67,0xdb,0x12,0x37,0x98,0xd9,0x6d,0xf1,0xea,0x0a,0x13,0x14,0xf6,0xb6,0x86,0x8e,0xa0,0x95,0xa9,0x80,0x58,0x2e,0x02,0x02,0x63,0x07 +.byte 0x32,0xff,0x57,0xb2,0xd5,0x4f,0xa9,0xd2,0x60,0x65,0x9c,0x15,0x8f,0xff,0x9b,0xe4,0x79,0x29,0x19,0xa7,0x8b,0x98,0xfa,0x68,0x2c,0x3a,0x1c,0x63,0xb5,0x95,0x3c,0x1d,0xa1,0xfe,0x67,0xa8,0xaf,0x48,0x35,0x80,0xc7,0x3f,0x53,0xb4,0x61,0xa4,0xb8,0x39,0xa4,0xce,0x32,0xff,0x98,0xc3,0x75,0xb0,0x82,0x52,0x59,0x64,0xfc,0xc5,0x8e,0x50 +.byte 0x67,0xbd,0x57,0x48,0x06,0x05,0x87,0xaf,0x6e,0x26,0xf1,0x91,0x76,0xac,0x7d,0x67,0xd7,0xea,0xd6,0x54,0xf2,0x43,0x5c,0x57,0x71,0x02,0x27,0x6e,0x24,0xd8,0x46,0x82,0x30,0x76,0xa1,0xd7,0xc9,0xc0,0xc0,0x2a,0x35,0x87,0x2c,0xf5,0x0b,0xb9,0x2d,0x3d,0xdf,0xd4,0x9b,0xd5,0x68,0x68,0x5c,0x00,0x55,0x74,0x6c,0x09,0x6b,0x82,0x96,0x4c +.byte 0xf4,0xfd,0xf9,0x8f,0x43,0x29,0x12,0xee,0xf6,0xfb,0xcf,0xdf,0x9b,0x4f,0xed,0x42,0xca,0x52,0x54,0xa2,0xf5,0x49,0x20,0x54,0x8f,0x34,0x76,0xba,0x68,0xf1,0x62,0x56,0x9d,0xc7,0xe1,0xfa,0xff,0x6b,0xf6,0x7e,0xab,0xfe,0x40,0x6d,0x0d,0xb1,0x44,0x16,0x84,0x28,0xbe,0x78,0x00,0xe3,0xe1,0x8c,0x6c,0x49,0x02,0x41,0xcd,0x07,0xd7,0x1d +.byte 0xba,0x63,0xed,0x91,0xb8,0x74,0xae,0xa2,0x12,0x3c,0xac,0x31,0xe1,0xb9,0x46,0x9b,0x3a,0x0d,0xc8,0x6a,0xf3,0x83,0xa7,0x68,0x48,0x5c,0xc4,0xc8,0xc7,0x0f,0x81,0x0c,0x6d,0x29,0x4b,0xac,0x91,0xfa,0x7e,0x8e,0x08,0xd3,0xdc,0x8b,0x30,0x25,0x36,0xba,0xae,0x61,0x98,0x84,0xfb,0x2d,0x3b,0x97,0xa2,0x46,0x8f,0xf2,0x50,0xae,0xbf,0x8a +.byte 0x52,0x46,0xf8,0x87,0x8e,0x8e,0xff,0x2e,0x73,0x8f,0x90,0x8f,0x0e,0x3f,0x0a,0x4b,0x9a,0x3c,0x80,0xef,0x0a,0x3d,0xaf,0xd8,0x3d,0xc3,0x8b,0x71,0x1d,0x5b,0x37,0xe5,0x62,0x5f,0xde,0xc2,0x14,0xac,0x2c,0x13,0x6e,0x49,0x0c,0xc3,0x31,0x58,0x35,0x1e,0xf0,0xe5,0x16,0x84,0xe1,0xe8,0x60,0x98,0x2d,0x1a,0x1d,0x1f,0x58,0x57,0xb8,0x40 +.byte 0xd7,0xcf,0xac,0xef,0x0d,0x4e,0xf4,0x4e,0x62,0x1e,0x97,0x81,0x88,0x26,0xb9,0xeb,0x02,0x67,0x0e,0x89,0xfe,0x65,0x5e,0x04,0xc6,0xc1,0xe1,0x25,0xa6,0xd6,0x81,0x86,0x76,0xcd,0x23,0x5b,0x64,0x61,0x75,0x5d,0x4c,0xfa,0x43,0xa2,0x21,0xd2,0x4b,0x62,0xc3,0x13,0x39,0x12,0xa6,0x9c,0x16,0x87,0x62,0x5e,0xaf,0xff,0xf3,0x76,0x7d,0xed +.byte 0x05,0x11,0x56,0xa0,0x63,0x10,0x1a,0xed,0x0e,0x90,0x14,0xa1,0xef,0x0a,0xcf,0x1b,0xcd,0xe4,0x29,0xf6,0x4d,0xee,0x04,0xea,0xd5,0x7f,0xa4,0x67,0xf7,0xe2,0x2e,0x35,0x1a,0xab,0x64,0x1c,0x47,0x78,0x65,0x39,0xff,0x65,0x5a,0xd8,0xd1,0x9f,0xca,0xe4,0xec,0xb7,0xf7,0xe2,0x90,0x66,0xa6,0x72,0xd4,0xd7,0x71,0xa2,0x3a,0x9d,0x9b,0xc5 +.byte 0x22,0xce,0x45,0x8f,0x6d,0xe1,0xd1,0xd9,0x96,0x1c,0x9b,0xc0,0xb8,0x03,0x3b,0x3c,0x69,0x49,0xb3,0x66,0x2b,0x00,0x70,0x99,0x6f,0x3a,0x17,0x93,0x28,0xec,0x4d,0x2d,0x0f,0x66,0x11,0x26,0x98,0x66,0x60,0xa5,0x8d,0xe8,0x13,0xaa,0xd6,0xe7,0x10,0x9e,0x5d,0x52,0x76,0xcc,0xd0,0xd7,0x67,0x19,0x33,0xc7,0xe0,0xff,0x11,0x3a,0x94,0x57 +.byte 0xc0,0xd1,0x2e,0x3c,0x8d,0x39,0x3e,0xf9,0x62,0x97,0xcb,0x8e,0xf5,0x0c,0x62,0x8c,0x79,0xad,0x06,0xec,0x51,0x0c,0x03,0xc0,0xf0,0x5c,0xd6,0x61,0x7d,0x0b,0xd8,0xf5,0x65,0x7b,0xb4,0x05,0x6c,0x62,0xa7,0xab,0x42,0xe5,0x8b,0x82,0x6d,0xa0,0xcc,0xe2,0x83,0xa3,0xe3,0x63,0x68,0x61,0x48,0x74,0x2b,0x3f,0x1b,0x10,0x85,0x61,0x48,0xcf +.byte 0x19,0xba,0x82,0xa9,0xde,0xc9,0xfd,0xa6,0x1e,0xed,0x2c,0xc7,0xef,0xaa,0x77,0xbb,0x61,0xb5,0xea,0x73,0x85,0x72,0xf6,0x1f,0x5c,0x3d,0xbe,0x99,0x70,0x1f,0x19,0x8a,0x39,0x41,0x07,0xda,0x1e,0x35,0x15,0xa8,0x80,0x2c,0xf3,0xe9,0xe6,0x0e,0x81,0x71,0xf8,0x1f,0xee,0x35,0xd5,0xd4,0xf8,0xbb,0x93,0xf5,0x19,0x26,0xb5,0xea,0x98,0x5f +.byte 0x92,0xae,0xcd,0x5c,0x0a,0x2f,0x8e,0x12,0x55,0x29,0xa6,0xc6,0x0e,0xde,0x50,0x83,0xa0,0x5a,0xb9,0x05,0x0d,0x7c,0x96,0xfd,0x41,0xd2,0xb2,0x2b,0xea,0x14,0x9f,0x8b,0x77,0x20,0x83,0xc8,0xf7,0xe6,0xd6,0x8d,0x43,0x00,0x0b,0xf0,0xde,0xcf,0x6c,0x46,0xb0,0xd3,0x02,0xe1,0x7f,0x89,0x1c,0xe7,0x8d,0x7d,0x5c,0x59,0xa1,0xf7,0x17,0x04 +.byte 0xd6,0x1c,0x85,0x8c,0x6a,0x4f,0x74,0xd2,0x1c,0x7b,0x4a,0xcb,0x8a,0x42,0x2a,0x35,0x17,0x08,0xe7,0xa3,0x6a,0x00,0xdd,0x28,0x8e,0x12,0x8a,0x03,0x99,0x29,0x34,0x69,0x84,0xec,0x98,0xef,0x31,0x21,0x23,0xeb,0xf8,0x44,0x15,0xdc,0xab,0x7e,0x7f,0x7b,0x0a,0xb6,0x4c,0xfb,0x21,0xe4,0x5b,0xe6,0xf0,0x3e,0xe5,0x81,0x8a,0xc9,0x84,0x76 +.byte 0xb7,0xf7,0xa2,0x05,0x14,0x91,0xb2,0x0d,0x90,0xa0,0x32,0xdc,0x1c,0xf4,0xdd,0x1b,0x70,0x06,0xf5,0xb9,0xb1,0x20,0xd7,0xcd,0x58,0x04,0xfd,0xb7,0xa9,0xc7,0x4d,0xbf,0xa3,0xce,0xc8,0xa7,0x0c,0x8d,0x1f,0x96,0xfa,0x8c,0xa7,0xe0,0x99,0x6c,0x4d,0x71,0xa4,0x3d,0x67,0xb1,0x59,0xa7,0xe3,0xdb,0xbb,0x59,0xa5,0x1c,0xdf,0xfd,0x3a,0x05 +.byte 0xc4,0xd8,0xe6,0xde,0x42,0x5a,0x0c,0x88,0xe6,0xe3,0x52,0xb7,0xcb,0xa0,0xdc,0xc5,0x8a,0x70,0xa5,0xd1,0x99,0xd8,0x18,0xec,0xd9,0x8d,0x7d,0x54,0xca,0xf3,0x1c,0xdb,0x1f,0xc5,0x74,0xeb,0xd3,0xbf,0x96,0x6e,0xa4,0xc9,0x62,0x8b,0xff,0x64,0x4b,0x63,0x65,0x97,0x83,0xe7,0x02,0x64,0x70,0x56,0x0d,0x78,0xcc,0x75,0x30,0xf1,0xd2,0xb6 +.byte 0x69,0x9d,0xe2,0x56,0x63,0xb3,0x9a,0xa2,0x7b,0x91,0xad,0x24,0xbb,0x61,0x3b,0xea,0xcd,0xb2,0xce,0xd7,0xa8,0xb0,0x9e,0xc3,0xac,0x67,0x01,0x57,0x0b,0xb3,0xc5,0x47,0xf7,0xb2,0x32,0xdc,0x25,0x18,0x22,0x1d,0xef,0x88,0xe0,0x47,0x67,0xeb,0xad,0x09,0xd8,0xb8,0x17,0x17,0xc7,0xc5,0x3d,0xa2,0x51,0x9b,0xa5,0xd4,0x0b,0x6c,0xe5,0x39 +.byte 0x30,0xed,0x6e,0xf9,0x15,0xc2,0xaa,0x2c,0xb2,0x86,0x1c,0x33,0xca,0x0d,0x27,0xe8,0x68,0xb2,0x11,0xad,0x8b,0x9e,0x69,0xb9,0x3f,0xdb,0x54,0xf3,0x46,0xb4,0xc3,0x9d,0x47,0x32,0x1e,0x5b,0x49,0xc5,0xa2,0x2d,0xaf,0x37,0x8a,0x53,0xfd,0x96,0x70,0xfc,0x0b,0x55,0xaa,0x35,0x22,0x9e,0xb1,0x09,0xf6,0xae,0x9f,0x47,0x5f,0x5f,0xd7,0x9e +.byte 0xc2,0x13,0x7a,0x82,0x32,0x1a,0xdc,0xdc,0x87,0x7d,0x9c,0x00,0xc0,0xef,0xef,0x71,0x76,0xf9,0x48,0x17,0x95,0x69,0x30,0x30,0x36,0xf6,0x24,0xc9,0x11,0xd5,0xd7,0xbd,0x1b,0x23,0xd9,0x9f,0x57,0xf4,0xf3,0x01,0x9d,0x22,0x91,0x92,0xa0,0x0f,0xb5,0x88,0xe6,0x3d,0xa7,0x2b,0x19,0x7a,0x65,0x73,0x34,0xc5,0x16,0x1d,0x93,0xeb,0x08,0x71 +.byte 0x46,0x98,0x2b,0x21,0x70,0x9b,0x83,0x15,0x9b,0x4e,0x1f,0x6c,0xf0,0x6e,0xde,0x6d,0xd1,0x40,0x17,0x8d,0x18,0xc2,0x5f,0x91,0x97,0xb0,0x66,0xe8,0x77,0xf7,0x22,0xdf,0x10,0x5f,0xb2,0xc2,0x3b,0x37,0x59,0x52,0xf1,0xea,0x0c,0x6f,0xd4,0xa5,0x40,0xa5,0xb6,0x38,0xe9,0x81,0x5b,0x81,0xc8,0x9d,0xf5,0xbe,0xbf,0x4d,0x7d,0xc2,0x53,0x9f +.byte 0xac,0xa6,0xf0,0x7a,0x22,0x9c,0x16,0xa9,0x1f,0xb9,0x54,0x25,0xf9,0xd3,0x6e,0x42,0xe8,0xc2,0xf4,0x9d,0xa7,0x25,0x95,0xab,0x7e,0x9a,0xaa,0x4a,0xcc,0x89,0xc5,0x73,0x4f,0xe2,0xed,0x2e,0x22,0x6d,0xb0,0x22,0x5f,0x79,0x9b,0xf2,0x0d,0x9d,0xd2,0xa2,0x7e,0xbf,0x2a,0xe0,0xe4,0xf2,0x2c,0xec,0x52,0xd7,0xac,0x63,0xac,0x82,0xa5,0xbf +.byte 0x02,0xda,0x3a,0x9e,0x36,0x8f,0xdf,0x39,0xbc,0x96,0xdf,0xbc,0x38,0x39,0x84,0xe6,0x7e,0x6e,0x65,0x1b,0x48,0x58,0x24,0x54,0x25,0x6b,0x70,0xd5,0xe4,0x33,0x59,0x1c,0x12,0xca,0xe7,0xbf,0x21,0xa7,0xc0,0x96,0x85,0x52,0x0e,0x53,0xc5,0xea,0xdc,0xd4,0x37,0xb7,0x02,0x38,0x41,0xf5,0x3e,0x39,0x3a,0x65,0x4e,0x93,0xe3,0xe6,0x9d,0x8b +.byte 0x15,0x1f,0xdf,0x6f,0xaa,0x4b,0x6f,0x11,0xfd,0xb6,0x47,0x3b,0xc8,0xb1,0x01,0x25,0x9b,0xbf,0x7c,0xae,0x75,0x9b,0xab,0xec,0x93,0xdc,0x28,0x42,0x92,0xb5,0x3d,0xdc,0xdc,0xa1,0x82,0xdb,0x2a,0x05,0xec,0xaf,0xa9,0xfa,0x34,0xca,0xaa,0x6d,0xa1,0x6a,0x4b,0xe5,0x43,0x73,0x31,0xde,0xb0,0x5d,0xc2,0xdb,0xd0,0x3a,0xb7,0x9f,0xe2,0x86 +.byte 0xfd,0x96,0xa9,0x93,0x5e,0xe7,0x5d,0xa6,0x24,0xe4,0x72,0x16,0xb8,0x27,0x06,0x95,0xbe,0x87,0x78,0xb7,0xba,0xa3,0xcb,0x7e,0x2b,0xfc,0x3a,0x24,0x1c,0x3c,0x16,0x03,0xd4,0xe1,0x28,0x25,0xac,0xb2,0x73,0xcb,0xff,0xf1,0x0c,0x65,0xc7,0x44,0x84,0xe0,0x19,0xe8,0x58,0x4f,0xc4,0xa0,0x19,0x5a,0x64,0x41,0xf7,0xaf,0x4a,0x87,0xf3,0xc2 +.byte 0xc3,0xa6,0x11,0xd2,0xf2,0xd3,0x18,0x13,0x38,0xec,0x26,0xf3,0xcd,0x17,0x9b,0xaf,0x9a,0x40,0x10,0xb9,0x0c,0x60,0x82,0xd2,0x62,0xe2,0xae,0xba,0x4d,0x95,0x44,0xea,0x19,0xff,0x21,0xca,0xba,0x31,0x38,0xa0,0x8d,0xcd,0xde,0xae,0x50,0x93,0x96,0xfe,0x39,0x50,0x97,0x79,0xd9,0xcd,0x68,0x56,0xc9,0xe3,0x3c,0x85,0x7c,0xb8,0x1d,0x01 +.byte 0x92,0x72,0xf2,0x35,0x26,0x5e,0xf0,0x38,0x85,0xd9,0x05,0xd1,0xe9,0x18,0x1f,0xf5,0xd1,0xf3,0xc3,0xc5,0x43,0xe6,0x87,0xcb,0xf7,0x25,0x89,0xb3,0x17,0xea,0x58,0xa1,0x5f,0x61,0x28,0x37,0x72,0x65,0x44,0xde,0x53,0xa8,0xd8,0x80,0x35,0x14,0x1d,0x02,0x64,0x68,0x2f,0xc9,0x1c,0x75,0x44,0xec,0x07,0x4e,0xba,0x49,0xa0,0xe8,0x3b,0x3c +.byte 0x63,0x32,0x66,0x62,0xa8,0xe3,0x39,0x3c,0xe7,0x70,0x20,0x6d,0x1e,0x2e,0x74,0x91,0xb4,0x8f,0xdf,0x59,0xc2,0x0e,0x1e,0x43,0x9b,0x26,0x7b,0x36,0x7b,0xe8,0x96,0x61,0x81,0x96,0x16,0x12,0xeb,0xd9,0x8e,0xd8,0xd8,0x04,0x1f,0x00,0x90,0x81,0x9f,0xbe,0x59,0x83,0x83,0x7d,0x83,0x56,0x41,0x78,0x1d,0xac,0x64,0x7b,0xdd,0xea,0x2f,0x34 +.byte 0x2e,0xf4,0x58,0x21,0x8b,0x39,0x82,0x90,0x80,0x75,0x63,0xd9,0x2e,0xf9,0x4a,0x75,0x77,0xa8,0x66,0xa9,0x95,0x88,0x38,0xd7,0x1f,0xd9,0xae,0xf9,0xba,0x29,0x65,0x29,0x3d,0xd6,0x3c,0x47,0xb7,0x22,0x37,0x65,0xce,0x81,0xf3,0x70,0xc9,0xeb,0x5c,0x02,0x65,0x71,0x65,0x8a,0x93,0xcc,0x02,0xe5,0x21,0x2c,0x38,0x69,0xad,0xb6,0x89,0x7d +.byte 0x46,0x37,0x44,0x67,0x87,0xb0,0x41,0x85,0x7d,0xae,0x82,0x05,0xc0,0x28,0x29,0xf3,0x76,0xa6,0x54,0x4a,0x15,0x84,0x49,0xb6,0xce,0x82,0x45,0x5a,0x2d,0x46,0xae,0xf8,0x8a,0xe6,0x82,0x27,0xe7,0xc0,0xe4,0x6c,0xce,0xd7,0x2e,0x7f,0xd7,0x69,0x97,0x22,0x69,0x1f,0x0f,0xdb,0x6e,0x4e,0x21,0x31,0x9b,0x9b,0xdb,0x33,0xcb,0x7f,0x1f,0x2d +.byte 0x08,0x16,0xb8,0x1e,0x87,0x2f,0x39,0x87,0xc2,0xe9,0x6f,0xd8,0x14,0xbc,0xe9,0x09,0x17,0x66,0xab,0x09,0xe6,0x69,0xe9,0x75,0xca,0xa9,0xe5,0xc6,0xbf,0x6d,0xce,0x5d,0xb5,0x86,0xe4,0xf1,0x59,0x73,0xfd,0xf5,0xc7,0xcf,0xf0,0xa7,0xb2,0xcf,0xe7,0x2b,0x4a,0x57,0x99,0x48,0xf8,0x49,0x31,0x9a,0xdc,0xd3,0x05,0x7c,0x00,0xbc,0x47,0x3e +.byte 0x22,0x6d,0x45,0xe3,0x13,0x1b,0x75,0x0f,0xac,0xc7,0xc9,0xed,0x4a,0xd8,0xc6,0xf5,0x16,0x30,0x16,0xcc,0x6b,0x1f,0x8b,0xb4,0x7a,0x28,0xa7,0x90,0xd4,0x6b,0xab,0x6a,0x6e,0x02,0x03,0x75,0x08,0x40,0x82,0x64,0x3a,0xbe,0xbb,0x3c,0x46,0xab,0x47,0xc2,0x08,0xbb,0xa4,0xd0,0x95,0x5d,0x1f,0x1f,0x5b,0xa3,0x7d,0x47,0x2f,0x1c,0xee,0x10 +.byte 0x1b,0xbd,0xf8,0xd2,0x86,0x78,0x72,0x6c,0x2f,0x7b,0xba,0x5c,0x8a,0x0a,0x0e,0x13,0x9c,0x4e,0x33,0x6b,0xa1,0x47,0xdd,0xe5,0x66,0x4e,0x23,0x82,0x18,0x83,0xb8,0xe7,0xb2,0x9b,0x75,0x29,0xef,0x95,0x5a,0xb2,0xbe,0x06,0x4d,0x44,0x7c,0xdf,0x31,0x04,0x92,0xe6,0x5b,0x52,0x0c,0x98,0xac,0x85,0xee,0x04,0x8d,0x87,0x55,0x59,0x3d,0x7e +.byte 0xa2,0x19,0xdd,0xdb,0xbd,0xb2,0x9c,0x6d,0x51,0x67,0x42,0xdd,0xb8,0xb7,0x51,0x7b,0x93,0xb1,0x69,0x22,0x10,0x94,0x46,0x6f,0xc4,0xcc,0x53,0xf0,0x66,0x26,0x56,0xf8,0x95,0x52,0xba,0xf2,0xac,0xe1,0x34,0x47,0x9c,0x7a,0xae,0x56,0x8b,0x77,0x81,0xc6,0x25,0x96,0xda,0xe9,0x87,0x85,0xda,0x1b,0x0f,0x24,0x7f,0x46,0x99,0xe0,0x9e,0x4b +.byte 0xb1,0x01,0xe2,0xc0,0x58,0xbd,0xb4,0xb4,0x09,0xa0,0xfe,0x82,0xd8,0xde,0x9e,0x2f,0x0e,0x03,0xbd,0x35,0x1b,0x46,0x9b,0x14,0xff,0x5c,0x5f,0xf0,0xab,0x56,0x8c,0x38,0xae,0x7e,0x36,0x73,0x0d,0x85,0xe4,0x54,0x40,0xcc,0xe7,0x11,0xcf,0x46,0x9f,0x58,0x56,0x45,0xa8,0xce,0x35,0xe7,0x41,0x15,0xce,0xeb,0x36,0xca,0x42,0xfe,0x13,0x25 +.byte 0x57,0xff,0xdd,0xe0,0x7a,0xde,0x67,0xa7,0xbc,0x5f,0x32,0xaa,0x87,0xe6,0xb8,0x3a,0xfd,0x86,0xa7,0x64,0x0d,0x69,0x66,0x2b,0xd1,0xae,0x55,0x63,0x4b,0x36,0x19,0x3d,0x69,0xde,0x6b,0x27,0x6a,0xfb,0x4b,0x73,0xac,0xf7,0xa0,0x13,0x2e,0xf0,0x37,0x15,0xd8,0x71,0xf3,0x1e,0xca,0x00,0x60,0x61,0xee,0xc1,0x5e,0x18,0xc3,0x3d,0x5c,0xca +.byte 0x60,0xbe,0x40,0xac,0x22,0xd0,0xba,0x2a,0xbb,0xdc,0x57,0x33,0x05,0x1a,0x33,0xf7,0x58,0x97,0x4e,0x88,0xb3,0x70,0x91,0x05,0xa9,0x92,0x1b,0x22,0x3c,0x4a,0xcf,0x20,0x15,0x5e,0xad,0xa7,0x77,0x37,0xc7,0x57,0x20,0xbc,0xaf,0xd8,0x02,0x2a,0x01,0x93,0xbc,0xc7,0x29,0x21,0xdf,0x9a,0xe4,0x39,0x0e,0xa8,0x91,0x03,0x92,0x25,0xc9,0x2c +.byte 0x63,0x78,0x49,0xe7,0x37,0xa2,0x36,0xff,0x5a,0x44,0x84,0xf1,0xe5,0x30,0xcd,0x9b,0x72,0xe2,0x70,0xb9,0x4c,0x9a,0xef,0x1f,0xcf,0x7e,0x4c,0xdb,0x79,0xde,0xd5,0x7a,0x87,0x93,0x31,0x26,0x42,0x67,0x34,0xa2,0x1e,0xae,0x39,0x84,0xaf,0xe8,0xf5,0x49,0xe0,0xd2,0x16,0xb8,0x28,0x4a,0x7c,0xb4,0x58,0xef,0x5d,0xf3,0x6c,0xe6,0x89,0xa2 +.byte 0x5b,0x19,0x5e,0xc3,0x1d,0x7b,0xcb,0x60,0x3b,0x48,0xc3,0xb2,0x98,0x41,0x22,0xac,0x8a,0x86,0x0f,0x29,0xb7,0xa9,0xe8,0x7d,0x1e,0xce,0x7e,0x7f,0xd2,0x4f,0x59,0x70,0x18,0xb9,0x43,0xb3,0x09,0xa5,0xcf,0x8d,0xa7,0x74,0x62,0xf9,0x92,0xf6,0x99,0xc8,0xed,0x2d,0x32,0xa3,0xe8,0x51,0x8a,0x9e,0x55,0xf3,0x9e,0xef,0xdf,0x90,0xe0,0xbe +.byte 0x1b,0x36,0x0e,0x3a,0x28,0x99,0x21,0x1c,0x14,0x2c,0xa1,0x7e,0xf6,0x51,0x7f,0x19,0x96,0xe4,0xcc,0xd4,0xbf,0xdd,0xaa,0x0a,0x06,0xa3,0x05,0x2c,0x8b,0x17,0x85,0xef,0xfb,0x76,0xa3,0xd0,0x90,0xb3,0xb9,0x6c,0x2d,0xf9,0xba,0x51,0xbf,0x13,0xd4,0xf3,0x23,0x5b,0x8e,0x6e,0x8a,0x03,0x02,0x70,0x01,0xf8,0x54,0x41,0x09,0x12,0x57,0x31 +.byte 0x0c,0x30,0x11,0xf2,0x10,0x2d,0xc3,0x90,0xac,0xc8,0x01,0x7f,0x2f,0xc0,0x8b,0x56,0xd5,0xb5,0x1d,0xd7,0x85,0xe3,0x26,0x90,0x0a,0x47,0xbe,0xee,0xeb,0xea,0x62,0x6d,0x95,0xe2,0x0e,0x04,0x21,0x65,0xd8,0x1b,0x88,0xc8,0x5e,0xec,0x3a,0xc7,0x2b,0x12,0x4f,0x2d,0xfb,0xc8,0x56,0x1b,0x6f,0xe5,0xf7,0x03,0xa6,0x94,0x29,0x3e,0xd7,0xf1 +.byte 0x46,0x91,0x26,0xbf,0x3c,0x8f,0x55,0x71,0x39,0xaf,0x1f,0x4f,0x96,0xdc,0x9f,0xaa,0xef,0xc2,0xcb,0xc4,0x97,0xa8,0xf5,0x82,0xaa,0x36,0x47,0x80,0x80,0x10,0x1b,0x68,0x88,0x29,0x8e,0x8e,0x14,0x4f,0xf2,0x3f,0xb6,0x16,0x2a,0x42,0xe8,0x8f,0x7b,0xd6,0xb9,0x1f,0x3a,0x56,0x7a,0x3f,0xad,0x5d,0x68,0x34,0x6d,0x65,0xde,0x13,0x4d,0xa9 +.byte 0xf9,0x4f,0x37,0x49,0xc0,0x63,0xc4,0x28,0x42,0x4c,0x77,0xae,0x78,0x38,0x31,0x87,0xf4,0x9f,0x4a,0x16,0xbb,0x6e,0x06,0x9a,0xa1,0x1c,0xe2,0x97,0xc9,0xf9,0xfb,0x3a,0xe1,0x25,0x4e,0x4e,0xc3,0xfe,0x9a,0xef,0x1f,0x43,0xfb,0x69,0xb1,0x06,0x09,0x4b,0x33,0xf3,0x9c,0x40,0x05,0x83,0x17,0x71,0x81,0xd6,0x87,0xb5,0xd1,0xa7,0x59,0x38 +.byte 0x1f,0xbc,0x6c,0x64,0xb6,0x85,0xee,0xce,0x39,0xb4,0xfe,0x3a,0xf2,0x9e,0x02,0x84,0xc4,0xf9,0x2c,0x56,0xeb,0xd1,0x06,0x8d,0xf4,0x25,0x91,0x98,0xf0,0x49,0xb1,0xa5,0xcd,0x06,0x43,0x74,0xfe,0xea,0x50,0xeb,0x8c,0x42,0x47,0x2d,0x33,0x3a,0xc6,0x4d,0xe4,0x9d,0xa5,0xea,0xc2,0x26,0x90,0xa7,0x17,0xb7,0x8a,0x0c,0x3e,0x0d,0x31,0xeb +.byte 0xe5,0xfe,0x98,0xc9,0x43,0x15,0x2b,0x36,0x06,0x68,0x52,0x12,0xf6,0xa8,0xcb,0x61,0xa8,0xb3,0xc1,0xcc,0xe3,0xf7,0xb4,0x05,0x1c,0xea,0x67,0x48,0xb8,0xe8,0x6f,0x08,0xc3,0x9d,0x48,0xdc,0x06,0xbc,0xae,0xbe,0x35,0x49,0x58,0xe9,0x33,0xbe,0xe5,0xbb,0x5c,0x25,0x79,0x2e,0xde,0xc6,0x7c,0x2d,0xdf,0x53,0xb4,0xa9,0xc3,0x00,0x86,0xe6 +.byte 0xe8,0x1f,0x2b,0x83,0x7c,0xb5,0x90,0xba,0x29,0x63,0x26,0xbf,0x04,0x4a,0xee,0xb9,0xa5,0xd1,0x34,0xc5,0x2f,0x18,0xb8,0xc3,0xdc,0xa1,0x30,0x83,0x8b,0xe7,0x84,0x1b,0x96,0x7b,0x93,0xe9,0xe8,0x15,0x6e,0x3f,0xf7,0x6e,0xe4,0x44,0x0f,0xcf,0x98,0x74,0x63,0x35,0x36,0x29,0xaf,0xc1,0x14,0x98,0xcb,0x7a,0x38,0x37,0xc3,0x0d,0x11,0x43 +.byte 0x7e,0xda,0x34,0x22,0x86,0xb8,0x96,0x6d,0x36,0xfb,0xd4,0x36,0x6e,0x10,0x06,0x41,0xa6,0x80,0xd5,0x1b,0x96,0x1b,0x06,0x71,0x08,0x97,0x17,0x1e,0x2d,0x62,0x3f,0x8d,0xd8,0x46,0xbd,0x5d,0x31,0x74,0x04,0x48,0xaa,0x2c,0xd2,0xb3,0x5e,0xbd,0x60,0x60,0xa4,0x81,0x5c,0xda,0x13,0xd5,0xd6,0x96,0x76,0x2f,0x9c,0x7f,0x40,0x23,0x9f,0x5c +.byte 0x49,0x58,0x2f,0x34,0xb0,0xbb,0xf0,0xb1,0x67,0x8e,0x95,0xeb,0x92,0xee,0xba,0xcf,0x16,0xe2,0x85,0x22,0x67,0x6f,0xd8,0xb7,0x4c,0x17,0x34,0x68,0x5d,0xea,0x4a,0xa3,0xa5,0xad,0x8f,0xf0,0x86,0xdf,0x79,0xa1,0x84,0xb3,0xf2,0x4f,0xbe,0xae,0x55,0x60,0x4c,0xd5,0x44,0x3f,0xe9,0xe3,0x9d,0xf2,0x3c,0x42,0x1b,0x35,0x95,0x3b,0x5f,0x6c +.byte 0x76,0xdb,0x5c,0x8a,0x67,0x10,0x15,0x52,0xde,0x50,0x62,0x87,0x66,0x0f,0x36,0xdb,0x14,0x8f,0xda,0x13,0x35,0x9f,0xce,0x90,0x22,0xcd,0x78,0xe5,0xc5,0xcb,0xb4,0x4a,0x23,0x49,0x30,0xe9,0x3a,0xfd,0x9d,0x63,0x98,0xd7,0x9e,0x2f,0x32,0x8b,0xb9,0x34,0x4e,0xaa,0x20,0xe9,0xbc,0x72,0x85,0x2b,0xee,0x2c,0xc3,0xb6,0x31,0x81,0x3e,0x56 +.byte 0x9c,0xda,0x4d,0x9f,0x19,0x36,0xe7,0x47,0x46,0x8f,0x9d,0x83,0xcd,0xa1,0xcc,0xcf,0x69,0xfc,0xbd,0x5d,0x7d,0xd8,0xa8,0x71,0xb5,0xc0,0x6c,0xe5,0xbb,0x5b,0xe3,0xd0,0x6b,0x38,0x53,0x51,0x9b,0x3d,0x0d,0x93,0x95,0x5c,0xc1,0x82,0xbd,0x59,0x8b,0x2a,0xef,0xb8,0x07,0x92,0x3d,0x0f,0x34,0x3c,0xc8,0x39,0x91,0x8e,0x9b,0x72,0x7f,0x51 +.byte 0x61,0xdd,0xce,0x98,0x71,0xde,0xdc,0xdd,0x14,0x0c,0x77,0x48,0x8e,0x26,0xc0,0xc7,0xa0,0x22,0xa5,0xb2,0x36,0xe1,0x2f,0x1b,0x43,0x6b,0xd8,0x8e,0xb2,0x18,0x5d,0xc3,0xba,0xcc,0xae,0xf6,0xb8,0x4a,0x79,0xb2,0x95,0x4b,0xfe,0x15,0x4c,0xc6,0x17,0x4f,0x0f,0x65,0xe2,0xc2,0xc7,0xbf,0x53,0x89,0xa3,0x64,0xbb,0x93,0x58,0x47,0x2a,0xcb +.byte 0x5c,0xc6,0x9c,0x69,0x83,0x2e,0x82,0x92,0xe2,0xcd,0xff,0xfa,0x3f,0xe3,0x4e,0x45,0xce,0x7f,0x71,0x60,0x98,0x06,0x1a,0x4d,0x21,0x26,0x1e,0x3c,0x1d,0xef,0xd5,0xbb,0x10,0x33,0x45,0xdf,0xed,0xd9,0x89,0x32,0x68,0x91,0x3f,0xee,0xc7,0x6a,0x43,0xef,0x33,0xcf,0x3e,0x1e,0x0f,0xa2,0x3e,0x81,0x06,0xc8,0x85,0x7f,0x42,0x23,0xd9,0x85 +.byte 0x8b,0x9a,0xbb,0x11,0x3b,0x26,0xb7,0x21,0x45,0xe8,0x28,0x34,0x32,0x86,0x32,0x18,0x84,0x74,0x27,0x33,0x7e,0xd7,0x07,0x84,0x26,0x50,0x7f,0xc0,0xce,0x1d,0x17,0x1a,0x99,0x5a,0xeb,0x15,0xd2,0x6a,0xaf,0xea,0x89,0xcf,0x11,0xa2,0x9d,0x76,0x70,0x07,0xb2,0x73,0x7a,0x9b,0xad,0xf7,0x3a,0x02,0xf3,0xdb,0x7b,0xdc,0x28,0xec,0xb6,0x6e +.byte 0x0e,0xee,0xae,0xe6,0x20,0xa3,0xc9,0xb1,0x21,0xc7,0x7b,0xb4,0xba,0x5d,0x0c,0xc0,0x1c,0xab,0xea,0xf7,0xfb,0x5b,0x78,0xbe,0x91,0x2d,0x48,0x4a,0x56,0x59,0x90,0x0e,0x4e,0xf1,0xda,0xa9,0x46,0x5a,0x76,0x96,0xa6,0x14,0x7f,0xeb,0x75,0xe5,0x86,0x7a,0x63,0xbe,0x74,0xbc,0xcb,0x9e,0xee,0x03,0x6e,0x98,0xb5,0x62,0xf8,0x27,0x8e,0x46 +.byte 0x37,0xe6,0x7a,0x12,0x45,0xad,0x0f,0xc1,0x2d,0xef,0xad,0x8f,0xc1,0xf6,0xcc,0x97,0x88,0x14,0x0e,0xea,0xbf,0xe3,0x14,0x26,0x0c,0xaf,0xe2,0x9e,0xca,0x30,0xc6,0x51,0x36,0x35,0x6f,0x8b,0x37,0x8d,0x09,0x8f,0x48,0x18,0xea,0xa6,0x13,0x01,0x38,0x04,0xcc,0xa5,0x71,0x91,0x07,0x43,0xc8,0x76,0x1f,0x88,0x57,0xaa,0xd6,0x44,0x3b,0xf0 +.byte 0x17,0xca,0x2d,0x30,0x36,0x41,0xfc,0x24,0x3c,0xbc,0xa3,0x4b,0x10,0x03,0xd2,0xa9,0xef,0xe1,0x98,0x3e,0x88,0xcc,0x7f,0x64,0xb5,0xb7,0x25,0xac,0xf6,0xf6,0xc6,0xd9,0xe4,0x73,0xc3,0xe9,0x21,0x6e,0xee,0x24,0xb3,0xf6,0xa0,0x3f,0xa0,0xdf,0x1c,0xf7,0x66,0x7a,0x87,0x7d,0x8a,0x21,0xd0,0xce,0x2a,0x34,0xef,0xd8,0x83,0x34,0xcb,0x97 +.byte 0xc7,0xb8,0xb5,0xa8,0x9d,0x06,0x2d,0x35,0x70,0x6a,0x3f,0x91,0x81,0x37,0x3d,0xae,0x43,0xb2,0xff,0x6b,0x81,0x44,0x69,0xba,0x81,0xf4,0xb5,0xf6,0xf4,0xea,0x17,0xb5,0x7f,0x0a,0x02,0x2c,0x7a,0x3f,0x6c,0x7a,0x07,0xea,0xd5,0x48,0x17,0x75,0x80,0xa0,0x35,0x03,0x59,0xe9,0x45,0x4f,0x18,0xd7,0xd3,0xed,0x48,0x2b,0xa2,0x17,0xd6,0x35 +.byte 0xc6,0x2f,0x7a,0x9c,0x08,0x83,0x12,0xe6,0x1e,0xc8,0xc7,0x02,0x8f,0xf8,0x15,0x2a,0x79,0xe5,0x1f,0xd2,0x1f,0x05,0x34,0xe4,0xb4,0x7e,0xb8,0x05,0xb7,0xae,0x44,0x5c,0x35,0x6c,0x2e,0x69,0xde,0x09,0x2d,0x71,0xe3,0x40,0x7e,0x50,0xb7,0x09,0xdf,0xe8,0x87,0x19,0x82,0x17,0x7b,0x46,0x5b,0xa4,0x23,0x62,0x0b,0x79,0x59,0x5f,0x3a,0x19 +.byte 0x0a,0xc1,0x90,0x79,0x0d,0xce,0x9b,0xc0,0xaa,0xb5,0x6a,0x71,0xe3,0x88,0x31,0x66,0x0c,0x0d,0x8c,0xaa,0xd6,0xf0,0x61,0x71,0x09,0xb4,0xbe,0x61,0x8b,0x9e,0xf3,0xb3,0x9e,0x8b,0x5a,0x50,0x55,0x13,0x0f,0xbe,0x9b,0xa6,0x76,0x34,0xbc,0xae,0xa1,0x7f,0x72,0x21,0xac,0x6c,0x58,0x74,0x5b,0x19,0x16,0x53,0xa9,0x0f,0x0f,0x0f,0x15,0xc9 +.byte 0x2b,0xbb,0x80,0x97,0x5e,0x37,0x8b,0xef,0xf7,0xb5,0x4f,0xf0,0x01,0x77,0xce,0x03,0x86,0x8e,0xe7,0x7b,0x9e,0x52,0x2e,0x3b,0xbb,0x17,0xf5,0x12,0xd5,0xac,0xb2,0x0d,0xe1,0xb4,0xcd,0x04,0xe8,0xfa,0x65,0xea,0x95,0xa5,0xf6,0x82,0x75,0x28,0x90,0xfe,0xef,0x2c,0xd1,0xbb,0x9e,0x71,0x47,0xfc,0xf1,0x63,0x5a,0xd0,0x49,0x4d,0xfe,0xf9 +.byte 0x5d,0x22,0xbf,0x80,0x8d,0x07,0x50,0xde,0x57,0x9e,0x0c,0xc5,0x00,0xad,0xfa,0x57,0x8f,0xcd,0x53,0x70,0x37,0x25,0x22,0x56,0x2b,0xea,0x8e,0x62,0x41,0xe8,0xac,0x3b,0x1f,0xef,0x46,0xd4,0x8d,0xf7,0x4d,0x89,0xb1,0x61,0x1b,0xb8,0x74,0x1a,0x40,0x80,0xbc,0x62,0x71,0x76,0x90,0x37,0x9c,0x91,0x3c,0xfb,0x0c,0xc5,0x18,0x63,0x9a,0xcf +.byte 0xe1,0x43,0xd0,0x01,0xe3,0xcc,0xc6,0x93,0xc7,0x4f,0x04,0x5f,0x07,0x33,0x1f,0xd8,0x5d,0xb0,0xe7,0xa1,0xa1,0xfc,0xbf,0xff,0x4f,0x3e,0x38,0x38,0x14,0x1c,0x90,0xc0,0x77,0x60,0x85,0x4c,0x11,0x75,0xca,0xe5,0x87,0xbb,0x0a,0x49,0xb1,0xd8,0x12,0x06,0x00,0xa0,0xe9,0xe6,0x8a,0x34,0xd5,0x8f,0x56,0xd1,0x6f,0xfc,0xcb,0x6a,0xbd,0x4a +.byte 0x68,0x4a,0xbc,0x90,0xf0,0x1c,0x9f,0x36,0x68,0xab,0x26,0xc9,0x7f,0x48,0xe9,0xf6,0x8a,0x68,0x85,0x95,0x30,0x31,0xdb,0x02,0xc8,0x48,0xbf,0x1a,0x76,0x85,0x23,0xde,0xc6,0xa3,0x83,0x02,0x5f,0x7f,0x1e,0x57,0x7c,0x1b,0x4c,0x77,0x72,0x76,0xb9,0xe3,0x09,0xd6,0x73,0xe1,0x0c,0x03,0x51,0x55,0xe9,0xfc,0xab,0x79,0x9f,0xc5,0x00,0xd9 +.byte 0xcf,0x5c,0x61,0x6a,0x30,0x83,0xd8,0x38,0xc8,0x41,0x8e,0xb9,0x6a,0xbc,0x33,0x02,0x03,0x0b,0x03,0x3a,0xf1,0x8e,0xfc,0xb8,0xa8,0xf9,0x4f,0x6b,0x87,0x21,0x23,0x60,0x33,0x53,0xa4,0x38,0x0c,0x95,0x07,0x31,0x14,0x8a,0x71,0x2c,0xd8,0x58,0x67,0xa0,0x78,0x6f,0x9f,0xac,0xf0,0xe3,0xcd,0x9a,0x63,0x5b,0x3b,0xa9,0xae,0x7f,0xf8,0x94 +.byte 0x4f,0x81,0x21,0x8a,0xd9,0xe9,0x65,0xe4,0x98,0xb4,0x8b,0xad,0xfc,0x47,0xf3,0xe4,0x38,0xe1,0x90,0x74,0xfa,0xa8,0xab,0xbd,0xac,0x3d,0xb7,0x93,0x8f,0x99,0x10,0x3e,0x9a,0xb1,0xba,0x9b,0xb0,0xe9,0x43,0x34,0x3c,0x20,0x03,0x65,0x50,0x37,0x9b,0xe1,0xcf,0x64,0x94,0xaf,0xd4,0x9c,0x07,0xad,0x68,0xc4,0xaf,0x2c,0xda,0xd7,0xdd,0x49 +.byte 0xb6,0xed,0xcd,0xcb,0x1e,0x8a,0x4b,0x6e,0x7f,0x5f,0x54,0x79,0x12,0x30,0xbe,0xfe,0x8a,0xeb,0x84,0xd8,0x48,0xc2,0x5d,0x83,0x09,0x5c,0xfd,0x3f,0x80,0xfd,0x68,0x78,0xc3,0xa4,0x90,0xae,0xb7,0x1d,0x9a,0xd3,0x57,0x8b,0x5e,0x3d,0xc9,0xda,0xff,0x52,0xca,0x3f,0xf7,0x5f,0x84,0x25,0x1f,0xa3,0x64,0x68,0x69,0xb9,0x84,0xb1,0xd7,0x0c +.byte 0x4c,0xbc,0xd3,0x66,0xcc,0x28,0xab,0xa7,0x9b,0x1f,0xd0,0xe5,0xac,0x54,0xf3,0x5a,0x1f,0xdb,0xcf,0x9e,0xa3,0x26,0xfd,0x2e,0xd7,0x02,0x89,0xa5,0xb6,0x8c,0x81,0xac,0xa8,0x54,0x4e,0xa7,0x6c,0x1d,0x5d,0x31,0x0e,0xdf,0xf7,0x32,0x77,0x83,0x00,0x81,0xd2,0x3b,0x39,0xd9,0xda,0xbf,0x0d,0xdc,0xab,0x46,0xb1,0xdc,0x1f,0x8a,0x6d,0xe9 +.byte 0x20,0xf8,0xf3,0xe9,0xdc,0x94,0x15,0x5e,0xe9,0x62,0x44,0xf0,0xbc,0x76,0x64,0x92,0x31,0xb7,0xf1,0x27,0xbb,0x83,0x16,0xfa,0x6e,0xc4,0xc4,0x03,0x50,0x8a,0x08,0x54,0x1d,0xfb,0x3d,0x66,0x05,0x83,0x93,0x62,0x25,0xc3,0xff,0x2d,0x84,0x12,0x98,0x1a,0x61,0x37,0xc5,0x09,0x00,0xdc,0x08,0xa5,0xd5,0x08,0xde,0x78,0x73,0x54,0x1a,0x54 +.byte 0x98,0xc6,0x97,0xec,0x52,0x4c,0x90,0x46,0xa0,0xf5,0xec,0x90,0x8d,0x7e,0xb3,0x8b,0x41,0x5a,0xad,0xd7,0x73,0x8c,0xdc,0x2e,0xc1,0xd6,0xbb,0x95,0x76,0x09,0x32,0x17,0x6e,0x14,0x6a,0x84,0xb2,0xc4,0xa3,0x9c,0x96,0x8d,0x57,0x62,0x43,0xb7,0x75,0x3d,0xd1,0x79,0x0f,0x75,0x13,0xfe,0x63,0x75,0xe6,0x83,0xde,0xc8,0xa2,0x11,0x4d,0x93 +.byte 0x92,0xc7,0x4d,0xfc,0xaf,0x35,0x0f,0x98,0x76,0x22,0xe1,0x95,0x27,0x3a,0xb0,0x62,0x67,0xb2,0x62,0x9f,0x34,0x47,0xb8,0x41,0xa8,0xc9,0x82,0xbd,0xed,0x5b,0xf7,0x33,0xd0,0xcc,0x60,0xef,0xe4,0x47,0xfe,0x6d,0xf8,0xa5,0xee,0x5b,0x3d,0x00,0xc8,0x22,0x7d,0xcf,0x81,0xe3,0xac,0xf9,0x26,0x77,0x26,0x11,0x85,0x99,0xa0,0x77,0x19,0x7d +.byte 0x67,0x80,0x74,0xc7,0xbb,0xe6,0xbb,0x8d,0x16,0x2b,0x50,0x81,0x08,0x89,0x32,0x21,0x20,0xd4,0x7b,0x80,0xd7,0x20,0x53,0x4a,0x0c,0x18,0xb3,0xec,0x49,0x2f,0x3b,0x9b,0x9f,0x69,0x99,0xb5,0x85,0x74,0x0b,0x54,0x61,0x9a,0xe9,0xa1,0xd6,0x98,0x20,0x52,0x82,0x78,0x30,0x5a,0x66,0x02,0x43,0xbf,0x5c,0x5e,0x36,0x3a,0x3b,0xaf,0x7e,0x92 +.byte 0xbc,0x64,0x62,0x2a,0x20,0x65,0xd5,0x1b,0x64,0x6a,0x00,0x88,0xec,0x9b,0xe8,0xd7,0x61,0x80,0x38,0x9e,0x4e,0x55,0x1b,0x5b,0x85,0x7b,0xa0,0x2f,0xc3,0xbe,0x73,0x09,0xfd,0x24,0xbe,0xa6,0x9b,0x81,0x3b,0x3c,0x0c,0xd7,0x23,0xb0,0xe1,0x7b,0x26,0xda,0x54,0x39,0x2e,0x85,0x44,0xe2,0x8b,0x50,0x00,0x31,0x37,0x02,0x68,0x06,0xf1,0x47 +.byte 0x62,0xf9,0x09,0x07,0xbf,0x80,0xd6,0x36,0x8b,0xb7,0x8b,0x28,0x0c,0x2b,0x28,0x4d,0xfc,0xa4,0xc9,0x96,0x90,0xf9,0x12,0xab,0xb2,0xa3,0x91,0x78,0xf4,0x3a,0x6c,0xea,0x29,0xb5,0x9d,0xe5,0x2c,0xd5,0x28,0xdf,0xdd,0xb6,0x0a,0xbe,0xff,0x60,0x23,0x88,0x5b,0x0d,0x98,0xbe,0xb5,0x7c,0xb8,0x4d,0x5c,0x2b,0x2d,0xeb,0xc3,0xce,0xca,0x21 +.byte 0x11,0x2c,0x34,0xef,0xc7,0xce,0xb7,0x11,0x6d,0x46,0x6d,0xcb,0x58,0x2b,0x73,0xae,0xc0,0x9c,0xf6,0x75,0xe1,0x2c,0xbf,0xab,0x9d,0x9f,0x0e,0xd4,0xba,0xf1,0x1f,0xd7,0x8b,0xd2,0x2e,0x00,0xd0,0x01,0xc9,0xe5,0x3a,0xd6,0x2e,0x98,0x79,0x6d,0x04,0xd8,0x39,0xb5,0xd7,0x47,0x48,0x78,0xa6,0xfa,0xbe,0xe3,0x73,0xd9,0x60,0x50,0xc0,0x32 +.byte 0xc2,0xa9,0x08,0xaf,0xce,0xc1,0xda,0x17,0xf6,0xc0,0xa6,0xa8,0x1d,0x58,0xff,0xb1,0x2e,0x3a,0x14,0xa8,0x75,0x8b,0x2e,0xcb,0x0d,0x9d,0x2a,0xe2,0x16,0xc3,0xa6,0x2f,0x48,0xa9,0xe6,0xe7,0xfb,0x85,0xd2,0x75,0xfb,0x7f,0x42,0x4a,0x78,0xa9,0x03,0x43,0xc5,0x9d,0xf3,0xfe,0xd0,0x0a,0xd0,0xb3,0x4c,0xc9,0xad,0x3e,0xd9,0x17,0x3c,0x93 +.byte 0xde,0x05,0x5b,0xb3,0xbb,0x7f,0x79,0x40,0x42,0xe6,0x32,0x6e,0x5e,0xee,0x8a,0xa1,0x8c,0xc6,0x3b,0x50,0x1f,0x46,0x91,0x10,0x21,0xbb,0xa9,0x45,0x5e,0x59,0xe8,0x27,0xb4,0x4a,0x55,0x10,0xae,0xe2,0xfc,0xa3,0x0e,0x62,0x3c,0x47,0xc6,0x65,0x5c,0xcf,0x5d,0x02,0x5c,0x53,0x5c,0x03,0xc0,0xce,0x8a,0x57,0x10,0xe8,0xb6,0xab,0xc1,0xa3 +.byte 0x0b,0x81,0xb2,0x93,0xef,0x48,0x5e,0x79,0x4e,0x79,0x9b,0xfe,0xd6,0x6c,0xef,0xd0,0xe7,0x9d,0x7d,0x74,0x6c,0xb5,0x44,0x34,0xa6,0x8c,0x38,0x3d,0x90,0xd9,0xf2,0x53,0x15,0x60,0xdd,0xb9,0xde,0x7d,0x66,0x93,0xae,0xef,0xa2,0xd8,0xce,0x48,0x3e,0x32,0x13,0x0e,0xd0,0x36,0x42,0xe0,0xc9,0x40,0x3b,0xc3,0xe6,0x37,0x3d,0x7f,0xf6,0xe0 +.byte 0x11,0x51,0xda,0xba,0x10,0x59,0xa2,0xcb,0x96,0x69,0xe2,0x84,0x2d,0x7b,0x1b,0x4b,0x81,0x5f,0xd2,0x8f,0xfc,0x2b,0x7c,0xdd,0xd6,0xcf,0xcf,0x98,0xac,0xe5,0x52,0x07,0xbf,0xe9,0xe7,0x0d,0x2d,0x6b,0xf1,0x69,0x5e,0xc8,0xaf,0xd0,0x70,0xb2,0xca,0xe6,0xc6,0x37,0x29,0x75,0xbf,0xca,0x6f,0x69,0x27,0x8c,0x15,0x3d,0x69,0x83,0xee,0x2b +.byte 0x10,0x9d,0x1d,0xd5,0xad,0x36,0x5a,0x15,0x78,0x1f,0x6c,0x92,0xca,0x5a,0x84,0x1c,0x35,0x49,0x2b,0x33,0x79,0x0f,0xc2,0x84,0x54,0x24,0x3c,0xae,0xac,0x0a,0x76,0xe1,0x22,0x48,0xed,0x8f,0x89,0xeb,0x05,0xfe,0x32,0x6b,0x83,0x00,0x8c,0x36,0xee,0xff,0x1b,0xa0,0x71,0x0e,0xd8,0xe9,0x29,0xa3,0xbb,0x5b,0x8e,0xbf,0x10,0x4f,0xc3,0xeb +.byte 0x3b,0x85,0x3a,0xb3,0x63,0xbb,0x77,0x1a,0x07,0x7a,0x47,0xfa,0x76,0xf5,0x05,0xc4,0xd7,0xe1,0x8f,0xd0,0x4a,0xf9,0x96,0xda,0xcb,0x84,0x43,0xe8,0x61,0xe4,0x2d,0xa8,0x1f,0x4e,0x81,0xaa,0x50,0x2a,0x66,0x2a,0x8c,0xc8,0x0f,0x1c,0x57,0x79,0xdc,0x02,0xbf,0xfb,0x1c,0x68,0xe9,0x02,0x34,0x9b,0xe6,0x2e,0xba,0x60,0x61,0x7c,0x5f,0xc1 +.byte 0xa6,0x7a,0x6c,0x2d,0x02,0xb8,0x6c,0xf2,0x91,0xe3,0xf0,0xed,0xbe,0xe8,0x2d,0x03,0x5a,0x4b,0xcb,0xe5,0x3b,0x3f,0x24,0x30,0x09,0x4d,0x22,0x76,0xf6,0x20,0x9c,0x07,0x1a,0x75,0x2a,0xb3,0xd1,0x9e,0x69,0x6a,0xca,0xc4,0x54,0x5d,0xd8,0x23,0x70,0x5f,0x27,0x94,0x7b,0x0f,0x90,0x12,0xc2,0xbc,0x9c,0x5b,0x02,0x15,0x14,0x4f,0x32,0x0d +.byte 0xef,0xf3,0xa5,0x2a,0xab,0xb3,0xf0,0xe9,0xdc,0x2c,0x66,0x65,0x41,0x67,0x04,0x75,0x81,0x3b,0xb0,0x53,0x42,0x88,0x74,0x26,0x7a,0x9c,0x3f,0x39,0x40,0x25,0xb6,0x4f,0x54,0x86,0xa0,0xea,0x8d,0x78,0xb5,0x43,0x5e,0xfc,0x2d,0x4d,0x14,0xcd,0x4b,0x5f,0x2e,0x37,0x0b,0x28,0xbe,0xbf,0x91,0x60,0xa5,0x40,0xdf,0x73,0xbb,0xa7,0x8e,0xc1 +.byte 0xcc,0xdb,0x8e,0x3a,0xfc,0x7a,0x21,0xac,0x84,0x79,0x33,0x50,0x41,0xa1,0xad,0xb3,0x2e,0xbc,0x74,0xbd,0x66,0x3e,0x36,0x2d,0xf6,0xfd,0xba,0xc4,0x51,0x95,0xaa,0x49,0x92,0xc4,0x6a,0x56,0x9a,0x70,0x5e,0x93,0x74,0x2f,0x6b,0x15,0x60,0x1b,0x3c,0xa9,0x05,0xc4,0xe2,0x0b,0xb9,0x9e,0x86,0x60,0x29,0xb5,0x70,0xe2,0x63,0x10,0xc5,0xfa +.byte 0x73,0xc3,0xb1,0x89,0xcf,0x3d,0xf0,0xf9,0x28,0xa4,0x94,0x9b,0xcd,0xd2,0x9b,0x47,0x4d,0xd4,0x0e,0xb6,0x95,0x68,0x94,0x5b,0x8d,0xcb,0x77,0xa5,0x41,0xf1,0x74,0xb0,0x43,0x9d,0x40,0x1c,0xf3,0x1d,0x66,0x6e,0x00,0x23,0x5f,0x3c,0x00,0xdd,0x9d,0x89,0x8f,0xdf,0x58,0x18,0x9c,0x2d,0xc9,0xaf,0xd5,0x73,0x38,0x23,0x5c,0x2c,0xf6,0x27 +.byte 0x69,0x0d,0xc5,0xe6,0x99,0xb1,0x64,0xa5,0x60,0x74,0x1f,0x7b,0xd2,0x9c,0x1e,0x9f,0x49,0x78,0x17,0x32,0x18,0xce,0xac,0x55,0x6d,0x91,0x7a,0x69,0xed,0xa4,0xa7,0x5f,0x1f,0x5e,0xa1,0xae,0x03,0x6f,0x0e,0xe7,0xed,0x44,0xdd,0xe4,0x9b,0x25,0x4b,0xbf,0x63,0x8b,0x87,0x73,0xb5,0x6f,0x1a,0x1b,0xdc,0xb1,0xf1,0x6b,0xc8,0xb6,0x15,0x84 +.byte 0xc5,0x6b,0x17,0xdc,0x8a,0x20,0xa1,0xeb,0x5b,0x60,0xb4,0x65,0x3a,0x0d,0xe2,0x42,0x97,0x2d,0x93,0xbc,0x93,0x23,0xb0,0x9a,0xa4,0x06,0xa9,0x0e,0xaf,0xa1,0xbc,0xfa,0xe8,0x8e,0xa7,0xa6,0x85,0xc2,0x8d,0x8e,0x70,0xfe,0xa7,0xac,0x8b,0x94,0x8e,0xea,0x6c,0xa6,0xf2,0x6c,0x0e,0x91,0xb6,0xc2,0x6f,0xa4,0x71,0x61,0x05,0xd9,0xb2,0xfa +.byte 0x1a,0x19,0x23,0x4f,0x8f,0x41,0xec,0x9a,0x88,0x2b,0xc7,0x8d,0xf3,0x19,0x21,0xd0,0x40,0x12,0xa9,0x3b,0x44,0x54,0x26,0xc2,0x19,0x35,0x05,0xb0,0x70,0x4a,0xc5,0x91,0x63,0x1e,0x4e,0x74,0x79,0x53,0xd3,0xc8,0x3f,0x39,0x46,0x7a,0x6b,0x74,0x64,0xd3,0xa0,0x97,0x61,0xc2,0x1b,0xe5,0x7f,0x88,0xb1,0xb9,0xf7,0xae,0xbf,0x67,0xc3,0x19 +.byte 0xde,0x41,0xc9,0xbf,0xd1,0x5e,0xc7,0xee,0xc9,0x54,0x02,0x8c,0x92,0xe4,0x6a,0x91,0x60,0x59,0x7f,0x88,0xef,0x0a,0xfc,0x1c,0x09,0x1c,0x9f,0xb4,0x22,0xa2,0x95,0x81,0x81,0x47,0x27,0xee,0x8b,0x7a,0x4c,0x66,0xff,0x15,0xea,0x3e,0xbb,0x41,0x1f,0x6a,0xdf,0x07,0x9e,0xb6,0x43,0xe6,0x88,0x78,0xd4,0x02,0xa7,0x0f,0x88,0x0a,0x1d,0xf3 +.byte 0xe0,0x30,0x06,0x89,0xfc,0x85,0x37,0xef,0xc2,0x03,0xa6,0x2b,0xe8,0xd9,0x35,0x03,0x59,0x93,0x82,0x2b,0x54,0x2f,0x1f,0xee,0x50,0xab,0xa2,0xbf,0xcb,0x07,0xed,0x6a,0xab,0x37,0xf9,0x7e,0x21,0xf6,0xa5,0xe1,0xec,0x06,0x55,0x0e,0x78,0x60,0x18,0x80,0x07,0x62,0x56,0xee,0x3e,0x75,0x94,0x59,0x04,0xe1,0x8c,0x1d,0x07,0x22,0xa3,0x2f +.byte 0x97,0xe6,0xeb,0x62,0x6d,0x3e,0xcc,0x63,0xcf,0xcb,0x53,0xd2,0x5c,0xc6,0xdf,0x9b,0x00,0xb8,0x86,0xaf,0x3d,0xdf,0x6c,0xe9,0xe0,0xf1,0xd6,0xeb,0xf0,0xe3,0xe3,0x37,0x70,0x55,0x14,0x07,0x86,0xf4,0x07,0x00,0x96,0x1b,0x7e,0xd9,0xa8,0x4b,0x15,0xa4,0xf0,0x87,0x20,0x1b,0xdb,0x6c,0xa4,0x37,0x52,0x31,0xb6,0x59,0xaf,0xc4,0x00,0xc2 +.byte 0xfa,0x7c,0xc7,0xc4,0x9e,0xdf,0xd8,0x61,0x90,0x52,0xd9,0x0b,0xcf,0xe3,0xe3,0x82,0x9e,0x3d,0xb4,0xf7,0xc8,0x7b,0x17,0x1a,0xf6,0x48,0x62,0x2e,0x84,0x89,0x07,0xe1,0x8a,0xb4,0xdd,0xa5,0x46,0x9f,0x5d,0x91,0x16,0x23,0xc2,0x81,0x99,0x4f,0x3c,0xb9,0x24,0xd6,0xcc,0xfd,0x16,0xde,0x83,0x10,0xaa,0x69,0xed,0xe4,0x36,0xed,0x54,0xd8 +.byte 0xe3,0xec,0x4e,0x3d,0x19,0xa5,0x09,0xd2,0xd6,0xd2,0x54,0x51,0x95,0xbe,0xf0,0x23,0xcc,0xeb,0x50,0x77,0x0b,0x94,0xa3,0x71,0xee,0x70,0x83,0x3b,0x87,0x07,0x53,0x89,0x0a,0x3c,0x60,0xb2,0xb8,0x2b,0x7e,0xf8,0x91,0xf9,0xc2,0xd5,0xad,0x2f,0x2d,0x9e,0xa2,0xfb,0xad,0xee,0x16,0x9d,0x0a,0x7e,0xaf,0x94,0x37,0x86,0x94,0xd2,0x09,0xcf +.byte 0xf9,0xe3,0xfe,0x26,0xd8,0xde,0xdf,0x73,0xa0,0xcb,0x75,0x6c,0x78,0xef,0x42,0xa0,0xb4,0x25,0x2d,0x1e,0xf2,0x77,0x8e,0xd0,0x91,0xdb,0xde,0xb5,0x3b,0x32,0xfb,0x4a,0x92,0x69,0x68,0xba,0x37,0xba,0xe7,0xc4,0x3c,0xe6,0xc2,0x7f,0xc9,0x33,0xbb,0x3d,0x10,0xae,0xff,0x75,0x99,0xe7,0x2a,0x92,0xc4,0x7e,0x03,0x10,0xb1,0xa7,0x71,0x88 +.byte 0x8b,0xc9,0xfe,0x73,0x17,0x44,0x06,0x6c,0x87,0xd3,0x09,0xfd,0xd2,0x9d,0x7e,0x0a,0xba,0xdc,0xab,0xd0,0xa1,0x28,0x2c,0x92,0x57,0xa3,0xfc,0x89,0xba,0xbc,0x10,0x44,0x8e,0xb6,0x86,0x20,0x1a,0xc3,0xcf,0x93,0x1d,0x33,0x08,0xf8,0x06,0x47,0x5c,0x5e,0xda,0x8e,0x2d,0x36,0xff,0xf8,0xf2,0x07,0x8d,0x99,0x6c,0xbd,0xd2,0xa0,0xe7,0x74 +.byte 0x0c,0x67,0x4a,0x66,0x06,0x02,0xa5,0x01,0x51,0x0b,0x28,0xaa,0x39,0x2e,0x62,0x8b,0x2c,0xcb,0x2b,0xec,0xec,0xe3,0xbf,0x77,0x28,0x06,0x9a,0x6c,0x2c,0xb2,0xf1,0xd5,0x65,0x37,0x4f,0x46,0x5f,0xef,0x50,0x20,0xd4,0x95,0x12,0xdd,0x38,0x21,0x34,0xe5,0x21,0xd3,0x4c,0x42,0xec,0xc4,0x9c,0x4c,0x79,0xb1,0x03,0x14,0x60,0x09,0xd3,0x52 +.byte 0x0e,0x10,0x1c,0x39,0xf1,0xeb,0x2f,0x77,0x9a,0xc2,0x4f,0xe8,0x71,0x0c,0xdd,0x3b,0x61,0x09,0xf3,0x63,0x11,0x56,0xde,0x54,0x13,0x82,0x18,0x38,0x40,0x92,0x81,0x4a,0xe5,0x3b,0x41,0x4c,0x37,0x9d,0xd9,0x87,0x9a,0x8b,0x2a,0x25,0xfb,0x0a,0x33,0xc8,0x33,0x30,0x54,0x6d,0x1a,0xda,0xea,0xa3,0x23,0x0f,0x2c,0x94,0x74,0x12,0xa3,0x96 +.byte 0x3d,0x0d,0xad,0xe0,0xe9,0x85,0xef,0xe6,0x3b,0xb3,0x52,0xcb,0x36,0xd4,0x4a,0x50,0xf3,0x08,0xf6,0x10,0x91,0xed,0x13,0x2f,0x0f,0x02,0x61,0x72,0x8a,0x73,0x49,0x3c,0x07,0x8d,0x80,0x4b,0xb7,0xdf,0x43,0x4f,0x31,0x95,0x67,0x25,0x11,0x37,0x6e,0x79,0x6d,0xbd,0x59,0xb6,0x53,0xf1,0x0c,0x86,0x79,0x7b,0xb6,0x9a,0x34,0x92,0xaf,0x01 +.byte 0x3e,0x25,0x90,0xc9,0x3f,0x73,0x67,0xb3,0x33,0xd5,0xa6,0xef,0x0d,0x85,0xcb,0xc3,0xec,0x5b,0x9a,0xcc,0x5d,0x8b,0xac,0x60,0x81,0x1f,0xea,0x12,0xac,0x27,0xc2,0xf6,0x49,0xcd,0xc2,0xe2,0xd8,0x67,0x0a,0x0d,0x65,0x5a,0x46,0x19,0x8e,0x68,0x37,0xbb,0x6d,0x2b,0x2f,0x9f,0x7a,0xaf,0x27,0x19,0x26,0xeb,0x47,0x16,0xdf,0x70,0x07,0x84 +.byte 0x69,0x4b,0xb8,0xdf,0x77,0x85,0x13,0x44,0xda,0x65,0xac,0xeb,0x23,0x71,0x0b,0x45,0x8a,0xc0,0x8c,0x12,0x42,0xb2,0x24,0x8c,0x13,0x64,0x30,0x47,0x80,0x69,0x73,0xb7,0xb2,0xd7,0xb0,0x11,0x6d,0x37,0x05,0xfd,0xbc,0xf2,0x42,0xc6,0x00,0x3d,0xd8,0x17,0x58,0x38,0x3a,0xf2,0x11,0x72,0x14,0xbf,0x4a,0x90,0xf7,0x83,0x59,0x41,0x7c,0xe6 +.byte 0xfb,0xf6,0x87,0x52,0xe2,0xa1,0x76,0xa8,0xb4,0x5f,0x35,0xb8,0x6d,0xee,0x27,0x50,0x55,0x8a,0xbe,0xda,0x6d,0xa1,0xe2,0x3e,0xf6,0xaf,0x6a,0x67,0xc2,0x9e,0x5c,0x13,0xd1,0x2f,0xdc,0xca,0x29,0x96,0xee,0x8e,0xac,0x04,0x6b,0x44,0x99,0x92,0x81,0x2c,0x73,0xa5,0x5d,0xcd,0xaa,0x20,0x51,0x36,0x62,0xc8,0xac,0x24,0x54,0x40,0x8e,0xd4 +.byte 0x5e,0xd9,0xb7,0x88,0x64,0xb9,0x9a,0xcc,0xfe,0x78,0xbe,0xd7,0x95,0x33,0xa3,0x5f,0xff,0x3f,0xcd,0x90,0x83,0xd0,0xb6,0xcf,0x90,0x9e,0x7f,0xf1,0x3b,0x25,0xa0,0xa1,0x3f,0xfb,0xcf,0x0d,0x36,0x36,0x90,0x24,0x73,0x1d,0xeb,0x2b,0x67,0xd0,0xf9,0x01,0xe9,0x3f,0xb0,0xa4,0xd3,0xf5,0x56,0xd9,0xb0,0x17,0xe4,0x78,0x90,0x1c,0x16,0xe2 +.byte 0xb4,0xd8,0x1a,0xb6,0x48,0xa3,0xc6,0x06,0xee,0x0c,0xea,0x07,0xc1,0x48,0x11,0xe5,0x9e,0x2f,0xb8,0x47,0xcf,0xac,0x32,0x35,0x8b,0xce,0x4f,0xe4,0x1a,0x8b,0xc9,0x7b,0x9b,0x07,0x27,0xf4,0x8e,0x2c,0xb5,0x61,0xef,0x85,0x7a,0x39,0xb3,0x03,0x7a,0xac,0x8f,0x64,0x53,0xd8,0x3b,0x4d,0xf5,0x80,0xab,0x2b,0x81,0xa1,0xb1,0xf0,0x2d,0x46 +.byte 0xfc,0x8d,0x80,0x62,0x48,0xe0,0xee,0xee,0x87,0xc6,0xdb,0xda,0xc4,0xb5,0xe7,0x10,0xc3,0x70,0x3a,0xbe,0x8d,0x34,0xa8,0x8b,0x02,0xf6,0x11,0xbc,0x92,0x66,0x58,0x89,0x83,0xff,0x43,0xd1,0x89,0x02,0x69,0xea,0xc7,0xc8,0x4f,0x97,0xca,0x22,0x29,0x1d,0x2c,0x74,0x5e,0x21,0xdc,0x40,0x02,0xe9,0x7f,0x66,0x4e,0x9e,0x7d,0x59,0xae,0xa7 +.byte 0xd4,0x1f,0xde,0xf3,0x70,0xcf,0x81,0xea,0x3c,0xab,0x4e,0xb1,0x12,0x80,0x22,0xc0,0x36,0x7c,0xb9,0x15,0x9a,0x01,0x72,0x67,0xd5,0xbd,0xef,0x68,0x37,0x18,0x94,0xb9,0xec,0x09,0xf9,0x47,0x8e,0x38,0x2e,0xe0,0xb1,0xe8,0x63,0xae,0x44,0x84,0xf2,0xc8,0x15,0x5d,0xff,0x58,0xf4,0x9b,0x48,0x4a,0x30,0x1b,0xb9,0xea,0x1a,0xce,0xc7,0xaa +.byte 0xd2,0x3d,0x0e,0x3a,0x08,0xa7,0x5b,0x57,0x15,0x4f,0xfd,0x96,0xd0,0xa3,0xd3,0x98,0x9e,0xd3,0xc3,0xc3,0x00,0xc2,0xf3,0xdc,0xf8,0x25,0x59,0x42,0x09,0x19,0xa3,0x6c,0xb6,0xcf,0x22,0x4c,0xb7,0x0d,0xd3,0x8f,0xf0,0x49,0xae,0xb8,0xcd,0xdc,0x0c,0x99,0x26,0x58,0x9f,0x6b,0x59,0xbb,0xa2,0xc3,0x6b,0xd6,0xb6,0xf0,0xe1,0xfa,0x94,0x67 +.byte 0xe9,0x21,0x92,0x95,0xe1,0xa3,0x76,0x07,0x98,0x43,0x29,0x98,0x3e,0xc5,0x58,0x88,0x7a,0xbb,0xb0,0x58,0x18,0x53,0x35,0xde,0x47,0xf9,0x05,0xa2,0x46,0x67,0x1c,0x09,0x9c,0x16,0x10,0x2e,0xb1,0xd3,0xda,0xea,0x20,0x34,0xf7,0xeb,0x35,0xfb,0x9b,0x74,0x38,0xbf,0xc1,0x97,0xd3,0x7e,0xe8,0xc1,0xf6,0x83,0x76,0xc0,0x94,0xa0,0xa1,0x7d +.byte 0x48,0x13,0x9a,0x08,0xe8,0x8e,0xa4,0x2b,0x95,0x61,0x12,0xaf,0xbd,0xc9,0x81,0x26,0xef,0x87,0x06,0x7b,0xc3,0x52,0xc2,0xd5,0xde,0xf3,0x55,0x34,0x71,0xc6,0xe3,0xe9,0xf7,0x5e,0x0b,0x6e,0xd4,0xee,0xeb,0xb3,0xa0,0xf9,0x99,0x33,0x14,0x5d,0x28,0x1a,0x57,0xcf,0xf5,0xa9,0x92,0x08,0xa6,0x10,0x6d,0x5a,0xd5,0x6b,0xe0,0x15,0x17,0x06 +.byte 0x72,0x32,0xcd,0xc7,0x79,0x1b,0x4c,0x12,0x78,0xea,0x88,0xb3,0x1a,0x4c,0x9a,0x3c,0xbe,0x41,0xe9,0x69,0xb5,0xe3,0x4c,0xd7,0xce,0x86,0x3b,0xca,0x3f,0xf6,0xaa,0xa2,0xc4,0x34,0x41,0x89,0x2c,0x9d,0xdd,0x0e,0x01,0x0c,0x35,0xa0,0xe8,0x7f,0x26,0xcd,0x0c,0x27,0x16,0x70,0xaf,0x8d,0x30,0xcf,0xe5,0x22,0x21,0x95,0xf6,0x98,0x84,0x2e +.byte 0x03,0xf2,0xdc,0x7a,0x00,0x1a,0xed,0x6c,0x5f,0x8d,0xb6,0xed,0xa9,0x84,0xb0,0x12,0x35,0xbf,0x55,0xe2,0xe5,0xae,0x52,0x03,0x9a,0xf9,0x69,0x30,0xd5,0x58,0x1b,0x88,0xf2,0x63,0xff,0xfd,0x47,0x47,0x86,0xae,0x7b,0x18,0xd1,0x67,0xcf,0x49,0xb6,0xfd,0x8b,0x76,0xbe,0x2d,0x91,0x6c,0x52,0xd4,0x85,0xec,0xd9,0x1b,0x73,0x0b,0x3f,0xfa +.byte 0x83,0x70,0x0a,0x5f,0xd6,0x91,0x52,0x33,0xe0,0x92,0x0b,0x99,0x52,0xa8,0x59,0xe1,0x71,0xfa,0x45,0x29,0x25,0x56,0xd1,0xc2,0xf9,0x66,0x5c,0x48,0x41,0x2a,0xe8,0x1e,0x34,0x04,0xbd,0xd8,0xe6,0x7f,0x87,0x88,0x37,0x14,0x91,0xea,0x48,0x30,0x0b,0x93,0x68,0x37,0x8c,0x75,0x8c,0x3d,0x3d,0x36,0xa2,0x83,0xf4,0x4c,0x27,0x59,0xef,0x9e +.byte 0x8d,0x98,0xcc,0x97,0x0c,0x49,0x7b,0x32,0xa7,0x32,0x50,0x7d,0x47,0x6e,0x53,0xca,0xa2,0xec,0xa7,0x62,0x6b,0x08,0x50,0x72,0x5c,0x92,0x71,0x35,0xde,0x0b,0xde,0x15,0xc6,0x46,0xa1,0x3a,0x82,0x09,0xe7,0xcd,0x7b,0x11,0x1e,0x34,0x6d,0x7f,0x3e,0x8c,0xc9,0x27,0x88,0xc9,0x35,0xe7,0x1d,0x0a,0xb1,0x5e,0x85,0xfa,0x6e,0x47,0xa3,0x4f +.byte 0x22,0x84,0x16,0x36,0x84,0x1b,0x28,0xe8,0x28,0xdb,0x0b,0x41,0xca,0xf1,0x93,0xd9,0x3f,0x3c,0xe9,0xbc,0x46,0x0b,0x8c,0x34,0x04,0x3a,0xd4,0xfc,0x87,0x1b,0xd6,0x9a,0xe4,0x01,0x9e,0xf0,0xa9,0x83,0xca,0x72,0xfe,0x25,0xb3,0xc8,0x9a,0x07,0x84,0x61,0xea,0x6a,0x11,0x3f,0xaa,0x85,0x19,0x89,0xa7,0x1b,0x47,0x85,0x1e,0x72,0x29,0xc3 +.byte 0x43,0x2a,0xc7,0xcc,0x6d,0xec,0x16,0x12,0xfa,0xa3,0xa0,0xce,0x3f,0x64,0xb2,0x40,0x90,0x57,0x0f,0x0b,0xd7,0x21,0xe8,0x9d,0x12,0xf8,0x77,0xd8,0x88,0xf9,0xb7,0xdc,0x82,0xb4,0x07,0x52,0x01,0xdf,0xb5,0x58,0x5f,0x39,0x53,0x66,0x52,0xaf,0xb0,0xa5,0x3a,0xa3,0x8b,0xc2,0xca,0xd7,0x46,0x31,0x95,0xcc,0xa6,0xfb,0xb0,0x2b,0x1e,0x1e +.byte 0x3a,0x99,0xc0,0x67,0x98,0x0d,0xb0,0x61,0x58,0x10,0x1f,0x47,0x7d,0x4d,0x11,0x69,0xf5,0xe5,0x6a,0xbf,0xbc,0x83,0x4c,0xef,0xef,0x8f,0x15,0x08,0x32,0xae,0x47,0x0c,0x9f,0xfd,0x10,0xa5,0xc6,0xe1,0x11,0x26,0x20,0xfe,0xb4,0xd6,0x7a,0xd3,0x16,0x5c,0xaf,0x0f,0xd6,0x12,0x44,0x1e,0x99,0x46,0x6d,0x22,0x35,0x52,0x90,0xb7,0xe7,0xc9 +.byte 0xb4,0xdd,0x18,0x86,0x4f,0x94,0xa2,0x7c,0x10,0xb1,0x00,0xb9,0xea,0x30,0x6a,0xfe,0x84,0xb8,0x18,0x28,0xd0,0xa3,0x1b,0xfa,0x65,0xbe,0x67,0x0f,0x0d,0x28,0x32,0x05,0x3c,0xf1,0x15,0x9c,0x54,0x92,0x41,0x4f,0x7d,0x32,0x01,0x49,0x8d,0x83,0x01,0x51,0x70,0x24,0x7e,0x53,0xf8,0x69,0x96,0x56,0xd4,0xe5,0xe7,0x37,0xd5,0x5b,0x9a,0x2d +.byte 0x41,0x33,0x52,0x84,0x1c,0x13,0xae,0x67,0x96,0x9f,0x96,0x5f,0x6a,0xc4,0x55,0x4d,0x68,0x7c,0x27,0x0b,0xc9,0x15,0x01,0x47,0x40,0x42,0x45,0xaf,0x33,0x20,0x62,0x53,0xed,0xe0,0x0e,0x84,0xaa,0x26,0x76,0x30,0x0d,0x4d,0x64,0x5b,0x68,0x4c,0x04,0xe1,0xe3,0x57,0x66,0x88,0xd7,0xe5,0x3b,0x5c,0x7d,0x70,0x56,0xe1,0x18,0x48,0x18,0x80 +.byte 0xab,0x4d,0xd8,0x16,0xdb,0x31,0x58,0x6a,0xea,0xd7,0xca,0x80,0x42,0xa0,0x02,0x4c,0x99,0xdc,0xff,0xa4,0x4e,0x99,0x8e,0xba,0xae,0x9b,0xc4,0xe5,0x80,0xce,0x51,0x26,0x5c,0x83,0xa4,0xdb,0x4c,0x98,0x20,0xc6,0x09,0xd1,0x11,0xab,0x29,0x48,0xc9,0x58,0xb4,0xa8,0xd0,0x8c,0xe5,0x5f,0xa8,0x80,0x19,0xc3,0x8c,0xb1,0xb6,0xae,0xfc,0x80 +.byte 0x99,0x35,0x49,0xfb,0x8c,0xae,0xb0,0x28,0x74,0x6a,0xf5,0xc4,0x2a,0x23,0x6e,0x09,0x1e,0xe6,0xdb,0x97,0x65,0x89,0x4f,0x45,0xbd,0x45,0x35,0x08,0x34,0x3f,0x13,0x59,0xf8,0x78,0x26,0xc0,0x26,0x00,0x24,0xa1,0xda,0x66,0xd8,0x87,0x03,0x3a,0x31,0xd1,0x66,0xc1,0xdc,0x7b,0x2a,0x67,0x57,0x5b,0xfb,0xfb,0x07,0xe9,0xdc,0x3a,0x2e,0x03 +.byte 0x3f,0x63,0x1c,0x1d,0x28,0x85,0x8e,0xbf,0xec,0xc6,0xcd,0x6c,0xf6,0x86,0x12,0x0f,0x92,0x03,0x70,0x14,0x5c,0x48,0x1c,0x13,0xe8,0xbd,0x32,0xfd,0xa5,0xfd,0x93,0xa8,0x64,0x50,0x5d,0x35,0xcd,0x08,0x31,0x90,0xd2,0x33,0xb4,0x42,0x92,0xb5,0x45,0x42,0x32,0x1b,0x25,0x29,0x18,0x04,0xf2,0xea,0x41,0x8b,0xcd,0x8c,0xb2,0xc6,0x30,0x06 +.byte 0xd6,0x57,0x69,0x5f,0x34,0xf4,0xcd,0xc9,0xf5,0x36,0x7d,0x91,0x11,0x71,0x8c,0xa1,0xda,0x5f,0xca,0xd9,0x23,0xf0,0x77,0x7d,0xcc,0x01,0x70,0x3b,0x9e,0x3d,0x65,0xb0,0x44,0x41,0x5d,0x4e,0x91,0x4b,0xfd,0x8b,0x47,0xc7,0x36,0x41,0xf1,0x58,0xb0,0xd9,0xb6,0x62,0x3e,0xd6,0x24,0xa6,0x87,0xfe,0x63,0x0b,0x29,0x3c,0x80,0xd4,0x93,0x81 +.byte 0x4a,0x41,0x85,0x9d,0xe6,0x36,0xd0,0xdc,0x0b,0xb5,0x5d,0x8b,0x22,0x7e,0xaf,0x11,0xb9,0xd1,0x49,0xdf,0xdb,0xde,0xa8,0xc7,0x9c,0x01,0x6b,0xd7,0x86,0xf0,0x79,0x3b,0x3a,0x89,0xd0,0x02,0x34,0x55,0x1d,0x27,0x17,0xca,0x44,0x47,0xc2,0x06,0x69,0x77,0xc4,0x63,0x80,0x05,0x99,0x2e,0x7b,0x57,0x3c,0x86,0x5f,0x38,0xe1,0xb2,0x4c,0x33 +.byte 0x30,0x4b,0x90,0x68,0xc0,0xe1,0x20,0x12,0x25,0xda,0xfc,0xc3,0x49,0x16,0x96,0x80,0xd2,0xae,0xcd,0x5e,0x1a,0x02,0x07,0x97,0xaf,0x97,0xf9,0xd0,0x0c,0x23,0x27,0x08,0x14,0x19,0xdc,0xe9,0x11,0x6c,0x58,0x3c,0xfb,0xbc,0xd4,0x18,0x0d,0x44,0xa8,0x2b,0xe9,0x66,0x3e,0x06,0xe4,0xb6,0xdd,0x00,0xd6,0xd1,0x7b,0xce,0xcd,0xe1,0xf0,0x35 +.byte 0x1c,0x96,0xff,0xf1,0x62,0x95,0x35,0x35,0xcf,0x37,0x8c,0xdc,0x09,0xac,0xaa,0x95,0x0f,0x7e,0x9f,0xc0,0xbe,0x06,0xe8,0xf6,0x2c,0x1c,0x19,0xb5,0xdf,0x0a,0xd9,0xfc,0x83,0x99,0xad,0xdb,0x5e,0x8f,0x7f,0x1d,0x3e,0x25,0x7a,0x3e,0x25,0xf8,0xb3,0x43,0xfe,0x13,0x8c,0x58,0xb7,0x5a,0xc8,0xf6,0x7a,0x4a,0x63,0x57,0x2c,0x53,0x06,0x2d +.byte 0xae,0x16,0xb5,0xac,0x1d,0x21,0x34,0xbb,0x26,0x8a,0x09,0x93,0x2c,0x1c,0x38,0x86,0xda,0x49,0x24,0x83,0xdd,0xa8,0x32,0xdf,0xcb,0x74,0x00,0x10,0xe0,0x87,0x48,0xdb,0xfb,0xce,0xd9,0xe8,0xd3,0x73,0xcb,0x6c,0x7f,0xbf,0xba,0xe4,0x7f,0x78,0xb1,0x65,0xf7,0xdc,0x0e,0x71,0x1d,0xdb,0x1f,0x3e,0x4e,0x2d,0x56,0x12,0x7e,0x53,0xe9,0x77 +.byte 0x24,0xa7,0xf4,0x02,0x47,0xf1,0xa1,0x0f,0xc7,0xe2,0x5c,0x4b,0xf1,0x8b,0xda,0x05,0xe6,0x66,0x08,0x1c,0x84,0xa5,0x75,0x3a,0x6f,0xc7,0xd3,0x50,0x5d,0xce,0x09,0x9e,0x8e,0xa8,0x1a,0xc7,0x1d,0x28,0x13,0x80,0x3b,0x36,0x0c,0x3b,0x9c,0xea,0x53,0xe6,0xe4,0x35,0x5e,0x15,0x1a,0xa5,0x28,0x70,0x9c,0xde,0xbc,0xd6,0x04,0x94,0xcb,0xd8 +.byte 0x29,0xe5,0xc6,0x94,0x61,0xe0,0x73,0x61,0x66,0xa9,0x85,0x23,0xb5,0x3e,0x7f,0x4b,0x54,0x20,0x49,0x05,0x88,0x09,0xe4,0xee,0x25,0xeb,0x86,0x5a,0x17,0xed,0xed,0xe7,0x25,0xfe,0x4f,0x89,0x05,0x2f,0xfb,0x1c,0x19,0x5c,0x66,0x47,0xf9,0x53,0x30,0xa8,0x64,0x97,0x4a,0x39,0x9a,0x4a,0x88,0x30,0xce,0xdf,0x67,0xae,0xa9,0x2c,0x0e,0xf3 +.byte 0x12,0xe0,0x6a,0xaa,0xa1,0x2e,0x85,0x0f,0x96,0xe6,0x6a,0x33,0xb6,0xf0,0x16,0xb6,0x1e,0x44,0xac,0xdf,0x16,0xd5,0x8e,0xaf,0x65,0x9c,0xe9,0x65,0xea,0xe8,0x35,0x91,0xca,0x2e,0x8d,0xc7,0x6b,0x2f,0xae,0xbc,0xc5,0x49,0xfd,0x2a,0x2d,0xec,0xd8,0x67,0x56,0x68,0xa2,0xdd,0x5d,0x51,0x75,0x30,0x2e,0x56,0x50,0x4d,0xa4,0x6f,0xe1,0xb4 +.byte 0xa5,0x9b,0x35,0x3b,0xc8,0x1a,0xd5,0x78,0x22,0x49,0x44,0x27,0xe7,0x67,0x60,0x91,0xb0,0x08,0x1c,0x83,0x3c,0x64,0x27,0x15,0xcf,0xbd,0x69,0xfe,0x56,0xff,0xab,0x56,0x1d,0x79,0xe6,0xc3,0xbd,0xce,0x75,0xf0,0x4f,0xa7,0x7a,0x9a,0x2e,0x7a,0xd7,0xf7,0xac,0xfb,0x87,0x8e,0x87,0xc6,0x10,0x3c,0x4c,0xb2,0xe3,0xf7,0xae,0x7d,0xaa,0x0c +.byte 0x46,0x17,0xce,0x61,0xce,0x73,0xc5,0x0d,0xdb,0x8e,0x8c,0x21,0x7b,0x7c,0x09,0x34,0x5d,0x3f,0x44,0xf0,0x16,0x7c,0xe2,0xdd,0xf2,0x07,0xd6,0x53,0x3c,0x0a,0xe9,0xfd,0x7a,0x41,0x13,0xcf,0x7c,0xa2,0x11,0xca,0xb5,0xdb,0x10,0x21,0x68,0x02,0x85,0xb6,0xe3,0xd4,0xb9,0xf7,0x9c,0xdf,0x54,0xaf,0x48,0x67,0x3e,0xd2,0x04,0xde,0xce,0x53 +.byte 0x1a,0x9b,0x6b,0xd4,0x5e,0xb2,0xd0,0xa5,0xc8,0x7b,0x2e,0xb3,0xd8,0x46,0xc2,0x57,0x69,0x69,0xe6,0x54,0xee,0xf9,0x48,0x04,0x4e,0x11,0x2e,0x80,0x53,0x87,0x61,0xc7,0x1b,0x75,0xab,0xac,0x5f,0x17,0xda,0x25,0x5f,0x66,0xa0,0x59,0xfb,0xc2,0xf0,0xbf,0xc2,0x53,0xdc,0x8e,0x2d,0x41,0x13,0x7c,0x29,0xf0,0x80,0x70,0xb5,0x07,0x14,0x6c +.byte 0x5f,0x3a,0x66,0x1a,0xf8,0x7f,0xb4,0x8e,0x55,0xe8,0x2d,0x5b,0xec,0x65,0xe6,0x7b,0xf2,0xde,0xa2,0x51,0x45,0x9a,0x8a,0xfa,0xba,0x0c,0xcb,0x28,0x27,0x2c,0x01,0x81,0x38,0x5b,0x2e,0xbb,0x31,0x37,0x77,0xe7,0x52,0x2c,0xf9,0xb8,0x42,0x76,0x49,0x81,0xd4,0x64,0xd0,0x86,0xd4,0x3d,0x2c,0x74,0xca,0x4d,0xbb,0xa6,0x99,0x9d,0x79,0xd6 +.byte 0x52,0x5e,0xfd,0xd4,0xc2,0x50,0x48,0x2e,0x4d,0x9c,0x4e,0xe6,0xbe,0x57,0xdb,0x28,0xf2,0xc0,0x25,0x9f,0x26,0x0e,0xc7,0x61,0xa0,0x77,0x7c,0x3d,0xf4,0xec,0x70,0x6c,0x06,0x37,0x3f,0xa2,0x3c,0x70,0xca,0x53,0xcb,0x56,0x51,0x0f,0x30,0x20,0x16,0x21,0xac,0x3a,0xe5,0x78,0x4c,0xe2,0x8e,0x9f,0x6e,0x36,0xb2,0x3d,0xb2,0x15,0x10,0x06 +.byte 0x8e,0xff,0xa4,0x62,0x8e,0xa7,0x61,0x56,0xe7,0x27,0xa6,0x72,0x24,0x0b,0x47,0xca,0xa6,0x6b,0x74,0x5f,0x5e,0x80,0x64,0x47,0x1f,0x95,0x20,0x99,0x13,0x66,0x99,0x92,0xe7,0x82,0xdb,0xa1,0x97,0xdc,0x2d,0x35,0xa2,0xc9,0x91,0xf4,0x12,0x91,0xdd,0xb3,0xb4,0x7a,0x34,0xa0,0xd6,0x02,0xb1,0x38,0x42,0xad,0x53,0xd4,0xd1,0x82,0xd0,0x3f +.byte 0xb4,0x32,0x7a,0x70,0xe2,0x6e,0xae,0x9c,0x99,0xe3,0x62,0x6e,0x7d,0x01,0xcd,0x3b,0x4e,0xb0,0x57,0x9d,0x47,0x6f,0x2a,0x62,0x12,0x44,0x28,0xfd,0x78,0x00,0x08,0x9a,0x2b,0x5b,0x3f,0x62,0x24,0x94,0x75,0x5c,0x1e,0x8b,0xc4,0x3c,0xbc,0x7d,0xe8,0x10,0xbf,0x9d,0x23,0x52,0xc8,0x65,0xe8,0x39,0x8a,0x97,0x70,0xbb,0xa4,0x09,0xf8,0x29 +.byte 0xd2,0x36,0x7a,0x46,0x4a,0x19,0x68,0xe8,0x57,0xc8,0x3c,0x88,0xa2,0x8c,0x01,0xa5,0x21,0x32,0xff,0x6c,0xa7,0x6f,0x07,0x94,0xc3,0x07,0xfc,0x09,0x1a,0x0c,0xe4,0x01,0x41,0x51,0x80,0xf2,0x47,0x41,0xe7,0x8d,0x97,0x34,0xe4,0xdf,0x21,0x17,0x27,0x41,0x8c,0x31,0x03,0x5e,0xee,0x36,0xaf,0x37,0x4f,0x89,0x92,0x6b,0x03,0xb1,0x19,0xc1 +.byte 0x26,0xb1,0x32,0x68,0x6f,0x9e,0x1c,0xc4,0x7f,0xce,0x1f,0xa9,0xd7,0xd8,0x19,0xd4,0x76,0xd5,0xe5,0xe6,0xeb,0x99,0x45,0xe6,0x72,0x2e,0xdb,0x13,0x2b,0x4d,0xdd,0x39,0x2a,0xd4,0x0f,0x26,0x49,0x81,0xaa,0x9d,0x6a,0xad,0x0e,0x58,0x81,0xc8,0x74,0x60,0xb3,0x29,0x92,0xc4,0x2e,0x3c,0x2b,0xdd,0x7f,0x13,0x91,0x84,0xa4,0xc5,0x8e,0x75 +.byte 0xcd,0x83,0x4b,0x9f,0xfa,0x6e,0x29,0x1d,0xa5,0xfd,0x97,0x6e,0x36,0xcb,0x50,0x3f,0x68,0xac,0xec,0xee,0x00,0xb8,0x38,0xb9,0xcb,0x8b,0xf6,0x1c,0x45,0x28,0x8d,0x6f,0x5a,0x97,0x64,0x9c,0x52,0x40,0xff,0xbb,0xf6,0x46,0x1f,0xcc,0xad,0x93,0xcb,0x3a,0xce,0xc9,0xae,0x03,0x04,0xe0,0x9b,0x54,0xde,0xe0,0xdc,0xbf,0x9f,0x4e,0xb6,0xc4 +.byte 0x0f,0x1b,0x95,0x92,0xbc,0x8e,0x70,0x2b,0xbf,0x8d,0xf1,0xdd,0x4c,0xad,0xb6,0x5d,0xbd,0x36,0x5a,0x3c,0x0e,0x0b,0x83,0x1a,0x5d,0x0a,0xaf,0x0b,0x69,0x46,0xb4,0x42,0x3c,0x5c,0xe2,0x7d,0x75,0x3c,0x6b,0x03,0x32,0x1b,0xd0,0xe9,0xe7,0xe3,0x87,0xe8,0xd2,0x39,0x3b,0xe0,0x5f,0x8e,0xf7,0xeb,0x89,0x2e,0x0f,0x3f,0x1e,0xf3,0x34,0x0d +.byte 0x86,0x6b,0x28,0xbb,0x7c,0x7a,0x61,0xb2,0xab,0xfe,0xbc,0xba,0xaf,0xf5,0xab,0x2d,0xe9,0x9b,0x88,0x8b,0xd0,0x2d,0x3e,0xf6,0x12,0x25,0x24,0x63,0x60,0xfb,0x32,0x23,0x5a,0xbf,0x1a,0x3e,0x07,0xb9,0x46,0xe6,0x09,0x30,0xa8,0x59,0x87,0x14,0xcc,0x94,0x0b,0xa4,0xac,0x31,0x51,0x04,0xde,0xda,0xe4,0x50,0x5a,0xa2,0x9e,0xae,0x3f,0xed +.byte 0xaf,0x9d,0xc7,0x6f,0xf3,0x05,0x2b,0xb8,0xd9,0xcc,0xe9,0xc1,0x7e,0x9c,0xbb,0x86,0xe3,0x3b,0xa0,0xc3,0x0b,0x38,0x28,0xf1,0x83,0x50,0xc8,0xf2,0x1f,0x05,0xcc,0x1b,0xd1,0x59,0xff,0x73,0xb0,0x13,0x75,0x59,0x22,0x4d,0xac,0x65,0x75,0x47,0x3b,0x37,0x91,0xf1,0x40,0x6b,0x7b,0xe8,0x72,0xe5,0x11,0x12,0x23,0x5a,0x2c,0x9c,0xa2,0xe5 +.byte 0x14,0x5b,0x17,0xb5,0x41,0x95,0xdd,0x0d,0x0b,0x70,0xba,0xbc,0xb7,0x55,0x37,0x77,0x1e,0x32,0xf4,0xba,0x57,0x81,0x0b,0x64,0xf6,0x1f,0x57,0x99,0xeb,0xb2,0x06,0x9c,0x6c,0x4f,0x1c,0xbf,0xca,0x79,0xeb,0xff,0x6e,0x32,0xaf,0x0e,0x2b,0xf3,0xbb,0x75,0xf8,0x80,0x9f,0x95,0xb3,0x35,0x63,0xe0,0x92,0x8f,0x50,0xa3,0x41,0x38,0xb7,0x7b +.byte 0xa1,0x3b,0xde,0x69,0x85,0x36,0xb7,0x44,0xb3,0xb2,0xc5,0x85,0xd3,0x9a,0x78,0x26,0x97,0xc1,0x58,0xfd,0x0f,0x27,0x74,0x93,0x0e,0x54,0x23,0x6f,0x5c,0x48,0x38,0xb9,0xb5,0x7d,0x17,0x23,0x5a,0x36,0x32,0xdd,0x40,0x7e,0x1c,0xb4,0x65,0x84,0x83,0xcc,0x6e,0xa0,0x3a,0xa6,0xbe,0xf8,0xca,0x55,0xf4,0x0a,0x65,0x83,0x52,0x14,0x9d,0x10 +.byte 0x4a,0x31,0xe7,0x05,0x99,0x01,0xb3,0x01,0x47,0x64,0xa2,0xee,0x8f,0xf1,0x77,0x91,0x94,0xa3,0xad,0xfc,0xfa,0x7e,0x92,0x90,0x41,0xb6,0x2a,0xb7,0xa1,0xfa,0xf3,0x74,0x8f,0x27,0xe1,0x48,0xe1,0x96,0xff,0x85,0xd4,0x40,0x76,0x15,0x2a,0x6c,0xce,0xdb,0x72,0x0b,0xf6,0x33,0x5f,0xa0,0x72,0xf1,0xf1,0x92,0xaa,0xfc,0x75,0xef,0x11,0x2b +.byte 0x71,0x2f,0x6b,0xe4,0x70,0x13,0xa3,0xbe,0xfc,0xa4,0x35,0xc5,0xa7,0x2a,0x94,0x34,0x7a,0x15,0x7e,0x0d,0x8b,0x92,0xe6,0xfb,0x12,0x77,0xf9,0xe3,0x0e,0xce,0x1e,0x84,0xcd,0x3a,0xce,0x44,0x65,0xe8,0x6c,0x0b,0x86,0x70,0xe9,0x66,0x18,0x37,0x3d,0xc0,0xc0,0xcb,0xe0,0x7b,0x16,0xda,0x89,0xc9,0x8e,0x83,0xc4,0x21,0x40,0x65,0xd2,0xe8 +.byte 0x3f,0xa5,0xda,0xe9,0x4b,0x2e,0x1d,0x89,0x4d,0x3b,0x84,0x4b,0xfd,0x0e,0x2c,0x50,0xe2,0x01,0x7d,0xec,0x12,0x81,0x49,0x9b,0xe3,0x14,0xd8,0xb4,0xe3,0x44,0x06,0x7f,0xbf,0x92,0xd4,0xb8,0x65,0x1f,0xdb,0x7a,0xb4,0xd6,0x9e,0x0c,0xe0,0xc2,0xc9,0xe8,0xc9,0xf8,0x34,0xff,0x7b,0x1a,0x0d,0xc9,0xc7,0x77,0xf2,0x44,0x79,0xdb,0xef,0x31 +.byte 0x61,0xd4,0x85,0x0d,0x0f,0x11,0x29,0xfb,0x07,0xe0,0x83,0x11,0x81,0xbb,0xe0,0x6e,0x1c,0x0a,0x31,0xe3,0x29,0x53,0x91,0xab,0xea,0xc8,0x2f,0xaf,0x96,0xe7,0x64,0x8b,0xfd,0x4f,0x49,0xf5,0x1f,0x93,0x3b,0x32,0xdf,0x0c,0x1d,0x8e,0x33,0x15,0x00,0x7c,0x0c,0x4b,0x95,0xd5,0x09,0x8f,0x48,0xc3,0x6e,0xdc,0xd8,0x5d,0x36,0x53,0xc2,0x19 +.byte 0xef,0xd7,0x50,0x0d,0xa2,0xc9,0x39,0xd1,0xef,0xe4,0x26,0x30,0x27,0x77,0x79,0x85,0x18,0x39,0xb7,0xb7,0xb6,0xba,0xf2,0x1f,0xa4,0xee,0x53,0x7b,0x43,0xff,0xd6,0x1c,0xa8,0x32,0xb7,0xfb,0x9b,0x45,0x6f,0x0f,0x60,0x62,0x5c,0xfe,0x02,0x5d,0x11,0xeb,0xe5,0x27,0xde,0x75,0xd4,0x11,0xbb,0xa4,0x7f,0xa0,0xb6,0x23,0x8a,0xbb,0x75,0x3c +.byte 0xba,0x8b,0x3d,0x61,0x93,0xc2,0x1b,0x6f,0x79,0x93,0xc2,0x22,0x4c,0x48,0xe9,0x94,0x6e,0xed,0x2c,0x1d,0x51,0x0e,0xa6,0x69,0x1d,0x62,0xeb,0x67,0x47,0x5d,0x2f,0xa8,0x47,0x4f,0xe7,0x2f,0x65,0x92,0xd7,0x55,0xc1,0x46,0xfe,0x1d,0xfc,0xef,0x26,0xaf,0x3a,0x18,0x63,0x02,0x4d,0x8b,0xf4,0x24,0x99,0x3f,0x1a,0x74,0xd2,0x8e,0xd8,0x9e +.byte 0xd6,0x3b,0xf9,0xce,0x67,0xa3,0xa6,0x0a,0x74,0x21,0x4e,0x0e,0x15,0x07,0xb6,0xbf,0xa2,0xcf,0x6e,0xf7,0xfa,0x49,0x98,0xfa,0xa0,0xf7,0xf0,0xd8,0x50,0xbf,0x6f,0x64,0x93,0xac,0xe0,0x88,0x04,0x04,0x74,0xa4,0xdd,0x9f,0x75,0xfe,0x30,0x37,0x77,0x09,0x1c,0xfc,0x54,0x47,0x4d,0x3f,0xda,0xfe,0x14,0x50,0x19,0x5e,0x88,0x4a,0xe9,0xcb +.byte 0x5e,0x60,0x4e,0xef,0x5b,0x15,0x10,0x3b,0x1d,0x98,0x43,0xe4,0xbe,0x92,0xc6,0x8f,0x04,0x0e,0x04,0x16,0x68,0x82,0x1c,0xfe,0x30,0x9a,0xd2,0x4b,0x25,0xd7,0xed,0x19,0x22,0x06,0x09,0x3b,0x26,0xa6,0x9a,0x17,0x65,0x01,0x8f,0x70,0x8a,0x83,0x2a,0xa3,0xbf,0xeb,0xf9,0x3f,0xf3,0x5a,0x3f,0x62,0x86,0x6a,0x3b,0x3b,0xe3,0x43,0xc8,0x4c +.byte 0x79,0x46,0xd3,0x9f,0x98,0x0d,0xac,0x11,0xf9,0xa3,0x46,0xe1,0xea,0x8c,0x1d,0x26,0x5e,0xca,0xd1,0x84,0x3b,0x01,0xb2,0x3d,0xe8,0xe5,0x8f,0x78,0x41,0x76,0xe9,0x18,0xcd,0x34,0xd9,0x48,0xb0,0x34,0xda,0xc2,0x34,0x3a,0x58,0x9d,0x12,0xa7,0x2a,0x73,0x40,0xc5,0x28,0x67,0xef,0x1a,0x7a,0x39,0x45,0x86,0x02,0x47,0xb8,0xde,0xc9,0x6b +.byte 0x78,0x7a,0x01,0x48,0xa8,0xc6,0xc4,0x57,0x52,0xa9,0xad,0x8e,0x4e,0x22,0x1a,0xc5,0x21,0x65,0x98,0x0a,0x1d,0xf5,0x68,0x13,0xd8,0xef,0xb9,0x40,0x49,0x98,0x02,0x76,0x54,0x0f,0x36,0xf8,0x8f,0x88,0xfc,0xec,0xe1,0x73,0xc0,0x45,0xe1,0x1a,0x92,0x86,0x7b,0x78,0x63,0x7e,0x06,0xce,0x16,0x39,0x57,0xbc,0x96,0x63,0x32,0x99,0xad,0xff +.byte 0xeb,0x63,0x33,0x35,0xef,0x33,0x08,0xca,0x0c,0xac,0x4b,0xc1,0x26,0xa1,0x7a,0x71,0x8e,0x2d,0x18,0x8b,0x6c,0x4a,0x18,0xa1,0x6c,0x15,0x9b,0xb8,0xc1,0xa1,0xc2,0x01,0x6e,0x65,0x40,0x6b,0x8c,0xf7,0x61,0x93,0x3f,0xe3,0xf0,0x56,0xe3,0x3d,0xa1,0x59,0xd9,0x80,0x6b,0x0c,0xe2,0x84,0x56,0xb5,0x06,0xc0,0x83,0xc3,0xf3,0xdd,0xfc,0xc9 +.byte 0xad,0xa0,0x0e,0x5f,0x3b,0x36,0x79,0x46,0xc3,0x0e,0x6c,0x74,0xb0,0xc1,0x75,0xd1,0xe4,0x0b,0xd6,0x8e,0xbd,0x32,0x68,0x8f,0x77,0x0e,0xd4,0xdc,0xa1,0xa8,0x02,0x07,0xef,0x7d,0x5b,0x88,0x29,0x3f,0x7a,0x0a,0x46,0xf1,0x6b,0xfd,0x87,0x59,0x61,0x13,0x69,0x66,0x92,0x3a,0xd9,0x45,0xb7,0x76,0x10,0xad,0x31,0xe0,0x36,0x7e,0x6e,0x57 +.byte 0x65,0x95,0x53,0xc6,0xd3,0xbb,0x6d,0xd2,0x5f,0xd6,0xed,0xbe,0x83,0x7e,0x51,0x0b,0x54,0xc4,0xf7,0xda,0xe1,0x3b,0x96,0xae,0x86,0x90,0x7f,0x1d,0x16,0x37,0xfa,0x7c,0x2e,0x9b,0x27,0x4e,0xf5,0x44,0xf3,0x72,0xec,0xd4,0xa1,0xc8,0xcf,0xb6,0xda,0x26,0x95,0x37,0xbf,0xdc,0x2e,0x3b,0xd4,0xf1,0x09,0x14,0x58,0x8e,0x01,0xcb,0x8c,0x28 +.byte 0x18,0xdd,0x71,0x99,0x7b,0xdf,0x94,0x77,0xc6,0x39,0xea,0x61,0x8a,0x71,0x9a,0xe3,0xd2,0x14,0x6c,0xec,0xfc,0xc6,0x6e,0xf8,0xe2,0x5b,0x55,0xe5,0x58,0xfc,0x06,0x65,0xdb,0xbc,0x9f,0x22,0x30,0x98,0x40,0xc5,0xcf,0xa8,0x97,0xab,0x2e,0x15,0x79,0xe0,0x30,0xb5,0x28,0xd5,0x32,0xec,0x2d,0x4b,0x2c,0x00,0x47,0xdf,0xc5,0xc2,0x19,0x3d +.byte 0xf5,0xc9,0xff,0x7b,0x7a,0x97,0x5f,0x8c,0xd9,0x0f,0x8c,0xa5,0x84,0x1f,0xd6,0x2b,0x36,0x94,0xf9,0xf2,0x92,0x46,0xb9,0x3d,0x67,0xc6,0x4a,0x14,0x57,0xb6,0x16,0x90,0x31,0xd9,0x8e,0xb7,0xbf,0x7b,0x74,0xde,0x7f,0x0e,0x34,0x14,0xb8,0x83,0x7e,0x31,0x15,0xb0,0xa1,0xc8,0xfc,0x28,0x3f,0x7e,0x2b,0xe8,0xc3,0xf6,0x49,0x2d,0x03,0xc6 +.byte 0x94,0x8f,0xe8,0x97,0x46,0x2b,0x83,0x1c,0xe2,0xab,0xe3,0xf1,0xc4,0x20,0x0c,0xa6,0xca,0x78,0x89,0x66,0xb1,0xce,0x8e,0x0d,0x07,0x97,0x9a,0xce,0x8f,0x63,0x9b,0x5a,0x2f,0x51,0x38,0x40,0x37,0xa1,0x8b,0x13,0x51,0xe0,0x4c,0x86,0x8f,0x90,0xe8,0x00,0x1b,0xef,0xb7,0x98,0x7e,0xb8,0xf4,0x29,0xe8,0xa6,0xba,0x58,0x19,0x5f,0x13,0x5e +.byte 0xd6,0x21,0x48,0x8b,0x64,0xee,0xd5,0xc9,0xbd,0x12,0xf4,0xf1,0x2b,0x89,0xaf,0x50,0xab,0x0c,0x9a,0xaa,0x78,0x62,0x90,0x71,0x3f,0xa8,0x19,0x92,0xb3,0x28,0xa9,0x37,0x93,0xbc,0x4c,0xf6,0xde,0xa5,0x02,0x22,0xc1,0x24,0x80,0x03,0x09,0x2a,0x9c,0xdb,0x5a,0xd0,0xf1,0x25,0xe1,0x46,0x0c,0xbf,0xed,0x4b,0x05,0xa1,0xde,0x40,0x71,0xb4 +.byte 0xa9,0x3e,0xf4,0xf1,0x8e,0x00,0x17,0x09,0xa8,0x2c,0xcc,0xbc,0xfe,0x6e,0x9f,0xb6,0x2c,0x53,0x2c,0x12,0x67,0xad,0xa8,0xcc,0xfb,0x46,0xe6,0x00,0x6b,0xb7,0x9b,0xe0,0xd8,0x39,0x4d,0xbe,0xa0,0x14,0x25,0xd6,0xe4,0xc3,0x04,0xde,0xfb,0x85,0x14,0x46,0x5a,0x01,0x64,0x2f,0xb7,0x66,0x31,0x20,0x3e,0x06,0xf8,0x4a,0x68,0xf2,0xa1,0xa1 +.byte 0xe6,0x0b,0xd8,0x3d,0x93,0xb3,0x72,0xff,0x36,0xf8,0xcc,0xa6,0x4f,0x32,0x9d,0xcb,0x25,0x2f,0x4f,0x78,0xb6,0xd3,0xb1,0x58,0x98,0x95,0xc1,0xbf,0xfe,0x08,0x92,0x55,0xf8,0x8a,0x8f,0x65,0xa8,0x51,0xb5,0x69,0x76,0xb0,0x03,0x05,0x93,0xef,0xf3,0x7d,0xfd,0x1e,0xda,0x7e,0x59,0x2c,0x84,0xaf,0x1c,0xd3,0xf0,0x3c,0xe6,0x83,0x4d,0x92 +.byte 0xce,0x62,0x42,0x1b,0xbd,0x81,0xa5,0x5d,0xfe,0xaf,0x47,0xd4,0xf0,0x00,0x95,0x19,0x6c,0xbd,0x9d,0x86,0xdc,0xd9,0xc2,0x67,0x52,0x48,0xa7,0x0c,0x5b,0x4c,0xc1,0x31,0x1e,0xd1,0x1d,0x8b,0x1b,0x01,0x92,0x41,0x4e,0x32,0xbd,0x8e,0x61,0x84,0x02,0x57,0x7f,0x24,0x7c,0xb4,0x02,0x6e,0x2d,0xe2,0x6e,0x44,0xa5,0x2a,0xcc,0xed,0xf6,0xc6 +.byte 0x1f,0x59,0x64,0xad,0x3f,0xc5,0xd4,0x07,0x83,0x32,0xfb,0xd2,0x7e,0xb8,0x50,0x3f,0x2a,0x06,0x7c,0xdd,0x61,0x5f,0xad,0x89,0x57,0x61,0xce,0x75,0xe5,0xa8,0x8b,0x33,0xb1,0x87,0xe3,0x3b,0x64,0xab,0xac,0xb7,0x7e,0xd5,0xbe,0xfa,0x28,0xc4,0x2b,0xe5,0x4b,0x49,0xcd,0x27,0x41,0xcc,0xe3,0x3d,0x6a,0xb7,0x0b,0xf5,0x6f,0xa3,0x1b,0x18 +.byte 0xe2,0x03,0xd9,0x88,0x6a,0xf3,0x05,0x39,0x02,0x79,0xf8,0x2f,0x28,0xbc,0xed,0x39,0xf3,0x14,0xe6,0xfd,0x73,0x4c,0xf0,0x5f,0xd9,0xc9,0x7a,0x6c,0x1c,0xcf,0x38,0x0b,0xae,0xfa,0x34,0x02,0x21,0xc6,0xb3,0x88,0xda,0x96,0xe2,0xe0,0x68,0x75,0x7a,0x98,0x88,0x0d,0x1c,0x92,0xee,0xca,0xac,0x18,0x28,0x89,0x40,0xd7,0x1b,0x6f,0x59,0x21 +.byte 0xd3,0x30,0x4c,0x0c,0x2c,0xca,0x41,0x46,0x8e,0x7d,0xe9,0x76,0x81,0x70,0xc3,0x10,0x42,0x64,0xaf,0x52,0x3e,0x78,0x38,0xcd,0xab,0x88,0xa5,0x32,0xbe,0xbe,0x55,0x39,0xc4,0xc6,0xce,0x53,0xfc,0x11,0x1b,0x0b,0x83,0xd3,0x3e,0x7b,0x71,0x3a,0x58,0x5d,0x70,0xfb,0x49,0x41,0x7d,0xe8,0x1e,0x37,0x17,0x3f,0x80,0x34,0x3a,0x81,0x65,0xb9 +.byte 0x27,0x3c,0xfa,0xdb,0xc1,0xb8,0x5e,0x4c,0x80,0xf7,0x1e,0x89,0x2a,0x04,0xf0,0xfd,0x14,0xf2,0xbc,0x72,0xbb,0x36,0x9d,0x79,0xa5,0x7c,0xed,0x0f,0xf7,0x4f,0x69,0x7d,0xaf,0x8f,0xfc,0xcd,0x14,0x4c,0x29,0x55,0xb5,0xcd,0xb9,0x7c,0xa7,0xd4,0x83,0x28,0xcd,0x9c,0x35,0x75,0x00,0x0f,0xaa,0x3b,0x18,0xa5,0x0f,0x2e,0x97,0xa3,0x38,0xca +.byte 0xb5,0x8a,0x8f,0x9e,0x47,0xc8,0xde,0x82,0x72,0xe0,0xb2,0x14,0xfc,0x28,0xa5,0xf9,0x76,0x38,0xf5,0x42,0xd2,0x87,0x82,0xfe,0x49,0x4d,0xb1,0x32,0x30,0x37,0xdf,0xc4,0x11,0x10,0x30,0xf8,0x51,0x5f,0x5f,0x59,0x02,0x17,0x90,0x5c,0xe6,0x6b,0xec,0x5b,0x14,0xb0,0xde,0xa9,0xca,0xe4,0x00,0x8c,0xe0,0xdb,0xf8,0xd2,0x2b,0x08,0x30,0xbb +.byte 0x37,0xb2,0xd1,0x0e,0x8d,0xba,0xe6,0x60,0x4b,0xe7,0xe3,0x23,0xb6,0x31,0x5f,0x8c,0xb5,0x34,0x7b,0x6f,0x61,0xae,0xeb,0xc7,0xf6,0x0b,0x94,0x28,0xae,0x76,0x81,0xeb,0x44,0xcc,0x51,0xd5,0x5e,0xba,0x97,0x36,0xd3,0xc3,0xc9,0x03,0xe9,0x08,0x92,0x98,0x83,0x2a,0x7b,0x14,0x36,0xd0,0x27,0x5a,0x60,0xa5,0xc0,0xc6,0x12,0x42,0x44,0x85 +.byte 0x8a,0xc7,0x2e,0x5d,0x2a,0xf4,0x25,0x50,0x7d,0x91,0x1c,0x95,0xb6,0x4f,0x1d,0x77,0x80,0x83,0x1c,0x4e,0x55,0xf8,0x1f,0x16,0xee,0xc3,0x8b,0xf5,0x96,0x25,0x1e,0xb6,0x34,0x5c,0xd7,0xd4,0xfa,0xff,0xa1,0x5b,0xd8,0x03,0xc2,0xe9,0x85,0x16,0xde,0x9d,0xef,0x37,0xc4,0x4c,0x82,0xdb,0xe4,0xf9,0x0f,0xcb,0x5e,0x9b,0x75,0xc1,0x3d,0x72 +.byte 0xdd,0xa3,0x31,0xbe,0x19,0x90,0x3d,0x7f,0x5e,0xed,0xa4,0xa4,0xc6,0x5c,0x96,0xfe,0x87,0x44,0x50,0x10,0x9d,0x70,0xf7,0x50,0x11,0xb3,0x20,0x6b,0x48,0xf5,0x5e,0x26,0xed,0x30,0x69,0x91,0x66,0x83,0xf7,0x45,0xa1,0x0e,0x60,0x68,0xae,0x8a,0x84,0x8c,0x6a,0x7d,0x27,0x34,0xc0,0x85,0xaf,0xb5,0x47,0xcd,0x5b,0xab,0xbc,0xb9,0xf8,0x14 +.byte 0xb1,0x81,0xd3,0xd9,0x26,0x5d,0xda,0xb1,0x8b,0x50,0x3f,0xa5,0x88,0x2c,0xc0,0x31,0x14,0x9a,0x5a,0xef,0x24,0x18,0xcf,0x8d,0x1e,0x25,0x38,0x30,0xa9,0x5f,0x8c,0xc6,0xc1,0x85,0x7f,0xec,0xa3,0xb3,0xf8,0xf2,0x48,0x1a,0x9a,0xef,0x21,0xc5,0x13,0xfb,0x89,0xc6,0xec,0xb6,0x81,0xd1,0xef,0xd7,0x2e,0x1d,0x06,0x5a,0x51,0x9b,0xbb,0x44 +.byte 0xce,0x14,0x83,0xb7,0x04,0xf2,0x61,0x47,0x2a,0xff,0x4f,0xe6,0x6d,0x6e,0xd9,0x95,0x48,0x36,0x89,0x96,0x7d,0xfa,0xaf,0xb8,0xf1,0x80,0x66,0x3d,0x01,0x20,0x42,0x76,0xe7,0x58,0xb3,0xbf,0xc7,0xde,0xfb,0x12,0xfa,0x21,0xfb,0x63,0x3e,0xa0,0x7e,0x21,0x90,0xd7,0xf1,0x37,0xa4,0x43,0xbc,0x1b,0xf9,0x51,0x81,0xd0,0x88,0x42,0xf0,0xec +.byte 0x82,0xce,0x92,0x81,0x19,0x77,0x50,0x5b,0xa3,0xd8,0xbd,0x50,0x7b,0xec,0x4d,0x63,0x99,0x29,0x89,0x28,0x9c,0xe4,0x90,0xfb,0x05,0x7e,0x0c,0xc8,0xb9,0xd7,0xc4,0xc6,0x11,0x82,0x22,0xaa,0xe9,0x60,0x20,0x72,0xd6,0x5b,0xa8,0x8e,0x04,0x0b,0x14,0xfc,0x38,0x50,0x7e,0x8b,0x55,0x13,0xe3,0x4a,0x25,0x03,0x88,0x50,0x17,0x73,0x3c,0x0a +.size g_preCompTable,.-g_preCompTable + +#endif diff --git a/crypto/ecc/src/asm/ecp256_x86_64.S b/crypto/ecc/src/asm/ecp256_x86_64.S new file mode 100644 index 00000000..90a20d4f --- /dev/null +++ b/crypto/ecc/src/asm/ecp256_x86_64.S @@ -0,0 +1,2848 @@ +/* + * 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_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include "ecp256_pre_comp_table.s" +.file "ecp256_x86.S" + +.data +.align 64 +.Lpoly: // P +.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 +.LrrModP: // Indicates the calculated value of R * R mod p, which is used in montgomery modular multiplication. +.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd +.Lone_mont: // R mod P, R = 2^256, = 2^256 - P +.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe +.Lord: // order, n +.quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 +.LordK: // (2^64 - ord[0]) * ordK = 1 (mod 2^64)) LordK = -(ord[0])^(-1) (mod 2^64) LordK * Lord, + // The lower 64 bits are all Fs. +.quad 0xccd1c8aaee00bc4f +.LOne: +.quad 0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 + +.text +/** + * Function description: Returns the address of the field calculation table of the ECP256 field. + * Function prototype: const ECP256_TableRow *ECP256_GetPreCompTable(void); + * Input register: None + * Change register: None + * Output register: rax + * Function/Macro Call: None + */ +.globl ECP256_GetPreCompTable +.type ECP256_GetPreCompTable,@function +.align 32 +ECP256_GetPreCompTable: +.cfi_startproc + + leaq g_preCompTable(%rip), %rax + + ret +.cfi_endproc +.size ECP256_GetPreCompTable, .-ECP256_GetPreCompTable + +/** + * Function description: Addition of the ECP256 field. res = a + b mod P + * Function prototype: void ECP256_Add(Coord *r, const Coord *a, const Coord *b); + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * rdx: Address pointing to input data b + * Change register: rsi, rdx, rcx, rax, r8, r9, r10, r11, r12, r13 + * Output register: None + * Function/Macro call: Addition can be implemented by calling ECP256_AddCore. + */ +.globl ECP256_Add +.type ECP256_Add,@function +.align 32 +ECP256_Add: +.cfi_startproc + pushq %r12 + pushq %r13 + + movq (%rsi), %r8 // a[0] + movq 8(%rsi), %r9 // a[1] + xorq %r13, %r13 // Save carry + movq 16(%rsi), %r10 // a[2] + movq 24(%rsi), %r11 // a[3] + leaq .Lpoly(%rip), %rsi // P + + addq (%rdx), %r8 // c[0] = a[0] + b[0] + adcq 8(%rdx), %r9 // c[1] = a[1] + b[1] + carry + movq %r8, %rax // save c[0] + adcq 16(%rdx), %r10 // c[2] = a[2] + b[2] + carry + adcq 24(%rdx), %r11 // c[3] = a[3] = b[3] + carry + movq %r9, %rcx // save c[1] + adcq $0, %r13 // save carry value to r13 + + subq $-1, %r8 // d[0] = c[0] - P[0] + movq %r10, %rdx // save c[2] + sbbq 8(%rsi), %r9 // d[1] = c[1] - P[1] - borrow + sbbq $0, %r10 // d[2] = c[2] - P[2] - borrow + movq %r11, %r12 // save c[3] + sbbq 24(%rsi), %r11 // d[3] = c[3] - P[3] - borrow + sbbq $0, %r13 // r13 = 0 + carry - borrow + + cmovcq %rax, %r8 // res[0] = (r13 < 0) ? c[0]: d[0] + cmovcq %rcx, %r9 // res[1] = (r13 < 0) ? c[1]: d[1] + movq %r8, (%rdi) + cmovcq %rdx, %r10 // res[2] = (r13 < 0) ? c[2]: d[2] + movq %r9, 8(%rdi) + cmovcq %r12, %r11 // res[3] = (r13 < 0) ? c[3]: d[3] + movq %r10, 16(%rdi) + + movq (%rsp), %r13 + movq %r11, 24(%rdi) + movq 8(%rsp), %r12 + leaq 16(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_Add, .-ECP256_Add + +/** + * Function description: Addition core part of the ECP256 field, a + b mod P; Outputs r8-r11, r14,15 are P[1] and P[3] + * Input register: + * r8-r11:256-bit input data a + * rdx: points to the input 256-bit data b. + * r14:P[1] + * r15:P[3] + * Change register: rdx, rcx, rax, r8, r9, r10, r11, r12, r13 + * Output register: r8-r11 + */ +.type ECP256_AddCore,@function +.align 32 +ECP256_AddCore: +.cfi_startproc + xorq %r13, %r13 + addq (%rdx), %r8 // Addition result. + adcq 8(%rdx), %r9 + movq %r8, %rax + adcq 16(%rdx), %r10 + adcq 24(%rdx), %r11 + movq %r9, %rcx + adcq $0, %r13 // Save carry value to r13. + + subq $-1, %r8 // Mod P. + movq %r10, %rdx + sbbq %r14, %r9 + sbbq $0, %r10 + movq %r11, %r12 + sbbq %r15, %r11 + sbbq $0, %r13 + + cmovcq %rax, %r8 // Obtain mod P result. + cmovcq %rcx, %r9 + movq %r8, (%rdi) + cmovcq %rdx, %r10 + movq %r9, 8(%rdi) + cmovcq %r12, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + ret +.cfi_endproc +.size ECP256_AddCore, .-ECP256_AddCore + +/** + * Function description: Subtraction of the ECP256 field. Res = a - b mod P + * Function prototype: void ECP256_Sub(Coord *r, const Coord *a, const Coord *b); + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * rdx: Address pointing to input data b + * Change register: rsi, rdx, rcx, rax, r8, r9, r10, r11, r12, r13 + * Output register: None + * Function/Macro call: Subtraction can be implemented by calling ECP256_SubCore. + */ +.globl ECP256_Sub +.type ECP256_Sub,@function +.align 32 +ECP256_Sub: +.cfi_startproc + pushq %r12 + pushq %r13 + + movq (%rsi), %r8 // a[0] + movq 8(%rsi), %r9 // a[1] + xorq %r13, %r13 // Save borrow + movq 16(%rsi), %r10 // a[3] + movq 24(%rsi), %r11 // a[4] + leaq .Lpoly(%rip), %rsi // P + + subq (%rdx), %r8 // c[0] = a[0] - b[0] + sbbq 8(%rdx), %r9 // c[1] = a[1] - b[1] - borrow + movq %r8, %rax // save c[0] + sbbq 16(%rdx), %r10 // c[2] = a[2] - b[2] - borrow + sbbq 24(%rdx), %r11 // c[3] = a[3] - b[3] - borrow + movq %r9, %rcx // save c[1] + sbbq $0, %r13 // save borrow value to r13 + + addq $-1, %r8 // d[0] = c[0] + P[0] + movq %r10, %rdx // save c[2] + adcq 8(%rsi), %r9 // d[1] = c[1] + P[1] + carry + adcq $0, %r10 // d[2] = c[2] + P[2] + carry + movq %r11, %r12 // save c[3] + adcq 24(%rsi), %r11 // d[3] = c[3] + P[3] + carry + testq %r13, %r13 + + cmovzq %rax, %r8 // res[0] = (r13 == 0) ? c[0] : d[0] + cmovzq %rcx, %r9 // res[1] = (r13 == 0) ? c[1] : d[1] + movq %r8, (%rdi) + cmovzq %rdx, %r10 // res[2] = (r13 == 0) ? c[2] : d[2] + movq %r9, 8(%rdi) + cmovzq %r12, %r11 // res[3] = (r13 == 0) ? c[3] : d[3] + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + movq (%rsp), %r13 + movq 8(%rsp), %r12 + leaq 16(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_Sub, .-ECP256_Sub + +/** + * Function description: subtraction core part of the ECP256 field, a-b mod P; no writeback + * Input register: + * r8-r11:256-bit input data a + * rdx:Points to the input 256-bit data b. + * r14:P[1] + * r15:P[3] + * Change register: rdx, rcx, rax, r8, r9, r10, r11, r12, r13 + * Output register: r8-r11 + */ +.type ECP256_SubCore,@function +.align 32 +ECP256_SubCore: +.cfi_startproc + xorq %r13, %r13 + subq (%rdx), %r8 // Subtraction results. + sbbq 8(%rdx), %r9 + movq %r8, %rax // Save Results. + sbbq 16(%rdx), %r10 + sbbq 24(%rdx), %r11 + movq %r9, %rcx + sbbq $0, %r13 // Borrowing saved in r13. + + addq $-1, %r8 // a - b + P + movq %r10, %rdx + adcq %r14, %r9 + adcq $0, %r10 + movq %r11, %r12 + adcq %r15, %r11 + testq %r13, %r13 + + cmovzq %rax, %r8 // If r13 is equal to 0, a-b is used. Otherwise, a-b+P is used. + cmovzq %rcx, %r9 + cmovzq %rdx, %r10 + cmovzq %r12, %r11 + + ret +.cfi_endproc +.size ECP256_SubCore, .-ECP256_SubCore + +/** + * Function description: negation of the ECP256 field. res = -a mod P + * Function prototype: void ECP256_Neg(Coord *r, const Coord *a); + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * Change register: rsi, rdx, rcx, rax, r8, r9, r10, r11, r12, r13 + * Output register: None + * Function/Macro Call: + */ +.globl ECP256_Neg +.type ECP256_Neg,@function +.align 32 +ECP256_Neg: +.cfi_startproc + pushq %r12 + pushq %r13 + + xorq %r8, %r8 // -a = 0 - a + xorq %r9, %r9 + xorq %r13, %r13 + leaq .Lpoly(%rip), %rdx + xorq %r10, %r10 + xorq %r11, %r11 + + subq (%rsi),%r8 + sbbq 8(%rsi),%r9 + movq %r8, %rax + sbbq 16(%rsi),%r10 + sbbq 24(%rsi),%r11 + movq %r9, %rcx + sbbq $0, %r13 + + addq $-1, %r8 + movq %r10, %rsi + adcq 8(%rdx), %r9 + adcq $0, %r10 + movq %r11, %r12 + adcq 24(%rdx), %r11 + testq %r13, %r13 // Choost result + + cmovzq %rax, %r8 + cmovzq %rcx, %r9 + movq %r8, (%rdi) + cmovzq %rsi, %r10 + movq %r9, 8(%rdi) + cmovzq %r12, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + movq (%rsp), %r13 + movq 8(%rsp), %r12 + leaq 16(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_Neg, .-ECP256_Neg + +/** + * Function description: multiplication of the ECP256 field: res = a * b * 2^-256 mod P + * Function prototype: void ECP256_Mul(Coord *r, const Coord *a, const Coord *b); + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * rdx: Address pointing to input data b + * Change register: rax, rbx, rcx, rdx, rbp, r8, r9, r10, r11, r12, r13, r14, r15 + * Output register: None + * Function/macro call: Multiplication can be implemented by calling ECP256_MulCore. + */ +.globl ECP256_Mul +.type ECP256_Mul,@function +.align 32 +ECP256_Mul: +.cfi_startproc + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq %rdx, %rcx // rdx is for mul + movq .Lpoly+8(%rip), %r14 + movq .Lpoly+24(%rip), %r15 + call ECP256_MulCore_q + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + movq 32(%rsp), %rbp + movq 40(%rsp), %rbx + leaq 48(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_Mul, .-ECP256_Mul + +/** + * Function description: Montgomery multiplication of the ECP256 field + * Input register: + * rdi: Return address. + * rsi: Factor address. + * rcx: Factor address. + * Change register: rax,rbx,rcx,rdx,rbp,r8-r13 + * Output register: None. + */ +.type ECP256_MulCore_q,@function +.align 32 +ECP256_MulCore_q: +.cfi_startproc + movq (%rcx), %rax // b[0] + + movq %rax, %rbp // save b[0] + mulq (%rsi) // a[0] * b[0] + movq %rax, %r10 + movq %rbp, %rax // b[0] + movq %rdx, %r11 + + mulq 8(%rsi) // a[1] * b[0] + addq %rax, %r11 + movq %rbp, %rax + adcq $0, %rdx // a[1:0] * b[0] < 2^192, no overflow + movq %rdx, %r12 + + mulq 16(%rsi) // a[2] * b[0] + addq %rax, %r12 + movq %rbp, %rax + adcq $0, %rdx + movq %rdx, %r13 + + mulq 24(%rsi) // a[3] * b[0] + addq %rax, %r13 + adcq $0, %rdx + movq %rdx, %r8 // result: r8 r13 r12 r11 r10 + xorq %r9, %r9 + movq %r10, %rax // first reduction + movq %r10, %rbp + shlq $32, %r10 // r10 * 2^96 low + mulq %r15 // r10 * 0xffffffff00000001 + shrq $32, %rbp // r10 * 2^96 high + addq %r10, %r11 + adcq %rbp, %r12 + adcq %rax, %r13 + adcq %rdx, %r8 + movq 8(%rcx), %rax + adcq $0, %r9 + xorq %r10, %r10 + movq %rax, %rbp + + mulq (%rsi) + addq %rax, %r11 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 8(%rsi) + addq %rbx, %r12 + adcq $0, %rdx + addq %rax, %r12 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 16(%rsi) + addq %rbx, %r13 + adcq $0, %rdx + addq %rax, %r13 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 24(%rsi) + addq %rbx, %r8 + adcq $0, %rdx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + + movq %r11, %rbp + movq %r11, %rax + shlq $32, %r11 // r11 * 2^96 low + mulq %r15 // r11 * 0xffffffff00000001 + shrq $32, %rbp // r11 * 2^96 high + addq %r11, %r12 + adcq %rbp, %r13 + movq 16(%rcx), %rbp + adcq %rax, %r8 + adcq %rdx, %r9 + movq %rbp, %rax + adcq $0, %r10 + xorq %r11, %r11 + + mulq (%rsi) // a[0] * b[2] + addq %rax, %r12 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 8(%rsi) + addq %rbx, %r13 + adcq $0, %rdx + addq %rax, %r13 + movq %rbp, %rax + adcq $0, %rdx + movq %rdx, %rbx + + mulq 16(%rsi) + addq %rbx, %r8 + adcq $0, %rdx + addq %rax, %r8 + movq %rbp, %rax + adcq $0, %rdx + movq %rdx, %rbx + + mulq 24(%rsi) + addq %rbx, %r9 + adcq $0, %rdx + addq %rax, %r9 + adcq %rdx, %r10 + movq %r12, %rbp + adcq $0, %r11 + + movq %r12, %rax // third reduction + shlq $32, %r12 // r12 * 2^96 low + mulq %r15 // r12 * 0xffffffff00000001 + shrq $32, %rbp // r12 * 2^96 high + addq %r12, %r13 + adcq %rbp, %r8 + movq 24(%rcx), %rbp + adcq %rax, %r9 + adcq %rdx, %r10 + movq %rbp, %rax + adcq $0, %r11 + xorq %r12, %r12 + + mulq (%rsi) // a[0] * b[3] + addq %rax, %r13 + adcq $0, %rdx + movq %rdx, %rbx + + movq %rbp, %rax + mulq 8(%rsi) + addq %rbx, %r8 + adcq $0, %rdx + addq %rax, %r8 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 16(%rsi) + addq %rbx, %r9 + adcq $0, %rdx + addq %rax, %r9 + movq %rbp, %rax + adcq $0, %rdx + movq %rdx, %rbx + + mulq 24(%rsi) + addq %rbx, %r10 + adcq $0, %rdx + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0, %r12 + + movq %r13, %rbp + movq %r13, %rax // last reduction + shlq $32, %r13 // r13 * 2^96 low + mulq %r15 // r13 * 0xffffffff00000001 + shrq $32, %rbp // r13 * 2^96 high + + addq %r13, %r8 + adcq %rbp, %r9 + adcq %rax, %r10 + adcq %rdx, %r11 + movq %r8, %rbx + movq %r9, %rbp + adcq $0, %r12 + movq %r10, %rax + movq %r11, %rdx + subq $-1, %r8 + sbbq %r14, %r9 + sbbq $0, %r10 + sbbq %r15, %r11 + sbbq $0, %r12 + + cmovcq %rbx, %r8 + cmovcq %rbp, %r9 + cmovcq %rax, %r10 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + cmovcq %rdx, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + ret +.cfi_endproc +.size ECP256_MulCore_q, .-ECP256_MulCore_q + +/** + * Function description: ECP256 Montgomery form + * Function prototype: void ECP256_ToMont(Coord *r, const Coord *a); + * Input register: + * rdi: pointer to the output Coord structure + * rsi: address pointing to input data a + * Change register: rax,rbx,rcx,rdx,rbp,r8-r13 + * Output register: None + * Function/Macro invoking: This function can be implemented by calling ECP256_Mul. + */ +.globl ECP256_ToMont +.type ECP256_ToMont,@function +.align 32 +ECP256_ToMont: +.cfi_startproc + leaq .LrrModP(%rip),%rcx + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq .Lpoly+8(%rip), %r14 + movq .Lpoly+24(%rip), %r15 + call ECP256_MulCore_q + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + movq 32(%rsp), %rbp + movq 40(%rsp), %rbx + leaq 48(%rsp), %rsp + + ret +.cfi_endproc +.size ECP256_ToMont, .-ECP256_ToMont + +/** + * Function description: ECP256 Montgomery form converted to normal form + * Function prototype: void ECP256_FromMont(Coord *r, const Coord *a); + * Input register: + * rdi: Pointer to the output Coord structure. + * rsi: Address pointing to input data a. + * Change register: rax,rcx,rdx,r8-r13 + * Output register: None. + * Function/Macro Call: + */ +.globl ECP256_FromMont +.type ECP256_FromMont,@function +.align 32 +ECP256_FromMont: +.cfi_startproc + pushq %r12 + pushq %r13 + + movq .Lpoly+8(%rip), %r12 + movq .Lpoly+24(%rip), %r13 + + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + + movq %r8, %rax + movq %r8, %rcx + shlq $32, %r8 + mulq %r13 // 0xff * 0xff = 0xfe01 + shrq $32, %rcx + addq %r8, %r9 + adcq %rcx, %r10 + movq %r9, %rcx + adcq %rax, %r11 + adcq $0, %rdx // rdx + 1 <= 0xff + movq %r9, %rax + movq %rdx, %r8 + + shlq $32, %r9 + mulq %r13 + shrq $32, %rcx + addq %r9, %r10 + adcq %rcx, %r11 + movq %r10, %rcx + adcq %rax, %r8 + adcq $0, %rdx + movq %r10, %rax + movq %rdx, %r9 + + shlq $32, %r10 + mulq %r13 + shrq $32, %rcx + addq %r10, %r11 + adcq %rcx, %r8 + movq %r11, %rcx + adcq %rax, %r9 + adcq $0, %rdx + movq %r11, %rax + movq %rdx, %r10 + + shlq $32, %r11 + mulq %r13 + shrq $32, %rcx + addq %r11, %r8 + adcq %rcx, %r9 + movq %r8, %rsi + adcq %rax, %r10 + adcq $0, %rdx + movq %rdx, %r11 // r8 r9 r10 r11 + + movq %r9, %rdx + subq $-1, %r8 + movq %r10, %rcx + sbbq %r12, %r9 + movq %r11, %rax + sbbq $0, %r10 + sbbq %r13, %r11 + + cmovcq %rsi, %r8 // < P + cmovcq %rdx, %r9 + movq %r8, (%rdi) + cmovcq %rcx, %r10 + movq %r9, 8(%rdi) + cmovcq %rax, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + movq (%rsp), %r13 + movq 8(%rsp), %r12 + leaq 16(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_FromMont, .-ECP256_FromMont + +/** + * Function description: Multiplication of the ECP256 field:res = a*b*2^-256 mod P + * Function prototype: void ECP256_Sqr(Coord *r, const Coord *a); + * Input register: + * rdi: pointer to the output Coord structure + * rsi: address pointing to input data a + * Change register: rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12, r13, r14, r15 + * Output register: None + * Function/Macro Call: Multiplication can be implemented by calling ECP256_SqrCore_q. + */ +.globl ECP256_Sqr +.type ECP256_Sqr,@function +.align 32 +ECP256_Sqr: +.cfi_startproc + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + nop // add this instruction to improve performance, movq %rsi, %rdx is ok + movq (%rsi), %rax // a[0] + movq 8(%rsi), %r14 // a[1] + movq 16(%rsi), %rbp // a[2] + movq 24(%rsi), %r15 // a[3] + call ECP256_SqrCore_q + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + movq 32(%rsp), %rbp + movq 40(%rsp), %rbx + leaq 48(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_Sqr, .-ECP256_Sqr + +/** + * Function description: Montgomery square of the ECP256 field + * Input register: + * rdi: Return address + * rsi: Factor address + * Change register: rax, rbx, rcx, rdx, rbp, rsi, r8-r15 + * Output register: None + */ +.type ECP256_SqrCore_q,@function +.align 32 +ECP256_SqrCore_q: +.cfi_startproc + movq %rax, %r8 + mulq %r14 // rdx:rax = a[0] * a[1] + xorq %rcx, %rcx + movq %rax, %r9 // r9 = rax + xorq %r11, %r11 + xorq %r12, %r12 + movq %r8, %rax + xorq %r13, %r13 + xorq %rbx, %rbx + movq %rdx, %r10 // r10:r9 = a[0] * a[1] + + mulq %rbp // rdx:rax = a[0] * a[2] + addq %rax, %r10 // r10 += rax + movq %r8, %rax // a[0] --> rax + adcq %rdx, %r11 // a[0] * (a[2] * 2^64 + a[1]) < 2^196, no overflow + + mulq %r15 // rdx:rax = a[0] * a[3] + addq %rax, %r11 // r11 += rax + movq %r14, %rax // a[0] --> rax + adcq %rdx, %r12 // a[0] * (a[3] * 2^128 + a[2] * 2^64 + a[1]) < 2^256, no overflow + + mulq %rbp // rdx:rax = a[1] * a[2] + addq %rax, %r11 + movq %r14, %rax + adcq %rdx, %r12 + adcq $0, %r13 + + mulq %r15 // rdx:rax = a[1] * a[3] + addq %rax, %r12 + movq %rbp, %rax + adcq %rdx, %r13 + adcq $0, %rbx + + mulq %r15 // rdx:rax = a[2] * a[3] + addq %rax, %r13 + adcq %rdx, %rbx // rbx not overflow + + movq %r8, %rax + addq %r9, %r9 // twice + adcq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + adcq %r13, %r13 + adcq %rbx, %rbx + adcq $0, %rcx + + mulq %rax // rdx:rax = a[0] * a[0] + movq %rax, %r8 + movq %r14, %rax + movq %rdx, %rsi + + mulq %rax // rdx:rax = a[1] * a[1] + addq %rsi, %r9 + adcq %rax, %r10 + movq %rbp, %rax + adcq $0, %rdx + movq %rdx, %rsi + + mulq %rax // rdx:rax = a[2] * a[2] + addq %rsi, %r11 + adcq %rax, %r12 + movq %r15, %rax + adcq $0, %rdx + movq %rdx, %rsi + + mulq %rax // rdx:rax = a[3] * a[3] + addq %rsi, %r13 + adcq %rax, %rbx + movq %r8, %rax + adcq %rdx, %rcx // rcx not overflow + + movq .Lpoly+8(%rip), %r14 + movq .Lpoly+24(%rip), %r15 + movq %r8, %rbp // First reduction + shlq $32, %r8 // l32[r8 << 96] + mulq %r15 + shrq $32, %rbp // h32[r8 << 96] + addq %r8, %r9 + adcq %rbp, %r10 + adcq %rax, %r11 + adcq $0, %rdx + movq %r9, %rax + movq %r9, %rbp + movq %rdx, %r8 // r8 r11 r10 r9 0 + + shlq $32, %r9 // Second reduction + mulq %r15 + shrq $32, %rbp + addq %r9, %r10 + adcq %rbp, %r11 + adcq %rax, %r8 + adcq $0, %rdx + movq %r10, %rax + movq %r10, %rbp + movq %rdx, %r9 // r9 r8 r11 r10 0 + + shlq $32, %r10 // Third reduction + mulq %r15 + shrq $32, %rbp + addq %r10, %r11 + adcq %rbp, %r8 + adcq %rax, %r9 + adcq $0, %rdx + movq %r11, %rax + movq %r11, %rbp + movq %rdx, %r10 // r10 r9 r8 r11 0 + + shlq $32, %r11 // Last reduction + mulq %r15 + shrq $32, %rbp + addq %r11, %r8 + adcq %rbp, %r9 + adcq %rax, %r10 + adcq $0, %rdx // rdx r10 r9 r8 0 + + xorq %rsi, %rsi // Add the reduction result + addq %r8, %r12 + adcq %r9, %r13 + movq %r12, %r8 + adcq %r10, %rbx + adcq %rdx, %rcx + movq %r13, %r9 + adcq $0, %rsi // Reserve carry value + + subq $-1, %r8 + movq %rbx, %r10 + sbbq %r14, %r9 + sbbq $0, %r10 + movq %rcx, %r11 + sbbq %r15, %r11 + sbbq $0, %rsi + + cmovcq %r12, %r8 + cmovcq %r13, %r9 + movq %r8, (%rdi) + cmovcq %rbx, %r10 + movq %r9, 8(%rdi) + cmovcq %rcx, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + ret +.cfi_endproc +.size ECP256_SqrCore_q, .-ECP256_SqrCore_q + +/** + * Function description: Multiplication of the ECP256 field: res = a*b*2^-256 mod Order(P) + * Function prototype: void ECP256_OrdSqr(Coord *r, const Coord *a, int32_t repeat); + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * rdx:Repeat + * Change register: rax, rbx, rcx, rdx, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, r15 + * Output register: None + * Function/Macro Call: + */ +.globl ECP256_OrdSqr +.type ECP256_OrdSqr,@function +.align 32 +ECP256_OrdSqr: +.cfi_startproc + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq (%rsi), %r8 + movq 8(%rsi), %rax + movq 16(%rsi), %r14 + movq 24(%rsi), %r15 + leaq .Lord(%rip), %rbp // ptr(N) --> rbp + movq %rdx, %rbx +.align 32 +.Lord_sqr_loop: + movq %rax, %rsi + mulq %r8 // rdx:rax = acc[0] * acc[1] + movq %rax, %r9 // r9 = rax + vmovq %rsi, %xmm1 // save acc[1] -> xmm1 + movq %r14, %rax // acc[2] --> rax + movq %rdx, %r10 // r10:r9 = acc[0] * acc[1] + + mulq %r8 // rdx:rax = acc[0] * acc[2] + addq %rax, %r10 // r10 += rax + vmovq %r14, %xmm2 // save acc[2] -> xmm2 + adcq $0, %rdx // acc[0] * (acc[2] * 2^64 + acc[1]) < 2^196, no overflow + movq %r15, %rax // acc[3] --> rax + movq %rdx, %r11 + + mulq %r8 // rdx:rax = a[0] * a[3] + addq %rax, %r11 // r11 += rax + vmovq %r15, %xmm3 // Save acc[3] -> xmm3 + adcq $0, %rdx // acc[0] * (acc[3] * 2^128 + acc[2] * 2^64 + acc[1]) < 2^256, no overflow + movq %r15, %rax // acc[1] --> rax + movq %rdx, %r12 + + mulq %r14 + movq %rax, %r13 + movq %r14, %rax + movq %rdx, %r14 + + mulq %rsi + addq %rax, %r11 + movq %r15, %rax + adcq $0, %rdx + movq %rdx, %r15 + + mulq %rsi + addq %rax, %r12 + adcq $0, %rdx + addq %r15, %r12 + adcq %rdx, %r13 + movq %r8, %rax // acc[0] --> rax + adcq $0, %r14 // r14 r13 r12 r11 r10 r9 + + xorq %r15, %r15 // 0 --> r15 + addq %r9, %r9 // twice + adcq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + adcq %r13, %r13 + adcq %r14, %r14 + adcq $0, %r15 // result: r15 r14 r13 r12 r11 r10 r9 + + mulq %rax // rdx:rax = acc[0] * acc[0] + movq %rax, %r8 // rax --> r8 + vmovq %xmm1, %rax // acc[1] --> rax + movq %rdx, %rcx // save rdx to rcx + + mulq %rax // rdx:rax = acc[1] * acc[1] + addq %rcx, %r9 // r9 += rcx + adcq %rax, %r10 // r10 += rax + adcq $0, %rdx // no overflow + vmovq %xmm2, %rax // acc[2] --> rax + movq %rdx, %rcx // save rdx to rcx + + mulq %rax // rdx:rax = a[2] * a[2] + addq %rcx, %r11 // r11 += rcx + adcq %rax, %r12 // r12 += rax + movq %r8, %rsi // acc[0] --> rsi + adcq $0, %rdx // no overflow + vmovq %xmm3, %rax // acc[3] --> rax + movq %rdx, %rcx // save rcx to rdx + + imulq 32(%rbp), %r8 // m = acc[0] * LordK (mod 2^64) --> r8 + + mulq %rax // rdx:rax = a[3] * a[3] + addq %rcx, %r13 // r13 += rcx + adcq %rax, %r14 // r14 += r + movq (%rbp), %rax // N[0] --> rax + adcq %rdx, %r15 // r15 not overflow + + /* Result acc[8:0] = r15 r14 r13 r12 r11 r10 r9 r8; */ + /* The first reduction */ + mulq %r8 // rdx:rax = m * N[0] + addq %rax, %rsi // rsi = 0 + movq %r8, %rcx // m --> rcx + adcq %rdx, %rsi // rsi = rdx + carry --> acc[1] + + subq %r8, %r10 // acc[2] - m + sbbq $0, %rcx // m - borrwo, to acc[3] + + movq 8(%rbp), %rax // N[1] --> rax + mulq %r8 // rdx:rax = m * N[1] + addq %rsi, %r9 // acc[1] += high[m * N[0]] + adcq $0, %rdx // save carry + addq %rax, %r9 // acc[1] += low[m * N[1]] + movq %r8, %rax // m --> rax + adcq %rdx, %r10 // acc[2] += high[m * N[1]] + movq %r9, %rsi // acc[1] --> rsi + movq %r8, %rdx // m --> rdx + adcq $0, %rcx // m - borrwoto acc[3] + + imulq 32(%rbp), %r9 // m = acc[1] * LordK --> r9 + + shlq $32, %rax // low(m) --> rax low(m * 2^228) + shrq $32, %rdx // high(m) --> rdx high(m * 2^228) + subq %rax, %r11 // acc[3] - low(m * 2^228) + movq (%rbp), %rax // N[0] --> rax + sbbq %rdx, %r8 // m - high(m * 2^228) to acc[4] + + addq %rcx, %r11 // acc[3] += m + carry - borrow + adcq $0, %r8 // to acc[4] + + /* Second reduction */ + mulq %r9 // rdx:rax = m * N[0] + addq %rax, %rsi // acc[1] += rax --> 0 + movq %r9, %rcx // m --> rcx + adcq %rdx, %rsi // rsi = high[m * N[0]] + carry --> acc[2] + + movq 8(%rbp), %rax // N[1] --> rax + subq %r9, %r11 // acc[3] -= m + sbbq $0, %rcx // m - borrow --> rcx + + mulq %r9 // rdx:rax = m * N[1] + addq %rsi, %r10 // acc[2] += high[m * N[1]] + carry + adcq $0, %rdx // rdx += carry, no overflow + addq %rax, %r10 // acc[2] += rax + movq %r9, %rax // m --> rax + adcq %rdx, %r11 // acc[3] += rdx + movq %r10, %rsi // acc[2] --> rsi + movq %r9, %rdx // m --> rdx + adcq $0, %rcx // m - borrow + carry --> rcx + + imulq 32(%rbp), %r10 // m = acc[2] * LordK --> r10 + + shlq $32, %rax // low(m * 2^228) + shrq $32, %rdx // high(m * 2^228) + subq %rax, %r8 // t0 acc[4] - low(m * 2^228) + movq (%rbp), %rax // N[0] --> rax + sbbq %rdx, %r9 // m - high(m * 2^228) to acc[5] + + addq %rcx, %r8 // to acc[4] + adcq $0, %r9 // to acc[5] + + /* Third reduction */ + mulq %r10 // rdx:rax = m * N[0] + movq %r10, %rcx // m --> rcx + addq %rax, %rsi // acc[2] += rax --> 0 + adcq %rdx, %rsi // rsi = high[m * N[0]] + carry --> acc[3] + movq 8(%rbp), %rax // N[1] --> rax + subq %r10, %r8 // to acc[4] -= m + sbbq $0, %rcx // m - borrow --> rcx + + mulq %r10 // rdx:rax = m * N[1] + addq %rsi, %r11 // acc[3] += high[m * N[1]] + carry + adcq $0, %rdx // rdx += carry, no overflow + addq %rax, %r11 // acc[3] += rax + movq %r10, %rax // m --> rax + adcq %rdx, %r8 // to acc[4] += rdx + movq %r11, %rsi // acc[3] --> rsi + movq %r10, %rdx // m --> rdx + adcq $0, %rcx // m - borrow + carry --> rcx + + imulq 32(%rbp), %r11 // m = acc[3] * LordK --> r11 + + shlq $32, %rax // low(m * 2^228) + shrq $32, %rdx // high(m * 2^228) + subq %rax, %r9 // to acc[5]: - low(m * 2^228) + sbbq %rdx, %r10 // to acc[6]: m - high(m * 2^228) + movq (%rbp), %rax // N[0] --> rax + addq %rcx, %r9 // to acc[5] + adcq $0, %r10 // to acc[6] + + /* Last reduction */ + mulq %r11 // rdx:rax = m * N[0] + addq %rax, %rsi // acc[3] += rax --> 0 + movq %r11, %rcx // m --> rcx + adcq %rdx, %rsi // rsi = high[m * N[0]] + carry --> acc[4] + movq 8(%rbp), %rax // N[1] --> rax + subq %r11, %r9 // to acc[5] : -= m + sbbq $0, %rcx // to acc[6] : m - borrow + + mulq %r11 // rdx:rax = m * N[1] + addq %rsi, %r8 // to acc[4]: += high[m * N[1]] + carry + adcq $0, %rdx // rdx += carry, no overflow + addq %rax, %r8 // to acc[4]: += rax + movq %r11, %rax // m --> rax + adcq %rdx, %r9 // to acc[5]: += rdx + movq %r11, %rdx // m --> rdx + adcq $0, %rcx // m - borrow + carry --> rcx + + shlq $32, %rax // low(m * 2^228) + shrq $32, %rdx // high(m * 2^228) + + subq %rax, %r10 // to acc[6]: - low(m * 2^228) + sbbq %rdx, %r11 // to acc[7]: m - high(m * 2^228) + + addq %rcx, %r10 // to acc[6] + adcq $0, %r11 // to acc[7] + + /* r15 r14 r13 r12 + r11 r10 r9 r8 */ + xorq %rdx, %rdx + addq %r12, %r8 + adcq %r13, %r9 + movq %r8, %r12 + adcq %r14, %r10 + adcq %r15, %r11 + movq %r9, %rax + adcq $0, %rdx + + subq (%rbp), %r8 + movq %r10, %r14 + sbbq 8(%rbp), %r9 + sbbq 16(%rbp), %r10 + movq %r11, %r15 + sbbq 24(%rbp), %r11 + sbbq $0, %rdx + + cmovcq %r12, %r8 + cmovncq %r9, %rax + cmovncq %r10, %r14 + cmovncq %r11, %r15 // r8 rax r14 r15 + + decq %rbx + jnz .Lord_sqr_loop + + movq %r8, (%rdi) + movq %rax, 8(%rdi) + vpxor %xmm2, %xmm2, %xmm2 + movq %r14, 16(%rdi) + vpxor %xmm3, %xmm3, %xmm3 + movq %r15, 24(%rdi) + vpxor %xmm1, %xmm1, %xmm1 + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + movq 32(%rsp), %rbp + movq 40(%rsp), %rbx + leaq 48(%rsp), %rsp + + ret +.cfi_endproc +.size ECP256_OrdSqr, .-ECP256_OrdSqr + +/** + * Function description: half calculation of the ECP256 field: res = a/2 mod P + * Input register: + * rdi: Pointer to the output Coord structure + * r8: a[0] + * r9: a[1] + * r10:a[2] + * r11:a[3] + * r14:P[1] + * r15:P[3] + * Change register: rax, rcx, rdx, rsi, r8, r9, r10, r11, r12, r13 + * Output register: r8, r9, r10, r11 + */ +.type ECP256_DivBy2Core,@function +ECP256_DivBy2Core: +.cfi_startproc + xorq %r13, %r13 + movq %r8, %rax + movq %r9, %rcx + + addq $-1, %r8 + movq %r10, %rdx + adcq %r14, %r9 + movq %r11, %r12 + adcq $0, %r10 + adcq %r15, %r11 + adcq $0, %r13 + xorq %rsi, %rsi + + testq $1, %rax + cmovzq %rax, %r8 + cmovzq %rcx, %r9 + cmovzq %rdx, %r10 + cmovzq %r12, %r11 + movq %r9, %rcx + cmovzq %rsi, %r13 + movq %r10, %rdx + movq %r11, %r12 + + shrq $1, %r8 + shlq $63, %rcx + shrq $1, %r9 + shlq $63, %rdx + shrq $1, %r10 + orq %rcx, %r8 + shlq $63, %r12 + + shrq $1, %r11 + shlq $63, %r13 + orq %rdx, %r9 + orq %r12, %r10 + orq %r13, %r11 + + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + ret +.cfi_endproc +.size ECP256_DivBy2Core, .-ECP256_DivBy2Core + +/** + * Function description: Half calculation of the ECP256 field: res = a/2 mod P + * Function prototype: void ECP256_DivBy2(Coord *r, const Coord *a); + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * Change register: rax, rcx, rdx, rsi, r8, r9, r10, r11, r12, r13, r14, r15 + * Output register: None + * Function/macro call: Call ECP256_DivBy2Core to implement half calculation. + */ +.globl ECP256_DivBy2 +.type ECP256_DivBy2, @function +ECP256_DivBy2: +.cfi_startproc + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + movq 8+.Lpoly(%rip), %r14 + movq 24+.Lpoly(%rip), %r15 + call ECP256_DivBy2Core + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + leaq 32(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_DivBy2, .-ECP256_DivBy2 + +/* r14 = .Lpoly[1], r15 = .Lpoly[3] */ +.type ECP256_MulBy2Core,@function +.align 32 +ECP256_MulBy2Core: +.cfi_startproc + xorq %r13, %r13 + + addq %r8, %r8 + adcq %r9, %r9 + movq %r8, %rax + adcq %r10, %r10 + adcq %r11, %r11 + movq %r9, %rcx + adcq $0, %r13 + + subq $-1, %r8 + movq %r10, %rdx + sbbq %r14, %r9 + movq %r11, %r12 + sbbq $0, %r10 + sbbq %r15, %r11 + sbbq $0, %r13 + + cmovcq %rax, %r8 // Obtain mod P result + cmovcq %rcx, %r9 + movq %r8, (%rdi) + cmovcq %rdx, %r10 + movq %r9, 8(%rdi) + cmovcq %r12, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + ret +.cfi_endproc +.size ECP256_MulBy2Core, .-ECP256_MulBy2Core + +.globl ECP256_MulBy2 +.type ECP256_MulBy2,@function +.align 32 +ECP256_MulBy2: +.cfi_startproc + pushq %r12 + pushq %r13 + + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + xorq %r13, %r13 + + leaq .Lpoly(%rip), %rsi + + addq %r8, %r8 + adcq %r9, %r9 + movq %r8, %rax + adcq %r10, %r10 + adcq %r11, %r11 + movq %r9, %rcx + adcq $0, %r13 + + subq $-1, %r8 + movq %r10, %rdx + sbbq 8(%rsi), %r9 + movq %r11, %r12 + sbbq $0, %r10 + sbbq 24(%rsi), %r11 + sbbq $0, %r13 + + cmovcq %rax, %r8 // Obtain mod P result + cmovcq %rcx, %r9 + movq %r8, (%rdi) + cmovcq %rdx, %r10 + movq %r9, 8(%rdi) + cmovcq %r12, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + movq 0(%rsp), %r13 + movq 8(%rsp), %r12 + leaq 16(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_MulBy2, .-ECP256_MulBy2 + +/* r14 = .Lpoly[1], r15 = .Lpoly[3] */ +.type ECP256_MulBy3Core,@function +.align 32 +ECP256_MulBy3Core: +.cfi_startproc + xorq %r13, %r13 + addq %r8, %r8 + adcq %r9, %r9 + movq %r8, %rax + adcq %r10, %r10 + adcq %r11, %r11 + movq %r9, %rcx + adcq $0, %r13 + subq $-1, %r8 + movq %r10, %rdx + sbbq %r14, %r9 + movq %r11, %r12 + sbbq $0, %r10 + sbbq %r15, %r11 + sbbq $0, %r13 + + cmovcq %rax, %r8 // Obtain mod P result + cmovcq %rcx, %r9 + cmovcq %rdx, %r10 + cmovcq %r12, %r11 + + xorq %r13, %r13 + addq (%rsi), %r8 + adcq 8(%rsi), %r9 + movq %r8, %rax + adcq 16(%rsi), %r10 + adcq 24(%rsi), %r11 + movq %r9, %rcx + adcq $0, %r13 + subq $-1, %r8 + movq %r10, %rdx + sbbq %r14, %r9 + sbbq $0, %r10 + movq %r11, %r12 + sbbq %r15, %r11 + sbbq $0, %r13 + + cmovcq %rax, %r8 // Obtain mod P result + cmovcq %rcx, %r9 + movq %r8, (%rdi) + cmovcq %rdx, %r10 + movq %r9, 8(%rdi) + cmovcq %r12, %r11 + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + ret +.cfi_endproc +.size ECP256_MulBy3Core, .-ECP256_MulBy3Core + +.globl ECP256_MulBy3 +.type ECP256_MulBy3,@function +.align 32 +ECP256_MulBy3: +.cfi_startproc + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + movq 8+.Lpoly(%rip), %r14 + movq 24+.Lpoly(%rip), %r15 + call ECP256_MulBy3Core + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + leaq 32(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_MulBy3, .-ECP256_MulBy3 + +/** + * Function description: This function is used to calculate the Montgomery multiplication of the ord(P256) field: + * res = a * b * 2^(-256) mod ord(P) + * Input register: + * rdi: Pointer to the output Coord structure + * rsi: Address pointing to input data a + * rdx: Address pointing to input data b + * Change register: rax, rbx, rcx, rdx, rbp, r8, r9, r10, r11, r12, r13, r14, r15 + * Function/Macro invoking: The calculation can be implemented by calling ECP256_OrdMulCore. + */ +.globl ECP256_OrdMul +.type ECP256_OrdMul,@function +.align 32 +ECP256_OrdMul: +.cfi_startproc + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + movq %rdx, %rcx // rdx used to output the mul multiplication result. + // The rcx saves the b address. + leaq .Lord(%rip), %r15 + movq .LordK(%rip), %r14 + movq (%rdx), %rax // b[0] + + //a[0-3] * b[0] + movq %rax, %rbp // save b[0] + mulq (%rsi) // a[0] * b[0] + movq %rax, %r8 + movq %rbp, %rax // b[0] + movq %rdx, %r9 + + mulq 8(%rsi) // a[1] * b[0] + addq %rax, %r9 + movq %rbp, %rax + adcq $0, %rdx // a[1:0] * b[0] The result must be less than 2 ^ 192, + // So no carry is required. + movq %rdx, %r10 + + mulq 16(%rsi) // a[2] * b[0] + addq %rax, %r10 + movq %rbp, %rax + adcq $0, %rdx + movq %rdx, %r11 + + mulq 24(%rsi) // a[3] * b[0] + addq %rax, %r11 + adcq $0, %rdx + movq %r8, %r13 + movq %rdx, %r12 // First round multiplication results r12 r11 r10 r9 r8 + + // First round of reduction + // n[0] = 0xf3b9cac2fc632551 + // n[1] = 0xbce6faada7179e84 + // n[2] = 0xffffffffffffffff, lo(q*n[2]) = -q , hi(q*n[2]) = q + // n[3] = 0xffffffff00000000, lo(q*n[3]) = -lq<<32, hi(q*n[3]) = q-hq + imulq %r14, %r8 // r8 = r8 * ordK = q + + movq %r8, %rax + mulq (%r15) // n[0] * q + addq %rax, %r13 // %r13 must be 0. + adcq $0, %rdx // hi(n[0]*q) + 1 < 2^32 + 1 < 2^64 No further carry is required. + movq %r8, %rax + movq %rdx, %rbp // %rbp = hi(n[0]*q) + + mulq 8(%r15) // n[1] * q + addq %rbp, %rax // %rax = lo(n[1]*q)+hi(n[0]*q) + adcq $0, %rdx // %rdx = hi(n[1]*q), be the same as the above hi(n[1]*q) + 1 < 2^64 + // No further carry is required. + + movq %r8, %rbx + subq %r8, %r10 // r10 = r[2] - q + sbbq $0, %rbx // When q>0, rbx - 1 = q - 1 >= 0, when q=0 (r[2]-q) does not borrow, + // rbx = rbx - 0 >= 0, so the following formula does not borrow + + addq %rax, %r9 // r9 = r[1] + lo(n[1]*q) + hi(n[0]*q) + adcq %rdx, %r10 // r10 = r[2] - q + hi(n[1]*q) + movq %r8, %rax + adcq $0, %rbx // Overflowing is not possible. + + movq %r8, %rdx + shrq $32, %rax // rax = hq + shlq $32, %rdx // rdx = lq<<32 + + subq %rdx, %rbx // q - lq<<32 + sbbq %rax, %r8 // r8 = q - hq = hq * 2^32 + lq - hq >= lq, + // When lq!=0, The following formula does not borrow. + // When lq==0, the upper formula does not borrow. + + adcq %rbx, %r11 + movq 8(%rcx), %rax + adcq %r8, %r12 + movq %rax, %rbp + adcq $0, %r13 + + // a[0-3] * b[1] + mulq (%rsi) + addq %rax, %r9 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 8(%rsi) + addq %rbx, %r10 + adcq $0, %rdx + addq %rax, %r10 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 16(%rsi) + addq %rbx, %r11 + adcq $0, %rdx + addq %rax, %r11 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + xorq %r8, %r8 // r8 = 0 + mulq 24(%rsi) + addq %rbx, %r12 + adcq $0, %rdx + addq %rax, %r12 + adcq %rdx, %r13 + movq %r9, %rbx + adcq $0, %r8 // Second round of multiplication results r9,r10,r11,r12,r13,r8 + + // Second round of reduction + imulq %r14, %r9 // r9 = r9 * ordK = q + movq %r9, %rax + + mulq (%r15) // n[0] * q + addq %rax, %rbx // %rbx must be 0 + adcq $0, %rdx // hi(n[0]*q) + 1 < 2^32 + 1 < 2^64 No further carry is required + movq %r9, %rax + movq %rdx, %rbp // %rbp = hi(n[0]*q) + + mulq 8(%r15) // n[1] * q + addq %rbp, %rax // %rax = lo(n[1]*q)+hi(n[0]*q) + adcq $0, %rdx // %rdx = hi(n[1]*q), be the same as the above hi(n[1]*q) + 1 < 2^64 + // No further carry is required + + movq %r9, %rbx + subq %r9, %r11 // r11 = r[2] - q + sbbq $0, %rbx // when q>0 rbx - 1 = q - 1 >= 0, + // When q=0 (r[2]-q) does not borrow, rbx = rbx - 0 >= 0, + // So the following equation does not borrow + + addq %rax, %r10 // r10 = r[1] + lo(n[1]*q) + hi(n[0]*q) + adcq %rdx, %r11 // r11 = r[2] - q + hi(n[1]*q) + movq %r9, %rax + adcq $0, %rbx // Overflowing is not possible. + + movq %r9, %rdx + shrq $32, %rax // rax = hq + shlq $32, %rdx // rdx = lq<<32 + + subq %rdx, %rbx // q - lq<<32 + sbbq %rax, %r9 // r9 = q - hq = hq * 2^32 + lq - hq >= lq, + // When lq!=0, The following formula does not borrow. + // When lq==0, the preceding formula does not borrow. + + movq 16(%rcx), %rax + adcq %rbx, %r12 + adcq %r9, %r13 + adcq $0, %r8 + + // a[0-3] * b[2] + movq %rax, %rbp + mulq (%rsi) // a[0] * b[2] + addq %rax, %r10 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 8(%rsi) + addq %rbx, %r11 + adcq $0, %rdx + addq %rax, %r11 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 16(%rsi) + addq %rbx, %r12 + adcq $0, %rdx + addq %rax, %r12 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + xorq %r9, %r9 + mulq 24(%rsi) + addq %rbx, %r13 + adcq $0, %rdx + addq %rax, %r13 + adcq %rdx, %r8 + movq %r10, %rbx + adcq $0, %r9 + + // Third round reduction + imulq %r14, %r10 // r10 = r10 * ordK = q + + movq %r10, %rax + mulq (%r15) // n[0] * q + addq %rax, %rbx // %rbx must be 0 + adcq $0, %rdx // hi(n[0]*q) + 1 < 2^32 + 1 < 2^64 no further carry is required. + movq %r10, %rax + movq %rdx, %rbp // %rbp = hi(n[0]*q) + + mulq 8(%r15) // n[1] * q + addq %rbp, %rax // %rax = lo(n[1]*q)+hi(n[0]*q) + adcq $0, %rdx // %rdx = hi(n[1]*q), same as above hi(n[1]*q) + 1 < 2^64 no further carry is required. + + movq %r10, %rbx + subq %r10, %r12 // r12 = r[2] - q + sbbq $0, %rbx // if q>0, rbx - 1 = q - 1 >= 0. + // if q=0, (r[2]-q) Won't borrow , rbx = rbx - 0 >= 0, + // the following formula will not borrow. + + addq %rax, %r11 // r11 = r[1] + lo(n[1]*q) + hi(n[0]*q) + adcq %rdx, %r12 // r12 = r[2] - q + hi(n[1]*q) + movq %r10, %rax + adcq $0, %rbx // Overflowing is not possible. + + movq %r10, %rdx + shrq $32, %rax // rax = hq + shlq $32, %rdx // rdx = lq<<32 + + subq %rdx, %rbx // q - lq<<32 + sbbq %rax, %r10 // r10 = q - hq = hq * 2^32 + lq - hq >= lq, + // if lq!=0, the following formula does not borrow, + // if lq==0, The above formula does not borrow. + + movq 24(%rcx), %rax + adcq %rbx, %r13 + adcq %r10, %r8 + adcq $0, %r9 + + // a[0-3] * b[3] + movq %rax, %rbp + mulq (%rsi) // a[0] * b[3] + addq %rax, %r11 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 8(%rsi) + addq %rbx, %r12 + adcq $0, %rdx + addq %rax, %r12 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + mulq 16(%rsi) + addq %rbx, %r13 + adcq $0, %rdx + addq %rax, %r13 + adcq $0, %rdx + movq %rbp, %rax + movq %rdx, %rbx + + xorq %r10, %r10 + mulq 24(%rsi) + addq %rbx, %r8 + adcq $0, %rdx + addq %rax, %r8 + adcq %rdx, %r9 + movq %r11, %rbx + adcq $0, %r10 + + // last round reduction. + imulq %r14, %r11 // r11 = r11 * ordK = q + + movq %r11, %rax + mulq (%r15) // n[0] * q + addq %rax, %rbx // %rbx must be 0 + adcq $0, %rdx // hi(n[0]*q) + 1 < 2^32 + 1 < 2^64 no further carry is required. + movq %r11, %rax + movq %rdx, %rbp // %rbp = hi(n[0]*q) + + mulq 8(%r15) // n[1] * q + addq %rbp, %rax // %rax = lo(n[1]*q)+hi(n[0]*q) + adcq $0, %rdx // %rdx = hi(n[1]*q), same as above, + // hi(n[1]*q) + 1 < 2^64 no further carry is required. + + movq %r11, %rbx + subq %r11, %r13 // r13 = r[2] - q + sbbq $0, %rbx // When q>0 rbx - 1 = q - 1 >= 0, + // When q=0,(r[2]-q)No borrowing, rbx = rbx - 0 >= 0, + // so the following formula does not borrow. + + addq %rax, %r12 // r12 = r[1] + lo(n[1]*q) + hi(n[0]*q) + adcq %rdx, %r13 // r13 = r[2] - q + hi(n[1]*q) + movq %r11, %rax + adcq $0, %rbx // Overflowing is not possible. + + movq %r11, %rdx + shrq $32, %rax // rax = hq + shlq $32, %rdx // rdx = lq<<32 + + subq %rdx, %rbx // q - lq<<32 + sbbq %rax, %r11 // r11 = q - hq = hq * 2^32 + lq - hq >= lq, + // when lq!=0, the following formula does not borrow. + // When lq==0, the preceding formula does not borrow. + + adcq %rbx, %r8 + adcq %r11, %r9 + adcq $0, %r10 + + // mod n + movq %r12, %rbx + movq %r13, %rbp + movq %r8, %rax + movq %r9, %rdx + + subq (%r15), %r12 + sbbq 8(%r15), %r13 + sbbq 16(%r15), %r8 + sbbq 24(%r15), %r9 + sbbq $0, %r10 + + cmovcq %rbx, %r12 + cmovcq %rbp, %r13 + cmovcq %rax, %r8 + cmovcq %rdx, %r9 + + movq %r12, (%rdi) + movq %r13, 8(%rdi) + movq %r8, 16(%rdi) + movq %r9, 24(%rdi) + + movq (%rsp), %r15 + movq 8(%rsp), %r14 + movq 16(%rsp), %r13 + movq 24(%rsp), %r12 + movq 32(%rsp), %rbp + movq 40(%rsp), %rbx + leaq 48(%rsp), %rsp + ret +.cfi_endproc +.size ECP256_OrdMul, .-ECP256_OrdMul + +/** + * Function description: Calculate the point doubling of an elliptic curve: res = 2*a + * Function prototype: void ECP256_PointDouble(P256_Point *r, const P256_Point *a); + * Input register: + * rdi: pointer to the output P256_POINT structure + * rsi: address pointing to input data a + * Change register: rax, rbx, rcx, rdx, rbp, rsi, r8, r9, r10, r11, r12, r13, r14, r15 + * Function/Macro Call: ECP256_MulBy2Core, ECP256_SqrCore_q, ECP256_AddCore, ECP256_MulCore_q, ECP256_SubCore + */ +.globl ECP256_PointDouble +.type ECP256_PointDouble,@function +.align 32 +ECP256_PointDouble: +.cfi_startproc + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $168, %rsp // Create 32 x 5 + 8 stack space. +.Lpoint_double_core: + vmovdqu (%rsi), %xmm0 // Save x to stack + vmovdqu 16(%rsi), %xmm1 + vmovdqa %xmm0, (%rsp) + vmovdqa %xmm1, 16(%rsp) + + vmovq %rsi, %xmm3 // Backup a + vmovq %rdi, %xmm0 // Backup &r->x, &r->y, &r->z + leaq 32(%rdi), %r12 + leaq 64(%rdi), %r13 + vmovq %r12, %xmm1 + vmovq %r13, %xmm2 + + movq 32(%rsi), %r8 // Read a->y + movq 40(%rsi), %r9 + movq 48(%rsi), %r10 + movq 56(%rsi), %r11 + + movq 8+.Lpoly(%rip), %r14 // Read P[1], P[3] + movq 24+.Lpoly(%rip), %r15 + + leaq 32(%rsp), %rdi + call ECP256_MulBy2Core // ECP256_MulBy2(S, &a->y), Not overwritten rsi + + movq 64(%rsi), %rax + movq 72(%rsi), %r14 + movq 80(%rsi), %rbp + movq 88(%rsi), %r15 + leaq 64(%rsi), %rsi // Setting Input Parameters + leaq 64(%rsp), %rdi // Z2 = rsp + 64 + call ECP256_SqrCore_q // ECP256_Sqr(Z2, &a->z) + + leaq (%rsp), %rdx + leaq 96(%rsp), %rdi // M = rsp + 96 + call ECP256_AddCore // ECP256_Add(M, a->x, Z2) + + movq 32(%rsp), %rax + movq 40(%rsp), %r14 + movq 48(%rsp), %rbp + movq 56(%rsp), %r15 + leaq 32(%rsp), %rdi // S = rsp + 32 + call ECP256_SqrCore_q // ECP256_Sqr(S, S) + + vmovq %xmm3, %rcx + leaq 32(%rcx), %rsi + leaq 64(%rcx), %rcx + vmovq %xmm2, %rdi + call ECP256_MulCore_q // ECP256_Mul(r->z, a->y, a->z) + call ECP256_MulBy2Core // ECP256_MulBy2(r->z, r->z) + + movq (%rsp), %r8 + movq 8(%rsp), %r9 + movq 16(%rsp), %r10 + movq 24(%rsp), %r11 + leaq 64(%rsp), %rdx + call ECP256_SubCore // ECP256_SubCore(Z2,a->x,Z2) + movq %r8, 64(%rsp) + movq %r9, 72(%rsp) + movq %r10, 80(%rsp) + movq %r11, 88(%rsp) + + movq 32(%rsp), %rax + movq 40(%rsp), %r14 + movq 48(%rsp), %rbp + movq 56(%rsp), %r15 + vmovq %xmm1, %rdi + call ECP256_SqrCore_q // ECP256_Sqr(r->y,S) + + call ECP256_DivBy2Core // ECP256_Div(r->y,r->y) + + leaq 96(%rsp), %rdi + leaq 96(%rsp), %rsi + leaq 64(%rsp), %rcx + call ECP256_MulCore_q // ECP256_MulCore_q(M,M,Z2) + call ECP256_MulBy3Core // ECP256_MulBy3Core(M,M) + + leaq (%rsp), %rcx + leaq 32(%rsp), %rsi + leaq 32(%rsp), %rdi + call ECP256_MulCore_q // ECP256_MulCore_q(S, S, a->x) + + leaq 128(%rsp), %rdi // T = 128 + rsp + call ECP256_MulBy2Core // ECP256_MulBy2Core(T, S) + + movq 96(%rsp), %rax + movq 104(%rsp), %r14 + movq 112(%rsp), %rbp + movq 120(%rsp), %r15 + vmovq %xmm0, %rdi + call ECP256_SqrCore_q // ECP256_Sqr(r->x, M) + + leaq 128(%rsp), %rdx + call ECP256_SubCore // ECP256_SubCore(r->x, r->x, T) + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + xorq %rsi, %rsi // ECP256_SubCore(S, S, r->x), output %r12, %r13, %r8, %r9 + movq 32(%rsp), %rax + movq 40(%rsp), %rbx + movq 48(%rsp), %rcx + subq %r8, %rax + sbbq %r9, %rbx + movq 56(%rsp), %rdx + movq %rax, %r12 + sbbq %r10, %rcx + sbbq %r11, %rdx + movq %rbx, %r13 + movq %rcx, %r8 + sbbq $0, %rsi + addq $-1, %rax + movq %rdx, %r9 + adcq %r14, %rbx + adcq $0, %rcx + adcq %r15, %rdx + testq %rsi, %rsi + cmovnzq %rax, %r12 + cmovnzq %rbx, %r13 + cmovnzq %rcx, %r8 + cmovnzq %rdx, %r9 + movq %r12, 32(%rsp) + movq %r13, 40(%rsp) + movq %r8, 48(%rsp) + movq %r9, 56(%rsp) + + leaq 32(%rsp), %rdi + leaq 32(%rsp), %rsi + leaq 96(%rsp), %rcx + call ECP256_MulCore_q // ECP256_MulCore_q(S, S, M) + + vmovq %xmm1, %rdx + vmovq %xmm1, %rdi + call ECP256_SubCore // ECP256_SubCore(r->y, S, r->y) + movq %r8, (%rdi) + movq %r9, 8(%rdi) + leaq 168+48(%rsp), %rsi + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + movq -48(%rsi), %r15 + movq -40(%rsi), %r14 + movq -32(%rsi), %r13 + movq -24(%rsi), %r12 + movq -16(%rsi), %rbp + movq -8(%rsi), %rbx + leaq (%rsi), %rsp + ret +.cfi_endproc +.size ECP256_PointDouble, .-ECP256_PointDouble + +/** + * Function description: Elliptic curve point addition calculation: res = a + b + * Function prototype: void ECP256_PointAdd(P256_Point *r, const P256_Point *a, const P256_Point *b); + * Input register: + * rdi: Pointer to the output P256_POINT structure + * rsi: Address pointing to input data a + * rdx: Address pointing to input data b + * Change register: rax, rbx, rcx, rdx, rbp, rsi, r8, r9, r10, r11, r12, r13, r14, r15 + * Function/Macro Call: ECP256_PointDouble, ECP256_SqrCore_q, ECP256_MulCore_q, ECP256_SubCore, ECP256_MulBy2Core + */ +.globl ECP256_PointAdd +.type ECP256_PointAdd,@function +.align 32 +ECP256_PointAdd: +.cfi_startproc + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + subq $640+8, %rsp // Create 32 x 20 + 8 stack space. + + vmovdqu (%rsi), %xmm0 + vmovdqu 16(%rsi), %xmm1 + vmovdqu 32(%rsi), %xmm2 + vmovdqu 48(%rsi), %xmm3 + vmovdqu 64(%rsi), %xmm4 + vmovdqu 80(%rsi), %xmm5 + movq %rsi, %rcx + movq %rdx, %rsi + vmovdqu %xmm0, (%rsp) // Save a on the stack, a_cpy: 0~96(%rsp) + vmovdqu %xmm1, 16(%rsp) + vmovdqu %xmm2, 32(%rsp) + vmovdqu %xmm3, 48(%rsp) + vmovdqu %xmm4, 64(%rsp) + vmovdqu %xmm5, 80(%rsp) + vpor %xmm4, %xmm5, %xmm5 // xmm5 = (Za[3]|Za[1], Za[2]|Za[0]) + + vmovdqu (%rsi), %xmm0 + vpshufd $0xb1, %xmm5, %xmm3 // xmm3 = ((lo(Za[3]|Za[1])<<32) | hi(Za[3]|Za[1]), (lo(Za[2]|Za[0])<<32) | hi(Za[2]|Za[0])) + vmovdqu 16(%rsi), %xmm1 + vmovdqu 32(%rsi), %xmm2 + vpor %xmm3, %xmm5, %xmm5 // xmm5 = ((lo(Za[3]|Za[1])|hi(Za[3]|Za[1]))##~, (lo(Za[2]|Za[0])|hi(Za[2]|Za[0]))##~) + vmovdqu 48(%rsi), %xmm3 + + movq 64(%rsi), %rax // Read b.z, then calculate (b.z)^2 + movq 72(%rsi), %r14 + movq 80(%rsi), %rbp + movq 88(%rsi), %r15 + + vmovdqu %xmm0, 96(%rsp) // Save b on the stack. b_cpy: 96–192(%rsp) + vpshufd $0x1e, %xmm5, %xmm4 // xmm4 = ((lo(Za[2]|Za[0])|hi(Za[2]|Za[0]))##~, (lo(Za[3]|Za[1])|hi(Za[3]|Za[1]))##~) + vmovdqu %xmm1, 112(%rsp) + vmovdqu 64(%rsi), %xmm0 + vmovdqu 80(%rsi), %xmm1 + vmovdqu %xmm2, 128(%rsp) + vmovdqu %xmm3, 144(%rsp) + vpor %xmm4, %xmm5, %xmm5 // xmm5 = ((lo(Za[0]|Za[1]|Za[2]|Za[3])|hi(Za[0]|Za[1]|Za[2]|Za[3]))##~##~##~) + vpxor %xmm4, %xmm4, %xmm4 + vpor %xmm0, %xmm1, %xmm1 + vmovq %rdi, %xmm0 // Backup rdi + movq %rax, 160(%rsp) + movq %r14, 168(%rsp) + leaq 192(%rsp), %rdi // Zb^2: 192~224(%rsp) + movq %rbp, 176(%rsp) + movq %r15, 184(%rsp) + + vmovq %rcx, %xmm2 // Backup a + call ECP256_SqrCore_q // sqr(Zb^2, Zb) + + vpcmpeqd %xmm4, %xmm5, %xmm5 // a_infty, Whether a is an infinity point (Za == 0) + vpshufd $0xb1, %xmm1, %xmm4 + vpor %xmm1, %xmm4, %xmm4 + vpshufd $0x1e, %xmm4, %xmm3 + vpor %xmm3, %xmm4, %xmm4 + vpxor %xmm3, %xmm3, %xmm3 + vpcmpeqd %xmm3, %xmm4, %xmm4 // b_infty, Whether b is an infinity point (Zb == 0) + + movq 64(%rsp), %rax + movq 72(%rsp), %r14 + leaq 224(%rsp), %rdi // Za^2: 224~256(%rsp) + movq 80(%rsp), %rbp + movq 88(%rsp), %r15 + call ECP256_SqrCore_q // sqr(Za^2, Za) + + leaq 160(%rsp), %rsi // Zb + leaq 192(%rsp), %rcx // Zb^2 + leaq 256(%rsp), %rdi // S1: 256~288(%rsp) + call ECP256_MulCore_q // mul(S1, Zb, Zb^2) + + leaq 64(%rsp), %rsi // Za + leaq 224(%rsp), %rcx // Za^2 + leaq 288(%rsp), %rdi // S2: 288~320(%rsp) + call ECP256_MulCore_q // mul(S2, Za, Za^2) + + leaq 32(%rsp), %rsi // Ya + leaq 256(%rsp), %rcx // S1 + leaq 256(%rsp), %rdi // S1 + call ECP256_MulCore_q // mul(S1,S1,Ya) + + leaq 128(%rsp), %rsi // Yb + leaq 288(%rsp), %rcx // S2 + leaq 288(%rsp), %rdi // S2 + call ECP256_MulCore_q // mul(S2,S2,Yb) + + leaq 256(%rsp), %rdx // S1 + call ECP256_SubCore // sub(R,S2,S1) + movq %r8, 320(%rsp) // R: 320~352(%rsp) + movq %r9, 328(%rsp) + movq %r10, 336(%rsp) + movq %r11, 344(%rsp) + + orq %r9, %r8 + vmovdqa %xmm4, %xmm1 + orq %r10, %r8 + orq %r11, %r8 + vpor %xmm5, %xmm1, %xmm1 // a_infty | b_infty + vmovq %r8, %xmm3 + + leaq (%rsp), %rsi // Xa + leaq 192(%rsp), %rcx // Zb^2 + leaq 352(%rsp), %rdi // U1: 352~384(%rsp) + call ECP256_MulCore_q // Mul(U1, Xa, Zb^2) + + leaq 96(%rsp), %rsi // Xb + leaq 224(%rsp), %rcx // Za^2 + leaq 384(%rsp), %rdi // U2: 384~416(%rsp) + call ECP256_MulCore_q // Mul(U2, Xb, Za^2) + + leaq 352(%rsp), %rdx // U1 + leaq 416(%rsp), %rdi // H: 416~448(%rsp) + call ECP256_SubCore // sub(H,U2,U1) + movq %r8, 416(%rsp) + movq %r9, 424(%rsp) + movq %r10, 432(%rsp) + movq %r11, 440(%rsp) + + orq %r9, %r8 + vmovq %xmm1, %r12 + orq %r10, %r8 + vmovq %xmm3, %r13 + orq %r11, %r8 + + orq %r12, %r8 + orq %r13, %r8 + + jnz .Lpoint_add + +.Lequal_point: + vmovq %xmm0, %rdi + vmovq %xmm2, %rsi + addq $640-32*5, %rsp + jmp .Lpoint_double_core + +.align 32 +.Lpoint_add: + movq 320(%rsp), %rax // R + movq 328(%rsp), %r14 + leaq 448(%rsp), %rdi // R^2: 448~480(%rsp) + movq 336(%rsp), %rbp + movq 344(%rsp), %r15 + call ECP256_SqrCore_q // sqr(R^2,R) + + leaq 64(%rsp), %rsi // Za + leaq 416(%rsp), %rcx // H + leaq 480(%rsp), %rdi // Zr:480~512(%rsp) + call ECP256_MulCore_q // Mul(Zr,H,Za) + + movq 416(%rsp), %rax // H + movq 424(%rsp), %r14 + leaq 512(%rsp), %rdi // H^2:512~544(%rsp) + movq 432(%rsp), %rbp + movq 440(%rsp), %r15 + call ECP256_SqrCore_q // sqr(H^2, H) + + leaq 480(%rsp), %rdi // Zr + leaq 480(%rsp), %rsi // Zr + leaq 160(%rsp), %rcx // Zb + call ECP256_MulCore_q // Mul(Zr, Zr, Zb) + + leaq 544(%rsp), %rdi // H3:544~576(%rsp) + leaq 512(%rsp), %rsi // H2 + leaq 416(%rsp), %rcx // H + call ECP256_MulCore_q // mul(H^3,H,H^2) + + leaq 384(%rsp), %rdi // U2 + leaq 352(%rsp), %rsi // U1 + leaq 512(%rsp), %rcx // H2 + call ECP256_MulCore_q // mul(U2,U1,H^2) + + leaq 512(%rsp), %rdi // H^2 + call ECP256_MulBy2Core // mulby2(H^2,U2) + + movq 448(%rsp), %rax // sub(Xr,R^2,H^2) + movq 456(%rsp), %rbx + xorq %rsi, %rsi + movq 464(%rsp), %rcx + movq 472(%rsp), %rdx + subq %r8, %rax + sbbq %r9, %rbx + movq %rax, %r8 + sbbq %r10, %rcx + sbbq %r11, %rdx + movq %rbx, %r9 + sbbq $0, %rsi + + addq $-1, %r8 + movq %rcx, %r10 + adcq %r14, %r9 + adcq $0, %r10 + movq %rdx, %r11 + adcq %r15, %r11 + testq %rsi, %rsi + cmovzq %rax, %r8 + cmovzq %rbx, %r9 + cmovzq %rcx, %r10 + cmovzq %rdx, %r11 + + leaq 576(%rsp), %rdi // Xr: 576~608(%rsp) + leaq 544(%rsp), %rdx // H^3 + call ECP256_SubCore // sub(Xr, Xr, H^3) + movq %r8, 576(%rsp) + movq %r9, 584(%rsp) + movq %r10, 592(%rsp) + movq %r11, 600(%rsp) + + movq 384(%rsp), %rax // sub(Yr, U2, Xr) + movq 392(%rsp), %rbx + xorq %rsi, %rsi + movq 400(%rsp), %rcx + movq 408(%rsp), %rdx + subq %r8, %rax + sbbq %r9, %rbx + movq %rax, %r8 + sbbq %r10, %rcx + sbbq %r11, %rdx + movq %rbx, %r9 + sbbq $0, %rsi + + addq $-1, %r8 + movq %rcx, %r10 + adcq %r14, %r9 + adcq $0, %r10 + movq %rdx, %r11 + adcq %r15, %r11 + testq %rsi, %rsi + cmovzq %rax, %r8 + cmovzq %rbx, %r9 + cmovzq %rcx, %r10 + cmovzq %rdx, %r11 + movq %r8, 608(%rsp) // Yr: 608~640(%rsp) + movq %r9, 616(%rsp) + movq %r10, 624(%rsp) + movq %r11, 632(%rsp) + + leaq 288(%rsp), %rdi // S2 + leaq 256(%rsp), %rsi // S1 + leaq 544(%rsp), %rcx // H^3 + call ECP256_MulCore_q // Mul(S2, S1, H^3) + + leaq 608(%rsp), %rdi // Yr + leaq 608(%rsp), %rsi + leaq 320(%rsp), %rcx // r + call ECP256_MulCore_q // Mul(Yr, Yr, R) + + leaq 608(%rsp), %rdi // Yr + leaq 288(%rsp), %rdx // S2 + call ECP256_SubCore // sub(Yr,Yr,S2) + movq %r8, 608(%rsp) + movq %r9, 616(%rsp) + movq %r10, 624(%rsp) + movq %r11, 632(%rsp) + + vmovq %xmm0, %rdi + + vmovdqa %xmm5, %xmm0 // a_infty + vmovdqa %xmm5, %xmm1 + vpandn 576(%rsp), %xmm0, %xmm0 // !a_infty & Xr + vpandn 592(%rsp), %xmm1, %xmm1 + vmovdqa %xmm5, %xmm2 + vmovdqa %xmm5, %xmm3 + vpand 96(%rsp), %xmm2, %xmm2 // a_infty & Xb + vpand 112(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 // a_infty ? Xb : Xr + vpor %xmm1, %xmm3, %xmm3 + + vmovdqa %xmm4, %xmm0 // b_infty + vmovdqa %xmm4, %xmm1 + vpandn %xmm2, %xmm0, %xmm0 // !b_infty & (a_infty ? Xb : Xr) + vpandn %xmm3, %xmm1, %xmm1 + vmovdqa %xmm4, %xmm2 + vmovdqa %xmm4, %xmm3 + vpand (%rsp), %xmm2, %xmm2 // b_infty & Xa + vpand 16(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 // b_infty ? Xa : (a_infty ? Xb : Xr) + vpor %xmm1, %xmm3, %xmm3 + vmovdqu %xmm2, (%rdi) + vmovdqu %xmm3, 16(%rdi) + + vmovdqa %xmm5, %xmm0 // a_infty + vmovdqa %xmm5, %xmm1 + vpandn 608(%rsp), %xmm0, %xmm0 // !a_infty & Yr + vpandn 624(%rsp), %xmm1, %xmm1 + vmovdqa %xmm5, %xmm2 + vmovdqa %xmm5, %xmm3 + vpand 128(%rsp), %xmm2, %xmm2 // a_infty & Yb + vpand 144(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 // a_infty ? Yb : Yr + vpor %xmm1, %xmm3, %xmm3 + + vmovdqa %xmm4, %xmm0 // b_infty + vmovdqa %xmm4, %xmm1 + vpandn %xmm2, %xmm0, %xmm0 // !b_infty & (a_infty ? Yb : Yr) + vpandn %xmm3, %xmm1, %xmm1 + vmovdqa %xmm4, %xmm2 + vmovdqa %xmm4, %xmm3 + vpand 32(%rsp), %xmm2, %xmm2 // b_infty & Ya + vpand 48(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 // b_infty ? Ya : (a_infty ? Yb : Yr) + vpor %xmm1, %xmm3, %xmm3 + vmovdqu %xmm2, 32(%rdi) + vmovdqu %xmm3, 48(%rdi) + + vmovdqa %xmm5, %xmm0 // a_infty + vmovdqa %xmm5, %xmm1 + vpandn 480(%rsp), %xmm0, %xmm0 // !a_infty & Zr + vpandn 496(%rsp), %xmm1, %xmm1 + vmovdqa %xmm5, %xmm2 + vmovdqa %xmm5, %xmm3 + vpand 160(%rsp), %xmm2, %xmm2 // a_infty & Zb + vpand 176(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 // a_infty ? Zb : Zr + vpor %xmm1, %xmm3, %xmm3 + + vmovdqa %xmm4, %xmm0 // b_infty + vmovdqa %xmm4, %xmm1 + vpandn %xmm2, %xmm0, %xmm0 // !b_infty & (a_infty ? Zb : Zr) + vpandn %xmm3, %xmm1, %xmm1 + vmovdqa %xmm4, %xmm2 + vmovdqa %xmm4, %xmm3 + vpand 64(%rsp), %xmm2, %xmm2 // b_infty & Za + vpand 80(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 // b_infty ? Za : (a_infty ? Zb : Zr) + vpor %xmm1, %xmm3, %xmm3 + vmovdqu %xmm2, 64(%rdi) + vmovdqu %xmm3, 80(%rdi) + + leaq 640+56(%rsp), %rsi + movq -48(%rsi), %r15 + movq -40(%rsi), %r14 + movq -32(%rsi), %r13 + movq -24(%rsi), %r12 + movq -16(%rsi), %rbp + movq -8(%rsi), %rbx + leaq (%rsi), %rsp + ret +.cfi_endproc +.size ECP256_PointAdd, .-ECP256_PointAdd + +/** + * Function description: Point addition of normal coordinates and affine coordinates assembly implementation + * Function prototype: void ECP256_AddAffine(P256_Point *r, const P256_Point *a, const P256_AffinePoint *b); + * Input register: + * rdi: Points to the returned P256_Point. + * rsi: Points to the input P256_Point. + * rdx: P256_AffinePoint that points to the input + * Change register: rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12, r13, r14, r15 + * Output register: None + * Function/Macro Call: ECP256_MulBy2Core, ECP256_SqrCore_q, ECP256_AddCore, ECP256_MulCore_q, ECP256_SubCore + */ +.globl ECP256_AddAffine +.type ECP256_AddAffine,@function +.align 32 +ECP256_AddAffine: +.cfi_startproc + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + subq $488, %rsp // open up stack space 32 * 15 + 8 = 488 + + vmovdqu 0(%rsi), %xmm0 // X1[1]X1[0] --> xmm0 + vmovdqu 16(%rsi), %xmm1 // X1[3]X1[2] + vmovdqu 32(%rsi), %xmm2 // Y1[1]Y1[0] + vmovdqu 48(%rsi), %xmm3 // Y1[3]Y1[2] + movq 72(%rsi), %r14 // Z1[1] 64 + 8 + movq 64(%rsi), %rax // Z1[0] 64 + 0 + vmovdqu 64(%rsi), %xmm4 // Z1[1]Z1[0] + movq 88(%rsi), %r15 // Z1[3] 64 + 24 + movq 80(%rsi), %rbp // Z1[2] 64 + 16 + vmovdqu 80(%rsi), %xmm5 // Z1[3]Z1[2] + + vmovdqa %xmm0, 320(%rsp) // save X1[1]X1[0] to stack + vmovdqa %xmm1, 336(%rsp) // save X1[3]X1[2] to stack + vmovdqa %xmm2, 352(%rsp) // save Y1[1]Y1[0] to stack + vmovdqa %xmm3, 368(%rsp) // save Y1[3]Y1[2] to stack + vmovdqa %xmm4, 384(%rsp) // save Z1[1]Z1[0] to stack + vmovdqa %xmm5, 400(%rsp) // save Z1[3]Z1[2] to stack + vpor %xmm4, %xmm5, %xmm5 // Z1[1]Z1[0] | Z1[3]Z1[2] + + vmovdqu (%rdx), %xmm0 // X2[1]X2[0] --> xmm0 + vpshufd $0xb1, %xmm5, %xmm3 // Order(10 11 00 01) --> [2 3 0 1] with 32bit + vmovdqu 16(%rdx), %xmm1 // X2[3]X2[2] --> xmm1 + vmovdqu 32(%rdx), %xmm2 // Y2[1]Y2[0] --> xmm2 + vpor %xmm3, %xmm5, %xmm5 // [2 3 0 1] | [3 2 1 0] + vmovdqu 48(%rdx), %xmm3 // Y2[3]Y2[2] --> xmm3 + vmovdqa %xmm0, 416(%rsp) // save X2[1]X2[0] to stack + vpshufd $0x1e, %xmm5, %xmm4 // Order(00 01 11 10) --> [0 1 3 2] + vmovdqa %xmm1, 432(%rsp) // save X2[3]X2[1] to stack + vpor %xmm0, %xmm1, %xmm1 // X2[1]X2[0] | X2[3]X2[2] + + vmovq %rdi, %xmm0 // save rdi to xmm0 + vmovdqa %xmm2, 448(%rsp) // save X2[1]X2[0] to stack + vmovdqa %xmm3, 464(%rsp) // save X2[3]X2[2] to stack + vpor %xmm2, %xmm3, %xmm3 // Y2[1]Y2[0] | Y2[3]Y2[2] + vpor %xmm4, %xmm5, %xmm5 + vpxor %xmm4, %xmm4, %xmm4 // 0 + vpor %xmm1, %xmm3, %xmm3 // X2[1]X2[0] | X2[3]X2[2] | Y2[1]Y2[0] | Y2[3]Y2[2] + +.balign 32 + /* Z1Z1 = Z1 ^ 2 */ + leaq 64(%rsi), %rsi // addr(z) + leaq 32(%rsp), %rdi // save Z1Z1 to stack + call ECP256_SqrCore_q // Output: r8 - r11 P[1] --> r14 P[3] --> r15 + + vpcmpeqd %xmm4, %xmm5, %xmm5 + vpshufd $0xb1, %xmm3, %xmm4 // Order(10 11 00 01) + vpor %xmm3, %xmm4, %xmm4 + vpshufd $0, %xmm5, %xmm5 // Order(00 00 00 00) + vpshufd $0x1e, %xmm4, %xmm3 // Order(00 01 11 10) + vpor %xmm3, %xmm4, %xmm4 + vpxor %xmm3, %xmm3, %xmm3 + vpcmpeqd %xmm3, %xmm4, %xmm4 + vpshufd $0, %xmm4, %xmm4 + + /* U2 = X2 * Z1Z1 */ + leaq 416(%rsp), %rcx // addr of X2 in stack + leaq 32(%rsp), %rsi // read Z1Z1 from stack + leaq (%rsp), %rdi // save U2 to stack + call ECP256_MulCore_q // ouput: r8 - r11 P[1] --> r14 P[3] --> r15 + + /* H = U2 - X1 */ + leaq 320(%rsp), %rdx // read X1 from stack + leaq 64(%rsp), %rdi // save H to stack + call ECP256_SubCore // input: rdx, r8 - r11 P[1] --> r14 P[3] --> r15 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + /* Z1Z1Z1 = Z1Z1 * Z1 */ + leaq 384(%rsp), %rcx // read Z1 from stack + leaq 32(%rsp), %rsi // read Z1Z1 from stack + leaq 32(%rsp), %rdi // save Z1Z1Z1 to stack + call ECP256_MulCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + /* Z3/2 = H * Z1 */ + leaq 384(%rsp), %rcx // read Z1 from stack + leaq 64(%rsp), %rsi // read H from stack + leaq 288(%rsp), %rdi // save Z3/2 to stack + call ECP256_MulCore_q // P[1] --> r14 P[3] --> r15 + + /* S2 = Y2 * Z1Z1Z1 */ + leaq 448(%rsp), %rcx // read Y2 from stack + leaq 32(%rsp), %rsi // read Z1Z1Z1 from stack + leaq 32(%rsp), %rdi // save S2 to stack + call ECP256_MulCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* r/2 = (S2 - Y1) */ + leaq 352(%rsp), %rdx // read Y1 from stack + leaq 96(%rsp), %rdi // save r/2 to stack + call ECP256_SubCore // output: r8-r11 P[1] --> r14 P[3] --> r15 + movq %r8, (%rdi) // save r/2 to stack + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + /* I/4 = H ^ 2 */ + leaq 64(%rsp), %rsi // read H from stack + movq (%rsi), %rax // a[0] + movq 8(%rsi), %r14 // a[1] + movq 16(%rsi), %rbp // a[2] + movq 24(%rsi), %r15 // a[3] + leaq 128(%rsp), %rdi // save I/4 to stack + call ECP256_SqrCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* (r/2)^2 = (r^2)/4 */ + leaq 96(%rsp), %rsi // read r/2 from stack + movq (%rsi), %rax // a[0] + movq 8(%rsi), %r14 // a[1] + movq 16(%rsi), %rbp // a[2] + movq 24(%rsi), %r15 // a[3] + leaq 192(%rsp), %rdi // save (r^2)/4 to stack + call ECP256_SqrCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* J/4 = I/4 * H */ + leaq 128(%rsp), %rcx // read I/4 from stack + leaq 64(%rsp), %rsi // read H from stack + leaq 160(%rsp), %rdi // save J/4 to stack + call ECP256_MulCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* V/4 = X1 * I */ + leaq 320(%rsp), %rcx // read X1 from stack + leaq 128(%rsp), %rsi // read I/4 from stack + leaq (%rsp), %rdi // save V/4 to stack + call ECP256_MulCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + xorq %r12, %r12 + addq %r8, %r8 + adcq %r9, %r9 + movq %r8, %rax + adcq %r10, %r10 + adcq %r11, %r11 + movq %r9, %rbp + adcq $0, %r12 + + subq $-1, %r8 + movq %r10, %rcx + sbbq %r14, %r9 + sbbq $0, %r10 + movq %r11, %r13 + sbbq %r15, %r11 + sbbq $0, %r12 + leaq 192(%rsp), %rsi // read (r^2)/4 from + cmovcq %rax,%r8 // b[0] V/2 --> r8-r11 + cmovcq %rbp,%r9 // b[1] + cmovcq %rcx,%r10 // b[2] + cmovcq %r13,%r11 // b[3] + + /* (r^2 - 2 * V)/4 = (r^2)/4 - V/2 */ + xorq %r13, %r13 + movq (%rsi), %rax // a[0] + movq 8(%rsi), %rcx // a[1] + movq 16(%rsi), %rdx // a[2] + movq 24(%rsi), %r12 // a[3] + + subq %r8, %rax + sbbq %r9, %rcx + movq %rax, %r8 + sbbq %r10, %rdx + sbbq %r11, %r12 + movq %rcx, %r9 + sbbq $0, %r13 + + addq $-1, %r8 // a - b + P + movq %rdx, %r10 + adcq %r14, %r9 + adcq $0, %r10 + movq %r12, %r11 + adcq %r15, %r11 + testq %r13, %r13 + + cmovzq %rax, %r8 + cmovzq %rcx, %r9 + cmovzq %rdx, %r10 + cmovzq %r12, %r11 // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* X3/4 = (r^2 - 2 * V - J)/4 = (r^2 - 2 * V)/4 - J/4 */ + leaq 160(%rsp), %rdx // read J/4 from stack + leaq 224(%rsp), %rdi // save (r^2 - 2 * V - J)/4 to stack + call ECP256_SubCore // output: r8-r11 P[1] --> r14 P[3] --> r15 + movq %r8, (%rdi) // b[0] + movq %r9, 8(%rdi) // b[1] + movq %r10, 16(%rdi) // b[2] + movq %r11, 24(%rdi) // b[3] + + /* (V - X3)/4 = V/4 - X3/4 */ + leaq (%rsp), %rsi // read (r^2 - 2 * V)/4 from stack + xorq %r13, %r13 + movq (%rsi), %rax // a[0] + movq 8(%rsi), %rcx // a[1] + movq 16(%rsi), %rdx // a[2] + movq 24(%rsi), %r12 // a[3] + + subq %r8, %rax + sbbq %r9, %rcx + movq %rax, %r8 + sbbq %r10, %rdx + sbbq %r11, %r12 + movq %rcx, %r9 + sbbq $0, %r13 + movq %rdx, %r10 + movq %r12, %r11 + + addq $-1, %r8 // a - b + P + adcq %r14, %r9 + adcq $0, %r10 + adcq %r15, %r11 + testq %r13, %r13 + + cmovzq %rax, %r8 + cmovzq %rcx, %r9 + cmovzq %rdx, %r10 + cmovzq %r12, %r11 + + leaq 64(%rsp), %rdi // save (V - X3)/4 from stack + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* (J * Y1)/4 = Y1 * J/4 */ + leaq 352(%rsp), %rcx // read Y1 from stack + leaq 160(%rsp), %rsi // read J/4 from stack + leaq 32(%rsp), %rdi // save (J * Y1)/4 to stack + call ECP256_MulCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* (r * (V - X3)/8) = (V - X3)/4 * r/2 */ + leaq 96(%rsp), %rcx // read r/2 from stack + leaq 64(%rsp), %rsi // read (V - X3)/4 from stack + leaq 64(%rsp), %rdi // save (r * (V - X3)/8) to stack + call ECP256_MulCore_q // output: r8-r11 P[1] --> r14 P[3] --> r15 + + /* Y3/8 = (r * (V - X3)/8) - (J * Y1)/4 */ + leaq 32(%rsp), %rdx // read (J * Y1)/4 from stack + leaq 256(%rsp), %rdi // save Y3/8 + call ECP256_SubCore + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + vmovq %xmm0, %rdi + + vmovdqa %xmm5, %xmm0 + vmovdqa %xmm5, %xmm1 + vpandn 288(%rsp), %xmm0, %xmm0 + vmovdqa %xmm5, %xmm2 + vpandn 304(%rsp), %xmm1, %xmm1 + vmovdqa %xmm5, %xmm3 + vpand .Lone_mont(%rip), %xmm2, %xmm2 + vpand .Lone_mont+16(%rip), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 + vpor %xmm1, %xmm3, %xmm3 + + vmovdqa %xmm4, %xmm0 + vmovdqa %xmm4, %xmm1 + vpandn %xmm2, %xmm0, %xmm0 + vmovdqa %xmm4, %xmm2 + vpandn %xmm3, %xmm1, %xmm1 + vmovdqa %xmm4, %xmm3 + vpand 384(%rsp), %xmm2, %xmm2 + vpand 400(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 + vpor %xmm1, %xmm3, %xmm3 + vmovdqu %xmm2, 64(%rdi) + vmovdqu %xmm3, 80(%rdi) + + vmovdqa %xmm5, %xmm0 + vmovdqa %xmm5, %xmm1 + vpandn 224(%rsp), %xmm0, %xmm0 + vmovdqa %xmm5, %xmm2 + vpandn 224+16(%rsp), %xmm1, %xmm1 + vmovdqa %xmm5, %xmm3 + vpand 416(%rsp), %xmm2, %xmm2 + vpand 416+16(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 + vpor %xmm1, %xmm3, %xmm3 + + vmovdqa %xmm4, %xmm0 + vmovdqa %xmm4, %xmm1 + vpandn %xmm2, %xmm0, %xmm0 + vmovdqa %xmm4, %xmm2 + vpandn %xmm3, %xmm1, %xmm1 + vmovdqa %xmm4, %xmm3 + vpand 320(%rsp), %xmm2, %xmm2 + vpand 336(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 + vpor %xmm1, %xmm3, %xmm3 + vmovdqu %xmm2, 0(%rdi) + vmovdqu %xmm3, 16(%rdi) + + vmovdqa %xmm5, %xmm0 + vmovdqa %xmm5, %xmm1 + vpandn 256(%rsp), %xmm0, %xmm0 + vmovdqa %xmm5, %xmm2 + vpandn 272(%rsp), %xmm1, %xmm1 + vmovdqa %xmm5, %xmm3 + vpand 448(%rsp), %xmm2, %xmm2 + vpand 464(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 + vpor %xmm1, %xmm3, %xmm3 + + vmovdqa %xmm4, %xmm0 + vmovdqa %xmm4, %xmm1 + vpandn %xmm2, %xmm0, %xmm0 + vmovdqa %xmm4, %xmm2 + vpandn %xmm3, %xmm1, %xmm1 + vmovdqa %xmm4, %xmm3 + vpand 352(%rsp), %xmm2, %xmm2 + vpand 368(%rsp), %xmm3, %xmm3 + vpor %xmm0, %xmm2, %xmm2 + vpor %xmm1, %xmm3, %xmm3 + vmovdqu %xmm2, 32(%rdi) + vmovdqu %xmm3, 48(%rdi) + + addq $488, %rsp + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbx + popq %rbp + ret +.cfi_endproc +.size ECP256_AddAffine, .-ECP256_AddAffine + +/** + * Function description: This interface is used to store the G-16G pre-computation table discretely. + * Function prototype: void ECP256_Scatterw5(P256_Point *table, const P256_Point *point, uint32_t index); + * Input register: + * rdi: Points to the base address of the pre-computation table. + * rsi: Points to P256_Point. + * rdx: Index value. The value ranges from 1 to 16. + * Change register: rdx, rsi, rdi, r8, r9, r10, r11 + * Output register: None + * Function/Macro Call: + */ +.globl ECP256_Scatterw5 +.type ECP256_Scatterw5,@function +.align 32 +ECP256_Scatterw5: +.cfi_startproc + subq $1, %rdx // index - 1 + movq (%rsi), %r8 // x[0] + movq 8(%rsi), %r9 // x[1] + movq 16(%rsi), %r10 // x[2] + movq 24(%rsi), %r11 // x[3] + leaq (%rdi, %rdx, 8), %rdi // base = base + (index - 1) * 8 . offset for table + + movq %r8, (%rdi) // x[0] --> base + 0 * 128 + movq %r9, 128(%rdi) // x[1] --> base + 1 * 128 + movq %r10, 256(%rdi) // x[2] --> base + 2 * 128 + movq %r11, 384(%rdi) // x[3] --> base + 3 * 128 + leaq 512(%rdi), %rdi // base + 128 * 4 + + leaq 32(%rsi), %rsi // addr(y) --> rsi + + movq (%rsi), %r8 // y[0] + movq 8(%rsi), %r9 // y[1] + movq 16(%rsi), %r10 // y[2] + movq 24(%rsi), %r11 // y[3] + + movq %r8, (%rdi) // y[0] --> base + 4 * 128 + movq %r9, 128(%rdi) // y[1] --> base + 5 * 128 + movq %r10, 256(%rdi) // y[2] --> base + 6 * 128 + movq %r11, 384(%rdi) // y[3] --> base + 7 * 128 + leaq 512(%rdi), %rdi // base + 128 * 8 + + leaq 32(%rsi), %rsi // addr(z) --> rsi + + movq (%rsi), %r8 // z[0] + movq 8(%rsi), %r9 // z[1] + movq 16(%rsi), %r10 // z[2] + movq 24(%rsi), %r11 // z[3] + + movq %r8, (%rdi) // z[0] --> base + 8 * 128 + movq %r9, 128(%rdi) // z[1] --> base + 9 * 128 + movq %r10, 256(%rdi) // z[2] --> base + 10 * 128 + movq %r11, 384(%rdi) // z[3] --> base + 11 * 128 + + ret +.cfi_endproc +.size ECP256_Scatterw5, .-ECP256_Scatterw5 + +/** + * Function description: This interface is used to obtain the G-16G pre-computation table discretely. + * Function prototype: void ECP256_Gatherw5(P256_Point *point, const P256_Point *table, uint32_t index); + * Input register: + * rdi: points to P256_Point. + * rsi: points to the base address of the pre-computation table. + * edx: index value + * Change register: edx, rsi, rdi, r8, r9, r10, r11 + * Output register: None + * Function/Macro Call: + */ +.globl ECP256_Gatherw5 +.type ECP256_Gatherw5,@function +.align 32 +ECP256_Gatherw5: +.cfi_startproc + movq $-1, %rax + xorq %rcx, %rcx + cmp $0, %rdx + cmovzq %rcx, %rax // rax = (rdx == 0) ? 0 : -1 + add %rax, %rdx // rdx = (rdx == 0) ? rdx : (rdx - 1) + + leaq (%rsi, %rdx, 8), %rsi // Calculate offset. base = base + (index -1) * 8 + + movq (%rsi), %r8 // x[0] + movq 128(%rsi), %r9 // x[1] + movq 256(%rsi), %r10 // x[2] + movq 384(%rsi), %r11 // x[3] + leaq 512(%rsi), %rsi // base += 512 + + andq %rax, %r8 + andq %rax, %r9 + andq %rax, %r10 + andq %rax, %r11 + + movq %r8, (%rdi) // Write back + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + leaq 32(%rdi), %rdi // Write back point offset + + movq (%rsi), %r8 // y[0] + movq 128(%rsi), %r9 // y[1] + movq 256(%rsi), %r10 // y[2] + movq 384(%rsi), %r11 // y[3] + leaq 512(%rsi), %rsi // base += 512 + + andq %rax, %r8 + andq %rax, %r9 + andq %rax, %r10 + andq %rax, %r11 + + movq %r8, (%rdi) // Write back + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + leaq 32(%rdi), %rdi // Write back point offset + + movq (%rsi), %r8 // z[0] + movq 128(%rsi), %r9 // z[1] + movq 256(%rsi), %r10 // z[2] + movq 384(%rsi), %r11 // z[3] + + andq %rax, %r8 + andq %rax, %r9 + andq %rax, %r10 + andq %rax, %r11 + + movq %r8, (%rdi) // Write back + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + ret +.cfi_endproc +.size ECP256_Gatherw5, .-ECP256_Gatherw5 + +/** + * Function description: Discretely obtains affine points in the precomputation table. + * Function prototype: void ECP256_Gatherw7(P256_AffinePoint *point, const P256_AffinePoint *table, uint32_t index); + * Input register: + * rdi: points to the returned P256_AffinePoint. + * rsi: points to the base address of the pre-computation table. + * rdx: index value + * Change register: rax, rcx, rdx, rsi, rdi, rbp, r8, r9, r10 + * Output register: None + * Function/Macro Call: + */ +.globl ECP256_Gatherw7 +.type ECP256_Gatherw7,@function +.align 32 +ECP256_Gatherw7: +.cfi_startproc + movq $-1, %rax + xorq %rcx, %rcx + cmp $0, %rdx + cmovzq %rcx, %rax // rax = (rdx == 0) ? 0 : -1 + addq %rax, %rdx // rdx = (rdx == 0) ? rdx : (rdx - 1) + subq $63, %rdx // rdx = (rdx == 0) ? (rdx - 63) : (rdx - 1 - 63) + subq %rdx, %rsi // rsi = (rdx == 0) ? (rsi + 63 - rdx) : (rsi + 64 - rdx) + movq $8, %r10 // Loop value + +.Lgather_w7_loop: + xorq %r8, %r8 // Empty reg for data low 32 + xorq %r9, %r9 // Empty reg for data high 32 + movb 192(%rsi), %r8b // r8 = [0 0 0 byte(3)] + movb 448(%rsi), %r9b // r9 = [0 0 0 byte(7)] + shlq $8, %r8 // r8 = [0 0 byte(3) 0] + shlq $8, %r9 // r9 = [0 0 byte(7) 0] + movb 128(%rsi), %r8b // r8 = [0 0 byte(3) byte(2)] + movb 384(%rsi), %r9b // r9 = [0 0 byte(7) byte(6)] + shlq $8, %r8 // r8 = [0 byte(3) byte(2) 0] + shlq $8, %r9 // r9 = [0 byte(7) byte(6) 0] + movb 64(%rsi), %r8b // r8 = [0 byte(3) byte(2) byte(1)] + movb 320(%rsi), %r9b // r9 = [0 byte(7) byte(6) byte(5)] + shlq $8, %r8 // r8 = [byte(3) byte(2) byte(1) 0] + shlq $8, %r9 // r9 = [byte(7) byte(6) byte(5) 0] + movb (%rsi), %r8b // r8 = [byte(3) byte(2) byte(1) byte(0)] + movb 256(%rsi), %r9b // r9 = [byte(7) byte(6) byte(5) byte(4)] + leaq 512(%rsi), %rsi // base += 64 * 8 + shlq $32, %r9 // r9 = [byte(7) byte(6) byte(5) byte(4) 0 0 0 0] + orq %r9, %r8 // r8 = [byte(7) byte(6) byte(5) byte(4) byte(3) byte(2) byte(1) byte(0)] + + andq %rax, %r8 + movq %r8, (%rdi) + leaq 8(%rdi), %rdi + + subq $1, %r10 + jnz .Lgather_w7_loop + + ret +.cfi_endproc +.size ECP256_Gatherw7, .-ECP256_Gatherw7 + +#endif diff --git a/crypto/ecc/src/asm/ecp_sm2_armv8.S b/crypto/ecc/src/asm/ecp_sm2_armv8.S new file mode 100644 index 00000000..5dae08d7 --- /dev/null +++ b/crypto/ecc/src/asm/ecp_sm2_armv8.S @@ -0,0 +1,807 @@ +/* + * 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. + */ +.file "ecp_sm2_armv8.S" +.text + +#define s0 x7 +#define s1 x8 +#define s2 x9 +#define s3 x10 +#define s4 x11 +#define s5 x12 +#define s6 x13 +#define s7 x14 + +# The polynomial +.align 4 +.Lpoly: +.quad 0xffffffffffffffff, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffeffffffff +# The order of polynomial +.Lord: +.quad 0x53bbf40939d54123, 0x7203df6b21c6052b, 0xffffffffffffffff, 0xfffffffeffffffff + +### Right shift: in >> 1 ### +# void ECP_Sm2BnRshift1(uint64_t *a) +# 1-bit right shift +# a %x0 +.globl ECP_Sm2BnRshift1 +.type ECP_Sm2BnRshift1, @function +.align 4 +ECP_Sm2BnRshift1: + + # Load inputs + ldp x9, x10, [x0] + ldp x11, x12, [x0, #16] + + + # Right shift + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + lsr x12, x12, #1 + + # Store results + stp x9, x10, [x0] + stp x11, x12, [x0, #16] + + ret +.size ECP_Sm2BnRshift1, .-ECP_Sm2BnRshift1 + + +### Modular div by 2: res = in/2 mod p ### +# void ECP_Sm2DivBy2(uint64_t *r, const uint64_t *a) +# Modular div by 2 +# r %x0 +# a %x1 +.globl ECP_Sm2DivBy2 +.type ECP_Sm2DivBy2, @function +.align 4 +ECP_Sm2DivBy2: + eor x13, x13, x13 + eor x15, x15, x15 + + # Load inputs + ldp x9, x10, [x1] + ldp x11, x12, [x1, #16] + + mov x14, x9 + + # Add polynomial + ldr x2, .Lpoly + ldr x3, .Lpoly+8 + ldr x4, .Lpoly+16 + ldr x5, .Lpoly+24 + adds x9, x9, x2 + adcs x10, x10, x3 + adcs x11, x11, x4 + adcs x12, x12, x5 + adcs x13, x13, xzr + + # Parity check + tst x14, #1 + b.ne .not_equal_1 + ldp x9, x10, [x1] + ldp x11, x12, [x1, #16] + mov x13, x15 + +.not_equal_1: + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + extr x12, x13, x12, #1 + + # Store results + stp x9, x10, [x0] + stp x11, x12, [x0, #16] + + ret +.size ECP_Sm2DivBy2, .-ECP_Sm2DivBy2 + + +### Modular mul by 3: r = 3*a mod p ### +# void ECP_Sm2MulBy3(uint64_t *r, const uint64_t *a) +# Modular mul by 3 +# r %rdi +# a %rsi +.globl ECP_Sm2MulBy3 +.type ECP_Sm2MulBy3, @function +.align 4 +ECP_Sm2MulBy3: + # Load inputs + ldp x3, x4, [x1] + ldp x5, x6, [x1, #16] + + # 2*a + adds x3, x3, x3 + adcs x4, x4, x4 + adcs x5, x5, x5 + adcs x6, x6, x6 + adcs x7, xzr, xzr + + mov x8, x3 + mov x9, x4 + mov x10, x5 + mov x11, x6 + + # Sub polynomial + adrp x2, .Lpoly + add x2, x2, :lo12:.Lpoly + ldp x12, x13, [x2] + ldp x14, x15, [x2, #16] + subs x3, x3, x12 + sbcs x4, x4, x13 + sbcs x5, x5, x14 + sbcs x6, x6, x15 + sbcs x7, x7, xzr + + csel x3, x3, x8, cs + csel x4, x4, x9, cs + csel x5, x5, x10, cs + csel x6, x6, x11, cs + eor x7, x7, x7 + + # 3*a + ldp x12, x13, [x1] + ldp x14, x15, [x1, #16] + adds x3, x3, x12 + adcs x4, x4, x13 + adcs x5, x5, x14 + adcs x6, x6, x15 + adcs x7, xzr, xzr + + mov x8, x3 + mov x9, x4 + mov x10, x5 + mov x11, x6 + + # Sub polynomial + adrp x2, .Lpoly + add x2, x2, :lo12:.Lpoly + ldp x12, x13, [x2] + ldp x14, x15, [x2, #16] + subs x3, x3, x12 + sbcs x4, x4, x13 + sbcs x5, x5, x14 + sbcs x6, x6, x15 + sbcs x7, x7, xzr + + csel x3, x3, x8, cs + csel x4, x4, x9, cs + csel x5, x5, x10, cs + csel x6, x6, x11, cs + + # Store results + stp x3, x4, [x0] + stp x5, x6, [x0, #16] + + ret +.size ECP_Sm2MulBy3, .-ECP_Sm2MulBy3 + +#define bn_mod_add(mod) \ + /* Load inputs */ \ + ldp x3,x4,[x1]; \ + ldp x5,x6,[x1,#0x10]; \ + /* Addition */ \ + ldp x7,x8,[x2]; \ + ldp x9,x10,[x2,#0x10]; \ + adds x3,x3,x7; \ + adcs x4,x4,x8; \ + adcs x5,x5,x9; \ + adcs x6,x6,x10; \ + adc x15,xzr,xzr; \ + mov x11,x3; \ + mov x12,x4; \ + mov x13,x5; \ + mov x14,x6; \ + /* Sub polynomial */ \ + adrp x2, mod; \ + add x2, x2, :lo12:mod; \ + ldp x7,x8,[x2]; \ + ldp x9,x10,[x2,#0x10]; \ + subs x11,x11,x7; \ + sbcs x12,x12,x8; \ + sbcs x13,x13,x9; \ + sbcs x14,x14,x10; \ + sbcs x15,x15,xzr; \ + csel x3,x3,x11,cc; \ + csel x4,x4,x12,cc; \ + csel x5,x5,x13,cc; \ + csel x6,x6,x14,cc; \ + /* Store results */ \ + stp x3,x4,[x0]; \ + stp x5,x6,[x0,#0x10]; \ + +#define bn_mod_sub(mod) \ + /* Load inputs */ \ + ldp x3,x4,[x1]; \ + ldp x5,x6,[x1,#0x10]; \ + /* Addition */ \ + ldp x7,x8,[x2]; \ + ldp x9,x10,[x2,#0x10]; \ + subs x3,x3,x7; \ + sbcs x4,x4,x8; \ + sbcs x5,x5,x9; \ + sbcs x6,x6,x10; \ + sbc x15,xzr,xzr; \ + mov x11,x3; \ + mov x12,x4; \ + mov x13,x5; \ + mov x14,x6; \ + /* Add polynomial */ \ + adrp x2, mod; \ + add x2, x2, :lo12:mod; \ + ldp x7,x8,[x2]; \ + ldp x9,x10,[x2,#0x10]; \ + adds x11,x11,x7; \ + adcs x12,x12,x8; \ + adcs x13,x13,x9; \ + adcs x14,x14,x10; \ + tst x15,x15; \ + csel x3,x3,x11,eq; \ + csel x4,x4,x12,eq; \ + csel x5,x5,x13,eq; \ + csel x6,x6,x14,eq; \ + /* Store results */ \ + stp x3,x4,[x0]; \ + stp x5,x6,[x0,#0x10]; \ + + +### Modular add: r = a+b mod p ### +.globl ECP_Sm2Add +.type ECP_Sm2Add, @function +.align 4 +ECP_Sm2Add: + bn_mod_add(.Lpoly); + ret +.size ECP_Sm2Add, .-ECP_Sm2Add + +### Modular sub: r = a-b mod p ### +.globl ECP_Sm2Sub +.type ECP_Sm2Sub, @function +.align 4 + +ECP_Sm2Sub: + bn_mod_sub(.Lpoly); + ret +.size ECP_Sm2Sub, .-ECP_Sm2Sub + +### Modular add: r = a+b mod n/p, where n = ord(p) ### +.globl ECP_Sm2AddModOrd +.type ECP_Sm2AddModOrd, @function +.align 4 +ECP_Sm2AddModOrd: + bn_mod_add(.Lord); + ret +.size ECP_Sm2AddModOrd, .-ECP_Sm2AddModOrd + +### Modular sub: r = a-b mod n/p, where n = ord(p) ### +.globl ECP_Sm2SubModOrd +.type ECP_Sm2SubModOrd, @function +.align 4 +ECP_Sm2SubModOrd: + bn_mod_sub(.Lord); + ret +.size ECP_Sm2SubModOrd, .-ECP_Sm2SubModOrd + +.macro RDC + # registers map + # x3 x4 x5 x6 x15 + # rsi rax rcx rdx rbx + + # r = a mod p256 + # a = a15 | a14 | ... | a0, where ai are 32–bit quantities + # | a7 | a6 | a5 | a4 | a3 | a2 | a1 | a0 | (+) + # | a8 | a11 | a10 | a9 | a8 | 0 | a9 | a8 | (+) + # | a9 | a14 | a13 | a12 | a11 | 0 | a10 | a9 | (+) + # | a10 | a15 | a14 | a13 | a12 | 0 | a11 | a10 | (+) + # | a11 | 0 | a15 | a14 | a13 | 0 | a12 | a11 | (+) + # | a12 | 0 | a15 | a14 | a13 | 0 | a13 | a12 | (+) + # | a12 | 0 | 0 | a15 | a14 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | a15 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | 0 | 0 | a15 | a14 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | a15 | a14 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | 0 | 0 | 0 | 0 | 0 | a8 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a9 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a13 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a14 | 0 | 0 | (-) + # | U[7]| U[6]| U[5]| U[4]| U[3]| U[2]| U[1]| U[0]| + # | V[3] | V[2] | V[1] | V[0] | + # until r < p256 + # s7 (a15|a14), s6 (a13|a12), s5 (a11|a10), s4 (a9|a8) + # s3 (a7|a6), s2 (a5|a4), s1 (a3|a2), s0 (a1|a0) + + # 1. 64-bit addition + eor x3, x3, x3 // to store all carry + eor x4, x4, x4 + mov x5, s6 // rcx <- s6 + mov x6, s4 // rdx <- s4 + # a13 | a12 + adds x5, x5, s7 // rcx <- s6 + s7 + adcs x4, xzr, xzr // rax <- carry(s6+s7) + adds x5, x5, s7 // rcx <- s6 + 2*s7 + adcs x4, x4, xzr + # a9 | a8 + mov x15, x4 // rbx <- carry (rax) + adds x6, x6, x5 // rdx <- s4 + s6 + 2*s7 + adcs x15, x15, xzr + adds x6, x6, s5 // rdx <- s4 + s5 + s6 + 2*s7 + adcs x15, x15, xzr + # sum + adds s0, s0, x6 // s0 <- s0 + s4 + s5 + s6 + 2*s7 + adcs s1, s1, x15 // s1 <- s1 + rbx + carry + adcs s2, s2, x5 // s2 <- s2 + s6 + 2*s7 + carry + adcs s3, s3, s7 + adcs x3, xzr, xzr + # add carry + adds s3, s3, x4 + adcs x3, x3, xzr // all carry + + stp s0, s1, [sp, #32] + stp s2, s3, [sp, #48] + # 2. 4 -> 8 64-bit to 32-bit spread + mov x4, #0xffffffff + mov s0, s4 + mov s1, s5 + mov s2, s6 + mov s3, s7 + and s0, s0, x4 // a8 + and s1, s1, x4 // a10 + and s2, s2, x4 // a12 + and s3, s3, x4 // a14 + lsr s4, s4, #32 // a9 + lsr s5, s5, #32 // a11 + lsr s6, s6, #32 // a13 + lsr s7, s7, #32 // a15 + # 3. 32-bit addition + mov x4, s3 + add x4, x4, s2 // rax <- a12 + a14 + mov x15, s3 + add x15, x15, s1 // rbx <- a10 + a14 + mov x5, s7 + add x5, x5, s6 // rcx <- a13 + a15 + mov x6, s0 + add x6, x6, s4 // rdx <- a8 + a9 + add s7, s7, s5 // s7 <- a11 + a15 + mov s2, x5 // s2 <- a13 + a15 + add s2, s2, x4 // s2 <- a12 + a13 + a14 + a15 + add s1, s1, s2 // s1 <- a10 + a12 + a13 + a14 + a15 + add s1, s1, s2 // s1 <- a10 + 2*(a12 + a13 + a14 + a15) + add s1, s1, x6 // s1 <- a8 + a9 + a10 + 2*(a12 + a13 + a14 + a15) + add s1, s1, s5 // s1 <- a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + add s2, s2, s6 // s2 <- a12 + 2*a13 + a14 + a15 + add s2, s2, s5 // s2 <- a11 + a12 + 2*a13 + a14 + a15 + add s2, s2, s0 // s2 <- a8 + a11 + a12 + 2*a13 + a14 + a15 + add x6, x6, s3 // rdx <- a8 + a9 + a14 + add x6, x6, s6 // rdx <- a8 + a9 + a13 + a14 + add s4, s4, x5 // s4 <- a9 + a13 + a15 + add s5, s5, s4 // s5 <- a9 + a11 + a13 + a15 + add s5, s5, x5 // s5 <- a9 + a11 + 2*(a13 + a15) + add x4, x4, x15 // rax <- a10 + a12 + 2*a14 + + # U[0] s5 a9 + a11 + 2*(a13 + a15) + # U[1] %rax a10 + a12 + 2*a14 + # U[2] + # U[3] s2 a8 + a11 + a12 + 2*a13 + a14 + a15 + # U[4] s4 a9 + a13 + a15 + # U[5] %rbx a10 + a14 + # U[6] s7 a11 + a15 + # U[7] s1 a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + # sub %rdx a8 + a9 + a13 + a14 + + # s0 s3 s6 %rcx + + # 4. 8 -> 4 32-bit to 64-bit + # sub %rdx + mov s0, x4 + lsl s0, s0, #32 + extr x4, s2, x4, #32 + extr s2, x15, s2, #32 + extr x15, s1, x15, #32 + lsr s1, s1, #32 + + # 5. 64-bit addition + adds s5, s5, s0 + adcs x4, x4, xzr + adcs s4, s4, s2 + adcs s7, s7, x15 + adcs x3, x3, s1 + + # V[0] s5 + # V[1] %rax + # V[2] s4 + # V[3] s7 + # carry %rsi + # sub %rdx + + # 5. ADD & SUB + ldp s0, s1, [sp, #32] + ldp s2, s3, [sp, #48] + + # ADD + adds s0, s0, s5 + adcs s1, s1, x4 + adcs s2, s2, s4 + adcs s3, s3, s7 + adcs x3, x3, xzr + # SUB + subs s1, s1, x6 + sbcs s2, s2, xzr + sbcs s3, s3, xzr + sbcs x3, x3, xzr + + # 6. MOD + # First Mod + mov x4, x3 + lsl x4, x4, #32 + mov x5, x4 + subs x4, x4, x3 + + adds s0, s0, x3 + adcs s1, s1, x4 + adcs s2, s2, xzr + adcs s3, s3, x5 + + # Last Mod + # return y - p if y > p else y + mov s4, s0 + mov s5, s1 + mov s6, s2 + mov s7, s3 + + adrp x3, .Lpoly + add x3, x3, :lo12:.Lpoly + ldp x4, x15, [x3] + ldp x16, x17, [x3, #16] + + eor x5, x5, x5 + adcs x5, xzr, xzr + + subs s0, s0, x4 + sbcs s1, s1, x15 + sbcs s2, s2, x16 + sbcs s3, s3, x17 + sbcs x5, x5, xzr + + csel s0, s0, s4, cs + csel s1, s1, s5, cs + csel s2, s2, s6, cs + csel s3, s3, s7, cs + + stp s0, s1, [x0] + stp s2, s3, [x0, #16] +.endm + +### Modular mul: r = a*b mod p ### +# void ECP_Sm2Mul(uint64_t *r, const uint64_t *a, const uint64_t *b) +# 256-bit modular multiplication in SM2 +# r %rdi +# a %rsi +# b %rdx +# registers map +# s0 s1 s2 s3 s4 s5 s6 s7 +# x7 x8 x9 x10 x11 x12 x13 x14 x3 x4 x5 x6 x15 +# r8 r9 r10 r11 r12 r13 r14 r15 rax rdx rbx rcx rsi +.globl ECP_Sm2Mul +.type ECP_Sm2Mul, @function +.align 4 +ECP_Sm2Mul: + # Store scalar registers + stp x29, x30, [sp, #-80]! + add x29, sp, #0 + stp x16, x17, [sp, #16] + stp x18, x19, [sp, #64] + + # Load inputs + ldp s0, s1, [x1] + ldp s2, s3, [x1, #16] + ldp s4, s5, [x2] + ldp s6, s7, [x2, #16] + +### multiplication ### + + # ======================== + # s7 s6 s5 s4 + # * s3 s2 s1 s0 + # ------------------------ + # + s0 s0 s0 s0 + # * * * * + # s7 s6 s5 s4 + # s1 s1 s1 s1 + # * * * * + # s7 s6 s5 s4 + # s2 s2 s2 s2 + # * * * * + # s7 s6 s5 s4 + # s3 s3 s3 s3 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s0*s4 ### + mul x16, s0, s4 + umulh x5, s0, s4 + eor x6, x6, x6 + +### s1*s4 + s0*s5 ### + mul x3, s1, s4 + umulh x4, s1, s4 + adds x5, x5, x3 + adcs x6, x6, x4 + eor x15, x15, x15 + + mul x3, s0, s5 + umulh x4, s0, s5 + adds x5, x5, x3 + adcs x6, x6, x4 + adcs x15, x15, xzr + mov x17, x5 + eor x5, x5, x5 + +### s2 * s4 + s1 * s5 + s0 *s6 ### + mul x3, s2, s4 + umulh x4, s2, s4 + adds x6, x6, x3 + adcs x15, x15, x4 + + mul x3, s1, s5 + umulh x4, s1, s5 + adds x6, x6, x3 + adcs x15, x15, x4 + adcs x5, x5, xzr + + mul x3, s0, s6 + umulh x4, s0, s6 + adds x6, x6, x3 + adcs x15, x15, x4 + adcs x5, x5, xzr + mov x18, x6 + eor x6, x6, x6 + +### s3*s4 + s2*s5 + s1*s6 + s0*s7 ### + mul x3, s3, s4 + umulh x4, s3, s4 + adds x15, x15, x3 + adcs x5, x5, x4 + adcs x6, x6, xzr + + mul x3, s2, s5 + umulh x4, s2, s5 + adds x15, x15, x3 + adcs x5, x5, x4 + adcs x6, x6, xzr + + mul x3, s1, s6 + umulh x4, s1, s6 + adds x15, x15, x3 + adcs x5, x5, x4 + adcs x6, x6, xzr + + mul x3, s0 ,s7 + umulh x4, s0, s7 + adds x15, x15, x3 + adcs x5, x5, x4 + adcs x6, x6, xzr + mov x19, x15 + eor x15, x15, x15 + +### s3*s5 + s2*s6 + s1*s7 ### + mul x3, s3, s5 + umulh x4, s3, s5 + adds x5, x5, x3 + adcs x6, x6, x4 + # carry + adcs x15, x15, xzr + + mul x3, s2, s6 + umulh x4, s2, s6 + adds x5, x5, x3 + adcs x6, x6, x4 + adcs x15, x15, xzr + + mul x3, s1, s7 + umulh x4, s1, s7 + adds x5, x5, x3 + adcs x6, x6, x4 + adcs x15, x15, xzr + mov s4, x5 + eor x5, x5, x5 + +### s3*s6 + s2*s7 ### + mul x3, s3, s6 + umulh x4, s3, s6 + adds x6, x6, x3 + adcs x15, x15, x4 + adcs x5, x5, xzr + + mul x3, s2, s7 + umulh x4, s2, s7 + adds x6, x6, x3 + adcs x15, x15, x4 + adcs x5, x5, xzr + mov s5, x6 + +### s3*s7 ### + mul x3, s3, s7 + umulh x4, s3, s7 + adds x15, x15, x3 + adcs x5, x5, x4 + mov s6, x15 + mov s7, x5 + + mov s0, x16 + mov s1, x17 + mov s2, x18 + mov s3, x19 + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + # Restore scalar registers + ldp x16, x17, [sp, #16] + ldp x18, x19, [sp, #64] + ldp x29, x30, [sp], #80 + + ret +.size ECP_Sm2Mul, .-ECP_Sm2Mul + +### Modular sqr: r = a^2 mod p ### +# void ECP_Sm2Sqr(uint64_t *r, const uint64_t *a) +# 256-bit modular multiplication in SM2 ### +# r %rdi +# a %rsi +# registers map +# s0 s1 s2 s3 s4 s5 s6 s7 +# x7 x8 x9 x10 x11 x12 x13 x14 x3 x4 x5 x6 x15 x16 x17 +# r8 r9 r10 r11 r12 r13 r14 r15 rax rdx rbx rcx rsi rbp rdi +.globl ECP_Sm2Sqr +.type ECP_Sm2Sqr, @function +.align 4 +ECP_Sm2Sqr: + # Store scalar registers + stp x29, x30, [sp, #-64]! + add x29, sp, #0 + stp x16, x17, [sp, #16] + + # Load inputs + ldp s4, s5, [x1] + ldp s6, s7, [x1, #16] + +### square ### + + # ======================== + # s7 s6 s5 s4 + # * s7 s6 s5 s4 + # ------------------------ + # + s4 s4 s4 s4 + # * * * * + # s7 s6 s5 s4 + # s5 s5 s5 s5 + # * * * * + # s7 s6 s5 s4 + # s6 s6 s6 s6 + # * * * * + # s7 s6 s5 s4 + # s7 s7 s7 s7 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s1 <- s4*s5, s2 <- carry ### + mul s1, s4, s5 + umulh s2, s4, s5 + eor s3, s3, s3 + +### s2 <- s4*s6 + carry(s2), s3 <- carry ### + mul x3, s6, s4 + umulh s3, s6, s4 + adds s2, s2, x3 + adcs s3, s3, xzr + eor s0, s0, s0 + +### s3 <- s4*s7 + s5*s6 + carry(s3), s0 <- carry ### + mul x3, s7, s4 + umulh x4, s7, s4 + adds s3, s3, x3 + adcs s0, s0, x4 + eor x5, x5, x5 + + mul x3, s6, s5 + umulh x4, s6, s5 + adds s3, s3, x3 + adcs s0, s0, x4 + adcs x5, xzr, xzr + +### s0 <- s5*s7 + carry(s0), rbx <- carry ### + mul x3, s7, s5 + umulh x4, s7, s5 + adds s0, s0, x3 + adcs x5, x5, x4 + eor x6, x6, x6 + +### rbx <- s6*s7 + carry(rbx), rcx <- carry ### + mul x3, s7, s6 + umulh x4, s7, s6 + adds x5, x5, x3 + adcs x6, x6, x4 + eor x15, x15, x15 + +### 2*s0|1|2|3 ### + adds s1, s1, s1 + adcs s2, s2, s2 + adcs s3, s3, s3 + adcs s0, s0, s0 + adcs x5, x5, x5 + # update carry + adcs x6, x6, x6 + adcs x15, xzr, xzr + +### rbp <- s4*s4, carry <- rdi ### + mul x16, s4, s4 + umulh x17, s4, s4 + +### s4 <- s5*s5, carry <- s5 ### + mul s4, s5, s5 + umulh s5, s5, s5 + +### s6*s6 ### + mul x3, s6, s6 + umulh x4, s6, s6 + + # s1 += carry(s4*s4) + adds s1, s1, x17 + # s2 += s5*s5 + adcs s2, s2, s4 + # s3 += carry(s5*s5) + adcs s3, s3, s5 + # s4(s0) += s6*s6 + adcs s0, s0, x3 + # s5(rbx) += carry(s6*s6) + adcs x5, x5, x4 + adcs x6, x6, xzr + adcs x15, x15, xzr + +### s7*s7 ### + mul x3, s7, s7 + umulh x4, s7, s7 + # s6(rcx) += s7*s7 + adds x6, x6, x3 + # s7(rsi) += carry(s7*s7) + adcs x15, x15, x4 + + mov s4, s0 + mov s0, x16 + mov s5, x5 + mov s6, x6 + mov s7, x15 + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0= +### Reduction ### + RDC + + # Restore scalar registers + ldp x16, x17, [sp, #16] + ldp x29, x30, [sp], #64 + + ret +.size ECP_Sm2Sqr, .-ECP_Sm2Sqr diff --git a/crypto/ecc/src/asm/ecp_sm2_x86_64.S b/crypto/ecc/src/asm/ecp_sm2_x86_64.S new file mode 100644 index 00000000..364163df --- /dev/null +++ b/crypto/ecc/src/asm/ecp_sm2_x86_64.S @@ -0,0 +1,927 @@ +/* + * 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_CURVE_SM2 + +.file "ecp_sm2_x86_64.S" +.text + +.set s0,%r8 +.set s1,%r9 +.set s2,%r10 +.set s3,%r11 +.set s4,%r12 +.set s5,%r13 +.set s6,%r14 +.set s7,%r15 + +# The polynomial +.align 64 +.Lpoly: +.quad 0xffffffffffffffff, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffeffffffff +# The order of polynomial +.Lord: +.quad 0x53bbf40939d54123, 0x7203df6b21c6052b, 0xffffffffffffffff, 0xfffffffeffffffff + +### Right shift: in >> 1 ### + # void ECP_Sm2BnRshift1(uint64_t *a) + # 1-bit right shift + # a %rdi + .globl ECP_Sm2BnRshift1 + .type ECP_Sm2BnRshift1, @function + .align 64 + +ECP_Sm2BnRshift1: + + # Load inputs + movq (%rdi), %r8 + movq 8(%rdi), %r9 + movq 16(%rdi), %r10 + movq 24(%rdi), %r11 + + # Right shift + shrd $1, %r9, %r8 + shrd $1, %r10, %r9 + shrd $1, %r11, %r10 + shrq $1, %r11 + + # Store results + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + ret + .size ECP_Sm2BnRshift1, .-ECP_Sm2BnRshift1 + +### Modular div by 2: res = in/2 mod p ### + # void ECP_Sm2DivBy2(uint64_t *r, const uint64_t *a) + # Modular div by 2 + # r %rdi + # a %rsi + .globl ECP_Sm2DivBy2 + .type ECP_Sm2DivBy2, @function + .align 64 + +ECP_Sm2DivBy2: + # Store scalar registers + subq $24, %rsp + movq %rbx, (%rsp) + movq %r12, 8(%rsp) + movq %r13, 16(%rsp) + + xorq %r12, %r12 + xorq %r13, %r13 + + # Load inputs + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + + movq %r8, %rax + movq %r9, %rbx + movq %r10, %rcx + movq %r11, %rdx + + # Add polynomial + leaq .Lpoly(%rip), %rsi + addq 0(%rsi), %r8 + adcq 8(%rsi), %r9 + adcq 16(%rsi), %r10 + adcq 24(%rsi), %r11 + adcq $0, %r12 + + # Parity check + testq $1, %rax + + cmovzq %rax, %r8 + cmovzq %rbx, %r9 + cmovzq %rcx, %r10 + cmovzq %rdx, %r11 + cmovzq %r13, %r12 + + shrd $1, %r9, %r8 + shrd $1, %r10, %r9 + shrd $1, %r11, %r10 + shrd $1, %r12, %r11 + + # Store results + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + # Restore scalar registers + movq (%rsp), %rbx + movq 8(%rsp), %r12 + movq 16(%rsp), %r13 + addq $24, %rsp + + ret + .size ECP_Sm2DivBy2, .-ECP_Sm2DivBy2 + +### Modular mul by 3: r = 3*a mod p ### + # void ECP_Sm2MulBy3(uint64_t *r, const uint64_t *a) + # Modular mul by 3 + # r %rdi + # a %rsi + .globl ECP_Sm2MulBy3 + .type ECP_Sm2MulBy3, @function + .align 64 + +ECP_Sm2MulBy3: + + # Store scalar registers + subq $32, %rsp + movq %r12, (%rsp) + movq %r13, 8(%rsp) + movq %r14, 16(%rsp) + movq %r15, 24(%rsp) + + xorq %rax, %rax + + # Load inputs + movq (%rsi), %r8 + movq 8(%rsi), %r9 + movq 16(%rsi), %r10 + movq 24(%rsi), %r11 + + # 2*a + addq %r8, %r8 + adcq %r9, %r9 + adcq %r10, %r10 + adcq %r11, %r11 + adcq $0, %rax + + movq %r8, %r12 + movq %r9, %r13 + movq %r10, %r14 + movq %r11, %r15 + + # Sub polynomial + subq .Lpoly(%rip), %r8 + sbbq .Lpoly+8(%rip), %r9 + sbbq .Lpoly+16(%rip), %r10 + sbbq .Lpoly+24(%rip), %r11 + sbbq $0, %rax + + cmovcq %r12, %r8 + cmovcq %r13, %r9 + cmovcq %r14, %r10 + cmovcq %r15, %r11 + + xorq %rax, %rax + + # 3*a + addq (%rsi), %r8 + adcq 8(%rsi), %r9 + adcq 16(%rsi), %r10 + adcq 24(%rsi), %r11 + adcq $0, %rax + + movq %r8, %r12 + movq %r9, %r13 + movq %r10, %r14 + movq %r11, %r15 + + # Sub polynomial + subq .Lpoly(%rip), %r8 + sbbq .Lpoly+8(%rip), %r9 + sbbq .Lpoly+16(%rip), %r10 + sbbq .Lpoly+24(%rip), %r11 + sbbq $0, %rax + + cmovcq %r12, %r8 + cmovcq %r13, %r9 + cmovcq %r14, %r10 + cmovcq %r15, %r11 + + # Store results + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + + # Restore scalar registers + movq (%rsp), %r12 + movq 8(%rsp), %r13 + movq 16(%rsp), %r14 + movq 24(%rsp), %r15 + addq $32, %rsp + + ret + .size ECP_Sm2MulBy3, .-ECP_Sm2MulBy3 + +#define bn_mod_add(mod) \ + /* Store scalar registers */ \ + subq $32, %rsp; \ + movq %r12, (%rsp); \ + movq %r13, 8(%rsp); \ + movq %r14, 16(%rsp); \ + movq %r15, 24(%rsp); \ + xorq %rax, %rax; \ + /* Load inputs */ \ + movq (%rsi), %r8; \ + movq 8(%rsi), %r9; \ + movq 16(%rsi), %r10; \ + movq 24(%rsi), %r11; \ + /* Addition */ \ + addq (%rdx), %r8; \ + adcq 8(%rdx), %r9; \ + adcq 16(%rdx), %r10; \ + adcq 24(%rdx), %r11; \ + /* Store carry */ \ + adcq $0, %rax; \ + movq %r8, %r12; \ + movq %r9, %r13; \ + movq %r10, %r14; \ + movq %r11, %r15; \ + /* Sub polynomial */ \ + leaq mod, %rsi; \ + subq 0(%rsi), %r8; \ + sbbq 8(%rsi), %r9; \ + sbbq 16(%rsi), %r10; \ + sbbq 24(%rsi), %r11; \ + sbbq $0, %rax; \ + cmovcq %r12, %r8; \ + cmovcq %r13, %r9; \ + cmovcq %r14, %r10; \ + cmovcq %r15, %r11; \ + /* Store results */ \ + movq %r8, (%rdi); \ + movq %r9, 8(%rdi); \ + movq %r10, 16(%rdi); \ + movq %r11, 24(%rdi); \ + /* Restore scalar registers */ \ + movq (%rsp), %r12; \ + movq 8(%rsp), %r13; \ + movq 16(%rsp), %r14; \ + movq 24(%rsp), %r15; \ + addq $32, %rsp; \ + +#define bn_mod_sub(mod) \ + /* Store scalar registers */ \ + subq $32, %rsp; \ + movq %r12, (%rsp); \ + movq %r13, 8(%rsp); \ + movq %r14, 16(%rsp); \ + movq %r15, 24(%rsp); \ + xorq %rax, %rax; \ + /* Load inputs */ \ + movq (%rsi), %r8; \ + movq 8(%rsi), %r9; \ + movq 16(%rsi), %r10; \ + movq 24(%rsi), %r11; \ + /* Subtraction */ \ + subq (%rdx), %r8; \ + sbbq 8(%rdx), %r9; \ + sbbq 16(%rdx), %r10; \ + sbbq 24(%rdx), %r11; \ + sbbq $0, %rax; \ + movq %r8, %r12; \ + movq %r9, %r13; \ + movq %r10, %r14; \ + movq %r11, %r15; \ + /* Add polynomial */ \ + leaq mod, %rsi; \ + addq 0(%rsi), %r8; \ + adcq 8(%rsi), %r9; \ + adcq 16(%rsi), %r10; \ + adcq 24(%rsi), %r11; \ + testq %rax, %rax; \ + cmovzq %r12, %r8; \ + cmovzq %r13, %r9; \ + cmovzq %r14, %r10; \ + cmovzq %r15, %r11; \ + /* Store results */ \ + movq %r8, (%rdi); \ + movq %r9, 8(%rdi); \ + movq %r10, 16(%rdi); \ + movq %r11, 24(%rdi); \ + /* Restore scalar registers */ \ + movq (%rsp), %r12; \ + movq 8(%rsp), %r13; \ + movq 16(%rsp), %r14; \ + movq 24(%rsp), %r15; \ + addq $32, %rsp; \ + +### Modular add: r = a+b mod n/p, where n = ord(p) ### + # void ECP_Sm2Add(uint64_t *r, const uint64_t *a, const uint64_t *b) + # Modular poly add + # r %rdi + # a %rsi + # b %rdx + .globl ECP_Sm2Add + .type ECP_Sm2Add, @function + .align 64 + +ECP_Sm2Add: + + bn_mod_add(.Lpoly(%rip)) + + ret + .size ECP_Sm2Add, .-ECP_Sm2Add + + # void ECP_Sm2AddModOrd(uint64_t *r, const uint64_t *a, const uint64_t *b) + # Modular order add + # r %rdi + # a %rsi + # b %rdx + .globl ECP_Sm2AddModOrd + .type ECP_Sm2AddModOrd, @function + .align 64 + +ECP_Sm2AddModOrd: + + bn_mod_add(.Lord(%rip)) + + ret + .size ECP_Sm2AddModOrd, .-ECP_Sm2AddModOrd + +### Modular sub: r = a-b mod n/p, where n = ord(p) ### + # void ECP_Sm2Sub(uint64_t *r, const uint64_t *a, const uint64_t *b) + # Modular poly sub + # r %rdi + # a %rsi + # b %rdx + .globl ECP_Sm2Sub + .type ECP_Sm2Sub, @function + .align 64 + +ECP_Sm2Sub: + + bn_mod_sub(.Lpoly(%rip)) + + ret + .size ECP_Sm2Sub, .-ECP_Sm2Sub + + # void ECP_Sm2SubModOrd(uint64_t *r, const uint64_t *a, const uint64_t *b) + # Modular order sub + # r %rdi + # a %rsi + # b %rdx + .globl ECP_Sm2SubModOrd + .type ECP_Sm2SubModOrd, @function + .align 64 + +ECP_Sm2SubModOrd: + + bn_mod_sub(.Lord(%rip)) + + ret + .size ECP_Sm2SubModOrd, .-ECP_Sm2SubModOrd + +.macro RDC + # r = a mod p256 + # a = a15 | a14 | ... | a0, where ai are 32–bit quantities + # | a7 | a6 | a5 | a4 | a3 | a2 | a1 | a0 | (+) + # | a8 | a11 | a10 | a9 | a8 | 0 | a9 | a8 | (+) + # | a9 | a14 | a13 | a12 | a11 | 0 | a10 | a9 | (+) + # | a10 | a15 | a14 | a13 | a12 | 0 | a11 | a10 | (+) + # | a11 | 0 | a15 | a14 | a13 | 0 | a12 | a11 | (+) + # | a12 | 0 | a15 | a14 | a13 | 0 | a13 | a12 | (+) + # | a12 | 0 | 0 | a15 | a14 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | a15 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | 0 | 0 | a15 | a14 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | a15 | a14 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | 0 | 0 | 0 | 0 | 0 | a8 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a9 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a13 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a14 | 0 | 0 | (-) + # | U[7]| U[6]| U[5]| U[4]| U[3]| U[2]| U[1]| U[0]| + # | V[3] | V[2] | V[1] | V[0] | + # until r < p256 + # s7 (a15|a14), s6 (a13|a12), s5 (a11|a10), s4 (a9|a8) + # s3 (a7|a6), s2 (a5|a4), s1 (a3|a2), s0 (a1|a0) + + # 1. 64-bit addition + xorq %rsi, %rsi # to store all carry + xorq %rax, %rax + movq s6, %rcx # rcx <- s6 + movq s4, %rdx # rdx <- s4 + # a13 | a12 + addq s7, %rcx # rcx <- s6 + s7 + adcq $0, %rax # rax <- carry(s6+s7) + addq s7, %rcx # rcx <- s6 + 2*s7 + adcq $0, %rax + # a9 | a8 + movq %rax, %rbx # rbx <- carry (rax) + addq %rcx, %rdx # rdx <- s4 + s6 + 2*s7 + adcq $0, %rbx + addq s5, %rdx # rdx <- s4 + s5 + s6 + 2*s7 + adcq $0, %rbx + # sum + addq %rdx, s0 # s0 <- s0 + s4 + s5 + s6 + 2*s7 + adcq %rbx, s1 # s1 <- s1 + rbx + carry + adcq %rcx, s2 # s2 <- s2 + s6 + 2*s7 + carry + adcq s7, s3 # s3 <- s3 + s7 + carry + adcq $0, %rsi + # add carry + addq %rax, s3 + adcq $0, %rsi # rsi <- carry + # store registers + movq s0, (%rsp) + movq s1, 8(%rsp) + movq s2, 16(%rsp) + movq s3, 24(%rsp) + # 2. 4 -> 8 64-bit to 32-bit spread + movq $0xffffffff, %rax + movq s4, s0 + movq s5, s1 + movq s6, s2 + movq s7, s3 + andq %rax, s0 # a8 + andq %rax, s1 # a10 + andq %rax, s2 # a12 + andq %rax, s3 # a14 + shrq $32, s4 # a9 + shrq $32, s5 # a11 + shrq $32, s6 # a13 + shrq $32, s7 # a15 + # 3. 32-bit addition + movq s3, %rax + addq s2, %rax # rax <- a12 + a14 + movq s3, %rbx + addq s1, %rbx # rbx <- a10 + a14 + movq s7, %rcx + addq s6, %rcx # rcx <- a13 + a15 + movq s0, %rdx + addq s4, %rdx # rdx <- a8 + a9 + addq s5, s7 # s7 <- a11 + a15 + movq %rcx, s2 # s2 <- a13 + a15 + addq %rax, s2 # s2 <- a12 + a13 + a14 + a15 + addq s2, s1 # s1 <- a10 + a12 + a13 + a14 + a15 + addq s2, s1 # s1 <- a10 + 2*(a12 + a13 + a14 + a15) + addq %rdx, s1 # s1 <- a8 + a9 + a10 + 2*(a12 + a13 + a14 + a15) + addq s5, s1 # s1 <- a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + addq s6, s2 # s2 <- a12 + 2*a13 + a14 + a15 + addq s5, s2 # s2 <- a11 + a12 + 2*a13 + a14 + a15 + addq s0, s2 # s2 <- a8 + a11 + a12 + 2*a13 + a14 + a15 + addq s3, %rdx # rdx <- a8 + a9 + a14 + addq s6, %rdx # rdx <- a8 + a9 + a13 + a14 + addq %rcx, s4 # s4 <- a9 + a13 + a15 + addq s4, s5 # s5 <- a9 + a11 + a13 + a15 + addq %rcx, s5 # s5 <- a9 + a11 + 2*(a13 + a15) + addq %rbx, %rax # rax <- a10 + a12 + 2*a14 + + # U[0] s5 a9 + a11 + 2*(a13 + a15) + # U[1] %rax a10 + a12 + 2*a14 + # U[2] + # U[3] s2 a8 + a11 + a12 + 2*a13 + a14 + a15 + # U[4] s4 a9 + a13 + a15 + # U[5] %rbx a10 + a14 + # U[6] s7 a11 + a15 + # U[7] s1 a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + # sub %rdx a8 + a9 + a13 + a14 + + # vacant registers: s0 s3 s6 %rcx + + # 4. 8 -> 4 32-bit to 64-bit + # sub %rdx + movq %rax, s0 + shlq $32, s0 # U[1]'(s0) <- U[1] << 32 + shrd $32, s2, %rax # U[3]'(%rax) <- U[3]U[1] >> 32 + shrd $32, %rbx, s2 # U[5]'(s2) <- U[5]U[3] >> 32 + shrd $32, s1, %rbx # U[7]'(%rbx) <- U[7]U[5] >> 32 + shrq $32, s1 # U[7](s1) <- U[7] >> 32 (carry) + + # 5. 64-bit addition + addq s0, s5 # U[0] <- U[1]' + U[0] + adcq $0, %rax # U[3]' <- 0 + U[3]' + adcq s2, s4 # U[4] <- U[5]' + U[4] + adcq %rbx, s7 # U[6] <- U[7]' + U[6] + adcq s1, %rsi # rsi <- U[7]carry + carry + + # V[0] s5 + # V[1] %rax + # V[2] s4 + # V[3] s7 + # carry %rsi + # sub %rdx + + # 5. ADD & SUB + movq (%rsp), s0 + movq 8(%rsp), s1 + movq 16(%rsp), s2 + movq 24(%rsp), s3 + # ADD + addq s5, s0 + adcq %rax, s1 + adcq s4, s2 + adcq s7, s3 + adcq $0, %rsi + # SUB + subq %rdx, s1 + sbbq $0, s2 + sbbq $0, s3 + sbbq $0, %rsi + + # 6. MOD + # First Mod + movq %rsi, %rax # rax <- carry (rsi) +out[0] + shlq $32, %rax # rax <- carry << 32 + movq %rax, %rcx # rcx <- rax +out[3] + subq %rsi, %rax # rax <- carry << 32 - carry +out[1] + + addq %rsi, s0 + adcq %rax, s1 + adcq $0, s2 + adcq %rcx, s3 + + # Last Mod + # return r - p if r > p else r + movq s0, s4 + movq s1, s5 + movq s2, s6 + movq s3, s7 + + leaq .Lpoly(%rip), %rsi + + movq $0, %rcx + adcq $0, %rcx + + subq 0(%rsi), s0 + sbbq 8(%rsi), s1 + sbbq 16(%rsi), s2 + sbbq 24(%rsi), s3 + sbbq $0, %rcx + + cmovcq s4, s0 + cmovcq s5, s1 + cmovcq s6, s2 + cmovcq s7, s3 + + movq s0, (%rdi) + movq s1, 8(%rdi) + movq s2, 16(%rdi) + movq s3, 24(%rdi) +.endm + +### Modular mul: r = a*b mod p ### + # void ECP_Sm2Mul(uint64_t *r, const uint64_t *a, const uint64_t *b) + # 256-bit modular multiplication in SM2 + # r %rdi + # a %rsi + # b %rdx + .globl ECP_Sm2Mul + .type ECP_Sm2Mul, @function + .align 64 + +ECP_Sm2Mul: + + # Store scalar registers + subq $72, %rsp + movq %rbx, 32(%rsp) + movq %r12, 40(%rsp) + movq %r13, 48(%rsp) + movq %r14, 56(%rsp) + movq %r15, 64(%rsp) + + # Load inputs + movq (%rsi), s0 + movq 8(%rsi), s1 + movq 16(%rsi), s2 + movq 24(%rsi), s3 + movq (%rdx), s4 + movq 8(%rdx), s5 + movq 16(%rdx), s6 + movq 24(%rdx), s7 + +### multiplication ### + + # ======================== + # s7 s6 s5 s4 + # * s3 s2 s1 s0 + # ------------------------ + # + s0 s0 s0 s0 + # * * * * + # s7 s6 s5 s4 + # s1 s1 s1 s1 + # * * * * + # s7 s6 s5 s4 + # s2 s2 s2 s2 + # * * * * + # s7 s6 s5 s4 + # s3 s3 s3 s3 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s0*s4 ### + movq s0, %rax + mulq s4 + movq %rax, (%rsp) + movq %rdx, %rbx + xorq %rcx, %rcx + +### s1*s4 + s0*s5 ### + movq s1, %rax + mulq s4 + addq %rax, %rbx + adcq %rdx, %rcx + xorq %rsi, %rsi + + movq s0, %rax + mulq s5 + addq %rax, %rbx + adcq %rdx, %rcx + adcq $0, %rsi + movq %rbx, 8(%rsp) + xorq %rbx, %rbx + +### s2 * s4 + s1 * s5 + s0 *s6 ### + movq s2, %rax + mulq s4 + addq %rax, %rcx + adcq %rdx, %rsi + + movq s1, %rax + mulq s5 + addq %rax, %rcx + adcq %rdx, %rsi + adcq $0, %rbx + + movq s0, %rax + mulq s6 + addq %rax, %rcx + adcq %rdx, %rsi + adcq $0, %rbx + movq %rcx, 16(%rsp) + xorq %rcx, %rcx + +### s3*s4 + s2*s5 + s1*s6 + s0*s7 ### + movq s3, %rax + mulq s4 + addq %rax, %rsi + adcq %rdx, %rbx + adcq $0, %rcx + + movq s2, %rax + mulq s5 + addq %rax, %rsi + adcq %rdx, %rbx + adcq $0, %rcx + + movq s1, %rax + mulq s6 + addq %rax, %rsi + adcq %rdx, %rbx + adcq $0, %rcx + + movq s0, %rax + mulq s7 + addq %rax, %rsi + adcq %rdx, %rbx + adcq $0, %rcx + movq %rsi, 24(%rsp) + xorq %rsi, %rsi + +### s3*s5 + s2*s6 + s1*s7 ### + movq s3, %rax + mulq s5 + addq %rax, %rbx + adcq %rdx, %rcx + # carry + adcq $0, %rsi + + movq s2, %rax + mulq s6 + addq %rax, %rbx + adcq %rdx, %rcx + adcq $0, %rsi + + movq s1, %rax + mulq s7 + addq %rax, %rbx + adcq %rdx, %rcx + adcq $0, %rsi + movq %rbx, s4 + xorq %rbx, %rbx + +### s3*s6 + s2*s7 ### + movq s3, %rax + mulq s6 + addq %rax, %rcx + adcq %rdx, %rsi + # carry + adcq $0, %rbx + + movq s2, %rax + mulq s7 + addq %rax, %rcx + adcq %rdx, %rsi + adcq $0, %rbx + movq %rcx, s5 + +### s3*s7 ### + movq s3, %rax + mulq s7 + addq %rax, %rsi + adcq %rdx, %rbx + movq %rsi, s6 + movq %rbx, s7 + + movq (%rsp), s0 + movq 8(%rsp), s1 + movq 16(%rsp), s2 + movq 24(%rsp), s3 + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + # Restore scalar registers + movq 32(%rsp), %rbx + movq 40(%rsp), %r12 + movq 48(%rsp), %r13 + movq 56(%rsp), %r14 + movq 64(%rsp), %r15 + addq $72, %rsp + + ret + .size ECP_Sm2Mul, .-ECP_Sm2Mul + +### Modular sqr: r = a^2 mod p ### + # void ECP_Sm2Sqr(uint64_t *r, const uint64_t *a) + # 256-bit modular multiplication in SM2 ### + # r %rdi + # a %rsi + .globl ECP_Sm2Sqr + .type ECP_Sm2Sqr, @function + .align 64 + +ECP_Sm2Sqr: + + # Store scalar registers + subq $88, %rsp + movq %rbx, 32(%rsp) + movq %r12, 40(%rsp) + movq %r13, 48(%rsp) + movq %r14, 56(%rsp) + movq %r15, 64(%rsp) + movq %rbp, 72(%rsp) + movq %rdi, 80(%rsp) + + # Load inputs + movq (%rsi), s4 + movq 8(%rsi), s5 + movq 16(%rsi), s6 + movq 24(%rsi), s7 + +### square ### + + # ======================== + # s7 s6 s5 s4 + # * s7 s6 s5 s4 + # ------------------------ + # + s4 s4 s4 s4 + # * * * * + # s7 s6 s5 s4 + # s5 s5 s5 s5 + # * * * * + # s7 s6 s5 s4 + # s6 s6 s6 s6 + # * * * * + # s7 s6 s5 s4 + # s7 s7 s7 s7 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s1 <- s4*s5, s2 <- carry ### + movq s5, %rax + mulq s4 + movq %rax, s1 + movq %rdx, s2 + xorq s3, s3 + +### s2 <- s4*s6 + carry(s2), s3 <- carry ### + movq s6, %rax + mulq s4 + addq %rax, s2 + adcq %rdx, s3 + xorq s0, s0 + +### s3 <- s4*s7 + s5*s6 + carry(s3), s0 <- carry ### + movq s7, %rax + mulq s4 + addq %rax, s3 + adcq %rdx, s0 + xorq %rbx, %rbx + + movq s6, %rax + mulq s5 + addq %rax, s3 + adcq %rdx, s0 + adcq $0, %rbx + +### s0 <- s5*s7 + carry(s0), rbx <- carry ### + movq s7, %rax + mulq s5 + addq %rax, s0 + adcq %rdx, %rbx + xorq %rcx, %rcx + +### rbx <- s6*s7 + carry(rbx), rcx <- carry ### + movq s7, %rax + mulq s6 + addq %rax, %rbx + adcq %rdx, %rcx + xorq %rsi, %rsi + +### 2*s0|1|2|3 ### + addq s1, s1 + adcq s2, s2 + adcq s3, s3 + adcq s0, s0 + adcq %rbx, %rbx + # update carry + adcq %rcx, %rcx + adcq $0, %rsi +### rbp <- s4*s4, carry <- rdi ### + movq s4, %rax + mulq s4 + movq %rax, %rbp + movq %rdx, %rdi + +### s4 <- s5*s5, carry <- s5 ### + movq s5, %rax + mulq s5 + movq %rax, s4 + movq %rdx, s5 + +### s6*s6 ### + movq s6, %rax + mulq s6 + + # s1 += carry(s4*s4) + addq %rdi, s1 + # s2 += s5*s5 + adcq s4, s2 + # s3 += carry(s5*s5) + adcq s5, s3 + # s4(s0) += s6*s6 + adcq %rax, s0 + # s5(rbx) += carry(s6*s6) + adcq %rdx, %rbx + adcq $0, %rcx + adcq $0, %rsi + +### s7*s7 ### + movq s7, %rax + mulq s7 + # s6(rcx) += s7*s7 + addq %rax, %rcx + # s7(rsi) += carry(s7*s7) + adcq %rdx, %rsi + + movq s0, s4 + movq %rbp, s0 + movq %rbx, s5 + movq %rcx, s6 + movq %rsi, s7 + + # Restore rdi + movq 80(%rsp), %rdi + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + # Restore scalar registers + movq 32(%rsp), %rbx + movq 40(%rsp), %r12 + movq 48(%rsp), %r13 + movq 56(%rsp), %r14 + movq 64(%rsp), %r15 + movq 72(%rsp), %rbp + addq $88, %rsp + + ret + .size ECP_Sm2Sqr, .-ECP_Sm2Sqr + +#endif \ No newline at end of file diff --git a/crypto/ecc/src/asm64_ecp_nistp256.c b/crypto/ecc/src/asm64_ecp_nistp256.c new file mode 100644 index 00000000..2f876223 --- /dev/null +++ b/crypto/ecc/src/asm64_ecp_nistp256.c @@ -0,0 +1,190 @@ +/* + * 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_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include +#include "crypt_errno.h" +#include "crypt_bn.h" +#include "ecp_nistp256.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "bsl_err_internal.h" +#include "asm_ecp_nistp256.h" + +static const Coord g_rrModOrder = {{ + 0x83244c95be79eea2, + 0x4699799c49bd6fa6, + 0x2845b2392b6bec59, + 0x66e12d94f3d95620 +}}; + +static int32_t ECP256_ModOrderInvCheck(const ECC_Para *para, const BN_BigNum *r, const BN_BigNum *a) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (para->id != CRYPT_ECC_NISTP256) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + + if (BN_IsZero(a)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_INVERSE_INPUT_ZERO); + return CRYPT_ECC_INVERSE_INPUT_ZERO; + } + + return CRYPT_SUCCESS; +} + +static int32_t Bn2CoordArray(const ECC_Para *para, Coord *aArr, const BN_BigNum *a) +{ + int32_t ret = CRYPT_SUCCESS; + uint32_t bits = BN_Bits(para->n); + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *aTemp = BN_Create(bits); + if (opt == NULL || aTemp == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + if (BN_Cmp(a, para->n) >= 0) { + ret = BN_Mod(aTemp, a, para->n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + if (BN_IsZero(aTemp)) { // If x and m are coprime, the module inverse cannot be obtained. + BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_NO_INVERSE); + ret = CRYPT_BN_ERR_NO_INVERSE; + goto END; + } + } else { + ret = BN_Copy(aTemp, a); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + } + (void)BN_BN2Array(aTemp, aArr->value, P256_SIZE); +END: + BN_OptimizerDestroy(opt); + BN_Destroy(aTemp); + return ret; +} + +// r = a^(-1) mod n, a cannot be 0 +// a^(-1) mod n = a^(n-2) mod n +// n = 0xffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551 +// n-2 = 0xffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc63254f +// Split the file into binary files as follows: +// 11111111111111111111111111111111---------0xffffffff +// 00000000000000000000000000000000---------0x00000000 +// 11111111111111111111111111111111---------0xffffffff +// 11111111111111111111111111111111---------0xffffffff +// 101111 00 111 00 11 0 1111 10101 0 101 101 +// 101 00 111 000 101111 00 1111 0 1 0000 1 00 +// 1111 00 111 0 111 00 111 00 101 0 11 0000 10(1111): append four 1s +// (1111) 11 000 11 000 11 00 1 00 10101 00 1111 +// To calculate the power of a, the exponent list is { 1, 10, 11, 101, 111, 1010, 1111, 10101, 101010, 101111, ffffffff} +// To calculate a^(0xffffffff), a^(0xffff) is required. The former requires a^(0xff), the latter requires a^(0x3f). +// The above is the optimal multiplication chain of a^(n-2) +// https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion +int32_t ECP256_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a) +{ + int32_t ret = ECP256_ModOrderInvCheck(para, r, a); + if (ret != CRYPT_SUCCESS) { + return ret; + } + const Coord one = {{1}}; + Coord aArr, res; + Coord table[14]; + enum { + bin1 = 0, bin10, bin11, bin101, bin111, bin1010, bin1111, + bin10101, bin101010, bin101111, hex3f, hexff, hexffff, hexffffffff + }; + static const uint8_t mulMap[26] = { // The lower 128 bits of n-2 can be split into 26 binary numbers. + bin101111, bin111, bin11, bin1111, bin10101, bin101, + bin101, bin101, bin111, bin101111, bin1111, bin1, + bin1, bin1111, bin111, bin111, bin111, bin101, + bin11, bin101111, bin11, bin11, bin11, bin1, + bin10101, bin1111 + }; + static const uint8_t sqrRep[26] = { // The lower 128 bits of n-2 can be split into 26 binary numbers. + 6, 5, 4, 5, 5, 4, + 3, 3, 5, 9, 6, 2, + 5, 6, 5, 4, 5, 5, + 3, 10, 2, 5, 5, 3, + 7, 6 + }; + + ret = Bn2CoordArray(para, &aArr, a); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ECP256_OrdMul(&table[bin1], &aArr, &g_rrModOrder); // table[bin1] = a, to the field with Montgomery + + ECP256_OrdSqr(&table[bin10], &table[bin1], 1); // table[bin10] = a^(0b10) + ECP256_OrdMul(&table[bin11], &table[bin1], &table[bin10]); // table[bin11] = a^(0b11) + ECP256_OrdMul(&table[bin101], &table[bin11], &table[bin10]); // table[bin101] = a^(0b101) + ECP256_OrdMul(&table[bin111], &table[bin101], &table[bin10]); // table[bin111] = a^(0b111) + + ECP256_OrdSqr(&table[bin1010], &table[bin101], 1); // table[bin1010] = a^(0b1010) + + ECP256_OrdMul(&table[bin1111], &table[bin1010], &table[bin101]); // table[bin1111] = a^(0b1111) + + ECP256_OrdSqr(&table[bin10101], &table[bin1010], 1); // table[bin10101] = a^(0b10100) + ECP256_OrdMul(&table[bin10101], &table[bin10101], &table[bin1]); // table[bin10101] = a^(0b10101) + + ECP256_OrdSqr(&table[bin101010], &table[bin10101], 1); // table[bin101010] = a^(0b101010) + + ECP256_OrdMul(&table[bin101111], &table[bin101010], &table[bin101]); // table[bin101111] = a^(0b101111) + + ECP256_OrdMul(&table[hex3f], &table[bin101010], &table[bin10101]); // table[hex3f] = a^(0b0011 1111) = a^(0x3f) + + ECP256_OrdSqr(&table[hexff], &table[hex3f], 2); // left shift by 2 bits, table[hexff] = a^(0b1111 1100) = a^(0xfc) + ECP256_OrdMul(&table[hexff], &table[hexff], &table[bin11]); // table[hexff] = a^(0b1111 1111) = a^(0xff) + + ECP256_OrdSqr(&table[hexffff], &table[hexff], 8); // left shift by 8 bits, table[hexffff] = a^(0xff00) + ECP256_OrdMul(&table[hexffff], &table[hexffff], &table[hexff]); // table[hexffff] = a^(0xffff) + + // left shift by 16 bits, table[hexffffffff] = a^(0xffff0000) + ECP256_OrdSqr(&table[hexffffffff], &table[hexffff], 16); + ECP256_OrdMul(&table[hexffffffff], &table[hexffffffff], &table[hexffff]); // table[hexffffffff] = a^(0xffffffff) + + ECP256_OrdSqr(&res, &table[hexffffffff], 64); // res = a^(0xffffffff 00000000 00000000), left shift by 64 bits + ECP256_OrdMul(&res, &res, &table[hexffffffff]); // res = a^(0xffffffff 00000000 ffffffff) + + ECP256_OrdSqr(&res, &res, 32); // res = a^(0xffffffff 00000000 ffffffff 00000000), left shift by 32 bits + ECP256_OrdMul(&res, &res, &table[hexffffffff]); // res = a^(0xffffffff 00000000 ffffffff ffffffff) + + for (uint32_t i = 0; i < sizeof(mulMap); i++) { + ECP256_OrdSqr(&res, &res, sqrRep[i]); + ECP256_OrdMul(&res, &res, &table[mulMap[i]]); + } + + // Multiplied by 1 can be converted back to the normal real number field, which is equivalent to a reduce. + // For details, see Montgomery modular multiplication. + ECP256_OrdMul(&res, &res, &one); + + (void)BN_Array2BN(r, res.value, P256_SIZE); + return ret; +} +#endif \ No newline at end of file diff --git a/crypto/ecc/src/asm_ecp_nistp256.c b/crypto/ecc/src/asm_ecp_nistp256.c new file mode 100644 index 00000000..5b542aa8 --- /dev/null +++ b/crypto/ecc/src/asm_ecp_nistp256.c @@ -0,0 +1,544 @@ +/* + * 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_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include +#include +#include +#include "crypt_errno.h" +#include "crypt_bn.h" +#include "ecp_nistp256.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "bsl_err_internal.h" +#include "asm_ecp_nistp256.h" + +#if defined(HITLS_SIXTY_FOUR_BITS) + // 1 is on the field with Montgomery, 1 * RR * R' mod P = R mod P = R - P + static const Coord g_oneMont = {{ + 0x0000000000000001, + 0xffffffff00000000, + 0xffffffffffffffff, + 0x00000000fffffffe + }}; + static const Coord g_rrModP = {{ + 0x0000000000000003, + 0xfffffffbffffffff, + 0xfffffffffffffffe, + 0x00000004fffffffd + }}; +#elif defined(HITLS_THIRTY_TWO_BITS) + // 1 is on the field with Montgomery, 1 * RR * R' mod P = R mod P = R - P + static const Coord g_oneMont = {{ + 0x00000001, + 0x00000000, + 0x00000000, + 0xffffffff, + 0xffffffff, + 0xffffffff, + 0xfffffffe, + 0x00000000 + }}; + static const Coord g_rrModP = {{ + 0x00000003, + 0x00000000, + 0xffffffff, + 0xfffffffb, + 0xfffffffe, + 0xffffffff, + 0xfffffffd, + 0x00000004 + }}; +#else +#error BN_UINT MUST be 4 or 8 +#endif + +// If the value is 0, all Fs are returned. If the value is not 0, 0 is returned. +static BN_UINT IsZero(const Coord *a) +{ + BN_UINT ret = a->value[0]; + for (uint32_t i = 1; i < P256_SIZE; i++) { + ret |= a->value[i]; + } + return BN_IsZeroUintConsttime(ret); +} + +// r = cond == 0 ? r : a, the input parameter cond can only be 0 or 1. +// If cond is 0, the value remains unchanged. If cond is 1, copy a. +static void CopyConditional(Coord *r, const Coord *a, BN_UINT cond) +{ + BN_UINT mask1 = ~cond & (cond - 1); + BN_UINT mask2 = ~mask1; + + for (uint32_t i = 0; i < P256_SIZE; i++) { + r->value[i] = (r->value[i] & mask1) ^ (a->value[i] & mask2); + } +} + +// Jacobian affine -> Jacobian projection, (X,Y)->(X,Y,Z) +static void Affine2Jproj(P256_Point *r, const P256_AffinePoint *a, BN_UINT mask) +{ + for (uint32_t i = 0; i < P256_SIZE; i++) { + r->x.value[i] = a->x.value[i] & mask; + r->y.value[i] = a->y.value[i] & mask; + r->z.value[i] = g_oneMont.value[i] & mask; + } +} + +// r = a^-1 mod p = a^(p-2) mod p +// p-2 = 0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffd +static void ECP256_ModInverse(Coord *r, const Coord *a) +{ + // a^(0x3), a^(0xc) = a^(0b1100), a^(0xf), a^(0xf0), a^(0xff) + // a^(0xff00), a^(0xffff), a^(0xffff0000), a^(0xffffffff) + Coord a3, ac, af, af0, a2f, a2f20, a4f, a4f40, a8f, ans; + uint32_t i; + // 0x3 = 0b11 = 0b10 + 0b01 + ECP256_Sqr(&a3, a); // a^2 + ECP256_Mul(&a3, &a3, a); // a^3 = a^2 * a + // 0xf = 0b1111 = 0b1100 + 0b11, 0b11->0b1100 requires *4, and the exponent*4(2^2) requires twice square operations + ECP256_Sqr(&af, &a3); // a^6 = (a^3)^2 + ECP256_Sqr(&ac, &af); // a^12 = (a^3)^2 = a^(0xc) + ECP256_Mul(&af, &ac, &a3); // a^f = a^15 = a^12 * a^3 + // 0xff = 0b11111111 = 0b11110000 + 0b1111, 0b1111->0b11110000 requires *16, + // the exponent*16(2^4) requires 4 times square operations + ECP256_Sqr(&a2f, &af); // a^(0b11110) = (a^f)^2 + ECP256_Sqr(&a2f, &a2f); // a^(0b111100) = (a^(0b11110))^2 + ECP256_Sqr(&a2f, &a2f); // a^(0b1111000) = (a^(0b111100))^2 + ECP256_Sqr(&af0, &a2f); // a^(0xf0) = a^(0b11110000) = (a^(0b1111000))^2 + ECP256_Mul(&a2f, &af0, &af); // a^(0xff) = a^(0xf0) * a^(0xf) + // a^(0xffff) + ECP256_Sqr(&a2f20, &a2f); + for (i = 1; i < 8; i++) { // need to left shift by 8 bits + ECP256_Sqr(&a2f20, &a2f20); + } + // When the loop ends, &a2f20 = a^(0xff00) + ECP256_Mul(&a4f, &a2f20, &a2f); // a^(0xffff) = a^(0xff00) * a^(0xff) + // a^(0xffffffff) + ECP256_Sqr(&a4f40, &a4f); + for (i = 1; i < 16; i++) { // need to left shift by 16 bits + ECP256_Sqr(&a4f40, &a4f40); + } + // When the loop ends, &a4f40 = a^(0xffff0000) + ECP256_Mul(&a8f, &a4f40, &a4f); // a^(0xffffffff) = a^(0xffff0000) * a^(0xffff) + // a^(0xffffffff 00000001) + ECP256_Sqr(&ans, &a8f); + for (i = 1; i < 32; i++) { // need to left shift by 32 bits + ECP256_Sqr(&ans, &ans); + } + ECP256_Mul(&ans, &ans, a); // a^(0xffffffff 00000001) = a^(0xffffffff 00000000) * a + // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff) + for (i = 0; i < 32 * 4; i++) { // need to left shift by 32 * 4 bits + ECP256_Sqr(&ans, &ans); + } + ECP256_Mul(&ans, &ans, &a8f); + // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff) + for (i = 0; i < 32; i++) { // need to left shift by 32 bits + ECP256_Sqr(&ans, &ans); + } + ECP256_Mul(&ans, &ans, &a8f); + // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffd) + for (i = 0; i < 32; i++) { // need to left shift by 32 bits + ECP256_Sqr(&ans, &ans); + } + // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff 00000000) + ECP256_Mul(&ans, &ans, &a4f40); // a^(0xffff0000) + ECP256_Mul(&ans, &ans, &a2f20); // a^(0xff00) + ECP256_Mul(&ans, &ans, &af0); // a^(0xf0) + ECP256_Mul(&ans, &ans, &ac); // a^(0xc) + ECP256_Mul(r, &ans, a); // a^(0x1) +} + +static int32_t ECP256_GetAffine(ECC_Point *r, const P256_Point *pt) +{ + Coord zInv3; + Coord zInv2; + Coord res_x; + Coord res_y; + int32_t ret; + if (IsZero(&(pt->z)) != 0) { + ret = CRYPT_ECC_POINT_AT_INFINITY; + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + ECP256_ModInverse(&zInv3, &(pt->z)); // zInv + ECP256_Sqr(&zInv2, &zInv3); // zInv^2 + ECP256_Mul(&zInv3, &zInv2, &zInv3); // zInv^3 + ECP256_Mul(&res_x, &(pt->x), &zInv2); // xMont = x / (z^2) + ECP256_Mul(&res_y, &(pt->y), &zInv3); // yMont = y / (z^3) + ECP256_FromMont(&res_x, &res_x); + ECP256_FromMont(&res_y, &res_y); + ret = BN_Array2BN(r->x, res_x.value, P256_SIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + ret = BN_Array2BN(r->y, res_y.value, P256_SIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + ret = BN_SetLimb(r->z, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + return CRYPT_SUCCESS; + +END: + return ret; +} + +static void ECP256_P256Point2EccPoint(ECC_Point *r, const P256_Point *pt) +{ + Coord xTemp; + Coord yTemp; + Coord zTemp; + ECP256_FromMont(&xTemp, &(pt->x)); + ECP256_FromMont(&yTemp, &(pt->y)); + ECP256_FromMont(&zTemp, &(pt->z)); + (void)BN_Array2BN(r->x, xTemp.value, P256_SIZE); + (void)BN_Array2BN(r->y, yTemp.value, P256_SIZE); + (void)BN_Array2BN(r->z, zTemp.value, P256_SIZE); +} + +static void ECP256_EccPoint2P256Point(P256_Point *r, const ECC_Point *pt) +{ + (void)BN_BN2Array(pt->x, r->x.value, P256_SIZE); + (void)BN_BN2Array(pt->y, r->y.value, P256_SIZE); + (void)BN_BN2Array(pt->z, r->z.value, P256_SIZE); + ECP256_Mul(&(r->x), &(r->x), &g_rrModP); + ECP256_Mul(&(r->y), &(r->y), &g_rrModP); + ECP256_Mul(&(r->z), &(r->z), &g_rrModP); +} + +int32_t ECP256_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + bool flag = (r == NULL || a == NULL || para == NULL); + if (flag) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (para->id != CRYPT_ECC_NISTP256 || r->id != CRYPT_ECC_NISTP256 || a->id != CRYPT_ECC_NISTP256) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + P256_Point temp; + ECP256_EccPoint2P256Point(&temp, a); + return ECP256_GetAffine(r, &temp); +} + +// The value of 'in' contains a maximum of six bits. The input parameter must be & 0b111111 in advance. +static uint32_t Recodew5(uint32_t in) +{ + // Shift rightwards by 5 bits to get the most significant bit, check whether the most significant bit is 1. + uint32_t sign = (in >> 5) - 1; + uint32_t data = (1 << 6) - 1 - in; // (6 Ones)0b111111 - in + data = (data & ~sign) | (in & sign); + data = (data >> 1) + (data & 1); + + return (data << 1) + (~sign & 1); +} + +// The value of 'in' contains a maximum of six bits. The input parameter must be & 0b11111111 in advance. +static uint32_t Recodew7(uint32_t in) +{ + // Shift rightwards by 7 bits to get the most significant bit, check whether the most significant bit is 1. + uint32_t sign = (in >> 7) - 1; + uint32_t data = (1 << 8) - 1 - in; // (8 Ones)0b11111111 - in + data = (data & ~sign) | (in & sign); + data = (data >> 1) + (data & 1); + + return (data << 1) + (~sign & 1); +} + +static void ECP256_CopyPoint(P256_Point *dst, const P256_Point *src) +{ + for (uint32_t i = 0; i < P256_SIZE; i++) { + dst->x.value[i] = src->x.value[i]; + dst->y.value[i] = src->y.value[i]; + dst->z.value[i] = src->z.value[i]; + } +} + +static void ECP256_PreCompWindow(P256_Point table[16], P256_Point *pt) +{ + P256_Point temp[5]; + ECP256_CopyPoint(&temp[0], pt); + ECP256_Scatterw5(table, &temp[0], 1); // Discretely save temp[0] to the 1st position in the table. + ECP256_PointDouble(&temp[1], &temp[0]); // 2G + ECP256_Scatterw5(table, &temp[1], 2); // Discretely save temp[1] to the 2nd position of the table. + ECP256_PointAdd(&temp[2], &temp[1], &temp[0]); // temp[2] = 3G = 2G + G + ECP256_Scatterw5(table, &temp[2], 3); // Discretely saves temp[2] to the 3rd position of the table. + ECP256_PointDouble(&temp[3], &temp[1]); // temp[3] = 4G = 2G * 2 + ECP256_Scatterw5(table, &temp[3], 4); // Discretely save temp[3] to the 4th position in the table. + ECP256_PointAdd(&temp[4], &temp[3], &temp[0]); // temp[4] = 5G = 4G + G = = temp[3] + temp[0] + ECP256_Scatterw5(table, &temp[4], 5); // Discretely save temp[4] to the 5th position in the table. + ECP256_PointDouble(&temp[1], &temp[2]); // temp[1] = 6G = 3G * 2 + ECP256_Scatterw5(table, &temp[1], 6); // Discretely save temp[1] to the 6th position in the table. + ECP256_PointAdd(&temp[2], &temp[1], &temp[0]); // temp[2] = 7G = 6G + G + ECP256_Scatterw5(table, &temp[2], 7); // Discretely save temp[2] to the 7th position in the table. + ECP256_PointDouble(&temp[3], &temp[3]); // temp[3] = 8G = 4G * 2 + ECP256_Scatterw5(table, &temp[3], 8); // Discretely save temp[3] to the 8th position in the table. + ECP256_PointDouble(&temp[4], &temp[4]); // temp[4] = 10G = 5G * 2 + ECP256_Scatterw5(table, &temp[4], 10); // Discretely save temp[4] to the 10th position in the table. + ECP256_PointAdd(&temp[4], &temp[4], &temp[0]); // temp[4] = 11G = 10G + G + ECP256_Scatterw5(table, &temp[4], 11); // Discretely save temp[4] to the 11th position in the table. + ECP256_PointDouble(&temp[1], &temp[1]); // temp[1] = 12G = 6G * 2 + ECP256_Scatterw5(table, &temp[1], 12); // Discretely save temp[1] to the 12th position in the table. + ECP256_PointAdd(&temp[4], &temp[3], &temp[0]); // temp[4] = 9G = 8G + G = temp[3] + temp[0] + ECP256_Scatterw5(table, &temp[4], 9); // Discretely save temp[4] to the 9th position in the table. + ECP256_PointAdd(&temp[4], &temp[1], &temp[0]); // temp[4] = 13G = 12G + G + ECP256_Scatterw5(table, &temp[4], 13); // Discretely save temp[4] to the 13th position of the table. + ECP256_PointDouble(&temp[2], &temp[2]); // temp[2] = 14G = 7G * 2 + ECP256_Scatterw5(table, &temp[2], 14); // Discretely saves temp[2] to the 14th position of the table. + ECP256_PointAdd(&temp[1], &temp[2], &temp[0]); // temp[1] = 15G = 14G + G = temp[2] + temp[0] + ECP256_Scatterw5(table, &temp[1], 15); // Discretely save temp[1] to the 15th position of the table. + ECP256_PointDouble(&temp[2], &temp[3]); // temp[2] = 16G = 8G * 2 = temp[3] * 2 + ECP256_Scatterw5(table, &temp[2], 16); // Discretely saves temp[2] to the 16th position of the table. +} + +static void CRYPT_ECP256_PointDouble5Times(P256_Point *r) +{ + ECP256_PointDouble(r, r); + ECP256_PointDouble(r, r); + ECP256_PointDouble(r, r); + ECP256_PointDouble(r, r); + ECP256_PointDouble(r, r); +} + +// r = k*point +// Ensure that m is not empty and is in the range (0, n-1) +static void ECP256_WindowMul(P256_Point *r, const BN_BigNum *k, const ECC_Point *point) +{ + uint8_t kOctets[33]; // m big endian byte stream. Apply for 33 bytes and reserve one byte for the following offset. + uint32_t mLen = BN_Bytes(k); + // Offset during byte stream conversion. Ensure that the valid data of the mOctet is in the upper bits. + uint32_t offset = sizeof(kOctets) - mLen; + P256_Point table[16]; // The pre-computation window is 2 ^ (5 - 1) = 16 points + P256_Point temp; // Apply for temporary space of two points. + Coord tempY; + (void)BN_Bn2Bin(k, kOctets + offset, &mLen); + for (uint32_t i = 0; i < offset; i++) { + kOctets[i] = 0; + } + + ECP256_EccPoint2P256Point(&temp, point); + + ECP256_PreCompWindow(table, &temp); + + // The first byte is the first two bits of kOctets[1]. + // The subscript starts from 0. Therefore, it is bit 0 + 8 and bit 1 + 8 = 9. + uint32_t scans = 9; + uint32_t index = (scans / 8) + 1; // position of the byte to be scanned. + // Number of bits to be shifted rightwards by the current byte. + // Each byte needs to be moved backward by a maximum of 7 bits. + uint32_t shift = 7 - (scans % 8); + uint32_t w = 5; // Window size = 5 + // the recode mask, the window size is 5, thus the value is 6 bits, mask = 0b111111 = 0x3f + uint32_t mask = (1 << (w + 1)) - 1; + uint32_t wCode = kOctets[1]; + wCode = (wCode >> shift) & mask; + wCode = Recodew5(wCode); + ECP256_Gatherw5(&temp, table, wCode >> 1); + ECP256_CopyPoint(r, &temp); + + // 5 bits is obtained each time. The total number of bits is 256 + 8 (1 byte reserved) = 264 bits. + // Therefore, the last time can be scanned to 264-5 = 259 bits. + while (scans < 259) { + // Double the point for 5 times + CRYPT_ECP256_PointDouble5Times(r); + + scans += w; // Number of bits in the next scan. + index = scans / 8; // Location of the byte to be scanned. (1 byte = 8 bits) + // Number of bits to be shifted rightwards by the current byte. + // Each byte needs to be moved backward by a maximum of 7 bits. (1 byte = 8 bits) + shift = 7 - (scans % 8); + // Shift the upper byte by 8 bits to left, concatenate the current byte, and then shift to get the current wCode + wCode = kOctets[index] | (kOctets[index - 1] << 8); + wCode = (wCode >> shift) & mask; + wCode = Recodew5(wCode); + ECP256_Gatherw5(&temp, table, wCode >> 1); + ECP256_Neg(&tempY, &(temp.y)); + // If the least significant bit of the code is 1, plus -(wCode >> 1) times point. + CopyConditional(&(temp.y), &tempY, wCode & 1); + ECP256_PointAdd(r, r, &temp); + } + + // Special processing of the last block + CRYPT_ECP256_PointDouble5Times(r); + + wCode = kOctets[32]; // Obtain the last byte, that is, kOctets[32]. + wCode = (wCode << 1) & mask; + wCode = Recodew5(wCode); + ECP256_Gatherw5(&temp, table, wCode >> 1); + ECP256_Neg(&tempY, &(temp.y)); + // If the least significant bit of the code is 1, plus -(wCode >> 1) times point. + CopyConditional(&(temp.y), &tempY, wCode & 1); + ECP256_PointAdd(r, r, &temp); +} + +static void ComputeK1G(P256_Point *k1G, const BN_BigNum *k1) +{ + uint8_t kOctets[33]; // applies for 33 bytes and reserves one byte for the following offset. 256 bits are 32 bytes. + Coord tempY; + P256_AffinePoint k1GAffine; + const ECP256_TableRow *preCompTable = NULL; // precompute window size is 2 ^(7 - 1) = 64 + preCompTable = ECP256_GetPreCompTable(); + + uint32_t kLen = BN_Bytes(k1); + // Offset during byte stream conversion. Ensure that the valid data of the mOctet is in the upper bits. + uint32_t offset = sizeof(kOctets) - kLen; + (void)BN_Bn2Bin(k1, kOctets + offset, &kLen); + for (uint32_t i = 0; i < offset; i++) { + kOctets[i] = 0; + } + + uint32_t w = 7; // Window size = 7 + // the recode mask, the window size is 7, thus 8 bits are used (one extra bit is the sign bit). + // mask = 0b11111111 = 0xff + uint32_t mask = (1 << (w + 1)) - 1; + uint32_t wCode = (kOctets[32] << 1) & mask; // Last byte kOctets[32] is the least significant 7 bits. + wCode = Recodew7(wCode); + ECP256_Gatherw7(&k1GAffine, preCompTable[0], wCode >> 1); + ECP256_Neg(&tempY, &(k1GAffine.y)); + // If the least significant bit of the code is 1, plus -(wCode >> 1) times point. + CopyConditional(&(k1GAffine.y), &tempY, wCode & 1); + // If the x and y coordinates of k1GAffine are both 0, then the infinity is all Fs; otherwise, the infinity is 0. + BN_UINT infinity = IsZero(&(k1GAffine.x)) & IsZero(&(k1GAffine.y)); + Affine2Jproj(k1G, &k1GAffine, ~infinity); + + uint32_t scans = 0; + uint32_t index, shift; + // pre-computation table is table[37][64]. The table is queried every 7 bits (valid bits) of 256 bits. 256/7 = 36.57 + for (uint32_t i = 1; i < 37; i++) { + scans += w; + index = 32 - ((scans - 1) / 8); // The subscript of the last byte is 32, and 8 means 8 bits(1byte) + shift = (scans - 1) % 8; // 8 means 8 bits(1byte) + wCode = kOctets[index] | (kOctets[index - 1] << 8); // 8 means 8 bits(1byte) + wCode = (wCode >> shift) & mask; + wCode = Recodew7(wCode); + ECP256_Gatherw7(&k1GAffine, preCompTable[i], wCode >> 1); + ECP256_Neg(&tempY, &(k1GAffine.y)); + // If the least significant bit of the code is 1, plus -(wCode >> 1) times point. + CopyConditional(&(k1GAffine.y), &tempY, wCode & 1); + ECP256_AddAffine(k1G, k1G, &k1GAffine); + } +} + +static int32_t ECP256_PointMulCheck(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + bool flag = (para == NULL || r == NULL || k == NULL); + uint32_t bits; + if (flag) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != CRYPT_ECC_NISTP256 || r->id != CRYPT_ECC_NISTP256) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (pt != NULL) { + if (pt->id != CRYPT_ECC_NISTP256) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + // Special processing for the infinite point. + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + } + bits = BN_Bits(k); + if (bits > 256) { // 256 is the number of bits in the curve mode + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_MUL_ERR_K_LEN); + return CRYPT_ECC_POINT_MUL_ERR_K_LEN; + } + + return CRYPT_SUCCESS; +} + +// if pt == NULL, r = k * G, otherwise r = k * pt +int32_t ECP256_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + P256_Point rTemp; + int32_t ret = ECP256_PointMulCheck(para, r, k, pt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (pt == NULL) { + ComputeK1G(&rTemp, k); + } else { + ECP256_WindowMul(&rTemp, k, pt); + } + + ECP256_P256Point2EccPoint(r, &rTemp); + + return ret; +} + +static int32_t ECP256_PointMulAddCheck( + ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt) +{ + bool flag = (para == NULL || r == NULL || k1 == NULL || k2 == NULL || pt == NULL); + uint32_t bits1, bits2; + if (flag) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != CRYPT_ECC_NISTP256 || r->id != CRYPT_ECC_NISTP256 || pt->id != CRYPT_ECC_NISTP256) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + // Special processing of the infinite point. + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + bits1 = BN_Bits(k1); + bits2 = BN_Bits(k2); + if (bits1 > 256 || bits2 > 256) { // 256 is the number of bits in the curve mode + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_MUL_ERR_K_LEN); + return CRYPT_ECC_POINT_MUL_ERR_K_LEN; + } + + return CRYPT_SUCCESS; +} + +// r = k1 * G + k2 * pt +int32_t ECP256_PointMulAdd(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, + const ECC_Point *pt) +{ + int32_t ret = ECP256_PointMulAddCheck(para, r, k1, k2, pt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + P256_Point k2Pt; + P256_Point k1G; + + ECP256_WindowMul(&k2Pt, k2, pt); + + ComputeK1G(&k1G, k1); + + ECP256_PointAdd(&k1G, &k1G, &k2Pt); + ECP256_P256Point2EccPoint(r, &k1G); + return ret; +} +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ diff --git a/crypto/ecc/src/asm_ecp_nistp256.h b/crypto/ecc/src/asm_ecp_nistp256.h new file mode 100644 index 00000000..f7cc5c05 --- /dev/null +++ b/crypto/ecc/src/asm_ecp_nistp256.h @@ -0,0 +1,80 @@ +/* + * 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 ASM_ECP_NISTP256_H +#define ASM_ECP_NISTP256_H + +#include "hitls_build.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define P256_BYTES 32 +#define P256_SIZE (P256_BYTES / sizeof(BN_UINT)) + +typedef struct { + BN_UINT value[P256_SIZE]; +} Coord; // Point Coordinates + +typedef struct p256_point { + Coord x; + Coord y; + Coord z; +} P256_Point; + +typedef struct p256_pointaffine { + Coord x; + Coord y; +} P256_AffinePoint; + +#if defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +typedef P256_AffinePoint ECP256_TableRow[64]; + +const ECP256_TableRow *ECP256_GetPreCompTable(void); + +void ECP256_FromMont(Coord *r, const Coord *a); + +void ECP256_Mul(Coord *r, const Coord *a, const Coord *b); + +void ECP256_Sqr(Coord *r, const Coord *a); + +void ECP256_Neg(Coord *r, const Coord *a); + +void ECP256_OrdMul(Coord *r, const Coord *a, const Coord *b); + +void ECP256_OrdSqr(Coord *r, const Coord *a, int32_t repeat); + +void ECP256_PointDouble(P256_Point *r, const P256_Point *a); + +void ECP256_PointAdd(P256_Point *r, const P256_Point *a, const P256_Point *b); + +void ECP256_AddAffine(P256_Point *r, const P256_Point *a, const P256_AffinePoint *b); + +void ECP256_Scatterw5(P256_Point *table, const P256_Point *point, uint32_t index); + +void ECP256_Gatherw5(P256_Point *point, const P256_Point *table, uint32_t index); + +void ECP256_Gatherw7(P256_AffinePoint *point, const P256_AffinePoint *table, uint32_t index); + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ + +#ifdef __cplusplus +} +#endif + + +#endif \ No newline at end of file diff --git a/crypto/ecc/src/asm_ecp_sm2.c b/crypto/ecc/src/asm_ecp_sm2.c new file mode 100644 index 00000000..b06f4d67 --- /dev/null +++ b/crypto/ecc/src/asm_ecp_sm2.c @@ -0,0 +1,791 @@ +/* + * 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_ECC) && defined(HITLS_CRYPTO_SM2) + +#include +#include "securec.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "asm_ecp_sm2.h" + +static const uint64_t g_sm2Precompute[8 * 256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* Base point G */ + 0x715a4589334c74c7, 0x8fe30bbff2660be1, 0x5f9904466a39c994, 0x32c4ae2c1f198119, 0x02df32e52139f0a0, 0xd0a9877cc62a4740, 0x59bdcee36b692153, 0xbc3736a2f4f6779c, + /* 2 * G */ + 0x495c2e1da3f2bd52, 0x9c0dfa08c08a7331, 0x0d58ef57fa73ba4d, 0x56cefd60d7c87c00, 0x6f780d3a970a23c3, 0x6de84c182f6c8e71, 0x68535ce0f8eaf1bd, 0x31b7e7e6cc8189f6, + /* 3 * G */ + 0xe26918f1d0509ebf, 0xa13f6bd945302244, 0xbe2daa8cdb41e24c, 0xa97f7cd4b3c993b4, 0xaaacdd037458f6e6, 0x7c400ee5cd045292, 0xccc5cec08a72150f, 0x530b5dd88c688ef5, + 0xb21646cd34a0ced5, 0x009a084ad5cc937d, 0x2a81052ff641ed69, 0xc239507105c68324, 0x7a253666cb66e009, 0x6bee2e96ab8c71fb, 0x35f1294ac0db1968, 0xb1bf7ec4080f3c87, + 0xa575da57cc372a9e, 0x344a417b7fce19db, 0x040e008fdd5eb77a, 0xc749061668652e26, 0xa6976eff5fbe6480, 0x5006206eb579ff7d, 0x4504c622b51cf38f, 0xf2df5db2d144e945, + 0x2c8b1a1a3c4b0d30, 0x05ff8856a6601689, 0xbb17c93e71f22a31, 0x0927afb57d93483b, 0xd572103000088f63, 0x81adf1f0855a064d, 0xac1c0ef6ebf26645, 0x150c6b1ab4d1fc7e, + 0xcd27e384d9fcaf15, 0xa80198337744ee78, 0xfdbe86a75c139906, 0xddf092555409c19d, 0x223b949657e52bc1, 0x037937707d6a49a2, 0x5cd6b6e9c12d2922, 0x847d18ffb38e8706, + 0x675d822ded0bb916, 0xd4ea35d60c1c29bb, 0x3db4333d4e860e64, 0xb9c3faeb4b161071, 0x3c286da2cfd31a3e, 0x0366a8a03024b3e0, 0x2491d2de9accf2be, 0xc519b309ecf7269c, + 0x173472a58cca247e, 0xfe8d59cb43619e4f, 0x0b4a2444a46a74c5, 0xa27233f3a5959508, 0x85227940922c02e9, 0xc3a8433140d1ebca, 0x768f7689b210f45f, 0x379e72f63722c924, + 0x84a04814db522756, 0xb2d0d065cd219e32, 0x21666061f65c3e32, 0xd3f94862519621c1, 0x47d46fb2bab82a14, 0xf6b743f64d1482d1, 0x2ebd57d146dca428, 0x4b9030cf676f6a74, + 0x668c74d78ce20ace, 0x125dcdd589c2ff82, 0x7c1aab770f67f543, 0x04b3cb10c9c6d8e2, 0x739a8fd805174a4b, 0x0c94816e63c4bc72, 0x4918e5c02e2b0b93, 0x63516355287e39fe, + 0x9c9f042d0279270a, 0x5f7b516c5bdaddad, 0xd89058ca059be46e, 0xbfc2df6bb17f971a, 0xb5fbf87b64af3c26, 0x73c9fc6fd150aaaa, 0xcef696b67939bd7b, 0xb145513f59636106, + 0x2b834f1d509b9cd0, 0x7bea65c6421e189e, 0xfa804513275f58aa, 0x952072d6ff9c65bd, 0x03891e105e009b00, 0x58d1434ae934ba75, 0x1a473f8d9748f238, 0xe6bb9804458bb70f, + 0x0a44248a36bb0a07, 0xef22ea28be9d44de, 0x4aaf81826982d748, 0x83b4a4de96a4d70f, 0x2e663cd4373a2f24, 0x3e707c8a43852949, 0xeeb6d6c6d7e74f8e, 0xe481c0d9ee8a98d4, + 0x461b1bbcb80f829c, 0x3b424f35f0ecce4c, 0x3291676c38d39324, 0xf73b839f13912c1a, 0x4c3533771db0955e, 0xdc2e788fb170aa14, 0x5ee9fab985c12455, 0x32ec7722695dc7cf, + 0x55645bbc8704fb68, 0xea133cd248a93e25, 0xbbce44ef5db3e419, 0x35648233f554ae51, 0x4411a9a30eca2046, 0x154b1870a6a65166, 0x6117bca9ce885dd6, 0x04d7ac60f6d975ef, + 0x36969f8b77125e6a, 0xbf5113ab85b5ed44, 0x1c993f01115c57f7, 0xdd18aa4aec26eac4, 0xe0180d54d4ae2221, 0x6cce6001d7c0b853, 0x3361493f76fac50f, 0x161e5851969da822, + 0x427e33ae8ed9c317, 0xa3448557a24554db, 0x221ea8657781ce71, 0x69fdf8a436fd8e5d, 0x71e35709341fdcab, 0xeb7b1ad657c155f5, 0x6b0a9658b33b347b, 0xbaa856d1cad68af3, + 0x1323f252e493952a, 0xf7c96c55940a4726, 0xe2e0586bb5dc9419, 0xa68b2ec49d1921d0, 0xfd4520a63f5cc585, 0xb95f2de69200269e, 0x933ef442fca7a734, 0x96f361a23b3deb99, + 0x0588fdd88abdee94, 0xabbb1ea1417f958d, 0x7575e3cb2fa9092d, 0x08314765e44847eb, 0x5eeb0e99c2eb61e9, 0x7de3a53937e8a75f, 0x6b443ab436095378, 0xdf922344fa592a98, + 0xe1de5f100950c8ab, 0x5b551c86a8976933, 0x137cbf4e8aa50535, 0x6407be639bc5b738, 0xf945321148e90344, 0x60fcfd988fff6dec, 0x12a9423fd80dea54, 0x141caee612e7ab07, + 0x0755a352dafa1e1d, 0x3e7307f46fa550d1, 0x1835a4d0f3e5e299, 0xe61120569974c0bc, 0x3b86cc142850b0f3, 0x02855e18d12379b4, 0xd08fc10e5056e4bc, 0xcfe30aa2c3877e52, + 0x4dbb2fcd069d45db, 0xbb570a9f430ea7f6, 0x15c07a8c04226fe3, 0xac8df677299e8288, 0x7bd8b7c847718ce5, 0x0e9b9643d766da33, 0x30c43be69b23cc14, 0xaef82cf361db1c71, + 0xd7240a35d1f4ffed, 0xec268911ccb79283, 0x314fa6c814c7bda8, 0xdf8a74f904d1715e, 0xbcb60a9e82017c30, 0xe1c80e7752bd6499, 0x7a7606ef148aa5fb, 0x0fed448a3f263918, + 0x0263b20d539e4139, 0x7e8581fbbcf5de01, 0xce1564c3df7d67ea, 0x178d1f6bd584afcc, 0x9b499a7da7820bf9, 0x7021aafc29ac8e86, 0x53da45cec1caada1, 0xf575f34e5f6c63c6, + 0x8e6a9e4fdf895290, 0x73783ef304251e74, 0xbcf26fe238a102c2, 0xa0a1a4fbeb476576, 0xe54f7f3a4896d9d3, 0xec73068587361b34, 0x0d09c3f281d4c41c, 0x8dfdd7cd150d2564, + 0xce37e84fc9541b4b, 0x02a85a7410754529, 0xd7a1f169475b4ddf, 0xec6f34ceacaa73a0, 0x73306a0ff0485872, 0xe607f33be20135ea, 0x6f251c63fbbd2927, 0x3c85cf62a744817e, + 0x6cb2f058c747d33f, 0x36f0dfe49113c16e, 0x94ed53ed581d191d, 0x91cb72dc55f84346, 0x3ea6aace93921f31, 0xf4c600e8b5dfe811, 0xf7efb07682931f88, 0x1957ad4cfffd491e, + 0x9dd4ef421635b9dc, 0xc9816be068be66db, 0x625773cae69bbe05, 0x28221c36398c4c3a, 0x2995225e66b162ba, 0x64c77a81858d4ca1, 0xab2012c41627cd81, 0x3b4d172d6963510b, + 0xfd23ea021da51c9d, 0x8b1ac02e98d543ce, 0xc315796922bf1343, 0x17a5f74d533ae724, 0x57d2e81dbb945dfe, 0x7befa4db8c8d3eff, 0xb9038823d9ad0d5f, 0x498470ec6752b2ec, + 0xac995c5066bdaaa5, 0x27d053c0f150fe10, 0xd6b48259b69e8530, 0x08daae840b2a43eb, 0x2458b9e3c73bf657, 0xf7dc310560bbe83a, 0xc1b8e58150da662d, 0x80cc0a980495af87, + 0xa32641e56024666c, 0x791734cd03e5565c, 0xa6d5c2b5817f2329, 0x25d3debd0950d180, 0xd39e100303fa10a2, 0x0458895120e208b4, 0xb938c406dd5cb0e1, 0x92d99a70679d61ef, + 0x6d69b1bd07837dc9, 0x451641e8455eedb6, 0x4624f85fe9b7cb83, 0xa1aa7f4a42808908, 0xc3c8bd75b5fe25de, 0x6e67fd81941c6a60, 0xeb15fccc63694830, 0x3d420dee447499cf, + 0x37a60fce33247b4c, 0x1afddac4a9667094, 0x72e11351388e9d3d, 0x87e13ab96307c971, 0x217ed12bbc413d35, 0xd7ac6191958240c7, 0xadb32c8ad1d8a615, 0x3ff4e73fac0283e5, + 0x549786448c4f3f4d, 0xbaf30f4638d2231b, 0x46dab2eba04afd78, 0x68126a90b051062b, 0x5a8ce092c6b7c016, 0xe7fec8984be51251, 0x35ecf208bdec5980, 0x7e72f70a2eaf1bf4, + 0xfa2f46cf90a47d2b, 0xe7579164cc5a233c, 0xcdd2cc00d6ce411e, 0x323159ac22478ac2, 0x939227b1d05f49ba, 0xa94c472c0089e4b4, 0x7e7a32282a0c2900, 0xe488cf88fe83acfc, + 0x31f8514dc6115cb5, 0x8c641a6cb43ae7da, 0x8b8f45b58a12e6cc, 0x3242e1de1fa494c5, 0x7dab7b373c8f551b, 0x56ab9bcf11b6f25a, 0xaa27b4380a8333ad, 0xcbf18ef2f229c025, + 0xb7d6af71fb640a75, 0x47a9f7f697a28e0b, 0x6b663188dc931a44, 0x7f404379407b0976, 0xf500974f78295571, 0xc7652177fdfae41b, 0x860bec0a6c78c5d0, 0x3178d1bb1435c9af, + 0xcd1bb864637cf4f9, 0x10e34d63f48c5ed4, 0x5b075be3c412ad03, 0xe6857f7fc3345385, 0x1ca28a8ee15f1878, 0x5d72264551d68eae, 0x581dfa7d2b4c09e3, 0x6b61903f2ba03769, + 0x2bed704f6dff2150, 0x3b66f17073149664, 0x2a722a8a3b798a66, 0x376bf9e5403eedb7, 0x95c769d2fc372cd9, 0x35698578596b792f, 0x2670a8f2e7f7a641, 0xf6f8ca3c58d3089e, + 0x47d58af32a91ddc2, 0x30abb6eab3f02921, 0x490df25e43f73f13, 0xf537773939d38a9b, 0xf9099fa3212d8fc1, 0x63ae367eb959d9f8, 0x8e2e511cce74be18, 0xbeb6132d28ff4099, + 0xc88b69c57731c07e, 0x52ed6a3d227ff763, 0x52cd70822173c59f, 0xd0d299040f1250d8, 0x5769c965f01be7a3, 0xf6db21dd26bbf942, 0x648ab14004516e12, 0xabfc349e2f1d2118, + 0x0180bb9d84d7141b, 0x134911d8e4bbaaec, 0x4b92b8f64e804905, 0x897da7bb358b6d21, 0x38ecb2e51caf0aae, 0x6543e7e5a787f93d, 0xf571032510364cd2, 0x995b4a9a20d88c89, + 0xdd379996725be125, 0xb1df2f7a4fcad9d2, 0xa7b5fa7d47457508, 0x2575c600187cec18, 0x1e259e3d752b00d1, 0x83580245568efa73, 0xed22d2e0508647f4, 0x84442dfc92fb06ff, + 0x3d24524ac4d2c465, 0x0462308a30d9d3e5, 0x45254a01baae8a2e, 0xd2593661cf6daf12, 0x5dca599abe435bf0, 0xa169da8afcb3a620, 0x6cf13824af9f6508, 0x416b602161b2bbf6, + 0x5c4b342a0ead84ed, 0x654b3a33c67ed63d, 0xa31dbd4bffd8c960, 0x2f7fa743ade7d8ef, 0x3e6c057797b29702, 0xd19f608ec8d8fdbd, 0xfc7473793f836beb, 0x3a0b20471be6e94a, + 0xec0ddc2b82cb0747, 0xdaeda7da80dde8ce, 0x98e2f9df22a96604, 0x8ab85f67eec67f06, 0xe2874ab08c6c6e2b, 0x0445b6381fc45c42, 0x53e29b91b9afd253, 0x0d90c6f4584c9d15, + 0xbcafd803c7fa407d, 0xd4a5aebc3d150787, 0xf0d92d5deb9a8696, 0x516478a2567460c7, 0xab9d905b209fb8a3, 0x0e93b2f066f5b023, 0x36ecf288427a2ed2, 0xcd8596762e7c1384, + 0x2755c80bb1316dd9, 0x787ab24d5a604fb9, 0xdf25cd6e045b914d, 0x968513d803c0a611, 0x60f9fd6e5a72901a, 0x9a31b57f2e430478, 0x893c927b9668ddd5, 0xb0992fa258261de1, + 0xf4bfcc77ea4809c9, 0xc56284e868ddcfa0, 0x6f0aea97a43907c7, 0xfbb54c148bd5828b, 0x18c1df9b3daafa9b, 0xd037d19f80bdadce, 0x06a3849d9204ccb4, 0x3ace4fd8dfca573e, + 0x35eaa6e36461d0d3, 0x17905f2a781de540, 0x2d531dd8552f2765, 0x01eeb7b6a1494475, 0xb769488b3901a9f3, 0x7460ad9d8bcceeb9, 0x66a2abf1c7753bb8, 0xabd4a0f7fac6deb4, + 0x869252402e6a9f99, 0x109e9f4b61c6f6bd, 0x20498d04f39cdf59, 0xd62fed8ce52682d6, 0x58f3f064c341c481, 0xaeb47ad53e382513, 0xe63d189ea323c1db, 0x106309c4f4f41c3b, + 0x828cc5c0f20462a9, 0x6d96e2a601b93c0e, 0x4cd09b8e39701ff1, 0xd909bb3be4c02cd8, 0x5eefa9a3ec3f9511, 0x05977fb39adacec7, 0x5bb65608aa16f24f, 0x10d8c2a3b3396bd8, + 0x4b9fdb48e73da1f4, 0xaf424d81ca4837d3, 0x12977a990acddfbc, 0x30c06b0c4ad8881a, 0xbdb45a06820f214c, 0x0d2b4dcdd1d72197, 0x6ac7be40ce1c0b24, 0xdffe969d5c0c2037, + 0xc86610f34f66b3df, 0x015c9bf09e75950a, 0xcbde1f5982ace379, 0x6a13800155ef04b7, 0x1d092851b33025b7, 0x41d95d9e42639ac6, 0x84f5b14011d026db, 0x2de1cdf12e9cb8c0, + 0x866723c1db16de4b, 0xdca3ec1ca731d89c, 0x72976afd2d0f4836, 0xb21e68780bd8ee9a, 0xaeece0bcd44dbd4b, 0x01b03b987a6324f8, 0xcef0026bcefa2aac, 0x85405981156ecd7d, + 0x123308b4a9c5711a, 0x721dd5dacce5bc3d, 0x26804860af6a7e95, 0x7ccbc3bf87cc4d54, 0x5995334c3e242616, 0x3acfb676b987c213, 0x145518b80573d4c0, 0xc6ebde08aded9af4, + 0x9a4daa72d104dd8b, 0xdde4dac3cd08710b, 0x57e470f1db64f91b, 0x6c7f036eb374832a, 0x9f07db54caab8fcf, 0xbc06cf52d8d5f56c, 0x4aea7bee9c0e0ed6, 0x282c76e18b24f8b4, + 0xcd43853968e0f8c3, 0x9cab4fb10369ef34, 0xf5aba10ba06befde, 0x99ff4d8ff311e9a0, 0xd35aaa101d22c55a, 0xf2b3182557bf0529, 0xdd523fc5310a3ecf, 0x0b3cc5a35c82a6b7, + 0x3a15c7a108af767c, 0x0693ab9cd8951ee4, 0x05f23cff908ed521, 0xba38ae4ed8f30818, 0x3567e7eb19841fbc, 0xd4f1f91388ce0fbd, 0x7b3440651da95cb5, 0x56b6c91fef0c0213, + 0x0c5516aa79811c1c, 0x8869b952943a29fc, 0xf382d60f67fcc2e2, 0xd3a606c601b5c66f, 0x0d6b519f677f9e84, 0x3ef8e988f9e9e6c0, 0x8726d00ed296c2b3, 0x16429acf62bb2d8f, + 0x858ddab4a1817e91, 0x6f0b334f51351a23, 0x7f09f1f531213b6f, 0x82a81778d373eb3a, 0xbed0e457d7a8801d, 0x632446bf2a988560, 0x3f2e4e9a57914a68, 0x45690fae01c59d44, + 0x29dc4c21401d787f, 0x5c4a52f82ad10df3, 0x7048dcd10cdece63, 0x5eee8921f4fcd342, 0x9ffe119727f734ae, 0xf39e93dc1c8b27ad, 0x73516bbad0f603e4, 0xb6b3462b6a39a55b, + 0x4a69c806e78615c2, 0xe988794843797b0c, 0xa47dcf644f700651, 0x97662389f36ce643, 0x17eef58bf866b33f, 0x5eb06c4515ff01bd, 0x328b8d67d4ae956f, 0xcd4d9449aea5cac5, + 0xcd382e53ed23ae1f, 0x7b1eb83b8306ace5, 0x15a8ecd063d726ba, 0x403b18162679c055, 0xd0a5d4ebea56f425, 0xdf882dfcffcc84bc, 0x8d61a1c805ef7074, 0xeb42ebf496a7bd69, + 0x4932828fa1eda64a, 0x9b29f654ca04e515, 0x899b922465789ef1, 0xf37e88764c7ac45c, 0x5c21a5c0dd61d736, 0x2554d8e82845136b, 0xbad57a13e441c8c8, 0xfbf59fee83ed48c0, + 0xb6dfed771b9c57aa, 0xd2a721c4ca5988de, 0x4a72eef2c3b79c4a, 0x4735ff387ce5d531, 0x6595b84458e25402, 0x9050829a6000ae69, 0x4e309f2a26856099, 0xa8ed2943cca6016f, + 0x93533941dbcc0ace, 0x841a1067098656b6, 0x30bb10f83e216e8a, 0xb4f7130dc7e9212a, 0x93ce7fc238b81921, 0x5b7e8e5a8f641f8c, 0x9ddc33deb95a5b71, 0x2f29f4a14bab0c77, + 0xfcfdd7e629b3cadf, 0x773924b26ef7247d, 0xda1da81a16bb9420, 0xd25e0cb35f1f1faa, 0xc545c1a75e458451, 0xabedaafe76dcc117, 0x429b67f6ae073a8f, 0x67295cb2e7ed1851, + 0x844c475a38b961fa, 0x355386afd494c53d, 0x81c6dcf871dd881b, 0x092af9a79f4170d1, 0x7d3dce96cbf08554, 0x72eac8accba2b32d, 0xca582b8e15cc89af, 0xc9a3d27ecf09b2f3, + 0x09acc52ed3b84f43, 0xb5b0f39553570b43, 0xe9f8c0f1152682a5, 0xdc532866d1359272, 0xa830e1dfd3792ce9, 0x6ad5e7da482f3096, 0x0c80e17dba0aaedf, 0x306cfc30b3a85aae, + 0x13970909b51d1a80, 0x14ce48989614edc1, 0xdc467497755cbd57, 0x9660670c8b61b1f5, 0x63d8896cd021a129, 0xff50d6958c5fb8d2, 0x39ee34cd34b67a5f, 0x8358e926ccc8e30d, + 0x99f8edca8af044d5, 0xd3cbf4330b841d22, 0xd174131b63b02eba, 0x38eb496124b15eeb, 0x48a22e8cfb012cfc, 0xf5da2e278065962b, 0xff4403f9200acae2, 0xf184e282b6b418f7, + 0xc6b107ca5b20c9f3, 0x26f583a441e0630a, 0x92d0e75229f427bc, 0x4f703d0de9e071bc, 0x3171ddeaace634c6, 0x12c49c6dc514680a, 0xa7002297639b4906, 0x1700f3d434b737fc, + 0xbe75a9cad6bd2300, 0x748db9d9c1cb48ba, 0xadcafa24a2f2c39b, 0xea6d56b46741bf09, 0xc30eead02da09851, 0x8577fffe20f3731e, 0x245a5b85a5e0ebf1, 0x18e5eead89732407, + 0x746075b5bfc55131, 0xba4453d3d8e14282, 0xf8a86d159d9a709d, 0xa4f4630217f0e85b, 0xf04d0d9b0b09c7c9, 0xe9669f06d6c1b268, 0xe2e27fbcfbda045e, 0xc8a35bec05eb827b, + 0xeb9d4eaae174d6f2, 0x03e09a3ad81dd4ff, 0xebda3404ab654a2f, 0x5d39c2892dfb220a, 0xf1c3399fdb7845ad, 0x7d979bb1bce205b1, 0x89d18134a93a533c, 0x35b91f56afed2092, + 0x7c42374fe8984cb6, 0x9c764897cfffdca0, 0xcaac6a4d50fade17, 0xe0ef4846a887c038, 0xd82902a52c00d995, 0xc5067a8d1a2f3a41, 0x0b4ce0b7d7daff7d, 0x9230ff23783733a8, + 0xad1951435957726a, 0x2206d08929796e05, 0xd4fe4d4127cba088, 0xa162fb5f8af4185f, 0x3427a4e96c94f67c, 0xe86e6a15f91af428, 0xb465eb367ca10566, 0xb9e3bb2376a12196, + 0xe445463326fd5391, 0xd2cb5fc8266bef82, 0x39f16938e29cf376, 0xb5e7992af43ff901, 0x4bd11a57af8b46ab, 0x0c5e337332e53a91, 0x5585aff51f34de17, 0x3324dae6ff8a7d31, + 0x7d1a4a46cbefccd9, 0x27f1086e10c87ee9, 0xc78c20aec8a5fdfe, 0x4da8bbb0f99ffecb, 0xc62e8ca1d2255a8e, 0x6888bcbdff421c66, 0x4505e94b0635a09e, 0xcd4588f38a097beb, + 0x5dd66e10fd954995, 0xf4c89fe58d2946ee, 0x9a994e3b6e6e8e23, 0xd8a26b12ea5c4d4f, 0x5ad271ccd78f3f33, 0xcc32ddea6b84a3ba, 0xe06e913d6923d4a2, 0x47d54e91bac13b53, + 0x9c284015294338fd, 0xd5e81534cce44432, 0xcbe70ca22e5c5807, 0x28449ff72f96a915, 0xdde032503e64423c, 0xf7bdbe2478c4a4d8, 0x8b7b8d331850a22f, 0x6c6d8382d09406fb, + 0xef14705131546e8c, 0xe37d671893d4f2fc, 0x5d8d444d3e8cf4ba, 0x61572c322b045a47, 0x82d10acd5f5bebce, 0xa1959df1dec34077, 0xe91ea4d68a7640f3, 0xe3b511c42ceef515, + 0x481f41613b55ec09, 0xcfc60e29aa074743, 0x58d29712da50cb69, 0x9912f2f0ae0595ac, 0x43196eb35d95b713, 0x76e6a7ee0eb0d7f7, 0xa63822a6684c88ec, 0x308d561a3f241d0e, + 0xc044c871fa3ba783, 0x37dae2451b0fed32, 0xcfcc32d3fcaf9df7, 0x8363e2ee5e5c4c5c, 0xf7ed72d0656c9949, 0xdc3b5a0fe7c9306a, 0x1c69661627293531, 0x9efda4aa036202c1, + 0x062de907d0953ad0, 0xf8041e0c6f8a9ecc, 0x6115b8f3de7a86b0, 0x347ddd33f2a2a793, 0x8e7bcacc36680035, 0x9fa94d3cdc8750a8, 0x04e8b20daa55606e, 0x5a2280dbdb9b3752, + 0x6e31484dbd771d0e, 0xa5fc6ff489cfc13e, 0xb169aadf11e60e81, 0x2837c25fdadc2e26, 0xf2030f4225a85995, 0x7807147e3e464e77, 0xf99091981e6bac0a, 0xc3723f3fc316243d, + 0x2741ab72959580d9, 0x1cb62f04ad353b13, 0xd083375dc8f7410b, 0xaed46d363137584e, 0xa3d1bb4c8eb5d8f2, 0x830282b1dc1d81a1, 0x083108d71d52fa0d, 0x3b0d22596a1813ae, + 0x4267a218068f0d8e, 0x0ad610f0ff4c2d83, 0xa8c734baf1d3ad11, 0xec1fbdf9e74e9729, 0x776d76940e9089f7, 0x423ce1f3edd46634, 0x47826701c68b519b, 0x3eedfd07b9887154, + 0x68ef1d10a42f776a, 0x6386fcab69688add, 0x36a5dd89d191c3cb, 0x8c4881e5d7393294, 0x66def5145491bd99, 0x0a91c1fa773c3457, 0x43799ffb08efb028, 0x85cdcfb669092acb, + 0x7f4fc84c4030cbfb, 0x72269f3f2b240663, 0x2fbdd32ac29920a7, 0xbdc4d61a0367ef71, 0xaa1216a122a659a2, 0xab1da8335c171bb0, 0x3ca0d22c3b3e45c4, 0x0f946baaadeae8d8, + 0xef14e81fdd2b364f, 0x2f55ada2ae0de459, 0x940af90140a2de69, 0xc7e75e9aabf401bc, 0x47a9ff788e1c3a3a, 0x2ce3f69491e5dce8, 0x81dbf7dde0977adc, 0x42ba0b11851f6dd9, + 0x1b4edf339840cf0e, 0xad8ff5b21132fd4f, 0xd5e31a8a588a6101, 0x1661c89b16294868, 0x8019be652e5068b1, 0xd91b1fada5f73c41, 0x283898bb911395dd, 0x06ba3fad70685b96, + 0xdefeb106c49760ae, 0xdad52aa98d5e77f0, 0x0b9e3af9140b5ea4, 0x6ea78774ca7519f2, 0xcb4aa4498abb9d51, 0xa5c5b3f4d0469271, 0x397aadf70746ccb3, 0xc624e8dffabcc782, + 0xcfdc959047b20f62, 0x6839796b357d0be1, 0x2c431e27f83005b7, 0x0569f1c4a75037ca, 0x709460772e4c876a, 0xeaa568fd7c9f7dd9, 0x4eae8ce3c8dd9b61, 0x8847a12643e7a6f3, + 0x50337833e84a623a, 0x6d0f0e64adf10b27, 0xf3029bda34083597, 0x8204c4bb5cc07376, 0x5eb6dc8d28db1c54, 0x08f42a900ba5d9db, 0x90744ed74b2b207d, 0x1e9991f233d884f0, + 0xaf5ca8e8bfa880e6, 0xfa43aab6924390d1, 0x4a7d2a178fc16736, 0x5a4aa3bf0525ff25, 0x00092c75b19c8544, 0x31fb7664db32f0ef, 0x196515334ea72250, 0x053efa8bfc39562f, + 0x9bf9efc1b0242cb9, 0xfdd1f568ad88cea0, 0x5bd701ea2ded6b29, 0xe3ffd2783b7121e1, 0x6301c5c26b454d79, 0xc4d21c15e28fe4f0, 0xa2a4b664ef38802e, 0x7e23d698181dfdd3, + 0x2a76ce3fcc775c7e, 0xbcf7808774f52159, 0x080f9528ffbf916c, 0x885bebd0441de6f0, 0x51e6593154e91061, 0xe5233d5e7b348535, 0x473b3b3f184aa822, 0x21151e7b977aaa95, + 0xde51ba8cbee9bd99, 0xae5f23f269f957cd, 0x708d74a0a5a682c7, 0x91097071cb646e5e, 0x3bc35e10f5963bbc, 0xb426789ae226b25e, 0xef6cad6c7f12beb6, 0xeab10ec96bacab69, + 0x23f3533bb1ac8e06, 0x8a6724bfaa07e6b3, 0x7b8760a2905deae8, 0x56702de289f4e2f0, 0xdada3f65d4f55bf8, 0x7f8c6d057d31d642, 0xc9b00abdc8495650, 0x1c51e60abc0eccd2, + 0xfec65ffbf9c42481, 0x22e8c26bb26384db, 0x6be43bc89cf09d40, 0xbd6c96655fcfe6a2, 0xb626341c04311030, 0x905fe7ef57925046, 0x9509529bde2ef3df, 0x7948636bc0cdc7a4, + 0xc30c108a100fec81, 0x6221aa9d592e8828, 0xf3c8215591cebb72, 0xd8bf6ea39c57b9dc, 0x1d183b59164b8c40, 0x7ea2a786319e78a6, 0xc973b32e93bc2f87, 0x9025624014782cbe, + 0xbd6e444a134eac53, 0xfe0f19b444f2e570, 0xf60bc3c21500767c, 0xa8502a4bd10e123e, 0xded8e57012f4651f, 0xaeb1b9241eb04d7a, 0xd513f05f555fed42, 0xfa0c380af507ac6a, + 0x65b433a8dfb5ce3d, 0x98999ef103eca182, 0xf56d0853313c64ec, 0x3e0417206422ad1b, 0xed5571f713fb7ed3, 0x02876cabef2d641d, 0x60cabfa0f8547278, 0x63a185e898896c4a, + 0x0e1ecd9e46466a47, 0xd757ae92795b1541, 0xd9dcd23ac5c15de8, 0x3b3de05121ff3a36, 0xa11606102e19c39b, 0xd6106c43e6eb5c91, 0x5ab4cccacefee53a, 0x007b8326ebd1926d, + 0x32ba940140487c6d, 0x46e0755a22260568, 0x7790f1c8c0222f19, 0xb2bb4be2c6bded6f, 0x175f675d63cdbf6e, 0xa1809a9af4da899a, 0xf7138f89ad5d7afb, 0x761b3fb67fd8c602, + 0xa2eca2c4334f453b, 0xf64d9dc500a7a507, 0x924adebceb539c8a, 0xc209a7edb19c905e, 0x6dbbff18fdc777c1, 0x17fd5c2997f84b5a, 0x73c3bbc097fbb941, 0xf67681a6300cb02c, + 0x5dcfafe1b79d21f7, 0x7d4217fb0d2f24bc, 0x53cc4b66d1bf5b67, 0x8512234b09a632ee, 0x7afef5d3c566680a, 0xcc16073d5ac4919b, 0x8cc1c7b68bbc832d, 0x50c43f4413c4c58c, + 0x724c733a800256f2, 0xff3978a5dbd4f083, 0x9b2a00ed5c8a3916, 0x69e19793abf7a632, 0xcecb6edcab1857af, 0xa462893d3c564a29, 0x61c82e8a6cd57f10, 0x3fa79f6ccffe83c8, + 0x364ce350ccad2815, 0x83d7adbfcaf46f89, 0x4c2fd40ac0ad5ce2, 0xd51c2c33a7b276b2, 0x37328b5094395ce3, 0x70812a15ff5243fe, 0x15ad4a85db620d26, 0xff3f9978e53508fc, + 0x4dbe3930f085dd46, 0xe68954afa8bc18b9, 0x1e20699412fc97b3, 0x2b5bc43566c8182b, 0xe948a5e26d1d3ddc, 0xa35730ae4e899f73, 0x8187e151ade21342, 0x22ddbfb842707e88, + 0x314b8155d6b6ad5b, 0x73d0d75407a752cb, 0xd9da783ff9fa2b9d, 0xf435d414df4f5076, 0x1dff839d5c16d42b, 0xd136dc23e40ab6c1, 0xfca6360f0e1c5a33, 0xaf1c58598e7cb56e, + 0x43dcc5d73e585d51, 0x519f6ad4eebd062b, 0x80754ac3c1d740f1, 0xaf1fe551463c5b67, 0x1d24556ff8ace198, 0x02b91a2134d2ee23, 0x13d1ffba18d54997, 0x5d56aaa246770a3d, + 0x4fbbcd60cdb5494b, 0x848f8dffabbea9b6, 0x42672e40d5a53819, 0x584f13fbeaca5bf3, 0xf160a9ccab6e11b4, 0x51a73a3a653b6373, 0x63c3bc25ecdf58c7, 0x325cc030e9514373, + 0xe2a6b8f7aa1916bf, 0x9c668a4c33a54663, 0x5931972834a653b2, 0xc5e8ca195ea0274e, 0xa5a7a5e95eabfb91, 0xdd71f31da6f7c46e, 0x51b21e140a5fcb76, 0x7d4dc704d3c881db, + 0x72bb35a49a20c914, 0x1c426d0b4fe64fef, 0xecfeeaed431bab4b, 0x85ac16eb56493abb, 0x45c61bdd78abbe40, 0x937b96bb7431209a, 0xaccf7f070abbe8fb, 0xa17a2586c5bab868, + 0x0b40d7846acd93bd, 0xe92a3100a8aa7d86, 0x5a90c85c2b95d141, 0x42b957edf0eac80b, 0x97b291bad89c9cf3, 0x8164c5fc56ad0b3c, 0xe178efd995023ccd, 0x0035cde42dc2cf15, + 0x6a755592839eaf7a, 0x324a4b4eba667d1a, 0xf5c3460b16ba21a4, 0xde9f478017f5ef6b, 0x8d31bc90b58a334a, 0x31fbdfe21dc8eb9c, 0x23d8b2d4a678ac83, 0x4dbb4cad0a7e2706, + 0x7c91dba2fa129d98, 0x213e75991c59be79, 0x59f768c230bde513, 0x8c2972d5ff12ff22, 0xc691e275dd7475c9, 0x25f4ac9004ef9825, 0xfaad8de2af3a5b1a, 0x0460afdc2ee1ae1c, + 0x8f542a7f1830047a, 0x2d9c80739c120316, 0x259137908d220bb6, 0xc1f1ed239eb2e2d6, 0x52fc97633cb4e187, 0x466c94626a15b643, 0x4a2391acbad2fc28, 0xd85fcc762fbee484, + 0xe746df69c444e173, 0xe716b7df6ff3866f, 0xde7f692c0021274f, 0xb5ff42f5c63a693a, 0x183370004c000aa6, 0xcbb94a5f3fd9d41a, 0x592117ec50ae9cf2, 0xba6d987fe545a9d9, + 0x7f564fc0813b5d4d, 0xb0c3c5252443ec98, 0xf763d3b20ef393ef, 0x86ba065985aab176, 0x1089bea456d640dc, 0x572ab615149aaddc, 0xbb18497c0b5e8699, 0x42acc8ecf1858fd0, + 0xc7033a8ea70569dd, 0xf6670a5251e942ca, 0x76f01cc756a45ce9, 0x12192f6c25bb90b7, 0x5e67d8c073397f3e, 0x5943d66bca82b331, 0x2177d44402e76b82, 0x1e247b0fb5819ef9, + 0x69f15537f160c9db, 0x2b7b74de9915f35c, 0xb028cd637d5f3b3f, 0x730cac8955b4a829, 0xff62e2a27178e739, 0xd895fd5a4574f298, 0x9245177f0510e27b, 0xf5d500feda9a7127, + 0x073a60f73af7d8b2, 0x36fc50273862bdbb, 0xcf8391afee8b886a, 0xcd304e07207e8fd6, 0xf71260f3d5316697, 0xe8d71e81ffa497c1, 0xa945c9b42720abae, 0x45e5de0e5987e1ad, + 0xce05418c9fdb0589, 0x94a780beb0eda9d8, 0x5b7ded5404d3fa8c, 0xdbe264a2ee1ad880, 0x7aebcd67079987f5, 0xf60062c177a57277, 0x9f71be1267cec822, 0x3f901c7848bef8e0, + 0xecebbadd7dbef974, 0x3d01a5999ab31878, 0x9646807f6f1f91ba, 0xd8b30022c4e5f774, 0xd4f845b74984a74a, 0x9ef317840a4cd193, 0x201c39b8e0cbedc6, 0x19204c0d6c7fab92, + 0x2aff1d698b3e9596, 0x03c3310096cbfdfd, 0x37fb5e89e4ade4a1, 0x73fd021127db2008, 0x1e56cc63984cbbdf, 0x884aa70a81db42e6, 0x2230ad7167d0a7ee, 0x6eac311bf6f3a5af, + 0xa6bb02fdb15ad981, 0xd53d933ff264dba9, 0xa46551cb65cfac45, 0x666c41a76471a819, 0x7bd7ba38a851312a, 0x480fa8cd7fa30feb, 0xa5c42ef922662d51, 0x0afa1c9a8be1ab4f, + 0x8d9c9aa214346d55, 0x516094082cdc3e18, 0x16a963ea107997d4, 0x8280001138c15cfc, 0xe4ab234bb9ff258d, 0x69880d3b6699086d, 0x3d7d3d1e32308eca, 0xbed0774a3daa1b2e, + 0xb6df4485983a76d4, 0xc6fb7d520aee753e, 0xdb74f71648c81d1f, 0xb88725df36319c29, 0x9d0c477978210a58, 0x841060a628470c02, 0x70ccd8bc370e425c, 0x1634e628b865cc42, + 0x0e037ed34a49d063, 0x53cdc28cf90ff0e6, 0x348b5047fc84dcbc, 0xf79591be4e039c0b, 0x9e5db80c33f78fb6, 0x69ce92f11c21829d, 0x919dc94a46942844, 0x0d8185a00b9273ca, + 0xbb19136e4077238d, 0xdd9d4ca7441d8075, 0xd51e8bfd157c3dca, 0xcefba865bb345540, 0x89564e91dd8456bc, 0x1029166c5b13d782, 0xe02cd50a812d2c44, 0x654de0c9dadd2e89, + 0x14709b5a9e1a3379, 0xff2a7b2dc49a6ce6, 0x93bb630b0c412bd8, 0x11f4f036687dd7c0, 0xee7fad8f341b1c8f, 0xaf83447eca86634e, 0xbd9c1795dc812ce4, 0xb7099de7e683f6bc, + 0x2d39ca5fc097f911, 0xfdff3a8358576b7a, 0x272beaee1c8f9796, 0x726e78ffdbc59ca0, 0xb67d5853eaa0c878, 0xc03a497efc478336, 0xdc72b0f36a94a20f, 0x15d177b6ad45123a, + 0xb887bb864c795fb3, 0x6566180c005efe01, 0xb3b53dc1f6851821, 0x44699e38ee0a6581, 0x1c55a93806333642, 0x1fcbc68cd58d1cd6, 0xa244bb60d708e219, 0x07173dff1b5350f7, + 0xb8715e9116baeff0, 0xd3752ba762ba2ca1, 0x86d91965e5a31a56, 0x3c27c4951d076d17, 0xd41f651c2ade59ba, 0x8f2ca8db21b97bc5, 0x1c2a1efdae15b528, 0x96977c9dcdba8c3a, + 0x91c8ddf3688697af, 0xc2de47e16a2fa935, 0x01d09ee453aeaf90, 0x9dbc205a2b000616, 0xc7a82e96d594c62e, 0x3317b8eb5b8b73e5, 0xfff7c8b4c3a32096, 0x6453b70094e3358c, + 0x2b1bae699aff8a4e, 0xbf7b4736ad753b49, 0x20f6e0752f5bfc7b, 0x497dd9715e1cd5d4, 0xa91030923e88ceb4, 0x602ac3f33ced7c4c, 0xbf584ae8dfb8e2d9, 0x3105b41ec3549b6f, + 0x163d3abbe998423f, 0x51234aac25187982, 0x8770f9bcfe97c132, 0x1800daeee2fe2a88, 0x0f02b3a8243fd4aa, 0x4a536e070e2bc9ae, 0x628c64308bc9c315, 0xfbecf1323c9722d9, + 0x331ad785fc3e1d41, 0x5f5508bdfb62937d, 0x91a3214706923e0c, 0xfc796e8da1017f42, 0xaafe90f59343d9bc, 0x2d136e33a60bef49, 0x02f9f2c3db9d0229, 0xd4892cd932be8419, + 0x79c72ac302f0d281, 0x8abb8e35b1d94786, 0x0c6de808c0c12a8d, 0xac6d4d8e5b9c2ed0, 0xcba0baa1708e791d, 0x4bec127f651f20ff, 0x261d3b5a50d67450, 0x0fc781b9f92cd6c3, + 0x383faf53f2a71eb8, 0x0c20e971447ba60d, 0x3bdbd7533c088d5b, 0x56c8661b6d330584, 0xb60ad35ea1d2263f, 0x737d7418bce8ebe2, 0xdda539ab99ec21ed, 0xe5c1cea1abbce298, + 0x4c92449387476985, 0x9c3be4e72e40685f, 0xf6d9c228a9f85902, 0xa44764c91adc6a9a, 0x0db0d2ba599a7553, 0xe3788aa1dd74946a, 0xd239baffacd81b2e, 0xef52f85666c340f8, + 0xaaadb6ea9b1c8a45, 0x86fc426284837b81, 0xb33810a5001fa2cf, 0xf990bd17f7e2ecf7, 0x14aa4676275e6c1c, 0xf19a05d12146d05e, 0xea5f3c7c6d5b9b4f, 0x32efb45c62042da0, + 0x7f430093a67ce3ea, 0xc8f47792c4d16d4a, 0xa7e72976b7f5e237, 0x26550333603f8d3e, 0x9b8fe810f3c3b225, 0x65e904778694f5c3, 0xe18bde37757c008c, 0x4fc064ba9ccda596, + 0xa6ec138b14e30506, 0x064b8d8f63af9202, 0xc3783b153f753ecd, 0x20315c3032141460, 0xbe04af9758a4cb35, 0xa7f4476ceb2653a3, 0xc4699159169fac3b, 0x4e2d709e9b1d01cd, + 0x4ec5972ace479262, 0x2fc417acdf559f30, 0x0605a730b11000e5, 0x8b65acbb6a17e365, 0xd967fbe917266184, 0x1c10125e01f5db0a, 0xbf638c23b61967f9, 0x71b359fac654beb9, + 0x9d83451d64277002, 0xc8777ce755abe4f8, 0xfb4530585d7e824a, 0x63c28165d9737d56, 0x7d9dbb4c39824fe3, 0x469e8165902bacf8, 0x5fad83c408ef9c40, 0xf8b2d576c30d1026, + 0x29f9f4bea44b1781, 0xac726909624bfe7c, 0xaafd751738177909, 0x90563245ba1c612c, 0x389ec2a7d7e59ce3, 0x50500c567966d3c3, 0x26b15bf6cb1ad6cc, 0xe9080fe122c631b5, + 0x17f6dabe12e3e5d3, 0xc3f85d05a0f070f8, 0x67d33630af152ed4, 0xdb3b4096c5c332d7, 0xc3dd07768e70b774, 0xa1e0b82d0516b75c, 0x867ca995ad903a61, 0x4fcd47a488ba6d51, + 0x6c6aba39dfc7d00e, 0xab65e0c18b16269b, 0x09ba717e85654122, 0x07e4cb761fb1b0e5, 0x9265799c5d55a837, 0xf7e6d513b6437316, 0x94a696b3988e41e6, 0x2607761bf2629a5f, + 0x973e75d9df82ece9, 0x48730461eb3c4d75, 0x5796dc273ed9d51a, 0xf325bafd97b61151, 0x7007d37e9b53ea4c, 0x3368fe5e05f94087, 0xadd778da036b0736, 0xc31fcbabf6fdf8d7, + 0x35de52e719187698, 0x1d2f3e4087fa3c08, 0x8047f5eb6ee05190, 0xd5add1eda45df387, 0xc2431d8a98a8fe49, 0xb1c0388fa3162e61, 0x1f0ab07565c55677, 0x7f3b14c57417b083, + 0x1f0ffa4f1abb4291, 0xdfec55dc328de4d0, 0xb792695f0a121172, 0xe684ea8df0457fae, 0xcef58a827a97e9ba, 0xfd341be16fb9e359, 0xc87a2331a9fb1692, 0x2527b948cee2e7e3, + 0x5e101fbe7514323e, 0x0d06560293e73c10, 0x1829f79b98724d80, 0x0c6ea39a34167a64, 0x1da654dac1c2b486, 0x4381d7a197d73b93, 0xed2de677dfea2660, 0x98cf929f0489101c, + 0xd6f382504a8d8ea7, 0x483110e79c14ef66, 0xce485d95bbc34776, 0xaec1a6a8430e7289, 0xcafe578fb670a41a, 0x61243b580f10d832, 0x221c3043ce630b2f, 0x8e8705368c784121, + 0x7963cf963518f155, 0xc21b75f27e48406f, 0x8f2f2bb31db2a418, 0x467a4ce355531acb, 0xd45bfce4db6ad410, 0x116a3d9dbd9162db, 0x26b549e62d30c113, 0xb4799b40daeb1ca5, + 0xac6d4450ef27b16a, 0x51303f5d166ed3ae, 0x2a7b47acf0255aef, 0x85c10733b0fd7de5, 0xfa1b80f6fcd647ba, 0xc3b3a75c8e36ba96, 0xb89f7cf587c773bb, 0x2585e4ca847ec1e1, + 0x8f587f5b9b828303, 0xdaf3e553b32110ee, 0x5a080e99f299f28b, 0x60b02561cbf056d9, 0x819439e181a81c62, 0x68e7551c7255e324, 0x8e47a1bdf4e2642f, 0x30b7c9517b5baffe, + 0x2effcd65da6cf6e5, 0xc0e53b063106b643, 0xd1ac9588459392bf, 0xc3a9b3fe5c4914b8, 0x6fd4a4e70d53afbc, 0xb16f9f98ee51d7d6, 0xc372f1f76b65fc1c, 0x7ace9609a780c6dc, + 0x4b62ba7528b34440, 0xba37cf920321a2ec, 0xdab82152af4d36ec, 0x359da66c3e405aa0, 0x32133b6e7e57f6b4, 0xfb739dd61168c5ee, 0xfbfc045b30bf74a2, 0xc1c2002bb95c9009, + 0xfb0e87292c13de33, 0xe6a1ada23c8a0b87, 0x4a4ad963b5c4b22f, 0xed9800b5e15d4c3f, 0x1d3fd890d8ae7729, 0x46aa7d9d9bae01b2, 0x4f6e3a19e1a8fb67, 0x2b460d0337d72c74, + 0x7be622092baae6c5, 0x8949c3aeda3c2feb, 0xa9d884a9e4704860, 0xfd3dd63e0fd6e075, 0x5de1715bbc8b024c, 0xaebb8f1195f7516c, 0x3bd0bf7a3f4a5378, 0xddd22dd5c8597960, + 0x94e9199dc8d209b4, 0x5de530f34523777b, 0x51ba8ba0b866a17e, 0xfd55a04a1d22b19c, 0xcdb238bd4130d0d6, 0xa06aeb43357757f5, 0xa475cc0cc62d4527, 0x6d0e779b6e6a8758, + 0x713405fae15e9778, 0x0f00a2b27568a6a3, 0x62bd58efbe3090fb, 0xf05cdf4c267eb1b6, 0x5e62d04738221b8e, 0xf5b9900f1295612f, 0xa0e5749d177233cf, 0xc44c5592311f8054, + 0xbd52eb6cdf769fe2, 0xdd0d254454cf2122, 0xb981221ff70b0658, 0x3c36fb55ff496fd5, 0xf430a57f99390967, 0x0954ace551e02989, 0xaafe4ec82b2d9387, 0x6d9fb14548a4f4bc, + 0x8031a9996ef12134, 0xf6416c9d68835bd2, 0xaffdc09d53a51a0c, 0x19ecea50392e51e3, 0x34a13752a3b17634, 0xee74fe197f0a21c7, 0x428f82d78e4fdbf6, 0x43d9a86b4ee32b41, + 0x37bcb35d71d05a42, 0x6f9295c16c0084c8, 0x83be0ff5413d3a04, 0x3cd1cc1bba243b00, 0x9a355c5fe780c65d, 0x96f751125aa49305, 0x4996cbc8f7336602, 0x0c35ae189a910bda, + 0x17aa114cd1e76239, 0x3b9a332aabe8563a, 0xe1275ec7a3241720, 0x7725b43f265d42a2, 0x652de643921dc113, 0x95074114a43d3ba2, 0x6ac46e80d122a80f, 0x1af28df0f5ddb5d8, + 0xc49b4fcafd637609, 0x60812edd2d354b6f, 0x3491bbfbc599c6e0, 0xfc5c0fada9da1453, 0xb9d457569b43643a, 0x70ba805435dffd85, 0x128cc37ce3a2d1e3, 0xa5e7f2845bf10011, + 0x5a9599124872a087, 0x6358b4f5deaff08f, 0x2d11e3e6dc803a0d, 0xe028f2b88218e837, 0x0f71a38a839a4b4b, 0xc92a5c359039daaf, 0xb2cc835b6228f5db, 0x8ae04d563cbc4d7a, + 0x1c1cac7a75e61830, 0xfd2fd5f227d0984a, 0xaa90ea33113594e1, 0xf9e02ffebbe576ff, 0x5ce891014479b80c, 0x605419be299f8523, 0x83202fb7a4ae2a75, 0xf6e64ff96707e5d7, + 0x3ccaf13d7dd066ce, 0x01aac585c5b5e009, 0x1b4aab8014566d6e, 0x11e7198efab59ba3, 0x24a323f70fc7120c, 0x5609b08316141155, 0x98b0a7b806547c85, 0xaca41a2e51149415, + 0xcf751f8bd38bf1f5, 0x58ccdf65c8344efe, 0x6c72df390c015ec8, 0x133f9c9c23306d85, 0x61d1cfe15b558202, 0x6a3c4c3582a5f673, 0x637f9512f4c797a7, 0xd330644463579ff0, + 0xf16e1e34b4ee7ea3, 0x618000e4502dc31c, 0xaa71c457381d0335, 0xf8d920561946d767, 0x9cecf035b94a3d40, 0x3e4545a17b61d5d5, 0x1c3564aa53e6e73f, 0xc2f4bd3857b00d4b, + 0x211858b81239b300, 0x5e4926ac16c86f0a, 0xe83e64adca66d4c2, 0x63f875c830616302, 0xc6d8069d2b091649, 0x92f747c0d271c5eb, 0x39fa58b367129527, 0x4984ea9b3a80ff9d, + 0x354da29136527160, 0x997edad9709c86fc, 0xad497e23b94da9bf, 0x7d12cc94bd4d5b76, 0xcabccf6f82027a0d, 0xed6559dcebfc6c95, 0x2f81892df9e2941b, 0x83c3531b95bc842b, + 0xe48a4ee1f58654e0, 0x05fdbf72d0daa87b, 0x51ad2decf57851ea, 0xd61ba55be8f651a5, 0xceed919f6700c3e6, 0x763257403bff52ef, 0x61af8a4943b1a111, 0xddaf8c619a405fef, + 0xd722bc84759b7dea, 0x35e5a14698bb02c2, 0xadcf17d7252bb6e3, 0xffe831ce375687b0, 0x02a7b4f8dba11145, 0xd4e67ff0a1cc75bd, 0xf6bed864cb3c0f74, 0xe379cc57b232b594, + 0xb6599ef34e3d74df, 0xd06b61e56f72748b, 0x2ad1cf0c57a4d409, 0x98afe437bbe1e3aa, 0x1e21f20f87f1dcfb, 0xaaf3d2c81546a6f4, 0x7d14ff98c8a0d395, 0x3664b61f266003a0, + 0x707b3ab273ddc773, 0xbb486f128f8ecd85, 0x7a396e34185f08f6, 0xa9d40d14282ef537, 0xad0fa6ce1e0d0138, 0x990146e8ced1b2ef, 0xb73509ea936fd5e5, 0x8408168b79b481aa, + 0x9217fc8086230dd9, 0xaf81fa1a7a00519d, 0xd3c65b61ac9d8d7d, 0x3e83ff6d216d466a, 0x6393d00840e8fe0b, 0x5195eff7a58ecd18, 0x7b7aabcecde2f2bb, 0x1553aee7976dbbb9, + 0x5d7f749ca175d496, 0x6292f95e5d333f51, 0xffe7f74bb8baf5a7, 0xe9649e0679728c39, 0xa937ccfa06522d38, 0xa7495d7e37c3a928, 0x974158e812ddc092, 0x9a6e70c82ca0b636, + 0x4ba73f678b2d9ba1, 0x752ba57f558e6a5d, 0x9586e2990a7af7b4, 0xa486d8ada4ae89fd, 0x15ba224f45406dcb, 0x5854cc00ca213240, 0x12cd7a5d7053add0, 0x960b6b398a21e899, + 0xac81ded4ec6e91d1, 0xe148de8034d93ae0, 0x3084579bb0d44847, 0xdb718742421f4cc0, 0x7358c2d19a2d549a, 0x929c1c9f9de2d932, 0x269b4d558077ce0b, 0x25fcf5912e113dc7, + 0x04cc755f9b71f92b, 0x54069e1f886a4974, 0x5789c6348dc58a5a, 0x1dd27d9819361398, 0x7a2c2390a9dead06, 0x836b38bd06ad26e8, 0x735114cacf0abb97, 0x4ecfb2f5999e82c0, + 0x85cd7efe9da98029, 0x88e472a38d18b4ce, 0x6e0a3ee3d8777812, 0xa05e44ebb1425ce7, 0xeb884cca4ee53297, 0x67a0f982cb5689e9, 0x84fee0ff278b4fa9, 0xa002601e44d5e266, + 0x95fa98bbdae12807, 0x118c212dbb88133f, 0x9ede913100051a91, 0xd354ec4f9b29f406, 0x032ab62fc51a4ed6, 0xbfa91cfd68c85311, 0xfb98f0ef27647507, 0x5e418f8926b631ad, + 0xc17e3e4fee8c4e5a, 0xc221a1b7acf82d68, 0x67bc9540ebff48f4, 0x390b760628e7982d, 0x0d9a4b18c65ca2ac, 0xe27166e392c64490, 0x081ae367a842acde, 0xa041f47bfe8bde53, + 0x4992b5f7f17e54af, 0x99c4a493193d843c, 0x932846bd07cfbaba, 0x1de956fd8e865a43, 0xeba2f84cbff126af, 0xfc5a5703ac806638, 0x47cbc2aece2dfa99, 0x20cbbf78bd8d99e2, + 0x22f23b1804c21205, 0x401b1e0887941f00, 0x4421d0c0c7631a72, 0xb7cdbc7b4156fde4, 0x61fce30f2abd51d0, 0xbc70fa9f22178665, 0x94516d4d06878320, 0xfb4a042f53e53e96, + 0x34e40b1d511804ac, 0x22f37391e01602d1, 0xc280b1aa78edf92d, 0x0efbce19d6a90f10, 0x2bd9185734d40dcc, 0x213d47ac1e778360, 0xc63af769b6d25114, 0x13232c903e39fab3, + 0xb6757d5b86fd514f, 0x1a6dd98096301f47, 0x18bab6a726908647, 0x05d536ca761feda8, 0x15bff4d2b834d102, 0x0ddc2d840252dd3a, 0x766542ad05502aff, 0x109015445ce703d5, + 0xae20cb8c3d9dfea0, 0x46c095b0284fdcde, 0x2aec0ae73dbf67c3, 0x85bd72390c54277b, 0x85d589367f593a03, 0x8c18f9bb056fff2e, 0xfa2e3c913319abe9, 0x9ff6e4cd79254ae9, + 0x03fc24efd2f3d4b4, 0xb2706372e82111fb, 0x097721ba480b1e14, 0x9e06c158cd3746a9, 0x683ec04d3612e0bb, 0xed3a15599cbe3da5, 0x807d052bd2d5260c, 0xdd923767b4122b7b, + 0xd186423ef1afb4c9, 0x22ac6c53b4c862e1, 0x13da7b1fca53e5df, 0xdd5251565fab22e4, 0xa1197271cface62f, 0xc877adf578cd19a2, 0xee960066597841bd, 0x366359a40c773e2d, + 0xaeabb0a3600f13fd, 0xabebe74e161a2d18, 0xd71b9e26fe2b124d, 0xc4662e6e1f313619, 0xfe173a50c65e8caf, 0x1bec45186302f028, 0xc075ff623f3bb554, 0x4323d08715ed7717, + 0xbb776e2356075217, 0x1de047b5503e9641, 0x2e1bae289a76bdd7, 0xa757dc4e78636ced, 0x1095069123a4d1f9, 0x3f14e9b797008cda, 0xec63848d50b81ff9, 0xaf3b5cad36a95559, + 0x233f53e5cf01a158, 0x5c8d2abb26b8dcce, 0x6d7537e21ef21ad0, 0x3c97225a9782d11a, 0xa6d3757ad819677a, 0xbb1692af9785433d, 0xd185a54d16cc6631, 0x39a85ac7b47d54d7, + 0xb1a3cc96aa01e9b6, 0x8e7379d626c41f79, 0xde4e39bf11f63063, 0x3583d9a70f56bdd6, 0x4a41104b4edc1f13, 0xb32372a1e2403d80, 0x24f4942ad83baa34, 0x851fed6fc80a5dab, + 0xcf66b12331d0de29, 0xd29c8987a3759f4f, 0xb724eca99bd71bd8, 0x998eed25e5462fd7, 0x18cc0667b23ed309, 0xa1678d75c0f9970e, 0x0e94c4407c882ebc, 0xaff49c696b108ff0, + 0x8b85dc03cf67af83, 0xc3b8971a2c053ba2, 0x51b58872e31237dd, 0x270d8a4bdac2c029, 0x592315a7ffdee7ab, 0x6f9616538e5248cb, 0xd3852c3c412ced71, 0x627199cb4cea1797, + 0xcce13b89571aae9a, 0x6d89ba4fb0251209, 0x1c9f50ab6c243e6b, 0x8aa0b93b2dc1383c, 0x7f548b6e1f79e9ab, 0x0cebfb32a3be244f, 0x017d1af1793fd3cd, 0x00ff6670e1a38c31, + 0x36eed14d0e34adc7, 0x3abe441ae4f2a164, 0xb72d2b9e2fb7d8d3, 0x9da2accc7a9055af, 0x97d125518e51fa97, 0x99c34b9a44826d1f, 0x4f4076a28ddf9638, 0xf9c53f64cc369d29, + 0x511e0048328995c1, 0xa88a11c39be88ceb, 0x2cf0f489fdd207e5, 0x9340574aef831f56, 0x804be4f3f31293ea, 0xbb4faf64c2a79175, 0x7e1b92775f22058c, 0x64ddc9fad2caaf6a, + 0x0cc102dd78d54fcb, 0x75420b65bd9076d6, 0x43ad0f0faf4e6657, 0x7b7be9498e27286c, 0x28ebea8ca428e47f, 0xb8261eee41c26b60, 0xfb9699617411b1bf, 0xb2f5a238c8e024f6, + 0x7e6243e5c35f8bd3, 0x9d8a370c1d4933d7, 0xf90035f232f83b9d, 0xde869941089e4792, 0xbb56c69fc5e94c5d, 0x3c20a31cb2acfee3, 0xec681c5669d1aed4, 0x35f813bbbd63efc8, + 0x230bf3de5360fa81, 0x019ca9307351b1ea, 0x89483d5f294ad0d1, 0x2d26d5c3523a7bb0, 0xf448b3a734829026, 0xea966ac84c0d84a0, 0xbbc75b0df9cb45b3, 0x223fc92dd877705e, + 0x82116ddf8aa5f946, 0xd833740e0435e67f, 0x3dd62d9029b2c9b5, 0x9d586c02e7d84980, 0x053549bc36234aa6, 0xb714a37694615d34, 0x310fe9eeb979f658, 0x49195c1ebd4390dd, + 0xf8eca25389e4ad62, 0x3c0aec86657896d5, 0xb4ff852a39a579ed, 0x746e85d2c5b681b8, 0xa79919f1fed354ee, 0x3b5af8c711d7552e, 0x2ad734a81d085256, 0xace41048241012e7, + 0x136b210fcacc5cba, 0x9030ac05d3bc5ef7, 0xae4581e0662ea88a, 0x9dab74fde9f5e395, 0x97c99675e85ca95b, 0xa6daedb7fba8027a, 0x627efe55a1a9d222, 0xa1ca5bf7d9bdb3b2, + 0x7f9a4f4ff38af6a5, 0xe6daaa3132c047e9, 0x8ed319a4c49017d8, 0xdecec69b23dde41c, 0x6252770bd96b69b8, 0x57a7550df92a1734, 0xa515e7cc2adc773d, 0x4a0275ace8116020, + 0x8d457d4f899101da, 0xab405c20ee2cc2e7, 0x3dc8c539033cc8f8, 0x1722b2c04c0bdb46, 0xa5e9648b2dacd730, 0x7034710480a5bd9a, 0x7eac55fe42fbd17d, 0x09289386d2f4082b, + 0xd1a2f0078ce8def6, 0x1242812623174229, 0x08599f664d91c228, 0xc81c406a7396224e, 0xd509938218066269, 0xd2343389470438bf, 0x3447fb9f941dae35, 0x004de4a9a48ac636, + 0x27ca90f4689c2301, 0x2f3412defbbc0ce5, 0x2ee5bb659869f6c3, 0x15261632db5911f7, 0x4199cac2a1336353, 0xebf5478d0e80e1e5, 0x48e4fa2e689db485, 0x9f8fc1c1df2169c7, + 0x58acc70991dedf76, 0x32bd6dd6df76e594, 0xb1294d9a558addef, 0x939f07081590bd58, 0xe7353289595edd46, 0x6843a58ece448307, 0xa4f54869bbaa00e0, 0x3b74ece02c301fda, + 0xe5c428dbe2f92851, 0xa968e8cd8720a09a, 0x04200b07e3772957, 0xf5ea6a41259fe96b, 0x51ba8890646974d1, 0x23a5b771eb9ef59a, 0x8ce5a677e27e30fa, 0xcd275c9060dad20b, + 0x3db013fabfb3e7f0, 0x05285a98f8dcb9df, 0xfa1f29b103bbb7ef, 0x99b296a1cf43bdea, 0xb4a6f3c0a0b38b3d, 0xaeb12c1aeb5f28d8, 0xae2f1f03eb3e3968, 0x9693b9a888df1b69, + 0xbec2bac7d73e3d13, 0x820cdad7cbb99d6b, 0xfe541ea866e19a24, 0xf8e2001b77881b99, 0x4442c8e030e9d71f, 0x3370b7879f9014e3, 0xb37106c5ed768dff, 0xf5f96b4753b52deb, + 0xeb5b72aa23740779, 0x3c02fd793a6a8c6a, 0xbfb37fd699f63b3d, 0x637caaa95593d047, 0xcc3db0ced7526e79, 0xda0ba925cfaab89c, 0x0a1e599f26764a93, 0x98619f3e4d9ae02b, + 0x9cfce1cf38a28a84, 0x49e24fd3eeb4444f, 0xc55ba9775274a5d1, 0x4039064d18391462, 0x49bad4dba89b74f5, 0x87a4287d22a51523, 0x08007c717cdbd135, 0xfde0ad0c0dc31b17, + 0xfca05d8e9d566c4a, 0xe1c22849a715f865, 0x4f77083d9194bd32, 0x04de5434dc8aa50a, 0x8786c84405db498d, 0x451cf2e8867c0994, 0xf6277144136903e6, 0x3d442f97db571722, + 0x14afeca0645cfaa3, 0x1ca827f4190b6464, 0x9b1a7cb30ee81922, 0xdedbbecf9c1f0335, 0x7f4eb403f969fea2, 0x5ac4f8a651f1348e, 0x003fc5816243b999, 0xe5fe41ff42ee5925, + 0x973631b960509287, 0x06a13b8162813286, 0x9f9f8709acd52ff3, 0x5c11e094abaece8b, 0x354a7913bd03c8a2, 0x2eafde865751f313, 0x0b8712a8ef75ec69, 0xe848590e2df8c405, + 0x60770245efcbc022, 0x218656367a1d7070, 0xf44c069e7f97795e, 0x72b0541de7a5879c, 0x08358548d77ac787, 0x92e2c32dc055d4f8, 0x4cc1abe176a5d932, 0x9ec9aab004d3ff13, + 0x0ee5fd1c3b8aec79, 0x5d8f935675f05c32, 0x68ff2e62e4518e70, 0x501f9f82e0fca152, 0x842603f19c33c874, 0xc735950dc7e2f996, 0x8c1d99be490e3597, 0x8e42d0e66230fe93, + 0xae329aa1564a80e9, 0x5649e17791c1ef21, 0xd02fb4de5056b33c, 0xaf53eb7e9c69160f, 0x526587c48aeb958b, 0xe5bd7f689e8f1d01, 0xfa7c125443e9cf4b, 0xda376c156aa7605a, + 0x7ec566537c0424d6, 0x8c1a06af932c661f, 0xcd9125069014bc3c, 0xee08acb4bbfc0cee, 0xe6501cae883efb79, 0xa6f190b1ce1a8394, 0x2c8f90c4a264b718, 0x34a813d4c676a289, + 0xd9ac28124c66cdb9, 0xa84842ddf899fee5, 0xd6f4dfb2165b1a4a, 0xdd9d2eb71a17b11b, 0xcd78677ebb392b2d, 0xec292883c27357c7, 0xbce91e11f9830d92, 0x7aa8b68435489adb, + 0x54eb584bcdfea954, 0xb8dd62f763e7e58e, 0xa438f6df8db982d8, 0xca9441de3b544abb, 0x1deda190c70f9a4a, 0x445bb6ced6490995, 0x76bf6a3ded7b314d, 0x8a66f016dfdfab07, + 0x64a21901e2bbdbac, 0x191ff6bb807fc7f4, 0x86b368995e99d41e, 0x417e6535be219210, 0x1491867633f53559, 0x0cecb02863af988a, 0x8e4e386e752beffa, 0x4ba58fed077cf4a5, + 0xd777631cb7cc0ef3, 0xe11c0ccd18c90c4f, 0x9343426a5050f38e, 0x55efc291307ee56d, 0x0fbcae5d59aeb627, 0x288b467aa5bdfbca, 0xc0a392953f680019, 0x48916fc91ba84c06, + 0x4a8b4836ba342ed5, 0x03142a9ea4c0e59d, 0xcf342a86d47380b3, 0x3454da8dc9c8791a, 0x0260f14f96803fa0, 0x973bbe79a5f164a8, 0x49edc10d9edee956, 0x0cf5cacd8fccfba6, + 0xdb4f8f51bb534076, 0x470b7f9d70824b90, 0x1a2e4d589fbe3c75, 0xcbc03b148e363146, 0x99ee702383e08652, 0x7d3a7bc2b1d17942, 0xe29dbdde2a789780, 0xd05be133837d8a4a, + 0xf2657c5783404faa, 0xe4c60bef204ebf83, 0x8af681c946077603, 0xa4c30856371c7ea4, 0xfd8491493be53498, 0x65b4bb5c0b432d37, 0xf36cf84d1e69c2fc, 0x72540952b560db4c, + 0x926fe399b48b06bd, 0xbe7bba0600877983, 0x78756a5857287bcf, 0x39344c4f631fab92, 0x8938f0d75f41bb00, 0x62950eb07231d85c, 0x151250c44835e534, 0xeaa6153d366040b6, + 0x0399ff3ab9d2029b, 0x4f9291ac66bea780, 0x5538b8774466b317, 0x104a472bddd01ce6, 0xbb530a2727a7c317, 0x12a408915c974a92, 0x02d8e5447e228765, 0xbb6c944b06c2be01, + 0x860518c2841ca8a0, 0x68edab4683438cfd, 0xd5764f712a25913f, 0x14a6ec6cfa7c3115, 0x6f0cc123ec798547, 0x19ae22cc367c885f, 0xd7be6d5f449e5951, 0x8555f4f8fd21152f, + 0xf3335605e1495f41, 0xb2ea3183d8e360a9, 0xb6221434c5c90c63, 0xdf215d9c2e93390e, 0x98519ef2b0af8143, 0x06044c2d81e1edf6, 0x645f2661d1fc17e2, 0x469a5d2269c3b05f, + 0xca70212744447558, 0x07a4eb3b4b8e8cfd, 0xef200622675d49f9, 0xd7024c3ac1a6d90c, 0x5c54fcec35596bf2, 0x030e135fcb8673a0, 0x9f1cc6537857af20, 0xbf75a9960af6a424, + 0xa1ce52907049fd5f, 0xb85d9f1d69b9e757, 0x85beffbfcc396269, 0x0bdf4af30f73131a, 0x74e5c58ffc16a8fe, 0xc3cc87ed72fe0e64, 0x604c1bc18d443cba, 0x9a1b8fd3634f1d41, + 0xa33795d2516fad6e, 0x99ac9eb1c2ada062, 0xa2713d9be0bcb94d, 0xfd2f6b2989fdf4ea, 0x55e33b2805a13f58, 0x2c7bd9290ee9b966, 0x81fd6f83134014ff, 0x179f8894deefcc6f, + 0xc61c8e56d5fdb3c0, 0xa4e5343bc6afdde1, 0x36ad5e9310f6d4eb, 0xd5fd90a79e27cc78, 0xd8ccd606e4d48e8d, 0x25f66a9cc989fed6, 0x3d0402457fc4bae1, 0x612733dcf3d0d07b, + 0xe38fd4832db05d6c, 0x8e2809b7ea934954, 0x52004f18865f4734, 0xbb8ee10a8dd754c1, 0x0fd0437b265a01b3, 0xad6498e5df9586e8, 0x8e143ecbe7db3bba, 0x17331ca3a86566a0, + 0x50cf16807d23b56d, 0x7c52f40e61c17c15, 0x70aff594054aca7d, 0xa9005fada5801d62, 0xc2c62f1740a8a26d, 0xccccb11f991fb387, 0x2f38ade83ab14eac, 0x33a947c235f4d753, + 0xa5625e617031d563, 0x4f964fabfa8b3b58, 0x84b4e9eaead9b63c, 0x6df29966734e4146, 0x11dd7ce026d0c29a, 0x9963e5fa15f8d521, 0x1e20c4ade063847d, 0xaed43f08f72a9080, + 0x3dd7ce36cef85b37, 0x78e5e46f7874aed5, 0x5ded630f68dab2fa, 0x9e41471fb56fd63b, 0xda4d8c5b0c650d1c, 0x9939dd39cf15b48c, 0xc4caf8da2e6475b3, 0x783e1a913f0b79cb, + 0xd6131558db68427a, 0x544774b505054d4c, 0xa30cadbbabc33d9d, 0xa8d250afca0b7a81, 0x36f07dfcde5fd8d0, 0xd25bb4feb8a0b5d6, 0x52cfde1125affcca, 0x95876763d947df39, + 0x916a38f31aa8c326, 0x7fbdbbe0054a44be, 0xf26e36f7c5eb7a26, 0xdb7ba35f9caacbbd, 0x8de921ce9854cb9c, 0x83c48c8ba5f3ac18, 0xea86332217508916, 0x89d816e3efccd171, + 0xea8314449612a664, 0xf3afd7b04e3e9dcd, 0x0265cf8252d368bc, 0xd9b9f2c5b09ab82e, 0x1be9d93315e7e8e8, 0x4e263044ea592f12, 0x4390a239830f4ecf, 0x55c249d481ef6a4c, + 0xb263e1e7553222ef, 0x11ea971a5642c42c, 0x7894d600bebd1abb, 0xdd6fb6941031338f, 0x29568a2c0c94d52d, 0x01315555449edeb9, 0xb8a03366e13184df, 0xaafa5d4593a6277d, + 0x066b638835960be2, 0xf5215adaeb2e42da, 0x020ebe86ab18e836, 0x1999e5c85d17cc7c, 0xf2d3af28af6c1437, 0x168c7ecd2b437f59, 0xeb96f37a2f474f63, 0x9de6b71e12e31189 +}; +#if defined(HITLS_SIXTY_FOUR_BITS) +static const BN_UINT g_one[P256_SIZE] = {1, 0, 0, 0}; +static const BN_UINT g_sm2Poly[P256_SIZE] = { + 0xffffffffffffffff, 0xffffffff00000000, + 0xffffffffffffffff, 0xfffffffeffffffff +}; +static const BN_UINT g_poly2[P256_SIZE] __attribute__((aligned(32))) = { + 0x8000000000000000, 0xffffffff80000000, + 0xffffffffffffffff, 0x7fffffff7fffffff +}; +#elif defined(HITLS_THIRTY_TWO_BITS) +static const BN_UINT g_one[P256_SIZE] = {1, 0, 0, 0, 0, 0, 0, 0}; +static const BN_UINT g_sm2Poly[P256_SIZE] = { + 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe +}; +static const BN_UINT g_poly2[P256_SIZE] __attribute__((aligned(16))) = { + 0x00000000, 0x80000000, 0x80000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0x7fffffff, 0x7fffffff +}; +#else +#error BN_UINT MUST be 4 or 8 +#endif + +static uint32_t IsZero(BN_UINT a) +{ + a |= (0 - a); + a = ~a; + a >>= (sizeof(BN_UINT) * 8 - 1); + return a; +} + +static uint32_t IsZeros(const BN_UINT *a) +{ + BN_UINT res; + res = a[0] ^ 0; + for (uint32_t i = 1; i < P256_SIZE; i++) { + res |= a[i] ^ 0; + } + return IsZero(res); +} + +static int IsEqual(const BN_UINT *a, const BN_UINT *b) +{ + BN_UINT res; + + res = a[0] ^ b[0]; + for (uint32_t i = 1; i < P256_SIZE; i++) { + res |= a[i] ^ b[i]; + } + return IsZero(res); +} + +static int IsGreater(const BN_UINT *a, const BN_UINT *b) +{ + int i; + + for (i = P256_SIZE - 1; i >= 0; --i) { + if (a[i] > b[i]) + return 1; + if (a[i] < b[i]) + return -1; + } + + return 0; +} + +static int ECP_Sm2PointEqual(const P256_Point *a, const P256_Point *b) +{ + return IsEqual(a->x.value, b->x.value) && IsEqual(a->y.value, b->y.value) && IsEqual(a->z.value, b->z.value); +} + + /* Montgomery modular inverse: r = a^-1 mod p/n, where n = ord(p) */ +static void ECP_Sm2ModInv(BN_UINT *r, const BN_UINT *a) +{ + BN_UINT u[P256_SIZE] __attribute__((aligned(32))); + BN_UINT v[P256_SIZE] __attribute__((aligned(32))); + BN_UINT x1[P256_SIZE] __attribute__((aligned(32))) = {1, 0, 0, 0}; + BN_UINT x2[P256_SIZE] __attribute__((aligned(32))) = {0}; + if (IsZeros(a)) { + return; + } + (void)memcpy_s(u, sizeof(u), a, sizeof(u)); + (void)memcpy_s(v, sizeof(v), g_sm2Poly, sizeof(v)); + while (!IsEqual(u, g_one) && !IsEqual(v, g_one)) { + while (!(u[0] & 1)) { + ECP_Sm2BnRshift1(u); + if (!(x1[0] & 1)) { + ECP_Sm2BnRshift1(x1); + } else { + ECP_Sm2BnRshift1(x1); + ECP_Sm2Add(x1, x1, g_poly2); + } + } + while (!(v[0] & 1)) { + ECP_Sm2BnRshift1(v); + if (!(x2[0] & 1)) { + ECP_Sm2BnRshift1(x2); + } else { + ECP_Sm2BnRshift1(x2); + ECP_Sm2Add(x2, x2, g_poly2); + } + } + if (IsGreater(u, v) == 1) { + ECP_Sm2Sub(u, u, v); + ECP_Sm2Sub(x1, x1, x2); + } else { + ECP_Sm2Sub(v, v, u); + ECP_Sm2Sub(x2, x2, x1); + } + } + if (IsEqual(u, g_one)) { + (void)memcpy_s(r, sizeof(x1), x1, sizeof(x1)); + } else { + (void)memcpy_s(r, sizeof(x2), x2, sizeof(x2)); + } +} + +static int32_t ECP_Sm2Point2Array(P256_Point *r, const ECC_Point *p) +{ + uint32_t len = P256_SIZE; + int ret = CRYPT_SUCCESS; +#if defined(HITLS_SIXTY_FOUR_BITS) + GOTO_ERR_IF_EX(BN_Bn2U64Array(p->x, (BN_UINT *)&r->x.value, &len), ret); + GOTO_ERR_IF_EX(BN_Bn2U64Array(p->y, (BN_UINT *)&r->y.value, &len), ret); + GOTO_ERR_IF_EX(BN_Bn2U64Array(p->z, (BN_UINT *)&r->z.value, &len), ret); +#else + GOTO_ERR_IF_EX(BN_BN2Array(p->x, (BN_UINT *)&r->x.value, len), ret); + GOTO_ERR_IF_EX(BN_BN2Array(p->y, (BN_UINT *)&r->y.value, len), ret); + GOTO_ERR_IF_EX(BN_BN2Array(p->z, (BN_UINT *)&r->z.value, len), ret); +#endif +ERR: + return ret; +} + +static int32_t ECP_Sm2Array2Point(ECC_Point *r, const P256_Point *a) +{ + uint32_t len = P256_SIZE; + int ret = CRYPT_SUCCESS; +#if defined(HITLS_SIXTY_FOUR_BITS) + GOTO_ERR_IF_EX(BN_U64Array2Bn(r->x, (const BN_UINT *)a->x.value, len), ret); + GOTO_ERR_IF_EX(BN_U64Array2Bn(r->y, (const BN_UINT *)a->y.value, len), ret); + GOTO_ERR_IF_EX(BN_U64Array2Bn(r->z, (const BN_UINT *)a->z.value, len), ret); +#else + GOTO_ERR_IF_EX(BN_Array2BN(r->x, (const BN_UINT *)a->x.value, len), ret); + GOTO_ERR_IF_EX(BN_Array2BN(r->y, (const BN_UINT *)a->y.value, len), ret); + GOTO_ERR_IF_EX(BN_Array2BN(r->z, (const BN_UINT *)a->z.value, len), ret); +#endif +ERR: + return ret; +} + +int32_t ECP_Sm2GetAffine(P256_AffinePoint *r, const P256_Point *a) +{ + BN_UINT zInv3[P256_SIZE] __attribute__((aligned(32))) = {0}; + BN_UINT zInv2[P256_SIZE] __attribute__((aligned(32))) = {0}; + if (IsZeros(a->z.value)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (IsEqual(a->z.value, g_one)) { + (void)memcpy_s(r->x.value, sizeof(r->x.value), a->x.value, sizeof(r->x.value)); + (void)memcpy_s(r->y.value, sizeof(r->y.value), a->y.value, sizeof(r->x.value)); + return CRYPT_SUCCESS; + } + + ECP_Sm2ModInv(zInv3, a->z.value); + ECP_Sm2Sqr(zInv2, zInv3); + ECP_Sm2Mul(r->x.value, a->x.value, zInv2); + ECP_Sm2Mul(zInv3, zInv3, zInv2); + ECP_Sm2Mul(r->y.value, a->y.value, zInv3); + + return CRYPT_SUCCESS; +} + +int32_t ECP_Sm2Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + if (r == NULL || a == NULL || para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != CRYPT_ECC_SM2 || r->id != CRYPT_ECC_SM2 || a->id != CRYPT_ECC_SM2) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + + P256_Point temp = {0}; + P256_AffinePoint rTemp = {0}; + int32_t ret = CRYPT_SUCCESS; + + GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&temp, a), ret); + GOTO_ERR_IF_EX(ECP_Sm2GetAffine(&rTemp, &temp), ret); + GOTO_ERR_IF_EX(BN_Array2BN(r->x, rTemp.x.value, P256_SIZE), ret); + GOTO_ERR_IF_EX(BN_Array2BN(r->y, rTemp.y.value, P256_SIZE), ret); + GOTO_ERR_IF_EX(BN_SetLimb(r->z, 1), ret); + +ERR: + return ret; +} + +void ECP_Sm2PointDbl(P256_Point *r, const P256_Point *a) +{ + unsigned int i; + BN_UINT T1[P256_SIZE] __attribute__((aligned(32))); + BN_UINT T2[P256_SIZE] __attribute__((aligned(32))); + BN_UINT T3[P256_SIZE] __attribute__((aligned(32))); + + /* zero-check a->z.value */ + if (IsZeros(a->z.value)) { + for (i = 0; i < P256_SIZE; ++i) + r->z.value[i] = 0; + + return; + } + + /* 4Mul + 4Sqr */ + ECP_Sm2Sqr(T1, a->z.value); /* Z1^2 */ + ECP_Sm2Sub(T2, a->x.value, T1); /* X1 - Z1^2 */ + ECP_Sm2Add(T1, a->x.value, T1); /* X1 + Z1^2 */ + ECP_Sm2Mul(T2, T2, T1); /* X1^2 - Z1^4 */ + ECP_Sm2MulBy3(T2, T2); /* T2 = 3*X1^2 - 3*Z1^4 -> lambda_1 */ + ECP_Sm2Add(r->y.value, a->y.value, a->y.value); /* 2*Y1 */ + ECP_Sm2Mul(r->z.value, r->y.value, a->z.value); /* Z3 = 2*Y1*Z1 */ + ECP_Sm2Sqr(r->y.value, r->y.value); /* 4*Y1^2 */ + ECP_Sm2Mul(T3, r->y.value, a->x.value); /* T3 = 4*X1*Y1^2 -> lambda_2 */ + ECP_Sm2Sqr(r->y.value, r->y.value); + ECP_Sm2DivBy2(r->y.value, r->y.value); /* Y3 = 8*Y1^4 -> lambda_3 */ + ECP_Sm2Sqr(r->x.value, T2); + ECP_Sm2Add(T1, T3, T3); + ECP_Sm2Sub(r->x.value, r->x.value, T1); /* X3 = lambda_1^2 - 2*lambda_2 */ + ECP_Sm2Sub(T1, T3, r->x.value); /* T1 = lambda_2 - X3 */ + ECP_Sm2Mul(T1, T1, T2); + ECP_Sm2Sub(r->y.value, T1, r->y.value); /* Y3 = lambda_1*T1 - lambda_3 */ +} + +int32_t ECP_Sm2PointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + (void)para; + P256_Point re = {0}; + P256_Point ina = {0}; + int32_t ret = CRYPT_SUCCESS; + GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&ina, a), ret); + ECP_Sm2PointDbl(&re, &ina); + GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &re), ret); +ERR: + return ret; +} + +static void ECP_Sm2PointAddJacob(P256_Point *r, const P256_Point *a, const P256_Point *b) +{ + unsigned int i; + BN_UINT T1[P256_SIZE] __attribute__((aligned(32))) = {0}; + BN_UINT T2[P256_SIZE] __attribute__((aligned(32))) = {0}; + BN_UINT T3[P256_SIZE] __attribute__((aligned(32))) = {0}; + + /* zero-check a | b ->z.value */ + if (IsZeros(a->z.value)) { + for (i = 0; i < P256_SIZE; ++i) { + r->x.value[i] = b->x.value[i]; + r->y.value[i] = b->y.value[i]; + r->z.value[i] = b->z.value[i]; + } + return; + } else if (IsZeros(b->z.value)) { + for (i = 0; i < P256_SIZE; ++i) { + r->x.value[i] = a->x.value[i]; + r->y.value[i] = a->y.value[i]; + r->z.value[i] = a->z.value[i]; + } + return; + } else if (ECP_Sm2PointEqual(a, b)) { + ECP_Sm2PointDbl(r, a); + return; + } + + /* 12Mul + 4Sqr */ + ECP_Sm2Sqr(T1, b->z.value); /* Z2^2 */ + ECP_Sm2Mul(T2, T1, b->z.value); /* Z2^3 */ + ECP_Sm2Mul(T1, T1, a->x.value); /* T1 = X1*Z2^2 -> lambda_1 */ + ECP_Sm2Mul(T2, T2, a->y.value); /* T2 = Y1*Z2^3 -> lambda_4 */ + ECP_Sm2Sqr(T3, a->z.value); /* T3 = Z1^2 */ + ECP_Sm2Mul(r->y.value, a->z.value, b->y.value); /* Y2*Z1 */ + ECP_Sm2Mul(r->z.value, a->z.value, b->z.value); /* Z1*Z2 */ + ECP_Sm2Mul(r->y.value, T3, r->y.value); /* Y2*Z1^3 -> lambda_5 */ + ECP_Sm2Mul(r->x.value, T3, b->x.value); /* X2*Z1^2 -> lambda_2 */ + ECP_Sm2Sub(T1, T1, r->x.value); /* T1 = X1*Z2^2 - X2*Z1^2 -> lambda_3 */ + ECP_Sm2Mul(r->z.value, T1, r->z.value); /* Z3 = Z1*Z2*lambda_3 */ + ECP_Sm2Sub(T2, T2, r->y.value); /* T2 = Y1*Z2^3 - Y2*Z1^3 -> lambda_6 */ + ECP_Sm2Sqr(T3, T1); /* T3 = lambda_3^2 */ + ECP_Sm2Mul(T1, T1, T3); /* T1 = lambda_3^3 */ + ECP_Sm2Mul(T3, T3, r->x.value); /* T3 = lambda_2*lambda_3^2 */ + ECP_Sm2Sqr(r->x.value, T2); /* lambda_6^2 */ + ECP_Sm2Sub(r->x.value, r->x.value, T3); + ECP_Sm2Sub(r->x.value, r->x.value, T3); + ECP_Sm2Sub(r->x.value, r->x.value, T1); /* X3 = lambda_6^2 - 2*lambda_2*lambda_3^2 - lambda_3^3 */ + ECP_Sm2Sub(T3, T3, r->x.value); + ECP_Sm2Mul(T3, T2, T3); /* T3 = lambda_6 * (lambda_2*lambda_3^2 - X3) */ + ECP_Sm2Mul(T1, T1, r->y.value); /* T1 = lambda_3^3*lambda_5 */ + ECP_Sm2Sub(r->y.value, T3, T1); /* Y3 = T3 - T1 */ +} + +void ECP_Sm2PointAddAffine(P256_Point *r, const P256_Point *a, const P256_AffinePoint *b) +{ + unsigned int i; + BN_UINT T1[P256_SIZE] __attribute__((aligned(32))) = {0}; + BN_UINT T2[P256_SIZE] __attribute__((aligned(32))) = {0}; + BN_UINT T3[P256_SIZE] __attribute__((aligned(32))) = {0}; + BN_UINT T4[P256_SIZE] __attribute__((aligned(32))) = {0}; + + /* zero-check a->z.value */ + if (IsZeros(a->z.value)) { + for (i = 0; i < P256_SIZE; ++i) { + r->x.value[i] = b->x.value[i]; + r->y.value[i] = b->y.value[i]; + r->z.value[i] = 0; + } + r->z.value[0] = 1; + + return; + } + + ECP_Sm2Sqr(T1, a->z.value); + ECP_Sm2Mul(T2, T1, a->z.value); + ECP_Sm2Mul(T1, T1, b->x.value); + ECP_Sm2Mul(T2, T2, b->y.value); + ECP_Sm2Sub(T1, T1, a->x.value); + ECP_Sm2Sub(T2, T2, a->y.value); + + /* zero-check T1, T2 */ + if (IsZeros(T1)) { + if (IsZeros(T2)) { + P256_Point p; + for (i = 0; i < P256_SIZE; ++i) { + p.x.value[i] = b->x.value[i]; + p.y.value[i] = b->y.value[i]; + p.z.value[i] = 0; + } + p.z.value[0] = 1; + ECP_Sm2PointDbl(r, &p); + } else { + for (i = 0; i < P256_SIZE; ++i) + r->z.value[i] = 0; + } + + return; + } + + ECP_Sm2Mul(r->z.value, a->z.value, T1); + ECP_Sm2Sqr(T3, T1); + ECP_Sm2Mul(T4, T3, T1); + ECP_Sm2Mul(T3, T3, a->x.value); + ECP_Sm2Add(T1, T3, T3); + ECP_Sm2Sqr(r->x.value, T2); + ECP_Sm2Sub(r->x.value, r->x.value, T1); + ECP_Sm2Sub(r->x.value, r->x.value, T4); + ECP_Sm2Sub(T3, T3, r->x.value); + ECP_Sm2Mul(T3, T3, T2); + ECP_Sm2Mul(T4, T4, a->y.value); + ECP_Sm2Sub(r->y.value, T3, T4); +} + +// Jacobian add affine +int32_t ECP_Sm2PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b) +{ + if (para == NULL || r == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + P256_Point re = {0}; + P256_Point ina = {0}; + P256_Point inb = {0}; + P256_AffinePoint affb = {0}; + int32_t ret = CRYPT_SUCCESS; + GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&ina, a), ret); + GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&inb, b), ret); + GOTO_ERR_IF_EX(ECP_Sm2GetAffine(&affb, &inb), ret); + ECP_Sm2PointAddAffine(&re, &ina, &affb); + GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &re), ret); +ERR: + return ret; +} + +void ECP_Sm2ScalarMulG(P256_Point *r, const BN_UINT *k) +{ + const BN_UINT *precompute = (BN_UINT *)g_sm2Precompute; + uint32_t index, mask = 0xff; + for (int i = 31; i >= 0; --i) { + /* 'i / 8' is for split i to 4 parts(k is a 4 elements array) + '(8 * (i % 8))' is for the size of k's element is 64bits */ +#if defined(HITLS_SIXTY_FOUR_BITS) + index = (k[i / 8] >> (8 * (i % 8))) & mask; +#else + index = (k[i / 4] >> (8 * (i % 4))) & mask; +#endif + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + if (index) { +#if defined(HITLS_SIXTY_FOUR_BITS) + index = index * 8; // 1 point has 64 bytes, which is 8*8 bytes +#else + index = index * 16; // 1 point has 64 bytes, which is 8*8 bytes +#endif + ECP_Sm2PointAddAffine(r, r, (const P256_AffinePoint *)&precompute[index]); + } + } +} + +int32_t ECP_Sm2WindowedMul(P256_Point *r, const BN_UINT *k, P256_AffinePoint *a) +{ + int i; + unsigned int index, mask = 0x0f; + P256_Point precomputed[16] __attribute__((aligned(64))); + + BSL_SAL_CleanseData(r, sizeof(P256_Point)); + + ECP_Sm2PointAddAffine(&precomputed[1], r, a); + ECP_Sm2PointDbl(&precomputed[2], &precomputed[1]); + ECP_Sm2PointAddAffine(&precomputed[3], &precomputed[2], a); + ECP_Sm2PointDbl(&precomputed[4], &precomputed[2]); + ECP_Sm2PointAddAffine(&precomputed[5], &precomputed[4], a); + ECP_Sm2PointDbl(&precomputed[6], &precomputed[3]); + ECP_Sm2PointAddAffine(&precomputed[7], &precomputed[6], a); + ECP_Sm2PointDbl(&precomputed[8], &precomputed[4]); + ECP_Sm2PointAddAffine(&precomputed[9], &precomputed[8], a); + ECP_Sm2PointDbl(&precomputed[10], &precomputed[5]); + ECP_Sm2PointAddAffine(&precomputed[11], &precomputed[10], a); + ECP_Sm2PointDbl(&precomputed[12], &precomputed[6]); + ECP_Sm2PointAddAffine(&precomputed[13], &precomputed[12], a); + ECP_Sm2PointDbl(&precomputed[14], &precomputed[7]); + ECP_Sm2PointAddAffine(&precomputed[15], &precomputed[14], a); + + for (i = 63; i >= 0; --i) { +#if defined(HITLS_SIXTY_FOUR_BITS) + index = (k[i / 16] >> (4 * (i % 16))) & mask; +#else + index = (k[i / 8] >> (4 * (i % 8))) & mask; +#endif + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + ECP_Sm2PointDbl(r, r); + if (index) + ECP_Sm2PointAddJacob(r, r, &precomputed[index]); + } + return CRYPT_SUCCESS; +} + +int32_t ECP_Sm2PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *scalar, const ECC_Point *pt) +{ + if (para == NULL || r == NULL || scalar == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != CRYPT_ECC_SM2 || r->id != CRYPT_ECC_SM2 || (pt != NULL && (pt->id != CRYPT_ECC_SM2))) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (pt != NULL && BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (BN_IsZero(scalar)) { + BN_Zeroize(r->z); + return CRYPT_SUCCESS; + } + int32_t ret = CRYPT_SUCCESS; + BN_UINT k[P256_SIZE] = {0}; + uint32_t klen = P256_SIZE; + P256_Point re = {0}; + P256_Point sm2Pt = {0}; + P256_AffinePoint sm2Aff = {0}; +#if defined(HITLS_SIXTY_FOUR_BITS) + GOTO_ERR_IF_EX(BN_Bn2U64Array(scalar, k, &klen), ret); +#else + GOTO_ERR_IF_EX(BN_BN2Array(scalar, k, klen), ret); +#endif + if (pt == NULL) { + // calculate k*G + ECP_Sm2ScalarMulG(&re, k); + // P256_Point 2 ECC_Point + GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &re), ret); + } else { + // point 2 affine + GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&sm2Pt, pt), ret); + GOTO_ERR_IF_EX(ECP_Sm2GetAffine(&sm2Aff, &sm2Pt), ret); + GOTO_ERR_IF_EX(ECP_Sm2WindowedMul(&re, k, &sm2Aff), ret); + // P256_Point 2 ECC_Point + GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &re), ret); + } + +ERR: + return ret; +} + +#endif diff --git a/crypto/ecc/src/asm_ecp_sm2.h b/crypto/ecc/src/asm_ecp_sm2.h new file mode 100644 index 00000000..e8068446 --- /dev/null +++ b/crypto/ecc/src/asm_ecp_sm2.h @@ -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 ASM_ECP_SM2_H +#define ASM_ECP_SM2_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_ECC) && defined(HITLS_CRYPTO_SM2) + +#include +#include "crypt_bn.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define P256_BYTES 32 +#define P256_SIZE (P256_BYTES / sizeof(BN_UINT)) + +typedef struct { + BN_UINT value[P256_SIZE]; +} Coord; // Point Coordinates + +typedef struct p256_point { + Coord x; + Coord y; + Coord z; +} P256_Point; + +typedef struct p256_pointaffine { + Coord x; + Coord y; +} P256_AffinePoint; + +typedef P256_AffinePoint ECP256_TableRow[64]; + +/* Right shift: a >> 1 */ +void ECP_Sm2BnRshift1(BN_UINT *a); +/* Finite field operations */ +/* Modular div by 2: r = a/2 mod p */ +void ECP_Sm2DivBy2(BN_UINT *r, const BN_UINT *a); +/* Modular add: r = a+b mod p */ +void ECP_Sm2Add(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); +/* Modular add: r = a+b mod n, where n = ord(p) */ +void ECP_Sm2AddModOrd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); +/* Modular sub: r = a-b mod p */ +void ECP_Sm2Sub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); +/* Modular sub: r = a-b mod n, where n = ord(p) */ +void ECP_Sm2SubModOrd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); +/* Modular mul by 3: r = 3*a mod p */ +void ECP_Sm2MulBy3(BN_UINT *r, const BN_UINT *a); +/* Modular mul: r = a*b mod p */ +void ECP_Sm2Mul(BN_UINT *r, const BN_UINT *a, const BN_UINT *b); +/* Modular sqr: r = a^2 mod p */ +void ECP_Sm2Sqr(BN_UINT *r, const BN_UINT *a); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SM2 + +#endif // ASM_ECP_SM2_H diff --git a/crypto/ecc/src/ecc.c b/crypto/ecc/src/ecc.c new file mode 100644 index 00000000..175135ec --- /dev/null +++ b/crypto/ecc/src/ecc.c @@ -0,0 +1,406 @@ +/* + * 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_ECC + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "ecc_local.h" + +ECC_Point *ECC_NewPoint(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + uint32_t bits = BN_Bits(para->p); + ECC_Point *pt = BSL_SAL_Malloc(sizeof(ECC_Point)); + if (pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + pt->id = para->id; + pt->x = BN_Create(bits); + pt->y = BN_Create(bits); + pt->z = BN_Create(bits); + if (pt->x == NULL || pt->y == NULL || pt->z == NULL) { + ECC_FreePoint(pt); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + return pt; +} + +void ECC_FreePoint(ECC_Point *pt) +{ + if (pt == NULL) { + return; + } + BN_Destroy(pt->x); + BN_Destroy(pt->y); + BN_Destroy(pt->z); + BSL_SAL_FREE(pt); +} + +int32_t ECC_CopyPoint(ECC_Point *dst, const ECC_Point *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (dst->id != src->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + int32_t ret; + GOTO_ERR_IF(BN_Copy(dst->x, src->x), ret); + GOTO_ERR_IF(BN_Copy(dst->y, src->y), ret); + GOTO_ERR_IF(BN_Copy(dst->z, src->z), ret); +ERR: + return ret; +} + +ECC_Point *ECC_DupPoint(const ECC_Point *pt) +{ + if (pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + ECC_Point *newPt = BSL_SAL_Malloc(sizeof(ECC_Point)); + if (newPt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + newPt->id = pt->id; + newPt->x = BN_Dup(pt->x); + newPt->y = BN_Dup(pt->y); + newPt->z = BN_Dup(pt->z); + if (newPt->x == NULL || newPt->y == NULL || newPt->z == NULL) { + ECC_FreePoint(newPt); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + return newPt; +} + +// Convert to Cartesian coordinates +int32_t ECC_GetPoint(const ECC_Para *para, ECC_Point *pt, CRYPT_Data *x, CRYPT_Data *y) +{ + int32_t ret; + uint32_t pBytes; + if (para == NULL || pt == NULL || x == NULL || x->data == NULL || + ((y != NULL) && (y->data == NULL))) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != pt->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + pBytes = BN_Bytes(para->p); + if ((x->len < pBytes) || ((y != NULL) && (y->len < pBytes))) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_BUFF_LEN_NOT_ENOUGH); + return CRYPT_ECC_BUFF_LEN_NOT_ENOUGH; + } + if (BN_IsZero(pt->z)) { // infinity point + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (para->method->point2Affine == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + GOTO_ERR_IF(para->method->point2Affine(para, pt, pt), ret); + GOTO_ERR_IF(BN_Bn2BinFixZero(pt->x, x->data, pBytes), ret); + x->len = pBytes; + if (y != NULL) { + GOTO_ERR_IF(BN_Bn2BinFixZero(pt->y, y->data, pBytes), ret); + y->len = pBytes; + } +ERR: + return ret; +} + +int32_t ECC_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != a->id || para->id != r->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(a->z)) { // infinity point + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (para->method->point2Affine == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + int32_t ret = para->method->point2Affine(para, r, a); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t ECC_GetPointDataX(const ECC_Para *para, ECC_Point *pt, BN_BigNum *x) +{ + int32_t ret; + if (x == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + GOTO_ERR_IF(ECP_PointAtInfinity(para, pt), ret); + if (para->method->point2Affine == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + GOTO_ERR_IF(para->method->point2Affine(para, pt, pt), ret); + GOTO_ERR_IF(BN_Copy(x, pt->x), ret); +ERR: + return ret; +} + +ECC_Point *ECC_GetGFromPara(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + ECC_Point *pt = ECC_NewPoint(para); + if (pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)BN_Copy(pt->x, para->x); + (void)BN_Copy(pt->y, para->y); + (void)BN_SetLimb(pt->z, 1); + return pt; +} + +int32_t ECC_PointMulAdd(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->method->pointMulAdd == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + return para->method->pointMulAdd(para, r, k1, k2, pt); +} + +int32_t ECC_PointMul(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k, const ECC_Point *pt) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->method->pointMul == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + return para->method->pointMul(para, r, k, pt); +} + +int32_t ECC_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b) +{ + // Currently, only prime number curves are supported. Other curves need to be expanded. + return ECP_PointCmp(para, a, b); +} + +ECC_Para *ECC_DupPara(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return ECC_NewPara(para->id); +} + +uint32_t ECC_ParaBits(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return BN_Bits(para->p); +} + +BN_BigNum *ECC_GetParaH(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return BN_Dup(para->h); +} + +BN_BigNum *ECC_GetParaN(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return BN_Dup(para->n); +} + +BN_BigNum *ECC_GetParaA(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return BN_Dup(para->a); +} + +BN_BigNum *ECC_GetParaB(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return BN_Dup(para->b); +} + +BN_BigNum *ECC_GetParaX(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return BN_Dup(para->x); +} + +BN_BigNum *ECC_GetParaY(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + return BN_Dup(para->y); +} + +int32_t ECC_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen, + CRYPT_PKEY_PointFormat format) +{ + // Currently, only prime number curves are supported. Other curves need to be expanded. + return ECP_EncodePoint(para, pt, data, dataLen, format); +} + +int32_t ECC_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen) +{ + // Currently, only prime number curves are supported. Other curves need to be expanded. + return ECP_DecodePoint(para, pt, data, dataLen); +} + +int32_t ECC_PointCheck(const ECC_Point *pt) +{ + if (pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + return CRYPT_SUCCESS; +} + +int32_t ECC_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->method->modOrdInv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + return para->method->modOrdInv(para, r, a); +} + +/** + Prime curve, point addition r = a + b + Calculation formula: + X3 = (Y2*Z1^3-Y1)^2 - (X2*Z1^2-X1)^2 * (X1+X2*Z1^2) + Y3 = (Y2*Z1^3-Y1) * (X1*(X2*Z1^2-X1)^2-X3) - Y1 * (X2*Z1^2-X1)^3 + Z3 = (X2*Z1^2-X1) * Z1 +*/ +int32_t ECC_PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b) +{ + int32_t ret; + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->method->pointAdd == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return CRYPT_ECC_NOT_SUPPORT; + } + ECC_Point *affineb = ECC_NewPoint(para); + if (affineb == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + GOTO_ERR_IF(ECC_Point2Affine(para, affineb, b), ret); + + GOTO_ERR_IF(para->method->pointAdd(para, r, a, affineb), ret); +ERR: + ECC_FreePoint(affineb); + return ret; +} + +typedef struct { + uint32_t ecKeyLen; + uint32_t secBits; +} ComparableStrengths; + +/* See the standard document + https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf + Table 2: Comparable strengths */ +const ComparableStrengths g_strengthsTable[] = { + {512, 256}, + {384, 192}, + {256, 128}, + {224, 112}, + {160, 80} +}; + +int32_t ECC_GetSecBits(const ECC_Para *para) +{ + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + uint32_t bits = BN_Bits(para->n); + for (size_t i = 0; i < (sizeof(g_strengthsTable) / sizeof(g_strengthsTable[0])); i++) { + if (bits >= g_strengthsTable[i].ecKeyLen) { + return g_strengthsTable[i].secBits; + } + } + return bits / 2; +} +#endif /* HITLS_CRYPTO_ECC */ diff --git a/crypto/ecc/src/ecc_local.h b/crypto/ecc/src/ecc_local.h new file mode 100644 index 00000000..d66a245d --- /dev/null +++ b/crypto/ecc/src/ecc_local.h @@ -0,0 +1,409 @@ +/* + * 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 ECC_LOCAL_H +#define ECC_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECC + +#include "crypt_ecc.h" +#include "crypt_bn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ECC_MAX_BIT_LEN 521 + +#define PRE_COMPUTE_WINDOW 5 // Default Window Size +#define PRE_COMPUTE_MAX_TABLELEN (1 << 5) // Maximum specifications of the pre-calculation table + +/** + * Elliptic Curve Implementation Method + */ +typedef struct { + // Calculate r = k1 * G + k2 * pt + int32_t (*pointMulAdd)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, + const ECC_Point *pt); + // Calculate r = k * pt. If pt is null, calculate r = k * G. This is the ConstTime processing function. + int32_t (*pointMul)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); + // Calculate r = k * pt. If pt is null, calculate r = k * G + int32_t (*pointMulFast)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); + // point addition r = a + b + int32_t (*pointAdd)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); + // point double r = a + a + int32_t (*pointDouble)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + // point Multi-double Calculate r = (2^m)*a + int32_t (*pointMultDouble)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); + // Module inverse + int32_t (*modInv)( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt); + // Convert points to affine coordinates based on the given module inverse information. + int32_t (*point2AffineWithInv)( + const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const BN_BigNum *inv); + // Convert the point information to affine coordinates. + int32_t (*point2Affine)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + // Calculate r = (a*b) % mod + int32_t (*bnModNistEccMul)(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, + const BN_BigNum *mod, BN_Optimizer *opt); + // Calculate r = (a^2) % mod + int32_t (*bnModNistEccSqr)( + BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt); + // Inverse mode order. + int32_t (*modOrdInv)(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); +} ECC_Method; + +/** + * Elliptic Curve Point Information + */ +struct EccPointInfo { + BN_BigNum *x; + BN_BigNum *y; + BN_BigNum *z; + CRYPT_PKEY_ParaId id; +}; + +/** + * Elliptic curve parameter information + */ +struct EccPara { + BN_BigNum *p; + BN_BigNum *a; + BN_BigNum *b; + BN_BigNum *n; + BN_BigNum *h; + BN_BigNum *x; + BN_BigNum *y; + // Currently, the 5-bit window is used. Only odd multiple points are calculated. + // The total number of pre-calculated data is (2 ^ 5)/2, that is 16 points. + ECC_Point *tableG[16]; + const ECC_Method *method; + CRYPT_PKEY_ParaId id; +}; + +/** + * @ingroup ecc + * @brief Check whether the checkpoint is at infinity. + * + * @param para [IN] Curve parameters + * @param pt [IN] Point information + * + * @retval CRYPT_SUCCESS succeeded, indicating that the point is not at infinity. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointAtInfinity(const ECC_Para *para, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Check whether the point is on the curve. + * The determined point must be on the Cartesian coordinate, which is used to check the validity of the point input. + * + * @param para [IN] Curve parameters + * @param pt [IN] Point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointOnCurve(const ECC_Para *para, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Add salt to the pt point and add random z information. + * + * @param para [IN] Curve parameters + * @param pt [IN/OUT] Point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointBlind(const ECC_Para *para, ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Convert the point information pt to the affine coordinate system and synchronize the data to r. + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param pt [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Converts all point information on pt to affine coordinate system, + * which is used for the coordinate system conversion of the pre-computation table. + * + * @attention pt[0] cannot be an infinite point. + * + * @param para [IN] Curve parameters + * @param pt [IN/OUT] Point information + * @param ptNums [IN] Number of pts + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Points2Affine(const ECC_Para *para, ECC_Point *pt[], uint32_t ptNums); + +/** + * @ingroup ecc + * @brief Calculated r = -a + * + * @attention point a must be a point in the Cartesian coordinate system + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param pt [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointInvertAtAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + +/** + * @ingroup ecc + * @brief Convert the point information pt to the affine coordinate system and refresh the data to r. + * The inverse information of z is provided by the user. + * + * @attention The validity of inv is guaranteed by the user. + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param pt [IN] Input point information + * @param inv [IN] inverse information of z + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Point2AffineWithInv( + const ECC_Para *para, ECC_Point *r, const ECC_Point *pt, const BN_BigNum *inv); + +/** + * @ingroup ecc + * @brief Calculate r = k1 * G + k2 * pt + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param k1 [IN] Scalar 1 + * @param k2 [IN] Scalar 2 + * @param pt [IN] Point data + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointMulAdd( + ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Check whether a is consistent with b. + * + * @param para [IN] Curve parameter information + * @param a [IN] Input point information + * @param b [IN] Input point information + * + * @retval CRYPT_SUCCESS The two points are the same. + * @retval CRYPT_ECC_POINT_NOT_EQUAL The two points are different. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b); + +/** + * @ingroup ecc + * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G + * The pre-computation table under para will be updated. + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param k [IN] Scalar + * @param pt [IN] Point data, which can be set to NULL + * + * @retval CRYPT_SUCCESS set successfully + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointMul(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G + * The pre-computation table under para will be updated. + * Non-consttime calculation + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param k [IN] Scalar + * @param pt [IN] Point data, which can be set to NULL + * + * @retval CRYPT_SUCCESS set successfully + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointMulFast(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); + +/** + * @ingroup ecc + * @brief Calculation of multiplication(double) of points of prime curve: r = a + b + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * @param b [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); + +/** + * @ingroup ecc + * @brief Calculation of multiplication(double) of points of prime curve: r = a + a + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + +/** + * @ingroup ecc + * @brief Calculation of multiplication(double) of points of prime curve: r = (2^m)*a + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_PointMultDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); + +/** + * @ingroup ecc + * @brief Obtaining a prime number curve (p + 1)/2 + * + * @param p [IN] Input module + * + * @retval non-NULL succeeded. + * @retval NULL failed + */ +BN_BigNum *ECP_HalfPGet(const BN_BigNum *p); + +/** + * @ingroup ecc + * @brief Search implementation method by curve ID + * + * @param id [IN] Curve enumeration + * + * @retval non-NULL succeeded. + * @retval NULL failed + */ +const ECC_Method *ECC_FindMethod(CRYPT_PKEY_ParaId id); + +/** + * @ingroup ecc + * @brief nist Calculation of multiplication(double) of points of prime curve: r = a + a + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_NistPointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + +/** + * @ingroup ecc + * @brief nist Calculation of multi-double of points of prime curve: r = (2^m)*a + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * @param m [IN] Exponential information of point multiplication scalar + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_NistPointMultDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m); + +/** + * @ingroup ecc + * @brief nist Calculation of multiplication(double) of points of prime curve: r = a + b + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * @param b [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_NistPointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); + +/** + * @ingroup ecc + * @brief Convert the point to the affine coordinate and encode the point information as a data stream. + * + * @param para [IN] Curve parameter information + * @param pt [IN/OUT] Point data + * @param data [OUT] data stream + * @param dataLen [IN/OUT] The input is the buff length of data and the output is the valid length of data. + * @param format [IN] Encoding format + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen, + CRYPT_PKEY_PointFormat format); + +/** + * @ingroup ecc + * @brief Encode the data stream into point information. + * + * @param para [IN] Curve parameter information + * @param pt [OUT] Point data + * @param data [IN] data stream + * @param dataLen [IN] data stream length + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen); + +/** + * @brief Calculate r = 1/a mod para->n + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output modulus inverse value + * @param a [IN] BigNum that needs to be inverted. + * + * @retval CRYPT_SUCCESS set successfully + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ECC + +#endif // ECC_LOCAL_H diff --git a/crypto/ecc/src/ecc_method.c b/crypto/ecc/src/ecc_method.c new file mode 100644 index 00000000..6d00a84b --- /dev/null +++ b/crypto/ecc/src/ecc_method.c @@ -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_CRYPTO_ECC + +#include "ecc_local.h" +#include "bsl_err_internal.h" +#include "ecp_sm2.h" + +typedef struct { + uint32_t id; + const ECC_Method *ecMeth; +} ECC_MethodMap; + +// general method implementation of NIST prime curve +static const ECC_Method EC_METHOD_NIST = { + .pointMulAdd = ECP_PointMulAdd, + .pointMul = ECP_PointMul, + .pointMulFast = ECP_PointMulFast, + .pointAdd = ECP_NistPointAdd, + .pointDouble = ECP_NistPointDouble, + .pointMultDouble = ECP_NistPointMultDouble, + .modInv = BN_ModInv, + .point2AffineWithInv = ECP_Point2AffineWithInv, + .point2Affine = ECP_Point2Affine, + .bnModNistEccMul = BN_ModNistEccMul, + .bnModNistEccSqr = BN_ModNistEccSqr, + .modOrdInv = ECP_ModOrderInv, +}; + +#ifdef HITLS_CRYPTO_SM2 +// method implementation of SM2 +static const ECC_Method EC_METHOD_SM2 = { + .pointMulAdd = ECP_PointMulAdd, + .pointMul = ECP_Sm2PointMul, + .pointAdd = ECP_Sm2PointAdd, + .pointDouble = ECP_Sm2PointDouble, + .pointMultDouble = ECP_NistPointMultDouble, + .modInv = BN_ModInv, + .point2AffineWithInv = ECP_Point2AffineWithInv, + .point2Affine = ECP_Sm2Point2Affine, + .bnModNistEccMul = BN_ModSm2EccMul, + .bnModNistEccSqr = BN_ModSm2EccSqr, + .modOrdInv = ECP_ModOrderInv, +}; +#endif + +// general method implementation of prime curve +static const ECC_Method EC_METHOD_PRIME = { + .pointMulAdd = ECP_PointMulAdd, + .pointMul = ECP_PointMul, + .pointAdd = ECP_PointAdd, + .pointDouble = ECP_PointDouble, + .pointMultDouble = ECP_PointMultDouble, + .modInv = BN_ModInv, + .point2AffineWithInv = ECP_Point2AffineWithInv, + .point2Affine = ECP_Point2Affine, + .bnModNistEccMul = BN_ModNistEccMul, + .bnModNistEccSqr = BN_ModNistEccSqr, + .modOrdInv = ECP_ModOrderInv, +}; + +static const ECC_MethodMap EC_METHODS[] = { + { CRYPT_ECC_NISTP224, &EC_METHOD_NIST }, + { CRYPT_ECC_NISTP256, &EC_METHOD_NIST }, + { CRYPT_ECC_NISTP384, &EC_METHOD_NIST }, + { CRYPT_ECC_NISTP521, &EC_METHOD_NIST }, + { CRYPT_ECC_BRAINPOOLP256R1, &EC_METHOD_PRIME }, + { CRYPT_ECC_BRAINPOOLP384R1, &EC_METHOD_PRIME }, + { CRYPT_ECC_BRAINPOOLP512R1, &EC_METHOD_PRIME }, +#ifdef HITLS_CRYPTO_SM2 + { CRYPT_ECC_SM2, &EC_METHOD_SM2 }, +#endif +}; + + +const ECC_Method *ECC_FindMethod(CRYPT_PKEY_ParaId id) +{ + for (uint32_t i = 0; i < sizeof(EC_METHODS) / sizeof(EC_METHODS[0]); i++) { + if (EC_METHODS[i].id == id) { + return EC_METHODS[i].ecMeth; + } + } + return NULL; +} +#endif /* HITLS_CRYPTO_ECC */ diff --git a/crypto/ecc/src/ecc_para.c b/crypto/ecc/src/ecc_para.c new file mode 100644 index 00000000..848bcfdc --- /dev/null +++ b/crypto/ecc/src/ecc_para.c @@ -0,0 +1,596 @@ +/* + * 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_ECC + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "ecc_local.h" +#include "crypt_types.h" +#include "crypt_ecc_pkey.h" + +typedef struct { + const uint8_t *data; + uint32_t dataLen; +} ECC_ReadData; + +typedef struct { + ECC_ReadData p; + ECC_ReadData a; + ECC_ReadData b; + ECC_ReadData n; + ECC_ReadData h; + ECC_ReadData x; + ECC_ReadData y; +} CURVE_Para; + +static const uint8_t NIST_P_H[] = { + 0x01 +}; + +static const uint8_t NIST_P224_P[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 +}; + +static const uint8_t NIST_P224_A[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe +}; + +static const uint8_t NIST_P224_B[] = { + 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, + 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4 +}; + +static const uint8_t NIST_P224_X[] = { + 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, + 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21 +}; + +static const uint8_t NIST_P224_Y[] = { + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, + 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34 +}; + +static const uint8_t NIST_P224_N[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0xa2, + 0xe0, 0xb8, 0xf0, 0x3e, 0x13, 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d +}; + +static const uint8_t NIST_P256_P[] = { + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static const uint8_t NIST_P256_A[] = { + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc +}; + +static const uint8_t NIST_P256_B[] = { + 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, + 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b +}; + +static const uint8_t NIST_P256_X[] = { + 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96 +}; + +static const uint8_t NIST_P256_Y[] = { + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 +}; + +static const uint8_t NIST_P256_N[] = { + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51 +}; + +static const uint8_t NIST_P384_P[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; + +static const uint8_t NIST_P384_A[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc +}; + +static const uint8_t NIST_P384_B[] = { + 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19, + 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a, + 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef +}; + +static const uint8_t NIST_P384_X[] = { + 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7 +}; + +static const uint8_t NIST_P384_Y[] = { + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, + 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, + 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f +}; + +static const uint8_t NIST_P384_N[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf, + 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a, 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73 +}; + +static const uint8_t NIST_P521_P[] = { + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff +}; + +static const uint8_t NIST_P521_A[] = { + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc +}; + +static const uint8_t NIST_P521_B[] = { + 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, + 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, + 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, + 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, + 0x3f, 0x00 +}; + +static const uint8_t NIST_P521_X[] = { + 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, + 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, + 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, + 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, + 0xbd, 0x66 +}; + +static const uint8_t NIST_P521_Y[] = { + 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, + 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, + 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, + 0x66, 0x50 +}; + +static const uint8_t NIST_P521_N[] = { + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, + 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, + 0x64, 0x09 +}; + +static const uint8_t BRAINPOOL_P_H[] = { + 0x01 +}; + +static const uint8_t BRAINPOOL_P256R1_P[] = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, + 0x6e, 0x3b, 0xf6, 0x23, 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e, 0x53, 0x77 +}; + +static const uint8_t BRAINPOOL_P256R1_A[] = { + 0x7d, 0x5a, 0x09, 0x75, 0xfc, 0x2c, 0x30, 0x57, 0xee, 0xf6, 0x75, 0x30, 0x41, 0x7a, 0xff, 0xe7, + 0xfb, 0x80, 0x55, 0xc1, 0x26, 0xdc, 0x5c, 0x6c, 0xe9, 0x4a, 0x4b, 0x44, 0xf3, 0x30, 0xb5, 0xd9 +}; + +static const uint8_t BRAINPOOL_P256R1_B[] = { + 0x26, 0xdc, 0x5c, 0x6c, 0xe9, 0x4a, 0x4b, 0x44, 0xf3, 0x30, 0xb5, 0xd9, 0xbb, 0xd7, 0x7c, 0xbf, + 0x95, 0x84, 0x16, 0x29, 0x5c, 0xf7, 0xe1, 0xce, 0x6b, 0xcc, 0xdc, 0x18, 0xff, 0x8c, 0x07, 0xb6 +}; + +static const uint8_t BRAINPOOL_P256R1_X[] = { + 0x8b, 0xd2, 0xae, 0xb9, 0xcb, 0x7e, 0x57, 0xcb, 0x2c, 0x4b, 0x48, 0x2f, 0xfc, 0x81, 0xb7, 0xaf, + 0xb9, 0xde, 0x27, 0xe1, 0xe3, 0xbd, 0x23, 0xc2, 0x3a, 0x44, 0x53, 0xbd, 0x9a, 0xce, 0x32, 0x62 +}; + +static const uint8_t BRAINPOOL_P256R1_Y[] = { + 0x54, 0x7e, 0xf8, 0x35, 0xc3, 0xda, 0xc4, 0xfd, 0x97, 0xf8, 0x46, 0x1a, 0x14, 0x61, 0x1d, 0xc9, + 0xc2, 0x77, 0x45, 0x13, 0x2d, 0xed, 0x8e, 0x54, 0x5c, 0x1d, 0x54, 0xc7, 0x2f, 0x04, 0x69, 0x97 +}; + +static const uint8_t BRAINPOOL_P256R1_N[] = { + 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66, 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x71, + 0x8c, 0x39, 0x7a, 0xa3, 0xb5, 0x61, 0xa6, 0xf7, 0x90, 0x1e, 0x0e, 0x82, 0x97, 0x48, 0x56, 0xa7 +}; + +static const uint8_t BRAINPOOL_P384R1_P[] = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, + 0x15, 0x2f, 0x71, 0x09, 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7, 0x11, 0x23, + 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x53 +}; + +static const uint8_t BRAINPOOL_P384R1_A[] = { + 0x7b, 0xc3, 0x82, 0xc6, 0x3d, 0x8c, 0x15, 0x0c, 0x3c, 0x72, 0x08, 0x0a, 0xce, 0x05, 0xaf, 0xa0, + 0xc2, 0xbe, 0xa2, 0x8e, 0x4f, 0xb2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xef, 0xba, 0x91, 0xf9, 0x0f, + 0x8a, 0xa5, 0x81, 0x4a, 0x50, 0x3a, 0xd4, 0xeb, 0x04, 0xa8, 0xc7, 0xdd, 0x22, 0xce, 0x28, 0x26 +}; + +static const uint8_t BRAINPOOL_P384R1_B[] = { + 0x04, 0xa8, 0xc7, 0xdd, 0x22, 0xce, 0x28, 0x26, 0x8b, 0x39, 0xb5, 0x54, 0x16, 0xf0, 0x44, 0x7c, + 0x2f, 0xb7, 0x7d, 0xe1, 0x07, 0xdc, 0xd2, 0xa6, 0x2e, 0x88, 0x0e, 0xa5, 0x3e, 0xeb, 0x62, 0xd5, + 0x7c, 0xb4, 0x39, 0x02, 0x95, 0xdb, 0xc9, 0x94, 0x3a, 0xb7, 0x86, 0x96, 0xfa, 0x50, 0x4c, 0x11 +}; + +static const uint8_t BRAINPOOL_P384R1_X[] = { + 0x1d, 0x1c, 0x64, 0xf0, 0x68, 0xcf, 0x45, 0xff, 0xa2, 0xa6, 0x3a, 0x81, 0xb7, 0xc1, 0x3f, 0x6b, + 0x88, 0x47, 0xa3, 0xe7, 0x7e, 0xf1, 0x4f, 0xe3, 0xdb, 0x7f, 0xca, 0xfe, 0x0c, 0xbd, 0x10, 0xe8, + 0xe8, 0x26, 0xe0, 0x34, 0x36, 0xd6, 0x46, 0xaa, 0xef, 0x87, 0xb2, 0xe2, 0x47, 0xd4, 0xaf, 0x1e +}; + +static const uint8_t BRAINPOOL_P384R1_Y[] = { + 0x8a, 0xbe, 0x1d, 0x75, 0x20, 0xf9, 0xc2, 0xa4, 0x5c, 0xb1, 0xeb, 0x8e, 0x95, 0xcf, 0xd5, 0x52, + 0x62, 0xb7, 0x0b, 0x29, 0xfe, 0xec, 0x58, 0x64, 0xe1, 0x9c, 0x05, 0x4f, 0xf9, 0x91, 0x29, 0x28, + 0x0e, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3c, 0x53, 0x15 +}; + +static const uint8_t BRAINPOOL_P384R1_N[] = { + 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d, 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, + 0x15, 0x2f, 0x71, 0x09, 0xed, 0x54, 0x56, 0xb3, 0x1f, 0x16, 0x6e, 0x6c, 0xac, 0x04, 0x25, 0xa7, + 0xcf, 0x3a, 0xb6, 0xaf, 0x6b, 0x7f, 0xc3, 0x10, 0x3b, 0x88, 0x32, 0x02, 0xe9, 0x04, 0x65, 0x65 +}; + +static const uint8_t BRAINPOOL_P512R1_P[] = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, + 0xcb, 0x30, 0x8d, 0xb3, 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, 0x08, 0x71, + 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42, 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, + 0x28, 0x81, 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56, 0x58, 0x3a, 0x48, 0xf3 +}; + +static const uint8_t BRAINPOOL_P512R1_A[] = { + 0x78, 0x30, 0xa3, 0x31, 0x8b, 0x60, 0x3b, 0x89, 0xe2, 0x32, 0x71, 0x45, 0xac, 0x23, 0x4c, 0xc5, + 0x94, 0xcb, 0xdd, 0x8d, 0x3d, 0xf9, 0x16, 0x10, 0xa8, 0x34, 0x41, 0xca, 0xea, 0x98, 0x63, 0xbc, + 0x2d, 0xed, 0x5d, 0x5a, 0xa8, 0x25, 0x3a, 0xa1, 0x0a, 0x2e, 0xf1, 0xc9, 0x8b, 0x9a, 0xc8, 0xb5, + 0x7f, 0x11, 0x17, 0xa7, 0x2b, 0xf2, 0xc7, 0xb9, 0xe7, 0xc1, 0xac, 0x4d, 0x77, 0xfc, 0x94, 0xca +}; + +static const uint8_t BRAINPOOL_P512R1_B[] = { + 0x3d, 0xf9, 0x16, 0x10, 0xa8, 0x34, 0x41, 0xca, 0xea, 0x98, 0x63, 0xbc, 0x2d, 0xed, 0x5d, 0x5a, + 0xa8, 0x25, 0x3a, 0xa1, 0x0a, 0x2e, 0xf1, 0xc9, 0x8b, 0x9a, 0xc8, 0xb5, 0x7f, 0x11, 0x17, 0xa7, + 0x2b, 0xf2, 0xc7, 0xb9, 0xe7, 0xc1, 0xac, 0x4d, 0x77, 0xfc, 0x94, 0xca, 0xdc, 0x08, 0x3e, 0x67, + 0x98, 0x40, 0x50, 0xb7, 0x5e, 0xba, 0xe5, 0xdd, 0x28, 0x09, 0xbd, 0x63, 0x80, 0x16, 0xf7, 0x23 +}; + +static const uint8_t BRAINPOOL_P512R1_X[] = { + 0x81, 0xae, 0xe4, 0xbd, 0xd8, 0x2e, 0xd9, 0x64, 0x5a, 0x21, 0x32, 0x2e, 0x9c, 0x4c, 0x6a, 0x93, + 0x85, 0xed, 0x9f, 0x70, 0xb5, 0xd9, 0x16, 0xc1, 0xb4, 0x3b, 0x62, 0xee, 0xf4, 0xd0, 0x09, 0x8e, + 0xff, 0x3b, 0x1f, 0x78, 0xe2, 0xd0, 0xd4, 0x8d, 0x50, 0xd1, 0x68, 0x7b, 0x93, 0xb9, 0x7d, 0x5f, + 0x7c, 0x6d, 0x50, 0x47, 0x40, 0x6a, 0x5e, 0x68, 0x8b, 0x35, 0x22, 0x09, 0xbc, 0xb9, 0xf8, 0x22 +}; + +static const uint8_t BRAINPOOL_P512R1_Y[] = { + 0x7d, 0xde, 0x38, 0x5d, 0x56, 0x63, 0x32, 0xec, 0xc0, 0xea, 0xbf, 0xa9, 0xcf, 0x78, 0x22, 0xfd, + 0xf2, 0x09, 0xf7, 0x00, 0x24, 0xa5, 0x7b, 0x1a, 0xa0, 0x00, 0xc5, 0x5b, 0x88, 0x1f, 0x81, 0x11, + 0xb2, 0xdc, 0xde, 0x49, 0x4a, 0x5f, 0x48, 0x5e, 0x5b, 0xca, 0x4b, 0xd8, 0x8a, 0x27, 0x63, 0xae, + 0xd1, 0xca, 0x2b, 0x2f, 0xa8, 0xf0, 0x54, 0x06, 0x78, 0xcd, 0x1e, 0x0f, 0x3a, 0xd8, 0x08, 0x92 +}; + +static const uint8_t BRAINPOOL_P512R1_N[] = { + 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4, 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, + 0xcb, 0x30, 0x8d, 0xb3, 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33, 0x08, 0x70, + 0x55, 0x3e, 0x5c, 0x41, 0x4c, 0xa9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7f, 0xac, 0x10, 0x47, + 0x1d, 0xb1, 0xd3, 0x81, 0x08, 0x5d, 0xda, 0xdd, 0xb5, 0x87, 0x96, 0x82, 0x9c, 0xa9, 0x00, 0x69 +}; + +#ifdef HITLS_CRYPTO_SM2 +static const uint8_t NIST_SM2_P[] = { + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static const uint8_t NIST_SM2_A[] = { + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc +}; + +static const uint8_t NIST_SM2_B[] = { + 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b, 0xcf, 0x65, 0x09, 0xa7, + 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92, 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93 +}; + +static const uint8_t NIST_SM2_X[] = { + 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46, 0x6a, 0x39, 0xc9, 0x94, + 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1, 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7 +}; + +static const uint8_t NIST_SM2_Y[] = { + 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3, 0x6b, 0x69, 0x21, 0x53, + 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40, 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0 +}; + +static const uint8_t NIST_SM2_N[] = { + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x72, 0x03, 0xdf, 0x6b, 0x21, 0xc6, 0x05, 0x2b, 0x53, 0xbb, 0xf4, 0x09, 0x39, 0xd5, 0x41, 0x23 +}; +#endif + +#define CRYPT_CURVE_PARA_DECLARE(name) \ + static const CURVE_Para paraNist##name = { \ + .p.data = NIST_##name##_P, \ + .p.dataLen = sizeof(NIST_##name##_P), \ + .a.data = NIST_##name##_A, \ + .a.dataLen = sizeof(NIST_##name##_A), \ + .b.data = NIST_##name##_B, \ + .b.dataLen = sizeof(NIST_##name##_B), \ + .n.data = NIST_##name##_N, \ + .n.dataLen = sizeof(NIST_##name##_N), \ + .h.data = NIST_P_H, \ + .h.dataLen = sizeof(NIST_P_H), \ + .x.data = NIST_##name##_X, \ + .x.dataLen = sizeof(NIST_##name##_X), \ + .y.data = NIST_##name##_Y, \ + .y.dataLen = sizeof(NIST_##name##_Y) \ + } + +#define CRYPT_CURVE_BRAINPOOL_PARA_DECLARE(name) \ + static const CURVE_Para paraBrainpool##name = { \ + .p.data = BRAINPOOL_##name##_P, \ + .p.dataLen = sizeof(BRAINPOOL_##name##_P), \ + .a.data = BRAINPOOL_##name##_A, \ + .a.dataLen = sizeof(BRAINPOOL_##name##_A), \ + .b.data = BRAINPOOL_##name##_B, \ + .b.dataLen = sizeof(BRAINPOOL_##name##_B), \ + .n.data = BRAINPOOL_##name##_N, \ + .n.dataLen = sizeof(BRAINPOOL_##name##_N), \ + .h.data = BRAINPOOL_P_H, \ + .h.dataLen = sizeof(BRAINPOOL_P_H), \ + .x.data = BRAINPOOL_##name##_X, \ + .x.dataLen = sizeof(BRAINPOOL_##name##_X), \ + .y.data = BRAINPOOL_##name##_Y, \ + .y.dataLen = sizeof(BRAINPOOL_##name##_Y) \ + } + +CRYPT_CURVE_PARA_DECLARE(P224); +CRYPT_CURVE_PARA_DECLARE(P256); +CRYPT_CURVE_PARA_DECLARE(P384); +CRYPT_CURVE_PARA_DECLARE(P521); + +CRYPT_CURVE_BRAINPOOL_PARA_DECLARE(P256R1); +CRYPT_CURVE_BRAINPOOL_PARA_DECLARE(P384R1); +CRYPT_CURVE_BRAINPOOL_PARA_DECLARE(P512R1); +#ifdef HITLS_CRYPTO_SM2 +CRYPT_CURVE_PARA_DECLARE(SM2); +#endif + +typedef struct { + uint32_t id; + const CURVE_Para *curvePara; +} CURVE_ParaMap; + +static const CURVE_ParaMap CURVE_PARAS[] = { + { CRYPT_ECC_NISTP224, ¶NistP224 }, + { CRYPT_ECC_NISTP256, ¶NistP256 }, + { CRYPT_ECC_NISTP384, ¶NistP384 }, + { CRYPT_ECC_NISTP521, ¶NistP521 }, + { CRYPT_ECC_BRAINPOOLP256R1, ¶BrainpoolP256R1 }, + { CRYPT_ECC_BRAINPOOLP384R1, ¶BrainpoolP384R1 }, + { CRYPT_ECC_BRAINPOOLP512R1, ¶BrainpoolP512R1 }, +#ifdef HITLS_CRYPTO_SM2 + { CRYPT_ECC_SM2, ¶NistSM2 }, +#endif +}; + +static const CURVE_Para *GetCurvePara(CRYPT_PKEY_ParaId id) +{ + for (uint32_t i = 0; i < sizeof(CURVE_PARAS) / sizeof(CURVE_PARAS[0]); i++) { + if (CURVE_PARAS[i].id == id) { + return CURVE_PARAS[i].curvePara; + } + } + return NULL; +} + +ECC_Para *ECC_NewPara(CRYPT_PKEY_ParaId id) +{ + const CURVE_Para *curve = GetCurvePara(id); + if (curve == NULL) { + return NULL; + } + const ECC_Method *method = ECC_FindMethod(id); + if (method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_NOT_SUPPORT); + return NULL; + } + ECC_Para *para = BSL_SAL_Malloc(sizeof(ECC_Para)); + if (para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)memset_s(para, sizeof(ECC_Para), 0, sizeof(ECC_Para)); + para->method = method; + uint32_t bits = curve->p.dataLen * 8; + para->id = id; + para->p = BN_Create(bits); + para->a = BN_Create(bits); + para->b = BN_Create(bits); + para->n = BN_Create(bits); + para->h = BN_Create(bits); + para->x = BN_Create(bits); + para->y = BN_Create(bits); + + if (para->p == NULL || para->a == NULL || para->b == NULL || para->n == NULL || + para->h == NULL || para->x == NULL || para->y == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + + int32_t ret; + GOTO_ERR_IF(BN_Bin2Bn(para->p, curve->p.data, curve->p.dataLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(para->a, curve->a.data, curve->a.dataLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(para->b, curve->b.data, curve->b.dataLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(para->n, curve->n.data, curve->n.dataLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(para->h, curve->h.data, curve->h.dataLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(para->x, curve->x.data, curve->x.dataLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(para->y, curve->y.data, curve->y.dataLen), ret); + return para; +ERR: + ECC_FreePara(para); + return NULL; +} + +static const uint32_t CURVE_ID_LIST[] = { + CRYPT_ECC_NISTP224, + CRYPT_ECC_NISTP256, + CRYPT_ECC_NISTP384, + CRYPT_ECC_NISTP521, + CRYPT_ECC_BRAINPOOLP256R1, + CRYPT_ECC_BRAINPOOLP384R1, + CRYPT_ECC_BRAINPOOLP512R1, + CRYPT_ECC_SM2, +}; + +CRYPT_PKEY_ParaId ECC_GetCurveId(const CRYPT_EccPara *eccPara) +{ + int32_t ret; + BN_BigNum *a = BN_Create(ECC_MAX_BIT_LEN); + BN_BigNum *b = BN_Create(ECC_MAX_BIT_LEN); + + for (uint32_t i = 0; i < sizeof(CURVE_ID_LIST) / sizeof(CURVE_ID_LIST[0]); i++) { + const CURVE_Para *curve = GetCurvePara(CURVE_ID_LIST[i]); + if (curve == NULL) { + continue; + } + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->p, eccPara->pLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->p.data, curve->p.dataLen), ret); + if (BN_Cmp(a, b) != 0) { + continue; + } + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->a, eccPara->aLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->a.data, curve->a.dataLen), ret); + BREAK_IF(BN_Cmp(a, b) != 0); + + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->b, eccPara->bLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->b.data, curve->b.dataLen), ret); + BREAK_IF(BN_Cmp(a, b) != 0); + + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->h, eccPara->hLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->h.data, curve->h.dataLen), ret); + BREAK_IF(BN_Cmp(a, b) != 0); + + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->n, eccPara->nLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->n.data, curve->n.dataLen), ret); + BREAK_IF(BN_Cmp(a, b) != 0); + + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->x, eccPara->xLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->x.data, curve->x.dataLen), ret); + BREAK_IF(BN_Cmp(a, b) != 0); + + GOTO_ERR_IF_EX(BN_Bin2Bn(a, eccPara->y, eccPara->yLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(b, curve->y.data, curve->y.dataLen), ret); + BREAK_IF(BN_Cmp(a, b) != 0); + + BN_Destroy(a); + BN_Destroy(b); + return CURVE_ID_LIST[i]; + } +ERR: + BN_Destroy(a); + BN_Destroy(b); + return CRYPT_PKEY_PARAID_MAX; +} + +int32_t ECC_GetPara(const ECC_Pkey *pkey, CRYPT_EccPara *eccPara) +{ + if (pkey == NULL || eccPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pkey->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_EMPTY_KEY); + return CRYPT_ECC_PKEY_ERR_EMPTY_KEY; + } + int32_t ret = BN_Bn2Bin(pkey->para->a, eccPara->a, &eccPara->aLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(pkey->para->b, eccPara->b, &eccPara->bLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(pkey->para->h, eccPara->h, &eccPara->hLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(pkey->para->n, eccPara->n, &eccPara->nLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(pkey->para->p, eccPara->p, &eccPara->pLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(pkey->para->x, eccPara->x, &eccPara->xLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(pkey->para->y, eccPara->y, &eccPara->yLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +void ECC_FreePara(ECC_Para *para) +{ + if (para == NULL) { + return; + } + BN_Destroy(para->p); + BN_Destroy(para->a); + BN_Destroy(para->b); + BN_Destroy(para->n); + BN_Destroy(para->h); + BN_Destroy(para->x); + BN_Destroy(para->y); + uint32_t i; + for (i = 0; i < sizeof(para->tableG) / sizeof(ECC_Point *); i++) { + // clear pre-computation table + ECC_FreePoint(para->tableG[i]); + } + BSL_SAL_FREE(para); +} + + +CRYPT_PKEY_ParaId ECC_GetParaId(const ECC_Para *para) +{ + if (para == NULL) { + return CRYPT_PKEY_PARAID_MAX; + } + return para->id; +} +#endif /* HITLS_CRYPTO_ECC */ diff --git a/crypto/ecc/src/ecc_pkey.c b/crypto/ecc/src/ecc_pkey.c new file mode 100644 index 00000000..4d1d136e --- /dev/null +++ b/crypto/ecc/src/ecc_pkey.c @@ -0,0 +1,403 @@ +/* + * 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_ECC + +#include +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_utils.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "crypt_ecc_pkey.h" + +typedef struct { + const char *name; /* elliptic curve NIST name */ + CRYPT_PKEY_ParaId id; /* elliptic curve ID */ +} EC_NAME; + +void ECC_FreeCtx(ECC_Pkey *ctx) +{ + int ret = 0; + if (ctx == NULL) { + return; + } + BSL_SAL_AtomicDownReferences(&(ctx->references), &ret); + if (ret > 0) { + return; + } + BSL_SAL_ReferencesFree(&(ctx->references)); + BN_Destroy(ctx->prvkey); + ECC_FreePoint(ctx->pubkey); + ECC_FreePara(ctx->para); + BSL_SAL_FREE(ctx); + return; +} + +ECC_Pkey *ECC_DupCtx(ECC_Pkey *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + + ECC_Pkey *newCtx = BSL_SAL_Calloc(1u, sizeof(ECC_Pkey)); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + newCtx->useCofactorMode = ctx->useCofactorMode; + newCtx->pointFormat = ctx->pointFormat; + BSL_SAL_ReferencesInit(&(newCtx->references)); + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->prvkey, ctx->prvkey, BN_Dup(ctx->prvkey), CRYPT_MEM_ALLOC_FAIL); + + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pubkey, ctx->pubkey, ECC_DupPoint(ctx->pubkey), CRYPT_MEM_ALLOC_FAIL); + + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->para, ctx->para, ECC_DupPara(ctx->para), CRYPT_MEM_ALLOC_FAIL); + return newCtx; + +ERR: + ECC_FreeCtx(newCtx); + return NULL; +} + +// GetBits applies to both public and private keys. +// The public key requires the largest space. Therefore, the public key space prevails. +uint32_t ECC_PkeyGetBits(const ECC_Pkey *ctx) +{ + if ((ctx == NULL) || (ctx->para == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + + // The length of ECC_ParaBits is internally specified and can ensure that the length is not 0. 1 byte = 8 bits. + uint32_t bytes = ((ECC_ParaBits(ctx->para) - 1) / 8) + 1; + + // The public key contains 2 coordinates. The public key flag occupies is 1 byte. 1 byte = 8 bits. + return (bytes * 2 + 1) * 8; +} + +int32_t ECC_PkeySetPrvKey(ECC_Pkey *ctx, const CRYPT_EccPrv *prv) +{ + if ((ctx == NULL) || (ctx->para == NULL) || (prv == NULL) || (prv->data == NULL) || (prv->len == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret; + BN_BigNum *paraN = ECC_GetParaN(ctx->para); + BN_BigNum *newPrvKey = BN_Create(ECC_ParaBits(ctx->para)); + if ((paraN == NULL) || (newPrvKey == NULL)) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (ctx->para->id == CRYPT_ECC_SM2) { + (void)BN_SubLimb(paraN, paraN, 1); + } + ret = BN_Bin2Bn(newPrvKey, prv->data, prv->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + if (BN_IsZero(newPrvKey) || (BN_Cmp(newPrvKey, paraN)) >= 0) { + ret = CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + BN_Destroy(ctx->prvkey); + ctx->prvkey = newPrvKey; + BN_Destroy(paraN); + return CRYPT_SUCCESS; + +ERR: + BN_Destroy(newPrvKey); + BN_Destroy(paraN); + return ret; +} + +int32_t ECC_PkeySetPubKey(ECC_Pkey *ctx, const CRYPT_EccPub *pub) +{ + if ((ctx == NULL) || (ctx->para == NULL) || (pub == NULL) || (pub->data == NULL) || (pub->len == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + BN_BigNum *paraN = NULL; + ECC_Point *pointQ = NULL; + + ECC_Point *newPubKey = ECC_NewPoint(ctx->para); + if (newPubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + int32_t ret = ECC_DecodePoint(ctx->para, newPubKey, pub->data, pub->len); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + + // Check whether n * pubKey is equal to infinity. + paraN = ECC_GetParaN(ctx->para); + pointQ = ECC_NewPoint(ctx->para); + if ((paraN == NULL) || (pointQ == NULL)) { + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + + ret = ECC_PointMul(ctx->para, pointQ, paraN, newPubKey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + if (BN_IsZero(pointQ->z) == false) { + ret = CRYPT_ECC_PKEY_ERR_INVALID_PUBLIC_KEY; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = CRYPT_SUCCESS; + + ECC_FreePoint(ctx->pubkey); + ctx->pubkey = newPubKey; + newPubKey = NULL; + +ERR: + ECC_FreePoint(newPubKey); + BN_Destroy(paraN); + ECC_FreePoint(pointQ); + return ret; +} + +int32_t ECC_PkeyGetPrvKey(const ECC_Pkey *ctx, CRYPT_EccPrv *prv) +{ + if ((ctx == NULL) || (prv == NULL) || (prv->data == NULL) || (prv->len == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->prvkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_EMPTY_KEY); + return CRYPT_ECC_PKEY_ERR_EMPTY_KEY; + } + + return BN_Bn2Bin(ctx->prvkey, prv->data, &prv->len); +} + +int32_t ECC_PkeyGetPubKey(const ECC_Pkey *ctx, CRYPT_EccPub *pub) +{ + if ((ctx == NULL) || (ctx->para == NULL) || (pub == NULL) || (pub->data == NULL) || (pub->len == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->pubkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_EMPTY_KEY); + return CRYPT_ECC_PKEY_ERR_EMPTY_KEY; + } + + return ECC_EncodePoint(ctx->para, ctx->pubkey, pub->data, &pub->len, ctx->pointFormat); +} + +static int32_t GenPrivateKey(ECC_Pkey *ctx) +{ + int32_t ret = CRYPT_SUCCESS; + uint32_t tryCount = 0; + uint32_t paraBits = ECC_ParaBits(ctx->para); + BN_BigNum *paraN = NULL; + if (ctx->para->id == CRYPT_ECC_SM2) { + paraN = BN_Create(paraBits); + if (paraN == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)BN_SubLimb(paraN, ctx->para->n, 1); + } else { + paraN = ctx->para->n; + } + if (ctx->prvkey == NULL) { + ctx->prvkey = BN_Create(paraBits); + if (ctx->prvkey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + } + do { + ret = BN_RandRange(ctx->prvkey, paraN); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + tryCount += 1; + } while ((BN_IsZero(ctx->prvkey) == true) && (tryCount < CRYPT_ECC_TRY_MAX_CNT)); + + if (tryCount == CRYPT_ECC_TRY_MAX_CNT) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_TRY_CNT); + ret = CRYPT_ECC_PKEY_ERR_TRY_CNT; + } +ERR: + if (paraN != ctx->para->n) { + BN_Destroy(paraN); + } + return ret; +} + +int32_t ECC_GenPublicKey(ECC_Pkey *ctx) +{ + if (ctx->pubkey != NULL) { + return CRYPT_SUCCESS; + } + ctx->pubkey = ECC_NewPoint(ctx->para); + if (ctx->pubkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = ECC_PointMul(ctx->para, ctx->pubkey, ctx->prvkey, NULL); + if (ret != CRYPT_SUCCESS) { + ECC_FreePoint(ctx->pubkey); + ctx->pubkey = NULL; + } + return ret; +} + +static int32_t GenPublicKey(ECC_Pkey *ctx) +{ + if ((ctx == NULL) || (ctx->prvkey == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret; + if (ctx->pubkey == NULL) { + ctx->pubkey = ECC_NewPoint(ctx->para); + if (ctx->pubkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + } + + ret = ECC_PointMul(ctx->para, ctx->pubkey, ctx->prvkey, NULL); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + return CRYPT_SUCCESS; +} + +int32_t ECC_PkeyGen(ECC_Pkey *ctx) +{ + if ((ctx == NULL) || (ctx->para == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret = GenPrivateKey(ctx); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + + ret = GenPublicKey(ctx); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + + return CRYPT_SUCCESS; +ERR: + BN_Zeroize(ctx->prvkey); + BN_Destroy(ctx->prvkey); + ctx->prvkey = NULL; + ECC_FreePoint(ctx->pubkey); + ctx->pubkey = NULL; + return ret; +} + +int32_t ECC_PkeyCtrl(ECC_Pkey *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + if ((ctx == NULL) || (val == NULL && opt != CRYPT_CTRL_GEN_ECC_PUBLICKEY)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (opt == CRYPT_CTRL_SET_ECC_POINT_FORMAT) { + uint32_t pointFormat = *(uint32_t *)val; + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN); + return CRYPT_ECC_PKEY_ERR_CTRL_LEN; + } + if (pointFormat >= CRYPT_POINT_MAX) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT); + return CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT; + } + + ctx->pointFormat = pointFormat; + return CRYPT_SUCCESS; + } else if (opt == CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE) { + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN); + return CRYPT_ECC_PKEY_ERR_CTRL_LEN; + } + + ctx->useCofactorMode = *(uint32_t *)val; + return CRYPT_SUCCESS; + } else if (opt == CRYPT_CTRL_UP_REFERENCES && len == (uint32_t)sizeof(int)) { + return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val); + } else if (opt == CRYPT_CTRL_GEN_ECC_PUBLICKEY) { + return GenPublicKey(ctx); + } + + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION); + return CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION; +} + +ECC_Pkey *ECC_PkeyNewCtx(CRYPT_PKEY_ParaId id) +{ + ECC_Para *para = ECC_NewPara(id); + if (para == NULL) { + return NULL; + } + ECC_Pkey *key = BSL_SAL_Calloc(1u, sizeof(ECC_Pkey)); + if (key == NULL) { + ECC_FreePara(para); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + key->para = para; + key->pointFormat = CRYPT_POINT_UNCOMPRESSED; + BSL_SAL_ReferencesInit(&(key->references)); + return key; +} + +int32_t ECC_PkeyCmp(const ECC_Pkey *a, const ECC_Pkey *b) +{ + RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT); + + // Compare public keys. + RETURN_RET_IF(ECC_PointCmp(a->para, a->pubkey, b->pubkey), CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL); + + // Compare parameters. + RETURN_RET_IF(b->para == NULL || a->para->id != b->para->id, CRYPT_ECC_POINT_ERR_CURVE_ID); + + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_ECC */ diff --git a/crypto/ecc/src/ecc_utils.h b/crypto/ecc/src/ecc_utils.h new file mode 100644 index 00000000..6f774aff --- /dev/null +++ b/crypto/ecc/src/ecc_utils.h @@ -0,0 +1,93 @@ +/* + * 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 ECC_UTILS_H +#define ECC_UTILS_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECC + +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "crypt_errno.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* the window length of common point multiplication */ +#define WINDOW_SIZE 5 + +/* + * Decoded from a 6-bit signed code to obtain the sign and value. The upper five bits are the complement of the value, + * and the least significant bit is the carry (positive) of the next group of numbers. + * Output: + * sign = 0 or 1 + * 0 <= value <= 16 + */ +inline static void DecodeScalarCode(uint32_t *sign, uint32_t *value, uint32_t code) +{ + uint32_t s, v; + s = 0 - (code >> WINDOW_SIZE); // Bit 5 is the sign bit, and the negative number is all 1s. + // Take its value and add a carry. Because the symbol is obtained and then the carry is added, v may be + 16 or - 0. + v = (code >> 1) + (code & 1); + // Find the Take its value and add a carry. If the number is positive, v is the Take its value and add a carry. + // If the number is negative, v is inverted + 1. + v = (~s & v) | (s & (~v + 1)); + + *sign = s & 1; + *value = v & ((1 << WINDOW_SIZE) - 1); // Five bits are intercepted. +} + +inline static int32_t CheckParaValid(const ECC_Para *para, CRYPT_PKEY_ParaId id) +{ + if (para == NULL) { + return CRYPT_NULL_INPUT; + } + if (para->id != id) { + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + return CRYPT_SUCCESS; +} + +inline static int32_t CheckPointValid(const ECC_Point *pt, CRYPT_PKEY_ParaId id) +{ + if (pt == NULL) { + return CRYPT_NULL_INPUT; + } + if (pt->id != id) { + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + return CRYPT_SUCCESS; +} + +inline static int32_t CheckBnValid(const BN_BigNum *k, uint32_t maxBits) +{ + if (k == NULL) { + return CRYPT_NULL_INPUT; + } + if (BN_Bits(k) > maxBits) { // If K is greater than maxBits, it is considered too long. + return CRYPT_ECC_POINT_MUL_ERR_K_LEN; + } + return CRYPT_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ECC + +#endif // ECC_UTILS_H diff --git a/crypto/ecc/src/ecp_nist.c b/crypto/ecc/src/ecp_nist.c new file mode 100644 index 00000000..c4073f69 --- /dev/null +++ b/crypto/ecc/src/ecp_nist.c @@ -0,0 +1,250 @@ +/* + * 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_ECC + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "ecc_local.h" + +static int32_t CreatTmpBn(BN_BigNum **t1, BN_BigNum **t2, BN_BigNum **t3, + BN_BigNum **t4, uint32_t bits) +{ + *t1 = BN_Create(bits); + *t2 = BN_Create(bits); + *t3 = BN_Create(bits); + *t4 = BN_Create(bits); + if (*t1 == NULL || *t2 == NULL || *t3 == NULL || *t4 == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +static void DestroyTmpBn( + BN_BigNum *t1, BN_BigNum *t2, BN_BigNum *t3, BN_BigNum *t4) +{ + BN_Destroy(t1); + BN_Destroy(t2); + BN_Destroy(t3); + BN_Destroy(t4); +} + +// Jacobian coordinate double the point +int32_t ECP_NistPointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + uint32_t bits = BN_Bits(para->p); + + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *t1 = BN_Create(bits); + BN_BigNum *t2 = BN_Create(bits); + BN_BigNum *t3 = BN_Create(bits); + BN_BigNum *halfP = ECP_HalfPGet(para->p); + if (t1 == NULL || t2 == NULL || t3 == NULL || halfP == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(para->method->bnModNistEccSqr(t1, a->z, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(t2, a->x, t1, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(t1, a->x, t1, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t2, t2, t1, para->p, opt), ret); + + GOTO_ERR_IF(BN_ModAddQuick(t3, t2, t2, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(t2, t3, t2, para->p, opt), ret); // t2 = 3*t2 + GOTO_ERR_IF(BN_ModAddQuick(r->y, a->y, a->y, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(r->z, r->y, a->z, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccSqr(r->y, r->y, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t3, r->y, a->x, para->p, opt), ret); + + GOTO_ERR_IF(para->method->bnModNistEccSqr(r->y, r->y, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(r->y, r->y, halfP, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccSqr(r->x, t2, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(t1, t3, t3, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t1, para->p, opt), ret); + + GOTO_ERR_IF(BN_ModSubQuick(t1, t3, r->x, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t1, t1, t2, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->y, t1, r->y, para->p, opt), ret); +ERR: + BN_Destroy(t1); + BN_Destroy(t2); + BN_Destroy(t3); + BN_Destroy(halfP); + BN_OptimizerDestroy(opt); + return ret; +} + +// Jacobian coordinate multi-double the point: r = (2^m) * pt +int32_t ECP_NistPointMultDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t tm = m; + int32_t ret; + uint32_t bits = BN_Bits(para->p); + BN_BigNum *ta = NULL, *tb = NULL, *tc = NULL, *tw = NULL; + BN_BigNum *halfP = ECP_HalfPGet(para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + GOTO_ERR_IF_EX(CreatTmpBn(&ta, &tb, &tc, &tw, bits), ret); + if (halfP == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(BN_Copy(r->x, a->x), ret); + GOTO_ERR_IF(BN_ModAddQuick(r->y, a->y, a->y, para->p, opt), ret); + GOTO_ERR_IF(BN_Copy(r->z, a->z), ret); + + GOTO_ERR_IF(para->method->bnModNistEccSqr(tw, a->z, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccSqr(tw, tw, para->p, opt), ret); + + while (tm > 0) { + // 3.1 + // ta = 3*(x^2 - tw) + GOTO_ERR_IF(para->method->bnModNistEccSqr(ta, r->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(tc, ta, tw, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(ta, tc, tc, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(ta, ta, tc, para->p, opt), ret); + // tb = x*(y^2) + GOTO_ERR_IF(para->method->bnModNistEccSqr(tc, r->y, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(tb, tc, r->x, para->p, opt), ret); + + // 3.2 + // x = ta^2 - 2*tb + GOTO_ERR_IF(para->method->bnModNistEccSqr(r->x, ta, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, tb, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, tb, para->p, opt), ret); + // z = zy + GOTO_ERR_IF(para->method->bnModNistEccMul(r->z, r->z, r->y, para->p, opt), ret); + + // 3.3 + // tc = y^4 + GOTO_ERR_IF(para->method->bnModNistEccSqr(tc, r->y, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccSqr(tc, tc, para->p, opt), ret); + // m = m - 1, if bit > 0, tw = tw * (y^4) + tm--; + if (tm > 0) { + GOTO_ERR_IF(para->method->bnModNistEccMul(tw, tw, tc, para->p, opt), ret); + } + // 3.4 + // y = 2*ta*(tb - x) - (y^4) + GOTO_ERR_IF(BN_ModSubQuick(r->y, tb, r->x, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(r->y, r->y, ta, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(r->y, r->y, r->y, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->y, r->y, tc, para->p, opt), ret); + } + GOTO_ERR_IF(para->method->bnModNistEccMul(r->y, r->y, halfP, para->p, opt), ret); +ERR: + DestroyTmpBn(ta, tb, tc, tw); + BN_Destroy(halfP); + BN_OptimizerDestroy(opt); + return ret; +} + +// Point addition calculation (Jacobian point a plus affine point b) +int32_t ECP_NistPointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, + const ECC_Point *b) +{ + if (para == NULL || r == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_IsZero(a->z)) { + // If point a is an infinity point, r = b + return ECC_CopyPoint(r, b); + } + int32_t ret; + uint32_t bits = BN_Bits(para->p); + + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *t1 = NULL, *t2 = NULL, *t3 = NULL, *t4 = NULL; + GOTO_ERR_IF_EX(CreatTmpBn(&t1, &t2, &t3, &t4, bits), ret); + if (opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(para->method->bnModNistEccSqr(t1, a->z, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t2, t1, a->z, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t1, t1, b->x, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t2, t2, b->y, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(t1, t1, a->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(t2, t2, a->y, para->p, opt), ret); + + if (BN_IsZero(t1)) { + if (BN_IsZero(t2)) { + // If two points are equal, use double the point for calculation. + GOTO_ERR_IF(ECP_NistPointDouble(para, r, b), ret); + goto ERR; + } else { + // Obtain the infinity point. + GOTO_ERR_IF(BN_SetLimb(r->z, 0), ret); + goto ERR; + } + } + GOTO_ERR_IF(para->method->bnModNistEccMul(r->z, a->z, t1, para->p, opt), ret); + + GOTO_ERR_IF(para->method->bnModNistEccSqr(t3, t1, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t4, t1, t3, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t3, t3, a->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(t1, t3, t3, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccSqr(r->x, t2, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t1, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t4, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(t3, t3, r->x, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t3, t3, t2, para->p, opt), ret); + GOTO_ERR_IF(para->method->bnModNistEccMul(t4, t4, a->y, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSubQuick(r->y, t3, t4, para->p, opt), ret); +ERR: + DestroyTmpBn(t1, t2, t3, t4); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t ECP_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a) +{ + int32_t ret; + BN_Optimizer *opt = NULL; + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + opt = BN_OptimizerCreate(); + if (opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = BN_ModInv(r, a, para->n, opt); + BN_OptimizerDestroy(opt); + return ret; +} +#endif /* HITLS_CRYPTO_ECC */ diff --git a/crypto/ecc/src/ecp_nistp224.c b/crypto/ecc/src/ecp_nistp224.c new file mode 100644 index 00000000..81d92cb9 --- /dev/null +++ b/crypto/ecc/src/ecp_nistp224.c @@ -0,0 +1,1522 @@ +/* + * 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_CURVE_NISTP224) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "ecc_utils.h" + +typedef __uint128_t uint128_t; + + +/* field element definition */ +#define FELEM_BITS 224 +#define FELEM_BYTES 28 +#define LIMB_BITS (sizeof(uint64_t) << 3) +#define LIMB_NUM 4 +#define BASE_BITS 56 +#define BASE_MASK 0x00ffffffffffffff +/* The pre-calculation table of the G table has 16 points. */ +#define TABLE_G_SIZE 16 +/* The pre-calculation table of the P table has 17 points. */ +#define TABLE_P_SIZE 17 + +/* + * field elements, stored as arrays, all represented in little endian. + * Each element of the array is called a digit, and each digit represents an extended 2^56-number-system digit, + * that is, Felem can be expressed as: + * f_0 + f_1 * 2^56 + f_2 * 2^112 + f_3 * 2^168 + * LongFelem is the same, but twice the width of Felem. + * It is used to store the result of multiplication of field elements. + * Point is a point represented as a Jacobian coordinate + */ +typedef struct { + uint64_t data[LIMB_NUM]; +} Felem; + +typedef struct { + uint128_t data[LIMB_NUM * 2 - 1]; +} LongFelem; + +typedef struct { + Felem x; + Felem y; + Felem z; +} Point; + +/* ------------------------------------------------------------ */ +/* ECP224 field order p, the value is 2^224 - 2^96 + 1, little endian. */ +static const Felem FIELD_ORDER = { + {0x0000000000000001, 0x00ffff0000000000, 0x00ffffffffffffff, 0x00ffffffffffffff} +}; + +/* + * A pre-calculated table of the base point G, which contains the (X, Y, Z) coordinates of k*G + * + * PRE_MUL_G divides all bits into four equal parts. + * index Corresponding bit value of k + * 0 0 0 0 0 0 + 0 + 0 + 0 + * 1 0 0 0 1 0 + 0 + 0 + 1 + * 2 0 0 1 0 0 + 0 + 2^56 + 0 + * 3 0 0 1 1 0 + 0 + 2^56 + 1 + * 4 0 1 0 0 0 + 2^112 + 0 + 0 + * 5 0 1 0 1 0 + 2^112 + 0 + 1 + * 6 0 1 1 0 0 + 2^112 + 2^56 + 0 + * 7 0 1 1 1 0 + 2^112 + 2^56 + 1 + * 8 1 0 0 0 2^168 + 0 + 0 + 0 + * 9 1 0 0 1 2^168 + 0 + 0 + 1 + * 10 1 0 1 0 2^168 + 0 + 2^56 + 0 + * 11 1 0 1 1 2^168 + 0 + 2^56 + 1 + * 12 1 1 0 0 2^168 + 2^112 + 0 + 0 + * 13 1 1 0 1 2^168 + 2^112 + 0 + 1 + * 14 1 1 1 0 2^168 + 2^112 + 2^56 + 0 + * 15 1 1 1 1 2^168 + 2^112 + 2^56 + 1 + */ +static const Point PRE_MUL_G[TABLE_G_SIZE] = { + { + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x003280d6115c1d21, 0x00c1d356c2112234, 0x007f321390b94a03, 0x00b70e0cbd6bb4bf}}, + {{0x00d5819985007e34, 0x0075a05a07476444, 0x00fb4c22dfe6cd43, 0x00bd376388b5f723}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00fd9675666ebbe9, 0x00bca7664d40ce5e, 0x002242df8d8a2a43, 0x001f49bbb0f99bc5}}, + {{0x0029e0b892dc9c43, 0x00ece8608436e662, 0x00dc858f185310d0, 0x009812dd4eb8d321}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x006d3e678d5d8eb8, 0x00559eed1cb362f1, 0x0016e9a3bbce8a3f, 0x00eedcccd8c2a748}}, + {{0x00f19f90ed50266d, 0x00abf2b4bf65f9df, 0x00313865468fafec, 0x005cb379ba910a17}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x000641966cab26e3, 0x0091fb2991fab0a0, 0x00efec27a4e13a0b, 0x000499aa8a5f8ebe}}, + {{0x007510407766af5d, 0x0084d929610d5450, 0x0081d77aae82f706, 0x006916f6d4338c5b}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00ea95ac3b1f15c6, 0x00086000905e82d4, 0x00dd323ae4d1c8b1, 0x00932b56be7685a3}}, + {{0x009ef93dea25dbbf, 0x0041665960f390f0, 0x00fdec76dbe2a8a7, 0x00523e80f019062a}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00822fdd26732c73, 0x00a01c83531b5d0f, 0x00363f37347c1ba4, 0x00c391b45c84725c}}, + {{0x00bbd5e1b2d6ad24, 0x00ddfbcde19dfaec, 0x00c393da7e222a7f, 0x001efb7890ede244}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x004c9e90ca217da1, 0x00d11beca79159bb, 0x00ff8d33c2c98b7c, 0x002610b39409f849}}, + {{0x0044d1352ac64da0, 0x00cdbb7b2c46b4fb, 0x00966c079b753c89, 0x00fe67e4e820b112}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00e28cae2df5312d, 0x00c71b61d16f5c6e, 0x0079b7619a3e7c4c, 0x0005c73240899b47}}, + {{0x009f7f6382c73e3a, 0x0018615165c56bda, 0x00641fab2116fd56, 0x0072855882b08394}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x000469182f161c09, 0x0074a98ca8d00fb5, 0x00b89da93489a3e0, 0x0041c98768fb0c1d}}, + {{0x00e5ea05fb32da81, 0x003dce9ffbca6855, 0x001cfe2d3fbf59e6, 0x000e5e03408738a7}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00dab22b2333e87f, 0x004430137a5dd2f6, 0x00e03ab9f738beb8, 0x00cb0c5d0dc34f24}}, + {{0x00764a7df0c8fda5, 0x00185ba5c3fa2044, 0x009281d688bcbe50, 0x00c40331df893881}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00b89530796f0f60, 0x00ade92bd26909a3, 0x001a0c83fb4884da, 0x001765bf22a5a984}}, + {{0x00772a9ee75db09e, 0x0023bc6c67cec16f, 0x004c1edba8b14e2f, 0x00e2a215d9611369}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00571e509fb5efb3, 0x00ade88696410552, 0x00c8ae85fada74fe, 0x006c7e4be83bbde3}}, + {{0x00ff9f51160f4652, 0x00b47ce2495a6539, 0x00a2946c53b582f4, 0x00286d2db3ee9a60}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x0040bbd5081a44af, 0x000995183b13926c, 0x00bcefba6f47f6d0, 0x00215619e9cc0057}}, + {{0x008bc94d3b0df45e, 0x00f11c54a3694f6f, 0x008631b93cdfe8b5, 0x00e7e3f4b0982db9}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00b17048ab3e1c7b, 0x00ac38f36ff8a1d8, 0x001c29819435d2c6, 0x00c813132f4c07e9}}, + {{0x002891425503b11f, 0x0008781030579fea, 0x00f5426ba5cc9674, 0x001e28ebf18562bc}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x009f31997cc864eb, 0x0006cd91d28b5e4c, 0x00ff17036691a973, 0x00f1aef351497c58}}, + {{0x00dd1f2d600564ff, 0x00dead073b1402db, 0x0074a684435bd693, 0x00eea7471f962558}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + } +}; + +/* + * A pre-calculated table of the base point G, which contains the (X, Y, Z) coordinates of k*G + * + * PRE_MUL_G2[] = PRE_MUL_G[] * 2^28 + * index Corresponding bit value of k + * 0 0 0 0 0 0 + 0 + 0 + 0 + * 1 0 0 0 1 0 + 0 + 0 + 2^28 + * 2 0 0 1 0 0 + 0 + 2^84 + 0 + * 3 0 0 1 1 0 + 0 + 2^84 + 2^28 + * 4 0 1 0 0 0 + 2^140 + 0 + 0 + * 5 0 1 0 1 0 + 2^140 + 0 + 2^28 + * 6 0 1 1 0 0 + 2^140 + 2^84 + 0 + * 7 0 1 1 1 0 + 2^140 + 2^84 + 2^28 + * 8 1 0 0 0 2^196 + 0 + 0 + 0 + * 9 1 0 0 1 2^196 + 0 + 0 + 2^28 + * 10 1 0 1 0 2^196 + 0 + 2^84 + 0 + * 11 1 0 1 1 2^196 + 0 + 2^84 + 2^28 + * 12 1 1 0 0 2^196 + 2^140 + 0 + 0 + * 13 1 1 0 1 2^196 + 2^140 + 0 + 2^28 + * 14 1 1 1 0 2^196 + 2^140 + 2^84 + 0 + * 15 1 1 1 1 2^196 + 2^140 + 2^84 + 2^28 + */ +static const Point PRE_MUL_G2[TABLE_G_SIZE] = { + { + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x009665266dddf554, 0x009613d78b60ef2d, 0x00ce27a34cdba417, 0x00d35ab74d6afc31}}, + {{0x0085ccdd22deb15e, 0x002137e5783a6aab, 0x00a141cffd8c93c6, 0x00355a1830e90f2d}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x001a494eadaade65, 0x00d6da4da77fe53c, 0x00e7992996abec86, 0x0065c3553c6090e3}}, + {{0x00fa610b1fb09346, 0x00f1c6540b8a4aaf, 0x00c51a13ccd3cbab, 0x0002995b1b18c28a}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x007874568e7295ef, 0x0086b419fbe38d04, 0x00dc0690a7550d9a, 0x00d3966a44beac33}}, + {{0x002b7280ec29132f, 0x00beaa3b6a032df3, 0x00dc7dd88ae41200, 0x00d25e2513e3a100}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00924857eb2efafd, 0x00ac2bce41223190, 0x008edaa1445553fc, 0x00825800fd3562d5}}, + {{0x008d79148ea96621, 0x0023a01c3dd9ed8d, 0x00af8b219f9416b5, 0x00d8db0cc277daea}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x0076a9c3b1a700f0, 0x00e9acd29bc7e691, 0x0069212d1a6b0327, 0x006322e97fe154be}}, + {{0x00469fc5465d62aa, 0x008d41ed18883b05, 0x001f8eae66c52b88, 0x00e4fcbe9325be51}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00825fdf583cac16, 0x00020b857c7b023a, 0x00683c17744b0165, 0x0014ffd0a2daf2f1}}, + {{0x00323b36184218f9, 0x004944ec4e3b47d4, 0x00c15b3080841acf, 0x000bced4b01a28bb}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x0092ac22230df5c4, 0x0052f33b4063eda8, 0x00cb3f19870c0c93, 0x0040064f2ba65233}}, + {{0x00fe16f0924f8992, 0x00012da25af5b517, 0x001a57bb24f723a6, 0x0006f8bc76760def}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x004a7084f7817cb9, 0x00bcab0738ee9a78, 0x003ec11e11d9c326, 0x00dc0fe90e0f1aae}}, + {{0x00cf639ea5f98390, 0x005c350aa22ffb74, 0x009afae98a4047b7, 0x00956ec2d617fc45}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x004306d648c1be6a, 0x009247cd8bc9a462, 0x00f5595e377d2f2e, 0x00bd1c3caff1a52e}}, + {{0x00045e14472409d0, 0x0029f3e17078f773, 0x00745a602b2d4f7d, 0x00191837685cdfbb}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x005b6ee254a8cb79, 0x004953433f5e7026, 0x00e21faeb1d1def4, 0x00c4c225785c09de}}, + {{0x00307ce7bba1e518, 0x0031b125b1036db8, 0x0047e91868839e8f, 0x00c765866e33b9f3}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x003bfece24f96906, 0x004794da641e5093, 0x00de5df64f95db26, 0x00297ecd89714b05}}, + {{0x00701bd3ebb2c3aa, 0x007073b4f53cb1d5, 0x0013c5665658af16, 0x009895089d66fe58}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x000fef05f78c4790, 0x002d773633b05d2e, 0x0094229c3a951c94, 0x00bbbd70df4911bb}}, + {{0x00b2c6963d2c1168, 0x00105f47a72b0d73, 0x009fdf6111614080, 0x007b7e94b39e67b0}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00ad1a7d6efbe2b3, 0x00f012482c0da69d, 0x006b3bdf12438345, 0x0040d7558d7aa4d9}}, + {{0x008a09fffb5c6d3d, 0x009a356e5d9ffd38, 0x005973f15f4f9b1c, 0x00dcd5f59f63c3ea}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00acf39f4c5ca7ab, 0x004c8071cc5fd737, 0x00c64e3602cd1184, 0x000acd4644c9abba}}, + {{0x006c011a36d8bf6e, 0x00fecd87ba24e32a, 0x0019f6f56574fad8, 0x00050b204ced9405}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x00ed4f1cae7d9a96, 0x005ceef7ad94c40a, 0x00778e4a3bf3ef9b, 0x007405783dc3b55e}}, + {{0x0032477c61b6e8c6, 0x00b46a97570f018b, 0x0091176d0a7e95d1, 0x003df90fbc4c7d0e}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + } +}; + +/* --------------------------helper function-------------------------- */ +/* + * Convert big endian byte stream to Felem + */ +static void Bin2Felem(Felem *out, const uint8_t in[FELEM_BYTES]) +{ + int32_t offset; + for (int32_t i = LIMB_NUM - 1; i >= 0; --i) { + offset = 7 * (LIMB_NUM - 1 - i); // 56bits occupy 7 bytes. + out->data[i] = ((uint64_t)in[offset + 0] << 48) | // Byte 0 is shifted by 48 bits to the left. + ((uint64_t)in[offset + 1] << 40) | // The 1st byte is shifted leftward by 40 bits. + ((uint64_t)in[offset + 2] << 32) | // The 2nd byte is shifted leftward by 32 bits. + ((uint64_t)in[offset + 3] << 24) | // The 3rd byte is shifted leftward by 24 bits. + ((uint64_t)in[offset + 4] << 16) | // The 4th byte is shifted leftward by 16 bits. + ((uint64_t)in[offset + 5] << 8) | // The 5th byte is shifted leftward by 8 bits. + ((uint64_t)in[offset + 6]); // No shift is required for the 6th byte. + } +} + +/* + * Convert Felem to big-endian byte stream + * Input: + * in[] < 2^56 + * Output: + * the length of out is 28 + */ +static void Felem2Bin(uint8_t out[FELEM_BYTES], const Felem *in) +{ + int32_t offset; + for (int32_t i = LIMB_NUM - 1; i >= 0; --i) { + offset = 7 * (LIMB_NUM - 1 - i); // 56bits occupy 7 bytes. + out[offset + 0] = (uint8_t)(in->data[i] >> 48); // out[i + 0] get 48~55 bits + out[offset + 1] = (uint8_t)(in->data[i] >> 40); // out[i + 1] get 40~47 bits + out[offset + 2] = (uint8_t)(in->data[i] >> 32); // out[i + 2] get 32~39 bits + out[offset + 3] = (uint8_t)(in->data[i] >> 24); // out[i + 3] get 24~31 bits + out[offset + 4] = (uint8_t)(in->data[i] >> 16); // out[i + 4] get 16~23 bits + out[offset + 5] = (uint8_t)(in->data[i] >> 8); // out[i + 5] get 8~15 bits + out[offset + 6] = (uint8_t)in->data[i]; // out[i + 6] get 0~7 bits + } +} + +/* + * Convert BN to Felem + * Output: + * out[] < 2^56 + */ +static int32_t BN2Felem(Felem *out, const BN_BigNum *in) +{ + int32_t retVal; + uint8_t bin[FELEM_BYTES]; + uint32_t len = FELEM_BYTES; + + GOTO_ERR_IF(BN_Bn2Bin(in, bin, &len), retVal); + + for (uint32_t i = 0; i < FELEM_BYTES; ++i) { + bin[FELEM_BYTES - 1 - i] = i < len ? bin[len - 1 - i] : 0; + } + + Bin2Felem(out, bin); +ERR: + return retVal; +} + +/* + * Convert Felem to BN + * Input: + * in[] < 2^56 + */ +static int32_t Felem2BN(BN_BigNum *out, const Felem *in) +{ + int32_t retVal; + uint8_t bin[FELEM_BYTES]; + + Felem2Bin(bin, in); + + GOTO_ERR_IF(BN_Bin2Bn(out, bin, FELEM_BYTES), retVal); +ERR: + return retVal; +} + +/* ---------------------------field operation--------------------------- */ +/* + * Assignment + */ +static inline void FelemAssign(Felem *out, const Felem *in) +{ + out->data[0] = in->data[0]; // out->data[0] takes the value + out->data[1] = in->data[1]; // out->data[1] takes the value + out->data[2] = in->data[2]; // out->data[2] takes the value + out->data[3] = in->data[3]; // out->data[3] takes the value +} + +/* + * Copy bits by mask. If the corresponding bit is 1, copy the bit. If the corresponding bit is 0, retain the bit. + */ +static inline void FelemAssignWithMask(Felem *out, const Felem *in, const uint64_t mask) +{ + uint64_t rmask = ~mask; + out->data[0] = (in->data[0] & mask) | (out->data[0] & rmask); // out->data[0] get a new value or remain unchanged. + out->data[1] = (in->data[1] & mask) | (out->data[1] & rmask); // out->data[1] get a new value or remain unchanged. + out->data[2] = (in->data[2] & mask) | (out->data[2] & rmask); // out->data[2] get a new value or remain unchanged. + out->data[3] = (in->data[3] & mask) | (out->data[3] & rmask); // out->data[3] get a new value or remain unchanged. +} + +/* + * Set the lowest digit + */ +static inline void FelemSetLimb(Felem *out, const uint64_t in) +{ + out->data[0] = in; // out->data[0] takes the value + out->data[1] = 0; // out->data[1] clear to 0 + out->data[2] = 0; // out->data[2] clear to 0 + out->data[3] = 0; // out->data[3] clear to 0 +} + +/* + * Zero judgment: is input less than(2^224 + 2^(16 + 192)). Only 0 and p need to be judged. + * Input: + * in[] < 2^56 + 2^16 + * - in[0] < 2^56 + * - in[1] < 2^56 + * - in[2] < 2^56 + * - in[3] < 2^56 + 2^16 + */ +static inline uint64_t FelemIsZero(const Felem *in) +{ + uint64_t isZero, isP; + + // Check whether digits 0, 1, 2, and 3 of in are all 0. + isZero = in->data[0] | in->data[1] | in->data[2] | in->data[3]; + isZero -= 1; // If in == 0, the most significant bit is 1. + + // Determine that in is equal to the field order. + isP = (in->data[0] ^ FIELD_ORDER.data[0]) | // Determines whether the digits 0 are equal. + (in->data[1] ^ FIELD_ORDER.data[1]) | // Determines whether the digits 1 are equal. + (in->data[2] ^ FIELD_ORDER.data[2]) | // Determines whether the digits 2 are equal. + (in->data[3] ^ FIELD_ORDER.data[3]); // Determines whether the digits 3 are equal. + isP -= 1; // If in == p, the most significant bit is 1 + + return (isZero | isP) >> (LIMB_BITS - 1); +} + +/* + * Obtain the bit string whose length is len at idx in Felem. + * Input: + * in[i] < 2^56 + * 0 < len <= 64 + */ +static uint64_t FelemGetBits(const Felem *in, int32_t idx, uint32_t len) +{ + uint64_t ret; + uint32_t lower, upper; + uint64_t mask; + + lower = (uint32_t)idx; + // when 0 <= lower < 224, the most significant bit is 1. Obtain the most significant bit by right shifted by 31 bits + mask = (uint64_t)0 - ((~lower & (lower - 224)) >> 31); + ret = (in->data[(lower / BASE_BITS) & mask] & BASE_MASK & mask) >> (lower % BASE_BITS); + + upper = (uint32_t)idx + BASE_BITS; // Next Unary Block + // when 0 <= upper < 224, the most significant bit is 1. Obtain the most significant bit by right shifted by 31 bits + mask = (uint64_t)0 - ((~upper & (upper - 224)) >> 31); + ret |= (in->data[(upper / BASE_BITS) & mask] & BASE_MASK & mask) << (BASE_BITS - upper % BASE_BITS); + + ret &= ((uint64_t)1 << len) - 1; // All 1s of the len length + + return ret; +} + +/* + * field element reduction, retain the lower 56 bits of each Limb in the 4-ary Felem, + * perform reduction on the upper bits, and perform modulo operation to reduce all Limbs to [0, 2 ^ 56 + 2 ^ 7). + * Input: + * in[] < 2^63 + * Output: + * out[] < 2^56 + 2^7 + * - out[0] < 2^56 + * - out[1] < 2^56 + * - out[2] < 2^56 + * - out[3] < 2^56 + 2^7 + */ +static void FelemReduce(Felem *out, const Felem *in) +{ + uint64_t carryLimb = in->data[3] >> BASE_BITS; + const uint64_t borrow = (uint64_t)1 << 56; + const uint64_t lend = 1; + + // reduction carryLimb * (2^96 - 1), because it's the non-negative number, it must can be borrowed. + // Calculate out->data[0] + out->data[0] = in->data[0] + borrow - carryLimb; // carryLimb * (-1) + // Calculate out->data[1] + out->data[1] = in->data[1] + (out->data[0] >> BASE_BITS) + (carryLimb << 40) - lend; // carryLimb * 2^(56 + 40) + // Calculate out->data[2] + out->data[2] = in->data[2] + (out->data[1] >> BASE_BITS); + // Calculate out->data[3] + out->data[3] = (in->data[3] & BASE_MASK) + (out->data[2] >> BASE_BITS); // < 2^56 + 2^7 + + out->data[0] &= BASE_MASK; // out->data[0] Take the lower bits. + out->data[1] &= BASE_MASK; // out->data[1] Take the lower bits. + out->data[2] &= BASE_MASK; // out->data[2] Take the lower bits. +} + +/* + * field element reduction, convert 7-ary LongFelem to 4-ary Felem, + * and modulo reduction to all Limbs to [0, 2 ^ 56 + 2 ^ 16) + * Input: + * in[] < 2^126 + * Output: + * out[] < 2^56 + 2^16 + * - out[0] < 2^56 + * - out[1] < 2^56 + * - out[2] < 2^56 + * - out[3] < 2^56 + 2^16 + */ +static void LongFelemReduce(Felem *out, const LongFelem *in) +{ + const uint128_t *pi = in->data; + // p shifts left by 15 + static const LongFelem zeroBase = { + { + (((uint128_t)1 << 112) - ((uint128_t)1 << 96) + 1) << 15, // 2^127 - 2^111 + 2^15 + (((uint128_t)1 << 112) - ((uint128_t)1 << 56)) << 15, // 2^127 - 2^71 + (((uint128_t)1 << 112) - ((uint128_t)1 << 56)) << 15, // 2^127 - 2^71 + 0, + 0, + 0, + 0, + } + }; + + uint128_t lout[4] = { + zeroBase.data[0] + pi[0], // < 2^127 + 2^126 - 2^111 + 2^15 + zeroBase.data[1] + pi[1], // < 2^127 + 2^126 - 2^71 + zeroBase.data[2] + pi[2], // < 2^127 + 2^126 - 2^71 + pi[3] // < 2^126 + }; + uint128_t carryLimb = pi[4]; // < 2^126 + + // n = n / a * (a - b) ≡ n / a * b (mod (a - b)) + // It can be obtained from the above formula: + // 2^n = 2^(n - 128) - 2^(n - 224) (mod (2^224 - 2^96 + 1)) + // + // The following equation can be listed: + // 2^224 mod p + // = 2^96 - 1 + // + // 2^280 mod p + // = 2^152 - 2^56 + // + // 2^336 mod p + // = 2^208 - 2^112 + + // reduce pi[6] and obtain the part higher 16 bits. + carryLimb += pi[6] >> 16; + // lout[3], reduce pi[6], shift leftwards by 40 bits then truncate; reduce pi[5] and obtain the part higher 16 bits. + lout[3] += ((pi[6] << 40) & BASE_MASK) + (pi[5] >> 16); + // lout[2], reduce pi[5], leftshift by 40bit then truncate; reduce carryLimb, obtain the higher 16bits. reduce pi[6] + lout[2] += ((pi[5] << 40) & BASE_MASK) + (carryLimb >> 16) - pi[6]; + // lout[1], reduce carryLimb, shift leftwards by 40 bits then truncate; reduce pi[5] + lout[1] += ((carryLimb << 40) & BASE_MASK) - pi[5]; + // lout[0], reduce carryLimb + lout[0] -= carryLimb; + + // Range after reduction: + // carryLimb < 2^126 + 2^110 + // lout[3] < 2^126 + 2^56 + 2^110 < 2^127 + // lout[2] < (2^127 + 2^126 - 2^71) + 2^56 + (2^110 + 2^94) < 2^128 + // lout[1] < (2^127 + 2^126 - 2^71) + 2^56 + // lout[0] < 2^127 + 2^126 - 2^111 + 2^15 < 2^128 + + // carry + lout[3] += lout[2] >> BASE_BITS; // lout[3] < 2^127 + 2^72 < 2^128 + carryLimb = lout[3] >> BASE_BITS; // carryLimb < 2^72 + + lout[2] &= BASE_MASK; // lout[2] < 2^56 + lout[3] &= BASE_MASK; // lout[3] < 2^56 + + // reduce carryLimb + // lout[2],reduce carryLimb and obtain the part higher 16 bits. + lout[2] += carryLimb >> 16; + // lout[1],reduce carryLimb, shift leftwards by 40 bits then truncate; + lout[1] += (carryLimb << 40) & BASE_MASK; + // lout[0],reduce carryLimb + lout[0] -= carryLimb; + + // Range after reduction: + // lout[2] < 2^56 + 2^56 + // lout[1] < (2^127 + 2^126 - 2^71 + 2^56) + 2^56 + // lout[0] < 2^128 + + // carry + lout[1] += lout[0] >> BASE_BITS; // lout[1] < (2^127 + 2^126 - 2^71 + 2^57 - 2^41) + 2^72 + lout[2] += lout[1] >> BASE_BITS; // lout[2] < 2^57 + (2^71 + 2^70 + 2^16 - 2^15 + 1) < 2^72 + + out->data[0] = (uint64_t)lout[0] & BASE_MASK; // out->data[0] < 2^56 + out->data[1] = (uint64_t)lout[1] & BASE_MASK; // out->data[1] < 2^56 + out->data[2] = (uint64_t)lout[2] & BASE_MASK; // out->data[2] < 2^56 + out->data[3] = (uint64_t)lout[3] + (uint64_t)(lout[2] >> BASE_BITS); // out->data[3] < 2^56 + 2^16 +} + +/* + * field element modulo in [0, p), call FelemReduce or LongFelemReduce in advance. + * Input: + * in[] < 2^56 + 2^16 + * - in[0] < 2^56 + * - in[1] < 2^56 + * - in[2] < 2^56 + * - in[3] < 2^56 + 2^16 + * Output: + * out < p, out[i] < 2^56 + */ +static void FelemContract(Felem *out, const Felem *in) +{ + Felem tmp = {{in->data[0], in->data[1], in->data[2], in->data[3] & BASE_MASK}}; // tmp[] < 2^56 + uint64_t carryLimb = in->data[3] >> BASE_BITS; // 0 or 1, because of in[3] < 2^56 + 2^16 + uint64_t mask; // Check the mask greater than or equal to p. + + const uint64_t lower40Mask = 0x000000ffffffffff; // Lower 40-bit mask + const uint64_t borrow = (uint64_t)1 << BASE_BITS; + const uint64_t lend = 1; + + // Check whether tmp is greater than or equal to p. The upper 128 bits of p are all 1s and the lower 96 bits are 1. + // If the upper 128 bits (digit 3, 2, and 1) are all 1s, the value is 1. Otherwise, the value is 0. + mask = ((tmp.data[3] & tmp.data[2] & (tmp.data[1] | lower40Mask)) + 1) >> BASE_BITS; + // If the lower 96 bits are not zero, the value is 1. Otherwise, the value is 0. + mask &= (0 - ((tmp.data[1] & lower40Mask) | tmp.data[0])) >> (LIMB_BITS - 1); + mask = 0 - mask; // If tmp is greater than or equal to p, the value is 1. Otherwise, the value is 0. + + // reduce carryLimb or subtract p. Note that carryLimb and mask cannot be true at the same time. + // p_0 = 0x0000000000000001 + tmp.data[0] = (tmp.data[0] ^ borrow) - carryLimb - (mask & FIELD_ORDER.data[0]); + // p_1 = 0x00ffff0000000000 + tmp.data[1] += carryLimb << 40; // reduction carryLimb * 2^(56 + 40) + // If the value is less than p, remains unchanged. If it's greater than or equal to p, subtract 0x00ffff0000000000. + // That is, the lower 40 bits remain unchanged, and other bits are set to 0. + tmp.data[1] &= ~mask | lower40Mask; + // Lend to the low bit: if reduce it, then 2^96 - 1 > 0, if minus p, then tmp[1] + tmp[0] > p_1 + p_2 + tmp.data[1] -= lend; + + // If the value is less than p, remains unchanged. If it's greater than or equal to p, subtract 0x00ffffffffffffff. + // That is, set to 0. + tmp.data[2] &= ~mask; // p_2 = 0x00ffffffffffffff + + // If the value is less than p, remains unchanged. If it's greater than or equal to p, subtract 0x00ffffffffffffff. + // That is, set to 0. + tmp.data[3] &= ~mask; // p_3 = 0x00ffffffffffffff + + // carry 0 -> 1 -> 2 -> 3 + out->data[0] = tmp.data[0] & BASE_MASK; // tmp.data[0] get the lower bits. + out->data[1] = (tmp.data[1] += tmp.data[0] >> BASE_BITS) & BASE_MASK; // tmp.data[1] plus carry & get the lower bits + out->data[2] = (tmp.data[2] += tmp.data[1] >> BASE_BITS) & BASE_MASK; // tmp.data[2] plus carry & get the lower bits + out->data[3] = (tmp.data[3] += tmp.data[2] >> BASE_BITS) & BASE_MASK; // tmp.data[3] plus carry & get the lower bits +} + +/* + * field Addition + */ +static inline void FelemAdd(Felem *out, const Felem *a, const Felem *b) +{ + out->data[0] = a->data[0] + b->data[0]; // out->data[0] takes the value + out->data[1] = a->data[1] + b->data[1]; // out->data[1] takes the value + out->data[2] = a->data[2] + b->data[2]; // out->data[2] takes the value + out->data[3] = a->data[3] + b->data[3]; // out->data[3] takes the value +} + +/* + * field element negation(NOT) + * Input: + * in[] <= 2^57 - 2^41 - 2^1 + * Output: + * out[] <= 2^57 + 2^1 + in[] < 2^64 + */ +static inline void FelemNeg(Felem *out, const Felem *in) +{ + static const Felem zeroBase = {{ + (((uint64_t)1 << 56) + 1) << 1, + (((uint64_t)1 << 56) - ((uint64_t)1 << 40) - 1) << 1, + (((uint64_t)1 << 56) - 1) << 1, + (((uint64_t)1 << 56) - 1) << 1, + }}; + + out->data[0] = zeroBase.data[0] - in->data[0]; // out->data[0] takes the value + out->data[1] = zeroBase.data[1] - in->data[1]; // out->data[1] takes the value + out->data[2] = zeroBase.data[2] - in->data[2]; // out->data[2] takes the value + out->data[3] = zeroBase.data[3] - in->data[3]; // out->data[3] takes the value +} + +/* + * field subtraction + * Input: + * a[] < 2^64 - 2^60 - 2^4,b[] <= 2^60 - 2^44 - 2^4 + * Output: + * out[] <= 2^60 + 2^4 + a[] < 2^64 + */ +static inline void FelemSub(Felem *out, const Felem *a, const Felem *b) +{ + static const Felem zeroBase = {{ + (((uint64_t)1 << 56) + 1) << 4, + (((uint64_t)1 << 56) - ((uint64_t)1 << 40) - 1) << 4, + (((uint64_t)1 << 56) - 1) << 4, + (((uint64_t)1 << 56) - 1) << 4, + }}; + + out->data[0] = zeroBase.data[0] + a->data[0] - b->data[0]; // out->data[0] takes the value + out->data[1] = zeroBase.data[1] + a->data[1] - b->data[1]; // out->data[1] takes the value + out->data[2] = zeroBase.data[2] + a->data[2] - b->data[2]; // out->data[2] takes the value + out->data[3] = zeroBase.data[3] + a->data[3] - b->data[3]; // out->data[3] takes the value +} + +/* + * field subtraction, input LongFelem directly. + * Input: + * a[] < 2^128 - 2^124,b[] <= 2^124 - 2^68 - 2^52 + * Output: + * out[] <= 2^124 + a[] < 2^128 + */ +static void LongFelemSub(LongFelem *out, const LongFelem *a, const LongFelem *b) +{ + // p shift left (8 + 56 * 3) + static const LongFelem zeroBase = {{ + ((uint128_t)1 << 112) << 12, + (((uint128_t)1 << 112) - ((uint128_t)1 << 56)) << 12, + (((uint128_t)1 << 112) - ((uint128_t)1 << 56)) << 12, + (((uint128_t)1 << 112) - ((uint128_t)1 << 56)) << 12, + (((uint128_t)1 << 112) - ((uint128_t)1 << 56) + 1) << 12, // 1 + (((uint128_t)1 << 112) - ((uint128_t)1 << 56) - ((uint128_t)1 << 40)) << 12, // -2^96 + (((uint128_t)1 << 112) - ((uint128_t)1 << 56)) << 12, // 2^224 + }}; + + out->data[0] = zeroBase.data[0] + a->data[0] - b->data[0]; // out->data[0] takes the value + out->data[1] = zeroBase.data[1] + a->data[1] - b->data[1]; // out->data[1] takes the value + out->data[2] = zeroBase.data[2] + a->data[2] - b->data[2]; // out->data[2] takes the value + out->data[3] = zeroBase.data[3] + a->data[3] - b->data[3]; // out->data[3] takes the value + out->data[4] = zeroBase.data[4] + a->data[4] - b->data[4]; // out->data[4] takes the value + out->data[5] = zeroBase.data[5] + a->data[5] - b->data[5]; // out->data[5] takes the value + out->data[6] = zeroBase.data[6] + a->data[6] - b->data[6]; // out->data[6] takes the value +} + +/* + * field element magnification + * Use only a small magnification factor to ensure that in[]*scalar does not overflow. + */ +static inline void FelemScale(Felem *out, const Felem *in, const uint32_t scalar) +{ + out->data[0] = in->data[0] * scalar; // out->data[0] takes the value + out->data[1] = in->data[1] * scalar; // out->data[1] takes the value + out->data[2] = in->data[2] * scalar; // out->data[2] takes the value + out->data[3] = in->data[3] * scalar; // out->data[3] takes the value +} + +/* + * field element magnification, input LongFelem directly. + * Use only a small magnification factor to ensure that in[]*scalar does not overflow. + */ +static inline void LongFelemScale(LongFelem *out, const LongFelem *in, const uint32_t scalar) +{ + out->data[0] = in->data[0] * scalar; // out->data[0] takes the value + out->data[1] = in->data[1] * scalar; // out->data[1] takes the value + out->data[2] = in->data[2] * scalar; // out->data[2] takes the value + out->data[3] = in->data[3] * scalar; // out->data[3] takes the value + out->data[4] = in->data[4] * scalar; // out->data[4] takes the value + out->data[5] = in->data[5] * scalar; // out->data[5] takes the value + out->data[6] = in->data[6] * scalar; // out->data[6] takes the value +} + +/* + * field Multiplication + * Input: + * a[] < 2^62, b[] < 2^62 + * output: + * out[] < a[] * b[] * 4 < 2^126 + * - out[0] < 2^124 + * - out[1] < 2^124 * 2 + * - out[2] < 2^124 * 3 + * - out[3] < 2^124 * 4 + * - out[4] < 2^124 * 3 + * - out[5] < 2^124 * 2 + * - out[6] < 2^124 + */ +static void FelemMul(LongFelem *out, const Felem *a, const Felem *b) +{ + // out[0] = a[0]*b[0] + // out[1] = a[0]*b[1] + a[1]*b[0] + // out[2] = a[0]*b[2] + a[1]*b[1] + a[2]*b[0] + // out[3] = a[0]*b[3] + a[1]*b[2] + a[2]*b[1] + a[3]*b[0] + // out[4] = a[1]*b[3] + a[2]*b[2] + a[3]*b[1] + // out[5] = a[2]*b[3] + a[3]*b[2] + // out[6] = a[3]*b[3] + + uint128_t *po = out->data; + const uint64_t *pa = a->data; + const uint64_t *pb = b->data; + + po[0] = (uint128_t)pa[0] * pb[0]; + po[1] = (uint128_t)pa[0] * pb[1] + (uint128_t)pa[1] * pb[0]; + po[2] = (uint128_t)pa[0] * pb[2] + (uint128_t)pa[1] * pb[1] + (uint128_t)pa[2] * pb[0]; + po[3] = (uint128_t)pa[0] * pb[3] + (uint128_t)pa[1] * pb[2] + (uint128_t)pa[2] * pb[1] + (uint128_t)pa[3] * pb[0]; + po[4] = (uint128_t)pa[1] * pb[3] + (uint128_t)pa[2] * pb[2] + (uint128_t)pa[3] * pb[1]; + po[5] = (uint128_t)pa[2] * pb[3] + (uint128_t)pa[3] * pb[2]; + po[6] = (uint128_t)pa[3] * pb[3]; +} + +/* + * field Square + * Input: + * a[] < 2^62 + * output: + * out[] < a[] * a[] * 4 < 2^126 + * - out[0] < 2^124 + * - out[1] < 2^124 * 2 + * - out[2] < 2^124 * 3 + * - out[3] < 2^124 * 4 + * - out[4] < 2^124 * 3 + * - out[5] < 2^124 * 2 + * - out[6] < 2^124 + */ +static void FelemSqr(LongFelem *out, const Felem *a) +{ + // out[0] = a[0]*a[0] + // out[1] = a[0]*a[1]*2 + // out[2] = a[0]*a[2]*2 + a[1]*a[1] + // out[3] = a[0]*a[3]*2 + a[1]*a[2]*2 + // out[4] = a[1]*a[3]*2 + a[2]*a[2] + // out[5] = a[2]*a[3]*2 + // out[6] = a[3]*a[3] + + const uint64_t *pa = a->data; + + uint64_t a1x2 = pa[1] << 1; + uint64_t a2x2 = pa[2] << 1; + + out->data[0] = (uint128_t)pa[0] * pa[0]; + out->data[1] = (uint128_t)pa[0] * a1x2; + out->data[2] = (uint128_t)pa[0] * a2x2 + (uint128_t)pa[1] * pa[1]; + out->data[3] = ((uint128_t)pa[0] * pa[3] + (uint128_t)pa[1] * pa[2]) << 1; + out->data[4] = (uint128_t)pa[3] * a1x2 + (uint128_t)pa[2] * pa[2]; + out->data[5] = (uint128_t)pa[3] * a2x2; + out->data[6] = (uint128_t)pa[3] * pa[3]; +} + +static inline void FelemMulReduce(Felem *out, const Felem *a, const Felem *b) +{ + LongFelem ltmp; + FelemMul(<mp, a, b); + LongFelemReduce(out, <mp); +} + +static inline void FelemSqrReduce(Felem *out, const Felem *in) +{ + LongFelem ltmp; + FelemSqr(<mp, in); + LongFelemReduce(out, <mp); +} + +/* + * field element inversion + * From Fermat's small theorem, in^(p - 2) = in^(-1) (mod p) + * in^(-1) = in^(2^224 - 2^96 + 1 - 2) (mod p) + * Input: + * in[i] < 2^63 + * Output: + * reduce(out[i]) + */ +static void FelemInv(Felem *out, const Felem *in) +{ + Felem inE1, inE6, inE24, inE96; // inEx indicates in^(2^(0)+2^(1)+'''+2^(x-1)) + uint32_t i; + + // Construct inE1 + FelemReduce(out, in); + FelemAssign(&inE1, out); + + // Construct inE2 + FelemSqrReduce(out, out); + FelemMulReduce(out, out, &inE1); + + // Construct inE4, and store it in inE6 + FelemAssign(&inE6, out); + FelemSqrReduce(&inE6, &inE6); + FelemSqrReduce(&inE6, &inE6); + FelemMulReduce(&inE6, out, &inE6); // inE6 is temporarily stored in inE4 + + // Construct in^6 + FelemSqrReduce(&inE6, &inE6); + FelemSqrReduce(&inE6, &inE6); + FelemMulReduce(&inE6, out, &inE6); + + // Construct inE12 + FelemAssign(out, &inE6); + for (i = 0; i < 6; ++i) { // Moves the out by 6 digits to the left. + FelemSqrReduce(out, out); + } + FelemMulReduce(out, &inE6, out); + + // Construct inE24 + FelemAssign(&inE96, out); + for (i = 0; i < 12; ++i) { // Moves the out by 12 digits to the left. + FelemSqrReduce(out, out); + } + FelemMulReduce(&inE24, &inE96, out); + + // Construct inE48 + FelemAssign(out, &inE24); + for (i = 0; i < 24; ++i) { // Moves the out by 24 digits to the left. + FelemSqrReduce(out, out); + } + FelemMulReduce(out, &inE24, out); + + // Construct inE96 + FelemAssign(&inE96, out); + for (i = 0; i < 48; ++i) { // Moves the out by 48 digits to the left. + FelemSqrReduce(out, out); + } + FelemMulReduce(&inE96, &inE96, out); + + // Construct inE7, and store it in inE6 + FelemSqrReduce(&inE6, &inE6); + FelemMulReduce(&inE6, &inE6, &inE1); + + // Construct inE31, and store it in inE24 + for (i = 0; i < 7; ++i) { // Moves the inE24 by 7 digits to the left. + FelemSqrReduce(&inE24, &inE24); + } + FelemMulReduce(&inE24, &inE6, &inE24); + + // Construct inE127, and store it in inE24 + FelemAssign(out, &inE96); + for (i = 0; i < 31; ++i) { // Moves the out by 31 digits to the left. + FelemSqrReduce(out, out); + } + FelemMulReduce(&inE24, &inE24, out); + + // Move inE127 by 97 bits to the left and add inE97 to obtain inE(2^224 - 2^96 + 1 - 2) + for (i = 0; i < 97; ++i) { // shifts inE24 to the left by 97 bits, and inE24 stores inE127. + FelemSqrReduce(&inE24, &inE24); + } + FelemMulReduce(out, &inE96, &inE24); +} + +/* --------------------------Point group operation-------------------------- */ +static inline void PtAssign(Point *out, const Point *in) +{ + FelemAssign(&out->x, &in->x); + FelemAssign(&out->y, &in->y); + FelemAssign(&out->z, &in->z); +} + +static inline void PtAssignWithMask(Point *out, const Point *in, const uint64_t mask) +{ + FelemAssignWithMask(&out->x, &in->x, mask); + FelemAssignWithMask(&out->y, &in->y, mask); + FelemAssignWithMask(&out->z, &in->z, mask); +} + +/* + * double the point + * Algorithm reference: http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * Number of field operations: 3M + 5S + * delta = Z^2 + * gamma = Y^2 + * beta = X * gamma + * alpha = 3 * (X - delta) * (X + delta) + * X' = alpha^2 - 8 * beta + * Z' = (Y + Z)^2 - gamma - delta + * Y' = alpha * (4 * beta - X') - 8 * gamma^2 + * Input: + * in->x[] < 2^59, in->y[] < 2^61, in->z[] < 2^61 + * Output: + * reduce(out->x), reduce(out->y), out->z[] < 2^61 + */ +static void PtDouble(Point *out, const Point *in) +{ + Felem delta, gamma, beta, alpha; + Felem tmp, tmp2; + LongFelem ltmp, ltmp2; + + // delta = Z^2 + FelemSqrReduce(&delta, &in->z); + + // gamma = Y^2 + FelemSqrReduce(&gamma, &in->y); + + // beta = X * gamma + FelemMulReduce(&beta, &in->x, &gamma); + + // alpha = 3 * (X - delta) * (X + delta) + FelemAdd(&tmp, &in->x, &delta); // tmp[] < 2^59 + 2^57 < 2^60 + FelemScale(&tmp, &tmp, 3); // tmp[] < 2^60 * 3 < 2^62 + FelemSub(&tmp2, &in->x, &delta); // tmp2[] < 2^60 + 2^4 + 2^59 < 2^61 + FelemMulReduce(&alpha, &tmp, &tmp2); + + // X' = alpha^2 - 8 * beta + FelemSqrReduce(&tmp, &alpha); // alpha^2, tmp[] < 2^56 + 2^16 + FelemScale(&tmp2, &beta, 8); // tmp2[] < (2^56 + 2^16) * 8 = 2^59 + 2^19 + FelemSub(&out->x, &tmp, &tmp2); // xout[] < 2^60 + 2^4 + 2^56 + 2^16 < 2^61 + FelemReduce(&out->x, &out->x); // xout[] < 2^56 + 2^7 + + // Z' = (Y + Z)^2 - gamma - delta + FelemAdd(&tmp, &in->y, &in->z); // < 2^61 + 2^61 = 2^62 + FelemSqrReduce(&tmp, &tmp); // (Y + Z)^2, tmp[] < 2^56 + 2^16 + FelemAdd(&tmp2, &gamma, &delta); // (gamma + delta), tmp2[] < (2^56 + 2^16) * 2 = 2^57 + 2^17 + FelemSub(&out->z, &tmp, &tmp2); // zout[] < 2^60 + 2^4 + 2^56 + 2^16 < 2^61 + + // Y' = alpha * (4 * beta - X') - 8 * gamma^2 + FelemScale(&tmp, &beta, 4); // tmp[] < (2^56 + 2^16) * 4 = 2^58 + 2^18 + FelemSub(&tmp, &tmp, &out->x); // tmp[] < 2^60 + 2^4 + 2^58 + 2^18 < 2^61 + FelemMul(<mp, &alpha, &tmp); // alpha * (4 * beta - X'), ltmp[] < 2^(61 * 2) * 4 = 2^124 + FelemSqr(<mp2, &gamma); // gamma < 2^57, ltmp2[] < 2^(57 * 2) * 4 = 2^116 + LongFelemScale(<mp2, <mp2, 8); // 8 * gamma^2, ltmp2[] < 2^116 * 8 = 2^119 + LongFelemSub(<mp, <mp, <mp2); // ltmp[] < 2^124 + 2^124 < 2^125 + LongFelemReduce(&out->y, <mp); // yout[] < 2^56 + 2^16 +} + +/* + * point addition + * Algorithm reference: http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl + * Infinity point calculation is not supported. + * Number of field operations: 11M + 5S + * Z1Z1 = Z1^2 + * Z2Z2 = Z2^2 + * U1 = X1 * Z2Z2 + * U2 = X2 * Z1Z1 + * S1 = Y1 * Z2 * Z2Z2 + * S2 = Y2 * Z1 * Z1Z1 + * H = U2 - U1 + * I = (2 * H)^2 + * J = H * I + * r = 2 * (S2 - S1) + * V = U1 * I + * X3 = r^2 - J - 2 * V + * Y3 = r * (V - X3) - 2 * S1 * J + * Z3 = ((Z1 + Z2)^2 - Z1Z1 - Z2Z2) * H + * Input: + * a->x[] < 2^64, a->y[] < 2^64, a->z[] < 2^61 + * reduce(b->x), b->y[] < 2^58, reduce(b->z) + * Output: + * out->x[] < max(reduce(out->x), a->x[]) + * out->y[] < max(reduce(out->y), a->y[], b->y[]) + * out->z[] < max(reduce(out->z), a->z[]) + */ +static void PtAdd(Point *out, const Point *a, const Point *b) +{ + Point result; + Felem z1sqr, z2sqr, u1, u2, s1, s2, h, i, j, r, v; + Felem tmp; + LongFelem ltmp, ltmp2; + uint64_t isZ1Zero, isZ2Zero; + + // Z1Z1 = Z1^2 + FelemSqrReduce(&z1sqr, &a->z); + + // Z2Z2 = Z2^2 + FelemSqrReduce(&z2sqr, &b->z); + + isZ1Zero = 0 - FelemIsZero(&z1sqr); + isZ2Zero = 0 - FelemIsZero(&z2sqr); + + // U1 = X1 * Z2Z2 + FelemMulReduce(&u1, &a->x, &z2sqr); + + // U2 = X2 * Z1Z1 + FelemMulReduce(&u2, &b->x, &z1sqr); + + // S1 = Y1 * Z2 * Z2Z2 + FelemMulReduce(&s1, &b->z, &z2sqr); // Z2 * Z2Z2 + FelemMulReduce(&s1, &a->y, &s1); + + // S2 = Y2 * Z1 * Z1Z1 + FelemMulReduce(&s2, &a->z, &z1sqr); // Z1 * Z1Z1 + FelemMulReduce(&s2, &b->y, &s2); + + // H = U2 - U1 + FelemSub(&h, &u2, &u1); + FelemReduce(&h, &h); + + // r = 2 * (S2 - S1) + FelemSub(&r, &s2, &s1); + FelemScale(&r, &r, 2); // 2 * (S2 - S1) + FelemReduce(&r, &r); + + // H and r can determine whether x and y of the affine coordinates of two points are equal. + // If the values are equal, double the values. + if (isZ1Zero == 0 && isZ2Zero == 0 && FelemIsZero(&h) != 0 && FelemIsZero(&r) != 0) { + // Use the smaller b point + PtDouble(out, b); + return; + } + + // I = (2 * H)^2 + FelemScale(&tmp, &h, 2); + FelemSqrReduce(&i, &tmp); + + // J = H * I + FelemMulReduce(&j, &h, &i); + + // V = U1 * I + FelemMulReduce(&v, &u1, &i); + + // X3 = r^2 - (J + 2 * V) + FelemSqrReduce(&result.x, &r); // r^2 + FelemScale(&tmp, &v, 2); // tmp[] < (2^56 + 2^16) * 2 = 2^57 + 2^17 + FelemAdd(&tmp, &tmp, &j); // J + 2 * V, tmp[] < (2^57 + 2^17) + (2^56 + 2^16) < 2^58 + FelemSub(&result.x, &result.x, &tmp); // result.x[] < (2^60 + 2^4) + (2^56 + 2^16) < 2^61 + FelemReduce(&result.x, &result.x); // result.x[] < 2^56 + 2^7 + + // Y3 = r * (V - X3) - 2 * S1 * J + FelemSub(&tmp, &v, &result.x); // tmp < (2^60 + 2^4) + (2^56 + 2^16) < 2^61 + FelemMul(<mp, &r, &tmp); // r * (V - X3), ltmp[] < 2^57 * 2^61 * 4 = 2^120 + FelemMul(<mp2, &s1, &j); // ltmp2[] < 2^57 * 2^57 * 4 = 2^116 + LongFelemScale(<mp2, <mp2, 2); // 2 * S1 * J, ltmp2[] < 2^117 + LongFelemSub(<mp, <mp, <mp2); // ltmp[] < 2^124 + 2^120 < 2^125 + LongFelemReduce(&result.y, <mp); // result.y[] < 2^56 + 2^16 + + // Z3 = ((Z1 + Z2)^2 - Z1Z1 - Z2Z2) * H + FelemAdd(&result.z, &a->z, &b->z); // Z1 + Z2, result.z[] < 2^61 + 2^57 < 2^62 + FelemSqrReduce(&result.z, &result.z); // (Z1 + Z2)^2 + FelemAdd(&tmp, &z1sqr, &z2sqr); // Z1Z1 + Z2Z2 + FelemSub(&result.z, &result.z, &tmp); // ((Z1 + Z2)^2 - Z1Z1 - Z2Z2) + FelemMulReduce(&result.z, &result.z, &h); // result.z[] < 2^56 + 2^16 + + // Special case processing for infinity points + PtAssignWithMask(&result, a, isZ2Zero); + PtAssignWithMask(&result, b, isZ1Zero); + PtAssign(out, &result); +} + +/* + * mixed addition of point + * Algorithm reference: http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-madd-2007-bl + * Infinity point calculation is not supported. + * Number of field operations: 7M + 4S + * Z1Z1 = Z1^2 + * U2 = X2 * Z1Z1 + * S2 = Y2 * Z1 * Z1Z1 + * H = U2 - X1 + * HH = H^2 + * I = 4 * HH + * J = H * I + * r = 2 * (S2 - Y1) + * V = X1 * I + * X3 = r^2 - J - 2 * V + * Y3 = r * (V - X3) - 2 * Y1 * J + * Z3 = (Z1 + H)^2 - Z1Z1 - HH + * Input: + * a->x[] <= 2^60 - 2^44 - 2^4, a->y[] <= 2^60 - 2^44 - 2^4, a->z[] < 2^61 + * b->x < p, b->y < p, b->z = 0 or 1 + * Output: + * out->x[] < max(reduce(out->x), a->x[]) + * out->y[] < max(reduce(out->y), a->y[]) + * out->z[] < 2^61 + */ +static void PtAddMixed(Point *out, const Point *a, const Point *b) +{ + Point result; + Felem z1sqr, u2, s2, h, hsqr, i, j, r, v; + Felem tmp; + LongFelem ltmp, ltmp2; + uint64_t isZ1Zero, isZ2Zero; + + // Z1Z1 = Z1^2 + FelemSqrReduce(&z1sqr, &a->z); + + isZ1Zero = 0 - FelemIsZero(&z1sqr); + // The Z coordinate of point b can only be 0 or 1, that is, the bit 0 can only be 0 or 1, and the other bits are 0. + isZ2Zero = b->z.data[0] - 1; + + // U2 = X2 * Z1Z1 + FelemMulReduce(&u2, &b->x, &z1sqr); + + // S2 = Y2 * Z1 * Z1Z1 + FelemMulReduce(&s2, &a->z, &z1sqr); // Z1 * Z1Z1 + FelemMulReduce(&s2, &b->y, &s2); + + // H = U2 - X1 + FelemSub(&h, &u2, &a->x); + FelemReduce(&h, &h); + + // r = 2 * (S2 - Y1) + FelemSub(&r, &s2, &a->y); // r[] < (2^60 + 2^4) + (2^56 + 2^16) < 2^61 + FelemScale(&r, &r, 2); // r[] < 2^62 + FelemReduce(&r, &r); + + // H and r can determine whether x and y of the affine coordinates of two points are equal. + // If they are equal, double the point. + if (isZ1Zero == 0 && isZ2Zero == 0 && FelemIsZero(&h) != 0 && FelemIsZero(&r) != 0) { + // Use the smaller b point + PtDouble(out, b); + return; + } + + // HH = H^2 + FelemSqrReduce(&hsqr, &h); + + // I = 4 * HH + FelemScale(&i, &hsqr, 4); // i[] < (2^56 + 2^16) * 4 = 2^58 + 2^18 + + // J = H * I + FelemMulReduce(&j, &h, &i); + + // V = X1 * I + FelemMulReduce(&v, &a->x, &i); + + // X3 = r^2 - J - 2 * V + FelemSqrReduce(&result.x, &r); // r^2 + FelemScale(&tmp, &v, 2); // 2 * V, tmp[] < (2^56 + 2^16) * 2 = 2^57 + 2^17 + FelemAdd(&tmp, &j, &tmp); // J + 2 * V, tmp[] < (2^56 + 2^16) + (2^57 + 2^17) < 2^58 + FelemSub(&result.x, &result.x, &tmp); // result.x[] < (2^60 + 2^4) + (2^56 + 2^16) < 2^61 + FelemReduce(&result.x, &result.x); // result.x[] < 2^56 + 2^7 + + // Y3 = r * (V - X3) - 2 * Y1 * J + FelemSub(&tmp, &v, &result.x); // V - X3, tmp[] < (2^60 + 2^4) + (2^56 + 2^16) < 2^61 + FelemMul(<mp, &r, &tmp); // r * (V - X3), ltmp[] < 2^57 * 2^61 * 4 = 2^120 + FelemMul(<mp2, &a->y, &j); // Y1 * J, ltmp2[] < 2^61 * 2^57 * 4 = 2^120 + LongFelemScale(<mp2, <mp2, 2); // 2 * Y1 * J, ltmp2[] < 2^120 * 2 = 2^121 + LongFelemSub(<mp, <mp, <mp2); // ltmp[] < 2^124 + 2^120 < 2^125 + LongFelemReduce(&result.y, <mp); // result.y[] < 2^56 + 2^16 + + // Z3 = (Z1 + H)^2 - Z1Z1 - HH + FelemAdd(&result.z, &a->z, &h); // Z1 + H, result.z[] < 2^61 + (2^56 + 2^7) = 2^62 + FelemSqrReduce(&result.z, &result.z); + FelemAdd(&tmp, &z1sqr, &hsqr); // Z1Z1 + HH, tmp[] < (2^56 + 2^16) + (2^56 + 2^16) < 2^58 + FelemSub(&result.z, &result.z, &tmp); // result.z[] < (2^60 + 2^4) + 2^58 < 2^61 + + // Special case processing for infinity points + PtAssignWithMask(&result, a, isZ2Zero); + PtAssignWithMask(&result, b, isZ1Zero); + PtAssign(out, &result); +} + +/* Select the point that subscript is index in the table and place it in the Point *point. + The anti-side channel processing exists. */ +static inline void GetPointFromTable(Point *point, const Point table[], uint32_t pointNum, const uint32_t index) +{ + uint64_t mask; + for (uint32_t i = 0; i < pointNum; i++) { + /* If i is equal to index, the last mask is all Fs. Otherwise, the last mask is all 0s. */ + mask = (0 - (i ^ index)) >> 31; // shifted rightwards by 31 bits to get the most significant bit + mask--; + /* Conditional value assignment, valid only when i == index */ + PtAssignWithMask(point, &table[i], mask); + } +} + +/* + * Input: + * k1 < n + * 0 <= i < 28 + * Output: + * out->x < p, out->y < p, out->z = 0 OR 1 + */ +static inline void GetUpperPrecomputePtOfG(Point *out, const Felem *k1, int32_t curBit) +{ + uint32_t bits; + uint32_t i = (uint32_t)curBit; + + // The i bit of the upper half of digit 0. (BASE_BITS/2) is half-wide. + bits = (uint32_t)(k1->data[0] >> (i + BASE_BITS / 2)) & 1; + // The i bit of the upper half of digit 1. (BASE_BITS/2) is half-wide. + bits |= ((uint32_t)(k1->data[1] >> (i + BASE_BITS / 2)) & 1) << 1; + // The i bit of the upper half of digit 2. (BASE_BITS/2) is half-wide. + bits |= ((uint32_t)(k1->data[2] >> (i + BASE_BITS / 2)) & 1) << 2; + // The i bit of the upper half of digit 3. (BASE_BITS/2) is half-wide. + bits |= ((uint32_t)(k1->data[3] >> (i + BASE_BITS / 2)) & 1) << 3; + + GetPointFromTable(out, PRE_MUL_G2, TABLE_G_SIZE, bits); +} + +/* + * Input: + * k1 < n + * 0 <= i < 28 + * Output: + * out->x < p, out->y < p, out->z = 0 or 1 + */ +static inline void GetLowerPrecomputePtOfG(Point *out, const Felem *k1, int32_t curBit) +{ + uint32_t bits; + uint32_t i = (uint32_t)curBit; + + bits = (uint32_t)(k1->data[0] >> i) & 1; // The i bit of the lower half of digit 0. + bits |= ((uint32_t)(k1->data[1] >> i) & 1) << 1; // The i bit of the lower half of digit 1. + bits |= ((uint32_t)(k1->data[2] >> i) & 1) << 2; // The i bit of the lower half of digit 2. + bits |= ((uint32_t)(k1->data[3] >> i) & 1) << 3; // The i bit of the lower half of digit 3. + + GetPointFromTable(out, PRE_MUL_G, TABLE_G_SIZE, bits); +} + +/* + * Input: + * k2 < n + * 0 <= i <= 220 + * The coordinates of each point of preMulPt are reduced. + * Output: + * reduce(out->x) + * out->y[] < max(reduce(out->y), negY) + * reduce(out->z) + */ +static inline void GetPrecomputePtOfP(Point *out, const Felem *k2, int32_t curBit, const Point preMulPt[TABLE_P_SIZE]) +{ + uint32_t bits; + uint32_t sign, value; // the grouping sign and actual value. + Felem negY; + // Obtain the 5-bit signed code and read the sign bits of the next group of numbers + // to determine whether there is a carry. The total length is 6. + bits = (uint32_t)FelemGetBits(k2, curBit - 1, WINDOW_SIZE + 1); + DecodeScalarCode(&sign, &value, bits); + + GetPointFromTable(out, preMulPt, TABLE_P_SIZE, value); + + // out->y < 2^56 + 2^16 + FelemNeg(&negY, &out->y); // negY[] < (2^57 + 2^1) + (2^56 + 2^16) < 2^58 + FelemAssignWithMask(&out->y, &negY, (uint64_t)0 - sign); +} + +/* + * Calculate k1 * G + k2 * P + * Input: + * k1 < n + * k2 < n + * The coordinates of each point of preMulPt are reduced. + * Output: + * out->x < p, out->y < p, out->z < p + */ +static void PtMul(Point *out, const Felem *k1, const Felem *k2, const Point preMulPt[TABLE_P_SIZE]) +{ + Point ptQ = {}; // ptQ stores result + Point ptPre = {}; // ptPre stores the points obtained from the table. + bool isGMul = k1 != NULL; + bool isPtMul = k2 != NULL && preMulPt != NULL; + int32_t curBit; + + // Initialize the Q point. + if (isPtMul) { + curBit = 220; // Start from 220th bit. + // From k2's (_, 223, 222, 221, 220, 219) bit coding to select the initial point + GetPrecomputePtOfP(&ptQ, k2, curBit, preMulPt); + } else if (isGMul) { + curBit = 27; // Start from 27th. + // From k1's (195, 139, 83, 27) bit coding to select the initial point + GetLowerPrecomputePtOfG(&ptQ, k1, curBit); + // From k1's (195 + 28, 139 + 28, 83 + 28, 27 + 28) bit to select the pre-calculation point + // and adds it to the point Q. + GetUpperPrecomputePtOfG(&ptPre, k1, curBit); + PtAddMixed(&ptQ, &ptQ, &ptPre); + } else { + // k1 and k2 are all NULL, and the infinite point is output. + (void)memset_s((void *)out, sizeof(Point), 0, sizeof(Point)); + return; + } + + // Operation chain: point Q output range: + // x[] y[] z[] + // Initialization the value reduced reduced < 2^61 + // ↓ + // Double ←↑ reduced reduced < 2^61 + // ↓ ↑ + // mixed add ↑ reduced reduced < 2^61 + // ↓ ↑ + // mixed add →↑ reduced reduced < 2^61 + // ↓ ↑ + // negation of Y ↑ reduced < 2^58 < 2^61 + // ↓ ↑ + // add →↑ reduced < 2^58 < 2^61 + + while (--curBit >= 0) { + // Start to shift right bit by bit. Due to the initialization of the most significant bit, + // common point multiplication starts from 219th bit and base point multiplication starts from 26th bit. + // Whether G-point multiplication is performed in the current cycle, + // calculated once in each cycle starting from bit 27. + bool isStepGMul = curBit <= 27; + // Whether the current cycle is a common point multiplication, calculated once every 5 cycles + bool isStepPtMul = curBit % WINDOW_SIZE == 0; + + PtDouble(&ptQ, &ptQ); + + // Generator G multiplication part + // Divide k1 into eight segments, from high bits to low bits, + // select bits from each segment and combine them together, and read the pre-computation table. + // To reduce the precomputation table, + // the divided eight segments are combined according to the upper half and the lower half + if (isGMul && isStepGMul) { + // Add the point multiplication result of the current bit of the eight-segment to the point Q + GetLowerPrecomputePtOfG(&ptPre, k1, curBit); + PtAddMixed(&ptQ, &ptQ, &ptPre); + + GetUpperPrecomputePtOfG(&ptPre, k1, curBit); + PtAddMixed(&ptQ, &ptQ, &ptPre); + } + + // Common point multiplication part + // Use the sliding window signed encoding method + // to group the most significant bits to the least significant bits every five bits. + // Each group of numbers is regarded as a signed number. 00000 to 01111 are decimal numbers 0 to 15, + // and 10000 to 11111 are decimal numbers (32-16) to (32-1). + // This is equivalent to the set the number in complement form after the number carries 1. + // for example + // 11011(Complement) = 100000 - 00101 + if (isPtMul && isStepPtMul) { + // Add the point multiplication result of the current group to the point Q. + GetPrecomputePtOfP(&ptPre, k2, curBit, preMulPt); + PtAdd(&ptQ, &ptQ, &ptPre); + } + } + + // Refer to the output range of the operation chain. Reduce the Y and Z coordinates. + FelemReduce(&ptQ.y, &ptQ.y); + FelemReduce(&ptQ.z, &ptQ.z); + // do the modulo operation then output. + FelemContract(&ptQ.x, &ptQ.x); + FelemContract(&ptQ.y, &ptQ.y); + FelemContract(&ptQ.z, &ptQ.z); + + PtAssign(out, &ptQ); +} + +/* + * Convert Jacobian coordinates to affine coordinates by a given module inverse + */ +static void PtMakeAffineWithInv(Point *out, const Point *in, const Felem *zInv) +{ + Felem tmp; + + // 1/Z^2 + FelemSqrReduce(&tmp, zInv); + + // X/Z^2 + FelemMulReduce(&out->x, &in->x, &tmp); + FelemContract(&out->x, &out->x); + + // 1/Z^3 + FelemMulReduce(&tmp, &tmp, zInv); + + // Y/Z^3 + FelemMulReduce(&out->y, &in->y, &tmp); + FelemContract(&out->y, &out->y); + + FelemSetLimb(&out->z, 1); +} + +/* + * Obtain the pre-multiplication table of the input point pt, including 0pt-16pt. + * The coordinates of all points are reduced. + */ +static int32_t GetPreMulPt(Point preMulPt[TABLE_P_SIZE], const ECC_Point *pt) +{ + int32_t ret; + + // 0pt + (void)memset_s((void *)&preMulPt[0], sizeof(Point), 0, sizeof(Point)); + // 1pt + GOTO_ERR_IF_EX(BN2Felem(&preMulPt[1].x, pt->x), ret); + GOTO_ERR_IF_EX(BN2Felem(&preMulPt[1].y, pt->y), ret); + GOTO_ERR_IF_EX(BN2Felem(&preMulPt[1].z, pt->z), ret); + // 2pt ~ 15pt + for (uint32_t i = 2; i < 15; i += 2) { + PtDouble(&preMulPt[i], &preMulPt[i >> 1]); + // Z coordinate after the doubled point is reduced. + FelemReduce(&preMulPt[i].z, &preMulPt[i].z); + + PtAdd(&preMulPt[i + 1], &preMulPt[i], &preMulPt[1]); + } + // 16pt + PtDouble(&preMulPt[16], &preMulPt[16 >> 1]); + // Z coordinate of the 16pt after the doubled point 16pt is reduced. + FelemReduce(&preMulPt[16].z, &preMulPt[16].z); +ERR: + return ret; +} + +int32_t ECP224_PointMulAdd( + ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt) +{ + int32_t retVal; + Felem fK1; + Felem fK2; + Point preMulPt[TABLE_P_SIZE]; + Point out; + + // Check the input parameters. + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP224), retVal); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP224), retVal); + GOTO_ERR_IF(CheckBnValid(k1, FELEM_BITS), retVal); + GOTO_ERR_IF(CheckBnValid(k2, FELEM_BITS), retVal); + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP224), retVal); + // Special treatment of infinity points + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + + GOTO_ERR_IF_EX(BN2Felem(&fK1, k1), retVal); + GOTO_ERR_IF_EX(BN2Felem(&fK2, k2), retVal); + GOTO_ERR_IF_EX(GetPreMulPt(preMulPt, pt), retVal); + + PtMul(&out, &fK1, &fK2, preMulPt); + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), retVal); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), retVal); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), retVal); +ERR: + return retVal; +} + +int32_t ECP224_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + int32_t retVal; + Felem felemK; + Point preMulPt[TABLE_P_SIZE]; + Point out; + + // Check the input parameters. + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP224), retVal); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP224), retVal); + GOTO_ERR_IF(CheckBnValid(k, FELEM_BITS), retVal); + if (pt != NULL) { + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP224), retVal); + // Special treatment of infinity points + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + } + + GOTO_ERR_IF_EX(BN2Felem(&felemK, k), retVal); + // When pt is NULL, r = k * G + if (pt == NULL) { + PtMul(&out, &felemK, NULL, NULL); + } else { // If pt is not null, r = k * pt + GOTO_ERR_IF_EX(GetPreMulPt(preMulPt, pt), retVal); + PtMul(&out, NULL, &felemK, preMulPt); + } + + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), retVal); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), retVal); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), retVal); +ERR: + return retVal; +} + +int32_t ECP224_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt) +{ + int32_t retVal; + Point out; + Felem zInv; + + // Check the input parameters. + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP224), retVal); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP224), retVal); + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP224), retVal); + // Special treatment of infinity points + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + + GOTO_ERR_IF_EX(BN2Felem(&out.x, pt->x), retVal); + GOTO_ERR_IF_EX(BN2Felem(&out.y, pt->y), retVal); + GOTO_ERR_IF_EX(BN2Felem(&out.z, pt->z), retVal); + + FelemInv(&zInv, &out.z); + PtMakeAffineWithInv(&out, &out, &zInv); + + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), retVal); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), retVal); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), retVal); +ERR: + return retVal; +} + + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP224) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ diff --git a/crypto/ecc/src/ecp_nistp224.h b/crypto/ecc/src/ecp_nistp224.h new file mode 100644 index 00000000..169c09b3 --- /dev/null +++ b/crypto/ecc/src/ecp_nistp224.h @@ -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 ECP_NISTP224_H +#define ECP_NISTP224_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_CURVE_NISTP224) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include "ecc_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Convert the point information pt to the affine coordinate system and refresh the data to r. + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param pt [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP224_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt); + +/** + * @brief Calculate r = k1 * G + k2 * pt + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param k1 [IN] Scalar 1, with a maximum of 224 bits + * @param k2 [IN] Scalar 2, with a maximum of 224 bits + * @param pt [IN] Point data + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP224_PointMulAdd( + ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); + +/** + * @brief If pt != NULL, calculate r = k * pt; otherwise, calculate r = k * G + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param k [IN] scalar with a maximum of 224 bits. + * @param pt [IN] Point data, which can be set to NULL. + * + * @retval CRYPT_SUCCESS set successfully + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP224_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); + +#ifdef __cplusplus +} +#endif + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP224) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ + +#endif diff --git a/crypto/ecc/src/ecp_nistp256.h b/crypto/ecc/src/ecp_nistp256.h new file mode 100644 index 00000000..9d2dfcae --- /dev/null +++ b/crypto/ecc/src/ecp_nistp256.h @@ -0,0 +1,86 @@ +/* + * 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 ECP_NISTP256_H +#define ECP_NISTP256_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include "ecc_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Convert the point information pt to the affine coordinate system and refresh the data to r. + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param pt [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP256_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt); + +/** + * @brief Calculate r = k1 * G + k2 * pt + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param k1 [IN] Scalar 1, with a maximum of 256 bits + * @param k2 [IN] Scalar 2, with a maximum of 256 bits + * @param pt [IN] Point data + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP256_PointMulAdd(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); + +/** + * @brief If pt != NULL, calculate r = k * pt; Otherwise, calculate r = k * G + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param k [IN] Scalar, with a maximum of 256 bits + * @param pt [IN] Point data, which can be set to NULL. + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP256_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); + +/** + * @brief Calculate r = 1/a mod para->n + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output modulus inverse value + * @param a [IN] input BigNum that needs to be inverted. + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP256_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a); + +#ifdef __cplusplus +} +#endif + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ + +#endif diff --git a/crypto/ecc/src/ecp_nistp521.c b/crypto/ecc/src/ecp_nistp521.c new file mode 100644 index 00000000..6d632a51 --- /dev/null +++ b/crypto/ecc/src/ecp_nistp521.c @@ -0,0 +1,1528 @@ +/* + * 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_CURVE_NISTP521) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "ecc_utils.h" + +typedef __uint128_t uint128_t; + + +#define FELEM_BITS 521 +/* Each element of a BigNum array is carried by 2 ^ 58 */ +#define BASE_BITS 58 +/* The length of a BigNum array is 9: 58 * 9 = 522 > 521 */ +#define NUM_LIMBS 9 +/* Mask with 58 bits */ +#define MASK_58BITS ((uint64_t)0x3FFFFFFFFFFFFFF) +/* Mask with 57 bits */ +#define MASK_57BITS ((uint64_t)0x1FFFFFFFFFFFFFF) +/* The pre-calculation table of the G table has 16 points. */ +#define TABLE_G_SIZE 16 +/* The pre-calculation table of the P table has 17 points. */ +#define TABLE_P_SIZE 17 +/* Forcibly convert to uint128_t */ +#define U128(x) ((uint128_t)(x)) + +/* Obtain the nth bit of a BigNum. The BigNum is stored in the uint64_t array in little-endian order. */ +#define GET_ARRAY64_BIT(k, n) ((((k)->data)[(n) / 64] >> ((n) & 63)) & 1) + +typedef struct { + uint64_t data[NUM_LIMBS]; +} Array64; + +typedef struct { + uint64_t data[NUM_LIMBS]; +} Felem; + +typedef struct { + uint128_t data[NUM_LIMBS]; +} LongFelem; + +typedef struct { + Felem x, y, z; /* Each point contains three coordinates x, y, and z. */ +} Point; + +/* + * The point type (Point) contains three field elements (Felem) (x, y, and z). + * Each field element consists of nine 64-bit data blocks (uint64_t). + * Point :pt + * Felem :x + * uint64_t :x[9] + * Felem :y + * uint64_t :y[9] + * Felem :z + * uint64_t :z[9] + */ + +static inline void FelemToArray64(Array64 *array, const Felem *felem) +{ + uint32_t shift = 0; + for (int32_t i = 0; i + 1 < NUM_LIMBS; i++) { + array->data[i] = (felem->data[i] >> shift) | (felem->data[i + 1] << (BASE_BITS - shift)); // i < 8, shift < 48 + /* Felem is carried 1 every 58 bits, and array is carried 1 every 64 bits. The difference is 6 bits. */ + shift += 6; + } + array->data[8] = felem->data[8] >> shift; /* felem->data[8] is the last data block. */ +} + +static inline void Array64ToFelem(Felem *felem, const Array64 *array) +{ + uint32_t shift = 0; + felem->data[0] = array->data[0] & MASK_58BITS; + for (int32_t i = 1; i < NUM_LIMBS; i++) { + /* Felem is carried 1 every 58 bits, and array is carried 1 every 64 bits. The difference is 6 bits. */ + shift += 6; + felem->data[i] = ((array->data[i - 1] >> (64 - shift)) | (array->data[i] << shift)) & MASK_58BITS; + } +} + +static inline void FelemAssign(Felem *r, const Felem *a) +{ + r->data[0] = a->data[0]; // r->data[0] take the value + r->data[1] = a->data[1]; // r->data[1] take the value + r->data[2] = a->data[2]; // r->data[2] take the value + r->data[3] = a->data[3]; // r->data[3] take the value + r->data[4] = a->data[4]; // r->data[4] take the value + r->data[5] = a->data[5]; // r->data[5] take the value + r->data[6] = a->data[6]; // r->data[6] take the value + r->data[7] = a->data[7]; // r->data[7] take the value + r->data[8] = a->data[8]; // r->data[8] take the value +} + +static inline void FelemPointAssign(Point *ptR, const Point *ptIn) +{ + FelemAssign(&ptR->x, &ptIn->x); + FelemAssign(&ptR->y, &ptIn->y); + FelemAssign(&ptR->z, &ptIn->z); +} + +static inline void FelemAssignWithMask(Felem *r, const Felem *a, uint64_t mask) +{ + uint64_t rmask = ~mask; + r->data[0] = (a->data[0] & mask) | (r->data[0] & rmask); // r->data[0] Obtain a new value or remain unchanged. + r->data[1] = (a->data[1] & mask) | (r->data[1] & rmask); // r->data[1] Obtain a new value or remain unchanged. + r->data[2] = (a->data[2] & mask) | (r->data[2] & rmask); // r->data[2] Obtain a new value or remain unchanged. + r->data[3] = (a->data[3] & mask) | (r->data[3] & rmask); // r->data[3] Obtain a new value or remain unchanged. + r->data[4] = (a->data[4] & mask) | (r->data[4] & rmask); // r->data[4] Obtain a new value or remain unchanged. + r->data[5] = (a->data[5] & mask) | (r->data[5] & rmask); // r->data[5] Obtain a new value or remain unchanged. + r->data[6] = (a->data[6] & mask) | (r->data[6] & rmask); // r->data[6] Obtain a new value or remain unchanged. + r->data[7] = (a->data[7] & mask) | (r->data[7] & rmask); // r->data[7] Obtain a new value or remain unchanged. + r->data[8] = (a->data[8] & mask) | (r->data[8] & rmask); // r->data[8] Obtain a new value or remain unchanged. +} + +static inline void FelemPointAssignWithMask(Point *ptR, const Point *ptIn, uint64_t mask) +{ + FelemAssignWithMask(&ptR->x, &ptIn->x, mask); + FelemAssignWithMask(&ptR->y, &ptIn->y, mask); + FelemAssignWithMask(&ptR->z, &ptIn->z, mask); +} + +static inline void FelemSetLimb(Felem *felem, const uint64_t a) +{ + felem->data[0] = a; // r->data[0] take the value of a + felem->data[1] = 0; // r->data[1] clear to 0 + felem->data[2] = 0; // r->data[2] clear to 0 + felem->data[3] = 0; // r->data[3] clear to 0 + felem->data[4] = 0; // r->data[4] clear to 0 + felem->data[5] = 0; // r->data[5] clear to 0 + felem->data[6] = 0; // r->data[6] clear to 0 + felem->data[7] = 0; // r->data[7] clear to 0 + felem->data[8] = 0; // r->data[8] clear to 0 +} + +static inline void LongFelemMulLimb(LongFelem *r, const LongFelem *a, uint64_t limb) +{ + r->data[0] = a->data[0] * limb; // r->data[0] take the value + r->data[1] = a->data[1] * limb; // r->data[1] take the value + r->data[2] = a->data[2] * limb; // r->data[2] take the value + r->data[3] = a->data[3] * limb; // r->data[3] take the value + r->data[4] = a->data[4] * limb; // r->data[4] take the value + r->data[5] = a->data[5] * limb; // r->data[5] take the value + r->data[6] = a->data[6] * limb; // r->data[6] take the value + r->data[7] = a->data[7] * limb; // r->data[7] take the value + r->data[8] = a->data[8] * limb; // r->data[8] take the value +} + +static inline void FelemMulLimb(Felem *r, const Felem *a, uint64_t b) +{ + r->data[0] = a->data[0] * b; // r->data[0] take the value + r->data[1] = a->data[1] * b; // r->data[1] take the value + r->data[2] = a->data[2] * b; // r->data[2] take the value + r->data[3] = a->data[3] * b; // r->data[3] take the value + r->data[4] = a->data[4] * b; // r->data[4] take the value + r->data[5] = a->data[5] * b; // r->data[5] take the value + r->data[6] = a->data[6] * b; // r->data[6] take the value + r->data[7] = a->data[7] * b; // r->data[7] take the value + r->data[8] = a->data[8] * b; // r->data[8] take the value +} + +static inline void FelemAdd(Felem *r, const Felem *a, const Felem *b) +{ + r->data[0] = a->data[0] + b->data[0]; // r->data[0] take the value + r->data[1] = a->data[1] + b->data[1]; // r->data[1] take the value + r->data[2] = a->data[2] + b->data[2]; // r->data[2] take the value + r->data[3] = a->data[3] + b->data[3]; // r->data[3] take the value + r->data[4] = a->data[4] + b->data[4]; // r->data[4] take the value + r->data[5] = a->data[5] + b->data[5]; // r->data[5] take the value + r->data[6] = a->data[6] + b->data[6]; // r->data[6] take the value + r->data[7] = a->data[7] + b->data[7]; // r->data[7] take the value + r->data[8] = a->data[8] + b->data[8]; // r->data[8] take the value +} + +/* + * input: + * a->data[i] < 7*2^61 + * b->data[i] < 2^60 - 2^3 + * output: + * r->data[i] <= max(a->data[i]) + 2^61 - 2^3 + */ +static inline void FelemSub(Felem *r, const Felem *a, const Felem *b) +{ + r->data[0] = a->data[0] + (MASK_58BITS << 3) - b->data[0]; // b->data[0] < 2^61 - 2^3 + r->data[1] = a->data[1] + (MASK_58BITS << 3) - b->data[1]; // b->data[1] < 2^61 - 2^3 + r->data[2] = a->data[2] + (MASK_58BITS << 3) - b->data[2]; // b->data[2] < 2^61 - 2^3 + r->data[3] = a->data[3] + (MASK_58BITS << 3) - b->data[3]; // b->data[3] < 2^61 - 2^3 + r->data[4] = a->data[4] + (MASK_58BITS << 3) - b->data[4]; // b->data[4] < 2^61 - 2^3 + r->data[5] = a->data[5] + (MASK_58BITS << 3) - b->data[5]; // b->data[5] < 2^61 - 2^3 + r->data[6] = a->data[6] + (MASK_58BITS << 3) - b->data[6]; // b->data[6] < 2^61 - 2^3 + r->data[7] = a->data[7] + (MASK_58BITS << 3) - b->data[7]; // b->data[7] < 2^61 - 2^3 + r->data[8] = a->data[8] + (MASK_57BITS << 3) - b->data[8]; // b->data[8] < 2^60 - 2^3 +} +/* + * input: + * r->data[i] < 2^127 + * a->data[i] < 2^64 - 2^6 + * output: + * r->data[i] <= r->data[i] + 2^64 - 2^6 + */ +static inline void LongFelemDiff(LongFelem *r, const Felem *a) +{ + r->data[0] += (MASK_58BITS << 6) - a->data[0]; // a->data[0] < 2^64 - 2^6 + r->data[1] += (MASK_58BITS << 6) - a->data[1]; // a->data[1] < 2^64 - 2^6 + r->data[2] += (MASK_58BITS << 6) - a->data[2]; // a->data[2] < 2^64 - 2^6 + r->data[3] += (MASK_58BITS << 6) - a->data[3]; // a->data[3] < 2^64 - 2^6 + r->data[4] += (MASK_58BITS << 6) - a->data[4]; // a->data[4] < 2^64 - 2^6 + r->data[5] += (MASK_58BITS << 6) - a->data[5]; // a->data[5] < 2^64 - 2^6 + r->data[6] += (MASK_58BITS << 6) - a->data[6]; // a->data[6] < 2^64 - 2^6 + r->data[7] += (MASK_58BITS << 6) - a->data[7]; // a->data[7] < 2^64 - 2^6 + r->data[8] += (MASK_57BITS << 6) - a->data[8]; // a->data[8] < 2^63 - 2^6 +} + +static inline void FelemNeg(Felem *r, const Felem *a) +{ + r->data[0] = (MASK_58BITS << 3) - a->data[0]; // a->data[0], r->data[0] < 2^61 - 2^3 + r->data[1] = (MASK_58BITS << 3) - a->data[1]; // a->data[1], r->data[1] < 2^61 - 2^3 + r->data[2] = (MASK_58BITS << 3) - a->data[2]; // a->data[2], r->data[2] < 2^61 - 2^3 + r->data[3] = (MASK_58BITS << 3) - a->data[3]; // a->data[3], r->data[3] < 2^61 - 2^3 + r->data[4] = (MASK_58BITS << 3) - a->data[4]; // a->data[4], r->data[4] < 2^61 - 2^3 + r->data[5] = (MASK_58BITS << 3) - a->data[5]; // a->data[5], r->data[5] < 2^61 - 2^3 + r->data[6] = (MASK_58BITS << 3) - a->data[6]; // a->data[6], r->data[6] < 2^61 - 2^3 + r->data[7] = (MASK_58BITS << 3) - a->data[7]; // a->data[7], r->data[7] < 2^61 - 2^3 + r->data[8] = (MASK_57BITS << 3) - a->data[8]; // a->data[8], r->data[8] < 2^60 - 2^3 +} + +/* Calculate r = a / 2, which can be regarded as a cyclic right shift by one bit in the modulo P(2^521-1) field. */ +static inline void FelemDivTwo(Felem *r, const Felem *a) +{ + const uint64_t *pa = a->data; + r->data[0] = (pa[0] >> 1) + ((pa[1] & 1) << 57); // The 57th bit plus the LSB of pa[1] + r->data[1] = (pa[1] >> 1) + ((pa[2] & 1) << 57); // The 57th bit plus the LSB of pa[2] + r->data[2] = (pa[2] >> 1) + ((pa[3] & 1) << 57); // The 57th bit plus the LSB of pa[3] + r->data[3] = (pa[3] >> 1) + ((pa[4] & 1) << 57); // The 57th bit plus the LSB of pa[4] + r->data[4] = (pa[4] >> 1) + ((pa[5] & 1) << 57); // The 57th bit plus the LSB of pa[5] + r->data[5] = (pa[5] >> 1) + ((pa[6] & 1) << 57); // The 57th bit plus the LSB of pa[6] + r->data[6] = (pa[6] >> 1) + ((pa[7] & 1) << 57); // The 57th bit plus the LSB of pa[7] + r->data[7] = (pa[7] >> 1) + ((pa[8] & 1) << 57); // The 57th bit plus the LSB of pa[8] + r->data[8] = (pa[8] >> 1) + ((pa[0] & 1) << 56); // The 56th bit plus the LSB of pa[0] +} + +/* + * reduce to prevent subsequent calculation overflow. + * input: + * in[i] < 2^128 + * output: + * out[i] < 2^59 + 2^14 + */ +static void FelemReduce(Felem *r, const LongFelem *a) +{ + uint64_t tmp; + const uint32_t shift2 = BASE_BITS * 2; // 116 = 58 * 2 + r->data[0] = (uint64_t)(a->data[0] & MASK_58BITS); // r->data[0] < 2^58 + r->data[1] = (uint64_t)(a->data[1] & MASK_58BITS); // r->data[1] < 2^58 + r->data[2] = (uint64_t)(a->data[2] & MASK_58BITS); // r->data[2] < 2^58 + r->data[3] = (uint64_t)(a->data[3] & MASK_58BITS); // r->data[3] < 2^58 + r->data[4] = (uint64_t)(a->data[4] & MASK_58BITS); // r->data[4] < 2^58 + r->data[5] = (uint64_t)(a->data[5] & MASK_58BITS); // r->data[5] < 2^58 + r->data[6] = (uint64_t)(a->data[6] & MASK_58BITS); // r->data[6] < 2^58 + r->data[7] = (uint64_t)(a->data[7] & MASK_58BITS); // r->data[7] < 2^58 + r->data[8] = (uint64_t)(a->data[8] & MASK_58BITS); // r->data[8] < 2^58 + + r->data[1] += (uint64_t)(a->data[0] >> BASE_BITS) & MASK_58BITS; // r->data[1] < 2^59 + r->data[2] += (uint64_t)(a->data[1] >> BASE_BITS) & MASK_58BITS; // r->data[2] < 2^59 + r->data[3] += (uint64_t)(a->data[2] >> BASE_BITS) & MASK_58BITS; // r->data[3] < 2^59 + r->data[4] += (uint64_t)(a->data[3] >> BASE_BITS) & MASK_58BITS; // r->data[4] < 2^59 + r->data[5] += (uint64_t)(a->data[4] >> BASE_BITS) & MASK_58BITS; // r->data[5] < 2^59 + r->data[6] += (uint64_t)(a->data[5] >> BASE_BITS) & MASK_58BITS; // r->data[6] < 2^59 + r->data[7] += (uint64_t)(a->data[6] >> BASE_BITS) & MASK_58BITS; // r->data[7] < 2^59 + r->data[8] += (uint64_t)(a->data[7] >> BASE_BITS) & MASK_58BITS; // r->data[8] < 2^59 + // a->data[8] The most significant bits above 58bits correspond to the most significant bits above 522 bits. + tmp = (uint64_t)(a->data[8] >> BASE_BITS) & MASK_58BITS; + r->data[0] += tmp << 1; // r->data[0] < 3*2^58 + + r->data[2] += (uint64_t)(a->data[0] >> shift2); // r->data[2] < 2^59 + 2^6 + r->data[3] += (uint64_t)(a->data[1] >> shift2); // r->data[3] < 2^59 + 2^6 + r->data[4] += (uint64_t)(a->data[2] >> shift2); // r->data[4] < 2^59 + 2^6, add the upper bits of a[2]116 bits. + r->data[5] += (uint64_t)(a->data[3] >> shift2); // r->data[5] < 2^59 + 2^6, add the upper bits of a[3]116 bits. + r->data[6] += (uint64_t)(a->data[4] >> shift2); // r->data[6] < 2^59 + 2^6, add the upper bits of a[4]116 bits. + r->data[7] += (uint64_t)(a->data[5] >> shift2); // r->data[7] < 2^59 + 2^6, add the upper bits of a[5]116 bits. + r->data[8] += (uint64_t)(a->data[6] >> shift2); // r->data[8] < 2^59 + 2^6, add the upper bits of a[6]116 bits. + // a->data[7] The most significant bits above 116bits correspond to the most significant bits above 522 bits. + tmp = (uint64_t)(a->data[7] >> shift2); + r->data[0] += tmp << 1; // r->data[0] < 3*2^58 + 2^13 + // a->data[8] The most significant bits above 116bits correspond to the most significant bits above 580 bits. + tmp = (uint64_t)(a->data[8] >> shift2); + r->data[1] += tmp << 1; // r->data[1] < 2^59 + 2^13 + + /* Considering that out[0] may be too large, carry needs to be continued. */ + r->data[1] += r->data[0] >> BASE_BITS; // r->data[1] < 2^59 + 2^14 + r->data[0] &= MASK_58BITS; // r->data[0] < 2^58 +} +/* + * Reduce the number of bits to less than 58 to prevent subsequent operation overflow. + * input: + * felem->data[i] < 2^64 - 2^6 + * output: + * felem->data[i] < 2^58 + */ +static void FelemShrink(Felem *felem) +{ + uint64_t carry = 0; /* Carry value between Limb */ + + /* Reduce each limb to less than 58 bits */ + for (int32_t i = 0; i < NUM_LIMBS - 1; i++) { + felem->data[i] += carry; /* plus the carry of the previous block */ + carry = (uint64_t)(felem->data[i] >> BASE_BITS); /* Take the carry of this block. */ + felem->data[i] &= MASK_58BITS; /* 58 bits reserved */ + } + felem->data[NUM_LIMBS - 1] += carry; + carry = felem->data[NUM_LIMBS - 1] >> 57; /* 521 = 58 * 8 + 57, carry the upper bits to the lower bits */ + felem->data[NUM_LIMBS - 1] &= MASK_57BITS; /* The upper bits are discarded, only the lower 521 bits are retained */ + + /* Add the bits above 521 to the lower bits. */ + for (int32_t i = 0; i < NUM_LIMBS; i++) { + felem->data[i] += carry; /* plus the carry of the previous block */ + carry = (uint64_t)(felem->data[i] >> BASE_BITS); /* Take the carry of this block. */ + felem->data[i] &= MASK_58BITS; /* 58 bits reserved */ + } +} + +/* + * Reduce felem to a unique value less than P. + * input: + * felem->data[i] < 2^64 - 2^6 + * output: + * felem->data[i] < 2^58 + * Return value: + * If felem is 0, the mask is all 1s. Otherwise, the mask is 0. + */ +static uint64_t FelemContract(Felem *felem) +{ + uint64_t notP = 0; + uint64_t notZero = 0; + uint64_t mask; + uint64_t carry; + FelemShrink(felem); + + /* After the shrink command is executed, felem->data[i] < 2^58, but it may still be greater than 521 bits. */ + carry = felem->data[NUM_LIMBS - 1] >> 57; /* 521 = 58 * 8 + 57, carry the upper bits to the lower bits */ + felem->data[NUM_LIMBS - 1] &= MASK_57BITS; + /* Add the bits above 521 to the lower bits. */ + for (int32_t i = 0; i < NUM_LIMBS; i++) { + felem->data[i] += carry; /* plus the carry of the previous block */ + carry = (uint64_t)(felem->data[i] >> BASE_BITS); /* Take the carry of this block. */ + felem->data[i] &= MASK_58BITS; /* 58 bits reserved */ + } + + /* Check whether the value is P. */ + for (int32_t i = 0; i < NUM_LIMBS - 1; i++) { + notP |= felem->data[i] ^ MASK_58BITS; /* If the value of felem is P, the value remains 0. */ + } + notP |= felem->data[NUM_LIMBS - 1] ^ MASK_57BITS; + /* The most significant bit is 1 only when notP = 0. In this case, the mask is 0. */ + mask = 0 - ((0 - notP) >> 63); /* Shift rightwards by 63 bits and get the most significant bit. */ + + for (int32_t i = 0; i < NUM_LIMBS; i++) { + felem->data[i] &= mask; /* If the value is P, clear all the bits to 0 */ + notZero |= felem->data[i]; /* an determine whether the value is zero. */ + } + /* only when notZero == 0, the most significant bit is 1. In this case, each bit of the mask is all 1s. */ + mask = ((0 - notZero) >> 63) - 1; /* Shift rightwards by 63 bits and get the most significant bit. */ + return mask; +} + +/* Convert a BigNum to the Felem *. Note that the value cannot be a negative number and cannot be greater than P. */ +static int32_t BN2Felem(Felem *r, const BN_BigNum *a) +{ + int32_t ret; + Array64 array = {0}; + uint32_t len = NUM_LIMBS; + ret = BN_Bn2U64Array(a, array.data, &len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + Array64ToFelem(r, &array); + return CRYPT_SUCCESS; +} + +/* Felem * Convert to BigNum */ +static int32_t Felem2BN(BN_BigNum *r, const Felem *a) +{ + Array64 array = {0}; + uint32_t len = NUM_LIMBS; + Felem felem; + FelemAssign(&felem, a); + FelemContract(&felem); + FelemToArray64(&array, &felem); + return BN_U64Array2Bn(r, array.data, len); +} + +/* + * Calculate r = a * b + * input: + * a->data[i] < 2^63 + * b->data[i] < 2^128 / (17*a[i]) + * output: + * r->data[i] < 17(max(a[i]*b[i])) + */ +static void FelemMul(LongFelem *r, const Felem *a, const Felem *b) +{ + Felem ax2; + const uint64_t *pa = a->data; + const uint64_t *pb = b->data; + const uint64_t *p2 = ax2.data; + /* Because the modulo P is 2^521 - 1, the higher bits above the 521 bits + can be truncated and then added to the lower bits. */ + FelemMulLimb(&ax2, a, 2); + + r->data[0] = U128(pa[0]) * pb[0] + U128(p2[1]) * pb[8] + U128(p2[2]) * pb[7] + // 0 = 0+0, 1+8, 2+7 (mod 9) + U128(p2[3]) * pb[6] + U128(p2[4]) * pb[5] + U128(p2[5]) * pb[4] + // 0 = 3+6, 4+5, 5+4 (mod 9) + U128(p2[6]) * pb[3] + U128(p2[7]) * pb[2] + U128(p2[8]) * pb[1]; // 0 = 6+3, 7+2, 8+1 (mod 9) + + r->data[1] = U128(pa[0]) * pb[1] + U128(pa[1]) * pb[0] + U128(p2[2]) * pb[8] + // 1 = 0+1, 1+0, 2+8 (mod 9) + U128(p2[3]) * pb[7] + U128(p2[4]) * pb[6] + U128(p2[5]) * pb[5] + // 1 = 3+7, 4+6, 5+5 (mod 9) + U128(p2[6]) * pb[4] + U128(p2[7]) * pb[3] + U128(p2[8]) * pb[2]; // 1 = 6+4, 7+3, 8+2 (mod 9) + + r->data[2] = U128(pa[0]) * pb[2] + U128(pa[1]) * pb[1] + U128(pa[2]) * pb[0] + // 2 = 0+2, 1+1, 2+0 (mod 9) + U128(p2[3]) * pb[8] + U128(p2[4]) * pb[7] + U128(p2[5]) * pb[6] + // 2 = 3+8, 4+7, 5+6 (mod 9) + U128(p2[6]) * pb[5] + U128(p2[7]) * pb[4] + U128(p2[8]) * pb[3]; // 2 = 6+5, 7+4, 8+3 (mod 9) + + r->data[3] = U128(pa[0]) * pb[3] + U128(pa[1]) * pb[2] + U128(pa[2]) * pb[1] + // 3 = 0+3, 1+2, 2+1 (mod 9) + U128(pa[3]) * pb[0] + U128(p2[4]) * pb[8] + U128(p2[5]) * pb[7] + // 3 = 3+0, 4+8, 5+7 (mod 9) + U128(p2[6]) * pb[6] + U128(p2[7]) * pb[5] + U128(p2[8]) * pb[4]; // 3 = 6+6, 7+5, 8+4 (mod 9) + + r->data[4] = U128(pa[0]) * pb[4] + U128(pa[1]) * pb[3] + U128(pa[2]) * pb[2] + // 4 = 0+4, 1+3, 2+2 (mod 9) + U128(pa[3]) * pb[1] + U128(pa[4]) * pb[0] + U128(p2[5]) * pb[8] + // 4 = 3+1, 4+0, 5+8 (mod 9) + U128(p2[6]) * pb[7] + U128(p2[7]) * pb[6] + U128(p2[8]) * pb[5]; // 4 = 6+7, 7+6, 8+5 (mod 9) + + r->data[5] = U128(pa[0]) * pb[5] + U128(pa[1]) * pb[4] + U128(pa[2]) * pb[3] + // 5 = 0+5, 1+4, 2+3 (mod 9) + U128(pa[3]) * pb[2] + U128(pa[4]) * pb[1] + U128(pa[5]) * pb[0] + // 5 = 3+2, 4+1, 5+0 (mod 9) + U128(p2[6]) * pb[8] + U128(p2[7]) * pb[7] + U128(p2[8]) * pb[6]; // 5 = 6+8, 7+7, 8+6 (mod 9) + + r->data[6] = U128(pa[0]) * pb[6] + U128(pa[1]) * pb[5] + U128(pa[2]) * pb[4] + // 6 = 0+6, 1+5, 2+4 (mod 9) + U128(pa[3]) * pb[3] + U128(pa[4]) * pb[2] + U128(pa[5]) * pb[1] + // 6 = 3+3, 4+2, 5+1 (mod 9) + U128(pa[6]) * pb[0] + U128(p2[7]) * pb[8] + U128(p2[8]) * pb[7]; // 6 = 6+0, 7+8, 8+7 (mod 9) + + r->data[7] = U128(pa[0]) * pb[7] + U128(pa[1]) * pb[6] + U128(pa[2]) * pb[5] + // 7 = 0+7, 1+6, 2+5 (mod 9) + U128(pa[3]) * pb[4] + U128(pa[4]) * pb[3] + U128(pa[5]) * pb[2] + // 7 = 3+4, 4+3, 5+2 (mod 9) + U128(pa[6]) * pb[1] + U128(pa[7]) * pb[0] + U128(p2[8]) * pb[8]; // 7 = 6+1, 7+0, 8+8 (mod 9) + + r->data[8] = U128(pa[0]) * pb[8] + U128(pa[1]) * pb[7] + U128(pa[2]) * pb[6] + // 8 = 0+8, 1+7, 2+6 (mod 9) + U128(pa[3]) * pb[5] + U128(pa[4]) * pb[4] + U128(pa[5]) * pb[3] + // 8 = 3+5, 4+4, 5+3 (mod 9) + U128(pa[6]) * pb[2] + U128(pa[7]) * pb[1] + U128(pa[8]) * pb[0]; // 8 = 6+2, 7+1, 8+0 (mod 9) +} + +/* + * Calculate r = a^2 + * input: + * a->data[i] < 2^62 - 2^57 + * output: + * r->data[i] < 17*max(a[i]*a[i]) + */ +static void FelemSqr(LongFelem *r, const Felem *a) +{ + Felem ax2; + Felem ax4; + const uint64_t *pa = a->data; + const uint64_t *p2 = ax2.data; + const uint64_t *p4 = ax4.data; + /* Because the modulo P is 2^521 - 1, the higher bits above the 521 bits + can be truncated and then added to the lower bits. */ + FelemMulLimb(&ax2, a, 2); /* ax2 is twice the value of a */ + FelemMulLimb(&ax4, a, 4); /* ax4 is 4 times the value of a */ + + r->data[0] = U128(pa[0]) * pa[0]; // 0 = 0+0 (mod 9) + r->data[1] = U128(p2[5]) * pa[5]; // 1 = 5+5 (mod 9) + r->data[2] = U128(pa[1]) * pa[1]; // 2 = 1+1 (mod 9) + r->data[3] = U128(p2[6]) * pa[6]; // 3 = 6+6 (mod 9) + r->data[4] = U128(pa[2]) * pa[2]; // 4 = 2+2 (mod 9) + r->data[5] = U128(p2[7]) * pa[7]; // 5 = 7+7 (mod 9) + r->data[6] = U128(pa[3]) * pa[3]; // 6 = 3+3 (mod 9) + r->data[7] = U128(p2[8]) * pa[8]; // 7 = 8+8 (mod 9) + r->data[8] = U128(pa[4]) * pa[4]; // 8 = 4+4 (mod 9) + + // r->data[0] < 17*49*2^114 < 2^124 + // 0 = 1+8, 2+7, 3+6, 4+5 (mod 9) + r->data[0] += U128(p4[1]) * pa[8] + U128(p4[2]) * pa[7] + U128(p4[3]) * pa[6] + U128(p4[4]) * pa[5]; + // 1 = 0+1, 2+8, 3+7, 4+6 (mod 9) + r->data[1] += U128(p2[0]) * pa[1] + U128(p4[2]) * pa[8] + U128(p4[3]) * pa[7] + U128(p4[4]) * pa[6]; + // 2 = 0+2, 3+8, 4+7, 5+6 (mod 9) + r->data[2] += U128(p2[0]) * pa[2] + U128(p4[3]) * pa[8] + U128(p4[4]) * pa[7] + U128(p4[5]) * pa[6]; + // 3 = 0+3, 1+2, 4+8, 5+7 (mod 9) + r->data[3] += U128(p2[0]) * pa[3] + U128(p2[1]) * pa[2] + U128(p4[4]) * pa[8] + U128(p4[5]) * pa[7]; + // 4 = 0+4, 1+3, 5+8, 6+7 (mod 9) + r->data[4] += U128(p2[0]) * pa[4] + U128(p2[1]) * pa[3] + U128(p4[5]) * pa[8] + U128(p4[6]) * pa[7]; + // 5 = 0+5, 1+4, 2+3, 6+8 (mod 9) + r->data[5] += U128(p2[0]) * pa[5] + U128(p2[1]) * pa[4] + U128(p2[2]) * pa[3] + U128(p4[6]) * pa[8]; + // 6 = 0+6, 1+5, 2+4, 7+8 (mod 9) + r->data[6] += U128(p2[0]) * pa[6] + U128(p2[1]) * pa[5] + U128(p2[2]) * pa[4] + U128(p4[7]) * pa[8]; + // 7 = 0+7, 1+6, 2+5, 3+4 (mod 9) + r->data[7] += U128(p2[0]) * pa[7] + U128(p2[1]) * pa[6] + U128(p2[2]) * pa[5] + U128(p2[3]) * pa[4]; + // 8 = 0+8, 1+7, 2+6, 3+5 (mod 9) + r->data[8] += U128(p2[0]) * pa[8] + U128(p2[1]) * pa[7] + U128(p2[2]) * pa[6] + U128(p2[3]) * pa[5]; +} + +// Multiply and reduce +static inline void FelemMulReduce(Felem *r, const Felem *a, const Felem *b) +{ + LongFelem tmp; + FelemMul(&tmp, a, b); + FelemReduce(r, &tmp); +} + +// Square and reduce +static inline void FelemSqrReduce(Felem *r, const Felem *in) +{ + LongFelem tmp; + FelemSqr(&tmp, in); + FelemReduce(r, &tmp); +} + +/* + * Calculate r = 1/a (mod P) + * Fermat's Little Theorem: + * a^p = a mod p + * a^(p-1) = 1 mod p + * a^(p-2) = a^(-1) mod p + * Calculate the inverse modulus value according to this formula and: + * p = 2^521 - 1 + * p - 2 = 2^521 - 3 = (2^519 - 1) << 2 + 1 +*/ +static void FelemInv(Felem *r, const Felem *a) +{ + Felem tmp1, tmp2, tmp3; + int32_t bits; + /* Calculate a^e and update the e value until e = p - 2 */ + FelemSqrReduce(&tmp1, a); /* (10) */ + FelemMulReduce(&tmp1, &tmp1, a); /* (11) */ + + FelemSqrReduce(&tmp2, &tmp1); /* (110) */ + FelemMulReduce(&tmp3, &tmp2, a); /* (111) is stored in tmp3 */ + FelemSqrReduce(&tmp2, &tmp2); /* (1100) */ + FelemMulReduce(&tmp1, &tmp2, &tmp1); /* (1111) */ + + FelemSqrReduce(&tmp2, &tmp1); /* (0001 1110) */ + FelemSqrReduce(&tmp2, &tmp2); /* (0011 1100) */ + FelemSqrReduce(&tmp2, &tmp2); /* (0111 1000) */ + FelemMulReduce(&tmp3, &tmp2, &tmp3); /* (0111 1111) is stored in tmp3 */ + FelemSqrReduce(&tmp2, &tmp2); /* (1111 0000) */ + FelemMulReduce(&tmp1, &tmp2, &tmp1); /* 2^8 - 1 */ + + /* The current value of e is (11111111) The value consists of 8 bits */ + bits = 8; + + /* Perform the square & multiplication until the value of e becomes 2 ^ 512 - 1, that is, 512 bits */ + while (bits < 512) { + FelemAssign(&tmp2, &tmp1); + for (int32_t i = 0; i < bits; i++) { /* e value shifts to the left */ + FelemSqrReduce(&tmp2, &tmp2); + } + FelemMulReduce(&tmp1, &tmp2, &tmp1); /* e Change the lower bits 0 to 1, e = 2^bits - 1 */ + /* In this case, the bit length of the e value becomes twice (* 2). */ + bits *= 2; + } + /* In this case, the value of e is 2^512-1 */ + for (int32_t i = 0; i < 7; i++) { /* e value shifts to the left by 7 bits */ + FelemSqrReduce(&tmp1, &tmp1); + } + FelemMulReduce(&tmp1, &tmp1, &tmp3); /* 2^519 - 1, plus the previous &tmp3 */ + + FelemSqrReduce(&tmp1, &tmp1); + FelemSqrReduce(&tmp1, &tmp1); /* (2^519 - 1) << 2 */ + FelemMulReduce(r, &tmp1, a); /* p - 2 */ +} + +/* + * "dbl-2001-b" + * delta = Z1^2 + * gamma = Y1^2 + * beta = X1*gamma + * alpha = 3*(X1-delta)*(X1+delta) + * X3 = alpha^2-8*beta + * Z3 = (Y1+Z1)^2-gamma-delta + * Y3 = alpha*(4*beta-X3)-8*gamma^2 +*/ +/* Calculate the double point coordinates. */ +static void FelemPointDouble(Point *pointOut, const Point *pointIn) +{ + Felem delta, gamma, beta, alpha; + Felem tmp1, tmp2; + LongFelem ltmp1; + + /* delta = Z1^2 */ + FelemSqrReduce(&delta, &pointIn->z); // delta[i] < 2^59 + 2^14 + /* gamma = Y1^2 */ + FelemSqrReduce(&gamma, &pointIn->y); // gamma[i] < 2^59 + 2^14 + /* beta = X1*gamma */ + FelemMulReduce(&beta, &pointIn->x, &gamma); // beta[i] < 2^59 + 2^14 + + /* X1 - delta */ + FelemSub(&tmp1, &pointIn->x, &delta); // tmp1[i] < 9*2^59 + 2^14 + /* X1 + delta */ + FelemAdd(&tmp2, &pointIn->x, &delta); // tmp2[i] < 2^60 + 2^15 + /* 3*(X1 + delta) */ + FelemMulLimb(&tmp2, &tmp2, 3); // tmp2[i] < 6*(2^59 + 2^14) + /* alpha = 3*(X1-delta)*(X1+delta) */ + FelemMulReduce(&alpha, &tmp1, &tmp2); // alpha[i] < 2^59 + 2^14 + + /* alpha^2 */ + FelemSqr(<mp1, &alpha); // ltmp1[i] < 2^125 + /* 8*beta */ + FelemMulLimb(&tmp2, &beta, 8); // tmp2[i] < 2^62 + 2^17 + /* alpha^2-8*beta */ + LongFelemDiff(<mp1, &tmp2); // ltmp1[i] < 2^126 + /* X3 = alpha^2-8*beta */ + FelemReduce(&pointOut->x, <mp1); + + /* Y1+Z1 */ + FelemAdd(&tmp1, &pointIn->y, &pointIn->z); // tmp1[i] < 2^60 + 2^15 + /* (Y1+Z1)^2 */ + FelemSqr(<mp1, &tmp1); // ltmp1[i] < 17*(2^60 + 2^15) + /* gamma+delta */ + FelemAdd(&tmp2, &gamma, &delta); // tmp2[i] < 2^60 + 2^15 + /* (Y1+Z1)^2 - gamma - delta */ + LongFelemDiff(<mp1, &tmp2); + /* Z3 = (Y1+Z1)^2-gamma-delta */ + FelemReduce(&pointOut->z, <mp1); + + /* 4*beta */ + FelemMulLimb(&tmp2, &beta, 4); // tmp2[i] < 2^61 + 2^16 + /* 4*beta-X3 */ + FelemSub(&tmp1, &tmp2, &pointOut->x); // tmp1[i] < 2^62 + 2^16 + FelemShrink(&tmp1); // Subtraction and reduction process can be optimized + /* alpha*(4*beta-X3) */ + FelemMul(<mp1, &alpha, &tmp1); // ltmp1[i] < 2^128 + /* gamma^2 */ + FelemSqrReduce(&tmp2, &gamma); // tmp2[i] < 2^59 + 2^14 + /* 8*gamma^2 */ + FelemMulLimb(&tmp1, &tmp2, 8); // tmp1[i] < 2^62 + 2^17 + /* alpha*(4*beta-X3)-8*gamma^2 */ + LongFelemDiff(<mp1, &tmp1); + /* Y3 = alpha*(4*beta-X3)-8*gamma^2 */ + FelemReduce(&pointOut->y, <mp1); +} + +/* + * "add-2007-bl" + * Z1Z1 = Z1^2 + * Z2Z2 = Z2^2 + * U1 = X1*Z2Z2 + * S1 = Y1*Z2*Z2Z2 + * U2 = X2*Z1Z1 + * S2 = Y2*Z1*Z1Z1 + * H = U2-U1 + * r = 2*(S2-S1) + * I = (2*H)^2 + * J = H*I + * V = U1*I + * X3 = r^2-J-2*V + * Y3 = r*(V-X3)-2*S1*J + * Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H +*/ +/* Calculate the point addition coordinates, pt3 = pt1 + pt2 */ +static void FelemPointAdd(Point *pt3, const Point *pt1, const Point *pt2) +{ + uint64_t pointEqual, xEqual, yEqual, z1Zero, z2Zero; + Felem z1z1, z2z2, u1, u2, s1, s2, h, r, i, j, v, tmp1; + Point res; + LongFelem ltmp1; + + /* Z1Z1 = Z1^2 */ + FelemSqrReduce(&z1z1, &pt1->z); + z1Zero = FelemContract(&z1z1); // z1z1[i] < 2^58 + + /* Z2Z2 = Z2^2 */ + FelemSqrReduce(&z2z2, &pt2->z); + z2Zero = FelemContract(&z2z2); // z2z2[i] < 2^58 + + /* U1 = X1*Z2Z2 */ + FelemMulReduce(&u1, &pt1->x, &z2z2); // u1[i] < 2^59 + 2^14 + + /* S1 = Y1*Z2*Z2Z2 */ + FelemMulReduce(&tmp1, &pt1->y, &pt2->z); + FelemMulReduce(&s1, &tmp1, &z2z2); // s1[i] < 2^59 + 2^14 + + /* U2 = X2*Z1Z1 */ + FelemMulReduce(&u2, &pt2->x, &z1z1); // u2[i] < 2^59 + 2^14 + + /* S2 = Y2*Z1*Z1Z1 */ + FelemMulReduce(&tmp1, &pt2->y, &pt1->z); + FelemMulReduce(&s2, &tmp1, &z1z1); // s2[i] < 2^59 + 2^14 + + /* H = U2-U1 */ + FelemSub(&h, &u2, &u1); + xEqual = FelemContract(&h); // h[i] < 2^58 + + /* r = 2*(S2-S1) */ + FelemSub(&tmp1, &s2, &s1); + yEqual = FelemContract(&tmp1); + /* If the coordinates are equal, use the double point formula. */ + pointEqual = (xEqual & yEqual & (~z1Zero) & (~z2Zero)); + if (pointEqual != 0) { + FelemPointDouble(pt3, pt1); + return; + } + FelemMulLimb(&r, &tmp1, 2); // r[i] < 2^59 + + /* I = (2*h)^2 */ + FelemMulLimb(&tmp1, &h, 2); // tmp1[i] < 2^59 + FelemSqrReduce(&i, &tmp1); + + /* J = H*I */ + FelemMulReduce(&j, &h, &i); // j[i] < 2^59 + 2^14 + + /* v = U1*I */ + FelemMulReduce(&v, &u1, &i); // v[i] < 2^59 + 2^14 + + /* X3 = r^2-j-2*v */ + FelemSqr(<mp1, &r); // ltmp1[i] < 17*2^118 + FelemMulLimb(&tmp1, &v, 2); // tmp1[i] < 2^60 + 2^15 + FelemAdd(&tmp1, &tmp1, &j); // tmp1[i] < 3*(2^59 + 2^14) + LongFelemDiff(<mp1, &tmp1); // ltmp1 < 2^123 + FelemReduce(&res.x, <mp1); // x[i] < 2^59 + 2^14 + + /* Y3 = r*(v-X3)-2*S1*j */ + FelemSub(&tmp1, &v, &res.x); // tmp1[i] < 5*2^59 + 2^14 + FelemMul(<mp1, &r, &tmp1); // ltmp1[i] < 17*(5*2^59 + 2^14)*(2^59) < 2^125 + FelemMulReduce(&tmp1, &s1, &j); // tmp1[i] < 2^59 + 2^14 + FelemMulLimb(&tmp1, &tmp1, 2); // tmp1[i] < 2^60 + 2^15 + LongFelemDiff(<mp1, &tmp1); // ltmp1[i] < 2^125 + 2^64 - 2^6 + FelemReduce(&res.y, <mp1); // y3[i] < 2^59 + 2^14 + + /* Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H */ + FelemAdd(&tmp1, &pt1->z, &pt2->z); // tmp1[i] < 2^60 + 2^15 + FelemSqr(<mp1, &tmp1); // ltmp1[i] < 17*(2^120 + 2^76 + 2^30) + FelemAdd(&tmp1, &z1z1, &z2z2); // tmp1[i] < 2^59 + LongFelemDiff(<mp1, &tmp1); // ltmp1[i] < 2^125 + FelemReduce(&tmp1, <mp1); // tmp1[i] < 2^59 + 2^14 + FelemMulReduce(&res.z, &tmp1, &h); // z3[i] < 2^59 + 2^14 + + FelemPointAssignWithMask(&res, pt2, z1Zero); + FelemPointAssignWithMask(&res, pt1, z2Zero); + FelemPointAssign(pt3, &res); +} + +/* + * "madd-2007-bl" + * Z1Z1 = Z1^2 + * U2 = X2*Z1Z1 + * S2 = Y2*Z1*Z1Z1 + * H = U2-X1 + * r = 2*(S2-Y1) + * HH = H^2 + * I = 4*HH + * J = H*I + * V = X1*I + * X3 = r^2-J-2*V + * Y3 = r*(V-X3)-2*Y1*J + * Z3 = (Z1+H)^2-Z1Z1-HH +*/ +/* Calculate the points coordinates addition in the mixed coordinate system, pt3 = pt1 + pt2, z2 == 1 */ +static void FelemPointMixAdd(Point *pt3, const Point *pt1, const Point *pt2) +{ + uint64_t pointEqual, xEqual, yEqual, z1Zero, z2Zero; + Felem z1z1, h, hh, r, i, j, v, tmp1, tmp2; + Point res; + LongFelem ltmp1; + + /* Z1Z1 = Z1^2 */ + FelemSqrReduce(&z1z1, &pt1->z); + z1Zero = FelemContract(&z1z1); // z1z1[i] < 2^58 + + FelemAssign(&tmp1, &pt2->z); + z2Zero = FelemContract(&tmp1); + + /* U2 = X2*Z1Z1 */ + FelemMulReduce(&tmp2, &pt2->x, &z1z1); // tmp2[i] < 2^59 + 2^14 + + /* S2 = Y2*Z1*Z1Z1 */ + FelemMulReduce(&tmp1, &pt2->y, &pt1->z); + FelemMulReduce(&tmp1, &tmp1, &z1z1); // tmp1[i] < 2^59 + 2^14 + + /* H = U2-X1 */ + FelemSub(&h, &tmp2, &pt1->x); + xEqual = FelemContract(&h); // h[i] < 2^58 + + /* r = 2*(S2-Y1) */ + FelemSub(&tmp1, &tmp1, &pt1->y); + yEqual = FelemContract(&tmp1); + /* If the coordinates are equal, use the double point formula. */ + pointEqual = (xEqual & yEqual & (~z1Zero) & (~z2Zero)); + if (pointEqual != 0) { + FelemPointDouble(pt3, pt1); + return; + } + FelemMulLimb(&r, &tmp1, 2); // r[i] < 2^59 + + /* HH = H^2 */ + FelemSqrReduce(&hh, &h); // hh[i] < 2^59 + 2^14 + + /* I = 4*HH */ + FelemMulLimb(&i, &hh, 4); // i[i] < 2^61 + 2^16 + + /* J = H*I */ + FelemMulReduce(&j, &h, &i); // j[i] < 2^59 + 2^14 + + /* V = X1*I */ + FelemMulReduce(&v, &pt1->x, &i); // v[i] < 2^59 + 2^14 + + /* X3 = r^2-J-2*V */ + FelemMulLimb(&tmp1, &v, 2); // tmp1[i] < 2^60 + 2^15 + FelemAdd(&tmp2, &j, &tmp1); // tmp2[i] < 3*2^59 + 3*2^14 + FelemSqr(<mp1, &r); // ltmp1[i] < 17*2^118 + LongFelemDiff(<mp1, &tmp2); // ltmp1[i] < 2^123 + FelemReduce(&res.x, <mp1); // x3[i] < 2^59 + 2^14 + + /* Y3 = r*(V-X3)-2*Y1*J */ + FelemSub(&tmp1, &v, &res.x); // tmp1[i] < 5*2^59 + 2^14 + FelemMul(<mp1, &r, &tmp1); // ltmp1[i] < 17*(5*2^59 + 2^14)*(2^59) < 2^125 + FelemMulReduce(&tmp2, &pt1->y, &j); // tmp2[i] < 2^59 + 2^14 + FelemMulLimb(&tmp1, &tmp2, 2); // tmp1[i] < 2^60 + 2^15 + LongFelemDiff(<mp1, &tmp1); // ltmp1[i] < 2^125 + 2^64 - 2^6 + FelemReduce(&res.y, <mp1); // y3[i] < 2^59 + 2^14 + + /* Z3 = (Z1+H)^2-Z1Z1-HH */ + FelemAdd(&tmp1, &pt1->z, &h); // tmp1[i] < 3*2^59 + 2^14 + FelemSqr(<mp1, &tmp1); // ltmp1[i] < 17*(9*2^118 + 3*2^74 + 2^28) + FelemAdd(&tmp2, &z1z1, &hh); // tmp2[i] < 3*2^59 + 2^14 + LongFelemDiff(<mp1, &tmp2); // ltmp1[i] < 2^126 + FelemReduce(&res.z, <mp1); // z3[i] < 2^59 + 2^14 + + FelemPointAssignWithMask(&res, pt2, z1Zero); + FelemPointAssignWithMask(&res, pt1, z2Zero); + FelemPointAssign(pt3, &res); +} + +/* + * Y = 2*Y + * W = Z^4 + * while (m > 0) { + * A = 3*(X^2-W) + * B = X*Y^2 + * X = A^2-2*B + * Z = Z*Y + * m = m-1 + * if (m > 0) { + * W = W*Y^4 + * } + * Y = 2*A*(B-X)-Y^4 + * } + * Y = Y/2 +*/ +static void FelemPointMultDouble(Point *pointOut, const Point *pointIn, int32_t m) +{ + Felem x, y, z; + Felem w, a, b; + Felem tmp1, tmp2, tmp3; + LongFelem ltmp1; + int32_t left = m; + if (left == 1) { + FelemPointDouble(pointOut, pointIn); + return; + } + + FelemAssign(&x, &pointIn->x); + FelemAssign(&z, &pointIn->z); + /* Y = 2*Y */ + FelemMulLimb(&y, &pointIn->y, 2); // y[i] < 2^60 + 2^15 + /* W = Z^4 */ + FelemSqrReduce(&tmp1, &pointIn->z); + FelemSqrReduce(&w, &tmp1); // w[i] < 2^59 + 2^14 + while (left > 0) { + /* A = 3*(X^2-W) */ + FelemSqr(<mp1, &x); // ltmp1[i] < 17*(2^118 + 2^74 + 2^28) < 17*(2^118 + 2^75) + LongFelemDiff(<mp1, &w); // ltmp1[i] < 18*2^118 + LongFelemMulLimb(<mp1, <mp1, 3); // ltmp1[i] < 3*18*2^118 < 2^124 + FelemReduce(&a, <mp1); // a[i] < 2^59 + 2^14 + + /* B = X*Y^2 */ + FelemSqrReduce(&tmp3, &y); // tmp3[i] < 2^59 + 2^14, tmp3 = Y^2 + FelemMulReduce(&b, &x, &tmp3); // b[i] < 2^59 + 2^14 + + /* X = A^2-2*B */ + FelemSqr(<mp1, &a); // ltmp1[i] < 17*(2^118 + 2^74 + 2^28) < 17*(2^118 + 2^75) + FelemMulLimb(&tmp1, &b, 2); // tmp1[i] < 2^60 + 2^15 + LongFelemDiff(<mp1, &tmp1); // ltmp1[i] < 18*2^118 + FelemReduce(&x, <mp1); // x[i] < 2^59 + 2^14 + + /* Z = Z*Y */ + FelemMulReduce(&z, &z, &y); // z[i] < 2^59 + 2^14 + FelemSqrReduce(&tmp3, &tmp3); // tmp3[i] < 2^59 + 2^14, tmp3 = Y^4 + left--; + if (left > 0) { + /* W = W*Y^4 */ + FelemMulReduce(&w, &tmp3, &w); // w[i] < 2^59 + 2^14 + } + + /* Y = 2*A*(B-X)-Y^4 */ + FelemMulLimb(&tmp1, &a, 2); // tmp1[i] < 2^60 + 2^15 + FelemSub(&tmp2, &b, &x); // b[i] < 5*2^59 + 2^14 + FelemMul(<mp1, &tmp1, &tmp2); // ltmp1[i] < 17*(5*2^119 + 6*2^74 + 2^29) < 2^126 + LongFelemDiff(<mp1, &tmp3); // ltmp1[i] < 2^126 + 2^64 + FelemReduce(&y, <mp1); + } + + /* Y = Y/2 */ + FelemDivTwo(&pointOut->y, &y); + FelemAssign(&pointOut->x, &x); + FelemAssign(&pointOut->z, &z); +} + +/* + * Pre-computation table of base point G, which contains the X, Y, Z coordinates of n*G. + * + * index corresponding bit Value of n + * 0 0 0 0 0 0 + 0 + 0 + 0 + * 1 0 0 0 1 0 + 0 + 0 + 1 + * 2 0 0 1 0 0 + 0 + 2^130 + 0 + * 3 0 0 1 1 0 + 0 + 2^130 + 1 + * 4 0 1 0 0 0 + 2^260 + 0 + 0 + * 5 0 1 0 1 0 + 2^260 + 0 + 1 + * 6 0 1 1 0 0 + 2^260 + 2^130 + 0 + * 7 0 1 1 1 0 + 2^260 + 2^130 + 1 + * 8 1 0 0 0 2^390 + 0 + 0 + 0 + * 9 1 0 0 1 2^390 + 0 + 0 + 1 + * 10 1 0 1 0 2^390 + 0 + 2^130 + 0 + * 11 1 0 1 1 2^390 + 0 + 2^130 + 1 + * 12 1 1 0 0 2^390 + 2^260 + 0 + 0 + * 13 1 1 0 1 2^390 + 2^260 + 0 + 1 + * 14 1 1 1 0 2^390 + 2^260 + 2^130 + 0 + * 15 1 1 1 1 2^390 + 2^260 + 2^130 + 1 + */ +static const Point PRE_COMPUTE_G[TABLE_G_SIZE] = { + { + {{0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334, + 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8, + 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404}}, + {{0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353, + 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45, + 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad, + 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e, + 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5}}, + {{0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58, + 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c, + 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873, + 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c, + 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9}}, + {{0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52, + 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e, + 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2, + 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561, + 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065}}, + {{0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a, + 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e, + 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6, + 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51, + 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe}}, + {{0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d, + 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c, + 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27, + 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f, + 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256}}, + {{0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa, + 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2, + 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890, + 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74, + 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23}}, + {{0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516, + 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1, + 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce, + 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7, + 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5}}, + {{0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318, + 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83, + 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae, + 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef, + 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203}}, + {{0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447, + 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283, + 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5, + 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c, + 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a}}, + {{0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df, + 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645, + 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292, + 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422, + 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b}}, + {{0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30, + 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb, + 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767, + 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3, + 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf}}, + {{0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2, + 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692, + 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3, + 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade, + 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684}}, + {{0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8, + 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a, + 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608, + 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610, + 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d}}, + {{0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006, + 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86, + 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c, + 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9, + 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f}}, + {{0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7, + 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c, + 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + } +}; + +/* + * Pre-computation table of base point G, which contains the X, Y, Z coordinates of n*G. + * + * index corresponding bit value of n + * 0 0 0 0 0 0 + 0 + 0 + 0 + * 1 0 0 0 1 0 + 0 + 0 + 2^65 + * 2 0 0 1 0 0 + 0 + 2^195 + 0 + * 3 0 0 1 1 0 + 0 + 2^195 + 2^65 + * 4 0 1 0 0 0 + 2^325 + 0 + 0 + * 5 0 1 0 1 0 + 2^325 + 0 + 2^65 + * 6 0 1 1 0 0 + 2^325 + 2^195 + 0 + * 7 0 1 1 1 0 + 2^325 + 2^195 + 2^65 + * 8 1 0 0 0 2^455 + 0 + 0 + 0 + * 9 1 0 0 1 2^455 + 0 + 0 + 2^65 + * 10 1 0 1 0 2^455 + 0 + 2^195 + 0 + * 11 1 0 1 1 2^455 + 0 + 2^195 + 2^65 + * 12 1 1 0 0 2^455 + 2^325 + 0 + 0 + * 13 1 1 0 1 2^455 + 2^325 + 0 + 2^65 + * 14 1 1 1 0 2^455 + 2^325 + 2^195 + 0 + * 15 1 1 1 1 2^455 + 2^325 + 2^195 + 2^65 + */ +static const Point PRE_COMPUTE_G2[TABLE_G_SIZE] = { + { + {{0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x0192b0164b374ff4, 0x037b520497f54a7c, 0x00ac45dfa717d3aa, + 0x012692d390795d21, 0x013153d4af815b65, 0x01dda688f88c3a92, + 0x0205e32bd883b127, 0x025156b962597ab5, 0x00a54cc9cfcf7717}}, + {{0x00fe2ea43f30741f, 0x0144a9495978f5d7, 0x035adaea005bd79c, + 0x009dff281db66901, 0x00166a36786b2593, 0x01d7f68c07aa0052, + 0x013e05225075d36d, 0x03181b67caeea6b5, 0x009004fc6adc182a}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x0287bbca1236bec1, 0x03aaf618239ad718, 0x013ef15fcd3c6c16, + 0x031f697f988c94c6, 0x01ac806cb8d4ee71, 0x0035f8035894c512, + 0x00a16689152cf169, 0x02236a87815c0f48, 0x014f6480d486bbf5}}, + {{0x03f70ab3fe2753e3, 0x03d291808faf7e0d, 0x00d7d89caf63a562, + 0x029ead2c77ee5cd6, 0x022c8c3421387422, 0x02e384f360359525, + 0x01901927d338b4bd, 0x0010c294d54a76b1, 0x00c739a28761a676}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x0321984bf604e26a, 0x00a0a4346e1beaa6, 0x03959055560b38f4, + 0x001c383384c9b58c, 0x013212bf16c0badc, 0x00fc4f13c1530004, + 0x0297632bcdf70503, 0x0306dbd604f5574d, 0x016c53a4d13a129b}}, + {{0x03534a0ccd1d6c44, 0x02279af4660bfa03, 0x030eb700f21771d7, + 0x01134017e2c6529e, 0x0237abadf41d7409, 0x03547fae79ff1ce6, + 0x027b74026ac60650, 0x038912af6d6a8213, 0x00c3257758f97db5}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x037d9850fb6f765b, 0x01b6f2b4333f3817, 0x025e9d97d6f42afe, + 0x00a0ddfdfa42799a, 0x02bfc71aab1b4029, 0x0378d9bd912c361e, + 0x012c4f53cffd5151, 0x03a0621175f5d2ca, 0x0017e0822ef93f88}}, + {{0x03f7c1d7104d2069, 0x03848b7b03f6c63f, 0x003395646b614e53, + 0x0342d1dd97dbc1e9, 0x022cb3def43f2341, 0x02a5f4833f79b757, + 0x037b25687d324787, 0x031f409c8d51daf2, 0x010bb03f98dc9303}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x03efcaf76c0f7bd7, 0x015b1ffdf6ccf484, 0x0263903e662a439d, + 0x036dfdd7c185fe97, 0x015b51f55e640b08, 0x01b1764270cbce73, + 0x01e346d1bb5c8f2a, 0x03199be2199e0b68, 0x004adb8d3d68e650}}, + {{0x019bce039c0da6bf, 0x0280560629ade3b2, 0x01418eb6001c82e3, + 0x01e464b38910b655, 0x02b21034d1a402e4, 0x028c2df0b056c5fa, + 0x032be9714380fe04, 0x01f9ecd5a9a2fcca, 0x015aa21ec32e0387}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x036ad61ba5561dd5, 0x02dab309a8810a66, 0x037393ceee004b75, + 0x001e6bf8a4921c61, 0x0316b2aa5307a051, 0x0014c93b7032e644, + 0x03f6b33b796d11e2, 0x023d7387badaa578, 0x003387854547b6ca}}, + {{0x002d4c5b57434eda, 0x01d6e1888a73d938, 0x0018f0f64605d2fa, + 0x028a20eeb35b0cc6, 0x03b68c858d509955, 0x01141d740c8bd567, + 0x010750725080144c, 0x023d6ac06393f441, 0x0042923f464fb5d1}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x037549a3c618e088, 0x008b414778fa66e4, 0x00723b6b05db1367, + 0x013e930419c79520, 0x0191ed1c4447ff41, 0x00bee132be6a81cb, + 0x02fa7516973beafc, 0x02e25b501cead6d6, 0x01fdb7d1dc08792c}}, + {{0x039cb1f8f679b9d1, 0x0083db2827d85eaf, 0x03b023aa80726182, + 0x022a7457eb1c3efa, 0x03caef438de54158, 0x033997a18583466f, + 0x02d7bffa14e33c59, 0x001b92a9cd69ce59, 0x0113258b03a75ad8}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x0324c5b4c56caae5, 0x0151cedc6869fdbe, 0x039370cf6ff1d385, + 0x00d2d6b3a7948969, 0x0126b6384f3cdb06, 0x02f045c111b79e63, + 0x00519f9f1ede134e, 0x03baffa03938dd55, 0x0179812e76db6349}}, + {{0x00b69f323b354956, 0x01e0bb3f034a976c, 0x02befa0dff80f27c, + 0x0098b221eb08aecb, 0x030ca3bf38ae8e58, 0x01327945cb922185, + 0x0308de377b1b7b43, 0x03ab15750b28636d, 0x0091c1b0482a4305}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x02c1b0be6b746613, 0x00478b27bfbe1387, 0x03ac86e5d9c6a2d3, + 0x034f25d578d34127, 0x014e05b75ec6fecc, 0x01f44f38b4e2189f, + 0x00660fddda38b664, 0x03d587c9195d6412, 0x00e9dcec7d477b78}}, + {{0x03321366097b5fe6, 0x011364f5be162f87, 0x03d074359e750aaa, + 0x01d55171921585a2, 0x022527bb5c6eb7c7, 0x01428f6af0426fe3, + 0x0036bb94e1d4d74e, 0x03c7c757a44dbe6a, 0x0088a86c9ed6cbef}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x02bff33e6cbff097, 0x019cccbe703a64a6, 0x01e7d4c24e09e350, + 0x021908a33eaf46a0, 0x01a07762f8cc7516, 0x01e12df29d8644c9, + 0x0098c656997c8284, 0x0373d9622e713265, 0x01ff6b101932f0be}}, + {{0x0048f9e92e2c1256, 0x033fae66bf45eb34, 0x0341ddb09e352f2b, + 0x0019a6a6560f97fe, 0x02cda473f1bd03ab, 0x013c344018f55636, + 0x00329598b2276e7e, 0x0388a96e2249b63f, 0x00b6d123f38483d2}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x02a97232bae87062, 0x0069587df4826cd5, 0x021402a5fdf14035, + 0x026f406d0b49dc31, 0x01efc862b95739c4, 0x00a6e35dc23a4083, + 0x0385b4e2faa85fd8, 0x01deae552ff5231e, 0x019e03275123852a}}, + {{0x0120d17ebd7a996d, 0x00a56e635a2ab069, 0x03a2d775353348fe, + 0x02c60edc1e521033, 0x01078fbf7ab9fefc, 0x0375262d1601e76e, + 0x00d963629d272a65, 0x027c82575888f1bb, 0x013629c8c2a9841f}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x02634027d95abe73, 0x01c2e2ef1799e9c6, 0x02eedf3cf13b5ffc, + 0x0060e6a5de211043, 0x01a7806f233bb516, 0x0355633a88a8638c, + 0x01dcbcc58d7d5dcc, 0x02071903acda896f, 0x01dce602b80ca444}}, + {{0x013c47920922ddb6, 0x013f221e68d728d8, 0x0128ca5192ab3cb8, + 0x002a19a405f6d544, 0x0074330020d40403, 0x0085611df0ce1a97, + 0x028fda4edff5fc93, 0x0303b834136862a5, 0x00f443f3b7cd86cf}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x00f5614d1673ed2e, 0x03e442a78b43dbb3, 0x02408ebf00c8324c, + 0x0043b6f94f69ea8b, 0x02a32bb5a7c8f6ac, 0x02b7758b243883fa, + 0x00f4bd68881089bf, 0x03f61eb91693a587, 0x001d298cf9f11b0b}}, + {{0x00ee97751d8d6f36, 0x0318dcb929941397, 0x022cf9840311e590, + 0x02fc6b1da06aae09, 0x0134298323032dcf, 0x00d7b9072d9bb059, + 0x01a099906260485b, 0x037d9ca3796ce405, 0x0147a49ba1ca4467}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x030993f7ba6f7b2c, 0x019720e705ec5bc1, 0x001c9ee10167839e, + 0x0378869753d92351, 0x02bb1ace9f456b2e, 0x0336d504d809599d, + 0x02d549f9910bffd0, 0x019c6284b1ec6150, 0x00c67a7fcc4ffb2c}}, + {{0x022fe778c100a1dc, 0x01d14e5e8e693cb1, 0x03c139f63d3a44d9, + 0x01d0b45344a8a5c9, 0x0253f5e630be559d, 0x01eaad81980912b1, + 0x003febb5458d1ece, 0x01c6d59feaae8cfd, 0x01c3558976ca7dd7}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + }, { + {{0x01ec0d67348526ae, 0x0334bb61a85f8ed5, 0x0286ba7fecf2d764, + 0x01600344518c0c0c, 0x034e83852188ae46, 0x023d71754d3c015c, + 0x010eeccfb5a5a825, 0x004247e9a02cded9, 0x0187b9aa607ca24c}}, + {{0x00e77b967bc701ac, 0x022a2a00ef91bdc3, 0x01fa7bfaf46148d2, + 0x003feb6276929d54, 0x028ad7f3a3f075ca, 0x035f6ba48b87bd53, + 0x03fd400e74a80040, 0x0150a714837d88b5, 0x003969fa95c4e093}}, + {{1, 0, 0, 0, 0, 0, 0, 0, 0}} + } +}; + +/* Select the point with subscript index in the table and place it in the point. + The anti-side channel processing exists. */ +static void GetPointFromTable(Point *point, const Point table[], + uint32_t pointNum, const uint64_t index) +{ + uint64_t mask, i; + for (i = 0; i < pointNum; i++) { + /* If i is equal to index, the last mask is all Fs. Otherwise, the last mask is all 0s. */ + /* Shift rightwards by 63 bits and get the most significant bit. */ + mask = (0 - (i ^ index)) >> 63; + mask--; + /* Conditionally assign a value, which takes effect only when i = index. */ + FelemPointAssignWithMask(point, &table[i], mask); + } +} + +/* + * Four bits at a fixed interval are intercepted from the scalar k1, + and then decoded to obtain the index of the precomputation table G + * input: + * k1 indicates a array of scalars, consisting of nine 64-bit data in little-endian order. + * i Corresponding bit. The value is an integer ranging [0, 65] + * output: + * Value range: 0–15, indicating the index of the pre-computation table. + */ +static void GetIndexOfTableG(uint64_t *value1, uint64_t *value2, const Array64 *k1, uint32_t i) +{ + // The scalar k1 contains a maximum of 521 bits. 521 = 65 * 4 * 2 + 1. Therefore, one bit needs special processing. + if (i == 0) { + *value1 = k1->data[0] & 1; // get the least significant bit of the scalar + *value2 = 0; + } else { + uint64_t bits1, bits2; + bits1 = GET_ARRAY64_BIT(k1, i + 390) << 3; // 3rd corresponds to the scalar k1 bit: [391, 455] + bits1 |= GET_ARRAY64_BIT(k1, i + 260) << 2; // 2nd corresponds to the scalar k1 bit: [261, 325] + bits1 |= GET_ARRAY64_BIT(k1, i + 130) << 1; // 1st corresponds to the scalar k1 bit: [131, 195] + bits1 |= GET_ARRAY64_BIT(k1, i); // 0th corresponds to the scalar k1 bit: [1 , 65] + *value1 = bits1; + bits2 = GET_ARRAY64_BIT(k1, i + 455) << 3; // 3rd corresponds to the scalar k1 bit: [456, 520] + bits2 |= GET_ARRAY64_BIT(k1, i + 325) << 2; // 2nd corresponds to the scalar k1 bit: [326, 390] + bits2 |= GET_ARRAY64_BIT(k1, i + 195) << 1; // 1st corresponds to the scalar k1 bit: [196, 260] + bits2 |= GET_ARRAY64_BIT(k1, i + 65); // 0th corresponds to the scalar k1 bit: [66 , 130] + *value2 = bits2; + } +} + +/* + * Six consecutive bits (i-1 to i+4) are intercepted from the scalar k2, + and then decoded to obtain an index of the precomputation table P and a sign of a point + * input: + * k2 indicates a array of scalars, consisting of nine 64-bit data in little-endian order. + * i Corresponding bit. The value range is [0, 520], which can be exactly divisible by 5. + * output: + * sign 0 or 1: indicates whether the corresponding point needs negation. + * value 0-16: indicates the index of the pre-computation table. + */ +static void GetIndexOfTableP(uint64_t *sign, uint64_t *value, const Array64 *k2, uint32_t i) +{ + uint32_t s, v; + uint64_t bits; + if (i == 0) { + // When i is the least significant bit, only the four least significant bits of k2 are truncated. + bits = k2->data[0] << 1; + } else { + uint32_t num = (i - 1) / 64; // Each uint64_t contains 64 bits. + uint32_t shift = (i - 1) % 64; // Each uint64_t contains 64 bits. + bits = (k2->data[num] >> shift); + if (shift + 6 > 64) { // (64 - shift) bits have been truncated. If it is less than 6 bits, continue truncating. + bits |= k2->data[num + 1] << (64 - shift); + } + } + // truncates six bits. (5-bit signed number complement + 1-bit low-order carry flag) + bits &= (1 << (WINDOW_SIZE + 1)) - 1; + + DecodeScalarCode(&s, &v, (uint32_t)bits); + *sign = s; + *value = v; +} + +/* + * Calculation point coordinate r = k1 * G + k2 * P + * input: + * k1 a scalar multiplied by point G. If k1 is null, it will be not calculated. + * k2 a scalar multiplied by point P. If k1 is null, it will be not calculated. + * preCompute P-point precalculation table (0P, 1P, ... 16P) 17 points in total. + * output: + * r Point of the calculation result + */ +static void FelemPointMul(Point *r, const Array64 *k1, const Array64 *k2, + const Point preCompute[TABLE_P_SIZE]) +{ + Point res = {0}; // res is initialized to 0. + Point tmp = {0}; + Felem negY; + uint64_t mask, sign, index, index2; + bool computeG = k1 != NULL; + bool computeP = k2 != NULL; + bool isZero = true; // Whether the res point is zero. + int32_t step = computeP ? 5 : 1; // Times of one cycle multiple the point + /* P point multiplication requires 520 times, and G point multiplication requires 65 times. */ + for (int32_t i = computeP ? 520 : 65; i >= 0; i -= step) { + /* If the point out remains zero, the double point operation has no effect, skipping */ + if (!isZero) { + FelemPointMultDouble(&res, &res, step); + } + // Calculate the multiplication of point G. i starts calculation in the range [0, 65]. + if (computeG && (i <= 65)) { + /* If the G-point multiplication starts, the step of the multiple point needs to be changed to 1. */ + step = 1; + /* Obtain the corresponding bits. */ + GetIndexOfTableG(&index, &index2, k1, (uint32_t)i); + /* Add the points in Table 1 */ + if (isZero) { + /* If the point out is zero, the point addition operation is equivalent to direct assignment. */ + GetPointFromTable(&res, PRE_COMPUTE_G, TABLE_G_SIZE, index); + isZero = false; + } else { + GetPointFromTable(&tmp, PRE_COMPUTE_G, TABLE_G_SIZE, index); + // precomputation table G is all affine coordinates, use the hybrid coordinates for acceleration. + FelemPointMixAdd(&res, &res, &tmp); + } + /* Add the points in Table 2 */ + if (i != 0) { + GetPointFromTable(&tmp, PRE_COMPUTE_G2, TABLE_G_SIZE, index2); + // precomputation table G2 is all affine coordinates, use the hybrid coordinates for acceleration. + FelemPointMixAdd(&res, &res, &tmp); + } + } + // Calculate the multiplication of point P. The calculation is performed every 5 bits. + if (computeP && (i % 5 == 0)) { + /* Obtain the corresponding bits. */ + GetIndexOfTableP(&sign, &index, k2, (uint32_t)i); + GetPointFromTable(&tmp, preCompute, TABLE_P_SIZE, index); + /* If the value is a negative number, the point is also negative. */ + FelemNeg(&negY, &tmp.y); + mask = 0 - sign; + FelemAssignWithMask(&tmp.y, &negY, mask); + /* execute point addition */ + if (isZero) { + /* If the point out is zero, the point addition operation is equivalent to direct assignment. */ + FelemPointAssign(&res, &tmp); + isZero = false; + } else { + // precomputation table P is not necessarily affine coordinates, using Jacobian coordinates addition. + FelemPointAdd(&res, &res, &tmp); + } + } + } + FelemPointAssign(r, &res); +} + +/* + * calculate pre-calculation table for the P point + * input: + * pt P point + * output: + * preCompute precalculation table of P point, (0P, 1P, ... 16P) 17 points in total + */ +static int32_t InitPreComputeTable(Point preCompute[TABLE_P_SIZE], const ECC_Point *pt) +{ + int32_t ret; + /* zero point */ + FelemSetLimb(&preCompute[0].x, 0); + FelemSetLimb(&preCompute[0].y, 0); + FelemSetLimb(&preCompute[0].z, 0); + /* 1x point */ + GOTO_ERR_IF_EX(BN2Felem(&preCompute[1].x, pt->x), ret); + GOTO_ERR_IF_EX(BN2Felem(&preCompute[1].y, pt->y), ret); + GOTO_ERR_IF_EX(BN2Felem(&preCompute[1].z, pt->z), ret); + /* 2 to 16x points */ + for (uint32_t i = 2; i < TABLE_P_SIZE; i++) { + if ((i & 1) == 0) { + /* If multiple for even times, use the multiple point formula (2n)*P = 2*(n*P), where i == 2n */ + FelemPointDouble(&preCompute[i], &preCompute[i / 2]); + } else { + /* If multiple for odd times, use the point addition formula n*P = P + (n-1)*P, where i == n */ + FelemPointAdd(&preCompute[i], &preCompute[1], &preCompute[i - 1]); + } + } +ERR: + return ret; +} + +static int32_t ComputePointMulAdd(Point *out, const Array64 *binG, const Array64 *binP, const ECC_Point *pt) +{ + // The stack space of a function cannot exceed 4096 bytes. + // Therefore, the precomputation table is allocated by the function. + Point preCompute[TABLE_P_SIZE]; /* Pre-calculation table of point pt */ + int32_t ret = InitPreComputeTable(preCompute, pt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + FelemPointMul(out, binG, binP, preCompute); + return CRYPT_SUCCESS; +} + +/* Calculate r = k1 * G + k2 * pt */ +int32_t ECP521_PointMulAdd(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt) +{ + int32_t ret; + Array64 binG = {0}; + Array64 binP = {0}; + Point out; + uint32_t len; + /* Input parameter check */ + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP521), ret); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP521), ret); + GOTO_ERR_IF(CheckBnValid(k1, FELEM_BITS), ret); + GOTO_ERR_IF(CheckBnValid(k2, FELEM_BITS), ret); + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP521), ret); + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + /* Convert the input BigNum */ + len = NUM_LIMBS; + GOTO_ERR_IF(BN_Bn2U64Array(k1, binG.data, &len), ret); + len = NUM_LIMBS; + GOTO_ERR_IF(BN_Bn2U64Array(k2, binP.data, &len), ret); + /* Calculate */ + GOTO_ERR_IF_EX(ComputePointMulAdd(&out, &binG, &binP, pt), ret); + /* Output result */ + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), ret); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), ret); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), ret); +ERR: + return ret; +} + +/* Calculate r = k * pt; If pt is NULL, calculate r = k * G. This is the ConstTime processing function. */ +int32_t ECP521_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + int32_t ret; + Array64 bin = {0}; + uint32_t len = NUM_LIMBS; + Point preCompute[TABLE_P_SIZE]; /* Pre-calculation table of Point pt */ + Point out; + /* Input parameter check */ + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP521), ret); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP521), ret); + GOTO_ERR_IF(CheckBnValid(k, FELEM_BITS), ret); + if (pt != NULL) { + if (pt->id != CRYPT_ECC_NISTP521) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + } + /* Convert the input BigNum */ + GOTO_ERR_IF(BN_Bn2U64Array(k, bin.data, &len), ret); + /* Calculate */ + if (pt != NULL) { + GOTO_ERR_IF_EX(InitPreComputeTable(preCompute, pt), ret); + FelemPointMul(&out, NULL, &bin, preCompute); + } else { + FelemPointMul(&out, &bin, NULL, NULL); + } + /* Output result */ + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), ret); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), ret); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), ret); +ERR: + return ret; +} + +static int32_t MakeAffineWithInv(ECC_Point *r, const ECC_Point *a, const Felem *zInv) +{ + int32_t ret; + Felem x, y, tmp; + GOTO_ERR_IF_EX(BN2Felem(&x, a->x), ret); + GOTO_ERR_IF_EX(BN2Felem(&y, a->y), ret); + FelemMulReduce(&y, &y, zInv); // y/z + FelemSqrReduce(&tmp, zInv); // 1/(z^2) + FelemMulReduce(&x, &x, &tmp); // x/(z^2) + FelemMulReduce(&y, &y, &tmp); // y/(z^3) + GOTO_ERR_IF_EX(Felem2BN(r->x, &x), ret); + GOTO_ERR_IF_EX(Felem2BN(r->y, &y), ret); + GOTO_ERR_IF_EX(BN_SetLimb(r->z, 1), ret); +ERR: + return ret; +} + +/* Convert a point to affine coordinates. */ +int32_t ECP521_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt) +{ + int32_t ret; + Felem z, zInv; + /* Input parameter check */ + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP521), ret); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP521), ret); + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP521), ret); + /* Special data processing */ + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + /* Convert the input data. */ + GOTO_ERR_IF_EX(BN2Felem(&z, pt->z), ret); + /* Calculate and output result */ + FelemInv(&zInv, &z); + GOTO_ERR_IF_EX(MakeAffineWithInv(r, pt, &zInv), ret); +ERR: + return ret; +} + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP521) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ diff --git a/crypto/ecc/src/ecp_nistp521.h b/crypto/ecc/src/ecp_nistp521.h new file mode 100644 index 00000000..ada5305f --- /dev/null +++ b/crypto/ecc/src/ecp_nistp521.h @@ -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 ECP_NISTP521_H +#define ECP_NISTP521_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_CURVE_NISTP521) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include "ecc_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Convert the point information pt to the affine coordinate system and refresh the data to r. + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param pt [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP521_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt); + +/** + * @brief Calculate r = k1 * G + k2 * pt + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param k1 [IN] Scalar 1, with a maximum of 521 bits + * @param k2 [IN] Scalar 2, with a maximum of 521 bits + * @param pt [IN] Point data + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP521_PointMulAdd(ECC_Para *para, ECC_Point *r, + const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt); + +/** + * @brief If pt != NULL, calculate r = k * pt; Otherwise, calculate r = k * G + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param k [IN] A scalar with a maximum of 521 bits. + * @param pt [IN] Point data, which can be set to NULL. + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP521_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt); + +#ifdef __cplusplus +} +#endif + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP521) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ + +#endif diff --git a/crypto/ecc/src/ecp_simple.c b/crypto/ecc/src/ecp_simple.c new file mode 100644 index 00000000..49060983 --- /dev/null +++ b/crypto/ecc/src/ecp_simple.c @@ -0,0 +1,1301 @@ +/* + * 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_ECC + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "ecc_local.h" + +static bool BN_IsZeroOrOne(const BN_BigNum *bn) +{ + return (BN_IsZero(bn) || BN_IsOne(bn)); +} + +int32_t ECP_PointAtInfinity(const ECC_Para *para, const ECC_Point *pt) +{ + if (para == NULL || pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != pt->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + // If z is 0, the point is the infinite point (0 point). + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + return CRYPT_SUCCESS; +} + +// Check whether the point is on the curve. +int32_t ECP_PointOnCurve(const ECC_Para *para, const ECC_Point *pt) +{ + int32_t ret = 0; + uint32_t nistList[] = {CRYPT_ECC_NISTP224, CRYPT_ECC_NISTP256, CRYPT_ECC_NISTP384, CRYPT_ECC_NISTP521}; + ret = ECP_PointAtInfinity(para, pt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + // Do not check the point on the Jacobian coordinate system. + if (!BN_IsOne(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_NOT_AFFINE); + return CRYPT_ECC_POINT_NOT_AFFINE; + } + + uint32_t bits = BN_Bits(para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *y = BN_Create(bits); + BN_BigNum *x = BN_Create(bits); + if (opt == NULL || x == NULL || y == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + GOTO_ERR_IF(BN_ModSqr(x, pt->x, para->p, opt), ret); // x^2 + GOTO_ERR_IF(BN_ModMul(x, x, pt->x, para->p, opt), ret); // x^3 + if (ParamIdIsValid(para->id, nistList, sizeof(nistList) / sizeof(nistList[0]))) { + // Currently, only the NIST curve is supported(calculating x^3 - 3x). + // Other curves need to be expanded in the future. + GOTO_ERR_IF(BN_ModSub(x, x, pt->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSub(x, x, pt->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSub(x, x, pt->x, para->p, opt), ret); // x^3 - 3x + } else { + // General implementation + GOTO_ERR_IF(BN_ModMul(y, para->a, pt->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAdd(x, x, y, para->p, opt), ret); // x^3 + ax + } + + GOTO_ERR_IF(BN_ModAdd(x, x, para->b, para->p, opt), ret); // x^3 - 3x + b + GOTO_ERR_IF(BN_ModSqr(y, pt->y, para->p, opt), ret); // y^2 + if (BN_Cmp(x, y) != 0) { + ret = CRYPT_ECC_POINT_NOT_ON_CURVE; + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + BN_Destroy(x); + BN_Destroy(y); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t ECP_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt) +{ + if (para == NULL || r == NULL || pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != pt->id || para->id != r->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (BN_IsOne(pt->z)) { + return ECC_CopyPoint(r, pt); + } + int32_t ret; + uint32_t bits = BN_Bits(para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *zz = BN_Create(bits); + BN_BigNum *inv = BN_Create(bits); + if (opt == NULL || zz == NULL || inv == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(para->method->modInv(inv, pt->z, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSqr(zz, inv, para->p, opt), ret); + + GOTO_ERR_IF(BN_ModMul(r->x, pt->x, zz, para->p, opt), ret); + + GOTO_ERR_IF(BN_ModMul(zz, zz, inv, para->p, opt), ret); + GOTO_ERR_IF(BN_ModMul(r->y, pt->y, zz, para->p, opt), ret); + + GOTO_ERR_IF(BN_SetLimb(r->z, 1), ret); +ERR: + BN_Destroy(zz); + BN_Destroy(inv); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t Points2AffineParaCheck(const ECC_Para *para, ECC_Point *pt[], uint32_t ptNums) +{ + if (para == NULL || pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ptNums == 0 || ptNums > PRE_COMPUTE_MAX_TABLELEN) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_WINDOW_TOO_MAX); + return CRYPT_ECC_POINT_WINDOW_TOO_MAX; + } + if (BN_IsZero(pt[0]->z)) { + // If the first point is an infinite point, exit directly. + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + // Check whether the point ID matches. + uint32_t i; + for (i = 0; i < ptNums; i++) { + if (para->id != pt[i]->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + } + return CRYPT_SUCCESS; +} + +static int32_t Points2AffineCreatTmpData(BN_BigNum *pt[PRE_COMPUTE_MAX_TABLELEN], uint32_t ptNums, + BN_BigNum **inv, BN_Optimizer **opt, const BN_BigNum *p) +{ + uint32_t bits = BN_Bits(p); + *opt = BN_OptimizerCreate(); + *inv = BN_Create(bits); + if (*opt == NULL || *inv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + uint32_t i; + // Apply for pre-calculation table data. + for (i = 0; i < ptNums; i++) { + pt[i] = BN_Create(bits); + if (pt[i] == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + } + return CRYPT_SUCCESS; +} + +static void Points2AffineDestroyTmpData(BN_BigNum *pt[PRE_COMPUTE_MAX_TABLELEN], uint32_t ptNums, + BN_BigNum *inv, BN_Optimizer *opt) +{ + uint32_t i; + for (i = 0; i < ptNums; i++) { + BN_Destroy(pt[i]); + } + BN_Destroy(inv); + BN_OptimizerDestroy(opt); +} + +// Multiple points are converted to the affine coordinate system. pt[0] cannot be infinite. +int32_t ECP_Points2Affine(const ECC_Para *para, ECC_Point *pt[], uint32_t ptNums) +{ + int32_t ret = Points2AffineParaCheck(para, pt, ptNums); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BN_BigNum *t[PRE_COMPUTE_MAX_TABLELEN] = { 0 }; // pre-calculation table + BN_BigNum *inv = NULL; + BN_Optimizer *opt = NULL; + GOTO_ERR_IF(Points2AffineCreatTmpData(t, ptNums, &inv, &opt, para->p), ret); + // t[i] = z[0] * z[1]* ... * z[i] + GOTO_ERR_IF(BN_Copy(t[0], pt[0]->z), ret); + uint32_t i; + for (i = 1; i < ptNums; i++) { + if (BN_IsZeroOrOne(pt[i]->z)) { + GOTO_ERR_IF(BN_Copy(t[i], t[i - 1]), ret); // copy last one + continue; + } + GOTO_ERR_IF(BN_ModMul(t[i], t[i - 1], pt[i]->z, para->p, opt), ret); + } + + // inv = 1 / (z[0] * z[1] * .... * z[ptNums - 1]) + GOTO_ERR_IF(para->method->modInv(inv, t[ptNums - 1], para->p, opt), ret); + + // t[i] = 1/z[i] + for (i = ptNums - 1; i > 0; i--) { + if (BN_IsZeroOrOne(pt[i]->z)) { + continue; + } + // t[i] *= z[0]*z[1]*...*z[i - 1] = 1/z[i] + GOTO_ERR_IF(BN_ModMul(t[i], t[i - 1], inv, para->p, opt), ret); + // inv *= z[i] = 1/(z[0]*z[1]*...z[i - 1]) + GOTO_ERR_IF(BN_ModMul(inv, pt[i]->z, inv, para->p, opt), ret); + } + GOTO_ERR_IF(BN_Copy(t[0], inv), ret); // inv = 1/z[0] + + // Calculate x = x/(z^2); y = y/(z^3) + for (i = 0; i < ptNums; i++) { + if (BN_IsZeroOrOne(pt[i]->z)) { + continue; + } + GOTO_ERR_IF(para->method->point2AffineWithInv(para, pt[i], pt[i], t[i]), ret); + } +ERR: + Points2AffineDestroyTmpData(t, ptNums, inv, opt); + return ret; +} + +// consttime +static int32_t ECP_PointCopyWithMask(ECC_Point *r, const ECC_Point *a, const ECC_Point *b, + BN_UINT mask) +{ + int32_t ret; + GOTO_ERR_IF(BN_CopyWithMask(r->x, a->x, b->x, mask), ret); + GOTO_ERR_IF(BN_CopyWithMask(r->y, a->y, b->y, mask), ret); + GOTO_ERR_IF(BN_CopyWithMask(r->z, a->z, b->z, mask), ret); +ERR: + return ret; +} + +int32_t ECP_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + if (para == NULL || r == NULL || k == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((para->id != r->id) || ((pt != NULL) && (para->id != pt->id))) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (pt != NULL && BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (BN_IsZero(k)) { + BN_Zeroize(r->z); + return CRYPT_SUCCESS; + } + if (BN_Cmp(k, para->n) == 0 && pt != NULL) { + // In this case, the consttime calculation is not required + // for checking whether the public key information is valid. + return ECP_PointMulFast(para, r, para->n, pt); + } + uint32_t i; + int32_t ret; + BN_UINT mask; + uint32_t bits; + ECC_Point *base = (pt != NULL) ? ECC_DupPoint(pt) : ECC_GetGFromPara(para); + ECC_Point *t = ECC_NewPoint(para); + if (base == NULL || t == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(ECC_CopyPoint(r, base), ret); + // Convert base to affine. + GOTO_ERR_IF(ECP_Point2Affine(para, base, base), ret); + // Add salt to prevent side channels. + GOTO_ERR_IF(ECP_PointBlind(para, r), ret); + bits = BN_Bits(k); + for (i = bits - 1; i > 0; i--) { + GOTO_ERR_IF(para->method->pointDouble(para, r, r), ret); + GOTO_ERR_IF(para->method->pointAdd(para, t, r, base), ret); + mask = BN_GetBit(k, i - 1) ? 0 : (-1); + // The last bit must be 1, and r must be updated to the latest data. + GOTO_ERR_IF(ECP_PointCopyWithMask(r, t, r, mask), ret); + } +ERR: + ECC_FreePoint(t); + ECC_FreePoint(base); + return ret; +} + +// Generate a BigNum equal to (p + 1) / 2 +BN_BigNum *ECP_HalfPGet(const BN_BigNum *p) +{ + int32_t ret; + uint32_t bits = BN_Bits(p); + BN_BigNum *halfP = BN_Create(bits + 1); + if (halfP == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + GOTO_ERR_IF_EX(BN_AddLimb(halfP, p, 1), ret); + GOTO_ERR_IF_EX(BN_Rshift(halfP, halfP, 1), ret); + return halfP; +ERR: + BN_Destroy(halfP); + return NULL; +} + +inline static int32_t CheckPointerNotNull(const void *p1, const void *p2, const void *p3, + int32_t err) +{ + if (p1 == NULL || p2 == NULL || p3 == NULL) { + return err; + } + return CRYPT_SUCCESS; +} + +static void DestroyTempBn( + BN_BigNum *ta, BN_BigNum *tb, BN_BigNum *tc, BN_BigNum *td) +{ + BN_Destroy(ta); + BN_Destroy(tb); + BN_Destroy(tc); + BN_Destroy(td); +} +// Assign a value to *ta *tb *tc *td. The original value is ignored. +// The pointers of the input parameters must be different. +static int32_t CreateTempBn(BN_BigNum **ta, BN_BigNum **tb, BN_BigNum **tc, + BN_BigNum **td, uint32_t bits) +{ + *ta = BN_Create(bits); + *tb = BN_Create(bits); + *tc = BN_Create(bits); + *td = BN_Create(bits); + if (*ta == NULL || *tb == NULL || *tc == NULL || *td == NULL) { + DestroyTempBn(*ta, *tb, *tc, *td); + *ta = NULL; + *tb = NULL; + *tc = NULL; + *td = NULL; + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +/** + prime curve point addition r = a + b, , depending on the method->pointDouble point operation. + Calculation formula: + X3 = (Y2*Z1^3-Y1)^2 - (X2*Z1^2-X1)^2 * (X1+X2*Z1^2) + Y3 = (Y2*Z1^3-Y1) * (X1*(X2*Z1^2-X1)^2-X3) - Y1 * (X2*Z1^2-X1)^3 + Z3 = (X2*Z1^2-X1) * Z1 +*/ +int32_t ECP_PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b) +{ + int32_t ret; + if (para == NULL || r == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (BN_IsZero(a->z)) { // if point a is an infinity point, r = b, + return ECC_CopyPoint(r, b); + } + uint32_t bits = BN_Bits(para->p); + BN_BigNum *t1 = NULL, *t2 = NULL, *t3 = NULL, *t4 = NULL; + BN_Optimizer *opt = BN_OptimizerCreate(); + CreateTempBn(&t1, &t2, &t3, &t4, bits); + if (t1 == NULL || t2 == NULL || t3 == NULL || t4 == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(BN_ModSqr(t1, a->z, para->p, opt), ret); // Z1^2 + GOTO_ERR_IF(BN_ModMul(t2, t1, a->z, para->p, opt), ret); // Z1^3 + GOTO_ERR_IF(BN_ModMul(t1, t1, b->x, para->p, opt), ret); // X2*Z1^2 + GOTO_ERR_IF(BN_ModMul(t2, t2, b->y, para->p, opt), ret); // Y2*Z1^3 + GOTO_ERR_IF(BN_ModSubQuick(t1, t1, a->x, para->p, opt), ret); // X2*Z1^2 - X1 + GOTO_ERR_IF(BN_ModSubQuick(t2, t2, a->y, para->p, opt), ret); // Y2*Z1^3 - Y1 + + if (BN_IsZero(t1)) { + if (BN_IsZero(t2)) { + // If two points are equal, use double for calculation. + GOTO_ERR_IF(para->method->pointDouble(para, r, b), ret); + } else { + // Obtain the infinite point. + GOTO_ERR_IF(BN_SetLimb(r->z, 0), ret); + } + goto ERR; + } + GOTO_ERR_IF(BN_ModMul(r->z, a->z, t1, para->p, opt), ret); // Z3 = (X2*Z1^2 - X1)*Z1 + + GOTO_ERR_IF(BN_ModSqr(t3, t1, para->p, opt), ret); // (X2*Z1^2 - X1)^2 + GOTO_ERR_IF(BN_ModMul(t4, t1, t3, para->p, opt), ret); // (X2*Z1^2 - X1)^3 + GOTO_ERR_IF(BN_ModMul(t3, t3, a->x, para->p, opt), ret); // X1*(X2*Z1^2 - X1)^2 + GOTO_ERR_IF(BN_ModAddQuick(t1, t3, t3, para->p, opt), ret); // 2*X1*(X2*Z1^2 - X1)^2 + GOTO_ERR_IF(BN_ModSqr(r->x, t2, para->p, opt), ret); // (Y2*Z1^3 - Y1)^2 + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t1, para->p, opt), ret); // (Y2*Z1^3-Y1)^2 - 2*X1*(X2*Z1^2-X1)^2 + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t4, para->p, opt), ret); // X3 + GOTO_ERR_IF(BN_ModSubQuick(t3, t3, r->x, para->p, opt), ret); // X1*(X2*Z1^2-X1)^2 - X3 + GOTO_ERR_IF(BN_ModMul(t3, t3, t2, para->p, opt), ret); // (Y2*Z1^3 - Y1)*(X1*(X2*Z1^2-X1)^2 - X3) + GOTO_ERR_IF(BN_ModMul(t4, t4, a->y, para->p, opt), ret); // Y1*(X2*Z1^2 - X1)^3 + GOTO_ERR_IF(BN_ModSubQuick(r->y, t3, t4, para->p, opt), ret); // Y3 +ERR: + DestroyTempBn(t1, t2, t3, t4); + BN_OptimizerDestroy(opt); + return ret; +} + +/** + prime curves point double r = a + a + Calculation formula: + X3 = (3*X1^2+a*Z1^4)^2 - 8*X1*Y1^2 + Y3 = (3*X1^2+a*Z1^4) * (4*X1*Y1^2-X3) - 8*Y1^4 + Z3 = 2 * Y1 * Z1 +*/ +int32_t ECP_PointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + int32_t ret; + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t bits = BN_Bits(para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *t1 = BN_Create(bits); + BN_BigNum *t2 = BN_Create(bits); + BN_BigNum *t3 = BN_Create(bits); + BN_BigNum *halfP = ECP_HalfPGet(para->p); + if (t1 == NULL || t2 == NULL || t3 == NULL || halfP == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + GOTO_ERR_IF(BN_ModSqr(t1, a->z, para->p, opt), ret); // Z1^2 + GOTO_ERR_IF(BN_ModSqr(t2, t1, para->p, opt), ret); // Z1^4 + GOTO_ERR_IF(BN_ModMul(t1, t2, para->a, para->p, opt), ret); // a*Z1^4 + GOTO_ERR_IF(BN_ModSqr(t2, a->x, para->p, opt), ret); // X1^2 + GOTO_ERR_IF(BN_ModAddQuick(t3, t2, t2, para->p, opt), ret); // 2*X1^2 + GOTO_ERR_IF(BN_ModAddQuick(t2, t3, t2, para->p, opt), ret); // 3*X1^2 + GOTO_ERR_IF(BN_ModAddQuick(t2, t1, t2, para->p, opt), ret); // t2 = 3*X1^2 + a*Z1^4 + + GOTO_ERR_IF(BN_ModAddQuick(r->y, a->y, a->y, para->p, opt), ret); // 2*Y1 + GOTO_ERR_IF(BN_ModMul(r->z, r->y, a->z, para->p, opt), ret); // Z3 = 2*Y1*Z1 + + GOTO_ERR_IF(BN_ModSqr(r->y, r->y, para->p, opt), ret); // 4*Y1^2 + GOTO_ERR_IF(BN_ModMul(t3, r->y, a->x, para->p, opt), ret); // t3 = 4*X1*Y1^2 + + GOTO_ERR_IF(BN_ModSqr(r->y, r->y, para->p, opt), ret); // 16*Y1^4 + GOTO_ERR_IF(BN_ModMul(r->y, r->y, halfP, para->p, opt), ret); // y3 = 8*Y1^4 + + GOTO_ERR_IF(BN_ModSqr(r->x, t2, para->p, opt), ret); // (3*X1^2 + a*Z1^4)^2 + GOTO_ERR_IF(BN_ModAddQuick(t1, t3, t3, para->p, opt), ret); // 8*X1*Y1^2 + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t1, para->p, opt), ret); // X3 = (3*X1^2 + a*Z1^4)^2 - 8*X1*Y1^2 + + GOTO_ERR_IF(BN_ModSubQuick(t1, t3, r->x, para->p, opt), ret); // 4*X1*Y1^2 - X3 + GOTO_ERR_IF(BN_ModMul(t1, t1, t2, para->p, opt), ret); // (3*X1^2 + a*Z1^4)*(4*X1*Y1^2 - X3) + GOTO_ERR_IF(BN_ModSubQuick(r->y, t1, r->y, para->p, opt), ret); // Y3 = (3*X1^2 + a*Z1^4)*(4*X1*Y1^2 - X3) - 8*Y1^4 + +ERR: + BN_Destroy(t1); + BN_Destroy(t2); + BN_Destroy(t3); + BN_Destroy(halfP); + BN_OptimizerDestroy(opt); + return ret; +} + +/** + prime curves point multi-double r = (2^m)*a + Calculation procedure: + 1. If the point is an infinity point, return the infinity point. + 2. Y = 2*Y, W = Z^4 + 3. If m > 0, repeat the following steps: + A = 3*X^2 + a*W + B = X*Y^2 + X = A^2 - 2*B + Z = Z*Y + m = m - 1 + if m > 0 then W = W*Y^4 + Y = 2*A*(B-X)-Y^4 + 4. Return (X, Y/2, Z) +*/ +int32_t ECP_PointMultDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t tm = m; + int32_t ret; + uint32_t bits = BN_Bits(para->p); + BN_BigNum *t1 = NULL, *t2 = NULL, *ta = NULL, *tb = NULL; + BN_BigNum *tw = BN_Create(bits); + BN_BigNum *halfP = ECP_HalfPGet(para->p); + BN_Optimizer *opt = BN_OptimizerCreate(); + GOTO_ERR_IF(CreateTempBn(&t1, &t2, &ta, &tb, bits), ret); + GOTO_ERR_IF(CheckPointerNotNull(tw, halfP, opt, CRYPT_MEM_ALLOC_FAIL), ret); // Check pointer not null + + GOTO_ERR_IF(BN_Copy(r->x, a->x), ret); + GOTO_ERR_IF(BN_ModAddQuick(r->y, a->y, a->y, para->p, opt), ret); + GOTO_ERR_IF(BN_Copy(r->z, a->z), ret); + + GOTO_ERR_IF(BN_ModSqr(tw, a->z, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSqr(tw, tw, para->p, opt), ret); // Z^4 + + while (tm > 0) { + // A = 3*X^2 + a*W + GOTO_ERR_IF(BN_ModSqr(t1, r->x, para->p, opt), ret); // X^2 + GOTO_ERR_IF(BN_ModAddQuick(ta, t1, t1, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(ta, ta, t1, para->p, opt), ret); // 3*X^2 + GOTO_ERR_IF(BN_ModMul(t2, para->a, tw, para->p, opt), ret); // a*W + GOTO_ERR_IF(BN_ModAddQuick(ta, ta, t2, para->p, opt), ret); // A = 3*X^2 + a*W + + // B = X*Y^2 + GOTO_ERR_IF(BN_ModSqr(t1, r->y, para->p, opt), ret); // t1 = Y^2 + GOTO_ERR_IF(BN_ModMul(tb, t1, r->x, para->p, opt), ret); // B = X*Y^2 + + GOTO_ERR_IF(BN_ModSqr(t1, t1, para->p, opt), ret); // t1 = Y^4 + + // X = A^2 - 2*B + GOTO_ERR_IF(BN_ModSqr(r->x, ta, para->p, opt), ret); // A^2 + GOTO_ERR_IF(BN_ModAddQuick(t2, tb, tb, para->p, opt), ret); // 2*B + GOTO_ERR_IF(BN_ModSubQuick(r->x, r->x, t2, para->p, opt), ret); // X = A^2 - 2*B + + // Z = Z*Y + GOTO_ERR_IF(BN_ModMul(r->z, r->z, r->y, para->p, opt), ret); + + // m = m - 1 + tm--; + if (tm > 0) { + GOTO_ERR_IF(BN_ModMul(tw, tw, t1, para->p, opt), ret); // W = W*Y^4 + } + // Y = 2*A*(B-X)-Y^4 + GOTO_ERR_IF(BN_ModSubQuick(r->y, tb, r->x, para->p, opt), ret); // (B-X) + GOTO_ERR_IF(BN_ModMul(r->y, r->y, ta, para->p, opt), ret); // A*(B-X) + GOTO_ERR_IF(BN_ModAddQuick(r->y, r->y, r->y, para->p, opt), ret); // 2*A*(B-X) + GOTO_ERR_IF(BN_ModSubQuick(r->y, r->y, t1, para->p, opt), ret); // Y = 2*A*(B-X)-Y^4 + } + // return (X, Y/2, Z) + GOTO_ERR_IF(BN_ModMul(r->y, r->y, halfP, para->p, opt), ret); +ERR: + BN_Destroy(tw); + BN_Destroy(halfP); + DestroyTempBn(t1, t2, ta, tb); + BN_OptimizerDestroy(opt); + return ret; +} + +// The z coordinate of point pt multiplied by z. +int32_t ECP_Point2AffineWithInv(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt, const BN_BigNum *inv) +{ + if (para == NULL || r == NULL || pt == NULL || inv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != pt->id || para->id != r->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(pt->z)) { + // Infinite point multiplied by z is meaningless. + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + BN_Optimizer *opt = BN_OptimizerCreate(); + if (opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret; + GOTO_ERR_IF(BN_ModSqr(r->z, inv, para->p, opt), ret); // z = inv^2 + GOTO_ERR_IF(BN_ModMul(r->x, pt->x, r->z, para->p, opt), ret); // x = x * (inv^2) + GOTO_ERR_IF(BN_ModMul(r->y, pt->y, inv, para->p, opt), ret); + GOTO_ERR_IF(BN_ModMul(r->y, r->y, r->z, para->p, opt), ret); // y = y * (inv^3) + GOTO_ERR_IF(BN_SetLimb(r->z, 1), ret); // z = 1 +ERR: + BN_OptimizerDestroy(opt); + return ret; +} + +// Convert (x, y, z) to (x/z0^2, y/z0^3, z*z0) +static int32_t ECP_PointJacMulZ(const ECC_Para *para, ECC_Point *pt, const BN_BigNum *z, BN_Optimizer *opt) +{ + if (BN_IsZero(pt->z)) { + // Infinite point multiplied by z is meaningless. + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + uint32_t bits = BN_Bits(para->p); + BN_BigNum *t = BN_Create(bits); + if (t == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret; + GOTO_ERR_IF(BN_ModMul(pt->z, pt->z, z, para->p, opt), ret); // z = z * z0 + GOTO_ERR_IF(BN_ModMul(pt->y, pt->y, z, para->p, opt), ret); // y = y * z0 + GOTO_ERR_IF(BN_ModSqr(t, z, para->p, opt), ret); // t = z0^2 + GOTO_ERR_IF(BN_ModMul(pt->x, pt->x, t, para->p, opt), ret); // x = x * (z0^2) + GOTO_ERR_IF(BN_ModMul(pt->y, pt->y, t, para->p, opt), ret); // y = y * (z0^3) +ERR: + BN_Destroy(t); + return ret; +} + +int32_t ECP_PointBlind(const ECC_Para *para, ECC_Point *pt) +{ + if (para == NULL || pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != pt->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + int32_t ret; + uint32_t bits = BN_Bits(para->p); + BN_BigNum *blind = BN_Create(bits); + BN_Optimizer *opt = BN_OptimizerCreate(); + if (blind == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // Generate random numbers as salt information. + GOTO_ERR_IF(BN_RandRange(blind, para->p), ret); + if (BN_IsZero(blind)) { + ret = CRYPT_ECC_POINT_BLIND_WITH_ZERO; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF_EX(ECP_PointJacMulZ(para, pt, blind, opt), ret); +ERR: + BN_Destroy(blind); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t ECP_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b) +{ + if (para == NULL || a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != a->id || para->id != b->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + // If both points are infinite points, equality is returned. + if (BN_IsZero(a->z) && BN_IsZero(b->z)) { + return CRYPT_SUCCESS; + } + if (BN_IsZero(a->z) || BN_IsZero(b->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_NOT_EQUAL); + return CRYPT_ECC_POINT_NOT_EQUAL; + } + + int32_t ret; + BN_Optimizer *opt = BN_OptimizerCreate(); + ECC_Point *az = ECC_DupPoint(a); + ECC_Point *bz = ECC_DupPoint(b); + if (opt == NULL || az == NULL || bz == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // Transfer a and b to the same z. + GOTO_ERR_IF(ECP_PointJacMulZ(para, az, b->z, opt), ret); + GOTO_ERR_IF(ECP_PointJacMulZ(para, bz, a->z, opt), ret); + if ((BN_Cmp(az->x, bz->x) != 0) || (BN_Cmp(az->y, bz->y) != 0)) { + ret = CRYPT_ECC_POINT_NOT_EQUAL; + goto ERR; + } +ERR: + ECC_FreePoint(az); + ECC_FreePoint(bz); + BN_OptimizerDestroy(opt); + return ret; +} + +// Cartesian coordinate point inversion. +int32_t ECP_PointInvertAtAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != r->id || para->id != a->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(a->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + if (!BN_IsOne(a->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_NOT_AFFINE); + return CRYPT_ECC_POINT_NOT_AFFINE; + } + int32_t ret; + GOTO_ERR_IF(ECC_CopyPoint(r, a), ret); + GOTO_ERR_IF(BN_Sub(r->y, para->p, r->y), ret); +ERR: + return ret; +} + +// The default ECP window length is 5 bits and only odd points are calculated. +#define WINDOW_TABLE_SIZE (PRE_COMPUTE_MAX_TABLELEN >> 1) + +static int32_t ECP_PointPreCompute(const ECC_Para *para, ECC_Point *windows[], const ECC_Point *pt) +{ + int32_t ret; + ECC_Point *doubleP = ECC_NewPoint(para); + windows[0] = ECC_DupPoint(pt); + uint32_t i; + for (i = 1; i < WINDOW_TABLE_SIZE; i++) { + windows[i] = ECC_NewPoint(para); + } + if (doubleP == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (i = 0; i < WINDOW_TABLE_SIZE; i++) { + if (windows[i] == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } + GOTO_ERR_IF(para->method->pointDouble(para, doubleP, windows[0]), ret); + GOTO_ERR_IF(para->method->point2Affine(para, doubleP, doubleP), ret); + for (i = 1; i < (WINDOW_TABLE_SIZE >> 1); i++) { + GOTO_ERR_IF(para->method->pointAdd(para, windows[i], windows[i - 1], doubleP), ret); + } + GOTO_ERR_IF(ECP_Points2Affine(para, windows, WINDOW_TABLE_SIZE >> 1), ret); + for (i = WINDOW_TABLE_SIZE >> 1; i < WINDOW_TABLE_SIZE; i++) { + GOTO_ERR_IF(ECP_PointInvertAtAffine(para, windows[i], windows[i - (WINDOW_TABLE_SIZE >> 1)]), ret); + } + ECC_FreePoint(doubleP); + return ret; +ERR: + for (i = 0; i < WINDOW_TABLE_SIZE; i++) { + ECC_FreePoint(windows[i]); + windows[i] = NULL; + } + ECC_FreePoint(doubleP); + return ret; +} + +static int32_t ECP_ParaPrecompute(ECC_Para *para) +{ + if (para->tableG[0] != NULL) { + // The pre-computation table already exists. + return CRYPT_SUCCESS; + } + int32_t ret; + ECC_Point *pt = ECC_GetGFromPara(para); + if (pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + GOTO_ERR_IF(ECP_PointPreCompute(para, para->tableG, pt), ret); +ERR: + ECC_FreePoint(pt); + return ret; +} + +void ECC_ReCodeFree(ReCodeData *code) +{ + if (code == NULL) { + return; + } + BSL_SAL_FREE(code->num); // The encoded data is insensitive and does not need to be set to 0. + BSL_SAL_FREE(code->wide); + BSL_SAL_FREE(code); +} + +static ReCodeData *WinCodeNew(uint32_t len) +{ + ReCodeData *code = BSL_SAL_Malloc(sizeof(ReCodeData)); + if (code == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + code->num = BSL_SAL_Malloc(len * sizeof(int8_t)); + code->wide = BSL_SAL_Malloc(len * sizeof(uint32_t)); + if (code->num == NULL || code->wide == NULL) { + ECC_ReCodeFree(code); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + return code; +} + +// Shift the recoded data. If the shift fails, release the code data. +static int32_t RecodeKMove(ReCodeData *code, uint32_t len, uint32_t offset) +{ + // Data shift. The value assignment starts from the tail and moves the data to the left to start position. + if (memmove_s(code->num, len * sizeof(int8_t), &(code->num[offset]), code->size * sizeof(int8_t)) != EOK || + memmove_s(code->wide, len * sizeof(uint32_t), &(code->wide[offset]), code->size * sizeof(uint32_t)) != EOK) { + ECC_ReCodeFree(code); + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +// Recode scalar data, remove the most significant bit 1 of the data in the window. +ReCodeData *ECC_ReCodeK(const BN_BigNum *k, uint32_t window) +{ + if (k == NULL || window == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return NULL; + } + int8_t max = (1 << window); + uint32_t bits = BN_Bits(k); + uint32_t len = (bits / window) + 1; + ReCodeData *code = WinCodeNew(len); + if (code == NULL) { + // The internal function WinCodeNew has executed push_err. + return NULL; + } + uint32_t offset = len; + uint32_t base = 0; + bool carry = false; + uint32_t lastWide = 0; + while (base != bits) { + offset--; + // Find the start bit of the new item. + while (BN_GetBit(k, base) == carry) { + base++; + lastWide++; + } + int8_t num = 0; + uint32_t shift = 0; + // Obtain the item of the window length. + while ((shift < window) && (base != bits)) { + int8_t add = (((BN_GetBit(k, base) ? 1 : 0)) << shift); + num += add; + base++; + shift++; + } + // If there is a carry, perform carry processing. + num += (carry ? 1 : 0); + // Refresh carry. + carry = num >= (max / 2); // Check whether the value >= (max/2). If yes, convert the value. + // If the value of a new carry item exists, convert it to -(2^win - num) + num = carry ? (-(max - num)) : num; + code->num[offset] = num; + code->wide[offset] = lastWide; + lastWide = shift; + } + // If carry information exists, store data 1 in the most significant bit. + if (carry) { + offset--; + code->num[offset] = 1; + code->wide[offset] = lastWide; + } + code->baseBits = carry ? bits : (bits - lastWide); + code->size = len - offset; + // Data shift. The value assignment starts from the tail and moves the data to the left to start position. + if (RecodeKMove(code, len, offset) != CRYPT_SUCCESS) { + // If the operation fails, the RecodeKMove releases the code data. + return NULL; + } + return code; +} + +// Layout format of the pre-computation table. +// This macro is used to convert values into corresponding offsets. +// layout rules (1, 3, 5, 7... 15, -1, -3, ... -15) +#define NUMTOOFFSET(num) (((num) < 0) ? (WINDOW_TABLE_SIZE / 2 - 1 - (((num) - 1) / 2)) : (((num) - 1) / 2)) + +typedef struct { + uint32_t baseBits; + uint32_t bit; + uint32_t bit1; + uint32_t bit2; + uint32_t offsetK1; + uint32_t offsetK2; + ReCodeData *codeK1; + ReCodeData *codeK2; +} MulAddOffData; + +static int32_t GetFirstData(const ECC_Para *para, ECC_Point *t, MulAddOffData *offData, + ECC_Point **windowsP) +{ + int32_t ret; + ECC_Point *const *windowsG = para->tableG; + // Obtain the maximum start offset of the first item. + offData->baseBits = (offData->codeK1->baseBits > offData->codeK2->baseBits) ? + offData->codeK1->baseBits : offData->codeK2->baseBits; + // If they are equal, the initial value is the sum of the two first items. + // Otherwise, the initial value is the item with a larger offset among the two items. + if (offData->codeK1->baseBits == offData->codeK2->baseBits) { + int8_t offset1 = NUMTOOFFSET(offData->codeK1->num[offData->offsetK1]); + int8_t offset2 = NUMTOOFFSET(offData->codeK2->num[offData->offsetK2]); + GOTO_ERR_IF(para->method->pointAdd(para, t, windowsG[offset1], windowsP[offset2]), ret); + offData->offsetK1++; + offData->offsetK2++; + offData->bit1 = offData->codeK1->wide[offData->offsetK1 - 1]; + offData->bit2 = offData->codeK2->wide[offData->offsetK2 - 1]; + } else if (offData->codeK1->baseBits > offData->codeK2->baseBits) { + int8_t offset = NUMTOOFFSET(offData->codeK1->num[offData->offsetK1]); + GOTO_ERR_IF(ECC_CopyPoint(t, windowsG[offset]), ret); + offData->offsetK1++; + offData->bit1 = offData->codeK1->wide[offData->offsetK1 - 1]; + offData->bit2 = offData->baseBits - offData->codeK2->baseBits; + } else { + int8_t offset = NUMTOOFFSET(offData->codeK2->num[offData->offsetK2]); + GOTO_ERR_IF(ECC_CopyPoint(t, windowsP[offset]), ret); + offData->offsetK2++; + offData->bit1 = offData->baseBits - offData->codeK1->baseBits; + offData->bit2 = offData->codeK2->wide[offData->offsetK2 - 1]; + } +ERR: + return ret; +} + +static int32_t PointMulAddParaCheck(const ECC_Para *para, const ECC_Point *r, const BN_BigNum *k1, + const BN_BigNum *k2, const ECC_Point *pt) +{ + if (para == NULL || r == NULL || k1 == NULL || k2 == NULL || pt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((para->id != r->id) || (para->id != pt->id)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + return CRYPT_SUCCESS; +} + +// NotConstTime r = order*pt +int32_t ECP_PointMulFast(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + if (para == NULL || r == NULL || k == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((para->id != r->id) || ((pt != NULL) && (para->id != pt->id))) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + if (BN_IsZero(k)) { + BN_Zeroize(r->z); + return CRYPT_SUCCESS; + } + int32_t ret; + ReCodeData *codeK = NULL; + int8_t offset; + + ECC_Point *windowsP[WINDOW_TABLE_SIZE] = { 0 }; + ECC_Point **windows = NULL; + if (pt == NULL) { + GOTO_ERR_IF(ECP_ParaPrecompute(para), ret); + windows = para->tableG; + } else { + GOTO_ERR_IF(ECP_PointPreCompute(para, windowsP, pt), ret); + windows = windowsP; + } + + codeK = ECC_ReCodeK(k, PRE_COMPUTE_WINDOW); + if (codeK == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + offset = NUMTOOFFSET(codeK->num[0]); + GOTO_ERR_IF(ECC_CopyPoint(r, windows[offset]), ret); + GOTO_ERR_IF(para->method->pointMultDouble(para, r, r, codeK->wide[0]), ret); + for (uint32_t i = 1; i < codeK->size; i++) { + offset = NUMTOOFFSET(codeK->num[i]); + GOTO_ERR_IF(para->method->pointAdd(para, r, r, windows[offset]), ret); + GOTO_ERR_IF(para->method->pointMultDouble(para, r, r, codeK->wide[i]), ret); + } +ERR: + for (uint32_t i = 0; i < WINDOW_TABLE_SIZE; i++) { + // Clear the pre-computation table. + ECC_FreePoint(windowsP[i]); + } + ECC_ReCodeFree(codeK); + return ret; +} + +static int32_t KZeroHandle(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, + const BN_BigNum *k2, const ECC_Point *pt) +{ + if (BN_IsZero(k1) && BN_IsZero(k2)) { + // When k1 and k2 are both 0, the result is infinity. + BN_Zeroize(r->z); + return CRYPT_SUCCESS; + } + if (BN_IsZero(k1)) { + return ECP_PointMulFast(para, r, k2, pt); + } + // k2 is 0 + return ECP_PointMulFast(para, r, k1, NULL); +} + +// wNaf NotConstTime +int32_t ECP_PointMulAdd(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, + const BN_BigNum *k2, const ECC_Point *pt) +{ + int32_t ret = PointMulAddParaCheck(para, r, k1, k2, pt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (BN_IsZero(k1) || BN_IsZero(k2)) { + return KZeroHandle(para, r, k1, k2, pt); + } + uint32_t i; + MulAddOffData offData = { 0 }; + ECC_Point *windowsP[WINDOW_TABLE_SIZE] = { 0 }; + ECC_Point **windowsG = NULL; + GOTO_ERR_IF(ECP_ParaPrecompute(para), ret); + GOTO_ERR_IF(ECP_PointPreCompute(para, windowsP, pt), ret); + windowsG = para->tableG; + offData.codeK1 = ECC_ReCodeK(k1, PRE_COMPUTE_WINDOW); + offData.codeK2 = ECC_ReCodeK(k2, PRE_COMPUTE_WINDOW); + if (offData.codeK1 == NULL || offData.codeK2 == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // Obtain the initial point data. + GetFirstData(para, r, &offData, windowsP); + + while (offData.baseBits != 0) { + // Slide window + offData.bit1 = (offData.bit1 == 0) ? (offData.codeK1->wide[offData.offsetK1 - 1]) : (offData.bit1); + offData.bit2 = (offData.bit2 == 0) ? (offData.codeK2->wide[offData.offsetK2 - 1]) : (offData.bit2); + offData.bit = (offData.bit1 < offData.bit2) ? (offData.bit1) : (offData.bit2); + GOTO_ERR_IF(para->method->pointMultDouble(para, r, r, offData.bit), ret); + if (offData.bit == offData.bit1 && offData.offsetK1 < offData.codeK1->size) { + int8_t offset = NUMTOOFFSET(offData.codeK1->num[offData.offsetK1]); + GOTO_ERR_IF(para->method->pointAdd(para, r, r, windowsG[offset]), ret); + offData.offsetK1++; + } + if (offData.bit == offData.bit2 && offData.offsetK2 < offData.codeK2->size) { + int8_t offset = NUMTOOFFSET(offData.codeK2->num[offData.offsetK2]); + GOTO_ERR_IF(para->method->pointAdd(para, r, r, windowsP[offset]), ret); + offData.offsetK2++; + } + offData.bit1 -= offData.bit; + offData.bit2 -= offData.bit; + offData.baseBits -= offData.bit; + } +ERR: + for (i = 0; i < WINDOW_TABLE_SIZE; i++) { + // Clear the pre-computation table. + ECC_FreePoint(windowsP[i]); + } + ECC_ReCodeFree(offData.codeK1); + ECC_ReCodeFree(offData.codeK2); + return ret; +} + +static int32_t PointParaCheck(const ECC_Para *para, const ECC_Point *pt, CRYPT_PKEY_PointFormat format) +{ + int32_t ret = ECP_PointAtInfinity(para, pt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (format < CRYPT_POINT_COMPRESSED || format > CRYPT_POINT_HYBRID) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_FORMAT); + return CRYPT_ECC_ERR_POINT_FORMAT; + } + return CRYPT_SUCCESS; +} + +static int32_t EncodePointParaCheck(const ECC_Para *para, const ECC_Point *pt, const uint8_t *data, + const uint32_t *dataLen, CRYPT_PKEY_PointFormat format) +{ + int32_t ret = PointParaCheck(para, pt, format); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (data == NULL || dataLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + uint32_t curveBytes = BN_Bytes(para->p); + // Obtain the required buff length based on the compression format. + uint32_t needBytes = (format == CRYPT_POINT_COMPRESSED) ? (curveBytes + 1) : ((curveBytes << 1) + 1); + if (needBytes > *dataLen) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_BUFF_LEN_NOT_ENOUGH); + return CRYPT_ECC_BUFF_LEN_NOT_ENOUGH; + } + return CRYPT_SUCCESS; +} + +int32_t ECP_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen, + CRYPT_PKEY_PointFormat format) +{ + int32_t ret; + bool z = 0; + uint32_t bytes, off, lastLen, i, curveBytes; + GOTO_ERR_IF(EncodePointParaCheck(para, pt, data, dataLen, format), ret); + // Convert the point to affine. + GOTO_ERR_IF(para->method->point2Affine(para, pt, pt), ret); + z = BN_GetBit(pt->y, 0); + bytes = BN_Bytes(pt->x); + curveBytes = BN_Bytes(para->p); + off = curveBytes - bytes; + for (i = 0; i < off; i++) { + // Padded 0s to the most significant bits. + data[i + 1] = 0; + } + lastLen = *dataLen - off - 1; + GOTO_ERR_IF(BN_Bn2Bin(pt->x, &data[off + 1], &lastLen), ret); + /** + * ANS X9.62–2005 A.5.5 + * If the compressed form is used PC is either 02 or 03. + * If the uncompressed form is used Verify that PC is 04. + * If the hybrid form is used Verify that PC is either 06 or 07 + */ + if (format == CRYPT_POINT_COMPRESSED) { + // Set the bit zP to be equal to 0 if PC = 02, or 1 if PC = 03. + data[0] = z ? 0x03 : 0x02; + *dataLen = curveBytes + 1; + return CRYPT_SUCCESS; + } else if (format == CRYPT_POINT_UNCOMPRESSED) { + data[0] = 0x04; + } else if (format == CRYPT_POINT_HYBRID) { + // Set the bit zP to be equal to 0 if PC = 06, or 1 if PC = 07. + data[0] = z ? 0x07 : 0x06; + } + bytes = BN_Bytes(pt->y); + off = curveBytes - bytes; + for (i = 0; i < off; i++) { + // Padded 0s to the most significant bits. + data[i + curveBytes + 1] = 0; + } + lastLen = *dataLen - off - curveBytes - 1; + GOTO_ERR_IF(BN_Bn2Bin(pt->y, &data[off + curveBytes + 1], &lastLen), ret); + *dataLen = (curveBytes << 1) + 1; +ERR: + return ret; +} + +// Calculate the y coordinate based on the x coordinate. +// Currently, only the y^2 = x^3 + a*x + b curve equation can be solved. +static int32_t GetYData(const ECC_Para *para, ECC_Point *pt, bool pcBit) +{ + uint32_t bits = BN_Bits(para->p); + BN_BigNum *t1 = BN_Create(bits); + BN_BigNum *t2 = BN_Create(bits); + BN_Optimizer *opt = BN_OptimizerCreate(); + int32_t ret; + if (t1 == NULL || t2 == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(BN_ModSqr(t1, pt->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModMul(t1, t1, pt->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModMul(t2, para->a, pt->x, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAdd(t1, t1, t2, para->p, opt), ret); + GOTO_ERR_IF(BN_ModAdd(t1, t1, para->b, para->p, opt), ret); + GOTO_ERR_IF(BN_ModSqrt(pt->y, t1, para->p, opt), ret); + + if (BN_GetBit(pt->y, 0) != pcBit) { // if parity is inconsistent, y = -y + GOTO_ERR_IF(BN_ModSub(pt->y, para->p, pt->y, para->p, opt), ret); + } +ERR: + BN_Destroy(t1); + BN_Destroy(t2); + BN_OptimizerDestroy(opt); + return ret; +} + +// Check whether the parsed data is valid during point decoding and provide compression information. +static int32_t GetFormatAndCheckLen(const uint8_t *data, uint32_t dataLen, CRYPT_PKEY_PointFormat *format, + uint32_t curveBytes) +{ + if (dataLen < curveBytes + 1) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); + return CRYPT_ECC_ERR_POINT_CODE; + } + uint8_t pc = data[0]; + /** + * ANS X9.62–2005 A.5.5 + * If the compressed form is used PC is either 02 or 03. + * If the uncompressed form is used Verify that PC is 04. + * If the hybrid form is used Verify that PC is either 06 or 07 + */ + if (pc == 0x04) { + // uncompressed + if (dataLen != (curveBytes << 1) + 1) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); + return CRYPT_ECC_ERR_POINT_CODE; + } + *format = CRYPT_POINT_UNCOMPRESSED; + return CRYPT_SUCCESS; + } else if (pc == 0x02 || pc == 0x03) { + // compressed + if (dataLen != curveBytes + 1) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); + return CRYPT_ECC_ERR_POINT_CODE; + } + *format = CRYPT_POINT_COMPRESSED; + return CRYPT_SUCCESS; + } else if (pc == 0x06 || pc == 0x07) { + // hybriid + if (dataLen != (curveBytes << 1) + 1) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); + return CRYPT_ECC_ERR_POINT_CODE; + } + *format = CRYPT_POINT_HYBRID; + return CRYPT_SUCCESS; + } + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); + return CRYPT_ECC_ERR_POINT_CODE; +} + +int32_t ECP_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen) +{ + if (para == NULL || pt == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != pt->id) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + int32_t ret; + uint32_t curveBytes = BN_Bytes(para->p); + CRYPT_PKEY_PointFormat format = CRYPT_POINT_UNCOMPRESSED; + bool pcBit = ((data[0] & 0x01) == 1); // Parity check. If it's odd, return true. If it's even, return false. + GOTO_ERR_IF(GetFormatAndCheckLen(data, dataLen, &format, curveBytes), ret); + + GOTO_ERR_IF(BN_SetLimb(pt->z, 1), ret); + if (format == CRYPT_POINT_COMPRESSED) { + GOTO_ERR_IF(BN_Bin2Bn(pt->x, &data[1], curveBytes), ret); + // The y-coordinate information is obtained through calculation. + GOTO_ERR_IF(GetYData(para, pt, pcBit), ret); + } else if (format == CRYPT_POINT_UNCOMPRESSED) { + GOTO_ERR_IF(BN_Bin2Bn(pt->x, &data[1], curveBytes), ret); + GOTO_ERR_IF(BN_Bin2Bn(pt->y, &data[1 + curveBytes], curveBytes), ret); + } else if (format == CRYPT_POINT_HYBRID) { + GOTO_ERR_IF(BN_Bin2Bn(pt->x, &data[1], curveBytes), ret); + GOTO_ERR_IF(BN_Bin2Bn(pt->y, &data[1 + curveBytes], curveBytes), ret); + // The parity information on the coded information is inconsistent. + if (BN_GetBit(pt->y, 0) != pcBit) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); + ret = CRYPT_ECC_ERR_POINT_CODE; + goto ERR; + } + } + // Check whether the value on the point exceeds the modulus field. + if ((BN_Cmp(para->p, pt->y) <= 0) || (BN_Cmp(para->p, pt->x) <= 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_NOT_ON_CURVE); + ret = CRYPT_ECC_POINT_NOT_ON_CURVE; + goto ERR; + } + if (format != CRYPT_POINT_COMPRESSED) { + // Check whether the point is on the curve. + GOTO_ERR_IF(ECP_PointOnCurve(para, pt), ret); + } + return ret; +ERR: + // Ensure that pt is not NULL. Therefore, pt->z is not NULL. This invoking does not fail. + (void)BN_Zeroize(pt->z); + return ret; +} +#endif /* HITLS_CRYPTO_ECC */ diff --git a/crypto/ecc/src/ecp_sm2.h b/crypto/ecc/src/ecp_sm2.h new file mode 100644 index 00000000..00cdb038 --- /dev/null +++ b/crypto/ecc/src/ecp_sm2.h @@ -0,0 +1,88 @@ +/* + * 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 ECP_SM2_H +#define ECP_SM2_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_ECC) && defined(HITLS_CRYPTO_SM2) + +#include "crypt_ecc.h" +#include "crypt_bn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup sm2 + * @brief Calculate r = k * pt. When pt is NULL, calculate r = k * G + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param k [IN] Scalar + * @param pt [IN] Point data, which can be set to NULL. + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Sm2PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *scalar, const ECC_Point *pt); + +/** + * @ingroup sm2 + * @brief Calculate r = a + b, where a is the Jacobian coordinate system and b is the affine coordinate system. + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param a,b [IN] Point data + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Sm2PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b); + +/** + * @ingroup sm2 + * @brief Calculate r = 2*a, where a is the Jacobian coordinate system. + * + * @param para [IN] Curve parameter information + * @param r [OUT] Output point information + * @param a [IN] Point data + * + * @retval CRYPT_SUCCESS succeeded. + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Sm2PointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + +/** + * @ingroup sm2 + * @brief Convert the point information pt to the affine coordinate system and refresh the data to r. + * + * @param para [IN] Curve parameters + * @param r [OUT] Output point information + * @param a [IN] Input point information + * + * @retval CRYPT_SUCCESS succeeded + * @retval For details about other errors, see crypt_errno.h + */ +int32_t ECP_Sm2Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SM2 + +#endif // ECP_SM2_H diff --git a/crypto/ecc/src/noasm_ecp_nistp256.c b/crypto/ecc/src/noasm_ecp_nistp256.c new file mode 100644 index 00000000..04747a3a --- /dev/null +++ b/crypto/ecc/src/noasm_ecp_nistp256.c @@ -0,0 +1,1678 @@ +/* + * 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_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "ecc_local.h" +#include "ecc_utils.h" + +typedef __uint128_t uint128_t; + + +/* field element definition */ +#define FELEM_BITS 256 +#define FELEM_BYTES 32 +#define LIMB_BITS (sizeof(uint128_t) << 3) +#define LIMB_NUM 4 +#define BASE_BITS 64 +/* The pre-calculation table of the G table has 16 points. */ +#define TABLE_G_SIZE 16 +/* The pre-calculation table of the P table has 17 points. */ +#define TABLE_P_SIZE 17 + +/* + * Field elements, stored as arrays, all represented in little endian. + * Each element of the array is called a digit. Each digit represents an extended 2 ^ 64-bit. + * That is, Felem can be expressed as: + * f_0 + f_1 * 2^64 + f_2 * 2^128 + f_3 * 2^192 + * LongFelem is used to store the result of multiplication of field elements and is twice the width of Felem. + * Point is a point represented as a Jacobian coordinate + */ +typedef struct { + uint128_t data[LIMB_NUM]; +} Felem; + +typedef struct { + uint128_t data[LIMB_NUM * 2]; +} LongFelem; + +typedef struct { + Felem x; + Felem y; + Felem z; +} Point; + +/* ------------------------------------------------------------ */ +/* ECP256 field order p. The value is 2^256 - 2^224 + 2^192 + 2^96 - 1, little endian */ +static const Felem FIELD_ORDER = { + {0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001} +}; + +/* + * Pre-computation table of the base point G, which contains the (X, Y, Z) coordinates of k*G + * + * PRE_MUL_G divides all bits into four equal parts. + * index corresponding bit value of k + * 0 0 0 0 0 0 + 0 + 0 + 0 + * 1 0 0 0 1 0 + 0 + 0 + 1 + * 2 0 0 1 0 0 + 0 + 2^64 + 0 + * 3 0 0 1 1 0 + 0 + 2^64 + 1 + * 4 0 1 0 0 0 + 2^128 + 0 + 0 + * 5 0 1 0 1 0 + 2^128 + 0 + 1 + * 6 0 1 1 0 0 + 2^128 + 2^64 + 0 + * 7 0 1 1 1 0 + 2^128 + 2^64 + 1 + * 8 1 0 0 0 2^192 + 0 + 0 + 0 + * 9 1 0 0 1 2^192 + 0 + 0 + 1 + * 10 1 0 1 0 2^192 + 0 + 2^64 + 0 + * 11 1 0 1 1 2^192 + 0 + 2^64 + 1 + * 12 1 1 0 0 2^192 + 2^128 + 0 + 0 + * 13 1 1 0 1 2^192 + 2^128 + 0 + 1 + * 14 1 1 1 0 2^192 + 2^128 + 2^64 + 0 + * 15 1 1 1 1 2^192 + 2^128 + 2^64 + 1 + * + */ +static const Point PRE_MUL_G[TABLE_G_SIZE] = { + { + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, 0x6b17d1f2e12c4247}}, + {{0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, 0x4fe342e2fe1a7f9b}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, 0x0fa822bc2811aaa5}}, + {{0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, 0xbff44ae8f5dba80d}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, 0x300a4bbc89d6726f}}, + {{0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, 0x72aac7e0d09b4644}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, 0x447d739beedb5e67}}, + {{0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, 0x2d4825ab834131ee}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, 0xef9519328a9c72ff}}, + {{0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, 0x611e9fc37dbb2c9b}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, 0x550663797b51f5d8}}, + {{0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, 0x157164848aecb851}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, 0xeb5d7745b21141ea}}, + {{0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, 0xeafd72ebdbecc17b}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, 0xa6d39677a7849276}}, + {{0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, 0x674f84749b0b8816}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, 0x4e769e7672c9ddad}}, + {{0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, 0x42b99082de830663}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, 0x78878ef61c6ce04d}}, + {{0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, 0xb6cb3f5d7b72c321}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, 0x0c88bc4d716b1287}}, + {{0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, 0xdd5ddea3f3901dc6}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, 0x68f344af6b317466}}, + {{0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, 0x31b9c405f8540a20}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, 0x4052bf4b6f461db9}}, + {{0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, 0xfecf4d5190b0fc61}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, 0x1eddbae2c802e41a}}, + {{0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, 0x43104d86560ebcfc}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, 0xb48e26b484f7a21c}}, + {{0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, 0xfac015404d4d3dab}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + } +}; + +/* + * Pre-computation table of the base point G, which contains the (X, Y, Z) coordinates of k*G + * + * PRE_MUL_G2[] = PRE_MUL_G[] * 2^32 + * index corresponding bit value of k + * 0 0 0 0 0 0 + 0 + 0 + 0 + * 1 0 0 0 1 0 + 0 + 0 + 2^32 + * 2 0 0 1 0 0 + 0 + 2^96 + 0 + * 3 0 0 1 1 0 + 0 + 2^96 + 2^32 + * 4 0 1 0 0 0 + 2^160 + 0 + 0 + * 5 0 1 0 1 0 + 2^160 + 0 + 2^32 + * 6 0 1 1 0 0 + 2^160 + 2^96 + 0 + * 7 0 1 1 1 0 + 2^160 + 2^96 + 2^32 + * 8 1 0 0 0 2^224 + 0 + 0 + 0 + * 9 1 0 0 1 2^224 + 0 + 0 + 2^32 + * 10 1 0 1 0 2^224 + 0 + 2^96 + 0 + * 11 1 0 1 1 2^224 + 0 + 2^96 + 2^32 + * 12 1 1 0 0 2^224 + 2^160 + 0 + 0 + * 13 1 1 0 1 2^224 + 2^160 + 0 + 2^32 + * 14 1 1 1 0 2^224 + 2^160 + 2^96 + 0 + * 15 1 1 1 1 2^224 + 2^160 + 2^96 + 2^32 + */ +static const Point PRE_MUL_G2[TABLE_G_SIZE] = { + { + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}}, + {{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, 0x7fe36b40af22af89}}, + {{0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, 0xe697d45825b63624}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, 0x4a5b506612a677a6}}, + {{0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, 0xeb13461ceac089f1}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, 0x0781b8291c6a220a}}, + {{0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, 0x690cde8df0151593}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, 0x8a535f566ec73617}}, + {{0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, 0x0455c08468b08bd7}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, 0x06bada7ab77f8276}}, + {{0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, 0x5b476dfd0e6cb18a}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, 0x3e29864e8a2ec908}}, + {{0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, 0x239b90ea3dc31e7e}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, 0x820f4dd949f72ff7}}, + {{0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, 0x140406ec783a05ec}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, 0x68f6b8542783dfee}}, + {{0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, 0xcbe1feba92e40ce6}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, 0xd0b2f94d2f420109}}, + {{0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, 0x971459828b0719e5}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, 0x961610004a866aba}}, + {{0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, 0x7acb9fadcee75e44}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, 0x24eb9acca333bf5b}}, + {{0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, 0x69f891c5acd079cc}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, 0xe51f547c5972a107}}, + {{0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, 0x1c309a2b25bb1387}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, 0x20b87b8aa2c4e503}}, + {{0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, 0xf5c6fa49919776be}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, 0x1ed7d1b9332010b9}}, + {{0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, 0x3a2b03f03217257a}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + }, { + {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, 0x15fee545c78dd9f6}}, + {{0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81}}, + {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}} + } +}; + +/* --------------------------helper function-------------------------- */ +/* + * Convert big-endian byte stream to Felem + */ +static inline void Bin2Felem(Felem *out, const uint8_t in[FELEM_BYTES]) +{ + // Write the input data to 128-bit digits every 64 bits. + out->data[3] = (uint128_t)Uint64FromBeBytes(in); // Index 3 read 0~7 bytes + out->data[2] = (uint128_t)Uint64FromBeBytes(in + 8); // Index 2 read 8~15 bytes + out->data[1] = (uint128_t)Uint64FromBeBytes(in + 16); // Index 1 read 16~23 bytes + out->data[0] = (uint128_t)Uint64FromBeBytes(in + 24); // Index 0 read 24~31 bytes +} + +/* + * Convert Felem to big-endian byte stream + * Input: + * in[] < 2^64 + * Output: + * out length is 32 + */ +static inline void Felem2Bin(uint8_t out[FELEM_BYTES], const Felem *in) +{ + Uint64ToBeBytes((uint64_t)in->data[3], out); // Index 3 write 0~7 bytes + Uint64ToBeBytes((uint64_t)in->data[2], out + 8); // Index 2 write 8~15 bytes + Uint64ToBeBytes((uint64_t)in->data[1], out + 16); // Index 1 write 16~23 bytes + Uint64ToBeBytes((uint64_t)in->data[0], out + 24); // Index 0 write 24~31 bytes +} + +/* + * Convert BN to Felem + * Output: + * out[] < 2^64 + */ +static int32_t BN2Felem(Felem *out, const BN_BigNum *in) +{ + int32_t ret; + uint8_t bin[FELEM_BYTES]; + uint32_t len = FELEM_BYTES; + + GOTO_ERR_IF(BN_Bn2Bin(in, bin, &len), ret); + + for (uint32_t i = 0; i < FELEM_BYTES; ++i) { + bin[FELEM_BYTES - 1 - i] = i < len ? bin[len - 1 - i] : 0; + } + + Bin2Felem(out, bin); +ERR: + return ret; +} + +/* + * Convert Felem to BN + * Input: + * in[] < 2^64 + */ +static int32_t Felem2BN(BN_BigNum *out, const Felem *in) +{ + int32_t ret; + uint8_t bin[FELEM_BYTES]; + + Felem2Bin(bin, in); + + GOTO_ERR_IF(BN_Bin2Bn(out, bin, FELEM_BYTES), ret); +ERR: + return ret; +} + +/* ---------------------------field operation--------------------------- */ +/* + * Assignment + */ +static inline void FelemAssign(Felem *out, const Felem *in) +{ + out->data[0] = in->data[0]; // out->data[0] get the value + out->data[1] = in->data[1]; // out->data[1] get the value + out->data[2] = in->data[2]; // out->data[2] get the value + out->data[3] = in->data[3]; // out->data[3] get the value +} + +/* + * Copy each digit by mask. If the corresponding bit is 1, copy it. If the corresponding bit is 0, retain it. + */ +static inline void FelemAssignWithMask(Felem *out, const Felem *in, const uint128_t mask) +{ + uint128_t rmask = ~mask; + // The value of out->data[0] is changed or remains unchanged. + out->data[0] = (in->data[0] & mask) | (out->data[0] & rmask); + // The value of out->data[1] is changed or remains unchanged. + out->data[1] = (in->data[1] & mask) | (out->data[1] & rmask); + // The value of out->data[2] is changed or remains unchanged. + out->data[2] = (in->data[2] & mask) | (out->data[2] & rmask); + // The value of out->data[3] is changed or remains unchanged. + out->data[3] = (in->data[3] & mask) | (out->data[3] & rmask); +} + +/* + * Set the lowest digit + */ +static inline void FelemSetLimb(Felem *out, const uint128_t in) +{ + out->data[0] = in; // out->data[0] get the value + out->data[1] = 0; // out->data[1] clear to 0 + out->data[2] = 0; // out->data[2] clear to 0 + out->data[3] = 0; // out->data[3] clear to 0 +} + +/* + * Zero judgment: input less than 2 ^ 256, only 0 and p need to be judged. + * Input: + * in[] < 2^64 + */ +static inline uint128_t FelemIsZero(const Felem *in) +{ + uint128_t isZero, isP; + + // Check whether digits 0, 1, 2, and 3 are all 0. + isZero = in->data[0] | in->data[1] | in->data[2] | in->data[3]; + isZero -= 1; // If in == 0, the most significant bit is 1. + + // Determine that in is equal to the field order. + isP = (in->data[0] ^ FIELD_ORDER.data[0]) | // Determine whether the digits 0 is equal to the order + (in->data[1] ^ FIELD_ORDER.data[1]) | // Determine whether the digits 1 is equal to the order + (in->data[2] ^ FIELD_ORDER.data[2]) | // Determine whether the digits 2 is equal to the order + (in->data[3] ^ FIELD_ORDER.data[3]); // Determine whether the digits 3 is equal to the order + isP -= 1; // If in == p, the most significant bit is 1. + + return (isZero | isP) >> (LIMB_BITS - 1); +} + +/* + * Obtain the bit string whose length is len at idx in Felem. + * Input: + * in[] < 2^64 + * 0 < len <= 64 + */ +static uint64_t FelemGetBits(const Felem *in, int32_t idx, uint32_t len) +{ + uint128_t ret; + uint32_t lower, upper; + uint64_t mask; + + lower = (uint32_t)idx; + // When 0 <= lower < 256, the most significant bit is 1, obtain the most significant bit by right shifted by 31 bits + mask = (uint64_t)0 - ((~lower & (lower - 256)) >> 31); + ret = (uint64_t)in->data[(lower / BASE_BITS) & mask] & mask; + + upper = (uint32_t)idx + BASE_BITS; // next unary block + // When 0 <= upper < 256, the most significant bit is 1, obtain the most significant bit by right shifted by 31 bits + mask = (uint64_t)0 - ((~upper & (upper - 256)) >> 31); + ret |= (uint128_t)((uint64_t)in->data[(upper / BASE_BITS) & mask] & mask) << BASE_BITS; + + // Take the lower six bits, that is, mod 64, regardless of the positive and negative values of "lower". + ret >>= lower & (BASE_BITS - 1); + ret &= ((uint64_t)1 << len) - 1; // All 1-bit string with the len length + + return (uint64_t)ret; +} + +/* + * Field element reduction, retains the base bit (64 bits) of each digit in the 4-ary Felem, and reduce the high bit. + * Should be called before modular multiplication, modulus square, or modulus + * Input: + * in[] < 2^127 + * Output: + * out[] < 2^64 + */ +static void FelemReduce(Felem *out, const Felem *in) +{ + uint128_t *po = out->data; + const uint128_t *pi = in->data; + const uint128_t borrow = (uint128_t)1 << 96; // 2 ^ 96 borrowed from low to high + const uint128_t lend = (uint128_t)1 << 32; // 2 ^ 32 lent from high to low + uint128_t carryLimb, carryLimbTotal; + + // Process the carry of each digit first: 0 -> 1 -> 2 -> 3 + po[1] = pi[1] + (pi[0] >> BASE_BITS); // po[1] takes the input value and adds the carry of digit 0. + po[2] = pi[2] + (po[1] >> BASE_BITS); // po[2] takes the input value and adds the carry of digit 1. + po[3] = pi[3] + (po[2] >> BASE_BITS); // po[3] takes the input value and adds the carry of digit 2. + + po[0] = (uint64_t)pi[0]; // po[0] takes the basic digit. + po[1] = (uint64_t)po[1]; // po[1] takes the basic digit. + po[2] = (uint64_t)po[2]; // po[2] takes the basic digit. + + // Now reduce the highest digit. Only need to reduce the carry of the highest digit three times. + // Note the carry bit of out[3] as carryLimb. + // It can be known from the equation: + // carryLimb * 2^256 = carryLimb * (2^224 - 2^192 - 2^96 + 1) (mod 2^256 - 2^224 + 2^192 + 2^96 - 1) + // The part of carryLimb * (2^224 - 2^192) needs to be placed in out[3] + // + // First reduction: po[3] < 2^128 ---> po[3] < 2^96 + // Assume that po[3] = 0x ffffffffffffffff ffffffffffffffff + // 0x 0000000000000000 ffffffffffffffff -> po[3] basic digit(unit) + // + 0x 00000000ffffffff ffffffff00000000 -> carryLimb * 2^32 + // - 0x 0000000000000000 ffffffffffffffff -> carryLimb + // ----------------------------------------- + // = 0x 00000000ffffffff ffffffff00000000 -> po[3] <= 2^96 - 2^32 < 2^96 + // Second reduction: po[3] < 2^96 ---> po[3] < 2^65 - 2^33 + // Assume that po[3] = 0x 00000000ffffffff ffffffffffffffff + // 0x 0000000000000000 ffffffffffffffff + // + 0x 0000000000000000 ffffffff00000000 + // - 0x 0000000000000000 00000000ffffffff + // ----------------------------------------- + // = 0x 0000000000000001 fffffffe00000000 -> po[3] <= 2^65 - 2^33 < 2^65 - 2^33 + // Third reduction: po[3] < 2^65 - 2^32 ---> po[3] < 2^64 + // Assume that po[3] = 0x 0000000000000001 ffffffff00000000 + // 0x 0000000000000000 ffffffff00000000 + // + 0x 0000000000000000 0000000100000000 + // - 0x 0000000000000000 0000000000000001 + // ----------------------------------------- + // = 0x 0000000000000000 ffffffffffffffff -> po[3] < 2^64 + // + // In addition, use carryLimbTotal to store the sum of carry bits. + // In this way, carryLimbTotal*(-2^96 + 1) can be calculated at a time. + // The simple conclusion is that when out[3] is the maximum, carryLimbTotal is the maximum. + // Consider the maximum value of out[3]. + // 0x 7fffffffffffffff ffffffffffffffff -> Maximum value of pi[3] (pi[3] < 2^127) + // + 0x 0000000000000000 8000000000000000 -> Maximum value of carry of pi[2] + // ----------------------------------------- + // = 0x 8000000000000000 7fffffffffffffff -> Maximum value of po[3] + // Use the value to perform three reduction: + // carryLimbTotal = 0x8000000000000000 + 0x7fffffff + 0x1 = 0x8000000080000000 < 2^64 + carryLimbTotal = carryLimb = po[3] >> BASE_BITS; // Reduce carryLimb and take the carry of po[3]. + po[3] = (uint64_t)po[3] + (carryLimb << 32) - carryLimb; // The reduction factor on po[3] is (2 ^ 32 - 1). + carryLimbTotal += (carryLimb = po[3] >> BASE_BITS); // Reduce carryLimb and take the carry of po[3]. + po[3] = (uint64_t)po[3] + (carryLimb << 32) - carryLimb; // The reduction factor on po[3] is (2 ^ 32 - 1). + carryLimbTotal += (carryLimb = po[3] >> BASE_BITS); // Reduce carryLimb and take the carry of po[3]. + po[3] = (uint64_t)po[3] + (carryLimb << 32) - carryLimb; // The reduction factor on po[3] is (2 ^ 32 - 1). + + // Calculate the remaining carryLimbTotal * (-2^96 + 1) <= 0 + // In this case, it is impossible to carry out[4]. Therefore, po[3] < 2^64. + // If carryLimbTotal > 0, po[3] must be equal to at least 2 ^ 32 - 1. (i.e., po[3] = 2^64 in the last step) + // In this case, it is obvious that (2^32 - 1) * 2^192 > |carryLimbTotal * (-2^96 + 1)| + po[0] += carryLimbTotal; // reduction of carryLimbTotal which the coefficient is 1 + // po[1] + po[0] carry + Borrowed Bits - Reduction Factor 2^32 + po[1] += ((po[0] >> BASE_BITS) ^ borrow) - (carryLimbTotal << 32); + // po[2] + po[1] carry + Borrowing Bits - Lending Bits + po[2] += ((po[1] >> BASE_BITS) ^ borrow) - lend; + // po[3] + po[2] carry - Lending Bits + po[3] += (po[2] >> BASE_BITS) - lend; + + po[0] = (uint64_t)po[0]; // po[0] takes the basic digit. + po[1] = (uint64_t)po[1]; // po[1] takes the basic digit. + po[2] = (uint64_t)po[2]; // po[2] takes the basic digit. +} + +/* + * Field element reduction, converting 8-ary LongFelem to 4-ary Felem + * Input: + * in[] < 2^80 + * Output: + * out[] < 2^115 + * - out[0] < (2^114 + 2^82 - 2^50) + 2^(80 + 32) + 2 * 2^80 < 2^115 + * - out[1] < (2^114 + 2^82 - 2^50) + 2^(80 + 33) + 2 * 2^80 < 2^115 + * - out[2] < (2^114 + 2^82 - 2^50) + 2^(80 + 33) + 4 * 2^80 < 2^115 + * - out[3] < (2^114 + 2^82 - 2^50) + 2^(80 + 32) + 4 * 2^80 < 2^115 + * out[] > 0 + * - out[0] > (2^114 - 2^82) - 2 * 2^(80 + 32) - 2 * 2^80 > 0 + * - out[1] > (2^114 - 2^82) - 2^(80 + 32) - 2^80 > 0 + * - out[2] > (2^114 - 2^82) - 2^(80 + 32) - 2^80 > 0 + * - out[3] > (2^114 - 2^82) - 2 * 2^(80 + 32) - 2^80 > 0 + */ +static void LongFelemReduce(Felem *out, const LongFelem *in) +{ + // n ≡ n / a * (a - b) ≡ n / a * b (mod (a - b)) + // The following formula can be obtained: + // 2^n ≡ 2^(n - 256) * (2^224 - 2^192 - 2^96 + 1) (mod (2^256 - 2^224 + 2^192 + 2^96 - 1)) + // + // 2^256 mod p + // = 2^224 - 2^192 - 2^96 + 1 + // + // 2^288 mod p + // = 2^256 - 2^224 - 2^128 + 2^32 + // = -2^192 - 2^128 - 2^96 + 2^32 + 1 + // + // 2^320 mod p + // = 2^288 - 2^256 - 2^160 + 2^64 + // = -2^224 - 2^160 - 2^128 + 2^64 + 2^32 + // + // 2^352 mod p + // = 2^320 - 2^288 - 2^192 + 2^96 + // = -2^224 - 2^160 + 2 * 2^96 + 2^64 - 1 + // + // 2^384 mod p + // = 2^352 - 2^320 - 2^224 + 2^128 + // = -2^224 + 2 * 2^128 + 2 * 2^96 - 2^32 - 1 + // + // 2^416 mod p + // = 2^384 - 2^352 - 2^256 + 2^160 + // = -2^224 + 2^192 + 2 * 2^160 + 2 * 2^128 + 2^96 - 2^64 - 2^32 - 1 + // + // 2^448 mod p + // = 2^416 - 2^384 - 2^288 + 2^192 + // = 3 * 2^192 + 2 * 2^160 + 2^128 - 2^64 - 2^32 - 1 + // + // 2^480 mod p + // = 2^448 - 2^416 - 2^320 + 2^224 + // = 3 * 2^224 + 2 * 2^192 + 2^160 - 2^96 - 2^64 - 2^32 + + static const Felem zeroBase = { + { + (((uint128_t)1 << 64) - 1) << 50, + (((uint128_t)1 << 64) + ((uint128_t)1 << 32) - 1) << 50, + (((uint128_t)1 << 64) - 1) << 50, + (((uint128_t)1 << 64) - ((uint128_t)1 << 32)) << 50, + } + }; + + uint128_t *po = out->data; + const uint128_t *pi = in->data; + // Add the term reduced by pi[4]*2^256, pi[5]*2^320, pi[6]*2^384, pi[7]*2^448 to the corresponding digit. + // Assign a value after zero adjustment. + // Adjust to zero of digit 0. Take the input value pi[0]. + // The reduction item list is (pi[4], pi[5]*2^32, -pi[6] - pi[6]*2^32, -pi[7] - pi[7]*2^32) + po[0] = zeroBase.data[0] + pi[0] + pi[4] + (pi[5] << 32) - pi[6] - (pi[6] << 32) - pi[7] - (pi[7] << 32); + // Adjust to zero of digit 1. Take the input value pi[1]. + // The reduction item list is (-pi[4]*2^32, pi[5], pi[6]*2^33, -pi[7]) + po[1] = zeroBase.data[1] + pi[1] - (pi[4] << 32) + pi[5] + (pi[6] << 33) - pi[7]; + // Adjust to zero of digit 2. Take the input value pi[2]. + // The reduction item list is (0, -pi[5] - pi[5]*2^32, -pi[6]*2, pi[7] + pi[7]*2^33) + po[2] = zeroBase.data[2] + pi[2] - pi[5] - (pi[5] << 32) + (pi[6] << 1) + pi[7] + (pi[7] << 33); + // Adjust to zero of digit 3. Take the input value pi[3]. + // The reduction item list is (-pi[4] + pi[4]*2^32, -pi[5]*2^32, -pi[6]*2^32, pi[7]*3) + po[3] = zeroBase.data[3] + pi[3] - pi[4] + (pi[4] << 32) - (pi[5] << 32) - (pi[6] << 32) + (pi[7] * 3); +} + +/* + * field element modulo: convert the field element to a unique value within [0, p) + * Input: + * in[] < 2^64 + * Output: + * out < p, out[] < 2^64 + */ +static void FelemContract(Felem *out, const Felem *in) +{ + uint128_t *po = out->data; + const uint128_t *pi = in->data; + const uint128_t borrow = (uint128_t)1 << BASE_BITS; + const uint128_t lend = 1; + + bool isGreaterOrEqual = true; + for (int32_t i = 3; i >= 0; i--) { + if (pi[i] > FIELD_ORDER.data[i]) { + break; + } else if (pi[i] < FIELD_ORDER.data[i]) { + isGreaterOrEqual = false; + break; + } + } + + if (isGreaterOrEqual) { + // p_3 = 0xffffffff00000001 + po[3] = (pi[3] - lend) - FIELD_ORDER.data[3]; + // p_2 = 0x0000000000000000 + po[2] = (borrow ^ pi[2]) - lend; + // p_1 = 0x00000000ffffffff + po[1] = ((borrow ^ pi[1]) - lend) - FIELD_ORDER.data[1]; + // p_0 = 0xffffffffffffffff + po[0] = (borrow ^ pi[0]) - FIELD_ORDER.data[0]; + } + + // Process carry 0 -> 1 -> 2 -> 3 + po[1] += po[0] >> BASE_BITS; // po[1] + po[0] carry + po[2] += po[1] >> BASE_BITS; // po[2] + po[1] carry + po[3] += po[2] >> BASE_BITS; // po[3] + po[2] carry + + po[0] = (uint64_t)po[0]; // po[0] takes the basic digit. + po[1] = (uint64_t)po[1]; // po[1] takes the basic digit. + po[2] = (uint64_t)po[2]; // po[2] takes the basic digit. +} + +/* + * Field Addition + */ +static inline void FelemAdd(Felem *out, const Felem *a, const Felem *b) +{ + out->data[0] = a->data[0] + b->data[0]; // out->data[0] get the value + out->data[1] = a->data[1] + b->data[1]; // out->data[1] get the value + out->data[2] = a->data[2] + b->data[2]; // out->data[2] get the value + out->data[3] = a->data[3] + b->data[3]; // out->data[3] get the value +} + +/* + * Field element negation + * Input: + * in[] <= 2^124 - 2^92 + * Output: + * out[] <= 2^124 + 2^92 - 2^60 + in[] + */ +static inline void FelemNeg(Felem *out, const Felem *in) +{ + static const Felem zeroBase = {{ + (((uint128_t)1 << 64) - 1) << 60, + (((uint128_t)1 << 64) + ((uint128_t)1 << 32) - 1) << 60, + (((uint128_t)1 << 64) - 1) << 60, + (((uint128_t)1 << 64) - ((uint128_t)1 << 32)) << 60, + }}; + + out->data[0] = zeroBase.data[0] - in->data[0]; // out->data[0] get the value + out->data[1] = zeroBase.data[1] - in->data[1]; // out->data[1] get the value + out->data[2] = zeroBase.data[2] - in->data[2]; // out->data[2] get the value + out->data[3] = zeroBase.data[3] - in->data[3]; // out->data[3] get the value +} + +/* + * Field subtraction + * Input: + * a[] < 2^128 - 2^124 - 2^92 + 2^60,b[] <= 2^124 - 2^92 + * Output: + * out[] <= 2^124 + 2^92 - 2^60 + a[] < 2^128 + */ +static inline void FelemSub(Felem *out, const Felem *a, const Felem *b) +{ + static const Felem zeroBase = {{ + (((uint128_t)1 << 64) - 1) << 60, + (((uint128_t)1 << 64) + ((uint128_t)1 << 32) - 1) << 60, + (((uint128_t)1 << 64) - 1) << 60, + (((uint128_t)1 << 64) - ((uint128_t)1 << 32)) << 60, + }}; + + out->data[0] = zeroBase.data[0] + a->data[0] - b->data[0]; // out->data[0] get the value + out->data[1] = zeroBase.data[1] + a->data[1] - b->data[1]; // out->data[1] get the value + out->data[2] = zeroBase.data[2] + a->data[2] - b->data[2]; // out->data[2] get the value + out->data[3] = zeroBase.data[3] + a->data[3] - b->data[3]; // out->data[3] get the value +} + +/* + * Field subtraction. Input LongFelem directly. + * Input: + * a[] < 2^128 - 2^74 - 2^42 + 2^10,b[] <= 2^74 - 2^42 + * Output: + * out[] <= 2^74 + 2^42 - 2^10 + a[] < 2^128 + */ +static void LongFelemSub(LongFelem *out, const LongFelem *a, const LongFelem *b) +{ + static const LongFelem zeroBase = {{ + ((uint128_t)1 << 64) << 10, + (((uint128_t)1 << 64) - 1) << 10, + (((uint128_t)1 << 64) - 1) << 10, + (((uint128_t)1 << 64) - 1) << 10, + (((uint128_t)1 << 64) - 2) << 10, + (((uint128_t)1 << 64) + ((uint128_t)1 << 32) - 1) << 10, + (((uint128_t)1 << 64) - 1) << 10, + (((uint128_t)1 << 64) - ((uint128_t)1 << 32)) << 10, + }}; + + out->data[0] = zeroBase.data[0] + a->data[0] - b->data[0]; // out->data[0] get the value + out->data[1] = zeroBase.data[1] + a->data[1] - b->data[1]; // out->data[1] get the value + out->data[2] = zeroBase.data[2] + a->data[2] - b->data[2]; // out->data[2] get the value + out->data[3] = zeroBase.data[3] + a->data[3] - b->data[3]; // out->data[3] get the value + out->data[4] = zeroBase.data[4] + a->data[4] - b->data[4]; // out->data[4] get the value + out->data[5] = zeroBase.data[5] + a->data[5] - b->data[5]; // out->data[5] get the value + out->data[6] = zeroBase.data[6] + a->data[6] - b->data[6]; // out->data[6] get the value + out->data[7] = zeroBase.data[7] + a->data[7] - b->data[7]; // out->data[7] get the value +} + +/* + * Scale the field element + * Use only a small magnification(scale) factor to ensure that in[] * scalar does not overflow. + */ +static inline void FelemScale(Felem *out, const Felem *in, const uint32_t scalar) +{ + out->data[0] = in->data[0] * scalar; // out->data[0] get the value + out->data[1] = in->data[1] * scalar; // out->data[1] get the value + out->data[2] = in->data[2] * scalar; // out->data[2] get the value + out->data[3] = in->data[3] * scalar; // out->data[3] get the value +} + +/* + * Scale the field element. Input LongFelem directly. + * Use only a small magnification(scale) factor to ensure that in[] * scalar does not overflow. + */ +static inline void LongFelemScale(LongFelem *out, const LongFelem *in, const uint32_t scalar) +{ + out->data[0] = in->data[0] * scalar; // out->data[0] get the value + out->data[1] = in->data[1] * scalar; // out->data[1] get the value + out->data[2] = in->data[2] * scalar; // out->data[2] get the value + out->data[3] = in->data[3] * scalar; // out->data[3] get the value + out->data[4] = in->data[4] * scalar; // out->data[4] get the value + out->data[5] = in->data[5] * scalar; // out->data[5] get the value + out->data[6] = in->data[6] * scalar; // out->data[6] get the value + out->data[7] = in->data[7] * scalar; // out->data[7] get the value +} + +/* + * Field Multiplication + * Input: + * a[] < 2^64, b[] < 2^64 + * Output: + * out[] < 2^67 + * - out[0] < 2^64 + * - out[1] < 2^64 * 3 + * - out[2] < 2^64 * 5 + * - out[3] < 2^64 * 7 + * - out[4] < 2^64 * 7 + * - out[5] < 2^64 * 5 + * - out[6] < 2^64 * 3 + * - out[7] < 2^64 + */ +static void FelemMul(LongFelem *out, const Felem *a, const Felem *b) +{ + // out[0] = a[0]*b[0] + // out[1] = a[0]*b[1] + a[1]*b[0] + // out[2] = a[0]*b[2] + a[1]*b[1] + a[2]*b[0] + // out[3] = a[0]*b[3] + a[1]*b[2] + a[2]*b[1] + a[3]*b[0] + // out[4] = a[1]*b[3] + a[2]*b[2] + a[3]*b[1] + // out[5] = a[2]*b[3] + a[3]*b[2] + // out[6] = a[3]*b[3] + + const uint64_t a64[4] = {(uint64_t)a->data[0], (uint64_t)a->data[1], (uint64_t)a->data[2], (uint64_t)a->data[3]}; + const uint64_t b64[4] = {(uint64_t)b->data[0], (uint64_t)b->data[1], (uint64_t)b->data[2], (uint64_t)b->data[3]}; + uint128_t limbMul; + + // out[0] = a[0]*b[0] + limbMul = (uint128_t)a64[0] * b64[0]; // a[0] * b[0] + out->data[0] = (uint64_t)limbMul; // Digit 0 plus the basic digit + out->data[1] = limbMul >> BASE_BITS; // Digit 1 plus the carry + + // out[1] = a[0]*b[1] + a[1]*b[0] + limbMul = (uint128_t)a64[0] * b64[1]; // a[0] * b[1] + out->data[1] += (uint64_t)limbMul; // Digit 1 plus the basic digit + out->data[2] = limbMul >> BASE_BITS; // Digit 2 plus the carry + + limbMul = (uint128_t)a64[1] * b64[0]; // a[1] * b[0] + out->data[1] += (uint64_t)limbMul; // Digit 1 plus the basic digit + out->data[2] += limbMul >> BASE_BITS; // Digit 2 plus the carry + + // out[2] = a[0]*b[2] + a[1]*b[1] + a[2]*b[0] + limbMul = (uint128_t)a64[0] * b64[2]; // a[0] * b[2] + out->data[2] += (uint64_t)limbMul; // Digit 2 plus the basic digit + out->data[3] = limbMul >> BASE_BITS; // Digit 3 plus the carry + + limbMul = (uint128_t)a64[1] * b64[1]; // a[1] * a[1] + out->data[2] += (uint64_t)limbMul; // Digit 2 plus the basic digit + out->data[3] += limbMul >> BASE_BITS; // Digit 3 plus the carry + + limbMul = (uint128_t)a64[2] * b64[0]; // a[2] * b[0] + out->data[2] += (uint64_t)limbMul; // Digit 2 plus the basic digit + out->data[3] += limbMul >> BASE_BITS; // Digit 3 plus the carry + + // out[3] = a[0]*b[3] + a[1]*b[2] + a[2]*b[1] + a[3]*b[0] + limbMul = (uint128_t)a64[0] * b64[3]; // a[0] * b[3] + out->data[3] += (uint64_t)limbMul; // Digit 3 plus the basic digit + out->data[4] = limbMul >> BASE_BITS; // Digit 4 plus the carry + + limbMul = (uint128_t)a64[1] * b64[2]; // a[1] * b[2] + out->data[3] += (uint64_t)limbMul; // Digit 3 plus the basic digit + out->data[4] += limbMul >> BASE_BITS; // Digit 4 plus the carry + + limbMul = (uint128_t)a64[2] * b64[1]; // a[2] * b[1] + out->data[3] += (uint64_t)limbMul; // Digit 3 plus the basic digit + out->data[4] += limbMul >> BASE_BITS; // Digit 4 plus the carry + + limbMul = (uint128_t)a64[3] * b64[0]; // a[3] * b[0] + out->data[3] += (uint64_t)limbMul; // Digit 3 plus the basic digit + out->data[4] += limbMul >> BASE_BITS; // Digit 4 plus the carry + + // out[4] = a[1]*b[3] + a[2]*b[2] + a[3]*b[1] + limbMul = (uint128_t)a64[1] * b64[3]; // a[1] * b[3] + out->data[4] += (uint64_t)limbMul; // Digit 4 plus the basic digit + out->data[5] = limbMul >> BASE_BITS; // Digit 5 plus the carry + + limbMul = (uint128_t)a64[2] * b64[2]; // a[2] * b[2] + out->data[4] += (uint64_t)limbMul; // Digit 4 plus the basic digit + out->data[5] += limbMul >> BASE_BITS; // Digit 5 plus the carry + + limbMul = (uint128_t)a64[3] * b64[1]; // a[3] * b[1] + out->data[4] += (uint64_t)limbMul; // Digit 4 plus the basic digit + out->data[5] += limbMul >> BASE_BITS; // Digit 5 plus the carry + + // out[5] = a[2]*b[3] + a[3]*b[2] + limbMul = (uint128_t)a64[2] * b64[3]; // a[2] * b[3] + out->data[5] += (uint64_t)limbMul; // Digit 5 plus the basic digit + out->data[6] = limbMul >> BASE_BITS; // Digit 6 plus the carry + + limbMul = (uint128_t)a64[3] * b64[2]; // a[3] * b[2] + out->data[5] += (uint64_t)limbMul; // Digit 5 plus the basic digit + out->data[6] += limbMul >> BASE_BITS; // Digit 6 plus the carry + + // out[6] = a[3]*b[3] + limbMul = (uint128_t)a64[3] * b64[3]; // a[3] * b[3] + out->data[6] += (uint64_t)limbMul; // Digit 6 plus the basic digit + out->data[7] = limbMul >> BASE_BITS; // Digit 7 plus the carry +} + +/* + * Field square + * Input: + * a[] < 2^64 + * Output: + * out[] < 2^67 + * - out[0] < 2^64 + * - out[1] < 2^64 * 2 + * - out[2] < 2^64 * 4 + * - out[3] < 2^64 * 5 + * - out[4] < 2^64 * 6 + * - out[5] < 2^64 * 4 + * - out[6] < 2^64 * 3 + * - out[7] < 2^64 + */ +static void FelemSqr(LongFelem *out, const Felem *a) +{ + // out[0] = a[0]*a[0] + // out[1] = a[0]*a[1]*2 + // out[2] = a[0]*a[2]*2 + a[1]*a[1] + // out[3] = a[0]*a[3]*2 + a[1]*a[2]*2 + // out[4] = a[1]*a[3]*2 + a[2]*a[2] + // out[5] = a[2]*a[3]*2 + // out[6] = a[3]*a[3] + + const uint64_t a64[4] = {(uint64_t)a->data[0], (uint64_t)a->data[1], (uint64_t)a->data[2], (uint64_t)a->data[3]}; + uint128_t limbMul; + + // out[0] = a[0]*a[0] + limbMul = (uint128_t)a64[0] * a64[0]; // a[0] * a[0] + out->data[0] = (uint64_t)limbMul; // Digit 0 plus the basic digit + out->data[1] = limbMul >> BASE_BITS; // Digit 1 plus the carry + + // out[1] = a[0]*a[1]*2 + limbMul = (uint128_t)a64[0] * a64[1]; // a[0] * a[1] + out->data[1] += (uint64_t)limbMul << 1; // basic digit after the product is left shifted by 1bit, add to digit 1 + out->data[2] = limbMul >> (BASE_BITS - 1); // carry after product shift, add to digit 2 + + // out[2] = a[0]*a[2]*2 + a[1]*a[1] + limbMul = (uint128_t)a64[0] * a64[2]; // a[0] * a[2] + out->data[2] += (uint64_t)limbMul << 1; // basic digit after the product is left shifted by 1bit, add to digit 2 + out->data[3] = limbMul >> (BASE_BITS - 1); // carry after product shift, add to digit 3 + + limbMul = (uint128_t)a64[1] * a64[1]; // a[1] * a[1] + out->data[2] += (uint64_t)limbMul; // Digit 2 plus the basic digit + out->data[3] += limbMul >> BASE_BITS; // Digit 3 plus the carry + + // out[3] = a[0]*a[3]*2 + a[1]*a[2]*2 + limbMul = (uint128_t)a64[0] * a64[3]; // a[0] * a[3] + out->data[3] += (uint64_t)limbMul << 1; // basic digit after the product is left shifted by 1bit, add to digit 3 + out->data[4] = limbMul >> (BASE_BITS - 1); // carry after product shift, add to digit 4 + + limbMul = (uint128_t)a64[1] * a64[2]; // a[1] * a[2] + out->data[3] += (uint64_t)limbMul << 1; // basic digit after the product is left shifted by 1bit, add to digit 3 + out->data[4] += limbMul >> (BASE_BITS - 1); // carry after product shift, add to digit 4 + + // out[4] = a[1]*a[3]*2 + a[2]*a[2] + limbMul = (uint128_t)a64[1] * a64[3]; // a[1] * a[3] + out->data[4] += (uint64_t)limbMul << 1; // basic digit after the product is left shifted by 1bit, add to digit 4 + out->data[5] = limbMul >> (BASE_BITS - 1); // carry after product shift, add to digit 5 + + limbMul = (uint128_t)a64[2] * a64[2]; // a[2] * a[2] + out->data[4] += (uint64_t)limbMul; // Digit 4 plus the basic digit + out->data[5] += limbMul >> BASE_BITS; // Digit 5 plus the carry + + // out[5] = a[2]*a[3]*2 + limbMul = (uint128_t)a64[2] * a64[3]; // a[2] * a[3] + out->data[5] += (uint64_t)limbMul << 1; // basic digit after the product is left shifted by 1bit, add to digit 5 + out->data[6] = limbMul >> (BASE_BITS - 1); // carry after product shift, add to digit 6 + + // out[6] = a[3]*a[3] + limbMul = (uint128_t)a64[3] * a64[3]; // a[3] * a[3] + out->data[6] += (uint64_t)limbMul; // Digit 6 plus the basic digit + out->data[7] = limbMul >> BASE_BITS; // Digit 7 plus the carry +} + +static inline void FelemMulReduce(Felem *out, const Felem *a, const Felem *b) +{ + LongFelem ltmp; + FelemMul(<mp, a, b); + LongFelemReduce(out, <mp); +} + +static inline void FelemSqrReduce(Felem *out, const Felem *in) +{ + LongFelem ltmp; + FelemSqr(<mp, in); + LongFelemReduce(out, <mp); +} + +static inline void FelemMulReduceToBase(Felem *out, const Felem *a, const Felem *b) +{ + LongFelem ltmp; + FelemMul(<mp, a, b); + LongFelemReduce(out, <mp); + FelemReduce(out, out); +} + +static inline void FelemSqrReduceToBase(Felem *out, const Felem *in) +{ + LongFelem ltmp; + FelemSqr(<mp, in); + LongFelemReduce(out, <mp); + FelemReduce(out, out); +} + +/* + * Field element inversion + * From Fermat's small theorem, in^(p - 2) = in^(-1) (mod p) + * in^(-1) = in^(2^256 - 2^224 + 2^192 + 2^96 - 1 - 2) (mod p) + * Input: + * in[] < 2^64 + * Output: + * out[] < 2^64 + */ +static void FelemInv(Felem *out, const Felem *in) +{ + Felem inE3, inEf, inEff, inEffff, inEffffffff, inEfx16Lsh32, inEfffffffd; + + // Construct in^(p - 2) by moving left and adding. + // The value of p - 2 is as follows: + // ffffffff 00000001 + // 00000000 00000000 + // 00000000 ffffffff + // ffffffff fffffffd + + // Construct the {1, 3, f, ff, ffff, ffffffff} power of in by left shift and addition. + // Construct in^1 + FelemAssign(out, in); // in^1 + // Construct in^3 + FelemSqrReduceToBase(out, out); // in^2 + FelemMulReduceToBase(out, out, in); // in^3 + FelemAssign(&inE3, out); + // Construct in^f + FelemSqrReduceToBase(out, out); // in^6 + FelemSqrReduceToBase(out, out); // in^c + FelemMulReduceToBase(&inEfffffffd, out, in); // inEfffffffd = in^d + FelemMulReduceToBase(out, out, &inE3); // in^f + FelemAssign(&inEf, out); + // Construct in^ff + FelemSqrReduceToBase(out, out); // in^1e + FelemSqrReduceToBase(out, out); // in^3c + FelemSqrReduceToBase(out, out); // in^78 + FelemSqrReduceToBase(out, out); // in^f0 + FelemMulReduceToBase(&inEfffffffd, out, &inEfffffffd); // inEfffffffd = in^fd + FelemMulReduceToBase(out, out, &inEf); // in^ff + FelemAssign(&inEff, out); + // Construct in^ffff and shift ff to the left by 8 bits to obtain ff00 + for (int32_t i = 0; i < 8; ++i) { + FelemSqrReduceToBase(out, out); + } // in^ff00 + FelemMulReduceToBase(&inEfffffffd, out, &inEfffffffd); // inEfffffffd = in^fffd + FelemMulReduceToBase(out, out, &inEff); // in^ffff + FelemAssign(&inEffff, out); + // Construct in^ffffffff and shift ffff to the left by 16 bits to obtain ffff0000 + for (int32_t i = 0; i < 16; ++i) { + FelemSqrReduceToBase(out, out); + } // in^ffff0000 + FelemMulReduceToBase(&inEfffffffd, out, &inEfffffffd); // inEfffffffd = in^fffffffd + FelemMulReduceToBase(out, out, &inEffff); // in^ffffffff + FelemAssign(&inEffffffff, out); + + // Construct in^ffffffff ffffffff 00000000 + // Obtain in^ffffffff 00000000 and shift ffffffff to the left by 32 bits. + for (int32_t i = 0; i < 32; ++i) { + FelemSqrReduceToBase(out, out); + } // in^ffffffff 00000000 + FelemAssign(&inEfx16Lsh32, out); + // Then obtain ffffffff 00000000 00000000 and shift it leftwards by 32 bits. + for (int32_t i = 0; i < 32; ++i) { + FelemSqrReduceToBase(out, out); + } // out = in^ffffffff 00000000 00000000 + FelemMulReduceToBase(&inEfx16Lsh32, out, &inEfx16Lsh32); // inEfx16Lsh32 = in^ffffffff ffffffff 00000000 + + // Construct in^ffffffff 00000001 00000000 + FelemMulReduceToBase(out, out, &inEffffffff); // in^ffffffff 00000000 ffffffff + FelemMulReduceToBase(out, out, in); // in^ffffffff 00000001 00000000 + + // Shift leftward by 160 bits to the top. + for (int32_t i = 0; i < 160; ++i) { + FelemSqrReduceToBase(out, out); + } // in^ffffffff 00000001 00000000 00000000 00000000 00000000 00000000 00000000 + + // Construct in^ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff 00000000 + FelemMulReduceToBase(out, out, &inEfx16Lsh32); + // Construct in^ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffd + FelemMulReduceToBase(out, out, &inEfffffffd); +} + +/* --------------------------Point group operation-------------------------- */ +static inline void PtAssign(Point *out, const Point *in) +{ + FelemAssign(&out->x, &in->x); + FelemAssign(&out->y, &in->y); + FelemAssign(&out->z, &in->z); +} + +static inline void PtAssignWithMask(Point *out, const Point *in, const uint128_t mask) +{ + FelemAssignWithMask(&out->x, &in->x, mask); + FelemAssignWithMask(&out->y, &in->y, mask); + FelemAssignWithMask(&out->z, &in->z, mask); +} + +/* + * point double + * Algorithm reference: http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * Number of field operations: 3M + 5S + * delta = Z^2 + * gamma = Y^2 + * beta = X * gamma + * alpha = 3 * (X - delta) * (X + delta) + * X' = alpha^2 - 8 * beta + * Z' = (Y + Z)^2 - gamma - delta + * Y' = alpha * (4 * beta - X') - 8 * gamma^2 + * Input: + * in->x[], in->y[], in->z[] < 2^64 + * Output: + * out->x[], out->y[], out->z[] < 2^64 + */ +static void PtDouble(Point *out, const Point *in) +{ + Felem delta, gamma, beta, alpha; + Felem tmp, tmp2; + LongFelem ltmp, ltmp2; + + // delta = Z^2 + FelemSqrReduce(&delta, &in->z); // delta[] < 2^115 + + // gamma = Y^2 + FelemSqrReduceToBase(&gamma, &in->y); + + // beta = X * gamma + FelemMulReduce(&beta, &in->x, &gamma); // beta[] < 2^115 + + // alpha = 3 * (X - delta) * (X + delta) + FelemAdd(&tmp, &in->x, &delta); // tmp[] < 2^64 + 2^115 + FelemScale(&tmp, &tmp, 3); // 3 * (X + delta), tmp[] < (2^64 + 2^115) * 3 < 2^117 + FelemSub(&tmp2, &in->x, &delta); // tmp2[] < (2^124 + 2^92 - 2^60) + 2^64 < 2^125 + FelemReduce(&tmp, &tmp); + FelemReduce(&tmp2, &tmp2); + FelemMulReduceToBase(&alpha, &tmp, &tmp2); + + // X' = alpha^2 - 8 * beta + FelemSqrReduce(&tmp, &alpha); // alpha^2, tmp[] < 2^115 + FelemScale(&tmp2, &beta, 8); // 8 * beta, tmp2[] < 2^115 * 8 = 2^119 + FelemSub(&out->x, &tmp, &tmp2); // out->x[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&out->x, &out->x); // out->x[] < 2^64 + + // Z' = (Y + Z)^2 - gamma - delta + FelemAdd(&tmp, &in->y, &in->z); + FelemReduce(&tmp, &tmp); + FelemSqrReduce(&tmp, &tmp); // (Y + Z)^2, tmp[] < 2^115 + FelemAdd(&tmp2, &gamma, &delta); // (gamma + delta), tmp2[] < 2^64 + 2^115 < 2^116 + FelemSub(&out->z, &tmp, &tmp2); // out->z[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&out->z, &out->z); // out->z[] < 2^64 + + // Y' = alpha * (4 * beta - X') - 8 * gamma^2 + FelemScale(&beta, &beta, 4); // beta[] < 2^115 * 4 = 2^117 + FelemSub(&tmp, &beta, &out->x); + FelemReduce(&tmp, &tmp); + FelemMul(<mp, &alpha, &tmp); // alpha * (4 * beta - X'), ltmp[] < 2^67 + FelemSqr(<mp2, &gamma); + LongFelemScale(<mp2, <mp2, 8); // 8 * gamma^2, ltmp2[] < 2^67 * 8 < 2^70 + LongFelemSub(<mp, <mp, <mp2); // ltmp[] < (2^74 + 2^42 - 2^10) + 2^67 < 2^75 + LongFelemReduce(&out->y, <mp); // out->y[] < 2^115 + FelemReduce(&out->y, &out->y); // out->y[] < 2^64 +} + +/* + * point addition + * Algorithm reference: http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl + * Infinity point calculation is not supported. + * Number of field operations: 11M + 5S + * Z1Z1 = Z1^2 + * Z2Z2 = Z2^2 + * U1 = X1 * Z2Z2 + * U2 = X2 * Z1Z1 + * S1 = Y1 * Z2 * Z2Z2 + * S2 = Y2 * Z1 * Z1Z1 + * H = U2 - U1 + * I = (2 * H)^2 + * J = H * I + * r = 2 * (S2 - S1) + * V = U1 * I + * X3 = r^2 - J - 2 * V + * Y3 = r * (V - X3) - 2 * S1 * J + * Z3 = ((Z1 + Z2)^2 - Z1Z1 - Z2Z2) * H + * Input: + * a->x[], a->y[], a->z[] < 2^64 + * b->x[], b->y[], b->z[] < 2^64 + * Output: + * out->x[], out->y[], out->z[] < 2^64 + */ +static void PtAdd(Point *out, const Point *a, const Point *b) +{ + Point result; + Felem z1sqr, z2sqr, u1, u2, s1, s2, h, i, j, r, v; + Felem tmp; + LongFelem ltmp, ltmp2; + uint128_t isZ1Zero, isZ2Zero; + + // Z1Z1 = Z1^2 + FelemSqrReduceToBase(&z1sqr, &a->z); + + // Z2Z2 = Z2^2 + FelemSqrReduceToBase(&z2sqr, &b->z); + + isZ1Zero = 0 - FelemIsZero(&z1sqr); + isZ2Zero = 0 - FelemIsZero(&z2sqr); + + // U1 = X1 * Z2Z2 + FelemMulReduceToBase(&u1, &a->x, &z2sqr); + + // U2 = X2 * Z1Z1 + FelemMulReduce(&u2, &b->x, &z1sqr); // u2[] < 2^115 + + // S1 = Y1 * Z2 * Z2Z2 + FelemMulReduceToBase(&s1, &b->z, &z2sqr); + FelemMulReduceToBase(&s1, &a->y, &s1); + + // S2 = Y2 * Z1 * Z1Z1 + FelemMulReduceToBase(&s2, &a->z, &z1sqr); + FelemMulReduce(&s2, &b->y, &s2); // s2[] < 2^115 + + // H = U2 - U1 + FelemSub(&h, &u2, &u1); // h[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&h, &h); + + // r = 2 * (S2 - S1) + FelemSub(&r, &s2, &s1); // r[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemScale(&r, &r, 2); // r[] < 2^126 + FelemReduce(&r, &r); + + // H and r can determine whether x and y of the affine coordinates of two points are equal. + // If the values are equal, use double(). + if (isZ1Zero == 0 && isZ2Zero == 0 && FelemIsZero(&h) != 0 && FelemIsZero(&r) != 0) { + // Use a smaller b point + PtDouble(out, b); + return; + } + + // I = (2 * H)^2 + FelemSqrReduce(&i, &h); // H^2, i[] < 2^115 + FelemScale(&i, &i, 4); // 4 * H^2, i[] < 2^117 + FelemReduce(&i, &i); + + // J = H * I + FelemMulReduceToBase(&j, &h, &i); + + // V = U1 * I + FelemMulReduce(&v, &u1, &i); // v[] < 2^115 + + // X3 = r^2 - (J + 2 * V) + FelemSqrReduce(&result.x, &r); // result.x[] < 2^115 + FelemScale(&tmp, &v, 2); // tmp[] < 2^115 * 2 = 2^116 + FelemAdd(&tmp, &j, &tmp); // tmp[] < 2^64 + 2^116 < 2^117 + FelemSub(&result.x, &result.x, &tmp); // result.x[] < (2^124 + 2^90 - 2^60) + 2^115 < 2^125 + FelemReduce(&result.x, &result.x); // result.x[] < 2^64 + + // Y3 = r * (V - X3) - 2 * S1 * J + FelemSub(&tmp, &v, &result.x); + FelemReduce(&tmp, &tmp); + FelemMul(<mp, &r, &tmp); // r * (V - X3), ltmp[] < 2^67 + FelemMul(<mp2, &s1, &j); // ltmp2[] < 2^67 + LongFelemScale(<mp2, <mp2, 2); // 2 * S1 * J, ltmp2[] < 2^68 + LongFelemSub(<mp, <mp, <mp2); // ltmp[] < (2^74 + 2^42 - 2^10) + 2^67 < 2^75 + LongFelemReduce(&result.y, <mp); // result.y[] < 2^115 + FelemReduce(&result.y, &result.y); // result.y[] < 2^64 + + // Z3 = ((Z1 + Z2)^2 - Z1Z1 - Z2Z2) * H + FelemAdd(&result.z, &a->z, &b->z); + FelemReduce(&result.z, &result.z); + FelemSqrReduce(&result.z, &result.z); // (Z1 + Z2)^2 + FelemAdd(&tmp, &z1sqr, &z2sqr); // Z1Z1 + Z2Z2 + FelemSub(&result.z, &result.z, &tmp); // ((Z1 + Z2)^2 - Z1Z1 - Z2Z2) + FelemReduce(&result.z, &result.z); + FelemMulReduceToBase(&result.z, &result.z, &h); // result.z[] < 2^64 + + // Special case processing for infinity points + PtAssignWithMask(&result, a, isZ2Zero); + PtAssignWithMask(&result, b, isZ1Zero); + PtAssign(out, &result); +} + +/* + * Mixed point addition + * Algorithm reference: http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-madd-2007-bl + * Infinity point calculation is not supported. + * Number of field operations: 7M + 4S + * Z1Z1 = Z1^2 + * U2 = X2 * Z1Z1 + * S2 = Y2 * Z1 * Z1Z1 + * H = U2 - X1 + * HH = H^2 + * I = 4 * HH + * J = H * I + * r = 2 * (S2 - Y1) + * V = X1 * I + * X3 = r^2 - J - 2 * V + * Y3 = r * (V - X3) - 2 * Y1 * J + * Z3 = (Z1 + H)^2 - Z1Z1 - HH + * Input: + * a->x[] < 2^64, a->y[] < 2^64, a->z[] < 2^64 + * b->x < p, b->y < p, b->z = 0 或 1 + * Output: + * out->x[] < 2^64 + * out->y[] < 2^64 + * out->z[] < 2^64 + */ +static void PtAddMixed(Point *out, const Point *a, const Point *b) +{ + Point result; + Felem z1sqr, u2, s2, h, hsqr, i, j, r, v; + Felem tmp; + LongFelem ltmp, ltmp2; + uint128_t isZ1Zero, isZ2Zero; + + // Z1Z1 = Z1^2 + FelemSqrReduceToBase(&z1sqr, &a->z); + + isZ1Zero = 0 - FelemIsZero(&z1sqr); + // The Z coordinate of point b can only be 0 or 1, that is, digit 0 can only be 0 or 1, and the other digits are 0. + isZ2Zero = b->z.data[0] - 1; + + // U2 = X2 * Z1Z1 + FelemMulReduce(&u2, &b->x, &z1sqr); // u2[] < 2^115 + + // S2 = Y2 * Z1 * Z1Z1 + FelemMulReduceToBase(&s2, &a->z, &z1sqr); + FelemMulReduce(&s2, &b->y, &s2); // s2[] < 2^115 + + // H = U2 - X1 + FelemSub(&h, &u2, &a->x); // h[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&h, &h); + + // r = 2 * (S2 - Y1) + FelemSub(&r, &s2, &a->y); // r[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemScale(&r, &r, 2); // r[] < 2^126 + FelemReduce(&r, &r); + + // H and r can determine whether x and y of the affine coordinates of two points are equal. + // If the values are equal, use double(). + if (isZ1Zero == 0 && isZ2Zero == 0 && FelemIsZero(&h) != 0 && FelemIsZero(&r) != 0) { + // Use a smaller b point + PtDouble(out, b); + return; + } + + // HH = H^2 + FelemSqrReduce(&hsqr, &h); // hsqr[] < 2^115 + + // I = 4 * HH + FelemScale(&i, &hsqr, 4); // i[] < 2^117 + FelemReduce(&i, &i); + + // J = H * I + FelemMulReduceToBase(&j, &h, &i); + + // V = X1 * I + FelemMulReduce(&v, &a->x, &i); // v[] < 2^115 + + // X3 = r^2 - J - 2 * V + FelemSqrReduce(&result.x, &r); + FelemScale(&tmp, &v, 2); // tmp[] < 2^116 + FelemAdd(&tmp, &j, &tmp); // tmp[] < 2^64 + 2^116 < 2^117 + FelemSub(&result.x, &result.x, &tmp); // result.x[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&result.x, &result.x); // result.x[] < 2^64 + + // Y3 = r * (V - X3) - 2 * Y1 * J + FelemSub(&tmp, &v, &result.x); // tmp[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&tmp, &tmp); + FelemMul(<mp, &r, &tmp); // ltmp[] < 2^67 + FelemMul(<mp2, &a->y, &j); // ltmp2[] < 2^67 + LongFelemScale(<mp2, <mp2, 2); // ltmp2[] < 2^68 + LongFelemSub(<mp, <mp, <mp2); // ltmp[] < (2^74 + 2^42 - 2^10) + 2^67 < 2^75 + LongFelemReduce(&result.y, <mp); // result.y[] < 2^115 + FelemReduce(&result.y, &result.y); // result.y[] < 2^64 + + // Z3 = (Z1 + H)^2 - Z1Z1 - HH + FelemAdd(&result.z, &a->z, &h); // result.z[] < 2^64 + 2^64 = 2^65 + FelemReduce(&result.z, &result.z); + FelemSqrReduce(&result.z, &result.z); // result.z[] < 2^115 + FelemAdd(&tmp, &z1sqr, &hsqr); // tmp[] < 2^64 + 2^115 < 2^116 + FelemSub(&result.z, &result.z, &tmp); // result.z[] < (2^124 + 2^92 - 2^60) + 2^115 < 2^125 + FelemReduce(&result.z, &result.z); // result.z[] < 2^64 + + // Special case processing for infinity points + PtAssignWithMask(&result, a, isZ2Zero); + PtAssignWithMask(&result, b, isZ1Zero); + PtAssign(out, &result); +} + +/* Select the point with subscript index in the table and place it in the point. Anti-side channel process is exists. */ +static inline void GetPointFromTable(Point *point, const Point table[], uint32_t pointNum, const uint32_t index) +{ + uint128_t mask; + for (uint32_t i = 0; i < pointNum; i++) { + /* If i is equal to index, the last mask is all Fs. Otherwise, the last mask is all 0s. */ + mask = (0 - (i ^ index)) >> 31; // shifted rightwards by 31 bits and obtain the most significant bit. + mask--; + /* Conditional value assignment, valid only when i == index */ + PtAssignWithMask(point, &table[i], mask); + } +} + +/* + * Input: + * k1 < n + * 0 <= i < 32 + * Output: + * out->x < p, out->y < p, out->z = 0 或 1 + */ +static inline void GetLowerPrecomputePtOfG(Point *out, const Felem *k1, int32_t curBit) +{ + uint32_t bits; + uint32_t i = (uint32_t)curBit; + + bits = (uint32_t)(k1->data[0] >> i) & 1; // i-bit of the lower half of the digit 0 + bits |= ((uint32_t)(k1->data[1] >> i) & 1) << 1; // i-bit of the lower half of the digit 1 + bits |= ((uint32_t)(k1->data[2] >> i) & 1) << 2; // i-bit of the lower half of the digit 2 + bits |= ((uint32_t)(k1->data[3] >> i) & 1) << 3; // i-bit of the lower half of the digit 3 + + GetPointFromTable(out, PRE_MUL_G, TABLE_G_SIZE, bits); +} + +/* + * Input: + * k1 < n + * 0 <= i < 32 + * Output: + * out->x < p, out->y < p, out->z = 0 或 1 + */ +static inline void GetUpperPrecomputePtOfG(Point *out, const Felem *k1, int32_t curBit) +{ + uint32_t bits; + uint32_t i = (uint32_t)curBit; + + // i-bit of the upper half of the digit 0. (BASE_BITS/2) is the half width. + bits = (uint32_t)(k1->data[0] >> (i + BASE_BITS / 2)) & 1; + // i-bit of the upper half of the digit 1. (BASE_BITS/2) is the half width. + bits |= ((uint32_t)(k1->data[1] >> (i + BASE_BITS / 2)) & 1) << 1; + // i-bit of the upper half of the digit 2. (BASE_BITS/2) is the half width. + bits |= ((uint32_t)(k1->data[2] >> (i + BASE_BITS / 2)) & 1) << 2; + // i-bit of the upper half of the digit 3. (BASE_BITS/2) is the half width. + bits |= ((uint32_t)(k1->data[3] >> (i + BASE_BITS / 2)) & 1) << 3; + + GetPointFromTable(out, PRE_MUL_G2, TABLE_G_SIZE, bits); +} + +/* + * Input: + * k2 < n + * 0 <= i <= 255 + * The coordinates of each point of preMulPt are reduced. + * Output: + * out->x[] < 2^64, out->y[] < 2^64, out->z[] < 2^64 + */ +static inline void GetPrecomputePtOfP(Point *out, const Felem *k2, int32_t curBit, const Point preMulPt[TABLE_P_SIZE]) +{ + uint32_t bits; + uint32_t sign, value; // Indicates the grouping sign and actual value. + Felem negY; + // Obtain the 5-bit signed code. Read the sign bits of the next group of numbers + // to determine whether there is a carry. The total length is 6. + bits = (uint32_t)FelemGetBits(k2, curBit - 1, WINDOW_SIZE + 1); + DecodeScalarCode(&sign, &value, bits); + + GetPointFromTable(out, preMulPt, TABLE_P_SIZE, value); + + FelemNeg(&negY, &out->y); + FelemReduce(&negY, &negY); + FelemAssignWithMask(&out->y, &negY, (uint128_t)0 - sign); +} + +/* + * Calculate k1 * G + k2 * P + * Input: + * k1 < n + * k2 < n + * The coordinates of each point of preMulPt are reduced. + * Output: + * out->x < p, out->y < p, out->z < p + */ +static void PtMul(Point *out, const Felem *k1, const Felem *k2, const Point preMulPt[TABLE_P_SIZE]) +{ + Point ptQ = {}; // ptQ stores the result + Point ptPre = {}; // ptPre stores the points obtained from the table. + bool isGMul = k1 != NULL; + bool isPtMul = k2 != NULL && preMulPt != NULL; + int32_t curBit; + + // Initialize the Q point. + if (isPtMul) { + curBit = 255; // Start from 255th bit. + // Select the initial point from bit coding (_, _, _, _, 255, 254) of k2 + GetPrecomputePtOfP(&ptQ, k2, curBit, preMulPt); + } else if (isGMul) { + curBit = 31; // Start from 31. + // Select the initial point from bit coding (223, 159, 95, 31) of k1 + GetLowerPrecomputePtOfG(&ptQ, k1, curBit); + // Select a precomputation point from the (223 + 32, 159 + 32, 95 + 32, 31 + 32) bit of k1 + // and add the precomputation point to the point Q + GetUpperPrecomputePtOfG(&ptPre, k1, curBit); + PtAddMixed(&ptQ, &ptQ, &ptPre); + } else { + // k1 and k2 are NULL, output the infinite point. + (void)memset_s((void *)out, sizeof(Point), 0, sizeof(Point)); + return; + } + + // Operation chain: Q point output range: + // x[] y[] z[] + // Init value < 2^64 < 2^64 < 2^64 + // ↓ + // double ←↑ < 2^64 < 2^64 < 2^64 + // ↓ ↑ + // mixed add ↑ < 2^64 < 2^64 < 2^64 + // ↓ ↑ + // mixed add →↑ < 2^64 < 2^64 < 2^64 + // ↓ ↑ + // Y negation & reduction ↑ < 2^64 < 2^64 < 2^64 + // ↓ ↑ + // add →↑ < 2^64 < 2^64 < 2^64 + + while (--curBit >= 0) { + // Start to shift right bit by bit. Because the most significant bit is initialized, + // common point multiplication starts from 254th bit and base point multiplication starts from 30th bit. + // Whether G-point multiplication is performed in the current cycle. + // It is calculated once in each cycle starting from bit 31. + bool isStepGMul = curBit <= 31; + // Whether the current cycle is a common point multiplication, calculated once every 5 cycles + bool isStepPtMul = curBit % WINDOW_SIZE == 0; + + PtDouble(&ptQ, &ptQ); + + // Generator G-point multiplication part. + // Divide k1 into 8 segments, from high bits to low bits, select bits from each segment + // and combine them together, then read the pre-computation table. + // Specially, to shrink the precomputation table, the divided 8 segments are combined + // according to the upper half and the lower half. + if (isGMul && isStepGMul) { + // Add the point multiplication result of the current bit of the eight-segment packet to the point Q + GetLowerPrecomputePtOfG(&ptPre, k1, curBit); + PtAddMixed(&ptQ, &ptQ, &ptPre); + + GetUpperPrecomputePtOfG(&ptPre, k1, curBit); + PtAddMixed(&ptQ, &ptQ, &ptPre); + } + + // Common point multiplication part. + // Use the sliding window signed encoding method + // to group the most significant bits to the least significant bits every five bits. + // Each group of numbers is regarded as a signed number. 00000 to 01111 are decimal numbers 0 to 15, + // and 10000 to 11111 are decimal numbers (32-16) to (32-1). + // This is equivalent to the set of numbers in the complement form after carry 1. + // for example: + // 11011(complement) = 100000 - 00101 + if (isPtMul && isStepPtMul) { + // Add the point multiplication result of the current group to point Q. + GetPrecomputePtOfP(&ptPre, k2, curBit, preMulPt); + PtAdd(&ptQ, &ptQ, &ptPre); + } + } + + // Output the modulo operation. + FelemContract(&ptQ.x, &ptQ.x); + FelemContract(&ptQ.y, &ptQ.y); + FelemContract(&ptQ.z, &ptQ.z); + + PtAssign(out, &ptQ); +} + +/* + * Convert Jacobian coordinates to affine coordinates by a given module inverse + * Input: + * in->x[] < 2^64, in->y[] < 2^64 + * zInv < 2^64 + * Output: + * out->x < p, out->y < p, out->z = 1 + */ +static void PtMakeAffineWithInv(Point *out, const Point *in, const Felem *zInv) +{ + Felem tmp; + + // 1/Z^2 + FelemSqrReduceToBase(&tmp, zInv); + // X/Z^2 + FelemMulReduceToBase(&out->x, &in->x, &tmp); + FelemContract(&out->x, &out->x); + + // 1/Z^3 + FelemMulReduceToBase(&tmp, &tmp, zInv); + // Y/Z^3 + FelemMulReduceToBase(&out->y, &in->y, &tmp); + FelemContract(&out->y, &out->y); + + FelemSetLimb(&out->z, 1); +} + +/* --------------------------other functions-------------------------- */ +/* + * Obtain the pre-multiplication table of the input point pt, including 0pt-16pt. All points are reduced. + */ +static int32_t GetPreMulPt(Point preMulPt[TABLE_P_SIZE], const ECC_Point *pt) +{ + int32_t ret; + + // 0pt + (void)memset_s((void *)&preMulPt[0], sizeof(Point), 0, sizeof(Point)); + // 1pt + GOTO_ERR_IF_EX(BN2Felem(&preMulPt[1].x, pt->x), ret); + GOTO_ERR_IF_EX(BN2Felem(&preMulPt[1].y, pt->y), ret); + GOTO_ERR_IF_EX(BN2Felem(&preMulPt[1].z, pt->z), ret); + // 2pt ~ 15pt + for (uint32_t i = 2; i < 15; i += 2) { + PtDouble(&preMulPt[i], &preMulPt[i >> 1]); + PtAdd(&preMulPt[i + 1], &preMulPt[i], &preMulPt[1]); + } + // 16pt + PtDouble(&preMulPt[16], &preMulPt[16 >> 1]); +ERR: + return ret; +} + +int32_t ECP256_PointMulAdd( + ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt) +{ + int32_t ret; + Felem felemK1; + Felem felemK2; + Point preMulPt[TABLE_P_SIZE]; + Point out; + + // Check the input parameters. + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP256), ret); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP256), ret); + GOTO_ERR_IF(CheckBnValid(k1, FELEM_BITS), ret); + GOTO_ERR_IF(CheckBnValid(k2, FELEM_BITS), ret); + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP256), ret); + // Special treatment of infinity points + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + + GOTO_ERR_IF_EX(BN2Felem(&felemK1, k1), ret); + GOTO_ERR_IF_EX(BN2Felem(&felemK2, k2), ret); + GOTO_ERR_IF_EX(GetPreMulPt(preMulPt, pt), ret); + + PtMul(&out, &felemK1, &felemK2, preMulPt); + + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), ret); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), ret); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), ret); +ERR: + return ret; +} + +int32_t ECP256_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt) +{ + int32_t ret; + Felem felemK; + Point preMulPt[TABLE_P_SIZE]; + Point out; + + // Check the input parameters. + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP256), ret); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP256), ret); + GOTO_ERR_IF(CheckBnValid(k, FELEM_BITS), ret); + if (pt != NULL) { + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP256), ret); + // Special treatment of infinity points + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + } + + GOTO_ERR_IF_EX(BN2Felem(&felemK, k), ret); + if (pt != NULL) { + GOTO_ERR_IF_EX(GetPreMulPt(preMulPt, pt), ret); + PtMul(&out, NULL, &felemK, preMulPt); + } else { + PtMul(&out, &felemK, NULL, NULL); + } + + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), ret); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), ret); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), ret); +ERR: + return ret; +} + +int32_t ECP256_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt) +{ + int32_t ret; + Point out; + Felem zInv; + + // Check the input parameters. + GOTO_ERR_IF(CheckParaValid(para, CRYPT_ECC_NISTP256), ret); + GOTO_ERR_IF(CheckPointValid(r, CRYPT_ECC_NISTP256), ret); + GOTO_ERR_IF(CheckPointValid(pt, CRYPT_ECC_NISTP256), ret); + // Special treatment of infinity points + if (BN_IsZero(pt->z)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY); + return CRYPT_ECC_POINT_AT_INFINITY; + } + + GOTO_ERR_IF_EX(BN2Felem(&out.x, pt->x), ret); + GOTO_ERR_IF_EX(BN2Felem(&out.y, pt->y), ret); + GOTO_ERR_IF_EX(BN2Felem(&out.z, pt->z), ret); + + FelemInv(&zInv, &out.z); + PtMakeAffineWithInv(&out, &out, &zInv); + + GOTO_ERR_IF_EX(Felem2BN(r->x, &out.x), ret); + GOTO_ERR_IF_EX(Felem2BN(r->y, &out.y), ret); + GOTO_ERR_IF_EX(Felem2BN(r->z, &out.z), ret); +ERR: + return ret; +} + +int32_t ECP256_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (para->id != CRYPT_ECC_NISTP256) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + + if (BN_IsZero(a)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_INVERSE_INPUT_ZERO); + return CRYPT_ECC_INVERSE_INPUT_ZERO; + } + return ECP_ModOrderInv(para, r, a); +} + +#endif /* defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */ diff --git a/crypto/ecc/src/noasm_ecp_sm2.c b/crypto/ecc/src/noasm_ecp_sm2.c new file mode 100644 index 00000000..1a2f554d --- /dev/null +++ b/crypto/ecc/src/noasm_ecp_sm2.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_ECC) && defined(HITLS_CRYPTO_SM2) + +#include "ecp_sm2.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "bsl_err_internal.h" +#include "ecc_local.h" + +int32_t ECP_Sm2PointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + return ECP_NistPointDouble(para, r, a); +} + +int32_t ECP_Sm2PointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b) +{ + return ECP_NistPointAdd(para, r, a, b); +} + +int32_t ECP_Sm2PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *scalar, const ECC_Point *pt) +{ + return ECP_PointMul(para, r, scalar, pt); +} + +int32_t ECP_Sm2Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a) +{ + if (para == NULL || r == NULL || a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->id != CRYPT_ECC_SM2 || r->id != CRYPT_ECC_SM2 || a->id != CRYPT_ECC_SM2) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID); + return CRYPT_ECC_POINT_ERR_CURVE_ID; + } + return ECP_Point2Affine(para, r, a); +} +#endif diff --git a/crypto/ecdh/include/crypt_ecdh.h b/crypto/ecdh/include/crypt_ecdh.h new file mode 100644 index 00000000..67160f07 --- /dev/null +++ b/crypto/ecdh/include/crypt_ecdh.h @@ -0,0 +1,279 @@ +/* + * 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_ECDH_H +#define CRYPT_ECDH_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECDH + +#include +#include "crypt_types.h" +#include "crypt_algid.h" +#include "crypt_ecc_pkey.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/* ECDH key context */ +typedef struct ECC_PkeyCtx CRYPT_ECDH_Ctx; + +/* ECDH parameter structure */ +typedef struct EccPara CRYPT_EcdhPara; + +/** + * @ingroup ecdh + * @brief ecdh Allocate the context memory space. + * + * @retval (CRYPT_ECDH_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_ECDH_Ctx *CRYPT_ECDH_NewCtx(void); + +/** + * @ingroup ecdh + * @brief Copy the ECDH context. After the duplication is complete, call the CRYPT_ECDH_FreeCtx to release the memory. + * + * @param ctx [IN] Source ECDH context + * + * @return CRYPT_ECDH_Ctx ECDH context pointer + * If the operation fails, null is returned. + */ +CRYPT_ECDH_Ctx *CRYPT_ECDH_DupCtx(CRYPT_ECDH_Ctx *ctx); + +/** + * @ingroup ecdh + * @brief ecdh Release the key context structure + * + * @param ctx [IN] Indicate the pointer of the context structure to be released. The ctx is set NULL by the invoker. + */ +void CRYPT_ECDH_FreeCtx(CRYPT_ECDH_Ctx *ctx); + +/** + * @ingroup ecdh + * @brief Set a parameter based on the parameter ID. + * + * @param id [IN] Curve ID Parameter ID, which can be selected CRYPT_ECC_NISTP224 to CRYPT_ECC_BRAINPOOLP512R1 only + * from CRYPT_PKEY_ParaId. + * + * @retval (CRYPT_EcdhPara *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_EcdhPara *CRYPT_ECDH_NewParaById(CRYPT_PKEY_ParaId id); + +/** + * @ingroup ecdh + * @brief Set a parameter based on the eccPara parameter. + * + * @param eccPara [IN] Curve parameter information, + * which can be selected CRYPT_ECC_NISTP224 to CRYPT_ECC_BRAINPOOLP512R1 only from the CRYPT_PKEY_ParaId. + * + * @retval (CRYPT_EcdhPara *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_EcdhPara *CRYPT_ECDH_NewPara(const CRYPT_EccPara *eccPara); + +/** + * @ingroup ecdh + * @brief Obtain the parameter ID. + * + * @param ctx [IN] ECDH context + * + * @retval ID. If the context is invalid, CRYPT_PKEY_PARAID_MAX is returned. + */ +CRYPT_PKEY_ParaId CRYPT_ECDH_GetParaId(const CRYPT_ECDH_Ctx *ctx); + +/** + * @ingroup ecdh + * @brief ecdh Release a key parameter structure + * + * @param para [IN] Pointer to the key parameter structure to be released. The parameter is set NULL by the invoker. + */ +void CRYPT_ECDH_FreePara(CRYPT_EcdhPara *para); + +/** + * @ingroup ecdh + * @brief Set the data of the key parameter structure to the key structure. + * + * @param ctx [OUT] Key structure for setting related parameters + * @param para [IN] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_MEM_ALLOC_FAIL internal memory allocation error + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_ECDH_SetPara(CRYPT_ECDH_Ctx *ctx, const CRYPT_EcdhPara *para); + +/** + * @ingroup ecdh + * @brief Get the data of the key structure to the key parameter structure. + * + * @param ctx [IN] Key structure for setting related parameters + * @param para [OUT] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_MEM_ALLOC_FAIL Internal memory allocation error + * @retval CRYPT_SUCCESS Get successfully. + */ +int32_t CRYPT_ECDH_GetPara(const CRYPT_ECDH_Ctx *ctx, CRYPT_EccPara *para); + +/** + * @ingroup ecdh + * @brief Obtain the valid length of the private key, which is used before obtaining the private key. + * + * @param ctx [IN] Structure from which the key length is expected to be obtained + * + * @retval 0 The input is incorrect or the corresponding key structure does not have a valid key length. + * @retval uint32_t Valid key length + */ +uint32_t CRYPT_ECDH_GetBits(const CRYPT_ECDH_Ctx *ctx); + +/** + * @ingroup ecdh + * @brief Generate the ECDH key pair. + * + * @param ctx [IN] ECDH Context structure + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error code. Internal ECC calculation error + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_ECDH_Gen(CRYPT_ECDH_Ctx *ctx); + +/** + * @ingroup ecdh + * @brief ECDH key exchange + * + * @param ctx [IN] dh Context structure + * @param pubKey [IN] Public key data + * @param shareKey [OUT] Shared key + * @param shareKeyLen [IN/OUT] The input parameter is the space length of the shareKey, + * and the output parameter is the valid length of the shareKey. + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_ECDH_ERR_EMPTY_KEY The ctx private key is empty or the public key pubKey is empty. + * @retval CRYPT_ECDH_ERR_INVALID_COFACTOR Invalid harmonic factor h + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval ECC error code. Internal ECC calculation error + * @retval CRYPT_SUCCESS Key exchange succeeded. + */ +int32_t CRYPT_ECDH_ComputeShareKey(const CRYPT_ECDH_Ctx *ctx, const CRYPT_ECDH_Ctx *pubKey, + uint8_t *shareKey, uint32_t *shareKeyLen); + +/** + * @ingroup ecdh + * @brief ECDH Set the private key data. + * + * @param ctx [OUT] ecdh context structure + * @param prv [IN] Private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_ECDH_SetPrvKey(CRYPT_ECDH_Ctx *ctx, const CRYPT_EcdhPrv *prv); + +/** + * @ingroup ecdh + * @brief ECDH Set the public key data. + * + * @param ctx [OUT] ecdh context structure + * @param pub [IN] Public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_ECDH_SetPubKey(CRYPT_ECDH_Ctx *ctx, const CRYPT_EcdhPub *pub); + +/** + * @ingroup ecdh + * @brief ECDH Obtain the private key data. + * + * @param ctx [IN] ecdh context structure + * @param prv [OUT] Private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_ECC_PKEY_ERR_EMPTY_KEY The key is empty. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_ECDH_GetPrvKey(const CRYPT_ECDH_Ctx *ctx, CRYPT_EcdhPrv *prv); + +/** + * @ingroup ecdh + * @brief ECDH Obtain the public key data. + * + * @param ctx [IN] ecdh context structure + * @param pub [OUT] Public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_ECC_PKEY_ERR_EMPTY_KEY The key is empty. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_ECDH_GetPubKey(const CRYPT_ECDH_Ctx *ctx, CRYPT_EcdhPub *pub); + +/** + * @ingroup ecdh + * @brief ecdh control interface + * + * @param ctx [IN/OUT] ecdh context structure + * @param opt [IN] Operation mode. For details, see ECC_CtrlType. + * @param val [IN] Input parameter about ctrl + * @param len [IN] val Length + * + * @retval CRYPT_SUCCESS Set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT Invalid point format + * @retval CRYPT_ECC_PKEY_ERR_CTRL_LEN The len is incorrect. + * @retval CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION opt mode not supported + */ +int32_t CRYPT_ECDH_Ctrl(CRYPT_ECDH_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +/** + * @ingroup ecdh + * @brief ecdh Compare public keys and parameters + * + * @param a [IN] ecdh context structure + * @param b [IN] ecdh context structure + * + * @retval CRYPT_SUCCESS is the same + * Others. For details, see errno. + */ +int32_t CRYPT_ECDH_Cmp(const CRYPT_ECDH_Ctx *a, const CRYPT_ECDH_Ctx *b); + +/** + * @ingroup ecdh + * @brief ecdh get security bits + * + * @param para [IN] ecdh Context structure + * + * @retval security bits + */ +int32_t CRYPT_ECDH_GetSecBits(const CRYPT_ECDH_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ECDH + +#endif // CRYPT_ECDH_H diff --git a/crypto/ecdh/src/ecdh.c b/crypto/ecdh/src/ecdh.c new file mode 100644 index 00000000..986ee0fe --- /dev/null +++ b/crypto/ecdh/src/ecdh.c @@ -0,0 +1,243 @@ +/* + * 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_ECDH + +#include +#include "crypt_errno.h" +#include "crypt_types.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "crypt_ecc_pkey.h" +#include "crypt_ecdh.h" +#include "sal_atomic.h" + +CRYPT_ECDH_Ctx *CRYPT_ECDH_NewCtx(void) +{ + ECC_Pkey *ctx = BSL_SAL_Calloc(1u, sizeof(ECC_Pkey)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + ctx->useCofactorMode = true; + ctx->pointFormat = CRYPT_POINT_UNCOMPRESSED; // the point format is uncompressed by default + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +CRYPT_ECDH_Ctx *CRYPT_ECDH_DupCtx(CRYPT_ECDH_Ctx *ctx) +{ + return ECC_DupCtx(ctx); +} + +void CRYPT_ECDH_FreeCtx(CRYPT_ECDH_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + ECC_FreeCtx(ctx); + return; +} + +CRYPT_EcdhPara *CRYPT_ECDH_NewParaById(CRYPT_PKEY_ParaId id) +{ + return ECC_NewPara(id); +} + +CRYPT_EcdhPara *CRYPT_ECDH_NewPara(const CRYPT_EccPara *eccPara) +{ + if (eccPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + CRYPT_PKEY_ParaId id = ECC_GetCurveId(eccPara); + if (id == CRYPT_PKEY_PARAID_MAX) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA); + return NULL; + } + return CRYPT_ECDH_NewParaById(id); +} + +CRYPT_PKEY_ParaId CRYPT_ECDH_GetParaId(const CRYPT_ECDH_Ctx *ctx) +{ + if (ctx == NULL) { + return CRYPT_PKEY_PARAID_MAX; + } + return ECC_GetParaId(ctx->para); +} + +void CRYPT_ECDH_FreePara(CRYPT_EcdhPara *para) +{ + ECC_FreePara(para); +} + +int32_t CRYPT_ECDH_GetPara(const CRYPT_ECDH_Ctx *ctx, CRYPT_EccPara *para) +{ + return ECC_GetPara(ctx, para); +} + +int32_t CRYPT_ECDH_SetPara(CRYPT_ECDH_Ctx *ctx, const CRYPT_EcdhPara *para) +{ + if (ctx == NULL || para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + CRYPT_EcdhPara *dstPara = ECC_DupPara(para); + if (dstPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + // updating public and private keys + BN_Destroy(ctx->prvkey); + ECC_FreePoint(ctx->pubkey); + ctx->prvkey = NULL; + ctx->pubkey = NULL; + + ECC_FreePara(ctx->para); + ctx->para = dstPara; + + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_ECDH_GetBits(const CRYPT_ECDH_Ctx *ctx) +{ + return ECC_PkeyGetBits(ctx); +} + +int32_t CRYPT_ECDH_SetPrvKey(CRYPT_ECDH_Ctx *ctx, const CRYPT_EcdhPrv *prv) +{ + return ECC_PkeySetPrvKey(ctx, prv); +} + +int32_t CRYPT_ECDH_SetPubKey(CRYPT_ECDH_Ctx *ctx, const CRYPT_EcdhPub *pub) +{ + return ECC_PkeySetPubKey(ctx, pub); +} + +int32_t CRYPT_ECDH_GetPrvKey(const CRYPT_ECDH_Ctx *ctx, CRYPT_EcdhPrv *prv) +{ + return ECC_PkeyGetPrvKey(ctx, prv); +} + +int32_t CRYPT_ECDH_GetPubKey(const CRYPT_ECDH_Ctx *ctx, CRYPT_EcdhPub *pub) +{ + return ECC_PkeyGetPubKey(ctx, pub); +} + +int32_t CRYPT_ECDH_Gen(CRYPT_ECDH_Ctx *ctx) +{ + return ECC_PkeyGen(ctx); +} + +static int32_t ComputeShareKeyInputCheck(const CRYPT_ECDH_Ctx *ctx, const CRYPT_ECDH_Ctx *pubKey, + const uint8_t *shareKey, const uint32_t *shareKeyLen) +{ + if ((ctx == NULL) || (pubKey == NULL) || (shareKey == NULL) || (shareKeyLen == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if ((ctx->prvkey == NULL) || (pubKey->pubkey == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECDH_ERR_EMPTY_KEY); + return CRYPT_ECDH_ERR_EMPTY_KEY; + } + + // only the cofactor which value is 1 is supported currently + BN_BigNum *paraH = ECC_GetParaH(ctx->para); + if (paraH == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (BN_IsOne(paraH) != true) { + BN_Destroy(paraH); + BSL_ERR_PUSH_ERROR(CRYPT_ECDH_ERR_INVALID_COFACTOR); + return CRYPT_ECDH_ERR_INVALID_COFACTOR; + } + BN_Destroy(paraH); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_ECDH_ComputeShareKey(const CRYPT_ECDH_Ctx *ctx, const CRYPT_ECDH_Ctx *pubKey, + uint8_t *shareKey, uint32_t *shareKeyLen) +{ + int32_t ret = ComputeShareKeyInputCheck(ctx, pubKey, shareKey, shareKeyLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ECC_Point *sharePoint = NULL; + CRYPT_Data shareKeyX = {shareKey, *shareKeyLen}; + BN_BigNum *tmpPrvkey = BN_Dup(ctx->prvkey); + sharePoint = ECC_NewPoint(ctx->para); + if ((tmpPrvkey == NULL) || (sharePoint == NULL)) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + /** When the cofactor mode is enabled, pubkey = prvkey * h * G. When h is 1, no calculation is required. + * Currently, the cofactor of the prime curve is only 1, and no related calculation is required. + */ + ret = ECC_PointMul(ctx->para, sharePoint, ctx->prvkey, pubKey->pubkey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = ECC_PointCheck(sharePoint); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = ECC_GetPoint(ctx->para, sharePoint, &shareKeyX, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + *shareKeyLen = shareKeyX.len; + +ERR: + ECC_FreePoint(sharePoint); + BN_Destroy(tmpPrvkey); + return ret; +} + +int32_t CRYPT_ECDH_Ctrl(CRYPT_ECDH_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + return ECC_PkeyCtrl(ctx, opt, val, len); +} + +int32_t CRYPT_ECDH_Cmp(const CRYPT_ECDH_Ctx *a, const CRYPT_ECDH_Ctx *b) +{ + return ECC_PkeyCmp(a, b); +} + +int32_t CRYPT_ECDH_GetSecBits(const CRYPT_ECDH_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return ECC_GetSecBits(ctx->para); +} +#endif /* HITLS_CRYPTO_ECDH */ diff --git a/crypto/ecdsa/include/crypt_ecdsa.h b/crypto/ecdsa/include/crypt_ecdsa.h new file mode 100644 index 00000000..1370a79d --- /dev/null +++ b/crypto/ecdsa/include/crypt_ecdsa.h @@ -0,0 +1,313 @@ +/* + * 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_ECDSA_H +#define CRYPT_ECDSA_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECDSA + +#include +#include "crypt_types.h" +#include "crypt_ecc_pkey.h" +#include "crypt_ecc.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/* ECDSA key context */ +typedef struct ECC_PkeyCtx CRYPT_ECDSA_Ctx; + +/* ECDSA parameter structure */ +typedef struct EccPara CRYPT_EcdsaPara; + +/** + * @ingroup ecdsa + * @brief ecdsa Allocate context memory space. + * + * @retval (CRYPT_ECDSA_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_ECDSA_Ctx *CRYPT_ECDSA_NewCtx(void); + +/** + * @ingroup ecdsa + * @brief Copy the ECDSA context. After the duplication is complete, call the CRYPT_ECDSA_FreeCtx to release the memory. + * + * @param ctx [IN] Source ECDSA context + * + * @return CRYPT_ECDSA_Ctx ECDSA context pointer + * If it fails, null is returned. + */ +CRYPT_ECDSA_Ctx *CRYPT_ECDSA_DupCtx(CRYPT_ECDSA_Ctx *ctx); + +/** + * @ingroup ecdsa + * @brief ecdsa Releasing the key context structure + * + * @param ctx [IN] Pointer to the context structure to be released. The ctx is set NULL by the invoker. + */ +void CRYPT_ECDSA_FreeCtx(CRYPT_ECDSA_Ctx *ctx); + +/** + * @ingroup ecdsa + * @brief ecdsa Generate the key parameter structure + * + * @param id [IN] Curve ID Parameter ID, which can be selected CRYPT_ECC_NISTP224 to CRYPT_ECC_NISTP521 only + * from CRYPT_PKEY_ParaId. + * + * @retval (CRYPT_EcdsaPara *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_EcdsaPara *CRYPT_ECDSA_NewParaById(CRYPT_PKEY_ParaId id); + +/** + * @ingroup ecdsa + * @brief ecdsa Generate the key parameter structure + * + * @param eccPara [IN] Curve parameter information, which can be selected CRYPT_ECC_NISTP224 to CRYPT_ECC_NISTP521 only + * from CRYPT_PKEY_ParaId. + * + * @retval (CRYPT_EcdsaPara *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer + */ +CRYPT_EcdsaPara *CRYPT_ECDSA_NewPara(const CRYPT_EccPara *eccPara); + +/** + * @ingroup ecdsa + * @brief Obtain the parameter ID. + * + * @param ctx [IN] ECDSA context + * + * @retval ID. If the context is invalid, CRYPT_PKEY_PARAID_MAX is returned. + */ +CRYPT_PKEY_ParaId CRYPT_ECDSA_GetParaId(const CRYPT_ECDSA_Ctx *ctx); + +/** + * @ingroup ecdsa + * @brief ecdsa Release the key parameter structure + * + * @param para [IN] Pointer to the key parameter structure to be released. The parameter is set NULL by the invoker. + */ +void CRYPT_ECDSA_FreePara(CRYPT_EcdsaPara *para); + +/** + * @ingroup ecdsa + * @brief Set the data of the key parameter structure to the key structure. + * + * @param ctx [OUT] Key structure for which related parameters need to be set + * @param para [IN] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Internal memory allocation error + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_ECDSA_SetPara(CRYPT_ECDSA_Ctx *ctx, const CRYPT_EcdsaPara *para); + +/** + * @ingroup ecdsa + * @brief Obtain the key parameter structure. + * + * @param ctx [IN] Key structure for which related parameters need to be get + * @param para [OUT] Key parameters + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Internal memory allocation error + * @retval CRYPT_SUCCESS Get parameters successfully. + */ +int32_t CRYPT_ECDSA_GetPara(const CRYPT_ECDSA_Ctx *ctx, CRYPT_EccPara *para); + +/** + * @ingroup ecdsa + * @brief ecdsa Obtain the key length. + * + * @param ctx [IN] ecdsa context structure + * + * @retval 0 The input is incorrect or the corresponding key structure does not contain valid key length. + * @retval uint32_t Valid key length + */ +uint32_t CRYPT_ECDSA_GetBits(const CRYPT_ECDSA_Ctx *ctx); + +/** + * @ingroup ecdsa + * @brief ecdsa Obtains the length required for signing. + * + * @param ctx [IN] ecdsa context structure + * + * @retval 0 The input is incorrect or the corresponding key structure does not contain valid parameter data. + * @retval uint32_t Length required for valid signature data + */ +uint32_t CRYPT_ECDSA_GetSignLen(const CRYPT_ECDSA_Ctx *ctx); + +/** + * @ingroup ecdsa + * @brief Generate the ECDSA key pair. + * + * @param ctx [IN/OUT] ecdsa context structure + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error code. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_ECDSA_Gen(CRYPT_ECDSA_Ctx *ctx); + +/** + * @ingroup ecdsa + * @brief ECDSA Signature + * + * @param ctx [IN] ecdsa context structure + * @param data [IN] Data to be signed + * @param dataLen [IN] Length of the data to be signed + * @param sign [OUT] Signature data + * @param signLen [IN/OUT] The input parameter is the space length of the sign, + * and the output parameter is the valid length of the sign. + * The required space can be obtained by calling CRYPT_ECDSA_GetSignLen. + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_ECDSA_ERR_EMPTY_KEY The key cannot be empty. + * @retval CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Signed successfully. + */ +int32_t CRYPT_ECDSA_Sign(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen); + +/** + * @ingroup ecdsa + * @brief ECDSA Verification + * + * @param ctx [IN] ecdsa context structure + * @param data [IN] Data to be signed + * @param dataLen [IN] Length of the data to be signed + * @param sign [IN] Signature data + * @param signLen [IN] Valid length of the sign + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_ECDSA_VERIFY_FAIL Failed to verify the signature. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval DSA error. An error occurs in the DSA encoding and decoding part. + * @retval CRYPT_SUCCESS The signature is verified successfully. + */ +int32_t CRYPT_ECDSA_Verify(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen); + +/** + * @ingroup ecdsa + * @brief ECDSA Set the private key data. + * + * @param ctx [OUT] ecdsa context structure + * @param prv [IN] External private key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_ECDSA_SetPrvKey(CRYPT_ECDSA_Ctx *ctx, const CRYPT_DsaPrv *prv); + +/** + * @ingroup ecdsa + * @brief ECDSA Set the public key data. + * + * @param ctx [OUT] ecdsa context structure + * @param pub [IN] External public key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Set successfully. + */ +int32_t CRYPT_ECDSA_SetPubKey(CRYPT_ECDSA_Ctx *ctx, const CRYPT_DsaPub *pub); + +/** + * @ingroup ecdsa + * @brief ECDSA Obtain the private key data. + * + * @param ctx [IN] ecdsa context structure + * @param prv [OUT] External private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_ECC_PKEY_ERR_EMPTY_KEY The key is empty. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_ECDSA_GetPrvKey(const CRYPT_ECDSA_Ctx *ctx, CRYPT_DsaPrv *prv); + +/** + * @ingroup ecdsa + * @brief ECDSA Obtain the public key data. + * + * @param ctx [IN] ecdsa context structure + * @param pub [OUT] External public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_ECC_PKEY_ERR_EMPTY_KEY The key is empty. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_ECDSA_GetPubKey(const CRYPT_ECDSA_Ctx *ctx, CRYPT_DsaPub *pub); + +/** + * @ingroup ecdsa + * @brief ecdsa control interface + * + * @param ctx [IN/OUT] ecdsa context structure + * @param opt [IN] Operation mode. For details, see ECC_CtrlType. + * @param val [IN] Input parameter + * @param len [IN] val length + * + * @retval CRYPT_SUCCESS Set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT Invalid point format + * @retval CRYPT_ECC_PKEY_ERR_CTRL_LEN The length of len is incorrect. + * @retval CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION The opt mode is not supported. + */ +int32_t CRYPT_ECDSA_Ctrl(CRYPT_ECDSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +/** + * @ingroup ecdsa + * @brief ecdsa Compare public keys and parameters + * + * @param a [IN] ecdsa Context structure + * @param b [IN] ecdsa context structure + * + * @retval CRYPT_SUCCESS is the same + * Others. For details, see error code in errno. + */ +int32_t CRYPT_ECDSA_Cmp(const CRYPT_ECDSA_Ctx *a, const CRYPT_ECDSA_Ctx *b); + +/** + * @ingroup ecdsa + * @brief ecdsa get security bits + * + * @param para [IN] ecdsa Context structure + * + * @retval security bits + */ +int32_t CRYPT_ECDSA_GetSecBits(const CRYPT_ECDSA_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ECDSA + +#endif // CRYPT_ECDSA_H diff --git a/crypto/ecdsa/src/ecdsa.c b/crypto/ecdsa/src/ecdsa.c new file mode 100644 index 00000000..df510be2 --- /dev/null +++ b/crypto/ecdsa/src/ecdsa.c @@ -0,0 +1,515 @@ +/* + * 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_ECDSA + +#include +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_utils.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_encode.h" +#include "crypt_ecc.h" +#include "crypt_ecc_pkey.h" +#include "crypt_ecdsa.h" + +CRYPT_ECDSA_Ctx *CRYPT_ECDSA_NewCtx(void) +{ + CRYPT_ECDSA_Ctx *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_ECDSA_Ctx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + ctx->pointFormat = CRYPT_POINT_UNCOMPRESSED; // point format is uncompressed by default. + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +CRYPT_ECDSA_Ctx *CRYPT_ECDSA_DupCtx(CRYPT_ECDSA_Ctx *ctx) +{ + return ECC_DupCtx(ctx); +} + +void CRYPT_ECDSA_FreeCtx(CRYPT_ECDSA_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + ECC_FreeCtx(ctx); + return; +} + +CRYPT_EcdsaPara *CRYPT_ECDSA_NewParaById(CRYPT_PKEY_ParaId id) +{ + return ECC_NewPara(id); +} + +CRYPT_EcdsaPara *CRYPT_ECDSA_NewPara(const CRYPT_EccPara *eccPara) +{ + if (eccPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + CRYPT_PKEY_ParaId id = ECC_GetCurveId(eccPara); + if (id == CRYPT_PKEY_PARAID_MAX) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA); + return NULL; + } + return CRYPT_ECDSA_NewParaById(id); +} + +CRYPT_PKEY_ParaId CRYPT_ECDSA_GetParaId(const CRYPT_ECDSA_Ctx *ctx) +{ + if (ctx == NULL) { + return CRYPT_PKEY_PARAID_MAX; + } + return ECC_GetParaId(ctx->para); +} + +void CRYPT_ECDSA_FreePara(CRYPT_EcdsaPara *para) +{ + ECC_FreePara(para); +} + +int32_t CRYPT_ECDSA_GetPara(const CRYPT_ECDSA_Ctx *ctx, CRYPT_EccPara *para) +{ + return ECC_GetPara(ctx, para); +} + +int32_t CRYPT_ECDSA_SetPara(CRYPT_ECDSA_Ctx *ctx, const CRYPT_EcdsaPara *para) +{ + if ((ctx == NULL) || (para == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + CRYPT_EcdsaPara *dstPara = ECC_DupPara(para); + if (dstPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + // Refresh the public and private keys. + BN_Destroy(ctx->prvkey); + ctx->prvkey = NULL; + ECC_FreePoint(ctx->pubkey); + ctx->pubkey = NULL; + + ECC_FreePara(ctx->para); + ctx->para = dstPara; + + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_ECDSA_GetBits(const CRYPT_ECDSA_Ctx *ctx) +{ + return ECC_PkeyGetBits(ctx); +} + +int32_t CRYPT_ECDSA_SetPrvKey(CRYPT_ECDSA_Ctx *ctx, const CRYPT_EcdsaPrv *prv) +{ + return ECC_PkeySetPrvKey(ctx, prv); +} + +int32_t CRYPT_ECDSA_SetPubKey(CRYPT_ECDSA_Ctx *ctx, const CRYPT_EcdsaPub *pub) +{ + return ECC_PkeySetPubKey(ctx, pub); +} + +int32_t CRYPT_ECDSA_GetPrvKey(const CRYPT_ECDSA_Ctx *ctx, CRYPT_EcdsaPrv *prv) +{ + return ECC_PkeyGetPrvKey(ctx, prv); +} + +int32_t CRYPT_ECDSA_GetPubKey(const CRYPT_ECDSA_Ctx *ctx, CRYPT_EcdsaPub *pub) +{ + return ECC_PkeyGetPubKey(ctx, pub); +} + +int32_t CRYPT_ECDSA_Gen(CRYPT_ECDSA_Ctx *ctx) +{ + return ECC_PkeyGen(ctx); +} + +uint32_t CRYPT_ECDSA_GetSignLen(const CRYPT_ECDSA_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + + /** + * https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer + * If the integer is positive but the high order bit is set to 1, + * a leading 0x00 is added to the content to indicate that the number is not negative + */ + // When the number of bits is a multiple of 8 and the most significant bit is 1, 0x00 needs to be added. + // If the number of bits is not a multiple of 8, + // an extra byte needs to be added to store the data with less than 8 bits. + uint32_t qLen = (ECC_ParaBits(ctx->para) / 8) + 1; // divided by 8 to converted to bytes + return ASN1_SignEnCodeLen(qLen, qLen); +} + +static void EcdsaSignFree(DSA_Sign *sign) +{ + if (sign == NULL) { + return; + } + BN_Destroy(sign->r); + BN_Destroy(sign->s); + BSL_SAL_FREE(sign); + return; +} + +static DSA_Sign *EcdsaSignNew(const CRYPT_ECDSA_Ctx *ctx) +{ + DSA_Sign *sign = BSL_SAL_Malloc(sizeof(DSA_Sign)); + if (sign == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + uint32_t keyBits = ECC_PkeyGetBits(ctx); + sign->r = BN_Create(keyBits); + sign->s = BN_Create(keyBits); + if ((sign->r == NULL) || (sign->s == NULL)) { + EcdsaSignFree(sign); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + return sign; +} + +// Obtain the input hash data. For details, see RFC6979-2.4.1 and RFC6979-2.3.2 +static BN_BigNum *GetBnByData(BN_BigNum *n, const uint8_t *data, uint32_t dataLen) +{ + int32_t ret; + uint32_t nBits = BN_Bits(n); + BN_BigNum *d = BN_Create(nBits); // each byte has 8bits + if (d == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + if (data == NULL) { + return d; + } + + uint32_t dLen = dataLen; + if (8 * dLen > nBits) { // bytes * 8 = bits + dLen = (nBits + 7) >> 3; // Add 7 and shift rightward by 3 (equal to /8) to achieve the effect of bits2bytes. + } + // The input parameters of the function have been verified, and no failure case exists. + (void)BN_Bin2Bn(d, data, dLen); + if (8 * dLen > nBits) { // bytes * 8 = bits + // Subtracted by 8 and &7 to be accurate to bits. + if ((ret = BN_Rshift(d, d, (8 - (nBits & 7)))) != CRYPT_SUCCESS) { + BN_Destroy(d); + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + } + + return d; +} + +static int32_t EcdsaSignCore(const CRYPT_ECDSA_Ctx *ctx, BN_BigNum *d, + BN_BigNum *r, BN_BigNum *s) +{ + uint32_t keyBits = CRYPT_ECDSA_GetBits(ctx); // input parameter has been checked externally. + BN_BigNum *k = BN_Create(keyBits); + BN_BigNum *k2 = BN_Create(keyBits); + BN_BigNum *paraN = ECC_GetParaN(ctx->para); + ECC_Point *pt = ECC_NewPoint(ctx->para); + BN_BigNum *ptX = BN_Create(keyBits); + BN_Optimizer *opt = BN_OptimizerCreate(); + int32_t ret; + int32_t i; + + if ((k == NULL) || (k2 == NULL) || (pt == NULL) || (paraN == NULL) || (opt == NULL) || (ptX == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + + for (i = 0; i < CRYPT_ECC_TRY_MAX_CNT; i++) { + GOTO_ERR_IF(BN_RandRange(k, paraN), ret); + if (BN_IsZero(k)) { + continue; + } + + // pt = k * G + GOTO_ERR_IF(ECC_PointMul(ctx->para, pt, k, NULL), ret); + + // r = pt->x mod n + GOTO_ERR_IF_EX(ECC_GetPointDataX(ctx->para, pt, ptX), ret); + GOTO_ERR_IF(BN_Mod(r, ptX, paraN, opt), ret); + + // if r == 0, then restart + if (BN_IsZero(r)) { + continue; + } + + // prvkey * r mod n + GOTO_ERR_IF(BN_ModMul(s, ctx->prvkey, r, paraN, opt), ret); + + // hash + prvkey * r mod n + GOTO_ERR_IF(BN_ModAddQuick(s, d, s, paraN, opt), ret); + + // 1/k mod n + GOTO_ERR_IF(ECC_ModOrderInv(ctx->para, k2, k), ret); + + // s = (1/k) * (hash + prvkey * r) mod n + GOTO_ERR_IF(BN_ModMul(s, k2, s, paraN, opt), ret); + + // if s == 0, then restart + if (BN_IsZero(s) != true) { + break; + } + } + + if (i >= CRYPT_ECC_TRY_MAX_CNT) { + BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_TRY_CNT); + ret = CRYPT_ECDSA_ERR_TRY_CNT; + } + +ERR: + BN_Destroy(k); + BN_Destroy(k2); + BN_Destroy(paraN); + BN_Destroy(ptX); + ECC_FreePoint(pt); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t CryptEcdsaSign(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + BN_BigNum **r, BN_BigNum **s) +{ + int32_t rc = CRYPT_SUCCESS; + BN_BigNum *signR = NULL; + BN_BigNum *signS = NULL; + BN_BigNum *d = NULL; + BN_BigNum *paraN = ECC_GetParaN(ctx->para); + if (paraN == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + uint32_t keyBits = ECC_PkeyGetBits(ctx); + signR = BN_Create(keyBits); + signS = BN_Create(keyBits); + if ((signR == NULL) || (signS == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + rc = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + + d = GetBnByData(paraN, data, dataLen); + if (d == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + rc = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + GOTO_ERR_IF_EX(EcdsaSignCore(ctx, d, signR, signS), rc); + + *r = signR; + *s = signS; + goto OK; +ERR: + BN_Destroy(signR); + BN_Destroy(signS); +OK: + BN_Destroy(paraN); + BN_Destroy(d); + return rc; +} + +// Data with a value of 0 can also be signed. +int32_t CRYPT_ECDSA_Sign(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen) +{ + if ((ctx == NULL) || (ctx->para == NULL) || (sign == NULL) || (signLen == NULL) || + ((data == NULL) && (dataLen != 0))) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->prvkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_EMPTY_KEY); + return CRYPT_ECDSA_ERR_EMPTY_KEY; + } + + if (*signLen < CRYPT_ECDSA_GetSignLen(ctx)) { + BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH; + } + + int32_t ret; + BN_BigNum *r = NULL; + BN_BigNum *s = NULL; + ret = CryptEcdsaSign(ctx, data, dataLen, &r, &s); + if (ret != CRYPT_SUCCESS) { + return ret; + } + DSA_Sign dsaSign = {r, s}; + ret = ASN1_SignDataEncode(&dsaSign, sign, signLen); + BN_Destroy(r); + BN_Destroy(s); + return ret; +} + +static int32_t VrifyCheckSign(const CRYPT_ECDSA_Ctx *ctx, const DSA_Sign *sign) +{ + int32_t ret = CRYPT_SUCCESS; + BN_BigNum *paraN = ECC_GetParaN(ctx->para); + if (paraN == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + if ((BN_Cmp(sign->r, paraN) >= 0) || (BN_Cmp(sign->s, paraN) >= 0)) { + ret = CRYPT_ECDSA_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (BN_IsZero(sign->r) || BN_IsZero(sign->s)) { + ret = CRYPT_ECDSA_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } + +ERR: + BN_Destroy(paraN); + return ret; +} + +static int32_t EcdsaVerifyCore(const CRYPT_ECDSA_Ctx *ctx, BN_BigNum *d, const DSA_Sign *sign) +{ + uint32_t keyBits = CRYPT_ECDSA_GetBits(ctx); + BN_BigNum *w = BN_Create(keyBits); + BN_BigNum *u1 = BN_Create(keyBits); + BN_BigNum *u2 = BN_Create(keyBits); + BN_BigNum *v = BN_Create(keyBits); + BN_BigNum *paraN = ECC_GetParaN(ctx->para); + BN_Optimizer *opt = BN_OptimizerCreate(); + ECC_Point *tpt = ECC_NewPoint(ctx->para); + BN_BigNum *tptX = BN_Create(keyBits); + int32_t ret; + + if ((w == NULL) || (u1 == NULL) || (u2 == NULL) || (v == NULL) || + (tpt == NULL) || (paraN == NULL) || (opt == NULL) || (tptX == NULL)) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // w = 1/s mod n + GOTO_ERR_IF(ECC_ModOrderInv(ctx->para, w, sign->s), ret); + + // u1 = msg*(1/s) mod n + GOTO_ERR_IF(BN_ModMul(u1, d, w, paraN, opt), ret); + + // u2 = r*(1/s) mod n + GOTO_ERR_IF(BN_ModMul(u2, sign->r, w, paraN, opt), ret); + + // tpt : u1*G + u2*pubkey + GOTO_ERR_IF(ECC_PointMulAdd(ctx->para, tpt, u1, u2, ctx->pubkey), ret); + + GOTO_ERR_IF(ECC_GetPointDataX(ctx->para, tpt, tptX), ret); + GOTO_ERR_IF(BN_Mod(v, tptX, paraN, opt), ret); + + if (BN_Cmp(v, sign->r) != 0) { + BSL_ERR_PUSH_ERROR(ret); + ret = CRYPT_ECDSA_VERIFY_FAIL; + } + +ERR: + BN_Destroy(w); + BN_Destroy(u1); + BN_Destroy(u2); + BN_Destroy(v); + BN_Destroy(paraN); + ECC_FreePoint(tpt); + BN_Destroy(tptX); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t CRYPT_ECDSA_Verify(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen) +{ + if ((ctx == NULL) || (ctx->para == NULL) || ((data == NULL) && (dataLen != 0)) || + (sign == NULL) || (signLen == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->pubkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_EMPTY_KEY); + return CRYPT_ECDSA_ERR_EMPTY_KEY; + } + + int32_t ret; + BN_BigNum *paraN = ECC_GetParaN(ctx->para); + if (paraN == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + DSA_Sign *s = EcdsaSignNew(ctx); + BN_BigNum *d = GetBnByData(paraN, data, dataLen); + if ((d == NULL) || ((s == NULL))) { + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + + GOTO_ERR_IF(ASN1_SignDataDecode(s, sign, signLen), ret); + + GOTO_ERR_IF(VrifyCheckSign(ctx, s), ret); + + GOTO_ERR_IF(EcdsaVerifyCore(ctx, d, s), ret); +ERR: + EcdsaSignFree(s); + BN_Destroy(paraN); + BN_Destroy(d); + return ret; +} + +int32_t CRYPT_ECDSA_Ctrl(CRYPT_ECDSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + if (opt == CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE) { + BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION); + return CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION; + } + + return ECC_PkeyCtrl(ctx, opt, val, len); +} + +int32_t CRYPT_ECDSA_Cmp(const CRYPT_ECDSA_Ctx *a, const CRYPT_ECDSA_Ctx *b) +{ + return ECC_PkeyCmp(a, b); +} + +int32_t CRYPT_ECDSA_GetSecBits(const CRYPT_ECDSA_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return ECC_GetSecBits(ctx->para); +} +#endif /* HITLS_CRYPTO_ECDSA */ diff --git a/crypto/encode/include/crypt_encode.h b/crypto/encode/include/crypt_encode.h new file mode 100644 index 00000000..d8955060 --- /dev/null +++ b/crypto/encode/include/crypt_encode.h @@ -0,0 +1,83 @@ +/* + * 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_ENCODE_H +#define CRYPT_ENCODE_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ENCODE + +#include "bsl_type.h" +#include "bsl_asn1.h" +#include "crypt_eal_pkey.h" +#include "crypt_bn.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_HASH 0 +#define CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_MASKGEN 1 +#define CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_SALTLEN 2 +#define CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_TRAILED 3 + +typedef struct { + BN_BigNum *r; + BN_BigNum *s; +} DSA_Sign; +// encode signature data +int32_t ASN1_SignDataEncode(const DSA_Sign *s, uint8_t *sign, uint32_t *signLen); + +// decode signature data +int32_t ASN1_SignDataDecode(DSA_Sign *s, const uint8_t *sign, uint32_t signLen); + +// Obtain the required length of the signature data. +uint32_t ASN1_SignEnCodeLen(uint32_t rLen, uint32_t sLen); + +// Stream length for encoding a BigNum. +uint32_t ASN1_SignStringLenOfBn(const BN_BigNum *num); + +int32_t ASN1_Sm2EncryptDataEncode(const uint8_t *input, uint32_t inputLen, uint8_t *encode, uint32_t *encodeLen); + +int32_t ASN1_Sm2EncryptDataDecode(const uint8_t *eData, uint32_t eLen, uint8_t *decode, uint32_t *decodeLen); + +uint64_t ASN1_Sm2GetEnCodeLen(uint32_t dataLen); + +int32_t CRYPT_EAL_ParseRsaPssAlgParam(BSL_ASN1_Buffer *param, CRYPT_RSA_PssPara *para); + +int32_t CRYPT_EAL_ParseAsn1SubPubkey(uint8_t *buff, uint32_t buffLen, void **ealPubKey, bool isComplete); + +int32_t CRYPT_EAL_EncodePubKeyBuffInternal(CRYPT_EAL_PkeyCtx *ealPubKey, + BSL_ParseFormat format, int32_t type, bool isComplete, BSL_Buffer *encode); + +int32_t CRYPT_EAL_EncodeRsaPssAlgParam(CRYPT_RSA_PssPara *rsaPssParam, uint8_t **buf, uint32_t *bufLen); + +int32_t CRYPT_EAL_PriKeyParseFile(BSL_ParseFormat format, int32_t type, const char *path, uint8_t *pwd, uint32_t pwdlen, + CRYPT_EAL_PkeyCtx **ealPriKey); + +// parse PKCS7-EncryptData:only support PBES2 + PBKDF2. +int32_t CRYPT_EAL_ParseAsn1PKCS7EncryptedData(BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, + BSL_Buffer *encryptData); + +// encode PKCS7-EncryptData:only support PBES2 + PBKDF2. +int32_t CRYPT_EAL_EncodePKCS7EncryptDataBuff(BSL_Buffer *data, const void *encodeParam, BSL_Buffer *encode); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ENCODE + +#endif // CRYPT_ENCODE_H diff --git a/crypto/encode/src/crypt_eal_encode.c b/crypto/encode/src/crypt_eal_encode.c new file mode 100644 index 00000000..d43bb09e --- /dev/null +++ b/crypto/encode/src/crypt_eal_encode.c @@ -0,0 +1,2412 @@ +/* + * 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_ENCODE +#include +#include + +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_asn1.h" +#include "bsl_pem_internal.h" +#include "crypt_ecc.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "bsl_obj_internal.h" +#include "crypt_eal_encode.h" +#include "crypt_eal_kdf.h" +#include "crypt_eal_cipher.h" +#include "sal_file.h" +#include "bsl_bytes.h" +#include "crypt_eal_rand.h" +#include "crypt_encode.h" + +#define PATH_MAX_LEN 4096 +#define PWD_MAX_LEN 4096 + +// clang-format off +/** + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER } -- e + * + * https://datatracker.ietf.org/doc/html/rfc4055#autoid-3 + */ +static BSL_ASN1_TemplateItem rsaPubTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* ignore seq */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* n */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* e */ +}; + +typedef enum { + CRYPT_RSA_PUB_N_IDX = 0, + CRYPT_RSA_PUB_E_IDX = 1, +} CRYPT_RSA_PUB_TEMPL_IDX; + +/** + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + * + * https://datatracker.ietf.org/doc/html/rfc3447#autoid-39 +*/ + +static BSL_ASN1_TemplateItem rsaPrvTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* ignore seq header */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* version */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* n */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* e */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* p */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* q */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d mod (p-1) */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d mod (q-1) */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* q^-1 mod p */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 1}, /* OtherPrimeInfos OPTIONAL */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, /* OtherPrimeInfo */ + {BSL_ASN1_TAG_INTEGER, 0, 3}, /* ri */ + {BSL_ASN1_TAG_INTEGER, 0, 3}, /* di */ + {BSL_ASN1_TAG_INTEGER, 0, 3} /* ti */ +}; + +typedef enum { + CRYPT_RSA_PRV_VERSION_IDX = 0, + CRYPT_RSA_PRV_N_IDX = 1, + CRYPT_RSA_PRV_E_IDX = 2, + CRYPT_RSA_PRV_D_IDX = 3, + CRYPT_RSA_PRV_P_IDX = 4, + CRYPT_RSA_PRV_Q_IDX = 5, + CRYPT_RSA_PRV_DP_IDX = 6, + CRYPT_RSA_PRV_DQ_IDX = 7, + CRYPT_RSA_PRV_QINV_IDX = 8, + CRYPT_RSA_PRV_OTHER_PRIME_IDX = 9 +} CRYPT_RSA_PRV_TEMPL_IDX; + + +/** + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + * + * https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.1.2 +*/ +static BSL_ASN1_TemplateItem algoIdTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 0}, +}; + +typedef enum { + BSL_ASN1_TAG_ALGOID_IDX = 0, + BSL_ASN1_TAG_ALGOID_ANY_IDX = 1, +} ALGOID_TEMPL_IDX; + +/** + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + * + * https://datatracker.ietf.org/doc/html/rfc5480#autoid-3 +*/ +static BSL_ASN1_TemplateItem subKeyInfoTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, + {BSL_ASN1_TAG_BITSTRING, 0, 1}, +}; + +static BSL_ASN1_TemplateItem subKeyInfoInnerTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 0}, + {BSL_ASN1_TAG_BITSTRING, 0, 0}, +}; + +typedef enum { + CRYPT_SUBKEYINFO_ALGOID_IDX = 0, + CRYPT_SUBKEYINFO_BITSTRING_IDX = 1, +} CRYPT_SUBKEYINFO_TEMPL_IDX; + + +/** + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + * + * https://datatracker.ietf.org/doc/html/rfc5915#autoid-3 + */ + +#define BSL_ASN1_TAG_EC_PRIKEY_PARAM 0 +#define BSL_ASN1_TAG_EC_PRIKEY_PUBKEY 1 + +static BSL_ASN1_TemplateItem ecPriKeyTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, // ignore seq header + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* version */ + {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, /* private key */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_EC_PRIKEY_PARAM, + BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_EC_PRIKEY_PUBKEY, + BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_BITSTRING, 0, 2}, +}; + +typedef enum { + CRYPT_ECPRIKEY_VERSION_IDX = 0, + CRYPT_ECPRIKEY_PRIKEY_IDX = 1, + CRYPT_ECPRIKEY_PARAM_IDX = 2, + CRYPT_ECPRIKEY_PUBKEY_IDX = 3, +} CRYPT_ECPRIKEY_TEMPL_IDX; + +/** + * PrivateKeyInfo ::= SEQUENCE { + * version INTEGER, + * privateKeyAlgorithm AlgorithmIdentifier, + * privateKey OCTET STRING, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * + * https://datatracker.ietf.org/doc/html/rfc5208#autoid-5 +*/ +static BSL_ASN1_TemplateItem pk8PriKeyTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, // ignore seq header + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, + {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, +}; + +typedef enum { + CRYPT_PK8_PRIKEY_VERSION_IDX = 0, + CRYPT_PK8_PRIKEY_ALGID_IDX = 1, + CRYPT_PK8_PRIKEY_PRIKEY_IDX = 2, +} CRYPT_PK8_PRIKEY_TEMPL_IDX; + +/** + * EncryptedPrivateKeyInfo ::= SEQUENCE { + * encryptionAlgorithm EncryptionAlgorithmIdentifier, + * encryptedData EncryptedData } + * + * https://datatracker.ietf.org/doc/html/rfc5208#autoid-6 +*/ +static BSL_ASN1_TemplateItem pk8EncPriKeyTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, // EncryptionAlgorithmIdentifier + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 3}, // derivation param + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 3}, // enc scheme + {BSL_ASN1_TAG_OBJECT_ID, 0, 4}, // alg + {BSL_ASN1_TAG_OCTETSTRING, 0, 4}, // iv + {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, // EncryptedData +}; + +static BSL_ASN1_TemplateItem g_pbkdf2DerParamTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, // derive alg + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, // salt + {BSL_ASN1_TAG_INTEGER, 0, 1}, // iteration + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_OPTIONAL, 1}, // keyLen + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_DEFAULT | BSL_ASN1_FLAG_HEADERONLY, 1}, // prf +}; + +typedef enum { + CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX, + CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX, + CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX, + CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX, + CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX, + CRYPT_PKCS_ENCPRIKEY_MAX +} CRYPT_PKCS_ENCPRIKEY_TEMPL_IDX; + +typedef enum { + CRYPT_PKCS_ENC_DERALG_IDX, + CRYPT_PKCS_ENC_DERSALT_IDX, + CRYPT_PKCS_ENC_DERITER_IDX, + CRYPT_PKCS_ENC_DERKEYLEN_IDX, + CRYPT_PKCS_ENC_DERPRF_IDX, + CRYPT_PKCS_ENC_DERPARAM_MAX +} CRYPT_PKCS_ENC_DERIVEPARAM_IDX; + +// clang-format on + +static CRYPT_PKEY_ParaId GetParaId(uint8_t *octs, uint32_t octsLen) +{ + BslOidString oidStr = {octsLen, (char *)octs, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_UNKNOWN) { + return CRYPT_PKEY_PARAID_MAX; + } + return (CRYPT_PKEY_ParaId)cid; +} + +static int32_t DecSubKeyInfoCb(int32_t type, int32_t idx, void *data, void *expVal) +{ + (void)idx; + BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data; + + switch (type) { + case BSL_ASN1_TYPE_GET_ANY_TAG: { + BslOidString oidStr = {param->len, (char *)param->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_EC_PUBLICKEY) { + // note: any It can be encoded empty or it can be null + *(uint8_t *)expVal = BSL_ASN1_TAG_OBJECT_ID; + } else if (cid == BSL_CID_RSASSAPSS) { + *(uint8_t *)expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + } else { + *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null + } + return CRYPT_SUCCESS; + } + default: + break; + } + return CRYPT_DECODE_ASN1_BUFF_FAILED; +} + +static int32_t ParseAlgoIdAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *algoId, uint32_t algoIdNum) +{ + uint8_t *tmpBuff = buff; + uint32_t tmpBuffLen = buffLen; + + BSL_ASN1_Template templ = {algoIdTempl, sizeof(algoIdTempl) / sizeof(algoIdTempl[0])}; + return BSL_ASN1_DecodeTemplate(&templ, DecSubKeyInfoCb, &tmpBuff, &tmpBuffLen, algoId, algoIdNum); +} + +static int32_t EncodeAlgoIdAsn1Buff(BSL_ASN1_Buffer *algoId, uint32_t algoIdNum, uint8_t **buff, uint32_t *buffLen) +{ + BSL_ASN1_Template templ = {algoIdTempl, sizeof(algoIdTempl) / sizeof(algoIdTempl[0])}; + return BSL_ASN1_EncodeTemplate(&templ, algoId, algoIdNum, buff, buffLen); +} + +static int32_t ProcRsaPssParam(BSL_ASN1_Buffer *rsaPssParam, CRYPT_EAL_PkeyCtx *ealPriKey) +{ + CRYPT_RSA_PssPara para = {0}; + int32_t ret = CRYPT_EAL_ParseRsaPssAlgParam(rsaPssParam, ¶); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + CRYPT_RsaPadType padType = CRYPT_PKEY_EMSA_PSS; + ret = CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_SET_RSA_PADDING, &padType, sizeof(CRYPT_RsaPadType)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_SET_RSA_EMSA_PSS, ¶, sizeof(CRYPT_RSA_PssPara)); +} + +static int32_t ParseRsaPubkeyAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *param, + CRYPT_EAL_PkeyCtx **ealPubKey, BslCid cid) +{ + uint8_t *tmpBuff = buff; + uint32_t tmpBuffLen = buffLen; + // decode n and e + BSL_ASN1_Buffer pubAsn1[CRYPT_RSA_PUB_E_IDX + 1] = {0}; + BSL_ASN1_Template pubTempl = {rsaPubTempl, sizeof(rsaPubTempl) / sizeof(rsaPubTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&pubTempl, NULL, &tmpBuff, &tmpBuffLen, pubAsn1, CRYPT_RSA_PUB_E_IDX + 1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + CRYPT_EAL_PkeyCtx *pctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + if (pctx == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + CRYPT_EAL_PkeyPub pub; + pub.id = CRYPT_PKEY_RSA; + pub.key.rsaPub.n = pubAsn1[CRYPT_RSA_PUB_N_IDX].buff; + pub.key.rsaPub.nLen = pubAsn1[CRYPT_RSA_PUB_N_IDX].len; + pub.key.rsaPub.e = pubAsn1[CRYPT_RSA_PUB_E_IDX].buff; + pub.key.rsaPub.eLen = pubAsn1[CRYPT_RSA_PUB_E_IDX].len; + ret = CRYPT_EAL_PkeySetPub(pctx, &pub); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + + if (cid != BSL_CID_RSASSAPSS) { + *ealPubKey = pctx; + return CRYPT_SUCCESS; + } + + ret = ProcRsaPssParam(param, pctx); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + + *ealPubKey = pctx; + return ret; +} + +static bool IsEcdsaEcParaId(int32_t paraId) +{ + if (paraId == CRYPT_ECC_NISTP224 || paraId == CRYPT_ECC_NISTP256 || + paraId == CRYPT_ECC_NISTP384 || paraId == CRYPT_ECC_NISTP521 || + paraId == CRYPT_ECC_BRAINPOOLP256R1 || paraId == CRYPT_ECC_BRAINPOOLP384R1 || + paraId == CRYPT_ECC_BRAINPOOLP512R1) { + return true; + } + return false; +} + +static int32_t EccEalKeyNew(BSL_ASN1_Buffer *ecParamOid, int32_t *alg, CRYPT_EAL_PkeyCtx **ealKey) +{ + int32_t algId; + CRYPT_PKEY_ParaId paraId = GetParaId(ecParamOid->buff, ecParamOid->len); + if (paraId == CRYPT_ECC_SM2) { + algId = CRYPT_PKEY_SM2; + } else if (IsEcdsaEcParaId(paraId)) { + algId = CRYPT_PKEY_ECDSA; + } else { // scenario ecdh is not considered, and it will be improved in the future + return CRYPT_DECODE_UNKNOWN_OID; + } + + CRYPT_EAL_PkeyCtx *key = CRYPT_EAL_PkeyNewCtx(algId); + if (key == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + if (paraId != CRYPT_ECC_SM2) { + int32_t ret = CRYPT_EAL_PkeySetParaById(key, paraId); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(key); + return ret; + } + } + *ealKey = key; + *alg = algId; + return CRYPT_SUCCESS; +} + +static int32_t ParseEccPubkeyAsn1Buff(BSL_ASN1_BitString *bitPubkey, BSL_ASN1_Buffer *ecParamOid, + CRYPT_EAL_PkeyCtx **ealPubKey) +{ + int32_t algId; + CRYPT_EAL_PkeyCtx *pctx = NULL; + int32_t ret = EccEalKeyNew(ecParamOid, &algId, &pctx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_EAL_PkeyPub pub; + pub.id = algId; + pub.key.eccPub.data = bitPubkey->buff; + pub.key.eccPub.len = bitPubkey->len; + ret = CRYPT_EAL_PkeySetPub(pctx, &pub); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + *ealPubKey = pctx; + return ret; +} + +static int32_t ParseSubPubkeyAsn1(BSL_ASN1_Buffer *encode, CRYPT_EAL_PkeyCtx **ealPubKey) +{ + uint8_t *algoBuff = encode->buff; // AlgorithmIdentifier Tag and Len, 2 bytes. + uint32_t algoBuffLen = encode->len; + BSL_ASN1_Buffer algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX + 1] = {0}; + int32_t ret = ParseAlgoIdAsn1Buff(algoBuff, algoBuffLen, algoId, BSL_ASN1_TAG_ALGOID_ANY_IDX + 1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BSL_ASN1_Buffer *oid = algoId; // OID + BSL_ASN1_Buffer *algParam = algoId + 1; // the parameters + BSL_ASN1_Buffer *pubkey = &encode[CRYPT_SUBKEYINFO_BITSTRING_IDX]; // the last BSL_ASN1_Buffer, the pubkey + BSL_ASN1_BitString bitPubkey = {0}; + ret = BSL_ASN1_DecodePrimitiveItem(pubkey, &bitPubkey); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BslOidString oidStr = {oid->len, (char *)oid->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_EC_PUBLICKEY) { + return ParseEccPubkeyAsn1Buff(&bitPubkey, algParam, ealPubKey); + } else if (cid == BSL_CID_RSA || cid == BSL_CID_RSASSAPSS) { + return ParseRsaPubkeyAsn1Buff(bitPubkey.buff, bitPubkey.len, algParam, ealPubKey, cid); + } else { // ed25519 448 will be added in the future + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNKNOWN_OID); + return CRYPT_DECODE_UNKNOWN_OID; + } +} + +int32_t CRYPT_EAL_ParseAsn1SubPubkey(uint8_t *buff, uint32_t buffLen, void **ealPubKey, bool isComplete) +{ + uint8_t *tmpBuff = buff; + uint32_t tmpBuffLen = buffLen; + // decode sub pubkey info + BSL_ASN1_Buffer pubAsn1[CRYPT_SUBKEYINFO_BITSTRING_IDX + 1] = {0}; + BSL_ASN1_Template pubTempl; + if (isComplete) { + pubTempl.templItems = subKeyInfoTempl; + pubTempl.templNum = sizeof(subKeyInfoTempl) / sizeof(subKeyInfoTempl[0]); + } else { + pubTempl.templItems = subKeyInfoInnerTempl; + pubTempl.templNum = sizeof(subKeyInfoInnerTempl) / sizeof(subKeyInfoInnerTempl[0]); + } + int32_t ret = BSL_ASN1_DecodeTemplate(&pubTempl, DecSubKeyInfoCb, &tmpBuff, &tmpBuffLen, pubAsn1, + CRYPT_SUBKEYINFO_BITSTRING_IDX + 1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + return ParseSubPubkeyAsn1(pubAsn1, (CRYPT_EAL_PkeyCtx **)ealPubKey); +} + +static int32_t ParseEccPrikeyAsn1(BSL_ASN1_Buffer *encode, BSL_ASN1_Buffer *pk8AlgoParam, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + BSL_ASN1_Buffer *prikey = &encode[CRYPT_ECPRIKEY_PRIKEY_IDX]; // the ECC OID + BSL_ASN1_Buffer *ecParamOid = &encode[CRYPT_ECPRIKEY_PARAM_IDX]; // the parameters OID + BSL_ASN1_Buffer *pubkey = &encode[CRYPT_ECPRIKEY_PUBKEY_IDX]; // the ECC OID + BSL_ASN1_Buffer *param = pk8AlgoParam; + if (ecParamOid->len != 0) { + // has a valid Algorithm param + param = ecParamOid; + } else { + if (param == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (param->len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM); + return CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM; + } + } + int32_t algId; + CRYPT_EAL_PkeyCtx *pctx = NULL; + int32_t ret = EccEalKeyNew(param, &algId, &pctx); + if (ret != CRYPT_SUCCESS) { + return ret; + } + CRYPT_EAL_PkeyPrv prv; + prv.id = algId; + prv.key.eccPrv.data = prikey->buff; + prv.key.eccPrv.len = prikey->len; + ret = CRYPT_EAL_PkeySetPrv(pctx, &prv); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + + CRYPT_EAL_PkeyPub pub; + pub.id = algId; + pub.key.eccPub.data = pubkey->buff + 1; // the tag of public key is BSL_ASN1_TAG_BITSTRING, 1 denote unusedBits + pub.key.eccPub.len = pubkey->len - 1; + ret = CRYPT_EAL_PkeySetPub(pctx, &pub); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + *ealPriKey = pctx; + return ret; +} + +static int32_t ParseEccPrikeyAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *pk8AlgoParam, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + uint8_t *tmpBuff = buff; + uint32_t tmpBuffLen = buffLen; + + BSL_ASN1_Buffer asn1[CRYPT_ECPRIKEY_PUBKEY_IDX + 1] = {0}; + BSL_ASN1_Template templ = {ecPriKeyTempl, sizeof(ecPriKeyTempl) / sizeof(ecPriKeyTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &tmpBuff, &tmpBuffLen, asn1, CRYPT_ECPRIKEY_PUBKEY_IDX + 1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + return ParseEccPrikeyAsn1(asn1, pk8AlgoParam, ealPriKey); +} + +/** + * ref: rfc4055 + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] INTEGER DEFAULT 1 + * } + * HashAlgorithm ::= AlgorithmIdentifier + * MaskGenAlgorithm ::= AlgorithmIdentifier + */ +static BSL_ASN1_TemplateItem g_rsaPssTempl[] = { + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_HASH, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_MASKGEN, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 3}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 3}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_SALTLEN, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_TRAILED, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1} +}; + +typedef enum { + CRYPT_RSAPSS_HASH_IDX, + CRYPT_RSAPSS_HASHANY_IDX, + CRYPT_RSAPSS_MGF1_IDX, + CRYPT_RSAPSS_MGF1PARAM_IDX, + CRYPT_RSAPSS_MGF1PARAMANY_IDX, + CRYPT_RSAPSS_SALTLEN_IDX, + CRYPT_RSAPSS_TRAILED_IDX, + CRYPT_RSAPSS_MAX +} CRYPT_RSAPSS_IDX; + +static int32_t RsaPssTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + (void) idx; + (void) data; + if (type == BSL_ASN1_TYPE_GET_ANY_TAG) { + *(uint8_t *) expVal = BSL_ASN1_TAG_NULL; // is null + return CRYPT_SUCCESS; + } + return CRYPT_DECODE_ERR_RSSPSS_GET_ANY_TAG; +} + +int32_t CRYPT_EAL_ParseRsaPssAlgParam(BSL_ASN1_Buffer *param, CRYPT_RSA_PssPara *para) +{ + para->mdId = (CRYPT_MD_AlgId)BSL_CID_SHA1; // hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, + para->mgfId = (CRYPT_MD_AlgId)BSL_CID_SHA1; // maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, + para->saltLen = 20; // saltLength [2] INTEGER DEFAULT 20 + if (param == NULL || param->buff == NULL) { + return CRYPT_SUCCESS; + } + + uint8_t *temp = param->buff; + uint32_t tempLen = param->len; + BSL_ASN1_Buffer asns[CRYPT_RSAPSS_MAX] = {0}; + BSL_ASN1_Template templ = {g_rsaPssTempl, sizeof(g_rsaPssTempl) / sizeof(g_rsaPssTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, &RsaPssTagGetOrCheck, &temp, &tempLen, asns, CRYPT_RSAPSS_MAX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_RSSPSS); + return CRYPT_DECODE_ERR_RSSPSS; + } + + if (asns[CRYPT_RSAPSS_HASH_IDX].tag != 0) { + BslOidString hashOid = {asns[CRYPT_RSAPSS_HASH_IDX].len, (char *)asns[CRYPT_RSAPSS_HASH_IDX].buff, 0}; + para->mdId = (CRYPT_MD_AlgId)BSL_OBJ_GetCIDFromOid(&hashOid); + if (para->mdId == (CRYPT_MD_AlgId)BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_RSSPSS_MD); + return CRYPT_DECODE_ERR_RSSPSS_MD; + } + } + if (asns[CRYPT_RSAPSS_MGF1PARAM_IDX].tag != 0) { + BslOidString mgf1 = {asns[CRYPT_RSAPSS_MGF1PARAM_IDX].len, (char *)asns[CRYPT_RSAPSS_MGF1PARAM_IDX].buff, 0}; + para->mgfId = (CRYPT_MD_AlgId)BSL_OBJ_GetCIDFromOid(&mgf1); + if (para->mgfId == (CRYPT_MD_AlgId)BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_RSSPSS_MGF1MD); + return CRYPT_DECODE_ERR_RSSPSS_MGF1MD; + } + } + + if (asns[CRYPT_RSAPSS_SALTLEN_IDX].tag != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(&asns[CRYPT_RSAPSS_SALTLEN_IDX], ¶->saltLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + if (asns[CRYPT_RSAPSS_TRAILED_IDX].tag != 0) { + // trailerField + ret = BSL_ASN1_DecodePrimitiveItem(&asns[CRYPT_RSAPSS_TRAILED_IDX], &tempLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (tempLen != 1) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_RSSPSS_TRAILER); + return CRYPT_DECODE_ERR_RSSPSS_TRAILER; + } + } + return ret; +} + +static int32_t ProcRsaPubKey(const BSL_ASN1_Buffer *asn1, CRYPT_EAL_PkeyCtx *ealPkey) +{ + CRYPT_EAL_PkeyPub rsaPub; + rsaPub.id = CRYPT_PKEY_RSA; + rsaPub.key.rsaPub.e = asn1[CRYPT_RSA_PRV_E_IDX].buff; + rsaPub.key.rsaPub.eLen = asn1[CRYPT_RSA_PRV_E_IDX].len; + rsaPub.key.rsaPub.n = asn1[CRYPT_RSA_PRV_N_IDX].buff; + rsaPub.key.rsaPub.nLen = asn1[CRYPT_RSA_PRV_N_IDX].len; + return CRYPT_EAL_PkeySetPub(ealPkey, &rsaPub); +} + +static int32_t ProcRsaPrivKey(const BSL_ASN1_Buffer *asn1, CRYPT_EAL_PkeyCtx *ealPkey) +{ + CRYPT_EAL_PkeyPrv rsaPrv; + rsaPrv.id = CRYPT_PKEY_RSA; + rsaPrv.key.rsaPrv.d = asn1[CRYPT_RSA_PRV_D_IDX].buff; + rsaPrv.key.rsaPrv.dLen = asn1[CRYPT_RSA_PRV_D_IDX].len; + rsaPrv.key.rsaPrv.n = asn1[CRYPT_RSA_PRV_N_IDX].buff; + rsaPrv.key.rsaPrv.nLen = asn1[CRYPT_RSA_PRV_N_IDX].len; + rsaPrv.key.rsaPrv.e = asn1[CRYPT_RSA_PRV_E_IDX].buff; + rsaPrv.key.rsaPrv.eLen = asn1[CRYPT_RSA_PRV_E_IDX].len; + rsaPrv.key.rsaPrv.p = asn1[CRYPT_RSA_PRV_P_IDX].buff; + rsaPrv.key.rsaPrv.pLen = asn1[CRYPT_RSA_PRV_P_IDX].len; + rsaPrv.key.rsaPrv.q = asn1[CRYPT_RSA_PRV_Q_IDX].buff; + rsaPrv.key.rsaPrv.qLen = asn1[CRYPT_RSA_PRV_Q_IDX].len; + rsaPrv.key.rsaPrv.dP = asn1[CRYPT_RSA_PRV_DP_IDX].buff; + rsaPrv.key.rsaPrv.dPLen = asn1[CRYPT_RSA_PRV_DP_IDX].len; + rsaPrv.key.rsaPrv.dQ = asn1[CRYPT_RSA_PRV_DQ_IDX].buff; + rsaPrv.key.rsaPrv.dQLen = asn1[CRYPT_RSA_PRV_DQ_IDX].len; + rsaPrv.key.rsaPrv.qInv = asn1[CRYPT_RSA_PRV_QINV_IDX].buff; + rsaPrv.key.rsaPrv.qInvLen = asn1[CRYPT_RSA_PRV_QINV_IDX].len; + + return CRYPT_EAL_PkeySetPrv(ealPkey, &rsaPrv); +} + +static int32_t ProcRsaKeyPair(uint8_t *buff, uint32_t buffLen, CRYPT_EAL_PkeyCtx *ealPkey) +{ + uint8_t *tmpBuff = buff; + uint32_t tmpBuffLen = buffLen; + // decode n and e + BSL_ASN1_Buffer asn1[CRYPT_RSA_PRV_OTHER_PRIME_IDX + 1] = {0}; + BSL_ASN1_Template templ = {rsaPrvTempl, sizeof(rsaPrvTempl) / sizeof(rsaPrvTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &tmpBuff, &tmpBuffLen, asn1, CRYPT_RSA_PRV_OTHER_PRIME_IDX + 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = ProcRsaPrivKey(asn1, ealPkey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ProcRsaPubKey(asn1, ealPkey); +} + +static int32_t ParseRsaPrikeyAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *rsaPssParam, BslCid cid, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + CRYPT_EAL_PkeyCtx *pctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + if (pctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + int32_t ret = ProcRsaKeyPair(buff, buffLen, pctx); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + if (cid != BSL_CID_RSASSAPSS) { + *ealPriKey = pctx; + return CRYPT_SUCCESS; + } + + ret = ProcRsaPssParam(rsaPssParam, pctx); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pctx); + return ret; + } + *ealPriKey = pctx; + return ret; +} + +static int32_t ParsePk8PrikeyAsn1(BSL_ASN1_Buffer *encode, CRYPT_EAL_PkeyCtx **ealPriKey) +{ + BSL_ASN1_Buffer *algo = &encode[CRYPT_PK8_PRIKEY_ALGID_IDX]; // AlgorithmIdentifier + BSL_ASN1_Buffer *octPriKey = &encode[CRYPT_PK8_PRIKEY_PRIKEY_IDX]; // PrivateKey octet string + BSL_ASN1_Buffer algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX + 1] = {0}; + int32_t ret = ParseAlgoIdAsn1Buff(algo->buff, algo->len, algoId, BSL_ASN1_TAG_ALGOID_ANY_IDX + 1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BslOidString oidStr = {algoId[0].len, (char *)algoId[0].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_RSA || cid == BSL_CID_RSASSAPSS) { + return ParseRsaPrikeyAsn1Buff(octPriKey->buff, octPriKey->len, algoId + 1, cid, ealPriKey); + } else if (cid == BSL_CID_EC_PUBLICKEY) { + return ParseEccPrikeyAsn1Buff(octPriKey->buff, octPriKey->len, algoId + 1, ealPriKey); + } + return CRYPT_DECODE_UNSUPPORTED_PKCS8_TYPE; +} + +static int32_t ParsePk8PriKeyBuff(BSL_Buffer *buff, CRYPT_EAL_PkeyCtx **ealPriKey) +{ + uint8_t *tmpBuff = buff->data; + uint32_t tmpBuffLen = buff->dataLen; + + BSL_ASN1_Buffer asn1[CRYPT_PK8_PRIKEY_PRIKEY_IDX + 1] = {0}; + BSL_ASN1_Template templ = {pk8PriKeyTempl, sizeof(pk8PriKeyTempl) / sizeof(pk8PriKeyTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &tmpBuff, &tmpBuffLen, asn1, CRYPT_PK8_PRIKEY_PRIKEY_IDX + 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ParsePk8PrikeyAsn1(asn1, ealPriKey); +} + +static int32_t ParseDeriveKeyPrfAlgId(BSL_ASN1_Buffer *asn, int32_t *prfId) +{ + int32_t ret = CRYPT_SUCCESS; + if (asn->len != 0) { + BSL_ASN1_Buffer algoId[2] = {0}; + ret = ParseAlgoIdAsn1Buff(asn->buff, asn->len, algoId, 2); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BslOidString oidStr = {algoId[BSL_ASN1_TAG_ALGOID_IDX].len, + (char *)algoId[BSL_ASN1_TAG_ALGOID_IDX].buff, 0}; + *prfId = BSL_OBJ_GetCIDFromOid(&oidStr); + if (*prfId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM); + return CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM; + } + } else { + *prfId = BSL_CID_HMAC_SHA1; + } + return ret; +} + +static int32_t ParseDeriveKeyParam(BSL_Buffer *derivekeyData, int *iter, int *keyLen, BSL_Buffer *salt, int *prfId) +{ + uint8_t *tmpBuff = derivekeyData->data; + uint32_t tmpBuffLen = derivekeyData->dataLen; + BSL_ASN1_Buffer derParam[CRYPT_PKCS_ENC_DERPARAM_MAX] = {0}; + BSL_ASN1_Template templ = {g_pbkdf2DerParamTempl, sizeof(g_pbkdf2DerParamTempl) / sizeof(g_pbkdf2DerParamTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, + &tmpBuff, &tmpBuffLen, derParam, CRYPT_PKCS_ENC_DERPARAM_MAX); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BslOidString oidStr = {derParam[CRYPT_PKCS_ENC_DERALG_IDX].len, + (char *)derParam[CRYPT_PKCS_ENC_DERALG_IDX].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid != BSL_CID_PBKDF2) { // only pbkdf2 is supported + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM); + return CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM; + } + ret = BSL_ASN1_DecodePrimitiveItem(&derParam[CRYPT_PKCS_ENC_DERITER_IDX], iter); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_ITER); + return CRYPT_DECODE_PKCS8_INVALID_ITER; + } + if (derParam[CRYPT_PKCS_ENC_DERKEYLEN_IDX].len != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(&derParam[CRYPT_PKCS_ENC_DERKEYLEN_IDX], keyLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_KEYLEN); + return CRYPT_DECODE_PKCS8_INVALID_KEYLEN; + } + } + salt->data = derParam[CRYPT_PKCS_ENC_DERSALT_IDX].buff; + salt->dataLen = derParam[CRYPT_PKCS_ENC_DERSALT_IDX].len; + return ParseDeriveKeyPrfAlgId(&derParam[CRYPT_PKCS_ENC_DERPRF_IDX], prfId); +} + +static int32_t DecryptEncData(BSL_Buffer *ivData, BSL_Buffer *enData, int32_t alg, bool isEnc, BSL_Buffer *key, + uint8_t *output, uint32_t *dataLen) +{ + uint32_t buffLen = *dataLen; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(alg); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + (void)CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_DES_NOKEYCHECK, NULL, 0); + int32_t ret = CRYPT_EAL_CipherInit(ctx, key->data, key->dataLen, ivData->data, ivData->dataLen, isEnc); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + uint32_t blockSize; + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, &blockSize, sizeof(blockSize)); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + if (blockSize != 1) { + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + } + ret = CRYPT_EAL_CipherUpdate(ctx, enData->data, enData->dataLen, output, dataLen); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + buffLen -= *dataLen; + ret = CRYPT_EAL_CipherFinal(ctx, output + *dataLen, &buffLen); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + *dataLen += buffLen; +ERR: + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; +} + +typedef struct { + BSL_Buffer *derivekeyData; + BSL_Buffer *ivData; + BSL_Buffer *enData; +} EncryptPara; + +static int32_t ParseEncDataAsn1(BslCid symAlg, EncryptPara *encPara, const uint8_t *pwd, uint32_t pwdlen, + BSL_Buffer *decode) +{ + int32_t iter, prfId; + int32_t keylen = 0; + uint8_t key[512]; // The maximum length of the symmetry algorithm + BSL_Buffer salt = {0}; + int32_t ret = ParseDeriveKeyParam(encPara->derivekeyData, &iter, &keylen, &salt, &prfId); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + uint32_t symKeyLen; + ret = CRYPT_EAL_CipherGetInfo((CRYPT_CIPHER_AlgId)symAlg, CRYPT_INFO_KEY_LEN, &symKeyLen); + if (keylen != 0 && symKeyLen != (uint32_t)keylen) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS8_INVALID_KEYLEN); + return CRYPT_DECODE_PKCS8_INVALID_KEYLEN; + } + + ret = CRYPT_EAL_Pbkdf2(prfId, pwd, pwdlen, salt.data, salt.dataLen, iter, key, symKeyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (encPara->enData->dataLen != 0) { + uint8_t *output = BSL_SAL_Malloc(encPara->enData->dataLen); + if (output == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + uint32_t dataLen = encPara->enData->dataLen; + BSL_Buffer keyBuff = {key, symKeyLen}; + ret = DecryptEncData(encPara->ivData, encPara->enData, symAlg, false, &keyBuff, output, &dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_Free(output); + return ret; + } + decode->data = output; + decode->dataLen = dataLen; + } + return ret; +} + +static int32_t ParsePk8EncPriKeyBuff(BSL_Buffer *buff, const uint8_t *pwd, uint32_t pwdlen, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + if (pwdlen > PWD_MAX_LEN || (pwd == NULL && pwdlen != 0)) { + return CRYPT_INVALID_ARG; + } + uint8_t *tmpBuff = buff->data; + uint32_t tmpBuffLen = buff->dataLen; + + BSL_ASN1_Buffer asn1[CRYPT_PKCS_ENCPRIKEY_MAX] = {0}; + BSL_ASN1_Template templ = {pk8EncPriKeyTempl, sizeof(pk8EncPriKeyTempl) / sizeof(pk8EncPriKeyTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &tmpBuff, &tmpBuffLen, asn1, CRYPT_PKCS_ENCPRIKEY_MAX); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + BslOidString encOidStr = {asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].len, + (char *)asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&encOidStr); + if (cid != BSL_CID_PBES2) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNKNOWN_OID); + return CRYPT_DECODE_UNKNOWN_OID; + } + // parse sym alg id + BslOidString symOidStr = {asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].len, + (char *)asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].buff, 0}; + BslCid symId = BSL_OBJ_GetCIDFromOid(&symOidStr); + if (symId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNKNOWN_OID); + return CRYPT_DECODE_UNKNOWN_OID; + } + + BSL_Buffer decode = {0}; + BSL_Buffer derivekeyData = {asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].buff, + asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].len}; + BSL_Buffer ivData = {asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff, asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].len}; + BSL_Buffer enData = {asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff, asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].len}; + EncryptPara encPara = { + .derivekeyData = &derivekeyData, + .ivData = &ivData, + .enData = &enData, + }; + ret = ParseEncDataAsn1(symId, &encPara, pwd, pwdlen, &decode); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = ParsePk8PriKeyBuff(&decode, ealPriKey); + BSL_SAL_Free(decode.data); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_EAL_ParseAsn1PubKey(int32_t type, BSL_Buffer *encode, CRYPT_EAL_PkeyCtx **ealPubKey) +{ + switch (type) { + case CRYPT_PUBKEY_SUBKEY: + return CRYPT_EAL_ParseAsn1SubPubkey(encode->data, encode->dataLen, (void **)ealPubKey, true); + default: + return ParseRsaPubkeyAsn1Buff(encode->data, encode->dataLen, NULL, ealPubKey, BSL_CID_UNKNOWN); + } +} + +static int32_t EAL_GetPemPubKeySymbol(int32_t type, BSL_PEM_Symbol *symbol) +{ + switch (type) { + case CRYPT_PUBKEY_SUBKEY: + symbol->head = BSL_PEM_PUB_KEY_BEGIN_STR; + symbol->tail = BSL_PEM_PUB_KEY_END_STR; + return CRYPT_SUCCESS; + case CRYPT_PUBKEY_RSA: + symbol->head = BSL_PEM_RSA_PUB_KEY_BEGIN_STR; + symbol->tail = BSL_PEM_RSA_PUB_KEY_END_STR; + return CRYPT_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_NO_SUPPORT_TYPE); + return CRYPT_DECODE_NO_SUPPORT_TYPE; + } +} + +int32_t CRYPT_EAL_ParsePemPubKey(int32_t type, BSL_Buffer *encode, CRYPT_EAL_PkeyCtx **ealPubKey) +{ + BSL_PEM_Symbol symbol = {0}; + int32_t ret = EAL_GetPemPubKeySymbol(type, &symbol); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BSL_Buffer asn1 = {0}; + ret = BSL_PEM_ParsePem2Asn1((char **)&(encode->data), &(encode->dataLen), &symbol, &(asn1.data), &(asn1.dataLen)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_ParseAsn1PubKey(type, &asn1, ealPubKey); + BSL_SAL_Free(asn1.data); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_ParseUnknownPubKey(int32_t type, BSL_Buffer *encode, CRYPT_EAL_PkeyCtx **ealPubKey) +{ + bool isPem = BSL_PEM_IsPemFormat((char *)(encode->data), encode->dataLen); + if (isPem) { + return CRYPT_EAL_ParsePemPubKey(type, encode, ealPubKey); + } else { + return CRYPT_EAL_ParseAsn1PubKey(type, encode, ealPubKey); + } +} + +int32_t CRYPT_EAL_PubKeyParseBuff(BSL_ParseFormat format, int32_t type, BSL_Buffer *encode, + CRYPT_EAL_PkeyCtx **ealPubKey) +{ + if (encode == NULL || encode->data == NULL || encode->dataLen == 0 || ealPubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + switch (format) { + case BSL_FORMAT_ASN1: + return CRYPT_EAL_ParseAsn1PubKey(type, encode, ealPubKey); + case BSL_FORMAT_PEM: + return CRYPT_EAL_ParsePemPubKey(type, encode, ealPubKey); + case BSL_FORMAT_UNKNOWN: + return CRYPT_EAL_ParseUnknownPubKey(type, encode, ealPubKey); + default: + return CRYPT_DECODE_NO_SUPPORT_FORMAT; + } +} + +int32_t CRYPT_EAL_PubKeyParseFile(BSL_ParseFormat format, int32_t type, const char *path, CRYPT_EAL_PkeyCtx **ealPubKey) +{ + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_Buffer encode = {data, dataLen}; + ret = CRYPT_EAL_PubKeyParseBuff(format, type, &encode, ealPubKey); + BSL_SAL_Free(data); + return ret; +} + +int32_t CRYPT_EAL_ParseAsn1PriKey(int32_t type, BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + switch (type) { + case CRYPT_PRIKEY_ECC: + return ParseEccPrikeyAsn1Buff(encode->data, encode->dataLen, NULL, ealPriKey); + case CRYPT_PRIKEY_RSA: + return ParseRsaPrikeyAsn1Buff(encode->data, encode->dataLen, NULL, BSL_CID_UNKNOWN, ealPriKey); + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + return ParsePk8PriKeyBuff(encode, ealPriKey); + default: + return ParsePk8EncPriKeyBuff(encode, pwd, pwdlen, ealPriKey); + } +} + +static int32_t EAL_GetPemPriKeySymbol(int32_t type, BSL_PEM_Symbol *symbol) +{ + switch (type) { + case CRYPT_PRIKEY_ECC: + symbol->head = BSL_PEM_EC_PIR_KEY_BEGIN_STR; + symbol->tail = BSL_PEM_EC_PIR_KEY_END_STR; + return CRYPT_SUCCESS; + case CRYPT_PRIKEY_RSA: + symbol->head = BSL_PEM_RSA_PIR_KEY_BEGIN_STR; + symbol->tail = BSL_PEM_RSA_PIR_KEY_END_STR; + return CRYPT_SUCCESS; + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + symbol->head = BSL_PEM_PIR_KEY_BEGIN_STR; + symbol->tail = BSL_PEM_PIR_KEY_END_STR; + return CRYPT_SUCCESS; + case CRYPT_PRIKEY_PKCS8_ENCRYPT: + symbol->head = BSL_PEM_P8_PRI_KEY_BEGIN_STR; + symbol->tail = BSL_PEM_P8_PRI_KEY_END_STR; + return CRYPT_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_NO_SUPPORT_TYPE); + return CRYPT_DECODE_NO_SUPPORT_TYPE; + } +} + +int32_t CRYPT_EAL_ParsePemPriKey(int32_t type, BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + BSL_PEM_Symbol symbol = {0}; + int32_t ret = EAL_GetPemPriKeySymbol(type, &symbol); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BSL_Buffer asn1 = {0}; + ret = BSL_PEM_ParsePem2Asn1((char **)&(encode->data), &(encode->dataLen), &symbol, &(asn1.data), + &(asn1.dataLen)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_ParseAsn1PriKey(type, &asn1, pwd, pwdlen, ealPriKey); + BSL_SAL_Free(asn1.data); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_ParseUnkownPriKey(int32_t type, BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + bool isPem = BSL_PEM_IsPemFormat((char *)(encode->data), encode->dataLen); + if (isPem) { + return CRYPT_EAL_ParsePemPriKey(type, encode, pwd, pwdlen, ealPriKey); + } else { + return CRYPT_EAL_ParseAsn1PriKey(type, encode, pwd, pwdlen, ealPriKey); + } +} + +int32_t CRYPT_EAL_PriKeyParseBuff(BSL_ParseFormat format, int32_t type, BSL_Buffer *encode, + const uint8_t *pwd, uint32_t pwdlen, CRYPT_EAL_PkeyCtx **ealPriKey) +{ + if (encode == NULL || encode->data == NULL || encode->dataLen == 0 || ealPriKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + switch (format) { + case BSL_FORMAT_ASN1: + return CRYPT_EAL_ParseAsn1PriKey(type, encode, pwd, pwdlen, ealPriKey); + case BSL_FORMAT_PEM: + return CRYPT_EAL_ParsePemPriKey(type, encode, pwd, pwdlen, ealPriKey); + case BSL_FORMAT_UNKNOWN: + return CRYPT_EAL_ParseUnkownPriKey(type, encode, pwd, pwdlen, ealPriKey); + default: + return CRYPT_DECODE_NO_SUPPORT_FORMAT; + } +} + +int32_t CRYPT_EAL_PriKeyParseFile(BSL_ParseFormat format, int32_t type, const char *path, uint8_t *pwd, uint32_t pwdlen, + CRYPT_EAL_PkeyCtx **ealPriKey) +{ + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_Buffer encode = {data, dataLen}; + ret = CRYPT_EAL_PriKeyParseBuff(format, type, &encode, pwd, pwdlen, ealPriKey); + BSL_SAL_Free(data); + return ret; +} + +static int32_t EncodeEccKeyPair(CRYPT_EAL_PkeyCtx *ealPriKey, CRYPT_PKEY_AlgId cid, + BSL_ASN1_Buffer *asn1, BSL_Buffer *encode) +{ + int32_t ret; + uint32_t keyLen = CRYPT_EAL_PkeyGetKeyLen(ealPriKey); + if (keyLen == 0) { + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + uint8_t *pri = (uint8_t *)BSL_SAL_Malloc(keyLen); + if (pri == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + CRYPT_EAL_PkeyPrv prv = {0}; + prv.id = cid; + prv.key.eccPrv.data = pri; + prv.key.eccPrv.len = keyLen; + uint8_t *pub = NULL; + do { + ret = CRYPT_EAL_PkeyGetPrv(ealPriKey, &prv); + if (ret != CRYPT_SUCCESS) { + break; + } + asn1[CRYPT_ECPRIKEY_PRIKEY_IDX].buff = prv.key.eccPrv.data; + asn1[CRYPT_ECPRIKEY_PRIKEY_IDX].len = prv.key.eccPrv.len; + asn1[CRYPT_ECPRIKEY_PRIKEY_IDX].tag = BSL_ASN1_TAG_OCTETSTRING; + pub = (uint8_t *)BSL_SAL_Malloc(keyLen); + if (pub == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + break; + } + CRYPT_EAL_PkeyPub pubKey = {0}; + pubKey.id = cid; + pubKey.key.eccPub.data = pub; + pubKey.key.eccPub.len = keyLen; + ret = CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_GEN_ECC_PUBLICKEY, NULL, 0); + if (ret != CRYPT_SUCCESS) { + break; + } + ret = CRYPT_EAL_PkeyGetPub(ealPriKey, &pubKey); + if (ret != CRYPT_SUCCESS) { + break; + } + BSL_ASN1_BitString bitStr = {pubKey.key.eccPub.data, pubKey.key.eccPub.len, 0}; + asn1[CRYPT_ECPRIKEY_PUBKEY_IDX].buff = (uint8_t *)&bitStr; + asn1[CRYPT_ECPRIKEY_PUBKEY_IDX].len = sizeof(BSL_ASN1_BitString); + asn1[CRYPT_ECPRIKEY_PUBKEY_IDX].tag = BSL_ASN1_TAG_BITSTRING; + BSL_ASN1_Template templ = {ecPriKeyTempl, sizeof(ecPriKeyTempl) / sizeof(ecPriKeyTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asn1, CRYPT_ECPRIKEY_PUBKEY_IDX + 1, &encode->data, &encode->dataLen); + } while (0); + BSL_SAL_ClearFree(pri, keyLen); + BSL_SAL_FREE(pub); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeEccPrikeyAsn1Buff(CRYPT_EAL_PkeyCtx *ealPriKey, BSL_ASN1_Buffer *pk8AlgoParam, BSL_Buffer *encode) +{ + BSL_ASN1_Buffer asn1[CRYPT_ECPRIKEY_PUBKEY_IDX + 1] = {0}; + uint8_t version = 1; + asn1[CRYPT_ECPRIKEY_VERSION_IDX].buff = &version; + asn1[CRYPT_ECPRIKEY_VERSION_IDX].len = sizeof(version); + asn1[CRYPT_ECPRIKEY_VERSION_IDX].tag = BSL_ASN1_TAG_INTEGER; + BslOidString *oid = NULL; + CRYPT_PKEY_AlgId cid = CRYPT_EAL_PkeyGetId(ealPriKey); + if (cid == CRYPT_PKEY_SM2) { + oid = BSL_OBJ_GetOidFromCID((BslCid)CRYPT_ECC_SM2); + } else { + CRYPT_PKEY_ParaId paraId = CRYPT_EAL_PkeyGetParaId(ealPriKey); + oid = BSL_OBJ_GetOidFromCID((BslCid)paraId); + } + if (oid == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + if (pk8AlgoParam != NULL) { // pkcs8 + pk8AlgoParam->buff = (uint8_t *)oid->octs; + pk8AlgoParam->len = oid->octetLen; + pk8AlgoParam->tag = BSL_ASN1_TAG_OBJECT_ID; + } else { // pkcs1 + asn1[CRYPT_ECPRIKEY_PARAM_IDX].buff = (uint8_t *)oid->octs; + asn1[CRYPT_ECPRIKEY_PARAM_IDX].len = oid->octetLen; + asn1[CRYPT_ECPRIKEY_PARAM_IDX].tag = BSL_ASN1_TAG_OBJECT_ID; + } + + return EncodeEccKeyPair(ealPriKey, cid, asn1, encode); +} + +static void DeinitRsaPrvCtx(CRYPT_EAL_PkeyPrv *rsaPrv) +{ + BSL_SAL_ClearFree(rsaPrv->key.rsaPrv.d, rsaPrv->key.rsaPrv.dLen * 8); // 8 items +} + +static int32_t InitRsaPrvCtx(const CRYPT_EAL_PkeyCtx *ealPriKey, CRYPT_PKEY_AlgId cid, CRYPT_EAL_PkeyPrv *rsaPrv) +{ + uint32_t bnLen = CRYPT_EAL_PkeyGetKeyLen(ealPriKey); + if (bnLen == 0) { + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + uint8_t *pri = (uint8_t *)BSL_SAL_Malloc(bnLen * 8); // 8 items + if (pri == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + rsaPrv->id = cid; + rsaPrv->key.rsaPrv.d = pri; + rsaPrv->key.rsaPrv.n = pri + bnLen; + rsaPrv->key.rsaPrv.p = pri + bnLen * 2; // 2nd buffer + rsaPrv->key.rsaPrv.q = pri + bnLen * 3; // 3rd buffer + rsaPrv->key.rsaPrv.dP = pri + bnLen * 4; // 4th buffer + rsaPrv->key.rsaPrv.dQ = pri + bnLen * 5; // 5th buffer + rsaPrv->key.rsaPrv.qInv = pri + bnLen * 6; // 6th buffer + rsaPrv->key.rsaPrv.e = pri + bnLen * 7; // 7th buffer + + rsaPrv->key.rsaPrv.dLen = bnLen; + rsaPrv->key.rsaPrv.nLen = bnLen; + rsaPrv->key.rsaPrv.pLen = bnLen; + rsaPrv->key.rsaPrv.qLen = bnLen; + rsaPrv->key.rsaPrv.dPLen = bnLen; + rsaPrv->key.rsaPrv.dQLen = bnLen; + rsaPrv->key.rsaPrv.qInvLen = bnLen; + rsaPrv->key.rsaPrv.eLen = bnLen; + return CRYPT_SUCCESS; +} + +static void SetRsaPrv2Arr(const CRYPT_EAL_PkeyPrv *rsaPrv, BSL_ASN1_Buffer *asn1) +{ + asn1[CRYPT_RSA_PRV_D_IDX].buff = rsaPrv->key.rsaPrv.d; + asn1[CRYPT_RSA_PRV_D_IDX].len = rsaPrv->key.rsaPrv.dLen; + asn1[CRYPT_RSA_PRV_N_IDX].buff = rsaPrv->key.rsaPrv.n; + asn1[CRYPT_RSA_PRV_N_IDX].len = rsaPrv->key.rsaPrv.nLen; + asn1[CRYPT_RSA_PRV_E_IDX].buff = rsaPrv->key.rsaPrv.e; + asn1[CRYPT_RSA_PRV_E_IDX].len = rsaPrv->key.rsaPrv.eLen; + asn1[CRYPT_RSA_PRV_P_IDX].buff = rsaPrv->key.rsaPrv.p; + asn1[CRYPT_RSA_PRV_P_IDX].len = rsaPrv->key.rsaPrv.pLen; + asn1[CRYPT_RSA_PRV_Q_IDX].buff = rsaPrv->key.rsaPrv.q; + asn1[CRYPT_RSA_PRV_Q_IDX].len = rsaPrv->key.rsaPrv.qLen; + asn1[CRYPT_RSA_PRV_DP_IDX].buff = rsaPrv->key.rsaPrv.dP; + asn1[CRYPT_RSA_PRV_DP_IDX].len = rsaPrv->key.rsaPrv.dPLen; + asn1[CRYPT_RSA_PRV_DQ_IDX].buff = rsaPrv->key.rsaPrv.dQ; + asn1[CRYPT_RSA_PRV_DQ_IDX].len = rsaPrv->key.rsaPrv.dQLen; + asn1[CRYPT_RSA_PRV_QINV_IDX].buff = rsaPrv->key.rsaPrv.qInv; + asn1[CRYPT_RSA_PRV_QINV_IDX].len = rsaPrv->key.rsaPrv.qInvLen; + + asn1[CRYPT_RSA_PRV_D_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_N_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_E_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_P_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_Q_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_DP_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_DQ_IDX].tag = BSL_ASN1_TAG_INTEGER; + asn1[CRYPT_RSA_PRV_QINV_IDX].tag = BSL_ASN1_TAG_INTEGER; +} + +static int32_t EncodeRsaPrikeyAsn1Buff(CRYPT_EAL_PkeyCtx *ealPriKey, CRYPT_PKEY_AlgId cid, BSL_Buffer *encode) +{ + int32_t ret; + BSL_ASN1_Buffer asn1[CRYPT_RSA_PRV_OTHER_PRIME_IDX + 1] = {0}; + + CRYPT_EAL_PkeyPrv rsaPrv = {0}; + ret = InitRsaPrvCtx(ealPriKey, cid, &rsaPrv); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_PkeyGetPrv(ealPriKey, &rsaPrv); + if (ret != CRYPT_SUCCESS) { + DeinitRsaPrvCtx(&rsaPrv); + return ret; + } + SetRsaPrv2Arr(&rsaPrv, asn1); + uint8_t version = 0; + asn1[CRYPT_RSA_PRV_VERSION_IDX].buff = (uint8_t *)&version; + asn1[CRYPT_RSA_PRV_VERSION_IDX].len = sizeof(version); + asn1[CRYPT_RSA_PRV_VERSION_IDX].tag = BSL_ASN1_TAG_INTEGER; + BSL_ASN1_Template templ = {rsaPrvTempl, sizeof(rsaPrvTempl) / sizeof(rsaPrvTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asn1, CRYPT_RSA_PRV_OTHER_PRIME_IDX + 1, &encode->data, &encode->dataLen); + DeinitRsaPrvCtx(&rsaPrv); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t GetPssParamInfo(CRYPT_EAL_PkeyCtx *ealPriKey, CRYPT_RSA_PssPara *rsaPssParam) +{ + int32_t ret; + ret = CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_GET_RSA_SALT, &rsaPssParam->saltLen, sizeof(rsaPssParam->saltLen)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_GET_RSA_MD, &rsaPssParam->mdId, sizeof(rsaPssParam->mdId)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_GET_RSA_MGF, &rsaPssParam->mgfId, sizeof(rsaPssParam->mgfId)); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodePk8AlgidAny(CRYPT_EAL_PkeyCtx *ealPriKey, BSL_Buffer *bitStr, + BSL_ASN1_Buffer *algoId, CRYPT_PKEY_AlgId *cidOut) +{ + int32_t ret; + BSL_Buffer tmp = {0}; + CRYPT_PKEY_AlgId cid = CRYPT_EAL_PkeyGetId(ealPriKey); + if (cid == CRYPT_PKEY_RSA) { + CRYPT_RsaPadType pad = CRYPT_PKEY_RSA_PADDINGMAX; + ret = CRYPT_EAL_PkeyCtrl(ealPriKey, CRYPT_CTRL_GET_RSA_PADDING, &pad, sizeof(pad)); + if (ret != CRYPT_SUCCESS) { + return ret; + } + CRYPT_RSA_PssPara rsaPssParam = {0}; + switch (pad) { + case CRYPT_PKEY_EMSA_PSS: + ret = GetPssParamInfo(ealPriKey, &rsaPssParam); + if (ret != BSL_SUCCESS) { + return ret; + } + ret = EncodeRsaPrikeyAsn1Buff(ealPriKey, CRYPT_PKEY_RSA, &tmp); + if (ret != BSL_SUCCESS) { + return ret; + } + ret = CRYPT_EAL_EncodeRsaPssAlgParam(&rsaPssParam, &algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].buff, + &algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].len); + algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].tag = BSL_ASN1_TAG_SEQUENCE | BSL_ASN1_TAG_CONSTRUCTED; + cid = (CRYPT_PKEY_AlgId)BSL_CID_RSASSAPSS; + break; + default: + ret = EncodeRsaPrikeyAsn1Buff(ealPriKey, CRYPT_PKEY_RSA, &tmp); + algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].tag = BSL_ASN1_TAG_NULL; + break; + } + } else if (cid == CRYPT_PKEY_ECDSA || cid == CRYPT_PKEY_SM2) { + cid = (CRYPT_PKEY_AlgId)BSL_CID_EC_PUBLICKEY; + ret = EncodeEccPrikeyAsn1Buff(ealPriKey, &algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX], &tmp); + } else { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + if (ret != CRYPT_SUCCESS) { + BSL_SAL_ClearFree(tmp.data, tmp.dataLen); + return ret; + } + bitStr->data = tmp.data; + bitStr->dataLen = tmp.dataLen; + *cidOut = cid; + return ret; +} + +static int32_t EncodePk8PriKeyBuff(CRYPT_EAL_PkeyCtx *ealPriKey, BSL_Buffer *asn1) +{ + int32_t ret; + CRYPT_PKEY_AlgId cid; + BSL_Buffer bitStr = {0}; + BSL_ASN1_Buffer algo = {0}; + BSL_ASN1_Buffer algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX + 1] = {0}; + do { + ret = EncodePk8AlgidAny(ealPriKey, &bitStr, algoId, &cid); + if (ret != CRYPT_SUCCESS) { + break; + } + BslOidString *oidStr = BSL_OBJ_GetOidFromCID((BslCid)cid); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + ret = CRYPT_ERR_ALGID; + break; + } + algoId[BSL_ASN1_TAG_ALGOID_IDX].buff = (uint8_t *)oidStr->octs; + algoId[BSL_ASN1_TAG_ALGOID_IDX].len = oidStr->octetLen; + algoId[BSL_ASN1_TAG_ALGOID_IDX].tag = BSL_ASN1_TAG_OBJECT_ID; + ret = EncodeAlgoIdAsn1Buff(algoId, BSL_ASN1_TAG_ALGOID_ANY_IDX + 1, &algo.buff, &algo.len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + break; + } + + uint8_t version = 0; + BSL_ASN1_Buffer encode[CRYPT_PK8_PRIKEY_PRIKEY_IDX + 1] = { + {BSL_ASN1_TAG_INTEGER, sizeof(version), &version}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, algo.len, algo.buff}, + {BSL_ASN1_TAG_OCTETSTRING, bitStr.dataLen, bitStr.data} + }; + + BSL_ASN1_Template pubTempl = {pk8PriKeyTempl, sizeof(pk8PriKeyTempl) / sizeof(pk8PriKeyTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&pubTempl, + encode, CRYPT_PK8_PRIKEY_PRIKEY_IDX + 1, &asn1->data, &asn1->dataLen); + } while (0); + // rsa-pss mode release buffer + if (algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].tag == (BSL_ASN1_TAG_SEQUENCE | BSL_ASN1_TAG_CONSTRUCTED)) { + BSL_SAL_FREE(algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].buff); + } + BSL_SAL_ClearFree(bitStr.data, bitStr.dataLen); + BSL_SAL_FREE(algo.buff); + return ret; +} + +static int32_t EncodeDeriveKeyParam(CRYPT_Pbkdf2Param *param, BSL_Buffer *encode, BSL_Buffer *salt) +{ + BSL_ASN1_Buffer derParam[CRYPT_PKCS_ENC_DERPRF_IDX + 1] = {0}; + /* deralg */ + BslOidString *oidPbkdf = BSL_OBJ_GetOidFromCID((BslCid)param->pbkdfId); + if (oidPbkdf == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + derParam[CRYPT_PKCS_ENC_DERALG_IDX].buff = (uint8_t *)oidPbkdf->octs; + derParam[CRYPT_PKCS_ENC_DERALG_IDX].len = oidPbkdf->octetLen; + derParam[CRYPT_PKCS_ENC_DERALG_IDX].tag = BSL_ASN1_TAG_OBJECT_ID; + /* salt */ + int32_t ret = CRYPT_EAL_Randbytes(salt->data, salt->dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + derParam[CRYPT_PKCS_ENC_DERSALT_IDX].buff = salt->data; + derParam[CRYPT_PKCS_ENC_DERSALT_IDX].len = salt->dataLen; + derParam[CRYPT_PKCS_ENC_DERSALT_IDX].tag = BSL_ASN1_TAG_OCTETSTRING; + /* iter */ + ret = BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, param->itCnt, &derParam[CRYPT_PKCS_ENC_DERITER_IDX]); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Template templ = {g_pbkdf2DerParamTempl, sizeof(g_pbkdf2DerParamTempl) / sizeof(g_pbkdf2DerParamTempl[0])}; + if (param->hmacId == CRYPT_MAC_HMAC_SHA1) { + ret = BSL_ASN1_EncodeTemplate(&templ, derParam, CRYPT_PKCS_ENC_DERPRF_IDX + 1, &encode->data, &encode->dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + BSL_SAL_FREE(derParam[CRYPT_PKCS_ENC_DERITER_IDX].buff); + return ret; + } + BslOidString *oidHmac = BSL_OBJ_GetOidFromCID((BslCid)param->hmacId); + if (oidHmac == NULL) { + BSL_SAL_FREE(derParam[CRYPT_PKCS_ENC_DERITER_IDX].buff); + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + BSL_Buffer algo = {0}; + BSL_ASN1_Buffer algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX + 1] = { + {BSL_ASN1_TAG_OBJECT_ID, oidHmac->octetLen, (uint8_t *)oidHmac->octs}, + {BSL_ASN1_TAG_NULL, 0, NULL}, + }; + ret = EncodeAlgoIdAsn1Buff(algoId, BSL_ASN1_TAG_ALGOID_ANY_IDX + 1, &algo.data, &algo.dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(derParam[CRYPT_PKCS_ENC_DERITER_IDX].buff); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + derParam[CRYPT_PKCS_ENC_DERPRF_IDX].buff = algo.data; + derParam[CRYPT_PKCS_ENC_DERPRF_IDX].len = algo.dataLen; + derParam[CRYPT_PKCS_ENC_DERPRF_IDX].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + + ret = BSL_ASN1_EncodeTemplate(&templ, + derParam, CRYPT_PKCS_ENC_DERPRF_IDX + 1, &encode->data, &encode->dataLen); + BSL_SAL_FREE(algo.data); + BSL_SAL_FREE(derParam[CRYPT_PKCS_ENC_DERITER_IDX].buff); + return ret; +} + +static int32_t EncodeEncryptedData(CRYPT_Pbkdf2Param *pkcsParam, + BSL_Buffer *unEncrypted, BSL_Buffer *salt, BSL_ASN1_Buffer *asn1) +{ + int32_t ret; + uint8_t *symKey = NULL; + uint8_t *output = NULL; + uint32_t keyLen = 0; + do { + ret = CRYPT_EAL_CipherGetInfo(pkcsParam->symId, CRYPT_INFO_KEY_LEN, &keyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + break; + } + symKey = (uint8_t *)BSL_SAL_Malloc(keyLen); + if (symKey == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + ret = BSL_MALLOC_FAIL; + break; + } + ret = CRYPT_EAL_Pbkdf2(pkcsParam->hmacId, pkcsParam->pwd, pkcsParam->pwdLen, + salt->data, salt->dataLen, pkcsParam->itCnt, symKey, keyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + break; + } + + BSL_Buffer keyBuff = {symKey, keyLen}; + uint32_t pkcsDataLen = unEncrypted->dataLen + 16; // extras 16 for padding. + output = (uint8_t *)BSL_SAL_Malloc(pkcsDataLen); + if (output == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + ret = BSL_MALLOC_FAIL; + break; + } + BSL_Buffer enData = {unEncrypted->data, unEncrypted->dataLen}; + BSL_Buffer ivData = {asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff, asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].len}; + ret = DecryptEncData(&ivData, &enData, pkcsParam->symId, true, &keyBuff, output, &pkcsDataLen); + if (ret != CRYPT_SUCCESS) { + break; + } + asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff = output; + asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].len = pkcsDataLen; + asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].tag = BSL_ASN1_TAG_OCTETSTRING; + BSL_SAL_ClearFree(symKey, keyLen); + return ret; + } while (0); + BSL_SAL_ClearFree(symKey, keyLen); + asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff = NULL; + asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].len = 0; + BSL_SAL_FREE(output); + return ret; +} + +static int32_t GenRandIv(CRYPT_Pbkdf2Param *pkcsParam, BSL_ASN1_Buffer *asn1) +{ + int32_t ret; + BslOidString *oidSym = BSL_OBJ_GetOidFromCID((BslCid)pkcsParam->symId); + if (oidSym == NULL) { + return CRYPT_ERR_ALGID; + } + asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].buff = (uint8_t *)oidSym->octs; + asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].len = oidSym->octetLen; + asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].tag = BSL_ASN1_TAG_OBJECT_ID; + + uint32_t ivLen; + ret = CRYPT_EAL_CipherGetInfo(pkcsParam->symId, CRYPT_INFO_IV_LEN, &ivLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ivLen == 0) { + asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].tag = BSL_ASN1_TAG_OCTETSTRING; + return CRYPT_SUCCESS; + } + uint8_t *iv = (uint8_t *)BSL_SAL_Malloc(ivLen); + if (iv == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + ret = CRYPT_EAL_Randbytes(iv, ivLen); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(iv); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff = iv; + asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].len = ivLen; + asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].tag = BSL_ASN1_TAG_OCTETSTRING; + return ret; +} + +static int32_t CheckEncodeParam(const CRYPT_EncodeParam *encodeParam) +{ + if (encodeParam == NULL || encodeParam->param == NULL) { + return CRYPT_NULL_INPUT; + } + if (encodeParam->deriveMode != CRYPT_DERIVE_PBKDF2) { + return CRYPT_ENCODE_NO_SUPPORT_TYPE; + } + CRYPT_Pbkdf2Param *pkcsParam = (CRYPT_Pbkdf2Param *)encodeParam->param; + if (pkcsParam->pwdLen > PWD_MAX_LEN || (pkcsParam->pwd == NULL && pkcsParam->pwdLen != 0)) { + return CRYPT_INVALID_ARG; + } + if (pkcsParam->pbesId != BSL_CID_PBES2 || pkcsParam->pbkdfId != BSL_CID_PBKDF2) { + return CRYPT_ERR_ALGID; + } + return CRYPT_SUCCESS; +} + +static int32_t EncodePkcsEncryptedBuff(CRYPT_Pbkdf2Param *pkcsParam, + BSL_Buffer *unEncrypted, BSL_ASN1_Buffer *asn1) +{ + BslOidString *oidPbes = BSL_OBJ_GetOidFromCID((BslCid)pkcsParam->pbesId); + if (oidPbes == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + int32_t ret; + asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].buff = (uint8_t *)oidPbes->octs; + asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].len = oidPbes->octetLen; + asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].tag = BSL_ASN1_TAG_OBJECT_ID; + /* derivation param */ + BSL_Buffer derParam = {0}; + uint8_t *saltData = (uint8_t *)BSL_SAL_Malloc(pkcsParam->saltLen); + if (saltData == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + do { + BSL_Buffer salt = {saltData, pkcsParam->saltLen}; + ret = EncodeDeriveKeyParam(pkcsParam, &derParam, &salt); + if (ret != CRYPT_SUCCESS) { + break; + } + asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].buff = derParam.data; + asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].len = derParam.dataLen; + asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + /* iv */ + ret = GenRandIv(pkcsParam, asn1); + if (ret != CRYPT_SUCCESS) { + break; + } + /* encryptedData */ + ret = EncodeEncryptedData(pkcsParam, unEncrypted, &salt, asn1); + if (ret != CRYPT_SUCCESS) { + break; + } + BSL_SAL_FREE(saltData); + return CRYPT_SUCCESS; + } while (0); + BSL_SAL_FREE(saltData); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].buff); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff); + return ret; +} + +static int32_t EncodePk8EncPriKeyBuff(CRYPT_EAL_PkeyCtx *ealPriKey, + const CRYPT_EncodeParam *encodeParam, BSL_Buffer *encode) +{ + /* EncAlgid */ + int32_t ret = CheckEncodeParam(encodeParam); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_Pbkdf2Param *pkcs8Param = (CRYPT_Pbkdf2Param *)encodeParam->param; + BSL_Buffer unEncrypted = {0}; + ret = EncodePk8PriKeyBuff(ealPriKey, &unEncrypted); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BSL_ASN1_Buffer asn1[CRYPT_PKCS_ENCPRIKEY_MAX] = {0}; + do { + /* code */ + ret = EncodePkcsEncryptedBuff(pkcs8Param, &unEncrypted, asn1); + if (ret != CRYPT_SUCCESS) { + break; + } + /* encode */ + BSL_ASN1_Template templ = {pk8EncPriKeyTempl, sizeof(pk8EncPriKeyTempl) / sizeof(pk8EncPriKeyTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asn1, CRYPT_PKCS_ENCPRIKEY_MAX, &encode->data, &encode->dataLen); + } while (0); + BSL_SAL_ClearFree(unEncrypted.data, unEncrypted.dataLen); + if (ret == CRYPT_SUCCESS) { + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].buff); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff); + } + return ret; +} + +int32_t CRYPT_EAL_EncodeAsn1PriKey(CRYPT_EAL_PkeyCtx *ealPriKey, const CRYPT_EncodeParam *encodeParam, + int32_t type, BSL_Buffer *encode) +{ + switch (type) { + case CRYPT_PRIKEY_ECC: + return EncodeEccPrikeyAsn1Buff(ealPriKey, NULL, encode); + case CRYPT_PRIKEY_RSA: + return EncodeRsaPrikeyAsn1Buff(ealPriKey, CRYPT_PKEY_RSA, encode); + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + return EncodePk8PriKeyBuff(ealPriKey, encode); + default: + return EncodePk8EncPriKeyBuff(ealPriKey, encodeParam, encode); + } +} + +int32_t CRYPT_EAL_EncodePemPriKey(CRYPT_EAL_PkeyCtx *ealPriKey, const CRYPT_EncodeParam *encodeParam, + int32_t type, BSL_Buffer *encode) +{ + BSL_Buffer asn1 = {0}; + int32_t ret = CRYPT_EAL_EncodeAsn1PriKey(ealPriKey, encodeParam, type, &asn1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_PEM_Symbol symbol = {0}; + ret = EAL_GetPemPriKeySymbol(type, &symbol); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_Free(asn1.data); + return ret; + } + ret = BSL_PEM_EncodeAsn1ToPem(asn1.data, asn1.dataLen, &symbol, (char **)&encode->data, &encode->dataLen); + BSL_SAL_Free(asn1.data); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_EAL_PriKeyEncodeBuff(CRYPT_EAL_PkeyCtx *ealPriKey, const CRYPT_EncodeParam *encodeParam, + BSL_ParseFormat format, int32_t type, BSL_Buffer *encode) +{ + if (ealPriKey == NULL || encode == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + switch (format) { + case BSL_FORMAT_ASN1: + return CRYPT_EAL_EncodeAsn1PriKey(ealPriKey, encodeParam, type, encode); + case BSL_FORMAT_PEM: + return CRYPT_EAL_EncodePemPriKey(ealPriKey, encodeParam, type, encode); + default: + return CRYPT_ENCODE_NO_SUPPORT_FORMAT; + } +} + +int32_t CRYPT_EAL_PriKeyEncodeFile(CRYPT_EAL_PkeyCtx *ealPriKey, const CRYPT_EncodeParam *encodeParam, + BSL_ParseFormat format, int32_t type, const char *path) +{ + BSL_Buffer encode = {0}; + int32_t ret = CRYPT_EAL_PriKeyEncodeBuff(ealPriKey, encodeParam, format, type, &encode); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_SAL_WriteFile(path, encode.data, encode.dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + BSL_SAL_Free(encode.data); + return ret; +} + +static int32_t EncodeEccPubkeyAsn1Buff(CRYPT_EAL_PkeyCtx *ealPubKey, BSL_ASN1_Buffer *ecParamOid, BSL_Buffer *encodePub) +{ + int32_t ret; + CRYPT_PKEY_ParaId paraId = CRYPT_EAL_PkeyGetParaId(ealPubKey); + BslOidString *oid = BSL_OBJ_GetOidFromCID((BslCid)paraId); + if (CRYPT_EAL_PkeyGetId(ealPubKey) == CRYPT_PKEY_SM2) { + oid = BSL_OBJ_GetOidFromCID((BslCid)CRYPT_ECC_SM2); + } + if (oid == NULL) { + return CRYPT_ERR_ALGID; + } + ecParamOid->buff = (uint8_t *)oid->octs; + ecParamOid->len = oid->octetLen; + ecParamOid->tag = BSL_ASN1_TAG_OBJECT_ID; + + uint32_t pubLen = CRYPT_EAL_PkeyGetKeyLen(ealPubKey); + if (pubLen == 0) { + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + uint8_t *pub = (uint8_t *)BSL_SAL_Malloc(pubLen); + if (pub == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + CRYPT_EAL_PkeyPub pubKey = {0}; + pubKey.id = CRYPT_EAL_PkeyGetId(ealPubKey); + pubKey.key.eccPub.data = pub; + pubKey.key.eccPub.len = pubLen; + ret = CRYPT_EAL_PkeyGetPub(ealPubKey, &pubKey); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(pub); + return ret; + } + encodePub->data = pubKey.key.eccPub.data; + encodePub->dataLen = pubKey.key.eccPub.len; + return ret; +} + +static int32_t EncodePssParam(CRYPT_EAL_PkeyCtx *ealPubKey, BSL_ASN1_Buffer *pssParam) +{ + if (pssParam == NULL) { + return CRYPT_SUCCESS; + } + int32_t padType = 0; + int32_t ret = CRYPT_EAL_PkeyCtrl(ealPubKey, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(padType)); + if (ret != CRYPT_SUCCESS) { + return ret; + } + if (padType != CRYPT_PKEY_EMSA_PSS) { + pssParam->tag = BSL_ASN1_TAG_NULL; + return CRYPT_SUCCESS; + } + CRYPT_RSA_PssPara rsaPssParam = {0}; + ret = GetPssParamInfo(ealPubKey, &rsaPssParam); + if (ret != CRYPT_SUCCESS) { + return ret; + } + pssParam->tag = BSL_ASN1_TAG_SEQUENCE | BSL_ASN1_TAG_CONSTRUCTED; + return CRYPT_EAL_EncodeRsaPssAlgParam(&rsaPssParam, &pssParam->buff, &pssParam->len); +} + +static int32_t EncodeRsaPubkeyAsn1Buff(CRYPT_EAL_PkeyCtx *ealPubKey, BSL_ASN1_Buffer *pssParam, BSL_Buffer *encodePub) +{ + int32_t ret; + BSL_ASN1_Buffer pubAsn1[CRYPT_RSA_PUB_E_IDX + 1] = {0}; + uint32_t bnLen = CRYPT_EAL_PkeyGetKeyLen(ealPubKey); + if (bnLen == 0) { + return CRYPT_EAL_ALG_NOT_SUPPORT; + } + CRYPT_EAL_PkeyPub pub = {0}; + pub.id = CRYPT_PKEY_RSA; + pub.key.rsaPub.n = (uint8_t *)BSL_SAL_Malloc(bnLen); + if (pub.key.rsaPub.n == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + pub.key.rsaPub.e = (uint8_t *)BSL_SAL_Malloc(bnLen); + if (pub.key.rsaPub.e == NULL) { + BSL_SAL_FREE(pub.key.rsaPub.n); + return CRYPT_MEM_ALLOC_FAIL; + } + pub.key.rsaPub.nLen = bnLen; + pub.key.rsaPub.eLen = bnLen; + + ret = CRYPT_EAL_PkeyGetPub(ealPubKey, &pub); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(pub.key.rsaPub.n); + BSL_SAL_FREE(pub.key.rsaPub.e); + return ret; + } + pubAsn1[CRYPT_RSA_PUB_N_IDX].buff = pub.key.rsaPub.n; + pubAsn1[CRYPT_RSA_PUB_N_IDX].len = pub.key.rsaPub.nLen; + pubAsn1[CRYPT_RSA_PUB_E_IDX].buff = pub.key.rsaPub.e; + pubAsn1[CRYPT_RSA_PUB_E_IDX].len = pub.key.rsaPub.eLen; + pubAsn1[CRYPT_RSA_PUB_N_IDX].tag = BSL_ASN1_TAG_INTEGER; + pubAsn1[CRYPT_RSA_PUB_E_IDX].tag = BSL_ASN1_TAG_INTEGER; + + BSL_ASN1_Template pubTempl = {rsaPubTempl, sizeof(rsaPubTempl) / sizeof(rsaPubTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&pubTempl, pubAsn1, CRYPT_RSA_PUB_E_IDX + 1, &encodePub->data, &encodePub->dataLen); + BSL_SAL_FREE(pub.key.rsaPub.n); + BSL_SAL_FREE(pub.key.rsaPub.e); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = EncodePssParam(ealPubKey, pssParam); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(encodePub->data); + } + return ret; +} + +static int32_t CRYPT_EAL_SubPubkeyGetInfo(CRYPT_EAL_PkeyCtx *ealPubKey, BSL_ASN1_Buffer *algo, BSL_Buffer *bitStr) +{ + int32_t ret; + CRYPT_PKEY_AlgId cid = CRYPT_EAL_PkeyGetId(ealPubKey); + BSL_Buffer bitTmp = {0}; + BSL_ASN1_Buffer algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX + 1] = {0}; + if (cid == CRYPT_PKEY_RSA) { + ret = EncodeRsaPubkeyAsn1Buff(ealPubKey, &algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX], &bitTmp); + if (algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].tag == (BSL_ASN1_TAG_SEQUENCE | BSL_ASN1_TAG_CONSTRUCTED)) { + cid = (CRYPT_PKEY_AlgId)BSL_CID_RSASSAPSS; + } + } else if (cid == CRYPT_PKEY_ECDSA || cid == CRYPT_PKEY_SM2) { + cid = (CRYPT_PKEY_AlgId)BSL_CID_EC_PUBLICKEY; + ret = EncodeEccPubkeyAsn1Buff(ealPubKey, &algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX], &bitTmp); + } else { + return CRYPT_ERR_ALGID; + } + if (ret != CRYPT_SUCCESS) { + return ret; + } + BslOidString *oidStr = BSL_OBJ_GetOidFromCID((BslCid)cid); + if (oidStr == NULL) { + BSL_SAL_FREE(bitTmp.data); + ret = CRYPT_ERR_ALGID; + goto end; + } + algoId[BSL_ASN1_TAG_ALGOID_IDX].buff = (uint8_t *)oidStr->octs; + algoId[BSL_ASN1_TAG_ALGOID_IDX].len = oidStr->octetLen; + algoId[BSL_ASN1_TAG_ALGOID_IDX].tag = BSL_ASN1_TAG_OBJECT_ID; + ret = EncodeAlgoIdAsn1Buff(algoId, BSL_ASN1_TAG_ALGOID_ANY_IDX + 1, &algo->buff, &algo->len); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(bitTmp.data); + goto end; + } + bitStr->data = bitTmp.data; + bitStr->dataLen = bitTmp.dataLen; +end: + if (cid == (CRYPT_PKEY_AlgId)BSL_CID_RSASSAPSS) { + BSL_SAL_FREE(algoId[BSL_ASN1_TAG_ALGOID_ANY_IDX].buff); + } + return ret; +} + +static int32_t CRYPT_EAL_EncodeAsn1SubPubkey(CRYPT_EAL_PkeyCtx *ealPubKey, bool isComplete, BSL_Buffer *encodeH) +{ + BSL_ASN1_Buffer algo = {0}; + BSL_Buffer bitStr = {0}; + int32_t ret = CRYPT_EAL_SubPubkeyGetInfo(ealPubKey, &algo, &bitStr); + if (ret != CRYPT_SUCCESS) { + return ret; + } + BSL_ASN1_Buffer encode[CRYPT_SUBKEYINFO_BITSTRING_IDX + 1] = {0}; + encode[CRYPT_SUBKEYINFO_ALGOID_IDX].buff = algo.buff; + encode[CRYPT_SUBKEYINFO_ALGOID_IDX].len = algo.len; + encode[CRYPT_SUBKEYINFO_ALGOID_IDX].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + BSL_ASN1_BitString bitPubkey = {bitStr.data, bitStr.dataLen, 0}; + encode[CRYPT_SUBKEYINFO_BITSTRING_IDX].buff = (uint8_t *)&bitPubkey; + encode[CRYPT_SUBKEYINFO_BITSTRING_IDX].len = sizeof(BSL_ASN1_BitString); + encode[CRYPT_SUBKEYINFO_BITSTRING_IDX].tag = BSL_ASN1_TAG_BITSTRING; + + BSL_ASN1_Template pubTempl; + if (isComplete) { + pubTempl.templItems = subKeyInfoTempl; + pubTempl.templNum = sizeof(subKeyInfoTempl) / sizeof(subKeyInfoTempl[0]); + } else { + pubTempl.templItems = subKeyInfoInnerTempl; + pubTempl.templNum = sizeof(subKeyInfoInnerTempl) / sizeof(subKeyInfoInnerTempl[0]); + } + ret = BSL_ASN1_EncodeTemplate(&pubTempl, + encode, CRYPT_SUBKEYINFO_BITSTRING_IDX + 1, &encodeH->data, &encodeH->dataLen); + BSL_SAL_FREE(bitStr.data); + BSL_SAL_FREE(algo.buff); + return ret; +} + +static int32_t CRYPT_EAL_EncodeAsn1PubKey(CRYPT_EAL_PkeyCtx *ealPubKey, + int32_t type, bool isComplete, BSL_Buffer *encode) +{ + switch (type) { + case CRYPT_PUBKEY_SUBKEY: + return CRYPT_EAL_EncodeAsn1SubPubkey(ealPubKey, isComplete, encode); + case CRYPT_PUBKEY_RSA: + return EncodeRsaPubkeyAsn1Buff(ealPubKey, NULL, encode); + default: + return CRYPT_ENCODE_NO_SUPPORT_TYPE; + } +} + +static int32_t CRYPT_EAL_EncodePemPubKey(CRYPT_EAL_PkeyCtx *ealPubKey, + int32_t type, bool isComplete, BSL_Buffer *encode) +{ + BSL_Buffer asn1 = {0}; + int32_t ret = CRYPT_EAL_EncodeAsn1PubKey(ealPubKey, type, isComplete, &asn1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_PEM_Symbol symbol = {0}; + ret = EAL_GetPemPubKeySymbol(type, &symbol); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(asn1.data); + return ret; + } + ret = BSL_PEM_EncodeAsn1ToPem(asn1.data, asn1.dataLen, &symbol, (char **)&encode->data, &encode->dataLen); + BSL_SAL_FREE(asn1.data); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_EAL_EncodePubKeyBuffInternal(CRYPT_EAL_PkeyCtx *ealPubKey, + BSL_ParseFormat format, int32_t type, bool isComplete, BSL_Buffer *encode) +{ + if (ealPubKey == NULL || encode == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + switch (format) { + case BSL_FORMAT_ASN1: + return CRYPT_EAL_EncodeAsn1PubKey(ealPubKey, type, isComplete, encode); + case BSL_FORMAT_PEM: + return CRYPT_EAL_EncodePemPubKey(ealPubKey, type, isComplete, encode); + default: + return CRYPT_ENCODE_NO_SUPPORT_FORMAT; + } +} + +int32_t CRYPT_EAL_PubKeyEncodeBuff(CRYPT_EAL_PkeyCtx *ealPubKey, + BSL_ParseFormat format, int32_t type, BSL_Buffer *encode) +{ + return CRYPT_EAL_EncodePubKeyBuffInternal(ealPubKey, format, type, true, encode); +} + +int32_t CRYPT_EAL_PubKeyEncodeFile(CRYPT_EAL_PkeyCtx *ealPubKey, + BSL_ParseFormat format, int32_t type, const char *path) +{ + BSL_Buffer encode = {0}; + int32_t ret = CRYPT_EAL_PubKeyEncodeBuff(ealPubKey, format, type, &encode); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_SAL_WriteFile(path, encode.data, encode.dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + BSL_SAL_FREE(encode.data); + return ret; +} + +int32_t CRYPT_EAL_DecodeBuffKey(BSL_ParseFormat format, int32_t type, BSL_Buffer *encode, + const uint8_t *pwd, uint32_t pwdlen, CRYPT_EAL_PkeyCtx **ealPKey) +{ + switch (type) { + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + case CRYPT_PRIKEY_PKCS8_ENCRYPT: + case CRYPT_PRIKEY_RSA: + case CRYPT_PRIKEY_ECC: + return CRYPT_EAL_PriKeyParseBuff(format, type, encode, pwd, pwdlen, ealPKey); + case CRYPT_PUBKEY_SUBKEY: + case CRYPT_PUBKEY_RSA: + return CRYPT_EAL_PubKeyParseBuff(format, type, encode, ealPKey); + default: + return CRYPT_DECODE_NO_SUPPORT_TYPE; + } +} + +int32_t CRYPT_EAL_DecodeFileKey(BSL_ParseFormat format, int32_t type, const char *path, + uint8_t *pwd, uint32_t pwdlen, CRYPT_EAL_PkeyCtx **ealPKey) +{ + if (path == NULL || strlen(path) > PATH_MAX_LEN) { + return CRYPT_INVALID_ARG; + } + switch (type) { + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + case CRYPT_PRIKEY_PKCS8_ENCRYPT: + case CRYPT_PRIKEY_RSA: + case CRYPT_PRIKEY_ECC: + return CRYPT_EAL_PriKeyParseFile(format, type, path, pwd, pwdlen, ealPKey); + case CRYPT_PUBKEY_SUBKEY: + case CRYPT_PUBKEY_RSA: + return CRYPT_EAL_PubKeyParseFile(format, type, path, ealPKey); + default: + return CRYPT_DECODE_NO_SUPPORT_TYPE; + } +} + +int32_t CRYPT_EAL_EncodeBuffKey(CRYPT_EAL_PkeyCtx *ealPKey, const CRYPT_EncodeParam *encodeParam, + BSL_ParseFormat format, int32_t type, BSL_Buffer *encode) +{ + switch (type) { + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + case CRYPT_PRIKEY_PKCS8_ENCRYPT: + case CRYPT_PRIKEY_RSA: + case CRYPT_PRIKEY_ECC: + return CRYPT_EAL_PriKeyEncodeBuff(ealPKey, encodeParam, format, type, encode); + case CRYPT_PUBKEY_SUBKEY: + case CRYPT_PUBKEY_RSA: + return CRYPT_EAL_PubKeyEncodeBuff(ealPKey, format, type, encode); + default: + return CRYPT_ENCODE_NO_SUPPORT_TYPE; + } +} + +int32_t CRYPT_EAL_EncodeFileKey(CRYPT_EAL_PkeyCtx *ealPKey, const CRYPT_EncodeParam *encodeParam, + BSL_ParseFormat format, int32_t type, const char *path) +{ + if (path == NULL || strlen(path) > PATH_MAX_LEN) { + return CRYPT_INVALID_ARG; + } + switch (type) { + case CRYPT_PRIKEY_PKCS8_UNENCRYPT: + case CRYPT_PRIKEY_PKCS8_ENCRYPT: + case CRYPT_PRIKEY_RSA: + case CRYPT_PRIKEY_ECC: + return CRYPT_EAL_PriKeyEncodeFile(ealPKey, encodeParam, format, type, path); + case CRYPT_PUBKEY_SUBKEY: + case CRYPT_PUBKEY_RSA: + return CRYPT_EAL_PubKeyEncodeFile(ealPKey, format, type, path); + default: + return CRYPT_ENCODE_NO_SUPPORT_TYPE; + } +} + +#define HITLS_P7_SPECIFIC_ENCONTENTINFO_EXTENSION 0 + +/** + * EncryptedContentInfo ::= SEQUENCE { + * contentType ContentType, + * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, + * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL + * } + * + * https://datatracker.ietf.org/doc/html/rfc5652#section-6.1 + */ + +static BSL_ASN1_TemplateItem enContentInfoTempl[] = { + /* ContentType */ + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + /* ContentEncryptionAlgorithmIdentifier */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, // ContentEncryptionAlgorithmIdentifier + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 2}, // derivation param + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, // enc scheme + {BSL_ASN1_TAG_OBJECT_ID, 0, 3}, // alg + {BSL_ASN1_TAG_OCTETSTRING, 0, 3}, // iv + /* encryptedContent */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_P7_SPECIFIC_ENCONTENTINFO_EXTENSION, BSL_ASN1_FLAG_OPTIONAL, 0}, +}; + +typedef enum { + HITLS_P7_ENC_CONTINFO_TYPE_IDX, + HITLS_P7_ENC_CONTINFO_ENCALG_IDX, + HITLS_P7_ENC_CONTINFO_DERIVE_PARAM_IDX, + HITLS_P7_ENC_CONTINFO_SYMALG_IDX, + HITLS_P7_ENC_CONTINFO_SYMIV_IDX, + HITLS_P7_ENC_CONTINFO_ENCONTENT_IDX, + HITLS_P7_ENC_CONTINFO_MAX_IDX, +} HITLS_P7_ENC_CONTINFO_IDX; + +static int32_t ParsePKCS7EncryptedContentInfo(BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, + BSL_Buffer *output) +{ + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + BSL_ASN1_Buffer asn1[HITLS_P7_ENC_CONTINFO_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {enContentInfoTempl, sizeof(enContentInfoTempl) / sizeof(enContentInfoTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asn1, HITLS_P7_ENC_CONTINFO_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BslOidString typeOidStr = {asn1[HITLS_P7_ENC_CONTINFO_TYPE_IDX].len, + (char *)asn1[HITLS_P7_ENC_CONTINFO_TYPE_IDX].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&typeOidStr); + if (cid != BSL_CID_DATA) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNSUPPORTED_PKCS7_TYPE); + return CRYPT_DECODE_UNSUPPORTED_PKCS7_TYPE; + } + BslOidString encOidStr = {asn1[HITLS_P7_ENC_CONTINFO_ENCALG_IDX].len, + (char *)asn1[HITLS_P7_ENC_CONTINFO_ENCALG_IDX].buff, 0}; + cid = BSL_OBJ_GetCIDFromOid(&encOidStr); + if (cid != BSL_CID_PBES2) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNSUPPORTED_ENCRYPT_TYPE); + return CRYPT_DECODE_UNSUPPORTED_ENCRYPT_TYPE; + } + // parse sym alg id + BslOidString symOidStr = {asn1[HITLS_P7_ENC_CONTINFO_SYMALG_IDX].len, + (char *)asn1[HITLS_P7_ENC_CONTINFO_SYMALG_IDX].buff, 0}; + BslCid symId = BSL_OBJ_GetCIDFromOid(&symOidStr); + if (symId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNKNOWN_OID); + return CRYPT_DECODE_UNKNOWN_OID; + } + BSL_Buffer derivekeyData = {asn1[HITLS_P7_ENC_CONTINFO_DERIVE_PARAM_IDX].buff, + asn1[HITLS_P7_ENC_CONTINFO_DERIVE_PARAM_IDX].len}; + BSL_Buffer ivData = {asn1[HITLS_P7_ENC_CONTINFO_SYMIV_IDX].buff, asn1[HITLS_P7_ENC_CONTINFO_SYMIV_IDX].len}; + BSL_Buffer enData = {asn1[HITLS_P7_ENC_CONTINFO_ENCONTENT_IDX].buff, asn1[HITLS_P7_ENC_CONTINFO_ENCONTENT_IDX].len}; + EncryptPara encPara = { + .derivekeyData = &derivekeyData, + .ivData = &ivData, + .enData = &enData, + }; + ret = ParseEncDataAsn1(symId, &encPara, pwd, pwdlen, output); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +#define HITLS_P7_SPECIFIC_UNPROTECTEDATTRS_EXTENSION 1 + +/** + * EncryptedData ::= SEQUENCE { + * version CMSVersion, + * encryptedContentInfo EncryptedContentInfo, + * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL + * } + * + * https://datatracker.ietf.org/doc/html/rfc5652#page-29 +*/ +static BSL_ASN1_TemplateItem encryptedDataTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + /* version */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, + /* EncryptedContentInfo */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, + /* unprotectedAttrs */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET | HITLS_P7_SPECIFIC_UNPROTECTEDATTRS_EXTENSION, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 1}, +}; + +typedef enum { + HITLS_P7_ENCRYPTDATA_VERSION_IDX, + HITLS_P7_ENCRYPTDATA_ENCRYPTINFO_IDX, + HITLS_P7_ENCRYPTDATA_UNPROTECTEDATTRS_IDX, + HITLS_P7_ENCRYPTDATA_MAX_IDX, +} HITLS_P7_ENCRYPTDATA_IDX; + +int32_t CRYPT_EAL_ParseAsn1PKCS7EncryptedData(BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, + BSL_Buffer *output) +{ + if (encode == NULL || pwd == NULL || output == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pwdlen > PWD_MAX_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + BSL_ASN1_Buffer asn1[HITLS_P7_ENCRYPTDATA_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {encryptedDataTempl, sizeof(encryptedDataTempl) / sizeof(encryptedDataTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asn1, HITLS_P7_ENCRYPTDATA_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t version = 0; + ret = BSL_ASN1_DecodePrimitiveItem(&asn1[HITLS_P7_ENCRYPTDATA_VERSION_IDX], &version); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (version == 0 && asn1[HITLS_P7_ENCRYPTDATA_UNPROTECTEDATTRS_IDX].buff != NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS7_INVALIDE_ENCRYPTDATA_TYPE); + return CRYPT_DECODE_PKCS7_INVALIDE_ENCRYPTDATA_TYPE; + } + // In RFC5652, if the encapsulated content type is other than id-data, then the value of version MUST be 2. + if (version == 2 && asn1[HITLS_P7_ENCRYPTDATA_UNPROTECTEDATTRS_IDX].buff == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_PKCS7_INVALIDE_ENCRYPTDATA_TYPE); + return CRYPT_DECODE_PKCS7_INVALIDE_ENCRYPTDATA_TYPE; + } + BSL_Buffer encryptInfo = {asn1[HITLS_P7_ENCRYPTDATA_ENCRYPTINFO_IDX].buff, + asn1[HITLS_P7_ENCRYPTDATA_ENCRYPTINFO_IDX].len}; + ret = ParsePKCS7EncryptedContentInfo(&encryptInfo, pwd, pwdlen, output); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +/** + * @brief 编码PKCS7-EncryptData:只支持编码PBES2 + PBKDF2的Buffer,校验参考CheckEncodeParam + * + * @param data [IN] 待加密和编码的明文 + * @param encodeParam [IN] 加密参数 + * @param encode [OUT] 编码数据,内存由本接口分配 + * + * @return CRYPT_SUCCESS: 编码成功 + * @return other: 编码失败 + */ +static int32_t EncodePKCS7EncryptedContentInfo(BSL_Buffer *data, const CRYPT_EncodeParam *encodeParam, + BSL_Buffer *encode) +{ + /* EncAlgid */ + int32_t ret = CheckEncodeParam(encodeParam); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_Pbkdf2Param *pkcs7Param = (CRYPT_Pbkdf2Param *)encodeParam->param; + BSL_ASN1_Buffer asn1[CRYPT_PKCS_ENCPRIKEY_MAX] = {0}; + do { + /* code */ + ret = EncodePkcsEncryptedBuff(pkcs7Param, data, asn1); + if (ret != CRYPT_SUCCESS) { + break; + } + /* encode */ + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(BSL_CID_DATA); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + ret = CRYPT_ERR_ALGID; + break; + } + BSL_ASN1_Buffer p7asn[HITLS_P7_ENC_CONTINFO_MAX_IDX] = { + {BSL_ASN1_TAG_OBJECT_ID, oidStr->octetLen, (uint8_t *)oidStr->octs}, + {asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].tag, + asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].len, asn1[CRYPT_PKCS_ENCPRIKEY_ENCALG_IDX].buff}, + {asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].tag, + asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].len, asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].buff}, + {asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].tag, + asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].len, asn1[CRYPT_PKCS_ENCPRIKEY_SYMALG_IDX].buff}, + {asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].tag, + asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].len, asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_P7_SPECIFIC_ENCONTENTINFO_EXTENSION, + asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].len, asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff}, + }; + BSL_ASN1_Template templ = {enContentInfoTempl, sizeof(enContentInfoTempl) / sizeof(enContentInfoTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, p7asn, HITLS_P7_ENC_CONTINFO_MAX_IDX, &encode->data, &encode->dataLen); + } while (0); + if (ret == CRYPT_SUCCESS) { + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_DERPARAM_IDX].buff); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_SYMIV_IDX].buff); + BSL_SAL_FREE(asn1[CRYPT_PKCS_ENCPRIKEY_ENCDATA_IDX].buff); + } + return ret; +} + +/** + * @brief 编码PKCS7-EncryptData:只支持编码PBES2 + PBKDF2的Buffer,校验参考CheckEncodeParam + * + * @param data [IN] 待加密和编码的明文 + * @param encodeParam [IN] 加密参数 + * @param encode [OUT] 编码数据,内存由本接口分配 + * + * @return CRYPT_SUCCESS: 编码成功 + * @return other: 编码失败 + */ +int32_t CRYPT_EAL_EncodePKCS7EncryptDataBuff(BSL_Buffer *data, const void *encodeParam, BSL_Buffer *encode) +{ + if (data == NULL || encodeParam == NULL || encode == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + BSL_Buffer contentInfo = {0}; + int32_t ret = EncodePKCS7EncryptedContentInfo(data, encodeParam, &contentInfo); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint8_t version = 0; + BSL_ASN1_Buffer asn1[HITLS_P7_ENCRYPTDATA_MAX_IDX] = { + {BSL_ASN1_TAG_INTEGER, sizeof(version), &version}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, contentInfo.dataLen, contentInfo.data}, + {0, 0, 0}, + }; + BSL_ASN1_Template templ = {encryptedDataTempl, sizeof(encryptedDataTempl) / sizeof(encryptedDataTempl[0])}; + BSL_Buffer tmp = {0}; + ret = BSL_ASN1_EncodeTemplate(&templ, asn1, HITLS_P7_ENCRYPTDATA_MAX_IDX, &tmp.data, &tmp.dataLen); + BSL_SAL_FREE(contentInfo.data); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + encode->data = tmp.data; + encode->dataLen = tmp.dataLen; + return ret; +} + +#endif // HITLS_CRYPTO_ENCODE diff --git a/crypto/encode/src/crypt_encode.c b/crypto/encode/src/crypt_encode.c new file mode 100644 index 00000000..7edf82cf --- /dev/null +++ b/crypto/encode/src/crypt_encode.c @@ -0,0 +1,612 @@ +/* + * 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_ENCODE +#include "securec.h" +#include "crypt_errno.h" +#include "bsl_err_internal.h" +#include "bsl_obj_internal.h" +#include "crypt_encode.h" +#include "bsl_asn1.h" + +/** + * https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-der-encoding-of-asn-1-types asn1 encoding format + * https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer interger encoding format + */ + +#define CONS_SEQ_TAG 0x30 +#define PRIM_INT_TAG 0x02 + +static uint32_t GetBytes(uint32_t num) +{ + uint32_t val = num; + uint32_t ret = 0; + while (val != 0) { + ret++; + val >>= 8; // right shifting 8 bits equals the offset of 1 byte. + } + return ret; +} + +/** + * ANS1 encoding format: When the length is less than 0x80, the first byte indicates the data length. + * If the length is greater than 0x80, the most significant bit of the first byte is set to 1, + * the least significant seven bits indicate the length of the len data. + * For example: + * The length is 0x40, and the encoded data is represented as 0x40 data... + * The length is 0x85, and the encoded data is 0x81 0x85 data... + * The length is 0x50FF, and the encoded data is 0x82 0x50 0xFF data... + */ +static uint32_t GetEnCodeLen(uint32_t dataLen) +{ + uint32_t ret = 2; // tag + len need 2 bytes + if (dataLen > 0x7F) { // if the most significant bit is 1 + ret += GetBytes(dataLen); + } + return ret; +} + +/** Internal function, which is not supported when rLen/sLen is greater than 32764. + * When r and s exceed 32764, the total length exceeds 65536 (that is, 0xFFFF) 32764 * 2 + 4 * 2 = 65536. + * Currently, the DSA key is limited to 3072 bits, that is, 384 bytes. This code can be used to cover this case. + */ +uint32_t ASN1_SignEnCodeLen(uint32_t rLen, uint32_t sLen) +{ + uint32_t rEncodeLen = GetEnCodeLen(rLen) + rLen; + uint32_t sEncodeLen = GetEnCodeLen(sLen) + sLen; + uint32_t enCodeLen = GetEnCodeLen(rEncodeLen + sEncodeLen); + return rEncodeLen + sEncodeLen + enCodeLen; +} + +static void TagLenEncode(uint8_t *data, uint32_t *off, uint8_t tag, uint32_t len) +{ + uint32_t offset = *off; + data[offset] = tag; + offset++; + if (len > 0x7F) { + uint32_t bytes = GetBytes(len); + data[offset++] = 0x80 | (bytes & 0x7F); + while (bytes > 0) { + data[offset++] = (len >> ((bytes - 1) * 8)) & 0xFF; // * 8 to calculate the number of offset bits. + bytes--; + } + } else { + data[offset] = len & 0xFF; + offset++; + } + *off = offset; +} + +uint32_t ASN1_SignStringLenOfBn(const BN_BigNum *num) +{ + uint32_t bits = BN_Bits(num); + /** + * https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer + * If the integer is positive but the high order bit is set to 1, + * a leading 0x00 is added to the content to indicate that the number is not negative + */ + // When the bit is a multiple of 8, and the most significant bit is 1, 0x00 needs to be added. + // If the bit is not a multiple of 8, an extra byte needs to be added to store the data less than 8 bits. + return (bits / 8) + 1; +} + +// Encode num into sign. +static int32_t StringEncode(uint8_t *sign, uint32_t *signLen, const BN_BigNum *num) +{ + uint32_t bits = BN_Bits(num); + if (*signLen < 1) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH; + } + if (bits == 0) { + sign[0] = 0; + *signLen = 1; + return CRYPT_SUCCESS; + } + + uint32_t offset = 0; + // If the first byte is greater than 0x7F, and the bit length is a multiple of 8, 0 is added at the beginning. + if (bits % 8 == 0) { + sign[0] = 0; + offset++; + (*signLen)--; + } + int32_t ret = BN_Bn2Bin(num, sign + offset, signLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *signLen += offset; + return ret; +} + +// Decode the sign to the num. +static int32_t StringDecode(const uint8_t *sign, uint32_t signLen, BN_BigNum *num) +{ + uint32_t offset = 0; + // Ignore the first byte 0. + if (sign[0] == 0) { + offset++; + } + if (signLen == offset) { + return BN_Zeroize(num); + } + if (((sign[offset] & 0x80) != 0) && (offset == 0)) { + // The most significant bit is 0x80, indicating that the data is a negative number and decoding fails. + BSL_ERR_PUSH_ERROR(CRYPT_DSA_DECODE_FAIL); + return CRYPT_DSA_DECODE_FAIL; + } + return BN_Bin2Bn(num, sign + offset, signLen - offset); +} + +/** Internal function, which is not supported when rLen/sLen is greater than 32764. + * When r and s exceed 32764, the total length exceeds 65536 (that is, 0xFFFF) 32764 * 2 + 4 * 2 = 65536. + * Currently the specification of the DSA key is 3072 bits, that is 384 bytes. The code in this case can be implemented. + * EncodeData: CONS_SEQ_TAG + Len + PRIM_INT_TAG + rLen + r + PRIM_INT_TAG + sLen + s + * For details about the encoding format, see RFC6979-A.1.3. + */ +int32_t ASN1_SignDataEncode(const DSA_Sign *s, uint8_t *sign, uint32_t *signLen) +{ + uint32_t rLen = ASN1_SignStringLenOfBn(s->r); + uint32_t sLen = ASN1_SignStringLenOfBn(s->s); + // Ensure that the data length is sufficient for encoding and decoding. + if (ASN1_SignEnCodeLen(rLen, sLen) > *signLen) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH; + } + uint32_t offset = 0; + sign[offset] = CONS_SEQ_TAG; + // CONS_SEQ_TAG + Len + TagLenEncode(sign, &offset, CONS_SEQ_TAG, rLen + sLen + GetEnCodeLen(rLen) + GetEnCodeLen(sLen)); + // PRIM_INT_TAG + rLen + TagLenEncode(sign, &offset, PRIM_INT_TAG, rLen); + uint32_t len = *signLen - offset; + // r + int32_t ret = StringEncode(sign + offset, &len, s->r); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + offset += len; + // PRIM_INT_TAG + sLen + TagLenEncode(sign, &offset, PRIM_INT_TAG, sLen); + len = *signLen - offset; + // s + ret = StringEncode(sign + offset, &len, s->s); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *signLen = offset + len; + return ret; +} +// Obtain the size of the next data block and check the validity of the length. If 0 is returned, the parsing fails. +// If other values are returned, that means the parsed data length is obtained. +static uint32_t GetDecodeLen(const uint8_t *sign, uint32_t signLen, uint32_t *off, uint8_t tag) +{ + uint32_t offset = *off; + uint32_t cnt = 0; + uint32_t ret = 0; + // Determine whether out-of-bounds. + if (offset >= signLen) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return 0; + } + // Check whether the tags are consistent. + if (sign[offset] != tag) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return 0; + } + offset++; + // Determine whether out-of-bounds. + if (offset >= signLen) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return 0; + } + // Obtain the length of the length identifier. + if ((sign[offset] & 0x80) != 0) { + cnt = sign[offset] & 0x7F; + offset++; + } else { + cnt = 1; + } + // Check whether the length is meaningful and out of range. + if (cnt == 0 || (offset + cnt) > signLen) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return 0; + } + uint32_t i; + // Obtain the length. + for (i = 0; i < cnt; i++) { + ret <<= 8; + ret += sign[offset + i]; + } + // Check whether the length is meaningful. + if (ret == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return 0; + } + offset += i; + // Determine whether out-of-bounds. + if (offset + ret > signLen) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return 0; + } + *off = offset; + return ret; +} +// For details about the decoding format, see RFC6979-A.1.3. +int32_t ASN1_SignDataDecode(DSA_Sign *s, const uint8_t *sign, uint32_t signLen) +{ + uint32_t len; + uint32_t offset = 0; + + len = GetDecodeLen(sign, signLen, &offset, CONS_SEQ_TAG); + if (len == 0 || len != signLen - offset) { // Check whether the total length is correct. + BSL_ERR_PUSH_ERROR(CRYPT_DSA_DECODE_FAIL); + return CRYPT_DSA_DECODE_FAIL; + } + len = GetDecodeLen(sign, signLen, &offset, PRIM_INT_TAG); + if (len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DSA_DECODE_FAIL); + return CRYPT_DSA_DECODE_FAIL; + } + int32_t ret = StringDecode(sign + offset, len, s->r); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + offset += len; + len = GetDecodeLen(sign, signLen, &offset, PRIM_INT_TAG); + if (len == 0 || len != (signLen - offset)) { // last block + BSL_ERR_PUSH_ERROR(CRYPT_DSA_DECODE_FAIL); + return CRYPT_DSA_DECODE_FAIL; + } + ret = StringDecode(sign + offset, len, s->s); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t EncodeHashAlg(CRYPT_MD_AlgId mdId, BSL_ASN1_Buffer *asn) +{ + if (mdId == CRYPT_MD_SHA1) { + asn->tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_HASH; + asn->buff = NULL; + asn->len = 0; + return CRYPT_SUCCESS; + } + BSL_ASN1_Buffer asnArr[2] = {0}; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID((BslCid)mdId); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + asnArr[0].tag = BSL_ASN1_TAG_OBJECT_ID; + asnArr[0].len = oidStr->octetLen; + asnArr[0].buff = (uint8_t *)oidStr->octs; + asnArr[1].tag = BSL_ASN1_TAG_NULL; + + BSL_ASN1_TemplateItem hashTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 1}, + }; + BSL_ASN1_Template templ = {hashTempl, sizeof(hashTempl) / sizeof(hashTempl[0])}; + int32_t ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, 2, &(asn->buff), &(asn->len)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asn->tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_HASH; + return CRYPT_SUCCESS; +} + +static int32_t EncodeMgfAlg(CRYPT_MD_AlgId mgfId, BSL_ASN1_Buffer *asn) +{ + if (mgfId == CRYPT_MD_SHA1) { + asn->tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_MASKGEN; + asn->buff = NULL; + asn->len = 0; + return CRYPT_SUCCESS; + } + BSL_ASN1_Buffer asnArr[3] = {0}; + BslOidString *mgfStr = BSL_OBJ_GetOidFromCID(BSL_CID_MGF1); + if (mgfStr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + asnArr[0].tag = BSL_ASN1_TAG_OBJECT_ID; + asnArr[0].len = mgfStr->octetLen; + asnArr[0].buff = (uint8_t *)mgfStr->octs; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID((BslCid)mgfId); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + asnArr[1].tag = BSL_ASN1_TAG_OBJECT_ID; + asnArr[1].len = oidStr->octetLen; + asnArr[1].buff = (uint8_t *)oidStr->octs; + asnArr[2].tag = BSL_ASN1_TAG_NULL; // 2 : param + BSL_ASN1_TemplateItem mgfTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2}, + }; + BSL_ASN1_Template templ = {mgfTempl, sizeof(mgfTempl) / sizeof(mgfTempl[0])}; + int32_t ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, 3, &(asn->buff), &(asn->len)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asn->tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_MASKGEN; + return CRYPT_SUCCESS; +} + +static int32_t EncodeSaltLen(uint64_t saltLen, BSL_ASN1_Buffer *asn) +{ + if (saltLen == 20) { // 20 : default saltLen + asn->tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | + CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_SALTLEN; + asn->buff = NULL; + asn->len = 0; + return CRYPT_SUCCESS; + } + BSL_ASN1_Buffer saltAsn = {0}; + int32_t ret = BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, saltLen, &saltAsn); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_TemplateItem saltTempl = {BSL_ASN1_TAG_INTEGER, 0, 0}; + BSL_ASN1_Template templ = {&saltTempl, 1}; + ret = BSL_ASN1_EncodeTemplate(&templ, &saltAsn, 1, &(asn->buff), &(asn->len)); + BSL_SAL_Free(saltAsn.buff); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asn->tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_SALTLEN; + return CRYPT_SUCCESS; +} + +#define X509_RSAPSS_ELEM_NUMBER 4 +int32_t CRYPT_EAL_EncodeRsaPssAlgParam(CRYPT_RSA_PssPara *rsaPssParam, uint8_t **buf, uint32_t *bufLen) +{ + BSL_ASN1_Buffer asnArr[X509_RSAPSS_ELEM_NUMBER] = {0}; + int32_t ret = EncodeHashAlg(rsaPssParam->mdId, &asnArr[0]); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = EncodeMgfAlg(rsaPssParam->mgfId, &asnArr[1]); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + + ret = EncodeSaltLen(rsaPssParam->saltLen, &asnArr[2]); // 2: saltLength + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + if (asnArr[0].len + asnArr[1].len + asnArr[2].len == 0) { // [0]:hash + [1]:mgf + [2]:salt all default + return ret; + } + // 3 : trailed + asnArr[3].tag = BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_TRAILED; + BSL_ASN1_TemplateItem rsapssTempl[] = { + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_HASH, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_MASKGEN, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_SALTLEN, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | CRYPT_ASN1_CTX_SPECIFIC_TAG_RSAPSS_TRAILED, + BSL_ASN1_FLAG_DEFAULT, 0}, + }; + BSL_ASN1_Template templ = {rsapssTempl, sizeof(rsapssTempl) / sizeof(rsapssTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, X509_RSAPSS_ELEM_NUMBER, buf, bufLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR: + for (uint32_t i = 0; i < X509_RSAPSS_ELEM_NUMBER; i++) { + BSL_SAL_Free(asnArr[i].buff); + } + return ret; +} + +#ifdef HITLS_CRYPTO_SM2_CRYPT + +#define PRIM_OCT_STRING_TAG 0x04 +#define SM2_CURVE_BITS_WIDTH 32 +#define SM2_CURVE_BITS_WIDTH_TWICE 64 +#define SM3_HASH_LEN 32 + +uint64_t ASN1_Sm2GetEnCodeLen(uint32_t dataLen) +{ + uint32_t initBytes = 2; // 'tag', 'len' needs 2 bytes. + uint32_t c1EncodeLen = (SM2_CURVE_BITS_WIDTH + initBytes + 1) * 2; // x, y all needs to be encoded. + uint32_t c3EncodeLen = SM3_HASH_LEN + initBytes; + uint32_t c2EncodeLen = GetEnCodeLen(dataLen) + dataLen; + uint32_t sum = GetEnCodeLen(c1EncodeLen + c3EncodeLen + c2EncodeLen); + return c1EncodeLen + c3EncodeLen + c2EncodeLen + sum; +} + +static int32_t Sm2FetchString(const uint8_t *encode, uint32_t encodeLen, uint8_t *num, uint32_t numLen, uint8_t tag) +{ + if (tag == PRIM_INT_TAG && (encode[0] & 0x80) != 0) { + // The most significant bit is not 0. Decoding failed. + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECODE_FAIL); + return CRYPT_SM2_DECODE_FAIL; + } + uint32_t hasPad = 0; + uint32_t hasZero = 0; + if (tag == PRIM_INT_TAG && encodeLen > SM2_CURVE_BITS_WIDTH) { + hasPad = 1; // There are padding of INT_TAG data during encoding. + } + if (tag == PRIM_INT_TAG && encodeLen < SM2_CURVE_BITS_WIDTH) { + // if encodeLen < 32, add 0 to the front of the data to facilitate transcoding during decryption. + hasZero = SM2_CURVE_BITS_WIDTH - encodeLen; + } + (void)memcpy_s(num + hasZero, numLen - hasZero, encode + hasPad, encodeLen - hasPad); + return CRYPT_SUCCESS; +} + +static void Sm2EnterString(uint8_t *output, uint32_t *outputLen, + const uint8_t *num, uint32_t numLen, bool pad) +{ + uint32_t len = *outputLen; + if (numLen == 0) { + output[0] = 0; + *outputLen = 1; + return; + } + + uint32_t offset = 0; + if (pad) { + output[0] = 0; + offset++; + len--; + } + (void)memcpy_s(output + offset, len, num, numLen); + *outputLen = numLen + offset; +} + +static void GetXYstatus(const uint8_t *input, uint32_t *tmpXLen, uint32_t *tmpYLen, bool *xPad, bool *yPad) +{ + if ((input[0] & 0x80) != 0) { + *tmpXLen += 1; + *xPad = true; + } + if ((input[SM2_CURVE_BITS_WIDTH] & 0x80) != 0) { + *tmpYLen += 1; + *yPad = true; + } + return; +} + +// Encode the SM2 ciphertext into the ASNI format according to the GM/T 0009-2012. +int32_t ASN1_Sm2EncryptDataEncode(const uint8_t *input, uint32_t inputLen, uint8_t *encode, uint32_t *encodeLen) +{ + uint32_t tmpXLen = SM2_CURVE_BITS_WIDTH; + uint32_t tmpYLen = SM2_CURVE_BITS_WIDTH; + uint32_t c2Len = inputLen - SM2_CURVE_BITS_WIDTH_TWICE - SM3_HASH_LEN; + bool xPad = false; + bool yPad = false; + uint32_t len = 0; + uint32_t offset = 0; + + // CONS_SEQ_TAG + Len + GetXYstatus(input, &tmpXLen, &tmpYLen, &xPad, &yPad); + // x, y and hash are all less than 128 bytes long, so only need 2 extra bytes to encode, 2 * 3 = 6 + TagLenEncode(encode, &offset, CONS_SEQ_TAG, tmpXLen + tmpYLen + SM3_HASH_LEN + 6 + c2Len + GetEnCodeLen(c2Len)); + + // x + // PRIM_INT_TAG + tmpXLen + TagLenEncode(encode, &offset, PRIM_INT_TAG, tmpXLen); + len = *encodeLen - offset; + Sm2EnterString(encode + offset, &len, input, SM2_CURVE_BITS_WIDTH, xPad); + offset += len; + + // y + // PRIM_INT_TAG + tmpYLen + TagLenEncode(encode, &offset, PRIM_INT_TAG, tmpYLen); + len = *encodeLen - offset; + Sm2EnterString(encode + offset, &len, input + SM2_CURVE_BITS_WIDTH, SM2_CURVE_BITS_WIDTH, yPad); + offset += len; + + // c3 + // PRIM_INT_TAG + tmpSLen + TagLenEncode(encode, &offset, PRIM_OCT_STRING_TAG, SM3_HASH_LEN); + len = *encodeLen - offset; + Sm2EnterString(encode + offset, &len, input + SM2_CURVE_BITS_WIDTH_TWICE, SM3_HASH_LEN, false); + offset += len; + + // c2 + // PRIM_INT_TAG + tmpSLen + TagLenEncode(encode, &offset, PRIM_OCT_STRING_TAG, c2Len); + len = *encodeLen - offset; + Sm2EnterString(encode + offset, &len, input + SM2_CURVE_BITS_WIDTH_TWICE + SM3_HASH_LEN, c2Len, false); + + *encodeLen = offset + len; + return CRYPT_SUCCESS; +} + +int32_t ASN1_Sm2EncryptDataDecode(const uint8_t *eData, uint32_t eLen, uint8_t *decode, uint32_t *decodeLen) +{ + uint32_t len; + uint32_t offset = 0; + int32_t ret = 0; + // decode whole len + len = GetDecodeLen(eData, eLen, &offset, CONS_SEQ_TAG); + if (len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECODE_FAIL); + return CRYPT_SM2_DECODE_FAIL; + } + + // get X + len = GetDecodeLen(eData, eLen, &offset, PRIM_INT_TAG); + if (len == 0 || len > SM2_CURVE_BITS_WIDTH + 1) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECODE_FAIL); + return CRYPT_SM2_DECODE_FAIL; + } + + ret = Sm2FetchString(eData + offset, len, decode, SM2_CURVE_BITS_WIDTH, PRIM_INT_TAG); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + offset += len; + + // get Y + len = GetDecodeLen(eData, eLen, &offset, PRIM_INT_TAG); + if (len == 0 || len > SM2_CURVE_BITS_WIDTH + 1) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECODE_FAIL); + return CRYPT_SM2_DECODE_FAIL; + } + ret = Sm2FetchString(eData + offset, len, decode + SM2_CURVE_BITS_WIDTH, SM2_CURVE_BITS_WIDTH, PRIM_INT_TAG); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + offset += len; + + // get c3 + len = GetDecodeLen(eData, eLen, &offset, PRIM_OCT_STRING_TAG); + if (len != SM3_HASH_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECODE_FAIL); + return CRYPT_SM2_DECODE_FAIL; + } + (void)Sm2FetchString(eData + offset, len, decode + SM2_CURVE_BITS_WIDTH_TWICE, SM3_HASH_LEN, PRIM_OCT_STRING_TAG); + offset += len; + + // get c2 + len = GetDecodeLen(eData, eLen, &offset, PRIM_OCT_STRING_TAG); + if (len == 0 || (len > (*decodeLen - SM2_CURVE_BITS_WIDTH_TWICE - SM3_HASH_LEN))) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECODE_FAIL); + return CRYPT_SM2_DECODE_FAIL; + } + (void)Sm2FetchString(eData + offset, len, decode + SM2_CURVE_BITS_WIDTH_TWICE + SM3_HASH_LEN, len, + PRIM_OCT_STRING_TAG); + *decodeLen = SM2_CURVE_BITS_WIDTH_TWICE + SM3_HASH_LEN + len; + return ret; +} +#endif // HITLS_CRYPTO_SM2_CRYPT + +#endif // HITLS_CRYPTO_ENCODE diff --git a/crypto/entropy/include/entropy.h b/crypto/entropy/include/entropy.h new file mode 100644 index 00000000..f9ef1098 --- /dev/null +++ b/crypto/entropy/include/entropy.h @@ -0,0 +1,76 @@ +/* + * 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 ENTROPY_H +#define ENTROPY_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ENTROPY + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__linux__) +#ifndef ENTROPY_USE_DEVRANDOM +#define ENTROPY_USE_DEVRANDOM +#endif +#endif + +typedef int32_t (*ExternalConditioningFunction)(uint32_t algId, uint8_t *in, uint32_t inLen, uint8_t *out, + uint32_t *outLen); + +typedef struct EntropyCtx { + uint32_t algId; + ExternalConditioningFunction conFunc; +} EntropyCtx; + +/** + * @brief Obtain the entropy source handle. + * + * @param conFunc external conditioning function + * @param algId ID of Algorithm + * @return Success: EntropyCtx + */ +EntropyCtx *ENTROPY_GetCtx(ExternalConditioningFunction conFunc, uint32_t algId); + +/** + * @brief Obtain random number using the default system entropy source + * + * @param data data + * @param len length + * @return Success: CRYPT_SUCCESS + */ +int32_t ENTROPY_GetRandom(uint8_t *data, uint32_t len); + +/** + * @brief Obtain the full entropy output. + * + * @param ctx context + * @param data random number + * @param len length + * @return Success: CRYPT_SUCCESS + */ +int32_t ENTROPY_GetFullEntropyInput(void *ctx, uint8_t *data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_ENTROPY + +#endif // ENTROPY_H diff --git a/crypto/entropy/src/entropy.c b/crypto/entropy/src/entropy.c new file mode 100644 index 00000000..0311caea --- /dev/null +++ b/crypto/entropy/src/entropy.c @@ -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_CRYPTO_ENTROPY + +#include + +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "securec.h" +#include "entropy.h" + +static EntropyCtx g_entropyCtx = { 0 }; + +static uint32_t ECFAlgidValidCheck(uint32_t algId) +{ + uint32_t algTable[] = { + CRYPT_MD_SHA224, CRYPT_MD_SHA256, CRYPT_MD_SHA384, CRYPT_MD_SHA512, + CRYPT_MD_SHA3_224, CRYPT_MD_SHA3_256, CRYPT_MD_SHA3_384, CRYPT_MD_SHA3_512, + CRYPT_MAC_HMAC_SHA224, CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512, + CRYPT_MAC_HMAC_SHA3_224, CRYPT_MAC_HMAC_SHA3_256, CRYPT_MAC_HMAC_SHA3_384, CRYPT_MAC_HMAC_SHA3_512 + }; + for (uint32_t iter = 0; iter < sizeof(algTable) / sizeof(algTable[0]); iter++) { + if (algId == algTable[iter]) { + return CRYPT_SUCCESS; + } + } + BSL_ERR_PUSH_ERROR(CRYPT_ENTROPY_ECF_ALG_ERROR); + return CRYPT_ENTROPY_ECF_ALG_ERROR; +} + +EntropyCtx *ENTROPY_GetCtx(ExternalConditioningFunction conFunc, uint32_t algId) +{ + if (ECFAlgidValidCheck(algId) != CRYPT_SUCCESS || conFunc == NULL) { + return NULL; + } + g_entropyCtx.algId = algId; + g_entropyCtx.conFunc = conFunc; + return &g_entropyCtx; +} + +#define ECF_MAX_OUTPUT_LEN 64 +#define ECF_ADDITION_LEN 8 // reference nist-800 90c-3pd section 3.3.2 + +int32_t ENTROPY_GetFullEntropyInput(void *ctx, uint8_t *data, uint32_t len) +{ + EntropyCtx *enCtx = (EntropyCtx *)ctx; + uint8_t *ptr = data; + uint32_t remainLen = len; + int32_t ret = CRYPT_SUCCESS; + if (enCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t oneLen = len + ECF_ADDITION_LEN; + uint8_t *tmp = BSL_SAL_Malloc(oneLen); + if (tmp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + do { + ret = ENTROPY_GetRandom(tmp, oneLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + break; + } + uint8_t conData[ECF_MAX_OUTPUT_LEN] = {0}; + uint32_t conLen = ECF_MAX_OUTPUT_LEN; + ret = enCtx->conFunc(enCtx->algId, tmp, oneLen, conData, &conLen); + (void)memset_s(tmp, oneLen, 0, oneLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + break; + } + uint32_t cpLen = (conLen > remainLen) ? remainLen : conLen; + (void)memcpy_s(ptr, remainLen, conData, cpLen); + remainLen -= cpLen; + ptr += cpLen; + (void)memset_s(conData, conLen, 0, conLen); + } while (remainLen > 0); + BSL_SAL_FREE(tmp); + return ret; +} +#endif /* HITLS_CRYPTO_ENTROPY */ diff --git a/crypto/entropy/src/system_entropy.c b/crypto/entropy/src/system_entropy.c new file mode 100644 index 00000000..538f731f --- /dev/null +++ b/crypto/entropy/src/system_entropy.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ENTROPY + +#include + +#include "entropy.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" + +#ifdef ENTROPY_USE_DEVRANDOM +#include +#include +#include +#endif + +int32_t ENTROPY_GetRandom(uint8_t *data, uint32_t len) +{ +#ifdef ENTROPY_USE_DEVRANDOM + int32_t fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY); + return CRYPT_DRBG_FAIL_GET_ENTROPY; + } + uint32_t remain = len; + int32_t count = 0; + uint8_t *ptr = data; + do { + count = (int32_t)read(fd, ptr, remain); + if (count == -1 && errno == EINTR) { + continue; + } else if (count == -1) { + break; + } + remain -= (uint32_t)count; + ptr += (uint32_t)count; + } while (remain > 0); + close(fd); + if (remain > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY); + return CRYPT_DRBG_FAIL_GET_ENTROPY; + } + return CRYPT_SUCCESS; +#else + (void)data; + (void)len; + BSL_ERR_PUSH_ERROR(CRYPT_DRBG_FAIL_GET_ENTROPY); + return CRYPT_DRBG_FAIL_GET_ENTROPY; +#endif +} +#endif /* HITLS_CRYPTO_ENTROPY */ diff --git a/crypto/hkdf/include/crypt_hkdf.h b/crypto/hkdf/include/crypt_hkdf.h new file mode 100644 index 00000000..3ca294f8 --- /dev/null +++ b/crypto/hkdf/include/crypt_hkdf.h @@ -0,0 +1,102 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_HKDF_H +#define CRYPT_HKDF_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_HKDF + +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief HKdf Key derivation algorithm + * + * @param macMeth [in] HMAC algorithm method. Only the HMAC method is supported. + * @param mdMeth [in] md algorithm method + * @param key [IN] Password, a string entered by the user. + * @param keyLen [IN] The password length is any length, including 0. + * @param salt [IN] Salt value, a string entered by the user. + * @param saltLen [IN] Salt value length, including 0. + * @param info [in] Additional information + * @param infoLen [in] Length of the extra information, which can be any length, including 0. + * @param out [OUT] Derive key. + * @param outLen [IN] Derived key length, is any integer other than 0. The maximum value is as follows: + * The maximum value of CRYPT_MAC_HMAC_SHA1 is 5100. + * The maximum value of CRYPT_MAC_HMAC_SHA224 is 7140. + * The maximum value of CRYPT_MAC_HMAC_SHA256 is 8160. + * The maximum value of CRYPT_MAC_HMAC_SHA384 is 12240. + * The maximum value of CRYPT_MAC_HMAC_SHA512 is 16320, + * + * @return CRYPT_OK succeeded. + * For other error codes, see ht_error.h. + */ + +int32_t CRYPT_HKDF(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len); + +/** + * @brief Extract function of the HKDf algorithm + * + * @param macMeth [in] HMAC algorithm method. Only the HMAC method is supported. + * @param mdMeth [in] md algorithm method + * @param key [IN] Password, a string entered by the user. + * @param keyLen [IN] The password length, which can be any length, including 0. + * @param salt [IN] Salt value, a string entered by the user. + * @param saltLen [IN] Salt value length, including 0. + * @param prk [OUT] Pseudo-random key + * @param prkLen [OUT] Pseudo-random key length + * + * @return CRYPT_OK succeeded. + * For other error codes, see ht_error.h. + */ +int32_t CRYPT_HKDF_Extract(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, uint8_t *prk, uint32_t *prkLen); + +/** + * @brief Expand function for the HKdf algorithm + * + * @param macMeth [in] HMAC algorithm method. Only the HMAC method is supported. + * @param mdMeth [in] md algorithm method + * @param prk [IN] Pseudo-random key, at least the length of hash (generally the output of the Extract function) + * @param prkLen [IN] Pseudo-random key length + * @param info [in] Additional information + * @param infoLen [in] Length of the extra information, which can be any length, including 0. + * @param out [OUT] Derive key. + * @param outLen [IN] length of the derived key, any integer other than 0. The maximum value is as follows: + * The maximum value of CRYPT_MAC_HMAC_SHA1 is 5100. + * The maximum value of CRYPT_MAC_HMAC_SHA224 is 7140. + * The maximum value of CRYPT_MAC_HMAC_SHA256 is 8160. + * The maximum value of CRYPT_MAC_HMAC_SHA384 is 12240. + * The maximum value of CRYPT_MAC_HMAC_SHA512 is 16320, + * + * @return CRYPT_OK succeeded. + * For other error codes, see ht_error.h. + */ +int32_t CRYPT_HKDF_Expand(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *prk, uint32_t prkLen, + const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t outLen); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_HKDF + +#endif // CRYPT_HKDF_H diff --git a/crypto/hkdf/src/hkdf.c b/crypto/hkdf/src/hkdf.c new file mode 100644 index 00000000..bf250f8a --- /dev/null +++ b/crypto/hkdf/src/hkdf.c @@ -0,0 +1,157 @@ +/* + * 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_HKDF + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_local_types.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_hkdf.h" + +#define HKDF_MAX_HMACSIZE 64 + +int32_t CRYPT_HKDF_Extract(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, + uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint8_t *prk, uint32_t *prkLen) +{ + int32_t ret; + if (macMeth == NULL || mdMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (key == NULL && keyLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (salt == NULL && saltLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + void *macCtx = BSL_SAL_Malloc(macMeth->ctxSize); + if (macCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)memset_s(macCtx, macMeth->ctxSize, 0, macMeth->ctxSize); + + GOTO_ERR_IF(macMeth->initCtx(macCtx, mdMeth), ret); + GOTO_ERR_IF(macMeth->init(macCtx, salt, saltLen), ret); + GOTO_ERR_IF(macMeth->update(macCtx, key, keyLen), ret); + GOTO_ERR_IF(macMeth->final(macCtx, prk, prkLen), ret); + +ERR: + macMeth->deinit(macCtx); + macMeth->deinitCtx(macCtx); + BSL_SAL_FREE(macCtx); + return ret; +} + +static int32_t HKDF_ExpandParamCheck(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *prk, + uint32_t prkLen, const uint8_t *info, uint32_t infoLen, const uint8_t *out, uint32_t outLen) +{ + if (macMeth == NULL || mdMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (prk == NULL && prkLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (info == NULL && infoLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((out == NULL) || (outLen == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (mdMeth->mdSize == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_HKDF_PARAM_ERROR); + return CRYPT_HKDF_PARAM_ERROR; + } + /* len cannot be larger than 255 * hashLen */ + if (outLen > (uint32_t)mdMeth->mdSize * 255) { + BSL_ERR_PUSH_ERROR(CRYPT_HKDF_DKLEN_OVERFLOW); + return CRYPT_HKDF_DKLEN_OVERFLOW; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_HKDF_Expand(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *prk, uint32_t prkLen, + const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t outLen) +{ + int32_t ret = HKDF_ExpandParamCheck(macMeth, mdMeth, prk, prkLen, info, infoLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint8_t hash[HKDF_MAX_HMACSIZE]; + uint32_t hashLen = mdMeth->mdSize; + uint8_t counter = 1; + uint32_t totalLen = 0; + uint32_t n; + void *macCtx = BSL_SAL_Malloc(macMeth->ctxSize); + if (macCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + GOTO_ERR_IF(macMeth->initCtx(macCtx, mdMeth), ret); + GOTO_ERR_IF(macMeth->init(macCtx, prk, prkLen), ret); + + /* ceil(a / b) = (a + b - 1) / b */ + n = (outLen + hashLen - 1) / hashLen; + for (uint32_t i = 1; i <= n; i++, counter++) { + if (i > 1) { + macMeth->reinit(macCtx); + GOTO_ERR_IF(macMeth->update(macCtx, hash, hashLen), ret); + } + GOTO_ERR_IF(macMeth->update(macCtx, info, infoLen), ret); + GOTO_ERR_IF(macMeth->update(macCtx, &counter, 1), ret); + GOTO_ERR_IF(macMeth->final(macCtx, hash, &hashLen), ret); + hashLen = hashLen > (outLen - totalLen) ? (outLen - totalLen) : hashLen; + (void)memcpy_s(out + totalLen, outLen - totalLen, hash, hashLen); + totalLen += hashLen; + } + +ERR: + macMeth->deinit(macCtx); + macMeth->deinitCtx(macCtx); + BSL_SAL_FREE(macCtx); + return ret; +} + +int32_t CRYPT_HKDF(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len) +{ + int ret; + uint8_t prk[HKDF_MAX_HMACSIZE]; + uint32_t prkLen = HKDF_MAX_HMACSIZE; + ret = CRYPT_HKDF_Extract(macMeth, mdMeth, key, keyLen, salt, saltLen, prk, &prkLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = CRYPT_HKDF_Expand(macMeth, mdMeth, prk, prkLen, info, infoLen, out, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_HKDF diff --git a/crypto/hmac/include/crypt_hmac.h b/crypto/hmac/include/crypt_hmac.h new file mode 100644 index 00000000..c2c4ed04 --- /dev/null +++ b/crypto/hmac/include/crypt_hmac.h @@ -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 CRYPT_HMAC_H +#define CRYPT_HMAC_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_HMAC + +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define HMAC_MAXBLOCKSIZE 144 +#define HMAC_MAXOUTSIZE 64 + +typedef struct HMAC_Ctx { + const EAL_MdMethod *method; + void *mdCtx; /* md ctx */ + void *oCtx; /* opad ctx */ + void *iCtx; /* ipad ctx */ +} CRYPT_HMAC_Ctx; + +int32_t CRYPT_HMAC_InitCtx(CRYPT_HMAC_Ctx *ctx, const EAL_MdMethod *m); +void CRYPT_HMAC_DeinitCtx(CRYPT_HMAC_Ctx *ctx); +int32_t CRYPT_HMAC_Init(CRYPT_HMAC_Ctx *ctx, const uint8_t *key, uint32_t len); +int32_t CRYPT_HMAC_Update(CRYPT_HMAC_Ctx *ctx, const uint8_t *in, uint32_t len); +int32_t CRYPT_HMAC_Final(CRYPT_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len); +void CRYPT_HMAC_Reinit(CRYPT_HMAC_Ctx *ctx); +void CRYPT_HMAC_Deinit(CRYPT_HMAC_Ctx *ctx); +uint32_t CRYPT_HMAC_GetMacLen(const CRYPT_HMAC_Ctx *ctx); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // HITLS_CRYPTO_HMAC + +#endif // CRYPT_HMAC_H diff --git a/crypto/hmac/src/hmac.c b/crypto/hmac/src/hmac.c new file mode 100644 index 00000000..1d23f1a1 --- /dev/null +++ b/crypto/hmac/src/hmac.c @@ -0,0 +1,181 @@ +/* + * 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_HMAC + +#include +#include "securec.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_hmac.h" + +uint32_t CRYPT_HMAC_GetMacLen(const CRYPT_HMAC_Ctx *ctx) +{ + if (ctx == NULL || ctx->method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return ctx->method->mdSize; +} + +int32_t CRYPT_HMAC_InitCtx(CRYPT_HMAC_Ctx *ctx, const EAL_MdMethod *m) +{ + if (ctx == NULL || m == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + void *mdCtx = (void *)BSL_SAL_Malloc(m->ctxSize * 3); // 3 contexts including mdCtx, iCtx, oCtx + if (mdCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + // clear 3 contexts including mdCtx, iCtx, oCtx + (void)memset_s(mdCtx, m->ctxSize * 3, 0, m->ctxSize * 3); + + ctx->mdCtx = mdCtx; + ctx->iCtx = (void *)((uint8_t *)mdCtx + m->ctxSize); + // offset 2 ctxSize: (mdCtx, iCtx) + ctx->oCtx = (void *)((uint8_t *)mdCtx + m->ctxSize * 2); + ctx->method = m; + + return CRYPT_SUCCESS; +} + +void CRYPT_HMAC_DeinitCtx(CRYPT_HMAC_Ctx *ctx) +{ + if (ctx == NULL || ctx->method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + const EAL_MdMethod *method = ctx->method; + // clear 3 contexts including mdCtx, iCtx, oCtx + BSL_SAL_CleanseData((void *)(ctx->mdCtx), method->ctxSize * 3); + BSL_SAL_FREE(ctx->mdCtx); +} + +static void HmacCleanseData(uint8_t *tmp, uint32_t tmpLen, uint8_t *ipad, uint32_t ipadLen, + uint8_t *opad, uint32_t opadLen) +{ + BSL_SAL_CleanseData(tmp, tmpLen); + BSL_SAL_CleanseData(ipad, ipadLen); + BSL_SAL_CleanseData(opad, opadLen); +} + +int32_t CRYPT_HMAC_Init(CRYPT_HMAC_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL || ctx->method == NULL || (key == NULL && len != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + const EAL_MdMethod *method = ctx->method; + uint32_t blockSize = method->blockSize; + uint8_t tmp[HMAC_MAXBLOCKSIZE]; + uint32_t tmpLen = HMAC_MAXBLOCKSIZE; + const uint8_t *keyTmp = key; + uint32_t i, keyLen = len; + uint8_t ipad[HMAC_MAXBLOCKSIZE]; + uint8_t opad[HMAC_MAXBLOCKSIZE]; + int32_t ret; + + if (keyLen > blockSize) { + keyTmp = tmp; + GOTO_ERR_IF(method->init(ctx->mdCtx), ret); + GOTO_ERR_IF(method->update(ctx->mdCtx, key, keyLen), ret); + GOTO_ERR_IF(method->final(ctx->mdCtx, tmp, &tmpLen), ret); + keyLen = method->mdSize; + } + for (i = 0; i < keyLen; i++) { + ipad[i] = 0x36 ^ keyTmp[i]; + opad[i] = 0x5c ^ keyTmp[i]; + } + for (i = keyLen; i < blockSize; i++) { + ipad[i] = 0x36; + opad[i] = 0x5c; + } + GOTO_ERR_IF(method->init(ctx->iCtx), ret); + GOTO_ERR_IF(method->update(ctx->iCtx, ipad, method->blockSize), ret); + GOTO_ERR_IF(method->init(ctx->oCtx), ret); + GOTO_ERR_IF(method->update(ctx->oCtx, opad, method->blockSize), ret); + GOTO_ERR_IF(method->copyCtx(ctx->mdCtx, ctx->iCtx), ret); + + HmacCleanseData(tmp, HMAC_MAXBLOCKSIZE, ipad, HMAC_MAXBLOCKSIZE, opad, HMAC_MAXBLOCKSIZE); + return CRYPT_SUCCESS; + +ERR: + HmacCleanseData(tmp, HMAC_MAXBLOCKSIZE, ipad, HMAC_MAXBLOCKSIZE, opad, HMAC_MAXBLOCKSIZE); + method->deinit(ctx->mdCtx); + method->deinit(ctx->iCtx); + method->deinit(ctx->oCtx); + return ret; +} + +int32_t CRYPT_HMAC_Update(CRYPT_HMAC_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + if (ctx == NULL || ctx->method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ctx->method->update(ctx->mdCtx, in, len); +} + +int32_t CRYPT_HMAC_Final(CRYPT_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + if (ctx == NULL || ctx->method == NULL || out == NULL || len == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + const EAL_MdMethod *method = ctx->method; + if (*len < method->mdSize) { + BSL_ERR_PUSH_ERROR(CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH; + } + *len = method->mdSize; + uint8_t tmp[HMAC_MAXOUTSIZE]; + uint32_t tmpLen = sizeof(tmp); + int32_t ret; + GOTO_ERR_IF(method->final(ctx->mdCtx, tmp, &tmpLen), ret); + GOTO_ERR_IF(method->copyCtx(ctx->mdCtx, ctx->oCtx), ret); + GOTO_ERR_IF(method->update(ctx->mdCtx, tmp, tmpLen), ret); + return method->final(ctx->mdCtx, out, len); +ERR: + return ret; +} + +void CRYPT_HMAC_Reinit(CRYPT_HMAC_Ctx *ctx) +{ + if (ctx == NULL || ctx->method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + const EAL_MdMethod *method = ctx->method; + method->copyCtx(ctx->mdCtx, ctx->iCtx); +} + +void CRYPT_HMAC_Deinit(CRYPT_HMAC_Ctx *ctx) +{ + if (ctx == NULL || ctx->method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + const EAL_MdMethod *method = ctx->method; + method->deinit(ctx->mdCtx); + method->deinit(ctx->iCtx); + method->deinit(ctx->oCtx); +} +#endif // HITLS_CRYPTO_HMAC diff --git a/crypto/include/crypt_local_types.h b/crypto/include/crypt_local_types.h new file mode 100644 index 00000000..a7ffb941 --- /dev/null +++ b/crypto/include/crypt_local_types.h @@ -0,0 +1,256 @@ +/* + * 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_LOCAL_TYPES_H +#define CRYPT_LOCAL_TYPES_H + +#include +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_method.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/* Prototype of the MD algorithm operation functions */ +typedef int32_t (*MdInit)(void *data); +typedef int32_t (*MdUpdate)(void *data, const uint8_t *input, uint32_t len); +typedef int32_t (*MdFinal)(void *data, uint8_t *out, uint32_t *len); +typedef void (*MdDeinit)(void *data); +typedef int32_t (*MdCopyCtx)(void *dst, void *src); + +typedef struct { + uint16_t blockSize; // Block size processed by the hash algorithm at a time, which is used with other algorithms. + uint16_t mdSize; // Output length of the HASH algorithm + uint16_t ctxSize; // Context size of the HASH. + MdInit init; // Initialize the MD context. + MdUpdate update; // Add block data for MD calculation. + MdFinal final; // Complete the MD calculation and obtain the MD result. + MdDeinit deinit; // Clear the key information of the MD context. + MdCopyCtx copyCtx; // Copy the MD context. +} EAL_MdMethod; + +typedef struct { + uint32_t id; + EAL_MdMethod *mdMeth; +} EAL_CidToMdMeth; + +/* provide asymmetric primitive method */ +typedef void *(*PkeyNew)(void); +typedef void *(*PkeyDup)(void *key); +typedef void (*PkeyFree)(void *key); +typedef void *(*PkeyNewParaById)(int32_t id); +typedef CRYPT_PKEY_ParaId (*PkeyGetParaId)(const void *key); +typedef void (*PkeyFreePara)(void *para); +typedef int32_t (*PkeySetPara)(void *key, const void *para); +typedef int32_t (*PkeyGetPara)(const void *key, void *para); +typedef int32_t (*PkeyGen)(void *key); +typedef uint32_t (*PkeyBits)(void *key); +typedef uint32_t (*PkeyGetSignLen)(void *key); +typedef int32_t (*PkeyCtrl)(void *key, CRYPT_PkeyCtrl opt, void *val, uint32_t len); +typedef int32_t (*PkeySetPrv)(void *key, const void *prv); +typedef int32_t (*PkeySetPub)(void *key, const void *pub); +typedef int32_t (*PkeyGetPrv)(const void *key, void *prv); +typedef int32_t (*PkeyGetPub)(const void *key, void *pub); +typedef void *(*PkeyNewPara)(const void *para); +typedef int32_t (*PkeySign)(const void *key, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen); +typedef int32_t (*PkeyVerify)(const void *key, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen); +typedef int32_t (*PkeyComputeShareKey)(const void *key, const void *pub, + uint8_t *share, uint32_t *shareLen); +typedef int32_t (*PkeyCrypt)(const void *key, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen); +typedef int32_t (*PkeyCheck)(const void *key); +typedef int32_t (*PkeyCmp)(const void *key1, const void *key2); +typedef int32_t (*PkeyGetSecBits)(const void *key); + +/** +* @ingroup EAL +* +* Method structure of the EAL +*/ +typedef struct EAL_PkeyMethod { + uint32_t id; + PkeyNew newCtx; // Apply for a key pair structure resource. + PkeyDup dupCtx; // Copy key pair structure resource. + PkeyFree freeCtx; // Free the key structure. + PkeySetPara setPara; // Set parameters of the key pair structure. + PkeyGetPara getPara; // Obtain parameters from the key pair structure. + PkeyGen gen; // Generate a key pair. + PkeyBits bits; // Obtain the key length. + PkeyGetSignLen signLen; // Obtain the signature data length. + PkeyCtrl ctrl; // Control function. + PkeyNewParaById newParaById; // Generate parameters by parameter ID. + PkeyGetParaId getParaId; // Obtain the parameter ID. + PkeyFreePara freePara; // Free key parameters. + PkeyNewPara newPara; // Generate key parameters. + PkeySetPub setPub; // Set the public key. + PkeySetPrv setPrv; // Set the private key. + PkeyGetPub getPub; // Obtain the public key. + PkeyGetPrv getPrv; // Obtain the private key. + PkeySign sign; // Sign the signature. + PkeyVerify verify; // Verify the signature. + PkeyComputeShareKey computeShareKey; // Calculate the shared key. + PkeyCrypt encrypt; // Encrypt. + PkeyCrypt decrypt; // Decrypt. + PkeyCheck check; // Check the consistency of the key pair. + PkeyCmp cmp; // Compare keys and parameters. + PkeyGetSecBits getSecBits; // get key security bits +} EAL_PkeyMethod; + +/** + * @ingroup sym_algid + * Symmetric encryption/decryption algorithm ID + */ +typedef enum { + CRYPT_SYM_AES128 = 0, + CRYPT_SYM_AES192, + CRYPT_SYM_AES256, + CRYPT_SYM_CHACHA20, + CRYPT_SYM_SM4, + CRYPT_SYM_MAX +} CRYPT_SYM_AlgId; + +typedef struct EAL_CipherMethod { + /** + * @ingroup crypt_type + * @brief Initialize the handle and register other modules. + * @return 0 indicates success, and other values indicate failure. + */ + int32_t (*initCtx)(void *ctx, const struct EAL_CipherMethod *m); + /** + * @ingroup crypt_type + * @brief Deinitialize the handle, return to the state after init is called, including releasing memory. + * @return void + */ + void (*deinitCtx)(void *ctx); + /** + * @ingroup crypt_type + * @brief Clear the key and sensitive information, but do not release the memory, return to the state after initCtx. + * @return void + */ + void (*clean)(void *ctx); + /** + * @ingroup crypt_type + * @brief Set the encryption key and key length. + * @return 0 indicates success, and other values indicate failure. + */ + int32_t (*setEncryptKey)(void *ctx, const uint8_t *key, uint32_t len); + /** + * @ingroup crypt_type + * @brief Set the decryption key and key length. + * @return 0 indicates success, and other values indicate failure. + */ + int32_t (*setDecryptKey)(void *ctx, const uint8_t *key, uint32_t len); + /** + * @ingroup crypt_type + * @brief Encrypt the input data. The lengths of the encrypted and decrypted data are the same. + * @return 0 indicates success, and other values indicate failure. + */ + int32_t (*encrypt)(void *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + /** + * @ingroup crypt_type + * @brief Decrypt the input data. The lengths of the encrypted and decrypted data are the same. + * @return 0 indicates success, and other values indicate failure. + */ + int32_t (*decrypt)(void *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + /** + * @ingroup crypt_type + * @brief Set parameters for the CTX. + * @return 0 indicates success, and other values indicate failure. + */ + int32_t (*ctrl)(void *ctx, uint32_t opt, void *val, uint32_t len); + + uint8_t blockSize; /**< block size in bytes */ + uint16_t ctxSize; /**< ctx size. The maximum size is 65535 bytes. */ + CRYPT_SYM_AlgId algId; /**< algorithm ID */ +} EAL_CipherMethod; + +/* prototype of MAC algorithm operation functions */ +// Initialize the memory and set the method. +typedef int32_t (*MacInitCtx)(void *ctx, const void *method); +// Complete key initialization. +typedef int32_t (*MacInit)(void *ctx, const uint8_t *key, uint32_t len); +typedef int32_t (*MacUpdate)(void *ctx, const uint8_t *in, uint32_t len); +typedef int32_t (*MacFinal)(void *ctx, const uint8_t *out, uint32_t *len); +typedef void (*MacDeinit)(void *ctx); +// The action is opposite to the initCtx. Sensitive data is deleted. +typedef void (*MacDeinitCtx)(void *ctx); +typedef void (*MacReinit)(void *ctx); +typedef uint32_t (*MacGetMacLen)(void *ctx); + +/* set of MAC algorithm operation methods */ +typedef struct { + MacInitCtx initCtx; // Allocate memory, initializing, and setting the method + MacInit init; // Initialize the MAC context. + MacUpdate update; // Add block data for MAC calculation. + MacFinal final; // Complete MAC calculation and obtain the MAC result. + MacDeinit deinit; // Clear the key information in MAC context. + MacDeinitCtx deinitCtx; // Delete sensitive data and free memory + // Re-initialize the key. This method is used where the keys are the same during multiple MAC calculations. + MacReinit reinit; + MacGetMacLen getLen; // Obtain the data length of the MAC calculation result. + uint16_t ctxSize; // Context size of the MAC algorithm +} EAL_MacMethod; + +typedef struct { + union { + const EAL_MacMethod *macMethod; + const EAL_CipherMethod *modeMethod; // Method of gmac-dependent symmetric algorithms + const void *masMeth; // Method pointer of the master algorithm. + }; + union { + const EAL_MdMethod *md; // MD algorithm which HMAC depends on + const void *depMeth; // Pointer to the dependent algorithm, which is reserved for extension. + }; +} EAL_MacMethLookup; + +/** + * @ingroup mode_algid + * Symmetric encryption/decryption mode ID + */ +typedef enum { + CRYPT_MODE_CBC = 0, + CRYPT_MODE_CTR, + CRYPT_MODE_ECB, + CRYPT_MODE_XTS, + CRYPT_MODE_CCM, + CRYPT_MODE_GCM, + CRYPT_MODE_CHACHA20_POLY1305, + CRYPT_MODE_CFB, + CRYPT_MODE_OFB, + CRYPT_MODE_MAX +} CRYPT_MODE_AlgId; + +/** + * @ingroup crypt_eal_pkey + * + * Structure of the PSS padding mode when RSA is used for signature + */ +typedef struct { + int32_t saltLen; /**< pss salt length. -1 indicates hashLen, -2 indicates MaxLen, -3 is AutoLen */ + const EAL_MdMethod *mdMeth; /**< pss mdid method when padding */ + const EAL_MdMethod *mgfMeth; /**< pss mgfid method when padding */ + CRYPT_MD_AlgId mdId; /**< pss mdid when padding */ + CRYPT_MD_AlgId mgfId; /**< pss mgfid when padding */ +} RSA_PadingPara; + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // EAL_LOCAL_TYPES_H diff --git a/crypto/include/crypt_util_rand.h b/crypto/include/crypt_util_rand.h new file mode 100644 index 00000000..a0022fd6 --- /dev/null +++ b/crypto/include/crypt_util_rand.h @@ -0,0 +1,56 @@ +/* + * 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_UTIL_RAND_H +#define CRYPT_UTIL_RAND_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_DRBG) || defined(HITLS_CRYPTO_CURVE25519) || \ + defined(HITLS_CRYPTO_RSA) || defined(HITLS_CRYPTO_BN) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int32_t (*CRYPT_RandFunc)(uint8_t *rand, uint32_t randLen); + +/** + * @brief Random number registration + * + * @param func [IN] Interface for obtaining random numbers + */ +void CRYPT_RandRegist(CRYPT_RandFunc func); + +/** + * @brief Generate a random number + * + * @param rand [OUT] buffer of random number + * @param randLen [IN] length of random number + * + * @retval CRYPT_SUCCESS A random number is generated successfully. + * @retval CRYPT_NO_REGIST_RAND The random number function is not registered. + * @retval Error returned when the registered random number fails during the generate. + */ +int32_t CRYPT_Rand(uint8_t *rand, uint32_t randLen); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/crypto/include/crypt_utils.h b/crypto/include/crypt_utils.h new file mode 100644 index 00000000..46fdf182 --- /dev/null +++ b/crypto/include/crypt_utils.h @@ -0,0 +1,423 @@ +/* + * 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_UTILS_H +#define CRYPT_UTILS_H + +#include +#include +#include "crypt_algid.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define BITS_PER_BYTE 8 +#define SHIFTS_PER_BYTE 3 +#define BITSIZE(t) (sizeof(t) * BITS_PER_BYTE) + +#define PUT_UINT32_BE(v, p, i) \ +do { \ + (p)[(i) + 0] = (uint8_t)((v) >> 24); \ + (p)[(i) + 1] = (uint8_t)((v) >> 16); \ + (p)[(i) + 2] = (uint8_t)((v) >> 8); \ + (p)[(i) + 3] = (uint8_t)((v) >> 0); \ +} while (0) + +#define GET_UINT32_BE(p, i) \ +( \ + ((uint32_t)(p)[(i) + 0] << 24) | \ + ((uint32_t)(p)[(i) + 1] << 16) | \ + ((uint32_t)(p)[(i) + 2] << 8) | \ + ((uint32_t)(p)[(i) + 3] << 0) \ +) + +#define PUT_UINT32_LE(v, p, i) \ +do { \ + (p)[(i) + 3] = (uint8_t)((v) >> 24); \ + (p)[(i) + 2] = (uint8_t)((v) >> 16); \ + (p)[(i) + 1] = (uint8_t)((v) >> 8); \ + (p)[(i) + 0] = (uint8_t)((v) >> 0); \ +} while (0) + +#define PUT_UINT64_LE(v, p, i) do { \ + (p)[(i) + 7] = (uint8_t)((v) >> 56); \ + (p)[(i) + 6] = (uint8_t)((v) >> 48); \ + (p)[(i) + 5] = (uint8_t)((v) >> 40); \ + (p)[(i) + 4] = (uint8_t)((v) >> 32); \ + (p)[(i) + 3] = (uint8_t)((v) >> 24); \ + (p)[(i) + 2] = (uint8_t)((v) >> 16); \ + (p)[(i) + 1] = (uint8_t)((v) >> 8); \ + (p)[(i) + 0] = (uint8_t)((v) >> 0); \ +} while (0) + +#define GET_UINT64_LE(p, i) \ +( \ + ((uint64_t)(p)[(i) + 7] << 56) | ((uint64_t)(p)[(i) + 6] << 48) | \ + ((uint64_t)(p)[(i) + 5] << 40) | ((uint64_t)(p)[(i) + 4] << 32) | \ + ((uint64_t)(p)[(i) + 3] << 24) | ((uint64_t)(p)[(i) + 2] << 16) | \ + ((uint64_t)(p)[(i) + 1] << 8) | ((uint64_t)(p)[(i) + 0] << 0) \ +) + +/** + * Check whether conditions are met. If yes, an error code is returned. + */ +#define RETURN_RET_IF(condition, ret) \ + do { \ + if (condition) { \ + BSL_ERR_PUSH_ERROR(ret); \ + return ret; \ + } \ + } while (0) + +/** + * If the return value of func is not CRYPT_SUCCESS, go to the label ERR. + */ +#define GOTO_ERR_IF(func, ret) do { \ + (ret) = (func); \ + if ((ret) != CRYPT_SUCCESS) { \ + BSL_ERR_PUSH_ERROR((ret)); \ + goto ERR; \ + } \ + } while (0) + +#define GOTO_ERR_IF_EX(func, ret) do { \ + (ret) = (func); \ + if ((ret) != CRYPT_SUCCESS) { \ + goto ERR; \ + } \ + } while (0) + +/** + * Check whether conditions are met. If conditions are met, go to the label EXIT. + */ +#define GOTO_EXIT_IF(condition, ret) \ + do { \ + if (condition) { \ + BSL_ERR_PUSH_ERROR((ret)); \ + goto EXIT; \ + } \ + } while (0) + +#define GOTO_EXIT_IF_EX(condition, ret) \ + do { \ + if (condition) { \ + goto EXIT; \ + } \ + } while (0) + +#define BREAK_IF(condition) \ + do { \ + if (condition) { \ + break; \ + } \ + } while (0) + +/** + * If src is not NULL, then execute the fun function. If the operation fails, go to the label ERR. + */ +#define GOTO_ERR_IF_SRC_NOT_NULL(dest, src, func, ret) \ + do { \ + if ((src) != NULL) { \ + (dest) = (func); \ + if ((dest) == NULL) { \ + BSL_ERR_PUSH_ERROR((ret)); \ + goto ERR; \ + } \ + } \ + } while (0) + +/** + * @brief Perform the XOR operation on the data of two arrays. + * + * @param a [IN] Input data a + * @param b [IN] Input data b + * @param r [out] Output the result data. + * @param len [IN] Output result data length + */ +#define DATA_XOR(a, b, r, len) \ + do { \ + uint32_t subscript; \ + for (subscript = 0; subscript < (len); subscript++) { \ + (r)[subscript] = (a)[subscript] ^ (b)[subscript]; \ + } \ + } while (0) + +/** + * @brief Perform the XOR operation on the data of 32 bits in two arrays each time. + * Ensure that the input and output are integer multiples of 32 bits. + * Type conversion is performed only when the address is 4-byte aligned. + * + * @param a [IN] Input data a + * @param b [IN] Input data b + * @param r [out] Output the result data. + * @param len [IN] Output result data length + */ +#define DATA32_XOR(a, b, r, len) \ + do { \ + uint32_t ii; \ + uintptr_t aPtr = (uintptr_t)(a); \ + uintptr_t bPtr = (uintptr_t)(b); \ + uintptr_t rPtr = (uintptr_t)(r); \ + if (((aPtr & 0x3) != 0) || ((bPtr & 0x3) != 0) || ((rPtr & 0x3) != 0)) { \ + for (ii = 0; ii < (len); ii++) { \ + (r)[ii] = (a)[ii] ^ (b)[ii]; \ + } \ + } else { \ + for (ii = 0; ii < (len); ii += 4) { \ + *(uint32_t *)((r) + ii) = (*(const uint32_t *)((a) + ii)) ^ (*(const uint32_t *)((b) + ii)); \ + } \ + } \ + } while (0) + +/** + * @brief Perform the XOR operation on 64 bits of data in two arrays each time. + * Ensure that the input and output are integer multiples of 64 bits. + * Type conversion is performed only when the address is 8-byte aligned. + * + * @param a [IN] Input data a + * @param b [IN] Input data b + * @param r [out] Output the result data. + * @param len [IN] Output result data length + */ +#define DATA64_XOR(a, b, r, len) \ + do { \ + uint32_t ii; \ + uintptr_t aPtr = (uintptr_t)(a); \ + uintptr_t bPtr = (uintptr_t)(b); \ + uintptr_t rPtr = (uintptr_t)(r); \ + if (((aPtr & 0x7) != 0) || ((bPtr & 0x7) != 0) || ((rPtr & 0x7) != 0)) { \ + for (ii = 0; ii < (len); ii++) { \ + (r)[ii] = (a)[ii] ^ (b)[ii]; \ + } \ + } else { \ + for (ii = 0; ii < (len); ii += 8) { \ + *(uint64_t *)((r) + ii) = (*(const uint64_t *)((a) + ii)) ^ (*(const uint64_t *)((b) + ii)); \ + } \ + } \ + } while (0) + +/* Assumes that x is uint32_t and 0 < n < 32 */ +#define ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define ROTR64(x, n) (((x) << (64 - (n))) | ((x) >> (n))) // Assumes that x is uint64_t and 0 < n < 64 + +#define IS_BUF_NON_ZERO(out, outLen) (((out) != NULL) && ((outLen) > 0)) +#define CRYPT_IS_BUF_NON_ZERO(out, outLen) (((out) != NULL) && ((outLen) > 0)) +#define CRYPT_CHECK_DATA_INVALID(d) (((d)->data == NULL && (d)->len != 0)) +#define CRYPT_IsDataNull(d) ((d) == NULL || (d)->data == NULL || (d)->len == 0) +#define CRYPT_IN_RANGE(x, range) ((x) >= (range)->min && (x) <= (range)->max) +#define CRYPT_CHECK_BUF_INVALID(buf, len) (((buf) == NULL && (len) != 0)) +#define CRYPT_SWAP32(x) ((((x) & 0xff000000) >> 24) | \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x000000ff) << 24)) +#ifdef HITLS_BIG_ENDIAN + +#define CRYPT_HTONL(x) (x) + +// Interpret p + i as little endian order. The type of p must be uint8_t *. +#define GET_UINT32_LE(p, i) \ +( \ + ((uint32_t)((const uint8_t *)(p))[(i) + 3] << 24) | \ + ((uint32_t)((const uint8_t *)(p))[(i) + 2] << 16) | \ + ((uint32_t)((const uint8_t *)(p))[(i) + 1] << 8) | \ + ((uint32_t)((const uint8_t *)(p))[(i) + 0] << 0) \ +) + +// Convert little-endian order to host order +#define CRYPT_LE32TOH(x) CRYPT_SWAP32(x) +// Convert host order to little-endian order +#define CRYPT_HTOLE32(x) CRYPT_SWAP32(x) + +#else + +#define CRYPT_HTONL(x) CRYPT_SWAP32(x) + +// Interpret p + i as little endian. +#define GET_UINT32_LE(p, i) \ +( \ + (((uintptr_t)(p) & 0x7) != 0) ? ((uint32_t)((const uint8_t *)(p))[(i) + 3] << 24) | \ + ((uint32_t)((const uint8_t *)(p))[(i) + 2] << 16) | \ + ((uint32_t)((const uint8_t *)(p))[(i) + 1] << 8) | \ + ((uint32_t)((const uint8_t *)(p))[(i) + 0] << 0) \ + : (*(uint32_t *)((uint8_t *)(uintptr_t)(p) + (i))) \ +) +// Convert little-endian order to host order +#define CRYPT_LE32TOH(x) (x) +// Convert host order to little-endian order +#define CRYPT_HTOLE32(x) (x) + +#endif + +#ifdef HITLS_BIG_ENDIAN + +// Interpret p + i as little endian. The type of p must be uint8_t *. +#define GET_UINT16_LE(p, i) \ +( \ + ((uint16_t)((const uint8_t *)(p))[(i) + 1] << 8) | \ + ((uint16_t)((const uint8_t *)(p))[(i) + 0] << 0) \ +) +#else +// Interpret p + i as little endian. +#define GET_UINT16_LE(p, i) \ +( \ + (((uintptr_t)(p) & 0x7) != 0) ? ((uint16_t)((const uint8_t *)(p))[(i) + 1] << 8) | \ + ((uint16_t)((const uint8_t *)(p))[(i) + 0] << 0) \ + : (*(uint16_t *)((uint8_t *)(uintptr_t)(p) + (i))) \ +) +#endif + +#define PUT_UINT16_LE(v, p, i) \ + do \ + { \ + (p)[(i) + 1] = (uint8_t)((v) >> 8); \ + (p)[(i) + 0] = (uint8_t)((v) >> 0); \ + } while (0) + +/** + * 64-bit integer manipulation functions (big endian) + */ +static inline uint64_t Uint64FromBeBytes(const uint8_t *bytes) +{ + return (((uint64_t)bytes[0] << 56) | + ((uint64_t)bytes[1] << 48) | + ((uint64_t)bytes[2] << 40) | + ((uint64_t)bytes[3] << 32) | + ((uint64_t)bytes[4] << 24) | + ((uint64_t)bytes[5] << 16) | + ((uint64_t)bytes[6] << 8) | + (uint64_t)bytes[7]); +} + +static inline void Uint64ToBeBytes(uint64_t v, uint8_t *bytes) +{ + bytes[0] = (uint8_t)(v >> 56); + bytes[1] = (uint8_t)(v >> 48); + bytes[2] = (uint8_t)(v >> 40); + bytes[3] = (uint8_t)(v >> 32); + bytes[4] = (uint8_t)(v >> 24); + bytes[5] = (uint8_t)(v >> 16); + bytes[6] = (uint8_t)(v >> 8); + bytes[7] = (uint8_t)(v & 0xffu); +} + +#ifdef HITLS_CRYPTO_RSA +uint32_t CRYPT_MD_GetSizeById(CRYPT_MD_AlgId id); +#endif + +static inline bool ParamIdIsValid(uint32_t id, const uint32_t *list, uint32_t num) +{ + for (uint32_t i = 0; i < num; i++) { + if (id == list[i]) { + return true; + } + } + return false; +} + +static inline uint32_t Uint32ConstTimeMsb(uint32_t a) +{ + // 31 == (4 * 8 - 1) + return 0u - (a >> 31); +} + +static inline uint32_t Uint32ConstTimeIsZero(uint32_t a) +{ + return Uint32ConstTimeMsb(~a & (a - 1)); +} + +static inline uint32_t Uint32ConstTimeEqual(uint32_t a, uint32_t b) +{ + return Uint32ConstTimeIsZero(a ^ b); +} +// (mask & a) | (~mask & b) +static inline uint32_t Uint32ConstTimeSelect(uint32_t mask, uint32_t a, uint32_t b) +{ + return ((mask) & a) | ((~mask) & b); +} + +static inline uint32_t Uint32ConstTimeLt(uint32_t a, uint32_t b) +{ + return Uint32ConstTimeMsb(a ^ ((a ^ b) | ((a - b) ^ a))); +} + +static inline uint32_t Uint32ConstTimeGt(uint32_t a, uint32_t b) +{ + return ~Uint32ConstTimeLt(a, b); +} + +void GetCpuInstrSupportState(void); + +#ifdef __x86_64__ +#define CPU_ID_OUT_U32_CNT 4 +#define EAX_OUT_IDX 0 +#define EBX_OUT_IDX 1 +#define ECX_OUT_IDX 2 +#define EDX_OUT_IDX 3 + +/* %eax */ +#define XCR0_BIT_SSE (1ULL << 1) +#define XCR0_BIT_AVX (1ULL << 2) +#define XCR0_BIT_OPMASK (1ULL << 5) +#define XCR0_BIT_ZMM_LOW (1ULL << 6) +#define XCR0_BIT_ZMM_HIGH (1ULL << 7) + +typedef struct { + uint32_t code1Out[CPU_ID_OUT_U32_CNT]; + uint32_t code7Out[CPU_ID_OUT_U32_CNT]; + bool osSupportAVX; /* input ecx = 0, output edx:eax bit 2 */ + bool osSupportAVX512; /* input ecx = 0, output edx:eax bit 6 */ +} CpuInstrSupportState; + +bool IsSupportAES(void); +bool IsSupportBMI1(void); +bool IsSupportBMI2(void); +bool IsSupportAVX(void); +bool IsSupportAVX2(void); +bool IsSupportSSE(void); +bool IsSupportSSE2(void); +bool IsSupportSSE3(void); +bool IsSupportMOVBE(void); +bool IsSupportAVX512F(void); +bool IsSupportAVX512VL(void); +bool IsSupportAVX512BW(void); +bool IsSupportAVX512DQ(void); +bool IsSupportXSAVE(void); +bool IsSupportOSXSAVE(void); +bool IsOSSupportAVX(void); +bool IsOSSupportAVX512(void); + +void GetCpuId(uint32_t eax, uint32_t ecx, uint32_t cpuId[CPU_ID_OUT_U32_CNT]); + +#elif defined(__arm__) || defined(__arm) || defined(__aarch64__) + +bool IsSupportAES(void); +bool IsSupportPMULL(void); +bool IsSupportSHA1(void); +bool IsSupportSHA256(void); +bool IsSupportNEON(void); + +#if defined(__aarch64__) +bool IsSupportSHA512(void); +#endif // __aarch64__ + +#endif // __arm__ || __arm || __aarch64__ + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_UTILS_H diff --git a/crypto/kdf/include/crypt_kdf_tls12.h b/crypto/kdf/include/crypt_kdf_tls12.h new file mode 100644 index 00000000..f9ad1d59 --- /dev/null +++ b/crypto/kdf/include/crypt_kdf_tls12.h @@ -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 CRYPT_KDF_TLS12_H +#define CRYPT_KDF_TLS12_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_KDFTLS12 + +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief KDF-TLS1.2 + * + * @param macMeth [IN] Pointer to the HMAC algorithm method + * @param mdMeth [IN] Pointer to the MD algorithm method + * @param key [IN] Key, byte array entered by the user. + * @param keyLen [IN] Key length, any length + * @param label [IN] Label, byte array entered by the user. Combined with the seed as the PRF input data. + * @param labelLen [IN] Label length, any length + * @param seed [IN] Seed, byte array entered by a user, used as the PRF input data. + * @param seedLen [IN] Seed length, any length + * @param out [OUT] Derive key. + * @param outLen [IN] Length of the derived key. The value range is [1, 0xFFFFFFFF]. + * + * @return If the operation is successful, the CRYPT_SUCCESS is returned. + * For other error codes, see the crypt_errno.h. + */ +int32_t CRYPT_KDF_TLS12(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen, + const uint8_t *label, uint32_t labelLen, const uint8_t *seed, uint32_t seedLen, uint8_t *out, uint32_t len); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_KDFTLS12 + +#endif // CRYPT_KDF_TLS12_H diff --git a/crypto/kdf/src/kdf_tls12.c b/crypto/kdf/src/kdf_tls12.c new file mode 100644 index 00000000..f47e3af2 --- /dev/null +++ b/crypto/kdf/src/kdf_tls12.c @@ -0,0 +1,140 @@ +/* + * 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_KDFTLS12 + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_local_types.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_kdf_tls12.h" + +#define KDFTLS12_MAX_BLOCKSIZE 64 + +typedef struct { + const EAL_MacMethod *macMeth; + const EAL_MdMethod *mdMeth; + const uint8_t *key; + uint32_t keyLen; + const uint8_t *label; + uint32_t labelLen; + const uint8_t *seed; + uint32_t seedLen; +} CRYPT_KDF_Info; + +int32_t KDF_Hmac(const EAL_MacMethod *macMeth, void *macCtx, uint8_t *data, uint32_t *len) +{ + int32_t ret; + macMeth->reinit(macCtx); + ret = macMeth->update(macCtx, data, *len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = macMeth->final(macCtx, data, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + return CRYPT_SUCCESS; +} + +// algorithm implementation see https://datatracker.ietf.org/doc/pdf/rfc5246.pdf, chapter 5, p_hash function +int32_t KDF_PHASH(const CRYPT_KDF_Info *kdfInfo, uint8_t *out, uint32_t len) +{ + int32_t ret; + const EAL_MacMethod *macMeth = kdfInfo->macMeth; + const EAL_MdMethod *mdMeth = kdfInfo->mdMeth; + uint32_t totalLen = 0; + uint8_t nextIn[KDFTLS12_MAX_BLOCKSIZE]; + uint32_t nextInLen = KDFTLS12_MAX_BLOCKSIZE; + uint8_t outTmp[KDFTLS12_MAX_BLOCKSIZE]; + uint32_t outTmpLen = KDFTLS12_MAX_BLOCKSIZE; + + void *macCtx = BSL_SAL_Malloc(macMeth->ctxSize); + if (macCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)memset_s(macCtx, macMeth->ctxSize, 0, macMeth->ctxSize); + GOTO_ERR_IF(macMeth->initCtx(macCtx, mdMeth), ret); + + while (len > totalLen) { + if (totalLen == 0) { + GOTO_ERR_IF(macMeth->init(macCtx, kdfInfo->key, kdfInfo->keyLen), ret); + GOTO_ERR_IF(macMeth->update(macCtx, kdfInfo->label, kdfInfo->labelLen), ret); + GOTO_ERR_IF(macMeth->update(macCtx, kdfInfo->seed, kdfInfo->seedLen), ret); + GOTO_ERR_IF(macMeth->final(macCtx, nextIn, &nextInLen), ret); + } else { + GOTO_ERR_IF(KDF_Hmac(macMeth, macCtx, nextIn, &nextInLen), ret); + } + + macMeth->reinit(macCtx); + GOTO_ERR_IF(macMeth->update(macCtx, nextIn, nextInLen), ret); + GOTO_ERR_IF(macMeth->update(macCtx, kdfInfo->label, kdfInfo->labelLen), ret); + GOTO_ERR_IF(macMeth->update(macCtx, kdfInfo->seed, kdfInfo->seedLen), ret); + GOTO_ERR_IF(macMeth->final(macCtx, outTmp, &outTmpLen), ret); + + uint32_t cpyLen = outTmpLen > (len - totalLen) ? (len - totalLen) : outTmpLen; + (void)memcpy_s(out + totalLen, len - totalLen, outTmp, cpyLen); + totalLen += cpyLen; + } + +ERR: + macMeth->deinit(macCtx); + macMeth->deinitCtx(macCtx); + BSL_SAL_FREE(macCtx); + return ret; +} + +int32_t CRYPT_KDF_TLS12(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen, + const uint8_t *label, uint32_t labelLen, const uint8_t *seed, uint32_t seedLen, uint8_t *out, uint32_t len) +{ + if (macMeth == NULL || mdMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (key == NULL && keyLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (label == NULL && labelLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (seed == NULL && seedLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((out == NULL) || (len == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + CRYPT_KDF_Info kdfInfo; + kdfInfo.macMeth = macMeth; + kdfInfo.mdMeth = mdMeth; + kdfInfo.key = key; + kdfInfo.keyLen = keyLen; + kdfInfo.label = label; + kdfInfo.labelLen = labelLen; + kdfInfo.seed = seed; + kdfInfo.seedLen = seedLen; + + return KDF_PHASH(&kdfInfo, out, len); +} +#endif // HITLS_CRYPTO_KDFTLS12 diff --git a/crypto/md5/include/crypt_md5.h b/crypto/md5/include/crypt_md5.h new file mode 100644 index 00000000..20a9ae35 --- /dev/null +++ b/crypto/md5/include/crypt_md5.h @@ -0,0 +1,101 @@ +/* + * 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_MD5_H +#define CRYPT_MD5_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_MD5 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CRYPT_MD5_DIGESTSIZE 16 +#define CRYPT_MD5_BLOCKSIZE 64 + +/* md5 ctx */ +typedef struct { + uint32_t h[CRYPT_MD5_DIGESTSIZE / sizeof(uint32_t)]; /* store the intermediate data of the hash value */ + uint8_t block[CRYPT_MD5_BLOCKSIZE]; /* store the remaining data of less than one block */ + uint32_t hNum, lNum; /* input data counter, maximum value 2 ^ 64 bits */ + /* Number of remaining bytes in 'block' arrary that are stored less than one block */ + uint32_t num; +} CRYPT_MD5_Ctx; + +/** + * @ingroup MD5 + * @brief This API is used to initialize the MD5 context. + * + * @param ctx [in,out] Pointer to the MD5 context. + * + * @retval #CRYPT_SUCCESS Initialization succeeded. + * @retval #CRYPT_NULL_INPUT Pointer ctx is NULL + */ +int32_t CRYPT_MD5_Init(CRYPT_MD5_Ctx *ctx); + +/** + * @ingroup MD5 + * @brief MD5 deinitialization API + * @param ctx [in,out] Pointer to the MD5 context. + */ +void CRYPT_MD5_Deinit(CRYPT_MD5_Ctx *ctx); + +/** + * @ingroup MD5 + * @brief Encode the input text and update the message digest. + * + * @param ctx [in,out] Pointer to the MD5 context. + * @param in [in] Pointer to the data to be calculated + * @param len [in] Length of the data to be calculated + * + * @retval #CRYPT_SUCCESS Succeeded in updating the internal status of the digest. + * @retval #CRYPT_NULL_INPUT The input parameter is NULL. + * @retval #CRYPT_MD5_INPUT_OVERFLOW The accumulated length of the input data exceeds the maximum (2^64 bits). + */ +int32_t CRYPT_MD5_Update(CRYPT_MD5_Ctx *ctx, const uint8_t *in, uint32_t len); + +/** + * @ingroup MD5 + * @brief Obtain the message digest based on the passed MD5 context. + * + * @param ctx [in,out] Pointer to the MD5 context. + * @param out [in] Digest buffer + * @param outLen [in,out] Digest buffer size + * + * @retval #CRYPT_SUCCESS succeeded in updating the internal status of the digest. + * @retval #CRYPT_NULL_INPUT The input parameter is NULL. + * @retval #CRYPT_MD5_OUT_BUFF_LEN_NOT_ENOUGH The output buffer length is insufficient. + */ +int32_t CRYPT_MD5_Final(CRYPT_MD5_Ctx *ctx, uint8_t *out, uint32_t *outLen); + +/** + * @ingroup MD5 + * @brief MD5 copy CTX function + * @param dst [out] Pointer to the new MD5 context. + * @param src [in] Pointer to the original MD5 context. + */ +int32_t CRYPT_MD5_CopyCtx(CRYPT_MD5_Ctx *dst, const CRYPT_MD5_Ctx *src); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_MD5 + +#endif // CRYPT_MD5_H diff --git a/crypto/md5/src/asm/md5_x86_64.S b/crypto/md5/src/asm/md5_x86_64.S new file mode 100644 index 00000000..5d9b274e --- /dev/null +++ b/crypto/md5/src/asm/md5_x86_64.S @@ -0,0 +1,393 @@ +/* + * 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_MD5 + +.file "md5_x86_64.S" + +.set TEMP1, %r14d +.set TEMP2, %r15d + +.set T, %r13d +.set W, %r12d + +.set T_ORIGIN_ADDR, %rcx +.set HASH, %rdi +.set INPUT, %rsi +.set NUM, %rdx + +.set S11, 7 +.set S12, 12 +.set S13, 17 +.set S14, 22 +.set S21, 5 +.set S22, 9 +.set S23, 14 +.set S24, 20 +.set S31, 4 +.set S32, 11 +.set S33, 16 +.set S34, 23 +.set S41, 6 +.set S42, 10 +.set S43, 15 +.set S44, 21 + +.set A, %r8d +.set B, %r9d +.set C, %r10d +.set D, %r11d + +/* MD5 Used constant value. For details about the data source, see the RFC1321 document. */ + .text + .align 64 + .type g_tMd5, %object +g_tMd5: + .long 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE + .long 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501 + .long 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE + .long 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821 + + .long 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA + .long 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8 + .long 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED + .long 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A + + .long 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C + .long 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70 + .long 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05 + .long 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665 + + .long 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039 + .long 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1 + .long 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1 + .long 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 +.size g_tMd5, .-g_tMd5 + +/* + * Macro description: The FF function processes the update of a hash value in a round of 0-15 compression. + * Input register: + * wAddr: sequence corresponding to W (wi) + * tAddr: order (ti) corresponding to t + * a - d: intermediate variable of the hash value + * Change register: r8d-r15d + * Output register: + * a: indicates the value after a round of cyclic update. + * Function/Macro Call: None + * Implementation description: + * Parameter: S11->28, S12->48, S13->17, S14->22 + * T2 = BSIG0(a) + MAJ(a,b,c) + * a = b + ROTL32(F(a,b,c)+x+ac),s) + * F(X,Y,Z) = XY v not(X) Z + * G(X,Y,Z) = XZ v Y not(Z) + * H(X,Y,Z) = X xor Y xor Z + * I(X,Y,Z) = Y xor (X v not(Z)) + */ +.macro FF_ONE_ROUND a, b, c, d, wAddr, s, tAddr, w, t, temp1, temp2 + mov \tAddr(T_ORIGIN_ADDR), \t + mov \wAddr(INPUT), \w + + /* F(b, c, d) ((b & c) | ((~b) & d)) */ + mov \b, \temp1 + andn \d, \b, \temp2 // (~b) & d + and \c, \temp1 // b & c + or \temp1, \temp2 // (b & c) | ((~b) & d) + + /* (a) += F((b), (c), (d)) + (\w) + (\t) */ + add \w, \a + add \t, \a + add \temp2, \a + + /* (a) = ROTL32((a), (s)) */ + rol $\s, \a + + /* (a) += (b) */ + add \b, \a +.endm + +/* + * Macro description: The GG function updates a round of hash values in rounds 16-31 compression. + * Input register: + * wAddr: sequence corresponding to W (wi) + * tAddr: order (ti) corresponding to t + * a - d: intermediate variable of the hash value + * Change register: r8d-r15d + * Output register: + * a: indicates the value after a round of cyclic update. + * Function/Macro Call: None + * Implementation description: + * For t = 0 to 63, T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + * T2 = BSIG0(a) + MAJ(a,b,c) + * h = g, g = f, f = e, e = d + T1, d = c, c = b, b = a, a = T1 + T2 + * G(x, y, z) (((x) & (z)) | ((y) & (~(z)))) + * (a) += G((b), (c), (d)) + (x) + (ac); + * (a) = ROTL32((a), (s)); + * (a) += (b); + */ +.macro GG_ONE_ROUND a, b, c, d, wAddr, s, tAddr, w, t, temp1, temp2 + mov \tAddr(T_ORIGIN_ADDR), \t + mov \wAddr(INPUT), \w + + /* G(x, y, z) ((b & d) | (c & (~d))) */ + mov \b, \temp1 + and \d, \temp1 + andn \c, \d, \temp2 + or \temp1, \temp2 + + /* (a) += G((b), (c), (d)) + (\w) + (t) */ + add \t, \a + add \w, \a + add \temp2, \a + + /* (a) = ROTL32((a), (s)) */ + rol $\s, \a + + /* (a) += (b) */ + add \b, \a +.endm + +/* + * Macro description: The HH function processes the update of a hash value in a round of 32-47 compression. + * Input register: + * wAddr: sequence corresponding to W (wi) + * tAddr: order (ti) corresponding to t + * a - d: intermediate variable of the hash value + * Change register: r8d-r15d + * Output register: + * a: indicates the value after a round of cyclic update. + * Function/Macro Call: None + * Implementation description: + * + * H(x, y, z) ((x) ^ (y) ^ (z)) + * (a) += H((b), (c), (d)) + (x) + (ac); + * (a) = ROTL32((a), (s)); + * (a) += (b); + * b and c ->next c and d + * swap \temp2 temp4 for next round + */ +.macro HH_ONE_ROUND a, b, c, d, wAddr, s, tAddr, w, t, temp1, temp2 + mov \tAddr(T_ORIGIN_ADDR), \t + mov \wAddr(INPUT), \w + + /* H(x, y, z) (b ^ c ^ d) */ + mov \b, \temp1 + xor \d, \temp1 + xor \c, \temp1 + + /* (a) += H((b), (c), (d)) + (\w) + (\t) */ + add \t, \a + add \w, \a + add \temp1, \a + + /* (a) = ROTL32((a), (s)) */ + rol $\s, \a + + /* (a) += (b) */ + add \b, \a +.endm + +/* + * Macro description: Processes the update of a hash value in a round of 48-63 compression. + * Input register: + * wAddr: Sequence corresponding to W (wi) + * tAddr: Order (ti) corresponding to t + * a - d: Intermediate variable of the hash value + * Change register: r8d-r15d. + * Output register: + * a: indicates the value after a round of cyclic update. + * Function/Macro Call: None + * Implementation description: + * For t = 0 to 63, T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + * T2 = BSIG0(a) + MAJ(a,b,c) + * h = g, g = f, f = e, e = d + T1, d = c, c = b, b = a, a = T1 + T2 + * I(x, y, z) ((y) ^ ((x) | (~(z)))) + * (a) += I((b), (c), (d)) + (x) + (ac); \ + * (a) = ROTL32((a), (s)); \ + * (a) += (b); + * swap \temp2 temp4 for next round + */ +.macro II_ONE_ROUND a, b, c, d, wAddr, s, tAddr, w, t, temp1, temp2 + mov \tAddr(T_ORIGIN_ADDR), \t + mov \wAddr(INPUT), \w + + /* I(b, c, d) (c ^ (b | (~d))) */ + mov \d, \temp1 + not \temp1 + or \b, \temp1 + xor \c, \temp1 + + /* (a) += I((b), (c), (d)) + (\w) + (\t); */ + add \t, \a + add \w, \a + add \temp1, \a + + /* (a) = ROTL32((a), (s)) */ + rol $\s, \a + + /* (a) += (b) */ + add \b, \a +.endm + +/* + * Function description: Performs 64 rounds of compression calculation + * based on the input plaintext data and updates the hash value. + * Function prototype: void MD5_Compress(uint32_t hash[32], const uint8_t *in, uint32_t num); + * Input register: + * rdi: Indicates the storage address of the hash value. + * rsi: Pointer to the input data address (Wi) + * rdx: Indicates the number of 64 rounds of cycles. + * (You need to do several blocks, that is, you need to do several loops.) + * Change register: rsi, r8d-r15d, rcx. + * Output register: None + * Function/Macro Call: FF_ONE_ROUND, GG_ONE_ROUND, HH_ONE_ROUND, II_ONE_ROUND + */ +.text +.globl MD5_Compress +.type MD5_Compress,%function +.align 4 +MD5_Compress: +.cfi_startproc + /* Push stack and pop stack protection */ + pushq %r14 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r15 + + /* r8d-r10d: a-d */ + mov 0(%rdi), A + mov 4(%rdi), B + mov 8(%rdi), C + mov 12(%rdi), D + +.Lmd5_loop: + leaq g_tMd5(%rip), T_ORIGIN_ADDR + + /* LEND_MD5_FF_ROUND_ROUND_0_15 */ + /* FF_ONE_ROUND a, b, c, d, wAddr, s, tAddr, w, t, temp1, temp2 */ + FF_ONE_ROUND A, B, C, D, 0, S11, 0, W, T, TEMP1, TEMP2 + FF_ONE_ROUND D, A, B, C, 4, S12, 4, W, T, TEMP1, TEMP2 + FF_ONE_ROUND C, D, A, B, 8, S13, 8, W, T, TEMP1, TEMP2 + FF_ONE_ROUND B, C, D, A, 12, S14, 12, W, T, TEMP1, TEMP2 + + FF_ONE_ROUND A, B, C, D, 16, S11, 16, W, T, TEMP1, TEMP2 + FF_ONE_ROUND D, A, B, C, 20, S12, 20, W, T, TEMP1, TEMP2 + FF_ONE_ROUND C, D, A, B, 24, S13, 24, W, T, TEMP1, TEMP2 + FF_ONE_ROUND B, C, D, A, 28, S14, 28, W, T, TEMP1, TEMP2 + + FF_ONE_ROUND A, B, C, D, 32, S11, 32, W, T, TEMP1, TEMP2 + FF_ONE_ROUND D, A, B, C, 36, S12, 36, W, T, TEMP1, TEMP2 + FF_ONE_ROUND C, D, A, B, 40, S13, 40, W, T, TEMP1, TEMP2 + FF_ONE_ROUND B, C, D, A, 44, S14, 44, W, T, TEMP1, TEMP2 + + FF_ONE_ROUND A, B, C, D, 48, S11, 48, W, T, TEMP1, TEMP2 + FF_ONE_ROUND D, A, B, C, 52, S12, 52, W, T, TEMP1, TEMP2 + FF_ONE_ROUND C, D, A, B, 56, S13, 56, W, T, TEMP1, TEMP2 + FF_ONE_ROUND B, C, D, A, 60, S14, 60, W, T, TEMP1, TEMP2 + + /* LEND_MD5_GG_ROUND_ROUND_16_31 */ + /* GG_ONE_ROUND a, b, c, d, wAddr, s, tAddr, w, t, temp1, temp2 */ + GG_ONE_ROUND A, B, C, D, 4, S21, 64, W, T, TEMP1, TEMP2 + GG_ONE_ROUND D, A, B, C, 24, S22, 68, W, T, TEMP1, TEMP2 + GG_ONE_ROUND C, D, A, B, 44, S23, 72, W, T, TEMP1, TEMP2 + GG_ONE_ROUND B, C, D, A, 0, S24, 76, W, T, TEMP1, TEMP2 + + GG_ONE_ROUND A, B, C, D, 20, S21, 80, W, T, TEMP1, TEMP2 + GG_ONE_ROUND D, A, B, C, 40, S22, 84, W, T, TEMP1, TEMP2 + GG_ONE_ROUND C, D, A, B, 60, S23, 88, W, T, TEMP1, TEMP2 + GG_ONE_ROUND B, C, D, A, 16, S24, 92, W, T, TEMP1, TEMP2 + + GG_ONE_ROUND A, B, C, D, 36, S21, 96, W, T, TEMP1, TEMP2 + GG_ONE_ROUND D, A, B, C, 56, S22, 100, W, T, TEMP1, TEMP2 + GG_ONE_ROUND C, D, A, B, 12, S23, 104, W, T, TEMP1, TEMP2 + GG_ONE_ROUND B, C, D, A, 32, S24, 108, W, T, TEMP1, TEMP2 + + GG_ONE_ROUND A, B, C, D, 52, S21, 112, W, T, TEMP1, TEMP2 + GG_ONE_ROUND D, A, B, C, 8, S22, 116, W, T, TEMP1, TEMP2 + GG_ONE_ROUND C, D, A, B, 28, S23, 120, W, T, TEMP1, TEMP2 + GG_ONE_ROUND B, C, D, A, 48, S24, 124, W, T, TEMP1, TEMP2 + + /* LEND_MD5_HH_ROUND_ROUND_32_47 */ + /* HH_ONE_ROUND a,b,c,d,wAddr,s,tAddr, w, t, temp1, temp2 */ + HH_ONE_ROUND A, B, C, D, 20, S31, 128, W, T, TEMP1, TEMP2 + HH_ONE_ROUND D, A, B, C, 32, S32, 132, W, T, TEMP1, TEMP2 + HH_ONE_ROUND C, D, A, B, 44, S33, 136, W, T, TEMP1, TEMP2 + HH_ONE_ROUND B, C, D, A, 56, S34, 140, W, T, TEMP1, TEMP2 + + HH_ONE_ROUND A, B, C, D, 4, S31, 144, W, T, TEMP1, TEMP2 + HH_ONE_ROUND D, A, B, C, 16, S32, 148, W, T, TEMP1, TEMP2 + HH_ONE_ROUND C, D, A, B, 28, S33, 152, W, T, TEMP1, TEMP2 + HH_ONE_ROUND B, C, D, A, 40, S34, 156, W, T, TEMP1, TEMP2 + + HH_ONE_ROUND A, B, C, D, 52, S31, 160, W, T, TEMP1, TEMP2 + HH_ONE_ROUND D, A, B, C, 0, S32, 164, W, T, TEMP1, TEMP2 + HH_ONE_ROUND C, D, A, B, 12, S33, 168, W, T, TEMP1, TEMP2 + HH_ONE_ROUND B, C, D, A, 24, S34, 172, W, T, TEMP1, TEMP2 + + HH_ONE_ROUND A, B, C, D, 36, S31, 176, W, T, TEMP1, TEMP2 + HH_ONE_ROUND D, A, B, C, 48, S32, 180, W, T, TEMP1, TEMP2 + HH_ONE_ROUND C, D, A, B, 60, S33, 184, W, T, TEMP1, TEMP2 + HH_ONE_ROUND B, C, D, A, 8, S34, 188, W, T, TEMP1, TEMP2 + + /* LEND_MD5_II_ROUND_ROUND_48_63 */ + /* II_ONE_ROUND a, b,c,d,wAddr,s,tAddr, w, t, temp1, temp2 */ + II_ONE_ROUND A, B, C, D, 0, S41, 192, W, T, TEMP1, TEMP2 + II_ONE_ROUND D, A, B, C, 28, S42, 196, W, T, TEMP1, TEMP2 + II_ONE_ROUND C, D, A, B, 56, S43, 200, W, T, TEMP1, TEMP2 + II_ONE_ROUND B, C, D, A, 20, S44, 204, W, T, TEMP1, TEMP2 + + II_ONE_ROUND A, B, C, D, 48, S41, 208, W, T, TEMP1, TEMP2 + II_ONE_ROUND D, A, B, C, 12, S42, 212, W, T, TEMP1, TEMP2 + II_ONE_ROUND C, D, A, B, 40, S43, 216, W, T, TEMP1, TEMP2 + II_ONE_ROUND B, C, D, A, 4, S44, 220, W, T, TEMP1, TEMP2 + + II_ONE_ROUND A, B, C, D, 32, S41, 224, W, T, TEMP1, TEMP2 + II_ONE_ROUND D, A, B, C, 60, S42, 228, W, T, TEMP1, TEMP2 + II_ONE_ROUND C, D, A, B, 24, S43, 232, W, T, TEMP1, TEMP2 + II_ONE_ROUND B, C, D, A, 52, S44, 236, W, T, TEMP1, TEMP2 + + II_ONE_ROUND A, B, C, D, 16, S41, 240, W, T, TEMP1, TEMP2 + II_ONE_ROUND D, A, B, C, 44, S42, 244, W, T, TEMP1, TEMP2 + II_ONE_ROUND C, D, A, B, 8, S43, 248, W, T, TEMP1, TEMP2 + II_ONE_ROUND B, C, D, A, 36, S44, 252, W, T, TEMP1, TEMP2 + + /* Update the storage hash value. */ + add 0(%rdi), A + add 4(%rdi), B + add 8(%rdi), C + add 12(%rdi), D + mov A, 0(%rdi) + mov B, 4(%rdi) + mov C, 8(%rdi) + mov D, 12(%rdi) + lea 64(INPUT), INPUT + sub $1, NUM + ja .Lmd5_loop + +.LEND_MD5_FINFISH_INITIAL: + /* Registers and pointers are reset. */ + popq %r15 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %r14 + ret +.cfi_endproc + .size MD5_Compress, .-MD5_Compress + +#endif diff --git a/crypto/md5/src/md5.c b/crypto/md5/src/md5.c new file mode 100644 index 00000000..fc155507 --- /dev/null +++ b/crypto/md5/src/md5.c @@ -0,0 +1,202 @@ +/* + * 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_MD5 + +#include "securec.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "md5_core.h" +#include "crypt_md5.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +int32_t CRYPT_MD5_Init(CRYPT_MD5_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_MD5_Ctx), 0, sizeof(CRYPT_MD5_Ctx)); + /* Set the initial values of A, B, C, and D according to step 3 in section 3.3 of RFC1321. */ + ctx->h[0] = 0x67452301; + ctx->h[1] = 0xefcdab89; + ctx->h[2] = 0x98badcfe; + ctx->h[3] = 0x10325476; + return CRYPT_SUCCESS; +} + +void CRYPT_MD5_Deinit(CRYPT_MD5_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + (void)memset_s(ctx, sizeof(CRYPT_MD5_Ctx), 0, sizeof(CRYPT_MD5_Ctx)); +} + +static uint32_t IsInputOverflow(CRYPT_MD5_Ctx *ctx, uint32_t nbytes) +{ + uint32_t cnt0 = ctx->lNum + (nbytes << SHIFTS_PER_BYTE); + if (cnt0 < ctx->lNum) { + if (++ctx->hNum == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MD5_INPUT_OVERFLOW); + return CRYPT_MD5_INPUT_OVERFLOW; + } + } + uint32_t cnt1 = ctx->hNum + (uint32_t)(nbytes >> (BITSIZE(uint32_t) - SHIFTS_PER_BYTE)); + if (cnt1 < ctx->hNum) { + BSL_ERR_PUSH_ERROR(CRYPT_MD5_INPUT_OVERFLOW); + return CRYPT_MD5_INPUT_OVERFLOW; + } + ctx->hNum = cnt1; + ctx->lNum = cnt0; + return CRYPT_SUCCESS; +} + +static int32_t IsUpdateParamValid(CRYPT_MD5_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + if ((ctx == NULL) || (in == NULL && len != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (IsInputOverflow(ctx, len) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_MD5_INPUT_OVERFLOW); + return CRYPT_MD5_INPUT_OVERFLOW; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_MD5_Update(CRYPT_MD5_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + int32_t ret = IsUpdateParamValid(ctx, in, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (len == 0) { + return CRYPT_SUCCESS; + } + + const uint8_t *data = in; + uint32_t dataLen = len; + uint32_t left = CRYPT_MD5_BLOCKSIZE - ctx->num; + + if (ctx->num != 0) { + if (dataLen < left) { + (void)memcpy_s(ctx->block + ctx->num, left, data, dataLen); + ctx->num += dataLen; + return CRYPT_SUCCESS; + } + // When the external input data is greater than the remaining space of the block, + // copy the data which is the same length as the remaining space. + (void)memcpy_s(ctx->block + ctx->num, left, data, left); + MD5_Compress(ctx->h, ctx->block, 1); + dataLen -= left; + data += left; + ctx->num = 0; + } + + uint32_t blockCnt = dataLen / CRYPT_MD5_BLOCKSIZE; + if (blockCnt > 0) { + MD5_Compress(ctx->h, data, blockCnt); + blockCnt *= CRYPT_MD5_BLOCKSIZE; + data += blockCnt; + dataLen -= blockCnt; + } + + if (dataLen != 0) { + // Copy the remaining data to the cache array. + (void)memcpy_s(ctx->block, CRYPT_MD5_BLOCKSIZE, data, dataLen); + ctx->num = dataLen; + } + + return CRYPT_SUCCESS; +} + +static int32_t IsFinalParamValid(const CRYPT_MD5_Ctx *ctx, const uint8_t *out, const uint32_t *outLen) +{ + if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (*outLen < CRYPT_MD5_DIGESTSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_MD5_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_MD5_OUT_BUFF_LEN_NOT_ENOUGH; + } + + return CRYPT_SUCCESS; +} + + +int32_t CRYPT_MD5_Final(CRYPT_MD5_Ctx *ctx, uint8_t *out, uint32_t *outLen) +{ + int32_t ret = IsFinalParamValid(ctx, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ctx->block[ctx->num++] = 0x80; /* 0x80 indicates that '1' is appended to the end of a message. */ + uint8_t *block = ctx->block; + uint32_t num = ctx->num; + uint32_t left = CRYPT_MD5_BLOCKSIZE - num; + if (left < 8) { /* Less than 8 bytes, insufficient for storing data of the accumulated data length(lNum&hNum). */ + (void)memset_s(block + num, left, 0, left); + MD5_Compress(ctx->h, ctx->block, 1); + num = 0; + left = CRYPT_MD5_BLOCKSIZE; + } + (void)memset_s(block + num, left - 8, 0, left - 8); /* 8 byte is used to store data of accumulated data length. */ + block += CRYPT_MD5_BLOCKSIZE - 8; /* 8 byte is used to store data of the accumulated data length(lNum&hNum). */ + PUT_UINT32_LE(ctx->lNum, block, 0); + block += sizeof(uint32_t); + PUT_UINT32_LE(ctx->hNum, block, 0); + MD5_Compress(ctx->h, ctx->block, 1); + ctx->num = 0; + + PUT_UINT32_LE(ctx->h[0], out, 0); + PUT_UINT32_LE(ctx->h[1], out, 4); + PUT_UINT32_LE(ctx->h[2], out, 8); + PUT_UINT32_LE(ctx->h[3], out, 12); + *outLen = CRYPT_MD5_DIGESTSIZE; + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_MD5_CopyCtx(CRYPT_MD5_Ctx *dst, const CRYPT_MD5_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_MD5_Ctx), src, sizeof(CRYPT_MD5_Ctx)); + return CRYPT_SUCCESS; +} + +#ifdef __cplusplus +} +#endif /* __cpluscplus */ + +#endif // HITLS_CRYPTO_MD5 diff --git a/crypto/md5/src/md5_core.h b/crypto/md5/src/md5_core.h new file mode 100644 index 00000000..fe1a9ca8 --- /dev/null +++ b/crypto/md5/src/md5_core.h @@ -0,0 +1,36 @@ +/* + * 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 MD5_CORE_H +#define MD5_CORE_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_MD5 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void MD5_Compress(uint32_t state[4], const uint8_t *data, uint32_t blockCnt); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_MD5 + +#endif // MD5_CORE_H diff --git a/crypto/md5/src/noasm_md5.c b/crypto/md5/src/noasm_md5.c new file mode 100644 index 00000000..571f1fe4 --- /dev/null +++ b/crypto/md5/src/noasm_md5.c @@ -0,0 +1,216 @@ +/* + * 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_MD5 + +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "md5_core.h" +#include "crypt_md5.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/* F, G, H and I are basic MD5 functions. */ +#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~(z)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~(z)))) + +#define FF(a, b, c, d, x, s, ac) \ + do { \ + (a) += F((b), (c), (d)) + (x) + (ac); \ + (a) = ROTL32((a), (s)); \ + (a) += (b); \ + } while (0) + +#define GG(a, b, c, d, x, s, ac) \ + do { \ + (a) += G((b), (c), (d)) + (x) + (ac); \ + (a) = ROTL32((a), (s)); \ + (a) += (b); \ + } while (0) + +#define HH(a, b, c, d, x, s, ac) \ + do { \ + (a) += H((b), (c), (d)) + (x) + (ac); \ + (a) = ROTL32((a), (s)); \ + (a) += (b); \ + } while (0) + +#define II(a, b, c, d, x, s, ac) \ + do { \ + (a) += I((b), (c), (d)) + (x) + (ac); \ + (a) = ROTL32((a), (s)); \ + (a) += (b); \ + } while (0) + +/* Constants for MD5_Compress routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static const uint32_t T[64] = { + 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, + 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, + 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, + 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, + + 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, + 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, + 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, + 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, + + 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, + 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, + 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, + 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, + + 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, + 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, + 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, + 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391, +}; + +/* see RFC1321 chapter 3.4 Step 4 https://www.rfc-editor.org/rfc/rfc1321 */ +void MD5_Compress(uint32_t state[4], const uint8_t *data, uint32_t blockCnt) + { + uint32_t w[16] = {0}; + const uint8_t *input = data; + uint32_t count = blockCnt; + + while (count > 0) { + /* convert data to 32 bits for calculation */ + w[0] = GET_UINT32_LE(input, 0); + w[1] = GET_UINT32_LE(input, 4); + w[2] = GET_UINT32_LE(input, 8); + w[3] = GET_UINT32_LE(input, 12); + w[4] = GET_UINT32_LE(input, 16); + w[5] = GET_UINT32_LE(input, 20); + w[6] = GET_UINT32_LE(input, 24); + w[7] = GET_UINT32_LE(input, 28); + w[8] = GET_UINT32_LE(input, 32); + w[9] = GET_UINT32_LE(input, 36); + w[10] = GET_UINT32_LE(input, 40); + w[11] = GET_UINT32_LE(input, 44); + w[12] = GET_UINT32_LE(input, 48); + w[13] = GET_UINT32_LE(input, 52); + w[14] = GET_UINT32_LE(input, 56); + w[15] = GET_UINT32_LE(input, 60); + + uint32_t a = state[0]; + uint32_t b = state[1]; + uint32_t c = state[2]; + uint32_t d = state[3]; + + FF(a, b, c, d, w[0], S11, T[0]); + FF(d, a, b, c, w[1], S12, T[1]); + FF(c, d, a, b, w[2], S13, T[2]); + FF(b, c, d, a, w[3], S14, T[3]); + FF(a, b, c, d, w[4], S11, T[4]); + FF(d, a, b, c, w[5], S12, T[5]); + FF(c, d, a, b, w[6], S13, T[6]); + FF(b, c, d, a, w[7], S14, T[7]); + FF(a, b, c, d, w[8], S11, T[8]); + FF(d, a, b, c, w[9], S12, T[9]); + FF(c, d, a, b, w[10], S13, T[10]); + FF(b, c, d, a, w[11], S14, T[11]); + FF(a, b, c, d, w[12], S11, T[12]); + FF(d, a, b, c, w[13], S12, T[13]); + FF(c, d, a, b, w[14], S13, T[14]); + FF(b, c, d, a, w[15], S14, T[15]); + + GG(a, b, c, d, w[1], S21, T[16]); + GG(d, a, b, c, w[6], S22, T[17]); + GG(c, d, a, b, w[11], S23, T[18]); + GG(b, c, d, a, w[0], S24, T[19]); + GG(a, b, c, d, w[5], S21, T[20]); + GG(d, a, b, c, w[10], S22, T[21]); + GG(c, d, a, b, w[15], S23, T[22]); + GG(b, c, d, a, w[4], S24, T[23]); + GG(a, b, c, d, w[9], S21, T[24]); + GG(d, a, b, c, w[14], S22, T[25]); + GG(c, d, a, b, w[3], S23, T[26]); + GG(b, c, d, a, w[8], S24, T[27]); + GG(a, b, c, d, w[13], S21, T[28]); + GG(d, a, b, c, w[2], S22, T[29]); + GG(c, d, a, b, w[7], S23, T[30]); + GG(b, c, d, a, w[12], S24, T[31]); + + HH(a, b, c, d, w[5], S31, T[32]); + HH(d, a, b, c, w[8], S32, T[33]); + HH(c, d, a, b, w[11], S33, T[34]); + HH(b, c, d, a, w[14], S34, T[35]); + HH(a, b, c, d, w[1], S31, T[36]); + HH(d, a, b, c, w[4], S32, T[37]); + HH(c, d, a, b, w[7], S33, T[38]); + HH(b, c, d, a, w[10], S34, T[39]); + HH(a, b, c, d, w[13], S31, T[40]); + HH(d, a, b, c, w[0], S32, T[41]); + HH(c, d, a, b, w[3], S33, T[42]); + HH(b, c, d, a, w[6], S34, T[43]); + HH(a, b, c, d, w[9], S31, T[44]); + HH(d, a, b, c, w[12], S32, T[45]); + HH(c, d, a, b, w[15], S33, T[46]); + HH(b, c, d, a, w[2], S34, T[47]); + + II(a, b, c, d, w[0], S41, T[48]); + II(d, a, b, c, w[7], S42, T[49]); + II(c, d, a, b, w[14], S43, T[50]); + II(b, c, d, a, w[5], S44, T[51]); + II(a, b, c, d, w[12], S41, T[52]); + II(d, a, b, c, w[3], S42, T[53]); + II(c, d, a, b, w[10], S43, T[54]); + II(b, c, d, a, w[1], S44, T[55]); + II(a, b, c, d, w[8], S41, T[56]); + II(d, a, b, c, w[15], S42, T[57]); + II(c, d, a, b, w[6], S43, T[58]); + II(b, c, d, a, w[13], S44, T[59]); + II(a, b, c, d, w[4], S41, T[60]); + II(d, a, b, c, w[11], S42, T[61]); + II(c, d, a, b, w[2], S43, T[62]); + II(b, c, d, a, w[9], S44, T[63]); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + input += CRYPT_MD5_BLOCKSIZE; + count--; + } +} +#ifdef __cplusplus +} +#endif /* __cpluscplus */ + +#endif // HITLS_CRYPTO_MD5 diff --git a/crypto/modes/include/crypt_modes.h b/crypto/modes/include/crypt_modes.h new file mode 100644 index 00000000..f2e4e6fc --- /dev/null +++ b/crypto/modes/include/crypt_modes.h @@ -0,0 +1,175 @@ +/* + * 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_MODES_H +#define CRYPT_MODES_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_MODES + +#include +#include "crypt_eal_cipher.h" +#include "crypt_types.h" +#include "crypt_algid.h" +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define MODES_MAX_IV_LENGTH 24 +#define MODES_MAX_BUF_LENGTH 24 +#define DES_BLOCK_BYTE_NUM 8 + +#define UPDATE_VALUES(l, i, o, len) \ + do { \ + (l) -= (len); \ + (i) += (len); \ + (o) += (len); \ + } while (false) + +/** + * @ingroup crypt_mode_cipherctx + * mode handle + */ +typedef struct { + void *ciphCtx; /* Context defined by each algorithm */ + const EAL_CipherMethod *ciphMeth; /* Corresponding to the related methods for each symmetric algorithm */ + uint8_t iv[MODES_MAX_IV_LENGTH]; /* IV information */ + uint8_t buf[MODES_MAX_BUF_LENGTH]; /* Cache the information of the previous block. */ + uint8_t blockSize; /* Save the block size. */ + /* Used in CTR and OFB modes. If offset > 0, [0, offset-1] of iv indicates the used data, + [offset, blockSize-1] indicates unused data. */ + uint8_t offset; + CRYPT_SYM_AlgId algId; /* symmetric algorithm ID */ +} MODE_CipherCtx; + +typedef struct { + const uint8_t *in; + uint8_t *out; + const uint8_t *ctr; + uint8_t *tag; +} XorCryptData; + +/** + * @brief Initialize the module, register the method of the encryption and decryption algorithm with the module, + * and create the algorithm context. + * + * @param ctx [IN/OUT] mode handle + * @param method [IN] Symmetric encryption and decryption method + * @return If the operation is successful, the return value is CRYPT_SUCCESS. + * Other error codes are returned if the operation fails. + */ +int32_t MODE_InitCtx(MODE_CipherCtx *ctx, const EAL_CipherMethod *method); + +/** + * @brief Deinitialize the module, remove the relationship between the module and the algorithm module, + * and release the algorithm context. + * + * @param ctx [IN] Mode handle + * @param method [IN] Symmetric encryption and decryption methods + */ +void MODE_DeInitCtx(MODE_CipherCtx *ctx); + +/** + * @brief Set the encryption key. + * + * @param ctx [IN/OUT] mode handle + * @param key [IN] Encryption key + * @param len [IN] Encryption key length + * @return Success: CRYPT_SUCCESS + * failure: Other error codes. + */ +int32_t MODE_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len); + + +/** + * @brief Set the decryption key. + * + * @param ctx [IN/OUT] mode handle + * @param key [IN] Decryption key + * @param len [IN] Decryption key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len); + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief Set the encryption key in SM4. + * + * @param ctx [IN] mode handle + * @param key [IN] Encryption key + * @param len [IN] Encryption key length. Only 16 (128 bits) is supported. + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief Set the decryption key in SM4. + * + * @param ctx [IN] mode handle + * @param key [IN] Decryption key + * @param len [IN] Decryption key length. Only 16 (128 bits) is supported. + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len); +#endif + +/** + * @brief Operate the mode parameter. + * + * @param ctx [IN/OUT] mode handle + * @param opt [IN] Operation + * @param val [IN/OUT] Parameter, which can be an input parameter or an output parameter. + * @param len [IN] Parameter length + * @return Success: CRYPT_SUCCESS + * failure: Other error codes. + */ +int32_t MODE_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +/** + * @brief Clean Mode content and sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] Mode handle + * @return None + */ +void MODE_Clean(MODE_CipherCtx *ctx); + +int32_t MODE_SetIv(MODE_CipherCtx *ctx, uint8_t *val, uint32_t len); +int32_t MODE_GetIv(MODE_CipherCtx *ctx, uint8_t *val, uint32_t len); + +static inline void MODE_IncCounter(uint8_t *counter, uint32_t counterLen) +{ + uint32_t i = counterLen; + uint16_t carry = 1; + + while (i > 0) { + i--; + carry += counter[i]; + counter[i] = carry & (0xFFu); + carry >>= 8; // Take the upper 8 bits. + } +} + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_MODES + +#endif // CRYPT_MODES_H diff --git a/crypto/modes/include/crypt_modes_cbc.h b/crypto/modes/include/crypt_modes_cbc.h new file mode 100644 index 00000000..cc145e7c --- /dev/null +++ b/crypto/modes/include/crypt_modes_cbc.h @@ -0,0 +1,118 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_MODES_CBC_H +#define CRYPT_MODES_CBC_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CBC + +#include "crypt_modes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief CBC mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CBC_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief CBC mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CBC_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef HITLS_CRYPTO_AES +/** + * @brief AES CBC mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t AES_CBC_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief AES CBC mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t AES_CBC_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +/** + * @brief Clear the content in CBC mode, delete sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] mode handle + * @return none + */ +void MODE_CBC_Clean(MODE_CipherCtx *ctx); + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief SM4-CBC mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_CBC_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-CBC mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_CBC_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CBC + +#endif // CRYPT_MODES_CBC_H diff --git a/crypto/modes/include/crypt_modes_ccm.h b/crypto/modes/include/crypt_modes_ccm.h new file mode 100644 index 00000000..14bfa6f5 --- /dev/null +++ b/crypto/modes/include/crypt_modes_ccm.h @@ -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 CRYPT_MODES_CCM_H +#define CRYPT_MODES_CCM_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CCM + +#include +#include "crypt_local_types.h" +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define CCM_BLOCKSIZE 16 + +typedef struct { + void *ciphCtx; /* Context defined by each algorithm */ + const EAL_CipherMethod *ciphMeth; /* Corresponding to the related methods for each symmetric algorithm */ + + uint8_t nonce[CCM_BLOCKSIZE]; /* Data nonce, ctr encrypted data */ + uint8_t tag[CCM_BLOCKSIZE]; /* Data tag, intermediate data encrypted by the CBC */ + uint8_t last[CCM_BLOCKSIZE]; /* Previous data block in ctr mode */ + uint64_t msgLen; /* The message length */ + uint8_t lastLen; /* Unused data length of the previous data block in ctr mode. */ + uint8_t tagLen; /* The length of the tag is 16 by default. The tag is reset each time the key is set. */ + uint8_t tagInit; /* Indicate whether the tag is initialized. */ +} MODES_CCM_Ctx; + +int32_t MODES_CCM_InitCtx(MODES_CCM_Ctx *ctx, const struct EAL_CipherMethod *m); + +void MODES_CCM_DeinitCtx(MODES_CCM_Ctx *ctx); + +void MODES_CCM_Clean(MODES_CCM_Ctx *ctx); + +int32_t MODES_CCM_Ctrl(MODES_CCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +int32_t MODES_CCM_SetKey(MODES_CCM_Ctx *ctx, const uint8_t *key, uint32_t len); + +int32_t MODES_CCM_Encrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +int32_t MODES_CCM_Decrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CCM + +#endif // CRYPT_MODES_CCM_H diff --git a/crypto/modes/include/crypt_modes_cfb.h b/crypto/modes/include/crypt_modes_cfb.h new file mode 100644 index 00000000..a81f9582 --- /dev/null +++ b/crypto/modes/include/crypt_modes_cfb.h @@ -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. + */ + +#ifndef CRYPT_MODES_CFB_H +#define CRYPT_MODES_CFB_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CFB + +#include "crypt_modes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct { + MODE_CipherCtx *modeCtx; /* Stores the pointer to MODE_CipherCtx */ + uint8_t feedbackBits; /* Save the FeedBack length. */ +} MODE_CFB_Ctx; + +/** + * @brief Set the encryption key in CFB mode. + * + * @param ctx [IN/OUT] mode handle + * @param key [IN] Encryption key + * @param len [IN] Encryption key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CFB_SetEncryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief Initialize the module, register the method of the encryption and decryption algorithm in the module, + * and create the algorithm context. + * + * @param ctx [IN] mode handle + * @param method [IN] Symmetric encryption and decryption methods + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CFB_InitCtx(MODE_CFB_Ctx *ctx, const EAL_CipherMethod *method); + +/** + * @brief CFB mode encryption. Any byte can be encrypted, including 1-bit/8-bit/64-bit/128-bit CFB + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CFB_Encrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief CFB mode decryption. Any byte can be decrypted, including 1-bit/8-bit/64-bit/128-bit CFB + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief Perform parameter operation on mode. + * + * @param ctx [IN] mode handle + * @param opt [IN] operation (Set/Get IV; Set/Get FeedbackSize) + * @param val [IN/OUT] Parameter, which can be an input parameter or an output parameter. + * @param len [IN] Parameter length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CFB_Ctrl(MODE_CFB_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +/** + * @brief Clear the content in CFB mode, delete sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] mode handle + * @return none + */ +void MODE_CFB_Clean(MODE_CFB_Ctx *ctx); + +/** + * @brief Deinitialize the module, remove the relationship between the module and the algorithm, + * and release the algorithm context. + * + * @param ctx [IN] mode handle + * @param method [IN] Symmetric encryption and decryption methods + */ +void MODE_CFB_DeInitCtx(MODE_CFB_Ctx *ctx); + +/** + * @brief For encrypting and decrypting bits in CFB mode (internal function, only for test) + */ +int32_t MODE_CFB_BitCrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc); + +#ifdef HITLS_CRYPTO_AES +/** + * @brief AES-CFB mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @param iv [IN] iv + * @return Remaining unprocessed length + */ +int32_t MODE_AES_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif // HITLS_CRYPTO_AES + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief Set the encryption key in SM4-CFB mode. + * + * @param ctx [IN] mode handle + * @param key [IN] Encryption key + * @param len [IN] Encryption key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_CFB_SetEncryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief SM4-CFB mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_CFB_Encrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-CFB mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif // HITLS_CRYPTO_SM4 + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CFB + +#endif // CRYPT_MODES_CFB_H diff --git a/crypto/modes/include/crypt_modes_chacha20poly1305.h b/crypto/modes/include/crypt_modes_chacha20poly1305.h new file mode 100644 index 00000000..b05f03c5 --- /dev/null +++ b/crypto/modes/include/crypt_modes_chacha20poly1305.h @@ -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 CRYPT_MODES_CHACHA20POLY1305_H +#define CRYPT_MODES_CHACHA20POLY1305_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CHACHA20POLY1305 + +#include +#include "crypt_local_types.h" +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct { + uint32_t acc[6]; // The intermediate data of the acc, must be greater than 130 bits. + uint32_t r[4]; // Key information r, 16 bytes, that is, 4 * sizeof(uint32_t) + uint32_t s[4]; // Key information s, 16 bytes, that is, 4 * sizeof(uint32_t) + uint32_t table[36]; // Indicates the table used to accelerate the assembly calculation. + uint8_t last[16]; // A block 16 bytes are cached for the last unprocessed data. + uint32_t lastLen; // Indicates the remaining length of the last data. + uint32_t flag; // Used to save the assembly status information. +} Poly1305Ctx; + +typedef struct { + void *key; // Handle for the method. + const EAL_CipherMethod *method; // algorithm method + Poly1305Ctx polyCtx; + uint64_t aadLen; // Status, indicating whether identification data is set. + uint64_t cipherTextLen; // status, indicating whether the identification data is set. +} MODES_CHACHA20POLY1305_Ctx; + +int32_t MODES_CHACHA20POLY1305_InitCtx(MODES_CHACHA20POLY1305_Ctx *ctx, const struct EAL_CipherMethod *m); + +void MODES_CHACHA20POLY1305_DeinitCtx(MODES_CHACHA20POLY1305_Ctx *ctx); + +void MODES_CHACHA20POLY1305_Clean(MODES_CHACHA20POLY1305_Ctx *ctx); + +int32_t MODES_CHACHA20POLY1305_Ctrl(MODES_CHACHA20POLY1305_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +int32_t MODES_CHACHA20POLY1305_SetEncryptKey(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *key, uint32_t len); + +int32_t MODES_CHACHA20POLY1305_SetDecryptKey(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *key, uint32_t len); + +int32_t MODES_CHACHA20POLY1305_Encrypt(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +int32_t MODES_CHACHA20POLY1305_Decrypt(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CHACHA20POLY1305 + +#endif // CRYPT_MODES_CHACHA20POLY1305_H diff --git a/crypto/modes/include/crypt_modes_ctr.h b/crypto/modes/include/crypt_modes_ctr.h new file mode 100644 index 00000000..c9592310 --- /dev/null +++ b/crypto/modes/include/crypt_modes_ctr.h @@ -0,0 +1,118 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_MODES_CTR_H +#define CRYPT_MODES_CTR_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CTR + +#include "crypt_modes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief CTR mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_CTR_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef HITLS_CRYPTO_AES +/** + * @brief CTR mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t AES_CTR_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief CTR mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t AES_CTR_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +/** + * @brief Clear the content in CTR mode, delete sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] mode handle + * @return none + */ +void MODE_CTR_Clean(MODE_CipherCtx *ctx); + +/** + * @brief Process the case that the number of bytes is less than 16 in CTR mode. + * + */ +uint32_t MODE_CTR_LastHandle(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief Process the CTR mode tail. + * + */ +void MODE_CTR_RemHandle(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief SM4-CTR mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_CTR_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-CTR mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_CTR_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CTR + +#endif // CRYPT_MODES_CTR_H diff --git a/crypto/modes/include/crypt_modes_ecb.h b/crypto/modes/include/crypt_modes_ecb.h new file mode 100644 index 00000000..10af3146 --- /dev/null +++ b/crypto/modes/include/crypt_modes_ecb.h @@ -0,0 +1,130 @@ +/* + * 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_MODES_ECB_H +#define CRYPT_MODES_ECB_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_ECB + +#include "crypt_modes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief ECB mode encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_ECB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief ECB mode decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_ECB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef HITLS_CRYPTO_AES +/** + * @brief ECB mode assembly encryption + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t AES_ECB_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief ECB mode assembly decryption + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t AES_ECB_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +/** + * @brief Clear the ECB mode context, delete sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] mode handle + * @return none + */ +void MODE_ECB_Clean(MODE_CipherCtx *ctx); + +/** + * @brief In ECB mode, perform parameter operations on mode. + * + * @param ctx [IN] mode handle + * @param opt [IN] Operation + * @param val [IN/OUT] Parameter, which can be an input parameter or an output parameter. + * @param len [IN] Parameter length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_ECB_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief SM4-ECB mode encryption. When the value of len is not an integer multiple of 16, + * MODE_SM4_ECB_Encrypt cannot be invoked to encrypt new data. + * + * @param [IN] ctx mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_ECB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-ECB mode decryption. If the value of len is not an integer multiple of 16, + * this round of decryption is complete. + * + * @param ctx [IN] mode handle + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_ECB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif +#endif \ No newline at end of file diff --git a/crypto/modes/include/crypt_modes_gcm.h b/crypto/modes/include/crypt_modes_gcm.h new file mode 100644 index 00000000..e3e99237 --- /dev/null +++ b/crypto/modes/include/crypt_modes_gcm.h @@ -0,0 +1,126 @@ +/* + * 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_MODES_GCM_H +#define CRYPT_MODES_GCM_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_GCM + +#include +#include "crypt_local_types.h" +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define GCM_BLOCKSIZE 16 + +typedef struct { + uint64_t h; + uint64_t l; +} MODES_GCM_GF128; + +typedef struct { + // The information can be set once and used multiple times. + uint8_t iv[GCM_BLOCKSIZE]; // Processed IV information. The length is 16 bytes. + uint8_t ghash[GCM_BLOCKSIZE]; // Intermediate data for tag calculation. + MODES_GCM_GF128 hTable[16]; // The window uses 4 bits, 2 ^ 4 = 16 entries need to be pre-calculated. + void *ciphCtx; // Context defined by each symmetric algorithm. + const EAL_CipherMethod *ciphMeth; // algorithm method + /** + * tagLen may be any one of the following five values: 16, 15, 14, 13, or 12 bytes + * For certain applications, tagLen may be 8 or 4 bytes + */ + uint8_t tagLen; + uint32_t cryptCnt; // Indicate the number of encryption times that the key can be used. + + // Intermediate encryption/decryption information. The lifecycle is one encryption/decryption operation, + // and needs to be reset during each encryption/decryption operation. + uint8_t last[GCM_BLOCKSIZE]; // ctr mode last + uint8_t remCt[GCM_BLOCKSIZE]; // Remaining ciphertext + uint8_t ek0[GCM_BLOCKSIZE]; // ek0 + uint64_t plaintextLen; // use for calc tag + uint32_t aadLen; // use for calc tag + uint32_t lastLen; // ctr mode lastLen +} MODES_GCM_Ctx; + +int32_t MODES_GCM_InitCtx(MODES_GCM_Ctx *ctx, const struct EAL_CipherMethod *m); + +void MODES_GCM_DeinitCtx(MODES_GCM_Ctx *ctx); + +void MODES_GCM_Clean(MODES_GCM_Ctx *ctx); + +int32_t MODES_GCM_Ctrl(MODES_GCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +int32_t MODES_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *ciphCtx, uint32_t len); + +int32_t MODES_GCM_InitHashTable(MODES_GCM_Ctx *ctx); + +int32_t MODES_GCM_Encrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +int32_t MODES_GCM_Decrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef HITLS_CRYPTO_AES +int32_t AES_GCM_EncryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +int32_t AES_GCM_DecryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif // HITLS_CRYPTO_AES + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief SM4-GCM mode key setting + * + * @param ctx [IN] Mode handle + * @param key [IN] Encryption key + * @param len [IN] Encryption key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief SM4-GCM mode encryption + * + * @param [IN] ctx Mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_GCM_EncryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-GCM mode decryption + * + * @param ctx [IN] Mode handle + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_GCM_DecryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif // HITLS_CRYPTO_SM4 + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_GCM + +#endif // CRYPT_MODES_GCM_H diff --git a/crypto/modes/include/crypt_modes_ofb.h b/crypto/modes/include/crypt_modes_ofb.h new file mode 100644 index 00000000..baa2076d --- /dev/null +++ b/crypto/modes/include/crypt_modes_ofb.h @@ -0,0 +1,72 @@ +/* + * 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_MODES_OFB_H +#define CRYPT_MODES_OFB_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_OFB + +#include "crypt_modes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief OFB mode encryption/decryption. Any byte length can be encrypted/decrypted. + * + * @param [IN] ctx Context of ofb mode encryption + * @param [IN] in Data to be encrypted/decrypted + * @param [OUT] out Encrypted/decrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_OFB_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief SM4-OFB mode encryption + * + * @param [IN] ctx Context of ofb mode encryption + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_OFB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-OFB mode decryption + * + * @param ctx [IN] Context of ofb mode encryption + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_SM4_OFB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_OFB + +#endif // CRYPT_MODES_OFB_H diff --git a/crypto/modes/include/crypt_modes_xts.h b/crypto/modes/include/crypt_modes_xts.h new file mode 100644 index 00000000..b70a8705 --- /dev/null +++ b/crypto/modes/include/crypt_modes_xts.h @@ -0,0 +1,179 @@ +/* + * 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_MODES_XTS_H +#define CRYPT_MODES_XTS_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_XTS + +#include "crypt_local_types.h" +#include "crypt_types.h" +#include "crypt_modes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct { + void *ciphCtx; /* Key defined by each algorithm */ + const EAL_CipherMethod *ciphMeth; /* corresponding to the encrypt and decrypt in the bottom layer, operate keyctx */ + uint8_t iv[MODES_MAX_IV_LENGTH]; /* The length is blocksize */ + uint8_t tweak[MODES_MAX_IV_LENGTH]; /* The length is blocksize */ + uint8_t blockSize; /* Save the block size. */ + CRYPT_SYM_AlgId algId; /* symmetric algorithm ID */ +} MODE_XTS_Ctx; + +/** + * @brief Initialize the module, register the method of the encryption and decryption algorithm in the module, + * and create the algorithm context. + * + * @param ctx [IN] Context of xts mode encryption + * @param method [IN] Symmetric encryption and decryption methods + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_XTS_InitCtx(MODE_XTS_Ctx *ctx, EAL_CipherMethod *method); +/** + * @brief Set the encryption key in XTS mode. + * + * @param ctx [IN] Context of xts mode encryption + * @param key [IN] Encryption key + * @param len [IN] Encryption key length. Only 32 (256 bits) and 64 (512 bits) are supported. + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_XTS_SetEncryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief Set the decryption key in XTS mode. + * + * @param ctx [IN] Context of xts mode encryption + * @param key [IN] Decryption key + * @param len [IN] Decryption key length. Only 32 (256 bits) and 64 (512 bits) are supported. + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_XTS_SetDecryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief XTS mode encryption. If the value of len is not an integer multiple of 16, + * MODE_XTS_Encrypt cannot be invoked to encrypt new data. + * + * @param [IN] ctx Context of xts mode encryption + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_XTS_Encrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief XTS mode decryption. If the value of len is not an integer multiple of 16, + * this round of the decryption is complete. + * + * @param ctx [IN] Context of xts mode encryption + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_XTS_Decrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +/** + * @brief Clear the XTS mode context, delete sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] Context of xts mode encryption + * @return none + */ +void MODE_XTS_Clean(MODE_XTS_Ctx *ctx); +/** + * @brief Operate parameters for the XTS mode. + * + * @param ctx [IN] Context of xts mode encryption + * @param opt [IN] Operation + * @param val [IN/OUT] Parameter, which can be an input parameter or an output parameter. + * @param len [IN] Parameter length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODE_XTS_Ctrl(MODE_XTS_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len); + +#ifdef HITLS_CRYPTO_SM4 +/** + * @brief SM4-XTS mode setting encryption key + * + * @param ctx [IN] Context of xts mode encryption + * @param key [IN] Encryption key + * @param len [IN] Encryption key length. Only 32 bytes (256bits) is supported. + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_XTS_SetEncryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief SM4-XTS mode setting decryption key + * + * @param ctx [IN] Context of xts mode encryption + * @param key [IN] Decryption key + * @param len [IN] Decryption key length. Only 32 bytes (256bits) is supported. + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_XTS_SetDecryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief SM4-XTS mode encryption. When the value of len is not an integer multiple of 16, + * MODE_SM4_XTS_Encrypt cannot be invoked to encrypt new data. + * + * @param [IN] ctx Mode handle + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] len Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_XTS_Encrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4-XTS mode decryption. If the value of len is not an integer multiple of 16, + * this round of the decryption is complete. + * + * @param ctx [IN] Context of xts mode encryption + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t MODES_SM4_XTS_Decrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief Clear the SM4-XTS mode context, delete sensitive data. Preserve the memory and methods of algorithm modules + * + * @param ctx [IN] Context of xts mode encryption + * @return none + */ +void MODES_SM4_XTS_Clean(MODE_XTS_Ctx *ctx); +#endif // HITLS_CRYPTO_SM4 + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_XTS + +#endif // CRYPT_MODES_XTS_H diff --git a/crypto/modes/src/asm/aes_ccm_x86_64.S b/crypto/modes/src/asm/aes_ccm_x86_64.S new file mode 100644 index 00000000..b5704a85 --- /dev/null +++ b/crypto/modes/src/asm/aes_ccm_x86_64.S @@ -0,0 +1,204 @@ +/* + * 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_CCM) + +.text + +.balign 16 +g_byteSwapMask: +.byte 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08 +.byte 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 +.size g_byteSwapMask, .-g_byteSwapMask +.balign 16 +g_one: +.byte 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +.size g_one, .-g_one + +/* + * void AesCcmEncryptAsm(void *key, uint8_t *nonce, const uint8_t *in, uint8_t *out, uint32_t len) + * rdi *key + * rsi *nonce + * rdx *in + * rcx *out + * r8 len + */ +.globl AesCcmEncryptAsm +.type AesCcmEncryptAsm, @function +.balign 16 +AesCcmEncryptAsm: +.cfi_startproc + shr $4, %r8d // loop times + jz .Lenc_ret + lea g_byteSwapMask(%rip), %r11 + mov 0xf0(%rdi), %r9d // key->rounds + vmovdqa (%r11), %xmm15 // g_byteSwapMask + sub $1, %r9d + vmovdqa 0x10(%r11), %xmm14 // g_one + vmovdqu (%rsi), %xmm0 // nonce(counter) + vmovdqu 0x10(%rsi), %xmm8 // tag + vmovdqu 0x20(%rsi), %xmm9 // last +.balign 16 +.Lenc_outer_loop: + mov %r9d, %r10d + vpxor (%rdx), %xmm8, %xmm8 // in ^ tag = tag + vmovdqu (%rdi), %xmm1 // key0 + lea 0x10(%rdi), %r11 // &key + 1 + vpxor %xmm0, %xmm1, %xmm2 // first round xor(aes-ctr) + vpshufb %xmm15, %xmm0, %xmm0 // reverse byte order of nonce => nonce' + vpxor %xmm8, %xmm1, %xmm3 // first round xor(aes-cmac) +.balign 16 +.Lenc_aes_loop: + vmovdqu (%r11), %xmm1 + vaesenc %xmm1, %xmm2, %xmm2 + vaesenc %xmm1, %xmm3, %xmm3 + lea 0x10(%r11), %r11 // to next key ptr + dec %r10d + jnz .Lenc_aes_loop + vmovdqu (%r11), %xmm1 // get the last key + vpaddq %xmm14, %xmm0, %xmm0 // nonce' + 1 + vaesenclast %xmm1, %xmm2, %xmm9 + vaesenclast %xmm1, %xmm3, %xmm8 + vpxor (%rdx), %xmm9, %xmm2 // in ^ last = out + vpshufb %xmm15, %xmm0, %xmm0 // reverse byte order of nonce' => nonce + lea 0x10(%rdx), %rdx // go to next ptr + vmovdqu %xmm2, (%rcx) // out out + + lea 0x10(%rcx), %rcx // go to next ptr + dec %r8d + jnz .Lenc_outer_loop + vpxor %xmm1, %xmm1, %xmm1 + vpxor %xmm2, %xmm2, %xmm2 + vpxor %xmm3, %xmm3, %xmm3 + vmovdqu %xmm0, (%rsi) // out nonce + vpxor %xmm0, %xmm0, %xmm0 + vmovdqu %xmm8, 0x10(%rsi) // out tag + vpxor %xmm8, %xmm8, %xmm8 + vmovdqu %xmm9, 0x20(%rsi) // out last + vpxor %xmm9, %xmm9, %xmm9 +.Lenc_ret: + ret +.cfi_endproc +.size AesCcmEncryptAsm, .-AesCcmEncryptAsm + +/* + * void AesCcmDecryptAsm(void *key, uint8_t *nonce, const uint8_t *in, uint8_t *out, uint32_t len) + * rdi *key + * rsi *nonce + * rdx *in + * rcx *out + * r8 len + */ +.globl AesCcmDecryptAsm +.type AesCcmDecryptAsm, @function +.balign 16 +AesCcmDecryptAsm: +.cfi_startproc + shr $4, %r8d // loop times + jz .Ldec_ret + lea g_byteSwapMask(%rip), %r11 + mov 0xf0(%rdi), %r9d // key->rounds + vmovdqa (%r11), %xmm15 // g_byteSwapMask + sub $1, %r9d + vmovdqa 0x10(%r11), %xmm14 // g_one + vmovdqu (%rsi), %xmm0 // nonce(counter) + vmovdqu 0x10(%rsi), %xmm8 // tag + +.balign 16 +.Ldec_outer_loop: + mov %r9d, %r10d + lea 0x10(%rdi), %r11 // &key + vmovdqu (%rdi), %xmm1 // key0 + vpxor %xmm0, %xmm1, %xmm2 // first round xor(aes-ctr) +.Ldec_aes_loop: + vmovdqu (%r11), %xmm1 + vaesenc %xmm1, %xmm2, %xmm2 + lea 0x10(%r11), %r11 + dec %r10d + jnz .Ldec_aes_loop + vmovdqu (%r11), %xmm1 + vaesenclast %xmm1, %xmm2, %xmm4 + vmovdqu %xmm4, 0x20(%rsi) // out last + vpxor (%rdx), %xmm4, %xmm2 // in ^ last = out + vpxor %xmm2, %xmm8, %xmm8 // out ^ tag = tag + vmovdqu %xmm2, (%rcx) // out out + lea 0x10(%rdx), %rdx + lea 0x10(%rcx), %rcx + vpshufb %xmm15, %xmm0, %xmm0 // reverse byte order of nonce => nonce' + vpaddq %xmm14, %xmm0, %xmm0 // nonce' + 1 + vpshufb %xmm15, %xmm0, %xmm0 // reverse byte order of nonce' => nonce + cmp $2, %r8d + jb .Ldec_parallel_out + +.Ldec_parallel_loop: + mov %r9d, %r10d + lea 0x10(%rdi), %r11 // &key + vmovdqu (%rdi), %xmm1 // key0 + vpxor %xmm0, %xmm1, %xmm2 // first round xor(aes-ctr) + vpxor %xmm8, %xmm1, %xmm3 // first round xor(aes-cmac) +.Ldec_parallel_inner_loop: + vmovdqu (%r11), %xmm1 + vaesenc %xmm1, %xmm2, %xmm2 + lea 0x10(%r11), %r11 + vaesenc %xmm1, %xmm3, %xmm3 + dec %r10d + jnz .Ldec_parallel_inner_loop + vmovdqu (%r11), %xmm1 + vaesenclast %xmm1, %xmm2, %xmm4 + vaesenclast %xmm1, %xmm3, %xmm8 + vmovdqu %xmm4, 0x20(%rsi) // out last + vpxor (%rdx), %xmm4, %xmm2 // in ^ last = out + vpxor %xmm2, %xmm8, %xmm8 // out ^ tag = tag + vmovdqu %xmm2, (%rcx) // out out + lea 0x10(%rdx), %rdx + lea 0x10(%rcx), %rcx + vpshufb %xmm15, %xmm0, %xmm0 // reverse byte order of nonce => nonce' + vpaddq %xmm14, %xmm0, %xmm0 // nonce' + 1 + vpshufb %xmm15, %xmm0, %xmm0 // reverse byte order of nonce' => nonce + dec %r8d + cmp $2, %r8d + jae .Ldec_parallel_loop + +.Ldec_parallel_out: + mov %r9d, %r10d + lea 0x10(%rdi), %r11 // &key + vmovdqu (%rdi), %xmm1 // key0 + vpxor %xmm8, %xmm1, %xmm3 // first round xor(aes-cmac) +.Ldec_aes_loop_1: + vmovdqu (%r11), %xmm1 + vaesenc %xmm1, %xmm3, %xmm3 + lea 0x10(%r11), %r11 + dec %r10d + jnz .Ldec_aes_loop_1 + vmovdqu (%r11), %xmm1 + vaesenclast %xmm1, %xmm3, %xmm8 + dec %r8d + jnz .Ldec_outer_loop + + vmovdqu %xmm0, (%rsi) // out nonce + vpxor %xmm0, %xmm0, %xmm0 + vpxor %xmm1, %xmm1, %xmm1 + vpxor %xmm2, %xmm2, %xmm2 + vmovdqu %xmm8, 0x10(%rsi) // out tag + vpxor %xmm8, %xmm8, %xmm8 + vpxor %xmm3, %xmm3, %xmm3 + vpxor %xmm4, %xmm4, %xmm4 +.Ldec_ret: + ret +.cfi_endproc +.size AesCcmDecryptAsm, .-AesCcmDecryptAsm +#endif diff --git a/crypto/modes/src/asm/ghash_armv8.S b/crypto/modes/src/asm/ghash_armv8.S new file mode 100644 index 00000000..e6fd437e --- /dev/null +++ b/crypto/modes/src/asm/ghash_armv8.S @@ -0,0 +1,190 @@ +/* + * 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. + */ +#ifdef HITLS_CRYPTO_GCM +.arch armv8-a+crypto +.text + +INPUT_H .req x0 +OUT_TB .req x1 +MULL_C2 .req v31 +MULL_H .req v24 +OUT_H0 .req v25 +OUT_H1_2 .req v26 +OUT_H2 .req v27 +OUT_H3 .req v28 +OUT_H3_4 .req v29 +OUT_H4 .req v30 +INPUT_X .req v0 +OUT_X .req v23 + +.macro GEN_H + ext v1.16b, MULL_H.16b, MULL_H.16b, #8 // + ushr v2.2d, MULL_C2.2d, #63 + dup MULL_H.4s, MULL_H.s[1] + ext v3.16b, v2.16b, MULL_C2.16b, #8 // t0 = 0xc2....01 + + ushr v2.2d, v1.2d, #63 + sshr MULL_H.4s, MULL_H.4s, #31 // broadcast carry bit + and v2.16b, v2.16b, v3.16b + shl v1.2d, v1.2d, #1 + + ext v2.16b, v2.16b, v2.16b, #8 + + and v3.16b, v3.16b, MULL_H.16b + orr v1.16b, v1.16b, v2.16b // H<<<=1 + eor OUT_H0.16b, v1.16b, v3.16b // twisted H + st1 {OUT_H0.2d}, [OUT_TB], #16 // store H0 +.endm + +.macro GEN_H2 + //(ah + al) * (ah + al) = ah * ah + 2 * ah * al + al * al + ext v10.16b, OUT_H0.16b, OUT_H0.16b, #8 // A + pmull v12.1q, OUT_H0.1d, OUT_H0.1d // aL * aL + eor v10.16b, v10.16b, OUT_H0.16b // A + h + pmull2 v11.1q, OUT_H0.2d, OUT_H0.2d // ah * ah + pmull v13.1q, v10.1d, v10.1d // (A + h) * (A + h) + + ext v14.16b, v12.16b, v11.16b, #8 // B + eor v15.16b, v12.16b, v11.16b // aL * aL + ah * ah + eor v13.16b, v13.16b, v14.16b // ah * al + B + eor v13.16b, v13.16b, v15.16b // + pmull v15.1q, v12.1d, MULL_C2.1d // 1st phase + + ins v11.d[0], v13.d[1] + ins v13.d[1], v12.d[0] + eor v12.16b, v13.16b, v15.16b + + ext v15.16b, v12.16b, v12.16b, #8 + pmull v12.1q, v12.1d, MULL_C2.1d + eor v15.16b, v15.16b, v11.16b + eor OUT_H2.16b, v12.16b, v15.16b // H^2 + + ext v16.16b, OUT_H2.16b, OUT_H2.16b, #8 + eor v16.16b, v16.16b, OUT_H2.16b + ext OUT_H1_2.16b, v10.16b, v16.16b, #8 + st1 {OUT_H1_2.2d, OUT_H2.2d}, [OUT_TB], #32 // store H^2h H^2 +.endm + +.macro GEN_H3_4 + //calculate H^3 and H^4 + pmull v0.1q, OUT_H0.1d, OUT_H2.1d + pmull v1.1q, OUT_H2.1d, OUT_H2.1d + pmull2 v2.1q, OUT_H0.2d, OUT_H2.2d + pmull2 v3.1q, OUT_H2.2d, OUT_H2.2d + pmull v4.1q, v10.1d, v16.1d + pmull v5.1q, v16.1d, v16.1d + + ext v6.16b, v0.16b, v2.16b, #8 // Karatsuba post-processing + ext v7.16b, v1.16b, v3.16b, #8 + eor v8.16b, v0.16b, v2.16b + + eor v4.16b, v4.16b, v6.16b + eor v9.16b, v1.16b, v3.16b + eor v5.16b, v5.16b, v7.16b + eor v4.16b, v4.16b, v8.16b + + pmull v8.1q, v0.1d, MULL_C2.1d // 1st phase + eor v5.16b, v5.16b, v9.16b + pmull v9.1q, v1.1d, MULL_C2.1d + + ins v2.d[0], v4.d[1] + ins v3.d[0], v5.d[1] + ins v4.d[1], v0.d[0] + ins v5.d[1], v1.d[0] + + eor v0.16b, v4.16b, v8.16b + eor v1.16b, v5.16b, v9.16b + + ext v8.16b, v0.16b, v0.16b,#8 // 2nd phase + ext v9.16b, v1.16b, v1.16b,#8 + + pmull v0.1q, v0.1d, MULL_C2.1d + pmull v1.1q, v1.1d, MULL_C2.1d + + eor v8.16b, v8.16b, v2.16b + eor v9.16b, v9.16b, v3.16b + eor OUT_H3.16b, v0.16b, v8.16b // H^3 + eor OUT_H4.16b, v1.16b, v9.16b // H^4 + + ext v20.16b, OUT_H3.16b, OUT_H3.16b, #8 // Karatsuba pre-processing + ext v21.16b, OUT_H4.16b, OUT_H4.16b, #8 + eor v20.16b, v20.16b, OUT_H4.16b + eor v21.16b, v21.16b, OUT_H4.16b + ext OUT_H3_4.16b, v20.16b, v21.16b, #8 // h + st1 {OUT_H3.2d, OUT_H3_4.2d, OUT_H4.2d}, [OUT_TB] // store h^3 h^3+h^4 h^4 +.endm + +.globl GcmTableGen4bit +.type GcmTableGen4bit, %function +.align 4 +GcmTableGen4bit: + movi MULL_C2.16b, #0xe1 // set 0xc2 + ld1 {MULL_H.16b}, [INPUT_H] // load input H + shl MULL_C2.2d, MULL_C2.2d, #57 // 0xc20000000000000 + rev64 MULL_H.16b, MULL_H.16b + GEN_H + GEN_H2 + GEN_H3_4 +ret +.size GcmTableGen4bit,.-GcmTableGen4bit + +// void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], const uint8_t *in, uint32_t inLen) +.globl GcmHashMultiBlock +.type GcmHashMultiBlock, %function +.align 4 +GcmHashMultiBlock: + lsr x3, x3, #4 // Divided by 64 16*2*2 + ld1 {INPUT_X.16b}, [INPUT_H] // load Xi + movi MULL_C2.16b, #0xe1 // set 0xc2 + ld1 {OUT_H0.2d, OUT_H1_2.2d}, [OUT_TB] // load twisted H, ... + shl MULL_C2.2d, MULL_C2.2d, #57 // 0xc20000000000000 +.LGcmLoop: + subs x3, x3, #1 + ld1 {v20.16b}, [x2], #16 // load in + eor INPUT_X.16b, INPUT_X.16b, v20.16b // t ^ in + + rev64 INPUT_X.16b, INPUT_X.16b // Vectors are reversed in doublewords + + ext v3.16b, INPUT_X.16b, INPUT_X.16b, #8 // {Xi.hi, Xi.lo} => {Xi.lo, Xi.hi} + pmull OUT_X.1q, OUT_H0.1d, v3.1d // (H.lo * Xi.hi) + eor INPUT_X.16b, INPUT_X.16b, v3.16b // (Xi.lo + Xi.hi) + pmull2 v2.1q, OUT_H0.2d, v3.2d // (H.hi * Xi.lo) + pmull v1.1q, OUT_H1_2.1d, INPUT_X.1d // (H.lo + H.hi) * (Xi.lo + Xi.hi) + + ext v7.16b, OUT_X.16b, v2.16b, #8 // M + eor v8.16b, OUT_X.16b, v2.16b // (H.lo * Xi.hi) + (H.hi * Xi.lo) + eor v1.16b, v1.16b, v7.16b // (H.lo + H.hi) * (Xi.lo + Xi.hi) + M + eor v1.16b, v1.16b, v8.16b // (H.lo * Xi.hi) + (H.hi * Xi.lo) + (H.lo + H.hi) * (Xi.lo + Xi.hi) + M + pmull v18.1q, OUT_X.1d, MULL_C2.1d // 1st phase of reduction + + ins v2.d[0], v1.d[1] + ins v1.d[1], OUT_X.d[0] + eor OUT_X.16b, v1.16b, v18.16b + + ext v18.16b, OUT_X.16b, OUT_X.16b, #8 // 2nd phase of reduction + pmull OUT_X.1q, OUT_X.1d, MULL_C2.1d + eor v18.16b, v18.16b, v2.16b + eor OUT_X.16b, OUT_X.16b, v18.16b + + rev64 OUT_X.16b, OUT_X.16b + + ext INPUT_X.16b, OUT_X.16b, OUT_X.16b, #8 + b.gt .LGcmLoop // > 0 + st1 {INPUT_X.16b}, [INPUT_H] // write out Xi +.LhashEnd: + ret +.size GcmHashMultiBlock,.-GcmHashMultiBlock + +#endif diff --git a/crypto/modes/src/asm/ghash_x86_64.S b/crypto/modes/src/asm/ghash_x86_64.S new file mode 100644 index 00000000..3a76915f --- /dev/null +++ b/crypto/modes/src/asm/ghash_x86_64.S @@ -0,0 +1,362 @@ +/* + * 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_GCM + +.file "ghash_x86_64.S" +.text + +.set INL, %xmm11 +.set INH, %xmm12 +.set INM, %xmm13 +.set HKEY3, %xmm14 +.set HKEY4, %xmm15 + +.set INPUT_XI, %rdi +.set HTABLE, %rsi +.set INPUT_IN, %rdx +.set LEN, %rcx +.set XI_L, %xmm0 +.set XI_H, %xmm1 +.set HKEY, %xmm2 + +.set IN_L, %xmm3 +.set IN_H, %xmm4 +.set IN_M, %xmm5 +.set HKEY2, %xmm6 +.set HKEY1_2, %xmm7 +.set TEMP1, %xmm8 +.set TEMP2, %xmm9 +.set MASK, %xmm10 + +.balign 16 +g_bswapMask: + .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +.size g_bswapMask, .-g_bswapMask +.balign 16 +g_polynomial: + .byte 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc2 +.size g_polynomial, .-g_polynomial +.balign 16 +g_64swapMask: + .byte 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 +.size g_64swapMask, .-g_64swapMask +.balign 16 +g_poly: + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2 +.size g_poly, .-g_poly + +/** + * Macro description: one block * H (128bit * 128bit) + * Input registers: xl, hKey, hKey12 + * Change registers: temp1 and temp2 + * Result register: xh, xl + */ +.macro GHASH_MUL128X128 xh, xl, hKey, hKey12, temp1, temp2 + vpshufd $0x4e, \xl, \temp1 + vpclmulqdq $0x11, \hKey, \xl, \xh + vpxor \xl, \temp1, \temp1 + + vpclmulqdq $0x00, \hKey, \xl, \xl + vpxor \xl, \xh, \temp2 + vpclmulqdq $0x00, \hKey12, \temp1, \temp1 + vpxor \temp2, \temp1, \temp1 + + vpslldq $8, \temp1, \temp2 + vpsrldq $8, \temp1, \temp1 + vpxor \temp1, \xh, \xh + vpxor \temp2, \xl, \xl +.endm + +/** + * Macro description: 256-bit large number reduction modulo g(x) + * Input register: xh, xl + * Change registers: temp1 and temp2 + * Result register: xl + */ +.macro REDUCTION_256BIT xh, xl, temp1, temp2, reducMask + vmovdqa \reducMask(%rip), \temp1 // g_poly + vpalignr $8, \xl, \xl, \temp2 // 1st phase of reduction + vpclmulqdq $0x10, \temp1, \xl, \xl + vpxor \temp2, \xl, \xl + + vpalignr $8, \xl, \xl, \temp2 // 2nd phase of reduction + vpclmulqdq $0x10, \temp1, \xl, \xl + vpxor \xh, \temp2, \temp2 + vpxor \temp2, \xl, \xl +.endm + +/** + * Function description: x86_64 hTable pre-computation table implementation (H has been transformed) + * Function prototype: void GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE], MODES_GCM_GF128 hTable[16]); + * Input register: + * rdi: uint8_t key[GCM_BLOCKSIZE] + * rsi: MODES_GCM_GF128 hTable[16] + * Change register: xmm0-xmm15 + * Function/Macro Call: + * GHASH_MUL128X128 + * REDUCTION_256BIT + */ +.align 32 +.globl GcmTableGen4bit +.type GcmTableGen4bit, %function +GcmTableGen4bit: +.cfi_startproc + vmovdqu (INPUT_XI), HKEY + vpshufb g_64swapMask(%rip), HKEY, HKEY + vpshufd $0x4e, HKEY, IN_L + vpshufd $0x55, HKEY, HKEY // broadcast carry bit + vmovdqa g_polynomial(%rip), IN_H + + vpsrlq $63, IN_L, IN_M + vpxor MASK, MASK, MASK + vpcmpgtd HKEY, MASK, HKEY + vpand IN_H, IN_M, IN_M + vpsllq $1, IN_L, IN_L + + vpshufd $0x4e, IN_M, IN_M + + vpand HKEY, IN_H, IN_H + vpor IN_M, IN_L, IN_L // H<<<=1 + vpxor IN_L, IN_H, HKEY // twisted H + + vmovdqu HKEY, (HTABLE) // store in H[0] + vpshufd $0x4e, HKEY, HKEY1_2 + vpxor HKEY, HKEY1_2, HKEY1_2 + vmovdqa HKEY, XI_L + /* xh, xl, hKey, hKey12, temp1, temp2 */ + GHASH_MUL128X128 XI_H, XI_L, HKEY, HKEY1_2, TEMP1, TEMP2 // calculate H^2 + /* xh, xl, temp1, temp2, reducMask */ + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + vmovdqa XI_L, HKEY2 + GHASH_MUL128X128 XI_H, XI_L, HKEY, HKEY1_2, TEMP1, TEMP2 // calculate H^3 + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + vmovdqa XI_L, HKEY3 + GHASH_MUL128X128 XI_H, XI_L, HKEY, HKEY1_2, TEMP1, TEMP2 // calculate H^4 + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + vmovdqa XI_L, HKEY4 + vmovdqu HKEY2, 0x10(HTABLE) // store H^2 in H[1] + vmovdqu HKEY3, 0x30(HTABLE) // store H^3 in H[3] + vmovdqu HKEY4, 0x40(HTABLE) // store H^4 in H[4] + + vpshufd $0x4e, HKEY2, TEMP1 + vpxor HKEY2, TEMP1, TEMP1 + vshufps $0x44, TEMP1, HKEY1_2, HKEY1_2 + vmovdqu HKEY1_2, 0x20(HTABLE) // store [H^2.h + H^2.l, H.h + H.l] in H[2] + + vpshufd $0x4e, HKEY3, TEMP1 + vpshufd $0x4e, HKEY4, TEMP2 + vpxor HKEY3, TEMP1, TEMP1 + vpxor HKEY4, TEMP2, TEMP2 + vshufps $0x44, TEMP2, TEMP1, HKEY1_2 + vmovdqu HKEY1_2, 0x50(HTABLE) // store [H^4.h + H^4.l, H^3.h + H^3.l] in H[5] + + vmovdqu 0x20(HTABLE), HKEY1_2 // reload [H^2.h + H^2.l, H.h + H.l] + GHASH_MUL128X128 XI_H, XI_L, HKEY, HKEY1_2, TEMP1, TEMP2 // calculate H^5, for aes-gcm + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + vmovdqa XI_L, HKEY3 + GHASH_MUL128X128 XI_H, XI_L, HKEY, HKEY1_2, TEMP1, TEMP2 // calculate H^6, for aes-gcm + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + vmovdqa XI_L, HKEY4 + vmovdqu HKEY3, 0x60(HTABLE) // store H^5 in H[6] + vmovdqu HKEY4, 0x70(HTABLE) // store H^6 in H[7] + vpshufd $0x4e, HKEY3, TEMP1 + vpshufd $0x4e, HKEY4, TEMP2 + vpxor HKEY3, TEMP1, TEMP1 + vpxor HKEY4, TEMP2, TEMP2 + vshufps $0x44, TEMP2, TEMP1, HKEY1_2 + vmovdqu HKEY1_2, 0x80(HTABLE) // store [H^6.h + H^6.l, H^5.h + H^5.l] in H[8] + + vpxor HKEY, HKEY, HKEY // clear hTable + vpxor HKEY1_2, HKEY1_2, HKEY1_2 + vpxor HKEY2, HKEY2, HKEY2 + vpxor HKEY3, HKEY3, HKEY3 + vpxor HKEY4, HKEY4, HKEY4 + ret +.cfi_endproc +.size GcmTableGen4bit, .-GcmTableGen4bit + +/** + * Function description: x86_64 ghash assembly acceleration implementation + * Function prototype: void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], + * const uint8_t *in, uint32_t inLen); + * Input register: + * rdi: uint8_t t[GCM_BLOCKSIZE] + * rsi: const MODES_GCM_GF128 hTable[16] + * rdx: const uint8_t *in + * rcx: uint32_t inLen + * Change register: xmm0-xmm15 + * Function/Macro Call: + * GHASH_MUL128X128 + * REDUCTION_256BIT // reduction modulo g(x) + */ +.align 32 +.globl GcmHashMultiBlock +.type GcmHashMultiBlock, %function +GcmHashMultiBlock: +.cfi_startproc + vmovdqa g_bswapMask(%rip), MASK + vmovdqu (INPUT_XI), XI_L + vmovdqu (HTABLE), HKEY + vmovdqu 0x20(HTABLE), HKEY1_2 + vpshufb MASK, XI_L, XI_L + + cmp $0x10, LEN + je .Lremain_1block + + vmovdqu 0x10(HTABLE), HKEY2 + cmp $0x40, LEN + jae .Lmul_4blocks + jmp .Lremain_Least_2blocks + +.align 32 +.Lmul_4blocks: + subq $0x40, LEN + + vmovdqu 0x30(INPUT_IN), IN_L // load In_3, In_2 + vmovdqu 0x20(INPUT_IN), INL + vpshufb MASK, IN_L, IN_L + vpshufb MASK, INL, INL + + vmovdqa IN_L, IN_H // H * In_3 + vpshufd $0x4e, IN_L, IN_M + vpxor IN_L, IN_M, IN_M + vpclmulqdq $0x00, HKEY, IN_L, IN_L + vpclmulqdq $0x11, HKEY, IN_H, IN_H + vpclmulqdq $0x00, HKEY1_2, IN_M, IN_M + + vmovdqa INL, INH // H^2 * In_2 + vpshufd $0x4e, INL, INM + vpxor INL, INM, INM + vpclmulqdq $0x00, HKEY2, INL, INL + vpclmulqdq $0x11, HKEY2, INH, INH + vpclmulqdq $0x10, HKEY1_2, INM, INM + vxorps INL, IN_L, IN_L // H * In_3 + H^2 * In_2 + vxorps INH, IN_H, IN_H + vxorps INM, IN_M, IN_M + + vmovdqu 0x30(HTABLE), HKEY3 + vmovdqu 0x40(HTABLE), HKEY4 + vmovdqu 0x50(HTABLE), HKEY1_2 + + vmovdqu 0x10(INPUT_IN), INL // load In_1, In_0 + vmovdqu (INPUT_IN), TEMP1 + vpshufb MASK, INL, INL + vpshufb MASK, TEMP1, TEMP1 + + vmovdqa INL, INH // H^3 * In_1 + vpshufd $0x4e, INL, INM + vpxor INL, INM, INM + vpclmulqdq $0x00, HKEY3, INL, INL + vpclmulqdq $0x11, HKEY3, INH, INH + vpclmulqdq $0x00, HKEY1_2, INM, INM + vxorps INL, IN_L, IN_L // H * In_3 + H^2 * In_2 + H^3 * In_1 + vxorps INH, IN_H, IN_H + vxorps INM, IN_M, IN_M + + vpxor TEMP1, XI_L, XI_L // (In_1 + Xi) + vmovdqa XI_L, XI_H + vpshufd $0x4e, XI_L, TEMP1 + vpxor XI_L, TEMP1, TEMP1 + vpclmulqdq $0x00, HKEY4, XI_L, XI_L // H^4 * (In_1 + Xi) + vpclmulqdq $0x11, HKEY4, XI_H, XI_H + vpclmulqdq $0x10, HKEY1_2, TEMP1, TEMP1 + vxorps IN_L, XI_L, XI_L // H * In_3 + H^2 * In_2 + H^3 * In_1 + H^4 * (In_1 + Xi) + vxorps IN_H, XI_H, XI_H + vxorps IN_M, TEMP1, TEMP1 + + vpxor XI_L, TEMP1, TEMP1 + vpxor XI_H, TEMP1, TEMP1 + vmovdqa TEMP1, TEMP2 + vpslldq $8, TEMP1, TEMP1 + vpsrldq $8, TEMP2, TEMP2 + vpxor TEMP1, XI_L, XI_L + vpxor TEMP2, XI_H, XI_H + + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + cmp $0x00, LEN + jz .Lend // finshed all blocks + leaq 0x40(INPUT_IN), INPUT_IN + vmovdqu 0x20(HTABLE), HKEY1_2 + cmp $0x40, LEN + jae .Lmul_4blocks + cmp $0x20, LEN + jae .Lremain_Least_2blocks + jmp .Lremain_1block + +.align 32 +.Lremain_Least_2blocks: + subq $0x20, LEN + vmovdqu 0x10(INPUT_IN), IN_L // loda (4 * i) + 1 or 2 block + vmovdqu (INPUT_IN), TEMP1 + vpshufb MASK, IN_L, IN_L + vpshufb MASK, TEMP1, TEMP1 + vpxor TEMP1, XI_L, XI_L + + vmovdqa IN_L, IN_H + vpshufd $0x4e, IN_L, IN_M + vpxor IN_L, IN_M, IN_M + vpclmulqdq $0x00, HKEY, IN_L, IN_L + vpclmulqdq $0x11, HKEY, IN_H, IN_H + vpclmulqdq $0x00, HKEY1_2, IN_M, IN_M + + vmovdqa XI_L, XI_H + vpshufd $0x4e, XI_L, TEMP1 + vpxor XI_L, TEMP1, TEMP1 + vpclmulqdq $0x00, HKEY2, XI_L, XI_L + vpclmulqdq $0x11, HKEY2, XI_H, XI_H + vpclmulqdq $0x10, HKEY1_2, TEMP1, TEMP1 + vxorps IN_L, XI_L, XI_L + vxorps IN_H, XI_H, XI_H + vxorps IN_M, TEMP1, TEMP1 + + vpxor XI_L, TEMP1, TEMP1 + vpxor XI_H, TEMP1, TEMP1 + vmovdqa TEMP1, TEMP2 + vpslldq $8, TEMP1, TEMP1 + vpsrldq $8, TEMP2, TEMP2 + vpxor TEMP1, XI_L, XI_L + vpxor TEMP2, XI_H, XI_H + + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + cmp $0x00, LEN + jz .Lend + leaq 0x20(INPUT_IN), INPUT_IN + +.align 32 +.Lremain_1block: + subq $0x10, LEN + vmovdqu (INPUT_IN), TEMP1 + vpshufb MASK, TEMP1, TEMP1 + vpxor TEMP1, XI_L, XI_L + + GHASH_MUL128X128 XI_H, XI_L, HKEY, HKEY1_2, TEMP1, TEMP2 + REDUCTION_256BIT XI_H, XI_L, TEMP1, TEMP2, g_poly + +.Lend: + vpshufb MASK, XI_L, XI_L + vmovdqu XI_L, (INPUT_XI) + vpxor HKEY, HKEY, HKEY // clear hTable + vpxor HKEY1_2, HKEY1_2, HKEY1_2 + vpxor HKEY2, HKEY2, HKEY2 + vpxor HKEY3, HKEY3, HKEY3 + vpxor HKEY4, HKEY4, HKEY4 + ret +.cfi_endproc +.size GcmHashMultiBlock, .-GcmHashMultiBlock + +#endif diff --git a/crypto/modes/src/asm_aes_cbc.c b/crypto/modes/src/asm_aes_cbc.c new file mode 100644 index 00000000..515e3aae --- /dev/null +++ b/crypto/modes/src/asm_aes_cbc.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CBC) + +#include "bsl_err_internal.h" +#include "crypt_aes.h" +#include "modes_local.h" +#include "crypt_errno.h" +#include "crypt_modes_cbc.h" + +int32_t AES_CBC_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((len & 0x0f) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + (void)CRYPT_AES_CBC_Encrypt(ctx->ciphCtx, in, out, len, ctx->iv); + return CRYPT_SUCCESS; +} + +int32_t AES_CBC_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((len & 0x0f) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + (void)CRYPT_AES_CBC_Decrypt(ctx->ciphCtx, in, out, len, ctx->iv); + return CRYPT_SUCCESS; +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_aes_ccm.c b/crypto/modes/src/asm_aes_ccm.c new file mode 100644 index 00000000..c0cac9c3 --- /dev/null +++ b/crypto/modes/src/asm_aes_ccm.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CCM) + +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_modes.h" +#include "asm_aes_ccm.h" +#include "ccm_core.h" +#include "crypt_modes_ccm.h" + +static int32_t AesCcmBlocks(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + XorCryptData data; + data.in = in; + data.out = out; + data.ctr = ctx->last; + data.tag = ctx->tag; + + uint8_t countLen = (ctx->nonce[0] & 0x07) + 1; + uint32_t dataLen = len; + void (*xor)(XorCryptData *data, uint32_t len) = enc ? XorInEncrypt : XorInDecrypt; + void (*crypt_asm)(void *key, uint8_t *nonce, const uint8_t *in, uint8_t *out, uint32_t len) = + enc ? AesCcmEncryptAsm : AesCcmDecryptAsm; + crypt_asm(ctx->ciphCtx, ctx->nonce, data.in, data.out, dataLen); + uint32_t tmpOffset = dataLen & 0xfffffff0; + dataLen &= 0x0fU; + data.in += tmpOffset; + data.out += tmpOffset; + if (dataLen > 0) { // data processing with less than 16 bytes + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->nonce, ctx->last, CCM_BLOCKSIZE); + xor(&data, dataLen); + MODE_IncCounter(ctx->nonce + CCM_BLOCKSIZE - countLen, countLen); // counter +1 + } + return CRYPT_SUCCESS; +} + +int32_t MODES_AES_CCM_Encrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return CcmCrypt(ctx, in, out, len, true, AesCcmBlocks); +} + +int32_t MODES_AES_CCM_Decrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return CcmCrypt(ctx, in, out, len, false, AesCcmBlocks); +} + +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_aes_ccm.h b/crypto/modes/src/asm_aes_ccm.h new file mode 100644 index 00000000..337ee3b0 --- /dev/null +++ b/crypto/modes/src/asm_aes_ccm.h @@ -0,0 +1,43 @@ +/* + * 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 ASM_AES_CCM_H +#define ASM_AES_CCM_H + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CCM) + +#include "crypt_utils.h" +#include "crypt_modes.h" +#include "crypt_modes_ccm.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void AesCcmEncryptAsm(void *key, uint8_t *nonce, const uint8_t *in, uint8_t *out, uint32_t len); +void AesCcmDecryptAsm(void *key, uint8_t *nonce, const uint8_t *in, uint8_t *out, uint32_t len); +void XorInDecrypt(XorCryptData *data, uint32_t len); +void XorInEncrypt(XorCryptData *data, uint32_t len); +void XorInEncryptBlock(XorCryptData *data); +void XorInDecryptBlock(XorCryptData *data); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif + +#endif diff --git a/crypto/modes/src/asm_aes_cfb.c b/crypto/modes/src/asm_aes_cfb.c new file mode 100644 index 00000000..38084450 --- /dev/null +++ b/crypto/modes/src/asm_aes_cfb.c @@ -0,0 +1,88 @@ +/* + * 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 "bsl_err_internal.h" +#include "crypt_aes.h" +#include "crypt_errno.h" +#include "crypt_modes_cfb.h" + +/* Decrypt the 128-bit CFB. Here, len indicates the number of bytes to be processed. */ +static int32_t CRYPT_AES_CFB16_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx->modeCtx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + const uint8_t *input = in; + uint8_t *output = out; + uint8_t *tmp = ctx->modeCtx->buf; + uint32_t blockSize = ctx->modeCtx->blockSize; + uint32_t left = len; + uint32_t i, k; + + // If the remaining encryption iv is not used up last time, use the part to perform exclusive OR. + while (left > 0 && ctx->modeCtx->offset > 0) { + uint8_t tmpInput = *input; // To support the same address in and out + *(output++) = ctx->modeCtx->iv[ctx->modeCtx->offset] ^ *(input++); + // Write the iv to ciphertext to prepare for the next round of encryption. + ctx->modeCtx->iv[ctx->modeCtx->offset] = tmpInput; + ctx->modeCtx->offset = (ctx->modeCtx->offset + 1) % blockSize; + left--; + } + + if (left >= blockSize) { + uint32_t processedLen = left - (left % blockSize); + (void)CRYPT_AES_CFB_Decrypt(ctx->modeCtx->ciphCtx, input, output, processedLen, ctx->modeCtx->iv); + UPDATE_VALUES(left, input, output, processedLen); + } + + if (left > 0) { + // encrypt the IV + int32_t ret = ctx->modeCtx->ciphMeth->encrypt(ctx->modeCtx->ciphCtx, ctx->modeCtx->iv, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + for (i = 0, k = 0; k < left; k++, i++) { + // Write the iv to ciphertext to prepare for the next round of encryption. + ctx->modeCtx->iv[i] = input[k]; + output[k] = input[k] ^ tmp[k]; + } + + while (i < blockSize) { + ctx->modeCtx->iv[i++] = tmp[k++]; + } + ctx->modeCtx->offset = (uint8_t)left; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_AES_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || ctx->modeCtx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->feedbackBits == 128) { // feedbackBits 128 has assembly optimization + return CRYPT_AES_CFB16_Decrypt(ctx, in, out, len); + } else { // no optimization + return MODE_CFB_Decrypt(ctx, in, out, len); + } +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_aes_ctr.c b/crypto/modes/src/asm_aes_ctr.c new file mode 100644 index 00000000..24068b49 --- /dev/null +++ b/crypto/modes/src/asm_aes_ctr.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CTR) + +#include "bsl_err_internal.h" +#include "crypt_aes.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_modes_ctr.h" + +int32_t AES_CTR_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + // The ctx, in, and out pointers have been determined at the EAL layer and are not determined again. + if (ctx->ciphCtx == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t offset = MODE_CTR_LastHandle(ctx, in, out, len); + uint32_t left = len - offset; + const uint8_t *tmpIn = in + offset; + uint8_t *tmpOut = out + offset; + + uint32_t blockSize = ctx->blockSize; // ctr supports only 16-byte block size + uint32_t blocks, beCtr32; + while (left >= blockSize) { + blocks = left >> 4; // Shift rightwards by 4 bytes to obtain the number of blocks. + beCtr32 = GET_UINT32_BE(ctx->iv, 12); // offset of 12 bytes, it is used to obtain the lower 32 bits of IV + beCtr32 += blocks; + if (beCtr32 < blocks) { + blocks -= beCtr32; + beCtr32 = 0; + } + // Shift leftwards by 4 bytes to obtain the length of the data involved in the calculation. + uint32_t calLen = blocks << 4; + (void)CRYPT_AES_CTR_Encrypt(ctx->ciphCtx, tmpIn, tmpOut, calLen, ctx->iv); + left -= calLen; + tmpIn += calLen; + tmpOut += calLen; + if (beCtr32 == 0) { + // 16 - 4, the lower 32 bits are carried, and the upper 12 bytes are increased by 1. + MODE_IncCounter(ctx->iv, blockSize - 4); + } + } + MODE_CTR_RemHandle(ctx, tmpIn, tmpOut, left); + return CRYPT_SUCCESS; +} + +int32_t AES_CTR_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return AES_CTR_EncryptBlock(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_aes_ecb.c b/crypto/modes/src/asm_aes_ecb.c new file mode 100644 index 00000000..7e6a9cb3 --- /dev/null +++ b/crypto/modes/src/asm_aes_ecb.c @@ -0,0 +1,51 @@ +/* + * 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 "bsl_err_internal.h" +#include "crypt_aes.h" +#include "crypt_errno.h" +#include "crypt_modes_ecb.h" + +int32_t AES_ECB_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((len & 0x0f) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + (void)CRYPT_AES_ECB_Encrypt(ctx->ciphCtx, in, out, len); + return CRYPT_SUCCESS; +} + +int32_t AES_ECB_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((len & 0x0f) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + (void)CRYPT_AES_ECB_Decrypt(ctx->ciphCtx, in, out, len); + return CRYPT_SUCCESS; +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_cbc.c b/crypto/modes/src/asm_sm4_cbc.c new file mode 100644 index 00000000..f52d8dbf --- /dev/null +++ b/crypto/modes/src/asm_sm4_cbc.c @@ -0,0 +1,41 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_CBC) + +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_sm4.h" +#include "crypt_modes_cbc.h" + +int32_t MODE_SM4_CBC_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_CBC_Encrypt(ctx->ciphCtx, in, out, len, ctx->iv); +} + +int32_t MODE_SM4_CBC_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_CBC_Decrypt(ctx->ciphCtx, in, out, len, ctx->iv); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_cfb.c b/crypto/modes/src/asm_sm4_cfb.c new file mode 100644 index 00000000..486232db --- /dev/null +++ b/crypto/modes/src/asm_sm4_cfb.c @@ -0,0 +1,67 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_CFB) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_errno.h" +#include "crypt_modes_cfb.h" + +int32_t MODES_SM4_CFB_SetEncryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return MODES_SM4_SetEncryptKey(ctx->modeCtx, key, len); +} + +int32_t MODES_SM4_CFB_SetDecryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return MODES_SM4_SetDecryptKey(ctx->modeCtx, key, len); +} + +int32_t MODE_SM4_CFB_Encrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || ctx->modeCtx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->feedbackBits == 128) { // feedbackBits value of 128 has assembly optimizations + return CRYPT_SM4_CFB_Encrypt(ctx->modeCtx->ciphCtx, in, out, len, ctx->modeCtx->iv, &ctx->modeCtx->offset); + } else { // no assembly optimization + return MODE_CFB_Encrypt(ctx, in, out, len); + } +} + +int32_t MODE_SM4_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || ctx->modeCtx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->feedbackBits == 128) { // feedbackBits value of 128 has assembly optimizations + return CRYPT_SM4_CFB_Decrypt(ctx->modeCtx->ciphCtx, in, out, len, ctx->modeCtx->iv, &ctx->modeCtx->offset); + } else { // no assembly optimization + return MODE_CFB_Decrypt(ctx, in, out, len); + } +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_ctr.c b/crypto/modes/src/asm_sm4_ctr.c new file mode 100644 index 00000000..f7916c8c --- /dev/null +++ b/crypto/modes/src/asm_sm4_ctr.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_SM4) && defined(HITLS_CRYPTO_CTR) + +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_sm4.h" +#include "crypt_modes_ctr.h" + +int32_t MODE_SM4_CTR_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t offset = MODE_CTR_LastHandle(ctx, in, out, len); + uint32_t left = len - offset; + const uint8_t *tmpIn = in + offset; + uint8_t *tmpOut = out + offset; + + uint32_t blockSize = ctx->blockSize; + uint32_t blocks, beCtr32; + while (left >= blockSize) { + blocks = left >> 4; + beCtr32 = GET_UINT32_BE(ctx->iv, 12); + beCtr32 += blocks; + if (beCtr32 < blocks) { + blocks -= beCtr32; + beCtr32 = 0; + } + + uint32_t calLen = blocks << 4; + (void)CRYPT_SM4_CTR_Encrypt(ctx->ciphCtx, tmpIn, tmpOut, calLen / ctx->blockSize, ctx->iv); + left -= calLen; + tmpIn += calLen; + tmpOut += calLen; + if (beCtr32 == 0) { + // 16 - 4, The lower 32 bits are carried, and the upper 12 bytes are increased by 1. + MODE_IncCounter(ctx->iv, blockSize - 4); + } + } + MODE_CTR_RemHandle(ctx, tmpIn, tmpOut, left); + return CRYPT_SUCCESS; +} + +int32_t MODE_SM4_CTR_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_SM4_CTR_Encrypt(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_ecb.c b/crypto/modes/src/asm_sm4_ecb.c new file mode 100644 index 00000000..0e421c77 --- /dev/null +++ b/crypto/modes/src/asm_sm4_ecb.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM4 + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_errno.h" +#include "crypt_modes.h" +#include "crypt_modes_ecb.h" + +int32_t MODES_SM4_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_SetDecryptKey(ctx->ciphCtx, key, len); +} + +#ifdef HITLS_CRYPTO_ECB +int32_t MODE_SM4_ECB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_ECB_Encrypt(ctx->ciphCtx, in, out, len); +} + +int32_t MODE_SM4_ECB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_ECB_Decrypt(ctx->ciphCtx, in, out, len); +} +#endif +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_gcm.c b/crypto/modes/src/asm_sm4_gcm.c new file mode 100644 index 00000000..07cea22a --- /dev/null +++ b/crypto/modes/src/asm_sm4_gcm.c @@ -0,0 +1,122 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_GCM) + +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_sm4.h" +#include "modes_local.h" +#include "crypt_modes_gcm.h" + +int32_t MODES_SM4_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint8_t gcmKey[GCM_BLOCKSIZE] = { 0 }; + MODES_GCM_Clean(ctx); + int32_t ret = CRYPT_SM4_SetEncryptKey(ctx->ciphCtx, key, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, gcmKey, gcmKey, GCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + GcmTableGen4bit(gcmKey, ctx->hTable); + ctx->tagLen = 16; + BSL_SAL_CleanseData(gcmKey, sizeof(gcmKey)); + return CRYPT_SUCCESS; +} + +static void GcmRemHandle(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE); + uint32_t i; + if (enc) { + for (i = 0; i < len; i++) { + out[i] = in[i] ^ ctx->last[i]; + ctx->remCt[i] = out[i]; + } + } else { + for (i = 0; i < len; i++) { + ctx->remCt[i] = in[i]; + out[i] = in[i] ^ ctx->last[i]; + } + } + + uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); + ctr++; + PUT_UINT32_BE(ctr, ctx->iv, 12); + ctx->lastLen = GCM_BLOCKSIZE - len; +} + +int32_t MODES_SM4_GCM_EncryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + ctx->plaintextLen += len; + uint32_t lastLen = LastHandle(ctx, in, out, len, true); + // Data processing is complete. Exit. + if (lastLen == len) { + return CRYPT_SUCCESS; + } + const uint8_t *tmpIn = in + lastLen; + uint8_t *tmpOut = out + lastLen; + uint32_t clen = len - lastLen; + if (clen >= GCM_BLOCKSIZE) { + uint32_t calLen = clen & 0xfffffff0; + (void)CRYPT_SM4_CTR_Encrypt(ctx->ciphCtx, tmpIn, tmpOut, calLen / GCM_BLOCKSIZE, ctx->iv); + GcmHashMultiBlock(ctx->ghash, ctx->hTable, tmpOut, calLen); + clen -= calLen; + tmpIn += calLen; + tmpOut += calLen; + } + if (clen > 0) { // tail processing + GcmRemHandle(ctx, tmpIn, tmpOut, clen, true); + } + return CRYPT_SUCCESS; +} + +int32_t MODES_SM4_GCM_DecryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + ctx->plaintextLen += len; + uint32_t lastLen = LastHandle(ctx, in, out, len, false); + // Data processing is complete. Exit. + if (lastLen == len) { + return CRYPT_SUCCESS; + } + const uint8_t *tmpIn = in + lastLen; + uint8_t *tmpOut = out + lastLen; + uint32_t clen = len - lastLen; + if (clen >= GCM_BLOCKSIZE) { + uint32_t calLen = clen & 0xfffffff0; + GcmHashMultiBlock(ctx->ghash, ctx->hTable, tmpIn, calLen); + (void)CRYPT_SM4_CTR_Encrypt(ctx->ciphCtx, tmpIn, tmpOut, calLen / GCM_BLOCKSIZE, ctx->iv); + tmpIn += calLen; + tmpOut += calLen; + clen -= calLen; + } + if (clen > 0) { // tail processing + GcmRemHandle(ctx, tmpIn, tmpOut, clen, false); + } + return CRYPT_SUCCESS; +} +#endif diff --git a/crypto/modes/src/asm_sm4_ofb_armv8.c b/crypto/modes/src/asm_sm4_ofb_armv8.c new file mode 100644 index 00000000..a62fb135 --- /dev/null +++ b/crypto/modes/src/asm_sm4_ofb_armv8.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_SM4) && defined(HITLS_CRYPTO_OFB) + +#include "crypt_errno.h" +#include "crypt_modes_ofb.h" + +int32_t MODE_SM4_OFB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + return CRYPT_NULL_INPUT; + } + return MODE_OFB_Crypt(ctx, in, out, len); +} + +int32_t MODE_SM4_OFB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + return CRYPT_NULL_INPUT; + } + return MODE_OFB_Crypt(ctx, in, out, len); +} +#endif diff --git a/crypto/modes/src/asm_sm4_ofb_x86_64.c b/crypto/modes/src/asm_sm4_ofb_x86_64.c new file mode 100644 index 00000000..fd1ea8aa --- /dev/null +++ b/crypto/modes/src/asm_sm4_ofb_x86_64.c @@ -0,0 +1,41 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_OFB) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_errno.h" +#include "crypt_modes_ofb.h" + +int32_t MODE_SM4_OFB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_OFB_Encrypt(ctx->ciphCtx, in, out, len, ctx->iv, &ctx->offset); +} + +int32_t MODE_SM4_OFB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_OFB_Decrypt(ctx->ciphCtx, in, out, len, ctx->iv, &ctx->offset); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_setkey.c b/crypto/modes/src/asm_sm4_setkey.c new file mode 100644 index 00000000..5ec6e72a --- /dev/null +++ b/crypto/modes/src/asm_sm4_setkey.c @@ -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_CRYPTO_SM4 + +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_sm4.h" +#include "crypt_modes.h" + +int32_t MODES_SM4_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_SetEncryptKey(ctx->ciphCtx, key, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/asm_sm4_xts.c b/crypto/modes/src/asm_sm4_xts.c new file mode 100644 index 00000000..6adc1a0a --- /dev/null +++ b/crypto/modes/src/asm_sm4_xts.c @@ -0,0 +1,68 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_XTS) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_errno.h" +#include "crypt_modes_xts.h" + +void MODES_SM4_XTS_Clean(MODE_XTS_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + CRYPT_SM4_XTS_Clean(ctx->ciphCtx); + return; +} + +int32_t MODES_SM4_XTS_SetEncryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_XTS_SetEncryptKey(ctx->ciphCtx, key, len); +} + +int32_t MODES_SM4_XTS_SetDecryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_XTS_SetDecryptKey(ctx->ciphCtx, key, len); +} + +int32_t MODES_SM4_XTS_Encrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_XTS_Encrypt(ctx->ciphCtx, in, out, len, ctx->tweak); +} + +int32_t MODES_SM4_XTS_Decrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SM4_XTS_Decrypt(ctx->ciphCtx, in, out, len, ctx->tweak); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/ccm_core.h b/crypto/modes/src/ccm_core.h new file mode 100644 index 00000000..a8d313ab --- /dev/null +++ b/crypto/modes/src/ccm_core.h @@ -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 CCM_CORE_H +#define CCM_CORE_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CCM + +#include "crypt_modes_ccm.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef int32_t (*CcmCore)(MODES_CCM_Ctx *, const uint8_t *, uint8_t *, uint32_t, bool); + +int32_t CcmCrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc, const CcmCore func); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif +#endif \ No newline at end of file diff --git a/crypto/modes/src/ghash_core.h b/crypto/modes/src/ghash_core.h new file mode 100644 index 00000000..27a25514 --- /dev/null +++ b/crypto/modes/src/ghash_core.h @@ -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. + */ +#ifndef GHASH_CORE_H +#define GHASH_CORE_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_GCM + +#include "crypt_modes_gcm.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void GcmTableGen4bitAsm(const MODES_GCM_GF128 *H, MODES_GCM_GF128 hTable[16]); + +void GcmMultH4bitAsm(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16]); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif +#endif \ No newline at end of file diff --git a/crypto/modes/src/modes.c b/crypto/modes/src/modes.c new file mode 100644 index 00000000..d7d9cf28 --- /dev/null +++ b/crypto/modes/src/modes.c @@ -0,0 +1,160 @@ +/* + * 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_MODES + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_modes.h" + + +int32_t MODE_InitCtx(MODE_CipherCtx *ctx, const EAL_CipherMethod *method) +{ + if (ctx == NULL || method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + ctx->ciphCtx = BSL_SAL_Malloc(method->ctxSize); + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)memset_s(ctx->ciphCtx, method->ctxSize, 0, method->ctxSize); + + ctx->blockSize = method->blockSize; + ctx->ciphMeth = method; + ctx->algId = method->algId; + ctx->offset = 0; + + return CRYPT_SUCCESS; +} + +void MODE_DeInitCtx(MODE_CipherCtx *ctx) +{ + if (ctx == NULL || ctx->ciphMeth == NULL || ctx->ciphMeth->clean == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + + ctx->ciphMeth->clean(ctx->ciphCtx); + BSL_SAL_FREE(ctx->ciphCtx); + ctx->ciphMeth = NULL; +} + +int32_t MODE_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len) +{ + // The ctx and key have been checked at the EAL layer and will not be checked again here. + // The keyMethod will support registration in the future. Therefore, this check is added. + if (ctx->ciphMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, key, len); +} + +int32_t MODE_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len) +{ + // The ctx and key have been checked at the EAL layer and will not be checked again here. + // The keyMethod will support registration in the future. Therefore, this check is added. + if (ctx->ciphMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ctx->ciphMeth->setDecryptKey(ctx->ciphCtx, key, len); +} + +int32_t MODE_SetIv(MODE_CipherCtx *ctx, uint8_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len != ctx->blockSize) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_IVLEN_ERROR); + return CRYPT_MODES_IVLEN_ERROR; + } + + if (memcpy_s(ctx->iv, MODES_MAX_IV_LENGTH, (uint8_t*)val, len) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + ctx->offset = 0; // If the IV value is changed, the original offset is useless. + return CRYPT_SUCCESS; +} + +int32_t MODE_GetIv(MODE_CipherCtx *ctx, uint8_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + uint32_t ivLen = ctx->blockSize; + + if (len != ivLen) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + + if (memcpy_s(val, len, ctx->iv, ivLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_DefaultCtrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, uint32_t *val, uint32_t len) +{ + if (ctx->ciphMeth == NULL || ctx->ciphMeth->ctrl == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TYPE_ERROR); + return CRYPT_MODES_CTRL_TYPE_ERROR; + } + return ctx->ciphMeth->ctrl(ctx->ciphCtx, opt, val, len); +} + +// support: finally do the MODE_DefaultCtrl, but not all MODEs have assembly optimizations +int32_t MODE_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + switch (opt) { + case CRYPT_CTRL_SET_IV: + return MODE_SetIv(ctx, (uint8_t *)val, len); + case CRYPT_CTRL_GET_IV: + return MODE_GetIv(ctx, (uint8_t *)val, len); + default: + return MODE_DefaultCtrl(ctx, opt, val, len); + } +} + +void MODE_Clean(MODE_CipherCtx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx->buf), MODES_MAX_IV_LENGTH); + BSL_SAL_CleanseData((void *)(ctx->iv), MODES_MAX_IV_LENGTH); + ctx->ciphMeth->clean(ctx->ciphCtx); + ctx->offset = 0; +} +#endif // HITLS_CRYPTO_MODES diff --git a/crypto/modes/src/modes_cbc.c b/crypto/modes/src/modes_cbc.c new file mode 100644 index 00000000..6b44421a --- /dev/null +++ b/crypto/modes/src/modes_cbc.c @@ -0,0 +1,132 @@ +/* + * 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_CBC + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_modes.h" +#include "crypt_modes_cbc.h" + +#define CBC_UPDATE_VALUES(l, i, o, len) \ + do { \ + (l) -= (len); \ + (i) += (len); \ + (o) += (len); \ + } while (false) + +int32_t MODE_CBC_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + uint32_t blockSize = ctx->blockSize; + int32_t ret; + uint8_t *iv = ctx->iv; + uint8_t *tmp = ctx->buf; + uint32_t left = len; + const uint8_t *input = in; + uint8_t *output = out; + // The ctx, in, and out pointers have been determined at the EAL layer and are not determined again. + if ((left % blockSize) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + + while (left >= blockSize) { + /* Plaintext XOR IV. BlockSize must be an integer multiple of 4 bytes. */ + DATA32_XOR(input, iv, tmp, blockSize); + + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, tmp, output, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* The current encryption result is used as the next IV value. */ + iv = output; + + /* Offset length is the size of integer multiple blocks */ + CBC_UPDATE_VALUES(left, input, output, blockSize); + } + + if (memcpy_s(ctx->iv, MODES_MAX_IV_LENGTH, iv, blockSize) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_SECUREC_FAIL; + } + + return CRYPT_SUCCESS; +} + +int32_t MODE_CBC_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + const uint8_t *iv = ctx->iv; + uint8_t *tmp = ctx->buf; + uint32_t blockSize = ctx->blockSize; + uint32_t left = len; + uint8_t *output = out; + uint8_t tmpChar; + const uint8_t *input = in; + + // The ctx, in, and out pointers have been determined at the EAL layer and are not determined again. + if ((left % blockSize) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + + // In the case where the input and output are at the same address, + // the judgment should be placed outside the while loop. Otherwise, the performance will be affected. + if (in != out) { + while (left >= blockSize) { + int32_t ret = ctx->ciphMeth->decrypt(ctx->ciphCtx, input, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* The ciphertext is used as the next IV value. BlockSize must be an integer multiple of 4 bytes. */ + DATA32_XOR(iv, tmp, output, blockSize); + iv = input; + + CBC_UPDATE_VALUES(left, input, output, blockSize); + } + if (iv != ctx->iv) { + (void)memcpy_s(ctx->iv, MODES_MAX_IV_LENGTH, iv, blockSize); + } + } else { + while (left >= blockSize) { + int32_t ret = ctx->ciphMeth->decrypt(ctx->ciphCtx, input, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + for (uint32_t i = 0; i < blockSize; i++) { + tmpChar = input[i]; + output[i] = tmp[i] ^ ctx->iv[i]; + ctx->iv[i] = tmpChar; + } + + CBC_UPDATE_VALUES(left, input, output, blockSize); + } + } + + return CRYPT_SUCCESS; +} + +void MODE_CBC_Clean(MODE_CipherCtx *ctx) +{ + MODE_Clean(ctx); +} +#endif // HITLS_CRYPTO_CBC diff --git a/crypto/modes/src/modes_ccm.c b/crypto/modes/src/modes_ccm.c new file mode 100644 index 00000000..7bb42079 --- /dev/null +++ b/crypto/modes/src/modes_ccm.c @@ -0,0 +1,556 @@ +/* + * 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_CCM + +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_modes.h" +#include "ccm_core.h" +#include "crypt_modes_ccm.h" + + +int32_t MODES_CCM_InitCtx(MODES_CCM_Ctx *ctx, const struct EAL_CipherMethod *m) +{ + if (ctx == NULL || m == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(MODES_CCM_Ctx), 0, sizeof(MODES_CCM_Ctx)); + ctx->ciphMeth = m; + ctx->ciphCtx = BSL_SAL_Malloc(m->ctxSize); + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +void MODES_CCM_DeinitCtx(MODES_CCM_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData(ctx->ciphCtx, ctx->ciphMeth->ctxSize); + BSL_SAL_FREE(ctx->ciphCtx); + BSL_SAL_CleanseData(ctx, sizeof(MODES_CCM_Ctx)); +} + +void MODES_CCM_Clean(MODES_CCM_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + void *ciphCtx = ctx->ciphCtx; + const EAL_CipherMethod *ciphMeth = ctx->ciphMeth; + BSL_SAL_CleanseData((void *)(ctx->ciphCtx), ctx->ciphMeth->ctxSize); + BSL_SAL_CleanseData((void *)(ctx), sizeof(MODES_CCM_Ctx)); + + ctx->ciphCtx = ciphCtx; + ctx->ciphMeth = ciphMeth; +} + +int32_t MODES_CCM_SetKey(MODES_CCM_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + MODES_CCM_Clean(ctx); + ctx->tagLen = 16; + return ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, key, len); +} + +void XorInEncrypt(XorCryptData *data, uint32_t len) +{ + uint32_t i; + for (i = 0; i < len; i++) { + data->tag[i] ^= data->in[i]; + data->out[i] = data->in[i] ^ data->ctr[i]; + } +} + +void XorInEncryptBlock(XorCryptData *data) +{ + DATA64_XOR(data->in, data->tag, data->tag, CCM_BLOCKSIZE); + DATA64_XOR(data->in, data->ctr, data->out, CCM_BLOCKSIZE); +} + +void XorInDecrypt(XorCryptData *data, uint32_t len) +{ + uint32_t i; + // Decryption + for (i = 0; i < len; i++) { + data->out[i] = data->in[i] ^ data->ctr[i]; + data->tag[i] ^= data->out[i]; + } +} + +void XorInDecryptBlock(XorCryptData *data) +{ + DATA64_XOR(data->in, data->ctr, data->out, CCM_BLOCKSIZE); + DATA64_XOR(data->out, data->tag, data->tag, CCM_BLOCKSIZE); +} + +// Process the remaining data in the last update. +static uint32_t LastHandle(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + uint32_t lastLen = (ctx->lastLen < len) ? ctx->lastLen : len; + if (ctx->lastLen > 0) { + XorCryptData data; + data.in = in; + data.out = out; + data.ctr = &(ctx->last[CCM_BLOCKSIZE - ctx->lastLen]); + data.tag = &(ctx->tag[CCM_BLOCKSIZE - ctx->lastLen]); + if (enc) { + XorInEncrypt(&data, lastLen); + } else { + XorInDecrypt(&data, lastLen); + } + // Refresh the remaining length. + // The judgment of the function entry ensures that lastLen does not exceed ctx->lastLen, + // and this forcible transition does not occur truncation. + ctx->lastLen -= (uint8_t)lastLen; + } + return lastLen; +} + +static void RefreshNonce(MODES_CCM_Ctx *ctx) +{ + if ((ctx->nonce[0] & (~0x07)) != 0) { + /** + * RFC_3610-2.3 + * Bit Number Contents + * ---------- ---------------------- + * 7 Reserved (always zero) + * 6 Reserved (always zero) + * 5 ... 3 Zero + * 2 ... 0 L' + */ + ctx->nonce[0] &= 0x07; + + /** + * RFC_3610-2.3 + * Octet Number Contents + * ------------ --------- + * 0 Flags + * 1 ... 15-L Nonce N + * 16-L ... 15 Counter i + */ + uint8_t i; + uint8_t l = ctx->nonce[0] + 1; + for (i = 1; i < l; i++) { + ctx->nonce[CCM_BLOCKSIZE - 1 - i] = 0; + } + /** + * RFC_3610-2.3 + * The message is encrypted by XORing the octets of message m with the + * first l(m) octets of the concatenation of S_1, S_2, S_3, ... . Note + * that S_0 is not used to encrypt the message. + */ + ctx->nonce[CCM_BLOCKSIZE - 1] = 1; + } +} + +static int32_t TagInit(MODES_CCM_Ctx *ctx) +{ + if (ctx->tagInit == 0) { + int32_t ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->nonce, ctx->tag, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ctx->tagInit = 1; + } + return CRYPT_SUCCESS; +} + +static int32_t CcmBlocks(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + XorCryptData data; + data.in = in; + data.out = out; + data.ctr = ctx->last; + data.tag = ctx->tag; + + uint8_t countLen = (ctx->nonce[0] & 0x07) + 1; + uint32_t dataLen = len; + void (*xorBlock)(XorCryptData *data) = enc ? XorInEncryptBlock : XorInDecryptBlock; + void (*xor)(XorCryptData *data, uint32_t len) = enc ? XorInEncrypt : XorInDecrypt; + while (dataLen >= CCM_BLOCKSIZE) { // process the integer multiple of 16bytes data + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->nonce, ctx->last, CCM_BLOCKSIZE); + xorBlock(&data); + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->tag, ctx->tag, CCM_BLOCKSIZE); + MODE_IncCounter(ctx->nonce + CCM_BLOCKSIZE - countLen, countLen); // counter +1 + dataLen -= CCM_BLOCKSIZE; + data.in += CCM_BLOCKSIZE; + data.out += CCM_BLOCKSIZE; + } + if (dataLen > 0) { // process the integer multiple of 16bytes data + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->nonce, ctx->last, CCM_BLOCKSIZE); + xor(&data, dataLen); + MODE_IncCounter(ctx->nonce + CCM_BLOCKSIZE - countLen, countLen); // counter +1 + } + return CRYPT_SUCCESS; +} + +// Enc: true for encryption and false for decryption. +int32_t CcmCrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc, const CcmCore func) +{ + if (ctx == NULL || ctx->ciphCtx == NULL || in == NULL || out == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len > ctx->msgLen) { + // The message length is exceeded. + BSL_ERR_PUSH_ERROR(CRYPT_MODES_MSGLEN_OVERFLOW); + return CRYPT_MODES_MSGLEN_OVERFLOW; + } + int32_t ret = TagInit(ctx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // Determine whether to start encryption and update the nonce information. + RefreshNonce(ctx); + + uint32_t lastLen = LastHandle(ctx, in, out, len, enc); + if (lastLen != 0 && ctx->lastLen == 0) { + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->tag, ctx->tag, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + // Data processing is complete and exits in advance. + if (lastLen == len) { + ctx->msgLen -= len; // Refresh the remaining length. + return CRYPT_SUCCESS; + } + + uint32_t tmpLen = len - lastLen; + ret = func(ctx, in + lastLen, out + lastLen, tmpLen, enc); + if (ret != CRYPT_SUCCESS) { + // Returned by the internal function. No redundant push err is required. + return ret; + } + ctx->lastLen = (CCM_BLOCKSIZE - (tmpLen % CCM_BLOCKSIZE)) % CCM_BLOCKSIZE; + ctx->msgLen -= len; // Refresh the remaining length. + return CRYPT_SUCCESS; +} + +int32_t MODES_CCM_Encrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return CcmCrypt(ctx, in, out, len, true, CcmBlocks); +} + +int32_t MODES_CCM_Decrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return CcmCrypt(ctx, in, out, len, false, CcmBlocks); +} + +// 7 <= ivLen <= 13 +static int32_t SetIv(MODES_CCM_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + /** + * RFC_3610-2 + * Valid values of L range between 2 octets and 8 octets + */ + // L = 15 - ivLen that is 7 <= ivLen <= 13 + if (len < 7 || len > 13) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_IVLEN_ERROR); + return CRYPT_MODES_IVLEN_ERROR; + } + // The previous judgment limits the size of iv to [7, 13]. Therefore, forcible conversion does not cause truncation. + uint8_t l = CCM_BLOCKSIZE - 1 - (uint8_t)len; + + // Clear data. + void *ciphCtx = ctx->ciphCtx; // Handle used by the method + const EAL_CipherMethod *ciphMeth = ctx->ciphMeth; // algorithm method + uint8_t tagLen = ctx->tagLen; + (void)memset_s(ctx, sizeof(MODES_CCM_Ctx), 0, sizeof(MODES_CCM_Ctx)); + ctx->ciphCtx = ciphCtx; + ctx->ciphMeth = ciphMeth; + ctx->tagLen = tagLen; + + uint8_t m = (ctx->tagLen - 2) / 2; // M' = (M - 2)/2 + ctx->nonce[0] = (uint8_t)((l - 1) & 0x7); // set L + ctx->nonce[0] |= (m << 3); // set M. The default value of TagLen is 16bytes. (bit2 bit3 bit4) indicating the tagLen + (void)memcpy_s(ctx->nonce + 1, CCM_BLOCKSIZE - 1, val, len); + + return CRYPT_SUCCESS; +} + +// The input data is the uint64_t. +static int32_t SetMsgLen(MODES_CCM_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint64_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_MSGLEN_ERROR); + return CRYPT_MODES_CTRL_MSGLEN_ERROR; + } + if ((ctx->nonce[0] & 0x40) != 0) { + // If aad has been set, msgLen cannot be set. + BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_IS_SET_ERROR); + return CRYPT_MODES_AAD_IS_SET_ERROR; + } + const uint64_t msgLen = *(const uint64_t *)val; + uint8_t l = (ctx->nonce[0] & 0x7) + 1; + /** + * RFC_3610-7 + * octet aligned message of arbitrary length, up to 2^(8*L) octets, + * and octet aligned arbitrary additional authenticated data, up to + * 2^64 octets + */ + if (l < 8 && msgLen >= ((uint64_t)1 << (8 * l))) { // When l is 8, the condition must be met. + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_MSGLEN_ERROR); + return CRYPT_MODES_CTRL_MSGLEN_ERROR; + } + uint8_t i; + /** + * RFC_3610-2.3 + * Octet Number Contents + * ------------ --------- + * 0 Flags + * 1 ... 15-L Nonce N + * 16-L ... 15 Counter i + */ + uint8_t bytes[sizeof(uint64_t)]; + Uint64ToBeBytes(msgLen, bytes); + for (i = 0; i < l; i++) { + ctx->nonce[CCM_BLOCKSIZE - 1 - i] = bytes[8 - 1 - i]; // 8 bit msgLen information + } + ctx->msgLen = msgLen; + return CRYPT_SUCCESS; +} + +static int32_t SetTagLen(MODES_CCM_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR); + return CRYPT_MODES_CTRL_TAGLEN_ERROR; + } + if ((ctx->nonce[0] & 0x40) != 0) { + // If aad has been set, tagLen cannot be set. + BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_IS_SET_ERROR); + return CRYPT_MODES_AAD_IS_SET_ERROR; + } + /** + * RFC_3610-2 + * Valid values are 4, 6, 8, 10, 12, 14, and 16 octets + */ + uint32_t tagLen = *((const uint32_t *)val); + // 4 <= tagLen <= 16 and tagLen is an even number. + if (tagLen > 16 || tagLen < 4 || ((tagLen & 0x01) != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR); + return CRYPT_MODES_CTRL_TAGLEN_ERROR; + } + ctx->tagLen = (uint8_t)tagLen; + uint8_t m = (ctx->tagLen - 2) / 2; // M' = (M - 2)/2 + ctx->nonce[0] &= ~(0x7 << 3); // Clear 3|4|5 three bits + ctx->nonce[0] |= (m << 3); // Set M + return CRYPT_SUCCESS; +} + +static uint32_t XorAadLen(MODES_CCM_Ctx *ctx, uint32_t aadLen) +{ + /** + * RFC_3610-2.2 + * First two octets Followed by Comment + * ----------------- ---------------- ------------------------------- + * 0x0000 Nothing Reserved + * 0x0001 ... 0xFEFF Nothing For 0 < l(a) < (2^16 - 2^8) + * 0xFF00 ... 0xFFFD Nothing Reserved + * 0xFFFE 4 octets of l(a) For (2^16 - 2^8) <= l(a) < 2^32 + * 0xFFFF 8 octets of l(a) For 2^32 <= l(a) < 2^64 + */ + uint32_t record; /* In order to record aadlen */ + // For 0 < l(a) < (2^16 - 2^8) + if (aadLen < (((size_t)1 << 16) - ((size_t)1 << 8))) { + /* 0 < l(a) < (2^16 - 2^8) */ + record = 2; /* 2 octets */ + ctx->tag[1] ^= (uint8_t)aadLen; + ctx->tag[0] ^= (uint8_t)(aadLen >> 8); // 1byte = 8bit + } else { + /* (2^16 - 2^8) <= l(a) < 2^32 */ + record = 6; /* 6 octets */ + ctx->tag[5] ^= (uint8_t)aadLen; // base offset = 5 + ctx->tag[4] ^= (uint8_t)(aadLen >> 8); // 1byte(off 5 -> 4) == 8bit + ctx->tag[3] ^= (uint8_t)(aadLen >> 16); // 2byte(off 5 -> 3) == 16bit + ctx->tag[2] ^= (uint8_t)(aadLen >> 24); // 3byte(off 5 -> 2) == 24bit + ctx->tag[1] ^= 0xfe; + ctx->tag[0] ^= 0xff; + } + return record; +} + +// 0 < aadLen < 2^32 +static int32_t SetAad(MODES_CCM_Ctx *ctx, const void *val, uint32_t len) +{ + if ((ctx->nonce[0] & 0x40) != 0) { + // If aad has been set, the setting cannot be repeated. + BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_REPEAT_SET_ERROR); + return CRYPT_MODES_AAD_REPEAT_SET_ERROR; + } + if (len == 0) { // If AAD is 0, returned directly. + return CRYPT_SUCCESS; + } + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // bit6 Adata + ctx->nonce[0] |= 0x40; + // X_1 := E( K, B_0 ) + int32_t ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->nonce, ctx->tag, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ctx->tagInit = 1; + + uint32_t i; + uint32_t aadLen = len; + uint32_t record = XorAadLen(ctx, aadLen); + const uint8_t *aad = val; + uint32_t use = CCM_BLOCKSIZE - record; + use = (use < aadLen) ? use : aadLen; + for (i = 0; i < use; i++) { + ctx->tag[i + record] ^= aad[i]; + } + aad += use; + aadLen -= use; + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->tag, ctx->tag, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + while (aadLen > 0) { + uint32_t blockLen = (aadLen < CCM_BLOCKSIZE) ? aadLen : CCM_BLOCKSIZE; + for (i = 0; i < blockLen; i++) { + ctx->tag[i] ^= aad[i]; + } + aad += blockLen; + aadLen -= blockLen; + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->tag, ctx->tag, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + return CRYPT_SUCCESS; +} + +static int32_t CtrTagCalc(MODES_CCM_Ctx *ctx) +{ + /** + * RFC_3610-2.3 + * The authentication value U is computed by encrypting T with the ciphCtx + * stream block S_0 and truncating it to the desired length. + */ + ctx->nonce[0] &= 0x07; // update the nonce + uint8_t l = (ctx->nonce[0] & 0x07) + 1; + (void)memset_s(ctx->nonce + CCM_BLOCKSIZE - l, l, 0, l); + int32_t ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->nonce, ctx->nonce, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t GetTag(MODES_CCM_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != ctx->tagLen) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_TAGLEN_ERROR); + return CRYPT_MODES_TAGLEN_ERROR; + } + if (ctx->msgLen != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_MSGLEN_LEFT_ERROR); + return CRYPT_MODES_MSGLEN_LEFT_ERROR; + } + int32_t ret = TagInit(ctx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CtrTagCalc(ctx); + if (ret != CRYPT_SUCCESS) { + // An error is reported by the internal function, and no redundant pushErr is required. + return ret; + } + if (ctx->lastLen != 0) { + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->tag, ctx->tag, CCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + uint32_t i; + uint8_t *tag = val; + /** + * RFC_3610-2.3 + * U := T XOR first-M-bytes( S_0 ) + */ + for (i = 0; i < len; i++) { + tag[i] = ctx->tag[i] ^ ctx->nonce[i]; + } + return CRYPT_SUCCESS; +} + +int32_t MODES_CCM_Ctrl(MODES_CCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + switch (opt) { + case CRYPT_CTRL_SET_IV: + return SetIv(ctx, val, len); + case CRYPT_CTRL_SET_TAGLEN: + return SetTagLen(ctx, val, len); + case CRYPT_CTRL_SET_MSGLEN: + return SetMsgLen(ctx, val, len); + case CRYPT_CTRL_SET_AAD: + return SetAad(ctx, val, len); + case CRYPT_CTRL_GET_TAG: + return GetTag(ctx, val, len); + default: + BSL_ERR_PUSH_ERROR(CRYPT_MODES_METHODS_NOT_SUPPORT); + return CRYPT_MODES_METHODS_NOT_SUPPORT; + } +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/modes_cfb.c b/crypto/modes/src/modes_cfb.c new file mode 100644 index 00000000..00d3b750 --- /dev/null +++ b/crypto/modes/src/modes_cfb.c @@ -0,0 +1,371 @@ +/* + * 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_CFB + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_modes.h" +#include "crypt_errno.h" +#include "crypt_modes_cfb.h" + +int32_t MODE_CFB_InitCtx(MODE_CFB_Ctx *ctx, const EAL_CipherMethod *method) +{ + if (ctx == NULL || method == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + ctx->modeCtx = BSL_SAL_Malloc(sizeof(MODE_CipherCtx)); + if (ctx->modeCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + int32_t ret = MODE_InitCtx(ctx->modeCtx, method); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(ctx->modeCtx); + return ret; + } + + uint8_t blockBits = ctx->modeCtx->blockSize * 8; + if (blockBits <= 128) { + ctx->feedbackBits = blockBits; + } else { + ctx->feedbackBits = 128; + } + return CRYPT_SUCCESS; +} + +void MODE_CFB_Clean(MODE_CFB_Ctx *ctx) +{ + if (ctx == NULL || ctx->modeCtx == NULL) { + return; + } + MODE_Clean(ctx->modeCtx); +} + +/* 8-bit | 64-bit | 128-bit CFB encryption. Here, len indicates the number of bytes to be processed. */ +static int32_t MODE_CFB_BytesEncrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + const uint8_t *input = in; + uint8_t *output = out; + uint8_t *tmp = ctx->modeCtx->buf; + uint32_t blockSize = ctx->modeCtx->blockSize; + uint32_t feedbackBytes = ctx->feedbackBits >> 3; + uint32_t left = len; + uint32_t i, k; + + // If the remaining encryption iv is not used up last time, use that part to perform XOR. + while (left > 0 && ctx->modeCtx->offset > 0) { + ctx->modeCtx->iv[ctx->modeCtx->offset] ^= *(input++); + *(output++) = ctx->modeCtx->iv[ctx->modeCtx->offset]; + left--; + ctx->modeCtx->offset = (ctx->modeCtx->offset + 1) % blockSize; + } + + while (left > 0) { + // Encrypt the IV. + int32_t ret = ctx->modeCtx->ciphMeth->encrypt(ctx->modeCtx->ciphCtx, ctx->modeCtx->iv, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + i = 0; + + // The first (blockSize - feedbackBytes) bytes are filled with the least significant bytes of the previous IV. + if (blockSize - feedbackBytes > 0) { + (void)memmove_s(&ctx->modeCtx->iv[0], blockSize, &ctx->modeCtx->iv[feedbackBytes], + blockSize - feedbackBytes); + i = blockSize - feedbackBytes; + } + + // The input data is XORed with the encrypted IV, and the current ciphertext is sent to the next IV. + if (left >= feedbackBytes) { + // Enter the last feedbackBytes in ciphertext. + for (k = 0; i < blockSize; i++, k++) { + output[k] = input[k] ^ tmp[k]; + ctx->modeCtx->iv[i] = output[k]; + } + UPDATE_VALUES(left, input, output, feedbackBytes); + } else { + // Enter the last feedbackBytes in ciphertext. + // The cache with insufficient feedbackBytes is used to encrypt the IV. + for (k = 0; k < left; k++) { + output[k] = input[k] ^ tmp[k]; + ctx->modeCtx->iv[i++] = output[k]; + } + + while (i < blockSize) { + ctx->modeCtx->iv[i++] = tmp[k++]; + } + ctx->modeCtx->offset = (uint8_t)(blockSize - feedbackBytes + left); + left = 0; + } + } + + return CRYPT_SUCCESS; +} + +/* 8-bit | 64-bit | 128-bit CFB decryption. Here, len indicates the number of bytes to be processed. */ +static int32_t MODE_CFB_BytesDecrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + const uint8_t *input = in; + uint8_t *output = out; + uint8_t *tmp = ctx->modeCtx->buf; + uint32_t blockSize = ctx->modeCtx->blockSize; + uint32_t feedbackBytes = ctx->feedbackBits >> 3; + uint32_t left = len; + uint32_t i, k; + + // If the remaining encryption iv is not used up last time, use that part to perform XOR. + while (left > 0 && ctx->modeCtx->offset > 0) { + uint8_t tmpInput = *input; // To support the same address in and out + *(output++) = ctx->modeCtx->iv[ctx->modeCtx->offset] ^ *(input++); + ctx->modeCtx->iv[ctx->modeCtx->offset] = tmpInput; + left--; + ctx->modeCtx->offset = (ctx->modeCtx->offset + 1) % blockSize; + } + + while (left > 0) { + // Encrypt the IV. + int32_t ret = ctx->modeCtx->ciphMeth->encrypt(ctx->modeCtx->ciphCtx, ctx->modeCtx->iv, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + i = 0; + + // The first (blockSize - feedbackBytes) bytes are filled with the least significant bytes of the previous IV. + if (blockSize - feedbackBytes > 0) { + (void)memmove_s(&ctx->modeCtx->iv[0], blockSize, &ctx->modeCtx->iv[feedbackBytes], + blockSize - feedbackBytes); + i = blockSize - feedbackBytes; + } + + // The input data is XORed with the encrypted IV, and the current ciphertext is sent to the next IV. + if (left >= feedbackBytes) { + // Enter the last feedbackBytes in ciphertext. + for (k = 0; i < blockSize; i++, k++) { + ctx->modeCtx->iv[i] = input[k]; + output[k] = input[k] ^ tmp[k]; + } + UPDATE_VALUES(left, input, output, feedbackBytes); + } else { + // Enter the last feedbackBytes in ciphertext. + // The cache with insufficient feedbackBytes is used to encrypt the IV. + for (k = 0; k < left; k++) { + ctx->modeCtx->iv[i++] = input[k]; + output[k] = input[k] ^ tmp[k]; + } + + while (i < blockSize) { + ctx->modeCtx->iv[i++] = tmp[k++]; + } + ctx->modeCtx->offset = (uint8_t)(blockSize - feedbackBytes + left); + left = 0; + } + } + + return CRYPT_SUCCESS; +} + +static int32_t Cfb1Crypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, bool enc) +{ + int32_t ret; + uint8_t *tmp = ctx->modeCtx->buf; + uint32_t blockSize = ctx->modeCtx->blockSize; + uint32_t i; + + // Encrypt the IV. + ret = ctx->modeCtx->ciphMeth->encrypt(ctx->modeCtx->ciphCtx, ctx->modeCtx->iv, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + for (i = 0; i < blockSize - 1; i++) { + // All bytes are shifted left by one bit, + // and the least significant bits are obtained by shifting right by 7 bits from the next byte. + ctx->modeCtx->iv[i] = (ctx->modeCtx->iv[i] << 1) | (ctx->modeCtx->iv[i + 1] >> 7); + } + + if (enc) { + *out = tmp[0] ^ *in; + // The last byte is shifted to the left by one bit and then filled in the ciphertext. + // Shifted to the right by 7 bits to obtain the first bit of the byte. + ctx->modeCtx->iv[i] = (ctx->modeCtx->iv[i] << 1) | (*out >> 7); + } else { + // The last byte is shifted to the left by one bit and then filled in the ciphertext. + // Shifted to the right by 7 bits to obtain the first bit of the byte. + ctx->modeCtx->iv[i] = (ctx->modeCtx->iv[i] << 1) | (*in >> 7); + *out = tmp[0] ^ *in; + } + + return CRYPT_SUCCESS; +} + +/* 1-bit CFB. Here, len indicates the number of bits to be processed. */ +int32_t MODE_CFB_BitCrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + int32_t ret; + uint8_t tmp[2]; + uint32_t pos; + for (uint32_t i = 0; i < len; i++) { + // 7 - i % 8 is used to obtain the number of bits in the byte stream (high bit -> low bit). + pos = 7 - i % 8; + // Obtain the bits to be encrypted. 0x80 indicates a byte whose most significant bit is 1. + tmp[0] = ((in[i / 8] & (1 << pos)) > 0) ? 0x80 : 0; + ret = Cfb1Crypt(ctx, &tmp[0], &tmp[1], enc); + if (ret != CRYPT_SUCCESS) { + return ret; + } + // Divide by 8 to obtain the current byte position. Assign the out encryption bit to 0. + out[i / 8] = out[i / 8] & ~(1u << pos); + // Divide by 8 to obtain the current byte position. tmpOut[0] >> 7 to obtain the most significant bit. + out[i / 8] |= (tmp[1] >> 7) << pos; // Assign the out encryption bit to the encrypted/decrypted value. + } + (void)memset_s(tmp, sizeof(tmp), 0, sizeof(tmp)); + return CRYPT_SUCCESS; +} + +static int32_t CFB_Crypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + if (ctx == NULL || in == NULL || out == NULL || len == 0 || ctx->modeCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + switch (ctx->feedbackBits) { + case 1: + return MODE_CFB_BitCrypt(ctx, in, out, len * 8, enc); + case 8: + case 64: + case 128: + return enc ? MODE_CFB_BytesEncrypt(ctx, in, out, len) : MODE_CFB_BytesDecrypt(ctx, in, out, len); + + default: + BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE); + return CRYPT_MODES_ERR_FEEDBACKSIZE; + } +} + +int32_t MODE_CFB_Encrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return CFB_Crypt(ctx, in, out, len, true); +} + +int32_t MODE_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return CFB_Crypt(ctx, in, out, len, false); +} + +static int32_t SetIv(MODE_CFB_Ctx *ctx, uint8_t *val, uint32_t len) +{ + int32_t ret = MODE_SetIv(ctx->modeCtx, val, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return CRYPT_SUCCESS; +} + +static int32_t SetFeedbackSize(MODE_CFB_Ctx *ctx, const uint32_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + if (ctx->modeCtx->algId == CRYPT_SYM_SM4 && *val != 128) { // sm4 set 128 feedbackbits only + BSL_ERR_PUSH_ERROR(CRYPT_MODES_FEEDBACKSIZE_NOT_SUPPORT); + return CRYPT_MODES_FEEDBACKSIZE_NOT_SUPPORT; + } + if (*val != 1 && *val != 8 && *val != 128) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE); + return CRYPT_MODES_ERR_FEEDBACKSIZE; + } + + if (*val > (uint32_t)(ctx->modeCtx->blockSize * 8)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_FEEDBACKSIZE); + return CRYPT_MODES_ERR_FEEDBACKSIZE; + } + ctx->feedbackBits = (uint8_t)*val; + return CRYPT_SUCCESS; +} + +static int32_t GetFeedbackSize(MODE_CFB_Ctx *ctx, uint32_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + *val = ctx->feedbackBits; + return CRYPT_SUCCESS; +} + +int32_t MODE_CFB_Ctrl(MODE_CFB_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL || ctx->modeCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + switch (opt) { + case CRYPT_CTRL_SET_IV: + return SetIv(ctx, (uint8_t *)val, len); + case CRYPT_CTRL_GET_IV: + return MODE_GetIv(ctx->modeCtx, (uint8_t *)val, len); + case CRYPT_CTRL_SET_FEEDBACKSIZE: + return SetFeedbackSize(ctx, (uint32_t *)val, len); + case CRYPT_CTRL_GET_FEEDBACKSIZE: + return GetFeedbackSize(ctx, (uint32_t *)val, len); + default: + BSL_ERR_PUSH_ERROR(CRYPT_MODES_METHODS_NOT_SUPPORT); + return CRYPT_MODES_METHODS_NOT_SUPPORT; + } +} + +int32_t MODE_CFB_SetEncryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL || ctx->modeCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return MODE_SetEncryptKey(ctx->modeCtx, key, len); +} + +void MODE_CFB_DeInitCtx(MODE_CFB_Ctx *ctx) +{ + if (ctx == NULL || ctx->modeCtx == NULL) { + return; + } + MODE_DeInitCtx(ctx->modeCtx); + BSL_SAL_FREE(ctx->modeCtx); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/modes_chacha20_poly1305.c b/crypto/modes/src/modes_chacha20_poly1305.c new file mode 100644 index 00000000..40bbbe8c --- /dev/null +++ b/crypto/modes/src/modes_chacha20_poly1305.c @@ -0,0 +1,374 @@ +/* + * 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_CHACHA20POLY1305 + +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "poly1305_core.h" + + +void Poly1305SetKey(Poly1305Ctx *ctx, const uint8_t key[POLY1305_KEYSIZE]) +{ + // RFC_7539-2.5 + ctx->r[0] = GET_UINT32_LE(key, 0); + ctx->r[1] = GET_UINT32_LE(key, 4); + ctx->r[2] = GET_UINT32_LE(key, 8); + ctx->r[3] = GET_UINT32_LE(key, 12); + ctx->s[0] = GET_UINT32_LE(key, 16); + ctx->s[1] = GET_UINT32_LE(key, 20); + ctx->s[2] = GET_UINT32_LE(key, 24); + ctx->s[3] = GET_UINT32_LE(key, 28); + + /** + * r[3], r[7], r[11], and r[15] are required to have their top four + * bits clear (be smaller than 16) + * r[4], r[8], and r[12] are required to have their bottom two bits + * clear (be divisible by 4) + */ + ctx->r[0] &= 0x0FFFFFFF; + ctx->r[1] &= 0x0FFFFFFC; + ctx->r[2] &= 0x0FFFFFFC; + ctx->r[3] &= 0x0FFFFFFC; + + ctx->acc[0] = 0; + ctx->acc[1] = 0; + ctx->acc[2] = 0; + ctx->acc[3] = 0; + ctx->acc[4] = 0; + ctx->acc[5] = 0; + + ctx->lastLen = 0; +} + +void Poly1305Update(Poly1305Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + uint32_t i; + uint32_t len = dataLen; + const uint8_t *off = data; + if (ctx->lastLen != 0) { + uint64_t end = (uint64_t)len + ctx->lastLen; + if (end > POLY1305_BLOCKSIZE) { + end = POLY1305_BLOCKSIZE; + } + for (i = ctx->lastLen; i < end; i++) { + ctx->last[i] = *off; + off++; + } + len -= (uint32_t)(end - ctx->lastLen); + if (end == POLY1305_BLOCKSIZE) { + (void)Poly1305Block(ctx, ctx->last, POLY1305_BLOCKSIZE, 1); + } else { + ctx->lastLen = (uint32_t)end; + return; + } + } + /** + * Add one bit beyond the number of octets. For a 16-byte block, + * this is equivalent to adding 2^128 to the number. + */ + if (len >= POLY1305_BLOCKSIZE) { + (void)Poly1305Block(ctx, off, len & 0xfffffff0, 1); + } + ctx->lastLen = len & 0x0f; // mod 16; + off += len - ctx->lastLen; + for (i = 0; i < ctx->lastLen; i++) { + ctx->last[i] = off[i]; + } + return; +} + +void Poly1305Final(Poly1305Ctx *ctx, uint8_t mac[POLY1305_TAGSIZE]) +{ + uint32_t len = ctx->lastLen; + if (len > 0) { + /** + * For the shorter block, it can be 2^120, 2^112, or any power of two that is + * evenly divisible by 8, all the way down to 2^8 + */ + ctx->last[len++] = 1; + /** + * If the block is not 17 bytes long (the last block), pad it with + * zeros. This is meaningless if you are treating the blocks as + * numbers. + */ + while (len < POLY1305_BLOCKSIZE) { + ctx->last[len++] = 0; + } + Poly1305Block(ctx, ctx->last, POLY1305_BLOCKSIZE, 0); + ctx->lastLen = 0; + } + Poly1305Last(ctx, mac); +} + +int32_t MODES_CHACHA20POLY1305_InitCtx(MODES_CHACHA20POLY1305_Ctx *ctx, const struct EAL_CipherMethod *m) +{ + if (ctx == NULL || m == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(MODES_CHACHA20POLY1305_Ctx), 0, sizeof(MODES_CHACHA20POLY1305_Ctx)); + ctx->method = m; + ctx->key = BSL_SAL_Malloc(m->ctxSize); + if (ctx->key == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)memset_s(ctx->key, m->ctxSize, 0, m->ctxSize); + return CRYPT_SUCCESS; +} + +void MODES_CHACHA20POLY1305_DeinitCtx(MODES_CHACHA20POLY1305_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + if (ctx->method != NULL) { + BSL_SAL_CleanseData(ctx->key, ctx->method->ctxSize); + } + BSL_SAL_FREE(ctx->key); + (void)memset_s(ctx, sizeof(MODES_CHACHA20POLY1305_Ctx), 0, sizeof(MODES_CHACHA20POLY1305_Ctx)); +} + +void MODES_CHACHA20POLY1305_Clean(MODES_CHACHA20POLY1305_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + if (ctx->method != NULL) { + BSL_SAL_CleanseData((void *)(ctx->key), ctx->method->ctxSize); + } + BSL_SAL_CleanseData((void *)(&(ctx->polyCtx)), sizeof(Poly1305Ctx)); + ctx->aadLen = 0; + ctx->cipherTextLen = 0; + Poly1305CleanRegister(); +} + +int32_t MODES_CHACHA20POLY1305_SetEncryptKey(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ctx->method->setEncryptKey(ctx->key, key, len); +} + +int32_t MODES_CHACHA20POLY1305_SetDecryptKey(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ctx->method->setDecryptKey(ctx->key, key, len); +} + +int32_t MODES_CHACHA20POLY1305_Encrypt(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = ctx->method->encrypt(ctx->key, in, out, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + Poly1305Update(&(ctx->polyCtx), out, len); + ctx->cipherTextLen += (uint64_t)len; + return CRYPT_SUCCESS; +} + +int32_t MODES_CHACHA20POLY1305_Decrypt(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + Poly1305Update(&(ctx->polyCtx), in, len); + ctx->cipherTextLen += (uint64_t)len; + int32_t ret = ctx->method->decrypt(ctx->key, in, out, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static void CipherTextPad(MODES_CHACHA20POLY1305_Ctx *ctx) +{ + /** + * The ciphertext + * padding2 -- the padding is up to 15 zero bytes, and it brings + * the total length so far to an integral multiple of 16. If the + * length of the ciphertext was already an integral multiple of 16 + * bytes, this field is zero-length. + */ + Poly1305Ctx *polyCtx = &(ctx->polyCtx); + uint32_t len = polyCtx->lastLen; + if (len != 0) { + const uint8_t pad2[POLY1305_BLOCKSIZE] = {0}; + Poly1305Update(polyCtx, pad2, POLY1305_BLOCKSIZE - len); + } + + uint8_t pad[POLY1305_BLOCKSIZE]; + /** + * The length of the additional data in octets (as a 64-bit + * little-endian integer). + */ + PUT_UINT64_LE(ctx->aadLen, pad, 0); // The first eight bytes are padded with the length of the AAD. + /** + * The length of the ciphertext in octets (as a 64-bit littleendian + * integer). + */ + PUT_UINT64_LE(ctx->cipherTextLen, pad, 8); // The last 8 bytes are padded the length of the ciphertext. + Poly1305Update(polyCtx, pad, POLY1305_BLOCKSIZE); +} + +static int32_t GetTag(MODES_CHACHA20POLY1305_Ctx *ctx, uint8_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != POLY1305_TAGSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_TAGLEN_ERROR); + return CRYPT_MODES_TAGLEN_ERROR; + } + CipherTextPad(ctx); + Poly1305Final(&(ctx->polyCtx), val); + return CRYPT_SUCCESS; +} + +static int32_t SetIv(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *iv, uint32_t ivLen) +{ + /** + * RFC_7539-2.6 + * ChaCha20 as specified here requires a 96-bit nonce. + * So if the provided nonce is only 64-bit, then the first 32 + * bits of the nonce will be set to a constant number. This will + * usually be zero, but for protocols with multiple senders it may be + * different for each sender, but should be the same for all + * invocations of the function with the same key by a particular + * sender. + */ + if (iv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // 96 bits or 64 bits, that is, 12 bytes or 8 bytes. + if (ivLen != 12 && ivLen != 8) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_IVLEN_ERROR); + return CRYPT_MODES_IVLEN_ERROR; + } + int32_t ret; + uint8_t block[POLY1305_KEYSIZE] = { 0 }; + if (ivLen == 8) { // If the length of the IV is 8, 0 data must be padded before. + uint8_t tmpBuff[12] = { 0 }; + (void)memcpy_s(tmpBuff + 4, 12 - 4, iv, ivLen); + ret = ctx->method->ctrl(ctx->key, CRYPT_CTRL_SET_IV, tmpBuff, 12); + // Clear sensitive data. + (void)BSL_SAL_CleanseData(tmpBuff, sizeof(tmpBuff)); + } else { + ret = ctx->method->ctrl(ctx->key, CRYPT_CTRL_SET_IV, (void *)(uintptr_t)iv, ivLen); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /** + * RFC_7539-2.6 + * The block counter is set to zero + */ + uint8_t initCount[4] = { 0 }; + ret = ctx->method->ctrl(ctx->key, CRYPT_CTRL_SET_COUNT, initCount, sizeof(initCount)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = ctx->method->encrypt(ctx->key, block, block, POLY1305_KEYSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + Poly1305SetKey(&(ctx->polyCtx), block); + /** + * RFC_7539-2.8 + * the ChaCha20 encryption function is called to encrypt the + * plaintext, using the same key and nonce, and with the initial + * counter set to 1 + */ + initCount[0] = 0x01; + ret = ctx->method->ctrl(ctx->key, CRYPT_CTRL_SET_COUNT, initCount, sizeof(initCount)); // 4bytes count + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + // Information that needs to be reset. + ctx->aadLen = 0; + ctx->cipherTextLen = 0; + return ret; +} + +// Set the AAD information. The AAD information can be set only once. +static int32_t SetAad(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *aad, uint32_t aadLen) +{ + /** + * RFC_7539-2.8 + * The AAD + * padding1 -- the padding is up to 15 zero bytes, and it brings + * the total length so far to an integral multiple of 16. If the + * length of the AAD was already an integral multiple of 16 bytes, + * this field is zero-length. + */ + if (aadLen == 0) { + return CRYPT_SUCCESS; + } + if (aad == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->aadLen != 0) { // aad is set + BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_REPEAT_SET_ERROR); + return CRYPT_MODES_AAD_REPEAT_SET_ERROR; + } + const uint8_t pad[16] = { 0 }; + ctx->aadLen = aadLen; + Poly1305Update(&(ctx->polyCtx), aad, aadLen); + uint32_t padLen = (16 - aadLen % 16) % 16; + Poly1305Update(&(ctx->polyCtx), pad, padLen); + return CRYPT_SUCCESS; +} + +int32_t MODES_CHACHA20POLY1305_Ctrl(MODES_CHACHA20POLY1305_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + switch (opt) { + case CRYPT_CTRL_SET_IV: + return SetIv(ctx, val, len); + case CRYPT_CTRL_GET_TAG: + return GetTag(ctx, val, len); + case CRYPT_CTRL_SET_AAD: + return SetAad(ctx, val, len); + default: + return ctx->method->ctrl(ctx->key, opt, val, len); + } +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/modes_ctr.c b/crypto/modes/src/modes_ctr.c new file mode 100644 index 00000000..b9f35553 --- /dev/null +++ b/crypto/modes/src/modes_ctr.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CTR + +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_modes.h" +#include "crypt_modes_ctr.h" + +void MODE_CTR_Clean(MODE_CipherCtx *ctx) +{ + MODE_Clean(ctx); +} + +uint32_t MODE_CTR_LastHandle(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + uint32_t left = len; + uint32_t blockSize = ctx->blockSize; + const uint8_t *tmpIn = in; + uint8_t *tmpOut = out; + // buf[0, ctx->offset, blockSize) + // The data from st to blockSize - 1 is the data obtained after the last encryption and is not used up. + while ((ctx->offset != 0) && (left > 0)) { + *(tmpOut++) = ((*(tmpIn++)) ^ (ctx->buf[ctx->offset++])); + --left; + // & (blockSize - 1) is equivalent to mod blockSize. + ctx->offset &= (uint8_t)(blockSize - 1); + } + // Return the calculated length. + return (len - left); +} + +void MODE_CTR_RemHandle(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (len == 0) { + return; + } + uint32_t left = len; + uint32_t blockSize = ctx->blockSize; + const uint8_t *tmpIn = in; + uint8_t *tmpOut = out; + // Ensure that the length of IV is 16 when setting it, which will not cause encryption failures. + // To optimize performance, the function does not determine the length of the IV. + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->buf, blockSize); + MODE_IncCounter(ctx->iv, ctx->blockSize); + ctx->offset = 0; + while ((left) > 0) { + tmpOut[ctx->offset] = (tmpIn[ctx->offset]) ^ (ctx->buf[ctx->offset]); + --left; + ++ctx->offset; + } +} + +int32_t MODE_CTR_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + // The ctx, in, and out pointers have been determined at the EAL layer and are not determined again. + if (len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + uint32_t offset = MODE_CTR_LastHandle(ctx, in, out, len); + uint32_t left = len - offset; + const uint8_t *tmpIn = in + offset; + uint8_t *tmpOut = out + offset; + uint32_t blockSize = ctx->blockSize; + + while (left >= blockSize) { + // Ensure that the length of IV is 16 when setting it, which will not cause encryption failures. + // To optimize performance, the function does not determine the length of the IV. + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->buf, blockSize); + MODE_IncCounter(ctx->iv, ctx->blockSize); + DATA64_XOR(tmpIn, ctx->buf, tmpOut, blockSize); + left -= blockSize; + tmpOut += blockSize; + tmpIn += blockSize; + } + + MODE_CTR_RemHandle(ctx, tmpIn, tmpOut, left); + + return CRYPT_SUCCESS; +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/modes_ecb.c b/crypto/modes/src/modes_ecb.c new file mode 100644 index 00000000..8b9c618b --- /dev/null +++ b/crypto/modes/src/modes_ecb.c @@ -0,0 +1,86 @@ +/* + * 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_ECB + +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_modes_ecb.h" + + +int32_t MODE_ECB_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + // ctx, in, out, these pointer have been judged at the EAL layer and is not judged again here. + if (ctx->ciphCtx == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + uint32_t left = len; + const uint8_t *input = in; + uint8_t *output = out; + uint32_t blockSize = ctx->blockSize; + + while (left >= blockSize) { + if (enc) { + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, input, output, blockSize); + } else { + ret = ctx->ciphMeth->decrypt(ctx->ciphCtx, input, output, blockSize); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + input += blockSize; + output += blockSize; + left -= blockSize; + } + if (left > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_ECB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_ECB_Crypt(ctx, in, out, len, true); +} + +int32_t MODE_ECB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_ECB_Crypt(ctx, in, out, len, false); +} + +void MODE_ECB_Clean(MODE_CipherCtx *ctx) +{ + if (ctx != NULL && ctx->ciphMeth != NULL && ctx->ciphMeth->clean != NULL) { + ctx->ciphMeth->clean(ctx->ciphCtx); + } +} + +int32_t MODE_ECB_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return MODE_DefaultCtrl(ctx, opt, val, len); +} +#endif // end HITLS_CRYPTO_ECB diff --git a/crypto/modes/src/modes_gcm.c b/crypto/modes/src/modes_gcm.c new file mode 100644 index 00000000..75d77528 --- /dev/null +++ b/crypto/modes/src/modes_gcm.c @@ -0,0 +1,470 @@ +/* + * 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_GCM + +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "modes_local.h" +#include "crypt_modes.h" +#include "crypt_modes_gcm.h" + +/** + * NIST_800-38D-5.2 + * len(P) ≤ 2^39-256 (bit) + * Equivalent to len(P) ≤ 2^36 - 32 (byte) + */ +#define GCM_MAX_COMBINED_LENGTH (((uint64_t)1 << 36) - 32) +/** + * NIST_800-38D-8.3 + * The total number of invocations of the authenticated encryption function shall not exceed + * 2^32, including all IV lengths and all instances of the authenticated encryption function with + * the given ciphCtx + */ +#define GCM_MAX_INVOCATIONS_TIMES ((uint32_t)(-1)) + +#define GCM_BLOCK_MASK (0xfffffff0) + +int32_t MODES_GCM_InitCtx(MODES_GCM_Ctx *ctx, const struct EAL_CipherMethod *m) +{ + if (ctx == NULL || m == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(MODES_GCM_Ctx), 0, sizeof(MODES_GCM_Ctx)); + ctx->ciphMeth = m; + ctx->ciphCtx = BSL_SAL_Malloc(m->ctxSize); + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +void MODES_GCM_DeinitCtx(MODES_GCM_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + (void)BSL_SAL_CleanseData(ctx->ciphCtx, ctx->ciphMeth->ctxSize); + BSL_SAL_FREE(ctx->ciphCtx); + (void)BSL_SAL_CleanseData(ctx, sizeof(MODES_GCM_Ctx)); +} + +void MODES_GCM_Clean(MODES_GCM_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + void *ciphCtx = ctx->ciphCtx; + const EAL_CipherMethod *ciphMeth = ctx->ciphMeth; + BSL_SAL_CleanseData((void *)(ciphCtx), ciphMeth->ctxSize); + BSL_SAL_CleanseData((void *)(ctx), sizeof(MODES_GCM_Ctx)); + ctx->ciphCtx = ciphCtx; + ctx->ciphMeth = ciphMeth; +} + +int32_t MODES_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *ciphCtx, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + MODES_GCM_Clean(ctx); + int32_t ret = ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, ciphCtx, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return MODES_GCM_InitHashTable(ctx); +} + +int32_t MODES_GCM_InitHashTable(MODES_GCM_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint8_t gcmKey[GCM_BLOCKSIZE] = { 0 }; + int32_t ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, gcmKey, gcmKey, GCM_BLOCKSIZE); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + GcmTableGen4bit(gcmKey, ctx->hTable); + ctx->tagLen = 16; + BSL_SAL_CleanseData(gcmKey, sizeof(gcmKey)); + return CRYPT_SUCCESS; +} + +// Update the number of usage times. +static int32_t CheckUseCnt(const MODES_GCM_Ctx *ctx) +{ + // 128, 120, 112, 104, or 96 that is 12 byte - 16 byte + if (ctx->cryptCnt == GCM_MAX_INVOCATIONS_TIMES) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_KEYUSE_TOOMANY_TIME); + return CRYPT_MODES_KEYUSE_TOOMANY_TIME; + } + return CRYPT_SUCCESS; +} + +/** + * NIST_800-38D-5.2 + * 1 ≤ len(IV) ≤ 2^64 - 1 (bit) + * It is currently restricted to no more than 2^32 - 1 bytes + */ +static int32_t SetIv(MODES_GCM_Ctx *ctx, const uint8_t *iv, uint32_t ivLen) +{ + if (iv == NULL || ivLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = CheckUseCnt(ctx); // Check the number of usage times. + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t i; + uint64_t len = (uint64_t)ivLen; + // when ivLen == 0, do reinit, no need to refersh iv + if (len == 12) { // len(IV ) = 96bit = 12byte + const uint8_t ivPad[4] = {0x00, 0x00, 0x00, 0x01}; + /* Y0 = IV || 0^31 || 1 if len(IV ) = 96 = 12byte */ + (void)memcpy_s(ctx->iv, GCM_BLOCKSIZE, iv, 12); + (void)memcpy_s(ctx->iv + 12, GCM_BLOCKSIZE - 12, ivPad, sizeof(ivPad)); // pad last 4bit(base = 12) + } else { + /* Y0 = GHASH(H, {}, IV ) otherwise */ + (void)memset_s(ctx->iv, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE); + const uint8_t *off = iv; + uint32_t blockLen = ivLen & GCM_BLOCK_MASK; + uint32_t lastLen = ivLen - blockLen; + uint8_t tmp[GCM_BLOCKSIZE] = {0}; + if (blockLen > 0) { + GcmHashMultiBlock(ctx->iv, ctx->hTable, off, blockLen); + off += blockLen; + } + if (lastLen > 0) { + for (i = 0; i < lastLen; i++) { + tmp[i] = off[i]; + } + GcmHashMultiBlock(ctx->iv, ctx->hTable, tmp, GCM_BLOCKSIZE); + } + len = (uint64_t)ivLen << 3; // bitLen = byteLen << 3 + (void)BSL_SAL_CleanseData(tmp, GCM_BLOCKSIZE); + Uint64ToBeBytes(len, tmp + 8); // The last 8 bytes store the length of the IV. + GcmHashMultiBlock(ctx->iv, ctx->hTable, tmp, GCM_BLOCKSIZE); + } + /** + * NIST_800-38D-7.1 + * GCTR(J0) + */ + ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->ek0, GCM_BLOCKSIZE); + + /** + * NIST_800-38D-7.1 + * INC32 + * the 32-bit incrementing function is applied to the pre-counter block + * to produce the initial counter block for an invocation of the GCTR + * function on the plaintext + */ + uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); // Offset of 12 bytes. Use the last four bytes. + ctr++; + PUT_UINT32_BE(ctr, ctx->iv, 12); // Writeback of offset 12 bytes + + // Reset information. + (void)memset_s(ctx->ghash, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE); + ctx->aadLen = 0; + ctx->lastLen = 0; + ctx->plaintextLen = 0; + + // Clear sensitive information. + BSL_SAL_CleanseData(&ctr, sizeof(uint32_t)); + return CRYPT_SUCCESS; +} + +/** + * NIST_800-38D-5.2 + * len(AAD) ≤ 2^64 - 1 (bit) + * Currently, it is restricted to no more than 2^32 - 1 bytes. + */ +static int32_t SetAad(MODES_GCM_Ctx *ctx, const uint8_t *aad, uint32_t aadLen) +{ + if (aad == NULL && aadLen != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + const uint8_t *off = aad; + uint32_t i; + if (ctx->aadLen != 0) { // aad is set + BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_REPEAT_SET_ERROR); + return CRYPT_MODES_AAD_REPEAT_SET_ERROR; + } + uint32_t blockLen = aadLen & GCM_BLOCK_MASK; + uint32_t lastLen = aadLen - blockLen; + if (blockLen > 0) { + GcmHashMultiBlock(ctx->ghash, ctx->hTable, off, blockLen); + off += blockLen; + } + if (lastLen > 0) { + uint8_t temp[GCM_BLOCKSIZE] = {0}; + for (i = 0; i < lastLen; i++) { + temp[i] = off[i]; + } + GcmHashMultiBlock(ctx->ghash, ctx->hTable, temp, GCM_BLOCKSIZE); + } + ctx->aadLen = aadLen; + return CRYPT_SUCCESS; +} + +// Overflow occurs when the encryption length is determined and the encrypted length information is updated. +int32_t CryptLenCheckAndRefresh(MODES_GCM_Ctx *ctx, uint32_t len) +{ + // The length of len is only 32 bits. This calculation does not cause overflow. + uint64_t plaintextLen = ctx->plaintextLen + len; + if (plaintextLen > GCM_MAX_COMBINED_LENGTH) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CRYPTLEN_OVERFLOW); + return CRYPT_MODES_CRYPTLEN_OVERFLOW; + } + ctx->plaintextLen = plaintextLen; + return CRYPT_SUCCESS; +} + +static void GcmXorInEncrypt(XorCryptData *data, uint32_t len) +{ + uint32_t i; + for (i = 0; i < len; i++) { + data->out[i] = data->in[i] ^ data->ctr[i]; + data->tag[i] = data->out[i]; + } +} + +static void GcmXorInDecrypt(XorCryptData *data, uint32_t len) +{ + uint32_t i; + for (i = 0; i < len; i++) { + data->tag[i] = data->in[i]; + data->out[i] = data->in[i] ^ data->ctr[i]; + } +} + +// Process the remaining data in the last update. +uint32_t LastHandle(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + uint32_t lastLen = 0; + if (ctx->lastLen > 0) { + XorCryptData data; + lastLen = (ctx->lastLen < len) ? ctx->lastLen : len; + data.in = in; + data.out = out; + data.ctr = &(ctx->last[GCM_BLOCKSIZE - ctx->lastLen]); + data.tag = &(ctx->remCt[GCM_BLOCKSIZE - ctx->lastLen]); + if (enc) { // ctx->lastLen must be smaller than the GCM_BLOCKSIZE + GcmXorInEncrypt(&data, lastLen); + } else { + GcmXorInDecrypt(&data, lastLen); + } + // Refresh the remaining length. + ctx->lastLen -= lastLen; + if (ctx->lastLen == 0) { + GcmHashMultiBlock(ctx->ghash, ctx->hTable, ctx->remCt, GCM_BLOCKSIZE); + } + } + return lastLen; +} + +static void GcmMultiBlockCrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + uint32_t blockLen = len; + const uint8_t *dataIn = in; + uint8_t *dataOut = out; + // count information, last 32 bits of the IV, with an offset of 12 bytes (16-4 = 12) + uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); + if (enc == false) { + GcmHashMultiBlock(ctx->ghash, ctx->hTable, in, len); + } + while (blockLen > 0) { + ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE); + DATA64_XOR(dataIn, ctx->last, dataOut, GCM_BLOCKSIZE); + /** + * NIST_800-38D-7.1 + * INC32 + */ + ctr++; + PUT_UINT32_BE(ctr, ctx->iv, 12); // Offset of 12 bytes. Use the last four bytes. + // Refresh the remaining length. + blockLen -= GCM_BLOCKSIZE; + // offset + dataIn += GCM_BLOCKSIZE; + dataOut += GCM_BLOCKSIZE; + } + if (enc) { + GcmHashMultiBlock(ctx->ghash, ctx->hTable, out, len); + } + // Clear sensitive information. + BSL_SAL_CleanseData(&ctr, sizeof(uint32_t)); +} + +// enc: true: the encryption operation, false: the decryption operation +static int32_t MODES_GCM_Crypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc) +{ + if (ctx == NULL || in == NULL || out == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = CryptLenCheckAndRefresh(ctx, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t lastLen = LastHandle(ctx, in, out, len, enc); + // Data processing is complete. Exit. + if (lastLen == len) { + return CRYPT_SUCCESS; + } + + XorCryptData data; + data.in = in + lastLen; + data.out = out + lastLen; + data.ctr = ctx->last; + data.tag = ctx->remCt; + + uint32_t multiBlockLen = (len - lastLen) & GCM_BLOCK_MASK; + if (multiBlockLen > 0) { + GcmMultiBlockCrypt(ctx, data.in, data.out, multiBlockLen, enc); + data.in += multiBlockLen; + data.out += multiBlockLen; + } + uint32_t remLen = len - lastLen - multiBlockLen; + if (remLen > 0) { + // count information, last 32 bits of the IV, with an offset of 12 bytes (16-4 = 12) + uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE); + if (enc) { + GcmXorInEncrypt(&data, remLen); + } else { + GcmXorInDecrypt(&data, remLen); + } + /** + * NIST_800-38D-7.1 + * INC32 + */ + ctr++; + PUT_UINT32_BE(ctr, ctx->iv, 12); // Offset of 12 bytes. Use the last four bytes. + // Clear sensitive information. + BSL_SAL_CleanseData(&ctr, sizeof(uint32_t)); + } + ctx->lastLen = (remLen > 0) ? (GCM_BLOCKSIZE - remLen) : 0; + + return CRYPT_SUCCESS; +} + +static void GcmPad(MODES_GCM_Ctx *ctx) +{ + // S = GHASHH (A || 0v || C || 0u || [len(A)]64 || [len(C)]64). + if (ctx->lastLen != 0) { + uint32_t offset = GCM_BLOCKSIZE - ctx->lastLen; + (void)memset_s(ctx->remCt + offset, GCM_BLOCKSIZE - offset, 0, ctx->lastLen); + GcmHashMultiBlock(ctx->ghash, ctx->hTable, ctx->remCt, GCM_BLOCKSIZE); + } + uint64_t aadLen = (uint64_t)(ctx->aadLen) << 3; // bitLen = byteLen << 3 + uint64_t plaintextLen = ctx->plaintextLen << 3; // bitLen = byteLen << 3 + uint8_t padBuf[GCM_BLOCKSIZE]; + Uint64ToBeBytes(aadLen, padBuf); + Uint64ToBeBytes(plaintextLen, padBuf + 8); // The last 64 bits (8 bytes) is the length of the ciphertext. + + GcmHashMultiBlock(ctx->ghash, ctx->hTable, padBuf, GCM_BLOCKSIZE); +} + +static int32_t SetTagLen(MODES_GCM_Ctx *ctx, const uint8_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR); + return CRYPT_MODES_CTRL_TAGLEN_ERROR; + } + /** + * NIST_800-38D-5.2.1.2 + * The bit length of the tag, denoted t, is a security parameter, as discussed in Appendix B. + * In general, t may be any one of the following five values: 128, 120, 112, 104, or 96. For certain + * applications, t may be 64 or 32; guidance for the use of these two tag lengths, including + * requirements on the length of the input data and the lifetime of the ciphCtx in these cases, + * is given in Appendix C + */ + uint32_t tagLen = *((const uint32_t *)val); + // 32bit is 4 bytes, 64bit is 8 bytes, 128, 120, 112, 104, or 96 is 12byte - 16byte + if (tagLen == 4 || tagLen == 8 || (tagLen >= 12 && tagLen <= 16)) { + ctx->tagLen = (uint8_t)tagLen; + return CRYPT_SUCCESS; + } + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR); + return CRYPT_MODES_CTRL_TAGLEN_ERROR; +} + +static int32_t GetTag(MODES_GCM_Ctx *ctx, uint8_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != ctx->tagLen) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_TAGLEN_ERROR); + return CRYPT_MODES_TAGLEN_ERROR; + } + ctx->cryptCnt++; // The encryption/decryption process ends. Key usage times + 1 + GcmPad(ctx); + uint32_t i; + for (i = 0; i < len; i++) { + val[i] = ctx->ghash[i] ^ ctx->ek0[i]; + } + return CRYPT_SUCCESS; +} + +int32_t MODES_GCM_Encrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_GCM_Crypt(ctx, in, out, len, true); +} + +int32_t MODES_GCM_Decrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_GCM_Crypt(ctx, in, out, len, false); +} + +int32_t MODES_GCM_Ctrl(MODES_GCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + return CRYPT_NULL_INPUT; + } + switch (opt) { + case CRYPT_CTRL_SET_IV: + return SetIv(ctx, val, len); + case CRYPT_CTRL_SET_TAGLEN: + return SetTagLen(ctx, val, len); + case CRYPT_CTRL_SET_AAD: + return SetAad(ctx, val, len); + case CRYPT_CTRL_GET_TAG: + return GetTag(ctx, val, len); + default: + BSL_ERR_PUSH_ERROR(CRYPT_MODES_METHODS_NOT_SUPPORT); + return CRYPT_MODES_METHODS_NOT_SUPPORT; + } +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/modes_local.h b/crypto/modes/src/modes_local.h new file mode 100644 index 00000000..3d22680e --- /dev/null +++ b/crypto/modes/src/modes_local.h @@ -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. + */ + +#ifndef MODES_LOCAL_H +#define MODES_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_GCM + +#include +#include +#include "crypt_modes_gcm.h" + +void GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE], MODES_GCM_GF128 hTable[16]); + +void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], const uint8_t *in, uint32_t inLen); + +int32_t CryptLenCheckAndRefresh(MODES_GCM_Ctx *ctx, uint32_t len); + +uint32_t LastHandle(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc); + +#endif +#endif diff --git a/crypto/modes/src/modes_ofb.c b/crypto/modes/src/modes_ofb.c new file mode 100644 index 00000000..9e205343 --- /dev/null +++ b/crypto/modes/src/modes_ofb.c @@ -0,0 +1,79 @@ +/* + * 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_OFB + +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_modes.h" +#include "crypt_modes_ofb.h" + +int32_t MODE_OFB_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret; + const uint8_t *input = in; + uint8_t *tmp = ctx->buf; + uint32_t blockSize = ctx->blockSize; + uint32_t left = len; + uint8_t *output = out; + uint32_t i; + + // If the remaining encrypted iv is not used up last time, use that part to perform XOR. + while (left > 0 && ctx->offset > 0) { + *(output++) = ctx->iv[ctx->offset] ^ *(input++); + left--; + ctx->offset = (ctx->offset + 1) % blockSize; + } + + while (left > 0) { + // Encrypt the IV. + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, tmp, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // Update the IV. + if (memcpy_s(ctx->iv, MODES_MAX_IV_LENGTH, tmp, blockSize) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + + if (left >= blockSize) { + /* Plaintext XOR IV. BlockSize must be an integer multiple of 4 bytes. */ + DATA32_XOR(input, tmp, output, blockSize); + UPDATE_VALUES(left, input, output, blockSize); + } else { + for (i = 0; i < left; i++) { + output[i] = input[i] ^ tmp[i]; + } + ctx->offset = (uint8_t)left; + left = 0; + } + } + + return CRYPT_SUCCESS; +} + +#endif // HITLS_CRYPTO_OFB \ No newline at end of file diff --git a/crypto/modes/src/modes_xts.c b/crypto/modes/src/modes_xts.c new file mode 100644 index 00000000..4cd3e156 --- /dev/null +++ b/crypto/modes/src/modes_xts.c @@ -0,0 +1,404 @@ +/* + * 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_XTS + +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "crypt_modes_xts.h" + + +#define MODE_XTS_BLOCKSIZE 16 +#define SM4_XTS_POLYNOMIAL 0xE1 +#define XTS_UPDATE_VALUES(l, i, o, len) \ + do { \ + (l) -= (len); \ + (i) += (len); \ + (o) += (len); \ + } while (false) + +int32_t MODE_XTS_InitCtx(MODE_XTS_Ctx *ctx, EAL_CipherMethod *method) +{ + // The upper layer has checked the validity of the ctx and method. + ctx->ciphCtx = BSL_SAL_Malloc(2 * method->ctxSize); // cipher context has 2 method contexts in xts mode + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + // Use 2 primitive contexts. + (void)memset_s(ctx->ciphCtx, 2 * method->ctxSize, 0, 2 * method->ctxSize); + // If the mode does not specify the blockSize, the blockSize value of algorithm will be assigned to the mode. + if (ctx->blockSize == 0) { + ctx->blockSize = method->blockSize; + } + ctx->algId = method->algId; + ctx->ciphMeth = method; + return CRYPT_SUCCESS; +} + +static int32_t XtsCheckPara(const MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (ctx == NULL || key == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // The key length supports only 256 bytes (32 bytes) and 512 bytes (64 bytes), corresponding to AES-128 and AES-256. + if (len != 32 && len != 64) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_KEYLEN); + return CRYPT_MODES_ERR_KEYLEN; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_XTS_SetEncryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + int32_t ret = XtsCheckPara(ctx, key, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + uint32_t keyLen = len >> 1; + if (memcmp(key, key + keyLen, keyLen) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_KEY); + return CRYPT_MODES_ERR_KEY; + } + ret = ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, key, keyLen); // key1 + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = ctx->ciphMeth->setEncryptKey((uint8_t*)ctx->ciphCtx + ctx->ciphMeth->ctxSize, key + keyLen, keyLen); // key2 + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_XTS_SetDecryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + int32_t ret = XtsCheckPara(ctx, key, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + uint32_t keyLen = len >> 1; + if (memcmp(key + keyLen, key, keyLen) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_ERR_KEY); + return CRYPT_MODES_ERR_KEY; + } + ret = ctx->ciphMeth->setEncryptKey((uint8_t*)ctx->ciphCtx + ctx->ciphMeth->ctxSize, key + keyLen, keyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = ctx->ciphMeth->setDecryptKey(ctx->ciphCtx, key, keyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +#ifdef HITLS_BIG_ENDIAN +// AES XTS IEEE P1619/D16 Annex C +// Pseudocode for XTS-AES-128 and XTS-AES-256 Encryption +void GF128Mul(uint8_t *a, uint32_t len) +{ + uint8_t in; + uint8_t out = 0; + in = 0; + // xts blocksize MODE_XTS_BLOCKSIZE + for (uint32_t j = 0; j < len; j++) { + out = (a[j] >> 7) & 1; // >> 7 + a[j] = (uint8_t)((a[j] << 1) + in) & 0xFFu; // << 1 + in = out; + } + if (out > 0) { + a[0] ^= 0x87; // 0x87 gf 128 + } +} +#else +// AES XTS IEEE P1619/D16 5.2 +// Multiplication by a primitive element α +void GF128Mul(uint8_t *a, uint32_t len) +{ + (void)len; + uint64_t *t = (uint64_t *)a; + uint8_t c = (t[1] >> 63) & 0xff; // 63 is the last bit of the last eight bytes. + t[1] = t[1] << 1 | t[0] >> 63; // 63 is the last bit of the first eight bytes + t[0] = t[0] << 1; + if (c != 0) { + t[0] ^= 0x87; + } +} +#endif + +void GF128Mul_GM(uint8_t *a, uint32_t len) +{ + uint8_t in = 0; + uint8_t out = 0; + + for (uint32_t j = 0; j < len; j++) { + out = (a[j] << 7) & 0x80; // shift left by 7 bits + a[j] = (uint8_t)((a[j] >> 1) + in) & 0xFFu; + in = out; + } + if (out > 0) { + a[0] ^= SM4_XTS_POLYNOMIAL; // reverse (10000111)2 + } +} + +int32_t BlockCrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, const uint8_t *t, uint8_t *pp, bool enc) +{ + int32_t ret; + uint32_t blockSize = ctx->blockSize; + DATA64_XOR(in, t, pp, blockSize); + + if (enc) { + ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, pp, pp, blockSize); + } else { + ret = ctx->ciphMeth->decrypt(ctx->ciphCtx, pp, pp, blockSize); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + DATA64_XOR(pp, t, pp, blockSize); + + return CRYPT_SUCCESS; +} + +int32_t BlocksCrypt(MODE_XTS_Ctx *ctx, const uint8_t **in, uint8_t **out, uint32_t *tmpLen, + bool enc) +{ + int32_t ret; + uint32_t blockSize = ctx->blockSize; + const uint8_t *tmpIn = *in; + uint8_t *tmpOut = *out; + while (*tmpLen >= 2 * blockSize) { // If the value is greater than blockSize * 2, process the tmpIn. + ret = BlockCrypt(ctx, tmpIn, ctx->tweak, tmpOut, enc); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + XTS_UPDATE_VALUES(*tmpLen, tmpIn, tmpOut, blockSize); + if (ctx->algId == CRYPT_SYM_SM4) { + GF128Mul_GM(ctx->tweak, blockSize); + } else { + GF128Mul(ctx->tweak, blockSize); + } + } + *in = tmpIn; + *out = tmpOut; + return CRYPT_SUCCESS; +} + +int32_t MODE_XTS_Encrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + int32_t ret; + uint32_t i; + uint8_t pp[MODE_XTS_BLOCKSIZE]; + uint32_t tmpLen = len; + const uint8_t *tmpIn = in; + uint8_t *tmpOut = out; + uint8_t *lastBlock = NULL; + uint32_t blockSize = ctx->blockSize; + + if (len < blockSize) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_BUFF_LEN_NOT_ENOUGH); + return CRYPT_MODE_BUFF_LEN_NOT_ENOUGH; + } + + ret = BlocksCrypt(ctx, &tmpIn, &tmpOut, &tmpLen, true); + RETURN_RET_IF(ret != CRYPT_SUCCESS, ret); + + // Encryption + ret = BlockCrypt(ctx, tmpIn, ctx->tweak, tmpOut, true); + RETURN_RET_IF(ret != CRYPT_SUCCESS, ret); + XTS_UPDATE_VALUES(tmpLen, tmpIn, tmpOut, blockSize); + + if (ctx->algId == CRYPT_SYM_SM4) { + GF128Mul_GM(ctx->tweak, blockSize); + } else { + GF128Mul(ctx->tweak, blockSize); + } + if (tmpLen == 0) { + return CRYPT_SUCCESS; + } + + lastBlock = tmpOut - blockSize; + // Process the subsequent two pieces of data. + for (i = 0; i < tmpLen; i++) { + tmpOut[i] = lastBlock[i]; + pp[i] = tmpIn[i]; + } + + for (i = tmpLen; i < blockSize; i++) { + pp[i] = lastBlock[i]; + } + ret = BlockCrypt(ctx, pp, ctx->tweak, pp, true); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // set c m-1 + tmpOut -= blockSize; + if (memcpy_s(tmpOut, blockSize + tmpLen, pp, blockSize) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_XTS_Decrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + int32_t ret; + uint8_t pp[MODE_XTS_BLOCKSIZE], t2[MODE_XTS_BLOCKSIZE]; // xts blocksize MODE_XTS_BLOCKSIZE + uint32_t i; + uint32_t tmpLen = len; + const uint8_t *tmpIn = in; + uint32_t blockSize = ctx->blockSize; + uint8_t *tmpOut = out; + + if (len < blockSize) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_BUFF_LEN_NOT_ENOUGH); + return CRYPT_MODE_BUFF_LEN_NOT_ENOUGH; + } + + ret = BlocksCrypt(ctx, &tmpIn, &tmpOut, &tmpLen, false); + RETURN_RET_IF(ret != CRYPT_SUCCESS, ret); + + // If len is an integer multiple of blockSize, the subsequent calculations is not required. + if (tmpLen == blockSize) { + ret = BlockCrypt(ctx, tmpIn, ctx->tweak, tmpOut, false); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ctx->algId == CRYPT_SYM_SM4) { + GF128Mul_GM(ctx->tweak, blockSize); + } else { + GF128Mul(ctx->tweak, blockSize); + } + return CRYPT_SUCCESS; + } + + (void)memcpy_s(t2, MODE_XTS_BLOCKSIZE, ctx->tweak, blockSize); + + if (ctx->algId == CRYPT_SYM_SM4) { + GF128Mul_GM(ctx->tweak, blockSize); + } else { + GF128Mul(ctx->tweak, blockSize); + } + ret = BlockCrypt(ctx, tmpIn, ctx->tweak, pp, false); + RETURN_RET_IF(ret != CRYPT_SUCCESS, ret); + tmpLen -= blockSize; + + for (i = 0; i < tmpLen; i++) { + tmpOut[i + blockSize] = pp[i]; + pp[i] = tmpIn[i + blockSize]; + } + + ret = BlockCrypt(ctx, pp, t2, pp, false); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (memcpy_s(tmpOut, blockSize + tmpLen, pp, blockSize) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +void MODE_XTS_Clean(MODE_XTS_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx->iv), MODES_MAX_IV_LENGTH); + BSL_SAL_CleanseData((void *)(ctx->tweak), MODES_MAX_IV_LENGTH); + if (ctx->ciphMeth != NULL && ctx->ciphMeth->clean != NULL) { + ctx->ciphMeth->clean(ctx->ciphCtx); + ctx->ciphMeth->clean((void *)((uintptr_t)ctx->ciphCtx + ctx->ciphMeth->ctxSize)); + } +} + +static int32_t SetIv(MODE_XTS_Ctx *ctx, uint8_t *val, uint32_t len) +{ + int32_t ret; + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != ctx->blockSize) { + BSL_ERR_PUSH_ERROR(CRYPT_MODES_IVLEN_ERROR); + return CRYPT_MODES_IVLEN_ERROR; + } + if (memcpy_s(ctx->iv, MODES_MAX_IV_LENGTH, (uint8_t*)val, len) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + + // Use key2 and i to encrypt to obtain the tweak. + ret = ctx->ciphMeth->encrypt((uint8_t*)ctx->ciphCtx + ctx->ciphMeth->ctxSize, ctx->iv, ctx->tweak, ctx->blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +static int32_t GetIv(MODE_XTS_Ctx *ctx, uint8_t *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != ctx->blockSize) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + if (memcpy_s(val, len, ctx->iv, ctx->blockSize) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t MODE_XTS_Ctrl(MODE_XTS_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + switch (opt) { + case CRYPT_CTRL_SET_IV: + return SetIv(ctx, (uint8_t *)val, len); + case CRYPT_CTRL_GET_IV: + return GetIv(ctx, (uint8_t *)val, len); + default: + BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TYPE_ERROR); + return CRYPT_MODES_CTRL_TYPE_ERROR; + } +} +#endif // HITLS_CRYPTO_XTS diff --git a/crypto/modes/src/noasm_aes_cbc.c b/crypto/modes/src/noasm_aes_cbc.c new file mode 100644 index 00000000..ed8c7d5f --- /dev/null +++ b/crypto/modes/src/noasm_aes_cbc.c @@ -0,0 +1,30 @@ +/* + * 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_modes_cbc.h" + +int32_t AES_CBC_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CBC_Encrypt(ctx, in, out, len); +} + +int32_t AES_CBC_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CBC_Decrypt(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_aes_ccm.c b/crypto/modes/src/noasm_aes_ccm.c new file mode 100644 index 00000000..c9732193 --- /dev/null +++ b/crypto/modes/src/noasm_aes_ccm.c @@ -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 "hitls_build.h" +#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CCM) + +#include "crypt_modes.h" +#include "crypt_modes_ccm.h" + +int32_t MODES_AES_CCM_Encrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_CCM_Encrypt(ctx, in, out, len); +} + +int32_t MODES_AES_CCM_Decrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_CCM_Decrypt(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_aes_cfb.c b/crypto/modes/src/noasm_aes_cfb.c new file mode 100644 index 00000000..d4046ada --- /dev/null +++ b/crypto/modes/src/noasm_aes_cfb.c @@ -0,0 +1,32 @@ +/* + * 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 "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_modes_cfb.h" + +int32_t MODE_AES_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || ctx->modeCtx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return MODE_CFB_Decrypt(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_aes_ctr.c b/crypto/modes/src/noasm_aes_ctr.c new file mode 100644 index 00000000..aee8384d --- /dev/null +++ b/crypto/modes/src/noasm_aes_ctr.c @@ -0,0 +1,30 @@ +/* + * 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_modes_ctr.h" + +int32_t AES_CTR_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CTR_Crypt(ctx, in, out, len); +} + +int32_t AES_CTR_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CTR_Crypt(ctx, in, out, len); +} +#endif diff --git a/crypto/modes/src/noasm_aes_ecb.c b/crypto/modes/src/noasm_aes_ecb.c new file mode 100644 index 00000000..19ca07aa --- /dev/null +++ b/crypto/modes/src/noasm_aes_ecb.c @@ -0,0 +1,67 @@ +/* + * 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_errno.h" +#include "crypt_modes_ecb.h" +#include "bsl_err_internal.h" + +#define AES_ECB_BLOCK_SIZE 16 + +// process 64block +int32_t AES_ECB_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + // ctx, in, out, these pointer have been judged at the EAL layer and is not judged again here. + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t count = len >> 4; // aes block must be 16 bytes + uint32_t i; + const uint8_t *input = in; + uint8_t *output = out; + for (i = 0; i < count; i++) { + (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, input, output, AES_ECB_BLOCK_SIZE); + input += AES_ECB_BLOCK_SIZE; + output += AES_ECB_BLOCK_SIZE; + } + return CRYPT_SUCCESS; +} + +int32_t AES_ECB_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + // ctx, in, out, these pointer have been judged at the EAL layer and is not judged again here. + if (ctx->ciphCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((len & 0x0f) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_MODE_ERR_INPUT_LEN); + return CRYPT_MODE_ERR_INPUT_LEN; + } + uint32_t count = len >> 4; // aes block must be 16 bytes + uint32_t i; + const uint8_t *input = in; + uint8_t *output = out; + for (i = 0; i < count; i++) { + (void)ctx->ciphMeth->decrypt(ctx->ciphCtx, input, output, AES_ECB_BLOCK_SIZE); + input += AES_ECB_BLOCK_SIZE; + output += AES_ECB_BLOCK_SIZE; + } + return CRYPT_SUCCESS; +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_aes_gcm.c b/crypto/modes/src/noasm_aes_gcm.c new file mode 100644 index 00000000..6244a8c0 --- /dev/null +++ b/crypto/modes/src/noasm_aes_gcm.c @@ -0,0 +1,30 @@ +/* + * 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_GCM) + +#include "crypt_modes_gcm.h" + +int32_t AES_GCM_EncryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_GCM_Encrypt(ctx, in, out, len); +} + +int32_t AES_GCM_DecryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_GCM_Decrypt(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_ghash.c b/crypto/modes/src/noasm_ghash.c new file mode 100644 index 00000000..9d71e927 --- /dev/null +++ b/crypto/modes/src/noasm_ghash.c @@ -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" +#ifdef HITLS_CRYPTO_GCM + +#include "bsl_sal.h" +#include "crypt_utils.h" +#include "modes_local.h" + +/* table[i] = (P^4)*i, P = 0x4000000000000000, i = 0...16 */ +static const uint64_t TABLE_P4_BITS[16] = { + 0x0000000000000000, 0x1c20000000000000, 0x3840000000000000, 0x2460000000000000, + 0x7080000000000000, 0x6ca0000000000000, 0x48c0000000000000, 0x54e0000000000000, + 0xe100000000000000, 0xfd20000000000000, 0xd940000000000000, 0xc560000000000000, + 0x9180000000000000, 0x8da0000000000000, 0xa9c0000000000000, 0xb5e0000000000000 +}; + +// Calculate n*H, n is in 0 .... 16 +void GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE], MODES_GCM_GF128 hTable[16]) +{ + uint32_t i; + uint32_t j; + const uint64_t r = 0xE100000000000000; + hTable[0].h = 0; + hTable[0].l = 0; + // The intermediate term of the table (16 / 2 = = 8) is H itself. + hTable[8].h = Uint64FromBeBytes(key); + // The intermediate term of the table (16 / 2 = = 8) is H itself. + hTable[8].l = Uint64FromBeBytes(key + sizeof(uint64_t)); + + for (i = 4; i > 0; i >>= 1) { // 4-bit table, the value of the 2^n item is calculated first. + // cyclically shift to right by 1bit. The upper 1 bit of h is combined with the lower 63 bits of l. + hTable[i].l = (hTable[ i * 2].h << 63) | (hTable[ i * 2].l >> 1); + hTable[i].h = (hTable[ i * 2].h >> 1) ^ ((hTable[ i * 2].l & 1) * r); // the value of the 2^n item + } + for (i = 1; i < 16; i <<= 1) { + for (j = 1; j < i; j++) { + hTable[i + j].h = hTable[i].h ^ hTable[j].h; + hTable[i + j].l = hTable[i].l ^ hTable[j].l; + } + } +} + +// Calculate t = t * H +void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], const uint8_t *in, uint32_t inLen) +{ + MODES_GCM_GF128 x; + uint8_t r; + uint8_t h, l, tag; // Ciphertext information, digest information, and non-sensitive information. + const uint8_t *tempIn = in; + for (uint32_t i = 0; i < inLen; i += GCM_BLOCKSIZE) { + uint8_t cnt = GCM_BLOCKSIZE - 1; + x.h = 0; + x.l = 0; + while (1) { + tag = t[cnt] ^ tempIn[cnt]; + + l = tag & 0xf; + h = (tag >> 4) & 0xf; + x.h ^= hTable[l].h; + x.l ^= hTable[l].l; + + r = (x.l & 0xf); + // Cyclically shift to right by 4 bits. The upper 4 bits of h is combined with the lower 60 bits of l. + x.l = (x.h << 60) | (x.l >> 4); + x.h = (x.h >> 4); // Cyclically shift to right by 4 bits. + x.h ^= TABLE_P4_BITS[r]; + + x.h ^= hTable[h].h; + x.l ^= hTable[h].l; + if (cnt == 0) { + break; + } + cnt--; + r = (x.l & 0xf); + // Cyclically shift to right by 4 bits. The upper 4 bits of h is combined with the lower 60 bits of l. + x.l = (x.h << 60) | (x.l >> 4); + x.h = (x.h >> 4); // Cyclically shift to right by 4 bits. + x.h ^= TABLE_P4_BITS[r]; + } + tempIn += GCM_BLOCKSIZE; + Uint64ToBeBytes(x.h, t); + Uint64ToBeBytes(x.l, t + 8); + } + // Clear sensitive information. + BSL_SAL_CleanseData(&x, sizeof(MODES_GCM_GF128)); + BSL_SAL_CleanseData(&r, sizeof(uint8_t)); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_poly1305.c b/crypto/modes/src/noasm_poly1305.c new file mode 100644 index 00000000..abbeb251 --- /dev/null +++ b/crypto/modes/src/noasm_poly1305.c @@ -0,0 +1,178 @@ +/* + * 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_CHACHA20POLY1305 + +#include "bsl_sal.h" +#include "crypt_utils.h" +#include "poly1305_core.h" + +// Operation for blocks. The return value is the length of the remaining unprocessed data. +uint32_t Poly1305Block(Poly1305Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint32_t padbit) +{ + uint32_t a[5], r[4]; + uint64_t b[8]; + // RFC_7539-2.5.1 for loop internal operation + a[0] = ctx->acc[0]; + a[1] = ctx->acc[1]; + a[2] = ctx->acc[2]; + a[3] = ctx->acc[3]; + a[4] = ctx->acc[4]; + r[0] = ctx->r[0]; + r[1] = ctx->r[1]; + r[2] = ctx->r[2]; + r[3] = ctx->r[3]; + + const uint8_t *off = data; + uint32_t len = dataLen; + + while (len >= POLY1305_BLOCKSIZE) { + // a = acc + inputret + b[0] = (uint64_t)a[0] + GET_UINT32_LE(off, 0); + b[1] = (uint64_t)a[1] + GET_UINT32_LE(off, 4) + (b[0] >> 32); + b[2] = (uint64_t)a[2] + GET_UINT32_LE(off, 8) + (b[1] >> 32); + b[3] = (uint64_t)a[3] + GET_UINT32_LE(off, 12) + (b[2] >> 32); + + a[0] = (uint32_t)b[0]; + a[1] = (uint32_t)b[1]; + a[2] = (uint32_t)b[2]; + a[3] = (uint32_t)b[3]; + // Upper 32 bits of b[3] carry to a[4]. Because a[4] <= 4, this processing can never overflow + a[4] += (uint32_t)(b[3] >> 32) + padbit; + + /* Lower bits of the data product. Because the high bits of each term of r are processed, + there is no carry in the following polynomial multiplication and addition. */ + b[0] = (uint64_t)a[0] * r[0]; + b[1] = (uint64_t)a[0] * r[1] + (uint64_t)a[1] * r[0]; + b[2] = (uint64_t)a[0] * r[2] + (uint64_t)a[1] * r[1] + (uint64_t)a[2] * r[0]; + b[3] = (uint64_t)a[0] * r[3] + (uint64_t)a[1] * r[2] + (uint64_t)a[2] * r[1] + (uint64_t)a[3] * r[0]; + + /** + * Higher bits of the data product. Because the high bits of each term of r are processed, + * there is no carry in the following polynomial multiplication and addition. + */ + // (Ensure that the calculation (b[4] * 5) does not overflow, calculate (a[4] * r[0]) items later.) + b[4] = (uint64_t)a[1] * r[3] + (uint64_t)a[2] * r[2] + (uint64_t)a[3] * r[1]; + b[5] = (uint64_t)a[2] * r[3] + (uint64_t)a[3] * r[2] + (uint64_t)a[4] * r[1]; + b[6] = (uint64_t)a[3] * r[3] + (uint64_t)a[4] * r[2]; + b[7] = (uint64_t)a[4] * r[3]; + /** + * The upper bits are multiplied by 5/4, because r1, r[2], r3 is processed, + * so the above values are divisible by 4. Because the high bits of each term of r are processed, + * there is no carry in the following polynomial multiplication and addition: (3 * 5) < 0xF + */ + b[4] = (b[4] >> 2) + b[4]; + b[5] = (b[5] >> 2) + b[5]; + b[6] = (b[6] >> 2) + b[6]; + b[7] = (b[7] >> 2) + b[7]; + /* After offset 130 bits, the combination is obtained a0 = b[4] * 5 + b[0].... + Because the high bits of each term of r are processed, + there is no carry in the following polynomial multiplication and addition. */ + b[0] += (b[4] & 0xFFFFFFFF); + b[1] += (b[0] >> 32) + (b[4] >> 32) + (b[5] & 0xFFFFFFFF); + b[2] += (b[1] >> 32) + (b[5] >> 32) + (b[6] & 0xFFFFFFFF); + b[3] += (b[2] >> 32) + (b[6] >> 32) + (b[7] & 0xFFFFFFFF); + a[4] = a[4] * r[0] + (uint32_t)(b[3] >> 32) + (uint32_t)(b[7] >> 32); + b[0] = (uint32_t)b[0]; + b[1] = (uint32_t)b[1]; + b[2] = (uint32_t)b[2]; + b[3] = (uint32_t)b[3]; + // Shift the upper bits of a4 by 130 bits and then multiply it by 5. + // The amount of a4 data is small and carry cannot be occurred. + b[0] += (a[4] >> 2) + (a[4] & 0xFFFFFFFC); + a[4] &= 0x3; + + /* Process carry */ + b[1] += (b[0] >> 32); + b[2] += (b[1] >> 32); + b[3] += (b[2] >> 32); + a[4] += (uint32_t)(b[3] >> 32); + + a[0] = (uint32_t)b[0]; + a[1] = (uint32_t)b[1]; + a[2] = (uint32_t)b[2]; + a[3] = (uint32_t)b[3]; + len -= POLY1305_BLOCKSIZE; + off += POLY1305_BLOCKSIZE; + } + + ctx->acc[0] = a[0]; + ctx->acc[1] = a[1]; + ctx->acc[2] = a[2]; + ctx->acc[3] = a[3]; + ctx->acc[4] = a[4]; + + // Clear sensitive information. + BSL_SAL_CleanseData(a, sizeof(a)); + BSL_SAL_CleanseData(r, sizeof(r)); + BSL_SAL_CleanseData(b, sizeof(b)); + return len; +} + +void Poly1305Last(Poly1305Ctx *ctx, uint8_t mac[POLY1305_TAGSIZE]) +{ + uint32_t a[5]; + uint64_t b[5]; + a[0] = ctx->acc[0]; + a[1] = ctx->acc[1]; + a[2] = ctx->acc[2]; + a[3] = ctx->acc[3]; + a[4] = ctx->acc[4]; + /* Check whether it is greater than p. */ + b[0] = (uint64_t)(a[0]) + 5; + b[1] = a[1] + (b[0] >> 32); + b[2] = a[2] + (b[1] >> 32); + b[3] = a[3] + (b[2] >> 32); + b[4] = a[4] + (b[3] >> 32); + /* Obtain the mask. If there is a carry, the number is greater than p. */ + // Whether a value exists in the upper bits of b[4], 128bit + 2bit = 130bit + uint32_t mask = 0 - (uint32_t)((b[4] >> 2) & 0x1); + b[0] = (uint32_t)b[0] & mask; + b[1] = (uint32_t)b[1] & mask; + b[2] = (uint32_t)b[2] & mask; + b[3] = (uint32_t)b[3] & mask; + mask = ~mask; + b[0] = (a[0] & mask) | (uint32_t)b[0]; + b[1] = (a[1] & mask) | (uint32_t)b[1]; + b[2] = (a[2] & mask) | (uint32_t)b[2]; + b[3] = (a[3] & mask) | (uint32_t)b[3]; + /** + * Finally, the value of the secret key "s" is added to the accumulator, + * and the 128 least significant bits are serialized in little-endian + * order to form the tag + */ + // Adding s at the end does not require modulo processing. + b[0] += ctx->s[0]; + b[1] += ctx->s[1] + (b[0] >> 32); + b[2] += ctx->s[2] + (b[1] >> 32); + b[3] += ctx->s[3] + (b[2] >> 32); + PUT_UINT32_LE(b[0], mac, 0); + PUT_UINT32_LE(b[1], mac, 4); + PUT_UINT32_LE(b[2], mac, 8); + PUT_UINT32_LE(b[3], mac, 12); + + // Clear sensitive information. + BSL_SAL_CleanseData(a, sizeof(a)); + BSL_SAL_CleanseData(b, sizeof(b)); +} + +// Clear the residual sensitive information in the register. +// This function is implemented only when the assembly function is enabled. +void Poly1305CleanRegister(void) +{ + return; +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_sm4_cbc.c b/crypto/modes/src/noasm_sm4_cbc.c new file mode 100644 index 00000000..3fdb61cf --- /dev/null +++ b/crypto/modes/src/noasm_sm4_cbc.c @@ -0,0 +1,34 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_CBC) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_modes.h" +#include "crypt_modes_cbc.h" + +int32_t MODE_SM4_CBC_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CBC_Encrypt(ctx, in, out, len); +} + +int32_t MODE_SM4_CBC_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CBC_Decrypt(ctx, in, out, len); +} + +#endif diff --git a/crypto/modes/src/noasm_sm4_cfb.c b/crypto/modes/src/noasm_sm4_cfb.c new file mode 100644 index 00000000..d4c8aaac --- /dev/null +++ b/crypto/modes/src/noasm_sm4_cfb.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_SM4) && defined(HITLS_CRYPTO_CFB) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_modes.h" +#include "crypt_modes_cfb.h" + +int32_t MODES_SM4_CFB_SetEncryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + return MODE_SetEncryptKey(ctx->modeCtx, key, len); +} + +int32_t MODE_SM4_CFB_Encrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CFB_Encrypt(ctx, in, out, len); +} + +int32_t MODE_SM4_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CFB_Decrypt(ctx, in, out, len); +} +#endif diff --git a/crypto/modes/src/noasm_sm4_ctr.c b/crypto/modes/src/noasm_sm4_ctr.c new file mode 100644 index 00000000..8408ecb2 --- /dev/null +++ b/crypto/modes/src/noasm_sm4_ctr.c @@ -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" +#if defined(HITLS_CRYPTO_SM4) && defined(HITLS_CRYPTO_CTR) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_modes.h" +#include "crypt_modes_ctr.h" + +int32_t MODE_SM4_CTR_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CTR_Crypt(ctx, in, out, len); +} + +int32_t MODE_SM4_CTR_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_CTR_Crypt(ctx, in, out, len); +} +#endif diff --git a/crypto/modes/src/noasm_sm4_gcm.c b/crypto/modes/src/noasm_sm4_gcm.c new file mode 100644 index 00000000..116b3fd3 --- /dev/null +++ b/crypto/modes/src/noasm_sm4_gcm.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_SM4) && defined(HITLS_CRYPTO_GCM) + +#include "crypt_sm4.h" +#include "crypt_modes.h" +#include "crypt_modes_gcm.h" + +int32_t MODES_SM4_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + return MODES_GCM_SetKey(ctx, key, len); +} + +int32_t MODES_SM4_GCM_EncryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_GCM_Encrypt(ctx, in, out, len); +} + +int32_t MODES_SM4_GCM_DecryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODES_GCM_Decrypt(ctx, in, out, len); +} + +#endif \ No newline at end of file diff --git a/crypto/modes/src/noasm_sm4_ofb.c b/crypto/modes/src/noasm_sm4_ofb.c new file mode 100644 index 00000000..6df98d39 --- /dev/null +++ b/crypto/modes/src/noasm_sm4_ofb.c @@ -0,0 +1,34 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_OFB) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_modes.h" +#include "crypt_modes_ofb.h" + +int32_t MODE_SM4_OFB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_OFB_Crypt(ctx, in, out, len); +} + +int32_t MODE_SM4_OFB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return MODE_OFB_Crypt(ctx, in, out, len); +} + +#endif diff --git a/crypto/modes/src/noasm_sm4_setkey.c b/crypto/modes/src/noasm_sm4_setkey.c new file mode 100644 index 00000000..7ac2b175 --- /dev/null +++ b/crypto/modes/src/noasm_sm4_setkey.c @@ -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_CRYPTO_SM4 + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_modes.h" + +int32_t MODES_SM4_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len) +{ + return MODE_SetEncryptKey(ctx, key, len); +} + +int32_t MODES_SM4_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len) +{ + return MODE_SetDecryptKey(ctx, key, len); +} + +#endif // HITLS_CRYPTO_SM4 diff --git a/crypto/modes/src/noasm_sm4_xts.c b/crypto/modes/src/noasm_sm4_xts.c new file mode 100644 index 00000000..7244f926 --- /dev/null +++ b/crypto/modes/src/noasm_sm4_xts.c @@ -0,0 +1,56 @@ +/* + * 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_SM4) && defined(HITLS_CRYPTO_XTS) + +#include "bsl_err_internal.h" +#include "crypt_sm4.h" +#include "crypt_errno.h" +#include "crypt_modes_xts.h" + +void MODES_SM4_XTS_Clean(MODE_XTS_Ctx *ctx) +{ + MODE_XTS_Clean(ctx); +} + +int32_t MODES_SM4_XTS_SetEncryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + return MODE_XTS_SetEncryptKey(ctx, key, len); +} + +int32_t MODES_SM4_XTS_SetDecryptKey(MODE_XTS_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + return MODE_XTS_SetDecryptKey(ctx, key, len); +} + +int32_t MODES_SM4_XTS_Encrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return MODE_XTS_Encrypt(ctx, in, out, len); +} + +int32_t MODES_SM4_XTS_Decrypt(MODE_XTS_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL || in == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return MODE_XTS_Decrypt(ctx, in, out, len); +} +#endif \ No newline at end of file diff --git a/crypto/modes/src/poly1305_core.h b/crypto/modes/src/poly1305_core.h new file mode 100644 index 00000000..d89e0f27 --- /dev/null +++ b/crypto/modes/src/poly1305_core.h @@ -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 POLY1305_CORE_H +#define POLY1305_CORE_H + + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_CHACHA20POLY1305 + +#include "crypt_modes_chacha20poly1305.h" + + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define POLY1305_BLOCKSIZE 16 +#define POLY1305_TAGSIZE 16 +#define POLY1305_KEYSIZE 32 + +uint32_t Poly1305Block(Poly1305Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint32_t padbit); +void Poly1305Last(Poly1305Ctx *ctx, uint8_t mac[POLY1305_TAGSIZE]); +void Poly1305CleanRegister(void); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_CHACHA20POLY1305 + +#endif // POLY1305_CORE_H \ No newline at end of file diff --git a/crypto/paillier/include/crypt_paillier.h b/crypto/paillier/include/crypt_paillier.h new file mode 100644 index 00000000..b4e0ea92 --- /dev/null +++ b/crypto/paillier/include/crypt_paillier.h @@ -0,0 +1,291 @@ +/* + * 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_PAILLIER_H +#define CRYPT_PAILLIER_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_PAILLIER + +#include +#include +#include "crypt_bn.h" +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define PAILLIER_MAX_MODULUS_BITS 16384 + +/* Paillier*/ +typedef struct PAILLIER_Ctx CRYPT_PAILLIER_Ctx; +typedef struct PAILLIER_Para CRYPT_PAILLIER_Para; + + +/* Paillier method*/ +/** + * @ingroup paillier + * @brief Allocate paillier context memory space. + * + * @retval (CRYPT_PAILLIER_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer. +*/ +CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_NewCtx(void); + +/** + * @ingroup paillier + * @brief Copy the Paillier context. After the duplication is complete, call the CRYPT_PAILLIER_FreeCtx to release the memory. + * + * @param ctx [IN] PAILLIER context + * + * @return CRYPT_PAILLIER_Ctx Paillier context pointer + * If the operation fails, a null value is returned. + */ +CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_DupCtx(CRYPT_PAILLIER_Ctx *keyCtx); + +/** + * @ingroup paillier + * @brief Create paillier key parameter structure + * + * @param para [IN] PAILLIER External parameter + * + * @retval (CRYPT_PAILLIER_Para *) Pointer to the allocated memory space of the structure + * @retval NULL Invalid null pointer. + */ +CRYPT_PAILLIER_Para *CRYPT_PAILLIER_NewPara(const CRYPT_PaillierPara *para); + +/** + * @ingroup paillier + * @brief release paillier key context structure + * + * @param ctx [IN] Pointer to the context structure to be released. The ctx is set NULL by the invoker. + */ +void CRYPT_PAILLIER_FreeCtx(CRYPT_PAILLIER_Ctx *ctx); + +/** + * @ingroup paillier + * @brief Release paillier key parameter structure + * + * @param para [IN] Storage pointer in the parameter structure to be released. The parameter is set NULL by the invoker. + */ +void CRYPT_PAILLIER_FreePara(CRYPT_PAILLIER_Para *para); + +/** + * @ingroup paillier + * @brief Set the data of the key parameter structure to the key structure. + * + * @param ctx [OUT] Paillier context structure for which related parameters need to be set + * @param para [IN] Key parameter structure + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_PAILLIER_ERR_KEY_BITS The expected key length does not meet the requirements. + * @retval CRYPT_PAILLIER_ERR_E_VALUE The expected value of e does not meet the requirements. + * @retval CRYPT_MEM_ALLOC_FAIL internal memory allocation error + * @retval CRYPT_SUCCESS set successfully. + */ +int32_t CRYPT_PAILLIER_SetPara(CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PAILLIER_Para *para); + +/** + * @ingroup paillier + * @brief Obtain the valid length of the key. + * + * @param ctx [IN] Structure from which the key length is expected to be obtained + * + * @retval 0: The input is incorrect or the corresponding key structure does not have a valid key length. + * @retval uint32_t: Valid key length + */ +uint32_t CRYPT_PAILLIER_GetBits(const CRYPT_PAILLIER_Ctx *ctx); + +/** + * @ingroup paillier + * @brief Generate the Paillier key pair. + * + * @param ctx [IN/OUT] paillier context structure + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_PAILLIER_ERR_KEY_BITS The value of e in the context structure does not meet the requirements. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_PAILLIER_Gen(CRYPT_PAILLIER_Ctx *ctx); + +/** + * @ingroup paillier + * @brief Paillier public key encryption + * + * @param ctx [IN] Paillier context structure + * @param input [IN] Information to be encrypted + * @param inputLen [IN] Length of the information to be encrypted + * @param out [OUT] Pointer to the encrypted information output. + * @param outLen [IN/OUT] Pointer to the length of the encrypted information. + * Before being transferred, the value must be set to the maximum length of the array. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_PAILLIER_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_PAILLIER_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS encryption succeeded. + */ +int32_t CRYPT_PAILLIER_PubEnc(const CRYPT_PAILLIER_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup paillier + * @brief Paillier private key decryption + * + * @param ctx [IN] Paillier context structure + * @param ciphertext [IN] Information to be decrypted + * @param bits [IN] Length of the information to be decrypted + * @param out [OUT] Pointer to the decrypted information output. + * @param outLen [IN/OUT] Pointer to the length of the decrypted information. + * Before being transferred, the value must be set to the maximum length of the array. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_PAILLIER_ERR_DEC_BITS Incorrect length of the encrypted private key. + * @retval CRYPT_PAILLIER_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_PAILLIER_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Decrypted Successfully + */ +int32_t CRYPT_PAILLIER_PrvDec(const CRYPT_PAILLIER_Ctx *ctx, const BN_BigNum *ciphertext, uint32_t bits, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup paillier + * @brief Paillier Set the private key information. + * + * @param ctx [OUT] paillier context structure + * @param prv [IN] Private key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_PAILLIER_ERR_KEY_BITS The key length does not meet the requirements. + * @retval CRYPT_PAILLIER_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_PAILLIER_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The private key is successfully set. + */ +int32_t CRYPT_PAILLIER_SetPrvKey(CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PaillierPrv *prv); + +/** + * @ingroup paillier + * @brief Paillier Set the public key information. + * + * @param ctx [OUT] Paillier context structure + * @param pub [IN] Public key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_PAILLIER_ERR_KEY_BITS The key length does not meet the requirements. + * @retval CRYPT_PAILLIER_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The public key is successfully set. + */ +int32_t CRYPT_PAILLIER_SetPubKey(CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PaillierPub *pub); + +/** + * @ingroup paillier + * @brief Paillier Obtain the private key information. + * + * @param ctx [IN] Paillier context structure + * @param prv [OUT] Private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The private key is obtained successfully. + */ +int32_t CRYPT_PAILLIER_GetPrvKey(const CRYPT_PAILLIER_Ctx *ctx, CRYPT_PaillierPrv *prv); + +/** + * @ingroup paillier + * @brief Paillier Obtain the public key information. + * + * @param ctx [IN] Paillier context structure + * @param pub [OUT] Public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The public key is obtained successfully. + */ +int32_t CRYPT_PAILLIER_GetPubKey(const CRYPT_PAILLIER_Ctx *ctx, CRYPT_PaillierPub *pub); + +/** + * @ingroup paillier + * @brief PAILLIER public key encryption + * + * @param ctx [IN] PAILLIER context structure + * @param data [IN] Information to be encrypted + * @param dataLen [IN] Length of the information to be encrypted + * @param out [OUT] Pointer to the encrypted information output. + * @param outLen [OUT] Pointer to the length of the encrypted information + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_PAILLIER_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_PAILLIER_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A safe function error occurs. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_EAL_ALG_NOT_SUPPORT does not register the encryption method. + * @retval CRYPT_SUCCESS encryption succeeded. +*/ +int32_t CRYPT_PAILLIER_Encrypt(CRYPT_PAILLIER_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup paillier + * @brief PAILLIER private key decryption + * + * @param ctx [IN] PAILLIER context structure + * @param data [IN] Information to be decrypted + * @param dataLen [IN] Length of the information to be decrypted + * @param out [OUT] Pointer to the output information after decryption. + * @param outLen [OUT] Pointer to the length of the decrypted information + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_PAILLIER_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_PAILLIER_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval CRYPT_EAL_ALG_NOT_SUPPORT does not register the decryption method. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Decryption succeeded. + */ +int32_t CRYPT_PAILLIER_Decrypt(CRYPT_PAILLIER_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup paillier + * @brief PAILLIER get security bits + * + * @param ctx [IN] PAILLIER Context structure + * + * @retval security bits + */ +int32_t CRYPT_PAILLIER_GetSecBits(const CRYPT_PAILLIER_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_PAILLIER + +#endif // CRYPT_PAILLIER_H \ No newline at end of file diff --git a/crypto/paillier/src/paillier_encdec.c b/crypto/paillier/src/paillier_encdec.c new file mode 100644 index 00000000..6ddd4457 --- /dev/null +++ b/crypto/paillier/src/paillier_encdec.c @@ -0,0 +1,340 @@ +/* + * 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_PAILLIER + +#include "crypt_utils.h" +#include "crypt_paillier.h" +#include "paillier_local.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "securec.h" +#include "bsl_err_internal.h" + +int32_t CRYPT_PAILLIER_PubEnc(const CRYPT_PAILLIER_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + CRYPT_PAILLIER_PubKey *pubKey = ctx->pubKey; + if (pubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + uint32_t bits = CRYPT_PAILLIER_GetBits(ctx); + BN_Optimizer *optimizer = BN_OptimizerCreate(); + if (optimizer == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + BN_BigNum *m = BN_Create(bits); + BN_BigNum *r = BN_Create(bits); + + BN_BigNum *gm = BN_Create(bits); + BN_BigNum *rn = BN_Create(bits); + + BN_BigNum *result = BN_Create(bits); + + bool createFailed = (m == NULL || r == NULL || gm == NULL || rn == NULL || result == NULL); + if (createFailed) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto OUT; + } + + ret = BN_Bin2Bn(m, input, inputLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + // Check whether m is less than n and non-negative + if (BN_Cmp(m, pubKey->n) >= 0 || BN_IsNegative(m)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE); + ret = CRYPT_PAILLIER_ERR_INPUT_VALUE; + goto OUT; + } + + ret = BN_RandRange(r, pubKey->n); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + BN_BigNum *gcd_result = BN_Create(bits); + if (gcd_result == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + BN_Destroy(gcd_result); + goto OUT; + } + + while (true) { + // Check whether r is relatively prime to n, if not, regenerate r + ret = BN_Gcd(gcd_result, r, pubKey->n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BN_Destroy(gcd_result); + goto OUT; + } + if (BN_IsOne(gcd_result)) { + BN_Destroy(gcd_result); + break; + } + ret = BN_RandRange(r, pubKey->n); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BN_Destroy(gcd_result); + goto OUT; + } + } + + ret = BN_ModExp(gm, pubKey->g, m, pubKey->n2, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_ModExp(rn, r, pubKey->n, pubKey->n2, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_ModMul(result, gm, rn, pubKey->n2, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_Bn2Bin(result, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } +OUT : + BN_Destroy(m); + BN_Destroy(r); + BN_Destroy(gm); + BN_Destroy(rn); + BN_Destroy(result); + BN_OptimizerDestroy(optimizer); + return ret; +} + +int32_t CRYPT_PAILLIER_PrvDec(const CRYPT_PAILLIER_Ctx *ctx, const BN_BigNum *ciphertext, uint32_t bits, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + CRYPT_PAILLIER_PrvKey *prvKey = ctx->prvKey; + if (prvKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + BN_Optimizer *optimizer = BN_OptimizerCreate(); + if (optimizer == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + BN_BigNum *m = BN_Create(bits); + BN_BigNum *result = BN_Create(bits); + + bool createFailed = (m == NULL || result == NULL); + + if (createFailed) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto OUT; + } + + ret = BN_ModExp(m, ciphertext, prvKey->lambda, prvKey->n2, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_SubLimb(result, m, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_Div(result, NULL, result, prvKey->n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_ModMul(result, result, prvKey->mu, prvKey->n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_Bn2Bin(result, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } +OUT : + BN_Destroy(m); + BN_Destroy(result); + BN_OptimizerDestroy(optimizer); + return ret; +} + +static int32_t EncryptInputCheck(const CRYPT_PAILLIER_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + const uint8_t *out, const uint32_t *outLen) +{ + if (ctx == NULL || (input == NULL && inputLen != 0) || out == NULL || outLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->pubKey == NULL) { + // Check whether the public key information exists. + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_NO_KEY_INFO); + return CRYPT_PAILLIER_NO_KEY_INFO; + } + // Check whether the length of the out is sufficient to place the encryption information. + uint32_t bits = CRYPT_PAILLIER_GetBits(ctx); + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH); + return CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH; + } + if (inputLen > BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_ENC_BITS); + return CRYPT_PAILLIER_ERR_ENC_BITS; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PAILLIER_Encrypt(CRYPT_PAILLIER_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret = EncryptInputCheck(ctx, data, dataLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = CRYPT_PAILLIER_PubEnc(ctx, data, dataLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t DecryptInputCheck(const CRYPT_PAILLIER_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *out, const uint32_t *outLen) +{ + if (ctx == NULL || data == NULL || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->prvKey == NULL) { + // Check whether the private key information exists. + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_NO_KEY_INFO); + return CRYPT_PAILLIER_NO_KEY_INFO; + } + // Check whether the length of the out is sufficient to place the decryption information. + uint32_t bits = CRYPT_PAILLIER_GetBits(ctx); + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH); + return CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH; + } + if (dataLen != BN_BITS_TO_BYTES(bits) * 2) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_DEC_BITS); + return CRYPT_PAILLIER_ERR_DEC_BITS; + } + + return CRYPT_SUCCESS; +} + +static int32_t CRYPT_PAILLIER_CheckCiphertext(const BN_BigNum* ciphertext, const CRYPT_PAILLIER_PrvKey* prvKey) +{ + if (BN_Cmp(ciphertext, prvKey->n2) >= 0 || BN_IsNegative(ciphertext)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE); + return CRYPT_PAILLIER_ERR_INPUT_VALUE; + } + int32_t ret = CRYPT_SUCCESS; + BN_BigNum *gcd_result = BN_Create(BN_Bits(ciphertext)); + BN_Optimizer *optimizer = BN_OptimizerCreate(); + if (gcd_result == NULL || optimizer == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto OUT; + } + ret = BN_Gcd(gcd_result, ciphertext, prvKey->n2, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + if (BN_IsOne(gcd_result) == false) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE); + ret = CRYPT_PAILLIER_ERR_INPUT_VALUE; + goto OUT; + } +OUT: + BN_Destroy(gcd_result); + BN_OptimizerDestroy(optimizer); + return ret; +} + +int32_t CRYPT_PAILLIER_Decrypt(CRYPT_PAILLIER_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret = DecryptInputCheck(ctx, data, dataLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + uint32_t bits = CRYPT_PAILLIER_GetBits(ctx); + BN_BigNum *c = BN_Create(bits); + + if (c == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto OUT; + } + + ret = BN_Bin2Bn(c, data, dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + // check whether c is in Zn2* + ret = CRYPT_PAILLIER_CheckCiphertext(c, ctx->prvKey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = CRYPT_PAILLIER_PrvDec(ctx, c, bits, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + +OUT: + BN_Destroy(c); + return ret; +} + +#endif // HITLS_CRYPTO_PAILLIER \ No newline at end of file diff --git a/crypto/paillier/src/paillier_keygen.c b/crypto/paillier/src/paillier_keygen.c new file mode 100644 index 00000000..a6333e95 --- /dev/null +++ b/crypto/paillier/src/paillier_keygen.c @@ -0,0 +1,525 @@ +/* + * 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_PAILLIER + +#include "crypt_paillier.h" +#include "paillier_local.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" + + +CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_NewCtx(void) +{ + CRYPT_PAILLIER_Ctx *ctx = NULL; + + ctx = (CRYPT_PAILLIER_Ctx *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Ctx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(ctx, sizeof(CRYPT_PAILLIER_Ctx), 0, sizeof(CRYPT_PAILLIER_Ctx)); + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +static CRYPT_PAILLIER_PubKey *PaillierPubKeyDupCtx(CRYPT_PAILLIER_PubKey *pubKey) +{ + CRYPT_PAILLIER_PubKey *newPubKey = (CRYPT_PAILLIER_PubKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PubKey)); + if (newPubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newPubKey, sizeof(CRYPT_PAILLIER_PubKey), 0, sizeof(CRYPT_PAILLIER_PubKey)); + + GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->n, pubKey->n, BN_Dup(pubKey->n), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->g, pubKey->g, BN_Dup(pubKey->g), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->n2, pubKey->n2, BN_Dup(pubKey->n2), CRYPT_MEM_ALLOC_FAIL); + + return newPubKey; + +ERR : + PAILLIER_FREE_PUB_KEY(newPubKey); + return NULL; +} + +static CRYPT_PAILLIER_PrvKey *PaillierPrvKeyDupCtx(CRYPT_PAILLIER_PrvKey *prvKey) +{ + CRYPT_PAILLIER_PrvKey *newPrvKey = (CRYPT_PAILLIER_PrvKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PrvKey)); + if (newPrvKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newPrvKey, sizeof(CRYPT_PAILLIER_PrvKey), 0, sizeof(CRYPT_PAILLIER_PrvKey)); + + GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->n, prvKey->n, BN_Dup(prvKey->n), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->lambda, prvKey->lambda, BN_Dup(prvKey->lambda), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->mu, prvKey->mu, BN_Dup(prvKey->mu), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPrvKey->n2, prvKey->n2, BN_Dup(prvKey->n2), CRYPT_MEM_ALLOC_FAIL); + + return newPrvKey; +ERR : + PAILLIER_FREE_PRV_KEY(newPrvKey); + return NULL; +} + +static CRYPT_PAILLIER_Para *PaillierParaDupCtx(CRYPT_PAILLIER_Para *para) +{ + CRYPT_PAILLIER_Para *newPara = (CRYPT_PAILLIER_Para *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Para)); + if (newPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newPara, sizeof(CRYPT_PAILLIER_Para), 0, sizeof(CRYPT_PAILLIER_Para)); + + newPara->bits = para->bits; + GOTO_ERR_IF_SRC_NOT_NULL(newPara->p, para->p, BN_Dup(para->p), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPara->q, para->q, BN_Dup(para->q), CRYPT_MEM_ALLOC_FAIL); + + return newPara; + +ERR : + PAILLIER_FREE_PARA(newPara); + return NULL; +} + +CRYPT_PAILLIER_Ctx *CRYPT_PAILLIER_DupCtx(CRYPT_PAILLIER_Ctx *keyCtx) +{ + if (keyCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + CRYPT_PAILLIER_Ctx *newKeyCtx = NULL; + newKeyCtx = BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Ctx)); + if (newKeyCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newKeyCtx, sizeof(CRYPT_PAILLIER_Ctx), 0, sizeof(CRYPT_PAILLIER_Ctx)); + + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->prvKey, keyCtx->prvKey, PaillierPrvKeyDupCtx(keyCtx->prvKey), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->pubKey, keyCtx->pubKey, PaillierPubKeyDupCtx(keyCtx->pubKey), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->para, keyCtx->para, PaillierParaDupCtx(keyCtx->para), CRYPT_MEM_ALLOC_FAIL); + BSL_SAL_ReferencesInit(&(newKeyCtx->references)); + return newKeyCtx; + +ERR : + CRYPT_PAILLIER_FreeCtx(newKeyCtx); + return NULL; +} + +static int32_t PaillierNewParaBasicCheck(const CRYPT_PaillierPara *para) +{ + if (para == NULL || para->p == NULL || para->pLen == 0 || para->q == NULL || para->qLen == 0 || para->bits <= 0 || para->bits > PAILLIER_MAX_MODULUS_BITS) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + /* the length of p and q should be equal to bits */ + if (para->pLen != BN_BITS_TO_BYTES(para->bits) || para->qLen != BN_BITS_TO_BYTES(para->bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_KEY_BITS); + return CRYPT_PAILLIER_ERR_KEY_BITS; + } + return CRYPT_SUCCESS; +} + +CRYPT_PAILLIER_Para *CRYPT_PAILLIER_NewPara(const CRYPT_PaillierPara *para) +{ + int32_t ret = PaillierNewParaBasicCheck(para); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + CRYPT_PAILLIER_Para *retPara = BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Para)); + if (retPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + retPara->bits = para->bits; + retPara->p = BN_Create(para->bits); + retPara->q = BN_Create(para->bits); + if (retPara->p == NULL || retPara->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + return retPara; +ERR: + CRYPT_PAILLIER_FreePara(retPara); + return NULL; +} + +void CRYPT_PAILLIER_FreeCtx(CRYPT_PAILLIER_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + int i = 0; + BSL_SAL_AtomicDownReferences(&(ctx->references), &i); + if (i > 0) { + return; + } + + BSL_SAL_ReferencesFree(&(ctx->references)); + PAILLIER_FREE_PRV_KEY(ctx->prvKey); + PAILLIER_FREE_PUB_KEY(ctx->pubKey); + PAILLIER_FREE_PARA(ctx->para); + BSL_SAL_Free(ctx); +} + +void CRYPT_PAILLIER_FreePara(CRYPT_PAILLIER_Para *para) +{ + if (para == NULL) { + return; + } + BN_Destroy(para->p); + BN_Destroy(para->q); + BSL_SAL_Free(para); +} + +void PAILLIER_FreePrvKey(CRYPT_PAILLIER_PrvKey *prvKey) +{ + if (prvKey == NULL) { + return; + } + BN_Destroy(prvKey->n); + BN_Destroy(prvKey->lambda); + BN_Destroy(prvKey->mu); + BN_Destroy(prvKey->n2); + BSL_SAL_Free(prvKey); +} + +void PAILLIER_FreePubKey(CRYPT_PAILLIER_PubKey *pubKey) +{ + if (pubKey == NULL) { + return; + } + BN_Destroy(pubKey->n); + BN_Destroy(pubKey->g); + BN_Destroy(pubKey->n2); + BSL_SAL_Free(pubKey); +} + +static int32_t IsPAILLIERSetParaVaild(const CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PAILLIER_Para *para) +{ + if (ctx == NULL || para == NULL || para->p == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->bits > PAILLIER_MAX_MODULUS_BITS || para->bits <= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_KEY_BITS); + return CRYPT_PAILLIER_ERR_KEY_BITS; + } + return CRYPT_SUCCESS; +} + +CRYPT_PAILLIER_Para *CRYPT_Paillier_DupPara(const CRYPT_PAILLIER_Para *para) +{ + CRYPT_PAILLIER_Para *paraCopy = BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_Para)); + if (paraCopy == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + paraCopy->bits = para->bits; + paraCopy->p = BN_Dup(para->p); + paraCopy->q = BN_Dup(para->q); + if (paraCopy->p == NULL || paraCopy->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + PAILLIER_FREE_PARA(paraCopy); + return NULL; + } + + return paraCopy; +} + +int32_t CRYPT_PAILLIER_SetPara(CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PAILLIER_Para *para) +{ + int32_t ret = IsPAILLIERSetParaVaild(ctx, para); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + CRYPT_PAILLIER_Para *paraCopy = CRYPT_Paillier_DupPara(para); + if (paraCopy == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + PAILLIER_FREE_PARA(ctx->para); + PAILLIER_FREE_PUB_KEY(ctx->pubKey); + PAILLIER_FREE_PRV_KEY(ctx->prvKey); + ctx->para = paraCopy; + return CRYPT_SUCCESS; +} + +uint32_t CRYPT_PAILLIER_GetBits(const CRYPT_PAILLIER_Ctx *ctx) +{ + if (ctx == NULL) { + return 0; + } + if (ctx->para != NULL) { + return ctx->para->bits; + } + if (ctx->prvKey != NULL) { + return BN_Bits(ctx->prvKey->lambda); + } + if (ctx->pubKey != NULL) { + return BN_Bits(ctx->pubKey->n); + } + return 0; +} + +CRYPT_PAILLIER_PrvKey *Paillier_NewPrvKey(uint32_t bits) +{ + CRYPT_PAILLIER_PrvKey *prvKey = (CRYPT_PAILLIER_PrvKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PrvKey)); + if (prvKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + prvKey->n = BN_Create(bits); + prvKey->lambda = BN_Create(bits); + prvKey->mu = BN_Create(bits); + prvKey->n2 = BN_Create(bits); + if (prvKey->n == NULL || prvKey->lambda == NULL || prvKey->mu == NULL || prvKey->n2 == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + PAILLIER_FREE_PRV_KEY(prvKey); + } + return prvKey; +} + +CRYPT_PAILLIER_PubKey *Paillier_NewPubKey(uint32_t bits) +{ + CRYPT_PAILLIER_PubKey *pubKey = (CRYPT_PAILLIER_PubKey *)BSL_SAL_Malloc(sizeof(CRYPT_PAILLIER_PubKey)); + if (pubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + pubKey->n = BN_Create(bits); + pubKey->g = BN_Create(bits); + pubKey->n2 = BN_Create(bits); + if (pubKey->n == NULL || pubKey->g == NULL || pubKey->n2 == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + PAILLIER_FREE_PUB_KEY(pubKey); + } + return pubKey; +} + +static int32_t Paillier_GenPQ(CRYPT_PAILLIER_Para *para, BN_Optimizer *optimizer) +{ + uint32_t bits = para->bits; + int32_t ret = BN_GenPrime(para->p, bits, true, optimizer, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_GenPrime(para->q, bits, true, optimizer, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +static int32_t Paillier_CalcPubKey(CRYPT_PAILLIER_PubKey *pubKey, CRYPT_PAILLIER_Para *para, BN_Optimizer *optimizer) +{ + int32_t ret = BN_Mul(pubKey->n, para->p, para->q, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_AddLimb(pubKey->g, pubKey->n, 1); // g = n + 1 + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Sqr(pubKey->n2, pubKey->n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +static int32_t Paillier_CalcLambda(BN_BigNum *lambda, CRYPT_PAILLIER_Para *para, BN_Optimizer *optimizer) +{ + uint32_t bits = para->bits; + BN_BigNum *pMinus1 = BN_Create(bits); + BN_BigNum *qMinus1 = BN_Create(bits); + int32_t ret = CRYPT_MEM_ALLOC_FAIL; + if (pMinus1 == NULL || qMinus1 == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto OUT; + } + ret = BN_SubLimb(pMinus1, para->p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + ret = BN_SubLimb(qMinus1, para->q, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + ret = BN_Lcm(lambda, pMinus1, qMinus1, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } +OUT : + BN_Destroy(pMinus1); + BN_Destroy(qMinus1); + return ret; +} + +static int32_t Paillier_CalcMu(BN_BigNum *mu, const BN_BigNum *lambda, CRYPT_PAILLIER_PubKey *pubKey, uint32_t bits, BN_Optimizer *optimizer) +{ + BN_BigNum *x = BN_Create(bits); + BN_BigNum *xMinus1 = BN_Create(bits); + BN_BigNum *Lx = BN_Create(bits); + + int32_t ret; + if (x == NULL || xMinus1 == NULL || Lx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto OUT; + } + + ret = BN_ModExp(x, pubKey->g, lambda, pubKey->n2, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_SubLimb(xMinus1, x, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_Div(Lx, NULL, xMinus1, pubKey->n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_ModInv(mu, Lx, pubKey->n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } +OUT : + BN_Destroy(x); + BN_Destroy(xMinus1); + BN_Destroy(Lx); + + return ret; +} + +int32_t Paillier_CalcPrvKey(CRYPT_PAILLIER_Ctx *ctx, BN_Optimizer *optimizer) +{ + int32_t ret = Paillier_CalcLambda(ctx->prvKey->lambda, ctx->para, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = Paillier_CalcMu(ctx->prvKey->mu, ctx->prvKey->lambda, ctx->pubKey, ctx->para->bits, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PAILLIER_Gen(CRYPT_PAILLIER_Ctx *ctx) +{ + if (ctx == NULL || ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret = CRYPT_MEM_ALLOC_FAIL; + BN_Optimizer *optimizer = NULL; + CRYPT_PAILLIER_Ctx *newCtx = CRYPT_PAILLIER_NewCtx(); + + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + newCtx->para = CRYPT_Paillier_DupPara(ctx->para); + if (newCtx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + + newCtx->prvKey = Paillier_NewPrvKey(newCtx->para->bits); + newCtx->pubKey = Paillier_NewPubKey(newCtx->para->bits); + optimizer = BN_OptimizerCreate(); + if (optimizer == NULL || newCtx->prvKey == NULL || newCtx->pubKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = Paillier_GenPQ(newCtx->para, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = Paillier_CalcPubKey(newCtx->pubKey, newCtx->para, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = Paillier_CalcPrvKey(newCtx, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(BN_Copy(newCtx->prvKey->n, newCtx->pubKey->n), ret); + GOTO_ERR_IF(BN_Copy(newCtx->prvKey->n2, newCtx->pubKey->n2), ret); + + PAILLIER_FREE_PARA(ctx->para); + PAILLIER_FREE_PRV_KEY(ctx->prvKey); + PAILLIER_FREE_PUB_KEY(ctx->pubKey); + BSL_SAL_ReferencesFree(&(newCtx->references)); + + ctx->prvKey = newCtx->prvKey; + ctx->pubKey = newCtx->pubKey; + ctx->para = newCtx->para; + BSL_SAL_FREE(newCtx); + BN_OptimizerDestroy(optimizer); + + return ret; + +ERR: + CRYPT_PAILLIER_FreeCtx(newCtx); + BN_OptimizerDestroy(optimizer); + return ret; +} + + +#endif // HITLS_CRYPTO_PAILLIER \ No newline at end of file diff --git a/crypto/paillier/src/paillier_keyop.c b/crypto/paillier/src/paillier_keyop.c new file mode 100644 index 00000000..d583eab1 --- /dev/null +++ b/crypto/paillier/src/paillier_keyop.c @@ -0,0 +1,255 @@ +/* + * 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_PAILLIER + +#include "crypt_types.h" +#include "crypt_paillier.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "paillier_local.h" +#include "crypt_errno.h" +#include "securec.h" +#include "bsl_sal.h" + + +static int32_t CheckSquare(const BN_BigNum *n2, const BN_BigNum *n, uint32_t bits) +{ + BN_BigNum *tmp = BN_Create(bits); + BN_Optimizer *optimizer = BN_OptimizerCreate(); + int32_t ret; + if (optimizer == NULL || tmp == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + ret = BN_Sqr(tmp, n, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto OUT; + } + + if (BN_Cmp(tmp, n2) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE); + ret = CRYPT_PAILLIER_ERR_INPUT_VALUE; + goto OUT; + } + +OUT: + BN_Destroy(tmp); + BN_OptimizerDestroy(optimizer); + return ret; +} + +static int32_t SetPrvPara(const CRYPT_PAILLIER_PrvKey *prvKey, const CRYPT_PaillierPrv *prv) +{ + int32_t ret = BN_Bin2Bn(prvKey->n, prv->n, prv->nLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + uint32_t bnBits = BN_Bits(prvKey->n); + if (bnBits > PAILLIER_MAX_MODULUS_BITS || bnBits <= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_KEY_BITS); + return CRYPT_PAILLIER_ERR_KEY_BITS; + } + + ret = BN_Bin2Bn(prvKey->lambda, prv->lambda, prv->lambdaLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bin2Bn(prvKey->mu, prv->mu, prv->muLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bin2Bn(prvKey->n2, prv->n2, prv->n2Len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CheckSquare(prvKey->n2, prvKey->n, prv->n2Len * 8); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_IsZero(prvKey->mu) || BN_IsOne(prvKey->mu)) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE); + return CRYPT_PAILLIER_ERR_INPUT_VALUE; + } + return ret; +} + +static int32_t SetPrvBasicCheck(const CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PaillierPrv *prv) +{ + if (ctx == NULL || prv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (prv->n == NULL || prv->lambda == NULL || prv->mu == NULL || prv->n2 == NULL || prv->lambdaLen == 0 || prv->muLen == 0 || prv->nLen == 0 || prv->n2Len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE); + return CRYPT_PAILLIER_ERR_INPUT_VALUE; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PAILLIER_SetPrvKey(CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PaillierPrv *prv) +{ + int32_t ret = SetPrvBasicCheck(ctx, prv); + if (ret != CRYPT_SUCCESS) { + return ret; + } + CRYPT_PAILLIER_Ctx *newCtx = CRYPT_PAILLIER_NewCtx(); + if (newCtx == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + newCtx->prvKey = Paillier_NewPrvKey(prv->lambdaLen * 8); // Bit length is obtained by multiplying byte length by 8. + if (newCtx->prvKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = SetPrvPara(newCtx->prvKey, prv); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + PAILLIER_FREE_PRV_KEY(ctx->prvKey); + ctx->prvKey = newCtx->prvKey; + + BSL_SAL_FREE(newCtx); + return ret; +ERR: + CRYPT_PAILLIER_FreeCtx(newCtx); + return ret; +} + +static int32_t SetPubBasicCheck(const CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PaillierPub *pub) +{ + if (ctx == NULL || pub == NULL || pub->n == NULL || pub->g == NULL || pub->n2 == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PAILLIER_SetPubKey(CRYPT_PAILLIER_Ctx *ctx, const CRYPT_PaillierPub *pub) +{ + int32_t ret = SetPubBasicCheck(ctx, pub); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_PAILLIER_PubKey *newPub = NULL; + + /* Bit length is obtained by multiplying byte length by 8. */ + newPub = Paillier_NewPubKey(pub->nLen * 8); + if (newPub == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + GOTO_ERR_IF(BN_Bin2Bn(newPub->n, pub->n, pub->nLen), ret); + uint32_t bnBits = BN_Bits(newPub->n); + if (bnBits > PAILLIER_MAX_MODULUS_BITS || bnBits <= 0) { + ret = CRYPT_PAILLIER_ERR_KEY_BITS; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(BN_Bin2Bn(newPub->g, pub->g, pub->gLen), ret); + GOTO_ERR_IF(BN_Bin2Bn(newPub->n2, pub->n2, pub->n2Len), ret); + + GOTO_ERR_IF(CheckSquare(newPub->n2, newPub->n, pub->nLen * 8), ret); + + PAILLIER_FREE_PUB_KEY(ctx->pubKey); + ctx->pubKey = newPub; + return ret; +ERR: + PAILLIER_FREE_PUB_KEY(newPub); + return ret; +} + +int32_t CRYPT_PAILLIER_GetPrvKey(const CRYPT_PAILLIER_Ctx *ctx, CRYPT_PaillierPrv *prv) +{ + if (ctx == NULL || ctx->prvKey == NULL || prv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = BN_Bn2Bin(ctx->prvKey->lambda, prv->lambda, &prv->lambdaLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(ctx->prvKey->mu, prv->mu, &prv->muLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + if (prv->n != NULL) + { + ret = BN_Bn2Bin(ctx->prvKey->n, prv->n, &prv->nLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + } + if (prv->n2 != NULL) + { + ret = BN_Bn2Bin(ctx->prvKey->n2, prv->n2, &prv->n2Len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + } + return ret; +} + +int32_t CRYPT_PAILLIER_GetPubKey(const CRYPT_PAILLIER_Ctx *ctx, CRYPT_PaillierPub *pub) +{ + if (ctx == NULL || ctx->pubKey == NULL || pub == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = BN_Bn2Bin(ctx->pubKey->g, pub->g, &pub->gLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(ctx->pubKey->n, pub->n, &pub->nLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (pub->n2 != NULL) { + ret = BN_Bn2Bin(ctx->pubKey->n2, pub->n2, &pub->n2Len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + } + return ret; +} + +int32_t CRYPT_PAILLIER_GetSecBits(const CRYPT_PAILLIER_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + int32_t bits = (int32_t)CRYPT_PAILLIER_GetBits(ctx); + return BN_SecBit(bits, -1); +} + +#endif /* HITLS_CRYPTO_PAILLIER */ \ No newline at end of file diff --git a/crypto/paillier/src/paillier_local.h b/crypto/paillier/src/paillier_local.h new file mode 100644 index 00000000..8e38351a --- /dev/null +++ b/crypto/paillier/src/paillier_local.h @@ -0,0 +1,86 @@ +/* + * 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 PAILLIER_LOCAL_H +#define PAILLIER_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_PAILLIER + +#include "crypt_paillier.h" +#include "crypt_bn.h" +#include "crypt_local_types.h" +#include "crypt_types.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +typedef struct { + BN_BigNum *n; // modulo Value - converted.Not in char + BN_BigNum *g; // modulo Value -converted.Not in char + BN_BigNum *n2; // square of n +} CRYPT_PAILLIER_PubKey; + +typedef struct { + BN_BigNum *n; // pub key n needed for decryption + BN_BigNum *lambda; // modulo Value - converted.Not in char + BN_BigNum *mu; // modulo Value -converted.Not in char + BN_BigNum *n2; // pub key n2 needed for decryption +} CRYPT_PAILLIER_PrvKey; + +struct PAILLIER_Para { + BN_BigNum *p; // prime factor p + BN_BigNum *q; // prime factor q + uint32_t bits; // length in bits of modulus +}; + +struct PAILLIER_Ctx { + CRYPT_PAILLIER_PubKey *pubKey; + CRYPT_PAILLIER_PrvKey *prvKey; + CRYPT_PAILLIER_Para *para; + BSL_SAL_RefCount references; +}; + +CRYPT_PAILLIER_PrvKey *Paillier_NewPrvKey(uint32_t bits); +CRYPT_PAILLIER_PubKey *Paillier_NewPubKey(uint32_t bits); +void PAILLIER_FreePrvKey(CRYPT_PAILLIER_PrvKey *prvKey); +void PAILLIER_FreePubKey(CRYPT_PAILLIER_PubKey *pubKey); +CRYPT_PAILLIER_Para *CRYPT_Paillier_DupPara(const CRYPT_PAILLIER_Para *para); + +#define PAILLIER_FREE_PRV_KEY(prvKey_) \ +do { \ + PAILLIER_FreePrvKey((prvKey_)); \ + (prvKey_) = NULL; \ + } while (0) + +#define PAILLIER_FREE_PUB_KEY(pubKey_) \ + do { \ + PAILLIER_FreePubKey((pubKey_)); \ + (pubKey_) = NULL; \ + } while (0) + +#define PAILLIER_FREE_PARA(para_) \ + do { \ + CRYPT_PAILLIER_FreePara((para_)); \ + (para_) = NULL; \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_PAILLIER +#endif // PAILLIER_LOCAL_H \ No newline at end of file diff --git a/crypto/pbkdf2/include/crypt_pbkdf2.h b/crypto/pbkdf2/include/crypt_pbkdf2.h new file mode 100644 index 00000000..41422435 --- /dev/null +++ b/crypto/pbkdf2/include/crypt_pbkdf2.h @@ -0,0 +1,58 @@ +/* + * 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_PBKDF2_H +#define CRYPT_PBKDF2_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_PBKDF2 + +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief PBKDF Password-based key derivation function + * + * @param macMeth [IN] Pointer to the HMAC algorithm method + * @param mdMeth [IN] MD algorithm method pointer + * @param key [IN] Password, a string entered by the user. + * @param keyLen [IN] Password length, which can be any length, including 0. + * @param salt [IN] Salt value, a string entered by the user. + * @param saltLen [IN] Salt value length, which can be any length, including 0. + * @param iterCnt [IN] Iteration times. The value can be any positive integer that is not 0. + * The value can be 1000 in special performance cases. The default value is 10000, + * 10000000 is recommended in cases where performance is insensitive or security requirements are high. + * @param out [OUT] Derived key. + * @param len [IN] Length of the derived key. The value range is [1, 0xFFFFFFFF]. + * + * @return Success: CRYPT_SUCCESS + * For other error codes, see crypt_errno.h + */ +int32_t CRYPT_PBKDF2_HMAC(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, + const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, + uint32_t iterCnt, uint8_t *out, uint32_t len); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_PBKDF2 + +#endif // CRYPT_PBKDF2_H diff --git a/crypto/pbkdf2/src/pbkdf2.c b/crypto/pbkdf2/src/pbkdf2.c new file mode 100644 index 00000000..9f781be6 --- /dev/null +++ b/crypto/pbkdf2/src/pbkdf2.c @@ -0,0 +1,198 @@ +/* + * 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_PBKDF2 + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_local_types.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_pbkdf2.h" + + +#define PBKDF2_MAX_BLOCKSIZE 64 +#define PBKDF2_MAX_KEYLEN 0xFFFFFFFF + +typedef struct { + const EAL_MacMethod *macMeth; + void *macCtx; + const uint8_t *salt; + uint32_t saltLen; + uint32_t iterCnt; +} CRYPT_PBKDF2_Ctx; + +int32_t CRYPT_PBKDF2_U1(const CRYPT_PBKDF2_Ctx *pCtx, uint32_t blockCount, uint8_t *u, uint32_t *blockSize) +{ + int32_t ret; + const EAL_MacMethod *macMeth = pCtx->macMeth; + void *macCtx = pCtx->macCtx; + (void)macMeth->reinit(macCtx); + if ((ret = macMeth->update(macCtx, pCtx->salt, pCtx->saltLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + /* processing the big endian */ + uint32_t blockCnt = CRYPT_HTONL(blockCount); + if ((ret = macMeth->update(macCtx, (uint8_t *)&blockCnt, sizeof(blockCnt))) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if ((ret = macMeth->final(macCtx, u, blockSize)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PBKDF2_Un(const CRYPT_PBKDF2_Ctx *pCtx, uint8_t *u, uint32_t *blockSize, uint8_t *t, uint32_t tLen) +{ + int32_t ret; + const EAL_MacMethod *macMeth = pCtx->macMeth; + void *macCtx = pCtx->macCtx; + + macMeth->reinit(macCtx); + if ((ret = macMeth->update(macCtx, u, *blockSize)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if ((ret = macMeth->final(macCtx, u, blockSize)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + DATA_XOR(t, u, t, tLen); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PBKDF2_CalcT(const CRYPT_PBKDF2_Ctx *pCtx, uint32_t blockCount, uint8_t *t, uint32_t *tlen) +{ + uint8_t u[PBKDF2_MAX_BLOCKSIZE] = {0}; + uint8_t tmpT[PBKDF2_MAX_BLOCKSIZE] = {0}; + uint32_t blockSize = PBKDF2_MAX_BLOCKSIZE; + int32_t ret; + uint32_t iterCnt = pCtx->iterCnt; + /* U1 = PRF(Password, Salt + INT_32_BE(i)) + tmpT = U1 */ + ret = CRYPT_PBKDF2_U1(pCtx, blockCount, u, &blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + (void)memcpy_s(tmpT, PBKDF2_MAX_BLOCKSIZE, u, blockSize); + for (uint32_t un = 1; un < iterCnt; un++) { + /* t = t ^ Un */ + ret = CRYPT_PBKDF2_Un(pCtx, u, &blockSize, tmpT, blockSize); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + uint32_t len = (*tlen > blockSize) ? blockSize : (*tlen); + (void)memcpy_s(t, *tlen, tmpT, len); + *tlen = len; + BSL_SAL_CleanseData(u, PBKDF2_MAX_BLOCKSIZE); + BSL_SAL_CleanseData(tmpT, PBKDF2_MAX_BLOCKSIZE); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PBKDF2_GenDk(const CRYPT_PBKDF2_Ctx *pCtx, const uint8_t *key, uint32_t keyLen, uint8_t *dk, + uint32_t dkLen) +{ + uint32_t curLen; + uint8_t *t = dk; + uint32_t tlen; + uint32_t i; + int32_t ret; + + ret = pCtx->macMeth->init(pCtx->macCtx, key, keyLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + /* DK = T1 + T2 + ⋯ + Tdklen/hlen */ + for (i = 1, curLen = dkLen; curLen > 0; i++) { + tlen = curLen; + ret = CRYPT_PBKDF2_CalcT(pCtx, i, t, &tlen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + curLen -= tlen; + t += tlen; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_PBKDF2_HMAC(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, + const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, + uint32_t iterCnt, uint8_t *out, uint32_t len) +{ + int32_t ret; + CRYPT_PBKDF2_Ctx pCtx; + + if (macMeth == NULL || mdMeth == NULL || out == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (key == NULL && keyLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + // add keyLen limit based on rfc2898 + if (mdMeth->mdSize == 0 || (keyLen / mdMeth->mdSize) >= PBKDF2_MAX_KEYLEN) { + BSL_ERR_PUSH_ERROR(CRYPT_PBKDF2_PARAM_ERROR); + return CRYPT_PBKDF2_PARAM_ERROR; + } + if (salt == NULL && saltLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if ((len == 0) || (iterCnt == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_PBKDF2_PARAM_ERROR); + return CRYPT_PBKDF2_PARAM_ERROR; + } + + void *macCtx = BSL_SAL_Malloc(macMeth->ctxSize); + if (macCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = macMeth->initCtx(macCtx, mdMeth); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(macCtx); + return ret; + } + + pCtx.macMeth = macMeth; + pCtx.macCtx = macCtx; + pCtx.salt = salt; + pCtx.saltLen = saltLen; + pCtx.iterCnt = iterCnt; + ret = CRYPT_PBKDF2_GenDk(&pCtx, key, keyLen, out, len); + + macMeth->deinit(macCtx); + macMeth->deinitCtx(macCtx); + BSL_SAL_FREE(macCtx); + return ret; +} +#endif // HITLS_CRYPTO_PBKDF2 diff --git a/crypto/rsa/include/crypt_rsa.h b/crypto/rsa/include/crypt_rsa.h new file mode 100644 index 00000000..24b2ac8c --- /dev/null +++ b/crypto/rsa/include/crypt_rsa.h @@ -0,0 +1,468 @@ +/* + * 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_RSA_H +#define CRYPT_RSA_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_RSA + +#include +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define RSA_MIN_MODULUS_BITS 1024 +#define RSA_MAX_MODULUS_BITS 16384 +#define RSA_SMALL_MODULUS_BYTES (3072 / 8) +#define RSA_MAX_PUBEXP_BYTES (64 / 8) +#define RSA_MIN_MODULUS_LEN (RSA_MIN_MODULUS_BITS / 8) +#define RSA_MAX_MODULUS_LEN (RSA_MAX_MODULUS_BITS / 8) + +/* RSA */ +typedef struct RSA_Ctx CRYPT_RSA_Ctx; +typedef struct RSA_Para CRYPT_RSA_Para; + + +/* RSA method */ + +/** + * @ingroup rsa + * @brief Allocate rsa context memory space. + * + * @retval (CRYPT_RSA_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer. + */ +CRYPT_RSA_Ctx *CRYPT_RSA_NewCtx(void); // create key structure + +/** + * @ingroup rsa + * @brief Copy the RSA context. After the duplication is complete, call the CRYPT_RSA_FreeCtx to release the memory. + * + * @param ctx [IN] RSA context + * + * @return CRYPT_RSA_Ctx Rsa context pointer + * If the operation fails, a null value is returned. + */ +CRYPT_RSA_Ctx *CRYPT_RSA_DupCtx(CRYPT_RSA_Ctx *keyCtx); + +/** + * @ingroup rsa + * @brief Create rsa key parameter structure + * + * @param para [IN] RSA External parameter + * + * @retval (CRYPT_RSA_Para *) Pointer to the allocated memory space of the structure + * @retval NULL Invalid null pointer. + */ +CRYPT_RSA_Para *CRYPT_RSA_NewPara(const CRYPT_RsaPara *para); + +/** + * @ingroup rsa + * @brief Release rsa key parameter structure + * + * @param para [IN] Storage pointer in the parameter structure to be released. The parameter is set NULL by the invoker. + */ +void CRYPT_RSA_FreePara(CRYPT_RSA_Para *para); + +/** + * @ingroup rsa + * @brief release rsa key context structure + * + * @param ctx [IN] Pointer to the context structure to be released. The ctx is set NULL by the invoker. + */ +void CRYPT_RSA_FreeCtx(CRYPT_RSA_Ctx *ctx); + +/** + * @ingroup rsa + * @brief Set the data of the key parameter structure to the key structure. + * + * @param ctx [OUT] RSA context structure for which related parameters need to be set + * @param para [IN] Key parameter structure + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input. + * @retval CRYPT_RSA_ERR_KEY_BITS The expected key length does not meet the requirements. + * @retval CRYPT_RSA_ERR_E_VALUE The expected value of e does not meet the requirements. + * @retval CRYPT_MEM_ALLOC_FAIL internal memory allocation error + * @retval CRYPT_SUCCESS set successfully. + */ +int32_t CRYPT_RSA_SetPara(CRYPT_RSA_Ctx *ctx, const CRYPT_RSA_Para *para); + +/** + * @ingroup rsa + * @brief Obtain the valid length of the key. + * + * @param ctx [IN] Structure from which the key length is expected to be obtained + * + * @retval 0: The input is incorrect or the corresponding key structure does not have a valid key length. + * @retval uint32_t: Valid key length + */ +uint32_t CRYPT_RSA_GetBits(const CRYPT_RSA_Ctx *ctx); + +/** + * @ingroup rsa + * @brief Obtain the maximum length of RSA signature data. + * + * @param ctx [IN] Maximum length of the RSA signature data that is expected to be obtained + * + * @retval 0: The input is incorrect or the corresponding key structure does not contain valid key information. + * @retval uint32_t: Maximum length of the signature data + */ +uint32_t CRYPT_RSA_GetSignLen(const CRYPT_RSA_Ctx *ctx); +/** + * @ingroup rsa + * @brief Generate the RSA key pair. + * + * @param ctx [IN/OUT] rsa context structure + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_ERR_KEY_BITS The value of e in the context structure does not meet the requirements. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_RSA_Gen(CRYPT_RSA_Ctx *ctx); + +/** + * @ingroup rsa + * @brief RSA public key encryption + * + * @param ctx [IN] RSA context structure + * @param input [IN] Information to be encrypted + * @param inputLen [IN] Length of the information to be encrypted + * @param out [OUT] Pointer to the encrypted information output. + * @param outLen [IN/OUT] Pointer to the length of the encrypted information. + * Before being transferred, the value must be set to the maximum length of the array. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS encryption succeeded. + */ +int32_t CRYPT_RSA_PubEnc(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup rsa + * @brief RSA private key decryption + * + * @param ctx [IN] RSA context structure + * @param input [IN] Information to be decrypted + * @param inputLen [IN] Length of the information to be decrypted + * @param out [OUT] Pointer to the decrypted information output. + * @param outLen [IN/OUT] Pointer to the length of the decrypted information. + * Before being transferred, the value must be set to the maximum length of the array. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_ERR_DEC_BITS Incorrect length of the encrypted private key. + * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Decrypted Successfully + */ +int32_t CRYPT_RSA_PrvDec(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup rsa + * @brief RSA Set the private key information. + * + * @param ctx [OUT] rsa context structure + * @param prv [IN] Private key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. + * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The private key is successfully set. + */ +int32_t CRYPT_RSA_SetPrvKey(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPrv *prv); + +/** + * @ingroup rsa + * @brief RSA Set the public key information. + * + * @param ctx [OUT] RSA context structure + * @param pub [IN] Public key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The public key is successfully set. + */ +int32_t CRYPT_RSA_SetPubKey(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPub *pub); + +/** + * @ingroup rsa + * @brief RSA Obtain the private key information. + * + * @param ctx [IN] RSA context structure + * @param prv [OUT] Private key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The private key is obtained successfully. + */ +int32_t CRYPT_RSA_GetPrvKey(const CRYPT_RSA_Ctx *ctx, CRYPT_RsaPrv *prv); + +/** + * @ingroup rsa + * @brief RSA Obtain the public key information. + * + * @param ctx [IN] RSA context structure + * @param pub [OUT] Public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval BN error An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS The public key is obtained successfully. + */ +int32_t CRYPT_RSA_GetPubKey(const CRYPT_RSA_Ctx *ctx, CRYPT_RsaPub *pub); + +/** + * @ingroup rsa + * @brief Set the PSS for the original data. + * + * @param hashMethod [IN] pss Required Hash Method + * @param mgfMethod [IN] pss Internal hash method required by the mgf. + * @param keyBits [IN] pss Key length + * @param salt [IN] Input salt value + * @param saltLen [IN] Length of the input salt. + * @param data [IN] Original data + * @param dataLen [IN] Length of the original data + * @param pad [OUT] pss Output buffer + * @param padLen [OUT] Maximum length of the array output by the PSS. + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_ERR_PSS_SALT_DATA The salt value does not meet the requirements. + * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. + * @retval CRYPT_RSA_ERR_PSS_SALT_LEN The salt length does not meet the requirements. + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length of the reserved buffer is insufficient. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SUCCESS Succeeded in setting the PSS. + */ +int32_t CRYPT_RSA_SetPss(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, uint32_t keyBits, + const uint8_t *salt, uint32_t saltLen, const uint8_t *data, uint32_t dataLen, uint8_t *pad, uint32_t padLen); + +/** + * @ingroup rsa + * @brief Compare the original data from the PSS. + * + * @param hashMethod [IN] pss Required the hash method + * @param mgfMethod [IN] pss Internal hash method required by the mgf. + * @param keyBits [IN] pss Key length + * @param saltLen [IN] Salt value length + * @param data [IN] Original data + * @param dataLen [IN] Length of the original data + * @param pad [IN] Data after PSS is set. + * @param padLen [IN] Data length after PSS is set. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_ERR_PSS_SALT_DATA The salt value does not meet the requirements. + * @retval CRYPT_RSA_ERR_PSS_SALT_LEN The salt length does not meet the requirements. + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length required for padding does not match the input parameter. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SUCCESS pss comparison succeeded. + */ +int32_t CRYPT_RSA_VerifyPss(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, uint32_t keyBits, + uint32_t saltLen, const uint8_t *data, uint32_t dataLen, const uint8_t *pad, uint32_t padLen); + +/** + * @ingroup rsa + * @brief Set pkcsv1.5 padding. + * + * @param hashId [IN] the hash method required by pkcsv1.5 setting. + * @param data [IN] Original data + * @param dataLen [IN] Length of the original data + * @param pad [OUT] Pointer to the array for receiving the padding. + * @param padLen [IN] Array length for receiving padding. + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_NO_KEY_INFO The key information is insufficient. + * @retval CRYPT_SECUREC_FAIL The security function fails. + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length required by the padding does not match the input parameter. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The hash algorithm ID is not supported. + * @retval CRYPT_SUCCESS The pkcsv1.5 padding is successfully set. + */ +int32_t CRYPT_RSA_SetPkcsV15Type1(CRYPT_MD_AlgId hashId, const uint8_t *data, uint32_t dataLen, + uint8_t *pad, uint32_t padLen); + +/** + * @ingroup rsa + * @brief Verify pkcsv1.5 padding. + * + * @param hashId [IN] the hash method corresponding to pkcsv1.5 verification. + * @param pad [IN] Data after padding + * @param padLen [IN] Data length after padding + * @param data [IN] Original data + * @param dataLen [IN] Length of the original data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_ERR_INPUT_VALUE Incorrect padding value. + * @retval CRYPT_SECUREC_FAIL Security Function Failure + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length required for padding does not match the input parameter. + * @retval CRYPT_RSA_ERR_MD_ALGID The hash algorithm ID is not supported. + * @retval CRYPT_SUCCESS Verify pkcsv1.5 is padded successfully. + */ +int32_t CRYPT_RSA_VerifyPkcsV15Type1(CRYPT_MD_AlgId hashId, const uint8_t *pad, uint32_t padLen, + const uint8_t *data, uint32_t dataLen); + +int32_t CRYPT_RSA_Ctrl(CRYPT_RSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +int32_t CRYPT_RSA_Verify(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen); + +int32_t CRYPT_RSA_Sign(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen); + +/** + * @ingroup rsa + * @brief RSA public key encryption + * + * @param ctx [IN] RSA context structure + * @param data [IN] Information to be encrypted + * @param dataLen [IN] Length of the information to be encrypted + * @param out [OUT] Pointer to the encrypted information output. + * @param outLen [OUT] Pointer to the length of the encrypted information + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A safe function error occurs. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_EAL_ALG_NOT_SUPPORT does not register the encryption method. + * @retval CRYPT_SUCCESS encryption succeeded. +*/ +int32_t CRYPT_RSA_Encrypt(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup rsa + * @brief RSA private key decryption + * + * @param ctx [IN] RSA context structure + * @param data [IN] Information to be decrypted + * @param dataLen [IN] Length of the information to be decrypted + * @param out [OUT] Pointer to the output information after decryption. + * @param outLen [OUT] Pointer to the length of the decrypted information + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval CRYPT_EAL_ALG_NOT_SUPPORT does not register the decryption method. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval CRYPT_SUCCESS Decryption succeeded. + */ +int32_t CRYPT_RSA_Decrypt(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup rsa + * @brief RSA compare the public key + * + * @param a [IN] RSA context structure + * @param b [IN] RSA context structure + * + * @retval CRYPT_SUCCESS is the same + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_RSA_NO_KEY_INFO No public key + * @retval CRYPT_RSA_PUBKEY_NOT_EQUAL Public Keys are not equal + */ +int32_t CRYPT_RSA_Cmp(const CRYPT_RSA_Ctx *a, const CRYPT_RSA_Ctx *b); + +/** + * @ingroup rsa + * @brief oaep padding + * + * @param hashMethod [IN] Hash method. Only sha1, sha244, sha256, sha384, and sha512 are supported. + * @param mgfMethod [IN] Hash method required by mgf + * @param in [IN] Original data + * @param inLen [IN] Original data length + * @param param [IN] oaep parameter, which can be null + * @param paramLen [IN] oaep Parameter length + * @param pad [IN] Data after padding + * @param padLen [IN] Data length after padding + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient + * */ +int32_t CRYPT_RSA_SetPkcs1Oaep(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, const uint8_t *in, + uint32_t inLen, const uint8_t *param, uint32_t paramLen, uint8_t *pad, uint32_t padLen); + +/** + * @ingroup rsa + * @brief Verify the oaep padding. + * + * @param hashMethod [IN] Hash method, which supports sha1, sha244, sha256, sha384, and sha512. + * @param mgfMethod [IN] Hash method required by mgf + * @param in [IN] Data after padding + * @param inLen [IN] Data length after padding + * @param param [IN] oaep parameter, which can be null + * @param paramLen [IN] oaep Parameter length + * @param msg [IN] Data after the de-padding + * @param msgLen [IN/OUT] The input parameter is the length of the msg buffer, + * and the output parameter is the length of the msg after the de-padding. + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. + * @retval CRYPT_SECUREC_FAIL A security function error occurs. + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * */ +int32_t CRYPT_RSA_VerifyPkcs1Oaep(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, const uint8_t *in, + uint32_t inLen, const uint8_t *param, uint32_t paramLen, uint8_t *msg, uint32_t *msgLen); + +int32_t CRYPT_RSA_SetPkcsV15Type2(const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t outLen); + +int32_t CRYPT_RSA_VerifyPkcsV15Type2(const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup RSA + * @brief RSA get security bits + * + * @param ctx [IN] RSA Context structure + * + * @retval security bits + */ +int32_t CRYPT_RSA_GetSecBits(const CRYPT_RSA_Ctx *ctx); + + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_RSA + +#endif // CRYPT_RSA_H diff --git a/crypto/rsa/src/rsa_blinding.c b/crypto/rsa/src/rsa_blinding.c new file mode 100644 index 00000000..e15a80cd --- /dev/null +++ b/crypto/rsa/src/rsa_blinding.c @@ -0,0 +1,153 @@ +/* + * 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_RSA + +#include "crypt_utils.h" +#include "crypt_rsa.h" +#include "rsa_local.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "securec.h" +#include "bsl_err_internal.h" + +RSA_Blind *RSA_BlindNewCtx(void) +{ + RSA_Blind *ret = BSL_SAL_Malloc(sizeof(RSA_Blind)); + if (ret == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)memset_s(ret, sizeof(RSA_Blind), 0, sizeof(RSA_Blind)); + return ret; +} + + +void RSA_BlindFreeCtx(RSA_Blind *b) +{ + if (b == NULL) { + return; + } + BN_Destroy(b->a); + BN_Destroy(b->ai); + BSL_SAL_FREE(b); +} + +static int32_t BlindUpdate(RSA_Blind *b, BN_BigNum *n, BN_Optimizer *opt) +{ + int32_t ret = BN_ModMul(b->a, b->a, b->a, n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_ModMul(b->ai, b->ai, b->ai, n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +int32_t RSA_BlindCovert(RSA_Blind *b, BN_BigNum *data, BN_BigNum *n, BN_Optimizer *opt) +{ + int32_t ret; + + ret = BlindUpdate(b, n, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + // 8. z = m * x mod n + ret = BN_ModMul(data, data, b->a, n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +int32_t RSA_BlindInvert(RSA_Blind *b, BN_BigNum *data, BN_BigNum *n, BN_Optimizer *opt) +{ + int32_t ret; + ret = BN_ModMul(data, data, b->ai, n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +static int32_t RSA_CreateBlind(RSA_Blind *b, uint32_t bits) +{ + b->a = BN_Create(bits); + if (b->a == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + b->ai = BN_Create(bits); + if (b->ai == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t RSA_BlindCreateParam(RSA_Blind *b, BN_BigNum *e, BN_BigNum *n, BN_Optimizer *opt) +{ + int32_t ret; + if (b == NULL || e == NULL || n == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + BN_Destroy(b->a); + BN_Destroy(b->ai); + b->a = NULL; + b->ai = NULL; + + ret = RSA_CreateBlind(b, BN_Bits(n)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = BN_RandRange(b->a, n); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = BN_ModInv(b->ai, b->a, n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = BN_ModExp(b->a, b->a, e, n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + return ret; +END: + BN_Destroy(b->a); + BN_Destroy(b->ai); + b->a = NULL; + b->ai = NULL; + return ret; +} +#endif // HITLS_CRYPTO_RSA diff --git a/crypto/rsa/src/rsa_encdec.c b/crypto/rsa/src/rsa_encdec.c new file mode 100644 index 00000000..fec7c13e --- /dev/null +++ b/crypto/rsa/src/rsa_encdec.c @@ -0,0 +1,1189 @@ +/* + * 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_RSA + +#include "crypt_utils.h" +#include "crypt_rsa.h" +#include "rsa_local.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "securec.h" +#include "bsl_err_internal.h" + + +// rsa-decrypt Calculation used by Chinese Remainder Theorem(CRT). intermediate variables: +typedef struct { + BN_Optimizer *optimizer; + BN_BigNum *cP; + BN_BigNum *cQ; + BN_BigNum *mP; + BN_BigNum *mQ; + BN_Mont *montP; + BN_Mont *montQ; +} RsaDecProcedurePara; + +static int32_t InputRangeCheck(const BN_BigNum *input, const BN_BigNum *n) +{ + // The value range defined in RFC is [0, n - 1]. Because the operation result of 0, 1, n - 1 is relatively fixed, + // it is considered invalid here. The actual valid value range is [2, n - 2]. + int32_t ret; + BN_BigNum *nMinusOne = NULL; + if (BN_IsLimb(input, 0) == true || BN_IsLimb(input, 1) == true) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + /* Allocate 8 extra bits to prevent calculation errors due to the feature of BigNum calculation. */ + nMinusOne = BN_Create(BN_Bits(n) + 8); + if (nMinusOne == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + ret = BN_SubLimb(nMinusOne, n, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BN_Destroy(nMinusOne); + return ret; + } + if (BN_Cmp(input, nMinusOne) >= 0) { + ret = CRYPT_RSA_ERR_INPUT_VALUE; + BSL_ERR_PUSH_ERROR(ret); + } + BN_Destroy(nMinusOne); + return ret; +} + +static int32_t AddZero(uint32_t bits, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + uint32_t i; + uint32_t zeros = 0; + /* Divide bits by 8 to obtain the byte length. If it is smaller than the key length, pad it with 0. */ + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + /* Divide bits by 8 to obtain the byte length. If it is smaller than the key length, pad it with 0. */ + zeros = BN_BITS_TO_BYTES(bits) - (*outLen); + ret = memmove_s(out + zeros, BN_BITS_TO_BYTES(bits) - zeros, out, (*outLen)); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + for (i = 0; i < zeros; i++) { + out[i] = 0x0; + } + } + *outLen = BN_BITS_TO_BYTES(bits); + return CRYPT_SUCCESS; +} + +static int32_t ResultToOut(uint32_t bits, const BN_BigNum *result, uint8_t *out, uint32_t *outLen) +{ + int32_t ret = BN_Bn2Bin(result, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return AddZero(bits, out, outLen); +} + +static int32_t AllocResultAndInputBN(uint32_t bits, BN_BigNum **result, BN_BigNum **inputBN, + const uint8_t *input, uint32_t inputLen) +{ + if (inputLen > BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + *result = BN_Create(bits + 1); + *inputBN = BN_Create(bits); + if (*result == NULL || *inputBN == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return BN_Bin2Bn(*inputBN, input, inputLen); +} + +static int32_t CalcMontExp(const BN_BigNum *n, const BN_BigNum *eOrd, + BN_BigNum *result, const BN_BigNum *input, bool consttime) +{ + int32_t ret; + BN_Optimizer *optimizer = NULL; + BN_Mont *mont = NULL; + if (BN_IsZero(n) || BN_IsZero(eOrd)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + optimizer = BN_OptimizerCreate(); + mont = BN_MontCreate(n); + if (optimizer == NULL || mont == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + if (consttime) { + ret = BN_MontExpConsttime(result, input, eOrd, mont, optimizer); + } else { + ret = BN_MontExp(result, input, eOrd, mont, optimizer); + } +ERR: + BN_OptimizerDestroy(optimizer); + BN_MontDestroy(mont); + return ret; +} + +int32_t CRYPT_RSA_PubEnc(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + BN_BigNum *inputBN = NULL; + BN_BigNum *result = NULL; + if (ctx == NULL || input == NULL || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + CRYPT_RSA_PubKey *pubKey = ctx->pubKey; + if (pubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + uint32_t bits = CRYPT_RSA_GetBits(ctx); + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + BN_Optimizer *optimizer = BN_OptimizerCreate(); + if (optimizer == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + GOTO_ERR_IF_EX(AllocResultAndInputBN(bits, &result, &inputBN, input, inputLen), ret); + GOTO_ERR_IF_EX(InputRangeCheck(inputBN, pubKey->n), ret); + + // pubKey->mont: Ensure that this value is not empty when the public key is set or generated. + GOTO_ERR_IF(BN_MontExp(result, inputBN, pubKey->e, pubKey->mont, optimizer), ret); + ret = ResultToOut(bits, result, out, outLen); +ERR: + BN_Destroy(result); + BN_Destroy(inputBN); + BN_OptimizerDestroy(optimizer); + return ret; +} + +/* Release intermediate variables. */ +static void RsaDecProcedureFree(RsaDecProcedurePara *para) +{ + if (para == NULL) { + return; + } + BN_Destroy(para->cP); + BN_Destroy(para->cQ); + BN_Destroy(para->mP); + BN_Destroy(para->mQ); + BN_OptimizerDestroy(para->optimizer); + BN_MontDestroy(para->montP); + BN_MontDestroy(para->montQ); + return; +} + +/* Apply for intermediate variables. */ +static int32_t RsaDecProcedureAlloc(RsaDecProcedurePara *para, uint32_t bits, const CRYPT_RSA_PrvKey *priKey) +{ + para->optimizer = BN_OptimizerCreate(); + para->cP = BN_Create(bits); + para->cQ = BN_Create(bits); + para->mP = BN_Create(bits); + para->mQ = BN_Create(bits); + para->montP = BN_MontCreate(priKey->p); + para->montQ = BN_MontCreate(priKey->q); + bool creatFailed = (para->optimizer == NULL || para->cP == NULL || para->cQ == NULL || + para->mP == NULL || para->mQ == NULL || para->montP == NULL || para->montQ == NULL); + if (creatFailed) { + RsaDecProcedureFree(para); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + return CRYPT_SUCCESS; +} + +/* rsa decryption calculation by CRT. Message is the BigNum converted from the original input ciphertext. */ +static int32_t NormalDecProcedure( + const CRYPT_RSA_Ctx *ctx, const BN_BigNum *message, BN_BigNum *result) +{ + CRYPT_RSA_PrvKey *priKey = ctx->prvKey; + uint32_t bits = CRYPT_RSA_GetBits(ctx); + RsaDecProcedurePara procedure = {0}; // Temporary variable + /* Apply for temporary variable */ + int32_t ret = RsaDecProcedureAlloc(&procedure, bits, priKey); + if (ret != CRYPT_SUCCESS) { + return ret; + } + /* cP = M mod P where inp = M = Message */ + ret = BN_Mod(procedure.cP, message, priKey->p, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* cQ = M mod Q where inp = M = Message */ + ret = BN_Mod(procedure.cQ, message, priKey->q, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* mP = cP^dP mod p */ + ret = BN_MontExpConsttime(procedure.mP, procedure.cP, priKey->dP, procedure.montP, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* mQ = cQ^dQ mod q */ + ret = BN_MontExpConsttime(procedure.mQ, procedure.cQ, priKey->dQ, procedure.montQ, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* result = (mP - mQ) mod p */ + ret = BN_ModSub(result, procedure.mP, procedure.mQ, priKey->p, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* result = result * qInv mod p */ + ret = BN_ModMul(result, result, priKey->qInv, priKey->p, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* result = result * q */ + ret = BN_Mul(result, result, priKey->q, procedure.optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + /* result = result + mQ */ + ret = BN_Add(result, result, procedure.mQ); +ERR: + RsaDecProcedureFree(&procedure); + return ret; +} + +static int32_t RSA_GetSub( + const BN_BigNum *p, const BN_BigNum *q, BN_BigNum *r1, BN_BigNum *r2) +{ + int32_t ret; + + ret = BN_SubLimb(r1, p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_SubLimb(r2, q, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +static int32_t RSA_GetL( + BN_BigNum *l, BN_BigNum *u, BN_BigNum *r1, BN_BigNum *r2, BN_Optimizer *opt) +{ + int32_t ret; + ret = BN_Mul(l, r1, r2, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = BN_Gcd(u, r1, r2, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = BN_Div(l, NULL, l, u, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +static BN_BigNum *RSA_GetPublicExp(const BN_BigNum *d, const BN_BigNum *p, + const BN_BigNum *q, uint32_t bits, BN_Optimizer *opt) +{ + int32_t ret; + /* Apply for the temporary space of the BN object */ + BN_BigNum *l = BN_Create(BN_Bits(p) + BN_Bits(q)); + BN_BigNum *r1 = BN_Create(BN_Bits(p)); + BN_BigNum *r2 = BN_Create(BN_Bits(q)); + BN_BigNum *u = BN_Create(bits + 1); + BN_BigNum *e = BN_Create(bits); + + if (l == NULL || r1 == NULL || r2 == NULL || u == NULL || e == NULL) { + ret = CRYPT_NULL_INPUT; + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + + ret = RSA_GetSub(p, q, r1, r2); + // The push error in GetSub can be used to locate the fault. Therefore, it is not added here. + if (ret != CRYPT_SUCCESS) { + goto END; + } + + ret = RSA_GetL(l, u, r1, r2, opt); + // The push error in GetL can be used to locate the fault. Therefore, it is not added here. + if (ret != CRYPT_SUCCESS) { + goto END; + } + + ret = BN_ModInv(e, d, l, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } +END: + BN_Destroy(r1); + BN_Destroy(r2); + BN_Destroy(l); + BN_Destroy(u); + if (ret != CRYPT_SUCCESS) { + BN_Destroy(e); + e = NULL; + } + return e; +} + +static int32_t RSA_InitBlind(CRYPT_RSA_Ctx *ctx, BN_Optimizer *opt) +{ + uint32_t bits = BN_Bits(ctx->prvKey->n); + bool needDestoryE = false; + BN_BigNum *e = ctx->prvKey->e; + if (e == NULL || BN_IsZero(e)) { + e = RSA_GetPublicExp(ctx->prvKey->d, ctx->prvKey->p, ctx->prvKey->q, bits, opt); + if (e == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_E_VALUE); + return CRYPT_RSA_ERR_E_VALUE; + } + needDestoryE = true; + } + + ctx->blind = RSA_BlindNewCtx(); + + int32_t ret = RSA_BlindCreateParam(ctx->blind, e, ctx->prvKey->n, opt); + if (needDestoryE) { + BN_Destroy(e); + } + return ret; +} + +static int32_t RSA_BlindProcess(CRYPT_RSA_Ctx *ctx, BN_BigNum *message, BN_Optimizer *opt) +{ + int32_t ret; + if (ctx->blind == NULL) { + ret = RSA_InitBlind(ctx, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + + ret = RSA_BlindCovert(ctx->blind, message, ctx->prvKey->n, opt); + if (ret != CRYPT_SUCCESS) { + return ret; + } + return ret; +} + +static int32_t RSA_AllocAndCheck(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + BN_BigNum **result, BN_BigNum **message) +{ + int32_t ret; + if (ctx->prvKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + + uint32_t bits = CRYPT_RSA_GetBits(ctx); + + ret = AllocResultAndInputBN(bits, result, message, input, inputLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = InputRangeCheck(*message, ctx->prvKey->n); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + return ret; +ERR: + BN_Destroy(*result); + BN_Destroy(*message); + return ret; +} + +static int32_t RSA_PrvProcess( + const CRYPT_RSA_Ctx *ctx, BN_BigNum *message, BN_BigNum *result, BN_Optimizer *opt) +{ + int32_t ret; + // blinding + if ((ctx->flags & CRYPT_RSA_BLINDING) != 0) { + ret = RSA_BlindProcess((CRYPT_RSA_Ctx *)(uintptr_t)ctx, message, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + /* If ctx->prvKey->p is set to 0, the standard mode is used for RSA decryption. + Otherwise, the CRT mode is used for RSA decryption. */ + if (BN_IsZero(ctx->prvKey->p)) { + ret = CalcMontExp(ctx->prvKey->n, ctx->prvKey->d, result, message, true); + } else { + ret = NormalDecProcedure(ctx, message, result); + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // unblinding + if ((ctx->flags & CRYPT_RSA_BLINDING) != 0) { + ret = RSA_BlindInvert(ctx->blind, result, ctx->prvKey->n, opt); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + return ret; +} + +int32_t CRYPT_RSA_PrvDec(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + uint32_t bits; + BN_BigNum *result = NULL; + BN_BigNum *message = NULL; + BN_Optimizer *opt = NULL; + + if (ctx == NULL || input == NULL || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->prvKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + + bits = CRYPT_RSA_GetBits(ctx); + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + opt = BN_OptimizerCreate(); + if (opt == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + ret = RSA_AllocAndCheck(ctx, input, inputLen, &result, &message); + if (ret != CRYPT_SUCCESS) { + BN_OptimizerDestroy(opt); + return ret; + } + + ret = RSA_PrvProcess(ctx, message, result, opt); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + + ret = ResultToOut(bits, result, out, outLen); +ERR: + BN_OptimizerDestroy(opt); + BN_Destroy(result); + BN_Destroy(message); + return ret; +} + +static uint32_t GetHashLen(const CRYPT_RSA_Ctx *ctx) +{ + if (ctx->pad.type == EMSA_PKCSV15) { + return CRYPT_MD_GetSizeById(ctx->pad.para.pkcsv15.mdId); + } + + return (uint32_t)(ctx->pad.para.pss.mdMeth->mdSize); +} + +static int32_t SignInputCheck(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + const uint8_t *out, const uint32_t *outLen) +{ + if (ctx == NULL || input == NULL || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->prvKey == NULL) { + // Check whether the private key information exists. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + // Check whether the length of the out is sufficient to place the signature information. + uint32_t bits = CRYPT_RSA_GetBits(ctx); + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + if (ctx->pad.type != EMSA_PKCSV15 && ctx->pad.type != EMSA_PSS) { + // No padding type is set. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_PAD_NO_SET_ERROR); + return CRYPT_RSA_PAD_NO_SET_ERROR; + } + if (GetHashLen(ctx) != inputLen) { + // Inconsistent length + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ALGID); + return CRYPT_RSA_ERR_ALGID; + } + return CRYPT_SUCCESS; +} + +static int32_t PssPad(CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, uint8_t *out, uint32_t outLen) +{ + CRYPT_Data salt = { 0 }; + bool kat = false; + if (ctx->pad.salt.data != NULL) { + // If the salt contains data, that is the kat test. + kat = true; + } + if (kat) { + salt.data = ctx->pad.salt.data; + salt.len = ctx->pad.salt.len; + ctx->pad.salt.data = NULL; + ctx->pad.salt.len = 0; + } else if (ctx->pad.para.pss.saltLen != 0) { + // Generate a salt information to the salt. + int32_t ret = GenPssSalt(&salt, ctx->pad.para.pss.mdMeth, ctx->pad.para.pss.saltLen, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_GEN_SALT); + return CRYPT_RSA_ERR_GEN_SALT; + } + } + int32_t ret = CRYPT_RSA_SetPss(ctx->pad.para.pss.mdMeth, ctx->pad.para.pss.mgfMeth, CRYPT_RSA_GetBits(ctx), + salt.data, salt.len, input, inputLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + if (!kat && (ctx->pad.para.pss.saltLen != 0)) { + // The generated salt needs to be released. + BSL_SAL_CleanseData(salt.data, salt.len); + BSL_SAL_FREE(salt.data); + } + return ret; +} + +int32_t CRYPT_RSA_Sign(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen) +{ + int32_t ret = SignInputCheck(ctx, data, dataLen, sign, signLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t bits = CRYPT_RSA_GetBits(ctx); + uint32_t padLen = BN_BITS_TO_BYTES(bits); + uint8_t *pad = BSL_SAL_Malloc(padLen); + if (pad == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + switch (ctx->pad.type) { + case EMSA_PKCSV15: + ret = CRYPT_RSA_SetPkcsV15Type1(ctx->pad.para.pkcsv15.mdId, data, + dataLen, pad, padLen); + break; + case EMSA_PSS: + ret = PssPad(ctx, data, dataLen, pad, padLen); + break; + default: // This branch cannot be entered because it's been verified before. + ret = CRYPT_RSA_PAD_NO_SET_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = CRYPT_RSA_PrvDec(ctx, pad, padLen, sign, signLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + (void)memset_s(pad, padLen, 0, padLen); + BSL_SAL_FREE(pad); + return ret; +} + +static int32_t VerifyInputCheck(const CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign) +{ + if (ctx == NULL || data == NULL || sign == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->pubKey == NULL) { + // Check whether the private key information exists. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + if (ctx->pad.type != EMSA_PKCSV15 && ctx->pad.type != EMSA_PSS) { + // No padding type is set. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_PAD_NO_SET_ERROR); + return CRYPT_RSA_PAD_NO_SET_ERROR; + } + if (GetHashLen(ctx) != dataLen) { + // Inconsistent length + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ALGID); + return CRYPT_RSA_ERR_ALGID; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_Verify(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen) +{ + uint8_t *pad = NULL; + uint32_t saltLen = 0; + int32_t ret = VerifyInputCheck(ctx, data, dataLen, sign); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t bits = CRYPT_RSA_GetBits(ctx); + uint32_t padLen = BN_BITS_TO_BYTES(bits); + pad = BSL_SAL_Malloc(padLen); + if (pad == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = CRYPT_RSA_PubEnc(ctx, sign, signLen, pad, &padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + saltLen = (uint32_t)ctx->pad.para.pss.saltLen; + switch (ctx->pad.type) { + case EMSA_PKCSV15: + ret = CRYPT_RSA_VerifyPkcsV15Type1(ctx->pad.para.pkcsv15.mdId, pad, padLen, + data, dataLen); + break; + case EMSA_PSS: + if (ctx->pad.para.pss.saltLen == SALTLEN_PSS_HASHLEN_TYPE) { // saltLen is -1 + saltLen = (uint32_t)ctx->pad.para.pss.mdMeth->mdSize; + } else if (ctx->pad.para.pss.saltLen == SALTLEN_PSS_MAXLEN_TYPE) { // saltLen is -2 + saltLen = (uint32_t)(padLen - ctx->pad.para.pss.mdMeth->mdSize - 2); // salt, obtains DRBG + } + ret = CRYPT_RSA_VerifyPss(ctx->pad.para.pss.mdMeth, ctx->pad.para.pss.mgfMeth, + bits, saltLen, data, dataLen, pad, padLen); + break; + default: // This branch cannot be entered because it's been verified before. + ret = CRYPT_RSA_PAD_NO_SET_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR: + (void)memset_s(pad, padLen, 0, padLen); + BSL_SAL_FREE(pad); + return ret; +} + +static int32_t EncryptInputCheck(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, + const uint8_t *out, const uint32_t *outLen) +{ + if (ctx == NULL || (input == NULL && inputLen != 0) || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->pubKey == NULL) { + // Check whether the public key information exists. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + // Check whether the length of the out is sufficient to place the encryption information. + uint32_t bits = CRYPT_RSA_GetBits(ctx); + if ((*outLen) < BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + if (inputLen > BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ENC_BITS); + return CRYPT_RSA_ERR_ENC_BITS; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_Encrypt(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen) +{ + uint32_t bits, padLen; + uint8_t *pad = NULL; + int32_t ret = EncryptInputCheck(ctx, data, dataLen, out, outLen); + // The static function has pushed an error. The push error is not repeated here. + if (ret != CRYPT_SUCCESS) { + return ret; + } + bits = CRYPT_RSA_GetBits(ctx); + padLen = BN_BITS_TO_BYTES(bits); + pad = BSL_SAL_Malloc(padLen); + if (pad == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + switch (ctx->pad.type) { + case RSAES_PKCSV15: + ret = CRYPT_RSA_SetPkcsV15Type2(data, dataLen, pad, padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + break; + case RSAES_OAEP: + ret = CRYPT_RSA_SetPkcs1Oaep(ctx->pad.para.oaep.mdMeth, + ctx->pad.para.oaep.mgfMeth, data, dataLen, ctx->label.data, ctx->label.len, pad, padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + break; + case RSA_NO_PAD: + if (dataLen != padLen) { + ret = CRYPT_RSA_ERR_ENC_INPUT_NOT_ENOUGH; + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ENC_INPUT_NOT_ENOUGH); + goto ERR; + } + (void)memcpy_s(pad, padLen, data, dataLen); + break; + default: + ret = CRYPT_RSA_PAD_NO_SET_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = CRYPT_RSA_PubEnc(ctx, pad, padLen, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + (void)memset_s(pad, padLen, 0, padLen); + BSL_SAL_FREE(pad); + return ret; +} + +static int32_t DecryptInputCheck(const CRYPT_RSA_Ctx *ctx, const uint8_t *data, const uint32_t dataLen, + const uint8_t *out, const uint32_t *outLen) +{ + if (ctx == NULL || data == NULL || out == NULL || outLen == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->prvKey == NULL) { + // Check whether the private key information exists. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + + uint32_t bits = CRYPT_RSA_GetBits(ctx); + if (dataLen != BN_BITS_TO_BYTES(bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_DEC_BITS); + return CRYPT_RSA_ERR_DEC_BITS; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_Decrypt(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *out, uint32_t *outLen) +{ + uint8_t *pad = NULL; + int32_t ret = DecryptInputCheck(ctx, data, dataLen, out, outLen); + // The static function has pushed an error. The push error is not repeated here. + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t bits = CRYPT_RSA_GetBits(ctx); + uint32_t padLen = BN_BITS_TO_BYTES(bits); + pad = BSL_SAL_Malloc(padLen); + if (pad == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = CRYPT_RSA_PrvDec(ctx, data, dataLen, pad, &padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + switch (ctx->pad.type) { + case RSAES_OAEP: + ret = CRYPT_RSA_VerifyPkcs1Oaep(ctx->pad.para.oaep.mdMeth, + ctx->pad.para.oaep.mgfMeth, pad, padLen, ctx->label.data, ctx->label.len, out, outLen); + break; + case RSAES_PKCSV15: + ret = CRYPT_RSA_VerifyPkcsV15Type2(pad, padLen, out, outLen); + break; + case RSA_NO_PAD: + if (memcpy_s(out, *outLen, pad, padLen) != EOK) { + ret = CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + goto ERR; + } + *outLen = padLen; + break; + default: + ret = CRYPT_RSA_PAD_NO_SET_ERROR; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } +ERR: + BSL_SAL_CleanseData(pad, padLen); + BSL_SAL_FREE(pad); + return ret; +} + +static int32_t SetEmsaPkcsV15(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(CRYPT_RSA_PkcsV15Para)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR); + return CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR; + } + static const uint32_t SIGN_MD_ID_LIST[] = { CRYPT_MD_SHA224, CRYPT_MD_SHA256, + CRYPT_MD_SHA384, CRYPT_MD_SHA512, CRYPT_MD_SM3, CRYPT_MD_SHA1, CRYPT_MD_MD5 + }; + + CRYPT_RSA_PkcsV15Para *pad = val; + if (ParamIdIsValid(pad->mdId, SIGN_MD_ID_LIST, sizeof(SIGN_MD_ID_LIST) / sizeof(SIGN_MD_ID_LIST[0])) == false) { + // This hash algorithm is not supported. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_MD_ALGID); + return CRYPT_RSA_ERR_MD_ALGID; + } + (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad)); + (void)memcpy_s(&(ctx->pad.para.pkcsv15), sizeof(CRYPT_RSA_PkcsV15Para), val, sizeof(CRYPT_RSA_PkcsV15Para)); + ctx->pad.type = EMSA_PKCSV15; + ctx->pad.para.pkcsv15.mdId = pad->mdId; + return CRYPT_SUCCESS; +} + +static int32_t SetEmsaPss(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(RSA_PadingPara)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_EMS_PSS_LEN_ERROR); + return CRYPT_RSA_SET_EMS_PSS_LEN_ERROR; + } + + RSA_PadingPara *pad = val; + if (pad->mdMeth == NULL || pad->mgfMeth == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t bits = CRYPT_RSA_GetBits(ctx); + if (bits == 0) { + // The valid key information does not exist. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + if (pad->saltLen < SALTLEN_PSS_AUTOLEN_TYPE) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_SALT_LEN); + return CRYPT_RSA_ERR_SALT_LEN; + } + uint32_t saltLen = (uint32_t)pad->saltLen; + if (pad->saltLen == SALTLEN_PSS_HASHLEN_TYPE) { + saltLen = pad->mdMeth->mdSize; + } + uint32_t bytes = BN_BITS_TO_BYTES(bits); + // The minimum specification supported by RSA is 1K, + // and the maximum hash length supported by the hash algorithm is 64 bytes. + // Therefore, specifying the salt length as the maximum available length is satisfied. + if (pad->saltLen != SALTLEN_PSS_MAXLEN_TYPE && pad->saltLen != SALTLEN_PSS_AUTOLEN_TYPE && + saltLen > bytes - pad->mdMeth->mdSize - 2) { // maximum length of the salt is padLen-mdMethod->GetDigestSize-2 + // The configured salt length does not meet the specification. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_PSS_SALT_LEN); + return CRYPT_RSA_ERR_PSS_SALT_LEN; + } + (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad)); + (void)memcpy_s(&(ctx->pad.para.pss), sizeof(RSA_PadingPara), val, sizeof(RSA_PadingPara)); + ctx->pad.type = EMSA_PSS; + ctx->pad.para.pss.mdId = pad->mdId; + ctx->pad.para.pss.mgfId = pad->mgfId; + return CRYPT_SUCCESS; +} + +static int32_t SetOaep(CRYPT_RSA_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(RSA_PadingPara)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_RSAES_OAEP_LEN_ERROR); + return CRYPT_RSA_SET_RSAES_OAEP_LEN_ERROR; + } + + (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad)); + (void)memcpy_s(&(ctx->pad.para.oaep), sizeof(RSA_PadingPara), val, sizeof(RSA_PadingPara)); + ctx->pad.type = RSAES_OAEP; + return CRYPT_SUCCESS; +} + +static int32_t SetOaepLabel(CRYPT_RSA_Ctx *ctx, const void *val, uint32_t len) +{ + uint8_t *data = NULL; + // val can be NULL + if ((val == NULL && len != 0) || (len == 0 && val != NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len == 0 && val == NULL) { + BSL_SAL_FREE(ctx->label.data); + ctx->label.data = NULL; + ctx->label.len = 0; + return CRYPT_SUCCESS; + } + data = (uint8_t *)BSL_SAL_Malloc(len); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + BSL_SAL_FREE(ctx->label.data); + ctx->label.data = data; + ctx->label.len = len; + (void)memcpy_s(ctx->label.data, ctx->label.len, val, len); + return CRYPT_SUCCESS; +} +static int32_t SetRsaesPkcsV15(CRYPT_RSA_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(CRYPT_RSA_PkcsV15Para)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR); + return CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR; + } + + (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad)); + (void)memcpy_s(&(ctx->pad.para.pkcsv15), sizeof(CRYPT_RSA_PkcsV15Para), val, sizeof(CRYPT_RSA_PkcsV15Para)); + ctx->pad.type = RSAES_PKCSV15; + return CRYPT_SUCCESS; +} +static int32_t SetSalt(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->prvKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + if (ctx->pad.type != EMSA_PSS) { + // In non-PSS mode, salt information cannot be set. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_SALT_NOT_PSS_ERROR); + return CRYPT_RSA_SET_SALT_NOT_PSS_ERROR; + } + RSA_PadingPara *pad = &(ctx->pad.para.pss); + uint32_t bytes = BN_BITS_TO_BYTES(CRYPT_RSA_GetBits(ctx)); + // The maximum salt length is padLen - mdMethod->GetDigestSize - 2 + if (len > bytes - pad->mdMeth->mdSize - 2) { + // The configured salt length does not meet the specification. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_SALT_LEN); + return CRYPT_RSA_ERR_SALT_LEN; + } + ctx->pad.salt.data = val; + ctx->pad.salt.len = len; + return CRYPT_SUCCESS; +} + +static int32_t GetSaltLen(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + (void)len; + int32_t *valTmp = val; + if (valTmp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->pad.type != EMSA_PSS) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ALGID); + return CRYPT_RSA_ERR_ALGID; + } + *valTmp = ctx->pad.para.pss.saltLen; + return CRYPT_SUCCESS; +} + +static int32_t GetPadding(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + RSA_PadType *valTmp = val; + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(int32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_FLAG_LEN_ERROR); + return CRYPT_RSA_SET_FLAG_LEN_ERROR; + } + *valTmp = ctx->pad.type; + return CRYPT_SUCCESS; +} + +static int32_t GetMd(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + (void)len; + CRYPT_MD_AlgId *valTmp = val; + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->pad.type == EMSA_PKCSV15) { + *valTmp = ctx->pad.para.pkcsv15.mdId; + return CRYPT_SUCCESS; + } + *valTmp = ctx->pad.para.pss.mdId; + + return CRYPT_SUCCESS; +} + +static int32_t GetMgf(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + (void)len; + CRYPT_MD_AlgId *valTmp = val; + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (ctx->pad.type == EMSA_PKCSV15) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ALGID); + return CRYPT_RSA_ERR_ALGID; + } + *valTmp = ctx->pad.para.pss.mgfId; + return CRYPT_SUCCESS; +} + +static int32_t SetFlag(CRYPT_RSA_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL || ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t flag = *(const uint32_t *)val; + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_FLAG_LEN_ERROR); + return CRYPT_RSA_SET_FLAG_LEN_ERROR; + } + if (flag == 0 || flag >= CRYPT_RSA_MAXFLAG) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_FLAG_NOT_SUPPORT_ERROR); + return CRYPT_RSA_FLAG_NOT_SUPPORT_ERROR; + } + ctx->flags |= flag; + return CRYPT_SUCCESS; +} + +static int32_t ClearFlag(CRYPT_RSA_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL || ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_FLAG_LEN_ERROR); + return CRYPT_RSA_SET_FLAG_LEN_ERROR; + } + uint32_t flag = *(const uint32_t *)val; + + if (flag == 0 || flag >= CRYPT_RSA_MAXFLAG) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_FLAG_NOT_SUPPORT_ERROR); + return CRYPT_RSA_FLAG_NOT_SUPPORT_ERROR; + } + ctx->flags &= ~flag; + return CRYPT_SUCCESS; +} + +static int32_t RsaUpReferences(CRYPT_RSA_Ctx *ctx, void *val, uint32_t len) +{ + if (val != NULL && len == (uint32_t)sizeof(int)) { + return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val); + } + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; +} + +static int32_t SetRsaPad(CRYPT_RSA_Ctx *ctx, const void *val, const uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(int32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_SET_FLAG_LEN_ERROR); + return CRYPT_RSA_SET_FLAG_LEN_ERROR; + } + + int32_t pad = *(int32_t *)val; + if (pad < EMSA_PKCSV15 || pad > RSA_NO_PAD) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + + ctx->pad.type = pad; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_Ctrl(CRYPT_RSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + switch (opt) { + case CRYPT_CTRL_SET_RSA_EMSA_PKCSV15: + return SetEmsaPkcsV15(ctx, val, len); + case CRYPT_CTRL_SET_RSA_EMSA_PSS: + return SetEmsaPss(ctx, val, len); + case CRYPT_CTRL_SET_RSA_SALT: + return SetSalt(ctx, val, len); + case CRYPT_CTRL_GET_RSA_SALT: + return GetSaltLen(ctx, val, len); + case CRYPT_CTRL_GET_RSA_PADDING: + return GetPadding(ctx, val, len); + case CRYPT_CTRL_GET_RSA_MD: + return GetMd(ctx, val, len); + case CRYPT_CTRL_GET_RSA_MGF: + return GetMgf(ctx, val, len); + + case CRYPT_CTRL_SET_RSA_RSAES_OAEP: + return SetOaep(ctx, val, len); + case CRYPT_CTRL_SET_RSA_OAEP_LABEL: + return SetOaepLabel(ctx, val, len); + case CRYPT_CTRL_SET_RSA_RSAES_PKCSV15: + return SetRsaesPkcsV15(ctx, val, len); + case CRYPT_CTRL_SET_RSA_FLAG: + return SetFlag(ctx, val, len); + case CRYPT_CTRL_CLR_RSA_FLAG: + return ClearFlag(ctx, val, len); + case CRYPT_CTRL_SET_RSA_PADDING: + return SetRsaPad(ctx, val, len); + case CRYPT_CTRL_UP_REFERENCES: + return RsaUpReferences(ctx, val, len); + default: + BSL_ERR_PUSH_ERROR(CRYPT_RSA_CTRL_NOT_SUPPORT_ERROR); + return CRYPT_RSA_CTRL_NOT_SUPPORT_ERROR; + } +} +#endif // HITLS_CRYPTO_RSA diff --git a/crypto/rsa/src/rsa_keygen.c b/crypto/rsa/src/rsa_keygen.c new file mode 100644 index 00000000..d0a59875 --- /dev/null +++ b/crypto/rsa/src/rsa_keygen.c @@ -0,0 +1,669 @@ +/* + * 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_RSA + +#include "crypt_rsa.h" +#include "rsa_local.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" + + +CRYPT_RSA_Ctx *CRYPT_RSA_NewCtx(void) +{ + CRYPT_RSA_Ctx *keyCtx = NULL; + keyCtx = BSL_SAL_Malloc(sizeof(CRYPT_RSA_Ctx)); + if (keyCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + (void)memset_s(keyCtx, sizeof(CRYPT_RSA_Ctx), 0, sizeof(CRYPT_RSA_Ctx)); + BSL_SAL_ReferencesInit(&(keyCtx->references)); + return keyCtx; +} + +static CRYPT_RSA_PubKey *RSAPubKeyDupCtx(CRYPT_RSA_PubKey *pubKey) +{ + CRYPT_RSA_PubKey *newPubKey = BSL_SAL_Malloc(sizeof(CRYPT_RSA_PubKey)); + if (newPubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newPubKey, sizeof(CRYPT_RSA_PubKey), 0, sizeof(CRYPT_RSA_PubKey)); + + GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->e, pubKey->e, BN_Dup(pubKey->e), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPubKey->n, pubKey->n, BN_Dup(pubKey->n), CRYPT_MEM_ALLOC_FAIL); + + newPubKey->mont = BN_MontCreate(pubKey->n); + if (newPubKey->mont == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + + return newPubKey; + +ERR : + RSA_FREE_PUB_KEY(newPubKey); + return NULL; +} + +static CRYPT_RSA_PrvKey *RSAPriKeyDupCtx(CRYPT_RSA_PrvKey *prvKey) +{ + CRYPT_RSA_PrvKey *newPriKey = BSL_SAL_Malloc(sizeof(CRYPT_RSA_PrvKey)); + if (newPriKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newPriKey, sizeof(CRYPT_RSA_PrvKey), 0, sizeof(CRYPT_RSA_PrvKey)); + + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->n, prvKey->n, BN_Dup(prvKey->n), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->d, prvKey->d, BN_Dup(prvKey->d), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->p, prvKey->p, BN_Dup(prvKey->p), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->q, prvKey->q, BN_Dup(prvKey->q), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->dP, prvKey->dP, BN_Dup(prvKey->dP), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->dQ, prvKey->dQ, BN_Dup(prvKey->dQ), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->qInv, prvKey->qInv, BN_Dup(prvKey->qInv), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPriKey->e, prvKey->e, BN_Dup(prvKey->e), CRYPT_MEM_ALLOC_FAIL); + + return newPriKey; +ERR: + RSA_FREE_PRV_KEY(newPriKey); + return NULL; +} + +static CRYPT_RSA_Para *RSAParaDupCtx(CRYPT_RSA_Para *para) +{ + CRYPT_RSA_Para *newPara = BSL_SAL_Malloc(sizeof(CRYPT_RSA_Para)); + if (newPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newPara, sizeof(CRYPT_RSA_Para), 0, sizeof(CRYPT_RSA_Para)); + + newPara->bits = para->bits; + GOTO_ERR_IF_SRC_NOT_NULL(newPara->e, para->e, BN_Dup(para->e), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPara->p, para->p, BN_Dup(para->p), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newPara->q, para->q, BN_Dup(para->q), CRYPT_MEM_ALLOC_FAIL); + return newPara; + +ERR : + RSA_FREE_PARA(newPara); + return NULL; +} + +static RSA_Blind *RSABlindDupCtx(RSA_Blind *blind) +{ + RSA_Blind *newBlind = BSL_SAL_Malloc(sizeof(RSA_Blind)); + if (newBlind == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newBlind, sizeof(RSA_Blind), 0, sizeof(RSA_Blind)); + + GOTO_ERR_IF_SRC_NOT_NULL(newBlind->a, blind->a, BN_Dup(blind->a), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newBlind->ai, blind->ai, BN_Dup(blind->ai), CRYPT_MEM_ALLOC_FAIL); + return newBlind; + +ERR: + RSA_BlindFreeCtx(newBlind); + return NULL; +} + +CRYPT_RSA_Ctx *CRYPT_RSA_DupCtx(CRYPT_RSA_Ctx *keyCtx) +{ + if (keyCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + CRYPT_RSA_Ctx *newKeyCtx = NULL; + newKeyCtx = BSL_SAL_Malloc(sizeof(CRYPT_RSA_Ctx)); + if (newKeyCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + (void)memset_s(newKeyCtx, sizeof(CRYPT_RSA_Ctx), 0, sizeof(CRYPT_RSA_Ctx)); + + newKeyCtx->flags = keyCtx->flags; + (void)memcpy_s(&(newKeyCtx->pad), sizeof(RSAPad), &(keyCtx->pad), sizeof(RSAPad)); + + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->prvKey, keyCtx->prvKey, RSAPriKeyDupCtx(keyCtx->prvKey), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->pubKey, keyCtx->pubKey, RSAPubKeyDupCtx(keyCtx->pubKey), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->blind, keyCtx->blind, RSABlindDupCtx(keyCtx->blind), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newKeyCtx->para, keyCtx->para, RSAParaDupCtx(keyCtx->para), CRYPT_MEM_ALLOC_FAIL); + BSL_SAL_ReferencesInit(&(newKeyCtx->references)); + return newKeyCtx; + +ERR : + CRYPT_RSA_FreeCtx(newKeyCtx); + return NULL; +} + +static int32_t RsaNewParaBasicCheck(const CRYPT_RsaPara *para) +{ + if (para == NULL || para->e == NULL || para->eLen == 0 || + para->bits > RSA_MAX_MODULUS_BITS || para->bits < RSA_MIN_MODULUS_BITS) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + /* the length of e cannot be greater than bits */ + if (para->eLen > BN_BITS_TO_BYTES(para->bits)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + return CRYPT_SUCCESS; +} + +CRYPT_RSA_Para *CRYPT_RSA_NewPara(const CRYPT_RsaPara *para) +{ + if (RsaNewParaBasicCheck(para) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return NULL; + } + CRYPT_RSA_Para *retPara = BSL_SAL_Malloc(sizeof(CRYPT_RSA_Para)); + if (retPara == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + retPara->bits = para->bits; + retPara->e = BN_Create(para->bits); + retPara->p = BN_Create(para->bits); + retPara->q = BN_Create(para->bits); + if (retPara->e == NULL || retPara->p == NULL || retPara->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + int32_t ret; + ret = BN_Bin2Bn(retPara->e, para->e, para->eLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (BN_BITS_TO_BYTES(para->bits) > RSA_SMALL_MODULUS_BYTES && BN_Bytes(retPara->e) > RSA_MAX_PUBEXP_BYTES) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + goto ERR; + } + return retPara; +ERR: + CRYPT_RSA_FreePara(retPara); + return NULL; +} + +void CRYPT_RSA_FreePara(CRYPT_RSA_Para *para) +{ + if (para == NULL) { + return; + } + BN_Destroy(para->e); + BN_Destroy(para->p); + BN_Destroy(para->q); + BSL_SAL_FREE(para); +} + +void RSA_FreePrvKey(CRYPT_RSA_PrvKey *prvKey) +{ + if (prvKey == NULL) { + return; + } + BN_Destroy(prvKey->n); + BN_Destroy(prvKey->d); + BN_Destroy(prvKey->p); + BN_Destroy(prvKey->q); + BN_Destroy(prvKey->e); + BN_Destroy(prvKey->dP); + BN_Destroy(prvKey->dQ); + BN_Destroy(prvKey->qInv); + BSL_SAL_FREE(prvKey); +} + +void RSA_FreePubKey(CRYPT_RSA_PubKey *pubKey) +{ + if (pubKey == NULL) { + return; + } + BN_Destroy(pubKey->n); + BN_Destroy(pubKey->e); + BN_MontDestroy(pubKey->mont); + BSL_SAL_FREE(pubKey); +} + +void CRYPT_RSA_FreeCtx(CRYPT_RSA_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + int i = 0; + BSL_SAL_AtomicDownReferences(&(ctx->references), &i); + if (i > 0) { + return; + } + + BSL_SAL_ReferencesFree(&(ctx->references)); + RSA_FREE_PARA(ctx->para); + RSA_FREE_PRV_KEY(ctx->prvKey); + RSA_FREE_PUB_KEY(ctx->pubKey); + RSA_BlindFreeCtx(ctx->blind); + ctx->blind = NULL; + BSL_SAL_CleanseData((void *)(&(ctx->pad)), sizeof(RSAPad)); + BSL_SAL_FREE(ctx->label.data); + BSL_SAL_FREE(ctx); +} + +static int32_t IsRSASetParaVaild(const CRYPT_RSA_Ctx *ctx, const CRYPT_RSA_Para *para) +{ + if (ctx == NULL || para == NULL || para->e == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (para->bits > RSA_MAX_MODULUS_BITS || para->bits < RSA_MIN_MODULUS_BITS) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + + if (BN_GetBit(para->e, 0) != true || BN_IsLimb(para->e, 1) == true) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_E_VALUE); + return CRYPT_RSA_ERR_E_VALUE; + } + return CRYPT_SUCCESS; +} + +CRYPT_RSA_Para *CRYPT_RSA_DupPara(const CRYPT_RSA_Para *para) +{ + CRYPT_RSA_Para *paraCopy = BSL_SAL_Malloc(sizeof(CRYPT_RSA_Para)); + if (paraCopy == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + paraCopy->bits = para->bits; + paraCopy->e = BN_Dup(para->e); + paraCopy->p = BN_Dup(para->p); + paraCopy->q = BN_Dup(para->q); + if (paraCopy->e == NULL || paraCopy->p == NULL || paraCopy->q == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + RSA_FREE_PARA(paraCopy); + return NULL; + } + + return paraCopy; +} + +int32_t CRYPT_RSA_SetPara(CRYPT_RSA_Ctx *ctx, const CRYPT_RSA_Para *para) +{ + int32_t ret = IsRSASetParaVaild(ctx, para); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad)); + CRYPT_RSA_Para *paraCopy = CRYPT_RSA_DupPara(para); + if (paraCopy == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + RSA_FREE_PARA(ctx->para); + RSA_FREE_PRV_KEY(ctx->prvKey); + RSA_FREE_PUB_KEY(ctx->pubKey); + ctx->para = paraCopy; + return CRYPT_SUCCESS; +} + +CRYPT_RSA_PrvKey *RSA_NewPrvKey(uint32_t bits) +{ + CRYPT_RSA_PrvKey *priKey = BSL_SAL_Malloc(sizeof(CRYPT_RSA_PrvKey)); + if (priKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + priKey->n = BN_Create(bits); + priKey->d = BN_Create(bits); + priKey->p = BN_Create(bits); + priKey->q = BN_Create(bits); + priKey->e = BN_Create(bits); + priKey->dP = BN_Create(bits); + priKey->dQ = BN_Create(bits); + priKey->qInv = BN_Create(bits); + bool creatFailed = (priKey->n == NULL || priKey->d == NULL || priKey->e == NULL || priKey->p == NULL || + priKey->q == NULL || priKey->dP == NULL || priKey->dQ == NULL || priKey->qInv == NULL); + if (creatFailed) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + RSA_FREE_PRV_KEY(priKey); + } + return priKey; +} + +CRYPT_RSA_PubKey *RSA_NewPubKey(uint32_t bits) +{ + CRYPT_RSA_PubKey *pubKey = BSL_SAL_Malloc(sizeof(CRYPT_RSA_PubKey)); + if (pubKey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + pubKey->n = BN_Create(bits); + pubKey->e = BN_Create(bits); + pubKey->mont = NULL; + if (pubKey->n == NULL || pubKey->e == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + RSA_FREE_PUB_KEY(pubKey); + } + return pubKey; +} + +uint32_t CRYPT_RSA_GetBits(const CRYPT_RSA_Ctx *ctx) +{ + if (ctx == NULL) { + return 0; + } + if (ctx->para != NULL) { + return ctx->para->bits; + } + if (ctx->prvKey != NULL) { + return BN_Bits(ctx->prvKey->n); + } + if (ctx->pubKey != NULL) { + return BN_Bits(ctx->pubKey->n); + } + return 0; +} + +uint32_t CRYPT_RSA_GetSignLen(const CRYPT_RSA_Ctx *ctx) +{ + return BN_BITS_TO_BYTES(CRYPT_RSA_GetBits(ctx)); +} + +static int32_t RSA_Filter( + const BN_BigNum *p, uint32_t bits, const BN_BigNum *e, BN_Optimizer *optimizer) +{ + int32_t ret; + BN_BigNum *pMinus1 = BN_Create(bits); + BN_BigNum *u = BN_Create(bits); + if (pMinus1 == NULL || u == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_SubLimb(pMinus1, p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Gcd(u, pMinus1, e, optimizer); + if (ret == CRYPT_SUCCESS) { + if (BN_IsOne(u) != true) { + ret = CRYPT_RSA_NOR_KEYGEN_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } + } + +ERR: + BN_Destroy(pMinus1); + BN_Destroy(u); + return ret; +} + +static int32_t RsaPGen(CRYPT_RSA_Para *para, CRYPT_RSA_PrvKey *priKey, BN_Optimizer *optimizer) +{ + uint32_t pBits = (para->bits + 1) / 2; + int32_t ret = BN_GenPrime(priKey->p, pBits, true, optimizer, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return RSA_Filter(priKey->p, pBits, para->e, optimizer); +} + +static int32_t RsaQGen(CRYPT_RSA_Para *para, CRYPT_RSA_PrvKey *priKey, BN_Optimizer *optimizer) +{ + uint32_t pBits = (para->bits + 1) / 2; + uint32_t qBits = para->bits - pBits; + int32_t ret = BN_GenPrime(priKey->q, qBits, true, optimizer, NULL); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return RSA_Filter(priKey->q, qBits, para->e, optimizer); +} + +static int32_t RsaPQGen(CRYPT_RSA_Para *para, CRYPT_RSA_PrvKey *priKey, BN_Optimizer *optimizer) +{ + int32_t ret = CRYPT_BN_RAND_GEN_FAIL; + uint32_t i; + uint32_t halfBits = para->bits / 2; + BN_BigNum *val = BN_Create(halfBits - 100); + BN_BigNum *sub = BN_Create(para->bits); + if (val == NULL || sub == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + // FIPS 186-4 B.3.3 5.4, compare with 2^(nlen/2-100) + GOTO_ERR_IF(BN_SetBit(val, halfBits - 100), ret); + + // FIPS 186-4 B.3.3 4.7, retry 5(nlen/2) times + for (i = 0; i < 5 * halfBits; i++) { + ret = RsaPGen(para, priKey, optimizer); + if (ret == CRYPT_SUCCESS) { + break; + } + } + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // FIPS 186-4 B.3.3 5.8, retry 5(nlen/2) times + for (i = 0; i < 5 * halfBits; i++) { + ret = RsaQGen(para, priKey, optimizer); + if (ret != CRYPT_SUCCESS) { + continue; + } + GOTO_ERR_IF(BN_Sub(sub, priKey->p, priKey->q), ret); + GOTO_ERR_IF(BN_SetSign(sub, false), ret); + if (BN_Cmp(sub, val) <= 0) { + continue; + } + break; + } + if (BN_Cmp(priKey->p, priKey->q) < 0) { + BN_BigNum *tmp = priKey->p; + priKey->p = priKey->q; + priKey->q = tmp; + } +ERR: + BN_Destroy(val); + BN_Destroy(sub); + return ret; +} + +static int32_t RsaPrvKeyCalcND( + CRYPT_RSA_Ctx *ctx, BN_BigNum *pMinusOne, BN_BigNum *qMinusOne, BN_Optimizer *optimizer) +{ + int32_t ret; + if (ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + CRYPT_RSA_PrvKey *prvKey = ctx->prvKey; + BN_BigNum *l = BN_Create(ctx->para->bits); + BN_BigNum *u = BN_Create(ctx->para->bits); + if (l == NULL || u == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + ret = BN_Mul(prvKey->n, prvKey->p, prvKey->q, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Mul(l, pMinusOne, qMinusOne, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Gcd(u, pMinusOne, qMinusOne, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Div(l, NULL, l, u, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_ModInv(prvKey->d, ctx->para->e, l, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + BN_Destroy(l); + BN_Destroy(u); + return ret; +} + +// p, q [ => n, d] => dP dQ qInv +// ctx->para may be NULL when setting key +int32_t RSA_CalcPrvKey(CRYPT_RSA_Ctx *ctx, BN_Optimizer *optimizer) +{ + int32_t ret; + CRYPT_RSA_PrvKey *prvKey = ctx->prvKey; + BN_BigNum *pMinusOne = BN_Create(BN_Bits(prvKey->p)); + BN_BigNum *qMinusOne = BN_Create(BN_Bits(prvKey->q)); + if (pMinusOne == NULL || qMinusOne == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_SubLimb(pMinusOne, prvKey->p, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_SubLimb(qMinusOne, prvKey->q, 1); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (BN_IsZero(prvKey->n)) { // when generating key + ret = RsaPrvKeyCalcND(ctx, pMinusOne, qMinusOne, optimizer); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + } + ret = BN_ModInv(prvKey->qInv, prvKey->q, prvKey->p, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Div(NULL, prvKey->dP, prvKey->d, pMinusOne, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = BN_Div(NULL, prvKey->dQ, prvKey->d, qMinusOne, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + BN_Destroy(pMinusOne); + BN_Destroy(qMinusOne); + return ret; +} + +int32_t CRYPT_RSA_Gen(CRYPT_RSA_Ctx *ctx) +{ + if (ctx == NULL || ctx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + int32_t ret = CRYPT_MEM_ALLOC_FAIL; + BN_Optimizer *optimizer = NULL; + CRYPT_RSA_Ctx *newCtx = CRYPT_RSA_NewCtx(); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + newCtx->para = CRYPT_RSA_DupPara(ctx->para); + if (newCtx->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + + newCtx->prvKey = RSA_NewPrvKey(newCtx->para->bits); + newCtx->pubKey = RSA_NewPubKey(newCtx->para->bits); + optimizer = BN_OptimizerCreate(); + if (optimizer == NULL || newCtx->prvKey == NULL || newCtx->pubKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = RsaPQGen(newCtx->para, newCtx->prvKey, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = RSA_CalcPrvKey(newCtx, optimizer); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(BN_Copy(newCtx->pubKey->n, newCtx->prvKey->n), ret); + GOTO_ERR_IF(BN_Copy(newCtx->pubKey->e, newCtx->para->e), ret); + GOTO_ERR_IF(BN_Copy(newCtx->prvKey->e, newCtx->para->e), ret); + + if ((newCtx->pubKey->mont = BN_MontCreate(newCtx->pubKey->n)) == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ShallowCopyCtx(ctx, newCtx); + BSL_SAL_FREE(newCtx); + BN_OptimizerDestroy(optimizer); + return ret; +ERR: + CRYPT_RSA_FreeCtx(newCtx); + BN_OptimizerDestroy(optimizer); + return ret; +} + +void ShallowCopyCtx(CRYPT_RSA_Ctx *ctx, CRYPT_RSA_Ctx *newCtx) +{ + RSA_FREE_PARA(ctx->para); + RSA_FREE_PRV_KEY(ctx->prvKey); + RSA_FREE_PUB_KEY(ctx->pubKey); + RSA_BlindFreeCtx(ctx->blind); + BSL_SAL_ReferencesFree(&(newCtx->references)); + + ctx->prvKey = newCtx->prvKey; + ctx->pubKey = newCtx->pubKey; + ctx->para = newCtx->para; + ctx->blind = newCtx->blind; + ctx->pad = newCtx->pad; + ctx->flags = newCtx->flags; +} +#endif // HITLS_CRYPTO_RSA diff --git a/crypto/rsa/src/rsa_keyop.c b/crypto/rsa/src/rsa_keyop.c new file mode 100644 index 00000000..22a746e9 --- /dev/null +++ b/crypto/rsa/src/rsa_keyop.c @@ -0,0 +1,342 @@ +/* + * 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_RSA + +#include "crypt_types.h" +#include "crypt_rsa.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "rsa_local.h" +#include "crypt_errno.h" +#include "securec.h" +#include "bsl_sal.h" + + +static int32_t SetPrvPara(const CRYPT_RSA_PrvKey *prvKey, const CRYPT_RsaPrv *prv) +{ + int32_t ret = BN_Bin2Bn(prvKey->n, prv->n, prv->nLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t bnBits = BN_Bits(prvKey->n); + if (bnBits > RSA_MAX_MODULUS_BITS || bnBits < RSA_MIN_MODULUS_BITS) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + ret = BN_Bin2Bn(prvKey->d, prv->d, prv->dLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // d cannot be 0 or 1. The mathematical logic of e and d is that + // d and e are reciprocal in mod((p-1) * (q-1)); When d is 1, e and d must be 1. When d is 0, e doesn't exist. + if (BN_IsZero(prvKey->d) || BN_IsOne(prvKey->d)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + if (BN_Cmp(prvKey->n, prvKey->d) <= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + if (prv->e != NULL) { + ret = BN_Bin2Bn(prvKey->e, prv->e, prv->eLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (BN_Cmp(prvKey->n, prvKey->e) <= 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + } + if (prv->p != NULL) { + GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->p, prv->p, prv->pLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->q, prv->q, prv->qLen), ret); + if (BN_IsZero(prvKey->p) == true || BN_IsZero(prvKey->q) == true) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + if (prv->dP != NULL) { + GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->dP, prv->dP, prv->dPLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->dQ, prv->dQ, prv->dQLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->qInv, prv->qInv, prv->qInvLen), ret); + } + } +ERR: + return ret; +} + +// If n and d are not NULL, p and q are optional. If p and q exist, qInv, dP, and dQ need to be calculated. +static int32_t SetPrvBasicCheck(const CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPrv *prv) +{ + if (ctx == NULL || prv == NULL || prv->n == NULL || prv->d == NULL || prv->nLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (prv->nLen > RSA_MAX_MODULUS_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + // prv->p\q and prv->dP\dQ\qInv must be both empty or not. + // If prv->p is empty, prv->dP must be empty. + if ((prv->p == NULL) != (prv->q == NULL) || (prv->p == NULL && prv->dP != NULL) || + ((prv->dP == NULL || prv->dQ == NULL || prv->qInv == NULL) && (prv->dP || prv->dQ || prv->qInv))) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO); + return CRYPT_RSA_NO_KEY_INFO; + } + return CRYPT_SUCCESS; +} + +static int32_t SetPrvBnLenCheck(const CRYPT_RsaPrv *prv) +{ + /* The length of n is used as the length of a BigNum. The lengths of d, p, and q are not greater than n. */ + uint32_t bnBytes = prv->nLen; + if (prv->dLen > bnBytes || prv->pLen > bnBytes || prv->qLen > bnBytes) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_SetPrvKey(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPrv *prv) +{ + int32_t ret = SetPrvBasicCheck(ctx, prv); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = SetPrvBnLenCheck(prv); + if (ret != CRYPT_SUCCESS) { + return ret; + } + CRYPT_RSA_Ctx *newCtx = CRYPT_RSA_NewCtx(); + if (newCtx == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + newCtx->prvKey = RSA_NewPrvKey(prv->nLen * 8); // Bit length is obtained by multiplying byte length by 8. + if (newCtx->prvKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = SetPrvPara(newCtx->prvKey, prv); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (prv->p != NULL && prv->dP == NULL) { + BN_Optimizer *optimizer = BN_OptimizerCreate(); + if (optimizer == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + ret = RSA_CalcPrvKey(newCtx, optimizer); + if (ret != CRYPT_SUCCESS) { + BN_OptimizerDestroy(optimizer); + goto ERR; + } + BN_OptimizerDestroy(optimizer); + } + + RSA_FREE_PRV_KEY(ctx->prvKey); + RSA_BlindFreeCtx(ctx->blind); + + ctx->prvKey = newCtx->prvKey; + ctx->blind = newCtx->blind; + ctx->pad = newCtx->pad; + + BSL_SAL_FREE(newCtx); + return ret; +ERR: + CRYPT_RSA_FreeCtx(newCtx); + return ret; +} + +static int32_t SetPubBasicCheck(const CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPub *pub) +{ + if (ctx == NULL || pub == NULL || pub->n == NULL || pub->e == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (pub->nLen > RSA_MAX_MODULUS_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + /* The length of n is used as the length of a BigNum, and the length of e is not greater than n. */ + if (pub->eLen > pub->nLen) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_SetPubKey(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPub *pub) +{ + int32_t ret = SetPubBasicCheck(ctx, pub); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t bnBits; + CRYPT_RSA_PubKey *newPub = NULL; + (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad)); + /* Bit length is obtained by multiplying byte length by 8. */ + newPub = RSA_NewPubKey(pub->nLen * 8); + if (newPub == NULL) { + return CRYPT_MEM_ALLOC_FAIL; + } + GOTO_ERR_IF(BN_Bin2Bn(newPub->n, pub->n, pub->nLen), ret); + bnBits = BN_Bits(newPub->n); + if (bnBits > RSA_MAX_MODULUS_BITS || bnBits < RSA_MIN_MODULUS_BITS) { + ret = CRYPT_RSA_ERR_KEY_BITS; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(BN_Bin2Bn(newPub->e, pub->e, pub->eLen), ret); + if (pub->nLen > RSA_SMALL_MODULUS_BYTES && BN_Bytes(newPub->e) > RSA_MAX_PUBEXP_BYTES) { + ret = CRYPT_RSA_ERR_KEY_BITS; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /** + * n > e + * e cannot be 0 or 1; The mathematical logic of e and d is that + * d and e are reciprocal in mod((p - 1) * (q - 1)); + * When e is 1, both e and d must be 1. When e is 0, d does not exist. + */ + if (BN_Cmp(newPub->n, newPub->e) <= 0 || BN_IsZero(newPub->e) || BN_IsOne(newPub->e)) { + ret = CRYPT_RSA_ERR_INPUT_VALUE; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + newPub->mont = BN_MontCreate(newPub->n); + if (newPub->mont == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + RSA_FREE_PUB_KEY(ctx->pubKey); + ctx->pubKey = newPub; + return ret; +ERR: + RSA_FREE_PUB_KEY(newPub); + return ret; +} + +static int32_t GetPrvBasicCheck(const CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPrv *prv) +{ + // ctx\ctx->prvKey\prv is not empty. + // prv->p\q and prv->dP\dQ\qInv are both null or non-null. + // If prv->p is empty, prv->dP is empty. + if (ctx == NULL || ctx->prvKey == NULL || prv == NULL || ((prv->p == NULL) != (prv->q == NULL)) || + ((prv->dP == NULL || prv->dQ == NULL || prv->qInv == NULL) && (prv->dP || prv->dQ || prv->qInv)) || + (prv->p == NULL && prv->dP != NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_GetPrvKey(const CRYPT_RSA_Ctx *ctx, CRYPT_RsaPrv *prv) +{ + int32_t ret = GetPrvBasicCheck(ctx, prv); + if (ret != CRYPT_SUCCESS) { + return ret; + } + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->n, prv->n, &prv->nLen), ret); + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->d, prv->d, &prv->dLen), ret); + if (prv->e != NULL) { + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->e, prv->e, &prv->eLen), ret); + } + if (prv->p != NULL) { + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->p, prv->p, &prv->pLen), ret); + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->q, prv->q, &prv->qLen), ret); + } + if (prv->dQ != NULL) { + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->dQ, prv->dQ, &prv->dQLen), ret); + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->dP, prv->dP, &prv->dPLen), ret); + GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->qInv, prv->qInv, &prv->qInvLen), ret); + } + return CRYPT_SUCCESS; + +ERR: + if (prv->d != NULL && prv->dLen != 0) { + BSL_SAL_CleanseData(prv->d, prv->dLen); + } + if (prv->p != NULL && prv->pLen != 0) { + BSL_SAL_CleanseData(prv->p, prv->pLen); + } + if (prv->q != NULL && prv->qLen != 0) { + BSL_SAL_CleanseData(prv->q, prv->qLen); + } + if (prv->dQ != NULL && prv->dQLen != 0) { + BSL_SAL_CleanseData(prv->dQ, prv->dQLen); + } + if (prv->dP != NULL && prv->dPLen != 0) { + BSL_SAL_CleanseData(prv->dP, prv->dPLen); + } + if (prv->qInv != NULL && prv->qInvLen != 0) { + BSL_SAL_CleanseData(prv->qInv, prv->qInvLen); + } + return ret; +} + +int32_t CRYPT_RSA_GetPubKey(const CRYPT_RSA_Ctx *ctx, CRYPT_RsaPub *pub) +{ + if (ctx == NULL || ctx->pubKey == NULL || pub == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = BN_Bn2Bin(ctx->pubKey->e, pub->e, &pub->eLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BN_Bn2Bin(ctx->pubKey->n, pub->n, &pub->nLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t CRYPT_RSA_Cmp(const CRYPT_RSA_Ctx *a, const CRYPT_RSA_Ctx *b) +{ + RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT); + + RETURN_RET_IF(a->pubKey == NULL || b->pubKey == NULL, CRYPT_RSA_NO_KEY_INFO); + + RETURN_RET_IF(BN_Cmp(a->pubKey->n, b->pubKey->n) != 0 || + BN_Cmp(a->pubKey->e, b->pubKey->e) != 0, + CRYPT_RSA_PUBKEY_NOT_EQUAL); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_GetSecBits(const CRYPT_RSA_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + int32_t bits = (int32_t)CRYPT_RSA_GetBits(ctx); + return BN_SecBit(bits, -1); +} +#endif // HITLS_CRYPTO_RSA diff --git a/crypto/rsa/src/rsa_local.h b/crypto/rsa/src/rsa_local.h new file mode 100644 index 00000000..8c16e12e --- /dev/null +++ b/crypto/rsa/src/rsa_local.h @@ -0,0 +1,195 @@ +/* + * 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 RSA_LOCAL_H +#define RSA_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_RSA + +#include "crypt_rsa.h" +#include "crypt_bn.h" +#include "crypt_local_types.h" +#include "crypt_types.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +// When the padding type is PSS, the salt data is obtained by the DRBG and the length is hashlen. +#define SALTLEN_PSS_HASHLEN_TYPE (-1) +// When the padding type is PSS, the salt data is obtained by the DRBG. +// and the length is padLen - mdMethod->GetDigestSize - 2 +#define SALTLEN_PSS_MAXLEN_TYPE (-2) +// get salt length from signature +#define SALTLEN_PSS_AUTOLEN_TYPE (-3) + +#define HASH_MAX_MDSIZE (64) + +typedef struct RSA_BlindSt { + BN_BigNum *a; + BN_BigNum *ai; +} RSA_Blind; + +typedef struct { + BN_BigNum *n; // pub key n needed for no padding + BN_BigNum *d; // private key d needed for asn encoding + BN_BigNum *p; // prime factor p + BN_BigNum *q; // prime factor q + BN_BigNum *dP; // exponent dP for CRT + BN_BigNum *dQ; // exponent dQ for CRT + BN_BigNum *qInv; // CRT coefficient qInv + BN_BigNum *e; // public key e +} CRYPT_RSA_PrvKey; + +typedef struct { + BN_BigNum *n; // modulo Value - converted.Not in char + BN_BigNum *e; // Exponent Value -converted.Not in char + + // Montgomery pre-calculation cache + BN_Mont *mont; +} CRYPT_RSA_PubKey; + +struct RSA_Para { + BN_BigNum *e; // Exponent Value -converted.Not in char + uint32_t bits; // length in bits of modulus + BN_BigNum *p; // prime factor p + BN_BigNum *q; // prime factor q +}; + +/** + * @ingroup crypt_eal_pkey + * + * (For internal use)Set the padding mode of the RSA. The value 0 indicates that the padding mode is not set. + */ +typedef enum { + EMSA_PKCSV15 = 1, /**< PKCS1-v1_5 complies with RFC8017 */ + EMSA_PSS, /**< PSS complies with RFC8017 */ + RSAES_OAEP, /**< OAEP complies with RFC8017 */ + RSAES_PKCSV15, /**< RSAES_PKCSV15 complies with RFC8017 */ + RSA_NO_PAD, +} RSA_PadType; + +typedef struct { + RSA_PadType type; /**< padding id */ + union { + CRYPT_RSA_PkcsV15Para pkcsv15; /**< pkcsv15 padding mode */ + RSA_PadingPara pss; /**< pss padding mode */ + RSA_PadingPara oaep; /**< oaep padding mode */ + } para; /**< padding mode combination, including pss and pkcsv15 */ + CRYPT_Data salt; // Used for the KAT test. +} RSAPad; + +struct RSA_Ctx { + CRYPT_RSA_PrvKey *prvKey; + CRYPT_RSA_PubKey *pubKey; + CRYPT_RSA_Para *para; + RSA_Blind *blind; + RSAPad pad; + uint32_t flags; + CRYPT_Data label; // Used for oaep padding + BSL_SAL_RefCount references; +}; + +CRYPT_RSA_PrvKey *RSA_NewPrvKey(uint32_t bits); +CRYPT_RSA_PubKey *RSA_NewPubKey(uint32_t bits); +void RSA_FreePrvKey(CRYPT_RSA_PrvKey *prvKey); +void RSA_FreePubKey(CRYPT_RSA_PubKey *pubKey); +int32_t RSA_CalcPrvKey(CRYPT_RSA_Ctx *ctx, BN_Optimizer *optimizer); +int32_t GenPssSalt(CRYPT_Data *salt, const EAL_MdMethod *mdMethod, int32_t saltLen, uint32_t padBuffLen); +void ShallowCopyCtx(CRYPT_RSA_Ctx *ctx, CRYPT_RSA_Ctx *newCtx); +CRYPT_RSA_Para *CRYPT_RSA_DupPara(const CRYPT_RSA_Para *para); + +/** + * @ingroup rsa + * @brief Create a blinding handle. + * + * @retval Return the blinding handle. + */ +RSA_Blind *RSA_BlindNewCtx(void); + +/** + * @ingroup rsa + * @brief Release the blinding handle. + * + * @param b [IN] blinding Handle. b is set NULL by the invoker. + * + * @retval none + */ +void RSA_BlindFreeCtx(RSA_Blind *b); +/** + * @ingroup rsa + * @brief Multiply n by blinding factor A + * + * @param b [IN] Blinding Handle + * @param data [IN] Input data + * @param n [IN] n in the public key (n, e) + * @param opt [IN] BigNum optimizer + * + * @retval Return the error code. + */ +int32_t RSA_BlindCovert(RSA_Blind *b, BN_BigNum *data, BN_BigNum *n, BN_Optimizer *opt); + +/** + * @ingroup rsa + * @brief Multiply n by the reverse blinding factor Ai + * + * @param b [IN] Blinding Handle + * @param data [IN] Input data + * @param n [IN] n in the public key (n, e) + * @param opt [IN] BigNum optimizer + * + * @retval Return the error code. + */ +int32_t RSA_BlindInvert(RSA_Blind *b, BN_BigNum *data, BN_BigNum *n, BN_Optimizer *opt); +/** + * @ingroup rsa + * @brief Create a new Blind parameter with the parameters e and m, + * e in the public key (n, e), n in the public key (n, e) + * + * @param b [IN] Blinding Handle + * @param e [IN] e in the public key (n, e) + * @param n [IN] n in the public key (n, e) + * + * @retval Return the error code. + */ +int32_t RSA_BlindCreateParam(RSA_Blind *b, BN_BigNum *e, BN_BigNum *n, BN_Optimizer *opt); + +#define RSA_FREE_PRV_KEY(prvKey_) \ +do { \ + RSA_FreePrvKey((prvKey_)); \ + (prvKey_) = NULL; \ + } while (0) + +#define RSA_FREE_PUB_KEY(pubKey_) \ + do { \ + RSA_FreePubKey((pubKey_)); \ + (pubKey_) = NULL; \ + } while (0) + +#define RSA_FREE_PARA(para_) \ + do { \ + CRYPT_RSA_FreePara((para_)); \ + (para_) = NULL; \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_RSA + +#endif // RSA_LOCAL_H diff --git a/crypto/rsa/src/rsa_padding.c b/crypto/rsa/src/rsa_padding.c new file mode 100644 index 00000000..77b7acd3 --- /dev/null +++ b/crypto/rsa/src/rsa_padding.c @@ -0,0 +1,974 @@ +/* + * 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_RSA + +#include "crypt_rsa.h" +#include "rsa_local.h" +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_utils.h" +#include "crypt_util_rand.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" + +#define UINT32_SIZE 4 + +// outlen should be hash len +static int32_t CalcHash(const EAL_MdMethod *hashMethod, const CRYPT_Data *hashData, uint32_t size, + uint8_t *out, uint32_t outlen) +{ + uint32_t hLen = outlen; + void *mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + int32_t ret = hashMethod->init(mdCtx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (uint32_t i = 0; i < size; i++) { + ret = hashMethod->update(mdCtx, hashData[i].data, hashData[i].len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } + ret = hashMethod->final(mdCtx, out, &hLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +// T init to empty +// loop: T = T || Hash(mgfSeed || C), C = I2OSP (counter, 4), counter from 0 to ceil(maskLen / hLen) - 1 +static int32_t Mgf(const EAL_MdMethod *hashMethod, const uint8_t *seed, const uint32_t seedLen, + uint8_t *mask, uint32_t maskLen) +{ + uint32_t hashLen = hashMethod->mdSize; + if (hashLen > HASH_MAX_MDSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + uint8_t md[HASH_MAX_MDSIZE]; + uint8_t counter[UINT32_SIZE]; + + const CRYPT_Data hashData[] = { + {(uint8_t *)(uintptr_t)seed, seedLen}, // mgfSeed + {counter, sizeof(counter)} // counter + }; + int32_t ret = CRYPT_RSA_ERR_INPUT_VALUE; + uint32_t i, outLen, partLen; + for (i = 0, outLen = 0; outLen < maskLen; i++, outLen += partLen) { + PUT_UINT32_BE(i, counter, 0); + ret = CalcHash(hashMethod, hashData, sizeof(hashData) / sizeof(hashData[0]), md, hashLen); + if (ret != CRYPT_SUCCESS) { + goto ERR; + } + // Output the leading maskLen octets of T as the octet string mask + partLen = (outLen + hashLen <= maskLen) ? hashLen : (maskLen - outLen); + if (memcpy_s(mask + outLen, maskLen - outLen, md, partLen) != EOK) { + ret = CRYPT_SECUREC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + } +ERR: + BSL_SAL_CleanseData(md, sizeof(md)); + return ret; +} + +// maskedDB: [in] maskDB from MGF +// [out] maskedDB = DB xor maskDB +// DB: PS || 0x01 || salt; +// msBit: indicates the number of valid bits in the most significant bytes of the EM, +// value 0 indicates that all bits are valid. +static void MaskDB(uint8_t *maskedDB, uint32_t len, const uint8_t *salt, uint32_t saltLen, uint32_t msBit) +{ + uint8_t *tmp = maskedDB + (len - saltLen) - 1; // init point to pos of 0x01 + *tmp ^= 0x01; + tmp++; + uint32_t i; + for (i = 0; i < saltLen; i++) { + tmp[i] ^= salt[i]; + } + if (msBit != 0) { + // Set the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB to zero + maskedDB[0] &= ((uint8_t)(0xFF >> (8 - msBit))); + } +} + +static int32_t PssEncodeLengthCheck(uint32_t modBits, uint32_t hLen, + uint32_t saltLen, uint32_t dataLen, uint32_t padLen) +{ + if (modBits < RSA_MIN_MODULUS_BITS || modBits > RSA_MAX_MODULUS_BITS) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS); + return CRYPT_RSA_ERR_KEY_BITS; + } + if (hLen > RSA_MAX_MODULUS_LEN || dataLen != hLen) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + uint32_t keyBytes = BN_BITS_TO_BYTES(modBits); + if (keyBytes != padLen) { // The length required for padding does not match the key module length (API convention). + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + if (saltLen == (uint32_t)SALTLEN_PSS_AUTOLEN_TYPE) { + return CRYPT_SUCCESS; + } + if (saltLen > RSA_MAX_MODULUS_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_PSS_SALT_LEN); + return CRYPT_RSA_ERR_PSS_SALT_LEN; + } + uint32_t emLen = keyBytes; + // the octet length of EM will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise + if (((modBits - 1) & 0x7) == 0) { + emLen--; + } + if (emLen < hLen + saltLen + 2) { // RFC: If emLen < hLen + sLen + 2, output "encoding error" and stop. + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_PSS_SALT_LEN); + return CRYPT_RSA_ERR_PSS_SALT_LEN; + } + return CRYPT_SUCCESS; +} + +int32_t GenPssSalt(CRYPT_Data *salt, const EAL_MdMethod *mdMethod, int32_t saltLen, uint32_t padBuffLen) +{ + uint32_t hashLen = mdMethod->mdSize; + if (saltLen == SALTLEN_PSS_HASHLEN_TYPE) { // saltLen is -1 + salt->len = hashLen; + } else if (saltLen == SALTLEN_PSS_MAXLEN_TYPE || saltLen == SALTLEN_PSS_AUTOLEN_TYPE) { // saltLen is -2 or -3 + salt->len = padBuffLen - hashLen - 2; // salt, obtains from the DRBG + } else { + salt->len = (uint32_t)saltLen; + } + + salt->data = BSL_SAL_Malloc(salt->len); + if (salt->data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + // Obtain the salt through the public random number. + int32_t ret = CRYPT_Rand(salt->data, salt->len); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(salt->data); + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +/** + * EMSA-PSS Encoding Operation + * +-----------+ + * | M | + * +-----------+ + * | + * V + * Hash + * | + * V + * +--------+----------+----------+ + * M' = |Padding1| mHash | salt | + * +--------+----------+----------+ + * | + * +--------+----------+ V + * DB = |Padding2| salt | Hash + * +--------+----------+ | + * | | + * V | + * xor <--- MGF <---| maskDB = MGF(H, emLen - hLen - 1). + * | | + * | | + * V V + * +-------------------+----------+--+ + * EM = | maskedDB | H |bc| + * +-------------------+----------+--+ + * Output EM data with a fixed length (keyBytes) to the pad buffer. + * Add 0s to the first byte, if the EM length + 1 = keyBytes. + * Of which: + * The data is the mHash in the preceding figure. + * M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt + * DB = PS || 0x01 || salt; DB is an octet string of length emLen - hLen - 1 + * PS consisting of emLen - sLen - hLen - 2 zero octets, The length of PS may be 0. + */ +int32_t CRYPT_RSA_SetPss(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, uint32_t keyBits, + const uint8_t *salt, uint32_t saltLen, const uint8_t *data, uint32_t dataLen, uint8_t *pad, uint32_t padLen) +{ + int32_t ret; + if (hashMethod == NULL || mgfMethod == NULL || pad == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (salt == NULL && saltLen != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_PSS_SALT_DATA); + return CRYPT_RSA_ERR_PSS_SALT_DATA; + } + uint32_t hLen = hashMethod->mdSize; + ret = PssEncodeLengthCheck(keyBits, hLen, saltLen, dataLen, padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t keyBytes = BN_BITS_TO_BYTES(keyBits); + uint8_t *em = pad; + uint32_t emLen = keyBytes; + // the octet length of EM will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise + uint32_t msBit = ((keyBits - 1) & 0x7); + if (msBit == 0) { + emLen--; + *em = 0; + em++; + } + em[emLen - 1] = 0xbc; // EM = maskedDB || H || 0xbc. + + // set H + static const uint8_t zeros8[8] = {0}; + const CRYPT_Data hashData[] = { + {(uint8_t *)(uintptr_t)zeros8, sizeof(zeros8)}, + {(uint8_t *)(uintptr_t)data, dataLen}, // mHash + {(uint8_t *)(uintptr_t)salt, saltLen} // salt + }; + + const uint32_t maskedDBLen = emLen - hLen - 1; + uint8_t *h = em + maskedDBLen; + ret = CalcHash(hashMethod, hashData, sizeof(hashData) / sizeof(hashData[0]), h, hLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // set maskedDB + ret = Mgf(mgfMethod, h, hLen, em, maskedDBLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + MaskDB(em, maskedDBLen, salt, saltLen, msBit); + return CRYPT_SUCCESS; +} + +static int32_t GetVerifySaltLen(const uint8_t *emData, const uint8_t *dbBuff, uint32_t maskedDBLen, uint32_t msBit, + uint32_t *saltLen) +{ + uint32_t i = 0; + uint8_t *tmpBuff = (uint8_t *)BSL_SAL_Malloc(maskedDBLen); + if (tmpBuff == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void)memcpy_s(tmpBuff, maskedDBLen, dbBuff, maskedDBLen); + if (msBit != 0) { + tmpBuff[0] &= ((uint8_t)(0xFF >> (8 - msBit))); // Set the leftmost 8emLen - emBits bits to zero + } + + for (i = 0; i < maskedDBLen; i++) { + tmpBuff[i] ^= emData[i]; + if (tmpBuff[i] != 0) { + break; + } + } + if (i == maskedDBLen || tmpBuff[i] != 0x01) { + BSL_SAL_FREE(tmpBuff); + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_PSS_SALT_LEN); + return CRYPT_RSA_ERR_PSS_SALT_LEN; + } + i++; + BSL_SAL_FREE(tmpBuff); + *saltLen = maskedDBLen - i; + return CRYPT_SUCCESS; +} + +static int32_t GetAndVerifyDB(const EAL_MdMethod *mgfMethod, const CRYPT_Data *emData, + const CRYPT_Data *dbBuff, uint32_t *saltLen, uint32_t msBit) +{ + uint32_t maskedDBLen = dbBuff->len; + uint32_t hLen = emData->len - maskedDBLen - 1; + uint32_t tmpSaltLen = *saltLen; + const uint8_t *h = emData->data + maskedDBLen; + int32_t ret = Mgf(mgfMethod, h, hLen, dbBuff->data, dbBuff->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (tmpSaltLen == (uint32_t)SALTLEN_PSS_AUTOLEN_TYPE) { + ret = GetVerifySaltLen(emData->data, dbBuff->data, maskedDBLen, msBit, &tmpSaltLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + // A ^ B == C => A ^ C == B + MaskDB(dbBuff->data, dbBuff->len, h - tmpSaltLen, tmpSaltLen, msBit); + if (memcmp(dbBuff->data, emData->data, maskedDBLen - tmpSaltLen) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + *saltLen = tmpSaltLen; + return CRYPT_SUCCESS; +} + +static int32_t VerifyH(const EAL_MdMethod *hashMethod, const CRYPT_Data *mHash, const CRYPT_Data *salt, + const CRYPT_Data *h, const CRYPT_Data *hBuff) +{ + static const uint8_t zeros8[8] = {0}; + const CRYPT_Data hashData[] = { + {(uint8_t *)(uintptr_t)zeros8, sizeof(zeros8)}, + *mHash, + *salt + }; + + uint32_t hLen = hBuff->len; + int32_t ret = CalcHash(hashMethod, hashData, sizeof(hashData) / sizeof(hashData[0]), hBuff->data, hLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (memcmp(h->data, hBuff->data, hLen) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + return CRYPT_SUCCESS; +} + +// Reverse verification process of EMSA-PSS Encoding Operation: +// MGF(H,maskedDBLen) ^ MaskedDB => DB' (PS||0x01||salt'), H' = Hash(padding1 || mHash || salt') == H ? +int32_t CRYPT_RSA_VerifyPss(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, uint32_t keyBits, + uint32_t saltLen, const uint8_t *data, uint32_t dataLen, const uint8_t *pad, uint32_t padLen) +{ + if (hashMethod == NULL || mgfMethod == NULL || pad == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t hLen = hashMethod->mdSize; + int32_t ret = PssEncodeLengthCheck(keyBits, hLen, saltLen, dataLen, padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // EM = maskedDB || H || 0xbc + if (pad[padLen - 1] != 0xbc) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + + const uint8_t *em = pad; + uint32_t emLen = BN_BITS_TO_BYTES(keyBits); + // the octet length of EM will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise + uint32_t msBit = ((keyBits - 1) & 0x7); + if (msBit == 0) { + emLen--; + em++; + } + if ((pad[0] >> msBit) != 0) { + // if msBit == 0, 8emLen == emBits, pad[0] should be 0 + // the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB should be 0 + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + uint8_t *tmpBuff = BSL_SAL_Malloc(emLen); // for maskDB' / DB' and H' + if (tmpBuff == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + const uint32_t maskedDBLen = emLen - hLen - 1; + const CRYPT_Data dbBuff = {tmpBuff, maskedDBLen}; + const CRYPT_Data emData = {(uint8_t *)(uintptr_t)em, emLen}; + const CRYPT_Data mHash = {(uint8_t *)(uintptr_t)data, dataLen}; + const CRYPT_Data h = {(uint8_t *)(uintptr_t)&em[maskedDBLen], hLen}; + const CRYPT_Data hBuff = {&tmpBuff[maskedDBLen], hLen}; + ret = GetAndVerifyDB(mgfMethod, &emData, &dbBuff, &saltLen, msBit); + if (ret != CRYPT_SUCCESS) { + (void)memset_s(tmpBuff, emLen, 0, emLen); + BSL_SAL_FREE(tmpBuff); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + const CRYPT_Data salt = {&tmpBuff[maskedDBLen - saltLen], saltLen}; + ret = VerifyH(hashMethod, &mHash, &salt, &h, &hBuff); + (void)memset_s(tmpBuff, emLen, 0, emLen); + BSL_SAL_FREE(tmpBuff); + return ret; +} + +static int32_t PkcsSetLengthCheck(uint32_t emLen, uint32_t hashLen, uint32_t algIdentLen) +{ + if (emLen > RSA_MAX_MODULUS_LEN || hashLen > RSA_MAX_MODULUS_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + if (hashLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + /* The length of the pad must exceed 11 bytes at least. tLen = hashLen + algIdentLen */ + if (emLen < hashLen + algIdentLen + 11) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + return CRYPT_SUCCESS; +} + +static int32_t PkcsGetIdentifier(CRYPT_MD_AlgId hashId, CRYPT_Data *algIdentifier) +{ + static uint8_t sha1TInfo[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14}; + static uint8_t sha224TInfo[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}; + static uint8_t sha256TInfo[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; + static uint8_t sha384TInfo[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; + static uint8_t sha512TInfo[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; + static uint8_t md5TInfo[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; + static uint8_t sm3TInfo[] = {0x30, 0x30, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, + 0x83, 0x11, 0x05, 0x00, 0x04, 0x20}; + algIdentifier->data = NULL; + algIdentifier->len = 0; + + if (hashId == CRYPT_MD_SHA1) { + algIdentifier->data = (uint8_t *)sha1TInfo; + algIdentifier->len = sizeof(sha1TInfo); + } else if (hashId == CRYPT_MD_SHA224) { + algIdentifier->data = (uint8_t *)sha224TInfo; + algIdentifier->len = sizeof(sha224TInfo); + } else if (hashId == CRYPT_MD_SHA256) { + algIdentifier->data = (uint8_t *)sha256TInfo; + algIdentifier->len = sizeof(sha256TInfo); + } else if (hashId == CRYPT_MD_SHA384) { + algIdentifier->data = (uint8_t *)sha384TInfo; + algIdentifier->len = sizeof(sha384TInfo); + } else if (hashId == CRYPT_MD_SHA512) { + algIdentifier->data = (uint8_t *)sha512TInfo; + algIdentifier->len = sizeof(sha512TInfo); + } else if (hashId == CRYPT_MD_MD5) { + algIdentifier->data = (uint8_t *)md5TInfo; + algIdentifier->len = sizeof(md5TInfo); + } else if (hashId == CRYPT_MD_SM3) { + algIdentifier->data = (uint8_t *)sm3TInfo; + algIdentifier->len = sizeof(sm3TInfo); + } else { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_MD_ALGID); + return CRYPT_RSA_ERR_MD_ALGID; + } + return CRYPT_SUCCESS; +} + +// Pad output format:EM = 00 || 01 || PS || 00 || T; where T = algIdentifier || hash(M); +// hash(M) is the input parameter data of this function. +int32_t CRYPT_RSA_SetPkcsV15Type1(CRYPT_MD_AlgId hashId, const uint8_t *data, uint32_t dataLen, + uint8_t *pad, uint32_t padLen) +{ + int32_t ret; + uint32_t padSize; + uint8_t *tmp = pad; + uint32_t tmpLen = padLen; + if (pad == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + CRYPT_Data algIdentifier = {NULL, 0}; + ret = PkcsGetIdentifier(hashId, &algIdentifier); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = PkcsSetLengthCheck(padLen, dataLen, algIdentifier.len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + // Considering that the data space and pad space may overlap, + // move the data to the specified position(the end of the pad). + if (memmove_s(pad + (padLen - dataLen), dataLen, data, dataLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + *tmp = 0x0; + tmp++; + *tmp = 0x1; + tmp++; + tmpLen -= 2; // Skip the first 2 bytes. + + // PS length: padSize = padLen - dataLen - algIdentifier.len - 3 + padSize = padLen - dataLen - algIdentifier.len - 3; + if (memset_s(tmp, tmpLen, 0xff, padSize) != EOK) { // 0xff padded in PS + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + tmp += padSize; + tmpLen -= padSize; + + *tmp = 0x0; + tmp++; + tmpLen--; + + if ((algIdentifier.len > 0) && memcpy_s(tmp, tmpLen, algIdentifier.data, algIdentifier.len) != EOK) { + // padding when identifier exit + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_VerifyPkcsV15Type1(CRYPT_MD_AlgId hashId, const uint8_t *pad, uint32_t padLen, + const uint8_t *data, uint32_t dataLen) +{ + if (pad == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (padLen == 0 || dataLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + + uint8_t *padBuff = BSL_SAL_Malloc(padLen); + if (padBuff == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + int32_t ret = CRYPT_RSA_SetPkcsV15Type1(hashId, data, dataLen, padBuff, padLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(padBuff); + return ret; + } + + if (memcmp(pad, padBuff, padLen) != 0) { + BSL_SAL_FREE(padBuff); + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + BSL_SAL_FREE(padBuff); + return CRYPT_SUCCESS; +} + +static int32_t OaepSetLengthCheck(uint32_t outLen, uint32_t inLen, uint32_t hashLen) +{ + if (outLen > RSA_MAX_MODULUS_LEN || inLen > RSA_MAX_MODULUS_LEN || hashLen > HASH_MAX_MDSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + if (outLen == 0 || hashLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + // If mLen > k - 2hLen - 2, output "message too long" and stop. + if (inLen + 2 * hashLen + 2 > outLen) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_ENC_BITS); + return CRYPT_RSA_ERR_ENC_BITS; + } + return CRYPT_SUCCESS; +} + +static int32_t OaepSetPs(const uint8_t *in, uint32_t inLen, uint8_t *db, uint32_t padLen, uint32_t hashLen) +{ + uint8_t *ps = db + hashLen; + // Generate a padding string PS consisting of k - mLen - 2hLen - 2 zero octets. The length of PS may be zero + // This operation cannot be reversed because the OaepSetLengthCheck has checked the validity of the data. + uint32_t psLen = padLen - inLen - 2 * hashLen - 2; + // padding 0x00 + (void)memset_s(ps, psLen, 0, psLen); + ps += psLen; + *ps = 0x01; + ps++; + /** + * padLen minus twice hashLen, then subtract 2 bytes of fixed data, and subtract the padding length. + * The remaining length is the plaintext length. + */ + if (inLen != 0 && memcpy_s(ps, padLen - 2 * hashLen - 2 - psLen, in, inLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + return CRYPT_SUCCESS; +} + +static int32_t OaepSetMaskedDB(const EAL_MdMethod *mgfMethod, uint8_t *db, uint8_t *seed, uint32_t padLen, + uint32_t hashLen) +{ + int32_t ret; + uint32_t i; + uint32_t maskedDBLen = padLen - hashLen - 1; + uint8_t *maskedDB = (uint8_t *)BSL_SAL_Malloc(maskedDBLen); + if (maskedDB == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + ret = Mgf(mgfMethod, seed, hashLen, maskedDB, maskedDBLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + for (i = 0; i < maskedDBLen; i++) { + db[i] ^= maskedDB[i]; + } +END: + BSL_SAL_CleanseData(maskedDB, maskedDBLen); + BSL_SAL_FREE(maskedDB); + return ret; +} + +static int32_t OaepSetSeedMask(const EAL_MdMethod *mgfMethod, uint8_t *db, uint8_t *seed, uint32_t padLen, + uint32_t hashLen) +{ + uint32_t i; + int32_t ret; + uint8_t seedmask[HASH_MAX_MDSIZE]; + uint32_t maskedDBLen = padLen - hashLen - 1; + + ret = Mgf(mgfMethod, db, maskedDBLen, seedmask, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto END; + } + for (i = 0; i < hashLen; i++) { + seed[i] ^= seedmask[i]; + } +END: + BSL_SAL_CleanseData(seedmask, hashLen); + return ret; +} + +/** +* _________________________________________________________________ +* +* +----------+------+--+-------+ +* DB = | lHash | PS |01| M | +* +----------+------+--+-------+ +* | +* +----------+ | +* | seed | | +* +----------+ | +* | | +* |-------> MGF ---> xor +* | | +* +--+ V | +* |00| xor <----- MGF <-----| +* +--+ | | +* | | | +* V V V +* +--+----------+----------------------------+ +* EM = |00|maskedSeed| maskedDB | +* +--+----------+----------------------------+ +* _________________________________________________________________ +* +* Figure 1: EME-OAEP Encoding Operation +*/ +int32_t CRYPT_RSA_SetPkcs1Oaep(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, const uint8_t *in, + uint32_t inLen, const uint8_t *param, uint32_t paramLen, uint8_t *pad, uint32_t padLen) +{ + int32_t ret; + + if (hashMethod == NULL || mgfMethod == NULL || (in == NULL && inLen != 0) || pad == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + uint32_t hashLen = hashMethod->mdSize; + + /* If mLen > k - 2hLen - 2, output "message too long" and stop + k is output len, hLen is hashLen, mLen is inLen + */ + ret = OaepSetLengthCheck(padLen, inLen, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + *pad = 0x00; + uint8_t *seed = pad + 1; + // Generate a random octet string seed of length hLen + ret = CRYPT_Rand(seed, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint8_t *db = seed + hashLen; + + // Calculate hash + CRYPT_Data data = {(uint8_t *)(uintptr_t)param, paramLen}; + ret = CalcHash(hashMethod, &data, 1, db, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = OaepSetPs(in, inLen, db, padLen, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // set maskedDB + ret = OaepSetMaskedDB(mgfMethod, db, seed, padLen, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // set seedmask + ret = OaepSetSeedMask(mgfMethod, db, seed, padLen, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return ret; +} + +static int32_t OaepVerifyLengthCheck(uint32_t outLen, uint32_t inLen, uint32_t hashLen) +{ + if (outLen > RSA_MAX_MODULUS_LEN || inLen > RSA_MAX_MODULUS_LEN || hashLen > HASH_MAX_MDSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + if (outLen == 0 || hashLen == 0 || inLen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + // If k < 2hLen + 2, output "decryption error" and stop + if (inLen < 2 * hashLen + 2) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + return CRYPT_SUCCESS; +} + +static int32_t OaepDecodeSeedMask(const EAL_MdMethod *mgfMethod, const uint8_t *in, uint32_t inLen, + CRYPT_Data *seedMask, uint32_t hashLen) +{ + uint32_t i; + int32_t ret; + + const uint8_t *maskedSeed = in + 1; + uint32_t maskedDBLen = inLen - hashLen - 1; + const uint8_t *maskedDB = maskedSeed + hashLen; + + ret = Mgf(mgfMethod, maskedDB, maskedDBLen, seedMask->data, hashLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + for (i = 0; i < hashLen; i++) { + seedMask->data[i] ^= maskedSeed[i]; + } + return CRYPT_SUCCESS; +} + +static int32_t OaepDecodeMaskedDB(const EAL_MdMethod *mgfMethod, const CRYPT_Data *in, const uint8_t *seedMask, + uint32_t hashLen, const CRYPT_Data *dbMaskData) +{ + int32_t ret; + uint32_t i; + const uint8_t *maskedDB = in->data + 1 + hashLen; + uint32_t maskedDBLen = in->len - hashLen - 1; + + ret = Mgf(mgfMethod, seedMask, hashLen, dbMaskData->data, maskedDBLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + for (i = 0; i < maskedDBLen; i++) { + dbMaskData->data[i] ^= maskedDB[i]; + } + + return ret; +} + +static int32_t OaepVerifyHashMaskDB(const EAL_MdMethod *hashMethod, CRYPT_Data *paramData, CRYPT_Data *dbMaskData, + uint32_t hashLen, uint32_t *offset) +{ + int32_t ret; + uint8_t hashVal[HASH_MAX_MDSIZE]; + ret = CalcHash(hashMethod, paramData, 1, hashVal, hashLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (memcmp(dbMaskData->data, hashVal, hashLen) != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + + *offset = hashLen; + while ((*offset) < dbMaskData->len && dbMaskData->data[(*offset)] == 0) { + (*offset)++; + } + if ((*offset) >= dbMaskData->len) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + + if (dbMaskData->data[(*offset)] != 0x01) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + + (*offset)++; + return ret; +} + +int32_t CRYPT_RSA_VerifyPkcs1Oaep(const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, const uint8_t *in, + uint32_t inLen, const uint8_t *param, uint32_t paramLen, uint8_t *msg, uint32_t *msgLen) +{ + if (hashMethod == NULL || mgfMethod == NULL || in == NULL || msg == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t hashLen = hashMethod->mdSize; + if (inLen <= (hashLen + 1)) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE); + return CRYPT_RSA_ERR_INPUT_VALUE; + } + uint32_t maskedDBLen = inLen - hashLen - 1; + int32_t ret; + uint32_t offset; + uint8_t seedMask[HASH_MAX_MDSIZE]; + CRYPT_Data seedData = { (uint8_t *)(uintptr_t)seedMask, HASH_MAX_MDSIZE }; + CRYPT_Data paramData = { (uint8_t *)(uintptr_t)param, paramLen }; + CRYPT_Data inData = { (uint8_t *)(uintptr_t)in, inLen }; + uint8_t *maskDB = (uint8_t *)BSL_SAL_Malloc(maskedDBLen); + if (maskDB == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + CRYPT_Data dbMaskData = { maskDB, maskedDBLen }; + + /* If k < 2hLen + 2, output "decryption error" and stop. + k is intLen , hLen is hashLen + */ + GOTO_ERR_IF_EX(OaepVerifyLengthCheck(*msgLen, inLen, hashLen), ret); + + GOTO_ERR_IF_EX(OaepDecodeSeedMask(mgfMethod, in, inLen, &seedData, hashLen), ret); + + GOTO_ERR_IF_EX(OaepDecodeMaskedDB(mgfMethod, &inData, seedMask, hashLen, &dbMaskData), ret); + + GOTO_ERR_IF_EX(OaepVerifyHashMaskDB(hashMethod, ¶mData, &dbMaskData, hashLen, &offset), ret); + + if (memcpy_s(msg, *msgLen, maskDB + offset, maskedDBLen - offset) != EOK) { + ret = CRYPT_RSA_NOR_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + *msgLen = maskedDBLen - offset; +ERR: + BSL_SAL_CleanseData(maskDB, maskedDBLen); + BSL_SAL_FREE(maskDB); + return ret; +} + +// Pad output format: EM = 00 || 02 || PS || 00 || M; where M indicates message. +int32_t CRYPT_RSA_SetPkcsV15Type2(const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t outLen) +{ + // If mLen > k - 11, output "message too long" and stop. + if (inLen + 11 > outLen) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + return CRYPT_RSA_BUFF_LEN_NOT_ENOUGH; + } + + int32_t ret; + uint32_t i; + uint8_t *ps = out + 2; + uint32_t psLen = outLen - inLen - 3; + uint8_t *msg = out + psLen + 3; + + *out = 0x00; + *(out + 1) = 0x02; + *(out + outLen - inLen - 2) = 0x00; + // msg padding, outLen minus the 3-byte constant, ps length, and start padding. + if (inLen != 0 && memcpy_s(msg, outLen - (psLen + 3), in, inLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + + // cal ps + ret = CRYPT_Rand(ps, psLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ps[psLen] = 0; + for (i = 0; i < psLen; i++) { + if (*(ps + i) != 0) { + continue; + } + do { + // no zero + ret = CRYPT_Rand(ps + i, 1); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } while (*(ps + i) == 0); + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_RSA_VerifyPkcsV15Type2(const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + uint32_t i; + uint32_t zeroIndex = 0; + uint32_t index = ~(0); + uint32_t equals0; + uint32_t firstZero = Uint32ConstTimeEqual(in[0], 0x00); + uint32_t firstTwo = Uint32ConstTimeEqual(in[1], 0x02); + // Check the ps starting from subscript 2. + for (i = 2; i < inLen; i++) { + equals0 = Uint32ConstTimeIsZero(in[i]); + zeroIndex = Uint32ConstTimeSelect(index & equals0, i, zeroIndex); + index = Uint32ConstTimeSelect(equals0, 0, index); + } + + uint32_t valid = firstZero; + valid &= firstTwo; + + valid &= ~index; + // Pad output format: EM = 00 || 02 || PS || 00 || M; where M is a message, and PS must be >= 8. + // Therefore, the subscript of the second 0 must be greater than or equal to 10. + valid &= Uint32ConstTimeGt(zeroIndex, 10); + + zeroIndex++; + if (valid == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + + if (inLen - zeroIndex > *outLen) { + BSL_ERR_PUSH_ERROR(CRYPT_RSA_NOR_VERIFY_FAIL); + return CRYPT_RSA_NOR_VERIFY_FAIL; + } + + (void)memcpy_s(out, *outLen, in + zeroIndex, inLen - zeroIndex); + *outLen = inLen - zeroIndex; + + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_RSA diff --git a/crypto/scrypt/include/crypt_scrypt.h b/crypto/scrypt/include/crypt_scrypt.h new file mode 100644 index 00000000..5929ebae --- /dev/null +++ b/crypto/scrypt/include/crypt_scrypt.h @@ -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. + */ + +#ifndef CRYPT_SCRYPT_H +#define CRYPT_SCRYPT_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SCRYPT + +#include +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef int32_t (*PBKDF2_PRF)(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, + const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, + uint32_t iterCnt, uint8_t *out, uint32_t len); + +/** + * @brief scrypt Password-based key derivation function + * + * @param pbkdf2Prf [IN] pbkdf2 function pointer. + * @param macMeth [IN] HMAC algorithm method. Only the HMAC method is supported. + * @param mdMeth [IN] md algorithm method + * @param key [IN] Password, a string entered by the user. + * @param keyLen [IN] Password length, which can be any length, including 0. + * @param salt [IN] Salt value, a string entered by the user. + * @param saltLen [IN] Salt value length, which can be any length, including 0. + * @param n [IN] CPU and memory consumption parameters. The value must be a power of 2, between 1 and 2 ^ (128 * r / 8) + * @param r [IN] Block size parameter, which can be any positive integer except 0, where r * p < 2 ^ 30 + * @param p [IN] Parallelization parameter, which can be any positive integer but 0. p <= (2 ^ 32 - 1) * 32 / (128 * r) + * @param out [OUT] Derived key, which cannot be empty. + * @param len [IN] Length of the derived key. Range: (0, 0xFFFFFFFF] + * + * @return Success: CRYPT_SUCCESS + * For other error codes, see crypt_errno.h + */ +int32_t CRYPT_SCRYPT(PBKDF2_PRF pbkdf2Prf, const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, + const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint32_t n, + uint32_t r, uint32_t p, uint8_t *out, uint32_t len); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HITLS_CRYPTO_SCRYPT + +#endif // CRYPT_SCRYPT_H diff --git a/crypto/scrypt/src/scrypt.c b/crypto/scrypt/src/scrypt.c new file mode 100644 index 00000000..adf2e1f2 --- /dev/null +++ b/crypto/scrypt/src/scrypt.c @@ -0,0 +1,285 @@ +/* + * 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_SCRYPT + +#include +#include "securec.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt_local_types.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_types.h" +#include "crypt_scrypt.h" + + +#define SCRYPT_PR_MAX ((1 << 30) - 1) + +// Convert the little-endian array to the host order. +#define SALSA_INPUT_TO_HOST(T, x) \ +do { \ + (x)[0] = CRYPT_LE32TOH((T)[0]); \ + (x)[1] = CRYPT_LE32TOH((T)[1]); \ + (x)[2] = CRYPT_LE32TOH((T)[2]); \ + (x)[3] = CRYPT_LE32TOH((T)[3]); \ + (x)[4] = CRYPT_LE32TOH((T)[4]); \ + (x)[5] = CRYPT_LE32TOH((T)[5]); \ + (x)[6] = CRYPT_LE32TOH((T)[6]); \ + (x)[7] = CRYPT_LE32TOH((T)[7]); \ + (x)[8] = CRYPT_LE32TOH((T)[8]); \ + (x)[9] = CRYPT_LE32TOH((T)[9]); \ + (x)[10] = CRYPT_LE32TOH((T)[10]); \ + (x)[11] = CRYPT_LE32TOH((T)[11]); \ + (x)[12] = CRYPT_LE32TOH((T)[12]); \ + (x)[13] = CRYPT_LE32TOH((T)[13]); \ + (x)[14] = CRYPT_LE32TOH((T)[14]); \ + (x)[15] = CRYPT_LE32TOH((T)[15]); \ +} while (0) + +// Convert the host order to little endian order. +#define SALSA_OUTPUT_TO_LE32(T, x) \ +do { \ + (T)[0] = CRYPT_HTOLE32((x)[0] + CRYPT_LE32TOH((T)[0])); \ + (T)[1] = CRYPT_HTOLE32((x)[1] + CRYPT_LE32TOH((T)[1])); \ + (T)[2] = CRYPT_HTOLE32((x)[2] + CRYPT_LE32TOH((T)[2])); \ + (T)[3] = CRYPT_HTOLE32((x)[3] + CRYPT_LE32TOH((T)[3])); \ + (T)[4] = CRYPT_HTOLE32((x)[4] + CRYPT_LE32TOH((T)[4])); \ + (T)[5] = CRYPT_HTOLE32((x)[5] + CRYPT_LE32TOH((T)[5])); \ + (T)[6] = CRYPT_HTOLE32((x)[6] + CRYPT_LE32TOH((T)[6])); \ + (T)[7] = CRYPT_HTOLE32((x)[7] + CRYPT_LE32TOH((T)[7])); \ + (T)[8] = CRYPT_HTOLE32((x)[8] + CRYPT_LE32TOH((T)[8])); \ + (T)[9] = CRYPT_HTOLE32((x)[9] + CRYPT_LE32TOH((T)[9])); \ + (T)[10] = CRYPT_HTOLE32((x)[10] + CRYPT_LE32TOH((T)[10])); \ + (T)[11] = CRYPT_HTOLE32((x)[11] + CRYPT_LE32TOH((T)[11])); \ + (T)[12] = CRYPT_HTOLE32((x)[12] + CRYPT_LE32TOH((T)[12])); \ + (T)[13] = CRYPT_HTOLE32((x)[13] + CRYPT_LE32TOH((T)[13])); \ + (T)[14] = CRYPT_HTOLE32((x)[14] + CRYPT_LE32TOH((T)[14])); \ + (T)[15] = CRYPT_HTOLE32((x)[15] + CRYPT_LE32TOH((T)[15])); \ +} while (0) + +#define SCRYPT_ELEMENTSIZE 64 + +/* This function is implemented by referring to the RFC standard. + For details, see section 3 in https://www.rfc-editor.org/rfc/rfc7914.txt */ +static void SCRYPT_Salsa20WordSpecification(uint32_t t[16]) +{ + uint32_t x[16]; + + SALSA_INPUT_TO_HOST(t, x); + + for (int i = 0; i < 4; i++) { + x[4] ^= ROTL32(x[0] + x[12], 7); + x[8] ^= ROTL32(x[4] + x[0], 9); + x[12] ^= ROTL32(x[8] + x[4], 13); + x[0] ^= ROTL32(x[12] + x[8], 18); + x[9] ^= ROTL32(x[5] + x[1], 7); + x[13] ^= ROTL32(x[9] + x[5], 9); + x[1] ^= ROTL32(x[13] + x[9], 13); + x[5] ^= ROTL32(x[1] + x[13], 18); + x[14] ^= ROTL32(x[10] + x[6], 7); + x[2] ^= ROTL32(x[14] + x[10], 9); + x[6] ^= ROTL32(x[2] + x[14], 13); + x[10] ^= ROTL32(x[6] + x[2], 18); + x[3] ^= ROTL32(x[15] + x[11], 7); + x[7] ^= ROTL32(x[3] + x[15], 9); + x[11] ^= ROTL32(x[7] + x[3], 13); + x[15] ^= ROTL32(x[11] + x[7], 18); + x[1] ^= ROTL32(x[0] + x[3], 7); + x[2] ^= ROTL32(x[1] + x[0], 9); + x[3] ^= ROTL32(x[2] + x[1], 13); + x[0] ^= ROTL32(x[3] + x[2], 18); + x[6] ^= ROTL32(x[5] + x[4], 7); + x[7] ^= ROTL32(x[6] + x[5], 9); + x[4] ^= ROTL32(x[7] + x[6], 13); + x[5] ^= ROTL32(x[4] + x[7], 18); + x[11] ^= ROTL32(x[10] + x[9], 7); + x[8] ^= ROTL32(x[11] + x[10], 9); + x[9] ^= ROTL32(x[8] + x[11], 13); + x[10] ^= ROTL32(x[9] + x[8], 18); + x[12] ^= ROTL32(x[15] + x[14], 7); + x[13] ^= ROTL32(x[12] + x[15], 9); + x[14] ^= ROTL32(x[13] + x[12], 13); + x[15] ^= ROTL32(x[14] + x[13], 18); + } + SALSA_OUTPUT_TO_LE32(t, x); +} + +static void SCRYPT_BlockMix(uint8_t *b, uint8_t *y, uint32_t r) +{ + uint8_t *bTmp = b; + uint8_t *y0 = y; + uint8_t *y1 = y + (r << 6); + + /* RFC7914 section 4 + In this implementation, the output Y is split and processed separately based on the description in section 4. + The performance is slightly improved. + 1. B' = Y, Y0 = Y, Y1 = Y[r], b=B, + The block size of each Y is 64 bytes. The processing unit in this function is 64 bytes. + 2. Y0 = B[2 * r - 1] ^ B[0] + Salsa(Y0) + Y1 = Y0 ^ B[1] + Salsa(Y1) + 3. for i = 1 to r -1 do + b += 2 // Two blocks have been processed in step 2. + Y0 += 1 // Process the next block of Y0. + Y0 = b[0] ^ Y1 + Salsa(Y0) + Y1 += 1 + Y1 = b[1] ^ Y0 + Salsa(Y1) + 4. B = Y // Copy Y to B. + */ + + // r << 7 is equal to r * 128, where r * 128 is the block size of the algorithm. + DATA32_XOR(b + (r << 7) - SCRYPT_ELEMENTSIZE, bTmp, y0, SCRYPT_ELEMENTSIZE); + SCRYPT_Salsa20WordSpecification((uint32_t*)y0); + DATA32_XOR(y0, bTmp + SCRYPT_ELEMENTSIZE, y1, SCRYPT_ELEMENTSIZE); + SCRYPT_Salsa20WordSpecification((uint32_t*)y1); + + for (uint32_t i = 1; i < r; i++) { + bTmp += 128; // Process two pieces of 64-bit(SCRYPT_ELEMENTSIZE) data in one cycle. 64 * 2 = 128 + + y0 += SCRYPT_ELEMENTSIZE; + DATA32_XOR(y1, bTmp, y0, SCRYPT_ELEMENTSIZE); + SCRYPT_Salsa20WordSpecification((uint32_t*)y0); + + y1 += SCRYPT_ELEMENTSIZE; + DATA32_XOR(y0, bTmp + SCRYPT_ELEMENTSIZE, y1, SCRYPT_ELEMENTSIZE); + SCRYPT_Salsa20WordSpecification((uint32_t*)y1); + } + + (void)memcpy_s(b, r << 7, y, r << 7); // Length bit r of B and y: r << 7 +} + +/* For details about this function, see section 5 in RFC7914 */ +static void SCRYPT_ROMix(uint8_t *b, uint32_t n, uint32_t r, uint8_t *v, uint8_t *y) +{ + uint32_t i; + uint8_t *tmp = NULL; + uint32_t blockSize = r << 7; + + for (i = 0, tmp = v; i < n; i++, tmp += blockSize) { + (void)memcpy_s(tmp, blockSize, b, blockSize); + SCRYPT_BlockMix(b, y, r); + } + + for (i = 0; i < n; i++) { + uint32_t j = GET_UINT32_LE(b, blockSize - 64) & (n - 1); + + // X= B, X = X ^ Vj + DATA32_XOR(b, &v[j * blockSize], b, blockSize); + SCRYPT_BlockMix(b, y, r); + } +} + +static int32_t SCRYPT_CheckParam(uint32_t n, uint32_t r, uint32_t p, const uint8_t *out, uint32_t len) +{ + if (r == 0 || p == 0 || n <= 1 || ((n & (n - 1)) != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_SCRYPT_PARAM_ERROR); + return CRYPT_SCRYPT_PARAM_ERROR; + } + if (p > SCRYPT_PR_MAX / r) { + BSL_ERR_PUSH_ERROR(CRYPT_SCRYPT_PARAM_ERROR); + return CRYPT_SCRYPT_PARAM_ERROR; + } + /* r <= 3 indicates 16 * r < (sizeof(uint64_t) * 8 - 1) */ + if ((r <= 3) && (n >= (((uint64_t)1) << (16 * r)))) { + BSL_ERR_PUSH_ERROR(CRYPT_SCRYPT_PARAM_ERROR); + return CRYPT_SCRYPT_PARAM_ERROR; + } + /* (p * 128 * r < UINT32_MAX) && (32 * r * n * sizeof(uint32_t)) */ + if ((r > ((UINT32_MAX / 128) / p)) || (n > ((UINT32_MAX / 128) / r))) { + BSL_ERR_PUSH_ERROR(CRYPT_SCRYPT_PARAM_ERROR); + return CRYPT_SCRYPT_PARAM_ERROR; + } + if (out == NULL || len == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SCRYPT_PARAM_ERROR); + return CRYPT_SCRYPT_PARAM_ERROR; + } + + return CRYPT_SUCCESS; +} + +static int32_t SCRYPT_CheckPointer(PBKDF2_PRF pbkdf2Prf, const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen) +{ + if (pbkdf2Prf == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (key == NULL && keyLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (salt == NULL && saltLen > 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return CRYPT_SUCCESS; +} + +/* For details about this function, see section 6 in RFC7914. */ +int32_t CRYPT_SCRYPT(PBKDF2_PRF pbkdf2Prf, const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, + const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint32_t n, + uint32_t r, uint32_t p, uint8_t *out, uint32_t len) +{ + int32_t ret; + // V in ROMix and BlockMix is allocated here, reducing memory application and release costs + uint8_t *b = NULL, *v = NULL, *bi = NULL, *y = NULL; + uint32_t bLen, blockSize, sumLen; + + if ((ret = SCRYPT_CheckParam(n, r, p, out, len)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if ((ret = SCRYPT_CheckPointer(pbkdf2Prf, key, keyLen, salt, saltLen)) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + blockSize = r << 7; // block length: r << 7 (r * 128) + bLen = blockSize * p; + + sumLen = bLen + blockSize * n + blockSize; + if (sumLen < bLen) { + BSL_ERR_PUSH_ERROR(CRYPT_SCRYPT_DATA_TOO_MAX); + return CRYPT_SCRYPT_DATA_TOO_MAX; + } + b = BSL_SAL_Malloc(sumLen); + if (b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + + v = b + bLen; + y = v + blockSize * n; + + GOTO_ERR_IF(pbkdf2Prf(macMeth, mdMeth, key, keyLen, salt, saltLen, 1, b, bLen), ret); + + bi = b; + for (uint32_t i = 0; i < p; i++, bi += blockSize) { + SCRYPT_ROMix(bi, n, r, v, y); + } + + GOTO_ERR_IF(pbkdf2Prf(macMeth, mdMeth, key, keyLen, b, bLen, 1, out, len), ret); + +ERR: + BSL_SAL_FREE(b); + + return ret; +} +#endif /* HITLS_CRYPTO_SCRYPT */ diff --git a/crypto/sha1/include/crypt_sha1.h b/crypto/sha1/include/crypt_sha1.h new file mode 100644 index 00000000..8a7b2f75 --- /dev/null +++ b/crypto/sha1/include/crypt_sha1.h @@ -0,0 +1,99 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_SHA1_H +#define CRYPT_SHA1_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SHA1 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/* Length of the message digest buffer. */ +#define CRYPT_SHA1_DIGESTSIZE 20 + +/* Message processing block size */ +#define CRYPT_SHA1_BLOCKSIZE 64 + +/* SHA-1 context structure */ +typedef struct { + uint8_t m[CRYPT_SHA1_BLOCKSIZE]; /* store the remaining data which less than one block */ + uint32_t h[CRYPT_SHA1_DIGESTSIZE / sizeof(uint32_t)]; /* store the intermediate data of the hash value */ + uint32_t hNum, lNum; /* input data counter, maximum value 2 ^ 64 bits */ + int32_t errorCode; /* Error code */ + uint32_t count; /* Number of remaining data bytes less than one block, corresponding to the length of the m */ +} CRYPT_SHA1_Ctx; + +/** + * @ingroup SHA1 + * @brief This API is invoked to initialize the SHA-1 context. + * + * @param *ctx [in,out] Pointer to the SHA-1 context. + * + * @retval #CRYPT_SUCCESS initialization succeeded. + * @retval #CRYPT_NULL_INPUT Pointer ctx is NULL + */ +int32_t CRYPT_SHA1_Init(CRYPT_SHA1_Ctx *ctx); + +/** + * @ingroup SHA1 + * @brief Encode the input text and update the message digest. + * + * @param *ctx [in,out] Pointer to the SHA-1 context. + * @param *in [in] Pointer to the data to be calculated + * @param len [in] Length of the data to be calculated + * + * @retval #CRYPT_SUCCESS succeeded in updating the internal status of the digest. + * @retval #CRYPT_NULL_INPUT The input parameter is NULL. + * @retval #CRYPT_SHA1_ERR_OVERFLOW input data length exceeds the maximum (2^64 bits) + */ +int32_t CRYPT_SHA1_Update(CRYPT_SHA1_Ctx *ctx, const uint8_t *in, uint32_t len); + +/** + * @ingroup SHA1 + * @brief Obtain the message digest based on the passed SHA-1 text. + * + * @param *ctx [in,out] Pointer to the SHA-1 context. + * @param *out [in] Digest buffer + * @param *len [in,out] Digest buffer size + * + * @retval #CRYPT_SUCCESS succeeded in obtaining the computed digest. + * @retval #CRYPT_NULL_INPUT The input parameter is NULL. + * @retval #CRYPT_SHA1_ERR_OVERFLOW Input data length exceeds the maximum (2^64 bits). + * @retval #CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH The output buffer is insufficient. + */ +int32_t CRYPT_SHA1_Final(CRYPT_SHA1_Ctx *ctx, uint8_t *out, uint32_t *len); + +/** + * @ingroup SHA1 + * @brief SHA1 deinitialization API + * @param *ctx [in,out] Pointer to the SHA-1 context. + */ +void CRYPT_SHA1_Deinit(CRYPT_SHA1_Ctx *ctx); + +int32_t CRYPT_SHA1_CopyCtx(CRYPT_SHA1_Ctx *dst, CRYPT_SHA1_Ctx *src); + +#ifdef __cplusplus +} +#endif /* __cpluscplus */ + +#endif // HITLS_CRYPTO_SHA1 + +#endif // CRYPT_SHA1_H diff --git a/crypto/sha1/src/asm/sha1_armv8.S b/crypto/sha1/src/asm/sha1_armv8.S new file mode 100644 index 00000000..e6a2905e --- /dev/null +++ b/crypto/sha1/src/asm/sha1_armv8.S @@ -0,0 +1,645 @@ +/* + * 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_SHA1 + +#include "crypt_arm.h" + +.arch armv8-a+crypto + +/* SHA1 used constant value. For the data source, see the RFC3174 document. + * K(t) = 5A827999 ( 0 <= t <= 19) + * K(t) = 6ED9EBA1 (20 <= t <= 39) + * K(t) = 8F1BBCDC (40 <= t <= 59) + * K(t) = CA62C1D6 (60 <= t <= 79) + */ +.data +.balign 64 // Alignment based on the size of the read data block +.type g_k, %object +g_k: + .long 0x5a827999 + .long 0x6ed9eba1 + .long 0x8f1bbcdc + .long 0xca62c1d6 +.size g_k, .-g_k + +.balign 64 // Alignment based on the size of the read data block +.type g_kExt, %object +g_kExt: + .long 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999 //K_00_19 + .long 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1 //K_20_39 + .long 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc //K_40_59 + .long 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 //K_60_79 +.size g_kExt, .-g_kExt + +/** + * Macro Description: 32位Message block扩展Wi + * input register: + * wi_3: W[i-3] + * wi_8: W[i-8] + * wi_14: W[i-14] + * wi_16: W[i-16] + * temp1: temporary register + * temp2: temporary register + * Modify the register: wi_16 temp1 temp2 + * Output register: + * wi_16: Latest W[i] value, W(i) = S^1(W(i-3) XOR W(i-8) XOR W(i-14) XOR W(i-16)) + * Function/Macro Call: NONE + */ +.macro MESSAGE_EXPAND wi_16, wi_14, wi_8, wi_3, temp1, temp2 + eor \temp1, \wi_14, \wi_16 // W(i-14) XOR W(i-16) + eor \temp2, \wi_3, \wi_8 // W(i-3) XOR W(i-8) + eor \wi_16, \temp1, \temp2 // W(i-3) XOR W(i-8) XOR W(i-14) XOR W(i-16) + ror \wi_16, \wi_16, #31 // Cyclic left shift 1 equals cyclic right shift 31 +.endm + +/** + * Macro Description: b、e Compute + * input register: + * k: Constant data + * wi: Message block + * a、b、e: Intermediate variable of hash value + * f: f(B, C, D) + * temp1-4: temporary register + * Modify the register: b e temp3-temp4 + * Output register: + * b: Indicates the value after a cyclic update. + * e: Indicates the value after a cyclic update. + * Macro implementation: + * e = S^5(A) + f(B, C, D) + E + W(i) + K(i) + * b = S^30(B) + * Function/Macro Call: NONE + */ +.macro CAL_B_E a, b, e, wi, k, f, temp3, temp4 + add \temp3, \wi, \k // W(i) + K(i) + ror \temp4, \a, #27 // S^5(A) Cyclic shift left 5 equal Cyclic shift right 27 + + ror \b, \b, #2 // b = S^30(B) Cyclic shift left 30 equal Cyclic shift right 2 + add \temp4, \temp4, \temp3 // S^5(A) + W(i) + K(i) + add \e, \e, \f // f(B, C, D) + E + add \e, \e, \temp4 // f(B, C, D) + E + S^5(A) + W(i) + K(i) +.endm + +/** + * Macro Description: Message compression,0~19round data compression + * input register: + * k: Constant data + * wi: Message block + * a - h: Intermediate variable of hash value + * temp1-4: temporary register + * Modify the register: b e temp1-temp4 + * Output register: + * b: Indicates the value after a cyclic update. + * e: Indicates the value after a cyclic update. + * Macro implementation: f(B, C, D) = (B AND C) OR ((NOT B) AND D) + * e = S^5(A) + f(B, C, D) + E + W(i) + K(i) + * b = S^30(B) + * Function/Macro Call: CAL_B_E + */ +.macro DATA_COMPRE_0_19 a, b, c, d, e, wi, k, temp1, temp2, temp3, temp4 + and \temp1, \b, \c // b&c + bic \temp2, \d, \b // d&(~b) + orr \temp1, \temp1, \temp2 // f(B, C, D) + + CAL_B_E \a, \b, \e, \wi, \k, \temp1, \temp3, \temp4 +.endm + +/** + * Macro Description: Message compression,20~39、60~79round data compression + * input register: + * k: Constant data + * wi: Message block + * a - h: Intermediate variable of hash value + * temp1-4: temporary register + * Modify the register: b e temp1-temp4 + * Output register: + * b: Indicates the value after a cyclic update. + * e: Indicates the value after a cyclic update. + * Macro implementation: f(B, C, D) = B XOR C XOR D + * e = S^5(A) + f(B, C, D) + E + W(i) + K(i) + * b = S^30(B) + * Function/Macro Call: CAL_B_E + */ +.macro DATA_COMPRE_20_39_60_79 a, b, c, d, e, wi, k, temp1, temp2, temp3, temp4 + eor \temp2, \b, \c // b&c + eor \temp1, \temp2, \d // f(B, C, D) = b&c&d + + CAL_B_E \a, \b, \e, \wi, \k, \temp1, \temp3, \temp4 +.endm + +/** + * Macro Description: Message compression,40~59round data compression + * input register: + * k: Constant data + * wi: Message block + * a - h: Intermediate variable of hash value + * temp1-4: temporary register + * Modify the register: b e temp1-temp4 + * Output register: + * b: Indicates the value after a cyclic update. + * e: Indicates the value after a cyclic update. + * Macro implementation: f(B, C, D) = (B AND C) OR (B AND D) OR (C AND D) + * e = S^5(A) + f(B, C, D) + E + W(i) + K(i) + * b = S^30(B) + * Function/Macro Call: CAL_B_E + */ +.macro DATA_COMPRE_40_59 a, b, c, d, e, wi, k, temp1, temp2, temp3, temp4 + and \temp1, \b, \c // b&c + and \temp2, \b, \d // b&d + and \temp3, \c, \d // c&d + orr \temp1, \temp1, \temp2 // (b&c) or (b&d) + orr \temp1, \temp1, \temp3 // f(B, C, D) + + CAL_B_E \a, \b, \e, \wi, \k, \temp1, \temp3, \temp4 +.endm + +/** + * Function Description: Perform SHA1 compression calculation based on the input message and update the hash value. + * Function prototype: static const uint8_t *SHA1_Step(const uint8_t *input, uint32_t len, uint32_t *h) + * Input register: + * x0: Pointer to the input data address + * x1: Message length + * x2: Storage address of the hash value + * Register usage: w0–w15 store message blocks, x/w16, w17, w28, and w29 are temporary registers, + * and x30 stores the hash value address. a to e correspond to w20 to w24. w19 stores the k constant, + * x25 stores the message pointer, and x26 stores the remaining message length. + * Output register: x0 returns the address of the message for which sha1 calculation is not performed. + * Function/Macro Call: DATA_COMPRE_0_19、DATA_COMPRE_20_39_60_79、DATA_COMPRE_40_59、MESSAGE_EXPAND、SHA1CryptoExt + */ +.text +.balign 16 +.global SHA1_Step +.type SHA1_Step, %function +SHA1_Step: + .inst 0xd503233f // paciasp + cmp x1, #64 + b.lo .Lend_sha1 + + /* If the SHA1 cryptography extension instruction is supported, go to. */ + adrp x5, g_cryptArmCpuInfo + add x5, x5, :lo12:g_cryptArmCpuInfo + ldr x6, [x5] + tst x6, #CRYPT_ARM_SHA1 + bne SHA1CryptoExt + + /* Extended instructions are not supported, Using Base Instructions, Open up stack space, push stack protection */ + stp x29, x30, [sp, #-96]! + stp x19, x20, [sp, #8*2] + stp x21, x22, [sp, #8*4] + stp x23, x24, [sp, #8*6] + stp x25, x26, [sp, #8*8] + stp x27, x28, [sp, #8*10] + + /* load a - e */ + ldp w20, w21, [x2] + ldp w22, w23, [x2, #4*2] + ldr w24, [x2, #4*4] + + mov x30, x2 // x30 address for storing hash values + mov x25, x0 // pointer to the x25 store message + mov x26, x1 // x26: stores the remaining message length. + +.Lloop_sha1_compress: + adrp x16, g_k + add x16, x16, :lo12:g_k + ldr w19, [x16] // load k1 + + ldp w0, w1, [x25] // load input value, load 64 bytes at a time + ldp w2, w3, [x25, #4*2] + ldp w4, w5, [x25, #4*4] + ldp w6, w7, [x25, #4*6] + ldp w8, w9, [x25, #4*8] + ldp w10, w11, [x25, #4*10] + ldp w12, w13, [x25, #4*12] + ldp w14, w15, [x25, #4*14] + + add x25, x25, #64 // address offset: 64 bytes + sub x26, x26, #64 // update the remaining address length. + +#ifndef HITLS_BIG_ENDIAN + rev w0, w0 + rev w1, w1 + rev w2, w2 + rev w3, w3 + rev w4, w4 + rev w5, w5 + rev w6, w6 + rev w7, w7 + rev w8, w8 + rev w9, w9 + rev w10, w10 + rev w11, w11 + rev w12, w12 + rev w13, w13 + rev w14, w14 + rev w15, w15 +#endif + /* 0~19round data compression */ + /* a, b, c, d, e, wi, k, temp1, temp2, temp3, temp4 */ + DATA_COMPRE_0_19 w20, w21, w22, w23, w24, w0, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w24, w20, w21, w22, w23, w1, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w23, w24, w20, w21, w22, w2, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w22, w23, w24, w20, w21, w3, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w21, w22, w23, w24, w20, w4, w19, w16, w17, w28, w29 + + DATA_COMPRE_0_19 w20, w21, w22, w23, w24, w5, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w24, w20, w21, w22, w23, w6, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w23, w24, w20, w21, w22, w7, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w22, w23, w24, w20, w21, w8, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w21, w22, w23, w24, w20, w9, w19, w16, w17, w28, w29 + + DATA_COMPRE_0_19 w20, w21, w22, w23, w24, w10, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w24, w20, w21, w22, w23, w11, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w23, w24, w20, w21, w22, w12, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w22, w23, w24, w20, w21, w13, w19, w16, w17, w28, w29 + DATA_COMPRE_0_19 w21, w22, w23, w24, w20, w14, w19, w16, w17, w28, w29 + + DATA_COMPRE_0_19 w20, w21, w22, w23, w24, w15, w19, w16, w17, w28, w29 + /* Message block extension calculation wi_16, wi_14, wi_8, wi_3, temp1, temp2 */ + MESSAGE_EXPAND w0, w2, w8, w13, w16, w17 + DATA_COMPRE_0_19 w24, w20, w21, w22, w23, w0, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w1, w3, w9, w14, w16, w17 + DATA_COMPRE_0_19 w23, w24, w20, w21, w22, w1, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w2, w4, w10, w15, w16, w17 + DATA_COMPRE_0_19 w22, w23, w24, w20, w21, w2, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w3, w5, w11, w0, w16, w17 + DATA_COMPRE_0_19 w21, w22, w23, w24, w20, w3, w19, w16, w17, w28, w29 + + /* 20~39 round data compression */ + adrp x16, g_k + add x16, x16, :lo12:g_k + ldr w19, [x16, #4] // load k2 + MESSAGE_EXPAND w4, w6, w12, w1, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w4, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w5, w7, w13, w2, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w5, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w6, w8, w14, w3, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w6, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w7, w9, w15, w4, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w7, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w8, w10, w0, w5, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w8, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w9, w11, w1, w6, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w9, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w10, w12, w2, w7, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w10, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w11, w13, w3, w8, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w11, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w12, w14, w4, w9, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w12, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w13, w15, w5, w10, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w13, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w14, w0, w6, w11, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w14, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w15, w1, w7, w12, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w15, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w0, w2, w8, w13, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w0, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w1, w3, w9, w14, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w1, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w2, w4, w10, w15, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w2, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w3, w5, w11, w0, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w3, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w4, w6, w12, w1, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w4, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w5, w7, w13, w2, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w5, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w6, w8, w14, w3, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w6, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w7, w9, w15, w4, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w7, w19, w16, w17, w28, w29 + + /* 40~59 round data compression */ + adrp x16, g_k + add x16, x16, :lo12:g_k + ldr w19, [x16, #8] // load k3 + MESSAGE_EXPAND w8, w10, w0, w5, w16, w17 + DATA_COMPRE_40_59 w20, w21, w22, w23, w24, w8, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w9, w11, w1, w6, w16, w17 + DATA_COMPRE_40_59 w24, w20, w21, w22, w23, w9, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w10, w12, w2, w7, w16, w17 + DATA_COMPRE_40_59 w23, w24, w20, w21, w22, w10, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w11, w13, w3, w8, w16, w17 + DATA_COMPRE_40_59 w22, w23, w24, w20, w21, w11, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w12, w14, w4, w9, w16, w17 + DATA_COMPRE_40_59 w21, w22, w23, w24, w20, w12, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w13, w15, w5, w10, w16, w17 + DATA_COMPRE_40_59 w20, w21, w22, w23, w24, w13, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w14, w0, w6, w11, w16, w17 + DATA_COMPRE_40_59 w24, w20, w21, w22, w23, w14, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w15, w1, w7, w12, w16, w17 + DATA_COMPRE_40_59 w23, w24, w20, w21, w22, w15, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w0, w2, w8, w13, w16, w17 + DATA_COMPRE_40_59 w22, w23, w24, w20, w21, w0, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w1, w3, w9, w14, w16, w17 + DATA_COMPRE_40_59 w21, w22, w23, w24, w20, w1, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w2, w4, w10, w15, w16, w17 + DATA_COMPRE_40_59 w20, w21, w22, w23, w24, w2, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w3, w5, w11, w0, w16, w17 + DATA_COMPRE_40_59 w24, w20, w21, w22, w23, w3, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w4, w6, w12, w1, w16, w17 + DATA_COMPRE_40_59 w23, w24, w20, w21, w22, w4, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w5, w7, w13, w2, w16, w17 + DATA_COMPRE_40_59 w22, w23, w24, w20, w21, w5, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w6, w8, w14, w3, w16, w17 + DATA_COMPRE_40_59 w21, w22, w23, w24, w20, w6, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w7, w9, w15, w4, w16, w17 + DATA_COMPRE_40_59 w20, w21, w22, w23, w24, w7, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w8, w10, w0, w5, w16, w17 + DATA_COMPRE_40_59 w24, w20, w21, w22, w23, w8, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w9, w11, w1, w6, w16, w17 + DATA_COMPRE_40_59 w23, w24, w20, w21, w22, w9, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w10, w12, w2, w7, w16, w17 + DATA_COMPRE_40_59 w22, w23, w24, w20, w21, w10, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w11, w13, w3, w8, w16, w17 + DATA_COMPRE_40_59 w21, w22, w23, w24, w20, w11, w19, w16, w17, w28, w29 + + /* 60~79 round data compression */ + adrp x16, g_k + add x16, x16, :lo12:g_k + ldr w19, [x16, #12] // load k4 + MESSAGE_EXPAND w12, w14, w4, w9, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w12, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w13, w15, w5, w10, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w13, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w14, w0, w6, w11, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w14, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w15, w1, w7, w12, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w15, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w0, w2, w8, w13, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w0, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w1, w3, w9, w14, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w1, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w2, w4, w10, w15, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w2, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w3, w5, w11, w0, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w3, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w4, w6, w12, w1, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w4, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w5, w7, w13, w2, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w5, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w6, w8, w14, w3, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w6, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w7, w9, w15, w4, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w7, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w8, w10, w0, w5, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w8, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w9, w11, w1, w6, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w9, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w10, w12, w2, w7, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w10, w19, w16, w17, w28, w29 + + MESSAGE_EXPAND w11, w13, w3, w8, w16, w17 + DATA_COMPRE_20_39_60_79 w20, w21, w22, w23, w24, w11, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w12, w14, w4, w9, w16, w17 + DATA_COMPRE_20_39_60_79 w24, w20, w21, w22, w23, w12, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w13, w15, w5, w10, w16, w17 + DATA_COMPRE_20_39_60_79 w23, w24, w20, w21, w22, w13, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w14, w0, w6, w11, w16, w17 + DATA_COMPRE_20_39_60_79 w22, w23, w24, w20, w21, w14, w19, w16, w17, w28, w29 + MESSAGE_EXPAND w15, w1, w7, w12, w16, w17 + DATA_COMPRE_20_39_60_79 w21, w22, w23, w24, w20, w15, w19, w16, w17, w28, w29 + + /* load a - e */ + ldp w0, w1, [x30] + ldp w2, w3, [x30, #4*2] + ldr w4, [x30, #4*4] + + /* H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E */ + add w20, w20, w0 + add w21, w21, w1 + add w22, w22, w2 + add w23, w23, w3 + add w24, w24, w4 + + stp w20, w21, [x30] + stp w22, w23, [x30, #4*2] + str w24, [x30, #4*4] + + cmp x26, #64 + b.hs .Lloop_sha1_compress + + /* returns the address of the message for which SHA1 calculation is not performed. */ + mov x0, x25 + + /* pop-stack */ + ldp x19, x20, [sp, #8*2] + ldp x21, x22, [sp, #8*4] + ldp x23, x24, [sp, #8*6] + ldp x25, x26, [sp, #8*8] + ldp x27, x28, [sp, #8*10] + ldp x29, x30, [sp], #96 + +.Lend_sha1: + .inst 0xd50323bf // autiasp + ret +.size SHA1_Step, .-SHA1_Step + +/** + * Function Description: Based on the input message, compress the SHA1 dedicated instruction and + * update the hash value. + * Function prototype: static const uint8_t *SHA1CryptoExt(const uint8_t *input, uint32_t len, uint32_t *h) + * Input register: + * x0: Pointer to the input data address + * x1: Message length + * x2: Storage address of the hash value + * Register usage: v0–v3 stores k0–k3, s5 stores e temporarily, v6 stores abcd, and v7 stores e, + * V23–V26 stores w0–w15 and recycles w16–w79. V19–v22 stores w+k calculation results. + * V16 is used as the 0 register. v17 stores abcd and v18 stores e. v16 is used together with v6 and v7. + * Output register: x0 returns the address of the message for which sha1 calculation is not performed. + * Function/Macro Call: NONE + */ +.text +.balign 16 +.type SHA1CryptoExt, %function +SHA1CryptoExt: + /* load k */ + adrp x3, g_kExt + add x3, x3, :lo12:g_kExt + ld1 {v0.4s-v3.4s}, [x3] + + /* load a - e */ + ld1 {v17.4s}, [x2] + ld1 {v6.4s}, [x2], #16 + ld1 {v18.s}[0], [x2] + ld1 {v7.s}[0], [x2] + sub x2, x2, #16 + + eor v16.16b, v16.16b, v16.16b + +.Lloop_sha1_ext_compress: + + /* load w */ + ld1 {v23.4s-v26.4s}, [x0], #64 + sub x1, x1, #64 // update the remaining address length. + + /* little endian inversion */ + +#ifndef HITLS_BIG_ENDIAN + rev32 v23.16b, v23.16b + rev32 v24.16b, v24.16b + rev32 v25.16b, v25.16b + rev32 v26.16b, v26.16b +#endif + + add v19.4s, v0.4s, v23.4s // k0+w[3:0] + add v20.4s, v0.4s, v24.4s // k0+w[4:7] + add v21.4s, v0.4s, v25.4s // k0+w[11:8] + add v22.4s, v0.4s, v26.4s // k0+w[15:12] + + /* [0:16] data compression */ + sha1su0 v23.4s, v24.4s, v25.4s // w[16:20] + sha1h s5, s6 // a -> e + sha1c q6, s7, v19.4s // a, b, c, d -> a, b, c, d + sha1su1 v23.4s, v26.4s + + sha1su0 v24.4s, v25.4s, v26.4s + sha1h s7, s6 + sha1c q6, s5, v20.4s + sha1su1 v24.4s, v23.4s + + sha1su0 v25.4s, v26.4s, v23.4s + sha1h s5, s6 + sha1c q6, s7, v21.4s + sha1su1 v25.4s, v24.4s + + sha1su0 v26.4s, v23.4s, v24.4s + sha1h s7, s6 + sha1c q6, s5, v22.4s + sha1su1 v26.4s, v25.4s + + add v19.4s, v0.4s, v23.4s // k0+w[19:16] + add v20.4s, v1.4s, v24.4s // k1+w[23:20] + add v21.4s, v1.4s, v25.4s // k1+w[27:24] + add v22.4s, v1.4s, v26.4s // k1+w[31:28] + + /* [16:20] data compression */ + sha1su0 v23.4s, v24.4s, v25.4s + sha1h s5, s6 + sha1c q6, s7, v19.4s + sha1su1 v23.4s, v26.4s + + /* [20:40] data compression */ + sha1su0 v24.4s, v25.4s, v26.4s + sha1h s7, s6 + sha1p q6, s5, v20.4s + sha1su1 v24.4s, v23.4s + + sha1su0 v25.4s, v26.4s, v23.4s + sha1h s5, s6 + sha1p q6, s7, v21.4s + sha1su1 v25.4s, v24.4s + + sha1su0 v26.4s, v23.4s, v24.4s + sha1h s7, s6 + sha1p q6, s5, v22.4s + sha1su1 v26.4s, v25.4s + + add v19.4s, v1.4s, v23.4s // k1+w[35:32] + add v20.4s, v1.4s, v24.4s // k1+w[39:36] + add v21.4s, v2.4s, v25.4s // k2+w[43:40] + add v22.4s, v2.4s, v26.4s // k2+w[47:44] + + sha1su0 v23.4s, v24.4s, v25.4s + sha1h s5, s6 + sha1p q6, s7, v19.4s + sha1su1 v23.4s, v26.4s + + sha1su0 v24.4s, v25.4s, v26.4s + sha1h s7, s6 + sha1p q6, s5, v20.4s + sha1su1 v24.4s, v23.4s + + /* [40:60] data compression */ + sha1su0 v25.4s, v26.4s, v23.4s + sha1h s5, s6 + sha1m q6, s7, v21.4s + sha1su1 v25.4s, v24.4s + + sha1su0 v26.4s, v23.4s, v24.4s + sha1h s7, s6 + sha1m q6, s5, v22.4s + sha1su1 v26.4s, v25.4s + + add v19.4s, v2.4s, v23.4s // k2+w[51:48] + add v20.4s, v2.4s, v24.4s // k2+w[55:52] + add v21.4s, v2.4s, v25.4s // k2+w[59:56] + add v22.4s, v3.4s, v26.4s // k3+w[63:60] + + sha1su0 v23.4s, v24.4s, v25.4s + sha1h s5, s6 + sha1m q6, s7, v19.4s + sha1su1 v23.4s, v26.4s + + sha1su0 v24.4s, v25.4s, v26.4s + sha1h s7, s6 + sha1m q6, s5, v20.4s + sha1su1 v24.4s, v23.4s + + sha1su0 v25.4s, v26.4s, v23.4s + sha1h s5, s6 + sha1m q6, s7, v21.4s + sha1su1 v25.4s, v24.4s + + /* [60:80] data compression */ + sha1su0 v26.4s, v23.4s, v24.4s + sha1h s7, s6 + sha1p q6, s5, v22.4s + sha1su1 v26.4s, v25.4s + + add v19.4s, v3.4s, v23.4s // k3+w[67:64] + add v20.4s, v3.4s, v24.4s // k3+w[71:68] + add v21.4s, v3.4s, v25.4s // k3+w[75:72] + add v22.4s, v3.4s, v26.4s // k3+w[79:76] + + sha1h s5, s6 + sha1p q6, s7, v19.4s + + sha1h s7, s6 + sha1p q6, s5, v20.4s + + sha1h s5, s6 + sha1p q6, s7, v21.4s + + sha1h s7, s6 + sha1p q6, s5, v22.4s + + /* calculate H0 H1 H2 H3 H4 */ + add v17.4s, v17.4s, v6.4s + add v18.4s, v18.4s, v7.4s + + add v6.4s, v17.4s, v16.4s + add v7.4s, v18.4s, v16.4s + + cmp x1, #64 + b.hs .Lloop_sha1_ext_compress + + st1 {v17.4s}, [x2], #16 + st1 {v18.s}[0], [x2] + + ret +.size SHA1CryptoExt, .-SHA1CryptoExt + +#endif diff --git a/crypto/sha1/src/asm/sha1_x86_64.S b/crypto/sha1/src/asm/sha1_x86_64.S new file mode 100644 index 00000000..cd3c2008 --- /dev/null +++ b/crypto/sha1/src/asm/sha1_x86_64.S @@ -0,0 +1,723 @@ +/* + * 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_SHA1 + +.file "sha1_x86_64.S" +.text + +.set INPUT, %rdi +.set LEN, %rsi +.set HASH, %rdx + +.set A, %r8d +.set B, %r9d +.set C, %r10d +.set D, %r11d +.set E, %r12d + +.set TEMP, %r13d +.set TEMP1, %r15d +.set TEMP2, %ebx +.set TEMP3, %eax +.set BLK0, %xmm0 +.set BLK1, %xmm1 +.set BLK2, %xmm2 +.set BLK3, %xmm3 + +.set ZERO, %ymm4 +.set EXPAND0, %ymm5 +.set EXPAND1, %ymm6 +.set EXPAND2, %ymm7 +.set EXPAND3, %ymm8 +.set TEMP_W0, %ymm9 +.set TEMP_W1, %ymm10 +.set TEMP_W2, %ymm11 +.set KNUM, %ymm12 + +/* sha1 constant value used */ +.section .rodata +.balign 64 +.type g_k, %object +g_k: + .long 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999 // K_00_19 + .long 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1 // K_20_39 + .long 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc // K_40_59 + .long 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 // K_60_79 + .size g_k, .-g_k + +/* inverted mask */ +.balign 64 +.type endian_mask, %object +endian_mask: + .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f + .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f +.size endian_mask, .-endian_mask + +/** + * Macro Description: Message compression, 0 to 18 rounds of data compression, pre-computation Next round F0, b + * Input register: + *a - e, temp: Intermediate variable of hash value + * addr: Stack Address, Kt+W + * wkOffset: Kt+W read Offset + * temp1-2: temporary register + * Modify the register: a e temp temp1 temp2 + * Output register: + * a: Next round F0 + * e: Indicates the value after a cyclic update. + * temp: Next round B + * Macro implementation: F0(b,c,d) = (b AND c) OR ((NOT b) AND d) + * =(((b) & (c)) | ((~(b)) & (d))) + * e = S^5(a) + F0(b,c,d) + e + W(i) + K(i) + * temp = S^30(b) + */ +.macro ROUND00_18 a, temp, b, c, d, e, addr, wkOffset, temp1, temp2 + addl \wkOffset(\addr), \e // e = e + W + KT + andn \c, \a, \temp1 // Next (~(b)) & (d) + addl \temp, \e // e = F0(b, c, d) + e + W + KT + rorxl $27, \a, \temp2 // Temp2 = ROTL32(a, 5) + rorxl $2, \a, \temp // Next ROTL32(b, 30) + and \b, \a // Next ((b) & (c)) + addl \temp2, \e // e = F0(b, c, d) + e + W + KT + S^5(a) + or \temp1, \a // Next (((b) & (c)) | ((~(b)) & (d))) +.endm + +/** + * Macro Description: 0 to 18 rounds of message compression and 16 to 31 message extension, + * pre-calculation Next round F0, b + * Input register: + *a - e, temp: Intermediate variable of hash value + * addr: Stack Address, Kt+W + * wkOffset: Kt+W read offset + * temp1-2: temporary register + * wt_16_13: w(t-16) ~ w(t-13) + * wt_12_9: w(t-12) ~ w(t-9) + * wt_8_5: w(t-8) ~ w(t-5) + * wt_4_1: w(t-4) ~ w(t-1) + * expand0: w(t) ~ w(t+3) + * tempw0-2: temporary register + * zero: register with a value of zero + * knum: k constant value + * Modify the register: a b c d e temp temp1 temp2 expand0 tempw0 tempw1 tempw2 + * Output register: + * a: Third round B + * b: Value after four rounds of cyclic update + * c: Next round F0 + * d: Next round B + * e: Fourth round B + * temp: next b + * expand0: Value after a round of extension + * Macro implementation: f(b,c,d) = (b AND c) OR ((NOT b) AND d) +* =(((b) & (c)) | ((~(b)) & (d))) + * temp = S^5(a) + f(b,c,d) + e + W(i) + K(i) + * b = S^30(b) + * W(t ) = ROL(W(t-3) ^ W(t-8) ^ W(t-14) ^ W(t-16), 1) + * W(t+1) = ROL(W(t-2) ^ W(t-7) ^ W(t-13) ^ W(t-15), 1) + * W(t+2) = ROL(W(t-1) ^ W(t-6) ^ W(t-12) ^ W(t-14), 1) + * W(t+3) = ROL(0 ^ W(t-5) ^ W(t-11) ^ W(t-13), 1) + * W(t+3) = W(t+3) ^ ROL(W(t), 1) + */ +.macro ROUND00_18_EXPAND a, temp, b, c, d, e, addr, wkOffset, wt_16_13, wt_12_9, wt_8_5, wt_4_1, expand0 + vpalignr $8, \wt_16_13, \wt_12_9, TEMP_W1 // Expand w(t-14) w(t-13) w(t-12) w(t-11) + addl \wkOffset(\addr), \e // e = e + W + KT + andn \c, \a, TEMP1 // Next (~(b)) & (d) + addl \temp, \e // e = F0 + e + W + KT + vpalignr $4, \wt_4_1, ZERO, TEMP_W0 // Expand w(t-3) w(t-2) w(t-1) 0 + vpxor \wt_8_5, \wt_16_13, \expand0 // Expand w(t-8) ^ w(t-16) + rorxl $27, \a, TEMP2 // Temp2 = ROTL32(a, 5) + rorxl $2, \a, \temp // Next ROTL32(b, 30) + and \b, \a // Next ((b) & (c)) + vpxor TEMP_W1, \expand0, \expand0 // Expand w(t-14) ^ w(t-8) ^ w(t-16) + addl TEMP2, \e // e = F0 + e + W + KT + S^5(a) + or TEMP1, \a // Next F0 done + + addl \wkOffset + 4(\addr), \d // Next d = d + W + KT + vpxor TEMP_W0, \expand0, TEMP_W0 // Expand tempw0 = w[t:t+4] before rol 1 + andn \b, \e, TEMP1 // Next F0 + addl \a, \d // d = F0 + d + W + KT + rorxl $27, \e, TEMP2 // Temp2 = ROTL32(E, 5) + rorxl $2, \e, \a // next ROTL32(E, 30) + vpalignr $4, ZERO, TEMP_W0, TEMP_W1 // Expand tempw1 = 0 0 0 w(t) + and \temp, \e // Next F0 + addl TEMP2, \d // d = F0 + d + W + KT + S^5(E) + or TEMP1, \e // Next F0 done + + vpsrld $31, TEMP_W0, \expand0 // Expand ROL(w(t), w(t+1), w(t+2), w(t+3),1) + addl \wkOffset + 8(\addr), \c // c = c + W + KT + vpaddd TEMP_W0, TEMP_W0, TEMP_W0 // Expand ROL(w(t), w(t+1), w(t+2), w(t+3),1) + andn \temp, \d, TEMP1 // Next F0 + addl \e, \c // c = F0 + c + W + KT + rorxl $27, \d, TEMP2 // Temp2 = ROTL32(D, 5) + rorxl $2, \d, \e // Next ROTL32(D, 30) + vpsrld $30, TEMP_W1, TEMP_W2 // Expand ROL(w(t), 2) + and \a, \d // Next F0 + addl TEMP2, \c // c = F0 + c + W + KT + S^5(D) + or TEMP1, \d // Next F0 done + + vpslld $2, TEMP_W1, TEMP_W1 // Expand ROL(w(t), 2) + vpxor \expand0, TEMP_W0, \expand0 // Expand ROL(w(t), w(t+1), w(t+2), w(t+3),1) + addl \wkOffset + 12(\addr), \b // b = b + W + KT + andn \a, \c, TEMP1 // Next F0 + vpxor TEMP_W2, TEMP_W1, TEMP_W0 // Expand ROL(w(t), 2) + addl \d, \b // b = F0 + b + W + KT + rorxl $27, \c, TEMP2 // Temp2 = ROTL32(C, 5) + rorxl $2, \c, \d // Next ROTL32(C, 30) + vpxor \expand0, TEMP_W0, \expand0 // Expand w[t:t+4] + and \e, \c // Next F0 + addl TEMP2, \b // b = F0 + b + W + KT + S^5(C) + vpaddd KNUM,\expand0, TEMP_W0 // Expand w + k + or TEMP1, \c // Next F0 done + vmovdqa TEMP_W0, \wkOffset + 128(\addr) +.endm + +/** + * Macro Description: Message compression, 20~39, 60~79 round data compression, precomputation Next round F1, b + * Input register: + *a - e, temp: Intermediate variable of hash value + * addr: Stack Address, Kt+W + * wkOffset: Kt+W read offset + * temp1-2: temporary register + * Modify the register: a e temp temp1 temp2 + * Output register: + * a: Next round F1 + * e: Indicates the value after a cyclic update. + * temp: Next round B + * Macro implementation: F1(b,c,d) = b XOR c XOR d + * =(((b) ^ (c)) ^ (d)) + * e = S^5(a) + F1(b,c,d) + e + W(i) + K(i) + * temp = S^30(b) + */ +.macro ROUND20_39 a, temp, b, c, d, e, addr, wkOffset, temp1, temp2 + addl \wkOffset(\addr), \e // e = e + W + KT + addl \temp, \e // e = F1(b, c, d) + e + W + KT + rorx $27, \a, TEMP2 // Temp2 = ROTL32(a, 5) + rorx $2, \a, \temp // Next ROTL32(b, 30) + xor \b, \a // Next (b) ^ (c) + addl TEMP2, \e // e = F0(b, c, d) + e + W + KT + S^5(a) + xor \c, \a // Next (b) ^ (c) ^ (d) +.endm + +/** + * Macro Description: 20~39, 60~79 round data compression, and 16-31 message extension, precomputation Next round F1, b + * Input register: + *a - e, temp: Intermediate variable of hash value + * addr: Stack Address, Kt+W + * wkOffset: Kt+W read offset + * temp1-2: temporary register + * wt_32_29: w(t-32) ~ w(t-29) + * wt_28_25: w(t-28) ~ w(t-25) + * wt_8_5: w(t-8) ~ w(t-5) + * wt_4_1: w(t-4) ~ w(t-1) + * expand0: w(t) ~ w(t+3) + * zero: register with a value of zero + * knum: k constant value + * Modify the register: a b c d e temp temp1 temp2 wt_32_29 tempw0 + * Output register: + * a: Third round B value + * b: Value after four rounds of cyclic update + * c: Next round F1 + * d: Next round B + * e: Fourth round B value + * temp: next b + * expand0: Value after a round of extension + * Macro implementation: F1(b,c,d) = b XOR c XOR d + * =(((b) ^ (c)) ^ (d)) + * e = S^5(a) + F1(b,c,d) + e + W(i) + K(i) + * temp = S^30(b) + * w(t) = ROL(w(t-3) ^ w(t-8) ^ w(t-14) ^ w(t-16), 1) + * = ROL(w(t-6) ^ w(t-11) ^ w(t-17) ^ w(t-19) ^ + * w(t-11) ^ w(t-16) ^ w(t-22) ^ w(t-24) ^ + * w(t-17) ^ w(t-22) ^ w(t-28) ^ w(t-30) ^ + * w(t-19) ^ w(t-24) ^ w(t-30) ^ w(t-32), 2) + * = ROL(w(t-6) ^ w(t-16) ^ w(t-28) ^ w(t-32), 2) + * w(t+1), w(t+2), w(t+3) in the same way + */ +.macro ROUND20_39_EXPAND a, temp, b, c, d, e, addr, wkOffset, wt_32_29, wt_28_25, wt_16_13, wt_8_5, wt_4_1, wkOffset2 + vpalignr $8, \wt_8_5, \wt_4_1, TEMP_W0 // Expand w(t-6), w(t-5), w(t-4), w(t-3) + vpxor \wt_32_29, \wt_16_13, \wt_32_29 // Expand wt_32_29 =w[t-32:t-28] ^ w[t-16:t-12] + addl \wkOffset(\addr), \e // e = e + W + KT + addl \temp, \e // e = F1(b, c, d) + e + W + KT + rorx $27, \a, TEMP2 // temp2 = ROTL32(a, 5) + rorx $2, \a, \temp // Next ROTL32(b, 30) + vpxor \wt_32_29, \wt_28_25, \wt_32_29 // Expand wt_32_29 =w[t-32:t-28] ^ w[t-16:t-12]^ w[t-28:t-24] + xor \b, \a // Next (b) ^ (c) + addl TEMP2, \e // e = F0(b, c, d) + e + W + KT + S^5(a) + xor \c, \a // Next F1 done + + addl \wkOffset + 4(\addr), \d // d = d + W + KT + vpxor \wt_32_29, TEMP_W0, \wt_32_29 // Expand wt_32_29 =w[t-32] ^ w[t-16]^ w[t-28]^ w[t-6] + addl \a, \d // d = F1 + d + W + KT + rorx $27, \e, TEMP2 // Temp2 = ROTL32(e, 5) + rorx $2, \e, \a // Next temp = ROTL32(e, 30) + xor \temp, \e // Next F1 + addl TEMP2, \d // Expand d = F1 + d + W + KT + S^5(e) + vpsrld $30, \wt_32_29, TEMP_W0 // Expand ROL(wt_32_29,2) + xor \b, \e // Next F1 done + + addl \wkOffset + 8(\addr), \c // c = c + W + KT + addl \e, \c // c = F1 + c + W + KT + rorx $27, \d, TEMP2 // Temp2 = ROTL32(e, 5) + rorx $2, \d, \e // Next ROTL32(e, 30) + vpslld $2, \wt_32_29, \wt_32_29 + xor \a, \d // Next F1 + addl TEMP2, \c // c = F1 + c + W + KT + S^5(e) + xor \temp, \d // Next F1 done + + addl \wkOffset + 12(\addr), \b // b = b + W + KT + vpxor \wt_32_29, TEMP_W0, \wt_32_29 // Expand ROL(wt_32_29,2) + rorx $27, \c, TEMP2 // Temp2 = ROTL32(c, 5) + addl \d, \b // b = F1 + b + W + KT + rorx $2, \c, \d // Next ROTL32(c, 30) + vpaddd KNUM, \wt_32_29, TEMP_W0 + xor \e, \c // Next F1 + addl TEMP2, \b // b = F1 + b + W + KT + S^5(c) + xor \a, \c // Next F1 done + vmovdqa TEMP_W0, \wkOffset2(\addr) +.endm + +/** + * Macro Description: Message compression, 40~59 round data compression, pre-computation Next round F2, b + * Input register: + *a - e, temp: Intermediate variable of hash value + * addr: Stack Address, Kt+W + * wkOffset: Kt+W read offset + * temp1-2: temporary register + * Modify the register: a e temp temp1 temp2 + * Output register: + * a: Next round F1 + * e: Indicates the value after a cyclic update. + * temp: Next round B + * Macro implementation: F1(b,c,d) = (b AND c) OR (b AND d) OR (c AND d) + * =((b^c) & (c^d) ^ c) + * e = S^5(a) + F1(b,c,d) + e + W(i) + K(i) + * temp = S^30(b) + */ +.macro ROUND40_59 a, temp, b, c, d, e, addr, wkOffset, temp1, temp2 + addl \wkOffset(\addr), \e // e = e + W + KT + mov \c, \temp1 + addl \temp, \e // e = F2(b, c, d) + e + W + KT + xor \b, \temp1 // Next (c^d) + rorx $27, \a, \temp2 // Temp2 = ROTL32(a, 5) + rorx $2, \a, \temp // Next ROTL32(b, 30) + xor \b, \a // Next (b^c) + addl \temp2, \e // e = F0(b, c, d) + e + W + KT + S^5(a) + and \temp1, \a // Next (b^c) & (c^d) + xor \b, \a // Next (((b^c)) & (c^d) ^ c) +.endm + +/** + * Macro Description: 40~59 round data compression, and 32 to 79 rounds of message extension, + * precomputation Next round F2, b + * Input register: + *a - e, temp: Intermediate variable of hash value + * addr: Stack Address, Kt+W + * wkOffset: Kt+W read offset + * temp1-2: temporary register + * wt_32_29: w(t-32) ~ w(t-29) + * wt_28_25: w(t-28) ~ w(t-25) + * wt_8_5: w(t-8) ~ w(t-5) + * wt_4_1: w(t-4) ~ w(t-1) + * expand0: w(t) ~ w(t+3) + * zero: register with a value of zero + * knum: k constant value + * Modify the register: a b c d e temp temp1 temp2 wt_32_29 tempw0 + * Output register: + * a: Third round B value + * b: Value after four rounds of cyclic update + * c: Next round F1 + * d: Next round B + * e: Fourth round B value + * temp: next b + * expand0: Value after a round of extension + * Macro implementation: F1(b,c,d) = (b AND c) OR (b AND d) OR (c AND d) + * =((b^c) & (c^d) ^ c) + * e = S^5(a) + F1(b,c,d) + e + W(i) + K(i) + * w(t) = ROL(w(t-3) ^ w(t-8) ^ w(t-14) ^ w(t-16), 1) + * = ROL(w(t-6) ^ w(t-11) ^ w(t-17) ^ w(t-19) ^ + * w(t-11) ^ w(t-16) ^ w(t-22) ^ w(t-24) ^ + * w(t-17) ^ w(t-22) ^ w(t-28) ^ w(t-30) ^ + * w(t-19) ^ w(t-24) ^ w(t-30) ^ w(t-32), 2) + * = ROL(w(t-6) ^ w(t-16) ^ w(t-28) ^ w(t-32), 2) + * w(t+1), w(t+2), w(t+3) in the same way + */ +.macro ROUND40_59_EXPAND a, temp, b, c, d, e, addr, wkOffset, wt_32_29, wt_28_25, wt_16_13, wt_8_5, wt_4_1, wkOffset2 + vpalignr $8, \wt_8_5, \wt_4_1, TEMP_W0 // Expand w(t-6), w(t-5), w(t-4), w(t-3) + vpxor \wt_32_29, \wt_16_13, \wt_32_29 // Expand wt_32_29 =w[t-32:t-28] ^ w[t-16:t-12] + addl \wkOffset(\addr), \e // e = e + W + KT + mov \c, TEMP1 + addl \temp, \e // e = F2(b, c, d) + e + W + KT + xor \b, TEMP1 // Next temp1 = (c^d) + rorx $27, \a, TEMP2 // Temp2 = ROTL32(a, 5) + rorx $2, \a, \temp // Next ROTL32(b, 30) + vpxor \wt_32_29, \wt_28_25, \wt_32_29 // Expand wt_32_29 =w[t-32:t-28] ^ w[t-16:t-12]^ w[t-28:t-24] + xor \b, \a // Next (b^c) + addl TEMP2, \e // e = F0(b, c, d) + e + W + KT + S^5(a) + and TEMP1, \a // Next (b^c) & (c^d) + addl \wkOffset + 4(\addr), \d // d = d + W + KT + xor \b, \a // Next (((b^c)) & (c^d) ^ c) + + vpxor \wt_32_29, TEMP_W0, \wt_32_29 // Expand wt_32_29 =w[t-32] ^ w[t-16]^ w[t-28]^ w[t-6] + mov \b, TEMP1 + addl \a, \d // d = F2 + d + W + KT + xor \temp, TEMP1 // Next F2 + rorx $27, \e, TEMP2 // Temp2 = ROTL32(e, 5) + rorx $2, \e, \a // Next ROTL32(e, 30) + addl \wkOffset + 8(\addr), \c // c = c + W + KT + xor \temp, \e // Next F2 + vpsrld $30, \wt_32_29, TEMP_W0 // Expand ROL(wt_32_29,2) + and TEMP1, \e // Next F2 + addl TEMP2, \d // d = F2 + d + W + KT + S^5(e) + xor \temp, \e // Next F2 done + + mov \temp, TEMP1 + addl \e, \c // c = F2 + c + W + KT + xor \a, TEMP1 // Next F2 + vpslld $2, \wt_32_29, \wt_32_29 + rorx $27, \d, TEMP2 // Temp2 = ROTL32(d, 5) + rorx $2, \d, \e // Next ROTL32(d, 30) + xor \a, \d // Next F2 + addl TEMP2, \c // c = F2 + c + W + KT + S^5(d) + and TEMP1, \d // Next F2 + addl \wkOffset + 12(\addr), \b // b = b + W + KT + vpxor \wt_32_29, TEMP_W0, \wt_32_29 // Expand ROL(wt_32_29,2) + xor \a, \d // Next F2 done + + mov \a, TEMP1 + addl \d, \b // b = F2 + b + W + KT + xor \e, TEMP1 // Next F2 + rorx $27, \c, TEMP2 // Temp2 = ROTL32(c, 5) + rorx $2, \c, \d // Next ROTL32(c, 30) + xor \e, \c // Next F2 + vpaddd KNUM, \wt_32_29, TEMP_W0 + addl TEMP2, \b // b = F2 + b + W + KT + S^5(c) + and TEMP1, \c // Next F2 + xor \e, \c // Next F2 done + vmovdqa TEMP_W0, \wkOffset2(\addr) +.endm + +/** + * Function Description: Perform SHA1 compression calculation based on the input message and update the hash value. + * Function prototype: static const uint8_t *SHA1_Step(const uint8_t *input, uint32_t len, uint32_t *h) + * Input register: + * rdi: Pointer to the input data address + * rsi: Message length + * rdx: Storage address of the hash value + * Register usage: r8~r12: A~E, r13: TEMP, r15, ebx, eax: temporary register, ymm0~ymm3: w0~w15 Message block, + * ymm4: 0, ymm5~ymm8: extended message block, ymm9~ymm13: temporary register, ymm13: k+w value + * Output register: rax Returns the address of the message for which SHA1 calculation is not performed. + * Function/Macro Call: ROUND00_18, ROUND00_18_EXPAND, ROUND20_39, ROUND20_39_EXPAND, ROUND40_59, ROUND40_59_EXPAND + */ +.text +.globl SHA1_Step + .type SHA1_Step, @function +SHA1_Step: + .cfi_startproc + cmp $64, LEN + jb .Lend_sha1 + + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + mov %rsp, %r14 + lea -1024(%rsp), %rsp // Apply for 1024-byte stack space. + + mov 0(HASH), A // r8~r13: a~e + mov 4(HASH), B + andq $-256, %rsp + mov 8(HASH), C + mov 12(HASH), D + mov 16(HASH), E + +.Lloop_sha1_compress: +.align 16 + vmovdqu (INPUT), BLK0 // Loads the data of a block to the lower 128 bits + // of the YMM register. + vmovdqu 16(INPUT), BLK1 + vmovdqu 32(INPUT), BLK2 + sub $64, LEN + vmovdqu 48(INPUT), BLK3 + add $64, INPUT + + cmp $64, LEN // Check whether the remaining length is greater than 64. + jb .Lsha1_compress + vinserti128 $1, 0(INPUT), %ymm0, %ymm0 // Loads the data of a block to the upper 128 bits + // of the ymm register. + vinserti128 $1, 16(INPUT), %ymm1, %ymm1 + vinserti128 $1, 32(INPUT), %ymm2, %ymm2 + vinserti128 $1, 48(INPUT), %ymm3, %ymm3 + add $64, INPUT + +.Lsha1_compress: + vmovdqa endian_mask + 0(%rip), %ymm8 // Endian inversion mask + leaq g_k + 0(%rip), %rbp // Get k + + vpshufb %ymm8, %ymm0, %ymm0 // Little endian to big endian + vmovdqa 0(%rbp), KNUM + vpshufb %ymm8, %ymm1, %ymm1 + vpaddd KNUM, %ymm0, %ymm13 // w[0:15] + k0 + vpshufb %ymm8, %ymm2, %ymm2 + vmovdqa %ymm13, 0(%rsp) // wk push stack + vpaddd KNUM, %ymm1, %ymm9 + vpshufb %ymm8, %ymm3, %ymm3 + vmovdqa %ymm9, 32(%rsp) + vpaddd KNUM, %ymm2, %ymm10 + vpxor %ymm4, %ymm4, %ymm4 + + mov C, TEMP // The first round F0 + vmovdqa %ymm10, 64(%rsp) + and B, TEMP // Round0 ((b) & (c)) + andn D, B, TEMP2 // Round0 (~(b)) & (d) + vpaddd KNUM, %ymm3, %ymm11 + or TEMP2, TEMP // Round0 (((b) & (c)) | ((~(b)) & (d))) + rol $30, B // Round0 B = ROTL32(B, 30) + vmovdqa %ymm11, 96(%rsp) + ROUND00_18_EXPAND A, TEMP, B, C, D, E, %rsp, 0, %ymm0, %ymm1, %ymm2, %ymm3, EXPAND0 + vmovdqa 32(%rbp), KNUM + ROUND00_18_EXPAND B, C, D, E, A, TEMP, %rsp, 32, %ymm1, %ymm2, %ymm3, EXPAND0, EXPAND1 + ROUND00_18_EXPAND D, E, A, TEMP, B, C, %rsp, 64, %ymm2, %ymm3, EXPAND0, EXPAND1, EXPAND2 + ROUND00_18_EXPAND A, TEMP, B, C, D, E, %rsp, 96, %ymm3, EXPAND0, EXPAND1, EXPAND2, EXPAND3 + ROUND00_18 B, C, D, E, A, TEMP, %rsp, 128, TEMP1, TEMP2 + ROUND00_18 TEMP, B, C, D, E, A, %rsp, 132, TEMP1, TEMP2 + ROUND00_18 A, TEMP, B, C, D, E, %rsp, 136, TEMP1, TEMP2 // 18 + addl 140( %rsp), D // D = DE + W + KT + rorx $27, E, TEMP2 // TEMP2 = ROTL32(E, 5) + addl A, D // D = F0 + D + W + KT + rorx $2, E, A // Round20 ROTL32(E, 30) + xor TEMP, E // Round20 (TEMP) ^ (E) + addl TEMP2, D // D = F0 + D + W + KT + S^5(E) + xor B, E // Round20 F1 + + ROUND20_39_EXPAND D, E, A, TEMP, B, C, %rsp, 160, %ymm0, %ymm1, EXPAND0, EXPAND2, EXPAND3, 256 + ROUND20_39_EXPAND A, TEMP, B, C, D, E, %rsp, 192, %ymm1, %ymm2, EXPAND1, EXPAND3, %ymm0, 288 + vmovdqa 64(%rbp), KNUM + ROUND20_39_EXPAND B, C, D, E, A, TEMP, %rsp, 224, %ymm2, %ymm3, EXPAND2, %ymm0, %ymm1, 320 + ROUND20_39_EXPAND D, E, A, TEMP, B, C, %rsp, 256, %ymm3, EXPAND0, EXPAND3, %ymm1, %ymm2, 352 + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 288, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 292, TEMP1, TEMP2 + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 296, TEMP1, TEMP2 // 38 + addl 300(%rsp), B // B = B + W + KT + mov A, TEMP1 + addl D, B // B = F1 + B + W + KT + xor E, TEMP1 // Round40 (E^A) + rorx $27, C, TEMP2 // TEMP2 = ROTL32(C, 5) + rorx $2, C, D // Round40 ROTL32(C, 30) + xor E, C // Round40 (E^C) + addl TEMP2, B // B = F1 + B + W + KT + S^5(C) + and TEMP1, C // Round40 (E^A) & (E^C) + xor E, C // Round40 F2 + + ROUND40_59_EXPAND B, C, D, E, A, TEMP, %rsp, 320, EXPAND0, EXPAND1, %ymm0, %ymm2, %ymm3, 384 + ROUND40_59_EXPAND D, E, A, TEMP, B, C, %rsp, 352, EXPAND1, EXPAND2, %ymm1, %ymm3, EXPAND0, 416 + ROUND40_59_EXPAND A, TEMP, B, C, D, E, %rsp, 384, EXPAND2, EXPAND3, %ymm2, EXPAND0, EXPAND1, 448 + vmovdqa 96(%rbp), KNUM + ROUND40_59_EXPAND B, C, D, E, A, TEMP, %rsp, 416, EXPAND3, %ymm0, %ymm3, EXPAND1, EXPAND2, 480 + ROUND40_59 D, E, A, TEMP, B, C, %rsp, 448, TEMP1, TEMP2 + ROUND40_59 C, D, E, A, TEMP, B, %rsp, 452, TEMP1, TEMP2 + ROUND40_59 B, C, D, E, A, TEMP, %rsp, 456, TEMP1, TEMP2 // 58 + addl 460(%rsp), A // A = A + W + KT + rorx $27, TEMP, TEMP2 // TEMP2 = ROTL32(TEMP, 5) + addl B, A // A = F2 + A + W + KT + rorx $2, TEMP, B // Round60 ROTL32(TEMP, 30) + xor C, TEMP // Round60 (C) ^ (TEMP) + addl TEMP2, A // A = F2 + A + W + KT + S^5(TEMP) + xor D, TEMP // Round60 F0 + + ROUND20_39_EXPAND A, TEMP, B, C, D, E, %rsp, 480, %ymm0, %ymm1, EXPAND0, EXPAND2, EXPAND3, 512 + ROUND20_39_EXPAND B, C, D, E, A, TEMP, %rsp, 512, %ymm1, %ymm2, EXPAND1, EXPAND3, %ymm0, 544 + ROUND20_39_EXPAND D, E, A, TEMP, B, C, %rsp, 544, %ymm2, %ymm3, EXPAND2, %ymm0, %ymm1, 576 + ROUND20_39_EXPAND A, TEMP, B, C, D, E, %rsp, 576, %ymm3, EXPAND0, EXPAND3, %ymm1, %ymm2, 608 + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 608, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 612, TEMP1, TEMP2 + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 616, TEMP1, TEMP2 // 78 + addl 620(%rsp), D // D = D + W + KT + add E, 4(HASH) // Update HASH + lea (A, D), D // D = F1 + D + W + KT + add TEMP, 8(HASH) + rorx $27, E, TEMP2 // TEMP2 = ROTL32(E, 5) + + add B, 12(HASH) + addl TEMP2, D // D = F1 + D + W + KT + S^5(E) + add C, 16(HASH) + mov 4(HASH), B + add D, 0(HASH) + mov 8(HASH), C + mov 16(HASH), E + mov 12(HASH), D + mov 0(HASH), A + + cmp $64, LEN // Check whether the upper-bit register is calculated. + jb .Lend_sha1_pre + sub $64, LEN + + mov C, TEMP + andn D, B, TEMP2 // TEMP2 = (~(b)) & (d) + and B, TEMP // TEMP=((b) & (c)) + or TEMP2, TEMP // TEMP = (((b) & (c)) | ((~(b)) & (d))) + rol $30, B // B = ROTL32(B, 30) + ROUND00_18 A, TEMP, B, C, D, E, %rsp, 16, TEMP1, TEMP2 + ROUND00_18 E, A, TEMP, B, C, D, %rsp, 20, TEMP1, TEMP2 + ROUND00_18 D, E, A, TEMP, B, C, %rsp, 24, TEMP1, TEMP2 + ROUND00_18 C, D, E, A, TEMP, B, %rsp, 28, TEMP1, TEMP2 // Round 3 + + ROUND00_18 B, C, D, E, A, TEMP, %rsp, 48, TEMP1, TEMP2 + ROUND00_18 TEMP, B, C, D, E, A, %rsp, 52, TEMP1, TEMP2 + ROUND00_18 A, TEMP, B, C, D, E, %rsp, 56, TEMP1, TEMP2 + ROUND00_18 E, A, TEMP, B, C, D, %rsp, 60, TEMP1, TEMP2 // Round 7 + + ROUND00_18 D, E, A, TEMP, B, C, %rsp, 80, TEMP1, TEMP2 + ROUND00_18 C, D, E, A, TEMP, B, %rsp, 84, TEMP1, TEMP2 + ROUND00_18 B, C, D, E, A, TEMP, %rsp, 88, TEMP1, TEMP2 + ROUND00_18 TEMP, B, C, D, E, A, %rsp, 92, TEMP1, TEMP2 // Round 11 + + ROUND00_18 A, TEMP, B, C, D, E, %rsp, 112, TEMP1, TEMP2 + ROUND00_18 E, A, TEMP, B, C, D, %rsp, 116, TEMP1, TEMP2 + ROUND00_18 D, E, A, TEMP, B, C, %rsp, 120, TEMP1, TEMP2 + ROUND00_18 C, D, E, A, TEMP, B, %rsp, 124, TEMP1, TEMP2 // Round 15 + + ROUND00_18 B, C, D, E, A, TEMP, %rsp, 144, TEMP1, TEMP2 + ROUND00_18 TEMP, B, C, D, E, A, %rsp, 148, TEMP1, TEMP2 + ROUND00_18 A, TEMP, B, C, D, E, %rsp, 152, TEMP1, TEMP2 // Round 18 + addl 156( %rsp), D // D = D + W + KT + rorx $27, E, TEMP2 // TEMP2 = ROTL32(E, 5) + addl A, D // D = F0 + D + W + KT + rorx $2, E, A // Round20 ROTL32(E, 30) + xor TEMP, E // Round20 (TEMP) ^ (E) + addl TEMP2, D // D = F0 + D + W + KT + S^5(E) + xor B, E // Round20 F1 + + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 176, TEMP1, TEMP2 + ROUND20_39 C, D, E, A, TEMP, B, %rsp, 180, TEMP1, TEMP2 + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 184, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 188, TEMP1, TEMP2 // Round 23 + + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 208, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 212, TEMP1, TEMP2 + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 216, TEMP1, TEMP2 + ROUND20_39 C, D, E, A, TEMP, B, %rsp, 220, TEMP1, TEMP2 // Round 27 + + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 240, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 244, TEMP1, TEMP2 + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 248, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 252, TEMP1, TEMP2 // Round 31 + + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 272, TEMP1, TEMP2 + ROUND20_39 C, D, E, A, TEMP, B, %rsp, 276, TEMP1, TEMP2 + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 280, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 284, TEMP1, TEMP2 // Round 35 + + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 304, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 308, TEMP1, TEMP2 + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 312, TEMP1, TEMP2 // Round 38 + addl 316(%rsp), B // B = B + W + KT + mov A, TEMP1 + addl D, B // B = F1 + B + W + KT + xor E, TEMP1 // Round40 (A^E) + rorx $2, C, D // Round40 ROTL32(C, 30) + rorx $27, C, TEMP2 // TEMP2 = ROTL32(C, 5) + xor E, C // Round40 (E^C) + addl TEMP2, B // B = F1 + B + W + KT + S^5(C) + and TEMP1, C // Round40 (A^E) & (E^C) + xor E, C // Round40 F2 + + ROUND40_59 B, C, D, E, A, TEMP, %rsp, 336, TEMP1, TEMP2 + ROUND40_59 TEMP, B, C, D, E, A, %rsp, 340, TEMP1, TEMP2 + ROUND40_59 A, TEMP, B, C, D, E, %rsp, 344, TEMP1, TEMP2 + ROUND40_59 E, A, TEMP, B, C, D, %rsp, 348, TEMP1, TEMP2 // Round 43 + + ROUND40_59 D, E, A, TEMP, B, C, %rsp, 368, TEMP1, TEMP2 + ROUND40_59 C, D, E, A, TEMP, B, %rsp, 372, TEMP1, TEMP2 + ROUND40_59 B, C, D, E, A, TEMP, %rsp, 376, TEMP1, TEMP2 + ROUND40_59 TEMP, B, C, D, E, A, %rsp, 380, TEMP1, TEMP2 // Round 47 + + ROUND40_59 A, TEMP, B, C, D, E, %rsp, 400, TEMP1, TEMP2 + ROUND40_59 E, A, TEMP, B, C, D, %rsp, 404, TEMP1, TEMP2 + ROUND40_59 D, E, A, TEMP, B, C, %rsp, 408, TEMP1, TEMP2 + ROUND40_59 C, D, E, A, TEMP, B, %rsp, 412, TEMP1, TEMP2 // Round 51 + + ROUND40_59 B, C, D, E, A, TEMP, %rsp, 432, TEMP1, TEMP2 + ROUND40_59 TEMP, B, C, D, E, A, %rsp, 436, TEMP1, TEMP2 + ROUND40_59 A, TEMP, B, C, D, E, %rsp, 440, TEMP1, TEMP2 + ROUND40_59 E, A, TEMP, B, C, D, %rsp, 444, TEMP1, TEMP2 // Round 55 + + ROUND40_59 D, E, A, TEMP, B, C, %rsp, 464, TEMP1, TEMP2 + ROUND40_59 C, D, E, A, TEMP, B, %rsp, 468, TEMP1, TEMP2 + ROUND40_59 B, C, D, E, A, TEMP, %rsp, 472, TEMP1, TEMP2 // Round 58 + addl 476(%rsp), A // A = A + W + KT + rorx $27, TEMP, TEMP2 // TEMP2 = ROTL32(TEMP, 5) + addl B, A // A = F2 + A + W + KT + rorx $2, TEMP, B // Round60 ROTL32(TEMP, 30) + xor C, TEMP // Round60 (TEMP) ^ (c) + addl TEMP2, A // A = F2 + A + W + KT + S^5(TEMP) + xor D, TEMP // Round60 F1 + + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 496, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 500, TEMP1, TEMP2 + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 504, TEMP1, TEMP2 + ROUND20_39 C, D, E, A, TEMP, B, %rsp, 508, TEMP1, TEMP2 // Round 63 + + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 528, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 532, TEMP1, TEMP2 + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 536, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 540, TEMP1, TEMP2 // Round 67 + + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 560, TEMP1, TEMP2 + ROUND20_39 C, D, E, A, TEMP, B, %rsp, 564, TEMP1, TEMP2 + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 568, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 572, TEMP1, TEMP2 // Round 71 + + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 592, TEMP1, TEMP2 + ROUND20_39 E, A, TEMP, B, C, D, %rsp, 596, TEMP1, TEMP2 + ROUND20_39 D, E, A, TEMP, B, C, %rsp, 600, TEMP1, TEMP2 + ROUND20_39 C, D, E, A, TEMP, B, %rsp, 604, TEMP1, TEMP2 // Round 75 + + ROUND20_39 B, C, D, E, A, TEMP, %rsp, 624, TEMP1, TEMP2 + ROUND20_39 TEMP, B, C, D, E, A, %rsp, 628, TEMP1, TEMP2 + ROUND20_39 A, TEMP, B, C, D, E, %rsp, 632, TEMP1, TEMP2 // Round 78 + addl 636(%rsp), D // D = D + W + KT + add E, 4(HASH) // Update HASH + add TEMP, 8(HASH) // Upadate H0~H5 + lea (A, D), D // D = F1 + D + W + KT + rorx $27, E, TEMP2 // TEMP2 = ROTL32(E, 5) + add B, 12(HASH) + add C, 16(HASH) + addl TEMP2, D // D = F1 + D + W + KT + S^5(E) + mov 4(HASH), B + mov 8(HASH), C + add D, 0(HASH) + mov 16(HASH), E + mov 12(HASH), D + mov 0(HASH), A + cmp $64, LEN + jae .Lloop_sha1_compress + +.Lend_sha1_pre: + mov %r14, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx +.Lend_sha1: + mov INPUT, %rax + ret + .cfi_endproc + .size SHA1_Step, .-SHA1_Step + +#endif diff --git a/crypto/sha1/src/noasm_sha1.c b/crypto/sha1/src/noasm_sha1.c new file mode 100644 index 00000000..753b85ba --- /dev/null +++ b/crypto/sha1/src/noasm_sha1.c @@ -0,0 +1,195 @@ +/* + * 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_SHA1 + +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "crypt_sha1.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/* e767 is because H is defined in SHA1 and MD5. +But the both the macros are different. So masked +this error */ + +#define K0 0x5A827999 +#define K1 0x6ED9EBA1 +#define K2 0x8F1BBCDC +#define K3 0xCA62C1D6 + +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) +#define F1(b, c, d) (((b) ^ (c)) ^ (d)) +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define F3(b, c, d) (((b) ^ (c)) ^ (d)) + +#define ROUND00_16(s, a, b, c, d, e, temp, w, Kt) \ + do { \ + (temp) = ROTL32(a, 5) + F##Kt(b, c, d) + (e) + (w)[s] + K##Kt; \ + (b) = ROTL32(b, 30); \ + } while (0) + +#define ROUND16_80(t, a, b, c, d, e, temp, w, Kt) \ + do { \ + (w)[(t) & 0xF] = ROTL32( \ + (w)[((t) + 13) & 0xF] ^ (w)[((t) + 8) & 0xF] ^ (w)[((t) + 2) & 0xF] ^ (w)[(t) & 0xF], 1); \ + ROUND00_16((t) & 0xF, a, b, c, d, e, temp, w, Kt); \ + } while (0) + +const uint8_t *SHA1_Step(const uint8_t *input, uint32_t len, uint32_t *h) +{ + uint32_t temp; + uint32_t w[16]; + const uint8_t *data = input; + uint32_t dataLen = len; + + while (dataLen >= CRYPT_SHA1_BLOCKSIZE) { + /* Convert data into 32 bits for calculation. */ + w[0] = GET_UINT32_BE(data, 0); + w[1] = GET_UINT32_BE(data, 4); + w[2] = GET_UINT32_BE(data, 8); + w[3] = GET_UINT32_BE(data, 12); + w[4] = GET_UINT32_BE(data, 16); + w[5] = GET_UINT32_BE(data, 20); + w[6] = GET_UINT32_BE(data, 24); + w[7] = GET_UINT32_BE(data, 28); + w[8] = GET_UINT32_BE(data, 32); + w[9] = GET_UINT32_BE(data, 36); + w[10] = GET_UINT32_BE(data, 40); + w[11] = GET_UINT32_BE(data, 44); + w[12] = GET_UINT32_BE(data, 48); + w[13] = GET_UINT32_BE(data, 52); + w[14] = GET_UINT32_BE(data, 56); + w[15] = GET_UINT32_BE(data, 60); + + uint32_t a = h[0]; + uint32_t b = h[1]; + uint32_t c = h[2]; + uint32_t d = h[3]; + uint32_t e = h[4]; + + // Required by referring to section 6.2 in rfc3174. To ensure performance, + // the variables A\b\c\d\e\TEMP are reused cyclically. + ROUND00_16(0, a, b, c, d, e, temp, w, 0); + ROUND00_16(1, temp, a, b, c, d, e, w, 0); + ROUND00_16(2, e, temp, a, b, c, d, w, 0); + ROUND00_16(3, d, e, temp, a, b, c, w, 0); + ROUND00_16(4, c, d, e, temp, a, b, w, 0); + ROUND00_16(5, b, c, d, e, temp, a, w, 0); + ROUND00_16(6, a, b, c, d, e, temp, w, 0); + ROUND00_16(7, temp, a, b, c, d, e, w, 0); + ROUND00_16(8, e, temp, a, b, c, d, w, 0); + ROUND00_16(9, d, e, temp, a, b, c, w, 0); + ROUND00_16(10, c, d, e, temp, a, b, w, 0); + ROUND00_16(11, b, c, d, e, temp, a, w, 0); + ROUND00_16(12, a, b, c, d, e, temp, w, 0); + ROUND00_16(13, temp, a, b, c, d, e, w, 0); + ROUND00_16(14, e, temp, a, b, c, d, w, 0); + ROUND00_16(15, d, e, temp, a, b, c, w, 0); + + ROUND16_80(16, c, d, e, temp, a, b, w, 0); + ROUND16_80(17, b, c, d, e, temp, a, w, 0); + ROUND16_80(18, a, b, c, d, e, temp, w, 0); + ROUND16_80(19, temp, a, b, c, d, e, w, 0); + + ROUND16_80(20, e, temp, a, b, c, d, w, 1); + ROUND16_80(21, d, e, temp, a, b, c, w, 1); + ROUND16_80(22, c, d, e, temp, a, b, w, 1); + ROUND16_80(23, b, c, d, e, temp, a, w, 1); + ROUND16_80(24, a, b, c, d, e, temp, w, 1); + ROUND16_80(25, temp, a, b, c, d, e, w, 1); + ROUND16_80(26, e, temp, a, b, c, d, w, 1); + ROUND16_80(27, d, e, temp, a, b, c, w, 1); + ROUND16_80(28, c, d, e, temp, a, b, w, 1); + ROUND16_80(29, b, c, d, e, temp, a, w, 1); + ROUND16_80(30, a, b, c, d, e, temp, w, 1); + ROUND16_80(31, temp, a, b, c, d, e, w, 1); + ROUND16_80(32, e, temp, a, b, c, d, w, 1); + ROUND16_80(33, d, e, temp, a, b, c, w, 1); + ROUND16_80(34, c, d, e, temp, a, b, w, 1); + ROUND16_80(35, b, c, d, e, temp, a, w, 1); + ROUND16_80(36, a, b, c, d, e, temp, w, 1); + ROUND16_80(37, temp, a, b, c, d, e, w, 1); + ROUND16_80(38, e, temp, a, b, c, d, w, 1); + ROUND16_80(39, d, e, temp, a, b, c, w, 1); + + ROUND16_80(40, c, d, e, temp, a, b, w, 2); + ROUND16_80(41, b, c, d, e, temp, a, w, 2); + ROUND16_80(42, a, b, c, d, e, temp, w, 2); + ROUND16_80(43, temp, a, b, c, d, e, w, 2); + ROUND16_80(44, e, temp, a, b, c, d, w, 2); + ROUND16_80(45, d, e, temp, a, b, c, w, 2); + ROUND16_80(46, c, d, e, temp, a, b, w, 2); + ROUND16_80(47, b, c, d, e, temp, a, w, 2); + ROUND16_80(48, a, b, c, d, e, temp, w, 2); + ROUND16_80(49, temp, a, b, c, d, e, w, 2); + ROUND16_80(50, e, temp, a, b, c, d, w, 2); + ROUND16_80(51, d, e, temp, a, b, c, w, 2); + ROUND16_80(52, c, d, e, temp, a, b, w, 2); + ROUND16_80(53, b, c, d, e, temp, a, w, 2); + ROUND16_80(54, a, b, c, d, e, temp, w, 2); + ROUND16_80(55, temp, a, b, c, d, e, w, 2); + ROUND16_80(56, e, temp, a, b, c, d, w, 2); + ROUND16_80(57, d, e, temp, a, b, c, w, 2); + ROUND16_80(58, c, d, e, temp, a, b, w, 2); + ROUND16_80(59, b, c, d, e, temp, a, w, 2); + + ROUND16_80(60, a, b, c, d, e, temp, w, 3); + ROUND16_80(61, temp, a, b, c, d, e, w, 3); + ROUND16_80(62, e, temp, a, b, c, d, w, 3); + ROUND16_80(63, d, e, temp, a, b, c, w, 3); + ROUND16_80(64, c, d, e, temp, a, b, w, 3); + ROUND16_80(65, b, c, d, e, temp, a, w, 3); + ROUND16_80(66, a, b, c, d, e, temp, w, 3); + ROUND16_80(67, temp, a, b, c, d, e, w, 3); + ROUND16_80(68, e, temp, a, b, c, d, w, 3); + ROUND16_80(69, d, e, temp, a, b, c, w, 3); + ROUND16_80(70, c, d, e, temp, a, b, w, 3); + ROUND16_80(71, b, c, d, e, temp, a, w, 3); + ROUND16_80(72, a, b, c, d, e, temp, w, 3); + ROUND16_80(73, temp, a, b, c, d, e, w, 3); + ROUND16_80(74, e, temp, a, b, c, d, w, 3); + ROUND16_80(75, d, e, temp, a, b, c, w, 3); + ROUND16_80(76, c, d, e, temp, a, b, w, 3); + ROUND16_80(77, b, c, d, e, temp, a, w, 3); + ROUND16_80(78, a, b, c, d, e, temp, w, 3); + ROUND16_80(79, temp, a, b, c, d, e, w, 3); + + // Let H0 = H0 + a, H1 = H1 + b, H2 = H2 + c, H3 = H3 + d, H4 = H4 + e. + // Because A, B, C, D and E are reused, after the last round of conversion, A = e, b = temp, c = a, d = b, e = c + h[0] += e; // H[0] += a + h[1] += temp; // H[1] += b + h[2] += a; // H[2] += c + h[3] += b; // H[3] += d + h[4] += c; // H[4] += e + + data += CRYPT_SHA1_BLOCKSIZE; + dataLen -= CRYPT_SHA1_BLOCKSIZE; + } + + return data; +} + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA1 diff --git a/crypto/sha1/src/sha1.c b/crypto/sha1/src/sha1.c new file mode 100644 index 00000000..f39935a5 --- /dev/null +++ b/crypto/sha1/src/sha1.c @@ -0,0 +1,224 @@ +/* + * 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_SHA1 + +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "sha1_core.h" +#include "bsl_sal.h" +#include "crypt_sha1.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/* e767 is because H is defined in SHA1 and MD5. +But the both the macros are different. So masked +this error */ + +int32_t CRYPT_SHA1_Init(CRYPT_SHA1_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_SHA1_Ctx), 0, sizeof(CRYPT_SHA1_Ctx)); + + /** + * RFC3174 6.1 Initialize the H constants of the input ctx + * These constants are provided by the standard + */ + ctx->h[0] = 0x67452301; + ctx->h[1] = 0xefcdab89; + ctx->h[2] = 0x98badcfe; + ctx->h[3] = 0x10325476; + ctx->h[4] = 0xc3d2e1f0; + return CRYPT_SUCCESS; +} + +void CRYPT_SHA1_Deinit(CRYPT_SHA1_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA1_Ctx)); +} + +int32_t CRYPT_SHA1_CopyCtx(CRYPT_SHA1_Ctx *dst, CRYPT_SHA1_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SHA1_Ctx), src, sizeof(CRYPT_SHA1_Ctx)); + return CRYPT_SUCCESS; +} + +static int32_t SHA1_CheckIsCorrupted(CRYPT_SHA1_Ctx *ctx, uint32_t textLen) +{ + uint32_t low = (ctx->lNum + (textLen << 3)) & 0xffffffffUL; + if (low < ctx->lNum) { /* overflow */ + if (++ctx->hNum == 0) { + ctx->errorCode = CRYPT_SHA1_INPUT_OVERFLOW; + BSL_ERR_PUSH_ERROR(CRYPT_SHA1_INPUT_OVERFLOW); + return CRYPT_SHA1_INPUT_OVERFLOW; + } + } + uint32_t high = ctx->hNum + (uint32_t)(textLen >> (32 - 3)); + if (high < ctx->hNum) { /* overflow */ + ctx->errorCode = CRYPT_SHA1_INPUT_OVERFLOW; + BSL_ERR_PUSH_ERROR(CRYPT_SHA1_INPUT_OVERFLOW); + return CRYPT_SHA1_INPUT_OVERFLOW; + } + ctx->hNum = high; + ctx->lNum = low; + + return CRYPT_SUCCESS; +} + +static int32_t SHA1_UpdateParamIsValid(CRYPT_SHA1_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + if ((ctx == NULL) || (data == NULL && nbytes != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->errorCode != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ctx->errorCode); + return ctx->errorCode; + } + + if (SHA1_CheckIsCorrupted(ctx, nbytes) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA1_INPUT_OVERFLOW); + return CRYPT_SHA1_INPUT_OVERFLOW; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA1_Update(CRYPT_SHA1_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + int32_t ret = SHA1_UpdateParamIsValid(ctx, in, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + const uint8_t *data = in; + uint32_t dataLen = len; + uint32_t start = ctx->count; + uint32_t left = CRYPT_SHA1_BLOCKSIZE - start; + + /* Check whether the user input data and cached data can form a block. */ + if (dataLen < left) { + (void)memcpy_s(&ctx->m[start], left, data, dataLen); + ctx->count += dataLen; + return CRYPT_SUCCESS; + } + + /* Preferentially process the buf data and form a block with the user input data. */ + if (start != 0) { + (void)memcpy_s(&ctx->m[start], left, data, left); + (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h); + dataLen -= left; + data += left; + ctx->count = 0; + } + + /* Cyclically process the input data */ + data = SHA1_Step(data, dataLen, ctx->h); + dataLen = len - (data - in); + + /* The remaining data is less than one block and stored in the buf. */ + if (dataLen != 0) { + (void)memcpy_s(ctx->m, CRYPT_SHA1_BLOCKSIZE, data, dataLen); + ctx->count = dataLen; + } + return CRYPT_SUCCESS; +} + +static int32_t SHA1_FinalParamIsValid(const CRYPT_SHA1_Ctx *ctx, const uint8_t *out, const uint32_t *outLen) +{ + if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (*outLen < CRYPT_SHA1_DIGESTSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH; + } + + if (ctx->errorCode != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ctx->errorCode); + return ctx->errorCode; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA1_Final(CRYPT_SHA1_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + int32_t ret = SHA1_FinalParamIsValid(ctx, out, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + uint32_t padLen; + uint32_t padPos; + /* Add "1" to the end of the user data */ + ctx->m[ctx->count] = 0x80; + ctx->count++; + + /* If here is one complete data block, one complete data block is processed first. */ + if (ctx->count == CRYPT_SHA1_BLOCKSIZE) { + (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h); + ctx->count = 0; + } + + /* Calculate the padding position. */ + padPos = ctx->count; + padLen = CRYPT_SHA1_BLOCKSIZE - padPos; + + if (padLen < 8) { /* 64 bits (8 bytes) of 512 bits are reserved to pad "0" */ + (void)memset_s(&ctx->m[padPos], padLen, 0, padLen); + padPos = 0; + padLen = CRYPT_SHA1_BLOCKSIZE; + (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h); + } + /* offset 8 bytes, reserved for storing the data length */ + (void)memset_s(&ctx->m[padPos], (padLen - 8), 0, (padLen - 8)); + PUT_UINT32_BE(ctx->hNum, ctx->m, 56); /* The 56th byte starts to store the upper 32-bit data. */ + PUT_UINT32_BE(ctx->lNum, ctx->m, 60); /* The 60th byte starts to store the lower 32-bit data. */ + (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h); + + PUT_UINT32_BE(ctx->h[0], out, 0); + PUT_UINT32_BE(ctx->h[1], out, 4); + PUT_UINT32_BE(ctx->h[2], out, 8); + PUT_UINT32_BE(ctx->h[3], out, 12); + PUT_UINT32_BE(ctx->h[4], out, 16); + *len = CRYPT_SHA1_DIGESTSIZE; + return CRYPT_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA1 diff --git a/crypto/sha1/src/sha1_core.h b/crypto/sha1/src/sha1_core.h new file mode 100644 index 00000000..b4bed7ee --- /dev/null +++ b/crypto/sha1/src/sha1_core.h @@ -0,0 +1,36 @@ +/* + * 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 SHA1_CORE_H +#define SHA1_CORE_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SHA1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const uint8_t *SHA1_Step(const uint8_t *input, uint32_t len, uint32_t *h); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA1 + +#endif // SHA1_CORE_H diff --git a/crypto/sha2/include/crypt_sha2.h b/crypto/sha2/include/crypt_sha2.h new file mode 100644 index 00000000..015fe8f9 --- /dev/null +++ b/crypto/sha2/include/crypt_sha2.h @@ -0,0 +1,456 @@ +/* + * 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_SHA2_H +#define CRYPT_SHA2_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SHA2 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +/** @defgroup LLF SHA2 Low level function */ + +#ifdef HITLS_CRYPTO_SHA224 +#define CRYPT_SHA2_224_BLOCKSIZE 64 +#define CRYPT_SHA2_224_DIGESTSIZE 28 +#endif // HITLS_CRYPTO_SHA224 + +#ifdef HITLS_CRYPTO_SHA256 +#define CRYPT_SHA2_256_BLOCKSIZE 64 +#define CRYPT_SHA2_256_DIGESTSIZE 32 +#endif // HITLS_CRYPTO_SHA256 + +#ifdef HITLS_CRYPTO_SHA384 +#define CRYPT_SHA2_384_BLOCKSIZE 128 +#define CRYPT_SHA2_384_DIGESTSIZE 48 +#endif // HITLS_CRYPTO_SHA384 + +#ifdef HITLS_CRYPTO_SHA512 +#define CRYPT_SHA2_512_BLOCKSIZE 128 +#define CRYPT_SHA2_512_DIGESTSIZE 64 +#endif // HITLS_CRYPTO_SHA512 + +#ifdef HITLS_CRYPTO_SHA256 +typedef struct { + uint32_t h[CRYPT_SHA2_256_DIGESTSIZE / sizeof(uint32_t)]; /* 256 bits for SHA256 state */ + uint32_t block[CRYPT_SHA2_256_BLOCKSIZE / sizeof(uint32_t)]; /* 512 bits block cache */ + uint32_t lNum, hNum; /* input bits counter, max 2^64 bits */ + uint32_t blocklen; /* block length */ + uint32_t outlen; /* digest output length */ + uint32_t errorCode; /* error Code */ +} CRYPT_SHA2_256_Ctx; +#endif // HITLS_CRYPTO_SHA256 + +#ifdef HITLS_CRYPTO_SHA224 +typedef CRYPT_SHA2_256_Ctx CRYPT_SHA2_224_Ctx; +#endif // HITLS_CRYPTO_SHA224 + +#ifdef HITLS_CRYPTO_SHA512 +typedef struct { + uint64_t h[CRYPT_SHA2_512_DIGESTSIZE / sizeof(uint64_t)]; + uint8_t block[CRYPT_SHA2_512_BLOCKSIZE]; + uint64_t lNum, hNum; + uint32_t num, mdlen; + uint32_t errorCode; /* error Code */ +} CRYPT_SHA2_512_Ctx; +#endif // HITLS_CRYPTO_SHA512 + +#ifdef HITLS_CRYPTO_SHA384 +typedef CRYPT_SHA2_512_Ctx CRYPT_SHA2_384_Ctx; +#endif // HITLS_CRYPTO_SHA384 + +#ifdef HITLS_CRYPTO_SHA224 +/** + * @defgroup CRYPT_SHA2_224_Init + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx) + * @endcode + * + * @par Purpose + * This is used to initialize the SHA224 ctx for a digest operation. + * + * @par Description + * CRYPT_SHA2_224_Init function initializes the ctx for a digest operation. This function must be called before + * CRYPT_SHA2_224_Update or CRYPT_SHA2_224_Final operations. This function will not allocate memory for any of the + * ctx variables. Instead the caller is expected to pass a ctx pointer pointing to a valid memory location + * (either locally or dynamically allocated). + * + * @param[in] ctx The sha224 ctx + * + * @retval #CRYPT_SUCCESS ctx is initialized + * @retval #CRYPT_NULL_INPUT ctx is NULL + */ +int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx); + +/** + * @defgroup CRYPT_SHA2_224_Update + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, usize_t nbytes) + * @endcode + * + * @par Purpose + * This is used to perform sha224 digest operation on chunks of data. + * + * @par Description + * CRYPT_SHA2_224_Update function performs digest operation on chunks of data. This method of digesting is used when + * data is present in multiple buffers or not available all at once. CRYPT_SHA2_224_Init must have been called before + * calling this function. + * + * @param[in] ctx The sha224 ctx + * @param[in] data The input data + * @param[in] nbytes The input data length + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow + */ +int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, uint32_t nbytes); + +/** + * @defgroup CRYPT_SHA2_224_Final + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len) + * @endcode + * + * @par Purpose + * This is used to complete sha224 digest operation on remaining data, and is + * called at the end of digest operation. + * + * @par Description + * CRYPT_SHA2_224_Final function completes digest operation on remaining data, and is called at the end of digest + * operation. CRYPT_SHA2_224_Init must have been called before calling this function. This function calculates the + * digest. The memory for digest must already have been allocated. + * + * @param[in] ctx The sha224 ctx + * @param[out] digest The digest + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow + * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough + */ +int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len); +#endif // HITLS_CRYPTO_SHA224 + +#ifdef HITLS_CRYPTO_SHA256 +/** + * @defgroup CRYPT_SHA2_256_Init + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx) + * @endcode + * + * @par Purpose + * This is used to initialize the SHA256 ctx for a digest operation. + * + * @par Description + * CRYPT_SHA2_256_Init function initializes the ctx for + * a digest operation. This function must be called before + * CRYPT_SHA2_256_Update or CRYPT_SHA2_256_Final operations. This function will not + * allocate memory for any of the ctx variables. Instead the caller is + * expected to pass a ctx pointer pointing to a valid memory location + * (either locally or dynamically allocated). + * + * @param[in] ctx The sha256 ctx + * + * @retval #CRYPT_SUCCESS ctx is initialized + * @retval #CRYPT_NULL_INPUT ctx is NULL + */ +int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx); + +/** + * @defgroup CRYPT_SHA2_256_Update + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, usize_t nbytes) + * @endcode + * + * @par Purpose + * This is used to perform sha256 digest operation on chunks of data. + * + * @par Description + * CRYPT_SHA2_256_Update function performs digest operation on + * chunks of data. This method of digesting is used when data is + * present in multiple buffers or not available all at once. + * CRYPT_SHA2_256_Init must have been called before calling this + * function. + * + * @param[in] ctx The sha256 ctx + * @param[in] data The input data + * @param[in] nbytes The input data length + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow + */ +int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes); + +/** + * @defgroup CRYPT_SHA2_256_Final + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *len) + * @endcode + * + * @par Purpose + * This is used to complete sha256 digest operation on remaining data, and is + * called at the end of digest operation. + * + * @par Description + * CRYPT_SHA2_256_Final function completes digest operation on remaining data, and + * is called at the end of digest operation. + * CRYPT_SHA2_256_Init must have been called before calling this function. This + * function calculates the digest. The memory for digest must + * already have been allocated. + * + * @param[in] ctx The sha256 ctx + * @param[out] digest The digest + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow + * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough + */ +int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *outlen); +#endif // HITLS_CRYPTO_SHA256 + +#ifdef HITLS_CRYPTO_SHA384 +/** + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx *ctx) + * @endcode + * + * @par Purpose + * This is used to initialize the SHA384 ctx for a digest operation. + * + * @par Description + * CRYPT_SHA2_384_Init function initializes the ctx for a digest operation. This function must be called before + * CRYPT_SHA2_384_Update or CRYPT_SHA2_384_Final operations. This function will not allocate memory for any of the + * ctx variables. Instead the caller is expected to pass a ctx pointer pointing to a valid memory location + * (either locally or dynamically allocated). + * + * @param[in,out] ctx The sha384 ctx + * + * @retval #CRYPT_SUCCESS ctx is initialized + * @retval #CRYPT_NULL_INPUT ctx is NULL + */ +int32_t CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx *ctx); + +/** + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx *ctx, const uint8_t *data, uint32_t nbytes) + * @endcode + * + * @par Purpose + * This is used to perform sha384 digest operation on chunks of data. + * + * @par Description + * CRYPT_SHA2_384_Update function performs digest operation on chunks of data. This method of digesting is used when + * data is present in multiple buffers or not available all at once. CRYPT_SHA2_384_Init must have been called before + * calling this function. + * + * @param[in,out] ctx The sha384 ctx + * @param[in] data The input data + * @param[in] nbytes The input data length + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow + * @retval #CRYPT_SECUREC_FAIL secure c function fail. + */ +int32_t CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx *ctx, const uint8_t *data, uint32_t nbytes); +/** + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx *ctx, uint8_t *digest, uint32_t *len) + * @endcode + * + * @par Purpose + * This is used to complete sha384 digest operation on remaining data, and is + * called at the end of digest operation. + * + * @par Description + * CRYPT_SHA2_384_Final function completes digest operation on remaining data, and is called at the end of digest + * operation. CRYPT_SHA2_384_Init must have been called before calling this function. This function calculates the + * digest. The memory for digest must already have been allocated. + * + * @param[in,out] ctx The sha384 ctx + * @param[out] digest The digest + * @param[in,out] len length of buffer + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow + * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough + */ +int32_t CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx *ctx, uint8_t *digest, uint32_t *len); +#endif // HITLS_CRYPTO_SHA384 + +#ifdef HITLS_CRYPTO_SHA512 +/** + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx *ctx) + * @endcode + * + * @par Purpose + * This is used to initialize the SHA512 ctx for a digest operation. + * + * @par Description + * CRYPT_SHA2_512_Init function initializes the ctx for a digest operation. This function must be called before + * CRYPT_SHA2_512_Update or CRYPT_SHA2_512_Final operations. This function will not allocate memory for any of the + * ctx variable. Instead the caller is expected to pass a ctx pointer pointing to a valid memory location + * (either locally or dynamically allocated). + * + * @param[in,out] ctx The sha512 ctx + * + * @retval #CRYPT_SUCCESS ctx is initialized + * @retval #CRYPT_NULL_INPUT ctx is NULL + */ +int32_t CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx *ctx); + +/** + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, usize_t nbytes) + * @endcode + * + * @par Purpose + * This is used to perform sha512 digest operation on chunks of data. + * + * @par Description + * CRYPT_SHA2_512_Update function performs digest operation on chunks of data. This method of digesting is used when + * data is present in multiple buffers or not available all at once. CRYPT_SHA2_512_Init must have been called before + * calling this function. + * + * @param[in,out] ctx The sha512 ctx + * @param[in] data The input data + * @param[in] nbytes The input data length + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow + * @retval #CRYPT_SECUREC_FAIL secure c function fail. + */ +int32_t CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, uint32_t nbytes); + +/** + * @ingroup LLF Low Level Functions + * @par Prototype + * @code + * int32_t CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx *ctx, uint8_t *digest, uint32_t *len) + * @endcode + * + * @par Purpose + * This is used to complete sha512 digest operation on remaining data, and is called at the end of digest operation. + * + * @par Description + * CRYPT_SHA2_512_Final function completes digest operation on remaining data, and is called at the end of digest + * operation. CRYPT_SHA2_512_Init must have been called before calling this function. This function calculates the + * digest. The memory for digest must already have been allocated. + * + * @param[in,out] ctx The sha512 ctx + * @param[out] digest The digest + * @param[in,out] len length of buffer + * + * @retval #CRYPT_SUCCESS If partial digest is calculated + * @retval #CRYPT_NULL_INPUT input arguments is NULL + * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow + * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough + */ +int32_t CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx *ctx, uint8_t *digest, uint32_t *len); +#endif // HITLS_CRYPTO_SHA512 + +#ifdef HITLS_CRYPTO_SHA224 +/** + * @ingroup LLF Low Level Functions + * + * @brief SHA224 deinit function + * + * @param[in,out] ctx The SHA224 ctx + */ +void CRYPT_SHA2_224_Deinit(CRYPT_SHA2_224_Ctx *ctx); + +int32_t CRYPT_SHA2_224_CopyCtx(CRYPT_SHA2_224_Ctx *dst, CRYPT_SHA2_224_Ctx *src); +#endif // HITLS_CRYPTO_SHA224 + +#ifdef HITLS_CRYPTO_SHA256 +/** + * @ingroup LLF Low Level Functions + * + * @brief SHA256 deinit function + * + * @param[in,out] ctx The SHA256 ctx + */ +void CRYPT_SHA2_256_Deinit(CRYPT_SHA2_256_Ctx *ctx); + +int32_t CRYPT_SHA2_256_CopyCtx(CRYPT_SHA2_256_Ctx *dst, CRYPT_SHA2_256_Ctx *src); +#endif // HITLS_CRYPTO_SHA256 + +#ifdef HITLS_CRYPTO_SHA384 +/** + * @ingroup LLF Low Level Functions + * + * @brief SHA384 deinit function + * + * @param[in,out] ctx The SHA384 ctx + */ +void CRYPT_SHA2_384_Deinit(CRYPT_SHA2_384_Ctx *ctx); + +int32_t CRYPT_SHA2_384_CopyCtx(CRYPT_SHA2_384_Ctx *dst, CRYPT_SHA2_384_Ctx *src); +#endif // HITLS_CRYPTO_SHA384 + +#ifdef HITLS_CRYPTO_SHA512 +/** + * @ingroup LLF Low Level Functions + * + * @brief SHA512 deinit function + * + * @param[in,out] ctx The SHA512 ctx + */ +void CRYPT_SHA2_512_Deinit(CRYPT_SHA2_512_Ctx *ctx); + +int32_t CRYPT_SHA2_512_CopyCtx(CRYPT_SHA2_512_Ctx *dst, CRYPT_SHA2_512_Ctx *src); +#endif // HITLS_CRYPTO_SHA512 + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA2 + +#endif // CRYPT_SHA2_H diff --git a/crypto/sha2/src/asm/sha2_256_armv8.S b/crypto/sha2/src/asm/sha2_256_armv8.S new file mode 100644 index 00000000..ac9ba2a4 --- /dev/null +++ b/crypto/sha2/src/asm/sha2_256_armv8.S @@ -0,0 +1,474 @@ +/* + * 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_SHA256 + +#include "crypt_arm.h" + + .arch armv8-a+crypto + +/* sha256 used constant value. For the data source, see the RFC4634 document. */ +.extern g_cryptArmCpuInfo +.hidden g_cryptArmCpuInfo +.section .rodata +.balign 64 +.K256: + .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 + .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 + .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da + .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 + .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 + .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 + .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 + .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + +/* + * Macro description: updates the 32-bit plaintext information. W + * Input register: + * wi_16: W[i-16] + * wi_15: W[i-15] + * wi_7: W[i-7] + * wi_2: W[i-2] + * Modify the register: wi_16 w17 w28 + * Output register: + * wi_16: Latest W[i] value, W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16] + * Function/Macro Call:None + */ + .macro UPDATE_W wi_16, wi_15, wi_7, wi_2 + ror w28, \wi_15, #7 + ror w17, \wi_2, #17 + eor w28, w28, \wi_15, ror#18 + eor w17, w17, \wi_2, ror#19 + eor w28, w28, \wi_15, lsr#3 // w28 = sigma0(w[i-15]) + eor w17, w17, \wi_2, lsr#10 // w17 = sigma1(W[i-2]) + add \wi_16, \wi_16, \wi_7 // + W[i-7] + add \wi_16, \wi_16, w28 // + sigma0(w[i-15]) + add \wi_16, \wi_16, w17 // + sigma1(W[i-2]) + .endm + +/* + * Macro description: Processes the update of a round of hash values in 64 rounds of compression. + * Input register: + * x19: Point to the address of the corresponding element in the g_k256 constant + * wi: Plaintext data after processing + * a - h: Intermediate variable of hash value + * Modify the register: h d w16 w17 w28 w29 + * Output register: + * h: Indicates the value after a cyclic update. + * d: Indicates the value after a cyclic update. + * Function/Macro Call:None + */ + .macro ONE_ROUND wi, a, b, c, d, e, f, g, h + ldr w16, [x19], #4 // K[i] + and w17, \f, \e // e&f + bic w28, \g, \e // g&(~e) + add \h, \h, w16 // h += K[i] + eor w29, \e, \e, ror#14 + ror w16, \e, #6 + orr w17, w17, w28 // Ch(e, f, g) = e&f | g&(~e) + add \h, \h, \wi // h += W[i] + eor w29, w16, w29, ror#11 // Sigma1(e) = ROR(e, 6) ^ ROR(e, 11) ^ ROR(e, 25) + eor w28, \a, \c // a^c + eor w16, \a, \b // a^b + add \h, \h, w29 // h += Sigma1(e) + and w28, w28, w16 // (a^b)&(a^c) + eor w29, \a, \a, ror#9 + add \h, \h, w17 // h += Ch(e, f, g) + eor w28, w28, \a // Maj(a, b, c) = ((a^b)&(a^c))^a = (a&b)^(b&c)^(a&c) + ror w16, \a, #2 + add \d, \d, \h // d += h + add \h, \h, w28 // h += Maj(a, b, c) + eor w29, w16, w29, ror#13 // Sigma0(a) = ROR(a, 2)^ROR(a, 13)^ROR(a, 22) + add \h, \h, w29 // h += Sigma0(a) + .endm + +/* + * Function Description:Performs 64 rounds of compression calculation based on the input plaintext data + * and updates the hash value. + * Function prototype:void SHA256CompressMultiBlocks(uint32_t hash[8], const uint8_t *in, uint32_t num); + * Input register: + * x0: Storage address of the hash value + * x1: Pointer to the input data address + * x2: Number of 64 rounds of cycles + * Modify the register: x0-x17 + * Output register: None + * Function/Macro Call: None + * + */ + .text + .balign 16 + .global SHA256CompressMultiBlocks + .type SHA256CompressMultiBlocks, %function +SHA256CompressMultiBlocks: + cbz x2, .Lend_sha256 + /* If the SHA256 cryptography extension instruction is supported, go to. */ + adrp x5, g_cryptArmCpuInfo + ldr w6, [x5, #:lo12:g_cryptArmCpuInfo] + tst w6, #CRYPT_ARM_SHA256 + bne SHA256CryptoExt + /* Extension instructions are not supported. Base instructions are used. */ + stp x29, x30, [sp, #-112]! + add x29, sp, #0 + stp x19, x20, [sp, #8*2] + stp x21, x22, [sp, #8*4] + stp x23, x24, [sp, #8*6] + stp x25, x26, [sp, #8*8] + stp x27, x28, [sp, #8*10] + + /* load a - h */ + ldp w20, w21, [x0] + ldp w22, w23, [x0, #4*2] + ldp w24, w25, [x0, #4*4] + ldp w26, w27, [x0, #4*6] + + str x0, [sp, #96] + mov x16, x1 // Enter Value Address + lsl x30, x2, #6 // Number of times to process 2^6 = 64 + + /* w0-w15 are used to record input values W[i] and temporary registers */ +.Lloop_compress_64: + + /* Start a 64-round process */ + sub x30, x30, #16 + adrp x19, .K256 + add x19, x19, :lo12:.K256 + /* 8 bytes are loaded each time, and then two rounds are processed. */ + ldp w0, w1, [x16] // load input value + ldp w2, w3, [x16, #4*2] + ldp w4, w5, [x16, #4*4] + ldp w6, w7, [x16, #4*6] + ldp w8, w9, [x16, #4*8] + ldp w10, w11, [x16, #4*10] + ldp w12, w13, [x16, #4*12] + ldp w14, w15, [x16, #4*14] + + add x16, x16, #64 + str x16, [sp, #104] +#ifndef HITLS_BIG_ENDIAN + rev w0, w0 + rev w1, w1 + rev w2, w2 + rev w3, w3 + rev w4, w4 + rev w5, w5 + rev w6, w6 + rev w7, w7 + rev w8, w8 + rev w9, w9 + rev w10, w10 + rev w11, w11 + rev w12, w12 + rev w13, w13 + rev w14, w14 + rev w15, w15 +#endif + /* w16 w17 w28 w29 used as a temporary register */ + ONE_ROUND w0, w20, w21, w22, w23, w24, w25, w26, w27 + ONE_ROUND w1, w27, w20, w21, w22, w23, w24, w25, w26 + ONE_ROUND w2, w26, w27, w20, w21, w22, w23, w24, w25 + ONE_ROUND w3, w25, w26, w27, w20, w21, w22, w23, w24 + + ONE_ROUND w4, w24, w25, w26, w27, w20, w21, w22, w23 + ONE_ROUND w5, w23, w24, w25, w26, w27, w20, w21, w22 + ONE_ROUND w6, w22, w23, w24, w25, w26, w27, w20, w21 + ONE_ROUND w7, w21, w22, w23, w24, w25, w26, w27, w20 + + ONE_ROUND w8, w20, w21, w22, w23, w24, w25, w26, w27 + ONE_ROUND w9, w27, w20, w21, w22, w23, w24, w25, w26 + ONE_ROUND w10, w26, w27, w20, w21, w22, w23, w24, w25 + ONE_ROUND w11, w25, w26, w27, w20, w21, w22, w23, w24 + + ONE_ROUND w12, w24, w25, w26, w27, w20, w21, w22, w23 + ONE_ROUND w13, w23, w24, w25, w26, w27, w20, w21, w22 + ONE_ROUND w14, w22, w23, w24, w25, w26, w27, w20, w21 + ONE_ROUND w15, w21, w22, w23, w24, w25, w26, w27, w20 + +.Lloop_compress_16_63: + /* Start 16-31, 32-47, 48-63 compression */ + sub x30, x30, #16 + + /* 0 */ + UPDATE_W w0, w1, w9, w14 + ONE_ROUND w0, w20, w21, w22, w23, w24, w25, w26, w27 + + /* 1 */ + UPDATE_W w1, w2, w10, w15 + ONE_ROUND w1, w27, w20, w21, w22, w23, w24, w25, w26 + + /* 2 */ + UPDATE_W w2, w3, w11, w0 + ONE_ROUND w2, w26, w27, w20, w21, w22, w23, w24, w25 + + /* 3 */ + UPDATE_W w3, w4, w12, w1 + ONE_ROUND w3, w25, w26, w27, w20, w21, w22, w23, w24 + + /* 4 */ + UPDATE_W w4, w5, w13, w2 + ONE_ROUND w4, w24, w25, w26, w27, w20, w21, w22, w23 + + /* 5 */ + UPDATE_W w5, w6, w14, w3 + ONE_ROUND w5, w23, w24, w25, w26, w27, w20, w21, w22 + + /* 6 */ + UPDATE_W w6, w7, w15, w4 + ONE_ROUND w6, w22, w23, w24, w25, w26, w27, w20, w21 + + /* 7 */ + UPDATE_W w7, w8, w0, w5 + ONE_ROUND w7, w21, w22, w23, w24, w25, w26, w27, w20 + + /* 8 */ + UPDATE_W w8, w9, w1, w6 + ONE_ROUND w8, w20, w21, w22, w23, w24, w25, w26, w27 + + /* 9 */ + UPDATE_W w9, w10, w2, w7 + ONE_ROUND w9, w27, w20, w21, w22, w23, w24, w25, w26 + + /* 10 */ + UPDATE_W w10, w11, w3, w8 + ONE_ROUND w10, w26, w27, w20, w21, w22, w23, w24, w25 + + /* 11 */ + UPDATE_W w11, w12, w4, w9 + ONE_ROUND w11, w25, w26, w27, w20, w21, w22, w23, w24 + + /* 12 */ + UPDATE_W w12, w13, w5, w10 + ONE_ROUND w12, w24, w25, w26, w27, w20, w21, w22, w23 + + /* 13 */ + UPDATE_W w13, w14, w6, w11 + ONE_ROUND w13, w23, w24, w25, w26, w27, w20, w21, w22 + + /* 14 */ + UPDATE_W w14, w15, w7, w12 + ONE_ROUND w14, w22, w23, w24, w25, w26, w27, w20, w21 + + /* 15 */ + UPDATE_W w15, w0, w8, w13 + ONE_ROUND w15, w21, w22, w23, w24, w25, w26, w27, w20 + + /* If the processing length is less than 64 bytes, the loop continues. */ + tst x30, #63 + bne .Lloop_compress_16_63 + + /* Stores a - h information. */ + ldr x0, [sp, #96] + + ldp w10, w11, [x0] + ldp w12, w13, [x0, #4*2] + ldp w14, w15, [x0, #4*4] + ldp w16, w17, [x0, #4*6] + + add w20, w20, w10 + add w21, w21, w11 + add w22, w22, w12 + add w23, w23, w13 + stp w20, w21, [x0] + add w24, w24, w14 + add w25, w25, w15 + stp w22, w23, [x0, #4*2] + add w26, w26, w16 + add w27, w27, w17 + stp w24, w25, [x0, #4*4] + stp w26, w27, [x0, #4*6] + + ldr x16, [sp, #104] + /* If the remaining length is not processed, the processing continues for 64 rounds. */ + cbnz x30, .Lloop_compress_64 + + /* The function returns */ + ldp x19, x20, [sp, #8*2] + ldp x21, x22, [sp, #8*4] + ldp x23, x24, [sp, #8*6] + ldp x25, x26, [sp, #8*8] + ldp x27, x28, [sp, #8*10] + ldp x29, x30, [sp], #112 +.Lend_sha256: + ret + .size SHA256CompressMultiBlocks, .-SHA256CompressMultiBlocks + +/* + * Function Description:Performs 64 rounds of compression calculation based on the input plaintext data + * and updates the hash value + * Function prototype:void SHA256CryptoExt(uint32_t hash[8], const uint8_t *in, uint32_t num); + * Input register: + * x0: Storage address of the hash value + * x1: Pointer to the input data address + * x2: Number of 64 rounds of cycles + * Modify the register: x1-x4, v0-v5, v16-v23 + * Output register: None + * Function/Macro Call: None + * + */ + .text + .balign 16 + .type SHA256CryptoExt, %function +SHA256CryptoExt: + ld1 {v4.4s-v5.4s}, [x0] +.Lloop_compress_64_ext: + adrp x4, .K256 + add x4, x4, :lo12:.K256 + sub x2, x2, #1 + /* 0-15 */ + ld1 {v16.16b-v19.16b}, [x1], #64 + + mov v0.16b, v4.16b + mov v1.16b, v5.16b + + rev32 v16.16b, v16.16b + ld1 {v20.4s}, [x4], #16 + rev32 v17.16b, v17.16b + ld1 {v21.4s}, [x4], #16 + rev32 v18.16b, v18.16b + ld1 {v22.4s}, [x4], #16 + + add v20.4s, v20.4s, v16.4s + + rev32 v19.16b, v19.16b + ld1 {v23.4s}, [x4], #16 + + sha256su0 v16.4s, v17.4s + mov v2.16b, v0.16b + sha256h q0, q1, v20.4s + sha256h2 q1, q2, v20.4s + add v21.4s, v21.4s, v17.4s + sha256su1 v16.4s, v18.4s, v19.4s + ld1 {v20.4s}, [x4], #16 + + sha256su0 v17.4s, v18.4s + mov v3.16b, v0.16b + sha256h q0, q1, v21.4s + sha256h2 q1, q3, v21.4s + add v22.4s, v22.4s, v18.4s + sha256su1 v17.4s, v19.4s, v16.4s + ld1 {v21.4s}, [x4], #16 + + sha256su0 v18.4s, v19.4s + mov v2.16b, v0.16b + sha256h q0, q1, v22.4s + sha256h2 q1, q2, v22.4s + add v23.4s, v23.4s, v19.4s + sha256su1 v18.4s, v16.4s, v17.4s + ld1 {v22.4s}, [x4], #16 + + sha256su0 v19.4s, v16.4s + mov v3.16b, v0.16b + sha256h q0, q1, v23.4s + sha256h2 q1, q3, v23.4s + add v20.4s, v20.4s, v16.4s + sha256su1 v19.4s, v17.4s, v18.4s + ld1 {v23.4s}, [x4], #16 + + /* 16-31 */ + sha256su0 v16.4s, v17.4s + mov v2.16b, v0.16b + sha256h q0, q1, v20.4s + sha256h2 q1, q2, v20.4s + add v21.4s, v21.4s, v17.4s + sha256su1 v16.4s, v18.4s, v19.4s + ld1 {v20.4s}, [x4], #16 + + sha256su0 v17.4s, v18.4s + mov v3.16b, v0.16b + sha256h q0, q1, v21.4s + sha256h2 q1, q3, v21.4s + add v22.4s, v22.4s, v18.4s + sha256su1 v17.4s, v19.4s, v16.4s + ld1 {v21.4s}, [x4], #16 + + mov v2.16b, v0.16b + sha256su0 v18.4s, v19.4s + sha256h q0, q1, v22.4s + sha256h2 q1, q2, v22.4s + add v23.4s, v23.4s, v19.4s + sha256su1 v18.4s, v16.4s, v17.4s + ld1 {v22.4s}, [x4], #16 + + sha256su0 v19.4s, v16.4s + mov v3.16b, v0.16b + sha256h q0, q1, v23.4s + sha256h2 q1, q3, v23.4s + add v20.4s, v20.4s, v16.4s + sha256su1 v19.4s, v17.4s, v18.4s + ld1 {v23.4s}, [x4], #16 + + /* 32-47 */ + sha256su0 v16.4s, v17.4s + mov v2.16b, v0.16b + sha256h q0, q1, v20.4s + sha256h2 q1, q2, v20.4s + add v21.4s, v21.4s, v17.4s + sha256su1 v16.4s, v18.4s, v19.4s + ld1 {v20.4s}, [x4], #16 + + sha256su0 v17.4s, v18.4s + mov v3.16b, v0.16b + sha256h q0, q1, v21.4s + sha256h2 q1, q3, v21.4s + add v22.4s, v22.4s, v18.4s + + sha256su1 v17.4s, v19.4s, v16.4s + ld1 {v21.4s}, [x4], #16 + + sha256su0 v18.4s, v19.4s + mov v2.16b, v0.16b + sha256h q0, q1, v22.4s + sha256h2 q1, q2, v22.4s + add v23.4s, v23.4s, v19.4s + sha256su1 v18.4s, v16.4s, v17.4s + ld1 {v22.4s}, [x4], #16 + + + sha256su0 v19.4s, v16.4s + mov v3.16b, v0.16b + sha256h q0, q1, v23.4s + sha256h2 q1, q3, v23.4s + add v20.4s, v20.4s, v16.4s + sha256su1 v19.4s, v17.4s, v18.4s + ld1 {v23.4s}, [x4], #16 + /* 48-63 */ + mov v2.16b, v0.16b + sha256h q0, q1, v20.4s + add v21.4s, v21.4s, v17.4s + sha256h2 q1, q2, v20.4s + + mov v3.16b, v0.16b + sha256h q0, q1, v21.4s + add v22.4s, v22.4s, v18.4s + sha256h2 q1, q3, v21.4s + + mov v2.16b, v0.16b + sha256h q0, q1, v22.4s + add v23.4s, v23.4s, v19.4s + sha256h2 q1, q2, v22.4s + + mov v3.16b, v0.16b + sha256h q0, q1, v23.4s + sha256h2 q1, q3, v23.4s + /* Add the original hash value */ + add v4.4s, v4.4s, v0.4s + add v5.4s, v5.4s, v1.4s + cbnz x2, .Lloop_compress_64_ext + + /* Output result */ + st1 {v4.4s-v5.4s}, [x0] + ret + .size SHA256CryptoExt, .-SHA256CryptoExt +#endif diff --git a/crypto/sha2/src/asm/sha2_256_x86_64.S b/crypto/sha2/src/asm/sha2_256_x86_64.S new file mode 100644 index 00000000..cd306cc6 --- /dev/null +++ b/crypto/sha2/src/asm/sha2_256_x86_64.S @@ -0,0 +1,645 @@ +/* + * 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_SHA256 + +.file "sha2_256_x86_64.S" + +.set HashAddr, %rdi +.set InAddr, %rsi +.set NUM, %rdx + +.set tempFirst, %ebp +.set tempThird, %ebx +.set tempFifth, %edi +.set avx2Temp1, %ymm4 +.set avx2Temp2, %ymm5 +.set avx2Temp3, %ymm6 +.set avx2Temp4, %ymm7 +.set avx2Temp5, %ymm10 +.set avx2Temp6, %ymm11 +.set avx2Temp7, %ymm15 + +.set BlockFrontMessageW3_0, %xmm0 +.set BlockFrontMessageW7_4, %xmm1 +.set BlockFrontMessageW11_8, %xmm2 +.set BlockFrontMessageW15_12, %xmm3 + +.set g_maskMerge, %ymm12 +.set g_maskShift, %ymm13 +.set g_maskTransformEndian, %ymm14 + +/* Constant value used by sha256. For details about the data source, see the RFC4634 document. */ +.section .rodata +.align 64 +.type g_K256, %object +g_K256: + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.size g_K256, .-g_K256 + +/* Mask block */ +.balign 64 +.type g_mask, %object +g_mask: + .long 0x00010203,0x04050607, 0x08090a0b,0x0c0d0e0f + .long 0x00010203,0x04050607, 0x08090a0b,0x0c0d0e0f + .long 0x03020100,0x0b0a0908, 0xffffffff,0xffffffff + .long 0x03020100,0x0b0a0908, 0xffffffff,0xffffffff + .long 0xffffffff,0xffffffff, 0x03020100,0x0b0a0908 + .long 0xffffffff,0xffffffff, 0x03020100,0x0b0a0908 +.size g_mask, .-g_mask + +/* + * Macro description: Processes the fast extension of four messages of two blocks at the same time + * and completes the four-round compression function of the first block. + * Input register: + * WkAddr: Address of the stack space where wi+kt is located. + * a - h: Intermediate variable of hash value + * Modify the register: r8d-r15d, ebp, eax, ebx, ecx, edi, ymm0-ymm10 + * Output register: + * a-h: Value after four rounds of cyclic update + * B3_0: Value after data extension + * Naming convention: + * B3_0: w3-w0 + * B7_4: w7-w4 + * B11_8: w11-w8 + * B15_12: w15-w12 + * Function/Macro Call:None + * Implementation Description: + * ONE_ROUND algorithm implementation: + * For t = 0 to 63, T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + * T2 = BSIG0(a) + MAJ(a,b,c) + * h = g, g = f, f = e, e = d + T1, d = c, c = b, b = a, a = T1 + T2 + * CH( x, y, z) = (x AND y) XOR ( (NOT x) AND z) CH(e,f,g) + * MAJ(a, b, c) = (a AND b) XOR (a AND c) XOR (b AND c) + * = CH(a^b, c, b) + * = ((a XOR b) AND c) XOR ((NOT(a XOR b)) AND b) + * = (b XOR c) AND (a XOR b) XOR b + * BSIG0(x) = ROTR^2(x) XOR ROTR^13(x) XOR ROTR^22(x) BSIG0(a) + * BSIG1(x) = ROTR^6(x) XOR ROTR^11(x) XOR ROTR^25(x) BSIG1(e) + * Optimization idea: b xor c in the next round of MAJ is a xor b in the previous round of MAJ + * to avoid redundant calculation. + * + * UPDATE_4W algorithm implementation: + * For t = 0 to 15 Wt = W0_W15(input w0-w15) + * For t = 16 to 63 Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(w(t-15)) + W(t-16) + * SSIG0(x) = ROTR^7(x) XOR ROTR^18(x) XOR SHR^3(x) + * SSIG1(x) = ROTR^17(x) XOR ROTR^19(x) XOR SHR^10(x) + * Optimization idea: Optimization point 1: Each WI message block is 32-bit, and the xmm register is + * a 128-bit register. Therefore, the common operation of four WI messages can be + * performed at the same time (SSIG0, W(t-16), W(t-7)). + * Due to the dependency of wi, four wis are calculated each time as the + * optimal solution found so far. + * Optimization point 2: The ymm register is a 256-bit register. Therefore, two rounds + * of 128-bit calculation can be performed at the same time, and two blocks can be used + * for the same calculation. + */ +.macro FOUR_ROUND_UPDATE_4W a, b, c, d, e, f, g, h, tempSwitch2, tempSwitch4, WkAddr, B3_0, B7_4, B11_8, B15_12 + vpalignr $4,\B3_0,\B7_4,avx2Temp1 // avx2Temp1->w4_1 + add \WkAddr(%rsp),\h // h += Kt + Wt + and \e, tempFifth // e&f + rorx $6, \e, \tempSwitch2 // ROTR^6(e) + add tempFirst, \a // a += BSIG0(a) from last round + rorx $11, \e, tempThird // ROTR^11(e) + andn \g, \e, tempFirst // (~e)&g + xor \tempSwitch2, tempThird // ROTR^6(e) ^ ROTR^11(e) + xor tempFirst, tempFifth // CH(e,f,g) + vpshufd $250, \B15_12, avx2Temp5 + rorx $25, \e, \tempSwitch2 // ROTR^25(e) + add tempFifth, \h // h += CH(e,f,g) + xor \tempSwitch2, tempThird // BSIG1(e) + vpalignr $4, \B11_8, \B15_12, avx2Temp2 // avx2Temp2->w12_9 + vpslld $14, avx2Temp1, avx2Temp4 // w4_1<T1] + vpsrld $3, avx2Temp1, avx2Temp3 // w4_1>>datum line 3 + rorx $13, \a, tempFifth // ROTR^13(a) + xor \b, \tempSwitch2 // b^a for next round b^c + add \h, \d // d += T1 + vpsrld $10, avx2Temp5, avx2Temp6 // >>10 + xor tempFifth, tempFirst // ROTR^2(a) ^ ROTR^13(a) + and \tempSwitch2, \tempSwitch4 // (b^a) & (b^c) + vpsrld $7, avx2Temp1, avx2Temp1 // >>7 + vpaddd avx2Temp2, \B3_0, \B3_0 + rorx $22, \a, tempThird // ROTR^22(a) + add 4+\WkAddr(%rsp),\g // h += Kt + Wt + xor \b, \tempSwitch4 // Maj(a,b,c) + vpxor avx2Temp3, avx2Temp4, avx2Temp3 // 3 xor 14 + mov \e, tempFifth // for next round f + xor tempThird, tempFirst // BSIG0(a) + vpsrlq $17, avx2Temp5, avx2Temp7 // >>17 + add \tempSwitch4, \h // h += Maj(a,b,c) + and \d, tempFifth // e&f + rorx $6, \d, \tempSwitch4 + add tempFirst, \h // a += BSIG0(a) from last round + vpxor avx2Temp3, avx2Temp1, avx2Temp3 // 7xor14xor3 + vpsrlq $19, avx2Temp5, avx2Temp5 // >>19 + rorx $11, \d, tempThird + andn \f, \d, tempFirst + xor \tempSwitch4, tempThird + vpsrld $11, avx2Temp1, avx2Temp1 // >>18 + xor tempFirst, tempFifth + rorx $25, \d, \tempSwitch4 + add tempFifth, \g + xor \tempSwitch4, tempThird + vpslld $11, avx2Temp4, avx2Temp4 // <<25 + rorx $2, \h, tempFirst + mov \h, \tempSwitch4 + add tempThird, \g + rorx $13, \h,tempFifth + xor \a, \tempSwitch4 + vpxor avx2Temp7, avx2Temp6, avx2Temp7 // 17xor10 + add \g, \c + xor tempFifth, tempFirst + vpxor avx2Temp3, avx2Temp1, avx2Temp3 // 7xor14xor3xor18 + and \tempSwitch4, \tempSwitch2 + rorx $22, \h, tempThird + add 8+\WkAddr(%rsp),\f + xor \a, \tempSwitch2 + vpxor avx2Temp7, avx2Temp5, avx2Temp7 // 17xor10xor19 + mov \d, tempFifth + xor tempThird, tempFirst + add \tempSwitch2, \g + vpshufb g_maskMerge, avx2Temp7, avx2Temp7 // BSIG1 w15_14 + vpxor avx2Temp3, avx2Temp4, avx2Temp3 // 7xor14xor3xor18xor25 + and \c, tempFifth + rorx $6, \c, \tempSwitch2 + add tempFirst, \g + rorx $11, \c, tempThird + vpaddd avx2Temp3, \B3_0, \B3_0 // BSIG0+w(t-16)+w(t-7) + andn \e, \c, tempFirst + xor \tempSwitch2, tempThird + xor tempFirst, tempFifth + rorx $25, \c, \tempSwitch2 + add tempFifth, \f + xor \tempSwitch2, tempThird + rorx $2, \g, tempFirst + mov \g, \tempSwitch2 + add tempThird, \f + rorx $13, \g, tempFifth + vpaddd \B3_0, avx2Temp7, \B3_0 // w17_16 + xor \h, \tempSwitch2 + add \f, \b + xor tempFifth, tempFirst + and \tempSwitch2, \tempSwitch4 + vpshufd $80, \B3_0, avx2Temp1 + rorx $22, \g, tempThird + add 12+\WkAddr(%rsp),\e + xor \h, \tempSwitch4 + mov \c, tempFifth + xor tempThird, tempFirst + add \tempSwitch4, \f + vpsrld $10, avx2Temp1, avx2Temp2 // >>10 + and \b, tempFifth + rorx $6, \b, \tempSwitch4 + vpsrlq $17, avx2Temp1, avx2Temp3 // >>17 + add tempFirst, \f + rorx $11, \b, tempThird + andn \d, \b, tempFirst + xor \tempSwitch4, tempThird + vpsrlq $19,avx2Temp1, avx2Temp1 // >>19 + xor tempFirst, tempFifth + rorx $25, \b, \tempSwitch4 + add tempFifth, \e + xor \tempSwitch4, tempThird + vpxor avx2Temp2, avx2Temp3, avx2Temp3 // 10xor17 + rorx $2, \f, tempFirst + mov \f, \tempSwitch4 + add tempThird, \e + rorx $13, \f, tempFifth + xor \g, \tempSwitch4 + vpxor avx2Temp3, avx2Temp1, avx2Temp3 // 10xor17xor19 + add \e, \a + xor tempFifth, tempFirst + and \tempSwitch4, \tempSwitch2 + rorx $22, \f, tempThird + vpshufb g_maskShift, avx2Temp3, avx2Temp3 // BSIG1(W17_16)Move to the desired location + xor \g, \tempSwitch2 + mov \b, tempFifth + xor tempThird, tempFirst + add \tempSwitch2, \e + vpaddd avx2Temp3, \B3_0, \B3_0 // W19_16 +.endm + +/* + * Macro description: Processes the update of a round of hash values in 64 rounds of compression. + * Input register: + * wkAddr: wi+kt Stack space address. + * a - h: Intermediate variable of hash value + * Modify the register: r8d-r15d, ebp, eax, ebx, ecx, edi + * Output register: + * a-h: Indicates the value after a cyclic update. + * Function/Macro Call:None + * ONE_ROUND Algorithm Implementation: + * For t = 0 to 63, T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + * T2 = BSIG0(a) + MAJ(a,b,c) + * h = g, g = f, f = e, e = d + T1, d = c, c = b, b = a, a = T1 + T2 + * CH( x, y, z) = (x AND y) XOR ( (NOT x) AND z) CH(e,f,g) + * MAJ(a, b, c) = (a AND b) XOR (a AND c) XOR (b AND c) + * = CH(a^b, c, b) + * = ((a XOR b) AND c) XOR ((NOT(a XOR b)) AND b) + * = (b XOR c) AND (a XOR b) XOR b + * BSIG0(x) = ROTR^2(x) XOR ROTR^13(x) XOR ROTR^22(x) BSIG0(a) + * BSIG1(x) = ROTR^6(x) XOR ROTR^11(x) XOR ROTR^25(x) BSIG1(e) + * Optimization idea: b xor c in the next round of MAJ is a xor b in the + * previous round of MAJ to avoid redundant calculation. + * Note: At the end of each round, the tempSwitch2 and tempSwitch4 of the next round need to be exchanged. + */ + .macro ONE_ROUND a, b, c, d, e, f, g, h, tempSwitch2, tempSwitch4, WkAddr + rorx $11, \e, tempThird // ROTR^11(e) + rorx $6, \e, \tempSwitch2 // ROTR^6(e) + add tempFirst, \a // a += BSIG0(a) from last round + and \e, tempFifth // e&f + andn \g, \e, tempFirst // (~e)&g + xor \tempSwitch2, tempThird // ROTR^6(e) ^ ROTR^11(e) + add \WkAddr(%rsp),\h // h += Kt + Wt + xor tempFirst, tempFifth // CH(e,f,g) + rorx $25, \e, \tempSwitch2 // ROTR^25(e) + add tempFifth, \h // h += CH(e,f,g) + xor \tempSwitch2, tempThird // BSIG1(e) + rorx $2, \a, tempFirst // ROTR^2(a) + mov \a, \tempSwitch2 // a + leal (tempThird, \h), \h // h += BSIG1(e)[h->T1] + rorx $13, \a, tempFifth // ROTR^13(a) + xor \b, \tempSwitch2 // b^a for next round b^c + add \h, \d // d += T1 + xor tempFifth, tempFirst // ROTR^2(a) ^ ROTR^13(a) + and \tempSwitch2, \tempSwitch4 // (b^a) & (b^c) + rorx $22, \a, tempThird // ROTR^22(a) + xor \b, \tempSwitch4 // Maj(a,b,c) + mov \e, tempFifth // for next round f + xor tempThird, tempFirst // BSIG0(a) + add \tempSwitch4, \h // h += Maj(a,b,c) + .endm + +/* + * Function description: Performs 64 rounds of compression calculation based on the input plaintext data and updates the hash value. + * function prototype:void SHA256CompressMultiBlocks(uint32_t hash[8], const uint8_t *in, uint32_t num); + * Input register: + * rdi: Storage address of the hash value + * rsi: Pointer to the input data address (Wi) + * rdx: Number of 64 rounds of cycles. (You need to do several blocks, that is, you need to do several loops.) + * Modify the register: r0-r14 + * Output register: None + * Function/Macro Call: None + */ +.text +.globl SHA256CompressMultiBlocks +.type SHA256CompressMultiBlocks,%function +.align 4 +SHA256CompressMultiBlocks: +.cfi_startproc + /* Determine whether to end the process directly. */ + cmp $0, NUM + je .LEND_SHA256 + + /* Pop-stack/push stack protection */ + pushq %r14 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r15 + + /* The pre-stored stack space and 32-byte address are aligned. + The original RSP value is added to the stack and the mask is assigned. */ + mov %rsp, %r14 + mov 0(HashAddr), %r8d + sub $600, %rsp + vmovdqa g_mask + 0(%rip), g_maskTransformEndian + mov 4(HashAddr), %r9d + mov 8(HashAddr), %r10d + and $-256, %rsp + vmovdqa g_mask + 64(%rip), g_maskShift + mov 12(HashAddr), %r11d + mov %r14, 0(%rsp) + + /* r8d-r15d: a-h */ + mov 16(HashAddr), %r12d + mov 20(HashAddr), %r13d + vmovdqa g_mask + 32(%rip), g_maskMerge + mov 24(HashAddr), %r14d + mov 28(HashAddr), %r15d + +.LEND_SHA256_LOOP: + mov InAddr, %rcx + + /* Loads the data of a block to the lower 128 bits of the ymm register. */ + vmovdqu 0(InAddr), BlockFrontMessageW3_0 + vmovdqu 16(InAddr), BlockFrontMessageW7_4 + vmovdqu 32(InAddr), BlockFrontMessageW11_8 + vmovdqu 48(InAddr), BlockFrontMessageW15_12 + + /* block Judgment condition processing */ + leaq 64(InAddr), InAddr + cmp $1, NUM + cmovne InAddr, %rcx // If num is greater than 1, rcx points to the next block. + + /* Load the data of another block to the upper 128 bits of the ymm register. */ + vinserti128 $1, 0(%rcx), %ymm0, %ymm0 + vinserti128 $1, 16(%rcx), %ymm1, %ymm1 + vpshufb g_maskTransformEndian, %ymm0, %ymm0 + mov NUM, 16(%rsp) + vinserti128 $1, 32(%rcx), %ymm2, %ymm2 + mov HashAddr, 24(%rsp) + vpshufb g_maskTransformEndian, %ymm1, %ymm1 + vinserti128 $1, 48(%rcx), %ymm3, %ymm3 + vpshufb g_maskTransformEndian, %ymm2, %ymm2 + + add $64, %rcx + leaq g_K256(%rip), NUM + + /* Little-endian order to big-endian order, wi + kt:ymm9-11*/ + mov %rcx, 8(%rsp) + leaq 32(%rsp), %rsp + vpaddd 0(NUM), %ymm0, %ymm8 + mov %r9d, %ecx + vpaddd 32(NUM), %ymm1, %ymm9 + vmovdqa %ymm8, 0(%rsp) + vpshufb g_maskTransformEndian, %ymm3, %ymm3 + xor %ebp, %ebp + vpaddd 64(NUM), %ymm2, %ymm10 + vmovdqu %ymm9, 32(%rsp) + xor %r10d, %ecx + vpaddd 96(NUM), %ymm3, %ymm11 + mov %r13d, %edi + vmovdqa %ymm10, 64(%rsp) + vmovdqu %ymm11, 96(%rsp) + +.LEND_SHA256_ROUND_00_47: + + /* Next round wi + kt: ymm9-11, 16 rounds of compression + 4 rounds of message block expansion */ + /* FOUR_ROUND_UPDATE_4W a, b, c, d, e, f, g, h, tempSwitch2,tempSwitch4, WkAddr,B3_0, B7_4, B11_8, B15_12 */ + FOUR_ROUND_UPDATE_4W %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 0, %ymm0, %ymm1, %ymm2, %ymm3 + leaq 128(NUM), NUM + FOUR_ROUND_UPDATE_4W %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 32, %ymm1, %ymm2, %ymm3, %ymm0 + vpaddd 0(NUM), %ymm0, %ymm8 + FOUR_ROUND_UPDATE_4W %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 64, %ymm2, %ymm3, %ymm0, %ymm1 + vpaddd 32(NUM), %ymm1, %ymm9 + vmovdqa %ymm8, 128(%rsp) + FOUR_ROUND_UPDATE_4W %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 96, %ymm3, %ymm0, %ymm1, %ymm2 + vpaddd 64(NUM), %ymm2, %ymm10 + vmovdqa %ymm9, 160(%rsp) + vpaddd 96(NUM), %ymm3, %ymm11 + vmovdqu %ymm10, 192(%rsp) + vmovdqa %ymm11, 224(%rsp) + + /* Next round wi + kt: ymm9-11, 16 rounds of compression + 4 rounds of message block expansion */ + /* FOUR_ROUND_UPDATE_4W a, b, c, d, e, f, g, h, tempSwitch2,tempSwitch4, WkAddr,B19_16, B23_20, B27_24, B31_27 */ + FOUR_ROUND_UPDATE_4W %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 128, %ymm0, %ymm1, %ymm2, %ymm3 + leaq 128(NUM), NUM + FOUR_ROUND_UPDATE_4W %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 160, %ymm1, %ymm2, %ymm3, %ymm0 + vpaddd 0(NUM), %ymm0, %ymm8 + FOUR_ROUND_UPDATE_4W %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 192, %ymm2, %ymm3, %ymm0, %ymm1 + vpaddd 32(NUM), %ymm1, %ymm9 + vmovdqa %ymm8, 256(%rsp) + FOUR_ROUND_UPDATE_4W %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 224, %ymm3, %ymm0, %ymm1, %ymm2 + vpaddd 64(NUM), %ymm2, %ymm10 + vmovdqa %ymm9, 288(%rsp) + vpaddd 96(NUM), %ymm3, %ymm11 + vmovdqu %ymm10, 320(%rsp) + vmovdqa %ymm11, 352(%rsp) + + /* Next round wi + kt: ymm9-11, 16 rounds of compression + 4 rounds of message block expansion */ + /* FOUR_ROUND_UPDATE_4W a, b, c, d, e, f, g, h, tempSwitch2,tempSwitch4, WkAddr,B35_32, B39_36, B43_40, B47_44 */ + FOUR_ROUND_UPDATE_4W %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 256, %ymm0, %ymm1, %ymm2, %ymm3 + leaq 128(NUM), NUM + FOUR_ROUND_UPDATE_4W %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 288, %ymm1, %ymm2, %ymm3, %ymm0 + vpaddd 0(NUM), %ymm0, %ymm8 + FOUR_ROUND_UPDATE_4W %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 320, %ymm2, %ymm3, %ymm0, %ymm1 + vpaddd 32(NUM), %ymm1, %ymm9 + vmovdqa %ymm8, 384(%rsp) + FOUR_ROUND_UPDATE_4W %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 352, %ymm3, %ymm0, %ymm1, %ymm2 + vpaddd 64(NUM), %ymm2, %ymm10 + vmovdqa %ymm9, 416(%rsp) + vpaddd 96(NUM), %ymm3, %ymm11 + vmovdqu %ymm10, 448(%rsp) + vmovdqa %ymm11, 480(%rsp) + +.LEND_SHA256_ROUND_48_63: + /* ONE_ROUND a, b, c, d, e, f, g, h, tempSwitch2, Fourth, WkAddr */ + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 384 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 388 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 392 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 396 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 416 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 420 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 424 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 428 + + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 448 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 452 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 456 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 460 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 480 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 484 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 488 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 492 + + sub $32, %rsp + add %ebp, %r8d // a+=BSIG0 + mov 24(%rsp), HashAddr + + /* Update the storage hash value. */ + add 0(HashAddr), %r8d + add 4(HashAddr), %r9d + mov %r8d, 0(HashAddr) + add 8(HashAddr), %r10d + mov %r9d, 4(HashAddr) + add 12(HashAddr), %r11d + mov %r10d, 8(HashAddr) + add 16(HashAddr), %r12d + mov 16(%rsp), NUM + mov %r11d, 12(HashAddr) + add 20(HashAddr), %r13d + mov %r12d, 16(HashAddr) + add 24(HashAddr), %r14d + mov %r13d, 20(HashAddr) + add 28(HashAddr), %r15d + mov %r14d, 24(HashAddr) + mov %r15d, 28(HashAddr) + + cmp $1, NUM + je .LEND_SHA256_FINFISH_INITIAL + + /* Data compression of the second block */ + xor %ebp, %ebp + mov %r9d, %ecx + xor %r10d, %ecx + mov %r13d, %edi + +.LEND_SHA256_NEXT_BLOCK: + /* 0-15 */ + /* ONE_ROUND a, b, c, d, e, f, g, h, tempSwitch2,tempSwitch4, WkAddr */ + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 16+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 20+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 24+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 28+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 48+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 52+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 56+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 60+32 + + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 80+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 84+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 88+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 92+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 112+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 116+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 120+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 124+32 + + /* 16-31 */ + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 16+128+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 20+128+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 24+128+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 28+128+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 48+128+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 52+128+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 56+128+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 60+128+32 + + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 80+128+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 84+128+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 88+128+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 92+128+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 112+128+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 116+128+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 120+128+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 124+128+32 + + /* 32-47 */ + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 16+256+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 20+256+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 24+256+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 28+256+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 48+256+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 52+256+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 56+256+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 60+256+32 + + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 80+256+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 84+256+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 88+256+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 92+256+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 112+256+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 116+256+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 120+256+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 124+256+32 + + /* 48-63 */ + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 16+384+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 20+384+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 24+384+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 28+384+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 48+384+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 52+384+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 56+384+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 60+384+32 + + ONE_ROUND %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %eax, %ecx, 80+384+32 + ONE_ROUND %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %ecx, %eax, 84+384+32 + ONE_ROUND %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %eax, %ecx, 88+384+32 + ONE_ROUND %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %r12d, %ecx, %eax, 92+384+32 + + ONE_ROUND %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %r11d, %eax, %ecx, 112+384+32 + ONE_ROUND %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %r10d, %ecx, %eax, 116+384+32 + ONE_ROUND %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %r9d, %eax, %ecx, 120+384+32 + ONE_ROUND %r9d, %r10d, %r11d, %r12d, %r13d, %r14d, %r15d, %r8d, %ecx, %eax, 124+384+32 + + mov 24(%rsp), HashAddr + lea (%ebp, %r8d), %r8d // a+=BSIG0 + + /* Update the storage hash value. */ + add 0(HashAddr), %r8d + add 4(HashAddr), %r9d + mov %r8d, 0(HashAddr) + add 8(HashAddr), %r10d + mov %r9d, 4(HashAddr) + add 12(HashAddr), %r11d + mov %r10d, 8(HashAddr) + add 16(HashAddr), %r12d + mov %r11d, 12(HashAddr) + add 20(HashAddr), %r13d + mov %r12d, 16(HashAddr) + mov 8(%rsp), InAddr + add 24(HashAddr), %r14d + mov %r13d, 20(HashAddr) + mov 16(%rsp), NUM + add 28(HashAddr), %r15d + mov %r14d, 24(HashAddr) + mov %r15d, 28(HashAddr) + + sub $2, NUM + ja .LEND_SHA256_LOOP + +.LEND_SHA256_FINFISH_INITIAL: + /* Registers and pointers are reset. */ + mov 0(%rsp), %rsp + popq %r15 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %r14 + +.LEND_SHA256: + ret +.cfi_endproc + .size SHA256CompressMultiBlocks, .-SHA256CompressMultiBlocks + +#endif diff --git a/crypto/sha2/src/asm/sha2_512_armv8.S b/crypto/sha2/src/asm/sha2_512_armv8.S new file mode 100644 index 00000000..018e1e9c --- /dev/null +++ b/crypto/sha2/src/asm/sha2_512_armv8.S @@ -0,0 +1,310 @@ +/* + * 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_SHA512 + +.arch armv8-a+crypto +/* sha512 used constant value. For the data source, see the RFC4634 document. */ +.section .rodata +.balign 64 +.K512: + .quad 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc + .quad 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118 + .quad 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2 + .quad 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694 + .quad 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65 + .quad 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5 + .quad 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4 + .quad 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70 + .quad 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df + .quad 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b + .quad 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30 + .quad 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8 + .quad 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8 + .quad 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3 + .quad 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec + .quad 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b + .quad 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178 + .quad 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b + .quad 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c + .quad 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 + +/** + * Macro description: Update the processed 64-bit plaintext information W. + * Input register: + * wi_16: W[i-16] + * wi_15: W[i-15] + * wi_7: W[i-7] + * wi_2: W[i-2] + * Modify the register: wi_16 x17 x28. + * Output register: + * wi_16: latest W[i] value, W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16] + * Function/Macro Call: None + */ + .macro UPDATE_W wi_16, wi_15, wi_7, wi_2 + ror x28, \wi_15, #1 + ror x17, \wi_2, #19 + eor x28, x28, \wi_15, ror#8 + eor x17, x17, \wi_2, ror#61 + eor x28, x28, \wi_15, lsr#7 + eor x17, x17, \wi_2, lsr#6 + add \wi_16, \wi_16, \wi_7 + add \wi_16, \wi_16, x28 + add \wi_16, \wi_16, x17 + .endm + +/** + * Macro description: Processes the update of a hash value in 80 rounds of compression. + * Input register: + * x19: indicates the address of the corresponding element in the g_k512 constant. + * wi: plaintext data after processing + * a - h: intermediate variable of the hash value + * Modify the register: h d x16 x17 x28 x29 + * Output register: + * h: value after a round of cyclic update + * d: value after a round of cyclic update + * Function/Macro Call: None + */ + .macro ONE_ROUND wi, a, b, c, d, e, f, g, h + ldr x16, [x19], #8 // K[i] + add \h, \h, x16 // h += K[i] + add \h, \h, \wi // h += W[i] + + and x17, \f, \e // e&f + bic x28, \g, \e // g&(~e) + orr x17, x17, x28 // Ch(e, f, g) = e&f | g&(~e) + add \h, \h, x17 // h += Ch(e, f, g) + + eor x29, \e, \e, ror#23 + ror x16, \e, #14 + eor x29, x16, x29, ror#18 // Sigma1(e) = ROR(e, 14) ^ ROR(e, 18) ^ ROR(e, 41) + add \h, \h, x29 // h += Sigma1(e) + + eor x17, \a, \b // a^b + eor x28, \a, \c // a^c + and x28, x28, x17 // (a^b)&(a^c) + eor x28, x28, \a // Maj(a, b, c) = ((a^b)&(a^c))^a = (a&b)^(b&c)^(a&c) + + add \d, \d, \h // d += h + add \h, \h, x28 // h += Maj(a, b, c) + + eor x29, \a, \a, ror#5 + ror x16, \a, #28 + eor x29, x16, x29, ror#34 // Sigma0(a) = ROR(a, 28)^ROR(a, 34)^ROR(a, 39) + add \h, \h, x29 // h += Sigma0(a) + .endm + +/** + * Function description: Performs 80 rounds of compression calculation + *based on the input plaintext data and updates the hash value. + * Function prototype: void SHA512CompressMultiBlocks(uint64_t hash[8], const uint8_t *in, uint32_t num); + * Input register: + * x0: indicates the storage address of the hash value. + * x1: pointer to the input data address + * x2: number of 80 rounds of cycles. The value is the input data length divided by 128. + * Change register: x0-x17. + * Output register: None + * Function/Macro Call: None + * + */ + .text + .balign 16 + .global SHA512CompressMultiBlocks + .type SHA512CompressMultiBlocks, %function +SHA512CompressMultiBlocks: + cbz x2, .Lend_sha512 + stp x29, x30, [sp, #-112]! + add x29, sp, #0 + stp x19, x20, [sp, #8*2] + stp x21, x22, [sp, #8*4] + stp x23, x24, [sp, #8*6] + stp x25, x26, [sp, #8*8] + stp x27, x28, [sp, #8*10] + + /* load a - h */ + ldp x20, x21, [x0] + ldp x22, x23, [x0, #8*2] + ldp x24, x25, [x0, #8*4] + ldp x26, x27, [x0, #8*6] + + str x0, [sp, #96] + mov x16, x1 // input Value Address + lsl x30, x2, #2 + +.Lloop_compress_80: + /* Start 80 rounds of processing */ + adrp x19, .K512 + add x19, x19, :lo12:.K512 + ldp x0, x1, [x16] // Load input values. + ldp x2, x3, [x16, #8*2] + ldp x4, x5, [x16, #8*4] + ldp x6, x7, [x16, #8*6] + ldp x8, x9, [x16, #8*8] + ldp x10, x11, [x16, #8*10] + ldp x12, x13, [x16, #8*12] + ldp x14, x15, [x16, #8*14] + + add x16, x16, #8*16 + str x16, [sp, #104] +#ifndef HITLS_BIG_ENDIAN + rev x0, x0 + rev x1, x1 + rev x2, x2 + rev x3, x3 + rev x4, x4 + rev x5, x5 + rev x6, x6 + rev x7, x7 + rev x8, x8 + rev x9, x9 + rev x10, x10 + rev x11, x11 + rev x12, x12 + rev x13, x13 + rev x14, x14 + rev x15, x15 +#endif + /* x16 x17 x28 x29 used as a temporary register */ + ONE_ROUND x0, x20, x21, x22, x23, x24, x25, x26, x27 + ONE_ROUND x1, x27, x20, x21, x22, x23, x24, x25, x26 + ONE_ROUND x2, x26, x27, x20, x21, x22, x23, x24, x25 + ONE_ROUND x3, x25, x26, x27, x20, x21, x22, x23, x24 + + ONE_ROUND x4, x24, x25, x26, x27, x20, x21, x22, x23 + ONE_ROUND x5, x23, x24, x25, x26, x27, x20, x21, x22 + ONE_ROUND x6, x22, x23, x24, x25, x26, x27, x20, x21 + ONE_ROUND x7, x21, x22, x23, x24, x25, x26, x27, x20 + + ONE_ROUND x8, x20, x21, x22, x23, x24, x25, x26, x27 + ONE_ROUND x9, x27, x20, x21, x22, x23, x24, x25, x26 + ONE_ROUND x10, x26, x27, x20, x21, x22, x23, x24, x25 + ONE_ROUND x11, x25, x26, x27, x20, x21, x22, x23, x24 + + ONE_ROUND x12, x24, x25, x26, x27, x20, x21, x22, x23 + ONE_ROUND x13, x23, x24, x25, x26, x27, x20, x21, x22 + ONE_ROUND x14, x22, x23, x24, x25, x26, x27, x20, x21 + ONE_ROUND x15, x21, x22, x23, x24, x25, x26, x27, x20 + +.Lloop_compress_16_79: + /* Start 16 - 31, 32 - 47, 48 - 63, 64 - 79 compression */ + sub x30, x30, #1 + + /* 0 */ + UPDATE_W x0, x1, x9, x14 + ONE_ROUND x0, x20, x21, x22, x23, x24, x25, x26, x27 + + /* 1 */ + UPDATE_W x1, x2, x10, x15 + ONE_ROUND x1, x27, x20, x21, x22, x23, x24, x25, x26 + + /* 2 */ + UPDATE_W x2, x3, x11, x0 + ONE_ROUND x2, x26, x27, x20, x21, x22, x23, x24, x25 + + /* 3 */ + UPDATE_W x3, x4, x12, x1 + ONE_ROUND x3, x25, x26, x27, x20, x21, x22, x23, x24 + + /* 4 */ + UPDATE_W x4, x5, x13, x2 + ONE_ROUND x4, x24, x25, x26, x27, x20, x21, x22, x23 + + /* 5 */ + UPDATE_W x5, x6, x14, x3 + ONE_ROUND x5, x23, x24, x25, x26, x27, x20, x21, x22 + + /* 6 */ + UPDATE_W x6, x7, x15, x4 + ONE_ROUND x6, x22, x23, x24, x25, x26, x27, x20, x21 + + /* 7 */ + UPDATE_W x7, x8, x0, x5 + ONE_ROUND x7, x21, x22, x23, x24, x25, x26, x27, x20 + + /* 8 */ + UPDATE_W x8, x9, x1, x6 + ONE_ROUND x8, x20, x21, x22, x23, x24, x25, x26, x27 + + /* 9 */ + UPDATE_W x9, x10, x2, x7 + ONE_ROUND x9, x27, x20, x21, x22, x23, x24, x25, x26 + + /* 10 */ + UPDATE_W x10, x11, x3, x8 + ONE_ROUND x10, x26, x27, x20, x21, x22, x23, x24, x25 + + /* 11 */ + UPDATE_W x11, x12, x4, x9 + ONE_ROUND x11, x25, x26, x27, x20, x21, x22, x23, x24 + + /* 12 */ + UPDATE_W x12, x13, x5, x10 + ONE_ROUND x12, x24, x25, x26, x27, x20, x21, x22, x23 + + /* 13 */ + UPDATE_W x13, x14, x6, x11 + ONE_ROUND x13, x23, x24, x25, x26, x27, x20, x21, x22 + + /* 14 */ + UPDATE_W x14, x15, x7, x12 + ONE_ROUND x14, x22, x23, x24, x25, x26, x27, x20, x21 + + /* 15 */ + UPDATE_W x15, x0, x8, x13 + ONE_ROUND x15, x21, x22, x23, x24, x25, x26, x27, x20 + + /* If the processing length is not 80, continue the loop. */ + tst x30, #3 + bne .Lloop_compress_16_79 + + /* Stores a - h information. */ + ldr x0, [sp, #96] + + ldp x10, x11, [x0] + ldp x12, x13, [x0, #8*2] + ldp x14, x15, [x0, #8*4] + ldp x16, x17, [x0, #8*6] + + add x20, x20, x10 + add x21, x21, x11 + add x22, x22, x12 + add x23, x23, x13 + add x24, x24, x14 + add x25, x25, x15 + add x26, x26, x16 + add x27, x27, x17 + + stp x20, x21, [x0] + stp x22, x23, [x0, #8*2] + stp x24, x25, [x0, #8*4] + stp x26, x27, [x0, #8*6] + + ldr x16, [sp, #104] + /* If the remaining length is not processed, continue to process 80 rounds. */ + cbnz x30, .Lloop_compress_80 + + /* The function returns */ + ldp x19, x20, [sp, #8*2] + ldp x21, x22, [sp, #8*4] + ldp x23, x24, [sp, #8*6] + ldp x25, x26, [sp, #8*8] + ldp x27, x28, [sp, #8*10] + ldp x29, x30, [sp], #112 +.Lend_sha512: + ret + .size SHA512CompressMultiBlocks, .-SHA512CompressMultiBlocks + +#endif diff --git a/crypto/sha2/src/asm/sha2_512_x86_64.S b/crypto/sha2/src/asm/sha2_512_x86_64.S new file mode 100644 index 00000000..a729b66e --- /dev/null +++ b/crypto/sha2/src/asm/sha2_512_x86_64.S @@ -0,0 +1,523 @@ +/* + * 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_SHA512 + +.file "sha2_512_x86_64.S" + +.set TEMP1, %rbp +.set TEMP2, %rax +.set TEMP3, %rbx +.set TEMP4, %rcx +.set TEMP5, %rdi + +.set YTEMP1, %ymm8 +.set YTEMP2, %ymm9 +.set YTEMP3, %ymm10 +.set YTEMP4, %ymm11 +.set YTEMP5, %ymm12 +.set YTEMP6, %ymm13 +.set YTEMP7, %ymm14 + + .struct 0 +SHA512_wk: + .struct SHA512_wk + 1280 +SHA512_in: + .struct SHA512_in + 8 +SHA512_hash: + .struct SHA512_hash + 8 +SHA512_num: + .struct SHA512_num + 8 +SHA512_rsp: + .struct SHA512_rsp + 8 +SHA512_size: + +.section .rodata +.balign 64 +.type g_k512,%object +g_k512: + .quad 0x428a2f98d728ae22, 0x7137449123ef65cd, 0x428a2f98d728ae22, 0x7137449123ef65cd + .quad 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc + .quad 0x3956c25bf348b538, 0x59f111f1b605d019, 0x3956c25bf348b538, 0x59f111f1b605d019 + .quad 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118 + .quad 0xd807aa98a3030242, 0x12835b0145706fbe, 0xd807aa98a3030242, 0x12835b0145706fbe + .quad 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2 + .quad 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1 + .quad 0x9bdc06a725c71235, 0xc19bf174cf692694, 0x9bdc06a725c71235, 0xc19bf174cf692694 + .quad 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3 + .quad 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65 + .quad 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x2de92c6f592b0275, 0x4a7484aa6ea6e483 + .quad 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5 + .quad 0x983e5152ee66dfab, 0xa831c66d2db43210, 0x983e5152ee66dfab, 0xa831c66d2db43210 + .quad 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xb00327c898fb213f, 0xbf597fc7beef0ee4 + .quad 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0xc6e00bf33da88fc2, 0xd5a79147930aa725 + .quad 0x06ca6351e003826f, 0x142929670a0e6e70, 0x06ca6351e003826f, 0x142929670a0e6e70 + .quad 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x27b70a8546d22ffc, 0x2e1b21385c26c926 + .quad 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df + .quad 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x650a73548baf63de, 0x766a0abb3c77b2a8 + .quad 0x81c2c92e47edaee6, 0x92722c851482353b, 0x81c2c92e47edaee6, 0x92722c851482353b + .quad 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xa2bfe8a14cf10364, 0xa81a664bbc423001 + .quad 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xc24b8b70d0f89791, 0xc76c51a30654be30 + .quad 0xd192e819d6ef5218, 0xd69906245565a910, 0xd192e819d6ef5218, 0xd69906245565a910 + .quad 0xf40e35855771202a, 0x106aa07032bbd1b8, 0xf40e35855771202a, 0x106aa07032bbd1b8 + .quad 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53 + .quad 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8 + .quad 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb + .quad 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3 + .quad 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x748f82ee5defb2fc, 0x78a5636f43172f60 + .quad 0x84c87814a1f0ab72, 0x8cc702081a6439ec, 0x84c87814a1f0ab72, 0x8cc702081a6439ec + .quad 0x90befffa23631e28, 0xa4506cebde82bde9, 0x90befffa23631e28, 0xa4506cebde82bde9 + .quad 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xbef9a3f7b2c67915, 0xc67178f2e372532b + .quad 0xca273eceea26619c, 0xd186b8c721c0c207, 0xca273eceea26619c, 0xd186b8c721c0c207 + .quad 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178 + .quad 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x06f067aa72176fba, 0x0a637dc5a2c898a6 + .quad 0x113f9804bef90dae, 0x1b710b35131c471b, 0x113f9804bef90dae, 0x1b710b35131c471b + .quad 0x28db77f523047d84, 0x32caab7b40c72493, 0x28db77f523047d84, 0x32caab7b40c72493 + .quad 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c + .quad 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a + .quad 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +.size g_k512, .-g_k512 + + .balign 64 + .type g_endianMask,%object +g_endianMask: + .quad 0x0001020304050607, 0x08090a0b0c0d0e0f + .quad 0x0001020304050607, 0x08090a0b0c0d0e0f +.size g_endianMask, .-g_endianMask + +/** + * Macro Description: Processes the update of the hash value in one round of 80 compressions. + * input register: + * addr: Stack space initial address + * wkOffset: wi+k512 Data address offset + * a - h: Intermediate variable of hash value + * Modify the register:temp1, temp2, temp3, temp4, temp5 + * Output register: + * h: Indicates the value after a cyclic update. + * d: Indicates the value after a cyclic update. + * temp1: BSIG0(a) from last round + * temp4: b^a for next round b^c + * Function/Macro Call: None + * Implementation Description: + * T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + * T2 = BSIG0(a) + MAJ(a,b,c) + * CH(e, f, g) = (e AND f) XOR ((NOT e) AND g) + * MAJ(a, b, c) = (a AND b) XOR (a AND c) XOR (b AND c) + * = CH(a^b, c, b) + * = ((a XOR b) AND c) XOR ((NOT(a XOR b)) AND b) + * = (b XOR c) AND (a XOR b) XOR b + * BSIG0(x) = ROTR^28(x) XOR ROTR^34(x) XOR ROTR^39(x) + * BSIG1(x) = ROTR^14(x) XOR ROTR^18(x) XOR ROTR^41(x) + * d += T1; h = T1 + T2 + * Optimization Principle:asert b^c in temp4, temp1 equal 0, f in temp5 when round begin + * mov b, temp4 + * xor temp1, temp1 + * xor c, temp4 + * mov f, temp5 + * swap temp2 temp4 for next round + * add BSIG0(a) back to a when all round finished + */ + .macro ONE_ROUND a, b, c, d, e, f, g, h, temp1, temp2, temp3, temp4, temp5, addr, wkOffset + // asert b^c in temp4, temp1 equal 0, f in temp5 when round begin + addq \wkOffset(\addr), \h // h += Kt + Wt + and \e, \temp5 // e&f + rorx $14, \e, \temp2 // ROTR^14(e) + addq \temp1, \a // a += BSIG0(a) from last round + rorx $18, \e, \temp3 // ROTR^18(e) + andn \g, \e, \temp1 // (~e)&g + xor \temp2, \temp3 // ROTR^14(e) ^ ROTR^18(e) + xor \temp1, \temp5 // CH(e,f,g) + rorx $41, \e, \temp2 // ROTR^41(e) + addq \temp5, \h // h += CH(e,f,g) + xor \temp2, \temp3 // BSIG1(e) + rorx $28, \a, \temp1 // ROTR^28(a) + mov \a, \temp2 // a + addq \temp3, \h // h += BSIG1(e) + rorx $34, \a, \temp5 // ROTR^34(a) + xor \b, \temp2 // b^a for next round b^c + addq \h, \d // d += T1 + xor \temp5, \temp1 // ROTR^14(a) ^ ROTR^34(a) + and \temp2, \temp4 // (b^a) & (b^c) + rorx $39, \a, \temp3 // ROTR^39(a) + xor \b, \temp4 // Maj(a,b,c) + mov \e, \temp5 // for next round f + xor \temp3, \temp1 // BSIG0(a) + addq \temp4, \h // h += Maj(a,b,c) + // swap temp2 temp4 for next round + // add BSIG0(a) back to a when all round finished + .endm + +/** + * Macro Description: Processes the update of two rounds of hash values in 80 rounds of compression, + * and expands messages. + * Input register: + * addr: Stack space initial address + * wkOffset: wi+k512 Data address offset + * a - h: Intermediate variable of hash value + * wi_17_16: W[i-16-15] + * wi_15_14: W[i-15-14] + * wi_7_6: W[i-7-6] + * wi_9_8: W[i-7-8] + * wi_3_2: W[i-3-2] + * Modify the register:TEMP1, TEMP2, TEMP3, TEMP4, TEMP5, wi_17_16, YTEMP1, YTEMP2, YTEMP3, YTEMP4, YTEMP5, YTEMP6 + * Output register: + * h: Value after two rounds of cyclic update + * d: Value after two rounds of cyclic update + * TEMP1: BSIG0(a) from last round + * TEMP4: b^a for next round b^c + * wi_17_16: expanded message + * Function/Macro Call: None + * Implementation Description: + * T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + * T2 = BSIG0(a) + MAJ(a,b,c) + * CH(e, f, g) = (e AND f) XOR ((NOT e) AND g) + * MAJ(a, b, c) = (a AND b) XOR (a AND c) XOR (b AND c) + * = CH(a^b, c, b) + * = ((a XOR b) AND c) XOR ((NOT(a XOR b)) AND b) + * = (b XOR c) AND (a XOR b) XOR b + * BSIG0(x) = ROTR^28(x) XOR ROTR^34(x) XOR ROTR^39(x) + * BSIG1(x) = ROTR^14(x) XOR ROTR^18(x) XOR ROTR^41(x) + * d += T1; h = T1 + T2 + * + * wi_16: Latest W[i] value, W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16] + * SSIG0(x) = ROTR^1(x) XOR ROTR^8(x) XOR SHR^7(x) + * SSIG1(x) = ROTR^19(x) XOR ROTR^61(x) XOR SHR^6(x) + * Optimization Principle:asert b^c in TEMP4, TEMP1 equal 0, f in TEMP5 when round begin + * mov b, TEMP4 + * xor TEMP1, TEMP1 + * xor c, TEMP4 + * mov f, TEMP5 + * swap TEMP2 TEMP4 for next round + * add BSIG0(a) back to a when all round finished + */ + .macro TWO_ROUND_UPDATE_2W a, b, c, d, e, f, g, h, wkOffset, wi_17_16, wi_15_14, wi_9_8, wi_7_6, wi_3_2 + // 1st round + vpalignr $8, \wi_17_16, \wi_15_14, YTEMP1 // wi_16_15 + vpalignr $8, \wi_9_8, \wi_7_6, YTEMP7 // wi_8_7 + addq \wkOffset(%rsi), \h // h += Kt + Wt + and \e, TEMP5 // e&f + vpsrlq $1, YTEMP1, YTEMP2 + rorx $14, \e, TEMP2 // ROTR^14(e) + addq TEMP1, \a // a += BSIG0(a) from last round + vpsrlq $8, YTEMP1, YTEMP3 + rorx $18, \e, TEMP3 // ROTR^18(e) + andn \g, \e, TEMP1 // (~e)&g + vpsrlq $7, YTEMP1, YTEMP4 + xor TEMP2, TEMP3 // ROTR^14(e) ^ ROTR^18(e) + xor TEMP1, TEMP5 // CH(e,f,g) + vpsllq $63, YTEMP1, YTEMP5 + rorx $41, \e, TEMP2 // ROTR^41(e) + addq TEMP5, \h // h += CH(e,f,g) + vpsllq $56, YTEMP1, YTEMP6 + xor TEMP2, TEMP3 // BSIG1(e) + rorx $28, \a, TEMP1 // ROTR^28(a) + vpaddq YTEMP7, \wi_17_16, \wi_17_16 // W[i-17..16] + W[8..7] + mov \a, TEMP2 // a + addq TEMP3, \h // h += BSIG1(e) + vpxor YTEMP5, YTEMP2, YTEMP2 // ROTR^1(wi_16_15) + rorx $34, \a, TEMP5 // ROTR^34(a) + xor \b, TEMP2 // b^a for next round b^c + vpxor YTEMP6, YTEMP3, YTEMP3 // ROTR^8(wi_16_15) + addq \h, \d // d += T1 + xor TEMP5, TEMP1 // ROTR^14(a) ^ ROTR^34(a) + vpxor YTEMP4, YTEMP2, YTEMP1 + and TEMP2, TEMP4 // (b^a) & (b^c) + rorx $39, \a, TEMP3 // ROTR^39(a) + vpxor YTEMP3, YTEMP1, YTEMP1 // SSIG0(wi_16_15) + xor \b, TEMP4 // Maj(a,b,c) + mov \e, TEMP5 // for next round f + vpaddq YTEMP1, \wi_17_16, \wi_17_16 // SSIG0(wi_16_15) + W[i-17..16] + W[8..7] + xor TEMP3, TEMP1 // BSIG0(a) + addq TEMP4, \h // h += Maj(a,b,c) + // swap TEMP2 TEMP4 for next round + + // 2nd round + // ror abcdefgh to habcdefg + vpsrlq $19, \wi_3_2, YTEMP2 + addq 8+\wkOffset(%rsi), \g // h += Kt + Wt + and \d, TEMP5 // e&f + vpsrlq $61, \wi_3_2, YTEMP3 + rorx $14, \d, TEMP4 // ROTR^14(e) + addq TEMP1, \h // a += BSIG0(a) from last round + vpsrlq $6, \wi_3_2, YTEMP4 + rorx $18, \d, TEMP3 // ROTR^18(e) + andn \f, \d, TEMP1 // (~e)&g + vpsllq $45, \wi_3_2, YTEMP5 + xor TEMP4, TEMP3 // ROTR^14(e) ^ ROTR^18(e) + xor TEMP1, TEMP5 // CH(e,f,g) + vpsllq $3, \wi_3_2, YTEMP6 + rorx $41, \d, TEMP4 // ROTR^41(e) + addq TEMP5, \g // h += CH(e,f,g) + vpxor YTEMP5, YTEMP2, YTEMP2 // ROTR^19(wi_3_2) + xor TEMP4, TEMP3 // BSIG1(e) + rorx $28, \h, TEMP1 // ROTR^28(a) + vpxor YTEMP6, YTEMP3, YTEMP3 // ROTR^61(wi_3_2) + mov \h, TEMP4 // a + addq TEMP3, \g // h += BSIG1(e) + vpxor YTEMP4, YTEMP2, YTEMP1 + rorx $34, \h, TEMP5 // ROTR^34(a) + xor \a, TEMP4 // b^a for next round b^c + vpxor YTEMP3, YTEMP1, YTEMP1 // SSIG1(wi_3_2) + addq \g, \c // d += T1 + xor TEMP5, TEMP1 // ROTR^14(a) ^ ROTR^34(a) + vpaddq YTEMP1, \wi_17_16, \wi_17_16 // SSIG0(wi_16_15) + W[i-17..16] + W[i-8..7] + SSIG1(wi_3_2) + and TEMP4, TEMP2 // (b^a) & (b^c) + rorx $39, \h, TEMP3 // ROTR^39(a) + vpaddq \wkOffset(%rdx), \wi_17_16, YTEMP1 // wi + k + xor \a, TEMP2 // Maj(a,b,c) + mov \d, TEMP5 // for next round f + vmovdqa YTEMP1, \wkOffset + 256(%rsi) + xor TEMP3, TEMP1 // BSIG0(a) + addq TEMP2, \g // h += Maj(a,b,c) + // swap TEMP2 TEMP4 for next round + // add BSIG0(a) back to a when all round finished + .endm + +/** + * Function description: Performs 80 rounds of compression calculation based on the input plaintext data and updates the hash value. + * function prototype:void SHA512CompressMultiBlocks(uint64_t hash[8], const uint8_t *in, uint32_t num); + * input register: + * rdi:function prototype + * rsi:Pointer to the input data address + * rdx:Number of 80 rounds of cycles. The value is the length of the input data divided by 128. + * Register usage:ymm0-ymm7 to participate in the calculation of message blocks (of two data blocks). + * ymm8-ymm14 is temporary wide register + * r8-r15 Storage a-h + * The stack space temporarily stores wi+k512 (1280 bytes) and hash addresses、in、num + * Output register:None + * Function/Macro Call:UPDATE_W、ONE_ROUND + * + */ + .text + .balign 16 + .global SHA512CompressMultiBlocks + .type SHA512CompressMultiBlocks, %function +SHA512CompressMultiBlocks: +.cfi_startproc + cmp $0, %rdx + je .Lsha512end + + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + mov %rsp, %r14 + sub $1320, %rsp + and $-256, %rsp // 32-byte address alignment + mov %r14, SHA512_rsp(%rsp) // rsp The original value is added to the stack. + + /* load A-H */ + mov 0(%rdi), %r8 + mov 8(%rdi), %r9 + mov 16(%rdi), %r10 + mov 24(%rdi), %r11 + mov 32(%rdi), %r12 + mov 40(%rdi), %r13 + mov 48(%rdi), %r14 + mov 56(%rdi), %r15 + + mov %rdi, SHA512_hash(%rsp) + mov %rsi, SHA512_in(%rsp) // The input data address is stored in the stack. + +.Lsha512_loop: + mov SHA512_in(%rsp), %rsi + + /* Loads the data of a block to the lower 128 bits of the ymm register. */ + vmovdqu 0(%rsi), %xmm0 + vmovdqu 16(%rsi), %xmm1 + vmovdqu 32(%rsi), %xmm2 + vmovdqu 48(%rsi), %xmm3 + vmovdqu 64(%rsi), %xmm4 + vmovdqu 80(%rsi), %xmm5 + vmovdqu 96(%rsi), %xmm6 + vmovdqu 112(%rsi), %xmm7 + + mov %rsi, %rcx + add $128, %rsi + cmp $1, %rdx + cmovne %rsi, %rcx // If num is greater than 1, rcx points to the next block. + + mov %rdx, SHA512_num(%rsp) // Remaining nums are added to the stack. + + /* Loads the data of a block to the upper 128 bits of the ymm register. */ + vinserti128 $1, 0(%rcx), %ymm0, %ymm0 + vinserti128 $1, 16(%rcx), %ymm1, %ymm1 + vinserti128 $1, 32(%rcx), %ymm2, %ymm2 + vinserti128 $1, 48(%rcx), %ymm3, %ymm3 + vinserti128 $1, 64(%rcx), %ymm4, %ymm4 + vinserti128 $1, 80(%rcx), %ymm5, %ymm5 + vinserti128 $1, 96(%rcx), %ymm6, %ymm6 + vinserti128 $1, 112(%rcx),%ymm7, %ymm7 + add $128, %rcx + mov %rcx, SHA512_in(%rsp) // The input data address is stored in the stack. + + vmovdqa g_endianMask + 0(%rip), %ymm8 + leaq g_k512 + 0(%rip), %rdx + /* Little-endian order to big-endian order */ + vpshufb %ymm8, %ymm0, %ymm0 + vpshufb %ymm8, %ymm1, %ymm1 + vpshufb %ymm8, %ymm2, %ymm2 + vpshufb %ymm8, %ymm3, %ymm3 + vpshufb %ymm8, %ymm4, %ymm4 + vpshufb %ymm8, %ymm5, %ymm5 + vpshufb %ymm8, %ymm6, %ymm6 + vpshufb %ymm8, %ymm7, %ymm7 + /* w[0..15] + k*/ + vpaddq 0(%rdx), %ymm0, %ymm8 + vpaddq 32(%rdx), %ymm1, %ymm9 + vpaddq 64(%rdx), %ymm2, %ymm10 + vpaddq 96(%rdx), %ymm3, %ymm11 + vpaddq 128(%rdx), %ymm4, %ymm12 + vpaddq 160(%rdx), %ymm5, %ymm13 + vpaddq 192(%rdx), %ymm6, %ymm14 + vpaddq 224(%rdx), %ymm7, %ymm15 + /* wk push stack */ + vmovdqa %ymm8, 0(%rsp) + vmovdqa %ymm9, 32(%rsp) + vmovdqa %ymm10, 64(%rsp) + vmovdqa %ymm11, 96(%rsp) + vmovdqa %ymm12, 128(%rsp) + vmovdqa %ymm13, 160(%rsp) + vmovdqa %ymm14, 192(%rsp) + vmovdqa %ymm15, 224(%rsp) + + movq $4, 1312(%rsp) + leaq 0(%rsp), %rsi + + mov %r9, %rcx // mov b, TEMP4 + xor %rbp, %rbp // xor TEMP1, TEMP1 + xor %r10, %rcx // xor c, TEMP4 + mov %r13, %rdi // mov f, TEMP5 +.Lround00_63: + leaq 256(%rdx), %rdx + + TWO_ROUND_UPDATE_2W %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15, 0, %ymm0, %ymm1, %ymm4, %ymm5, %ymm7 + TWO_ROUND_UPDATE_2W %r14, %r15, %r8, %r9, %r10, %r11, %r12, %r13, 32, %ymm1, %ymm2, %ymm5, %ymm6, %ymm0 + TWO_ROUND_UPDATE_2W %r12, %r13, %r14, %r15, %r8, %r9, %r10, %r11, 64, %ymm2, %ymm3, %ymm6, %ymm7, %ymm1 + TWO_ROUND_UPDATE_2W %r10, %r11, %r12, %r13, %r14, %r15, %r8, %r9, 96, %ymm3, %ymm4, %ymm7, %ymm0, %ymm2 + TWO_ROUND_UPDATE_2W %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15, 128, %ymm4, %ymm5, %ymm0, %ymm1, %ymm3 + TWO_ROUND_UPDATE_2W %r14, %r15, %r8, %r9, %r10, %r11, %r12, %r13, 160, %ymm5, %ymm6, %ymm1, %ymm2, %ymm4 + TWO_ROUND_UPDATE_2W %r12, %r13, %r14, %r15, %r8, %r9, %r10, %r11, 192, %ymm6, %ymm7, %ymm2, %ymm3, %ymm5 + TWO_ROUND_UPDATE_2W %r10, %r11, %r12, %r13, %r14, %r15, %r8, %r9, 224, %ymm7, %ymm0, %ymm3, %ymm4, %ymm6 + + leaq 256(%rsi), %rsi + decq 1312(%rsp) + jne .Lround00_63 + + /* round 64-79 */ + ONE_ROUND %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 0 + ONE_ROUND %r15, %r8, %r9, %r10, %r11, %r12, %r13, %r14, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 8 + ONE_ROUND %r14, %r15, %r8, %r9, %r10, %r11, %r12, %r13, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 32 + ONE_ROUND %r13, %r14, %r15, %r8, %r9, %r10, %r11, %r12, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 40 + ONE_ROUND %r12, %r13, %r14, %r15, %r8, %r9, %r10, %r11, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 64 + ONE_ROUND %r11, %r12, %r13, %r14, %r15, %r8, %r9, %r10, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 72 + ONE_ROUND %r10, %r11, %r12, %r13, %r14, %r15, %r8, %r9, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 96 + ONE_ROUND %r9, %r10, %r11, %r12, %r13, %r14, %r15, %r8, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 104 + + ONE_ROUND %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 128 + ONE_ROUND %r15, %r8, %r9, %r10, %r11, %r12, %r13, %r14, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 136 + ONE_ROUND %r14, %r15, %r8, %r9, %r10, %r11, %r12, %r13, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 160 + ONE_ROUND %r13, %r14, %r15, %r8, %r9, %r10, %r11, %r12, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 168 + ONE_ROUND %r12, %r13, %r14, %r15, %r8, %r9, %r10, %r11, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 192 + ONE_ROUND %r11, %r12, %r13, %r14, %r15, %r8, %r9, %r10, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 200 + ONE_ROUND %r10, %r11, %r12, %r13, %r14, %r15, %r8, %r9, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 224 + ONE_ROUND %r9, %r10, %r11, %r12, %r13, %r14, %r15, %r8, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 232 + addq %rbp, %r8 // a += BSIG0(a) from last round + + leaq -1024(%rsi), %rsi // rsi Point to the original address + /* Update the hash value. */ + mov SHA512_hash(%rsp), %rdi + mov SHA512_num(%rsp), %rdx + addq 0(%rdi), %r8 + addq 8(%rdi), %r9 + addq 16(%rdi), %r10 + addq 24(%rdi), %r11 + addq 32(%rdi), %r12 + addq 40(%rdi), %r13 + addq 48(%rdi), %r14 + addq 56(%rdi), %r15 + mov %r8, 0(%rdi) + mov %r9, 8(%rdi) + mov %r10, 16(%rdi) + mov %r11, 24(%rdi) + mov %r12, 32(%rdi) + mov %r13, 40(%rdi) + mov %r14, 48(%rdi) + mov %r15, 56(%rdi) + + cmp $1, %rdx + je .Lsha512_finish + + movq $10, 1312(%rsp) + + mov %r9, %rcx // mov b, TEMP4 + xor %rbp, %rbp // xor TEMP1, TEMP1 + xor %r10, %rcx // xor c, TEMP4 + mov %r13, %rdi // mov f, TEMP5 +.Lnext_block: + ONE_ROUND %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 16 + ONE_ROUND %r15, %r8, %r9, %r10, %r11, %r12, %r13, %r14, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 24 + ONE_ROUND %r14, %r15, %r8, %r9, %r10, %r11, %r12, %r13, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 48 + ONE_ROUND %r13, %r14, %r15, %r8, %r9, %r10, %r11, %r12, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 56 + ONE_ROUND %r12, %r13, %r14, %r15, %r8, %r9, %r10, %r11, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 80 + ONE_ROUND %r11, %r12, %r13, %r14, %r15, %r8, %r9, %r10, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 88 + ONE_ROUND %r10, %r11, %r12, %r13, %r14, %r15, %r8, %r9, %rbp, %rax, %rbx, %rcx, %rdi, %rsi, 112 + ONE_ROUND %r9, %r10, %r11, %r12, %r13, %r14, %r15, %r8, %rbp, %rcx, %rbx, %rax, %rdi, %rsi, 120 + leaq 128(%rsi), %rsi + decq 1312(%rsp) + jne .Lnext_block + + addq %rbp, %r8 // a += BSIG0(a) from last round + leaq -1280(%rsi), %rsi // rsi Point to the original address + /* Update the hash value. */ + mov SHA512_hash(%rsp), %rdi + addq 0(%rdi), %r8 + addq 8(%rdi), %r9 + addq 16(%rdi), %r10 + addq 24(%rdi), %r11 + addq 32(%rdi), %r12 + addq 40(%rdi), %r13 + addq 48(%rdi), %r14 + addq 56(%rdi), %r15 + mov %r8, 0(%rdi) + mov %r9, 8(%rdi) + mov %r10, 16(%rdi) + mov %r11, 24(%rdi) + mov %r12, 32(%rdi) + mov %r13, 40(%rdi) + mov %r14, 48(%rdi) + mov %r15, 56(%rdi) + + sub $2, %rdx + jne .Lsha512_loop + +.Lsha512_finish: + mov SHA512_rsp(%rsp), %rsp + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + +.Lsha512end: + ret +.cfi_endproc + .size SHA512CompressMultiBlocks, .-SHA512CompressMultiBlocks + +#endif diff --git a/crypto/sha2/src/noasm_sha256.c b/crypto/sha2/src/noasm_sha256.c new file mode 100644 index 00000000..95658977 --- /dev/null +++ b/crypto/sha2/src/noasm_sha256.c @@ -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" +#ifdef HITLS_CRYPTO_SHA256 +#include "crypt_sha2.h" +#include "crypt_utils.h" +#include "sha2_core.h" + +static const uint32_t K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, +}; +#define ROTR32(x, n) (((x) << (32 - (n))) | ((x) >> (n))) // Assumes that x is uint32_t and 0 < n < 32 + +#define S0(x) (ROTR32((x), 7) ^ ROTR32((x), 18) ^ ((x) >> 3)) +#define S1(x) (ROTR32((x), 17) ^ ROTR32((x), 19) ^ ((x) >> 10)) + +#define R(w, t) \ + (S1((w)[(t) - 2]) + (w)[(t) - 7] + \ + S0((w)[(t) - 15]) + (w)[(t) - 16]) + +#define ROUND(a, b, c, d, e, f, g, h, i, k) \ + do { \ + /* constants: 6, 11, 25 */ \ + (h) += (ROTR32((e), 6) ^ ROTR32((e), 11) ^ ROTR32((e), 25)) + \ + ((g) ^ ((e) & ((f) ^ (g)))) + (k) + (i); \ + (d) += (h); \ + /* constants: 2, 13, 22 */ \ + (h) += (ROTR32((a), 2) ^ ROTR32((a), 13) ^ ROTR32((a), 22)) + \ + (((a) & ((b) | (c))) | ((b) & (c))); \ + } while (0) + +static void CompressBlock(uint32_t state[8], const uint8_t block[CRYPT_SHA2_256_BLOCKSIZE]) +{ + uint32_t w[64]; + + // RFC 6.2.1. Prepare the message schedule w: + // For t = 0 to 15 + // Wt = M(i)t + for (unsigned i = 0; i < 16; i++) { // 16 rounds to prepare the message schedule + w[i] = GET_UINT32_BE(block, 4 * (i)); /* 4 means bytes of uint32_t */ + } + + // For t = 16 to 63 + // Wt = SSIG1(w(t-2)) + w(t-7) + SSIG0(t-15) + w(t-16) + // @perf: speed up about 18% than expanded in x86_64 + + // RFC 6.2.2. Initialize the working variables: + // a, b, ..., g, h = H(i-1)[0..7] + uint32_t a = state[0]; + uint32_t b = state[1]; + uint32_t c = state[2]; + uint32_t d = state[3]; + uint32_t e = state[4]; + uint32_t f = state[5]; + uint32_t g = state[6]; + uint32_t h = state[7]; + + // RFC 6.2.3. Perform the main hash computation: + for (unsigned i = 0; i < 16; i += 8) { /* 0 ~ 16 rounds to do hash computation, 8 rounds pre loop */ + ROUND(a, b, c, d, e, f, g, h, w[i + 0], K256[i + 0]); + ROUND(h, a, b, c, d, e, f, g, w[i + 1], K256[i + 1]); + ROUND(g, h, a, b, c, d, e, f, w[i + 2], K256[i + 2]); + ROUND(f, g, h, a, b, c, d, e, w[i + 3], K256[i + 3]); + ROUND(e, f, g, h, a, b, c, d, w[i + 4], K256[i + 4]); + ROUND(d, e, f, g, h, a, b, c, w[i + 5], K256[i + 5]); + ROUND(c, d, e, f, g, h, a, b, w[i + 6], K256[i + 6]); + ROUND(b, c, d, e, f, g, h, a, w[i + 7], K256[i + 7]); + } + + for (unsigned i = 16; i < 64; i += 8) { /* 16 ~ 64 rounds to do hash computation, 8 rounds pre loop */ + w[i + 0] = R(w, i + 0); + ROUND(a, b, c, d, e, f, g, h, w[i + 0], K256[i + 0]); + w[i + 1] = R(w, i + 1); + ROUND(h, a, b, c, d, e, f, g, w[i + 1], K256[i + 1]); + w[i + 2] = R(w, i + 2); + ROUND(g, h, a, b, c, d, e, f, w[i + 2], K256[i + 2]); + w[i + 3] = R(w, i + 3); + ROUND(f, g, h, a, b, c, d, e, w[i + 3], K256[i + 3]); + w[i + 4] = R(w, i + 4); + ROUND(e, f, g, h, a, b, c, d, w[i + 4], K256[i + 4]); + w[i + 5] = R(w, i + 5); + ROUND(d, e, f, g, h, a, b, c, w[i + 5], K256[i + 5]); + w[i + 6] = R(w, i + 6); + ROUND(c, d, e, f, g, h, a, b, w[i + 6], K256[i + 6]); + w[i + 7] = R(w, i + 7); + ROUND(b, c, d, e, f, g, h, a, w[i + 7], K256[i + 7]); + } + + // RFC 6.2.4. Compute the intermediate hash value H(i): + // H(i) = [a, b, ..., g, h] + H(i-1)[0..7] + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} +#undef ROTR32 +#undef ROUND + +void SHA256CompressMultiBlocks(uint32_t hash[8], const uint8_t *in, uint32_t num) +{ + uint32_t n = num; + const uint8_t *p = in; + while (n > 0) { + CompressBlock(hash, p); + p += CRYPT_SHA2_256_BLOCKSIZE; + n--; + } +} +#endif // HITLS_CRYPTO_SHA256 diff --git a/crypto/sha2/src/noasm_sha512.c b/crypto/sha2/src/noasm_sha512.c new file mode 100644 index 00000000..99890320 --- /dev/null +++ b/crypto/sha2/src/noasm_sha512.c @@ -0,0 +1,147 @@ +/* + * 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_SHA512 +#include "crypt_sha2.h" +#include "crypt_utils.h" +#include "sha2_core.h" + +#ifndef U64 +#define U64(v) (uint64_t)(v) +#endif + +// define in rfc 4634 +static const uint64_t K512[80] = { + U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd), U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc), + U64(0x3956c25bf348b538), U64(0x59f111f1b605d019), U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118), + U64(0xd807aa98a3030242), U64(0x12835b0145706fbe), U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2), + U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1), U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694), + U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3), U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65), + U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483), U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5), + U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210), U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4), + U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725), U64(0x06ca6351e003826f), U64(0x142929670a0e6e70), + U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926), U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df), + U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8), U64(0x81c2c92e47edaee6), U64(0x92722c851482353b), + U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001), U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30), + U64(0xd192e819d6ef5218), U64(0xd69906245565a910), U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8), + U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53), U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8), + U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb), U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3), + U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60), U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec), + U64(0x90befffa23631e28), U64(0xa4506cebde82bde9), U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b), + U64(0xca273eceea26619c), U64(0xd186b8c721c0c207), U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178), + U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6), U64(0x113f9804bef90dae), U64(0x1b710b35131c471b), + U64(0x28db77f523047d84), U64(0x32caab7b40c72493), U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c), + U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a), U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817), +}; + +#undef ROUND00_16 +#undef ROUND16_80 + +#define SHA512_CH(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define SHA512_MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define SHA512_BSIG0(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39)) +#define SHA512_BSIG1(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41)) +#define SHA512_SSIG0(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ ((x) >> 7)) +#define SHA512_SSIG1(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ ((x) >> 6)) + +#define SHA512_ROUND(a, b, c, d, e, f, g, h, t, s, w) \ +do { \ + (h) += SHA512_BSIG1(e) + SHA512_CH(e, f, g) + K512[t] + (w)[s]; \ + (d) += (h); \ + (h) += SHA512_BSIG0(a) + SHA512_MAJ(a, b, c); \ +} while (0) + +#define ROUND00_16(w, a, b, c, d, e, f, g, h, t, M) \ +do { \ + (w)[t] = Uint64FromBeBytes((M) + (t) * 8); \ + SHA512_ROUND(a, b, c, d, e, f, g, h, t, t, w); \ +} while (0) + +#define ROUND16_80(w, a, b, c, d, e, f, g, h, t, s) \ +do { \ + (w)[s] += SHA512_SSIG1((w)[((s) + 14) & 0xF]) + (w)[((s) + 9) & 0xF] + SHA512_SSIG0((w)[((s) + 1) & 0xF]); \ + SHA512_ROUND(a, b, c, d, e, f, g, h, (t) + (s), s, w); \ +} while (0) + +void SHA512CompressMultiBlocks(uint64_t hash[8], const uint8_t *bl, uint32_t bcnt) +{ + uint32_t t; + uint64_t w[16]; + const uint8_t *block = bl; + uint32_t blockn = bcnt; + + while (blockn > 0) { + uint64_t a = hash[0]; + uint64_t b = hash[1]; + uint64_t c = hash[2]; + uint64_t d = hash[3]; + uint64_t e = hash[4]; + uint64_t f = hash[5]; + uint64_t g = hash[6]; + uint64_t h = hash[7]; + + ROUND00_16(w, a, b, c, d, e, f, g, h, 0, block); + ROUND00_16(w, h, a, b, c, d, e, f, g, 1, block); + ROUND00_16(w, g, h, a, b, c, d, e, f, 2, block); + ROUND00_16(w, f, g, h, a, b, c, d, e, 3, block); + ROUND00_16(w, e, f, g, h, a, b, c, d, 4, block); + ROUND00_16(w, d, e, f, g, h, a, b, c, 5, block); + ROUND00_16(w, c, d, e, f, g, h, a, b, 6, block); + ROUND00_16(w, b, c, d, e, f, g, h, a, 7, block); + ROUND00_16(w, a, b, c, d, e, f, g, h, 8, block); + ROUND00_16(w, h, a, b, c, d, e, f, g, 9, block); + ROUND00_16(w, g, h, a, b, c, d, e, f, 10, block); + ROUND00_16(w, f, g, h, a, b, c, d, e, 11, block); + ROUND00_16(w, e, f, g, h, a, b, c, d, 12, block); + ROUND00_16(w, d, e, f, g, h, a, b, c, 13, block); + ROUND00_16(w, c, d, e, f, g, h, a, b, 14, block); + ROUND00_16(w, b, c, d, e, f, g, h, a, 15, block); + + // 16th - 80th round of operation, corresponding to steps 1 and 3 in rfc6234 6.4 + for (t = 16; t < 80; t += 16) { + ROUND16_80(w, a, b, c, d, e, f, g, h, t, 0); + ROUND16_80(w, h, a, b, c, d, e, f, g, t, 1); + ROUND16_80(w, g, h, a, b, c, d, e, f, t, 2); + ROUND16_80(w, f, g, h, a, b, c, d, e, t, 3); + ROUND16_80(w, e, f, g, h, a, b, c, d, t, 4); + ROUND16_80(w, d, e, f, g, h, a, b, c, t, 5); + ROUND16_80(w, c, d, e, f, g, h, a, b, t, 6); + ROUND16_80(w, b, c, d, e, f, g, h, a, t, 7); + ROUND16_80(w, a, b, c, d, e, f, g, h, t, 8); + ROUND16_80(w, h, a, b, c, d, e, f, g, t, 9); + ROUND16_80(w, g, h, a, b, c, d, e, f, t, 10); + ROUND16_80(w, f, g, h, a, b, c, d, e, t, 11); + ROUND16_80(w, e, f, g, h, a, b, c, d, t, 12); + ROUND16_80(w, d, e, f, g, h, a, b, c, t, 13); + ROUND16_80(w, c, d, e, f, g, h, a, b, t, 14); + ROUND16_80(w, b, c, d, e, f, g, h, a, t, 15); + } + + // RFC6234 STEP 4: Compute the intermediate hash value H(i) + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; + hash[4] += e; + hash[5] += f; + hash[6] += g; + hash[7] += h; + + block += CRYPT_SHA2_512_BLOCKSIZE; + blockn--; + } +} +#endif diff --git a/crypto/sha2/src/sha2_256.c b/crypto/sha2/src/sha2_256.c new file mode 100644 index 00000000..fd9328d0 --- /dev/null +++ b/crypto/sha2/src/sha2_256.c @@ -0,0 +1,294 @@ +/* + * 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_SHA256 +#include "crypt_sha2.h" +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "sha2_core.h" +#include "bsl_sal.h" + +int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_SHA2_256_Ctx), 0, sizeof(CRYPT_SHA2_256_Ctx)); + /** + * @RFC 4634 6.1 SHA-224 and SHA-256 Initialization + * SHA-256, the initial hash value, H(0): + * H(0)0 = 6a09e667 + * H(0)1 = bb67ae85 + * H(0)2 = 3c6ef372 + * H(0)3 = a54ff53a + * H(0)4 = 510e527f + * H(0)5 = 9b05688c + * H(0)6 = 1f83d9ab + * H(0)7 = 5be0cd19 + */ + ctx->h[0] = 0x6a09e667UL; + ctx->h[1] = 0xbb67ae85UL; + ctx->h[2] = 0x3c6ef372UL; + ctx->h[3] = 0xa54ff53aUL; + ctx->h[4] = 0x510e527fUL; + ctx->h[5] = 0x9b05688cUL; + ctx->h[6] = 0x1f83d9abUL; + ctx->h[7] = 0x5be0cd19UL; + ctx->outlen = CRYPT_SHA2_256_DIGESTSIZE; + return CRYPT_SUCCESS; +} + +void CRYPT_SHA2_256_Deinit(CRYPT_SHA2_256_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_256_Ctx)); +} + +int32_t CRYPT_SHA2_256_CopyCtx(CRYPT_SHA2_256_Ctx *dst, CRYPT_SHA2_256_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SHA2_256_Ctx), src, sizeof(CRYPT_SHA2_256_Ctx)); + return CRYPT_SUCCESS; +} + +static int32_t CheckIsCorrupted(CRYPT_SHA2_256_Ctx *ctx, uint32_t nbytes); +static int32_t UpdateParamIsValid(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + if ((ctx == NULL) || (data == NULL && nbytes != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->errorCode != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + + if (CheckIsCorrupted(ctx, nbytes) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + + return CRYPT_SUCCESS; +} + +static int32_t CheckIsCorrupted(CRYPT_SHA2_256_Ctx *ctx, uint32_t nbytes) +{ + uint32_t cnt0 = (ctx->lNum + (nbytes << SHIFTS_PER_BYTE)) & 0xffffffffUL; + if (cnt0 < ctx->lNum) { /* overflow */ + if (++ctx->hNum == 0) { + ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW; + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + } + uint32_t cnt1 = ctx->hNum + (uint32_t)(nbytes >> (BITSIZE(uint32_t) - SHIFTS_PER_BYTE)); + if (cnt1 < ctx->hNum) { /* overflow */ + ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW; + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + ctx->hNum = cnt1; + ctx->lNum = cnt0; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + int32_t ret = UpdateParamIsValid(ctx, data, nbytes); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (nbytes == 0) { + return CRYPT_SUCCESS; + } + + const uint8_t *d = data; + uint32_t left = nbytes; + uint32_t n = ctx->blocklen; + uint8_t *p = (uint8_t *)ctx->block; + + if (left < CRYPT_SHA2_256_BLOCKSIZE - n) { + if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, left) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + ctx->blocklen += (uint32_t)left; + return CRYPT_SUCCESS; + } + if ((n != 0) && (left >= CRYPT_SHA2_256_BLOCKSIZE - n)) { + if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, CRYPT_SHA2_256_BLOCKSIZE - n) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + SHA256CompressMultiBlocks(ctx->h, p, 1); + n = CRYPT_SHA2_256_BLOCKSIZE - n; + d += n; + left -= n; + ctx->blocklen = 0; + (void)memset_s(p, CRYPT_SHA2_256_BLOCKSIZE, 0, CRYPT_SHA2_256_BLOCKSIZE); + } + + n = (uint32_t)(left / CRYPT_SHA2_256_BLOCKSIZE); + if (n > 0) { + SHA256CompressMultiBlocks(ctx->h, d, n); + n *= CRYPT_SHA2_256_BLOCKSIZE; + d += n; + left -= n; + } + + if (left != 0) { + ctx->blocklen = (uint32_t)left; + if (memcpy_s((uint8_t *)ctx->block, CRYPT_SHA2_256_BLOCKSIZE, d, left) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + } + + return CRYPT_SUCCESS; +} + +static int32_t FinalParamIsValid(const CRYPT_SHA2_256_Ctx *ctx, const uint8_t *out, const uint32_t *outLen) +{ + if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (*outLen < ctx->outlen) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH; + } + + if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + + return CRYPT_SUCCESS; +} +int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *outlen) +{ + int32_t ret = FinalParamIsValid(ctx, digest, outlen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + uint8_t *p = (uint8_t *)ctx->block; + uint32_t n = ctx->blocklen; + + p[n++] = 0x80; + if (n > (CRYPT_SHA2_256_BLOCKSIZE - 8)) { /* 8 bytes to save bits of input */ + (void)memset_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, 0, CRYPT_SHA2_256_BLOCKSIZE - n); + n = 0; + SHA256CompressMultiBlocks(ctx->h, p, 1); + } + (void)memset_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, 0, + CRYPT_SHA2_256_BLOCKSIZE - 8 - n); /* 8 bytes to save bits of input */ + + p += CRYPT_SHA2_256_BLOCKSIZE - 8; /* 8 bytes to save bits of input */ + PUT_UINT32_BE(ctx->hNum, p, 0); + p += sizeof(uint32_t); + PUT_UINT32_BE(ctx->lNum, p, 0); + p += sizeof(uint32_t); + p -= CRYPT_SHA2_256_BLOCKSIZE; + SHA256CompressMultiBlocks(ctx->h, p, 1); + ctx->blocklen = 0; + (void)memset_s(p, CRYPT_SHA2_256_BLOCKSIZE, 0, CRYPT_SHA2_256_BLOCKSIZE); + + n = ctx->outlen / sizeof(uint32_t); + for (uint32_t nn = 0; nn < n; nn++) { + PUT_UINT32_BE(ctx->h[nn], digest, sizeof(uint32_t) * nn); + } + *outlen = ctx->outlen; + + return CRYPT_SUCCESS; +} + +#ifdef HITLS_CRYPTO_SHA224 +int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_SHA2_224_Ctx), 0, sizeof(CRYPT_SHA2_224_Ctx)); + /** + * @RFC 4634 6.1 SHA-224 and SHA-256 Initialization + * SHA-224, the initial hash value, H(0): + * H(0)0 = c1059ed8 + * H(0)1 = 367cd507 + * H(0)2 = 3070dd17 + * H(0)3 = f70e5939 + * H(0)4 = ffc00b31 + * H(0)5 = 68581511 + * H(0)6 = 64f98fa7 + * H(0)7 = befa4fa4 + */ + ctx->h[0] = 0xc1059ed8UL; + ctx->h[1] = 0x367cd507UL; + ctx->h[2] = 0x3070dd17UL; + ctx->h[3] = 0xf70e5939UL; + ctx->h[4] = 0xffc00b31UL; + ctx->h[5] = 0x68581511UL; + ctx->h[6] = 0x64f98fa7UL; + ctx->h[7] = 0xbefa4fa4UL; + ctx->outlen = CRYPT_SHA2_224_DIGESTSIZE; + return CRYPT_SUCCESS; +} + +void CRYPT_SHA2_224_Deinit(CRYPT_SHA2_224_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_224_Ctx)); +} + +int32_t CRYPT_SHA2_224_CopyCtx(CRYPT_SHA2_224_Ctx *dst, CRYPT_SHA2_224_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SHA2_224_Ctx), src, sizeof(CRYPT_SHA2_224_Ctx)); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + return CRYPT_SHA2_256_Update((CRYPT_SHA2_256_Ctx *)ctx, data, nbytes); +} + +int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len) +{ + return CRYPT_SHA2_256_Final((CRYPT_SHA2_256_Ctx *)ctx, digest, len); +} +#endif // HITLS_CRYPTO_SHA224 + +#endif // HITLS_CRYPTO_SHA256 diff --git a/crypto/sha2/src/sha2_512.c b/crypto/sha2/src/sha2_512.c new file mode 100644 index 00000000..418f9fcd --- /dev/null +++ b/crypto/sha2/src/sha2_512.c @@ -0,0 +1,281 @@ +/* + * 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_SHA512 +#include "crypt_sha2.h" +#include +#include "securec.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "bsl_err_internal.h" +#include "sha2_core.h" +#include "bsl_sal.h" + +#define SHA2_512_PADSIZE 112 + +// function : num1 += num2(num1 and num2 are 128bit int32_t) +static int32_t Add128Bit(uint64_t *num1h, uint64_t *num1l, uint64_t num2h, uint64_t num2l) +{ + uint64_t num1hTemp = *num1h; + uint64_t num1lTemp = *num1l; + uint64_t sumh = num1hTemp; + uint64_t suml = num1lTemp + num2l; + uint64_t carry = 0; + if (suml < num1lTemp) { + carry = 1; + sumh += carry; + } + sumh += num2h; + // num2h + carry >= 1, thus sumh shoud > num1hTemp; otherwise overflow + if ((carry > 0 || num2h > 0) && sumh <= num1hTemp) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + *num1h = sumh; + *num1l = suml; + return 0; +} + +static int32_t CheckIsCorrupted(CRYPT_SHA2_512_Ctx *ctx, uint32_t nbytes) +{ + // bit len of data = len << 3, which may be 2^67, thus need to 2 uint64 to represent + uint64_t bitLenl = (uint64_t)nbytes << 3; // low 64 bit + // high 64 bit, right shift 61 to get higest 3 bit + uint64_t bitLenh = sizeof(nbytes) >= sizeof(uint64_t) ? (uint64_t)nbytes >> 61 : 0; + if (Add128Bit(&ctx->hNum, &ctx->lNum, bitLenh, bitLenl) != 0) { + // overflow, the len of msg over 2 ^ 128; + ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW; + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memset_s(ctx, sizeof(CRYPT_SHA2_512_Ctx), 0, sizeof(CRYPT_SHA2_512_Ctx)); + + // see RFC6234 chapter 6.3 + ctx->h[0] = U64(0x6a09e667f3bcc908); + ctx->h[1] = U64(0xbb67ae8584caa73b); + ctx->h[2] = U64(0x3c6ef372fe94f82b); + ctx->h[3] = U64(0xa54ff53a5f1d36f1); + ctx->h[4] = U64(0x510e527fade682d1); + ctx->h[5] = U64(0x9b05688c2b3e6c1f); + ctx->h[6] = U64(0x1f83d9abfb41bd6b); + ctx->h[7] = U64(0x5be0cd19137e2179); + ctx->mdlen = CRYPT_SHA2_512_DIGESTSIZE; + + return CRYPT_SUCCESS; +} + +void CRYPT_SHA2_512_Deinit(CRYPT_SHA2_512_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_512_Ctx)); +} + +int32_t CRYPT_SHA2_512_CopyCtx(CRYPT_SHA2_512_Ctx *dst, CRYPT_SHA2_512_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SHA2_512_Ctx), src, sizeof(CRYPT_SHA2_512_Ctx)); + return CRYPT_SUCCESS; +} + +static int32_t UpdateParamIsValid(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + if ((ctx == NULL) || (data == NULL && nbytes != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + + return CheckIsCorrupted(ctx, nbytes); +} + +int32_t CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + int32_t ret = UpdateParamIsValid(ctx, data, nbytes); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (nbytes == 0) { + return CRYPT_SUCCESS; + } + + const uint32_t n = CRYPT_SHA2_512_BLOCKSIZE - ctx->num; + if (nbytes < n) { + // if the data can't fill block, just copy data to block + (void)memcpy_s(ctx->block + ctx->num, n, data, nbytes); + ctx->num += (uint32_t)nbytes; + return CRYPT_SUCCESS; + } + + const uint8_t *d = data; + uint32_t dataLen = nbytes; + if (ctx->num != 0) { + // fill the block first and compute + (void)memcpy_s(ctx->block + ctx->num, n, data, n); + ctx->num = 0; + dataLen -= n; + d += n; + SHA512CompressMultiBlocks(ctx->h, ctx->block, 1); + } + + SHA512CompressMultiBlocks(ctx->h, d, dataLen / CRYPT_SHA2_512_BLOCKSIZE); + d += dataLen; + dataLen &= (CRYPT_SHA2_512_BLOCKSIZE - 1); + d -= dataLen; + + if (dataLen != 0) { + // copy rest data to blcok + if (memcpy_s(ctx->block, CRYPT_SHA2_512_BLOCKSIZE, d, dataLen) != EOK) { + BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL); + return CRYPT_SECUREC_FAIL; + } + ctx->num = (uint32_t)dataLen; + } + + return CRYPT_SUCCESS; +} + +static int32_t FinalParamIsValid(const CRYPT_SHA2_512_Ctx *ctx, const uint8_t *out, const uint32_t *outLen) +{ + if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (*outLen < ctx->mdlen) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH; + } + + if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW); + return CRYPT_SHA2_INPUT_OVERFLOW; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx *ctx, uint8_t *digest, uint32_t *len) +{ + int32_t ret = FinalParamIsValid(ctx, digest, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + uint32_t pad; + uint32_t n = ctx->num; + uint8_t *block = ctx->block; + + block[n++] = 0x80; + + if (n > SHA2_512_PADSIZE) { + pad = CRYPT_SHA2_512_BLOCKSIZE - n; + (void)memset_s(block + n, pad, 0, pad); + SHA512CompressMultiBlocks(ctx->h, block, 1); + n = 0; + pad = SHA2_512_PADSIZE; + } else { + pad = SHA2_512_PADSIZE - n; + } + + (void)memset_s(block + n, pad, 0, pad); + Uint64ToBeBytes(ctx->hNum, block + SHA2_512_PADSIZE); + Uint64ToBeBytes(ctx->lNum, block + SHA2_512_PADSIZE + sizeof(uint64_t)); + SHA512CompressMultiBlocks(ctx->h, block, 1); + + uint8_t *out = digest; + uint32_t ncnt = ctx->mdlen >> 3; // MDSize / 8, calculate the number of times that values need to be assigned to out + for (n = 0; n < ncnt; n++) { + Uint64ToBeBytes(ctx->h[n], out); + out += sizeof(uint64_t); + } + *len = ctx->mdlen; + + return CRYPT_SUCCESS; +} + +#ifdef HITLS_CRYPTO_SHA384 +int32_t CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_SHA2_384_Ctx), 0, sizeof(CRYPT_SHA2_384_Ctx)); + ctx->h[0] = U64(0xcbbb9d5dc1059ed8); + ctx->h[1] = U64(0x629a292a367cd507); + ctx->h[2] = U64(0x9159015a3070dd17); + ctx->h[3] = U64(0x152fecd8f70e5939); + ctx->h[4] = U64(0x67332667ffc00b31); + ctx->h[5] = U64(0x8eb44a8768581511); + ctx->h[6] = U64(0xdb0c2e0d64f98fa7); + ctx->h[7] = U64(0x47b5481dbefa4fa4); + ctx->mdlen = CRYPT_SHA2_384_DIGESTSIZE; + return CRYPT_SUCCESS; +} + +void CRYPT_SHA2_384_Deinit(CRYPT_SHA2_384_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_384_Ctx)); +} + +int32_t CRYPT_SHA2_384_CopyCtx(CRYPT_SHA2_384_Ctx *dst, CRYPT_SHA2_384_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SHA2_384_Ctx), src, sizeof(CRYPT_SHA2_384_Ctx)); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx *ctx, const uint8_t *data, uint32_t nbytes) +{ + return CRYPT_SHA2_512_Update((CRYPT_SHA2_512_Ctx *)ctx, data, nbytes); +} + +int32_t CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx *ctx, uint8_t *digest, uint32_t *len) +{ + return CRYPT_SHA2_512_Final((CRYPT_SHA2_512_Ctx *)ctx, digest, len); +} + +#endif // HITLS_CRYPTO_SHA384 + +#endif // HITLS_CRYPTO_SHA512 diff --git a/crypto/sha2/src/sha2_core.h b/crypto/sha2/src/sha2_core.h new file mode 100644 index 00000000..d6477b82 --- /dev/null +++ b/crypto/sha2/src/sha2_core.h @@ -0,0 +1,41 @@ +/* + * 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 SHA2_CORE_H +#define SHA2_CORE_H +#include +#include "hitls_build.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef U64 +#define U64(v) (uint64_t)(v) +#endif + +#ifdef HITLS_CRYPTO_SHA256 +void SHA256CompressMultiBlocks(uint32_t hash[8], const uint8_t *in, uint32_t num); +#endif + +#ifdef HITLS_CRYPTO_SHA512 +void SHA512CompressMultiBlocks(uint64_t hash[8], const uint8_t *bl, uint32_t bcnt); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // SHA2_CORE_H diff --git a/crypto/sha3/include/crypt_sha3.h b/crypto/sha3/include/crypt_sha3.h new file mode 100644 index 00000000..1eb33ee3 --- /dev/null +++ b/crypto/sha3/include/crypt_sha3.h @@ -0,0 +1,140 @@ +/* + * 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_SHA3_H +#define CRYPT_SHA3_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SHA3 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + + +/** @defgroup LLF SHA3 Low level function */ + +/* SHA3-224 */ +#define CRYPT_SHA3_224_BLOCKSIZE 144 // ((1600 - 224 * 2) / 8) +#define CRYPT_SHA3_224_DIGESTSIZE 28 + +/* SHA3-256 */ +#define CRYPT_SHA3_256_BLOCKSIZE 136 // ((1600 - 256 * 2) / 8) +#define CRYPT_SHA3_256_DIGESTSIZE 32 + +/* SHA3-384 */ +#define CRYPT_SHA3_384_BLOCKSIZE 104 // ((1600 - 384 * 2) / 8) +#define CRYPT_SHA3_384_DIGESTSIZE 48 + +/* SHA3-512 */ +#define CRYPT_SHA3_512_BLOCKSIZE 72 // ((1600 - 512 * 2) / 8) +#define CRYPT_SHA3_512_DIGESTSIZE 64 + +/* SHAKE128 */ +#define CRYPT_SHAKE128_BLOCKSIZE 168 // ((1600 - 128 * 2) / 8) +#define CRYPT_SHAKE128_DIGESTSIZE 0 + +/* SHAKE256 */ +#define CRYPT_SHAKE256_BLOCKSIZE 136 // ((1600 - 256 * 2) / 8) +#define CRYPT_SHAKE256_DIGESTSIZE 0 + +typedef struct { + uint8_t state[200]; // State array, 200bytes is 1600bits + uint32_t num; // Data length in the remaining buffer. + uint32_t blockSize; // For example, BlockSize(sha3-224) = ((1600 - 224 * 2) / 8) bytes + uint32_t mdSize; // sha3-224 corresponds to 28 bytes, sha3-256: 32 bytes, sha3-384: 48 bytes, sha3-512: 64 bytes + // Non-integer multiple data cache. 168 = (1600 - 128 * 2) / 8, that is maximum block size used by shake_* + uint8_t buf[168]; + uint8_t padChr; // char for padding, sha3_* use 0x06 and shake_* use 0x1f +} CRYPT_SHA3_Ctx; + +typedef CRYPT_SHA3_Ctx CRYPT_SHA3_224_Ctx; + +typedef CRYPT_SHA3_Ctx CRYPT_SHA3_256_Ctx; + +typedef CRYPT_SHA3_Ctx CRYPT_SHA3_384_Ctx; + +typedef CRYPT_SHA3_Ctx CRYPT_SHA3_512_Ctx; + +typedef CRYPT_SHA3_Ctx CRYPT_SHAKE128_Ctx; + +typedef CRYPT_SHA3_Ctx CRYPT_SHAKE256_Ctx; + +// Initialize the context +int32_t CRYPT_SHA3_224_Init(CRYPT_SHA3_224_Ctx *ctx); + +int32_t CRYPT_SHA3_256_Init(CRYPT_SHA3_256_Ctx *ctx); + +int32_t CRYPT_SHA3_384_Init(CRYPT_SHA3_384_Ctx *ctx); + +int32_t CRYPT_SHA3_512_Init(CRYPT_SHA3_512_Ctx *ctx); +int32_t CRYPT_SHAKE128_Init(CRYPT_SHAKE128_Ctx *ctx); +int32_t CRYPT_SHAKE256_Init(CRYPT_SHAKE256_Ctx *ctx); + +// Data update API +int32_t CRYPT_SHA3_224_Update(CRYPT_SHA3_224_Ctx *ctx, const uint8_t *in, uint32_t len); + +int32_t CRYPT_SHA3_256_Update(CRYPT_SHA3_256_Ctx *ctx, const uint8_t *in, uint32_t len); + +int32_t CRYPT_SHA3_384_Update(CRYPT_SHA3_384_Ctx *ctx, const uint8_t *in, uint32_t len); + +int32_t CRYPT_SHA3_512_Update(CRYPT_SHA3_512_Ctx *ctx, const uint8_t *in, uint32_t len); +int32_t CRYPT_SHAKE128_Update(CRYPT_SHAKE128_Ctx *ctx, const uint8_t *in, uint32_t len); +int32_t CRYPT_SHAKE256_Update(CRYPT_SHAKE256_Ctx *ctx, const uint8_t *in, uint32_t len); + +// Padding and output the digest value +int32_t CRYPT_SHA3_224_Final(CRYPT_SHA3_224_Ctx *ctx, uint8_t *out, uint32_t *len); + +int32_t CRYPT_SHA3_256_Final(CRYPT_SHA3_256_Ctx *ctx, uint8_t *out, uint32_t *len); + +int32_t CRYPT_SHA3_384_Final(CRYPT_SHA3_384_Ctx *ctx, uint8_t *out, uint32_t *len); + +int32_t CRYPT_SHA3_512_Final(CRYPT_SHA3_512_Ctx *ctx, uint8_t *out, uint32_t *len); +int32_t CRYPT_SHAKE128_Final(CRYPT_SHAKE128_Ctx *ctx, uint8_t *out, uint32_t *len); +int32_t CRYPT_SHAKE256_Final(CRYPT_SHAKE256_Ctx *ctx, uint8_t *out, uint32_t *len); + +// Clear the context +void CRYPT_SHA3_224_Deinit(CRYPT_SHA3_224_Ctx *ctx); + +void CRYPT_SHA3_256_Deinit(CRYPT_SHA3_256_Ctx *ctx); + +void CRYPT_SHA3_384_Deinit(CRYPT_SHA3_384_Ctx *ctx); + +void CRYPT_SHA3_512_Deinit(CRYPT_SHA3_512_Ctx *ctx); +void CRYPT_SHAKE128_Deinit(CRYPT_SHAKE128_Ctx *ctx); +void CRYPT_SHAKE256_Deinit(CRYPT_SHAKE256_Ctx *ctx); + +// Copy the context +int32_t CRYPT_SHA3_224_CopyCtx(CRYPT_SHA3_224_Ctx *dst, CRYPT_SHA3_224_Ctx *src); + +int32_t CRYPT_SHA3_256_CopyCtx(CRYPT_SHA3_256_Ctx *dst, CRYPT_SHA3_256_Ctx *src); + +int32_t CRYPT_SHA3_384_CopyCtx(CRYPT_SHA3_384_Ctx *dst, CRYPT_SHA3_384_Ctx *src); + +int32_t CRYPT_SHA3_512_CopyCtx(CRYPT_SHA3_512_Ctx *dst, CRYPT_SHA3_512_Ctx *src); + +#define CRYPT_SHAKE128_CopyCtx NULL +#define CRYPT_SHAKE256_CopyCtx NULL + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA3 + +#endif // CRYPT_SHA3_H diff --git a/crypto/sha3/src/asm/sha3_armv8.S b/crypto/sha3/src/asm/sha3_armv8.S new file mode 100644 index 00000000..780995b9 --- /dev/null +++ b/crypto/sha3/src/asm/sha3_armv8.S @@ -0,0 +1,771 @@ +/* + * 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_SHA3 + +.arch armv8-a+crypto + +/* + * Status matrix using register aliases + * A00~A04: x0~x4 + * A10~A14: x5~x9 + * A20~A24: x10~x14 + * A30~A34: x15~x19 + * A40~A44: x20~x24 + * T0~T4: x25~x29 temporary calculation register + */ +A00 .req x0 +A01 .req x1 +A02 .req x2 +A03 .req x3 +A04 .req x4 +A10 .req x5 +A11 .req x6 +A12 .req x7 +A13 .req x8 +A14 .req x9 +A20 .req x10 +A21 .req x11 +A22 .req x12 +A23 .req x13 +A24 .req x14 +A30 .req x15 +A31 .req x16 +A32 .req x17 +A33 .req x18 +A34 .req x19 +A40 .req x20 +A41 .req x21 +A42 .req x22 +A43 .req x23 +A44 .req x24 + +T0 .req x25 +T1 .req x26 +T2 .req x27 +T3 .req x28 +T4 .req x29 + +/** + * Macro Description: THETA mapping function + * Input register: + * A00~A44: x0~x24 State Matrix + * T0~T4: x25~x29 temporary calculation register + * Modify the register: + * A00~A44: x0~x24 State Matrix + * T0~T4: x25~x29 temporary calculation register + * Output register: + * A00~A44: x0~x24 The latest State Matrix, among them, The values of A10, A20, A30, + * and A40 are temporarily stored by T0, T1, T2, T3. + * T0~T3: x25 to x29 temporarily store the values of A10, A20, A30, and A40. + * Function/Macro Call: None + */ +.macro THETA + // for x in 0…4, C[x] = A[x,0] xor A[x,1] xor A[x,2] xor A[x,3] xor A[x,4] + eor T0, A00, A10 + eor T1, A01, A11 + eor T2, A02, A12 + eor T3, A03, A13 + eor T4, A04, A14 + + stp A00, A10, [sp, #-16]! // Borrow A00 and A10 + + eor T0, T0, A20 + eor T1, T1, A21 + eor T2, T2, A22 + eor T3, T3, A23 + eor T4, T4, A24 + + eor T0, T0, A30 + eor T1, T1, A31 + eor T2, T2, A32 + eor T3, T3, A33 + eor T4, T4, A34 + + eor T0, T0, A40 + eor T1, T1, A41 + eor T2, T2, A42 + eor T3, T3, A43 + eor T4, T4, A44 + + // D[1] = C[0] xor rol(C[2],1) + eor A00, T0, T2, ror#63 // Borrow A00 + // D[2] = C[1] xor rol(C[3],1) + eor A10, T1, T3, ror#63 // Borrow A10 + + // for y in 0…4, A[y][1] ^= D[1] + eor A01, A01, A00 + eor A11, A11, A00 + eor A21, A21, A00 + eor A31, A31, A00 + eor A41, A41, A00 + + // D[3] = C[2] xor rol(C[4],1) + eor T2, T2, T4, ror#63 + + // for y in 0…4, A[y][2] ^= D[2] + eor A02, A02, A10 + eor A12, A12, A10 + eor A22, A22, A10 + eor A32, A32, A10 + eor A42, A42, A10 + + // D[4] = C[3] xor rol(C[0],1) + eor T3, T3, T0, ror#63 + + // for y in 0…4, A[y][3] ^= D[3] + eor A03, A03, T2 + eor A13, A13, T2 + eor A23, A23, T2 + eor A33, A33, T2 + eor A43, A43, T2 + + ldp A00, A10, [sp], #16 // Restore A00 and A10 + + // D[0] = C[4] xor rol(C[1],1) + eor T4, T4, T1, ror#63 + + // for y in 0…4, A[y][4] ^= D[4] + eor A04, A04, T3 + eor A14, A14, T3 + eor A24, A24, T3 + eor A34, A34, T3 + eor A44, A44, T3 + + // for y in 0…4, A[y][0] ^= D[0] + eor A00, A00, T4 + eor T0, A10, T4 // Store A10, A20, A30, and A40 in the rho phase in advance. + eor T1, A20, T4 + eor T2, A30, T4 + eor T3, A40, T4 +.endm + +/** + * Macro Description: RHO mapping function and PI mapping function + * Input register: + * A00~A44: x0~x24 State Matrix among them, The values of A10, A20, A30, and A40 are temporarily stored by T0, + * T1, T2, T3 in the THETA function. + * T0~T3: x25 to x28: temporarily store the values of A10, A20, A30, and A40. + * Modify the register: + * A00~A44: x0~x24 State Matrix + * Output register: + * A00~A44: x0~x24 The latest State Matrix + * Function/Macro Call: None + * Implementation part: + * for x in 0…4: for y in 0…4: A[x, y] = rol(A[y,3x+y], rhotates[y,3x+y]) + */ +.macro RHOPi + ror A10, A03, #64-28 + ror A20, A01, #64-1 + ror A30, A04, #64-27 + ror A40, A02, #64-62 + + ror A01, A11, #64-44 + ror A02, A22, #64-43 + ror A03, A33, #64-21 + ror A04, A44, #64-14 + + ror A11, A14, #64-20 + ror A22, A23, #64-25 + ror A33, A32, #64-15 + ror A44, A41, #64-2 + + ror A14, A42, #64-61 + ror A23, A34, #64-8 + ror A32, A21, #64-10 + ror A41, A13, #64-55 + + ror A42, A24, #64-39 + ror A34, A43, #64-56 + ror A21, A12, #64-6 + ror A13, A31, #64-45 + + ror A24, T3, #64-18 + ror A43, T2, #64-41 + ror A12, T1, #64-3 + ror A31, T0, #64-36 +.endm + +/** + * Macro Description: CHI mapping function与IOTA mapping function + * Input register: + * A00~A44: x0~x24 State Matrix + * T0~T3: x25~x28 temporary calculation register + * Modify the register: + * A00~A44: x0~x24 State Matrix + * T0~T3: x25~x28 temporary calculation register + * Output register: + * A00~A44: x0~x24 The latest State Matrix + * Function/Macro Call: None + * Implementation part: + * for x in 0…4: for y in 0…4: A[x, y] ^= not A[x, y+1] and A[x, y+2] + * if x,y = 0,0: A[x, y] = A[x, y] xor iotas[i] + */ +.macro CHIOTA offset + // for y in 0…4: A[0, y] ^= not A[0, y+1] and A[0, y+2] + bic T0, A02, A01 + bic T1, A01, A00 + bic T2, A00, A04 + bic T3, A03, A02 + eor A00, A00, T0 + eor A01, A01, T3 + bic T0, A04, A03 + eor A02, A02, T0 + eor A03, A03, T2 + eor A04, A04, T1 + +#ifdef __ILP32__ + ldr w25, =g_roundConstant +#else + ldr x25, =g_roundConstant // x25 === T0 +#endif + ldr T3, [x25, \offset*8] + eor A00, A00, T3 // iota: A[0, 0] = A[0, 0] xor iotas[i] + + // for y in 0…4: A[1, y] ^= not A[1, y+1] and A[1, y+2] + bic T0, A12, A11 + bic T1, A11, A10 + bic T2, A10, A14 + bic T3, A13, A12 + eor A10, A10, T0 + eor A11, A11, T3 + bic T0, A14, A13 + eor A12, A12, T0 + eor A13, A13, T2 + eor A14, A14, T1 + + // for y in 0…4: A[2, y] ^= not A[2, y+1] and A[2, y+2] + bic T0, A22, A21 + bic T1, A21, A20 + bic T2, A20, A24 + bic T3, A23, A22 + eor A20, A20, T0 + eor A21, A21, T3 + bic T0, A24, A23 + eor A22, A22, T0 + eor A23, A23, T2 + eor A24, A24, T1 + + // for y in 0…4: A[3, y] ^= not A[3, y+1] and A[3, y+2] + bic T0, A32, A31 + bic T1, A31, A30 + bic T2, A30, A34 + bic T3, A33, A32 + eor A30, A30, T0 + eor A31, A31, T3 + bic T0, A34, A33 + eor A32, A32, T0 + eor A33, A33, T2 + eor A34, A34, T1 + + // for y in 0…4: A[4, y] ^= not A[4, y+1] and A[4, y+2] + bic T0, A42, A41 + bic T1, A41, A40 + bic T2, A40, A44 + bic T3, A43, A42 + eor A40, A40, T0 + eor A41, A41, T3 + bic T0, A44, A43 + eor A42, A42, T0 + eor A43, A43, T2 + eor A44, A44, T1 +.endm + +/** + * Macro Description: Round of phase mapping + * Input register: + * A00~A44: x0~x24 State Matrix + * T0~T4: x25~x29 temporary calculation register + * Modify the register: + * A00~A44: x0~x24 State Matrix + * T0~T4: x25~x29 temporary calculation register + * Output register: + * A00~A44: The latest State Matrix + * Function/Macro Call: THETA RHOPi CHIOTA + */ +.macro ROUND offset + THETA + RHOPi + CHIOTA \offset +.endm + +.section .rodata +.balign 64 +.type g_roundConstant, %object +g_roundConstant: + .quad 0x0000000000000001 + .quad 0x0000000000008082 + .quad 0x800000000000808a + .quad 0x8000000080008000 + .quad 0x000000000000808b + .quad 0x0000000080000001 + .quad 0x8000000080008081 + .quad 0x8000000000008009 + .quad 0x000000000000008a + .quad 0x0000000000000088 + .quad 0x0000000080008009 + .quad 0x000000008000000a + .quad 0x000000008000808b + .quad 0x800000000000008b + .quad 0x8000000000008089 + .quad 0x8000000000008003 + .quad 0x8000000000008002 + .quad 0x8000000000000080 + .quad 0x000000000000800a + .quad 0x800000008000000a + .quad 0x8000000080008081 + .quad 0x8000000000008080 + .quad 0x0000000080000001 + .quad 0x8000000080008008 + .size g_roundConstant, .-g_roundConstant + +/** + * Function description: Perform shA3 absorption according to the input message. + * Function prototype: const uint8_t *SHA3_Absorb(uint8_t *state, const uint8_t *in, uinT32_t inLen, uinT32_t r); + * Input register: + * x0: Pointer to the address of the State Matrix + * x1: Pointer to the input data address + * x2: Message length + * x3: Different shA3 algorithms are executed based on the shA3 parameter r. + * Register usage: A00~A44: x0~x24 State Matrix + * T0~T4: x25~x29 temporary calculation register + * Output register: x0 Returns the address of the message for which shA3 calculation is not performed. + * Function/Macro Call: ROUND + */ + +.text +.balign 16 +.global SHA3_Absorb +.type SHA3_Absorb, %function +SHA3_Absorb: + /* push stack protection */ + stp x29, x30, [sp, #-96]! + stp x19, x20, [sp, #8*2] + stp x21, x22, [sp, #8*4] + stp x23, x24, [sp, #8*6] + stp x25, x26, [sp, #8*8] + stp x27, x28, [sp, #8*10] + + stp x0, x1, [sp, #-32]! + stp x2, x3, [sp, #8*2] + mov x25, x0 + mov x26, x1 + mov x27, x2 + mov x28, x3 + + cmp x2, x3 + blo .Labsorb_end + + /* Load states: x0~x24 */ + ldp A00, A01, [x25] + ldp A02, A03, [x25, #16] + ldp A04, A10, [x25, #16*2] + ldp A11, A12, [x25, #16*3] + ldp A13, A14, [x25, #16*4] + ldp A20, A21, [x25, #16*5] + ldp A22, A23, [x25, #16*6] + ldp A24, A30, [x25, #16*7] + ldp A31, A32, [x25, #16*8] + ldp A33, A34, [x25, #16*9] + ldp A40, A41, [x25, #16*10] + ldp A42, A43, [x25, #16*11] + ldr A44, [x25, #16*12] + +.Labsorb: + /* Absorb from inputs according to r */ + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A00, A00, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A01, A01, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A02, A02, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A03, A03, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A04, A04, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A10, A10, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A11, A11, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A12, A12, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A13, A13, x25 + + cmp x28, #72 // SHA3_512: 72=8*9: (x0~x8) + beq .Labsorb_mapping + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A14, A14, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A20, A20, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A21, A21, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A22, A22, x25 + + cmp x28, #104 // SHA3_384: 104=8*13: (x0~x12) + beq .Labsorb_mapping + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A23, A23, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A24, A24, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A30, A30, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A31, A31, x25 + + cmp x28, #136 // SHA3_256: 136=8*17: (x0~x16) + beq .Labsorb_mapping + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A32, A32, x25 + + cmp x28, #144 // SHA3_224: 144=8*18: (x0~x17) + beq .Labsorb_mapping + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A33, A33, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A34, A34, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A40, A40, x25 + + cmp x28, #168 // SHAKE128: 168=8*21: (0~20) + beq .Labsorb_mapping + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A41, A41, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A42, A42, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A43, A43, x25 + + ldr x25, [x26], #8 +#ifdef HITLS_BIG_ENDIAN + rev x25, x25 +#endif + eor A44, A44, x25 + +.Labsorb_mapping: + /* Updating the Input Data Pointer and Length */ + sub x27, x27, x28 + stp x26, x27, [sp, #8] + /* Mapping */ + ROUND #0 + ROUND #1 + ROUND #2 + ROUND #3 + ROUND #4 + ROUND #5 + ROUND #6 + ROUND #7 + ROUND #8 + ROUND #9 + ROUND #10 + ROUND #11 + ROUND #12 + ROUND #13 + ROUND #14 + ROUND #15 + ROUND #16 + ROUND #17 + ROUND #18 + ROUND #19 + ROUND #20 + ROUND #21 + ROUND #22 + ROUND #23 + ldp x26, x27, [sp, #8] + ldr x28, [sp, #24] + cmp x27, x28 + bhs .Labsorb + + /* Store states: x0~x24 */ + ldr x25, [sp] + stp A00, A01, [x25] + stp A02, A03, [x25, #8*2] + stp A04, A10, [x25, #8*4] + stp A11, A12, [x25, #8*6] + stp A13, A14, [x25, #8*8] + stp A20, A21, [x25, #8*10] + stp A22, A23, [x25, #8*12] + stp A24, A30, [x25, #8*14] + stp A31, A32, [x25, #8*16] + stp A33, A34, [x25, #8*18] + stp A40, A41, [x25, #8*20] + stp A42, A43, [x25, #8*22] + str A44, [x25, #8*24] + +.Labsorb_end: + /* Return the remaining message address. */ + mov x0, x26 + + /* End popping */ + add sp, sp, #32 // skip x0~x3 + ldp x29, x30, [sp], #8*2 + ldp x19, x20, [sp], #8*2 + ldp x21, x22, [sp], #8*2 + ldp x23, x24, [sp], #8*2 + ldp x25, x26, [sp], #8*2 + ldp x27, x28, [sp], #8*2 + + ret +.size SHA3_Absorb, .-SHA3_Absorb + +.balign 16 +/** + * Function description: Perform SHA3 squeezing to obtain the digest message. + * Function prototyp: void SHA3_Squeeze(uint8_t *state, uint8_t *out, uinT32_t outLen, uinT32_t r) + * Input register: + * x0: Pointer to the address of the State Matrix + * x1: Pointer to the output summary address + * x2: digist Length + * x3: Different SHA3 algorithms are executed based on the SHA3 parameter r. + * Register usage: A00~A44: x0~x24 State Matrix + * T0~T4: x25~x29 temporary calculation register + * Output register: x1: Pointer to the output summary address + * Function/Macro Call: ROUND + */ +.global SHA3_Squeeze +.type SHA3_Squeeze, %function +SHA3_Squeeze: + /* push stack protection */ + stp x29, x30, [sp, #-96]! + stp x19, x20, [sp, #8*2] + stp x21, x22, [sp, #8*4] + stp x23, x24, [sp, #8*6] + stp x25, x26, [sp, #8*8] + stp x27, x28, [sp, #8*10] + + mov x25, x0 + mov x26, x1 + mov x27, x2 + mov x28, x3 + + /* Cyclically squeezing message summaries from the State Matrix */ +.Loop_squeeze: + ldr x4, [x0], #8 + cmp x27, #8 + blo .Lsqueeze_tail // If the remaining length is less than 8 bytes, perform single-byte extrusion. + +#ifdef HITLS_BIG_ENDIAN + rev x4, x4 +#endif + + str x4, [x26], #8 // Perform 8-byte squeeze + subs x27, x27, #8 + beq .Lsqueeze_done + + subs x3, x3, #8 + bhi .Loop_squeeze + + /* The length of the digest after extrusion is greater than r. Then, the digest is mapped and then extruded. */ + stp x25, x26, [sp, #-32]! + stp x27, x28, [sp, #8*2] + /* Load states: x0~x24 */ + ldp A00, A01, [x25] + ldp A02, A03, [x25, #16] + ldp A04, A10, [x25, #16*2] + ldp A11, A12, [x25, #16*3] + ldp A13, A14, [x25, #16*4] + ldp A20, A21, [x25, #16*5] + ldp A22, A23, [x25, #16*6] + ldp A24, A30, [x25, #16*7] + ldp A31, A32, [x25, #16*8] + ldp A33, A34, [x25, #16*9] + ldp A40, A41, [x25, #16*10] + ldp A42, A43, [x25, #16*11] + ldr A44, [x25, #16*12] + /* Mapping */ + ROUND #0 + ROUND #1 + ROUND #2 + ROUND #3 + ROUND #4 + ROUND #5 + ROUND #6 + ROUND #7 + ROUND #8 + ROUND #9 + ROUND #10 + ROUND #11 + ROUND #12 + ROUND #13 + ROUND #14 + ROUND #15 + ROUND #16 + ROUND #17 + ROUND #18 + ROUND #19 + ROUND #20 + ROUND #21 + ROUND #22 + ROUND #23 + + ldp x25, x26, [sp], #8*2 + ldp x27, x28, [sp], #8*2 + /* Store states: x0~x24 */ + stp A00, A01, [x25] + stp A02, A03, [x25, #8*2] + stp A04, A10, [x25, #8*4] + stp A11, A12, [x25, #8*6] + stp A13, A14, [x25, #8*8] + stp A20, A21, [x25, #8*10] + stp A22, A23, [x25, #8*12] + stp A24, A30, [x25, #8*14] + stp A31, A32, [x25, #8*16] + stp A33, A34, [x25, #8*18] + stp A40, A41, [x25, #8*20] + stp A42, A43, [x25, #8*22] + str A44, [x25, #8*24] + + mov x0, x25 + mov x3, x28 + b .Loop_squeeze + + /* Single Byte Squeezing */ +.Lsqueeze_tail: + strb w4, [x26], #1 + lsr x4, x4, #8 + subs x27, x27, #1 + beq .Lsqueeze_done + strb w4, [x26], #1 + lsr x4, x4, #8 + subs x27, x27, #1 + beq .Lsqueeze_done + strb w4, [x26], #1 + lsr x4, x4, #8 + subs x27, x27, #1 + beq .Lsqueeze_done + strb w4, [x26], #1 + lsr x4, x4, #8 + subs x27, x27, #1 + beq .Lsqueeze_done + strb w4, [x26], #1 + lsr x4, x4, #8 + subs x27, x27, #1 + beq .Lsqueeze_done + strb w4, [x26], #1 + lsr x4, x4, #8 + subs x27, x27, #1 + beq .Lsqueeze_done + strb w4, [x26], #1 + +.Lsqueeze_done: + /* End popping */ + ldp x29, x30, [sp], #8*2 + ldp x19, x20, [sp], #8*2 + ldp x21, x22, [sp], #8*2 + ldp x23, x24, [sp], #8*2 + ldp x25, x26, [sp], #8*2 + ldp x27, x28, [sp], #8*2 + eor x0, x0, x0 + ret +.size SHA3_Squeeze, .-SHA3_Squeeze + +#endif diff --git a/crypto/sha3/src/noasm_sha3.c b/crypto/sha3/src/noasm_sha3.c new file mode 100644 index 00000000..ffe2fab6 --- /dev/null +++ b/crypto/sha3/src/noasm_sha3.c @@ -0,0 +1,218 @@ +/* + * 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_SHA3 + +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "crypt_sha3.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +static void SHA3_Keccak(uint8_t *state); +static void Round(const uint64_t *a, uint64_t *e, uint32_t i); + +#define ROL64(a, offset) ((((uint64_t)(a)) << (offset)) ^ (((uint64_t)(a)) >> (64 - (offset)))) + +// the rotation offsets, see https://keccak.team/keccak_specs_summary.html +static const uint8_t g_rotationOffset[5][5] = { + { 0, 1, 62, 28, 27 }, + { 36, 44, 6, 55, 20 }, + { 3, 10, 43, 25, 39 }, + { 41, 45, 15, 21, 8 }, + { 18, 2, 61, 56, 14 } +}; + +// the round constants, see https://keccak.team/keccak_specs_summary.html +static const uint64_t g_roundConstant[24] = { + (uint64_t)0x0000000000000001, (uint64_t)0x0000000000008082, + (uint64_t)0x800000000000808a, (uint64_t)0x8000000080008000, + (uint64_t)0x000000000000808b, (uint64_t)0x0000000080000001, + (uint64_t)0x8000000080008081, (uint64_t)0x8000000000008009, + (uint64_t)0x000000000000008a, (uint64_t)0x0000000000000088, + (uint64_t)0x0000000080008009, (uint64_t)0x000000008000000a, + (uint64_t)0x000000008000808b, (uint64_t)0x800000000000008b, + (uint64_t)0x8000000000008089, (uint64_t)0x8000000000008003, + (uint64_t)0x8000000000008002, (uint64_t)0x8000000000000080, + (uint64_t)0x000000000000800a, (uint64_t)0x800000008000000a, + (uint64_t)0x8000000080008081, (uint64_t)0x8000000000008080, + (uint64_t)0x0000000080000001, (uint64_t)0x8000000080008008 +}; + +// Absorbing function of the sponge structure +const uint8_t *SHA3_Absorb(uint8_t *state, const uint8_t *in, uint32_t inLen, uint32_t r) +{ + const uint8_t *data = (const uint8_t *)in; + uint64_t *pSt = (uint64_t *)state; + uint32_t dataLen = inLen; + // Divide one block data into some uint64_t data (8 bytes) and perform XOR with the status variable. + uint32_t blockInWord = r / 8; + + while (dataLen >= r) { + for (uint32_t i = 0; i < blockInWord; i++) { + uint64_t oneLane = GET_UINT64_LE(data, i << 3); + pSt[i] ^= oneLane; + } + + // Process one block data. + SHA3_Keccak(state); + dataLen -= r; + data += r; + } + + return (const uint8_t *)data; +} + +// Squeezing function of the sponge structure +void SHA3_Squeeze(uint8_t *state, uint8_t *out, uint32_t outLen, uint32_t r) +{ + uint32_t dataLen = outLen; + uint32_t copyLen; + // Divide one block data into some uint64_t data (8 bytes) and perform XOR with the status variable. + uint32_t blockInWord = r / 8; + uint64_t *oneLane = (uint64_t *)state; + uint8_t outTmp[168]; + + while (dataLen > 0) { + copyLen = (dataLen > r) ? r : dataLen; + + for (uint32_t i = 0; i < blockInWord; i++) { + PUT_UINT64_LE(oneLane[i], outTmp, i << 3); // left shift by 3 bits equals i * 8. + } + (void)memcpy_s(out + outLen - dataLen, dataLen, outTmp, copyLen); + dataLen -= copyLen; + if (dataLen > 0) { + SHA3_Keccak(state); + } + } +} + +static void SHA3_Keccak(uint8_t *state) +{ + uint8_t stTmp[200] = {0}; + + // See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + // SHA3 depends on keccak-p[1600,24] for 24 rounds of cyclic calculation. + for (uint32_t i = 0; i < 24; i += 2) { + Round((uint64_t *)state, (uint64_t *)stTmp, i); + Round((uint64_t *)stTmp, (uint64_t *)state, i + 1); + } +} + +// see section 2.4 Algorithm 1 in https://keccak.team/files/Keccak-implementation-3.2.pdf +static void Round(const uint64_t *a, uint64_t *e, uint32_t i) +{ + uint64_t c[5], d[5]; + + // The corresponding formula for calculating the indexes of array A and array E is (5 * x) + y, + // the value of x is in [0, 4] and the value of y is [0, 4]. + // The row coordinates of the array index correspond to y in the algorithm principle, + // and the column coordinates correspond to x in the algorithm principle, for example, A[1, 1] = A[5 * 1 + 1] = A[6] + // THETA operation + c[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]; + c[1] = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]; + c[2] = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]; + c[3] = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]; + c[4] = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]; + + d[0] = ROL64(c[1], 1) ^ c[4]; + d[1] = ROL64(c[2], 1) ^ c[0]; + d[2] = ROL64(c[3], 1) ^ c[1]; + d[3] = ROL64(c[4], 1) ^ c[2]; + d[4] = ROL64(c[0], 1) ^ c[3]; + + // THETA RHP Pi operation + c[0] = a[0] ^ d[0]; + c[1] = ROL64(a[6] ^ d[1], g_rotationOffset[1][1]); + c[2] = ROL64(a[12] ^ d[2], g_rotationOffset[2][2]); + c[3] = ROL64(a[18] ^ d[3], g_rotationOffset[3][3]); + c[4] = ROL64(a[24] ^ d[4], g_rotationOffset[4][4]); + + // CHI IOTA operation, + e[0] = c[0] ^ (~c[1] & c[2]) ^ g_roundConstant[i]; + // CHI operation + e[1] = c[1] ^ (~c[2] & c[3]); + e[2] = c[2] ^ (~c[3] & c[4]); + e[3] = c[3] ^ (~c[4] & c[0]); + e[4] = c[4] ^ (~c[0] & c[1]); + + // THETA RHP Pi operation + c[0] = ROL64(a[3] ^ d[3], g_rotationOffset[0][3]); + c[1] = ROL64(a[9] ^ d[4], g_rotationOffset[1][4]); + c[2] = ROL64(a[10] ^ d[0], g_rotationOffset[2][0]); + c[3] = ROL64(a[16] ^ d[1], g_rotationOffset[3][1]); + c[4] = ROL64(a[22] ^ d[2], g_rotationOffset[4][2]); + + // CHI operation + e[5] = c[0] ^ (~c[1] & c[2]); + e[6] = c[1] ^ (~c[2] & c[3]); + e[7] = c[2] ^ (~c[3] & c[4]); + e[8] = c[3] ^ (~c[4] & c[0]); + e[9] = c[4] ^ (~c[0] & c[1]); + + // THETA RHP Pi operation + c[0] = ROL64(a[1] ^ d[1], g_rotationOffset[0][1]); + c[1] = ROL64(a[7] ^ d[2], g_rotationOffset[1][2]); + c[2] = ROL64(a[13] ^ d[3], g_rotationOffset[2][3]); + c[3] = ROL64(a[19] ^ d[4], g_rotationOffset[3][4]); + c[4] = ROL64(a[20] ^ d[0], g_rotationOffset[4][0]); + + // CHI operation + e[10] = c[0] ^ (~c[1] & c[2]); + e[11] = c[1] ^ (~c[2] & c[3]); + e[12] = c[2] ^ (~c[3] & c[4]); + e[13] = c[3] ^ (~c[4] & c[0]); + e[14] = c[4] ^ (~c[0] & c[1]); + + // THETA RHP Pi operation + c[0] = ROL64(a[4] ^ d[4], g_rotationOffset[0][4]); + c[1] = ROL64(a[5] ^ d[0], g_rotationOffset[1][0]); + c[2] = ROL64(a[11] ^ d[1], g_rotationOffset[2][1]); + c[3] = ROL64(a[17] ^ d[2], g_rotationOffset[3][2]); + c[4] = ROL64(a[23] ^ d[3], g_rotationOffset[4][3]); + + // CHI operation + e[15] = c[0] ^ (~c[1] & c[2]); + e[16] = c[1] ^ (~c[2] & c[3]); + e[17] = c[2] ^ (~c[3] & c[4]); + e[18] = c[3] ^ (~c[4] & c[0]); + e[19] = c[4] ^ (~c[0] & c[1]); + + // THETA RHP Pi operation + c[0] = ROL64(a[2] ^ d[2], g_rotationOffset[0][2]); + c[1] = ROL64(a[8] ^ d[3], g_rotationOffset[1][3]); + c[2] = ROL64(a[14] ^ d[4], g_rotationOffset[2][4]); + c[3] = ROL64(a[15] ^ d[0], g_rotationOffset[3][0]); + c[4] = ROL64(a[21] ^ d[1], g_rotationOffset[4][1]); + + // CHI operation + e[20] = c[0] ^ (~c[1] & c[2]); + e[21] = c[1] ^ (~c[2] & c[3]); + e[22] = c[2] ^ (~c[3] & c[4]); + e[23] = c[3] ^ (~c[4] & c[0]); + e[24] = c[4] ^ (~c[0] & c[1]); +} + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA3 diff --git a/crypto/sha3/src/sha3.c b/crypto/sha3/src/sha3.c new file mode 100644 index 00000000..8f24b19d --- /dev/null +++ b/crypto/sha3/src/sha3.c @@ -0,0 +1,272 @@ +/* + * 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_SHA3 + +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "sha3_core.h" +#include "crypt_sha3.h" + + +static int32_t CRYPT_SHA3_Init(CRYPT_SHA3_Ctx *ctx, uint32_t mdSize, uint32_t blockSize, uint8_t padChr) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_SHA3_Ctx), 0, sizeof(CRYPT_SHA3_Ctx)); + ctx->mdSize = mdSize; + ctx->padChr = padChr; + ctx->blockSize = blockSize; + return CRYPT_SUCCESS; +} + +static int32_t CRYPT_SHA3_Update(CRYPT_SHA3_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + if (ctx == NULL || (in == NULL && len != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len == 0) { + return CRYPT_SUCCESS; + } + const uint8_t *data = in; + uint32_t left = ctx->blockSize - ctx->num; + uint32_t dataLen = len; + + if (ctx->num != 0) { + if (dataLen < left) { + (void)memcpy_s(ctx->buf + ctx->num, left, data, dataLen); + ctx->num += dataLen; + return CRYPT_SUCCESS; + } + + // When the external input data is greater than the remaining space of the block, + // copy the data of the remaining space. + (void)memcpy_s(ctx->buf + ctx->num, left, data, left); + SHA3_Absorb(ctx->state, ctx->buf, ctx->blockSize, ctx->blockSize); + dataLen -= left; + data += left; + ctx->num = 0; + } + + data = SHA3_Absorb(ctx->state, data, dataLen, ctx->blockSize); + dataLen = len - (data - in); + if (dataLen != 0) { + // copy the remaining data to the cache array + (void)memcpy_s(ctx->buf, ctx->blockSize, data, dataLen); + ctx->num = dataLen; + } + + return CRYPT_SUCCESS; +} + +static int32_t CRYPT_SHA3_Final(CRYPT_SHA3_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + if (ctx == NULL || out == NULL || len == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (*len < ctx->mdSize) { + BSL_ERR_PUSH_ERROR(CRYPT_SHA3_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_SHA3_OUT_BUFF_LEN_NOT_ENOUGH; + } + + uint32_t left = ctx->blockSize - ctx->num; + uint32_t outLen = (ctx->mdSize == 0) ? *len : ctx->mdSize; + (void)memset_s(ctx->buf + ctx->num, left, 0, left); + ctx->buf[ctx->num] = ctx->padChr; + ctx->buf[ctx->blockSize - 1] |= 0x80; // 0x80 is the last 1 of pad 10*1 mode + + (void)SHA3_Absorb(ctx->state, ctx->buf, ctx->blockSize, ctx->blockSize); + SHA3_Squeeze(ctx->state, out, outLen, ctx->blockSize); + *len = outLen; + return CRYPT_SUCCESS; +} + +static void CRYPT_SHA3_Deinit(CRYPT_SHA3_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + BSL_SAL_CleanseData(ctx, sizeof(CRYPT_SHA3_Ctx)); +} + +static int32_t CRYPT_SHA3_CopyCtx(CRYPT_SHA3_Ctx *dst, CRYPT_SHA3_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SHA3_Ctx), src, sizeof(CRYPT_SHA3_Ctx)); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SHA3_224_Init(CRYPT_SHA3_224_Ctx *ctx) +{ + // 0x06 is SHA3 padding character, see https://keccak.team/keccak_specs_summary.html + return CRYPT_SHA3_Init(ctx, CRYPT_SHA3_224_DIGESTSIZE, CRYPT_SHA3_224_BLOCKSIZE, 0x06); +} + +int32_t CRYPT_SHA3_256_Init(CRYPT_SHA3_256_Ctx *ctx) +{ + // 0x06 is SHA3 padding character, see https://keccak.team/keccak_specs_summary.html + return CRYPT_SHA3_Init(ctx, CRYPT_SHA3_256_DIGESTSIZE, CRYPT_SHA3_256_BLOCKSIZE, 0x06); +} + +int32_t CRYPT_SHA3_384_Init(CRYPT_SHA3_384_Ctx *ctx) +{ + // 0x06 is SHA3 padding character, see https://keccak.team/keccak_specs_summary.html + return CRYPT_SHA3_Init(ctx, CRYPT_SHA3_384_DIGESTSIZE, CRYPT_SHA3_384_BLOCKSIZE, 0x06); +} + +int32_t CRYPT_SHA3_512_Init(CRYPT_SHA3_512_Ctx *ctx) +{ + // 0x06 is SHA3 padding character, see https://keccak.team/keccak_specs_summary.html + return CRYPT_SHA3_Init(ctx, CRYPT_SHA3_512_DIGESTSIZE, CRYPT_SHA3_512_BLOCKSIZE, 0x06); +} + +int32_t CRYPT_SHAKE128_Init(CRYPT_SHAKE128_Ctx *ctx) +{ + // 0x1f is SHA3 padding character, see https://keccak.team/keccak_specs_summary.html + return CRYPT_SHA3_Init(ctx, 0, CRYPT_SHAKE128_BLOCKSIZE, 0x1F); +} + +int32_t CRYPT_SHAKE256_Init(CRYPT_SHAKE256_Ctx *ctx) +{ + // 0x1f is SHA3 padding character, see https://keccak.team/keccak_specs_summary.html + return CRYPT_SHA3_Init(ctx, 0, CRYPT_SHAKE256_BLOCKSIZE, 0x1F); +} + +int32_t CRYPT_SHA3_224_Update(CRYPT_SHA3_224_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + return CRYPT_SHA3_Update(ctx, in, len); +} + +int32_t CRYPT_SHA3_256_Update(CRYPT_SHA3_256_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + return CRYPT_SHA3_Update(ctx, in, len); +} + +int32_t CRYPT_SHA3_384_Update(CRYPT_SHA3_384_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + return CRYPT_SHA3_Update(ctx, in, len); +} + +int32_t CRYPT_SHA3_512_Update(CRYPT_SHA3_512_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + return CRYPT_SHA3_Update(ctx, in, len); +} + +int32_t CRYPT_SHAKE128_Update(CRYPT_SHAKE128_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + return CRYPT_SHA3_Update(ctx, in, len); +} + +int32_t CRYPT_SHAKE256_Update(CRYPT_SHAKE256_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + return CRYPT_SHA3_Update(ctx, in, len); +} + +int32_t CRYPT_SHA3_224_Final(CRYPT_SHA3_224_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + return CRYPT_SHA3_Final(ctx, out, len); +} + +int32_t CRYPT_SHA3_256_Final(CRYPT_SHA3_256_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + return CRYPT_SHA3_Final(ctx, out, len); +} + +int32_t CRYPT_SHA3_384_Final(CRYPT_SHA3_384_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + return CRYPT_SHA3_Final(ctx, out, len); +} + +int32_t CRYPT_SHA3_512_Final(CRYPT_SHA3_512_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + return CRYPT_SHA3_Final(ctx, out, len); +} + +int32_t CRYPT_SHAKE128_Final(CRYPT_SHAKE128_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + return CRYPT_SHA3_Final(ctx, out, len); +} + +int32_t CRYPT_SHAKE256_Final(CRYPT_SHAKE256_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + return CRYPT_SHA3_Final(ctx, out, len); +} + +void CRYPT_SHA3_224_Deinit(CRYPT_SHA3_224_Ctx *ctx) +{ + CRYPT_SHA3_Deinit(ctx); +} + +void CRYPT_SHA3_256_Deinit(CRYPT_SHA3_256_Ctx *ctx) +{ + CRYPT_SHA3_Deinit(ctx); +} + +void CRYPT_SHA3_384_Deinit(CRYPT_SHA3_384_Ctx *ctx) +{ + CRYPT_SHA3_Deinit(ctx); +} + +void CRYPT_SHA3_512_Deinit(CRYPT_SHA3_512_Ctx *ctx) +{ + CRYPT_SHA3_Deinit(ctx); +} + +void CRYPT_SHAKE128_Deinit(CRYPT_SHAKE128_Ctx *ctx) +{ + CRYPT_SHA3_Deinit(ctx); +} + +void CRYPT_SHAKE256_Deinit(CRYPT_SHAKE256_Ctx *ctx) +{ + CRYPT_SHA3_Deinit(ctx); +} + +int32_t CRYPT_SHA3_224_CopyCtx(CRYPT_SHA3_224_Ctx *dst, CRYPT_SHA3_224_Ctx *src) +{ + return CRYPT_SHA3_CopyCtx(dst, src); +} + +int32_t CRYPT_SHA3_256_CopyCtx(CRYPT_SHA3_256_Ctx *dst, CRYPT_SHA3_256_Ctx *src) +{ + return CRYPT_SHA3_CopyCtx(dst, src); +} + +int32_t CRYPT_SHA3_384_CopyCtx(CRYPT_SHA3_384_Ctx *dst, CRYPT_SHA3_384_Ctx *src) +{ + return CRYPT_SHA3_CopyCtx(dst, src); +} + +int32_t CRYPT_SHA3_512_CopyCtx(CRYPT_SHA3_512_Ctx *dst, CRYPT_SHA3_512_Ctx *src) +{ + return CRYPT_SHA3_CopyCtx(dst, src); +} + +#endif // HITLS_CRYPTO_SHA3 diff --git a/crypto/sha3/src/sha3_core.h b/crypto/sha3/src/sha3_core.h new file mode 100644 index 00000000..459e13b4 --- /dev/null +++ b/crypto/sha3/src/sha3_core.h @@ -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 SHA3_CORE_H +#define SHA3_CORE_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SHA3 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const uint8_t *SHA3_Absorb(uint8_t *state, const uint8_t *in, uint32_t inLen, uint32_t r); +void SHA3_Squeeze(uint8_t *state, uint8_t *out, uint32_t outLen, uint32_t r); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SHA3 + +#endif // SHA3_CORE_H diff --git a/crypto/sm2/include/crypt_sm2.h b/crypto/sm2/include/crypt_sm2.h new file mode 100644 index 00000000..d5c3daa4 --- /dev/null +++ b/crypto/sm2/include/crypt_sm2.h @@ -0,0 +1,290 @@ +/* + * 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_SM2_H +#define CRYPT_SM2_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM2 + +#include +#include "crypt_types.h" +#include "crypt_ecc.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +typedef struct SM2_Ctx CRYPT_SM2_Ctx; +/* SM2 parameter structure */ +typedef struct EccPara CRYPT_Sm2Para; + +/** + * @ingroup sm2 + * @brief sm2 Allocate the context memory space. + * + * @retval (CRYPT_SM2_Ctx *) Pointer to the memory space of the allocated context + * @retval NULL Invalid null pointer. + */ +CRYPT_SM2_Ctx *CRYPT_SM2_NewCtx(void); + +/** + * @ingroup sm2 + * @brief Copy the sm2 context. After the duplication is complete, invoke the CRYPT_SM2_FreeCtx to release the memory. + * + * @param ctx [IN] Source SM2 context + * + * @return CRYPT_SM2_Ctx SM2 context pointer= + */ +CRYPT_SM2_Ctx *CRYPT_SM2_DupCtx(CRYPT_SM2_Ctx *ctx); + +/** + * @ingroup sm2 + * @brief release sm2 key context structure + * + * @param ctx [IN] Context structure to be released. + */ +void CRYPT_SM2_FreeCtx(CRYPT_SM2_Ctx *ctx); + +/** + * @ingroup sm2 + * @brief sm2 Obtain the key length. + * + * @param ctx [IN] sm2 context structure + * + * @retval 0 The input is incorrect or the corresponding key structure does not contain valid key length. + * @retval uint32_t Valid key length + */ +uint32_t CRYPT_SM2_GetBits(const CRYPT_SM2_Ctx *ctx); + +/** + * @ingroup sm2 + * @brief Generate the SM2 key pair. + * + * @param ctx [IN/OUT] sm2 context structure + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error code. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS The key pair is successfully generated. + */ +int32_t CRYPT_SM2_Gen(CRYPT_SM2_Ctx *ctx); + +#ifdef HITLS_CRYPTO_SM2_SIGN +/** + * @ingroup sm2 + * @brief sm2 obtain the length of the signature data, in bytes. + * + * @param ctx [IN] sm2 context structure + * + * @retval 0 The input is incorrect or the corresponding key structure does not contain valid parameter data. + * @retval uint32_t Length required for valid signature data + */ +uint32_t CRYPT_SM2_GetSignLen(const CRYPT_SM2_Ctx *ctx); + +/** + * @ingroup sm2 + * @brief SM2 Signature + * + * @param ctx [IN] sm2 context structure + * @param data [IN] Data to be signed + * @param dataLen [IN] Length of the data to be signed + * @param sign [OUT] Signature data + * @param signLen [IN/OUT] The input parameter is the space length of the sign, + * and the output parameter is the valid length of the sign. + * The required space can be obtained by calling CRYPT_SM2_GetSignLen. + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SM2_ERR_EMPTY_KEY The key cannot be empty. + * @retval CRYPT_SM2_BUFF_LEN_NOT_ENOUGH The buffer length is insufficient. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Signed successfully. + */ +int32_t CRYPT_SM2_Sign(const CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen); + +/** + * @ingroup sm2 + * @brief SM2 Verify the signature. + * + * @param ctx [IN] sm2 context structure + * @param data [IN] Data to be signed + * @param dataLen [IN] Length of the data to be signed + * @param sign [IN] Signature data + * @param signLen [IN] Valid length of the sign + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval CRYPT_SM2_VERIFY_FAIL Failed to verify the signature. + * @retval BN error. An error occurs in the internal BigNum operation. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval DSA error. An error occurs in the DSA encoding and decoding part. + * @retval CRYPT_SUCCESS The signature verification is successful. + */ +int32_t CRYPT_SM2_Verify(const CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen); +#endif + +/** + * @ingroup sm2 + * @brief SM2 Set the private key data. + * + * @param ctx [OUT] sm2 context structure + * @param prv [IN] External private key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS set successfully. + */ +int32_t CRYPT_SM2_SetPrvKey(CRYPT_SM2_Ctx *ctx, const CRYPT_Sm2Prv *prv); + +/** + * @ingroup sm2 + * @brief SM2 Set the public key data. + * + * @param ctx [OUT] sm2 context structure + * @param pub [IN] External public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS set successfully. + */ +int32_t CRYPT_SM2_SetPubKey(CRYPT_SM2_Ctx *ctx, const CRYPT_DsaPub *pub); + +/** + * @ingroup sm2 + * @brief SM2 Obtain the private key data. + * + * @param ctx [IN] sm2 context structure + * @param prv [OUT] External private key data + * + * @retval CRYPT_NULL_INPUT Error null pointer input + * @retval CRYPT_ECC_PKEY_ERR_EMPTY_KEY The key is empty. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS obtained successfully. + */ +int32_t CRYPT_SM2_GetPrvKey(const CRYPT_SM2_Ctx *ctx, CRYPT_DsaPrv *prv); + +/** + * @ingroup sm2 + * @brief SM2 Obtain the public key data. + * + * @param ctx [IN] sm2 context structure + * @param pub [OUT] External public key data + * + * @retval CRYPT_NULL_INPUT Invalid null pointer input + * @retval CRYPT_ECC_PKEY_ERR_EMPTY_KEY The key is empty. + * @retval ECC error. An error occurred in the internal ECC calculation. + * @retval CRYPT_SUCCESS Obtained successfully. + */ +int32_t CRYPT_SM2_GetPubKey(const CRYPT_SM2_Ctx *ctx, CRYPT_DsaPub *pub); + +/** + * @ingroup sm2 + * @brief sm2 control interface + * + * @param ctx [IN/OUT] sm2 context structure + * @param opt [IN] Operation mode. For details, see ECC_CtrlType. + * @param val [IN] Input parameter + * @param len [IN] val Length + * + * @retval CRYPT_SUCCESS set successfully. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_SM2_Ctrl(CRYPT_SM2_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len); + +#ifdef HITLS_CRYPTO_SM2_EXCH +/** + * @ingroup sm2 + * @brief sm2 Generate the shared key. + * + * @param selfCtx [IN] Local context structure + * @param peerCtx [IN] Peer context structure + * @param out [OUT] Generated shared key + * @param outlen [IN/OUT] Length of the generated shared key + * + * @retval CRYPT_SUCCESS secceeded. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_SM2_KapComputeKey(const CRYPT_SM2_Ctx *selfCtx, const CRYPT_SM2_Ctx *peerCtx, uint8_t *out, + uint32_t *outlen); +#endif + +#ifdef HITLS_CRYPTO_SM2_CRYPT +/** + * @ingroup sm2 + * @brief sm2 Encryption + * @param ctx [IN] Context structure + * @param data [IN] Plaintext + * @param datalen [IN] Plaintext length + * @param out [OUT] Output ciphertext + * @param outlen [OUT] Ciphertext length + * + * @retval CRYPT_SUCCESS secceeded. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_SM2_Encrypt(CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t datalen, uint8_t *out, uint32_t *outlen); + +/** + * @ingroup sm2 + * @brief sm2 Decryption + * @param ctx [IN] Context structure + * @param data [IN] Received ciphertext + * @param datalen [IN] Ciphertext length + * @param out [OUT] Output plaintext after decryption + * @param outlen [OUT] Length of the decrypted plaintext + * + * @retval CRYPT_SUCCESS secceeded. + * @retval CRYPT_NULL_INPUT If any input parameter is empty + * @retval For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_SM2_Decrypt(CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t datalen, uint8_t *out, uint32_t *outlen); +#endif +/** + * @ingroup sm2 + * @brief sm2 Compare the public key and parameters. + * + * @param a [IN] sm2 context structure + * @param b [IN] sm2 context structure + * + * @retval CRYPT_SUCCESS is the same + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_SM2_Cmp(const CRYPT_SM2_Ctx *a, const CRYPT_SM2_Ctx *b); + +/** + * @ingroup sm2 + * @brief sm2 get security bits + * + * @param para [IN] sm2 Context structure + * + * @retval security bits + */ +int32_t CRYPT_SM2_GetSecBits(const CRYPT_SM2_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SM2 + +#endif // CRYPT_SM2_H diff --git a/crypto/sm2/src/sm2_crypt.c b/crypto/sm2/src/sm2_crypt.c new file mode 100644 index 00000000..034e7354 --- /dev/null +++ b/crypto/sm2/src/sm2_crypt.c @@ -0,0 +1,312 @@ +/* + * 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_SM2_CRYPT +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_utils.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "crypt_ecc_pkey.h" +#include "crypt_local_types.h" +#include "sm2_local.h" +#include "crypt_sm2.h" +#include "crypt_encode.h" + +static void EncryptMemFree(ECC_Point *c1, ECC_Point *tmp, BN_BigNum *k, + BN_BigNum *order, uint8_t *c2) +{ + ECC_FreePoint(c1); + ECC_FreePoint(tmp); + BN_Destroy(k); + BN_Destroy(order); + BSL_SAL_FREE(c2); +} + +static int32_t ParaCheckAndCalculate(CRYPT_SM2_Ctx *ctx, ECC_Point *tmp, BN_BigNum *k) +{ + int32_t ret; + // Check whether [h]PB is equal to infinity point. + GOTO_ERR_IF(ECC_PointCheck(ctx->pkey->pubkey), ret); + // Calculate [k] * PB + GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, tmp, k, ctx->pkey->pubkey), ret); +ERR: + return ret; +} + +static int32_t Sm3Hash(const EAL_MdMethod *hashMethod, const uint8_t *pbBuf, const uint8_t *data, uint32_t datalen, + uint8_t *c3Buf, uint32_t *c3BufLen) +{ + int32_t ret; + void *mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + GOTO_ERR_IF(hashMethod->init(mdCtx), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, pbBuf + 1, + SM2_POINT_SINGLE_COORDINATE_LEN), ret); // Horizontal coordinate x2 of PB + GOTO_ERR_IF(hashMethod->update(mdCtx, data, datalen), ret); // M + GOTO_ERR_IF(hashMethod->update(mdCtx, pbBuf + SM2_POINT_SINGLE_COORDINATE_LEN + 1, + SM2_POINT_SINGLE_COORDINATE_LEN), ret); // Vertical coordinate y2 of PB + // Calculated c3, in c3Buf + GOTO_ERR_IF(hashMethod->final(mdCtx, c3Buf, c3BufLen), ret); +ERR: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +static int32_t IsDataZero(const uint8_t *data, uint32_t datalen) +{ + uint8_t check = 0; + for (uint32_t i = 0; i < datalen; i++) { + check |= data[i]; + } + if (check == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_DECRYPT_FAIL); + return CRYPT_SM2_DECRYPT_FAIL; + } + return CRYPT_SUCCESS; +} + +static int32_t MemAllocCheck(const BN_BigNum *k, const BN_BigNum *order, + const ECC_Point *c1, const ECC_Point *tmp, const uint8_t *c2) +{ + int32_t ret; + if (k == NULL || order == NULL || c1 == NULL || tmp == NULL || c2 == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +static void XorCalculate(uint8_t *c2, const uint8_t *data, uint32_t datalen) +{ + uint32_t i; + for (i = 0; i < datalen; ++i) { + c2[i] ^= data[i]; + } + return; +} + +static int32_t EncryptInputCheck(const CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t datalen, + const uint8_t *out, const uint32_t *outlen) +{ + int32_t ret; + // 0-length plaintext encryption is not supported. + if (ctx == NULL || data == NULL || datalen == 0 || out == NULL || outlen == NULL || *outlen == 0) { + ret = CRYPT_NULL_INPUT; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint64_t tmpdatalen = ASN1_Sm2GetEnCodeLen(datalen); + if ((uint64_t)*outlen < tmpdatalen || tmpdatalen > UINT32_MAX) { + ret = CRYPT_SM2_BUFF_LEN_NOT_ENOUGH; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ctx->pkey == NULL) { + ret = CRYPT_SM2_ERR_EMPTY_KEY; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ctx->pkey->pubkey == NULL) { + ret = CRYPT_SM2_NO_PUBKEY; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM2_Encrypt(CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t datalen, uint8_t *out, uint32_t *outlen) +{ + int32_t ret = EncryptInputCheck(ctx, data, datalen, out, outlen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + uint32_t i; + uint8_t *outTmp = BSL_SAL_Calloc(1u, SM2_POINT_COORDINATE_LEN + SM3_MD_SIZE + datalen); + if (outTmp == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + uint32_t outTmpLen = *outlen; + BN_BigNum *k = BN_Create(keyBits); + BN_BigNum *order = ECC_GetParaN(ctx->pkey->para); + ECC_Point *c1 = ECC_NewPoint(ctx->pkey->para); + ECC_Point *tmp = ECC_NewPoint(ctx->pkey->para); + uint32_t buflen = SM2_POINT_COORDINATE_LEN; + uint8_t c1Buf[SM2_POINT_COORDINATE_LEN]; + uint8_t tmpBuf[SM2_POINT_COORDINATE_LEN]; + uint8_t *c2 = BSL_SAL_Malloc(datalen); + uint8_t c3Buf[SM3_MD_SIZE]; + uint32_t c3BufLen = SM3_MD_SIZE; + GOTO_ERR_IF(MemAllocCheck(k, order, c1, tmp, c2), ret); + for (i = 0; i < CRYPT_ECC_TRY_MAX_CNT; i++) { + GOTO_ERR_IF(BN_RandRange(k, order), ret); + if (BN_IsZero(k)) { + continue; + } + // c1 = k * G + GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, c1, k, NULL), ret); + // Convert the point format into binary data stream and save the data stream in tmpbuf. + GOTO_ERR_IF(ECC_EncodePoint(ctx->pkey->para, c1, c1Buf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + GOTO_ERR_IF(ParaCheckAndCalculate(ctx, tmp, k), ret); + GOTO_ERR_IF(ECC_EncodePoint(ctx->pkey->para, tmp, tmpBuf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + // Calculate the kdf. + GOTO_ERR_IF(KdfGmt0032012(c2, &datalen, tmpBuf + 1, buflen - 1, ctx->hashMethod), ret); + if (IsDataZero(c2, datalen) == CRYPT_SUCCESS) { + break; + } + } + if (i == CRYPT_ECC_TRY_MAX_CNT) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_TRY_CNT); + ret = CRYPT_SM2_ERR_TRY_CNT; + goto ERR; + } + // Bitwise XOR + XorCalculate(c2, data, datalen); + // x2 || M || y2, calculate the hash value + GOTO_ERR_IF(Sm3Hash(ctx->hashMethod, tmpBuf, data, datalen, c3Buf, &c3BufLen), ret); + (void)memcpy_s(outTmp, outTmpLen, c1Buf, buflen); // c1 + (void)memcpy_s(outTmp + buflen, outTmpLen - buflen, c3Buf, c3BufLen); // c3 + (void)memcpy_s(outTmp + buflen + c3BufLen, outTmpLen - buflen - c3BufLen, c2, datalen); // c2 + outTmpLen = datalen + c3BufLen + buflen; + // outTmp, outTmpLen need to offset 1 bytes for skipping first bits which indicating identifiers of ecc point code. + GOTO_ERR_IF(ASN1_Sm2EncryptDataEncode(outTmp + 1, outTmpLen - 1, out, outlen), ret); +ERR: + BSL_SAL_FREE(outTmp); + EncryptMemFree(c1, tmp, k, order, c2); + return ret; +} + +static int32_t IsUEqualToC3(const uint8_t *data, const uint8_t *sm3Buf, uint32_t sm3BufLen) +{ + int32_t ret; + uint8_t check = 0; + for (uint32_t i = 0; i < sm3BufLen; i++) { + check |= sm3Buf[i] ^ data[i + SM2_POINT_COORDINATE_LEN]; + } + if (check != 0) { + ret = CRYPT_SM2_DECRYPT_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +static int32_t DecryptInputCheck(const CRYPT_SM2_Ctx *ctx, const uint8_t *data, const uint32_t datalen, + const uint8_t *out, const uint32_t *outlen) +{ + int32_t ret; + // 0-length plaintext decryption is not supported. + if (ctx == NULL || data == NULL || datalen == 0 || out == NULL || outlen == NULL || *outlen == 0) { + ret = CRYPT_NULL_INPUT; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ASN1_Sm2GetEnCodeLen(*outlen) < datalen) { + ret = CRYPT_SM2_BUFF_LEN_NOT_ENOUGH; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ctx->pkey == NULL) { + ret = CRYPT_SM2_ERR_EMPTY_KEY; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (ctx->pkey->prvkey == NULL) { + ret = CRYPT_SM2_NO_PRVKEY; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM2_Decrypt(CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t datalen, uint8_t *out, uint32_t *outlen) +{ + // take out the c1 + int32_t ret = DecryptInputCheck(ctx, data, datalen, out, outlen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t decodeLen = datalen; + uint8_t *decode = BSL_SAL_Calloc(1u, datalen); // The decoded length will be smaller than the original length. + if (decode == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + ret = ASN1_Sm2EncryptDataDecode(data, datalen, decode + 1, &decodeLen); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_FREE(decode); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + decode[0] = 0x04; // 0x04 indicate uncompressed. + // add 1 for marking '0x40' in pubkey decoode + uint32_t klen = decodeLen + 1 - SM2_POINT_COORDINATE_LEN - SM3_MD_SIZE; + ECC_Point *c1 = ECC_NewPoint(ctx->pkey->para); + ECC_Point *tmp = ECC_NewPoint(ctx->pkey->para); + uint8_t sm3Buf[SM3_MD_SIZE]; + uint32_t sm3BufLen = SM3_MD_SIZE; + uint32_t tmplen = SM2_POINT_COORDINATE_LEN; + uint8_t tmpBuf[SM2_POINT_COORDINATE_LEN]; + uint8_t *t = BSL_SAL_Malloc(klen); + if (c1 == NULL || tmp == NULL || t == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(ECC_DecodePoint(ctx->pkey->para, c1, decode, SM2_POINT_COORDINATE_LEN), ret); + // Calculate [dB]C1 = (x2, y2) and save it to the point tmp. + GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, tmp, ctx->pkey->prvkey, c1), ret); + // Extract x and y of the point tmp and save them to tmpbuf. + GOTO_ERR_IF(ECC_EncodePoint(ctx->pkey->para, tmp, tmpBuf, &tmplen, CRYPT_POINT_UNCOMPRESSED), ret); + // Calculate kdf(x2 || y2, klen), klen is msglen + GOTO_ERR_IF(KdfGmt0032012(t, &klen, tmpBuf + 1, tmplen - 1, ctx->hashMethod), ret); + // Check whether t is all 0s. If yes, report an error and exit. + GOTO_ERR_IF(IsDataZero(t, klen), ret); + // Calculate M' = C2 ^ t + // Bitwise XOR, and the result is still stored in t. + for (uint32_t i = 0; i < klen; ++i) { + t[i] ^= decode[i + SM2_POINT_COORDINATE_LEN + SM3_MD_SIZE]; + } + // Calculate hash(x2 || t || y2) + GOTO_ERR_IF(Sm3Hash(ctx->hashMethod, tmpBuf, t, klen, sm3Buf, &sm3BufLen), ret); + // Check whether u is equal to c3. + GOTO_ERR_IF(IsUEqualToC3(decode, sm3Buf, sm3BufLen), ret); + // The verification is successful. M' is the last plaintext. + (void)memcpy_s(out, *outlen, t, klen); + *outlen = klen; +ERR: + BSL_SAL_FREE(decode); + ECC_FreePoint(c1); + ECC_FreePoint(tmp); + BSL_SAL_CleanseData((void*)t, klen); + BSL_SAL_FREE(t); + return ret; +} +#endif // HITLS_CRYPTO_SM2_CRYPT diff --git a/crypto/sm2/src/sm2_exch.c b/crypto/sm2/src/sm2_exch.c new file mode 100644 index 00000000..b6a32182 --- /dev/null +++ b/crypto/sm2/src/sm2_exch.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_SM2_EXCH) || defined(HITLS_CRYPTO_SM2_CRYPT) + +#include +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_utils.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_ecc.h" +#include "crypt_ecc_pkey.h" +#include "crypt_local_types.h" +#include "crypt_sm2.h" +#include "sm2_local.h" + +/* GM/T003_2012 Defined Key Derive Function */ +int32_t KdfGmt0032012(uint8_t *out, const uint32_t *outlen, const uint8_t *z, uint32_t zlen, + const EAL_MdMethod *hashMethod) +{ + if (out == NULL || outlen == NULL || *outlen == 0 || (z == NULL && zlen != 0) || hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t counter; + uint8_t ctr[4]; + uint32_t mdlen; + int32_t ret; + uint32_t len = MAX_MD_SIZE; + void *mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + uint8_t dgst[MAX_MD_SIZE]; + uint8_t *tmp = out; + uint32_t tmplen = *outlen; + if (mdCtx == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + mdlen = (uint32_t)hashMethod->mdSize; + for (counter = 1;; counter++) { + GOTO_ERR_IF(hashMethod->init(mdCtx), ret); + PUT_UINT32_BE(counter, ctr, 0); + GOTO_ERR_IF(hashMethod->update(mdCtx, z, zlen), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, ctr, sizeof(ctr)), ret); + GOTO_ERR_IF(hashMethod->final(mdCtx, dgst, &len), ret); + if (tmplen > mdlen) { + (void)memcpy_s(tmp, tmplen, dgst, mdlen); + tmp += mdlen; + tmplen -= mdlen; + } else { + (void)memcpy_s(tmp, tmplen, dgst, tmplen); + (void)memset_s(dgst, mdlen, 0, mdlen); + break; + } + } +ERR: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +void Sm2CleanR(CRYPT_SM2_Ctx *ctx) +{ + BN_Destroy(ctx->r); + ctx->r = NULL; + ECC_FreePoint(ctx->pointR); + ctx->pointR = NULL; + return; +} + +static int32_t Sm2CalculateKey(const CRYPT_SM2_Ctx *selfCtx, const CRYPT_SM2_Ctx *peerCtx, ECC_Point *uorv, + uint8_t *out, uint32_t *outlen) +{ + uint32_t keyBits = CRYPT_SM2_GetBits(selfCtx); + uint32_t elementLen = (keyBits + 7) / 8; // Multiply keyBits by 8. Add 7 to round up the result. + int32_t ret; + uint32_t bufLen = elementLen * 2 + SM3_MD_SIZE * 2 + 1; /* add 1 byte tag; 2: 2 coordinates x and y, 2 z values */ + uint32_t dataLen = 0; // length of actual data; + uint32_t curLen = 0; // length of buffer reserved for the current operation. + uint8_t *buf = (uint8_t *)BSL_SAL_Calloc(bufLen, sizeof(uint8_t)); + if (buf == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + goto ERR; + } + /* 1 : Get public key for uorv, Notice: the first byte is a tag, not a valid char */ + curLen = elementLen * 2 + 1; // add 1 byte tag; 2: 2 coordinates x and y + GOTO_ERR_IF(ECC_EncodePoint(selfCtx->pkey->para, uorv, buf, &curLen, CRYPT_POINT_UNCOMPRESSED), ret); + dataLen += curLen; + if (selfCtx->server == 1) { + /* SIDE A, Z_A || Z_B, server is initiator(Z_A), client is responder(Z_B) */ + curLen = SM3_MD_SIZE; + GOTO_ERR_IF_EX(Sm2ComputeZDigest(selfCtx, buf + dataLen, &curLen), ret); + dataLen += curLen; + } + /* Caculate Peer z */ + curLen = SM3_MD_SIZE; + GOTO_ERR_IF_EX(Sm2ComputeZDigest(peerCtx, buf + dataLen, &curLen), ret); + dataLen += curLen; + if (selfCtx->server == 0) { + /* SIDE B */ + curLen = SM3_MD_SIZE; + GOTO_ERR_IF_EX(Sm2ComputeZDigest(selfCtx, buf + dataLen, &curLen), ret); + dataLen += curLen; + } + GOTO_ERR_IF(KdfGmt0032012(out, outlen, (const uint8_t *)(buf + 1), dataLen - 1, selfCtx->hashMethod), ret); +ERR: + BSL_SAL_FREE(buf); + return ret; +} + +static int32_t IsParamValid(const CRYPT_SM2_Ctx *selfCtx, const CRYPT_SM2_Ctx *peerCtx) +{ + if (selfCtx->pkey->prvkey == NULL || peerCtx->pkey->pubkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_EMPTY_KEY); + return CRYPT_SM2_ERR_EMPTY_KEY; + } + + if (selfCtx->hashMethod == NULL || peerCtx->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_NO_HASH_METHOD); + return CRYPT_SM2_ERR_NO_HASH_METHOD; + } + + if (peerCtx->pointR == NULL || selfCtx->r == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_R_NOT_SET); + return CRYPT_SM2_R_NOT_SET; + } + + if (selfCtx->pkey->pubkey == NULL) { + int32_t ret = ECC_GenPublicKey(selfCtx->pkey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + return CRYPT_SUCCESS; +} + +void BnMemDestroy(BN_BigNum *xs, BN_BigNum *xp, BN_BigNum *t, + BN_BigNum *twoPowerW, BN_BigNum *order) +{ + BN_Destroy(xs); + BN_Destroy(xp); + BN_Destroy(t); + BN_Destroy(twoPowerW); + BN_Destroy(order); +} + +static int32_t Sm3MsgHash(const EAL_MdMethod *hashMethod, const uint8_t *yBuf, const uint8_t *hashBuf, + uint8_t *out, uint32_t *outlen, uint8_t tag) +{ + int32_t ret; + void *mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + GOTO_ERR_IF(hashMethod->init(mdCtx), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, &tag, 1), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, yBuf, SM3_MD_SIZE), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, hashBuf, SM3_MD_SIZE), ret); + GOTO_ERR_IF(hashMethod->final(mdCtx, out, outlen), ret); +ERR: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +static int32_t Sm3InnerHash(const EAL_MdMethod *hashMethod, const uint8_t *coordinate, const uint8_t *zBuf, + uint32_t zlen, const uint8_t *rBuf, uint8_t *out, uint32_t *outlen) +{ + int32_t ret; + void *mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + GOTO_ERR_IF(hashMethod->init(mdCtx), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, coordinate, SM2_X_LEN), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, zBuf, zlen), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, rBuf, SM2_TWO_POINT_COORDINATE_LEN), ret); + GOTO_ERR_IF(hashMethod->final(mdCtx, out, outlen), ret); +ERR: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} + +int32_t Sm2KapFinalCheck(CRYPT_SM2_Ctx *sCtx, CRYPT_SM2_Ctx *pCtx, ECC_Point *uorv) +{ + int32_t ret; + uint32_t len = SM3_MD_SIZE; + uint8_t r1Buf[SM2_POINT_COORDINATE_LEN]; + uint8_t r2Buf[SM2_POINT_COORDINATE_LEN]; + uint8_t rBuf[SM2_TWO_POINT_COORDINATE_LEN]; + uint8_t xBuf[SM2_X_LEN]; + uint8_t yBuf[SM2_X_LEN]; + uint8_t zBuf[SM2_POINT_COORDINATE_LEN - 1]; + uint8_t stmpBuf[SM3_MD_SIZE]; + uint32_t buflen = SM2_POINT_COORDINATE_LEN; + uint32_t zlen = 0; + uint8_t tag1 = 0x03; + uint8_t tag2 = 0x02; + // Xv + GOTO_ERR_IF(ECC_EncodePoint(sCtx->pkey->para, uorv, r1Buf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + (void)memcpy_s(xBuf, SM2_X_LEN, r1Buf + 1, SM2_X_LEN); + (void)memcpy_s(yBuf, SM2_X_LEN, r1Buf + 1 + SM2_X_LEN, SM2_X_LEN); + // Calculate ZA || ZB + if (sCtx->server == 1) { + /* SIDE A, Z_A || Z_B, server is initiator(Z_A), client is responder(Z_B) */ + GOTO_ERR_IF_EX(Sm2ComputeZDigest(sCtx, zBuf, &len), ret); + zlen += len; + GOTO_ERR_IF(ECC_EncodePoint(sCtx->pkey->para, sCtx->pointR, r1Buf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + GOTO_ERR_IF(ECC_EncodePoint(sCtx->pkey->para, pCtx->pointR, r2Buf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + } + /* Calculate Peer z */ + GOTO_ERR_IF_EX(Sm2ComputeZDigest(pCtx, zBuf + zlen, &len), ret); + zlen += len; + if (sCtx->server == 0) { + /* SIDE B */ + GOTO_ERR_IF_EX(Sm2ComputeZDigest(sCtx, zBuf + zlen, &len), ret); + zlen += len; + GOTO_ERR_IF(ECC_EncodePoint(sCtx->pkey->para, pCtx->pointR, r1Buf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + GOTO_ERR_IF(ECC_EncodePoint(sCtx->pkey->para, sCtx->pointR, r2Buf, &buflen, CRYPT_POINT_UNCOMPRESSED), ret); + tag1 = 0x02; + tag2 = 0x03; + } + (void)memcpy_s(rBuf, SM2_TWO_POINT_COORDINATE_LEN, r1Buf + 1, SM2_POINT_COORDINATE_LEN - 1); + (void)memcpy_s(rBuf + SM2_POINT_COORDINATE_LEN - 1, SM2_TWO_POINT_COORDINATE_LEN - SM2_POINT_COORDINATE_LEN + 1, + r2Buf + 1, SM2_POINT_COORDINATE_LEN - 1); + // Calculate the hash value. + GOTO_ERR_IF_EX(Sm3InnerHash(sCtx->hashMethod, xBuf, zBuf, zlen, rBuf, stmpBuf, &len), ret); + // Calculate the hash value sent to the peer end. + GOTO_ERR_IF_EX(Sm3MsgHash(sCtx->hashMethod, yBuf, stmpBuf, sCtx->sumSend, &len, tag1), ret); + // Computes the hash value for validation + GOTO_ERR_IF_EX(Sm3MsgHash(sCtx->hashMethod, yBuf, stmpBuf, sCtx->sumCheck, &len, tag2), ret); + sCtx->isSumValid = 1; + return ret; +ERR: + sCtx->isSumValid = 0; // Reset checksum validity flag + return ret; +} + +static int SM2_PKG_Kdf(const CRYPT_SM2_Ctx *ctx, uint8_t *in, const uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + const uint32_t shareKeyLen = 16; + const EAL_MdMethod *hashMethod = ctx->hashMethod; + uint8_t *tmp = BSL_SAL_Malloc(hashMethod->mdSize); + uint32_t tmpLen = hashMethod->mdSize; + void *mdCtx = BSL_SAL_Malloc(hashMethod->ctxSize); + if (mdCtx == NULL || tmp == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(hashMethod->init(mdCtx), ret); + GOTO_ERR_IF(hashMethod->update(mdCtx, in, inLen), ret); + GOTO_ERR_IF(hashMethod->final(mdCtx, tmp, &tmpLen), ret); + if (memcpy_s(out, *outLen, tmp, shareKeyLen) != EOK) { + ret = CRYPT_SECUREC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + *outLen = shareKeyLen; +ERR: + hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + BSL_SAL_ClearFree(tmp, hashMethod->mdSize); + return ret; +} + +static int32_t SM2_PKGComputeKey(const CRYPT_SM2_Ctx *selfCtx, const CRYPT_SM2_Ctx *peerCtx, + uint8_t *out, uint32_t *outlen) +{ + if (selfCtx->pkey == NULL || peerCtx->pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (selfCtx->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_NO_HASH_METHOD); + return CRYPT_SM2_ERR_NO_HASH_METHOD; + } + int32_t ret; + uint8_t sharePointCode[65] = {0}; + uint32_t codeLen = sizeof(sharePointCode); + const ECC_Pkey *eccPkey = selfCtx->pkey; + BN_BigNum *tmpPrvkey = BN_Dup(eccPkey->prvkey); + ECC_Point *sharePoint = ECC_NewPoint(eccPkey->para); + if ((tmpPrvkey == NULL) || (sharePoint == NULL)) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(ECC_PointMul(eccPkey->para, sharePoint, eccPkey->prvkey, peerCtx->pkey->pubkey), ret); + GOTO_ERR_IF(ECC_PointCheck(sharePoint), ret); + GOTO_ERR_IF_EX(ECC_EncodePoint(eccPkey->para, sharePoint, sharePointCode, &codeLen, CRYPT_POINT_UNCOMPRESSED), ret); + GOTO_ERR_IF_EX(SM2_PKG_Kdf(selfCtx, sharePointCode + 1, codeLen - 1, out, outlen), ret); +ERR: + BN_Destroy(tmpPrvkey); + ECC_FreePoint(sharePoint); + return ret; +} + +int32_t CRYPT_SM2_KapComputeKey(const CRYPT_SM2_Ctx *selfCtx, const CRYPT_SM2_Ctx *peerCtx, + uint8_t *out, uint32_t *outlen) +{ + if (selfCtx == NULL || peerCtx == NULL || out == NULL || outlen == NULL || *outlen == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (selfCtx->pkgImpl != 0) { + return SM2_PKGComputeKey(selfCtx, peerCtx, out, outlen); + } + ECC_Point *uorv = ECC_NewPoint(selfCtx->pkey->para); + uint32_t keyBits = CRYPT_SM2_GetBits(selfCtx); + BN_BigNum *xs = BN_Create(keyBits); + BN_BigNum *xp = BN_Create(keyBits); + BN_BigNum *t = BN_Create(keyBits); + BN_BigNum *twoPowerW = BN_Create(keyBits); + BN_BigNum *order = ECC_GetParaN(selfCtx->pkey->para); + uint32_t w; + int32_t ret; + BN_Optimizer *opt = BN_OptimizerCreate(); + if (uorv == NULL || xs == NULL || xp == NULL || t == NULL || twoPowerW == NULL || + order == NULL || opt == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF(IsParamValid(selfCtx, peerCtx), ret); + /* Second: Caculate -- w */ + // w is equal to the number of digits of n rounded up, divided by 2, and then subtracted by 1. + w = (BN_Bits(order) + 1) / 2 - 1; + GOTO_ERR_IF(BN_Zeroize(twoPowerW), ret); + GOTO_ERR_IF(BN_SetBit(twoPowerW, w), ret); + /* Third: Caculate -- X = 2 ^ w + (x & (2 ^ w - 1)) = 2 ^ w + (x mod 2 ^ w) */ + /* Get x */ + GOTO_ERR_IF(ECC_GetPointDataX(selfCtx->pkey->para, selfCtx->pointR, xs), ret); + GOTO_ERR_IF(ECC_GetPointDataX(peerCtx->pkey->para, peerCtx->pointR, xp), ret); + /* x mod 2 ^ w */ + /* Caculate Self x */ + GOTO_ERR_IF(BN_Mod(xs, xs, twoPowerW, opt), ret); + GOTO_ERR_IF(BN_Add(xs, xs, twoPowerW), ret); + /* Caculate Peer x */ + GOTO_ERR_IF(BN_Mod(xp, xp, twoPowerW, opt), ret); + GOTO_ERR_IF(BN_Add(xp, xp, twoPowerW), ret); + /* Forth: Caculate t */ + GOTO_ERR_IF(BN_ModMul(t, xs, selfCtx->r, order, opt), ret); + GOTO_ERR_IF(BN_ModAddQuick(t, t, selfCtx->pkey->prvkey, order, opt), ret); + /* Fifth: Caculate V or U */ + GOTO_ERR_IF(ECC_PointMul(peerCtx->pkey->para, uorv, xp, peerCtx->pointR), ret); + /* P + [x]R */ + GOTO_ERR_IF(ECC_PointAdd(selfCtx->pkey->para, uorv, uorv, peerCtx->pkey->pubkey), ret); + GOTO_ERR_IF(ECC_PointMul(selfCtx->pkey->para, uorv, t, uorv), ret); + /* Detect uorv is in */ + GOTO_ERR_IF(ECC_PointCheck(uorv), ret); + /* Sixth: Caculate Key -- Need Xuorv, Yuorv, Zc, Zs, klen */ + GOTO_ERR_IF_EX(Sm2CalculateKey(selfCtx, peerCtx, uorv, out, outlen), ret); + GOTO_ERR_IF_EX(Sm2KapFinalCheck((CRYPT_SM2_Ctx *)(uintptr_t)selfCtx, (CRYPT_SM2_Ctx *)(uintptr_t)peerCtx, uorv), + ret); +ERR: + BnMemDestroy(xs, xp, t, twoPowerW, order); + ECC_FreePoint(uorv); + Sm2CleanR((CRYPT_SM2_Ctx *)(uintptr_t)selfCtx); + BN_OptimizerDestroy(opt); + return ret; +} +#endif diff --git a/crypto/sm2/src/sm2_local.h b/crypto/sm2/src/sm2_local.h new file mode 100644 index 00000000..4c4b85bd --- /dev/null +++ b/crypto/sm2/src/sm2_local.h @@ -0,0 +1,95 @@ +/* + * 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 SM2_LOCAL_H +#define SM2_LOCAL_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM2 + +#include +#include "crypt_sm2.h" +#include "crypt_local_types.h" +#include "crypt_ecc_pkey.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define SM2_MAX_ID_BITS 65535 +#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS / 8) +#define SM2_MAX_PUBKEY_DATA_LENGTH 256 +#define MAX_MD_SIZE 64 +#define SM3_MD_SIZE 32 +#define SM2_POINT_SINGLE_COORDINATE_LEN 32 +#define SM2_POINT_COORDINATE_LEN 65 +#define SM2_TWO_POINT_COORDINATE_LEN 128 +#define SM2_X_LEN 32 + +/* SM2 key context */ +struct SM2_Ctx { + ECC_Pkey *pkey; + uint32_t pkgImpl; + ECC_Point *pointR; // Local R + const EAL_MdMethod *hashMethod; + BN_BigNum *r; // Local r + uint8_t *userId; // User ID + uint32_t userIdLen; // the length of User ID + int32_t server; // 1: the initiator, 0: the receiver, and the default value is 1. + uint8_t sumCheck[SM3_MD_SIZE]; // Hash value used as a check + uint8_t sumSend[SM3_MD_SIZE]; // Hash value sent to the peer end + uint8_t isSumValid; // Indicates whether the checksum is valid. 1: valid; 0: invalid. + BSL_SAL_RefCount references; +}; + +/** + * @ingroup sm2 + * @brief The sm2 invokes the SM3 to calculate the hash value. + * + * @param ctx [IN] sm2 context structure + * @param out [IN/OUT] Hash value + * @param outLen [IN/OUT] Length of the hash value + * + * @retval CRYPT_SUCCESS calculated successfully. + * @retval Other: The calculation fails. For details about the return value type, see crypt_errno.h. + */ +int32_t Sm2ComputeZDigest(const CRYPT_SM2_Ctx *ctx, uint8_t *out, uint32_t *outLen); + +#if defined(HITLS_CRYPTO_SM2_EXCH) || defined(HITLS_CRYPTO_SM2_CRYPT) +/** + * @ingroup sm2 + * @brief sm2 kdf function + * + * @param out [IN/OUT] Calculation result + * @param outlen [IN/OUT] Output data length + * @param z [IN] Input data + * @param zlen [IN] Length of the input data + * @param hashMethod [IN] hash method + * + * @retval CRYPT_SUCCESS calculated successfully. + * @retval Other: The calculation fails. For details about the return value type, see crypt_errno.h. + */ +int32_t KdfGmt0032012(uint8_t *out, const uint32_t *outlen, const uint8_t *z, uint32_t zlen, + const EAL_MdMethod *hashMethod); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRYPTO_SM2 + +#endif // SM2_LOCAL_H diff --git a/crypto/sm2/src/sm2_sign.c b/crypto/sm2/src/sm2_sign.c new file mode 100644 index 00000000..9cc63f12 --- /dev/null +++ b/crypto/sm2/src/sm2_sign.c @@ -0,0 +1,871 @@ +/* + * 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_SM2 + +#include +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_utils.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_bn.h" +#include "crypt_encode.h" +#include "crypt_ecc.h" +#include "crypt_ecc_pkey.h" +#include "crypt_local_types.h" +#include "crypt_sm2.h" +#include "sm2_local.h" + +static int32_t Sm2SetUserId(CRYPT_SM2_Ctx *ctx, const uint8_t *val, uint32_t len) +{ + ctx->userId = BSL_SAL_Calloc(len, 1u); + if (ctx->userId == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + (void) memcpy_s(ctx->userId, len, val, len); + ctx->userIdLen = len; + return CRYPT_SUCCESS; +} + +CRYPT_SM2_Ctx *CRYPT_SM2_NewCtx(void) +{ + CRYPT_SM2_Ctx *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_SM2_Ctx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + ctx->pkey = ECC_PkeyNewCtx(CRYPT_ECC_SM2); + if (ctx->pkey == NULL) { + CRYPT_SM2_FreeCtx(ctx); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + ctx->server = 1; // Indicates the initiator by default. + ctx->isSumValid = 0; // checksum is invalid by default. + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +CRYPT_SM2_Ctx *CRYPT_SM2_DupCtx(CRYPT_SM2_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return NULL; + } + + CRYPT_SM2_Ctx *newCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_SM2_Ctx)); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pkey, ctx->pkey, ECC_DupCtx(ctx->pkey), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pointR, ctx->pointR, ECC_DupPoint(ctx->pointR), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->r, ctx->r, BN_Dup(ctx->r), CRYPT_MEM_ALLOC_FAIL); + GOTO_ERR_IF_SRC_NOT_NULL(newCtx->userId, ctx->userId, BSL_SAL_Dump(ctx->userId, ctx->userIdLen), + CRYPT_MEM_ALLOC_FAIL); + newCtx->userIdLen = ctx->userIdLen; + + newCtx->pkgImpl = ctx->pkgImpl; + newCtx->hashMethod = ctx->hashMethod; + newCtx->server = ctx->server; + newCtx->isSumValid = ctx->isSumValid; + BSL_SAL_ReferencesInit(&(newCtx->references)); + (void)memcpy_s(newCtx->sumCheck, SM3_MD_SIZE, ctx->sumCheck, SM3_MD_SIZE); + (void)memcpy_s(newCtx->sumSend, SM3_MD_SIZE, ctx->sumSend, SM3_MD_SIZE); + + return newCtx; +ERR: + CRYPT_SM2_FreeCtx(newCtx); + return NULL; +} + +void CRYPT_SM2_FreeCtx(CRYPT_SM2_Ctx *ctx) +{ + int val = 0; + if (ctx == NULL) { + return; + } + BSL_SAL_AtomicDownReferences(&(ctx->references), &val); + if (val > 0) { + return; + } + BSL_SAL_ReferencesFree(&(ctx->references)); + ECC_FreeCtx(ctx->pkey); + + BSL_SAL_FREE(ctx->userId); + BN_Destroy(ctx->r); + ECC_FreePoint(ctx->pointR); + BSL_SAL_FREE(ctx); + return; +} + +int32_t Sm2ComputeZDigest(const CRYPT_SM2_Ctx *ctx, uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + if (ctx->userIdLen >= (UINT16_MAX / 8)) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ID_TOO_LARGE); + return CRYPT_SM2_ID_TOO_LARGE; + } + /* 2-byte id length in bits */ + uint16_t entl = (uint16_t)(8 * ctx->userIdLen); + uint8_t eByte = (uint8_t)(entl >> 8); + uint8_t maxPubData[SM2_MAX_PUBKEY_DATA_LENGTH] = {0}; + CRYPT_Sm2Pub pub = {maxPubData, SM2_MAX_PUBKEY_DATA_LENGTH}; + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + BN_BigNum *a = ECC_GetParaA(ctx->pkey->para); + BN_BigNum *b = ECC_GetParaB(ctx->pkey->para); + BN_BigNum *xG = ECC_GetParaX(ctx->pkey->para); + BN_BigNum *yG = ECC_GetParaY(ctx->pkey->para); + void *mdCtx = BSL_SAL_Malloc(ctx->hashMethod->ctxSize); + uint8_t *buf = BSL_SAL_Calloc(1u, keyBits); + if (a == NULL || b == NULL || xG == NULL || yG == NULL || buf == NULL || mdCtx == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + CRYPT_SM2_GetPubKey(ctx, &pub); + GOTO_ERR_IF(ctx->hashMethod->init(mdCtx), ret); + // User A has a distinguishable identifier IDA with a length of entlenA bits, + // and ENTLA is two bytes converted from an integer entlenA + // H256(ENTLA || IDA || a || b || xG || yG || xA || yA) + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, &eByte, 1), ret); // ENTLA + eByte = entl & 0xFF; + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, &eByte, 1), ret); // ENTLA + if (ctx->userIdLen > 0) { + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, ctx->userId, ctx->userIdLen), ret); // IDA + } + GOTO_ERR_IF_EX(BN_Bn2Bin(a, buf, &keyBits), ret); + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // a + GOTO_ERR_IF_EX(BN_Bn2Bin(b, buf, &keyBits), ret); + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // b + GOTO_ERR_IF_EX(BN_Bn2Bin(xG, buf, &keyBits), ret); + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // xG + keyBits = CRYPT_SM2_GetBits(ctx); + GOTO_ERR_IF_EX(BN_Bn2Bin(yG, buf, &keyBits), ret); + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // yG + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, pub.data + 1, pub.len - 1), ret); // xA and yA + GOTO_ERR_IF(ctx->hashMethod->final(mdCtx, out, outLen), ret); +ERR: + ctx->hashMethod->deinit(mdCtx); + BN_Destroy(a); + BN_Destroy(b); + BN_Destroy(xG); + BN_Destroy(yG); + BSL_SAL_FREE(mdCtx); + BSL_SAL_FREE(buf); + return ret; +} + +#ifdef HITLS_CRYPTO_SM2_SIGN +static int32_t Sm2ComputeMsgHash(const CRYPT_SM2_Ctx *ctx, const uint8_t *msg, uint32_t msgLen, BN_BigNum *e) +{ + int ret; + uint8_t out[SM3_MD_SIZE]; + uint32_t outLen = sizeof(out); + void *mdCtx = BSL_SAL_Calloc(1u, ctx->hashMethod->ctxSize); + if (mdCtx == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF_EX(Sm2ComputeZDigest(ctx, out, &outLen), ret); + GOTO_ERR_IF(ctx->hashMethod->init(mdCtx), ret); + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, out, outLen), ret); + GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, msg, msgLen), ret); + GOTO_ERR_IF(ctx->hashMethod->final(mdCtx, out, &outLen), ret); + GOTO_ERR_IF_EX(BN_Bin2Bn(e, out, outLen), ret); +ERR: + ctx->hashMethod->deinit(mdCtx); + BSL_SAL_FREE(mdCtx); + return ret; +} +#endif + +uint32_t CRYPT_SM2_GetBits(const CRYPT_SM2_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return ECC_PkeyGetBits(ctx->pkey); +} + +int32_t CRYPT_SM2_SetPrvKey(CRYPT_SM2_Ctx *ctx, const CRYPT_Sm2Prv *prv) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ECC_PkeySetPrvKey(ctx->pkey, prv); +} + +int32_t CRYPT_SM2_SetPubKey(CRYPT_SM2_Ctx *ctx, const CRYPT_Sm2Pub *pub) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ECC_PkeySetPubKey(ctx->pkey, pub); +} + +int32_t CRYPT_SM2_GetPrvKey(const CRYPT_SM2_Ctx *ctx, CRYPT_Sm2Prv *prv) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return ECC_PkeyGetPrvKey(ctx->pkey, prv); +} + +int32_t CRYPT_SM2_GetPubKey(const CRYPT_SM2_Ctx *ctx, CRYPT_Sm2Pub *pub) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return ECC_PkeyGetPubKey(ctx->pkey, pub); +} + +int32_t CRYPT_SM2_Gen(CRYPT_SM2_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return ECC_PkeyGen(ctx->pkey); +} + +#ifdef HITLS_CRYPTO_SM2_SIGN +uint32_t CRYPT_SM2_GetSignLen(const CRYPT_SM2_Ctx *ctx) +{ + if (ctx == NULL || ctx->pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + uint32_t qLen = (ECC_ParaBits(ctx->pkey->para) / 8) + 1; + return ASN1_SignEnCodeLen(qLen, qLen); +} + +static void Sm2SignFree(DSA_Sign *sign) +{ + if (sign == NULL) { + return; + } + BN_Destroy(sign->r); + BN_Destroy(sign->s); + BSL_SAL_FREE(sign); + return; +} + +static DSA_Sign *Sm2SignNew(const CRYPT_SM2_Ctx *ctx) +{ + DSA_Sign *sign = BSL_SAL_Malloc(sizeof(DSA_Sign)); + if (sign == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + uint32_t keyBits = ECC_PkeyGetBits(ctx->pkey); + sign->r = BN_Create(keyBits); + sign->s = BN_Create(keyBits); + if ((sign->r == NULL) || (sign->s == NULL)) { + Sm2SignFree(sign); + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return NULL; + } + return sign; +} + +static int32_t Sm2SignCore(const CRYPT_SM2_Ctx *ctx, BN_BigNum *e, DSA_Sign *sign) +{ + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + BN_BigNum *k = BN_Create(keyBits); + BN_BigNum *tmp = BN_Create(keyBits); + // An extra bit is allocated to prevent the number of bits in the result of adding BNs from exceeding the keybits. + BN_BigNum *t = BN_Create(keyBits + 1); + BN_BigNum *paraN = ECC_GetParaN(ctx->pkey->para); + ECC_Point *pt = ECC_NewPoint(ctx->pkey->para); + BN_Optimizer *opt = BN_OptimizerCreate(); + int32_t ret, i; + + if ((k == NULL) || (tmp == NULL) || (t == NULL) || (pt == NULL) || (paraN == NULL) || (opt == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + for (i = 0; i < CRYPT_ECC_TRY_MAX_CNT; i++) { + GOTO_ERR_IF(BN_RandRange(k, paraN), ret); + if (BN_IsZero(k)) { + continue; + } + // pt = k * G + GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, pt, k, NULL), ret); + // sign->r = (e + pt->x) mod n + GOTO_ERR_IF(ECC_GetPointDataX(ctx->pkey->para, pt, tmp), ret); + GOTO_ERR_IF(BN_ModAdd(sign->r, e, tmp, paraN, opt), ret); + // if sign->r == 0 || r + k == n, then restart + GOTO_ERR_IF(BN_Add(t, sign->r, k), ret); + if (BN_IsZero(sign->r) || BN_Cmp(t, paraN) == 0) { + continue; + } + // prvkey * r mod n == (r * dA) mod n + GOTO_ERR_IF(BN_ModMul(sign->s, ctx->pkey->prvkey, sign->r, paraN, opt), ret); + // k - prvkey * r mod n + GOTO_ERR_IF(BN_ModSub(sign->s, k, sign->s, paraN, opt), ret); + // 1/(1 + d) mod n, tmp stores 1/(1 + d) + GOTO_ERR_IF(BN_AddLimb(t, ctx->pkey->prvkey, 1), ret); + GOTO_ERR_IF(BN_ModInv(tmp, t, paraN, opt), ret); + // sign->s = (1/(1+d)) * (k - prvkey * r) mod n + GOTO_ERR_IF(BN_ModMul(sign->s, tmp, sign->s, paraN, opt), ret); + // if sign->s == 0, then restart + if (BN_IsZero(sign->s) != true) { + break; + } + } + if (i >= CRYPT_ECC_TRY_MAX_CNT) { + ret = CRYPT_SM2_ERR_TRY_CNT; + BSL_ERR_PUSH_ERROR(ret); + } + +ERR: + BN_Destroy(k); + BN_Destroy(tmp); + BN_Destroy(t); + BN_Destroy(paraN); + ECC_FreePoint(pt); + BN_OptimizerDestroy(opt); + return ret; +} + +int32_t KeyCheckAndPubGen(const CRYPT_SM2_Ctx *ctx) +{ + int32_t ret; + if (ctx->pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_EMPTY_KEY); + return CRYPT_SM2_ERR_EMPTY_KEY; + } + + if (ctx->pkey->prvkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_NO_PRVKEY); + return CRYPT_SM2_NO_PRVKEY; + } + if (ctx->pkey->pubkey != NULL) { + return CRYPT_SUCCESS; + } + ret = ECC_GenPublicKey(ctx->pkey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM2_Sign(const CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + uint8_t *sign, uint32_t *signLen) +{ + int32_t ret; + if ((ctx == NULL) || (sign == NULL) || (signLen == NULL) || ((data == NULL) && (dataLen != 0))) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + ret = KeyCheckAndPubGen(ctx); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (ctx->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_NO_HASH_METHOD); + return CRYPT_SM2_ERR_NO_HASH_METHOD; + } + if (*signLen < CRYPT_SM2_GetSignLen(ctx)) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_BUFF_LEN_NOT_ENOUGH); + return CRYPT_SM2_BUFF_LEN_NOT_ENOUGH; + } + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + DSA_Sign *s = Sm2SignNew(ctx); + BN_BigNum *d = BN_Create(keyBits); + if (s == NULL || d == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF_EX(Sm2ComputeMsgHash(ctx, data, dataLen, d), ret); + GOTO_ERR_IF_EX(Sm2SignCore(ctx, d, s), ret); + ret = ASN1_SignDataEncode(s, sign, signLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +ERR: + Sm2SignFree(s); + BN_Destroy(d); + return ret; +} + +static int32_t VerifyCheckSign(const CRYPT_SM2_Ctx *ctx, DSA_Sign *sign) +{ + int32_t ret = CRYPT_SUCCESS; + if (ctx->pkey->para == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + BN_BigNum *paraN = ECC_GetParaN(ctx->pkey->para); + if (paraN == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + + if ((BN_Cmp(sign->r, paraN) >= 0) || (BN_Cmp(sign->s, paraN) >= 0)) { + ret = CRYPT_SM2_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + if (BN_IsZero(sign->r) || BN_IsZero(sign->s)) { + ret = CRYPT_SM2_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } + +ERR: + BN_Destroy(paraN); + return ret; +} + +static int32_t Sm2VerifyCore(const CRYPT_SM2_Ctx *ctx, BN_BigNum *e, const DSA_Sign *sign) +{ + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + BN_BigNum *t = BN_Create(keyBits); + ECC_Point *tpt = ECC_NewPoint(ctx->pkey->para); + BN_BigNum *tptX = BN_Create(keyBits); + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *paraN = ECC_GetParaN(ctx->pkey->para); + int32_t ret; + + if ((t == NULL) || (tpt == NULL) || (tptX == NULL) || (paraN == NULL) || (opt == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + ret = CRYPT_MEM_ALLOC_FAIL; + goto ERR; + } + // B5: calculate t = (r' + s') modn, verification failed if t=0 + GOTO_ERR_IF_EX(BN_ModAdd(t, sign->r, sign->s, paraN, opt), ret); + if (BN_IsZero(t)) { + ret = CRYPT_SM2_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } + // calculate the point (x1', y1')=[s']G + [t]PA + GOTO_ERR_IF(ECC_PointMulAdd(ctx->pkey->para, tpt, sign->s, t, ctx->pkey->pubkey), ret); + GOTO_ERR_IF_EX(ECC_GetPointDataX(ctx->pkey->para, tpt, tptX), ret); + // calculate R=(e'+x1') modn, verification pass if yes, otherwise failed + GOTO_ERR_IF_EX(BN_ModAdd(t, e, tptX, paraN, opt), ret); + if (BN_Cmp(sign->r, t) != 0) { + ret = CRYPT_SM2_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + } + +ERR: + BN_Destroy(t); + BN_Destroy(paraN); + ECC_FreePoint(tpt); + BN_Destroy(tptX); + BN_OptimizerDestroy(opt); + return ret; +} + +static int32_t IsParaVaild(const CRYPT_SM2_Ctx *ctx) +{ + if (ctx->pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_EMPTY_KEY); + return CRYPT_SM2_ERR_EMPTY_KEY; + } + + if (ctx->pkey->pubkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_NO_PUBKEY); + return CRYPT_SM2_NO_PUBKEY; + } + + if (ctx->hashMethod == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_NO_HASH_METHOD); + return CRYPT_SM2_ERR_NO_HASH_METHOD; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM2_Verify(const CRYPT_SM2_Ctx *ctx, const uint8_t *data, uint32_t dataLen, + const uint8_t *sign, uint32_t signLen) +{ + if ((ctx == NULL) || ((data == NULL) && (dataLen != 0)) || (sign == NULL) || (signLen == 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + int32_t ret; + ret = IsParaVaild(ctx); + if (ret != CRYPT_SUCCESS) { + return ret; + } + DSA_Sign *s = Sm2SignNew(ctx); + BN_BigNum *e = BN_Create(keyBits); + if (s == NULL || e == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + GOTO_ERR_IF_EX(Sm2ComputeMsgHash(ctx, data, dataLen, e), ret); + GOTO_ERR_IF(ASN1_SignDataDecode(s, sign, signLen), ret); + // Verify that r->s and s->s are within the range of 1~n-1. + GOTO_ERR_IF_EX(VerifyCheckSign(ctx, s), ret); + GOTO_ERR_IF_EX(Sm2VerifyCore(ctx, e, s), ret); +ERR: + Sm2SignFree(s); + BN_Destroy(e); + return ret; +} +#endif + +static void Sm2Clean(CRYPT_SM2_Ctx *ctx) +{ + BN_Destroy(ctx->r); + ctx->r = NULL; + ECC_FreePoint(ctx->pointR); + ctx->pointR = NULL; + ctx->isSumValid = 0; + return; +} + +static int32_t Sm2GenerateR(CRYPT_SM2_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + Sm2Clean(ctx); + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + int32_t tryNum = 0; + BN_BigNum *order = ECC_GetParaN(ctx->pkey->para); + ctx->r = BN_Create(keyBits); + ctx->pointR = ECC_NewPoint(ctx->pkey->para); + BN_BigNum *tmp = BN_Create(keyBits); + if (order == NULL || ctx->r == NULL || ctx->pointR == NULL || tmp == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + for (; tryNum < CRYPT_ECC_TRY_MAX_CNT; tryNum++) { + GOTO_ERR_IF_EX(BN_RandRange(ctx->r, order), ret); + if (!BN_IsZero(ctx->r)) { + break; + } + } + + if (tryNum >= CRYPT_ECC_TRY_MAX_CNT) { + ret = CRYPT_SM2_ERR_TRY_CNT; + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_TRY_CNT); + goto ERR; + } + + GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, ctx->pointR, ctx->r, NULL), ret); + GOTO_ERR_IF(ECC_GetPointDataX(ctx->pkey->para, ctx->pointR, tmp), ret); + GOTO_ERR_IF(ECC_EncodePoint(ctx->pkey->para, ctx->pointR, (uint8_t *)val, &len, CRYPT_POINT_UNCOMPRESSED), ret); + BN_Destroy(tmp); + BN_Destroy(order); + return ret; +ERR: + BN_Destroy(tmp); + BN_Destroy(order); + Sm2Clean(ctx); + return ret; +} + +static int32_t Sm2SetR(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + Sm2Clean(ctx); + ECC_Point *rs = ECC_NewPoint(ctx->pkey->para); + if (rs == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); + return CRYPT_MEM_ALLOC_FAIL; + } + ret = ECC_DecodePoint(ctx->pkey->para, rs, (const uint8_t *)val, len); + if (ret != CRYPT_SUCCESS) { + ECC_FreePoint(rs); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ctx->pointR = rs; + return ret; +} + +static int32_t Sm2SetRandom(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + uint32_t keyBits = CRYPT_SM2_GetBits(ctx); + BN_BigNum *order = ECC_GetParaN(ctx->pkey->para); + ctx->r = BN_Create(keyBits); + ctx->pointR = ECC_NewPoint(ctx->pkey->para); + BN_BigNum *tmp = BN_Create(keyBits); + if (order == NULL || ctx->r == NULL || ctx->pointR == NULL || tmp == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + ret = BN_Bin2Bn(ctx->r, (const uint8_t *)val, len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, ctx->pointR, ctx->r, NULL), ret); + GOTO_ERR_IF(ECC_GetPointDataX(ctx->pkey->para, ctx->pointR, tmp), ret); + BN_Destroy(order); + BN_Destroy(tmp); + return ret; +ERR: + BN_Destroy(order); + BN_Destroy(tmp); + Sm2Clean(ctx); + return ret; +} + +static int32_t Sm2GetSumSend(CRYPT_SM2_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + if (ctx->isSumValid != 1) { + ret = CRYPT_SM2_ERR_S_NOT_SET; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (len != SM3_MD_SIZE) { + ret = CRYPT_SM2_BUFF_LEN_NOT_ENOUGH; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = memcpy_s((uint8_t *)val, len, ctx->sumSend, SM3_MD_SIZE); + if (ret != EOK) { + ret = CRYPT_SM2_ERR_GET_S; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return CRYPT_SUCCESS; +} + +/* consttime memcmp function */ +static int32_t IsDataEqual(const uint8_t *data1, const uint8_t *data2, uint32_t len) +{ + int32_t ret; + uint8_t check = 0; + for (uint32_t i = 0; i < len; i++) { + check |= data1[i] ^ data2[i]; + } + if (check != 0) { + ret = CRYPT_SM2_EXCH_VERIFY_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return CRYPT_SUCCESS; +} + +static int32_t Sm2DoCheck(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret; + if (ctx->isSumValid != 1) { + ret = CRYPT_SM2_ERR_S_NOT_SET; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (len != SM3_MD_SIZE) { + ret = CRYPT_SM2_ERR_DATA_LEN; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = IsDataEqual(ctx->sumCheck, val, len); + if (ret != CRYPT_SUCCESS) { + ctx->isSumValid = 0; + } + return ret; +} + +static int32_t CtrlServerSet(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_CTRL_LEN); + return CRYPT_SM2_ERR_CTRL_LEN; + } + const int32_t t = *(const int32_t *)val; + if (t != 0 && t != 1) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_INVALID_SERVER_TYPE); + return CRYPT_SM2_INVALID_SERVER_TYPE; + } + ctx->server = t; + return CRYPT_SUCCESS; +} + +static int32_t CtrlUserId(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len == 0 || len > SM2_MAX_ID_LENGTH) { + BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN); + return CRYPT_ECC_PKEY_ERR_CTRL_LEN; + } + BSL_SAL_FREE(ctx->userId); + return Sm2SetUserId(ctx, val, len); +} + +static int32_t SM2SetHash(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != (uint32_t)sizeof(EAL_MdMethod)) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + ctx->hashMethod = (const EAL_MdMethod *)val; + return CRYPT_SUCCESS; +} + +static int32_t Sm2SetPKG(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_CTRL_LEN); + return CRYPT_SM2_ERR_CTRL_LEN; + } + if (*(uint32_t *)val != 0 && *(uint32_t *)val != 1) { + BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG); + return CRYPT_INVALID_ARG; + } + ctx->pkgImpl = *(uint32_t *)val; + return CRYPT_SUCCESS; +} + +static int32_t SM2UpReferences(CRYPT_SM2_Ctx *ctx, void *val, uint32_t len) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (val != NULL && len == (uint32_t)sizeof(int)) { + return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val); + } + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; +} + +int32_t CRYPT_SM2_Ctrl(CRYPT_SM2_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len) +{ + int32_t ret = CRYPT_SUCCESS; + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + switch (opt) { + case CRYPT_CTRL_SET_SM2_SERVER: + ret = CtrlServerSet(ctx, val, len); + break; + case CRYPT_CTRL_SET_SM2_USER_ID: + ret = CtrlUserId(ctx, val, len); + break; + case CRYPT_CTRL_GENE_SM2_R: + ret = Sm2GenerateR(ctx, val, len); + break; + case CRYPT_CTRL_SET_SM2_R: + ret = Sm2SetR(ctx, val, len); + break; + case CRYPT_CTRL_SET_SM2_RANDOM: + ret = Sm2SetRandom(ctx, val, len); + break; + case CRYPT_CTRL_SM2_GET_SEND_CHECK: + ret = Sm2GetSumSend(ctx, val, len); + break; + case CRYPT_CTRL_SM2_DO_CHECK: + ret = Sm2DoCheck(ctx, val, len); + break; + case CRYPT_CTRL_SET_SM2_PKG: + ret = Sm2SetPKG(ctx, val, len); + break; + case CRYPT_CTRL_UP_REFERENCES: + ret = SM2UpReferences(ctx, val, len); + break; + case CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE: + BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_UNSUPPORTED_CTRL_OPTION); + ret = CRYPT_SM2_ERR_UNSUPPORTED_CTRL_OPTION; + break; + case CRYPT_CTRL_SET_SM2_HASH_METHOD: + ret = SM2SetHash(ctx, val, len); + break; + default: + ret = ECC_PkeyCtrl(ctx->pkey, opt, val, len); + break; + } + return ret; +} + +int32_t CRYPT_SM2_Cmp(const CRYPT_SM2_Ctx *a, const CRYPT_SM2_Ctx *b) +{ + if (a == NULL || b == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + return ECC_PkeyCmp(a->pkey, b->pkey); +} + +int32_t CRYPT_SM2_GetSecBits(const CRYPT_SM2_Ctx *ctx) +{ + if (ctx == NULL || ctx->pkey == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return 0; + } + return ECC_GetSecBits(ctx->pkey->para); +} +#endif // HITLS_CRYPTO_SM2_SIGN diff --git a/crypto/sm3/include/crypt_sm3.h b/crypto/sm3/include/crypt_sm3.h new file mode 100644 index 00000000..a5b63a4c --- /dev/null +++ b/crypto/sm3/include/crypt_sm3.h @@ -0,0 +1,100 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_SM3_H +#define CRYPT_SM3_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM3 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +#define CRYPT_SM3_BLOCKSIZE 64 +#define CRYPT_SM3_DIGESTSIZE 32 + +typedef struct { + uint32_t h[CRYPT_SM3_DIGESTSIZE / sizeof(uint32_t)]; /* store the intermediate data of the hash value */ + uint32_t hNum, lNum; /* input data counter, maximum value 2 ^ 64 bits */ + uint8_t block[CRYPT_SM3_BLOCKSIZE]; /* store the remaining data which less than one block */ + /* Number of remaining bytes in 'block' arrary that are stored less than one block */ + uint32_t num; +} CRYPT_SM3_Ctx; + +/** + * @ingroup SM3 + * @brief This API is used to initialize the SM3 context. + * + * @param ctx [in,out] SM3 context pointer. + * + * @retval #CRYPT_SUCCESS initialization succeeded. + * @retval #CRYPT_NULL_INPUT Pointer ctx is NULL + */ +int32_t CRYPT_SM3_Init(CRYPT_SM3_Ctx *ctx); + +/** + * @ingroup SM3 + * @brief Encode the text and update the message digest. + * + * @param ctx [in,out] SM3 context pointer. + * @param in [in] Pointer to the data to be calculated + * @param len [in] Length of the data to be calculated + * + * @retval #CRYPT_SUCCESS succeeded in updating the internal status of the digest. + * @retval #CRYPT_NULL_INPUT The input parameter is NULL. + * @retval #CRYPT_SM3_INPUT_OVERFLOW Accumulated input data length exceeds the maximum (2^64 bits). + */ +int32_t CRYPT_SM3_Update(CRYPT_SM3_Ctx *ctx, const uint8_t *in, uint32_t len); + +/** + * @ingroup SM3 + * @brief Obtain the message digest based on the passed SM3 text. + * + * @param ctx [in,out] SM3 context pointer. + * @param out [in] digest buffer + * @param outLen [in,out] digest buffer size + * + * @retval #CRYPT_SUCCESS succeeded in updating the internal status of the digest. + * @retval #CRYPT_NULL_INPUT The input parameter is NULL. + * @retval #CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH The output buffer is insufficient. + */ +int32_t CRYPT_SM3_Final(CRYPT_SM3_Ctx *ctx, uint8_t *out, uint32_t *outLen); + +/** + * @ingroup SM3 + * @brief SM3 Deinitialization API + * @param ctx [in,out] SM3 context pointer. + */ +void CRYPT_SM3_Deinit(CRYPT_SM3_Ctx *ctx); + +/** + * @ingroup SM3 + * @brief Copy SM3 CTX function + * @param dst [out] SM3 context pointer. + * @param src [in] Pointer to the original SM3 context. + */ +int32_t CRYPT_SM3_CopyCtx(CRYPT_SM3_Ctx *dst, const CRYPT_SM3_Ctx *src); + +#ifdef __cplusplus +} +#endif /* __cpluscplus */ + +#endif // HITLS_CRYPTO_SM3 + +#endif // CRYPT_SM3_H diff --git a/crypto/sm3/src/asm/sm3_armv8.S b/crypto/sm3/src/asm/sm3_armv8.S new file mode 100644 index 00000000..490e2e72 --- /dev/null +++ b/crypto/sm3/src/asm/sm3_armv8.S @@ -0,0 +1,681 @@ +/* + * 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. + */ +.arch armv8-a+crypto + +// The first 16 of the compression function, w13 is Tj. +.macro first16 A B C D E F G H W1 W2 + ror w13, w13, #31 + ror w10, \A, #20 + add w9, \E, w10 + eor w12, \E, \F + ror \F, \F, #13 + eor w12, w12, \G + add w12, w12, \H + add w9, w9, w13 + ror w9, w9, #25 + add w12, w12, w9 + eor w10, w10, w9 + add w12, w12, \W1 + eor \H, w12, w12, ror #23 + ror w9, w12, #15 + eor \H, \H, w9 + eor w11, \A, \B + ror \B, \B, #23 + eor w11, w11, \C + add w11, w11, \D + add w11, w11, w10 + eor w9, \W1, \W2 + add \D, w11, w9 + .endm + +// Compress the last 48 of the function, w13 is Tj +.macro second48 A B C D E F G H W1 W2 + ror w13, w13, #31 + orr w11, \B, \C + eor w12, \F, \G + ror \F, \F, #13 + ror w10, \A, #20 + add w9, w10, \E + and w14, \A, w11 + and w12, w12, \E + eor w12, w12, \G + add w12, w12, \H + add w9, w9, w13 + ror w9, w9, #25 + add w12, w12, w9 + eor w10, w10, w9 + add w12, w12, \W1 + and w11, \B, \C + ror \B, \B, #23 + orr w11, w11, w14 + eor w9, \W1, \W2 + add w11, w11, \D + add w11, w11, w10 + add \D, w11, w9 + eor \H, w12, w12, ror #23 + ror w9, w12, #15 + eor \H, \H, w9 + .endm + +// void SM3_CompressAsm(uint32_t state[8], const uint8_t *data, uint32_t blockCnt); +.globl SM3_CompressAsm +.type SM3_CompressAsm, %function +.align 4 +SM3_CompressAsm: + sub sp, sp, 128 + stp x19, x20, [sp] + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp x25, x26, [sp, #48] + // According to the calling convention, this function needs to be saved. + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + + sub sp, sp, 64 + mov x25, sp + sub sp, sp, 64 + mov x26, sp + + mov x22, x0 // x22: state + mov x23, x1 // x23: data + mov w24, w2 // x24: blockCnt + + // w0-w7: ABCDEFGH word register in"SM3 cryptographic hash algorithm" + ldp w0, w1, [x22] + ldp w2, w3, [x22, #8] + ldp w4, w5, [x22, #16] + ldp w6, w7, [x22, #24] + + prfm pldl1keep, [x23, #64] + blocksloop_1: + subs w24, w24, #1 + bmi end + // Due to the SM3 feature, only three messages can be extended in parallel. + // You need to use ext to ensure that the data meets the requirements for calculation. + // To reduce the delay, the message expansion is calculated together with the compression function, + // and the compression function is calculated three times for every three Ws. + + // v0-v3 message group w0-w15 + ld1 {v0.4s-v3.4s}, [x23] +#ifndef HITLS_BIG_ENDIAN + rev32 v0.16B, v0.16B + rev32 v1.16B, v1.16B + rev32 v2.16B, v2.16B + rev32 v3.16B, v3.16B +#endif + + ldp w15, w20, [x23] + ldp w19, w21, [x23, #16] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w19, w19 + rev w20, w20 + rev w21, w21 +#endif + + ext v24.16b, v3.16b, v3.16b, #4 // 13, 14, 15 + ext v25.16b, v0.16b, v1.16b, #12 // 3, 4, 5 + ext v23.16b, v1.16b, v2.16b, #12 // 7, 8, 9 + ext v26.16b, v2.16b, v3.16b, #8 // 10, 11, 12 + eor v27.16b, v0.16b, v23.16b + // w13: constant Tj , 0 <= j <= 16 + mov w13, #0x228c + movk w13, #0xbce6, lsl #16 + + // Message grouping: Wj−3 ≪ 15, Wj−13 ≪ 7 + shl v21.4s, v24.4s, #15 + shl v22.4s, v25.4s, #7 + sri v21.4s, v24.4s, #17 // 13, 14, 15<<<15 + sri v22.4s, v25.4s, #25 // 3, 4, 5<<<7 + first16 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v26.16b + first16 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + // permutation function P1: X ^ (X ≪ 15) ^ (X ≪ 23) + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x23, #8] + ldp w19, w21, [x23, #24] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w19, w19 + rev w20, w20 + rev w21, w21 +#endif + eor v27.16b, v27.16b, v30.16b + first16 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v4.16b, v27.16b, v28.16b + + // 2:19, 20, 21 + ext v23.16b, v1.16b, v2.16b, #8 // 6, 7, 8 + eor v27.16b, v25.16b, v26.16b + first16 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v21.4s, v4.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v4.4s, #17 // 16, 17, 18<<<15 + sri v22.4s, v23.4s, #25 // 6, 7, 8<<<7 + ldp w15, w20, [x23, #16] + ldp w19, w21, [x23, #32] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w19, w19 + rev w20, w20 + rev w21, w21 +#endif + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v24.16b + first16 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + first16 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + eor v27.16b, v27.16b, v30.16b + mov v4.s[3], v4.s[2] // Due to ext requirements, to fill s[3] + eor v5.16b, v27.16b, v28.16b + + // 3:22, 23, 24 + ext v25.16b, v2.16b, v3.16b, #4 // 9, 10, 11 + eor v27.16b, v23.16b, v24.16b + ldp w15, w20, [x23, #24] + ldp w19, w21, [x23, #40] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w19, w19 + rev w20, w20 + rev w21, w21 +#endif + shl v21.4s, v5.4s, #15 + shl v22.4s, v25.4s, #7 + sri v21.4s, v5.4s, #17 // 19, 20, 21<<<15 + sri v22.4s, v25.4s, #25 // 9, 10, 11<<<7 + first16 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v4.16b + first16 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x23, #32] + ldp w19, w21, [x23, #48] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w19, w19 + rev w20, w20 + rev w21, w21 +#endif + first16 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v27.16b, v30.16b + mov v5.s[3], v5.s[2] // Due to ext requirements, to fill s[3] + eor v6.16b, v27.16b, v28.16b + + // 4:25, 26, 27 + eor v27.16b, v25.16b, v4.16b + shl v21.4s, v6.4s, #15 + shl v22.4s, v3.4s, #7 + sri v21.4s, v6.4s, #17 // 22, 23, 24<<<15 + sri v22.4s, v3.4s, #25 // 12, 13, 14<<<7 + first16 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v5.16b + ldp w15, w20, [x23, #40] + ldp w19, w21, [x23, #56] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w19, w19 + rev w20, w20 + rev w21, w21 +#endif + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + first16 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v27.16b, v29.16b + first16 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + eor v27.16b, v27.16b, v30.16b + mov v6.s[3], v6.s[2] // Due to ext requirements, to fill s[3] + eor v7.16b, v27.16b, v28.16b + + // 5:28, 29, 30 + ext v23.16b, v3.16b, v4.16b, #12 // 15, 16, 17 + eor v27.16b, v3.16b, v5.16b + st1 {v4.4s-v7.4s}, [x25] // There is a redundant data for every four 32-bit bits of the stored data. + // The data needs to be read in a skip manner. + shl v21.4s, v7.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v7.4s, #17 // 25, 26, 27<<<15 + sri v22.4s, v23.4s, #25 // 15, 16, 17<<<7 + ldp w15, w20, [x23, #48] + ldp w19, w21, [x25] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w20, w20 +#endif + first16 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v6.16b + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + first16 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + ldp w15, w20, [x23, #56] +#ifndef HITLS_BIG_ENDIAN + rev w15, w15 + rev w20, w20 +#endif + add x23, x23, #64 + prfm pldl1keep, [x23, #64] + ldr w19, [x25, #8] + ldr w21, [x25, #16] + eor v27.16b, v27.16b, v30.16b + first16 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + mov v7.s[3], v7.s[2] // Due to ext requirements, to fill s[3] + eor v8.16b, v27.16b, v28.16b + + // Message extension completed. Continue with the next 48 compression. + ext v24.16b, v4.16b, v5.16b, #12 // 18, 19, 20 + eor v27.16b, v23.16b, v6.16b + first16 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v21.4s, v8.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v8.4s, #17 // 28, 29, 30<<<15 + sri v22.4s, v24.4s, #25 // 18, 19, 20<<<7 + ldp w15, w20, [x25] + ldp w19, w21, [x25, #20] + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v7.16b + // w13: constant Tj , 17 <= j <= 63 + mov w13, #0x3d43 + movk w13, #0xcec5, lsl #16 + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + eor v27.16b, v27.16b, v30.16b + mov v8.s[3], v8.s[2] // Due to ext requirements, to fill s[3] + eor v9.16b, v27.16b, v28.16b + + // 7:34, 35, 36 + ext v23.16b, v5.16b, v6.16b, #12 // 21, 22, 23 + eor v27.16b, v24.16b, v7.16b + ldr w15, [x25, #8] + ldr w20, [x25, #16] + ldp w19, w21, [x25, #32] + shl v21.4s, v9.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v9.4s, #17 // 31, 32, 33<<<15 + sri v22.4s, v23.4s, #25 // 21, 22, 23<<<7 + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v8.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x25, #20] + ldr w19, [x25, #40] + ldr w21, [x25, #48] + eor v27.16b, v27.16b, v30.16b + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + mov v9.s[3], v9.s[2] // Due to ext requirements, to fill s[3] + eor v10.16b, v27.16b, v28.16b + + // 8:37, 38, 39 + ext v24.16b, v6.16b, v7.16b, #12 // 24, 25, 26 + eor v27.16b, v23.16b, v8.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + shl v21.4s, v10.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v10.4s, #17 // 34, 35, 36<<<15 + sri v22.4s, v24.4s, #25 // 24, 25, 26<<<7 + ldp w15, w20, [x25, #32] + ldp w19, w21, [x25, #52] + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v9.16b + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + eor v27.16b, v27.16b, v30.16b + mov v10.s[3], v10.s[2] // Due to ext requirements, to fill s[3] + eor v11.16b, v27.16b, v28.16b + + // 9:40, 41, 42 + ext v23.16b, v7.16b, v8.16b, #12 // 27, 28, 29 + eor v27.16b, v24.16b, v9.16b + st1 {v8.4s-v11.4s}, [x26] + shl v21.4s, v11.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v11.4s, #17 // 37, 38, 39<<<15 + sri v22.4s, v23.4s, #25 // 27, 28, 29<<<7 + ldr w15, [x25, #40] + ldr w20, [x25, #48] + ldp w19, w21, [x26] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v10.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x25, #52] + ldr w19, [x26, #8] + ldr w21, [x26, #16] + eor v27.16b, v27.16b, v30.16b + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + mov v11.s[3], v11.s[2] // Due to ext requirements, to fill s[3] + eor v12.16b, v27.16b, v28.16b + + // 10:43, 44, 45 + ext v24.16b, v8.16b, v9.16b, #12 // 30, 31, 32 + eor v27.16b, v23.16b, v10.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v21.4s, v12.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v12.4s, #17 // 40, 41, 42<<<15 + sri v22.4s, v24.4s, #25 // 30, 31, 32<<<7 + ldp w15, w20, [x26] + ldp w19, w21, [x26, #20] + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v11.16b + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + eor v27.16b, v27.16b, v30.16b + mov v12.s[3], v12.s[2] // Due to ext requirements, to fill s[3] + eor v13.16b, v27.16b, v28.16b + + // 11:46, 47, 48 + ext v23.16b, v9.16b, v10.16b, #12 // 33, 34, 35 + eor v27.16b, v24.16b, v11.16b + ldr w15, [x26, #8] + ldr w20, [x26, #16] + ldp w19, w21, [x26, #32] + shl v21.4s, v13.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v13.4s, #17 // 43, 44, 45<<<15 + sri v22.4s, v23.4s, #25 // 33, 34, 35<<<7 + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v12.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x26, #20] + ldr w19, [x26, #40] + ldr w21, [x26, #48] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v27.16b, v30.16b + mov v13.s[3], v13.s[2] // Due to ext requirements, to fill s[3] + eor v14.16b, v27.16b, v28.16b + + // 12:49, 50, 51 + ext v24.16b, v10.16b, v11.16b, #12 // 36, 37, 38 + eor v27.16b, v23.16b, v12.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + shl v21.4s, v14.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v14.4s, #17 // 46, 47, 48<<<15 + sri v22.4s, v24.4s, #25 // 36, 37, 38<<<7 + ldp w15, w20, [x26, #32] + ldp w19, w21, [x26, #52] + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v13.16b + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + eor v27.16b, v27.16b, v30.16b + mov v14.s[3], v14.s[2] // Due to ext requirements, to fill s[3] + eor v15.16b, v27.16b, v28.16b + + // 13:52, 53, 54 + ext v23.16b, v11.16b, v12.16b, #12 // 39, 40, 41 + eor v27.16b, v24.16b, v13.16b + st1 {v12.4s-v15.4s}, [x25] + shl v21.4s, v15.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v15.4s, #17 // 49, 50, 51<<<15 + sri v22.4s, v23.4s, #25 // 39, 40, 41<<<7 + ldr w15, [x26, #40] + ldr w20, [x26, #48] + ldp w19, w21, [x25] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v14.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x26, #52] + ldr w19, [x25, #8] + ldr w21, [x25, #16] + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v27.16b, v30.16b + mov v15.s[3], v15.s[2] // Due to ext requirements, to fill s[3] + eor v16.16b, v27.16b, v28.16b + + // 14:55, 56, 57 + ext v24.16b, v12.16b, v13.16b, #12 // 42, 43, 44 + eor v27.16b, v23.16b, v14.16b + shl v21.4s, v16.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v16.4s, #17 // 52, 53, 54<<<15 + sri v22.4s, v24.4s, #25 // 42, 43, 44<<<7 + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v15.16b + ldp w15, w20, [x25] + ldp w19, w21, [x25, #20] + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v27.16b, v30.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + mov v16.s[3], v16.s[2] // Due to ext requirements, to fill s[3] + eor v17.16b, v27.16b, v28.16b + + // 15:58, 59, 60 + ext v23.16b, v13.16b, v14.16b, #12 // 45, 46, 47 + eor v27.16b, v24.16b, v15.16b + shl v21.4s, v17.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v17.4s, #17 // 55, 56, 57<<<15 + sri v22.4s, v23.4s, #25 // 45, 46, 47<<<7 + ldr w15, [x25, #8] + ldr w20, [x25, #16] + ldp w19, w21, [x25, #32] + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v16.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x25, #20] + ldr w19, [x25, #40] + ldr w21, [x25, #48] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v27.16b, v30.16b + eor v18.16b, v27.16b, v28.16b + + // 16:61, 62, 63 + ext v24.16b, v14.16b, v15.16b, #12 // 48, 49, 50 + eor v27.16b, v23.16b, v16.16b + shl v21.4s, v18.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v18.4s, #17 // 58, 59, 60<<<15 + sri v22.4s, v24.4s, #25 // 48, 49, 50<<<7 + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v17.16b + ldp w15, w20, [x25, #32] + ldp w19, w21, [x25, #52] + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v27.16b, v27.16b, v30.16b + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + eor v19.16b, v27.16b, v28.16b + + // 17:64, 65, 66 + ext v23.16b, v15.16b, v16.16b, #12 // 51, 52, 53 + eor v27.16b, v24.16b, v17.16b + st1 {v16.4s-v19.4s}, [x26] + shl v21.4s, v19.4s, #15 + shl v22.4s, v23.4s, #7 + sri v21.4s, v19.4s, #17 // 61, 62, 63<<<15 + sri v22.4s, v23.4s, #25 // 51, 52, 53<<<7 + ldr w15, [x25, #40] + ldr w20, [x25, #48] + ldp w19, w21, [x26] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v18.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + ldp w15, w20, [x25, #52] + ldr w19, [x26, #8] + ldr w21, [x26, #16] + eor v27.16b, v27.16b, v30.16b + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + eor v20.16b, v27.16b, v28.16b + + // 18:67 + ext v24.16b, v16.16b, v17.16b, #12 // 54, 55, 56 + eor v27.16b, v23.16b, v18.16b + shl v21.4s, v20.4s, #15 + shl v22.4s, v24.4s, #7 + sri v21.4s, v20.4s, #17 // 64, 65, 66<<<15 + sri v22.4s, v24.4s, #25 // 54, 55, 56<<<7 + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + eor v27.16b, v21.16b, v27.16b + eor v28.16b, v22.16b, v19.16b + ldp w15, w20, [x26] + ldp w19, w21, [x26, #20] + shl v29.4s, v27.4s, #15 + shl v30.4s, v27.4s, #23 + sri v29.4s, v27.4s, #17 + sri v30.4s, v27.4s, #9 + eor v27.16b, v27.16b, v29.16b + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + eor v27.16b, v27.16b, v30.16b + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + eor v21.16b, v27.16b, v28.16b + + ldr w15, [x26, #8] + ldr w20, [x26, #16] + ldp w19, w21, [x26, #32] + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + st1 {v20.4s-v21.4s}, [x25] + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + ldp w15, w20, [x26, #20] + ldr w19, [x26, #40] + ldr w21, [x26, #48] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + ldp w15, w20, [x26, #32] + ldp w19, w21, [x26, #52] + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + ldr w15, [x26, #40] + ldr w20, [x26, #48] + ldp w19, w21, [x25] + second48 w0 w1 w2 w3 w4 w5 w6 w7 w15 w19 + second48 w3 w0 w1 w2 w7 w4 w5 w6 w20 w21 + ldp w15, w20, [x26, #52] + ldr w19, [x25, #8] + ldr w21, [x25, #16] + second48 w2 w3 w0 w1 w6 w7 w4 w5 w15 w19 + second48 w1 w2 w3 w0 w5 w6 w7 w4 w20 w21 + ldp w9, w10, [x22] // XOR with the previous hash result + ldp w11, w12, [x22, #8] + ldp w13, w14, [x22, #16] + ldp w15, w19, [x22, #24] + eor w0, w0, w9 + eor w1, w1, w10 + eor w2, w2, w11 + eor w3, w3, w12 + eor w4, w4, w13 + eor w5, w5, w14 + eor w6, w6, w15 + eor w7, w7, w19 + stp w0, w1, [x22] // Result saving + stp w2, w3, [x22, #8] + stp w4, w5, [x22, #16] + stp w6, w7, [x22, #24] + b blocksloop_1 + end: + + add sp, sp, 128 + + ldp x19, x20, [sp] + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp x25, x26, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + add sp, sp, 128 + + ret +.size SM3_CompressAsm,.-SM3_CompressAsm \ No newline at end of file diff --git a/crypto/sm3/src/asm/sm3_x86_64.s b/crypto/sm3/src/asm/sm3_x86_64.s new file mode 100644 index 00000000..1b0f9dc5 --- /dev/null +++ b/crypto/sm3/src/asm/sm3_x86_64.s @@ -0,0 +1,635 @@ +/* + * 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_SM3 + +.file "sm3_x86_64.s" +.text + +.set A,%r8d +.set B,%r9d +.set C,%r10d +.set D,%r11d +.set E,%r12d +.set F,%r13d +.set G,%r14d +.set H,%r15d + +.set STATE,%rdi +.set DATA,%rsi +.set NUM,%rdx + +.set ADDR,%rax +.set BOOL_OUT,%eax +.set SS1,%ebx +.set SS2,%eax + +.set X0,%xmm0 +.set X1,%xmm1 +.set X2,%xmm2 +.set X3,%xmm3 +.set X4,%xmm4 +.set X5,%xmm5 +.set X6,%xmm6 +.set X7,%xmm7 +.set R16,%xmm13 +.set R24,%xmm14 +.set SHUFFLEMASK,%xmm15 + +.macro FF0 X Y Z + # X ^ Y ^ Z + movl \X,%eax + xorl \Y,%eax + xorl \Z,%eax +.endm + +.macro FF1 X Y Z + # (X & Y) | (X & Z) | (Y & Z) + # = (X & (Y | Z)) | (Y & Z) + movl \Y,%eax + movl %eax,%ebx + orl \Z,%eax + andl \Z,%ebx + andl \X,%eax + orl %ebx,%eax +.endm + +.macro GG0 X Y Z + FF0 \X \Y \Z +.endm + +.macro GG1 X Y Z + # (X & Y) | (~X & Z) + movl \X,%ebx + andn \Z,%ebx,%eax + andl \Y,%ebx + orl %ebx,%eax +.endm + +.macro P0 X + rorx $15,\X,%eax + rorx $23,\X,%ebx + xorl %eax,\X + xorl %ebx,\X +.endm + +.macro P1 X + rorx $9,\X,%eax + rorx $17,\X,%ebx + xorl %eax,\X + xorl %ebx,\X +.endm + +.macro ROUND FF GG Ar Br Cr Dr Er Fr Gr Hr TJ + # A <<< 12 + rorx $20,\Ar,%eax + # SS1 (%ebx) <- ((A <<< 12) + E + (Tj <<< (jmod32))) <<< 7 + # pre-computed TJ = Tj <<< (jmod32) + movl %eax,%ebx + addl \Er,%ebx + addl $\TJ,%ebx + rorx $25,%ebx,SS1 + # SS2 (%eax) <- SS1 ^ (A <<< 12) + xorl SS1,SS2 + # TT1 (D) <- FF(A,B,C) + D + SS2 + W(i)' + # TT2 (H) <- GG(E,F,G) + H + SS1 + W(i) + addl SS2,\Dr + addl SS1,\Hr + # FF(A,B,C) + \FF \Ar \Br \Cr + addl BOOL_OUT,\Dr + # GG(E,F,G) + \GG \Er \Fr \Gr + addl BOOL_OUT,\Hr + # B <- B <<< 9 + rorx $23,\Br,\Br + # F <- F <<< 19 + rorx $13,\Fr,\Fr + # P0(TT2) + P0 \Hr +.endm + +.macro ROUND_00_15 Ar Br Cr Dr Er Fr Gr Hr TJ WADDR WPADDR + # H <- H + W(i) + # D <- D + W(i)' + addl \WADDR(%rsp),\Hr + addl \WPADDR(%rsp),\Dr + ROUND FF0 GG0 \Ar \Br \Cr \Dr \Er \Fr \Gr \Hr \TJ +.endm + +.macro ROUND_16_63 Ar Br Cr Dr Er Fr Gr Hr TJ WADDR WPADDR + # H <- H + W(i) + # D <- D + W(i)' + addl \WADDR(%rsp),\Hr + addl \WPADDR(%rsp),\Dr + ROUND FF1 GG1 \Ar \Br \Cr \Dr \Er \Fr \Gr \Hr \TJ +.endm + +.macro ROTATE IN OUT LEFT RIGHT + vpslld $\LEFT,\IN,%xmm6 + vpsrld $\RIGHT,\IN,%xmm7 + vpxor %xmm6,%xmm7,\OUT +.endm + +.macro WORD_SCHEDULER_00_11 I + # W'(i) <- W(i) ^ W(i+4) + # i = 0, ... ,11 + movl \I(%rsp), %ecx # load W(i) + xorl \I+4*4(%rsp),%ecx # W'(i) <- W(i) ^ W(i+4) + movl %ecx,284(%rsp) # store W(i)' +.endm + +.macro WORD_SCHEDULER_12_63 I + # W(i) <- P1( W(i-16) ^ W(i-9) ^ ( W(i-3) <<< 15 ) ) ^ ( W(i-13) <<< 7 ) ^ W(i-6) + # i = 12, ... ,63 + rorx $17,\I+13*4(%rsp),%ecx # W(i-3) + xorl \I(%rsp),%ecx # W(i-16) + xorl \I+7*4(%rsp),%ecx # W(i-9) + P1 %ecx + rorx $25,\I+3*4(%rsp),%eax # W(i-13) + xorl \I+10*4(%rsp),%eax # W(i-6) + xorl %eax,%ecx + # Store W(i) and W'(i) + movl %ecx,\I+16*4(%rsp) # store W(i) + xorl \I+12*4(%rsp),%ecx # W'(i) <- W(i) ^ W(i+4) + movl %ecx,284(%rsp) # store W(i)' +.endm + +.macro LOAD_WORD_FOR_SCHEDULER START + vmovdqu \START(%rsp),X0 + vmovdqu \START+12(%rsp),X1 + vmovdqu \START+28(%rsp),X2 + vmovdqu \START+40(%rsp),X3 + vmovdqu \START+48(%rsp),X4 + vmovdqu \START+52(%rsp),X5 +.endm + +.macro LOAD_WORD_FOR_SCHEDULER_FAST START W0 W1 W2 W3 W4 W5 + vmovdqu \START+12(%rsp),\W1 + vmovdqu \START+48(%rsp),\W4 + vmovdqu \START+52(%rsp),\W5 +.endm + +.macro MESSAGE_SCHEDULER START W0 W1 W2 W3 W4 W5 + vpxor \W2,\W0,\W0 + ROTATE \W5,\W2,15,17 + vpxor \W2,\W0,\W0 + + # P1 + vpshufb R16,\W0,X6 + vpshufb R24,\W0,X7 + vpxor X6,X7,X7 + ROTATE X7,X7,31,1 + vpxor X7,\W0,\W0 + ROTATE \W1,\W2,7,25 + vpxor \W2,\W0,\W0 + vpxor \W3,\W0,\W0 + # W'(i) <- W(i) ^ W(i+4) + vpxor \W0,\W4,\W4 + + vmovdqu \W0,\START+64(%rsp) + vmovdqu \W4,284(%rsp) +.endm + +.macro MESSAGE_SCHEDULER_FAST START W0 W1 W2 W3 W4 W5 + LOAD_WORD_FOR_SCHEDULER_FAST \START \W0 \W1 \W2 \W3 \W4 \W5 + MESSAGE_SCHEDULER \START \W0 \W1 \W2 \W3 \W4 \W5 +.endm + + +##### SM3 ##### +# void SM3_CompressSIMD(uint32_t state[8], const uint8_t *data, uint32_t blockCnt) +# state|out %rdi 32 bytes +# p %rsi +# num %rdx +.globl SM3_CompressSIMD +.type SM3_CompressSIMD, @function +.align 64 +SM3_CompressSIMD: + testq NUM,NUM + jz .Lsm3_avx_ret + + # Store Registers + subq $348,%rsp + movq %rbx,300(%rsp) + movq %rbp,8+300(%rsp) + movq %r12,16+300(%rsp) + movq %r13,24+300(%rsp) + movq %r14,32+300(%rsp) + movq %r15,40+300(%rsp) + +.Lsm3_avx_init: + leaq MASKS(%rip),ADDR + vmovdqa (ADDR),SHUFFLEMASK + vmovdqa 16(ADDR),R16 + vmovdqa 32(ADDR),R24 + +.Lsm3_avx_update: + # Load Data (Big Endian) + vmovdqu (DATA),%xmm0 + vmovdqu 16(DATA),%xmm1 + vmovdqu 32(DATA),%xmm2 + vmovdqu 48(DATA),%xmm3 + vpshufb SHUFFLEMASK,%xmm0,%xmm0 + vpshufb SHUFFLEMASK,%xmm1,%xmm1 + vpshufb SHUFFLEMASK,%xmm2,%xmm2 + vpshufb SHUFFLEMASK,%xmm3,%xmm3 + vmovdqu %xmm0,(%rsp) + vmovdqu %xmm1,16(%rsp) + vmovdqu %xmm2,32(%rsp) + vmovdqu %xmm3,48(%rsp) + vpxor %xmm1,%xmm0,%xmm0 + vpxor %xmm2,%xmm1,%xmm1 + vpxor %xmm3,%xmm2,%xmm2 + + # Load State + movl (STATE),A + movl 4(STATE),B + movl 8(STATE),C + movl 12(STATE),D + movl 16(STATE),E + movl 20(STATE),F + movl 24(STATE),G + movl 28(STATE),H + + # ROUND 0-11 + vmovdqu %xmm0,284(%rsp) + ROUND_00_15 A B C D E F G H 0x79CC4519 0 284 + ROUND_00_15 D A B C H E F G 0xF3988A32 4 288 + ROUND_00_15 C D A B G H E F 0xE7311465 8 292 + ROUND_00_15 B C D A F G H E 0xCE6228CB 12 296 + vmovdqu %xmm1,284(%rsp) + ROUND_00_15 A B C D E F G H 0x9CC45197 16 284 + ROUND_00_15 D A B C H E F G 0x3988A32F 20 288 + ROUND_00_15 C D A B G H E F 0x7311465E 24 292 + ROUND_00_15 B C D A F G H E 0xE6228CBC 28 296 + vmovdqu %xmm2,284(%rsp) + ROUND_00_15 A B C D E F G H 0xCC451979 32 284 + ROUND_00_15 D A B C H E F G 0x988A32F3 36 288 + ROUND_00_15 C D A B G H E F 0x311465E7 40 292 + ROUND_00_15 B C D A F G H E 0x6228CBCE 44 296 + # ROUND 12-15 + LOAD_WORD_FOR_SCHEDULER 0 + MESSAGE_SCHEDULER 0 X0 X1 X2 X3 X4 X5 + ROUND_00_15 A B C D E F G H 0xC451979C 48 284 + ROUND_00_15 D A B C H E F G 0x88A32F39 52 288 + ROUND_00_15 C D A B G H E F 0x11465E73 56 292 + MESSAGE_SCHEDULER_FAST 12 X1 X0 X3 X5 X4 X2 + ROUND_00_15 B C D A F G H E 0x228CBCE6 60 284 + # ROUND 16-63 + ROUND_16_63 A B C D E F G H 0x9D8A7A87 64 288 + ROUND_16_63 D A B C H E F G 0x3B14F50F 68 292 + MESSAGE_SCHEDULER_FAST 24 X0 X1 X5 X2 X4 X3 + ROUND_16_63 C D A B G H E F 0x7629EA1E 72 284 + ROUND_16_63 B C D A F G H E 0xEC53D43C 76 288 + ROUND_16_63 A B C D E F G H 0xD8A7A879 80 292 + MESSAGE_SCHEDULER_FAST 36 X1 X0 X2 X3 X4 X5 + ROUND_16_63 D A B C H E F G 0xB14F50F3 84 284 + ROUND_16_63 C D A B G H E F 0x629EA1E7 88 288 + ROUND_16_63 B C D A F G H E 0xC53D43CE 92 292 + MESSAGE_SCHEDULER_FAST 48 X0 X1 X3 X5 X4 X2 + ROUND_16_63 A B C D E F G H 0x8A7A879D 96 284 + ROUND_16_63 D A B C H E F G 0x14F50F3B 100 288 + ROUND_16_63 C D A B G H E F 0x29EA1E76 104 292 + MESSAGE_SCHEDULER_FAST 60 X1 X0 X5 X2 X4 X3 + ROUND_16_63 B C D A F G H E 0x53D43CEC 108 284 + ROUND_16_63 A B C D E F G H 0xA7A879D8 112 288 + ROUND_16_63 D A B C H E F G 0x4F50F3B1 116 292 + MESSAGE_SCHEDULER_FAST 72 X0 X1 X2 X3 X4 X5 + ROUND_16_63 C D A B G H E F 0x9EA1E762 120 284 + ROUND_16_63 B C D A F G H E 0x3D43CEC5 124 288 + ROUND_16_63 A B C D E F G H 0x7A879D8A 128 292 + MESSAGE_SCHEDULER_FAST 84 X1 X0 X3 X5 X4 X2 + ROUND_16_63 D A B C H E F G 0xF50F3B14 132 284 + ROUND_16_63 C D A B G H E F 0xEA1E7629 136 288 + ROUND_16_63 B C D A F G H E 0xD43CEC53 140 292 + MESSAGE_SCHEDULER_FAST 96 X0 X1 X5 X2 X4 X3 + ROUND_16_63 A B C D E F G H 0xA879D8A7 144 284 + ROUND_16_63 D A B C H E F G 0x50F3B14F 148 288 + ROUND_16_63 C D A B G H E F 0xA1E7629E 152 292 + MESSAGE_SCHEDULER_FAST 108 X1 X0 X2 X3 X4 X5 + ROUND_16_63 B C D A F G H E 0x43CEC53D 156 284 + ROUND_16_63 A B C D E F G H 0x879D8A7A 160 288 + ROUND_16_63 D A B C H E F G 0x0F3B14F5 164 292 + MESSAGE_SCHEDULER_FAST 120 X0 X1 X3 X5 X4 X2 + ROUND_16_63 C D A B G H E F 0x1E7629EA 168 284 + ROUND_16_63 B C D A F G H E 0x3CEC53D4 172 288 + ROUND_16_63 A B C D E F G H 0x79D8A7A8 176 292 + MESSAGE_SCHEDULER_FAST 132 X1 X0 X5 X2 X4 X3 + ROUND_16_63 D A B C H E F G 0xF3B14F50 180 284 + ROUND_16_63 C D A B G H E F 0xE7629EA1 184 288 + ROUND_16_63 B C D A F G H E 0xCEC53D43 188 292 + MESSAGE_SCHEDULER_FAST 144 X0 X1 X2 X3 X4 X5 + ROUND_16_63 A B C D E F G H 0x9D8A7A87 192 284 + ROUND_16_63 D A B C H E F G 0x3B14F50F 196 288 + ROUND_16_63 C D A B G H E F 0x7629EA1E 200 292 + MESSAGE_SCHEDULER_FAST 156 X1 X0 X3 X5 X4 X2 + ROUND_16_63 B C D A F G H E 0xEC53D43C 204 284 + ROUND_16_63 A B C D E F G H 0xD8A7A879 208 288 + ROUND_16_63 D A B C H E F G 0xB14F50F3 212 292 + MESSAGE_SCHEDULER_FAST 168 X0 X1 X5 X2 X4 X3 + ROUND_16_63 C D A B G H E F 0x629EA1E7 216 284 + ROUND_16_63 B C D A F G H E 0xC53D43CE 220 288 + ROUND_16_63 A B C D E F G H 0x8A7A879D 224 292 + MESSAGE_SCHEDULER_FAST 180 X1 X0 X2 X3 X4 X5 + ROUND_16_63 D A B C H E F G 0x14F50F3B 228 284 + ROUND_16_63 C D A B G H E F 0x29EA1E76 232 288 + ROUND_16_63 B C D A F G H E 0x53D43CEC 236 292 + MESSAGE_SCHEDULER_FAST 192 X0 X1 X3 X5 X4 X2 + ROUND_16_63 A B C D E F G H 0xA7A879D8 240 284 + ROUND_16_63 D A B C H E F G 0x4F50F3B1 244 288 + ROUND_16_63 C D A B G H E F 0x9EA1E762 248 292 + WORD_SCHEDULER_12_63 204 + ROUND_16_63 B C D A F G H E 0x3D43CEC5 252 284 + + xorl A,(STATE) + xorl B,4(STATE) + xorl C,8(STATE) + xorl D,12(STATE) + xorl E,16(STATE) + xorl F,20(STATE) + xorl G,24(STATE) + xorl H,28(STATE) + + leaq 64(DATA),DATA + decq NUM + jz .Lsm3_avx_final + jmp .Lsm3_avx_update + +.Lsm3_avx_final: + vzeroall + + # Clear Context + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + # Restore Registers + movq 300(%rsp),%rbx + movq 8+300(%rsp),%rbp + movq 16+300(%rsp),%r12 + movq 24+300(%rsp),%r13 + movq 32+300(%rsp),%r14 + movq 40+300(%rsp),%r15 + addq $348,%rsp + +.Lsm3_avx_ret: + ret +.size SM3_CompressSIMD, .-SM3_CompressSIMD + +##### SM3 ##### +# void SM3_CompressAsm(uint32_t state[8], const uint8_t *data, uint32_t blockCnt) +# state|out %rdi 32 bytes +# p %rsi +# num %rdx +.globl SM3_CompressAsm +.type SM3_CompressAsm, @function +.align 64 +SM3_CompressAsm: + testq NUM,NUM + jz .Lsm3_ret + + # Store Registers + subq $348,%rsp + movq %rbx,300(%rsp) + movq %rbp,8+300(%rsp) + movq %r12,16+300(%rsp) + movq %r13,24+300(%rsp) + movq %r14,32+300(%rsp) + movq %r15,40+300(%rsp) + +.Lsm3_loop: + # Load Data (Big Endian) + movl (DATA),%r8d + movl 4(DATA),%r9d + movl 8(DATA),%r10d + movl 12(DATA),%r11d + movbe %r8d,(%rsp) + movbe %r9d,4(%rsp) + movbe %r10d,8(%rsp) + movbe %r11d,12(%rsp) + movl 16(DATA),%r8d + movl 20(DATA),%r9d + movl 24(DATA),%r10d + movl 28(DATA),%r11d + movbe %r8d,16(%rsp) + movbe %r9d,20(%rsp) + movbe %r10d,24(%rsp) + movbe %r11d,28(%rsp) + movl 32(DATA),%r8d + movl 36(DATA),%r9d + movl 40(DATA),%r10d + movl 44(DATA),%r11d + movbe %r8d,32(%rsp) + movbe %r9d,36(%rsp) + movbe %r10d,40(%rsp) + movbe %r11d,44(%rsp) + movl 48(DATA),%r8d + movl 52(DATA),%r9d + movl 56(DATA),%r10d + movl 60(DATA),%r11d + movbe %r8d,48(%rsp) + movbe %r9d,52(%rsp) + movbe %r10d,56(%rsp) + movbe %r11d,60(%rsp) + + # Load State + movl (STATE),A + movl 4(STATE),B + movl 8(STATE),C + movl 12(STATE),D + movl 16(STATE),E + movl 20(STATE),F + movl 24(STATE),G + movl 28(STATE),H + + # ROUND 0-11 + WORD_SCHEDULER_00_11 0 + ROUND_00_15 A B C D E F G H 0x79CC4519 0 284 + WORD_SCHEDULER_00_11 4 + ROUND_00_15 D A B C H E F G 0xF3988A32 4 284 + WORD_SCHEDULER_00_11 8 + ROUND_00_15 C D A B G H E F 0xE7311465 8 284 + WORD_SCHEDULER_00_11 12 + ROUND_00_15 B C D A F G H E 0xCE6228CB 12 284 + WORD_SCHEDULER_00_11 16 + ROUND_00_15 A B C D E F G H 0x9CC45197 16 284 + WORD_SCHEDULER_00_11 20 + ROUND_00_15 D A B C H E F G 0x3988A32F 20 284 + WORD_SCHEDULER_00_11 24 + ROUND_00_15 C D A B G H E F 0x7311465E 24 284 + WORD_SCHEDULER_00_11 28 + ROUND_00_15 B C D A F G H E 0xE6228CBC 28 284 + WORD_SCHEDULER_00_11 32 + ROUND_00_15 A B C D E F G H 0xCC451979 32 284 + WORD_SCHEDULER_00_11 36 + ROUND_00_15 D A B C H E F G 0x988A32F3 36 284 + WORD_SCHEDULER_00_11 40 + ROUND_00_15 C D A B G H E F 0x311465E7 40 284 + WORD_SCHEDULER_00_11 44 + ROUND_00_15 B C D A F G H E 0x6228CBCE 44 284 + # ROUND 12-15 + WORD_SCHEDULER_12_63 0 + ROUND_00_15 A B C D E F G H 0xC451979C 48 284 + WORD_SCHEDULER_12_63 4 + ROUND_00_15 D A B C H E F G 0x88A32F39 52 284 + WORD_SCHEDULER_12_63 8 + ROUND_00_15 C D A B G H E F 0x11465E73 56 284 + WORD_SCHEDULER_12_63 12 + ROUND_00_15 B C D A F G H E 0x228CBCE6 60 284 + # ROUND 16-63 + WORD_SCHEDULER_12_63 16 + ROUND_16_63 A B C D E F G H 0x9D8A7A87 64 284 + WORD_SCHEDULER_12_63 20 + ROUND_16_63 D A B C H E F G 0x3B14F50F 68 284 + WORD_SCHEDULER_12_63 24 + ROUND_16_63 C D A B G H E F 0x7629EA1E 72 284 + WORD_SCHEDULER_12_63 28 + ROUND_16_63 B C D A F G H E 0xEC53D43C 76 284 + WORD_SCHEDULER_12_63 32 + ROUND_16_63 A B C D E F G H 0xD8A7A879 80 284 + WORD_SCHEDULER_12_63 36 + ROUND_16_63 D A B C H E F G 0xB14F50F3 84 284 + WORD_SCHEDULER_12_63 40 + ROUND_16_63 C D A B G H E F 0x629EA1E7 88 284 + WORD_SCHEDULER_12_63 44 + ROUND_16_63 B C D A F G H E 0xC53D43CE 92 284 + WORD_SCHEDULER_12_63 48 + ROUND_16_63 A B C D E F G H 0x8A7A879D 96 284 + WORD_SCHEDULER_12_63 52 + ROUND_16_63 D A B C H E F G 0x14F50F3B 100 284 + WORD_SCHEDULER_12_63 56 + ROUND_16_63 C D A B G H E F 0x29EA1E76 104 284 + WORD_SCHEDULER_12_63 60 + ROUND_16_63 B C D A F G H E 0x53D43CEC 108 284 + WORD_SCHEDULER_12_63 64 + ROUND_16_63 A B C D E F G H 0xA7A879D8 112 284 + WORD_SCHEDULER_12_63 68 + ROUND_16_63 D A B C H E F G 0x4F50F3B1 116 284 + WORD_SCHEDULER_12_63 72 + ROUND_16_63 C D A B G H E F 0x9EA1E762 120 284 + WORD_SCHEDULER_12_63 76 + ROUND_16_63 B C D A F G H E 0x3D43CEC5 124 284 + WORD_SCHEDULER_12_63 80 + ROUND_16_63 A B C D E F G H 0x7A879D8A 128 284 + WORD_SCHEDULER_12_63 84 + ROUND_16_63 D A B C H E F G 0xF50F3B14 132 284 + WORD_SCHEDULER_12_63 88 + ROUND_16_63 C D A B G H E F 0xEA1E7629 136 284 + WORD_SCHEDULER_12_63 92 + ROUND_16_63 B C D A F G H E 0xD43CEC53 140 284 + WORD_SCHEDULER_12_63 96 + ROUND_16_63 A B C D E F G H 0xA879D8A7 144 284 + WORD_SCHEDULER_12_63 100 + ROUND_16_63 D A B C H E F G 0x50F3B14F 148 284 + WORD_SCHEDULER_12_63 104 + ROUND_16_63 C D A B G H E F 0xA1E7629E 152 284 + WORD_SCHEDULER_12_63 108 + ROUND_16_63 B C D A F G H E 0x43CEC53D 156 284 + WORD_SCHEDULER_12_63 112 + ROUND_16_63 A B C D E F G H 0x879D8A7A 160 284 + WORD_SCHEDULER_12_63 116 + ROUND_16_63 D A B C H E F G 0x0F3B14F5 164 284 + WORD_SCHEDULER_12_63 120 + ROUND_16_63 C D A B G H E F 0x1E7629EA 168 284 + WORD_SCHEDULER_12_63 124 + ROUND_16_63 B C D A F G H E 0x3CEC53D4 172 284 + WORD_SCHEDULER_12_63 128 + ROUND_16_63 A B C D E F G H 0x79D8A7A8 176 284 + WORD_SCHEDULER_12_63 132 + ROUND_16_63 D A B C H E F G 0xF3B14F50 180 284 + WORD_SCHEDULER_12_63 136 + ROUND_16_63 C D A B G H E F 0xE7629EA1 184 284 + WORD_SCHEDULER_12_63 140 + ROUND_16_63 B C D A F G H E 0xCEC53D43 188 284 + WORD_SCHEDULER_12_63 144 + ROUND_16_63 A B C D E F G H 0x9D8A7A87 192 284 + WORD_SCHEDULER_12_63 148 + ROUND_16_63 D A B C H E F G 0x3B14F50F 196 284 + WORD_SCHEDULER_12_63 152 + ROUND_16_63 C D A B G H E F 0x7629EA1E 200 284 + WORD_SCHEDULER_12_63 156 + ROUND_16_63 B C D A F G H E 0xEC53D43C 204 284 + WORD_SCHEDULER_12_63 160 + ROUND_16_63 A B C D E F G H 0xD8A7A879 208 284 + WORD_SCHEDULER_12_63 164 + ROUND_16_63 D A B C H E F G 0xB14F50F3 212 284 + WORD_SCHEDULER_12_63 168 + ROUND_16_63 C D A B G H E F 0x629EA1E7 216 284 + WORD_SCHEDULER_12_63 172 + ROUND_16_63 B C D A F G H E 0xC53D43CE 220 284 + WORD_SCHEDULER_12_63 176 + ROUND_16_63 A B C D E F G H 0x8A7A879D 224 284 + WORD_SCHEDULER_12_63 180 + ROUND_16_63 D A B C H E F G 0x14F50F3B 228 284 + WORD_SCHEDULER_12_63 184 + ROUND_16_63 C D A B G H E F 0x29EA1E76 232 284 + WORD_SCHEDULER_12_63 188 + ROUND_16_63 B C D A F G H E 0x53D43CEC 236 284 + WORD_SCHEDULER_12_63 192 + ROUND_16_63 A B C D E F G H 0xA7A879D8 240 284 + WORD_SCHEDULER_12_63 196 + ROUND_16_63 D A B C H E F G 0x4F50F3B1 244 284 + WORD_SCHEDULER_12_63 200 + ROUND_16_63 C D A B G H E F 0x9EA1E762 248 284 + WORD_SCHEDULER_12_63 204 + ROUND_16_63 B C D A F G H E 0x3D43CEC5 252 284 + + xorl A,(STATE) + xorl B,4(STATE) + xorl C,8(STATE) + xorl D,12(STATE) + xorl E,16(STATE) + xorl F,20(STATE) + xorl G,24(STATE) + xorl H,28(STATE) + + leaq 64(DATA),DATA + decq NUM + jz .Lsm3_final + jmp .Lsm3_loop + +.Lsm3_final: + # Clear Context + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + # Restore Registers + movq 300(%rsp),%rbx + movq 8+300(%rsp),%rbp + movq 16+300(%rsp),%r12 + movq 24+300(%rsp),%r13 + movq 32+300(%rsp),%r14 + movq 40+300(%rsp),%r15 + addq $348,%rsp + +.Lsm3_ret: + ret +.size SM3_CompressAsm, .-SM3_CompressAsm + +.section .rodata +.align 64 +MASKS: +# .shuffle_mask: (%rax) +.byte 3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12 +# left rotations +# .r16: 16(%rax) +.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 +# .r24: 32(%rax) +.byte 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12 + +#endif diff --git a/crypto/sm3/src/asm_sm3.c b/crypto/sm3/src/asm_sm3.c new file mode 100644 index 00000000..29e0b2e6 --- /dev/null +++ b/crypto/sm3/src/asm_sm3.c @@ -0,0 +1,26 @@ +/* + * 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_SM3 + +#include "sm3_local.h" +#include "crypt_utils.h" + +void SM3_Compress(uint32_t state[8], const uint8_t *data, uint32_t blockCnt) +{ + return SM3_CompressAsm(state, data, blockCnt); +} +#endif // HITLS_CRYPTO_SM3 diff --git a/crypto/sm3/src/noasm_sm3.c b/crypto/sm3/src/noasm_sm3.c new file mode 100644 index 00000000..e0849b4a --- /dev/null +++ b/crypto/sm3/src/noasm_sm3.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM3 + +#include +#include "crypt_utils.h" +#include "bsl_sal.h" +#include "crypt_sm3.h" + +#define K0 0x79cc4519U +#define K1 0xf3988a32U +#define K2 0xe7311465U +#define K3 0xce6228cbU +#define K4 0x9cc45197U +#define K5 0x3988a32fU +#define K6 0x7311465eU +#define K7 0xe6228cbcU +#define K8 0xcc451979U +#define K9 0x988a32f3U +#define K10 0x311465e7U +#define K11 0x6228cbceU +#define K12 0xc451979cU +#define K13 0x88a32f39U +#define K14 0x11465e73U +#define K15 0x228cbce6U +#define K16 0x9d8a7a87U +#define K17 0x3b14f50fU +#define K18 0x7629ea1eU +#define K19 0xec53d43cU +#define K20 0xd8a7a879U +#define K21 0xb14f50f3U +#define K22 0x629ea1e7U +#define K23 0xc53d43ceU +#define K24 0x8a7a879dU +#define K25 0x14f50f3bU +#define K26 0x29ea1e76U +#define K27 0x53d43cecU +#define K28 0xa7a879d8U +#define K29 0x4f50f3b1U +#define K30 0x9ea1e762U +#define K31 0x3d43cec5U +#define K32 0x7a879d8aU +#define K33 0xf50f3b14U +#define K34 0xea1e7629U +#define K35 0xd43cec53U +#define K36 0xa879d8a7U +#define K37 0x50f3b14fU +#define K38 0xa1e7629eU +#define K39 0x43cec53dU +#define K40 0x879d8a7aU +#define K41 0x0f3b14f5U +#define K42 0x1e7629eaU +#define K43 0x3cec53d4U +#define K44 0x79d8a7a8U +#define K45 0xf3b14f50U +#define K46 0xe7629ea1U +#define K47 0xcec53d43U +#define K48 0x9d8a7a87U +#define K49 0x3b14f50fU +#define K50 0x7629ea1eU +#define K51 0xec53d43cU +#define K52 0xd8a7a879U +#define K53 0xb14f50f3U +#define K54 0x629ea1e7U +#define K55 0xc53d43ceU +#define K56 0x8a7a879dU +#define K57 0x14f50f3bU +#define K58 0x29ea1e76U +#define K59 0x53d43cecU +#define K60 0xa7a879d8U +#define K61 0x4f50f3b1U +#define K62 0x9ea1e762U +#define K63 0x3d43cec5U + +#define P0(x) ((x) ^ ROTL32((x), 9) ^ ROTL32((x), 17)) +#define P1(x) ((x) ^ ROTL32((x), 15) ^ ROTL32((x), 23)) + +#define FF0(x, y, z) ((x) ^ (y) ^ (z)) +#define FF1(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define GG0(x, y, z) ((x) ^ (y) ^ (z)) +#define GG1(x, y, z) (((x) & (y)) | (~(x) & (z))) + +#define ROUND(A, B, C, D, E, F, G, H, K, FF, GG, Wj, Wi) do { \ + uint32_t a12 = ROTL32((A), 12); \ + uint32_t ss1 = ROTL32(a12 + (E) + (K), 7); \ + uint32_t ss2 = ss1 ^ a12; \ + uint32_t tt1 = FF((A), (B), (C)) + (D) + ss2 + (Wi); \ + uint32_t tt2 = GG((E), (F), (G)) + (H) + ss1 + (Wj); \ + (H) = tt1; (D) = P0(tt2); \ + (B) = ROTL32((B), 9); (F) = ROTL32((F), 19); \ +} while (0) + +#define ROUND00_16(A, B, C, D, E, F, G, H, K, Wj, Wi) \ + ROUND(A, B, C, D, E, F, G, H, K, FF0, GG0, Wj, Wi) + +#define ROUND16_63(A, B, C, D, E, F, G, H, K, Wj, Wi) \ + ROUND(A, B, C, D, E, F, G, H, K, FF1, GG1, Wj, Wi) + +#define EXPAND(W1, W2, W3, W4, W5) \ + (P1((W1) ^ (W2) ^ ROTL32((W3), 15)) ^ ROTL32((W4), 7) ^ (W5)) + +/* see the GM standard document GM/T 0004-2012 chapter 5.3.3 */ +void SM3_Compress(uint32_t state[8], const uint8_t *data, uint32_t blockCnt) +{ + uint32_t w[16] = {0}; + const uint8_t *input = data; + uint32_t count = blockCnt; + + while (count > 0) { + /* converts data to 32 bits for calculation */ + w[0] = GET_UINT32_BE(input, 0); + w[1] = GET_UINT32_BE(input, 4); + w[2] = GET_UINT32_BE(input, 8); + w[3] = GET_UINT32_BE(input, 12); + w[4] = GET_UINT32_BE(input, 16); + w[5] = GET_UINT32_BE(input, 20); + w[6] = GET_UINT32_BE(input, 24); + w[7] = GET_UINT32_BE(input, 28); + w[8] = GET_UINT32_BE(input, 32); + w[9] = GET_UINT32_BE(input, 36); + w[10] = GET_UINT32_BE(input, 40); + w[11] = GET_UINT32_BE(input, 44); + w[12] = GET_UINT32_BE(input, 48); + w[13] = GET_UINT32_BE(input, 52); + w[14] = GET_UINT32_BE(input, 56); + w[15] = GET_UINT32_BE(input, 60); + + uint32_t a = state[0]; + uint32_t b = state[1]; + uint32_t c = state[2]; + uint32_t d = state[3]; + uint32_t e = state[4]; + uint32_t f = state[5]; + uint32_t g = state[6]; + uint32_t h = state[7]; + + // 0 ~ 15 round + ROUND00_16(a, b, c, d, e, f, g, h, K0, w[0], w[0] ^ w[4]); + ROUND00_16(h, a, b, c, d, e, f, g, K1, w[1], w[1] ^ w[5]); + ROUND00_16(g, h, a, b, c, d, e, f, K2, w[2], w[2] ^ w[6]); + ROUND00_16(f, g, h, a, b, c, d, e, K3, w[3], w[3] ^ w[7]); + ROUND00_16(e, f, g, h, a, b, c, d, K4, w[4], w[4] ^ w[8]); + ROUND00_16(d, e, f, g, h, a, b, c, K5, w[5], w[5] ^ w[9]); + ROUND00_16(c, d, e, f, g, h, a, b, K6, w[6], w[6] ^ w[10]); + ROUND00_16(b, c, d, e, f, g, h, a, K7, w[7], w[7] ^ w[11]); + ROUND00_16(a, b, c, d, e, f, g, h, K8, w[8], w[8] ^ w[12]); + ROUND00_16(h, a, b, c, d, e, f, g, K9, w[9], w[9] ^ w[13]); + ROUND00_16(g, h, a, b, c, d, e, f, K10, w[10], w[10] ^ w[14]); + ROUND00_16(f, g, h, a, b, c, d, e, K11, w[11], w[11] ^ w[15]); + w[0] = EXPAND(w[0], w[7], w[13], w[3], w[10]); + ROUND00_16(e, f, g, h, a, b, c, d, K12, w[12], w[12] ^ w[0]); + w[1] = EXPAND(w[1], w[8], w[14], w[4], w[11]); + ROUND00_16(d, e, f, g, h, a, b, c, K13, w[13], w[13] ^ w[1]); + w[2] = EXPAND(w[2], w[9], w[15], w[5], w[12]); + ROUND00_16(c, d, e, f, g, h, a, b, K14, w[14], w[14] ^ w[2]); + w[3] = EXPAND(w[3], w[10], w[0], w[6], w[13]); + ROUND00_16(b, c, d, e, f, g, h, a, K15, w[15], w[15] ^ w[3]); + + // 16 ~ 63 round + w[4] = EXPAND(w[4], w[11], w[1], w[7], w[14]); + ROUND16_63(a, b, c, d, e, f, g, h, K16, w[0], w[0] ^ w[4]); + w[5] = EXPAND(w[5], w[12], w[2], w[8], w[15]); + ROUND16_63(h, a, b, c, d, e, f, g, K17, w[1], w[1] ^ w[5]); + w[6] = EXPAND(w[6], w[13], w[3], w[9], w[0]); + ROUND16_63(g, h, a, b, c, d, e, f, K18, w[2], w[2] ^ w[6]); + w[7] = EXPAND(w[7], w[14], w[4], w[10], w[1]); + ROUND16_63(f, g, h, a, b, c, d, e, K19, w[3], w[3] ^ w[7]); + w[8] = EXPAND(w[8], w[15], w[5], w[11], w[2]); + ROUND16_63(e, f, g, h, a, b, c, d, K20, w[4], w[4] ^ w[8]); + w[9] = EXPAND(w[9], w[0], w[6], w[12], w[3]); + ROUND16_63(d, e, f, g, h, a, b, c, K21, w[5], w[5] ^ w[9]); + w[10] = EXPAND(w[10], w[1], w[7], w[13], w[4]); + ROUND16_63(c, d, e, f, g, h, a, b, K22, w[6], w[6] ^ w[10]); + w[11] = EXPAND(w[11], w[2], w[8], w[14], w[5]); + ROUND16_63(b, c, d, e, f, g, h, a, K23, w[7], w[7] ^ w[11]); + w[12] = EXPAND(w[12], w[3], w[9], w[15], w[6]); + ROUND16_63(a, b, c, d, e, f, g, h, K24, w[8], w[8] ^ w[12]); + w[13] = EXPAND(w[13], w[4], w[10], w[0], w[7]); + ROUND16_63(h, a, b, c, d, e, f, g, K25, w[9], w[9] ^ w[13]); + w[14] = EXPAND(w[14], w[5], w[11], w[1], w[8]); + ROUND16_63(g, h, a, b, c, d, e, f, K26, w[10], w[10] ^ w[14]); + w[15] = EXPAND(w[15], w[6], w[12], w[2], w[9]); + ROUND16_63(f, g, h, a, b, c, d, e, K27, w[11], w[11] ^ w[15]); + w[0] = EXPAND(w[0], w[7], w[13], w[3], w[10]); + ROUND16_63(e, f, g, h, a, b, c, d, K28, w[12], w[12] ^ w[0]); + w[1] = EXPAND(w[1], w[8], w[14], w[4], w[11]); + ROUND16_63(d, e, f, g, h, a, b, c, K29, w[13], w[13] ^ w[1]); + w[2] = EXPAND(w[2], w[9], w[15], w[5], w[12]); + ROUND16_63(c, d, e, f, g, h, a, b, K30, w[14], w[14] ^ w[2]); + w[3] = EXPAND(w[3], w[10], w[0], w[6], w[13]); + ROUND16_63(b, c, d, e, f, g, h, a, K31, w[15], w[15] ^ w[3]); + + w[4] = EXPAND(w[4], w[11], w[1], w[7], w[14]); + ROUND16_63(a, b, c, d, e, f, g, h, K32, w[0], w[0] ^ w[4]); + w[5] = EXPAND(w[5], w[12], w[2], w[8], w[15]); + ROUND16_63(h, a, b, c, d, e, f, g, K33, w[1], w[1] ^ w[5]); + w[6] = EXPAND(w[6], w[13], w[3], w[9], w[0]); + ROUND16_63(g, h, a, b, c, d, e, f, K34, w[2], w[2] ^ w[6]); + w[7] = EXPAND(w[7], w[14], w[4], w[10], w[1]); + ROUND16_63(f, g, h, a, b, c, d, e, K35, w[3], w[3] ^ w[7]); + w[8] = EXPAND(w[8], w[15], w[5], w[11], w[2]); + ROUND16_63(e, f, g, h, a, b, c, d, K36, w[4], w[4] ^ w[8]); + w[9] = EXPAND(w[9], w[0], w[6], w[12], w[3]); + ROUND16_63(d, e, f, g, h, a, b, c, K37, w[5], w[5] ^ w[9]); + w[10] = EXPAND(w[10], w[1], w[7], w[13], w[4]); + ROUND16_63(c, d, e, f, g, h, a, b, K38, w[6], w[6] ^ w[10]); + w[11] = EXPAND(w[11], w[2], w[8], w[14], w[5]); + ROUND16_63(b, c, d, e, f, g, h, a, K39, w[7], w[7] ^ w[11]); + w[12] = EXPAND(w[12], w[3], w[9], w[15], w[6]); + ROUND16_63(a, b, c, d, e, f, g, h, K40, w[8], w[8] ^ w[12]); + w[13] = EXPAND(w[13], w[4], w[10], w[0], w[7]); + ROUND16_63(h, a, b, c, d, e, f, g, K41, w[9], w[9] ^ w[13]); + w[14] = EXPAND(w[14], w[5], w[11], w[1], w[8]); + ROUND16_63(g, h, a, b, c, d, e, f, K42, w[10], w[10] ^ w[14]); + w[15] = EXPAND(w[15], w[6], w[12], w[2], w[9]); + ROUND16_63(f, g, h, a, b, c, d, e, K43, w[11], w[11] ^ w[15]); + w[0] = EXPAND(w[0], w[7], w[13], w[3], w[10]); + ROUND16_63(e, f, g, h, a, b, c, d, K44, w[12], w[12] ^ w[0]); + w[1] = EXPAND(w[1], w[8], w[14], w[4], w[11]); + ROUND16_63(d, e, f, g, h, a, b, c, K45, w[13], w[13] ^ w[1]); + w[2] = EXPAND(w[2], w[9], w[15], w[5], w[12]); + ROUND16_63(c, d, e, f, g, h, a, b, K46, w[14], w[14] ^ w[2]); + w[3] = EXPAND(w[3], w[10], w[0], w[6], w[13]); + ROUND16_63(b, c, d, e, f, g, h, a, K47, w[15], w[15] ^ w[3]); + + w[4] = EXPAND(w[4], w[11], w[1], w[7], w[14]); + ROUND16_63(a, b, c, d, e, f, g, h, K48, w[0], w[0] ^ w[4]); + w[5] = EXPAND(w[5], w[12], w[2], w[8], w[15]); + ROUND16_63(h, a, b, c, d, e, f, g, K49, w[1], w[1] ^ w[5]); + w[6] = EXPAND(w[6], w[13], w[3], w[9], w[0]); + ROUND16_63(g, h, a, b, c, d, e, f, K50, w[2], w[2] ^ w[6]); + w[7] = EXPAND(w[7], w[14], w[4], w[10], w[1]); + ROUND16_63(f, g, h, a, b, c, d, e, K51, w[3], w[3] ^ w[7]); + w[8] = EXPAND(w[8], w[15], w[5], w[11], w[2]); + ROUND16_63(e, f, g, h, a, b, c, d, K52, w[4], w[4] ^ w[8]); + w[9] = EXPAND(w[9], w[0], w[6], w[12], w[3]); + ROUND16_63(d, e, f, g, h, a, b, c, K53, w[5], w[5] ^ w[9]); + w[10] = EXPAND(w[10], w[1], w[7], w[13], w[4]); + ROUND16_63(c, d, e, f, g, h, a, b, K54, w[6], w[6] ^ w[10]); + w[11] = EXPAND(w[11], w[2], w[8], w[14], w[5]); + ROUND16_63(b, c, d, e, f, g, h, a, K55, w[7], w[7] ^ w[11]); + w[12] = EXPAND(w[12], w[3], w[9], w[15], w[6]); + ROUND16_63(a, b, c, d, e, f, g, h, K56, w[8], w[8] ^ w[12]); + w[13] = EXPAND(w[13], w[4], w[10], w[0], w[7]); + ROUND16_63(h, a, b, c, d, e, f, g, K57, w[9], w[9] ^ w[13]); + w[14] = EXPAND(w[14], w[5], w[11], w[1], w[8]); + ROUND16_63(g, h, a, b, c, d, e, f, K58, w[10], w[10] ^ w[14]); + w[15] = EXPAND(w[15], w[6], w[12], w[2], w[9]); + ROUND16_63(f, g, h, a, b, c, d, e, K59, w[11], w[11] ^ w[15]); + w[0] = EXPAND(w[0], w[7], w[13], w[3], w[10]); + ROUND16_63(e, f, g, h, a, b, c, d, K60, w[12], w[12] ^ w[0]); + w[1] = EXPAND(w[1], w[8], w[14], w[4], w[11]); + ROUND16_63(d, e, f, g, h, a, b, c, K61, w[13], w[13] ^ w[1]); + w[2] = EXPAND(w[2], w[9], w[15], w[5], w[12]); + ROUND16_63(c, d, e, f, g, h, a, b, K62, w[14], w[14] ^ w[2]); + w[3] = EXPAND(w[3], w[10], w[0], w[6], w[13]); + ROUND16_63(b, c, d, e, f, g, h, a, K63, w[15], w[15] ^ w[3]); + + state[0] ^= a; + state[1] ^= b; + state[2] ^= c; + state[3] ^= d; + state[4] ^= e; + state[5] ^= f; + state[6] ^= g; + state[7] ^= h; + + input += CRYPT_SM3_BLOCKSIZE; + count--; + } +} +#endif // HITLS_CRYPTO_SM3 diff --git a/crypto/sm3/src/sm3_local.h b/crypto/sm3/src/sm3_local.h new file mode 100644 index 00000000..eacd50b7 --- /dev/null +++ b/crypto/sm3/src/sm3_local.h @@ -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 SM3_LOCAL_H +#define SM3_LOCAL_H + + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM3 + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +void SM3_Compress(uint32_t state[8], const uint8_t *data, uint32_t blockCnt); +/* assembly interface */ +void SM3_CompressAsm(uint32_t state[8], const uint8_t *data, uint32_t blockCnt); + + +#ifdef __cplusplus +} +#endif /* __cpluscplus */ + +#endif // HITLS_CRYPTO_SM3 + +#endif // SM3_LOCAL_H diff --git a/crypto/sm3/src/sm3_public.c b/crypto/sm3/src/sm3_public.c new file mode 100644 index 00000000..72f1e455 --- /dev/null +++ b/crypto/sm3/src/sm3_public.c @@ -0,0 +1,200 @@ +/* + * 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_SM3 + +#include +#include +#include "securec.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "crypt_sm3.h" +#include "sm3_local.h" + +int32_t CRYPT_SM3_Init(CRYPT_SM3_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + (void)memset_s(ctx, sizeof(CRYPT_SM3_Ctx), 0, sizeof(CRYPT_SM3_Ctx)); + /* GM/T 0004-2012 chapter 4.1 */ + ctx->h[0] = 0x7380166F; + ctx->h[1] = 0x4914B2B9; + ctx->h[2] = 0x172442D7; + ctx->h[3] = 0xDA8A0600; + ctx->h[4] = 0xA96F30BC; + ctx->h[5] = 0x163138AA; + ctx->h[6] = 0xE38DEE4D; + ctx->h[7] = 0xB0FB0E4E; + return CRYPT_SUCCESS; +} + +void CRYPT_SM3_Deinit(CRYPT_SM3_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return; + } + (void)memset_s(ctx, sizeof(CRYPT_SM3_Ctx), 0, sizeof(CRYPT_SM3_Ctx)); +} + +static uint32_t IsInputOverflow(CRYPT_SM3_Ctx *ctx, uint32_t nbytes) +{ + uint32_t cnt0 = ctx->lNum + (nbytes << SHIFTS_PER_BYTE); + if (cnt0 < ctx->lNum) { + if (++ctx->hNum == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM3_INPUT_OVERFLOW); + return CRYPT_SM3_INPUT_OVERFLOW; + } + } + uint32_t cnt1 = ctx->hNum + (uint32_t)(nbytes >> (BITSIZE(uint32_t) - SHIFTS_PER_BYTE)); + if (cnt1 < ctx->hNum) { + BSL_ERR_PUSH_ERROR(CRYPT_SM3_INPUT_OVERFLOW); + return CRYPT_SM3_INPUT_OVERFLOW; + } + ctx->hNum = cnt1; + ctx->lNum = cnt0; + return CRYPT_SUCCESS; +} + +static int32_t IsUpdateParamValid(CRYPT_SM3_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + if ((ctx == NULL) || (in == NULL && len != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (IsInputOverflow(ctx, len) != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(CRYPT_SM3_INPUT_OVERFLOW); + return CRYPT_SM3_INPUT_OVERFLOW; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM3_Update(CRYPT_SM3_Ctx *ctx, const uint8_t *in, uint32_t len) +{ + int32_t ret = IsUpdateParamValid(ctx, in, len); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (len == 0) { + return CRYPT_SUCCESS; + } + + const uint8_t *data = in; + uint32_t dataLen = len; + uint32_t left = CRYPT_SM3_BLOCKSIZE - ctx->num; + + if (ctx->num != 0) { + if (dataLen < left) { + (void)memcpy_s(ctx->block + ctx->num, left, data, dataLen); + ctx->num += dataLen; + return CRYPT_SUCCESS; + } + // When the external input data is greater than the remaining space of the block, + // copy the data which is the same length as the remaining space. + (void)memcpy_s(ctx->block + ctx->num, left, data, left); + SM3_Compress(ctx->h, ctx->block, 1); + dataLen -= left; + data += left; + ctx->num = 0; + } + + uint32_t blockCnt = dataLen / CRYPT_SM3_BLOCKSIZE; + if (blockCnt > 0) { + SM3_Compress(ctx->h, data, blockCnt); + blockCnt *= CRYPT_SM3_BLOCKSIZE; + data += blockCnt; + dataLen -= blockCnt; + } + + if (dataLen != 0) { + // copy the remaining data to the cache array + (void)memcpy_s(ctx->block, CRYPT_SM3_BLOCKSIZE, data, dataLen); + ctx->num = dataLen; + } + + return CRYPT_SUCCESS; +} + +static int32_t IsFinalParamValid(const CRYPT_SM3_Ctx *ctx, const uint8_t *out, const uint32_t *outLen) +{ + if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (*outLen < CRYPT_SM3_DIGESTSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH); + return CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH; + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM3_Final(CRYPT_SM3_Ctx *ctx, uint8_t *out, uint32_t *outLen) +{ + int32_t ret = IsFinalParamValid(ctx, out, outLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ctx->block[ctx->num++] = 0x80; /* 0x80 means add '1' to the end of the message */ + uint8_t *block = ctx->block; + uint32_t num = ctx->num; + uint32_t left = CRYPT_SM3_BLOCKSIZE - num; + if (left < 8) { /* less than 8 bytes which insufficient for storing data length data */ + (void)memset_s(block + num, left, 0, left); + SM3_Compress(ctx->h, ctx->block, 1); + num = 0; + left = CRYPT_SM3_BLOCKSIZE; + } + (void)memset_s(block + num, left - 8, 0, left - 8); + block += CRYPT_SM3_BLOCKSIZE - 8; + PUT_UINT32_BE(ctx->hNum, block, 0); + block += sizeof(uint32_t); + PUT_UINT32_BE(ctx->lNum, block, 0); + SM3_Compress(ctx->h, ctx->block, 1); + ctx->num = 0; + + PUT_UINT32_BE(ctx->h[0], out, 0); + PUT_UINT32_BE(ctx->h[1], out, 4); + PUT_UINT32_BE(ctx->h[2], out, 8); + PUT_UINT32_BE(ctx->h[3], out, 12); + PUT_UINT32_BE(ctx->h[4], out, 16); + PUT_UINT32_BE(ctx->h[5], out, 20); + PUT_UINT32_BE(ctx->h[6], out, 24); + PUT_UINT32_BE(ctx->h[7], out, 28); + *outLen = CRYPT_SM3_DIGESTSIZE; + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM3_CopyCtx(CRYPT_SM3_Ctx *dst, const CRYPT_SM3_Ctx *src) +{ + if (dst == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + (void)memcpy_s(dst, sizeof(CRYPT_SM3_Ctx), src, sizeof(CRYPT_SM3_Ctx)); + return CRYPT_SUCCESS; +} +#endif /* HITLS_CRYPTO_SM3 */ diff --git a/crypto/sm4/include/crypt_sm4.h b/crypto/sm4/include/crypt_sm4.h new file mode 100644 index 00000000..4a63c32a --- /dev/null +++ b/crypto/sm4/include/crypt_sm4.h @@ -0,0 +1,334 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_SM4_H +#define CRYPT_SM4_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM4 + +#include +#include +#include +#include "crypt_types.h" +#include "crypt_local_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define CRYPT_SM4_BLOCKSIZE 16 +#define CRYPT_SM4_BLOCKSIZE_16 256 +#define CRYPT_SM4_ROUNDS 32 + +typedef struct { + uint8_t iv[CRYPT_SM4_BLOCKSIZE]; + uint32_t rk[CRYPT_SM4_ROUNDS]; + bool safeMode; // Side channel security +} CRYPT_SM4_Ctx; + +/** + * TE(a,b,c,d) = LE(SBOX[a],SBOX[b],SBOX[c],SBOX[d]) + * = LE(SBOX[a],0,0,0)⊕LE(0,SBOX[b],0,0)⊕LE(0,0,SBOX[c],0)⊕LE(0,0,0,SBOX[d]) + * = LE(SBOX[a] << 24)⊕LE(SBOX[b] << 16)⊕LE(SBOX[c] << 8)⊕LE(SBOX[d]) + * = LE(SBOX[a] <<< 24)⊕LE(SBOX[b] <<< 16)⊕LE(SBOX[c] <<< 8)⊕LE(SBOX[d]) + * = (LE(SBOX[a]) <<< 24)⊕(LE(SBOX[b]) <<< 16)⊕(LE(SBOX[c]) <<< 8)⊕LE(SBOX[d]) + * = (XBOX_0[a] <<< 24)⊕(XBOX_0[b] <<< 16)⊕(XBOX_0[c] <<< 8)⊕XBOX_0[d] + * = XBOX_3[a]⊕XBOX_2[b]⊕XBOX_1[c]⊕XBOX_0[d] + * F(Xi,Xi+1,Xi+2,Xi+3,rki) = Xi⊕TE(Xi+1⊕Xi+2⊕Xi+3⊕rki) + */ +#define ROUND(t, x0, x1, x2, x3, rk, sbox) \ + do { \ + (t) = (x1) ^ (x2) ^ (x3) ^ (rk); \ + (x0) ^= (sbox##_3)[((t) >> 24) & 0xff]; \ + (x0) ^= (sbox##_2)[((t) >> 16) & 0xff]; \ + (x0) ^= (sbox##_1)[((t) >> 8) & 0xff]; \ + (x0) ^= (sbox##_0)[(t) & 0xff]; \ + } while (0) + +/** + * @brief SM4 Set the encryption and decryption key. + * + * @param [IN] ctx SM4 context + * @param [IN] key Key + * @param [IN] keyLen Key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_SetKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t keyLen); + +/** + * @brief SM4 encryption. The data length must be an integer multiple of 16. + * + * @param [IN] ctx SM4 context + * @param [IN] in Data to be encrypted + * @param [OUT] out Encrypted data + * @param [IN] length Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length); + +/** + * @brief SM4 decryption. The data length must be an integer multiple of 16. + * + * @param [IN] ctx SM4 context + * @param [IN] in Data to be decrypted + * @param [OUT] out Decrypted Data + * @param [IN] length Data length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length); + +/** + * @brief Clear the SM4 context + * + * @param [IN] ctx sm4 context + */ +void CRYPT_SM4_Clean(CRYPT_SM4_Ctx *ctx); + +#ifdef HITLS_CRYPTO_XTS +/** + * @brief SM4 Set the encryption key. + * + * @param ctx [IN] sm4 Context + * @param key [IN] Key. The first 16 bytes are data_key, and the last 16 bytes are tweak_key. + * @param keyLen [IN] Key length + * + * @retval #CRYPT_SUCCESS succeeded. + * @retval #CRYPT_NULL_INPUT ctx or key is NULL. + * @retval #CRYPT_SM4_ERR_KEY_LEN The key length is not equal to 32. + */ +int32_t CRYPT_SM4_XTS_SetEncryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief SM4 Set the decryption key. + * + * @param ctx [IN] sm4 Context + * @param key [IN] Key + * @param keyLen [IN] Key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_XTS_SetDecryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief Clear SM4_xts context + * + * @param [IN] ctx sm4 context + */ +void CRYPT_SM4_XTS_Clean(CRYPT_SM4_Ctx *ctx); + +/** + * @brief SM4 XTS mode encryption + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Length of the decrypted data + * @param iv [IN] Set IV + * + * @retval #CRYPT_SUCCESS succeeded. + * @retval #CRYPT_NULL_INPUT ctx,in,out is NULL + * @retval #CRYPT_SM4_DATALEN_ERROR The length of the decrypted data is less than 16 bytes. + */ +int32_t CRYPT_SM4_XTS_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv); + +/** + * @brief SM4 XTS mode encryption + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Length of the encrypted data + * @param iv [IN] Set IV + * + * @retval #CRYPT_SUCCESS succeeded. + * @retval #CRYPT_NULL_INPUT ctx/in/out is NULL + * @retval #CRYPT_SM4_DATALEN_ERROR The length of the encrypted data is less than 16. + */ +int32_t CRYPT_SM4_XTS_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv); +#endif + +/** + * @brief SM4 Set the encryption key (optimized). + * + * @param [IN] ctx SM4 context + * @param [IN] key Key + * @param [IN] len Key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_SetEncryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len); + +/** + * @brief SM4 Set the decryption key (optimized). + * + * @param [IN] ctx SM4 context + * @param [IN] key Key + * @param [IN] len Key length + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_SetDecryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len); + +#ifdef HITLS_CRYPTO_ECB +/** + * @brief SM4 ECB mode encryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Length of the encrypted data + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_ECB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); + +/** + * @brief SM4 ECB mode decryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be decrypted + * @param out [OUT] Decrypted data + * @param len [IN] Length of the decrypted data + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_ECB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len); +#endif + +#ifdef HITLS_CRYPTO_CBC +/** + * @brief SM4 CBC mode encryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Length of the encrypted data + * @param iv [IN] Set IV + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_CBC_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv); + +/** + * @brief SM4 CBC mode decryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be decrypted + * @param out [OUT] decrypted data + * @param len [IN] Length of the decrypted data + * @param iv [IN] Set IV + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_CBC_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv); +#endif + +#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_GCM) +/** + * @brief SM4 CTR mode encryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Length of the encrypted data + * @param iv [IN] Set IV + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_CTR_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv); + +/** + * @brief SM4 CTR mode decryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be decrypted + * @param out [OUT] decrypted data + * @param len [IN] Length of the decrypted data + * @param iv [IN] Set IV + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_CTR_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv); +#endif + +#ifdef HITLS_CRYPTO_OFB +/** + * @brief SM4 OFB mode encryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Length of the encrypted data + * @param iv [IN] Set IV + * @param offset [OUT] Length of less than one block + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_OFB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset); + +/** + * @brief SM4 OFB mode decryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be decrypted + * @param out [OUT] decrypted data + * @param len [IN] Length of the decrypted data + * @param iv [IN] Set IV + * @param offset [OUT] Length of less than one block + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_OFB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset); +#endif + +#ifdef HITLS_CRYPTO_CFB +/** + * @brief SM4 CFB mode encryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be encrypted + * @param out [OUT] Encrypted data + * @param len [IN] Length of the encrypted data + * @param iv [IN] Set IV + * @param offset [OUT] Length of less than one block. + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_CFB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset); + +/** + * @brief SM4 CFB mode decryption (optimized). + * @param ctx [IN] sm4 Context + * @param in [IN] Data to be decrypted + * @param out [OUT] decrypted data + * @param len [IN] Length of the decrypted data + * @param iv [IN] Set IV + * @param offset [OUT] Length of less than one block. + * + * @return Success: CRYPT_SUCCESS + * Other error codes are returned if the operation fails. + */ +int32_t CRYPT_SM4_CFB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // HITLS_CRYPTO_SM4 + +#endif // CRYPT_SM4_H \ No newline at end of file diff --git a/crypto/sm4/src/asm/crypt_sm4_armv8.S b/crypto/sm4/src/asm/crypt_sm4_armv8.S new file mode 100644 index 00000000..6eb97417 --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_armv8.S @@ -0,0 +1,1823 @@ +/* + * 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_SM4 + +.arch armv8-a+crypto +.text + +rk0 .req v12 +rk1 .req v13 +rka .req v14 +rkb .req v15 +rk2 .req v20 +rkc .req v21 + +vtmp0 .req v0 +vtmp1 .req v1 +vtmp2 .req v2 +vtmp3 .req v3 + +vtmp4 .req v24 +vtmp5 .req v25 +vtmp6 .req v22 +vtmp7 .req v23 + +data0 .req v4 +data1 .req v5 +data2 .req v6 +data3 .req v7 + +datax0 .req v8 +datax1 .req v9 +datax2 .req v10 +datax3 .req v11 + +vtmpx0 .req v12 +vtmpx1 .req v13 +vtmpx2 .req v14 +vtmpx3 .req v15 + +data10 .req v16 +data11 .req v17 +data12 .req v18 +data13 .req v19 + +MaskV .req v26 +TAHMatV .req v27 +TALMatV .req v28 +ATAHMatV .req v29 +ATALMatV .req v30 +ANDMaskV .req v31 + +MaskQ .req q26 +TAHMatQ .req q27 +TALMatQ .req q28 +ATAHMatQ .req q29 +ATALMatQ .req q30 +ANDMaskQ .req q31 +vtmp5q .req q25 +vtmp6q .req q22 +vtmp7q .req q23 + +inp .req x0 +outp .req x1 +blocks .req w2 +rks .req x3 + +wtmp0 .req w7 +wtmp1 .req w8 +wtmp2 .req w9 + +ptr .req x10 +counter .req w11 + +word0 .req w12 +word1 .req w13 +word2 .req w14 +word3 .req w15 + +xword1 .req x13 +tbox0 .req x19 +tbox1 .req x20 +tbox2 .req x21 +tbox3 .req x22 + +len .req x2 +ivp .req x4 +ctr .req w5 +ivec .req v3 +ivec1 .req v15 + +.Lxts_magic: + .quad 0x0101010101010187,0x0101010101010101 + +.Ltbox1: +.word 0xd55b5b8e, 0x924242d0, 0xeaa7a74d, 0xfdfbfb06, 0xcf3333fc, 0xe2878765, 0x3df4f4c9, 0xb5dede6b, 0x1658584e +.word 0xb4dada6e, 0x14505044, 0xc10b0bca, 0x28a0a088, 0xf8efef17, 0x2cb0b09c, 0x05141411, 0x2bacac87, 0x669d9dfb +.word 0x986a6af2, 0x77d9d9ae, 0x2aa8a882, 0xbcfafa46, 0x04101014, 0xc00f0fcf, 0xa8aaaa02, 0x45111154, 0x134c4c5f +.word 0x269898be, 0x4825256d, 0x841a1a9e, 0x0618181e, 0x9b6666fd, 0x9e7272ec, 0x4309094a, 0x51414110, 0xf7d3d324 +.word 0x934646d5, 0xecbfbf53, 0x9a6262f8, 0x7be9e992, 0x33ccccff, 0x55515104, 0x0b2c2c27, 0x420d0d4f, 0xeeb7b759 +.word 0xcc3f3ff3, 0xaeb2b21c, 0x638989ea, 0xe7939374, 0xb1cece7f, 0x1c70706c, 0xaba6a60d, 0xca2727ed, 0x08202028 +.word 0xeba3a348, 0x975656c1, 0x82020280, 0xdc7f7fa3, 0x965252c4, 0xf9ebeb12, 0x74d5d5a1, 0x8d3e3eb3, 0x3ffcfcc3 +.word 0xa49a9a3e, 0x461d1d5b, 0x071c1c1b, 0xa59e9e3b, 0xfff3f30c, 0xf0cfcf3f, 0x72cdcdbf, 0x175c5c4b, 0xb8eaea52 +.word 0x810e0e8f, 0x5865653d, 0x3cf0f0cc, 0x1964647d, 0xe59b9b7e, 0x87161691, 0x4e3d3d73, 0xaaa2a208, 0x69a1a1c8 +.word 0x6aadadc7, 0x83060685, 0xb0caca7a, 0x70c5c5b5, 0x659191f4, 0xd96b6bb2, 0x892e2ea7, 0xfbe3e318, 0xe8afaf47 +.word 0x0f3c3c33, 0x4a2d2d67, 0x71c1c1b0, 0x5759590e, 0x9f7676e9, 0x35d4d4e1, 0x1e787866, 0x249090b4, 0x0e383836 +.word 0x5f797926, 0x628d8def, 0x59616138, 0xd2474795, 0xa08a8a2a, 0x259494b1, 0x228888aa, 0x7df1f18c, 0x3bececd7 +.word 0x01040405, 0x218484a5, 0x79e1e198, 0x851e1e9b, 0xd7535384, 0x00000000, 0x4719195e, 0x565d5d0b, 0x9d7e7ee3 +.word 0xd04f4f9f, 0x279c9cbb, 0x5349491a, 0x4d31317c, 0x36d8d8ee, 0x0208080a, 0xe49f9f7b, 0xa2828220, 0xc71313d4 +.word 0xcb2323e8, 0x9c7a7ae6, 0xe9abab42, 0xbdfefe43, 0x882a2aa2, 0xd14b4b9a, 0x41010140, 0xc41f1fdb, 0x38e0e0d8 +.word 0xb7d6d661, 0xa18e8e2f, 0xf4dfdf2b, 0xf1cbcb3a, 0xcd3b3bf6, 0xfae7e71d, 0x608585e5, 0x15545441, 0xa3868625 +.word 0xe3838360, 0xacbaba16, 0x5c757529, 0xa6929234, 0x996e6ef7, 0x34d0d0e4, 0x1a686872, 0x54555501, 0xafb6b619 +.word 0x914e4edf, 0x32c8c8fa, 0x30c0c0f0, 0xf6d7d721, 0x8e3232bc, 0xb3c6c675, 0xe08f8f6f, 0x1d747469, 0xf5dbdb2e +.word 0xe18b8b6a, 0x2eb8b896, 0x800a0a8a, 0x679999fe, 0xc92b2be2, 0x618181e0, 0xc30303c0, 0x29a4a48d, 0x238c8caf +.word 0xa9aeae07, 0x0d343439, 0x524d4d1f, 0x4f393976, 0x6ebdbdd3, 0xd6575781, 0xd86f6fb7, 0x37dcdceb, 0x44151551 +.word 0xdd7b7ba6, 0xfef7f709, 0x8c3a3ab6, 0x2fbcbc93, 0x030c0c0f, 0xfcffff03, 0x6ba9a9c2, 0x73c9c9ba, 0x6cb5b5d9 +.word 0x6db1b1dc, 0x5a6d6d37, 0x50454515, 0x8f3636b9, 0x1b6c6c77, 0xadbebe13, 0x904a4ada, 0xb9eeee57, 0xde7777a9 +.word 0xbef2f24c, 0x7efdfd83, 0x11444455, 0xda6767bd, 0x5d71712c, 0x40050545, 0x1f7c7c63, 0x10404050, 0x5b696932 +.word 0xdb6363b8, 0x0a282822, 0xc20707c5, 0x31c4c4f5, 0x8a2222a8, 0xa7969631, 0xce3737f9, 0x7aeded97, 0xbff6f649 +.word 0x2db4b499, 0x75d1d1a4, 0xd3434390, 0x1248485a, 0xbae2e258, 0xe6979771, 0xb6d2d264, 0xb2c2c270, 0x8b2626ad +.word 0x68a5a5cd, 0x955e5ecb, 0x4b292962, 0x0c30303c, 0x945a5ace, 0x76ddddab, 0x7ff9f986, 0x649595f1, 0xbbe6e65d +.word 0xf2c7c735, 0x0924242d, 0xc61717d1, 0x6fb9b9d6, 0xc51b1bde, 0x86121294, 0x18606078, 0xf3c3c330, 0x7cf5f589 +.word 0xefb3b35c, 0x3ae8e8d2, 0xdf7373ac, 0x4c353579, 0x208080a0, 0x78e5e59d, 0xedbbbb56, 0x5e7d7d23, 0x3ef8f8c6 +.word 0xd45f5f8b, 0xc82f2fe7, 0x39e4e4dd, 0x49212168 + +.Ltbox2: +.word 0x5b5b8ed5, 0x4242d092, 0xa7a74dea, 0xfbfb06fd, 0x3333fccf, 0x878765e2, 0xf4f4c93d, 0xdede6bb5, 0x58584e16 +.word 0xdada6eb4, 0x50504414, 0x0b0bcac1, 0xa0a08828, 0xefef17f8, 0xb0b09c2c, 0x14141105, 0xacac872b, 0x9d9dfb66 +.word 0x6a6af298, 0xd9d9ae77, 0xa8a8822a, 0xfafa46bc, 0x10101404, 0x0f0fcfc0, 0xaaaa02a8, 0x11115445, 0x4c4c5f13 +.word 0x9898be26, 0x25256d48, 0x1a1a9e84, 0x18181e06, 0x6666fd9b, 0x7272ec9e, 0x09094a43, 0x41411051, 0xd3d324f7 +.word 0x4646d593, 0xbfbf53ec, 0x6262f89a, 0xe9e9927b, 0xccccff33, 0x51510455, 0x2c2c270b, 0xd0d4f42, 0xb7b759ee +.word 0x3f3ff3cc, 0xb2b21cae, 0x8989ea63, 0x939374e7, 0xcece7fb1, 0x70706c1c, 0xa6a60dab, 0x2727edca, 0x20202808 +.word 0xa3a348eb, 0x5656c197, 0x02028082, 0x7f7fa3dc, 0x5252c496, 0xebeb12f9, 0xd5d5a174, 0x3e3eb38d, 0xfcfcc33f +.word 0x9a9a3ea4, 0x1d1d5b46, 0x1c1c1b07, 0x9e9e3ba5, 0xf3f30cff, 0xcfcf3ff0, 0xcdcdbf72, 0x5c5c4b17, 0xeaea52b8 +.word 0x0e0e8f81, 0x65653d58, 0xf0f0cc3c, 0x64647d19, 0x9b9b7ee5, 0x16169187, 0x3d3d734e, 0xa2a208aa, 0xa1a1c869 +.word 0xadadc76a, 0x06068583, 0xcaca7ab0, 0xc5c5b570, 0x9191f465, 0x6b6bb2d9, 0x2e2ea789, 0xe3e318fb, 0xafaf47e8 +.word 0x3c3c330f, 0x2d2d674a, 0xc1c1b071, 0x59590e57, 0x7676e99f, 0xd4d4e135, 0x7878661e, 0x9090b424, 0x3838360e +.word 0x7979265f, 0x8d8def62, 0x61613859, 0x474795d2, 0x8a8a2aa0, 0x9494b125, 0x8888aa22, 0xf1f18c7d, 0xececd73b +.word 0x04040501, 0x8484a521, 0xe1e19879, 0x1e1e9b85, 0x535384d7, 0x00000000, 0x19195e47, 0x5d5d0b56, 0x7e7ee39d +.word 0x4f4f9fd0, 0x9c9cbb27, 0x49491a53, 0x31317c4d, 0xd8d8ee36, 0x08080a02, 0x9f9f7be4, 0x828220a2, 0x1313d4c7 +.word 0x2323e8cb, 0x7a7ae69c, 0xabab42e9, 0xfefe43bd, 0x2a2aa288, 0x4b4b9ad1, 0x01014041, 0x1f1fdbc4, 0xe0e0d838 +.word 0xd6d661b7, 0x8e8e2fa1, 0xdfdf2bf4, 0xcbcb3af1, 0x3b3bf6cd, 0xe7e71dfa, 0x8585e560, 0x54544115, 0x868625a3 +.word 0x838360e3, 0xbaba16ac, 0x7575295c, 0x929234a6, 0x6e6ef799, 0xd0d0e434, 0x6868721a, 0x55550154, 0xb6b619af +.word 0x4e4edf91, 0xc8c8fa32, 0xc0c0f030, 0xd7d721f6, 0x3232bc8e, 0xc6c675b3, 0x8f8f6fe0, 0x7474691d, 0xdbdb2ef5 +.word 0x8b8b6ae1, 0xb8b8962e, 0x0a0a8a80, 0x9999fe67, 0x2b2be2c9, 0x8181e061, 0x0303c0c3, 0xa4a48d29, 0x8c8caf23 +.word 0xaeae07a9, 0x3434390d, 0x4d4d1f52, 0x3939764f, 0xbdbdd36e, 0x575781d6, 0x6f6fb7d8, 0xdcdceb37, 0x15155144 +.word 0x7b7ba6dd, 0xf7f709fe, 0x3a3ab68c, 0xbcbc932f, 0x0c0c0f03, 0xffff03fc, 0xa9a9c26b, 0xc9c9ba73, 0xb5b5d96c +.word 0xb1b1dc6d, 0x6d6d375a, 0x45451550, 0x3636b98f, 0x6c6c771b, 0xbebe13ad, 0x4a4ada90, 0xeeee57b9, 0x7777a9de +.word 0xf2f24cbe, 0xfdfd837e, 0x44445511, 0x6767bdda, 0x71712c5d, 0x05054540, 0x7c7c631f, 0x40405010, 0x6969325b +.word 0x6363b8db, 0x2828220a, 0x0707c5c2, 0xc4c4f531, 0x2222a88a, 0x969631a7, 0x3737f9ce, 0xeded977a, 0xf6f649bf +.word 0xb4b4992d, 0xd1d1a475, 0x434390d3, 0x48485a12, 0xe2e258ba, 0x979771e6, 0xd2d264b6, 0xc2c270b2, 0x2626ad8b +.word 0xa5a5cd68, 0x5e5ecb95, 0x2929624b, 0x30303c0c, 0x5a5ace94, 0xddddab76, 0xf9f9867f, 0x9595f164, 0xe6e65dbb +.word 0xc7c735f2, 0x24242d09, 0x1717d1c6, 0xb9b9d66f, 0x1b1bdec5, 0x12129486, 0x60607818, 0xc3c330f3, 0xf5f5897c +.word 0xb3b35cef, 0xe8e8d23a, 0x7373acdf, 0x3535794c, 0x8080a020, 0xe5e59d78, 0xbbbb56ed, 0x7d7d235e, 0xf8f8c63e +.word 0x5f5f8bd4, 0x2f2fe7c8, 0xe4e4dd39, 0x21216849 + +.Ltbox3: +.word 0x5b8ed55b, 0x42d09242, 0xa74deaa7, 0xfb06fdfb, 0x33fccf33, 0x8765e287, 0xf4c93df4, 0xde6bb5de, 0x584e1658 +.word 0xda6eb4da, 0x50441450, 0x0bcac10b, 0xa08828a0, 0xef17f8ef, 0xb09c2cb0, 0x14110514, 0xac872bac, 0x9dfb669d +.word 0x6af2986a, 0xd9ae77d9, 0xa8822aa8, 0xfa46bcfa, 0x10140410, 0x0fcfc00f, 0xaa02a8aa, 0x11544511, 0x4c5f134c +.word 0x98be2698, 0x256d4825, 0x1a9e841a, 0x181e0618, 0x66fd9b66, 0x72ec9e72, 0x094a4309, 0x41105141, 0xd324f7d3 +.word 0x46d59346, 0xbf53ecbf, 0x62f89a62, 0xe9927be9, 0xccff33cc, 0x51045551, 0x2c270b2c, 0x0d4f420d, 0xb759eeb7 +.word 0x3ff3cc3f, 0xb21caeb2, 0x89ea6389, 0x9374e793, 0xce7fb1ce, 0x706c1c70, 0xa60daba6, 0x27edca27, 0x20280820 +.word 0xa348eba3, 0x56c19756, 0x02808202, 0x7fa3dc7f, 0x52c49652, 0xeb12f9eb, 0xd5a174d5, 0x3eb38d3e, 0xfcc33ffc +.word 0x9a3ea49a, 0x1d5b461d, 0x1c1b071c, 0x9e3ba59e, 0xf30cfff3, 0xcf3ff0cf, 0xcdbf72cd, 0x5c4b175c, 0xea52b8ea +.word 0x0e8f810e, 0x653d5865, 0xf0cc3cf0, 0x647d1964, 0x9b7ee59b, 0x16918716, 0x3d734e3d, 0xa208aaa2, 0xa1c869a1 +.word 0xadc76aad, 0x06858306, 0xca7ab0ca, 0xc5b570c5, 0x91f46591, 0x6bb2d96b, 0x2ea7892e, 0xe318fbe3, 0xaf47e8af +.word 0x3c330f3c, 0x2d674a2d, 0xc1b071c1, 0x590e5759, 0x76e99f76, 0xd4e135d4, 0x78661e78, 0x90b42490, 0x38360e38 +.word 0x79265f79, 0x8def628d, 0x61385961, 0x4795d247, 0x8a2aa08a, 0x94b12594, 0x88aa2288, 0xf18c7df1, 0xecd73bec +.word 0x04050104, 0x84a52184, 0xe19879e1, 0x1e9b851e, 0x5384d753, 0x00000000, 0x195e4719, 0x5d0b565d, 0x7ee39d7e +.word 0x4f9fd04f, 0x9cbb279c, 0x491a5349, 0x317c4d31, 0xd8ee36d8, 0x080a0208, 0x9f7be49f, 0x8220a282, 0x13d4c713 +.word 0x23e8cb23, 0x7ae69c7a, 0xab42e9ab, 0xfe43bdfe, 0x2aa2882a, 0x4b9ad14b, 0x01404101, 0x1fdbc41f, 0xe0d838e0 +.word 0xd661b7d6, 0x8e2fa18e, 0xdf2bf4df, 0xcb3af1cb, 0x3bf6cd3b, 0xe71dfae7, 0x85e56085, 0x54411554, 0x8625a386 +.word 0x8360e383, 0xba16acba, 0x75295c75, 0x9234a692, 0x6ef7996e, 0xd0e434d0, 0x68721a68, 0x55015455, 0xb619afb6 +.word 0x4edf914e, 0xc8fa32c8, 0xc0f030c0, 0xd721f6d7, 0x32bc8e32, 0xc675b3c6, 0x8f6fe08f, 0x74691d74, 0xdb2ef5db +.word 0x8b6ae18b, 0xb8962eb8, 0x0a8a800a, 0x99fe6799, 0x2be2c92b, 0x81e06181, 0x03c0c303, 0xa48d29a4, 0x8caf238c +.word 0xae07a9ae, 0x34390d34, 0x4d1f524d, 0x39764f39, 0xbdd36ebd, 0x5781d657, 0x6fb7d86f, 0xdceb37dc, 0x15514415 +.word 0x7ba6dd7b, 0xf709fef7, 0x3ab68c3a, 0xbc932fbc, 0x0c0f030c, 0xff03fcff, 0xa9c26ba9, 0xc9ba73c9, 0xb5d96cb5 +.word 0xb1dc6db1, 0x6d375a6d, 0x45155045, 0x36b98f36, 0x6c771b6c, 0xbe13adbe, 0x4ada904a, 0xee57b9ee, 0x77a9de77 +.word 0xf24cbef2, 0xfd837efd, 0x44551144, 0x67bdda67, 0x712c5d71, 0x05454005, 0x7c631f7c, 0x40501040, 0x69325b69 +.word 0x63b8db63, 0x28220a28, 0x07c5c207, 0xc4f531c4, 0x22a88a22, 0x9631a796, 0x37f9ce37, 0xed977aed, 0xf649bff6 +.word 0xb4992db4, 0xd1a475d1, 0x4390d343, 0x485a1248, 0xe258bae2, 0x9771e697, 0xd264b6d2, 0xc270b2c2, 0x26ad8b26 +.word 0xa5cd68a5, 0x5ecb955e, 0x29624b29, 0x303c0c30, 0x5ace945a, 0xddab76dd, 0xf9867ff9, 0x95f16495, 0xe65dbbe6 +.word 0xc735f2c7, 0x242d0924, 0x17d1c617, 0xb9d66fb9, 0x1bdec51b, 0x12948612, 0x60781860, 0xc330f3c3, 0xf5897cf5 +.word 0xb35cefb3, 0xe8d23ae8, 0x73acdf73, 0x35794c35, 0x80a02080, 0xe59d78e5, 0xbb56edbb, 0x7d235e7d, 0xf8c63ef8 +.word 0x5f8bd45f, 0x2fe7c82f, 0xe4dd39e4, 0x21684921 + +.Ltbox4: +.word 0x8ed55b5b, 0xd0924242, 0x4deaa7a7, 0x06fdfbfb, 0xfccf3333, 0x65e28787, 0xc93df4f4, 0x6bb5dede, 0x4e165858 +.word 0x6eb4dada, 0x44145050, 0xcac10b0b, 0x8828a0a0, 0x17f8efef, 0x9c2cb0b0, 0x11051414, 0x872bacac, 0xfb669d9d +.word 0xf2986a6a, 0xae77d9d9, 0x822aa8a8, 0x46bcfafa, 0x14041010, 0xcfc00f0f, 0x02a8aaaa, 0x54451111, 0x5f134c4c +.word 0xbe269898, 0x6d482525, 0x9e841a1a, 0x1e061818, 0xfd9b6666, 0xec9e7272, 0x4a430909, 0x10514141, 0x24f7d3d3 +.word 0xd5934646, 0x53ecbfbf, 0xf89a6262, 0x927be9e9, 0xff33cccc, 0x04555151, 0x270b2c2c, 0x4f420d0d, 0x59eeb7b7 +.word 0xf3cc3f3f, 0x1caeb2b2, 0xea638989, 0x74e79393, 0x7fb1cece, 0x6c1c7070, 0x0daba6a6, 0xedca2727, 0x28082020 +.word 0x48eba3a3, 0xc1975656, 0x80820202, 0xa3dc7f7f, 0xc4965252, 0x12f9ebeb, 0xa174d5d5, 0xb38d3e3e, 0xc33ffcfc +.word 0x3ea49a9a, 0x5b461d1d, 0x1b071c1c, 0x3ba59e9e, 0x0cfff3f3, 0x3ff0cfcf, 0xbf72cdcd, 0x4b175c5c, 0x52b8eaea +.word 0x8f810e0e, 0x3d586565, 0xcc3cf0f0, 0x7d196464, 0x7ee59b9b, 0x91871616, 0x734e3d3d, 0x08aaa2a2, 0xc869a1a1 +.word 0xc76aadad, 0x85830606, 0x7ab0caca, 0xb570c5c5, 0xf4659191, 0xb2d96b6b, 0xa7892e2e, 0x18fbe3e3, 0x47e8afaf +.word 0x330f3c3c, 0x674a2d2d, 0xb071c1c1, 0x0e575959, 0xe99f7676, 0xe135d4d4, 0x661e7878, 0xb4249090, 0x360e3838 +.word 0x265f7979, 0xef628d8d, 0x38596161, 0x95d24747, 0x2aa08a8a, 0xb1259494, 0xaa228888, 0x8c7df1f1, 0xd73becec +.word 0x05010404, 0xa5218484, 0x9879e1e1, 0x9b851e1e, 0x84d75353, 0x00000000, 0x5e471919, 0x0b565d5d, 0xe39d7e7e +.word 0x9fd04f4f, 0xbb279c9c, 0x1a534949, 0x7c4d3131, 0xee36d8d8, 0x0a020808, 0x7be49f9f, 0x20a28282, 0xd4c71313 +.word 0xe8cb2323, 0xe69c7a7a, 0x42e9abab, 0x43bdfefe, 0xa2882a2a, 0x9ad14b4b, 0x40410101, 0xdbc41f1f, 0xd838e0e0 +.word 0x61b7d6d6, 0x2fa18e8e, 0x2bf4dfdf, 0x3af1cbcb, 0xf6cd3b3b, 0x1dfae7e7, 0xe5608585, 0x41155454, 0x25a38686 +.word 0x60e38383, 0x16acbaba, 0x295c7575, 0x34a69292, 0xf7996e6e, 0xe434d0d0, 0x721a6868, 0x01545555, 0x19afb6b6 +.word 0xdf914e4e, 0xfa32c8c8, 0xf030c0c0, 0x21f6d7d7, 0xbc8e3232, 0x75b3c6c6, 0x6fe08f8f, 0x691d7474, 0x2ef5dbdb +.word 0x6ae18b8b, 0x962eb8b8, 0x8a800a0a, 0xfe679999, 0xe2c92b2b, 0xe0618181, 0xc0c30303, 0x8d29a4a4, 0xaf238c8c +.word 0x07a9aeae, 0x390d3434, 0x1f524d4d, 0x764f3939, 0xd36ebdbd, 0x81d65757, 0xb7d86f6f, 0xeb37dcdc, 0x51441515 +.word 0xa6dd7b7b, 0x09fef7f7, 0xb68c3a3a, 0x932fbcbc, 0x0f030c0c, 0x03fcffff, 0xc26ba9a9, 0xba73c9c9, 0xd96cb5b5 +.word 0xdc6db1b1, 0x375a6d6d, 0x15504545, 0xb98f3636, 0x771b6c6c, 0x13adbebe, 0xda904a4a, 0x57b9eeee, 0xa9de7777 +.word 0x4cbef2f2, 0x837efdfd, 0x55114444, 0xbdda6767, 0x2c5d7171, 0x45400505, 0x631f7c7c, 0x50104040, 0x325b6969 +.word 0xb8db6363, 0x220a2828, 0xc5c20707, 0xf531c4c4, 0xa88a2222, 0x31a79696, 0xf9ce3737, 0x977aeded, 0x49bff6f6 +.word 0x992db4b4, 0xa475d1d1, 0x90d34343, 0x5a124848, 0x58bae2e2, 0x71e69797, 0x64b6d2d2, 0x70b2c2c2, 0xad8b2626 +.word 0xcd68a5a5, 0xcb955e5e, 0x624b2929, 0x3c0c3030, 0xce945a5a, 0xab76dddd, 0x867ff9f9, 0xf1649595, 0x5dbbe6e6 +.word 0x35f2c7c7, 0x2d092424, 0xd1c61717, 0xd66fb9b9, 0xdec51b1b, 0x94861212, 0x78186060, 0x30f3c3c3, 0x897cf5f5 +.word 0x5cefb3b3, 0xd23ae8e8, 0xacdf7373, 0x794c3535, 0xa0208080, 0x9d78e5e5, 0x56edbbbb, 0x235e7d7d, 0xc63ef8f8 +.word 0x8bd45f5f, 0xe7c82f2f, 0xdd39e4e4, 0x68492121 + +#ifdef HITLS_BIG_ENDIAN +.Lsbox_magic: + .dword 0x0306090c0f020508,0x0b0e0104070a0d00 + .dword 0x22581a6002783a40,0x62185a2042387a00 + .dword 0xc10bb67c4a803df7,0x15df62a89e54e923 + .dword 0x1407c6d56c7fbead,0xb9aa6b78c1d21300 + .dword 0xe383c1a1fe9edcbc,0x6404462679195b3b + .dword 0x0E0D0C0F0A09080B,0x0605040702010003 + .dword 0x0D0C0F0E09080B0A,0x0504070601000302 + .dword 0x0C0F0E0D080B0A09,0x0407060500030201 +#else +.Lsbox_magic: + .dword 0x0b0e0104070a0d00,0x0306090c0f020508 + .dword 0x62185a2042387a00,0x22581a6002783a40 + .dword 0x15df62a89e54e923,0xc10bb67c4a803df7 + .dword 0xb9aa6b78c1d21300,0x1407c6d56c7fbead + .dword 0x6404462679195b3b,0xe383c1a1fe9edcbc + .dword 0x0605040702010003,0x0E0D0C0F0A09080B + .dword 0x0504070601000302,0x0D0C0F0E09080B0A + .dword 0x0407060500030201,0x0C0F0E0D080B0A09 +#endif + +.macro LoadSbox + ldr MaskQ, .Lsbox_magic + ldr TAHMatQ, .Lsbox_magic+16 + ldr TALMatQ, .Lsbox_magic+32 + ldr ATAHMatQ, .Lsbox_magic+48 + ldr ATALMatQ, .Lsbox_magic+64 + ldr vtmp5q, .Lsbox_magic+80 + ldr vtmp6q, .Lsbox_magic+96 + ldr vtmp7q, .Lsbox_magic+112 +.endm + +.macro round x1, x2, x3, x4, rk + eor word0,\x2, \x3 + eor word0, word0, \rk + eor word0, word0, \x4 + + and word1, word0, #0xff + ldr word1, [tbox0,xword1,lsl #2] + eor \x1, word1, \x1 + + ubfx word1, word0,#8,#8 + ldr word1, [tbox1, xword1, lsl #2] + eor \x1, word1, \x1 + + ubfx word1, word0, #16, #8 + ldr word1,[tbox2, xword1, lsl #2] + eor \x1, word1, \x1 + + lsr word1, word0, #24 + ldr word1, [tbox3, xword1, lsl #2] + eor \x1, word1, \x1 +.endm + +.macro EncRound4 offset1, offset2 + ldp word2, word3,[rks, \offset1] + round w8, w9, w10, w11, word2 + round w9, w10, w11, w8, word3 + ldp word2, word3,[rks, \offset2] + round w10, w11, w8, w9, word2 + round w11, w8, w9, w10, word3 +.endm + +.macro EncRound + EncRound4 0, 8 + EncRound4 16, 24 + EncRound4 32, 40 + EncRound4 48, 56 + EncRound4 64, 72 + EncRound4 80, 88 + EncRound4 96, 104 + EncRound4 112, 120 +.endm + +.macro transpose dat0s, dat1s, dat2s, dat3s, dat0d, dat1d, dat2d, dat3d, vt0s, vt1s, vt2s, vt3s, vt0d, vt1d, vt2d, vt3d + zip1 \vt0s, \dat0s, \dat1s + zip2 \vt1s, \dat0s, \dat1s + zip1 \vt2s, \dat2s, \dat3s + zip2 \vt3s, \dat2s, \dat3s + zip1 \dat0d, \vt0d, \vt2d + zip2 \dat1d, \vt0d, \vt2d + zip1 \dat2d, \vt1d, \vt3d + zip2 \dat3d, \vt1d, \vt3d +.endm + +.macro Encrypt1blkNorevCtr + mov w8,ivec.s[0] + mov w9,ivec.s[1] + mov w10,ivec.s[2] + mov w11,ivec.s[3] + EncRound + mov ivec.s[0],w11 + mov ivec.s[1],w10 + mov ivec.s[2],w9 + mov ivec.s[3],w8 +#ifndef HITLS_BIG_ENDIAN + rev32 v3.16b,v3.16b +#endif +.endm + +# matrix multiplication Mat*x = (lowerMat*x) ^ (higherMat*x) +.macro MulMatrix x, higherMat, lowerMat, tmp + ushr \tmp, \x, 4 + and \x, \x, ANDMaskV.16b + tbl \x, {\lowerMat}, \x + tbl \tmp, {\higherMat}, \tmp + eor \x, \x, \tmp +.endm + +# matrix multiplication Mat*x = (lowerMat*x) ^ (higherMat*x) +.macro MulMatrixOut x, higherMat, lowerMat, tmp, out + ushr \tmp, \x, 4 + and \x, \x, ANDMaskV.16b + tbl \x, {\lowerMat}, \x + tbl \tmp, {\higherMat}, \tmp + eor \out, \x, \tmp +.endm + +# Sbox operations for 4-lane of words +.macro Sbox dat, dat2 + movi ANDMaskV.16b, #0x0f + // optimize Sbox using AESE instruction + tbl v0.16b, {\dat}, MaskV.16b + MulMatrix v0.16b, TAHMatV.16b, TALMatV.16b, v24.16b + + eor v1.16b, v1.16b, v1.16b + aese v0.16b, v1.16b + + MulMatrix v0.16b, ATAHMatV.16b, ATALMatV.16b, v24.16b + + mov \dat, v0.16b + + // linear transformation + ushr v0.4s, \dat2,32-2 + ushr v1.4s, \dat2,32-10 + ushr v2.4s, \dat2,32-18 + ushr v3.4s, \dat2,32-24 + sli v0.4s, \dat2,2 + sli v1.4s, \dat2,10 + sli v2.4s, \dat2,18 + sli v3.4s, \dat2,24 + eor v24.16b, v0.16b, \dat + eor v24.16b, v24.16b, v1.16b + eor \dat, v2.16b, v3.16b + eor \dat, \dat, v24.16b +.endm + +# sm4 for 4-lanes of data, in neon registers data0/data1/data2/data3 +.macro Sm44blks kptr + ldp wtmp0, wtmp1,[\kptr],8 + dup rk0.4s, wtmp0 + dup rk1.4s, wtmp1 + + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor rka.16b, v6.16b, v7.16b + eor rk0.16b, v5.16b, rk0.16b + eor rk0.16b, rka.16b, rk0.16b + + Sbox rk0.16b, rk0.4s + + eor v4.16b, v4.16b, rk0.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor rka.16b, rka.16b, v4.16b + eor rk1.16b, rka.16b, rk1.16b + + Sbox rk1.16b, rk1.4s + + ldp wtmp0, wtmp1,[\kptr],8 + eor v5.16b,v5.16b, rk1.16b + + dup rk0.4s, wtmp0 + dup rk1.4s, wtmp1 + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor rka.16b, v4.16b, v5.16b + eor rk0.16b, v7.16b, rk0.16b + eor rk0.16b, rka.16b, rk0.16b + + Sbox rk0.16b, rk0.4s + + eor v6.16b, v6.16b, rk0.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor rka.16b, rka.16b, v6.16b + eor rk1.16b, rka.16b, rk1.16b + + Sbox rk1.16b, rk1.4s + + eor v7.16b, v7.16b, rk1.16b +.endm + + +.macro Encrypt4blks + mov ptr, rks + mov counter,#8 +10: + Sm44blks ptr + + subs counter, counter,#1 + b.ne 10b +#ifndef HITLS_BIG_ENDIAN + rev32 v3.16b,v4.16b + rev32 v2.16b,v5.16b + rev32 v1.16b,v6.16b + rev32 v0.16b,v7.16b +#else + mov v3.16b,v4.16b + mov v2.16b,v5.16b + mov v1.16b,v6.16b + mov v0.16b,v7.16b +#endif +.endm + +# Sbox operation for 8-lane of words +.macro SboxDouble dat datx + movi ANDMaskV.16b, #0x0f + // optimize Sbox using AESE instruction + tbl v0.16b, {rk0.16b}, MaskV.16b + tbl v1.16b, {rk1.16b}, MaskV.16b + + MulMatrix v0.16b, TAHMatV.16b, TALMatV.16b, v24.16b + MulMatrix v1.16b, TAHMatV.16b, TALMatV.16b, v24.16b + eor vtmp5.16b, vtmp5.16b, vtmp5.16b + aese v0.16b,vtmp5.16b + aese v1.16b,vtmp5.16b + MulMatrixOut v0.16b, ATAHMatV.16b, ATALMatV.16b, v24.16b, rk0.16b + MulMatrixOut v1.16b, ATAHMatV.16b, ATALMatV.16b, v24.16b, rk1.16b + + // linear transformation + ushr v0.4s,rk0.4s,32-2 + ushr vtmp5.4s,rk1.4s,32-2 + ushr v1.4s,rk0.4s,32-10 + ushr v2.4s,rk0.4s,32-18 + ushr v3.4s,rk0.4s,32-24 + sli v0.4s,rk0.4s,2 + sli vtmp5.4s,rk1.4s,2 + sli v1.4s,rk0.4s,10 + sli v2.4s,rk0.4s,18 + sli v3.4s,rk0.4s,24 + eor v24.16b,v0.16b,rk0.16b + eor v24.16b,v24.16b,v1.16b + eor rk0.16b,v2.16b,v3.16b + eor rk0.16b,rk0.16b,v24.16b + ushr v1.4s,rk1.4s,32-10 + ushr v2.4s,rk1.4s,32-18 + ushr v3.4s,rk1.4s,32-24 + sli v1.4s,rk1.4s,10 + sli v2.4s,rk1.4s,18 + sli v3.4s,rk1.4s,24 + eor v24.16b,vtmp5.16b,rk1.16b + eor v24.16b,v24.16b,v1.16b + eor rk1.16b,v2.16b,v3.16b + eor rk1.16b,rk1.16b,v24.16b +.endm + + +.macro SboxThree dat, datx, dat1 + movi ANDMaskV.16b, #0x0f + // optimize sbox using AESE instruction + tbl v0.16b, {\dat}, MaskV.16b + tbl v1.16b, {\datx}, MaskV.16b + tbl v2.16b, {\dat1}, MaskV.16b + eor v3.16b, v3.16b, v3.16b + + MulMatrix v0.16b, TAHMatV.16b, TALMatV.16b, v24.16b + MulMatrix v1.16b, TAHMatV.16b, TALMatV.16b, v24.16b + + aese v0.16b, v3.16b + + MulMatrix v2.16b, TAHMatV.16b, TALMatV.16b, v24.16b + + aese v1.16b, v3.16b + aese v2.16b, v3.16b + + MulMatrixOut v0.16b, ATAHMatV.16b, ATALMatV.16b, v24.16b, \dat + MulMatrixOut v1.16b, ATAHMatV.16b, ATALMatV.16b, v24.16b, \datx + MulMatrixOut v2.16b, ATAHMatV.16b, ATALMatV.16b, v24.16b, \dat1 + + // linear transformation + tbl v0.16b, {\dat}, vtmp5.16b // shitf left 8 + tbl v1.16b, {\datx}, vtmp5.16b + tbl v2.16b, {\dat1}, vtmp5.16b + + tbl v3.16b, {\dat}, v22.16b // shitf left 16 + tbl v24.16b, {\datx}, v22.16b + tbl ANDMaskV.16b, {\dat1}, v22.16b + + eor v0.16b, v0.16b, \dat + eor v1.16b, v1.16b, \datx + eor v2.16b, v2.16b, \dat1 + + eor v0.16b, v0.16b, v3.16b + eor v1.16b, v1.16b, v24.16b + eor v2.16b, v2.16b, ANDMaskV.16b + + shl v3.4s, v0.4s, #2 // shift left by 2 bits, equivalent to v12<<2 xor v12<<10 xor v12<<18 + sri v3.4s, v0.4s, #30 + shl v24.4s, v1.4s, #2 + sri v24.4s, v1.4s, #30 + shl ANDMaskV.4s, v2.4s, #2 + sri ANDMaskV.4s, v2.4s, #30 + + tbl v0.16b, {\dat}, v23.16b // shitf left 24 + tbl v1.16b, {\datx}, v23.16b + tbl v2.16b, {\dat1}, v23.16b + + eor \dat, \dat, v3.16b + eor \datx, \datx, v24.16b + eor \dat1, \dat1, ANDMaskV.16b + + eor \dat, v0.16b, \dat + eor \datx, v1.16b, \datx + eor \dat1, v2.16b, \dat1 +.endm + +.macro Sm48blks kptr + ldp wtmp0, wtmp1,[\kptr],8 + + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + dup rk0.4s, wtmp0 + eor rka.16b,v6.16b,v7.16b + eor rkb.16b,v10.16b,v11.16b + eor v0.16b,v5.16b,rk0.16b + eor v1.16b,v9.16b,rk0.16b + eor rk0.16b, rka.16b,v0.16b + eor rk1.16b, rkb.16b,v1.16b + SboxDouble + eor v4.16b, v4.16b, rk0.16b + eor v8.16b,v8.16b, rk1.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + dup rk1.4s, wtmp1 + eor rka.16b,rka.16b,v4.16b + eor rkb.16b,rkb.16b,v8.16b + eor rk0.16b,rka.16b,rk1.16b + eor rk1.16b,rkb.16b,rk1.16b + SboxDouble + + ldp wtmp0, wtmp1,[\kptr],8 + eor v5.16b,v5.16b,rk0.16b + eor v9.16b,v9.16b,rk1.16b + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + dup rk0.4s, wtmp0 + eor rka.16b,v4.16b,v5.16b + eor rkb.16b,v8.16b,v9.16b + eor v0.16b,v7.16b,rk0.16b + eor v1.16b,v11.16b,rk0.16b + eor rk0.16b,rka.16b,v0.16b + eor rk1.16b,rkb.16b,v1.16b + SboxDouble + + eor v6.16b,v6.16b,rk0.16b + eor v10.16b,v10.16b,rk1.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + dup rk1.4s, wtmp1 + eor rka.16b,rka.16b,v6.16b + eor rkb.16b,rkb.16b,v10.16b + eor rk0.16b,rka.16b,rk1.16b + eor rk1.16b,rkb.16b,rk1.16b + SboxDouble + + eor v7.16b,v7.16b,rk0.16b + eor v11.16b,v11.16b,rk1.16b +.endm + + +.macro Sm412blks kptr + ldp wtmp0,wtmp1,[\kptr],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + dup rk0.4s,wtmp0 + eor rka.16b,v6.16b,v7.16b + eor rkb.16b,v10.16b,v11.16b + eor rkc.16b,v18.16b,v19.16b + eor v0.16b,v5.16b,rk0.16b + eor v1.16b,v9.16b,rk0.16b + eor v2.16b,v17.16b,rk0.16b + eor rk0.16b,rka.16b,v0.16b + eor rk1.16b,rkb.16b,v1.16b + eor rk2.16b,rkc.16b,v2.16b + + SboxThree rk0.16b, rk1.16b, rk2.16b + + eor v4.16b,v4.16b,rk0.16b + eor v8.16b,v8.16b,rk1.16b + eor v16.16b,v16.16b,rk2.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + dup rk1.4s,wtmp1 + eor rka.16b,rka.16b,v4.16b + eor rkb.16b,rkb.16b,v8.16b + eor rkc.16b,rkc.16b,v16.16b + eor rk0.16b,rka.16b,rk1.16b + eor rk2.16b,rkc.16b,rk1.16b + eor rk1.16b,rkb.16b,rk1.16b + + SboxThree rk0.16b, rk1.16b, rk2.16b + + ldp wtmp0,wtmp1,[\kptr],8 + eor v5.16b,v5.16b,rk0.16b + eor v9.16b,v9.16b,rk1.16b + eor v17.16b,v17.16b,rk2.16b + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + dup rk0.4s,wtmp0 + eor rka.16b,v4.16b,v5.16b + eor rkb.16b,v8.16b,v9.16b + eor rkc.16b,v16.16b,v17.16b + eor v0.16b,v7.16b,rk0.16b + eor v1.16b,v11.16b,rk0.16b + eor v2.16b,v19.16b,rk0.16b + eor rk0.16b,rka.16b,v0.16b + eor rk1.16b,rkb.16b,v1.16b + eor rk2.16b,rkc.16b,v2.16b + + SboxThree rk0.16b, rk1.16b, rk2.16b + + eor v6.16b,v6.16b,rk0.16b + eor v10.16b,v10.16b,rk1.16b + eor v18.16b,v18.16b,rk2.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + dup rk1.4s,wtmp1 + eor rka.16b,rka.16b,v6.16b + eor rkb.16b,rkb.16b,v10.16b + eor rkc.16b,rkc.16b,v18.16b + eor rk0.16b,rka.16b,rk1.16b + eor rk2.16b,rkc.16b,rk1.16b + eor rk1.16b,rkb.16b,rk1.16b + + SboxThree rk0.16b, rk1.16b, rk2.16b + + eor v7.16b,v7.16b,rk0.16b + eor v11.16b,v11.16b,rk1.16b + eor v19.16b,v19.16b,rk2.16b +.endm + + +.macro Encrypt8blks + mov ptr, rks + mov counter, #8 +10: + Sm48blks ptr + + subs counter, counter,#1 + b.ne 10b +#ifndef HITLS_BIG_ENDIAN + rev32 v3.16b,v4.16b + rev32 v2.16b,v5.16b + rev32 v1.16b,v6.16b + rev32 v0.16b,v7.16b + rev32 v7.16b,v8.16b + rev32 v6.16b,v9.16b + rev32 v5.16b,v10.16b + rev32 v4.16b,v11.16b +#else + mov v3.16b,v4.16b + mov v2.16b,v5.16b + mov v1.16b,v6.16b + mov v0.16b,v7.16b + mov v7.16b,v8.16b + mov v6.16b,v9.16b + mov v5.16b,v10.16b + mov v4.16b,v11.16b +#endif +.endm + +.macro Encrypt12blks + mov ptr, rks + mov counter, #8 +10: + Sm412blks ptr + + subs counter,counter,#1 + b.ne 10b + // last reverse transform +#ifndef HITLS_BIG_ENDIAN + rev32 v3.16b,v4.16b + rev32 v2.16b,v5.16b + rev32 v1.16b,v6.16b + rev32 v0.16b,v7.16b + + rev32 v7.16b,v8.16b + rev32 v6.16b,v9.16b + rev32 v5.16b,v10.16b + rev32 v4.16b,v11.16b + + rev32 v11.16b,v16.16b + rev32 v10.16b,v17.16b + rev32 v9.16b,v18.16b + rev32 v8.16b,v19.16b +#else + mov v3.16b,v4.16b + mov v2.16b,v5.16b + mov v1.16b,v6.16b + mov v0.16b,v7.16b + + mov v7.16b,v8.16b + mov v6.16b,v9.16b + mov v5.16b,v10.16b + mov v4.16b,v11.16b + + mov v11.16b,v16.16b + mov v10.16b,v17.16b + mov v9.16b,v18.16b + mov v8.16b,v19.16b +#endif +.endm + +.type Sm4Enc4blks,%function +.align 4 +Sm4Enc4blks: + Encrypt4blks + ret +.size Sm4Enc4blks,.-Sm4Enc4blks + +.type Sm4Enc8blks,%function +.align 4 +Sm4Enc8blks: + Encrypt8blks + ret +.size Sm4Enc8blks,.-Sm4Enc8blks + +.type Sm4Enc12blks,%function +.align 4 +Sm4Enc12blks: + Encrypt12blks + ret +.size Sm4Enc12blks,.-Sm4Enc12blks + +.globl Vpsm4EcbEncrypt +.type Vpsm4EcbEncrypt,%function +.align 5 +Vpsm4EcbEncrypt: + // convert length into blocks + lsr x2,x2,4 + stp d8,d9,[sp,#-112]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] + stp x19,x20,[sp,#80] + stp x21,x22,[sp,#96] + LoadSbox + +.Lecb_12_blocks_process: + cmp blocks,#12 + b.lt .Lecb_8_blocks_process + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[inp],#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[inp],#64 + ld4 {v16.4s,v17.4s,v18.4s,v19.4s},[inp],#64 + +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + + rev32 v8.16b,v8.16b + rev32 v9.16b,v9.16b + rev32 v10.16b,v10.16b + rev32 v11.16b,v11.16b + + rev32 v16.16b,v16.16b + rev32 v17.16b,v17.16b + rev32 v18.16b,v18.16b + rev32 v19.16b,v19.16b +#endif + + bl Sm4Enc12blks + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + st4 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + st4 {v8.4s,v9.4s,v10.4s,v11.4s},[outp],#64 + subs blocks,blocks,#12 + b.gt .Lecb_12_blocks_process + b 100f + +.Lecb_8_blocks_process: + cmp blocks, #8 + b.lt .Lecb_4_blocks_process + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + rev32 v8.16b,v8.16b + rev32 v9.16b,v9.16b + rev32 v10.16b,v10.16b + rev32 v11.16b,v11.16b +#endif + bl Sm4Enc8blks + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st4 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs blocks,blocks,#8 + b.gt .Lecb_8_blocks_process + b 100f +.Lecb_4_blocks_process: + cmp blocks,#4 + b.lt 1f + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b, v4.16b + rev32 v5.16b, v5.16b + rev32 v6.16b, v6.16b + rev32 v7.16b, v7.16b +#endif + bl Sm4Enc4blks + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + sub blocks,blocks,#4 +1: + // process last block + cmp blocks,#1 + b.lt 100f + b.gt 1f + + adrp x19, .Ltbox1 + add x19,x19,:lo12:.Ltbox1 + adrp x20, .Ltbox2 + add x20,x20,:lo12:.Ltbox2 + adrp x21, .Ltbox3 + add x21,x21,:lo12:.Ltbox3 + adrp x22, .Ltbox4 + add x22,x22,:lo12:.Ltbox4 + + ldp w8,w9,[inp],#8 + ldp w10,w11,[inp],#8 +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + EncRound +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + stp w11,w10,[outp] + stp w9,w8,[outp,#8] + b 100f +1: // process last 2 blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[0],[inp],#16 + ld4 {v4.s,v5.s,v6.s,v7.s}[1],[inp],#16 + cmp blocks,#2 + b.gt 1f +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + st4 {v0.s,v1.s,v2.s,v3.s}[0],[outp],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[outp] + b 100f // +1: // process last 3 blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[2],[inp],#16 +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + st4 {v0.s,v1.s,v2.s,v3.s}[0],[outp],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[outp],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[2],[outp] +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp x19,x20,[sp,#80] + ldp x21,x22,[sp,#96] + ldp d8,d9,[sp],#112 + ret +.size Vpsm4EcbEncrypt,.-Vpsm4EcbEncrypt + + +.globl Vpsm4CbcEncrypt +.type Vpsm4CbcEncrypt,%function +.align 5 +Vpsm4CbcEncrypt: + lsr len,len,4 + stp x29,x30,[sp,#-48]! + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + + // load tbox + adrp x19, .Ltbox1 + add x19,x19,:lo12:.Ltbox1 + adrp x20, .Ltbox2 + add x20,x20,:lo12:.Ltbox2 + adrp x21, .Ltbox3 + add x21,x21,:lo12:.Ltbox3 + adrp x22, .Ltbox4 + add x22,x22,:lo12:.Ltbox4 + + cbz w5,.Ldec + + // load iv + ldp w8,w9,[ivp] + ldp w10,w11,[ivp,#8] +.Lcbc_1_block_enc: + subs blocks,blocks,#1 + b.lt 2f + ldp w6,w7,[inp],#8 + ldp w16,w17,[inp],#8 + eor w8,w8,w6 + eor w9,w9,w7 + eor w10,w10,w16 + eor w11,w11,w17 +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + EncRound +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + // reverse to store + mov w6,w8 + mov w8,w11 + mov w11,w6 + mov w7,w9 + mov w9,w10 + mov w10,w7 + + stp w8,w9,[outp],#8 + stp w10,w11,[outp],#8 + b .Lcbc_1_block_enc +2: + // save back IV + stp w8,w9,[ivp] + stp w10,w11,[ivp,#8] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x29,x30,[sp],#48 + ret + +.Ldec: + LoadSbox + // decryption mode starts + stp d8,d9,[sp,#-64]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + +.Lcbc_12_blocks_dec: + cmp w2,#12 + b.lt .Lcbc_8_blocks_dec + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0] + add x10,x0,#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[x10] + add x10,x10,#64 + ld4 {v16.4s,v17.4s,v18.4s,v19.4s},[x10] + +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + rev32 v8.16b,v8.16b + rev32 v9.16b,v9.16b + rev32 v10.16b,v10.16b + rev32 v11.16b,v11.16b + rev32 v16.16b,v16.16b + rev32 v17.16b,v17.16b + rev32 v18.16b,v18.16b + rev32 v19.16b,v19.16b +#endif + bl Sm4Enc12blks + // transpose to xor iv + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v16.4s,v17.4s,v18.4s,v19.4s,v16.2d,v17.2d,v18.2d,v19.2d + transpose v4.4s,v5.4s,v6.4s,v7.4s,v4.2d,v5.2d,v6.2d,v7.2d,v16.4s,v17.4s,v18.4s,v19.4s,v16.2d,v17.2d,v18.2d,v19.2d + transpose v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d,v16.4s,v17.4s,v18.4s,v19.4s,v16.2d,v17.2d,v18.2d,v19.2d + ld1 {ivec1.4s},[ivp] + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[inp],#64 + eor v0.16b,v0.16b,ivec1.16b + ld1 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v1.16b,v1.16b,v16.16b + eor v2.16b,v2.16b,v17.16b + eor v3.16b,v3.16b,v18.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + + eor v4.16b,v4.16b,v19.16b + eor v5.16b,v5.16b,v12.16b + eor v6.16b,v6.16b,v13.16b + eor v7.16b,v7.16b,v14.16b + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[inp],#64 + eor v8.16b,v8.16b,v15.16b + eor v9.16b,v9.16b,v16.16b + eor v10.16b,v10.16b,v17.16b + eor v11.16b,v11.16b,v18.16b + st1 {v8.4s,v9.4s,v10.4s,v11.4s},[outp],#64 + // save back iv + st1 {v19.4s}, [ivp] + + subs blocks,blocks,#12 + b.gt .Lcbc_12_blocks_dec + b 100f + +.Lcbc_8_blocks_dec: + cmp blocks,#8 + b.lt 1f + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[inp] + add ptr, inp, #64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[ptr] + +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + rev32 v8.16b,v8.16b + rev32 v9.16b,v9.16b + rev32 v10.16b,v10.16b + rev32 v11.16b,v11.16b +#endif + bl Sm4Enc8blks + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + transpose v4.4s,v5.4s,v6.4s,v7.4s,v4.2d,v5.2d,v6.2d,v7.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + ld1 {ivec1.4s},[ivp] + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[inp],#64 + // note ivec1 and v15 are resuing the same register + // care needs to be taken to avoid conflict + eor v0.16b,v0.16b,ivec1.16b + ld1 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v1.16b,v1.16b,v8.16b + eor v2.16b,v2.16b,v9.16b + eor v3.16b,v3.16b,v10.16b + // save back IV + st1 {v15.4s}, [ivp] + eor v4.16b,v4.16b,v11.16b + eor v5.16b,v5.16b,v12.16b + eor v6.16b,v6.16b,v13.16b + eor v7.16b,v7.16b,v14.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + subs blocks,blocks,#8 + b.gt .Lcbc_8_blocks_dec + b.eq 100f +1: + ld1 {ivec1.4s},[ivp] +.Lcbc_4_blocks_dec: + cmp blocks,#4 + b.lt 1f + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[inp] +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[inp],#64 + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + eor v0.16b,v0.16b,ivec1.16b + eor v1.16b,v1.16b,v4.16b + orr v15.16b,v7.16b,v7.16b + eor v2.16b,v2.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + // save back IV + st1 {v7.4s}, [ivp] + subs blocks,blocks,#4 + b.gt .Lcbc_4_blocks_dec + b 100f +1: // last block + subs blocks,blocks,#1 + b.lt 100f + b.gt 1f + // load iv + ldp w6,w7,[ivp] + ldp w16,w17,[ivp,#8] + + ldp w8,w9,[inp] + ldp w10,w11,[inp,#8] + // store back iv + stp w8,w9,[ivp] + stp w10,w11,[ivp,#8] +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + EncRound +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + eor w11,w11,w6 + eor w10,w10,w7 + eor w9,w9,w16 + eor w8,w8,w17 + stp w11,w10,[outp],#8 + stp w9,w8,[outp],#8 + b 100f +1: // last two blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[0], [inp] + add ptr,inp,#16 + ld4 {v4.s,v5.s,v6.s,v7.s}[1],[ptr],#16 + subs blocks,blocks,1 + b.gt 1f +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + ld1 {v4.4s,v5.4s},[inp],#32 + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + eor v0.16b,v0.16b,ivec1.16b + eor v1.16b,v1.16b,v4.16b + st1 {v0.4s,v1.4s},[outp],#32 + // save back IV + st1 {v5.4s}, [ivp] + b 100f +1: // last 3 blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[2],[ptr] +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + ld1 {v4.4s,v5.4s,v6.4s},[inp],#48 + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + eor v0.16b,v0.16b,ivec1.16b + eor v1.16b,v1.16b,v4.16b + eor v2.16b,v2.16b,v5.16b + st1 {v0.4s,v1.4s,v2.4s},[outp],#48 + // save back IV + st1 {v6.4s}, [ivp] +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp d8,d9,[sp],#64 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x29,x30,[sp],#48 + ret +.size Vpsm4CbcEncrypt,.-Vpsm4CbcEncrypt + + +# void Vpsm4Ctr32EncryptBlocks(const uint8_t *in, uint8_t *out, uint64_t blocks, const uint32_t *key, uint8_t *iv); +.globl Vpsm4Ctr32EncryptBlocks +.type Vpsm4Ctr32EncryptBlocks,%function +.align 5 +Vpsm4Ctr32EncryptBlocks: + ld1 {ivec.4s},[ivp] +#ifndef HITLS_BIG_ENDIAN + rev32 v3.16b,v3.16b +#endif + LoadSbox + cmp blocks,#1 + b.ne 1f + // fast processing for one single block without + // context saving overhead + stp x19,x20,[sp,#-32]! + stp x21,x22,[sp,#16] + adrp x19, .Ltbox1 + add x19,x19,:lo12:.Ltbox1 + adrp x20, .Ltbox2 + add x20,x20,:lo12:.Ltbox2 + adrp x21, .Ltbox3 + add x21,x21,:lo12:.Ltbox3 + adrp x22, .Ltbox4 + add x22,x22,:lo12:.Ltbox4 + + Encrypt1blkNorevCtr + + ld1 {v4.4s},[inp] + eor v4.16b,v4.16b,ivec.16b + st1 {v4.4s},[outp] + ldp x21,x22,[sp,#16] + ldp x19,x20,[sp],#32 + ldr ctr,[ivp,#12] +#ifndef HITLS_BIG_ENDIAN + rev ctr,ctr +#endif + add ctr,ctr,#1 +#ifndef HITLS_BIG_ENDIAN + rev ctr,ctr +#endif + str ctr,[ivp,#12] + ret +1: + stp d8,d9,[sp,#-112]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] + stp x19,x20,[sp,#80] + stp x21,x22,[sp,#96] + mov word0, ivec.s[0] + mov word1, ivec.s[1] + mov word2, ivec.s[2] + mov ctr, ivec.s[3] +.Lctr32_4_blocks_process: + cmp blocks,#4 + b.lt 1f + dup v4.4s,word0 + dup v5.4s,word1 + dup v6.4s,word2 + mov v7.s[0],w5 + add ctr,ctr,#1 + mov v7.s[1],ctr + add ctr,ctr,#1 + mov v7.s[2],ctr + add ctr,ctr,#1 + mov v7.s[3],ctr + add ctr,ctr,#1 + cmp blocks,#8 + b.ge .Lctr32_8_blocks_process + bl Sm4Enc4blks + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + subs blocks,blocks,#4 + b.ne .Lctr32_4_blocks_process + b 100f +.Lctr32_8_blocks_process: + dup v8.4s,word0 + dup v9.4s,word1 + dup v10.4s,word2 + mov v11.s[0],ctr + add ctr,ctr,#1 + mov v11.s[1],ctr + add ctr,ctr,#1 + mov v11.s[2],ctr + add ctr,ctr,#1 + mov v11.s[3],ctr + add ctr,ctr,#1 + cmp blocks,#12 + b.ge .Lctr32_12_blocks_process + bl Sm4Enc8blks + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[inp],#64 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + eor v4.16b,v4.16b,v8.16b + eor v5.16b,v5.16b,v9.16b + eor v6.16b,v6.16b,v10.16b + eor v7.16b,v7.16b,v11.16b + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + st4 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + subs blocks,blocks,#8 + b.ne .Lctr32_4_blocks_process + b 100f +.Lctr32_12_blocks_process: + dup v16.4s,word0 + dup v17.4s,word1 + dup v18.4s,word2 + mov v19.s[0],ctr + add ctr,ctr,#1 + mov v19.s[1],ctr + add ctr,ctr,#1 + mov v19.s[2],ctr + add ctr,ctr,#1 + mov v19.s[3],ctr + add ctr,ctr,#1 + bl Sm4Enc12blks + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[outp],#64 + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v4.16b,v4.16b,v12.16b + eor v5.16b,v5.16b,v13.16b + eor v6.16b,v6.16b,v14.16b + eor v7.16b,v7.16b,v15.16b + st4 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v8.16b,v8.16b,v12.16b + eor v9.16b,v9.16b,v13.16b + eor v10.16b,v10.16b,v14.16b + eor v11.16b,v11.16b,v15.16b + st4 {v8.4s,v9.4s,v10.4s,v11.4s},[outp],#64 + subs blocks,blocks,#12 + b.ne .Lctr32_4_blocks_process + b 100f + +1: // last block processing + subs blocks,blocks,#1 + b.lt 100f + b.gt 1f + mov ivec.s[0],word0 + mov ivec.s[1],word1 + mov ivec.s[2],word2 + mov ivec.s[3],ctr + add ctr,ctr,#1 + + adrp x19, .Ltbox1 + add x19,x19,:lo12:.Ltbox1 + adrp x20, .Ltbox2 + add x20,x20,:lo12:.Ltbox2 + adrp x21, .Ltbox3 + add x21,x21,:lo12:.Ltbox3 + adrp x22, .Ltbox4 + add x22,x22,:lo12:.Ltbox4 + + Encrypt1blkNorevCtr + + ld1 {v4.4s},[inp] + eor v4.16b,v4.16b,ivec.16b + st1 {v4.4s},[outp] + b 100f + +1: // last 2 blocks processing + + dup v4.4s,word0 + dup v5.4s,word1 + dup v6.4s,word2 + mov v7.s[0],ctr + add ctr,ctr,#1 + mov v7.s[1],ctr + subs blocks,blocks,#1 + b.ne 1f + add ctr,ctr,#1 + bl Sm4Enc4blks + ld4 {v12.s,v13.s,v14.s,v15.s}[0],[inp],#16 + ld4 {v12.s,v13.s,v14.s,v15.s}[1],[inp],#16 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.s,v1.s,v2.s,v3.s}[0],[outp],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[outp],#16 + b 100f + +1: // last 3 blocks processing + add ctr,ctr,#1 + mov v7.s[2],ctr + add ctr,ctr,#1 + bl Sm4Enc4blks + ld4 {v12.s,v13.s,v14.s,v15.s}[0],[inp],#16 + ld4 {v12.s,v13.s,v14.s,v15.s}[1],[inp],#16 + ld4 {v12.s,v13.s,v14.s,v15.s}[2],[inp],#16 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.s,v1.s,v2.s,v3.s}[0],[outp],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[outp],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[2],[outp],#16 +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp x19,x20,[sp,#80] + ldp x21,x22,[sp,#96] + ldp d8,d9,[sp],#112 +#ifndef HITLS_BIG_ENDIAN + rev ctr, ctr +#endif + str ctr, [ivp,#12] + ret +.size Vpsm4Ctr32EncryptBlocks,.-Vpsm4Ctr32EncryptBlocks + + +.globl Vpsm4Cfb128Encrypt +.type Vpsm4Cfb128Encrypt,%function +.align 5 +Vpsm4Cfb128Encrypt: + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x8,[sp,#48] + stp x16,x17,[sp,#64] + + // load tbox + adrp x19, .Ltbox1 + add x19,x19,:lo12:.Ltbox1 + adrp x20, .Ltbox2 + add x20,x20,:lo12:.Ltbox2 + adrp x21, .Ltbox3 + add x21,x21,:lo12:.Ltbox3 + adrp x22, .Ltbox4 + add x22,x22,:lo12:.Ltbox4 + + // load num + ldr w23,[x5] + cbz w23,.Lcfb128_enc_update +.Lcfb128_enc_init: + ldrb w7,[ivp,x23] + ldrb w8,[inp] + eor w7,w7,w8 + strb w7,[outp] + strb w7,[ivp,x23] + + add inp,inp,#1 + add outp,outp,#1 + add w23,w23,#1 + sub len,len,#1 + cmp w23,#16 + b.eq .Lcfb128_enc_init_final + cbz len,.Lcfb128_enc_ret + b .Lcfb128_enc_init +.Lcfb128_enc_init_final: + mov w23,#0 +.Lcfb128_enc_update: + cbz len,.Lcfb128_enc_ret + // load iv + ldp w8,w9,[ivp] + ldp w10,w11,[ivp,#8] +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + EncRound +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + // save back IV + stp w11,w10,[ivp] + stp w9,w8,[ivp,#8] + + cmp len,#16 + b.lt .Lcfb128_enc_final + // xor with plain + ldp w6,w7,[inp],#8 + ldp w16,w17,[inp],#8 + eor w11,w11,w6 + eor w10,w10,w7 + eor w9,w9,w16 + eor w8,w8,w17 + + stp w11,w10,[outp],#8 + stp w9,w8,[outp],#8 + // save back IV + stp w11,w10,[ivp] + stp w9,w8,[ivp,#8] + + sub len,len,#16 + b .Lcfb128_enc_update +.Lcfb128_enc_final: + ldrb w7,[ivp,x23] + ldrb w8,[inp] + eor w7,w7,w8 + strb w7,[outp] + strb w7,[ivp,x23] + + add inp,inp,#1 + add outp,outp,#1 + add w23,w23,#1 + subs len,len,#1 + b.ne .Lcfb128_enc_final +.Lcfb128_enc_ret: + // store num + str w23,[x5] + + // restore register + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x8,[sp,#48] + ldp x16,x17,[sp,#64] + ldp x29,x30,[sp],#80 + + ret +.size Vpsm4Cfb128Encrypt,.-Vpsm4Cfb128Encrypt + +# void Vpsm4Cfb128Decrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, int *num); +.globl Vpsm4Cfb128Decrypt +.type Vpsm4Cfb128Decrypt,%function +.align 5 +Vpsm4Cfb128Decrypt: + stp x29,x30,[sp,#-128]! + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp d8,d9,[sp,#64] + stp d10,d11,[sp,#80] + stp d12,d13,[sp,#96] + stp d14,d15,[sp,#112] + + // load tbox + adrp x19, .Ltbox1 + add x19,x19,:lo12:.Ltbox1 + adrp x20, .Ltbox2 + add x20,x20,:lo12:.Ltbox2 + adrp x21, .Ltbox3 + add x21,x21,:lo12:.Ltbox3 + adrp x22, .Ltbox4 + add x22,x22,:lo12:.Ltbox4 + LoadSbox +// load num + ldr w23,[x5] + cbz w23,.Lcfb128_12_blocks_dec + +.Lcfb128_dec_init: + ldrb w7,[ivp,x23] + ldrb w8,[inp] + eor w7,w7,w8 + strb w7,[outp] + // store in to iv + strb w8,[ivp,x23] + + add inp,inp,#1 + add outp,outp,#1 + subs len,len,#1 + add w23,w23,#1 + and w23,w23,#15 + b.eq 100f + cbz w23,.Lcfb128_12_blocks_dec + b .Lcfb128_dec_init + +.Lcfb128_12_blocks_dec: + cmp len,#192 + b.lt .Lcfb128_8_blocks_dec + + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[inp] + // append iv as last element + ld4 {v4.s,v5.s,v6.s,v7.s}[3],[ivp] + add ptr,inp,#48 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[ptr] + add ptr,ptr,#64 + ld4 {v16.4s,v17.4s,v18.4s,v19.4s},[ptr] +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + + rev32 v8.16b,v8.16b + rev32 v9.16b,v9.16b + rev32 v10.16b,v10.16b + rev32 v11.16b,v11.16b + + rev32 v16.16b,v16.16b + rev32 v17.16b,v17.16b + rev32 v18.16b,v18.16b + rev32 v19.16b,v19.16b +#endif + bl Sm4Enc12blks + + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v16.4s,v17.4s,v18.4s,v19.4s,v16.2d,v17.2d,v18.2d,v19.2d + transpose v4.4s,v5.4s,v6.4s,v7.4s,v4.2d,v5.2d,v6.2d,v7.2d,v16.4s,v17.4s,v18.4s,v19.4s,v16.2d,v17.2d,v18.2d,v19.2d + transpose v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d,v16.4s,v17.4s,v18.4s,v19.4s,v16.2d,v17.2d,v18.2d,v19.2d + + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[inp],#64 + ld1 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v0.16b,v0.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + eor v2.16b,v2.16b,v19.16b + eor v3.16b,v3.16b,v16.16b + // save plainText decrypted from iv as first one + st1 {v3.4s},[outp],#16 + st1 {v0.4s,v1.4s,v2.4s},[outp],#48 + + eor v4.16b,v4.16b,v12.16b + eor v5.16b,v5.16b,v13.16b + eor v6.16b,v6.16b,v14.16b + eor v7.16b,v7.16b,v15.16b + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[inp],#64 + eor v8.16b,v8.16b,v16.16b + eor v9.16b,v9.16b,v17.16b + eor v10.16b,v10.16b,v18.16b + eor v11.16b,v11.16b,v19.16b + st1 {v8.4s,v9.4s,v10.4s,v11.4s},[outp],#64 + // save back IV + st1 {v19.4s}, [ivp] + + subs len,len,#192 + b.gt .Lcfb128_12_blocks_dec + b.eq 100f + +.Lcfb128_8_blocks_dec: + cmp len,#128 + b.lt .Lcfb128_4_blocks_dec + + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[inp] + // append iv as last element + ld4 {v4.s,v5.s,v6.s,v7.s}[3],[ivp] + add ptr,inp,#48 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[ptr] +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + rev32 v8.16b,v8.16b + rev32 v9.16b,v9.16b + rev32 v10.16b,v10.16b + rev32 v11.16b,v11.16b +#endif + bl Sm4Enc8blks + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + transpose v4.4s,v5.4s,v6.4s,v7.4s,v4.2d,v5.2d,v6.2d,v7.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[inp],#64 + ld1 {v12.4s,v13.4s,v14.4s,v15.4s},[inp],#64 + eor v0.16b,v0.16b,v9.16b + eor v1.16b,v1.16b,v10.16b + eor v2.16b,v2.16b,v11.16b + eor v3.16b,v3.16b,v8.16b + // save back IV + st1 {v15.4s}, [ivp] + eor v4.16b,v4.16b,v12.16b + eor v5.16b,v5.16b,v13.16b + eor v6.16b,v6.16b,v14.16b + eor v7.16b,v7.16b,v15.16b + st1 {v3.4s},[outp],#16 + st1 {v0.4s,v1.4s,v2.4s},[outp],#48 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[outp],#64 + subs len,len,#128 + b.gt .Lcfb128_8_blocks_dec + b.eq 100f +.Lcfb128_4_blocks_dec: + cmp len,#64 + b.lt .Llast_block + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[inp] + // append iv as last element + ld4 {v4.s,v5.s,v6.s,v7.s}[3],[ivp] +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[inp],#64 + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + eor v0.16b,v0.16b,v5.16b + eor v1.16b,v1.16b,v6.16b + eor v2.16b,v2.16b,v7.16b + eor v3.16b,v3.16b,v4.16b + st1 {v3.4s},[outp],#16 + st1 {v0.4s,v1.4s,v2.4s},[outp],#48 + // save back IV + st1 {v7.4s}, [ivp] + subs len,len,#64 + b.gt .Lcfb128_4_blocks_dec + b.eq 100f + +.Llast_block: // last block + cmp len,#16 + b.gt .Llast_2_blocks +1: + // load in + ldp w6,w7,[inp] + ldp w16,w17,[inp,#8] + // load iv + ldp w8,w9,[ivp] + ldp w10,w11,[ivp,#8] +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + EncRound +#ifndef HITLS_BIG_ENDIAN + rev w8,w8 + rev w9,w9 + rev w10,w10 + rev w11,w11 +#endif + // save encrypted iv + stp w11,w10,[ivp] + stp w9,w8,[ivp,#8] + + cmp len,#16 + b.lt .Lcfb128_dec_final + + stp w6,w7,[ivp] + stp w16,w17,[ivp,#8] + eor w11,w11,w6 + eor w10,w10,w7 + eor w9,w9,w16 + eor w8,w8,w17 + stp w11,w10,[outp],#8 + stp w9,w8,[outp],#8 + add inp,inp,#16 + subs len,len,#16 + b.gt 1b + b.eq 100f + b .Lcfb128_dec_final +.Llast_2_blocks: // last two blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[0],[ivp] + mov ptr,inp + ld4 {v4.s,v5.s,v6.s,v7.s}[1],[ptr],#16 + + cmp x2,#32 + b.gt .Llast_3_blocks + b.lt 1b +1: +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + ld1 {v4.4s,v5.4s},[inp],#32 + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + eor v0.16b,v0.16b,v4.16b + eor v1.16b,v1.16b,v5.16b + st1 {v0.4s,v1.4s},[outp],#32 + // save back IV + st1 {v5.4s}, [ivp] + subs len,len,#32 + b.eq 100f + b .Llast_block +.Llast_3_blocks: // last 3 blocks + cmp len,#48 + b.lt 1b + ld4 {v4.s,v5.s,v6.s,v7.s}[2],[ptr] +#ifndef HITLS_BIG_ENDIAN + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b +#endif + bl Sm4Enc4blks + ld1 {v4.4s,v5.4s,v6.4s},[inp],#48 + transpose v0.4s,v1.4s,v2.4s,v3.4s,v0.2d,v1.2d,v2.2d,v3.2d,v8.4s,v9.4s,v10.4s,v11.4s,v8.2d,v9.2d,v10.2d,v11.2d + eor v0.16b,v0.16b,v4.16b + eor v1.16b,v1.16b,v5.16b + eor v2.16b,v2.16b,v6.16b + st1 {v0.4s,v1.4s,v2.4s},[outp],#48 + // save back IV + st1 {v6.4s}, [ivp] + subs len,len,#48 + b.eq 100f + b .Llast_block +.Lcfb128_dec_final: + ldrb w7,[ivp,x23] + ldrb w8,[inp] + eor w7,w7,w8 + strb w7,[outp] + // store in to iv + strb w8,[ivp,x23] + + add inp,inp,#1 + add outp,outp,#1 + add w23,w23,#1 + subs len,len,#1 + b.ne .Lcfb128_dec_final +100: + // store num + str w23,[x5] + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp d8,d9,[sp,#64] + ldp d10,d11,[sp,#80] + ldp d12,d13,[sp,#96] + ldp d14,d15,[sp,#112] + ldp x29,x30,[sp],#128 + + ret +.size Vpsm4Cfb128Decrypt,.-Vpsm4Cfb128Decrypt + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_macro_x86_64.s b/crypto/sm4/src/asm/crypt_sm4_macro_x86_64.s new file mode 100644 index 00000000..24077b4d --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_macro_x86_64.s @@ -0,0 +1,227 @@ +/* + * 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_SM4 + +.file "crypt_sm4_macro_x86_64.s" + +.macro MUL_MATRIX A0 HI_MASK LO_MASK + vpsrlw $4,\A0,%ymm5 + vpand %ymm14,\A0,%ymm6 + vpand %ymm14,%ymm5,%ymm5 + vpshufb %ymm6,\LO_MASK,%ymm6 + vpshufb %ymm5,\HI_MASK,%ymm5 + vpxor %ymm6,%ymm5,\A0 +.endm + +.macro SM4_MM256_AESENCLAST A0 + vextractf128 $0,\A0,%xmm5 + vextractf128 $1,\A0,%xmm6 + vpxor %xmm12,%xmm12,%xmm12 + + vaesenclast %xmm12,%xmm5,%xmm5 + vaesenclast %xmm12,%xmm6,%xmm6 + + subq $16, %rsp + vmovdqu %xmm5, (%rsp) + vbroadcasti128 (%rsp), %ymm5 + vinsertf128 $1,%xmm6,%ymm5,\A0 + addq $16, %rsp +.endm + +.macro SM4_MM256_ROL A0 A1 Imm1 Imm2 + vpslld \Imm1,\A1,%ymm5 + vpsrld \Imm2,\A1,%ymm6 + vpxor %ymm5,%ymm6,%ymm12 + vpxor %ymm12,\A0,\A0 +.endm + +# need to load aes_mask and andmask prewards +.macro SM4_AVX2_AES_2_ROUND A0 A1 A2 A3 B0 B1 B2 B3 RKey No + vpbroadcastd \No(\RKey),%ymm4 + vmovdqa %ymm4,%ymm11 + + vpxor \A1,%ymm4,%ymm4 + vpxor \A2,%ymm4,%ymm4 + vpxor \A3,%ymm4,%ymm4 + vpxor \B1,%ymm11,%ymm11 + vpxor \B2,%ymm11,%ymm11 + vpxor \B3,%ymm11,%ymm11 + + vpshufb %ymm15,%ymm4,%ymm4 + vpshufb %ymm15,%ymm11,%ymm11 + + vmovdqa 160+4096(%rax), %ymm12 + vmovdqa 224+4096(%rax), %ymm13 + + MUL_MATRIX %ymm4 %ymm12 %ymm13 + MUL_MATRIX %ymm11 %ymm12 %ymm13 + + vmovdqa 320+4096(%rax), %ymm12 + vpxor %ymm12,%ymm4,%ymm4 + vpxor %ymm12,%ymm11,%ymm11 + + SM4_MM256_AESENCLAST %ymm4 + SM4_MM256_AESENCLAST %ymm11 + + vmovdqa 192+4096(%rax), %ymm12 + vmovdqa 256+4096(%rax), %ymm13 + MUL_MATRIX %ymm4 %ymm12 %ymm13 + MUL_MATRIX %ymm11 %ymm12 %ymm13 + + vmovdqa 352+4096(%rax), %ymm12 + vpxor %ymm12,%ymm4,%ymm4 + vpxor %ymm12,%ymm11,%ymm11 + + vpxor \A0,%ymm4,\A0 + SM4_MM256_ROL \A0 %ymm4 $2 $30 + SM4_MM256_ROL \A0 %ymm4 $10 $22 + SM4_MM256_ROL \A0 %ymm4 $18 $14 + SM4_MM256_ROL \A0 %ymm4 $24 $8 + + vpxor \B0,%ymm11,\B0 + SM4_MM256_ROL \B0 %ymm11 $2 $30 + SM4_MM256_ROL \B0 %ymm11 $10 $22 + SM4_MM256_ROL \B0 %ymm11 $18 $14 + SM4_MM256_ROL \B0 %ymm11 $24 $8 + +.endm + +##### SBOX Extend Tables (1 Table, 256*4 bytes): SBOX_0, SBOX_1, SBOX_2, SBOX_3 ##### +##### MASK: XOR SHUFFLE LOAD STORE ##### + +.section .rodata +.align 64 + +SBOX4X_MASK: +#SBOX_0: +.long 0xd55b5b8e, 0x924242d0, 0xeaa7a74d, 0xfdfbfb06, 0xcf3333fc, 0xe2878765, 0x3df4f4c9, 0xb5dede6b, 0x1658584e, 0xb4dada6e, 0x14505044, 0xc10b0bca, 0x28a0a088, 0xf8efef17, 0x2cb0b09c, 0x5141411 +.long 0x2bacac87, 0x669d9dfb, 0x986a6af2, 0x77d9d9ae, 0x2aa8a882, 0xbcfafa46, 0x4101014, 0xc00f0fcf, 0xa8aaaa02, 0x45111154, 0x134c4c5f, 0x269898be, 0x4825256d, 0x841a1a9e, 0x618181e, 0x9b6666fd +.long 0x9e7272ec, 0x4309094a, 0x51414110, 0xf7d3d324, 0x934646d5, 0xecbfbf53, 0x9a6262f8, 0x7be9e992, 0x33ccccff, 0x55515104, 0xb2c2c27, 0x420d0d4f, 0xeeb7b759, 0xcc3f3ff3, 0xaeb2b21c, 0x638989ea +.long 0xe7939374, 0xb1cece7f, 0x1c70706c, 0xaba6a60d, 0xca2727ed, 0x8202028, 0xeba3a348, 0x975656c1, 0x82020280, 0xdc7f7fa3, 0x965252c4, 0xf9ebeb12, 0x74d5d5a1, 0x8d3e3eb3, 0x3ffcfcc3, 0xa49a9a3e +.long 0x461d1d5b, 0x71c1c1b, 0xa59e9e3b, 0xfff3f30c, 0xf0cfcf3f, 0x72cdcdbf, 0x175c5c4b, 0xb8eaea52, 0x810e0e8f, 0x5865653d, 0x3cf0f0cc, 0x1964647d, 0xe59b9b7e, 0x87161691, 0x4e3d3d73, 0xaaa2a208 +.long 0x69a1a1c8, 0x6aadadc7, 0x83060685, 0xb0caca7a, 0x70c5c5b5, 0x659191f4, 0xd96b6bb2, 0x892e2ea7, 0xfbe3e318, 0xe8afaf47, 0xf3c3c33, 0x4a2d2d67, 0x71c1c1b0, 0x5759590e, 0x9f7676e9, 0x35d4d4e1 +.long 0x1e787866, 0x249090b4, 0xe383836, 0x5f797926, 0x628d8def, 0x59616138, 0xd2474795, 0xa08a8a2a, 0x259494b1, 0x228888aa, 0x7df1f18c, 0x3bececd7, 0x1040405, 0x218484a5, 0x79e1e198, 0x851e1e9b +.long 0xd7535384, 0x0, 0x4719195e, 0x565d5d0b, 0x9d7e7ee3, 0xd04f4f9f, 0x279c9cbb, 0x5349491a, 0x4d31317c, 0x36d8d8ee, 0x208080a, 0xe49f9f7b, 0xa2828220, 0xc71313d4, 0xcb2323e8, 0x9c7a7ae6 +.long 0xe9abab42, 0xbdfefe43, 0x882a2aa2, 0xd14b4b9a, 0x41010140, 0xc41f1fdb, 0x38e0e0d8, 0xb7d6d661, 0xa18e8e2f, 0xf4dfdf2b, 0xf1cbcb3a, 0xcd3b3bf6, 0xfae7e71d, 0x608585e5, 0x15545441, 0xa3868625 +.long 0xe3838360, 0xacbaba16, 0x5c757529, 0xa6929234, 0x996e6ef7, 0x34d0d0e4, 0x1a686872, 0x54555501, 0xafb6b619, 0x914e4edf, 0x32c8c8fa, 0x30c0c0f0, 0xf6d7d721, 0x8e3232bc, 0xb3c6c675, 0xe08f8f6f +.long 0x1d747469, 0xf5dbdb2e, 0xe18b8b6a, 0x2eb8b896, 0x800a0a8a, 0x679999fe, 0xc92b2be2, 0x618181e0, 0xc30303c0, 0x29a4a48d, 0x238c8caf, 0xa9aeae07, 0xd343439, 0x524d4d1f, 0x4f393976, 0x6ebdbdd3 +.long 0xd6575781, 0xd86f6fb7, 0x37dcdceb, 0x44151551, 0xdd7b7ba6, 0xfef7f709, 0x8c3a3ab6, 0x2fbcbc93, 0x30c0c0f, 0xfcffff03, 0x6ba9a9c2, 0x73c9c9ba, 0x6cb5b5d9, 0x6db1b1dc, 0x5a6d6d37, 0x50454515 +.long 0x8f3636b9, 0x1b6c6c77, 0xadbebe13, 0x904a4ada, 0xb9eeee57, 0xde7777a9, 0xbef2f24c, 0x7efdfd83, 0x11444455, 0xda6767bd, 0x5d71712c, 0x40050545, 0x1f7c7c63, 0x10404050, 0x5b696932, 0xdb6363b8 +.long 0xa282822, 0xc20707c5, 0x31c4c4f5, 0x8a2222a8, 0xa7969631, 0xce3737f9, 0x7aeded97, 0xbff6f649, 0x2db4b499, 0x75d1d1a4, 0xd3434390, 0x1248485a, 0xbae2e258, 0xe6979771, 0xb6d2d264, 0xb2c2c270 +.long 0x8b2626ad, 0x68a5a5cd, 0x955e5ecb, 0x4b292962, 0xc30303c, 0x945a5ace, 0x76ddddab, 0x7ff9f986, 0x649595f1, 0xbbe6e65d, 0xf2c7c735, 0x924242d, 0xc61717d1, 0x6fb9b9d6, 0xc51b1bde, 0x86121294 +.long 0x18606078, 0xf3c3c330, 0x7cf5f589, 0xefb3b35c, 0x3ae8e8d2, 0xdf7373ac, 0x4c353579, 0x208080a0, 0x78e5e59d, 0xedbbbb56, 0x5e7d7d23, 0x3ef8f8c6, 0xd45f5f8b, 0xc82f2fe7, 0x39e4e4dd, 0x49212168 + +#SBOX_1: +.long 0x5b5b8ed5, 0x4242d092, 0xa7a74dea, 0xfbfb06fd, 0x3333fccf, 0x878765e2, 0xf4f4c93d, 0xdede6bb5, 0x58584e16, 0xdada6eb4, 0x50504414, 0xb0bcac1, 0xa0a08828, 0xefef17f8, 0xb0b09c2c, 0x14141105 +.long 0xacac872b, 0x9d9dfb66, 0x6a6af298, 0xd9d9ae77, 0xa8a8822a, 0xfafa46bc, 0x10101404, 0xf0fcfc0, 0xaaaa02a8, 0x11115445, 0x4c4c5f13, 0x9898be26, 0x25256d48, 0x1a1a9e84, 0x18181e06, 0x6666fd9b +.long 0x7272ec9e, 0x9094a43, 0x41411051, 0xd3d324f7, 0x4646d593, 0xbfbf53ec, 0x6262f89a, 0xe9e9927b, 0xccccff33, 0x51510455, 0x2c2c270b, 0xd0d4f42, 0xb7b759ee, 0x3f3ff3cc, 0xb2b21cae, 0x8989ea63 +.long 0x939374e7, 0xcece7fb1, 0x70706c1c, 0xa6a60dab, 0x2727edca, 0x20202808, 0xa3a348eb, 0x5656c197, 0x2028082, 0x7f7fa3dc, 0x5252c496, 0xebeb12f9, 0xd5d5a174, 0x3e3eb38d, 0xfcfcc33f, 0x9a9a3ea4 +.long 0x1d1d5b46, 0x1c1c1b07, 0x9e9e3ba5, 0xf3f30cff, 0xcfcf3ff0, 0xcdcdbf72, 0x5c5c4b17, 0xeaea52b8, 0xe0e8f81, 0x65653d58, 0xf0f0cc3c, 0x64647d19, 0x9b9b7ee5, 0x16169187, 0x3d3d734e, 0xa2a208aa +.long 0xa1a1c869, 0xadadc76a, 0x6068583, 0xcaca7ab0, 0xc5c5b570, 0x9191f465, 0x6b6bb2d9, 0x2e2ea789, 0xe3e318fb, 0xafaf47e8, 0x3c3c330f, 0x2d2d674a, 0xc1c1b071, 0x59590e57, 0x7676e99f, 0xd4d4e135 +.long 0x7878661e, 0x9090b424, 0x3838360e, 0x7979265f, 0x8d8def62, 0x61613859, 0x474795d2, 0x8a8a2aa0, 0x9494b125, 0x8888aa22, 0xf1f18c7d, 0xececd73b, 0x4040501, 0x8484a521, 0xe1e19879, 0x1e1e9b85 +.long 0x535384d7, 0x0, 0x19195e47, 0x5d5d0b56, 0x7e7ee39d, 0x4f4f9fd0, 0x9c9cbb27, 0x49491a53, 0x31317c4d, 0xd8d8ee36, 0x8080a02, 0x9f9f7be4, 0x828220a2, 0x1313d4c7, 0x2323e8cb, 0x7a7ae69c +.long 0xabab42e9, 0xfefe43bd, 0x2a2aa288, 0x4b4b9ad1, 0x1014041, 0x1f1fdbc4, 0xe0e0d838, 0xd6d661b7, 0x8e8e2fa1, 0xdfdf2bf4, 0xcbcb3af1, 0x3b3bf6cd, 0xe7e71dfa, 0x8585e560, 0x54544115, 0x868625a3 +.long 0x838360e3, 0xbaba16ac, 0x7575295c, 0x929234a6, 0x6e6ef799, 0xd0d0e434, 0x6868721a, 0x55550154, 0xb6b619af, 0x4e4edf91, 0xc8c8fa32, 0xc0c0f030, 0xd7d721f6, 0x3232bc8e, 0xc6c675b3, 0x8f8f6fe0 +.long 0x7474691d, 0xdbdb2ef5, 0x8b8b6ae1, 0xb8b8962e, 0xa0a8a80, 0x9999fe67, 0x2b2be2c9, 0x8181e061, 0x303c0c3, 0xa4a48d29, 0x8c8caf23, 0xaeae07a9, 0x3434390d, 0x4d4d1f52, 0x3939764f, 0xbdbdd36e +.long 0x575781d6, 0x6f6fb7d8, 0xdcdceb37, 0x15155144, 0x7b7ba6dd, 0xf7f709fe, 0x3a3ab68c, 0xbcbc932f, 0xc0c0f03, 0xffff03fc, 0xa9a9c26b, 0xc9c9ba73, 0xb5b5d96c, 0xb1b1dc6d, 0x6d6d375a, 0x45451550 +.long 0x3636b98f, 0x6c6c771b, 0xbebe13ad, 0x4a4ada90, 0xeeee57b9, 0x7777a9de, 0xf2f24cbe, 0xfdfd837e, 0x44445511, 0x6767bdda, 0x71712c5d, 0x5054540, 0x7c7c631f, 0x40405010, 0x6969325b, 0x6363b8db +.long 0x2828220a, 0x707c5c2, 0xc4c4f531, 0x2222a88a, 0x969631a7, 0x3737f9ce, 0xeded977a, 0xf6f649bf, 0xb4b4992d, 0xd1d1a475, 0x434390d3, 0x48485a12, 0xe2e258ba, 0x979771e6, 0xd2d264b6, 0xc2c270b2 +.long 0x2626ad8b, 0xa5a5cd68, 0x5e5ecb95, 0x2929624b, 0x30303c0c, 0x5a5ace94, 0xddddab76, 0xf9f9867f, 0x9595f164, 0xe6e65dbb, 0xc7c735f2, 0x24242d09, 0x1717d1c6, 0xb9b9d66f, 0x1b1bdec5, 0x12129486 +.long 0x60607818, 0xc3c330f3, 0xf5f5897c, 0xb3b35cef, 0xe8e8d23a, 0x7373acdf, 0x3535794c, 0x8080a020, 0xe5e59d78, 0xbbbb56ed, 0x7d7d235e, 0xf8f8c63e, 0x5f5f8bd4, 0x2f2fe7c8, 0xe4e4dd39, 0x21216849 + +#SBOX_2: +.long 0x5b8ed55b, 0x42d09242, 0xa74deaa7, 0xfb06fdfb, 0x33fccf33, 0x8765e287, 0xf4c93df4, 0xde6bb5de, 0x584e1658, 0xda6eb4da, 0x50441450, 0xbcac10b, 0xa08828a0, 0xef17f8ef, 0xb09c2cb0, 0x14110514 +.long 0xac872bac, 0x9dfb669d, 0x6af2986a, 0xd9ae77d9, 0xa8822aa8, 0xfa46bcfa, 0x10140410, 0xfcfc00f, 0xaa02a8aa, 0x11544511, 0x4c5f134c, 0x98be2698, 0x256d4825, 0x1a9e841a, 0x181e0618, 0x66fd9b66 +.long 0x72ec9e72, 0x94a4309, 0x41105141, 0xd324f7d3, 0x46d59346, 0xbf53ecbf, 0x62f89a62, 0xe9927be9, 0xccff33cc, 0x51045551, 0x2c270b2c, 0xd4f420d, 0xb759eeb7, 0x3ff3cc3f, 0xb21caeb2, 0x89ea6389 +.long 0x9374e793, 0xce7fb1ce, 0x706c1c70, 0xa60daba6, 0x27edca27, 0x20280820, 0xa348eba3, 0x56c19756, 0x2808202, 0x7fa3dc7f, 0x52c49652, 0xeb12f9eb, 0xd5a174d5, 0x3eb38d3e, 0xfcc33ffc, 0x9a3ea49a +.long 0x1d5b461d, 0x1c1b071c, 0x9e3ba59e, 0xf30cfff3, 0xcf3ff0cf, 0xcdbf72cd, 0x5c4b175c, 0xea52b8ea, 0xe8f810e, 0x653d5865, 0xf0cc3cf0, 0x647d1964, 0x9b7ee59b, 0x16918716, 0x3d734e3d, 0xa208aaa2 +.long 0xa1c869a1, 0xadc76aad, 0x6858306, 0xca7ab0ca, 0xc5b570c5, 0x91f46591, 0x6bb2d96b, 0x2ea7892e, 0xe318fbe3, 0xaf47e8af, 0x3c330f3c, 0x2d674a2d, 0xc1b071c1, 0x590e5759, 0x76e99f76, 0xd4e135d4 +.long 0x78661e78, 0x90b42490, 0x38360e38, 0x79265f79, 0x8def628d, 0x61385961, 0x4795d247, 0x8a2aa08a, 0x94b12594, 0x88aa2288, 0xf18c7df1, 0xecd73bec, 0x4050104, 0x84a52184, 0xe19879e1, 0x1e9b851e +.long 0x5384d753, 0x0, 0x195e4719, 0x5d0b565d, 0x7ee39d7e, 0x4f9fd04f, 0x9cbb279c, 0x491a5349, 0x317c4d31, 0xd8ee36d8, 0x80a0208, 0x9f7be49f, 0x8220a282, 0x13d4c713, 0x23e8cb23, 0x7ae69c7a +.long 0xab42e9ab, 0xfe43bdfe, 0x2aa2882a, 0x4b9ad14b, 0x1404101, 0x1fdbc41f, 0xe0d838e0, 0xd661b7d6, 0x8e2fa18e, 0xdf2bf4df, 0xcb3af1cb, 0x3bf6cd3b, 0xe71dfae7, 0x85e56085, 0x54411554, 0x8625a386 +.long 0x8360e383, 0xba16acba, 0x75295c75, 0x9234a692, 0x6ef7996e, 0xd0e434d0, 0x68721a68, 0x55015455, 0xb619afb6, 0x4edf914e, 0xc8fa32c8, 0xc0f030c0, 0xd721f6d7, 0x32bc8e32, 0xc675b3c6, 0x8f6fe08f +.long 0x74691d74, 0xdb2ef5db, 0x8b6ae18b, 0xb8962eb8, 0xa8a800a, 0x99fe6799, 0x2be2c92b, 0x81e06181, 0x3c0c303, 0xa48d29a4, 0x8caf238c, 0xae07a9ae, 0x34390d34, 0x4d1f524d, 0x39764f39, 0xbdd36ebd +.long 0x5781d657, 0x6fb7d86f, 0xdceb37dc, 0x15514415, 0x7ba6dd7b, 0xf709fef7, 0x3ab68c3a, 0xbc932fbc, 0xc0f030c, 0xff03fcff, 0xa9c26ba9, 0xc9ba73c9, 0xb5d96cb5, 0xb1dc6db1, 0x6d375a6d, 0x45155045 +.long 0x36b98f36, 0x6c771b6c, 0xbe13adbe, 0x4ada904a, 0xee57b9ee, 0x77a9de77, 0xf24cbef2, 0xfd837efd, 0x44551144, 0x67bdda67, 0x712c5d71, 0x5454005, 0x7c631f7c, 0x40501040, 0x69325b69, 0x63b8db63 +.long 0x28220a28, 0x7c5c207, 0xc4f531c4, 0x22a88a22, 0x9631a796, 0x37f9ce37, 0xed977aed, 0xf649bff6, 0xb4992db4, 0xd1a475d1, 0x4390d343, 0x485a1248, 0xe258bae2, 0x9771e697, 0xd264b6d2, 0xc270b2c2 +.long 0x26ad8b26, 0xa5cd68a5, 0x5ecb955e, 0x29624b29, 0x303c0c30, 0x5ace945a, 0xddab76dd, 0xf9867ff9, 0x95f16495, 0xe65dbbe6, 0xc735f2c7, 0x242d0924, 0x17d1c617, 0xb9d66fb9, 0x1bdec51b, 0x12948612 +.long 0x60781860, 0xc330f3c3, 0xf5897cf5, 0xb35cefb3, 0xe8d23ae8, 0x73acdf73, 0x35794c35, 0x80a02080, 0xe59d78e5, 0xbb56edbb, 0x7d235e7d, 0xf8c63ef8, 0x5f8bd45f, 0x2fe7c82f, 0xe4dd39e4, 0x21684921 + +#SBOX_3: +.long 0x8ed55b5b, 0xd0924242, 0x4deaa7a7, 0x6fdfbfb, 0xfccf3333, 0x65e28787, 0xc93df4f4, 0x6bb5dede, 0x4e165858, 0x6eb4dada, 0x44145050, 0xcac10b0b, 0x8828a0a0, 0x17f8efef, 0x9c2cb0b0, 0x11051414 +.long 0x872bacac, 0xfb669d9d, 0xf2986a6a, 0xae77d9d9, 0x822aa8a8, 0x46bcfafa, 0x14041010, 0xcfc00f0f, 0x2a8aaaa, 0x54451111, 0x5f134c4c, 0xbe269898, 0x6d482525, 0x9e841a1a, 0x1e061818, 0xfd9b6666 +.long 0xec9e7272, 0x4a430909, 0x10514141, 0x24f7d3d3, 0xd5934646, 0x53ecbfbf, 0xf89a6262, 0x927be9e9, 0xff33cccc, 0x4555151, 0x270b2c2c, 0x4f420d0d, 0x59eeb7b7, 0xf3cc3f3f, 0x1caeb2b2, 0xea638989 +.long 0x74e79393, 0x7fb1cece, 0x6c1c7070, 0xdaba6a6, 0xedca2727, 0x28082020, 0x48eba3a3, 0xc1975656, 0x80820202, 0xa3dc7f7f, 0xc4965252, 0x12f9ebeb, 0xa174d5d5, 0xb38d3e3e, 0xc33ffcfc, 0x3ea49a9a +.long 0x5b461d1d, 0x1b071c1c, 0x3ba59e9e, 0xcfff3f3, 0x3ff0cfcf, 0xbf72cdcd, 0x4b175c5c, 0x52b8eaea, 0x8f810e0e, 0x3d586565, 0xcc3cf0f0, 0x7d196464, 0x7ee59b9b, 0x91871616, 0x734e3d3d, 0x8aaa2a2 +.long 0xc869a1a1, 0xc76aadad, 0x85830606, 0x7ab0caca, 0xb570c5c5, 0xf4659191, 0xb2d96b6b, 0xa7892e2e, 0x18fbe3e3, 0x47e8afaf, 0x330f3c3c, 0x674a2d2d, 0xb071c1c1, 0xe575959, 0xe99f7676, 0xe135d4d4 +.long 0x661e7878, 0xb4249090, 0x360e3838, 0x265f7979, 0xef628d8d, 0x38596161, 0x95d24747, 0x2aa08a8a, 0xb1259494, 0xaa228888, 0x8c7df1f1, 0xd73becec, 0x5010404, 0xa5218484, 0x9879e1e1, 0x9b851e1e +.long 0x84d75353, 0x0, 0x5e471919, 0xb565d5d, 0xe39d7e7e, 0x9fd04f4f, 0xbb279c9c, 0x1a534949, 0x7c4d3131, 0xee36d8d8, 0xa020808, 0x7be49f9f, 0x20a28282, 0xd4c71313, 0xe8cb2323, 0xe69c7a7a +.long 0x42e9abab, 0x43bdfefe, 0xa2882a2a, 0x9ad14b4b, 0x40410101, 0xdbc41f1f, 0xd838e0e0, 0x61b7d6d6, 0x2fa18e8e, 0x2bf4dfdf, 0x3af1cbcb, 0xf6cd3b3b, 0x1dfae7e7, 0xe5608585, 0x41155454, 0x25a38686 +.long 0x60e38383, 0x16acbaba, 0x295c7575, 0x34a69292, 0xf7996e6e, 0xe434d0d0, 0x721a6868, 0x1545555, 0x19afb6b6, 0xdf914e4e, 0xfa32c8c8, 0xf030c0c0, 0x21f6d7d7, 0xbc8e3232, 0x75b3c6c6, 0x6fe08f8f +.long 0x691d7474, 0x2ef5dbdb, 0x6ae18b8b, 0x962eb8b8, 0x8a800a0a, 0xfe679999, 0xe2c92b2b, 0xe0618181, 0xc0c30303, 0x8d29a4a4, 0xaf238c8c, 0x7a9aeae, 0x390d3434, 0x1f524d4d, 0x764f3939, 0xd36ebdbd +.long 0x81d65757, 0xb7d86f6f, 0xeb37dcdc, 0x51441515, 0xa6dd7b7b, 0x9fef7f7, 0xb68c3a3a, 0x932fbcbc, 0xf030c0c, 0x3fcffff, 0xc26ba9a9, 0xba73c9c9, 0xd96cb5b5, 0xdc6db1b1, 0x375a6d6d, 0x15504545 +.long 0xb98f3636, 0x771b6c6c, 0x13adbebe, 0xda904a4a, 0x57b9eeee, 0xa9de7777, 0x4cbef2f2, 0x837efdfd, 0x55114444, 0xbdda6767, 0x2c5d7171, 0x45400505, 0x631f7c7c, 0x50104040, 0x325b6969, 0xb8db6363 +.long 0x220a2828, 0xc5c20707, 0xf531c4c4, 0xa88a2222, 0x31a79696, 0xf9ce3737, 0x977aeded, 0x49bff6f6, 0x992db4b4, 0xa475d1d1, 0x90d34343, 0x5a124848, 0x58bae2e2, 0x71e69797, 0x64b6d2d2, 0x70b2c2c2 +.long 0xad8b2626, 0xcd68a5a5, 0xcb955e5e, 0x624b2929, 0x3c0c3030, 0xce945a5a, 0xab76dddd, 0x867ff9f9, 0xf1649595, 0x5dbbe6e6, 0x35f2c7c7, 0x2d092424, 0xd1c61717, 0xd66fb9b9, 0xdec51b1b, 0x94861212 +.long 0x78186060, 0x30f3c3c3, 0x897cf5f5, 0x5cefb3b3, 0xd23ae8e8, 0xacdf7373, 0x794c3535, 0xa0208080, 0x9d78e5e5, 0x56edbbbb, 0x235e7d7d, 0xc63ef8f8, 0x8bd45f5f, 0xe7c82f2f, 0xdd39e4e4, 0x68492121 + +#.xor_mask: +.long 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF + +#.shuffle_mask: +.byte 3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12 + +#.load_mask: +.long 0,4,8,12,16,20,24,28 + +#.store_mask: +.long 0,8,16,24,1,9,17,25 + +#below are for AESNI +#.aes_mask: 128+4096(%rax) +.byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b, 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03 +.byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b, 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03 + +#.aes_hi_mask_0: 160+4096(%rax) +.byte 0x00, 0x7a, 0x38, 0x42, 0x20, 0x5a, 0x18, 0x62, 0x40, 0x3a, 0x78, 0x02, 0x60, 0x1a, 0x58, 0x22 +.byte 0x00, 0x7a, 0x38, 0x42, 0x20, 0x5a, 0x18, 0x62, 0x40, 0x3a, 0x78, 0x02, 0x60, 0x1a, 0x58, 0x22 + +#.aes_hi_mask_1: 192+4096(%rax) +.byte 0x00, 0x13, 0xd2, 0xc1, 0x78, 0x6b, 0xaa, 0xb9, 0xad, 0xbe, 0x7f, 0x6c, 0xd5, 0xc6, 0x07, 0x14 +.byte 0x00, 0x13, 0xd2, 0xc1, 0x78, 0x6b, 0xaa, 0xb9, 0xad, 0xbe, 0x7f, 0x6c, 0xd5, 0xc6, 0x07, 0x14 + +#.aes_lo_mask_0: 224+4096(%rax) +.byte 0x00, 0xca, 0x77, 0xbd, 0x8b, 0x41, 0xfc, 0x36, 0xd4, 0x1e, 0xa3, 0x69, 0x5f, 0x95, 0x28, 0xe2 +.byte 0x00, 0xca, 0x77, 0xbd, 0x8b, 0x41, 0xfc, 0x36, 0xd4, 0x1e, 0xa3, 0x69, 0x5f, 0x95, 0x28, 0xe2 + +#.aes_lo_mask_1: 256+4096(%rax) +.byte 0x00, 0x60, 0x22, 0x42, 0x1d, 0x7d, 0x3f, 0x5f, 0x87, 0xe7, 0xa5, 0xc5, 0x9a, 0xfa, 0xb8, 0xd8 +.byte 0x00, 0x60, 0x22, 0x42, 0x1d, 0x7d, 0x3f, 0x5f, 0x87, 0xe7, 0xa5, 0xc5, 0x9a, 0xfa, 0xb8, 0xd8 + +#.aes_and_mask: 288+4096(%rax) +.byte 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f +.byte 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f + +#.aes_mask_ta: 320 +.byte 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35 +.byte 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35 + +#.aes_mask_ata: 352 +.byte 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59 +.byte 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59 + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_modes_macro_x86_64.s b/crypto/sm4/src/asm/crypt_sm4_modes_macro_x86_64.s new file mode 100644 index 00000000..258e3506 --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_modes_macro_x86_64.s @@ -0,0 +1,345 @@ +/* + * 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_SM4 + +.file "crypt_sm4_modes_macro_x86_64.s" + +.set TMP0,%ymm8 +.set TMP1,%ymm9 +.set TMP2,%ymm10 +.set TMP3,%ymm11 +.set TMP4,%ymm12 +.set TMP5,%ymm13 +.set TMP6,%ymm14 +.set TMP7,%ymm15 + +.set AES_AND_MASK,%ymm14 +.set AES_MASK,%ymm15 + +.set TMP0x,%xmm8 +.set TMP1x,%xmm9 +.set TMP2x,%xmm10 +.set TMP3x,%xmm11 +.set TMP4x,%xmm12 +.set TMP5x,%xmm13 + +/* + * x4 = x1 ^ x2 ^ x3 ^ *(rk + i); + * x4 = SBOX(x4); + * x0 = x0 ^ L32(x4); + */ +.macro SM4_ROUND A0 A1 A2 A3 RKey No + # x4 = x1 ^ x2 ^ x3 ^ *(rk + i); + movl \No(\RKey), T0 + xorl \A1, T0 + xorl \A2, T0 + xorl \A3, T0 + # x0 = x0 ^ (SBOX_0[x4 & 0xff]) ^ (SBOX_1[(x4 >> 8) & 0xff]) ^ (SBOX_2[(x4 >> 16) & 0xff]) ^ (SBOX_3[(x4 >> 24) & 0xff]); + movzbl T0BL, T1 + xorl (ADDR,T1_64,4), \A0 + shrl $8, T0 + movzbl T0BL, T1 + xorl 1024(ADDR,T1_64,4), \A0 + shrl $8, T0 + movzbl T0BL, T1 + xorl 2048(ADDR,T1_64,4), \A0 + shrl $8, T0 + xorl 3072(ADDR,T0_64,4), \A0 +.endm + +.macro MATRIX_MUL X HI_MASK LO_MASK + vpsrlw $4,\X,TMP4 + vpand AES_AND_MASK,\X,TMP5 + vpand AES_AND_MASK,TMP4,TMP4 + vpshufb TMP5,\LO_MASK,TMP5 + vpshufb TMP4,\HI_MASK,TMP4 + vpxor TMP5,TMP4,\X +.endm + +.macro MATRIX_TRANSPOSE A0 A1 A2 A3 + vpunpckhdq \A1,\A0,TMP0 + vpunpckhdq \A3,\A2,TMP1 + vpunpckldq \A1,\A0,\A0 + vpunpckldq \A3,\A2,\A2 + + vpunpckhqdq \A2,\A0,\A1 + vpunpcklqdq \A2,\A0,\A0 + vpunpckhqdq TMP1,TMP0,\A3 + vpunpcklqdq TMP1,TMP0,\A2 +.endm + +.macro SM4_LT X Y + # load LR masks (8 16 24) + vmovdqa 288+4096(%rax),TMP3 + vmovdqa 320+4096(%rax),TMP4 + vmovdqa 352+4096(%rax),TMP5 + + vpshufb TMP5,\Y,TMP2 + vpxor TMP2,\X,\X + vpxor \Y,\X,\X + + vpshufb TMP3,\Y,TMP2 + vpshufb TMP4,\Y,TMP5 + vpxor TMP5,TMP2,TMP2 + vpxor \Y,TMP2,TMP2 + + vpslld $2,TMP2,TMP3 + vpsrld $30,TMP2,TMP4 + vpxor TMP4,TMP3,TMP3 + vpxor TMP3,\X,\X +.endm + +# load aes_mask and aes_and_mask prewards +.macro SM4_AVX2_AES_2_ROUND A0 A1 A2 A3 B0 B1 B2 B3 RKey No + # load round key + vpbroadcastd \No(\RKey),TMP0 + # S-BOX inputs + vpxor \B1,TMP0,TMP1 + vpxor \B2,TMP1,TMP1 + vpxor \B3,TMP1,TMP1 + vpxor \A1,TMP0,TMP0 + vpxor \A2,TMP0,TMP0 + vpxor \A3,TMP0,TMP0 + # inverse shift rows + vpshufb AES_MASK,TMP0,TMP0 + vpshufb AES_MASK,TMP1,TMP1 + # SM4 with AESENCLAST : SM4-S(x) = A2(AES-S(A1(x))) + # load aes_hi_mask_0 & aes_lo_mask_0 + vmovdqa 128+4096(%rax),TMP2 + vmovdqa 160+4096(%rax),TMP3 + # inner affine transform : A1(x) = M1*x + C1 + MATRIX_MUL TMP0 TMP2 TMP3 + MATRIX_MUL TMP1 TMP2 TMP3 + # aesni instruction : AES-S(x) + # perform AES-S transformation + vmovdqa 192+4096(%rax),TMP4 + vextracti128 $1,TMP0,TMP2x + vextracti128 $1,TMP1,TMP3x + vaesenclast TMP4x,TMP0x,TMP0x + vaesenclast TMP4x,TMP1x,TMP1x + vaesenclast TMP4x,TMP2x,TMP2x + vaesenclast TMP4x,TMP3x,TMP3x + vinserti128 $1,TMP2x,TMP0,TMP0 + vinserti128 $1,TMP3x,TMP1,TMP1 + # load aes_hi_mask_1 & aes_lo_mask_1 + vmovdqa 224+4096(%rax),TMP2 + vmovdqa 256+4096(%rax),TMP3 + # outer affine transform : A2(x) = M2*x + C2 + MATRIX_MUL TMP0 TMP2 TMP3 + MATRIX_MUL TMP1 TMP2 TMP3 + # linear transform : 4 parallel left rotations + SM4_LT \A0 TMP0 + SM4_LT \B0 TMP1 +.endm + +.macro SM4_SERIAL_ROUNDS + xorq T0_64, T0_64 + xorq T1_64, T1_64 + SM4_ROUND W0 W1 W2 W3 RK 0 + SM4_ROUND W1 W2 W3 W0 RK 4 + SM4_ROUND W2 W3 W0 W1 RK 8 + SM4_ROUND W3 W0 W1 W2 RK 12 + SM4_ROUND W0 W1 W2 W3 RK 16 + SM4_ROUND W1 W2 W3 W0 RK 20 + SM4_ROUND W2 W3 W0 W1 RK 24 + SM4_ROUND W3 W0 W1 W2 RK 28 + SM4_ROUND W0 W1 W2 W3 RK 32 + SM4_ROUND W1 W2 W3 W0 RK 36 + SM4_ROUND W2 W3 W0 W1 RK 40 + SM4_ROUND W3 W0 W1 W2 RK 44 + SM4_ROUND W0 W1 W2 W3 RK 48 + SM4_ROUND W1 W2 W3 W0 RK 52 + SM4_ROUND W2 W3 W0 W1 RK 56 + SM4_ROUND W3 W0 W1 W2 RK 60 + SM4_ROUND W0 W1 W2 W3 RK 64 + SM4_ROUND W1 W2 W3 W0 RK 68 + SM4_ROUND W2 W3 W0 W1 RK 72 + SM4_ROUND W3 W0 W1 W2 RK 76 + SM4_ROUND W0 W1 W2 W3 RK 80 + SM4_ROUND W1 W2 W3 W0 RK 84 + SM4_ROUND W2 W3 W0 W1 RK 88 + SM4_ROUND W3 W0 W1 W2 RK 92 + SM4_ROUND W0 W1 W2 W3 RK 96 + SM4_ROUND W1 W2 W3 W0 RK 100 + SM4_ROUND W2 W3 W0 W1 RK 104 + SM4_ROUND W3 W0 W1 W2 RK 108 + SM4_ROUND W0 W1 W2 W3 RK 112 + SM4_ROUND W1 W2 W3 W0 RK 116 + SM4_ROUND W2 W3 W0 W1 RK 120 + SM4_ROUND W3 W0 W1 W2 RK 124 +.endm + +.macro SM4_AVX2_AES_2_ROUNDS + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 0 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 4 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 8 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 12 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 16 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 20 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 24 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 28 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 32 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 36 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 40 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 44 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 48 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 52 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 56 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 60 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 64 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 68 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 72 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 76 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 80 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 84 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 88 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 92 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 96 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 100 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 104 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 108 + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 112 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 116 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 120 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 124 +.endm + +##### SBOX Extend Tables (1 Table, 256*4 bytes): SBOX_0, SBOX_1, SBOX_2, SBOX_3 ##### + +.section .rodata +.align 64 + +SBOX4X_MASK: +#SBOX_0: +.long 0xd55b5b8e, 0x924242d0, 0xeaa7a74d, 0xfdfbfb06, 0xcf3333fc, 0xe2878765, 0x3df4f4c9, 0xb5dede6b, 0x1658584e, 0xb4dada6e, 0x14505044, 0xc10b0bca, 0x28a0a088, 0xf8efef17, 0x2cb0b09c, 0x05141411 +.long 0x2bacac87, 0x669d9dfb, 0x986a6af2, 0x77d9d9ae, 0x2aa8a882, 0xbcfafa46, 0x04101014, 0xc00f0fcf, 0xa8aaaa02, 0x45111154, 0x134c4c5f, 0x269898be, 0x4825256d, 0x841a1a9e, 0x0618181e, 0x9b6666fd +.long 0x9e7272ec, 0x4309094a, 0x51414110, 0xf7d3d324, 0x934646d5, 0xecbfbf53, 0x9a6262f8, 0x7be9e992, 0x33ccccff, 0x55515104, 0x0b2c2c27, 0x420d0d4f, 0xeeb7b759, 0xcc3f3ff3, 0xaeb2b21c, 0x638989ea +.long 0xe7939374, 0xb1cece7f, 0x1c70706c, 0xaba6a60d, 0xca2727ed, 0x08202028, 0xeba3a348, 0x975656c1, 0x82020280, 0xdc7f7fa3, 0x965252c4, 0xf9ebeb12, 0x74d5d5a1, 0x8d3e3eb3, 0x3ffcfcc3, 0xa49a9a3e +.long 0x461d1d5b, 0x071c1c1b, 0xa59e9e3b, 0xfff3f30c, 0xf0cfcf3f, 0x72cdcdbf, 0x175c5c4b, 0xb8eaea52, 0x810e0e8f, 0x5865653d, 0x3cf0f0cc, 0x1964647d, 0xe59b9b7e, 0x87161691, 0x4e3d3d73, 0xaaa2a208 +.long 0x69a1a1c8, 0x6aadadc7, 0x83060685, 0xb0caca7a, 0x70c5c5b5, 0x659191f4, 0xd96b6bb2, 0x892e2ea7, 0xfbe3e318, 0xe8afaf47, 0x0f3c3c33, 0x4a2d2d67, 0x71c1c1b0, 0x5759590e, 0x9f7676e9, 0x35d4d4e1 +.long 0x1e787866, 0x249090b4, 0x0e383836, 0x5f797926, 0x628d8def, 0x59616138, 0xd2474795, 0xa08a8a2a, 0x259494b1, 0x228888aa, 0x7df1f18c, 0x3bececd7, 0x01040405, 0x218484a5, 0x79e1e198, 0x851e1e9b +.long 0xd7535384, 0x0, 0x4719195e, 0x565d5d0b, 0x9d7e7ee3, 0xd04f4f9f, 0x279c9cbb, 0x5349491a, 0x4d31317c, 0x36d8d8ee, 0x0208080a, 0xe49f9f7b, 0xa2828220, 0xc71313d4, 0xcb2323e8, 0x9c7a7ae6 +.long 0xe9abab42, 0xbdfefe43, 0x882a2aa2, 0xd14b4b9a, 0x41010140, 0xc41f1fdb, 0x38e0e0d8, 0xb7d6d661, 0xa18e8e2f, 0xf4dfdf2b, 0xf1cbcb3a, 0xcd3b3bf6, 0xfae7e71d, 0x608585e5, 0x15545441, 0xa3868625 +.long 0xe3838360, 0xacbaba16, 0x5c757529, 0xa6929234, 0x996e6ef7, 0x34d0d0e4, 0x1a686872, 0x54555501, 0xafb6b619, 0x914e4edf, 0x32c8c8fa, 0x30c0c0f0, 0xf6d7d721, 0x8e3232bc, 0xb3c6c675, 0xe08f8f6f +.long 0x1d747469, 0xf5dbdb2e, 0xe18b8b6a, 0x2eb8b896, 0x800a0a8a, 0x679999fe, 0xc92b2be2, 0x618181e0, 0xc30303c0, 0x29a4a48d, 0x238c8caf, 0xa9aeae07, 0x0d343439, 0x524d4d1f, 0x4f393976, 0x6ebdbdd3 +.long 0xd6575781, 0xd86f6fb7, 0x37dcdceb, 0x44151551, 0xdd7b7ba6, 0xfef7f709, 0x8c3a3ab6, 0x2fbcbc93, 0x030c0c0f, 0xfcffff03, 0x6ba9a9c2, 0x73c9c9ba, 0x6cb5b5d9, 0x6db1b1dc, 0x5a6d6d37, 0x50454515 +.long 0x8f3636b9, 0x1b6c6c77, 0xadbebe13, 0x904a4ada, 0xb9eeee57, 0xde7777a9, 0xbef2f24c, 0x7efdfd83, 0x11444455, 0xda6767bd, 0x5d71712c, 0x40050545, 0x1f7c7c63, 0x10404050, 0x5b696932, 0xdb6363b8 +.long 0x0a282822, 0xc20707c5, 0x31c4c4f5, 0x8a2222a8, 0xa7969631, 0xce3737f9, 0x7aeded97, 0xbff6f649, 0x2db4b499, 0x75d1d1a4, 0xd3434390, 0x1248485a, 0xbae2e258, 0xe6979771, 0xb6d2d264, 0xb2c2c270 +.long 0x8b2626ad, 0x68a5a5cd, 0x955e5ecb, 0x4b292962, 0x0c30303c, 0x945a5ace, 0x76ddddab, 0x7ff9f986, 0x649595f1, 0xbbe6e65d, 0xf2c7c735, 0x0924242d, 0xc61717d1, 0x6fb9b9d6, 0xc51b1bde, 0x86121294 +.long 0x18606078, 0xf3c3c330, 0x7cf5f589, 0xefb3b35c, 0x3ae8e8d2, 0xdf7373ac, 0x4c353579, 0x208080a0, 0x78e5e59d, 0xedbbbb56, 0x5e7d7d23, 0x3ef8f8c6, 0xd45f5f8b, 0xc82f2fe7, 0x39e4e4dd, 0x49212168 + +#SBOX_1: +.long 0x5b5b8ed5, 0x4242d092, 0xa7a74dea, 0xfbfb06fd, 0x3333fccf, 0x878765e2, 0xf4f4c93d, 0xdede6bb5, 0x58584e16, 0xdada6eb4, 0x50504414, 0x0b0bcac1, 0xa0a08828, 0xefef17f8, 0xb0b09c2c, 0x14141105 +.long 0xacac872b, 0x9d9dfb66, 0x6a6af298, 0xd9d9ae77, 0xa8a8822a, 0xfafa46bc, 0x10101404, 0x0f0fcfc0, 0xaaaa02a8, 0x11115445, 0x4c4c5f13, 0x9898be26, 0x25256d48, 0x1a1a9e84, 0x18181e06, 0x6666fd9b +.long 0x7272ec9e, 0x09094a43, 0x41411051, 0xd3d324f7, 0x4646d593, 0xbfbf53ec, 0x6262f89a, 0xe9e9927b, 0xccccff33, 0x51510455, 0x2c2c270b, 0x0d0d4f42, 0xb7b759ee, 0x3f3ff3cc, 0xb2b21cae, 0x8989ea63 +.long 0x939374e7, 0xcece7fb1, 0x70706c1c, 0xa6a60dab, 0x2727edca, 0x20202808, 0xa3a348eb, 0x5656c197, 0x02028082, 0x7f7fa3dc, 0x5252c496, 0xebeb12f9, 0xd5d5a174, 0x3e3eb38d, 0xfcfcc33f, 0x9a9a3ea4 +.long 0x1d1d5b46, 0x1c1c1b07, 0x9e9e3ba5, 0xf3f30cff, 0xcfcf3ff0, 0xcdcdbf72, 0x5c5c4b17, 0xeaea52b8, 0x0e0e8f81, 0x65653d58, 0xf0f0cc3c, 0x64647d19, 0x9b9b7ee5, 0x16169187, 0x3d3d734e, 0xa2a208aa +.long 0xa1a1c869, 0xadadc76a, 0x06068583, 0xcaca7ab0, 0xc5c5b570, 0x9191f465, 0x6b6bb2d9, 0x2e2ea789, 0xe3e318fb, 0xafaf47e8, 0x3c3c330f, 0x2d2d674a, 0xc1c1b071, 0x59590e57, 0x7676e99f, 0xd4d4e135 +.long 0x7878661e, 0x9090b424, 0x3838360e, 0x7979265f, 0x8d8def62, 0x61613859, 0x474795d2, 0x8a8a2aa0, 0x9494b125, 0x8888aa22, 0xf1f18c7d, 0xececd73b, 0x04040501, 0x8484a521, 0xe1e19879, 0x1e1e9b85 +.long 0x535384d7, 0x0, 0x19195e47, 0x5d5d0b56, 0x7e7ee39d, 0x4f4f9fd0, 0x9c9cbb27, 0x49491a53, 0x31317c4d, 0xd8d8ee36, 0x08080a02, 0x9f9f7be4, 0x828220a2, 0x1313d4c7, 0x2323e8cb, 0x7a7ae69c +.long 0xabab42e9, 0xfefe43bd, 0x2a2aa288, 0x4b4b9ad1, 0x01014041, 0x1f1fdbc4, 0xe0e0d838, 0xd6d661b7, 0x8e8e2fa1, 0xdfdf2bf4, 0xcbcb3af1, 0x3b3bf6cd, 0xe7e71dfa, 0x8585e560, 0x54544115, 0x868625a3 +.long 0x838360e3, 0xbaba16ac, 0x7575295c, 0x929234a6, 0x6e6ef799, 0xd0d0e434, 0x6868721a, 0x55550154, 0xb6b619af, 0x4e4edf91, 0xc8c8fa32, 0xc0c0f030, 0xd7d721f6, 0x3232bc8e, 0xc6c675b3, 0x8f8f6fe0 +.long 0x7474691d, 0xdbdb2ef5, 0x8b8b6ae1, 0xb8b8962e, 0x0a0a8a80, 0x9999fe67, 0x2b2be2c9, 0x8181e061, 0x0303c0c3, 0xa4a48d29, 0x8c8caf23, 0xaeae07a9, 0x3434390d, 0x4d4d1f52, 0x3939764f, 0xbdbdd36e +.long 0x575781d6, 0x6f6fb7d8, 0xdcdceb37, 0x15155144, 0x7b7ba6dd, 0xf7f709fe, 0x3a3ab68c, 0xbcbc932f, 0x0c0c0f03, 0xffff03fc, 0xa9a9c26b, 0xc9c9ba73, 0xb5b5d96c, 0xb1b1dc6d, 0x6d6d375a, 0x45451550 +.long 0x3636b98f, 0x6c6c771b, 0xbebe13ad, 0x4a4ada90, 0xeeee57b9, 0x7777a9de, 0xf2f24cbe, 0xfdfd837e, 0x44445511, 0x6767bdda, 0x71712c5d, 0x05054540, 0x7c7c631f, 0x40405010, 0x6969325b, 0x6363b8db +.long 0x2828220a, 0x0707c5c2, 0xc4c4f531, 0x2222a88a, 0x969631a7, 0x3737f9ce, 0xeded977a, 0xf6f649bf, 0xb4b4992d, 0xd1d1a475, 0x434390d3, 0x48485a12, 0xe2e258ba, 0x979771e6, 0xd2d264b6, 0xc2c270b2 +.long 0x2626ad8b, 0xa5a5cd68, 0x5e5ecb95, 0x2929624b, 0x30303c0c, 0x5a5ace94, 0xddddab76, 0xf9f9867f, 0x9595f164, 0xe6e65dbb, 0xc7c735f2, 0x24242d09, 0x1717d1c6, 0xb9b9d66f, 0x1b1bdec5, 0x12129486 +.long 0x60607818, 0xc3c330f3, 0xf5f5897c, 0xb3b35cef, 0xe8e8d23a, 0x7373acdf, 0x3535794c, 0x8080a020, 0xe5e59d78, 0xbbbb56ed, 0x7d7d235e, 0xf8f8c63e, 0x5f5f8bd4, 0x2f2fe7c8, 0xe4e4dd39, 0x21216849 + +#SBOX_2: +.long 0x5b8ed55b, 0x42d09242, 0xa74deaa7, 0xfb06fdfb, 0x33fccf33, 0x8765e287, 0xf4c93df4, 0xde6bb5de, 0x584e1658, 0xda6eb4da, 0x50441450, 0x0bcac10b, 0xa08828a0, 0xef17f8ef, 0xb09c2cb0, 0x14110514 +.long 0xac872bac, 0x9dfb669d, 0x6af2986a, 0xd9ae77d9, 0xa8822aa8, 0xfa46bcfa, 0x10140410, 0x0fcfc00f, 0xaa02a8aa, 0x11544511, 0x4c5f134c, 0x98be2698, 0x256d4825, 0x1a9e841a, 0x181e0618, 0x66fd9b66 +.long 0x72ec9e72, 0x094a4309, 0x41105141, 0xd324f7d3, 0x46d59346, 0xbf53ecbf, 0x62f89a62, 0xe9927be9, 0xccff33cc, 0x51045551, 0x2c270b2c, 0x0d4f420d, 0xb759eeb7, 0x3ff3cc3f, 0xb21caeb2, 0x89ea6389 +.long 0x9374e793, 0xce7fb1ce, 0x706c1c70, 0xa60daba6, 0x27edca27, 0x20280820, 0xa348eba3, 0x56c19756, 0x02808202, 0x7fa3dc7f, 0x52c49652, 0xeb12f9eb, 0xd5a174d5, 0x3eb38d3e, 0xfcc33ffc, 0x9a3ea49a +.long 0x1d5b461d, 0x1c1b071c, 0x9e3ba59e, 0xf30cfff3, 0xcf3ff0cf, 0xcdbf72cd, 0x5c4b175c, 0xea52b8ea, 0x0e8f810e, 0x653d5865, 0xf0cc3cf0, 0x647d1964, 0x9b7ee59b, 0x16918716, 0x3d734e3d, 0xa208aaa2 +.long 0xa1c869a1, 0xadc76aad, 0x06858306, 0xca7ab0ca, 0xc5b570c5, 0x91f46591, 0x6bb2d96b, 0x2ea7892e, 0xe318fbe3, 0xaf47e8af, 0x3c330f3c, 0x2d674a2d, 0xc1b071c1, 0x590e5759, 0x76e99f76, 0xd4e135d4 +.long 0x78661e78, 0x90b42490, 0x38360e38, 0x79265f79, 0x8def628d, 0x61385961, 0x4795d247, 0x8a2aa08a, 0x94b12594, 0x88aa2288, 0xf18c7df1, 0xecd73bec, 0x04050104, 0x84a52184, 0xe19879e1, 0x1e9b851e +.long 0x5384d753, 0x0, 0x195e4719, 0x5d0b565d, 0x7ee39d7e, 0x4f9fd04f, 0x9cbb279c, 0x491a5349, 0x317c4d31, 0xd8ee36d8, 0x080a0208, 0x9f7be49f, 0x8220a282, 0x13d4c713, 0x23e8cb23, 0x7ae69c7a +.long 0xab42e9ab, 0xfe43bdfe, 0x2aa2882a, 0x4b9ad14b, 0x01404101, 0x1fdbc41f, 0xe0d838e0, 0xd661b7d6, 0x8e2fa18e, 0xdf2bf4df, 0xcb3af1cb, 0x3bf6cd3b, 0xe71dfae7, 0x85e56085, 0x54411554, 0x8625a386 +.long 0x8360e383, 0xba16acba, 0x75295c75, 0x9234a692, 0x6ef7996e, 0xd0e434d0, 0x68721a68, 0x55015455, 0xb619afb6, 0x4edf914e, 0xc8fa32c8, 0xc0f030c0, 0xd721f6d7, 0x32bc8e32, 0xc675b3c6, 0x8f6fe08f +.long 0x74691d74, 0xdb2ef5db, 0x8b6ae18b, 0xb8962eb8, 0x0a8a800a, 0x99fe6799, 0x2be2c92b, 0x81e06181, 0x03c0c303, 0xa48d29a4, 0x8caf238c, 0xae07a9ae, 0x34390d34, 0x4d1f524d, 0x39764f39, 0xbdd36ebd +.long 0x5781d657, 0x6fb7d86f, 0xdceb37dc, 0x15514415, 0x7ba6dd7b, 0xf709fef7, 0x3ab68c3a, 0xbc932fbc, 0x0c0f030c, 0xff03fcff, 0xa9c26ba9, 0xc9ba73c9, 0xb5d96cb5, 0xb1dc6db1, 0x6d375a6d, 0x45155045 +.long 0x36b98f36, 0x6c771b6c, 0xbe13adbe, 0x4ada904a, 0xee57b9ee, 0x77a9de77, 0xf24cbef2, 0xfd837efd, 0x44551144, 0x67bdda67, 0x712c5d71, 0x05454005, 0x7c631f7c, 0x40501040, 0x69325b69, 0x63b8db63 +.long 0x28220a28, 0x07c5c207, 0xc4f531c4, 0x22a88a22, 0x9631a796, 0x37f9ce37, 0xed977aed, 0xf649bff6, 0xb4992db4, 0xd1a475d1, 0x4390d343, 0x485a1248, 0xe258bae2, 0x9771e697, 0xd264b6d2, 0xc270b2c2 +.long 0x26ad8b26, 0xa5cd68a5, 0x5ecb955e, 0x29624b29, 0x303c0c30, 0x5ace945a, 0xddab76dd, 0xf9867ff9, 0x95f16495, 0xe65dbbe6, 0xc735f2c7, 0x242d0924, 0x17d1c617, 0xb9d66fb9, 0x1bdec51b, 0x12948612 +.long 0x60781860, 0xc330f3c3, 0xf5897cf5, 0xb35cefb3, 0xe8d23ae8, 0x73acdf73, 0x35794c35, 0x80a02080, 0xe59d78e5, 0xbb56edbb, 0x7d235e7d, 0xf8c63ef8, 0x5f8bd45f, 0x2fe7c82f, 0xe4dd39e4, 0x21684921 + +#SBOX_3: +.long 0x8ed55b5b, 0xd0924242, 0x4deaa7a7, 0x06fdfbfb, 0xfccf3333, 0x65e28787, 0xc93df4f4, 0x6bb5dede, 0x4e165858, 0x6eb4dada, 0x44145050, 0xcac10b0b, 0x8828a0a0, 0x17f8efef, 0x9c2cb0b0, 0x11051414 +.long 0x872bacac, 0xfb669d9d, 0xf2986a6a, 0xae77d9d9, 0x822aa8a8, 0x46bcfafa, 0x14041010, 0xcfc00f0f, 0x02a8aaaa, 0x54451111, 0x5f134c4c, 0xbe269898, 0x6d482525, 0x9e841a1a, 0x1e061818, 0xfd9b6666 +.long 0xec9e7272, 0x4a430909, 0x10514141, 0x24f7d3d3, 0xd5934646, 0x53ecbfbf, 0xf89a6262, 0x927be9e9, 0xff33cccc, 0x04555151, 0x270b2c2c, 0x4f420d0d, 0x59eeb7b7, 0xf3cc3f3f, 0x1caeb2b2, 0xea638989 +.long 0x74e79393, 0x7fb1cece, 0x6c1c7070, 0x0daba6a6, 0xedca2727, 0x28082020, 0x48eba3a3, 0xc1975656, 0x80820202, 0xa3dc7f7f, 0xc4965252, 0x12f9ebeb, 0xa174d5d5, 0xb38d3e3e, 0xc33ffcfc, 0x3ea49a9a +.long 0x5b461d1d, 0x1b071c1c, 0x3ba59e9e, 0x0cfff3f3, 0x3ff0cfcf, 0xbf72cdcd, 0x4b175c5c, 0x52b8eaea, 0x8f810e0e, 0x3d586565, 0xcc3cf0f0, 0x7d196464, 0x7ee59b9b, 0x91871616, 0x734e3d3d, 0x08aaa2a2 +.long 0xc869a1a1, 0xc76aadad, 0x85830606, 0x7ab0caca, 0xb570c5c5, 0xf4659191, 0xb2d96b6b, 0xa7892e2e, 0x18fbe3e3, 0x47e8afaf, 0x330f3c3c, 0x674a2d2d, 0xb071c1c1, 0x0e575959, 0xe99f7676, 0xe135d4d4 +.long 0x661e7878, 0xb4249090, 0x360e3838, 0x265f7979, 0xef628d8d, 0x38596161, 0x95d24747, 0x2aa08a8a, 0xb1259494, 0xaa228888, 0x8c7df1f1, 0xd73becec, 0x05010404, 0xa5218484, 0x9879e1e1, 0x9b851e1e +.long 0x84d75353, 0x0, 0x5e471919, 0x0b565d5d, 0xe39d7e7e, 0x9fd04f4f, 0xbb279c9c, 0x1a534949, 0x7c4d3131, 0xee36d8d8, 0x0a020808, 0x7be49f9f, 0x20a28282, 0xd4c71313, 0xe8cb2323, 0xe69c7a7a +.long 0x42e9abab, 0x43bdfefe, 0xa2882a2a, 0x9ad14b4b, 0x40410101, 0xdbc41f1f, 0xd838e0e0, 0x61b7d6d6, 0x2fa18e8e, 0x2bf4dfdf, 0x3af1cbcb, 0xf6cd3b3b, 0x1dfae7e7, 0xe5608585, 0x41155454, 0x25a38686 +.long 0x60e38383, 0x16acbaba, 0x295c7575, 0x34a69292, 0xf7996e6e, 0xe434d0d0, 0x721a6868, 0x01545555, 0x19afb6b6, 0xdf914e4e, 0xfa32c8c8, 0xf030c0c0, 0x21f6d7d7, 0xbc8e3232, 0x75b3c6c6, 0x6fe08f8f +.long 0x691d7474, 0x2ef5dbdb, 0x6ae18b8b, 0x962eb8b8, 0x8a800a0a, 0xfe679999, 0xe2c92b2b, 0xe0618181, 0xc0c30303, 0x8d29a4a4, 0xaf238c8c, 0x07a9aeae, 0x390d3434, 0x1f524d4d, 0x764f3939, 0xd36ebdbd +.long 0x81d65757, 0xb7d86f6f, 0xeb37dcdc, 0x51441515, 0xa6dd7b7b, 0x09fef7f7, 0xb68c3a3a, 0x932fbcbc, 0x0f030c0c, 0x03fcffff, 0xc26ba9a9, 0xba73c9c9, 0xd96cb5b5, 0xdc6db1b1, 0x375a6d6d, 0x15504545 +.long 0xb98f3636, 0x771b6c6c, 0x13adbebe, 0xda904a4a, 0x57b9eeee, 0xa9de7777, 0x4cbef2f2, 0x837efdfd, 0x55114444, 0xbdda6767, 0x2c5d7171, 0x45400505, 0x631f7c7c, 0x50104040, 0x325b6969, 0xb8db6363 +.long 0x220a2828, 0xc5c20707, 0xf531c4c4, 0xa88a2222, 0x31a79696, 0xf9ce3737, 0x977aeded, 0x49bff6f6, 0x992db4b4, 0xa475d1d1, 0x90d34343, 0x5a124848, 0x58bae2e2, 0x71e69797, 0x64b6d2d2, 0x70b2c2c2 +.long 0xad8b2626, 0xcd68a5a5, 0xcb955e5e, 0x624b2929, 0x3c0c3030, 0xce945a5a, 0xab76dddd, 0x867ff9f9, 0xf1649595, 0x5dbbe6e6, 0x35f2c7c7, 0x2d092424, 0xd1c61717, 0xd66fb9b9, 0xdec51b1b, 0x94861212 +.long 0x78186060, 0x30f3c3c3, 0x897cf5f5, 0x5cefb3b3, 0xd23ae8e8, 0xacdf7373, 0x794c3535, 0xa0208080, 0x9d78e5e5, 0x56edbbbb, 0x235e7d7d, 0xc63ef8f8, 0x8bd45f5f, 0xe7c82f2f, 0xdd39e4e4, 0x68492121 + +##### MASKS ##### + +#.shuffle_mask_128: 4096(%rax) +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +#.shuffle_mask_32: 32+4096(%rax) +.byte 3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12 + +# below are for AESNI +#.aes_mask: 64+4096(%rax) +.byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b, 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03 +.byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b, 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03 + +#.aes_and_mask: 96+4096(%rax) +.byte 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f +.byte 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f + +#.aes_hi_mask_0: 128+4096(%rax) +.byte 0x00, 0xa2, 0x49, 0xeb, 0x09, 0xab, 0x40, 0xe2, 0x12, 0xb0, 0x5b, 0xf9, 0x1b, 0xb9, 0x52, 0xf0 +.byte 0x00, 0xa2, 0x49, 0xeb, 0x09, 0xab, 0x40, 0xe2, 0x12, 0xb0, 0x5b, 0xf9, 0x1b, 0xb9, 0x52, 0xf0 + +#.aes_lo_mask_0: 160+4096(%rax) +.byte 0x01, 0x07, 0x72, 0x74, 0xe4, 0xe2, 0x97, 0x91, 0x57, 0x51, 0x24, 0x22, 0xb2, 0xb4, 0xc1, 0xc7 +.byte 0x01, 0x07, 0x72, 0x74, 0xe4, 0xe2, 0x97, 0x91, 0x57, 0x51, 0x24, 0x22, 0xb2, 0xb4, 0xc1, 0xc7 + +#.all_zero_mask: 192+4096(%rax) +.long 0,0,0,0,0,0,0,0 + +#.aes_hi_mask_1: 224+4096(%rax) +.byte 0x00, 0xdc, 0xaf, 0x73, 0xdd, 0x01, 0x72, 0xae, 0xbf, 0x63, 0x10, 0xcc, 0x62, 0xbe, 0xcd, 0x11 +.byte 0x00, 0xdc, 0xaf, 0x73, 0xdd, 0x01, 0x72, 0xae, 0xbf, 0x63, 0x10, 0xcc, 0x62, 0xbe, 0xcd, 0x11 + +#.aes_lo_mask_1: 256+4096(%rax) +.byte 0x34, 0x08, 0x9d, 0xa1, 0xce, 0xf2, 0x67, 0x5b, 0x82, 0xbe, 0x2b, 0x17, 0x78, 0x44, 0xd1, 0xed +.byte 0x34, 0x08, 0x9d, 0xa1, 0xce, 0xf2, 0x67, 0x5b, 0x82, 0xbe, 0x2b, 0x17, 0x78, 0x44, 0xd1, 0xed + +# left rotations +#.r08: 288+4096(%rax) +.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14,3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 + +#.r16: 320+4096(%rax) +.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13,2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 + +#.r24: 352+4096(%rax) +.byte 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12,1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12 + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_modes_x86_64.S b/crypto/sm4/src/asm/crypt_sm4_modes_x86_64.S new file mode 100644 index 00000000..a132ef2d --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_modes_x86_64.S @@ -0,0 +1,1046 @@ +/* + * 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_SM4 + +#include "crypt_sm4_modes_macro_x86_64.s" + +.file "crypt_sm4_modes_x86_64.S" +.text + +.set X0,%ymm0 +.set X1,%ymm1 +.set X2,%ymm2 +.set X3,%ymm3 +.set Y0,%ymm4 +.set Y1,%ymm5 +.set Y2,%ymm6 +.set Y3,%ymm7 + +.set ADDR,%rax +.set IN,%rdi +.set OUT,%rsi +.set LEN,%rdx +.set BLOCKS,%rdx +.set RK,%rcx +.set IV,%r8 +.set TWEAK,%r8 +.set TWEAK_MASK,%r9 +.set ENC,%r9d +.set HI,%r12 +.set LO,%r13 +.set HI_TMP,%r14 +.set LO_TMP,%r15 + +.set T0,%r10d +.set T0BL,%r10b +.set T1,%r11d + +.set T0_64,%r10 +.set T1_64,%r11 + +.set W0,%r12d +.set W1,%r13d +.set W2,%r14d +.set W3,%r15d + +.macro LOAD_DATA + vmovdqu (IN),X0 + vmovdqu 32(IN),X1 + vmovdqu 64(IN),X2 + vmovdqu 96(IN),X3 + vmovdqu 128(IN),Y0 + vmovdqu 128+32(IN),Y1 + vmovdqu 128+64(IN),Y2 + vmovdqu 128+96(IN),Y3 +.endm + +.macro XOR_DATA + vpxor (IN),X0,X0 + vpxor 32(IN),X1,X1 + vpxor 64(IN),X2,X2 + vpxor 96(IN),X3,X3 + vpxor 128(IN),Y0,Y0 + vpxor 128+32(IN),Y1,Y1 + vpxor 128+64(IN),Y2,Y2 + vpxor 128+96(IN),Y3,Y3 +.endm + +.macro SM4_CRYPT_BLOCK16 + vmovdqa 32+4096(ADDR),TMP0 + vmovdqa 64+4096(ADDR),AES_MASK + vmovdqa 96+4096(ADDR),AES_AND_MASK + + vpshufb TMP0,X0,X0 + vpshufb TMP0,X1,X1 + vpshufb TMP0,X2,X2 + vpshufb TMP0,X3,X3 + vpshufb TMP0,Y0,Y0 + vpshufb TMP0,Y1,Y1 + vpshufb TMP0,Y2,Y2 + vpshufb TMP0,Y3,Y3 + + # Pack SIMD Vectors + MATRIX_TRANSPOSE X0 X1 X2 X3 + MATRIX_TRANSPOSE Y0 Y1 Y2 Y3 + + # AVX2 Rounds + SM4_AVX2_AES_2_ROUNDS + + # Restore SIMD Vectors + MATRIX_TRANSPOSE X0 X1 X2 X3 + MATRIX_TRANSPOSE Y0 Y1 Y2 Y3 + + # Reverse Transformation + vmovdqa 4096(ADDR),TMP0 + vpshufb TMP0,X0,X0 + vpshufb TMP0,X1,X1 + vpshufb TMP0,X2,X2 + vpshufb TMP0,X3,X3 + vpshufb TMP0,Y0,Y0 + vpshufb TMP0,Y1,Y1 + vpshufb TMP0,Y2,Y2 + vpshufb TMP0,Y3,Y3 +.endm + +.macro STORE_RESULTS + vmovdqu X0,0(OUT) + vmovdqu X1,32(OUT) + vmovdqu X2,64(OUT) + vmovdqu X3,96(OUT) + vmovdqu Y0,128(OUT) + vmovdqu Y1,128+32(OUT) + vmovdqu Y2,128+64(OUT) + vmovdqu Y3,128+96(OUT) +.endm + +.macro CLEAR_CONTEXT + xorl T0,T0 + xorl T1,T1 + xorl W0,W0 + xorl W1,W1 + xorl W2,W2 + xorl W3,W3 +.endm + +##### SM4-CBC ##### + # void SM4_CBC_Encrypt(const unsigned char *in, unsigned char *out, size_t len, const SM4_KEY *key, unsigned char *iv, const int enc) + # in %rdi + # out %rsi + # len %rdx + # rk %rcx + # iv %r8 + # enc %r9d + .globl SM4_CBC_Encrypt + .type SM4_CBC_Encrypt, @function + .align 64 + +SM4_CBC_Encrypt: + + # Store Registers + subq $72,%rsp + movq %rbx,(%rsp) + movq %rbp,8(%rsp) + movq %r9,16(%rsp) + movq %r10,24(%rsp) + movq %r11,32(%rsp) + movq %r12,40(%rsp) + movq %r13,48(%rsp) + movq %r14,56(%rsp) + movq %r15,64(%rsp) + + # Get Address + leaq SBOX4X_MASK(%rip),ADDR + + testl ENC,ENC + jz .Lcbc_decrypt + +.Lcbc_encrypt: + + cmpq $16,LEN + jl .Lcbc_ret + + # Load Data + movl (IN),W0 + movl 4(IN),W1 + movl 8(IN),W2 + movl 12(IN),W3 + + # XOR IV + xorl (IV),W0 + xorl 4(IV),W1 + xorl 8(IV),W2 + xorl 12(IV),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Results + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + movl W3,(IV) + movl W2,4(IV) + movl W1,8(IV) + movl W0,12(IV) + + leaq 16(IN),IN + leaq 16(OUT),OUT + subq $16,LEN + + jmp .Lcbc_encrypt + +.Lcbc_decrypt: + + cmpq $256,LEN + jl .Lcbc_dec + +.Lcbc_dec16: + + LOAD_DATA + SM4_CRYPT_BLOCK16 + + vmovdqu (IV),TMP0x + vmovdqu (IN),TMP1x + vinserti128 $1,TMP1x,TMP0,TMP0 + vmovdqu 240(IN),TMP2x + vmovdqu TMP2x,(IV) + + vpxor TMP0,X0,X0 + vpxor 16(IN),X1,X1 + vpxor 32+16(IN),X2,X2 + vpxor 64+16(IN),X3,X3 + vpxor 96+16(IN),Y0,Y0 + vpxor 128+16(IN),Y1,Y1 + vpxor 160+16(IN),Y2,Y2 + vpxor 192+16(IN),Y3,Y3 + + STORE_RESULTS + + leaq 256(IN),IN + leaq 256(OUT),OUT + subq $256,LEN + cmpq $256,LEN + jl .Lcbc_dec16_ret + jmp .Lcbc_dec16 + +.Lcbc_dec16_ret: + + vzeroall + +.Lcbc_dec: + + cmpq $16,LEN + jl .Lcbc_ret + + # Load Data + movl (IN),W0 + movl 4(IN),W1 + movl 8(IN),W2 + movl 12(IN),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Result + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + xorl (IV),W3 + xorl 4(IV),W2 + xorl 8(IV),W1 + xorl 12(IV),W0 + + movq (IN),%r10 + movq %r10,(IV) + movq 8(IN),%r10 + movq %r10,8(IV) + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + leaq 16(IN),IN + leaq 16(OUT),OUT + subq $16,LEN + + jmp .Lcbc_dec + +.Lcbc_ret: + + CLEAR_CONTEXT + + # Restore Registers + movq (%rsp),%rbx + movq 8(%rsp),%rbp + movq 16(%rsp),%rax + movq 24(%rsp),%r10 + movq 32(%rsp),%r11 + movq 40(%rsp),%r12 + movq 48(%rsp),%r13 + movq 56(%rsp),%r14 + movq 64(%rsp),%r15 + addq $72,%rsp + + ret + .size SM4_CBC_Encrypt, .-SM4_CBC_Encrypt + +##### SM4-ECB ##### + # void SM4_ECB_Encrypt(const unsigned char *in, unsigned char *out, size_t len, const SM4_KEY *key) + # in %rdi + # out %rsi + # len %rdx + # key %rcx + .globl SM4_ECB_Encrypt + .type SM4_ECB_Encrypt, @function + .align 64 + +SM4_ECB_Encrypt: + + # Store Registers + subq $32,%rsp + movq %r12,(%rsp) + movq %r13,8(%rsp) + movq %r14,16(%rsp) + movq %r15,24(%rsp) + + # Get Address + leaq SBOX4X_MASK(%rip),ADDR + +.Lecb_encrypt: + + cmpq $256,LEN + jl .Lecb_enc + +.Lecb_enc16: + + LOAD_DATA + SM4_CRYPT_BLOCK16 + STORE_RESULTS + + leaq 256(IN),IN + leaq 256(OUT),OUT + subq $256,LEN + cmpq $256,LEN + jl .Lecb_enc16_ret + jmp .Lecb_enc16 + +.Lecb_enc16_ret: + + vzeroall + +.Lecb_enc: + + cmpq $16,LEN + jl .Lecb_ret + + # Load Data + movl (IN),W0 + movl 4(IN),W1 + movl 8(IN),W2 + movl 12(IN),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Result + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + leaq 16(IN),IN + leaq 16(OUT),OUT + subq $16,LEN + + jmp .Lecb_enc + +.Lecb_ret: + + CLEAR_CONTEXT + + # Restore Registers + movq (%rsp),%r12 + movq 8(%rsp),%r13 + movq 16(%rsp),%r14 + movq 24(%rsp),%r15 + addq $32,%rsp + + ret + .size SM4_ECB_Encrypt, .-SM4_ECB_Encrypt + +##### SM4-CFB ENC ##### + # void SM4_CFB128_Encrypt(const unsigned char *in, unsigned char *out, size_t len, const SM4_KEY *key, unsigned char *iv, int *num) + # in %rdi + # out %rsi + # len %rdx + # rk %rcx + # iv %r8 + # num %r9d + .globl SM4_CFB128_Encrypt + .type SM4_CFB128_Encrypt, @function + .align 64 + +SM4_CFB128_Encrypt: + + # Store Registers + subq $72,%rsp + movq %rbx,(%rsp) + movq %rbp,8(%rsp) + movq %r9,16(%rsp) + movq %r10,24(%rsp) + movq %r11,32(%rsp) + movq %r12,40(%rsp) + movq %r13,48(%rsp) + movq %r14,56(%rsp) + movq %r15,64(%rsp) + + # Load Num + movl (%r9),%r9d + cmpl $0,%r9d + je .Lcfb128_enc_update + +.Lcfb128_enc_init: + + movb 0(IV,%r9,1),%al + xorb (IN),%al + movb %al,(OUT) + movb %al,0(IV,%r9,1) + + leaq 1(IN),IN + leaq 1(OUT),OUT + + incl %r9d + decq LEN + cmpl $16,%r9d + je .Lcfb128_enc_update + cmpq $0,LEN + je .Lcfb128_enc_ret + + jmp .Lcfb128_enc_init + +.Lcfb128_enc_update: + + movl $0,%r9d + + # Get Address + leaq SBOX4X_MASK(%rip),ADDR + +.Lcfb128_enc_loop: + + cmpq $0,LEN + je .Lcfb128_enc_ret + + movl $0,%r9d + + # Load IV + movl (IV),W0 + movl 4(IV),W1 + movl 8(IV),W2 + movl 12(IV),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Results + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + movl W3,(IV) + movl W2,4(IV) + movl W1,8(IV) + movl W0,12(IV) + + cmpq $16,LEN + jl .Lcfb128_enc_final + + xorl (IN),W3 + xorl 4(IN),W2 + xorl 8(IN),W1 + xorl 12(IN),W0 + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + movl W3,(IV) + movl W2,4(IV) + movl W1,8(IV) + movl W0,12(IV) + + leaq 16(IN),IN + leaq 16(OUT),OUT + subq $16,LEN + + jmp .Lcfb128_enc_loop + +.Lcfb128_enc_final: + + movb 0(IV,%r9,1),%al + xorb (IN),%al + movb %al,(OUT) + movb %al,0(IV,%r9,1) + + leaq 1(IN),IN + leaq 1(OUT),OUT + + incl %r9d + decq LEN + jnz .Lcfb128_enc_final + +.Lcfb128_enc_ret: + + CLEAR_CONTEXT + + # Restore Registers + movq (%rsp),%rbx + movq 8(%rsp),%rbp + movq 16(%rsp),%rax + movq 24(%rsp),%r10 + movq 32(%rsp),%r11 + movq 40(%rsp),%r12 + movq 48(%rsp),%r13 + movq 56(%rsp),%r14 + movq 64(%rsp),%r15 + addq $72,%rsp + + # Store Num + movl %r9d,(%rax) + + ret + .size SM4_CFB128_Encrypt, .-SM4_CFB128_Encrypt + +##### SM4-CFB DEC ##### + # void SM4_CFB128_Decrypt(const unsigned char *in, unsigned char *out, size_t len, const SM4_KEY *key, unsigned char *iv, int *num) + # in %rdi + # out %rsi + # len %rdx + # rk %rcx + # iv %r8 + # num %r9d + .globl SM4_CFB128_Decrypt + .type SM4_CFB128_Decrypt, @function + .align 64 + +SM4_CFB128_Decrypt: + + # Store Registers + subq $72,%rsp + movq %rbx,(%rsp) + movq %rbp,8(%rsp) + movq %r9,16(%rsp) + movq %r10,24(%rsp) + movq %r11,32(%rsp) + movq %r12,40(%rsp) + movq %r13,48(%rsp) + movq %r14,56(%rsp) + movq %r15,64(%rsp) + + # Load Num + movl (%r9),%r9d + cmpl $0,%r9d + je .Lcfb128_dec_update + +.Lcfb128_dec_init: + + movb 0(IV,%r9,1),%al + movb (IN),%bl + xorb %bl,%al + movb %al,(OUT) + movb %bl,0(IV,%r9,1) + + leaq 1(IN),IN + leaq 1(OUT),OUT + + incl %r9d + decq LEN + cmpl $16,%r9d + je .Lcfb128_dec_update + cmpq $0,LEN + je .Lcfb128_dec_ret + + jmp .Lcfb128_dec_init + +.Lcfb128_dec_update: + + # Get Address + leaq SBOX4X_MASK(%rip),ADDR + + movl $0,%r9d + + cmpq $256,LEN + jl .Lcfb128_dec + +.Lcfb128_dec16: + + vmovdqu (IV),TMP0x + vmovdqu (IN),TMP1x + vinserti128 $1,TMP1x,TMP0,TMP0 + vmovdqu 240(IN),TMP2x + vmovdqu TMP2x,(IV) + + vmovdqu TMP0,X0 + vmovdqu 16(IN),X1 + vmovdqu 32+16(IN),X2 + vmovdqu 64+16(IN),X3 + vmovdqu 96+16(IN),Y0 + vmovdqu 128+16(IN),Y1 + vmovdqu 160+16(IN),Y2 + vmovdqu 192+16(IN),Y3 + + SM4_CRYPT_BLOCK16 + XOR_DATA + STORE_RESULTS + + leaq 256(IN),IN + leaq 256(OUT),OUT + subq $256,LEN + cmpq $256,LEN + jl .Lcfb128_dec16_ret + jmp .Lcfb128_dec16 + +.Lcfb128_dec16_ret: + + vzeroall + +.Lcfb128_dec: + + cmpq $0,LEN + je .Lcfb128_dec_ret + +.Lcfb128_dec1: + + # Load IV + movl (IV),W0 + movl 4(IV),W1 + movl 8(IV),W2 + movl 12(IV),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Results + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + movl W3,(IV) + movl W2,4(IV) + movl W1,8(IV) + movl W0,12(IV) + + cmpq $16,LEN + jl .Lcfb128_dec_final + + movq (IN),%rbx + movq %rbx,(IV) + movq 8(IN),%rbx + movq %rbx,8(IV) + xorq %rbx,%rbx + + xorl (IN),W3 + xorl 4(IN),W2 + xorl 8(IN),W1 + xorl 12(IN),W0 + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + leaq 16(IN),IN + leaq 16(OUT),OUT + subq $16,LEN + cmpq $0,LEN + je .Lcfb128_dec_ret + jmp .Lcfb128_dec1 + +.Lcfb128_dec_final: + + movb 0(IV,%r9,1),%al + movb (IN),%bl + xorb %bl,%al + movb %al,(OUT) + movb %bl,0(IV,%r9,1) + + leaq 1(IN),IN + leaq 1(OUT),OUT + + incl %r9d + decq LEN + jnz .Lcfb128_dec_final + +.Lcfb128_dec_ret: + + CLEAR_CONTEXT + + # Restore Registers + movq (%rsp),%rbx + movq 8(%rsp),%rbp + movq 16(%rsp),%rax + movq 24(%rsp),%r10 + movq 32(%rsp),%r11 + movq 40(%rsp),%r12 + movq 48(%rsp),%r13 + movq 56(%rsp),%r14 + movq 64(%rsp),%r15 + addq $72,%rsp + + # Store Num + movl %r9d,(%rax) + + ret + .size SM4_CFB128_Decrypt, .-SM4_CFB128_Decrypt + +##### SM4-OFB ##### + # void SM4_OFB_Encrypt(const unsigned char *in, unsigned char *out, size_t len, const SM4_KEY *key, unsigned char *iv, int *num) + # in %rdi + # out %rsi + # len %rdx + # rk %rcx + # iv %r8 + # num %r9d + .globl SM4_OFB_Encrypt + .type SM4_OFB_Encrypt, @function + .align 64 + +SM4_OFB_Encrypt: + + # Store Registers + subq $72,%rsp + movq %rbx,(%rsp) + movq %rbp,8(%rsp) + movq %r9,16(%rsp) + movq %r10,24(%rsp) + movq %r11,32(%rsp) + movq %r12,40(%rsp) + movq %r13,48(%rsp) + movq %r14,56(%rsp) + movq %r15,64(%rsp) + + # Load Num + movl (%r9),%r9d + cmpl $0,%r9d + jz .Lofb128_enc_update + +.Lofb128_enc_init: + + movb 0(IV,%r9,1),%al + xorb (IN),%al + movb %al,(OUT) + + leaq 1(IN),IN + leaq 1(OUT),OUT + + incl %r9d + decq LEN + cmpl $16,%r9d + je .Lofb128_enc_update + cmpq $0,LEN + je .Lofb128_enc_ret + + jmp .Lofb128_enc_init + +.Lofb128_enc_update: + + movl $0,%r9d + + # Get Address + leaq SBOX4X_MASK(%rip),ADDR + +.Lofb128_enc_loop: + + cmpq $0,LEN + je .Lofb128_enc_ret + + # Load IV + movl (IV),W0 + movl 4(IV),W1 + movl 8(IV),W2 + movl 12(IV),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Results + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + movl W3,(IV) + movl W2,4(IV) + movl W1,8(IV) + movl W0,12(IV) + + cmpq $16,LEN + jl .Lofb128_enc_final + + xorl (IN),W3 + xorl 4(IN),W2 + xorl 8(IN),W1 + xorl 12(IN),W0 + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + leaq 16(IN),IN + leaq 16(OUT),OUT + subq $16,LEN + + jmp .Lofb128_enc_loop + +.Lofb128_enc_final: + + movb 0(IV,%r9,1),%al + xorb (IN),%al + movb %al,(OUT) + + leaq 1(IN),IN + leaq 1(OUT),OUT + + incl %r9d + decq LEN + jnz .Lofb128_enc_final + +.Lofb128_enc_ret: + + CLEAR_CONTEXT + + # Restore Registers + movq (%rsp),%rbx + movq 8(%rsp),%rbp + movq 16(%rsp),%rax + movq 24(%rsp),%r10 + movq 32(%rsp),%r11 + movq 40(%rsp),%r12 + movq 48(%rsp),%r13 + movq 56(%rsp),%r14 + movq 64(%rsp),%r15 + addq $72,%rsp + + # Store Num + movl %r9d,(%rax) + + ret + .size SM4_OFB_Encrypt, .-SM4_OFB_Encrypt + +##### SM4-CTR32 ##### +# NOTE: the IV/counter CTR mode is big-endian. +.align 64 +.Lmovbe12: +.byte 0,1,2,3,4,5,6,7,8,9,10,11,15,14,13,12,0,1,2,3,4,5,6,7,8,9,10,11,15,14,13,12 +.Lone: +.long 0,0,0,1 + +.macro INCREMENT_COUNTER + movbe 12(IV),%ebx + incl %ebx + movbe %ebx,12(IV) +.endm + +.macro LOAD_ECOUNT_BUF SINK + vpaddd TMP1x,TMP2x,TMP3x + vpaddd TMP1x,TMP3x,TMP4x + vinserti128 $1,TMP3x,TMP2,TMP2 + vpshufb TMP0,TMP2,TMP2 + vmovdqa TMP2,\SINK + vmovdqa TMP4x,TMP2x +.endm + +.macro LOAD_ECOUNT_BUF_ALL + vmovdqa .Lmovbe12(%rip),TMP0 + vmovdqa .Lone(%rip),TMP1x + vmovdqu (IV),TMP2x + vpshufb TMP0x,TMP2x,TMP2x + LOAD_ECOUNT_BUF X0 + LOAD_ECOUNT_BUF X1 + LOAD_ECOUNT_BUF X2 + LOAD_ECOUNT_BUF X3 + LOAD_ECOUNT_BUF Y0 + LOAD_ECOUNT_BUF Y1 + LOAD_ECOUNT_BUF Y2 + LOAD_ECOUNT_BUF Y3 + vpshufb TMP0x,TMP2x,TMP2x + vmovdqu TMP2x,(IV) +.endm + + # void SM4_CTR_EncryptBlocks(const unsigned char *in, unsigned char *out, size_t blocks, const SM4_KEY *key, const unsigned char *iv) + # in %rdi + # out %rsi + # blocks %rdx + # rk %rcx + # iv %r8 + .globl SM4_CTR_EncryptBlocks + .type SM4_CTR_EncryptBlocks, @function + .align 64 + +SM4_CTR_EncryptBlocks: + + # Get Address + leaq SBOX4X_MASK(%rip),ADDR + + # Store Registers + subq $88,%rsp + movq %rbx,(%rsp) + movq %rbp,8(%rsp) + movq %r8,16(%rsp) + movq %r9,24(%rsp) + movq %r10,32(%rsp) + movq %r11,40(%rsp) + movq %r12,48(%rsp) + movq %r13,56(%rsp) + movq %r14,64(%rsp) + movq %r15,72(%rsp) + movq %rdx,80(%rsp) + + cmpq $16,BLOCKS + jl .Lctr32_enc + +.Lctr32_enc16: + + LOAD_ECOUNT_BUF_ALL + SM4_CRYPT_BLOCK16 + XOR_DATA + STORE_RESULTS + + leaq 256(IN),IN + leaq 256(OUT),OUT + subq $16,BLOCKS + cmpq $16,BLOCKS + jl .Lctr32_enc16_ret + jmp .Lctr32_enc16 + +.Lctr32_enc16_ret: + + vzeroall + +.Lctr32_enc: + + cmpq $0,BLOCKS + je .Lctr32_ret + + # Load IV + movl (IV),W0 + movl 4(IV),W1 + movl 8(IV),W2 + movl 12(IV),W3 + + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + # Serial Rounds + SM4_SERIAL_ROUNDS + + # Store Results + bswap W0 + bswap W1 + bswap W2 + bswap W3 + + xorl (IN),W3 + xorl 4(IN),W2 + xorl 8(IN),W1 + xorl 12(IN),W0 + + movl W3,(OUT) + movl W2,4(OUT) + movl W1,8(OUT) + movl W0,12(OUT) + + leaq 16(IN),IN + leaq 16(OUT),OUT + decq BLOCKS + + INCREMENT_COUNTER + + jmp .Lctr32_enc + +.Lctr32_ret: + + CLEAR_CONTEXT + + # Restore Registers + movq (%rsp),%rbx + movq 8(%rsp),%rbp + movq 16(%rsp),%r8 + movq 24(%rsp),%r9 + movq 32(%rsp),%r10 + movq 40(%rsp),%r11 + movq 48(%rsp),%r12 + movq 56(%rsp),%r13 + movq 64(%rsp),%r14 + movq 72(%rsp),%r15 + movq 80(%rsp),%rdx + addq $88,%rsp + + ret + .size SM4_CTR_EncryptBlocks, .-SM4_CTR_EncryptBlocks + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_setkey_armv8.S b/crypto/sm4/src/asm/crypt_sm4_setkey_armv8.S new file mode 100644 index 00000000..ab7ca76e --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_setkey_armv8.S @@ -0,0 +1,191 @@ +/* + * 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. + */ +#ifdef HITLS_CRYPTO_SM4 + +#define VTMP0 V8 +#define VTMP1 V9 +#define VTMP2 V10 + +#define DATA0 V16 + +#define MaskV v26 +#define TAHMatV v27 +#define TALMatV v28 +#define ATAHMatV v29 +#define ATALMatV v30 +#define ANDMaskV v31 + +#define MaskQ q26 +#define TAHMatQ q27 +#define TALMatQ q28 +#define ATAHMatQ q29 +#define ATALMatQ q30 +#define ANDMaskQ q31 + +#ifndef HITLS_BIG_ENDIAN + #define REV32_EQ(DST, SRC) \ + rev32 DST.16b,DST.16b ; +#else + #define REV32_EQ(DST, SRC) \ + /*rev32 eq is null in armeb */ ; +#endif + +#define LOAD_SBOX_MATRIX() \ + ldr MaskQ, =0x0306090c0f0205080b0e0104070a0d00 ; \ + ldr TAHMatQ, =0x22581a6002783a4062185a2042387a00 ; \ + ldr TALMatQ, =0xc10bb67c4a803df715df62a89e54e923 ; \ + ldr ATAHMatQ, =0x1407c6d56c7fbeadb9aa6b78c1d21300 ; \ + ldr ATALMatQ, =0xe383c1a1fe9edcbc6404462679195b3b ; \ + ldr ANDMaskQ, =0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f ; + + +/* matrix multiplication Mat*x = (lowerMat*x) ^ (higherMat*x) */ +#define MUL_MATRIX(X, HIGHERMAT, LOWERMAT, TMP) \ + ushr TMP.16b, X.16b, 4 ; \ + and X.16b, X.16b, ANDMaskV.16b ; \ + tbl X.16b, {LOWERMAT.16b}, X.16b ; \ + tbl TMP.16b, {HIGHERMAT.16b}, TMP.16b ; \ + eor X.16b, X.16b, TMP.16b ; + + +.arch armv8-a+crypto +.text + +.type vpsm4_ex_consts,%object +.align 7 +vpsm4_ex_consts: +.Lck: + .long 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269 + .long 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9 + .long 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249 + .long 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9 + .long 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229 + .long 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299 + .long 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209 + .long 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 +.Lfk: + .long 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc +.Lshuffles: + .long 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x03020100 + +.size vpsm4_ex_consts,.-vpsm4_ex_consts + +#define USER_KEY x0 +#define ROUND_KEY1 x1 +#define ENC1 w2 + +#define POINTER1 x5 +#define SCHEDULES x6 +#define WTMP w7 +#define ROUND_KEY2 w8 + +#define V_KEY v5 +#define V_FK v6 +#define V_MAP v7 + +/** + * void vpsm4_ex_set_key(const unsigned char *userKey, SM4_KEY *key, int enc); + * generate sm4 rounk key context + * USER_KEY => userKey; + * ROUND_KEY1 => key ; + */ +.type vpsm4_ex_set_key,%function +.align 4 +vpsm4_ex_set_key: + ld1 {V_KEY.4s},[USER_KEY] + LOAD_SBOX_MATRIX() + REV32_EQ(V_KEY,V_KEY) + adr POINTER1,.Lshuffles + ld1 {V_MAP.4s},[POINTER1] + adr POINTER1,.Lfk + ld1 {V_FK.4s},[POINTER1] + eor V_KEY.16b,V_KEY.16b,V_FK.16b + mov SCHEDULES,#32 + adr POINTER1,.Lck + movi VTMP0.16b,#64 + cbnz ENC1,1f + add ROUND_KEY1,ROUND_KEY1,124 +1: // loop + mov WTMP,V_KEY.s[1] + ldr ROUND_KEY2,[POINTER1],#4 + eor ROUND_KEY2,ROUND_KEY2,WTMP + mov WTMP,V_KEY.s[2] + eor ROUND_KEY2,ROUND_KEY2,WTMP + mov WTMP,V_KEY.s[3] + eor ROUND_KEY2,ROUND_KEY2,WTMP + + /* optimize sbox using AESE instruction */ + mov DATA0.s[0],ROUND_KEY2 + tbl VTMP0.16b, {DATA0.16b}, MaskV.16b + MUL_MATRIX(VTMP0, TAHMatV, TALMatV, VTMP2) + eor VTMP1.16b, VTMP1.16b, VTMP1.16b + aese VTMP0.16b,VTMP1.16b + MUL_MATRIX(VTMP0, ATAHMatV, ATALMatV, VTMP2) + mov WTMP,VTMP0.s[0] + + /* linear transformation */ + eor ROUND_KEY2,WTMP,WTMP,ror #19 + eor ROUND_KEY2,ROUND_KEY2,WTMP,ror #9 + mov WTMP,V_KEY.s[0] + eor ROUND_KEY2,ROUND_KEY2,WTMP + mov V_KEY.s[0],ROUND_KEY2 + cbz ENC1,2f + str ROUND_KEY2,[ROUND_KEY1],#4 + b 3f +2: // set encrypt key + str ROUND_KEY2,[ROUND_KEY1],#-4 +3: // final + tbl V_KEY.16b,{V_KEY.16b},V_MAP.16b + subs SCHEDULES,SCHEDULES,#1 + b.ne 1b + /*clear register for temp key */ + eor V_KEY.16b, V_KEY.16b, V_KEY.16b + eor ROUND_KEY2, ROUND_KEY2, ROUND_KEY2 + ret +.size vpsm4_ex_set_key,.-vpsm4_ex_set_key + +/** + * void Vpsm4SetEncryptKey(const unsigned char *userKey, SM4_KEY *key); + * generate SM4 encrypt round KEY context + * x0 => userKey; x1 => key + */ +.globl Vpsm4SetEncryptKey +.type Vpsm4SetEncryptKey,%function +.align 5 +Vpsm4SetEncryptKey: + stp x29,x30,[sp,#-16]! + mov w2,1 + bl vpsm4_ex_set_key + ldp x29,x30,[sp],#16 + ret +.size Vpsm4SetEncryptKey,.-Vpsm4SetEncryptKey + +/** + * void Vpsm4SetDecryptKey(const unsigned char *userKey, SM4_KEY *key); + * generate SM4 decryption round KEY context + * x0 => userKey; x1 => key + */ +.globl Vpsm4SetDecryptKey +.type Vpsm4SetDecryptKey,%function +.align 5 +Vpsm4SetDecryptKey: + stp x29,x30,[sp,#-16]! + mov w2,0 + bl vpsm4_ex_set_key + ldp x29,x30,[sp],#16 + ret +.size Vpsm4SetDecryptKey,.-Vpsm4SetDecryptKey + +#endif \ No newline at end of file diff --git a/crypto/sm4/src/asm/crypt_sm4_setkey_x86_64.S b/crypto/sm4/src/asm/crypt_sm4_setkey_x86_64.S new file mode 100644 index 00000000..ddf03c97 --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_setkey_x86_64.S @@ -0,0 +1,328 @@ +/* + * 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_SM4 + +.file "crypt_sm4_setkey_x86_64.S" +.text + + +.set X0, %r8d +.set X1, %r9d +.set X2, %r10d +.set X3, %r11d + +.set T0, %eax +.set T0BL, %al +.set T1, %ecx + +.set T0_64, %rax +.set T1_64, %rcx + +.set RK, %rdi +.set ADDR, %rsi +.set CK, %rdx + + +.macro SETKEY_ROUND RKey A0 A1 A2 A3 CK_ADDR No Offset + + #x4 = x1 ^ x2 ^ x3 ^ *(CK + i); + #x4 = S32(x4); + #x4 = x0 ^ L_Key32(x4); + #*(rk + i) = x4; + + #x4 = x1 ^ x2 ^ x3 ^ *(CK + i); + movl \No(\CK_ADDR), T0 + xorl \A1, T0 + xorl \A2, T0 + xorl \A3, T0 + + #x0 = x0 ^ (SBOX_KEY_0[x4 & 0xff]) ^ (SBOX_KEY_1[(x4 >> 8) & 0xff]) ^ (SBOX_KEY_2[(x4 >> 16) & 0xff]) ^ (SBOX_KEY_3[(x4 >> 24) & 0xff]); + movzbl T0BL, T1 + xorl (ADDR,T1_64,4), \A0 + shrl $8, T0 + movzbl T0BL, T1 + + xorl 1024(ADDR,T1_64,4), \A0 + shrl $8, T0 + movzbl T0BL, T1 + xorl 2048(ADDR,T1_64,4), \A0 + shrl $8, T0 + xorl 3072(ADDR,T0_64,4), \A0 + + #*(rk + i) = x4; + movl \A0, \Offset(\RKey) + +.endm + + + +##### SM4 SET ROUND KEY ##### + + # void SM4_SetKey(unsigned int *rk, const uint8_t *key) + # %rdi rk: round key ptr 128 bytes + # %rsi key: encryption key ptr 16 bytes + + .globl SM4_SetKey + .type SM4_SetKey, @function + .align 64 + +SM4_SetKey: + + ##### Load MK ##################### + movl (%rsi), X0 + movl 4(%rsi), X1 + movl 8(%rsi), X2 + movl 12(%rsi), X3 + bswap X0 + bswap X1 + bswap X2 + bswap X3 + + ###### Load SBOX ADDRESS ##### + leaq SBOX_KEY_X4(%rip), ADDR + leaq CK_NUM(%rip), CK + xorq T0_64, T0_64 + xorq T1_64, T1_64 + + ###### XOR FK ######################## + xorl $0xa3b1bac6, X0 + xorl $0x56aa3350, X1 + xorl $0x677d9197, X2 + xorl $0xb27022dc, X3 + + ###### ROUNDS ######################## + SETKEY_ROUND RK X0 X1 X2 X3 CK 0 0 + SETKEY_ROUND RK X1 X2 X3 X0 CK 4 4 + SETKEY_ROUND RK X2 X3 X0 X1 CK 8 8 + SETKEY_ROUND RK X3 X0 X1 X2 CK 12 12 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 16 16 + SETKEY_ROUND RK X1 X2 X3 X0 CK 20 20 + SETKEY_ROUND RK X2 X3 X0 X1 CK 24 24 + SETKEY_ROUND RK X3 X0 X1 X2 CK 28 28 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 32 32 + SETKEY_ROUND RK X1 X2 X3 X0 CK 36 36 + SETKEY_ROUND RK X2 X3 X0 X1 CK 40 40 + SETKEY_ROUND RK X3 X0 X1 X2 CK 44 44 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 48 48 + SETKEY_ROUND RK X1 X2 X3 X0 CK 52 52 + SETKEY_ROUND RK X2 X3 X0 X1 CK 56 56 + SETKEY_ROUND RK X3 X0 X1 X2 CK 60 60 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 64 64 + SETKEY_ROUND RK X1 X2 X3 X0 CK 68 68 + SETKEY_ROUND RK X2 X3 X0 X1 CK 72 72 + SETKEY_ROUND RK X3 X0 X1 X2 CK 76 76 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 80 80 + SETKEY_ROUND RK X1 X2 X3 X0 CK 84 84 + SETKEY_ROUND RK X2 X3 X0 X1 CK 88 88 + SETKEY_ROUND RK X3 X0 X1 X2 CK 92 92 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 96 96 + SETKEY_ROUND RK X1 X2 X3 X0 CK 100 100 + SETKEY_ROUND RK X2 X3 X0 X1 CK 104 104 + SETKEY_ROUND RK X3 X0 X1 X2 CK 108 108 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 112 112 + SETKEY_ROUND RK X1 X2 X3 X0 CK 116 116 + SETKEY_ROUND RK X2 X3 X0 X1 CK 120 120 + SETKEY_ROUND RK X3 X0 X1 X2 CK 124 124 + + ##### Clear Context ##### + xorl X0, X0 + xorl X1, X1 + xorl X2, X2 + xorl X3, X3 + xorl T0, T0 + xorl T1, T1 + + ret + .size SM4_SetKey, .-SM4_SetKey + +##### SM4 SET DEC ROUND KEY ##### + + # void SM4_SetDecKey(unsigned int *rk, const uint8_t *key) + # %rdi rk: round key ptr 128 bytes + # %rsi key: decryption key ptr 16 bytes + + .globl SM4_SetDecKey + .type SM4_SetDecKey, @function + .align 64 + +SM4_SetDecKey: + + ##### Load MK ##################### + movl (%rsi), X0 + movl 4(%rsi), X1 + movl 8(%rsi), X2 + movl 12(%rsi), X3 + bswap X0 + bswap X1 + bswap X2 + bswap X3 + + ###### Load SBOX ADDRESS ##### + leaq SBOX_KEY_X4(%rip), ADDR + leaq CK_NUM(%rip), CK + xorq T0_64, T0_64 + xorq T1_64, T1_64 + + ###### XOR FK ######################## + xorl $0xa3b1bac6, X0 + xorl $0x56aa3350, X1 + xorl $0x677d9197, X2 + xorl $0xb27022dc, X3 + + ###### ROUNDS ######################## + SETKEY_ROUND RK X0 X1 X2 X3 CK 0 124 + SETKEY_ROUND RK X1 X2 X3 X0 CK 4 120 + SETKEY_ROUND RK X2 X3 X0 X1 CK 8 116 + SETKEY_ROUND RK X3 X0 X1 X2 CK 12 112 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 16 108 + SETKEY_ROUND RK X1 X2 X3 X0 CK 20 104 + SETKEY_ROUND RK X2 X3 X0 X1 CK 24 100 + SETKEY_ROUND RK X3 X0 X1 X2 CK 28 96 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 32 92 + SETKEY_ROUND RK X1 X2 X3 X0 CK 36 88 + SETKEY_ROUND RK X2 X3 X0 X1 CK 40 84 + SETKEY_ROUND RK X3 X0 X1 X2 CK 44 80 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 48 76 + SETKEY_ROUND RK X1 X2 X3 X0 CK 52 72 + SETKEY_ROUND RK X2 X3 X0 X1 CK 56 68 + SETKEY_ROUND RK X3 X0 X1 X2 CK 60 64 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 64 60 + SETKEY_ROUND RK X1 X2 X3 X0 CK 68 56 + SETKEY_ROUND RK X2 X3 X0 X1 CK 72 52 + SETKEY_ROUND RK X3 X0 X1 X2 CK 76 48 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 80 44 + SETKEY_ROUND RK X1 X2 X3 X0 CK 84 40 + SETKEY_ROUND RK X2 X3 X0 X1 CK 88 36 + SETKEY_ROUND RK X3 X0 X1 X2 CK 92 32 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 96 28 + SETKEY_ROUND RK X1 X2 X3 X0 CK 100 24 + SETKEY_ROUND RK X2 X3 X0 X1 CK 104 20 + SETKEY_ROUND RK X3 X0 X1 X2 CK 108 16 + + SETKEY_ROUND RK X0 X1 X2 X3 CK 112 12 + SETKEY_ROUND RK X1 X2 X3 X0 CK 116 8 + SETKEY_ROUND RK X2 X3 X0 X1 CK 120 4 + SETKEY_ROUND RK X3 X0 X1 X2 CK 124 0 + + ##### Clear Context ##### + xorl X0, X0 + xorl X1, X1 + xorl X2, X2 + xorl X3, X3 + xorl T0, T0 + xorl T1, T1 + + ret + .size SM4_SetDecKey, .-SM4_SetDecKey + + + +##### SBOX Extend Tables (1 Table, 256*4 bytes) for round key: SBOX_KEY_0, SBOX_KEY_1, SBOX_KEY_2, SBOX_KEY_3 ##### + .section .rodata + .align 64 + +CK_NUM: +.long 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9 +.long 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 + +SBOX_KEY_X4: +#SBOX_KEY_0: +.long 0x6b1ac0d6, 0x48120090, 0x749d20e9, 0x7f1fc0fe, 0x661980cc, 0x709c20e1, 0x1e87a03d, 0x5b96e0b7, 0x0b02c016, 0x5b16c0b6, 0x0a028014, 0x611840c2, 0x14050028, 0x7d9f60fb, 0x1605802c, 0x0280a005 +.long 0x1585602b, 0x338ce067, 0x4d13409a, 0x3b0ec076, 0x1505402a, 0x5f17c0be, 0x02008004, 0x619860c3, 0x551540aa, 0x22088044, 0x09826013, 0x1304c026, 0x24892049, 0x4310c086, 0x0300c006, 0x4c932099 +.long 0x4e13809c, 0x21084042, 0x280a0050, 0x7a1e80f4, 0x48922091, 0x779de0ef, 0x4c130098, 0x3d0f407a, 0x19866033, 0x2a0a8054, 0x0581600b, 0x21886043, 0x769da0ed, 0x6799e0cf, 0x561580ac, 0x310c4062 +.long 0x721c80e4, 0x599660b3, 0x0e03801c, 0x549520a9, 0x649920c9, 0x04010008, 0x741d00e8, 0x4a92a095, 0x40100080, 0x6f9be0df, 0x4a128094, 0x7d1f40fa, 0x3a8ea075, 0x4791e08f, 0x1f87e03f, 0x5314c0a6 +.long 0x2388e047, 0x0380e007, 0x5394e0a7, 0x7e1f80fc, 0x799e60f3, 0x398e6073, 0x0b82e017, 0x5d1740ba, 0x41906083, 0x2c8b2059, 0x1e07803c, 0x0c832019, 0x731cc0e6, 0x4290a085, 0x2789e04f, 0x541500a8 +.long 0x340d0068, 0x358d606b, 0x40902081, 0x591640b2, 0x388e2071, 0x320c8064, 0x6d1b40da, 0x4591608b, 0x7c1f00f8, 0x759d60eb, 0x0781e00f, 0x2589604b, 0x380e0070, 0x2b0ac056, 0x4e93a09d, 0x1a86a035 +.long 0x0f03c01e, 0x12048024, 0x0701c00e, 0x2f0bc05e, 0x318c6063, 0x2c0b0058, 0x689a20d1, 0x511440a2, 0x1284a025, 0x11044022, 0x3e0f807c, 0x1d87603b, 0x00802001, 0x10842021, 0x3c0f0078, 0x4390e087 +.long 0x6a1a80d4, 0x0, 0x2308c046, 0x2b8ae057, 0x4f93e09f, 0x699a60d3, 0x1384e027, 0x290a4052, 0x2609804c, 0x1b06c036, 0x01004002, 0x739ce0e7, 0x501400a0, 0x621880c4, 0x641900c8, 0x4f13c09e +.long 0x751d40ea, 0x5f97e0bf, 0x4511408a, 0x691a40d2, 0x20080040, 0x6398e0c7, 0x1c070038, 0x5a96a0b5, 0x519460a3, 0x7b9ee0f7, 0x791e40f2, 0x6719c0ce, 0x7c9f20f9, 0x308c2061, 0x0a82a015, 0x509420a1 +.long 0x701c00e0, 0x5715c0ae, 0x2e8ba05d, 0x521480a4, 0x4d93609b, 0x1a068034, 0x0d03401a, 0x2a8aa055, 0x5695a0ad, 0x49926093, 0x19064032, 0x18060030, 0x7a9ea0f5, 0x4611808c, 0x589620b1, 0x719c60e3 +.long 0x0e83a01d, 0x7b1ec0f6, 0x711c40e2, 0x1705c02e, 0x41104082, 0x330cc066, 0x651940ca, 0x300c0060, 0x601800c0, 0x14852029, 0x11846023, 0x559560ab, 0x0681a00d, 0x298a6053, 0x2709c04e, 0x378de06f +.long 0x6a9aa0d5, 0x6d9b60db, 0x1b86e037, 0x2288a045, 0x6f1bc0de, 0x7e9fa0fd, 0x4711c08e, 0x1785e02f, 0x01806003, 0x7f9fe0ff, 0x350d406a, 0x390e4072, 0x368da06d, 0x360d806c, 0x2d8b605b, 0x288a2051 +.long 0x4691a08d, 0x0d83601b, 0x5795e0af, 0x49124092, 0x5d9760bb, 0x6e9ba0dd, 0x5e1780bc, 0x3f8fe07f, 0x08822011, 0x6c9b20d9, 0x2e0b805c, 0x20882041, 0x0f83e01f, 0x08020010, 0x2d0b405a, 0x6c1b00d8 +.long 0x0501400a, 0x609820c1, 0x18862031, 0x44110088, 0x5294a0a5, 0x6699a0cd, 0x3d8f607b, 0x5e97a0bd, 0x1685a02d, 0x3a0e8074, 0x681a00d0, 0x09024012, 0x5c1700b8, 0x729ca0e5, 0x5a1680b4, 0x581600b0 +.long 0x44912089, 0x348d2069, 0x4b92e097, 0x2509404a, 0x0601800c, 0x4b12c096, 0x3b8ee077, 0x3f0fc07e, 0x328ca065, 0x5c9720b9, 0x789e20f1, 0x04812009, 0x6298a0c5, 0x370dc06e, 0x6318c0c6, 0x42108084 +.long 0x0c030018, 0x781e00f0, 0x3e8fa07d, 0x761d80ec, 0x1d07403a, 0x6e1b80dc, 0x2689a04d, 0x10040020, 0x3c8f2079, 0x771dc0ee, 0x2f8be05f, 0x1f07c03e, 0x6b9ae0d7, 0x659960cb, 0x1c872039, 0x24090048 + +#SBOX_KEY_1: +.long 0x1ac0d66b, 0x12009048, 0x9d20e974, 0x1fc0fe7f, 0x1980cc66, 0x9c20e170, 0x87a03d1e, 0x96e0b75b, 0x02c0160b, 0x16c0b65b, 0x0280140a, 0x1840c261, 0x05002814, 0x9f60fb7d, 0x05802c16, 0x80a00502 +.long 0x85602b15, 0x8ce06733, 0x13409a4d, 0x0ec0763b, 0x05402a15, 0x17c0be5f, 0x00800402, 0x9860c361, 0x1540aa55, 0x08804422, 0x82601309, 0x04c02613, 0x89204924, 0x10c08643, 0x00c00603, 0x9320994c +.long 0x13809c4e, 0x08404221, 0x0a005028, 0x1e80f47a, 0x92209148, 0x9de0ef77, 0x1300984c, 0x0f407a3d, 0x86603319, 0x0a80542a, 0x81600b05, 0x88604321, 0x9da0ed76, 0x99e0cf67, 0x1580ac56, 0x0c406231 +.long 0x1c80e472, 0x9660b359, 0x03801c0e, 0x9520a954, 0x9920c964, 0x01000804, 0x1d00e874, 0x92a0954a, 0x10008040, 0x9be0df6f, 0x1280944a, 0x1f40fa7d, 0x8ea0753a, 0x91e08f47, 0x87e03f1f, 0x14c0a653 +.long 0x88e04723, 0x80e00703, 0x94e0a753, 0x1f80fc7e, 0x9e60f379, 0x8e607339, 0x82e0170b, 0x1740ba5d, 0x90608341, 0x8b20592c, 0x07803c1e, 0x8320190c, 0x1cc0e673, 0x90a08542, 0x89e04f27, 0x1500a854 +.long 0x0d006834, 0x8d606b35, 0x90208140, 0x1640b259, 0x8e207138, 0x0c806432, 0x1b40da6d, 0x91608b45, 0x1f00f87c, 0x9d60eb75, 0x81e00f07, 0x89604b25, 0x0e007038, 0x0ac0562b, 0x93a09d4e, 0x86a0351a +.long 0x03c01e0f, 0x04802412, 0x01c00e07, 0x0bc05e2f, 0x8c606331, 0x0b00582c, 0x9a20d168, 0x1440a251, 0x84a02512, 0x04402211, 0x0f807c3e, 0x87603b1d, 0x80200100, 0x84202110, 0x0f00783c, 0x90e08743 +.long 0x1a80d46a, 0x0, 0x08c04623, 0x8ae0572b, 0x93e09f4f, 0x9a60d369, 0x84e02713, 0x0a405229, 0x09804c26, 0x06c0361b, 0x00400201, 0x9ce0e773, 0x1400a050, 0x1880c462, 0x1900c864, 0x13c09e4f +.long 0x1d40ea75, 0x97e0bf5f, 0x11408a45, 0x1a40d269, 0x08004020, 0x98e0c763, 0x0700381c, 0x96a0b55a, 0x9460a351, 0x9ee0f77b, 0x1e40f279, 0x19c0ce67, 0x9f20f97c, 0x8c206130, 0x82a0150a, 0x9420a150 +.long 0x1c00e070, 0x15c0ae57, 0x8ba05d2e, 0x1480a452, 0x93609b4d, 0x0680341a, 0x03401a0d, 0x8aa0552a, 0x95a0ad56, 0x92609349, 0x06403219, 0x06003018, 0x9ea0f57a, 0x11808c46, 0x9620b158, 0x9c60e371 +.long 0x83a01d0e, 0x1ec0f67b, 0x1c40e271, 0x05c02e17, 0x10408241, 0x0cc06633, 0x1940ca65, 0x0c006030, 0x1800c060, 0x85202914, 0x84602311, 0x9560ab55, 0x81a00d06, 0x8a605329, 0x09c04e27, 0x8de06f37 +.long 0x9aa0d56a, 0x9b60db6d, 0x86e0371b, 0x88a04522, 0x1bc0de6f, 0x9fa0fd7e, 0x11c08e47, 0x85e02f17, 0x80600301, 0x9fe0ff7f, 0x0d406a35, 0x0e407239, 0x8da06d36, 0x0d806c36, 0x8b605b2d, 0x8a205128 +.long 0x91a08d46, 0x83601b0d, 0x95e0af57, 0x12409249, 0x9760bb5d, 0x9ba0dd6e, 0x1780bc5e, 0x8fe07f3f, 0x82201108, 0x9b20d96c, 0x0b805c2e, 0x88204120, 0x83e01f0f, 0x02001008, 0x0b405a2d, 0x1b00d86c +.long 0x01400a05, 0x9820c160, 0x86203118, 0x11008844, 0x94a0a552, 0x99a0cd66, 0x8f607b3d, 0x97a0bd5e, 0x85a02d16, 0x0e80743a, 0x1a00d068, 0x02401209, 0x1700b85c, 0x9ca0e572, 0x1680b45a, 0x1600b058 +.long 0x91208944, 0x8d206934, 0x92e0974b, 0x09404a25, 0x01800c06, 0x12c0964b, 0x8ee0773b, 0x0fc07e3f, 0x8ca06532, 0x9720b95c, 0x9e20f178, 0x81200904, 0x98a0c562, 0x0dc06e37, 0x18c0c663, 0x10808442 +.long 0x0300180c, 0x1e00f078, 0x8fa07d3e, 0x1d80ec76, 0x07403a1d, 0x1b80dc6e, 0x89a04d26, 0x04002010, 0x8f20793c, 0x1dc0ee77, 0x8be05f2f, 0x07c03e1f, 0x9ae0d76b, 0x9960cb65, 0x8720391c, 0x09004824 + +#SBOX_KEY_2: +.long 0xc0d66b1a, 0x00904812, 0x20e9749d, 0xc0fe7f1f, 0x80cc6619, 0x20e1709c, 0xa03d1e87, 0xe0b75b96, 0xc0160b02, 0xc0b65b16, 0x80140a02, 0x40c26118, 0x00281405, 0x60fb7d9f, 0x802c1605, 0xa0050280 +.long 0x602b1585, 0xe067338c, 0x409a4d13, 0xc0763b0e, 0x402a1505, 0xc0be5f17, 0x80040200, 0x60c36198, 0x40aa5515, 0x80442208, 0x60130982, 0xc0261304, 0x20492489, 0xc0864310, 0xc0060300, 0x20994c93 +.long 0x809c4e13, 0x40422108, 0x0050280a, 0x80f47a1e, 0x20914892, 0xe0ef779d, 0x00984c13, 0x407a3d0f, 0x60331986, 0x80542a0a, 0x600b0581, 0x60432188, 0xa0ed769d, 0xe0cf6799, 0x80ac5615, 0x4062310c +.long 0x80e4721c, 0x60b35996, 0x801c0e03, 0x20a95495, 0x20c96499, 0x00080401, 0x00e8741d, 0xa0954a92, 0x00804010, 0xe0df6f9b, 0x80944a12, 0x40fa7d1f, 0xa0753a8e, 0xe08f4791, 0xe03f1f87, 0xc0a65314 +.long 0xe0472388, 0xe0070380, 0xe0a75394, 0x80fc7e1f, 0x60f3799e, 0x6073398e, 0xe0170b82, 0x40ba5d17, 0x60834190, 0x20592c8b, 0x803c1e07, 0x20190c83, 0xc0e6731c, 0xa0854290, 0xe04f2789, 0x00a85415 +.long 0x0068340d, 0x606b358d, 0x20814090, 0x40b25916, 0x2071388e, 0x8064320c, 0x40da6d1b, 0x608b4591, 0x00f87c1f, 0x60eb759d, 0xe00f0781, 0x604b2589, 0x0070380e, 0xc0562b0a, 0xa09d4e93, 0xa0351a86 +.long 0xc01e0f03, 0x80241204, 0xc00e0701, 0xc05e2f0b, 0x6063318c, 0x00582c0b, 0x20d1689a, 0x40a25114, 0xa0251284, 0x40221104, 0x807c3e0f, 0x603b1d87, 0x20010080, 0x20211084, 0x00783c0f, 0xe0874390 +.long 0x80d46a1a, 0x0, 0xc0462308, 0xe0572b8a, 0xe09f4f93, 0x60d3699a, 0xe0271384, 0x4052290a, 0x804c2609, 0xc0361b06, 0x40020100, 0xe0e7739c, 0x00a05014, 0x80c46218, 0x00c86419, 0xc09e4f13 +.long 0x40ea751d, 0xe0bf5f97, 0x408a4511, 0x40d2691a, 0x00402008, 0xe0c76398, 0x00381c07, 0xa0b55a96, 0x60a35194, 0xe0f77b9e, 0x40f2791e, 0xc0ce6719, 0x20f97c9f, 0x2061308c, 0xa0150a82, 0x20a15094 +.long 0x00e0701c, 0xc0ae5715, 0xa05d2e8b, 0x80a45214, 0x609b4d93, 0x80341a06, 0x401a0d03, 0xa0552a8a, 0xa0ad5695, 0x60934992, 0x40321906, 0x00301806, 0xa0f57a9e, 0x808c4611, 0x20b15896, 0x60e3719c +.long 0xa01d0e83, 0xc0f67b1e, 0x40e2711c, 0xc02e1705, 0x40824110, 0xc066330c, 0x40ca6519, 0x0060300c, 0x00c06018, 0x20291485, 0x60231184, 0x60ab5595, 0xa00d0681, 0x6053298a, 0xc04e2709, 0xe06f378d +.long 0xa0d56a9a, 0x60db6d9b, 0xe0371b86, 0xa0452288, 0xc0de6f1b, 0xa0fd7e9f, 0xc08e4711, 0xe02f1785, 0x60030180, 0xe0ff7f9f, 0x406a350d, 0x4072390e, 0xa06d368d, 0x806c360d, 0x605b2d8b, 0x2051288a +.long 0xa08d4691, 0x601b0d83, 0xe0af5795, 0x40924912, 0x60bb5d97, 0xa0dd6e9b, 0x80bc5e17, 0xe07f3f8f, 0x20110882, 0x20d96c9b, 0x805c2e0b, 0x20412088, 0xe01f0f83, 0x00100802, 0x405a2d0b, 0x00d86c1b +.long 0x400a0501, 0x20c16098, 0x20311886, 0x00884411, 0xa0a55294, 0xa0cd6699, 0x607b3d8f, 0xa0bd5e97, 0xa02d1685, 0x80743a0e, 0x00d0681a, 0x40120902, 0x00b85c17, 0xa0e5729c, 0x80b45a16, 0x00b05816 +.long 0x20894491, 0x2069348d, 0xe0974b92, 0x404a2509, 0x800c0601, 0xc0964b12, 0xe0773b8e, 0xc07e3f0f, 0xa065328c, 0x20b95c97, 0x20f1789e, 0x20090481, 0xa0c56298, 0xc06e370d, 0xc0c66318, 0x80844210 +.long 0x00180c03, 0x00f0781e, 0xa07d3e8f, 0x80ec761d, 0x403a1d07, 0x80dc6e1b, 0xa04d2689, 0x00201004, 0x20793c8f, 0xc0ee771d, 0xe05f2f8b, 0xc03e1f07, 0xe0d76b9a, 0x60cb6599, 0x20391c87, 0x00482409 + +#SBOX_KEY_3: +.long 0xd66b1ac0, 0x90481200, 0xe9749d20, 0xfe7f1fc0, 0xcc661980, 0xe1709c20, 0x3d1e87a0, 0xb75b96e0, 0x160b02c0, 0xb65b16c0, 0x140a0280, 0xc2611840, 0x28140500, 0xfb7d9f60, 0x2c160580, 0x050280a0 +.long 0x2b158560, 0x67338ce0, 0x9a4d1340, 0x763b0ec0, 0x2a150540, 0xbe5f17c0, 0x04020080, 0xc3619860, 0xaa551540, 0x44220880, 0x13098260, 0x261304c0, 0x49248920, 0x864310c0, 0x060300c0, 0x994c9320 +.long 0x9c4e1380, 0x42210840, 0x50280a00, 0xf47a1e80, 0x91489220, 0xef779de0, 0x984c1300, 0x7a3d0f40, 0x33198660, 0x542a0a80, 0x0b058160, 0x43218860, 0xed769da0, 0xcf6799e0, 0xac561580, 0x62310c40 +.long 0xe4721c80, 0xb3599660, 0x1c0e0380, 0xa9549520, 0xc9649920, 0x08040100, 0xe8741d00, 0x954a92a0, 0x80401000, 0xdf6f9be0, 0x944a1280, 0xfa7d1f40, 0x753a8ea0, 0x8f4791e0, 0x3f1f87e0, 0xa65314c0 +.long 0x472388e0, 0x070380e0, 0xa75394e0, 0xfc7e1f80, 0xf3799e60, 0x73398e60, 0x170b82e0, 0xba5d1740, 0x83419060, 0x592c8b20, 0x3c1e0780, 0x190c8320, 0xe6731cc0, 0x854290a0, 0x4f2789e0, 0xa8541500 +.long 0x68340d00, 0x6b358d60, 0x81409020, 0xb2591640, 0x71388e20, 0x64320c80, 0xda6d1b40, 0x8b459160, 0xf87c1f00, 0xeb759d60, 0x0f0781e0, 0x4b258960, 0x70380e00, 0x562b0ac0, 0x9d4e93a0, 0x351a86a0 +.long 0x1e0f03c0, 0x24120480, 0x0e0701c0, 0x5e2f0bc0, 0x63318c60, 0x582c0b00, 0xd1689a20, 0xa2511440, 0x251284a0, 0x22110440, 0x7c3e0f80, 0x3b1d8760, 0x01008020, 0x21108420, 0x783c0f00, 0x874390e0 +.long 0xd46a1a80, 0x0, 0x462308c0, 0x572b8ae0, 0x9f4f93e0, 0xd3699a60, 0x271384e0, 0x52290a40, 0x4c260980, 0x361b06c0, 0x02010040, 0xe7739ce0, 0xa0501400, 0xc4621880, 0xc8641900, 0x9e4f13c0 +.long 0xea751d40, 0xbf5f97e0, 0x8a451140, 0xd2691a40, 0x40200800, 0xc76398e0, 0x381c0700, 0xb55a96a0, 0xa3519460, 0xf77b9ee0, 0xf2791e40, 0xce6719c0, 0xf97c9f20, 0x61308c20, 0x150a82a0, 0xa1509420 +.long 0xe0701c00, 0xae5715c0, 0x5d2e8ba0, 0xa4521480, 0x9b4d9360, 0x341a0680, 0x1a0d0340, 0x552a8aa0, 0xad5695a0, 0x93499260, 0x32190640, 0x30180600, 0xf57a9ea0, 0x8c461180, 0xb1589620, 0xe3719c60 +.long 0x1d0e83a0, 0xf67b1ec0, 0xe2711c40, 0x2e1705c0, 0x82411040, 0x66330cc0, 0xca651940, 0x60300c00, 0xc0601800, 0x29148520, 0x23118460, 0xab559560, 0x0d0681a0, 0x53298a60, 0x4e2709c0, 0x6f378de0 +.long 0xd56a9aa0, 0xdb6d9b60, 0x371b86e0, 0x452288a0, 0xde6f1bc0, 0xfd7e9fa0, 0x8e4711c0, 0x2f1785e0, 0x03018060, 0xff7f9fe0, 0x6a350d40, 0x72390e40, 0x6d368da0, 0x6c360d80, 0x5b2d8b60, 0x51288a20 +.long 0x8d4691a0, 0x1b0d8360, 0xaf5795e0, 0x92491240, 0xbb5d9760, 0xdd6e9ba0, 0xbc5e1780, 0x7f3f8fe0, 0x11088220, 0xd96c9b20, 0x5c2e0b80, 0x41208820, 0x1f0f83e0, 0x10080200, 0x5a2d0b40, 0xd86c1b00 +.long 0x0a050140, 0xc1609820, 0x31188620, 0x88441100, 0xa55294a0, 0xcd6699a0, 0x7b3d8f60, 0xbd5e97a0, 0x2d1685a0, 0x743a0e80, 0xd0681a00, 0x12090240, 0xb85c1700, 0xe5729ca0, 0xb45a1680, 0xb0581600 +.long 0x89449120, 0x69348d20, 0x974b92e0, 0x4a250940, 0x0c060180, 0x964b12c0, 0x773b8ee0, 0x7e3f0fc0, 0x65328ca0, 0xb95c9720, 0xf1789e20, 0x09048120, 0xc56298a0, 0x6e370dc0, 0xc66318c0, 0x84421080 +.long 0x180c0300, 0xf0781e00, 0x7d3e8fa0, 0xec761d80, 0x3a1d0740, 0xdc6e1b80, 0x4d2689a0, 0x20100400, 0x793c8f20, 0xee771dc0, 0x5f2f8be0, 0x3e1f07c0, 0xd76b9ae0, 0xcb659960, 0x391c8720, 0x48240900 + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_x86_64.S b/crypto/sm4/src/asm/crypt_sm4_x86_64.S new file mode 100644 index 00000000..5ebe0d3c --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_x86_64.S @@ -0,0 +1,301 @@ +/* + * 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_SM4 + +#include "crypt_sm4_macro_x86_64.s" + + .file "crypt_sm4_x86_64.S" + .text + +##### 1st Block ##### +.set X0, %r8d +.set X1, %r9d +.set X2, %r10d +.set X3, %r11d + +.set T0, %eax +.set T0BL, %al +.set T1, %ecx + +.set T0_64, %rax +.set T1_64, %rcx + + +##### 2nd Block ##### +.set Y0, %r12d +.set Y1, %r13d +.set Y2, %r14d +.set Y3, %r15d + +.set V0, %ebx +.set V0BL, %bl +.set V1, %ebp + +.set V0_64, %rbx +.set V1_64, %rbp + + +##### Round Key ##### +.set RK, %rdx +.set ADDR, %rsi + + +##### Serial Round ##### +.macro SM4_ROUND A0 A1 A2 A3 RKey No + + #x4 = x1 ^ x2 ^ x3 ^ *(rk + i); + #x4 = SBOX(x4); + #x0 = x0 ^ L32(x4); + + #x4 = x1 ^ x2 ^ x3 ^ *(rk + i); + movl \No(\RKey), T0 + xorl \A1, T0 + xorl \A2, T0 + xorl \A3, T0 + + #x0 = x0 ^ (SBOX_0[x4 & 0xff]) ^ (SBOX_1[(x4 >> 8) & 0xff]) ^ (SBOX_2[(x4 >> 16) & 0xff]) ^ (SBOX_3[(x4 >> 24) & 0xff]); + movzbl T0BL, T1 + xorl (ADDR,T1_64,4), \A0 + shrl $8, T0 + movzbl T0BL, T1 + xorl 1024(ADDR,T1_64,4), \A0 + shrl $8, T0 + movzbl T0BL, T1 + xorl 2048(ADDR,T1_64,4), \A0 + shrl $8, T0 + xorl 3072(ADDR,T0_64,4), \A0 + +.endm + + +##### Parallel Round ##### +.macro SM4_2_ROUND A0 A1 A2 A3 B0 B1 B2 B3 RKey No + + #x4 = x1 ^ x2 ^ x3 ^ *(rk + i); + #x4 = SBOX(x4); + #x0 = x0 ^ L32(x4); + + #x4 = x1 ^ x2 ^ x3 ^ *(rk + i); + movl \No(\RKey), T0 + movl \No(\RKey), V0 + xorl \A1, T0 + xorl \B1, V0 + xorl \A2, T0 + xorl \B2, V0 + xorl \A3, T0 + xorl \B3, V0 + + #x0 = x0 ^ (SBOX_0[x4 & 0xff]) ^ (SBOX_1[(x4 >> 8) & 0xff]) ^ (SBOX_2[(x4 >> 16) & 0xff]) ^ (SBOX_3[(x4 >> 24) & 0xff]); + movzbl T0BL, T1 + movzbl V0BL, V1 + + xorl (ADDR,T1_64,4), \A0 + xorl (ADDR,V1_64,4), \B0 + shrl $8, T0 + shrl $8, V0 + movzbl T0BL, T1 + movzbl V0BL, V1 + + xorl 1024(ADDR,T1_64,4), \A0 + xorl 1024(ADDR,V1_64,4), \B0 + shrl $8, T0 + shrl $8, V0 + movzbl T0BL, T1 + movzbl V0BL, V1 + + xorl 2048(ADDR,T1_64,4), \A0 + xorl 2048(ADDR,V1_64,4), \B0 + shrl $8, T0 + shrl $8, V0 + + xorl 3072(ADDR,T0_64,4), \A0 + xorl 3072(ADDR,V0_64,4), \B0 + +.endm + + + +##### Serial Function ##### + + ##### SM4 Encryption ##### + # void SM4_Encrypt(uint8_t *out, const uint8_t *in, const unsigned int *rk) + # %rdi out cipher ptr 16 bytes + # %rsi in plain ptr 16 bytes + # %rdx rk round key ptr 128 bytes + + .globl SM4_Encrypt + .type SM4_Encrypt, @function + .align 64 + +SM4_Encrypt: + + ###### Load Plain ##### + movl (%rsi), X0 + movl 4(%rsi), X1 + movl 8(%rsi), X2 + movl 12(%rsi), X3 + bswap X0 + bswap X1 + bswap X2 + bswap X3 + + ###### Load SBOX ADDRESS ##### + leaq SBOX4X_MASK(%rip), ADDR + + xorq T0_64, T0_64 + xorq T1_64, T1_64 + + ##### Serial Rounds ##### + SM4_ROUND X0 X1 X2 X3 RK 0 + SM4_ROUND X1 X2 X3 X0 RK 4 + SM4_ROUND X2 X3 X0 X1 RK 8 + SM4_ROUND X3 X0 X1 X2 RK 12 + SM4_ROUND X0 X1 X2 X3 RK 16 + SM4_ROUND X1 X2 X3 X0 RK 20 + SM4_ROUND X2 X3 X0 X1 RK 24 + SM4_ROUND X3 X0 X1 X2 RK 28 + SM4_ROUND X0 X1 X2 X3 RK 32 + SM4_ROUND X1 X2 X3 X0 RK 36 + SM4_ROUND X2 X3 X0 X1 RK 40 + SM4_ROUND X3 X0 X1 X2 RK 44 + SM4_ROUND X0 X1 X2 X3 RK 48 + SM4_ROUND X1 X2 X3 X0 RK 52 + SM4_ROUND X2 X3 X0 X1 RK 56 + SM4_ROUND X3 X0 X1 X2 RK 60 + SM4_ROUND X0 X1 X2 X3 RK 64 + SM4_ROUND X1 X2 X3 X0 RK 68 + SM4_ROUND X2 X3 X0 X1 RK 72 + SM4_ROUND X3 X0 X1 X2 RK 76 + SM4_ROUND X0 X1 X2 X3 RK 80 + SM4_ROUND X1 X2 X3 X0 RK 84 + SM4_ROUND X2 X3 X0 X1 RK 88 + SM4_ROUND X3 X0 X1 X2 RK 92 + SM4_ROUND X0 X1 X2 X3 RK 96 + SM4_ROUND X1 X2 X3 X0 RK 100 + SM4_ROUND X2 X3 X0 X1 RK 104 + SM4_ROUND X3 X0 X1 X2 RK 108 + SM4_ROUND X0 X1 X2 X3 RK 112 + SM4_ROUND X1 X2 X3 X0 RK 116 + SM4_ROUND X2 X3 X0 X1 RK 120 + SM4_ROUND X3 X0 X1 X2 RK 124 + + ##### Store Result ##### + bswap X0 + bswap X1 + bswap X2 + bswap X3 + movl X3, (%rdi) + movl X2, 4(%rdi) + movl X1, 8(%rdi) + movl X0, 12(%rdi) + + ##### Clear Context ##### + xorl X0, X0 + xorl X1, X1 + xorl X2, X2 + xorl X3, X3 + xorl T0, T0 + xorl T1, T1 + + ret + .size SM4_Encrypt, .-SM4_Encrypt + + + #### SM4 Decryption ##### + # void SM4_Decrypt(uint8_t *out, const uint8_t *in, const unsigned int *rk) + # %rdi out plain ptr 16 bytes + # %rsi in cipher ptr 16 bytes + # %rdx rk round key ptr 128 bytes + + .globl SM4_Decrypt + .type SM4_Decrypt, @function + .align 64 + +SM4_Decrypt: + + ###### Load Plain ##### + movl (%rsi), X0 + movl 4(%rsi), X1 + movl 8(%rsi), X2 + movl 12(%rsi), X3 + bswap X0 + bswap X1 + bswap X2 + bswap X3 + + ###### Load SBOX ADDRESS ##### + leaq SBOX4X_MASK(%rip), ADDR + + xorq T0_64, T0_64 + xorq T1_64, T1_64 + + ##### Serial Rounds ##### + SM4_ROUND X0 X1 X2 X3 RK 124 + SM4_ROUND X1 X2 X3 X0 RK 120 + SM4_ROUND X2 X3 X0 X1 RK 116 + SM4_ROUND X3 X0 X1 X2 RK 112 + SM4_ROUND X0 X1 X2 X3 RK 108 + SM4_ROUND X1 X2 X3 X0 RK 104 + SM4_ROUND X2 X3 X0 X1 RK 100 + SM4_ROUND X3 X0 X1 X2 RK 96 + SM4_ROUND X0 X1 X2 X3 RK 92 + SM4_ROUND X1 X2 X3 X0 RK 88 + SM4_ROUND X2 X3 X0 X1 RK 84 + SM4_ROUND X3 X0 X1 X2 RK 80 + SM4_ROUND X0 X1 X2 X3 RK 76 + SM4_ROUND X1 X2 X3 X0 RK 72 + SM4_ROUND X2 X3 X0 X1 RK 68 + SM4_ROUND X3 X0 X1 X2 RK 64 + SM4_ROUND X0 X1 X2 X3 RK 60 + SM4_ROUND X1 X2 X3 X0 RK 56 + SM4_ROUND X2 X3 X0 X1 RK 52 + SM4_ROUND X3 X0 X1 X2 RK 48 + SM4_ROUND X0 X1 X2 X3 RK 44 + SM4_ROUND X1 X2 X3 X0 RK 40 + SM4_ROUND X2 X3 X0 X1 RK 36 + SM4_ROUND X3 X0 X1 X2 RK 32 + SM4_ROUND X0 X1 X2 X3 RK 28 + SM4_ROUND X1 X2 X3 X0 RK 24 + SM4_ROUND X2 X3 X0 X1 RK 20 + SM4_ROUND X3 X0 X1 X2 RK 16 + SM4_ROUND X0 X1 X2 X3 RK 12 + SM4_ROUND X1 X2 X3 X0 RK 8 + SM4_ROUND X2 X3 X0 X1 RK 4 + SM4_ROUND X3 X0 X1 X2 RK 0 + + ##### Store Result ##### + bswap X0 + bswap X1 + bswap X2 + bswap X3 + movl X3, (%rdi) + movl X2, 4(%rdi) + movl X1, 8(%rdi) + movl X0, 12(%rdi) + + ##### Clear Context ##### + xorl X0, X0 + xorl X1, X1 + xorl X2, X2 + xorl X3, X3 + xorl T0, T0 + xorl T1, T1 + + ret + .size SM4_Decrypt, .-SM4_Decrypt + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_xts_armv8.S b/crypto/sm4/src/asm/crypt_sm4_xts_armv8.S new file mode 100644 index 00000000..def47a71 --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_xts_armv8.S @@ -0,0 +1,971 @@ +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM4 + +#define INP X0 +#define OUTP X1 +#define RKS1 X3 +#define IVP X5 +#define ENC X6 + +#define BLOCKS X2 +#define LEN X2 +#define REMAIN X7 + +#define TWX0 X8 +#define TWX1 X9 +#define TWX2 X10 +#define TWX3 X11 +#define TWX4 X12 +#define TWX5 X13 +#define TWX6 X14 +#define TWX7 X15 +#define TWX8 X16 +#define TWX9 X17 +#define TWX10 X18 +#define TWX11 X19 +#define TWX12 X20 +#define TWX13 X21 +#define TWX14 X22 +#define TWX15 X23 + +#define PTR X24 +#define COUNTER W25 + +#define WTMP0 W27 +#define WTMP1 W28 +#define WTMP2 W29 +#define WTMP3 W30 + +#define XTMP1 X28 +#define XTMP2 X29 + +#define WORD0 W20 +#define WORD1 W21 +#define WORD2 W22 +#define WORD3 W23 + +#define LAST_BLK X26 + +#define TWEAK0 V0 +#define TWEAK1 V1 +#define TWEAK2 V2 +#define TWEAK3 V3 +#define TWEAK4 V4 +#define TWEAK5 V5 +#define TWEAK6 V6 +#define TWEAK7 V7 + +#define QTMP0 Q8 + +#define VTMP0 V8 +#define VTMP1 V9 +#define VTMP2 V10 +#define VTMP3 V11 + +#define RK0 V12 +#define RK1 V13 +#define RK_A V14 +#define RK_B V15 + +#define DATA0 V16 +#define DATA1 V17 +#define DATA2 V18 +#define DATA3 V19 + +#define DATAX0 V20 +#define DATAX1 V21 +#define DATAX2 V22 +#define DATAX3 V23 + +#define VTMP4 V24 +#define VTMP5 V25 +#define LAST_TWEAK V25 + +#define MaskV v26 +#define TAHMatV v27 +#define TALMatV v28 +#define ATAHMatV v29 +#define ATALMatV v30 +#define ANDMaskV v31 + +#define MaskQ q26 +#define TAHMatQ q27 +#define TALMatQ q28 +#define ATAHMatQ q29 +#define ATALMatQ q30 +#define ANDMaskQ q31 + +#define SAVE_STACK() \ + stp x15, x16, [sp, #-0x10]! ; \ + stp x17, x18, [sp, #-0x10]! ; \ + stp x19, x20, [sp, #-0x10]! ; \ + stp x21, x22, [sp, #-0x10]! ; \ + stp x23, x24, [sp, #-0x10]! ; \ + stp x25, x26, [sp, #-0x10]! ; \ + stp x27, x28, [sp, #-0x10]! ; \ + stp x29, x30, [sp, #-0x10]! ; \ + stp d8, d9, [sp, #-0x10]! ; \ + stp d10, d11, [sp, #-0x10]! ; \ + stp d12, d13, [sp, #-0x10]! ; \ + stp d14, d15, [sp, #-0x10]! ; + +#define LOAD_STACK() \ + ldp d14, d15, [sp], #0x10 ; \ + ldp d12, d13, [sp], #0x10 ; \ + ldp d10, d11, [sp], #0x10 ; \ + ldp d8, d9, [sp], #0x10 ; \ + ldp x29, x30, [sp], #0x10 ; \ + ldp x27, x28, [sp], #0x10 ; \ + ldp x25, x26, [sp], #0x10 ; \ + ldp x23, x24, [sp], #0x10 ; \ + ldp x21, x22, [sp], #0x10 ; \ + ldp x19, x20, [sp], #0x10 ; \ + ldp x17, x18, [sp], #0x10 ; \ + ldp x15, x16, [sp], #0x10 ; + +#ifdef HITLS_BIG_ENDIAN + #define MOV_REG_TO_VEC(SRC0, SRC1, DESV) \ + mov DESV.d[0],SRC0 ; \ + mov DESV.d[1],SRC1 ; \ + rev32 DESV.16b,DESV.16b ; +#else + #define MOV_REG_TO_VEC(SRC0, SRC1, DESV) \ + mov DESV.d[0],SRC0 ; \ + mov DESV.d[1],SRC1 ; +#endif + +#define MOV_VEC_TO_REG(SRCV, DES0, DES1) \ + mov DES0,SRCV.d[0] ; \ + mov DES1,SRCV.d[1] ; + +#define COMPUTE_ALPHA(SRC0, SRC1, DES0, DES1) \ + mov WTMP0,0x87 ; \ + extr XTMP2,SRC1,SRC1,#32 ; \ + extr DES1,SRC1,SRC0,#63 ; \ + and WTMP1,WTMP0,WTMP2,asr#31 ; \ + eor DES0,XTMP1,SRC0,lsl#1 ; + +#ifdef HITLS_BIG_ENDIAN + .qtmp0: + .dword 0x0101010101010101,0x0101010101010187 +#else + .qtmp0: + .dword 0x0101010101010187,0x0101010101010101 +#endif + +#define COMPUTE_ALPHA_VEC(SRC, DES) \ + ldr QTMP0, .qtmp0 ; \ + rbit VTMP2.16b,SRC.16b ; \ + shl DES.16b, VTMP2.16b, #1 ; \ + ext VTMP1.16b, VTMP2.16b, VTMP2.16b,#15 ; \ + ushr VTMP1.16b, VTMP1.16b, #7 ; \ + mul VTMP1.16b, VTMP1.16b, VTMP0.16b ; \ + eor DES.16b, DES.16b, VTMP1.16b ; \ + rbit DES.16b,DES.16b ; + +#ifndef HITLS_BIG_ENDIAN + #define REV32(DST, SRC) \ + rev32 DST.16b,SRC.16b ; + + #define REV32_EQ(DST, SRC) \ + rev32 DST.16b,DST.16b ; + + #define REV32_ARMEB_EQ(DST, SRC) \ + /*rev32_armeb eq is null if not in armeb */ ; + +#else + #define REV32(DST, SRC) \ + mov DST.16b,SRC.16b ; + + #define REV32_EQ(DST, SRC) \ + /*rev32 eq is null in armeb */ ; + + #define REV32_ARMEB_EQ(DST, SRC) \ + rev32 DST.16b,DST.16b ; + +#endif + +#define TRANSPOSE(DAT0,DAT1,DAT2,DAT3,VT0,VT1,VT2,VT3) \ + zip1 VT0.4s,DAT0.4s,DAT1.4s ; \ + zip2 VT1.4s,DAT0.4s,DAT1.4s ; \ + zip1 VT2.4s,DAT2.4s,DAT3.4s ; \ + zip2 VT3.4s,DAT2.4s,DAT3.4s ; \ + zip1 DAT0.2d,VT0.2d,VT2.2d ; \ + zip2 DAT1.2d,VT0.2d,VT2.2d ; \ + zip1 DAT2.2d,VT1.2d,VT3.2d ; \ + zip2 DAT3.2d,VT1.2d,VT3.2d ; + +/* sbox operations for 4-lane of words */ +#define SBOX(DAT) \ + /* optimize sbox using AESE instruction */ ; \ + tbl VTMP0.16b, {DAT.16b}, MaskV.16b ; \ + ; \ + MUL_MATRIX(VTMP0, TAHMatV, TALMatV, VTMP4) ; \ + ; \ + eor VTMP1.16b, VTMP1.16b, VTMP1.16b ; \ + aese VTMP0.16b,VTMP1.16b ; \ + ; \ + MUL_MATRIX(VTMP0, ATAHMatV, ATALMatV, VTMP4) ; \ + ; \ + mov DAT.16b,VTMP0.16b ; \ + ; \ + /* linear transformation */ ; \ + ushr VTMP0.4s,DAT.4s,32-2 ; \ + ushr VTMP1.4s,DAT.4s,32-10 ; \ + ushr VTMP2.4s,DAT.4s,32-18 ; \ + ushr VTMP3.4s,DAT.4s,32-24 ; \ + sli VTMP0.4s,DAT.4s,2 ; \ + sli VTMP1.4s,DAT.4s,10 ; \ + sli VTMP2.4s,DAT.4s,18 ; \ + sli VTMP3.4s,DAT.4s,24 ; \ + eor VTMP4.16b,VTMP0.16b,DAT.16b ; \ + eor VTMP4.16b,VTMP4.16b,VTMP1.16b ; \ + eor DAT.16b,VTMP2.16b,VTMP3.16b ; \ + eor DAT.16b,DAT.16b,VTMP4.16b ; + +/* sbox operation for 8-lane of words */ +#define SBOX_DOUBLE(DAT, DATX) \ + /* optimize sbox using AESE instruction */ ; \ + tbl VTMP0.16b, {DAT.16b}, MaskV.16b ; \ + tbl VTMP1.16b, {DATX.16b}, MaskV.16b ; \ + ; \ + MUL_MATRIX(VTMP0, TAHMatV, TALMatV, VTMP4) ; \ + MUL_MATRIX(VTMP1, TAHMatV, TALMatV, VTMP4) ; \ + ; \ + eor VTMP5.16b, VTMP5.16b, VTMP5.16b ; \ + aese VTMP0.16b,VTMP5.16b ; \ + aese VTMP1.16b,VTMP5.16b ; \ + ; \ + MUL_MATRIX(VTMP0, ATAHMatV, ATALMatV,VTMP4) ; \ + MUL_MATRIX(VTMP1, ATAHMatV, ATALMatV,VTMP4) ; \ + ; \ + mov DAT.16b,VTMP0.16b ; \ + mov DATX.16b,VTMP1.16b ; \ + ; \ + /* linear transformation */ ; \ + ushr VTMP0.4s,DAT.4s,32-2 ; \ + ushr VTMP5.4s,DATX.4s,32-2 ; \ + ushr VTMP1.4s,DAT.4s,32-10 ; \ + ushr VTMP2.4s,DAT.4s,32-18 ; \ + ushr VTMP3.4s,DAT.4s,32-24 ; \ + sli VTMP0.4s,DAT.4s,2 ; \ + sli VTMP5.4s,DATX.4s,2 ; \ + sli VTMP1.4s,DAT.4s,10 ; \ + sli VTMP2.4s,DAT.4s,18 ; \ + sli VTMP3.4s,DAT.4s,24 ; \ + eor VTMP4.16b,VTMP0.16b,DAT.16b ; \ + eor VTMP4.16b,VTMP4.16b,VTMP1.16b ; \ + eor DAT.16b,VTMP2.16b,VTMP3.16b ; \ + eor DAT.16b,DAT.16b,VTMP4.16b ; \ + ; \ + ushr VTMP1.4s,DATX.4s,32-10 ; \ + ushr VTMP2.4s,DATX.4s,32-18 ; \ + ushr VTMP3.4s,DATX.4s,32-24 ; \ + sli VTMP1.4s,DATX.4s,10 ; \ + sli VTMP2.4s,DATX.4s,18 ; \ + sli VTMP3.4s,DATX.4s,24 ; \ + eor VTMP4.16b,VTMP5.16b,DATX.16b ; \ + eor VTMP4.16b,VTMP4.16b,VTMP1.16b ; \ + eor DATX.16b,VTMP2.16b,VTMP3.16b ; \ + eor DATX.16b,DATX.16b,VTMP4.16b ; + +/* sbox operation for one single word */ +#define SBOX_1WORD(WORD) \ + mov VTMP3.s[0],WORD ; \ + /*optimize sbox using AESE instruction */ ; \ + tbl VTMP0.16b, {VTMP3.16b}, MaskV.16b ; \ + ; \ + MUL_MATRIX(VTMP0, TAHMatV, TALMatV, VTMP2) ; \ + eor VTMP1.16b, VTMP1.16b, VTMP1.16b ; \ + aese VTMP0.16b,VTMP1.16b ; \ + ; \ + MUL_MATRIX(VTMP0, ATAHMatV, ATALMatV, VTMP2) ; \ + ; \ + mov WTMP0,VTMP0.s[0] ; \ + eor WORD,WTMP0,WTMP0,ror #32-2 ; \ + eor WORD,WORD,WTMP0,ror #32-10 ; \ + eor WORD,WORD,WTMP0,ror #32-18 ; \ + eor WORD,WORD,WTMP0,ror #32-24 ; + +/* sm4 for one block of data, in scalar registers word0/word1/word2/word3 */ +#define SM4_1BLK(K_PTR) \ + ldp WTMP0,WTMP1,[K_PTR],8 ; \ + ; \ + /* B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) */ ; \ + eor WTMP3,WORD2,WORD3 ; \ + eor WTMP2,WTMP0,WORD1 ; \ + eor WTMP3,WTMP3,WTMP2 ; \ + SBOX_1WORD(WTMP3) ; \ + eor WORD0,WORD0,WTMP3 ; \ + ; \ + /* B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) */ ; \ + eor WTMP3,WORD2,WORD3 ; \ + eor WTMP2,WORD0,WTMP1 ; \ + eor WTMP3,WTMP3,WTMP2 ; \ + SBOX_1WORD(WTMP3) ; \ + ldp WTMP0,WTMP1,[K_PTR],8 ; \ + eor WORD1,WORD1,WTMP3 ; \ + ; \ + /* B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) */ ; \ + eor WTMP3,WORD0,WORD1 ; \ + eor WTMP2,WTMP0,WORD3 ; \ + eor WTMP3,WTMP3,WTMP2 ; \ + SBOX_1WORD(WTMP3) ; \ + eor WORD2,WORD2,WTMP3 ; \ + ; \ + /* B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) */ ; \ + eor WTMP3,WORD0,WORD1 ; \ + eor WTMP2,WORD2,WTMP1 ; \ + eor WTMP3,WTMP3,WTMP2 ; \ + SBOX_1WORD(WTMP3) ; \ + eor WORD3,WORD3,WTMP3 ; + +/* sm4 for 4-lanes of data, in neon registers data0/data1/data2/data3 */ +#define SM4_4BLKS(K_PTR) \ + ldp WTMP0,WTMP1,[K_PTR],8 ; \ + dup RK0.4s,WTMP0 ; \ + dup RK1.4s,WTMP1 ; \ + ; \ + /* B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) */ ; \ + eor RK_A.16b,DATA2.16b,DATA3.16b ; \ + eor RK0.16b,DATA1.16b,RK0.16b ; \ + eor RK0.16b,RK_A.16b,RK0.16b ; \ + SBOX(RK0) ; \ + eor DATA0.16b,DATA0.16b,RK0.16b ; \ + ; \ + /* B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) */ ; \ + eor RK_A.16b,RK_A.16b,DATA0.16b ; \ + eor RK1.16b,RK_A.16b,RK1.16b ; \ + SBOX(RK1) ; \ + ldp WTMP0,WTMP1,[K_PTR],8 ; \ + eor DATA1.16b,DATA1.16b,RK1.16b ; \ + ; \ + dup RK0.4s,WTMP0 ; \ + dup RK1.4s,WTMP1 ; \ + ; \ + /* B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) */ ; \ + eor RK_A.16b,DATA0.16b,DATA1.16b ; \ + eor RK0.16b,DATA3.16b,RK0.16b ; \ + eor RK0.16b,RK_A.16b,RK0.16b ; \ + SBOX(RK0) ; \ + eor DATA2.16b,DATA2.16b,RK0.16b ; \ + ; \ + /* B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) */ ; \ + eor RK_A.16b,RK_A.16b,DATA2.16b ; \ + eor RK1.16b,RK_A.16b,RK1.16b ; \ + SBOX(RK1) ; \ + eor DATA3.16b,DATA3.16b,RK1.16b ; + +/* sm4 for 8 lanes of data, in neon registers */ +/* data0/data1/data2/data3 datax0/datax1/datax2/datax3 */ +#define SM4_8BLKS(K_PTR) \ + ldp WTMP0,WTMP1,[K_PTR],8 ; \ + ; \ + /* B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) */ ; \ + dup RK0.4s,WTMP0 ; \ + eor RK_A.16b,DATA2.16b,DATA3.16b ; \ + eor RK_B.16b,DATAX2.16b,DATAX3.16b ; \ + eor VTMP0.16b,DATA1.16b,RK0.16b ; \ + eor VTMP1.16b,DATAX1.16b,RK0.16b ; \ + eor RK0.16b,RK_A.16b,VTMP0.16b ; \ + eor RK1.16b,RK_B.16b,VTMP1.16b ; \ + SBOX_DOUBLE(RK0,RK1) ; \ + ; \ + eor DATA0.16b,DATA0.16b,RK0.16b ; \ + eor DATAX0.16b,DATAX0.16b,RK1.16b ; \ + ; \ + /* B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) */ ; \ + dup RK1.4s,WTMP1 ; \ + eor RK_A.16b,RK_A.16b,DATA0.16b ; \ + eor RK_B.16b,RK_B.16b,DATAX0.16b ; \ + eor RK0.16b,RK_A.16b,RK1.16b ; \ + eor RK1.16b,RK_B.16b,RK1.16b ; \ + SBOX_DOUBLE(RK0,RK1) ; \ + ; \ + ldp WTMP0,WTMP1,[K_PTR],8 ; \ + eor DATA1.16b,DATA1.16b,RK0.16b ; \ + eor DATAX1.16b,DATAX1.16b,RK1.16b ; \ + ; \ + /* B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) */ ; \ + dup RK0.4s,WTMP0 ; \ + eor RK_A.16b,DATA0.16b,DATA1.16b ; \ + eor RK_B.16b,DATAX0.16b,DATAX1.16b ; \ + eor VTMP0.16b,DATA3.16b,RK0.16b ; \ + eor VTMP1.16b,DATAX3.16b,RK0.16b ; \ + eor RK0.16b,RK_A.16b,VTMP0.16b ; \ + eor RK1.16b,RK_B.16b,VTMP1.16b ; \ + SBOX_DOUBLE(RK0,RK1) ; \ + eor DATA2.16b,DATA2.16b,RK0.16b ; \ + eor DATAX2.16b,DATAX2.16b,RK1.16b ; \ + ; \ + /* B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) */ ; \ + dup RK1.4s,WTMP1 ; \ + eor RK_A.16b,RK_A.16b,DATA2.16b ; \ + eor RK_B.16b,RK_B.16b,DATAX2.16b ; \ + eor RK0.16b,RK_A.16b,RK1.16b ; \ + eor RK1.16b,RK_B.16b,RK1.16b ; \ + SBOX_DOUBLE(RK0,RK1) ; \ + eor DATA3.16b,DATA3.16b,RK0.16b ; \ + eor DATAX3.16b,DATAX3.16b,RK1.16b ; + +#define ENCRYPT_1BLK_NOREV(DAT, RKS) \ + mov PTR,RKS ; \ + mov COUNTER,#8 ; \ + mov WORD0,DAT.s[0] ; \ + mov WORD1,DAT.s[1] ; \ + mov WORD2,DAT.s[2] ; \ + mov WORD3,DAT.s[3] ; \ +10: \ + /* loop begin */ ; \ + SM4_1BLK(PTR) ; \ + subs COUNTER,COUNTER,#1 ; \ + b.ne 10b ; \ + mov DAT.s[0],WORD3 ; \ + mov DAT.s[1],WORD2 ; \ + mov DAT.s[2],WORD1 ; \ + mov DAT.s[3],WORD0 ; + +#define ENCRYPT_1BLK(DAT, RKS) \ + ENCRYPT_1BLK_NOREV(DAT,RKS) ; \ + REV32_EQ(DAT,DAT) ; + +#define ENCRYPT_4BLKS() \ + mov PTR,RKS1 ; \ + mov COUNTER,#8 ; \ +10: \ + /* loop begin */ ; \ + SM4_4BLKS(PTR) ; \ + subs COUNTER,COUNTER,#1 ; \ + b.ne 10b ; \ + REV32(VTMP3,DATA0) ; \ + REV32(VTMP2,DATA1) ; \ + REV32(VTMP1,DATA2) ; \ + REV32(VTMP0,DATA3) ; + +#define ENCRYPT_8BLKS(RKS) \ + mov PTR,RKS ; \ + mov COUNTER,#8 ; \ +10: \ + /* loop begin */ ; \ + SM4_8BLKS(PTR) ; \ + subs COUNTER,COUNTER,#1 ; \ + b.ne 10b ; \ + REV32(VTMP3,DATA0) ; \ + REV32(VTMP2,DATA1) ; \ + REV32(VTMP1,DATA2) ; \ + REV32(VTMP0,DATA3) ; \ + REV32(DATA3,DATAX0) ; \ + REV32(DATA2,DATAX1) ; \ + REV32(DATA1,DATAX2) ; \ + REV32(DATA0,DATAX3) ; + +.macro LOAD_SBOX_MATRIX + ldr MaskQ, .Lsbox_magic + ldr TAHMatQ, .Lsbox_magic+16 + ldr TALMatQ, .Lsbox_magic+32 + ldr ATAHMatQ, .Lsbox_magic+48 + ldr ATALMatQ, .Lsbox_magic+64 + ldr ANDMaskQ, .Lsbox_magic+80 +.endm + +#ifdef HITLS_BIG_ENDIAN +.Lsbox_magic: + .dword 0x0306090c0f020508,0x0b0e0104070a0d00 + .dword 0x22581a6002783a40,0x62185a2042387a00 + .dword 0xc10bb67c4a803df7,0x15df62a89e54e923 + .dword 0x1407c6d56c7fbead,0xb9aa6b78c1d21300 + .dword 0xe383c1a1fe9edcbc,0x6404462679195b3b + .dword 0x0f0f0f0f0f0f0f0f,0x0f0f0f0f0f0f0f0f +#else +.Lsbox_magic: + .dword 0x0b0e0104070a0d00,0x0306090c0f020508 + .dword 0x62185a2042387a00,0x22581a6002783a40 + .dword 0x15df62a89e54e923,0xc10bb67c4a803df7 + .dword 0xb9aa6b78c1d21300,0x1407c6d56c7fbead + .dword 0x6404462679195b3b,0xe383c1a1fe9edcbc + .dword 0x0f0f0f0f0f0f0f0f,0x0f0f0f0f0f0f0f0f +#endif + +/* matrix multiplication Mat*x = (lowerMat*x) ^ (higherMat*x) */ +#define MUL_MATRIX(X, HIGHERMAT, LOWERMAT, TMP) \ + ushr TMP.16b, X.16b, 4 ; \ + and X.16b, X.16b, ANDMaskV.16b ; \ + tbl X.16b, {LOWERMAT.16b}, X.16b ; \ + tbl TMP.16b, {HIGHERMAT.16b}, TMP.16b ; \ + eor X.16b, X.16b, TMP.16b ; + + +.arch armv8-a+crypto +.text + +.type vpsm4_ex_consts,%object +.align 7 +vpsm4_ex_consts: +.Lck: + .long 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269 + .long 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9 + .long 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249 + .long 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9 + .long 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229 + .long 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299 + .long 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209 + .long 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 +.Lfk: + .long 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc +.Lshuffles: + .long 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x03020100 + +.size vpsm4_ex_consts,.-vpsm4_ex_consts + +#define USER_KEY x0 +#define ROUND_KEY1 x1 +#define ENC1 w2 + +#define POINTER1 x5 +#define SCHEDULES x6 +#define WTMP w7 +#define ROUND_KEY2 w8 + +#define V_KEY v5 +#define V_FK v6 +#define V_MAP v7 + +/* + * void vpsm4_ex_set_key(const unsigned char *userKey, SM4_KEY *key, int enc); + * generate sm4 rounk key context + * USER_KEY => userKey; + * ROUND_KEY1 => key ; + * if encryption:ENC=>enc + */ +.type vpsm4_ex_set_key,%function +.align 4 +vpsm4_ex_set_key: + ld1 {V_KEY.4s},[USER_KEY] + LOAD_SBOX_MATRIX + REV32_EQ(V_KEY,V_KEY) + adr POINTER1,.Lshuffles + ld1 {V_MAP.4s},[POINTER1] + adr POINTER1,.Lfk + ld1 {V_FK.4s},[POINTER1] + eor V_KEY.16b,V_KEY.16b,V_FK.16b + mov SCHEDULES,#32 + adr POINTER1,.Lck + movi VTMP0.16b,#64 + cbnz ENC1,1f + add ROUND_KEY1,ROUND_KEY1,124 +1: // loop + mov WTMP,V_KEY.s[1] + ldr ROUND_KEY2,[POINTER1],#4 + eor ROUND_KEY2,ROUND_KEY2,WTMP + mov WTMP,V_KEY.s[2] + eor ROUND_KEY2,ROUND_KEY2,WTMP + mov WTMP,V_KEY.s[3] + eor ROUND_KEY2,ROUND_KEY2,WTMP + + /* optimize sbox using AESE instruction */ + mov DATA0.s[0],ROUND_KEY2 + tbl VTMP0.16b, {DATA0.16b}, MaskV.16b + MUL_MATRIX(VTMP0, TAHMatV, TALMatV, VTMP2) + eor VTMP1.16b, VTMP1.16b, VTMP1.16b + aese VTMP0.16b,VTMP1.16b + MUL_MATRIX(VTMP0, ATAHMatV, ATALMatV, VTMP2) + mov WTMP,VTMP0.s[0] + + /* linear transformation */ + eor ROUND_KEY2,WTMP,WTMP,ror #19 + eor ROUND_KEY2,ROUND_KEY2,WTMP,ror #9 + mov WTMP,V_KEY.s[0] + eor ROUND_KEY2,ROUND_KEY2,WTMP + mov V_KEY.s[0],ROUND_KEY2 + cbz ENC1,2f + str ROUND_KEY2,[ROUND_KEY1],#4 + b 3f +2: // set encrypt key + str ROUND_KEY2,[ROUND_KEY1],#-4 +3: // final + tbl V_KEY.16b,{V_KEY.16b},V_MAP.16b + subs SCHEDULES,SCHEDULES,#1 + b.ne 1b + /*clear register for temp key */ + eor V_KEY.16b, V_KEY.16b, V_KEY.16b + eor ROUND_KEY2, ROUND_KEY2, ROUND_KEY2 + ret +.size vpsm4_ex_set_key,.-vpsm4_ex_set_key + +/* + * void vpsm4_ex_enc_4blks(); + * encrypt four blocks + * use RSK1 register as user key + */ +.type vpsm4_ex_enc_4blks,%function +.align 4 +vpsm4_ex_enc_4blks: + ENCRYPT_4BLKS() + ret +.size vpsm4_ex_enc_4blks,.-vpsm4_ex_enc_4blks + +/* + * void vpsm4_ex_enc_8blks(); + * encrypt eight blocks + * use RSK1 register as user key + */ +.type vpsm4_ex_enc_8blks,%function +.align 4 +vpsm4_ex_enc_8blks: + ENCRYPT_8BLKS(RKS1) + ret +.size vpsm4_ex_enc_8blks,.-vpsm4_ex_enc_8blks + +/* + * void Vpsm4SetEncryptKey(const unsigned char *userKey, SM4_KEY *key); + * generate SM4 encrypt round KEY context + * x0 => userKey; x1 => key + */ +.globl Vpsm4SetEncryptKey +.type Vpsm4SetEncryptKey,%function +.align 5 +Vpsm4SetEncryptKey: + stp x29,x30,[sp,#-16]! + mov w2,1 + bl vpsm4_ex_set_key + ldp x29,x30,[sp],#16 + ret +.size Vpsm4SetEncryptKey,.-Vpsm4SetEncryptKey + +/* + * void Vpsm4SetDecryptKey(const unsigned char *userKey, SM4_KEY *key); + * generate SM4 decryption round KEY context + * x0 => userKey; x1 => key + */ +.globl Vpsm4SetDecryptKey +.type Vpsm4SetDecryptKey,%function +.align 5 +Vpsm4SetDecryptKey: + stp x29,x30,[sp,#-16]! + mov w2,0 + bl vpsm4_ex_set_key + ldp x29,x30,[sp],#16 + ret +.size Vpsm4SetDecryptKey,.-Vpsm4SetDecryptKey + + +/* + * void Vpsm4XtsCipher(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, + const SM4_KEY *key2, const uint8_t *iv, int env); + * encryption and decryption for sm4-xts, use ENC regsiter as ecrypt direction flag + * INP => in; OUTP => out; LEN => length; RKS1 => key1; IVP => iv; ENC=>enc + */ +.globl Vpsm4XtsCipher +.type Vpsm4XtsCipher,%function +.align 5 +Vpsm4XtsCipher: + SAVE_STACK() + ld1 {TWEAK0.4s}, [IVP] + LOAD_SBOX_MATRIX + + and REMAIN,LEN,#0x0F + // convert length into blocks + lsr BLOCKS,LEN,4 + cmp BLOCKS,#1 + b.lt .return + + cmp REMAIN,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks + b.eq .xts_encrypt_blocks + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak or .only_2blks_tweak + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks + subs BLOCKS,BLOCKS,#1 + b.eq .only_2blks_tweak + +.xts_encrypt_blocks: + rbit TWEAK0.16b,TWEAK0.16b + + REV32_ARMEB_EQ(TWEAK0,TWEAK0) + MOV_VEC_TO_REG(TWEAK0,TWX0,TWX1) + COMPUTE_ALPHA(TWX0,TWX1,TWX2,TWX3) + COMPUTE_ALPHA(TWX2,TWX3,TWX4,TWX5) + COMPUTE_ALPHA(TWX4,TWX5,TWX6,TWX7) + COMPUTE_ALPHA(TWX6,TWX7,TWX8,TWX9) + COMPUTE_ALPHA(TWX8,TWX9,TWX10,TWX11) + COMPUTE_ALPHA(TWX10,TWX11,TWX12,TWX13) + COMPUTE_ALPHA(TWX12,TWX13,TWX14,TWX15) + +.Lxts_8_blocks_process: + cmp BLOCKS,#8 + MOV_REG_TO_VEC(TWX0,TWX1,TWEAK0) + COMPUTE_ALPHA(TWX14,TWX15,TWX0,TWX1) + MOV_REG_TO_VEC(TWX2,TWX3,TWEAK1) + COMPUTE_ALPHA(TWX0,TWX1,TWX2,TWX3) + MOV_REG_TO_VEC(TWX4,TWX5,TWEAK2) + COMPUTE_ALPHA(TWX2,TWX3,TWX4,TWX5) + MOV_REG_TO_VEC(TWX6,TWX7,TWEAK3) + COMPUTE_ALPHA(TWX4,TWX5,TWX6,TWX7) + MOV_REG_TO_VEC(TWX8,TWX9,TWEAK4) + COMPUTE_ALPHA(TWX6,TWX7,TWX8,TWX9) + MOV_REG_TO_VEC(TWX10,TWX11,TWEAK5) + COMPUTE_ALPHA(TWX8,TWX9,TWX10,TWX11) + MOV_REG_TO_VEC(TWX12,TWX13,TWEAK6) + COMPUTE_ALPHA(TWX10,TWX11,TWX12,TWX13) + MOV_REG_TO_VEC(TWX14,TWX15,TWEAK7) + COMPUTE_ALPHA(TWX12,TWX13,TWX14,TWX15) + + b.lt .Lxts_4_blocks_process + ld1 {DATA0.4s,DATA1.4s,DATA2.4s,DATA3.4s},[INP],#64 + rbit TWEAK0.16b,TWEAK0.16b + rbit TWEAK1.16b,TWEAK1.16b + rbit TWEAK2.16b,TWEAK2.16b + rbit TWEAK3.16b,TWEAK3.16b + eor DATA0.16b, DATA0.16b, TWEAK0.16b + eor DATA1.16b, DATA1.16b, TWEAK1.16b + eor DATA2.16b, DATA2.16b, TWEAK2.16b + eor DATA3.16b, DATA3.16b, TWEAK3.16b + ld1 {DATAX0.4s,DATAX1.4s,DATAX2.4s,DATAX3.4s},[INP],#64 + rbit TWEAK4.16b,TWEAK4.16b + rbit TWEAK5.16b,TWEAK5.16b + rbit TWEAK6.16b,TWEAK6.16b + rbit TWEAK7.16b,TWEAK7.16b + eor DATAX0.16b, DATAX0.16b, TWEAK4.16b + eor DATAX1.16b, DATAX1.16b, TWEAK5.16b + eor DATAX2.16b, DATAX2.16b, TWEAK6.16b + eor DATAX3.16b, DATAX3.16b, TWEAK7.16b + + REV32_EQ(DATA0,DATA0) + REV32_EQ(DATA1,DATA1) + REV32_EQ(DATA2,DATA2) + REV32_EQ(DATA3,DATA3) + REV32_EQ(DATAX0,DATAX0) + REV32_EQ(DATAX1,DATAX1) + REV32_EQ(DATAX2,DATAX2) + REV32_EQ(DATAX3,DATAX3) + + TRANSPOSE(DATA0,DATA1,DATA2,DATA3,VTMP0,VTMP1,VTMP2,VTMP3) + TRANSPOSE(DATAX0,DATAX1,DATAX2,DATAX3,VTMP0,VTMP1,VTMP2,VTMP3) + + bl vpsm4_ex_enc_8blks + + TRANSPOSE(VTMP0,VTMP1,VTMP2,VTMP3,DATAX0,DATAX1,DATAX2,DATAX3) + TRANSPOSE(DATA0,DATA1,DATA2,DATA3,DATAX0,DATAX1,DATAX2,DATAX3) + + eor VTMP0.16b, VTMP0.16b, TWEAK0.16b + eor VTMP1.16b, VTMP1.16b, TWEAK1.16b + eor VTMP2.16b, VTMP2.16b, TWEAK2.16b + eor VTMP3.16b, VTMP3.16b, TWEAK3.16b + eor DATA0.16b, DATA0.16b, TWEAK4.16b + eor DATA1.16b, DATA1.16b, TWEAK5.16b + eor DATA2.16b, DATA2.16b, TWEAK6.16b + eor DATA3.16b, DATA3.16b, TWEAK7.16b + + // save the last tweak + mov LAST_TWEAK.16b,TWEAK7.16b + st1 {VTMP0.4s,VTMP1.4s,VTMP2.4s,VTMP3.4s},[OUTP],#64 + st1 {DATA0.4s,DATA1.4s,DATA2.4s,DATA3.4s},[OUTP],#64 + subs BLOCKS,BLOCKS,#8 + b.gt .Lxts_8_blocks_process + b 100f + +.Lxts_4_blocks_process: + cmp BLOCKS,#4 + b.lt 1f + ld1 {DATA0.4s,DATA1.4s,DATA2.4s,DATA3.4s},[INP],#64 + rbit TWEAK0.16b,TWEAK0.16b + rbit TWEAK1.16b,TWEAK1.16b + rbit TWEAK2.16b,TWEAK2.16b + rbit TWEAK3.16b,TWEAK3.16b + eor DATA0.16b, DATA0.16b, TWEAK0.16b + eor DATA1.16b, DATA1.16b, TWEAK1.16b + eor DATA2.16b, DATA2.16b, TWEAK2.16b + eor DATA3.16b, DATA3.16b, TWEAK3.16b + + REV32_EQ(DATA0,DATA0) + REV32_EQ(DATA1,DATA1) + REV32_EQ(DATA2,DATA2) + REV32_EQ(DATA3,DATA3) + TRANSPOSE(DATA0,DATA1,DATA2,DATA3,VTMP0,VTMP1,VTMP2,VTMP3) + + bl vpsm4_ex_enc_4blks + TRANSPOSE(VTMP0,VTMP1,VTMP2,VTMP3,DATA0,DATA1,DATA2,DATA3) + + eor VTMP0.16b, VTMP0.16b, TWEAK0.16b + eor VTMP1.16b, VTMP1.16b, TWEAK1.16b + eor VTMP2.16b, VTMP2.16b, TWEAK2.16b + eor VTMP3.16b, VTMP3.16b, TWEAK3.16b + st1 {VTMP0.4s,VTMP1.4s,VTMP2.4s,VTMP3.4s},[OUTP],#64 + sub BLOCKS,BLOCKS,#4 + mov TWEAK0.16b,TWEAK4.16b + mov TWEAK1.16b,TWEAK5.16b + mov TWEAK2.16b,TWEAK6.16b + // save the last tweak + mov LAST_TWEAK.16b,TWEAK3.16b +1: // process last block + cmp BLOCKS,#1 + b.lt 100f + b.gt 1f + ld1 {DATA0.4s},[INP],#16 + rbit TWEAK0.16b,TWEAK0.16b + eor DATA0.16b, DATA0.16b, TWEAK0.16b + REV32_EQ(DATA0,DATA0) + ENCRYPT_1BLK(DATA0,RKS1) + eor DATA0.16b, DATA0.16b, TWEAK0.16b + st1 {DATA0.4s},[OUTP],#16 + // save the last tweak + mov LAST_TWEAK.16b,TWEAK0.16b + b 100f +1: // process last 2 blocks + cmp BLOCKS,#2 + b.gt 1f + ld1 {DATA0.4s,DATA1.4s},[INP],#32 + rbit TWEAK0.16b,TWEAK0.16b + rbit TWEAK1.16b,TWEAK1.16b + eor DATA0.16b, DATA0.16b, TWEAK0.16b + eor DATA1.16b, DATA1.16b, TWEAK1.16b + + REV32_EQ(DATA0,DATA0) + REV32_EQ(DATA1,DATA1) + TRANSPOSE(DATA0,DATA1,DATA2,DATA3,VTMP0,VTMP1,VTMP2,VTMP3) + + bl vpsm4_ex_enc_4blks + TRANSPOSE(VTMP0,VTMP1,VTMP2,VTMP3,DATA0,DATA1,DATA2,DATA3) + + eor VTMP0.16b, VTMP0.16b, TWEAK0.16b + eor VTMP1.16b, VTMP1.16b, TWEAK1.16b + st1 {VTMP0.4s,VTMP1.4s},[OUTP],#32 + // save the last tweak + mov LAST_TWEAK.16b,TWEAK1.16b + b 100f +1: // process last 3 blocks + ld1 {DATA0.4s,DATA1.4s,DATA2.4s},[INP],#48 + rbit TWEAK0.16b,TWEAK0.16b + rbit TWEAK1.16b,TWEAK1.16b + rbit TWEAK2.16b,TWEAK2.16b + eor DATA0.16b, DATA0.16b, TWEAK0.16b + eor DATA1.16b, DATA1.16b, TWEAK1.16b + eor DATA2.16b, DATA2.16b, TWEAK2.16b + + REV32_EQ(DATA0,DATA0) + REV32_EQ(DATA1,DATA1) + REV32_EQ(DATA2,DATA2) + + TRANSPOSE(DATA0,DATA1,DATA2,DATA3,VTMP0,VTMP1,VTMP2,VTMP3) + + bl vpsm4_ex_enc_4blks + TRANSPOSE(VTMP0,VTMP1,VTMP2,VTMP3,DATA0,DATA1,DATA2,DATA3) + + eor VTMP0.16b, VTMP0.16b, TWEAK0.16b + eor VTMP1.16b, VTMP1.16b, TWEAK1.16b + eor VTMP2.16b, VTMP2.16b, TWEAK2.16b + st1 {VTMP0.4s,VTMP1.4s,VTMP2.4s},[OUTP],#48 + // save the last tweak + mov LAST_TWEAK.16b,TWEAK2.16b +100: //process end + cmp REMAIN,0 + b.eq .return + +// This brance calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak: + REV32_ARMEB_EQ(LAST_TWEAK,LAST_TWEAK) + COMPUTE_ALPHA_VEC(LAST_TWEAK,TWEAK1) + COMPUTE_ALPHA_VEC(TWEAK1,TWEAK2) + b .check_dec + + +// This brance calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak: + mov TWEAK1.16b,TWEAK0.16b + REV32_ARMEB_EQ(TWEAK1,TWEAK1) + COMPUTE_ALPHA_VEC(TWEAK1,TWEAK2) + + b .check_dec + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec: + // encryption:1 decryption:0 + cmp ENC,1 + b.eq .process_last_2blks + mov VTMP0.16B,TWEAK1.16b + mov TWEAK1.16B,TWEAK2.16b + mov TWEAK2.16B,VTMP0.16b + +.process_last_2blks: + REV32_ARMEB_EQ(TWEAK1,TWEAK1) + REV32_ARMEB_EQ(TWEAK2,TWEAK2) + ld1 {DATA0.4s},[INP],#16 + eor DATA0.16b, DATA0.16b, TWEAK1.16b + REV32_EQ(DATA0,DATA0) + ENCRYPT_1BLK(DATA0,RKS1) + eor DATA0.16b, DATA0.16b, TWEAK1.16b + st1 {DATA0.4s},[OUTP],#16 + + sub LAST_BLK,OUTP,16 + .loop: + subs REMAIN,REMAIN,1 + ldrb WTMP0,[LAST_BLK,REMAIN] + ldrb WTMP1,[INP,REMAIN] + strb WTMP1,[LAST_BLK,REMAIN] + strb WTMP0,[OUTP,REMAIN] + b.gt .loop + ld1 {DATA0.4s}, [LAST_BLK] + eor DATA0.16b, DATA0.16b, TWEAK2.16b + REV32_EQ(DATA0,DATA0) + ENCRYPT_1BLK(DATA0,RKS1) + eor DATA0.16b, DATA0.16b, TWEAK2.16b + st1 {DATA0.4s}, [LAST_BLK] +.return: + /*clear INPUT Data */ + eor DATA0.16b, DATA0.16b, DATA0.16b + eor DATA1.16b, DATA1.16b, DATA1.16b + eor DATA2.16b, DATA2.16b, DATA2.16b + eor DATA3.16b, DATA3.16b, DATA3.16b + eor DATAX0.16b, DATAX0.16b, DATAX0.16b + eor DATAX1.16b, DATAX1.16b, DATAX1.16b + eor DATAX2.16b, DATAX2.16b, DATAX2.16b + eor DATAX3.16b, DATAX3.16b, DATAX3.16b + /*clear user temp key data*/ + eor WTMP0,WTMP0,WTMP0 + eor WTMP1,WTMP1,WTMP1 + + LOAD_STACK() + ret +.size Vpsm4XtsCipher,.-Vpsm4XtsCipher + +/* + * void Vpsm4XtsEncrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, + const SM4_KEY *key2, const uint8_t *iv); + * encryption for sm4-xts + * x0 => in; x1 => out; x2 => length; x3 => key1; x4 => key2; x5 => iv + */ +.globl Vpsm4XtsEncrypt +.type Vpsm4XtsEncrypt,%function +.align 5 +Vpsm4XtsEncrypt: + SAVE_STACK() + mov ENC,1 + bl Vpsm4XtsCipher + LOAD_STACK() + ret +.size Vpsm4XtsEncrypt,.-Vpsm4XtsEncrypt + +/* + * void Vpsm4XtsDecrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, + const SM4_KEY *key2, const uint8_t *iv); + * decryption for sm4-xts + * x0 => in; x1 => out; x2 => length; x3 => key1; x4 => key2; x5 => iv + */ +.globl Vpsm4XtsDecrypt +.type Vpsm4XtsDecrypt,%function +.align 5 +Vpsm4XtsDecrypt: + SAVE_STACK() + mov ENC,0 + bl Vpsm4XtsCipher + LOAD_STACK() + ret +.size Vpsm4XtsDecrypt,.-Vpsm4XtsDecrypt + +#endif diff --git a/crypto/sm4/src/asm/crypt_sm4_xts_x86_64.S b/crypto/sm4/src/asm/crypt_sm4_xts_x86_64.S new file mode 100644 index 00000000..aa0201af --- /dev/null +++ b/crypto/sm4/src/asm/crypt_sm4_xts_x86_64.S @@ -0,0 +1,635 @@ +/* + * 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_SM4 + +#include "crypt_sm4_macro_x86_64.s" + +.file "crypt_sm4_xts_x86_64.S" +.text + +.set X0,%ymm0 +.set X1,%ymm1 +.set X2,%ymm2 +.set X3,%ymm3 + +.set T0,%ymm4 +.set T1,%ymm5 +.set T2,%ymm6 + +.set Y0,%ymm7 +.set Y1,%ymm8 +.set Y2,%ymm9 +.set Y3,%ymm10 + +.set V0,%ymm11 +.set V1,%ymm12 +.set V2,%ymm13 + +.set RK,%rdx + +.set XORMASK_2,%ymm14 +.set LOADMASK_2,T0 +.set STOREMASK_2,T1 +.set SHUFFLEMASK_2,T2 + +.set AES_MASK, %ymm15 +.set AND_MASK, %ymm14 +.set ENDIAN_MASK, %xmm14 +.set G_TMP_2,%ymm15 + +.macro GALOIS_FIELD_MUL Idx + #r8 = t[0], r10 = t[0] + #r9 = t[1], r11 = t[1] + + movq %r8,%r10 + movq %r9,%r11 + + shlq $63,%r10 + shrq $1,%r9 + addq %r10,%r9 + + shrq $1,%r8 + andq $1,%r11 + movq $0xe1,%r10 + shlq $56, %r10 + imulq %r10,%r11 + xorq %r11,%r8 + + movbe %r8,\Idx(%rcx) + movbe %r9,\Idx+8(%rcx) + +.endm + +.macro GALOIS_FIELD_MUL_16_INNER + GALOIS_FIELD_MUL 16 + + #T2:T1->T2 + GALOIS_FIELD_MUL 32 + + #T3:T2->T3 + GALOIS_FIELD_MUL 48 + + #T4:T3->T4 + GALOIS_FIELD_MUL 64 + + #T5:T4->T5 + GALOIS_FIELD_MUL 80 + + #T6:T5->T6 + GALOIS_FIELD_MUL 96 + + #T7:T6->T7 + GALOIS_FIELD_MUL 112 + + #T8:T7->T8 + GALOIS_FIELD_MUL 128 + + #T9:T8->T9 + GALOIS_FIELD_MUL 144 + + #T10:T9->T10 + GALOIS_FIELD_MUL 160 + + #T11:T10->T11 + GALOIS_FIELD_MUL 176 + + #T12:T11->T12 + GALOIS_FIELD_MUL 192 + + #T13:T12->T13 + GALOIS_FIELD_MUL 208 + + #T14:T13->T14 + GALOIS_FIELD_MUL 224 + + #T15:T14->T15 + GALOIS_FIELD_MUL 240 +.endm + +.macro GALOIS_FIELD_MUL_16 Idx + movbe \Idx(%rcx),%r8 + movbe \Idx+8(%rcx),%r9 + + #T0:T15->T0 + GALOIS_FIELD_MUL 0 + GALOIS_FIELD_MUL_16_INNER +.endm + +.macro GALOIS_FIELD_MUL_16_1st Idx + movbe \Idx(%rcx),%r8 + movbe \Idx+8(%rcx),%r9 + GALOIS_FIELD_MUL_16_INNER +.endm + + +.macro SM4_XTS_16_EN_INNER + #Prepare Mask + vmovdqa 4096(%rax), XORMASK_2 + vmovdqa 32+4096(%rax), SHUFFLEMASK_2 + vmovdqa 64+4096(%rax), LOADMASK_2 + + subq $256, %rsp + + vmovdqu (%rsi),X0 + vmovdqu 32(%rsi),X1 + vmovdqu 64(%rsi),X2 + vmovdqu 96(%rsi),X3 + + vmovdqu 128(%rsi),Y0 + vmovdqu 128+32(%rsi),Y1 + vmovdqu 128+64(%rsi),Y2 + vmovdqu 128+96(%rsi),Y3 + + vpxor (%rcx),X0,X0 + vpxor 32(%rcx),X1,X1 + vpxor 64(%rcx),X2,X2 + vpxor 96(%rcx),X3,X3 + + vpxor 128(%rcx),Y0,Y0 + vpxor 128+32(%rcx),Y1,Y1 + vpxor 128+64(%rcx),Y2,Y2 + vpxor 128+96(%rcx),Y3,Y3 + + vmovdqu X0,(%rsp) + vmovdqu X1,32(%rsp) + vmovdqu X2,64(%rsp) + vmovdqu X3,96(%rsp) + + vmovdqu Y0,128(%rsp) + vmovdqu Y1,128+32(%rsp) + vmovdqu Y2,128+64(%rsp) + vmovdqu Y3,128+96(%rsp) + + #Load Data + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,0(%rsp,LOADMASK_2,4),X0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,4(%rsp,LOADMASK_2,4),X1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,8(%rsp,LOADMASK_2,4),X2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,12(%rsp,LOADMASK_2,4),X3 + + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+0(%rsp,LOADMASK_2,4),Y0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+4(%rsp,LOADMASK_2,4),Y1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+8(%rsp,LOADMASK_2,4),Y2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+12(%rsp,LOADMASK_2,4),Y3 + + vpshufb SHUFFLEMASK_2,X0,X0 + vpshufb SHUFFLEMASK_2,X1,X1 + vpshufb SHUFFLEMASK_2,X2,X2 + vpshufb SHUFFLEMASK_2,X3,X3 + + vpshufb SHUFFLEMASK_2,Y0,Y0 + vpshufb SHUFFLEMASK_2,Y1,Y1 + vpshufb SHUFFLEMASK_2,Y2,Y2 + vpshufb SHUFFLEMASK_2,Y3,Y3 + + addq $256, %rsp + + vmovdqa 128+4096(%rax), AES_MASK + vmovdqa 288+4096(%rax), AND_MASK + #ROUNDS + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 0 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 4 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 8 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 12 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 16 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 20 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 24 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 28 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 32 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 36 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 40 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 44 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 48 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 52 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 56 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 60 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 64 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 68 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 72 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 76 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 80 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 84 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 88 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 92 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 96 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 100 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 104 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 108 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 112 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 116 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 120 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 124 + + #Store Result + subq $256,%rsp + + #Get Address + leaq SBOX4X_MASK(%rip), %rax + + #Prepare Mask + vmovdqa 32+4096(%rax), SHUFFLEMASK_2 + vmovdqa 96+4096(%rax), STOREMASK_2 + + vpshufb SHUFFLEMASK_2,X0,X0 + vpshufb SHUFFLEMASK_2,X1,X1 + vpshufb SHUFFLEMASK_2,X2,X2 + vpshufb SHUFFLEMASK_2,X3,X3 + + vpshufb SHUFFLEMASK_2,Y0,Y0 + vpshufb SHUFFLEMASK_2,Y1,Y1 + vpshufb SHUFFLEMASK_2,Y2,Y2 + vpshufb SHUFFLEMASK_2,Y3,Y3 + + vmovdqu X3,0(%rsp) + vmovdqu X2,32(%rsp) + vmovdqu X1,64(%rsp) + vmovdqu X0,96(%rsp) + + vmovdqu Y3,128+0(%rsp) + vmovdqu Y2,128+32(%rsp) + vmovdqu Y1,128+64(%rsp) + vmovdqu Y0,128+96(%rsp) + + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,0(%rsp,STOREMASK_2,4),X0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,8(%rsp,STOREMASK_2,4),X1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,16(%rsp,STOREMASK_2,4),X2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,24(%rsp,STOREMASK_2,4),X3 + + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+0(%rsp,STOREMASK_2,4),Y0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+8(%rsp,STOREMASK_2,4),Y1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+16(%rsp,STOREMASK_2,4),Y2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+24(%rsp,STOREMASK_2,4),Y3 + + vpxor (%rcx),X0,X0 + vpxor 32(%rcx),X1,X1 + vpxor 64(%rcx),X2,X2 + vpxor 96(%rcx),X3,X3 + + vpxor 128(%rcx),Y0,Y0 + vpxor 128+32(%rcx),Y1,Y1 + vpxor 128+64(%rcx),Y2,Y2 + vpxor 128+96(%rcx),Y3,Y3 + + + vmovdqu X0,0(%rdi) + vmovdqu X1,32(%rdi) + vmovdqu X2,64(%rdi) + vmovdqu X3,96(%rdi) + + vmovdqu Y0,128+0(%rdi) + vmovdqu Y1,128+32(%rdi) + vmovdqu Y2,128+64(%rdi) + vmovdqu Y3,128+96(%rdi) + + addq $256,%rsp + + vpxor X0,X0,X0 + vpxor X1,X1,X1 + vpxor X2,X2,X2 + vpxor X3,X3,X3 + + vpxor T0,T0,T0 + vpxor T1,T1,T1 + + vpxor Y0,Y0,Y0 + vpxor Y1,Y1,Y1 + vpxor Y2,Y2,Y2 + vpxor Y3,Y3,Y3 + + vpxor V0,V0,V0 + vpxor V1,V1,V1 +.endm + +############################################################################################################################ + + + #void SM4_XTS_16_EncryptBlock1st(uint8_t* cipher, uint8_t* plain, unsigned int* ecb_rk, uint8_t* T); + #cipher %rdi + #plain %rsi + #rk %rdx + #T %rcx + + .globl SM4_XTS_16_EncryptBlock1st + .type SM4_XTS_16_EncryptBlock1st, @function + .align 64 + +SM4_XTS_16_EncryptBlock1st: + #Get Address + leaq SBOX4X_MASK(%rip), %rax + + #compute tweak + GALOIS_FIELD_MUL_16_1st 0 + SM4_XTS_16_EN_INNER + + ret + .size SM4_XTS_16_EncryptBlock1st, .-SM4_XTS_16_EncryptBlock1st + + + #void SM4_XTS_16_EncryptBlock(uint8_t* cipher, uint8_t* plain, unsigned int* ecb_rk, uint8_t* T); + #cipher %rdi + #plain %rsi + #rk %rdx + #T %rcx + + .globl SM4_XTS_16_EncryptBlock + .type SM4_XTS_16_EncryptBlock, @function + .align 64 + +SM4_XTS_16_EncryptBlock: + #Get Address + leaq SBOX4X_MASK(%rip), %rax + + #compute tweak + GALOIS_FIELD_MUL_16 240 + SM4_XTS_16_EN_INNER + + ret + .size SM4_XTS_16_EncryptBlock, .-SM4_XTS_16_EncryptBlock + + +.macro SM4_XTS_16_DE_INNER + #Prepare Mask + vmovdqa 4096(%rax), XORMASK_2 + vmovdqa 32+4096(%rax), SHUFFLEMASK_2 + vmovdqa 64+4096(%rax), LOADMASK_2 + + subq $256, %rsp + + vmovdqu (%rsi),X0 + vmovdqu 32(%rsi),X1 + vmovdqu 64(%rsi),X2 + vmovdqu 96(%rsi),X3 + + vmovdqu 128(%rsi),Y0 + vmovdqu 128+32(%rsi),Y1 + vmovdqu 128+64(%rsi),Y2 + vmovdqu 128+96(%rsi),Y3 + + vpxor (%rcx),X0,X0 + vpxor 32(%rcx),X1,X1 + vpxor 64(%rcx),X2,X2 + vpxor 96(%rcx),X3,X3 + + vpxor 128(%rcx),Y0,Y0 + vpxor 128+32(%rcx),Y1,Y1 + vpxor 128+64(%rcx),Y2,Y2 + vpxor 128+96(%rcx),Y3,Y3 + + vmovdqu X0,(%rsp) + vmovdqu X1,32(%rsp) + vmovdqu X2,64(%rsp) + vmovdqu X3,96(%rsp) + + vmovdqu Y0,128(%rsp) + vmovdqu Y1,128+32(%rsp) + vmovdqu Y2,128+64(%rsp) + vmovdqu Y3,128+96(%rsp) + + #Load Data + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,0(%rsp,LOADMASK_2,4),X0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,4(%rsp,LOADMASK_2,4),X1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,8(%rsp,LOADMASK_2,4),X2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,12(%rsp,LOADMASK_2,4),X3 + + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+0(%rsp,LOADMASK_2,4),Y0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+4(%rsp,LOADMASK_2,4),Y1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+8(%rsp,LOADMASK_2,4),Y2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+12(%rsp,LOADMASK_2,4),Y3 + + vpshufb SHUFFLEMASK_2,X0,X0 + vpshufb SHUFFLEMASK_2,X1,X1 + vpshufb SHUFFLEMASK_2,X2,X2 + vpshufb SHUFFLEMASK_2,X3,X3 + + vpshufb SHUFFLEMASK_2,Y0,Y0 + vpshufb SHUFFLEMASK_2,Y1,Y1 + vpshufb SHUFFLEMASK_2,Y2,Y2 + vpshufb SHUFFLEMASK_2,Y3,Y3 + + addq $256, %rsp + + + vmovdqa 128+4096(%rax), AES_MASK + vmovdqa 288+4096(%rax), AND_MASK + #ROUNDS + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 124 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 120 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 116 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 112 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 108 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 104 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 100 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 96 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 92 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 88 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 84 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 80 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 76 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 72 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 68 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 64 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 60 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 56 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 52 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 48 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 44 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 40 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 36 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 32 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 28 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 24 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 20 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 16 + + SM4_AVX2_AES_2_ROUND X0 X1 X2 X3 Y0 Y1 Y2 Y3 RK 12 + SM4_AVX2_AES_2_ROUND X1 X2 X3 X0 Y1 Y2 Y3 Y0 RK 8 + SM4_AVX2_AES_2_ROUND X2 X3 X0 X1 Y2 Y3 Y0 Y1 RK 4 + SM4_AVX2_AES_2_ROUND X3 X0 X1 X2 Y3 Y0 Y1 Y2 RK 0 + + + #Store Result + subq $256,%rsp + + #Get Address + leaq SBOX4X_MASK(%rip), %rax + + #Prepare Mask + vmovdqa 32+4096(%rax), SHUFFLEMASK_2 + vmovdqa 96+4096(%rax), STOREMASK_2 + + vpshufb SHUFFLEMASK_2,X0,X0 + vpshufb SHUFFLEMASK_2,X1,X1 + vpshufb SHUFFLEMASK_2,X2,X2 + vpshufb SHUFFLEMASK_2,X3,X3 + + vpshufb SHUFFLEMASK_2,Y0,Y0 + vpshufb SHUFFLEMASK_2,Y1,Y1 + vpshufb SHUFFLEMASK_2,Y2,Y2 + vpshufb SHUFFLEMASK_2,Y3,Y3 + + vmovdqu X3,0(%rsp) + vmovdqu X2,32(%rsp) + vmovdqu X1,64(%rsp) + vmovdqu X0,96(%rsp) + + vmovdqu Y3,128+0(%rsp) + vmovdqu Y2,128+32(%rsp) + vmovdqu Y1,128+64(%rsp) + vmovdqu Y0,128+96(%rsp) + + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,0(%rsp,STOREMASK_2,4),X0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,8(%rsp,STOREMASK_2,4),X1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,16(%rsp,STOREMASK_2,4),X2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,24(%rsp,STOREMASK_2,4),X3 + + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+0(%rsp,STOREMASK_2,4),Y0 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+8(%rsp,STOREMASK_2,4),Y1 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+16(%rsp,STOREMASK_2,4),Y2 + vpcmpeqd G_TMP_2,G_TMP_2,G_TMP_2 + vpgatherdd G_TMP_2,128+24(%rsp,STOREMASK_2,4),Y3 + + vpxor (%rcx),X0,X0 + vpxor 32(%rcx),X1,X1 + vpxor 64(%rcx),X2,X2 + vpxor 96(%rcx),X3,X3 + + vpxor 128(%rcx),Y0,Y0 + vpxor 128+32(%rcx),Y1,Y1 + vpxor 128+64(%rcx),Y2,Y2 + vpxor 128+96(%rcx),Y3,Y3 + + + vmovdqu X0,0(%rdi) + vmovdqu X1,32(%rdi) + vmovdqu X2,64(%rdi) + vmovdqu X3,96(%rdi) + + vmovdqu Y0,128+0(%rdi) + vmovdqu Y1,128+32(%rdi) + vmovdqu Y2,128+64(%rdi) + vmovdqu Y3,128+96(%rdi) + + addq $256,%rsp + + vpxor X0,X0,X0 + vpxor X1,X1,X1 + vpxor X2,X2,X2 + vpxor X3,X3,X3 + + vpxor T0,T0,T0 + vpxor T1,T1,T1 + + vpxor Y0,Y0,Y0 + vpxor Y1,Y1,Y1 + vpxor Y2,Y2,Y2 + vpxor Y3,Y3,Y3 + + vpxor V0,V0,V0 + vpxor V1,V1,V1 +.endm + +####################################################################### + + + #void SM4_XTS_16_DecryptBlock1st(uint8_t* plain, uint8_t* cipher, unsigned int* ecb_rk, uint8_t* T); + #plain %rdi + #cipher %rsi + #rk %rdx + #T %rcx + + .globl SM4_XTS_16_DecryptBlock1st + .type SM4_XTS_16_DecryptBlock1st, @function + .align 64 + +SM4_XTS_16_DecryptBlock1st: + #Get Address + leaq SBOX4X_MASK(%rip), %rax + + #compute tweak + GALOIS_FIELD_MUL_16_1st 0 + SM4_XTS_16_DE_INNER + + ret + .size SM4_XTS_16_DecryptBlock1st, .-SM4_XTS_16_DecryptBlock1st + + + + #void SM4_XTS_16_DecryptBlock(uint8_t* plain, uint8_t* cipher, unsigned int* ecb_rk, uint8_t* T); + #plain %rdi + #cipher %rsi + #rk %rdx + #T %rcx + + .globl SM4_XTS_16_DecryptBlock + .type SM4_XTS_16_DecryptBlock, @function + .align 64 + +SM4_XTS_16_DecryptBlock: + #Get Address + leaq SBOX4X_MASK(%rip), %rax + + #compute tweak + GALOIS_FIELD_MUL_16 240 + SM4_XTS_16_DE_INNER + + ret + .size SM4_XTS_16_DecryptBlock, .-SM4_XTS_16_DecryptBlock + +#endif diff --git a/crypto/sm4/src/crypt_sm4.c b/crypto/sm4/src/crypt_sm4.c new file mode 100644 index 00000000..deb37af6 --- /dev/null +++ b/crypto/sm4/src/crypt_sm4.c @@ -0,0 +1,260 @@ +/* + * 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_SM4 + +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "crypt_sm4.h" + +/** + * <<<: Cyclic shift to the left + * ⊕: XOR + * S-box: (see GB/T 32907-2016 6.2 a or GM/T 0002-2012 6.2 1) + * L(B) = B⊕(B <<< 2)⊕(B <<< 10)⊕(B <<< 18)⊕(B <<< 24) + * XBOX_0[i] = L(SBOX[i]) + */ +static const uint32_t XBOX_0[] = { + 0xd55b5b8e, 0x924242d0, 0xeaa7a74d, 0xfdfbfb06, 0xcf3333fc, 0xe2878765, 0x3df4f4c9, 0xb5dede6b, + 0x1658584e, 0xb4dada6e, 0x14505044, 0xc10b0bca, 0x28a0a088, 0xf8efef17, 0x2cb0b09c, 0x05141411, + 0x2bacac87, 0x669d9dfb, 0x986a6af2, 0x77d9d9ae, 0x2aa8a882, 0xbcfafa46, 0x04101014, 0xc00f0fcf, + 0xa8aaaa02, 0x45111154, 0x134c4c5f, 0x269898be, 0x4825256d, 0x841a1a9e, 0x0618181e, 0x9b6666fd, + 0x9e7272ec, 0x4309094a, 0x51414110, 0xf7d3d324, 0x934646d5, 0xecbfbf53, 0x9a6262f8, 0x7be9e992, + 0x33ccccff, 0x55515104, 0x0b2c2c27, 0x420d0d4f, 0xeeb7b759, 0xcc3f3ff3, 0xaeb2b21c, 0x638989ea, + 0xe7939374, 0xb1cece7f, 0x1c70706c, 0xaba6a60d, 0xca2727ed, 0x08202028, 0xeba3a348, 0x975656c1, + 0x82020280, 0xdc7f7fa3, 0x965252c4, 0xf9ebeb12, 0x74d5d5a1, 0x8d3e3eb3, 0x3ffcfcc3, 0xa49a9a3e, + 0x461d1d5b, 0x071c1c1b, 0xa59e9e3b, 0xfff3f30c, 0xf0cfcf3f, 0x72cdcdbf, 0x175c5c4b, 0xb8eaea52, + 0x810e0e8f, 0x5865653d, 0x3cf0f0cc, 0x1964647d, 0xe59b9b7e, 0x87161691, 0x4e3d3d73, 0xaaa2a208, + 0x69a1a1c8, 0x6aadadc7, 0x83060685, 0xb0caca7a, 0x70c5c5b5, 0x659191f4, 0xd96b6bb2, 0x892e2ea7, + 0xfbe3e318, 0xe8afaf47, 0x0f3c3c33, 0x4a2d2d67, 0x71c1c1b0, 0x5759590e, 0x9f7676e9, 0x35d4d4e1, + 0x1e787866, 0x249090b4, 0x0e383836, 0x5f797926, 0x628d8def, 0x59616138, 0xd2474795, 0xa08a8a2a, + 0x259494b1, 0x228888aa, 0x7df1f18c, 0x3bececd7, 0x01040405, 0x218484a5, 0x79e1e198, 0x851e1e9b, + 0xd7535384, 0x00000000, 0x4719195e, 0x565d5d0b, 0x9d7e7ee3, 0xd04f4f9f, 0x279c9cbb, 0x5349491a, + 0x4d31317c, 0x36d8d8ee, 0x0208080a, 0xe49f9f7b, 0xa2828220, 0xc71313d4, 0xcb2323e8, 0x9c7a7ae6, + 0xe9abab42, 0xbdfefe43, 0x882a2aa2, 0xd14b4b9a, 0x41010140, 0xc41f1fdb, 0x38e0e0d8, 0xb7d6d661, + 0xa18e8e2f, 0xf4dfdf2b, 0xf1cbcb3a, 0xcd3b3bf6, 0xfae7e71d, 0x608585e5, 0x15545441, 0xa3868625, + 0xe3838360, 0xacbaba16, 0x5c757529, 0xa6929234, 0x996e6ef7, 0x34d0d0e4, 0x1a686872, 0x54555501, + 0xafb6b619, 0x914e4edf, 0x32c8c8fa, 0x30c0c0f0, 0xf6d7d721, 0x8e3232bc, 0xb3c6c675, 0xe08f8f6f, + 0x1d747469, 0xf5dbdb2e, 0xe18b8b6a, 0x2eb8b896, 0x800a0a8a, 0x679999fe, 0xc92b2be2, 0x618181e0, + 0xc30303c0, 0x29a4a48d, 0x238c8caf, 0xa9aeae07, 0x0d343439, 0x524d4d1f, 0x4f393976, 0x6ebdbdd3, + 0xd6575781, 0xd86f6fb7, 0x37dcdceb, 0x44151551, 0xdd7b7ba6, 0xfef7f709, 0x8c3a3ab6, 0x2fbcbc93, + 0x030c0c0f, 0xfcffff03, 0x6ba9a9c2, 0x73c9c9ba, 0x6cb5b5d9, 0x6db1b1dc, 0x5a6d6d37, 0x50454515, + 0x8f3636b9, 0x1b6c6c77, 0xadbebe13, 0x904a4ada, 0xb9eeee57, 0xde7777a9, 0xbef2f24c, 0x7efdfd83, + 0x11444455, 0xda6767bd, 0x5d71712c, 0x40050545, 0x1f7c7c63, 0x10404050, 0x5b696932, 0xdb6363b8, + 0x0a282822, 0xc20707c5, 0x31c4c4f5, 0x8a2222a8, 0xa7969631, 0xce3737f9, 0x7aeded97, 0xbff6f649, + 0x2db4b499, 0x75d1d1a4, 0xd3434390, 0x1248485a, 0xbae2e258, 0xe6979771, 0xb6d2d264, 0xb2c2c270, + 0x8b2626ad, 0x68a5a5cd, 0x955e5ecb, 0x4b292962, 0x0c30303c, 0x945a5ace, 0x76ddddab, 0x7ff9f986, + 0x649595f1, 0xbbe6e65d, 0xf2c7c735, 0x0924242d, 0xc61717d1, 0x6fb9b9d6, 0xc51b1bde, 0x86121294, + 0x18606078, 0xf3c3c330, 0x7cf5f589, 0xefb3b35c, 0x3ae8e8d2, 0xdf7373ac, 0x4c353579, 0x208080a0, + 0x78e5e59d, 0xedbbbb56, 0x5e7d7d23, 0x3ef8f8c6, 0xd45f5f8b, 0xc82f2fe7, 0x39e4e4dd, 0x49212168, +}; + +/* XBOX_1[i] = XBOX_0[i] <<< 8 */ +static const uint32_t XBOX_1[] = { + 0x5b5b8ed5, 0x4242d092, 0xa7a74dea, 0xfbfb06fd, 0x3333fccf, 0x878765e2, 0xf4f4c93d, 0xdede6bb5, + 0x58584e16, 0xdada6eb4, 0x50504414, 0x0b0bcac1, 0xa0a08828, 0xefef17f8, 0xb0b09c2c, 0x14141105, + 0xacac872b, 0x9d9dfb66, 0x6a6af298, 0xd9d9ae77, 0xa8a8822a, 0xfafa46bc, 0x10101404, 0x0f0fcfc0, + 0xaaaa02a8, 0x11115445, 0x4c4c5f13, 0x9898be26, 0x25256d48, 0x1a1a9e84, 0x18181e06, 0x6666fd9b, + 0x7272ec9e, 0x09094a43, 0x41411051, 0xd3d324f7, 0x4646d593, 0xbfbf53ec, 0x6262f89a, 0xe9e9927b, + 0xccccff33, 0x51510455, 0x2c2c270b, 0xd0d4f42, 0xb7b759ee, 0x3f3ff3cc, 0xb2b21cae, 0x8989ea63, + 0x939374e7, 0xcece7fb1, 0x70706c1c, 0xa6a60dab, 0x2727edca, 0x20202808, 0xa3a348eb, 0x5656c197, + 0x02028082, 0x7f7fa3dc, 0x5252c496, 0xebeb12f9, 0xd5d5a174, 0x3e3eb38d, 0xfcfcc33f, 0x9a9a3ea4, + 0x1d1d5b46, 0x1c1c1b07, 0x9e9e3ba5, 0xf3f30cff, 0xcfcf3ff0, 0xcdcdbf72, 0x5c5c4b17, 0xeaea52b8, + 0x0e0e8f81, 0x65653d58, 0xf0f0cc3c, 0x64647d19, 0x9b9b7ee5, 0x16169187, 0x3d3d734e, 0xa2a208aa, + 0xa1a1c869, 0xadadc76a, 0x06068583, 0xcaca7ab0, 0xc5c5b570, 0x9191f465, 0x6b6bb2d9, 0x2e2ea789, + 0xe3e318fb, 0xafaf47e8, 0x3c3c330f, 0x2d2d674a, 0xc1c1b071, 0x59590e57, 0x7676e99f, 0xd4d4e135, + 0x7878661e, 0x9090b424, 0x3838360e, 0x7979265f, 0x8d8def62, 0x61613859, 0x474795d2, 0x8a8a2aa0, + 0x9494b125, 0x8888aa22, 0xf1f18c7d, 0xececd73b, 0x04040501, 0x8484a521, 0xe1e19879, 0x1e1e9b85, + 0x535384d7, 0x00000000, 0x19195e47, 0x5d5d0b56, 0x7e7ee39d, 0x4f4f9fd0, 0x9c9cbb27, 0x49491a53, + 0x31317c4d, 0xd8d8ee36, 0x08080a02, 0x9f9f7be4, 0x828220a2, 0x1313d4c7, 0x2323e8cb, 0x7a7ae69c, + 0xabab42e9, 0xfefe43bd, 0x2a2aa288, 0x4b4b9ad1, 0x01014041, 0x1f1fdbc4, 0xe0e0d838, 0xd6d661b7, + 0x8e8e2fa1, 0xdfdf2bf4, 0xcbcb3af1, 0x3b3bf6cd, 0xe7e71dfa, 0x8585e560, 0x54544115, 0x868625a3, + 0x838360e3, 0xbaba16ac, 0x7575295c, 0x929234a6, 0x6e6ef799, 0xd0d0e434, 0x6868721a, 0x55550154, + 0xb6b619af, 0x4e4edf91, 0xc8c8fa32, 0xc0c0f030, 0xd7d721f6, 0x3232bc8e, 0xc6c675b3, 0x8f8f6fe0, + 0x7474691d, 0xdbdb2ef5, 0x8b8b6ae1, 0xb8b8962e, 0x0a0a8a80, 0x9999fe67, 0x2b2be2c9, 0x8181e061, + 0x0303c0c3, 0xa4a48d29, 0x8c8caf23, 0xaeae07a9, 0x3434390d, 0x4d4d1f52, 0x3939764f, 0xbdbdd36e, + 0x575781d6, 0x6f6fb7d8, 0xdcdceb37, 0x15155144, 0x7b7ba6dd, 0xf7f709fe, 0x3a3ab68c, 0xbcbc932f, + 0x0c0c0f03, 0xffff03fc, 0xa9a9c26b, 0xc9c9ba73, 0xb5b5d96c, 0xb1b1dc6d, 0x6d6d375a, 0x45451550, + 0x3636b98f, 0x6c6c771b, 0xbebe13ad, 0x4a4ada90, 0xeeee57b9, 0x7777a9de, 0xf2f24cbe, 0xfdfd837e, + 0x44445511, 0x6767bdda, 0x71712c5d, 0x05054540, 0x7c7c631f, 0x40405010, 0x6969325b, 0x6363b8db, + 0x2828220a, 0x0707c5c2, 0xc4c4f531, 0x2222a88a, 0x969631a7, 0x3737f9ce, 0xeded977a, 0xf6f649bf, + 0xb4b4992d, 0xd1d1a475, 0x434390d3, 0x48485a12, 0xe2e258ba, 0x979771e6, 0xd2d264b6, 0xc2c270b2, + 0x2626ad8b, 0xa5a5cd68, 0x5e5ecb95, 0x2929624b, 0x30303c0c, 0x5a5ace94, 0xddddab76, 0xf9f9867f, + 0x9595f164, 0xe6e65dbb, 0xc7c735f2, 0x24242d09, 0x1717d1c6, 0xb9b9d66f, 0x1b1bdec5, 0x12129486, + 0x60607818, 0xc3c330f3, 0xf5f5897c, 0xb3b35cef, 0xe8e8d23a, 0x7373acdf, 0x3535794c, 0x8080a020, + 0xe5e59d78, 0xbbbb56ed, 0x7d7d235e, 0xf8f8c63e, 0x5f5f8bd4, 0x2f2fe7c8, 0xe4e4dd39, 0x21216849, +}; + +/* XBOX_2[i] = XBOX_0[i] <<< 16 */ +static const uint32_t XBOX_2[] = { + 0x5b8ed55b, 0x42d09242, 0xa74deaa7, 0xfb06fdfb, 0x33fccf33, 0x8765e287, 0xf4c93df4, 0xde6bb5de, + 0x584e1658, 0xda6eb4da, 0x50441450, 0x0bcac10b, 0xa08828a0, 0xef17f8ef, 0xb09c2cb0, 0x14110514, + 0xac872bac, 0x9dfb669d, 0x6af2986a, 0xd9ae77d9, 0xa8822aa8, 0xfa46bcfa, 0x10140410, 0x0fcfc00f, + 0xaa02a8aa, 0x11544511, 0x4c5f134c, 0x98be2698, 0x256d4825, 0x1a9e841a, 0x181e0618, 0x66fd9b66, + 0x72ec9e72, 0x094a4309, 0x41105141, 0xd324f7d3, 0x46d59346, 0xbf53ecbf, 0x62f89a62, 0xe9927be9, + 0xccff33cc, 0x51045551, 0x2c270b2c, 0x0d4f420d, 0xb759eeb7, 0x3ff3cc3f, 0xb21caeb2, 0x89ea6389, + 0x9374e793, 0xce7fb1ce, 0x706c1c70, 0xa60daba6, 0x27edca27, 0x20280820, 0xa348eba3, 0x56c19756, + 0x02808202, 0x7fa3dc7f, 0x52c49652, 0xeb12f9eb, 0xd5a174d5, 0x3eb38d3e, 0xfcc33ffc, 0x9a3ea49a, + 0x1d5b461d, 0x1c1b071c, 0x9e3ba59e, 0xf30cfff3, 0xcf3ff0cf, 0xcdbf72cd, 0x5c4b175c, 0xea52b8ea, + 0x0e8f810e, 0x653d5865, 0xf0cc3cf0, 0x647d1964, 0x9b7ee59b, 0x16918716, 0x3d734e3d, 0xa208aaa2, + 0xa1c869a1, 0xadc76aad, 0x06858306, 0xca7ab0ca, 0xc5b570c5, 0x91f46591, 0x6bb2d96b, 0x2ea7892e, + 0xe318fbe3, 0xaf47e8af, 0x3c330f3c, 0x2d674a2d, 0xc1b071c1, 0x590e5759, 0x76e99f76, 0xd4e135d4, + 0x78661e78, 0x90b42490, 0x38360e38, 0x79265f79, 0x8def628d, 0x61385961, 0x4795d247, 0x8a2aa08a, + 0x94b12594, 0x88aa2288, 0xf18c7df1, 0xecd73bec, 0x04050104, 0x84a52184, 0xe19879e1, 0x1e9b851e, + 0x5384d753, 0x00000000, 0x195e4719, 0x5d0b565d, 0x7ee39d7e, 0x4f9fd04f, 0x9cbb279c, 0x491a5349, + 0x317c4d31, 0xd8ee36d8, 0x080a0208, 0x9f7be49f, 0x8220a282, 0x13d4c713, 0x23e8cb23, 0x7ae69c7a, + 0xab42e9ab, 0xfe43bdfe, 0x2aa2882a, 0x4b9ad14b, 0x01404101, 0x1fdbc41f, 0xe0d838e0, 0xd661b7d6, + 0x8e2fa18e, 0xdf2bf4df, 0xcb3af1cb, 0x3bf6cd3b, 0xe71dfae7, 0x85e56085, 0x54411554, 0x8625a386, + 0x8360e383, 0xba16acba, 0x75295c75, 0x9234a692, 0x6ef7996e, 0xd0e434d0, 0x68721a68, 0x55015455, + 0xb619afb6, 0x4edf914e, 0xc8fa32c8, 0xc0f030c0, 0xd721f6d7, 0x32bc8e32, 0xc675b3c6, 0x8f6fe08f, + 0x74691d74, 0xdb2ef5db, 0x8b6ae18b, 0xb8962eb8, 0x0a8a800a, 0x99fe6799, 0x2be2c92b, 0x81e06181, + 0x03c0c303, 0xa48d29a4, 0x8caf238c, 0xae07a9ae, 0x34390d34, 0x4d1f524d, 0x39764f39, 0xbdd36ebd, + 0x5781d657, 0x6fb7d86f, 0xdceb37dc, 0x15514415, 0x7ba6dd7b, 0xf709fef7, 0x3ab68c3a, 0xbc932fbc, + 0x0c0f030c, 0xff03fcff, 0xa9c26ba9, 0xc9ba73c9, 0xb5d96cb5, 0xb1dc6db1, 0x6d375a6d, 0x45155045, + 0x36b98f36, 0x6c771b6c, 0xbe13adbe, 0x4ada904a, 0xee57b9ee, 0x77a9de77, 0xf24cbef2, 0xfd837efd, + 0x44551144, 0x67bdda67, 0x712c5d71, 0x05454005, 0x7c631f7c, 0x40501040, 0x69325b69, 0x63b8db63, + 0x28220a28, 0x07c5c207, 0xc4f531c4, 0x22a88a22, 0x9631a796, 0x37f9ce37, 0xed977aed, 0xf649bff6, + 0xb4992db4, 0xd1a475d1, 0x4390d343, 0x485a1248, 0xe258bae2, 0x9771e697, 0xd264b6d2, 0xc270b2c2, + 0x26ad8b26, 0xa5cd68a5, 0x5ecb955e, 0x29624b29, 0x303c0c30, 0x5ace945a, 0xddab76dd, 0xf9867ff9, + 0x95f16495, 0xe65dbbe6, 0xc735f2c7, 0x242d0924, 0x17d1c617, 0xb9d66fb9, 0x1bdec51b, 0x12948612, + 0x60781860, 0xc330f3c3, 0xf5897cf5, 0xb35cefb3, 0xe8d23ae8, 0x73acdf73, 0x35794c35, 0x80a02080, + 0xe59d78e5, 0xbb56edbb, 0x7d235e7d, 0xf8c63ef8, 0x5f8bd45f, 0x2fe7c82f, 0xe4dd39e4, 0x21684921, +}; + +/* XBOX_3[i] = XBOX_0[i] <<< 24 */ +static const uint32_t XBOX_3[] = { + 0x8ed55b5b, 0xd0924242, 0x4deaa7a7, 0x06fdfbfb, 0xfccf3333, 0x65e28787, 0xc93df4f4, 0x6bb5dede, + 0x4e165858, 0x6eb4dada, 0x44145050, 0xcac10b0b, 0x8828a0a0, 0x17f8efef, 0x9c2cb0b0, 0x11051414, + 0x872bacac, 0xfb669d9d, 0xf2986a6a, 0xae77d9d9, 0x822aa8a8, 0x46bcfafa, 0x14041010, 0xcfc00f0f, + 0x02a8aaaa, 0x54451111, 0x5f134c4c, 0xbe269898, 0x6d482525, 0x9e841a1a, 0x1e061818, 0xfd9b6666, + 0xec9e7272, 0x4a430909, 0x10514141, 0x24f7d3d3, 0xd5934646, 0x53ecbfbf, 0xf89a6262, 0x927be9e9, + 0xff33cccc, 0x04555151, 0x270b2c2c, 0x4f420d0d, 0x59eeb7b7, 0xf3cc3f3f, 0x1caeb2b2, 0xea638989, + 0x74e79393, 0x7fb1cece, 0x6c1c7070, 0x0daba6a6, 0xedca2727, 0x28082020, 0x48eba3a3, 0xc1975656, + 0x80820202, 0xa3dc7f7f, 0xc4965252, 0x12f9ebeb, 0xa174d5d5, 0xb38d3e3e, 0xc33ffcfc, 0x3ea49a9a, + 0x5b461d1d, 0x1b071c1c, 0x3ba59e9e, 0x0cfff3f3, 0x3ff0cfcf, 0xbf72cdcd, 0x4b175c5c, 0x52b8eaea, + 0x8f810e0e, 0x3d586565, 0xcc3cf0f0, 0x7d196464, 0x7ee59b9b, 0x91871616, 0x734e3d3d, 0x08aaa2a2, + 0xc869a1a1, 0xc76aadad, 0x85830606, 0x7ab0caca, 0xb570c5c5, 0xf4659191, 0xb2d96b6b, 0xa7892e2e, + 0x18fbe3e3, 0x47e8afaf, 0x330f3c3c, 0x674a2d2d, 0xb071c1c1, 0x0e575959, 0xe99f7676, 0xe135d4d4, + 0x661e7878, 0xb4249090, 0x360e3838, 0x265f7979, 0xef628d8d, 0x38596161, 0x95d24747, 0x2aa08a8a, + 0xb1259494, 0xaa228888, 0x8c7df1f1, 0xd73becec, 0x05010404, 0xa5218484, 0x9879e1e1, 0x9b851e1e, + 0x84d75353, 0x00000000, 0x5e471919, 0x0b565d5d, 0xe39d7e7e, 0x9fd04f4f, 0xbb279c9c, 0x1a534949, + 0x7c4d3131, 0xee36d8d8, 0x0a020808, 0x7be49f9f, 0x20a28282, 0xd4c71313, 0xe8cb2323, 0xe69c7a7a, + 0x42e9abab, 0x43bdfefe, 0xa2882a2a, 0x9ad14b4b, 0x40410101, 0xdbc41f1f, 0xd838e0e0, 0x61b7d6d6, + 0x2fa18e8e, 0x2bf4dfdf, 0x3af1cbcb, 0xf6cd3b3b, 0x1dfae7e7, 0xe5608585, 0x41155454, 0x25a38686, + 0x60e38383, 0x16acbaba, 0x295c7575, 0x34a69292, 0xf7996e6e, 0xe434d0d0, 0x721a6868, 0x01545555, + 0x19afb6b6, 0xdf914e4e, 0xfa32c8c8, 0xf030c0c0, 0x21f6d7d7, 0xbc8e3232, 0x75b3c6c6, 0x6fe08f8f, + 0x691d7474, 0x2ef5dbdb, 0x6ae18b8b, 0x962eb8b8, 0x8a800a0a, 0xfe679999, 0xe2c92b2b, 0xe0618181, + 0xc0c30303, 0x8d29a4a4, 0xaf238c8c, 0x07a9aeae, 0x390d3434, 0x1f524d4d, 0x764f3939, 0xd36ebdbd, + 0x81d65757, 0xb7d86f6f, 0xeb37dcdc, 0x51441515, 0xa6dd7b7b, 0x09fef7f7, 0xb68c3a3a, 0x932fbcbc, + 0x0f030c0c, 0x03fcffff, 0xc26ba9a9, 0xba73c9c9, 0xd96cb5b5, 0xdc6db1b1, 0x375a6d6d, 0x15504545, + 0xb98f3636, 0x771b6c6c, 0x13adbebe, 0xda904a4a, 0x57b9eeee, 0xa9de7777, 0x4cbef2f2, 0x837efdfd, + 0x55114444, 0xbdda6767, 0x2c5d7171, 0x45400505, 0x631f7c7c, 0x50104040, 0x325b6969, 0xb8db6363, + 0x220a2828, 0xc5c20707, 0xf531c4c4, 0xa88a2222, 0x31a79696, 0xf9ce3737, 0x977aeded, 0x49bff6f6, + 0x992db4b4, 0xa475d1d1, 0x90d34343, 0x5a124848, 0x58bae2e2, 0x71e69797, 0x64b6d2d2, 0x70b2c2c2, + 0xad8b2626, 0xcd68a5a5, 0xcb955e5e, 0x624b2929, 0x3c0c3030, 0xce945a5a, 0xab76dddd, 0x867ff9f9, + 0xf1649595, 0x5dbbe6e6, 0x35f2c7c7, 0x2d092424, 0xd1c61717, 0xd66fb9b9, 0xdec51b1b, 0x94861212, + 0x78186060, 0x30f3c3c3, 0x897cf5f5, 0x5cefb3b3, 0xd23ae8e8, 0xacdf7373, 0x794c3535, 0xa0208080, + 0x9d78e5e5, 0x56edbbbb, 0x235e7d7d, 0xc63ef8f8, 0x8bd45f5f, 0xe7c82f2f, 0xdd39e4e4, 0x68492121, +}; + +/* X(i+4) = F(Xi Xi+1 Xi+2 Xi+3 rk[i]),i = 0,1,...,31; */ +#define ENC_ROUND_FUNCTION(t, x0, x1, x2, x3, roundKey, sbox) \ + for (int i = 0; i < 32; i += 4) { \ + ROUND((t), (x0), (x1), (x2), (x3), (roundKey)[(i) + 0], sbox); \ + ROUND((t), (x1), (x2), (x3), (x0), (roundKey)[(i) + 1], sbox); \ + ROUND((t), (x2), (x3), (x0), (x1), (roundKey)[(i) + 2], sbox); \ + ROUND((t), (x3), (x0), (x1), (x2), (roundKey)[(i) + 3], sbox); \ + } + +/* X(i+4) = F(Xi Xi+1 Xi+2 Xi+3 rk[31 - i]),i = 0,1,...,31; */ +#define DEC_ROUND_FUNCTION(t, x0, x1, x2, x3, roundKey, sbox) \ + for (int i = 28; i >= 0; i -= 4) { \ + ROUND((t), (x0), (x1), (x2), (x3), (roundKey)[(i) + 3], sbox); \ + ROUND((t), (x1), (x2), (x3), (x0), (roundKey)[(i) + 2], sbox); \ + ROUND((t), (x2), (x3), (x0), (x1), (roundKey)[(i) + 1], sbox); \ + ROUND((t), (x3), (x0), (x1), (x2), (roundKey)[(i) + 0], sbox); \ + } + +/* enc is true: encrypt, enc is false: decrypt */ +static void SM4_Crypt(uint8_t *out, const uint8_t *in, const uint32_t *rk, uint32_t x[5], bool enc) +{ + x[0] = GET_UINT32_BE(in, 0); + x[1] = GET_UINT32_BE(in, 4); + x[2] = GET_UINT32_BE(in, 8); + x[3] = GET_UINT32_BE(in, 12); + + /* Round function */ + if (enc) { + ENC_ROUND_FUNCTION(x[4], x[0], x[1], x[2], x[3], rk, XBOX); + } else { + DEC_ROUND_FUNCTION(x[4], x[0], x[1], x[2], x[3], rk, XBOX); + } + + /* Reverse R(X32 X33 X34 X35) = (X35 X34 X33 X32) */ + PUT_UINT32_BE(x[3], out, 0); + PUT_UINT32_BE(x[2], out, 4); + PUT_UINT32_BE(x[1], out, 8); + PUT_UINT32_BE(x[0], out, 12); +} + +static int32_t CRYPT_SM4_Crypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length, bool enc) +{ + if (ctx == NULL || in == NULL || out == NULL || length == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (length % CRYPT_SM4_BLOCKSIZE != 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + + uint32_t x[5]; + uint32_t blocks = length / CRYPT_SM4_BLOCKSIZE; + for (uint32_t i = 0; i < blocks; i++) { + SM4_Crypt(out + i * CRYPT_SM4_BLOCKSIZE, in + i * CRYPT_SM4_BLOCKSIZE, ctx->rk, x, enc); + } + + if (!enc) { + (void)memset_s(x, sizeof(x), 0, sizeof(x)); + } + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length) +{ + return CRYPT_SM4_Crypt(ctx, in, out, length, true); +} + +int32_t CRYPT_SM4_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length) +{ + return CRYPT_SM4_Crypt(ctx, in, out, length, false); +} + +void CRYPT_SM4_Clean(CRYPT_SM4_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SM4_Ctx)); +} +#endif // HITLS_CRYPTO_SM4 diff --git a/crypto/sm4/src/crypt_sm4_armv8.c b/crypto/sm4/src/crypt_sm4_armv8.c new file mode 100644 index 00000000..f3c232b6 --- /dev/null +++ b/crypto/sm4/src/crypt_sm4_armv8.c @@ -0,0 +1,224 @@ +/* + * 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_SM4 + +#include "crypt_sm4_armv8.h" +#include "crypt_sm4.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" + +#ifdef HITLS_CRYPTO_XTS +// key[0..16]: data key +// key[16..32]: tweak key +int32_t CRYPT_SM4_XTS_SetEncryptKey(CRYPT_SM4_Ctx *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 != XTS_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN); + return CRYPT_SM4_ERR_KEY_LEN; + } + + if (memcmp(key, key + CRYPT_SM4_BLOCKSIZE, CRYPT_SM4_BLOCKSIZE) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_UNSAFE_KEY); + return CRYPT_SM4_UNSAFE_KEY; + } + CRYPT_SM4_Ctx *tmk = (CRYPT_SM4_Ctx *)&ctx[1]; + Vpsm4SetEncryptKey(key, (SM4_KEY *)ctx->rk); + Vpsm4SetEncryptKey(key + CRYPT_SM4_BLOCKSIZE, (SM4_KEY *)tmk->rk); + + return CRYPT_SUCCESS; +} + +// key[0..16]: data key +// key[16..32]: tweak key +int32_t CRYPT_SM4_XTS_SetDecryptKey(CRYPT_SM4_Ctx *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 != XTS_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN); + return CRYPT_SM4_ERR_KEY_LEN; + } + + if (memcmp(key, key + CRYPT_SM4_BLOCKSIZE, CRYPT_SM4_BLOCKSIZE) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_UNSAFE_KEY); + return CRYPT_SM4_UNSAFE_KEY; + } + CRYPT_SM4_Ctx *tmk = (CRYPT_SM4_Ctx *)&ctx[1]; + Vpsm4SetDecryptKey(key, (SM4_KEY *)ctx->rk); + Vpsm4SetEncryptKey(key + CRYPT_SM4_BLOCKSIZE, (SM4_KEY *)tmk->rk); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_XTS_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + CRYPT_SM4_Ctx *tmk = NULL; + if (ctx == NULL || iv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + tmk = (CRYPT_SM4_Ctx *)&ctx[1]; + Vpsm4XtsEncrypt(in, out, len, (const SM4_KEY *)ctx->rk, (const SM4_KEY *)tmk->rk, iv); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_XTS_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + CRYPT_SM4_Ctx *tmk = NULL; + if (ctx == NULL || iv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + tmk = (CRYPT_SM4_Ctx *)&ctx[1]; + Vpsm4XtsDecrypt(in, out, len, (const SM4_KEY *)ctx->rk, (const SM4_KEY *)tmk->rk, iv); + + return CRYPT_SUCCESS; +} +#endif +int32_t CRYPT_SM4_SetEncryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (len != SM4_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_KEYLEN_ERROR); + return CRYPT_SM4_KEYLEN_ERROR; + } + Vpsm4SetEncryptKey(key, (SM4_KEY *)ctx->rk); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_SetDecryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + if (len != SM4_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_KEYLEN_ERROR); + return CRYPT_SM4_KEYLEN_ERROR; + } + + Vpsm4SetDecryptKey(key, (SM4_KEY *)ctx->rk); + return CRYPT_SUCCESS; +} + +#ifdef HITLS_CRYPTO_ECB +int32_t CRYPT_SM4_ECB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + Vpsm4EcbEncrypt(in, out, len, ctx->rk); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_ECB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + Vpsm4EcbEncrypt(in, out, len, ctx->rk); + return CRYPT_SUCCESS; +} +#endif +#ifdef HITLS_CRYPTO_CBC +int32_t CRYPT_SM4_CBC_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + Vpsm4CbcEncrypt(in, out, len, ctx->rk, iv, 1); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_CBC_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + Vpsm4CbcEncrypt(in, out, len, ctx->rk, iv, 0); + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_CBC + +#ifdef HITLS_CRYPTO_CFB +int32_t CRYPT_SM4_CFB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, + uint8_t *iv, uint8_t *offset) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int tmp = *offset; + Vpsm4Cfb128Encrypt(in, out, len, ctx->rk, iv, &tmp); + *offset = (uint8_t)tmp; + return CRYPT_SUCCESS; +} +int32_t CRYPT_SM4_CFB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, + uint8_t *iv, uint8_t *offset) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int tmp = *offset; + Vpsm4Cfb128Decrypt(in, out, len, ctx->rk, iv, &tmp); + *offset = (uint8_t)tmp; + return CRYPT_SUCCESS; +} +#endif +#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_GCM) +int32_t CRYPT_SM4_CTR_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + Vpsm4Ctr32EncryptBlocks(in, out, len, ctx->rk, iv); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_CTR_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + Vpsm4Ctr32EncryptBlocks(in, out, len, ctx->rk, iv); + return CRYPT_SUCCESS; +} +#endif + +#endif // HITLS_CRYPTO_SM4 diff --git a/crypto/sm4/src/crypt_sm4_armv8.h b/crypto/sm4/src/crypt_sm4_armv8.h new file mode 100644 index 00000000..b951e22a --- /dev/null +++ b/crypto/sm4/src/crypt_sm4_armv8.h @@ -0,0 +1,61 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_SM4_ARMV8_H +#define CRYPT_SM4_ARMV8_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM4 + +#include +#include + +#define XTS_KEY_LEN 32 +#define SM4_KEY_LEN 16 + +typedef struct SM4_KEY_st { + uint32_t rk[XTS_KEY_LEN]; +} SM4_KEY; + +void Vpsm4SetEncryptKey(const unsigned char *userKey, SM4_KEY *key); + +void Vpsm4SetDecryptKey(const unsigned char *userKey, SM4_KEY *key); + + +#ifdef HITLS_CRYPTO_XTS +void Vpsm4XtsEncrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, + const SM4_KEY *key2, const uint8_t *iv); + +void Vpsm4XtsDecrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1, + const SM4_KEY *key2, const uint8_t *iv); +#endif // HITLS_CRYPTO_XTS + +#ifdef HITLS_CRYPTO_CBC +void Vpsm4CbcEncrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, const int enc); +#endif +#ifdef HITLS_CRYPTO_ECB +void Vpsm4EcbEncrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key); +#endif +#ifdef HITLS_CRYPTO_CFB +void Vpsm4Cfb128Encrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, int *num); +void Vpsm4Cfb128Decrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, int *num); +#endif +#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_GCM) +void Vpsm4Ctr32EncryptBlocks(const uint8_t *in, uint8_t *out, uint64_t blocks, const uint32_t *key, uint8_t *iv); +#endif + +#endif // HITLS_CRYPTO_SM4 + +#endif \ No newline at end of file diff --git a/crypto/sm4/src/crypt_sm4_public.c b/crypto/sm4/src/crypt_sm4_public.c new file mode 100644 index 00000000..c178ba73 --- /dev/null +++ b/crypto/sm4/src/crypt_sm4_public.c @@ -0,0 +1,30 @@ +/* + * 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_SM4 + +#include "securec.h" +#include "bsl_sal.h" +#include "crypt_sm4.h" + +void CRYPT_SM4_XTS_Clean(CRYPT_SM4_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SM4_Ctx) * 2); // cipher context has 2 method contexts in xts mode +} +#endif /* HITLS_CRYPTO_SM4 */ diff --git a/crypto/sm4/src/crypt_sm4_x86_64.c b/crypto/sm4/src/crypt_sm4_x86_64.c new file mode 100644 index 00000000..62a92a97 --- /dev/null +++ b/crypto/sm4/src/crypt_sm4_x86_64.c @@ -0,0 +1,483 @@ +/* + * 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_SM4 + +#include "crypt_sm4_x86_64.h" +#include "crypt_sm4.h" +#include "bsl_err_internal.h" +#include "crypt_utils.h" +#include "crypt_errno.h" +#include "securec.h" + +#define XTS_KEY_LEN 32 +#define SM4_KEY_LEN 16 +#define XTS_POLYNOMIAL 0xe1 +#define LAST_BLOCK_HEAD 240 +#define BYTE_MOST_SIG 128 +#define BYTE 8 + +void SM4_XTS_Calculate_Tweak(unsigned char *t, const unsigned int idx) +{ + uint32_t j; + uint8_t tweak_in, tweak_out; + + tweak_in = 0; + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + tweak_out = (t[idx + j] << (BYTE - 1)) & BYTE_MOST_SIG; + t[j] = (t[idx + j] >> 1) + tweak_in; + tweak_in = tweak_out; + } + if (tweak_out) { + t[0] ^= XTS_POLYNOMIAL; + } +} + +int32_t SM4_XTS_16_En(uint8_t* cipher, const uint8_t* plain, const uint32_t* dataRk, const uint32_t dataLen, uint8_t* t) +{ + uint32_t i; + + SM4_XTS_16_EncryptBlock1st(cipher, plain, dataRk, t); + + for (i = CRYPT_SM4_BLOCKSIZE_16; i < dataLen; i += CRYPT_SM4_BLOCKSIZE_16) { + SM4_XTS_16_EncryptBlock(cipher + i, plain + i, dataRk, t); + } + + return 0; +} + +int32_t SM4_XTS_16_De(uint8_t* plain, const uint8_t* cipher, const uint32_t* dataRk, const uint32_t dataLen, uint8_t* t) +{ + uint32_t i; + + SM4_XTS_16_DecryptBlock1st(plain, cipher, dataRk, t); + + for (i = CRYPT_SM4_BLOCKSIZE_16; i < dataLen; i += CRYPT_SM4_BLOCKSIZE_16) { + SM4_XTS_16_DecryptBlock(plain + i, cipher + i, dataRk, t); + } + + return 0; +} + +static void SM4_XTS_Encrypt_Helper(uint32_t left, const uint32_t dataLen, uint8_t* t, uint8_t *x, + const uint8_t* plain, uint8_t* cipher, const uint32_t* dataRk) +{ + uint32_t i, j; + uint32_t init; + + init = dataLen - left; + if (left >= CRYPT_SM4_BLOCKSIZE) { + left = left % CRYPT_SM4_BLOCKSIZE; + + for (i = init; i < (dataLen - left); i += CRYPT_SM4_BLOCKSIZE) { + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + t[j + CRYPT_SM4_BLOCKSIZE] = t[j]; + } + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + x[j] = plain[i + j] ^ t[j]; + } + + SM4_Encrypt(cipher + i, x, dataRk); + + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + cipher[i + j] = cipher[i + j] ^ t[j]; + } + SM4_XTS_Calculate_Tweak(t, CRYPT_SM4_BLOCKSIZE); + } + } + init = dataLen - left; + + if (left != 0) { + for (i = 0; i < left; i++) { + cipher[init + i] = cipher[init - CRYPT_SM4_BLOCKSIZE + i]; + x[i] = plain[init + i]; + } + for (i = left; i < CRYPT_SM4_BLOCKSIZE; i++) { + x[i] = cipher[init - CRYPT_SM4_BLOCKSIZE + i]; + } + for (i = 0; i < CRYPT_SM4_BLOCKSIZE; i++) { + x[i] = x[i] ^ t[i]; + } + + SM4_Encrypt(cipher + init - CRYPT_SM4_BLOCKSIZE, x, dataRk); + for (i = 0; i < CRYPT_SM4_BLOCKSIZE; i++) { + cipher[init - CRYPT_SM4_BLOCKSIZE + i] = cipher[init - CRYPT_SM4_BLOCKSIZE + i] ^ t[i]; + } + } +} + +int32_t SM4_XTS_En(uint8_t* cipher, const uint8_t* plain, const uint32_t* dataRk, + const uint8_t* tweak, const uint32_t dataLen) +{ + uint32_t left; + + uint8_t x[CRYPT_SM4_BLOCKSIZE_16] = {0}; + uint8_t t[CRYPT_SM4_BLOCKSIZE_16] = {0}; + + if (dataLen < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + left = dataLen % CRYPT_SM4_BLOCKSIZE_16; + + // MODE_XTS_Ctrl has TW = Enc_K2(iv) done + memcpy_s(t, CRYPT_SM4_BLOCKSIZE_16, tweak, CRYPT_SM4_BLOCKSIZE); + + if (dataLen >= CRYPT_SM4_BLOCKSIZE_16) { + SM4_XTS_16_En(cipher, plain, dataRk, dataLen - left, t); + } + + if (left == 0) { + return CRYPT_SUCCESS; + } else { + if (dataLen >= CRYPT_SM4_BLOCKSIZE_16) { + SM4_XTS_Calculate_Tweak(t, LAST_BLOCK_HEAD); + } + SM4_XTS_Encrypt_Helper(left, dataLen, t, x, plain, cipher, dataRk); + } + return CRYPT_SUCCESS; +} + +static void SM4_XTS_Decrypt_Helper(uint32_t left, const uint32_t dataLen, uint8_t* t, uint8_t *x, + uint8_t* plain, const uint8_t* cipher, const uint32_t* dataRk) +{ + uint32_t i, j; + uint32_t init; + + init = dataLen - left; + if (left >= CRYPT_SM4_BLOCKSIZE) { + left = left % CRYPT_SM4_BLOCKSIZE; + + for (i = init; i < (dataLen - left); i += CRYPT_SM4_BLOCKSIZE) { + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + t[j + CRYPT_SM4_BLOCKSIZE] = t[j]; + } + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + x[j] = cipher[i + j] ^ t[j]; + } + + SM4_Decrypt(plain + i, x, dataRk); + + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + plain[i + j] = plain[i + j] ^ t[j]; + } + SM4_XTS_Calculate_Tweak(t, CRYPT_SM4_BLOCKSIZE); + } + } + + init = dataLen - left; + + if (left != 0) { + // recompute + // m-T + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + x[j] = cipher[init - CRYPT_SM4_BLOCKSIZE + j] ^ t[j]; + } + SM4_Decrypt(plain+init - CRYPT_SM4_BLOCKSIZE, x, dataRk); + + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + plain[init - CRYPT_SM4_BLOCKSIZE + j] = plain[init - CRYPT_SM4_BLOCKSIZE + j] ^ t[j]; + } + for (i = 0; i < left; i++) { + plain[init + i] = plain[init - CRYPT_SM4_BLOCKSIZE + i]; + x[i] = cipher[init + i]; + } + for (i = left; i < CRYPT_SM4_BLOCKSIZE; i++) { + x[i] = plain[init - CRYPT_SM4_BLOCKSIZE + i]; + } + // (m-1)-T + for (i = 0; i < CRYPT_SM4_BLOCKSIZE; i++) { + x[i] = x[i] ^ t[CRYPT_SM4_BLOCKSIZE + i]; + } + + SM4_Decrypt(plain + init - CRYPT_SM4_BLOCKSIZE, x, dataRk); + + for (i = 0; i < CRYPT_SM4_BLOCKSIZE; i++) { + plain[init - CRYPT_SM4_BLOCKSIZE + i] = plain[init - CRYPT_SM4_BLOCKSIZE + i] + ^ t[CRYPT_SM4_BLOCKSIZE + i]; + } + } +} + +int32_t SM4_XTS_De(uint8_t* plain, const uint8_t* cipher, const uint32_t* dataRk, + const uint8_t* tweak, const uint32_t dataLen) +{ + uint32_t j; + uint32_t left; + + uint8_t t[CRYPT_SM4_BLOCKSIZE_16] = {0}; + uint8_t x[CRYPT_SM4_BLOCKSIZE_16] = {0}; + + if (dataLen < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); // need push error code for error point + return CRYPT_SM4_DATALEN_ERROR; + } + left = dataLen % CRYPT_SM4_BLOCKSIZE_16; + + // MODE_XTS_Ctrl has TW = Enc_K2(iv) done + (void)memcpy_s(t, CRYPT_SM4_BLOCKSIZE_16, tweak, CRYPT_SM4_BLOCKSIZE); + + if (dataLen >= CRYPT_SM4_BLOCKSIZE_16) { + SM4_XTS_16_De(plain, cipher, dataRk, dataLen - left, t); + } + + if (left != 0) { + if (dataLen >= CRYPT_SM4_BLOCKSIZE_16) { + SM4_XTS_Calculate_Tweak(t, LAST_BLOCK_HEAD); + for (j = 0; j < CRYPT_SM4_BLOCKSIZE; j++) { + t[j + CRYPT_SM4_BLOCKSIZE] = t[j + LAST_BLOCK_HEAD]; + } + } + SM4_XTS_Decrypt_Helper(left, dataLen, t, x, plain, cipher, dataRk); + } + return CRYPT_SUCCESS; +} + +// key[0..16]: data key +// key[16..32]: tweak key +int32_t CRYPT_SM4_XTS_SetEncryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + CRYPT_SM4_Ctx *tmk = NULL; + if (ctx == NULL || key == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len != XTS_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN); + return CRYPT_SM4_ERR_KEY_LEN; + } + + if (memcmp(key, key + CRYPT_SM4_BLOCKSIZE, CRYPT_SM4_BLOCKSIZE) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_UNSAFE_KEY); + return CRYPT_SM4_UNSAFE_KEY; + } + + tmk = (CRYPT_SM4_Ctx *)&ctx[1]; + SM4_SetKey(ctx->rk, key); + SM4_SetKey(tmk->rk, key + CRYPT_SM4_BLOCKSIZE); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_XTS_SetDecryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len) +{ + CRYPT_SM4_Ctx *tmk = NULL; + if (ctx == NULL || key == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (len != XTS_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN); + return CRYPT_SM4_ERR_KEY_LEN; + } + + if (memcmp(key, key + CRYPT_SM4_BLOCKSIZE, CRYPT_SM4_BLOCKSIZE) == 0) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_UNSAFE_KEY); + return CRYPT_SM4_UNSAFE_KEY; + } + + tmk = (CRYPT_SM4_Ctx *)&ctx[1]; + SM4_SetKey(ctx->rk, key); + SM4_SetKey(tmk->rk, key + CRYPT_SM4_BLOCKSIZE); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_XTS_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (ctx == NULL || iv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return SM4_XTS_En(out, in, ctx->rk, iv, len); +} + +int32_t CRYPT_SM4_XTS_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (ctx == NULL || iv == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + return SM4_XTS_De(out, in, ctx->rk, iv, len); +} + +int32_t CRYPT_SM4_SetEncryptKey(CRYPT_SM4_Ctx *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 != SM4_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN); + return CRYPT_SM4_ERR_KEY_LEN; + } + + SM4_SetKey(ctx->rk, key); + + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_SetDecryptKey(CRYPT_SM4_Ctx *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 != SM4_KEY_LEN) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN); + return CRYPT_SM4_ERR_KEY_LEN; + } + + SM4_SetDecKey(ctx->rk, key); + + return CRYPT_SUCCESS; +} + +#ifdef HITLS_CRYPTO_ECB +int32_t SM4_ECB_Crypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + SM4_ECB_Encrypt(in, out, len, ctx->rk); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_ECB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return SM4_ECB_Crypt(ctx, in, out, len); +} + +int32_t CRYPT_SM4_ECB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len) +{ + return SM4_ECB_Crypt(ctx, in, out, len); +} +#endif + +#ifdef HITLS_CRYPTO_CBC +int32_t CRYPT_SM4_CBC_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + SM4_CBC_Encrypt(in, out, len, ctx->rk, iv, 1); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_CBC_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + if (len < CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_DATALEN_ERROR); + return CRYPT_SM4_DATALEN_ERROR; + } + SM4_CBC_Encrypt(in, out, len, ctx->rk, iv, 0); + return CRYPT_SUCCESS; +} +#endif + +#ifdef HITLS_CRYPTO_OFB +int32_t SM4_OFB_Crypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int tmp = *offset; + SM4_OFB_Encrypt(in, out, len, ctx->rk, iv, &tmp); + *offset = (uint8_t)tmp; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_OFB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, + uint8_t *iv, uint8_t *offset) +{ + return SM4_OFB_Crypt(ctx, in, out, len, iv, offset); +} + +int32_t CRYPT_SM4_OFB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, + uint8_t *iv, uint8_t *offset) +{ + return SM4_OFB_Crypt(ctx, in, out, len, iv, offset); +} +#endif + +#ifdef HITLS_CRYPTO_CFB +int32_t CRYPT_SM4_CFB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int tmp = *offset; + SM4_CFB128_Encrypt(in, out, len, ctx->rk, iv, &tmp); + *offset = (uint8_t)tmp; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_CFB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv, uint8_t *offset) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int tmp = *offset; + SM4_CFB128_Decrypt(in, out, len, ctx->rk, iv, &tmp); + *offset = (uint8_t)tmp; + return CRYPT_SUCCESS; +} +#endif + +#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_GCM) +int32_t CRYPT_SM4_CTR_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + SM4_CTR_EncryptBlocks(in, out, len, ctx->rk, iv); + return CRYPT_SUCCESS; +} + +int32_t CRYPT_SM4_CTR_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + SM4_CTR_EncryptBlocks(in, out, len, ctx->rk, iv); + return CRYPT_SUCCESS; +} +#endif + +#endif /* HITLS_CRYPTO_SM4 */ diff --git a/crypto/sm4/src/crypt_sm4_x86_64.h b/crypto/sm4/src/crypt_sm4_x86_64.h new file mode 100644 index 00000000..4bd24b0f --- /dev/null +++ b/crypto/sm4/src/crypt_sm4_x86_64.h @@ -0,0 +1,53 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_SM4_X86_64_H +#define CRYPT_SM4_X86_64_H + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_SM4 + +#include + +void SM4_SetKey(uint32_t *rk, const uint8_t *key); + +void SM4_SetDecKey(uint32_t *rk, const uint8_t *key); + +void SM4_Encrypt(uint8_t *cipher, const uint8_t *plain, const uint32_t *rk); + +void SM4_Decrypt(uint8_t *plain, const uint8_t *cipher, const uint32_t *rk); + +// SM4 XTS +void SM4_XTS_16_EncryptBlock1st(uint8_t* cipher, const uint8_t* plain, const uint32_t* ecb_rk, + uint8_t* t); + +void SM4_XTS_16_EncryptBlock(uint8_t* cipher, const uint8_t* plain, const uint32_t* ecb_rk, + uint8_t* t); + +void SM4_XTS_16_DecryptBlock1st(uint8_t* plain, const uint8_t* cipher, const uint32_t* ecb_rk, + uint8_t* t); + +void SM4_XTS_16_DecryptBlock(uint8_t* plain, const uint8_t* cipher, const uint32_t* ecb_rk, + uint8_t* t); + +void SM4_ECB_Encrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key); +void SM4_CBC_Encrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, const int enc); +void SM4_OFB_Encrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, int *num); +void SM4_CFB128_Encrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, int *num); +void SM4_CFB128_Decrypt(const uint8_t *in, uint8_t *out, uint64_t len, const uint32_t *key, uint8_t *iv, int *num); +void SM4_CTR_EncryptBlocks(const uint8_t *in, uint8_t *out, uint64_t blocks, const uint32_t *key, const uint8_t *iv); + +#endif /* HITLS_CRYPTO_SM4 */ +#endif \ No newline at end of file diff --git a/crypto/sm4/src/sm4_key.c b/crypto/sm4/src/sm4_key.c new file mode 100644 index 00000000..a6141e27 --- /dev/null +++ b/crypto/sm4/src/sm4_key.c @@ -0,0 +1,227 @@ +/* + * 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_SM4 + +#include +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_err_internal.h" +#include "crypt_sm4.h" + +/* System parameter FK (originating GB/T 32907-2016 7.3 b or GM/T 0002-2012 7.3 2) */ +static const uint32_t FK[] = {0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc}; + +/* Fixed parameter CK (originating GB/T 32907-2016 7.3 c or GM/T 0002-2012 7.3 3) */ +static const uint32_t CK[] = { + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279, +}; + +/** + * <<<: Cyclic shift to the left + * ⊕: XOR + * S-box: (originating GB/T 32907-2016 6.2 a or GM/T 0002-2012 6.2 1) + * LE(B) = B⊕(B <<< 13)⊕(B <<< 23) + * KBOX_0[i] = LE(SBOX[i]) + */ +static const uint32_t KBOX_0[] = { + 0x6b1ac0d6, 0x48120090, 0x749d20e9, 0x7f1fc0fe, 0x661980cc, 0x709c20e1, 0x1e87a03d, 0x5b96e0b7, + 0x0b02c016, 0x5b16c0b6, 0x0a028014, 0x611840c2, 0x14050028, 0x7d9f60fb, 0x1605802c, 0x0280a005, + 0x1585602b, 0x338ce067, 0x4d13409a, 0x3b0ec076, 0x1505402a, 0x5f17c0be, 0x02008004, 0x619860c3, + 0x551540aa, 0x22088044, 0x09826013, 0x1304c026, 0x24892049, 0x4310c086, 0x0300c006, 0x4c932099, + 0x4e13809c, 0x21084042, 0x280a0050, 0x7a1e80f4, 0x48922091, 0x779de0ef, 0x4c130098, 0x3d0f407a, + 0x19866033, 0x2a0a8054, 0x0581600b, 0x21886043, 0x769da0ed, 0x6799e0cf, 0x561580ac, 0x310c4062, + 0x721c80e4, 0x599660b3, 0x0e03801c, 0x549520a9, 0x649920c9, 0x04010008, 0x741d00e8, 0x4a92a095, + 0x40100080, 0x6f9be0df, 0x4a128094, 0x7d1f40fa, 0x3a8ea075, 0x4791e08f, 0x1f87e03f, 0x5314c0a6, + 0x2388e047, 0x0380e007, 0x5394e0a7, 0x7e1f80fc, 0x799e60f3, 0x398e6073, 0x0b82e017, 0x5d1740ba, + 0x41906083, 0x2c8b2059, 0x1e07803c, 0x0c832019, 0x731cc0e6, 0x4290a085, 0x2789e04f, 0x541500a8, + 0x340d0068, 0x358d606b, 0x40902081, 0x591640b2, 0x388e2071, 0x320c8064, 0x6d1b40da, 0x4591608b, + 0x7c1f00f8, 0x759d60eb, 0x0781e00f, 0x2589604b, 0x380e0070, 0x2b0ac056, 0x4e93a09d, 0x1a86a035, + 0x0f03c01e, 0x12048024, 0x0701c00e, 0x2f0bc05e, 0x318c6063, 0x2c0b0058, 0x689a20d1, 0x511440a2, + 0x1284a025, 0x11044022, 0x3e0f807c, 0x1d87603b, 0x00802001, 0x10842021, 0x3c0f0078, 0x4390e087, + 0x6a1a80d4, 0x00000000, 0x2308c046, 0x2b8ae057, 0x4f93e09f, 0x699a60d3, 0x1384e027, 0x290a4052, + 0x2609804c, 0x1b06c036, 0x01004002, 0x739ce0e7, 0x501400a0, 0x621880c4, 0x641900c8, 0x4f13c09e, + 0x751d40ea, 0x5f97e0bf, 0x4511408a, 0x691a40d2, 0x20080040, 0x6398e0c7, 0x1c070038, 0x5a96a0b5, + 0x519460a3, 0x7b9ee0f7, 0x791e40f2, 0x6719c0ce, 0x7c9f20f9, 0x308c2061, 0x0a82a015, 0x509420a1, + 0x701c00e0, 0x5715c0ae, 0x2e8ba05d, 0x521480a4, 0x4d93609b, 0x1a068034, 0x0d03401a, 0x2a8aa055, + 0x5695a0ad, 0x49926093, 0x19064032, 0x18060030, 0x7a9ea0f5, 0x4611808c, 0x589620b1, 0x719c60e3, + 0x0e83a01d, 0x7b1ec0f6, 0x711c40e2, 0x1705c02e, 0x41104082, 0x330cc066, 0x651940ca, 0x300c0060, + 0x601800c0, 0x14852029, 0x11846023, 0x559560ab, 0x0681a00d, 0x298a6053, 0x2709c04e, 0x378de06f, + 0x6a9aa0d5, 0x6d9b60db, 0x1b86e037, 0x2288a045, 0x6f1bc0de, 0x7e9fa0fd, 0x4711c08e, 0x1785e02f, + 0x01806003, 0x7f9fe0ff, 0x350d406a, 0x390e4072, 0x368da06d, 0x360d806c, 0x2d8b605b, 0x288a2051, + 0x4691a08d, 0x0d83601b, 0x5795e0af, 0x49124092, 0x5d9760bb, 0x6e9ba0dd, 0x5e1780bc, 0x3f8fe07f, + 0x08822011, 0x6c9b20d9, 0x2e0b805c, 0x20882041, 0x0f83e01f, 0x08020010, 0x2d0b405a, 0x6c1b00d8, + 0x0501400a, 0x609820c1, 0x18862031, 0x44110088, 0x5294a0a5, 0x6699a0cd, 0x3d8f607b, 0x5e97a0bd, + 0x1685a02d, 0x3a0e8074, 0x681a00d0, 0x09024012, 0x5c1700b8, 0x729ca0e5, 0x5a1680b4, 0x581600b0, + 0x44912089, 0x348d2069, 0x4b92e097, 0x2509404a, 0x0601800c, 0x4b12c096, 0x3b8ee077, 0x3f0fc07e, + 0x328ca065, 0x5c9720b9, 0x789e20f1, 0x04812009, 0x6298a0c5, 0x370dc06e, 0x6318c0c6, 0x42108084, + 0x0c030018, 0x781e00f0, 0x3e8fa07d, 0x761d80ec, 0x1d07403a, 0x6e1b80dc, 0x2689a04d, 0x10040020, + 0x3c8f2079, 0x771dc0ee, 0x2f8be05f, 0x1f07c03e, 0x6b9ae0d7, 0x659960cb, 0x1c872039, 0x24090048, +}; + +/* KBOX_1[i] = KBOX_0[i] <<< 8 */ +static const uint32_t KBOX_1[] = { + 0x1ac0d66b, 0x12009048, 0x9d20e974, 0x1fc0fe7f, 0x1980cc66, 0x9c20e170, 0x87a03d1e, 0x96e0b75b, + 0x02c0160b, 0x16c0b65b, 0x0280140a, 0x1840c261, 0x05002814, 0x9f60fb7d, 0x05802c16, 0x80a00502, + 0x85602b15, 0x8ce06733, 0x13409a4d, 0x0ec0763b, 0x05402a15, 0x17c0be5f, 0x00800402, 0x9860c361, + 0x1540aa55, 0x08804422, 0x82601309, 0x04c02613, 0x89204924, 0x10c08643, 0x00c00603, 0x9320994c, + 0x13809c4e, 0x08404221, 0x0a005028, 0x1e80f47a, 0x92209148, 0x9de0ef77, 0x1300984c, 0x0f407a3d, + 0x86603319, 0x0a80542a, 0x81600b05, 0x88604321, 0x9da0ed76, 0x99e0cf67, 0x1580ac56, 0x0c406231, + 0x1c80e472, 0x9660b359, 0x03801c0e, 0x9520a954, 0x9920c964, 0x01000804, 0x1d00e874, 0x92a0954a, + 0x10008040, 0x9be0df6f, 0x1280944a, 0x1f40fa7d, 0x8ea0753a, 0x91e08f47, 0x87e03f1f, 0x14c0a653, + 0x88e04723, 0x80e00703, 0x94e0a753, 0x1f80fc7e, 0x9e60f379, 0x8e607339, 0x82e0170b, 0x1740ba5d, + 0x90608341, 0x8b20592c, 0x07803c1e, 0x8320190c, 0x1cc0e673, 0x90a08542, 0x89e04f27, 0x1500a854, + 0x0d006834, 0x8d606b35, 0x90208140, 0x1640b259, 0x8e207138, 0x0c806432, 0x1b40da6d, 0x91608b45, + 0x1f00f87c, 0x9d60eb75, 0x81e00f07, 0x89604b25, 0x0e007038, 0x0ac0562b, 0x93a09d4e, 0x86a0351a, + 0x03c01e0f, 0x04802412, 0x01c00e07, 0x0bc05e2f, 0x8c606331, 0x0b00582c, 0x9a20d168, 0x1440a251, + 0x84a02512, 0x04402211, 0x0f807c3e, 0x87603b1d, 0x80200100, 0x84202110, 0x0f00783c, 0x90e08743, + 0x1a80d46a, 0x00000000, 0x08c04623, 0x8ae0572b, 0x93e09f4f, 0x9a60d369, 0x84e02713, 0x0a405229, + 0x09804c26, 0x06c0361b, 0x00400201, 0x9ce0e773, 0x1400a050, 0x1880c462, 0x1900c864, 0x13c09e4f, + 0x1d40ea75, 0x97e0bf5f, 0x11408a45, 0x1a40d269, 0x08004020, 0x98e0c763, 0x0700381c, 0x96a0b55a, + 0x9460a351, 0x9ee0f77b, 0x1e40f279, 0x19c0ce67, 0x9f20f97c, 0x8c206130, 0x82a0150a, 0x9420a150, + 0x1c00e070, 0x15c0ae57, 0x8ba05d2e, 0x1480a452, 0x93609b4d, 0x0680341a, 0x03401a0d, 0x8aa0552a, + 0x95a0ad56, 0x92609349, 0x06403219, 0x06003018, 0x9ea0f57a, 0x11808c46, 0x9620b158, 0x9c60e371, + 0x83a01d0e, 0x1ec0f67b, 0x1c40e271, 0x05c02e17, 0x10408241, 0x0cc06633, 0x1940ca65, 0x0c006030, + 0x1800c060, 0x85202914, 0x84602311, 0x9560ab55, 0x81a00d06, 0x8a605329, 0x09c04e27, 0x8de06f37, + 0x9aa0d56a, 0x9b60db6d, 0x86e0371b, 0x88a04522, 0x1bc0de6f, 0x9fa0fd7e, 0x11c08e47, 0x85e02f17, + 0x80600301, 0x9fe0ff7f, 0x0d406a35, 0x0e407239, 0x8da06d36, 0x0d806c36, 0x8b605b2d, 0x8a205128, + 0x91a08d46, 0x83601b0d, 0x95e0af57, 0x12409249, 0x9760bb5d, 0x9ba0dd6e, 0x1780bc5e, 0x8fe07f3f, + 0x82201108, 0x9b20d96c, 0x0b805c2e, 0x88204120, 0x83e01f0f, 0x02001008, 0x0b405a2d, 0x1b00d86c, + 0x01400a05, 0x9820c160, 0x86203118, 0x11008844, 0x94a0a552, 0x99a0cd66, 0x8f607b3d, 0x97a0bd5e, + 0x85a02d16, 0x0e80743a, 0x1a00d068, 0x02401209, 0x1700b85c, 0x9ca0e572, 0x1680b45a, 0x1600b058, + 0x91208944, 0x8d206934, 0x92e0974b, 0x09404a25, 0x01800c06, 0x12c0964b, 0x8ee0773b, 0x0fc07e3f, + 0x8ca06532, 0x9720b95c, 0x9e20f178, 0x81200904, 0x98a0c562, 0x0dc06e37, 0x18c0c663, 0x10808442, + 0x0300180c, 0x1e00f078, 0x8fa07d3e, 0x1d80ec76, 0x07403a1d, 0x1b80dc6e, 0x89a04d26, 0x04002010, + 0x8f20793c, 0x1dc0ee77, 0x8be05f2f, 0x07c03e1f, 0x9ae0d76b, 0x9960cb65, 0x8720391c, 0x09004824, +}; + +/* KBOX_2[i] = KBOX_0[i] <<< 16 */ +static const uint32_t KBOX_2[] = { + 0xc0d66b1a, 0x00904812, 0x20e9749d, 0xc0fe7f1f, 0x80cc6619, 0x20e1709c, 0xa03d1e87, 0xe0b75b96, + 0xc0160b02, 0xc0b65b16, 0x80140a02, 0x40c26118, 0x00281405, 0x60fb7d9f, 0x802c1605, 0xa0050280, + 0x602b1585, 0xe067338c, 0x409a4d13, 0xc0763b0e, 0x402a1505, 0xc0be5f17, 0x80040200, 0x60c36198, + 0x40aa5515, 0x80442208, 0x60130982, 0xc0261304, 0x20492489, 0xc0864310, 0xc0060300, 0x20994c93, + 0x809c4e13, 0x40422108, 0x0050280a, 0x80f47a1e, 0x20914892, 0xe0ef779d, 0x00984c13, 0x407a3d0f, + 0x60331986, 0x80542a0a, 0x600b0581, 0x60432188, 0xa0ed769d, 0xe0cf6799, 0x80ac5615, 0x4062310c, + 0x80e4721c, 0x60b35996, 0x801c0e03, 0x20a95495, 0x20c96499, 0x00080401, 0x00e8741d, 0xa0954a92, + 0x00804010, 0xe0df6f9b, 0x80944a12, 0x40fa7d1f, 0xa0753a8e, 0xe08f4791, 0xe03f1f87, 0xc0a65314, + 0xe0472388, 0xe0070380, 0xe0a75394, 0x80fc7e1f, 0x60f3799e, 0x6073398e, 0xe0170b82, 0x40ba5d17, + 0x60834190, 0x20592c8b, 0x803c1e07, 0x20190c83, 0xc0e6731c, 0xa0854290, 0xe04f2789, 0x00a85415, + 0x0068340d, 0x606b358d, 0x20814090, 0x40b25916, 0x2071388e, 0x8064320c, 0x40da6d1b, 0x608b4591, + 0x00f87c1f, 0x60eb759d, 0xe00f0781, 0x604b2589, 0x0070380e, 0xc0562b0a, 0xa09d4e93, 0xa0351a86, + 0xc01e0f03, 0x80241204, 0xc00e0701, 0xc05e2f0b, 0x6063318c, 0x00582c0b, 0x20d1689a, 0x40a25114, + 0xa0251284, 0x40221104, 0x807c3e0f, 0x603b1d87, 0x20010080, 0x20211084, 0x00783c0f, 0xe0874390, + 0x80d46a1a, 0x00000000, 0xc0462308, 0xe0572b8a, 0xe09f4f93, 0x60d3699a, 0xe0271384, 0x4052290a, + 0x804c2609, 0xc0361b06, 0x40020100, 0xe0e7739c, 0x00a05014, 0x80c46218, 0x00c86419, 0xc09e4f13, + 0x40ea751d, 0xe0bf5f97, 0x408a4511, 0x40d2691a, 0x00402008, 0xe0c76398, 0x00381c07, 0xa0b55a96, + 0x60a35194, 0xe0f77b9e, 0x40f2791e, 0xc0ce6719, 0x20f97c9f, 0x2061308c, 0xa0150a82, 0x20a15094, + 0x00e0701c, 0xc0ae5715, 0xa05d2e8b, 0x80a45214, 0x609b4d93, 0x80341a06, 0x401a0d03, 0xa0552a8a, + 0xa0ad5695, 0x60934992, 0x40321906, 0x00301806, 0xa0f57a9e, 0x808c4611, 0x20b15896, 0x60e3719c, + 0xa01d0e83, 0xc0f67b1e, 0x40e2711c, 0xc02e1705, 0x40824110, 0xc066330c, 0x40ca6519, 0x0060300c, + 0x00c06018, 0x20291485, 0x60231184, 0x60ab5595, 0xa00d0681, 0x6053298a, 0xc04e2709, 0xe06f378d, + 0xa0d56a9a, 0x60db6d9b, 0xe0371b86, 0xa0452288, 0xc0de6f1b, 0xa0fd7e9f, 0xc08e4711, 0xe02f1785, + 0x60030180, 0xe0ff7f9f, 0x406a350d, 0x4072390e, 0xa06d368d, 0x806c360d, 0x605b2d8b, 0x2051288a, + 0xa08d4691, 0x601b0d83, 0xe0af5795, 0x40924912, 0x60bb5d97, 0xa0dd6e9b, 0x80bc5e17, 0xe07f3f8f, + 0x20110882, 0x20d96c9b, 0x805c2e0b, 0x20412088, 0xe01f0f83, 0x00100802, 0x405a2d0b, 0x00d86c1b, + 0x400a0501, 0x20c16098, 0x20311886, 0x00884411, 0xa0a55294, 0xa0cd6699, 0x607b3d8f, 0xa0bd5e97, + 0xa02d1685, 0x80743a0e, 0x00d0681a, 0x40120902, 0x00b85c17, 0xa0e5729c, 0x80b45a16, 0x00b05816, + 0x20894491, 0x2069348d, 0xe0974b92, 0x404a2509, 0x800c0601, 0xc0964b12, 0xe0773b8e, 0xc07e3f0f, + 0xa065328c, 0x20b95c97, 0x20f1789e, 0x20090481, 0xa0c56298, 0xc06e370d, 0xc0c66318, 0x80844210, + 0x00180c03, 0x00f0781e, 0xa07d3e8f, 0x80ec761d, 0x403a1d07, 0x80dc6e1b, 0xa04d2689, 0x00201004, + 0x20793c8f, 0xc0ee771d, 0xe05f2f8b, 0xc03e1f07, 0xe0d76b9a, 0x60cb6599, 0x20391c87, 0x00482409, +}; + +/* KBOX_3[i] = KBOX_0[i] <<< 24 */ +static const uint32_t KBOX_3[] = { + 0xd66b1ac0, 0x90481200, 0xe9749d20, 0xfe7f1fc0, 0xcc661980, 0xe1709c20, 0x3d1e87a0, 0xb75b96e0, + 0x160b02c0, 0xb65b16c0, 0x140a0280, 0xc2611840, 0x28140500, 0xfb7d9f60, 0x2c160580, 0x050280a0, + 0x2b158560, 0x67338ce0, 0x9a4d1340, 0x763b0ec0, 0x2a150540, 0xbe5f17c0, 0x04020080, 0xc3619860, + 0xaa551540, 0x44220880, 0x13098260, 0x261304c0, 0x49248920, 0x864310c0, 0x060300c0, 0x994c9320, + 0x9c4e1380, 0x42210840, 0x50280a00, 0xf47a1e80, 0x91489220, 0xef779de0, 0x984c1300, 0x7a3d0f40, + 0x33198660, 0x542a0a80, 0x0b058160, 0x43218860, 0xed769da0, 0xcf6799e0, 0xac561580, 0x62310c40, + 0xe4721c80, 0xb3599660, 0x1c0e0380, 0xa9549520, 0xc9649920, 0x08040100, 0xe8741d00, 0x954a92a0, + 0x80401000, 0xdf6f9be0, 0x944a1280, 0xfa7d1f40, 0x753a8ea0, 0x8f4791e0, 0x3f1f87e0, 0xa65314c0, + 0x472388e0, 0x070380e0, 0xa75394e0, 0xfc7e1f80, 0xf3799e60, 0x73398e60, 0x170b82e0, 0xba5d1740, + 0x83419060, 0x592c8b20, 0x3c1e0780, 0x190c8320, 0xe6731cc0, 0x854290a0, 0x4f2789e0, 0xa8541500, + 0x68340d00, 0x6b358d60, 0x81409020, 0xb2591640, 0x71388e20, 0x64320c80, 0xda6d1b40, 0x8b459160, + 0xf87c1f00, 0xeb759d60, 0x0f0781e0, 0x4b258960, 0x70380e00, 0x562b0ac0, 0x9d4e93a0, 0x351a86a0, + 0x1e0f03c0, 0x24120480, 0x0e0701c0, 0x5e2f0bc0, 0x63318c60, 0x582c0b00, 0xd1689a20, 0xa2511440, + 0x251284a0, 0x22110440, 0x7c3e0f80, 0x3b1d8760, 0x01008020, 0x21108420, 0x783c0f00, 0x874390e0, + 0xd46a1a80, 0x00000000, 0x462308c0, 0x572b8ae0, 0x9f4f93e0, 0xd3699a60, 0x271384e0, 0x52290a40, + 0x4c260980, 0x361b06c0, 0x02010040, 0xe7739ce0, 0xa0501400, 0xc4621880, 0xc8641900, 0x9e4f13c0, + 0xea751d40, 0xbf5f97e0, 0x8a451140, 0xd2691a40, 0x40200800, 0xc76398e0, 0x381c0700, 0xb55a96a0, + 0xa3519460, 0xf77b9ee0, 0xf2791e40, 0xce6719c0, 0xf97c9f20, 0x61308c20, 0x150a82a0, 0xa1509420, + 0xe0701c00, 0xae5715c0, 0x5d2e8ba0, 0xa4521480, 0x9b4d9360, 0x341a0680, 0x1a0d0340, 0x552a8aa0, + 0xad5695a0, 0x93499260, 0x32190640, 0x30180600, 0xf57a9ea0, 0x8c461180, 0xb1589620, 0xe3719c60, + 0x1d0e83a0, 0xf67b1ec0, 0xe2711c40, 0x2e1705c0, 0x82411040, 0x66330cc0, 0xca651940, 0x60300c00, + 0xc0601800, 0x29148520, 0x23118460, 0xab559560, 0x0d0681a0, 0x53298a60, 0x4e2709c0, 0x6f378de0, + 0xd56a9aa0, 0xdb6d9b60, 0x371b86e0, 0x452288a0, 0xde6f1bc0, 0xfd7e9fa0, 0x8e4711c0, 0x2f1785e0, + 0x03018060, 0xff7f9fe0, 0x6a350d40, 0x72390e40, 0x6d368da0, 0x6c360d80, 0x5b2d8b60, 0x51288a20, + 0x8d4691a0, 0x1b0d8360, 0xaf5795e0, 0x92491240, 0xbb5d9760, 0xdd6e9ba0, 0xbc5e1780, 0x7f3f8fe0, + 0x11088220, 0xd96c9b20, 0x5c2e0b80, 0x41208820, 0x1f0f83e0, 0x10080200, 0x5a2d0b40, 0xd86c1b00, + 0x0a050140, 0xc1609820, 0x31188620, 0x88441100, 0xa55294a0, 0xcd6699a0, 0x7b3d8f60, 0xbd5e97a0, + 0x2d1685a0, 0x743a0e80, 0xd0681a00, 0x12090240, 0xb85c1700, 0xe5729ca0, 0xb45a1680, 0xb0581600, + 0x89449120, 0x69348d20, 0x974b92e0, 0x4a250940, 0x0c060180, 0x964b12c0, 0x773b8ee0, 0x7e3f0fc0, + 0x65328ca0, 0xb95c9720, 0xf1789e20, 0x09048120, 0xc56298a0, 0x6e370dc0, 0xc66318c0, 0x84421080, + 0x180c0300, 0xf0781e00, 0x7d3e8fa0, 0xec761d80, 0x3a1d0740, 0xdc6e1b80, 0x4d2689a0, 0x20100400, + 0x793c8f20, 0xee771dc0, 0x5f2f8be0, 0x3e1f07c0, 0xd76b9ae0, 0xcb659960, 0x391c8720, 0x48240900, +}; + +#define KROUND(t, k0, k1, k2, k3, ck, sbox, rki) \ + do { \ + ROUND(t, k0, k1, k2, k3, ck, sbox); \ + rki = k0; \ + } while (0) + +/* Generate a round key */ +#define KROUND_FUNCTION(t, k0, k1, k2, k3, sbox, rk) \ + for (int i = 0; i < 32; i += 4) { \ + KROUND((t), (k0), (k1), (k2), (k3), CK[(i) + 0], sbox, (rk)[(i) + 0]); \ + KROUND((t), (k1), (k2), (k3), (k0), CK[(i) + 1], sbox, (rk)[(i) + 1]); \ + KROUND((t), (k2), (k3), (k0), (k1), CK[(i) + 2], sbox, (rk)[(i) + 2]); \ + KROUND((t), (k3), (k0), (k1), (k2), CK[(i) + 3], sbox, (rk)[(i) + 3]); \ + } + +int32_t CRYPT_SM4_SetKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t keyLen) +{ + if (ctx == NULL || key == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + + if (keyLen != CRYPT_SM4_BLOCKSIZE) { + BSL_ERR_PUSH_ERROR(CRYPT_SM4_KEYLEN_ERROR); + return CRYPT_SM4_KEYLEN_ERROR; + } + + volatile uint32_t k0, k1, k2, k3; + volatile uint32_t t; + k0 = GET_UINT32_BE(key, 0) ^ FK[0]; + k1 = GET_UINT32_BE(key, 4) ^ FK[1]; + k2 = GET_UINT32_BE(key, 8) ^ FK[2]; + k3 = GET_UINT32_BE(key, 12) ^ FK[3]; + KROUND_FUNCTION(t, k0, k1, k2, k3, KBOX, ctx->rk); + k0 = 0; + k1 = 0; + k2 = 0; + k3 = 0; + t = 0; + return CRYPT_SUCCESS; +} +#endif // HITLS_CRYPTO_SM4 diff --git a/crypto/util/crypt_util_algId.c b/crypto/util/crypt_util_algId.c new file mode 100644 index 00000000..78256eeb --- /dev/null +++ b/crypto/util/crypt_util_algId.c @@ -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. + */ + +#include "hitls_build.h" +#ifdef HITLS_CRYPTO_RSA + +#include "crypt_local_types.h" +#include "crypt_utils.h" +typedef struct { + CRYPT_MD_AlgId id; + uint32_t mdSize; +} CRYPT_MdInfo; + +uint32_t CRYPT_MD_GetSizeById(CRYPT_MD_AlgId id) +{ + // need synchronize with enum CRYPT_MD_AlgId + static CRYPT_MdInfo mdInfo[] = { + {.id = CRYPT_MD_MD4, .mdSize = 16}, + {.id = CRYPT_MD_MD5, .mdSize = 16}, + {.id = CRYPT_MD_SHA1, .mdSize = 20}, + {.id = CRYPT_MD_SHA224, .mdSize = 28}, + {.id = CRYPT_MD_SHA256, .mdSize = 32}, + {.id = CRYPT_MD_SHA384, .mdSize = 48}, + {.id = CRYPT_MD_SHA512, .mdSize = 64}, + {.id = CRYPT_MD_SHA3_224, .mdSize = 28}, + {.id = CRYPT_MD_SHA3_256, .mdSize = 32}, + {.id = CRYPT_MD_SHA3_384, .mdSize = 48}, + {.id = CRYPT_MD_SHA3_512, .mdSize = 64}, + {.id = CRYPT_MD_SHAKE128, .mdSize = 0}, + {.id = CRYPT_MD_SHAKE256, .mdSize = 0}, + {.id = CRYPT_MD_SM3, .mdSize = 32}, + {.id = CRYPT_MD_MAX, .mdSize = 0}, + }; + uint32_t i = 0; + + while (mdInfo[i].id != CRYPT_MD_MAX) { + if (mdInfo[i].id == id) { + return mdInfo[i].mdSize; + } + i++; + } + + return 0; +} +#endif diff --git a/crypto/util/crypt_util_rand.c b/crypto/util/crypt_util_rand.c new file mode 100644 index 00000000..966ab096 --- /dev/null +++ b/crypto/util/crypt_util_rand.c @@ -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. + */ + +#include "hitls_build.h" +#if defined(HITLS_CRYPTO_DRBG) || defined(HITLS_CRYPTO_CURVE25519) || \ + defined(HITLS_CRYPTO_RSA) || defined(HITLS_CRYPTO_BN) + +#include +#include "crypt_errno.h" +#include "bsl_err_internal.h" +#include "crypt_util_rand.h" + +static CRYPT_RandFunc g_randFunc = NULL; + +void CRYPT_RandRegist(CRYPT_RandFunc func) +{ + g_randFunc = func; +} + +int32_t CRYPT_Rand(uint8_t *rand, uint32_t randLen) +{ + if (g_randFunc == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NO_REGIST_RAND); + return CRYPT_NO_REGIST_RAND; + } + int32_t ret = g_randFunc(rand, randLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} +#endif diff --git a/docs/en/.gitignore b/docs/en/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/docs/en/1_Release Notes.md b/docs/en/1_Release Notes.md new file mode 100644 index 00000000..4acc6f11 --- /dev/null +++ b/docs/en/1_Release Notes.md @@ -0,0 +1,12 @@ +# Version Mapping + +Version: openHiTLS 0.1.0 alpha1 + +# New Features + +**openHiTLS supports the following features:** + +* SM2, SM3, and SM4 commercial encryption algorithms +* (D)TLS, TLCP secure transmission protocol +* On-demand feature configuration to meet users' requirements for compact RAM and ROM +* Arm-based and x86-based performance optimization of commercial encryption algorithms to meet high-performance requirements diff --git a/docs/en/2_Key Features.md b/docs/en/2_Key Features.md new file mode 100644 index 00000000..4e6244e0 --- /dev/null +++ b/docs/en/2_Key Features.md @@ -0,0 +1,19 @@ +# Overview + +openHiTLS aims to provide efficient and agile cryptography suites for all scenarios. With the elastic architecture of hierarchical modules and features, features can be selected and constructed as required, supporting applications in all scenarios to meet different requirements for RAM and ROM, computing performance, and feature satisfaction. Currently, openHiTLS supports cryptographic algorithms, secure communication protocols (TLS, DTLS, and TLCP), and Arm-based performance optimization of commercial encryption algorithms. More features are to be planned and welcome to participate in co-construction. + +# Feature Description + +1. Supported Features + +1.1. Key functional features are as follows: + +* TLS protocols: TLS1.2, TLS1.3, DTLS1.2, and TLCP +* Encryption and decryption cryptographic algorithms: AES, SM4, Chacha20, RSA, (EC)DSA, (EC)DH, SM2, DRBG, HKDF, SCRYPT, PBKDF2, SHA2, SHA3, MD5, SM3, HMAC, and x509 + +1.2. Non-functional features are as follows: + +* Elastic architecture: Modules and features can be selected and constructed as required +* Performance optimization: The Arm-based and x86-based performance optimization of commercial encryption algorithms is supported +* Maintainability and testability: The log and error stack functions are supported + diff --git a/docs/en/3_Quick Start.md b/docs/en/3_Quick Start.md new file mode 100644 index 00000000..d9457d93 --- /dev/null +++ b/docs/en/3_Quick Start.md @@ -0,0 +1,38 @@ +# Quick Start + +Welcome to the openHiTLS tutorial. This tutorial will guide you through installing, integrating, and using openHiTLS. + +## What Is openHiTLS? + +openHiTLS is a C/C++ library for building cryptographic security capabilities. It provides cryptographic algorithms and TLS protocol stacks that comply with public standards. + +## Installing openHiTLS + +1. Download related codes. + openHiTLS download address: https://gitee.com/openhitls/openhitls.git + + libboundscheck download address: https://gitee.com/openeuler/libboundscheck.git + + Note: Download libboundscheck to the **openHiTLS/platform/Secure_C** directory. +2. To build and install openHiTLS, run the following commands in the openHiTLS root directory: + +```~~~~ +mkdir build +cd build +cmake .. +make && make install +``` + +## Integrate openHiTLS in your C/C++ project. + +1. Call the APIs provided by openHiTLS in your project code according to the API manual. +2. Add the header file and library path of openHiTLS to your project dependency. The following uses the gcc compiler as an example: + +``` +# Use **-I** to specify the path of the header file and **-L** to specify the path of the dynamic library. +gcc application.c -lhitls_crypto -lhitls_tls -lhitls_bsl -lboundscheck -I -L +``` + +## Getting Started with openHiTLS + +After the preceding operations are performed, the security capabilities provided by openHiTLS can be used. diff --git a/docs/en/4_User Guide/1_Build and Installation Guide.md b/docs/en/4_User Guide/1_Build and Installation Guide.md new file mode 100644 index 00000000..52d3cfd0 --- /dev/null +++ b/docs/en/4_User Guide/1_Build and Installation Guide.md @@ -0,0 +1,171 @@ +# Build and Installation Guide + +## 1. Preparing the Build Environment + +Check whether the build tools have been installed in the system and can be used properly. + +| **Name**| **Recommended Version**| **Description**| +| -------- | ------------ | -------- | +| Gcc | ≥ 7.3.0 | Linux | +| Python | ≥ 3.5 | Linux | +| CMake | ≥ 3.16 | Linux | +| Sctp | No restriction on versions | Linux | + +P.S. The DTLS feature depends on sctp. By default, sctp is disabled. To enable it, you need to pre-install sctp dependencies. + +## 2. Preparing the Source Code + +Method 1 + +1. Download the openHiTLS code, including the service code, build script, and test code. + + Repository address: https://gitcode.com/openhitls/openhitls.git +2. openHiTLS depends on the libboundscheck library. Before building openHiTLS, download the library to **openHiTLS/platform/Secure\_C**. + + Repository address: https://gitee.com/openeuler/libboundscheck.git + +Method 2 + +Run the **git submodule** command to download the source code and dependent SecureC library: + +``` +git clone --recurse-submodules https://gitcode.com/openhitls/openhitls.git +``` + +## 3. Building and Installing openHiTLS + +The openHiTLS code directory structure is as follows: + +``` +└── openHiTLS + ├── bsl + ├── CMakeLists.txt + ├── config + ├── configure.py + ├── crypto + ├── docs + ├── include + ├── LICENSE + ├── platform + ├── README-en.md + ├── README.md + ├── script + ├── testcode + ├── tls + └── x509 +``` +Where: + +- configure.py: provides the command line function for build configuration +- config and script: stores build-related scripts +- bsl: stores the code related to basic functions +- crypto: stores the code related to cryptographic algorithm capabilities. +- tls: stores the code related to secure transmission +- platform: stores other dependent codes +- testcode: stores the test project code +- x509: provides the X509 certificate function + +**Call CMake to build the source code. The detailed method is as follows:** + +### 3.1 CMake Build + +openHiTLS provides the CMake build mode, which can be configured using **configure.py**. You are advised to create a **build** directory to store temporary files generated during the build process, and then go to the **build** directory and run "cmake .. &&make" to build openHiTLS. You can run the `python3 ./configure.py –help` command to query the configuration of **configure.py**. The related parameters are as follows. + +| **Script Parameter**| **Parameter Description**| **Execution Mode**| +| ------------- | ------------ | ---------------- | +|--help |Displays the help information about the script.|python3 configure.py --help| +|-m |Generates a **moudules.cmake** file.|python3 configure.py -m| +|--build_dir |Specifies the temporary directory for compilation.|python3 configure.py --build_dir build| +|--output_dir |Specifies the output path of the compilation target.|python3 configure.py --output_dir output| +|--feature_config|Specifies the compilation feature configuration file.|python3 configure.py --feature_config path/to/xxx.json| +|--compile_config|Specifies the compilation parameter configuration file.|python3 configure.py --compile_config path/to/xxx.json| +|--enable|Specifies build features.|python3 configure.py --enable hitls_crypto hitls_tls hitls_pse| +|--disable|disable buld features|python3 configure.py --disable sal_thread | +|--enable-sctp|enable sctp which is DTLS depended on|python3 configure.py --enable-sctp| +|--asm_type|Indicates the assembly type.|python3 configure.py --lib_type static --asm_type armv8| +|--asm|Specifes build asm features, whicht needs to be used simultaneously with parameter `asm_type`.|python3 configure.py --lib_type static --asm_type armv8 --asm sha2| +|--endian|Indicates big-endian or little-endian build.|python3 configure.py --endian little| +|--system|Specified the system type, currently only supports `linux`, used for 'sal_xxx' related features|python3 configure.py --system linux| +|--bits|To enable feature "bn", should specify the number of OS bits, `32\|64`|python3 configure.py --bits 64| +|--lib_type|Builds a static library, a dynamic library, or an object.|python3 configure.py --lib_type static| +|--add_options|Adds compilation options.|python3 configure.py --add_options "-O0 -g3"| +|--del_options|Removes compilation options.|python3 configure.py --del_options"-O2"| +|--add_link_flags|Adds link options.|python3 configure.py --add_link_flags="-pie"| +|--del_link_flags|Removes link options.|python3 configure.py --del_options="-O2 -Werror"| + +The **configure.py** script modifies the existing configuration based on the **compile.json** and **feature.json** configuration files at the top layer. + +The overall CMake build procedure is as follows: + +```bash +cd openHiTLS +mkdir -p ./build +cd ./build +python3 ../configure.py # Modify the configuration. For details, see section 3.1.1. +cmake .. +make -j +``` + +The build result is stored in the **openHiTLS/build** directory. + +#### 3.1.1 Common Configuration Commands + +```bash +# Disable a feature. +python3 ../configure.py --disable [feature]::[module] + +# Enable a feature. +python3 ../configure.py --enable [feature]::[module] + +# Enable sctp +python3 ../configure.py --enable-sctp + +# Default configuration file. If the file does not exist, a file is generated. Otherwise, no action is performed. +python3 ../configure.py -m + +# Add or delete compilation options. +# Note: If a compilation option already exists and you want to update it, you must run **--del_options** and **--add_options** in sequence. In this example, O0 needs to be changed to O2. +python3 ../configure.py --del_options="-O2 -D_FORTIFY_SOURCE=2" --add_options="-O0 -g" + +# Add or delete link options. +python3 ../configure.py --add_link_flags="-lxxx" --del_link_flags="-lxxx" + +# Generate static libraries only. +python3 ../configure.py --lib_type static + +# Generate dynamic libraries only. +python3 ../configure.py --lib_type shared + +# Generate object files only. +python3 ../configure.py --lib_type object + +# Generate dynamic libraries, static libraries, and object files. +python3 ../configure.py --lib_type shared static object +``` + +#### 3.1.2 Cross Compilation + +To cross compile openHiTLS, you need to use the **-DCMAKE_TOOLCHAIN_FILE** parameter of CMake to transfer the cross compilation configuration, as follows: + +```bash +cd openHiTLS +mkdir -p ./build +cd ./build +python3 ../configure.py --bits=64 --system=linux # Modify the configuration. For details, see section 3.1.1. +cmake -DCMAKE_TOOLCHAIN_FILE=usr_gcc.toolchain.cmake .. # xxx.toolchain.cmake needs to be written by the user. +make -j +``` + +### 3.2 Installing the Build Result + +To install the build result of openHiTLS, you only need to enter the following command: + +```bash +make install +``` + +By default, header files are installed in **/usr/local/include**, and library files are installed in **/usr/local/lib**. If you need to customize the installation path, run the following command in the CMake configuration phase: + +```bash +cmake -DCMAKE_INSTALL_PREFIX= .. +``` diff --git a/docs/en/4_User Guide/2_Test Guide.md b/docs/en/4_User Guide/2_Test Guide.md new file mode 100644 index 00000000..e7c668ca --- /dev/null +++ b/docs/en/4_User Guide/2_Test Guide.md @@ -0,0 +1,120 @@ +The test project depends on the source code compilation. Prepare the environment on which the compilation depends by referring to *Build and Installation Guide* to ensure that the source code can be correctly compiled. + +## 1. Test Environment Preparation + +| **Name**| **Recommended Version**| **Description** | +| -------- | ------------ | --------------------------------------------------- | +| Gcc | ≥ 7.3.0 | Linux | +| Python | ≥ 3.5 | Linux | +| CMake | ≥ 3.16 | Linux | +| Sctp | No restriction on versions | Linux | + +## 2. Test Code Directory Structure + +``` +./testcode/ +├── CMakeLists.txt +├── common +│ ├── execute_base.c +│ └── execute_test.c +├── demo +├── framework +│ ├── crypto +│ ├── gen_test +│ ├── include +│ ├── process +│ ├── stub +│ └── tls +├── output +├── script +│ ├── all_mini_test.sh +│ ├── build_hitls.sh +│ ├── build_sdv.sh +│ ├── execute_sdv.sh +│ └── mini_build_test.sh +├── sdv +│ ├── CMakeLists.txt +│ ├── log +│ ├── report +│ └── testcase +└── testdata + ├── cert + └── tls +``` +Where: + +- common: common test framework code +- demo: openHiTLS function test demo +- framework: framework code of the openHiTLS test case +- output: output directory of case test results and process files +- script: directory of test script code +- sdv: code of the openHiTLS test case for function scenarios +- testdata: directory of test data + +## 3. Function Test Execution Guide + +### 3.1 Test Framework Description + +A test framework developed by the community provides public configurations and methods for community developers to compile and execute the test code. A test unit consists of a function file (.c) and a data file (.data), which store test functions and test data, respectively. + +![image](../images/User%20Guide/Test%20Guide_figures/TestFrameworkDescription.png) + +### 3.2 Script Parameter Description + +| **Command** | **Description** | +| --------------------------- | ------------------------------------------------------------ | +| bash build_hitls.sh | Compiles all source codes. | +| bash build_sdv.sh | Compiles all test codes. | +| bash execute_sdv.sh | Executes test cases.| + +- Parameters of the **build_hitls.sh** script + +| **Script Parameter**|**Execution Mode** | **Parameter Description** | +| -------- | ------------ | --------------------------------------------------- | +| gcov | bash build_hitls.sh gcov |Enables the capability of obtaining the coverage rate. | +| debug | bash build_hitls.sh debug |Enables the debug capability. | +| asan | bash build_hitls.sh asan |Enables the memory monitoring capability. | + +- Parameters of the **build_sdv.sh** script + +| **Script Parameter**| **Execution Mode** | **Parameter Description** | +| -------- | ------------ | --------------------------------------------------- | +| --help or -h | bash build_sdv.sh --help |Obtains help information. | +| no-crypto | bash build_sdv.sh no-crypto |Deletes the test cases of the crypto module. | +| no-bsl | bash build_sdv.sh no-bsl | Deletes the test cases of the bsl module. | +| no-tls | bash build_sdv.sh no-tls | Deletes the test cases of the tls module. | +| no-x509 | bash build_sdv.sh no-x509 | Deletes the test cases of the x509 module. | +| verbose |bash build_sdv.sh verbose |Displays the detailed information about the build process. | +| gcov | bash build_sdv.sh gcov | Enables the capability of obtaining the coverage rate. | +| asan | bash build_sdv.sh asan | Enables the memory monitoring capability. | +| big-endian |bash build_sdv.sh big-endian | Implements compilation in the big-endian environment. | +| run-tests | bash build_sdv.sh run-tests=xxx1xxx2xxx3 | Compiles a specified test suite. | + +- Parameters of the **execute_sdv.sh** script + +| **Script Parameter**| **Execution Mode**| **Parameter Description** | +| -------- | ------------ | --------------------------------------------------- | +| \ | bash execute_sdv.sh test_suites_xxx ... | Executes all test cases in a specified file.| +| \ | bash execute_sdv.sh UT_CRYPTO_xxx SDV_CRYPTO_xxx ... |Executes a test case with a specified name. | + +Remarks: Parameters can be transferred to the script in combination mode. For example: + +- Build the source code in default mode: bash build_hitls.sh +- Enable ASan, debug, and coverage during source code build: bash build_hitls.sh asan gcov debug +- Enable ASan and coverage during test code build, and display build details: bash build_sdv.sh asan gcov verbose +- Build the source code in default mode: bash build_hitls.sh +- Execute all test cases in default mode: bash execute_sdv.sh +- Execute a specified test set: bash execute_sdv.sh test_suites_xxx1 test_suites_xxx2 + +### 3.3 Test Case Execution Process + +The test project depends on the following scripts: + +- **build_hitls.sh**: script for building the source code in one-click mode +- **build_sdv.sh**: script for building test cases in one-click mode +- **execute_sdv.sh**: script for executing test cases in one-click mode + ![image](../images/User%20Guide/Test%20Guide_figures/TestCaseExecutionProcess.png) + +### 3.4 Viewing Test Case Results + +After the test is complete, you can go to the **output/log** directory to view the test case execution results. If a problem is found in the community repository, check whether there is a trouble ticket in the repository issue. If there is no trouble ticket, submit a trouble ticket to track the problem. diff --git a/docs/en/4_User Guide/3_Upgrade Guide.md b/docs/en/4_User Guide/3_Upgrade Guide.md new file mode 100644 index 00000000..58d2c777 --- /dev/null +++ b/docs/en/4_User Guide/3_Upgrade Guide.md @@ -0,0 +1,3 @@ +# Upgrade Guide + +This is the first release of openHiTLS. For details about how to build and use openHiTLS, see [Build and Installation Guide](./1_Build%20and%20Installation%20Guide.md). diff --git a/docs/en/5_Developer Guide/1_Encryption and Integrity Protection Application Development Guide.md b/docs/en/5_Developer Guide/1_Encryption and Integrity Protection Application Development Guide.md new file mode 100644 index 00000000..aba5c21b --- /dev/null +++ b/docs/en/5_Developer Guide/1_Encryption and Integrity Protection Application Development Guide.md @@ -0,0 +1,728 @@ +# Cryptographic Algorithm Functions + +openHiTLS provides functions such as encryption and decryption, signature verification, and hash calculation based on the cryptographic algorithm standard. Provided by algorithm module, the main function interfaces support the default cryptographic algorithm capability for the certificate and TLS module in the openHiTLS system + +## Function Specifications + +* Encryption and decryption: supports symmetric encryption and decryption based on SM4, AES, and CHACHA20, and asymmetric encryption and decryption based on SM2 and RSA. +* Signature verification: supports SM2, DSA, ED25519, RSA, and ECDSA. +* Key exchange: supports SM2, X25519, and ECDH. +* Key derivation: supports PBKDF2, HKDF, SCRYPT, and KDFTLS12. +* Integrity algorithm: supports integrity protection based on HMAC. +* Hash calculation: supports digest calculation based on SM3, SHA2, SHA3, MD5, and SHA1. +* Random number generation: supports DRBG-HASH, DRBG-CTR, and DRBG-HMAC. + +# Examples of Encryption and Decryption + +## Symmetric Encryption and Decryption + +This function provides encryption and decryption capabilities based on symmetric algorithms. The following uses the SM4-CBC algorithm as an example to describe the sample code for reference. + +## Sample Code + +```c +#include +#include +#include +#include +#include "crypt_eal_cipher.h" // Header file of the interfaces for symmetric encryption and decryption. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // Algorithm ID list. +#include "crypt_errno.h" // Error code list. + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // Obtain the name and number of lines of the error file. + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = { StdMalloc, free }; // Registered interfaces for memory allocation. + +int main(void) +{ + uint8_t data[10] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x1c, 0x14}; + uint8_t iv[16] = {0}; + uint8_t key[16] = {0}; + uint32_t dataLen = sizeof(data); + uint8_t cipherText[100]; + uint8_t plainText[100]; + uint32_t outTotalLen = 0; + uint32_t outLen = sizeof(cipherText); + uint32_t cipherTextLen; + int32_t ret; + + printf("plain text to be encrypted: "); + for (uint32_t i = 0; i < dataLen; i++) { + printf("%02x", data[i]); + } + printf("\n"); + + // Initialize the error code module. + BSL_ERR_Init(); + + // Before calling the algorithm APIs, call the **BSL_SAL_RegMemCallback** function to register the **malloc** and **free** functions. Execute this step only once. + // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. + BSL_SAL_RegMemCallback(&cb); + + // Create a context. + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC); + if (ctx == NULL) { + PrintLastError(); + BSL_ERR_DeInit(); + return 1; + } + // During initialization, the last input parameter can be **true** or **false**. **true** indicates encryption, and **false** indicates decryption. + ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); // Output the error code. You can find the error information in **crypt_errno.h** based on the error code. + PrintLastError(); + goto exit; + } + // Set the padding mode. + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Enter the data to be calculated. This interface can be called for multiple times. The input value of **outLen** is the length of the ciphertext, and the output value is the amount of processed data. + ret = CRYPT_EAL_CipherUpdate(ctx, data, dataLen, cipherText, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + outLen = sizeof(cipherText) - outTotalLen; + + ret = CRYPT_EAL_CipherFinal(ctx, cipherText + outTotalLen, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + printf("cipher text value is: "); + + for (uint32_t i = 0; i < outTotalLen; i++) { + printf("%02x", cipherText[i]); + } + printf("\n"); + + // Start decryption. + cipherTextLen = outTotalLen; + outTotalLen = 0; + outLen = sizeof(plainText); + + // When initializing the decryption function, set the last input parameter to **false**. + ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), false); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + //Set the padding mode, which must be the same as that for encryption. + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Enter the ciphertext data. + ret = CRYPT_EAL_CipherUpdate(ctx, cipherText, cipherTextLen, plainText, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + outTotalLen += outLen; + outLen = sizeof(plainText) - outTotalLen; + + // Decrypt the last segment of data and remove the filled content. + ret = CRYPT_EAL_CipherFinal(ctx, plainText + outTotalLen, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + + printf("decrypted plain text value is: "); + for (uint32_t i = 0; i < outTotalLen; i++) { + printf("%02x", plainText[i]); + } + printf("\n"); + + if (outTotalLen != dataLen || memcmp(plainText, data, dataLen) != 0) { + printf("plaintext comparison failed\n"); + goto exit; + } + printf("pass \n"); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + BSL_ERR_DeInit(); + return ret; +} +``` + +## Asymmetric Encryption and Decryption + +This function provides encryption and decryption capabilities based on asymmetric algorithms. The following uses the SM2 encryption and decryption process as an example to describe the sample code for reference. + +## Sample Code + +```c +#include +#include +#include +#include +#include "crypt_eal_pkey.h" // Header file of the interfaces for asymmetric encryption and decryption. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" +#include "crypt_types.h" + +void *StdMalloc(uint32_t len) { + return malloc((uint32_t)len); +} +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) { + int32_t ret; + BSL_ERR_Init(); // Initialize the error code module. + // Before calling the algorithm APIs, call the **BSL_SAL_RegMemCallback** function to register the **malloc** and **free** functions. Execute this step only once. + // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. + BSL_SAL_RegMemCallback(&cb); + CRYPT_EAL_PkeyCtx *pkey = NULL; + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (pkey == NULL) { + PrintLastError(); + goto exit; + } + + // Initialize the random number. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Generate a key pair. + ret = CRYPT_EAL_PkeyGen(pkey); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyGen: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Data to be encrypted. + char *data = "test enc data"; + uint32_t dataLen = 12; + uint8_t ecrypt[125] = {0}; + uint32_t ecryptLen = 125; + uint8_t dcrypt[125] = {0}; + uint32_t dcryptLen = 125; + // Encrypt data. + ret = CRYPT_EAL_PkeyEncrypt(pkey, data, dataLen, ecrypt, &ecryptLen); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyEncrypt: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Decrypt data. + ret = CRYPT_EAL_PkeyDecrypt(pkey, ecrypt, ecryptLen, dcrypt, &dcryptLen); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyDecrypt: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + if (memcmp(dcrypt, data, dataLen) == 0) { + printf("encrypt and decrypt success\n"); + } else { + ret = -1; + } +exit: + // Release the context memory. + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return ret; +} +``` + +# Example of Signature Verification + +## Algorithm Type + +This function provides the signature verification capability based on asymmetric algorithms. The following uses SM2 signature verification as an example to describe the sample code for reference. + +## Sample Code + +```c +#include +#include +#include +#include +#include "crypt_eal_pkey.h" // Header file for signature verification. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line);// Obtain the name and number of lines of the error file. + printf("failed at file %s at line %d\n", file, line); +} +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int ret; + uint8_t userId[32] = {0}; + uint8_t key[32] = {0}; + uint8_t msg[32] = {0}; + uint8_t signBuf[100] = {0}; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx = NULL; + + BSL_ERR_Init(); // Initialize the error code module. + // Before calling the algorithm APIs, call the **BSL_SAL_RegMemCallback** function to register the **malloc** and **free** functions. Execute this step only once. + // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. + BSL_SAL_RegMemCallback(&cb); + + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (ctx == NULL) { + goto exit; + } + + // Set a user ID. + ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Initialize the random number. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Generate a key pair. + ret = CRYPT_EAL_PkeyGen(ctx); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Sign. + ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Verify the signature. + ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("pass \n"); + +exit: + // Release the context memory. + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return ret; +} +``` + +# Example of Key Exchange + +## Algorithm Type + +This function provides the key exchange capability based on asymmetric algorithms. The following uses ECDH as an example to describe the sample code for reference. + +## Sample Code + +```c +#include +#include +#include +#include +#include "crypt_types.h" +#include "crypt_eal_pkey.h" // Header file for key exchange. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int ret; + + uint8_t prikey[] = + {0x7d, 0x7d, 0xc5, 0xf7, 0x1e, 0xb2, 0x9d, 0xda, 0xf8, 0x0d, 0x62, 0x14, 0x63, 0x2e, 0xea, 0xe0, + 0x3d, 0x90, 0x58, 0xaf, 0x1f, 0xb6, 0xd2, 0x2e, 0xd8, 0x0b, 0xad, 0xb6, 0x2b, 0xc1, 0xa5, 0x34}; + uint8_t pubkey[] = + {0x04, 0x70, 0x0c, 0x48, 0xf7, 0x7f, 0x56, 0x58, 0x4c, 0x5c, 0xc6, 0x32, 0xca, 0x65, 0x64, 0x0d, 0xb9, + 0x1b, 0x6b, 0xac, 0xce, 0x3a, 0x4d, 0xf6, 0xb4, 0x2c, 0xe7, 0xcc, 0x83, 0x88, 0x33, 0xd2, 0x87, + 0xdb, 0x71, 0xe5, 0x09, 0xe3, 0xfd, 0x9b, 0x06, 0x0d, 0xdb, 0x20, 0xba, 0x5c, 0x51, 0xdc, 0xc5, + 0x94, 0x8d, 0x46, 0xfb, 0xf6, 0x40, 0xdf, 0xe0, 0x44, 0x17, 0x82, 0xca, 0xb8, 0x5f, 0xa4, 0xac}; + uint8_t resSharekey[] = + {0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xff, 0x01, 0x2e, 0x54, 0xa4, 0x34, 0xfb, 0xdd, 0x2d, 0x25, + 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b}; + + CRYPT_EAL_PkeyPrv prvKey = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + uint32_t shareLen; + uint8_t *shareKey; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_PKEY_ParaId id = CRYPT_ECC_NISTP256; + + BSL_ERR_Init(); // Initialize the error code module. + // Before calling the algorithm APIs, call the **BSL_SAL_RegMemCallback** function to register the **malloc** and **free** functions. Execute this step only once. + // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. + BSL_SAL_RegMemCallback(&cb); + + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + if (prvCtx == NULL || pubCtx == NULL) { + goto exit; + } + + // Set the curve parameters. + ret = CRYPT_EAL_PkeySetParaById(prvCtx, id); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the private key of one end. + prvKey.id = CRYPT_PKEY_ECDH; + prvKey.key.eccPrv.len = sizeof(prikey); + prvKey.key.eccPrv.data = prikey; + ret = CRYPT_EAL_PkeySetPrv(prvCtx, &prvKey); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the curve parameters. + ret = CRYPT_EAL_PkeySetParaById(pubCtx, id); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the public key of the other end. + pubKey.id = CRYPT_PKEY_ECDH; + pubKey.key.eccPub.len = sizeof(pubkey); + pubKey.key.eccPub.data = pubkey; + ret = CRYPT_EAL_PkeySetPub(pubCtx, &pubKey); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // The shared key involves only the X axis. The length of the public key is not compressed in the returned results. + shareLen = CRYPT_EAL_PkeyGetKeyLen(prvCtx) / 2; + shareKey = (uint8_t *)BSL_SAL_Malloc(shareLen); + if (shareKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + PrintLastError(); + goto exit; + } + + // Initialize the random number. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Calculate the shared key. + ret = CRYPT_EAL_PkeyComputeShareKey(prvCtx, pubCtx, shareKey, &shareLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Compare the calculation result with the expected one. + if (shareLen != sizeof(resSharekey) || memcmp(shareKey, resSharekey, shareLen) != 0) { + printf("failed to compare test results\n"); + ret = -1; + goto exit; + } + + printf("pass \n"); + +exit: + // Release the context memory. + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(prvCtx); + CRYPT_EAL_PkeyFreeCtx(pubCtx); + BSL_SAL_Free(shareKey); + BSL_ERR_DeInit(); + return 0; +} +``` + +# Example of Key Derivation + +## Algorithm Type + +The PBKDF2, HKDF, SCRYPT, and KDFTLS12 algorithms can be used for key derivation. The following uses PBKDF2 as an example to describe the sample code for reference. + +## Sample Code + +```c +#include +#include +#include +#include +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_eal_kdf.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int32_t ret; + uint8_t key[] = {0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64}; + uint8_t salt[] = {0x4e, 0x61, 0x43, 0x6c}; + uint32_t iterations = 80000; + uint8_t result[] = { + 0x4d, 0xdc, 0xd8, 0xf6, 0x0b, 0x98, 0xbe, 0x21, + 0x83, 0x0c, 0xee, 0x5e, 0xf2, 0x27, 0x01, 0xf9, + 0x64, 0x1a, 0x44, 0x18, 0xd0, 0x4c, 0x04, 0x14, + 0xae, 0xff, 0x08, 0x87, 0x6b, 0x34, 0xab, 0x56, + 0xa1, 0xd4, 0x25, 0xa1, 0x22, 0x58, 0x33, 0x54, + 0x9a, 0xdb, 0x84, 0x1b, 0x51, 0xc9, 0xb3, 0x17, + 0x6a, 0x27, 0x2b, 0xde, 0xbb, 0xa1, 0xd0, 0x78, + 0x47, 0x8f, 0x62, 0xb3, 0x97, 0xf3, 0x3c, 0x8d}; + + uint8_t out[sizeof(result)] = {0}; + uint32_t outLen = sizeof(result); + + // Initialize the error code module. + BSL_ERR_Init(); + + // Before calling the algorithm APIs, call the **BSL_SAL_RegMemCallback** function to register the **malloc** and **free** functions. Execute this step only once. + // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. + BSL_SAL_RegMemCallback(&cb); + + ret = CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, sizeof(key), salt, sizeof(salt), iterations, out, outLen); + if (ret != CRYPT_SUCCESS) { + printf("pbkdf2 error code is %x\n", ret); + PrintLastError(); + goto exit; + } + if (memcmp(out, result, sizeof(result)) != 0) { + printf("failed to compare test results\n"); + ret = -1; + goto exit; + } + printf("pass \n"); +exit: + BSL_ERR_DeInit(); + return ret; +} +``` + +# Example of Random Number Generation + +## Algorithm Type + +The DRBG-SHA, DRBG-HMAC, and DRBG-CTR algorithms can be used for random number generation. The interfaces include global random number interfaces and multi-instance random number interfaces. + +```c +/* +* Global random number initializing and deinitializing interfaces. + * The **seedMeth** value of initializing interfaces is the entropy source of the callback, and the **seedCtx** value is the context called back by the user. +* Users can set their own entropy source. If it is not set, the default entropy source is used. +* Currently, entropy can be obtained from **/dev/random** of Linux. +*/ +int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, const uint8_t *pers, uint32_t persLen); +void CRYPT_EAL_RandDeinit(void); + +/* After initialization, users can call the following interfaces to obtain the pseudo-random number and supplement the entropy source.*/ +int32_t CRYPT_EAL_Randbytes(uint8_t *byte, uint32_t len); +int32_t CRYPT_EAL_RandSeed(void); + +/*The deterministic random bit generator (DRBG) context of the multi-instance random number interfaces is returned to the user. This is the main difference between the two types of interfaces. + * Multiple DRBG contexts can be created. Different contexts do not interfere with each other during entropy source setting and internal status change.*/ +CRYPT_EAL_RndCtx *CRYPT_EAL_DrbgInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, const uint8_t *pers, uint32_t persLen); +void CRYPT_EAL_DrbgDeinit(CRYPT_EAL_RndCtx *ctx); +``` + +The following uses the DRBG-SHA algorithm as an example to describe the sample code for reference. + +## Sample Code + +```c +#include +#include +#include +#include +#include "crypt_types.h" +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int ret; + uint8_t output[100] = {0}; + uint32_t len = 100; + + // Before calling the algorithm APIs, call the **BSL_SAL_RegMemCallback** function to register the **malloc** and **free** functions. Execute this step only once. + // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. + BSL_SAL_RegMemCallback(&cb); + + BSL_ERR_Init();// Initialize the error module. + + // Initialize the global random number by using the default entropy source from **/dev/random** of Linux. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Obtain the random number sequence of the **len** value. + ret = CRYPT_EAL_Randbytes(output, len); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("random value is: "); // Output the random number. + for (uint32_t i = 0; i < len; i++) { + printf("%02x", output[i]); + } + printf("\n"); + + // Reseeding + ret = CRYPT_EAL_RandSeed(); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandSeed: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Obtain the random number sequence of the **len** value. + ret = CRYPT_EAL_Randbytes(output, len); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("random value is: "); // Output the random number. + for (uint32_t i = 0; i < len; i++) { + printf("%02x", output[i]); + } + printf("\n"); + +exit: + // Release the context memory. + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return 0; +} +``` diff --git a/docs/en/5_Developer Guide/2_Secure Communication Application Development Guide.md b/docs/en/5_Developer Guide/2_Secure Communication Application Development Guide.md new file mode 100644 index 00000000..b941d956 --- /dev/null +++ b/docs/en/5_Developer Guide/2_Secure Communication Application Development Guide.md @@ -0,0 +1,820 @@ +# TLS Feature Introduction + +## Protocol Description + +openHiTLS offers functions such as creating, configuring, and managing security protocol links based on transport-layer security protocol standards, with the main functional interfaces available in the protocol module. openHiTLS supports various protocol versions and features, including basic protocol handshake, key update, application-layer protocol negotiation, and server name indication. + +Currently, openHiTLS supports the following protocol versions: + +- TLS1.2: used for secure renegotiation, application-layer protocol negotiation, server name indication, and session resumption +- TLS1.3: used for key update, application-layer protocol negotiation, server name indication, and session resumption +- DTLS1.2: used for secure renegotiation, application-layer protocol negotiation, server name indication, and session resumption +- TLCP: used for secure renegotiation and session resumption + +### TLS/DTLS1.2 Specifications + +| Configuration Item| Specifications| +| :---- | :---- | +| TLS version| TLS12 (0x0303u)
DTLS12 (0xfefdu)| +| Algorithm suite| TLS_RSA_WITH_AES_128_CBC_SHA (0x002F)
TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
TLS_DH_anon_WITH_AES_128_CBC_SHA (0x0034)
TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
TLS_DH_anon_WITH_AES_256_CBC_SHA (0x003A)
TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003C)
TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003D)
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 (0x006A)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006B)
TLS_DH_anon_WITH_AES_128_CBC_SHA256 (0x006C)
TLS_DH_anon_WITH_AES_256_CBC_SHA256 (0x006D)
TLS_PSK_WITH_AES_128_CBC_SHA (0x008C)
TLS_PSK_WITH_AES_256_CBC_SHA (0x008D)
TLS_DHE_PSK_WITH_AES_128_CBC_SHA (0x0090)
TLS_DHE_PSK_WITH_AES_256_CBC_SHA (0x0091)
TLS_RSA_PSK_WITH_AES_128_CBC_SHA (0x0094)
TLS_RSA_PSK_WITH_AES_256_CBC_SHA (0x0095)
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009C)
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009D)
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009E)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009F)
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00A2)
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 (0x00A3)
TLS_DH_anon_WITH_AES_128_GCM_SHA256 (0x00A6)
TLS_DH_anon_WITH_AES_256_GCM_SHA384 (0x00A7)
TLS_PSK_WITH_AES_128_GCM_SHA256 (0x00A8)
TLS_PSK_WITH_AES_256_GCM_SHA384 (0x00A9)
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 (0x00AA)
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 (0x00AB)
TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 (0x00AC)
TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 (0x00AD)
TLS_PSK_WITH_AES_128_CBC_SHA256 (0x00AE)
TLS_PSK_WITH_AES_256_CBC_SHA384 (0x00AF)
TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 (0x00B2)
TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 (0x00B3)
TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 (0x00B6)
TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 (0x00B7)
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xC009)
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xC00A)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xC013)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xC014)
TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xC018)
TLS_ECDH_anon_WITH_AES_256_CBC_SHA (0xC019)
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xC023)
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xC024)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xC027)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xC028)
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xC02B)
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xC02C)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xC030)
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA (0xC035)
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA (0xC036)
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 (0xC037)
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 (0xC038)
TLS_RSA_WITH_AES_128_CCM (0xC09C)
TLS_RSA_WITH_AES_256_CCM (0xC09D)
TLS_DHE_RSA_WITH_AES_128_CCM (0xC09E)
TLS_DHE_RSA_WITH_AES_256_CCM (0xC09F)
TLS_RSA_WITH_AES_128_CCM_8 (0xC0A0)
TLS_RSA_WITH_AES_256_CCM_8 (0xC0A1)
TLS_PSK_WITH_AES_256_CCM (0xC0A5)
TLS_DHE_PSK_WITH_AES_128_CCM (0xC0A6)
TLS_DHE_PSK_WITH_AES_256_CCM (0xC0A7)
TLS_ECDHE_ECDSA_WITH_AES_128_CCM (0xC0AC)
TLS_ECDHE_ECDSA_WITH_AES_256_CCM (0xC0AD)
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA8)
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA9)
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCAA)
TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAB)
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAC)
TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAD)
TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAE)
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 (0xD001)
TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 (0xD002)
TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 (0xD005)| +| EC dotted format| uncompressed (0)| +| Elliptic curve| secp256r1 (23)
secp384r1 (24)
secp521r1 (25)
brainpoolP256r1 (26)
brainpoolP384r1 (27)
brainpoolP512r1 (28)
x25519 (29)| +| Signature hash algorithm| dsa_sha256 (0x0402)
dsa_sha384 (0x0502)
dsa_sha512 (0x0602)
rsa_pkcs1_sha256 (0x0401)
rsa_pkcs1_sha384 (0x0501)
rsa_pkcs1_sha512 (0x0601)
ecdsa_secp256r1_sha256 (0x0403)
ecdsa_secp384r1_sha384 (0x0503)
ecdsa_secp521r1_sha512 (0x0603)
rsa_pss_rsae_sha256 (0x0804)
rsa_pss_rsae_sha384 (0x0805)
rsa_pss_rsae_sha512 (0x0806)
rsa_pss_pss_sha256 (0x0809)
rsa_pss_pss_sha384 (0x080a)
rsa_pss_pss_sha512 (0x080b)
ed25519 (0x0807)| +| Dual-ended verification| **HITLS_CFG_SetClientVerifySupport** (disabled by default)| +| Blank client certificate| **HITLS_CFG_SetNoClientCertSupport** (disabled by default)| +| Do not verify peer certificate| **HITLS_CFG_SetVerifyNoneSupport** (disabled by default)| +| Renegotiation| **HITLS_CFG_SetRenegotiationSupport** (disabled by default)| +| Verify client certificate only once| **HITLS_CFG_SetClientOnceVerifySupport** (disabled by default)| +| Send handshake packets in a single flight| **HITLS_CFG_SetFlightTransmitSwitch** (disabled by default)| +| Quiet shutdown mode| **HITLS_CFG_SetQuietShutdown** (disabled by default)| +| Extend primary key| **HITLS_CFG_SetExtenedMasterSecretSupport** (enabled by default)| +| Support **sessionTicket**| **HITLS_CFG_SetSessionTicketSupport** (enabled by default)| +| Verify **keyUsage**| **HITLS_CFG_SetCloseCheckKeyUsage** (enabled by default)| +| Auto-generate DH parameter| **HITLS_CFG_SetDhAutoSupport** (enabled by default)| + +### TLS1.3 Specifications + +| Configuration Item| Specifications| +| :---- | :---- | +| TLS version| TLS13 (0x0304u)| +| Algorithm suite| TLS_AES_128_GCM_SHA256 (0x1301)
TLS_AES_256_GCM_SHA384 (0x1302)
TLS_CHACHA20_POLY1305_SHA256 (0x1303)
TLS_AES_128_CCM_SHA256 (0x1304)
TLS_AES_128_CCM_8_SHA256 (0x1305)| +| EC dotted format| uncompressed (0)| +| Elliptic curve| secp256r1 (23)
secp384r1 (24)
secp521r1 (25)
x25519 (29)
ffdhe2048 (256)
ffdhe3072 (257)
ffdhe4096 (258)
ffdhe6144 (259)
ffdhe8192 (260)| +| Signature hash algorithm| rsa_pkcs1_sha256 (0x0401)
rsa_pkcs1_sha384 (0x0501)
rsa_pkcs1_sha512 (0x0601)
ecdsa_secp256r1_sha256 (0x0403)
ecdsa_secp384r1_sha384 (0x0503)
ecdsa_secp521r1_sha512 (0x0603)
rsa_pss_rsae_sha256 (0x0804)
rsa_pss_rsae_sha384 (0x0805)
rsa_pss_rsae_sha512 (0x0806)
rsa_pss_pss_sha256 (0x0809)
rsa_pss_pss_sha384 (0x080a)
rsa_pss_pss_sha512 (0x080b)
ed25519 (0x0807)| +| Dual-ended verification| **HITLS_CFG_SetClientVerifySupport** (disabled by default)| +| Blank client certificate| **HITLS_CFG_SetNoClientCertSupport** (disabled by default)| +| Do not verify peer certificate| **HITLS_CFG_SetVerifyNoneSupport** (disabled by default)| +| Verify client certificate only once| **HITLS_CFG_SetClientOnceVerifySupport** (disabled by default)| +| Authentication after handshake| **HITLS_CFG_SetPostHandshakeAuthSupport** (disabled by default)| +| Send handshake packets in a single flight| **HITLS_CFG_SetFlightTransmitSwitch** (disabled by default)| +| Quiet shutdown mode| **HITLS_CFG_SetQuietShutdown** (disabled by default)| +| Extend primary key| **HITLS_CFG_SetExtenedMasterSecretSupport** (enabled by default)| +| Support **sessionTicket**| **HITLS_CFG_SetSessionTicketSupport** (enabled by default)| +| Verify **keyUsage**| **HITLS_CFG_SetCloseCheckKeyUsage** (enabled by default)| +| Auto-generate DH parameter| **HITLS_CFG_SetDhAutoSupport** (enabled by default)| + +### TLCP Specifications + +| Configuration Item| Specifications| +| :---- | :---- | +| TLCP version| TLCP11 (0x0101u)| +| Algorithm suite| ECDHE_SM4_CBC_SM3 (0xE011)
ECC_SM4_CBC_SM3 (0xE013)| +| EC dotted format| HITLS_POINT_FORMAT_UNCOMPRESSED (0)| +| Elliptic curve| curveSM2 (41)| +| Signature hash algorithm| sm2sig_sm3 (0x0708)| +| Dual-ended verification| **HITLS_CFG_SetClientVerifySupport** (disabled by default)| +| Blank client certificate| **HITLS_CFG_SetNoClientCertSupport** (disabled by default)| +| Do not verify peer certificate| **HITLS_CFG_SetVerifyNoneSupport** (disabled by default)| +| Verify client certificate only once| **HITLS_CFG_SetClientOnceVerifySupport** (disabled by default)| +| Send handshake packets in a single flight| **HITLS_CFG_SetFlightTransmitSwitch** (disabled by default)| +| Quiet shutdown mode| **HITLS_CFG_SetQuietShutdown** (disabled by default)| +| Verify **keyUsage**| **HITLS_CFG_SetCloseCheckKeyUsage** (enabled by default)| + +### Extended Capabilities + +| Name| DTLS1.2 | TLS1.2 | TLS1.3 | TLCP | +| :---- | :---- | :---- | :---- | :---- | +| server_name | Yes| Yes| Yes| No| +| supported_groups | Yes| Yes| Yes| Yes| +| ec_point_formats | Yes| Yes| No| Yes| +| signature_algorithms | Yes| Yes| Yes| No| +| application_layer_protocol_negotiation | Yes| Yes| Yes| No| +| extended_master_secret | Yes| Yes| No| No| +| session_ticket | Yes| Yes| No| No| +| encrypt_then_mac | Yes| Yes| No| Yes| +| renegotiation_info | Yes| Yes| No| Yes| +| early_data | No| No| No| No| +| supported_versions | No| No| Yes| No| +| cookie | Yes| No| Yes| No| +| pre_shared_key | No| No| Yes| No| +| psk_key_exchange_modes | No| No| Yes| No| +| certificate_authorities | No| No| No| No| +| oid_filters | No| No| No| No| +| post_handshake_auth | No| No| Yes| No| +| signature_algorithms_cert | No| No| No| No| +| key_share | No| No| Yes| No| + +### Framework + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/TheFramework.png) + +### Context Overview + +In openHiTLS, secure transmission context is split into two layers: `HITLS_Config` and `HITLS_Ctx`. `HITLS_Config` is the configuration context, with one context for each service type (like client or server) in a process. `HITLS_Ctx` is the link context, with one context for each connection. The configuration context and link context have a many-to-one relationship, and each link context in openHiTLS has a copy of the configuration context. + +### Non-blocking I/O Capability + +The protocol module cannot create file descriptions (FDs). Users must create and configure FDs in openHiTLS. Once openHiTLS reads and writes the FDs, users should close them. openHiTLS supports **non-blocking I/O** in both handshake and read/write phases. If calling `HITLS_Read` or `HITLS_Write` returns `HITLS_REC_NORMAL_RECV_BUF_EMPTY` or `HITLS_REC_NORMAL_IO_BUSY`, openHiTLS needs to repeat the read/write operation. In practice, the epoll/select driver is typically used to implement non-blocking I/O capabilities. The following is a piece of exemplary code of non-blocking I/O: + +```c +// Shake hands with the client. +do { + ret = HITLS_Connect(ctx); +} while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); +// Shake hands with the server. +do { + ret = HITLS_Accept(ctx); +} while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); +``` + +> **NOTE:** The `do while` statement serves as a reference only. In practice, the service logic may be implemented in a different manner. + +### Constraints + +1. The openHiTLS client and server are both authenticated using certificates. +2. Users can quickly get started with openHiTLS using the default configurations provided. Typically, only a few additional configurations based on the defaults are required for openHiTLS to function properly. openHiTLS provides a rich set of configuration interfaces, and an API manual is provided to help product developers configure openHiTLS options as needed. + +### Dependencies + +The dependency on certain algorithm implementations and certificate parsing varies depending on product requirements. As such, openHiTLS offers registration interfaces for products to register interfaces that meet their specific requirements. For details about the interfaces that openHiTLS depends on, see the following headers file of the API manual: + +- [hitls_cert_reg.h](https://apidoc.openhitls.net/d4/d9a/a00246.html) +- [hitls_crypt_reg.h](https://apidoc.openhitls.net/d0/da7/a00250.html) + +Registering algorithm-related callback functions: + +```c +/** + * @brief Callback functions that must be registered + */ +typedef struct { + CRYPT_RandBytesCallback randBytes; /**<; Obtain a random number. */ + CRYPT_HmacSizeCallback hmacSize; /**<; HMAC: Obtain the HMAC length based on the hash algorithm. */ + CRYPT_HmacInitCallback hmacInit; /**<; HMAC: Initialize the context. */ + CRYPT_HmacFreeCallback hmacFree; /**<; HMAC: Release the context. */ + CRYPT_HmacUpdateCallback hmacUpdate; /**<; HMAC: Add input data. */ + CRYPT_HmacFinalCallback hmacFinal; /**<; HMAC: Output results. */ + CRYPT_HmacCallback hmac; /**<; HMAC: Use the complete HMAC function. */ + CRYPT_DigestSizeCallback digestSize; /**<; HASH: Obtain the hash length. */ + CRYPT_DigestInitCallback digestInit; /**<; HASH: Initialize the context. */ + CRYPT_DigestCopyCallback digestCopy; /**<; HASH: Copy the hash context. */ + CRYPT_DigestFreeCallback digestFree; /**<; HASH: Release the context. */ + CRYPT_DigestUpdateCallback digestUpdate; /**<; HASH: Add input data. */ + CRYPT_DigestFinalCallback digestFinal; /**<; HASH: Output hash results. */ + CRYPT_DigestCallback digest; /**<; HASH: Use the complete hash function. */ + CRYPT_EncryptCallback encrypt; /**<; TLS encryption: Provide the encryption capability for the record layer. */ + CRYPT_DecryptCallback decrypt; /**<; TLS decryption: Provide the decryption capability for the record layer. */ +} HITLS_CRYPT_BaseMethod; + +/** + * @brief Callback functions that need to be registered for ECDH + */ +typedef struct { + CRYPT_GenerateEcdhKeyPairCallback generateEcdhKeyPair; /**<; ECDH: Generate a key pair based on the elliptic curve parameters. */ + CRYPT_FreeEcdhKeyCallback freeEcdhKey; /**<; ECDH: Release the elliptic curve key. */ + CRYPT_GetEcdhEncodedPubKeyCallback getEcdhPubKey; /**<; ECDH: Extract public key data. */ + CRYPT_CalcEcdhSharedSecretCallback calcEcdhSharedSecret; /**<; ECDH: Calculate the shared key based on the local key and peer public key data. */ +} HITLS_CRYPT_EcdhMethod; + +/** + * @brief Callback functions that need to be registered for DH + */ +typedef struct { + CRYPT_GenerateDhKeyBySecbitsCallback generateDhKeyBySecbits; /**<; DH: Generate a key pair based on `secbits`. */ + CRYPT_GenerateDhKeyByParamsCallback generateDhKeyByParams; /**<; DH: Generate a key pair based on DH parameters. */ + CRYPT_FreeDhKeyCallback freeDhKey; /**<; DH: Release the key. */ + CRYPT_DHGetParametersCallback getDhParameters; /**<; DH: Leverage the key handle to obtain `p`, `g`, `plen`, and `glen`. */ + CRYPT_GetDhEncodedPubKeyCallback getDhPubKey; /**<; DH: Extract public key data. */ + CRYPT_CalcDhSharedSecretCallback calcDhSharedSecret; /**<; DH: Calculate the shared key based on the local key and peer public key data. */ +} HITLS_CRYPT_DhMethod; + +/** + * @brief Callback functions that need to be registered for KDF + */ +typedef struct { + CRYPT_HkdfExtractCallback hkdfExtract; + CRYPT_HkdfExpandCallback hkdfExpand; +} HITLS_CRYPT_KdfMethod; + +/** + * @brief Register fundamental callback functions + */ +int32_t HITLS_CRYPT_RegisterBaseMethod(HITLS_CRYPT_BaseMethod *userCryptCallBack); + +/** + * @brief Register ECDH callback functions + */ +int32_t HITLS_CRYPT_RegisterEcdhMethod(HITLS_CRYPT_EcdhMethod *userCryptCallBack); + +/** + * @brief Register DH callback functions + */ +int32_t HITLS_CRYPT_RegisterDhMethod(const HITLS_CRYPT_DhMethod *userCryptCallBack); + +/** + * @brief Register HKDF callback functions + */ +int32_t HITLS_CRYPT_RegisterHkdfMethod(HITLS_CRYPT_KdfMethod *userCryptCallBack); +``` + +Registering certificate-related callback functions: + +```c +/** + * @brief Callback functions that must be registered + */ +typedef struct { + CERT_StoreNewCallBack certStoreNew; /**< Create a certificate store. */ + CERT_StoreDupCallBack certStoreDup; /**< Copy the certificate store. */ + CERT_StoreFreeCallBack certStoreFree; /**< Release the certificate store. */ + CERT_StoreCtrlCallBack certStoreCtrl; /**< Control the certificate store. */ + CERT_BuildCertChainCallBack buildCertChain; /**< Build a certificate chain. */ + CERT_VerifyCertChainCallBack verifyCertChain; /**< Verify the certificate chain. */ + + CERT_CertEncodeCallBack certEncode; /**< Encode certificates. */ + CERT_CertParseCallBack certParse; /**< Decode certificates. */ + CERT_CertDupCallBack certDup; /**< Deep-copy certificates. */ + CERT_CertRefCallBack certRef; /**< Increase certificate references by 1. */ + CERT_CertFreeCallBack certFree; /**< Release certificates. */ + CERT_CertCtrlCallBack certCtrl; /**< Control certificates. */ + + CERT_KeyParseCallBack keyParse; /**< Parse keys. */ + CERT_KeyDupCallBack keyDup; /**< Deep-copy keys. */ + CERT_KeyFreeCallBack keyFree; /**< Release keys. */ + CERT_KeyCtrlCallBack keyCtrl; /**< Control keys. */ + CERT_CreateSignCallBack createSign; /**< Create a signature. */ + CERT_VerifySignCallBack verifySign; /**< Verify the signature. */ + CERT_EncryptCallBack encrypt; /**< Encrypt key exchange. */ + CERT_DecryptCallBack decrypt; /**< Decrypt key exchange. */ + + CERT_CheckPrivateKeyCallBack checkPrivateKey; /**< Check whether the certificates and keys match. */ +} HITLS_CERT_MgrMethod; + +/** + * @brief Register certificate-related callback functions + */ +int32_t HITLS_CERT_RegisterMgrMethod(HITLS_CERT_MgrMethod *method); + +/** + * @brief Deregister certificate-related callback functions + */ +void HITLS_CERT_DeinitMgrMethod(void); +``` + +## Time Sequence Interaction of Secure Communication Applications + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/CommunicationApplications.png) + +# Example TLS Client + +## Client Type + +### Certificate Authentication-based Client + +To use the certificate authentication-based client, you need both a trust certificate pool and device certificates. The trust certificate pool specifies which certificate authorities the client trusts. + +#### Loading Trust Certificates + +- The trust certificate pool specifies which certificate authorities the client trusts. It must be configured prior to connection establishment and will then be loaded into the certificate management engine. There are two types of trust certificate pools: + +1. Pool used to verify the peer certificate chain + When using algorithm suites that require server identity verification, the server sends certificates and the certificate chain to the TLS client through handshake messages. If the certificates and certificate chain are not issued by any authority trusted by the client, the client will send a critical alarm and terminate the handshake process. If no trust certificate pool is configured, certificate chain verification will fail, resulting in a TLS handshake failure. + + For the configuration context, users can use the following interface to configure a trust certificate pool for verifying peer certificates: + + ```c + /** + * @brief Set `VerifyStore` for TLS to verify certificates. + */ + int32_t HITLS_CFG_SetVerifyStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); + ``` + + For the link context, users can call `HITLS_SetVerifyStore` to set `VerifyStore`. + + > **NOTE:** Calling `HITLS_CFG_NewXXXConfig` will generate a default certificate pool, `CertStore`. If `VerifyStore` is not set, `CertStore` will be used to verify the certificate chain by default. + +2. Pool used to generate the local certificate chain + As part of the handshake process, the server sends its local certificate to the peer for verification. If the certificate chain for the local certificate is not configured, the server will search the trust certificate pool for the chain and send it to the peer. If the server has sent a certificate chain, it can request the TLS client's certificate to verify the client's identity, which is known as ***two-way authentication***. The TLS client will then send its local certificate and certificate chain to the server through handshake messages. If the local certificate is not found in the configured trust certificate pool or the pool is not configured, the client will send an empty certificate message. Whether the handshake can proceed depends on the server's behavior. + + Users can use the following interface to configure a trust certificate pool for generating the local certificate chain: + + ```c + /** + * @brief Set the chain store used for TLS configuration to construct a certificate chain. + */ + int32_t HITLS_CFG_SetChainStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); + ``` + +- Using device certificates and the corresponding certificate chains: The server or client (in two-way authentication) needs to send device certificates and certificate chains to the peer. In addition to the trust certificate pools, the certificate chains can be added based on the device certificates. When certificate chains are sent to the peer, those that match the device certificates are preferred. You can use the following interfaces to add the desired certificate chains: + + ```c + /** + * @brief Add certificates to the certificate chain being used by **config**. + */ + int32_t HITLS_CFG_AddChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); + ``` + +- Adding certificates to the trust certificate pool: After configuring a trust certificate pool, you can add trust certificates to it through the following interface: + + ```c + /** + * @brief Add certificates to the specified trust certificate pool. + */ + int32_t HITLS_CFG_AddCertToStore(HITLS_Config *config, char *certPath, HITLS_CERT_StoreType storeType); + ``` + + > **NOTE:** This interface can be used to add certificates to the default certificate pool, verification certificate pool, and certificate chain pool. The certificates are transferred using relative paths. + +#### Configuring Client Certificates + +A client certificate is a credential for client identity authentication. In two-way authentication, the TLS client will send its local certificate and certificate chain to the server through handshake messages. If no certificate is found in the client or no certificate is configured by users, the TLS client sends an empty certificate message. Whether the handshake can proceed depends on the server's behavior. + +For the configuration context, users can use the following interfaces to configure client certificates: + +```c +/** + * @brief Add device certificates. Only one certificate of each type can be added. + */ +int32_t HITLS_CFG_SetCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); +/** + * @brief Load the device certificates from a file. + */ +int32_t HITLS_CFG_LoadCertFile(HITLS_Config *config, const uint8_t *file, HITLS_ParseFormat format); +/** + * @brief Read the device certificates from the buffer. + */ +int32_t HITLS_CFG_LoadCertBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); +/** + * @brief Add SM device certificates. Only one certificate of each type can be added. + */ +int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); +``` + +In addition to certificates, you need to configure private keys. Configuring certificates alone will also lead to handshake failure. You can use the following interfaces to configure private keys for certificates in the configuration context: + +```c +/** + * @brief Add private keys for device certificates. Only one private key can be added for each type of certificate. + */ +int32_t HITLS_CFG_SetPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, bool isClone); +/** + * @brief Load the private keys of device certificates from a file. + */ +int32_t HITLS_CFG_LoadKeyFile(HITLS_Config *config, const uint8_t *file, HITLS_ParseFormat format); +/** + * @brief Read the private keys of device certificates from the buffer. + */ +int32_t HITLS_CFG_LoadKeyBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); +/** + * @brief Add SM device certificates. Only one certificate of each type can be added. + */ +int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); +``` + +You can use the following interface to delete all certificates and private keys: + +```c +/** + * @brief Release all loaded certificates and private keys. + */ +int32_t HITLS_CFG_RemoveCertAndKey(HITLS_Config *config); +``` + +In the link contexts that have been generated, you can use the following interface to delete the certificates and private keys: + +```c +/** + * @brief Release all loaded certificates and private keys. + */ +int32_t HITLS_RemoveCertAndKey(HITLS_Ctx *ctx); +``` + +> **NOTE:** Each type of certificate and the corresponding private keys can be configured only once. If you try to configure them again, the previous configuration will be overwritten. Certificates of different types are not affected. For example, if two RSA certificates are configured in sequence, only the last one takes effect. If you configure an RSA certificate and an ECDSA certificate in sequence, both certificates take effect. + +### PSK Authentication-based Client + +The procedure for establishing connections based on PSK negotiation is as follows: + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/LinkSetupProcess.PNG) + +1. If PSK negotiation is used, the client sends a **ClientHello** message containing the PSK algorithm suite to the server, and the server determines whether to use the PSK algorithm suite. +2. After a specific PSK algorithm suite is selected, the server includes **`identity_hint`** in the **ServerKeyExchange** message to indicate which PSK the client should use. +3. After receiving the **ServerKeyExchange** message containing **`identity_hint`**, the client requests the PSK and identity information from the TLS user through callback. +4. Then, the client includes **`identity`** in the **ClientKeyExchange** message to indicate which PSK the server should use. +5. After receiving the **ClientKeyExchange** message containing **`identity`**, the server requests the PSK from the upper-layer (the TLS user) through callback. +6. Then, the two ends generate a pre-master key based on the obtained PSK individually and clear the PSK. The PSK negotiation process is complete. + +Therefore, the client using PSK authentication needs to set a pre-shared key to obtain the following callback information: + +```c +/** + * @brief Obtain the PSK prototype on the client. + */ +typedef uint32_t (*HITLS_PskClientCb)(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, uint32_t maxPskLen); +/** + * @brief Set the PSK callback on the client, which is used to obtain an identity and PSK during PSK negotiation. + */ +int32_t HITLS_CFG_SetPskClientCallback(HITLS_Config *config, HITLS_PskClientCb callback); +``` + +## Sample Code + +### Certificate Authentication-based Client + +See [client.c](../../../testcode/demo/client.c) + +### PSK Authentication-based Client + +Most code of PSK Authentication-based client is the same as that Certificate Authentication-based client, except for the configuration of `HITLS_Config`. + +```c +... +uint32_t ExampleClientCb(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, + uint32_t maxPskLen) +{ + (void)ctx; + (void)hint; + int32_t ret; + const char pskTrans[] = "psk data"; + uint32_t pskTransUsedLen = sizeof(pskTransUsedLen); + if (memcpy_s(identity, maxIdentityLen, "hello", strlen("hello") + 1) != EOK) { + return 0; + } + if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { + return 0; + } + return pskTransUsedLen; +} + + +int main(int32_t argc, char *argv[]) +{ + ... + config = HITLS_CFG_NewTLS12Config(); + if (config == NULL) { + printf("HITLS_CFG_NewTLS12Config failed.\n"); + return -1; + } + uint16_t cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256; + // config cipher suite + if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; + } + // config PSK callbacks + if (HITLS_CFG_SetPskClientCallback(config, (HITLS_PskClientCb)ExampleClientCb) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetPskClientCallback err\n"); + return -1; + } + + ctx = HITLS_New(config); + if (ctx == NULL) { + printf("HITLS_New failed.\n"); + goto exit; + } + + ... +} +``` + +### TLCP Client + +The steps except for the following are the same as those described in "Certificate Authentication-based Client." + +```c +config = HITLS_CFG_NewTLCPConfig(); +if (config == NULL) { + printf("HITLS_CFG_NewTLCPConfig failed.\n"); + return -1; +} +uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; +// Configure the algorithm suite. +if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; +} + +/* Load certificates. This capability needs to be implemented by users. */ +HITLS_CFG_AddCertToStore(config, "rootCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +HITLS_CFG_AddCertToStore(config, "intCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +// In two-way authentication scenarios, load the signature certificate and private key from a file. This capability needs to be implemented by users. +HITLS_CERT_X509 *signCert = LoadCertFromFile("ClientSignCert.pem"); +HITLS_CERT_X509 *signKey = LoadKeyFromFile("ClientSignKey.pem"); +// Load the encryption certificate and private key from a file. +HITLS_CERT_X509 *encCert = LoadCertFromFile("ClientEncCert.pem"); +HITLS_CERT_X509 *encKey = LoadKeyFromFile("ClientEncKey.pem"); +//Add the SM signature certificate and private key. +HITLS_CFG_SetTlcpCertificate(config, signCert, false, false); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, false); +//Add the SM encryption certificate and private key. +HITLS_CFG_SetTlcpCertificate(config, signCert, false, true); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, true); +... +``` + +# Example TLS Server + +## Server Type + +### Certificate Authentication-based Server + +To use the certificate authentication-based TLS server, you need both a trust certificate pool and device certificates. The trust certificate pool specifies which certificate authorities the client trusts. A device certificate is a credential for server identity authentication. The server can determine whether to verify the client identity based on two-way authentication configuration items. + +#### Configuring the Two-Way Authentication Server + +If the server has sent a certificate chain, it can request the TLS client's certificate to verify the client's identity, which is known as two-way authentication. +openHiTLS provides the following configuration items: + +1. Two-way authentication + This function is disabled by default. That is, the server does not verify the client identity by default. You can control the function through the `HITLS_CFG_SetClientVerifySupport` interface. + +```c +/** + * @brief Set whether to verify the client certificate. + This setting has no impact on the client. + The server sends a certificate request. + */ +int32_t HITLS_CFG_SetClientVerifySupport(HITLS_Config *config, bool support); +``` + +2. Acceptance of no client certificates + This setting takes effect only when two-way authentication is enabled. It is disabled by default, meaning that the TLS server must verify the client certificate. If the certificate chain sent by the client is empty or fails verification, the TLS server sends a critical alarm and terminates the handshake. + You can control the function through the `HITLS_CFG_SetNoClientCertSupport` interface. + +```c +/** + * @brief Set whether to accept the scenario without any client certificates. This setting takes effect only when client certificate verification is enabled. + This setting has no impact on the client. + The server checks whether the certificate verification is successful when receiving an empty certificate from the client. The verification fails by default. + */ +int32_t HITLS_CFG_SetNoClientCertSupport(HITLS_Config *config, bool support); +``` + +#### Loading Trust Certificate Pools + +Refer to "Loading Trust Certificates." + +#### Configuring Server Certificates + +If the algorithm suite requires server identity verification, users need to configure the server certificates, certificate chain, and private keys. Refer to "Configuring Client Certificates." + +### PSK Authentication-based Server + +The callback for the PSK authentication-based server to obtain the pre-shared key is slightly different from that used by the client, as shown below: + +```c +/** + * @brief Server PSK negotiation callback +*/ +typedef int32_t (*HITLS_PskFindSessionCb)(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session); +/** + * @brief Set the callback for the PSK authentication-based server, which is used to obtain a PSK during PSK negotiation. + */ +int32_t HITLS_CFG_SetPskServerCallback(HITLS_Config *config, HITLS_PskServerCb callback); +``` + +For details about the remaining procedure, see "PSK Authentication-based Client." + +## Sample Code + +### Certificate Authentication-based Server + +See [server.c](../../../testcode/demo/server.c) + +### ### PSK Authentication-based Server + +Most code of PSK Authentication-based server is the same as that Certificate Authentication-based server, except for the configuration of `HITLS_Config`. + +```c +... + +uint32_t ExampleServerCb(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen) +{ + (void)ctx; + if (identity == NULL || strcmp((const char *)identity, "hello") != 0) { + return 0; + } + const char pskTrans[] = "psk data"; + uint32_t pskTransUsedLen = sizeof(pskTransUsedLen); + if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { + return 0; + } + return pskTransUsedLen; +} + +int main(int32_t argc, char *argv[]) +{ + ... + config = HITLS_CFG_NewTLS12Config(); + if (config == NULL) { + printf("HITLS_CFG_NewTLS12Config failed.\n"); + return -1; + } + uint16_t cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256; + // config cipher suite + if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; + } + // config PSK callback + if (HITLS_CFG_SetPskServerCallback(tlsConfig, (HITLS_PskServerCb)ExampleServerCb) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetPskClientCallback err\n"); + return -1; + } + + ctx = HITLS_New(config); + if (ctx == NULL) { + printf("HITLS_New failed.\n"); + goto exit; + } + + ... +} +``` + +### TLCP Server + +The steps except for the following are the same as those described in "Certificate Authentication-based Server." + +```c +... +config = HITLS_CFG_NewTLCPConfig(); +if (cfg == NULL) { + printf("HITLS_CFG_NewTLCPConfig failed.\n"); + return -1; +} + +uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; +// Configure the algorithm suite. +if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; +} + +if (HITLS_CFG_SetClientVerifySupport(config, ture) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetClientVerifySupport err\n"); + return -1; +} + +/* Load certificates. This capability needs to be implemented by users. */ +HITLS_CFG_AddCertToStore(config, "rootCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +HITLS_CFG_AddCertToStore(config, "intCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +// Load the signature certificate and private key from a file. This capability needs to be implemented by users. +HITLS_CERT_X509 *signCert = LoadCertFromFile("ServerSignCert.pem"); +HITLS_CERT_X509 *signKey = LoadKeyFromFile("ServerSignKey.pem"); +// Load the encryption certificate and private key from a file. +HITLS_CERT_X509 *encCert = LoadCertFromFile("ServerEncCert.pem"); +HITLS_CERT_X509 *encKey = LoadKeyFromFile("ServerEncKey.pem"); +//Add the SM signature certificate and private key. +HITLS_CFG_SetTlcpCertificate(config, signCert, false, false); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, false); +//Add the SM encryption certificate and private key. +HITLS_CFG_SetTlcpCertificate(config, signCert, false, true); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, true); +... +``` + +# Example of TLS Session Key Update + +## Update Type + +### TLS1.2/TLCP or DTLS1.2/TLCP Renegotiation Example + +TLS1.2/TLCP or DTLS1.2/TLCP supports security renegotiation. The renegotiation function enables the client or server to initiate a new negotiation over the same security connection to generate a new key. This function applies to connections that require high confidentiality and transmit a large amount of data. +The security renegotiation procedure is as follows: + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/SecurityRenegotiationProcedure.png) + +> **NOTE:** Users can enter the renegotiation state through the `HITLS_Renegotiate` interface and trigger renegotiation handshakes through the `HITLS_Accept`, `HITLS_Connect`, `HITLS_Write`, or `HITLS_Read` interface. The `HITLS_Accept` and `HITLS_Connect` interfaces are recommended. + +**Client example** + +```c +/* Exchange data at the application layer. */ +const uint8_t sndBuf[] = "Hi, this is client\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +/* The client enters the renegotiation state. */ +ret = HITLS_Renegotiate(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Renegotiate error:error code:%d\n", ret); + goto exit; +} +/* The client initiates a handshake, and the server processes the handshake through the `HITLS_Read` interface. */ +ret = HITLS_Connect(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Connect failed, ret = 0x%x.\n", ret); + goto exit; +} +/* The renegotiation is complete, and the data exchange at the application layer proceeds. */ +``` + +**Server example** + +```c +/* Exchange data at the application layer. */ +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +const uint8_t sndBuf[] = "Hi, this is server\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +/* The server enters the renegotiation state. */ +ret = HITLS_Renegotiate(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Renegotiate error:error code:%d\n", ret); + goto exit; +} +/* The server initiates a handshake, and the client processes the handshake through the `HITLS_Read` interface. */ +ret = HITLS_Accept(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Accept failed, ret = 0x%x.\n", ret); + goto exit; +} +/* The renegotiation is complete, and the data exchange at the application layer proceeds. */ +``` + +### Example of TLS1.3 Key Update + +TLS1.3 supports key update after connection establishment. The involved functions are as follows: + +```c +/** + * @brief Set the `KeyUpdate` type and send a `KeyUpdate` message to the peer. + */ +int32_t HITLS_KeyUpdate(HITLS_Ctx *ctx, uint32_t updateType); +``` + +The following `KeyUpdate` types are supported: + +```c +The HITLS_UPDATE_NOT_REQUESTED = 0, // The peer does not have to reply to the `KeyUpdate` message. +HITLS_UPDATE_REQUESTED = 1, // The peer must reply to the `KeyUpdate` message. +``` + +**Client example** + +```c +/* Exchange data at the application layer. */ +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +const uint8_t sndBuf[] = "Hi, this is server\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +/* The client initiates a `KeyUpdate` message that does not require replies from the peer. The peer processes the message through the `HITLS_Read` interface. */ +ret = HITLS_KeyUpdate(ctx, HITLS_UPDATE_NOT_REQUESTED); +if (ret != HITLS_SUCCESS) { + printf("HITLS_KeyUpdate error:error code:%d\n", ret); + goto exit; +} +/* The key update process is complete. */ +``` + +**Server example** + +```c +/* Exchange data at the application layer. */ +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +const uint8_t sndBuf[] = "Hi, this is server\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +/* The server initiates a `KeyUpdate` message that requires replies from the peer. The peer processes the message through the `HITLS_Read` interface and returns replies to the `KeyUpdate` message. */ +ret = HITLS_KeyUpdate(ctx, HITLS_UPDATE_REQUESTED); +if (ret != HITLS_SUCCESS) { + printf("HITLS_KeyUpdate error:error code:%d\n", ret); + goto exit; +} +/* The `HITLS_Read` interface receives the peer's replies to the `KeyUpdate` message. */ +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +/* The key update process is complete. */ +``` + diff --git a/docs/en/5_Developer Guide/3_API Reference.md b/docs/en/5_Developer Guide/3_API Reference.md new file mode 100644 index 00000000..5f195f53 --- /dev/null +++ b/docs/en/5_Developer Guide/3_API Reference.md @@ -0,0 +1 @@ +For details about the API reference, [see](https://apidocen.openhitls.net/modules.html). \ No newline at end of file diff --git a/docs/en/6_Appendix/1_Terms.md b/docs/en/6_Appendix/1_Terms.md new file mode 100644 index 00000000..35c68f1c --- /dev/null +++ b/docs/en/6_Appendix/1_Terms.md @@ -0,0 +1,52 @@ +|Acronym/Abbreviation|Full Name|Description| +|-|-|:-:| +|/|Symmetric Encryption|An algorithm that uses the same key for encryption and decryption, which is also called shared key cryptography.| +|/|Public Key Encryption|An algorithm that uses a pair of public and private keys for encryption and decryption. The public key is used for encryption, and the private key is used for decryption. Common public key encryption algorithms include RSA and ECC.| +|/|Hash Function|The hash function accepts an input and maps it to a fixed-length output. The hash function features anti-collision and irreversibility. Common hash functions include MD5, SHA-1, and SHA-256.| +|/|Digital Signature|A private key is used to encrypt the message and verify its source and integrity. A public key can be used to verify the digital signature.| +|/|Key Exchange|A secure communication channel is provided for the server and client so that they can securely share keys for symmetric encryption.| +|/|Replay Attack|An attacker repeats or delays sending authenticated messages during communication to deceive or damage communication integrity.| +|/|Key Length|An indicator used to measure the cryptographic algorithm strength. Generally, the longer the key, the more secure the algorithm.| +|/|TLS Handshake|A handshake process between the client and server before TLS communication starts. The handshake process includes encryption algorithm negotiation, identity authentication, session key generation, and other steps.| +|/|TLS Certificate|A digital certificate used to verify the identities of the server and client during a TLS handshake. The server usually has a public key certificate, and the client can verify the authenticity and credibility of the certificate.| +|/|Key Exchange Algorithm|An algorithm used during a TLS handshake to securely exchange cryptographic keys between the client and server. Common key exchange algorithms include RSA, Diffie-Hellman, and Elliptic Curve Diffie-Hellman (ECDH).| +|/|Block Cipher|A symmetric encryption algorithm used to encrypt and decrypt data in TLS. Common block cipher algorithms include Advanced Encryption Standard (AES) and Triple Data Encryption Standard (3DES).| +|/|Stream Cipher|A symmetric encryption algorithm used to encrypt and decrypt data in TLS. The input and keystream conduct an exclusive OR (XOR) operation to generate a ciphertext stream. Common stream cipher algorithms include RC4 and ChaCha20.| +|/|TLS Session|A secure session established between the client and server after the TLS handshake is complete. It is used to encrypt and protect communication data. Sessions can be reused in multiple TLS connections to improve performance.| +|/|Man-in-the-Middle Attack|An attack mode in which an attacker inserts itself as a man-in-the-middle in TLS communication and steals or tampers with the communication data.| +|/|Man-in-the-Middle Attack|During a TLS handshake, the client and server negotiate security parameters such as the encryption algorithm, key exchange algorithm, and certificate authentication mode.| +|/|Secure Renegotiation|After a TLS handshake is complete, the client or server initiates a handshake process again to negotiate a new key.| +|/|Server Name Indication|An extended TLS protocol. The client specifies the name of the host to be connected to the server in the CLIENTHELLO packet.| +|/|Application Layer Protocol Negotiation|An extended TLS protocol. The client and server negotiate the application layer protocol when negotiating the TLS protocol.| +|/|Session Resumption|After a handshake is complete, the TLS session information is saved. In the second handshake, the first session information is used to restore the link.| +|AES|Advanced Encryption Standard|A symmetric encryption algorithm that is widely used in fields such as data encryption and network security. The key length of the AES algorithm can be 128 bits, 192 bits, or 256 bits.| +|Arm|Advanced RISC Machines|A processor architecture that is widely used in fields such as mobile devices and embedded systems. The Arm processor features low power consumption and high performance.| +|Curl|Curl|An open-source network transmission tool that supports multiple protocols, such as HTTP, FTP, and SMTP. It is widely used in fields such as web development and testing.| +|DH|Diffie-Hellman|A key exchange algorithm that is widely used in fields such as network security and VPN. The key length of the DH algorithm can be 1024 bits, 2048 bits, or 4096 bits.| +|DRBG|Deterministic Random Byte Generator|A pseudo-random number generator used to generate random numbers such as keys and initialization vectors in encryption algorithms.| +|DSA|Digital Signature Algorithm|A digital signature algorithm that is widely used in fields such as digital signature and identity authentication. The key length of the DSA algorithm can be 1024 bits, 2048 bits, or 3072 bits.| +|DTLS|Datagram Transport Layer Security|A transport layer security protocol for data packets. It is used to protect the security and integrity of data packet communication and is widely used in real-time communication scenarios such as VoIP and video conferences.| +|EC|Elliptic Curve|An asymmetric encryption algorithm based on the elliptic curve mathematical theory. It is widely used in fields such as digital signature and key exchange.| +|HKDF|HMAC-based Extract-and-Expand Key Derivation Function|A key derivation function used to derive multiple subkeys from a long term key. The HKDF algorithm is based on the HMAC algorithm.| +|HMAC|Hash-based Message Authentication Code|A message authentication code used to ensure the integrity and authenticity of messages. The HMAC algorithm is based on the hash algorithm and key.| +|Java|Java|A cross-platform programming language that is widely used in fields such as web development and mobile applications. Java is object-oriented and secure.| +|MD5|Message-Digest Algorithm 5|A hash algorithm that is widely used in fields such as digital signature and message authentication. The key length of the MD5 algorithm is 128 bits.| +|Nginx|Engine X|A high-performance web server and reverse proxy server, which is widely used in fields such as the Internet and mobile applications. Nginx features high concurrency and low memory consumption.| +|PBKDF2|Password-Based Key Derivation Function 2|A key derivation function used to derive keys in encryption algorithms from user passwords.| +|Python|Python|A high-level programming language that is widely used in fields such as data analysis and artificial intelligence. Python is simple and easy to read.| +|QUIC|Quick UDP Internet Connections|A new network transmission protocol based on UDP, which is widely used in fields such as web pages and mobile applications. The QUIC protocol supports features such as encryption, multiplexing, and 0-RTT.| +|RAM|Random Access Memory|A computer internal memory used to temporarily store data and programs. RAM is a volatile memory. The stored data will be lost after a power failure.| +|ROM|Read-Only Memory|A computer internal memory used to store solidified programs and data. ROM is a non-volatile memory. The stored data will not be lost after a power failure.| +|RSA|Rivest-Shamir-Adleman|An asymmetric encryption algorithm that is widely used in fields such as digital signature and key exchange. The key length of the RSA algorithm can be 1024 bits, 2048 bits, or 4096 bits.| +|SCRYPT|Scrypt|A key derivation function used to derive multiple subkeys from a long term key. The SCRYPT algorithm is based on the PBKDF2 algorithm.| +|SDF|Security Domain Function|A standard cryptographic security interface that defines the communication protocol and data format between cryptographic devices (such as cryptographic chip cards) and user devices, including aspects such as key management, authentication, and data transmission. Implementation of the SDF interface specifications can ensure security and reliability of cryptographic devices, and is mainly applied to the financial field to ensure security of payment cards such as a bank card.| +|SHA2|Secure Hash Algorithm 2|A hash algorithm that is widely used in fields such as digital signature and message authentication. The SHA2 algorithm includes multiple variants, such as SHA-224, SHA-256, SHA-384 and SHA-512.| +|SHA3|Secure Hash Algorithm 3|A hash algorithm. It is the successor of the SHA2 algorithm and is widely used in fields such as digital signature and message authentication. The SHA3 algorithm includes multiple variants, such as SHA3-224, SHA3-256, SHA3-384 and SHA3-512.| +|SKF|Security Domain Function|A standard cryptographic security interface that defines the communication protocol and data format between cryptographic devices (such as cryptographic chip cards) and user devices, including aspects such as key management, authentication, and data transmission. Implementation of the SKF interface specifications can ensure security and reliability of cryptographic devices, and is applied to secure communication between cryptographic devices (such as cryptographic chip cards) and user devices, including aspects such as key management, authentication, and data transmission.| +|SM2|ShangMi-2|An asymmetric encryption algorithm, which is one of the encryption algorithms recommended by China. The key length of the SM2 algorithm is 256 bits.| +|SM3|ShangMi-3|A hash algorithm recommended by China. The output length of the SM3 algorithm is 256 bits.| +|SM4|ShangMi-4|A symmetric encryption algorithm, which is one of the encryption algorithms recommended by China. The key length of the SM4 algorithm is 128 bits.| +|TLCP|Transport Layer Cryptography Protocol|A transport layer cryptography protocol that is used to protect the security and integrity of network communication. It is widely used in secure communication scenarios such as web pages and emails in China.| +|TLS|Transport Layer Security|A transport layer security protocol that is used to protect the security and integrity of network communication. It is widely used in secure communication scenarios such as web pages and emails.| +|X.509|T-REC-X.509|A digital certificate standard used to prove the validity of public keys and the authenticity of identities. An X.509 certificate contains information such as the public key, certificate issuer, and validity period.| +|x86|Intel 80x86|A processor architecture that is widely used in fields such as personal computers and servers. The x86 processor features high performance and compatibility.| diff --git a/docs/en/6_Appendix/2_Change History.md b/docs/en/6_Appendix/2_Change History.md new file mode 100644 index 00000000..af3f967c --- /dev/null +++ b/docs/en/6_Appendix/2_Change History.md @@ -0,0 +1,5 @@ +# Change History + +| Date | Issue | Change Description | +| ---------- | ----------------- | -------------------------------- | +| 2024-01-25| The first release of openHiTLS.| First release of version alpha.| diff --git a/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/CommunicationApplications.png b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/CommunicationApplications.png new file mode 100644 index 00000000..6166181c Binary files /dev/null and b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/CommunicationApplications.png differ diff --git a/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/LinkSetupProcess.png b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/LinkSetupProcess.png new file mode 100644 index 00000000..ee50910f Binary files /dev/null and b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/LinkSetupProcess.png differ diff --git a/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/SecurityRenegotiationProcedure.png b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/SecurityRenegotiationProcedure.png new file mode 100644 index 00000000..05a0ce57 Binary files /dev/null and b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/SecurityRenegotiationProcedure.png differ diff --git a/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/TheFramework.png b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/TheFramework.png new file mode 100644 index 00000000..6b47cfbd Binary files /dev/null and b/docs/en/images/Developer Guide/Secure Communication Application Development Guide_figures/TheFramework.png differ diff --git a/docs/en/images/User Guide/Test Guide_figures/TestCaseExecutionProcess.png b/docs/en/images/User Guide/Test Guide_figures/TestCaseExecutionProcess.png new file mode 100644 index 00000000..29473154 Binary files /dev/null and b/docs/en/images/User Guide/Test Guide_figures/TestCaseExecutionProcess.png differ diff --git a/docs/en/images/User Guide/Test Guide_figures/TestFrameworkDescription.png b/docs/en/images/User Guide/Test Guide_figures/TestFrameworkDescription.png new file mode 100644 index 00000000..cf2b34c3 Binary files /dev/null and b/docs/en/images/User Guide/Test Guide_figures/TestFrameworkDescription.png differ diff --git a/docs/index/index.md b/docs/index/index.md new file mode 100644 index 00000000..28ea2ae1 --- /dev/null +++ b/docs/index/index.md @@ -0,0 +1,16 @@ + + +| 序号 | 中文文档 | 英文文档 | +| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 1 | [发行声明](../zh/1_发行声明.md) | [Release Notes](../en/1_Release%20Notes.md) | +| 2 | [关键特性](../zh/2_关键特性.md) | [Key Features](../en/2_Key%20Features.md) | +| 3 | [快速入门](../zh/3_快速入门.md) | [Quick Start](../en/3_Quick%20Start.md) | +| 4 | [构建及安装指导](../zh/4_使用指南/1_构建及安装指导.md) | [Build and Installation Guide](../en/4_User%20Guide/1_Build%20and%20Installation%20Guide.md) | +| 5 | [测试指南](../zh/4_使用指南/2_测试指南.md) | [Test Guide](../en/4_User%20Guide/2_Test%20Guide.md) | +| 6 | [版本升级指导](../zh/4_使用指南/3_版本升级指导.md) | [Upgrade Guide](../en/4_User%20Guide/3_Upgrade%20Guid.md) | +| 7 | [加密完保应用开发指南](../zh/5_开发指南/1_加密完保应用开发指南.md) | [Encryption and Integrity Protection Application Development Guide](../en/5_Developer%20Guide/1_Encryption%20and%20Integrity%20Protection%20Application%20Development%20Guide.md) | +| 8 | [安全通信应用开发指南](../zh/5_开发指南/2_安全通信应用开发指南.md) | [Secure Communication Application Development Guide](../en/5_Developer%20Guide/2_Secure%20Communication%20Application%20Development%20Guide.md) | +| 9 | [API参考](../zh/5_开发指南/3_API参考.md) | [API Reference](../en/5_Developer%20Guide/3_API%20Reference.md) | +| 10 | [术语列表](../zh/6_附录/1_术语列表.md) | [Terms](../en/6_Appendix/1_Terms.md) | +| 11 | [修订记录](../zh/6_附录/2_修订记录.md) | [Change History](../en/6_Appendix/2_Change%20History.md) | + diff --git a/docs/zh/1_发行声明.md b/docs/zh/1_发行声明.md new file mode 100644 index 00000000..52a7ba71 --- /dev/null +++ b/docs/zh/1_发行声明.md @@ -0,0 +1,14 @@ +# 配套关系 + +版本: openHiTLS 0.1.0 alpha1 + +# 新特性 + +**openHiTLS** + +* 支持SM2、SM3、SM4商密算法功能 +* 支持(D)TLS、TLCP安全传输协议功能 +* 支持特性按需构建、满足用户RAM/ROM小型化诉求 +* 支持基于ARM、x86的指令级商密算法性能优化,满足商密算法高性能诉求 + + diff --git a/docs/zh/2_关键特性.md b/docs/zh/2_关键特性.md new file mode 100644 index 00000000..193d5c52 --- /dev/null +++ b/docs/zh/2_关键特性.md @@ -0,0 +1,21 @@ +# 产品概述 + +openHiTLS的目标是提供高效敏捷的全场景密码学套件,通过模块分层特性分级的弹性架构,实现特性按需选择和扩展,支撑全场景应用满足RAM/ROM内存、计算性能、特性满足度等不同需求;当前已支持密码算法功能以及TLS、DTLS、TLCP安全通信协议功能,商密算法支持基于ARM 指令的性能优化,更多特性待规划、欢迎参与共建。 + +# 特性介绍 + +1. 已支持的特性 + +1.1. 关键功能特性: + +* 传输层安全协议:TLS1.2、TLS1.3、DTLS1.2、TLCP1.1; +* 加解密密码算法:AES、SM4、Chacha20、RSA、(EC)DSA、(EC)DH、SM2、DRBG、HKDF、SCRYPT、PBKDF2、SHA2、SHA3、MD5、SM3、HMAC、X509。 + +1.2. 非功能性特性: + +* 弹性架构:支持模块和特性按需选择和构建功能 +* 性能优化:支持基于ARM、x86指令的性能优化的商密算法功能 +* 可维可测性:支持日志和错误栈功能 + + + diff --git a/docs/zh/3_快速入门.md b/docs/zh/3_快速入门.md new file mode 100644 index 00000000..33b2da47 --- /dev/null +++ b/docs/zh/3_快速入门.md @@ -0,0 +1,38 @@ +# openHiTLS快速入门 + +欢迎学习openHiTLS教程。此教程将会指导您如何安装、集成和使用openHiTLS。 + +## 什么是openHiTLS + +openHiTLS是一款构建密码学安全能力的C/C++库,提供符合公开标准的密码学算法、TLS协议栈。 + +## 安装openHiTLS + +1. 下载相关代码 + openHiTLS下载地址:https://gitee.com/openhitls/openhitls.git + libboundscheck下载地址:https://gitee.com/openeuler/libboundscheck.git + 说明:需要将libboundscheck下载至openHiTLS/platform/Secure_C目录 +2. 构建安装,在openHiTLS根路径下执行以下命令: + +``` +mkdir build +cd build +cmake .. +make && make install +``` + +## 在您的C/C++项目中集成openHiTLS + +1. 按照openHiTLS的API手册,在您的项目代码中调用openHiTLS提供的接口。 +2. 将openHiTLS的头文件和库路径加入到您的项目依赖中,以gcc编译器为例,如下: + +``` +# 使用-I指定openHiTLS头文件所在路径,使用-L指定openHiTLS动态库所在路径 +gcc application.c -lhitls_crypto -lhitls_tls -lhitls_bsl -lboundscheck -I -L +``` + +## 开始使用openHiTLS + +通过以上方式,便可以使用openHiTLS提供的安全能力了。 + + diff --git a/docs/zh/4_使用指南/1_构建及安装指导.md b/docs/zh/4_使用指南/1_构建及安装指导.md new file mode 100644 index 00000000..12432c00 --- /dev/null +++ b/docs/zh/4_使用指南/1_构建及安装指导.md @@ -0,0 +1,172 @@ +# 构建及安装指导 + +## 1. 准备构建环境 + +检查系统中构建工具是否已安装,并能正常使用。 + +| **名称** | **推荐版本** | **说明** | +| -------- | ------------ | -------- | +| Gcc | >=7.3.0 | Linux | +| Python | >=3.5 | Linux | +| CMake | >=3.16 | Linux | +| Sctp | 无版本限制 | Linux | + +注:DTLS特性依赖sctp,默认sctp是关闭,如需开启,需要提前预装sctp依赖。 +## 2. 准备源码 + +方式一 + +1. 下载openHiTLS代码,含业务代码、构建脚本、测试代码 + 仓库地址:https://gitcode.com/openhitls/openhitls.git +2. openHiTLS依赖于libboundscheck库,构建之前需将其下载至openHiTLS/platform/Secure_C + 仓库地址:https://gitcode.com/openeuler/libboundscheck.git + +方式二 + +使用git submodule的方式下载,可以直接下载源码和依赖的Securec库,下载命令 + +``` +git clone --recurse-submodules https://gitcode.com/openhitls/openhitls.git +``` + +## 3. openHiTLS构建及安装 + +进入openHiTLS后代码目录结构如下: + +``` +└── openHiTLS + ├── bsl + ├── CMakeLists.txt + ├── config + ├── configure.py + ├── crypto + ├── docs + ├── include + ├── LICENSE + ├── platform + ├── README-en.md + ├── README.md + ├── script + ├── testcode + ├── tls + └── x509 +``` + +其中: + +- bsl:存放基础功能相关代码; +- CMakeLists.txt:构建入口文件 +- configure.py:提供构建配置命令行功能; +- config、script:存放构建相关脚本; +- crypto:存放密码学算法能力相关代码; +- platform:存放其他依赖的代码; +- testcode:存放测试工程类代码。 +- tls:存放安全传输相关代码; +- x509:存放x509证书功能相关代码; + +**源码构建调用CMake进行构建,具体方法下面介绍。** + +### 3.1 CMake构建 + +openHiTLS提供CMake构建方式,可通过configure.py进行配置,之后建议新建build目录用于存放构建过程中的产生的临时文件,进入build目录使用“cmake .. && make”的方式执行构建。configure.py的配置可以通过`python3 ./configure.py –help`查询,相关参数如下: + +| **脚本参数** | **参数说明** | **执行方式** | +| ------------- | ------------ | ---------------- | +|--help |显示脚本的帮助信息|python3 configure.py --help| +|-m |生成moudules.cmake文件|python3 configure.py -m| +|--build_dir |指定编译的临时目录|python3 configure.py --build_dir build| +|--output_dir |指定编译目标的输出路径|python3 configure.py --output_dir output| +|--feature_config|指定编译特性配置文件|python3 configure.py --feature_config path/to/xxx.json| +|--compile_config|指定编译参数配置文件|python3 configure.py --compile_config path/to/xxx.json| +|--enable|指定构建特性|python3 configure.py --enable hitls_crypto hitls_tls hitls_pse| +|--disable|关闭构建特性|python3 configure.py --disable sal_thread | +|--enable-sctp|开启sctp编译, DTLS依赖sctp|python3 configure.py --enable-sctp| +|--asm_type|汇编类型|python3 configure.py --lib_type static --asm_type armv8| +|--asm|指定汇编特性,需要与`asm_type`同时使用|python3 configure.py --lib_type static --asm_type armv8 --asm sha2| +|--endian|大小端构建|python3 configure.py --endian little| +|--system|系统类型,当前仅支持`linux`,用于`sal_xxx`相关特性|python3 configure.py --system linux| +|--bits|系统位数,使用大数需指定此参数,`32\|64`|python3 configure.py --bits 64| +|--lib_type|选择构建静态、动态库或者object|python3 configure.py --lib_type static| +|--add_options|添加编译选项|python3 configure.py --add_options "-O0 -g3"| +|--del_options|移除编译选项|python3 configure.py --del_options"-O2"| +|--add_link_flags|添加链接选项|python3 configure.py --add_link_flags="-pie"| +|--del_link_flags|移除链接选项|python3 configure.py --del_options="-O2 -Werror"| + +configure.py脚本会直接基于顶层的compile.json和feature.json配置文件修改已有配置。 + +CMake构建的总体执行步骤如下: + +``` +cd openHiTLS +mkdir -p ./build +cd ./build +python3 ../configure.py #修改配置,详见3.1.1节 +cmake .. +make -j +``` + +构建结果会输出在openHiTLS/build目录下。 + +#### 3.1.1 常用的配置命令 + +```bash +# 关闭某个特性 +python3 ../configure.py --disable [feature]::[module] + +# 开启某个特性 +python3 ../configure.py --enable [feature]::[module] + +# 开启sctp +python3 ../configure.py --enable-sctp + +# 默认配置,当文件不存在时,则生成文件,否则没有任何动作 +python3 ../configure.py -m + +# 增删编译选项 +# 注意:如果原本存在该编译选项,想要更新,必须先用--del_options再用--add_options添加,如本例子中,原本优化是O0要改为O2 +python3 ../configure.py --del_options="-O2 -D_FORTIFY_SOURCE=2" --add_options="-O0 -g" + +# 增删链接选项 +python3 ../configure.py --add_link_flags="-lxxx" --del_link_flags="-lxxx" + +# 只生成静态库 +python3 ../configure.py --lib_type static + +# 只生成动态库 +python3 ../configure.py --lib_type shared + +# 只生成object文件 +python3 ../configure.py --lib_type object + +# 动态库、静态库、object均生成 +python3 ../configure.py --lib_type shared static object +``` + +#### 3.1.2 交叉编译 + +交叉编译openHiTLS需要使用CMake的-DCMAKE_TOOLCHAIN_FILE参数将交叉编译配置传入,如下: + +```bash +cd openHiTLS +mkdir -p ./build +cd ./build +python3 ../configure.py --bits=64 --system=linux #其他配置 详见3.1.1节 +cmake -DCMAKE_TOOLCHAIN_FILE=xxx.toolchain.cmake .. # xxx.toolchain.cmake需用户编写 +make -j +``` + +### 3.2 构建结果安装 + +安装openHiTLS的构建结果只需要输入如下命令: + +``` +make install +``` + +头文件默认安装至/usr/local/include,库文件默认安装至/usr/local/lib。若需要自定义安装路径,在cmake配置阶段使用如下命令: + +``` +cmake -DCMAKE_INSTALL_PREFIX=<自定义路径> .. +``` + + diff --git a/docs/zh/4_使用指南/2_测试指南.md b/docs/zh/4_使用指南/2_测试指南.md new file mode 100644 index 00000000..25152e45 --- /dev/null +++ b/docs/zh/4_使用指南/2_测试指南.md @@ -0,0 +1,123 @@ +测试工程依赖编译源码,参考《构建及安装指导》准备构建源码编译依赖的环境等,确保源码能够得到正确编译。 + +## 1. 准备测试环境 + +| **名称** | **推荐版本** | **说明** | +| -------- | ------------ | --------------------------------------------------- | +| Gcc | >=7.3.0 | Linux | +| Python | >=3.5 | Linux | +| CMake | >=3.16 | Linux | +| Sctp | 无版本限制 | Linux | + +## 2. 测试代码目录结构 + +``` +./testcode/ +├── CMakeLists.txt +├── common +│   ├── execute_base.c +│   └── execute_test.c +├── demo +├── framework +│   ├── crypto +│   ├── gen_test +│   ├── include +│   ├── process +│   ├── stub +│   └── tls +├── output +├── script +│   ├── all_mini_test.sh +│   ├── build_hitls.sh +│   ├── build_sdv.sh +│   ├── execute_sdv.sh +│   └── mini_build_test.sh +├── sdv +│   ├── CMakeLists.txt +│   ├── log +│   ├── report +│   └── testcase +└── testdata + ├── cert + └── tls +``` + +其中: + +- common:公共类测试框架代码 +- demo:openHiTLS功能测试demo +- framework:openHiTLS测试用例的框架代码 +- output:用例测试结果及过程文件输出目录 +- script:测试脚本类代码目录 +- sdv:openHiTLS功能场景测试用例代码 +- testdata:存放测试类数据等 + +## 3. 功能测试执行指导 + +### 3.1 测试框架说明 + +使用社区开发的测试框架,提供公共的配置和方法以便社区开发者进行测试代码的编写和执行。一个测试单元由function文件(.c)和data(.data)文件组成,分别保存测试函数和测试数据。 + +![image](../images/User%20Guide/Test%20Guide_figures/TestFrameworkDescription.png) + +### 3.2 脚本参数说明 + +| **命令** | **含义** | +| --------------------------- | ------------------------------------------------------------ | +| bash build_hitls.sh | 编译全量源码。 | +| bash build_sdv.sh | 编译全量测试代码。 | +| bash execute_sdv.sh | 执行测试用例。 | + +- build_hitls.sh脚本参数说明 + +| **脚本参数** |**执行方式** | **参数说明** | +| -------- | ------------ | --------------------------------------------------- | +| gcov | bash build_hitls.sh gcov |开启获取覆盖率能力。 | +| debug | bash build_hitls.sh debug |开启debug调试能力。 | +| asan | bash build_hitls.sh asan |开启内存监测能力。 | + +- build_sdv.sh脚本参数说明 + +| **脚本参数** | **执行方式** | **参数说明** | +| -------- | ------------ | --------------------------------------------------- | +| --help或-h | bash build_sdv.sh --help |获取帮助信息。 | +| no-crypto | bash build_sdv.sh no-crypto |裁剪掉crypto模块用例。 | +| no-bsl | bash build_sdv.sh no-bsl | 裁剪掉bsl模块用例。 | +| no-tls | bash build_sdv.sh no-tls | 裁剪掉tls模块用例。 | +| no-x509 | bash build_sdv.sh no-x509 | 裁剪掉x509模块用例。 | +| verbose |bash build_sdv.sh verbose |显示构建过程详细信息。 | +| gcov | bash build_sdv.sh gcov | 开启获取覆盖率能力。 | +| asan | bash build_sdv.sh asan | 开启内存监测能力 。 | +| big-endian |bash build_sdv.sh big-endian | 大端环境编译选项。 | +| run-tests | bash build_sdv.sh run-tests=xxx1xxx2xxx3 | 编译指定测试套。 | + +- execute_sdv.sh脚本参数说明 + +| **脚本参数** | **执行方式**| **参数说明** | +| -------- | ------------ | --------------------------------------------------- | +| \ | bash execute_sdv.sh test_suites_xxx ... | 执行指定文件下的所有用例。 | +| \ | bash execute_sdv.sh UT_CRYPTO_xxx SDV_CRYPTO_xxx ... |执行指定用例名用例。 | + +备注:脚本参数可以以组合形式传给脚本,例如: + +- 默认方式构建源码:bash build_hitls.sh +- 源码构建过程中开启asan、debug及覆盖率:bash build_hitls.sh asan gcov debug +- 测试代码构建过程中开启asan、覆盖率及显示构建详情:bash build_sdv.sh asan gcov verbose +- 默认方式构建源码:bash build_hitls.sh +- 默认方式执行全量用例:bash execute_sdv.sh +- 执行指定的测试集合:bash execute_sdv.sh test_suites_xxx1 test_suites_xxx2 + +### 3.3 用例执行流程 + +测试工程主要依赖以下脚本: + +- **build_hitls.sh**: 一键式构建源码脚本 +- **build_sdv.sh** : 一键式构建测试用例脚本 +- **execute_sdv.sh** : 一键式执行用例脚本 + ![image](../images/User%20Guide/Test%20Guide_figures/TestCaseExecutionProcess.png) + +### 3.4 用例结果查看 + +测试完成后,可进入output/log目录查看用例执行结果。如果发现社区仓库问题,可先在仓库issue查看是否有问题单,如果不存在问题单则提单跟踪。 + + diff --git a/docs/zh/4_使用指南/3_版本升级指导.md b/docs/zh/4_使用指南/3_版本升级指导.md new file mode 100644 index 00000000..d2396385 --- /dev/null +++ b/docs/zh/4_使用指南/3_版本升级指导.md @@ -0,0 +1,5 @@ +# 版本升级指导 + +当前openHiTLS版本为首个Alpha版本,详细构建及使用方式参考[构建及安装指导](./1_构建及安装指导.md)。 + + diff --git a/docs/zh/5_开发指南/1_加密完保应用开发指南.md b/docs/zh/5_开发指南/1_加密完保应用开发指南.md new file mode 100644 index 00000000..6e1bb7e7 --- /dev/null +++ b/docs/zh/5_开发指南/1_加密完保应用开发指南.md @@ -0,0 +1,735 @@ +# 密码算法功能介绍 + +openHiTLS基于密码算法标准提供了加解密、签名验证、哈希等功能。主要功能接口在算法模块中提供,在openHiTLS系统内为证书和TLS模块提供默认密码算法能力。 + +## 功能规格 + +* 加密解密:支持SM4、AES、CHACHA20对称加解密功能;支持SM2, RSA非对称加解密功能。 +* 签名验证:支持SM2、DSA、ED25519、RSA、ECDSA签名验证功能。 +* 密钥交换:支持SM2、X25519、ECDH密钥交换功能。 +* 密钥派生:支持PBKDF2、HKDF、SCRYPT、KDFTLS12密钥派生功能。 +* 完整性算法:支持HMAC 完整性保护功能。 +* 哈希计算:支持SM3、SHA2、SHA3、MD5、SHA1摘要计算功能。 +* 随机数生成:支持DRBG-HASH, DRBG-CTR, DRBG-HMAC随机数功能。 + +# 加解密示例 + +## 对称加解密 + +对称加解密功能基于对称算法提供了加解密能力,如下以SM4-CBC算法为例,给出了对称加解密的示例代码,供适配参考。 + +## 示例代码 + +```c +#include +#include +#include +#include +#include "crypt_eal_cipher.h" // 对称加解密接口头文件 +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // 算法id列表 +#include "crypt_errno.h" // 错误码列表 + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // 获取错误发生的文件名和行数 + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; // 注册的内存分配接口 + +int main(void) +{ + uint8_t data[10] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x1c, 0x14}; + uint8_t iv[16] = {0}; + uint8_t key[16] = {0}; + uint32_t dataLen = sizeof(data); + uint8_t cipherText[100]; + uint8_t plainText[100]; + uint32_t outTotalLen = 0; + uint32_t outLen = sizeof(cipherText); + uint32_t cipherTextLen; + int32_t ret; + + printf("plain text to be encrypted: "); // 输出明文 + for (uint32_t i = 0; i < dataLen; i++) { + printf("%02x", data[i]); + } + printf("\n"); + + // 初始化错误码模块 + BSL_ERR_Init(); + + // 调用算法API接口之前需要调用BSL_SAL_RegMemCallback函数注册malloc和free函数。该步骤仅需执行一次。 + // 如果未注册并且默认能力没有被裁剪,使用默认linux实现 + BSL_SAL_RegMemCallback(&cb); + + // 创建上下文 + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC); + if (ctx == NULL) { + PrintLastError(); + BSL_ERR_DeInit(); + return 1; + } + // 初始化, 最后入参true为加密,false为解密 + ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); // 输出错误码,可借助错误码在crypt_errno.h中找到对应的错误信息 + PrintLastError(); + goto exit; + } + // 设置填充模式。 + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 输入待计算数据,该接口可以调用多次。此处outLen输入为cipherText长度,输出为处理的数据量 + ret = CRYPT_EAL_CipherUpdate(ctx, data, dataLen, cipherText, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; // 目前已处理数据量 + outLen = sizeof(cipherText) - outTotalLen; // cipherText剩余空间 + + // 填充并处理最后一段数据 + ret = CRYPT_EAL_CipherFinal(ctx, cipherText + outTotalLen, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + printf("cipher text value is: "); // 输出密文 + + for (uint32_t i = 0; i < outTotalLen; i++) { + printf("%02x", cipherText[i]); + } + printf("\n"); + + // 开始解密流程 + cipherTextLen = outTotalLen; + outTotalLen = 0; + outLen = sizeof(plainText); + + // 初始化, 设置为解密 + ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), false); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); // 输出错误码,可借助错误码在crypt_errno.h中找到对应的错误信息 + PrintLastError(); + goto exit; + } + + // 设置填充模式,填充模式必须和加密的填充模式相同 + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 输入密文数据 + ret = CRYPT_EAL_CipherUpdate(ctx, cipherText, cipherTextLen, plainText, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + outTotalLen += outLen; // 目前已处理数据量 + outLen = sizeof(plainText) - outTotalLen; // buffer剩余空间 + + // 解密最后一段数据并去填充 + ret = CRYPT_EAL_CipherFinal(ctx, plainText + outTotalLen, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + + printf("decrypted plain text value is: "); // 输出明文 + for (uint32_t i = 0; i < outTotalLen; i++) { + printf("%02x", plainText[i]); + } + printf("\n"); + + if (outTotalLen != dataLen || memcmp(plainText, data, dataLen) != 0) { + printf("plaintext comparison failed\n"); + goto exit; + } + printf("pass \n"); + +exit: + // 释放上下文内存 + CRYPT_EAL_CipherFreeCtx(ctx); + BSL_ERR_DeInit(); + return ret; +} + +``` + +## 非对称加解密 + +非对称加解密功能基于非对称算法提供了的加解密能力,如下以SM2加解密流程为例,给出了非对称加解密的示例代码,供适配参考。 + +## 示例代码 + +```c +#include +#include +#include +#include +#include "crypt_eal_pkey.h" // 非对称加解密接口头文件 +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // 算法id列表 +#include "crypt_errno.h" // 错误码列表 +#include "crypt_eal_rand.h" // 随机数头文件 +#include "crypt_types.h" + +void *StdMalloc(uint32_t len) { + return malloc((uint32_t)len); +} +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // 获取错误发生的文件名和行数 + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; // 注册的内存分配接口 + +int main(void) { + int32_t ret; + BSL_ERR_Init(); // 初始化错误码模块 + // 调用算法API接口之前需要调用BSL_SAL_RegMemCallback函数注册malloc和free函数。该步骤仅需执行一次 + // 如果未注册并且默认能力没有被裁剪,使用默认linux实现 + BSL_SAL_RegMemCallback(&cb); + CRYPT_EAL_PkeyCtx *pkey = NULL; + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (pkey == NULL) { + PrintLastError(); + goto exit; + } + + // 初始化随机数 + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 生成密钥对 + ret = CRYPT_EAL_PkeyGen(pkey); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyGen: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 待加密数据 + char *data = "test enc data"; + uint32_t dataLen = 12; + uint8_t ecrypt[125] = {0}; + uint32_t ecryptLen = 125; + uint8_t dcrypt[125] = {0}; + uint32_t dcryptLen = 125; + // 加密 + ret = CRYPT_EAL_PkeyEncrypt(pkey, data, dataLen, ecrypt, &ecryptLen); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyEncrypt: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 解密 + ret = CRYPT_EAL_PkeyDecrypt(pkey, ecrypt, ecryptLen, dcrypt, &dcryptLen); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyDecrypt: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + if (memcmp(dcrypt, data, dataLen) == 0) { + printf("encrypt and decrypt success\n"); + } else { + ret = -1; + } +exit: + // 释放上下文内存。 + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return ret; +} +``` + +# 签名验证示例 + +## 算法类型 + +签名验证功能基于非对称算法提供了的签名验证能力,如下以SM2签名验证为例,给出了签名验证的示例代码,供适配参考。 + +## 示例代码 + +```c +#include +#include +#include +#include +#include "crypt_eal_pkey.h" // 签名验签头文件 +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // 算法id列表 +#include "crypt_errno.h" // 错误码列表 +#include "crypt_eal_rand.h" // 随机数头文件 + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // 获取错误发生的文件名和行数 + printf("failed at file %s at line %d\n", file, line); +} +BSL_SAL_MemCallback cb = {StdMalloc, free}; // 注册的内存分配接口 + +int main(void) +{ + int ret; + uint8_t userId[32] = {0}; + uint8_t key[32] = {0}; // 此处密钥仅作示例 + uint8_t msg[32] = {0}; + uint8_t signBuf[100] = {0}; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx = NULL; + + BSL_ERR_Init(); // 初始化错误码模块 + // 调用算法API接口之前需要调用BSL_SAL_RegMemCallback函数注册malloc和free函数。该步骤仅需执行一次 + // 如果未注册并且默认能力没有被裁剪,使用默认linux实现 + BSL_SAL_RegMemCallback(&cb); + + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (ctx == NULL) { + goto exit; + } + + // 设置用户Id + ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 初始化随机数 + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 生成密钥对 + ret = CRYPT_EAL_PkeyGen(ctx); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 签名 + ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 验证 + ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("pass \n"); + +exit: + // 释放上下文内存 + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return ret; +} +``` + +# 密钥交换示例 + +## 算法类型 + +密钥交换功能基于非对称算法提供了密钥交换能力,如下以ECDH为例,给出了密钥交换的示例代码,供适配参考。 + +## 示例代码 + +```c +#include +#include +#include +#include +#include "crypt_types.h" +#include "crypt_eal_pkey.h" // 密钥交换头文件 +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // 算法id列表 +#include "crypt_errno.h" // 错误码列表 +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // 获取错误发生的文件名和行数 + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; // 注册的内存分配接口 + +int main(void) +{ + int ret; + + uint8_t prikey[] = + {0x7d, 0x7d, 0xc5, 0xf7, 0x1e, 0xb2, 0x9d, 0xda, 0xf8, 0x0d, 0x62, 0x14, 0x63, 0x2e, 0xea, 0xe0, + 0x3d, 0x90, 0x58, 0xaf, 0x1f, 0xb6, 0xd2, 0x2e, 0xd8, 0x0b, 0xad, 0xb6, 0x2b, 0xc1, 0xa5, 0x34}; + uint8_t pubkey[] = + {0x04, 0x70, 0x0c, 0x48, 0xf7, 0x7f, 0x56, 0x58, 0x4c, 0x5c, 0xc6, 0x32, 0xca, 0x65, 0x64, 0x0d, 0xb9, + 0x1b, 0x6b, 0xac, 0xce, 0x3a, 0x4d, 0xf6, 0xb4, 0x2c, 0xe7, 0xcc, 0x83, 0x88, 0x33, 0xd2, 0x87, + 0xdb, 0x71, 0xe5, 0x09, 0xe3, 0xfd, 0x9b, 0x06, 0x0d, 0xdb, 0x20, 0xba, 0x5c, 0x51, 0xdc, 0xc5, + 0x94, 0x8d, 0x46, 0xfb, 0xf6, 0x40, 0xdf, 0xe0, 0x44, 0x17, 0x82, 0xca, 0xb8, 0x5f, 0xa4, 0xac}; + uint8_t resSharekey[] = + {0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xff, 0x01, 0x2e, 0x54, 0xa4, 0x34, 0xfb, 0xdd, 0x2d, 0x25, + 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b}; + + CRYPT_EAL_PkeyPrv prvKey = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + uint32_t shareLen; + uint8_t *shareKey; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_PKEY_ParaId id = CRYPT_ECC_NISTP256; + + BSL_ERR_Init(); // 初始化错误码模块 + // 调用算法API接口之前需要调用BSL_SAL_RegMemCallback函数注册malloc和free函数。该步骤仅需执行一次 + // 如果未注册并且默认能力没有被裁剪,使用默认linux实现 + BSL_SAL_RegMemCallback(&cb); + + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + if (prvCtx == NULL || pubCtx == NULL) { + goto exit; + } + + // 设置曲线参数 + ret = CRYPT_EAL_PkeySetParaById(prvCtx, id); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 设置一端的私钥 + prvKey.id = CRYPT_PKEY_ECDH; + prvKey.key.eccPrv.len = sizeof(prikey); + prvKey.key.eccPrv.data = prikey; + ret = CRYPT_EAL_PkeySetPrv(prvCtx, &prvKey); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 设置曲线参数 + ret = CRYPT_EAL_PkeySetParaById(pubCtx, id); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 设置另一端的公钥 + pubKey.id = CRYPT_PKEY_ECDH; + pubKey.key.eccPub.len = sizeof(pubkey); + pubKey.key.eccPub.data = pubkey; + ret = CRYPT_EAL_PkeySetPub(pubCtx, &pubKey); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 共享密钥只涉及X轴, 这里返回点不压缩编码需要的长度 + shareLen = CRYPT_EAL_PkeyGetKeyLen(prvCtx) / 2; + shareKey = (uint8_t *)BSL_SAL_Malloc(shareLen); + if (shareKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + PrintLastError(); + goto exit; + } + + // 初始化随机数 + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 计算共享密钥 + ret = CRYPT_EAL_PkeyComputeShareKey(prvCtx, pubCtx, shareKey, &shareLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 和预期对比 + if (shareLen != sizeof(resSharekey) || memcmp(shareKey, resSharekey, shareLen) != 0) { + printf("failed to compare test results\n"); + ret = -1; + goto exit; + } + + printf("pass \n"); + +exit: + // 释放上下文内存。 + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(prvCtx); + CRYPT_EAL_PkeyFreeCtx(pubCtx); + BSL_SAL_Free(shareKey); + BSL_ERR_DeInit(); + return 0; +} + +``` + +# 密钥派生示例 + +## 算法类型 + +提供了PBKDF2、HKDF、SCRYPT和KDFTLS12密钥派生能力,如下以PBKDF2密钥派生算法为例,给出了密钥派生的示例代码,供适配参考。 + +## 示例代码 + +```c +#include +#include +#include +#include +#include "crypt_errno.h" // 错误码列表 +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // 算法id列表 +#include "crypt_eal_kdf.h" // 密钥派生接口头文件 + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int32_t ret; + uint8_t key[] = {0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64}; + uint8_t salt[] = {0x4e, 0x61, 0x43, 0x6c}; + uint32_t iterations = 80000; + uint8_t result[] = { + 0x4d, 0xdc, 0xd8, 0xf6, 0x0b, 0x98, 0xbe, 0x21, + 0x83, 0x0c, 0xee, 0x5e, 0xf2, 0x27, 0x01, 0xf9, + 0x64, 0x1a, 0x44, 0x18, 0xd0, 0x4c, 0x04, 0x14, + 0xae, 0xff, 0x08, 0x87, 0x6b, 0x34, 0xab, 0x56, + 0xa1, 0xd4, 0x25, 0xa1, 0x22, 0x58, 0x33, 0x54, + 0x9a, 0xdb, 0x84, 0x1b, 0x51, 0xc9, 0xb3, 0x17, + 0x6a, 0x27, 0x2b, 0xde, 0xbb, 0xa1, 0xd0, 0x78, + 0x47, 0x8f, 0x62, 0xb3, 0x97, 0xf3, 0x3c, 0x8d}; + + uint8_t out[sizeof(result)] = {0}; + uint32_t outLen = sizeof(result); + + // 初始化错误码模块 + BSL_ERR_Init(); + + // 调用算法API接口之前需要调用BSL_SAL_RegMemCallback函数注册malloc和free函数。该步骤仅需执行一次 + // 如果未注册并且默认能力没有被裁剪,使用默认linux实现 + BSL_SAL_RegMemCallback(&cb); + + ret = CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, sizeof(key), salt, sizeof(salt), iterations, out, outLen); + if (ret != CRYPT_SUCCESS) { + printf("pbkdf2 error code is %x\n", ret); + PrintLastError(); + goto exit; + } + if (memcmp(out, result, sizeof(result)) != 0) { + printf("failed to compare test results\n"); + ret = -1; + goto exit; + } + printf("pass \n"); +exit: + BSL_ERR_DeInit(); + return ret; +} +``` + +# 随机数生成示例 + +## 算法类型 + +提供了DRBG-SHA、DRBG-HMAC和DRBG-CTR随机数算法,其接口类型分为两类,全局随机数接口和多实例随机数接口。 + +```c +/* +* 全局随机数初始化和去初始化接口 + * 初始化接口的seedMeth参数是熵源回调,seedCtx是用户回调的上下文, +* 用户可以设置自己的熵源的实现。如果不设置,就使用系统默认熵源, +* 当前支持从 linux 的 /dev/random 获取熵 +*/ +int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, const uint8_t *pers, uint32_t persLen); +void CRYPT_EAL_RandDeinit(void); + +/* 初始化之后,用户就可以调用如下接口获取伪随机数和补充熵源 */ +int32_t CRYPT_EAL_Randbytes(uint8_t *byte, uint32_t len); +int32_t CRYPT_EAL_RandSeed(void); + +/* 多实例接口对比全局DRBG接口的主要区别就是将DRBG的上下文返回给用户, + * 支持用户创建多个DRBG上下文,不同上下文在熵源设置和内部状态变化之间互不干扰 。*/ +CRYPT_EAL_RndCtx *CRYPT_EAL_DrbgInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, const uint8_t *pers, uint32_t persLen); +void CRYPT_EAL_DrbgDeinit(CRYPT_EAL_RndCtx *ctx); +``` + +如下以DRBG-SHA算法为例,给出了随机数算法的示例代码,供适配参考。 + +## 示例代码 + +```c +#include +#include +#include +#include +#include "crypt_types.h" +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // 算法id列表 +#include "crypt_errno.h" // 错误码列表 +#include "crypt_eal_rand.h" // 随机数头文件 + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // 获取错误发生的文件名和行数 + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; // 注册的内存分配接口 + +int main(void) +{ + int ret; + uint8_t output[100] = {0}; + uint32_t len = 100; + + // 调用算法API接口之前需要调用BSL_SAL_RegMemCallback函数注册malloc和free函数, 该步骤仅需执行一次。 + // 如果未注册并且默认能力没有被裁剪,使用默认linux实现 + BSL_SAL_RegMemCallback(&cb); + + BSL_ERR_Init(); // 初始化错误模块 + + // 初始化全局随机数, 使用linux的/dev/random默认熵源 + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 获得len长度的随机数序列 + ret = CRYPT_EAL_Randbytes(output, len); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("random value is: "); // 输出随机数 + for (uint32_t i = 0; i < len; i++) { + printf("%02x", output[i]); + } + printf("\n"); + + // 重播种 + ret = CRYPT_EAL_RandSeed(); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandSeed: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // 获得len长度的随机数序列 + ret = CRYPT_EAL_Randbytes(output, len); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("random value is: "); // 输出随机数 + for (uint32_t i = 0; i < len; i++) { + printf("%02x", output[i]); + } + printf("\n"); + +exit: + // 释放上下文内存。 + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return 0; +} + +``` + + diff --git a/docs/zh/5_开发指南/2_安全通信应用开发指南.md b/docs/zh/5_开发指南/2_安全通信应用开发指南.md new file mode 100644 index 00000000..a5eba0bb --- /dev/null +++ b/docs/zh/5_开发指南/2_安全通信应用开发指南.md @@ -0,0 +1,823 @@ +# TLS特性介绍 + +## 协议功能介绍 + +openHiTLS基于传输层安全协议标准提供了安全协议链路创建、配置、管理等功能,主要功能接口在协议模块中提供。openHiTLS支持多种协议版本以及协议特性功能,包括基础协议握手、密钥更新、应用层协议协商、服务器名称指示等能力。 + +openHiTLS目前支持协议版本如下: + +- TLS1.2:支持安全重协商、应用层协议协商、服务器名称指示、会话恢复。 +- TLS1.3:密钥更新、应用层协议协商、服务器名称指示、会话恢复。 +- DTLS1.2:支持安全重协商、应用层协议协商、服务器名称指示、会话恢复。 +- TLCP:支持安全重协商、会话恢复。 + +### (D)TLS1.2规格说明 + +| 配置项 | 规格说明 | +| :---- | :---- | +| TLS版本 | TLS12(0x0303u)
DTLS12(0xfefdu) | +| 算法套 | TLS_RSA_WITH_AES_128_CBC_SHA(0x002F)
TLS_DHE_DSS_WITH_AES_128_CBC_SHA(0x0032)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033)
TLS_DH_anon_WITH_AES_128_CBC_SHA(0x0034)
TLS_RSA_WITH_AES_256_CBC_SHA(0x0035)
TLS_DHE_DSS_WITH_AES_256_CBC_SHA(0x0038)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039)
TLS_DH_anon_WITH_AES_256_CBC_SHA(0x003A)
TLS_RSA_WITH_AES_128_CBC_SHA256(0x003C)
TLS_RSA_WITH_AES_256_CBC_SHA256(0x003D)
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(0x0040)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(0x0067)
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(0x006A)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(0x006B)
TLS_DH_anon_WITH_AES_128_CBC_SHA256(0x006C)
TLS_DH_anon_WITH_AES_256_CBC_SHA256(0x006D)
TLS_PSK_WITH_AES_128_CBC_SHA(0x008C)
TLS_PSK_WITH_AES_256_CBC_SHA(0x008D)
TLS_DHE_PSK_WITH_AES_128_CBC_SHA(0x0090)
TLS_DHE_PSK_WITH_AES_256_CBC_SHA(0x0091)
TLS_RSA_PSK_WITH_AES_128_CBC_SHA(0x0094)
TLS_RSA_PSK_WITH_AES_256_CBC_SHA(0x0095)
TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C)
TLS_RSA_WITH_AES_256_GCM_SHA384(0x009D)
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x009E)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x009F)
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(0x00A2)
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(0x00A3)
TLS_DH_anon_WITH_AES_128_GCM_SHA256(0x00A6)
TLS_DH_anon_WITH_AES_256_GCM_SHA384(0x00A7)
TLS_PSK_WITH_AES_128_GCM_SHA256(0x00A8)
TLS_PSK_WITH_AES_256_GCM_SHA384(0x00A9)
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256(0x00AA)
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384(0x00AB)
TLS_RSA_PSK_WITH_AES_128_GCM_SHA256(0x00AC)
TLS_RSA_PSK_WITH_AES_256_GCM_SHA384(0x00AD)
TLS_PSK_WITH_AES_128_CBC_SHA256(0x00AE)
TLS_PSK_WITH_AES_256_CBC_SHA384(0x00AF)
TLS_DHE_PSK_WITH_AES_128_CBC_SHA256(0x00B2)
TLS_DHE_PSK_WITH_AES_256_CBC_SHA384(0x00B3)
TLS_RSA_PSK_WITH_AES_128_CBC_SHA256(0x00B6)
TLS_RSA_PSK_WITH_AES_256_CBC_SHA384(0x00B7)
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009)
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014)
TLS_ECDH_anon_WITH_AES_128_CBC_SHA(0xC018)
TLS_ECDH_anon_WITH_AES_256_CBC_SHA(0xC019)
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(0xC023)
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(0xC024)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(0xC027)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(0xC028)
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B)
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030)
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA(0xC035)
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA(0xC036)
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256(0xC037)
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384(0xC038)
TLS_RSA_WITH_AES_128_CCM(0xC09C)
TLS_RSA_WITH_AES_256_CCM(0xC09D)
TLS_DHE_RSA_WITH_AES_128_CCM(0xC09E)
TLS_DHE_RSA_WITH_AES_256_CCM(0xC09F)
TLS_RSA_WITH_AES_128_CCM_8(0xC0A0)
TLS_RSA_WITH_AES_256_CCM_8(0xC0A1)
TLS_PSK_WITH_AES_256_CCM(0xC0A5)
TLS_DHE_PSK_WITH_AES_128_CCM(0xC0A6)
TLS_DHE_PSK_WITH_AES_256_CCM(0xC0A7)
TLS_ECDHE_ECDSA_WITH_AES_128_CCM(0xC0AC)
TLS_ECDHE_ECDSA_WITH_AES_256_CCM(0xC0AD)
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCCA8)
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256(0xCCA9)
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCCAA)
TLS_PSK_WITH_CHACHA20_POLY1305_SHA256(0xCCAB)
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256(0xCCAC)
TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256(0xCCAD)
TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256(0xCCAE)
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256(0xD001)
TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384(0xD002)
TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256(0xD005) | +| EC点格式 | uncompressed(0) | +| 椭圆曲线 | secp256r1(23)
secp384r1(24)
secp521r1(25)
brainpoolP256r1(26)
brainpoolP384r1(27)
brainpoolP512r1(28)
x25519(29)| +| 签名哈希算法 | dsa_sha256(0x0402)
dsa_sha384(0x0502)
dsa_sha512(0x0602)
rsa_pkcs1_sha256(0x0401)
rsa_pkcs1_sha384(0x0501)
rsa_pkcs1_sha512(0x0601)
ecdsa_secp256r1_sha256(0x0403)
ecdsa_secp384r1_sha384(0x0503)
ecdsa_secp521r1_sha512(0x0603)
rsa_pss_rsae_sha256(0x0804)
rsa_pss_rsae_sha384(0x0805)
rsa_pss_rsae_sha512(0x0806)
rsa_pss_pss_sha256(0x0809)
rsa_pss_pss_sha384(0x080a)
rsa_pss_pss_sha512(0x080b)
ed25519(0x0807)| +| 是否开启双端校验 | HITLS_CFG_SetClientVerifySupport(默认关闭) | +| 是否允许客户端证书为空 | HITLS_CFG_SetNoClientCertSupport(默认关闭) | +| 是否不校验对端证书 | HITLS_CFG_SetVerifyNoneSupport(默认关闭) | +| 是否支持重协商 | HITLS_CFG_SetRenegotiationSupport(默认关闭) | +| 是否只校验一次客户端证书 | HITLS_CFG_SetClientOnceVerifySupport(默认关闭) | +| 是否开启单航程发送握手报文 | HITLS_CFG_SetFlightTransmitSwitch(默认关闭) | +| 是否开启安静断链模式 | HITLS_CFG_SetQuietShutdown(默认关闭) | +| 是否支持扩展主密钥 | HITLS_CFG_SetExtenedMasterSecretSupport(默认开启) | +| 是否支持sessionTicket | HITLS_CFG_SetSessionTicketSupport(默认开启) | +| 是否校验证书keyUsage | HITLS_CFG_SetCloseCheckKeyUsage(默认开启) | +| 是否支持自动生成DH参数 | HITLS_CFG_SetDhAutoSupport(默认开启) | + +### TLS1.3规格说明 + +| 配置项 | 规格说明 | +| :---- | :---- | +| TLS版本 | TLS13(0x0304u) | +| 算法套 | TLS_AES_128_GCM_SHA256(0x1301)
TLS_AES_256_GCM_SHA384(0x1302)
TLS_CHACHA20_POLY1305_SHA256(0x1303)
TLS_AES_128_CCM_SHA256(0x1304)
TLS_AES_128_CCM_8_SHA256(0x1305) | +| EC点格式 | uncompressed(0) | +| 椭圆曲线 | secp256r1(23)
secp384r1(24)
secp521r1(25)
x25519(29)
ffdhe2048(256)
ffdhe3072(257)
ffdhe4096(258)
ffdhe6144(259)
ffdhe8192(260) | +| 签名哈希算法 | rsa_pkcs1_sha256(0x0401)
rsa_pkcs1_sha384(0x0501)
rsa_pkcs1_sha512(0x0601)
ecdsa_secp256r1_sha256(0x0403)
ecdsa_secp384r1_sha384(0x0503)
ecdsa_secp521r1_sha512(0x0603)
rsa_pss_rsae_sha256(0x0804)
rsa_pss_rsae_sha384(0x0805)
rsa_pss_rsae_sha512(0x0806)
rsa_pss_pss_sha256(0x0809)
rsa_pss_pss_sha384(0x080a)
rsa_pss_pss_sha512(0x080b)
ed25519(0x0807)| +| 是否开启双端校验 | HITLS_CFG_SetClientVerifySupport(默认关闭) | +| 是否允许客户端证书为空 | HITLS_CFG_SetNoClientCertSupport(默认关闭) | +| 是否不校验对端证书 | HITLS_CFG_SetVerifyNoneSupport(默认关闭) | +| 是否只校验一次客户端证书 | HITLS_CFG_SetClientOnceVerifySupport(默认关闭) | +| 是否开启握手后认证 | HITLS_CFG_SetPostHandshakeAuthSupport(默认关闭) | +| 是否开启单航程发送握手报文 | HITLS_CFG_SetFlightTransmitSwitch(默认关闭) | +| 是否开启安静断链模式 | HITLS_CFG_SetQuietShutdown(默认关闭) | +| 是否支持扩展主密钥 | HITLS_CFG_SetExtenedMasterSecretSupport(默认开启) | +| 是否支持sessionTicket | HITLS_CFG_SetSessionTicketSupport(默认开启) | +| 是否校验证书keyUsage | HITLS_CFG_SetCloseCheckKeyUsage(默认开启) | +| 是否支持自动生成DH参数 | HITLS_CFG_SetDhAutoSupport(默认开启) | + +### TLCP规格说明 + +| 配置项 | 规格说明 | +| :---- | :---- | +| TLCP版本 | TLCP11(0x0101u) | +| 算法套 | ECDHE_SM4_CBC_SM3(0xE011)
ECC_SM4_CBC_SM3(0xE013) | +| EC点格式 | HITLS_POINT_FORMAT_UNCOMPRESSED(0) | +| 椭圆曲线 | curveSM2(41) | +| 签名哈希算法 | sm2sig_sm3(0x0708) | +| 是否开启双端校验 | HITLS_CFG_SetClientVerifySupport(默认关闭) | +| 是否允许客户端证书为空 | HITLS_CFG_SetNoClientCertSupport(默认关闭) | +| 是否不校验对端证书 | HITLS_CFG_SetVerifyNoneSupport(默认关闭) | +| 是否只校验一次客户端证书 | HITLS_CFG_SetClientOnceVerifySupport(默认关闭) | +| 是否开启单航程发送握手报文 | HITLS_CFG_SetFlightTransmitSwitch(默认关闭) | +| 是否开启安静断链模式 | HITLS_CFG_SetQuietShutdown(默认关闭) | +| 是否校验证书keyUsage | HITLS_CFG_SetCloseCheckKeyUsage(默认开启) | + +### 扩展能力 + +| 扩展类型名称 | DTLS1.2 | TLS1.2 | TLS1.3 | TLCP | +| :---- | :---- | :---- | :---- | :---- | +| server_name | 是 | 是 | 是 | 否 | +| supported_groups | 是 | 是 | 是 | 是 | +| ec_point_formats | 是 | 是 | 否 | 是 | +| signature_algorithms | 是 | 是 | 是 | 否 | +| application_layer_protocol_negotiation | 是 | 是 | 是 | 否 | +| extended_master_secret | 是 | 是 | 否 | 否 | +| session_ticket | 是 | 是 | 否 | 否 | +| encrypt_then_mac | 是 | 是 | 否 | 是 | +| renegotiation_info | 是 | 是 | 否 | 是 | +| early_data | 否 | 否 | 否 | 否 | +| supported_versions | 否 | 否 | 是 | 否 | +| cookie | 是 | 否 | 是 | 否 | +| pre_shared_key | 否 | 否 | 是 | 否 | +| psk_key_exchange_modes | 否 | 否 | 是 | 否 | +| certificate_authorities | 否 | 否 | 否 | 否 | +| oid_filters | 否 | 否 | 否 | 否 | +| post_handshake_auth | 否 | 否 | 是 | 否 | +| signature_algorithms_cert | 否 | 否 | 否 | 否 | +| key_share | 否 | 否 | 是 | 否 | + +### 框架 + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/TheFramework.png) + +### 上下文介绍 + +openHiTLS安全传输的上下文分为两层:HITLS_Config和HITLS_Ctx。其中HITLS_Config是openHiTLS的配置上下文,一般一个进程中的一类业务(如客户端、服务端)有一个配置上下文,HITLS_Ctx是openHiTLS的链路上下文,每条连接一个上下文,配置上下文和链路上下文是多对一的关系。openHiTLS中的每个链路上下文都拷贝了一个配置上下文的副本。 + +### 非阻塞IO能力 + +本模块不提供创建fd(file description)的能力,fd由用户创建后,配置到openHiTLS内,openHiTLS读写fd后,用户再关闭fd。openHiTLS提供**非阻塞IO**的支持,不管是在握手阶段,还是在读写阶段,都支持非阻塞IO的操作能力。 在调用HITLS_Read、HITLS_Write时,如果返回HITLS_REC_NORMAL_RECV_BUF_EMPTY或HITLS_REC_NORMAL_IO_BUSY,表示openHiTLS需要再次读写。在实际业务中,往往通过epoll/select驱动,以实现非阻塞IO的功能,非阻塞IO的示例代码如下: + +```c +// 客户端握手 +do { + ret = HITLS_Connect(ctx); +} while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); +// 服务端握手 +do { + ret = HITLS_Accept(ctx); +} while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); + +``` + +> **注意:** do while仅供参考,业务逻辑实现可能有所不同。 + +### 约束说明 + +1. openHiTLS支持基于证书认证的客户端和服务端。 +2. 为方便用户快速使用,提供了默认配置功能。大部分情况下,用户只需要在默认配置的基础上,做很小的额外配置,即可让openHiTLS开始工作。 同时,openHiTLS提供了丰富的配置接口,产品可以根据API手册,根据自己的需求配置openHiTLS的选项。 + +### 对外依赖 + +openHiTLS对部分算法实现,证书解析的依赖随着产品的需求不同而不同,所以对外提供了注册接口,供产品根据自己的实际情况注册对应的接口。openHiTLS依赖接口如下,接口详细参数介绍,请参考API手册头文件: + +- [hitls_cert_reg.h](https://apidoc.openhitls.net/d7/d06/a00131.html) +- [hitls_crypt_reg.h](https://apidoc.openhitls.net/d5/d5b/a00135.html) + +注册算法相关回调函数: + +```c +/** + * @brief 要求必须注册的回调函数 + */ +typedef struct { + CRYPT_RandBytesCallback randBytes; /**<; 获取随机数 */ + CRYPT_HmacSizeCallback hmacSize; /**<; HMAC:根据hash算法获取HMAC长度 */ + CRYPT_HmacInitCallback hmacInit; /**<; HMAC:初始化上下文 */ + CRYPT_HmacFreeCallback hmacFree; /**<; HMAC:释放上下文 */ + CRYPT_HmacUpdateCallback hmacUpdate; /**<; HMAC:添加输入数据 */ + CRYPT_HmacFinalCallback hmacFinal; /**<; HMAC:输出结果 */ + CRYPT_HmacCallback hmac; /**<; HMAC:单次HMAC函数 */ + CRYPT_DigestSizeCallback digestSize; /**<; HASH:获取哈希长度 */ + CRYPT_DigestInitCallback digestInit; /**<; HASH:初始化上下文 */ + CRYPT_DigestCopyCallback digestCopy; /**<; HASH:复制hash上下文 */ + CRYPT_DigestFreeCallback digestFree; /**<; HASH:释放上下文 */ + CRYPT_DigestUpdateCallback digestUpdate; /**<; HASH:添加输入数据 */ + CRYPT_DigestFinalCallback digestFinal; /**<; HASH:输出hash结果 */ + CRYPT_DigestCallback digest; /**<; HASH:单次hash函数 */ + CRYPT_EncryptCallback encrypt; /**<; TLS加密:为record提供加密能力 */ + CRYPT_DecryptCallback decrypt; /**<; TLS解密:为record提供解密能力 */ +} HITLS_CRYPT_BaseMethod; + +/** + * @brief ECDH需要注册的回调函数 + */ +typedef struct { + CRYPT_GenerateEcdhKeyPairCallback generateEcdhKeyPair; /**<; ECDH:根据椭圆曲线参数,生成密钥对 */ + CRYPT_FreeEcdhKeyCallback freeEcdhKey; /**<; ECDH:释放椭圆曲线密钥 */ + CRYPT_GetEcdhEncodedPubKeyCallback getEcdhPubKey; /**<; ECDH:提取公钥数据 */ + CRYPT_CalcEcdhSharedSecretCallback calcEcdhSharedSecret; /**<; ECDH:根据本端密钥和对端公钥数据,计算共享密钥 */ +} HITLS_CRYPT_EcdhMethod; + +/** + * @brief DH需要注册的回调函数 + */ +typedef struct { + CRYPT_GenerateDhKeyBySecbitsCallback generateDhKeyBySecbits; /**<; DH:根据secbits,生成密钥对 */ + CRYPT_GenerateDhKeyByParamsCallback generateDhKeyByParams; /**<; DH:根据dh参数,生成密钥对 */ + CRYPT_FreeDhKeyCallback freeDhKey; /**<; DH:释放密钥 */ + CRYPT_DHGetParametersCallback getDhParameters; /**<; DH:通过密钥句柄获取p g plen glen */ + CRYPT_GetDhEncodedPubKeyCallback getDhPubKey; /**<; DH:提取Dh公钥数据 */ + CRYPT_CalcDhSharedSecretCallback calcDhSharedSecret; /**<; DH:根据本端密钥和对端公钥数据,计算共享密钥 */ +} HITLS_CRYPT_DhMethod; + +/** + * @brief KDF函数需要注册回调函数 + */ +typedef struct { + CRYPT_HkdfExtractCallback hkdfExtract; + CRYPT_HkdfExpandCallback hkdfExpand; +} HITLS_CRYPT_KdfMethod; + +/** + * @brief 注册基本的回调函数 + */ +int32_t HITLS_CRYPT_RegisterBaseMethod(HITLS_CRYPT_BaseMethod *userCryptCallBack); + +/** + * @brief 注册ECDH的回调函数 + */ +int32_t HITLS_CRYPT_RegisterEcdhMethod(HITLS_CRYPT_EcdhMethod *userCryptCallBack); + +/** + * @brief 注册DH的回调函数 + */ +int32_t HITLS_CRYPT_RegisterDhMethod(const HITLS_CRYPT_DhMethod *userCryptCallBack); + +/** + * @brief 注册Hkdf的回调函数 + */ +int32_t HITLS_CRYPT_RegisterHkdfMethod(HITLS_CRYPT_KdfMethod *userCryptCallBack); +``` + +注册证书相关回调函数: + +```c +/** + * @brief 要求必须注册的回调函数 + */ +typedef struct { + CERT_StoreNewCallBack certStoreNew; /**< 创建证书store */ + CERT_StoreDupCallBack certStoreDup; /**< 复制证书store */ + CERT_StoreFreeCallBack certStoreFree; /**< 释放证书store */ + CERT_StoreCtrlCallBack certStoreCtrl; /**< 证书store ctrl接口 */ + CERT_BuildCertChainCallBack buildCertChain; /**< 构造证书链 */ + CERT_VerifyCertChainCallBack verifyCertChain; /**< 验证证书链 */ + + CERT_CertEncodeCallBack certEncode; /**< 证书编码 */ + CERT_CertParseCallBack certParse; /**< 证书解码 */ + CERT_CertDupCallBack certDup; /**< 深拷贝证书 */ + CERT_CertRefCallBack certRef; /**< 证书引用计数加一 */ + CERT_CertFreeCallBack certFree; /**< 释放证书 */ + CERT_CertCtrlCallBack certCtrl; /**< 证书ctrl接口 */ + + CERT_KeyParseCallBack keyParse; /**< 解析key */ + CERT_KeyDupCallBack keyDup; /**< 深拷贝key */ + CERT_KeyFreeCallBack keyFree; /**< 释放key */ + CERT_KeyCtrlCallBack keyCtrl; /**< key ctrl接口 */ + CERT_CreateSignCallBack createSign; /**< 签名 */ + CERT_VerifySignCallBack verifySign; /**< 验签 */ + CERT_EncryptCallBack encrypt; /**< 密钥交换加密 */ + CERT_DecryptCallBack decrypt; /**< 密钥交换解密 */ + + CERT_CheckPrivateKeyCallBack checkPrivateKey; /**< 检查证书和key是否匹配 */ +} HITLS_CERT_MgrMethod; + +/** + * @brief 注册证书相关回调函数 + */ +int32_t HITLS_CERT_RegisterMgrMethod(HITLS_CERT_MgrMethod *method); + +/** + * @brief 注销证书相关回调函数 + */ +void HITLS_CERT_DeinitMgrMethod(void); +``` + +## 安全通信应用时序交互介绍 + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/CommunicationApplications.png) + +# TLS客户端示例 + +## 客户端类型 + +### 基于证书认证的客户端 + +基于证书认证的客户端需要配置信任证书池和设备证书,信任证书池用来标识哪些证书颁发机构被客户端信任。 + +#### 加载信任证书 + +- 使用信任证书池:信任证书池用来标识哪些证书颁发机构被客户端信任。用户需要在进行连接前配置信任证书池,用户配置的信任证书池将会被加载到证书管理引擎中。信任证书池分为两类: + +1. 用于校验对端证书链 + 对于需要校验服务端身份的算法套,服务端会将证书及证书链通过握手消息发送给TLS客户端。若服务端发送的证书及证书链非客户端信任的颁发机构所颁发,客户端将发送致命告警并终止握手。若用户未配置信任证书池,也会导致证书链校验失败,最终造成TLS握手失败。 + + 对于配置上下文用户可通过以下接口设置用于校验对端证书的信任证书池: + +```c +/** + * @brief 设置TLS配置使用的verify store,用于证书校验 + */ +int32_t HITLS_CFG_SetVerifyStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); +``` + +对于链路上下文用户则可以调用`HITLS_SetVerifyStore`进行设置。 + +> **注意:** 在调用`HITLS_CFG_NewXXXConfig`时会生成一个默认证书池`CertStore`,若用户未设置`VerifyStore`时,默认使用`CertStore`进行证书链校验。 + +2. 用于产生本端证书链 + 服务端在进行握手时,需要发送本端证书给对端进行校验,若用户未配置本端设备证书对应的证书链,则服务端会从信任证书池中寻找证书链发送给对端。服务端在已经发送证书链的情况下,可以请求TLS客户端证书来校验客户端身份,该场景称为***双向认证***,TLS客户端会将本端证书及证书链通过握手消息发送给服务端。若用户配置的信任证书池中没有本端设备证书对应的证书链,或者用户未配置信任证书池,客户端会发送空的证书消息,能否继续握手取决于服务端的行为。 + + 用户可通过以下接口设置产生本端证书链的信任证书池: + +```c +/** + * @brief 设置TLS配置使用的chain store,用于构造证书链 + */ +int32_t HITLS_CFG_SetChainStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); +``` + +- 使用设备证书对应证书链:服务端或客户端(双向认证场景)需要给对端发送设备证书以及证书链,除了使用信任证书池之外,还提供根据设备证书添加相应证书链能力。给对端发送证书链时优先级以设备证书相应证书链为先。用户可通过以下接口设置用于添加相应证书链能力: + +```c +/** + * @brief 添加证书到当前config正在使用的证书链中 + */ +int32_t HITLS_CFG_AddChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); +``` + +- 向信任证书池添加证书:在设置完信任证书池后可以向相应的信任证书池添加信任证书,用户可通过以下接口设置: + +```c +/** + * @brief 向指定信任证书池添加证书 + */ +int32_t HITLS_CFG_AddCertToStore(HITLS_Config *config, char *certPath, HITLS_CERT_StoreType storeType); +``` + +> **说明:**该接口可以为默认证书池、校验证书池和证书链池添加证书,证书以相对路径传入。 + +#### 配置客户端证书 + +客户端证书是客户端身份认证的凭证,在双向认证场景下,TLS客户端会将本端证书及证书链通过握手消息发送给服务端,若客户端没有可用的证书,或者用户未配置证书,TLS客户端会发送空的证书消息,能否继续握手取决于服务端的行为。 + +对于配置上下文用户可通过以下接口配置客户端证书: + +```c +/** + * @brief 添加设备证书,每种类型的证书只能添加一本 + */ +int32_t HITLS_CFG_SetCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); +/** + * @brief 从文件中加载设备证书 + */ +int32_t HITLS_CFG_LoadCertFile(HITLS_Config *config, const uint8_t *file, HITLS_ParseFormat format); +/** + * @brief 从buffer中读取设备证书 + */ +int32_t HITLS_CFG_LoadCertBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); +/** + * @brief 添加国密设备证书,每种类型的证书只能添加一本 + */ +int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); +``` + +除了配置证书,用户还需要配置证书对应的私钥,只配置证书而不配置对应的私钥同样会导致握手失败。用户可通过以下接口对配置上下文配置证书对应的私钥: + +```c +/** + * @brief 添加设备证书私钥,每种类型的证书只能添加一个私钥 + */ +int32_t HITLS_CFG_SetPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, bool isClone); +/** + * @brief 从文件中加载设备证书私钥 + */ +int32_t HITLS_CFG_LoadKeyFile(HITLS_Config *config, const uint8_t *file, HITLS_ParseFormat format); +/** + * @brief 从buffer中读取设备证书私钥 + */ +int32_t HITLS_CFG_LoadKeyBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); +/** + * @brief 添加国密设备证书,每种类型的证书只能添加一本 + */ +int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); +``` + +用户可以通过以下接口卸载所有的证书和私钥: + +```c +/** + * @brief 释放加载的所有证书及私钥 + */ +int32_t HITLS_CFG_RemoveCertAndKey(HITLS_Config *config); +``` + +对于已生成的链路上下文则可以通过以下接口卸载证书和私钥: + +```c +/** + * @brief 释放加载的所有证书及私钥 + */ +int32_t HITLS_RemoveCertAndKey(HITLS_Ctx *ctx); +``` + +> **注意**:每一类证书及对应的私钥只允许配置一次,重复配置会被覆盖,不同类证书不受影响。比如先后配置两本RSA证书,只有最后配置的RSA证书会生效,但是可以先配置RSA证书,再配置ECDSA证书,两本证书都会生效。 + +### 基于PSK认证的客户端 + +基于PSK认证的基本建链流程如下: + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/LinkSetupProcess.png) + +1. 使用PSK密钥协商,客户端在**ClientHello**消息中提供PSK算法套选择,并由服务端选择是否使用PSK算法套; +2. 在选定具体的PSK类算法套后,服务端会在**ServerKeyExchange**消息中包含一个身份提示信息`identity_hint`,用于提示客户端使用哪一个psk identity_hint; +3. 客户端在收到包含身份提示信息的**ServerKeyExchange**消息后,通过回调的形式向TLS使用者索取PSK密钥及identity身份信息; +4. 随后客户端在**ClientKeyExchange**消息中包含`identity`身份信息,用于指示服务端使用哪一个PSK; +5. 服务端在收到包含`identity`身份信息后,通过回调的形式向上层索取PSK密钥; +6. 随后两端基于获取到的PSK生成预主密钥,并在生成后清除PSK,完成密钥协商流程。 + +因此,基于PSK认证的客户端需要先设置预共享密钥获取回调,回调形式如下: + +```c +/** + * @brief 客户端获取psk原型 + */ +typedef uint32_t (*HITLS_PskClientCb)(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, uint32_t maxPskLen); +/** + * @brief 设置客户端PSK回调,用于在PSK协商时通过该回调获取identity及psk + */ +int32_t HITLS_CFG_SetPskClientCallback(HITLS_Config *config, HITLS_PskClientCb callback); +``` + +## 示例代码 + +### 基于证书认证的客户端 + +参考[client.c](../../../testcode/demo/client.c) + +### 基于PSK认证的客户端 + +基于PSK认证的客户端代码大部分跟基于证书客户端的相同,只是在配置`HITLS_Config`有所不同。 +```c +... +uint32_t ExampleClientCb(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, + uint32_t maxPskLen) +{ + (void)ctx; + (void)hint; + int32_t ret; + const char pskTrans[] = "psk data"; + uint32_t pskTransUsedLen = sizeof(pskTransUsedLen); + if (memcpy_s(identity, maxIdentityLen, "hello", strlen("hello") + 1) != EOK) { + return 0; + } + if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { + return 0; + } + return pskTransUsedLen; +} + + +int main(int32_t argc, char *argv[]) +{ + ... + config = HITLS_CFG_NewTLS12Config(); + if (config == NULL) { + printf("HITLS_CFG_NewTLS12Config failed.\n"); + return -1; + } + uint16_t cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256; + // 配置算法套 + if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; + } + // 配置psk回调 + if (HITLS_CFG_SetPskClientCallback(config, (HITLS_PskClientCb)ExampleClientCb) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetPskClientCallback err\n"); + return -1; + } + + /* 新建openHiTLS上下文 */ + ctx = HITLS_New(config); + if (ctx == NULL) { + printf("HITLS_New failed.\n"); + goto exit; + } + + ... +} +``` + +### TLCP客户端 + +其他步骤与基于证书认证的客户端一致。 + +```c +config = HITLS_CFG_NewTLCPConfig(); +if (config == NULL) { + printf("HITLS_CFG_NewTLCPConfig failed.\n"); + return -1; +} +uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; +// 配置算法套 +if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; +} + +/* 加载证书:需要用户实现 */ +HITLS_CFG_AddCertToStore(config, "rootCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +HITLS_CFG_AddCertToStore(config, "intCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +// 双端认证场景下,需要从文件中加载签名证书和私钥, 由用户实现 +HITLS_CERT_X509 *signCert = LoadCertFromFile("ClientSignCert.pem"); +HITLS_CERT_X509 *signKey = LoadKeyFromFile("ClientSignKey.pem"); +// 从文件中加载加密证书和私钥 +HITLS_CERT_X509 *encCert = LoadCertFromFile("ClientEncCert.pem"); +HITLS_CERT_X509 *encKey = LoadKeyFromFile("ClientEncKey.pem"); +//设置添加国密签名证书和私钥 +HITLS_CFG_SetTlcpCertificate(config, signCert, false, false); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, false); +//设置添加国密加密证书和私钥 +HITLS_CFG_SetTlcpCertificate(config, signCert, false, true); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, true); +... +``` + +# TLS服务端示例 + +## 服务端类型 + +### 基于证书认证的服务端 + +基于证书认证的TLS服务端需要配置信任证书池和设备证书,信任证书池用来标识哪些证书颁发机构被客户端信任,设备证书是服务端身份认证的凭证。服务端可以通过双向认证配置项来决定是否校验客户端身份。 + +#### 双向认证服务端配置 + +服务端在已经发送证书链的情况下,可以请求TLS客户端证书来校验客户端身份,该场景称为“双向认证”。 +openHiTLS提供以下两个配置项: + +1. 双向认证开关 + 默认关闭,即服务端默认不校验客户端身份。用户可通过`HITLS_CFG_SetClientVerifySupport`接口控制开关。 + +```c +/** + * @brief 设置是否校验客户端证书 + 客户端:此设置无影响 + 服务端:将会发送certificate request + */ +int32_t HITLS_CFG_SetClientVerifySupport(HITLS_Config *config, bool support); +``` + +2. 是否接受无客户端证书 + 此配置仅在双向认证打开的场景下生效,默认不接受,即服务端必须校验客户端证书,如果客户端发送的证书链为空或者校验不通过,TLS服务端将发送致命告警并终止握手。 + 用户可通过HITLS_CFG_SetNoClientCertSupport接口控制开关。 + +```c +/** + * @brief 设置是否支持没有客户端证书,仅在开启校验客户端证书的场景下生效 + 客户端:此设置无影响 + 服务端:收到客户端空证书时,证书校验是否通过。默认校验不通过 + */ +int32_t HITLS_CFG_SetNoClientCertSupport(HITLS_Config *config, bool support); +``` + +#### 加载信任证书池 + +参考[加载信任证书](#### 加载信任证书)。 + +#### 配置服务端证书 + +对于需要校验服务端身份的算法套,用户需要配置服务端证书、证书链及对应的私钥。参考配置客户端证书。 + +### 基于PSK认证的服务端 + +基于PSK认证的服务端获取预共享密钥回调略有不同,如下所示: + +```c +/** + * @brief 服务端psk协商回调 +*/ +typedef int32_t (*HITLS_PskFindSessionCb)(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session); +/** + * @brief 设置服务端PSK回调,用于在PSK协商时通过该回调获取psk + */ +int32_t HITLS_CFG_SetPskServerCallback(HITLS_Config *config, HITLS_PskServerCb callback); +``` + +剩余流程参考客户端。 + +## 示例代码 + +### 基于证书认证的服务端 + +参考[server.c](../../../testcode/demo/server.c) + +### 基于PSK认证的服务端 + +基于PSK认证的服务端代码大部分跟基于证书服务端的相同,只是在配置`HITLS_Config`有所不同。 + +```c +... + +uint32_t ExampleServerCb(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen) +{ + (void)ctx; + if (identity == NULL || strcmp((const char *)identity, "hello") != 0) { + return 0; + } + const char pskTrans[] = "psk data"; + uint32_t pskTransUsedLen = sizeof(pskTransUsedLen); + if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { + return 0; + } + return pskTransUsedLen; +} + +int main(int32_t argc, char *argv[]) +{ + ... + config = HITLS_CFG_NewTLS12Config(); + if (config == NULL) { + printf("HITLS_CFG_NewTLS12Config failed.\n"); + return -1; + } + uint16_t cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256; + // 配置算法套 + if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; + } + // 配置psk回调 + if (HITLS_CFG_SetPskServerCallback(tlsConfig, (HITLS_PskServerCb)ExampleServerCb) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetPskClientCallback err\n"); + return -1; + } + + /* 新建openHiTLS上下文 */ + ctx = HITLS_New(config); + if (ctx == NULL) { + printf("HITLS_New failed.\n"); + goto exit; + } + + ... +} +``` + +### TLCP服务端 + +其他步骤与基于证书认证的服务端一致。 + +```c +... +config = HITLS_CFG_NewTLCPConfig(); +if (cfg == NULL) { + printf("HITLS_CFG_NewTLCPConfig failed.\n"); + return -1; +} + +uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; +// 配置算法套 +if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetCipherSuites err\n"); + return -1; +} + +if (HITLS_CFG_SetClientVerifySupport(config, ture) != HITLS_SUCCESS) { + printf("HITLS_CFG_SetClientVerifySupport err\n"); + return -1; +} + +/* 加载证书:需要用户实现 */ +HITLS_CFG_AddCertToStore(config, "rootCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +HITLS_CFG_AddCertToStore(config, "intCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); +// 从文件中加载签名证书和私钥, 需要用户实现 +HITLS_CERT_X509 *signCert = LoadCertFromFile("ServerSignCert.pem"); +HITLS_CERT_X509 *signKey = LoadKeyFromFile("ServerSignKey.pem"); +// 从文件中加载加密证书和私钥 +HITLS_CERT_X509 *encCert = LoadCertFromFile("ServerEncCert.pem"); +HITLS_CERT_X509 *encKey = LoadKeyFromFile("ServerEncKey.pem"); +//设置添加国密签名证书和私钥 +HITLS_CFG_SetTlcpCertificate(config, signCert, false, false); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, false); +//设置添加国密加密证书和私钥 +HITLS_CFG_SetTlcpCertificate(config, signCert, false, true); +HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, true); +... +``` + +# TLS会话密钥更新示例 + +## 会话密钥更新类型 + +### (D)TLS1.2/TLCP重协商示例 + +(D)TLS1.2/TLCP支持安全重协商,重协商功能允许客户端或服务端在同一个安全连接上发起新的协商,以产生新的密钥,一般应用在保密要求高,一条连接上传送数据量大的连接上。 +安全重协商流程如下: + +![image](../images/Developer%20Guide/Secure%20Communication%20Application%20Development%20Guide_figures/SecurityRenegotiationProcedure.png) + +> **注意**:用户通过`HITLS_Renegotiate`接口进入重协商状态,可以通过`HITLS_Accept`、`HITLS_Connect`、`HITLS_Write`和`HITLS_Read`触发重协商握手流程。推荐使用`HITLS_Accept`和`HITLS_Connect`发起重协商握手。 + +**客户端示例** + +```c +/* 应用层数据交互 */ +const uint8_t sndBuf[] = "Hi, this is client\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +/* 客户端进入重协商状态 */ +ret = HITLS_Renegotiate(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Renegotiate error:error code:%d\n", ret); + goto exit; +} +/* 客户端发起重协商握手,服务端则可以通过HITLS_Read进行处理 */ +ret = HITLS_Connect(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Connect failed, ret = 0x%x.\n", ret); + goto exit; +} +/* 重协商结束继续应用层交互 */ +``` + +**服务端示例** + +```c +/* 应用层数据交互 */ +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +const uint8_t sndBuf[] = "Hi, this is server\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +/* 服务端进入重协商状态 */ +ret = HITLS_Renegotiate(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Renegotiate error:error code:%d\n", ret); + goto exit; +} +/* 服务端发起重协商握手,客户端则可以通过HITLS_Read进行处理 */ +ret = HITLS_Accept(ctx); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Accept failed, ret = 0x%x.\n", ret); + goto exit; +} +/* 重协商结束继续应用层交互 */ +``` + +### TLS1.3密钥更新示例 + +TLS1.3支持建链后密钥更新能力,其涉及函数如下: + +```c +/** + * @brief 设置keyUpdate类型,并发送keyUpdate消息给对端 + */ +int32_t HITLS_KeyUpdate(HITLS_Ctx *ctx, uint32_t updateType); +``` + +其支持两种`KeyUpdate`类型,包括: + +```c +HITLS_UPDATE_NOT_REQUESTED = 0, // 要求对端不回复keyUpdate消息 +HITLS_UPDATE_REQUESTED = 1, // 要求对端回复KeyUpdate消息 +``` + +**客户端示例**: + +```c +/* 应用层数据交互 */ +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +const uint8_t sndBuf[] = "Hi, this is server\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +/* 客户端发起KeyUpdate消息,要求对端不回复,对端则通过HITLS_Read进行处理 */ +ret = HITLS_KeyUpdate(ctx, HITLS_UPDATE_NOT_REQUESTED); +if (ret != HITLS_SUCCESS) { + printf("HITLS_KeyUpdate error:error code:%d\n", ret); + goto exit; +} +/* keyUpdate完毕 */ +``` + +**服务端示例**: + +```c +/* 应用层数据交互 */ +uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; +uint32_t readLen = 0; +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +const uint8_t sndBuf[] = "Hi, this is server\n"; +ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; +} +/* 服务端发起KeyUpdate消息,要求对端回复,对端通过HITLS_Read进行处理,并回复KeyUpdate消息 */ +ret = HITLS_KeyUpdate(ctx, HITLS_UPDATE_REQUESTED); +if (ret != HITLS_SUCCESS) { + printf("HITLS_KeyUpdate error:error code:%d\n", ret); + goto exit; +} +/* HITLS_Read中处理对端回复KeyUpdate消息 */ +ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); +if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; +} +/* keyUpdate完毕 */ +``` + + diff --git a/docs/zh/5_开发指南/3_API参考.md b/docs/zh/5_开发指南/3_API参考.md new file mode 100644 index 00000000..11343f3d --- /dev/null +++ b/docs/zh/5_开发指南/3_API参考.md @@ -0,0 +1,3 @@ +API参考[请见](https://apidoc.openhitls.net/modules.html) + + diff --git a/docs/zh/6_附录/1_术语列表.md b/docs/zh/6_附录/1_术语列表.md new file mode 100644 index 00000000..5d137c8a --- /dev/null +++ b/docs/zh/6_附录/1_术语列表.md @@ -0,0 +1,52 @@ +|名称|英文全称|解释| +|-|-|-| +|AES|Advanced Encryption Standard|一种对称加密算法,被广泛应用于数据加密、网络安全等领域。AES算法的密钥长度可以是128位、192位或256位。| +|ARM|Advanced RISC Machines|一种处理器架构,被广泛应用于移动设备、嵌入式系统等领域。ARM处理器具有低功耗、高性能等特点。| +|Curl|Curl|一种开源的网络传输工具,支持多种协议(如HTTP、FTP、SMTP等),被广泛应用于Web开发、测试等领域。| +|DH|Diffie-Hellman|一种密钥交换算法,被广泛应用于网络安全、VPN等领域。DH算法的密钥长度可以是1024位、2048位或4096位。| +|DRBG|Deterministic Random Byte Generator|一种伪随机数生成器,用于生成加密算法中的密钥、初始化向量等随机数。| +|DSA|Digital Signature Algorithm|一种数字签名算法,被广泛应用于数字签名、身份认证等领域。DSA算法的密钥长度可以是1024位、2048位或3072位。| +|DTLS|Datagram Transport Layer Security|一种数据包传输层安全协议,用于保护数据包通信的安全性和完整性,广泛应用在VoIP、视频会议等实时通信场景中。| +|EC|Elliptic Curve|一种非对称加密算法,基于椭圆曲线数学理论,被广泛应用于数字签名、密钥交换等领域。| +|HKDF|HMAC-based Extract-and-Expand Key Derivation Function|一种密钥派生函数,用于从一个长密钥派生出多个子密钥。HKDF算法基于HMAC算法。| +|HMAC|Hash-based Message Authentication Code|一种消息认证码,用于保证消息的完整性和真实性。HMAC算法基于哈希算法和密钥。| +|Java|Java|一种跨平台的编程语言,被广泛应用于Web开发、移动应用等领域。Java具有面向对象、安全性等特点。| +|MD5|Message-Digest Algorithm 5|一种哈希算法,被广泛应用于数字签名、消息认证等领域。MD5算法的输出长度为128位。| +|Nginx|Engine X|一种高性能的Web服务器和反向代理服务器,被广泛应用于互联网、移动应用等领域。Nginx具有高并发、低内存消耗等特点。| +|PBKDF2|Password-Based Key Derivation Function 2|一种密钥派生函数,用于从用户密码派生出加密算法中的密钥。| +|Python|Python|一种高级的编程语言,被广泛应用于数据分析、人工智能等领域。Python具有简洁、易读等特点。| +|QUIC|Quick UDP Internet Connections|一种基于UDP协议的新型网络传输协议,被广泛应用于Web、移动应用等领域。QUIC协议支持加密、多路复用、0-RTT等特性。| +|RAM|Random Access Memory|一种计算机内部存储器,用于临时存储数据和程序。RAM是易失性存储器,断电后存储的数据会丢失。| +|ROM|Read-Only Memory|一种计算机内部存储器,用于存储固化的程序和数据。ROM是非易失性存储器,断电后存储的数据不会丢失。| +|RSA|Rivest-Shamir-Adleman|一种非对称加密算法,被广泛应用于数字签名、密钥交换等领域。RSA算法的密钥长度可以是1024位、2048位或4096位。| +|SCRYPT|Scrypt|一种密钥派生函数,用于从一个长密钥派生出多个子密钥。SCRYPT算法基于PBKDF2算法。| +|SDF|Security Domain Function|一种密码安全标准接口,定义了密码设备(如密码芯片卡)与终端设备之间的通信协议和数据格式,包括密钥管理、认证、数据传输等方面的内容。SDF接口规范的实现可以确保密码设备的安全性和可靠性,主要应用于金融领域,用于保障银行卡等支付卡的安全性。| +|SHA2|Secure Hash Algorithm 2|一种哈希算法,被广泛应用于数字签名、消息认证等领域。SHA2算法包括SHA-224、SHA-256、SHA-384、SHA-512等多种变种。| +|SHA3|Secure Hash Algorithm 3|一种哈希算法,是SHA2算法的继任者,被广泛应用于数字签名、消息认证等领域。SHA3算法包括SHA3-224、SHA3-256、SHA3-384、SHA3-512等多种变种。| +|SKF|Security Domain Function|一种密码安全标准接口,定义了密码设备(如密码芯片卡)与终端设备之间的通信协议和数据格式,包括密钥管理、认证、数据传输等方面的内容。SKF接口规范的实现可以确保密码设备的安全性和可靠性,应用于密码设备(如密码芯片卡)与终端设备之间的安全通信,包括密钥管理、认证、数据传输等方面。| +|SM2|ShangMi-2|一种非对称加密算法,是中国政府推荐的加密算法之一。SM2算法的密钥长度为256位。| +|SM3|ShangMi-3|一种哈希算法,是中国政府推荐的哈希算法之一。SM3算法的输出长度为256位。| +|SM4|ShangMi-4|一种对称加密算法,是中国政府推荐的加密算法之一。SM4算法的密钥长度为128位。| +|TLCP|Transport Layer Cryptography Protocol|一种传输层密码学协议,用于保护网络通信的安全性和完整性,广泛应用在中国的Web、电子邮件等安全通信场景中。| +|TLS|Transport Layer Security|一种传输层安全协议,用于保护网络通信的安全性和完整性,广泛应用在Web、电子邮件等安全通信场景中。| +|TLS会话|TLS Session|在TLS握手完成后,客户端和服务器之间建立的安全会话,用于加密和保护通信数据。会话可以在多个TLS连接中重用,以提高性能。| +|TLS握手|TLS Handshake|在TLS通信开始之前,客户端和服务器之间进行的握手过程,包括协商加密算法、验证双方身份、生成会话密钥等步骤。| +|TLS证书|TLS Certificate|用于在TLS握手过程中验证服务器和客户端身份的数字证书。服务器通常具有公钥证书,客户端可以验证该证书的真实性和可信度。| +|X.509|T-REC-X.509|一种数字证书标准,用于证明公钥的合法性和身份的真实性。X.509证书包括公钥、证书颁发者、有效期等信息。| +|X86|Intel 80x86|一种处理器架构,被广泛应用于个人电脑、服务器等领域。x86处理器具有高性能、兼容性等特点。| +|安全参数协商|Man-in-the-Middle Attack|TLS握手过程中,客户端和服务器协商加密算法、密钥交换算法、证书验证方式等安全参数的过程。| +|安全重协商|Secure Renegotiation|在TLS握手完成后,由客户端或服务端发起安全重协商,重新进行一次握手流程来协商新的密钥。| +|对称加密|Symmetric Encryption|使用相同的密钥进行加密和解密的算法,也被称为共享密钥加密。| +|防重放攻击|Replay Attack|攻击者在通信中重复或延迟发送已经通过认证的消息,以欺骗或破坏通信的完整性。| +|分组密码|Block Cipher|在TLS中用于加密和解密数据的对称加密算法。常见的分组密码算法包括AES(Advanced Encryption Standard)和3DES(Triple Data Encryption Standard)。| +|服务器名称指示|Server Name Indication|是TLS的一个扩展协议,在CLIENTHELLO报文中客户端指定服务端要连接的主机名称。| +|公钥加密|Public Key Encryption|使用公钥和私钥配对进行加密和解密的算法。公钥用于加密,私钥用于解密。常见的公钥加密算法包括RSA和ECC。| +|哈希函数|Hash Function|接受一个输入,并将其映射到固定长度的输出。哈希函数具有防碰撞和不可逆的特性。常见的哈希函数包括MD5、SHA-1和SHA-256。| +|会话恢复|Session Resumption|在完成一次握手之后,保存TLS会话信息,在第二次握手使用第一次的会话信息来恢复链接。| +|流密码|Stream Cipher|在TLS中用于加密和解密数据的对称加密算法,将输入与密钥流进行异或运算以生成密文流。常见的流密码算法包括RC4和ChaCha20。| +|密钥交换|Key Exchange|为双方提供一个安全的通信渠道,以便他们可以安全地共享密钥,以用于对称加密。| +|密钥交换算法|Key Exchange Algorithm|在TLS握手过程中使用的算法,用于在客户端和服务器之间安全地交换加密密钥。常见的密钥交换算法包括RSA、Diffie-Hellman和Elliptic Curve Diffie-Hellman(ECDH)。| +|密钥长度|Key Length|用于衡量密码算法强度的一个指标,一般来说,密钥长度越长,算法越安全。| +|数字签名|Digital Signature|使用私钥对消息进行加密来验证消息的来源和完整性。可以通过公钥对数字签名进行验证。| +|应用层协议协商|Application Layer Protocol Negotiation|是TLS的一个扩展协议, 是得客户端和服务端在协商TLS协议的同时协商应用层协议。| +|中间人攻击|Man-in-the-Middle Attack|一种攻击方式,攻击者在TLS通信中插入自己作为中间人,并能够窃取或篡改通信数据。| diff --git a/docs/zh/6_附录/2_修订记录.md b/docs/zh/6_附录/2_修订记录.md new file mode 100644 index 00000000..dc0dfa50 --- /dev/null +++ b/docs/zh/6_附录/2_修订记录.md @@ -0,0 +1,7 @@ +# 修订记录 + +| 日期 | 版本 | 变更说明 | +| ---------- | ----------------- | -------------------------------- | +| 2024/5/15 | openHiTLS首个版本 | 首次发布alpha版本 | + + diff --git a/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/CommunicationApplications.png b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/CommunicationApplications.png new file mode 100644 index 00000000..e9079613 Binary files /dev/null and b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/CommunicationApplications.png differ diff --git a/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/LinkSetupProcess.png b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/LinkSetupProcess.png new file mode 100644 index 00000000..2b6a8d40 Binary files /dev/null and b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/LinkSetupProcess.png differ diff --git a/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/SecurityRenegotiationProcedure.png b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/SecurityRenegotiationProcedure.png new file mode 100644 index 00000000..ade10076 Binary files /dev/null and b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/SecurityRenegotiationProcedure.png differ diff --git a/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/TheFramework.png b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/TheFramework.png new file mode 100644 index 00000000..840f1c39 Binary files /dev/null and b/docs/zh/images/Developer Guide/Secure Communication Application Development Guide_figures/TheFramework.png differ diff --git a/docs/zh/images/User Guide/Test Guide_figures/TestCaseExecutionProcess.png b/docs/zh/images/User Guide/Test Guide_figures/TestCaseExecutionProcess.png new file mode 100644 index 00000000..15fde025 Binary files /dev/null and b/docs/zh/images/User Guide/Test Guide_figures/TestCaseExecutionProcess.png differ diff --git a/docs/zh/images/User Guide/Test Guide_figures/TestFrameworkDescription.png b/docs/zh/images/User Guide/Test Guide_figures/TestFrameworkDescription.png new file mode 100644 index 00000000..099bfe89 Binary files /dev/null and b/docs/zh/images/User Guide/Test Guide_figures/TestFrameworkDescription.png differ diff --git a/include/bsl/bsl_base64.h b/include/bsl/bsl_base64.h new file mode 100644 index 00000000..c827a636 --- /dev/null +++ b/include/bsl/bsl_base64.h @@ -0,0 +1,178 @@ +/* + * 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_H +#define BSL_BASE64_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define HITLS_BASE64_CTX_BUF_LENGTH 80 +#define HITLS_BASE64_CTX_LENGTH 48 +/* Input length (len) divided by 3, rounded up, multiplied by 4, then add the number of newline characters,and + add the length of the context buffer */ +#define HITLS_BASE64_ENCODE_LENGTH(len) \ + ((((len) + 2) / 3 * 4) + ((len) / HITLS_BASE64_CTX_LENGTH + 1) * 2 + HITLS_BASE64_CTX_BUF_LENGTH) +#define HITLS_BASE64_DECODE_LENGTH(len) (((len) + 3) / 4 * 3 + HITLS_BASE64_CTX_BUF_LENGTH) + +/* + * When writing, it makes all the data written on one line without a newline character at the end; + * When reading, it expects all data to be on one line (regardless of whether there is a trailing newline character) + */ +#define BSL_BASE64_FLAGS_NO_NEWLINE 0x01 + +typedef struct BASE64_ControlBlock BSL_Base64Ctx; + +/** + * @ingroup bsl_base64 + * @brief Encode the specified buffer into the base64 format. + * @par Description: The function converts the DER code to base64 format, + * In the case of the encoding is successful, The user needs to release the dstBuf memory after the dstBuf is + * used up. The user needs to allocate space dstBuf in advance. dstBufLen indicates the length of the allocate space. + * @attention None + * @param srcBuf [IN] Passed buff buffer. + * @param srcBufLen [IN] Input buff buffer length. + * @param dstBuf [OUT] Output buff buffer. + * @param dstBufLen [OUT] Number of encoded bytes excluding the terminator (a multiple of 4) + * @return Error code + */ +int32_t BSL_BASE64_Encode(const uint8_t *srcBuf, const uint32_t srcBufLen, char *dstBuf, uint32_t *dstBufLen); + +/** + * @ingroup bsl_base64 + * @brief Decode the specified buffer into the DER format. + * @par Description: This function converts the specified base64 format into the DER format, In the case of the + * decoding is successful, the user needs to release the dstBuf memory after the dstBuf is used up. + * @attention None + * @param srcBuf [IN] Passed buff buffer. + * @param srcBufLen [IN] Input buff buffer length. + * @param dstBufLen [OUT] Encoding length obtained after decoding. + * @param dstBuf [OUT] Encoding string obtained after decoding. + * @retval when success , return BSL_SUCCESS; Otherwise, return error code + */ +int32_t BSL_BASE64_Decode(const char *srcBuf, const uint32_t srcBufLen, uint8_t *dstBuf, uint32_t *dstBufLen); + +/** + * @ingroup bsl_base64 + * @brief Generate Stream Encoding Context. + * @par Description: generate BSL_Base64Ctx. + * @param ctx [IN] Base64 context + * @retval void + */ +BSL_Base64Ctx *BSL_BASE64_CtxNew(void); + +/** + * @ingroup bsl_base64 + * @brief Release the stream encoding context. + * @par Description: release BSL_Base64Ctx. + * @param ctx [IN] Base64 context + * @retval void + */ +void BSL_BASE64_CtxFree(BSL_Base64Ctx *ctx); + +/** + * @ingroup bsl_base64 + * @brief Clear stream encoding context. + * @par Description: clear BSL_Base64Ctx. + * @param ctx [IN] Base64 context + * @retval void + */ +void BSL_BASE64_CtxClear(BSL_Base64Ctx *ctx); + +/** + * @ingroup bsl_base64 + * @brief Initialize stream encoding. + * @par Description: initialize the context. + * @param ctx [IN] Base64 context + * @retval In the case of success, return BSL_SUCCESS; Otherwise, returned error code. + */ +int32_t BSL_BASE64_EncodeInit(BSL_Base64Ctx *ctx); + +/** + * @ingroup bsl_base64 + * @brief Encodes a specified buffer into the Base64 format. + * @par Description: If the length of the data to be encoded is less than one line or one block, + * the data is stored in encData of the context for the next input by user. Until one block is + * satisfied or we encountered the last line. + * @param srcBuf [IN] Passed buff buffer. + * @param srcBufLen [IN] Input buff buffer length. + * @param dstBuf [OUT] String obtained after encoding. + * @param dstBufLen [OUT] Length obtained after encoding. + * @retval In the case of success, return BSL_SUCCESS. Otherwise, returned error code. + */ +int32_t BSL_BASE64_EncodeUpdate(BSL_Base64Ctx *ctx, const uint8_t *srcBuf, uint32_t srcBufLen, + char *dstBuf, uint32_t *dstBufLen); + +/** + * @ingroup bsl_base64 + * @brief Encode the specified buffer into the Base64 format. + * @par Description: Encode the remaining characters stored in the context buffer. + * @param dstBufLen [OUT] Length obtained after encoding. + * @param dstBuf [OUT] String obtained after encoding. + * @retval In the case of success, return BSL_SUCCESS. Otherwise, returned error code. + */ +int32_t BSL_BASE64_EncodeFinal(BSL_Base64Ctx *ctx, char *dstBuf, uint32_t *dstBufLen); + +/** + * @ingroup bsl_base64 + * @brief Initialize stream decoding. + * @par Description: Initialize the context. + * @param ctx [IN] Base64 context + * @retval In the case of success, return BSL_SUCCESS. Otherwise, returned error code. + */ +int32_t BSL_BASE64_DecodeInit(BSL_Base64Ctx *ctx); + +/** + * @ingroup bsl_base64 + * @brief Decode the specified buffer into the DER format. + * @par Description: Block decoding is performed for each full block, + * Otherwise, the padding is less one block are placed in the context for decodeFinal processing. + * @param srcBuf [IN] Passed buff buffer. + * @param srcBufLen [IN] Input buff buffer length. + * @param dstBuf [OUT] String obtained after decoding. + * @param dstBufLen [OUT] Length obtained after decoding. + * @retval In the case of success, return BSL_SUCCESS; Otherwise, returned error code. + */ +int32_t BSL_BASE64_DecodeUpdate(BSL_Base64Ctx *ctx, const char *srcBuf, const uint32_t srcBufLen, + uint8_t *dstBuf, uint32_t *dstBufLen); + +/** + * @ingroup bsl_base64 + * @brief Decode the specified buffer into the DER format. + * @par Description: Decode the remaining characters stored in the context buffer. + * @param dstBufLen [OUT] Length obtained after decoding. + * @param dstBuf [OUT] String obtained after decoding. + * @retval In the case of success, return BSL_SUCCESS. Otherwise, returned error code. + */ +int32_t BSL_BASE64_DecodeFinal(BSL_Base64Ctx *ctx, uint8_t *dstBuf, uint32_t *dstBufLen); + +/** + * @ingroup bsl_base64 + * @brief Set the flag + * @par Description: sets the context flags + * @param ctx [IN] Input context. + * @param flags [IN] Flags to be set. + * @retval In the case of success, return BSL_SUCCESS; Otherwise, returned error code. + */ +int32_t BSL_BASE64_SetFlags(BSL_Base64Ctx *ctx, uint32_t flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/bsl/bsl_err.h b/include/bsl/bsl_err.h new file mode 100644 index 00000000..ba92a7c1 --- /dev/null +++ b/include/bsl/bsl_err.h @@ -0,0 +1,279 @@ +/* + * 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 + * @brief Base Support Layer + */ + +/** + * @defgroup bsl_err + * @ingroup bsl + * @brief error module + */ + +#ifndef BSL_ERR_H +#define BSL_ERR_H + +#include +#include +#include "bsl_errno.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_err + * @brief Start value of the customized level-1 error module. + * + * Start value of the customized level-1 error module. The value 0x80 is 128. + */ +#define BSL_ERR_NEW_MODULE 0x80 + +/** + * @ingroup bsl_err + * @brief Initialize Error code module. + * + * The user must call this interface to initialize. + * + * @attention NONE + * @retval #BSL_SUCCESS, error code module is successfully initialized. + * @retval #BSL_MALLOC_FAIL, memory space is insufficient and thread lock space cannot be applied for. + * @retval #BSL_SAL_ERR_UNKNOWN, thread lock initialization failed. + */ +int32_t BSL_ERR_Init(void); + +/** + * @ingroup bsl_err + * @brief Error code module deinitialization. + * + * Called by the user when the process exits. + * + * @attention none + */ +void BSL_ERR_DeInit(void); + +/** + * @ingroup bsl_err + * @brief Delete the error stack + * + * Delete the error stack, which is called when a process or thread exits. + * + * @attention This function must be called when the thread exits. Otherwise, memory leakage occurs. + * @param isRemoveAll [IN] Indicates whether to delete all error stacks. + * The value is true when a process exits and false when a thread exits. + */ +void BSL_ERR_RemoveErrorStack(bool isRemoveAll); + +/** + * @ingroup bsl_err + * @brief Obtains the error code of the last push in the error stack. + * + * This API is called when an error occurs on a HiTLS interface to obtain the error code. + * The interface can be called continuously. The error code returned each time forms + * the error stack of the interface until BSL_SUCCESS is returned. + * + * @attention None. + * @retval Error code. The most significant 16 bits indicate the ID of the module where the error occurs, + * and the least significant 16 bits indicate the cause number. + */ +int32_t BSL_ERR_GetLastError(void); + +/** + * @ingroup bsl_err + * @brief Obtains the error code, file name, and line number of the last push message in the error stack. + * + * When an error occurs in a HiTLS interface, the user obtains an error code, file name, and line + * number. The obtained information is deleted from the error stack. + * The interface can be called continuously. The error code returned each time forms the error stack of + * the interface until BSL_SUCCESS is returned. + * + * @attention If either of the two parameters is null, the file name and line number cannot be obtained + * @param file [OUT] Obtains the name of the file where the error occurs, excluding the directory path + * @param lineNo [OUT] Obtain the line number of the file where the error occurs + * @retval Error code. The most significant 16 bits indicate the ID of the module where the error occurs, + * and the least significant 16 bits indicate the cause number. + */ +int32_t BSL_ERR_GetLastErrorFileLine(const char **file, uint32_t *lineNo); + +/** + * @ingroup bsl_err + * @brief Obtain the error code, file name, and line number of the last push message in the error stack. + * + * When an error occurs on a HiTLS interface, the user obtains an error code, file name, and line number. + * The obtained information is not deleted from the error stack. + * + * @attention If either of the two parameters is null, the file name and line number cannot be obtained. + * @param file [OUT] Obtains the name of the file where the error occurs, excluding the directory path. + * @param lineNo [OUT] Obtain the line number of the file where the error occurs. + * @retval Error code. The most significant 16 bits indicate the ID of the module where the error occurs, + * and the least significant 16 bits indicate the cause number. + */ +int32_t BSL_ERR_PeekLastErrorFileLine(const char **file, uint32_t *lineNo); + +/** + * @ingroup bsl_err + * @brief Obtain the earliest push error code in the error stack. + * + * This API is called when an error occurs on a HiTLS API to obtain the error code. + * The API can be called all the time. + * The error code returned each time forms the error stack of the interface until BSL_SUCCESS is returned. + * + * @attention None. + * @retval Error code. The most significant 16 bits indicate the ID of the module where the error occurs, + * and the least significant 16 bits indicate the cause number. + */ +int32_t BSL_ERR_GetError(void); + +/** + * @ingroup bsl_err + * @brief Obtain the error code, file name, and line number of the earliest push message in the error stack. + * + * The user calls this API after an error occurs on a HiTLS API to obtain an error code, + * file name, and line number. The obtained information will be deleted from the error stack. + * This API can be called continuously. The returned error code forms the error stack of the + * API until BSL_SUCCESS is returned. + * + * @attention If either of the two parameters is null, the file name and line number cannot be obtained. + * @param file [OUT] Obtains the name of the file where the error occurs, excluding the directory path. + * @param lineNo [OUT] Obtain the line number of the file where the error occurs. + * @retval Error code. The most significant 16 bits indicate the ID of the module where the error occurs, + * and the least significant 16 bits indicate the cause number. + */ +int32_t BSL_ERR_GetErrorFileLine(const char **file, uint32_t *lineNo); + +/** + * @ingroup bsl_err + * @brief Obtain the error code, file name, and line number of the earliest push message in the error stack. + * + * When an error occurs on a HiTLS interface, the user obtains an error code, file name, and line number. + * The obtained information is not deleted from the error stack. + * + * @attention If either of the two parameters is null, the file name and line number cannot be obtained. + * @param file [OUT] Obtains the name of the file where the error occurs, excluding the directory path. + * @param lineNo [OUT] Obtain the line number of the file where the error occurs. + * @retval Error code. The most significant 16 bits indicate the ID of the module where the error occurs, + * and the least significant 16 bits indicate the cause number. + */ +int32_t BSL_ERR_PeekErrorFileLine(const char **file, uint32_t *lineNo); + +/** + * @ingroup bsl_err + * @brief Clear the error stack. + * + * If an error is detected after the HiTLS API is called, if the error information is ignored, + * call this API to clear the error information before calling the HiTLS API again. + * + * @attention None + */ +void BSL_ERR_ClearError(void); + +/** + * @ingroup bsl_err + * @brief Add error description. + */ +typedef struct { + int32_t error; /**< Error code */ + const char *string; /**< Description string corresponding to an error code. */ +} BSL_ERR_Desc; + +/** + * @ingroup bsl_err + * @brief Add an error description string to an error code. + * + * The error description string is added to the error code. + * The error description can be extended to the user side. + * + * @attention This function is thread-safe. It stores only string pointers and does not perform deep + * copy. The same error can be added multiple times and overwrites the previously added error. + * @param descList [IN] BSL_ERR_Desc array + * @param num [IN] Length of descList + * @retval #BSL_SUCCESS. + * @retval For details, see bsl_errno.h + */ +int32_t BSL_ERR_AddErrStringBatch(const BSL_ERR_Desc *descList, uint32_t num); + +/** + * @ingroup bsl_err + * @brief Delete the error description + * + * The error description is deleted. + * If BSL_ERR_AddErrStringBatch is called, you need to use this API to release the memory. + * + * @attention This API must be called when a process exits. + * Otherwise, memory leakage occurs. Called before releasing the lock. + */ +void BSL_ERR_RemoveErrStringBatch(void); + +/** + * @ingroup bsl_err + * @brief Obtain the error description string based on the error code. + * + * Obtain the corresponding error description string based on the error code. + * + * @attention None + * @param error [IN] Error code + * @retval Error description + */ +const char *BSL_ERR_GetString(int32_t error); + +/** + * @ingroup bsl_err + * @brief Set the pop-up flag at the level of the current error stack. + * + * Set the pop-up flag. + * + * @attention none + * @retval #BSL_ERR_ERR_ACQUIRE_WRITE_LOCK_FAIL, failed to obtain the write lock. + * @retval #BSL_ERR_ERR_NO_STACK, no error stack. + * @retval #BSL_ERR_ERR_NO_ERROR, no error. + * @retval #BSL_SUCCESS, the flag is set successfully. + */ +int32_t BSL_ERR_SetMark(void); + +/** + * @ingroup bsl_err + * @brief Pop to the marked error stack level and clear the mark + * + * Pop up to the error stack level of the mark and clear the mark + * + * @attention none + * @retval #BSL_ERR_ERR_ACQUIRE_WRITE_LOCK_FAIL, failed to obtain the write lock. + * @retval #BSL_ERR_ERR_NO_STACK, no error stack. + * @retval #BSL_ERR_ERR_NO_ERROR, no error. + * @retval #BSL_ERR_ERR_NO_Mark, no mark. + * @retval #BSL_SUCCESS, pop-up succeeded. + */ +int32_t BSL_ERR_PopToMark(void); + +/** + * @ingroup bsl_err + * @brief Clear the latest flag in the error stack. + * + * Clear the latest flag in the error stack. + * + * @attention None. + * @retval #BSL_ERR_ERR_ACQUIRE_WRITE_LOCK_FAIL, failed to obtain the write lock. + * @retval #BSL_ERR_ERR_NO_STACK, no error stack. + * @retval #BSL_SUCCESS, cleared successfully. + */ +int32_t BSL_ERR_ClearLastMark(void); + +#ifdef __cplusplus +} +#endif + +#endif // BSL_ERR_H diff --git a/include/bsl/bsl_errno.h b/include/bsl/bsl_errno.h new file mode 100644 index 00000000..2bc8bd76 --- /dev/null +++ b/include/bsl/bsl_errno.h @@ -0,0 +1,151 @@ +/* + * 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_errno + * @ingroup bsl + * @brief error number module + */ + +#ifndef BSL_ERRNO_H +#define BSL_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_errno + * @brief Return success + */ +#define BSL_SUCCESS 0 + +/** + * @ingroup bsl_errno + * + * Return values of the BSL module range from 0x03000001 to 0x03ffffff. + */ +enum BSL_ERROR { + /* Common return value start from 0x03000001. */ + BSL_NULL_INPUT = 0x03000001, /**< NULL input. */ + BSL_INTERNAL_EXCEPTION, /**< Error occurs when calling internal BSL functions */ + BSL_MALLOC_FAIL, /**< Error occurs when allocating memory */ + BSL_MEMCPY_FAIL, /**< Error occurs when calling memcpy_s. */ + BSL_INVALID_ARG, /**< Invalid arguments. */ + BSL_DUMP_FAIL, /**< Error occurs when duplicating memory */ + + /* The return value of the SAL submodule starts from 0x03010001. */ + BSL_SAL_ERR_UNKNOWN = 0x03010001, /**< Unknown error. */ + BSL_SAL_ERR_BAD_PARAM, /**< Parameter incorrect. */ + + BSL_SAL_ERR_FILE_OPEN, /**< Open file error. */ + BSL_SAL_ERR_FILE_READ, /**< File reading error. */ + BSL_SAL_ERR_FILE_WRITE, /**< File writing error. */ + BSL_SAL_ERR_FILE_LENGTH, /**< Obtaining the file length error. */ + BSL_SAL_ERR_FILE_TELL, /**< Error in obtaining the file pointer offset. */ + BSL_SAL_ERR_FILE_SEEK, /**< Failed to set pointer position of file. */ + BSL_SAL_ERR_FILE_SET_ATTR, /**< Setting file attribute failed. */ + BSL_SAL_ERR_FILE_GET_ATTR, /**< Error in obtaining file attributes. */ + BSL_SAL_FILE_NO_REG_FUNC, + + BSL_SAL_ERR_NET_SOCKCLOSE, /**< Error occured when closing a socket. */ + BSL_SAL_ERR_NET_SETSOCKOPT, /**< Error occured when setting a socket option. */ + BSL_SAL_ERR_NET_GETSOCKOPT, /**< Error occured when getting a socket option. */ + BSL_SAL_ERR_NET_LISTEN, /**< Error occured when listening a socket. */ + BSL_SAL_ERR_NET_BIND, /**< Error occured when binding a socket */ + BSL_SAL_ERR_NET_CONNECT, /**< Error occured when building a connection. */ + BSL_SAL_ERR_NET_IOCTL, /**< Error occured when calling ioctl. */ + BSL_SAL_NET_NO_REG_FUNC, + + BSL_SAL_TIME_NO_REG_FUNC, + + /* The return value of the LOG submodule starts from 0x03020001. */ + BSL_LOG_ERR_BAD_PARAM = 0x03020001, /**< Bad parameter. */ + + /* The return value of the TLV submodule starts from 0x03030001. */ + BSL_TLV_ERR_BAD_PARAM = 0x03030001, /**< Bad parameter. */ + BSL_TLV_ERR_NO_WANT_TYPE, /**< No TLV found. */ + + /* The return value of the ERR submodule starts from 0x03040001. */ + BSL_ERR_ERR_ACQUIRE_READ_LOCK_FAIL = 0x03040001, /**< Failed to obtain the read lock. */ + BSL_ERR_ERR_ACQUIRE_WRITE_LOCK_FAIL, /**< Failed to obtain the write lock. */ + BSL_ERR_ERR_NO_STACK, /**< Error stack is empty. */ + BSL_ERR_ERR_NO_ERROR, /**< Error stack is NULL. */ + BSL_ERR_ERR_NO_MARK, /**< Error stack has no mark. */ + + /* The return value of the UIO submodule starts from 0x03060001. */ + BSL_UIO_FAIL = 0x03050001, /**< Invalid parameters. */ + BSL_UIO_IO_EXCEPTION, /**< I/O is abnormal. */ + BSL_UIO_IO_BUSY, /**< I/O is busy. */ + BSL_UIO_REF_MAX, /**< The number of UIO objects has reached the maximum. */ + BSL_UIO_IO_EOF, /**< I/O object has reached EOF */ + BSL_UIO_UNINITIALIZED, /**< UIO object is uninitialized */ + + /* The return value of the LIST submodule starts from 0x03070001. */ + BSL_LIST_INVALID_LIST_CURRENT = 0x03060001, /**< Current node pointer is NULL */ + BSL_LIST_DATA_NOT_AVAILABLE, /**< Data of current node is NULL */ + BSL_LIST_FULL, /**< Number of nodes has reached its limit */ + BSL_LIST_ERR_CONCAT, + + BSL_ASN1_FAIL = 0x03070001, + BSL_ASN1_ERR_DECODE_BOOL, + BSL_ASN1_ERR_NO_CALLBACK, + BSL_ASN1_ERR_MAX_DEPTH, + BSL_ASN1_ERR_OVERFLOW, + BSL_ASN1_ERR_TAG_EXPECTED, + BSL_ASN1_ERR_DECODE_LEN, + BSL_ASN1_ERR_MAX_LEN_NUM, + BSL_ASN1_ERR_DECODE_INT, + BSL_ASN1_ERR_DECODE_BIT_STRING, + BSL_ASN1_ERR_DECODE_UTC_TIME, + BSL_ASN1_ERR_DECODE_TIME, + BSL_ASN1_ERR_DECODE_GENERAL_TIME, + BSL_ASN1_ERR_CHECK_TIME, + BSL_ASN1_ERR_EXCEED_LIST_DEPTH, + BSL_ASN1_ERR_MISMATCH_TAG, + BSL_ASN1_ERR_BUFF_NOT_ENOUGH, + BSL_ASN1_ERR_ENCODE_FAIL, + BSL_ASN1_ERR_ENCODE_ASN_LACK, + BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH, + BSL_ASN1_ERR_ENCODE_BOOL, + BSL_ASN1_ERR_ENCODE_INT, + BSL_ASN1_ERR_ENCODE_BIT_STRING, + BSL_ASN1_ERR_ENCODE_UTC_TIME, + BSL_ASN1_ERR_ENCODE_GENERALIZED_TIME, + + /* The return value of the BASE64 submodule starts from 0x030a0001. */ + BSL_BASE64_INVALID = 0x03080001, + BSL_BASE64_BUF_NOT_ENOUGH, + BSL_BASE64_DATA_NOT_ENOUGH, + BSL_BASE64_WRITE_FAILED, + BSL_BASE64_READ_FAILED, + BSL_BASE64_DATA_AFTER_PADDING, + BSL_BASE64_ILLEGALLY_MODIFIED, + BSL_BASE64_ENCODE_FAILED, + BSL_BASE64_DECODE_FAILED, + BSL_BASE64_HEADER, + BSL_BASE64_INVALID_CHARACTER, + BSL_BASE64_INVALID_ENCODE, + + BSL_PEM_INVALID = 0x03090001, + BSL_PEM_DATA_NOT_ENOUGH, + BSL_PEM_SYMBOL_NOT_FOUND, +}; + +#ifdef __cplusplus +} +#endif + +#endif // BSL_ERRNO_H diff --git a/include/bsl/bsl_init.h b/include/bsl/bsl_init.h new file mode 100644 index 00000000..e72a7006 --- /dev/null +++ b/include/bsl/bsl_init.h @@ -0,0 +1,58 @@ +/* + * 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_init + * @ingroup bsl + * @brief initialization + */ + +#ifndef BSL_INIT_H +#define BSL_INIT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_init + * @brief Initialize the BSL module. + * + * The user must call this interface to initialize. + * + * @attention None. + * @retval #BSL_SUCCESS, error code module is successfully initialized. + * @retval #BSL_MALLOC_FAIL, memory space is insufficient and thread lock space cannot be applied for. + * @retval #BSL_SAL_ERR_UNKNOWN, thread lock initialization failed. + */ +int32_t BSL_GLOBAL_Init(void); + +/** + * @ingroup bsl_init + * @brief Deinitialize the BSL module. + * + * The user calls this interface when the process exits. + * + * @attention None + */ +int32_t BSL_GLOBAL_DeInit(void); + +#ifdef __cplusplus +} +#endif + +#endif // BSL_INIT_H \ No newline at end of file diff --git a/include/bsl/bsl_list.h b/include/bsl/bsl_list.h new file mode 100644 index 00000000..553cb953 --- /dev/null +++ b/include/bsl/bsl_list.h @@ -0,0 +1,507 @@ +/* + * 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 + * @ingroup bsl + * @brief linked list + */ + +#ifndef BSL_LIST_H +#define BSL_LIST_H + +#include +#include "bsl_errno.h" +#include "bsl_sal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* for handling ASN.1 SET OF type */ + +/** + * @ingroup bsl_list + * + */ +typedef struct BslListNode { + struct BslListNode *prev; /**< The previous node in the list */ + struct BslListNode *next; /**< The next node in the list */ + void *data; /**< This must be the last field of this structure */ +} BslListNode; + +/** + * @ingroup bsl_list + * + */ +typedef struct BslList { + BslListNode *first; /**< The first node in the list */ + BslListNode *last; /**< The last node in the list */ + BslListNode *curr; /**< The current node in the list */ + int32_t count; /**< count of elements */ + int32_t dataSize; /**< Memory needed for each node data */ +} BslList; + +/** + * @ingroup bsl_list + * + * the enum for specifying whether to add the element before/after the + * current element. It is used in BSL_LIST_AddElement() + * @datastruct BSL_LIST_POS_BEFORE Indication to to add the element before the current element. + * @datastruct BSL_LIST_POS_AFTER Indication to to add the element after the current element. + * @datastruct BSL_LIST_POS_BEGIN Indication to to add the element at the beginning of the list. + * @datastruct BSL_LIST_POS_END Indication to to add the element at the end of the list. + */ +typedef enum { + BSL_LIST_POS_BEFORE, /**< Indication to to add the element before the current element */ + BSL_LIST_POS_AFTER, /**< Indication to to add the element after the current element */ + BSL_LIST_POS_BEGIN, /**< Indication to to add the element at the beginning of the list */ + BSL_LIST_POS_END /**< Indication to to add the element at the end of the list */ +} BslListPosition; + +/** + * @ingroup bsl_list + * + * This is a pointer to the list comparison function used in BSL_LIST_Search function. + * It takes two pointers and compares them based on a criteria. If the two are equal a zero is returned. + * If the first should preceed the second, a negative is returned. Else a positive value is returned. + */ +typedef int32_t (*BSL_LIST_PFUNC_CMP)(const void *, const void *); + +/** + * @ingroup bsl_list + * + * This is a pointer to the free function. + * The free function takes a pointer to data structure to be freed and must return void. + */ +typedef void (*BSL_LIST_PFUNC_FREE)(void *); + +/** + * @ingroup bsl_list + * + * This is a pointer to the Copy function. + * The copy function takes a pointer to data structure to be freed and must return void. + */ +typedef void *(*BSL_LIST_PFUNC_DUP)(const void *); + +/* + The following macros return the specified element of the list. They do + not change the current list pointer. + */ +/* returns the current element */ +#define BSL_LIST_CURR_ELMT(pList) ((pList) ? ((pList)->curr ? ((pList)->curr->data) : NULL) : NULL) + +/* returns the next element */ +#define BSL_LIST_NEXT_ELMT(pList) \ + ((pList) ? ((pList)->curr ? ((pList)->curr->next ? ((pList)->curr->next->data) : NULL) : NULL) : NULL) + +/* returns the previous element */ +#define BSL_LIST_PREV_ELMT(pList) \ + ((pList) ? ((pList)->curr ? ((pList)->curr->prev ? ((pList)->curr->prev->data) : NULL) : NULL) : NULL) + +/* returns the last element */ +#define BSL_LIST_LAST_ELMT(pList) ((pList) ? ((pList)->last ? ((pList)->last->data) : NULL) : NULL) + +/* returns the first element */ +#define BSL_LIST_FIRST_ELMT(pList) ((pList) ? ((pList)->first ? ((pList)->first->data) : NULL) : NULL) + +/* checks if the list is NULL */ +#define BSL_LIST_EMPTY(pList) (((pList) != NULL) ? ((pList)->count == 0) : 0) + +/* returns the number of nodes in the list */ +#define BSL_LIST_COUNT(pList) ((pList) ? ((pList)->count) : 0) + +/* checks if current node is the end */ +#define BSL_LIST_IS_END(pList) ((pList) ? (NULL == (pList)->curr) : 0) + +/* checks if current node is the first one */ +#define BSL_LIST_IS_START(pList) ((pList) ? ((pList)->first == (pList)->curr) : 0) + +/* Get the next element */ +#define BSL_LIST_GET_NEXT(pList) ((pList) ? (BSL_LIST_Next(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL) + +/* Get the previous element */ +#define BSL_LIST_GET_PREV(pList) ((pList) ? (BSL_LIST_Prev(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL) + +/* Get the first element */ +#define BSL_LIST_GET_FIRST(pList) ((pList) ? (BSL_LIST_First(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL) + +/* Get the last element */ +#define BSL_LIST_GET_LAST(pList) ((pList) ? (BSL_LIST_Last(pList) ? BSL_LIST_CURR_ELMT(pList) : NULL) : NULL) + +/** + * @ingroup bsl_list + * + * Delete all the nodes in the list and then frees the header + */ +#define BSL_LIST_FREE(pList, pFreeFunc) \ + do { \ + BSL_LIST_DeleteAll((pList), pFreeFunc); \ + if (NULL != (pList)) { \ + BSL_SAL_Free(pList); \ + } \ + } while (0) + + +#define SEC_INT_ERROR (-2) + +/** + * @ingroup bsl_list + * + * This function sets the max element in BSL_LIST.Default value is 10000000 (10 Million). + * + * @param iMaxElements [IN] Max allowed element in BSL_LIST. It should be in range[0xffff, 0xfffffff] + * @retval #BSL_INVALID_ARG If input falls outside the range. + * @retval #BSL_SUCCESS If successful. + */ +int32_t BSL_LIST_SetMaxElements(int32_t iMaxElements); + +/** + * @ingroup bsl_list + * + * This function returns the max allowed elements in BSL_LIST. + * + * @retval int32_t Max configured elements in BSL_LIST + */ +int32_t BSL_LIST_GetMaxElements(void); + +/** + * @ingroup bsl_list + * + * This function creates a new node before, after or at the begining or end of the current node. If the list was already + * NULL, 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 pList [IN] The list + * @param pData [IN] The element to be added + * @param enPosition [IN] Whether the element is to be added before or after the list + * @retval The error code. + * @retval #BSL_SUCCESS If successful. + */ +int32_t BSL_LIST_AddElement(BslList *pList, void *pData, BslListPosition enPosition); + +/** + * @ingroup bsl_list + * + * This function deletes all the nodes of the list but does not delete the list header. + * + * @param pList [IN] The list + * @param pfFreeFunc [IN] The freefunction to free the data pointer in each node + */ +void BSL_LIST_DeleteAll(BslList *pList, BSL_LIST_PFUNC_FREE pfFreeFunc); + +/** + * @ingroup bsl_list + * + * This function deletes the current element of list. + * + * @param pList [IN] The list + * @param pfFreeFunc [IN] The pointer to the free function of data + */ +void BSL_LIST_DeleteCurrent(BslList *pList, BSL_LIST_PFUNC_FREE pfFreeFunc); + +/** + * @ingroup bsl_list + * + * This function detaches the current element from the list, the current node will be freed, but the data contained + * in the current node will not be freed.Also the pList->first, pList->curr and pList->last will be appropriately + * updated. If the current node is the last node, then pList->curr will point to its previous node after detachment, + * else it will point to its next node. + * + * @param pList [IN] The list + */ +void BSL_LIST_DetachCurrent(BslList *pList); + +/** + * @ingroup bsl_list + * + * 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. + * + * @param pList [IN] The list + * @param pSearchFor [IN] The element to be searched + * @param pSearcher [IN] The pointer to the comparison function of data + * @retval Void* The element which was found [Void*] + * @retval Void* If none found [NULL] + */ +void *BSL_LIST_Search(BslList *pList, const void *pSearchFor, BSL_LIST_PFUNC_CMP pSearcher, int32_t *pstErr); + +/** + * @ingroup bsl_list + * + * This function returns the node at the given index in the list, starting at 0. + * + * @param pList [IN] The list + * @param ulIndex [IN] The index in the list + * @retval Void* The element which was found [Void*] + * @retval Void* If none found [NULL] + */ +void *BSL_LIST_GetIndexNode(uint32_t ulIndex, BslList *pList); + +/** + * @ingroup bsl_list + * + * This function dups a list by copying the list by creating a copy of list + * and returns the destinaton list pointer. + * + * @param pSrcList [IN] The list + * @param pFuncCpy [IN] The dup function for the data in the node + * @param pfFreeFunc [IN] The pointer to the free function for the data in the node of data + * @retval BslList* The duplicated List pointer [BslList*] + * @retval BslList* If dup failed or memory allocation fails.[NULL] + */ +BslList *BSL_LIST_Copy(BslList *pSrcList, BSL_LIST_PFUNC_DUP pFuncCpy, BSL_LIST_PFUNC_FREE pfFreeFunc); + +/** + * @ingroup bsl_list + * + * This function sorts the list using the comparison function provided. + * + * @param pList [IN] The list + * @param pfCmp [IN] The comparison function + * @retval BslList* If unsuccessful [NULL] + * @retval BslList* If successful [The destination sorted list] + */ +BslList *BSL_LIST_Sort(BslList *pList, BSL_LIST_PFUNC_CMP pfCmp); + +/** + * @ingroup bsl_list + * + * This function is used to create a new list. + * + * @param dataSize [IN] Size of the data inside the list node + * @retval BslList* An NULL list [BslList*] + */ +BslList *BSL_LIST_New(int32_t dataSize); + +/** + * @ingroup bsl_list + * + * This function returns the data of the current element in the list. + * + * @param pstList [IN] Input list + * @retval void* Data at the current element in the list [void*] + * @retval void* If the current element does not exist in the list [NULL] + * @retval void* If memory allocation fails. [NULL] + */ +void *BSL_LIST_Curr(const BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function returns the data at the first element of the list. + * + * @param pstList [IN] the list + * @retval void* Data at the first element of the list [void*] + * @retval void* If the first element does not exist [NULL] + */ +void *BSL_LIST_First(BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function returns the data at the last element of the list. + * + * @param pstList [IN] The list + * @retval void* Data at the last element of the list [void*] + * @retval void* If the last element does not exist [NULL] + */ +void *BSL_LIST_Last(BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function advances the current pointer by one and returns the data address of the new + * current node. If the current pointer is off the list, the new current node + * will be the first node of the list (unless the list is NULL). + * + * @param pstList [IN] The list + * @retval void* Pointer to the next element in the list [void*] + * @retval void* If the next element does not exist [NULL] + */ +void *BSL_LIST_Next(BslList *pstList); + +/** + * @ingroup bsl_list + * + * backs up the current pointer by one and returns the data address of the new + * current node. If the current pointer is off the list, the new current node + * will be the last node of the list (unless the list is NULL). + * + * @param pstList [IN] The list + * @retval void* Pointer to the previous element in the list [void*] + * @retval void* If the previous element does not exist[NULL] + */ +void *BSL_LIST_Prev(BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function returns the index (starting a 0 for the first element) + * of the given element in the given list. + * Returns -1, if the element is not in the list. + * Assumes that the list node contains a single pointer. + * + * @param elmt [IN] The element whose index is to be retrieved + * @param pstList [IN] The list to which the element belongs to + * @retval int32_t The index of the specified element in the given list [int32_t] + * @retval int32_t If the element is not found in the list [-1] + */ +int32_t BSL_LIST_GetElmtIndex(const void *elmt, BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function is used to concatenate list 2 to list 1. + * + * @param pDestList [IN] The list to which the 2nd list is to be concatenated to. + * @param pSrcList [IN] The list which is to be concatenated. + * @retval BslList* The concatenated list. [BslList*] + */ +BslList *BSL_LIST_Concat(BslList *pDestList, const BslList *pSrcList); + +/** + * @ingroup bsl_list + * + * This function is used to free the Asn list. + * + * @param pstList [IN] list Pointer to the Asn list which has to be freed + * @retval void This function does not return any value. + */ +void BSL_LIST_FreeWithoutData(BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function is used to reverse the linked list. + * + * @param pstList [IN] Pointer to the list which has to be reversed + * @retval void This function does not return any value. + */ +void BSL_LIST_RevList(BslList *pstList); + +/** + * @ingroup bsl_list + * + * This function set the max qsort Size.Default value is 100000 + * + * @param uiQsortSize [IN] Max Buff Size. it should in range of [10000, 67108864] Default value is 100000 + * @retval int32_t BSL_SUCCESS on success BSL_INVALID_ARG on Failure. + */ +int32_t BSL_LIST_SetMaxQsortCount(uint32_t uiQsortSize); + +/** + * @ingroup bsl_list + * + * This function returns the MAX qsort Size + * + * @retval uint32_t Returns the max qsort Size. + */ +uint32_t BSL_LIST_GetMaxQsortCount(void); + +/** + * @ingroup bsl_list + * + * Delete all the nodes in the list. + * But it does not delete the data pointers inside the list nodes. + * It is used only after sort to delete the input list to the sort function. + * + * @param pList [IN] The list. + */ +void BSL_LIST_DeleteAllAfterSort(BslList *pList); + +/** + * @ingroup bsl_list + * + * This function returns the first element of the list. + * + * @param list [IN] The list. + * @retval BslListNode* first element of the list [BslListNode*] + * @retval BslListNode* If the first element does not exist [NULL] + */ +BslListNode *BSL_LIST_FirstNode(const BslList *list); + +/** + * @ingroup bsl_list + * + * This function returns the data of the passed list node. + * + * @param pstNode [IN] The node. + * @retval void* Data of the passed list node. [void*] + * @retval void* If the data is not present in the list node. [NULL] + */ +void *BSL_LIST_GetData(const BslListNode *pstNode); + +/** + * @ingroup bsl_list + * + * This function advances the current reference pointer by one and returns the + * new current node. If the current reference pointer is off the list, + * the new current node will be the first node of the list + * (unless the list is NULL). + * + * @param pstList [IN] The list. + * @param pstListNode [IN] The list node. + * @retval BslListNode* Pointer to next element in the list. [void*] + * @retval BslListNode* If the next element does not exist. [NULL] + */ +BslListNode *BSL_LIST_GetNextNode(const BslList *pstList, const BslListNode *pstListNode); + +/** + * @ingroup bsl_list + * + * This function backs up the current reference pointer by one and returns the + * new current node. + * + * @param pstListNode [IN] The list node. + * @retval BslListNode* Pointer to the previous element in the list + * @retval BslListNode* If the previous element does not exist[NULL] + */ +BslListNode *BSL_LIST_GetPrevNode(const BslListNode *pstListNode); + +/** + * @ingroup bsl_list + * + * This function deletes the matching input node from the input list. + * + * @param pstList [IN] The list. + * @param pstListNode [IN] The current reference node. + * @param pfFreeFunc [IN] The pointer to the free function of data. + */ +void BSL_LIST_DeleteNode(BslList *pstList, const BslListNode *pstListNode, BSL_LIST_PFUNC_FREE pfFreeFunc); + +/** + * @ingroup bsl_list + * + * This function detaches the matching input node from the input list. + * The node will be freed but, the data contained in the + * node will not be freed, and also the pList->first, pList->curr, + * and pList->last will be appropriately updated. If the matching node + * is the last node, then pList->curr will point to its previous node + * after detachment, else it will point to its next node. + * + * @param pstList [IN] The list. + * @param pstListNode [in/out] when it is input parameter, it is the list node to be detached. + */ +void BSL_LIST_DetachNode(BslList *pstList, BslListNode **pstListNode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // BSL_LIST_H diff --git a/include/bsl/bsl_log.h b/include/bsl/bsl_log.h new file mode 100644 index 00000000..1972505a --- /dev/null +++ b/include/bsl/bsl_log.h @@ -0,0 +1,179 @@ +/* + * 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_log + * @ingroup bsl + * @brief log module + */ + +#ifndef BSL_LOG_H +#define BSL_LOG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_log + * + * Audit log level + */ +#define BSL_LOG_LEVEL_SEC 0U + +/** + * @ingroup bsl_log + * + * Emergency log level + */ +#define BSL_LOG_LEVEL_FATAL 1U + +/** + * @ingroup bsl_log + * + * Error log level + */ +#define BSL_LOG_LEVEL_ERR 2U + +/** + * @ingroup bsl_log + * + * Warning log level + */ +#define BSL_LOG_LEVEL_WARN 3U + +/** + * @ingroup bsl_log + * + * Information log level + */ +#define BSL_LOG_LEVEL_INFO 4U + +/** + * @ingroup bsl_log + * + * Debug log level + */ +#define BSL_LOG_LEVEL_DEBUG 5U + +/** + * @ingroup bsl_log + * + * HiTLS version string + */ +#ifndef OPENHITLS_VERSION_S +#define OPENHITLS_VERSION_S "openHiTLS 0.1.0 alpha1" +#endif + +#ifndef OPENHITLS_VERSION_I +#define OPENHITLS_VERSION_I 0x00001000U +#endif + +#define HITLS_VERSION_LEN 150 + +/** + * @ingroup bsl_log + * @brief Obtain the openHiTLS version string. + * + * @attention The length of the received version string must be greater than or equal to HITLS_VERSION_LEN. + * @param version [OUT] openHiTLS current version string. + * @param versionLen [IN/OUT] String length of the current openHiTLS version. + * @retval #BSL_SUCCESS, if success. + * @retval #BSL_LOG_ERR_MEMCPY, memory copy failure. + */ +int32_t BSL_LOG_GetVersion(char *version, uint32_t *versionLen); + +/** + * @ingroup bsl_log + * @brief Obtain the openHiTLS version number. + * + * @retval openHiTLS version number. + */ +uint32_t BSL_LOG_GetVersionNum(void); + +/** + * @ingroup bsl_log + * @brief Binlog type, other types can be extended. + */ +#define BSL_LOG_BINLOG_TYPE_RUN 0x01 + +/** + * @ingroup bsl_log + * @brief Fixed-length callback type of binlogs. + * + * The function format of this type cannot contain %s, the number of parameters is less than four, add 0s. + * More than four parameters must be called multiple times. + */ +typedef void (*BSL_LOG_BinLogFixLenFunc)(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4); + +/** + * @ingroup bsl_log + * @brief Callback type for variable-length binlogs. + * + * This type function format contains only one %s, If no %s exists, use BSL_LOG_BinLogFixLenFunc type. + * If there are more than one %s, call the interface multiple times. + */ +typedef void (*BSL_LOG_BinLogVarLenFunc)(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para); + +/** + * @ingroup bsl_log + * @brief Register the parameter type of the binlog callback function. + */ +typedef struct { + BSL_LOG_BinLogFixLenFunc fixLenFunc; /**< 4 parameter callback */ + BSL_LOG_BinLogVarLenFunc varLenFunc; /**< 1 parameter callback */ +} BSL_LOG_BinLogFuncs; + +/** + * @ingroup bsl_log + * @brief Set the fixed-length and variable-length callback function for binlogs. + * + * @attention The input parameter can be NULL. + * @param funcs [IN] Callback function pointer collection of the binlog. + * The parameter cannot be null, but the member of the structure can be null. + * @retval #BSL_SUCCESS. + */ +int32_t BSL_LOG_RegBinLogFunc(const BSL_LOG_BinLogFuncs *funcs); + +/** + * @ingroup bsl_log + * @brief Set the level of binlogs. + * + * @attention The level must be valid. + * @param level [IN] Level of the binlogs. The valid values are BSL_LOG_LEVEL_SEC, BSL_LOG_LEVEL_FATAL, + * BSL_LOG_LEVEL_ERR, BSL_LOG_LEVEL_WARN, BSL_LOG_LEVEL_INFO, BSL_LOG_LEVEL_DEBUG + * @retval #BSL_SUCCESS. + * @retval #BSL_LOG_ERR_BAD_PARAM, invalid input parameter. + */ +int32_t BSL_LOG_SetBinLogLevel(uint32_t level); + +/** + * @ingroup bsl_log + * @brief Obtain the level of binlogs. + * + * @retval Level of the binlog. The value can be BSL_LOG_LEVEL_SEC, BSL_LOG_LEVEL_FATAL, BSL_LOG_LEVEL_ERR, + * BSL_LOG_LEVEL_WARN, BSL_LOG_LEVEL_INFO, BSL_LOG_LEVEL_DEBUG + */ +uint32_t BSL_LOG_GetBinLogLevel(void); + +#ifdef __cplusplus +} +#endif + +#endif // BSL_LOG_H diff --git a/include/bsl/bsl_obj.h b/include/bsl/bsl_obj.h new file mode 100644 index 00000000..2d6a5612 --- /dev/null +++ b/include/bsl/bsl_obj.h @@ -0,0 +1,271 @@ +/* + * 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_obj + * @ingroup bsl + * @brief object module + */ + +#ifndef BSL_OBJ_H +#define BSL_OBJ_H + +#include +#include +#include "bsl_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_obj + * All algorithm ID + */ +typedef enum { + BSL_CID_UNKNOWN = 0, /**< Unknown alg id */ + + /* Algorithm cids from symmetric algorithm */ + // chacha + BSL_CID_CHACHA20_POLY1305 = 1, + + // aes + BSL_CID_AES128_CBC = 16, /**< identifies AES-128 algorithm in CBC mode */ + BSL_CID_AES128_OFB, /**< identifies AES-128 algorithm in OFB mode */ + BSL_CID_AES128_CFB, /**< identifies AES-128 algorithm in CFB mode */ + BSL_CID_AES192_CBC, /**< identifies AES-192 algorithm in CBC mode */ + BSL_CID_AES192_OFB, /**< identifies AES-192 algorithm in OFB mode */ + BSL_CID_AES192_CFB, /**< identifies AES-192 algorithm in CFB mode */ + BSL_CID_AES256_CBC, /**< identifies AES-256 algorithm in CBC mode */ + BSL_CID_AES256_OFB, /**< identifies AES-256 algorithm in OFB mode */ + BSL_CID_AES256_CFB, /**< identifies AES-256 algorithm in CFB mode */ + BSL_CID_AES128_GCM, /**< Identifies the AES128 algorithm in GCM mode */ + BSL_CID_AES192_GCM, /**< Identifies the AES128 algorithm in GCM mode */ + BSL_CID_AES256_GCM, /**< Identifies the AES256 algorithm in GCM mode */ + BSL_CID_AES128_CTR, /**< Identifies the AES128 algorithm in CTR mode */ + BSL_CID_AES192_CTR, /**< Identifies the AES128 algorithm in CTR mode */ + BSL_CID_AES256_CTR, /**< Identifies the AES128 algorithm in CTR mode */ + BSL_CID_AES128_CCM, + BSL_CID_AES192_CCM, + BSL_CID_AES256_CCM, + + // sm4 + BSL_CID_SM4_XTS = 116, + BSL_CID_SM4_CBC, + BSL_CID_SM4_CTR, + BSL_CID_SM4_GCM, + BSL_CID_SM4_CFB, + BSL_CID_SM4_OFB, + + /* asymmetrical algorithm */ + BSL_CID_RSA = 5001, /**< identifies the RSA algorithm */ + BSL_CID_RSASSAPSS, + BSL_CID_MD5WITHRSA, + BSL_CID_SHA1WITHRSA, + BSL_CID_SHA224WITHRSAENCRYPTION, + BSL_CID_SHA256WITHRSAENCRYPTION, + BSL_CID_SHA384WITHRSAENCRYPTION, + BSL_CID_SHA512WITHRSAENCRYPTION, + BSL_CID_SM3WITHRSAENCRYPTION, + BSL_CID_DSA = 5051, /**< identifies the DSA algorithm */ + BSL_CID_DSAWITHSHA1, + BSL_CID_DSAWITHSHA224, + BSL_CID_DSAWITHSHA256, + BSL_CID_DSAWITHSHA384, + BSL_CID_DSAWITHSHA512, + BSL_CID_ECDSA = 5101, /**< identifies the ECDSA algorithm */ + BSL_CID_ECDSAWITHSHA1, + BSL_CID_ECDSAWITHSHA224, + BSL_CID_ECDSAWITHSHA256, + BSL_CID_ECDSAWITHSHA384, + BSL_CID_ECDSAWITHSHA512, + BSL_CID_SM2 = 5151, /**< identifies Chinese standard of SM2 */ + BSL_CID_SM2DSAWITHSM3, + BSL_CID_SM2DSAWITHSHA1, + BSL_CID_SM2DSAWITHSHA256, + + BSL_CID_DH = 5201, /**< identifies the Diffie-Hellman algorithm */ + BSL_CID_ECDH = 5216, /**< identifies the EC Diffie-Hellman algorithm */ + BSL_CID_ED25519 = 5261, /**< Identifies ED25519 algorithm */ + BSL_CID_X25519 = 5276, /**< Identifies X25519 algorithm */ + BSL_CID_PAILLIER = 5291, /**< identifies the Paillier algorithm */ + + /* hash algorithm */ + BSL_CID_MD4 = 10001, /**< identifies MD4 hash algorithm */ + BSL_CID_MD5, /**< identifies the MD5 hash algorithm */ + BSL_CID_SHA1, /**< identifies the SHA1 hash algorithm */ + BSL_CID_SHA224, /**< identifies the SHA224 hash algorithm */ + BSL_CID_SHA256, /**< identifies the SHA256 hash algorithm */ + BSL_CID_SHA384, /**< identifies the SHA384 hash algorithm */ + BSL_CID_SHA512, /**< identifies the SHA512 hash algorithm */ + BSL_CID_SHA3_224, + BSL_CID_SHA3_256, + BSL_CID_SHA3_384, + BSL_CID_SHA3_512, + BSL_CID_SHAKE128, + BSL_CID_SHAKE256, + BSL_CID_SM3, /**< identifies SM3 hash algorithm */ + + /* Message authentication code algorithm */ + // hmac + BSL_CID_HMAC_MD5 = 10501, /**< identifies hmac with MD5 */ + BSL_CID_HMAC_SHA1, /**< identifies hmac with SHA1 */ + BSL_CID_HMAC_SHA224, /**< identifies hmac with SHA224 */ + BSL_CID_HMAC_SHA256, /**< identifies hmac with SHA256 */ + BSL_CID_HMAC_SHA384, /**< identifies hmac with SHA384 */ + BSL_CID_HMAC_SHA512, /**< identifies hmac with SHA512 */ + BSL_CID_HMAC_SHA3_224, /**< identifies hmac with SHA3_224 */ + BSL_CID_HMAC_SHA3_256, /**< identifies hmac with SHA3_256 */ + BSL_CID_HMAC_SHA3_384, /**< identifies hmac with SHA3_384 */ + BSL_CID_HMAC_SHA3_512, /**< identifies hmac with SHA3_512 */ + BSL_CID_HMAC_SM3, /**< identifies hmac with SM3 */ + + /* Random number algorithm */ + // DRBG + BSL_CID_RAND_SHA1 = 11001, + BSL_CID_RAND_SHA224, + BSL_CID_RAND_SHA256, + BSL_CID_RAND_SHA384, + BSL_CID_RAND_SHA512, + BSL_CID_RAND_HMAC_SHA1, + BSL_CID_RAND_HMAC_SHA224, + BSL_CID_RAND_HMAC_SHA256, + BSL_CID_RAND_HMAC_SHA384, + BSL_CID_RAND_HMAC_SHA512, + BSL_CID_RAND_AES128_CTR, + BSL_CID_RAND_AES192_CTR, + BSL_CID_RAND_AES256_CTR, + BSL_CID_RAND_AES128_CTR_DF, + BSL_CID_RAND_AES192_CTR_DF, + BSL_CID_RAND_AES256_CTR_DF, + + /* Key derivation algorithm */ + BSL_CID_SCRYPT = 11501, /**< Identifieds Scrypt KDF algorithm */ + BSL_CID_KDFTLS12, + + // hkdf + BSL_CID_HKDF, + + /* PKCS 5 */ + BSL_CID_PBKDF2 = 12001, /**< identifies PBKDF2 */ + BSL_CID_PBES2, + + /* standard constant international curve */ + // BRAINPOOL + BSL_CID_ECC_BRAINPOOLP256R1 = 12501, + BSL_CID_ECC_BRAINPOOLP384R1, + BSL_CID_ECC_BRAINPOOLP512R1, + + // SECP + BSL_CID_SECP384R1, /**< identifies NIST prime curve 384 */ + BSL_CID_SECP521R1, /**< identifies NIST prime curve 521 */ + + // RFC 3279 Curve Id + BSL_CID_PRIME256V1, /**< identifies RFC 3279 PRIME256V1 */ + + // NIST Curve + BSL_CID_NIST_PRIME224, /**< NIST Curve P-224 */ + + // standard constant sm series curve + BSL_CID_SM2PRIME256, /**< identifies sm2 curve */ + + /* standard constant prime */ + BSL_CID_DH_RFC2409_768 = 12651, + BSL_CID_DH_RFC2409_1024, + BSL_CID_DH_RFC3526_1536, + BSL_CID_DH_RFC3526_2048, + BSL_CID_DH_RFC3526_3072, + BSL_CID_DH_RFC3526_4096, + BSL_CID_DH_RFC3526_6144, + BSL_CID_DH_RFC3526_8192, + BSL_CID_DH_RFC7919_2048, + BSL_CID_DH_RFC7919_3072, + BSL_CID_DH_RFC7919_4096, + BSL_CID_DH_RFC7919_6144, + BSL_CID_DH_RFC7919_8192, + + /* rfc5280 */ + BSL_CID_CE = 127001, + BSL_CID_CE_AUTHORITYKEYID, + BSL_CID_CE_SUBJECTKEYID, + BSL_CID_CE_KEYUSAGE, + BSL_CID_CE_SUBJECTALTNAME, + BSL_CID_CE_BASICCONSTRAINTS, + BSL_CID_CE_EXTENDEDKEYUSAGE, + BSL_CID_CE_SERVERAUTH, + BSL_CID_CE_CLIENTAUTH, + BSL_CID_CE_CODESIGNING, + BSL_CID_CE_EMAILPROTECTION, + BSL_CID_CE_TIMESTAMPING, + BSL_CID_CE_OSCPSIGNING, + + /* rfc4055 */ + BSL_CID_MGF1 = 127301, + + /* rfc3279 */ + BSL_CID_EC_PUBLICKEY = 130001, + + /* Attributes: rfc4519, rfc5280 */ + BSL_CID_COMMONNAME = 130301, + BSL_CID_SURNAME, + BSL_CID_SERIALNUMBER, + BSL_CID_COUNTRYNAME, + BSL_CID_LOCALITYNAME, + BSL_CID_STATEORPROVINCENAME, + BSL_CID_STREETADDRESS, + BSL_CID_ORGANIZATIONNAME, + BSL_CID_ORGANIZATIONUNITNAME, + BSL_CID_TITLE, + BSL_CID_GIVENNAME, + BSL_CID_INITIALS, + BSL_CID_GENERATIONQUALIFIER, + BSL_CID_DNQUALIFIER, + BSL_CID_PSEUDONYM, + BSL_CID_DOMAINCOMPONENT, + BSL_CID_USERID, + BSL_CID_EMAILADDRESS, + + /* rfc 2985 attribute */ + BSL_CID_REQ_EXTENSION = 130601, + + /* rfc2315 */ + BSL_CID_CONTENTINFO = 130701, + BSL_CID_DATA, // kind of contentInfo + BSL_CID_SIGENEDDATA, + BSL_CID_ENCRYPTEDDATA, + BSL_CID_ENVELOPEDDATA, + + /* PKCS9 */ + BSL_CID_FRIENDLYNAME = 130801, + BSL_CID_LOCALKEYID, + BSL_CID_X509CERTIFICATE, + + /* rfc7292 */ + BSL_CID_KEYBAG = 130901, // kind of safeBag. + BSL_CID_PKCS8SHROUDEDKEYBAG, + BSL_CID_CERTBAG, + BSL_CID_CRLBAG, + BSL_CID_SECRETBAG, + BSL_CID_SAFECONTENT, + + BSL_CID_MAX, + BSL_CID_EXTEND = 0x60000000, +} BslCid; + +#ifdef __cplusplus +} +#endif + +#endif // BSL_OBJ_H diff --git a/include/bsl/bsl_sal.h b/include/bsl/bsl_sal.h new file mode 100644 index 00000000..204c2b66 --- /dev/null +++ b/include/bsl/bsl_sal.h @@ -0,0 +1,1239 @@ +/* + * 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_sal + * @ingroup bsl + * @brief System Abstraction Layer + */ + +#ifndef BSL_SAL_H +#define BSL_SAL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_sal + * + * Registrable function structure for memory allocation/release. + */ +typedef struct MemCallback { + /** + * @ingroup bsl_sal + * @brief Allocate a memory block. + * + * Allocate a memory block. + * + * @param size [IN] Size of the allocated memory. + * @retval: Not NULL, The start address of the allocated memory when memory is allocated successfully. + * @retval NULL, Memory allocation failure. + */ + void *(*pfMalloc)(uint32_t size); + + /** + * @ingroup bsl_sal + * @brief Reclaim a memory block allocated by pfMalloc. + * + * Reclaim a block of memory allocated by pfMalloc. + * + * @param addr [IN] Start address of the memory allocated by pfMalloc. + */ + void (*pfFree)(void *addr); +} BSL_SAL_MemCallback; + +/** + * @ingroup bsl_sal + * + * Thread lock handle, the corresponding structure is provided by the user during registration. + */ +typedef void *BSL_SAL_ThreadLockHandle; + +/** + * @ingroup bsl_sal + * + * Thread handle, the corresponding structure is provided by the user during registration. + */ +typedef void *BSL_SAL_ThreadId; + +/** + * @ingroup bsl_sal + * + * mutex + */ +typedef void *BSL_SAL_Mutex; + +/** + * @ingroup bsl_sal + * + * Condition handle, the corresponding structure is provided by the user during registration. + */ +typedef void *BSL_SAL_CondVar; + +/** + * @ingroup bsl_sal + * + * The user registers the function structure for thread-related operations. + */ +typedef struct ThreadCallback { + /** + * @ingroup bsl_sal + * @brief Create a thread lock. + * + * Create a thread lock. + * + * @param lock [IN/OUT] Lock handle + * @retval #BSL_SUCCESS, created successfully. + * @retval #BSL_MALLOC_FAIL, memory space is insufficient and thread lock space cannot be applied for. + * @retval #BSL_SAL_ERR_UNKNOWN, thread lock initialization failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of lock is NULL. + */ + int32_t (*pfThreadLockNew)(BSL_SAL_ThreadLockHandle *lock); + + /** + * @ingroup bsl_sal + * @brief Release the thread lock. + * + * Release the thread lock. Ensure that the lock can be released when other threads obtain the lock. + * + * @param lock [IN] Lock handle + */ + void (*pfThreadLockFree)(BSL_SAL_ThreadLockHandle lock); + + /** + * @ingroup bsl_sal + * @brief Lock the read operation. + * + * Lock the read operation. + * + * @param lock [IN] Lock handle + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, operation failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of lock is NULL. + */ + int32_t (*pfThreadReadLock)(BSL_SAL_ThreadLockHandle lock); + + /** + * @ingroup bsl_sal + * @brief Lock the write operation. + * + * Lock the write operation. + * + * @param lock [IN] Lock handle + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, operation failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of lock is NULL. + */ + int32_t (*pfThreadWriteLock)(BSL_SAL_ThreadLockHandle lock); + + /** + * @ingroup bsl_sal + * @brief Unlock + * + * Unlock + * + * @param lock [IN] Lock handle + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, operation failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of lock is NULL. + */ + int32_t (*pfThreadUnlock)(BSL_SAL_ThreadLockHandle lock); + + /** + * @ingroup bsl_sal + * @brief Obtain the thread ID. + * + * Obtain the thread ID. + * + * @retval Thread ID + */ + uint64_t (*pfThreadGetId)(void); +} BSL_SAL_ThreadCallback; + +/** + * @ingroup bsl_sal + * @brief Interface for registering memory-related callback functions + * + * Register the memory application and release functions. + * + * @attention None + * @param cb [IN] Pointer to the memory-related callback function + * @retval #BSL_SUCCESS, memory application and release functions are successfully registered. + * @retval #BSL_SAL_ERR_BAD_PARAM 0x02010003. If the cb is null or the cb members have null, caution fill + * the input parameter cb. + */ +int32_t BSL_SAL_RegMemCallback(BSL_SAL_MemCallback *cb); + +/** + * @ingroup bsl_sal + * @brief Interface for registering thread-related callback functions. + * + * Register the functions related to thread lock creation, release, lock, unlock, and thread ID obtaining. + * Can't be called in single thread scenario. + * Must be called in multiple threads scenario. + * + * @attention None + * @param cb [IN] Thread related callback function pointer + * @retval #BSL_SUCCESS, The functions related to the thread are successfully registered. + * @retval #BSL_SAL_ERR_BAD_PARAM 0x02010003. If the cb is null or the cb members have null, fill in the + * cb pointer with caution. + */ +int32_t BSL_SAL_RegThreadCallback(BSL_SAL_ThreadCallback *cb); + +/** + * @ingroup bsl_sal + * @brief Allocate memory space. + * + * Allocate memory space. + * + * @attention None + * @param size [IN] Size of the allocated memory + * @retval If the application is successful, returned the pointer pointing to the memory. + * @retval If the application failed, return NULL. + */ +void *BSL_SAL_Malloc(uint32_t size); + +/** + * @ingroup bsl_sal + * @brief Allocate and clear the memory space. + * + * Allocate and clear the memory space. The maximum size of UINT32_MAX is allocated. + * + * @attention num*size should not have overflow wrap. + * @param num [IN] Number of allocated memory. + * @param size [IN] Size of each memory. + * @retval If the application is successful, returned the pointer pointing to the memory. + * @retval If the application failed, return NULL. + */ +void *BSL_SAL_Calloc(uint32_t num, uint32_t size); + +/** + * @ingroup bsl_sal + * @brief Duplicate the memory space. + * + * @param src Source memory address + * @param size Total memory size + * @retval If the allocation is successful, returned the pointer pointing to the memory. + * @retval If the allocation failed, return NULL. + */ +void *BSL_SAL_Dump(const void *src, uint32_t size); + +/** + * @ingroup bsl_sal + * @brief Release the specified memory. + * + * Release the specified memory. + * + * @attention NONE. + * @param value [IN] Pointer to the memory space to be released. + */ +void BSL_SAL_Free(void *value); + +/** + * @ingroup bsl_sal + * @brief Memory expansion + * + * Memory expansion function. + * + * @attention None. + * @param addr [IN] Original memory address. + * @param newSize [IN] Extended memory size. + * @param oldSize [IN] Memory size before expansion. + * @retval void* indicates successful, the extended memory address is returned. + * @retval NULL indicates failed, return NULL. + */ +void *BSL_SAL_Realloc(void *addr, uint32_t newSize, uint32_t oldSize); + +/** + * @ingroup bsl_sal + * @brief Set sensitive information to zero. + * + * @param ptr [IN] Memory to be zeroed + * @param size [IN] Length of the memory to be zeroed out + */ +void BSL_SAL_CleanseData(void *ptr, uint32_t size); + +/** + * @ingroup bsl_sal + * @brief Clear sensitive information and release memory. + * + * @param ptr [IN] Pointer to the memory to be released + * @param size [IN] Length of the memory to be zeroed out + */ +void BSL_SAL_ClearFree(void *ptr, uint32_t size); + +#define BSL_SAL_FREE(value_) \ + do { \ + if ((value_) != NULL) { \ + BSL_SAL_Free((void *)(value_)); \ + (value_) = NULL; \ + } \ + } while (0) + +#define BSL_SAL_ONCE_INIT 0 // equal to PTHREAD_ONCE_INIT, the pthread symbol is masked. + +/** + * @ingroup bsl_sal + * @brief Create a thread lock. + * + * Create a thread lock. + * + * @attention none + * @param lock [IN/OUT] Lock handle + * @retval #BSL_SUCCESS, created successfully. + * @retval #BSL_MALLOC_FAIL, memory space is insufficient and failed to apply for process lock space. + * @retval #BSL_SAL_ERR_UNKNOWN, thread lock initialization failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error, the value of lock is NULL. + */ +int32_t BSL_SAL_ThreadLockNew(BSL_SAL_ThreadLockHandle *lock); + +/** + * @ingroup bsl_sal + * @brief Lock the read operation. + * + * Lock the read operation. + * + * @attention none + * @param lock [IN] Lock handle + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, operation failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of lock is NULL. + */ +int32_t BSL_SAL_ThreadReadLock(BSL_SAL_ThreadLockHandle lock); + +/** + * @ingroup bsl_sal + * @brief Lock the write operation. + * + * Lock the write operation. + * + * @attention none + * @param lock [IN] Lock handle + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, operation failed. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of lock is NULL. + */ +int32_t BSL_SAL_ThreadWriteLock(BSL_SAL_ThreadLockHandle lock); + +/** + * @ingroup bsl_sal + * @brief Unlock + * + * Unlock + * + * @attention unlock: Locks that have been unlocked are undefined behavior and are not allowed by default. + * @param lock [IN] Lock handle + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN operation failed. + * @retval #BSL_SAL_ERR_BAD_PARAM parameter error. The value of lock is NULL. + */ +int32_t BSL_SAL_ThreadUnlock(BSL_SAL_ThreadLockHandle lock); + +/** + * @ingroup bsl_sal + * @brief Release the thread lock. + * + * Release the thread lock. + * + * @attention By default, repeated release is prohibited. + * @param lock [IN] Lock handle. + */ +void BSL_SAL_ThreadLockFree(BSL_SAL_ThreadLockHandle lock); + +/** + * @ingroup bsl_sal + * @brief Obtain the thread ID. + * + * Obtain the thread ID. + * + * @attention none + * @retval Thread ID + */ +uint64_t BSL_SAL_ThreadGetId(void); + +/** + * @ingroup bsl_sal + * @brief run once: Use the initialization callback. + * + * @attention This function should not be a cancel, otherwise the default implementation of run + * once seems to have never been called. + */ +typedef void (*BSL_SAL_ThreadInitRoutine)(void); + +/** + * @ingroup bsl_sal + * @brief Execute only once. + * + * Run the init Func command only once. + * + * @attention The current version does not support registration. + * @param onceControl [IN] Record the execution status. + * @param initFunc [IN] Initialization function. + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_BAD_PARAM, input parameter is abnormal. + * @retval #BSL_SAL_ERR_UNKNOWN, the default run once failed. + */ +int32_t BSL_SAL_ThreadRunOnce(uint32_t *onceControl, BSL_SAL_ThreadInitRoutine initFunc); + +/** + * @ingroup bsl_sal + * @brief Create a thread. + * + * Create a thread. + * + * @attention none + * @param thread [IN/OUT] Thread ID + * @param startFunc [IN] Thread function + * @param arg [IN] Thread function parameters + * @retval #BSL_SUCCESS, created successfully. + * @retval #BSL_SAL_ERR_UNKNOWN, Failed to create a thread. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. + */ +int32_t BSL_SAL_ThreadCreate(BSL_SAL_ThreadId *thread, void *(*startFunc)(void *), void *arg); + +/** + * @ingroup bsl_sal + * @brief Close the thread. + * + * Close the thread. + * + * @attention none + * @param thread [IN] Thread ID + */ +void BSL_SAL_ThreadClose(BSL_SAL_ThreadId thread); + +/** + * @ingroup bsl_sal + * @brief Create a condition variable. + * + * Create a condition variable. + * + * @attention none + * @param condVar [IN] Condition variable + * @retval #BSL_SUCCESS, created successfully. + * @retval #BSL_SAL_ERR_UNKNOWN, failed to create a condition variable. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of condVar is NULL. + */ +int32_t BSL_SAL_CreateCondVar(BSL_SAL_CondVar *condVar); + +/** + * @ingroup bsl_sal + * @brief The waiting time ends or the signal is obtained. + * + * The waiting time ends or the signal is obtained. + * + * @attention None + * @param condVar [IN] Condition variable + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, function failure + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of condVar is NULL. + */ +int32_t BSL_SAL_CondSignal(BSL_SAL_CondVar condVar); + +/** + * @ingroup bsl_sal + * @brief The waiting time ends or the signal is obtained. + * + * The waiting time ends or the signal is obtained. + * + * @attention None + * @param condMutex [IN] Mutex + * @param condVar [IN] Condition variable + * @param timeout [IN] Time + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, fails. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of condMutex or condVar is null. + */ +int32_t BSL_SAL_CondTimedwaitMs(BSL_SAL_Mutex condMutex, BSL_SAL_CondVar condVar, int32_t timeout); + +/** + * @ingroup bsl_sal + * @brief Delete a condition variable. + * + * Delete a condition variable. + * + * @attention none + * @param condVar [IN] Condition variable + * @retval #BSL_SUCCESS, Succeeded in deleting the condition variable. + * @retval #BSL_SAL_ERR_UNKNOWN, Failed to delete the condition variable. + * @retval #BSL_SAL_ERR_BAD_PARAM, parameter error. The value of condVar is NULL. + */ +int32_t BSL_SAL_DeleteCondVar(BSL_SAL_CondVar condVar); + +typedef void *bsl_sal_file_handle; // Pointer to file handle + +/** + * @ingroup bsl_sal + * @brief Open a file. + * + * Open the file and ensure that the entered path is standardized. + * + * @attention None + * @param stream [OUT] File handle + * @param path [IN] File path + * @param mode [IN] Reading mode + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_FILE_OPEN, failed to be opened. + * @retval #BSL_NULL_INPUT, parameter error. + */ +int32_t BSL_SAL_FileOpen(bsl_sal_file_handle *stream, const char *path, const char *mode); + +/** + * @ingroup bsl_sal + * @brief Close the file. + * + * Close the file. + * + * @attention none + * @param stream [IN] File handle + * @retval NA + */ +void BSL_SAL_FileClose(bsl_sal_file_handle stream); + +/** + * @ingroup bsl_sal + * @brief Read the file. + * + * Read the file. + * The actual memory of the interface is 1 more than the real length of the read file, + * which is used to add '\0' after the end of the read file content, and the outgoing parameter len is the real + * data length, excluding '\0'. + * + * @attention none + * @param stream [IN] File handle + * @param buffer [IN] Buffer for reading data + * @param size [IN] The unit of reading. + * @param num [IN] Number of data records to be read + * @param len [OUT] Read the data length. + * @retval #BSL_SUCCESS, succeeded. + * @retval #BSL_SAL_ERR_UNKNOWN, fails. + * @retval #BSL_NULL_INPUT, Incorrect parameter + */ +int32_t BSL_SAL_FileRead(bsl_sal_file_handle stream, void *buffer, size_t size, size_t num, size_t *len); + +/** + * @ingroup bsl_sal + * @brief Write a file + * + * Write File + * + * @attention none + * @param stream [IN] File handle + * @param buffer [IN] Data to be written + * @param size [IN] Write the unit + * @param num [IN] Number of written data + * @retval #BSL_SUCCESS, succeeded + * @retval #BSL_SAL_ERR_UNKNOWN, fails + * @retval #BSL_NULL_INPUT, parameter error + */ +int32_t BSL_SAL_FileWrite(bsl_sal_file_handle stream, const void *buffer, size_t size, size_t num); + +/** + * @ingroup bsl_sal + * @brief Obtain the file length. + * + * Obtain the file length. + * + * @attention none + * @param path [IN] File path + * @param len [OUT] File length + * @retval #BSL_SUCCESS, succeeded + * @retval #BSL_SAL_ERR_UNKNOWN, fails + * @retval #BSL_NULL_INPUT, parameter error + */ +int32_t BSL_SAL_FileLength(const char *path, size_t *len); + +/** + * @ingroup bsl_sal + * @brief Basic time data structure definition. + */ +typedef struct { + uint16_t year; /**< Year. the value range is [0, 65535]. */ + uint8_t month; /**< Month. the value range is [1, 12]. */ + uint8_t day; /**< Day, the value range is [1, 31]. */ + uint8_t hour; /**< Hour, the value range is [0, 23]. */ + uint8_t minute; /**< Minute, the value range is [0, 59]. */ + uint16_t millSec; /**< Millisecond, the value range is [0, 999]. */ + uint8_t second; /**< Second, the value range is [0, 59]. */ + uint32_t microSec; /**< Microseconds, the value range is [0, 999]. */ +} BSL_TIME; + +/** + * @ingroup bsl_sal + * @brief Unix Time structure definition. + */ +typedef int64_t BslUnixTime; + +/** + * @ingroup bsl_sal + * @brief Prototype of the callback function for obtaining the time + * + * Prototype definition of the callback function for obtaining the time. + */ +typedef BslUnixTime (*BslTimeFunc)(void); + +/** + * @ingroup bsl_sal + * @brief Interface for registering the function for obtaining the system time + * You can use this API to register the system time obtaining function. + * + * This interface can be registered for multiple times. After the registration is + * successful, the registration cannot be NULL again. + * Description of the time range: + * Users can use the Linux system at most 2038 per year. + * The lower limit of the time is 1970 - 1 - 1 0: 0: 0. + * It is recommended that users use this minimum intersection, i.e., the bounds of + * years are 1970-1-1 0:0:0 ~ 2038-01-19 03:14:08. + * + * @param func [IN] Register the function for obtaining the system time + */ +void BSL_SAL_SysTimeFuncReg(BslTimeFunc func); + +/** + * @ingroup bsl_sal + * @brief Compare Two Dates + * + * @param dateA [IN] The first date + * @param dateB [IN] The second date + * @param diffSeconds [OUT] Number of seconds between two dates + * @retval BslTimeCmpResult Comparison result of two dates + * @retval #BSL_TIME_CMP_ERROR - Error in comparison + * @retval #BSL_TIME_CMP_EQUAL - The two dates are consistent. + * @retval #BSL_TIME_DATE_BEFORE - The first date is before the second date. + * @retval #BSL_TIME_DATE_AFTER - The first date is after the second + */ +int32_t BSL_SAL_DateTimeCompare(const BSL_TIME *dateA, const BSL_TIME *dateB, int64_t *diffSec); + +/** + * @ingroup bsl_sal + * @brief Obtain the system time. + * + * Obtain the system time. + * + * @attention none + * @param sysTime [out] Time + * @retval #BSL_SUCCESS, obtained the time successfully. + * @retval #BSL_SAL_ERR_BAD_PARAM, the value of cb is null. + * @retval #BSL_INTERNAL_EXCEPTION, an exception occurred when obtaining the time. + */ +int32_t BSL_SAL_SysTimeGet(BSL_TIME *sysTime); + +/** + * @ingroup bsl_sal + * @brief Obtain the Unix time. + * + * Obtain the Unix time. + * + * @retval Return the Unix time. + */ +BslUnixTime BSL_SAL_CurrentSysTimeGet(void); + +/** + * @ingroup bsl_sal + * @brief Convert the date in the BslSysTime format to the UTC time format. + * + * Convert the date in the BslSysTime format to the UTC time format. + * + * @attention None + * @param dateTime [IN] Date and time + * @param utcTime [OUT] UTC time + * @retval #BSL_SUCCESS, time is successfully converted. + * @retval #BSL_INTERNAL_EXCEPTION, an exception occurred when obtaining the time. + */ +int32_t BSL_SAL_DateToUtcTimeConvert(const BSL_TIME *dateTime, int64_t *utcTime); + +/** + * @ingroup bsl_sal + * @brief Convert the date in the BslUnixTime format to the BslSysTime format. + * + * Convert the date in the BslUnixTime format to the BslSysTime format. + * + * @attention none + * @param utcTime [IN] UTC time + * @param sysTime [OUT] BslSysTime Time + * @retval #BSL_SUCCESS, time is converted successfully + * @retval #BSL_SAL_ERR_BAD_PARAM, the value of utcTime exceeds the upper limit or the value of sysTime is null. + */ +int32_t BSL_SAL_UtcTimeToDateConvert(int64_t utcTime, BSL_TIME *sysTime); + +/** + * @ingroup bsl_sal + * @brief Compare two dates, accurate to microseconds. + * + * Compare two dates, accurate to microseconds + * + * @attention None + * @param dateA [IN] Time + * @param dateB [IN] Time + * @retval #BslTimeCmpResult Comparison result of two dates + * @retval #BSL_TIME_CMP_ERROR - An error occurred in the comparison. + * @retval #BSL_TIME_CMP_EQUAL - The two dates are consistent. + * @retval #BSL_TIME_DATE_BEFORE - The first date is on the second + * @retval #BSL_TIME_DATE_ AFTER - The first date is after the second + */ +int32_t BSL_SAL_DateTimeCompareByUs(const BSL_TIME *dateA, const BSL_TIME *dateB); + +/** + * @ingroup bsl_sal + * @brief Sleep the current thread + * + * Sleep the current thread + * + * @attention none + * @param time [IN] Sleep time + */ +void BSL_SAL_Sleep(uint32_t time); + +/** + * @ingroup bsl_sal + * @brief Obtain the number of ticks that the system has experienced since startup. + * + * Obtain the system time. +* + * @attention none + * @retval Number of ticks + */ +long BSL_SAL_Tick(void); + +/** + * @ingroup bsl_sal + * @brief Obtain the number of system ticks per second. + * + * Obtain the system time. + * + * @attention none + * @retval Number of ticks per second + */ +long BSL_SAL_TicksPerSec(void); + +/** + * @ingroup bsl_sal_net + * + * socket address + */ +typedef void *BSL_SAL_SockAddr; + +/** + * @ingroup bsl_sal + * @brief Socket creation interface + * + * Socket creation interface. + * + * @attention none + * @param af [IN] Socket specifies the protocol set. + * @param type [IN] Socket type + * @param protocol [IN] Protocol type + * @retval If the creation is successful, a non-negative value is returned. + * @retval Otherwise, a negative value is returned. + */ +int32_t BSL_SAL_Socket(int32_t af, int32_t type, int32_t protocol); + +/** + * @ingroup bsl_sal + * @brief Close the socket + * + * Close the socket + * + * @attention none + * @param sockId [IN] Socket file descriptor ID + * @retval If the operation succeeds, BSL_SUCCESS is returned. + * @retval If the operation fails, BSL_SAL_ERR_NET_SOCKCLOSE is returned. + */ +int32_t BSL_SAL_SockClose(int32_t sockId); + +/** + * @ingroup bsl_sal + * @brief Set the socket + * + * Set the socket + * + * @attention none + * @param sockId [IN] Socket file descriptor ID + * @param level [IN] Level of the option to be set. + * @param name [IN] Options to be set + * @param val [IN] Value of the option. + * @param len [IN] val Length + * @retval If the operation succeeds, BSL_SUCCESS is returned + * @retval If the operation fails, BSL_SAL_ERR_NET_SETSOCKOPT is returned. + */ +int32_t BSL_SAL_SetSockopt(int32_t sockId, int32_t level, int32_t name, const void *val, uint32_t len); + +/** + * @ingroup bsl_sal + * @brief Listening socket + * + * Listen socket + * + * @attention none + * @param sockId [IN] Socket file descriptor ID + * @param backlog [IN] Length of the receiving queue + * @retval If the operation succeeds, BSL_SUCCESS is returned. + * @retval If the operation fails, BSL_SAL_ERR_NET_LISTEN is returned. + */ +int32_t BSL_SAL_SockListen(int32_t sockId, int32_t backlog); + +/** + * @ingroup bsl_sal + * @brief Binding a socket + * + * Binding Socket + * + * @attention None + * @param sockId [IN] Socket file descriptor ID + * @param addr [IN] Specify the address. + * @param len [IN] Address length + * @retval If the operation succeeds, BSL_SUCCESS is returned. + * @retval If the operation fails, BSL_SAL_ERR_NET_BIND is returned. + */ +int32_t BSL_SAL_SockBind(int32_t sockId, BSL_SAL_SockAddr addr, size_t len); + +/** + * @ingroup bsl_sal + * @brief Initiate a connection. + * + * Initiate a connection. + * + * @attention none + * @param sockId [IN] Socket file descriptor ID + * @param addr [IN] Address to be connected + * @param len [IN] Address length + * @retval If the operation succeeds, BSL_SUCCESS is returned + * @retval If the operation fails, BSL_SAL_ERR_NET_CONNECT is returned. + */ +int32_t BSL_SAL_SockConnect(int32_t sockId, BSL_SAL_SockAddr addr, size_t len); + +/** + * @ingroup bsl_sal + * @brief Send a message. + * + * Send messages + * + * @attention none + * @param sockId [IN] Socket file descriptor ID + * @param msg [IN] Message sent + * @param len [IN] Information length + * @param flags [IN] is generally set to 0. + * @retval If the operation succeeds, the length of the sent data is returned. + * @retval If the operation fails, a negative value is returned. + * @retval If the operation times out or the peer end disables the function, the value 0 is returned. + */ +int32_t BSL_SAL_SockSend(int32_t sockId, const void *msg, size_t len, int32_t flags); + +/** + * @ingroup bsl_sal + * @brief Receive the message. + * + * Receive information + * + * @attention none + * @param sockfd [IN] Socket file descriptor ID + * @param buff [IN] Buffer for receiving information + * @param len [IN] Length of the buffer + * @param flags [IN] is generally set to 0. + * @retval If the operation succeeds, the received data length is returned. + * @retval If the operation fails, a negative value is returned. + * @retval If the operation times out or the peer end disables the function, the value 0 is returned. + */ +int32_t BSL_SAL_SockRecv(int32_t sockfd, void *buff, size_t len, int32_t flags); + +/** + * @ingroup bsl_sal + * @brief Check the socket descriptor. + * + * Check the socket descriptor. + * + * @attention None + * @param nfds [IN] Total number of file descriptors that are listened on + * @param readfds [IN] Readable file descriptor (optional) + * @param writefds [IN] Descriptor of a writable file. This parameter is optional. + * @param exceptfds [IN] Exception file descriptor (optional) + * @param timeout [IN] Set the timeout interval. + * @retval If the operation succeeds, Number of ready descriptors are returned; + * @retval If the operation fails, a negative value is returned; + * @retval If the operation times out, 0 is returned + */ +int32_t BSL_SAL_Select(int32_t nfds, void *readfds, void *writefds, void *exceptfds, void *timeout); + +/** + * @ingroup bsl_sal + * @brief Device control interface function + * + * Device control interface function + * + * @attention None + * @param sockId [IN] Socket file descriptor ID + * @param cmd [IN] Interaction protocol + * @param arg [IN] Parameter + * @retval If the operation succeeds, BSL_SUCCESS is returned. + * @retval If the operation fails, BSL_SAL_ERR_NET_IOCTL is returned. + */ +int32_t BSL_SAL_Ioctlsocket(int32_t sockId, long cmd, unsigned long *arg); + +/** + * @ingroup bsl_sal + * @brief Obtain the last error corresponding to the socket. + * + * Obtain the last error corresponding to the socket. + * + * @attention none + * @retval Return the corresponding error. + */ +int32_t BSL_SAL_SockGetLastSocketError(void); + +/** + * @ingroup bsl_sal + * @brief String comparison + * + * String comparison + * + * @attention None. + * @param str1 [IN] First string to be compared. + * @param str2 [IN] Second string to be compared. + * @retval If the parameter is abnormal, BSL_NULL_INPUT is returned. + * @retval If the strings are the same, 0 is returned; + * Otherwise, the difference between different characters is returned. + */ +int32_t BSL_SAL_StrcaseCmp(const char *str1, const char *str2); + +/** + * @ingroup bsl_sal + * @brief Search for the corresponding character position in a string. + * + * Search for the corresponding character position in a string. + * + * @attention None. + * @param str [IN] String + * @param character [IN] Character to be searched for + * @param count [IN] Range to be found + * @retval If a character is found, the position of the character is returned; + * Otherwise, NULL is returned. + */ +void *BSL_SAL_Memchr(const char *str, int32_t character, size_t count); + +/** + * @ingroup bsl_sal + * @brief Convert string to number + * + * Convert string to number + * + * @attention None. + * @param str [IN] String to be converted. + * @retval If the conversion is successful, the corresponding number is returned; + * Otherwise, the value 0 is returned. + */ +int32_t BSL_SAL_Atoi(const char *str); + +/** + * @ingroup bsl_sal + * @brief Obtain the length of a given string. + * + * Obtain the length of a given string. + * + * @attention None. + * @param string [IN] String to obtain the length. + * @param count [IN] Maximum length + * @retval If the parameter is abnormal, return 0. + * @retval If the length of a string is greater than the count, return count. + * Otherwise, the actual length of the string is returned. + */ +uint32_t BSL_SAL_Strnlen(const char *string, uint32_t count); + +typedef enum { + BSL_SAL_NET_WRITE_CB_FUNC = 0x0300, + BSL_SAL_NET_READ_CB_FUNC, + BSL_SAL_NET_SOCKET_CB_FUNC, + BSL_SAL_NET_SOCKCLOSE_CB_FUNC, + BSL_SAL_NET_SETSOCKOPT_CB_FUNC, + BSL_SAL_NET_GETSOCKOPT_CB_FUNC, + BSL_SAL_NET_SOCKLISTEN_CB_FUNC, + BSL_SAL_NET_SOCKBIND_CB_FUNC, + BSL_SAL_NET_SOCKCONNECT_CB_FUNC, + BSL_SAL_NET_SOCKSEND_CB_FUNC, + BSL_SAL_NET_SOCKRECV_CB_FUNC, + BSL_SAL_NET_SELECT_CB_FUNC, + BSL_SAL_NET_IOCTLSOCKET_CB_FUNC, + BSL_SAL_NET_SOCKGETLASTSOCKETERROR_CB_FUNC, + + BSL_SAL_TIME_GET_SYS_TIME_CB_FUNC = 0x0400, + BSL_SAL_TIME_DATE_TO_STR_CONVERT_CB_FUNC, + BSL_SAL_TIME_SYS_TIME_GET_CB_FUNC, + BSL_SAL_TIME_UTC_TIME_TO_DATE_CONVERT_CB_FUNC, + BSL_SAL_TIME_SLEEP_CB_FUNC, + BSL_SAL_TIME_TICK_CB_FUNC, + BSL_SAL_TIME_TICKS_PER_SEC_CB_FUNC, + + BSL_SAL_FILE_OPEN_CB_FUNC = 0X0500, + BSL_SAL_FILE_CLOSE_CB_FUNC, + BSL_SAL_FILE_READ_CB_FUNC, + BSL_SAL_FILE_WRITE_CB_FUNC, + BSL_SAL_FILE_LENGTH_CB_FUNC, +} BSL_SAL_CB_FUNC_TYPE; + +/** + * @ingroup bsl_sal + * @brief Open the file. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_FILE_OPEN: file open fails. + * @retval #BSL_NULL_INPUT: parameter error. + */ +typedef int32_t (*BslSalFileOpen)(bsl_sal_file_handle *stream, const char *path, const char *mode); + +/** + * @ingroup bsl_sal + * @brief Read from the file. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_FILE_READ: file read fails. + * @retval #BSL_NULL_INPUT: parameter error. + */ +typedef int32_t (*BslSalFileRead)(bsl_sal_file_handle stream, void *buffer, size_t size, size_t num, size_t *len); + +/** + * @ingroup bsl_sal + * @brief Write to the file. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_FILE_WRITE: file write fails. + * @retval #BSL_NULL_INPUT: parameter error. + */ +typedef int32_t (*BslSalFileWrite)(bsl_sal_file_handle stream, const void *buffer, size_t size, size_t num); + +/** + * @ingroup bsl_sal + * @brief Close the file. + */ +typedef void (*BslSalFileClose)(bsl_sal_file_handle stream); + +/** + * @ingroup bsl_sal + * @brief Get the length of the file. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_FILE_LENGTH: get file length fails. + * @retval #BSL_NULL_INPUT: parameter error. + */ +typedef int32_t (*BslSalFileLength)(const char *path, size_t *len); + +/** + * @ingroup bsl_sal + * @brief Get the system time. + * + * @retval System time in int64_t format. + */ +typedef int64_t (*BslSalGetSysTime)(void); + +/** + * @ingroup bsl_sal + * @brief Convert date to string. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_INTERNAL_EXCEPTION: conversion fails. + */ +typedef uint32_t (*BslSalDateToStrConvert)(const BSL_TIME *dateTime, char *timeStr, size_t len); + +/** + * @ingroup bsl_sal + * @brief Get the system time. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_BAD_PARAM: parameter error. + * @retval #BSL_INTERNAL_EXCEPTION: an exception occurred when obtaining the time. + */ +typedef uint32_t (*BslSalSysTimeGet)(BSL_TIME *sysTime); + +/** + * @ingroup bsl_sal + * @brief Convert UTC time to date. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_BAD_PARAM: parameter error. + */ +typedef uint32_t (*BslSalUtcTimeToDateConvert)(int64_t utcTime, BSL_TIME *sysTime); + +/** + * @ingroup bsl_sal + * @brief Sleep for a specified time. + */ +typedef void (*BslSalSleep)(uint32_t time); + +/** + * @ingroup bsl_sal + * @brief Get the system tick count. + * + * @retval System tick count. + */ +typedef long (*BslSalTick)(void); + +/** + * @ingroup bsl_sal + * @brief Get the number of ticks per second. + * + * @retval Number of ticks per second. + */ +typedef long (*BslSalTicksPerSec)(void); + +/** + * @ingroup bsl_sal + * @brief Write data. + * + * @retval Positive integer: number of bytes written. + * @retval Negative integer: write operation failed. + */ +typedef int32_t (*BslSalWrite)(int32_t fd, const void *buf, uint32_t len, int32_t *err); + +/** + * @ingroup bsl_sal + * @brief Read data. + * + * @retval Positive integer: number of bytes read. + * @retval Negative integer: read operation failed. + */ +typedef int32_t (*BslSalRead)(int32_t fd, void *buf, uint32_t len, int32_t *err); + +/** + * @ingroup bsl_sal + * @brief Create a socket. + * + * @retval Non-negative integer: socket file descriptor. + * @retval Negative integer: socket creation failed. + */ +typedef int32_t (*BslSalSocket)(int32_t af, int32_t type, int32_t protocol); + +/** + * @ingroup bsl_sal + * @brief Close a socket. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_SOCKCLOSE: socket close fails. + */ +typedef int32_t (*BslSalSockClose)(int32_t sockId); + +/** + * @ingroup bsl_sal + * @brief Set socket options. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_SETSOCKOPT: set socket option fails. + */ +typedef int32_t (*BslSalSetSockopt)(int32_t sockId, int32_t level, int32_t name, const void *val, uint32_t len); + +/** + * @ingroup bsl_sal + * @brief Get socket options. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_GETSOCKOPT: get socket option fails. + */ +typedef int32_t (*BslSalGetSockopt)(int32_t sockId, int32_t level, int32_t name, void *val, uint32_t *len); + +/** + * @ingroup bsl_sal + * @brief Listen for socket connections. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_LISTEN: socket listen fails. + */ +typedef int32_t (*BslSalSockListen)(int32_t sockId, int32_t backlog); + +/** + * @ingroup bsl_sal + * @brief Bind a socket to an address. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_BIND: socket bind fails. + */ +typedef int32_t (*BslSalSockBind)(int32_t sockId, BSL_SAL_SockAddr addr, size_t len); + +/** + * @ingroup bsl_sal + * @brief Connect a socket to a remote address. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_CONNECT: socket connect fails. + */ +typedef int32_t (*BslSalSockConnect)(int32_t sockId, BSL_SAL_SockAddr addr, size_t len); + +/** + * @ingroup bsl_sal + * @brief Send data through a socket. + * + * @retval Positive integer: number of bytes sent. + * @retval Negative integer: send operation failed. + */ +typedef int32_t (*BslSalSockSend)(int32_t sockId, const void *msg, size_t len, int32_t flags); + +/** + * @ingroup bsl_sal + * @brief Receive data from a socket. + * + * @retval Positive integer: number of bytes received. + * @retval Negative integer: receive operation failed. + */ +typedef int32_t (*BslSalSockRecv)(int32_t sockfd, void *buff, size_t len, int32_t flags); + +/** + * @ingroup bsl_sal + * @brief Monitor multiple file descriptors for readiness. + * + * @retval Positive integer: number of ready descriptors. + * @retval 0: timeout occurred. + * @retval Negative integer: select operation failed. + */ +typedef int32_t (*BslSalSelect)(int32_t nfds, void *readfds, void *writefds, void *exceptfds, void *timeout); + +/** + * @ingroup bsl_sal + * @brief Perform I/O control on a socket. + * + * @retval #BSL_SUCCESS: succeeded. + * @retval #BSL_SAL_ERR_NET_IOCTL: ioctl operation fails. + */ +typedef int32_t (*BslSalIoctlsocket)(int32_t sockId, long cmd, unsigned long *arg); + +/** + * @ingroup bsl_sal + * @brief Get the last socket error. + * + * @retval Error code of the last socket operation. + */ +typedef int32_t (*BslSalSockGetLastSocketError)(void); + +/** + * @ingroup bsl_sal + * @brief Control callback functions for SAL (System Abstraction Layer). + * + * This function is used to control and register callback functions for different SAL modules + * such as network, time, and file operations. + * + * @attention None + * @param funcType [IN] Type of the callback function to be controlled + * @param funcCb [IN] Pointer to the callback function + * @retval #BSL_SUCCESS Callback function controlled successfully + * @retval #BSL_SAL_ERR_BAD_PARAM Invalid function type or callback pointer + * @retval Other error codes specific to the SAL module + */ +int32_t BSL_SAL_CallBack_Ctrl(BSL_SAL_CB_FUNC_TYPE funcType, void *funcCb); + + +#ifdef __cplusplus +} +#endif + +#endif // BSL_SAL_H \ No newline at end of file diff --git a/include/bsl/bsl_type.h b/include/bsl/bsl_type.h new file mode 100644 index 00000000..9e714fe4 --- /dev/null +++ b/include/bsl/bsl_type.h @@ -0,0 +1,46 @@ +/* + * 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_uio + * @ingroup bsl + * @brief uio module + */ + +#ifndef BSL_TYPE_H +#define BSL_TYPE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BSL_FORMAT_UNKNOWN, + BSL_FORMAT_PEM, + BSL_FORMAT_ASN1 +} BSL_ParseFormat; + +typedef struct { + uint8_t *data; + uint32_t dataLen; +} BSL_Buffer; + +#ifdef __cplusplus +} +#endif + +#endif // BSL_TYPE_H diff --git a/include/bsl/bsl_uio.h b/include/bsl/bsl_uio.h new file mode 100644 index 00000000..28d80b9b --- /dev/null +++ b/include/bsl/bsl_uio.h @@ -0,0 +1,558 @@ +/* + * 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_uio + * @ingroup bsl + * @brief uio module + */ + +#ifndef BSL_UIO_H +#define BSL_UIO_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_uio + * @brief UIO module control structure + */ +typedef struct UIO_ControlBlock BSL_UIO; + +/** + * @ingroup bsl_uio + * @brief BSL_UIO_BufMem structure + */ +typedef struct { + size_t length; + char *data; + size_t max; +} BSL_UIO_BufMem; + +/** + * @ingroup bsl_uio + * @brief userData release function + */ +typedef void (*BSL_UIO_USERDATA_FREE_FUNC)(void *); + +/** + * @ingroup bsl_uio + * @brief Transmission protocol enumeration + */ +typedef enum { + BSL_UIO_TCP, + BSL_UIO_SCTP, + BSL_UIO_BUFFER, + BSL_UIO_UNKNOWN, /* Unknown protocol should not appear */ + + BSL_UIO_EXTEND = 10000, /* extension value */ +} BSL_UIO_TransportType; + +/** + * @ingroup bsl_uio + * @brief Sctp auth key, hitls Use the BSL_UIO_Method.ctrl method to transfer the BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY + * instruction to notify the user that the auth key needs to be set. + */ +typedef struct { + uint16_t shareKeyId; + uint16_t authKeySize; + const uint8_t *authKey; +} BSL_UIO_SctpAuthKey; + +/** + * @ingroup bsl_uio + * @brief BSL_UIO_CtrlParameter controls the I/O callback function. Hitls notifies the + * user of the function to be implemented + */ +typedef enum { + /* The cmd(0-0x99) used by the abstraction layer and the uio + * implemented by the user cannot reuse these values. */ + BSL_UIO_GET_INIT = 0x0, + BSL_UIO_GET_WRITE_NUM, + BSL_UIO_GET_READ_NUM, + + /* Public use 0x100 */ + BSL_UIO_SET_PEER_IP_ADDR = 0x100, + BSL_UIO_GET_PEER_IP_ADDR, + BSL_UIO_SET_FD, + BSL_UIO_GET_FD, + BSL_UIO_FLUSH, + BSL_UIO_RESET, + + /* SCTP uses 0x3XX */ + BSL_UIO_SCTP_CHECK_PEER_AUTH = 0x300, + BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY, + BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY, + BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY, + BSL_UIO_SCTP_SND_BUFF_IS_EMPTY, + BSL_UIO_SCTP_GET_SEND_STREAM_ID, + BSL_UIO_SCTP_SET_APP_STREAM_ID, + BSL_UIO_SCTP_MARK_APP_MESSAGE, +} BSL_UIO_CtrlParameter; + +#define BSL_UIO_FILE_READ 0x02 +#define BSL_UIO_FILE_WRITE 0x04 +#define BSL_UIO_FILE_APPEND 0x08 +#define BSL_UIO_FILE_TEXT 0x10 + +#define BSL_UIO_FLAGS_READ 0x01 +#define BSL_UIO_FLAGS_WRITE 0x02 +#define BSL_UIO_FLAGS_IO_SPECIAL 0x04 +#define BSL_UIO_FLAGS_RWS (BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_IO_SPECIAL) +#define BSL_UIO_FLAGS_SHOULD_RETRY 0x08 + +#define BSL_UIO_FLAGS_MEM_READ_ONLY 0x10 /* This flag can be set only by uio_mem */ + +#define BSL_UIO_FLAGS_BASE64_NO_NEWLINE 0x20 +#define BSL_UIO_FLAGS_BASE64_PEM 0x40 + + +typedef struct { + uint8_t *addr; + uint32_t size; +} BSL_UIO_CtrlGetPeerIpAddrParam; + +typedef int32_t (*BslUioWriteCb)(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen); +typedef int32_t (*BslUioReadCb)(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen); +typedef int32_t (*BslUioCtrlCb)(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg); +typedef int32_t (*BslUioCreateCb)(BSL_UIO *uio); +typedef int32_t (*BslUioDestroyCb)(BSL_UIO *uio); +typedef int32_t (*BslUioPutsCb)(BSL_UIO *uio, const char *buf, uint32_t *writeLen); +typedef int32_t (*BslUioGetsCb)(BSL_UIO *uio, char *buf, uint32_t *readLen); + +typedef struct BSL_UIO_MethodStruct BSL_UIO_Method; + +typedef enum { + BSL_UIO_CREATE_CB, + BSL_UIO_DESTROY_CB, + BSL_UIO_WRITE_CB, + BSL_UIO_READ_CB, + BSL_UIO_CTRL_CB, + BSL_UIO_PUTS_CB, + BSL_UIO_GETS_CB, +} BSL_UIO_METHOD_TYPE; + +/** + * @ingroup bsl_uio + * @brief Creating uio method structure + * + * @retval uio method structure pointer + */ +BSL_UIO_Method *BSL_UIO_NewMethod(void); + +/** + * @ingroup bsl_uio + * @brief set uio method type + * + * @param meth [IN] uio method structure + * @param type [IN] type + * @retval #BSL_SUCCESS + * @retval #BSL_NULL_INPUT + */ +int32_t BSL_UIO_SetMethodType(BSL_UIO_Method *meth, int32_t type); + +/** + * @ingroup bsl_uio + * @brief set uio method callback + * + * @param meth [IN] uio method structure + * @param type [IN] callback type + * @param func [IN] callback pointer + * @retval #BSL_SUCCESS + * @retval #BSL_INVALID_ARG + */ +int32_t BSL_UIO_SetMethod(BSL_UIO_Method *meth, int32_t type, void *func); + +/** + * @ingroup bsl_uio + * @brief free uio Method + * + * @param meth [IN] uio method structure + * @retval void + */ +void BSL_UIO_FreeMethod(BSL_UIO_Method *meth); + +/** + * @ingroup bsl_uio + * @brief obtain the default TCP UIO method + * + * @retval pointer to the TCP UIO method + */ +const BSL_UIO_Method *BSL_UIO_TcpMethod(void); + +/** + * @ingroup bsl_uio + * @brief obtain the default SCTP UIO + * + * @retval pointer to the SCTP UIO method + */ +const BSL_UIO_Method *BSL_UIO_SctpMethod(void); + +/** + * @ingroup bsl_uio + * @brief obtain the default buffer UIO + * + * @retval pointer to the Buffer UIO method + */ +const BSL_UIO_Method *BSL_UIO_BufferMethod(void); + +/** + * @ingroup bsl_uio + * @brief Create a UIO object + * + * @param method [IN] UIO method structure + * @retval UIO, created successfully + * @retval NULL UIO, creation failure + */ +BSL_UIO *BSL_UIO_New(const BSL_UIO_Method *method); + +/** + * @ingroup bsl_uio + * @brief Release the UIO object. + * + * @param uio [IN] UIO object. + */ +void BSL_UIO_Free(BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Write data to the UIO object + * + * @param uio [IN] uio object. + * @param data [IN] Data to be written. + * @param len [IN] Data length. + * @param writeLen [OUT] Length of the data that is successfully written. + * @retval #BSL_SUCCESS, indicating that the data is successfully written. + * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. + * @retval #BSL_UIO_IO_BUSY, indicating that the underlying I/O is busy. + * @retval #BSL_UIO_IO_EXCEPTION, The I/O is abnormal. + * @retval #BSL_UIO_FAIL,invalid parameter. + */ +int32_t BSL_UIO_Write(BSL_UIO *uio, const void *data, uint32_t len, uint32_t *writeLen); + +/** + * @ingroup bsl_uio + * @brief Read data from the UIO object. + * + * @param uio [IN] uio object. + * @param data [IN] Buffer for receiving data + * @param len [IN] Length of the received data buffer. + * @param readLen [OUT] Length of the received data. + * @retval #BSL_SUCCESS, The data is read successfully(Determined based on the actual receive length, + * if the length is 0 means no data is read.) + * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. + * @retval #BSL_UIO_FAIL, invalid parameter. + * @retval #BSL_UIO_IO_EXCEPTION, IO is abnormal. + */ +int32_t BSL_UIO_Read(BSL_UIO *uio, void *data, uint32_t len, uint32_t *readLen); + +/** + * @ingroup bsl_uio + * @brief Process specific UIO implementations by cmd + * + * @param uio [IN] UIO object + * @param cmd [IN] Different cmd processes perform different operations on UIO objects. + * @param larg [IN] Determined by cmd. For details, see the following + * @param parg [IN/OUT] Determined by cmd. For details, see the following + * @retval #BSL_SUCCESS + * @retval Non-BSL_SUCCESS, for details, see bsl_errno.h. + * + * @brief set the peer IP address in the UIO object + * + * The address format is a binary address in network byte order, with a length of 4 or 16 bytes. + * A generated cookie will be provided for use by the HelloVerifyRequest for dtls. + * + * @param uio [IN] UIO object + * @param cmd [IN] BSL_UIO_SET_PEER_IP_ADDR + * @param larg [IN] Size of the peer address: The length must be 4 or 16 + * @param parg [IN] Peer address + * + * @brief Obtain the peer IP address from the UIO object + * + * The obtained address is in the network byte order binary address format. + * The input length must be greater than the configured size. + * The purpose is to provide a generated cookie for use by the HelloVerifyRequest of the dtls. + * + * @param uio [IN] UIO object + * @param cmd [IN] BSL_UIO_GET_PEER_IP_ADDR + * @param larg [IN] 0 + * @param parg [IN] BSL_UIO_CtrlGetPeerIpAddrParam *, include: + * addr [IN/OUT] Peer address, + * size [IN/OUT] IN: size of the input buffer OUT: size of the output peer address + * + * @brief Obtain the stream ID sent by the SCTP from the UIO object. + * + * This API needs to be called by users in BSL_UIO_Method.write + * and send SCTP messages based on the obtained stream ID + * + * @param uio [IN] UIO object + * @param cmd [IN] BSL_UIO_SCTP_GET_SEND_STREAM_ID + * @param larg [IN] 0 + * @param parg [IN/OUT] ID of the sent stream, uint16_t* Type + * + * @brief Set the stream ID of the app message sent by the SCTP in the UIO object. + * + * If a service message needs to be processed by a specific stream ID, this interface can be called. + * + * @param uio [IN] UIO object + * @param cmd [IN] BSL_UIO_SCTP_SET_APP_STREAM_ID + * @param larg [IN] App stream ID. The value ranges from 0 to 65535 + * @param parg [IN] NULL + */ +int32_t BSL_UIO_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg); + +/** + * @ingroup bsl_uio + * @brief Write a string to the UIO object. + * + * @param uio [IN] uio object. + * @param buf [IN] A null-terminated string to be written. + * @param writeLen [OUT] Length of the data that is successfully written. + * @retval #BSL_SUCCESS, Writing succeeded. + * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. + * @retval #BSL_UIO_IO_BUSY, indicating that the underlying I/O is busy. + * @retval #BSL_UIO_IO_EXCEPTION, IO abnormal. + * @retval #BSL_UIO_FAIL, invalid parameter. + */ +int32_t BSL_UIO_Puts(BSL_UIO *uio, const char *buf, uint32_t *writeLen); + +/** + * @ingroup bsl_uio + * @brief Reads a string from the UIO object + * + * @param uio [IN] uio object. + * @param buf [IN] Buffer that accepts a line of strings + * @param readLen [IN/OUT] Length of the buffer for receiving data/Length of the data that is successfully read + * @retval #BSL_SUCCESS (Determine the value based on the actual receive length. + * if the length is 0 means no data is read.) + * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. + * @retval #BSL_UIO_FAIL, invalid parameter. + * @retval #BSL_UIO_IO_EXCEPTION, IO abnormal. + */ +int32_t BSL_UIO_Gets(BSL_UIO *uio, char *buf, uint32_t *readLen); + +/** + * @ingroup bsl_uio + * @brief Obtain the UIO transmission protocol type + * + * @param uio [IN] UIO object. + * @retval protocol type + */ +int32_t BSL_UIO_GetTransportType(const BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Set the user data in the UIO object + * + * UIO will not modify the user data, user can add some information + * for the UIO, and get the information by use BSL_UIO_GetUserData function; After you set user data by calling + * BSL_UIO_SetUserData, you need to call BSL_UIO_SetUserData again before calling BSL_UIO_Free to set + * user data to null to ensure that all memory is released. + * + * @param uio [IN] UIO object. + * @param data [IN] User data pointer + * @retval #BSL_SUCCESS, success. + * @retval #BSL_NULL_INPUT, invalid null pointer. + */ +int32_t BSL_UIO_SetUserData(BSL_UIO *uio, void *data); + +/** + * @ingroup bsl_uio + * @brief Release the user data set in the UIO object. + * + * Free uio->userData at BSL_UIO_Free. + * + * @param uio [IN] UIO object + * @param data [IN] Pointer to the function for releasing user data + * @retval #BSL_SUCCESS, success. + * @retval #BSL_NULL_INPUT, invalid null pointer. + */ +int32_t BSL_UIO_SetUserDataFreeFunc(BSL_UIO *uio, BSL_UIO_USERDATA_FREE_FUNC userDataFreeFunc); + +/** + * @ingroup bsl_uio + * @brief Obtain the user data in the UIO object. + * + * The user data comes from users, and tls will not change any thing + * for user data, user can add some customize information. + * + * @param uio [IN] UIO object. + * @retval Succeeded in obtaining the data structure pointer stored by the user. + * @retval NULL, the obtained data does not exist. + */ +void *BSL_UIO_GetUserData(const BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Obtains whether resources associated with the UIO are closed by the UIO. + * + * @param uio [OUT] UIO object + * @retval ture The resources associated with the UIO are closed by the UIO. + * @retval false The resources associated with the UIO are not closed by the UIO. + */ +bool BSL_UIO_GetIsUnderlyingClosedByUio(const BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Set whether resources associated with the UIO are closed by the UIO. + * + * @param uio [IN/OUT] UIO object + * @param close [IN] true UIO-associated resources are closed by the UIO. + * false The resources associated with the UIO are not closed by the UIO. + */ +void BSL_UIO_SetIsUnderlyingClosedByUio(BSL_UIO *uio, bool close); + +/** + * @ingroup bsl_uio + * @brief Method for obtaining the UIO + * + * @param uio [IN/OUT] UIO object + * @retval UIO method + */ +const BSL_UIO_Method *BSL_UIO_GetMethod(const BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Obtain the implementation-related context. + * + * @param uio [IN] UIO object + * @retval Implementation-related context pointer + */ +void *BSL_UIO_GetCtx(const BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Set the implementation-related context. + * + * @param uio [IN] UIO object + * @param ctx [IN] Implement the relevant context pointer. + */ +void BSL_UIO_SetCtx(BSL_UIO *uio, void *ctx); + +/** + * @ingroup bsl_uio + * @brief Set the fd of the UIO object + * + * @param uio [IN] UIO object + * @param fd [IN] File Descriptor fd + */ +void BSL_UIO_SetFd(BSL_UIO *uio, int fd); + +/** + * @ingroup bsl_uio + * @brief Set the UIO object flag. + * + * @param uio [IN] UIO object + * @param flags [IN] flag + * @retval #BSL_SUCCESS, succeeded. + * @retval Other reference: bsl_errno.h. + */ +int32_t BSL_UIO_SetFlags(BSL_UIO *uio, uint32_t flags); + +/** + * @ingroup bsl_uio + * @brief Clear the UIO object flag + * + * @param uio [IN] UIO object + * @param flags [IN] flag + * @retval #BSL_SUCCESS, succeeded. + * @retval Other reference: bsl_errno.h. + */ +int32_t BSL_UIO_ClearFlags(BSL_UIO *uio, uint32_t flags); + +/** + * @ingroup bsl_uio + * @brief Check the UIO object flag + * + * @param uio [IN] UIO object + * @param flags [IN] To-be-checked flag + * @param out [OUT] Mark the detection result + * @retval #BSL_SUCCESS, succeeded. + * @retval Other reference: bsl_errno.h + */ +uint32_t BSL_UIO_TestFlags(const BSL_UIO *uio, uint32_t flags, uint32_t *out); + +/** + * @ingroup bsl_uio + * @brief Set the value of uio reference counting to 1 + * + * @attention Call BSL_UIO_Free to decrease the value of reference counting by 1 + * @param uio [IN] uio object + * @retval #BSL_SUCCESS, the setting is successful. + * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. + * @retval #BSL_UIO_REF_MAX, The number of UIO objects has reached the maximum. + */ +int32_t BSL_UIO_UpRef(BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Add a UIO object to the tail of the chain. + * + * @attention The reference counting of the added UIO object will not increase by 1. + * @param uio [IN] uio object + * @param tail [IN] UIO object added to the tail + * @retval #BSL_SUCCESS, success. + * @retval Non-BSL_SUCCESS, failure. For details, see bsl_errno.h. + */ +int32_t BSL_UIO_Append(BSL_UIO *uio, BSL_UIO *tail); + +/** + * @ingroup bsl_uio + * @brief Pop UIO object from the chain. + * + * @attention The reference counting of the added UIO object does not decrease by 1. + * @param uio [IN] UIO object of the pop-up link. + * @retval The next UIO object in the chain. + */ +BSL_UIO *BSL_UIO_PopCurrent(BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Release UIO object b and its subsequent chains. + * + * @attention: The release starts from b. + * If the reference counting of a UIO object in the chain is greater than or equal to 1, the release stops + * @param uio [IN] First UIO object in the UIO object chain to be released + */ +void BSL_UIO_FreeChain(BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Obtain the next UIO object in the chain. + * + * @param uio [IN] UIO object + * @retval Next UIO object in the chain. + */ +BSL_UIO *BSL_UIO_Next(BSL_UIO *uio); + +/** + * @ingroup bsl_uio + * @brief Set the UIO init. + * + * @param uio [IN] UIO object + * @param init [IN] init value + */ +void BSL_UIO_SetInit(BSL_UIO *uio, bool init); + +#ifdef __cplusplus +} +#endif + +#endif // BSL_UIO_H diff --git a/include/bsl/bsl_user_data.h b/include/bsl/bsl_user_data.h new file mode 100644 index 00000000..608b0f68 --- /dev/null +++ b/include/bsl/bsl_user_data.h @@ -0,0 +1,67 @@ +/* + * 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_userdata + * @ingroup bsl + * @brief user data module + */ + +#ifndef BSL_USER_DATA_H +#define BSL_USER_DATA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup bsl_userdata + * + * Modify the BSL_MAX_EX_TYPE if a new index is added. + */ +#define BSL_USER_DATA_EX_INDEX_SSL 0 +#define BSL_USER_DATA_EX_INDEX_X509_STORE_CTX 1 +#define BSL_USER_DATA_EX_INDEX_SSL_CTX 2 +#define BSL_USER_DATA_EX_INDEX_X509_STORE 3 +#define BSL_USER_DATA_EX_INDEX_UIO 4 + +#define BSL_MAX_EX_TYPE 5 +#define BSL_MAX_EX_DATA 20 + +typedef struct { + void *sk[BSL_MAX_EX_DATA]; +} BSL_USER_ExData; + +typedef void BSL_USER_ExDataNew(void *parent, void *ptr, BSL_USER_ExData *ad, int idx, long argl, void *argp); +typedef void BSL_USER_ExDataFree(void *parent, void *ptr, BSL_USER_ExData *ad, int idx, long argl, void *argp); +typedef int BSL_USER_ExDataDup(BSL_USER_ExData *to, const BSL_USER_ExData *from, void **fromD, int idx, long argl, + void *argp); + +int BSL_USER_SetExData(BSL_USER_ExData *ad, int32_t idx, void *val); + +void *BSL_USER_GetExData(const BSL_USER_ExData *ad, int32_t idx); + +int BSL_USER_GetExDataNewIndex(int32_t index, int64_t argl, const void *argp, void *newFunc, void *dupFunc, + void *freeFunc); + +void BSL_USER_FreeExDataIndex(int32_t index, void *obj, BSL_USER_ExData *ad); + +#ifdef __cplusplus +} +#endif + +#endif // BSL_USER_DATA_H diff --git a/include/crypto/crypt_algid.h b/include/crypto/crypt_algid.h new file mode 100644 index 00000000..124e8e02 --- /dev/null +++ b/include/crypto/crypt_algid.h @@ -0,0 +1,224 @@ +/* + * 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 crypt + * @brief crypto module + */ + +/** + * @defgroup crypt_algid + * @ingroup crypt + * @brief id of algorithms + */ + +#ifndef CRYPT_ALGID_H +#define CRYPT_ALGID_H + +#include "bsl_obj.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @ingroup crypt_algid + * + * RAND algorithm ID + */ +typedef enum { + CRYPT_RAND_SHA1 = BSL_CID_RAND_SHA1, + CRYPT_RAND_SHA224 = BSL_CID_RAND_SHA224, + CRYPT_RAND_SHA256 = BSL_CID_RAND_SHA256, + CRYPT_RAND_SHA384 = BSL_CID_RAND_SHA384, + CRYPT_RAND_SHA512 = BSL_CID_RAND_SHA512, + CRYPT_RAND_HMAC_SHA1 = BSL_CID_RAND_HMAC_SHA1, + CRYPT_RAND_HMAC_SHA224 = BSL_CID_RAND_HMAC_SHA224, + CRYPT_RAND_HMAC_SHA256 = BSL_CID_RAND_HMAC_SHA256, + CRYPT_RAND_HMAC_SHA384 = BSL_CID_RAND_HMAC_SHA384, + CRYPT_RAND_HMAC_SHA512 = BSL_CID_RAND_HMAC_SHA512, + CRYPT_RAND_AES128_CTR = BSL_CID_RAND_AES128_CTR, + CRYPT_RAND_AES192_CTR = BSL_CID_RAND_AES192_CTR, + CRYPT_RAND_AES256_CTR = BSL_CID_RAND_AES256_CTR, + CRYPT_RAND_AES128_CTR_DF = BSL_CID_RAND_AES128_CTR_DF, + CRYPT_RAND_AES192_CTR_DF = BSL_CID_RAND_AES192_CTR_DF, + CRYPT_RAND_AES256_CTR_DF = BSL_CID_RAND_AES256_CTR_DF, + CRYPT_RAND_ALGID_MAX = BSL_CID_UNKNOWN +} CRYPT_RAND_AlgId; + +/** + * @ingroup crypt_algid + * + * Hash algorithm ID + */ +typedef enum { + CRYPT_MD_MD4 = BSL_CID_MD4, + CRYPT_MD_MD5 = BSL_CID_MD5, + CRYPT_MD_SHA1 = BSL_CID_SHA1, + CRYPT_MD_SHA224 = BSL_CID_SHA224, + CRYPT_MD_SHA256 = BSL_CID_SHA256, + CRYPT_MD_SHA384 = BSL_CID_SHA384, + CRYPT_MD_SHA512 = BSL_CID_SHA512, + CRYPT_MD_SHA3_224 = BSL_CID_SHA3_224, + CRYPT_MD_SHA3_256 = BSL_CID_SHA3_256, + CRYPT_MD_SHA3_384 = BSL_CID_SHA3_384, + CRYPT_MD_SHA3_512 = BSL_CID_SHA3_512, + CRYPT_MD_SHAKE128 = BSL_CID_SHAKE128, + CRYPT_MD_SHAKE256 = BSL_CID_SHAKE256, + CRYPT_MD_SM3 = BSL_CID_SM3, + CRYPT_MD_MAX = BSL_CID_UNKNOWN +} CRYPT_MD_AlgId; + +/** + * @ingroup crypt_algid + * + * MAC algorithm ID + */ +typedef enum { + CRYPT_MAC_HMAC_MD5 = BSL_CID_HMAC_MD5, + CRYPT_MAC_HMAC_SHA1 = BSL_CID_HMAC_SHA1, + CRYPT_MAC_HMAC_SHA224 = BSL_CID_HMAC_SHA224, + CRYPT_MAC_HMAC_SHA256 = BSL_CID_HMAC_SHA256, + CRYPT_MAC_HMAC_SHA384 = BSL_CID_HMAC_SHA384, + CRYPT_MAC_HMAC_SHA512 = BSL_CID_HMAC_SHA512, + CRYPT_MAC_HMAC_SHA3_224 = BSL_CID_HMAC_SHA3_224, + CRYPT_MAC_HMAC_SHA3_256 = BSL_CID_HMAC_SHA3_256, + CRYPT_MAC_HMAC_SHA3_384 = BSL_CID_HMAC_SHA3_384, + CRYPT_MAC_HMAC_SHA3_512 = BSL_CID_HMAC_SHA3_512, + CRYPT_MAC_HMAC_SM3 = BSL_CID_HMAC_SM3, + CRYPT_MAC_MAX = BSL_CID_UNKNOWN +} CRYPT_MAC_AlgId; + +/** + * @ingroup crypt_algid + * + * Asymmetric algorithm ID + */ +typedef enum { + CRYPT_PKEY_DSA = BSL_CID_DSA, + CRYPT_PKEY_ED25519 = BSL_CID_ED25519, + CRYPT_PKEY_X25519 = BSL_CID_X25519, + CRYPT_PKEY_RSA = BSL_CID_RSA, + CRYPT_PKEY_DH = BSL_CID_DH, + CRYPT_PKEY_ECDSA = BSL_CID_ECDSA, + CRYPT_PKEY_ECDH = BSL_CID_ECDH, + CRYPT_PKEY_SM2 = BSL_CID_SM2, + CRYPT_PKEY_PAILLIER = BSL_CID_PAILLIER, + CRYPT_PKEY_MAX = BSL_CID_UNKNOWN +} CRYPT_PKEY_AlgId; + +/** + * @ingroup cipher_algid + * @brief Symmetric algorithm mode ID + * + * There is a mapping relationship with the g_ealCipherMethod list. Attention any modification must be synchronized. + */ +typedef enum { + CRYPT_CIPHER_AES128_CBC = BSL_CID_AES128_CBC, + CRYPT_CIPHER_AES192_CBC = BSL_CID_AES192_CBC, + CRYPT_CIPHER_AES256_CBC = BSL_CID_AES256_CBC, + + CRYPT_CIPHER_AES128_CTR = BSL_CID_AES128_CTR, + CRYPT_CIPHER_AES192_CTR = BSL_CID_AES192_CTR, + CRYPT_CIPHER_AES256_CTR = BSL_CID_AES256_CTR, + + CRYPT_CIPHER_AES128_CCM = BSL_CID_AES128_CCM, + CRYPT_CIPHER_AES192_CCM = BSL_CID_AES192_CCM, + CRYPT_CIPHER_AES256_CCM = BSL_CID_AES256_CCM, + + CRYPT_CIPHER_AES128_GCM = BSL_CID_AES128_GCM, + CRYPT_CIPHER_AES192_GCM = BSL_CID_AES192_GCM, + CRYPT_CIPHER_AES256_GCM = BSL_CID_AES256_GCM, + + CRYPT_CIPHER_CHACHA20_POLY1305 = BSL_CID_CHACHA20_POLY1305, + + CRYPT_CIPHER_SM4_XTS = BSL_CID_SM4_XTS, + CRYPT_CIPHER_SM4_CBC = BSL_CID_SM4_CBC, + CRYPT_CIPHER_SM4_CTR = BSL_CID_SM4_CTR, + CRYPT_CIPHER_SM4_GCM = BSL_CID_SM4_GCM, + CRYPT_CIPHER_SM4_CFB = BSL_CID_SM4_CFB, + CRYPT_CIPHER_SM4_OFB = BSL_CID_SM4_OFB, + + CRYPT_CIPHER_AES128_CFB = BSL_CID_AES128_CFB, + CRYPT_CIPHER_AES192_CFB = BSL_CID_AES192_CFB, + CRYPT_CIPHER_AES256_CFB = BSL_CID_AES256_CFB, + CRYPT_CIPHER_AES128_OFB = BSL_CID_AES128_OFB, + CRYPT_CIPHER_AES192_OFB = BSL_CID_AES192_OFB, + CRYPT_CIPHER_AES256_OFB = BSL_CID_AES256_OFB, + + CRYPT_CIPHER_MAX = BSL_CID_UNKNOWN, +} CRYPT_CIPHER_AlgId; + +/** + * @ingroup crypt_algid + * + * Parameter ID of an asymmetric algorithm. The most significant 16 bits indicate the algorithm ID, + * and the least significant 16 bits map the ID definition of the algorithm LowLevel. + */ +typedef enum { + CRYPT_DH_RFC2409_768 = BSL_CID_DH_RFC2409_768, + CRYPT_DH_RFC2409_1024 = BSL_CID_DH_RFC2409_1024, + CRYPT_DH_RFC3526_1536 = BSL_CID_DH_RFC3526_1536, + CRYPT_DH_RFC3526_2048 = BSL_CID_DH_RFC3526_2048, + CRYPT_DH_RFC3526_3072 = BSL_CID_DH_RFC3526_3072, + CRYPT_DH_RFC3526_4096 = BSL_CID_DH_RFC3526_4096, + CRYPT_DH_RFC3526_6144 = BSL_CID_DH_RFC3526_6144, + CRYPT_DH_RFC3526_8192 = BSL_CID_DH_RFC3526_8192, + CRYPT_DH_RFC7919_2048 = BSL_CID_DH_RFC7919_2048, + CRYPT_DH_RFC7919_3072 = BSL_CID_DH_RFC7919_3072, + CRYPT_DH_RFC7919_4096 = BSL_CID_DH_RFC7919_4096, + CRYPT_DH_RFC7919_6144 = BSL_CID_DH_RFC7919_6144, + CRYPT_DH_RFC7919_8192 = BSL_CID_DH_RFC7919_8192, + CRYPT_ECC_NISTP224 = BSL_CID_NIST_PRIME224, + CRYPT_ECC_NISTP256 = BSL_CID_PRIME256V1, + CRYPT_ECC_NISTP384 = BSL_CID_SECP384R1, + CRYPT_ECC_NISTP521 = BSL_CID_SECP521R1, + CRYPT_ECC_BRAINPOOLP256R1 = BSL_CID_ECC_BRAINPOOLP256R1, + CRYPT_ECC_BRAINPOOLP384R1 = BSL_CID_ECC_BRAINPOOLP384R1, + CRYPT_ECC_BRAINPOOLP512R1 = BSL_CID_ECC_BRAINPOOLP512R1, + CRYPT_ECC_SM2 = BSL_CID_SM2PRIME256, + CRYPT_PKEY_PARAID_MAX = BSL_CID_UNKNOWN +} CRYPT_PKEY_ParaId; + +/** + * @ingroup crypt_algid + * + * Elliptic Curve Point Encoding Format + */ +typedef enum { + CRYPT_POINT_COMPRESSED, + CRYPT_POINT_UNCOMPRESSED, /**< default format. */ + CRYPT_POINT_HYBRID, + CRYPT_POINT_MAX +} CRYPT_PKEY_PointFormat; + +/** + * @ingroup crypt_algid + * + * KDF algorithm ID + */ +typedef enum { + CRYPT_KDF_SCRYPT = BSL_CID_SCRYPT, + CRYPT_KDF_PBKDF2 = BSL_CID_PBKDF2, + CRYPT_KDF_KDFTLS12 = BSL_CID_KDFTLS12, + CRYPT_KDF_HKDF = BSL_CID_HKDF, + CRYPT_KDF_MAX = BSL_CID_UNKNOWN +} CRYPT_KDF_AlgId; + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_ALGID_H diff --git a/include/crypto/crypt_eal_cipher.h b/include/crypto/crypt_eal_cipher.h new file mode 100644 index 00000000..c5c3f685 --- /dev/null +++ b/include/crypto/crypt_eal_cipher.h @@ -0,0 +1,249 @@ +/* + * 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 crypt_eal_cipher + * @ingroup crypt + * @brief cipher suites + */ + +#ifndef CRYPT_EAL_CIPHER_H +#define CRYPT_EAL_CIPHER_H + +#include +#include +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_method.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct CryptEalCipherCtx CRYPT_EAL_CipherCtx; + +/** + * @ingroup crypt_eal_cipher + * @brief Check whether the given symmetric algorithm ID is valid. + * + * @param id [IN] Symmetric algorithm ID. + * @retval Valid, true is returned. + * Invalid, false is returned. + */ +bool CRYPT_EAL_CipherIsValidAlgId(CRYPT_CIPHER_AlgId id); + +/** + * @ingroup crypt_eal_cipher + * @brief Generate symmetric encryption and decryption handles. + * + * @attention If the function is called by an external user and the error stack is concerned, + * it is recommended that BSL_ERR_ClearError() be called before this function is called. + * @param id [IN] Symmetric encryption/decryption algorithm ID. + * @retval Success: cipher ctx. + * Fails: NULL. + */ +CRYPT_EAL_CipherCtx* CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AlgId id); + +/** + * @ingroup crypt_eal_cipher + * @brief Release the symmetric encryption/decryption handle. Clear sensitive information before releasing the handle. + * + * @attention If the function is called by an external user and the error stack is concerned, it is recommended + * that BSL_ERR_ClearError() be called before this function is called. + * @param ctx [IN] Symmetric encryption/decryption handle. The CTX is set null by the caller. + */ +void CRYPT_EAL_CipherFreeCtx(CRYPT_EAL_CipherCtx *ctx); + +/** + * @ingroup crypt_eal_cipher + * @brief Initialize the symmetric encryption/decryption handle. The key cannot be null. Except the ECB mode, + * other modes iv cannot be null. + * + * The length of iv must be the same as the block length (this requirement is not required in ECB mode). + * The block length can be obtained through CRYPT_CTRL_GET_BLOCKSIZE of CRYPT_EAL_CipherCtrl. + * CRYPT_EAL_CipherInit can be called repeatedly at any stage, resets the key and iv, and clears the cached data. + * + * @attention If the function is called by an external user and the error stack is concerned, + * you are advised to call BSL_ERR_ClearError() before calling this function. + * + * @param ctx [IN] Symmetric encryption/decryption handle + * @param key [IN] Key + * @param keyLen [IN] Key length + * @param iv [IN] Initialization vector + * @param ivLen [IN] Initialize the vector length. + * @param enc [IN] True: encryption; False: decryption + * @retval #CRYPT_SUCCESS, success. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_CipherInit(CRYPT_EAL_CipherCtx *ctx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv, + uint32_t ivLen, bool enc); + +/** + * @ingroup crypt_eal_cipher + * @brief Deinitialize the handle and restore the handle to the state, + * when the CRYPT_EAL_CipherNewCtx function is called. + * + * @attention If the function is called by an external user and the error stack is concerned, + * you are advised to call BSL_ERR_ClearError() before calling this function. + * @param ctx [IN] Symmetric encryption/decryption handle + */ +void CRYPT_EAL_CipherDeinit(CRYPT_EAL_CipherCtx *ctx); + +/** + * @ingroup crypt_eal_cipher + * + * Re-initialize the handle, retain the key, reset the IV, and clear the cache and sensitive data. + * Except the ECB mode, other modes iv cannot be null. The setting of iv must be based on the corresponding + * algorithm ID. For details, see the mapping in CRYPT_EAL_CipherInit. + * + * @param ctx [IN] Symmetric encryption/decryption handle + * @param iv [IN] Vector + * @param ivlen [IN] Vector length + */ +int32_t CRYPT_EAL_CipherReinit(CRYPT_EAL_CipherCtx *ctx, uint8_t *iv, uint32_t ivLen); + +/** + * @ingroup crypt_eal_cipher + * + * Continuously enter encrypted and decrypted data. + * CRYPT_EAL_CipherUpdate should be used in conjunction with CRYPT_EAL_CipherFinal, after one or more calls to + * CRYPT_EAL_CipherUpdate, Call CRYPT_EAL_CipherFinal. With the exception of SM4_XTS mode, multiple calls to + * CRYPT_EAL_CipherUpdate and CRYPT_EAL_CipherFinal are not supported. + * + * @attention If the function is called by an external user and the error stack is concerned, it is recommended + * that BSL_ERR_ClearError() be called before this function is called. + * + * @param ctx [IN] Symmetric encryption and decryption handle + * @param in [IN] Continuously input data + * @param inLen [IN] Length of continuously input data + * @param out [OUT] Output data + * @param outLen [IN/OUT] Input: For CBC and ECB block encryption, you are advised to set outLen > inLen + blockSize. + * For CTR and XTS stream encryption, you are advised to set outLen >= inLen. blockSize can be obtained by using + * CRYPT_CTRL_GET_BLOCKSIZE of CRYPT_EAL_CipherCtrl. + * Output: Length of the encrypted data. If the block encryption algorithm is used and the length of the last data + * to be processed is insufficient, the output value of outLen is 0. + * eg: CBC and ECB block encryption + * 1. Encrypted data is input for the first time, and inLen is less than blockSize. + * In this case, the output value of outLen is 0. + * 2. In the first input encrypted data length, inLen is an integer multiple of blockSize. + * In this case, outLen is equal to inLen. + * 3. In the first input encrypted data length, inLen > blockSize and not an integer multiple of blockSize. + * In this case, outLen < inLen. + * 4. Enter the encrypted data for multiple times. (inLen% blockSize) + cache (CTX cache data) >= blockSize. + * At this point outLen = (inlen / blockSize) * blockSize + blockSize + * CTR outLen equals inLen. + * In XTS mode, update reserves the last two blocks for final processing, If the total length of the input data + * plus the buffer is less than 32 blocks, the output is 0. + * 1. When data is input for the first time, outLen = (inLen / 16 - 2) * 16. + * 2. Enter the encrypted data for multiple times. At this time, outLen = ((inLen + cache) / 16 - 2) * 16. + * In SM4_XTS mode, after calling CRYPT_EAL_CipherUpdate, you need to use CRYPT_EAL_CipherInit or + * CRYPT_EAL_CipherReinit to reset the key or iv. + * @retval #CRYPT_SUCCESS, success. + * Other error codes see the crypt_errno.h. + */ +int32_t CRYPT_EAL_CipherUpdate(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out, + uint32_t *outLen); + +/** + * @ingroup crypt_eal_cipher + * @brief Fill the data with the size of the block and output the encrypted data; the AEAD tag is obtained + * through CRYPT_EAL_CipherCtrl. + * For block encryption algorithms such as CBC and ECB, padding must be set, In XTS mode, final needs + * to be called to obtain the last two blocks. + * @attention If the function is called by an external user and the error stack is concerned, + * you are advised to call BSL_ERR_ClearError() before calling this function. + * + * @param ctx [IN] Symmetric encryption/decryption handle + * @param out [OUT] Output the encrypted data + * @param outLen [IN/OUT] Input: outLen >= blockSize + * Output: The output value for stream encryption is 0. + * If padding is set for CBC and ECB block encryption, the output value of outLen is blockSize. + * If the padding is not set for CBC and ECB block encryption and CTX contains cached data, an error is reported. + * If padding is not set for CBC and ECB block encryption, and no data is cached in the CTX, the output value of + * outLen is 0. + * @retval #CRYPT_SUCCESS, success. + * Other error codes see the crypt_errno.h. + */ +int32_t CRYPT_EAL_CipherFinal(CRYPT_EAL_CipherCtx *ctx, uint8_t *out, uint32_t *outLen); + +/** + * @ingroup crypt_eal_cipher + * + * Set the mode ctx parameters in the CTX. + * parameter data type Length(len):number of data bytes + * CRYPT_CTRL_GET_IV uint8_t array The length of the IV depends on the corresponding algorithm, + see the mapping in CRYPT_EAL_CipherInit + * CRYPT_CTRL_SET_IV uint8_t array The length of the IV depends on the corresponding algorithm, + see the mapping in CRYPT_EAL_CipherInit. + * CRYPT_CTRL_SET_AAD uint8_t array It is used only for AEAD calculation. + The length is related to the corresponding AEAD algorithm. + * CRYPT_CTRL_GET_TAG uint8_t array It is used only for AEAD calculation. + The length is the tagLen value set by the user. + * CRYPT_CTRL_SET_COUNT uint8_t[4] length(len) 4 + * CRYPT_CTRL_SET_TAGLEN uint32_t length(len) 4 + * CRYPT_CTRL_SET_MSGLEN uint64_t length(len) 8 + * CRYPT_CTRL_SET_FEEDBACKSIZE uint32_t length(len) 4 + * CRYPT_CTRL_GET_FEEDBACKSIZE uint32_t pointer sizeof(*uint32_t) + * CRYPT_CTRL_GET_BLOCKSIZE uint32_t length(len) 4 + * CRYPT_CTRL_SET_SM4_CONSTTIME NULL 0 + * + * @attention If the function is called by an external user and the error stack is concerned, + * it is recommended that BSL_ERR_ClearError() be called before this function is called. + * @param ctx [IN] Symmetric encryption/decryption handle + * @param type [IN] Parameter type + * @param data [IN/OUT] Input and output data + * @param len [OUT] Data length + * @retval #CRYPT_SUCCESS, success. + * error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_CipherCtrl(CRYPT_EAL_CipherCtx *ctx, int32_t type, void *data, uint32_t len); + +/** + * @ingroup crypt_eal_cipher + * @brief Set the padding mode. + * + * @param ctx Symmetric encryption/decryption handle + * @param type Padding type + * @retval #CRYPT_SUCCESS, success. + * Error codes see crypt_errno.h + */ +int32_t CRYPT_EAL_CipherSetPadding(CRYPT_EAL_CipherCtx *ctx, CRYPT_PaddingType type); + +/** + * @ingroup crypt_eal_cipher + * @brief Obtain the padding type. + * + * @param ctx Symmetric encryption/decryption handle + * @retval Return mode + */ +int32_t CRYPT_EAL_CipherGetPadding(CRYPT_EAL_CipherCtx *ctx); + +/** + * @ingroup crypt_eal_cipher + * @brief Obtain the type of an algorithm based on the algorithm ID. + * + * @param id [IN] Symmetric algorithm ID. + * @param type [IN] Attribute type to be obtained. + * @param infoValue [OUT] Obtained attribute data. + * @retval CRYPT_SUCCESS, success + * Other error codes see crypt_errno.h + */ +int32_t CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AlgId id, int32_t type, uint32_t *infoValue); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_EAL_CIPHER_H diff --git a/include/crypto/crypt_eal_encode.h b/include/crypto/crypt_eal_encode.h new file mode 100644 index 00000000..72e0af60 --- /dev/null +++ b/include/crypto/crypt_eal_encode.h @@ -0,0 +1,135 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @defgroup crypt_eal_encode + * @ingroup crypt + * @brief pubkey encode/decode of crypto module + */ + +#ifndef CRYPT_EAL_ENCODE_H +#define CRYPT_EAL_ENCODE_H + +#include + +#include "bsl_type.h" +#include "crypt_eal_pkey.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum { + CRYPT_ENCODE_UNKNOW, + CRYPT_PRIKEY_PKCS8_UNENCRYPT, + CRYPT_PRIKEY_PKCS8_ENCRYPT, + CRYPT_PRIKEY_RSA, + CRYPT_PRIKEY_ECC, + CRYPT_PUBKEY_SUBKEY, + CRYPT_PUBKEY_RSA +} CRYPT_ENCODE_TYPE; + +typedef enum { + CRYPT_DERIVE_PBKDF2, +} CRYPT_DERIVE_MODE; + +typedef struct { + uint32_t deriveMode; + void *param; +} CRYPT_EncodeParam; + +typedef struct { + uint32_t pbesId; + uint32_t pbkdfId; + uint32_t hmacId; + uint32_t symId; + uint32_t saltLen; + uint8_t *pwd; + uint32_t pwdLen; + uint32_t itCnt; +} CRYPT_Pbkdf2Param; + + +/** + * @ingroup crypt_eal_encode + * @brief Decode formatted buffer of pkey + * + * @param format [IN] the buffer format. + * @param type [IN] the type of pkey. + * @param encode [IN] the encoded asn1 buffer. + * @param pwd [IN] the password, maybe NULL for unencrypted private key / public key. + * @param pwdlen [IN] the length of password. + * @param ealPKey [OUT] created CRYPT_EAL_PkeyCtx which parsed from the ans1 buffer. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_DecodeBuffKey(BSL_ParseFormat format, int32_t type, + BSL_Buffer *encode, const uint8_t *pwd, uint32_t pwdlen, CRYPT_EAL_PkeyCtx **ealPKey); + +/** + * @ingroup crypt_eal_encode + * @brief Decode formatted file of pkey + * + * @param format [IN] the file format. + * @param type [IN] the type of pkey. + * @param path [IN] the encoded file path. + * @param pwd [IN] the password, maybe NULL for unencrypted private key / public key. + * @param pwdlen [IN] the length of password. + * @param ealPKey [OUT] created CRYPT_EAL_PkeyCtx which parsed from the path. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_DecodeFileKey(BSL_ParseFormat format, int32_t type, const char *path, + uint8_t *pwd, uint32_t pwdlen, CRYPT_EAL_PkeyCtx **ealPKey); + +/** + * @ingroup crypt_eal_encode + * @brief Encode formatted buffer of pkey + * + * @param ealPKey [IN] CRYPT_EAL_PkeyCtx to encode. + * @param encodeParam [IN] pkcs8 encode params. + * @param format [IN] the buffer format. + * @param type [IN] the type of pkey. + * @param encode [OUT] the encoded asn1 buffer. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_EncodeBuffKey(CRYPT_EAL_PkeyCtx *ealPKey, const CRYPT_EncodeParam *encodeParam, + BSL_ParseFormat format, int32_t type, BSL_Buffer *encode); + +/** + * @ingroup crypt_eal_encode + * @brief Encode formatted file of pkey + * + * @param ealPKey [IN] CRYPT_EAL_PkeyCtx to encode. + * @param encodeParam [IN] pkcs8 encode params. + * @param format [IN] the file format. + * @param type [IN] the type of pkey. + * @param path [IN] the encoded file path. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_EncodeFileKey(CRYPT_EAL_PkeyCtx *ealPKey, const CRYPT_EncodeParam *encodeParam, + BSL_ParseFormat format, int32_t type, const char *path); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_EAL_ENCODE_H \ No newline at end of file diff --git a/include/crypto/crypt_eal_kdf.h b/include/crypto/crypt_eal_kdf.h new file mode 100644 index 00000000..34fbd232 --- /dev/null +++ b/include/crypto/crypt_eal_kdf.h @@ -0,0 +1,226 @@ +/* + * 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 crypt_eal_kdf + * @ingroup crypt + * @brief kdf of crypto module + */ + +#ifndef CRYPT_EAL_KDF_H +#define CRYPT_EAL_KDF_H + +#include +#include +#include "crypt_algid.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus +/** + * @ingroup crypt_eal_kdf + * @brief scrypt Password-based key derivation function + * + * @param key [IN] Password, a string input by the user. + * @param keyLen [IN] Password length, including 0 + * @param salt [IN] Salt value, a string input by the user. + * @param saltLen [IN] Salt value length, including 0 + * @param n [IN] CPU and memory consumption parameters. + * The value must be a power of 2, greater than 1 and less than 2 ^ (128 * r / 8) + * @param r [IN] Block size parameter, any positive integer not 0 where r * p < 2 ^ 30 + * @param p [IN] Parallelization parameter, any positive integer not 0; p <= (2 ^ 32 - 1) * 32 / (128 * r) + * @param out [OUT] Derived key, which cannot be null. + * @param len [IN] Length of the derived key. Range: (0, 0xFFFFFFFF] + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_Scrypt(const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint32_t n, + uint32_t r, uint32_t p, uint8_t *out, uint32_t len); + +/** + * @ingroup crypt_eal_kdf + * @brief PBKDF password-based key derivation function + * + * @param id [IN] HMAC algorithm ID (Only the HMAC algorithm ID is supported, including + * CRYPT_MAC_HMAC_MD5, CRYPT_MAC_HMAC_SHA1, and CRYPT_MAC_HMAC_SHA224, + * CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512, + * CRYPT_MAC_HMAC_SM3) + * @param key [IN] Password, a string input by the user. + * @param keyLen [IN] The password length is any length, including 0. + * @param salt [IN] Salt value, a string input by the user. + * @param saltLen [IN] Salt value length, including 0. + * @param it [IN] Iteration times. The value can be a positive integer that is not 0. The value + * can be 1000 in special performance scenarios. The default value is 10000, + * 10000000 is recommended in scenarios where performance is insensitive or + * security requirements are high. + * @param out [OUT] Derive the key. + * @param len [IN] Length of the derived key. The value range is [1, 0xFFFFFFFF]. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_Pbkdf2(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *salt, + uint32_t saltLen, uint32_t it, uint8_t *out, uint32_t len); + +/** + * @ingroup crypt_eal_kdf + * @brief PKCS5 PBKDF This MPI encapsulates the CRYPT_EAL_Pbkdf2 API. By default, the CRYPT_MAC_HMAC_SHA256 + * algorithm is used for calculation. + * + * @param key [IN] Password, a string input by the user. + * @param keyLen [IN] Password length, which is a positive integer not 0. + * @param salt [IN] Salt value, a string input by the user. + * @param saltLen [IN] Salt length, any positive integer that is not 0. + * @param it [IN] Iteration times, the value can be a positive integer that is not 0. The value + * can be 1000 in special performance scenarios. The default value is 10000, 10000000 is recommended + * in scenarios where performance is insensitive or security requirements are high. + * @param out [OUT] Derive the key. + * @param len [IN] Length of the derived key, the value range is [1, 0xFFFFFFFF]. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +#define CRYPT_EAL_PKCS5_PBKDF2(key, keyLen, salt, saltLen, it, out, len) \ + CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, keyLen, salt, saltLen, it, out, len) + +/** + * @ingroup crypt_eal_kdf + * @brief HKDF + * + * @param id [IN] MAC algorithm ID (Only the HMAC algorithm ID is supported, including + * CRYPT_MAC_HMAC_SHA1, CRYPT_MAC_HMAC_SHA224, CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512) + * @param key [IN] Password, a string input by the user. + * @param keyLen [IN] Key length, any length + * @param salt [IN] Salt value, a string input by the user. + * @param saltLen [IN] Salt length, any length + * @param info [IN] Additional information about the user, which is optional. + * @param infoLen [IN] Length of the additional information. The value can be 0. [0,0xFFFFFFFF] + * @param out [OUT] Derive the key. + * @param len [IN] Derived key length, any integer other than 0. The maximum value is as follows: + * The maximum value of CRYPT_MAC_HMAC_SHA1 is 5100. + * The maximum value of CRYPT_MAC_HMAC_SHA224 is 7140. + * The maximum value of CRYPT_MAC_HMAC_SHA256 is 8160. + * The maximum value of CRYPT_MAC_HMAC_SHA384 is 12240. + * The maximum value of CRYPT_MAC_HMAC_SHA512 is 16320. + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_Hkdf(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, + const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len); + +/** + * @ingroup crypt_eal_kdf + * @brief HKDF + * + * @param id [IN] MAC algorithm ID (Only the HMAC algorithm ID is supported, including CRYPT_MAC_HMAC_SHA1, + * CRYPT_MAC_HMAC_SHA224, CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512) + * @param key [IN] Password, a string input by the user. + * @param keyLen [IN] Key length, any length + * @param salt [IN] Salt value, a string input by the user. + * @param saltLen [IN] Salt length, any length + * @param out [OUT] Pseudorandom key + * @param len [OUT] Pseudorandom key length + * + * @retval #CRYPT_SUCCESS, if success. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_HkdfExtract(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, + const uint8_t *salt, uint32_t saltLen, uint8_t *out, uint32_t *len); + +/** + * @ingroup crypt_eal_kdf + * @brief HKDF + * + * @param id [IN] MAC algorithm ID (Only the HMAC algorithm ID is supported, including CRYPT_MAC_HMAC_SHA1, + * CRYPT_MAC_HMAC_SHA224, CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512) + * @param key [IN] Pseudorandom key, at least hashLen (generally the output of the Extract function) + * @param keyLen [IN] Pseudorandom key length + * @param info [IN] Additional information about the user, which is optional. + * @param infoLen [IN] Length of the additional information. The value can be 0. [0,0xFFFFFFFF] + * @param out [OUT] Derive the key. + * @param len [IN] Derived key length, any integer other than 0. The maximum value is as follows: + * The maximum value of CRYPT_MAC_HMAC_SHA1 is 5100. + * The maximum value of CRYPT_MAC_HMAC_SHA224 is 7140. + * The maximum value of CRYPT_MAC_HMAC_SHA256 is 8160. + * The maximum value of CRYPT_MAC_HMAC_SHA384 is 12240. + * The maximum value of CRYPT_MAC_HMAC_SHA512 is 16320, + * + * @retval #CRYPT_SUCCESS, if success. + * Error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_HkdfExpand(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, + const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len); + +/** + * @ingroup crypt_eal_kdf + * @brief KDF-TLS1.2 + * + * @param id [IN] MAC algorithm ID (Only some HMAC algorithm IDs are supported.) + * These include CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, and CRYPT_MAC_HMAC_SHA512) + * @param key [IN] Key, string input by the user. + * @param keyLen [IN] Key length, any length. + * @param label [IN] Label, string input by the user, combined with the seed as the PRF input data. + * @param labelLen [IN] Label length, any length. + * @param seed [IN] Seed, string input by the user, used as the input data of the PRF. + * @param seedLen [IN] Seed length, any length. + * @param out [OUT] Derive the key. + * @param len [IN] Derived key length. the value range is [1, 0xFFFFFFFF]. + * + * @retval #CRYPT_SUCCESS, if success. + * Error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_KdfTls12(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *label, + uint32_t labelLen, const uint8_t *seed, uint32_t seedLen, uint8_t *out, uint32_t len); + +/** + * @ingroup crypt_eal_kdf + * @brief Check whether the given HKDF algorithm ID is valid. + * + * @param id [IN] HKDF algorithm ID. + * + * @retval true, if valid. + * false, if invalid. + */ +bool CRYPT_EAL_HkdfIsValidAlgId(CRYPT_MAC_AlgId id); + +/** + * @ingroup crypt_eal_kdf + * @brief Check whether the given PBKDF2 algorithm ID is valid. + * + * @param id [IN] PBKDF2 algorithm ID. + * + * @retval true, if valid. + * false, if invalid. + */ +bool CRYPT_EAL_Pbkdf2IsValidAlgId(CRYPT_MAC_AlgId id); + +/** + * @ingroup crypt_eal_kdf + * @brief Check whether the given KDFTLS12 algorithm ID is a valid KDFTLS12 algorithm ID. + * + * @param id [IN] KDFTLS12 algorithm ID + * + * @retval true, if valid. + * false, if invalid. + */ +bool CRYPT_EAL_Kdftls12IsValidAlgId(CRYPT_MAC_AlgId id); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_EAL_KDF_H \ No newline at end of file diff --git a/include/crypto/crypt_eal_mac.h b/include/crypto/crypt_eal_mac.h new file mode 100644 index 00000000..7e70e002 --- /dev/null +++ b/include/crypto/crypt_eal_mac.h @@ -0,0 +1,175 @@ +/* + * 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 crypt_eal_mac + * @ingroup crypt + * @brief mac of crypto module + */ + +#ifndef CRYPT_EAL_MAC_H +#define CRYPT_EAL_MAC_H + +#include +#include +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_method.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct EAL_MacCtx CRYPT_EAL_MacCtx; + +/** + * @ingroup crypt_eal_mac + * @brief Check whether the id is Valid MAC algorithm ID. + * + * @param id [IN] MAC algorithm ID + * + * @retval true, if valid. + * false, if invalid. + */ +bool CRYPT_EAL_MacIsValidAlgId(CRYPT_MAC_AlgId id); + +/** + * @ingroup crypt_eal_mac + * @brief Apply for a MAC context. + * + * @param id [IN] MAC algorithm ID + * + * @retval CRYPT_EAL_MacCtx Pointer. + * NULL, if the operation fails. + */ +CRYPT_EAL_MacCtx *CRYPT_EAL_MacNewCtx(CRYPT_MAC_AlgId id); + +/** + * @ingroup crypt_eal_mac + * @brief Release the MAC context memory. + * + * @param ctx [IN] MAC context, ctx set NULL by caller. + */ +void CRYPT_EAL_MacFreeCtx(CRYPT_EAL_MacCtx *ctx); + +/** + * @ingroup crypt_eal_mac + * + * MAC algorithm initialize the context, which is used after the CRYPT_EAL_MacNewCtx interface is called. + * The initialization interface can be used at any time during the calculation, note that the last calculation data + * is cleared after the initialization interface is called. + * + * @param ctx [IN] MAC context + * @param key [IN] Key, The length specifications are as follows: + * HMAC:Any integer greater than or equal to 0 + * The length of HMAC-SHA1, HMAC-SHA224, and HMAC-SHA256 must be less than 2^64 bits, + * the length of HMAC-SHA384 and HMAC-SHA512 must be less than 2^128 bits. + * HMAC-SHA3 series has no limit on length + * CMAC: The length of CMAC-AES128 must be 128 bits, and the length of CMAC-AES192 must be 192 bits. + * The length of CMAC-AES256 must be 256 bits. + * @param len [IN] Key length + * + * @retval #CRYPT_SUCCESS, initialization succeeded. + * @retval #CRYPT_NULL_INPUT, pointer ctx parameter or key parameter is NULL. + * @retval #CRYPT_AES_ERR_KEYLEN, the key length of the AES & CMAC algorithm is incorrect. + * Other error codes see the crypt_errno.h. + */ +int32_t CRYPT_EAL_MacInit(CRYPT_EAL_MacCtx *ctx, const uint8_t *key, uint32_t len); + +/** + * @ingroup crypt_eal_mac + * @brief Continuously input the MAC data. + * + * This command is used only after the CRYPT_EAL_MacInit interface is successfully called. + * + * @param ctx [IN] MAC context + * @param in [IN] Input data, when the variable is null, the len parameter must be 0. + * Otherwise, an error is reported. + * @param len [IN] Input data length, the value can be 0. + * + * @retval #CRYPT_SUCCESS, succeeded in updating the internal status of the digest. + * @retval #CRYPT_NULL_INPUT, the input parameter is NULL. + * @retval #CRYPT_EAL_ERR_STATE, status error. + * @retval #CRYPT_SHA1_INPUT_OVERFLOW, the length of the HMAC-SHA1 input data exceeds the maximum value. + * @retval #CRYPT_SHA2_INPUT_OVERFLOW, the length of the HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512 + * input data exceeds the maximum value, Other error codes see the crypt_errno.h. + */ +int32_t CRYPT_EAL_MacUpdate(CRYPT_EAL_MacCtx *ctx, const uint8_t *in, uint32_t len); + +/** + * @ingroup crypt_eal_mac + * @brief Output the MAC result. + * + * This API must be used after the CRYPT_EAL_MacInit API is successfully executed, during the process, you + * do not need to call the CRYPT_EAL_MacUpdate API. + * MAC output length. HMAC-SHA1 corresponds to 20 bytes, HMAC-SHA224 corresponds to 28 bytes, and HMAC-SHA256 + * corresponds to 32 bytes. HMAC-SHA384 corresponds to 48 bytes, HMAC-SHA512 corresponds to 64 bytes, and CMAC-AES + * corresponds to 16 bytes. HMAC-SHA3-224 corresponds to 28 bytes, HMAC-SHA3-256 corresponds to 32 bytes, + * HMAC-SHA3-384 corresponds to 48 bytes, and HMAC-SHA3-512 corresponds to 64 bytes. + * + * @param ctx [IN] MAC context + * @param out [OUT] Output data. Sufficient memory must be allocated to store MAC results and cannot be null. + * @param len [IN/OUT] Output data length. The input parameter must specify the out length, + * which must be greater than or equal to the length generated by the MAC. + * The output parameter is the output length of the MAC. + * + * @retval #CRYPT_SUCCESS, calculation succeeded. + * @retval #CRYPT_NULL_INPUT, the input parameter is NULL. + * @retval #CRYPT_EAL_ERR_STATE, status incorrect. + * @retval #CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH, the length of the output buffer in the HMAC algorithm is insufficient. + * @retval #CRYPT_CMAC_OUT_BUFF_LEN_NOT_ENOUGH, the length of the output buffer in the CMAC algorithm is insufficient. + * @retval #CRYPT_SHA1_INPUT_OVERFLOW, the length of the HMAC-SHA1 input data exceeds the maximum. + * @retval #CRYPT_SHA2_INPUT_OVERFLOW, the length of the input data in HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or + * HMAC-SHA512 exceeds the maximum value. + * Other error codes see the crypt_errno.h + */ +int32_t CRYPT_EAL_MacFinal(CRYPT_EAL_MacCtx *ctx, uint8_t *out, uint32_t *len); + +/** + * @ingroup crypt_eal_mac + * @brief Deinitialization function. + * + * If calculation is required after this function is called, it needs to be initialized again. + * + * @param ctx [IN] MAC context + */ +void CRYPT_EAL_MacDeinit(CRYPT_EAL_MacCtx *ctx); + +/** + * @ingroup crypt_eal_mac + * @brief Re-initialize with the information retained in ctx. + * + * @attention Doesn't need call the init interface again for initialization, it is equivalent to the combination + * of the deinit and init interfaces. + * @param ctx [IN] MAC context + * @retval #CRYPT_SUCCESS, reinit succeeded. + * @retval #CRYPT_NULL_INPUT, the input parameter is NULL. + */ +int32_t CRYPT_EAL_MacReinit(CRYPT_EAL_MacCtx *ctx); + +/** + * @ingroup crypt_eal_mac + * @brief Through the context, obtain the output MAC length of the corresponding algorithm. + * + * @param ctx [IN] MAC context + * @retval The MAC length corresponding to the context. + */ +uint32_t CRYPT_EAL_GetMacLen(const CRYPT_EAL_MacCtx *ctx); + +#ifdef __cplusplus +} // end extern "C" +#endif + +#endif // CRYPT_EAL_MAC_H diff --git a/include/crypto/crypt_eal_md.h b/include/crypto/crypt_eal_md.h new file mode 100644 index 00000000..45626e6d --- /dev/null +++ b/include/crypto/crypt_eal_md.h @@ -0,0 +1,182 @@ +/* + * 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 crypt_eal_md + * @ingroup crypt + * @brief md algorithms of crypto module + */ + +#ifndef CRYPT_EAL_MD_H +#define CRYPT_EAL_MD_H + +#include +#include +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_method.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct EAL_MdCtx CRYPT_EAL_MdCTX; + +/** + * @ingroup crypt_eal_md + * @brief Create the MD context. + * + * After the calculation is complete, call the CRYPT_EAL_MdFreeCtx interface to release the memory. + * + * @param id [IN] Algorithm ID + * @retval CRYPT_EAL_MdCTX, MD context pointer. + * NULL, if the operation fails. + */ +CRYPT_EAL_MdCTX *CRYPT_EAL_MdNewCtx(CRYPT_MD_AlgId id); + +/** + * @ingroup crypt_eal_md + * @brief Check whether the id is valid MD algorithm ID. + * + * @param id [IN] MD algorithm ID. + * @retval true, If the value is valid. + * false, If the value is invalid. + */ +bool CRYPT_EAL_MdIsValidAlgId(CRYPT_MD_AlgId id); + +/** + * @ingroup crypt_eal_md + * @brief Return the MD algorithm ID. + * + * @param pkey [IN] MD context + * @retval ID, MD algorithm ID. + * CRYPT_MD_MAX, which indicates invalid ID or the input parameter is null. + */ +CRYPT_MD_AlgId CRYPT_EAL_MdGetId(CRYPT_EAL_MdCTX *ctx); + +/** + * @ingroup crypt_eal_md + * @brief Copy the MD context. + * + * @param to [IN/OUT] Target MD context + * @param from [IN] Source MD context + * @retval #CRYPT_SUCCESS. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_MdCopyCtx(CRYPT_EAL_MdCTX *to, const CRYPT_EAL_MdCTX *from); + +/** + * @ingroup crypt_eal_md + * @brief Copy the MD context. + * + * Note that need to call the CRYPT_EAL_MdFreeCtx interface to release the memory after the duplication is complete. + * + * @param ctx [IN] Source MD context + * @retval CRYPT_EAL_MdCTX, MD context pointer. + * NULL, if the operation fails. + */ +CRYPT_EAL_MdCTX *CRYPT_EAL_MdDupCtx(const CRYPT_EAL_MdCTX *ctx); + +/** + * @ingroup crypt_eal_md + * @brief Release the MD context. + * + * @param ctx [IN] MD context. which is created by using the CRYPT_EAL_MdNewCtx interface and need to be set + * NULL by caller. + * @retval Void, no return value. + */ +void CRYPT_EAL_MdFreeCtx(CRYPT_EAL_MdCTX *ctx); + +/** + * @ingroup crypt_eal_md + * @brief Initialize the MD context. + * + * @param ctx [IN/OUT] MD context, which is created by using the CRYPT_EAL_MdNewCtx interface. + * @retval #CRYPT_SUCCESS. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_MdInit(CRYPT_EAL_MdCTX *ctx); + +/** + * @ingroup crypt_eal_md + * @brief Continuously input the data to be digested. + * + * @param ctx [IN/OUT] MD context, which is created by using the CRYPT_EAL_MdNewCtx interface. + * @param data [IN] Data to be digested. + * @param len [IN] Data length. + * The maximum length of sha384 and sha512 is [0, 2^128 bits). + * The maximum total length of sha1, sha224, sha256, sm3, and md5 is [0, 2^64 bits). + * The maximum length at a time is [0, 0xffffffff]. + * @retval #CRYPT_SUCCESS. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_MdUpdate(CRYPT_EAL_MdCTX *ctx, const uint8_t *data, uint32_t len); + +/** + * @ingroup crypt_eal_md + * @brief Complete the digest and output the final digest result. + * + * @param ctx [IN/OUT] MD context, which is created by using the CRYPT_EAL_MdNewCtx interface. + * @param out [OUT] Digest result cache, which needs to be created and managed by users. + * @param len [IN/OUT] The input parameter indicates the length of the buffer marked as "out", and the output + * parameter indicates the valid length of the obtained "out". The length must be greater than or equal to + * the hash length of the corresponding algorithm, the hash length can be obtained through the + * CRYPT_EAL_MdGetDigestSize interface. + * Requires user creation management. + * @retval #CRYPT_SUCCESS. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_MdFinal(CRYPT_EAL_MdCTX *ctx, uint8_t *out, uint32_t *len); + +/** + * @ingroup crypt_eal_md + * @brief Obtain the digest length of the algorithm output. + * + * @param id [IN] Algorithm ID + * @retval Digest length, if successful. + * 0, if failed(in this case, the ID is invalid). + */ +uint32_t CRYPT_EAL_MdGetDigestSize(CRYPT_MD_AlgId id); + +/** + * @ingroup crypt_eal_md + * @brief Calculate the data digest + * + * @param id [IN] Algorithm ID + * @param in [IN] Data to be digested + * @param len [IN] Data length + * @param out [OUT] Digest result + * @param len [IN/OUT] The input parameter indicates the length of the buffer marked as "out", and the output + * parameter indicates the valid length of the obtained "out". + * @retval #CRYPT_SUCCESS. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_Md(CRYPT_MD_AlgId id, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); + +/** + * @ingroup crypt_eal_md + * @brief Deinitialize the function. + * + * If need to be calculated after the CRYPT_EAL_MdDeinit is called, it needs to be initialized again. + * + * @param ctx [IN] Md Context + */ +uint32_t CRYPT_EAL_MdDeinit(CRYPT_EAL_MdCTX *ctx); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_EAL_MD_H diff --git a/include/crypto/crypt_eal_pkey.h b/include/crypto/crypt_eal_pkey.h new file mode 100644 index 00000000..13296f67 --- /dev/null +++ b/include/crypto/crypt_eal_pkey.h @@ -0,0 +1,532 @@ +/* + * 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 crypt_eal_pkey + * @ingroup crypt + * @brief the asym key module + */ + +#ifndef CRYPT_EAL_PKEY_H +#define CRYPT_EAL_PKEY_H + +#include +#include +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_method.h" +#include "crypt_eal_pkey.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @ingroup crypt_eal_pkey + * + * EAL public key structure + */ +typedef struct { + CRYPT_PKEY_AlgId id; /**< Public Key Algorithm ID */ + union { + CRYPT_RsaPub rsaPub; /**< RSA public key structure */ + CRYPT_DsaPub dsaPub; /**< DSA public key structure */ + CRYPT_DhPub dhPub; /**< DH public key structure */ + CRYPT_EccPub eccPub; /**< ECC public key structure */ + CRYPT_Curve25519Pub curve25519Pub; /**< ed25519/x25519 public key structure */ + CRYPT_PaillierPub paillierPub; /**< Paillier public key structure */ + } key; /**< Public key union of all algorithms */ +} CRYPT_EAL_PkeyPub; + +/** + * @ingroup crypt_eal_pkey + * + * EAL private key structure + */ +typedef struct { + CRYPT_PKEY_AlgId id; /**< private key algorithm ID */ + union { + CRYPT_RsaPrv rsaPrv; /**< RSA private key structure */ + CRYPT_DsaPrv dsaPrv; /**< DSA private key structure */ + CRYPT_DhPrv dhPrv; /**< DH private key structure */ + CRYPT_EccPrv eccPrv; /**< ECC private key structure */ + CRYPT_Curve25519Prv curve25519Prv; /**< ed25519/x25519 private key structure */ + CRYPT_PaillierPrv paillierPrv; /**< Paillier private key structure */ + } key; /** +#include +#include "crypt_algid.h" +#include "crypt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup crypt_eal_rand + * @brief Random number initialization interface. This interface does not support multiple threads. + * + * Initialize global random number to RAND, Entropy sources and addtional random numbers in the seed material + * which implemented by HiTLS. and this value is provided by the user. if user not provid the entropy source + * (seedMeth and seedCtx are both NULL), the default software entropy source is used. + * In addition, this interface does not support multiple threads. + * The global random number is initialized to the random generation algorithm described in Nist 800-90a. + * Application scenarios are as follows: + * 1. seedMeth == NULL && seedCtx == NULL ====> Use the default system entropy source in AES_CTR mode + * (that is, non-DF cannot use the default entropy source). + * 2. seedMeth == NULL && seedCtx != NULL ===> Error report. + * 3. seedMeth != NULL ====> This function can be used normally, seedCtx is not restricted, but make sure + * seedMeth can handle all kinds of situations. + * + * @attention: Support obtain or generate random numbers with multithreading, but not support initialization + * and deinitialization with multithreading. + * @param id [IN] RAND id + * @param seedMeth [IN] Seed method, which can be set NULL with seedCtx, The default entropy source is used + * or provided by the user. + * @param seedCtx [IN] Seed context information, which can be set NULL, But the seedMeth provided by the user can + * handle the situation where seedCtx is NULL. + * Generally, seedCtx needs to contain data such as entropy and nonce. + * @param pers [IN] Personal data, which can be NULL. + * @param persLen [IN] Length of the personal data, the length ranges from [0,0x7FFFFFF0]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see the crypt_errno.h file. + */ +int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, + const uint8_t *pers, uint32_t persLen); + +/** + * @ingroup crypt_eal_rand + * @brief Deinitializing the global RAND interface, this interface does not support multiple threads. + * + * @retval void, no return value. + */ +void CRYPT_EAL_RandDeinit(void); + +/** + * @ingroup crypt_eal_rand + * @brief Generate a random number. + * + * The addtional data marked as "addin" can be NULL, and additional data specified by the user. + * This interface does not support multiple threads. + * + * @param byte [OUT] Output random numbers, the memory is provided by the user. + * @param len [IN] Required random number length, the maximum length is (0, 65536]. + * @param addin [IN] Addtional data, which can set be NULL. + * @param addinLen [IN] Addtional data length, the maximum length is[0,0x7FFFFFF0]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see the crypt_errno.h file. + */ +int32_t CRYPT_EAL_RandbytesWithAdin(uint8_t *byte, uint32_t len, uint8_t *addin, uint32_t addinLen); + +/** + * @ingroup crypt_eal_rand + * + * Generate a random number, which is equivalent to CRYPT_EAL_RandbytesWithAdin(bytes, len, NULL, 0). + * This interface supports multi-thread access. + * + * @param byte [OUT] Used to store output random numbers, the memory is provided by the user. + * @param len [IN] Required random number length, the length range is(0, 65536]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see the crypt_errno.h file. + */ +int32_t CRYPT_EAL_Randbytes(uint8_t *byte, uint32_t len); + +/** + * @ingroup crypt_eal_rand + * @brief Regenerate the seed. + * + * @attention The addtional data can set be NULL, and this interface supports multi-thread access. + * @param addin [IN] Additional data, which can set be NULL. + * @param addinLen [IN] Addtional data length, the range is [0,0x7FFFFFF0]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_RandSeedWithAdin(uint8_t *addin, uint32_t addinLen); + +/** + * @ingroup crypt_eal_rand + * + * Regenerate the seed, which is equivalent to CRYPT_EAL_RandSeedWithAdin(NULL, 0), and the interface + * supports multi-thread access. + * + * @retval #CRYPT_SUCCESS + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_RandSeed(void); + +typedef struct EAL_RndCtx CRYPT_EAL_RndCtx; + +/** + * @ingroup CRYPT_EAL_DrbgInit + * @brief Random number initialization interface, and this interface does not support multiple threads. + * + * Initial DRBG with HiTLS, entropy source and addtional random number in the seed material + * are provided by users. This interface does not support multi-threading, the initial random number is + * the random number generation algorithm described in Nist 800-90a. + * Usage scenes are as follows: + * 1. seedMeth == NULL && seedCtx == NULL ====> Use the default system entropy source in AES_CTR mode + * (that is, non-DF cannot use the default entropy source). + * 2. seedMeth == NULL && seedCtx != NULL ===> error reported. + * 3. seedMeth != NULL ====> This function can be used normally, seedCtx function is not restricted, + * but make sure seedMeth can handle all kinds of situations. + * + * @attention Initialization and deinitialization + * @param id [IN] RAND id + * @param seedMeth [IN] Seed method, this parameter and seedCtx can be null at the same time. The default entropy + * source is used or provided by the user. + * @param seedCtx [IN] Seed context information, which can be NULL, but the seedMeth provided by the user needs + * to be able to handle the situation where seedCtx is null. + * seedCtx generally needs to contain the entropy source marked as "entropy", additional random number "nonce", and + * other data. + * @param pers [IN] Personal data, which can be NULL. + * @param persLen [IN] Personal data length. the range is [0,0x7FFFFFF0]. + * @retval DRBG handle, if successful. + * NULL, if failed. + */ +CRYPT_EAL_RndCtx *CRYPT_EAL_DrbgInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, + const uint8_t *pers, uint32_t persLen); + +/** + * @ingroup CRYPT_EAL_DrbgDeinit + * @brief CRYPT_EAL_DrbgDeinit Deinitialization interface, this interface does not support multiple threads. + * + * @param ctx [IN] DRBG handle + * @retval Void, no value is returned. +*/ +void CRYPT_EAL_DrbgDeinit(CRYPT_EAL_RndCtx *ctx); + +/** + * @ingroup crypt_eal_rand + * @brief Generate a random number. + * + * @attention The addtional data can be NULL, user specifies the addtional data, + * and the interface supports multi-thread access. + * @param ctx [IN] DRBG handle + * @param byte [OUT] Outputs random numbers. the memory is provided by the user. + * @param len [IN] Required random number length. the range is (0, 65536]. + * @param addin [IN] Addtional data, which can be NULL. + * @param addinLen [IN] Addtional data length. the range is [0,0x7FFFFFF0]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see the crypt_errno.h file. + */ +int32_t CRYPT_EAL_DrbgbytesWithAdin(CRYPT_EAL_RndCtx *ctx, uint8_t *byte, uint32_t len, uint8_t *addin, uint32_t addinLen); + +/** + * @ingroup crypt_eal_rand + * + * Generate a random number, which is equivalent to CRYPT_EAL_RandbytesWithAdin(bytes, len, NULL, 0). + * This interface supports multi-thread access. + * + * @param ctx [IN] DRBG handle + * @param byte [OUT] Used to store output random numbers. the memory is provided by the user. + * @param len [IN] Required random number length. the range is (0, 65536]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see the crypt_errno.h file. + */ +int32_t CRYPT_EAL_Drbgbytes(CRYPT_EAL_RndCtx *ctx, uint8_t *byte, uint32_t len); + +/** + * @ingroup crypt_eal_rand + * @brief Regenerate the seed. The addtional data can be NULL. This interface supports multi-thread access. + * + * @param ctx [IN] DRBG handle + * @param addin [IN] Addtional data, which can be null. + * @param addinLen [IN] Addtional data length. The maximum length is [0,0x7FFFFFF0]. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_DrbgSeedWithAdin(CRYPT_EAL_RndCtx *ctx, uint8_t *addin, uint32_t addinLen); + +/** + * @ingroup crypt_eal_rand + * @brief Regenerate the seed, which is equivalent to CRYPT_EAL_RandSeedWithAdin(NULL, 0). + * + * @attention This interface supports multi-thread access. + * @param ctx [IN] DRBG handle. + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see crypt_errno.h. + */ +int32_t CRYPT_EAL_DrbgSeed(CRYPT_EAL_RndCtx *ctx); + +/** + * @ingroup crypt_eal_rand + * @brief Check whether the id is valid Rand algorithm ID. + * + * @param id [IN] Rand algorithm ID. + * + * @retval true, if valid. + * false, if invalid. + */ +bool CRYPT_EAL_RandIsValidAlgId(CRYPT_RAND_AlgId id); + +#ifdef __cplusplus +} +#endif + +#endif // CRYPT_EAL_RAND_H diff --git a/include/crypto/crypt_errno.h b/include/crypto/crypt_errno.h new file mode 100644 index 00000000..da2c15b5 --- /dev/null +++ b/include/crypto/crypt_errno.h @@ -0,0 +1,387 @@ +/* + * 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 crypt_errno + * @ingroup crypt + * @brief error number module of crypto module + */ + +#ifndef CRYPT_ERRNO_H +#define CRYPT_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup crypt_errno + * @brief Return success + */ +#define CRYPT_SUCCESS 0 + +/** + * @ingroup crypt_errno + * + * CRYPTO module return value. + */ +enum CRYPT_ERROR { + CRYPT_NULL_INPUT = 0x01010001, /**< Null pointer input error, bufferLen is 0. */ + CRYPT_SECUREC_FAIL, /**< Security function returns an error. */ + CRYPT_MEM_ALLOC_FAIL, /**< Failed to apply for memory. */ + CRYPT_NO_REGIST_RAND, /**< The global random number is not registered.*/ + CRYPT_ERR_ALGID, /**< Incorrect algorithm ID. */ + CRYPT_INVALID_ARG, /**< Invalid input parameter. */ + CRYPT_NOT_SUPPORT, + + CRYPT_BN_BUFF_LEN_NOT_ENOUGH = 0x01020001, /**< Insufficient buffer length. */ + CRYPT_BN_SPACE_NOT_ENOUGH, /**< Insufficient big number space. */ + CRYPT_BN_BITS_TOO_MAX, /**< The maximum bit limit is exceeded of the big number. */ + CRYPT_BN_RAND_GEN_FAIL, /**< Failed to generate the random number. */ + CRYPT_BN_OPTIMIZER_STACK_FULL, /**< Optimizer stack is full. */ + CRYPT_BN_NO_NEGATIVE_ZERO, /**< The big number is set to a positive number only. */ + CRYPT_BN_ERR_RAND_ZERO, /**< Generates a random number smaller than 0. */ + CRYPT_BN_ERR_RAND_NEGATIVE, /**< Generate a negative random number. */ + CRYPT_BN_ERR_RAND_TOP_BOTTOM, /**< The top or bottom is invalid during random number generation. */ + CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH, /**< The bit is too small during random number generation. */ + CRYPT_BN_OPTIMIZER_GET_FAIL, /**< Failed to obtain the space from the optimizer. */ + CRYPT_BN_ERR_DIVISOR_ZERO, /**< The divisor cannot be 0. */ + CRYPT_BN_ERR_EXP_NO_NEGATIVE, /**< The value of exponent cannot be negative. */ + CRYPT_BN_MONT_BASE_TOO_MAX, /**< Montgomery module exponentiation base is too large. */ + CRYPT_BN_NOR_GEN_PRIME, /**< Prime Number Generation Failure. */ + CRYPT_BN_NOR_CHECK_PRIME, /**< prime number check failed. */ + CRYPT_BN_ERR_GCD_NO_ZERO, /**< The maximum common divisor cannot contain 0. */ + CRYPT_BN_ERR_NO_INVERSE, /**< Cannot obtain the inverse module. */ + CRYPT_BN_ERR_SQRT_PARA, /**< The parameter is incorrect when modulus square root. */ + CRYPT_BN_ERR_LEGENDE_DATA, /**< Failed to find a specific number for z to p's Legendre sign (z|p) + equal to -1 when calculating the square root. */ + CRYPT_BN_ERR_NO_SQUARE_ROOT, /**< The square root cannot be found. */ + CRYPT_BN_ERR_MASKCOPY_LEN, /**< Data lengths are inconsistent when data is copied with masks. */ + CRYPT_BN_ERR_QUICK_MODDATA, /**< Uses the BN_ModNistEccMul and BN_ModNistEccSqr interfaces, + the module data is not supported. */ + CRYPT_BN_BITS_INVALID, /**< The bits of the big number exceeds the limit. */ + + CRYPT_RSA_BUFF_LEN_NOT_ENOUGH = 0x01030001, /**< The buffer length is insufficient. */ + CRYPT_RSA_NO_KEY_INFO, /**< Lacks valid key information. */ + CRYPT_RSA_ERR_KEY_BITS, /**< Incorrect key length. */ + CRYPT_RSA_ERR_E_VALUE, /**< The value of parameter e is incorrect. */ + CRYPT_RSA_NOR_KEYGEN_FAIL, /**< Key generation failure, it's normal error. */ + CRYPT_RSA_NOR_VERIFY_FAIL, /**< Failed to verify the signature. it's normal error. */ + CRYPT_RSA_ERR_ENC_BITS, /**< Incorrect length of the encrypted plaintext of the public key. */ + CRYPT_RSA_ERR_DEC_BITS, /**< Incorrect length of the decrypted ciphertext of the private key. */ + CRYPT_RSA_ERR_PSS_SALT_LEN, /**< Incorrect salt length of the PSS operation. */ + CRYPT_RSA_ERR_PSS_SALT_DATA, /**< PSS operation salt data error, failed to compare the salt extracted + during signature verification with the user's input. */ + CRYPT_RSA_ERR_INPUT_VALUE, /**< Some special values, which are used as input errors. */ + CRYPT_RSA_ERR_MD_ALGID, /**< The hash ID of the input parameter is incorrect when + the pkcs1.5 padding mode is set. */ + CRYPT_RSA_PAD_NO_SET_ERROR, /**< Padding information is not set when using RSA key for + signature verification. */ + CRYPT_RSA_CTRL_NOT_SUPPORT_ERROR, /**< The Ctrl type is not supported When RSA is used for Ctrl. */ + CRYPT_RSA_SET_SALT_NOT_PSS_ERROR, /**< When the padding type of the key is not pss, and set the salt + information, return failure. */ + CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR,/**< Sets the PKCSV15 padding information, the length of the input data + is incorrect and return failure. */ + CRYPT_RSA_SET_EMS_PSS_LEN_ERROR, /**< Sets the PSS padding information, the length of the input data is + incorrect, and return failure. */ + CRYPT_RSA_SET_RSAES_OAEP_LEN_ERROR, /**< Sets the OAEP padding information, the length of the input data + is incorrect and return failure. */ + CRYPT_RSA_SET_FLAG_LEN_ERROR, /**< The length of the input data is incorrect and return failure When + sets the flag. */ + CRYPT_RSA_FLAG_NOT_SUPPORT_ERROR, /**< Unsupported flag. */ + CRYPT_RSA_ERR_SALT_LEN, /**< Salt length error. */ + CRYPT_RSA_ERR_ALGID, /**< The hash ID of the input parameter is incorrect or conflict occurs when + sets the signature, signature verification, and padding parameters. */ + CRYPT_RSA_ERR_GEN_SALT, /**< An error is returned when salt information fails to be generated + during PSS signature. */ + CRYPT_RSA_ERR_ENC_INPUT_NOT_ENOUGH, /**< The plaintext length is too short for RSA NO PAD encryption. */ + CRYPT_RSA_PUBKEY_NOT_EQUAL, /**< RSA public keys are not equal. */ + + CRYPT_EAL_BUFF_LEN_NOT_ENOUGH = 0x01040001, /**< Insufficient buffer length. */ + CRYPT_EAL_ERR_ALGID, /**< Incorrect algorithm ID. */ + CRYPT_EAL_ALG_NOT_SUPPORT, /**< Algorithm not supported, algorithm behavior not supported. */ + CRYPT_EAL_ERR_NEW_PARA_FAIL, /**< Failed to generate parameters. */ + CRYPT_EAL_ERR_RAND_WORKING, /**< DRBG is in the working state. */ + CRYPT_EAL_ERR_RAND_NO_WORKING, /**< DRBG is not working. */ + CRYPT_EAL_ERR_METH_NULL_NUMBER, /**< The method variable member is NULL. */ + CRYPT_EAL_ERR_GLOBAL_DRBG_NULL, /**< The global DRBG is null. */ + CRYPT_EAL_ERR_DRBG_REPEAT_INIT, /**< DRBG is initialized repeatedly. */ + CRYPT_EAL_ERR_DRBG_INIT_FAIL, /**< DRBG initialization failure. */ + CRYPT_EAL_ERR_STATE, /**< The usage process is incorrect. For example, run the update + command without running the init command. + For details, see related algorithms. */ + CRYPT_EAL_CIPHER_DATA_ERROR, /**< Data error occurs when unpadding the decrypted data. + For X923, the last bit is the length of the original data, and the + rest data is 0, if this requirement is not met, an error is reported. + For pkcs, all padding data is + (the length of the padding data - the length of the original data), + if this requirement is not met,an error will be reported. + For ISO7816, the first bit of padding data is 0x80, and the other bits + are 0, if this requirement is not met, an error will be reported. */ + CRYPT_EAL_PADDING_NOT_SUPPORT, /**< Unsupported padding. */ + CRYPT_EAL_CIPHER_CTRL_ERROR, /**< CRYPT_EAL_CipherCtrl interface unsupported CTRL type. */ + CRYPT_EAL_CIPHER_FIANL_WITH_AEAD_ERROR, /**< An error occurs when the final operation is performed on the + AEAD algorithm. */ + CRYPT_EAL_PKEY_CTRL_ERROR, /**< When the CRYPT_EAL_PkeyCtrl interface performs CTRL, + the function is not supported or the input length is incorrect. */ + CRYPT_EAL_PKEY_DUP_ERROR, /**< Pkey context duplicate failure. */ + CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE, /**< Pkey comparison failure: different algorithm types. */ + CRYPT_EAL_ERR_PART_OVERLAP, /**< Some memory overlap. */ + CRYPT_EAL_INTO_TYPE_NOT_SUPPORT, /**< The info type is not supported. */ + CRYPT_EAL_ALG_ASM_NOT_SUPPORT, /**< Algorithm assembly is not supported. */ + + CRYPT_SHA2_INPUT_OVERFLOW = 0x01050001, /**< The length of the input data exceeds the maximum + processing range of SHA2. */ + CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH, /**< The length of the buffer that storing the output + result is insufficient. */ + + CRYPT_DRBG_ERR_STATE = 0x01060001, /**< DRBG status error. */ + CRYPT_DRBG_FAIL_GET_ENTROPY, /**< Failed to obtain the entropy. */ + CRYPT_DRBG_FAIL_GET_NONCE, /**< Failed to obtain the nonce. */ + CRYPT_DRBG_ALG_NOT_SUPPORT, /**< Does not support the given algorithm. */ + CRYPT_DRBG_INVALID_LEN, /**< Incorrect data length. */ + + CRYPT_CURVE25519_NO_PUBKEY = 0x01070001, /**< No public key. */ + CRYPT_CURVE25519_NO_PRVKEY, /**< No private key. */ + CRYPT_CURVE25519_KEYLEN_ERROR, /**< Incorrect key length. */ + CRYPT_CURVE25519_SIGNLEN_ERROR, /**< Incorrect signature length. */ + CRYPT_CURVE25519_HASH_METH_ERROR, /**< Hash method is not SHA512. */ + CRYPT_CURVE25519_VERIFY_FAIL, /**< Signature verification fails due to incorrect signature. */ + CRYPT_CURVE25519_NO_HASH_METHOD, /**< Hash method not set. */ + CRYPT_CURVE25519_UNSUPPORTED_CTRL_OPTION, /**< Unsupported mode of operation. */ + CRYPT_CURVE25519_KEY_COMPUTE_FAILED, /**< Failed to generate the shared key. */ + CRYPT_CURVE25519_INVALID_PUBKEY, /**< Invalid public key. */ + CRYPT_CURVE25519_PUBKEY_NOT_EQUAL, /**< Public keys are not equal. */ + + CRYPT_SHA1_INPUT_OVERFLOW = 0x01080001, /**< The length of the input data exceeds the + maximum processing range of SHA1. */ + CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH, /**< The length of the buffer that storing + the output result is insufficient. */ + + CRYPT_ENTROPY_CONDITION_FAILURE = 0x01090001, /**< Processing method error after invoking. */ + CRYPT_ENTROPY_RANGE_ERROR, /**< Entropy source generation range error */ + CRYPT_ENTROPY_ECF_ALG_ERROR, /**< Entropy source conditioning algorithm is incorrect. */ + + CRYPT_DSA_BUFF_LEN_NOT_ENOUGH = 0x010A0001, /**< Insufficient buffer length. */ + CRYPT_DSA_ERR_KEY_PARA, /**< Incorrect key parameter data. */ + CRYPT_DSA_ERR_KEY_INFO, /**< Incorrect key information. */ + CRYPT_DSA_VERIFY_FAIL, /**< Verification failure. */ + CRYPT_DSA_ERR_TRY_CNT, /**< Key generation and signature fail to be + generated within the specified number of attempts. */ + CRYPT_DSA_DECODE_FAIL, /**< Data decoding fails, the data does not meet + the decoding requirements. */ + CRYPT_DSA_PARA_ERROR, /**< The value of the key parameter does not meet + the requirements. The ctx command does not + contain necessary parameter information. */ + CRYPT_DSA_PUBKEY_NOT_EQUAL, /**< Public keys are not equal. */ + CRYPT_DSA_PARA_NOT_EQUAL, /**< Key parameters are not equal. */ + CRYPT_DSA_UNSUPPORTED_CTRL_OPTION, /**< Unsupported mode of operation. */ + + CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH = 0x010B0001, /**< The length of the buffer that storing + the output result is insufficient. */ + + CRYPT_DH_BUFF_LEN_NOT_ENOUGH = 0x010C0001, /**< The buffer length is insufficient. */ + CRYPT_DH_PARA_ERROR, /**< The value of the key parameter does not meet + the requirements, the ctx command does not + contain necessary parameter information. */ + CRYPT_DH_KEYINFO_ERROR, /**< The value of the public and private keys do + not meet the requirements, the ctx does not + contain the necessary public and private keys. */ + CRYPT_DH_RAND_GENERATE_ERROR, /**< Key generation fails within the specified + number of attempts. */ + CRYPT_DH_PAIRWISE_CHECK_FAIL, /**< The public and private keys are inconsistent. */ + CRYPT_DH_CREATE_PARA_FAIL, /**< Failed to create the p, q, and g parameters + of the DH algorithm. */ + CRYPT_DH_PUBKEY_NOT_EQUAL, /**< Public keys are not equal. */ + CRYPT_DH_PARA_NOT_EQUAL, /**< DH key parameters are not equal. */ + CRYPT_DH_UNSUPPORTED_CTRL_OPTION, /**< Unsupported mode of operation. */ + + CRYPT_CHACHA20_KEYLEN_ERROR = 0x010D0001, /**< The key length input is incorrect during key setting. */ + CRYPT_CHACHA20_NONCELEN_ERROR, /**< The length of the input nounce is incorrect when you + set the nounce. */ + CRYPT_CHACHA20_COUNTLEN_ERROR, /**< The length of the input count is incorrect when you + set the count. */ + CRYPT_CHACHA20_NO_KEYINFO, /**< Lack of valid key information during + encryption and decryption. */ + CRYPT_CHACHA20_NO_NONCEINFO, /**< Lack of valid nounce information during + encryption and decryption. */ + CRYPT_CHACHA20_CTRLTYPE_ERROR, /**< The input type is not supported when the + ctrl interface is used. */ + + CRYPT_AES_ERR_KEYLEN = 0x010E0001, /**< Incorrect key length. */ + + CRYPT_MODES_TAGLEN_ERROR = 0x010F0001, /**< In AEAD mode, the length of the TAG + is incorrect when the tag is obtained and verified. */ + CRYPT_MODES_IVLEN_ERROR, /**< The length of the input IV is incorrect + when setting the IV. */ + CRYPT_MODES_KEYUSE_TOOMANY_TIME, /**< In GCM mode, the number of times that a key + can be used for encryption and decryption is limited. + When the number of times that a key is used exceeds + the limit, an error is reported. */ + CRYPT_MODES_CRYPTLEN_OVERFLOW, /**< In AEAD mode, the length of the plaintext + or ciphertext input for a single + encryption exceeds the limit. */ + CRYPT_MODES_CTRL_TAGLEN_ERROR, /**< In GCM or CCM mode, the length of the input + parameter or the length of the input + parameter data is incorrect when the ctrl + interface is used to set the tag length. */ + CRYPT_MODES_AAD_REPEAT_SET_ERROR, /**< In the AEAD mode, the AAD information + is set repeatedly. */ + CRYPT_MODE_BUFF_LEN_NOT_ENOUGH, /**< The buffer length is insufficient. */ + CRYPT_MODE_ERR_INPUT_LEN, /**< The function input length is not the + expected length. */ + CRYPT_MODES_CTRL_TYPE_ERROR, /**< The input type is not supported when the ctrl + interface is used. */ + CRYPT_MODES_AAD_IS_SET_ERROR, /**< In ccm mode, an error is returned when the tagLen and + msgLen are set after the aad is set. */ + CRYPT_MODES_MSGLEN_OVERFLOW, /**< In ccm mode, the length of the input message during + encryption and decryption exceeds the set msgLen. */ + CRYPT_MODES_CTRL_MSGLEN_ERROR, /**< In ccm mode, When the ctrl interface is used to set the + msg length, the input parameter length or the input + parameter data length is incorrect. (This + specification is affected by ivLen.) */ + CRYPT_MODES_MSGLEN_LEFT_ERROR, /**< In ccm mode, when the ctrl interface is used to + obtain the tag, the length of the encrypted and + decrypted messages does not reach the configured + number. As a result, an error occurs. */ + CRYPT_MODES_ERR_KEYLEN, /**< Incorrect key length set. */ + CRYPT_MODES_ERR_KEY, /**< Incorrect key set. */ + CRYPT_MODES_ERR_FEEDBACKSIZE, /**< The operation are not support by the algorithm + on which the pattern depends on. */ + CRYPT_MODES_METHODS_NOT_SUPPORT, /**< Mode depends does not support the behavior. */ + CRYPT_MODES_FEEDBACKSIZE_NOT_SUPPORT, /**< The algorithm does not support the setting of feedbacksize. */ + + CRYPT_HKDF_DKLEN_OVERFLOW = 0x01100001, /**< The length of the derived key exceeds the maximum. */ + CRYPT_HKDF_NOT_SUPPORTED, /**< Unsupport HKDF algorithm. */ + CRYPT_HKDF_PARAM_ERROR, /**< Incorrect input parameter. */ + + CRYPT_SCRYPT_PARAM_ERROR = 0x01110001, /**< Incorrect input parameter. */ + CRYPT_SCRYPT_NOT_SUPPORTED, /**< Unsupport the SCRYPT algorithm. */ + CRYPT_SCRYPT_DATA_TOO_MAX, /**< The data calculated by the SCRYPT algorithm is too large. */ + + CRYPT_PBKDF2_PARAM_ERROR = 0x01120001, /**< Incorrect input parameter. */ + CRYPT_PBKDF2_NOT_SUPPORTED, /**< Does not support the PBKDF2 algorithm. */ + + CRYPT_ECC_POINT_AT_INFINITY = 0x01130001, /**< Point at infinity. */ + CRYPT_ECC_POINT_NOT_ON_CURVE, /**< Point is not on the curve. */ + CRYPT_ECC_POINT_ERR_CURVE_ID, /**< Curve ID is inconsistent or incorrect. */ + CRYPT_ECC_POINT_WINDOW_TOO_MAX, /**< Window is too max. */ + CRYPT_ECC_POINT_NOT_EQUAL, /**< The two points are not equal. */ + CRYPT_ECC_POINT_BLIND_WITH_ZERO, /**< The random number generated during point salting is 0. */ + CRYPT_ECC_POINT_NOT_AFFINE, /**< Point is not affine coordinates. */ + CRYPT_ECC_NOT_SUPPORT, /**< This function is not supported. */ + CRYPT_ECC_BUFF_LEN_NOT_ENOUGH, /**< Insufficient buffer length. */ + CRYPT_ECC_ERR_POINT_FORMAT, /**< The encoding format input during point encoding + is incorrect. */ + CRYPT_ECC_ERR_POINT_CODE, /**< Incorrect point code information. */ + CRYPT_ECC_ERR_PARA, /**< Incorrect curve parameter. */ + CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION, /**< Unsupport the control type. */ + CRYPT_ECC_PKEY_ERR_EMPTY_KEY, /**< Key is null. */ + CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT, /**< Invalid dot format. */ + CRYPT_ECC_PKEY_ERR_CTRL_LEN, /**< Control input parameter is incorrect. */ + CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY, /**< Invalid private key. */ + CRYPT_ECC_PKEY_ERR_INVALID_PUBLIC_KEY, /**< Invalid public key. */ + CRYPT_ECC_PKEY_ERR_TRY_CNT, /**< Key generation or generater signature fail + within the specified number of attempts. */ + CRYPT_ECC_PKEY_ERR_SIGN_LEN, /**< Invalid sign length */ + + CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL, /**< ECC public keys are not equal. */ + + CRYPT_SHA3_OUT_BUFF_LEN_NOT_ENOUGH = 0x01140001, /**< Insufficient buffer length for storing output results. */ + + CRYPT_ECDH_ERR_EMPTY_KEY = 0x01150001, /**< Key is null. */ + CRYPT_ECDH_ERR_INVALID_COFACTOR, /**< Invalid cofactor value. */ + + CRYPT_ECDSA_ERR_EMPTY_KEY = 0x01160001, /**< Key is NULL. */ + CRYPT_ECDSA_ERR_TRY_CNT, /**< Key generation and generate signature fail + within the specified number of attempts. */ + CRYPT_ECDSA_VERIFY_FAIL, /**< Verification failure. */ + CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION, /**< Unsupport the control type. */ + CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH, /**< BUFF insufficient length. */ + + CRYPT_SM3_INPUT_OVERFLOW = 0x01170001, /**< The length of the input data exceeds the maximum + processing range of the SM3. */ + CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH, /**< The length of the buffer that storing the output + result is insufficient. */ + + CRYPT_SM4_KEYLEN_ERROR = 0x01180001, /**< Wrong key length set. */ + CRYPT_SM4_DATALEN_ERROR, /**< Wrong data length is set. */ + CRYPT_SM4_ERR_KEY_LEN, /**< Wrong key length is set. */ + CRYPT_SM4_UNSAFE_KEY, /**< DataKey is the same as tweakKey. */ + + CRYPT_MD5_INPUT_OVERFLOW = 0x01190001, /**< The length of the input data exceeds the + maximum processing range of the MD5. */ + CRYPT_MD5_OUT_BUFF_LEN_NOT_ENOUGH, /**< The length of the buffer that storing the + output result is insufficient. */ + + CRYPT_SM2_BUFF_LEN_NOT_ENOUGH = 0x011B0001, /**< Insufficient buffer length. */ + CRYPT_SM2_NO_PUBKEY, /**< SM2 the public key is not set. */ + CRYPT_SM2_NO_PRVKEY, /**< SM2 The private key is not set. */ + CRYPT_SM2_ERR_EMPTY_KEY, /**< SM2 key is null. */ + CRYPT_SM2_ERR_TRY_CNT, /**< Key generation and generate signature fail + within the specified number of attempts. */ + CRYPT_SM2_VERIFY_FAIL, /**< verification failure. */ + CRYPT_SM2_ERR_UNSUPPORTED_CTRL_OPTION, /**< Unsupported control type. */ + CRYPT_SM2_ERR_NO_HASH_METHOD, /**< No hash method information. */ + CRYPT_SM2_USERID_NOT_SET, /**< Unset userID. */ + CRYPT_SM2_R_NOT_SET, /**< The peer R value is not set. */ + CRYPT_SM2_INVALID_SERVER_TYPE, /**< The user is neither the initiator nor the recipient. */ + CRYPT_SM2_ERR_CTRL_LEN, /**< Incorrect ctrl length. */ + CRYPT_SM2_DECRYPT_FAIL, /**< Decryption failure. */ + CRYPT_SM2_ERR_DATA_LEN, /**< Incorrect data length. */ + CRYPT_SM2_ERR_GET_S, /**< Failed to obtain the checksum. */ + CRYPT_SM2_ERR_S_NOT_SET, /**< Unset checksum. */ + CRYPT_SM2_EXCH_VERIFY_FAIL, /**< Key Negotiation Failure. */ + CRYPT_SM2_DECODE_FAIL, /**< Data decoding fails, the data does not meet + the decoding requirements. */ + CRYPT_SM2_ID_TOO_LARGE, /**< User id to large. */ + CRYPT_KDFTLS12_NOT_SUPPORTED = 0x011C0001, /**< Unsupport the KDFTLS12 algorithm. */ + + CRYPT_DECODE_ASN1_BUFF_NUM_NOT_ENOUGH = 0x011D0001, /**< The input number of BSL_ANS1_Buffer is not enough. */ + CRYPT_DECODE_UNSUPPORTED_PUBKEY_TYPE, /**< Unsupported pubkey type */ + CRYPT_DECODE_UNSUPPORTED_PKCS8_TYPE, /**< Unsupported pkcs8 type */ + CRYPT_DECODE_PKCS8_INVALID_ALGO_PARAM, /**< pkcs8 has no valid algorithm parameters */ + CRYPT_DECODE_UNKNOWN_OID, /**< Unknown OID */ + CRYPT_DECODE_ASN1_BUFF_FAILED, /**< decode asn1 buffer failed. */ + CRYPT_DECODE_NO_SUPPORT_TYPE, /**< decode no support key type. */ + CRYPT_DECODE_NO_SUPPORT_FORMAT, /**< decode no support key format. */ + CRYPT_DECODE_PKCS8_INVALID_ITER, /**< pkcs8 invalid iter num */ + CRYPT_DECODE_PKCS8_INVALID_KEYLEN, /**< pkcs8 invalid keylen */ + CRYPT_DECODE_ERR_RSSPSS_GET_ANY_TAG, /**< decode rsapss param failed. */ + CRYPT_DECODE_ERR_RSSPSS, /**< decode rsapss param failed. */ + CRYPT_DECODE_ERR_RSSPSS_MD, /**< rsapss md is invalid. */ + CRYPT_DECODE_ERR_RSSPSS_MGF1MD, /**< rsapss mgf1md is invalid. */ + CRYPT_DECODE_ERR_RSSPSS_TRAILER, /**< rsapss trailer field is invalid. */ + CRYPT_DECODE_PKCS7_INVALIDE_ENCRYPTDATA_TYPE, /**< Invaild pkcs7-encryptedData. */ + CRYPT_DECODE_UNSUPPORTED_PKCS7_TYPE, /**< Unsupported pkcs7 type */ + CRYPT_DECODE_UNSUPPORTED_ENCRYPT_TYPE, /**< Unsupported encrypt type */ + + CRYPT_ENCODE_NO_SUPPORT_TYPE = 0x011E0001, /**< encode no support key type. */ + CRYPT_ENCODE_NO_SUPPORT_FORMAT, /**< encode no support key format. */ + CRYPT_ENCODE_ERR_RSA_PAD, /**< rsa pad err. */ + + CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH = 0x011F0001, /**< The buffer length is insufficient. */ + CRYPT_PAILLIER_NO_KEY_INFO, /**< Lacks valid key information. */ + CRYPT_PAILLIER_ERR_KEY_BITS, /**< Incorrect key length. */ + CRYPT_PAILLIER_ERR_ENC_BITS, /**< Incorrect length of the encrypted plaintext of the public key. */ + CRYPT_PAILLIER_ERR_DEC_BITS, /**< Incorrect length of the decrypted ciphertext of the private key. */ + CRYPT_PAILLIER_ERR_INPUT_VALUE, /**< Some special values, which are used as input errors. */ +}; + +#ifdef __cplusplus +} +#endif + +#endif // CRYPT_ERRNO_H diff --git a/include/crypto/crypt_method.h b/include/crypto/crypt_method.h new file mode 100644 index 00000000..bd2e1514 --- /dev/null +++ b/include/crypto/crypt_method.h @@ -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. + */ + +/** + * @defgroup crypt_method + * @ingroup crypt + * @brief methods of crypto + */ + +#ifndef CRYPT_METHOD_H +#define CRYPT_METHOD_H + +#include +#include +#include "crypt_types.h" +#include "crypt_algid.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define CRYPT_EAL_INIT_CPU 0x01 +#define CRYPT_EAL_INIT_BSL 0x02 +#define CRYPT_EAL_INIT_RAND 0x04 + +/** + * @ingroup crypt_method + * @brief CRYPTO initialization + * + * @param opts [IN] Bit information to be initialized, the first three bits are used at present. + * The first bit is CRYPT_EAL_INIT_CPU marked as "CPU ", the second bit is BSL + * CRYPT_EAL_INIT_BSL marked as "BSL", and the third bit is CRYPT_EAL_INIT_RAND + * marked as "RAND". + * @retval #CRYPT_SUCCESS, if successful. + * For other error codes, see the crypt_errno.h file. + */ +int32_t CRYPT_EAL_Init(uint64_t opts); + +/** + * @ingroup crypt_method + * @brief release the CRYPTO initialization memory. + * + * @param opts [IN] information about the bits to be deinitialized, which is the same as that of CRYPT_EAL_Init. + */ +void CRYPT_EAL_Cleanup(uint64_t opts); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_METHOD_H diff --git a/include/crypto/crypt_types.h b/include/crypto/crypt_types.h new file mode 100644 index 00000000..c0c25f24 --- /dev/null +++ b/include/crypto/crypt_types.h @@ -0,0 +1,562 @@ +/* + * 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 crypt_types + * @ingroup crypt + * @brief types of crypto + */ + +#ifndef CRYPT_TYPES_H +#define CRYPT_TYPES_H + +#include +#include +#include "crypt_algid.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @ingroup crypt_types + * + * Data structure + */ +typedef struct { + uint8_t *data; /**< Data content */ + uint32_t len; /**< Data length */ +} CRYPT_Data; + +/** + * @ingroup crypt_types + * + * Data range + */ +typedef struct { +uint32_t min; /**< Minimum value */ +uint32_t max; /**< Maximum value */ +} CRYPT_Range; + +/** + * @ingroup crypt_types + * + * Pkcsv15 padding mode, when RSA is used for signature. + */ +typedef struct { + CRYPT_MD_AlgId mdId; /**< ID of the hash algorithm during pkcsv15 padding */ +} CRYPT_RSA_PkcsV15Para; + +/** + * @ingroup crypt_types + * + * PSS padding mode, when RSA is used for signature. + */ +typedef struct { + int32_t saltLen; /**< pss salt length. the value -1 indicates hashLen, and the value -2 indicates MaxLen. */ + CRYPT_MD_AlgId mdId; /**< mdid when pss padding. */ + CRYPT_MD_AlgId mgfId; /**< mgfid when pss padding. */ +} CRYPT_RSA_PssPara; + +typedef struct { + CRYPT_MD_AlgId mdId; /**< mdid when oaep padding */ + CRYPT_MD_AlgId mgfId; /**< mgfid when oaep padding */ +} CRYPT_RSA_OaepPara; + +typedef enum { + CRYPT_RSA_BLINDING = 0x00000001, /**< Enable the RSA blinding function for signature. */ + CRYPT_RSA_MAXFLAG +} CRYPT_RSA_Flag; + +/** + * @ingroup crypt_types + * + * RSA private key parameter structure + */ +typedef struct { + uint8_t *d; /**< RSA private key parameter marked as d. */ + uint8_t *n; /**< RSA private key parameter marked as n. */ + uint8_t *p; /**< RSA private key parameter marked as p. */ + uint8_t *q; /**< RSA private key parameter marked as q. */ + uint8_t *dP; /**< RSA private key parameter marked as dP. */ + uint8_t *dQ; /**< RSA private key parameter marked as dQ. */ + uint8_t *qInv; /**< RSA private key parameter marked as qInv. */ + uint8_t *e; /**< RSA public key parameter marked as e. */ + uint32_t dLen; /**< Length of the RSA private key parameter marked as d. */ + uint32_t nLen; /**< Length of the RSA private key parameter marked as n. */ + uint32_t pLen; /**< Length of the RSA private key parameter marked as p. */ + uint32_t qLen; /**< Length of the RSA private key parameter marked as q. */ + uint32_t dPLen; /**< Length of the RSA private key parameter marked as dPLen. */ + uint32_t dQLen; /**< Length of the RSA private key parameter marked as dQLen. */ + uint32_t qInvLen; /**< Length of the RSA private key parameter marked as qInvLen. */ + uint32_t eLen; /**< Length of the RSA public key parameter marked as eLen. */ +} CRYPT_RsaPrv; + +/** + * @ingroup crypt_types + * + * Elliptic curve parameter information + */ +typedef struct { + uint8_t *p; + uint8_t *a; + uint8_t *b; + uint8_t *n; + uint8_t *h; + uint8_t *x; + uint8_t *y; + uint32_t pLen; + uint32_t aLen; + uint32_t bLen; + uint32_t nLen; + uint32_t hLen; + uint32_t xLen; + uint32_t yLen; +} CRYPT_EccPara; + +/** + * @ingroup crypt_types + * + * Paillier private key parameter structure + */ +typedef struct { + uint8_t *n; /**< Paillier private key parameter marked as n */ + uint8_t *lambda; /**< Paillier private key parameter marked as lambda */ + uint8_t *mu; /**< Paillier private key parameter marked as mu */ + uint8_t *n2; /**< Paillier private key parameter marked as n2 */ + uint32_t nLen; /**< Length of the Paillier private key parameter marked as n */ + uint32_t lambdaLen; /**< Length of the Paillier private key parameter marked as lambda */ + uint32_t muLen; /**< Length of the Paillier private key parameter marked as mu */ + uint32_t n2Len; /**< Length of the Paillier private key parameter marked as n2 */ +} CRYPT_PaillierPrv; + +/** + * @ingroup crypt_types + * + * DSA private key parameter structure + */ +typedef CRYPT_Data CRYPT_DsaPrv; + +/** + * @ingroup crypt_types + * + * ECC private key parameter structure. + */ +typedef CRYPT_Data CRYPT_EccPrv; + +/** + * @ingroup crypt_types + * + * ECDSA private key parameter structure. + */ +typedef CRYPT_Data CRYPT_EcdsaPrv; + +/** + * @ingroup crypt_types + * + * SM2 private key parameter structure + */ +typedef CRYPT_Data CRYPT_Sm2Prv; + +/** + * @ingroup crypt_types + * + * DH private key parameter structure + */ +typedef CRYPT_Data CRYPT_DhPrv; + +/** + * @ingroup crypt_types + * + * ECDH private key parameter structure + */ +typedef CRYPT_Data CRYPT_EcdhPrv; + +/** + * @ingroup crypt_types + * + * ed25519/x25519 private key parameter structure + */ +typedef CRYPT_Data CRYPT_Curve25519Prv; + +/** + * @ingroup crypt_types + * + * RSA public key parameter structure + */ +typedef struct { + uint8_t *e; /**< RSA public key parameter marked as e */ + uint8_t *n; /**< RSA public key parameter marked as n */ + uint32_t eLen; /**< Length of the RSA public key parameter marked as e*/ + uint32_t nLen; /**< Length of the RSA public key parameter marked as e*/ +} CRYPT_RsaPub; + +/** + * @ingroup crypt_types + * + * Paillier public key parameter structure + */ +typedef struct { + uint8_t *n; /**< Paillier public key parameter marked as n */ + uint8_t *g; /**< Paillier public key parameter marked as g */ + uint8_t *n2; /**< Paillier public key parameter marked as n2 */ + uint32_t nLen; /**< Length of the Paillier public key parameter marked as n */ + uint32_t gLen; /**< Length of the Paillier public key parameter marked as g */ + uint32_t n2Len; /**< Length of the Paillier public key parameter marked as n2 */ +} CRYPT_PaillierPub; + +/** + * @ingroup crypt_types + * + * DSA public key parameter structure + */ +typedef CRYPT_Data CRYPT_DsaPub; + +/** + * @ingroup crypt_types + * + * ECC public key parameter structure + */ +typedef CRYPT_Data CRYPT_EccPub; + +/** + * @ingroup crypt_types + * + * ECDSA public key parameter structure. + */ +typedef CRYPT_Data CRYPT_EcdsaPub; + +/** + * @ingroup crypt_types + * + * SM2 public key parameter structure + */ +typedef CRYPT_Data CRYPT_Sm2Pub; + +/** + * @ingroup crypt_types + * + * DH public key parameter structure + */ +typedef CRYPT_Data CRYPT_DhPub; + +/** + * @ingroup crypt_types + * + * ECDH public key parameter structure + */ +typedef CRYPT_Data CRYPT_EcdhPub; + +/** + * @ingroup crypt_types + * + * ed25519/x25519 public key parameter structure + */ +typedef CRYPT_Data CRYPT_Curve25519Pub; + +/** + * @ingroup crypt_types + * + * Para structure of the RSA algorithm + */ +typedef struct { /**< This parameter cannot be NULL and is determined by the underlying structure. */ + uint8_t *e; /**< Para Parameter e */ + uint32_t eLen; /**< Length of para e*/ + uint32_t bits; /**< Bits of para */ +} CRYPT_RsaPara; + +/** + * @ingroup crypt_types + * + * Para structure of the DSA algorithm. This parameter cannot be null, and it is determined by the underlying structure. + */ +typedef struct { + uint8_t *p; /**< Parameter p */ + uint8_t *q; /**< Parameter q */ + uint8_t *g; /**< Parameter g */ + uint32_t pLen; /**< Length of parameter p*/ + uint32_t qLen; /**< Length of parameter q*/ + uint32_t gLen; /**< Length of parameter g*/ +} CRYPT_DsaPara; + +/** + * @ingroup crypt_types + * + * Para structure of the DH algorithm + */ +typedef struct { + uint8_t *p; /**< Parameter p. */ + uint8_t *q; /**< Parameter q, the parameter can be NULL. */ + uint8_t *g; /**< Parameter g. */ + uint32_t pLen; /**< Length of parameter p. */ + uint32_t qLen; /**< Length of parameter q. */ + uint32_t gLen; /**< Length of parameter g. */ +} CRYPT_DhPara; + +/** + * @ingroup crypt_types + * + * Para structure of the Paillier algorithm + */ +typedef struct { + uint8_t *p; /**< Parameter p. */ + uint8_t *q; /**< Parameter q. */ + uint32_t pLen; /**< Length of parameter p. */ + uint32_t qLen; /**< Length of parameter q. */ + uint32_t bits; /**< Bits of para. */ +} CRYPT_PaillierPara; + +/** + * @ingroup crypt_types + * + * Metohd structure of the RAND registration interface, including the entropy source obtaining and clearing + * interface and random number obtaining and clearing interface. + * For details about how to use the default entropy source of the HiTLS, see CRYPT_EAL_RandInit(). + * If the default mode is not used, the entropy source obtaining interface cannot be null, interface for + * obtaining random numbers can be null. + */ +typedef struct { + /** + * @ingroup crypt_types + * + * Obtain the entropy source. If the default entropy source provided by HiTLS is not used, + * the API must be registered. the output data must meet requirements such as the length. + * The HiTLS does not check the entropy source. The data must be provided by the entropy source. + * + * @param ctx [IN] Context used by the caller. + * @param entropy [OUT] Indicates the obtained entropy source data. The length of the entropy source data + * must meet the following requirements: lenRange->min <= len <= lenRange->max. + * @param strength [IN] Entropy source strength. + * @param lenRange [IN] Entropy source length range. + * @retval 0 indicates success, and other values indicate failure. + */ +int32_t (*getEntropy)(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange); + + /** + * @ingroup crypt_types + * @brief The entropy source memory is cleared, this API is optional. + * @param ctx [IN] Context used by the caller + * @param entropy [OUT] Entropy source data + * @retval void + */ + void (*cleanEntropy)(void *ctx, CRYPT_Data *entropy); + + /** + * @ingroup crypt_types + * @brief Obtain the random number. This API is not need to registered. + * For registration, the output data must meet requirements such as the length. + * The HiTLS does not check the entropy source, but will implement if provide the function. + * + * @param ctx [IN] Context used by the caller + * @param nonce [OUT] Obtained random number. + * The length of the random number must be lenRange->min <= len <= lenRange->max. + * @param strength [IN]: Random number strength + * @param lenRange [IN] Random number length range. + * @retval 0 indicates success, and other values indicate failure. + */ + int32_t (*getNonce)(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange); + + /** + * @ingroup crypt_types + * @brief Random number memory clearance. this API is optional. + * @param ctx [IN] Context used by the caller + * @param nonce [OUT] random number + * @retval void + */ + void (*cleanNonce)(void *ctx, CRYPT_Data *nonce); +} CRYPT_RandSeedMethod; + +/** + * @ingroup crypt_ctrl_param + * + * Set and obtain internal mode parameters. + */ +typedef enum { + CRYPT_CTRL_SET_IV = 0, /**< Set IV data, the data type is uint8_t type.. */ + CRYPT_CTRL_GET_IV, /**< Obtains the IV data, the data type is uint8_t type. */ + CRYPT_CTRL_GET_BLOCKSIZE, /**< Obtain the block size, the data type is uint8_t type. */ + CRYPT_CTRL_SET_COUNT, /**< Set the counter information, the input is a four-byte little-endian byte stream, + the algorithm required is chacha20. */ + CRYPT_CTRL_SET_AAD, /**< Set the ADD information in AEAD encryption and decryption mode. */ + CRYPT_CTRL_GET_TAG, /**< Obtain the tag at the end in AEAD encryption or decryption. */ + CRYPT_CTRL_SET_TAGLEN, /**< Set the tag length before the encryption/decryption starts in AEAD + encryption/decryption. the setting type is uint32_t. */ + CRYPT_CTRL_SET_MSGLEN, /**< In CMM mode, the length of the encrypted message needs to be used as the + input for calculation. the length must be set before SET_AAD. The input data + type is int64_t. */ + CRYPT_CTRL_SET_FEEDBACKSIZE, /**< Setting the ciphertext feedback length in CFB mode. */ + CRYPT_CTRL_GET_FEEDBACKSIZE, /**< Obtaining the ciphertext feedback length in CFB mode. */ + CRYPT_CTRL_DES_NOKEYCHECK, /**< DES does not verify the key. */ + CRYPT_CTRL_RC2_SETEFFLEN, /**< RC2 Change the valid length of the key. */ + CRYPT_CTRL_SET_SM4_CONSTTIME, /**< SM4 selects the side channel security implementation, which reduces + the performance. Valid only when ARM assembly implementation is enabled. */ + CRYPT_CTRL_MAX +} CRYPT_CipherCtrl; + +/** + * @ingroup crypt_ctrl_param + * + * Set and obtain internal parameters of pkey. + */ +typedef enum { + CRYPT_CTRL_SET_ED25519_HASH_METHOD, /**< ED25519 Set the hash method. */ + CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, /**< RSA set the signature padding mode to EMSA_PKCSV15. */ + CRYPT_CTRL_SET_RSA_EMSA_PSS, /**< RSA set the signature padding mode to EMSA_PSS. */ + CRYPT_CTRL_SET_RSA_SALT, /**< When the RSA algorithm is used for PSS signature, the salt data is + specified. During signature, the user data address is directly saved + to the key. And the user data is used for the next signature, the caller + must ensure that the next signature is called within the life cycle + of the salt data. This option is not recommended and is used only for + KAT and self-verification. */ + CRYPT_CTRL_SET_ECC_POINT_FORMAT, /**< ECC PKEY set the point format. For the point format, + see CRYPT_PKEY_PointFormat. */ + CRYPT_CTRL_GET_RSA_SALT, /**< Obtain the salt length of the RSA algorithm. */ + CRYPT_CTRL_GET_RSA_PADDING, /**< Obtain the padding mode of the RSA algorithm. */ + CRYPT_CTRL_SET_RSA_PADDING, /**< Set the padding mode of the RSA algorithm. */ + CRYPT_CTRL_GET_RSA_MD, /**< Obtain the MD algorithm of the RSA algorithm. */ + CRYPT_CTRL_GET_RSA_MGF, /**< Obtain the mgf algorithm when the RSA algorithm padding mode + is PSS. */ + CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE, /**< Indicates whether to use the cofactor mode to prevent + man-in-the-middle from tampering with the public key. + Set this parameter to 1 when used or 0 when not used. */ + CRYPT_CTRL_SET_RSA_RSAES_OAEP, /**< RSA set the padding mode to RSAES_OAEP. */ + CRYPT_CTRL_SET_RSA_OAEP_LABEL, /**< RSA oaep padding and setting labels, used to generate hash values. */ + CRYPT_CTRL_SET_RSA_FLAG, /**< RSA set the flag. */ + CRYPT_CTRL_CLR_RSA_FLAG, /**< RSA clear the flag. */ + CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, /**< RSA Set the encryption/decryption padding mode to RSAES_PKCSV15. */ + CRYPT_CTRL_SET_SM9_HASH_METHOD, /**< SM9 Set the hash method. */ + CRYPT_CTRL_SET_SM2_USER_ID, + CRYPT_CTRL_SET_SM2_HASH_METHOD, /* SM2 calculate the hash value by set SM3. */ + CRYPT_CTRL_SET_SM2_SERVER, /* SM2 set the user status. */ + CRYPT_CTRL_GENE_SM2_R, /* SM2 obtain the R value. */ + CRYPT_CTRL_SET_SM2_R, /* SM2 set the R value. */ + CRYPT_CTRL_SET_SM2_RANDOM, /* SM2 set the r value. */ + CRYPT_CTRL_SET_SM2_PKG, /* SM2 uses the PKG process. */ + CRYPT_CTRL_SM2_GET_SEND_CHECK, /* SM2 obtain the check value sent from the local end to the peer end. */ + CRYPT_CTRL_SM2_DO_CHECK, /* SM2 check the shared key. */ + + CRYPT_CTRL_UP_REFERENCES, /**< The reference count value increases automatically. + It is applicable to asymmetric algorithms such as 25519, RSA, and ECC. */ + CRYPT_CTRL_GEN_ECC_PUBLICKEY, /**< Use prikey genarate pubkey. */ +} CRYPT_PkeyCtrl; + +/** + * @ingroup crypt_padding_type + * + * Padding mode enumerated type + */ +typedef enum { + CRYPT_PADDING_NONE = 0, /**< Never pad (full blocks only). */ + CRYPT_PADDING_ZEROS, /**< Zero padding (not reversible). */ + CRYPT_PADDING_ISO7816, /**< ISO/IEC 7816-4 padding. */ + CRYPT_PADDING_X923, /**< ANSI X.923 padding. */ + CRYPT_PADDING_PKCS5, /**< PKCS5 padding. */ + CRYPT_PADDING_PKCS7, /**< PKCS7 padding. */ + CRYPT_PADDING_MAX_COUNT +} CRYPT_PaddingType; + +typedef enum { + CRYPT_PKEY_EMSA_PKCSV15 = 1, /**< PKCS1-v1_5 according to RFC8017. */ + CRYPT_PKEY_EMSA_PSS, /**< PSS according to RFC8017. */ + CRYPT_PKEY_RSAES_OAEP, /**< OAEP according to RFC8017. */ + CRYPT_PKEY_RSAES_PKCSV15, /**< RSAES_PKCSV15 according to RFC8017. */ + CRYPT_PKEY_RSA_NO_PAD, + CRYPT_PKEY_RSA_PADDINGMAX, +} CRYPT_RsaPadType; + +/** + * @ingroup crypt_types + * + * Operation type + */ +typedef enum { + CRYPT_EVENT_ENC, /**< Encryption. */ + CRYPT_EVENT_DEC, /**< Decryption. */ + CRYPT_EVENT_GEN, /**< Generate the key. */ + CRYPT_EVENT_SIGN, /**< Signature. */ + CRYPT_EVENT_VERIFY, /**< Verify the signature. */ + CRYPT_EVENT_MD, /**< Hash. */ + CRYPT_EVENT_MAC, /**< MAC. */ + CRYPT_EVENT_KEYAGGREMENT, /**< Key negotiation. */ + CRYPT_EVENT_KEYDERIVE, /**< Derived key. */ + CRYPT_EVENT_RANDGEN, /**< Generating a random number. */ + CRYPT_EVENT_ZERO, /**< sensitive information to zero. */ + CRYPT_EVENT_ERR, /**< An error occurred. */ + CRYPT_EVENT_SETSSP, /**< Adding and Modifying Password Data and SSP. */ + CRYPT_EVENT_GETSSP, /**< Access password data and SSP. */ + CRYPT_EVENT_MAX +} CRYPT_EVENT_TYPE; + +/** + * @ingroup crypt_types + * + * Algorithm type + */ +typedef enum { + CRYPT_ALGO_CIPHER = 0, + CRYPT_ALGO_PKEY, + CRYPT_ALGO_MD, + CRYPT_ALGO_MAC, + CRYPT_ALGO_KDF, + CRYPT_ALGO_RAND +} CRYPT_ALGO_TYPE; + +/** + * @ingroup crypt_types + * @brief event report. + * + * @param oper [IN] Operation type. + * @param type [IN] Algorithm type. + * @param id [IN] Algorithm ID. + * @param err [IN] CRYPT_SUCCESS, if successful. + * For other error codes, see crypt_errno.h. + * + * @retval None + */ +typedef void (*EventReport)(CRYPT_EVENT_TYPE oper, CRYPT_ALGO_TYPE type, int32_t id, int32_t err); + +/** + * @ingroup crypt_types + * + * Event reporting callback registration interface, the EAL reports an event when the service is executed + * and an error is reported. + * If the CMVP feature is enabled, the default implementation is provided and registration is not allowed. + * Note that Multi-threading is not supported. + * + * @param func [IN] Event reporting and processing callback + * + * @retval NONE + */ +void CRYPT_EAL_RegEventReport(EventReport func); + +/** + * @ingroup crypt_getInfo_type + * + * Obtain the algorithm attribute type. + */ +typedef enum { + CRYPT_INFO_IS_AEAD = 0, /**< Whether the AEAD algorithm is used. */ + CRYPT_INFO_IS_STREAM, /**< Stream encryption or not. */ + CRYPT_INFO_IV_LEN, /**< Algorithm IV length. */ + CRYPT_INFO_KEY_LEN, /**< Algorithm key length. */ + CRYPT_INFO_BLOCK_LEN, /**< Algorithm block length. */ + CRYPT_INFO_MAX +} CRYPT_INFO_TYPE; + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // CRYPT_TYPES_H diff --git a/include/tls/hitls.h b/include/tls/hitls.h new file mode 100644 index 00000000..79b3d87b --- /dev/null +++ b/include/tls/hitls.h @@ -0,0 +1,1274 @@ +/* + * 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 hitls + * @ingroup hitls + * @brief TLS parameter configuration + */ + +#ifndef HITLS_H +#define HITLS_H + +#include +#include +#include "hitls_type.h" +#include "hitls_config.h" +#include "hitls_cert_type.h" +#include "bsl_uio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls + * @brief Create a TLS object and deep copy the HITLS_Config to the HITLS_Ctx. + * + * This is the main TLS structure, which starts to establish a secure link through the client or server + * on the basis that the link has been established at the network layer. + * + * @attention The HITLS_Config can be released after the creation is successful. + * @param config [IN] Config context + * @retval HITLS_Ctx pointer. If the operation fails, a null value is returned. + */ +HITLS_Ctx *HITLS_New(HITLS_Config *config); + +/** + * @ingroup hitls + * @brief Release the TLS connection. + * + * @param ctx [IN] TLS connection handle. + * @retval void + */ +void HITLS_Free(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Set the UIO object for the HiTLS context. + * + * Bind the HiTLS context to the UIO object, through which the TLS object sends data, reads data, + * and controls the connection status at the network layer. + * After successfully setting, the number of times the UIO object is referenced increases by 1. + * BSL_UIO_Free is called to release the association between the HiTLS and UIO when HITLS_Free is called. + * + * @attention After a HiTLS context is bound to a UIO object, the UIO object cannot be bound to other HiTLS contexts. + * This function must be called before HITLS_Connect and HITLS_Accept. + * @param ctx [OUT] TLS connection handle. + * @param uio [IN] UIO object. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetUio(HITLS_Ctx *ctx, BSL_UIO *uio); + +/** + * @ingroup hitls + * @brief Read UIO for the HiTLS context. + * + * @attention Must be called before HITLS_Connect and HITLS_Accept and released after HITLS_Free. + * If this function has been called, you must call BSL_UIO_Free to release the UIO. + * @param ctx [OUT] TLS connection handle. + * @param uio [IN] UIO object. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetReadUio(HITLS_Ctx *ctx, BSL_UIO *uio); + +/** + * @ingroup hitls + * @brief Obtain the UIO object from the HiTLS context. + * + * @param ctx [IN] TLS object. + * @retval UIO object. + */ +BSL_UIO *HITLS_GetUio(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the UIO object of the read data. + * + * @param ctx [IN] TLS object + * @retval UIO object + */ +BSL_UIO *HITLS_GetReadUio(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief The client starts the handshake with the TLS server. + * + * Starting the handshake with the TLS server using HITLS_Connect. + * The UIO object must be created and bound to the HiTLS context. + * HITLS_Connect is designed as a non-blocking interface. If the handshake cannot be continued, + * the returned value will not be HITLS_SUCCESS. + * If the return value is HITLS_REC_NORMAL_RECV_BUF_EMPTY or HITLS_REC_NORMAL_IO_BUSY, + * no fatal error occurs. Problems such as network congestion or network delay may occur. + * You can continue to call HITLS_Connect. Note that if UIO is blocked, HITLS_Connect will also block, + * but the return value is processed in the same way. + * + * @attention Only clients can call this interface. + * @param ctx [IN] TLS connection handle. + * @retval HITLS_SUCCESS + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY, record The receiving buffer is NULL and the handshake can be continued. + * @retval HITLS_REC_NORMAL_IO_BUSY, the network I/O is busy and needs to wait for the next sending. + * You can continue the handshake. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_Connect(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Set the initial status of the connection. + * + * @param ctx [IN] TLS connection handle. + * @param isClient [IN] Set the current client or server. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetEndPoint(HITLS_Ctx *ctx, bool isClient); + +/** + * @ingroup hitls + * @brief The server waits for the client to start handshake. + * + * The server waits for the client to initiate the handshake. + * The UIO object must be created and bound to the HiTLS context.\n + * HITLS_Accept is designed for non-blocking interfaces. + * If the handshake cannot be continued, the system returns. The return value is not success. + * If the return value is HITLS_REC_NORMAL_RECV_BUF_EMPTY or HITLS_REC_NORMAL_IO_BUSY, no fatal error occurs. + * Problems such as network congestion or network delay may occur. You can continue to call HITLS_Accept. + * Note that if the UIO is blocked, the HITLS_Accept will also be blocked, but the processing + * of the returned value is the same. + * + * @attention Only the server calls this API. + * @param ctx [IN] TLS connection handle. + * @retval HITLS_SUCCESS, the handshake is successful. + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY, record The receiving buffer is NULL and the handshake can continue. + * @retval HITLS_REC_NORMAL_IO_BUSY, the network I/O is busy and needs to wait for the next sending. + * You can continue the handshake. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_Accept(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Read application data + * + * @attention Only the application data decrypted by one record can be read by HiTLS at a time + * HiTLS copies the application data to the input cache. + * If the cache size is less than 16 KB, the maximum size of the application message decrypted + * by a single record is 16 KB. This will result in a partial copy of the application data + * You can call HITLS_GetReadPendingBytes to obtain the size of the remaining readable application data + * in the current record. This is useful in DTLS scenarios. + * @param ctx [IN] TLS context + * @param data [OUT] Read data + * @param bufSize [IN] Size of the buffer + * @param readLen [OUT] Read length + * @retval HITLS_SUCCESS, if successful + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY, record The receiving buffer is NULL and can be read again. + * @retval HITLS_REC_NORMAL_IO_BUSY, the network I/O is busy and needs to wait for the next sending + * You can continue to read the I/O. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_Read(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen); + +/** + * @ingroup hitls + * @brief Write data. + * + * Encrypts and packs data with the specified length dataLen into a single record and sends the record. + * + * @attention The length of the data to be sent cannot exceed the maximum writable length, + * which can be obtained by calling HITLS_GetMaxWriteSize. + * @param ctx [IN] TLS context + * @param data [IN] Data to be written + * @param dataLen [IN] Length to be written + * @retval HITLS_SUCCESS is sent successfully. + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY, record If the receiving buffer is NULL, the message can be sent again. + * @retval HITLS_REC_NORMAL_IO_BUSY, The network I/O is busy and needs to wait for the next sending. + * You can continue sending the I/O. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_Write(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen); + +/** + * @ingroup hitls + * @brief Obtain the maximum writable (plaintext) length. + * + * @param ctx [OUT] TLS connection handle. + * @param len [OUT] Maximum writable plaintext length (within 16 KB) + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_GetMaxWriteSize(const HITLS_Ctx *ctx, uint32_t *len); + +/** + * @ingroup hitls + * @brief Obtain user data from the HiTLS context. This interface is called in the callback registered with the HiTLS. + * + * @attention must be called before HITLS_Connect and HITLS_Accept. + * The life cycle of the user data pointer must be longer than the life cycle of the TLS object. + * @param ctx [OUT] TLS connection handle. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the TLS object pointer of the input parameter is null. + */ +void *HITLS_GetUserData(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Save the user data in the HiTLS context, which can be obtained from the callback registered with the HiTLS. + * + * @attention must be called before HITLS_Connect and HITLS_Accept. + * The life cycle of the user data pointer must be greater than the life cycle of the TLS object.\n + * If the user data needs to be cleared, the HITLS_SetUserData(ctx, NULL) interface can be called directly. + * The Clean interface is not provided separately. + * @param ctx [OUT] TLS connection handle. + * @param userData [IN] Pointer to the user data. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the TLS object pointer of the input parameter is null. + */ +int32_t HITLS_SetUserData(HITLS_Ctx *ctx, void *userData); + +/** + * @ingroup hitls + * @brief Close the TLS connection. + * + * If the peer end is not closed, the system sends a closed notify message to the peer end. + * HITLS_Close must not be called if a fatal error has occurred on the link. + * + * @param ctx [IN] TLS connection handle. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_Close(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Set the shutdown status of the TLS link. + * + * In HITLS_Close, if the peer end is not closed, a closed notification message is sent to the peer end. + * When the local end sends a closed notify message, the HiTLS sets the HITLS_SENT_SHUTDOWN flag bit. + * When the local end receives the closed notify message, the HiTLS sets the HITLS_RECEIVED_SHUTDOWN flag bit. + * By default, the HiTLS needs to send and receive closed notifications. + * The actual condition for properly closing a session is HITLS_SENT_SHUTDOWN. (According to the TLS RFC, + * it is acceptable to send only close_notify alerts without waiting for a reply from the peer.) + * If HITLS_RECEIVED_SHUTDOWN is set, it indicates that the peer end does not need to wait for the closed notification. + * + * @param ctx [IN] TLS connection handle. + * @param mode [IN] TLS shutdown status: HITLS_SENT_SHUTDOWN / HITLS_RECEIVED_SHUTDOWN. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetShutdownState(HITLS_Ctx *ctx, uint32_t mode); + +/** + * @ingroup hitls + * @brief Obtain the shutdown status of the TLS link. + * + * @param ctx [IN] TLS connection handle. + * @param mode [OUT] TLS shutdown status: HITLS_SENT_SHUTDOWN / HITLS_RECEIVED_SHUTDOWN. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. +*/ +int32_t HITLS_GetShutdownState(const HITLS_Ctx *ctx, uint32_t *mode); + +/** + * @ingroup hitls + * @brief Obtain the HiTLS negotiation version. + * + * @param ctx [IN] TLS object + * @param version [OUT] Negotiated version + * @retval HITLS_SUCCESS, obtained successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetNegotiatedVersion(const HITLS_Ctx *ctx, uint16_t *version); + +/** + * @ingroup hitls + * @brief Obtain the latest protocol version. + * + * @param ctx [IN] TLS object + * @param maxVersion [OUT] Latest protocol version supported + * @retval HITLS_SUCCESS, obtained successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetMaxProtoVersion(const HITLS_Ctx *ctx, uint16_t *maxVersion); + +/** + * @ingroup hitls + * @brief Obtain the latest protocol version. + * + * @param ctx [IN] TLS object + * @param maxVersion [OUT] Latest protocol version supported + * @retval HITLS_SUCCESS, obtained successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetMinProtoVersion(const HITLS_Ctx *ctx, uint16_t *minVersion); + +/** + * @ingroup hitls + * @brief Set the minimum protocol version based on the specified version. + * + * @param ctx [OUT] TLS object + * @param versiion [IN] The given version + * @attention The maximum version number and minimum version number must be both TLS and DTLS. Currently, + * only DTLS 1.2 is supported. This interface is used together with the full configuration interfaces, + * such as HITLS_CFG_NewDTLSConfig and HITLS_CFG_NewTLSConfig. + * If the TLS full configuration is configured, only the TLS version can be set. + * If full DTLS configuration is configured, only the DTLS version can be set. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetMinProtoVersion(HITLS_Ctx *ctx, uint16_t version); + +/** + * @ingroup hitls + * @brief Set the maximum protocol version that is supported based on the specified version. + * + * @param ctx [OUT] TLS object + * @param versiion [IN] The given version + * @attention The maximum version number and minimum version number must be both TLS and DTLS. Currently, + * only DTLS 1.2 is supported. This function is used together with the full configuration interfaces, + * such as HITLS_CFG_NewDTLSConfig and HITLS_CFG_NewTLSConfig. + * If the TLS full configuration is configured, only the TLS version can be set. + * If full DTLS configuration is configured, only the DTLS version can be set. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetMaxProtoVersion(HITLS_Ctx *ctx, uint16_t version); + +/** + * @ingroup hitls + * @brief Obtain whether to use the AEAD algorithm. + * + * @param ctx [IN] TLS object + * @param isAead [OUT] Indicates whether to use the AEAD algorithm. + * @retval HITLS_SUCCESS, obtained successfully. + * HITLS_NULL_INPUT, The input parameter pointer is null. + */ +int32_t HITLS_IsAead(const HITLS_Ctx *ctx, uint8_t *isAead); + +/** + * @ingroup hitls + * @brief Check whether DTLS is used. + * + * @param ctx [IN] TLS object + * @param isDtls [OUT] Indicates whether to use DTLS. + * @retval HITLS_SUCCESS, is obtained successfully. + * HITLS_NULL_INPUT, The input parameter pointer is null. + */ +int32_t HITLS_IsDtls(const HITLS_Ctx *ctx, uint8_t *isDtls); + +/** + * @ingroup hitls + * @brief Record the error value of the HiTLS link. + * + * @param ctx [OUT] TLS connection handle + * @param ret [IN] Error value + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetErrorCode(HITLS_Ctx *ctx, int32_t errorCode); + +/** + * @ingroup hitls + * @brief Obtain the error value of the HiTLS link. + * + * @param ctx [OUT] TLS connection handle + * @retval Link error value + */ +int32_t HITLS_GetErrorCode(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the information about whether the handshake is complete. + * + * @param ctx [OUT] TLS connection handle + * @param isDone [IN] Indicates whether the handshake is complete. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_IsHandShakeDone(const HITLS_Ctx *ctx, uint8_t *isDone); + +/** + * @ingroup hitls + * @brief Indicates whether the HiTLS object functions as the server. + * + * @param ctx [OUT] TLS connection handle + * @param isServer [IN] Indicates whether to function as the server. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_IsServer(const HITLS_Ctx *ctx, uint8_t *isServer); + +/** + * @ingroup hitls + * @brief Check the HiTLS object in the read cache. + * + * (including processed and unprocessed data, excluding the network layer) Whether there is data + * + * @param ctx [IN] TLS connection handle + * @param isPending [OUT] Whether there is data. The options are as follows: 1: yes; 0: no. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_ReadHasPending(const HITLS_Ctx *ctx, uint8_t *isPending); + +/** + * @ingroup hitls + * @brief Obtain the number of bytes of application data to be read from the current record from the HiTLS object. + * + * @attention When the HiTLS works in data packet transmission (DTLS), the HITLS_Read may + * copy part of the application packet because the input buffer is not large enough. + * This function is used to obtain the remaining size of the application packet. + * This is useful for transport over DTLS. + * @param ctx [IN] TLS connection handle + * @retval Number of bytes of application data that can be read. + */ +uint32_t HITLS_GetReadPendingBytes(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the signature hash algorithm used by the peer end. + * + * @param ctx [IN] TLS connection handle + * @param peerSignScheme [OUT] Peer signature hash algorithm + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_GetPeerSignScheme(const HITLS_Ctx *ctx, HITLS_SignHashAlgo *peerSignScheme); + +/** + * @ingroup hitls + * @brief Obtain the signature hash algorithm used by the local end. + * + * @param ctx [IN] TLS connection handle + * @param localSignScheme [OUT] Local signature hash algorithm + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_GetLocalSignScheme(const HITLS_Ctx *ctx, HITLS_SignHashAlgo *localSignScheme); + +/** + * @ingroup hitls + * @brief Set the group supported by the hitls object. + * + * @param ctx [OUT] hitls context + * @param lst [IN] group list + * @param groupSize [IN] List length + * @retval HITLS_SUCCESS is set successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetEcGroups(HITLS_Ctx *ctx, uint16_t *lst, uint32_t groupSize); + +/** + * @ingroup hitls + * @brief Set the signature algorithm supported by the hitls object. + * + * @param ctx [OUT] hitls context. + * @param signAlgs [IN] List of supported signature algorithms. + * @param signAlgsSize [IN] Length of the signature algorithm list. + * @retval HITLS_SUCCESS, set successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetSigalgsList(HITLS_Ctx *ctx, const uint16_t *signAlgs, uint16_t signAlgsSize); + +/** + * @ingroup hitls + * @brief Set the EC point format of the hitls. + * + * @attention Currently, the value can only be HITLS_ECPOINTFORMAT_UNCOMPRESSED. + * @param ctx [OUT] hitls context. + * @param pointFormats [IN] ec point format, corresponding to the HITLS_ECPointFormat enumerated value. + * @param pointFormatsSize [IN] Length of the ec point format + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetEcPointFormats(HITLS_Ctx *ctx, const uint8_t *pointFormats, uint32_t pointFormatsSize); + +/** + * @ingroup hitls + * @brief Set whether to verify the client certificate. + * + * @param ctx [OUT] TLS connection handle + * @param support [IN] Indicates whether to verify the client certificate, the options are + * as follows: true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetClientVerifySupport(HITLS_Ctx *ctx, bool support); + +/** + * @ingroup hitls + * @brief Set whether to support the function without the client certificate, Takes effect only when the client + * certificate is verified. + * + * Client: This setting has no impact. + * Server: When an NULL certificate is received from the client, indicates whether the certificate passes + * the verification, the verification fails by default. + * + * @param ctx [OUT] TLS connection handle + * @param support [IN] Indicates whether the authentication is successful when there is no client certificate. + true: If the certificate sent by the client is NULL, the server still passes the verification. + false: If the certificate sent by the client is NULL, the server fails the verification. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetNoClientCertSupport(HITLS_Ctx *ctx, bool support); + +/** + * @ingroup hitls + * @brief Set whether to support post-handshake AUTH. + * + * @param ctx [OUT] TLS connection handle + * @param support [IN] true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetPostHandshakeAuthSupport(HITLS_Ctx *ctx, bool support); + +/** + * @ingroup hitls + * @brief Set whether to support do not proceed dual-ended verification. + * + * @param ctx [OUT] TLS connection handle + * @param support [IN] true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetVerifyNoneSupport(HITLS_Ctx *ctx, bool support); + +/** + * @ingroup hitls + * @brief Set whether the client certificate can be requested only once. + * + * @param ctx [OUT] TLS connection handle + * @param support [IN] true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetClientOnceVerifySupport(HITLS_Ctx *ctx, bool support); + +/** + * @ingroup hitls + * @brief Obtain the value of hitlsConfig. + * + * @param ctx [IN] TLS connection handle + * @retval NULL, The input parameter pointer is null. + * @retval hitlsConfig in ctx. + */ +const HITLS_Config *HITLS_GetConfig(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Clears the configured TLS1.3 cipher suite. + * + * @param ctx [IN] TLS connection handle. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_ClearTLS13CipherSuites(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Set the supported key suites. + * + * The sequence of the key suites affects the priority of the selected key suites. + * The key suites with the highest priority are selected first. + * + * @attention Do not check the cipher suite to meet the changes in the supported version. + * @param ctx [OUT] config handle. + * @param cipherSuites [IN] Key suite array, corresponding to the HITLS_CipherSuite enumerated value. + * @param cipherSuitesSize [IN] Key suite array length. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetCipherSuites(HITLS_Ctx *ctx, const uint16_t *cipherSuites, uint32_t cipherSuitesSize); + +/** + * @ingroup hitls + * @brief Obtain the negotiated cipher suite pointer. + * + * @param ctx [IN] TLS connection handle + * @retval Pointer to the negotiated cipher suite. + * NULL, the input parameter pointer is null. + */ +const HITLS_Cipher *HITLS_GetCurrentCipher(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the random number of the client and server during the handshake. + * + * @param ctx [IN] TLS connection handle + * @param out [OUT] Random number obtained + * @param outlen [OUT] Length of the input parameter out. + * If the length is greater than the maximum random number length, the value will be changed. + * @param isClient [IN] True, obtain the random number of the client. + * False, obtain the random number of the server. + * @retval HITLS_SUCCESS, obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetRandom(const HITLS_Ctx *ctx, uint8_t *out, uint32_t *outlen, bool isClient); + +/** + * @ingroup hitls + * @brief Obtain the current handshake status. + * + * @param ctx [IN] TLS connection handle + * @param state [OUT] Current handshake status + * @retval HITLS_SUCCESS, Obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetHandShakeState(const HITLS_Ctx *ctx, uint32_t *state); + +/** + * @brief Obtain the handshake status character string. + * + * @param state [IN] Handshake status + * @retval Character string corresponding to the handshake status + */ +const char *HITLS_GetStateString(uint32_t state); + +/** + * @ingroup hitls + * @brief Check whether a handshake is being performed. + * + * @param ctx [IN] TLS connection handle + * @param isHandShaking [OUT] Indicates whether the handshake is in progress. + * @retval HITLS_SUCCESS, Obtaining the status succeeded. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_IsHandShaking(const HITLS_Ctx *ctx, uint8_t *isHandShaking); + +/** + * @ingroup hitls + * @brief Obtain whether renegotiation is supported. + * + * @param ctx [IN] hitls Context + * @param isSupportRenegotiation [OUT] Whether to support renegotiation + * @retval HITLS_SUCCESS, obtain successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetRenegotiationSupport(const HITLS_Ctx *ctx, uint8_t *isSupportRenegotiation); + +/** + * @ingroup hitls + * @brief Check whether the handshake has not been performed. + * + * @param ctx [IN] TLS connection handle + * @param isBefore [OUT] Indicates whether the handshake has not been performed. + * @retval HITLS_SUCCESS, obtaining the status succeeded. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_IsBeforeHandShake(const HITLS_Ctx *ctx, uint8_t *isBefore); + +/** + * @ingroup hitls + * @brief Set the MTU of a path. + * + * @param ctx [IN] TLS connection handle + * @param mtu [IN] Set the MTU. + * @retval HITLS_SUCCESS, obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetMtu(HITLS_Ctx *ctx, long mtu); + +/** + * @ingroup hitls + * @brief Obtain the version number set by the client in ClientHello. + * + * @param ctx [IN] TLS connection handle + * @param clientVersion [OUT] Obtained version number + * @retval HITLS_SUCCESS, obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetClientVersion(const HITLS_Ctx *ctx, uint16_t *clientVersion); + +/** + * @ingroup hitls + * @brief The client/server starts handshake. + * + * @attention In the IDLE state, the HITLS_SetEndPoint must be called first. + * @param ctx [IN] TLS connection handle + * @retval HITLS_SUCCESS, obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_DoHandShake(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Check whether the current end is client. + * + * @param ctx [IN] TLS connection handle + * @param isClient [OUT] Client or not. + * @retval HITLS_SUCCESS, obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_IsClient(const HITLS_Ctx *ctx, bool *isClient); + +/** + * @ingroup hitls + * @brief Set the keyupdate type of the current context and send the keyupdate message. + * + * @param ctx [IN] TLS connection handle + * @param updateType [IN] keyupdate type + * @retval HITLS_SUCCESS, if successful. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_KeyUpdate(HITLS_Ctx *ctx, uint32_t updateType); + +/** + * @ingroup hitls + * @brief Return the keyupdate type of the current context. + * + * @param ctx [IN] TLS connection handle + * @retval KeyUpdateType in ctx + * @retval NULL, the input parameter pointer is null. + */ +int32_t HITLS_GetKeyUpdateType(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the supported peer group or the number of supported peer groups of the nth match. + * + * nmatch Value range: - 1 or a positive integer + * This function can be called only after negotiation and can be called only by the server. + * If nmatch is a positive integer, check the intersection of groups on the client and server, + * and return the nmatch group in the intersection by groupId. + * If the value of nmatch is - 1, the number of intersection groups on the client and server is + * returned based on groupId. + * + * @param ctx [IN] TLS connection handle. + * @param nmatch [IN] Sequence number of the group to be obtained, -1 Return the number of supported peer groups. + * @param groupId [OUT] Returned result. + * @retval HITLS_SUCCESS, Obtaining the status succeeded. + * For details about other error codes, see hitls_error.h. + * + */ +int32_t HITLS_GetSharedGroup(const HITLS_Ctx *ctx, int32_t nmatch, uint16_t *groupId); + +/** + * @ingroup hitls + * @brief Obtain the supported version number. + * + * @param ctx [IN] TLS connection handle. + * @param version [OUT] Supported version number. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_GetVersionSupport(const HITLS_Ctx *ctx, uint32_t *version); + +/** + * @ingroup hitls + * @brief Set the supported version number. + * + * @param ctx [OUT] TLS connection handle + * @param version [IN] Supported version number. + * @attention The maximum version number and minimum version number must be both TLS and DTLS. Currently, + * only DTLS 1.2 is supported. This function is used together with the full configuration interfaces, + * such as HITLS_CFG_NewDTLSConfig and HITLS_CFG_NewTLSConfig. + * If the TLS full configuration is configured, only the TLS version can be set. If full DTLS configuration + * is configured, only the DTLS version can be set. + * The versions must be consecutive. By default, the minimum and maximum versions are supported. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetVersionSupport(HITLS_Ctx *ctx, uint32_t version); + +/** + * @ingroup hitls + * @brief Set the supported version number range. + * + * @param ctx [OUT] TLS connection handle + * @param minVersion [IN] Minimum version number supported. + * @param maxVersion [IN] Maximum version number supported. + * @attention The maximum version number and minimum version number must be both TLS and DTLS. + * Currently, only DTLS 1.2 is supported. This function is used together with the full configuration interfaces, + * such as HITLS_CFG_NewDTLSConfig and HITLS_CFG_NewTLSConfig. + * If the TLS full configuration is configured, only the TLS version can be set. If full DTLS configuration is + * configured, only the DTLS version can be set. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetVersion(HITLS_Ctx *ctx, uint32_t minVersion, uint32_t maxVersion); + +/** + * @ingroup hitls + * @brief Set the version number to be disabled. + * + * @param ctx [OUT] TLS connection handle + * @param noversion [IN] Disabled version number. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetVersionForbid(HITLS_Ctx *ctx, uint32_t noVersion); + +/** + * @ingroup hitls + * @brief Sets whether to verify the version in the premaster secret. + * + * @param ctx [OUT] TLS Connection Handle. + * @param needCheck [IN] Indicates whether to perform check. + * @attention This parameter is valid for versions earlier than TLS1.1. + * true indicates that verification is supported, and false indicates that verification is not supported. In + * this case, rollback attacks may occur. For versions later than TLS1.1, forcible verification is supported. + * This interface takes effect on the server. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_SetNeedCheckPmsVersion(HITLS_Ctx *ctx, bool needCheck); + +/** + * @ingroup hitls + * @brief Set the silent disconnection mode. + * + * @param ctx [IN] TLS connection handle. + * @param mode [IN] Mode type. The value 0 indicates that the quiet disconnection mode is disabled, and the value 1 + * indicates that the quiet disconnection mode is enabled. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetQuietShutdown(HITLS_Ctx *ctx, int32_t mode); + +/** + * @ingroup hitls + * @brief Obtain the current silent disconnection mode. + * + * @param ctx [IN] TLS connection handle + * @param mode [OUT] Mode type. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetQuietShutdown(const HITLS_Ctx *ctx, int32_t *mode); + +/** + * @ingroup hitls + * @brief Sets whether to support the function of automatically selecting DH parameters. + * + * If the value is true, the DH parameter is automatically selected based on the length of the certificate private key. + * If the value is false, the DH parameter needs to be set. + * + * @param ctx [IN/OUT] hitls context. + * @param support [IN] Whether to support. The options are as follows: true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_SetDhAutoSupport(HITLS_Ctx *ctx, bool support); + +/** + * @ingroup hitls + * @brief Set the DH parameter specified by the user. + * + * @param ctx [IN/OUT] hitls context. + * @param dhPkey [IN] User-specified DH key. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT ctx or dhPkey field is NULL + */ +int32_t HITLS_SetTmpDh(HITLS_Ctx *ctx, HITLS_CRYPT_Key *dhPkey); + +/** + * @ingroup hitls + * @brief Sets the RecordPadding callback. + * + * @param ctx [IN/OUT] TLS Connection Handle + * @param callback [IN] Sets the RecordPadding callback. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetRecordPaddingCb(HITLS_Ctx *ctx, HITLS_RecordPaddingCb callback); + +/** + * @ingroup hitls + * @brief Obtains the RecordPadding callback function. + * + * @param ctx [IN/OUT] TLS Connection Handle + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +HITLS_RecordPaddingCb HITLS_GetRecordPaddingCb(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Sets the parameters arg required by the RecordPadding callback function. + * + * @param ctx [IN/OUT] TLS Connection Handle + * @param arg [IN] Related Parameter arg + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetRecordPaddingCbArg(HITLS_Ctx *ctx, void *arg); + +/** + * @ingroup hitls + * @brief Obtains the parameter arg required by the RecordPadding callback function. + * + * @param ctx [IN/OUT] TLS Connection Handle + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +void *HITLS_GetRecordPaddingCbArg(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the verification data and length of the peer end based on the received finished message. + * + * @param ctx [IN] TLS context + * @param buf [OUT] verify data + * @param bufLen [IN] Length of the buffer to be obtained + * @param dataLen [OUT] Actual length of the buf + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetPeerFinishVerifyData(const HITLS_Ctx *ctx, void *buf, uint32_t bufLen, uint32_t *dataLen); + +/** + * @ingroup hitls + * @brief Disables the verification of keyusage in the certificate. This function is enabled by default. + * + * @param ctx [OUT] config context + * @param close [IN] Sets whether to disable verification. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetCloseCheckKeyUsage(HITLS_Ctx *ctx, bool isClose); + +/** + * @ingroup hitls + * @brief Obtain the verification data and length of the local end based on the sent finished message. + * + * @param ctx [IN] TLS context + * @param buf [OUT] verify data + * @param bufLen [IN] Length of the buffer to be obtained + * @param dataLen [OUT] Indicates the actual length of the buffer + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetFinishVerifyData(const HITLS_Ctx *ctx, void *buf, uint32_t bufLen, uint32_t *dataLen); + +/** + * @ingroup hitls + * @brief Obtains whether security renegotiation is supported. + * + * @param ctx [IN] hitls context. + * @param isSecureRenegotiation [OUT] Whether to support security renegotiation + * @retval HITLS_SUCCESS, obtained successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetSecureRenegotiationSupport(const HITLS_Ctx *ctx, uint8_t *isSecureRenegotiation); + +/** + * @ingroup hitls + * @brief Perform renegotiation. + * + * @attention 1. After this interface is called, the user needs to call one of the + * HITLS_Connect / HITLS_Accept / HITLS_Read / HITLS_Write interfaces again, + * The HITLS_Renegotiate interface is used only for setting and initialization of renegotiation, + * The renegotiation process is performed when the user calls the + * HITLS_Connect / HITLS_Accept / HITLS_Read / HITLS_Write. + * 2. You are advised to use the HITLS_Connect / HITLS_Accept interface for renegotiation. + * After the negotiation is complete, call the HITLS_Read / HITLS_Write interface. + * 3. If the user uses HITLS_Read to perform renegotiation, + * the user may receive the app message from the peer end during the renegotiation. + * (1) If the renegotiation has not started, the HiTLS will return the message to the user. + * (2) If the renegotiation is in progress, no app message is received in this scenario, + * and the HiTLS sends an alert message to disconnect the link. + * 4. If the user uses the HITLS_Connect / HITLS_Accept / HITLS_Write for renegotiation, + * the user may receive the app message from the peer end during the renegotiation, + * HiTLS caches the message, the message is returned when a user calls HITLS_Read. + * Maximum of 50 app messages can be cached, if the cache is full, subsequent app messages will be + * ignored. + * @param ctx [IN] TLS Connection Handle + * @retval HITLS_SUCCESS, if successful. + * @retval For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_Renegotiate(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Obtain the current is whether in the renegotiation state. + * + * @attention For the server, the server does not enter the renegotiation state by sending only the hello request + * message, The server enters the renegotiation state only after receiving the client hello message. + * + * @param ctx [IN] TLS Connection Handle. + * @param isRenegotiationState [OUT] Indicates whether the renegotiation is in the renegotiation state. + * true: in the renegotiation state; false: not in the renegotiation state. + * @retval HITLS_SUCCESS, if successful. + * @retval For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetRenegotiationState(const HITLS_Ctx *ctx, uint8_t *isRenegotiationState); + + +/** + * @ingroup hitls + * @brief Obtain the current internal status. + * + * @param ctx [IN] TLS connection Handle. + * @param rwState [OUT] Current internal status information. + * @retval HITLS_SUCCESS, if successful. + * @retval For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetRwstate(const HITLS_Ctx *ctx, uint8_t *rwstate); + +/** + * @ingroup hitls + * @brief Check whether the client certificate can be verified. + * + * @param ctx [IN] TLS connection Handle. + * @param isSupport [OUT] Indicates whether to verify the client certificate. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_GetClientVerifySupport(HITLS_Ctx *ctx, uint8_t *isSupport); + +/** + * @ingroup hitls + * @brief Check whether no client certificate is supported, This command is valid only when client certificate + * verification is enabled. + * + * @param ctx [IN] TLS Connection Handle. + * @param isSupport [OUT] Whether no client certificate is supported. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_GetNoClientCertSupport(HITLS_Ctx *ctx, uint8_t *isSupport); + +/** + * @ingroup hitls + * @brief Query whether post-handshake AUTH is supported + * + * @param ctx [IN] TLS connection Handle. + * @param isSupport [OUT] indicates whether to support post-handshake AUTH. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_GetPostHandshakeAuthSupport(HITLS_Ctx *ctx, uint8_t *isSupport); + +/** + * @ingroup hitls + * @brief Query if support is available for not performing dual-end verification. + * + * @param ctx [IN] TLS Connection Handle. + * @param isSupport [OUT] if support is available for not performing dual-end verification. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_GetVerifyNoneSupport(HITLS_Ctx *ctx, uint8_t *isSupport); + +/** + * @ingroup hitls + * @brief Query whether the client certificate can be requested only once. + * + * @param ctx [IN] TLS Connection Handle. + * @param isSupport [OUT] Indicates whether the client certificate can be requested only once. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_GetClientOnceVerifySupport(HITLS_Ctx *ctx, uint8_t *isSupport); + + +/** + * @ingroup hitls + * @brief Clears the renegotiation count. + * + * @param ctx [IN] hitls context. + * @param renegotiationNum [OUT] Number of incoming renegotiations. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_ClearRenegotiationNum(HITLS_Ctx *ctx, uint32_t *renegotiationNum); + +/** + * @ingroup hitls + * @brief Obtain the negotiated group information. + * + * @param ctx [IN] TLS Connection Handle. + * @param group [OUT] Negotiated group information. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_GetNegotiateGroup(const HITLS_Ctx *ctx, uint16_t *group); + +/** + * @ingroup hitls + * @brief Setting the Encrypt-Then-Mac mode. + * + * @param ctx [IN] TLS connection handle. + * @param isEncryptThenMac [IN] Indicates whether to enable the Encrypt-Then-Mac mode. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetEncryptThenMac(HITLS_Ctx *ctx, uint32_t encryptThenMacType); + +/** + * @ingroup hitls + * @brief Obtains the Encrypt-Then-Mac type + * + * @param ctx [IN] TLS connection Handle. + * @param encryptThenMacType [OUT] Current Encrypt-Then-Mac mode. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_GetEncryptThenMac(const HITLS_Ctx *ctx, uint32_t *encryptThenMacType); + +/** + * @ingroup hitls + * @brief Setting the value of server_name. + * + * @param ctx [IN] TLS connection handle. + * @param serverName [IN] serverName. + * @param serverNameStrlen [IN] serverName length. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetServerName(HITLS_Ctx *ctx, uint8_t *serverName, uint32_t serverNameStrlen); + +/** + * @ingroup hitls + * @brief The algorithm suite can be preferentially selected from the algorithm list supported by the server. + * + * @param ctx [IN] TLS Connection Handle. + * @param isSupport [IN] Support or Not. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetCipherServerPreference(HITLS_Ctx *ctx, bool isSupport); + +/** + * @ingroup hitls + * @brief Obtains whether the current cipher suite supports preferential selection + * from the list of algorithms supported by the server. + * + * @param ctx [IN] TLS connection handle. + * @param isSupport [OUT] Support or Not. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_GetCipherServerPreference(const HITLS_Ctx *ctx, bool *isSupport); + +/** + * @ingroup hitls + * @brief Sets whether to support renegotiation. + * + * @param ctx [IN/OUT] TLS connection handle. + * @param isSupport [IN] Support or Not, true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + */ +int32_t HITLS_SetRenegotiationSupport(HITLS_Ctx *ctx, bool isSupport); + +/** + * @ingroup hitls + * @brief Sets whether to support session tickets. + * + * @param ctx [IN/OUT] TLS connection handle. + * @param support [IN] whether to support session tickets, true: yes; false: no + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + */ +int32_t HITLS_SetSessionTicketSupport(HITLS_Ctx *ctx, bool isSupport); + +/** + * @ingroup hitls + * @brief Check whether the session ticket is supported. + * + * @param ctx [IN] TLS connection handle. + * @param support [OUT] whether to support session tickets, true: yes; false: no + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + */ +int32_t HITLS_GetSessionTicketSupport(const HITLS_Ctx *ctx, uint8_t *isSupport); + +/** + * @ingroup hitls + * @brief Sets whether to send handshake messages by flight distance. + * + * @param ctx [IN/OUT] TLS connection handle. + * @param isEnable [IN] Indicates whether to enable handshake information sending by flight distance. + * The value 0 indicates disable, other values indicate enable. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetFlightTransmitSwitch(HITLS_Ctx *ctx, uint8_t isEnable); + +/** + * @ingroup hitls + * @brief Obtains the status of whether to send handshake information according to the flight distance. + * + * @param ctx [IN] TLS connection handle. + * @param isEnable [OUT] Indicates whether to send handshake information by flight distance + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_GetFlightTransmitSwitch(const HITLS_Ctx *ctx, uint8_t *isEnable); + +/** + * @ingroup hitls + * @brief Obtains all asynchronous fd. + * + * @param ctx [IN] TLS connection handle. + * @param fd [OUT] fd array. + * @param fdNums [OUT] fd number. + * @retval HITLS_SUCCESS, if successful. + * @retval For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetAllAsyncFds(HITLS_Ctx *ctx, int *fd, int *fdNums); + +/** + * @ingroup hitls + * @brief Obtains the certificate-based user data index number. + * + * @retval Index No. + * @retval For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_get_ex_data_X509_STORE_CTX_idx(void); + +/** + * @ingroup hitls + * @brief Sets the maximum size of the certificate chain that can be sent from the peer end. + * + * @param ctx [IN/OUT] TLS connection handle. + * @param maxSize [IN] Sets the maximum size of the certificate chain that can be sent from the peer end. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_SetMaxCertList(HITLS_Ctx *ctx, uint32_t maxSize); + +/** + * @ingroup hitls + * @brief Obtains the maximum size of the certificate chain that can be sent by the peer end. + * + * @param ctx [IN] TLS connection handle. + * @param maxSize [OUT] Maximum size of the certificate chain that can be sent from the peer end. + * @retval HITLS_NULL_INPUT, the input parameter pointer is NULL. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_GetMaxCertList(const HITLS_Ctx *ctx, uint32_t *maxSize); + +/** + * @ingroup hitls + * @brief This interface is valid only on the server. When the post-handshake command is configured, + * the client identity is verified through this interface. + * + * @param ctx [IN] TLS Connection Handle + * @retval HITLS_INVALID_INPUT, invalid input parameter. + * @retval HITLS_SUCCESS, if successful. + * @retval For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_VerifyClientPostHandshake(HITLS_Ctx *ctx); +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_H */ diff --git a/include/tls/hitls_alpn.h b/include/tls/hitls_alpn.h new file mode 100644 index 00000000..ca745ad2 --- /dev/null +++ b/include/tls/hitls_alpn.h @@ -0,0 +1,112 @@ +/* + * 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 hitls_alpn + * @ingroup hitls + * @brief TLS ALPN related type + */ + +#ifndef HITLS_ALPN_H +#define HITLS_ALPN_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HITLS_ALPN_ERR_OK 0 /* Correct execution. */ +#define HITLS_ALPN_ERR_ALERT_WARNING 1 /* Execution error, sent warning alert. */ +#define HITLS_ALPN_ERR_ALERT_FATAL 2 /* Execution error, sent fatal alert. */ +#define HITLS_ALPN_ERR_NOACK 3 /* Execution exception, ignore processing. */ + +/** + * @ingroup hitls_alpn + * @brief Callback prototype for selecting the ALPN protocol on the server, which is used to select + * the application layer protocol during ALPN negotiation. + * + * @param ctx [IN] Ctx context. + * @param selectedProto [OUT] Indicates the initial IP address of the protocol that is being matched. + * @param selectedProtoLen [OUT] Matching protocol length. + * @param clientAlpnList [IN] Client ALPN List. + * @param clientAlpnListSize [IN] Client ALPN List length. + * @param userData [IN] Context transferred by the user. + * @retval HITLS_ALPN_ERR_OK 0, indicates success. + HITLS_ALPN_ERR_ALERT_WARNING 1, indicates send warning alert. + HITLS_ALPN_ERR_ALERT_FATAL 2, indicates send fatal alert. + HITLS_ALPN_ERR_NOACK 3, indicates no processing. + */ +typedef int32_t (*HITLS_AlpnSelectCb)(HITLS_Ctx *ctx, uint8_t **selectedProto, uint8_t *selectedProtoSize, + uint8_t *clientAlpnList, uint32_t clientAlpnListSize, void *userData); + +/** + * @ingroup hitls_alpn + * @brief Sets the ALPN list on the client, which is used to negotiate the application layer protocol + * with the server in the handshake phase. + * + * @param config [OUT] Config context. + * @param alpnProtos [IN] Application layer protocol list. + * @param alpnProtosLen [IN] Length of the application layer protocol list. + * @retval If success, return HITLS_SUCCESS. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetAlpnProtos(HITLS_Config *config, const uint8_t *alpnProtos, uint32_t alpnProtosLen); + +/** + * @ingroup hitls_alpn + * @brief Sets the ALPN selection callback on the server. + * + * The callback is used to select the application layer protocol in the handshake phase, cb can be NULL. + * + * @param config [OUT] Config context. + * @param callback [IN] Server callback implemented by the user. + * @param userData [IN] Product context. + * @retval If success, return HITLS_SUCCESS. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetAlpnProtosSelectCb(HITLS_Config *config, HITLS_AlpnSelectCb callback, void *userData); + +/** + * @ingroup hitls_alpn + * @brief Sets the client ALPN list, which is used to negotiate the application layer protocol + * with the server in the handshake phase. + * + * @param ctx [OUT] TLS connection Handle. + * @param protos [IN] Application layer protocol list. + * @param protosLen [IN] Length of the application layer protocol list. + * @retval If success, return HITLS_SUCCESS. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetAlpnProtos(HITLS_Ctx *ctx, const uint8_t *protos, uint32_t protosLen); + +/** + * @ingroup hitls_alpn + * @brief Obtaining the ALPN Negotiation Result + * + * @param ctx [IN] Ctx context. + * @param proto [OUT] Header address of the outgoing selected protocol. + * @param protoLen [OUT] Length of the outgoing selected protocol. + * @retval If success, return HITLS_SUCCESS. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetSelectedAlpnProto(HITLS_Ctx *ctx, uint8_t **proto, uint32_t *protoLen); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_ALPN_H \ No newline at end of file diff --git a/include/tls/hitls_cert.h b/include/tls/hitls_cert.h new file mode 100644 index 00000000..e21ce682 --- /dev/null +++ b/include/tls/hitls_cert.h @@ -0,0 +1,754 @@ +/* + * 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 hitls_cert + * @ingroup hitls + * @brief TLS Certificate Operation Interface + */ + +#ifndef HITLS_CERT_H +#define HITLS_CERT_H + +#include +#include +#include "hitls_type.h" +#include "hitls_cert_type.h" +#include "hitls_cert_reg.h" +#include "hitls_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_cert + * @brief Set the verify store used by the TLS configuration, which is used for certificate verification. + * + * @param config [OUT] TLS link configuration. + * @param store [IN] CA certificate store. + * @param isClone [IN] Indicates whether deep copy is required. true indicates need, false indicates not need. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetVerifyStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the verify store used by the TLS configuration. + * + * @attention The user cannot release the memory. + * + * @param config [IN] TLS link configuration + * @retval Verify store + */ +HITLS_CERT_Store *HITLS_CFG_GetVerifyStore(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Set the verify store used by the TLS link for certificate verification. + * + * @param ctx [OUT] TLS link object + * @param store [IN] CA certificate store + * @param isClone [IN] Indicates whether deep copy is required. The options are true and false. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetVerifyStore(HITLS_Ctx *ctx, HITLS_CERT_Store *store, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the verify store used by the TLS link. + * + * @param ctx [IN] TLS link object + * @retval Verify store + */ +HITLS_CERT_Store *HITLS_GetVerifyStore(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Set the chain store used by the TLS configuration, which is used to construct the certificate chain. + * + * @param config [OUT] TLS link configuration + * @param store [IN] Certificate chain store + * @param isClone [IN] Indicates whether deep copy is required. The options are as follows: true: yes; false: no. + * @retval HITLS_SUCCESS. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetChainStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the chain store used by the TLS configuration. + * + * @attention The user cannot release the memory. + * @param config [IN] TLS link configuration + * @retval Chain store + */ +HITLS_CERT_Store *HITLS_CFG_GetChainStore(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Set the chain store used by the TLS link to construct the certificate chain. + * + * @param ctx [OUT] TLS link object + * @param store [IN] Certificate chain + * @param isClone [IN] Indicates whether deep copy is required. The options are true and false. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetChainStore(HITLS_Ctx *ctx, HITLS_CERT_Store *store, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the chain store used by the TLS link. + * + * @param ctx [IN] TLS object + * @retval Chain Store + */ +HITLS_CERT_Store *HITLS_GetChainStore(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Set the cert store used by the TLS configuration. + * + * @attention If verify store is not set, use cert store to verify the certificate. + * If chain store is not set, use cert store to construct a certificate chain. + * @param config [OUT] TLS link configuration + * @param store [IN] Trust certificate store + * @param isClone [IN] Indicates whether deep copy is required. The options are true and false. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetCertStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the cert store used by the TLS configuration. + * + * @attention The user cannot release the memory. + * @param config [IN] TLS link configuration + * @retval Cert store + */ +HITLS_CERT_Store *HITLS_CFG_GetCertStore(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Set the cert store used by the TLS link. + * + * @attention If verify store is not set, use cert store to verify the certificate. + * If chain store is not set, use cert store to construct a certificate chain. + * @param ctx [OUT] TLS link object + * @param store [IN] Trust certificate store + * @param isClone [IN] Indicates whether deep copy is required. The options are true and false. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetCertStore(HITLS_Ctx *ctx, HITLS_CERT_Store *store, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the cert store used by the TLS link. + * + * @param ctx [IN] TLS link object + * @retval Cert store + */ +HITLS_CERT_Store *HITLS_GetCertStore(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Set the certificate verification depth. + * + * @param config [OUT] TLS link configuration + * @param depth [IN] Verification depth + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetVerifyDepth(HITLS_Config *config, uint32_t depth); + +/** + * @ingroup hitls_cert + * @brief Obtain the certificate verification depth. + * + * @param config [IN] TLS link configuration + * @param depth [OUT] Certificate verification depth + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetVerifyDepth(const HITLS_Config *config, uint32_t *depth); + +/** + * @ingroup hitls_cert + * @brief Set the certificate verification depth. + * + * @param ctx [OUT] TLS link object + * @param depth [IN] Verification depth + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetVerifyDepth(HITLS_Ctx *ctx, uint32_t depth); + +/** + * @ingroup hitls_cert + * @brief Obtain the certificate verification depth. + * + * @param ctx [IN] TLS link object + * @param depth [OUT] Certificate verification depth + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_GetVerifyDepth(const HITLS_Ctx *ctx, uint32_t *depth); + +/** + * @ingroup hitls_cert + * @brief Password Callback + * + * @attention This callback function must be compatible with OpenSSL and logically the same as OpenSSL. + * @param buf [OUT] Passwd data. + * @param bufLen [IN] Maximum buffer length. + * @param flag [IN] r/w flag. The value 0 indicates read, and the value 1 indicates write. + * @param userdata [IN] User data. + * + * @retval Passwd Data length + */ +typedef int32_t (*HITLS_PasswordCb)(char *buf, int32_t bufLen, int32_t flag, void *userdata); + +/** + * @ingroup hitls_cert + * @brief Set the default password callback, cb can be NULL. + * + * @param config [OUT] TLS link configuration + * @param cb [IN] Password Callback + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetDefaultPasswordCb(HITLS_Config *config, HITLS_PasswordCb cb); + +/** + * @ingroup hitls_cert + * @brief Callback for obtaining the default password. + * + * @param config [IN] TLS link configuration. + * @retval Password Callback. + */ +HITLS_PasswordCb HITLS_CFG_GetDefaultPasswordCb(HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Set the user data used by the password callback. + * + * @param config [OUT] TLS link configuration + * @param userdata [IN] User data + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetDefaultPasswordCbUserdata(HITLS_Config *config, void *userdata); + +/** + * @ingroup hitls_cert + * @brief Obtain the user data used by the password callback. + * + * @param config [IN] TLS link configuration + * @retval User Data + */ +void *HITLS_CFG_GetDefaultPasswordCbUserdata(HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Set the default password callback, cb can be NULL + * + * @param ctx [OUT] TLS link object + * @param cb [IN] password Callback + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetDefaultPasswordCb(HITLS_Ctx *ctx, HITLS_PasswordCb cb); + +/** + * @ingroup hitls_cert + * @brief Callback for obtaining the default password + * + * @param ctx [IN] TLS link object + * @retval Password Callback + */ +HITLS_PasswordCb HITLS_GetDefaultPasswordCb(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Set the user data used by the default password callback. + * + * @param ctx [OUT] TLS link object + * @param userdata [IN] user data + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetDefaultPasswordCbUserdata(HITLS_Ctx *ctx, void *userdata); + +/** + * @ingroup hitls_cert + * @brief Obtain the user data used by the default password callback. + * + * @param ctx [IN] TLS link object + * @retval User data + */ +void *HITLS_GetDefaultPasswordCbUserdata(HITLS_Ctx *ctx); + +#ifndef HITLS_NO_TLCP11 +/** + * @ingroup hitls_cert + * @brief Add the device certificate by the ShangMi(SM) cipher suites. + * Only one certificate can be added for each type. + * + * @param config [OUT] TLS link configuration + * @param cert [IN] Device certificate + * @param isClone [IN] Indicates whether deep copy is required. The options are as follows: true: yes; false: no. + * @param isTlcpEncCert [IN] Indicates whether the certificate is encrypted by China. + * The options are as follows: true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); + +/** + * @ingroup hitls_cert + * @brief Add the private key of the device certificate by the ShangMi(SM) cipher suites. + * Only one private key can be added for each type of certificate. + * + * @param config [OUT] TLS link configuration + * @param privateKey [IN] Certificate private key + * @param isClone [IN] Indicates whether deep copy is required. The options are as follows: true: yes; false: no. + * @param isTlcpEncCertPriKey [IN] Indicates whether the private key of the encryption certificate is + * the private key of the encryption certificate. true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetTlcpPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, + bool isClone, bool isTlcpEncCertPriKey); +#endif + +/** + * @ingroup hitls_cert + * @brief Add a device certificate. Only one certificate of each type can be added + * + * @param config [OUT] TLS link configuration + * @param cert [IN] Device certificate + * @param isClone [IN] Indicates whether deep copy is required. The options are as follows: true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Load the device certificate from the file. + * + * @param config [OUT] TLS link configuration + * @param file [IN] File name + * @param type [IN] File format + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_LoadCertFile(HITLS_Config *config, const char *file, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Read the device certificate from the buffer. + * + * @param config [OUT] TLS link configuration + * @param buf [IN] Certificate data + * @param bufLen [IN] Data length + * @param format [IN] Data format + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_LoadCertBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Obtain the device certificate in use. + * + * @attention The user cannot release the memory. + * @param config [IN] TLS link configuration + * @retval Device certificate + */ +HITLS_CERT_X509 *HITLS_CFG_GetCertificate(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Add a device certificate. Only one certificate can be added for each type. + * + * @param ctx [OUT] TLS link object + * @param cert [IN] Device certificate + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetCertificate(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Use a file to set the device certificate. + * + * @param ctx [IN/OUT] TLS connection handle + * @param file [IN] File name + * @param format [IN] Data format + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_LoadCertFile(HITLS_Ctx *ctx, const char *file, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Read the device certificate from the buffer. + * + * @param ctx [OUT] TLS link object + * @param buf [IN] Certificate data + * @param bufLen [IN] Data length + * @param format [IN] Data format + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_LoadCertBuffer(HITLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Obtain the local certificate. + * + * Returns the most recently added certificate if it is called before the certificate is selected. + * If no certificate is added, NULL is returned. + * It returns the certificate selected during the handshake if a certificate selection occurs, or NULL + * if no certificate is selected (e.g. on a client that does not use a client certificate). + * + * @attention: Shallow copy, can be used only during the ctx life cycle, and the caller + * must not release the returned pointer. + * @param ctx [IN] TLS link object + * @retval Device certificate + */ +HITLS_CERT_X509 *HITLS_GetCertificate(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Obtain the peer certificate. + * + * @attention: Certificate reference increments by one. + * @param ctx [IN] hitls Context + * @retval Peer certificate + */ +HITLS_CERT_X509 *HITLS_GetPeerCertificate(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Add the private key of the device certificate. + * Only one private key can be added for each type of certificate. + * + * @param config [OUT] TLS link configuration + * @param privateKey [IN] Certificate private key + * @param isClone [IN] Indicates whether deep copy is required. The options are as follows: true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Load the private key of the device certificate from the file. + * + * @param config [OUT] TLS link configuration + * @param file [IN] File name + * @param format [IN] Data format + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_LoadKeyFile(HITLS_Config *config, const char *file, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Read the private key of the device certificate from the buffer. + * + * @param config [OUT] TLS link configuration + * @param buf [IN] Private key data + * @param bufLen [IN] Data length + * @param format [IN] Data format + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_LoadKeyBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Obtain the private key of the certificate in use. + * + * @attention The user cannot release the memory. + * + * @param config [IN] TLS link configuration + * @retval Certificate private key + */ +HITLS_CERT_Key *HITLS_CFG_GetPrivateKey(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Check whether the configured certificate matches the private key. + * + * @param config [IN] TLS link configuration + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_CheckPrivateKey(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Add the private key of the device certificate. + * + * Only one private key can be added for each type of certificate. + * + * @param ctx [OUT] TLS link object. + * @param pkey [IN] Device private key. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetPrivateKey(HITLS_Ctx *ctx, HITLS_CERT_Key *key, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Use the file to set the device private key. + * + * @param ctx [IN/OUT] TLS connection handle + * @param file [IN] File name. + * @param type [IN] Parsing type. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_LoadKeyFile(HITLS_Ctx *ctx, const char *file, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Read the private key of the device certificate from the buffer. + * + * @param ctx [OUT] TLS link object. + * @param buf [IN] Private key data. + * @param bufLen [IN] Data length. + * @param format [IN] Data format. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_LoadKeyBuffer(HITLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert + * @brief Obtain the private key of the certificate in use. + * + * @attention The user cannot release the memory. + * + * @param ctx [IN] TLS link object + * @retval Certificate private key + */ +HITLS_CERT_Key *HITLS_GetPrivateKey(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Check whether the configured certificate matches the private key. + * + * @param ctx [IN] TLS link object + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CheckPrivateKey(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Add the certificate to the certificate chain that is being used by the current config. + * + * @param config [IN] TLS link configuration + * @param cert [IN] Certificate to be added + * @param isClone [IN] Indicates whether deep copy is required. The options are true and false. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_AddChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); + +/** + * @ingroup hitls_cert + * @brief Add the certificate to the certificate store that is being used by the current config. + * + * @param config [IN] TLS link configuration + * @param cert [IN] Certificate to be added + * @param storeType [IN] Indicates which store to add cert. + * @param isClone [IN] Indicates whether deep copy is required. The options are true and false. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_AddCertToStore(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_StoreType storeType, + bool isClone); + +/** + * @ingroup hitls_cert + * @brief Obtain the certificate chain that is being used by the current config. + * + * @param config [IN] TLS link configuration + * @retval The certificate chain that is currently in use + */ +HITLS_CERT_Chain *HITLS_CFG_GetChainCerts(HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Clear the certificate chain associated with the current certificate. + * + * @param config [IN] TLS link configuration + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_ClearChainCerts(HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Clear the certificate in the current certificate. + * + * @param ctx [IN] hitls context + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_ClearChainCerts(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Release all loaded certificates and private keys. + * + * @param config [IN] TLS link configuration + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_RemoveCertAndKey(HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Release all loaded certificates and private keys. + * + * @param ctx [IN] TLS link object + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_RemoveCertAndKey(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Certificate verification callback + * + * @attention This callback function must be compatible with OpenSSL and has the same logic as OpenSSL. + * @param isPreverifyOk [IN] Indicates whether the relevant certificate has passed the verification + * (isPreverifyOk=1) or failed (isPreverifyOk=0) + * @param storeCtx [IN] Cert store context + * @retval 1 indicates success. Other values indicate failure. + */ +typedef int (*HITLS_VerifyCb)(int32_t isPreverifyOk, HITLS_CERT_StoreCtx *storeCtx); + +/** + * @ingroup hitls_cert + * @brief Set the certificate verification callback function, cb can be NULL. + * + * @param config [OUT] TLS link configuration + * @param callback [IN] Certificate verification callback function + */ +int32_t HITLS_CFG_SetVerifyCb(HITLS_Config *config, HITLS_VerifyCb callback); + +/** + * @ingroup hitls_cert + * @brief Obtain the certificate verification callback function. + * + * @param config [OUT] TLS link configuration + * @param callback [IN] Certificate verification callback function + */ +HITLS_VerifyCb HITLS_CFG_GetVerifyCb(const HITLS_Config *config); + +/** + * @ingroup hitls_cert + * @brief Set the certificate verification callback function, cb can be NULL. + * + * @param ctx [OUT] TLS link object + * @param callback [IN] Certificate verification callback function + */ +int32_t HITLS_SetVerifyCb(HITLS_Ctx *ctx, HITLS_VerifyCb callback); + +/** + * @ingroup hitls_cert + * @brief Obtain the certificate verification callback function. + * + * @param ctx [IN] TLS link object + * @retval Certificate verification callback function + */ +HITLS_VerifyCb HITLS_GetVerifyCb(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Set the peer certificate verification result of the current context. + * + * @param ctx [IN] TLS connection handle + * @param verifyResult [IN] Peer certificate verification result + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetVerifyResult(HITLS_Ctx *ctx, HITLS_ERROR verifyResult); + +/** + * @ingroup hitls_cert + * @brief Return the peer certificate verification result of the current context. + * + * @param ctx [IN] TLS connection handle + * @param verifyResult [OUT] Peer certificate verification result + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_GetVerifyResult(const HITLS_Ctx *ctx, HITLS_ERROR *verifyResult); + +/** + * @ingroup hitls_cert + * @brief Obtain the peer certificate chain. + * + * @param ctx [OUT] TLS connection handle + * @retval Peer certificate chain + */ +HITLS_CERT_Chain *HITLS_GetPeerCertChain(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Obtain the trusted CA list of the peer end. + * + * @param ctx [OUT] TLS connection handle + * @retval Peer CA list + */ +HITLS_TrustedCAList *HITLS_GetClientCAList(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_cert + * @brief Add a certificate to the attached certificate chain. + * + * @param config [OUT] Config handle + * @param cert [IN] X509 certificate + * @retval 0 indicates success. Other values indicate failure. + */ +int32_t HITLS_CFG_AddExtraChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert); + +/** + * @ingroup hitls_cert + * @brief Obtain the attached certificate chain. + * + * @param config [IN] Config handle + * @retval Attach the certificate chain. + */ +HITLS_CERT_Chain *HITLS_CFG_GetExtraChainCerts(HITLS_Config *config); + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_CERT_H */ \ No newline at end of file diff --git a/include/tls/hitls_cert_init.h b/include/tls/hitls_cert_init.h new file mode 100644 index 00000000..6b667286 --- /dev/null +++ b/include/tls/hitls_cert_init.h @@ -0,0 +1,53 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + /** + * @defgroup hitls_cert_init + * @ingroup hitls + * @brief TLS certificate abstraction layer initialization + */ + +#ifndef HITLS_CERT_INIT_H +#define HITLS_CERT_INIT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_cert_init + * @brief Certificate initialization interface, default use the HITLS X509 interface. + * + * @attention If HITLS X509 not be used, do not need to call this interface. + * @param NA + * @retval void + */ +int32_t HITLS_CertMethodInit(void); + +/** + * @ingroup hitls_cert_init + * @brief Deinitialize the certificate, set the certificate registration interface to NULL. + * + * @param NA + * @retval void + */ +void HITLS_CertMethodDeinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_CRYPT_CERT_H */ diff --git a/include/tls/hitls_cert_reg.h b/include/tls/hitls_cert_reg.h new file mode 100644 index 00000000..faef3caa --- /dev/null +++ b/include/tls/hitls_cert_reg.h @@ -0,0 +1,468 @@ +/* + * 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 hitls_cert_reg + * @ingroup hitls + * @brief Certificate related interfaces to be registered + */ + +#ifndef HITLS_CERT_REG_H +#define HITLS_CERT_REG_H + +#include +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_cert_reg + * @brief Create a certificate store + * + * @param void + * + * @retval Certificate store + */ +typedef HITLS_CERT_Store *(*CERT_StoreNewCallBack)(void); + +/** + * @ingroup hitls_cert_reg + * @brief Duplicate the certificate store. + * + * @param store [IN] Certificate store. + * + * @retval New certificate store. + */ +typedef HITLS_CERT_Store *(*CERT_StoreDupCallBack)(HITLS_CERT_Store *store); + +/** + * @ingroup hitls_cert_reg + * @brief Release the certificate store. + * + * @param store [IN] Certificate store. + * + * @retval void + */ +typedef void (*CERT_StoreFreeCallBack)(HITLS_CERT_Store *store); + +/** + * @ingroup hitls_cert_reg + * @brief ctrl interface + * + * @param config [IN] TLS link configuration. + * @param store [IN] Certificate store. + * @param cmd [IN] Ctrl option. + * @param input [IN] Input. + * @param output [IN] Output. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_StoreCtrlCallBack)(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_CtrlCmd cmd, + void *input, void *output); + +/** + * @ingroup hitls_cert_reg + * @brief Create a certificate chain based on the device certificate in use. + * + * @attention If the function is successful, the certificate in the certificate chain is managed by the HiTLS, + * and the user does not need to release the memory. Otherwise, the certificate chain is an empty pointer + * array. + * @param config [IN] TLS link configuration + * @param store [IN] Certificate store + * @param cert [IN] Device certificate + * @param certList [OUT] Certificate chain, which is a pointer array. Each element indicates a certificate. + * The first element is the device certificate. + * @param num [IN/OUT] IN: maximum length of the certificate chain OUT: length of the certificate chain + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_BuildCertChainCallBack)(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_X509 *cert, + HITLS_CERT_X509 **certList, uint32_t *num); + +/** + * @ingroup hitls_cert_reg + * @brief Verify the certificate chain + * + * @param ctx [IN] TLS link object + * @param store [IN] Certificate store. + * @param certList [IN] Certificate chain, a pointer array, each element indicates a certificate. + * The first element indicates the device certificate. + * @param num [IN] Certificate chain length. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_VerifyCertChainCallBack)(HITLS_Ctx *ctx, HITLS_CERT_Store *store, + HITLS_CERT_X509 **certList, uint32_t num); + +/** + * @ingroup hitls_cert_reg + * @brief Encode the certificate in ASN.1 DER format. + * + * @param ctx [IN] TLS link object. + * @param cert [IN] Certificate. + * @param buf [OUT] Certificate encoding data. + * @param len [IN] Maximum encoding length. + * @param usedLen [OUT] Actual encoding length. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_CertEncodeCallBack)(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t len, + uint32_t *usedLen); + +/** + * @ingroup hitls_cert_reg + * @brief Read the certificate. + * + * @attention If the data is loaded to config, config points to the TLS configuration. + * If the data is loaded to the TLS object, the config command is used only for a single link. + * + * @param config [IN] TLS link configuration, which can be used to obtain the passwd callback. + * @param buf [IN] Certificate data. + * @param len [IN] Certificate data length. + * @param type [IN] Parsing type. + * @param format [IN] Data format. + * + * @retval Certificate + */ +typedef HITLS_CERT_X509 *(*CERT_CertParseCallBack)(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert_reg + * @brief Duplicate the certificate. + * + * @param cert [IN] Certificate + * + * @retval New certificate + */ +typedef HITLS_CERT_X509 *(*CERT_CertDupCallBack)(HITLS_CERT_X509 *cert); + +/** + * @ingroup hitls_cert_reg + * @brief Certificate reference counting plus one. + * + * @param cert [IN] Certificate + * + * @retval certificate + */ +typedef HITLS_CERT_X509 *(*CERT_CertRefCallBack)(HITLS_CERT_X509 *cert); + +/** + * @ingroup hitls_cert_reg + * @brief Release the certificate. + * + * @param cert [IN] Certificate + * + * @retval void + */ +typedef void (*CERT_CertFreeCallBack)(HITLS_CERT_X509 *cert); + +/** + * @ingroup hitls_cert_reg + * @brief Ctrl interface + * + * @param config [IN] TLS link configuration + * @param cert [IN] Certificate + * @param cmd [IN] Ctrl option + * @param input [IN] Input + * @param output [IN] Output + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_CertCtrlCallBack)(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd cmd, + void *input, void *output); + +/** + * @ingroup hitls_cert_reg + * @brief Read the certificate key. + * @attention If the data is loaded to config, config points to the TLS configuration. + * If the data is loaded to the TLS object, the config command applies only to a single link. + * + * @param config [IN] LTS link configuration, which can be used to obtain the passwd callback. + * @param buf [IN] Private key data + * @param len [IN] Data length + * @param type [IN] Parsing type + * @param format [IN] Data format + * + * @retval Certificate key + */ +typedef HITLS_CERT_Key *(*CERT_KeyParseCallBack)(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format); + +/** + * @ingroup hitls_cert_reg + * @brief Duplicate the certificate key. + * + * @param key [IN] Certificate key + * + * @retval New certificate key + */ +typedef HITLS_CERT_Key *(*CERT_KeyDupCallBack)(HITLS_CERT_Key *key); + +/** + * @ingroup hitls_cert_reg + * @brief Release the certificate key. + * + * @param key [IN] Certificate key + * + * @retval void + */ +typedef void (*CERT_KeyFreeCallBack)(HITLS_CERT_Key *key); + +/** + * @ingroup hitls_cert_reg + * @brief Ctrl interface + * + * @param config [IN] TLS link configuration. + * @param key [IN] Certificate key. + * @param cmd [IN] Ctrl option. + * @param input [IN] Input. + * @param output [IN] Output. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_KeyCtrlCallBack)(HITLS_Config *config, HITLS_CERT_Key *key, HITLS_CERT_CtrlCmd cmd, + void *input, void *output); + +/** + * @ingroup hitls_cert_reg + * @brief Signature + * + * @param ctx [IN] TLS link object + * @param key [IN] Certificate private key + * @param signAlgo [IN] Signature algorithm + * @param hashAlgo [IN] Hash algorithm + * @param data [IN] Data to be signed + * @param dataLen [IN] Data length + * @param sign [OUT] Signature + * @param signLen [IN/OUT] IN: maximum signature length OUT: actual signature length + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_CreateSignCallBack)(HITLS_Ctx *ctx, HITLS_CERT_Key *key, HITLS_SignAlgo signAlgo, + HITLS_HashAlgo hashAlgo, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen); + +/** + * @ingroup hitls_cert_reg + * @brief Signature verification + * + * @param ctx [IN] TLS link object + * @param key [IN] Certificate public key + * @param signAlgo [IN] Signature algorithm + * @param hashAlgo [IN] Hash algorithm + * @param data [IN] Data to be signed + * @param dataLen [IN] Data length + * @param sign [IN] Signature + * @param signLen [IN] Signature length + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_VerifySignCallBack)(HITLS_Ctx *ctx, HITLS_CERT_Key *key, HITLS_SignAlgo signAlgo, + HITLS_HashAlgo hashAlgo, const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen); + +/** + * @ingroup hitls_cert_reg + * @brief Encrypted by the certificate public key. + * + * @param ctx [IN] TLS link object. + * @param key [IN] Certificate public key. + * @param in [IN] Plaintext. + * @param inLen [IN] Plaintext length. + * @param out [OUT] Ciphertext. + * @param outLen [IN/OUT] IN: maximum ciphertext length OUT: actual ciphertext length. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_EncryptCallBack)(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_cert_reg + * @brief Use the certificate private key to decrypt the data. + * + * @param ctx [IN] TLS link object. + * @param key [IN] Certificate private key. + * @param in [IN] Ciphertext. + * @param inLen [IN] Ciphertext length. + * @param out [OUT] Plaintext. + * @param outLen [IN/OUT] IN: maximum plaintext length OUT: actual plaintext length. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_DecryptCallBack)(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_cert_reg + * @brief Check whether the private key matches the certificate. + * + * @param config [IN] TLS link configuration. + * @param cert [IN] Certificate. + * @param key [IN] Private key. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_CheckPrivateKeyCallBack)(const HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_Key *key); + +/** + * @ingroup hitls_cert_reg + * @brief Callback for converting the underlying key of the hitls to the upper layer user (adaptation layer) + * + * @param srcKey [IN] Key type used by the HiTLS TLS layer. + * @param desKey [OUT] Key type used by upper layer users. + */ +typedef int32_t (*CERT_KeyToUserKeyCallBack)(HITLS_CERT_Key *srcKey, HITLS_CERT_USER_Key **desKey); + +/** + * @ingroup hitls_cert_reg + * @brief Callback for converting the key of the upper layer user (adaptation layer) to the key of the + * bottom layer hitls. + * + * @param srcKey [IN] Key type used by upper-layer users. + * @param desKey [OUT] Key type used by the HiTLS TLS layer. + * + * @retval HITLS_SUCCESS indicates success. Other values are considered as failure. + */ +typedef int32_t (*CERT_KeyFormUserKeyCallBack)(HITLS_CERT_USER_Key *srcKey, HITLS_CERT_Key **desKey); + +/** + * @ingroup hitls_cert_reg + * @brief Duplicate the certificate key. + * + * @param key [IN] Certificate key + * + * @retval New certificate key. + */ +typedef HITLS_CERT_USER_Key *(*CERT_UserKeyDupCallBack)(HITLS_CERT_USER_Key *key); + +/** + * @ingroup hitls_cert_reg + * @brief Callback for releasing the key of the upper layer user (adaptation layer). + * + * @param userKey [in] Key type used by upper layer users. + * + * @retval void + */ +typedef void (*CERT_UserKeyFreeCallBack)(HITLS_CERT_USER_Key *userKey); + +typedef struct { + CERT_StoreNewCallBack certStoreNew; /**< REQUIRED, Creating a certificate store. */ + CERT_StoreDupCallBack certStoreDup; /**< REQUIRED, duplicate certificate store. */ + CERT_StoreFreeCallBack certStoreFree; /**< REQUIRED, release the certificate store. */ + CERT_StoreCtrlCallBack certStoreCtrl; /**< REQUIRED, certificate interface store ctrl. */ + CERT_BuildCertChainCallBack buildCertChain; /**< REQUIRED, construct a certificate chain. */ + CERT_VerifyCertChainCallBack verifyCertChain; /**< REQUIRED, verify certificate chain. */ + + CERT_CertEncodeCallBack certEncode; /**< REQUIRED, certificate encode. */ + CERT_CertParseCallBack certParse; /**< REQUIRED, certificate decoding. */ + CERT_CertDupCallBack certDup; /**< REQUIRED, duplicate the certificate. */ + CERT_CertRefCallBack certRef; /**< REQUIRED, Certificate reference counting plus one. */ + CERT_CertFreeCallBack certFree; /**< REQUIRED, release certificate. */ + CERT_CertCtrlCallBack certCtrl; /**< REQUIRED, certificate interface ctrl. */ + + CERT_KeyParseCallBack keyParse; /**< REQUIRED, loading key. */ + CERT_KeyDupCallBack keyDup; /**< REQUIRED, duplicate key. */ + CERT_KeyFreeCallBack keyFree; /**< REQUIRED, Release the key. */ + CERT_KeyCtrlCallBack keyCtrl; /**< REQUIRED, key ctrl interface. */ + CERT_CreateSignCallBack createSign; /**< REQUIRED, signature. */ + CERT_VerifySignCallBack verifySign; /**< REQUIRED, verification. */ + CERT_EncryptCallBack encrypt; /**< OPTIONAL, RSA key exchange REQUIRED, RSA encryption. */ + CERT_DecryptCallBack decrypt; /**< OPTIONAL, RSA key exchange REQUIRED, RSA decryption. */ + + CERT_CheckPrivateKeyCallBack checkPrivateKey; /**< REQUIRED, Check whether the certificate matches the key. */ +} HITLS_CERT_MgrMethod; + +typedef struct { + CERT_KeyToUserKeyCallBack keyToUserKey; /**< converts the underlying key of the HiTLS to the + upper layer user (adaptation layer) for use */ + CERT_KeyFormUserKeyCallBack keyFormUserKey; /**< upper layer user (adaptation layer) key + to obtain the bottom-layer key of the HiTLS */ + CERT_UserKeyFreeCallBack userKeyFree; /**< upper-layer user (adaptation layer) key release*/ + CERT_UserKeyDupCallBack userKeyDup; /**< upper-layer user (adaptation layer) key copy */ +} HITLS_CERT_UserKeyMgrMethod; + +/** + * @ingroup hitls_cert_reg + * @brief Callback function related to certificate registration + * + * @param method [IN] Callback function + * + * @retval HITLS_SUCCESS, succeeded. + * @retval HITLS_NULL_INPUT, the callback function is NULL. + */ +int32_t HITLS_CERT_RegisterMgrMethod(HITLS_CERT_MgrMethod *method); + +/** + * @ingroup hitls_cert_reg + * @brief Certificate deregistration callback function + * + * @param method [IN] Callback function + * + * @retval + */ +void HITLS_CERT_DeinitMgrMethod(void); + +/** + * @ingroup hitls_cert_reg + * @brief Callback function related to register the certificate UserKey. + * Before calling this API, ensure that the HITLS_CERT_RegisterMgrMethod is successfully registered. + * + * @param method [IN] Callback function + * + * @retval HITLS_SUCCESS, succeeded. + * @retval HITLS_NULL_INPUT, the callback function is NULL. + */ +int32_t HITLS_CERT_RegisterUserKeyMgrMethod(HITLS_CERT_UserKeyMgrMethod *method); + +/** + * @ingroup hitls_cert_reg + * @brief Callback functions related to the deregistration certificate UserKey + * + * @param method [IN] Callback function + * + * @retval + */ +void HITLS_CERT_DeinitUserKeyMgrMethod(void); + +/** + * @ingroup hitls_cert_reg + * @brief Register the private key with the config file and certificate matching Check Interface. + * + * @param config [IN/OUT] Config context + * @param checkPrivateKey API registration + * @retval HITLS_SUCCESS. + * @retval For other error codes, see hitls_error.h. +*/ +int32_t HITLS_CFG_SetCheckPriKeyCb(HITLS_Config *config, CERT_CheckPrivateKeyCallBack checkPrivateKey); + +/** + * @ingroup hitls_cert_reg + * @brief Interface for obtaining the registered private key and certificate matching check + * + * @param config [IN] Config context + * + * @retval The interface for checking whether the registered private key matches the certificate is returned. + * If the registered private key does not match the certificate, NULL is returned. + */ +CERT_CheckPrivateKeyCallBack HITLS_CFG_GetCheckPriKeyCb(HITLS_Config *config); + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_CERT_REG_H */ diff --git a/include/tls/hitls_cert_type.h b/include/tls/hitls_cert_type.h new file mode 100644 index 00000000..0fcfdf71 --- /dev/null +++ b/include/tls/hitls_cert_type.h @@ -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. + */ + +/** + * @defgroup hitls_cert_type + * @ingroup hitls + * @brief Structures related to a certificate + */ + +#ifndef HITLS_CERT_TYPE_H +#define HITLS_CERT_TYPE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_cert_type + * @brief Describes the x509 certificate + */ +typedef void HITLS_CERT_X509; + +/** + * @ingroup hitls_cert_type + * @brief Describes the certificate key + */ +typedef void HITLS_CERT_Key; + +/** + * @ingroup hitls_cert_type + * @brief Describes the user key type + */ +typedef void HITLS_CERT_USER_Key; + +/** + * @ingroup hitls_cert_type + * @brief Describes the certificate + */ +typedef void HITLS_CERT_Store; + +/** + * @ingroup hitls_cert_type + * @brief Describes the certificate + */ +typedef void HITLS_CERT_StoreCtx; + +/** + * @ingroup hitls_cert_type + * @brief Describes the list of trusted CAs + */ +typedef struct BslList HITLS_TrustedCAList; + +/** + * @ingroup hitls_cert_type + * @brief Describes the certificate chain + */ +typedef struct BslList HITLS_CERT_Chain; + +/** + * @ingroup hitls_cert_type + * @brief ctrl option + */ +typedef enum { + CERT_STORE_CTRL_SET_VERIFY_DEPTH, /**< Set the certificate verification depth. */ + CERT_STORE_CTRL_DEEP_COPY_ADD_CERT_LIST, /**< Add ca and chain certificate to store */ + CERT_STORE_CTRL_SHALLOW_COPY_ADD_CERT_LIST, + + CERT_CTRL_GET_ENCODE_LEN, /**< Obtain the length of the certificate code. */ + CERT_CTRL_GET_PUB_KEY, /**< Obtaining the Certificate Public Key (Release Required). */ + CERT_CTRL_GET_SIGN_ALGO, /**< Obtain the certificate signature algorithm. */ + + CERT_KEY_CTRL_GET_SIGN_LEN, /**< Obtain the signature length. */ + CERT_KEY_CTRL_GET_TYPE, /**< Obtaining the Key Type. */ + CERT_KEY_CTRL_GET_CURVE_NAME, /**< Obtain the elliptic curve ID. */ + CERT_KEY_CTRL_GET_POINT_FORMAT, /**< Obtains the format of the EC point. */ + CERT_KEY_CTRL_GET_SECBITS, /**< Obtain the security bits. */ + CERT_KEY_CTRL_IS_KEYENC_USAGE, /**< Is the encryption certificate permission. */ + CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE, /**< Is it digital signature permission. */ + CERT_KEY_CTRL_IS_KEY_CERT_SIGN_USAGE, /**< Is the certificate issuing permission. */ + CERT_KEY_CTRL_IS_KEY_AGREEMENT_USAGE, /**< Is it the certificate verification permission. */ + + CERT_CTRL_BUTT, +} HITLS_CERT_CtrlCmd; + +/** + * @ingroup hitls_cert_type + * @brief Read data format + */ +typedef enum { + TLS_PARSE_TYPE_FILE, /**< Parse file */ + TLS_PARSE_TYPE_BUFF, /**< Parse buffer */ + TLS_PARSE_TYPE_BUTT, +} HITLS_ParseType; + +/** + * @ingroup hitls_cert_type + * @brief Read data format + */ +typedef enum { + TLS_PARSE_FORMAT_PEM, /**< PEM format */ + TLS_PARSE_FORMAT_ASN1, /**< ASN1 format */ + TLS_PARSE_FORMAT_PFX_COM, /**< PFX COM format */ + TLS_PARSE_FORMAT_PKCS12, /**< PKCS12 format */ + TLS_PARSE_FORMAT_BUTT, +} HITLS_ParseFormat; + +/** + * @ingroup hitls_cert_type + * @brief cert store type + */ +typedef enum { + TLS_CERT_STORE_TYPE_DEFAULT, /**< Default CA store */ + TLS_CERT_STORE_TYPE_VERIFY, /**< Verifies the store, which is used to verify the certificate chain */ + TLS_CERT_STORE_TYPE_CHAIN, /**< Certificate chain store, used to assemble the certificate chain */ + TLS_CERT_STORE_TYPE_BUTT, +} HITLS_CERT_StoreType; + +/** + * @ingroup hitls_cert_type + * @brief Certificate Public Key Type + */ +typedef enum { + TLS_CERT_KEY_TYPE_RSA, + TLS_CERT_KEY_TYPE_RSA_PSS, + TLS_CERT_KEY_TYPE_DSA, + TLS_CERT_KEY_TYPE_ECDSA, + TLS_CERT_KEY_TYPE_ED25519, +#ifndef HITLS_NO_TLCP11 + TLS_CERT_KEY_TYPE_SM2 = 9, /**< 9 is sign type, 10 is enc type */ + TLS_CERT_KEY_TYPE_ENC_SM2 = 10, + TLS_CERT_KEY_TYPE_NUM = 11, +#else + TLS_CERT_KEY_TYPE_NUM = 9, +#endif + TLS_CERT_KEY_TYPE_UNKNOWN = 255 +} HITLS_CERT_KeyType; + +/** + * @ingroup hitls_cert_type + * @brief Certificate Signature Algorithm Enumeration + */ +typedef enum { + /* Reservation algorithm. */ + CERT_SIG_SCHEME_RSA_PKCS1_SHA1 = 0x0201, + CERT_SIG_SCHEME_DSA_SHA1 = 0X0202, + CERT_SIG_SCHEME_ECDSA_SHA1 = 0x0203, + CERT_SIG_SCHEME_ECDSA_SHA224 = 0x0303, + /* RSASSA-PKCS1-v1_5 algorithms */ + CERT_SIG_SCHEME_RSA_PKCS1_SHA224 = 0x0301, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256 = 0x0401, + CERT_SIG_SCHEME_RSA_PKCS1_SHA384 = 0x0501, + CERT_SIG_SCHEME_RSA_PKCS1_SHA512 = 0x0601, + /* DSA algorithms */ + CERT_SIG_SCHEME_DSA_SHA224 = 0x0302, + CERT_SIG_SCHEME_DSA_SHA256 = 0X0402, /**< signature algorithm: DSA_SHA256 */ + CERT_SIG_SCHEME_DSA_SHA384 = 0X0502, /**< signature algorithm: DSA_SHA384 */ + CERT_SIG_SCHEME_DSA_SHA512 = 0X0602, /**< signature algorithm: DSA_SHA512 */ + /* ECDSA algorithms */ + CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256 = 0x0403, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384 = 0x0503, + CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512 = 0x0603, + /* GM sig algorithms */ + CERT_SIG_SCHEME_SM2_SM3 = 0x0708, + /* RSASSA-PSS algorithms with public key OID rsaEncryption */ + CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256 = 0x0804, + CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384 = 0x0805, + CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512 = 0x0806, + /* EdDSA algorithms */ + CERT_SIG_SCHEME_ED25519 = 0x0807, + /* RSASSA-PSS algorithms with public key OID RSASSA-PSS */ + CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256 = 0x0809, + CERT_SIG_SCHEME_RSA_PSS_PSS_SHA384 = 0x080a, + CERT_SIG_SCHEME_RSA_PSS_PSS_SHA512 = 0x080b, + CERT_SIG_SCHEME_UNKNOWN = 0xffff +} HITLS_SignHashAlgo; + +/** + * @ingroup hitls_cert_type + * @brief Trusted CA ID Type + */ +typedef enum { + HITLS_TRUSTED_CA_PRE_AGREED = 0, /**< preset CA */ + HITLS_TRUSTED_CA_KEY_SHA1 = 1, /**< Trusted CA key Hash */ + HITLS_TRUSTED_CA_X509_NAME = 2, /**< Trusted CA x509 Certificate Name */ + HITLS_TRUSTED_CA_CERT_SHA1 = 3, /**< Trusted CA Certificate Hash */ + HITLS_TRUSTED_CA_UNKNOWN = 255 +} HITLS_TrustedCAType; + +/** + * @ingroup hitls_cert_type + * @brief Node structure used to describe the trusted CA certificate list + */ +typedef struct HitlsTrustedCANode { + HITLS_TrustedCAType caType; /**< Trusted CA type */ + uint8_t *data; /**< Trusted CA data */ + uint32_t dataSize; /**< Trusted CA data length */ +} HITLS_TrustedCANode; + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_CERT_TYPE_H */ diff --git a/include/tls/hitls_config.h b/include/tls/hitls_config.h new file mode 100644 index 00000000..f94a322c --- /dev/null +++ b/include/tls/hitls_config.h @@ -0,0 +1,1240 @@ +/* + * 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 hitls_config + * @ingroup hitls + * @brief TLS parameter configuration + */ + +#ifndef HITLS_CONFIG_H +#define HITLS_CONFIG_H + +#include +#include +#include "hitls_type.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @ingroup hitls_config +* @brief TLCP 1.1 version +*/ +#define HITLS_VERSION_TLCP11 0x0101u + +/** + * @ingroup hitls_config + * @brief TLS any version +*/ +#define HITLS_TLS_ANY_VERSION 0x03ffu + +/** + * @ingroup hitls_config + * @brief SSL3.0 version number +*/ +#define HITLS_VERSION_SSL30 0x0300u + +/** + * @ingroup hitls_config + * @brief TLS1.0 version number +*/ +#define HITLS_VERSION_TLS10 0x0301u + +/** + * @ingroup hitls_config + * @brief TLS1.1 version number +*/ +#define HITLS_VERSION_TLS11 0x0302u + +/** + * @ingroup hitls_config + * @brief TLS1.2 version + */ +#define HITLS_VERSION_TLS12 0x0303u + +/** + * @ingroup config + * @brief TLS 1.3 version + */ +#define HITLS_VERSION_TLS13 0x0304u + +/** + * @ingroup config + * @brief Prefix of SSL 3.0 or later + */ +#define HITLS_VERSION_TLS_MAJOR 0x03u + +/** + * @ingroup hitls_config + * @brief DTLS any version +*/ +#define HITLS_DTLS_ANY_VERSION 0xfe00u + +/** + * @ingroup hitls_config + * @brief DTLS 1.2 version + */ +#define HITLS_VERSION_DTLS12 0xfefdu + +/** + * @ingroup hitls_config + * @brief Maximum size of the configuration data + */ +#define HITLS_CFG_MAX_SIZE 1024 + +/** + * @ingroup hitls_config + * @brief Configure the maximum size of the TLS1_3 cipher suite + */ +#define TLS13_CIPHERSUITES_MAX_LEN 80 + +/** + * @ingroup hitls_config + * @brief enumerate ciphersuites supported by HITLS with IANA coding + * */ +typedef enum { + HITLS_RSA_WITH_AES_128_CBC_SHA = 0x002F, + HITLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032, + HITLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033, + HITLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034, + HITLS_RSA_WITH_AES_256_CBC_SHA = 0x0035, + HITLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038, + HITLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039, + HITLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A, + HITLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C, + HITLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D, + HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040, + HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067, + HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A, + HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B, + HITLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C, + HITLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D, + HITLS_PSK_WITH_AES_128_CBC_SHA = 0x008C, + HITLS_PSK_WITH_AES_256_CBC_SHA = 0x008D, + HITLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090, + HITLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091, + HITLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094, + HITLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095, + HITLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C, + HITLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F, + HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3, + HITLS_DH_ANON_WITH_AES_128_GCM_SHA256 = 0x00A6, + HITLS_DH_ANON_WITH_AES_256_GCM_SHA384 = 0x00A7, + HITLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8, + HITLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9, + HITLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA, + HITLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB, + HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC, + HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD, + HITLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE, + HITLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF, + HITLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2, + HITLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3, + HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6, + HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7, + HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009, + HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A, + HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013, + HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014, + HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA = 0xC018, + HITLS_ECDH_ANON_WITH_AES_256_CBC_SHA = 0xC019, + HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023, + HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024, + HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027, + HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B, + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030, + HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035, + HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036, + HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037, + HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038, + HITLS_RSA_WITH_AES_128_CCM = 0xC09C, + HITLS_RSA_WITH_AES_256_CCM = 0xC09D, + HITLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E, + HITLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F, + HITLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0, + HITLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1, + HITLS_PSK_WITH_AES_256_CCM = 0xC0A5, + HITLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6, + HITLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7, + HITLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC, + HITLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA, + HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB, + HITLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC, + HITLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD, + HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE, + HITLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 0xD001, + HITLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 0xD002, + HITLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = 0xD005, + + /* TLS1.3 cipher suite */ + HITLS_AES_128_GCM_SHA256 = 0x1301, + HITLS_AES_256_GCM_SHA384 = 0x1302, + HITLS_CHACHA20_POLY1305_SHA256 = 0x1303, + HITLS_AES_128_CCM_SHA256 = 0x1304, + HITLS_AES_128_CCM_8_SHA256 = 0x1305, + /* TLCP 1.1 cipher suite */ + HITLS_ECDHE_SM4_CBC_SM3 = 0xE011, + HITLS_ECC_SM4_CBC_SM3 = 0xE013, +} HITLS_CipherSuite; + +/** + * @ingroup hitls_config + * @brief Create DTLS12 configuration items, including the default settings. The user can call the + * HITLS_CFG_SetXXX interface to modify the settings. + * + * @attention The default configuration is as follows: + Version number: HITLS_VERSION_DTLS12 + Algorithm suite: HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + EC point format: HITLS_POINT_FORMAT_UNCOMPRESSED + groups:secp256r1, secp384r1, secp521r1, x25519 + Extended Master Key: Not Enabled + Signature algorithm: All signature algorithms in the HITLS_SignHashAlgo table + Dual-ended check: Disabled + Allow Client No Certificate: Not Allowed + Renegotiation: Not supported + This API is a version-specific API. After the configuration context is created, + the HITLS_SetVersion, HITLS_CFG_SetVersion, HITLS_SetVersionSupport, HITLS_CFG_SetVersionSupport, + HITLS_SetMinProtoVersion, or HITLS_SetMaxProtoVersion interface cannot be used to set other supported versions. + * @retval HITLS_Config, object pointer succeeded. + * @retval NULL, failed to apply for the object. + * @see HITLS_CFG_FreeConfig + */ +HITLS_Config *HITLS_CFG_NewDTLS12Config(void); + +#ifndef HITLS_NO_TLCP11 +/** + * @ingroup hitls_config + * @brief Create TLCP configuration items, including default settings. + * + * The user can call the HITLS_CFG_SetXXX interface to modify the settings. + * + * @attention The default configuration is as follows: + Version number: HITLS_VERSION_TLCP11 + Algorithm suite: HITLS_ECDHE_SM4_CBC_SM3, HITLS_ECC_SM4_CBC_SM3 + EC point format: HITLS_POINT_FORMAT_UNCOMPRESSED + groups:sm2 + Extended Master Key: Enabled + Signature algorithm: All signature algorithms in the HITLS_SignHashAlgo table + Dual-ended check: Disabled + Allow Client No Certificate: Not Allowed + Renegotiation: Not supported + This API is a version-specific API. After the configuration context is created, + the HITLS_SetVersion, HITLS_CFG_SetVersion, HITLS_SetVersionSupport, HITLS_CFG_SetVersionSupport, + HITLS_SetMinProtoVersion, or HITLS_SetMaxProtoVersion interface cannot be used to set other supported versions. + * @retval HITLS_Config, object pointer succeeded. + * @retval NULL, object application failed. + */ +HITLS_Config *HITLS_CFG_NewTLCPConfig(void); +#endif + +/** + * @ingroup hitls_config + * @brief Create a TLS12 configuration item, including the default configuration. + * + * The user can call the HITLS_CFG_SetXXX interface to modify the configuration. + * + * @attention The default configuration is as follows: + Version number: HITLS_VERSION_TLS12 + Algorithm suite: HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + EC point format: HITLS_POINT_FORMAT_UNCOMPRESSED + groups:secp256r1, secp384r1, secp521r1, x25519 + Extended Master Key: Enabled + Signature algorithm: All signature algorithms in the HITLS_SignHashAlgo table + Dual-ended check: Disabled + Allow Client No Certificate: Not Allowed + Renegotiation: Not supported + This API is a version-specific API. After the configuration context is created, + the HITLS_SetVersion, HITLS_CFG_SetVersion, HITLS_SetVersionSupport, HITLS_CFG_SetVersionSupport, + HITLS_SetMinProtoVersion, or HITLS_SetMaxProtoVersion interface cannot be used to set other supported versions. + * @retval HITLS_Config, object pointer succeeded. + * @retval NULL, object application failed. + */ +HITLS_Config *HITLS_CFG_NewTLS12Config(void); + +/** + * @ingroup hitls_config + * @brief Creates the default TLS13 configuration. + * + * The HITLS_CFG_SetXXX interface can be used to modify the default TLS13 configuration. + * + * @attention The default configuration is as follows: + Version number: HITLS_VERSION_TLS13 + Algorithm suite: HITLS_AES_128_GCM_SHA256, HITLS_CHACHA20_POLY1305_SHA256, HITLS_AES_128_GCM_SHA256 + EC point format: HITLS_POINT_FORMAT_UNCOMPRESSED + groups:secp256r1, secp384r1, secp521r1, x25519 + Extended Master Key: Enabled + Signature algorithm: rsa, ecdsa, eddsa + Dual-ended check: Disabled + Allow Client No Certificate: Not Allowed + This API is a version-specific API. After the configuration context is created, + the HITLS_SetVersion, HITLS_CFG_SetVersion, HITLS_SetVersionSupport, + HITLS_CFG_SetVersionSupport, HITLS_SetMinProtoVersion, and HITLS_SetMaxProtoVersion + interface cannot be used to set other supported versions. + * @retval HITLS_Config, object pointer succeeded. + * @retval NULL, failed to apply for the object + */ +HITLS_Config *HITLS_CFG_NewTLS13Config(void); + +/** + * @ingroup hitls_config + * @brief Create full TLS configurations. The HITLS_CFG_SetXXX interface can be used to modify the configurations. + * + * @attention The default configuration is as follows: + Version number: HITLS_VERSION_TLS12, HITLS_VERSION_TLS13 + Algorithm suite: HITLS_AES_128_GCM_SHA256, HITLS_CHACHA20_POLY1305_SHA256, HITLS_AES_128_GCM_SHA256 + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + HITLS_DHE_RSA_WITH_AES_256_CBC_SHA, HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, HITLS_DHE_RSA_WITH_AES_128_CBC_SHA, + HITLS_RSA_WITH_AES_256_CBC_SHA, HITLS_RSA_WITH_AES_128_CBC_SHA, + EC point format: HITLS_POINT_FORMAT_UNCOMPRESSED + groups:secp256r1, secp384r1, secp521r1, x25519, brainpool256r1, brainpool384r1, brainpool521r1 + Extended Master Key: Enabled + Signature algorithm: All signature algorithms in the HITLS_SignHashAlgo table + Dual-ended check: Disabled + Allow Client No Certificate: Not Allowed + This interface is a unified configuration interface. After a configuration context is created, + it can be used with the HITLS_SetVersion, HITLS_CFG_SetVersion, HITLS_SetVersionSupport, + HITLS_CFG_SetVersionSupport, HITLS_SetMinProtoVersion, and HITLS_SetMaxProtoVersion are used together, + Set the supported version. However, only the TLS configuration item is configured in this interface. + Therefore, the DTLS version cannot be set. + * @retval HITLS_Config, object pointer succeeded. + * @retval NULL, object application failed. + */ +HITLS_Config *HITLS_CFG_NewTLSConfig(void); + +/** + * @ingroup hitls_config + * @brief Create full DTLS configurations. The HITLS_CFG_SetXXX interface can be called + * to modify the DTLS configuration. + * + * @attention The default configuration is as follows: + Version number: HITLS_VERSION_DTLS10, HITLS_VERSION_DTLS12 + Algorithm suite: HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + EC point format: HITLS_POINT_FORMAT_UNCOMPRESSED + groups:secp256r1, secp384r1, secp521r1, x25519, brainpool256r1, brainpool384r1, brainpool521r1 + Extended Master Key: Enabled + Signature algorithm: All signature algorithms in the HITLS_SignHashAlgo table + Dual-ended check: Disabled + Allow Client No Certificate: Not Allowed + This interface is a unified configuration interface. After a configuration context is created, + it can be used with the HITLS_SetVersion, HITLS_CFG_SetVersion, HITLS_SetVersionSupport, + HITLS_CFG_SetVersionSupport, HITLS_SetMinProtoVersion, and HITLS_SetMaxProtoVersion are used together, + Set the supported version. However, only the DTLS configuration item is configured in this interface. + Therefore, the TLS version cannot be set. + * @retval HITLS_Config, object pointer succeeded. + * @retval NULL, Object application failed. + */ +HITLS_Config *HITLS_CFG_NewDTLSConfig(void); + +/** + * @ingroup hitls_config + * @brief Release the config file. + * + * @param config [OUT] Config handle. + * @retval void + */ +void HITLS_CFG_FreeConfig(HITLS_Config *config); + +/** + * @ingroup hitls_config + * @brief The reference counter of config increases by 1. + * + * @param config [OUT] Config handle. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_UpRef(HITLS_Config *config); + +/** + * @ingroup hitls_config + * @brief Set the supported version number range. + * + * @param config [OUT] Config handle + * @param minVersion [IN] Minimum version number + * @param maxVersion [IN] Maximum version number + * @attention The maximum version number and minimum version number must be both TLS and DTLS. + * Currently, only DTLS 1.2. + * HITLS_CFG_NewDTLSConfig, HITLS_CFG_NewTLSConfig can be used with full configuration interfaces. + * If TLS full configuration is configured, only the TLS version can be set. + * If DTLS full configuration is configured, only the DTLS version can be set. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetVersion(HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion); + +/** + * @ingroup hitls_config + * @brief Setting the disabled version number. + * + * @param config [OUT] Config handle + * @param noversion [IN] Disabled version number. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetVersionForbid(HITLS_Config *config, uint32_t noVersion); + +/** + * @ingroup hitls_config + * @brief Set whether to support renegotiation. + * + * @param config [OUT] Config handle + * @param support [IN] Whether to support the function. The options are as follows: True: yes; False: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetRenegotiationSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Set whether to support session restoration during renegotiation.By default, session restoration is not + * supported. + * + * @param config [OUT] Config handle + * @param support [IN] Whether to support the function. The options are as follows: True: yes; False: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetResumptionOnRenegoSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Sets whether to verify the client certificate. + * Client: This setting has no impact + * Server: The certificate request will be sent. + * + * @param config [OUT] Config handle + * @param support [IN] Indicates whether the client certificate can be verified.True: yes; False: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, The config parameter is empty. + * @attention The settings on the client are invalid. Only the settings on the server take effect. + * If this parameter is not set, single-ended verification is used by default. + */ +int32_t HITLS_CFG_SetClientVerifySupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Sets whether to allow the client certificate to be empty. + * This parameter takes effect only when client certificate verification is enabled. + * Client: This setting has no impact + * Server: Check whether the certificate passes the verification when receiving an empty + * certificate from the client. The verification fails by default. + * + * @param config [OUT] Config handle + * @param support [IN] Indicates whether the authentication is successful when no client certificate is available. + true: The server still passes the verification when the certificate sent by the client is empty. + false: The server fails to pass the verification when the certificate sent by the client is empty. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, The config parameter is empty. + */ +int32_t HITLS_CFG_SetNoClientCertSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Sets whether to forcibly support extended master keys. + * + * @param config [OUT] Config handle + * @param support [IN] Indicates whether to forcibly support extended master keys. + The options are as follows: True: yes; False: no. The default value is true. + * @retval HITLS_SUCCESS. + * @retval HITLS_NULL_INPUT, config is NULL + */ +int32_t HITLS_CFG_SetExtenedMasterSecretSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Set whether the DH parameter can be automatically selected by users. + * + * If the value is true, the DH parameter is automatically selected based on the length of the + * certificate private key. If the value is false, the DH parameter needs to be set. + * + * @param config [OUT] Config handle + * @param support [IN] Whether to support the function. The options are as follows: True: yes; False: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetDhAutoSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Set the DH parameter specified by the user. + * + * @param config [OUT] Config handle + * @param dhPkey [IN] User-specified DH key. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is empty, or dhPkey is empty. + */ +int32_t HITLS_CFG_SetTmpDh(HITLS_Config *config, HITLS_CRYPT_Key *dhPkey); + +/** + * @ingroup hitls_config + * @brief Query whether renegotiation is supported. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Whether to support renegotiation + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetRenegotiationSupport(const HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Query whether the client certificate can be verified. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether to verify the client certificate. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetClientVerifySupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Query whether support there is no client certificate. This parameter takes effect + * only when the client certificate is verified. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether to support the function of not having a client certificate. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetNoClientCertSupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Query whether extended master keys are supported. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether to support the extended master key. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetExtenedMasterSecretSupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Query whether the DH parameter can be automatically selected by the user. If yes, + * the DH parameter will be automatically selected based on the length of the certificate private key. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether to support the function of automatically selecting the DH parameter. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetDhAutoSupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Setting whether to support post-handshake auth takes effect only for TLS1.3. + client: If the client supports pha, the client sends pha extensions. + Server: supports pha. After the handshake, the upper-layer interface HITLS_VerifyClientPostHandshake + initiates certificate verification. + * + * @param config [OUT] Config handle + * @param support [IN] Whether to support pha + True: pha is supported. + False: pha is not supported. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, The config parameter is empty. + * @attention Before enabling this function on the server, enable HITLS_CFG_SetClientVerifySupport. + * Otherwise, the configuration does not take effect. + */ +int32_t HITLS_CFG_SetPostHandshakeAuthSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Query whether the post-handshake AUTH function is supported. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether to support post-handshake AUTH. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetPostHandshakeAuthSupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Sets whether to support not perform dual-ended verification + * + * @param support [IN] True: yes; False: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetVerifyNoneSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Query whether not perform dual-ended verification is supported + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether not perform dual-ended verification is supported + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetVerifyNoneSupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Set whether request client certificate only once is supported + * + * @param config [OUT] TLS link configuration + * @param support [IN] True: yes; False: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetClientOnceVerifySupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_config + * @brief Query whether request client certificate only once is supported + * + * @param config [IN] Config handle + * @param isSupport [OUT] Indicates whether the client certificate can be requested only once. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetClientOnceVerifySupport(HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_config + * @brief Set the supported key suites. The sequence of the key suites affects the priority of the selected + * key suites. The key suite with the highest priority is the first. + * + * @attention This setting will automatically filter out unsupported cipher suites. + * @param config [OUT] Config handle. + * @param cipherSuites [IN] Key suite array, corresponding to the HITLS_CipherSuite enumerated value. + * @param cipherSuitesSize [IN] Key suite array length. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetCipherSuites(HITLS_Config *config, const uint16_t *cipherSuites, uint32_t cipherSuitesSize); + +/** + * @ingroup hitls_config + * @brief Clear the TLS1.3 cipher suite. + * + * @param config [IN] Config handle. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_ClearTLS13CipherSuites(HITLS_Config *config); + +/** + * @ingroup hitls_config + * @brief Set the format of the ec point. + * + * @attention Currently, this parameter can only be set to HITLS_ECPOINTFORMAT_UNCOMPRESSED. + * + * @param config [OUT] Config context. + * @param pointFormats [IN] EC point format, corresponding to the HITLS_ECPointFormat enumerated value. + * @param pointFormatsSize [IN] EC point format length + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetEcPointFormats(HITLS_Config *config, const uint8_t *pointFormats, uint32_t pointFormatsSize); + +/** + * @ingroup hitls_config + * @brief Set the group supported during key exchange. The group supported + * by HiTLS can be queried in HITLS_NamedGroup. + * + * @attention If a group is not supported, an error will be reported during configuration check. + * @param config [OUT] Config context. + * @param groups [IN] Key exchange group. Corresponds to the HITLS_NamedGroup enumerated value. + * @param groupsSize [IN] Group length + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetGroups(HITLS_Config *config, const uint16_t *groups, uint32_t groupsSize); + +/** + * @ingroup hitls_config + * @brief Set the signature algorithms supported during negotiation. The signature algorithms supported + * by the HiTLS can be queried in the HITLS_SignHashAlgo file. + * + * @attention If an unsupported signature algorithm is set, an error will be reported during configuration check. + * @param config [OUT] Config context + * @param signAlgs [IN] Signature algorithm array, that is, the enumerated value of HITLS_SignHashAlgo. + * @param signAlgsSize [IN] Signature algorithm array length + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSignature(HITLS_Config *config, const uint16_t *signAlgs, uint16_t signAlgsSize); + +/** + * @ingroup hitls_config + * @brief Add the CA indicator, which is used when the peer certificate is requested. + * + * @param config [OUT] TLS link configuration + * @param caType [IN] CA indication type + * @param data [IN] CA indication data + * @param len [IN] Data length + * @retval HITLS_SUCCESS, if successful. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_AddCAIndication(HITLS_Config *config, HITLS_TrustedCAType caType, const uint8_t *data, uint32_t len); + +/** + * @ingroup hitls_config + * @brief Obtain the CA list. + * + * @param config [OUT] TLS link configuration + * @retval CA list + */ +HITLS_TrustedCAList *HITLS_CFG_GetCAList(const HITLS_Config *config); + +/** + * @ingroup hitls_config + * @brief Set the key exchange mode, which is used by TLS1.3. + * + * @param config [OUT] TLS link configuration + * @param mode [IN] PSK key exchange mode. Currently, only TLS13_KE_MODE_PSK_ONLY and TLS13_KE_MODE_PSK_WITH_DHE + * are supported. The corresponding bit is set to 1. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetKeyExchMode(HITLS_Config *config, uint32_t mode); + +/** + * @ingroup hitls_config + * @brief Obtain the key exchange mode, which is used by TLS1.3. + * + * @param config [OUT] TLS link configuration + * @retval Key exchange mode + */ +uint32_t HITLS_CFG_GetKeyExchMode(HITLS_Config *config); + +/* If the ClientHello callback is successfully executed, the handshake continues */ +#define HITLS_CONTINUE_HANDHSAKE 1 +/* The ClientHello callback fails. Send an alert message and terminate the handshake */ +#define HITLS_ALERT_HANDSHAKE 0 + +/** + * @ingroup hitls_config + * @brief ClientHello callback prototype for the server to process the callback. + * + * @param ctx [IN] Ctx context + * @param alert [OUT] The callback that returns a failure should indicate the alert value to be sent in al. + * @param arg [IN] Product input context + * @retval HITLS_CONTINUE_HANDHSAKE: successful. Other values are considered as failure. + */ +typedef int32_t (*HITLS_ClientHelloCb)(HITLS_Ctx *ctx, int32_t *alert, void *arg); + +/** + * @ingroup hitls_config + * @brief Set the cookie verification callback on the server. + * + * @param config [OUT] Config context + * @param callback [IN] ClientHello callback + * @param arg [IN] Product input context + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetClientHelloCb(HITLS_Config *config, HITLS_ClientHelloCb callback, void *arg); + +/** + * @ingroup hitls_config + * @brief Callback function when the peer end does not support security renegotiation + * + * @attention If the user returns a failure message, the HITLS sends a handshake_failure alarm + * to the peer end and disconnects the link. If the user does not register the callback, + * the link establishment continues when the peer end does not support security renegotiation by default. + * @param ctx [IN] Ctx context + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*HITLS_NoSecRenegotiationCb)(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_config + * @brief Set the callback function when the peer end does not support security renegotiation. + * + * @param config [OUT] Config context + * @param callback [IN] Callback function when the peer end does not support security renegotiation + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetNoSecRenegotiationCb(HITLS_Config *config, HITLS_NoSecRenegotiationCb callback); + +/** + * @ingroup hitls_config + * @brief Obtaining the Minimum Supported Version Number + * + * @param config [IN] Config context + * @param minVersion [OUT] Minimum version supported + * @retval HITLS_SUCCESS is obtained successfully. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetMinVersion(const HITLS_Config *config, uint16_t *minVersion); + +/** + * @ingroup hitls_config + * @brief Obtaining the Maximum supported version number + * + * @param config [IN] Config context + * @param maxVersion [OUT] Maximum supported version + * @retval HITLS_SUCCESS is obtained successfully. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetMaxVersion(const HITLS_Config *config, uint16_t *maxVersion); + +/** + * @ingroup hitls_config + * @brief Obtain the symmetric encryption algorithm type based on the cipher suite. + * + * @param cipher[IN] Cipher suite + * @param cipherAlg [OUT] Obtained symmetric encryption algorithm type. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetCipherId(const HITLS_Cipher *cipher, HITLS_CipherAlgo *cipherAlg); + +/** + * @ingroup hitls_config + * @brief Obtain the hash algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param hashAlg [OUT] Obtained hash algorithm type. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetHashId(const HITLS_Cipher *cipher, HITLS_HashAlgo *hashAlg); + +/** + * @ingroup hitls_config + * @brief Obtain the MAC algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param macAlg [OUT] Obtained MAC algorithm type. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetMacId(const HITLS_Cipher *cipher, HITLS_MacAlgo *macAlg); + +/** + * @ingroup hitls_config + * @brief Obtain the server authorization algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param authAlg [OUT] Obtained server authorization type. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetAuthId(const HITLS_Cipher *cipher, HITLS_AuthAlgo *authAlg); + +/** + * @ingroup hitls_config + * @brief Obtain the key exchange algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param kxAlg [OUT] Obtained key exchange algorithm type. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetKeyExchId(const HITLS_Cipher *cipher, HITLS_KeyExchAlgo *kxAlg); + +/** + * @ingroup hitls_config + * @brief Obtain the cipher suite name based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @retval "(NONE)" Invalid cipher suite. + * @retval Name of the given cipher suite + */ +const uint8_t* HITLS_CFG_GetCipherSuiteName(const HITLS_Cipher *cipher); + +/** + * @ingroup hitls_config + * @brief Obtain the RFC standard name of the cipher suite based on the cipher suite. + * + * @param cipherSuite [IN] cipher suite + * + * @retval "(NONE)" Invalid cipher suite. + * @retval RFC standard name for the given cipher suite + */ +const uint8_t* HITLS_CFG_GetCipherSuiteStdName(const HITLS_Cipher *cipher); + +/** + * @ingroup hitls_config + * @brief Outputs the description of the cipher suite as a string. + * + * @param cipherSuite [IN] Cipher suite + * @param buf [OUT] Output the description. + * @param len [IN] Description length + * @retval NULL, Failed to obtain the description. + * @retval Description of the cipher suite + */ +int32_t HITLS_CFG_GetDescription(const HITLS_Cipher *cipher, uint8_t *buf, int32_t len); + +/** + * @ingroup hitls_config + * @brief Determine whether to use the AEAD algorithm based on the cipher suite information. + * + * @param cipher [IN] Cipher suite information + * @param isAead [OUT] Indicates whether to use the AEAD algorithm. + * @retval HITLS_SUCCESS, obtained successfully. + * HITLS_NULL_INPUT, the input parameter pointer is null. + */ +int32_t HITLS_CIPHER_IsAead(const HITLS_Cipher *cipher, uint8_t *isAead); + +/** + * @ingroup hitls_config + * @brief Obtain the earliest TLS version supported by the cipher suite based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param version [OUT] Obtain the earliest TLS version supported by the cipher suite. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetCipherVersion(const HITLS_Cipher *cipher, int32_t *version); + +/** + * @ingroup hitls_config + * @brief Obtain the cipher suite pointer based on the cipher suite ID. + * + * @param cipherSuite [IN] Cipher suite ID + * + * @retval HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE, Unsupported cipher suites + * @retval Pointer to the obtained cipher suite information. + */ +const HITLS_Cipher *HITLS_CFG_GetCipherByID(uint16_t cipherSuite); + +/** + * @ingroup hitls_config + * @brief Obtain the encryption ID in the cipher suite. + * + * @param cipher [IN] Cipher suite. + * @param cipherSuite [OUT] Cipher suite ID. + * + * @retval HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE, Unsupported cipher suites. + * @retval Minimum TLS version supported by the given cipher suite. + */ +int32_t HITLS_CFG_GetCipherSuite(const HITLS_Cipher *cipher, uint16_t *cipherSuite); + +/** + * @ingroup hitls_config + * @brief Obtain the supported version number. + * + * @param config [IN] Config handle + * @param version [OUT] Supported version number. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetVersionSupport(const HITLS_Config *config, uint32_t *version); + +/** + * @ingroup hitls_config + * @brief Set the supported version number. + * + * @param config [OUT] Config handle + * @param version [IN] Supported version number. + * @attention The maximum version number and minimum version number must be both TLS and DTLS. + * Currently, only DTLS 1.2 is supported. This function is used together with the full configuration interfaces, + * such as HITLS_CFG_NewDTLSConfig and HITLS_CFG_NewTLSConfig. + * If the TLS full configuration is configured, only the TLS version can be set. + * If full DTLS configuration is configured, only the DTLS version can be set. + * The versions must be consecutive. By default, the minimum and maximum versions are supported. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetVersionSupport(HITLS_Config *config, uint32_t version); + +/** + * @ingroup hitls_config + * @brief This interface is used to verify the version in the premaster secret. + * This interface takes effect on the server. The version must be earlier than 1.0, including 1.0. + * + * @param config [OUT] Config handle. + * @param needCheck [IN] Indicates whether to perform verification. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetNeedCheckPmsVersion(HITLS_Config *config, bool needCheck); + +/** + * @ingroup hitls_config + * @brief Set the quiet disconnection mode. + * + * @param config [IN] TLS link configuration + * @param mode [IN] Mode type. The value 0 indicates that the quiet disconnection mode is disabled, + * and the value 1 indicates that the quiet disconnection mode is enabled. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetQuietShutdown(HITLS_Config *config, int32_t mode); + +/** + * @ingroup hitls_config + * @brief Obtain the current quiet disconnection mode. + * + * @param config [IN] TLS link configuration + * @param mode [OUT] Current quiet disconnection mode + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_GetQuietShutdown(const HITLS_Config *config, int32_t *mode); + +/** + * @ingroup hitls_config + * @brief Set the Encrypt-Then-Mac mode. + * + * @param config [IN] TLS link configuration + * @param isEncryptThenMac [IN] Indicates whether to enable the Encrypt-Then-Mac mode. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetEncryptThenMac(HITLS_Config *config, uint32_t encryptThenMacType); + +/** + * @ingroup hitls_config + * @brief Obtain the Encrypt-Then-Mac type. + * + * @param config [IN] TLS link configuration + * @param encryptThenMacType [OUT] Current Encrypt-Then-Mac mode + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_GetEncryptThenMac(const HITLS_Config *config, uint32_t *encryptThenMacType); + +/** + * @ingroup hitls + * @brief Obtain the user data from the HiTLS Config object. + * Generally, this function is called during the callback registered with the HiTLS. + * + * @attention must be called before HITLS_Connect and HITLS_Accept. + * The life cycle of the user identifier must be longer than that of the TLS object. + * @param config [OUT] TLS connection handle. + * @param userData [IN] User identifier. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, The TLS object pointer of the input parameter is null. + */ +void *HITLS_CFG_GetConfigUserData(const HITLS_Config *config); + +/** + * @ingroup hitls + * @brief User data is stored in the HiTLS Config. The user data can be obtained + * from the callback registered with the HiTLS. + * + * @attention must be called before HITLS_Connect and HITLS_Accept. + * The life cycle of the user identifier must be longer than that of the TLS object. + * If the user data needs to be cleared, the HITLS_SetUserData(ctx, NULL) interface can be called directly. + * The Clean interface is not provided separately. + * @param config [OUT] TLS connection handle. + * @param userData [IN] User identifier. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, The TLS object pointer of the input parameter is null. + */ +int32_t HITLS_CFG_SetConfigUserData(HITLS_Config *config, void *userData); + +/** + * @ingroup hitls + * @brief UserData free callback + */ +typedef void (*HITLS_ConfigUserDataFreeCb)(void *); + +/** + * @ingroup hitls + * @brief Sets the UserData free callback + * + * @param config [OUT] TLS connection handle + * @param userData [IN] User Data + * @retval HITLS_SUCCESS + * @retval HITLS_NULL_INPUT The input pointer is null + */ +int32_t HITLS_CFG_SetConfigUserDataFreeCb(HITLS_Config *config, HITLS_ConfigUserDataFreeCb callback); + +/** + * @ingroup hitls_config + * @brief Determine whether to use DTLS. + * + * @param config [IN] TLS link configuration. + * @param isDtls [OUT] Indicates whether to use DTLS. + * @retval HITLS_SUCCESS, obtained successfully. + * HITLS_NULL_INPUT, the input parameter pointer is null. + */ +int32_t HITLS_CFG_IsDtls(const HITLS_Config *config, uint8_t *isDtls); + +/** + * @ingroup hitls_config + * @brief cipher suites are preferentially selected from the list of algorithms supported by the server. + * + * @param config [IN] TLS link configuration. + * @param isSupport [IN] Support or not. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetCipherServerPreference(HITLS_Config *config, bool isSupport); + +/** + * @ingroup hitls_config + * @brief Obtains whether the current cipher suite supports preferential selection from the list of + * algorithms supported by the server. + * + * @param config [IN] TLS link configuration + * @param isSupport [OUT] Support or not + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_GetCipherServerPreference(const HITLS_Config *config, bool *isSupport); + +/** + * @ingroup hitls_config + * @brief Set whether to send handshake messages by route. + * + * @param config [IN/OUT] TLS link configuration + * @param isEnable [IN] Indicates whether to enable the function of sending handshake information by range. + * 0 indicates that the function is disabled. Other values indicate that the function is enabled. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetFlightTransmitSwitch(HITLS_Config *config, uint8_t isEnable); + +/** + * @ingroup hitls_config + * @brief Obtains the status of whether to send handshake information according to the route. + * + * @param config [IN] TLS link configuration. + * @param isEnable [OUT] Indicates whether to send handshake information by route. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_GetFlightTransmitSwitch(const HITLS_Config *config, uint8_t *isEnable); + +/** + * @ingroup hitls_config + * @brief Obtain whether to enable the miniaturization function. + * By default, the miniaturization function is disabled. + * + * @param config [IN] TLS link configuration. + * @param isEnable [OUT] Indicates whether to enable the miniaturization function. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_GetMiniaturizationSwitch(const HITLS_Config *config, uint8_t *isEnable); + +/** + * @ingroup hitls_config + * @brief Set the maximum size of the certificate chain that can be sent by the peer end. + * + * @param config [IN/OUT] TLS link configuration. + * @param maxSize [IN] Set the maximum size of the certificate chain that can be sent by the peer end. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetMaxCertList(HITLS_Config *config, uint32_t maxSize); + +/** + * @ingroup hitls_config + * @brief Obtain the maximum size of the certificate chain that can be sent by the peer end. + * + * @param config [IN] TLS link configuration + * @param maxSize [OUT] Maximum size of the certificate chain that can be sent by the peer end. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_GetMaxCertList(const HITLS_Config *config, uint32_t *maxSize); + +typedef uint64_t (*HITLS_RecordPaddingCb)(HITLS_Ctx *ctx, int32_t type, uint64_t length, void *arg); + +/** + * @ingroup hitls_config + * @brief Set the RecordPadding callback. + * + * @param config [OUT] Config context + * @param callback [IN] RecordPadding Callback + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetRecordPaddingCb(HITLS_Config *config, HITLS_RecordPaddingCb callback); + +/** + * @ingroup hitls_config + * @brief Obtains the RecordPadding callback function. + * + * @param config [OUT] Config context + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +HITLS_RecordPaddingCb HITLS_CFG_GetRecordPaddingCb(HITLS_Config *config); + +/** + * @ingroup hitls_config + * @brief Sets the parameters arg required by the RecordPadding callback function. + * + * @param config [OUT] Config context + * @param arg [IN] Related parameters arg + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetRecordPaddingCbArg(HITLS_Config *config, void *arg); + +/** + * @ingroup hitls_config + * @brief Obtains the parameter arg required by the RecordPadding callback function. + * + * @param config [OUT] Config context + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +void *HITLS_CFG_GetRecordPaddingCbArg(HITLS_Config *config); + +/** + * @ingroup hitls_config + * @brief Disables the verification of keyusage in the certificate. This function is enabled by default. + * + * @param config [OUT] Config context + * @param close [IN] Sets whether to disable verification. + * @retval HITLS_NULL_INPUT, the input parameter pointer is null. + * @retval HITLS_SUCCESS, if successful. + */ +int32_t HITLS_CFG_SetCloseCheckKeyUsage(HITLS_Config *config, bool isClose); + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_CONFIG_H */ diff --git a/include/tls/hitls_crypt_init.h b/include/tls/hitls_crypt_init.h new file mode 100644 index 00000000..9a14fd98 --- /dev/null +++ b/include/tls/hitls_crypt_init.h @@ -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. + */ + /** + * @defgroup hitls_crypt_init + * @ingroup hitls + * @brief algorithm abstraction layer initialization + */ + +#ifndef HITLS_CRYPT_INIT_H +#define HITLS_CRYPT_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_crypt_init + * @brief Initialize the algorithm interface. By default, the hicrypto interface is used. + * + * @attention If hicrypto is not used, you do not need to call this API. + */ +void HITLS_CryptMethodInit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_CRYPT_INIT_H */ \ No newline at end of file diff --git a/include/tls/hitls_crypt_reg.h b/include/tls/hitls_crypt_reg.h new file mode 100644 index 00000000..63282ea1 --- /dev/null +++ b/include/tls/hitls_crypt_reg.h @@ -0,0 +1,525 @@ +/* + * 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 hitls_crypt_reg + * @ingroup hitls + * @brief Algorithm related interfaces to be registered + */ + +#ifndef HITLS_CRYPT_REG_H +#define HITLS_CRYPT_REG_H + +#include +#include "hitls_type.h" +#include "hitls_crypt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_crypt_reg + * @brief Obtain the random number. + * + * @param buf [OUT] Random number + * @param len [IN] Random number length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_RandBytesCallback)(uint8_t *buf, uint32_t len); + +/** + * @ingroup hitls_crypt_reg + * @brief ECDH: Generate a key pair based on elliptic curve parameters. + * + * @param curveParams [IN] Elliptic curve parameter + * + * @retval Key handle + */ +typedef HITLS_CRYPT_Key *(*CRYPT_GenerateEcdhKeyPairCallback)(const HITLS_ECParameters *curveParams); + +/** + * @ingroup hitls_crypt_reg + * @brief Deep copy key + * + * @param key [IN] Key handle + * + * @retval Key handle + */ +typedef HITLS_CRYPT_Key *(*CRYPT_DupEcdhKeyCallback)(HITLS_CRYPT_Key *key); + +/** + * @ingroup hitls_crypt_reg + * @brief Release the key. + * + * @param key [IN] Key handle + */ +typedef void (*CRYPT_FreeEcdhKeyCallback)(HITLS_CRYPT_Key *key); + +/** + * @ingroup hitls_crypt_reg + * @brief ECDH: Extract the public key data. + * + * @param key [IN] Key handle + * @param pubKeyBuf [OUT] Public key data + * @param bufLen [IN] Buffer length + * @param pubKeyLen [OUT] Public key data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_GetEcdhEncodedPubKeyCallback)(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, + uint32_t *pubKeyLen); + +/** + * @ingroup hitls_crypt_reg + * @brief ECDH: Calculate the shared key based on the local key and peer public key. + * + * @param key [IN] Key handle + * @param peerPubkey [IN] Public key data + * @param pubKeyLen [IN] Public key data length + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of the key padding OUT: Key length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_CalcEcdhSharedSecretCallback)(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @ingroup hitls_crypt_reg + * @brief SM2 calculates the shared key based on the local key and peer public key. + * + * @param sm2Params [IN] Shared key calculation parameters + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of the key padding OUT: Key length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_Sm2CalcEcdhSharedSecretCallback)(HITLS_Sm2GenShareKeyParameters *sm2Params, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @ingroup hitls_crypt_reg + * @brief Generate a key pair based on secbits. + * + * @param secbits [IN] Key security level + * + * @retval Key handle + */ +typedef HITLS_CRYPT_Key *(*CRYPT_GenerateDhKeyBySecbitsCallback)(int32_t secbits); + +/** + * @ingroup hitls_crypt_reg + * @brief DH: Generate a key pair based on the dh parameter. + * + * @param p [IN] p Parameter + * @param plen [IN] p Parameter length + * @param g [IN] g Parameter + * @param glen [IN] g Parameter length + * + * @retval Key handle + */ +typedef HITLS_CRYPT_Key *(*CRYPT_GenerateDhKeyByParamsCallback)(uint8_t *p, uint16_t plen, uint8_t *g, uint16_t glen); + +/** + * @ingroup hitls_crypt_reg + * @brief Deep copy key + * + * @param key [IN] Key handle + * @retval Key handle + */ +typedef HITLS_CRYPT_Key *(*CRYPT_DupDhKeyCallback)(HITLS_CRYPT_Key *key); + +/** + * @ingroup hitls_crypt_reg + * @brief Release the key. + * + * @param key [IN] Key handle + */ +typedef void (*CRYPT_FreeDhKeyCallback)(HITLS_CRYPT_Key *key); + +/** + * @ingroup hitls_crypt_reg + * @brief DH: Obtain p g plen glen by using the key handle. + * + * @attention If the p and g parameters are null pointers, only the lengths of p and g are obtained. + * + * @param key [IN] Key handle + * @param p [OUT] p Parameter + * @param plen [IN/OUT] IN: Maximum length of data padding OUT: p Parameter length + * @param g [OUT] g Parameter + * @param glen [IN/OUT] IN: Maximum length of data padding OUT: g Parameter length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_DHGetParametersCallback)(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *plen, + uint8_t *g, uint16_t *glen); + +/** + * @ingroup hitls_crypt_reg + * @brief DH: Extract the Dh public key data. + * + * @param key [IN] Key handle + * @param pubKeyBuf [OUT] Public key data + * @param bufLen [IN] Buffer length + * @param pubKeyLen [OUT] Public key data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_GetDhEncodedPubKeyCallback)(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, + uint32_t *pubKeyLen); + +/** + * @ingroup hitls_crypt_reg + * @brief DH: Calculate the shared key based on the local key and peer public key. + * + * @param key [IN] Key handle + * @param peerPubkey [IN] Public key data + * @param pubKeyLen [IN] Public key data length + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of the key padding OUT: Key length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_CalcDhSharedSecretCallback)(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @ingroup hitls_crypt_reg + * @brief Obtain the HMAC length based on the hash algorithm. + * + * @param hashAlgo [IN] Hash algorithm + * + * @retval HMAC length + */ +typedef uint32_t (*CRYPT_HmacSizeCallback)(HITLS_HashAlgo hashAlgo); + +/** + * @ingroup hitls_crypt_reg + * @brief Initialize the HMAC context. + * + * @param hashAlgo [IN] Hash algorithm + * @param key [IN] Key + * @param len [IN] Key length + * + * @retval HMAC context + */ +typedef HITLS_HMAC_Ctx *(*CRYPT_HmacInitCallback)(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len); + +/** + * @ingroup hitls_crypt_reg + * @brief Release the HMAC context. + * + * @param ctx [IN] HMAC context + */ +typedef void (*CRYPT_HmacFreeCallback)(HITLS_HMAC_Ctx *ctx); + +/** + * @ingroup hitls_crypt_reg + * @brief Add the HMAC input data. + * + * @param ctx [IN] HMAC context + * @param data [IN] Input data + * @param len [IN] Data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_HmacUpdateCallback)(HITLS_HMAC_Ctx *ctx, const uint8_t *data, uint32_t len); + +/** + * @ingroup hitls_crypt_reg + * @brief Output the HMAC result. + * + * @param ctx [IN] HMAC context + * @param out [OUT] Output data + * @param len [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_HmacFinalCallback)(HITLS_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len); + +/** + * @ingroup hitls_crypt_reg + * @brief Function for calculating the HMAC for a single time + * + * @param hashAlgo [IN] Hash algorithm + * @param key [IN] Key + * @param keyLen [IN] Key length + * @param in [IN] Input data. + * @param inLen [IN] Input data length + * @param out [OUT] Output the HMAC data result. + * @param outLen [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_HmacCallback)(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen, + const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_crypt_reg + * @brief Obtain the hash length. + * + * @param hashAlgo [IN] Hash algorithm. + * + * @retval Hash length + */ +typedef uint32_t (*CRYPT_DigestSizeCallback)(HITLS_HashAlgo hashAlgo); + +/** + * @ingroup hitls_crypt_reg + * @brief Initialize the hash context. + * + * @param hashAlgo [IN] Hash algorithm + * + * @retval Hash context + */ +typedef HITLS_HASH_Ctx *(*CRYPT_DigestInitCallback)(HITLS_HashAlgo hashAlgo); + +/** + * @ingroup hitls_crypt_reg + * @brief Copy the hash context. + * + * @param ctx [IN] Hash Context + * + * @retval Hash context + */ +typedef HITLS_HASH_Ctx *(*CRYPT_DigestCopyCallback)(HITLS_HASH_Ctx *ctx); + +/** + * @ingroup hitls_crypt_reg + * @brief Release the hash context. + * + * @param ctx [IN] Hash Context + */ +typedef void (*CRYPT_DigestFreeCallback)(HITLS_HASH_Ctx *ctx); + +/** + * @ingroup hitls_crypt_reg + * @brief Hash Add input data. + * + * @param ctx [IN] Hash context + * @param data [IN] Input data + * @param len [IN] Input data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_DigestUpdateCallback)(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len); + +/** + * @ingroup hitls_crypt_reg + * @brief Output the hash result. + * + * @param ctx [IN] Hash context + * @param out [IN] Output data. + * @param len [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_DigestFinalCallback)(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len); + +/** + * @ingroup hitls_crypt_reg + * @brief Hash function + * + * @param hashAlgo [IN] Hash algorithm + * @param in [IN] Input data + * @param inLen [IN] Input data length + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_DigestCallback)(HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_crypt_reg + * @brief TLS encryption + * + * Provides the encryption capability for records, including the AEAD and CBC algorithms. + * Encrypts the input factor (key parameter) and plaintext based on the record protocol + * to obtain the ciphertext. + * + * @attention: The protocol allows the sending of app packets with payload length 0. + * Therefore, the length of the plaintext input may be 0. Therefore, + * the plaintext with the length of 0 must be encrypted. + * @param cipher [IN] Key parameters + * @param in [IN] Plaintext data + * @param inLen [IN] Plaintext data length + * @param out [OUT] Ciphertext data + * @param outLen [IN/OUT] IN: maximum buffer length OUT: ciphertext data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_EncryptCallback)(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_crypt_reg + * @brief TLS decryption + * + * Provides decryption capabilities for records, including the AEAD and CBC algorithms. + * Decrypt the input factor (key parameter) and ciphertext according to the record protocol to obtain the plaintext. + * + * @param cipher [IN] Key parameters + * @param in [IN] Ciphertext data + * @param inLen [IN] Ciphertext data length + * @param out [OUT] Plaintext data + * @param outLen [IN/OUT] IN: maximum buffer length OUT: plaintext data length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_DecryptCallback)(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_crypt_reg + * @brief HKDF-Extract + * + * @param input [IN] Enter the key material. + * @param prk [OUT] Output key + * @param prkLen [IN/OUT] IN: Maximum buffer length OUT: Output key length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_HkdfExtractCallback)(const HITLS_CRYPT_HkdfExtractInput *input, uint8_t *prk, uint32_t *prkLen); + +/** + * @ingroup hitls_crypt_reg + * @brief HKDF-Expand + * + * @param input [IN] Enter the key material. + * @param okm [OUT] Output key + * @param okmLen [IN] Output key length + * + * @retval 0 indicates success. Other values indicate failure. + */ +typedef int32_t (*CRYPT_HkdfExpandCallback)(const HITLS_CRYPT_HkdfExpandInput *input, uint8_t *okm, uint32_t okmLen); + +/** + * @ingroup hitls_cert_reg + * @brief Callback function that must be registered + */ +typedef struct { + CRYPT_RandBytesCallback randBytes; /**< Obtain the random number. */ + CRYPT_HmacSizeCallback hmacSize; /**< HMAC: obtain the HMAC length based + on the hash algorithm. */ + CRYPT_HmacInitCallback hmacInit; /**< HMAC: initialize the context. */ + CRYPT_HmacFreeCallback hmacFree; /**< HMAC: release the context. */ + CRYPT_HmacUpdateCallback hmacUpdate; /**< HMAC: add input data. */ + CRYPT_HmacFinalCallback hmacFinal; /**< HMAC: output result. */ + CRYPT_HmacCallback hmac; /**< HMAC: single HMAC function. */ + CRYPT_DigestSizeCallback digestSize; /**< HASH: obtains the hash length. */ + CRYPT_DigestInitCallback digestInit; /**< HASH: initialize the context. */ + CRYPT_DigestCopyCallback digestCopy; /**< HASH: copy the hash context. */ + CRYPT_DigestFreeCallback digestFree; /**< HASH: release the context. */ + CRYPT_DigestUpdateCallback digestUpdate; /**< HASH: add input data. */ + CRYPT_DigestFinalCallback digestFinal; /**< HASH: output the hash result. */ + CRYPT_DigestCallback digest; /**< HASH: single hash function. */ + CRYPT_EncryptCallback encrypt; /**< TLS encryption: provides the encryption + capability for records. */ + CRYPT_DecryptCallback decrypt; /**< TLS decryption: provides the decryption + capability for records. */ +} HITLS_CRYPT_BaseMethod; + +/** + * @ingroup hitls_cert_reg + * @brief ECDH Callback function to be registered + */ +typedef struct { + CRYPT_GenerateEcdhKeyPairCallback generateEcdhKeyPair; /**< ECDH: generate a key pair based + on the elliptic curve parameters. */ + CRYPT_DupEcdhKeyCallback dupEcdhKey; /**< ECDH: deep copy key. */ + CRYPT_FreeEcdhKeyCallback freeEcdhKey; /**< ECDH: release the elliptic curve key. */ + CRYPT_GetEcdhEncodedPubKeyCallback getEcdhPubKey; /**< ECDH: extract public key data. */ + CRYPT_CalcEcdhSharedSecretCallback calcEcdhSharedSecret; /**< ECDH: calculate the shared key based on + the local key and peer public key. */ + CRYPT_Sm2CalcEcdhSharedSecretCallback sm2CalEcdhSharedSecret; +} HITLS_CRYPT_EcdhMethod; + +/** + * @ingroup hitls_cert_reg + * @brief DH Callback function to be registered + */ +typedef struct { + CRYPT_GenerateDhKeyBySecbitsCallback generateDhKeyBySecbits; /**< DH: Generate a key pair based on secbits */ + CRYPT_GenerateDhKeyByParamsCallback generateDhKeyByParams; /**< DH: Generate a key pair + based on the dh parameter */ + CRYPT_DupDhKeyCallback dupDhKey; /**< DH: deep copy key*/ + CRYPT_FreeDhKeyCallback freeDhKey; /**< DH: release the key */ + CRYPT_DHGetParametersCallback getDhParameters; /**< DH: obtain the p g plen glen + by using the key handle */ + CRYPT_GetDhEncodedPubKeyCallback getDhPubKey; /**< DH: extract the Dh public key data */ + CRYPT_CalcDhSharedSecretCallback calcDhSharedSecret; /**< DH: calculate the shared key based on + the local key and peer public key */ +} HITLS_CRYPT_DhMethod; + +/** + * @ingroup hitls_cert_reg + * @brief KDF function + */ +typedef struct { + CRYPT_HkdfExtractCallback hkdfExtract; + CRYPT_HkdfExpandCallback hkdfExpand; +} HITLS_CRYPT_KdfMethod; + +/** + * @ingroup hitls_cert_reg + * @brief Register the basic callback function. + * + * @param userCryptCallBack [IN] Callback function to be registered + * + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter is NULL.. + */ +int32_t HITLS_CRYPT_RegisterBaseMethod(HITLS_CRYPT_BaseMethod *userCryptCallBack); + +/** + * @ingroup hitls_cert_reg + * @brief Register the ECDH callback function. + * + * @param userCryptCallBack [IN] Callback function to be registered + * + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter is NULL.. + */ +int32_t HITLS_CRYPT_RegisterEcdhMethod(HITLS_CRYPT_EcdhMethod *userCryptCallBack); + +/** + * @ingroup hitls_cert_reg + * @brief Register the callback function of the DH. + * + * @param userCryptCallBack [IN] Callback function to be registered + * + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter is NULL.. + */ +int32_t HITLS_CRYPT_RegisterDhMethod(const HITLS_CRYPT_DhMethod *userCryptCallBack); + +/** + * @brief Register the callback function of the HKDF. + * + * @param userCryptCallBack [IN] Callback function to be registered + * + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, the input parameter is NULL.. + */ +int32_t HITLS_CRYPT_RegisterHkdfMethod(HITLS_CRYPT_KdfMethod *userCryptCallBack); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/tls/hitls_crypt_type.h b/include/tls/hitls_crypt_type.h new file mode 100644 index 00000000..aca2e89a --- /dev/null +++ b/include/tls/hitls_crypt_type.h @@ -0,0 +1,276 @@ +/* + * 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 hitls_crypt_reg + * @ingroup hitls + * @brief Algorithm related interfaces to be registered + */ + +#ifndef HITLS_CRYPT_TYPE_H +#define HITLS_CRYPT_TYPE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_crypt_type + * @brief Key handle, which is converted into the corresponding structure based on the algorithm library + * used by the user. + */ +typedef void HITLS_CRYPT_Key; + +/** + * @ingroup hitls_crypt_type + * @brief Hash context. The user converts the structure based on the algorithm library. + */ +typedef void HITLS_HASH_Ctx; + +/** + * @ingroup hitls_crypt_type + * @brief HMAC context. The user converts the HMAC context into the corresponding structure + * based on the algorithm library. + */ +typedef void HITLS_HMAC_Ctx; + +/** + * @ingroup hitls_crypt_type + * @brief Enumerated value of the symmetric encryption algorithm type. + */ +typedef enum { + HITLS_AEAD_CIPHER, + HITLS_CBC_CIPHER, + HITLS_CIPHER_TYPE_BUTT = 255 +} HITLS_CipherType; + +/** + * @ingroup hitls_crypt_type + * @brief Enumerated value of the symmetric encryption algorithm. + */ +typedef enum { + HITLS_CIPHER_NULL, + HITLS_CIPHER_AES_128_CBC, + HITLS_CIPHER_AES_256_CBC, + HITLS_CIPHER_AES_128_GCM, + HITLS_CIPHER_AES_256_GCM, + HITLS_CIPHER_AES_128_CCM, + HITLS_CIPHER_AES_256_CCM, + HITLS_CIPHER_AES_128_CCM8, + HITLS_CIPHER_AES_256_CCM8, + HITLS_CIPHER_CHACHA20_POLY1305, + HITLS_CIPHER_SM4_CBC, + HITLS_CIPHER_BUTT = 255 +} HITLS_CipherAlgo; + +/** + * @ingroup hitls_crypt_type + * @brief Hash algorithm enumeration + */ +typedef enum { + HITLS_HASH_NULL, + HITLS_HASH_MD5, + HITLS_HASH_SHA1, + HITLS_HASH_SHA_224, + HITLS_HASH_SHA_256, + HITLS_HASH_SHA_384, + HITLS_HASH_SHA_512, + HITLS_HASH_MD5_SHA1, + HITLS_HASH_SM3, + HITLS_HASH_BUTT = 255 +} HITLS_HashAlgo; + +/** + * @ingroup hitls_crypt_type + * @brief MAC algorithm enumerated value + */ +typedef enum { + HITLS_MAC_NULL, + HITLS_MAC_MD5, + HITLS_MAC_1, + HITLS_MAC_224, + HITLS_MAC_256, + HITLS_MAC_384, + HITLS_MAC_512, + HITLS_MAC_SM3, + HITLS_MAC_AEAD, + HITLS_MAC_BUTT = 255 +} HITLS_MacAlgo; + +/** + * @ingroup hitls_crypt_type + * @brief Enumerated value of the authentication algorithm + */ +typedef enum { + HITLS_AUTH_NULL, + HITLS_AUTH_RSA, + HITLS_AUTH_ECDSA, + HITLS_AUTH_DSS, + HITLS_AUTH_PSK, + HITLS_AUTH_SM2, + HITLS_AUTH_ANY, + HITLS_AUTH_BUTT = 255 +} HITLS_AuthAlgo; + +/** + * @ingroup hitls_crypt_type + * @brief Key exchange algorithm enumerated value + */ +typedef enum { + HITLS_KEY_EXCH_NULL, + HITLS_KEY_EXCH_ECDHE, + HITLS_KEY_EXCH_DHE, + HITLS_KEY_EXCH_ECDH, + HITLS_KEY_EXCH_DH, + HITLS_KEY_EXCH_RSA, + HITLS_KEY_EXCH_ECDHE_PSK, + HITLS_KEY_EXCH_DHE_PSK, + HITLS_KEY_EXCH_RSA_PSK, + HITLS_KEY_EXCH_PSK, + HITLS_KEY_EXCH_ECC, /* sm2 encrypt */ + HITLS_KEY_EXCH_BUTT = 255 +} HITLS_KeyExchAlgo; + +/** + * @ingroup hitls_crypt_type + * @brief Signature algorithm enumeration + */ +typedef enum { + HITLS_SIGN_RSA_PKCS1_V15, + HITLS_SIGN_DSA, /**< Signature algorithm: DSA */ + HITLS_SIGN_ECDSA, + HITLS_SIGN_RSA_PSS_RSAE, + HITLS_SIGN_ED25519, + HITLS_SIGN_RSA_PSS_PSS, + HITLS_SIGN_SM2, + HITLS_SIGN_BUTT = 255 +} HITLS_SignAlgo; + +/** + * @ingroup hitls_crypt_type + * @brief Elliptic curve type enumerated value + */ +typedef enum { + HITLS_EC_CURVE_TYPE_NAMED_CURVE = 3, + HITLS_EC_CURVE_TYPE_BUTT = 255 +} HITLS_ECCurveType; + +/** + * @ingroup hitls_crypt_type + * @brief Elliptic curve ID. + */ +typedef enum { + HITLS_EC_GROUP_SECP256R1 = 23, + HITLS_EC_GROUP_SECP384R1 = 24, + HITLS_EC_GROUP_SECP521R1 = 25, + HITLS_EC_GROUP_BRAINPOOLP256R1 = 26, + HITLS_EC_GROUP_BRAINPOOLP384R1 = 27, + HITLS_EC_GROUP_BRAINPOOLP512R1 = 28, + HITLS_EC_GROUP_CURVE25519 = 29, + HITLS_EC_GROUP_SM2 = 41, + HITLS_FF_DHE_2048 = 256, + HITLS_FF_DHE_3072 = 257, + HITLS_FF_DHE_4096 = 258, + HITLS_FF_DHE_6144 = 259, + HITLS_FF_DHE_8192 = 260, + HITLS_NAMED_GROUP_BUTT = 0xFFFFu +} HITLS_NamedGroup; + +/** + * @ingroup hitls_crypt_type + * @brief Elliptic curve point format enumerated value + */ +typedef enum { + HITLS_POINT_FORMAT_UNCOMPRESSED = 0, + HITLS_POINT_FORMAT_BUTT = 255 +} HITLS_ECPointFormat; + +/** + * @ingroup hitls_crypt_type + * @brief Elliptic curve parameter + */ +typedef struct { + HITLS_ECCurveType type; /**< Elliptic curve type. */ + union { + void *prime; /**< Display prime number: corresponding to the protocol explicit_prime. */ + void *char2; /**< Display char2: corresponding to the protocol explicit_char2. */ + HITLS_NamedGroup namedcurve; /**< Elliptic curve ID. */ + } param; +} HITLS_ECParameters; + +/** + * @ingroup hitls_crypt_type + * @brief Key parameters + */ +typedef struct { + HITLS_CipherType type; /**< Encryption algorithm type. Currently, only aead is supported. */ + HITLS_CipherAlgo algo; /**< Symmetric encryption algorithm. */ + const uint8_t *key; /**< Symmetry key. */ + uint32_t keyLen; /**< Symmetry key length. */ + const uint8_t *hmacKey; /**< Hmac key. */ + uint32_t hmacKeyLen; /**< Hmac key length. */ + const uint8_t *iv; /**< IV. */ + uint32_t ivLen; /**< IV length. */ + uint8_t *aad; /**< Aad: AEAD: one of the input parameters for encryption and decryption. + additional data. */ + uint32_t aadLen; /**< Aad length. */ +} HITLS_CipherParameters; + +/** + * @ingroup hitls_crypt_type + * @brief sm2 ecdhe negotiation key parameters + */ +typedef struct { + HITLS_CRYPT_Key *tmpPriKey; /**< Local temporary private key. */ + uint8_t *tmpPeerPubkey; /**< Peer temporary public key. */ + uint32_t tmpPeerPubKeyLen; /**< Length of the peer temporary public key. */ + HITLS_CRYPT_Key *priKey; /**< Local private key, which is used for SM2 algorithm negotiation. + It is the private key of the encryption certificate. */ + HITLS_CRYPT_Key *peerPubKey; /**< Peer public key, which is used for SM2 algorithm negotiation. + It is the public key in the encryption certificate. */ + bool isClient; /**< Client ID, which is used by the SM2 algorithm negotiation key. */ +} HITLS_Sm2GenShareKeyParameters; + +/** + * @ingroup hitls_crypt_type + * @brief HKDF-Extract Input + */ +typedef struct { + HITLS_HashAlgo hashAlgo; /**< Hash algorithm. */ + const uint8_t *salt; /**< Salt value. */ + uint32_t saltLen; /**< Salt value length. */ + const uint8_t *ikm; /**< Input Keying Material. */ + uint32_t ikmLen; /**< Ikm length. */ +} HITLS_CRYPT_HkdfExtractInput; + +/** + * @ingroup hitls_crypt_type + * @brief HKDF-Expand Input + */ +typedef struct { + HITLS_HashAlgo hashAlgo; /**< Hash algorithm. */ + const uint8_t *prk; /**< A pseudorandom key of at least HashLen octets. */ + uint32_t prkLen; /**< Prk length. */ + const uint8_t *info; /**< Extended data. */ + uint32_t infoLen; /**< Extend the data length. */ +} HITLS_CRYPT_HkdfExpandInput; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/tls/hitls_debug.h b/include/tls/hitls_debug.h new file mode 100644 index 00000000..a7cc053c --- /dev/null +++ b/include/tls/hitls_debug.h @@ -0,0 +1,160 @@ +/* + * 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 hitls_crypt_reg + * @ingroup hitls + * @brief hitls maintenance and debugging + */ + +#ifndef HITLS_DEBUG_H +#define HITLS_DEBUG_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INDICATE_VALUE_SUCCESS 1u + +#define INDICATE_EVENT_LOOP 0x01 // 0000 0000 0000 0001, Handshake state transition +#define INDICATE_EVENT_EXIT 0x02 // 0000 0000 0000 0010, Handshake status exit +#define INDICATE_EVENT_READ 0x04 // 0000 0000 0000 0100, Read event +#define INDICATE_EVENT_WRITE 0x08 // 0000 0000 0000 1000, Write event +#define INDICATE_EVENT_HANDSHAKE_START 0x10 // 0000 0000 0001 0000, Handshake Start +#define INDICATE_EVENT_HANDSHAKE_DONE 0x20 // 0000 0000 0010 0000, Handshake completed +#define INDICATE_EVENT_STATE_CONNECT 0x1000 // 0001 0000 0000 0000, Local client +#define INDICATE_EVENT_STATE_ACCEPT 0x2000 // 0010 0000 0000 0000, Local server +#define INDICATE_EVENT_ALERT 0x4000 // 0100 0000 0000 0000, Warning Time + +#define INDICATE_EVENT_READ_ALERT (INDICATE_EVENT_ALERT | INDICATE_EVENT_READ) +#define INDICATE_EVENT_WRITE_ALERT (INDICATE_EVENT_ALERT | INDICATE_EVENT_WRITE) +#define INDICATE_EVENT_STATE_ACCEPT_LOOP (INDICATE_EVENT_STATE_ACCEPT | INDICATE_EVENT_LOOP) +#define INDICATE_EVENT_STATE_ACCEPT_EXIT (INDICATE_EVENT_STATE_ACCEPT | INDICATE_EVENT_EXIT) +#define INDICATE_EVENT_STATE_CONNECT_LOOP (INDICATE_EVENT_STATE_CONNECT | INDICATE_EVENT_LOOP) +#define INDICATE_EVENT_STATE_CONNECT_EXIT (INDICATE_EVENT_STATE_CONNECT | INDICATE_EVENT_EXIT) + +/** + * @ingroup hitls_debug + * @brief Information prompt callback prototype + * + * @attention The message prompt callback function does not return a value + * @param ctx [IN] Ctx context + * @param eventType [IN] EventType Event type + * @param value [IN] Value Function return value or Alert type that matches the event type + * @retval No value is returned. + */ +typedef void (*HITLS_InfoCb)(const HITLS_Ctx *ctx, int32_t eventType, int32_t value); + +/** + * @ingroup hitls_debug + * @brief Set the callback for prompt information. + * + * @param ctx [OUT] Ctx context + * @param callback [IN] Callback function for prompting information + * @retval HITLS_SUCCESS, if successful. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetInfoCb(HITLS_Ctx *ctx, HITLS_InfoCb callback); + +/** + * @ingroup hitls_debug + * @brief Callback for obtaining information + * + * @param ctx [IN] Ctx context + * @retval Callback function of the current information prompt. + * If this parameter is not set, NULL is returned. + */ +HITLS_InfoCb HITLS_GetInfoCb(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_debug + * @brief Set the callback function for prompting information. + * + * @param config [OUT] Config Context + * @param callback [IN] Client callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetInfoCb(HITLS_Config *config, HITLS_InfoCb callback); + +/** + * @ingroup hitls_debug + * @brief Callback function for obtaining information prompts + * + * @param config [IN] config Context + * @retval Callback function of the current information prompt. + * If this parameter is not set, NULL is returned. + */ +HITLS_InfoCb HITLS_CFG_GetInfoCb(const HITLS_Config *config); + +/** + * @ingroup hitls_debug + * @brief Callback prototype of a protocol message + * + * @attention: The callback function for messages in the retention protocol does not return any value. + * @param writePoint [IN] writePoint Message direction in the callback ">>>" or "<<<" + * @param tlsVersion [IN] tlsVersion TLS version, for example, HITLS_VERSION_TLS12. + * @param contentType[IN] contentType Type of the processed message body. + * @param msg [IN] msg callback internal message processing instruction data + * @param msgLen [IN] msgLen Processing instruction data length + * @param ctx [IN] ctx HITLS context + * @param arg [IN] arg User data, for example, BIO + * @retval No value is returned. +*/ +typedef void (*HITLS_MsgCb) (int32_t writePoint, int32_t tlsVersion, int32_t contentType, const void *msg, + uint32_t msgLen, HITLS_Ctx *ctx, void *arg); + +/** + * @ingroup hitls_debug + * @brief Set the protocol message callback function, cb can be NULL. + * + * @param ctx [OUT] Ctx context + * @param callback [IN] Protocol message callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetMsgCb(HITLS_Ctx *ctx, HITLS_MsgCb callback); + +/** + * @ingroup hitls_debug + * @brief Set the protocol message callback function, cb can be NULL. + * + * @param config [OUT] Config Context + * @param callback [IN] Protocol message callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetMsgCb(HITLS_Config *config, HITLS_MsgCb callback); + +/** + * @ingroup hitls_debug + * @brief Set the related parameters arg required by the protocol message callback function. + * + * @param config [OUT] Config Context. + * @param arg [IN] Related parameters arg. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetMsgCbArg(HITLS_Config *config, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_DEBUG_H + diff --git a/include/tls/hitls_error.h b/include/tls/hitls_error.h new file mode 100644 index 00000000..eadb11cf --- /dev/null +++ b/include/tls/hitls_error.h @@ -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. + */ + +/** + * @defgroup hitls_errno + * @ingroup hitls + * @brief error module + */ + +#ifndef HITLS_ERROR_H +#define HITLS_ERROR_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define HITLS_SUCCESS 0 +#define HITLS_X509_V_OK 0 + +/** + * @ingroup hitls_errno + * @brief Indicates that the connection is blocked. You can call HITLS_Connect to continue the connection. + * This problem is usually caused by read and write operations. + */ +#define HITLS_WANT_CONNECT 1 + +/** + * @ingroup hitls_errno + * @brief Indicates that the connection is blocked and the HITLS_Accept can be called to continue the connection. + * This problem is usually caused by read and write operations. + */ +#define HITLS_WANT_ACCEPT 2 + +/** + * @ingroup hitls_errno + * @brief indicates that the receiving buffer is empty and the interface can be + * called to continue receiving data. + */ +#define HITLS_WANT_READ 3 + +/** + * @ingroup hitls_errno + * @brief The sending buffer is full and the interface can be called to continue sending data. + */ +#define HITLS_WANT_WRITE 4 + +/** + * @ingroup hitls_errno + * @brief An unrecoverable fatal error occurs in the TLS protocol, usually a protocol error. + */ +#define HITLS_ERR_TLS 5 + +/** + * @ingroup hitls_errno + * @brief An unrecoverable I/O error occurs, + * which is usually a low level receiving and receiving exception or an unknown error occurs. + */ +#define HITLS_ERR_SYSCALL 6 + +/** + * @ingroup hitls_errno + * + * Error code returned by the TLS module + */ +typedef enum { + HITLS_NULL_INPUT = 0x02010001, /**< Incorrect null pointer input. */ + HITLS_INVALID_INPUT, /**< Invalid input, the parameter value is out of the valid range.*/ + HITLS_INTERNAL_EXCEPTION, /**< Unexpected internal error, which is unlikely. */ + HITLS_MEMALLOC_FAIL, /**< Failed to apply for memory. */ + HITLS_MEMCPY_FAIL, /**< Memory Copy Failure. */ + HITLS_UNREGISTERED_CALLBACK, /**< Use unregistered callback. */ + + HITLS_CONFIG_FAIL_START = 0x02020001, /**< config module error code start bit. */ + HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE, /**< No suitable cipher suite is found. */ + HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE, /**< Unsupported cipher suites. */ + HITLS_CONFIG_INVALID_SET, /**< Invalid setting. */ + HITLS_CONFIG_NO_SUITABLE_SIGNATURE_ALGORITHM, /**< The signature algorithm and the cipher suite are nonmatching. */ + HITLS_CONFIG_NO_GROUPS, /**< The group is not set. */ + HITLS_CONFIG_UNSUPPORT_SIGNATURE_ALGORITHM, /**< Unsupported signature algorithm. */ + HITLS_CONFIG_UNSUPPORT_POINT_FORMATS, /**< Unsupported the dot format. */ + HITLS_CONFIG_INVALID_VERSION, /**< Unsupported the protocol version. */ + HITLS_CONFIG_INVALID_LENGTH, /**< Invalid length. */ + HITLS_CONFIG_NO_CERT, /**< Unset the certificate. */ + HITLS_CONFIG_NO_PRIVATE_KEY, /**< Unset the certificate private key. */ + HITLS_CONFIG_DUP_DH_KEY_FAIL, /**< Duplicate DH key failure. */ + HITLS_CONFIG_DUP_ECDH_KEY_FAIL, /**< Duplicate ecdh Key failure. */ + HITLS_CONFIG_ERR_LOAD_CERT_FILE, /**< Failed to load the certificate file. */ + HITLS_CONFIG_ERR_LOAD_CERT_BUFFER, /**< Failed to load the certificate buffer. */ + HITLS_CONFIG_ERR_LOAD_KEY_FILE, /**< Failed to load the key file. */ + HITLS_CONFIG_ERR_LOAD_KEY_BUFFER, /**< Failed to load the key buffer. */ + + HITLS_CM_FAIL_START = 0x02030001, /**< Error start bit of the conn module. */ + HITLS_CM_LINK_FATAL_ALERTED, /**< link sent fatal alert. */ + HITLS_CM_LINK_CLOSED, /**< Link has been closed. */ + HITLS_CM_LINK_UNESTABLISHED, /**< The current link is not established. + Do not perform other operations, such as read and write. */ + HITLS_CM_LINK_UNSUPPORT_SECURE_RENEGOTIATION, /**< The current link Unsupported security renegotiation. */ + + HITLS_MSG_HANDLE_FAIL_START = 0x02040001, /**< Start bit of the error code processed by the state machine. */ + HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE, /**< receives unexpected handshake messages. */ + HITLS_MSG_HANDLE_RANDOM_SIZE_ERR, /**< Incorrect random number length. */ + HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT, /**< Unsupported the point format. */ + HITLS_MSG_HANDLE_CIPHER_SUITE_ERR, /**< cannot find the supported cipher suite. */ + HITLS_MSG_HANDLE_UNSUPPORT_VERSION, /**< Unsupported version. */ + HITLS_MSG_HANDLE_STATE_ILLEGAL, /**< Handshake status error. */ + HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG, /**< Unsupported key exchange algorithm. */ + HITLS_MSG_HANDLE_UNSUPPORT_CERT, /**< Unsupported certificate. */ + HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE, /**< Unsupported elliptic curve type. */ + HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL, /**< Failed to verify the finished message. */ + HITLS_MSG_HANDLE_VERIFY_SIGN_FAIL, /**< Failed to verify the finished message. */ + HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN, /**< Incorrect length of the digest. */ + HITLS_MSG_HANDLE_UNSUPPORT_NAMED_CURVE, /**< Unsupported ECDH elliptic curves. */ + HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE, /**< Unsupported the extended type. */ + HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE, /**< Unsupported cipher suites. */ + HITLS_MSG_HANDLE_ERR_ENCODE_ECDH_KEY, /**< Failed to obtain the ECDH public key. */ + HITLS_MSG_HANDLE_ERR_ENCODE_DH_KEY, /**< Failed to obtain the DH public key. */ + HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS, /**< Failed to obtain the DH parameter. */ + HITLS_MSG_HANDLE_ERR_GET_DH_KEY, /**< Failed to generate the DH key. */ + HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE, /**< Not receive the peer certificate. */ + HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE, /**< Server has no certificate to send. */ + HITLS_MSG_HANDLE_UNMATCHED_SEQUENCE, /**< Handshake sequence number nonmatch */ + HITLS_MSG_HANDLE_ILLEGAL_VERSION, /**< Incorrect version. */ + HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE, /**< Incorrect cipher suite. */ + HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP, /**< Incorrect selectedGroup. */ + HITLS_MSG_HANDLE_ILLEGAL_EXTRENED_MASTER_SECRET, /**< Incorrect extended master key. */ + HITLS_MSG_HANDLE_MISSING_EXTENSION, /**< Message missing the extended field that must be sent */ + HITLS_MSG_HANDLE_DUPLICATE_HELLO_RETYR_REQUEST, /**< Duplicate Hello Retry Request messages */ + HITLS_MSG_HANDLE_ALPN_PROTOCOL_NO_MATCH, /**< No matching alpn */ + HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN, /**< Invalid PSK length */ + HITLS_MSG_HANDLE_ILLEGAL_IDENTITY_LEN, /**< Invalid identity length */ + HITLS_MSG_HANDLE_GET_UNSIGN_DATA_FAIL, /**< Failed to obtain the unsigned data + during signature calculation */ + HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID, /**< Receives an incorrect session ID */ + HITLS_MSG_HANDLE_SNI_UNRECOGNIZED_NAME, /**< Not accept the extended value of server_name */ + HITLS_MSG_HANDLE_ALPN_UNRECOGNIZED, /**< Not accept the extended ALPN value */ + HITLS_MSG_HANDLE_ILLEGAL_KEY_UPDATE_TYPE, /**< Receives an incorrect key update type */ + HITLS_MSG_HANDLE_UNSECURE_VERSION, /**< Insecure version. */ + HITLS_MSG_HANDLE_UNSECURE_CIPHER_SUITE, /**< Insecure cipher suites. */ + HITLS_MSG_HANDLE_RENEGOTIATION_FAIL, /**< Renegotiation failure */ + HITLS_MSG_HANDLE_SESSION_ID_CTX_ILLEGAL, /**< Session ID ctx mismatch */ + HITLS_MSG_HANDLE_ENCRYPT_THEN_MAC_ERR, /**< Failed to change the EncryptThenMac status */ + HITLS_MSG_HANDLE_ILLEGAL_PSK_IDENTITY, /**< psk identity error */ + HITLS_MSG_HANDLE_PSK_USE_SESSION_FAIL, /**< The TLS1.3 client fails to process the PSK callback. */ + HITLS_MSG_HANDLE_PSK_FIND_SESSION_FAIL, /**< The TLS1.3 server fails to process the PSK callback. */ + HITLS_MSG_HANDLE_PSK_SESSION_INVALID_CIPHER_SUITE, /**< TLS1.3 psk session algorithm suite is incorrect. */ + HITLS_MSG_HANDLE_PSK_INVALID, /**< TLS1.3 psk check failed. */ + HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX, /**< TLS1.3 invalid certificateReqCtx. */ + HITLS_MSG_HANDLE_HANDSHAKE_FAILURE, /**< TLS1.3 handshake parameters cannot be negotiated. */ + HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD, /**< Receives an incorrect compression algorithm. */ + HITLS_MSG_HANDLE_INVALID_EXTENDED_MASTER_SECRET, /**< The peer Unsupported the extended master key. */ + + HITLS_PACK_FAIL_START = 0x02050001, /**< Start bit of the pack error code. */ + HITLS_PACK_UNSUPPORT_VERSION, /**< Unsupported version. */ + HITLS_PACK_UNSECURE_VERSION, /**< Insecure version. */ + HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG, /**< Unsupported handshake messages. */ + HITLS_PACK_NOT_ENOUGH_BUF_LENGTH, /**< Insufficient buffer length. */ + HITLS_PACK_SESSIONID_ERR, /**< Failed to assemble the sessionId. */ + HITLS_PACK_COOKIE_ERR, /**< Failed to assemble the cookie. */ + HITLS_PACK_CLIENT_CIPHER_SUITE_ERR, /**< Failed to assemble client_cipher_suite. */ + HITLS_PACK_UNSUPPORT_KX_ALG, /**< Unsupported the key negotiation algorithm. */ + HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE, /**< Unsupported ECDH key negotiation algorithm curve. */ + HITLS_PACK_INVALID_KX_PUBKEY_LENGTH, /**< Invalid length of the public key for key negotiation */ + HITLS_PACK_SIGNATURE_ERR, /**< Failed to assemble the server_kx message signature data. */ + HITLS_PACK_PRE_SHARED_KEY_ERR, /**< Failed to assemble the PSK. */ + + HITLS_PARSE_FAIL_START = 0x02060001, /**< Start bit of the parse error code. */ + HITLS_PARSE_UNSUPPORT_VERSION, /**< Unsupported Version. */ + HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG, /**< Unsupported handshake messages. */ + HITLS_PARSE_INVALID_MSG_LEN, /**< Message length error. */ + HITLS_PARSE_DUPLICATE_EXTENDED_MSG, /**< Duplicate extended messages. */ + HITLS_PARSE_COMPRESSION_METHOD_ERR, /**< Incorrect compression type. */ + HITLS_PARSE_SERVER_NAME_ERR, /**< Failed to parse server_name. */ + HITLS_PARSE_CERT_ERR, /**< Failed to parse the certificate. */ + HITLS_PARSE_ECDH_PUBKEY_ERR, /**< Failed to parse the ecdh public key. */ + HITLS_PARSE_ECDH_SIGN_ERR, /**< Failed to parse the ecdh signature. */ + HITLS_PARSE_UNSUPPORT_KX_ALG, /**< Unsupported the key exchange algorithm. */ + HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE, /**< Unsupported ECC curve type. */ + HITLS_PARSE_GET_SIGN_PARA_ERR, /**< Failed to obtain the signature algorithm and hash algorithm */ + HITLS_PARSE_UNSUPPORT_SIGN_ALG, /**< Unsupported the signature algorithm. */ + HITLS_PARSE_VERIFY_SIGN_FAIL, /**< Failed to verify the signature. */ + HITLS_PARSE_DH_P_ERR, /**< Failed to parse the dh_p. */ + HITLS_PARSE_DH_G_ERR, /**< Failed to parse the dh_g. */ + HITLS_PARSE_DH_PUBKEY_ERR, /**< Failed to parse the DHE public key. */ + HITLS_PARSE_DH_SIGN_ERR, /**< Failed to parse the DHE signature. */ + HITLS_PARSE_UNSUPPORTED_EXTENSION, /**< Unsupported extended fields. */ + HTILS_PARSE_EXCESSIVE_MESSAGE_SIZE, /**< The length of the parsing exceeds the maximum. */ + HTILS_PARSE_PRE_SHARED_KEY_FAILED, /**< Failed to parse the PSK extension. */ + HTILS_PARSE_DUPLICATED_KEY_SHARE, /**< duplicated key share entry. */ + + HITLS_REASS_FAIL_START = 0x02070001, /**< Reassembly module error code start bit. */ + HITLS_REASS_INVALID_FRAGMENT, /**< Receives invalid fragmented messages. */ + + HITLS_CCS_FAIL_START = 0x02080001, /**< ccs module error code start bit. */ + HITLS_CCS_INVALID_CMD, /**< Invalid command. */ + + HITLS_ALERT_FAIL_START = 0x02090001, /**< alert module error code start bit. */ + HITLS_ALERT_NO_WANT_SEND, /**< No alert messages to be sent. */ + + HITLS_REC_FAIL_START = 0x020A0001, /**< record module error start bit. */ + HITLS_REC_PMTU_TOO_SMALL, /**< pmtu is too small to meet the record packet length. */ + HITLS_REC_ERR_BUFFER_NOT_ENOUGH, /**< Insufficient buffer. */ + HITLS_REC_ERR_TOO_BIG_LENGTH, /**< The length of the plaintext data to be written + exceeds the maximum length of a single record. */ + HITLS_REC_ERR_NOT_SUPPORT_CIPHER, /**< Unsupported the cipher suites. */ + HITLS_REC_ERR_ENCRYPT, /**< Encryption failed. */ + HITLS_REC_ERR_AEAD_NONCE_PARAM, /**< AEAD nonce input parameter is incorrect. */ + HITLS_REC_ERR_SN_WRAPPING, /**< Sequence number Rewind. */ + HITLS_REC_ERR_IO_EXCEPTION, /**< The low level I/O is abnormal. */ + HITLS_REC_NORMAL_IO_BUSY, /**< Low level I/O is busy, need wait for the next sending. */ + HITLS_REC_NORMAL_RECV_BUF_EMPTY, /**< The receiving buffer is empty. */ + HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, /**< If REC receives unexpected messages and the receiver is user, + needs to recall the previous function. */ + HITLS_REC_NORMAL_RECV_DISORDER_MSG, /**< The REC receives disordered records, + to receive disordered finished records. */ + HITLS_REC_INVLAID_RECORD, /**< record: invalid record message. */ + HITLS_REC_INVALID_PROTOCOL_VERSION, /**< record: Incorrect version. */ + HITLS_REC_BAD_RECORD_MAC, /**< record: Invalid MAC. */ + HITLS_REC_DECODE_ERROR, /**< Decoding failed. */ + HITLS_REC_RECORD_OVERFLOW, /**< Record is too long. */ + HITLS_REC_ERR_RECV_UNEXPECTED_MSG, /**< Record: unexpected message */ + HITLS_REC_ERR_GENERATE_MAC, /**< Failed to generate the MAC address. */ + HITLS_REC_NORMAL_IO_EOF, /**< IO object has reached EOF. */ + HITLS_REC_ENCRYPTED_NUMBER_OVERFLOW, /**< The number of AES-GCM encryption times cannot exceed 2^24.5. */ + HITLS_REC_ERR_MSAK_APP_MSG, /**< set app msg failure. */ + HITLS_REC_ERR_DATA_BETWEEN_CCS_AND_FINISHED, /**< When version is below TLS13, + must not have data between ccs and finished. */ + + HITLS_UIO_FAIL_START = 0x020B0001, /**< uio module error code start bit. */ + HITLS_UIO_FAIL, /**< UIO internal failure. */ + HITLS_UIO_IO_EXCEPTION, /**< Low level I/O exception. */ + HITLS_UIO_SCTP_IS_SND_BUF_EMPTY_FAIL, /**< Failed to obtain whether the sending buffer + of the UIO object is empty. */ + HITLS_UIO_SCTP_ADD_AUTH_KEY_FAIL, /**< Failed to add the auth key for the sctp UIO object. */ + HITLS_UIO_SCTP_ACTIVE_AUTH_KEY_FAIL, /**< Failed to activate the auth key for the sctp UIO object. */ + HITLS_UIO_SCTP_DEL_AUTH_KEY_FAIL, /**< Failed to delete the auth key for the sctp UIO object. */ + + HITLS_CERT_FAIL_START = 0x020C0001, /**< Certificate module error code start bit. */ + HITLS_CERT_STORE_ERR_NEW, /**< Failed to new certificate store. */ + HITLS_CERT_STORE_CTRL_ERR_SET_VERIFY_DEPTH, /**< Failed to set certificate store verify depth. */ + HITLS_CERT_STORE_CTRL_ERR_ADD_CERT_LIST, /**< Failed to add cert to certificate store. */ + HITLS_CERT_ERR_X509_DUP, /**< Failed to duplicate the certificate. */ + HITLS_CERT_ERR_KEY_DUP, /**< Failed to duplicate the key. */ + HITLS_CERT_ERR_STORE_DUP, /**< Failed to duplicate the store. */ + HITLS_CERT_ERR_CHAIN_DUP, /**< Failed to duplicate the certificate chain. */ + HITLS_CERT_CTRL_ERR_GET_ENCODE_LEN, /**< Failed to obtain the certificate encoding length. */ + HITLS_CERT_CTRL_ERR_GET_PUB_KEY, /**< Failed to obtain the certificate public key. */ + HITLS_CERT_CTRL_ERR_GET_SIGN_ALGO, /**< Failed to obtain the signature algorithm. */ + HITLS_CERT_KEY_CTRL_ERR_GET_SIGN_LEN, /**< Failed to obtain the signature length. */ + HITLS_CERT_KEY_CTRL_ERR_GET_TYPE, /**< Failed to obtain the key type. */ + HITLS_CERT_KEY_CTRL_ERR_GET_CURVE_NAME, /**< Failed to obtain the elliptic curve ID. */ + HITLS_CERT_KEY_CTRL_ERR_GET_POINT_FORMAT, /**< Failed to obtain the point format. */ + HITLS_CERT_KEY_CTRL_ERR_GET_SECBITS, /**< Failed to obtain security bits. */ + HITLS_CERT_KEY_CTRL_ERR_IS_ENC_USAGE, /**< Determine whether the certificate fails to be encrypted, + Applicable to Chinese secret scenarios. */ + HITLS_CERT_KEY_CTRL_ERR_IS_DIGITAL_SIGN_USAGE, /**< Determine whether the certificate fails to be digital sign. */ + HITLS_CERT_KEY_CTRL_ERR_IS_KEY_CERT_SIGN_USAGE, /**< Determine whether the certificate fails to be cert sign. */ + HITLS_CERT_KEY_CTRL_ERR_IS_KEY_AGREEMENT_USAGE, /**< Determine whether the certificate fails to be agreement. */ + HITLS_CERT_ERR_INVALID_KEY_TYPE, /**< Invalid key type */ + HITLS_CERT_ERR_CHECK_CERT_AND_KEY, /**< Certificate and private key nonmatch. */ + HITLS_CERT_ERR_NO_CURVE_MATCH, /**< Certificate and elliptic curve ID nonmatch. */ + HITLS_CERT_ERR_NO_POINT_FORMAT_MATCH, /**< Certificate and dot format nonmatch. */ + HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH, /**< Certificate and signature algorithm nonmatch. */ + HITLS_CERT_ERR_SELECT_CERTIFICATE, /**< Failed to select the certificate. */ + HITLS_CERT_ERR_BUILD_CHAIN, /**< Failed to construct the certificate chain. */ + HITLS_CERT_ERR_ENCODE_CERT, /**< Certificate encoding failure. */ + HITLS_CERT_ERR_PARSE_MSG, /**< Certificate decoding failure. */ + HITLS_CERT_ERR_VERIFY_CERT_CHAIN, /**< Certificate chain verification failure. */ + HITLS_CERT_ERR_CREATE_SIGN, /**< Failed to sign using the certificate private key. */ + HITLS_CERT_ERR_VERIFY_SIGN, /**< Failed to use the certificate public key + to verify the signature. */ + HITLS_CERT_ERR_ENCRYPT, /**< Failed to encrypt the RSA certificate public key. */ + HITLS_CERT_ERR_DECRYPT, /**< Failed to decrypt using the RSA Certificate Private Key */ + HITLS_CERT_ERR_ADD_CHAIN_CERT, /**< Failed to add the certificate chain. */ + HITLS_CERT_ERR_MGR_DUP, /**< Failed to duplicate the certificate management structure. */ + HITLS_CERT_ERR_INSECURE_SIG_ALG, /**< Insecure signature algorithm strength. */ + HITLS_CERT_ERR_CA_KEY_WITH_INSECURE_SECBITS, /**< Insecure CA certificate key security bits. */ + HITLS_CERT_ERR_EE_KEY_WITH_INSECURE_SECBITS, /**< Insecure EE certificate key security bits. */ + HITLS_CERT_ERR_EXP_CERT, /**< No expected certificate included. */ + HITLS_CERT_ERR_ENCODE, /**< Failed to encode the certificate. */ + HITLS_CERT_ERR_KEYUSAGE, /**< Failed to verify the certificate keyusage. */ + HITLS_CERT_ERR_INVALID_STORE_TYPE, /**< Invalid store type */ + HITLS_CERT_ERR_X509_REF, /**< Certificate reference counting error. */ + + HITLS_CRYPT_FAIL_START = 0x020D0001, /**< Crypt adaptation module error code start bit. */ + HITLS_CRYPT_ERR_GENERATE_RANDOM, /**< Failed to generate a random number. */ + HITLS_CRYPT_ERR_HMAC, /**< HMAC operation failure. */ + HITLS_CRYPT_ERR_DIGEST, /**< Hash operation failure. */ + HITLS_CRYPT_ERR_ENCRYPT, /**< Encryption failure. */ + HITLS_CRYPT_ERR_DECRYPT, /**< Decryption failure. */ + HITLS_CRYPT_ERR_ENCODE_ECDH_KEY, /**< Failed to obtain the ECDH public key. */ + HITLS_CRYPT_ERR_CALC_SHARED_KEY, /**< Failed to calculate the ECDH shared key. */ + HITLS_CRYPT_ERR_ENCODE_DH_KEY, /**< Failed to obtain the DH public key. */ + HITLS_CRYPT_ERR_HKDF_EXTRACT, /**< HKDF-Extract calculation error. */ + HITLS_CRYPT_ERR_HKDF_EXPAND, /**< HKDF-Expand calculation error. */ + + HITLS_APP_FAIL_START = 0x020E0001, /**< APP module error code start bit. */ + HITLS_APP_ERR_TOO_LONG_TO_WRITE, /**< APP Data written is too long. */ + HITLS_APP_ERR_ZERO_READ_BUF_LEN, /**< The buffer size read by the APP cannot be 0. */ + + HITLS_CLIENT_HELLO_CHECK_ERROR, /**< ClientHello callback detection failure. */ + + HITLS_SESS_FAIL_START = 0x020F0001, /**< Session feature error code start bit. */ + HITLS_SESS_ERR_SESSION_ID_GENRATE, /**< Session id output error. */ + HITLS_SESS_ERR_DECODE_TICKET, /**< Error decoding session ticket object. */ + HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT, /**< Session ticket length is incorrect. */ + HITLS_SESS_ERR_SESSION_TICKET_HMAC_FAIL, /**< Failed to calculate the session ticket hmac. */ + HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL, /**< Failed to obtain the ticket key, and then link + establishment failed, so needs to sent alert. */ + HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL, /**< Failed to verify the encoding result. */ + HITLS_SESS_ERR_ENC_MASTER_SECRET_FAIL, /**< Failed to encode the master secret. */ + HITLS_SESS_ERR_ENC_EXT_MASTER_SECRET_FAIL, /**< Failed to encode the extend master secret. */ + HITLS_SESS_ERR_ENC_SESSION_ID_FAIL, /**< Failed to encode the session ID. */ + HITLS_SESS_ERR_ENC_SESSION_ID_CTX_FAIL, /**< Failed to encode the session ID context. */ + HITLS_SESS_ERR_ENC_HOST_NAME_FAIL, /**< Failed to encode the host name. */ + HITLS_SESS_ERR_ENC_TIME_OUT_FAIL, /**< Failed to encode the time out. */ + HITLS_SESS_ERR_ENC_VERSION_FAIL, /**< Failed to encode the version. */ + HITLS_SESS_ERR_ENC_CIPHER_SUITE_FAIL, /**< Failed to encode the ciphersuite. */ + HITLS_SESS_ERR_ENC_START_TIME_FAIL, /**< Failed to encode the start time. */ + HITLS_SESS_ERR_ENC_PSK_IDENTITY_FAIL, /**< Failed to encode the PSK identity. */ + HITLS_SESS_ERR_DEC_VERIFY_RESULT_FAIL, /**< Failed to decode the verify result. */ + HITLS_SESS_ERR_DEC_VERSION_FAIL, /**< Failed to decode the version. */ + HITLS_SESS_ERR_DEC_CIPHER_SUITE_FAIL, /**< Fails to decode the cipher suite. */ + HITLS_SESS_ERR_DEC_MASTER_SECRET_FAIL, /**< Failed to decode the master secret. */ + HITLS_SESS_ERR_DEC_PSK_IDENTITY_FAIL, /**< Failed to decode the PSK identity. */ + HITLS_SESS_ERR_DEC_START_TIME_FAIL, /**< Failed to decode the start time. */ + HITLS_SESS_ERR_DEC_TIME_OUT_FAIL, /**< Failed to decode the time out. */ + HITLS_SESS_ERR_DEC_HOST_NAME_FAIL, /**< Failed to decode the host name. */ + HITLS_SESS_ERR_DEC_SESSION_ID_CTX_FAIL, /**< Failed to decode the session ID context. */ + HITLS_SESS_ERR_DEC_SESSION_ID_FAIL, /**< Failed to decode the session ID. */ + HITLS_SESS_ERR_DEC_EXT_MASTER_SECRET_FAIL, /**< Failed to decode the extended master secret. */ + HITLS_SESS_ERR_ENC_PEER_CERT_FAIL, /**< Failed to encode the peercert. */ + HITLS_SESS_ERR_DEC_PEER_CERT_FAIL, /**< Failed to decode the peercert. */ + + HITLS_X509_FAIL_START = 0x02100001, /**< The X509 feature error code start bit of. */ + HITLS_X509_V_ERR_UNSPECIFIED, + HITLS_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, + HITLS_X509_V_ERR_UNABLE_TO_GET_CRL, + HITLS_X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE, + HITLS_X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE, + HITLS_X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY, + HITLS_X509_V_ERR_CERT_SIGNATURE_FAILURE, + HITLS_X509_V_ERR_CRL_SIGNATURE_FAILURE, + HITLS_X509_V_ERR_CERT_NOT_YET_VALID, + HITLS_X509_V_ERR_CERT_HAS_EXPIRED, + HITLS_X509_V_ERR_CRL_NOT_YET_VALID, + HITLS_X509_V_ERR_CRL_HAS_EXPIRED, + HITLS_X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD, + HITLS_X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD, + HITLS_X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD, + HITLS_X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD, + HITLS_X509_V_ERR_OUT_OF_MEM, + HITLS_X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, + HITLS_X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, + HITLS_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, + HITLS_X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, + HITLS_X509_V_ERR_CERT_CHAIN_TOO_LONG, + HITLS_X509_V_ERR_CERT_REVOKED, + HITLS_X509_V_ERR_INVALID_CA, + HITLS_X509_V_ERR_PATH_LENGTH_EXCEEDED, + HITLS_X509_V_ERR_INVALID_PURPOSE, + HITLS_X509_V_ERR_CERT_UNTRUSTED, + HITLS_X509_V_ERR_CERT_REJECTED, + HITLS_X509_V_ERR_SUBJECT_ISSUER_MISMATCH, + HITLS_X509_V_ERR_AKID_SKID_MISMATCH, + HITLS_X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH, + HITLS_X509_V_ERR_KEYUSAGE_NO_CERTSIGN, + HITLS_X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER, + HITLS_X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, + HITLS_X509_V_ERR_KEYUSAGE_NO_CRL_SIGN, + HITLS_X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION, + HITLS_X509_V_ERR_INVALID_NON_CA, + HITLS_X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED, + HITLS_X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, + HITLS_X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED, + HITLS_X509_V_ERR_INVALID_EXTENSION, + HITLS_X509_V_ERR_INVALID_POLICY_EXTENSION, + HITLS_X509_V_ERR_NO_EXPLICIT_POLICY, + HITLS_X509_V_ERR_DIFFERENT_CRL_SCOPE, + HITLS_X509_V_ERR_ERROR_IN_CMP_CERT_NOT_AFTER_FIELD, + HITLS_X509_V_ERR_ERROR_IN_CMP_CRL_THIS_UPDATE_FIELD, + HITLS_X509_V_ERR_ERROR_IN_CMP_CRL_NEXT_UPDATE_FIELD, + HITLS_X509_V_ERR_ERROR_IN_CMP_CERT_NOT_BEFORE_FIELD, + HITLS_X509_V_ERR_CRL_PATH_VALIDATION_ERROR, + + HITLS_X509_ADAPT_ERR = 0x02200001, + HITLS_X509_ADAPT_BUILD_CERT_CHAIN_ERR, +} HITLS_ERROR; + +/** + * @ingroup hitls_error + * @brief Obtain the TLS operation error code. + * + * @param ctx [IN] TLS context + * @param ret [IN] Return value of the TLS interface called + * @retval HITLS_SUCCESS, No error. + * @retval HITLS_WANT_CONNECT, indicates that the connection is blocked. + * You can call HITLS_Connect to continue the connection, This problem is usually caused + * by the read and write operation failure. + * @retval HITLS_WANT_ACCEPT, indicates that the connection is blocked and the HITLS_Accept + * can be called to continue the connection. This problem is usually caused by the read and write operation failure. + * @retval HITLS_WANT_READ, indicates that the receiving buffer is empty and the interface + * can be called to continue receiving data. + * @retval HITLS_WANT_WRITE, indicates that the sending buffer is full and the interface + * can be called to continue sending data. + * @retval HITLS_ERR_TLS, An unrecoverable fatal error occurs in the TLS protocol, usually a protocol error. + * @retval HITLS_ERR_SYSCALL, An unrecoverable I/O error occurs. Generally, the I/O error is caused + * by the Low level receiving and receiving exception and an unknown error occurs. + */ +int32_t HITLS_GetError(const HITLS_Ctx *ctx, int32_t ret); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* end HITLS_ERROR_H */ diff --git a/include/tls/hitls_psk.h b/include/tls/hitls_psk.h new file mode 100644 index 00000000..b8954ade --- /dev/null +++ b/include/tls/hitls_psk.h @@ -0,0 +1,216 @@ +/* + * 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 hitls_psk + * @ingroup hitls + * @brief Basic functions for link establishment based on PSK + */ + +#ifndef HITLS_PSK_H +#define HITLS_PSK_H + +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_psk + * @brief PSK Maximum size of the identity message + */ +#define HITLS_IDENTITY_HINT_MAX_SIZE 128 +#define HITLS_PSK_FIND_SESSION_CB_SUCCESS 1 +#define HITLS_PSK_FIND_SESSION_CB_FAIL 0 +#define HITLS_PSK_USE_SESSION_CB_SUCCESS 1 +#define HITLS_PSK_USE_SESSION_CB_FAIL 0 + +/** + * @ingroup hitls_psk + * @brief Obtain the PSK prototype on the client. + * + * @param ctx [IN] Context. + * @param hint [IN] Message. + * @param identity [OUT] Identity information written back by the user. + * @param maxIdentityLen [IN] Maximum length of the identity buffer. + * @param psk [OUT] PSK information written back by the user. + * @param maxPskLen [IN] Maximum length of the psk buffer. + * @retval Return the PSK length. + */ +typedef uint32_t (*HITLS_PskClientCb)(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, + uint8_t *psk, uint32_t maxPskLen); + +/** + * @ingroup hitls_psk + * @brief Obtain the PSK prototype on the server. + * + * @param ctx [IN] Context. + * @param identity [IN] Identity information. + * @param psk [OUT] PSK information written back by the user. + * @param maxPskLen [IN] Maximum length of the psk buffer. + * @retval Return the PSK length. + */ +typedef uint32_t (*HITLS_PskServerCb)(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen); + +/** + * @ingroup hitls_psk + * @brief TLS1.3 server PSK negotiation callback + * + * @param ctx [IN] ctx context + * @param identity [OUT] Identity information + * @param identityLen [OUT] Identity information length + * @param session [OUT] session + * @retval HITLS_PSK_FIND_SESSION_CB_SUCCESS, if successful. + * HITLS_PSK_FIND_SESSION_CB_FAIL, if failed + */ +typedef int32_t (*HITLS_PskFindSessionCb)(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session); + +/** + * @ingroup hitls_psk + * @brief TLS1.3 client PSK negotiation callback + * + * @param ctx [IN] ctx context + * @param hashAlgo [IN] Hash algorithm + * @param id [IN] Identity information + * @param idLen [IN] Identity information length + * @param session [OUT] session + * @retval HITLS_PSK_USE_SESSION_CB_SUCCESS, if successful. + * HITLS_PSK_USE_SESSION_CB_FAIL, if failed + */ +typedef int32_t (*HITLS_PskUseSessionCb)(HITLS_Ctx *ctx, uint32_t hashAlgo, const uint8_t **id, + uint32_t *idLen, HITLS_Session **session); + +/** + * @ingroup hitls_psk + * @brief Set the PSK prompt information for PSK negotiation. + * + * @param config [OUT] config Context + * @param hint [IN] Hint + * @param hintSize [IN] Hint length + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetPskIdentityHint(HITLS_Config *config, const uint8_t *hint, uint32_t hintSize); + +/** + * @ingroup hitls_psk + * @brief Set the PSK callback function on the client, which is used to obtain the identity + * + * and PSK during PSK negotiation. + * @param config [OUT] config Context + * @param callback [IN] Client callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetPskClientCallback(HITLS_Config *config, HITLS_PskClientCb callback); + +/** + * @ingroup hitls_psk + * @brief Set the PSK callback on the server, which is used to obtain the PSK during PSK negotiation. + * + * @param config [OUT] config Context + * @param callback [IN] Client callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetPskServerCallback(HITLS_Config *config, HITLS_PskServerCb callback); + +/** + * @ingroup hitls_psk + * @brief Set the PSK callback function on the client, which is used to obtain the identity and PSK + * + * during PSK negotiation. + * @param ctx [OUT] TLS connection handle + * @param cb [IN] Client callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetPskClientCallback(HITLS_Ctx *ctx, HITLS_PskClientCb cb); + +/** + * @ingroup hitls_psk + * @brief Set the PSK callback on the server, which is used to obtain the PSK during PSK negotiation. + * + * @param ctx [OUT] TLS connection handle + * @param cb [IN] Server callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetPskServerCallback(HITLS_Ctx *ctx, HITLS_PskServerCb cb); + +/** + * @ingroup hitls_psk + * @brief Set the PSK identity hint on the server, which is used to provide identity hints for the + * + * client during PSK negotiation. + * @param ctx [OUT] TLS connection handle + * @param identityHint [IN] psk identity prompt + * @param identityHineLen [IN] psk Length of the identity message + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetPskIdentityHint(HITLS_Ctx *ctx, const uint8_t *identityHint, uint32_t identityHintLen); + +/** + * @ingroup hitls_psk + * @brief Set the server callback, which is used to restore the PSK session of TLS1.3, cb can be NULL. + * + * @param ctx [OUT] TLS connection handle + * @param callback [IN] Callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetPskFindSessionCallback(HITLS_Config *config, HITLS_PskFindSessionCb callback); + +/** + * @ingroup hitls_psk + * @brief Set the server callback, which is used to restore the PSK session of TLS1.3, cb can be NULL. + * + * @param ctx [OUT] TLS connection handle + * @param callback [IN] Callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetPskUseSessionCallback(HITLS_Config *config, HITLS_PskUseSessionCb callback); + +/** + * @ingroup hitls_psk + * @brief Set the server callback, which is used to restore the PSK session of TLS1.3, cb can be NULL. + * + * @param ctx [OUT] TLS connection handle + * @param cb [IN] Callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetPskFindSessionCallback(HITLS_Ctx *ctx, HITLS_PskFindSessionCb cb); + +/** + * @ingroup hitls_psk + * @brief Set the client callback, which is used to restore the PSK session of TLS1.3, cb can be NULL. + * + * @param ctx [OUT] TLS connection handle + * @param cb [IN] Callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetPskUseSessionCallback(HITLS_Ctx *ctx, HITLS_PskUseSessionCb cb); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/tls/hitls_security.h b/include/tls/hitls_security.h new file mode 100644 index 00000000..b4be8d98 --- /dev/null +++ b/include/tls/hitls_security.h @@ -0,0 +1,263 @@ +/* + * 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 hitls_security + * @ingroup hitls + * @brief TLS security features + */ + +#ifndef HITLS_SECURITY_H +#define HITLS_SECURITY_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_security + * + * HiTLS default level of security. You can configure the default level by using the compilation macro. + * If the compilation macro is not defined, the default level 0 is used. + */ + +#ifndef HITLS_DEFAULT_SECURITY_LEVEL +#define HITLS_DEFAULT_SECURITY_LEVEL 0 +#endif + +/* security level */ +#define HITLS_SECURITY_LEVEL_ZERO 0 +#define HITLS_SECURITY_LEVEL_ONE 1 +#define HITLS_SECURITY_LEVEL_TWO 2 +#define HITLS_SECURITY_LEVEL_THREE 3 +#define HITLS_SECURITY_LEVEL_FOUR 4 +#define HITLS_SECURITY_LEVEL_FIVE 5 +#define HITLS_SECURITY_LEVEL_MIN HITLS_SECURITY_LEVEL_ZERO +#define HITLS_SECURITY_LEVEL_MAX HITLS_SECURITY_LEVEL_FIVE + +/* security strength */ +#define HITLS_SECURITY_LEVEL_ONE_SECBITS 80 +#define HITLS_SECURITY_LEVEL_TWO_SECBITS 112 +#define HITLS_SECURITY_LEVEL_THREE_SECBITS 128 +#define HITLS_SECURITY_LEVEL_FOUR_SECBITS 192 +#define HITLS_SECURITY_LEVEL_FIVE_SECBITS 256 + +/* What the "other" parameter contains in security callback */ +/* Mask for type */ +# define HITLS_SECURITY_SECOP_OTHER_TYPE 0xffff0000 +# define HITLS_SECURITY_SECOP_OTHER_NONE 0 +# define HITLS_SECURITY_SECOP_OTHER_CIPHER (1 << 16) +# define HITLS_SECURITY_SECOP_OTHER_CURVE (2 << 16) +# define HITLS_SECURITY_SECOP_OTHER_DH (3 << 16) +# define HITLS_SECURITY_SECOP_OTHER_PKEY (4 << 16) +# define HITLS_SECURITY_SECOP_OTHER_SIGALG (5 << 16) +# define HITLS_SECURITY_SECOP_OTHER_CERT (6 << 16) + +/* Indicated operation refers to peer key or certificate */ +# define HITLS_SECURITY_SECOP_PEER 0x1000 + +/* Called to filter ciphers */ +/* Ciphers client supports */ +# define HITLS_SECURITY_SECOP_CIPHER_SUPPORTED (1 | HITLS_SECURITY_SECOP_OTHER_CIPHER) +/* Cipher shared by client/server */ +# define HITLS_SECURITY_SECOP_CIPHER_SHARED (2 | HITLS_SECURITY_SECOP_OTHER_CIPHER) +/* Sanity check of cipher server selects */ +# define HITLS_SECURITY_SECOP_CIPHER_CHECK (3 | HITLS_SECURITY_SECOP_OTHER_CIPHER) +/* Curves supported by client */ +# define HITLS_SECURITY_SECOP_CURVE_SUPPORTED (4 | HITLS_SECURITY_SECOP_OTHER_CURVE) +/* Curves shared by client/server */ +# define HITLS_SECURITY_SECOP_CURVE_SHARED (5 | HITLS_SECURITY_SECOP_OTHER_CURVE) +/* Sanity check of curve server selects */ +# define HITLS_SECURITY_SECOP_CURVE_CHECK (6 | HITLS_SECURITY_SECOP_OTHER_CURVE) +/* Temporary DH key */ +# define HITLS_SECURITY_SECOP_TMP_DH (7 | HITLS_SECURITY_SECOP_OTHER_PKEY) +/* SSL/TLS version */ +# define HITLS_SECURITY_SECOP_VERSION (9 | HITLS_SECURITY_SECOP_OTHER_NONE) +/* Session tickets */ +# define HITLS_SECURITY_SECOP_TICKET (10 | HITLS_SECURITY_SECOP_OTHER_NONE) +/* Supported signature algorithms sent to peer */ +# define HITLS_SECURITY_SECOP_SIGALG_SUPPORTED (11 | HITLS_SECURITY_SECOP_OTHER_SIGALG) +/* Shared signature algorithm */ +# define HITLS_SECURITY_SECOP_SIGALG_SHARED (12 | HITLS_SECURITY_SECOP_OTHER_SIGALG) +/* Sanity check signature algorithm allowed */ +# define HITLS_SECURITY_SECOP_SIGALG_CHECK (13 | HITLS_SECURITY_SECOP_OTHER_SIGALG) +/* Used to get mask of supported public key signature algorithms */ +# define HITLS_SECURITY_SECOP_SIGALG_MASK (14 | HITLS_SECURITY_SECOP_OTHER_SIGALG) +/* Use to see if compression is allowed */ +# define HITLS_SECURITY_SECOP_COMPRESSION (15 | HITLS_SECURITY_SECOP_OTHER_NONE) +/* EE key in certificate */ +# define HITLS_SECURITY_SECOP_EE_KEY (16 | HITLS_SECURITY_SECOP_OTHER_CERT) +/* CA key in certificate */ +# define HITLS_SECURITY_SECOP_CA_KEY (17 | HITLS_SECURITY_SECOP_OTHER_CERT) +/* CA digest algorithm in certificate */ +# define HITLS_SECURITY_SECOP_CA_MD (18 | HITLS_SECURITY_SECOP_OTHER_CERT) +/* Peer EE key in certificate */ +# define HITLS_SECURITY_SECOP_PEER_EE_KEY (HITLS_SECURITY_SECOP_EE_KEY | HITLS_SECURITY_SECOP_PEER) +/* Peer CA key in certificate */ +# define HITLS_SECURITY_SECOP_PEER_CA_KEY (HITLS_SECURITY_SECOP_CA_KEY | HITLS_SECURITY_SECOP_PEER) +/* Peer CA digest algorithm in certificate */ +# define HITLS_SECURITY_SECOP_PEER_CA_MD (HITLS_SECURITY_SECOP_CA_MD | HITLS_SECURITY_SECOP_PEER) + +/** + * @ingroup hitls_security + * @brief Secure Callback Function Prototype + * + * @param ctx [IN] context + * @param config [IN] context + * @param option [IN] indicates the options to be checked, such as the version, certificate, temporary key, + * signature algorithm, support group, and session ticket... + * @param bits [IN] Number of security bits, which is used to check the level of security of the key. + * @param id [IN] Indicates the ID to be checked, such as the version ID, signature algorithm ID, + * and support group ID. Input based on the options that need to be checked. + * @param other [IN] Parameters to be checked, such as cipher suites, certificates, and signature algorithms. + * @param exData [IN] Input the data as required. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes,see hitls_error.h + */ +typedef int32_t (*HITLS_SecurityCb)(const HITLS_Ctx *ctx, const HITLS_Config *config, int32_t option, + int32_t bits, int32_t id, void *other, void *exData); + +/** + * @ingroup hitls_security + * @brief Configure the security level + * + * @param config [IN/OUT] Config context + * @param securityLevel [IN] Security level + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h + */ +int32_t HITLS_CFG_SetSecurityLevel(HITLS_Config *config, int32_t securityLevel); + +/** + * @ingroup hitls_security + * @brief Obtain the configured security level. + * + * @param config [IN] Config context + * @param securityLevel [OUT] Security Context + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h + */ +int32_t HITLS_CFG_GetSecurityLevel(const HITLS_Config *config, int32_t *securityLevel); + +/** + * @ingroup hitls_security + * @brief Configure the security callback function. + * + * @param config [IN/OUT] Config context + * @param securityCb [IN] Security callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSecurityCb(HITLS_Config *config, HITLS_SecurityCb securityCb); + +/** + * @ingroup hitls_security + * @brief Obtain the configured security callback function + * + * @param config [IN] Config context + * @retval Security callback function HITLS_SecurityCb. + */ +HITLS_SecurityCb HITLS_CFG_GetSecurityCb(const HITLS_Config *config); + +/** + * @ingroup hitls_security + * @brief Configuring the Security ExData + * + * @param config [IN/OUT] Config context + * @param securityExData [IN] Security ExData + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h + */ +int32_t HITLS_CFG_SetSecurityExData(HITLS_Config *config, void *securityExData); + +/** + * @ingroup hitls_security + * @brief Obtain the configured Security ExData + * + * @param config [IN] Config context + * @retval Security ExData + */ +void *HITLS_CFG_GetSecurityExData(const HITLS_Config *config); + +/** + * @ingroup hitls_security + * @brief Set the link security level + * + * @param ctx [IN/OUT] Ctx context + * @param securityLevel [IN] Security level + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h + */ +int32_t HITLS_SetSecurityLevel(HITLS_Ctx *ctx, int32_t securityLevel); + +/** + * @ingroup hitls_security + * @brief Obtain the link security level + * + * @param ctx [IN] Ctx context + * @param securityLevel [OUT] Security level + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h + */ +int32_t HITLS_GetSecurityLevel(const HITLS_Ctx *ctx, int32_t *securityLevel); + +/** + * @ingroup hitls_security + * @brief Callback function for setting link security + * + * @param ctx [IN/OUT] Ctx context + * @param securityCb [IN] Security callback function + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h + */ +int32_t HITLS_SetSecurityCb(HITLS_Ctx *ctx, HITLS_SecurityCb securityCb); + +/** + * @ingroup hitls_security + * @brief Obtain the Security callback function of the link + * + * @param ctx [IN] Ctx context + * @retval Security callback HITLS_SecurityCb. + */ +HITLS_SecurityCb HITLS_GetSecurityCb(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_security + * @brief Setting Security ExData for the Link + * + * @param ctx [IN/OUT] Ctx context + * @param securityExData [IN] Security ExData + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, hitls_error.h + */ +int32_t HITLS_SetSecurityExData(HITLS_Ctx *ctx, void *securityExData); + +/** + * @ingroup hitls_security + * @brief Obtains the configured Security ExData. + * + * @param ctx [IN] Ctx context + * @retval Security ExData + */ +void *HITLS_GetSecurityExData(const HITLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end HITLS_SECURITY_H */ \ No newline at end of file diff --git a/include/tls/hitls_session.h b/include/tls/hitls_session.h new file mode 100644 index 00000000..6d3cd006 --- /dev/null +++ b/include/tls/hitls_session.h @@ -0,0 +1,623 @@ +/* + * 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 hitls_session + * @ingroup hitls + * @brief TLS session + */ + +#ifndef HITLS_SESSION_H +#define HITLS_SESSION_H + +#include +#include +#include +#include "hitls_type.h" +#include "hitls_crypt_type.h" +#include "bsl_uio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_session + * @brief Session id Maximum size of the CTX. + */ +#define HITLS_SESSION_ID_CTX_MAX_SIZE 32u + +/** + * @ingroup hitls_session + * @brief Maximum size of a session ID + */ +#define HITLS_SESSION_ID_MAX_SIZE 32u + +/** + * @ingroup hitls_session + * @brief Set whether to support the session ticket function. + * + * @param config [OUT] Config handle + * @param support [IN] Whether to support the session ticket. The options are as follows: true: yes; false: no. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetSessionTicketSupport(HITLS_Config *config, bool support); + +/** + * @ingroup hitls_session + * @brief Query whether the session ticket function is supported. + * + * @param config [IN] Config handle + * @param isSupport [OUT] Whether to support the session ticket. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_GetSessionTicketSupport(const HITLS_Config *config, uint8_t *isSupport); + +/** + * @ingroup hitls_session + * @brief Setting TLS1.3, number of new session tickets sent after a complete link is established. + * + * This interface should be called before handshake. The default number is 2. + * If the number is greater than or equal to 1, only one ticket is sent after the session is resumed. + * When this parameter is set to 0, the ticket is not sent for the complete handshake and session resumption. + * + * @param config [OUT] Config handle + * @param ticketNums [IN] Number of new session tickets sent. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is empty. + */ +int32_t HITLS_CFG_SetTicketNums(HITLS_Config *config, uint32_t ticketNums); + +/** + * @ingroup hitls_session + * @brief Obtain TLS1.3, number of new session tickets sent after complete link establishment. + * + * @param config [IN] config handle + * @retval Number of tickets. + */ +uint32_t HITLS_CFG_GetTicketNums(HITLS_Config *config); + +/** + * @ingroup hitls_session + * @brief Setting TLS1.3, number of new session tickets sent after complete link establishment. + * + * This interface should be called before handshake. The default number is 2. + * If the number is greater than or equal to 1, only one ticket is sent after the session is resumed. + * When this parameter is set to 0, tickets will not be sent for the complete handshake and session recovery. + * + * @param config [OUT] ctx context + * @param ticketNums [IN] Number of sent new session tickets. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, ctx is null. + */ +int32_t HITLS_SetTicketNums(HITLS_Ctx *ctx, uint32_t ticketNums); + +/** + * @ingroup hitls_session + * @brief Obtain TLS1.3, Number of new session tickets sent after complete link establishment. + * + * @param ctx [IN] ctx context + * @retval Number of tickets. + */ +uint32_t HITLS_GetTicketNums(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_session + * @brief This callback is called when a new session is negotiated. Users can use sessions. + * + * @param ctx [IN] ctx context + * @param session [IN] Session handle + * @retval 1 Success. If a user removes a session, the user needs to release the session handle. + * @retval 0 failed. The user does not use the session. + */ +typedef int32_t (*HITLS_NewSessionCb) (HITLS_Ctx *ctx, HITLS_Session *session); + +/** + * @ingroup hitls_session + * @brief Set a callback for negotiating a new session call. + * + * @param config [OUT] config handle + * @param newSessionCb [IN] Callback. + * @retval HITLS_SUCCESS, if successful. + * @retval HITLS_NULL_INPUT, config is null. + */ +int32_t HITLS_CFG_SetNewSessionCb(HITLS_Config *config, HITLS_NewSessionCb newSessionCb); + +#define HITLS_TICKET_KEY_RET_NEED_ALERT (-1) // callback fails. A fatal error occurs. + // You need to send an alert +#define HITLS_TICKET_KEY_RET_FAIL 0 // callback returns a failure, but the error is not a fatal error, + // for example, key_name matching fails. +#define HITLS_TICKET_KEY_RET_SUCCESS 1 // If the callback is successful, + // the key can be used for encryption and decryption +#define HITLS_TICKET_KEY_RET_SUCCESS_RENEW 2 // If the callback is successful, the key can be used for encryption + // and decryption. In the decryption scenario, + // the ticket needs to be renewed +/** + * @ingroup hitls_session + * @brief Obtain and verify ticket_key on the server. + * + * @attention keyName is fixed at 16 bytes, and iv is fixed at 16 bytes. + * During encryption, the keyName and cipher need to be returned. + * The encryption type, encryption algorithm, key, iv, and hmacKey need to be filled in. + * During decryption, the HiTLS transfers the keyName. + * The user needs to find the corresponding key based on the keyName and return the corresponding encryption type, + * encryption algorithm, and key. (HiTLS uses the iv value sent by the client, + * so the iv value does not need to be returned.) + * + * @param keyName [IN/OUT] name values corresponding to aes_key and hmac_key + * @param keyNameSize [IN] length of keyName + * @param cipher [IN/OUT] Encryption information + * @param isEncrypt [IN] Indicates whether to encrypt data. true: encrypt data. false: decrypt data. + * + * @retval TICKET_KEY_RET_NEED_ALERT : indicates that the function fails to be called. A fatal error occurs. + * An alert message needs to be sent. + * TICKET_KEY_RET_FAIL : During encryption, the failure to obtain the key_name is not a fatal error. + * In this case, the HiTLS sends an empty new session ticket message + * to the client.During decryption, the key_name matching fails, + * but it is not a fatal error. If the return value is the same, + * the HiTLS performs a complete handshake process or uses the + * session ID to restore the session. + * TICKET_KEY_RET_SUCCESS : indicates that the encryption is successful. Decryption succeeds. + * TICKET_KEY_RET_SUCCESS_RENEW : indicates that the encryption is successful. + * The value is the same as the returned value TICKET_KEY_RET_SUCCESS. + * If the decryption succeeds and the ticket needs to be renewed or changed, + * the HiTLS calls the callback again to encrypt the ticket + * when sending a new session ticket. + */ +typedef int32_t (*HITLS_TicketKeyCb)(uint8_t *keyName, uint32_t keyNameSize, HITLS_CipherParameters *cipher, + uint8_t isEncrypt); + +/** + * @ingroup hitls_session + * @brief Set the ticket key callback, which is used only by the server, cb can be NULL. + * + * @param config [OUT] Config Context + * @param callback [IN] Ticket key callback + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetTicketKeyCallback(HITLS_Config *config, HITLS_TicketKeyCb callback); + +/** + * @ingroup hitls_session + * @brief Obtain the default ticket key of the HiTLS. + * + * The key is used to encrypt and decrypt the ticket in the new session ticket when the HITLS_TicketKeyCb callback + * function is not set. + * + * @attention The returned key value is as follows: 16-byte key name + 32-byte AES key + 32-byte HMAC key + * + * @param config [IN] Config Context. + * @param key [OUT] Obtained ticket key. + * @param keySize [IN] Size of the key array. + * @param outSize [OUT] Size of the obtained ticket key. + * + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetSessionTicketKey(const HITLS_Config *config, uint8_t *key, uint32_t keySize, uint32_t *outSize); + +/** + * @ingroup hitls_session + * @brief Set the default ticket key of the HiTLS. The key is used to encrypt and decrypt tickets in the new + * session ticket when the HITLS_TicketKeyCb callback function is not set. + * + * @attention The returned key value is as follows: 16-byte key name + 32-byte AES key + 32-byte HMAC key + * + * @param config [OUT] Config Context. + * @param key [IN] Ticket key to be set. + * @param keySize [IN] Size of the ticket key. + * + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSessionTicketKey(HITLS_Config *config, const uint8_t *key, uint32_t keySize); + +/** + * @ingroup hitls_session + * @brief Set the user-specific session ID ctx, only on the server. + * + * @attention session id ctx is different from session id, session recovery can be performed only after + * session id ctx matching. + * @param config [OUT] Config context. + * @param sessionIdCtx [IN] Session ID Context. + * @param len [IN] Session id context length, a maximum of 32 bytes. + * @retval HITLS_SUCCESS, if successful. + * For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSessionIdCtx(HITLS_Config *config, const uint8_t *sessionIdCtx, uint32_t len); + +/** + * @ingroup hitls_session + * @brief Set the session cache mode. + * + * @param config [OUT] Config context. + * @param mode [IN] Cache mode, corresponding to the HITLS_SESS_CACHE_MODE enumerated value. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSessionCacheMode(HITLS_Config *config, HITLS_SESS_CACHE_MODE mode); + +/** + * @ingroup hitls_session + * @brief Obtain the session cache mode. + * + * @param config [IN] config Context. + * @param mode [OUT] Cache mode, corresponding to the HITLS_SESS_CACHE_MODE enumerated value. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetSessionCacheMode(HITLS_Config *config, HITLS_SESS_CACHE_MODE *mode); + +/** + * @ingroup hitls_session + * @brief Set the maximum number of sessions in the session cache. + * + * @param config [OUT] Config context. + * @param size [IN] Maximum number of sessions in the cache. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSessionCacheSize(HITLS_Config *config, uint32_t size); + +/** + * @ingroup hitls_session + * @brief Obtain the maximum number of sessions in the session cache. + * + * @param config [IN] Config context. + * @param size [OUT] Maximum number of sessions in the cache. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetSessionCacheSize(HITLS_Config *config, uint32_t *size); + +/** + * @ingroup hitls_session + * @brief Set the session timeout interval. + * + * @param config [OUT] Config context. + * @param timeout [IN] Session timeout interval, in seconds. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetSessionTimeout(HITLS_Config *config, uint64_t timeout); + +/** + * @ingroup hitls_session + * @brief Obtain the timeout interval of a session. + * + * @param config [IN] Config context. + * @param timeout [OUT] Session timeout interval, in seconds. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetSessionTimeout(const HITLS_Config *config, uint64_t *timeout); + +/** + * @ingroup hitls_session + * @brief Whether the link is multiplexed with a session. + * + * @param ctx [IN] config Context. + * @param isReused [OUT] Indicates whether to reuse a session. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_IsSessionReused(HITLS_Ctx *ctx, uint8_t *isReused); + +/** + * @ingroup hitls_session + * @brief Set the user-specific session ID ctx of the HiTLS link, only on the server. + * + * @attention session id ctx is different from sessio id, session recovery can be performed only after + * session id ctx matching. + * @param ctx [OUT] Config context. + * @param sessionIdCtx [IN] Session ID Context. + * @param len [IN] Session ID context length, which cannot exceed 32 bytes. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_SetSessionIdCtx(HITLS_Ctx *ctx, const uint8_t *sessionIdCtx, uint32_t len); + +/** + * @ingroup hitls_session + * @brief Obtain the default ticket key of the HiTLS. + * + * The key is used to encrypt and decrypt the ticket in the new session ticket + * when the HITLS_TicketKeyCb callback function is not set. + * + * @attention The returned key value is as follows: 16-byte key name + 32-byte AES key + 32-byte HMAC key + * + * @param ctx [OUT] TLS connection handle + * @param key [OUT] Obtained ticket key + * @param keySize [IN] Size of the key array + * @param outSize [OUT] Size of the obtained ticket key. + * + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_GetSessionTicketKey(const HITLS_Ctx *ctx, uint8_t *key, uint32_t keySize, uint32_t *outSize); + +/** + * @ingroup hitls_session + * @brief Set the default ticket key of the HiTLS. The key is used to encrypt and decrypt the ticket + * in the new session ticket when the HITLS_TicketKeyCb callback function is not set. + * + * @attention The returned key value is as follows: 16-byte key name + 32-byte AES key + 32-byte HMAC key + * + * @param ctx [OUT] TLS connection handle. + * @param key [IN] Ticket key to be set. + * @param keySize [IN] Size of the ticket key. + * + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetSessionTicketKey(HITLS_Ctx *ctx, const uint8_t *key, uint32_t keySize); + +/** + * @ingroup hitls_session + * @brief Set the handle for the session information about the HiTLS link. + * + * @attention Used only by the client. + * @param ctx [OUT] TLS connection handle + * @param session [IN] Session information handle. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SetSession(HITLS_Ctx *ctx, HITLS_Session *session); + +/** + * @ingroup hitls_session + * @brief Obtain the handle of the session information and directly obtain the pointer. + * + * @attention Directly obtain the pointer. + * Ensure that the invoking is correct and avoid the pointer being a wild pointer. + * @param ctx [IN] TLS connection handle + * @retval Session information handle + */ +HITLS_Session *HITLS_GetSession(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_session + * @brief Obtain the handle of the copied session information. + * + * @attention The number of times that the call is called increases by 1. + * The call is released by calling HITLS_SESS_Free. + * @param ctx [IN] TLS connection handle + * @retval Session information handle + */ +HITLS_Session *HITLS_GetDupSession(HITLS_Ctx *ctx); + +/** + * @ingroup hitls_session + * @brief Obtain the sign type of the peer + * + * @param ctx [IN] TLS connection handle + * @param sigType [OUT] sign type. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_GetPeerSignatureType(const HITLS_Ctx *ctx, HITLS_SignAlgo *sigType); + +/** + * @ingroup hitls_session + * @brief Apply for a new session. + * + * @param void + * @retval Session handle. + */ +HITLS_Session *HITLS_SESS_New(void); + +/** + * @ingroup hitls_session + * @brief Duplicate a session, the number of reference times increases by 1. + * + * @param sess + * @retval Session handle. + */ +HITLS_Session *HITLS_SESS_Dup(HITLS_Session *sess); + +/** + * @ingroup hitls_session + * @brief Release the session information handle. + * + * @param sess [IN] Session information handle + * @retval void + */ +void HITLS_SESS_Free(HITLS_Session *sess); + +/** + * @ingroup hitls_session + * @brief Set the master key of a session. + * + * @param sess [OUT] Session information handle. + * @param masterKey [IN] Master key. + * @param masterKeySize [IN] Size of the master key. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetMasterKey(HITLS_Session *sess, const uint8_t *masterKey, uint32_t masterKeySize); + +/** + * @ingroup hitls_session + * @brief Obtain the master key length of a session. + * + * @param sess [IN] Session information handle + * @retval Size of the master key + */ +uint32_t HITLS_SESS_GetMasterKeyLen(const HITLS_Session *sess); + +/** + * @ingroup hitls_session + * @brief Obtain the master key of a session. + * + * @param sess [IN] Session information handle. + * @param masterKey [OUT] Master key. + * @param masterKeySize [OUT] Size of the master key. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_GetMasterKey(const HITLS_Session *sess, uint8_t *masterKey, uint32_t *masterKeySize); + +/** + * @ingroup hitls_session + * @brief Obtain the session protocol version. + * + * @param sess [IN] Session information handle. + * @param version [OUT] Protocol version. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_GetProtocolVersion(const HITLS_Session *sess, uint16_t *version); + +/** + * @ingroup hitls_session + * @brief Set the session protocol version. + * + * @param sess [OUT] Session information handle + * @param version [IN] Protocol version + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetProtocolVersion(HITLS_Session *sess, uint16_t version); + +/** + * @ingroup hitls_session + * @brief Set the session password suite. + * + * @param sess [OUT] Session information handle. + * @param cipherSuite [IN] Password suite. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetCipherSuite(HITLS_Session *sess, uint16_t cipherSuite); + +/** + * @ingroup hitls_session + * @brief Obtain the session password suite. + * + * @param sess [IN] Session information handle. + * @param cipherSuite [OUT] Cipher suite. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_GetCipherSuite(HITLS_Session *sess, uint16_t *cipherSuite); + +/** + * @ingroup hitls_session + * @brief Set the session ID ctx. + * + * @param sess [OUT] Session information handle. + * @param sessionIdCtx [IN] Session ID Context. + * @param sessionIdCtxSize [IN] Session ID Context length. The maximum length is 32 bytes. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetSessionIdCtx(HITLS_Session *sess, uint8_t *sessionIdCtx, uint32_t sessionIdCtxSize); + +/** + * @ingroup hitls_session + * @brief Obtain the session ID ctx. + * + * @param sess [IN] Session information handle. + * @param sessionIdCtx [OUT] Session ID Context. + * @param sessionIdCtxSize [OUT] Session id Context length. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. +*/ +int32_t HITLS_SESS_GetSessionIdCtx(const HITLS_Session *sess, uint8_t *sessionIdCtx, uint32_t *sessionIdCtxSize); + +/** + * @ingroup hitls_session + * @brief Set the session ID. + * + * @param sess [OUT] Session information handle. + * @param sessionId [IN] Session id. + * @param sessionIdSize [IN] The session ID contains a maximum of 32 bytes. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetSessionId(HITLS_Session *sess, uint8_t *sessionId, uint32_t sessionIdSize); + +/** + * @ingroup hitls_session + * @brief Obtain the session ID. + * + * @param sess [IN] Session information handle + * @param sessionId [OUT] Session id + * @param sessionIdSize [OUT] Session ID length + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_GetSessionId(const HITLS_Session *sess, uint8_t *sessionId, uint32_t *sessionIdSize); + +/** + * @ingroup hitls_session + * @brief Set whether to contain the master key extension. + * + * @param sess [OUT] Session information handle. + * @param haveExtMasterSecret [IN] Whether the master key extension is include. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetHaveExtMasterSecret(HITLS_Session *sess, uint8_t haveExtMasterSecret); + +/** + * @ingroup hitls_session + * @brief Obtain the master key extension. + * + * @param sess [IN] Session information handle. + * @param haveExtMasterSecret [OUT] Whether the master key extension is contained. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_GetHaveExtMasterSecret(HITLS_Session *sess, uint8_t *haveExtMasterSecret); + +/** + * @ingroup hitls_session + * @brief Set the timeout interval, in seconds. + * + * @param sess [OUT] Session information handle + * @param timeout [IN] Timeout interval, in seconds. + * @retval HITLS_SUCCESS, if successful. + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_SESS_SetTimeout(HITLS_Session *sess, uint64_t timeout); + +/** + * @ingroup hitls_session + * @brief Check whether the session can be recovered. Only simple check is performed, but the validity period + * is not checked. + * + * @param sess [IN] Session information handle. + * @retval Indicates whether the recovery can be performed. + */ +bool HITLS_SESS_IsResumable(const HITLS_Session *sess); + +/** + * @ingroup hitls_session + * @brief Check whether the session has a ticket. + * + * @param sess [IN] Session information handle + * @retval Indicates whether a ticket exists. + */ +bool HITLS_SESS_HasTicket(const HITLS_Session *sess); + +#ifdef __cplusplus +} +#endif + +#endif /* HITLS_SESSION_H */ diff --git a/include/tls/hitls_sni.h b/include/tls/hitls_sni.h new file mode 100644 index 00000000..98a6fd15 --- /dev/null +++ b/include/tls/hitls_sni.h @@ -0,0 +1,154 @@ +/* + * 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 hitls_sni + * @ingroup hitls + * @brief TLS SNI correlation type + */ + +#ifndef HITLS_SNI_H +#define HITLS_SNI_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* Currently, the SNI supports only the host name type. */ + +/** + * @ingroup hitls_sni + * @brief Currently, the SNI supports only the host name type. + */ +typedef enum { + HITLS_SNI_HOSTNAME_TYPE, + HITLS_SNI_BUTT = 255 /**< Maximum enumerated value. */ +} SNI_Type; + +#define HITLS_ACCEPT_SNI_ERR_OK 0 /* Accepts the request and continues handshake. */ +#define HITLS_ACCEPT_SNI_ERR_ALERT_FATAL 2 /* Do not accept the request and aborts the handshake. */ +#define HITLS_ACCEPT_SNI_ERR_NOACK 3 /* Do not accept the request but continues the handshake. */ + +/** + * @ingroup hitls_sni + * @brief Obtain the value of server_name before, during, or after the handshake on the client or server. + * + * @param ctx [IN] TLS connection handle + * @param type [IN] serverName type + * @retval The value of server_name, if successful. + * NULL, if failure. + */ +const char *HITLS_GetServerName(const HITLS_Ctx *ctx, const int type); + +/** + * @ingroup hitls_sni + * @brief Obtain the server_name type before, during, or after the handshake on the client or server. + * + * @param ctx [IN] TLS connection handle + * @retval HITLS_SNI_HOSTNAME_TYPE, if successful. + * -1: if failure. + */ +int32_t HITLS_GetServernameType(const HITLS_Ctx *ctx); + +/** + * @ingroup hitls_sni + * @brief Set server_name. + * + * @param config [OUT] config Context + * @param serverName [IN] serverName + * @param serverNameStrlen [IN] serverName length + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetServerName(HITLS_Config *config, uint8_t *serverName, uint32_t serverNameStrlen); + +/** + * @ingroup hitls_sni + * @brief Obtain the value of server_name configured on the client. + * + * @param config [IN] config Context + * @param serverName [OUT] serverName + * @param serverNameStrlen [OUT] serverName length + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetServerName(HITLS_Config *config, uint8_t **serverName, uint32_t *serverNameStrlen); + +/** + * @ingroup hitls_sni + * @brief Set the extension prototype for the server to process Client Hello server_name. + * + * @param ctx [IN] ctx context. + * @param alert [IN] Warning information. + * @param arg [IN] The server supports the input parameters related to server_name. + * @retval The user return value contains: + * HITLS_ACCEPT_SNI_ERR_OK 0 (received, server_name null extension) + * HITLS_ACCEPT_SNI_ERR_ALERT_FATAL 2 (Do not accept, abort handshake) + * HITLS_ACCEPT_SNI_ERR_NOACK 3 (not accepted, but continue handshake, not sending server_name null extension) + */ +typedef int32_t (*HITLS_SniDealCb)(HITLS_Ctx *ctx, int *alert, void *arg); + +/** + * @ingroup hitls_sni + * @brief Set the server_name callback function on the server, which is used for SNI negotiation, cb can be NULL. + * + * @param config [OUT] Config Context + * @param callback [IN] Server callback implemented by the user + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetServerNameCb(HITLS_Config *config, HITLS_SniDealCb callback); + +/** + * @ingroup hitls_sni + * @brief Set the server_name parameters required during SNI negotiation on the server. + * + * @param ctx [OUT] ctx context + * @param arg [IN] Set parameters related to server_name. + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_SetServerNameArg(HITLS_Config *config, void *arg); + +/** + * @ingroup hitls_sni + * @brief Obtain the server_name callback settings on the server. + * + * @param config [IN] config Context + * @param callback [IN] [OUT] Server callback implemented by the user + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetServerNameCb(HITLS_Config *config, HITLS_SniDealCb *callback); + +/** + * @ingroup hitls_sni + * @brief Obtain the server_name required during SNI negotiation on the server, related Parameter arg. + * + * @param ctx [IN] ctx context + * @param arg [IN] [OUT] Set parameters related to server_name.arg + * @retval HITLS_SUCCESS, if successful. + * For details about other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetServerNameArg(HITLS_Config *config, void **arg); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/tls/hitls_type.h b/include/tls/hitls_type.h new file mode 100644 index 00000000..f88aaeee --- /dev/null +++ b/include/tls/hitls_type.h @@ -0,0 +1,176 @@ +/* + * 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 hitls_type + * @ingroup hitls + * @brief TLS type definition, provides the TLS type required by the user + */ + +#ifndef HITLS_TYPE_H +#define HITLS_TYPE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_type + * @brief HITLS context + */ +typedef struct TlsCtx HITLS_Ctx; + +/** + * @ingroup hitls_type + * @brief config context + */ +typedef struct TlsConfig HITLS_Config; + +/** + * @ingroup hitls_type + * @brief cipherSuite information + */ +typedef struct TlsCipherSuiteInfo HITLS_Cipher; + +typedef struct TlsSessCtx HITLS_Session; + +/** +* @ingroup hitls_type +* @brief DTLS SCTP authkey length, which is specified in the protocol and can be used to determine the length +* when the auth key is set. +*/ +#define DTLS_SCTP_SHARED_AUTHKEY_LEN 64 + +/** +* @ingroup hitls_type +* @brief TLS1.3 key exchange mode: Only PSKs are used for key negotiation. +*/ +#define TLS13_KE_MODE_PSK_ONLY 1u + +/** +* @ingroup hitls_type +* @brief TLS1.3 key exchange mode: Both PSK and (EC)DHE are used for key negotiation. +*/ +#define TLS13_KE_MODE_PSK_WITH_DHE 2u +/** +* @ingroup hitls_type +* @brief TLS1.3 certificate authentication: The certificate authentication is used and +* the (EC)DHE negotiation key is required. +*/ +#define TLS13_CERT_AUTH_WITH_DHE 4u + +/* Sets the number of digits in the version number. */ +#define SSLV2_VERSION_BIT 0x00000001U +#define SSLV3_VERSION_BIT 0x00000002U +#define TLS10_VERSION_BIT 0x00000004U +#define TLS11_VERSION_BIT 0x00000008U +#define TLS12_VERSION_BIT 0x00000010U +#define TLS13_VERSION_BIT 0x00000020U +#define DTLS10_VERSION_BIT 0x80000000U +#define DTLS12_VERSION_BIT 0x40000000U +#define TLS_VERSION_MASK (TLS12_VERSION_BIT | TLS13_VERSION_BIT) + +/* Currently, only DTLS12 is supported. DTLS10 is not supported */ +#define DTLS_VERSION_MASK DTLS12_VERSION_BIT + +/** + * @ingroup hitls_type + * @brief HITLS_SESS_CACHE_MODE: mode for storing hitls sessions. + */ +typedef enum { + HITLS_SESS_CACHE_NO, + HITLS_SESS_CACHE_CLIENT, + HITLS_SESS_CACHE_SERVER, + HITLS_SESS_CACHE_BOTH, +} HITLS_SESS_CACHE_MODE; + +/** + * @ingroup hitls_type + * @brief key update message type + */ +typedef enum { + HITLS_UPDATE_NOT_REQUESTED = 0, + HITLS_UPDATE_REQUESTED = 1, + HITLS_KEY_UPDATE_REQ_END = 255 +} HITLS_KeyUpdateRequest; + +#define HITLS_MODE_ENABLE_PARTIAL_WRITE 0x00000001U +#define HITLS_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U +#define HITLS_MODE_AUTO_RETRY 0x00000004U +#define HITLS_MODE_NO_AUTO_CHAIN 0x00000008U +#define HITLS_MODE_RELEASE_BUFFERS 0x00000010U +#define HITLS_MODE_SEND_CLIENTHELLO_TIME 0x00000020U +#define HITLS_MODE_SEND_SERVERHELLO_TIME 0x00000040U +#define HITLS_MODE_SEND_FALLBACK_SCSV 0x00000080U +#define HITLS_MODE_ASYNC 0x00000100U +#define HITLS_MODE_DTLS_SCTP_LABEL_LENGTH_BUG 0x00000400U + +/* close_notify message has been sent to the peer end, turn off the alarm, and the connection is considered closed. */ +# define HITLS_SENT_SHUTDOWN 1u +# define HITLS_RECEIVED_SHUTDOWN 2u /* Received peer shutdown alert, normal close_notify or fatal error */ + +// Used to mark the current internal status +#define HITLS_NOTHING 1u +#define HITLS_WRITING 2u +#define HITLS_READING 3u +#define HITLS_ASYNC_PAUSED 4u +#define HITLS_ASYNC_NO_JOBS 5u + +#define HITLS_CC_READ 0x001u /* Read state */ +#define HITLS_CC_WRITE 0x002u /* Write status */ + +/* Describes the handshake status */ +typedef enum { + TLS_IDLE, /**< initial state */ + TLS_CONNECTED, /**< Handshake succeeded */ + TRY_SEND_HELLO_REQUEST, /**< sends hello request message */ + TRY_SEND_CLIENT_HELLO, /**< sends client hello message */ + TRY_SEND_HELLO_VERIFY_REQUEST, /**< sends hello verify request message */ + TRY_SEND_HELLO_RETRY_REQUEST, /**< sends hello retry request message */ + TRY_SEND_SERVER_HELLO, /**< sends server hello message */ + TRY_SEND_ENCRYPTED_EXTENSIONS, /**< sends encrypted extensions message */ + TRY_SEND_CERTIFICATE, /**< sends certificate message */ + TRY_SEND_SERVER_KEY_EXCHANGE, /**< sends server key exchange message */ + TRY_SEND_CERTIFICATE_REQUEST, /**< sends certificate request message */ + TRY_SEND_SERVER_HELLO_DONE, /**< sends server hello done message */ + TRY_SEND_CLIENT_KEY_EXCHANGE, /**< sends client key exchange message */ + TRY_SEND_CERTIFICATE_VERIFY, /**< sends certificate verify message */ + TRY_SEND_NEW_SESSION_TICKET, /**< sends new session ticket message */ + TRY_SEND_CHANGE_CIPHER_SPEC, /**< sends change cipher spec message */ + TRY_SEND_END_OF_EARLY_DATA, /**< sends end of early data message */ + TRY_SEND_FINISH, /**< sends finished message */ + TRY_RECV_CLIENT_HELLO, /**< attempts to receive client hello message */ + TRY_RECV_HELLO_VERIFY_REQUEST, /**< attempts to receive hello verify request message */ + TRY_RECV_SERVER_HELLO, /**< attempts to receive server hello message */ + TRY_RECV_ENCRYPTED_EXTENSIONS, /**< attempts to receive encrypted extensions message */ + TRY_RECV_CERTIFICATE, /**< attempts to receive certificate message */ + TRY_RECV_SERVER_KEY_EXCHANGE, /**< attempts to receive server key exchange message */ + TRY_RECV_CERTIFICATE_REQUEST, /**< attempts to receive certificate request message */ + TRY_RECV_SERVER_HELLO_DONE, /**< attempts to receive server hello done message */ + TRY_RECV_CLIENT_KEY_EXCHANGE, /**< attempts to receive client key exchange message */ + TRY_RECV_CERTIFICATE_VERIFY, /**< attempts to receive certificate verify message */ + TRY_RECV_NEW_SESSION_TICKET, /**< attempts to receive new session ticket message */ + TRY_RECV_END_OF_EARLY_DATA, /**< attempts to receive end of early data message */ + TRY_RECV_FINISH, /**< attempts to receive finished message */ + HS_STATE_BUTT = 255 /**< enumerated Maximum Value */ +} HITLS_HandshakeState; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/Secure_C b/platform/Secure_C new file mode 160000 index 00000000..1ae16ab9 --- /dev/null +++ b/platform/Secure_C @@ -0,0 +1 @@ +Subproject commit 1ae16ab92de4884eacea211dcd1989af95dae79b diff --git a/script/config_parser.py b/script/config_parser.py new file mode 100644 index 00000000..117c7f6c --- /dev/null +++ b/script/config_parser.py @@ -0,0 +1,839 @@ +#!/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. +import sys +sys.dont_write_bytecode = True +import json +import os +import glob +import platform +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__)))) +from methods import trans2list, unique_list, save_json_file + +class FeatureParser: + """ Parsing feature files """ + lib_dir_map = { + "hitls_bsl": "bsl", + "hitls_crypto": "crypto", + "hitls_tls": "tls", + "hitls_x509": "x509" + } + + def __init__(self, file_path): + self._fp = file_path + with open(file_path, 'r', encoding='utf-8') as f: + self._cfg = json.loads(f.read()) + self._file_check() + + # Features and related information. + self._feas_info = self._get_feas_info() + # Assembly type supported by the openHiTLS. + self._asm_types = self._get_asm_types() + + @property + def libs(self): + return self._cfg['libs'] + + @property + def modules(self): + return self._cfg['modules'] + + @property + def asm_types(self): + return self._asm_types + + @property + def feas_info(self): + return self._feas_info + + def _file_check(self): + if 'libs' not in self._cfg or 'modules' not in self._cfg: + raise FileNotFoundError("The format of file %s is incorrect." % self._fp) + + @staticmethod + def _add_key_value(obj, key, value): + if value: + obj[key] = value + + def _add_fea(self, feas_info, fea, lib, parent, children, opts, deps, impl, ins_set): + feas_info.setdefault(fea, {}) + self._add_key_value(feas_info[fea], 'lib', lib) + self._add_key_value(feas_info[fea], 'parent', parent) + self._add_key_value(feas_info[fea], 'children', children) + self._add_key_value(feas_info[fea], 'opts', opts) + self._add_key_value(feas_info[fea], 'deps', deps) + + feas_info[fea].setdefault('impl', {}) + feas_info[fea]['impl'][impl] = ins_set if ins_set else [] + + def _parse_fea_obj(self, lib, impl, parent, fea, fea_obj, feas_info): + if not fea_obj: + self._add_fea(feas_info, fea, lib, parent, None, None, None, impl, None) + return + + opts = None + deps = None + ins_set = None + children = [] + for key, obj in fea_obj.items(): + if key == 'deps': + deps = obj + continue + if key == 'opts': + opts = obj + continue + if key == 'ins_set': + ins_set = obj + continue + children.append(key) + self._parse_fea_obj(lib, impl, fea, key, obj, feas_info) + + self._add_fea(feas_info, fea, lib, parent, children, opts, deps, impl, ins_set) + + def _get_feas_info(self): + """ + description: Parse the feature.json file to obtain feature information + and check that feature names in different libraries are unique. + return: + feas_info: { + "children":[], "parent":[], "deps":[], + "opts":[[],[]], "lib":"", + "impl":{"c":[], "armv8:[], ...}, # [] lists the instruction sets supported by the feature. + } + """ + all_feas = set() + lib_feas_info = {} + for lib, lib_obj in self._cfg['libs'].items(): + lib_feas_info[lib] = {} + + for impl, impl_obj in lib_obj['features'].items(): + for fea, fea_obj in impl_obj.items(): + self._parse_fea_obj(lib, impl, None, fea, fea_obj, lib_feas_info[lib]) + + # Check that feature names in different libraries are unique. + lib_feas = set(lib_feas_info[lib].keys()) + repeat_feas = all_feas.intersection(lib_feas) + if len(repeat_feas) != 0: + raise ValueError("Error: feature '%s' has been defined in multiple libs." % (repeat_feas)) + all_feas.update(lib_feas) + + feas_info = {} + for obj in lib_feas_info.values(): + feas_info.update(obj) + self._fill_fea_modules(feas_info) + return feas_info + + def _fill_fea_modules(self, feas_info): + for top_mod in self.modules: + for mod, mod_obj in self.modules[top_mod].items(): + formated_mod = "{}::{}".format(top_mod, mod) + for fea in mod_obj.get('.features', []): + if fea not in feas_info: + raise ValueError("Unrecognized '%s' in '.features' of '%s::%s'" % (fea, top_mod, mod)) + if 'modules' not in feas_info[fea]: + feas_info[fea]['modules'] = [formated_mod] + else: + feas_info[fea]['modules'].append(formated_mod) + + def _get_asm_types(self): + asm_type_set = set() + [asm_type_set.update(self.libs[lib]['features'].keys()) for lib in self.libs.keys()] + asm_type_set.discard('c') + asm_type_set.add('no_asm') + return asm_type_set + + def get_module_deps(self, module, dep_list, result): + return self._get_module_deps(module, dep_list, result) + + def _get_module_deps(self, module, dep_list, result): + """ + Recursively obtains the modules on which the modules depend. + module: [IN] module name, such as crypto::sha2 + dep_list: [OUT] Dependency list, which is an intermediate variable + result: [OUT] result + """ + top_module, sub_module = module.split('::') + mod_obj = self.modules[top_module][sub_module] + + if '.deps' not in mod_obj: + result.update(dep_list) + return + + for dep_mod in mod_obj['.deps']: + if dep_mod in dep_list: + # A dependency that already exists in a dependency chain is a circular dependency. + raise Exception("Cyclic dependency") + dep_list.append(dep_mod) + self._get_module_deps(dep_mod, dep_list, result) + dep_list.pop() + + def get_mod_srcs(self, top_mod, sub_mod, mod_obj): + srcs = self._cfg['modules'][top_mod][sub_mod]['.srcs'] + asm_type = mod_obj.get('asmType', 'c') + inc = mod_obj.get('incSet', '') + + blurred_srcs = [] + if not isinstance(srcs, dict): + blurred_srcs.extend(trans2list(srcs)) + return blurred_srcs + + blurred_srcs.extend(trans2list(srcs.get('public', []))) + if asm_type == 'c': + blurred_srcs.extend(trans2list(srcs.get('no_asm', []))) + return blurred_srcs + + if asm_type not in srcs: + raise ValueError("Missing '.srcs[%s]' in modules '%s::%s'" % (asm_type, top_mod, sub_mod)) + if not isinstance(srcs[asm_type], dict): + blurred_srcs.extend(trans2list(srcs[asm_type])) + return blurred_srcs + + if inc: + blurred_srcs.extend(trans2list(srcs[asm_type][inc])) + else: + first_key = list(srcs[asm_type].keys())[0] + blurred_srcs.extend(trans2list(srcs[asm_type][first_key])) + return blurred_srcs + +class FeatureConfigParser: + """ Parses the user feature configuration file. """ + # Specifications of keys and values in the file. + key_value = { + "system": {"require": False, "type": str, "choices": ["linux"], "default": "linux"}, + "bits": {"require": False, "type": int, "choices": [32, 64], "default": 64}, + "endian": {"require": True, "type": str, "choices": ["little", "big"], "default": "little"}, + "libType": { + "require": True, + "type": list, + "choices": ["static", "shared", "object"], + "default": ["static", "shared", "object"] + }, + "asmType":{"require": True, "type": str, "choices": [], "default": "no_asm"}, + "libs":{"require": True, "type": dict, "choices": [], "default": {}} + } + + def __init__(self, features: FeatureParser, file_path): + self._features = features + self._config_file = file_path + with open(file_path, 'r', encoding='utf-8') as f: + self._cfg = json.loads(f.read()) + self.key_value['asmType']['choices'] = list(features.asm_types) + self.key_value['libs']['choices'] = list(features.libs) + self._file_check() + + @classmethod + def default_cfg(cls): + config = {} + for key in cls.key_value.keys(): + if cls.key_value[key]["require"]: + config[key] = cls.key_value[key]["default"] + return config + + @property + def libs(self): + return self._cfg['libs'] + + @property + def lib_type(self): + return trans2list(self._cfg['libType']) + + @property + def asm_type(self): + return self._cfg['asmType'] + + @staticmethod + def _get_fea_and_inc(asm_fea): + if '::' in asm_fea: + return asm_fea.split('::') + else: + return asm_fea, '' + + def _asm_fea_check(self, asm_fea, asm_type, info): + fea, inc = self._get_fea_and_inc(asm_fea) + feas_info = self._features.feas_info + if fea not in feas_info: + raise ValueError("Unsupported '%s' in %s" % (fea, info)) + if asm_type not in feas_info[fea]['impl']: + raise ValueError("Feature '%s' has no assembly implementation of type '%s' in %s" % (fea, asm_type, info)) + if inc: + if inc not in feas_info[fea]['impl'] and inc not in feas_info[fea]['impl'][asm_type]: + raise ValueError("Unsupported instruction set of '%s' in %s" % (asm_fea, info)) + return fea, inc + + def _file_check(self): + for key, value in self.key_value.items(): + if value['require']: + if key not in self._cfg.keys(): + raise ValueError("Error feature_config file: missing '%s'" % key) + + for key, value in self._cfg.items(): + if key not in self.key_value.keys(): + raise ValueError("Error feature_config file: unsupported config '%s'" % key) + if not isinstance(value, self.key_value.get(key).get("type")): + raise ValueError("Error feature_config file: wrong type of '%s'" % key) + + value_type = type(value) + if value_type == str or value_type == str: + if value not in self.key_value.get(key).get("choices"): + raise ValueError("Error feature_config file: wrong value of '%s'" % key) + elif value_type == list: + choices = set(self.key_value[key]["choices"]) + if not set(value).issubset(choices): + raise ValueError("Error feature_config file: wrong value of '%s'" % key) + + for lib, lib_obj in self._cfg['libs'].items(): + if lib not in self._features.libs: + raise ValueError("Error feature_config file: unsupported lib '%s'" % lib) + for fea in lib_obj.get('c', []): + if fea not in self._features.feas_info: + raise ValueError("Error feature_config file: unsupported fea '%s' in lib '%s'" % (fea, lib)) + asm_feas = [] + for asm_fea in lib_obj.get('asm', []): + fea, inc = self._asm_fea_check(asm_fea, self.asm_type, 'feature_config file') + if fea in asm_feas: + raise ValueError("Error feature_config file: duplicate assembly feature '%s'" % fea) + asm_feas.append(fea) + + def set_param(self, key, value, set_default=True): + if value: + self._cfg[key] = value + return + if not set_default: + return + if key not in self._cfg or not self._cfg[key]: + print("Warning: Configuration item '{}' is missing and has been set to the default value '{}'.".format( + key, self.key_value.get(key).get('default'))) + self._cfg[key] = self.key_value.get(key).get('default') + + def _get_related_feas(self, fea, feas_info, related: set): + related.add(fea) + if 'parent' in feas_info[fea]: + parent = feas_info[fea]['parent'] + for dep in feas_info[parent].get('deps', []): + self._get_related_feas(dep, feas_info, related) + if 'children' in feas_info[fea]: + for child in feas_info[fea]['children']: + self._get_related_feas(child, feas_info, related) + if 'deps' in feas_info[fea]: + for dep in feas_info[fea]['deps']: + self._get_related_feas(dep, feas_info, related) + + def _get_json_feas(self, enable_feas, asm_feas): + for _, lib_obj in self._cfg['libs'].items(): + for fea in lib_obj.get('c', []): + related_feas = set() + self._get_related_feas(fea, self._features.feas_info, related_feas) + enable_feas.update(related_feas) + for asm_fea in lib_obj.get('asm', []): + fea, inc = self._get_fea_and_inc(asm_fea) + enable_feas.add(fea) + asm_feas[fea] = inc + if 'children' in self._features.feas_info[fea]: + enable_feas.update(self._features.feas_info[fea]['children']) + + def _get_parents(self, disables): + parents = set() + for d in disables: + relation = self._features.feas_info.get(d) + if relation and 'parent' in relation: + parents.add(relation['parent']) + return parents + + def get_enable_feas(self, enables): + """ + Obtain the enabled features from the configuration file and input parameters. + enables: [IN] 'all': add full c features. + Excluding 'all': Incremental addition of C features + """ + enable_feas = set() + enable_asm_feas = {} + self._get_json_feas(enable_feas, enable_asm_feas) + if not enables: + return enable_feas, enable_asm_feas + # Obtains the properties from the input parameters. + if 'all' in enables: + enable_feas = set(self._features.feas_info.keys()) + return enable_feas, enable_asm_feas + for enable in enables: + if enable in self._features.libs: + # lib + for fea, info in self._features.feas_info.items(): + if enable == info['lib']: + enable_feas.add(fea) + else: + # The feature is not lib and needs to be added separately. + related_feas = set() + self._get_related_feas(enable, self._features.feas_info, related_feas) + enable_feas.update(related_feas) + return enable_feas, enable_asm_feas + + def _add_feature(self, fea, impl_type, inc=''): + add_fea = fea if inc == '' else '{}::{}'.format(fea, inc) + lib = self._features.feas_info[fea]['lib'] + if lib not in self._cfg['libs']: + self._cfg['libs'][lib] = {impl_type: [add_fea]} + elif impl_type not in self._cfg['libs'][lib]: + self._cfg['libs'][lib][impl_type] = [add_fea] + elif fea not in self._cfg['libs'][lib][impl_type]: + self._cfg['libs'][lib][impl_type].append(add_fea) + + def set_asm_type(self, asm_type): + if self._cfg['asmType'] == 'no_asm': + self._cfg['asmType'] = asm_type + elif self._cfg['asmType'] != asm_type: + raise ValueError('Error asmType: %s is different from feature_config file.' % (asm_type)) + + def set_asm_features(self, enable_feas, added_asm_feas, asm_type, arg_asm): + feas_info = self._features.feas_info + # Clear the assembly features first. + for lib in self._cfg['libs']: + if 'asm' in self._cfg['libs'][lib]: + self._cfg['libs'][lib]['asm'] = [] + # Add assembly features. + if arg_asm: + for asm_feature in arg_asm: + fea, inc = self._asm_fea_check(asm_feature, asm_type, 'input asm list') + if fea not in enable_feas: + raise ValueError("To add '%s' assembly requires add it to 'enable' list" % fea) + if inc and inc != asm_type and inc not in self._features.feas_info[fea]['impl'][asm_type]: + raise ValueError("Unsupported instruction set '%s' of fea '%s'" % (inc, fea)) + self._add_feature(fea, 'asm', inc) + added_asm_feas[fea] = inc + else: + for fea in enable_feas: + if asm_type not in feas_info[fea]['impl']: + continue + self._add_feature(fea, 'asm') + added_asm_feas[fea] = '' + + def set_c_features(self, enable_feas): + for fea in enable_feas: + if 'c' in self._features.feas_info[fea]['impl']: + self._add_feature(fea, 'c') + + def _update_enable_feature(self, features, disables): + """ + The sub-feature macro is derived from the parent feature macro in the code. + Therefore, the sub-feature is removed and the parent feature is retained. + """ + disable_parents = self._get_parents(disables) + tmp_feas = features.copy() + enable_set = set() + feas_info = self._features.feas_info + for fea in tmp_feas: + rel = feas_info[fea] + if fea in disable_parents: + if 'children' in rel: + enable_set.update(rel['children']) + enable_set.discard(fea) + else: + is_fea_contained = False + while 'parent' in rel: + if rel['parent'] in disables: + raise Exception("The 'disables' features {} and 'enables' featrues {} conflict".format(fea, disables)) + + if rel['parent'] in features: + is_fea_contained = True + break + rel = feas_info[rel['parent']] + if not is_fea_contained: + enable_set.add(fea) + enable_set.difference_update(set(disables)) + return list(enable_set) + + def _check_bn_config(self): + lib = 'hitls_crypto' + if lib not in self._cfg['libs']: + return + + has_bn = False + for impl_type in self._cfg['libs'][lib]: + if 'bn' in self._cfg['libs'][lib][impl_type]: + has_bn = True + break + + if has_bn and 'bits' not in self._cfg: + raise ValueError("If 'bn' is used, the 'bits' of the system must be configured.") + + def _check_system_config(self): + lib = 'hitls_bsl' + if lib not in self._cfg['libs']: + return + sys_feas = ['sal_mem', 'sal_thread', 'sal_lock', 'sal_time', 'sal_file', 'sal_net', 'sal_str'] + has_sys_feas = False + for impl_type in self._cfg['libs'][lib]: + for fea in self._cfg['libs'][lib][impl_type]: + if fea in sys_feas: + has_sys_feas = True + break + + if has_sys_feas and 'system' not in self._cfg: + raise ValueError("If %s is used, the system type must be configured." % sys_feas) + + def _re_sort_lib(self): + # Change the key sequence of the 'libs' dictionary. Otherwise, the compilation fails. + lib_sort = ['hitls_bsl', 'hitls_crypto', 'hitls_tls', "hitls_x509"] + libs = self.libs.copy() + self._cfg['libs'].clear() + + for lib in lib_sort: + if lib in libs: + self._cfg['libs'][lib] = libs[lib].copy() + + def update_feature(self, enables, disables): + ''' + update feature: + 1. Add the default lib and features: hitls_bsl: sal + 2. Delete features based on the relationship between features. + ''' + libs = self._cfg['libs'] + if len(libs) == 0: + raise ValueError("No features are set, please check whether 'enable' and 'asm_type' need to be set") + + libs.setdefault('hitls_bsl', {'c':['sal']}) + if 'hitls_bsl' not in libs: + libs['hitls_bsl'] = {'c':['sal']} + elif 'c' not in libs['hitls_bsl']: + libs['hitls_bsl']['c'] = ['sal'] + elif 'sal' not in libs['hitls_bsl']['c']: + libs['hitls_bsl']['c'].append('sal') + + for lib in libs: + if 'c' in libs[lib]: + libs[lib]['c'] = self._update_enable_feature(libs[lib]['c'], disables) + libs[lib]['c'].sort() + if self.asm_type != 'no_asm' and self.asm_type in libs[lib]: + libs[lib]['asm'] = self._update_enable_feature(libs[lib]['asm'], disables) + libs[lib]['asm'].sort() + + self._re_sort_lib() + + if 'all' in enables: + self.set_param('system', None) + self.set_param('bits', None) + return + + def save(self, path): + save_json_file(self._cfg, path) + + def get_fea_macros(self): + macros = set() + for lib, lib_value in self.libs.items(): + lib_upper = lib.upper() + + for fea in lib_value.get('c', []): + macros.add("-D%s_%s" % (lib_upper, fea.upper())) + for fea in lib_value.get('asm', []): + fea = fea.split('::')[0] + macros.add("-D%s_%s" % (lib_upper, fea.upper())) + macros.add("-D%s_%s_ASM" % (lib_upper, fea.upper())) + macros.add("-D%s_%s_%s" % (lib_upper, fea.upper(), self.asm_type.upper())) + + if self._cfg['endian'] == 'big': + macros.add("-DHITLS_BIG_ENDIAN") + if self._cfg.get('system', ""): + macros.add("-DHITLS_BSL_SAL_LINUX") + + bits = self._cfg.get('bits', 0) + if bits == 32: + macros.add("-DHITLS_THIRTY_TWO_BITS") + elif bits == 64: + macros.add("-DHITLS_SIXTY_FOUR_BITS") + + return list(macros) + + def _re_get_fea_modules(self, fea, feas_info, asm_type, inc, modules): + """Obtain the modules on which the current feature and subfeature depend.""" + for mod in feas_info[fea].get('modules', []): + modules.setdefault(mod, {}) + modules[mod]["asmType"] = asm_type + if inc: + modules[mod]["incSet"] = inc + + for child in feas_info[fea].get('children', []): + self._re_get_fea_modules(child, feas_info, asm_type, inc, modules) + + def _get_lib_modules(self, lib): + """Obtain the enabled modules and their instruction sets.""" + lib_modules = {} + feas_info = self._features.feas_info + for fea in self.libs[lib].get('c', []): + self._re_get_fea_modules(fea, feas_info, 'c', '', lib_modules) + + for asm_fea in self.libs[lib].get('asm', []): + fea, inc = self._get_fea_and_inc(asm_fea) + self._re_get_fea_modules(fea, feas_info, self.asm_type, inc, lib_modules) + + return lib_modules + + def get_enable_modules(self): + """ + Obtain the modules required for compiling each lib features + and the modules on which the lib feature depends (for obtaining the include directory). + 1. Add modules and their dependent modules based on features. + 2. Check whether the dependent modules are enabled. + return: {'lib':{"mod1":{"deps":[], "asmType":"", "incSet":""}}} + Module format: top_dir::sub_dir + """ + enable_libs_mods = {} + enable_mods = set() + for lib in self.libs.keys(): + enable_libs_mods[lib] = self._get_lib_modules(lib) + for mod in enable_libs_mods[lib]: + mod_dep_mods = set() + self._features.get_module_deps(mod, [], mod_dep_mods) + enable_libs_mods[lib][mod]['deps'] = list(mod_dep_mods) + if len(enable_libs_mods[lib].keys()) == 0: + raise ValueError("Error: no module is enabled in lib%s" % lib) + enable_mods.update(enable_libs_mods[lib]) + + # Check whether the dependent module is enabled. + for lib in enable_libs_mods.keys(): + for mod in enable_libs_mods[lib]: + for dep_mod in enable_libs_mods[lib][mod].get('deps', []): + if dep_mod == "platform::Secure_C": + continue + if dep_mod not in enable_mods: + raise ValueError("Error: '%s' depends on '%s', but '%s' is disabled." % (mod, dep_mod, dep_mod)) + return enable_libs_mods + + def filter_no_asm_config(self): + self._cfg['asmType'] = 'no_asm' + for lib in self._cfg['libs']: + if 'asm' in self._cfg['libs'][lib]: + self._cfg['libs'][lib]['asm'] = [] + + def _check_fea_opts_arr(self, opts, fea, enable_feas): + for opt_arr in opts: + has_opt = False + for opt_fea in opt_arr: + parent = self._features.feas_info[opt_fea].get('parent', '') + if opt_fea in enable_feas or (parent and parent in enable_feas): + has_opt = True + continue + if not has_opt: + raise ValueError("The fea '%s' must work with at leaset one fea in %s" % (fea, opt_arr)) + + def _check_opts(self, fea, enable_feas): + if 'opts' not in self._features.feas_info[fea]: + return + opts = self._features.feas_info[fea]['opts'] + if not isinstance(opts[0], list): + opts = [opts] + + self._check_fea_opts_arr(opts, fea, enable_feas) + + def _check_family_opts(self, fea, key, enable_feas): + values = self._features.feas_info[fea].get(key, []) + if not isinstance(values, list): + values = [values] + for value in values: + self._check_opts(value, enable_feas) + self._check_family_opts(value, key, enable_feas) + + def check_fea_opts(self): + enable_feas = set() + for _, lib_obj in self.libs.items(): + enable_feas.update(lib_obj.get('c', [])) + enable_feas.update(lib_obj.get('asm', [])) + for fea in enable_feas: + fea = fea.split("::")[0] + self._check_opts(fea, enable_feas) + self._check_family_opts(fea, 'parent', enable_feas) + self._check_family_opts(fea, 'children', enable_feas) + +class CompleteOptionParser: + """ Parses all compilation options. """ + # Sequence in which compilation options are added, including all compilation option types. + option_order = [ + "CC_DEBUG_FLAGS", + "CC_OPT_LEVEL", # Optimization Level + "CC_OVERALL_FLAGS", # Overall Options + "CC_WARN_FLAGS", # Warning options + "CC_LANGUAGE_FLAGS", # Language Options + "CC_CDG_FLAGS", # Code Generation Options + "CC_MD_DEPENDENT_FLAGS", # MD_Dependent Options + "CC_OPT_FLAGS", # Optimization Options + "CC_SEC_FLAGS", # Secure compilation options + "CC_DEFINE_FLAGS", # Custom Macro + "CC_USER_DEFINE_FLAGS", # User-defined compilation options are reserved. + ] + + def __init__(self, file_path): + self._fp = file_path + with open(file_path, 'r') as f: + self._cfg = json.loads(f.read()) + self._file_check() + + self._option_type_map = {} + for option_type in self._cfg['compileFlag']: + for option in trans2list(self._cfg['compileFlag'][option_type]): + self._option_type_map[option] = option_type + + @property + def option_type_map(self): + return self._option_type_map + + @property + def type_options_map(self): + return self._cfg['compileFlag'] + + def _file_check(self): + if 'compileFlag' not in self._cfg or 'linkFlag' not in self._cfg: + raise FileNotFoundError("The format of file %s is incorrect." % self._fp) + for option_type in self._cfg['compileFlag']: + if option_type not in self.option_order: + raise FileNotFoundError("The format of file %s is incorrect." % self._fp) + +class CompileConfigParser: + """ Parse the user compilation configuration file. """ + + def __init__(self, all_options: CompleteOptionParser, file_path=''): + with open(file_path, 'r') as f: + self._cfg = json.loads(f.read()) + self._all_options = all_options + self._file_check() + + @property + def options(self): + return self._cfg['compileFlag'] + + @property + def link_flags(self): + return self._cfg['linkFlag'] + + @classmethod + def default_cfg(cls): + config = { + 'compileFlag': {}, + 'linkFlag': {} + } + return config + + def _file_check(self): + if 'compileFlag' not in self._cfg or 'linkFlag' not in self._cfg: + raise FileNotFoundError("Error compile_config file: missing 'compileFlag' or 'linkFlag'") + + # Check whether the configured compilation options are in the compilation option set. + for option_type in self._cfg['compileFlag']: + if option_type == 'CC_USER_DEFINE_FLAGS': + continue + + for option in self._cfg['compileFlag'][option_type].get('CC_FLAGS_ADD', []): + if option not in self._all_options.type_options_map[option_type]: + raise ValueError("unrecognized option {}".format(option)) + + def save(self, path): + save_json_file(self._cfg, path) + + def change_options(self, options, is_add): + option_op = 'CC_FLAGS_ADD' if is_add else 'CC_FLAGS_DEL' + for option in options: + option_type = 'CC_USER_DEFINE_FLAGS' + if option in self._all_options.option_type_map: + option_type = self._all_options.option_type_map[option] + + if option_type not in self._cfg['compileFlag']: + self._cfg['compileFlag'][option_type] = {} + + flags = self._cfg['compileFlag'][option_type] + flags[option_op] = unique_list(flags.get(option_op, []) + [option]) + + def change_link_flags(self, flags, is_add): + link_op = 'LINK_FLAG_ADD' if is_add else 'LINK_FLAG_DEL' + new_flags = self._cfg['linkFlag'].get(link_op, []) + flags + self._cfg['linkFlag'][link_op] = unique_list(new_flags) + + def add_debug_options(self): + flags_add = {'CC_FLAGS_ADD': ['-g3', '-gdwarf-2']} + flags_del = {'CC_FLAGS_DEL': ['-O2', '-D_FORTIFY_SOURCE=2']} + + self._cfg['compileFlag']['CC_DEBUG_FLAGS'] = flags_add + self._cfg['compileFlag']['CC_OPT_LEVEL'] = flags_del + + def filter_hitls_defines(self): + for flag in list(self.link_flags.keys()): + del self.link_flags[flag] + + for flag in list(self.options.keys()): + if flag != 'CC_USER_DEFINE_FLAGS' and flag != 'CC_DEFINE_FLAGS': + del self.options[flag] + +class CompileParser: + """ + Parse the compile.json file. + json key and value: + compileFlag: compilation options + linkFlag: link option + """ + + def __init__(self, all_options: CompleteOptionParser, file_path): + self._fp = file_path + self._all_options = all_options + with open(file_path, 'r') as f: + self._cfg = json.loads(f.read()) + self._file_check() + + @property + def options(self): + return self._cfg["compileFlag"] + + @property + def link_flags(self): + return self._cfg["linkFlag"] + + def _file_check(self): + if 'compileFlag' not in self._cfg or 'linkFlag' not in self._cfg: + raise FileNotFoundError("Error compile file: missing 'compileFlag' or 'linkFlag'") + for option_type in self.options: + if option_type not in self._all_options.type_options_map: + raise ValueError("no '{}' option type in complete_options.json".format(option_type)) + + for option in self.options[option_type]: + if option not in self._all_options.type_options_map[option_type]: + raise ValueError("unrecognized option '{}' in type {}.".format(option, option_type)) + for option_type in self._cfg['linkFlag']: + if option_type not in ['PUBLIC', 'SHARED', 'EXE']: + raise FileNotFoundError('Incorrect file format: %s' % self._fp) + + def union_options(self, custom_cfg: CompileConfigParser): + options = [] + for option_type in CompleteOptionParser.option_order: + options.extend(self.options.get(option_type, [])) + if option_type not in custom_cfg.options: + continue + for option in custom_cfg.options[option_type].get('CC_FLAGS_ADD', []): + if option not in options: + options.append(option) + for option in custom_cfg.options[option_type].get('CC_FLAGS_DEL', []): + if option in options: + options.remove(option) + + flags = self.link_flags + for flag in custom_cfg.link_flags.get('LINK_FLAG_ADD', []): + if flag not in flags['PUBLIC']: + flags['PUBLIC'].append(flag) + if flag not in flags['EXE']: + flags['EXE'].append(flag) + if flag not in flags['SHARED']: + flags['SHARED'].append(flag) + for flag in custom_cfg.link_flags.get('LINK_FLAG_DEL', []): + if flag in flags['PUBLIC']: + flags['PUBLIC'].remove(flag) + if flag in flags['EXE']: + flags['EXE'].remove(flag) + if flag in flags['SHARED']: + flags['SHARED'].remove(flag) + + return options, flags diff --git a/script/methods.py b/script/methods.py new file mode 100644 index 00000000..d9594f19 --- /dev/null +++ b/script/methods.py @@ -0,0 +1,45 @@ +#!/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. +import sys +sys.dont_write_bytecode = True +import os +import json + +# Convert x to list +def trans2list(x): + if x == None: return [] + if type(x) == list: return x + if type(x) == set: return x + if type(x) == str: return [x] + + raise ValueError('Unsupported type: "%s"' % type(x)) + +# list unique +def unique_list(x): + return list(dict.fromkeys(x)) + +def copy_file(src_file, dest_file, isCoverd=True): + if not os.path.exists(src_file): + raise FileNotFoundError('Src file not found: ' + src_file) + + if os.path.exists(dest_file): + if isCoverd: + shutil.copy2(src_file, dest_file) + else: + shutil.copy2(src_file, dest_file) + +def save_json_file(content, path): + with open(path, 'w') as f: + f.write(json.dumps(content, indent=4)) diff --git a/testcode/CMakeLists.txt b/testcode/CMakeLists.txt new file mode 100644 index 00000000..86fb7fd5 --- /dev/null +++ b/testcode/CMakeLists.txt @@ -0,0 +1,138 @@ +# 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_TEST) + +set(openHiTLS_SRC "${PROJECT_SOURCE_DIR}/..") +set(PROCESS PROCESS) +set(GEN_TESTCASE GEN_TESTCASE) +set(TESTCASE TESTCASE) +set(LIB_TEST_TLS LIB_TEST_TLS) + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + option(__x86_64__ "x86" ON) +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wformat=2 -Wno-format-nonliteral -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wl,--wrap=REC_Read -Wl,--wrap=REC_Write") + +message(STATUS "System processor :${CMAKE_SYSTEM_PROCESSOR}") +message(STATUS "Enable bsl uio sctp :${ENABLE_UIO_SCTP}") +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + message(STATUS "System architecture: 64") +else() + message(STATUS "System architecture: 32") +endif() + +if(ENABLE_GCOV) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -lgcov") +endif() + +if(ENABLE_ASAN) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-stack-protector -fno-omit-frame-pointer") +endif() + +if(CUSTOM_CFLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CUSTOM_CFLAGS}") +endif() + +if(DEBUG) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g") +endif() + +if(PRINT_TO_TERMINAL) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPRINT_TO_TERMINAL=${PRINT_TO_TERMINAL}") +endif() + +if(ENABLE_FAIL_REPEAT) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_FAIL_REPEAT=${ENABLE_FAIL_REPEAT}") +endif() + +if(OS_BIG_ENDIAN) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mbig-endian") +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FILE_OFFSET_BITS=64") + +include(ExternalProject) +ExternalProject_Add(${LIB_TEST_TLS} + SOURCE_DIR ${openHiTLS_SRC} + PREFIX "" + BINARY_DIR ${openHiTLS_SRC}/testcode/framework/tls/build + INSTALL_DIR "" + UPDATE_COMMAND "" + CONFIGURE_COMMAND cmake -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DENABLE_TLS_DEBUG=${TLS_DEBUG} .. + BUILD_COMMAND make + INSTALL_COMMAND "" + BUILD_ALWAYS FALSE + LOG_BUILD TRUE + LOG_DOWNLOAD TRUE + EXCLUDE_FROM_ALL TRUE + LOG_OUTPUT_ON_FAILURE TRUE +) + +ExternalProject_Add(${PROCESS} + SOURCE_DIR ${openHiTLS_SRC} + PREFIX "" + BINARY_DIR ${openHiTLS_SRC}/testcode/framework/process/build + INSTALL_DIR "" + UPDATE_COMMAND "" + CONFIGURE_COMMAND cmake -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DPRINT_TO_TERMINAL=${ENABLE_PRINT} -DENABLE_FAIL_REPEAT=${ENABLE_FAIL_REPEAT} .. + BUILD_COMMAND make + INSTALL_COMMAND "" + DEPENDS ${LIB_TEST_TLS} + BUILD_ALWAYS FALSE + LOG_BUILD TRUE + LOG_DOWNLOAD TRUE + EXCLUDE_FROM_ALL TRUE + LOG_OUTPUT_ON_FAILURE TRUE +) + +ExternalProject_Add(${GEN_TESTCASE} + SOURCE_DIR ${openHiTLS_SRC} + PREFIX "" + BINARY_DIR ${openHiTLS_SRC}/testcode/framework/gen_test/build/ + INSTALL_DIR "" + UPDATE_COMMAND "" + CONFIGURE_COMMAND cmake -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DPRINT_TO_TERMINAL=${ENABLE_PRINT} .. + BUILD_COMMAND make + INSTALL_COMMAND "" + BUILD_ALWAYS FALSE + LOG_BUILD TRUE + LOG_DOWNLOAD TRUE + EXCLUDE_FROM_ALL TRUE + LOG_OUTPUT_ON_FAILURE TRUE +) + +ExternalProject_Add(${TESTCASE} + SOURCE_DIR ${openHiTLS_SRC} + PREFIX "" + BINARY_DIR ${openHiTLS_SRC}/testcode/sdv/build/${TESTFILE} + INSTALL_DIR "" + UPDATE_COMMAND "" + CONFIGURE_COMMAND cmake -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DENABLE_CRYPTO=${ENABLE_CRYPTO} + -DENABLE_TLS=${ENABLE_TLS} + -DENABLE_X509=${ENABLE_X509} -DGEN_TEST_FILES=${GEN_TEST_FILES} + -DENABLE_UIO_SCTP=${ENABLE_UIO_SCTP} ../.. + BUILD_COMMAND make + INSTALL_COMMAND "" + BUILD_ALWAYS FALSE + LOG_BUILD TRUE + LOG_DOWNLOAD TRUE + EXCLUDE_FROM_ALL TRUE + LOG_OUTPUT_ON_FAILURE TRUE +) + +if(ENABLE_TLS) + add_dependencies(${GEN_TESTCASE} ${PROCESS}) +endif() diff --git a/testcode/common/execute_base.c b/testcode/common/execute_base.c new file mode 100644 index 00000000..c8eb49b0 --- /dev/null +++ b/testcode/common/execute_base.c @@ -0,0 +1,124 @@ +/* + * 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 +#include +#include +#include "securec.h" + +#define BUF_SIZE (65536 * 17) +#define MAX_RAND_SIZE (1024 * 16) +#define MAX_PATH 1024 +#define MAX_FILE_NAME 200 +#define MAX_IN_CASES 100000 +#define OUTPUT_LINE_LENGTH 60 + +#ifdef FAIL_REPEAT_RUN +#define FAIL_TRY_TWICE 2 +#else +#define FAIL_TRY_TWICE 0 +#endif + +#define FUNCTION_LOG_FORMAT "./log/%s.%s.log" +#define SUITE_LOG_FORMAT "./log/%s.log" +#define LOCAL_DIR "./" + +typedef struct { + char buf[MAX_DATA_LINE_LEN]; + char *arg[MAX_ARGUMENT_COUNT]; + char testVectorName[MAX_FILE_NAME]; + uint32_t argLen; +} TestArgs; + +typedef struct { + void *param[MAX_ARGUMENT_COUNT]; + int paramCount; + int intParam[MAX_ARGUMENT_COUNT]; + int intParamCount; + Hex hexParam[MAX_ARGUMENT_COUNT]; + int hexParamCount; +} TestParam; + +static TestArgs *g_executeCases[MAX_IN_CASES]; +static int g_executeCount = 0; + +static int ConvertStringCase(const TestArgs *arg) +{ + for (uint32_t i = 1; i < arg->argLen; i += 2) { + if (strcmp(arg->arg[i], "char") == 0 || strcmp(arg->arg[i], "Hex") == 0) { + if (ConvertString((char **)&(arg->arg[i+1])) != 0) { + return 1; + } + } + } + return 0; +} + +static int LoadDataFile(const char *fileName) +{ + if (g_executeCount > 0) { + return 0; + } + FILE *fpDatax = fopen(fileName, "r"); + if (fpDatax == NULL) { + Print("Error opening file\n"); + return (-1); + } + int rt = 0; + for (int i = 0; i < MAX_IN_CASES; i++) { + g_executeCases[i] = (TestArgs *)malloc(sizeof(TestArgs)); + if (g_executeCases[i] == NULL) { + rt = -1; + goto END; + } + g_executeCases[i]->argLen = MAX_ARGUMENT_COUNT; + if (ReadLine(fpDatax, g_executeCases[i]->testVectorName, MAX_FILE_NAME, 1, 1) != 0) { + free(g_executeCases[i]); + goto END; + } + if (ReadLine(fpDatax, g_executeCases[i]->buf, MAX_DATA_LINE_LEN, 1, 1) != 0) { + free(g_executeCases[i]); + Print("Read vector failed, test vector should have 2 lines, here there's only one\n"); + rt = -1; + goto END; + } + if (SplitArguments(g_executeCases[i]->buf, strlen(g_executeCases[i]->buf), + g_executeCases[i]->arg, &(g_executeCases[i]->argLen)) != 0) { + free(g_executeCases[i]); + rt = -1; + goto END; + } + if (ConvertStringCase(g_executeCases[i]) == 1) { + free(g_executeCases[i]); + rt = -1; + goto END; + } + g_executeCount += 1; + } + char tmpName[MAX_FILE_NAME]; + if (ReadLine(fpDatax, tmpName, MAX_FILE_NAME, 1, 1) == 0) { + Print("More test cases than max case num %d\n", MAX_IN_CASES); + rt = -1; + } + +END: + if (rt != 0) { + for (int i = 0; i < g_executeCount; i++) { + free(g_executeCases[i]); + } + } + (void)fclose(fpDatax); + return rt; +} \ No newline at end of file diff --git a/testcode/common/execute_test.c b/testcode/common/execute_test.c new file mode 100644 index 00000000..020af059 --- /dev/null +++ b/testcode/common/execute_test.c @@ -0,0 +1,312 @@ +/* + * 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 + +static jmp_buf env; +static int isSubProc = 0; +int *GetJmpAddress(void) +{ + return &isSubProc; +} + +void handleSignal(int sigNum) +{ + (void)sigNum; + siglongjmp(env, 1); +} + +static void PrintCaseName(FILE *logFile, bool showDetail, const char *name) +{ + int32_t dotCount = (OUTPUT_LINE_LENGTH - (int32_t)strlen(name) >= 4) ? + (OUTPUT_LINE_LENGTH - (int32_t)strlen(name)) : 4; + if (showDetail) { + Print("%s", name); + for (int32_t j = 0; j < dotCount; j++) { + Print("."); + } + } + (void)fprintf(logFile, "%s", name); + for (int32_t j = 0; j < dotCount; j++) { + (void)fprintf(logFile, "."); + } +} + +static int ParseArgs(const TestArgs *arg, TestParam *info) +{ + info->hexParamCount = 0; + info->intParamCount = 0; + info->paramCount = 0; + for (uint32_t i = 1; i < arg->argLen; i += 2) { + if (strcmp(arg->arg[i], "int") == 0) { + if (ConvertInt(arg->arg[i + 1], &(info->intParam[info->intParamCount])) == 0) { + info->param[info->paramCount] = &(info->intParam[info->intParamCount]); + info->intParamCount++; + } else { + Print("\nERROR: Int param conversion failed for:\n\"%s\"\n", arg->arg[i + 1]); + return 1; + } + } else if (strcmp(arg->arg[i], "char") == 0) { + info->param[info->paramCount] = arg->arg[i+1]; + } else if (strcmp(arg->arg[i], "Hex") == 0) { + if (ConvertHex(arg->arg[i + 1], &(info->hexParam[info->hexParamCount])) != 0) { + Print("\nERROR: Hex param conversion failed for:\n\"%s\"\n", arg->arg[i + 1]); + return 1; + } + info->param[info->paramCount] = &(info->hexParam[info->hexParamCount]); + info->hexParamCount++; + } else if (strcmp(arg->arg[i], "exp") == 0) { + int expId = 0; + if (ConvertInt(arg->arg[i + 1], &expId) != 0 || + getExpression(expId, &(info->intParam[info->intParamCount])) != 0) { + Print("\nERROR: Macro param conversion failed\n"); + return 1; + } + info->param[info->paramCount] = &(info->intParam[info->intParamCount]); + info->intParamCount++; + } else { + return 1; + } + info->paramCount++; + } + + return 0; +} + +static void PrintCaseNameResult(FILE *logFile, int vectorCount, int skipCount, int passCount, + const char *suiteName, time_t beginTime) +{ + static const char *outMem = "out of memory"; + int32_t dotCount = + (OUTPUT_LINE_LENGTH - (int32_t)strlen(suiteName) >= 4) ? (OUTPUT_LINE_LENGTH - (int32_t)strlen(suiteName)) : 4; + size_t suiteNameLen = strlen(suiteName); + char *suiteNameBuf = calloc(suiteNameLen + dotCount + 1, 1); + if (suiteNameBuf == NULL) { + suiteNameBuf = (char *)outMem; + } else { + memcpy_s(suiteNameBuf, suiteNameLen, suiteName, suiteNameLen); + memset_s(suiteNameBuf + suiteNameLen, OUTPUT_LINE_LENGTH - suiteNameLen, '.', dotCount); + } + int failCount = vectorCount - passCount - skipCount; + if (failCount == 0) { + Print("%sPASS || Run %-6d testcases, passed: %-6d, skipped: %-6d, failed: %-6d useSec:%-5lu\n", suiteNameBuf, + vectorCount, passCount, skipCount, failCount, time(NULL) - beginTime); + } else { + Print("%sFAIL || Run %-6d testcases, passed: %-6d, skipped: %-6d, failed: %-6d useSec:%-5lu\n", suiteNameBuf, + vectorCount, passCount, skipCount, failCount, time(NULL) - beginTime); + } + if (suiteNameBuf != outMem) { + free(suiteNameBuf); + } + time_t rawtime; + struct tm *timeinfo; + (void)time(&rawtime); + timeinfo = localtime(&rawtime); + (void)fprintf(logFile, "End time: %s", asctime(timeinfo)); + (void)fprintf(logFile, "Result: Run %d tests, Passed: %d, Skipped: %d, Failed: %d\n", vectorCount, passCount, + skipCount, failCount); +} + +static int ProcessCases(FILE *logFile, bool showDetail, int targetFuncId) +{ + (void)logFile; + volatile int vectorCount = 0; + volatile int passCount = 0; + volatile int skipCount = 0; + volatile int tryNum; + time_t beginTime = time(NULL); + for (volatile int i = 0; i < g_executeCount; i++) { + int funcId = strtoul(g_executeCases[i]->arg[0], NULL, 10); // 10 + if (funcId < 0 || funcId > ((int)(sizeof(test_funcs)/sizeof(TestWrapper)))) { + Print("funcId false!\n"); + return 1; + } + if ((targetFuncId != -1) && (funcId != targetFuncId)) { + continue; + } + (void)fprintf(logFile, "%s ", funcName[funcId]); + PrintCaseName(logFile, showDetail, g_executeCases[i]->testVectorName); + TestParam io; + if (ParseArgs(g_executeCases[i], &io) != 0) { + return -1; + } + TestWrapper fp = test_funcs[funcId]; + g_testResult.result = TEST_RESULT_SUCCEED; + tryNum = 0; + do { + if (tryNum > 0) { + sleep(10); + g_testResult.result = TEST_RESULT_SUCCEED; + } + tryNum++; +#ifdef ASAN + fp(io.param); +#else + // Executing Function + if (signal(SIGSEGV, handleSignal) == SIG_ERR) { + return -1; + } + int r = sigsetjmp(env, 1); + if (r == 0) { + fp(io.param); + } else if (r == 1){ + g_testResult.result = TEST_RESULT_FAILED; + } + if (isSubProc != 0) { + break; + } +#endif + } while ((g_testResult.result == TEST_RESULT_FAILED) && (tryNum < FAIL_TRY_TWICE)); + if (g_testResult.result == TEST_RESULT_SUCCEED) { + passCount++; + } else if (g_testResult.result == TEST_RESULT_SKIPPED) { + skipCount++; + } + vectorCount++; + PrintResult(showDetail, g_executeCases[i]->testVectorName); + PrintLog(logFile); + for (int j = 0; j < io.hexParamCount; j++) { + FreeHex(&io.hexParam[j]); + } + if (isSubProc != 0) { + break; + } + } + PrintCaseNameResult(logFile, vectorCount, skipCount, passCount, suiteName, beginTime); + return 0; +} + +static int ExecuteTest(const char *fileName, bool showDetail, int targetFuncId) +{ + if (LoadDataFile(fileName) != 0) { + return -1; + } + FILE *logFile = NULL; + char logFileName[MAX_FILE_NAME] = {0}; + if (targetFuncId == -1) { + if (sprintf_s(logFileName, MAX_FILE_NAME, SUITE_LOG_FORMAT, suiteName) <= 0) { + Print("An error occurred while creating the log file\n"); + return (-1); + } + } else { + if (sprintf_s(logFileName, MAX_FILE_NAME, FUNCTION_LOG_FORMAT, suiteName, funcName[targetFuncId]) <= 0) { + Print("An error occurred while creating the log file\n"); + return (-1); + } + } + time_t rawtime = time(NULL); + if (rawtime == 0) { + return -1; + } + logFile = fopen(logFileName, "w"); + if (logFile != NULL) { + struct tm *timeinfo; + timeinfo = localtime(&rawtime); + if (fprintf(logFile, "Begin time: %s", asctime(timeinfo)) <= 0) { + fclose(logFile); + return -1; + } + } + int rt = ProcessCases(logFile, showDetail, targetFuncId); + for (int i = 0; i < g_executeCount; i++) { + free(g_executeCases[i]); + } + if (logFile != NULL) { + fclose(logFile); + } + return rt; +} + +int ProcessMutiArgs(int argc, char **argv, const char *fileName) +{ + int printDetail = 1; + int curTestCnt = 0; + int ret = -1; + int testCnt = sizeof(test_funcs) / sizeof(test_funcs[0]); + int *funcIndex = malloc(sizeof(int) * testCnt); + int found; + + if (funcIndex == NULL) { + return ret; + } + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "NO_DETAIL") == 0) { + printDetail = 0; + continue; + } + found = 0; + for (int j = 0; j < testCnt; j++) { + if (strcmp(argv[i], funcName[j]) == 0) { + funcIndex[curTestCnt++] = j; + found = 1; + break; + } + } + if (found != 1) { + Print("test function '%s' do not exist\n", argv[i]); + goto exit; + } + } + + if (curTestCnt == 0) { + ret = ExecuteTest(fileName, printDetail, -1); + goto exit; + } + + for (int i = 0; i < curTestCnt; i++) { + if (ExecuteTest(fileName, printDetail, funcIndex[i]) != 0) { + goto exit; + } + } + ret = 0; + +exit: + free(funcIndex); + return ret; +} + +int main(int argc, char **argv) +{ + int ret = 0; +#ifndef PRINT_TO_TERMINAL + char testOutputName[MAX_FILE_NAME] = {0}; + if (sprintf_s(testOutputName, MAX_FILE_NAME, "%s.output", suiteName) <= 0) { + return 0; + } + FILE *fp = fopen(testOutputName, "w"); + if (fp == NULL) { + return 1; + } + SetOutputFile(fp); +#endif + char testName[MAX_FILE_PATH_LEN] = {0}; + if (sprintf_s(testName, MAX_FILE_PATH_LEN, "%s.datax", suiteName) <= 0) { + goto END; + } + if (argc == 1) { + ret = ExecuteTest(testName, 1, -1); + } else { + ret = ProcessMutiArgs(argc, argv, testName); + } + if (ret != 0) { + Print("execute test failed\n"); + } +END: +#ifndef PRINT_TO_TERMINAL + (void)fclose(fp); +#endif + return 0; +} diff --git a/testcode/demo/.gitignore b/testcode/demo/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/testcode/demo/CMakeLists.txt b/testcode/demo/CMakeLists.txt new file mode 100644 index 00000000..06089bc1 --- /dev/null +++ b/testcode/demo/CMakeLists.txt @@ -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. +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + +project(demo) + +message(status "HITLS_ROOT: ${HITLS_ROOT}") +set(HITLS_ROOT ../..) +set(HITLS_INCLUDE ${HITLS_ROOT}/include/bsl + ${HITLS_ROOT}/include/crypto + ${HITLS_ROOT}/include/tls + ${HITLS_ROOT}/x509/include + ${HITLS_ROOT}/platform/Secure_C/include) + +add_library(DEMO_INTF INTERFACE) +target_compile_options(DEMO_INTF INTERFACE -g) +target_link_directories(DEMO_INTF INTERFACE ${HITLS_ROOT}/build + ${HITLS_ROOT}/platform/Secure_C/lib/) +target_link_libraries(DEMO_INTF INTERFACE hitls_tls hitls_x509 hitls_crypto hitls_bsl boundscheck) +target_include_directories(DEMO_INTF INTERFACE ${HITLS_INCLUDE}) + +set(TESTS client.c server.c drbg.c ecdh.c pbkdf2.c sm2enc.c sm2sign.c sm4cbc.c) +foreach(testcase ${TESTS}) + get_filename_component(testname ${testcase} NAME_WLE) + add_executable(${testname} ${testcase}) + target_link_libraries(${testname} PRIVATE DEMO_INTF) +endforeach() diff --git a/testcode/demo/client.c b/testcode/demo/client.c new file mode 100644 index 00000000..872475ea --- /dev/null +++ b/testcode/demo/client.c @@ -0,0 +1,157 @@ +#include +#include + +#include +#include +#include +#include + +#include "securec.h" + +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_eal_rand.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "hitls.h" +#include "hitls_cert_init.h" +#include "hitls_cert.h" +#include "hitls_crypt_init.h" +#include "hitls_x509.h" + +#define CERTS_PATH "../../../testcode/testdata/tls/certificate/der/ecdsa_sha256/" +#define HTTP_BUF_MAXLEN (18 * 1024) /* 18KB */ + +int main(int32_t argc, char *argv[]) +{ + int32_t exitValue = -1; + int32_t ret = 0; + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + BSL_UIO *uio = NULL; + int fd = 0; + HITLS_X509_Cert *rootCA = NULL; + HITLS_X509_Cert *subCA = NULL; + + /* 注册BSL内存能力、仅供参考 */ + BSL_SAL_MemCallback memMthod = {(void *(*)(uint32_t size))malloc, free}; + BSL_SAL_RegMemCallback(&memMthod); + BSL_ERR_Init(); + + HITLS_CertMethodInit(); + CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + HITLS_CryptMethodInit(); + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) { + printf("Create socket failed.\n"); + return -1; + } + int option = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { + close(fd); + printf("setsockopt SO_REUSEADDR failed.\n"); + return -1; + } + + // Set the protocol and port number + struct sockaddr_in serverAddr; + (void)memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr)); + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(12345); + serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (connect(fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) { + printf("connect failed.\n"); + goto exit; + } + + config = HITLS_CFG_NewTLS12Config(); + if (config == NULL) { + printf("HITLS_CFG_NewTLS12Config failed.\n"); + goto exit; + } + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); // disable cert keyusage check + if (ret != HITLS_SUCCESS) { + printf("Disable check KeyUsage failed.\n"); + goto exit; + } + + /* 加载证书:需要用户实现 */ + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, CERTS_PATH "ca.der", &rootCA); + if (ret != HITLS_SUCCESS) { + printf("Parse ca failed.\n"); + goto exit; + } + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, CERTS_PATH "inter.der", &subCA); + if (ret != HITLS_SUCCESS) { + printf("Parse subca failed.\n"); + goto exit; + } + HITLS_CFG_AddCertToStore(config, rootCA, TLS_CERT_STORE_TYPE_DEFAULT, true); + HITLS_CFG_AddCertToStore(config, subCA, TLS_CERT_STORE_TYPE_DEFAULT, true); + + /* 新建openHiTLS上下文 */ + ctx = HITLS_New(config); + if (ctx == NULL) { + printf("HITLS_New failed.\n"); + goto exit; + } + + uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + if (uio == NULL) { + printf("BSL_UIO_New failed.\n"); + goto exit; + } + + ret = BSL_UIO_Ctrl(uio, BSL_UIO_SET_FD, (int32_t)sizeof(fd), &fd); + if (ret != HITLS_SUCCESS) { + BSL_UIO_Free(uio); + printf("BSL_UIO_SET_FD failed, fd = %u.\n", fd); + goto exit; + } + + ret = HITLS_SetUio(ctx, uio); + if (ret != HITLS_SUCCESS) { + BSL_UIO_Free(uio); + printf("HITLS_SetUio failed. ret = 0x%x.\n", ret); + goto exit; + } + + /* 进行TLS连接、用户需按实际场景考虑返回值 */ + ret = HITLS_Connect(ctx); + if (ret != HITLS_SUCCESS) { + printf("HITLS_Connect failed, ret = 0x%x.\n", ret); + goto exit; + } + + /* 向对端发送报文、用户需按实际场景考虑返回值 */ + const uint8_t sndBuf[] = "Hi, this is client\n"; + ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); + if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; + } + + /* 读取对端报文、用户需按实际场景考虑返回值 */ + uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; + uint32_t readLen = 0; + ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); + if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; + } + + printf("get from server size:%u :%s\n", readLen, readBuf); + + exitValue = 0; +exit: + HITLS_Close(ctx); + HITLS_Free(ctx); + HITLS_CFG_FreeConfig(config); + close(fd); + HITLS_X509_CertFree(rootCA); + HITLS_X509_CertFree(subCA); + return exitValue; +} \ No newline at end of file diff --git a/testcode/demo/drbg.c b/testcode/demo/drbg.c new file mode 100644 index 00000000..38c3eb6d --- /dev/null +++ b/testcode/demo/drbg.c @@ -0,0 +1,105 @@ +/* + * 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 +#include +#include +#include +#include "crypt_types.h" +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int ret; + uint8_t output[100] = {0}; + uint32_t len = 100; + + /** + * Before calling the algorithm APIs, + * call the BSL_SAL_RegMemCallback function to register the malloc and free functions. + * Execute this step only once. If the memory allocation ability of Linux is available, + * the two functions can be registered using Linux by default. + */ + BSL_SAL_RegMemCallback(&cb); + + BSL_ERR_Init(); // Initialize the error module. + + // Initialize the global random number by using the default entropy source from **/dev/random** of Linux. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Obtain the random number sequence of the **len** value. + ret = CRYPT_EAL_Randbytes(output, len); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("random value is: "); // Output the random number. + for (uint32_t i = 0; i < len; i++) { + printf("%02x", output[i]); + } + printf("\n"); + + // Reseeding + ret = CRYPT_EAL_RandSeed(); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandSeed: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Obtain the random number sequence of the **len** value. + ret = CRYPT_EAL_Randbytes(output, len); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("random value is: "); // Output the random number. + for (uint32_t i = 0; i < len; i++) { + printf("%02x", output[i]); + } + printf("\n"); + +exit: + // Release the context memory. + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return 0; +} \ No newline at end of file diff --git a/testcode/demo/ecdh.c b/testcode/demo/ecdh.c new file mode 100644 index 00000000..83d72bf4 --- /dev/null +++ b/testcode/demo/ecdh.c @@ -0,0 +1,160 @@ +/* + * 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 +#include +#include +#include +#include "crypt_types.h" +#include "crypt_eal_pkey.h" // Header file for key exchange. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int ret; + + uint8_t prikey[] = + {0x7d, 0x7d, 0xc5, 0xf7, 0x1e, 0xb2, 0x9d, 0xda, 0xf8, 0x0d, 0x62, 0x14, 0x63, 0x2e, 0xea, 0xe0, + 0x3d, 0x90, 0x58, 0xaf, 0x1f, 0xb6, 0xd2, 0x2e, 0xd8, 0x0b, 0xad, 0xb6, 0x2b, 0xc1, 0xa5, 0x34}; + uint8_t pubkey[] = + {0x04, 0x70, 0x0c, 0x48, 0xf7, 0x7f, 0x56, 0x58, 0x4c, 0x5c, 0xc6, 0x32, 0xca, 0x65, 0x64, 0x0d, 0xb9, + 0x1b, 0x6b, 0xac, 0xce, 0x3a, 0x4d, 0xf6, 0xb4, 0x2c, 0xe7, 0xcc, 0x83, 0x88, 0x33, 0xd2, 0x87, + 0xdb, 0x71, 0xe5, 0x09, 0xe3, 0xfd, 0x9b, 0x06, 0x0d, 0xdb, 0x20, 0xba, 0x5c, 0x51, 0xdc, 0xc5, + 0x94, 0x8d, 0x46, 0xfb, 0xf6, 0x40, 0xdf, 0xe0, 0x44, 0x17, 0x82, 0xca, 0xb8, 0x5f, 0xa4, 0xac}; + uint8_t resSharekey[] = + {0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xff, 0x01, 0x2e, 0x54, 0xa4, 0x34, 0xfb, 0xdd, 0x2d, 0x25, + 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b}; + + CRYPT_EAL_PkeyPrv prvKey = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + uint32_t shareLen; + uint8_t *shareKey; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_PKEY_ParaId id = CRYPT_ECC_NISTP256; + + BSL_ERR_Init(); // Initialize the error code module. + /** + * Before calling the algorithm APIs, + * call the BSL_SAL_RegMemCallback function to register the malloc and free functions. + * Execute this step only once. If the memory allocation ability of Linux is available, + * the two functions can be registered using Linux by default. + */ + BSL_SAL_RegMemCallback(&cb); + + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + if (prvCtx == NULL || pubCtx == NULL) { + goto exit; + } + + // Set the curve parameters. + ret = CRYPT_EAL_PkeySetParaById(prvCtx, id); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the private key of one end. + prvKey.id = CRYPT_PKEY_ECDH; + prvKey.key.eccPrv.len = sizeof(prikey); + prvKey.key.eccPrv.data = prikey; + ret = CRYPT_EAL_PkeySetPrv(prvCtx, &prvKey); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the curve parameters. + ret = CRYPT_EAL_PkeySetParaById(pubCtx, id); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the public key of the other end. + pubKey.id = CRYPT_PKEY_ECDH; + pubKey.key.eccPub.len = sizeof(pubkey); + pubKey.key.eccPub.data = pubkey; + ret = CRYPT_EAL_PkeySetPub(pubCtx, &pubKey); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // The shared key involves only the X axis. The length of the public key is not compressed in the returned results. + shareLen = CRYPT_EAL_PkeyGetKeyLen(prvCtx) / 2; + shareKey = (uint8_t *)BSL_SAL_Malloc(shareLen); + if (shareKey == NULL) { + ret = CRYPT_MEM_ALLOC_FAIL; + PrintLastError(); + goto exit; + } + + // Initialize the random number. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Calculate the shared key. + ret = CRYPT_EAL_PkeyComputeShareKey(prvCtx, pubCtx, shareKey, &shareLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Compare the calculation result with the expected one. + if (shareLen != sizeof(resSharekey) || memcmp(shareKey, resSharekey, shareLen) != 0) { + printf("failed to compare test results\n"); + ret = -1; + goto exit; + } + + printf("pass \n"); + +exit: + // Release the context memory. + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(prvCtx); + CRYPT_EAL_PkeyFreeCtx(pubCtx); + BSL_SAL_Free(shareKey); + BSL_ERR_DeInit(); + return 0; +} \ No newline at end of file diff --git a/testcode/demo/pbkdf2.c b/testcode/demo/pbkdf2.c new file mode 100644 index 00000000..c942a2f6 --- /dev/null +++ b/testcode/demo/pbkdf2.c @@ -0,0 +1,84 @@ +/* + * 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 +#include +#include +#include +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_eal_kdf.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int32_t ret; + uint8_t key[] = {0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64}; + uint8_t salt[] = {0x4e, 0x61, 0x43, 0x6c}; + uint32_t iterations = 80000; + uint8_t result[] = { + 0x4d, 0xdc, 0xd8, 0xf6, 0x0b, 0x98, 0xbe, 0x21, + 0x83, 0x0c, 0xee, 0x5e, 0xf2, 0x27, 0x01, 0xf9, + 0x64, 0x1a, 0x44, 0x18, 0xd0, 0x4c, 0x04, 0x14, + 0xae, 0xff, 0x08, 0x87, 0x6b, 0x34, 0xab, 0x56, + 0xa1, 0xd4, 0x25, 0xa1, 0x22, 0x58, 0x33, 0x54, + 0x9a, 0xdb, 0x84, 0x1b, 0x51, 0xc9, 0xb3, 0x17, + 0x6a, 0x27, 0x2b, 0xde, 0xbb, 0xa1, 0xd0, 0x78, + 0x47, 0x8f, 0x62, 0xb3, 0x97, 0xf3, 0x3c, 0x8d}; + + uint8_t out[sizeof(result)] = {0}; + uint32_t outLen = sizeof(result); + + // Initialize the error code module. + BSL_ERR_Init(); + + /** + * Before calling the algorithm APIs, + * call the BSL_SAL_RegMemCallback function to register the malloc and free functions. + * Execute this step only once. If the memory allocation ability of Linux is available, + * the two functions can be registered using Linux by default. + */ + BSL_SAL_RegMemCallback(&cb); + + ret = CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, sizeof(key), salt, sizeof(salt), iterations, out, outLen); + if (ret != CRYPT_SUCCESS) { + printf("pbkdf2 error code is %x\n", ret); + PrintLastError(); + goto exit; + } + if (memcmp(out, result, sizeof(result)) != 0) { + printf("failed to compare test results\n"); + ret = -1; + goto exit; + } + printf("pass \n"); +exit: + BSL_ERR_DeInit(); + return ret; +} \ No newline at end of file diff --git a/testcode/demo/server.c b/testcode/demo/server.c new file mode 100644 index 00000000..6b42b927 --- /dev/null +++ b/testcode/demo/server.c @@ -0,0 +1,174 @@ +#include +#include + +#include +#include +#include +#include + +#include "securec.h" + +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_eal_rand.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_encode.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "hitls.h" +#include "hitls_cert_init.h" +#include "hitls_cert.h" +#include "hitls_crypt_init.h" +#include "hitls_x509.h" + +#define CERTS_PATH "../../../testcode/testdata/tls/certificate/der/ecdsa_sha256/" +#define HTTP_BUF_MAXLEN (18 * 1024) /* 18KB */ + +int main(int32_t argc, char *argv[]) +{ + int32_t exitValue = -1; + int32_t ret = 0; + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + BSL_UIO *uio = NULL; + int fd = 0; + int infd = 0; + HITLS_X509_Cert *rootCA = NULL; + HITLS_X509_Cert *subCA = NULL; + HITLS_X509_Cert *serverCert = NULL; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + /* 注册BSL内存能力、仅供参考 */ + BSL_SAL_MemCallback memMthod = {(void *(*)(uint32_t size))malloc, free}; + BSL_SAL_RegMemCallback(&memMthod); + BSL_ERR_Init(); + + HITLS_CertMethodInit(); + CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + HITLS_CryptMethodInit(); + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) { + printf("Create socket failed.\n"); + return -1; + } + int option = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { + printf("setsockopt SO_REUSEADDR failed.\n"); + goto exit; + } + + struct sockaddr_in serverAddr; + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(12345); + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) { + printf("bind failed.\n"); + goto exit; + } + if (listen(fd, 5) != 0) { + printf("listen socket fail\n"); + goto exit; + } + + struct sockaddr_in clientAddr; + unsigned int len = sizeof(struct sockaddr_in); + infd = accept(fd, (struct sockaddr *)&clientAddr, &len); + if (infd < 0) { + printf("accept failed.\n"); + goto exit; + } + + config = HITLS_CFG_NewTLS12Config(); + if (config == NULL) { + printf("HITLS_CFG_NewTLS12Config failed.\n"); + goto exit; + } + ret = HITLS_CFG_SetClientVerifySupport(config, false); // disable peer verify + if (ret != HITLS_SUCCESS) { + printf("Disable peer verify faild.\n"); + goto exit; + } + + /* 加载证书:需要用户实现 */ + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, CERTS_PATH "ca.der", &rootCA); + if (ret != HITLS_SUCCESS) { + printf("Parse ca failed.\n"); + goto exit; + } + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, CERTS_PATH "inter.der", &subCA); + if (ret != HITLS_SUCCESS) { + printf("Parse subca failed.\n"); + goto exit; + } + HITLS_CFG_AddCertToStore(config, rootCA, TLS_CERT_STORE_TYPE_DEFAULT, true); + HITLS_CFG_AddCertToStore(config, subCA, TLS_CERT_STORE_TYPE_DEFAULT, true); + HITLS_CFG_LoadCertFile(config, CERTS_PATH "server.der", TLS_PARSE_FORMAT_ASN1); + HITLS_CFG_LoadKeyFile(config, CERTS_PATH "server.key.der", TLS_PARSE_FORMAT_ASN1); + + /* 新建openHiTLS上下文 */ + ctx = HITLS_New(config); + if (ctx == NULL) { + printf("HITLS_New failed.\n"); + goto exit; + } + + /* 用户可按需实现method */ + uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + if (uio == NULL) { + printf("BSL_UIO_New failed.\n"); + goto exit; + } + + ret = BSL_UIO_Ctrl(uio, BSL_UIO_SET_FD, (int32_t)sizeof(fd), &infd); + if (ret != HITLS_SUCCESS) { + BSL_UIO_Free(uio); + printf("BSL_UIO_SET_FD failed, fd = %u.\n", fd); + goto exit; + } + + ret = HITLS_SetUio(ctx, uio); + if (ret != HITLS_SUCCESS) { + BSL_UIO_Free(uio); + printf("HITLS_SetUio failed. ret = 0x%x.\n", ret); + goto exit; + } + + /* 进行TLS连接、用户需按实际场景考虑返回值 */ + ret = HITLS_Accept(ctx); + if (ret != HITLS_SUCCESS) { + printf("HITLS_Accept failed, ret = 0x%x.\n", ret); + goto exit; + } + + /* 读取对端报文、用户需按实际场景考虑返回值 */ + uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; + uint32_t readLen = 0; + ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); + if (ret != HITLS_SUCCESS) { + printf("HITLS_Read failed, ret = 0x%x.\n", ret); + goto exit; + } + printf("get from client size:%u :%s\n", readLen, readBuf); + + /* 向对端发送报文、用户需按实际场景考虑返回值 */ + const uint8_t sndBuf[] = "Hi, this is server\n"; + ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf)); + if (ret != HITLS_SUCCESS) { + printf("HITLS_Write error:error code:%d\n", ret); + goto exit; + } + exitValue = 0; +exit: + HITLS_Close(ctx); + HITLS_Free(ctx); + HITLS_CFG_FreeConfig(config); + close(fd); + close(infd); + HITLS_X509_CertFree(rootCA); + HITLS_X509_CertFree(subCA); + HITLS_X509_CertFree(serverCert); + CRYPT_EAL_PkeyFreeCtx(pkey); + return exitValue; +} \ No newline at end of file diff --git a/testcode/demo/sm2enc.c b/testcode/demo/sm2enc.c new file mode 100644 index 00000000..9dd59a2d --- /dev/null +++ b/testcode/demo/sm2enc.c @@ -0,0 +1,107 @@ +/* + * 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 +#include +#include +#include +#include "crypt_eal_pkey.h" // Header file of the interfaces for asymmetric encryption and decryption. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" +#include "crypt_types.h" + +void *StdMalloc(uint32_t len) { + return malloc((uint32_t)len); +} +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) { + int32_t ret; + BSL_ERR_Init(); // Initialize the error code module. + /** + * Before calling the algorithm APIs, + * call the BSL_SAL_RegMemCallback function to register the malloc and free functions. + * Execute this step only once. If the memory allocation ability of Linux is available, + * the two functions can be registered using Linux by default. + */ + BSL_SAL_RegMemCallback(&cb); + CRYPT_EAL_PkeyCtx *pkey = NULL; + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (pkey == NULL) { + PrintLastError(); + goto exit; + } + + // Initialize the random number. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_RandInit: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Generate a key pair. + ret = CRYPT_EAL_PkeyGen(pkey); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyGen: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Data to be encrypted. + char *data = "test enc data"; + uint32_t dataLen = 12; + uint8_t ecrypt[125] = {0}; + uint32_t ecryptLen = 125; + uint8_t dcrypt[125] = {0}; + uint32_t dcryptLen = 125; + // Encrypt data. + ret = CRYPT_EAL_PkeyEncrypt(pkey, data, dataLen, ecrypt, &ecryptLen); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyEncrypt: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Decrypt data. + ret = CRYPT_EAL_PkeyDecrypt(pkey, ecrypt, ecryptLen, dcrypt, &dcryptLen); + if (ret != CRYPT_SUCCESS) { + printf("CRYPT_EAL_PkeyDecrypt: error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + if (memcmp(dcrypt, data, dataLen) == 0) { + printf("encrypt and decrypt success\n"); + } else { + ret = -1; + } +exit: + // Release the context memory. + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return ret; +} \ No newline at end of file diff --git a/testcode/demo/sm2sign.c b/testcode/demo/sm2sign.c new file mode 100644 index 00000000..f7e5af6a --- /dev/null +++ b/testcode/demo/sm2sign.c @@ -0,0 +1,113 @@ +/* + * 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 +#include +#include +#include +#include "crypt_eal_pkey.h" // Header file for signature verification. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line);// Obtain the name and number of lines of the error file. + printf("failed at file %s at line %d\n", file, line); +} +BSL_SAL_MemCallback cb = {StdMalloc, free}; + +int main(void) +{ + int ret; + uint8_t userId[32] = {0}; + uint8_t key[32] = {0}; + uint8_t msg[32] = {0}; + uint8_t signBuf[100] = {0}; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx = NULL; + + BSL_ERR_Init(); // Initialize the error code module. + /** + * Before calling the algorithm APIs, + * call the BSL_SAL_RegMemCallback function to register the malloc and free functions. + * Execute this step only once. If the memory allocation ability of Linux is available, + * the two functions can be registered using Linux by default. + */ + BSL_SAL_RegMemCallback(&cb); + + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (ctx == NULL) { + goto exit; + } + + // Set a user ID. + ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Initialize the random number. + ret = CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Generate a key pair. + ret = CRYPT_EAL_PkeyGen(ctx); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Sign. + ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Verify the signature. + ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + printf("pass \n"); + +exit: + // Release the context memory. + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_RandDeinit(); + BSL_ERR_DeInit(); + return ret; +} \ No newline at end of file diff --git a/testcode/demo/sm4cbc.c b/testcode/demo/sm4cbc.c new file mode 100644 index 00000000..e8ff9938 --- /dev/null +++ b/testcode/demo/sm4cbc.c @@ -0,0 +1,182 @@ +/* + * 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 +#include +#include +#include +#include "crypt_eal_cipher.h" // Header file of the interfaces for symmetric encryption and decryption. +#include "bsl_sal.h" +#include "bsl_err.h" +#include "crypt_algid.h" // Algorithm ID list. +#include "crypt_errno.h" // Error code list. + +void *StdMalloc(uint32_t len) { + return malloc((size_t)len); +} + +void PrintLastError(void) { + const char *file = NULL; + uint32_t line = 0; + BSL_ERR_GetLastErrorFileLine(&file, &line); // Obtain the name and number of lines of the error file. + printf("failed at file %s at line %d\n", file, line); +} + +BSL_SAL_MemCallback cb = { StdMalloc, free }; // Registered interfaces for memory allocation. + +int main(void) +{ + uint8_t data[10] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x1c, 0x14}; + uint8_t iv[16] = {0}; + uint8_t key[16] = {0}; + uint32_t dataLen = sizeof(data); + uint8_t cipherText[100]; + uint8_t plainText[100]; + uint32_t outTotalLen = 0; + uint32_t outLen = sizeof(cipherText); + uint32_t cipherTextLen; + int32_t ret; + + printf("plain text to be encrypted: "); + for (uint32_t i = 0; i < dataLen; i++) { + printf("%02x", data[i]); + } + printf("\n"); + + // Initialize the error code module. + BSL_ERR_Init(); + + /** + * Before calling the algorithm APIs, + * call the BSL_SAL_RegMemCallback function to register the malloc and free functions. + * Execute this step only once. If the memory allocation ability of Linux is available, + * the two functions can be registered using Linux by default. + */ + BSL_SAL_RegMemCallback(&cb); + + // Create a context. + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC); + if (ctx == NULL) { + PrintLastError(); + BSL_ERR_DeInit(); + return 1; + } + /* + * During initialization, the last input parameter can be true or false. true indicates encryption, + * and false indicates decryption. + */ + ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true); + if (ret != CRYPT_SUCCESS) { + // Output the error code. You can find the error information in **crypt_errno.h** based on the error code. + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + // Set the padding mode. + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + /** + * Enter the data to be calculated. This interface can be called for multiple times. + * The input value of **outLen** is the length of the ciphertext, + * and the output value is the amount of processed data. + * + */ + ret = CRYPT_EAL_CipherUpdate(ctx, data, dataLen, cipherText, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + outLen = sizeof(cipherText) - outTotalLen; + + ret = CRYPT_EAL_CipherFinal(ctx, cipherText + outTotalLen, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + printf("cipher text value is: "); + + for (uint32_t i = 0; i < outTotalLen; i++) { + printf("%02x", cipherText[i]); + } + printf("\n"); + + // Start decryption. + cipherTextLen = outTotalLen; + outTotalLen = 0; + outLen = sizeof(plainText); + + // When initializing the decryption function, set the last input parameter to false. + ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), false); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Set the padding mode, which must be the same as that for encryption. + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + // Enter the ciphertext data. + ret = CRYPT_EAL_CipherUpdate(ctx, cipherText, cipherTextLen, plainText, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + outTotalLen += outLen; + outLen = sizeof(plainText) - outTotalLen; + + // Decrypt the last segment of data and remove the filled content. + ret = CRYPT_EAL_CipherFinal(ctx, plainText + outTotalLen, &outLen); + if (ret != CRYPT_SUCCESS) { + printf("error code is %x\n", ret); + PrintLastError(); + goto exit; + } + + outTotalLen += outLen; + + printf("decrypted plain text value is: "); + for (uint32_t i = 0; i < outTotalLen; i++) { + printf("%02x", plainText[i]); + } + printf("\n"); + + if (outTotalLen != dataLen || memcmp(plainText, data, dataLen) != 0) { + printf("plaintext comparison failed\n"); + goto exit; + } + printf("pass \n"); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + BSL_ERR_DeInit(); + return ret; +} \ No newline at end of file diff --git a/testcode/framework/crypto/alg_check.c b/testcode/framework/crypto/alg_check.c new file mode 100644 index 00000000..0ea5f2a5 --- /dev/null +++ b/testcode/framework/crypto/alg_check.c @@ -0,0 +1,445 @@ +/* + * 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 +#include "helper.h" + +#include "crypt_algid.h" +#include "hitls_build.h" +#include "crypto_test_util.h" + +#define ERR_ID (-1) + +typedef struct { + int id; + int offset; +} MdAlgMap; + +static MdAlgMap g_mdAlgMap[] = { + { CRYPT_MD_MD5, 0 }, + { CRYPT_MD_SHA1, 1 }, + { CRYPT_MD_SHA224, 2 }, + { CRYPT_MD_SHA256, 3 }, + { CRYPT_MD_SHA384, 4 }, + { CRYPT_MD_SHA512, 5 }, + { CRYPT_MD_SHA3_224, 6 }, + { CRYPT_MD_SHA3_256, 7 }, + { CRYPT_MD_SHA3_384, 8 }, + { CRYPT_MD_SHA3_512, 9 }, + { CRYPT_MD_SHAKE128, 10 }, + { CRYPT_MD_SHAKE256, 11 }, + { CRYPT_MD_SM3, 12 }, +}; + +#define MD_ALG_MAP_CNT ((int)(sizeof(g_mdAlgMap) / sizeof(MdAlgMap))) + +// All MD algorithms are available by default. +static int g_mdDisableTable[MD_ALG_MAP_CNT] = { 0 }; +static bool g_isInitMd = false; + +static int g_avlRandAlg = -1; +static bool g_isInitRandAlg = false; + +static void InitMdTable(void) +{ + if (g_isInitMd) { + return; + } +#ifndef HITLS_CRYPTO_MD5 + g_mdDisableTable[0] = 1; +#endif +#ifndef HITLS_CRYPTO_SHA1 + g_mdDisableTable[1] = 1; +#endif +#ifndef HITLS_CRYPTO_SHA224 + g_mdDisableTable[2] = 1; +#endif +#ifndef HITLS_CRYPTO_SHA256 + g_mdDisableTable[3] = 1; +#endif +#ifndef HITLS_CRYPTO_SHA384 + g_mdDisableTable[4] = 1; +#endif +#ifndef HITLS_CRYPTO_SHA512 + g_mdDisableTable[5] = 1; +#endif +#ifndef HITLS_CRYPTO_SHA3 + g_mdDisableTable[6] = 1; + g_mdDisableTable[7] = 1; + g_mdDisableTable[8] = 1; + g_mdDisableTable[9] = 1; + g_mdDisableTable[10] = 1; + g_mdDisableTable[11] = 1; +#endif +#ifndef HITLS_CRYPTO_SM3 + g_mdDisableTable[12] = 1; +#endif + g_isInitMd = true; +} + +static bool IsDrbgHashDisabled(void) +{ +#ifdef HITLS_CRYPTO_DRBG_HASH + return false; +#else + return true; +#endif +} + +static bool IsDrbgHmacDisabled(void) +{ +#ifdef HITLS_CRYPTO_DRBG_HMAC + return false; +#else + return true; +#endif +} + +static bool IsDrbgCtrDisabled(void) +{ +#ifdef HITLS_CRYPTO_DRBG_CTR + return false; +#else + return true; +#endif +} + +static int GetDrbgHashAlgId(void) +{ + InitMdTable(); + // CRYPT_RAND_SHA256 is preferred (224 depends on 256). + if (g_mdDisableTable[3] == 0) { + return CRYPT_RAND_SHA256; + } + + if (g_mdDisableTable[5] == 0) { + return CRYPT_RAND_SHA512; + } + + if (g_mdDisableTable[1] == 0) { + return CRYPT_RAND_SHA1; + } + return ERR_ID; +} + +static int GetDrbgHmacAlgId(void) +{ + InitMdTable(); + if (g_mdDisableTable[3] == 0) { + return CRYPT_RAND_HMAC_SHA256; + } + + if (g_mdDisableTable[5] == 0) { + return CRYPT_RAND_HMAC_SHA512; + } + + if (g_mdDisableTable[1] == 0) { + return CRYPT_RAND_HMAC_SHA1; + } + return ERR_ID; +} + +bool IsMdAlgDisabled(int id) +{ + InitMdTable(); + bool res = false; // By default, this algorithm is not disabled. + + for (int i = 0; i < MD_ALG_MAP_CNT; i++) { + if (id == g_mdAlgMap[i].id) { + res = g_mdDisableTable[g_mdAlgMap[i].offset] == 1; + break; + } + } + return res; +} + +bool IsHmacAlgDisabled(int id) +{ +#ifdef HITLS_CRYPTO_HMAC + InitMdTable(); + switch (id) { + case CRYPT_MAC_HMAC_MD5: + return g_mdDisableTable[0] == 1; + case CRYPT_MAC_HMAC_SHA1: + return g_mdDisableTable[1] == 1; + case CRYPT_MAC_HMAC_SHA224: + return g_mdDisableTable[2] == 1; + case CRYPT_MAC_HMAC_SHA256: + return g_mdDisableTable[3] == 1; + case CRYPT_MAC_HMAC_SHA384: + return g_mdDisableTable[4] == 1; + case CRYPT_MAC_HMAC_SHA512: + return g_mdDisableTable[5] == 1; + case CRYPT_MAC_HMAC_SHA3_224: + return g_mdDisableTable[6] == 1; + case CRYPT_MAC_HMAC_SHA3_256: + return g_mdDisableTable[7] == 1; + case CRYPT_MAC_HMAC_SHA3_384: + return g_mdDisableTable[8] == 1; + case CRYPT_MAC_HMAC_SHA3_512: + return g_mdDisableTable[9] == 1; + case CRYPT_MAC_HMAC_SM3: + return g_mdDisableTable[12] == 1; + default: + return false; + } +#else + (void)id; + return false; +#endif +} + +bool IsMacAlgDisabled(int id) +{ + switch (id) { + case CRYPT_MAC_HMAC_MD5: + case CRYPT_MAC_HMAC_SHA1: + case CRYPT_MAC_HMAC_SHA224: + case CRYPT_MAC_HMAC_SHA256: + case CRYPT_MAC_HMAC_SHA384: + case CRYPT_MAC_HMAC_SHA512: + case CRYPT_MAC_HMAC_SM3: + return IsHmacAlgDisabled(id); + default: + return false; + } +} + +bool IsDrbgHashAlgDisabled(int id) +{ + if (IsDrbgHashDisabled()) { + return true; + } + InitMdTable(); + switch (id) { + case CRYPT_RAND_SHA1: + return g_mdDisableTable[1] == 1; + case CRYPT_RAND_SHA224: + return g_mdDisableTable[2] == 1; + case CRYPT_RAND_SHA256: + return g_mdDisableTable[3] == 1; + case CRYPT_RAND_SHA384: + return g_mdDisableTable[4] == 1; + case CRYPT_RAND_SHA512: + return g_mdDisableTable[5] == 1; + default: + return false; + } +} + +bool IsDrbgHmacAlgDisabled(int id) +{ + if (IsDrbgHmacDisabled()) { + return true; + } + InitMdTable(); + switch (id) { + case CRYPT_RAND_HMAC_SHA1: + return g_mdDisableTable[1] == 1; + case CRYPT_RAND_HMAC_SHA224: + return g_mdDisableTable[2] == 1; + case CRYPT_RAND_HMAC_SHA256: + return g_mdDisableTable[3] == 1; + case CRYPT_RAND_HMAC_SHA384: + return g_mdDisableTable[4] == 1; + case CRYPT_RAND_HMAC_SHA512: + return g_mdDisableTable[5] == 1; + default: + return false; + } +} + +int GetAvailableRandAlgId(void) +{ + if (g_isInitRandAlg) { + return g_avlRandAlg; + } + g_isInitRandAlg = true; + + if (!IsDrbgHashDisabled()) { + g_avlRandAlg = GetDrbgHashAlgId(); + if (g_avlRandAlg != ERR_ID) { + return g_avlRandAlg; + } + } + + if (!IsDrbgHmacDisabled()) { + g_avlRandAlg = GetDrbgHmacAlgId(); + if (g_avlRandAlg != ERR_ID) { + return g_avlRandAlg; + } + } + + if (!IsDrbgCtrDisabled()) { + g_avlRandAlg = CRYPT_RAND_AES256_CTR; + return g_avlRandAlg; + } + + return g_avlRandAlg; +} + +bool IsRandAlgDisabled(int id) +{ + switch (id) { + case CRYPT_RAND_SHA1: + case CRYPT_RAND_SHA224: + case CRYPT_RAND_SHA256: + case CRYPT_RAND_SHA384: + case CRYPT_RAND_SHA512: + return IsDrbgHashAlgDisabled(id); + case CRYPT_RAND_HMAC_SHA1: + case CRYPT_RAND_HMAC_SHA224: + case CRYPT_RAND_HMAC_SHA256: + case CRYPT_RAND_HMAC_SHA384: + case CRYPT_RAND_HMAC_SHA512: + return IsDrbgHmacAlgDisabled(id); + case CRYPT_RAND_AES128_CTR: + case CRYPT_RAND_AES192_CTR: + case CRYPT_RAND_AES256_CTR: + case CRYPT_RAND_AES128_CTR_DF: + case CRYPT_RAND_AES192_CTR_DF: + case CRYPT_RAND_AES256_CTR_DF: + return IsDrbgCtrDisabled(); + default: + return false; + } + return false; +} + +bool IsAesAlgDisabled(int id) +{ +#ifdef HITLS_CRYPTO_AES + switch (id) { +#ifndef HITLS_CRYPTO_CBC + case CRYPT_CIPHER_AES128_CBC: + case CRYPT_CIPHER_AES192_CBC: + case CRYPT_CIPHER_AES256_CBC: + return true; +#endif +#ifndef HITLS_CRYPTO_CTR + case CRYPT_CIPHER_AES128_CTR: + case CRYPT_CIPHER_AES192_CTR: + case CRYPT_CIPHER_AES256_CTR: + return true; +#endif +#ifndef HITLS_CRYPTO_CCM + case CRYPT_CIPHER_AES128_CCM: + case CRYPT_CIPHER_AES192_CCM: + case CRYPT_CIPHER_AES256_CCM: + return true; +#endif +#ifndef HITLS_CRYPTO_GCM + case CRYPT_CIPHER_AES128_GCM: + case CRYPT_CIPHER_AES192_GCM: + case CRYPT_CIPHER_AES256_GCM: + return true; +#endif +#ifndef HITLS_CRYPTO_CFB + case CRYPT_CIPHER_AES128_CFB: + case CRYPT_CIPHER_AES192_CFB: + case CRYPT_CIPHER_AES256_CFB: + return true; +#endif +#ifndef HITLS_CRYPTO_OFB + case CRYPT_CIPHER_AES128_OFB: + case CRYPT_CIPHER_AES192_OFB: + case CRYPT_CIPHER_AES256_OFB: + return true; +#endif + default: + return false; // Unsupported algorithm ID + } +#else + (void)id; + return true; +#endif +} + +bool IsSm4AlgDisabled(int id) +{ +#ifdef HITLS_CRYPTO_SM4 + switch (id) { +#ifndef HITLS_CRYPTO_XTS + case CRYPT_CIPHER_SM4_XTS: + return true; +#endif +#ifndef HITLS_CRYPTO_CBC + case CRYPT_CIPHER_SM4_CBC: + return true; +#endif +#ifndef HITLS_CRYPTO_CTR + case CRYPT_CIPHER_SM4_CTR: + return true; +#endif +#ifndef HITLS_CRYPTO_GCM + case CRYPT_CIPHER_SM4_GCM: + return true; +#endif +#ifndef HITLS_CRYPTO_CFB + case CRYPT_CIPHER_SM4_CFB: + return true; +#endif +#ifndef HITLS_CRYPTO_OFB + case CRYPT_CIPHER_SM4_OFB: + return true; +#endif + default: + return false; // Unsupported algorithm ID + } +#else + (void)id; + return true; +#endif +} + +bool IsCipherAlgDisabled(int id) +{ + switch (id) { + case CRYPT_CIPHER_AES128_CBC: + case CRYPT_CIPHER_AES192_CBC: + case CRYPT_CIPHER_AES256_CBC: + case CRYPT_CIPHER_AES128_CTR: + case CRYPT_CIPHER_AES192_CTR: + case CRYPT_CIPHER_AES256_CTR: + case CRYPT_CIPHER_AES128_CCM: + case CRYPT_CIPHER_AES192_CCM: + case CRYPT_CIPHER_AES256_CCM: + case CRYPT_CIPHER_AES128_GCM: + case CRYPT_CIPHER_AES192_GCM: + case CRYPT_CIPHER_AES256_GCM: + case CRYPT_CIPHER_AES128_CFB: + case CRYPT_CIPHER_AES192_CFB: + case CRYPT_CIPHER_AES256_CFB: + case CRYPT_CIPHER_AES128_OFB: + case CRYPT_CIPHER_AES192_OFB: + case CRYPT_CIPHER_AES256_OFB: + return IsAesAlgDisabled(id); + case CRYPT_CIPHER_CHACHA20_POLY1305: +#if !defined(HITLS_CRYPTO_CHACHA20) && !defined(HITLS_CRYPTO_CHACHA20POLY1305) + return true; +#else + return false; +#endif + case CRYPT_CIPHER_SM4_XTS: + case CRYPT_CIPHER_SM4_CBC: + case CRYPT_CIPHER_SM4_CTR: + case CRYPT_CIPHER_SM4_GCM: + case CRYPT_CIPHER_SM4_CFB: + case CRYPT_CIPHER_SM4_OFB: + return IsSm4AlgDisabled(id); + default: + return false; + } +} diff --git a/testcode/framework/crypto/crypto_test_util.c b/testcode/framework/crypto/crypto_test_util.c new file mode 100644 index 00000000..09568655 --- /dev/null +++ b/testcode/framework/crypto/crypto_test_util.c @@ -0,0 +1,106 @@ +/* + * 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 + +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_eal_rand.h" + +#include "helper.h" +#include "crypto_test_util.h" + +#ifndef HITLS_BSL_SAL_MEM +void *TestMalloc(uint32_t len) +{ + return malloc((size_t)len); +} +#endif + +void TestMemInit(void) +{ +#ifdef HITLS_BSL_SAL_MEM + return; +#else + static BSL_SAL_MemCallback cb = {TestMalloc, free}; + BSL_SAL_RegMemCallback(&cb); +#endif +} + +#if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_DRBG) +typedef struct { + CRYPT_Data *entropy; + CRYPT_Data *nonce; + CRYPT_Data *pers; + + CRYPT_Data *addin1; + CRYPT_Data *entropyPR1; + + CRYPT_Data *addin2; + CRYPT_Data *entropyPR2; + + CRYPT_Data *retBits; +} DRBG_Vec_t; + +#ifdef HITLS_CRYPTO_ENTROPY +static int32_t GetEntropy(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + if (lenRange == NULL) { + Print("getEntropy Error lenRange NULL\n"); + return CRYPT_NULL_INPUT; + } + if (ctx == NULL || entropy == NULL) { + Print("getEntropy Error\n"); + lenRange->max = strength; + return CRYPT_NULL_INPUT; + } + + DRBG_Vec_t *seedCtx = (DRBG_Vec_t *)ctx; + + entropy->data = seedCtx->entropy->data; + entropy->len = seedCtx->entropy->len; + + return CRYPT_SUCCESS; +} + +static void CleanEntropy(void *ctx, CRYPT_Data *entropy) +{ + (void)ctx; + (void)entropy; + return; +} +#endif + +int TestRandInit(void) +{ + int drbgAlgId = GetAvailableRandAlgId(); + if (drbgAlgId == -1) { + Print("Drbg algs are disabled."); + return CRYPT_NOT_SUPPORT; + } + +#ifdef HITLS_CRYPTO_ENTROPY + CRYPT_RandSeedMethod seedMeth = {GetEntropy, CleanEntropy, NULL, NULL}; + uint8_t entropy[64] = {0}; + CRYPT_Data tempEntropy = {entropy, sizeof(entropy)}; + DRBG_Vec_t seedCtx = {0}; + seedCtx.entropy = &tempEntropy; + return CRYPT_EAL_RandInit(drbgAlgId, &seedMeth, (void *)&seedCtx, NULL, 0); +#else + return CRYPT_EAL_RandInit(drbgAlgId, NULL, NULL, NULL, 0); +#endif +} +#endif diff --git a/testcode/framework/crypto/crypto_test_util.h b/testcode/framework/crypto/crypto_test_util.h new file mode 100644 index 00000000..07f30e30 --- /dev/null +++ b/testcode/framework/crypto/crypto_test_util.h @@ -0,0 +1,51 @@ +/* + * 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 CRYPTO_TEST_UTIL_H +#define CRYPTO_TEST_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +void TestMemInit(void); + +int TestRandInit(void); + +bool IsMdAlgDisabled(int id); + +bool IsHmacAlgDisabled(int id); + +bool IsMacAlgDisabled(int id); + +bool IsDrbgHashAlgDisabled(int id); + +bool IsDrbgHmacAlgDisabled(int id); + +int GetAvailableRandAlgId(); + +bool IsRandAlgDisabled(int id); + +bool IsAesAlgDisabled(int id); + +bool IsSm4AlgDisabled(int id); + +bool IsCipherAlgDisabled(int id); + +#ifdef __cplusplus +} +#endif + +#endif // CRYPTO_TEST_UTIL_H \ No newline at end of file diff --git a/testcode/framework/gen_test/CMakeLists.txt b/testcode/framework/gen_test/CMakeLists.txt new file mode 100644 index 00000000..cda87b5a --- /dev/null +++ b/testcode/framework/gen_test/CMakeLists.txt @@ -0,0 +1,47 @@ +# 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(GEN_TEST) + +set(GEN_TESTCASE "gen_testcase") +set(HITLS_SRC ${PROJECT_SOURCE_DIR}/../../..) +set(EXECUTABLE_OUTPUT_PATH ${HITLS_SRC}/testcode/output) +set(SECURTE_INCLUDE ${HITLS_SRC}/platform/Secure_C/include) +set(GEN_SOURCE_SRC + ${PROJECT_SOURCE_DIR}/main.c + ${PROJECT_SOURCE_DIR}/helper.c + ${PROJECT_SOURCE_DIR}/test.c +) + +include_directories(${SECURTE_INCLUDE} + ${HITLS_SRC}/testcode/framework/include + ${HITLS_SRC}/testcode/framework/crypto + ${HITLS_SRC}/crypto/include + ${HITLS_SRC}/include/crypto + ${HITLS_SRC}/include/bsl +) + +add_executable(${GEN_TESTCASE} ${GEN_SOURCE_SRC}) + +if(PRINT_TO_TERMINAL) + target_compile_options(${GEN_TESTCASE} PUBLIC -DPRINT_TO_TERMINAL) +endif() + +target_link_directories(${GEN_TESTCASE} + PUBLIC + ${HITLS_SRC}/platform/Secure_C/lib +) +target_link_libraries(${GEN_TESTCASE} + -lboundscheck +) diff --git a/testcode/framework/gen_test/helper.c b/testcode/framework/gen_test/helper.c new file mode 100644 index 00000000..c4597a35 --- /dev/null +++ b/testcode/framework/gen_test/helper.c @@ -0,0 +1,1173 @@ +/* + * 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 "helper.h" +#include +#include "securec.h" +#include "crypt_utils.h" + +#define INCLUDE_BASE "/* INCLUDE_BASE" +#define BEGIN_HEADER "/* BEGIN_HEADER */" +#define END_HEADER "/* END_HEADER */" +#define BEGIN_CASE "/* BEGIN_CASE */" +#define END_CASE "/* END_CASE */" + +#define PRINT_TESTSUITES_TAG "\n" +#define PRINT_TESTSUITE_TAG " \n" +#define PRINT_TESTCASE_TAG " \n" +#define PRINT_TESTCASE_LIST_TAG " \n" +#define PRINT_FAILURE_TAG " \n" + +#define LINE_BREAK_SYMBOL '\n' +#define LINE_HEAD_SYMBOL '\r' + +FunctionTable g_testFunc[MAX_TEST_FUCNTION_COUNT]; +int g_testFuncCount = 0; +char g_expTable[MAX_EXPRESSION_COUNT][MAX_EXPRESSION_LEN]; +int g_expCount = 0; +FILE *g_fpOutput = NULL; +int g_lineCount = 0; +char g_suiteFileName[MAX_FILE_PATH_LEN]; + +void SetOutputFile(FILE *fp) +{ + g_fpOutput = fp; +} + +FILE *GetOutputFile(void) +{ + return g_fpOutput; +} + +void FreeHex(Hex *data) +{ + if (data == NULL) { + return; + } + data->len = 0; + if (data->x != NULL) { + free(data->x); + data->x = NULL; + } +} + +Hex *NewHex(void) +{ + Hex *data = (Hex *)malloc(sizeof(Hex)); + if (data == NULL) { + return NULL; + } + data->len = 0; + data->x = NULL; + return data; +} + +int IsInt(const char *str) +{ + uint32_t i = 0; + if (str[0] == '-') { + i = 1; + } + for (; i < strlen(str); i++) { + if (str[i] > '9' || str[i] < '0') { + return 0; + } + } + return 1; +} + +void Print(const char *fmt, ...) +{ +#ifdef PRINT_TO_TERMINAL + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +#else + va_list args; + va_start(args, fmt); + (void)vfprintf(g_fpOutput, fmt, args); + va_end(args); +#endif +} + +int ReadLine(FILE *file, char *buf, uint32_t bufLen, bool skipHash, bool skipEmptyLine) +{ + int foundLine = 0; + int i; + char *ret = NULL; + while (!foundLine) { + ret = fgets(buf, bufLen, file); + if (ret == NULL) { + return -1; + } + g_lineCount++; + + int len = strlen(buf); + if ((buf[0] == '#') && skipHash) { + continue; + } + if (!skipEmptyLine) { + foundLine = 1; + } + for (i = 0; i < len; i++) { + char cur = buf[i]; + if (cur != ' ' && cur != LINE_BREAK_SYMBOL && cur != LINE_HEAD_SYMBOL) { + foundLine = 1; + } + if (cur == LINE_BREAK_SYMBOL || cur == LINE_HEAD_SYMBOL) { + buf[i] = '\0'; + break; + } + } + } + return 0; +} + +int SplitArguments(char *inStr, uint32_t inLen, char **outParam, uint32_t *paramLen) +{ + uint32_t cur = 0; + uint32_t count = 0; + bool inString = false; + char *in = inStr; + char **param = outParam; + + param[count] = &in[cur]; + count++; + cur++; + if (count > *paramLen) { + return 1; + } + while (cur < inLen && in[cur] != '\0') { + if (in[cur] == '\"') { + inString = !inString; + } + if (in[cur] == ':' && !inString) { + if (cur == inLen - 1) { + param[count] = &in[cur]; + } else { + param[count] = &in[cur + 1]; + count++; + } + if (count > *paramLen) { + printf("Exceed maximum param limit, expect num %u, actual num %u\n", + *paramLen, count); + return 1; + } + in[cur] = '\0'; + } + cur++; + } + if (in[cur - 1] == '\n') { + in[cur - 1] = '\0'; + } + + *paramLen = count; + if (inString) { + return 1; + } + return 0; +} +static int g_fuzzEnd = 0; +int CheckTag(char *in, uint32_t len) +{ + char *cur = in; + while (*cur == ' ') { + cur++; + } + + uint32_t beginHeaderLen = strlen(BEGIN_HEADER); + uint32_t endHeaderLen = strlen(END_HEADER); + uint32_t beginCaseLen = strlen(BEGIN_CASE); + uint32_t endCaseLen = strlen(END_CASE); + uint32_t includeBaseLen = strlen(INCLUDE_BASE); + + if ((len >= beginHeaderLen) && (strlen(cur) >= beginHeaderLen) && + (strncmp(cur, BEGIN_HEADER, beginHeaderLen) == 0)) { + return TAG_BEGIN_HEADER; + } else if ((len >= endHeaderLen) && (strlen(cur) >= endHeaderLen) && + (strncmp(cur, END_HEADER, endHeaderLen) == 0)) { + return TAG_END_HEADER; + } else if ((len >= beginCaseLen) && (strlen(cur) >= beginCaseLen) && + (strncmp(cur, BEGIN_CASE, beginCaseLen) == 0)) { + return TAG_BEGIN_CASE; + } else if ((len >= endCaseLen) && (strlen(cur) >= endCaseLen) && + (strncmp(cur, END_CASE, endCaseLen) == 0)) { + return TAG_END_CASE; + } else if ((len >= includeBaseLen) && (strlen(cur) >= includeBaseLen) && + (strncmp(cur, INCLUDE_BASE, includeBaseLen) == 0)) { + return TAG_INCLUDE_BASE; + } + return TAG_NOT_TAG; +} + +static int ClearVoid(const char *in, const uint32_t inLen, uint32_t *cur, uint32_t *prev) +{ + uint32_t localCur = *cur; + uint32_t localPrev; + while (localCur < inLen && in[localCur] == ' ') { + localCur++; + } + localPrev = localCur; + + if (strncmp(&in[localCur], "void", strlen("void")) != 0) { + return 1; + } + + localCur += strlen("void"); + while (localCur < inLen && in[localCur] == ' ') { + localCur++; + } + localPrev = localCur; + + *cur = localCur; + *prev = localPrev; + return 0; +} + +static int NextArgument(const char *in, const uint32_t inLen, uint32_t *cur) +{ + uint32_t localCur = *cur; + + while (localCur < inLen && in[localCur] != ',' && in[localCur] != ')') { + localCur++; + } + + if (localCur >= inLen) { + return 1; + } + + *cur = localCur; + return 0; +} + +static int CheckType(const char *in, const uint32_t cur, const uint32_t prev, int *outType) +{ + int *type = outType; + if ((cur - prev == strlen("int")) && (strncmp(&in[prev], "int", strlen("int")) == 0)) { + *type = ARG_TYPE_INT; + } else if ((cur - prev == strlen("Hex")) && (strncmp(&in[prev], "Hex", strlen("Hex")) == 0)) { + *type = ARG_TYPE_HEX; + } else if ((cur - prev == strlen("char")) && (strncmp(&in[prev], "char", strlen("char")) == 0)) { + *type = ARG_TYPE_STR; + } else { + return 1; + } + + return 0; +} + +int ReadFunction(const char *in, const uint32_t inLen, char *outFuncName, uint32_t outLen, int argv[MAX_ARGUMENT_COUNT], + uint32_t *argCount) +{ + uint32_t cur = 0; + uint32_t prev = 0; + char *funcName = outFuncName; + + if (ClearVoid(in, inLen, &cur, &prev) != 0) { + return 1; + } + + // get function name + while (cur < inLen && in[cur] != '(') { + cur++; + } + if (cur >= inLen) { + return 1; + } + if (strncpy_s(funcName, outLen, &in[prev], cur - prev) != 0) { + return 1; + } + funcName[cur - prev] = '\0'; + cur++; + + // get argument types + uint32_t count = 0; + while (cur < inLen) { + while (cur < inLen && in[cur] == ' ') { + cur++; + } + prev = cur; + + while (cur < inLen && in[cur] != ' ' && in[cur] != ',' && in[cur] != '*' && in[cur] != ')') { + cur++; + } + + if (in[cur] == ')') { + break; + } + + if (cur == inLen || in[cur] == ',') { + return 1; + } + + int type = -1; + if (CheckType(in, cur, prev, &type) != 0) { + Print("******\nERROR: check type failed at: \n"); + return 1; + } + argv[count] = type; + + count++; + if (NextArgument(in, inLen, &cur) != 0) { + return 1; + } + if (in[cur] == ')') { + break; + } + cur++; + } + + *argCount = count; + + return 0; +} + +int AddFunction(const char *funcName, int argv[MAX_ARGUMENT_COUNT], const uint32_t argCount) +{ + if (g_testFuncCount >= MAX_TEST_FUCNTION_COUNT || argCount > MAX_ARGUMENT_COUNT) { + return 1; + } + + if (strcpy_s(g_testFunc[g_testFuncCount].name, MAX_TEST_FUNCTION_NAME, funcName) != 0) { + return 1; + } + g_testFunc[g_testFuncCount].argCount = argCount; + for (uint32_t i = 0; i < argCount; i++) { + g_testFunc[g_testFuncCount].argType[i] = argv[i]; + } + + g_testFunc[g_testFuncCount].id = g_testFuncCount; + g_testFuncCount++; + + return 0; +} + +int GenFunctionWrapper(FILE *file, FunctionTable *function) +{ + int ret; + ret = fprintf(file, "void %s_wrapper(void **param)\n", function->name); + if (ret < 0) { + return 1; + } + ret = fprintf(file, "{\n"); + if (ret < 0) { + return 1; + } + if (function->argCount == 0) { + ret = fprintf(file, " (void) param;\n"); + if (ret < 0) { + return 1; + } + } + ret = fprintf(file, " %s(", function->name); + if (ret < 0) { + return 1; + } + for (uint32_t i = 0; i < function->argCount; i++) { + if (function->argType[i] == ARG_TYPE_INT) { + ret = fprintf(file, "*((int*)param[%d])", (int)i); + if (ret < 0) { + return 1; + } + } else if (function->argType[i] == ARG_TYPE_STR) { + ret = fprintf(file, "(char*)param[%d]", (int)i); + if (ret < 0) { + return 1; + } + } else if (function->argType[i] == ARG_TYPE_HEX) { + ret = fprintf(file, "(Hex*)param[%d]", (int)i); + if (ret < 0) { + return 1; + } + } + if (i != function->argCount - 1) { + ret = fprintf(file, ", "); + if (ret < 0) { + return 1; + } + } + } + ret = fprintf(file, ");\n}\n\n"); + if (ret < 0) { + return 1; + } + return 0; +} + +int GenFunctionPointer(FILE *file) +{ + if (file == NULL) { + return 1; + } + int ret; + ret = fprintf(file, "%s\n\n", "typedef void (*TestWrapper)(void **param);"); + if (ret < 0) { + return 1; + } + ret = fprintf(file, "%s\n%s\n", "TestWrapper test_funcs[] = ", "{"); + if (ret < 0) { + return 1; + } + for (int i = 0; i < g_testFuncCount; i++) { + ret = fprintf(file, " %s_wrapper, \n", g_testFunc[i].name); + if (ret < 0) { + return 1; + } + } + ret = fprintf(file, "%s\n", "};"); + if (ret < 0) { + return 1; + } + return 0; +} + +static int ConnectFunction(char *lineBuf, uint32_t bufLen, FILE *fp) +{ + char buf[MAX_FUNCTION_LINE_LEN]; + bool reachEnd = false; + int ret = 0; + while (!reachEnd) { + for (int i = 0; lineBuf[i] != '\0'; i++) { + if (lineBuf[i] == ')') { + ret = 0; + reachEnd = true; + } + if (lineBuf[i] == '{') { + ret = 1; + reachEnd = true; + } + } + if (reachEnd) { + break; + } + if (ReadLine(fp, buf, MAX_FUNCTION_LINE_LEN, 0, 0) == 0) { + if (strcat_s(lineBuf, bufLen, buf) != 0) { + return 1; + } + } else { + return 1; + } + } + return ret; +} + +int ScanAllFunction(FILE *inFile, FILE *outFile) +{ + char buf[MAX_FUNCTION_LINE_LEN]; + int ret = 0; + uint32_t len = MAX_ARGUMENT_COUNT; + bool inFunction = false; + bool isDeclaration = true; + int arguments[MAX_ARGUMENT_COUNT]; + char funcName[MAX_TEST_FUNCTION_NAME]; + while (ReadLine(inFile, buf, MAX_FUNCTION_LINE_LEN, 0, 0) == 0) { + int curTag = CheckTag(buf, strlen(buf)); + if (curTag == TAG_NOT_TAG) { + if (!inFunction) { + fprintf(outFile, "%s\n", buf); + continue; + } + } else if (curTag == TAG_BEGIN_CASE) { + if (!inFunction) { + inFunction = true; + isDeclaration = true; + continue; + } + Print("ERROR: missing end case tag\n"); + return 1; + } else if (curTag == TAG_END_CASE) { + if (inFunction) { + inFunction = false; + fprintf(outFile, "\n"); + continue; + } + return 1; + } else { + return 1; + } + + if (isDeclaration) { + if (ConnectFunction(buf, sizeof(buf), inFile) != 0) { + Print("******\nERROR: connect function failed at: \n"); + Print("%s\n", buf); + return 1; + } + ret = ReadFunction(buf, strlen(buf), funcName, sizeof(funcName), arguments, &len); + if (ret != 0) { + Print("*******\nERROR: Read function failed at: \n"); + Print("%s\n", buf); + return ret; + } + ret = AddFunction(funcName, arguments, len); + if (ret != 0) { + return ret; + } + isDeclaration = false; + len = MAX_ARGUMENT_COUNT; + } + + (void)fprintf(outFile, "%s\n", buf); + } + + return 0; +} + +static int IncludeBase(char *line, uint32_t len, FILE *outFile, const char *dir) +{ + if (len < strlen(INCLUDE_BASE)) { + return 1; + } + + char *name = &line[strlen(INCLUDE_BASE)]; + while (*name == ' ') { + name++; + } + + if (*name == '\0') { + return 1; + } + + char *end = name; + + while (*end != ' ') { + end++; + } + *end = '\0'; + + char fileBuf[MAX_FILE_PATH_LEN]; + if (snprintf_s(fileBuf, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN, BASE_FILE_FORMAT, dir, name) == -1) { + return 1; + } + g_lineCount = 0; + FILE *fpBase = fopen(fileBuf, "r"); + if (fpBase == NULL) { + Print("ERROR:Open the base file. %s An error occurred when\n", fileBuf); + return 1; + } + + int ret; + char buf[MAX_FUNCTION_LINE_LEN]; + while (ReadLine(fpBase, buf, MAX_FUNCTION_LINE_LEN, 0, 0) == 0) { + ret = fprintf(outFile, "%s\n", buf); + if (ret < 0) { + goto include_end; + } + } + +include_end: + if (fclose(fpBase) != 0) { + Print("base file close failed\n"); + } + return 0; +} + +int WriteHeader(FILE *outFile) +{ + int ret; + ret = fprintf(outFile, "#include \"helper.h\"\n#include \"test.h\"\n#include \n"); + if (ret < 0) { + return 1; + } + return 0; +} + +int ScanHeader(FILE *inFile, FILE *outFile, const char *dir) +{ + char buf[MAX_FUNCTION_LINE_LEN]; + bool inHeader = false; + + while (ReadLine(inFile, buf, MAX_FUNCTION_LINE_LEN, 0, !inHeader) == 0) { + int curTag = CheckTag(buf, strlen(buf)); + if (curTag == TAG_BEGIN_HEADER) { + if (!inHeader) { + inHeader = true; + } else { + Print("******\nERROR: duplicate begin header tag\n"); + return 1; + } + } else if (curTag == TAG_END_HEADER) { + if (inHeader) { + (void)fprintf(outFile, "%s\n", buf); + return 0; + } else { + Print("******\nERROR: found end header without begin\n"); + return 1; + } + } else if (curTag == TAG_INCLUDE_BASE) { + int tmpLineCount = g_lineCount; + if (IncludeBase(buf, strlen(buf), outFile, dir) != 0) { + Print("******\nERROR: include base file failed\n"); + return 1; + } + g_lineCount = tmpLineCount; + continue; + } else if (curTag != TAG_NOT_TAG) { + Print("******\nERROR: missing end header tag\n"); + return 1; + } + (void)fprintf(outFile, "%s\n", buf); + } + return 0; +} + +static int AddExp(const char *exp) +{ + if (g_expCount >= MAX_EXPRESSION_COUNT) { + Print("Too much macros. Max macro count is %d\n", MAX_EXPRESSION_COUNT); + return -1; + } + for (int i = 0; i < g_expCount; i++) { + if (strcmp(exp, g_expTable[i]) == 0) { + return i; + } + } + if (strcpy_s(g_expTable[g_expCount], MAX_EXPRESSION_LEN, exp) != 0) { + Print("Macro too long, max length is %d\n", MAX_EXPRESSION_LEN); + return -1; + } + g_expCount++; + return g_expCount - 1; +} + +static int GetFuncIdByName(const char *name, uint32_t len) +{ + int funcId = -1; + for (int i = 0; i < g_testFuncCount; i++) { + if ((len < MAX_TEST_FUNCTION_NAME) && (strcmp(name, g_testFunc[i].name) == 0)) { + funcId = i; + break; + } + } + + return funcId; +} + +int GenDatax(FILE *inFile, FILE *outFile) +{ + char buf[MAX_DATA_LINE_LEN]; + char title[MAX_DATA_LINE_LEN]; + int ret; + int funcId = -1; + char *param[MAX_ARGUMENT_COUNT]; + uint32_t paramLen = MAX_ARGUMENT_COUNT; + while (ReadLine(inFile, title, MAX_DATA_LINE_LEN, 1, 1) == 0) { + ret = fprintf(outFile, "%s\n", title); + if (ret < 0) { + return 1; + } + + if ((ReadLine(inFile, buf, MAX_DATA_LINE_LEN, 1, 1) != 0)) { + return 1; + } + paramLen = MAX_ARGUMENT_COUNT; + ret = SplitArguments(buf, strlen(buf), param, ¶mLen); + if (ret != 0) { + Print("******\nERROR: Generate datax failed: split argument failed at testcase:\n"); + Print("%s\n", title); + return ret; + } + + funcId = GetFuncIdByName(param[0], strlen(param[0])); + if (funcId == -1) { + Print("******\nERROR: Generate datax failed: no function id for %s at testcase:\n", param[0]); + Print("%s\n", title); + return 1; + } + + if (paramLen != g_testFunc[funcId].argCount + 1) { + Print("******\nERROR: Generate datax failed: invalid argument count for function %s at testcase:\n", + param[0]); + Print("%s\n", title); + return 1; + } + + ret = fprintf(outFile, "%d:", funcId); + if (ret < 0) { + return 1; + } + int expId = 0; + for (uint32_t i = 0; i < g_testFunc[funcId].argCount; i++) { + if (g_testFunc[funcId].argType[i] == ARG_TYPE_INT && (IsInt(param[i + 1]) == 1)) { + ret = fprintf(outFile, "int:%s", param[i + 1]); + } else if (g_testFunc[funcId].argType[i] == ARG_TYPE_INT && (!IsInt(param[i + 1]))) { + expId = AddExp(param[i + 1]); + ret = fprintf(outFile, "exp:%d", expId); + } else if (g_testFunc[funcId].argType[i] == ARG_TYPE_STR) { + ret = fprintf(outFile, "char:%s", param[i + 1]); + } else if (g_testFunc[funcId].argType[i] == ARG_TYPE_HEX) { + ret = fprintf(outFile, "Hex:%s", param[i + 1]); + } else { + Print("invalid argument type\n"); + return 1; + } + if (ret < 0) { + return 1; + } + if (i != g_testFunc[funcId].argCount - 1) { + ret = fprintf(outFile, ":"); + } + if (expId == -1) { + return 1; + } + expId = 0; + } + ret = fprintf(outFile, "\n\n"); + if (ret < 0) { + return 1; + } + } + + return 0; +} + +int GenExpTable(FILE *outFile) +{ + int ret; + ret = fprintf(outFile, "int getExpression(int expId, int *out)\n{\n"); + if (ret < 0) { + return 1; + } + if (g_expCount == 0) { + ret = fprintf(outFile, " (void) out;\n (void) expId;\n"); + if (ret < 0) { + return 1; + } + } + ret = fprintf(outFile, " int ret = 0;\n"); + if (ret < 0) { + return 1; + } + ret = fprintf(outFile, " switch (expId)\n {\n"); + if (ret < 0) { + return 1; + } + + for (int i = 0; i < g_expCount; i++) { + ret = fprintf(outFile, " case %d:\n", i); + if (ret < 0) { + return 1; + } + ret = fprintf(outFile, " *out = %s;\n", g_expTable[i]); + if (ret < 0) { + return 1; + } + ret = fprintf(outFile, " break;\n"); + if (ret < 0) { + return 1; + } + } + + ret = fprintf(outFile, " default:\n"); + if (ret < 0) { + return 1; + } + ret = fprintf(outFile, " ret = 1;\n"); + if (ret < 0) { + return 1; + } + ret = fprintf(outFile, " break;\n"); + if (ret < 0) { + return 1; + } + ret = fprintf(outFile, " }\n return ret;\n}\n"); + if (ret < 0) { + return 1; + } + + return 0; +} + +int LoadFunctionName(FILE *outFile) +{ + int ret; + ret = fprintf(outFile, "const char * funcName[] = {\n"); + if (ret < 0) { + return 1; + } + for (int i = 0; i < g_testFuncCount; i++) { + ret = fprintf(outFile, " \"%s\",\n", g_testFunc[i].name); + if (ret < 0) { + return 1; + } + } + ret = fprintf(outFile, "};\n\n"); + if (ret < 0) { + return 1; + } + return 0; +} + +int LoadHelper(FILE *inFile, FILE *outFile) +{ + int ret; + char buf[MAX_FUNCTION_LINE_LEN]; + if (inFile == NULL || outFile == NULL) { + return 1; + } + while (fgets(buf, MAX_FUNCTION_LINE_LEN, inFile) != NULL) { + ret = fprintf(outFile, "%s", buf); + if (ret < 0) { + return 1; + } + } + (void)fprintf(outFile, "\n\n"); + return 0; +} + +int SplitHex(Hex *src, Hex *dest, int max) +{ + uint32_t blocks = src->len / SPILT_HEX_BLOCK_SIZE; + uint32_t remain = src->len % SPILT_HEX_BLOCK_SIZE; + uint32_t i; + if (blocks + 1 > (uint32_t)max) { + return 0; + } + for (i = 0; i < blocks; i++) { + dest[i].x = src->x + i * SPILT_HEX_BLOCK_SIZE; + dest[i].len = SPILT_HEX_BLOCK_SIZE; + } + + if (remain == 0) { + return blocks; + } else { + dest[i].x = src->x + i * SPILT_HEX_BLOCK_SIZE; + dest[i].len = remain; + return blocks + 1; + } +} + + +int SplitHexRand(Hex *src, Hex *dest, int max) +{ + uint32_t left = src->len; + int id = 0; + + if (left <= 3) { + dest[id].x = src->x; + dest[id].len = left; + id++; + return id; + } + + while (left > 3) { + dest[id].x = src->x + (src->len - left); + uint16_t clen = GET_UINT16_LE(dest[id].x, 0); + dest[id].len = clen > left ? left : clen; + left -= dest[id].len; + id++; + if (id > max - 1) { + break; + } + } + + if (left > 0) { + dest[id - 1].len += left; + } + + return id; +} + +FILE *OpenFile(const char *name, const char *option, const char *format) +{ + FILE *fp = NULL; + char fileBuf[MAX_FILE_PATH_LEN]; + if (snprintf_s(fileBuf, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN, format, name) == -1) { + Print("argument too long\n"); + return NULL; + } + fp = fopen(fileBuf, option); + return fp; +} + +int StripDir(const char *in, char *suiteName, const uint32_t suiteNameLen, char *dir, const uint32_t dirNameLen) +{ + int len = strlen(in); + int begin = len - 1; + + char *localDir = dir; + char *localSuiteName = suiteName; + while (begin >= 0 && in[begin] != '/') { + begin--; + } + + if (begin < 0) { + return 1; + } + + if (strncpy_s(localDir, dirNameLen, in, begin) != 0) { + return 1; + } + + if (strcpy_s(localSuiteName, suiteNameLen, &in[begin + 1]) != 0) { + return 1; + } + + if (strcpy_s(g_suiteFileName, MAX_FILE_PATH_LEN, &in[begin + 1]) != 0) { + return 1; + } + + return 0; +} + +int ScanFunctionFile(FILE *fpIn, FILE *fpOut, const char *dir) +{ + int ret; + ret = ScanHeader(fpIn, fpOut, dir); + if (ret != 0) { + Print("scan header failed\n"); + return 1; + } + + ret = ScanAllFunction(fpIn, fpOut); + if (ret != 0) { + Print("scan function failed\n"); + return 1; + } + + for (int i = 0; i < g_testFuncCount; i++) { + ret = GenFunctionWrapper(fpOut, &g_testFunc[i]); + if (ret < 0) { + Print("generate function wrapper failed\n"); + return 1; + } + } + if (g_fuzzEnd == 1) { + ret = fprintf(fpOut, "#define FREE_FUZZ_TC 1\n\n"); + } else { + ret = fprintf(fpOut, "#define FREE_FUZZ_TC 0\n\n"); + } + if (ret < 0) { + return 1; + } + return 0; +} + +static bool IsSuite(char *buf, uint32_t bufLen) +{ + uint32_t beginTagLen = strlen("Begin time:"); + uint32_t endTagLen = strlen("End time:"); + uint32_t resultTagLen = strlen("Result:"); + uint32_t atTagLen = strlen("at:"); + + if (bufLen >= beginTagLen && strncmp(buf, "Begin time:", beginTagLen) == 0) { + return false; + } else if (bufLen >= endTagLen && strncmp(buf, "End time:", endTagLen) == 0) { + return false; + } else if (bufLen >= resultTagLen && strncmp(buf, "Result:", resultTagLen) == 0) { + return false; + } else if (bufLen >= atTagLen && strncmp(buf, "at:", atTagLen) == 0) { + return false; + } + + return true; +} + +static void FileClose(FILE *file) +{ + if (file != NULL) { + (void)fclose(file); + } +} + +static int ReadAllLogFile(DIR *logDir, int *totalSuiteCount, FILE *outFile, TestSuiteResult *result, int resultLen) +{ + struct dirent *dir = NULL; + int suiteCount = 0; + int cur; + DIR *localLogDir = logDir; + int err = 1; + + // Stores the execution results of all test cases. + FILE *fpAllLog = OpenFile("result.log", "w+", "%s"); + if (fpAllLog == NULL) { + return 1; + } + FILE *fpLog = NULL; + + while ((dir = readdir(localLogDir)) != NULL) { + char buf[MAX_LOG_LEN]; + uint32_t bufLen = sizeof(buf); + if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) { + continue; + } + // len of ".log" is 4 + if (strlen(dir->d_name) <= 4 || strlen(dir->d_name) > MAX_FILE_PATH_LEN - 1) { + goto FINISH; + } + fpLog = OpenFile(dir->d_name, "r", LOG_FILE_FORMAT); + if (fpLog == NULL) { + goto FINISH; + } + if (suiteCount >= resultLen) { + Print("Reached maximum suite count\n"); + goto FINISH; + } + + if (strcpy_s(result[suiteCount].name, MAX_TEST_FUNCTION_NAME - 1, dir->d_name) != EOK) { + Print("Dir's Name is too long\n"); + goto FINISH; + } + // len of ".log" is 4 + result[suiteCount].name[strlen(dir->d_name) - 4] = '\0'; + result[suiteCount].total = 0; + result[suiteCount].pass = 0; + result[suiteCount].line = 0; + + while (ReadLine(fpLog, buf, bufLen, 0, 0) == 0) { + char testCaseName[MAX_TEST_FUNCTION_NAME]; + memset_s(testCaseName, MAX_TEST_FUNCTION_NAME, 0, MAX_TEST_FUNCTION_NAME); + if (!IsSuite(buf, strlen(buf))) { + continue; + } + result[suiteCount].total++; + cur = 0; + while (buf[cur] != '\0' && !(buf[cur] == '.' && buf[cur + 1] == '.')) { + cur++; + } + if (buf[cur] == '\0') { + Print("Read log file %s failed\n", dir->d_name); + goto FINISH; + } + if (strncpy_s(testCaseName, sizeof(testCaseName) - 1, buf, cur) != EOK) { + Print("TestCaseName is too long\n"); + goto FINISH; + } + testCaseName[cur] = '\0'; + while (buf[cur] == '.') { + cur++; + } + + if (strncmp(&buf[cur], "pass", strlen("pass")) == 0) { + result[suiteCount].pass++; + result[suiteCount].line++; + (void)fprintf(outFile, PRINT_TESTCASE_LIST_TAG, testCaseName, result[suiteCount].name); + (void)fprintf(fpAllLog, "%s %s\n", testCaseName, "PASS"); + } else if (strncmp(&buf[cur], "skip", strlen("skip")) == 0) { + result[suiteCount].skip++; + result[suiteCount].line++; + (void)fprintf(outFile, PRINT_TESTCASE_LIST_TAG, testCaseName, result[suiteCount].name); + (void)fprintf(fpAllLog, "%s %s\n", testCaseName, "SKIP"); + } else { + result[suiteCount].line += 3; // Incorrect test case requires 3 lines + (void)fprintf(outFile, PRINT_TESTCASE_LIST_TAG, testCaseName, result[suiteCount].name); + (void)fprintf(fpAllLog, "%s %s\n", testCaseName, "FAIL"); + (void)fprintf(outFile, PRINT_FAILURE_TAG); + (void)fprintf(outFile, PRINT_TESTCASE_TAG); + } + } + suiteCount++; + cur = 0; + FileClose(fpLog); + fpLog = NULL; + } + *totalSuiteCount = suiteCount; + err = 0; + +FINISH: + FileClose(fpLog); + FileClose(fpAllLog); + return err; +} + +static int GenResultFile(FILE *in, FILE *out, TestSuiteResult result[MAX_SUITE_COUNT], int testSuiteCount) +{ + int totalTests = 0; + int totalPass = 0; + + if (testSuiteCount >= MAX_SUITE_COUNT) { + Print("suites count too great\n"); + return 1; + } + + for (int i = 0; i < testSuiteCount; i++) { + totalTests += result[i].total; + totalPass += result[i].pass; + } + (void)fprintf(out, "\n"); + (void)fprintf(out, "\n"); + + for (int i = 0; i < testSuiteCount; i++) { + (void)fprintf(out, " \n"); + + for (int j = 0; j < result[i].line; j++) { + char buf[MAX_LOG_LEN]; + if (fgets(buf, sizeof(buf), in) != NULL) { + (void)fputs(buf, out); + } else { + return 1; + } + } + (void)fprintf(out, PRINT_TESTSUITE_TAG); + } + (void)fprintf(out, PRINT_TESTSUITES_TAG); + return 0; +} + +int GenResult(void) +{ + int ret; + TestSuiteResult result[MAX_SUITE_COUNT]; + int testSuiteCount = 0; + DIR *logDir = NULL; + logDir = opendir(LOG_FILE_DIR); + if (logDir == NULL) { + Print("fail to open log directory\n"); + return 1; + } + + FILE *fpTmp = NULL; + fpTmp = fopen("tmp.txt", "w+"); + if (fpTmp == NULL) { + Print("open tmp.txt failed\n"); + (void)closedir(logDir); + return 1; + } + + FILE *fpResult = NULL; + fpResult = fopen("result.xml", "w"); + if (fpResult == NULL) { + Print("open result.xml failed\n"); + (void)closedir(logDir); + (void)fclose(fpTmp); + (void)remove("tmp.txt"); + return 1; + } + + ret = ReadAllLogFile(logDir, &testSuiteCount, fpTmp, result, sizeof(result)); + if (ret != 0) { + Print("read log failed\n"); + goto END; + } + + rewind(fpTmp); + ret = GenResultFile(fpTmp, fpResult, result, testSuiteCount); + if (ret != 0) { + Print("gen result failed\n"); + goto END; + } + ret = 0; + +END: + (void)closedir(logDir); + (void)fclose(fpTmp); + (void)fclose(fpResult); + (void)remove("tmp.txt"); + return ret; +} diff --git a/testcode/framework/gen_test/main.c b/testcode/framework/gen_test/main.c new file mode 100644 index 00000000..025993da --- /dev/null +++ b/testcode/framework/gen_test/main.c @@ -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 "securec.h" +#include "helper.h" + +#define EXECUTE_BASE_FILE "../common/execute_base.c" +#define EXECUTE_TEST_FILE "../common/execute_test.c" + +typedef struct { + char suiteName[MAX_FILE_PATH_LEN]; + char dir[MAX_FILE_PATH_LEN]; + FILE *fpIn; + FILE *fpOut; + FILE *fpData; + FILE *fpBase; + FILE *fpDatax; + FILE *fpHelper; +} GenTestParams; + +int WriteToFile(GenTestParams *genParam) +{ + int ret = 0; + ret = WriteHeader(genParam->fpOut); + if (ret != 0) { + return ret; + } + + // Scanned test_suite_xxx.c, and write fpOut + ret = ScanFunctionFile(genParam->fpIn, genParam->fpOut, genParam->dir); + if (ret != 0) { + return ret; + } + + ret = GenFunctionPointer(genParam->fpOut); + if (ret != 0) { + return ret; + } + + ret = GenDatax(genParam->fpData, genParam->fpDatax); + if (ret != 0) { + Print("gen datax failed\n"); + return ret; + } + ret = GenExpTable(genParam->fpOut); + if (ret != 0) { + return ret; + } + ret = LoadFunctionName(genParam->fpOut); + if (ret != 0) { + return ret; + } + + (void)fprintf(genParam->fpOut, "char suiteName[200] = \"%s\";\n\n", genParam->suiteName); + // Write execute_base.c to fpOut + ret = LoadHelper(genParam->fpBase, genParam->fpOut); + if (ret != 0) { + return ret; + } + // Write execute_test.c to fpOut + ret = LoadHelper(genParam->fpHelper, genParam->fpOut); + if (ret != 0) { + return ret; + } + + return ret; +} + +int main(int argc, char **argv) +{ + (void)argc; +#ifndef PRINT_TO_TERMINAL + FILE *fp = fopen("GenTest.output", "a"); + if (fp == NULL) { + return 1; + } + SetOutputFile(fp); +#endif + + if (strcmp(argv[1], "GenReport") == 0) { + int resultRet = GenResult(); +#ifndef PRINT_TO_TERMINAL + (void)fclose(fp); +#endif + return resultRet; + } + + int ret = 0; + GenTestParams genParam = {0}; + StripDir(argv[1], genParam.suiteName, MAX_FILE_PATH_LEN, genParam.dir, MAX_FILE_PATH_LEN); + // Read test_suite_xxx.c + genParam.fpIn = OpenFile(argv[1], "r", "%s.c"); + if (genParam.fpIn == NULL) { + Print("Open %s.c error occurred while file\n", argv[1]); +#ifndef PRINT_TO_TERMINAL + (void)fclose(fp); +#endif + return -1; + } + // Output file testcode/output/test_suite_xxx.c + genParam.fpOut = OpenFile(genParam.suiteName, "w", "%s.c"); + if (genParam.fpOut == NULL) { + Print("Error generating c file\n"); + ret = 1; + goto end_fpIn; + } + + genParam.fpData = OpenFile(argv[1], "r", "%s.data"); + if (genParam.fpData == NULL) { + Print("An error occurred while opening the data file.\n"); + ret = 1; + goto end_fpOut; + } + + genParam.fpDatax = OpenFile(genParam.suiteName, "w", "%s.datax"); + if (genParam.fpDatax == NULL) { + Print("Error generating datax file\n"); + ret = 1; + goto end_fpData; + } + + genParam.fpBase = fopen(EXECUTE_BASE_FILE, "r"); + if (genParam.fpBase == NULL) { + Print("An error occurred when opening the base file.\n"); + ret = 1; + goto end_fpDatax; + } + + genParam.fpHelper = fopen(EXECUTE_TEST_FILE, "r"); + if (genParam.fpHelper == NULL) { + Print("Error opening secondary file\n"); + ret = 1; + goto end_fpBase; + } + + ret = WriteToFile(&genParam); + + (void)fclose(genParam.fpHelper); + +end_fpBase: + (void)fclose(genParam.fpBase); + +end_fpDatax: + (void)fclose(genParam.fpDatax); + +end_fpData: + (void)fclose(genParam.fpData); + +end_fpOut: + (void)fclose(genParam.fpOut); + +end_fpIn: + (void)fclose(genParam.fpIn); +#ifndef PRINT_TO_TERMINAL + (void)fclose(fp); +#endif + return ret; +} diff --git a/testcode/framework/gen_test/test.c b/testcode/framework/gen_test/test.c new file mode 100644 index 00000000..b524d20e --- /dev/null +++ b/testcode/framework/gen_test/test.c @@ -0,0 +1,176 @@ +/* + * 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 "securec.h" +#include "helper.h" +#include "test.h" + +TestInfo g_testResult; + +int ConvertInt(const char *intStr, int *outNum) +{ + int *num = outNum; + uint32_t i = 0; + if (intStr[0] == '-') { + i = 1; + } + + for (; i < strlen(intStr); i++) { + if (intStr[i] > '9' || intStr[i] < '0') { + return 1; + } + } + // Decimal + *num = strtol(intStr, NULL, 10); + + return 0; +} + +int ConvertString(char **str) +{ + if ((*str)[0] != '"') { + return 1; + } + uint32_t back = strlen(*str) - 1; + if ((*str)[back] != '"') { + back--; + if ((*str)[back] != '"') { + return 1; + } + } + (*str)[back] = '\0'; + (*str)++; + + return 0; +} + +int IsValidHexChar(char c) +{ + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + return 0; + } + return 1; +} + +int ConvertHex(const char *str, Hex *output) +{ + uint32_t len = strlen(str); + if (len == 0) { + output->x = NULL; + output->len = 0; + return 0; + } + // The length of a hex string must be a multiple of 2. + if (len % 2 != 0) { + return 1; + } + // Length of the hex string/2 = Length of the byte stream + len = len / 2; + output->x = (uint8_t *)malloc(len * sizeof(uint8_t)); + if (output->x == NULL) { + return 1; + } + output->len = len; + + // Every 2 bytes in a group + for (uint32_t i = 0; i < 2 * len; i += 2) { + if ((IsValidHexChar(str[i]) == 1) || (IsValidHexChar(str[i + 1]) == 1)) { + goto hex_error; + } + // hex to int formulas: (Hex % 32 + 9) % 25 = int, hex + output->x[i / 2] = (str[i] % 32 + 9) % 25 * 16 + (str[i + 1] % 32 + 9) % 25; + } + + return 0; + +hex_error: + free(output->x); + output->len = 0; + return 1; +} + +void RecordFailure(const char *test, const char *filename) +{ + g_testResult.result = TEST_RESULT_FAILED; + if (strcpy_s(g_testResult.test, sizeof(g_testResult.test), test) != 0) { + Print("failure log failed: message too long\n"); + } + if (strcpy_s(g_testResult.filename, sizeof(g_testResult.filename), filename) != 0) { + Print("failure log failed: filename too long\n"); + } +} + +void SkipTest(const char *filename) +{ + g_testResult.result = TEST_RESULT_SKIPPED; + if (strcpy_s(g_testResult.filename, sizeof(g_testResult.filename), filename) != 0) { + Print("failure log failed: filename too long\n"); + } +} +void PrintResult(bool showDetail, char *vectorName) +{ + if (showDetail) { + if (g_testResult.result == TEST_RESULT_SUCCEED) { + Print("pass\n"); + } else if (g_testResult.result == TEST_RESULT_SKIPPED) { + Print("skip\n"); + } else { + Print("failed\n"); + Print("at: (%s) in %s\n", g_testResult.test, g_testResult.filename); + } + } else if (g_testResult.result == TEST_RESULT_FAILED) { + Print("\nfailed at vector: %s\n", vectorName); + Print("at: (%s) in %s\n", g_testResult.test, g_testResult.filename); + } +} + +void PrintLog(FILE *logFile) +{ + int ret; + if (g_testResult.result == TEST_RESULT_SUCCEED) { + ret = fprintf(logFile, "pass\n"); + if (ret < 0) { + Print("write to log file failed\n"); + } + } else if (g_testResult.result == TEST_RESULT_SKIPPED) { + ret = fprintf(logFile, "skip\n"); + if (ret < 0) { + Print("write to log file failed\n"); + } + } else { + ret = fprintf(logFile, "failed\n"); + if (ret < 0) { + Print("write to log file failed\n"); + } + ret = fprintf(logFile, "at: (%s) in in %s\n", g_testResult.test, g_testResult.filename); + if (ret < 0) { + Print("write to log file failed\n"); + } + } +} + +void PrintDiff(const uint8_t *str1, uint32_t size1, const uint8_t *str2, uint32_t size2) +{ + Print("\nCompare different:\nstr1: "); + uint32_t i; + for (i = 0; i < size1; i++) { + Print("%X ", str1[i]); + } + Print("\nstr2: "); + for (i = 0; i < size2; i++) { + Print("%X ", str2[i]); + } + Print("\n"); +} \ No newline at end of file diff --git a/testcode/framework/include/helper.h b/testcode/framework/include/helper.h new file mode 100644 index 00000000..8b531347 --- /dev/null +++ b/testcode/framework/include/helper.h @@ -0,0 +1,140 @@ +/* + * 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 HELPER_H +#define HELPER_H + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_TEST_FUCNTION_COUNT 100 +#define MAX_TEST_FUNCTION_NAME 500 +#define MAX_ARGUMENT_COUNT 50 +#define MAX_EXPRESSION_COUNT 100 +#define MAX_EXPRESSION_LEN 100 +#define MAX_DATA_LINE_LEN 40000 +#define MAX_FUNCTION_LINE_LEN 300 +#define MAX_FILE_PATH_LEN 300 +#define MAX_SUITE_COUNT 600 +#define MAX_LOG_LEN 500 + +#define TAG_NOT_TAG 0 +#define TAG_BEGIN_HEADER 1 +#define TAG_END_HEADER 2 +#define TAG_BEGIN_CASE 3 +#define TAG_END_CASE 4 +#define TAG_INCLUDE_BASE 5 + +#define SPILT_HEX_BLOCK_SIZE 4 + +#define ARG_TYPE_INT 1 +#define ARG_TYPE_STR 2 +#define ARG_TYPE_HEX 3 + +#define BASE_FILE_FORMAT "%s/%s.base.c" +#define LOG_FILE_DIR "./log/" +#define LOG_FILE_FORMAT "./log/%s" +#define FUZZ_PRINT_EXECUTES "\r%d" + +typedef struct { + char name[MAX_FILE_PATH_LEN]; + int total; + int pass; + int skip; + int line; +} TestSuiteResult; + +typedef struct { + char name[MAX_TEST_FUNCTION_NAME]; + int id; + int argType[MAX_ARGUMENT_COUNT]; + uint32_t argCount; +} FunctionTable; + +typedef struct { + uint8_t *x; + uint32_t len; +} Hex; + +extern FunctionTable g_testFunc[MAX_TEST_FUCNTION_COUNT]; +extern int g_testFuncCount; +extern char g_expTable[MAX_EXPRESSION_COUNT][MAX_EXPRESSION_LEN]; +extern int g_expCount; + +void Print(const char *fmt, ...); + +void SetOutputFile(FILE *fp); + +FILE *GetOutputFile(void); + +void FreeHex(Hex *data); + +Hex *NewHex(void); + +int IsInt(const char *str); + +int ReadLine(FILE *file, char *buf, uint32_t bufLen, bool skipHash, bool skipEmptyLine); + +int SplitArguments(char *inStr, uint32_t inLen, char **outParam, uint32_t *paramLen); + +int ReadFunction(const char *in, const uint32_t inLen, char *outFuncName, uint32_t outLen, int argv[MAX_ARGUMENT_COUNT], + uint32_t *argCount); + +int AddFunction(const char *funcName, int argv[MAX_ARGUMENT_COUNT], const uint32_t argCount); + +int CheckTag(char *in, uint32_t len); + +int GenFunctionWrapper(FILE *file, FunctionTable *function); + +int ScanAllFunction(FILE *inFile, FILE *outFile); + +int ScanHeader(FILE *inFile, FILE *outFile, const char *dir); + +int GenFunctionPointer(FILE *file); + +int GenDatax(FILE *inFile, FILE *outFile); + +int GenExpTable(FILE *outFile); + +int LoadFunctionName(FILE *outFile); + +int LoadHelper(FILE *inFile, FILE *outFile); + +int ScanFunctionFile(FILE *fpIn, FILE *fpOut, const char *dir); + +int StripDir(const char *in, char *suiteName, const uint32_t suiteNameLen, char *dir, const uint32_t dirNameLen); + +FILE *OpenFile(const char *name, const char *option, const char *format); + +int GenResult(void); + +int SplitHex(Hex *src, Hex *dest, int max); + +int SplitHexRand(Hex *src, Hex *dest, int max); + +int WriteHeader(FILE *outFile); +#ifdef __cplusplus +} +#endif + +#endif // HELPER_H diff --git a/testcode/framework/include/test.h b/testcode/framework/include/test.h new file mode 100644 index 00000000..61d2ece1 --- /dev/null +++ b/testcode/framework/include/test.h @@ -0,0 +1,160 @@ +/* + * 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 TEST_H +#define TEST_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "helper.h" +#include "crypto_test_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_RESULT_SUCCEED 0 +#define TEST_RESULT_FAILED 1 +#define TEST_RESULT_SKIPPED 2 + +typedef struct { + int result; + char test[512]; + char filename[256]; +} TestInfo; + +#define TRUE_OR_EXIT(TEST) \ + do { \ + if (!(TEST)) { \ + goto exit; \ + } \ + } while (0) + +#define TRUE_OR_ABRT(TEST) \ + do { \ + if (!(TEST)) { \ + raise(SIGABRT); \ + } \ + } while (0) + +#define PRINT_ABRT(TEST) \ + do { \ + if (!(TEST)) { \ + goto abrt; \ + } \ + } while (0) + +#define ASSERT_TRUE(TEST) \ + do { \ + if (!(TEST)) { \ + RecordFailure(#TEST, __FILE__); \ + goto exit; \ + } \ + } while (0) + +#define ASSERT_EQ(VALUE1, VALUE2) \ + do { \ + int64_t value1__ = (int64_t)(VALUE1); \ + int64_t value2__ = (int64_t)(VALUE2); \ + if (value1__ != value2__) { \ + RecordFailure(#VALUE1 #VALUE2, __FILE__); \ + Print("\nvalue is %d (0x%x).\nexpect %d (0x%x).\n", value1__, value1__, value2__, value2__); \ + goto exit; \ + } \ + } while (0) + + +#define ASSERT_EQ_LOG(LOG, VALUE1, VALUE2) \ + do { \ + int64_t value1__ = (int64_t)(VALUE1); \ + int64_t value2__ = (int64_t)(VALUE2); \ + if (value1__ != value2__) { \ + RecordFailure(LOG, __FILE__); \ + Print("\nvalue is %d (0x%x).\nexpect %d (0x%x).\n", value1__, value1__, value2__, value2__); \ + goto exit; \ + } \ + } while (0) + +#define ASSERT_NE(VALUE1, VALUE2) \ + do { \ + int64_t value1__ = (int64_t)(VALUE1); \ + int64_t value2__ = (int64_t)(VALUE2); \ + if (value1__ == value2__) { \ + RecordFailure(#VALUE1#VALUE2, __FILE__); \ + Print("\nvalue is the same: %d (0x%x).\n", value1__, value2__); \ + goto exit; \ + } \ + } while (0) + +#define ASSERT_TRUE_AND_LOG(LOG, TEST) \ + do { \ + if (!(TEST)) { \ + RecordFailure(LOG, __FILE__); \ + goto exit; \ + } \ + } while (0) + +#define ASSERT_COMPARE(LOG, STR1, SIZE1, STR2, SIZE2) \ + do { \ + ASSERT_TRUE_AND_LOG(LOG, (SIZE1) == (SIZE2)); \ + if (memcmp((STR1), (STR2), (SIZE1)) != 0) { \ + RecordFailure((LOG), __FILE__); \ + PrintDiff((uint8_t *)(STR1), (uint32_t)(SIZE1), (uint8_t *)(STR2), (uint32_t)(SIZE2)); \ + goto exit; \ + } \ + } while (0) + +#define SKIP_TEST() \ + do {\ + SkipTest(__FILE__); \ + return; \ + } while (0) + +extern int *GetJmpAddress(); +#define SUB_PROC 1 +#define SUB_PROC_BEGIN(parentAction) if (fork() > 0) parentAction +#define SUB_PROC_END() *GetJmpAddress() = SUB_PROC; return +#define SUB_PROC_WAIT(times) for (uint16_t i = 0; i < times; i++) wait(NULL) + +extern TestInfo g_testResult; + +int ConvertInt(const char *intStr, int *outNum); + +int ConvertString(char **str); + +int ConvertHex(const char *str, Hex *output); + +void RecordFailure(const char *test, const char *filename); + +void SkipTest(const char *filename); + +void PrintResult(bool showDetail, char *vectorName); + +void PrintLog(FILE *logFile); + +void PrintDiff(const uint8_t *str1, uint32_t size1, const uint8_t *str2, uint32_t size2); + +#ifdef __cplusplus +} +#endif + +#endif // TEST_H \ No newline at end of file diff --git a/testcode/framework/process/CMakeLists.txt b/testcode/framework/process/CMakeLists.txt new file mode 100644 index 00000000..03bdf9d3 --- /dev/null +++ b/testcode/framework/process/CMakeLists.txt @@ -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. +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + +project(TLS_PROCESS) + +set(PROCESS "process") +set(HITLS_SRC ${PROJECT_SOURCE_DIR}/../../..) +set(EXECUTABLE_OUTPUT_PATH ${HITLS_SRC}/testcode/output) +set(SECUREC_INCLUDE ${HITLS_SRC}/platform/Secure_C/include) + +include_directories( + ${SECUREC_INCLUDE} + ${HITLS_SRC}/testcode/framework/tls/resource/include + ${HITLS_SRC}/testcode/framework/tls/base/include + ${HITLS_SRC}/testcode/framework/tls/process/include + ${HITLS_SRC}/testcode/framework/tls/include + ${HITLS_SRC}/testcode/framework/tls/transfer/include + ${HITLS_SRC}/testcode/framework/tls/rpc/include + ${HITLS_SRC}/include/bsl + ${HITLS_SRC}/bsl/sal/include + ${HITLS_SRC}/bsl/uio/src + ${HITLS_SRC}/bsl/uio/include + ${HITLS_SRC}/include/tls + ${HITLS_SRC}/tls/include + ${HITLS_SRC}/config/macro_config +) + +add_executable(${PROCESS} ${PROJECT_SOURCE_DIR}/process.c) + +if(PRINT_TO_TERMINAL) + target_compile_options(${PROCESS} PUBLIC -DPRINT_TO_TERMINAL) +endif() + +if(ENABLE_FAIL_REPEAT) + target_compile_options(${PROCESS} PUBLIC -DFAIL_REPEAT_RUN) +endif() + +target_link_directories(${PROCESS} + PUBLIC + ${HITLS_SRC}/build + ${HITLS_SRC}/testcode/framework/tls/lib + ${HITLS_SRC}/platform/Secure_C/lib +) +target_link_libraries(${PROCESS} + tls_hlt + tls_frame + hitls_tls + hitls_crypto + hitls_x509 + hitls_bsl + boundscheck + pthread + sctp + rec_wrapper +) diff --git a/testcode/framework/process/process.c b/testcode/framework/process/process.c new file mode 100644 index 00000000..9b1a5455 --- /dev/null +++ b/testcode/framework/process/process.c @@ -0,0 +1,201 @@ +/* + * 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 +#include +#include +#include +#include + +#include "securec.h" +#include "channel_res.h" +#include "handle_cmd.h" +#include "tls_res.h" +#include "control_channel.h" +#include "logger.h" +#include "lock.h" +#include "rpc_func.h" +#include "hlt_type.h" +#include "hlt.h" +#include "process.h" + +#define DOMAIN_PATH_LEN (128) +#define SUCCESS 0 +#define ERROR (-1) + +#define ASSERT_RETURN(condition, log) \ + do { \ + if (!(condition)) { \ + LOG_ERROR(log); \ + return ERROR; \ + } \ + } while (0) + +int IsFeedbackResult(ControlChannelRes *channelInfo) +{ + int i, ret; + ControlChannelBuf dataBuf = {0}; + + OsLock(channelInfo->sendBufferLock); + if (channelInfo->sendBufferNum == 0) { + OsUnLock(channelInfo->sendBufferLock); + return SUCCESS; + } + i = 0; + while (channelInfo->sendBufferNum > 0) { + ret = memcpy_s(dataBuf.data, CONTROL_CHANNEL_MAX_MSG_LEN, + channelInfo->sendBuffer[i], strlen((char*)(channelInfo->sendBuffer[i]))); + if (ret != EOK) { + LOG_ERROR("MemCpy Error"); + OsUnLock(channelInfo->sendBufferLock); + return ERROR; + } + dataBuf.dataLen = strlen((char*)channelInfo->sendBuffer[i]); + LOG_DEBUG("Remote Process Send Result %s", dataBuf.data); + ret = ControlChannelWrite(channelInfo->sockFd, channelInfo->peerDomainPath, &dataBuf); + if (ret != EOK) { + LOG_ERROR("ControlChannelWrite Error, Msg is %s, ret is %d\n", dataBuf.data, ret); + OsUnLock(channelInfo->sendBufferLock); + return ERROR; + } + LOG_DEBUG("Remote Process Send Result %s Success", dataBuf.data); + channelInfo->sendBufferNum--; + i++; + } + OsUnLock(channelInfo->sendBufferLock); + return SUCCESS; +} + +void FreeThreadRes(pthread_t *threadList, int threadNum) +{ + for (int i = 0; i < threadNum; i++) { + pthread_cancel(threadList[i]); + pthread_join(threadList[i], NULL); + } + return; +} + +void ThreadExcuteCmd(void *param) +{ + CmdData cmdData = {0}; + if (memcpy_s(&cmdData, sizeof(cmdData), (CmdData *)param, sizeof(CmdData)) != EOK) { + free(param); + return; + } + free(param); + ControlChannelRes *channelInfo = GetControlChannelRes(); + (int)ExecuteCmd(&cmdData); + PushResultToChannelSendBuffer(channelInfo, cmdData.result); + return; +} + +int main(int argc, char **argv) +{ + int ret, sctpFd; + ControlChannelRes* channelInfo = NULL; + ControlChannelBuf dataBuf; + CmdData exitCmdData = {0}; + CmdData* cmdData = NULL; + Process* process = NULL; + pid_t ppid = atoi(argv[4]); + (void)ppid; + // Do not set the output buffer + setbuf(stdout, NULL); + + LOG_DEBUG("argv value is %d", argc); + ret = InitProcess(); + ASSERT_RETURN(ret == SUCCESS, "InitProcess Error"); + + process = GetProcess(); + process->remoteFlag = 1; // Must be marked as a remote process + process->tlsType = atoi(argv[1]); // The first parameter indicates the Hitls function + ret = memcpy_s(process->srcDomainPath, DOMAIN_PATH_LEN, argv[2], + strlen(argv[2])); // The second parameter indicates the local IP address + ASSERT_RETURN(ret == SUCCESS, "memcpy process->srcDomainPath Error"); + ret = memcpy_s(process->peerDomainPath, DOMAIN_PATH_LEN, argv[3], + strlen(argv[3])); // The third parameter indicates the address of the control process + ASSERT_RETURN(ret == SUCCESS, "memcpy process->srcDomainPath Error"); + + // Dependent library initialization + ret = HLT_LibraryInit(process->tlsType); + ASSERT_RETURN(ret == SUCCESS, "HLT_TlsRegCallback Error"); + + // Initialize the linked list for storing CTX and SSL + ret = InitTlsResList(); + ASSERT_RETURN(ret == SUCCESS, "InitTlsResList Error"); + + // Initializes the global variable that stores the control channel information. + ret = InitControlChannelRes(process->srcDomainPath, strlen(process->srcDomainPath), + process->peerDomainPath, strlen(process->peerDomainPath)); + ASSERT_RETURN(ret == SUCCESS, "ChannelInfoInit Error"); + + // Creating a Control Link UDP DOMAIN SOCKET + channelInfo = GetControlChannelRes(); + ret = ControlChannelInit(channelInfo); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelInit Error"); + + // Print information + LOG_DEBUG("Create Remote Process Successful"); + // The message is sent to the peer end, indicating that the process is started successfully + PushResultToChannelSendBuffer(channelInfo, "0|HEART"); + while (1) { + if (kill(ppid, 0) != 0) { + LOG_DEBUG("\nthe parent process [%u] does not exist, I want to exist\n", ppid); + break; + } + // Waiting for the command from the peer end + ret = ControlChannelRead(channelInfo->sockFd, &dataBuf); + if (ret == 0) { + // Receives a message, parses the message, and performs related operations + LOG_DEBUG("Remote Process Rcv Cmd Is: %s", dataBuf.data); + cmdData = (CmdData*)malloc(sizeof(CmdData)); + if (cmdData == NULL) { + LOG_ERROR("Malloc cmdData Error"); + break; + } + ret = ParseCmdFromBuf(&dataBuf, cmdData); + if (ret != SUCCESS) { + LOG_ERROR("ParseCmdFromBuf Error ..."); + free(cmdData); + break; + } + if (strncmp((char *)cmdData->funcId, "HLT_RpcProcessExit", strlen("HLT_RpcProcessExit")) == 0) { + // Indicates that the process needs to exit + sctpFd = atoi((char *)cmdData->paras[0]); + (void)sprintf_s((char *)exitCmdData.result, sizeof(exitCmdData.result), "%s|%s|%d", + cmdData->id, cmdData->funcId, sctpFd); + PushResultToChannelSendBuffer(channelInfo, exitCmdData.result); + free(cmdData); + break; + } + ThreadExcuteCmd(cmdData); + } + // Check whether feedback is required + ret = IsFeedbackResult(channelInfo); + if (ret != 0) { + break; + } + } + LOG_DEBUG("Process Return"); + (void)IsFeedbackResult(channelInfo); + // Clearing Resources + FreeControlChannelRes(); + FreeTlsResList(); + FreeProcess(); + if (sctpFd > 0) { + close(sctpFd); + } + return SUCCESS; +} diff --git a/testcode/framework/stub/stub_replace.c b/testcode/framework/stub/stub_replace.c new file mode 100644 index 00000000..dd5bc9de --- /dev/null +++ b/testcode/framework/stub/stub_replace.c @@ -0,0 +1,325 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "stub_replace.h" + +/* The LSB of the function pointer indicates the thumb function. The LSB of the actual address needs to be cleared. */ +#define REAL_ADDR(ptr) (void *)(((uintptr_t)(ptr)) & (~(uintptr_t)1)) +/* + * Used to record the size of the system memory page. + */ +static long g_pageSize = -1; + +/* + * Obtains the start address of the memory page where the specified function code is located. + * fn - Function Address (Function Pointer) + */ +static inline void *FuncPageGet(uintptr_t fn) +{ + return (void *)(fn & (~(g_pageSize - 1))); +} + +/* + * This file does not use the memcpy function of the system. In this way, the mempcy function of + * the system can be dynamically replaced by STUB_Replace. + */ +static int32_t StubCopy(void *dest, void *src, uint32_t size) +{ + if ((src == NULL) || (dest == NULL)) { + return ERANGE; + } + + uint8_t *localDst = (uint8_t *)(dest); + uint8_t *localSrc = (uint8_t *)(src); + for (uint32_t i = 0; i < size; i++) { + localDst[i] = localSrc[i]; + } + return 0; +} + +/* + * This file does not use the memset function of the system. In this way, the memset function of + * the system can be dynamically replaced by STUB_Replace. + */ +static void StubSet(void *dest, int val, uint32_t size) +{ + if (dest == NULL) { + return; + } + + uint8_t *localDst = (uint8_t *)(dest); + for (uint32_t i = 0; i < size; i++) { + localDst[i] = val; + } +} + +#if defined(__arm__) || defined(__thumb__) + +static int ReplaceT32(void *srcFn, const void *stubFn) +{ + uint16_t instr1 = 0xF000; + uint16_t instr2; + uint32_t imm; + /* + * The difference between the jump instruction and srcFn is 4 bytes. The current address is obtained by + * subtracting 4 bytes from the PC. + */ + uint32_t addrDiff = REAL_ADDR(stubFn) - (REAL_ADDR(srcFn) + 4) - 4; + + /* + * 32-bit test occurrence address: srcFn - stubFn, the scope is out of range, + * temporarily comment on the following scope judgment. + * if (abs((int32_t)addrDiff) >= 0x100000) { // Max jump range + * return -1; + * } + */ + if (((uintptr_t)stubFn) & 0x01) { + // Thumb instruction set BL corresponding machine code is [1 1 1 1 0 S imm10][1 1 J1 1 J2 imm11] + // Address offset calculation: I1: NOT(J1 EOR S); I2: NOT(J2 EOR S); + // imm32: SignExtend(S:I1:I2:imm10:imm11:'0', 32) + instr2 = 0xF800; // Corresponding bit of machine code J1 J2 take 1 + if (stubFn < srcFn) { + instr1 = 0xF400; // The corresponding bit S of the machine code is 1. + } + imm = addrDiff >> 1; // The address is shifted right by one bit. + imm &= (1 << 21) - 1; // Lower 21 bits + instr1 |= (imm >> 11) & 0x3FF; // Move rightwards by 11 digits and take imm10. + instr2 |= (imm & 0x7FF); + } else { + // Thumb instruction set BLX corresponding machine code is [1 1 1 1 0 S imm10H][1 1 J1 0 J2 imm10L H] + // Address offset calculation: I1 = NOT(J1 EOR S); I2 = NOT(J2 EOR S) + // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32) + instr2 = 0xE800; // J1 and J2 corresponding to the machine code are set to 1. + if (stubFn < srcFn) { + instr1 = 0xF400; // The corresponding bit S of the machine code is 1. + } + imm = addrDiff >> 2; // Shift right by 2 bits + imm &= (1 << 20) - 1; // Take lower 20 bits + instr1 |= (imm >> 10) & 0x3FF; // Take 10 bits + instr2 |= (imm & 0x3FF) << 1; // Take lower 10 bits + } + uint8_t *text = (uint8_t*)REAL_ADDR(srcFn); + ((uint16_t *)text)[0] = 0xb580; + ((uint16_t *)text)[1] = 0xaf00; + ((uint16_t *)text)[2] = instr1; // BL/BLX offset 2 + ((uint16_t *)text)[3] = instr2; // Offset 3 + ((uint16_t *)text)[4] = 0xaf00; // Offset 4 + ((uint16_t *)text)[5] = 0xbd80; // Offset 5 + return 0; +} + +static int ReplaceA32(void *srcFn, const void *stubFn) +{ + uint32_t inst; + uint32_t addrDiff = REAL_ADDR(stubFn) - (srcFn + 4) - 8; + uint32_t imm24; + if (abs((int32_t)addrDiff) >= 0x1000000) { // Max jump range + return -1; + } + if (((uintptr_t)stubFn) & 0x01) { + // a32 instruction set BLX corresponding machine code is [1 1 1 1 1 0 1 H imm24] + // imm32 = SignExtend(imm24:H:'0', 32) + uint32_t h = (addrDiff & 0b10) >> 1; // bit[1] of the address difference + imm24 = (addrDiff >> 2); // Shift right by 2 bits + imm24 &= (1 << 24) - 1; // Take lower 24 bits + inst = 0xfa000000 | imm24 | (h << 24); // h is located in bit[24]. + } else { + // a32 instruction set BL corresponding machine code is [(!= 1111) 1 0 1 1 imm24] + // imm32 = SignExtend(imm24:'00', 32) + imm24 = (addrDiff >> 2); // Shift right by 2 bits + imm24 &= (1 << 24) - 1; // Take lower 24 bits + inst = 0xeb000000 | imm24; + } + ((uint32_t *)srcFn)[0] = 0xe92d4000; + ((uint32_t *)srcFn)[1] = inst; // BL/BLX + ((uint32_t *)srcFn)[2] = 0xe8bd8000; // Offset 2 + return 0; +} +#endif +/* + * Replaces the specified function with the specified stub function. + * stubInfo - Record information about stub replacement, which is used for STUB_Reset restoration. + * srcFn - Functions in the source code + * stubFn - You need to replace the stub function that is inserted into the run. + * return - 0:Success, non-zero:Error code + */ +int STUB_Replace(FuncStubInfo *stubInfo, void *srcFn, const void *stubFn) +{ + (void)stubFn; +#if defined(__arm__) || defined(__thumb__) + stubInfo->fn = REAL_ADDR(srcFn); +#else + stubInfo->fn = srcFn; +#endif + StubCopy(stubInfo->codeBuf, (char *)(stubInfo->fn), CODESIZE); + bool nextPage = false; + uintptr_t srcPoint = (uintptr_t)srcFn; + if ((g_pageSize - (srcPoint % g_pageSize)) < CODESIZE) { + nextPage = true; + } + + /* To modify instruction content corresponding to the source function, add memory write permission first */ + if (mprotect(FuncPageGet(srcPoint), g_pageSize, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { + perror("STUB_Replace: set error mprotect to w+r+x faild"); + return -1; + } + if (nextPage) { + if (mprotect(FuncPageGet(srcPoint + CODESIZE), g_pageSize, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { + perror("STUB_Replace: set error mprotect to w+r+x faild"); + return -1; + } + } +#if defined(__x86_64__) + /* + * Short jump mode: Change to jmp jump instruction, and set jump position (the offset of the current position). + * However, the offset cannot exceed 32 bits. There is a restriction on 64-bit systems. + * [*(unsigned char *)srcFn = (unsigned char)0xE9;] [*(unsigned int *)((unsigned char *)srcFn + 1) = + * (unsigned char *)stubFn - (unsigned char *)srcFn - CODESIZE;] Long jump mode: + * Directly use a 64-bit address to jump, the following method is used. + */ + unsigned char *tmpBuf = (unsigned char *)srcFn; + int idx = 0; + tmpBuf[idx++] = 0xFF; // 0xFF 0x25 Constructing a long jump instruction + tmpBuf[idx++] = 0x25; // 0xFF 0x25 Constructing a long jump instruction + tmpBuf[idx++] = 0x0; + tmpBuf[idx++] = 0x0; + tmpBuf[idx++] = 0x0; + tmpBuf[idx++] = 0x0; + + tmpBuf[idx++] = (((uintptr_t)stubFn) & 0xff); + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 8) & 0xff); // Obtain the address by little-endian shift by 8 bits + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 16) & 0xff); // Obtain the address by little-endian shift by 16 bits + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 24) & 0xff); // Obtain the address by little-endian shift by 24 bits + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 32) & 0xff); // Obtain the address by little-endian shift by 32 bits + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 40) & 0xff); // Obtain the address by little-endian shift by 40 bits + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 48) & 0xff); // Obtain the address by little-endian shift by 48 bits + tmpBuf[idx++] = ((((uintptr_t)stubFn) >> 56) & 0xff); // Obtain the address by little-endian shift by 56 bits +#elif defined(__aarch64__) || defined(_M_ARM64) + /* ldr x9, +8 + br x9 + addr */ + ((uint32_t *)srcFn)[0] = 0x58000040 | 9; // 9 = 1001 + ((uint32_t *)srcFn)[1] = 0xd61f0120 | (9 << 5); // 9 << 5 + /* ldr x9, + 8 */ + *(long long *)((char *)srcFn + 8) = (long long)stubFn; +#elif defined(__arm__) || defined(__thumb__) + if (((uintptr_t)srcFn) & 0x01) { + if (ReplaceT32(srcFn, stubFn) != 0) { + return -1; + } + } else { + if (ReplaceA32(srcFn, stubFn) != 0) { + return -1; + } + } +#elif defined(__i386__) + unsigned long tmpAdd = (unsigned long)stubFn - (unsigned long)(srcFn + 5); + unsigned char *tmpBuf = (unsigned char *)srcFn; + *(tmpBuf + 0) = 0xe9; + *(unsigned long *)(tmpBuf + 1) = tmpAdd; +#endif + /* Flush cached instructions into */ + __builtin___clear_cache((char *)(stubInfo->fn), (char *)(stubInfo->fn) + CODESIZE); + /* The modification is complete. Remove the memory write permission. */ + if (mprotect(FuncPageGet(srcPoint), g_pageSize, PROT_READ | PROT_EXEC) < 0) { + perror("STUB_Replace: set error mprotect to r+x failed"); + return -1; + } + if (nextPage) { + if (mprotect(FuncPageGet(srcPoint + CODESIZE), g_pageSize, PROT_READ | PROT_EXEC) < 0) { + perror("STUB_Replace: set error mprotect to r+x failed"); + return -1; + } + } + return 0; +} + +/* + * Restore the source function and remove the instrumentation. + * stubInfo - Information logged when instrumentation + * return - 0:Success, non-zero:Error code + */ +int STUB_Reset(FuncStubInfo *stubInfo) +{ + bool nextPage = false; + + if (stubInfo->fn == NULL) { + return -1; + } + + uintptr_t srcPoint = (uintptr_t)stubInfo->fn; + if ((g_pageSize - (srcPoint % g_pageSize)) < CODESIZE) { + nextPage = true; + } + + /* To modify instruction content corresponding to the source function, add memory write permission first */ + if (mprotect(FuncPageGet((uintptr_t)stubInfo->fn), g_pageSize, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { + perror("STUB_Reset: error mprotect to w+r+x faild"); + return -1; + } + if (nextPage) { + if (mprotect(FuncPageGet(srcPoint + CODESIZE), g_pageSize, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { + perror("STUB_Replace: set error mprotect to w+r+x faild"); + return -1; + } + } + + /* Restore the recorded rewritten original function mov/push/mov a few instructions */ + if (StubCopy(stubInfo->fn, stubInfo->codeBuf, CODESIZE) < 0) { + return -1; + } + /* Flush cached instructions into */ + __builtin___clear_cache((char *)stubInfo->fn, (char *)stubInfo->fn + CODESIZE); + /* If recovered, disable the memory modification permission. */ + if (mprotect(FuncPageGet((uintptr_t)stubInfo->fn), g_pageSize, PROT_READ | PROT_EXEC) < 0) { + perror("STUB_Reset: error mprotect to r+x failed"); + return -1; + } + if (nextPage) { + if (mprotect(FuncPageGet(srcPoint + CODESIZE), g_pageSize, PROT_READ | PROT_EXEC) < 0) { + perror("STUB_Replace: set error mprotect to r+x failed"); + return -1; + } + } + + StubSet(stubInfo, 0, sizeof(FuncStubInfo)); + return 0; +} + +/* + * Initialize the dynamic stub change function and obtain the memory page size. Invoke the function once. + * return - 0:Success, non-zero:Error code + */ +int STUB_Init(void) +{ + if (g_pageSize != -1) { + return 0; + } + g_pageSize = sysconf(_SC_PAGE_SIZE); + if (g_pageSize < 0) { + perror("STUB_Init: get system _SC_PAGE_SIZE configure failed"); + return -1; + } + return 0; +} diff --git a/testcode/framework/stub/stub_replace.h b/testcode/framework/stub/stub_replace.h new file mode 100644 index 00000000..29471275 --- /dev/null +++ b/testcode/framework/stub/stub_replace.h @@ -0,0 +1,71 @@ +/* + * 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 STUB_REPALCE_H +#define STUB_REPALCE_H + +#include + + +#if defined(__x86_64__) +/* + * The first 14 bytes of the function entry are used to construct the jump instruction. + * Short jump instruction is 5 bytes, and Long jump instruction is 14 bytes. + */ +#define CODESIZE 14U +#elif defined(__aarch64__) || defined(_M_ARM64) +/* ARM64 needs 16 bytes to construct the jump instruction. */ +#define CODESIZE 16U +#elif defined(__arm__) +/* ARM32 needs 12 bytes to construct the jump instruction. */ +#define CODESIZE 12U +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + void *fn; + unsigned char codeBuf[CODESIZE]; +} FuncStubInfo; + +/* + * Initialize the dynamic stub change function. Invoke the function once. + * return - 0:Success, non-zero:Error code + */ +int STUB_Init(); + +/* + * Replaces the specified function with the specified stub function. + * stubInfo - Record information about stub replacement, which is used for STUB_Reset restoration. + * srcFn - Functions in the source code + * stubFn - Need to replace the stub function that is inserted into the run. + * return - 0:Success, non-zero:Error code + */ +int STUB_Replace(FuncStubInfo *stubInfo, void *srcFn, const void *stubFn); + +/* + * Restore the source function and remove the instrumentation. + * stubInfo - Information logged when instrumentation + * return - 0:Success, non-zero:Error code + */ +int STUB_Reset(FuncStubInfo *stubInfo); + +#ifdef __cplusplus +} +#endif + +#endif // STUB_REPALCE_H \ No newline at end of file diff --git a/testcode/framework/tls/CMakeLists.txt b/testcode/framework/tls/CMakeLists.txt new file mode 100644 index 00000000..0c37cbd9 --- /dev/null +++ b/testcode/framework/tls/CMakeLists.txt @@ -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. +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + +PROJECT(TLS_FRAME) +set(CMAKE_VERBOSE_MAKEFILEON ON) +SET(DT_LIBNAME "tls_frame") +SET(HLT_LIBNAME "tls_hlt") +SET(WRAPPER_LIBNAME "rec_wrapper") + +if(ENABLE_TLS_DEBUG) + add_compile_definitions(TLS_DEBUG) +endif() +SET(HITLS_SRC ${PROJECT_SOURCE_DIR}/../../../) +set(SECUREC_INCLUDE ${HITLS_SRC}/platform/Secure_C/include) + +include_directories(${SECUREC_INCLUDE} + ${HITLS_SRC}/include + ${HITLS_SRC}/include/tls + ${HITLS_SRC}/include/bsl + ${HITLS_SRC}/include/crypto + ${HITLS_SRC}/config/macro_config + ${HITLS_SRC}/bsl/list/include + ${HITLS_SRC}/bsl/obj/include + ${HITLS_SRC}/bsl/include + ${HITLS_SRC}/bsl/sal/include + ${HITLS_SRC}/bsl/log/include + ${HITLS_SRC}/bsl/time/include + ${HITLS_SRC}/bsl/async/include + ${HITLS_SRC}/bsl/uio/include + ${HITLS_SRC}/bsl/uio/src + ${HITLS_SRC}/x509/x509_cert/include + ${HITLS_SRC}/tls/cert/hitls_x509_adapt + ${HITLS_SRC}/tls/include + ${HITLS_SRC}/tls/cert/cert_self + ${HITLS_SRC}/tls/cert/include + ${HITLS_SRC}/tls/config/include + ${HITLS_SRC}/tls/record/include + ${HITLS_SRC}/tls/handshake/cookie/include + ${HITLS_SRC}/tls/handshake/common/include + ${HITLS_SRC}/tls/crypt/include/ + ${HITLS_SRC}/tls/handshake/parse/include + ${HITLS_SRC}/tls/handshake/pack/src + ${HITLS_SRC}/tls/handshake/pack/include + ${HITLS_SRC}/tls/ccs/include + ${HITLS_SRC}/tls/alert/include + ${HITLS_SRC}/testcode/framework/stub + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/io/include + ${PROJECT_SOURCE_DIR}/cert/include + ${PROJECT_SOURCE_DIR}/crypt/include + ${PROJECT_SOURCE_DIR}/msg/include + ${PROJECT_SOURCE_DIR}/base/include + ${PROJECT_SOURCE_DIR}/resource/include + ${PROJECT_SOURCE_DIR}/rpc/include + ${PROJECT_SOURCE_DIR}/process/include + ${PROJECT_SOURCE_DIR}/transfer/include + ${PROJECT_SOURCE_DIR}/frame/src + ${PROJECT_SOURCE_DIR}/io/src + ${PROJECT_SOURCE_DIR}/func_wrapper/include + ${PROJECT_SOURCE_DIR}/callback/include) + +aux_source_directory(${PROJECT_SOURCE_DIR}/cert/src CERT_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/crypt/src CRYPT_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/io/src IO_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/frame/src FRAME_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/msg/src MSG_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/base/src BASE_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/resource/src RESOURCE_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/process/src PROCESS_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/rpc/src RPC_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/transfer/src TRANSFER_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/callback/src CALLBACK_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/func_wrapper/src WRAPPER_SRC) + +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) +SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) +add_compile_options(-g) +add_definitions(${CUSTOM_CFLAGS}) +add_library(${HLT_LIBNAME} + STATIC + ${BASE_SRC} ${RESOURCE_SRC} ${CALLBACK_SRC} ${PROCESS_SRC} ${RPC_SRC} ${TRANSFER_SRC}) +add_library(${DT_LIBNAME} + STATIC + ${BASE_SRC} ${CALLBACK_SRC} ${CRYPT_SRC} ${IO_SRC} ${FRAME_SRC} ${MSG_SRC}) +add_library(${WRAPPER_LIBNAME} + STATIC + ${WRAPPER_SRC}) + \ No newline at end of file diff --git a/testcode/framework/tls/base/include/lock.h b/testcode/framework/tls/base/include/lock.h new file mode 100644 index 00000000..e8cda7a4 --- /dev/null +++ b/testcode/framework/tls/base/include/lock.h @@ -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 __LOCK_H__ +#define __LOCK_H__ + +#include + +typedef pthread_mutex_t Lock; + +/** +* @brief Create a lock resource +*/ +Lock *OsLockNew(void); + +/** +* @brief Lock +*/ +int OsLock(Lock *lock); + +/** +* @brief Unlock +*/ +int OsUnLock(Lock *lock); + +/** +* @brief Release the lock resource +*/ +void OsLockDestroy(Lock *lock); + + +#endif // __LOCK_H__ \ No newline at end of file diff --git a/testcode/framework/tls/base/include/logger.h b/testcode/framework/tls/base/include/logger.h new file mode 100644 index 00000000..a719edbe --- /dev/null +++ b/testcode/framework/tls/base/include/logger.h @@ -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. + */ + +#ifndef __LOGGER_H__ +#define __LOGGER_H__ + +#include +#include +#include "securec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_MAX_SIZE 1024 + +typedef enum { + ENUM_LOG_LEVEL_TRACE, /* Basic level */ + ENUM_LOG_LEVEL_DEBUG, /* Debugging level */ + ENUM_LOG_LEVEL_WARNING, /* Warning level */ + ENUM_LOG_LEVEL_ERROR, /* Error level */ + ENUM_LOG_LEVEL_FATAL /* Fatal level */ +} LogLevel; + +/** +* @ingroup log +* @brief Record error information based on the log level +* +* @par +* Record error information based on the log level +* +* @attention +* +* @param[in] level Log level +* @param[in] file File where the error information is stored +* @param[in] line Number of the line where the error information is stored +* @param[in] fmt Format character string for printing +* +* @retval 0 Success +* @retval others failure +*/ +int LogWrite(LogLevel level, const char *file, int line, const char *fmt, ...); + +#define LOG_DEBUG(...) LogWrite(ENUM_LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__) +#define LOG_ERROR(...) LogWrite(ENUM_LOG_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // __LOGGER_H__ diff --git a/testcode/framework/tls/base/src/lock.c b/testcode/framework/tls/base/src/lock.c new file mode 100644 index 00000000..51530a49 --- /dev/null +++ b/testcode/framework/tls/base/src/lock.c @@ -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. + */ + +#include +#include +#include "securec.h" +#include "logger.h" +#include "lock.h" +Lock *OsLockNew(void) +{ + pthread_mutexattr_t attr; + Lock *lock; + + if ((lock = (Lock *)malloc(sizeof(pthread_mutex_t))) == NULL) { + LOG_ERROR("OAL_Malloc error"); + return NULL; + } + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + + if (pthread_mutex_init(lock, &attr) != 0) { + LOG_ERROR("pthread_mutex_init error"); + pthread_mutexattr_destroy(&attr); + free(lock); + return NULL; + } + + pthread_mutexattr_destroy(&attr); + return lock; +} + +int OsLock(Lock *lock) +{ + if (pthread_mutex_lock(lock) != 0) { + LOG_ERROR("pthread_mutex_lock error"); + return -1; + } + return 0; +} + +int OsUnLock(Lock *lock) +{ + if (pthread_mutex_unlock(lock) != 0) { + LOG_ERROR("pthread_mutex_unlock error"); + return -1; + } + return 0; +} + +void OsLockDestroy(Lock *lock) +{ + if (lock == NULL) { + return; + } + pthread_mutex_destroy(lock); + free(lock); +} diff --git a/testcode/framework/tls/base/src/logger.c b/testcode/framework/tls/base/src/logger.c new file mode 100644 index 00000000..398a1865 --- /dev/null +++ b/testcode/framework/tls/base/src/logger.c @@ -0,0 +1,95 @@ +/* + * 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 +#include "logger.h" + +LogLevel GetLogLevel(void) +{ +#ifdef TLS_DEBUG + return ENUM_LOG_LEVEL_TRACE; +#else + return ENUM_LOG_LEVEL_FATAL; +#endif +} + +static const char *ConvertLevel2Str(LogLevel level) +{ + switch (level) { + case ENUM_LOG_LEVEL_TRACE: + return "TRACE"; + case ENUM_LOG_LEVEL_DEBUG: + return "DEBUG"; + case ENUM_LOG_LEVEL_WARNING: + return "WARNING"; + case ENUM_LOG_LEVEL_ERROR: + return "ERROR"; + case ENUM_LOG_LEVEL_FATAL: + return "FATAL"; + default: + return "UNKNOWN"; + } +} + +int LogWrite(LogLevel level, const char *file, int line, const char *fmt, ...) +{ + int len, ilen; + LogLevel curLevel; + va_list vargs; + int tmpLevel = level; + char logBuf[LOG_MAX_SIZE] = {0}; + + if ((tmpLevel < ENUM_LOG_LEVEL_TRACE) || (tmpLevel > ENUM_LOG_LEVEL_FATAL)) { + return 0; + } + + // Print logs whose levels are higher than or equal to the current level. + curLevel = GetLogLevel(); + if (level < curLevel) { + return 0; + } + + // Process the log header + if (file == NULL || line == 0) { + len = snprintf_s(logBuf, LOG_MAX_SIZE, (size_t)(LOG_MAX_SIZE - 1), "[%d_TEST_%s]", + getpid(), ConvertLevel2Str((LogLevel)tmpLevel)); + } else { + len = snprintf_s(logBuf, LOG_MAX_SIZE, (size_t)(LOG_MAX_SIZE - 1), "[%d_TEST_%s][%s:%d]", + getpid(), ConvertLevel2Str((LogLevel)tmpLevel), file, line); + } + + if (len < 0 || len > LOG_MAX_SIZE - 1) { + return 0; + } + + va_start(vargs, fmt); + ilen = vsnprintf_s(logBuf + len, (size_t)(LOG_MAX_SIZE - len), (size_t)(LOG_MAX_SIZE - len - 1), fmt, vargs); + if (ilen < 0 || ilen > LOG_MAX_SIZE - len - 1) { + // In the case of overflow truncation, the maximum value is used + len = LOG_MAX_SIZE; + logBuf[len - 1] = '\0'; + goto END; + } + + len += ilen; + logBuf[len] = '\n'; + logBuf[len + 1] = '\0'; +END: + va_end(vargs); +#ifdef TLS_DEBUG + printf("%s", logBuf); +#endif + return 0; +} diff --git a/testcode/framework/tls/callback/include/cert_callback.h b/testcode/framework/tls/callback/include/cert_callback.h new file mode 100644 index 00000000..3a350265 --- /dev/null +++ b/testcode/framework/tls/callback/include/cert_callback.h @@ -0,0 +1,51 @@ +/* + * 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 CERT_CALLBACK_H +#define CERT_CALLBACK_H + +#include "hlt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief Certificate callback +*/ +int32_t RegCertCallback(CertCallbackType type); + +/** +* @brief Memory callback +*/ +int32_t RegMemCallback(MemCallbackType type); + +/** +* @brief Loading Certificates and Private Keys by hitls x509 +*/ +int32_t HiTLS_X509_LoadCertAndKey(HITLS_Config *tlsCfg, const char *caFile, const char *chainFile, + const char *eeFile, const char *signFile, const char *privateKeyFile, const char *signPrivateKeyFile); + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4); + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para); + +#ifdef __cplusplus +} +#endif + +#endif // CERT_CALLBACK_H \ No newline at end of file diff --git a/testcode/framework/tls/callback/src/cert_callback.c b/testcode/framework/tls/callback/src/cert_callback.c new file mode 100644 index 00000000..b35be48a --- /dev/null +++ b/testcode/framework/tls/callback/src/cert_callback.c @@ -0,0 +1,319 @@ +/* + * 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 +#include +#include +#include "crypt_eal_pkey.h" +#include "hlt_type.h" +#include "hitls_cert_type.h" +#include "hitls_cert.h" +#include "hitls_type.h" +#include "hitls_cert_reg.h" +#include "hitls_config.h" +#include "hitls_cert.h" +#include "hitls_cert_init.h" +#include "bsl_sal.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "logger.h" +#include "tls_config.h" +#include "tls.h" +#include "bsl_list.h" +#include "hitls_x509_adapt_local.h" +#include "hitls_cert_init.h" + +#define SUCCESS 0 +#define ERROR (-1) +#define SINGLE_CERT_LEN (512) +#define CERT_FILE_LEN (4 * 1024) + +int32_t RegCertCallback(CertCallbackType type) +{ + switch (type) { + case CERT_CALLBACK_DEFAULT: + HITLS_CertMethodInit(); + break; + default: + return ERROR; + } + return SUCCESS; +} + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para1, para2, para3, para4); + printf("\n"); + return; +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para); + printf("\n"); + return; +} + +void RegDefaultMemCallback(void) +{ + BSL_SAL_MemCallback memMthod = {(void *(*)(uint32_t size))(uintptr_t)malloc, free}; + BSL_SAL_RegMemCallback(&memMthod); + BSL_ERR_Init(); + BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_DEBUG); +#ifdef TLS_DEBUG + BSL_LOG_BinLogFuncs logFunc = { BinLogFixLenFunc, BinLogVarLenFunc }; + BSL_LOG_RegBinLogFunc(&logFunc); +#endif + LOG_DEBUG("HiTLS RegDefaultMemCallback"); + return; +} + +int32_t RegMemCallback(MemCallbackType type) +{ + switch (type) { + case MEM_CALLBACK_DEFAULT : RegDefaultMemCallback(); break; + default: + return ERROR; + } + return SUCCESS; +} + +HITLS_CERT_X509 *HiTLS_X509_LoadCertFile(const char *file) +{ + return HITLS_X509_Adapt_CertParse(NULL, (const uint8_t *)file, strlen(file) + 1, TLS_PARSE_TYPE_FILE, + TLS_PARSE_FORMAT_ASN1); +} + +void *HiTLS_X509_LoadCertListToStore(const char *fileList) +{ + int32_t ret; + char certList[MAX_CERT_LEN] = {0}; + char certPath[SINGLE_CERT_LEN] = {0}; + + ret = memcpy_s(certList, MAX_CERT_LEN, fileList, strlen(fileList)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + return NULL; + } + + void *store = HITLS_X509_Adapt_StoreNew(); + if(store == NULL){ + return NULL; + } + + char *rest = NULL; + char *token = strtok_s(certList, ":", &rest); + do { + (void)memset_s(certPath, SINGLE_CERT_LEN, 0, SINGLE_CERT_LEN); + ret = sprintf_s(certPath, SINGLE_CERT_LEN, "%s%s", DEFAULT_CERT_PATH, token); + if (ret <= 0) { + LOG_ERROR("sprintf_s Error"); + HITLS_X509_Adapt_StoreFree(store); + return NULL; + } + LOG_DEBUG("Load Cert Path is %s", certPath); + + HITLS_CERT_X509 *cert = HiTLS_X509_LoadCertFile(certPath); + if (cert == NULL) { + HITLS_X509_Adapt_StoreFree(store); + return NULL; + } + ret = HITLS_X509_Adapt_StoreCtrl(NULL, store, CERT_STORE_CTRL_SHALLOW_COPY_ADD_CERT_LIST, cert, NULL); + if (ret != SUCCESS) { + LOG_ERROR("X509_STORE_add_cert Error: path = %s.", certPath); + HITLS_X509_Adapt_StoreFree(store); + return NULL; + } + token = strtok_s(NULL, ":", &rest); + } while (token != NULL); + + return store; +} + +int32_t HITLS_X509_LoadEECertList(HITLS_Config *tlsCfg, const char *eeFileList, bool isEnc) +{ + int32_t ret; + HITLS_CERT_X509 *cert = NULL; + char certList[MAX_CERT_LEN] = {0}; + char certPath[SINGLE_CERT_LEN] = {0}; + + ret = memcpy_s(certList, MAX_CERT_LEN, eeFileList, strlen(eeFileList)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + return ERROR; + } + + char *rest = NULL; + char *token = strtok_s(certList, ":", &rest); + do { + (void)memset_s(certPath, SINGLE_CERT_LEN, 0, SINGLE_CERT_LEN); + ret = sprintf_s(certPath, SINGLE_CERT_LEN, "%s%s", DEFAULT_CERT_PATH, token); + if (ret <= 0) { + LOG_ERROR("sprintf_s Error"); + return ERROR; + } + LOG_DEBUG("Load Cert Path is %s", certPath); + + cert = HiTLS_X509_LoadCertFile(certPath); + if (cert == NULL) { + LOG_ERROR("LoadCert Error: path = %s", certPath); + return ERROR; + } + if (isEnc == true) { +#ifndef HITLS_NO_TLCP11 + ret = HITLS_CFG_SetTlcpCertificate(tlsCfg, cert, 0, isEnc); +#endif + } else { + ret = HITLS_CFG_SetCertificate(tlsCfg, cert, 0); + } + if (ret != SUCCESS) { + LOG_ERROR("HITLS_CFG_SetCertificate Error: path = %s.", certPath); + HITLS_X509_Adapt_CertFree(cert); + return ERROR; + } + token = strtok_s(NULL, ":", &rest); + } while (token != NULL); + return SUCCESS; +} + +int32_t HITLS_X509_LoadPrivateKeyList(HITLS_Config *tlsCfg, const char *keyFileList, bool isEnc) +{ + int32_t ret; + HITLS_CERT_Key *key = NULL; + char fileList[MAX_CERT_LEN] = {0}; + char filePath[SINGLE_CERT_LEN] = {0}; + + ret = memcpy_s(fileList, MAX_CERT_LEN, keyFileList, strlen(keyFileList)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + return ERROR; + } + + char *rest = NULL; + char *token = strtok_s(fileList, ":", &rest); + do { + (void)memset_s(filePath, SINGLE_CERT_LEN, 0, SINGLE_CERT_LEN); + ret = sprintf_s(filePath, SINGLE_CERT_LEN, "%s%s", DEFAULT_CERT_PATH, token); + if (ret <= 0) { + LOG_ERROR("sprintf_s Error"); + return ERROR; + } + LOG_DEBUG("Load Cert Path is %s", filePath); + + key = HITLS_X509_Adapt_KeyParse(tlsCfg, (const uint8_t *)filePath, strlen(filePath), + TLS_PARSE_TYPE_FILE, TLS_PARSE_FORMAT_ASN1); + if (key == NULL) { + LOG_ERROR("LoadCert Error: path = %s.", filePath); + return ERROR; + } + if (isEnc == true) { +#ifndef HITLS_NO_TLCP11 + ret = HITLS_CFG_SetTlcpPrivateKey(tlsCfg, key, 0, isEnc); +#endif + } else { + ret = HITLS_CFG_SetPrivateKey(tlsCfg, key, 0); + } + if (ret != SUCCESS) { + LOG_ERROR("HITLS_CFG_SetCertificate Error: path = %s.", filePath); + CRYPT_EAL_PkeyFreeCtx(key); + return ERROR; + } + token = strtok_s(NULL, ":", &rest); + } while (token != NULL); + return SUCCESS; +} + +void FRAME_HITLS_X509_FreeCert(HITLS_CERT_Store *caStore, HITLS_CERT_Store *chainStore) +{ + if (caStore != NULL) { + HITLS_X509_Adapt_StoreFree(caStore); + } + if (chainStore != NULL) { + HITLS_X509_Adapt_StoreFree(chainStore); + } + return; +} + +int32_t HiTLS_X509_LoadCertAndKey(HITLS_Config *tlsCfg, const char *caFile, const char *chainFile, + const char *eeFile, const char *signFile, const char *privateKeyFile, const char *signPrivateKeyFile) +{ + int32_t ret; + if ((caFile != NULL) && (strncmp(caFile, "NULL", strlen(caFile)) != 0)) { + HITLS_CERT_Store *caStore = HiTLS_X509_LoadCertListToStore(caFile); + if (caStore == NULL) { + return ERROR; + } + ret = HITLS_CFG_SetCertStore(tlsCfg, caStore, 0); + if (ret != SUCCESS) { + HITLS_X509_Adapt_StoreFree(caStore); + return ret; + } + } + + if ((chainFile != NULL) && (strncmp(chainFile, "NULL", strlen(chainFile)) != 0)) { + HITLS_CERT_Store *chainStore = HiTLS_X509_LoadCertListToStore(chainFile); + if (chainStore == NULL) { + return ERROR; + } + ret = HITLS_CFG_SetChainStore(tlsCfg, chainStore, 0); + if (ret != SUCCESS) { + HITLS_X509_Adapt_StoreFree(chainStore); + return ret; + } + } + + bool hasTlcpSignCert = ((signFile != NULL) && (strncmp(signFile, "NULL", strlen(signFile)) != 0)); + if (hasTlcpSignCert) { + ret = HITLS_X509_LoadEECertList(tlsCfg, signFile, false); + if (ret != SUCCESS) { + return ret; + } + } + + if ((eeFile != NULL) && (strncmp(eeFile, "NULL", strlen(eeFile)) != 0)) { + ret = HITLS_X509_LoadEECertList(tlsCfg, eeFile, hasTlcpSignCert); + if (ret != SUCCESS) { + return ret; + } + } + + if ((signPrivateKeyFile != NULL) && (strncmp(signPrivateKeyFile, "NULL", strlen(signPrivateKeyFile)) != 0)) { + ret = HITLS_X509_LoadPrivateKeyList(tlsCfg, signPrivateKeyFile, false); + if (ret != SUCCESS) { + return ret; + } + if ((privateKeyFile != NULL) && (strncmp(privateKeyFile, "NULL", strlen(eeFile)) != 0)) { + ret = HITLS_X509_LoadPrivateKeyList(tlsCfg, privateKeyFile, true); + if (ret != SUCCESS) { + return ret; + } + } + } else { + if ((privateKeyFile != NULL) && (strncmp(privateKeyFile, "NULL", strlen(eeFile)) != 0)) { + ret = HITLS_X509_LoadPrivateKeyList(tlsCfg, privateKeyFile, false); + if (ret != SUCCESS) { + return ret; + } + } + } + return SUCCESS; +} \ No newline at end of file diff --git a/testcode/framework/tls/crypt/include/stub_crypt.h b/testcode/framework/tls/crypt/include/stub_crypt.h new file mode 100644 index 00000000..8630fe84 --- /dev/null +++ b/testcode/framework/tls/crypt/include/stub_crypt.h @@ -0,0 +1,33 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef STUB_CRYPT_H +#define STUB_CRYPT_H +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief Stub the test framework +*/ +void FRAME_RegCryptMethod(void); + +void FRAME_DeRegCryptMethod(void); + +#ifdef __cplusplus +} +#endif + +#endif // STUB_CRYPT_H diff --git a/testcode/framework/tls/crypt/src/stub_crypt.c b/testcode/framework/tls/crypt/src/stub_crypt.c new file mode 100644 index 00000000..f1fa5828 --- /dev/null +++ b/testcode/framework/tls/crypt/src/stub_crypt.c @@ -0,0 +1,798 @@ +/* + * 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 +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls_crypt_reg.h" +#include "hitls_error.h" +#include "hs_common.h" + +#define MD5_DIGEST_LENGTH 16 +#define SHA1_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 +#define SM3_DIGEST_LENGTH 32 +#define AEAD_TAG_LENGTH 16 + +typedef struct { + HITLS_HashAlgo algo; + uint8_t *key; + uint32_t keyLen; +} FRAME_HmacCtx; + +typedef struct { + HITLS_HashAlgo algo; +} FRAME_HashCtx; + +typedef struct { + uint8_t *pubKey; + uint32_t pubKeyLen; + uint8_t *privateKey; + uint32_t privateKeyLen; +} FRAME_EcdhKey; + +typedef struct { + uint8_t *p; + uint8_t *g; + uint16_t plen; + uint16_t glen; + uint8_t *pubKey; + uint32_t pubKeyLen; + uint8_t *privateKey; + uint32_t privateKeyLen; +} FRAME_DhKey; + +/** + * @ingroup hitls_crypt_reg + * @brief Obtain the random number + * + * @param buf [OUT] random number + * @param len [IN] random number length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_RandBytesCallback(uint8_t *buf, uint32_t len) +{ + if (memset_s(buf, len, 1, len) != EOK) { + return HITLS_MEMCPY_FAIL; + } + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Generate a key pair based on the elliptic curve parameters + * + * @param curveParams [IN] Elliptic curve parameters + * + * @return Key handle + */ +HITLS_CRYPT_Key *STUB_CRYPT_GenerateEcdhKeyPairCallback(const HITLS_ECParameters *curveParams) +{ + uint32_t keyLen = 0u; + if (curveParams == NULL) { + return NULL; + } + + FRAME_EcdhKey *ecdhKey = (FRAME_EcdhKey *)BSL_SAL_Calloc(1u, sizeof(FRAME_EcdhKey)); + if (ecdhKey == NULL) { + return NULL; + } + switch (curveParams->type) { + case HITLS_EC_CURVE_TYPE_NAMED_CURVE: + keyLen = HS_GetNamedCurvePubkeyLen(curveParams->param.namedcurve); + break; + default: + break; + } + + uint8_t *pubKey = (uint8_t *)BSL_SAL_Malloc(keyLen); + if (pubKey == NULL) { + BSL_SAL_FREE(ecdhKey); + return NULL; + } + memset_s(pubKey, keyLen, 1u, keyLen); + + uint8_t *privateKey = (uint8_t *)BSL_SAL_Malloc(keyLen); + if (privateKey == NULL) { + BSL_SAL_FREE(pubKey); + BSL_SAL_FREE(ecdhKey); + return NULL; + } + memset_s(privateKey, keyLen, 2u, keyLen); + + ecdhKey->pubKey = pubKey; + ecdhKey->pubKeyLen = keyLen; + ecdhKey->privateKey = privateKey; + ecdhKey->privateKeyLen = keyLen; + return ecdhKey; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Release the key + * + * @param key [IN] Key handle + */ +void STUB_CRYPT_FreeEcdhKeyCallback(HITLS_CRYPT_Key *key) +{ + FRAME_EcdhKey *ecdhKey = (FRAME_EcdhKey *)key; + if (ecdhKey != NULL) { + BSL_SAL_FREE(ecdhKey->pubKey); + BSL_SAL_FREE(ecdhKey->privateKey); + BSL_SAL_FREE(ecdhKey); + } + return; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Extract the public key data + * + * @param key [IN] Key handle + * @param pubKeyBuf [OUT] Public key data + * @param bufLen [IN] buffer length + * @param pubKeyLen [OUT] Public key data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_GetEcdhEncodedPubKeyCallback(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, + uint32_t *pubKeyLen) +{ + FRAME_EcdhKey *ecdhKey = (FRAME_EcdhKey *)key; + if ((ecdhKey == NULL) || + (pubKeyBuf == NULL) || + (pubKeyLen == NULL) || + (bufLen < ecdhKey->pubKeyLen)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memcpy_s(pubKeyBuf, bufLen, ecdhKey->pubKey, ecdhKey->pubKeyLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *pubKeyLen = ecdhKey->pubKeyLen; + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Calculate the shared key based on the local key and peer public key + * + * @param key [IN] Key handle + * @param pubKeyBuf [IN] Public key data + * @param pubKeyLen [IN] Public key data length + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of the key padding OUT: Key length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_CalcEcdhSharedSecretCallback(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen) +{ + FRAME_EcdhKey *ecdhKey = (FRAME_EcdhKey *)key; + + if ((ecdhKey == NULL) || + (peerPubkey == NULL) || + (sharedSecret == NULL) || + (sharedSecretLen == NULL) || + (ecdhKey->privateKeyLen > pubKeyLen) || + (*sharedSecretLen < pubKeyLen)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memset_s(sharedSecret, *sharedSecretLen, 3u, pubKeyLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *sharedSecretLen = pubKeyLen; + return HITLS_SUCCESS; +} + +void STUB_CRYPT_FreeDhKeyCallback(HITLS_CRYPT_Key *key) +{ + FRAME_DhKey *dhKey = (FRAME_DhKey *)key; + if (dhKey != NULL) { + BSL_SAL_FREE(dhKey->p); + BSL_SAL_FREE(dhKey->g); + BSL_SAL_FREE(dhKey->privateKey); + BSL_SAL_FREE(dhKey->pubKey); + BSL_SAL_FREE(dhKey); + } + return; +} + +HITLS_CRYPT_Key *STUB_CRYPT_GenerateDhKeyBySecbitsCallback(int32_t secbits) +{ + uint16_t plen; + if (secbits >= 192) { + plen = 1024; + } else if (secbits >= 152) { + plen = 512; + } else if (secbits >= 128) { + plen = 384; + } else if (secbits >= 112) { + plen = 256; + } else { + plen = 128; + } + + FRAME_DhKey *dhKey = (FRAME_DhKey *)BSL_SAL_Calloc(1u, sizeof(FRAME_DhKey)); + if (dhKey == NULL) { + return NULL; + } + + dhKey->p = BSL_SAL_Calloc(1u, plen); + if (dhKey->p == NULL) { + BSL_SAL_FREE(dhKey); + return NULL; + } + memset_s(dhKey->p, plen, 1u, plen); + dhKey->plen = plen; + + dhKey->g = BSL_SAL_Calloc(1u, plen); + if (dhKey->g == NULL) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + memset_s(dhKey->g, plen, 2u, plen); + dhKey->glen = plen; + + dhKey->pubKey = BSL_SAL_Calloc(1u, plen); + if (dhKey->pubKey == NULL) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + memset_s(dhKey->pubKey, plen, 3u, plen); + dhKey->pubKeyLen = plen; + + dhKey->privateKey = BSL_SAL_Calloc(1u, plen); + if (dhKey->privateKey == NULL) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + memset_s(dhKey->privateKey, plen, 4u, plen); + dhKey->privateKeyLen = plen; + + return dhKey; +} + +HITLS_CRYPT_Key *STUB_CRYPT_GenerateDhKeyByParamsCallback(uint8_t *p, uint16_t plen, uint8_t *g, uint16_t glen) +{ + if ((p == NULL) || (plen == 0) || (g == NULL) || (glen == 0)) { + return NULL; + } + + FRAME_DhKey *dhKey = (FRAME_DhKey *)BSL_SAL_Calloc(1u, sizeof(FRAME_DhKey)); + if (dhKey == NULL) { + return NULL; + } + + dhKey->p = BSL_SAL_Dump(p, plen); + if (dhKey->p == NULL) { + BSL_SAL_FREE(dhKey); + return NULL; + } + dhKey->plen = plen; + + dhKey->g = BSL_SAL_Dump(g, glen); + if (dhKey->g == NULL) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + dhKey->glen = glen; + + dhKey->pubKey = BSL_SAL_Calloc(1u, plen); + if (dhKey->pubKey == NULL) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + if (memset_s(dhKey->pubKey, plen, 3u, plen) != EOK) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + dhKey->pubKeyLen = plen; + + dhKey->privateKey = BSL_SAL_Calloc(1u, plen); + if (dhKey->privateKey == NULL) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + if (memset_s(dhKey->privateKey, plen, 4u, plen) != EOK) { + STUB_CRYPT_FreeDhKeyCallback(dhKey); + return NULL; + } + dhKey->privateKeyLen = plen; + + return dhKey; +} + +int32_t STUB_CRYPT_DHGetParametersCallback(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *plen, uint8_t *g, uint16_t *glen) +{ + if ((key == NULL) || (plen == NULL) || (glen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + FRAME_DhKey *dhKey = (FRAME_DhKey *)key; + + if (p != NULL) { + if (memcpy_s(p, *plen, dhKey->p, dhKey->plen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + } + + if (g != NULL) { + if (memcpy_s(g, *glen, dhKey->g, dhKey->glen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + } + + *plen = dhKey->plen; + *glen = dhKey->glen; + return HITLS_SUCCESS; +} + +int32_t STUB_CRYPT_GetDhEncodedPubKeyCallback(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, + uint32_t *pubKeyLen) +{ + if ((key == NULL) || (pubKeyBuf == NULL) || (pubKeyLen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + FRAME_DhKey *dhKey = (FRAME_DhKey *)key; + + if (memcpy_s(pubKeyBuf, bufLen, dhKey->pubKey, dhKey->pubKeyLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + + *pubKeyLen = dhKey->pubKeyLen; + return HITLS_SUCCESS; +} + +int32_t STUB_CRYPT_CalcDhSharedSecretCallback(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen) +{ + FRAME_DhKey *dhKey = (FRAME_DhKey *)key; + + if ((dhKey == NULL) || + (peerPubkey == NULL) || + (sharedSecret == NULL) || + (sharedSecretLen == NULL) || + (dhKey->plen < pubKeyLen)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memset_s(sharedSecret, *sharedSecretLen, 1u, dhKey->plen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *sharedSecretLen = dhKey->plen; + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Obtain the HMAC length + * + * @param hashAlgo [IN] Hash algorithm + * + * @return HMAC length + */ +uint32_t STUB_CRYPT_HmacSizeCallback(HITLS_HashAlgo hashAlgo) +{ + switch (hashAlgo) { + case HITLS_HASH_MD5: + return MD5_DIGEST_LENGTH; + case HITLS_HASH_SHA1: + return SHA1_DIGEST_LENGTH; + case HITLS_HASH_SHA_256: + return SHA256_DIGEST_LENGTH; + case HITLS_HASH_SHA_384: + return SHA384_DIGEST_LENGTH; + case HITLS_HASH_SHA_512: + return SHA512_DIGEST_LENGTH; + case HITLS_HASH_MD5_SHA1: + return (MD5_DIGEST_LENGTH + SHA1_DIGEST_LENGTH); + default: + break; + } + return 0u; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Initialize the HMAC context + * + * @param hashAlgo [IN] Hash algorithm + * @param key [IN] Key + * @param len [IN] Key length + * + * @return HMAC context + */ +HITLS_HMAC_Ctx *STUB_CRYPT_HmacInitCallback(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len) +{ + FRAME_HmacCtx *ctx = BSL_SAL_Calloc(1u, sizeof(FRAME_HmacCtx)); + if (ctx == NULL) { + return NULL; + } + ctx->algo = hashAlgo; + ctx->key = BSL_SAL_Dump(key, len); + if (ctx->key == NULL) { + BSL_SAL_FREE(ctx); + return NULL; + } + ctx->keyLen = len; + return ctx; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Release the HMAC context + * + * @param ctx [IN] HMAC context + */ +void STUB_CRYPT_HmacFreeCallback(HITLS_HMAC_Ctx *ctx) +{ + FRAME_HmacCtx *hmacCtx = (FRAME_HmacCtx *)ctx; + if (hmacCtx != NULL) { + BSL_SAL_FREE(hmacCtx->key); + BSL_SAL_FREE(hmacCtx); + } + return; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Add the input data + * + * @param ctx [IN] HMAC context + * @param data [IN] Input data + * @param len [IN] Data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_HmacUpdateCallback(HITLS_HMAC_Ctx *ctx, const uint8_t *data, uint32_t len) +{ + if ((ctx == NULL) || (data == NULL) || len == 0) { + return HITLS_INTERNAL_EXCEPTION; + } + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Output the HMAC result + * + * @param ctx [IN] HMAC context + * @param out [OUT] Output data + * @param len [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_HmacFinalCallback(HITLS_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + FRAME_HmacCtx *hmacCtx = (FRAME_HmacCtx *)ctx; + if ((hmacCtx == NULL) || (out == NULL) || (len == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t hmacSize = STUB_CRYPT_HmacSizeCallback(hmacCtx->algo); + if ((hmacSize == 0u) || (hmacSize > *len)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memset_s(out, *len, 4u, hmacSize) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *len = hmacSize; + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief HMAC function + * + * @param hashAlgo [IN] Hash algorithm + * @param key [IN] Key + * @param keyLen [IN] Key length + * @param in [IN] Input data + * @param inLen [IN] Input data length + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_HmacCallback(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen, + const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ + if ((key == NULL) || (keyLen == 0) || (in == NULL) || (inLen == 0) || + (out == NULL) || (outLen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t hmacSize = STUB_CRYPT_HmacSizeCallback(hashAlgo); + if ((hmacSize == 0u) || (hmacSize > *outLen)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memset_s(out, *outLen, 4u, hmacSize) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *outLen = hmacSize; + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Obtain the hash length + * + * @param hashAlgo [IN] Hash algorithm + * + * @return Hash length + */ +uint32_t STUB_CRYPT_DigestSizeCallback(HITLS_HashAlgo hashAlgo) +{ + return STUB_CRYPT_HmacSizeCallback(hashAlgo); +} + +/** + * @ingroup hitls_crypt_reg + * @brief Initialize the hash context + * + * @param hashAlgo [IN] Hash algorithm + * + * @return hash context + */ +HITLS_HASH_Ctx *STUB_CRYPT_DigestInitCallback(HITLS_HashAlgo hashAlgo) +{ + FRAME_HashCtx *ctx = BSL_SAL_Calloc(1u, sizeof(FRAME_HashCtx)); + if (ctx == NULL) { + return NULL; + } + ctx->algo = hashAlgo; + return ctx; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Copy hash Context + * + * @param ctx [IN] hash Context + * + * @return hash Context + */ +HITLS_HASH_Ctx *STUB_CRYPT_DigestCopyCallback(HITLS_HASH_Ctx *ctx) +{ + FRAME_HashCtx *srcCtx = (FRAME_HashCtx *)ctx; + if (srcCtx == NULL) { + return NULL; + } + + FRAME_HashCtx *newCtx = BSL_SAL_Calloc(1u, sizeof(FRAME_HashCtx)); + if (newCtx == NULL) { + return NULL; + } + newCtx->algo = srcCtx->algo; + return newCtx; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Release the hash context + * + * @param ctx [IN] hash Context + */ +void STUB_CRYPT_DigestFreeCallback(HITLS_HASH_Ctx *ctx) +{ + BSL_SAL_FREE(ctx); + return; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Add the input data + * + * @param ctx [IN] hash Context + * @param data [IN] Input data + * @param len [IN] Input data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_DigestUpdateCallback(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len) +{ + if ((ctx == NULL) || (data == NULL) || (len == 0u)) { + return HITLS_INTERNAL_EXCEPTION; + } + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Output the hash result + * + * @param ctx [IN] hash Context + * @param out [IN] Output data + * @param len [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_DigestFinalCallback(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + FRAME_HashCtx *hashCtx = (FRAME_HashCtx *)ctx; + if ((hashCtx == NULL) || (out == NULL) || (len == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t digestSize = STUB_CRYPT_DigestSizeCallback(hashCtx->algo); + if ((digestSize == 0) || (digestSize > *len)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memset_s(out, *len, 5u, digestSize) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *len = digestSize; + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief hash function + * + * @param hashAlgo [IN] Hash algorithm + * @param in [IN] Input data + * @param inLen [IN] Input data length + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum buffer length OUT: Output data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_DigestCallback(HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + if ((in == NULL) || + (out == NULL) || + (outLen == NULL) || + (inLen == 0)) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t digestSize = STUB_CRYPT_DigestSizeCallback(hashAlgo); + if ((digestSize == 0) || (digestSize > *outLen)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memset_s(out, *outLen, 5u, digestSize) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *outLen = digestSize; + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Encryption + * + * @param cipher [IN] Key parameters + * @param in [IN] Plaintext data + * @param inLen [IN] Plaintext data length + * @param out [OUT] Ciphertext data + * @param outLen [IN/OUT] IN: maximum buffer length OUT: ciphertext data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_EncryptCallback(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + if (cipher->type == HITLS_AEAD_CIPHER) { + if (*outLen < inLen + AEAD_TAG_LENGTH) { + return HITLS_INTERNAL_EXCEPTION; + } + (void)memset_s(out, *outLen, 0, *outLen); + if (inLen != 0 && memcpy_s(out, *outLen, in, inLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *outLen = inLen + AEAD_TAG_LENGTH; + } else { + *outLen = 0; + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls_crypt_reg + * @brief Decrypt + * + * @param cipher [IN] Key parameters + * @param in [IN] Ciphertext data + * @param inLen [IN] Ciphertext data length + * @param out [OUT] Plaintext data + * @param outLen [IN/OUT] IN: Maximum buffer length OUT: Plaintext data length + * + * @return 0 indicates success. Other values indicate failure + */ +int32_t STUB_CRYPT_DecryptCallback(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + if (cipher->type == HITLS_AEAD_CIPHER) { + if (inLen < AEAD_TAG_LENGTH) { + return HITLS_INTERNAL_EXCEPTION; + } + (void)memset_s(out, *outLen, 0, *outLen); + if (memcpy_s(out, *outLen, in, inLen - AEAD_TAG_LENGTH) != EOK) { + return HITLS_MEMCPY_FAIL; + } + *outLen = inLen - AEAD_TAG_LENGTH; + } else { + *outLen = 0; + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +void FRAME_RegCryptMethod(void) +{ + HITLS_CRYPT_BaseMethod cryptMethod = { 0 }; + cryptMethod.randBytes = STUB_CRYPT_RandBytesCallback; + cryptMethod.hmacSize = STUB_CRYPT_HmacSizeCallback; + cryptMethod.hmacInit = STUB_CRYPT_HmacInitCallback; + cryptMethod.hmacFree = STUB_CRYPT_HmacFreeCallback; + cryptMethod.hmacUpdate = STUB_CRYPT_HmacUpdateCallback; + cryptMethod.hmacFinal = STUB_CRYPT_HmacFinalCallback; + cryptMethod.hmac = STUB_CRYPT_HmacCallback; + cryptMethod.digestSize = STUB_CRYPT_DigestSizeCallback; + cryptMethod.digestInit = STUB_CRYPT_DigestInitCallback; + cryptMethod.digestCopy = STUB_CRYPT_DigestCopyCallback; + cryptMethod.digestFree = STUB_CRYPT_DigestFreeCallback; + cryptMethod.digestUpdate = STUB_CRYPT_DigestUpdateCallback; + cryptMethod.digestFinal = STUB_CRYPT_DigestFinalCallback; + cryptMethod.digest = STUB_CRYPT_DigestCallback; + cryptMethod.encrypt = STUB_CRYPT_EncryptCallback; + cryptMethod.decrypt = STUB_CRYPT_DecryptCallback; + HITLS_CRYPT_RegisterBaseMethod(&cryptMethod); + + HITLS_CRYPT_EcdhMethod ecdhMethod = { 0 }; + ecdhMethod.generateEcdhKeyPair = STUB_CRYPT_GenerateEcdhKeyPairCallback; + ecdhMethod.freeEcdhKey = STUB_CRYPT_FreeEcdhKeyCallback; + ecdhMethod.getEcdhPubKey = STUB_CRYPT_GetEcdhEncodedPubKeyCallback; + ecdhMethod.calcEcdhSharedSecret = STUB_CRYPT_CalcEcdhSharedSecretCallback; + HITLS_CRYPT_RegisterEcdhMethod(&ecdhMethod); + + HITLS_CRYPT_DhMethod dhMethod = { 0 }; + dhMethod.generateDhKeyBySecbits = STUB_CRYPT_GenerateDhKeyBySecbitsCallback; + dhMethod.generateDhKeyByParams = STUB_CRYPT_GenerateDhKeyByParamsCallback; + dhMethod.freeDhKey = STUB_CRYPT_FreeDhKeyCallback; + dhMethod.getDhParameters = STUB_CRYPT_DHGetParametersCallback; + dhMethod.getDhPubKey = STUB_CRYPT_GetDhEncodedPubKeyCallback; + dhMethod.calcDhSharedSecret = STUB_CRYPT_CalcDhSharedSecretCallback; + HITLS_CRYPT_RegisterDhMethod(&dhMethod); + return; +} + +void FRAME_DeRegCryptMethod(void) +{ + HITLS_CRYPT_BaseMethod cryptMethod = { 0 }; + HITLS_CRYPT_RegisterBaseMethod(&cryptMethod); + + HITLS_CRYPT_EcdhMethod ecdhMethod = { 0 }; + HITLS_CRYPT_RegisterEcdhMethod(&ecdhMethod); + + HITLS_CRYPT_DhMethod dhMethod = { 0 }; + HITLS_CRYPT_RegisterDhMethod(&dhMethod); + return; +} \ No newline at end of file diff --git a/testcode/framework/tls/frame/src/frame_connect.c b/testcode/framework/tls/frame/src/frame_connect.c new file mode 100644 index 00000000..93a856cc --- /dev/null +++ b/testcode/framework/tls/frame/src/frame_connect.c @@ -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 +#include "securec.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "change_cipher_spec.h" +#include "stub_replace.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "frame_link.h" + +#define ENTER_USER_SPECIFY_STATE (HITLS_UIO_FAIL_START + 0xFFFF) + +#define READ_BUF_SIZE 18432 +HITLS_HandshakeState g_nextState; +bool g_isClient; + +int32_t FRAME_TrasferMsgBetweenLink(FRAME_LinkObj *linkA, FRAME_LinkObj *linkB) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t readLen = 0; + char *buffer = BSL_SAL_Calloc(1u, MAX_RECORD_LENTH); + if (buffer == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + // linkA->io->userData to buffer + ret = FRAME_TransportSendMsg(linkA->io, buffer, MAX_RECORD_LENTH, &readLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(buffer); + return ret; + } + if (readLen == 0) { + BSL_SAL_FREE(buffer); + return HITLS_SUCCESS; + } + + // buffer to linkB->io->userData + ret = FRAME_TransportRecMsg(linkB->io, buffer, readLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(buffer); + return ret; + } + + BSL_SAL_FREE(buffer); + return HITLS_SUCCESS; +} + +static int32_t STUB_ChangeState(TLS_Ctx *ctx, uint32_t nextState) +{ + int32_t ret = HITLS_SUCCESS; + if (g_nextState == nextState) { + if (g_isClient == ctx->isClient) { + ret = HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } + } + + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + hsCtx->state = nextState; + return ret; +} + +static bool StateCompare(FRAME_LinkObj *link, bool isClient, HITLS_HandshakeState state) +{ + if ((isClient == link->ssl->isClient) && (link->ssl->hsCtx != NULL) && (link->ssl->hsCtx->state == state)) { + if (state != TRY_RECV_FINISH && state != TRY_RECV_CERTIFICATE) { + return true; + } + /* In tls1.3, if the single-end verification is used, the server may receive the CCS message in the TRY_RECV_FINISH phase */ + if (state == TRY_RECV_FINISH){ + if (link->needStopBeforeRecvCCS || CCS_IsRecv(link->ssl) == true || + (link->ssl->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13 && isClient == true) || + (link->ssl->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13 && + link->ssl->config.tlsConfig.isSupportClientVerify == true)) { + return true; + } + } + // In tls1.3, the server may receive the CCS message in the TRY_RECV_CERTIFICATIONATE phase + if (state == TRY_RECV_CERTIFICATE){ + if (link->needStopBeforeRecvCCS || CCS_IsRecv(link->ssl) == true || link->ssl->hsCtx->haveHrr == true || + link->ssl->config.tlsConfig.maxVersion != HITLS_VERSION_TLS13 || isClient == true) { + return true; + } + } + } + return false; +} + +int32_t FRAME_CreateConnection(FRAME_LinkObj *client, FRAME_LinkObj *server, bool isClient, HITLS_HandshakeState state) +{ + int32_t clientRet; + int32_t serverRet; + int32_t ret; + uint32_t count = 0; + + if (client == NULL || server == NULL) { + return HITLS_NULL_INPUT; + } + + g_isClient = isClient; + g_nextState = state; + + FuncStubInfo tmpRpInfo = {0}; + STUB_Init(); + STUB_Replace(&tmpRpInfo, HS_ChangeState, STUB_ChangeState); + + do { + // Check whether the client needs to be stopped. If yes, return success + if (StateCompare(client, isClient, state)) { + ret = HITLS_SUCCESS; + break; + } + + // Invoke the client to establish a connection + clientRet = HITLS_Connect(client->ssl); + if (clientRet != HITLS_SUCCESS) { + ret = clientRet; + if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + break; + } + } + + // Transfer the message to the server + ret = FRAME_TrasferMsgBetweenLink(client, server); + if (ret != HITLS_SUCCESS) { + break; + } + + // Check whether the server needs to be stopped. If yes, return success + if (StateCompare(server, isClient, state)) { + ret = HITLS_SUCCESS; + break; + } + + // Invoke the server to establish a connection + serverRet = HITLS_Accept(server->ssl); + if (serverRet != HITLS_SUCCESS) { + ret = serverRet; + if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + break; + } + } + + // Transfer the message to the client + ret = FRAME_TrasferMsgBetweenLink(server, client); + if (ret != HITLS_SUCCESS) { + break; + } + + /* To receive TLS1.3 new session ticket messages */ + if (clientRet == HITLS_SUCCESS) { + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ret = HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen); + // No application data. return HITLS_REC_NORMAL_RECV_BUF_EMPTY + if (ret != HITLS_REC_NORMAL_RECV_BUF_EMPTY) { + return ret; + } + } + + // If the connection is set up on both sides, return success + if (clientRet == HITLS_SUCCESS && serverRet == HITLS_SUCCESS) { + ret = HITLS_SUCCESS; + break; + } + + count++; + ret = HITLS_INTERNAL_EXCEPTION; + // Prevent infinite loop. No more than 30 messages are exchanged between the client and server during the handshake + } while (count < 30); + + //Check whether the hsCtx status meets the expectation. If hsCtx is destructed, HITLS_INTERNAL_EXCEPTION is returned + if (state != HS_STATE_BUTT) { + FRAME_LinkObj *point = (isClient) ? (client) : (server); + if (point->ssl->hsCtx == NULL) { + ret = HITLS_INTERNAL_EXCEPTION; + } else if (point->ssl->hsCtx->state != state) { + ret = HITLS_INTERNAL_EXCEPTION; + } + } + + STUB_Reset(&tmpRpInfo); + return ret; +} + +int32_t FRAME_CreateRenegotiation(FRAME_LinkObj *linkA, FRAME_LinkObj *linkB) +{ + int32_t clientRet; + int32_t serverRet; + int32_t ret; + uint32_t count = 0; + // renegotiation signal + uint8_t writeBuf[1] = {1}; + uint8_t readBuf[32] = {0}; // buffer for receive temporary messages, 32 bytes long + uint32_t readBufLen = 0; + + if (linkA->ssl->state != CM_STATE_RENEGOTIATION) { + return HITLS_SUCCESS; + } + + do { + clientRet = HITLS_Write(linkA->ssl, writeBuf, sizeof(writeBuf)); + if (clientRet != HITLS_SUCCESS) { + ret = clientRet; + if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + break; + } + } + + ret = FRAME_TrasferMsgBetweenLink(linkA, linkB); + if (ret != HITLS_SUCCESS) { + break; + } + + readBufLen = 0; + (void)memset_s(readBuf, sizeof(readBuf), 0, sizeof(readBuf)); + serverRet = HITLS_Read(linkB->ssl, readBuf, sizeof(readBuf), &readBufLen); + if (serverRet != HITLS_SUCCESS) { + ret = serverRet; + if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + break; + } + } + + ret = FRAME_TrasferMsgBetweenLink(linkB, linkA); + if (ret != HITLS_SUCCESS) { + break; + } + + // If the connection is set up on both sides, return success + if (clientRet == HITLS_SUCCESS && serverRet == HITLS_SUCCESS && + linkA->ssl->state == CM_STATE_TRANSPORTING && linkB->ssl->state == CM_STATE_TRANSPORTING) { + if ((readBufLen != sizeof(writeBuf)) || + (memcmp(writeBuf, readBuf, readBufLen) != 0)) { + ret = HITLS_INTERNAL_EXCEPTION; + } else { + ret = HITLS_SUCCESS; + } + break; + } + + count++; + ret = HITLS_INTERNAL_EXCEPTION; + // Prevent infinite loop. No more than 30 messages are exchanged between the client and server during the handshake + } while (count < 30); + + return ret; +} \ No newline at end of file diff --git a/testcode/framework/tls/frame/src/frame_init.c b/testcode/framework/tls/frame/src/frame_init.c new file mode 100644 index 00000000..588c9a94 --- /dev/null +++ b/testcode/framework/tls/frame/src/frame_init.c @@ -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 +#include +#include +#include +#include "cert_callback.h" +#include "bsl_sal.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "crypt_algid.h" +#include "hitls_crypt_init.h" +#include "crypt_eal_rand.h" +#include "hitls_cert_init.h" + +static void *StdMalloc(uint32_t len) +{ + return malloc((uint32_t)len); +} + +static void StdFree(void *addr) +{ + free(addr); +} + +static void *StdMallocFail(uint32_t len) +{ + (void)len; + return NULL; +} + +void FRAME_Init(void) +{ + BSL_SAL_MemCallback memMthod = {StdMalloc, StdFree}; + BSL_SAL_RegMemCallback(&memMthod); + BSL_ERR_Init(); + HITLS_CertMethodInit(); + CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + HITLS_CryptMethodInit(); + return; +} + +void FRAME_DeInit(void) +{ + BSL_SAL_MemCallback memMthod = {StdMallocFail, StdFree}; + BSL_SAL_RegMemCallback(&memMthod); + + BSL_ERR_DeInit(); + return; +} \ No newline at end of file diff --git a/testcode/framework/tls/frame/src/frame_link.c b/testcode/framework/tls/frame/src/frame_link.c new file mode 100644 index 00000000..e94840f6 --- /dev/null +++ b/testcode/framework/tls/frame/src/frame_link.c @@ -0,0 +1,249 @@ +/* + * 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 "securec.h" +#include "bsl_sal.h" +#include "uio_base.h" +#include "uio_abstraction.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" +#include "hitls_error.h" +#include "hlt_type.h" +#include "cert_callback.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "frame_link.h" + +#define MAX_CERT_PATH_LENGTH (1024) + +HITLS_Ctx *FRAME_CreateDefaultDtlsObj(void) +{ + HITLS_Config *config = HITLS_CFG_NewDTLS12Config(); + if (config == NULL) { + return NULL; + } + + char verifyPath[MAX_CERT_PATH_LENGTH] = {0}; + char chainPath[MAX_CERT_PATH_LENGTH] = {0}; + char certPath[MAX_CERT_PATH_LENGTH] = {0}; + char keyPath[MAX_CERT_PATH_LENGTH] = {0}; + if (sprintf_s(verifyPath, MAX_CERT_PATH_LENGTH, "%s:%s", RSA_SHA_CA_PATH, ECDSA_SHA_CA_PATH) <= 0) { + HITLS_CFG_FreeConfig(config); + return NULL; + } + + if (sprintf_s(chainPath, MAX_CERT_PATH_LENGTH, "%s:%s", RSA_SHA_CHAIN_PATH, ECDSA_SHA_CHAIN_PATH) <= 0) { + HITLS_CFG_FreeConfig(config); + return NULL; + } + + if (sprintf_s(certPath, MAX_CERT_PATH_LENGTH, "%s:%s", RSA_SHA256_EE_PATH3, ECDSA_SHA256_EE_PATH) <= 0) { + HITLS_CFG_FreeConfig(config); + return NULL; + } + + if (sprintf_s(keyPath, MAX_CERT_PATH_LENGTH, "%s:%s", RSA_SHA256_PRIV_PATH3, ECDSA_SHA256_PRIV_PATH) <= 0) { + HITLS_CFG_FreeConfig(config); + return NULL; + } + + int32_t ret = HiTLS_X509_LoadCertAndKey(config, verifyPath, chainPath, certPath, NULL, keyPath, NULL); + if (ret != HITLS_SUCCESS) { + HITLS_CFG_FreeConfig(config); + return NULL; + } + + HITLS_Ctx *ctx = HITLS_New(config); + if (ctx == NULL) { + HITLS_CFG_FreeConfig(config); + return NULL; + } + + HITLS_CFG_FreeConfig(config); + return ctx; +} + +FRAME_LinkObj *CreateLink(HITLS_Config *config, BSL_UIO_TransportType type) +{ + BSL_UIO_Method method = {0}; + BSL_UIO *io = NULL; + FrameUioUserData *ioUserdata = NULL; + const BSL_UIO_Method *ori = NULL; + switch (type) { + case BSL_UIO_TCP: + ori = BSL_UIO_TcpMethod(); + break; + default: + ori = BSL_UIO_SctpMethod(); + break; + } + if (memcpy_s(&method, sizeof(BSL_UIO_Method), ori, sizeof(method)) != EOK) { + return NULL; + } + + FRAME_LinkObj *linkObj = BSL_SAL_Calloc(1u, sizeof(FRAME_LinkObj)); + if (linkObj == NULL) { + return NULL; + } + + HITLS_Ctx *sslObj = HITLS_New(config); + if (sslObj == NULL) { + goto exception; + } + + INIT_IO_METHOD(method, type, FRAME_Write, FRAME_Read, FRAME_Ctrl); + io = BSL_UIO_New(&method); + if (io == NULL) { + goto exception; + } + + ioUserdata = FRAME_IO_CreateUserData(); + if (ioUserdata == NULL) { + goto exception; + } + + uint32_t ret = BSL_UIO_SetUserData(io, ioUserdata); + if (ret != HITLS_SUCCESS) { + goto exception; + } + + int32_t fd = 666; + // Set any fd as the value of the underlying transfer I/O + ret = BSL_UIO_Ctrl(io, BSL_UIO_SET_FD, (int32_t)sizeof(fd), &fd); + if (ret != HITLS_SUCCESS) { + goto exception; + } + BSL_UIO_SetInit(io, 1); + // must return success + ret = HITLS_SetUio(sslObj, io); + if (ret != HITLS_SUCCESS) { + goto exception; + } + linkObj->io = io; + linkObj->ssl = sslObj; + return linkObj; +exception: + FRAME_IO_FreeUserData(ioUserdata); + BSL_UIO_Free(io); + HITLS_Free(sslObj); + BSL_SAL_FREE(linkObj); + return NULL; +} + +FRAME_LinkObj *FRAME_CreateTLCPLink(HITLS_Config *config, BSL_UIO_TransportType type, bool isClient) +{ + HITLS_CFG_SetCloseCheckKeyUsage(config, false); + int32_t ret; + if (isClient) { + ret = HiTLS_X509_LoadCertAndKey(config, SM2_VERIFY_PATH, SM2_CHAIN_PATH, SM2_CLIENT_ENC_CERT_PATH, + SM2_CLIENT_SIGN_CERT_PATH, SM2_CLIENT_ENC_KEY_PATH, SM2_CLIENT_SIGN_KEY_PATH); + } else { + ret = HiTLS_X509_LoadCertAndKey(config, SM2_VERIFY_PATH, SM2_CHAIN_PATH, SM2_SERVER_ENC_CERT_PATH, + SM2_SERVER_SIGN_CERT_PATH, SM2_SERVER_ENC_KEY_PATH, SM2_SERVER_SIGN_KEY_PATH); + } + if (ret != HITLS_SUCCESS) { + return NULL; + } + + return CreateLink(config, type); +} + +// Set certificate and creating a connection +FRAME_LinkObj *FRAME_CreateLinkBase(HITLS_Config *config, BSL_UIO_TransportType type, bool setCertFlag) +{ + int32_t ret; + if (setCertFlag) { + char verifyPath[MAX_CERT_PATH_LENGTH] = {0}; + char chainPath[MAX_CERT_PATH_LENGTH] = {0}; + char certPath[MAX_CERT_PATH_LENGTH] = {0}; + char keyPath[MAX_CERT_PATH_LENGTH] = {0}; + sprintf_s(verifyPath, MAX_CERT_PATH_LENGTH, "%s:%s", ECDSA_SHA_CA_PATH, RSA_SHA_CA_PATH); + sprintf_s(chainPath, + MAX_CERT_PATH_LENGTH, + "%s:%s", + ECDSA_SHA_CHAIN_PATH, + RSA_SHA_CHAIN_PATH); + sprintf_s( + certPath, MAX_CERT_PATH_LENGTH, "%s:%s", ECDSA_SHA256_EE_PATH, RSA_SHA256_EE_PATH3); + sprintf_s(keyPath, + MAX_CERT_PATH_LENGTH, + "%s:%s", + ECDSA_SHA256_PRIV_PATH, + RSA_SHA256_PRIV_PATH3); + ret = HiTLS_X509_LoadCertAndKey(config, verifyPath, chainPath, certPath, NULL, keyPath, NULL); + if (ret != HITLS_SUCCESS) { + return NULL; + } + } + + return CreateLink(config, type); +} + +FRAME_LinkObj *FRAME_CreateLink(HITLS_Config *config, BSL_UIO_TransportType type) +{ + HITLS_CFG_SetCloseCheckKeyUsage(config, false); + return FRAME_CreateLinkBase(config, type, true); +} + +FRAME_LinkObj *FRAME_CreateLinkEx(HITLS_Config *config, BSL_UIO_TransportType type) +{ + HITLS_CFG_SetCloseCheckKeyUsage(config, false); + return FRAME_CreateLinkBase(config, type, false); +} + +FRAME_LinkObj *FRAME_CreateLinkWithCert(HITLS_Config *config, BSL_UIO_TransportType type, const FRAME_CertInfo* certInfo) +{ + HITLS_CFG_SetCloseCheckKeyUsage(config, false); + int32_t ret; + ret = HiTLS_X509_LoadCertAndKey(config, + certInfo->caFile, + certInfo->chainFile, + certInfo->endEquipmentFile, + certInfo->signFile, + certInfo->privKeyFile, + certInfo->signPrivKeyFile); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return CreateLink(config, type); +} + +void FRAME_FreeLink(FRAME_LinkObj *linkObj) +{ + if (linkObj == NULL) { + return; + } + FRAME_IO_FreeUserData(BSL_UIO_GetUserData(linkObj->io)); + // BSL_UIO_Free is automatically invoked twice in HITLS_Free + if (linkObj->io != NULL && linkObj->io->references.count >= 2) { + while (linkObj->io->references.count > 2) { + BSL_UIO_Free(linkObj->io); + } + } else { + BSL_UIO_Free(linkObj->io); + } + + HITLS_Free(linkObj->ssl); + BSL_SAL_FREE(linkObj); + return; +} + +HITLS_Ctx *FRAME_GetTlsCtx(const FRAME_LinkObj *linkObj) +{ + if (linkObj == NULL) { + return NULL; + } + return linkObj->ssl; +} diff --git a/testcode/framework/tls/frame/src/frame_link.h b/testcode/framework/tls/frame/src/frame_link.h new file mode 100644 index 00000000..a22ea53e --- /dev/null +++ b/testcode/framework/tls/frame/src/frame_link.h @@ -0,0 +1,53 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef FRAME_LINK_H +#define FRAME_LINK_H + +#include "hitls.h" +#include "bsl_uio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FRAME_LinkObj_ { + HITLS_Ctx *ssl; + BSL_UIO *io; + /* For CCS test, make TRY_RECV_FINISH stop before receiving CCS message */ + bool needStopBeforeRecvCCS; +}; + +struct FRAME_CertInfo_ { + const char* caFile; + const char* chainFile; + const char* endEquipmentFile; + const char* signFile; // used TLCP + const char* privKeyFile; + const char* signPrivKeyFile; // used TLCP +}; +#define INIT_IO_METHOD(method, tp, pfWrite, pfRead, pfCtrl) \ + do { \ + (method).type = tp; \ + (method).read = pfRead; \ + (method).write = pfWrite; \ + (method).ctrl = pfCtrl; \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif // FRAME_LINK_H diff --git a/testcode/framework/tls/frame/src/frame_msg.c b/testcode/framework/tls/frame/src/frame_msg.c new file mode 100644 index 00000000..854e8eb2 --- /dev/null +++ b/testcode/framework/tls/frame/src/frame_msg.c @@ -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. + */ + +#include "frame_msg.h" +#include "hitls_error.h" +#include "frame_tls.h" + +FRAME_Msg *FRAME_GenerateMsgFromBuffer(const FRAME_LinkObj *linkObj, const uint8_t *buffer, uint32_t len) +{ + // Check whether the const Frame_LinkObj *linkObj parameter is required. If the parameter is not required, delete it + (void)linkObj; + (void)buffer; + (void)len; + return NULL; +} + +/** +* @ingroup Obtain a message from the I/O receiving buffer of the connection +* +* @return Return the CTX object of the TLS +*/ +int32_t FRAME_GetLinkRecMsg(FRAME_LinkObj *link, uint8_t *buffer, uint32_t len, uint32_t *msgLen) +{ + (void)link; + (void)buffer; + (void)len; + (void)msgLen; + return HITLS_SUCCESS; +} + +/** +* @ingroup Obtain a message from the I/O sending buffer of the connection +* +* @return Return the CTX object of the TLS +*/ +int32_t FRAME_GetLinkSndMsg(FRAME_LinkObj *link, uint8_t *buffer, uint32_t len, uint32_t *msgLen) +{ + (void)link; + (void)buffer; + (void)len; + (void)msgLen; + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/testcode/framework/tls/func_wrapper/include/rec_wrapper.h b/testcode/framework/tls/func_wrapper/include/rec_wrapper.h new file mode 100644 index 00000000..34d12666 --- /dev/null +++ b/testcode/framework/tls/func_wrapper/include/rec_wrapper.h @@ -0,0 +1,49 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef REC_WRAPPER_H +#define REC_WRAPPER_H +#include "rec.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief REC_read, REC_write read/write callback + * + * @param ctx [IN] TLS context + * @param buf [IN/OUT] Read/write buffer + * @param bufLen [IN/OUT] Reads and writes len bytes + * @param bufSize [IN] Maximum buffer size + * @param userData [IN/OUT] User-defined data + */ +typedef void (*WrapperFunc)(TLS_Ctx *ctx, uint8_t *buf, uint32_t *bufLen, uint32_t bufSize, void* userData); + +typedef struct { + HITLS_HandshakeState ctrlState; + REC_Type recordType; + bool isRecRead; + void *userData; + WrapperFunc func; +} RecWrapper; + +void RegisterWrapper(RecWrapper wrapper); +void ClearWrapper(void); + +#ifdef __cplusplus +} +#endif + +#endif // REC_WRAPPER_H diff --git a/testcode/framework/tls/func_wrapper/src/rec_wrapper.c b/testcode/framework/tls/func_wrapper/src/rec_wrapper.c new file mode 100644 index 00000000..03e9e047 --- /dev/null +++ b/testcode/framework/tls/func_wrapper/src/rec_wrapper.c @@ -0,0 +1,72 @@ +/* + * 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 "securec.h" +#include "hs_ctx.h" +#include "rec_wrapper.h" + +#define MAX_BUF 16384 +static RecWrapper g_recWrapper; +static bool g_enableWrapper; +static __thread uint8_t g_locBuffer[MAX_BUF] = { 0 }; + +void RegisterWrapper(RecWrapper wrapper) +{ + g_enableWrapper = true; + g_recWrapper = wrapper; +} + +void ClearWrapper(void) +{ + g_enableWrapper = false; +} + +extern int32_t __real_REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num); + +extern int32_t __real_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num); + +extern int32_t __wrap_REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num) +{ + int32_t ret = __real_REC_Read(ctx, recordType, data, readLen, num); + if (!g_enableWrapper || ret != 0 || !g_recWrapper.isRecRead || g_recWrapper.recordType != recordType) { + return ret; + } + if (g_recWrapper.recordType == REC_TYPE_HANDSHAKE && ctx->hsCtx->state != g_recWrapper.ctrlState) { + return ret; + } + g_recWrapper.func(ctx, data, readLen, num, g_recWrapper.userData); + return ret; +} + +extern int32_t __wrap_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num) +{ + // Length that can be manipulated in wrapper + uint32_t manipulateLen = num; + if (!g_enableWrapper || g_recWrapper.isRecRead || g_recWrapper.recordType != recordType) { + return __real_REC_Write(ctx, recordType, data, manipulateLen); + } + if (g_recWrapper.recordType == REC_TYPE_HANDSHAKE && ctx->hsCtx->state != g_recWrapper.ctrlState) { + return __real_REC_Write(ctx, recordType, data, manipulateLen); + } + (void)memcpy_s(g_locBuffer, MAX_BUF, data, num); + // The value of manipulateLen can be greater than or smaller than num + g_recWrapper.func(ctx, g_locBuffer, &manipulateLen, MAX_BUF, g_recWrapper.userData); + if (ctx->hsCtx->bufferLen < manipulateLen) { + exit(-1); + } + (void)memcpy_s(ctx->hsCtx->msgBuf, ctx->hsCtx->bufferLen, g_locBuffer, manipulateLen); + ctx->hsCtx->msgLen = manipulateLen; + return __real_REC_Write(ctx, recordType, g_locBuffer, manipulateLen); +} \ No newline at end of file diff --git a/testcode/framework/tls/include/frame_msg.h b/testcode/framework/tls/include/frame_msg.h new file mode 100644 index 00000000..6fe150b8 --- /dev/null +++ b/testcode/framework/tls/include/frame_msg.h @@ -0,0 +1,625 @@ +/* + * 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 FRAME_MSG_H +#define FRAME_MSG_H + +#include +#include "hs_msg.h" +#include "rec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to determine the field status during packing */ +typedef enum { + /* field is missing. If this state is set, the field will not be packed into the buffer during packing */ + MISSING_FIELD = 0, + /* field initial status. The field status in the parsed msg structure is filled with the value. */ + INITIAL_FIELD, + /* Specifies the value of the field. If the field content is modified, set the status to the value. */ + ASSIGNED_FIELD, + /* Repeat the field. During the packing, the field will be packed again */ + DUPLICATE_FIELD, + /* Only one byte length is packed and used to construct abnormal messages. + It is used for two or more bytes of fields (such as the cipher suite length). */ + SET_LEN_TO_ONE_BYTE, +} FieldState; + +// uint64_t data with status +typedef struct { + FieldState state; /* Field state */ + uint64_t data; /* Content */ +} FRAME_Integer; + +// uint8_t data with status +typedef struct { + FieldState state; /* Field state */ + uint32_t size; /* Number of data records */ + uint8_t *data; /* Content */ +} FRAME_Array8; + +// uint16_t data with status +typedef struct { + FieldState state; /* Field state */ + uint32_t size; /* Number of data records */ + uint16_t *data; /* Content */ +} FRAME_Array16; + +typedef struct { + FieldState exState; /* extension Field state */ + FRAME_Integer exType; /* extension type */ + FRAME_Integer exLen; /* Full length of extension */ + FRAME_Integer exDataLen; /* Length of extension content */ + FRAME_Array8 exData; /* extension content */ +} FRAME_HsExtArray8; + +// The handshake extension with state carries a variable-length array with uint16_t +// such as the signature algorithm extension +typedef struct { + FieldState exState; /* extension Field state */ + FRAME_Integer exType; /* extension type */ + FRAME_Integer exLen; /* Full length of extension */ + FRAME_Integer exDataLen; /* Length of extension content */ + FRAME_Array16 exData; /* extension content */ +} FRAME_HsExtArray16; + +typedef struct { + FieldState state; /* Field state */ + FRAME_Integer group; /* group */ + FRAME_Integer keyExchangeLen; /* key exchange size */ + FRAME_Array8 keyExchange; +} FRAME_HsKeyShareEntry; + +typedef struct { + FieldState state; /* Field state */ + uint32_t size; /* Number of entries */ + FRAME_HsKeyShareEntry *data; /* key shareContent */ +} FRAME_HsArrayKeyShare; + +typedef struct { + FieldState exState; /* extension Field state */ + FRAME_Integer exType; /* extension type */ + FRAME_Integer exLen; /* Full length of extension */ + FRAME_Integer exKeyShareLen; /* keyshare Array length */ + FRAME_HsArrayKeyShare exKeyShares; /* keyshare array content */ +} FRAME_HsExtKeyShare; + +typedef struct { + FieldState state; /* Field state */ + FRAME_Integer identityLen; + FRAME_Array8 identity; + FRAME_Integer obfuscatedTicketAge; +} FRAME_HsPskIdentity; + +typedef struct { + FieldState state; /* Field state */ + uint32_t size; /* Number of identities */ + FRAME_HsPskIdentity *data; /* identity Content */ +} FRAME_HsArrayPskIdentity; + +typedef struct { + FieldState state; /* Field state */ + FRAME_Integer binderLen; + FRAME_Array8 binder; +} FRAME_HsPskBinder; + +typedef struct { + FieldState state; /* Field state */ + uint32_t size; /* Number of identities */ + FRAME_HsPskBinder *data; /* identity Content */ +} FRAME_HsArrayPskBinder; + +typedef struct { + FieldState exState; /* extension Field state */ + FRAME_Integer exType; /* extension type */ + FRAME_Integer exLen; /* Full length of extension */ + FRAME_Integer identitySize; + FRAME_HsArrayPskIdentity identities; + FRAME_Integer binderSize; + FRAME_HsArrayPskBinder binders; +} FRAME_HsExtOfferedPsks; + +typedef struct { + FRAME_Integer version; /* Version number */ + FRAME_Array8 randomValue; /* Random number */ + FRAME_Integer sessionIdSize; /* session ID length */ + FRAME_Array8 sessionId; /* session ID */ + FRAME_Integer cookiedLen; /* Cookie length (for DTLS) */ + FRAME_Array8 cookie; /* cookie(for DTLS) */ + FRAME_Integer cipherSuitesSize; /* cipher suite length */ + FRAME_Array16 cipherSuites; /* cipher suite */ + FRAME_Integer compressionMethodsLen; /* compression method length */ + FRAME_Array8 compressionMethods; /* compression method */ + + FieldState extensionState; /* Indicates whether the extension is packed */ + FRAME_Integer extensionLen; /* Total length of the extension */ + FRAME_HsExtArray8 pointFormats; + FRAME_HsExtArray16 supportedGroups; + FRAME_HsExtArray16 signatureAlgorithms; + FRAME_HsExtArray8 extendedMasterSecret; + FRAME_HsExtArray8 secRenego; /* security renegotiation */ + FRAME_HsExtArray8 sessionTicket; + FRAME_HsExtArray8 serverName; /* sni */ + FRAME_HsExtArray8 alpn; /* alpn */ + FRAME_HsExtArray8 tls13Cookie; /* tls1.3 cookie */ + FRAME_HsExtKeyShare keyshares; /* tls1.3 key share */ + FRAME_HsExtArray8 pskModes; /* tls1.3 psk exchange mode */ + FRAME_HsExtArray16 supportedVersion; /* tls1.3 support version */ + FRAME_HsExtOfferedPsks psks; /* tls1.3 psk */ +} FRAME_ClientHelloMsg; + +typedef struct { + FieldState exState; /* extension Field state */ + FRAME_Integer exType; /* extension type */ + FRAME_Integer exLen; /* Full length of extension */ + FRAME_Integer data; /* extension content */ +} FRAME_HsExtUint16; + +typedef struct { + FieldState exState; /* extension Field state */ + FRAME_Integer exType; /* extension type */ + FRAME_Integer exLen; /* Full length of extension */ + FRAME_HsKeyShareEntry data; /* extension content */ +} FRAME_HsExtServerKeyShare; + +typedef struct { + FRAME_Integer version; /* Version number */ + FRAME_Array8 randomValue; /* Random number */ + FRAME_Integer sessionIdSize; /* session ID length */ + FRAME_Array8 sessionId; /* session ID */ + FRAME_Integer cipherSuite; + FRAME_Integer compressionMethod; + FRAME_Integer extensionLen; /* Full length of the extended field */ + FRAME_HsExtArray8 pointFormats; + FRAME_HsExtArray8 extendedMasterSecret; + FRAME_HsExtArray8 secRenego; /* security renegotiation */ + FRAME_HsExtArray8 sessionTicket; /* sessionTicket */ + FRAME_HsExtArray8 serverName; /* sni */ + FRAME_HsExtArray8 alpn; /* alpn */ + FRAME_HsExtUint16 supportedVersion; /* tls1.3 supported version */ + FRAME_HsExtServerKeyShare keyShare; /* tls1.3 key share */ + FRAME_HsExtUint16 pskSelectedIdentity; /* tls1.3 psk extension */ + FRAME_HsExtArray8 tls13Cookie; /* tls1.3 cookie */ +} FRAME_ServerHelloMsg; + +typedef struct { + FRAME_Array8 extra; /* server hello done is a null message. This field is used to construct abnormal messages */ +} FRAME_ServerHelloDoneMsg; + +typedef struct FrameCertItem_ { + FieldState state; /* Certificate Field state */ + FRAME_Integer certLen; /* Certificate length */ + FRAME_Array8 cert; /* Certificate Content */ + struct FrameCertItem_ *next; +} FrameCertItem; + +typedef struct { + FRAME_Integer certsLen; /* Certificate total length */ + FrameCertItem *certItem; /* Certificate */ + FRAME_Array8 certificateReqCtx; /* For TLS 1.3 */ + FRAME_Integer certificateReqCtxSize; /* For TLS 1.3 */ +} FRAME_CertificateMsg; + +typedef struct { + FRAME_Integer curveType; /* Curve type */ + FRAME_Integer namedcurve; /* Named curve */ + FRAME_Integer pubKeySize; /* ecdh public key size */ + FRAME_Array8 pubKey; /* ecdh public key content */ + FRAME_Integer signAlgorithm; /* Signature hash algorithm, for TLS1.2 and DTLS1.2 */ + FRAME_Integer signSize; /* Signature length */ + FRAME_Array8 signData; /* Signature Content */ +} FRAME_ServerEcdh; + +typedef struct { + FRAME_Integer plen; + FRAME_Array8 p; + FRAME_Integer glen; + FRAME_Array8 g; + FRAME_Integer pubKeyLen; /* dh public key */ + FRAME_Array8 pubKey; /* dH public key content */ + FRAME_Integer signAlgorithm; /* Signature hash algorithm, for TLS1.2 and DTLS1.2 */ + FRAME_Integer signSize; /* Signature length */ + FRAME_Array8 signData; /* Signature content */ +} FRAME_ServerDh; + +typedef struct { + union { + FRAME_ServerEcdh ecdh; + FRAME_ServerDh dh; + } keyEx; +} FRAME_ServerKeyExchangeMsg; + +typedef struct { + FRAME_Integer pubKeySize; /* Key exchange data length */ + FRAME_Array8 pubKey; /* Key exchange data */ +} FRAME_ClientKeyExchangeMsg; + +typedef struct { + FieldState state; /* Field state */ + FRAME_Integer certTypesSize; /* certificate type length */ + FRAME_Array8 certTypes; /* Certificate type list */ + FRAME_Integer signatureAlgorithmsSize; /* signature algorithm length */ + FRAME_Array16 signatureAlgorithms; /* signature algorithm list */ + FRAME_Integer reserved; /* Four-byte alignment */ + FRAME_Integer distinguishedNamesSize; /* DN length */ + FRAME_Array8 distinguishedNames; /* DN */ + FRAME_Array8 certificateReqCtx; /* For TLS 1.3 */ + FRAME_Integer certificateReqCtxSize; /* For TLS 1.3 */ + FRAME_Integer exMsgLen; +} FRAME_CertificateRequestMsg; + +/* Used to transmit certificate verification packets. */ +typedef struct { + FRAME_Integer signHashAlg; /* Signature hash algorithm, used for TLS1.2 and DTLS1.2 */ + FRAME_Integer signSize; /* Length of the signature data */ + FRAME_Array8 sign; /* Signature data */ +} FRAME_CertificateVerifyMsg; + +typedef struct { + FRAME_Integer ticketLifetime; + FRAME_Integer ticketAgeAdd; + FRAME_Integer ticketNonceSize; + FRAME_Array8 ticketNonce; + FRAME_Integer ticketSize; + FRAME_Array8 ticket; + FRAME_Integer extensionLen; /* Total length of the extension */ +} FRAME_NewSessionTicketMsg; + +/* Transmit the Finish message */ +typedef struct { + FRAME_Array8 verifyData; /* verify data Content */ +} FRAME_FinishedMsg; + +typedef struct { + FRAME_Integer type; /* Handshake type */ + FRAME_Integer length; /* Length of the handshake message */ + /* Sequence number of DTLS handshake messages. Increases by 1 each time a new handshake message is sent. + *Does not increase for retransmission */ + FRAME_Integer sequence; + FRAME_Integer fragmentOffset; /* Fragment offset of DTLS handshake message */ + FRAME_Integer fragmentLength; /* DTLS Handshake message Fragment Length */ + union { + FRAME_ClientHelloMsg clientHello; + FRAME_ServerHelloMsg serverHello; + FRAME_CertificateMsg certificate; + FRAME_ServerKeyExchangeMsg serverKeyExchange; + FRAME_CertificateRequestMsg certificateReq; + FRAME_ServerHelloDoneMsg serverHelloDone; + FRAME_ClientKeyExchangeMsg clientKeyExchange; + FRAME_CertificateVerifyMsg certificateVerify; + FRAME_NewSessionTicketMsg newSessionTicket; + FRAME_FinishedMsg finished; + } body; +} FRAME_HsMsg; + +typedef struct { + uint8_t level; /* To be deleted. The member is not processed because some code uses it */ + uint8_t description; /* To be deleted. The member is not processed because some code uses it */ + FRAME_Integer alertLevel; /* Alert level: See ALERT_Level */ + FRAME_Integer alertDescription; /* Alert description: See ALERT_Description */ + FRAME_Array8 extra; /* This field is used to construct abnormal messages */ +} FRAME_AlertMsg; + +typedef struct { + uint8_t type; /* To be deleted. The member is not processed because some code uses it */ + FRAME_Integer ccsType; /* ccs type */ + FRAME_Array8 extra; /* This field is used to construct abnormal messages */ +} FRAME_CcsMsg; + +typedef struct { + char *buffer; /* To be deleted. The member is not processed because some code uses it */ + uint32_t len; /* To be deleted. The member is not processed because some code uses it */ + FRAME_Array8 appData; /* app data */ +} FRAME_AppMsg; + +typedef struct { + uint8_t type; /* To be deleted. The member is not processed because some code uses it */ + uint8_t reverse; /* To be deleted. The member is not processed because some code uses it */ + uint16_t version; /* To be deleted. The member is not processed because some code uses it */ + uint16_t bodyLen; /* To be deleted. The member is not processed because some code uses it */ + uint64_t epochSeq; /* To be deleted. The member is not processed because some code uses it */ + + FRAME_Integer recType; /* record the message type */ + FRAME_Integer recVersion; /* record version */ + FRAME_Integer epoch; /* Counter value that increases each time the password status changes. + This counter is used by DTLS */ + FRAME_Integer sequence; /* Record message sequence number, for DTLS */ + FRAME_Integer length; /* Length of the record message */ + union { + HS_Msg handshakeMsg; /* To be deleted. The member is not processed because some code uses it */ + FRAME_HsMsg hsMsg; + FRAME_AlertMsg alertMsg; + FRAME_CcsMsg ccsMsg; + FRAME_AppMsg appMsg; + } body; + + uint8_t *buffer; /* To be deleted. The member is not processed because some code uses it */ + uint32_t len; /* To be deleted. The member is not processed because some code uses it */ +} FRAME_Msg; + +/* Used to transfer the message type. The framework packs and parses the corresponding message based on the field value + * of this structure */ +typedef struct { + uint16_t versionType; + /* To ensure that the memory can be released normally, a value is assigned to the member during parsing */ + REC_Type recordType; + /* To ensure that the memory can be released normally, a value is assigned to the member during parsing */ + HS_MsgType handshakeType; + HITLS_KeyExchAlgo keyExType; +} FRAME_Type; + +/** + * @brief Generate a TLS record byte stream based on the specified parameter of frameType + * and the field content of the msg structure and save the stream to the buffer + + * @param frameType [IN] Specified packing parameters + * @param msg [IN] Message structure + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Input buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_PackMsg(FRAME_Type *frameType, const FRAME_Msg *msg, uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Generate a TLS record body byte stream based on the specified parameter of frameType + * and the field content of the msg structure and save the byte stream to the buffer. + * + * @param frameType [IN] Specified packing parameters + * @param msg [IN] Message structure + * @param buffer [OUT] Returned handshake message + * @param bufLen [IN] Input buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_PackRecordBody(FRAME_Type *frameType, const FRAME_Msg *msg, + uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Parse the MSG structure based on the specified parameter of frameType and the TLS record byte stream. + * Only the record message header is parsed + * + * @param frameType [IN] Specified parsing parameter, mainly versionType + * @param buffer [IN] TLS record byte stream + * @param bufLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param parseLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseMsgHeader(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief parse TLS record header + * + * @param buffer [IN] TLS record byte stream + * @param bufferLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param headerLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseTLSRecordHeader(const uint8_t *buffer, uint32_t bufferLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief Parse the body of the TLS non-handshake record + * + * @param buffer [IN] TLS record byte stream + * @param bufferLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param headerLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseTLSNonHsRecordBody(const uint8_t *buffer, uint32_t bufferLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief Parse the TLS non-handshake record + * + * @param buffer [IN] TLS record byte stream + * @param bufferLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param headerLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseTLSNonHsRecord(const uint8_t *buffer, uint32_t bufferLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief Parse the record of the handshake type + * + * @param buffer [IN] TLS record byte stream + * @param bufferLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param headerLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseHsRecord(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufferLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief Parse the MSG structure based on the specified parameter of frameType and the TLS record byte stream. + * Only the record message body is parsed + * + * @attention Invoke the Frame_ParseMsgHeader interface to parse the message header + * + * @param frameType [IN] Specified parsing parameters, mainly versionType and keyExType + * @param buffer [IN] TLS record byte stream + * @param bufLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param parseLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseMsgBody(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief Parse the message into the msg structure based on the specified parameter of frameType and + * the TLS record byte stream + * + * @param frameType [IN] Specified parsing parameters, mainly versionType and keyExType + * @param buffer [IN] TLS record byte stream + * @param bufLen [IN] Input buffer size + * @param msg [OUT] Parsed Message structure + * @param parseLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ParseMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_Msg *msg, uint32_t *parseLen); + +/** + * @brief Clear the memory allocated during parsing + * + * @param frameType [IN] Specified parsing parameters, mainly versionType and keyExType + * @param msg [IN] Message structure + */ +void FRAME_CleanMsg(FRAME_Type *frameType, FRAME_Msg *msg); + +/** + * @brief Clear the memory allocated during parsing + * + * @param recType [IN] Specified record type + * @param msg [IN] Message structure + */ +void FRAME_CleanNonHsRecord(REC_Type recType, FRAME_Msg *msg); + +/** + * @brief Obtain a structure of a specified message type + * + * @attention This interface does not set the callback function. User need to set the callback interface first + * This interface obtains only the HANDSHAKE,Change_CIPHER_SPEC, and ALERT messages + * The existing framework does not support parsing of encrypted finished messages. + * Therefore, the finished messages cannot be obtained. + * + * @param frameType [IN] Specified message parameters + * @param msg [OUT] Returned Message structure + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_GetDefaultMsg(FRAME_Type *frameType, FRAME_Msg *msg); + +/** + * @brief Modify a message field + * This method is used to modify the contents of integer fields in a message, such as the message type, + * version number, and field length + * + * @param data [IN] Data content + * @param frameInteger [IN/OUT] IN original field; OUT New field + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ModifyMsgInteger(const uint64_t data, FRAME_Integer *frameInteger); + +/** + * @brief Modify the message field content. User can increase or decrease the length of the message field and modify + * the field content. + * (This implementation performs deep copy of the data content.) + * This method is used to modify the content of the uint8_t array field in a message, such as the session ID, + * cookie, and signature data + * + * @param data [IN] Data content + * @param dataLen [IN] Number of data records + * @param frameArray [IN/OUT] IN original field; OUT New field + * @param frameArrayLen [IN/OUT] IN Original field length; Length of the new field in the OUT field. This parameter + * can be none + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ModifyMsgArray8(const uint8_t *data, uint32_t dataLen, + FRAME_Array8 *frameArray, FRAME_Integer *frameArrayLen); + +/** + * @brief Retain the original handshake message field content and add a string of data data to the end of the data. + * (This implementation performs deep copy of the data content.) + * This method is used to modify the content of the uint8_t array field in a message, such as the session ID, + * cookie, and signature data. + * + * @param data [IN] Data content + * @param dataLen [IN] Number of data records + * @param frameArray [IN/OUT] IN original field; OUT New field + * @param frameArrayLen [IN/OUT] IN Original field length; Length of the new field in the OUT field. This parameter + * can be none + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_AppendMsgArray8(const uint8_t *data, uint32_t dataLen, + FRAME_Array8 *frameArray, FRAME_Integer *frameArrayLen); + +/** + * @brief Modify the message field content. User can increase or decrease the length of the message field and modify + * the field content. + * (This implementation performs deep copy of the data content.) + * This method is used to modify the uint16_t array field in a message, for example, cipher suite and support + * group extension + * + * @param data [IN] Data content + * @param dataLen [IN] Number of data records + * @param frameArray [IN/OUT] IN original field; OUT New field + * @param frameArrayLen [IN/OUT] IN Original field length; Length of the new field in the OUT field. This parameter + * can be none + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_ModifyMsgArray16(const uint16_t *data, uint32_t dataLen, + FRAME_Array16 *frameArray, FRAME_Integer *frameArrayLen); + +/** + * @brief Retain the original handshake message field content and add a string of data data to the end of the data. + * (This implementation performs deep copy of the data content.) + * This method is used to modify the uint16_t array field in a message, for example, the cipher suite and + * support group extension + * + * @param data [IN] Data content + * @param dataLen [IN] Number of data records + * @param frameArray [IN/OUT] IN original field; OUT New field + * @param frameArrayLen [IN/OUT] IN Original field length; Length of the new field in the OUT field. This parameter + * can be none + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t FRAME_AppendMsgArray16(const uint16_t *data, uint32_t dataLen, + FRAME_Array16 *frameArray, FRAME_Integer *frameArrayLen); + +#ifdef __cplusplus +} +#endif + +#endif // FRAME_MSG_H \ No newline at end of file diff --git a/testcode/framework/tls/include/frame_tls.h b/testcode/framework/tls/include/frame_tls.h new file mode 100644 index 00000000..0fa05e2c --- /dev/null +++ b/testcode/framework/tls/include/frame_tls.h @@ -0,0 +1,150 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef FRAME_TLS_H +#define FRAME_TLS_H + +#include "bsl_uio.h" +#include "hs_ctx.h" +#include "frame_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FRAME_LinkObj_ FRAME_LinkObj; + +typedef struct FRAME_CertInfo_ FRAME_CertInfo; + +typedef struct SSL_LINK_OBJ_ SSL_LINK_OBJ; + +HITLS_Ctx *FRAME_CreateDefaultDtlsObj(void); + +/** +* @brief Load the certificate to the connection configuration context resource. +* +* @return If the value 0 is returned, the certificate is loaded successfully. +* Otherwise, the certificate fails to be loaded +*/ +int32_t FRAME_LoadCertToConfig(HITLS_Config *config, const char *verifyCert, const char *chainCert, const char *eeCert, + const char *prvKey); + +/** +* @brief Create a TLCP connection. + This interface loads the certificate, applies for SSL CTX, and creates the underlying UIO +* +* @return Return the connection object, which can be used by the test framework to perform operations +*/ +FRAME_LinkObj *FRAME_CreateTLCPLink(HITLS_Config *config, BSL_UIO_TransportType type, bool isClient); + +/** +* @brief Create an SSL connection. This interface will complete the SSL CTX application, + bottom-layer UIO creation, and load the default certificate +* +* @return Return the connection object, which can be used by the test framework to perform operations +*/ +FRAME_LinkObj *FRAME_CreateLink(HITLS_Config *config, BSL_UIO_TransportType type); + +// This interface is used to create an SSL connection. +// The SSL CTX application and bottom-layer UIO creation are completed. The default certificate is not loaded. +FRAME_LinkObj *FRAME_CreateLinkEx(HITLS_Config *config, BSL_UIO_TransportType type); + +FRAME_LinkObj *FRAME_CreateLinkWithCert( + HITLS_Config *config, BSL_UIO_TransportType type, const FRAME_CertInfo *certInfo); + +/** +* @brief Releases an SSL connection, which corresponds to Frame_CreateLink +* +* @return +*/ +void FRAME_FreeLink(FRAME_LinkObj *linkObj); + +/** +* @brief Obtain the TLS ctx from the Frame_LinkObj to facilitate the test of HiTLS APIs because HiTLS APIs use +* HITLS_Ctx as the input parameter. +* Do not call HiTLS_Free to release the return values of this API. +* The values will be released in the Frame_FreeLink. +* +* @return Return the CTX object of the TLS +*/ +HITLS_Ctx *FRAME_GetTlsCtx(const FRAME_LinkObj *linkObj); + +/* +* @brief Simulate link establishment or simulate an SSL link in a certain state. +* For example, if state is TRY_RECV_SERVER_HELLO, the client is ready to receive the SERVER Hello message, +* and The server link is just sent SERVER_HELLO. +* +* @return If the operation is successful, HITLS_SUCCESS is returned. +*/ +int32_t FRAME_CreateConnection(FRAME_LinkObj *client, FRAME_LinkObj *server, bool isClient, HITLS_HandshakeState state); + +/** + * @brief Simulate renegotiation + + * @attention Internally invokes HITLS_Write and HITLS_Read to perform renegotiation. + * Ensure that linkA is the initiator of the renegotiation request and + * linkB is the receiver of the renegotiation request + * + * @param linkA [IN] Initiator of the renegotiation request + * @param linkB [IN] Recipient of the renegotiation request + * + * @return If the operation is successful, HITLS_SUCCESS is returned + */ +int32_t FRAME_CreateRenegotiation(FRAME_LinkObj *linkA, FRAME_LinkObj *linkB); + +/** +* @brief Obtain a message from the I/O receiving buffer of the connection +* +* @return If the operation is successful, HITLS_SUCCESS is returned +*/ +int32_t FRAME_GetLinkRecMsg(FRAME_LinkObj *link, uint8_t *buffer, uint32_t len, uint32_t *msgLen); + +/** +* @brief Obtain a message from the I/O sending buffer of the connection. +* +* @return If the operation is successful, HITLS_SUCCESS is returned. +*/ +int32_t FRAME_GetLinkSndMsg(FRAME_LinkObj *link, uint8_t *buffer, uint32_t len, uint32_t *msgLen); + +/** +* @brief Generate a framework message based on the content in the message buffer +* +* @return Return the Constructed Frame_Msg object +*/ +FRAME_Msg *FRAME_GenerateMsgFromBuffer(const FRAME_LinkObj *linkObj, const uint8_t *buffer, uint32_t len); + +/** +* @brief Send data from connection A to connection B +* +* @return If the operation is successful, HITLS_SUCCESS is returned +*/ +int32_t FRAME_TrasferMsgBetweenLink(FRAME_LinkObj *linkA, FRAME_LinkObj *linkB); + +/** +* @brief Initialize the framework +*/ + +void FRAME_Init(void); + +/** +* @brief Deinitialize the framework +*/ +void FRAME_DeInit(void); + +#ifdef __cplusplus +} +#endif + +#endif // FRAME_TLS_H diff --git a/testcode/framework/tls/include/hlt.h b/testcode/framework/tls/include/hlt.h new file mode 100644 index 00000000..6cc9c428 --- /dev/null +++ b/testcode/framework/tls/include/hlt.h @@ -0,0 +1,171 @@ +/* + * 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 HLT_H +#define HLT_H + +#include +#include "hlt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +// Create a process +HLT_Process* InitSrcProcess(TLS_TYPE tlsType, char* srcDomainPath); +HLT_Process* InitPeerProcess(TLS_TYPE tlsType, HILT_TransportType connType, int port, bool isBlock); +#define HLT_InitLocalProcess(tlsType) InitSrcProcess(tlsType, __FILE__) +#define HLT_CreateRemoteProcess(tlsType) InitPeerProcess(tlsType, NONE_TYPE, 0, 0) +#define HLT_LinkRemoteProcess(tlsType, connType, port, isBlock) InitPeerProcess(tlsType, connType, port, isBlock) + +// Clear all process resources +void HLT_FreeAllProcess(void); +int HLT_FreeResFormSsl(const void *ssl); + +// Create a local data connection +HLT_FD HLT_CreateDataChannel(HLT_Process* process1, HLT_Process* process2, DataChannelParam channelParam); +int HLT_DataChannelConnect(DataChannelParam* dstChannelParam); +pthread_t HLT_DataChannelAccept(DataChannelParam* channelParam); +void HLT_CloseFd(int fd, int linkType); + +// Interface for setting connection information +int HLT_SetVersion(HLT_Ctx_Config* ctxConfig, uint16_t minVersion, uint16_t maxVersion); +int HLT_SetSecurityLevel(HLT_Ctx_Config *ctxConfig, int32_t level); +int HLT_SetRenegotiationSupport(HLT_Ctx_Config* ctxConfig, bool support); +int HLT_SetNoSecRenegotiationCb(HLT_Ctx_Config *ctxConfig, char* NoSecRenegotiationCb); +int HLT_SetFlightTransmitSwitch(HLT_Ctx_Config *ctxConfig, bool support); +int HLT_SetClientVerifySupport(HLT_Ctx_Config* ctxConfig, bool support); +int HLT_SetNoClientCertSupport(HLT_Ctx_Config* ctxConfig, bool support); +int HLT_SetPostHandshakeAuth(HLT_Ctx_Config *ctxConfig, bool support); +int HLT_SetExtenedMasterSecretSupport(HLT_Ctx_Config* ctxConfig, bool support); +int HLT_SetCipherSuites(HLT_Ctx_Config* ctxConfig, const char* cipherSuites); +int HLT_SetTls13CipherSuites(HLT_Ctx_Config *ctxConfig, const char *cipherSuites); +int HLT_SetEcPointFormats(HLT_Ctx_Config* ctxConfig, const char* pointFormat); +int HLT_SetGroups(HLT_Ctx_Config* ctxConfig, const char* groups); +int HLT_SetSignature(HLT_Ctx_Config* ctxConfig, const char* signature); +int HLT_SetCaCertPath(HLT_Ctx_Config* ctxConfig, const char* caCertPath); +int HLT_SetChainCertPath(HLT_Ctx_Config* ctxConfig, const char* chainCertPath); +int HLT_SetEeCertPath(HLT_Ctx_Config* ctxConfig, const char* eeCertPath); +int HLT_SetPrivKeyPath(HLT_Ctx_Config* ctxConfig, const char* privKeyPath); +int HLT_SetPassword(HLT_Ctx_Config* ctxConfig, const char* password); +void HLT_SetCertPath(HLT_Ctx_Config* ctxConfig, const char *caPath, + const char *chainPath, const char *EePath, const char *PrivPath, const char *signCert, const char *signPrivKey); + +int HLT_SetPsk(HLT_Ctx_Config *ctxConfig, char *psk); +int HLT_SetKeyExchMode(HLT_Ctx_Config *config, uint32_t mode); +int HLT_SetTicketKeyCb(HLT_Ctx_Config *ctxConfig, char *ticketKeyCbName); + +int HLT_SetServerName(HLT_Ctx_Config *ctxConfig, const char *serverName); +int HLT_SetServerNameArg(HLT_Ctx_Config *ctxConfig, char *arg); +int HLT_SetServerNameCb(HLT_Ctx_Config *ctxConfig, char *sniCbName); + +int HLT_SetAlpnProtos(HLT_Ctx_Config *ctxConfig, const char *alpnProtos); +int HLT_SetAlpnProtosSelectCb(HLT_Ctx_Config *ctxConfig, char *callback, char *userData); + +// Interface for setting abnormal message operations +int HLT_SetFrameHandle(HLT_FrameHandle *frameHandle); +void HLT_CleanFrameHandle(void); +int HLT_FreeResFromSsl(const void *ssl); + +// General initialization interface +int HLT_LibraryInit(TLS_TYPE tlsType); + +// The local process invokes TLS functions +HLT_Tls_Res* HLT_ProcessTlsInit(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig); +void* HLT_TlsNewCtx(TLS_VERSION tlsVersion); +HLT_Ctx_Config* HLT_NewCtxConfig(char* setFile, const char* key); +HLT_Ctx_Config* HLT_NewCtxConfigTLCP(char *setFile, const char *key, bool isClient); +int HLT_TlsSetCtx(void* ctx, HLT_Ctx_Config* config); +HLT_Ssl_Config* HLT_NewSslConfig(char* setFile); +void* HLT_TlsNewSsl(void* ctx); +int HLT_TlsSetSsl(void* ssl, HLT_Ssl_Config* config); +unsigned long int HLT_TlsListen(void *ssl); +unsigned long int HLT_TlsAccept(void* ssl); +int HLT_TlsListenBlock(void* ssl); +int HLT_TlsAcceptBlock(void* ssl); +int HLT_GetTlsAcceptResultFromId(unsigned long int threadId); +int HLT_GetTlsAcceptResult(HLT_Tls_Res* tlsRes); +int HLT_TlsConnect(void* ssl); +int HLT_TlsRead(void* ssl, uint8_t *data, uint32_t bufSize, uint32_t *readLen); +int HLT_TlsWrite(void* ssl, uint8_t *data, uint32_t dataLen); +int HLT_TlsRegCallback(TlsCallbackType type); +int HLT_TlsRenegotiate(void *ssl); +int HLT_TlsVerifyClientPostHandshake(void *ssl); +int HLT_TlsClose(void *ssl); +int HLT_TlsSetSession(void *ssl, void *session); +int HLT_TlsSessionReused(void *ssl); +void *HLT_TlsGet1Session(void *ssl); +int32_t HLT_SetSessionCacheMode(HLT_Ctx_Config* config, HITLS_SESS_CACHE_MODE mode); +int32_t HLT_SetSessionTicketSupport(HLT_Ctx_Config* config, bool issupport); +int HLT_TlsSessionHasTicket(void *session); +int HLT_TlsSessionIsResumable(void *session); +void HLT_TlsFreeSession(void *session); + +// The RPC controls the remote process to invoke TLS functions +int HLT_RpcTlsNewCtx(HLT_Process* peerProcess, TLS_VERSION tlsVersion, bool isClient); +int HLT_RpcTlsSetCtx(HLT_Process* peerProcess, int ctxId, HLT_Ctx_Config* config); +int HLT_RpcTlsNewSsl(HLT_Process* peerProcess, int ctxId); +int HLT_RpcTlsSetSsl(HLT_Process* peerProcess, int sslId, HLT_Ssl_Config* config); +int HLT_RpcTlsListen(HLT_Process* peerProcess, int sslId); +int HLT_RpcTlsAccept(HLT_Process* peerProcess, int sslId); +int HLT_RpcGetTlsListenResult(int acceptId); +int HLT_RpcGetTlsAcceptResult(int acceptId); +int HLT_RpcTlsConnect(HLT_Process* peerProcess, int sslId); +int HLT_RpcTlsConnectUnBlock(HLT_Process *peerProcess, int sslId); +int HLT_RpcGetTlsConnectResult(int cmdIndex); +int HLT_RpcTlsRead(HLT_Process* peerProcess, int sslId, uint8_t *data, uint32_t bufSize, uint32_t *readLen); +int HLT_RpcTlsReadUnBlock(HLT_Process *peerProcess, int sslId, uint8_t *data, uint32_t bufSize, uint32_t *readLen); +int HLT_RpcGetTlsReadResult(int cmdIndex, uint8_t *data, uint32_t bufSize, uint32_t *readLen); +int HLT_RpcTlsWrite(HLT_Process* peerProcess, int sslId, uint8_t *data, uint32_t bufSize); +int HLT_RpcTlsWriteUnBlock(HLT_Process *peerProcess, int sslId, uint8_t *data, uint32_t bufSize); +int HLT_RpcGetTlsWriteResult(int cmdIndex); +int HLT_RpcTlsRenegotiate(HLT_Process *peerProcess, int sslId); +int HLT_RpcTlsVerifyClientPostHandshake(HLT_Process *peerProcess, int sslId); +int HLT_RpcTlsRegCallback(HLT_Process* peerProcess, TlsCallbackType type); +int HLT_RpcProcessExit(HLT_Process* peerProcess); +int HLT_RpcDataChannelBind(HLT_Process *peerProcess, DataChannelParam *channelParam); +int HLT_RpcDataChannelAccept(HLT_Process* peerProcess, DataChannelParam* channelParam); +int HLT_RpcGetAcceptFd(int acceptId); +int HLT_RpcDataChannelConnect(HLT_Process* peerProcess, DataChannelParam* channelParam); +int HLT_RpcTlsGetStatus(HLT_Process *peerProcess, int sslId); +int HLT_RpcTlsGetAlertFlag(HLT_Process *peerProcess, int sslId); +int HLT_RpcTlsGetAlertLevel(HLT_Process *peerProcess, int sslId); +int HLT_RpcTlsGetAlertDescription(HLT_Process *peerProcess, int sslId); +int HLT_RpcTlsClose(HLT_Process *peerProcess, int sslId); +int HLT_RpcFreeResFormSsl(HLT_Process *peerProcess, int sslId); +int HLT_RpcSctpClose(HLT_Process *peerProcess, int fd); +int HLT_RpcCloseFd(HLT_Process *peerProcess, int fd, int linkType); +int HLT_RpcTlsSetMtu(HLT_Process *peerProcess, int sslId, uint16_t mtu); +int HLT_RpcTlsGetErrorCode(HLT_Process *peerProcess, int sslId); + +// TLS connection establishment encapsulation interface +HLT_Tls_Res* HLT_ProcessTlsAccept(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig); +HLT_Tls_Res* HLT_ProcessTlsConnect(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig); +int HLT_ProcessTlsRead(HLT_Process *process, HLT_Tls_Res* tlsRes, uint8_t *data, uint32_t bufSize, uint32_t *dataLen); +int HLT_ProcessTlsWrite(HLT_Process *process, HLT_Tls_Res* tlsRes, uint8_t *data, uint32_t dataLen); + +int HLT_TlsSetMtu(void *ssl, uint16_t mtu); +int HLT_TlsGetErrorCode(void *ssl); + +bool IsEnableSctpAuth(void); +#ifdef __cplusplus +} +#endif + +#endif // HLT_H \ No newline at end of file diff --git a/testcode/framework/tls/include/hlt_type.h b/testcode/framework/tls/include/hlt_type.h new file mode 100644 index 00000000..baf1fa2d --- /dev/null +++ b/testcode/framework/tls/include/hlt_type.h @@ -0,0 +1,291 @@ +/* + * 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 HLT_TYPE_H +#define HLT_TYPE_H + +#include +#include +#include +#include +#include +#include "uio_base.h" +#include "bsl_uio.h" +#include "hitls_type.h" +#include "tls_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_LEN (32) +#define MAX_CIPHERSUITES_LEN (512) +#define MAX_POINTFORMATS_LEN (512) +#define MAX_GROUPS_LEN (512) +#define MAX_SIGNALGORITHMS_LEN (512) +#define MAX_CERT_LEN (512) +#define PSK_MAX_LEN (256) +#define TICKET_KEY_CB_NAME_LEN (50) +#define MAX_SERVER_NAME_LEN (256) +#define SERVER_NAME_CB_NAME_LEN (50) +#define SERVER_NAME_ARG_NAME_LEN (50) +#define MAX_ALPN_LEN (256) +#define ALPN_CB_NAME_LEN (50) +#define ALPN_DATA_NAME_LEN (50) +#define MAX_NO_RENEGOTIATIONCB_LEN (1024) + +#define DEFAULT_CERT_PATH "../../testcode/testdata/tls/certificate/der/" + +#define RSA_SHA_CA_PATH "rsa_sha/ca-3072.der:rsa_sha/inter-3072.der" +#define RSA_SHA_CHAIN_PATH "rsa_sha/inter-3072.der" +#define RSA_SHA1_EE_PATH "rsa_sha/end-sha1.der" +#define RSA_SHA1_PRIV_PATH "rsa_sha/end-sha1.key.der" +#define RSA_SHA384_EE_PATH "rsa_sha/end-sha384.der" +#define RSA_SHA384_PRIV_PATH "rsa_sha/end-sha384.key.der" +#define RSA_SHA512_EE_PATH "rsa_sha/end-sha512.der" +#define RSA_SHA512_PRIV_PATH "rsa_sha/end-sha512.key.der" +#define ECDSA_SHA_CA_PATH "ecdsa/ca-nist521.der:ecdsa/inter-nist521.der" +#define ECDSA_SHA_CHAIN_PATH "ecdsa/inter-nist521.der" +#define ECDSA_SHA256_EE_PATH "ecdsa/end256-sha256.der" +#define ECDSA_SHA256_PRIV_PATH "ecdsa/end256-sha256.key.der" +#define ECDSA_SHA384_EE_PATH "ecdsa/end384-sha384.der" +#define ECDSA_SHA384_PRIV_PATH "ecdsa/end384-sha384.key.der" +#define ECDSA_SHA512_EE_PATH "ecdsa/end521-sha512.der" +#define ECDSA_SHA512_PRIV_PATH "ecdsa/end521-sha512.key.der" + +#define ECDSA_SHA1_CA_PATH "ecdsa_sha1/ca-nist521.der:ecdsa_sha1/inter-nist521.der" +#define ECDSA_SHA1_CHAIN_PATH "ecdsa_sha1/inter-nist521.der" +#define ECDSA_SHA1_EE_PATH "ecdsa_sha1/end384-sha1.der" +#define ECDSA_SHA1_PRIV_PATH "ecdsa_sha1/end384-sha1.key.der" +#define RSA_SHA256_CA_PATH "rsa_sha256/ca.der:rsa_sha256/inter.der" +#define RSA_SHA256_CHAIN_PATH "rsa_sha256/inter.der" +#define RSA_SHA256_EE_PATH1 "rsa_sha256/server.der" +#define RSA_SHA256_PRIV_PATH1 "rsa_sha256/server.key.der" +#define RSA_SHA256_EE_PATH2 "rsa_sha256/client.der" +#define RSA_SHA256_PRIV_PATH2 "rsa_sha256/client.key.der" +#define RSA_SHA256_EE_PATH3 "rsa_sha/end-sha256.der" +#define RSA_SHA256_PRIV_PATH3 "rsa_sha/end-sha256.key.der" + +#define ECDSA_SHA256_CA_PATH "ecdsa_sha256/ca.der:ecdsa_sha256/inter.der" +#define ECDSA_SHA256_CHAIN_PATH "ecdsa_sha256/inter.der" +#define ECDSA_SHA256_EE_PATH1 "ecdsa_sha256/server.der" +#define ECDSA_SHA256_PRIV_PATH1 "ecdsa_sha256/server.key.der" +#define ECDSA_SHA256_EE_PATH2 "ecdsa_sha256/client.der" +#define ECDSA_SHA256_PRIV_PATH2 "ecdsa_sha256/client.key.der" + +#define SM2_VERIFY_PATH "sm2/ca.der:sm2/inter.der" +#define SM2_CHAIN_PATH "sm2/inter.der" +#define SM2_SERVER_ENC_CERT_PATH "sm2/enc.der" +#define SM2_SERVER_ENC_KEY_PATH "sm2/enc.key.der" +#define SM2_SERVER_SIGN_CERT_PATH "sm2/sign.der" +#define SM2_SERVER_SIGN_KEY_PATH "sm2/sign.key.der" +#define SM2_CLIENT_ENC_CERT_PATH "sm2/enc22.der" +#define SM2_CLIENT_ENC_KEY_PATH "sm2/enc22.key.der" +#define SM2_CLIENT_SIGN_CERT_PATH "sm2/sign22.der" +#define SM2_CLIENT_SIGN_KEY_PATH "sm2/sign22.key.der" + +typedef struct ProcessSt HLT_Process; + +typedef enum { + HITLS, +} TLS_TYPE; + +typedef enum { + CLIENT, + SERVER +} TLS_ROLE; + +typedef enum { + DTLS_ALL, + DTLS1_0, + DTLS1_2, + TLS_ALL, + SSL3_0, + TLS1_0, + TLS1_1, + TLS1_2, + TLS1_3, + TLCP1_1, +} TLS_VERSION; + +typedef enum { + TCP = 0, /**< TCP protocol */ + SCTP = 1, /**< SCTP protocol */ + NONE_TYPE = 10, +} HILT_TransportType; + +typedef enum { + CERT_CALLBACK_DEFAULT, +} CertCallbackType; + +typedef enum { + MEM_CALLBACK_DEFAULT, +} MemCallbackType; + +typedef enum { + HITLS_CALLBACK_DEFAULT, +} TlsCallbackType; + +typedef enum { + COOKIE_CB_DEFAULT, // Normal cookie callback + COOKIE_CB_LEN_0, // The length of the generated cookie is 0 +} CookieCallbackType; + +typedef struct { + struct sockaddr_in sockAddr; + HILT_TransportType type; + char ip[IP_LEN]; + int port; + int bindFd; + bool isBlock; +} DataChannelParam; + +typedef struct { + struct sockaddr_in sockAddr; + int connPort; + int srcFd; + int peerFd; +} HLT_FD; + +typedef enum { + SERVER_CTX_SET_TRUE = 1, + SERVER_CTX_SET_FALSE = 2, + SERVER_CFG_SET_TRUE = 3, + SERVER_CFG_SET_FALSE = 4, +} HILT_SupportType; + +typedef struct { + uint16_t mtu; // Set the MTU in the dtls. + // The maximum version number and minimum version number must be both TLS and DTLS. + // Currently, only DTLS 1.2 is supported + uint32_t minVersion; + uint32_t maxVersion; + + char cipherSuites[MAX_CIPHERSUITES_LEN]; // cipher suite + char tls13CipherSuites[MAX_CIPHERSUITES_LEN]; // TLS13 cipher suite + char pointFormats[MAX_POINTFORMATS_LEN]; // ec Point Format + // According to RFC 8446 4.2.7, before TLS 1.3: ec curves; TLS 1.3: group supported by the key exchange. + char groups[MAX_GROUPS_LEN]; + char signAlgorithms[MAX_SIGNALGORITHMS_LEN]; // signature algorithm + + char serverName[MAX_SERVER_NAME_LEN]; // Client server_name + // Name of the server_name callback function for processing the first handshake on the server + char sniDealCb[SERVER_NAME_CB_NAME_LEN]; + // name of the value function related to the server_name registered by the product + char sniArg[SERVER_NAME_ARG_NAME_LEN]; + + char alpnList[MAX_ALPN_LEN]; // alpn + char alpnUserData[ALPN_CB_NAME_LEN]; + char alpnSelectCb[ALPN_DATA_NAME_LEN]; // Application Layer Protocol Select Callback + /* Callback function when the peer end does not support security renegotiation */ + char noSecRenegotiationCb[MAX_NO_RENEGOTIATIONCB_LEN]; + + // Indicates whether renegotiation is supported. The default value is False, indicating that renegotiation is not + // supported + bool isSupportRenegotiation; + int SupportType; // 1:The server algorithm is preferred + bool needCheckKeyUsage; // Client verification is supported. The default value is False + // Indicates whether to allow the empty certificate list on the client. The default value is False + bool isSupportClientVerify; + bool isSupportNoClientCert; // supports extended master keys. The default value is True + // The handshake will be continued regardless of the verification result. for server and client + bool isSupportVerifyNone; + bool isSupportPostHandshakeAuth; // Indicates whether to support post handshake auth. The default value is false. + bool isSupportExtendMasterSecret; // supports extended master keys. The default value is True + bool isSupportSessionTicket; // Support session ticket + bool isEncryptThenMac; // Encrypt-then-mac is supported + // Users can set the DH parameter to be automatically selected. If the switch is enabled, + // the DH parameter is automatically selected based on the length of the certificate private key + bool isSupportDhAuto; + int32_t setSessionCache; // Setting the Session Storage Mode + uint32_t keyExchMode; // TLS1.3 key exchange mode + void *infoCb; // connection establishment callback function + void *msgCb; // Message callback function + void *msgArg; // Message callback parameter function + // Indicates whether to enable the function of sending handshake information by flight + bool isFlightTransmitEnable; + bool isNoSetCert; // Indicates whether the certificate does not need to be set + int32_t securitylevel; // Security level + + char psk[PSK_MAX_LEN]; // psk password + char ticketKeyCb[TICKET_KEY_CB_NAME_LEN]; // ticket key Callback Function Name + + char eeCert[MAX_CERT_LEN]; + char privKey[MAX_CERT_LEN]; + char signCert[MAX_CERT_LEN]; + char signPrivKey[MAX_CERT_LEN]; + char password[MAX_CERT_LEN]; + char caCert[MAX_CERT_LEN]; + char chainCert[MAX_CERT_LEN]; + + bool isClient; +} HLT_Ctx_Config; + +typedef struct { + struct sockaddr_in sockAddr; + int connPort; + int sockFd; + HILT_TransportType connType; + int SupportType; // 3:The server algorithm is preferred + int sctpCtrlCmd; +} HLT_Ssl_Config; + +typedef struct { + void *ctx; // hitls config + void *ssl; // hitls ctx + int ctxId; + int sslId; + unsigned long int acceptId; +} HLT_Tls_Res; + +typedef enum { + EXP_NONE, + EXP_IO_BUSY, + EXP_RECV_BUF_EMPTY, +} HLT_ExpectIoState; + +typedef enum { + POINT_NONE, + POINT_RECV, + POINT_SEND, +} HLT_PointType; + +/** + * @brief msg processing callback + */ +typedef void (*HLT_FrameCallBack)(void *msg, void *userData); + +typedef struct { + BSL_UIO_Method method; /**< User-defined message sending and receiving control function */ + HLT_FrameCallBack frameCallBack; /**< msg processing callback */ + void *ctx; /**< TLS context */ + int32_t expectReType; /**< Corresponding enumeration REC_Type */ + int32_t expectHsType; /**< Corresponding enumerated value HS_MsgType */ + HLT_ExpectIoState ioState; /**< customized I/O status */ + HLT_PointType pointType; /**< Callback function for recording keys */ + void *userData; /**< Customized data, which will be transferred to the msg processing callback */ +} HLT_FrameHandle; + +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define TIME_OUT_SEC 50 +#else +#define TIME_OUT_SEC 8 +#endif + +#ifdef __cplusplus +} +#endif + +#endif // HLT_TYPE_H diff --git a/testcode/framework/tls/io/include/frame_io.h b/testcode/framework/tls/io/include/frame_io.h new file mode 100644 index 00000000..0e6c856a --- /dev/null +++ b/testcode/framework/tls/io/include/frame_io.h @@ -0,0 +1,98 @@ +/* + * 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 FRAME_IO_H +#define FRAME_IO_H + +#include "bsl_errno.h" +#include "bsl_uio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_RECORD_LENTH (20 * 1024) // Simulates the bottom-layer sending and receiving processing of the DT framework. + +typedef struct FrameUioUserData_ FrameUioUserData; + +/** + * @brief SCTP bottom-layer I/O function, which is used to simulate the SCTP message sending interface. + * + * @par Description: + * SCTP bottom-layer I/O function, which is used to simulate the SCTP message sending interface. + * + * @attention + * @return If the operation is successful, success is returned. Otherwise, other values are returned. In this framework, + * a success message is returned without special reasons. + */ +int32_t FRAME_Write(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen); + + +/** + * @brief SCTP bottom-layer I/O function, which is used to simulate the SCTP message receiving interface. + * + * @par Description: + * SCTP bottom-layer I/O function, which is used to simulate the SCTP message receiving interface. + * + * @attention + * @return If the operation is successful, success is returned. Otherwise, other values are returned. + */ +int32_t FRAME_Read(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen); + + +/** + * @brief SCTP bottom-layer I/O function, which is used to simulate the SCTP control interface. + * + * @par Description: + * SCTP bottom-layer I/O function, which is used to simulate the SCTP control interface. + * + * @attention + * @return If the operation is successful, success is returned. Otherwise, other values are returned. + */ +int32_t FRAME_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param); + +/** +* @brief Create a UIO user data. The user data must be used when the I/O of the test framework is used. The user data +* stores the data to be sent and received by the I/O. +* +* @return If the operation is successful, the pointer of userdata is returned. +*/ +FrameUioUserData *FRAME_IO_CreateUserData(void); + +/** +* @brief Releases userdata created by the Frame_IO_CreateUserData function. +* +* @return NA +*/ +void FRAME_IO_FreeUserData(FrameUioUserData *userData); + +/** +* @brief Frame_TransportSendMsg sends the messages in the sending buffer in the I/O. +* +* @return If the operation is successful, 0 is returned. Otherwise, another value is returned. +*/ +int32_t FRAME_TransportSendMsg(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen); + +/** +* @brief Frame_TransportRecMsg simulates receiving messages from the I/O. +* +* @return If the operation is successful, 0 is returned. Otherwise, another value is returned. +*/ +int32_t FRAME_TransportRecMsg(BSL_UIO *uio, void *buf, uint32_t len); +#ifdef __cplusplus +} +#endif + +#endif // FRAME_IO_H diff --git a/testcode/framework/tls/io/src/simulate_io.c b/testcode/framework/tls/io/src/simulate_io.c new file mode 100644 index 00000000..01ef1b6c --- /dev/null +++ b/testcode/framework/tls/io/src/simulate_io.c @@ -0,0 +1,162 @@ +/* + * 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 "simulate_io.h" +#include "hitls_error.h" +#include "bsl_sal.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "securec.h" + +#define FAKE_BSL_UIO_FD 666 + +FrameUioUserData *FRAME_IO_CreateUserData(void) +{ + FrameUioUserData *userData = BSL_SAL_Calloc(1u, sizeof(FrameUioUserData)); + if (userData == NULL) { + return NULL; + } + return userData; +} + +void FRAME_IO_FreeUserData(FrameUioUserData *userData) +{ + if (userData == NULL) { + return; + } + + BSL_SAL_FREE(userData); + return; +} + +int32_t FRAME_Write(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + *writeLen = 0; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio); + if (ioUserData == NULL) { + return BSL_NULL_INPUT; + } + + // This indicates that there is still a message in the buffer. The second message can be sent only after the peer + // end receives the message. + if (ioUserData->sndMsg.len != 0) { + return BSL_SUCCESS; + } + + memcpy_s(ioUserData->sndMsg.msg, MAX_RECORD_LENTH, buf, len); + ioUserData->sndMsg.len = len; + *writeLen = len; + + return BSL_SUCCESS; +} + +int32_t FRAME_Read(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + *readLen = 0; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio); + if (ioUserData == NULL) { + return BSL_NULL_INPUT; + } + // This indicates that the user inserts data. Therefore, the simulated data inserted by the user is received first. + if (ioUserData->userInsertMsg.len != 0) { + if (len < ioUserData->userInsertMsg.len) { + return BSL_UIO_FAIL; + } + + memcpy_s(buf, len, ioUserData->userInsertMsg.msg, ioUserData->userInsertMsg.len); + *readLen = ioUserData->userInsertMsg.len; + ioUserData->userInsertMsg.len = 0; + return BSL_SUCCESS; + } else if (ioUserData->recMsg.len != 0) { + if (len < ioUserData->recMsg.len) { + return BSL_UIO_FAIL; + } + + memcpy_s(buf, len, ioUserData->recMsg.msg, ioUserData->recMsg.len); + *readLen = ioUserData->recMsg.len; + ioUserData->recMsg.len = 0; + return BSL_SUCCESS; + } // If there is no data in the receive buffer, a success message is returned and *readLen is set to 0. + + return BSL_SUCCESS; +} + +int32_t FRAME_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param) +{ + (void)uio; + (void)larg; + if (cmd == BSL_UIO_SCTP_SND_BUFF_IS_EMPTY) { + *(uint8_t *)param = true; + } + + if (cmd == BSL_UIO_GET_FD) { + *(int32_t *)param = FAKE_BSL_UIO_FD; + } + + return BSL_SUCCESS; +} + +/* + Frame_TransportSendMsg: Sends messages in the send buffer in the I/O. + Copy uio->userData to the buffer. +*/ +int32_t FRAME_TransportSendMsg(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + *readLen = 0; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio); + if (ioUserData == NULL) { + return HITLS_NULL_INPUT; + } + + if (ioUserData->sndMsg.len != 0) { + // The length of the data in the buffer exceeds len. + if (len < ioUserData->sndMsg.len) { + return HITLS_UIO_FAIL; + } + + memcpy_s(buf, len, ioUserData->sndMsg.msg, ioUserData->sndMsg.len); + *readLen = ioUserData->sndMsg.len; + ioUserData->sndMsg.len = 0; + } // If there is no data in the receive buffer, a success message is returned and *readLen is set to 0. + + return HITLS_SUCCESS; +} + +/* + Frame_TransportRecMsg simulates receiving messages from the I/O. + Copy the data in the buffer to uio->userData. +*/ +int32_t FRAME_TransportRecMsg(BSL_UIO *uio, void *buf, uint32_t len) +{ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio); + if (ioUserData == NULL) { + return HITLS_NULL_INPUT; + } + + if (ioUserData->recMsg.len != 0 || len > MAX_RECORD_LENTH) { + return HITLS_UIO_FAIL; + } + + memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, buf, len); + ioUserData->recMsg.len = len; + + return HITLS_SUCCESS; +} + +#ifdef __cplusplus +} +#endif diff --git a/testcode/framework/tls/io/src/simulate_io.h b/testcode/framework/tls/io/src/simulate_io.h new file mode 100644 index 00000000..4463c0fc --- /dev/null +++ b/testcode/framework/tls/io/src/simulate_io.h @@ -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. + */ + +#ifndef SIMULATE_IO_H +#define SIMULATE_IO_H + +#include "frame_io.h" +#include "bsl_bytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint8_t msg[MAX_RECORD_LENTH]; + uint32_t len; +} FrameMsg; + +struct FrameUioUserData_ { + FrameMsg sndMsg; + FrameMsg recMsg; + FrameMsg userInsertMsg; +}; + +#define REC_RECORD_DTLS_EPOCH_OFFSET 3 +#define REC_RECORD_DTLS_LENGTH_OFFSET 11 + + +#ifdef __cplusplus +} +#endif + +#endif // SIMULATE_IO_H \ No newline at end of file diff --git a/testcode/framework/tls/msg/include/pack_frame_msg.h b/testcode/framework/tls/msg/include/pack_frame_msg.h new file mode 100644 index 00000000..ce34d541 --- /dev/null +++ b/testcode/framework/tls/msg/include/pack_frame_msg.h @@ -0,0 +1,36 @@ +/* + * 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 PACK_FRAME_MSG_H +#define PACK_FRAME_MSG_H + +#include "frame_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief Generate a framework message based on the content in the message buffer. +* +* @return Returns the CTX object of the TLS. +*/ +int32_t PackFrameMsg(FRAME_Msg *msg); + +#ifdef __cplusplus +} +#endif + +#endif // PACK_FRAME_MSG_H \ No newline at end of file diff --git a/testcode/framework/tls/msg/include/parser_frame_msg.h b/testcode/framework/tls/msg/include/parser_frame_msg.h new file mode 100644 index 00000000..a966b3c6 --- /dev/null +++ b/testcode/framework/tls/msg/include/parser_frame_msg.h @@ -0,0 +1,36 @@ +/* + * 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 PARSER_FRAME_MSG_H +#define PARSER_FRAME_MSG_H + +#include "frame_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t ParserRecordHeader(FRAME_Msg *frameMsg, const uint8_t *buffer, uint32_t len, uint32_t *parserLen); +int32_t ParserRecordBody(const FRAME_LinkObj *linkObj, FRAME_Msg *frameMsg, + const uint8_t *buffer, uint32_t len, uint32_t *parserLen); +int32_t ParserTotalRecord(const FRAME_LinkObj *linkObj, FRAME_Msg *frameMsg, + const uint8_t *buffer, uint32_t len, uint32_t *parserLen); +void CleanRecordBody(FRAME_Msg *frameMsg); + +#ifdef __cplusplus +} +#endif + +#endif // PARSER_FRAME_MSG_H diff --git a/testcode/framework/tls/msg/src/frame_msg_method.c b/testcode/framework/tls/msg/src/frame_msg_method.c new file mode 100644 index 00000000..b472c15b --- /dev/null +++ b/testcode/framework/tls/msg/src/frame_msg_method.c @@ -0,0 +1,412 @@ +/* + * 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 +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "frame_link.h" +#include "frame_io.h" +#include "simulate_io.h" + +#define DEFAUTL_COOKIE_LEN 32 + +/* Used to establish a link and stop in the state. */ +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; +} LinkPara; + +static void CleanLinkPara(LinkPara *linkPara) +{ + HITLS_CFG_FreeConfig(linkPara->config); + FRAME_FreeLink(linkPara->client); + FRAME_FreeLink(linkPara->server); +} + +static int32_t PauseState(LinkPara *linkPara, uint16_t version) +{ + /* Check the TLS version type, which is converted to connection enumeration. */ + BSL_UIO_TransportType transportType = BSL_UIO_UNKNOWN; + if (IS_DTLS_VERSION(version)) { + transportType = BSL_UIO_SCTP; + } else if (version == HITLS_VERSION_TLS12 || version == HITLS_VERSION_TLS13 || version == HITLS_VERSION_TLCP11) { + transportType = BSL_UIO_TCP; + } else { + /* Link establishment in other versions is not supported. */ + return HITLS_INTERNAL_EXCEPTION; + } + + /* Constructing a Link */ + if ( version == HITLS_VERSION_TLCP11 ) { + linkPara->client = FRAME_CreateTLCPLink(linkPara->config, transportType, true); + linkPara->server = FRAME_CreateTLCPLink(linkPara->config, transportType, false); + }else { + linkPara->client = FRAME_CreateLink(linkPara->config, transportType); + linkPara->server = FRAME_CreateLink(linkPara->config, transportType); + } + + if (linkPara->client == NULL || linkPara->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* Establish a link and stop in a certain state. */ + if (FRAME_CreateConnection(linkPara->client, linkPara->server, + linkPara->isClient, linkPara->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* Check whether the status is consistent. */ + HITLS_Ctx *ctx = linkPara->isClient ? linkPara->client->ssl : linkPara->server->ssl; + if ((ctx->hsCtx == NULL) || (ctx->hsCtx->state != linkPara->state)) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +static int32_t SetLinkState(HS_MsgType hsType, LinkPara *linkPara) +{ + linkPara->isClient = true; + switch (hsType) { + case CLIENT_HELLO: + linkPara->isClient = false; + linkPara->state = TRY_RECV_CLIENT_HELLO; + return HITLS_SUCCESS; + case SERVER_HELLO: + linkPara->state = TRY_RECV_SERVER_HELLO; + return HITLS_SUCCESS; + case CERTIFICATE: + linkPara->state = TRY_RECV_CERTIFICATE; + return HITLS_SUCCESS; + case SERVER_KEY_EXCHANGE: + linkPara->state = TRY_RECV_SERVER_KEY_EXCHANGE; + return HITLS_SUCCESS; + case CERTIFICATE_REQUEST: + linkPara->state = TRY_RECV_CERTIFICATE_REQUEST; + return HITLS_SUCCESS; + case SERVER_HELLO_DONE: + linkPara->state = TRY_RECV_SERVER_HELLO_DONE; + return HITLS_SUCCESS; + case CERTIFICATE_VERIFY: + linkPara->isClient = false; + linkPara->state = TRY_RECV_CERTIFICATE_VERIFY; + return HITLS_SUCCESS; + case CLIENT_KEY_EXCHANGE: + linkPara->isClient = false; + linkPara->state = TRY_RECV_CLIENT_KEY_EXCHANGE; + return HITLS_SUCCESS; + case FINISHED: + // The existing framework does not support parsing of encrypted finished messages. + // Therefore, finished messages cannot be obtained. + break; + default: + break; + } + return HITLS_INTERNAL_EXCEPTION; +} + +static int32_t SetLinkConfig(uint16_t version, HITLS_KeyExchAlgo keyExAlgo, LinkPara *linkPara) +{ + if (linkPara == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + linkPara->config = NULL; + if (IS_DTLS_VERSION(version)) { + linkPara->config = HITLS_CFG_NewDTLS12Config(); + HITLS_CFG_SetCloseCheckKeyUsage(linkPara->config, false); + } else if (version == HITLS_VERSION_TLS12) { + linkPara->config = HITLS_CFG_NewTLS12Config(); + HITLS_CFG_SetCloseCheckKeyUsage(linkPara->config, false); + } else if (version == HITLS_VERSION_TLS13) { + linkPara->config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetCloseCheckKeyUsage(linkPara->config, false); + } else if (version == HITLS_VERSION_TLCP11) { + linkPara->config = HITLS_CFG_NewTLCPConfig(); + HITLS_CFG_SetCloseCheckKeyUsage(linkPara->config, false); + return HITLS_SUCCESS; + } + + int32_t ret; + ret = HITLS_CFG_SetVersion(linkPara->config, version, version); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HITLS_CFG_SetClientVerifySupport(linkPara->config, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (keyExAlgo == HITLS_KEY_EXCH_DHE) { + uint16_t cipherSuites[] = {HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(linkPara->config, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetSignature(linkPara->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + } else { + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(linkPara->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(linkPara->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + } + + return HITLS_SUCCESS; +} + +static int32_t GetdefaultHsMsg(FRAME_Type *frameType, FRAME_Msg *parsedMsg) +{ + int32_t ret; + LinkPara linkPara = {0}; + + /* Configure config. */ + ret = SetLinkConfig(frameType->versionType, frameType->keyExType, &linkPara); + if (ret != HITLS_SUCCESS) { + CleanLinkPara(&linkPara); + return ret; + } + + /* Setting the parked state */ + ret = SetLinkState(frameType->handshakeType, &linkPara); + if (ret != HITLS_SUCCESS) { + CleanLinkPara(&linkPara); + return ret; + } + + /* Stop in this state */ + ret = PauseState(&linkPara, frameType->versionType); + if (ret != HITLS_SUCCESS) { + CleanLinkPara(&linkPara); + return ret; + } + + /* Obtain the message buffer. */ + FRAME_LinkObj *link = linkPara.isClient ? linkPara.client : linkPara.server; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(link->io); + uint8_t *buffer = ioUserData->recMsg.msg; + uint32_t len = ioUserData->recMsg.len; + if (len == 0) { + CleanLinkPara(&linkPara); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Parse to msg structure */ + uint32_t parseLen = 0; + ret = FRAME_ParseMsg(frameType, buffer, len, parsedMsg, &parseLen); + if ((ret != HITLS_SUCCESS) || (len != parseLen)) { + CleanLinkPara(&linkPara); + return HITLS_INTERNAL_EXCEPTION; + } + + CleanLinkPara(&linkPara); + return HITLS_SUCCESS; +} + +static void SetDefaultRecordHeader(FRAME_Type *frameType, FRAME_Msg *msg, REC_Type recType) +{ + msg->recType.state = INITIAL_FIELD; + msg->recType.data = recType; + msg->recVersion.state = INITIAL_FIELD; + if (IS_DTLS_VERSION(frameType->versionType)) { + msg->recVersion.data = HITLS_VERSION_DTLS12; + } else if (frameType->versionType == HITLS_VERSION_TLCP11) { + msg->recVersion.data = HITLS_VERSION_TLCP11; + } else { + msg->recVersion.data = HITLS_VERSION_TLS12; + } + msg->epoch.state = INITIAL_FIELD; + /* In the default message, the value is set to 0 by default. You need to assign a value to the value. */ + msg->epoch.data = 0; + msg->sequence.state = INITIAL_FIELD; + /* In the default message, the value is set to 0 by default. You need to assign a value to the value. */ + msg->sequence.data = 0; + msg->length.state = INITIAL_FIELD; + /* The value of length is automatically calculated during assembly. + * Therefore, the value of length is initialized to 0. */ + msg->length.data = 0; +} + +static int32_t GetdefaultCcsMsg(FRAME_Type *frameType, FRAME_Msg *msg) +{ + SetDefaultRecordHeader(frameType, msg, REC_TYPE_CHANGE_CIPHER_SPEC); /* Setting the Default Record Header */ + msg->body.ccsMsg.ccsType.state = INITIAL_FIELD; + msg->body.ccsMsg.ccsType.data = 1u; /* In the protocol, the CCS type has only this value. */ + return HITLS_SUCCESS; +} + +static int32_t GetdefaultAlertMsg(FRAME_Type *frameType, FRAME_Msg *msg) +{ + SetDefaultRecordHeader(frameType, msg, REC_TYPE_ALERT); /* Setting the Default Record Header */ + msg->body.alertMsg.alertLevel.state = INITIAL_FIELD; + /*Default value. You can change the default value as required. */ + msg->body.alertMsg.alertLevel.data = ALERT_LEVEL_FATAL; + msg->body.alertMsg.alertDescription.state = INITIAL_FIELD; + /*Default value. You can change the default value as required. */ + msg->body.alertMsg.alertDescription.data = ALERT_HANDSHAKE_FAILURE; + return HITLS_SUCCESS; +} + +int32_t FRAME_GetDefaultMsg(FRAME_Type *frameType, FRAME_Msg *msg) +{ + if ((frameType == NULL) || (msg == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + switch (frameType->recordType) { + case REC_TYPE_HANDSHAKE: + return GetdefaultHsMsg(frameType, msg); + case REC_TYPE_CHANGE_CIPHER_SPEC: + return GetdefaultCcsMsg(frameType, msg); + case REC_TYPE_ALERT: + return GetdefaultAlertMsg(frameType, msg); + default: + break; + } + return HITLS_INTERNAL_EXCEPTION; +} + +int32_t FRAME_ModifyMsgInteger(const uint64_t data, FRAME_Integer *frameInteger) +{ + if (frameInteger == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + frameInteger->state = ASSIGNED_FIELD; + frameInteger->data = data; + return HITLS_SUCCESS; +} + +int32_t FRAME_ModifyMsgArray8(const uint8_t *data, uint32_t dataLen, + FRAME_Array8 *frameArray, FRAME_Integer *frameArrayLen) +{ + if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) { + return HITLS_INTERNAL_EXCEPTION; + } + BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */ + + frameArray->data = BSL_SAL_Dump(data, dataLen); + if (frameArray->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + frameArray->state = ASSIGNED_FIELD; + frameArray->size = dataLen; + + if (frameArrayLen != NULL) { + frameArrayLen->state = ASSIGNED_FIELD; + frameArrayLen->data = dataLen; + } + + return HITLS_SUCCESS; +} + +int32_t FRAME_AppendMsgArray8(const uint8_t *data, uint32_t dataLen, + FRAME_Array8 *frameArray, FRAME_Integer *frameArrayLen) +{ + if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* extended memory */ + uint32_t newDataLen = dataLen + frameArray->size; + uint8_t *newData = (uint8_t *)BSL_SAL_Calloc(1u, newDataLen); + if (newData == NULL) { + return HITLS_MEMALLOC_FAIL; + } + if (memcpy_s(newData, newDataLen, frameArray->data, frameArray->size) != EOK) { + BSL_SAL_FREE(newData); + return HITLS_MEMCPY_FAIL; + } + if (memcpy_s(&newData[frameArray->size], newDataLen - frameArray->size, data, dataLen) != EOK) { + BSL_SAL_FREE(newData); + return HITLS_MEMCPY_FAIL; + } + + BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */ + frameArray->state = ASSIGNED_FIELD; + frameArray->data = newData; + frameArray->size = newDataLen; + + if (frameArrayLen != NULL) { + frameArrayLen->state = ASSIGNED_FIELD; + frameArrayLen->data = newDataLen; + } + + return HITLS_SUCCESS; +} + +int32_t FRAME_ModifyMsgArray16(const uint16_t *data, uint32_t dataLen, + FRAME_Array16 *frameArray, FRAME_Integer *frameArrayLen) +{ + if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) { + return HITLS_INTERNAL_EXCEPTION; + } + BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */ + + frameArray->data = (uint16_t *)BSL_SAL_Dump(data, dataLen * sizeof(uint16_t)); + if (frameArray->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + frameArray->state = ASSIGNED_FIELD; + frameArray->size = dataLen; + + if (frameArrayLen != NULL) { + frameArrayLen->state = ASSIGNED_FIELD; + frameArrayLen->data = dataLen * sizeof(uint16_t); + } + + return HITLS_SUCCESS; +} + +int32_t FRAME_AppendMsgArray16(const uint16_t *data, uint32_t dataLen, + FRAME_Array16 *frameArray, FRAME_Integer *frameArrayLen) +{ + if ((data == NULL) || (frameArray == NULL) || (dataLen == 0)) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* extended memory */ + uint32_t newDataLen = (frameArray->size + dataLen) * sizeof(uint16_t); /* Data length */ + uint16_t *newData = (uint16_t *)BSL_SAL_Calloc(1u, newDataLen); + if (newData == NULL) { + return HITLS_MEMALLOC_FAIL; + } + for (uint32_t i = 0; i < frameArray->size; i++) { + newData[i] = frameArray->data[i]; + } + for (uint32_t i = 0; i < dataLen; i++) { + newData[frameArray->size + i] = data[i]; + } + + BSL_SAL_FREE(frameArray->data); /* Clear the old memory. */ + frameArray->state = ASSIGNED_FIELD; + frameArray->data = newData; + frameArray->size = newDataLen / sizeof(uint16_t); /* Number of data records */ + + if (frameArrayLen != NULL) { + frameArrayLen->state = ASSIGNED_FIELD; + frameArrayLen->data = newDataLen; + } + + return HITLS_SUCCESS; +} diff --git a/testcode/framework/tls/msg/src/frame_pack_msg.c b/testcode/framework/tls/msg/src/frame_pack_msg.c new file mode 100644 index 00000000..5bafc9ff --- /dev/null +++ b/testcode/framework/tls/msg/src/frame_pack_msg.c @@ -0,0 +1,1390 @@ +/* + * 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 "securec.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls.h" +#include "tls.h" +#include "hs_ctx.h" +#include "frame_msg.h" +#include "hs_extensions.h" + +#define TLS_RECORD_HEADER_LEN 5 +#define DTLS_RECORD_HEADER_LEN 13 + +#define SIZE_OF_UINT24 3 +#define SIZE_OF_UINT32 4 +#define SIZE_OF_UINT48 6 + +#define ONE_TIME 1 +#define TWO_TIMES 2 + +// Assemble 8-bit data(1 byte) +static int32_t PackInteger8(const FRAME_Integer *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + uint32_t bufOffset = 0; + + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Repeated assembly + if (field->state == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Not enough to assemble + if (bufLen < (sizeof(uint8_t) * repeats)) { + return HITLS_INTERNAL_EXCEPTION; + } + + for (uint32_t i = 0; i < repeats; i++) { + uint8_t data = (uint8_t)(field->data); + buf[bufOffset] = data; + bufOffset += sizeof(uint8_t); + *offset += sizeof(uint8_t); + } + return HITLS_SUCCESS; +} + +// Assemble 16-bit data(2 bytes) +static int32_t PackInteger16(const FRAME_Integer *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + uint32_t bufOffset = 0; + + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Repeated assembly + if (field->state == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Not enough to assemble + if (bufLen < (sizeof(uint16_t) * repeats)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (field->state == SET_LEN_TO_ONE_BYTE) { + uint8_t data = (uint8_t)field->data; + buf[0] = data; + *offset += sizeof(uint8_t); + return HITLS_SUCCESS; + } + + for (uint32_t i = 0; i < repeats; i++) { + uint16_t data = (uint16_t)(field->data); + BSL_Uint16ToByte(data, &buf[bufOffset]); + bufOffset += sizeof(uint16_t); + *offset += sizeof(uint16_t); + } + return HITLS_SUCCESS; +} + +// Assemble 24-bit data(3 bytes) +static int32_t PackInteger24(const FRAME_Integer *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + uint32_t bufOffset = 0; + + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Repeated assembly + if (field->state == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Not enough to assemble + if (bufLen < (SIZE_OF_UINT24 * repeats)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (field->state == SET_LEN_TO_ONE_BYTE) { + uint8_t data = (uint8_t)field->data; + buf[0] = data; + *offset += sizeof(uint8_t); + return HITLS_SUCCESS; + } + + for (uint32_t i = 0; i < repeats; i++) { + uint32_t data = (uint32_t)field->data; + BSL_Uint24ToByte(data, &buf[bufOffset]); + bufOffset += SIZE_OF_UINT24; + *offset += SIZE_OF_UINT24; + } + return HITLS_SUCCESS; +} + + +// Assemble 32-bit data(8 bytes) +static int32_t PackInteger32(const FRAME_Integer *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + uint32_t bufOffset = 0; + + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Repeated assembly + if (field->state == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Not enough to assemble + if (bufLen < (SIZE_OF_UINT32 * repeats)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (field->state == SET_LEN_TO_ONE_BYTE) { + uint8_t data = (uint8_t)field->data; + buf[0] = data; + *offset += sizeof(uint8_t); + return HITLS_SUCCESS; + } + + for (uint32_t i = 0; i < repeats; i++) { + uint32_t data = (uint32_t)field->data; + BSL_Uint32ToByte(data, &buf[bufOffset]); + bufOffset += SIZE_OF_UINT32; + *offset += SIZE_OF_UINT32; + } + return HITLS_SUCCESS; +} + +// Assemble 48-bit data(8 bytes) +static int32_t PackInteger48(const FRAME_Integer *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + uint32_t bufOffset = 0; + + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Repeated assembly + if (field->state == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Not enough to assemble + if (bufLen < (SIZE_OF_UINT48 * repeats)) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (field->state == SET_LEN_TO_ONE_BYTE) { + uint8_t data = (uint8_t)field->data; + buf[0] = data; + *offset += sizeof(uint8_t); + return HITLS_SUCCESS; + } + + for (uint32_t i = 0; i < repeats; i++) { + uint64_t data = (uint64_t)field->data; + BSL_Uint48ToByte(data, &buf[bufOffset]); + bufOffset += SIZE_OF_UINT48; + *offset += SIZE_OF_UINT48; + } + return HITLS_SUCCESS; +} + +// Assembles the buffer of 8-bit data.(1 byte * n) +static int32_t PackArray8(const FRAME_Array8 *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Total length to be assembled + uint32_t length = field->size; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memcpy_s(buf, bufLen, field->data, field->size) != EOK) { + return HITLS_MEMCPY_FAIL; + } + + *offset += length; + return HITLS_SUCCESS; +} + +// Assemble the buffer of 16-bit data.(2 bytes * n) +static int32_t PackArray16(const FRAME_Array16 *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + // No assembly required + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Total length to be assembled + uint32_t length = field->size * sizeof(uint16_t); + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t bufoffset = 0; + for (uint32_t i = 0; i < field->size; i++) { + BSL_Uint16ToByte(field->data[i], &buf[bufoffset]); + bufoffset += sizeof(uint16_t); + } + + *offset += length; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtArray8(const FRAME_HsExtArray8 *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exDataLen.state == MISSING_FIELD) ? 0 : sizeof(uint8_t)); + length += ((field->exData.state == MISSING_FIELD) ? 0 : sizeof(uint8_t) * field->exData.size); + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger8(&field->exDataLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->exData, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtArrayForList(const FRAME_HsExtArray8 *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exDataLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exData.state == MISSING_FIELD) ? 0 : sizeof(uint8_t) * field->exData.size); + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->exDataLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->exData, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + + +static int32_t PackHsExtArrayForTicket(const FRAME_HsExtArray8 *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exDataLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exData.state == MISSING_FIELD) ? 0 : sizeof(uint8_t) * field->exData.size); + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exDataLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->exData, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exDataLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtArray16(const FRAME_HsExtArray16 *field, uint8_t *buf, + uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exDataLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exData.state == MISSING_FIELD) ? 0 : sizeof(uint16_t) * field->exData.size); + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->exDataLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray16(&field->exData, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackPskIdentity(const FRAME_HsArrayPskIdentity *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + // This extension does not need to be assembled. + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + // Duplicate identity arrays are meaningless. The configuration value can be duplicated. + + uint32_t bufoffset = 0; + uint32_t tmpOffset = 0; + for (uint32_t j = 0; j < field->size; j++) { + uint32_t innerRepeat = ONE_TIME; + if (field->data[j].state == MISSING_FIELD) { + continue; + } + if (field->data[j].state == DUPLICATE_FIELD) { + innerRepeat = TWO_TIMES; + } + for (uint32_t k = 0; k < innerRepeat; k++) { + tmpOffset = bufoffset; + PackInteger16(&field->data[j].identityLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->data[j].identity, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->data[j].identityLen.state == INITIAL_FIELD) { + BSL_Uint16ToByte(field->data[j].identity.size, &buf[tmpOffset]); + } + PackInteger32(&field->data[j].obfuscatedTicketAge, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackPskBinder(const FRAME_HsArrayPskBinder *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + // This extension does not need to be assembled. + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + // Duplicate identity arrays are meaningless. The configuration value can be duplicated. + + uint32_t bufoffset = 0; + uint32_t tmpOffset = 0; + for (uint32_t j = 0; j < field->size; j++) { + uint32_t innerRepeat = ONE_TIME; + if (field->data[j].state == MISSING_FIELD) { + continue; + } + if (field->data[j].state == DUPLICATE_FIELD) { + innerRepeat = TWO_TIMES; + } + for (uint32_t k = 0; k < innerRepeat; k++) { + tmpOffset = bufoffset; + PackInteger8(&field->data[j].binderLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->data[j].binder, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->data[j].binderLen.state == INITIAL_FIELD) { + buf[tmpOffset] = field->data[j].binder.size; + } + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtOfferedPsks(const FRAME_HsExtOfferedPsks *field, uint8_t *buf, + uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += field->exLen.data; + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t bufoffset = 0; + uint32_t tmpOffset = 0; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->identitySize, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + // identity len INITIAL_FIELD Not supported currently + PackPskIdentity(&field->identities, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->binderSize, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + // binder len INITIAL_FIELD Not supported currently + PackPskBinder(&field->binders, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} +static int32_t PackKeyShareArray(const FRAME_HsArrayKeyShare *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + // This extension does not need to be assembled. + if (field->state == MISSING_FIELD) { + return HITLS_SUCCESS; + } + // Duplicate key share arrays are meaningless. The configuration value can be duplicated. + + uint32_t bufoffset = 0; + uint32_t tmpOffset = 0; + for (uint32_t j = 0; j < field->size; j++) { + uint32_t innerRepeat = ONE_TIME; + if (field->data[j].state == MISSING_FIELD) { + continue; + } + if (field->data[j].state == DUPLICATE_FIELD) { + innerRepeat = TWO_TIMES; + } + for (uint32_t k = 0; k < innerRepeat; k++) { + PackInteger16(&field->data[j].group, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->data[j].keyExchangeLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->data[j].keyExchange, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->data[j].keyExchangeLen.state == INITIAL_FIELD) { + BSL_Uint16ToByte(field->data[j].keyExchange.size, &buf[tmpOffset]); + } + } + } + *offset += bufoffset; + return HITLS_SUCCESS; + +} +static int32_t PackHsExtKeyShare(const FRAME_HsExtKeyShare *field, uint8_t *buf, + uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += field->exLen.data; + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t bufoffset = 0; + uint32_t tmpOffset = 0; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->exKeyShareLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + // exKeyShareLen INITIAL_FIELD Not supported currently + PackKeyShareArray(&field->exKeyShares, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtSupportedVersion(const FRAME_HsExtArray16 *field, uint8_t *buf, + uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exDataLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exData.state == MISSING_FIELD) ? 0 : sizeof(uint16_t) * field->exData.size); + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger8(&field->exDataLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray16(&field->exData, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackClientHelloMsg(const FRAME_ClientHelloMsg *clientHello, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + uint32_t bufOffset; + + PackInteger16(&clientHello->version, &buf[offset], bufLen, &offset); + PackArray8(&clientHello->randomValue, &buf[offset], bufLen - offset, &offset); + PackInteger8(&clientHello->sessionIdSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&clientHello->sessionId, &buf[offset], bufLen - offset, &offset); + PackInteger8(&clientHello->cookiedLen, &buf[offset], bufLen - offset, &offset); + PackArray8(&clientHello->cookie, &buf[offset], bufLen - offset, &offset); + PackInteger16(&clientHello->cipherSuitesSize, &buf[offset], bufLen - offset, &offset); + PackArray16(&clientHello->cipherSuites, &buf[offset], bufLen - offset, &offset); + PackInteger8(&clientHello->compressionMethodsLen, &buf[offset], bufLen - offset, &offset); + PackArray8(&clientHello->compressionMethods, &buf[offset], bufLen - offset, &offset); + + bufOffset = offset; + if (clientHello->extensionState != MISSING_FIELD) { + PackInteger16(&clientHello->extensionLen, &buf[offset], bufLen - offset, &offset); + if (clientHello->extensionLen.state == SET_LEN_TO_ONE_BYTE) { + goto PACK_EXIT; + } + PackHsExtArrayForList(&clientHello->serverName, &buf[offset], bufLen - offset, &offset); + PackHsExtArray16(&clientHello->signatureAlgorithms, &buf[offset], bufLen - offset, &offset); + PackHsExtArray16(&clientHello->supportedGroups, &buf[offset], bufLen - offset, &offset); + PackHsExtArray8(&clientHello->pointFormats, &buf[offset], bufLen - offset, &offset); + PackHsExtSupportedVersion(&clientHello->supportedVersion, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForList(&clientHello->tls13Cookie, &buf[offset], bufLen - offset, &offset); + PackHsExtArray8(&clientHello->extendedMasterSecret, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForList(&clientHello->alpn, &buf[offset], bufLen - offset, &offset); + PackHsExtArray8(&clientHello->pskModes, &buf[offset], bufLen - offset, &offset); + PackHsExtKeyShare(&clientHello->keyshares, &buf[offset], bufLen - offset, &offset); + PackHsExtArray8(&clientHello->secRenego, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForTicket(&clientHello->sessionTicket, &buf[offset], bufLen - offset, &offset); + PackHsExtOfferedPsks(&clientHello->psks, &buf[offset], bufLen - offset, &offset); + + if (clientHello->extensionLen.state == INITIAL_FIELD) { + uint32_t extensionLen = offset - sizeof(uint16_t) - bufOffset; + BSL_Uint16ToByte(extensionLen, &buf[bufOffset]); + } + } + +PACK_EXIT: + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtUint16(const FRAME_HsExtUint16 *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += field->exLen.data; + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->data, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackHsExtServerKeyShare( + const FRAME_HsExtServerKeyShare *field, uint8_t *buf, uint32_t bufLen, uint32_t *offset) +{ + uint32_t repeats = ONE_TIME; + // This extension does not need to be assembled. + if (field->exState == MISSING_FIELD) { + return HITLS_SUCCESS; + } + // Currently, duplicate extension types can be assembled. Only one extension type can be assembled. + if (field->exState == DUPLICATE_FIELD) { + repeats = TWO_TIMES; + } + // Calculate the total length to be assembled + uint32_t length = 0; + length += ((field->exType.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += ((field->exLen.state == MISSING_FIELD) ? 0 : sizeof(uint16_t)); + length += field->exLen.data; + length *= repeats; + + // Not enough to assemble + if (bufLen < length) { + return HITLS_INTERNAL_EXCEPTION; + } + // Assembly extension type. Duplicate extensions exist. Currently, assembly is performed twice consecutively. + uint32_t bufoffset = 0; + uint32_t tmpOffset; + for (uint32_t i = 0; i < repeats; i++) { + PackInteger16(&field->exType, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + tmpOffset = bufoffset; + PackInteger16(&field->exLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->data.group, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackInteger16(&field->data.keyExchangeLen, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + PackArray8(&field->data.keyExchange, &buf[bufoffset], bufLen - bufoffset, &bufoffset); + if (field->exLen.state == INITIAL_FIELD) { + uint32_t len = bufoffset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + *offset += bufoffset; + return HITLS_SUCCESS; +} + +static int32_t PackServerHelloMsg(const FRAME_ServerHelloMsg *serverHello, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + uint32_t bufOffset; + + PackInteger16(&serverHello->version, &buf[offset], bufLen, &offset); + PackArray8(&serverHello->randomValue, &buf[offset], bufLen - offset, &offset); + PackInteger8(&serverHello->sessionIdSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&serverHello->sessionId, &buf[offset], bufLen - offset, &offset); + PackInteger16(&serverHello->cipherSuite, &buf[offset], bufLen - offset, &offset); + PackInteger8(&serverHello->compressionMethod, &buf[offset], bufLen - offset, &offset); + + bufOffset = offset; + PackInteger16(&serverHello->extensionLen, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForList(&serverHello->serverName, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForList(&serverHello->tls13Cookie, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForTicket(&serverHello->sessionTicket, &buf[offset], bufLen - offset, &offset); + PackHsExtUint16(&serverHello->supportedVersion, &buf[offset], bufLen - offset, &offset); + PackHsExtArray8(&serverHello->extendedMasterSecret, &buf[offset], bufLen - offset, &offset); + PackHsExtArrayForList(&serverHello->alpn, &buf[offset], bufLen - offset, &offset); + PackHsExtServerKeyShare(&serverHello->keyShare, &buf[offset], bufLen - offset, &offset); + // hello retry request key share + PackHsExtArray8(&serverHello->secRenego, &buf[offset], bufLen - offset, &offset); + PackHsExtArray8(&serverHello->pointFormats, &buf[offset], bufLen - offset, &offset); + // encrypt then mac + PackHsExtUint16(&serverHello->pskSelectedIdentity, &buf[offset], bufLen - offset, &offset); + + if (serverHello->extensionLen.state == INITIAL_FIELD) { + uint32_t extensionLen = offset - sizeof(uint16_t) - bufOffset; + BSL_Uint16ToByte(extensionLen, &buf[bufOffset]); + } + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackCertificateMsg(FRAME_Type *type, const FRAME_CertificateMsg *certificate, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + uint32_t bufOffset; + + if (type->versionType == HITLS_VERSION_TLS13) { + PackInteger8(&certificate->certificateReqCtxSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&certificate->certificateReqCtx, &buf[offset], bufLen - offset, &offset); + } + bufOffset = offset; + PackInteger24(&certificate->certsLen, &buf[offset], bufLen - offset, &offset); + const FrameCertItem *next = certificate->certItem; + while (next != NULL) { + if (next->state == MISSING_FIELD) { + break; + } + PackInteger24(&next->certLen, &buf[offset], bufLen - offset, &offset); + PackArray8(&next->cert, &buf[offset], bufLen - offset, &offset); + next = next->next; + if (type->versionType == HITLS_VERSION_TLS13) { + FRAME_Integer status = { INITIAL_FIELD, 0}; + PackInteger16(&status, &buf[offset], bufLen - offset, &offset); + } + } + + if (certificate->certsLen.state == INITIAL_FIELD) { + uint32_t certsLen = offset - SIZE_OF_UINT24 - bufOffset; + BSL_Uint24ToByte(certsLen, &buf[bufOffset]); + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerEcdheMsg(FRAME_Type *type, const FRAME_ServerKeyExchangeMsg *serverKeyExchange, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + // Fill in the following values in sequence: curve type, curve ID, pubkeylen, pubkey value, signature algorithm, + // signature len, and signature value. + PackInteger8(&serverKeyExchange->keyEx.ecdh.curveType, &buf[offset], bufLen, &offset); + PackInteger16(&serverKeyExchange->keyEx.ecdh.namedcurve, &buf[offset], bufLen - offset, &offset); + PackInteger8(&serverKeyExchange->keyEx.ecdh.pubKeySize, &buf[offset], bufLen- offset, &offset); + PackArray8(&serverKeyExchange->keyEx.ecdh.pubKey, &buf[offset], bufLen- offset, &offset); + if (((IS_DTLS_VERSION(type->versionType)) && (type->versionType <= HITLS_VERSION_DTLS12)) || + ((!IS_DTLS_VERSION(type->versionType)) && (type->versionType >= HITLS_VERSION_TLS12))) { + // DTLS1.2, TLS1.2, and later versions + PackInteger16(&serverKeyExchange->keyEx.ecdh.signAlgorithm, &buf[offset], bufLen- offset, &offset); + } + + PackInteger16(&serverKeyExchange->keyEx.ecdh.signSize, &buf[offset], bufLen- offset, &offset); + PackArray8(&serverKeyExchange->keyEx.ecdh.signData, &buf[offset], bufLen- offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerDheMsg(FRAME_Type *type, const FRAME_ServerKeyExchangeMsg *serverKeyExchange, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + // Fill in the following values in sequence: plen, p value, glen, g value, pubkeylen, pubkey value, + // signature algorithm, signature len, and signature value. + PackInteger16(&serverKeyExchange->keyEx.dh.plen, &buf[offset], bufLen, &offset); + PackArray8(&serverKeyExchange->keyEx.dh.p, &buf[offset], bufLen - offset, &offset); + PackInteger16(&serverKeyExchange->keyEx.dh.glen, &buf[offset], bufLen - offset, &offset); + PackArray8(&serverKeyExchange->keyEx.dh.g, &buf[offset], bufLen - offset, &offset); + PackInteger16(&serverKeyExchange->keyEx.dh.pubKeyLen, &buf[offset], bufLen- offset, &offset); + PackArray8(&serverKeyExchange->keyEx.dh.pubKey, &buf[offset], bufLen- offset, &offset); + if (((IS_DTLS_VERSION(type->versionType)) && (type->versionType <= HITLS_VERSION_DTLS12)) || + ((!IS_DTLS_VERSION(type->versionType)) && (type->versionType >= HITLS_VERSION_TLS12))) { + // DTLS1.2, TLS1.2, and later versions + PackInteger16(&serverKeyExchange->keyEx.dh.signAlgorithm, &buf[offset], bufLen- offset, &offset); + } + PackInteger16(&serverKeyExchange->keyEx.dh.signSize, &buf[offset], bufLen- offset, &offset); + PackArray8(&serverKeyExchange->keyEx.dh.signData, &buf[offset], bufLen- offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerEccMsg(const FRAME_ServerKeyExchangeMsg *serverKeyExchange, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + PackInteger16(&serverKeyExchange->keyEx.ecdh.signSize, &buf[offset], bufLen- offset, &offset); + PackArray8(&serverKeyExchange->keyEx.ecdh.signData, &buf[offset], bufLen- offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerKeyExchangeMsg(FRAME_Type *type, const FRAME_ServerKeyExchangeMsg *serverKeyExchange, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + // Currently, ECDHE and DHE key exchange packets can be assembled. + if (type->keyExType == HITLS_KEY_EXCH_ECDHE) { + return PackServerEcdheMsg(type, serverKeyExchange, buf, bufLen, usedLen); + } else if (type->keyExType == HITLS_KEY_EXCH_DHE) { + return PackServerDheMsg(type, serverKeyExchange, buf, bufLen, usedLen); + } else if (type->keyExType == HITLS_KEY_EXCH_ECC) { + return PackServerEccMsg(serverKeyExchange, buf, bufLen, usedLen); + } + + return HITLS_PACK_UNSUPPORT_KX_ALG; +} + +static int32_t PackCertificateRequestExt(uint32_t type, const FRAME_CertificateRequestMsg *certificateRequest, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + FRAME_Integer exType; + FRAME_Integer size; + switch (type) { + case HS_EX_TYPE_SIGNATURE_ALGORITHMS: + exType.data = HS_EX_TYPE_SIGNATURE_ALGORITHMS; + exType.state = INITIAL_FIELD; + PackInteger16(&exType, &buf[offset], bufLen, &offset); + size.data = certificateRequest->signatureAlgorithmsSize.data + sizeof(uint16_t); + size.state = INITIAL_FIELD; + PackInteger16(&size, &buf[offset], bufLen, &offset); + + PackInteger16(&certificateRequest->signatureAlgorithmsSize, &buf[offset], bufLen, &offset); + PackArray16(&certificateRequest->signatureAlgorithms, &buf[offset], bufLen - offset, &offset); + + break; + default: + break; + } + + *usedLen += offset; + return HITLS_SUCCESS; +} + +static int32_t PackCertificateRequestMsg(FRAME_Type *type, const FRAME_CertificateRequestMsg *certificateRequest, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + if (certificateRequest->state == MISSING_FIELD){ + return HITLS_SUCCESS; + } + if (type->versionType != HITLS_VERSION_TLS13) { + PackInteger8(&certificateRequest->certTypesSize, &buf[offset], bufLen, &offset); + PackArray8(&certificateRequest->certTypes, &buf[offset], bufLen - offset, &offset); + PackInteger16(&certificateRequest->signatureAlgorithmsSize, &buf[offset], bufLen, &offset); + PackArray16(&certificateRequest->signatureAlgorithms, &buf[offset], bufLen - offset, &offset); + PackInteger16(&certificateRequest->distinguishedNamesSize, &buf[offset], bufLen, &offset); + PackArray8(&certificateRequest->distinguishedNames, &buf[offset], bufLen - offset, &offset); + } else { + PackInteger8(&certificateRequest->certificateReqCtxSize, &buf[offset], bufLen, &offset); + PackArray8(&certificateRequest->certificateReqCtx, &buf[offset], bufLen - offset, &offset); + // Packaged extension + uint32_t tmpOffset = offset; + PackInteger16(&certificateRequest->exMsgLen, &buf[offset], bufLen, &offset); + + bool ifPackSign = (certificateRequest->signatureAlgorithmsSize.state != MISSING_FIELD); + + // Package HS_EX_TYPE_SIGNATURE_ALGORITHMS Extensions + if(ifPackSign) { + PackCertificateRequestExt(HS_EX_TYPE_SIGNATURE_ALGORITHMS, certificateRequest, &buf[offset], + bufLen - offset, &offset); + } + if(certificateRequest->signatureAlgorithmsSize.state == DUPLICATE_FIELD) { + PackCertificateRequestExt(HS_EX_TYPE_SIGNATURE_ALGORITHMS, certificateRequest, &buf[offset], + bufLen - offset, &offset); + } + if (certificateRequest->exMsgLen.state == INITIAL_FIELD) { + uint32_t len = offset - sizeof(uint16_t) - tmpOffset; + BSL_Uint16ToByte(len, &buf[tmpOffset]); + } + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerHelloDoneMsg(const FRAME_ServerHelloDoneMsg *serverHelloDone, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + /* The ServerHelloDone packet is an empty packet. Extra data is assembled here to construct abnormal packets. */ + PackArray8(&serverHelloDone->extra, &buf[offset], bufLen, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientEcdheMsg(FRAME_Type *type, const FRAME_ClientKeyExchangeMsg *clientKeyExchange, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; +#ifndef HITLS_NO_TLCP11 + if (type->versionType == HITLS_VERSION_TLCP11) { /* Three bytes are added to the client key exchange. */ + buf[offset] = HITLS_EC_CURVE_TYPE_NAMED_CURVE; + offset += sizeof(uint8_t); + BSL_Uint16ToByte(HITLS_EC_GROUP_SM2, &buf[offset]); + offset += sizeof(uint16_t); + } +#endif + PackInteger8(&clientKeyExchange->pubKeySize, &buf[offset], bufLen, &offset); + PackArray8(&clientKeyExchange->pubKey, &buf[offset], bufLen - offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientDheMsg(const FRAME_ClientKeyExchangeMsg *clientKeyExchange, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + PackInteger16(&clientKeyExchange->pubKeySize, &buf[offset], bufLen, &offset); + PackArray8(&clientKeyExchange->pubKey, &buf[offset], bufLen - offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientKeyExchangeMsg(FRAME_Type *type, const FRAME_ClientKeyExchangeMsg *clientKeyExchange, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + // Currently, ECDHE and DHE key exchange packets can be assembled. + if (type->keyExType == HITLS_KEY_EXCH_ECDHE) { + return PackClientEcdheMsg(type, clientKeyExchange, buf, bufLen, usedLen); + } else if (type->keyExType == HITLS_KEY_EXCH_DHE) { + return PackClientDheMsg(clientKeyExchange, buf, bufLen, usedLen); + } + + return HITLS_PACK_UNSUPPORT_KX_ALG; +} + +static int32_t PackCertificateVerifyMsg(FRAME_Type *type, const FRAME_CertificateVerifyMsg *certificateVerify, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + if (((IS_DTLS_VERSION(type->versionType)) && (type->versionType <= HITLS_VERSION_DTLS12)) || + ((!IS_DTLS_VERSION(type->versionType)) && (type->versionType >= HITLS_VERSION_TLS12))) { + // DTLS1.2, TLS1.2, and later versions + PackInteger16(&certificateVerify->signHashAlg, &buf[offset], bufLen, &offset); + } + PackInteger16(&certificateVerify->signSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&certificateVerify->sign, &buf[offset], bufLen - offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackFinishedMsg(const FRAME_FinishedMsg *finished, uint8_t *buf, + uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + PackArray8(&finished->verifyData, &buf[offset], bufLen - offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static void PackHsMsgHeader(uint16_t version, const FRAME_HsMsg *hsMsg, uint32_t bodyLen, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + uint32_t bufOffset; + + PackInteger8(&hsMsg->type, &buf[offset], bufLen, &offset); + + bufOffset = offset; + PackInteger24(&hsMsg->length, &buf[offset], bufLen - offset, &offset); + if (IS_DTLS_VERSION(version)) { + PackInteger16(&hsMsg->sequence, &buf[offset], bufLen - offset, &offset); + PackInteger24(&hsMsg->fragmentOffset, &buf[offset], bufLen - offset, &offset); + if (hsMsg->fragmentLength.state == INITIAL_FIELD) { + BSL_Uint24ToByte(bodyLen, &buf[offset]); + offset += SIZE_OF_UINT24; + } else { + PackInteger24(&hsMsg->fragmentLength, &buf[offset], bufLen - offset, &offset); + } + } + + if (hsMsg->length.state == INITIAL_FIELD) { + BSL_Uint24ToByte(bodyLen, &buf[bufOffset]); + } + + *usedLen = offset; +} + +static int32_t PackNewSessionTicketMsg(FRAME_Type *type, const FRAME_NewSessionTicketMsg *newSessionTicket, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + PackInteger32(&newSessionTicket->ticketLifetime, &buf[offset], bufLen - offset, &offset); + if (type->versionType != HITLS_VERSION_TLS13) { + PackInteger16(&newSessionTicket->ticketSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&newSessionTicket->ticket, &buf[offset], bufLen - offset, &offset); + } else { + PackInteger32(&newSessionTicket->ticketAgeAdd, &buf[offset], bufLen - offset, &offset); + PackInteger8(&newSessionTicket->ticketNonceSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&newSessionTicket->ticketNonce, &buf[offset], bufLen - offset, &offset); + PackInteger16(&newSessionTicket->ticketSize, &buf[offset], bufLen - offset, &offset); + PackArray8(&newSessionTicket->ticket, &buf[offset], bufLen - offset, &offset); + PackInteger16(&newSessionTicket->extensionLen, &buf[offset], bufLen - offset, &offset); + } + *usedLen = offset; + if (offset != bufLen) { + return HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + } + return HITLS_SUCCESS; +} + +static int32_t PackHsMsgBody(FRAME_Type *type, const FRAME_Msg *msg, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret; + + const FRAME_HsMsg *hsMsg = &(msg->body.hsMsg); + + switch (type->handshakeType) { + case CLIENT_HELLO: + ret = PackClientHelloMsg(&(hsMsg->body.clientHello), buf, bufLen, usedLen); + break; + case SERVER_HELLO: + ret = PackServerHelloMsg(&(hsMsg->body.serverHello), buf, bufLen, usedLen); + break; + case CERTIFICATE: + ret = PackCertificateMsg(type, &(hsMsg->body.certificate), buf, bufLen, usedLen); + break; + case SERVER_KEY_EXCHANGE: + ret = PackServerKeyExchangeMsg(type, &(hsMsg->body.serverKeyExchange), buf, bufLen, usedLen); + break; + case CERTIFICATE_REQUEST: + ret = PackCertificateRequestMsg(type, &(hsMsg->body.certificateReq), buf, bufLen, usedLen); + break; + case SERVER_HELLO_DONE: + ret = PackServerHelloDoneMsg(&(hsMsg->body.serverHelloDone), buf, bufLen, usedLen); + break; + case CLIENT_KEY_EXCHANGE: + ret = PackClientKeyExchangeMsg(type, &(hsMsg->body.clientKeyExchange), buf, bufLen, usedLen); + break; + case CERTIFICATE_VERIFY: + ret = PackCertificateVerifyMsg(type, &(hsMsg->body.certificateVerify), buf, bufLen, usedLen); + break; + case FINISHED: + ret = PackFinishedMsg(&(hsMsg->body.finished), buf, bufLen, usedLen); + break; + case NEW_SESSION_TICKET: + ret = PackNewSessionTicketMsg(type, &(hsMsg->body.newSessionTicket), buf, bufLen, usedLen); + break; + default: + ret = HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + break; + } + + return ret; +} + +static int32_t PackHandShakeMsg(FRAME_Type *type, const FRAME_Msg *msg, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + const FRAME_HsMsg *hsMsg = &(msg->body.hsMsg); + uint32_t ret; + uint32_t offset; + uint32_t bodyMaxLen; + uint32_t headerLen; + uint32_t bodyLen = 0; + + if (IS_DTLS_VERSION(type->versionType)) { // DTLS + if (bufLen < DTLS_HS_MSG_HEADER_SIZE) { + return HITLS_INTERNAL_EXCEPTION; + } + + bodyMaxLen = bufLen - DTLS_HS_MSG_HEADER_SIZE; + offset = DTLS_HS_MSG_HEADER_SIZE; + headerLen = DTLS_HS_MSG_HEADER_SIZE; + } else { // TLS + if (bufLen < HS_MSG_HEADER_SIZE) { + return HITLS_INTERNAL_EXCEPTION; + } + + bodyMaxLen = bufLen - HS_MSG_HEADER_SIZE; + offset = HS_MSG_HEADER_SIZE; + headerLen = HS_MSG_HEADER_SIZE; + } + + // Assemble the body of the handshake message. + ret = PackHsMsgBody(type, msg, &buf[offset], bodyMaxLen, &bodyLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + // Assemble the handshake packet header. + PackHsMsgHeader(type->versionType, hsMsg, bodyLen, buf, headerLen, &headerLen); + + // Splicing body and head + // If some fields are missing in the header, the packet body is filled with an offset forward. + if (headerLen != offset) { + ret = memmove_s(&buf[headerLen], bufLen - headerLen, &buf[offset], bodyLen); + if (ret != EOK) { + return ret; + } + } + *usedLen = headerLen + bodyLen; + return ret; +} + +static int32_t PackCcsMsg(const FRAME_Msg *msg, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + PackInteger8(&msg->body.ccsMsg.ccsType, &buf[offset], bufLen, &offset); + /* Extra data is used to construct abnormal packets. */ + PackArray8(&msg->body.ccsMsg.extra, &buf[offset], bufLen - offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackAlertMsg(const FRAME_Msg *msg, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + PackInteger8(&msg->body.alertMsg.alertLevel, &buf[offset], bufLen, &offset); + PackInteger8(&msg->body.alertMsg.alertDescription, &buf[offset], bufLen - offset, &offset); + /* Extra data is used to construct abnormal packets. */ + PackArray8(&msg->body.alertMsg.extra, &buf[offset], bufLen - offset, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackAppMsg(const FRAME_Msg *msg, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + PackArray8(&msg->body.appMsg.appData, &buf[offset], bufLen, &offset); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackRecordHeader(uint16_t version, const FRAME_Msg *msg, uint32_t bodyLen, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0; + + PackInteger8(&msg->recType, &buf[offset], bufLen, &offset); + PackInteger16(&msg->recVersion, &buf[offset], bufLen - offset, &offset); + if (IS_DTLS_VERSION(version)) { + PackInteger16(&msg->epoch, &buf[offset], bufLen - offset, &offset); + PackInteger48(&msg->sequence, &buf[offset], bufLen - offset, &offset); + } + + if (msg->length.state == INITIAL_FIELD) { + BSL_Uint16ToByte(bodyLen, &buf[offset]); + offset += sizeof(uint16_t); + } else { + PackInteger16(&msg->length, &buf[offset], bufLen - offset, &offset); + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +int32_t FRAME_PackRecordBody(FRAME_Type *frameType, const FRAME_Msg *msg, + uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret; + + // pack Body + switch (frameType->recordType) { + case REC_TYPE_HANDSHAKE: + ret = PackHandShakeMsg(frameType, msg, buffer, bufLen, usedLen); + break; + case REC_TYPE_CHANGE_CIPHER_SPEC: + ret = PackCcsMsg(msg, buffer, bufLen, usedLen); + break; + case REC_TYPE_ALERT: + ret = PackAlertMsg(msg, buffer, bufLen, usedLen); + break; + case REC_TYPE_APP: + ret = PackAppMsg(msg, buffer, bufLen, usedLen); + break; + default: + ret = HITLS_INTERNAL_EXCEPTION; + break; + } + + return ret; +} + +int32_t FRAME_PackMsg(FRAME_Type *frameType, const FRAME_Msg *msg, uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret; + uint32_t offset; + uint32_t bodyMaxLen; + uint32_t headerLen; + uint32_t bodyLen = 0; + + if (msg == NULL || buffer == NULL || usedLen == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (IS_DTLS_VERSION(frameType->versionType)) { // DTLS + if (bufLen < DTLS_RECORD_HEADER_LEN) { + return HITLS_INTERNAL_EXCEPTION; + } + + bodyMaxLen = bufLen - DTLS_RECORD_HEADER_LEN; + offset = DTLS_RECORD_HEADER_LEN; + headerLen = DTLS_RECORD_HEADER_LEN; + } else { // TLS + if (bufLen < TLS_RECORD_HEADER_LEN) { + return HITLS_INTERNAL_EXCEPTION; + } + + bodyMaxLen = bufLen - TLS_RECORD_HEADER_LEN; + offset = TLS_RECORD_HEADER_LEN; + headerLen = TLS_RECORD_HEADER_LEN; + } + + // Assemble the message body. + ret = FRAME_PackRecordBody(frameType, msg, &buffer[offset], bodyMaxLen, &bodyLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + // Assemble the packet header. + PackRecordHeader(frameType->versionType, msg, bodyLen, buffer, headerLen, &headerLen); + + // Splicing body and head + // If some fields are missing in the header, the packet body is filled with an offset forward. + if (headerLen != offset) { + ret = memmove_s(&buffer[headerLen], bufLen - headerLen, &buffer[offset], bodyLen); + if (ret != EOK) { + return ret; + } + } + *usedLen = headerLen + bodyLen; + return ret; +} diff --git a/testcode/framework/tls/msg/src/frame_parse_msg.c b/testcode/framework/tls/msg/src/frame_parse_msg.c new file mode 100644 index 00000000..2be8b3cf --- /dev/null +++ b/testcode/framework/tls/msg/src/frame_parse_msg.c @@ -0,0 +1,1225 @@ +/* + * 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 "securec.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_extensions.h" +#include "frame_tls.h" +#include "frame_msg.h" + +#define SIZE_OF_UINT_24 3u +#define SIZE_OF_UINT_48 6u + +static int32_t ParseFieldInteger8(const uint8_t *buffer, uint32_t bufLen, FRAME_Integer *field, uint32_t *offset) +{ + if (bufLen < sizeof(uint8_t)) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->state = INITIAL_FIELD; + field->data = buffer[0]; + *offset += sizeof(uint8_t); + return HITLS_SUCCESS; +} + +static int32_t ParseFieldInteger16(const uint8_t *buffer, uint32_t bufLen, FRAME_Integer *field, uint32_t *offset) +{ + if (bufLen < sizeof(uint16_t)) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->state = INITIAL_FIELD; + field->data = BSL_ByteToUint16(buffer); + *offset += sizeof(uint16_t); + return HITLS_SUCCESS; +} + +static int32_t ParseFieldInteger24(const uint8_t *buffer, uint32_t bufLen, FRAME_Integer *field, uint32_t *offset) +{ + if (bufLen < SIZE_OF_UINT_24) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->state = INITIAL_FIELD; + field->data = BSL_ByteToUint24(buffer); + *offset += SIZE_OF_UINT_24; + return HITLS_SUCCESS; +} + +static int32_t ParseFieldInteger32(const uint8_t *buffer, uint32_t bufLen, FRAME_Integer *field, uint32_t *offset) +{ + if (bufLen < sizeof(uint32_t)) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->state = INITIAL_FIELD; + field->data = BSL_ByteToUint32(buffer); + *offset += sizeof(uint32_t); + return HITLS_SUCCESS; +} + +static int32_t ParseFieldInteger48(const uint8_t *buffer, uint32_t bufLen, FRAME_Integer *field, uint32_t *offset) +{ + if (bufLen < SIZE_OF_UINT_48) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->state = INITIAL_FIELD; + field->data = BSL_ByteToUint48(buffer); + *offset += SIZE_OF_UINT_48; + return HITLS_SUCCESS; +} + +static int32_t ParseFieldArray8(const uint8_t *buffer, uint32_t bufLen, FRAME_Array8 *field, uint32_t fieldLen, + uint32_t *offset) +{ + if (bufLen < fieldLen) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->data = BSL_SAL_Dump(buffer, fieldLen); + if (field->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + field->size = fieldLen; + field->state = INITIAL_FIELD; + *offset += fieldLen; + return HITLS_SUCCESS; +} + +static int32_t ParseFieldArray16(const uint8_t *buffer, uint32_t bufLen, FRAME_Array16 *field, uint32_t fieldLen, + uint32_t *offset) +{ + if ((bufLen < fieldLen) || (fieldLen % sizeof(uint16_t) != 0)) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + field->data = BSL_SAL_Calloc(1u, fieldLen); + if (field->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + field->size = fieldLen / sizeof(uint16_t); + for (uint32_t i = 0; i < field->size; i++) { + field->data[i] = BSL_ByteToUint16(&buffer[i * sizeof(uint16_t)]); + } + field->state = INITIAL_FIELD; + *offset += fieldLen; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtArray8(const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtArray8 *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger8(&buffer[exOffset], bufLen - exOffset, &field->exDataLen, &exOffset); + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->exData, field->exDataLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtArrayForList( + const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtArray8 *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exDataLen, &exOffset); + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->exData, field->exDataLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsSessionTicketExtArray8( + const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtArray8 *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exDataLen, &exOffset); + if (field->exDataLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->exData, field->exDataLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtArray16(const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtArray16 *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen - exOffset, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exDataLen, &exOffset); + ParseFieldArray16(&buffer[exOffset], bufLen - exOffset, &field->exData, field->exDataLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtPskIdentity(const uint8_t *buffer, uint32_t bufLen, FRAME_HsArrayPskIdentity *field, + uint32_t fieldLen, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->state = INITIAL_FIELD; + uint32_t size = 0; + FRAME_Integer tmpIdentityLen = { 0 }; + while (exOffset < fieldLen) { + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &tmpIdentityLen, &exOffset); + exOffset += (tmpIdentityLen.data + sizeof(uint32_t)); + if (exOffset <= fieldLen) { + size++; + } + } + if (size == 0) { + return HITLS_SUCCESS; + } + field->data = BSL_SAL_Calloc(size, sizeof(FRAME_HsPskIdentity)); + if (field->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + field->size = size; + exOffset = 0; + for (uint32_t i = 0; i < size; i++) { + field->data[i].state = INITIAL_FIELD; + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->data[i].identityLen, &exOffset); + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->data[i].identity, + field->data[i].identityLen.data, &exOffset); + ParseFieldInteger32(&buffer[exOffset], bufLen - exOffset, &field->data[i].obfuscatedTicketAge, &exOffset); + } + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtPskBinder(const uint8_t *buffer, uint32_t bufLen, FRAME_HsArrayPskBinder *field, + uint32_t fieldLen, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->state = INITIAL_FIELD; + uint32_t size = 0; + FRAME_Integer tmpBinderLen = { 0 }; + while (exOffset < fieldLen) { + ParseFieldInteger8(&buffer[exOffset], bufLen - exOffset, &tmpBinderLen, &exOffset); + exOffset += tmpBinderLen.data; + if (exOffset <= fieldLen) { + size++; + } + } + if (size == 0) { + return HITLS_SUCCESS; + } + field->data = BSL_SAL_Calloc(size, sizeof(FRAME_HsPskBinder)); + if (field->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + field->size = size; + exOffset = 0; + for (uint32_t i = 0; i < size; i++) { + field->data[i].state = INITIAL_FIELD; + ParseFieldInteger8(&buffer[exOffset], bufLen - exOffset, &field->data[i].binderLen, &exOffset); + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->data[i].binder, + field->data[i].binderLen.data, &exOffset); + } + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtPsk(const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtOfferedPsks *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen - exOffset, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->identitySize, &exOffset); + ParseHsExtPskIdentity(&buffer[exOffset], bufLen - exOffset, &field->identities, + field->identitySize.data, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->binderSize, &exOffset); + ParseHsExtPskBinder(&buffer[exOffset], bufLen - exOffset, &field->binders, field->binderSize.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtArrayKeyShare(const uint8_t *buffer, uint32_t bufLen, FRAME_HsArrayKeyShare *field, + uint32_t fieldLen, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->state = INITIAL_FIELD; + uint32_t size = 0; + FRAME_Integer tmpIdentityLen = { 0 }; + while (exOffset < fieldLen) { + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &tmpIdentityLen, &exOffset); // group + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &tmpIdentityLen, &exOffset); // key_exchange len + exOffset += tmpIdentityLen.data; + if (exOffset <= fieldLen) { + size++; + } + } + if (size == 0) { + return HITLS_SUCCESS; + } + field->data = BSL_SAL_Calloc(size, sizeof(FRAME_HsKeyShareEntry)); + if (field->data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + field->size = size; + exOffset = 0; + for (uint32_t i = 0; i < size; i++) { + field->data[i].state = INITIAL_FIELD; + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->data[i].group, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->data[i].keyExchangeLen, &exOffset); + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->data[i].keyExchange, + field->data[i].keyExchangeLen.data, &exOffset); + } + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtKeyShare(const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtKeyShare *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen - exOffset, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exKeyShareLen, &exOffset); + ParseHsExtArrayKeyShare(&buffer[exOffset], bufLen - exOffset, &field->exKeyShares, + field->exKeyShareLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsSupportedVersion(const uint8_t *buffer, uint32_t bufLen, + FRAME_HsExtArray16 *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen - exOffset, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger8(&buffer[exOffset], bufLen - exOffset, &field->exDataLen, &exOffset); + ParseFieldArray16(&buffer[exOffset], bufLen - exOffset, &field->exData, field->exDataLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseClientHelloMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_ClientHelloMsg *clientHello, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger16(&buffer[0], bufLen, &clientHello->version, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &clientHello->randomValue, HS_RANDOM_SIZE, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &clientHello->sessionIdSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &clientHello->sessionId, + clientHello->sessionIdSize.data, &offset); + if (IS_DTLS_VERSION(frameType->versionType)) { + ParseFieldInteger8(&buffer[offset], bufLen - offset, &clientHello->cookiedLen, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &clientHello->cookie, clientHello->cookiedLen.data, &offset); + } + ParseFieldInteger16(&buffer[offset], bufLen - offset, &clientHello->cipherSuitesSize, &offset); + ParseFieldArray16(&buffer[offset], bufLen - offset, &clientHello->cipherSuites, + clientHello->cipherSuitesSize.data, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &clientHello->compressionMethodsLen, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &clientHello->compressionMethods, + clientHello->compressionMethodsLen.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &clientHello->extensionLen, &offset); + clientHello->extensionState = INITIAL_FIELD; + + /* Parsing extended fields */ + while (offset < bufLen) { + FRAME_Integer tmpField = {0}; + uint32_t tmpOffset = offset; + ParseFieldInteger16(&buffer[tmpOffset], bufLen - tmpOffset, &tmpField, &tmpOffset); + switch (tmpField.data) { + case HS_EX_TYPE_POINT_FORMATS: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &clientHello->pointFormats, &offset); + break; + case HS_EX_TYPE_SUPPORTED_GROUPS: + ParseHsExtArray16(&buffer[offset], bufLen - offset, &clientHello->supportedGroups, &offset); + break; + case HS_EX_TYPE_SIGNATURE_ALGORITHMS: + ParseHsExtArray16(&buffer[offset], bufLen - offset, &clientHello->signatureAlgorithms, &offset); + break; + case HS_EX_TYPE_EXTENDED_MASTER_SECRET: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &clientHello->extendedMasterSecret, &offset); + break; + case HS_EX_TYPE_RENEGOTIATION_INFO: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &clientHello->secRenego, &offset); + break; + case HS_EX_TYPE_SESSION_TICKET: + ParseHsSessionTicketExtArray8(&buffer[offset], bufLen - offset, &clientHello->sessionTicket, &offset); + break; + case HS_EX_TYPE_SERVER_NAME: + ParseHsExtArrayForList(&buffer[offset], bufLen - offset, &clientHello->serverName, &offset); + break; + case HS_EX_TYPE_APP_LAYER_PROTOCOLS: + ParseHsExtArrayForList(&buffer[offset], bufLen - offset, &clientHello->alpn, &offset); + break; + case HS_EX_TYPE_KEY_SHARE: + ParseHsExtKeyShare(&buffer[offset], bufLen - offset, &clientHello->keyshares, &offset); + break; + case HS_EX_TYPE_PRE_SHARED_KEY: + ParseHsExtPsk(&buffer[offset], bufLen - offset, &clientHello->psks, &offset); + break; + case HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &clientHello->pskModes, &offset); + break; + case HS_EX_TYPE_SUPPORTED_VERSIONS: + ParseHsSupportedVersion(&buffer[offset], bufLen - offset, &clientHello->supportedVersion, &offset); + break; + case HS_EX_TYPE_COOKIE: + ParseHsExtArrayForList(&buffer[offset], bufLen - offset, &clientHello->tls13Cookie, &offset); + break; + default: /* Unrecognized extension. Skip parsing the extension. */ + ParseFieldInteger16(&buffer[tmpOffset], bufLen - tmpOffset, &tmpField, &tmpOffset); + tmpOffset += tmpField.data; + offset = tmpOffset; + break; + } + } + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanClientHelloMsg(FRAME_ClientHelloMsg *clientHello) +{ + BSL_SAL_FREE(clientHello->randomValue.data); + BSL_SAL_FREE(clientHello->sessionId.data); + BSL_SAL_FREE(clientHello->cookie.data); + BSL_SAL_FREE(clientHello->cipherSuites.data); + BSL_SAL_FREE(clientHello->compressionMethods.data); + BSL_SAL_FREE(clientHello->pointFormats.exData.data); + BSL_SAL_FREE(clientHello->supportedGroups.exData.data); + BSL_SAL_FREE(clientHello->signatureAlgorithms.exData.data); + BSL_SAL_FREE(clientHello->extendedMasterSecret.exData.data); + BSL_SAL_FREE(clientHello->secRenego.exData.data); + BSL_SAL_FREE(clientHello->sessionTicket.exData.data); + BSL_SAL_FREE(clientHello->serverName.exData.data); + BSL_SAL_FREE(clientHello->alpn.exData.data); + for (uint32_t i = 0; i < clientHello->keyshares.exKeyShares.size; i++) { + BSL_SAL_FREE(clientHello->keyshares.exKeyShares.data[i].keyExchange.data); + } + for (uint32_t i = 0; i < clientHello->psks.identities.size; i++) { + BSL_SAL_FREE(clientHello->psks.identities.data[i].identity.data); + } + for (uint32_t i = 0; i < clientHello->psks.binders.size; i++) { + BSL_SAL_FREE(clientHello->psks.binders.data[i].binder.data); + } + BSL_SAL_FREE(clientHello->keyshares.exKeyShares.data); + BSL_SAL_FREE(clientHello->psks.binders.data); + BSL_SAL_FREE(clientHello->psks.identities.data); + BSL_SAL_FREE(clientHello->supportedVersion.exData.data); + BSL_SAL_FREE(clientHello->tls13Cookie.exData.data); + BSL_SAL_FREE(clientHello->pskModes.exData.data); + return; +} + +static int32_t ParseHsExtUint16(const uint8_t *buffer, uint32_t bufLen, FRAME_HsExtUint16 *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseHsExtServerKeyShare(const uint8_t *buffer, uint32_t bufLen, + FRAME_HsExtServerKeyShare *field, uint32_t *offset) +{ + uint32_t exOffset = 0; + field->exState = INITIAL_FIELD; + ParseFieldInteger16(&buffer[0], bufLen, &field->exType, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->exLen, &exOffset); + if (field->exLen.data == 0u) { + *offset += exOffset; + return HITLS_SUCCESS; + } + field->data.state = INITIAL_FIELD; + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->data.group, &exOffset); + ParseFieldInteger16(&buffer[exOffset], bufLen - exOffset, &field->data.keyExchangeLen, &exOffset); + ParseFieldArray8(&buffer[exOffset], bufLen - exOffset, &field->data.keyExchange, + field->data.keyExchangeLen.data, &exOffset); + *offset += exOffset; + return HITLS_SUCCESS; +} + +static int32_t ParseServerHelloMsg(const uint8_t *buffer, uint32_t bufLen, FRAME_ServerHelloMsg *serverHello, + uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger16(&buffer[0], bufLen, &serverHello->version, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &serverHello->randomValue, HS_RANDOM_SIZE, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &serverHello->sessionIdSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &serverHello->sessionId, + serverHello->sessionIdSize.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &serverHello->cipherSuite, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &serverHello->compressionMethod, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &serverHello->extensionLen, &offset); + + /* Parsing extended fields */ + while (offset < bufLen) { + FRAME_Integer tmpField = {0}; + uint32_t tmpOffset = offset; + ParseFieldInteger16(&buffer[tmpOffset], bufLen - tmpOffset, &tmpField, &tmpOffset); + switch (tmpField.data) { + case HS_EX_TYPE_POINT_FORMATS: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &serverHello->pointFormats, &offset); + break; + case HS_EX_TYPE_EXTENDED_MASTER_SECRET: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &serverHello->extendedMasterSecret, &offset); + break; + case HS_EX_TYPE_RENEGOTIATION_INFO: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &serverHello->secRenego, &offset); + break; + case HS_EX_TYPE_SESSION_TICKET: + ParseHsSessionTicketExtArray8(&buffer[offset], bufLen - offset, &serverHello->sessionTicket, &offset); + break; + case HS_EX_TYPE_SERVER_NAME: + ParseHsExtArrayForList(&buffer[offset], bufLen - offset, &serverHello->serverName, &offset); + break; + case HS_EX_TYPE_APP_LAYER_PROTOCOLS: + ParseHsExtArrayForList(&buffer[offset], bufLen - offset, &serverHello->alpn, &offset); + break; + case HS_EX_TYPE_SUPPORTED_VERSIONS: + ParseHsExtUint16(&buffer[offset], bufLen - offset, &serverHello->supportedVersion, &offset); + break; + case HS_EX_TYPE_KEY_SHARE: + ParseHsExtServerKeyShare(&buffer[offset], bufLen - offset, &serverHello->keyShare, &offset); + break; + case HS_EX_TYPE_PRE_SHARED_KEY: + ParseHsExtUint16(&buffer[offset], bufLen - offset, &serverHello->pskSelectedIdentity, &offset); + break; + case HS_EX_TYPE_COOKIE: + ParseHsExtArray8(&buffer[offset], bufLen - offset, &serverHello->tls13Cookie, &offset); + break; + default: /* Unrecognized extension, return error */ + *parseLen += offset; + return HITLS_PARSE_UNSUPPORTED_EXTENSION; + } + } + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanServerHelloMsg(FRAME_ServerHelloMsg *serverHello) +{ + BSL_SAL_FREE(serverHello->randomValue.data); + BSL_SAL_FREE(serverHello->sessionId.data); + BSL_SAL_FREE(serverHello->pointFormats.exData.data); + BSL_SAL_FREE(serverHello->extendedMasterSecret.exData.data); + BSL_SAL_FREE(serverHello->secRenego.exData.data); + BSL_SAL_FREE(serverHello->sessionTicket.exData.data); + BSL_SAL_FREE(serverHello->serverName.exData.data); + BSL_SAL_FREE(serverHello->alpn.exData.data); + BSL_SAL_FREE(serverHello->keyShare.data.keyExchange.data); + BSL_SAL_FREE(serverHello->tls13Cookie.exData.data); + return; +} + +static int32_t ParseCertificateMsg( + FRAME_Type *type, const uint8_t *buffer, uint32_t bufLen, FRAME_CertificateMsg *certificate, uint32_t *parseLen) +{ + uint32_t offset = 0; + if (type->versionType == HITLS_VERSION_TLS13) { + ParseFieldInteger8(&buffer[0], bufLen, &certificate->certificateReqCtxSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &certificate->certificateReqCtx, + certificate->certificateReqCtxSize.data, &offset); + } + ParseFieldInteger24(&buffer[offset], bufLen - offset, &certificate->certsLen, &offset); + if (certificate->certsLen.data == 0) { + *parseLen += offset; + return HITLS_SUCCESS; + } + + FrameCertItem *certItem = NULL; + while (offset < bufLen) { + FrameCertItem *item = BSL_SAL_Calloc(1u, sizeof(FrameCertItem)); + if (item == NULL) { + return HITLS_MEMALLOC_FAIL; + } + item->state = INITIAL_FIELD; + ParseFieldInteger24(&buffer[offset], bufLen - offset, &item->certLen, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &item->cert, item->certLen.data, &offset); + if (certificate->certItem == NULL) { + certificate->certItem = item; + } else { + certItem->next = item; + } + certItem = item; + if (type->versionType == HITLS_VERSION_TLS13) { + FRAME_Integer status; + ParseFieldInteger16(&buffer[offset], bufLen - offset, &status, &offset); + } + } + *parseLen += offset; + + return HITLS_SUCCESS; +} + +static void CleanCertificateMsg(FRAME_CertificateMsg *certificate) +{ + BSL_SAL_FREE(certificate->certificateReqCtx.data); + FrameCertItem *certItem = certificate->certItem; + while (certItem != NULL) { + FrameCertItem *temp = certItem->next; + BSL_SAL_FREE(certItem->cert.data); + BSL_SAL_FREE(certItem); + certItem = temp; + } + certificate->certItem = NULL; + return; +} + +static int32_t ParseServerKxEcdhMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_ServerEcdh *ecdh, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger8(&buffer[0], bufLen, &ecdh->curveType, &offset); + if (ecdh->curveType.data != HITLS_EC_CURVE_TYPE_NAMED_CURVE) { + return HITLS_PARSE_UNSUPPORT_KX_ALG; + } + ParseFieldInteger16(&buffer[offset], bufLen - offset, &ecdh->namedcurve, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &ecdh->pubKeySize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &ecdh->pubKey, ecdh->pubKeySize.data, &offset); + if (((!IS_DTLS_VERSION(frameType->versionType)) && (frameType->versionType >= HITLS_VERSION_TLS12)) || + ((IS_DTLS_VERSION(frameType->versionType)) && (frameType->versionType <= HITLS_VERSION_DTLS12))) { + ParseFieldInteger16(&buffer[offset], bufLen - offset, &ecdh->signAlgorithm, &offset); + } + ParseFieldInteger16(&buffer[offset], bufLen - offset, &ecdh->signSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &ecdh->signData, ecdh->signSize.data, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static int32_t ParseServerKxDhMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_ServerDh *dh, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger16(&buffer[0], bufLen, &dh->plen, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &dh->p, dh->plen.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &dh->glen, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &dh->g, dh->glen.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &dh->pubKeyLen, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &dh->pubKey, dh->pubKeyLen.data, &offset); + if (((!IS_DTLS_VERSION(frameType->versionType)) && (frameType->versionType >= HITLS_VERSION_TLS12)) || + ((IS_DTLS_VERSION(frameType->versionType)) && (frameType->versionType <= HITLS_VERSION_DTLS12))) { + ParseFieldInteger16(&buffer[offset], bufLen - offset, &dh->signAlgorithm, &offset); + } + ParseFieldInteger16(&buffer[offset], bufLen - offset, &dh->signSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &dh->signData, dh->signSize.data, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static int32_t ParseServerKxEccMsg(const uint8_t *buffer, uint32_t bufLen, + FRAME_ServerEcdh *ecdh, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger16(&buffer[offset], bufLen - offset, &ecdh->signSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &ecdh->signData, ecdh->signSize.data, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static int32_t ParseServerKxMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_ServerKeyExchangeMsg *serverKx, uint32_t *parseLen) +{ + switch (frameType->keyExType) { + case HITLS_KEY_EXCH_ECDHE: + return ParseServerKxEcdhMsg(frameType, buffer, bufLen, &serverKx->keyEx.ecdh, parseLen); + case HITLS_KEY_EXCH_DHE: + return ParseServerKxDhMsg(frameType, buffer, bufLen, &serverKx->keyEx.dh, parseLen); + case HITLS_KEY_EXCH_ECC: + return ParseServerKxEccMsg(buffer, bufLen, &serverKx->keyEx.ecdh, parseLen); + default: + break; + } + return HITLS_PARSE_UNSUPPORT_KX_ALG; +} + +static void CleanServerKxMsg(HITLS_KeyExchAlgo kexType, FRAME_ServerKeyExchangeMsg *serverKx) +{ + FRAME_ServerEcdh *ecdh = &serverKx->keyEx.ecdh; + FRAME_ServerDh *dh = &serverKx->keyEx.dh; + switch (kexType) { + case HITLS_KEY_EXCH_ECDHE: + BSL_SAL_FREE(ecdh->pubKey.data); + BSL_SAL_FREE(ecdh->signData.data); + break; + case HITLS_KEY_EXCH_DHE: + BSL_SAL_FREE(dh->p.data); + BSL_SAL_FREE(dh->g.data); + BSL_SAL_FREE(dh->pubKey.data); + BSL_SAL_FREE(dh->signData.data); + break; + default: + break; + } + return; +} + +static int32_t ParseCertReqMsgExBody(uint16_t extMsgType, const uint8_t *buffer, uint32_t bufLen, + FRAME_CertificateRequestMsg *certReq, uint32_t *parseLen) +{ + uint32_t offset = 0; + switch (extMsgType) { + case HS_EX_TYPE_SIGNATURE_ALGORITHMS: + ParseFieldInteger16(&buffer[offset], bufLen - offset, &certReq->signatureAlgorithmsSize, &offset); + ParseFieldArray16(&buffer[offset], bufLen - offset, &certReq->signatureAlgorithms, + certReq->signatureAlgorithmsSize.data, &offset); + break; + default: + break; + } + *parseLen += offset; + return HITLS_SUCCESS; +} + +static int32_t ParseCertReqMsg( + FRAME_Type *type, const uint8_t *buffer, uint32_t bufLen, FRAME_CertificateRequestMsg *certReq, uint32_t *parseLen) +{ + uint32_t offset = 0; + certReq->state = INITIAL_FIELD; + if (type->versionType != HITLS_VERSION_TLS13) { + ParseFieldInteger8(&buffer[0], bufLen, &certReq->certTypesSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &certReq->certTypes, certReq->certTypesSize.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &certReq->signatureAlgorithmsSize, &offset); + ParseFieldArray16(&buffer[offset], bufLen - offset, &certReq->signatureAlgorithms, + certReq->signatureAlgorithmsSize.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &certReq->distinguishedNamesSize, &offset); + if (certReq->distinguishedNamesSize.data != 0u) { + ParseFieldArray8(&buffer[offset], bufLen - offset, &certReq->distinguishedNames, + certReq->distinguishedNamesSize.data, &offset); + } + } else { + ParseFieldInteger8(&buffer[0], bufLen, &certReq->certificateReqCtxSize, &offset); + ParseFieldArray8(&buffer[offset], + bufLen - offset, + &certReq->certificateReqCtx, + certReq->certificateReqCtxSize.data, + &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &certReq->exMsgLen, &offset); + while (offset < bufLen) { + uint32_t tmpOffset = offset; + FRAME_Integer extMsgType ; + FRAME_Integer extMsgLen ; + ParseFieldInteger16(&buffer[offset], bufLen - offset, &extMsgType, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &extMsgLen, &offset); + ParseCertReqMsgExBody(extMsgType.data, &buffer[offset], bufLen - offset, certReq, &offset); + if (offset == tmpOffset) { + break; + } + } + } + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanCertReqMsg(FRAME_CertificateRequestMsg *certReq) +{ + BSL_SAL_FREE(certReq->certTypes.data); + BSL_SAL_FREE(certReq->signatureAlgorithms.data); + BSL_SAL_FREE(certReq->distinguishedNames.data); + BSL_SAL_FREE(certReq->certificateReqCtx.data); + return; +} + +static int32_t ParseServerHelloDoneMsg(uint32_t bufLen) +{ + if (bufLen != 0) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; +} + +static void CleanServerHelloDoneMsg(FRAME_ServerHelloDoneMsg *serverHelloDone) +{ + /* The ServerHelloDone packet is an empty packet. If there is any constructed data, release it. */ + BSL_SAL_FREE(serverHelloDone->extra.data); + return; +} + +static int32_t ParseClientKxMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_ClientKeyExchangeMsg *clientKx, uint32_t *parseLen) +{ + uint32_t offset = 0; + switch (frameType->keyExType) { + case HITLS_KEY_EXCH_ECDHE: + /* Three bytes are added to the client key exchange. */ + +#ifndef HITLS_NO_TLCP11 + if (frameType->versionType == HITLS_VERSION_TLCP11) { + // Curve type + Curve ID + Public key length + uint8_t minLen = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t); + if (bufLen < minLen) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + // Ignore the first three bytes. + offset += sizeof(uint8_t) + sizeof(uint16_t); + } +#endif + ParseFieldInteger8(&buffer[offset], bufLen - offset, &clientKx->pubKeySize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &clientKx->pubKey, clientKx->pubKeySize.data, &offset); + break; + case HITLS_KEY_EXCH_DHE: + ParseFieldInteger16(&buffer[offset], bufLen - offset, &clientKx->pubKeySize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &clientKx->pubKey, clientKx->pubKeySize.data, &offset); + break; + default: + return HITLS_PARSE_UNSUPPORT_KX_ALG; + } + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanClientKxMsg(FRAME_ClientKeyExchangeMsg *clientKx) +{ + BSL_SAL_FREE(clientKx->pubKey.data); + return; +} + +static int32_t ParseCertVerifyMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_CertificateVerifyMsg *certVerify, uint32_t *parseLen) +{ + uint32_t offset = 0; + if (((!IS_DTLS_VERSION(frameType->versionType)) && (frameType->versionType >= HITLS_VERSION_TLS12)) || + ((IS_DTLS_VERSION(frameType->versionType)) && (frameType->versionType <= HITLS_VERSION_DTLS12))) { + ParseFieldInteger16(&buffer[0], bufLen, &certVerify->signHashAlg, &offset); + } + ParseFieldInteger16(&buffer[offset], bufLen - offset, &certVerify->signSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &certVerify->sign, certVerify->signSize.data, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanCertVerifyMsg(FRAME_CertificateVerifyMsg *certVerify) +{ + BSL_SAL_FREE(certVerify->sign.data); + return; +} + +static int32_t ParseFinishedMsg(const uint8_t *buffer, uint32_t bufLen, FRAME_FinishedMsg *finished, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldArray8(buffer, bufLen, &finished->verifyData, bufLen, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanFinishedMsg(FRAME_FinishedMsg *finished) +{ + BSL_SAL_FREE(finished->verifyData.data); + return; +} + +static int32_t ParseNewSessionTicket(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_NewSessionTicketMsg *sessionTicket, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger32(&buffer[0], bufLen, &sessionTicket->ticketLifetime, &offset); + + if (frameType->versionType != HITLS_VERSION_TLS13) { + ParseFieldInteger16(&buffer[offset], bufLen - offset, &sessionTicket->ticketSize, &offset); + ParseFieldArray8( + &buffer[offset], bufLen - offset, &sessionTicket->ticket, sessionTicket->ticketSize.data, &offset); + } else { + ParseFieldInteger32(&buffer[offset], bufLen - offset, &sessionTicket->ticketAgeAdd, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &sessionTicket->ticketNonceSize, &offset); + ParseFieldArray8(&buffer[offset], bufLen - offset, &sessionTicket->ticketNonce, + sessionTicket->ticketNonceSize.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &sessionTicket->ticketSize, &offset); + ParseFieldArray8( + &buffer[offset], bufLen - offset, &sessionTicket->ticket, sessionTicket->ticketSize.data, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &sessionTicket->extensionLen, &offset); + while (offset < bufLen) { + FRAME_Integer tmpField = {0}; + uint32_t tmpOffset = offset; + ParseFieldInteger16(&buffer[tmpOffset], bufLen - tmpOffset, &tmpField, &tmpOffset); + switch (tmpField.data) { + default: + /* The extensions in the tls 1.3 new session ticket cannot be parsed currently. Skip this step. */ + ParseFieldInteger16(&buffer[tmpOffset], bufLen - tmpOffset, &tmpField, &tmpOffset); + tmpOffset += tmpField.data; + offset = tmpOffset; + break; + } + } + } + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanNewSessionTicket(FRAME_NewSessionTicketMsg *sessionTicket) +{ + BSL_SAL_FREE(sessionTicket->ticket.data); + BSL_SAL_FREE(sessionTicket->ticketNonce.data); + return; +} + +static int32_t ParseHsMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_HsMsg *hsMsg, uint32_t *parseLen) +{ + uint32_t offset = 0; + ParseFieldInteger8(&buffer[0], bufLen, &hsMsg->type, &offset); + ParseFieldInteger24(&buffer[offset], bufLen - offset, &hsMsg->length, &offset); + + if (IS_DTLS_VERSION(frameType->versionType)) { + ParseFieldInteger16(&buffer[offset], bufLen - offset, &hsMsg->sequence, &offset); + ParseFieldInteger24(&buffer[offset], bufLen - offset, &hsMsg->fragmentOffset, &offset); + ParseFieldInteger24(&buffer[offset], bufLen - offset, &hsMsg->fragmentLength, &offset); + } + *parseLen += offset; + + /* To ensure that the memory can be normally released after users modify hsMsg->type.data, + * assign a value to frameType. */ + frameType->handshakeType = hsMsg->type.data; + switch (hsMsg->type.data) { + case CLIENT_HELLO: + return ParseClientHelloMsg(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.clientHello, parseLen); + case SERVER_HELLO: + return ParseServerHelloMsg(&buffer[offset], bufLen - offset, &hsMsg->body.serverHello, parseLen); + case CERTIFICATE: + return ParseCertificateMsg(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.certificate, parseLen); + case SERVER_KEY_EXCHANGE: + return ParseServerKxMsg(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.serverKeyExchange, + parseLen); + case CERTIFICATE_REQUEST: + return ParseCertReqMsg(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.certificateReq, parseLen); + case CLIENT_KEY_EXCHANGE: + return ParseClientKxMsg(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.clientKeyExchange, + parseLen); + case CERTIFICATE_VERIFY: + return ParseCertVerifyMsg(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.certificateVerify, + parseLen); + case FINISHED: + return ParseFinishedMsg(&buffer[offset], bufLen - offset, &hsMsg->body.finished, parseLen); + case SERVER_HELLO_DONE: + return ParseServerHelloDoneMsg(bufLen - offset); + case NEW_SESSION_TICKET: + return ParseNewSessionTicket(frameType, &buffer[offset], bufLen - offset, &hsMsg->body.newSessionTicket, + parseLen); + default: + break; + } + return HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG; +} + +static int32_t ParseCcsMsg(const uint8_t *buffer, uint32_t bufLen, FRAME_CcsMsg *ccsMsg, uint32_t *parseLen) +{ + /* The length of the CCS message is 1 byte. */ + if (bufLen != 1u) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t offset = 0; + ParseFieldInteger8(buffer, bufLen, &ccsMsg->ccsType, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanCcsMsg(FRAME_CcsMsg *ccsMsg) +{ + /* This field is used to construct abnormal packets. Data is not written during parsing. However, + * users may apply for memory. Therefore, this field needs to be released. */ + BSL_SAL_FREE(ccsMsg->extra.data); + return; +} + +static int32_t ParseAlertMsg(const uint8_t *buffer, uint32_t bufLen, FRAME_AlertMsg *alertMsg, uint32_t *parseLen) +{ + /* The length of the alert message is 2 bytes. */ + if (bufLen != 2u) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t offset = 0; + ParseFieldInteger8(&buffer[0], bufLen, &alertMsg->alertLevel, &offset); + ParseFieldInteger8(&buffer[offset], bufLen - offset, &alertMsg->alertDescription, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanAlertMsg(FRAME_AlertMsg *alertMsg) +{ + /* This field is used to construct abnormal packets. Data is not written during parsing. + * However, users may apply for memory. Therefore, this field needs to be released. */ + BSL_SAL_FREE(alertMsg->extra.data); + return; +} + +static int32_t ParseAppMsg(const uint8_t *buffer, uint32_t bufLen, FRAME_AppMsg *appMsg, uint32_t *parseLen) +{ + if (bufLen == 0u) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t offset = 0; + ParseFieldArray8(buffer, bufLen, &appMsg->appData, bufLen, &offset); + *parseLen += offset; + return HITLS_SUCCESS; +} + +static void CleanAppMsg(FRAME_AppMsg *appMsg) +{ + BSL_SAL_FREE(appMsg->appData.data); + return; +} + +int32_t FRAME_ParseMsgHeader( + FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, FRAME_Msg *msg, uint32_t *parseLen) +{ + if ((frameType == NULL) || (buffer == NULL) || (msg == NULL) || (parseLen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t offset = 0; + ParseFieldInteger8(&buffer[0], bufLen, &msg->recType, &offset); + ParseFieldInteger16(&buffer[offset], bufLen - offset, &msg->recVersion, &offset); + + if (IS_DTLS_VERSION(frameType->versionType)) { + ParseFieldInteger16(&buffer[offset], bufLen - offset, &msg->epoch, &offset); + ParseFieldInteger48(&buffer[offset], bufLen - offset, &msg->sequence, &offset); + } + + ParseFieldInteger16(&buffer[offset], bufLen - offset, &msg->length, &offset); + if ((msg->length.data + offset) > bufLen) { + return HITLS_PARSE_INVALID_MSG_LEN; + } + + *parseLen = offset; + return HITLS_SUCCESS; +} + +int32_t FRAME_ParseTLSRecordHeader(const uint8_t *buffer, uint32_t bufferLen, FRAME_Msg *msg, uint32_t *parsedLen) +{ + if ((buffer == NULL) || (msg == NULL) || (parsedLen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t offset = 0; + // Parse the 0th byte of the buffer. The parsing result is stored in msg->recType, offset = 1. + ParseFieldInteger8(buffer, bufferLen, &msg->recType, &offset); + // Parse the first and second bytes of the buffer. The parsing result is stored in msg->recVersion, offset = 3. + ParseFieldInteger16(buffer + offset, bufferLen - offset, &msg->recVersion, &offset); + // Parse the third to fourth bytes of the buffer. The parsing result is stored in msg->length, and offset = 5. + ParseFieldInteger16(buffer + offset, bufferLen - offset, &msg->length, &offset); + // msg->length.data indicates the length of the parsed record body. + // In this case, the value of offset is the header length. + if ((msg->length.data + offset) > bufferLen) { + // The length of the entire message cannot be greater than bufLen. + return HITLS_PARSE_INVALID_MSG_LEN; + } + + *parsedLen = offset; + return HITLS_SUCCESS; +} + +// Parse the body of a non-handshake record. +int32_t FRAME_ParseTLSNonHsRecordBody(const uint8_t *buffer, uint32_t bufferLen, FRAME_Msg *msg, uint32_t *parseLen) +{ + if ((buffer == NULL) || (msg == NULL) || (parseLen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + switch (msg->recType.data) { + case REC_TYPE_CHANGE_CIPHER_SPEC: + return ParseCcsMsg(buffer, bufferLen, &msg->body.ccsMsg, parseLen); + case REC_TYPE_ALERT: + return ParseAlertMsg(buffer, bufferLen, &msg->body.alertMsg, parseLen); + case REC_TYPE_APP: + return ParseAppMsg(buffer, bufferLen, &msg->body.appMsg, parseLen); + default: + break; + } + return HITLS_INTERNAL_EXCEPTION; +} + +int32_t FRAME_ParseMsgBody( + FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, FRAME_Msg *msg, uint32_t *parseLen) +{ + if ((frameType == NULL) || (buffer == NULL) || (msg == NULL) || (parseLen == NULL)) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* To ensure that the memory can be normally released after users modify msg->recType.data, + * assign a value to frameType. */ + frameType->recordType = msg->recType.data; + switch (msg->recType.data) { + case REC_TYPE_HANDSHAKE: + return ParseHsMsg(frameType, buffer, bufLen, &msg->body.hsMsg, parseLen); + case REC_TYPE_CHANGE_CIPHER_SPEC: + return ParseCcsMsg(buffer, bufLen, &msg->body.ccsMsg, parseLen); + case REC_TYPE_ALERT: + return ParseAlertMsg(buffer, bufLen, &msg->body.alertMsg, parseLen); + case REC_TYPE_APP: + return ParseAppMsg(buffer, bufLen, &msg->body.appMsg, parseLen); + default: + break; + } + + return HITLS_INTERNAL_EXCEPTION; +} + +int32_t FRAME_ParseMsg(FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufLen, + FRAME_Msg *msg, uint32_t *parseLen) +{ + int32_t ret; + ret = FRAME_ParseMsgHeader(frameType, buffer, bufLen, msg, parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return FRAME_ParseMsgBody(frameType, &buffer[*parseLen], msg->length.data, msg, parseLen); +} + +int32_t FRAME_ParseTLSNonHsRecord(const uint8_t *buffer, uint32_t bufLen, FRAME_Msg *msg, uint32_t *parseLen) +{ + int32_t ret; + uint32_t headerLen; + ret = FRAME_ParseTLSRecordHeader(buffer, bufLen, msg, parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + headerLen = *parseLen; + return FRAME_ParseTLSNonHsRecordBody(buffer + headerLen, msg->length.data, msg, parseLen); +} + +int32_t FRAME_ParseHsRecord( + FRAME_Type *frameType, const uint8_t *buffer, uint32_t bufferLen, FRAME_Msg *msg, uint32_t *parseLen) +{ + int32_t ret; + uint32_t headerLen; + ret = FRAME_ParseMsgHeader(frameType, buffer, bufferLen, msg, parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + headerLen = *parseLen; + /* To ensure that the memory can be normally released after users modify msg->recType.data, + * assign a value to frameType. */ + frameType->recordType = msg->recType.data; + if (msg->recType.data == REC_TYPE_HANDSHAKE) { + return ParseHsMsg(frameType, buffer + headerLen, msg->length.data, &msg->body.hsMsg, parseLen); + } + return HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG; +} + +static void CleanParsedHsMsg(HS_MsgType handshakeType, HITLS_KeyExchAlgo kexType, FRAME_HsMsg *hsMsg) +{ + switch (handshakeType) { + case CLIENT_HELLO: + return CleanClientHelloMsg(&hsMsg->body.clientHello); + case SERVER_HELLO: + return CleanServerHelloMsg(&hsMsg->body.serverHello); + case CERTIFICATE: + return CleanCertificateMsg(&hsMsg->body.certificate); + case SERVER_KEY_EXCHANGE: + return CleanServerKxMsg(kexType, &hsMsg->body.serverKeyExchange); + case CERTIFICATE_REQUEST: + return CleanCertReqMsg(&hsMsg->body.certificateReq); + case CLIENT_KEY_EXCHANGE: + return CleanClientKxMsg(&hsMsg->body.clientKeyExchange); + case CERTIFICATE_VERIFY: + return CleanCertVerifyMsg(&hsMsg->body.certificateVerify); + case FINISHED: + return CleanFinishedMsg(&hsMsg->body.finished); + case SERVER_HELLO_DONE: + return CleanServerHelloDoneMsg(&hsMsg->body.serverHelloDone); + case NEW_SESSION_TICKET: + return CleanNewSessionTicket(&hsMsg->body.newSessionTicket); + default: + break; + } + return; +} + +static void CleanHsMsg(FRAME_Type *frameType, FRAME_HsMsg *hsMsg) +{ + return CleanParsedHsMsg(frameType->handshakeType, frameType->keyExType, hsMsg); +} + +void FRAME_CleanMsg(FRAME_Type *frameType, FRAME_Msg *msg) +{ + if ((frameType == NULL) || (msg == NULL)) { + return; + } + + switch (frameType->recordType) { + case REC_TYPE_HANDSHAKE: + CleanHsMsg(frameType, &msg->body.hsMsg); + break; + case REC_TYPE_CHANGE_CIPHER_SPEC: + CleanCcsMsg(&msg->body.ccsMsg); + break; + case REC_TYPE_ALERT: + CleanAlertMsg(&msg->body.alertMsg); + break; + case REC_TYPE_APP: + CleanAppMsg(&msg->body.appMsg); + break; + default: + break; + } + memset_s(msg, sizeof(FRAME_Msg), 0, sizeof(FRAME_Msg)); + return; +} + +void FRAME_CleanNonHsRecord(REC_Type recType, FRAME_Msg *msg) +{ + if (msg == NULL) { + return; + } + switch (recType) { + case REC_TYPE_CHANGE_CIPHER_SPEC: + CleanCcsMsg(&msg->body.ccsMsg); + break; + case REC_TYPE_ALERT: + CleanAlertMsg(&msg->body.alertMsg); + break; + case REC_TYPE_APP: + CleanAppMsg(&msg->body.appMsg); + break; + default: + break; + } + memset_s(msg, sizeof(FRAME_Msg), 0, sizeof(FRAME_Msg)); +} \ No newline at end of file diff --git a/testcode/framework/tls/msg/src/pack_frame_msg.c b/testcode/framework/tls/msg/src/pack_frame_msg.c new file mode 100644 index 00000000..6840cea9 --- /dev/null +++ b/testcode/framework/tls/msg/src/pack_frame_msg.c @@ -0,0 +1,457 @@ +/* + * 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 "securec.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack_common.h" +#include "pack.h" +#include "frame_msg.h" +#include "pack_frame_msg.h" + +#define RECORD_BUF_LEN (18 * 1024) +#define TEST_CERT_LEN_TAG_SIZE 3 + +TLS_Ctx *NewFrameTlsCtx(void) +{ + TLS_Ctx *tlsCtx = (TLS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HITLS_Ctx)); + if (tlsCtx == NULL) { + return NULL; + } + + tlsCtx->hsCtx = (HS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HS_Ctx)); + if (tlsCtx->hsCtx == NULL) { + BSL_SAL_FREE(tlsCtx); + return NULL; + } + tlsCtx->hsCtx->clientRandom = tlsCtx->negotiatedInfo.clientRandom; + tlsCtx->hsCtx->serverRandom = tlsCtx->negotiatedInfo.serverRandom; + return tlsCtx; +} + +int32_t GenClientHelloMandatoryCtx(TLS_Ctx *tlsCtx, FRAME_Msg *msg) +{ + ClientHelloMsg *clientHello = &msg->body.handshakeMsg.body.clientHello; + TLS_Config *tlsConfig = &tlsCtx->config.tlsConfig; + tlsConfig->maxVersion = clientHello->version; + int32_t ret = memcpy_s(tlsCtx->hsCtx->clientRandom, HS_RANDOM_SIZE, clientHello->randomValue, HS_RANDOM_SIZE); + if (ret != EOK) { + return HITLS_MEMCPY_FAIL; + } + + if (clientHello->sessionIdSize > 0) { + tlsCtx->hsCtx->sessionId = (uint8_t *)BSL_SAL_Dump(clientHello->sessionId, clientHello->sessionIdSize); + if (tlsCtx->hsCtx->sessionId == NULL) { + return HITLS_MEMALLOC_FAIL; + } + tlsCtx->hsCtx->sessionIdSize = clientHello->sessionIdSize; + } + +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(clientHello->version) && clientHello->cookieLen > 0) { + tlsCtx->negotiatedInfo.cookieSize = clientHello->cookieLen; + tlsCtx->negotiatedInfo.cookie = (uint8_t *)BSL_SAL_Dump(clientHello->cookie, clientHello->cookieLen); + if (tlsCtx->negotiatedInfo.cookie == NULL) { + return HITLS_MEMALLOC_FAIL; + } + } +#endif + + tlsConfig->cipherSuitesSize = clientHello->cipherSuitesSize; + uint32_t suitsLen = clientHello->cipherSuitesSize * sizeof(uint16_t); + tlsConfig->cipherSuites = (uint16_t *)BSL_SAL_Dump(clientHello->cipherSuites, suitsLen); + if (tlsConfig->cipherSuites == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + return HITLS_SUCCESS; +} + +int32_t GenClientHelloExtensionCtx(TLS_Ctx *tlsCtx, FRAME_Msg *msg) +{ + ClientHelloMsg *clientHello = &msg->body.handshakeMsg.body.clientHello; + TLS_Config *tlsConfig = &tlsCtx->config.tlsConfig; + tlsConfig->isSupportExtendMasterSecret = clientHello->extension.flag.haveExtendedMasterSecret; + tlsConfig->signAlgorithmsSize = clientHello->extension.content.signatureAlgorithmsSize; + if (tlsConfig->signAlgorithmsSize > 0) { + uint32_t signAlgorithmsLen = tlsConfig->signAlgorithmsSize * sizeof(uint16_t); + tlsConfig->signAlgorithms = (uint16_t *)BSL_SAL_Dump(clientHello->extension.content.signatureAlgorithms, + signAlgorithmsLen); + if (tlsConfig->signAlgorithms == NULL) { + return HITLS_MEMALLOC_FAIL; + } + } + + tlsConfig->groupsSize = clientHello->extension.content.supportedGroupsSize; + if (tlsConfig->groupsSize > 0) { + uint32_t groupsLen = tlsConfig->groupsSize * sizeof(uint16_t); + tlsConfig->groups = (uint16_t *)BSL_SAL_Dump(clientHello->extension.content.supportedGroups, groupsLen); + if (tlsConfig->groups == NULL) { + return HITLS_MEMALLOC_FAIL; + } + } + + tlsConfig->pointFormatsSize = clientHello->extension.content.pointFormatsSize; + if (tlsConfig->pointFormatsSize > 0) { + uint32_t pointFormatsLen = tlsConfig->pointFormatsSize * sizeof(uint8_t); + tlsConfig->pointFormats = (uint8_t *)BSL_SAL_Dump(clientHello->extension.content.pointFormats, pointFormatsLen); + if (tlsConfig->pointFormats == NULL) { + return HITLS_MEMALLOC_FAIL; + } + } + + return HITLS_SUCCESS; +} + +int32_t PackClientHelloMsg(FRAME_Msg *msg) +{ + TLS_Ctx *tlsCtx = NewFrameTlsCtx(); + if (tlsCtx == NULL) { + return HITLS_MEMCPY_FAIL; + } + + int32_t ret = GenClientHelloMandatoryCtx(tlsCtx, msg); + if (ret != HITLS_SUCCESS) { + goto FREE_MEM; + } + + // extended information + ret = GenClientHelloExtensionCtx(tlsCtx, msg); + if (ret != HITLS_SUCCESS) { + goto FREE_MEM; + } + + uint32_t usedLen = 0; + ret = HS_PackMsg(tlsCtx, CLIENT_HELLO, &msg->buffer[msg->len], REC_MAX_PLAIN_LENGTH, &usedLen); + if (ret == HITLS_SUCCESS) { + msg->len += usedLen; + } + +FREE_MEM: + HITLS_Free(tlsCtx); + return ret; +} + +int32_t PackServerHelloMsg(FRAME_Msg *msg) +{ + TLS_Ctx *tlsCtx = NewFrameTlsCtx(); + if (tlsCtx == NULL) { + return HITLS_MEMCPY_FAIL; + } + + ServerHelloMsg *serverHello = &msg->body.handshakeMsg.body.serverHello; + tlsCtx->negotiatedInfo.version = serverHello->version; + + int32_t ret = 0; + ret = memcpy_s(tlsCtx->hsCtx->serverRandom, HS_RANDOM_SIZE, serverHello->randomValue, HS_RANDOM_SIZE); + if (ret != EOK) { + goto FREE_MEM; + } + + if (serverHello->sessionIdSize > 0) { // SessionId + tlsCtx->hsCtx->sessionId = (uint8_t *)BSL_SAL_Dump(serverHello->sessionId, serverHello->sessionIdSize); + if (tlsCtx->hsCtx->sessionId == NULL) { + ret = HITLS_MEMALLOC_FAIL; + goto FREE_MEM; + } + tlsCtx->hsCtx->sessionIdSize = serverHello->sessionIdSize; + } + + tlsCtx->negotiatedInfo.cipherSuiteInfo.cipherSuite = serverHello->cipherSuite; + tlsCtx->negotiatedInfo.isExtendedMasterSecret = serverHello->haveExtendedMasterSecret; + + uint32_t usedLen = 0; + ret = HS_PackMsg(tlsCtx, SERVER_HELLO, &msg->buffer[msg->len], REC_MAX_PLAIN_LENGTH, &usedLen); + if (ret == HITLS_SUCCESS) { + msg->len += usedLen; + } + +FREE_MEM: + HITLS_Free(tlsCtx); + return ret; +} + +int32_t PackCertificateMsg(FRAME_Msg *msg) +{ + CertificateMsg *certificate = &msg->body.handshakeMsg.body.certificate; + uint32_t allCertsLen = 0; // Total length of all certificates + uint32_t offset = msg->len + DTLS_HS_MSG_HEADER_SIZE; // Reserved packet header + // Indicates the offset of the total length of the certificate chain. + uint32_t certsLenOffset = offset; + offset += TEST_CERT_LEN_TAG_SIZE; // Total length of the reserved certificate chain + + CERT_Item *cur = certificate->cert; + while (cur != NULL) { + BSL_Uint24ToByte(cur->dataSize, &msg->buffer[offset]); + offset += TEST_CERT_LEN_TAG_SIZE; + int32_t ret = memcpy_s(&msg->buffer[offset], RECORD_BUF_LEN - offset, cur->data, cur->dataSize); + if (ret != EOK) { + return HITLS_MEMCPY_FAIL; + } + + offset += cur->dataSize; + allCertsLen += TEST_CERT_LEN_TAG_SIZE + cur->dataSize; + cur = cur->next; + } + // Indicates the total length of the certificate chain. + BSL_Uint24ToByte(allCertsLen, &msg->buffer[certsLenOffset]); + + /* Assemble the packet header. */ + const uint32_t sequence = 1; + const uint32_t bodyLen = TEST_CERT_LEN_TAG_SIZE + allCertsLen; + PackDtlsMsgHeader(CERTIFICATE, sequence, bodyLen, &msg->buffer[msg->len]); + msg->len += DTLS_HS_MSG_HEADER_SIZE + bodyLen; + + return HITLS_SUCCESS; +} + +int32_t PackServerKxMsg(FRAME_Msg *msg) +{ + ServerKeyExchangeMsg *serverKx = &msg->body.handshakeMsg.body.serverKeyExchange; + uint32_t offset = msg->len + DTLS_HS_MSG_HEADER_SIZE; // Reserved packet header + + /* Curve Type and Curve ID */ + msg->buffer[offset] = (uint8_t)(serverKx->keyEx.ecdh.ecPara.type); + offset += sizeof(uint8_t); + BSL_Uint16ToByte((uint16_t)(serverKx->keyEx.ecdh.ecPara.param.namedcurve), &msg->buffer[offset]); + offset += sizeof(uint16_t); + + /* Public key length and public key content */ + msg->buffer[offset] = (uint8_t)serverKx->keyEx.ecdh.pubKeySize; + offset += sizeof(uint8_t); + int32_t ret = memcpy_s(&msg->buffer[offset], RECORD_BUF_LEN - offset, + serverKx->keyEx.ecdh.pubKey, serverKx->keyEx.ecdh.pubKeySize); + if (ret != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += serverKx->keyEx.ecdh.pubKeySize; + + /* signature algorithm */ + BSL_Uint16ToByte(serverKx->keyEx.ecdh.signAlgorithm, &msg->buffer[offset]); + offset += sizeof(uint16_t); + + /* Signature Length */ + BSL_Uint16ToByte(serverKx->keyEx.ecdh.signSize, &msg->buffer[offset]); + offset += sizeof(uint16_t); + + ret = memcpy_s(&msg->buffer[offset], RECORD_BUF_LEN - offset, + serverKx->keyEx.ecdh.signData, serverKx->keyEx.ecdh.signSize); + if (ret != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += serverKx->keyEx.ecdh.signSize; + + /* Assemble the packet header. */ + const uint32_t sequence = msg->body.handshakeMsg.sequence; + const uint32_t bodyLen = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t) + serverKx->keyEx.ecdh.pubKeySize + + sizeof(uint16_t) + sizeof(uint16_t) + serverKx->keyEx.ecdh.signSize; + PackDtlsMsgHeader(SERVER_KEY_EXCHANGE, sequence, bodyLen, &msg->buffer[msg->len]); + msg->len += DTLS_HS_MSG_HEADER_SIZE + bodyLen; + + return HITLS_SUCCESS; +} + +int32_t PackServerHelloDoneMsg(FRAME_Msg *msg) +{ + /* Assemble the packet header. */ + const uint32_t sequence = msg->body.handshakeMsg.sequence; + const uint32_t bodyLen = 0; + PackDtlsMsgHeader(SERVER_HELLO_DONE, sequence, bodyLen, &msg->buffer[msg->len]); + msg->len += DTLS_HS_MSG_HEADER_SIZE + bodyLen; + + return HITLS_SUCCESS; +} + +int32_t PackClientKxMsg(FRAME_Msg *msg) +{ + ClientKeyExchangeMsg *clientKx = &msg->body.handshakeMsg.body.clientKeyExchange; + uint32_t offset = msg->len + DTLS_HS_MSG_HEADER_SIZE; // Reserved packet header + msg->buffer[offset] = (uint8_t)clientKx->dataSize; + offset += sizeof(uint8_t); + int32_t ret = memcpy_s(&msg->buffer[offset], RECORD_BUF_LEN - offset, clientKx->data, clientKx->dataSize); + if (ret != EOK) { + return HITLS_MEMCPY_FAIL; + } + + /* Assemble the packet header. */ + const uint32_t sequence = msg->body.handshakeMsg.sequence; + const uint32_t bodyLen = clientKx->dataSize + sizeof(uint8_t); + PackDtlsMsgHeader(CLIENT_KEY_EXCHANGE, sequence, bodyLen, &msg->buffer[msg->len]); + msg->len += DTLS_HS_MSG_HEADER_SIZE + bodyLen; + + return HITLS_SUCCESS; +} + +int32_t PackFinishMsg(FRAME_Msg *msg) +{ + TLS_Ctx *tlsCtx = NewFrameTlsCtx(); + if (tlsCtx == NULL) { + return HITLS_MEMCPY_FAIL; + } + + FinishedMsg *finished = &msg->body.handshakeMsg.body.finished; + int32_t ret = 0; + tlsCtx->hsCtx->verifyCtx = (VerifyCtx*)BSL_SAL_Calloc(1u, sizeof(VerifyCtx)); + if (tlsCtx->hsCtx->verifyCtx == NULL) { + ret = HITLS_MEMALLOC_FAIL; + goto FREE_MEM; + } + + tlsCtx->hsCtx->verifyCtx->verifyDataSize = finished->verifyDataSize; + ret = memcpy_s(tlsCtx->hsCtx->verifyCtx->verifyData, MAX_SIGN_SIZE, + finished->verifyData, finished->verifyDataSize); + if (ret != EOK) { + goto FREE_MEM; + } + + uint32_t usedLen = 0; + ret = HS_PackMsg(tlsCtx, FINISHED, &msg->buffer[msg->len], REC_MAX_PLAIN_LENGTH, &usedLen); + if (ret == HITLS_SUCCESS) { + msg->len += usedLen; + } + +FREE_MEM: + HITLS_Free(tlsCtx); + return ret; +} + +int32_t PackHandShakeMsg(FRAME_Msg *msg) +{ + HS_MsgType type = msg->body.handshakeMsg.type; + uint32_t ret = HITLS_SUCCESS; + switch (type) { + case CLIENT_HELLO: + ret = PackClientHelloMsg(msg); + break; + case SERVER_HELLO: + ret = PackServerHelloMsg(msg); + break; + case CERTIFICATE: + ret = PackCertificateMsg(msg); + break; + case SERVER_KEY_EXCHANGE: + ret = PackServerKxMsg(msg); + break; + case SERVER_HELLO_DONE: + ret = PackServerHelloDoneMsg(msg); + break; + case CLIENT_KEY_EXCHANGE: + ret = PackClientKxMsg(msg); + break; + case FINISHED: + ret = PackFinishMsg(msg); + break; + default: + ret = HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + } + + return ret; +} + +int32_t PackCCSMsg(FRAME_Msg *msg) +{ + FRAME_CcsMsg *ccsMsg = &msg->body.ccsMsg; + uint32_t offset = msg->len; + msg->buffer[offset] = ccsMsg->type; + msg->len += sizeof(uint8_t); + + return HITLS_SUCCESS; +} + +int32_t PackAlertMsg(FRAME_Msg *msg) +{ + FRAME_AlertMsg *alertMsg = &msg->body.alertMsg; + uint32_t offset = msg->len; + msg->buffer[offset] = alertMsg->level; + offset += sizeof(uint8_t); + msg->buffer[offset] = alertMsg->description; + msg->len += sizeof(uint8_t) + sizeof(uint8_t); + return HITLS_SUCCESS; +} + +int32_t PackAppData(FRAME_Msg *msg) +{ + FRAME_AppMsg *appMsg = &msg->body.appMsg; + uint32_t offset = msg->len; + BSL_Uint32ToByte(appMsg->len, &msg->buffer[offset]); + offset += sizeof(uint32_t); + int32_t ret = memcpy_s(&msg->buffer[offset], RECORD_BUF_LEN - offset, appMsg->buffer, appMsg->len); + if (ret != EOK) { + return HITLS_MEMCPY_FAIL; + } + msg->len += sizeof(uint32_t) + appMsg->len; + return HITLS_SUCCESS; +} + +// Pack header +int32_t PackRecordHeader(FRAME_Msg *msg) +{ + uint32_t offset = 0; + msg->buffer[offset] = msg->type; + offset += sizeof(uint8_t); + BSL_Uint16ToByte(msg->version, &msg->buffer[offset]); + offset += sizeof(uint16_t); + +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(msg->version)) { + BSL_Uint64ToByte(msg->epochSeq, &msg->buffer[offset]); + offset += sizeof(uint64_t); + } +#endif + + BSL_Uint16ToByte(msg->bodyLen, &msg->buffer[offset]); + offset += sizeof(uint16_t); + msg->len = offset; + return HITLS_SUCCESS; +} + +int32_t PackFrameMsg(FRAME_Msg *msg) +{ + // Apply for an 18 KB buffer for storing the current message. + msg->buffer = (uint8_t *)BSL_SAL_Calloc(1u, RECORD_BUF_LEN); + if (msg->buffer == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + msg->len = RECORD_BUF_LEN; // The length must be the same as the length of the applied 18 KB buffer. + + // pack Header + PackRecordHeader(msg); + + // pack Body + uint32_t ret = HITLS_SUCCESS; + switch (msg->type) { + case REC_TYPE_HANDSHAKE: + ret = PackHandShakeMsg(msg); + break; + case REC_TYPE_CHANGE_CIPHER_SPEC: + ret = PackCCSMsg(msg); + break; + case REC_TYPE_ALERT: + ret = PackAlertMsg(msg); + break; + case REC_TYPE_APP: + ret = PackAppData(msg); + break; + default: + break; + } + + return ret; +} \ No newline at end of file diff --git a/testcode/framework/tls/msg/src/parser_frame_msg.c b/testcode/framework/tls/msg/src/parser_frame_msg.c new file mode 100644 index 00000000..8b09b19c --- /dev/null +++ b/testcode/framework/tls/msg/src/parser_frame_msg.c @@ -0,0 +1,163 @@ +/* + * 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 "securec.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "parse.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "parser_frame_msg.h" + +void SendAlertStake(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + (void)ctx; + (void)level; + (void)description; + return; +} + +int32_t ParserRecordHeader(FRAME_Msg *frameMsg, const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + (void)len; + uint32_t bufOffset = 0; + + frameMsg->type = buffer[bufOffset]; + bufOffset += sizeof(uint8_t); + + frameMsg->version = BSL_ByteToUint16(&buffer[bufOffset]); + bufOffset += sizeof(uint16_t); + +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(frameMsg->version)) { + frameMsg->epochSeq = BSL_ByteToUint64(&buffer[bufOffset]); + bufOffset += sizeof(uint64_t); + } +#endif + + frameMsg->bodyLen = BSL_ByteToUint16(&buffer[bufOffset]); + bufOffset += sizeof(uint16_t); + *parserLen = bufOffset; + + return HITLS_SUCCESS; +} + +int32_t ParserHandShakeMsg(const FRAME_LinkObj *linkObj, FRAME_Msg *frameMsg, + const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + int32_t ret; + HS_MsgInfo hsMsgInfo = {0}; + HITLS_Ctx *sslCtx = FRAME_GetTlsCtx(linkObj); + + SendAlertCallback tmpAlertCallback = sslCtx->method.sendAlert; + sslCtx->method.sendAlert = SendAlertStake; + + ret = HS_ParseMsgHeader(sslCtx, buffer, len, &hsMsgInfo); + if (ret != HITLS_SUCCESS) { + sslCtx->method.sendAlert = tmpAlertCallback; + return ret; + } + + ret = HS_ParseMsg(sslCtx, &hsMsgInfo, &frameMsg->body.handshakeMsg); + if (ret != HITLS_SUCCESS) { + sslCtx->method.sendAlert = tmpAlertCallback; + return ret; + } + + sslCtx->method.sendAlert = tmpAlertCallback; + *parserLen += hsMsgInfo.length; + return HITLS_SUCCESS; +} + +int32_t ParserCCSMsg(FRAME_Msg *frameMsg, const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + (void)len; + frameMsg->body.ccsMsg.type = buffer[0]; + *parserLen += sizeof(uint8_t); + return HITLS_SUCCESS; +} + +int32_t ParserAlertMsg(FRAME_Msg *frameMsg, const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + (void)len; + uint32_t bufOffset = 0; + frameMsg->body.alertMsg.level = buffer[bufOffset]; + bufOffset += sizeof(uint8_t); + frameMsg->body.alertMsg.description = buffer[bufOffset]; + bufOffset += sizeof(uint8_t); + *parserLen += bufOffset; + return HITLS_SUCCESS; +} + +int32_t ParserAppMsg(FRAME_Msg *frameMsg, const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + (void)len; + uint32_t bufOffset = 0; + uint32_t userDataLen = BSL_ByteToUint32(&buffer[bufOffset]); + frameMsg->body.appMsg.len = userDataLen; + bufOffset += sizeof(uint32_t); + frameMsg->body.appMsg.buffer = BSL_SAL_Dump(&buffer[bufOffset], userDataLen); + if (frameMsg->body.appMsg.buffer == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + bufOffset += userDataLen; + *parserLen += bufOffset; + + return HITLS_SUCCESS; +} + +int32_t ParserRecordBody(const FRAME_LinkObj *linkObj, FRAME_Msg *frameMsg, + const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + switch (frameMsg->type) { + case REC_TYPE_HANDSHAKE: + return ParserHandShakeMsg(linkObj, frameMsg, buffer, len, parserLen); + case REC_TYPE_CHANGE_CIPHER_SPEC: + return ParserCCSMsg(frameMsg, buffer, len, parserLen); + case REC_TYPE_ALERT: + return ParserAlertMsg(frameMsg, buffer, len, parserLen); + case REC_TYPE_APP: + return ParserAppMsg(frameMsg, buffer, len, parserLen); + default: + break; + } + + return HITLS_SUCCESS; +} + +int32_t ParserTotalRecord(const FRAME_LinkObj *linkObj, FRAME_Msg *frameMsg, + const uint8_t *buffer, uint32_t len, uint32_t *parserLen) +{ + int32_t ret = ParserRecordHeader(frameMsg, buffer, len, parserLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return ParserRecordBody(linkObj, frameMsg, &buffer[*parserLen], len - *parserLen, parserLen); +} + +void CleanRecordBody(FRAME_Msg *frameMsg) +{ + if (frameMsg->type == REC_TYPE_HANDSHAKE) { + HS_CleanMsg(&frameMsg->body.handshakeMsg); + } else if (frameMsg->type == REC_TYPE_APP) { + BSL_SAL_FREE(frameMsg->body.appMsg.buffer); + } + BSL_SAL_FREE(frameMsg->buffer); +} diff --git a/testcode/framework/tls/process/include/handle_cmd.h b/testcode/framework/tls/process/include/handle_cmd.h new file mode 100644 index 00000000..6bb04798 --- /dev/null +++ b/testcode/framework/tls/process/include/handle_cmd.h @@ -0,0 +1,73 @@ +/* + * 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 HANDLE_CMD_H +#define HANDLE_CMD_H + +#include +#include "hlt_type.h" +#include "channel_res.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_CMD_ID_LEN (15) +#define MAX_CMD_FUNCID_LEN (64) +#define MAX_CMD_PARAS_NUM (100) + +typedef struct { + uint8_t parasNum; + char id[MAX_CMD_ID_LEN]; + char funcId[MAX_CMD_FUNCID_LEN]; + char paras[MAX_CMD_PARAS_NUM][CONTROL_CHANNEL_MAX_MSG_LEN]; + char result[CONTROL_CHANNEL_MAX_MSG_LEN]; +} CmdData; + +/** +* @brief Expected result value +*/ +int ExpectResult(CmdData *expectCmdData); + +/** +* @brief Waiting for the result of the peer end +*/ +int WaitResultFromPeer(CmdData *expectCmdData); + +/** +* @brief Resolve instructions from a string +*/ +int ParseCmdFromStr(char *str, CmdData *cmdData); + +/** +* @brief Parse the instruction from the buffer. +*/ +int ParseCmdFromBuf(ControlChannelBuf *dataBuf, CmdData *cmdData); + +/** +* @brief Execute the corresponding command. +*/ +int ExecuteCmd(CmdData *cmdData); + +/** +* @brief Obtain the CTX configuration content from the character string parsing. +*/ +int ParseCtxConfigFromString(char (*string)[CONTROL_CHANNEL_MAX_MSG_LEN], HLT_Ctx_Config *ctxConfig); + +#ifdef __cplusplus +} +#endif + +#endif // HANDLE_CMD_H \ No newline at end of file diff --git a/testcode/framework/tls/process/include/process.h b/testcode/framework/tls/process/include/process.h new file mode 100644 index 00000000..9204b23f --- /dev/null +++ b/testcode/framework/tls/process/include/process.h @@ -0,0 +1,83 @@ +/* + * 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 PROCESS_H +#define PROCESS_H + +#include +#include +#include +#include "hlt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DOMAIN_PATH_LEN (128) +#define TLS_RES_MAX_NUM (64) + +typedef struct ProcessSt { + TLS_TYPE tlsType; // Identifies whether the HiTLS interface is used. + char srcDomainPath[DOMAIN_PATH_LEN]; + char peerDomainPath[DOMAIN_PATH_LEN]; // This field is used only by remote processes. + int controlChannelFd; // This field is used only by the local process. + int remoteFlag; // Indicates whether the process is a remote process. The value 1 indicates a remote process. + int connFd; // FD used by the TLS link + int connType; // Enumerated value of HILT_TransportType, which is the communication protocol type used by the + // TLS link. + int connPort; + struct sockaddr_in sockAddr; + void* tlsResArray[TLS_RES_MAX_NUM]; // Stores ctx SSL resources. + int tlsResNum; // Number of created TLS resources + void* hltTlsResArray[TLS_RES_MAX_NUM]; // Stores the HLT_Tls_Res resource. This resource is used only + // by the local process. + int hltTlsResNum; // Number of created HLT_Tls_Res resources. +} Process; + +/** +* @brief Initializes the global table used to represent command IDs. +*/ +void InitCmdIndex(void); + +/** +* @brief Initializing Process Resources +*/ +int InitProcess(void); + +/** +* @brief Obtaining Process Resources +*/ +Process *GetProcess(void); + +/** +* @brief Obtain the process from the linked list. +*/ +Process *GetProcessFromList(void); + +/** +* @brief Release the linked list of the storage process. +*/ +void FreeProcessResList(void); + +/** +* @brief Release process resources. +*/ +void FreeProcess(void); + +#ifdef __cplusplus +} +#endif + +#endif // PROCESS_H \ No newline at end of file diff --git a/testcode/framework/tls/process/src/handle_cmd.c b/testcode/framework/tls/process/src/handle_cmd.c new file mode 100644 index 00000000..4cbd167d --- /dev/null +++ b/testcode/framework/tls/process/src/handle_cmd.c @@ -0,0 +1,392 @@ +/* + * 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 +#include +#include +#include +#include +#include "hlt_type.h" +#include "securec.h" +#include "logger.h" +#include "rpc_func.h" +#include "channel_res.h" +#include "handle_cmd.h" + +#define SUCCESS 0 +#define ERROR (-1) +#define ASSERT_RETURN(condition, log) \ + do { \ + if (!(condition)) { \ + LOG_ERROR(log); \ + return ERROR; \ + } \ + } while (0) + +int ExpectResult(CmdData *expectCmdData) +{ + int ret, id; + char *endPtr = NULL; + CmdData cmdData; + ControlChannelRes *channelRes; + channelRes = GetControlChannelRes(); + OsLock(channelRes->rcvBufferLock); + + id = (int)strtol(expectCmdData->id, &endPtr, 0) % MAX_RCV_BUFFER_NUM; + // Check whether the corresponding buffer contains content. + if (strlen(channelRes->rcvBuffer[id]) == 0) { + OsUnLock(channelRes->rcvBufferLock); + return ERROR; + } + + // Parsing the CMD + ret = ParseCmdFromStr(channelRes->rcvBuffer[id], &cmdData); + if (ret != SUCCESS) { + LOG_ERROR("ParseCmdFromStr ERROR"); + OsUnLock(channelRes->rcvBufferLock); + return ERROR; + } + + if ((strncmp(expectCmdData->id, cmdData.id, strlen(cmdData.id)) == 0) && + (strncmp(expectCmdData->funcId, cmdData.funcId, strlen(cmdData.funcId)) == 0)) { + ret = memcpy_s(expectCmdData->paras, sizeof(expectCmdData->paras), cmdData.paras, sizeof(cmdData.paras)); + if (ret != EOK) { + LOG_ERROR("memcpy_s ERROR"); + OsUnLock(channelRes->rcvBufferLock); + return ERROR; + } + (void)memset_s(channelRes->rcvBuffer[id], CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN); + OsUnLock(channelRes->rcvBufferLock); + return SUCCESS; + } + OsUnLock(channelRes->rcvBufferLock); + LOG_ERROR("strncmp ERROR [expectCmdData->id=%s, cmdData.id = %s, expectCmdData->funcId = %s, cmdData.funcId = %s]", + expectCmdData->id, cmdData.id, expectCmdData->funcId, cmdData.funcId); + return ERROR; +} + +int WaitResultFromPeer(CmdData *expectCmdData) +{ + int ret; + int tryNum = 0; + do { + ret = ExpectResult(expectCmdData); + usleep(1000); // Waiting for 1000 subtleties + tryNum++; + } while ((ret != SUCCESS) && (tryNum < 150000)); + ASSERT_RETURN(ret == SUCCESS, "ExpectResult Error"); + return SUCCESS; +} + +int ParseCmdFromStr(char *str, CmdData *cmdData) +{ + int ret, count, strBufLen; + char *token = NULL; + char *rest = NULL; + char *strBuf = NULL; + (void)memset_s(cmdData, sizeof(CmdData), 0, sizeof(CmdData)); + + strBufLen = strlen(str) + 1; + strBuf = (char*)malloc(strBufLen); + ASSERT_RETURN(strBuf != NULL, "Malloc Error"); + (void)memset_s(strBuf, strBufLen, 0, strBufLen); + ret = memcpy_s(strBuf, strBufLen, str, strlen(str)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + goto ERR; + } + + /* + The command message structure is as follows: + ID | FUNC | PARAS1 | PARAS2 |...... + Fields are separated by vertical bars (|). + */ + // Get ID + token = strtok_s(strBuf, "|", &rest); + ret = strcpy_s(cmdData->id, sizeof(cmdData->id), token); // Get Id + if (ret != EOK) { + LOG_ERROR("strcpy_s Error"); + goto ERR; + } + + // Get FUNC. + token = strtok_s(NULL, "|", &rest); + ret = strcpy_s(cmdData->funcId, sizeof(cmdData->funcId), token); // Get FunId + if (ret != EOK) { + LOG_ERROR("strcpy_s Error"); + goto ERR; + } + + // Obtaining Parameters + token = strtok_s(NULL, "|", &rest); + count = 0; + for (; token != NULL; token = strtok_s(NULL, "|", &rest)) { + // Maximum length of argument is CONTROL_CHANNEL_MAX_MSG_LEN + ret = strcpy_s(cmdData->paras[count], sizeof(cmdData->paras[0]), token); + int offset = 0; + while (rest[offset] == '|') { + count++; + offset++; + } + count++; + if (ret != EOK) { + break; + } + } + if (ret != EOK) { + LOG_ERROR("strcpy_s error"); + goto ERR; + } + cmdData->parasNum = count; + free(strBuf); + return SUCCESS; + +ERR: + free(strBuf); + return ERROR; +} + +int ParseCmdFromBuf(ControlChannelBuf *dataBuf, CmdData *cmdData) +{ + return ParseCmdFromStr(dataBuf->data, cmdData); +} + +int ExecuteCmd(CmdData *cmdData) +{ + int ret; + RpcFunList *rcpFuncList = GetRpcFuncList(); + int funcNum = GetRpcFuncNum(); + ret = ERROR; + for (int i = 0; i < funcNum; i++) { + if (strncmp(rcpFuncList[i].funcId, cmdData->funcId, strlen(cmdData->funcId)) == 0) { + ret = rcpFuncList[i].hfunc(cmdData); + return ret; + } + } + LOG_ERROR("Not Find FuncId"); + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ERROR); + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + return ret; +} + +int ParseCtxConfigFromString(char (*string)[CONTROL_CHANNEL_MAX_MSG_LEN], HLT_Ctx_Config *ctxConfig) +{ + int ret; + /* + The message structure is as follows: + minVersion | maxVersion |cipherSuites |CA |...... + Fields are separated by vertical bars (|). + */ + int index = 1; + // minimum version number + // The first parameter indicates the minimum version number. + ctxConfig->minVersion = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx minVersion is %u", ctxConfig->minVersion); + + // Maximum version number + // The second parameter indicates the maximum version number. + ctxConfig->maxVersion = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx maxVersion is %u", ctxConfig->maxVersion); + + // Obtaining the Algorithm Suite + // The third parameter indicates the algorithm suite. + ret = strcpy_s(ctxConfig->cipherSuites, sizeof(ctxConfig->cipherSuites), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx cipherSuites is %s", ctxConfig->cipherSuites); + + // The fourth parameter indicates the algorithm suite. + ret = strcpy_s(ctxConfig->tls13CipherSuites, sizeof(ctxConfig->tls13CipherSuites), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx tls13cipherSuites is %s", ctxConfig->tls13CipherSuites); + + // ECC Point Format Configuration for Asymmetric Algorithms + // The fifth parameter indicates the dot format. + ret = strcpy_s(ctxConfig->pointFormats, sizeof(ctxConfig->pointFormats), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx pointFormats is %s", ctxConfig->pointFormats); + + // Obtaining a Group + // The sixth parameter indicates a group. + ret = strcpy_s(ctxConfig->groups, sizeof(ctxConfig->groups), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx groups is %s", ctxConfig->groups); + + // Obtaining a Signature + // The seventh parameter indicates the signature. + ret = strcpy_s(ctxConfig->signAlgorithms, sizeof(ctxConfig->signAlgorithms), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx signAlgorithms is %s", ctxConfig->signAlgorithms); + + // Whether to support renegotiation + // The eighth parameter indicates whether renegotiation is supported. + ctxConfig->isSupportRenegotiation = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx isSupportRenegotiation is %d", ctxConfig->isSupportRenegotiation); + + // Indicates whether to verify the client. + // The tenth parameter indicates whether to verify the client. + ctxConfig->isSupportClientVerify = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx isSupportClientVerify is %d", ctxConfig->isSupportClientVerify); + + // Indicates whether the client can send an empty certificate chain. + // The eleventh parameter indicates whether the client can send an empty certificate chain. + ctxConfig->isSupportNoClientCert = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx isSupportNoClientCert is %d", ctxConfig->isSupportNoClientCert); + + // Indicates whether extended master keys are supported. + // The twelfth parameter indicates whether the extended master key is supported. + ctxConfig->isSupportExtendMasterSecret = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx isSupportExtendMasterSecret is %d", ctxConfig->isSupportExtendMasterSecret); + + // device certificate + // The thirteenth parameter indicates the location of the device certificate. + ret = strcpy_s(ctxConfig->eeCert, sizeof(ctxConfig->eeCert), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx EE is %s", ctxConfig->eeCert); + + // private key + // The fourteenth parameter indicates the location of the private key. + ret = strcpy_s(ctxConfig->privKey, sizeof(ctxConfig->privKey), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx privKey is %s", ctxConfig->privKey); + + // private key password + // The fifteenth parameter indicates the password of the private key. + ret = strcpy_s(ctxConfig->password, sizeof(ctxConfig->password), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx password is %s", ctxConfig->password); + + // CA certificate + // The 16th parameter indicates the CA certificate. + ret = strcpy_s(ctxConfig->caCert, sizeof(ctxConfig->caCert), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx caCert is %s", ctxConfig->caCert); + + // Chain certificate + // The 17th parameter indicates the certificate chain. + ret = strcpy_s(ctxConfig->chainCert, sizeof(ctxConfig->chainCert), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx chainCert is %s", ctxConfig->chainCert); + + // signature certificate + LOG_DEBUG("Remote Process Set Ctx signCert is %s", string[index]); + // The eighteenth parameter indicates the position of the signature certificate. + ret = strcpy_s(ctxConfig->signCert, sizeof(ctxConfig->signCert), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + + // private key for signature + LOG_DEBUG("Remote Process Set Ctx signPrivKey is %s", string[index]); + // The 19th parameter indicates the location of the signature private key. + ret = strcpy_s(ctxConfig->signPrivKey, sizeof(ctxConfig->signPrivKey), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + + // psk + ret = strcpy_s(ctxConfig->psk, sizeof(ctxConfig->psk), string[index++]); // 21st parameter psk + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx psk is %s", ctxConfig->psk); + + // Indicates whether to support session tickets. + // Indicates whether to enable the sessionTicket function. The value is a decimal number. + ctxConfig->isSupportSessionTicket = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx isSupportSessionTicket is %d", ctxConfig->isSupportSessionTicket); + + // Setting the Session Storage Mode + // The 23rd parameter is used to set the session storage mode. The value is a decimal number. + ctxConfig->setSessionCache = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx SessionCache is %d", ctxConfig->setSessionCache); + + // Setting the ticket key cb + // 24th parameter ticket key cb + ret = strcpy_s(ctxConfig->ticketKeyCb, sizeof(ctxConfig->ticketKeyCb), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx ticketKeyCb is %s", ctxConfig->ticketKeyCb); + + // Indicates whether isFlightTransmitEnable is supported. The 25th parameter indicates whether to send handshake + // messages by flight. The value is converted into a decimal number. + ctxConfig->isFlightTransmitEnable = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx isFlightTransmitEnable is %d", ctxConfig->isFlightTransmitEnable); + + // Setting the server name + ret = strcpy_s(ctxConfig->serverName, sizeof(ctxConfig->serverName), string[index++]); // Parameter 26 + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx ServerName is %s", ctxConfig->serverName); + + // Setting the server name cb + // 27th parameter server name cb + ret = strcpy_s(ctxConfig->sniDealCb, sizeof(ctxConfig->sniDealCb), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx ServerNameCb is %s", ctxConfig->sniDealCb); + + // Setting the server name arg + // 28th parameter server name arg cb + ret = strcpy_s(ctxConfig->sniArg, sizeof(ctxConfig->sniArg), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx ServerNameArg is %s", ctxConfig->sniArg); + + // Setting the ALPN + ret = strcpy_s(ctxConfig->alpnList, sizeof(ctxConfig->alpnList), string[index++]); // 29th parameter + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx alpnList is %s", ctxConfig->alpnList); + + // Setting the ALPN cb + ret = strcpy_s(ctxConfig->alpnSelectCb, sizeof(ctxConfig->alpnSelectCb), string[index++]); // 30th parameter + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx alpnSelectCb is %s", ctxConfig->alpnSelectCb); + + // Setting the ALPN data + ret = strcpy_s(ctxConfig->alpnUserData, sizeof(ctxConfig->alpnUserData), string[index++]); // 31th parameter + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx alpnUserData is %s", ctxConfig->alpnUserData); + + // Sets the security level. The parameter indicates that the security strength of the key meets the security level + // requirements and is converted into a decimal number. + ctxConfig->securitylevel = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx SecurityLevel is %d", ctxConfig->securitylevel); + + // Indicates whether the DH key length follows the certificate. The parameter indicates whether the DH key length + // follows the certificate, which is converted into a decimal number. + ctxConfig->isSupportDhAuto = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx issupportDhauto is %d", ctxConfig->isSupportDhAuto); + + // Setting insecure renegotiation callback + // 34th parameter + ret = strcpy_s(ctxConfig->noSecRenegotiationCb, sizeof(ctxConfig->noSecRenegotiationCb), string[index++]); + ASSERT_RETURN(ret == EOK, "strcpy_s Error"); + LOG_DEBUG("Remote Process Set Ctx noSecRenegotiationCb is %s", ctxConfig->noSecRenegotiationCb); + + // Sets the TLS1.3 key exchange mode. The parameter indicates the TLS1.3 key exchange mode, + // which is converted into a decimal number. + ctxConfig->keyExchMode = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx keyExchMode is %u", ctxConfig->keyExchMode); + + // The parameter indicates the SupportType callback type, which converts characters into decimal numbers. + ctxConfig->SupportType = (int)strtol(string[index++], NULL, 10); + LOG_DEBUG("Remote Process Set Ctx SupportType is %d", ctxConfig->SupportType); + + ctxConfig->isSupportPostHandshakeAuth = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + + // Sets whether to verify the keyusage in the certificate. The keyusage is converted into a decimal number. + ctxConfig->needCheckKeyUsage = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx needCheckKeyUsage is %d", ctxConfig->needCheckKeyUsage); + + // Set whether to continue the handshake when the verification of peer certificate fails + ctxConfig->isSupportVerifyNone = (((int)strtol(string[index++], NULL, 10)) > 0) ? true : false; + LOG_DEBUG("Remote Process Set Ctx isSupportVerifyNone is %d", ctxConfig->isSupportVerifyNone); + + // Setting the info cb + ctxConfig->infoCb = NULL; // The pointer cannot be transferred. Set this parameter to null. + + return SUCCESS; +} diff --git a/testcode/framework/tls/process/src/process.c b/testcode/framework/tls/process/src/process.c new file mode 100644 index 00000000..4fb303fb --- /dev/null +++ b/testcode/framework/tls/process/src/process.c @@ -0,0 +1,411 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "lock.h" +#include "hlt.h" +#include "logger.h" +#include "tls_res.h" +#include "channel_res.h" +#include "control_channel.h" +#include "rpc_func.h" +#include "hitls.h" +#include "hitls_config.h" +#include "process.h" + +#define SUCCESS 0 +#define ERROR (-1) +#define CMD_MAX_LEN (512) +#define DOMAIN_PATH_LEN (128) +#define START_PROCESS_CMD "./process %d ./%s_%d ./%s %d > ./%s_%d.log &" + +#define ASSERT_RETURN(condition, log) \ + do { \ + if (!(condition)) { \ + LOG_ERROR(log); \ + return ERROR; \ + } \ + } while (0) + +typedef struct ProcessRes { + Process *process; + struct ProcessRes *next; +} ProcessRes; + +typedef struct ProcessList { + ProcessRes *processRes; + uint8_t num; +} ProcessList; + +static ProcessList g_processList; +static Process *g_process = NULL; +static int g_processIndex = 0; + +// Initialization process linked list, which is used only in the Local Process process and is used to save the Remote +// Process. +int InitProcessList(void) +{ + g_processList.processRes = (ProcessRes*)malloc(sizeof(ProcessRes)); + ASSERT_RETURN(g_processList.processRes != NULL, "Malloc ProcessRes Error"); + memset_s(g_processList.processRes, sizeof(ProcessRes), 0, sizeof(ProcessRes)); + g_processList.num = 0; + return SUCCESS; +} + +// Inserts a process to a linked list. Currently, only remote processes are stored. +int InsertProcessToList(Process *tmpProcess) +{ + ProcessRes *frontProcessRes = g_processList.processRes; + ProcessRes *nextProcessRes = NULL; + ProcessRes *tmpProcessRes; + ASSERT_RETURN(tmpProcess != NULL, "TmpProcess is NULL"); + // Find the last process resource. The obtained frontProcessRes is the last process resource. + nextProcessRes = frontProcessRes->next; + while (nextProcessRes != NULL) { + frontProcessRes = nextProcessRes; + nextProcessRes = frontProcessRes->next; + } + // Applying for Process Resources + tmpProcessRes = (ProcessRes*)malloc(sizeof(ProcessRes)); + ASSERT_RETURN(tmpProcessRes != NULL, "Malloc ProcessRes Error"); + tmpProcessRes->process = tmpProcess; + tmpProcessRes->next = NULL; + frontProcessRes->next = tmpProcessRes; + g_processList.num++; + return SUCCESS; +} + +Process *GetProcessFromList(void) +{ + ProcessRes *headProcessRes = g_processList.processRes; + ProcessRes *firstProcessRes, *nextProcessRes; + Process* resultProcess; + + if (g_processList.num == 0) { + return NULL; + } + + // Find the last element + firstProcessRes = headProcessRes->next; + nextProcessRes = firstProcessRes; + while ((nextProcessRes != NULL) && (nextProcessRes->next != NULL)) { + firstProcessRes = nextProcessRes; + nextProcessRes = firstProcessRes->next; + } + resultProcess = firstProcessRes->process; + firstProcessRes->next = NULL; + g_processList.num--; + return resultProcess; +} + +void FreeProcessResList(void) +{ + ProcessRes *frontProcessRes = g_processList.processRes; + ProcessRes *nextProcessRes = NULL; + ProcessRes *tmpProcessRes = NULL; + + nextProcessRes = frontProcessRes->next; + while (nextProcessRes != NULL) { + tmpProcessRes = nextProcessRes->next; + free(nextProcessRes); + nextProcessRes = tmpProcessRes; + } + + free(g_processList.processRes); + memset_s(&g_processList, sizeof(g_processList), 0, sizeof(g_processList)); + return; +} + +int InitProcess(void) +{ + g_process= (Process*)malloc(sizeof(Process)); + ASSERT_RETURN(g_process != NULL, "Malloc ProcessRes Error"); + (void)memset_s(g_process, sizeof(Process), 0, sizeof(Process)); + return SUCCESS; +} + +Process *GetProcess(void) +{ + return g_process; +} + +void FreeProcess(void) +{ + if (g_process != NULL) { + free(g_process); + g_process = NULL; + } + return; +} + +void MonitorControlChannel(void) +{ + fd_set fdSet; + char *endPtr = NULL; + int ret, fdMax, index; + ControlChannelBuf dataBuf; + ControlChannelRes *channelInfo; + channelInfo = GetControlChannelRes(); + int32_t fd = channelInfo->sockFd; + fdMax = fd + 1; + struct timeval stTimeOut = {0}; + while (!channelInfo->isExit) { + stTimeOut.tv_sec = 1; + stTimeOut.tv_usec = 0; + FD_ZERO(&fdSet); + FD_SET(fd, &fdSet); + ret = select(fdMax, &fdSet, NULL, NULL, &stTimeOut); + if (ret <= 0) { + LOG_ERROR("Select Error"); + continue; + } + + if (FD_ISSET(fd, &fdSet)) { + ret = ControlChannelRead(fd, &dataBuf); + if (ret != SUCCESS) { + LOG_ERROR("ControlChannelRead Error"); + continue; + } + CmdData cmdData = {0}; + ret = ParseCmdFromStr(dataBuf.data, &cmdData); + index = (int)strtol(cmdData.id, &endPtr, 0) % MAX_RCV_BUFFER_NUM; + ret = PushResultToChannelIdBuffer(channelInfo, dataBuf.data, index); + if (ret != SUCCESS) { + LOG_ERROR("PushResultToChannelRcvBuffer Error"); + return; + } + LOG_DEBUG("Local Process Rcv is %s", dataBuf.data); + } else { + LOG_ERROR("FD_ISSET Error"); + } + } +} + +HLT_Process *InitSrcProcess(TLS_TYPE tlsType, char *srcDomainPath) +{ + int ret, srcPathLen; + ControlChannelRes *channelInfo; + char srcControlDomainPath[DOMAIN_PATH_LEN] = {0}; + HLT_Process *process; + + // Check whether the call is the first time. + process = GetProcess(); + if (process != NULL) { + LOG_ERROR("Repeat Init LocalProcess Is Not Support"); + return NULL; + } + + // The printf output buffer is not set. + setbuf(stdout, NULL); + + // Initializes the command statistics global variable, which is required only by the local process. + InitCmdIndex(); + + srcPathLen = strlen(srcDomainPath); + if (srcPathLen == 0) { + LOG_ERROR("srcDomainPath is NULL"); + return NULL; + } + + ret = sprintf_s(srcControlDomainPath, DOMAIN_PATH_LEN, "%s.%u.sock", basename(srcDomainPath), getpid()); + + ret = InitProcess(); + if (ret != SUCCESS) { + LOG_ERROR("InitProcess Error"); + return NULL; + } + + process = GetProcess(); + + if (HLT_LibraryInit(tlsType) != SUCCESS) { + LOG_ERROR("HLT_TlsRegCallback ERROR is %d", ret); + goto ERR; + } + + // Initialize the process resource linked list, which is used to store remote process resources. + ret = InitProcessList(); + if (ret != SUCCESS) { + LOG_ERROR("InitProcessList ERROR"); + goto ERR; + } + + // Initializes the CTX SSL resource linked list. + ret = InitTlsResList(); + if (ret != SUCCESS) { + LOG_ERROR("InitTlsResList ERROR"); + goto ERR; + } + + // Initialize the control link. + ret = InitControlChannelRes(srcControlDomainPath, strlen(srcControlDomainPath), NULL, 0); + if (ret != SUCCESS) { + LOG_ERROR("InitControlChannelRes ERROR"); + goto ERR; + } + + channelInfo = GetControlChannelRes(); + + // Create control link UDP domain socket + ret = ControlChannelInit(channelInfo); + if (ret != SUCCESS) { + LOG_ERROR("ControlChannelInit ERROR"); + goto ERR; + } + + // Start a thread to listen to the control link. The link is used to receive the results returned by other processes + pthread_t tId; + channelInfo->isExit = false; + if (pthread_create(&tId, NULL, (void*)MonitorControlChannel, NULL) != 0) { + LOG_ERROR("Create MonitorControlChannel Thread Error ..."); + goto ERR; + } + channelInfo->tid = tId; + + // Populate Process Information + process->tlsType = tlsType; + process->controlChannelFd = channelInfo->sockFd; + process->remoteFlag = 0; + process->tlsResNum = 0; + process->hltTlsResNum = 0; + process->connType = NONE_TYPE; + process->connFd = 0; + ret = memcpy_s(process->srcDomainPath, DOMAIN_PATH_LEN, srcControlDomainPath, strlen(srcControlDomainPath)); + if (ret != EOK) { + LOG_ERROR("memcpy_s process->srcDomainPath ERROR"); + goto ERR; + } + LOG_DEBUG("Init Local Process Successful"); + return (HLT_Process*)process; + +ERR: + free(process); + return NULL; +} + +HLT_Process *InitPeerProcess(TLS_TYPE tlsType, HILT_TransportType connType, int port, bool isBlock) +{ + // peerDomainPath address, which is the IP address of the monitoring process. + // Creating a Process + int ret, peerPathLen, tryNum; + char startCmd[CMD_MAX_LEN] = {0}; + HLT_Process *localProcess; + HLT_Process *process = NULL; + + localProcess = GetProcess(); + if (localProcess == NULL) { + LOG_ERROR("Must Call HLT_InitLocalProcess First"); + return NULL; + } + + peerPathLen = strlen(localProcess->srcDomainPath); + if (peerPathLen == 0) { + LOG_ERROR("peerDomainPath is NULL"); + return NULL; + } + + process = (HLT_Process*)malloc(sizeof(HLT_Process)); + if (process == NULL) { + LOG_ERROR("Malloc Process is NULL"); + return NULL; + } + (void)memset_s(process, sizeof(HLT_Process), 0, sizeof(HLT_Process)); + pid_t localpid = getpid(); + ret = sprintf_s(startCmd, + CMD_MAX_LEN, + START_PROCESS_CMD, + tlsType, + localProcess->srcDomainPath, + g_processIndex, + localProcess->srcDomainPath, + localpid, + localProcess->srcDomainPath, + g_processIndex); + if (ret == 0) { + LOG_ERROR("sprintf_s Error"); + free(process); + return NULL; + } + + LOG_DEBUG("Exect Cmd is %s", startCmd); + ret = system(startCmd); + if (ret == ERROR) { + LOG_ERROR("System Error"); + free(process); + return NULL; + } + + // After the remote process is started successfully, the remote process is stored in the linked list. + InsertProcessToList(process); + + // The message is received, indicating that the peer end is in the receiveable state. + CmdData expectCmdData = {0}; + (void)sprintf_s(expectCmdData.id, sizeof(expectCmdData.id), "0"); + (void)sprintf_s(expectCmdData.funcId, sizeof(expectCmdData.funcId), "HEART"); + tryNum = 0; + do { + ret = WaitResultFromPeer(&expectCmdData); + tryNum++; + } while ((ret == ERROR) && (tryNum < 2)); // Retry once + + if (ret == ERROR) { + LOG_ERROR("WaitResultFromPeer Error"); + goto ERR; + } + + // Populate Process Information + process->connType = NONE_TYPE; + process->connFd = 0; + process->tlsType = tlsType; + process->remoteFlag = 1; + ret = sprintf_s(process->srcDomainPath, DOMAIN_PATH_LEN, "%s_%d", localProcess->srcDomainPath, g_processIndex); + if (ret <= 0) { + LOG_ERROR("sprintf_s Error"); + goto ERR; + } + // Creating a Data Link + if (connType != NONE_TYPE) { + DataChannelParam channelParam; + HLT_FD sockFd = {0}; + channelParam.port = port; + channelParam.type = connType; + channelParam.isBlock = isBlock; // The SCTP link is set to non-block. Otherwise, the SCTP link may be suspended. + sockFd = HLT_CreateDataChannel(process, localProcess, channelParam); + localProcess->connType = connType; + localProcess->connFd = sockFd.peerFd; + localProcess->sockAddr = sockFd.sockAddr; + process->connType = connType; + process->connFd = sockFd.srcFd; + process->connPort = sockFd.connPort; + if ((sockFd.srcFd <= 0) || (sockFd.peerFd <= 0)) { + LOG_ERROR("Create CHANNEL ERROR"); + goto ERR; + } + } + g_processIndex++; + return (HLT_Process*)process; +ERR: + // You do not need to release the process. If you can go to this point, + // the process is successfully created and inserted into the table. + // The process resource is released in the HLT_FreeAllProcess function. + // If the remote process is released in advance, the remote process may be successfully started but cannot be exited + g_processIndex++; + return NULL; +} diff --git a/testcode/framework/tls/resource/include/channel_res.h b/testcode/framework/tls/resource/include/channel_res.h new file mode 100644 index 00000000..7ca961fe --- /dev/null +++ b/testcode/framework/tls/resource/include/channel_res.h @@ -0,0 +1,98 @@ +/* + * 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 CHANNEL_RES_H +#define CHANNEL_RES_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "lock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONTROL_CHANNEL_MAX_MSG_LEN (20 * 1024) +#define DOMAIN_PATH_LEN (128) +#define MAX_SEND_BUFFER_NUM (100) +#define MAX_RCV_BUFFER_NUM (100) + +typedef struct { + uint8_t *data; + uint32_t dataLen; +} DataBuf; + +typedef struct { + char data[CONTROL_CHANNEL_MAX_MSG_LEN]; + uint32_t dataLen; +} ControlChannelBuf; + +typedef struct { + char srcDomainPath[DOMAIN_PATH_LEN]; + char peerDomainPath[DOMAIN_PATH_LEN]; + struct sockaddr_un srcAddr; + struct sockaddr_un peerAddr; + int32_t sockFd; + char sendBuffer[MAX_SEND_BUFFER_NUM][CONTROL_CHANNEL_MAX_MSG_LEN]; + char rcvBuffer[MAX_RCV_BUFFER_NUM][CONTROL_CHANNEL_MAX_MSG_LEN]; + uint8_t sendBufferNum; + Lock *sendBufferLock; + uint8_t rcvBufferNum; + Lock *rcvBufferLock; + pthread_t tid; + bool isExit; +} ControlChannelRes; + +/** +* @brief Control Link Resource Initialization +*/ +int InitControlChannelRes(char *srcDomainPath, int srcDomainPathLen, char *peerDomainPath, int peerDomainPathLen); + +/** +* @brief Release control link resources. +*/ +void FreeControlChannelRes(void); + +/** +* @brief Obtaining Control Link Resources +*/ +ControlChannelRes* GetControlChannelRes(void); + +/** +* @brief Writes data to the control link +*/ +int PushResultToChannelSendBuffer(ControlChannelRes *channelInfo, char *result); + +/** +* @brief Read data from the control link +*/ +int PushResultToChannelRcvBuffer(ControlChannelRes *channelInfo, char *result); + +/** +* @brief Writes data to the control link by ID +*/ +int PushResultToChannelIdBuffer(ControlChannelRes *channelInfo, char *result, int id); + +#ifdef __cplusplus +} +#endif + +#endif // CHANNEL_RES_H diff --git a/testcode/framework/tls/resource/include/tls_res.h b/testcode/framework/tls/resource/include/tls_res.h new file mode 100644 index 00000000..8e488ac5 --- /dev/null +++ b/testcode/framework/tls/resource/include/tls_res.h @@ -0,0 +1,94 @@ +/* + * 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 TLS_RES_H +#define TLS_RES_H + +#include +#include "lock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Res { + void *tlsRes; // Indicates the CTX or SSL resource. + int ctxId; // This field is used only in sslList, indicating the ctx from which the SSL is generated. + struct Res *next; + uint8_t id; // Indicates the sequence number of a resource, that is, the number of times that the resource + // is created. The value starts from 0. +} Res; + +typedef struct { + Res *res; + uint8_t num; + Lock *resListLock; +} ResList; + +/** +* @brief Initializing the TLS Resource Linked List +*/ +int InitTlsResList(void); + +/** +* @brief Releasing the TLS Resource Linked List +*/ +void FreeTlsResList(void); + +/** +* @brief Releases CTX and SSL resources in the linked list based on CTX resources. +*/ +int FreeResFromSsl(const void *ctx); + +/** +* @brief Insert CTX resources into the linked list. +*/ +int InsertCtxToList(void *ctx); + +/** +* @brief Insert SSL resources into the linked list. +*/ +int InsertSslToList(void* ctx, void *ssl); + +/** +* @brief Obtains the CTX linked list from the linked list. +*/ +ResList* GetCtxList(void); + +/** +* @brief Obtains the SSL linked list from the linked list. +*/ +ResList* GetSslList(void); + +/** +* @brief Obtain the CTX from the CTX linked list based on the ID. +*/ +int GetCtxIdFromSsl(const void* tls); + +/** +* @brief Obtains the TLS RES in the linked list. +*/ +Res* GetResFromTlsResList(ResList *resList, const void* tlsRes); + +/** +* @brief Obtains TLS RES from the linked list based on the ID. +*/ +void* GetTlsResFromId(ResList *resList, int id); + +#ifdef __cplusplus +} +#endif + +#endif // TLS_RES_H diff --git a/testcode/framework/tls/resource/src/channel_res.c b/testcode/framework/tls/resource/src/channel_res.c new file mode 100644 index 00000000..51bb3c95 --- /dev/null +++ b/testcode/framework/tls/resource/src/channel_res.c @@ -0,0 +1,187 @@ +/* + * 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 +#include "logger.h" +#include "securec.h" +#include "lock.h" +#include "channel_res.h" + +#define SUCCESS 0 +#define ERROR (-1) + +static ControlChannelRes g_channelRes; + +static int SetControlChannelRes(ControlChannelRes *channelInfo, char *srcDomainPath, char *peerDomainPath) +{ + int ret; + + // Translate the source address. + ret = memset_s(&(channelInfo->srcAddr), sizeof(struct sockaddr_un), 0, sizeof(struct sockaddr_un)); + if (ret != EOK) { + LOG_ERROR("memset_s Error\n"); + return ERROR; + } + + ret = memcpy_s(channelInfo->srcDomainPath, DOMAIN_PATH_LEN, srcDomainPath, strlen(srcDomainPath)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error\n"); + return ERROR; + } + + channelInfo->srcAddr.sun_family = AF_UNIX; + ret = strcpy_s(channelInfo->srcAddr.sun_path, strlen(srcDomainPath) + 1, srcDomainPath); + if (ret != EOK) { + LOG_ERROR("strcpy_s Error"); + return ERROR; + } + + ret = memset_s(channelInfo->peerDomainPath, sizeof(channelInfo->peerDomainPath), + 0, sizeof(channelInfo->peerDomainPath)); + if (ret != EOK) { + LOG_ERROR("memset_s Error\n"); + return ERROR; + } + + if (peerDomainPath != NULL) { + ret = memcpy_s(channelInfo->peerDomainPath, DOMAIN_PATH_LEN, peerDomainPath, strlen(peerDomainPath)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error\n"); + return ERROR; + } + + channelInfo->peerAddr.sun_family = AF_UNIX; + ret = strcpy_s(channelInfo->peerAddr.sun_path, strlen(peerDomainPath) + 1, peerDomainPath); + if (ret != EOK) { + LOG_ERROR("strcpy_s Error"); + return ERROR; + } + } + return SUCCESS; +} + +int InitControlChannelRes(char *srcDomainPath, int srcDomainPathLen, char *peerDomainPath, int peerDomainPathLen) +{ + int ret; + if ((srcDomainPathLen <= 0) && (peerDomainPathLen <= 0)) { + LOG_ERROR("srcDomainPathLen or peerDomainPathLen is 0"); + return ERROR; + } + ret = memset_s(&g_channelRes, sizeof(ControlChannelRes), 0, sizeof(ControlChannelRes)); + if (ret != EOK) { + return ERROR; + } + + // Initializing the Send Buffer Lock + g_channelRes.sendBufferLock = OsLockNew(); + if (g_channelRes.sendBufferLock == NULL) { + LOG_ERROR("OsLockNew Error"); + return ERROR; + } + + // Initialize the receive buffer lock. + g_channelRes.rcvBufferLock = OsLockNew(); + if (g_channelRes.rcvBufferLock == NULL) { + LOG_ERROR("OsLockNew Error"); + return ERROR; + } + + // Initializes the communication address used for UDP Domain Socket communication. + ret = SetControlChannelRes(&g_channelRes, srcDomainPath, peerDomainPath); + + return ret; +} + +ControlChannelRes *GetControlChannelRes() +{ + return &g_channelRes; +} + +int PushResultToChannelSendBuffer(ControlChannelRes *channelInfo, char *result) +{ + int ret; + OsLock(channelInfo->sendBufferLock); + if (channelInfo->sendBufferNum == MAX_SEND_BUFFER_NUM) { + LOG_ERROR("Channel Send Buffer Is Full, Please Try Again"); + OsUnLock(channelInfo->sendBufferLock); + return 1; // The value 1 indicates that the current buffer is full and needs to be retried. + } + (void)memset_s(channelInfo->sendBuffer + channelInfo->sendBufferNum, + CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN); + ret = memcpy_s(channelInfo->sendBuffer + channelInfo->sendBufferNum, + CONTROL_CHANNEL_MAX_MSG_LEN, result, strlen(result)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + OsUnLock(channelInfo->sendBufferLock); + return ERROR; + } + channelInfo->sendBufferNum++; + channelInfo->sendBufferNum %= MAX_SEND_BUFFER_NUM; + OsUnLock(channelInfo->sendBufferLock); + return SUCCESS; +} + +int PushResultToChannelRcvBuffer(ControlChannelRes *channelInfo, char *result) +{ + int ret; + OsLock(channelInfo->rcvBufferLock); + if (channelInfo->rcvBufferNum == MAX_RCV_BUFFER_NUM) { + LOG_ERROR("Channel Send Buffer Is Full, Please Try Again"); + OsUnLock(channelInfo->rcvBufferLock); + return 1; // The value 1 indicates that the current buffer is full and needs to be retried. + } + (void)memset_s(channelInfo->rcvBuffer + channelInfo->rcvBufferNum, + CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN); + ret = memcpy_s(channelInfo->rcvBuffer + channelInfo->rcvBufferNum, + CONTROL_CHANNEL_MAX_MSG_LEN, result, strlen(result)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + OsUnLock(channelInfo->rcvBufferLock); + return ERROR; + } + channelInfo->rcvBufferNum++; + channelInfo->rcvBufferNum %= MAX_RCV_BUFFER_NUM; + OsUnLock(channelInfo->rcvBufferLock); + return SUCCESS; +} + +int PushResultToChannelIdBuffer(ControlChannelRes *channelInfo, char *result, int id) +{ + int ret; + OsLock(channelInfo->rcvBufferLock); + (void)memset_s(channelInfo->rcvBuffer + (id % MAX_RCV_BUFFER_NUM), + CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN); + ret = memcpy_s(channelInfo->rcvBuffer + (id % MAX_RCV_BUFFER_NUM), + CONTROL_CHANNEL_MAX_MSG_LEN, result, strlen(result)); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + OsUnLock(channelInfo->rcvBufferLock); + return ERROR; + } + OsUnLock(channelInfo->rcvBufferLock); + return SUCCESS; +} + +void FreeControlChannelRes(void) +{ + if (g_channelRes.tid != 0) { + g_channelRes.isExit = true; + pthread_join(g_channelRes.tid, NULL); + } + OsLockDestroy(g_channelRes.sendBufferLock); + OsLockDestroy(g_channelRes.rcvBufferLock); + memset_s(&g_channelRes, sizeof(g_channelRes), 0, sizeof(g_channelRes)); + return; +} diff --git a/testcode/framework/tls/resource/src/tls_res.c b/testcode/framework/tls/resource/src/tls_res.c new file mode 100644 index 00000000..df428146 --- /dev/null +++ b/testcode/framework/tls/resource/src/tls_res.c @@ -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 +#include +#include "securec.h" +#include "lock.h" +#include "logger.h" +#include "hitls_func.h" +#include "process.h" +#include "tls_res.h" + +#define SUCCESS 0 +#define ERROR (-1) + +ResList g_ctxList; +ResList g_sslList; + +int InitTlsResList(void) +{ + // Initializes the CTX resource management linked list. + (void)memset_s(&g_ctxList, sizeof(ResList), 0, sizeof(ResList)); + g_ctxList.resListLock = OsLockNew(); + if (g_ctxList.resListLock == NULL) { + LOG_ERROR("OsLockNew Error"); + return ERROR; + } + // Indicates the head element in the linked list, which does not store any resource. + g_ctxList.res = (Res *)malloc(sizeof(Res)); + if (g_ctxList.res == NULL) { + OsLockDestroy(g_ctxList.resListLock); + return ERROR; + } + (void)memset_s(g_ctxList.res, sizeof(Res), 0, sizeof(Res)); + g_ctxList.num = 0; + + // Initializing the SSL Resource Management Linked List + (void)memset_s(&g_sslList, sizeof(ResList), 0, sizeof(ResList)); + g_sslList.resListLock = OsLockNew(); + if (g_sslList.resListLock == NULL) { + LOG_ERROR("OsLockNew Error"); + free(g_ctxList.res); + OsLockDestroy(g_ctxList.resListLock); + g_ctxList.resListLock = NULL; + return ERROR; + } + // Indicates the head element in the linked list, which does not store any resource. + g_sslList.res = (Res *)malloc(sizeof(Res)); + if (g_sslList.res == NULL) { + free(g_ctxList.res); + OsLockDestroy(g_ctxList.resListLock); + OsLockDestroy(g_sslList.resListLock); + return ERROR; + } + (void)memset_s(g_sslList.res, sizeof(Res), 0, sizeof(Res)); + g_sslList.num = 0; + return SUCCESS; +} + +int InsertResToList(ResList *resList, Res tempRes) +{ + int id; + Res *curRes = NULL; + Res *res = (Res*)malloc(sizeof(Res)); + if (res == NULL) { + return ERROR; + } + memset_s(res, sizeof(Res), 0, sizeof(Res)); + + // Insert in the lock + OsLock(resList->resListLock); + + id = resList->num; + + res->ctxId = tempRes.ctxId; + res->tlsRes = tempRes.tlsRes; + res->next = NULL; + res->id = id; + // In the linked list, the first element is NULL by default and is used as the start element. + curRes = resList->res->next; + // When the first element is empty + if (curRes == NULL) { + resList->res->next = res; + resList->num++; + OsUnLock(resList->resListLock); + return id; + } + // Find the tail element + while (curRes->next != NULL) { + curRes = curRes->next; + } + curRes->next = res; + resList->num++; + OsUnLock(resList->resListLock); + return id; +} + +int InsertCtxToList(void *tlsRes) +{ + ResList *resList = GetCtxList(); + Res ctxRes = {0}; + ctxRes.tlsRes = tlsRes; + ctxRes.ctxId = -1; // This field is used only in the SSL linked list. + return InsertResToList(resList, ctxRes); +} + +static int GetTlsIdFromResList(ResList *resList, const void *tls) +{ + Res *tlsRes = GetResFromTlsResList(resList, tls); + if (tlsRes == NULL) { + LOG_ERROR("GetResFromTlsResList ERROR"); + return ERROR; + } + // Indicates the serial number of a resource. + return tlsRes->id; +} + +int InsertSslToList(void *ctx, void *ssl) +{ + int ctxId; + Res sslRes = {0}; + ResList *ctxList = GetCtxList(); + ResList *sslList = GetSslList(); + + ctxId = GetTlsIdFromResList(ctxList, ctx); + if (ctxId == ERROR) { + LOG_ERROR("GetTlsIdFromResList Error"); + return ERROR; + } + + sslRes.tlsRes = ssl; + sslRes.ctxId = ctxId; // This field is used only in the SSL linked list and indicates the CTX that is created. + return InsertResToList(sslList, sslRes); +} + +ResList *GetCtxList() +{ + return &g_ctxList; +} + +ResList *GetSslList() +{ + return &g_sslList; +} + +Res *GetResFromTlsResList(ResList *resList, const void *tlsRes) +{ + Res *tmpRes = NULL; + OsLock(resList->resListLock); + // In the linked list, the first element is NULL by default and is used as the start element. + tmpRes = resList->res->next; + while (tmpRes != NULL) { + if (tmpRes->tlsRes == tlsRes) { + OsUnLock(resList->resListLock); + return tmpRes; + } + tmpRes = tmpRes->next; + } + OsUnLock(resList->resListLock); + return NULL; +} + +static Res *GetResFromId(ResList *resList, int id) +{ + Res *tmpRes = NULL; + OsLock(resList->resListLock); + // In the linked list, the first element is NULL by default and is used as the start element. + tmpRes = resList->res->next; + while (tmpRes != NULL) { + if (tmpRes->id == id) { + OsUnLock(resList->resListLock); + return tmpRes; + } + tmpRes = tmpRes->next; + } + OsUnLock(resList->resListLock); + return NULL; +} + +void *GetTlsResFromId(ResList *resList, int id) +{ + Res *res = GetResFromId(resList, id); + if (res == NULL) { + LOG_ERROR("GetResFromId error"); + return NULL; + } + return res->tlsRes; +} + +int GetCtxIdFromSsl(const void *tls) +{ + ResList *sslList = GetSslList(); + Res *tmpRes = GetResFromTlsResList(sslList, tls); + if (tmpRes == NULL) { + LOG_ERROR("GetResFromTlsResList ERROR"); + return ERROR; + } + // CTX ID corresponding to SSL + return tmpRes->ctxId; +} + +static void *GetLastResFromList(ResList *resList) +{ + Res *headRes = resList->res; + Res *frontRes = NULL; + Res *nextRes = NULL; + + if (resList->num == 0) { + return NULL; + } + + frontRes = headRes->next; + nextRes = frontRes; + // Find the last element + while ((nextRes != NULL) && (nextRes->tlsRes != NULL)) { + frontRes = nextRes; + nextRes = frontRes->next; + } + resList->num--; + return frontRes; +} + +void FreeResList(ResList *resList) +{ + Res *curRes = NULL; + Res *tmpRes = NULL; + OsLock(resList->resListLock); + curRes = resList->res->next; + while (curRes != NULL) { + tmpRes = curRes->next; + free(curRes); + curRes = tmpRes; + } + OsUnLock(resList->resListLock); + free(resList->res); + OsLockDestroy(resList->resListLock); +} + +void FreeCtx(TLS_TYPE tlsType, Res *ctxRes) +{ + switch (tlsType) { + case HITLS: + HitlsFreeCtx(ctxRes->tlsRes); + break; + default: + /* Unknown type */ + return; + } + ctxRes->tlsRes = NULL; + return; +} + +void FreeSsl(TLS_TYPE tlsType, Res *sslRes) +{ + switch (tlsType) { + case HITLS: + HitlsFreeSsl(sslRes->tlsRes); + break; + default: + /* Unknown type */ + return; + } + sslRes->tlsRes = NULL; + return; +} + +void FreeTlsResList(void) +{ + Process *process = GetProcess(); + TLS_TYPE type = process->tlsType; + + // Clearing CTX Resources + ResList *ctxList = GetCtxList(); + void *resCtx; + resCtx = GetLastResFromList(ctxList); + while (resCtx != NULL) { + FreeCtx(type, resCtx); + resCtx = GetLastResFromList(ctxList); + } + FreeResList(ctxList); + + // Clearing SSL Resources + ResList *sslList = GetSslList(); + void *sslRes; + sslRes = GetLastResFromList(sslList); + while (sslRes != NULL) { + FreeSsl(type, sslRes); + sslRes = GetLastResFromList(sslList); + } + FreeResList(sslList); + return; +} + +int FreeResFromSsl(const void *ctx) +{ + Process *process = GetProcess(); + TLS_TYPE type = process->tlsType; + ResList *sslList = GetSslList(); + Res *preRes = NULL; + Res *curRes = NULL; + Res *nextRes = NULL; + + OsLock(sslList->resListLock); + preRes = sslList->res; + curRes = sslList->res->next; + while (curRes != NULL) { + if (curRes->tlsRes == ctx) { + nextRes = curRes->next; + FreeSsl(type, curRes); + FreeCtx(type, curRes); + free(curRes); + preRes->next = nextRes; + sslList->num--; + OsUnLock(sslList->resListLock); + return SUCCESS; + } + preRes = curRes; + curRes = curRes->next; + } + OsUnLock(sslList->resListLock); + return ERROR; +} \ No newline at end of file diff --git a/testcode/framework/tls/rpc/include/common_func.h b/testcode/framework/tls/rpc/include/common_func.h new file mode 100644 index 00000000..8979e237 --- /dev/null +++ b/testcode/framework/tls/rpc/include/common_func.h @@ -0,0 +1,88 @@ +/* + * 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 COMMON_FUNC_H +#define COMMON_FUNC_H + +#include +#include "hlt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + EE_CERT, + PRIVE_KEY, + CA_CERT, + CHAIN_CERT +} CERT_TYPE; + +typedef struct { + atomic_int mallocCnt; + atomic_int freeCnt; + atomic_int mallocSize; + atomic_int freeSize; + atomic_int maxMemSize; +} MemCnt; + +/** +* @brief Load a certificate from a file. +*/ +int LoadCertFromFile(void *ctx, char *pCert, CERT_TYPE certType); + +/** +* @brief Memory application that contains the count +*/ +void *CountMalloc(uint32_t len); + +/** +* @brief Memory release that contains the count +*/ +void CountFree(void *addr); + +/** +* @brief Clear the memory count. +*/ +void ClearMemCntData(void); + +/** +* @brief Obtain the memory count. +*/ +MemCnt *GetMemCntData(void); + +int32_t ExampleSetPsk(char *psk); + +uint32_t ExampleClientCb(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, + uint8_t *psk, uint32_t maxPskLen); + +uint32_t ExampleServerCb(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen); + +int32_t ExampleTicketKeySuccessCb(uint8_t *keyName, uint32_t keyNameSize, void *cipher, uint8_t isEncrypt); +int32_t ExampleTicketKeyRenewCb(uint8_t *keyName, uint32_t keyNameSize, void *cipher, uint8_t isEncrypt); +void *GetTicketKeyCb(char *str); + +void *GetExtensionCb(const char *str); +void *GetExampleData(const char *str); + +int32_t NoSecRenegotiationCb_Success(HITLS_Ctx *ctx); +int32_t NoSecRenegotiationCb_Fail(HITLS_Ctx *ctx); +void *GetNoSecRenegotiationCb(const char *str); + +#ifdef __cplusplus +} +#endif + +#endif // COMMON_FUNC_H \ No newline at end of file diff --git a/testcode/framework/tls/rpc/include/hitls_func.h b/testcode/framework/tls/rpc/include/hitls_func.h new file mode 100644 index 00000000..04bf2cd0 --- /dev/null +++ b/testcode/framework/tls/rpc/include/hitls_func.h @@ -0,0 +1,111 @@ +/* + * 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_FUNC_H +#define HITLS_FUNC_H + +#include "hitls_config.h" +#include "bsl_uio.h" +#include "hlt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief Hitls initialization +*/ +int HitlsInit(void); + +/** +* @brief HiTLS Create connection management resources. +*/ +void* HitlsNewCtx(TLS_VERSION tlsVersion); + +/** +* @brief HiTLS Releases connection management resources. +*/ +void HitlsFreeCtx(void *ctx); + +/** +* @brief HiTLS Setting connection information +*/ +int HitlsSetCtx(HITLS_Config *config, HLT_Ctx_Config *ctxConfig); + +/** +* @brief HiTLS Creating an SSL resource +*/ +void* HitlsNewSsl(void *ctx); + +/** +* @brief HiTLS Releases SSL resources. +*/ +void HitlsFreeSsl(void *ssl); + +/** +* @brief HiTLS Set TLS information. +*/ +int HitlsSetSsl(void *ssl, HLT_Ssl_Config *sslConfig); + +/** +* @brief HiTLS waits for a TLS connection. +*/ +int HitlsAccept(void *ssl); + +/** +* @brief The HiTLS initiates a TLS connection. +*/ +int HitlsConnect(void *ssl); + +/** +* @brief HiTLS writes data through the TLS connection. +*/ +int HitlsWrite(void *ssl, uint8_t *data, uint32_t dataLen); + +/** +* @brief HiTLS reads data through the TLS connection. +*/ +int HitlsRead(void *ssl, uint8_t *data, uint32_t bufSize, uint32_t *readLen); + +/** +* @brief HiTLS Disables the TLS connection. +*/ +int HitlsClose(void *ssl); + +/** +* @brief HiTLS supports renegotiation through TLS connection. +*/ +int HitlsRenegotiate(void *ssl); + +int HitlsSetMtu(void *ssl, uint16_t mtu); + +int HitlsSetSession(void *ssl, void *session); +int HitlsSessionReused(void *ssl); +void *HitlsGet1Session(void *ssl); +int HitlsSessionHasTicket(void *session); +int HitlsSessionIsResumable(void *session); +void HitlsFreeSession(void *session); +int HitlsGetErrorCode(void *ssl); + +/** +* @brief Obtaining method based on the connection type +*/ +BSL_UIO_Method *GetDefaultMethod(BSL_UIO_TransportType type); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_FUNC_H diff --git a/testcode/framework/tls/rpc/include/rpc_func.h b/testcode/framework/tls/rpc/include/rpc_func.h new file mode 100644 index 00000000..755fa153 --- /dev/null +++ b/testcode/framework/tls/rpc/include/rpc_func.h @@ -0,0 +1,177 @@ +/* + * 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 RPC_FUNC_H +#define RPC_FUNC_H + +#include + +#include "handle_cmd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *funcId; + int (*hfunc)(CmdData *cmdData); +} RpcFunList; + +/** +* @brief Obtain the list of registered functions. +*/ +RpcFunList* GetRpcFuncList(void); + +/** +* @brief Obtain the number of registered functions. +*/ +int GetRpcFuncNum(void); + +/** +* @brief Invoke the RPC to create CTX resources. +*/ +int RpcTlsNewCtx(CmdData*); + +/** +* @brief Invoke the RPC to set the CTX information. +*/ +int RpcTlsSetCtx(CmdData*); + +/** +* @brief Invoke the RPC to create an SSL resource. +*/ +int RpcTlsNewSsl(CmdData*); + +/** +* @brief Invoke the RPC to set the SSL information. +*/ +int RpcTlsSetSsl(CmdData*); + +/** +* @brief The RPC invokes the TLS connection to be listened on. +*/ +int RpcTlsListen(CmdData *cmdData); + +/** +* @brief Invoke the RPC to wait for the TLS connection. +*/ +int RpcTlsAccept(CmdData*); + +/** +* @brief Invoke the RPC interface for TLS connection. +*/ +int RpcTlsConnect(CmdData*); + +/** +* @brief Invoke the RPC to read data through TLS. +*/ +int RpcTlsRead(CmdData *cmdData); + +/** +* @brief Invoke the RPC to write data through TLS. +*/ +int RpcTlsWrite(CmdData *cmdData); + +/** +* @brief Invoke the RPC interface to enable renegotiation. +*/ +int RpcTlsRenegotiate(CmdData *cmdData); + +/** +* @brief The RPC call is used to enable the pha. +*/ +int RpcTlsVerifyClientPostHandshake(CmdData *cmdData); + +/** +* @brief The RPC exits the process +*/ +int RpcProcessExit(CmdData*); + +/** +* @brief RPC bound port +*/ +int RunDataChannelBind(void *param); + +/** +* @brief RPC listening data connection +*/ +int RpcDataChannelAccept(CmdData*); + +/** +* @brief The RPC data initiates a connection. +*/ +int RpcDataChannelConnect(CmdData *cmdData); + +/** +* @brief RPC listens on a certain type of data connection. +*/ +int RunDataChannelAccept(void *param); + +/** +* @brief RPC bound port +*/ +int RpcDataChannelBind(CmdData *cmdData); + +/** +* @brief RPC registration hook +*/ +int RpcTlsRegCallback(CmdData *cmdData); + +/** +* @brief RPC Obtain the SSL connection status. +*/ +int RpcTlsGetStatus(CmdData *cmdData); + +/** +* @brief RPC Obtain the flag of the alert message. +*/ +int RpcTlsGetAlertFlag(CmdData *cmdData); + +/** +* @brief RPC Obtain the level of the alert message. +*/ +int RpcTlsGetAlertLevel(CmdData *cmdData); + +/** +* @brief RPC Obtain the description of the alert message. +*/ +int RpcTlsGetAlertDescription(CmdData *cmdData); + +/** +* @brief RPC Disable the TLS connection. +*/ +int RpcTlsClose(CmdData *cmdData); + +/** +* @brief RPC Release the CTX and SSL contexts. +*/ +int RpcFreeResFormSsl(CmdData *cmdData); + +/** +* @brief RPC Disable the SCTP connection. +*/ +int RpcSctpClose(CmdData *cmdData); + +int RpcCloseFd(CmdData *cmdData); + +int RpcTlsSetMtu(CmdData *cmdData); + +int RpcTlsGetErrorCode(CmdData *cmdData); + +#ifdef __cplusplus +} +#endif + +#endif // RPC_FUNC_H diff --git a/testcode/framework/tls/rpc/src/common_func.c b/testcode/framework/tls/rpc/src/common_func.c new file mode 100644 index 00000000..f4137b86 --- /dev/null +++ b/testcode/framework/tls/rpc/src/common_func.c @@ -0,0 +1,448 @@ +/* + * 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 +#include +#include +#include "securec.h" +#include "hitls_crypt_type.h" +#include "hitls_session.h" +#include "logger.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_sni.h" +#include "sni.h" +#include "hitls_alpn.h" +#include "hitls_type.h" +#include "common_func.h" + +#define SUCCESS 0 +#define ERROR (-1) +#define MAX_CERT_PATH_LENGTH (128) +#define SINGLE_CERT_LEN (120) + +#define KEY_NAME_SIZE 16 +#define IV_SIZE 16 +#define KEY_SIZE 32 +#define RENEGOTIATE_FAIL 1 + +static uint8_t g_keyName[KEY_NAME_SIZE] = { + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A +}; + +static uint8_t g_key[KEY_SIZE] = { + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A +}; + +static uint8_t g_iv[IV_SIZE] = { + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A +}; + +typedef struct { + char *name; + void *cb; +} ExampleCb; + +typedef struct { + char *name; + void *(*data)(void); +} ExampleData; + +#define ASSERT_RETURN(condition, log) \ + do { \ + if (!(condition)) { \ + LOG_ERROR(log); \ + return ERROR; \ + } \ + } while (0) + +static char g_localIdentity[PSK_MAX_LEN] = "Client_identity"; +static char g_localPsk[PSK_MAX_LEN] = "1A1A1A1A1A"; + +int32_t ExampleSetPsk(char *psk) +{ + if (psk == NULL) { + LOG_DEBUG("input error."); + return -1; + } + (void)memset_s(g_localPsk, PSK_MAX_LEN, 0, PSK_MAX_LEN); + if (strcpy_s(g_localPsk, PSK_MAX_LEN, psk) != EOK) { + LOG_DEBUG("ExampleSetPsk failed."); + return -1; + } + return 0; +} + +int32_t ExampleHexStr2BufHelper(const uint8_t *input, uint32_t inLen, uint8_t *out, uint32_t outLen, uint32_t *usedLen) +{ + (void)inLen; + (void)outLen; + char indexH[2] = {0}; + char indexL[2] = {0}; + const uint8_t *curr = NULL; + uint8_t *outIndex = NULL; + int32_t high, low; + + if ((input == NULL) || (out == NULL) || (usedLen == NULL)) { + return -1; + } + + for (curr = input, outIndex = out; *curr;) { + indexH[0] = *curr++; + indexL[0] = *curr++; + if (indexL[0] == '\0') { + return -1; + } + + high = (int32_t)strtol(indexH, NULL, 16); // Converting char to Hexadecimal numbers + low = (int32_t)strtol(indexL, NULL, 16); // Converting char to Hexadecimal numbers + + if (high < 0 || low < 0) { + return -1; + } + *outIndex++ = (uint8_t)((high << 4) | low); // The upper four bits of the are shifted to the left + } + + *usedLen = outIndex - out; + + return 0; +} + +uint32_t ExampleClientCb(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, + uint32_t maxPskLen) +{ + (void)ctx; + (void)hint; + int32_t ret; + uint8_t pskTrans[PSK_MAX_LEN] = {0}; + uint32_t pskTransUsedLen = 0u; + + ret = ExampleHexStr2BufHelper((uint8_t *)g_localPsk, sizeof(g_localPsk), pskTrans, PSK_MAX_LEN, &pskTransUsedLen); + if (ret != 0) { + return 0; + } + + /* strlen(g_localIdentity) + 1 copy terminator */ + if (memcpy_s(identity, maxIdentityLen, g_localIdentity, strlen(g_localIdentity) + 1) != EOK) { + return 0; + } + if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { + return 0; + } + return pskTransUsedLen; +} + +uint32_t ExampleServerCb(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen) +{ + (void)ctx; + + if (identity == NULL || strcmp((const char *)identity, g_localIdentity) != 0) { + return 0; + } + + int32_t ret; + uint8_t pskTrans[PSK_MAX_LEN] = {0}; + uint32_t pskTransUsedLen = 0u; + + ret = ExampleHexStr2BufHelper((uint8_t *)g_localPsk, sizeof(g_localPsk), pskTrans, PSK_MAX_LEN, &pskTransUsedLen); + if (ret != 0) { + return 0; + } + + if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { + return 0; + } + + return pskTransUsedLen; +} + +static void SetCipherInfo(void *cipher) +{ + HITLS_CipherParameters *cipherPara = cipher; + cipherPara->type = HITLS_CBC_CIPHER; + cipherPara->algo = HITLS_CIPHER_AES_256_CBC; + cipherPara->key = g_key; + cipherPara->keyLen = sizeof(g_key); + cipherPara->hmacKey = g_key; + cipherPara->hmacKeyLen = sizeof(g_key); + cipherPara->iv = g_iv; + cipherPara->ivLen = sizeof(g_iv); + return; +} + +int32_t ExampleTicketKeySuccessCb(uint8_t *keyName, uint32_t keyNameSize, void *cipher, uint8_t isEncrypt) +{ + if (isEncrypt) { + if (memcpy_s(keyName, keyNameSize, g_keyName, KEY_NAME_SIZE) != EOK) { + return HITLS_TICKET_KEY_RET_FAIL; + } + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_SUCCESS; + } + + if (memcmp(keyName, g_keyName, KEY_NAME_SIZE) != 0) { + return HITLS_TICKET_KEY_RET_FAIL; + } + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_SUCCESS; +} + +int32_t ExampleTicketKeyRenewCb(uint8_t *keyName, uint32_t keyNameSize, void *cipher, uint8_t isEncrypt) +{ + if (isEncrypt) { + if (memcpy_s(keyName, keyNameSize, g_keyName, KEY_NAME_SIZE) != EOK) { + return HITLS_TICKET_KEY_RET_FAIL; + } + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_SUCCESS_RENEW; + } + + if (memcmp(keyName, g_keyName, KEY_NAME_SIZE) != 0) { + return HITLS_TICKET_KEY_RET_FAIL; + } + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_SUCCESS_RENEW; +} + +int32_t ExampleTicketKeyAlertCb(uint8_t *keyName, uint32_t keyNameSize, HITLS_CipherParameters *cipher, + uint8_t isEncrypt) +{ + if (isEncrypt) { + (void)memcpy_s(keyName, keyNameSize, g_keyName, KEY_NAME_SIZE); + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_SUCCESS_RENEW; + } else { + return HITLS_TICKET_KEY_RET_NEED_ALERT; + } +} + +int32_t ExampleTicketKeyFailCb(uint8_t *keyName, uint32_t keyNameSize, HITLS_CipherParameters *cipher, + uint8_t isEncrypt) +{ + if (isEncrypt) { + (void)memcpy_s(keyName, keyNameSize, g_keyName, KEY_NAME_SIZE); + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_SUCCESS_RENEW; + } + + SetCipherInfo(cipher); + return HITLS_TICKET_KEY_RET_FAIL; +} + +int32_t ExampleServerNameCb(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)arg; + *alert = HITLS_ACCEPT_SNI_ERR_OK; + return HITLS_ACCEPT_SNI_ERR_OK; +} + +int32_t ExampleServerNameCbNOACK(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)alert; + (void)arg; + return HITLS_ACCEPT_SNI_ERR_NOACK; +} + +int32_t ExampleServerNameCbALERT(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)alert; + (void)arg; + return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL; +} + +SNI_Arg *g_sniArg; +void *ExampleServerNameArg(void) +{ + return g_sniArg; +} + +static char *g_alpnhttp = "http"; + +int32_t ExampleAlpnParseProtocolList1(uint8_t *out, uint8_t *outLen, uint8_t *in, uint8_t inLen) +{ + if (out == NULL || outLen == NULL || in == NULL) { + return HITLS_NULL_INPUT; + } + + if (inLen == 0) { + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint8_t i = 0u; + uint8_t commaNum = 0u; + uint8_t startPos = 0u; + + for (i = 0u; i <= inLen; ++i) { + if (i == inLen || in[i] == ',') { + if (i == startPos) { + ++startPos; + ++commaNum; + continue; + } + out[startPos - commaNum] = (uint8_t)(i - startPos); + startPos = i + 1; + } else { + out[i + 1 - commaNum] = in[i]; + } + } + + *outLen = inLen + 1 - commaNum; + + return HITLS_SUCCESS; +} + +int32_t ExampleAlpnCb(HITLS_Ctx *ctx, char **selectedProto, uint8_t *selectedProtoSize, char *clientAlpnList, + uint32_t clientAlpnListSize, void *userData) +{ + (void)ctx; + (void)userData; + if (clientAlpnListSize >= 5 && memcmp(clientAlpnList + 1, "http", 4) == 0) { + *selectedProto = clientAlpnList + 1; + *selectedProtoSize = 4; + return HITLS_ALPN_ERR_OK; + } else if (clientAlpnListSize >= 4 && memcmp(clientAlpnList + 1, "ftp", 3) == 0) { + *selectedProto = g_alpnhttp; + *selectedProtoSize = 4; + return HITLS_ALPN_ERR_OK; + } else if (clientAlpnListSize >= 4 && memcmp(clientAlpnList + 1, "mml", 3) == 0) { + *selectedProto = g_alpnhttp; + *selectedProtoSize = 4; + return HITLS_ALPN_ERR_ALERT_FATAL; + } else if (clientAlpnListSize >= 4 && memcmp(clientAlpnList + 1, "www", 3) == 0) { + *selectedProto = g_alpnhttp; + *selectedProtoSize = 4; + return HITLS_ALPN_ERR_OK; + } else { + return HITLS_ALPN_ERR_NOACK; + } +} + +int32_t AlpnCbWARN1(HITLS_Ctx *ctx, uint8_t **selectedProto, uint8_t *selectedProtoSize, uint8_t *clientAlpnList, + uint32_t clientAlpnListSize, void *userData) +{ + (void)ctx; + (void)selectedProto; + (void)selectedProtoSize; + (void)clientAlpnList; + (void)clientAlpnListSize; + (void)userData; + + return HITLS_ALPN_ERR_ALERT_WARNING; +} + +int32_t AlpnCbALERT1(HITLS_Ctx *ctx, uint8_t **selectedProto, uint8_t *selectedProtoSize, uint8_t *clientAlpnList, + uint32_t clientAlpnListSize, void *userData) +{ + (void)ctx; + (void)selectedProto; + (void)selectedProtoSize; + (void)clientAlpnList; + (void)clientAlpnListSize; + (void)userData; + + return HITLS_ALPN_ERR_ALERT_FATAL; +} + +void *ExampleAlpnData(void) +{ + // Return the alpnData address. + return "audata"; +} + +void *GetTicketKeyCb(char *str) +{ + const ExampleCb cbList[] = { + {"ExampleTicketKeySuccessCb", ExampleTicketKeySuccessCb}, + {"ExampleTicketKeyRenewCb", ExampleTicketKeyRenewCb}, + {"ExampleTicketKeyAlertCb", ExampleTicketKeyAlertCb}, + {"ExampleTicketKeyFailCb", ExampleTicketKeyFailCb}, + }; + + int len = sizeof(cbList) / sizeof(cbList[0]); + for (int i = 0; i < len; i++) { + if (strcmp(str, cbList[i].name) == 0) { + return cbList[i].cb; + } + } + return NULL; +} + +int32_t NoSecRenegotiationCb_Success(HITLS_Ctx *ctx) +{ + (void)ctx; + return 0; +} + +int32_t NoSecRenegotiationCb_Fail(HITLS_Ctx *ctx) +{ + (void)ctx; + return RENEGOTIATE_FAIL; +} + +void *GetNoSecRenegotiationCb(const char *str) +{ + const ExampleCb cbList[] = { + {"NoSecRenegotiationCb_Success", NoSecRenegotiationCb_Success}, + {"NoSecRenegotiationCb_Fail", NoSecRenegotiationCb_Fail}, + }; + + int len = sizeof(cbList) / sizeof(cbList[0]); + for (int i = 0; i < len; i++) { + if (strcmp(str, cbList[i].name) == 0) { + return cbList[i].cb; + } + } + return NULL; +} + +void *GetExtensionCb(const char *str) +{ + const ExampleCb cbList[] = { + {"ExampleSNICb", ExampleServerNameCb}, + {"ExampleAlpnCb", ExampleAlpnCb}, + {"ExampleAlpnWarnCb", AlpnCbWARN1}, + {"ExampleAlpAlertCb", AlpnCbALERT1}, + {"ExampleSNICbnoack", ExampleServerNameCbNOACK}, + {"ExampleSNICbAlert", ExampleServerNameCbALERT}, + }; + + int len = sizeof(cbList) / sizeof(cbList[0]); + for (int i = 0; i < len; i++) { + if (strcmp(str, cbList[i].name) == 0) { + return cbList[i].cb; + } + } + return NULL; +} + +void *GetExampleData(const char *str) +{ + const ExampleData cbList[] = { + {"ExampleSNIArg", ExampleServerNameArg}, + {"ExampleAlpnData", ExampleAlpnData}, + }; + + int len = sizeof(cbList) / sizeof(cbList[0]); + for (int i = 0; i < len; i++) { + if (strcmp(str, cbList[i].name) == 0) { + return cbList[i].data(); + } + } + return NULL; +} diff --git a/testcode/framework/tls/rpc/src/hitls_func.c b/testcode/framework/tls/rpc/src/hitls_func.c new file mode 100644 index 00000000..6a19a57a --- /dev/null +++ b/testcode/framework/tls/rpc/src/hitls_func.c @@ -0,0 +1,719 @@ +/* + * 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 +#include +#include +#include + +#include "uio_base.h" +#include "hitls_cert_type.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_psk.h" +#include "hitls_session.h" +#include "hitls_session.h" +#include "hitls_debug.h" +#include "hitls_sni.h" +#include "hitls_alpn.h" +#include "hitls_security.h" +#include "hitls_crypt_init.h" +#include "hlt_type.h" +#include "logger.h" +#include "tls_res.h" +#include "cert_callback.h" +#include "sctp_channel.h" +#include "tcp_channel.h" +#include "common_func.h" +#include "crypt_eal_rand.h" +#include "crypt_algid.h" +#include "channel_res.h" + +#define SUCCESS 0 +#define ERROR (-1) +#define FUNC_TIME_OUT_SEC 120 + +#define ASSERT_RETURN(condition, log) \ + do { \ + if (!(condition)) { \ + LOG_ERROR(log); \ + return ERROR; \ + } \ + } while (0) + +typedef struct { + char *name; + uint16_t configValue; +} HitlsConfig; + +typedef enum { + CIPHER, + GROUPS, + SIGNATURE, + POINTFORMAT, +} HitlsConfigType; + +static const HitlsConfig g_cipherSuiteList[] = { + {"HITLS_RSA_WITH_AES_128_CBC_SHA", HITLS_RSA_WITH_AES_128_CBC_SHA}, + {"HITLS_DHE_DSS_WITH_AES_128_CBC_SHA", HITLS_DHE_DSS_WITH_AES_128_CBC_SHA}, + {"HITLS_DHE_RSA_WITH_AES_128_CBC_SHA", HITLS_DHE_RSA_WITH_AES_128_CBC_SHA}, + {"HITLS_RSA_WITH_AES_256_CBC_SHA", HITLS_RSA_WITH_AES_256_CBC_SHA}, + {"HITLS_DHE_DSS_WITH_AES_256_CBC_SHA", HITLS_DHE_DSS_WITH_AES_256_CBC_SHA}, + {"HITLS_DHE_RSA_WITH_AES_256_CBC_SHA", HITLS_DHE_RSA_WITH_AES_256_CBC_SHA}, + {"HITLS_RSA_WITH_AES_128_CBC_SHA256", HITLS_RSA_WITH_AES_128_CBC_SHA256}, + {"HITLS_RSA_WITH_AES_256_CBC_SHA256", HITLS_RSA_WITH_AES_256_CBC_SHA256}, + {"HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256", HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256}, + {"HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256", HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256}, + {"HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256", HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256}, + {"HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256", HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256}, + {"HITLS_RSA_WITH_AES_128_GCM_SHA256", HITLS_RSA_WITH_AES_128_GCM_SHA256}, + {"HITLS_RSA_WITH_AES_256_GCM_SHA384", HITLS_RSA_WITH_AES_256_GCM_SHA384}, + {"HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256", HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + {"HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384", HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384}, + {"HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256", HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256}, + {"HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384", HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384}, + {"HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, + {"HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, + {"HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, + {"HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, + {"HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}, + {"HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384}, + {"HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, + {"HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384}, + {"HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + {"HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, + {"HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + {"HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, + {"HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_AES_128_GCM_SHA256", HITLS_AES_128_GCM_SHA256}, + {"HITLS_AES_256_GCM_SHA384", HITLS_AES_256_GCM_SHA384}, + {"HITLS_CHACHA20_POLY1305_SHA256", HITLS_CHACHA20_POLY1305_SHA256}, + {"HITLS_AES_128_CCM_SHA256", HITLS_AES_128_CCM_SHA256}, + {"HITLS_AES_128_CCM_8_SHA256", HITLS_AES_128_CCM_8_SHA256}, + {"HITLS_ECDHE_ECDSA_WITH_AES_128_CCM", HITLS_ECDHE_ECDSA_WITH_AES_128_CCM}, + {"HITLS_ECDHE_ECDSA_WITH_AES_256_CCM", HITLS_ECDHE_ECDSA_WITH_AES_256_CCM}, + {"HITLS_DHE_RSA_WITH_AES_128_CCM", HITLS_DHE_RSA_WITH_AES_128_CCM}, + {"HITLS_DHE_RSA_WITH_AES_256_CCM", HITLS_DHE_RSA_WITH_AES_256_CCM}, + {"HITLS_RSA_WITH_AES_256_CCM", HITLS_RSA_WITH_AES_256_CCM}, + {"HITLS_RSA_WITH_AES_256_CCM_8", HITLS_RSA_WITH_AES_256_CCM_8}, + {"HITLS_RSA_WITH_AES_128_CCM", HITLS_RSA_WITH_AES_128_CCM}, + {"HITLS_RSA_WITH_AES_128_CCM_8", HITLS_RSA_WITH_AES_128_CCM_8}, + + /* psk cipher suite */ + {"HITLS_PSK_WITH_AES_128_CBC_SHA", HITLS_PSK_WITH_AES_128_CBC_SHA}, + {"HITLS_PSK_WITH_AES_256_CBC_SHA", HITLS_PSK_WITH_AES_256_CBC_SHA}, + {"HITLS_DHE_PSK_WITH_AES_128_CBC_SHA", HITLS_DHE_PSK_WITH_AES_128_CBC_SHA}, + {"HITLS_DHE_PSK_WITH_AES_256_CBC_SHA", HITLS_DHE_PSK_WITH_AES_256_CBC_SHA}, + {"HITLS_RSA_PSK_WITH_AES_128_CBC_SHA", HITLS_RSA_PSK_WITH_AES_128_CBC_SHA}, + {"HITLS_RSA_PSK_WITH_AES_256_CBC_SHA", HITLS_RSA_PSK_WITH_AES_256_CBC_SHA}, + {"HITLS_PSK_WITH_AES_128_GCM_SHA256", HITLS_PSK_WITH_AES_128_GCM_SHA256}, + {"HITLS_PSK_WITH_AES_256_GCM_SHA384", HITLS_PSK_WITH_AES_256_GCM_SHA384}, + {"HITLS_DHE_PSK_WITH_AES_128_GCM_SHA256", HITLS_DHE_PSK_WITH_AES_128_GCM_SHA256}, + {"HITLS_DHE_PSK_WITH_AES_256_GCM_SHA384", HITLS_DHE_PSK_WITH_AES_256_GCM_SHA384}, + {"HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256", HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256}, + {"HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384", HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384}, + {"HITLS_PSK_WITH_AES_128_CBC_SHA256", HITLS_PSK_WITH_AES_128_CBC_SHA256}, + {"HITLS_PSK_WITH_AES_256_CBC_SHA384", HITLS_PSK_WITH_AES_256_CBC_SHA384}, + {"HITLS_DHE_PSK_WITH_AES_128_CBC_SHA256", HITLS_DHE_PSK_WITH_AES_128_CBC_SHA256}, + {"HITLS_DHE_PSK_WITH_AES_256_CBC_SHA384", HITLS_DHE_PSK_WITH_AES_256_CBC_SHA384}, + {"HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256", HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256}, + {"HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384", HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384}, + {"HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, + {"HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA}, + {"HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256}, + {"HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384}, + {"HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256", HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", HITLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", HITLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256}, + {"HITLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256", HITLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256}, + {"HITLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384", HITLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384}, + {"HITLS_DHE_PSK_WITH_AES_128_CCM", HITLS_DHE_PSK_WITH_AES_128_CCM}, + {"HITLS_DHE_PSK_WITH_AES_256_CCM", HITLS_DHE_PSK_WITH_AES_256_CCM}, + {"HITLS_PSK_WITH_AES_256_CCM", HITLS_PSK_WITH_AES_256_CCM}, + {"HITLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256", HITLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256}, + + /* Anonymous ciphersuite */ + {"HITLS_DH_ANON_WITH_AES_256_CBC_SHA", HITLS_DH_ANON_WITH_AES_256_CBC_SHA}, + {"HITLS_DH_ANON_WITH_AES_128_CBC_SHA", HITLS_DH_ANON_WITH_AES_128_CBC_SHA}, + {"HITLS_DH_ANON_WITH_AES_128_CBC_SHA256", HITLS_DH_ANON_WITH_AES_128_CBC_SHA256}, + {"HITLS_DH_ANON_WITH_AES_256_CBC_SHA256", HITLS_DH_ANON_WITH_AES_256_CBC_SHA256}, + {"HITLS_DH_ANON_WITH_AES_128_GCM_SHA256", HITLS_DH_ANON_WITH_AES_128_GCM_SHA256}, + {"HITLS_DH_ANON_WITH_AES_256_GCM_SHA384", HITLS_DH_ANON_WITH_AES_256_GCM_SHA384}, + {"HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA", HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA}, + {"HITLS_ECDH_ANON_WITH_AES_256_CBC_SHA", HITLS_ECDH_ANON_WITH_AES_256_CBC_SHA}, + {"HITLS_ECDHE_SM4_CBC_SM3", HITLS_ECDHE_SM4_CBC_SM3}, + {"HITLS_ECC_SM4_CBC_SM3", HITLS_ECC_SM4_CBC_SM3}, + + /* error ciphersuite */ + {"HITLS_INVALID_CIPHER_TC01", 0xFFFF}, + {"HITLS_INVALID_CIPHER_TC02", 0xFFFE}, +}; + +static const HitlsConfig g_groupList[] = { + {"HITLS_EC_GROUP_SECP256R1", HITLS_EC_GROUP_SECP256R1}, + {"HITLS_EC_GROUP_SECP384R1", HITLS_EC_GROUP_SECP384R1}, + {"HITLS_EC_GROUP_SECP521R1", HITLS_EC_GROUP_SECP521R1}, + {"HITLS_EC_GROUP_CURVE25519", HITLS_EC_GROUP_CURVE25519}, + {"HITLS_EC_GROUP_SM2", HITLS_EC_GROUP_SM2}, + {"HITLS_INVALID_GROUP_TC01", 0xFF}, + {"HITLS_INVALID_GROUP_TC02", 0xFE}, + {"HITLS_FF_DHE_2048", HITLS_FF_DHE_2048}, + {"HITLS_FF_DHE_3072", HITLS_FF_DHE_3072}, + {"HITLS_FF_DHE_4096", HITLS_FF_DHE_4096}, + {"HITLS_FF_DHE_6144", HITLS_FF_DHE_6144}, + {"HITLS_FF_DHE_8192", HITLS_FF_DHE_8192}, +}; + +static const HitlsConfig g_signatureList[] = { + {"CERT_SIG_SCHEME_RSA_PKCS1_SHA1", CERT_SIG_SCHEME_RSA_PKCS1_SHA1}, + {"CERT_SIG_SCHEME_ECDSA_SHA1", CERT_SIG_SCHEME_ECDSA_SHA1}, + {"CERT_SIG_SCHEME_ECDSA_SHA224", CERT_SIG_SCHEME_ECDSA_SHA224}, + {"CERT_SIG_SCHEME_RSA_PKCS1_SHA224", CERT_SIG_SCHEME_RSA_PKCS1_SHA224}, + {"CERT_SIG_SCHEME_RSA_PKCS1_SHA256", CERT_SIG_SCHEME_RSA_PKCS1_SHA256}, + {"CERT_SIG_SCHEME_RSA_PKCS1_SHA384", CERT_SIG_SCHEME_RSA_PKCS1_SHA384}, + {"CERT_SIG_SCHEME_RSA_PKCS1_SHA512", CERT_SIG_SCHEME_RSA_PKCS1_SHA512}, + {"CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}, + {"CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384", CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384}, + {"CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512", CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512}, + {"CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256", CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256}, + {"CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384", CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384}, + {"CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512", CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512}, + {"CERT_SIG_SCHEME_ED25519", CERT_SIG_SCHEME_ED25519}, + {"CERT_SIG_SCHEME_DSA_SHA1", CERT_SIG_SCHEME_DSA_SHA1}, + {"CERT_SIG_SCHEME_DSA_SHA224", CERT_SIG_SCHEME_DSA_SHA224}, + {"CERT_SIG_SCHEME_DSA_SHA256", CERT_SIG_SCHEME_DSA_SHA256}, + {"CERT_SIG_SCHEME_DSA_SHA384", CERT_SIG_SCHEME_DSA_SHA384}, + {"CERT_SIG_SCHEME_DSA_SHA512", CERT_SIG_SCHEME_DSA_SHA512}, + {"CERT_SIG_SCHEME_SM2_SM3", CERT_SIG_SCHEME_SM2_SM3}, + {"HITLS_INVALID_SIG_TC01", 0xFFFF}, + {"HITLS_INVALID_SIG_TC02", 0xFFFE}, +}; + +static const HitlsConfig g_eccFormatList[] = { + {"HITLS_POINT_FORMAT_UNCOMPRESSED", HITLS_POINT_FORMAT_UNCOMPRESSED}, + {"HITLS_INVALID_FORMAT_TC01", 0xFF}, + {"HITLS_INVALID_FORMAT_TC02", 0xFE}, +}; + +int HitlsInit(void) +{ + int ret; + ret = RegMemCallback(MEM_CALLBACK_DEFAULT); + ret |= RegCertCallback(CERT_CALLBACK_DEFAULT); + CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + HITLS_CryptMethodInit(); + return ret; +} + +HITLS_Config *HitlsNewCtx(TLS_VERSION tlsVersion) +{ + HITLS_Config *hitlsConfig = NULL; + switch (tlsVersion) { + case DTLS1_2: + LOG_DEBUG("HiTLS New DTLS1_2 Ctx"); + hitlsConfig = HITLS_CFG_NewDTLS12Config(); + break; + case TLS1_2: + LOG_DEBUG("HiTLS New TLS1_2 Ctx"); + hitlsConfig = HITLS_CFG_NewTLS12Config(); + break; + case TLS1_3: + LOG_DEBUG("HiTLS New TLS1_3 Ctx"); + hitlsConfig = HITLS_CFG_NewTLS13Config(); + break; + case TLS_ALL: + LOG_DEBUG("HiTLS New TLS_ALL Ctx"); + hitlsConfig = HITLS_CFG_NewTLSConfig(); + break; +#ifndef HITLS_NO_TLCP11 + case TLCP1_1: + LOG_DEBUG("HiTLS New TLCP1_1 Ctx"); + hitlsConfig = HITLS_CFG_NewTLCPConfig(); + break; +#endif + default: + /* Unknown protocol type */ + break; + } + if (hitlsConfig == NULL) { + LOG_ERROR("HITLS Not Support This TlsVersion's ID %d", tlsVersion); + } + return hitlsConfig; +} + +void HitlsFreeCtx(void *ctx) +{ + HITLS_CFG_FreeConfig(ctx); +} + +static int32_t GetConfigVauleFromStr(const HitlsConfig *hitlsConfigList, uint32_t configSize, const char *cipherName) +{ + for (uint32_t i = 0; i < configSize; i++) { + if (strcmp(cipherName, hitlsConfigList[i].name) != 0) { + continue; + } + return hitlsConfigList[i].configValue; + } + return ERROR; // The cipher suite does not exist. +} + +static int8_t HitlsSetConfig(const HitlsConfig *hitlsConfigList, int configListSize, void *ctx, + char *name, HitlsConfigType type) +{ + int ret = 0; + char configArray[MAX_CIPHERSUITES_LEN] = {0}; // A maximum of 512 characters are supported. + char *token, *rest; + int32_t configValue; + uint16_t configValueArray[20] = {0}; // Currently, a maximum of 20 cipher suites are supported. + uint32_t configSize = 0; + ret = memcpy_s(configArray, sizeof(configArray), name, strlen(name)); + ASSERT_RETURN(ret == EOK, "Memcpy Error"); + + configSize = 0; + token = strtok_s(configArray, ":", &rest); + do { + // Currently, a maximum of 20 cipher suites are supported. + ASSERT_RETURN(configSize < 20, "Max Support Set 20 Config"); + configValue = GetConfigVauleFromStr(hitlsConfigList, configListSize, token); + ASSERT_RETURN(configValue != ERROR, "GetConfigVauleFromStr Error"); + configValueArray[configSize] = (uint16_t)configValue; + token = strtok_s(NULL, ":", &rest); + configSize++; + } while (token != NULL); + + switch (type) { + case CIPHER: + ret = HITLS_CFG_SetCipherSuites(ctx, configValueArray, configSize); + break; + case GROUPS: + ret = HITLS_CFG_SetGroups(ctx, configValueArray, configSize); + break; + case SIGNATURE: + ret = HITLS_CFG_SetSignature(ctx, configValueArray, configSize); + break; + case POINTFORMAT: + { + uint8_t pointformatArray[20] = {0}; + for (uint32_t i = 0; i < configSize; i++) { + pointformatArray[i] = configValueArray[i]; + } + ret = HITLS_CFG_SetEcPointFormats(ctx, pointformatArray, configSize); + break; + } + default: + ret = ERROR; + } + + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetXXX Error"); + return SUCCESS; +} + +int HitlsSetCtx(HITLS_Config *outCfg, HLT_Ctx_Config *inCtxCfg) +{ + int ret; + + if (inCtxCfg->setSessionCache >= 0) { + LOG_DEBUG("HiTLS Set SessionCache is %d", inCtxCfg->setSessionCache); + HITLS_CFG_SetSessionCacheMode(outCfg, inCtxCfg->setSessionCache); + } + + // Set the protocol version. + if ((inCtxCfg->minVersion != 0) && (inCtxCfg->maxVersion != 0)) { + LOG_DEBUG("HiTLS Set minVersion is %u maxVersion is %u", inCtxCfg->minVersion, inCtxCfg->maxVersion); + ret = HITLS_CFG_SetVersion(outCfg, inCtxCfg->minVersion, inCtxCfg->maxVersion); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetVersion Error ERROR"); + } + if (inCtxCfg->SupportType == SERVER_CFG_SET_TRUE) { + HITLS_CFG_SetCipherServerPreference(outCfg, true); + } + if (inCtxCfg->SupportType == SERVER_CFG_SET_FALSE) { + HITLS_CFG_SetCipherServerPreference(outCfg, false); + } + // Setting Renegotiation + LOG_DEBUG("HiTLS Set Support Renegotiation is %d", inCtxCfg->isSupportRenegotiation); + ret = HITLS_CFG_SetRenegotiationSupport(outCfg, inCtxCfg->isSupportRenegotiation); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetRenegotiationSupport ERROR"); + + // Whether to enable dual-ended verification + LOG_DEBUG("HiTLS Set Support Client Verify is %d", inCtxCfg->isSupportClientVerify); + ret = HITLS_CFG_SetClientVerifySupport(outCfg, inCtxCfg->isSupportClientVerify); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetClientVerifySupport ERROR"); + + // Indicates whether to allow empty certificate list on the client. + LOG_DEBUG("HiTLS Set Support Not Client Cert is %d", inCtxCfg->isSupportNoClientCert); + ret = HITLS_CFG_SetNoClientCertSupport(outCfg, inCtxCfg->isSupportNoClientCert); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetNoClientCertSupport ERROR"); + + // Whether to enable pha + LOG_DEBUG("HiTLS Set Support pha is %d", inCtxCfg->isSupportPostHandshakeAuth); + ret = HITLS_CFG_SetPostHandshakeAuthSupport(outCfg, inCtxCfg->isSupportPostHandshakeAuth); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetPostHandshakeAuth ERROR"); + + // Indicates whether extended master keys are supported. + LOG_DEBUG("HiTLS Set Support Extend Master Secret is %d", inCtxCfg->isSupportExtendMasterSecret); + ret = HITLS_CFG_SetExtenedMasterSecretSupport(outCfg, inCtxCfg->isSupportExtendMasterSecret); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetExtenedMasterSecretSupport ERROR"); + + // Support CloseCheckKeyUsage + LOG_DEBUG("HiTLS Set CloseCheckKeyUsage is false"); + ret = HITLS_CFG_SetCloseCheckKeyUsage(outCfg, inCtxCfg->needCheckKeyUsage); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetCloseCheckKeyUsage ERROR"); + + // Indicates whether to support sessionTicket. + LOG_DEBUG("HiTLS Set Support SessionTicket is %d", inCtxCfg->isSupportSessionTicket); + ret = HITLS_CFG_SetSessionTicketSupport(outCfg, inCtxCfg->isSupportSessionTicket); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetSessionTicketSupport ERROR"); + + // Whether encrypt-then-mac is supported + LOG_DEBUG("HiTLS Set Support EncryptThenMac is %d", inCtxCfg->isEncryptThenMac); + ret = HITLS_CFG_SetEncryptThenMac(outCfg, (uint32_t)inCtxCfg->isEncryptThenMac); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetEncryptThenMac ERROR"); + + // ECC Point Format Configuration for Asymmetric Algorithms + if (strncmp("NULL", inCtxCfg->pointFormats, strlen(inCtxCfg->pointFormats)) != 0) { + LOG_DEBUG("HiTLS Set PoinFormats is %s", inCtxCfg->pointFormats); + int configListSize = sizeof(g_eccFormatList) / sizeof(g_eccFormatList[0]); + ret = HitlsSetConfig(g_eccFormatList, configListSize, outCfg, inCtxCfg->pointFormats, POINTFORMAT); + ASSERT_RETURN(ret == SUCCESS, "ECC Format ERROR"); + } + + // Loading cipher suites + if (strncmp("NULL", inCtxCfg->cipherSuites, strlen(inCtxCfg->cipherSuites)) != 0) { + LOG_DEBUG("HiTLS Set CipherSuites is %s", inCtxCfg->cipherSuites); + int configListSize = sizeof(g_cipherSuiteList) / sizeof(g_cipherSuiteList[0]); + ret = HitlsSetConfig(g_cipherSuiteList, configListSize, outCfg, inCtxCfg->cipherSuites, CIPHER); + ASSERT_RETURN(ret == SUCCESS, "Hitls Set Cipher ERROR"); + } + + // set groups + if (strncmp("NULL", inCtxCfg->groups, strlen(inCtxCfg->groups)) != 0) { + LOG_DEBUG("HiTLS Set Groups is %s", inCtxCfg->groups); + int configListSize = sizeof(g_groupList) / sizeof(g_groupList[0]); + ret = HitlsSetConfig(g_groupList, configListSize, outCfg, inCtxCfg->groups, GROUPS); + ASSERT_RETURN(ret == SUCCESS, "Hitls Set Group ERROR"); + } + + // signature algorithm + if (strncmp("NULL", inCtxCfg->signAlgorithms, strlen(inCtxCfg->signAlgorithms)) != 0) { + LOG_DEBUG("HiTLS Set SignAlgorithms is %s", inCtxCfg->signAlgorithms); + int configListSize = sizeof(g_signatureList) / sizeof(g_signatureList[0]); + ret = HitlsSetConfig(g_signatureList, configListSize, outCfg, inCtxCfg->signAlgorithms, SIGNATURE); + ASSERT_RETURN(ret == SUCCESS, "Hitls Set Signature ERROR"); + } + + // sni + if (strncmp("NULL", inCtxCfg->serverName, strlen(inCtxCfg->serverName)) != 0) { + LOG_DEBUG("HiTLS Set ServerName is %s", inCtxCfg->serverName); + ret = HITLS_CFG_SetServerName(outCfg, (uint8_t *)inCtxCfg->serverName, strlen(inCtxCfg->serverName)); + ASSERT_RETURN(ret == SUCCESS, "Hitls Set ServerName ERROR"); + } + + // Register the server_name function callback. + if (strncmp("NULL", inCtxCfg->sniDealCb, strlen(inCtxCfg->sniDealCb)) != 0) { + LOG_DEBUG("HiTLS Set server_name callback is %s", inCtxCfg->sniDealCb); + ret = HITLS_CFG_SetServerNameCb(outCfg, GetExtensionCb(inCtxCfg->sniDealCb)); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetServerNameCb Fail"); + } + + // Register values related to server_name. + if (strncmp("NULL", inCtxCfg->sniArg, strlen(inCtxCfg->sniArg)) != 0) { + LOG_DEBUG("HiTLS Set sniArg"); + ret = HITLS_CFG_SetServerNameArg(outCfg, GetExampleData(inCtxCfg->sniArg)); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetServerNameArg Fail"); + } + + // alpn + if (strncmp("NULL", inCtxCfg->alpnList, strlen(inCtxCfg->alpnList)) != 0) { + LOG_DEBUG("HiTLS Set alpnList is %s", inCtxCfg->alpnList); + ret = HITLS_CFG_SetAlpnProtos(outCfg, (const uint8_t *)inCtxCfg->alpnList, strlen(inCtxCfg->alpnList)); + ASSERT_RETURN(ret == SUCCESS, "Hitls Set alpnList ERROR"); + } + + // Sets the ALPN selection callback on the server. + if (strncmp("NULL", inCtxCfg->alpnSelectCb, strlen(inCtxCfg->alpnSelectCb)) != 0) { + LOG_DEBUG("HiTLS Set ALPN callback is %s", inCtxCfg->alpnSelectCb); + ret = HITLS_CFG_SetAlpnProtosSelectCb( + outCfg, GetExtensionCb(inCtxCfg->alpnSelectCb), GetExampleData(inCtxCfg->alpnUserData)); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetAlpnProtosSelectCb Fail"); + } + + // Loading Certificates + ret = HiTLS_X509_LoadCertAndKey(outCfg, inCtxCfg->caCert, inCtxCfg->chainCert, + inCtxCfg->eeCert, inCtxCfg->signCert, inCtxCfg->privKey, inCtxCfg->signPrivKey); + ASSERT_RETURN(ret == SUCCESS, "Load cert Fail"); + + if (strncmp("NULL", inCtxCfg->psk, strlen(inCtxCfg->psk)) != 0) { + ret = ExampleSetPsk(inCtxCfg->psk); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetPskClientCallback Fail"); + + ret = HITLS_CFG_SetPskClientCallback(outCfg, ExampleClientCb); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetPskClientCallback Fail"); + + ret = HITLS_CFG_SetPskServerCallback(outCfg, ExampleServerCb); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetPskServerCallback Fail"); + } + + if (strncmp("NULL", inCtxCfg->ticketKeyCb, strlen(inCtxCfg->ticketKeyCb)) != 0) { + LOG_DEBUG("HiTLS Set Ticker key callback is %s", inCtxCfg->ticketKeyCb); + ret = HITLS_CFG_SetTicketKeyCallback(outCfg, GetTicketKeyCb(inCtxCfg->ticketKeyCb)); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetTicketKeyCallback Fail"); + } + + // Load link setup callback + if (inCtxCfg->infoCb != NULL) { + LOG_DEBUG("HiTLS Set info callback"); + ret = HITLS_CFG_SetInfoCb(outCfg, inCtxCfg->infoCb); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetInfoCb Fail"); + } + + if (inCtxCfg->msgCb != NULL) { + LOG_DEBUG("HiTLS Set msg callback"); + ret = HITLS_CFG_SetMsgCb(outCfg, inCtxCfg->msgCb); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetMsgCb Fail"); + } + + if (inCtxCfg->msgArg != NULL) { + LOG_DEBUG("HiTLS Set msgArg"); + ret = HITLS_CFG_SetMsgCbArg(outCfg, inCtxCfg->msgArg); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetMsgCbArg Fail"); + } + + // Sets whether to enable the function of sending handshake messages by flight. + LOG_DEBUG("HiTLS Set Support isFlightTransmitEnable is %d", inCtxCfg->isFlightTransmitEnable); + ret = HITLS_CFG_SetFlightTransmitSwitch(outCfg, inCtxCfg->isFlightTransmitEnable); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetFlightTransmitSwitch ERROR"); + + // Setting the security level + LOG_DEBUG("HiTLS Set SecurityLevel is %d", inCtxCfg->securitylevel); + ret = HITLS_CFG_SetSecurityLevel(outCfg, inCtxCfg->securitylevel); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetSecurityLevel ERROR"); + + // Indicates whether the DH key length can be followed by the certificate. + LOG_DEBUG("HiTLS Set Support DHAuto is %d", inCtxCfg->isSupportDhAuto); + ret = HITLS_CFG_SetDhAutoSupport(outCfg, inCtxCfg->isSupportDhAuto); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetDhAutoSupport ERROR"); + + // Register insecure renegotiation callback + if (strncmp("NULL", inCtxCfg->noSecRenegotiationCb, strlen(inCtxCfg->noSecRenegotiationCb)) != 0) { + LOG_DEBUG("HiTLS Set noSecRenegotiationCb callback is %s", inCtxCfg->noSecRenegotiationCb); + ret = HITLS_CFG_SetNoSecRenegotiationCb(outCfg, GetNoSecRenegotiationCb(inCtxCfg->noSecRenegotiationCb)); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetNoSecRenegotiationCb Fail"); + } + + // TLS1.3 key exchange mode + if (outCfg->maxVersion == HITLS_VERSION_TLS13) { + LOG_DEBUG("HiTLS Set keyExchMode is %u", inCtxCfg->keyExchMode); + ret = HITLS_CFG_SetKeyExchMode(outCfg, inCtxCfg->keyExchMode); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetKeyExchMode ERROR"); + } + + // Set whether to enable isSupportVerifyNone; + LOG_DEBUG("HiTLS Set Support pha is %d", inCtxCfg->isSupportVerifyNone); + ret = HITLS_CFG_SetVerifyNoneSupport(outCfg, inCtxCfg->isSupportVerifyNone); + ASSERT_RETURN(ret == SUCCESS, "HITLS_CFG_SetVerifyNoneSupport ERROR"); + + return SUCCESS; +} + +void *HitlsNewSsl(void *ctx) +{ + return HITLS_New(ctx); +} + +void HitlsFreeSsl(void *ssl) +{ + HITLS_Free(ssl); +} + +const BSL_UIO_Method *GetDefaultMethod(HILT_TransportType type) +{ + switch (type) { + case SCTP: + return SctpGetDefaultMethod(); + case TCP: + return TcpGetDefaultMethod(); + default: + break; + } + return NULL; +} + +int HitlsSetSsl(void *ssl, HLT_Ssl_Config *sslConfig) +{ + int ret; + SetNeedCbSctpCtrlCmd(sslConfig->sctpCtrlCmd); + if (sslConfig->SupportType == SERVER_CTX_SET_TRUE) { + HITLS_SetCipherServerPreference((HITLS_Ctx *)ssl, true); + } + if (sslConfig->SupportType == SERVER_CTX_SET_FALSE) { + HITLS_SetCipherServerPreference((HITLS_Ctx *)ssl, false); + } + HILT_TransportType type = (sslConfig->connType == NONE_TYPE) ? SCTP : sslConfig->connType; + + BSL_UIO *uio = BSL_UIO_New(GetDefaultMethod(type)); + ASSERT_RETURN(uio != NULL, "HITLS_SetUio Fail"); + + ret = BSL_UIO_Ctrl(uio, BSL_UIO_SET_FD, (int32_t)sizeof(sslConfig->sockFd), &sslConfig->sockFd); + if (ret != SUCCESS) { + LOG_ERROR("BSL_UIO_SET_FD Fail"); + BSL_UIO_Free(uio); + return ERROR; + } + BSL_UIO_SetInit(uio, 1); + + ret = HITLS_SetUio(ssl, uio); + if (ret != SUCCESS) { + LOG_ERROR("HITLS_SetUio Fail"); + BSL_UIO_Free(uio); + return ERROR; + } + + // Release the UIO to prevent memory leakage. + BSL_UIO_Free(uio); + return SUCCESS; +} + +int HitlsAccept(void *ssl) +{ + int ret, tryNum; + tryNum = 0; + LOG_DEBUG("HiTLS Tls Accept Ing..."); + do { + ret = HITLS_Accept(ssl); + usleep(1000); // stay 1000us + tryNum++; + } while ((ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || + ret == HITLS_REC_NORMAL_IO_BUSY) && + (tryNum < FUNC_TIME_OUT_SEC * 1000)); // usleep(1000) after each attemp. + if (ret != SUCCESS) { + LOG_ERROR("HITLS_Accept Error is %d", ret); + } else { + LOG_DEBUG("HiTLS Tls Accept Success"); + } + return ret; +} + +int HitlsConnect(void *ssl) +{ + int ret, tryNum; + tryNum = 0; + LOG_DEBUG("HiTLS Tls Connect Ing..."); + do { + ret = HITLS_Connect(ssl); + usleep(1000); // stay 1000us + tryNum++; + } while ((ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || + ret == HITLS_REC_NORMAL_IO_BUSY) && + (tryNum < FUNC_TIME_OUT_SEC * 1000)); // usleep(1000) after each attemp. + if (ret != SUCCESS) { + LOG_ERROR("HITLS_Connect Error is %d", ret); + } else { + LOG_DEBUG("HiTLS Tls Connect Success"); + } + return ret; +} + +int HitlsWrite(void *ssl, uint8_t *data, uint32_t dataLen) +{ + int ret, tryNum; + LOG_DEBUG("HiTLS Write Ing..."); + tryNum = 0; + do { + ret = HITLS_Write(ssl, data, dataLen); + tryNum++; + usleep(1000); // stay 1000us + } while ((ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || + ret == HITLS_REC_NORMAL_IO_BUSY) && + (tryNum < 4000)); // A maximum of 4000 calls + LOG_DEBUG("HiTLS Write Result is %d", ret); + return ret; +} + +int HitlsRead(void *ssl, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int ret, tryNum; + LOG_DEBUG("HiTLS Read Ing..."); + tryNum = 0; + do { + ret = HITLS_Read(ssl, data, bufSize, readLen); + tryNum++; + usleep(1000); // stay 1000us + } while ((ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || + ret == HITLS_REC_NORMAL_IO_BUSY) && + (tryNum < 8000)); // A maximum of 4000 calls + LOG_DEBUG("HiTLS Read Result is %d", ret); + return ret; +} + +int HitlsClose(void *ctx) +{ + return HITLS_Close(ctx); +} + +int HitlsRenegotiate(void *ssl) +{ + return HITLS_Renegotiate(ssl); +} + +int HitlsSetMtu(void *ssl, uint16_t mtu) +{ + return HITLS_SetMtu(ssl, mtu); +} + +int HitlsSetSession(void *ssl, void *session) +{ + return HITLS_SetSession(ssl, session); +} + +int HitlsSessionReused(void *ssl) +{ + int32_t ret; + uint8_t isReused = 0; + + ret = HITLS_IsSessionReused(ssl, &isReused); + if (ret != HITLS_SUCCESS) { + return 0; + } + + return (int)isReused; +} + +void *HitlsGet1Session(void *ssl) +{ + return HITLS_GetDupSession(ssl); +} + +int HitlsSessionHasTicket(void *session) +{ + return (HITLS_SESS_HasTicket(session) ? 1 : 0); +} + +int HitlsSessionIsResumable(void *session) +{ + return (HITLS_SESS_IsResumable(session) ? 1 : 0); +} + +void HitlsFreeSession(void *session) +{ + HITLS_SESS_Free(session); +} + +int HitlsGetErrorCode(void *ssl) +{ + return HITLS_GetErrorCode(ssl); +} \ No newline at end of file diff --git a/testcode/framework/tls/rpc/src/hlt_func.c b/testcode/framework/tls/rpc/src/hlt_func.c new file mode 100644 index 00000000..8161fccd --- /dev/null +++ b/testcode/framework/tls/rpc/src/hlt_func.c @@ -0,0 +1,1301 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include "securec.h" + +#include "logger.h" +#include "process.h" +#include "handle_cmd.h" +#include "hlt.h" +#include "tls_res.h" +#include "common_func.h" +#include "hitls_func.h" +#include "sctp_channel.h" +#include "tcp_channel.h" +#include "socket_common.h" +#include "cert_callback.h" +#include "sctp_channel.h" +#include "frame_tls.h" + +#define DOMAIN_PATH_LEN (128) +#define CMD_MAX_LEN 1024 +#define SUCCESS 0 +#define ERROR (-1) + +int g_acceptFd; + +void* HLT_TlsNewCtx(TLS_VERSION tlsVersion) +{ + int ret; + void *ctx = NULL; + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + ctx = HitlsNewCtx(tlsVersion); + break; + default: + ctx = NULL; + } + if ((process->remoteFlag == 0) && (ctx != NULL)) { + // If the value is LocalProcess, insert it to the CTX linked list. + ret = InsertCtxToList(ctx); + if (ret == ERROR) { + LOG_ERROR("InsertCtxToList ERROR"); + return NULL; + } + } + return ctx; +} + +void* HLT_TlsNewSsl(void *ctx) +{ + int ret; + void *ssl = NULL; + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + LOG_DEBUG("Hitls New Ssl"); + ssl = HitlsNewSsl(ctx); + break; + default: + ssl = NULL; + } + if ((process->remoteFlag == 0) && (ssl != NULL)) { + // If the value is LocalProcess, insert it to the SSL linked list. + ret = InsertSslToList(ctx, ssl); + if (ret == ERROR) { + LOG_ERROR("InsertSslToList ERROR"); + return NULL; + } + } + return ssl; +} + +int HLT_TlsSetCtx(void *ctx, HLT_Ctx_Config *ctxConfig) +{ + int ret; + Process *process = GetProcess(); + switch (process->tlsType) { + case HITLS: + LOG_DEBUG("HiTLS Set Ctx's Config"); + ret = HitlsSetCtx(ctx, ctxConfig); + break; + default: + ret = ERROR; + } + return ret; +} + +int HLT_TlsSetSsl(void *ssl, HLT_Ssl_Config *sslConfig) +{ + int ret = ERROR; + Process *process = GetProcess(); + switch (process->tlsType) { + case HITLS: + LOG_DEBUG("HiTLS Set Ssl's Config"); + ret = HitlsSetSsl(ssl, sslConfig); + break; + default: + LOG_DEBUG("Unknown tls type"); + break; + } + return ret; +} + +// listen non-blocking interface +unsigned long int HLT_TlsListen(void *ssl) +{ + (void)ssl; + Process *process = GetProcess(); + switch (process->tlsType) { + case HITLS : { + return ERROR; // Hitls does not support the listen function. + } + default: + return ERROR; + } +} + +// listen blocking interface +int HLT_TlsListenBlock(void* ssl) +{ + (void)ssl; + Process *process = GetProcess(); + switch (process->tlsType) { + case HITLS : return ERROR; // Hitls does not support the listen function. + default: + return ERROR; + } +} + +// Non-blocking interface +unsigned long int HLT_TlsAccept(void *ssl) +{ + (void)ssl; + unsigned long int ret = ERROR; + Process *process = GetProcess(); + pthread_t t_id; + switch (process->tlsType) { + case HITLS : + ret = pthread_create(&t_id, NULL, (void*)HitlsAccept, (void*)ssl); + break; + default: + break; + } + + if (ret != 0) { + return ret; + } + return t_id; +} + +int HLT_TlsAcceptBlock(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsAccept(ssl); + default: + return ERROR; + } +} + +int HLT_GetTlsAcceptResultFromId(unsigned long int threadId) +{ + pthread_join(threadId, NULL); + return SUCCESS; +} + +int HLT_GetTlsAcceptResult(HLT_Tls_Res* tlsRes) +{ + int ret; + if (tlsRes->acceptId <= 0) { + LOG_ERROR("This Res Has Not acceptId"); + return ERROR; + } + if (tlsRes->ctx == NULL) { + // Indicates that the remote process accepts the request. + ret = HLT_RpcGetTlsAcceptResult(tlsRes->acceptId); + } else { + // Indicates that the local process accepts the request. + pthread_join(tlsRes->acceptId, NULL); + return SUCCESS; + } + tlsRes->acceptId = 0; + return ret; +} + +int HLT_TlsConnect(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsConnect(ssl); + default: + return ERROR; + } +} + +int HLT_TlsWrite(void *ssl, uint8_t *data, uint32_t dataLen) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS : { + LOG_DEBUG("Hitls Write Ing..."); + return HitlsWrite(ssl, data, dataLen); + } + default: + return ERROR; + } +} + +int HLT_TlsRead(void *ssl, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + Process *process; + process = GetProcess(); + + switch (process->tlsType) { + case HITLS: { + LOG_DEBUG("Hitls Read Ing..."); + return HitlsRead(ssl, data, bufSize, readLen); + } + default: + return ERROR; + } +} + +int HLT_TlsRenegotiate(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsRenegotiate(ssl); + default: + return ERROR; + } +} + +int HLT_TlsVerifyClientPostHandshake(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: return HITLS_VerifyClientPostHandshake(ssl); + default: + return ERROR; + } +} + +int HLT_TlsClose(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: return HitlsClose(ssl); + default: + return ERROR; + } +} + +int HLT_TlsSetSession(void *ssl, void *session) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: return (HitlsSetSession(ssl, session) == 0) ? 1 : 0; + default: + return ERROR; + } +} + +int HLT_TlsSessionReused(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsSessionReused(ssl); + default: + return ERROR; + } +} + +void *HLT_TlsGet1Session(void *ssl) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsGet1Session(ssl); + default: + return NULL; + } +} + +int32_t HLT_SetSessionCacheMode(HLT_Ctx_Config* config, HITLS_SESS_CACHE_MODE mode) +{ + config->setSessionCache = mode; + return SUCCESS; +} + +int32_t HLT_SetSessionTicketSupport(HLT_Ctx_Config* config, bool issupport) +{ + config->isSupportSessionTicket = issupport; + return SUCCESS; +} + +int HLT_TlsSessionHasTicket(void *session) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsSessionHasTicket(session); + default: + return ERROR; + } +} + +int HLT_TlsSessionIsResumable(void *session) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsSessionIsResumable(session); + default: + return ERROR; + } +} + +void HLT_TlsFreeSession(void *session) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + HitlsFreeSession(session); + break; + default: + break; + } +} + +int RunDataChannelBind(void *param) +{ + int sockFd = -1; + LOG_DEBUG("RunDataChannelBind Ing...\n"); + DataChannelParam *channelParam = (DataChannelParam*)param; + switch (channelParam->type) { + case SCTP: sockFd = SctpBind(channelParam->port); break; + case TCP: sockFd = TcpBind(channelParam->port); break; + default: + return ERROR; + } + struct sockaddr_in add; + socklen_t len = sizeof(add); + getsockname(sockFd, (struct sockaddr *)&add, &len); + channelParam->port = ntohs(add.sin_port); + channelParam->bindFd = sockFd; + g_acceptFd = sockFd; + return sockFd; +} + +int RunDataChannelAccept(void *param) +{ + int sockFd = -1; + LOG_DEBUG("RunDataChannelAccept Ing...\n"); + DataChannelParam *channelParam = (DataChannelParam *)param; + switch (channelParam->type) { + case SCTP: + sockFd = SctpAccept(channelParam->ip, channelParam->bindFd, channelParam->isBlock); + break; + case TCP: + sockFd = TcpAccept(channelParam->ip, channelParam->bindFd, channelParam->isBlock, true); + break; + default: + return ERROR; + } + g_acceptFd = sockFd; + return sockFd; +} + +pthread_t HLT_DataChannelAccept(DataChannelParam *channelParam) +{ + pthread_t t_id; + if (pthread_create(&t_id, NULL, (void*)RunDataChannelAccept, (void*)channelParam) != 0) { + LOG_ERROR("Create Thread HLT_RpcDataChannelAccept Error ..."); + return 0; + } + return t_id; +} + +int HLT_DataChannelBind(DataChannelParam *channelParam) +{ + return RunDataChannelBind(channelParam); +} + + +int HLT_DataChannelConnect(DataChannelParam *dstChannelParam) +{ + switch (dstChannelParam->type) { + case SCTP: return SctpConnect(dstChannelParam->ip, dstChannelParam->port, dstChannelParam->isBlock); + case TCP: return TcpConnect(dstChannelParam->ip, dstChannelParam->port); + default: + return ERROR; + } + return ERROR; +} + +int HLT_GetAcceptFd(pthread_t threadId) +{ + pthread_join(threadId, NULL); + return g_acceptFd; +} + +HLT_FD HLT_CreateDataChannel(HLT_Process *process1, HLT_Process *process2, DataChannelParam channelParam) +{ + int acceptId; + int bindFd; + unsigned long int pthreadId; + HLT_FD sockFd; + char *userPort = getenv("FIXED_PORT"); + if (userPort == NULL) { + channelParam.port = 0; // The system randomly allocates available ports. + } + + if (process2->remoteFlag == 1) { + bindFd = HLT_RpcDataChannelBind(process2, &channelParam); + } else { + bindFd = HLT_DataChannelBind(&channelParam); + } + channelParam.bindFd = bindFd; + // Start Accept again. + if (process2->remoteFlag == 1) { + acceptId = HLT_RpcDataChannelAccept(process2, &channelParam); + } else { + pthreadId = HLT_DataChannelAccept(&channelParam); + } + + // In Connect + if (process1->remoteFlag == 1) { + sockFd.srcFd = HLT_RpcDataChannelConnect(process1, &channelParam); + } else { + sockFd.srcFd = HLT_DataChannelConnect(&channelParam); + } + + if (process2->remoteFlag == 1) { + if (sockFd.srcFd > 0) { + // Indicates that the CONNECT is successful. + sockFd.peerFd = HLT_RpcGetAcceptFd(acceptId); + } else { + sockFd.peerFd = -1; + } + } else { + if (sockFd.srcFd > 0) { + // Indicates that the CONNECT is successful. + sockFd.peerFd = HLT_GetAcceptFd(pthreadId); + sockFd.sockAddr = channelParam.sockAddr; + sockFd.connPort = channelParam.port; + } else { + // If the SCTP link fails to be established, delete the thread to avoid congestion. + pthread_cancel(pthreadId); + pthread_join(pthreadId, NULL); + } + } + + return sockFd; +} + +void HLT_CloseFd(int fd, int linkType) +{ + switch (linkType) { + case TCP: TcpClose(fd); break; + case SCTP: SctpClose(fd); break; + default: + /* Unknown fd type */ + break; + } +} + +HLT_Ctx_Config* HLT_NewCtxConfigTLCP(char *setFile, const char *key, bool isClient) +{ + (void)setFile; + HLT_Ctx_Config *ctxConfig; + Process *localProcess; + + ctxConfig = (HLT_Ctx_Config*)malloc(sizeof(HLT_Ctx_Config)); + if (ctxConfig == NULL) { + return NULL; + } + + (void)memset_s(ctxConfig, sizeof(HLT_Ctx_Config), 0, sizeof(HLT_Ctx_Config)); + ctxConfig->isSupportRenegotiation = false; + ctxConfig->isSupportClientVerify = false; + ctxConfig->isSupportNoClientCert = false; + ctxConfig->isSupportExtendMasterSecret = false; + ctxConfig->minVersion = HITLS_VERSION_TLCP11; + ctxConfig->maxVersion = HITLS_VERSION_TLCP11; + ctxConfig->isClient = isClient; + ctxConfig->setSessionCache = 2; + HLT_SetGroups(ctxConfig, "NULL"); + HLT_SetCipherSuites(ctxConfig, "NULL"); + HLT_SetTls13CipherSuites(ctxConfig, "NULL"); + HLT_SetSignature(ctxConfig, "NULL"); + HLT_SetEcPointFormats(ctxConfig, "NULL"); + HLT_SetPassword(ctxConfig, "NULL"); + HLT_SetPsk(ctxConfig, "NULL"); + HLT_SetTicketKeyCb(ctxConfig, "NULL"); + + if (strncmp("SERVER", key, strlen(key)) == 0) { + HLT_SetCertPath(ctxConfig, SM2_VERIFY_PATH, SM2_CHAIN_PATH, SM2_SERVER_ENC_CERT_PATH, SM2_SERVER_ENC_KEY_PATH, + SM2_SERVER_SIGN_CERT_PATH, SM2_SERVER_SIGN_KEY_PATH); + } else if (strncmp("CLIENT", key, strlen(key)) == 0) { + HLT_SetCertPath(ctxConfig, SM2_VERIFY_PATH, SM2_CHAIN_PATH, SM2_CLIENT_ENC_CERT_PATH, SM2_CLIENT_ENC_KEY_PATH, + SM2_CLIENT_SIGN_CERT_PATH, SM2_CLIENT_SIGN_KEY_PATH); + } else { + free(ctxConfig); + ctxConfig = NULL; + return NULL; + } + + // Store CTX configuration resources and release them later. + localProcess = GetProcess(); + localProcess->tlsResArray[localProcess->tlsResNum] = ctxConfig; + localProcess->tlsResNum++; + return ctxConfig; +} + +HLT_Ctx_Config* HLT_NewCtxConfig(char *setFile, const char *key) +{ + (void)setFile; + HLT_Ctx_Config *ctxConfig; + Process *localProcess; + + ctxConfig = (HLT_Ctx_Config*)malloc(sizeof(HLT_Ctx_Config)); + if (ctxConfig == NULL) { + return NULL; + } + + (void)memset_s(ctxConfig, sizeof(HLT_Ctx_Config), 0, sizeof(HLT_Ctx_Config)); + ctxConfig->needCheckKeyUsage = false; + ctxConfig->isSupportRenegotiation = false; + ctxConfig->isSupportClientVerify = false; + ctxConfig->isSupportNoClientCert = false; + ctxConfig->isSupportVerifyNone = false; + ctxConfig->isSupportExtendMasterSecret = true; + ctxConfig->isSupportSessionTicket = false; + ctxConfig->isSupportDhAuto = true; + ctxConfig->isEncryptThenMac = false; + ctxConfig->keyExchMode = TLS13_KE_MODE_PSK_WITH_DHE; + ctxConfig->setSessionCache = HITLS_SESS_CACHE_SERVER; + ctxConfig->mtu = 0; + ctxConfig->infoCb = NULL; + ctxConfig->securitylevel = HITLS_DEFAULT_SECURITY_LEVEL; + ctxConfig->SupportType = 0; + + HLT_SetGroups(ctxConfig, "NULL"); + HLT_SetCipherSuites(ctxConfig, "NULL"); + HLT_SetTls13CipherSuites(ctxConfig, "NULL"); + HLT_SetSignature(ctxConfig, "NULL"); + HLT_SetEcPointFormats(ctxConfig, "HITLS_POINT_FORMAT_UNCOMPRESSED"); + HLT_SetPassword(ctxConfig, "NULL"); + HLT_SetPsk(ctxConfig, "NULL"); + HLT_SetTicketKeyCb(ctxConfig, "NULL"); + HLT_SetServerName(ctxConfig, "NULL"); + HLT_SetServerNameCb(ctxConfig, "NULL"); + HLT_SetServerNameArg(ctxConfig, "NULL"); + HLT_SetAlpnProtos(ctxConfig, "NULL"); + HLT_SetAlpnProtosSelectCb(ctxConfig, "NULL", "NULL"); + + if (strncmp("SERVER", key, strlen(key)) == 0) { + HLT_SetCertPath(ctxConfig, ECDSA_SHA256_CA_PATH, + ECDSA_SHA256_CHAIN_PATH, ECDSA_SHA256_EE_PATH1, ECDSA_SHA256_PRIV_PATH1, "NULL", "NULL"); + } else if (strncmp("CLIENT", key, strlen(key)) == 0) { + HLT_SetCertPath(ctxConfig, ECDSA_SHA256_CA_PATH, + ECDSA_SHA256_CHAIN_PATH, ECDSA_SHA256_EE_PATH2, ECDSA_SHA256_PRIV_PATH2, "NULL", "NULL"); + } else { + free(ctxConfig); + ctxConfig = NULL; + return NULL; + } + + // Store CTX configuration resources and release them later. + localProcess = GetProcess(); + localProcess->tlsResArray[localProcess->tlsResNum] = ctxConfig; + localProcess->tlsResNum++; + return ctxConfig; +} + +HLT_Ssl_Config *HLT_NewSslConfig(char *setFile) +{ + (void)setFile; + HLT_Ssl_Config *sslConfig; + Process *localProcess; + + sslConfig = (HLT_Ssl_Config*)malloc(sizeof(HLT_Ssl_Config)); + if (sslConfig == NULL) { + return NULL; + } + + (void)memset_s(sslConfig, sizeof(HLT_Ssl_Config), 0, sizeof(HLT_Ssl_Config)); + + // Store SSL configuration resources and release them later. + localProcess = GetProcess(); + localProcess->tlsResArray[localProcess->tlsResNum] = sslConfig; + localProcess->tlsResNum++; + return sslConfig; +} + +int HLT_LibraryInit(TLS_TYPE tlsType) +{ + switch (tlsType) { + case HITLS: return HitlsInit(); break; + default: + /* Unknown type */ + break; + } + return ERROR; +} + +int HLT_TlsRegCallback(TlsCallbackType type) +{ + switch (type) { + case HITLS_CALLBACK_DEFAULT: + FRAME_Init(); + break; + default: + return SUCCESS; + } + return SUCCESS; +} + +void HLT_FreeAllProcess(void) +{ + int ret; + HLT_Tls_Res* tlsRes; + Process *remoteProcess; + Process *localProcess = GetProcess(); + + if (localProcess == NULL) { + return; + } + + if (localProcess->remoteFlag != 0) { + LOG_ERROR("Only Local Process Can Call HLT_FreeAllProcess"); + return; + } + + // Clearing HLT_Tls_Res and Threads + for (int i = 0; i < localProcess->hltTlsResNum; i++) { + tlsRes = localProcess->hltTlsResArray[i]; + if ((tlsRes->acceptId > 0) && (tlsRes->ctx != NULL)) { + pthread_join(tlsRes->acceptId, NULL); + } + free(tlsRes); + } + + // Sends a signal for the peer process to exit. + remoteProcess = GetProcessFromList(); + while (remoteProcess != NULL) { + ret = HLT_RpcProcessExit(remoteProcess); + if (ret != SUCCESS) { + LOG_ERROR("HLT_RpcProcessExit Error"); + } + free(remoteProcess); + remoteProcess = GetProcessFromList(); + } + + // Clearing Local Resources + // Clearing Ports + if (localProcess->connFd > 0) { + close(localProcess->connFd); + } + // Clear the TlsRes linked list. + FreeTlsResList(); + // Clear CTX SSL configuration resources. + for (int i = 0; i < localProcess->tlsResNum; i++) { + free(localProcess->tlsResArray[i]); + } + // Clear the linked list of the remote process. + FreeProcessResList(); + // Clear local control connection resources + FreeControlChannelRes(); + // Clear local processes. + FreeProcess(); + return; +} + +int HLT_FreeResFromSsl(const void *ssl) +{ + return FreeResFromSsl(ssl); +} + +static int LocalProcessTlsInit(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig, HLT_Tls_Res *tlsRes) +{ + void *ctx, *ssl; + + ctx = HLT_TlsNewCtx(tlsVersion); + if (ctx == NULL) { + LOG_ERROR("HLT_TlsNewCtx ERROR"); + goto ERR; + } + if (HLT_TlsSetCtx(ctx, ctxConfig) != SUCCESS) { + LOG_ERROR("HLT_TlsSetCtx ERROR"); + goto ERR; + } + ssl = HLT_TlsNewSsl(ctx); + if (ssl == NULL) { + LOG_ERROR("HLT_TlsNewSsl ERROR"); + goto ERR; + } + // When FD is 0, the default configuration is used. + if (sslConfig->sockFd == 0) { + sslConfig->sockAddr = process->sockAddr; + sslConfig->sockFd = process->connFd; + sslConfig->connType = process->connType; + } + if (HLT_TlsSetSsl(ssl, sslConfig) != SUCCESS) { + LOG_ERROR("HLT_TlsSetSsl ERROR"); + goto ERR; + } + if (ctxConfig->mtu > 0) { + if (HLT_TlsSetMtu(ssl, ctxConfig->mtu) != SUCCESS) { + LOG_ERROR("HLT_TlsSetMtu ERROR"); + goto ERR; + } + } + tlsRes->ctx = ctx; + tlsRes->ssl = ssl; + tlsRes->ctxId = -1; // -1 indicates that the field is discarded. + tlsRes->sslId = -1; // -1 indicates that the field is discarded. + return SUCCESS; +ERR: + return ERROR; +} + +static int RemoteProcessTlsInit(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig, HLT_Tls_Res *tlsRes) +{ + int ctxId; + int sslId; + + ctxId = HLT_RpcTlsNewCtx(process, tlsVersion, ctxConfig->isClient); + if (ctxId < 0) { + LOG_ERROR("HLT_RpcTlsNewCtx ERROR"); + goto ERR; + } + if (HLT_RpcTlsSetCtx(process, ctxId, ctxConfig) != SUCCESS) { + LOG_ERROR("HLT_RpcTlsSetCtx ERROR"); + goto ERR; + } + sslId = HLT_RpcTlsNewSsl(process, ctxId); + if (sslId < 0) { + LOG_ERROR("HLT_RpcTlsNewSsl ERROR"); + goto ERR; + } + // When FD is 0, the default configuration is used. + if (sslConfig->sockFd == 0) { + sslConfig->connPort = process->connPort; + sslConfig->sockFd = process->connFd; + sslConfig->connType = process->connType; + } + if (HLT_RpcTlsSetSsl(process, sslId, sslConfig) != SUCCESS) { + LOG_ERROR("HLT_RpcTlsSetSsl ERROR"); + goto ERR; + } + if (ctxConfig->mtu > 0) { + if (HLT_RpcTlsSetMtu(process, sslId, ctxConfig->mtu) != SUCCESS) { + LOG_ERROR("HLT_RpcTlsSetMtu ERROR"); + goto ERR; + } + } + + tlsRes->ctx = NULL; + tlsRes->ssl = NULL; + tlsRes->ctxId = ctxId; + tlsRes->sslId = sslId; + return SUCCESS; +ERR: + return ERROR; +} + +HLT_Tls_Res *HLT_ProcessTlsInit(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig) +{ + int ret; + HLT_Tls_Res *tlsRes = (HLT_Tls_Res*)malloc(sizeof(HLT_Tls_Res)); + if (tlsRes == NULL) { + LOG_ERROR("Malloc TlsRes ERROR"); + goto ERR; + } + + // Checking Configuration Parameters + if (ctxConfig == NULL) { + ctxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + } + if (sslConfig == NULL) { + sslConfig = HLT_NewSslConfig(NULL); + } + if ((ctxConfig == NULL) || (sslConfig == NULL)) { + LOG_ERROR("ctxConfig or sslConfig is NULL"); + goto ERR; + } + sslConfig->SupportType = ctxConfig->SupportType; + // Check whether the call is invoked by the local process or by the RPC. + if (process->remoteFlag == 0) { + ret = LocalProcessTlsInit(process, tlsVersion, ctxConfig, sslConfig, tlsRes); + if (ret == ERROR) { + LOG_ERROR("LocalProcessTlsInit ERROR"); + goto ERR; + } + } else { + ret = RemoteProcessTlsInit(process, tlsVersion, ctxConfig, sslConfig, tlsRes); + if (ret == ERROR) { + LOG_ERROR("RemoteProcessTlsInit ERROR"); + goto ERR; + } + } + // The configuration resources of the HLT_Tls_Res table are stored and will be released later. + Process *localProcess = GetProcess(); + tlsRes->acceptId = 0; + localProcess->hltTlsResArray[localProcess->hltTlsResNum] = tlsRes; + localProcess->hltTlsResNum++; + return tlsRes; +ERR: + free(tlsRes); + return NULL; +} + +int HLT_TlsSetMtu(void *ssl, uint16_t mtu) +{ + Process *process; + process = GetProcess(); + switch (process->tlsType) { + case HITLS: + return HitlsSetMtu(ssl, mtu); + default: + break; + } + return ERROR; +} + +int HLT_TlsGetErrorCode(void *ssl) +{ + return HitlsGetErrorCode(ssl); +} + +HLT_Tls_Res* HLT_ProcessTlsAccept(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig) +{ + unsigned long int acceptId; + + HLT_Tls_Res *tlsRes = NULL; + + tlsRes = HLT_ProcessTlsInit(process, tlsVersion, ctxConfig, sslConfig); + if (tlsRes == NULL) { + LOG_ERROR("HLT_ProcessTlsInit ERROR"); + return NULL; + } + // Check whether the call is invoked by the local process or by the RPC. + if (process->remoteFlag == 0) { + acceptId = HLT_TlsAccept(tlsRes->ssl); + if (acceptId == (unsigned long int)ERROR) { + LOG_ERROR("HLT_TlsAccept ERROR"); + return NULL; + } + } else { + acceptId = HLT_RpcTlsAccept(process, tlsRes->sslId); + if (acceptId == (unsigned long int)ERROR) { + LOG_ERROR("HLT_TlsAccept ERROR"); + return NULL; + } + } + tlsRes->acceptId = acceptId; + return tlsRes; +} + +HLT_Tls_Res* HLT_ProcessTlsConnect(HLT_Process *process, TLS_VERSION tlsVersion, + HLT_Ctx_Config *ctxConfig, HLT_Ssl_Config *sslConfig) +{ + int ret; + + HLT_Tls_Res *tlsRes = (HLT_Tls_Res*)malloc(sizeof(HLT_Tls_Res)); + if (tlsRes == NULL) { + LOG_ERROR("Malloc TlsRes ERROR"); + goto ERR; + } + (void)memset_s(tlsRes, sizeof(HLT_Tls_Res), 0, sizeof(HLT_Tls_Res)); + // Checking Configuration Parameters + if (ctxConfig == NULL) { + ctxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + } + if (sslConfig == NULL) { + sslConfig = HLT_NewSslConfig(NULL); + } + if ((ctxConfig == NULL) || (sslConfig == NULL)) { + LOG_ERROR("ctxConfig or sslConfig is NULL"); + goto ERR; + } + // Check whether the call is invoked by the local process or by the RPC. + if (process->remoteFlag == 0) { + ret = LocalProcessTlsInit(process, tlsVersion, ctxConfig, sslConfig, tlsRes); + if (ret == ERROR) { + LOG_ERROR("LocalProcessTlsInit ERROR"); + goto ERR; + } + ret = HLT_TlsConnect(tlsRes->ssl); + if (ret != SUCCESS) { + LOG_ERROR("HLT_TlsConnect ERROR is %d", ret); + goto ERR; + } + } else { + ret = RemoteProcessTlsInit(process, tlsVersion, ctxConfig, sslConfig, tlsRes); + if (ret == ERROR) { + LOG_ERROR("Retmote Process Init Tls ERROR"); + goto ERR; + } + ret = HLT_RpcTlsConnect(process, tlsRes->sslId); + if (ret != SUCCESS) { + LOG_ERROR("HLT_RpcTlsConnect ERROR is %d", ret); + goto ERR; + } + } + + // The configuration resources of the HLT_Tls_Res table are stored and will be released later. + Process *localProcess = GetProcess(); + localProcess->hltTlsResArray[localProcess->hltTlsResNum] = tlsRes; + localProcess->hltTlsResNum++; + return tlsRes; +ERR: + free(tlsRes); + return NULL; +} + +int HLT_ProcessTlsWrite(HLT_Process *process, HLT_Tls_Res *tlsRes, uint8_t *data, uint32_t dataLen) +{ + if (process == NULL) { + LOG_ERROR("Process is NULL"); + return ERROR; + } + if (process->remoteFlag == 0) { + return HLT_TlsWrite(tlsRes->ssl, data, dataLen); + } else { + return HLT_RpcTlsWrite(process, tlsRes->sslId, data, dataLen); + } +} + +int HLT_ProcessTlsRead(HLT_Process *process, HLT_Tls_Res *tlsRes, uint8_t *data, uint32_t bufSize, uint32_t *dataLen) +{ + if (process == NULL) { + LOG_ERROR("Process is NULL"); + return ERROR; + } + if (process->remoteFlag == 0) { + return HLT_TlsRead(tlsRes->ssl, data, bufSize, dataLen); + } else { + return HLT_RpcTlsRead(process, tlsRes->sslId, data, bufSize, dataLen); + } +} + +int HLT_SetVersion(HLT_Ctx_Config *ctxConfig, uint16_t minVersion, uint16_t maxVersion) +{ + ctxConfig->minVersion = minVersion; + ctxConfig->maxVersion = maxVersion; + return SUCCESS; +} + +int HLT_SetSecurityLevel(HLT_Ctx_Config *ctxConfig, int32_t level) +{ + ctxConfig->securitylevel = level; + return SUCCESS; +} + +int HLT_SetRenegotiationSupport(HLT_Ctx_Config *ctxConfig, bool support) +{ + ctxConfig->isSupportRenegotiation = support; + return SUCCESS; +} + +int32_t HLT_SetNoSecRenegotiationCb(HLT_Ctx_Config *ctxConfig, char* NoSecRenegotiationCb) +{ + (void)memset_s(ctxConfig->noSecRenegotiationCb, MAX_NO_RENEGOTIATIONCB_LEN, 0, MAX_NO_RENEGOTIATIONCB_LEN); + if (strcpy_s(ctxConfig->noSecRenegotiationCb, MAX_NO_RENEGOTIATIONCB_LEN, NoSecRenegotiationCb) != EOK) { + LOG_ERROR("HLT_SetNoSecRenegotiationCb failed."); + return -1; + } + return SUCCESS; +} + +int HLT_SetFlightTransmitSwitch(HLT_Ctx_Config *ctxConfig, bool support) +{ + ctxConfig->isFlightTransmitEnable = support; + return SUCCESS; +} + +int HLT_SetClientVerifySupport(HLT_Ctx_Config *ctxConfig, bool support) +{ + ctxConfig->isSupportClientVerify = support; + return SUCCESS; +} + +int HLT_SetPostHandshakeAuth(HLT_Ctx_Config *ctxConfig, bool support) +{ + ctxConfig->isSupportPostHandshakeAuth = support; + return SUCCESS; +} + +int HLT_SetNoClientCertSupport(HLT_Ctx_Config *ctxConfig, bool support) +{ + ctxConfig->isSupportNoClientCert = support; + return SUCCESS; +} + +int HLT_SetExtenedMasterSecretSupport(HLT_Ctx_Config *ctxConfig, bool support) +{ + ctxConfig->isSupportExtendMasterSecret = support; + return SUCCESS; +} + +int HLT_SetCipherSuites(HLT_Ctx_Config *ctxConfig, const char *cipherSuites) +{ + int ret; + (void)memset_s(ctxConfig->cipherSuites, sizeof(ctxConfig->cipherSuites), 0, sizeof(ctxConfig->cipherSuites)); + ret = sprintf_s(ctxConfig->cipherSuites, sizeof(ctxConfig->cipherSuites), cipherSuites); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetTls13CipherSuites(HLT_Ctx_Config *ctxConfig, const char *cipherSuites) +{ + int ret; + (void)memset_s(ctxConfig->tls13CipherSuites, sizeof(ctxConfig->tls13CipherSuites), 0, + sizeof(ctxConfig->tls13CipherSuites)); + ret = sprintf_s(ctxConfig->tls13CipherSuites, sizeof(ctxConfig->tls13CipherSuites), cipherSuites); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetEcPointFormats(HLT_Ctx_Config *ctxConfig, const char *pointFormat) +{ + int ret; + (void)memset_s(ctxConfig->pointFormats, sizeof(ctxConfig->pointFormats), 0, sizeof(ctxConfig->pointFormats)); + ret = sprintf_s(ctxConfig->pointFormats, sizeof(ctxConfig->pointFormats), pointFormat); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetGroups(HLT_Ctx_Config *ctxConfig, const char *groups) +{ + int ret; + (void)memset_s(ctxConfig->groups, sizeof(ctxConfig->groups), 0, sizeof(ctxConfig->groups)); + ret = sprintf_s(ctxConfig->groups, sizeof(ctxConfig->groups), groups); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetSignature(HLT_Ctx_Config *ctxConfig, const char *signature) +{ + int ret; + (void)memset_s(ctxConfig->signAlgorithms, sizeof(ctxConfig->signAlgorithms), 0, sizeof(ctxConfig->signAlgorithms)); + ret = sprintf_s(ctxConfig->signAlgorithms, sizeof(ctxConfig->signAlgorithms), signature); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetPsk(HLT_Ctx_Config *ctxConfig, char *psk) +{ + (void)memset_s(ctxConfig->psk, PSK_MAX_LEN, 0, PSK_MAX_LEN); + if (strcpy_s(ctxConfig->psk, PSK_MAX_LEN, psk) != EOK) { + LOG_ERROR("HLT_SetPsk failed."); + return -1; + } + return SUCCESS; +} + +int HLT_SetKeyExchMode(HLT_Ctx_Config *config, uint32_t mode) +{ + config->keyExchMode = mode; + return SUCCESS; +} + +int HLT_SetTicketKeyCb(HLT_Ctx_Config *ctxConfig, char *ticketKeyCbName) +{ + (void)memset_s(ctxConfig->ticketKeyCb, TICKET_KEY_CB_NAME_LEN, 0, TICKET_KEY_CB_NAME_LEN); + if (strcpy_s(ctxConfig->ticketKeyCb, TICKET_KEY_CB_NAME_LEN, ticketKeyCbName) != EOK) { + LOG_ERROR("HLT_SetTicketKeyCb failed."); + return -1; + } + return SUCCESS; +} + +int HLT_SetCaCertPath(HLT_Ctx_Config *ctxConfig, const char *caCertPath) +{ + int ret; + (void)memset_s(ctxConfig->caCert, sizeof(ctxConfig->caCert), 0, sizeof(ctxConfig->caCert)); + ret = sprintf_s(ctxConfig->caCert, sizeof(ctxConfig->caCert), caCertPath); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetChainCertPath(HLT_Ctx_Config *ctxConfig, const char *chainCertPath) +{ + int ret; + (void)memset_s(ctxConfig->chainCert, sizeof(ctxConfig->chainCert), 0, sizeof(ctxConfig->chainCert)); + ret = sprintf_s(ctxConfig->chainCert, sizeof(ctxConfig->chainCert), chainCertPath); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetEeCertPath(HLT_Ctx_Config *ctxConfig, const char *eeCertPath) +{ + int ret; + (void)memset_s(ctxConfig->eeCert, sizeof(ctxConfig->eeCert), 0, sizeof(ctxConfig->eeCert)); + ret = sprintf_s(ctxConfig->eeCert, sizeof(ctxConfig->eeCert), eeCertPath); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetPrivKeyPath(HLT_Ctx_Config *ctxConfig, const char *privKeyPath) +{ + int ret; + (void)memset_s(ctxConfig->privKey, sizeof(ctxConfig->privKey), 0, sizeof(ctxConfig->privKey)); + ret = sprintf_s(ctxConfig->privKey, sizeof(ctxConfig->privKey), privKeyPath); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetSignCertPath(HLT_Ctx_Config *ctxConfig, const char *signCertPath) +{ + int ret; + (void)memset_s(ctxConfig->signCert, sizeof(ctxConfig->signCert), 0, sizeof(ctxConfig->signCert)); + ret = sprintf_s(ctxConfig->signCert, sizeof(ctxConfig->signCert), signCertPath); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetSignPrivKeyPath(HLT_Ctx_Config *ctxConfig, const char *signPrivKeyPath) +{ + int ret; + (void)memset_s(ctxConfig->signPrivKey, sizeof(ctxConfig->signPrivKey), 0, sizeof(ctxConfig->signPrivKey)); + ret = sprintf_s(ctxConfig->signPrivKey, sizeof(ctxConfig->signPrivKey), signPrivKeyPath); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetPassword(HLT_Ctx_Config* ctxConfig, const char* password) +{ + int ret; + (void)memset_s(ctxConfig->password, sizeof(ctxConfig->password), 0, sizeof(ctxConfig->password)); + ret = sprintf_s(ctxConfig->password, sizeof(ctxConfig->password), password); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +void HLT_SetCertPath(HLT_Ctx_Config *ctxConfig, const char *caPath, const char *chainPath, const char *EePath, + const char *PrivPath, const char *signCert, const char *signPrivKey) +{ + HLT_SetCaCertPath(ctxConfig, caPath); + if (ctxConfig->isNoSetCert) { + return; + } + HLT_SetChainCertPath(ctxConfig, chainPath); + HLT_SetEeCertPath(ctxConfig, EePath); + HLT_SetPrivKeyPath(ctxConfig, PrivPath); + HLT_SetSignCertPath(ctxConfig, signCert); + HLT_SetSignPrivKeyPath(ctxConfig, signPrivKey); +} + +int HLT_SetServerName(HLT_Ctx_Config *ctxConfig, const char *serverName) +{ + (void)memset_s(ctxConfig->serverName, sizeof(ctxConfig->serverName), 0, sizeof(ctxConfig->serverName)); + int ret = sprintf_s(ctxConfig->serverName, sizeof(ctxConfig->serverName), serverName); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetServerNameArg(HLT_Ctx_Config *ctxConfig, char *arg) +{ + (void)memset_s(ctxConfig->sniArg, SERVER_NAME_ARG_NAME_LEN, 0, SERVER_NAME_ARG_NAME_LEN); + if (strcpy_s(ctxConfig->sniArg, SERVER_NAME_ARG_NAME_LEN, arg) != EOK) { + LOG_ERROR("HLT_SetServerNameArg failed."); + return ERROR; + } + return SUCCESS; +} + +int HLT_SetServerNameCb(HLT_Ctx_Config *ctxConfig, char *sniCbName) +{ + (void)memset_s(ctxConfig->sniDealCb, SERVER_NAME_CB_NAME_LEN, 0, SERVER_NAME_CB_NAME_LEN); + if (strcpy_s(ctxConfig->sniDealCb, SERVER_NAME_CB_NAME_LEN, sniCbName) != EOK) { + LOG_ERROR("HLT_SetServerNameCb failed."); + return ERROR; + } + return SUCCESS; +} + +int HLT_SetAlpnProtos(HLT_Ctx_Config *ctxConfig, const char *alpnProtos) +{ + (void)memset_s(ctxConfig->alpnList, sizeof(ctxConfig->alpnList), 0, sizeof(ctxConfig->alpnList)); + int ret = sprintf_s(ctxConfig->alpnList, sizeof(ctxConfig->alpnList), alpnProtos); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int HLT_SetAlpnProtosSelectCb(HLT_Ctx_Config *ctxConfig, char *callback, char *userData) +{ + (void)memset_s(ctxConfig->alpnSelectCb, ALPN_CB_NAME_LEN, 0, ALPN_CB_NAME_LEN); + if (strcpy_s(ctxConfig->alpnSelectCb, ALPN_CB_NAME_LEN, callback) != EOK) { + LOG_ERROR("HLT_SetAlpnCb failed."); + return ERROR; + } + (void)memset_s(ctxConfig->alpnUserData, ALPN_DATA_NAME_LEN, 0, ALPN_DATA_NAME_LEN); + if (strcpy_s(ctxConfig->alpnUserData, ALPN_DATA_NAME_LEN, userData) != EOK) { + LOG_ERROR("HLT_SetAlpnDataCb failed."); + return ERROR; + } + return SUCCESS; +} + +int HLT_SetFrameHandle(HLT_FrameHandle *frameHandle) +{ + return SetFrameHandle(frameHandle); +} + +void HLT_CleanFrameHandle(void) +{ + CleanFrameHandle(); +} + +#define SCTP_AUTH_FILE_PATH "/proc/sys/net/sctp/auth_enable" +#define SCTP_AUTH_ENABLE "echo 1 > /proc/sys/net/sctp/auth_enable" +#define SCTP_FLAG_BUFF 10 + +bool IsEnableSctpAuth(void) +{ + system(SCTP_AUTH_ENABLE); + char buf[SCTP_FLAG_BUFF] = { 0 }; + FILE* file = fopen(SCTP_AUTH_FILE_PATH, "r+"); + if (file == NULL) { + return false; + } + (void)fgets(buf, SCTP_FLAG_BUFF, file); + fclose(file); + if (strcmp(buf, "1") == 0) { + return true; + } + return false; +} diff --git a/testcode/framework/tls/rpc/src/hlt_rpc_func.c b/testcode/framework/tls/rpc/src/hlt_rpc_func.c new file mode 100644 index 00000000..fe1b6c5c --- /dev/null +++ b/testcode/framework/tls/rpc/src/hlt_rpc_func.c @@ -0,0 +1,987 @@ +/* + * 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 +#include +#include +#include "logger.h" +#include "process.h" +#include "hlt_type.h" +#include "control_channel.h" +#include "channel_res.h" +#include "handle_cmd.h" +#include "securec.h" + +#define SUCCESS 0 +#define ERROR (-1) + +uint64_t g_cmdIndex = 0; +pthread_mutex_t g_cmdMutex = PTHREAD_MUTEX_INITIALIZER; + +#define ASSERT_RETURN(condition, log) \ + do { \ + if (!(condition)) { \ + LOG_ERROR(log); \ + return ERROR; \ + } \ + } while (0) + +void InitCmdIndex(void) +{ + g_cmdIndex = 0; +} + +static int WaitResult(CmdData *expectCmdData, int cmdIndex, const char *funcName) +{ + int ret; + ret = sprintf_s(expectCmdData->id, sizeof(expectCmdData->id), "%d", cmdIndex); + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + ret = sprintf_s(expectCmdData->funcId, sizeof(expectCmdData->funcId), "%s", funcName); + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + // Receive the result. + ret = WaitResultFromPeer(expectCmdData); + ASSERT_RETURN(ret == SUCCESS, "WaitResultFromPeer Error"); + return SUCCESS; +} + +int HLT_RpcTlsNewCtx(HLT_Process *peerProcess, TLS_VERSION tlsVersion, bool isClient) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsNewCtx"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d", g_cmdIndex, __FUNCTION__, tlsVersion, isClient); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsSetCtx(HLT_Process *peerProcess, int ctxId, HLT_Ctx_Config *config) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsSetCtx"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), + "%llu|%s|%d|" + "%u|%u|%s|%s|" + "%s|%s|%s|%d|" + "%d|%d|%d|%s|" + "%s|%s|%s|%s|" + "%s|%s|%s|%d|" + "%d|%s|%d|%s|" + "%s|%s|%s|%s|" + "%s|%d|%d|%s|" + "%u|%d|%d|" + "%d|%d|", + g_cmdIndex, __FUNCTION__, ctxId, + config->minVersion, config->maxVersion, config->cipherSuites, config->tls13CipherSuites, + config->pointFormats, config->groups, config->signAlgorithms, config->isSupportRenegotiation, + config->isSupportClientVerify, config->isSupportNoClientCert, config->isSupportExtendMasterSecret, config->eeCert, + config->privKey, config->password, config->caCert, config->chainCert, + config->signCert, config->signPrivKey, config->psk, config->isSupportSessionTicket, + config->setSessionCache, config->ticketKeyCb, config->isFlightTransmitEnable, config->serverName, + config->sniDealCb, config->sniArg, config->alpnList, config->alpnSelectCb, + config->alpnUserData, config->securitylevel, config->isSupportDhAuto, config->noSecRenegotiationCb, + config->keyExchMode, config->SupportType, config->isSupportPostHandshakeAuth, + config->needCheckKeyUsage, config->isSupportVerifyNone); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Wait to receive the result. + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsNewSsl(HLT_Process *peerProcess, int ctxId) +{ + int ret; + uint64_t cmdIndex; + CmdData expectCmdData = {0}; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsNewSsl"); + + // Constructing Commands + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, ctxId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Wait to receive the result. + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsSetSsl(HLT_Process *peerProcess, int sslId, HLT_Ssl_Config *config) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsSetSsl"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d|%d|%d", + g_cmdIndex, __FUNCTION__, sslId, config->sockFd, config->connType, config->connPort); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Wait to receive the result. + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsListen(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t acceptId; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsListen"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + acceptId = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + return acceptId; +} + +int HLT_RpcTlsAccept(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t acceptId; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsAccept"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + acceptId = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + return acceptId; +} + +int HLT_RpcGetTlsListenResult(int acceptId) +{ + int ret; + CmdData expectCmdData = {0}; + ret = WaitResult(&expectCmdData, acceptId, "HLT_RpcTlsListen"); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], NULL, 10); // Convert to a decimal number +} + +int HLT_RpcGetTlsAcceptResult(int acceptId) +{ + int ret; + char *endPtr = NULL; + CmdData expectCmdData = {0}; + ret = WaitResult(&expectCmdData, acceptId, "HLT_RpcTlsAccept"); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcTlsConnect(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsConnect"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result returned by the peer + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsConnectUnBlock(HLT_Process *peerProcess, int sslId) +{ + uint64_t cmdIndex; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsConnect"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + int ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, "HLT_RpcTlsConnect", sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + return cmdIndex; +} + +int HLT_RpcGetTlsConnectResult(int cmdIndex) +{ + int ret; + CmdData expectCmdData = {0}; + // Waiting for the result returned by the peer + ret = WaitResult(&expectCmdData, cmdIndex, "HLT_RpcTlsConnect"); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsRead(HLT_Process *peerProcess, int sslId, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsRead"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%u", g_cmdIndex, __FUNCTION__, sslId, bufSize); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result returned by the peer + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + // Parsing result + ret = atoi(expectCmdData.paras[0]); + if (ret == SUCCESS) { + *readLen = atoi(expectCmdData.paras[1]); // The first parameter indicates the read length. + memcpy_s( + data, bufSize, expectCmdData.paras[2], *readLen); // The second parameter indicates the content to be read. + } + + return ret; +} + +int HLT_RpcTlsReadUnBlock(HLT_Process *peerProcess, int sslId, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + (void)data; + (void)readLen; + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsRead"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%u", g_cmdIndex, "HLT_RpcTlsRead", sslId, bufSize); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + return cmdIndex; +} + +int HLT_RpcGetTlsReadResult(int cmdIndex, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int ret; + char *endPtr = NULL; + CmdData expectCmdData = {0}; + ret = WaitResult(&expectCmdData, cmdIndex, "HLT_RpcTlsRead"); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + // Parsing result + ret = (int)strtol(expectCmdData.paras[0], &endPtr, 0); + if (ret == SUCCESS) { + *readLen = (int)strtol(expectCmdData.paras[1], &endPtr, 0); // The first parameter indicates the read length. + // The second parameter indicates the content to be read. + memcpy_s(data, bufSize, expectCmdData.paras[2], *readLen); + } + return ret; +} + +int HLT_RpcTlsWrite(HLT_Process *peerProcess, int sslId, uint8_t *data, uint32_t bufSize) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsWrite"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%u|%s", + g_cmdIndex, __FUNCTION__, sslId, bufSize, data); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result returned by the peer + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsWriteUnBlock(HLT_Process *peerProcess, int sslId, uint8_t *data, uint32_t bufSize) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsWrite"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%u|%s", + g_cmdIndex, "HLT_RpcTlsWrite", sslId, bufSize, data); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Do not wait for the result returned by the peer. + return cmdIndex; +} + +int HLT_RpcGetTlsWriteResult(int cmdIndex) +{ + int ret; + CmdData expectCmdData = {0}; + + ret = WaitResult(&expectCmdData, cmdIndex, "HLT_RpcTlsWrite"); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], NULL, 10); // Convert to a decimal number +} + +int HLT_RpcTlsRenegotiate(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + CmdData expectCmdData = {0}; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsRenegotiate"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + + +int HLT_RpcTlsVerifyClientPostHandshake(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + CmdData expectCmdData = {0}; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call RpcTlsVerifyClientPostHandshake"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcDataChannelConnect(HLT_Process *peerProcess, DataChannelParam *channelParam) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcDataChannelConnect"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d|%d", g_cmdIndex, __FUNCTION__, + channelParam->type, channelParam->port, channelParam->isBlock); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result returned by the peer + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcDataChannelBind(HLT_Process *peerProcess, DataChannelParam *channelParam) +{ + int ret; + uint64_t bindId; + Process *srcProcess = NULL; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcDataChannelBind"); + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d|%d|%d", g_cmdIndex, __FUNCTION__, + channelParam->type, channelParam->port, channelParam->isBlock, channelParam->bindFd); + dataBuf.dataLen = strlen(dataBuf.data); + bindId = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result returned by the peer + ret = WaitResult(&expectCmdData, bindId, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + channelParam->port = atoi(expectCmdData.paras[1]); + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcDataChannelAccept(HLT_Process *peerProcess, DataChannelParam *channelParam) +{ + int ret; + uint64_t acceptId; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcDataChannelAccept"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d|%d|%d", g_cmdIndex, __FUNCTION__, + channelParam->type, channelParam->port, channelParam->isBlock, channelParam->bindFd); + dataBuf.dataLen = strlen(dataBuf.data); + acceptId = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + return acceptId; +} + +int HLT_RpcGetAcceptFd(int acceptId) +{ + int ret; + CmdData expectCmdData = {0}; + + ret = WaitResult(&expectCmdData, acceptId, "HLT_RpcDataChannelAccept"); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcTlsRegCallback(HLT_Process *peerProcess, TlsCallbackType type) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsRegCallback"); + + srcProcess = GetProcess(); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, type); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return atoi(expectCmdData.paras[0]); +} + +int HLT_RpcProcessExit(HLT_Process *peerProcess) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcProcessExit"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, peerProcess->connFd); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return SUCCESS; +} + +int HLT_RpcTlsGetStatus(HLT_Process *peerProcess, int sslId) +{ + ASSERT_RETURN(peerProcess != NULL, "HLT_RpcTlsGetStatus Parameter Error"); + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsGetStatus"); + + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcTlsGetAlertFlag(HLT_Process *peerProcess, int sslId) +{ + ASSERT_RETURN(peerProcess != NULL, "HLT_RpcTlsGetAlertFlag Parameter Error"); + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcProcessExit"); + + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcTlsGetAlertLevel(HLT_Process *peerProcess, int sslId) +{ + ASSERT_RETURN(peerProcess != NULL, "HLT_RpcTlsGetAlertLevel Parameter Error"); + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsGetAlertLevel"); + + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcTlsGetAlertDescription(HLT_Process *peerProcess, int sslId) +{ + ASSERT_RETURN(peerProcess != NULL, "HLT_RpcTlsGetAlertDescription Parameter Error"); + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsGetAlertDescription"); + + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcTlsClose(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + CmdData expectCmdData = {0}; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsClose"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcFreeResFormSsl(HLT_Process *peerProcess, int sslId) +{ + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + CmdData expectCmdData = {0}; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcFreeResFormSsl"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcSctpClose(HLT_Process *peerProcess, int fd) +{ + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + CmdData expectCmdData = {0}; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcSctpClose"); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, fd); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol((const char *)expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcCloseFd(HLT_Process *peerProcess, int fd, int linkType) +{ + int ret; + uint64_t cmdIndex; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcCloseFd"); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d", g_cmdIndex, __FUNCTION__, fd, linkType); + + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // The close fd does not need to wait for the result. + return ret; +} + +int HLT_RpcTlsSetMtu(HLT_Process *peerProcess, int sslId, uint16_t mtu) +{ + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess = NULL; + ControlChannelBuf dataBuf; + CmdData expectCmdData = {0}; + srcProcess = GetProcess(); + + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsSetMtu"); + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d|%d", g_cmdIndex, __FUNCTION__, sslId, mtu); + + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} + +int HLT_RpcTlsGetErrorCode(HLT_Process *peerProcess, int sslId) +{ + ASSERT_RETURN(peerProcess != NULL, "HLT_RpcTlsGetStatus Parameter Error"); + ASSERT_RETURN(peerProcess->remoteFlag == 1, "Only Remote Process Support Call HLT_RpcTlsGetErrorCode"); + + int ret; + uint64_t cmdIndex; + char *endPtr = NULL; + Process *srcProcess; + CmdData expectCmdData = {0}; + ControlChannelBuf dataBuf; + srcProcess = GetProcess(); + + pthread_mutex_lock(&g_cmdMutex); + ret = sprintf_s(dataBuf.data, sizeof(dataBuf.data), "%llu|%s|%d", g_cmdIndex, __FUNCTION__, sslId); + dataBuf.dataLen = strlen(dataBuf.data); + cmdIndex = g_cmdIndex; + g_cmdIndex++; + pthread_mutex_unlock(&g_cmdMutex); + + ASSERT_RETURN(ret > 0, "sprintf_s Error"); + + ret = ControlChannelWrite(srcProcess->controlChannelFd, peerProcess->srcDomainPath, &dataBuf); + ASSERT_RETURN(ret == SUCCESS, "ControlChannelWrite Error"); + + // Waiting for the result + ret = WaitResult(&expectCmdData, cmdIndex, __FUNCTION__); + ASSERT_RETURN(ret == SUCCESS, "WaitResult Error"); + return (int)strtol(expectCmdData.paras[0], &endPtr, 0); +} \ No newline at end of file diff --git a/testcode/framework/tls/rpc/src/rpc_func.c b/testcode/framework/tls/rpc/src/rpc_func.c new file mode 100644 index 00000000..d9e2cb74 --- /dev/null +++ b/testcode/framework/tls/rpc/src/rpc_func.c @@ -0,0 +1,685 @@ +/* + * 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 +#include +#include +#include "securec.h" +#include "hlt.h" +#include "handle_cmd.h" +#include "tls_res.h" +#include "logger.h" +#include "lock.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "tls.h" +#include "alert.h" +#include "hitls.h" +#include "common_func.h" +#include "sctp_channel.h" +#include "rpc_func.h" + +#define HITLS_READBUF_MAXLEN (20 * 1024) /* 20K */ +#define SUCCESS 0 +#define ERROR (-1) + +#define ASSERT_RETURN(condition) \ + do { \ + if (!(condition)) { \ + LOG_ERROR("sprintf_s Error"); \ + return ERROR; \ + } \ + } while (0) + +RpcFunList g_rpcFuncList[] = { + {"HLT_RpcTlsNewCtx", RpcTlsNewCtx}, + {"HLT_RpcTlsSetCtx", RpcTlsSetCtx}, + {"HLT_RpcTlsNewSsl", RpcTlsNewSsl}, + {"HLT_RpcTlsSetSsl", RpcTlsSetSsl}, + {"HLT_RpcTlsListen", RpcTlsListen}, + {"HLT_RpcTlsAccept", RpcTlsAccept}, + {"HLT_RpcTlsConnect", RpcTlsConnect}, + {"HLT_RpcTlsRead", RpcTlsRead}, + {"HLT_RpcTlsWrite", RpcTlsWrite}, + {"HLT_RpcTlsRenegotiate", RpcTlsRenegotiate}, + {"HLT_RpcDataChannelAccept", RpcDataChannelAccept}, + {"HLT_RpcDataChannelConnect", RpcDataChannelConnect}, + {"HLT_RpcProcessExit", RpcProcessExit}, + {"HLT_RpcTlsRegCallback", RpcTlsRegCallback}, + {"HLT_RpcTlsGetStatus", RpcTlsGetStatus}, + {"HLT_RpcTlsGetAlertFlag", RpcTlsGetAlertFlag}, + {"HLT_RpcTlsGetAlertLevel", RpcTlsGetAlertLevel}, + {"HLT_RpcTlsGetAlertDescription", RpcTlsGetAlertDescription}, + {"HLT_RpcTlsClose", RpcTlsClose}, + {"HLT_RpcFreeResFormSsl", RpcFreeResFormSsl}, + {"HLT_RpcSctpClose", RpcSctpClose}, + {"HLT_RpcCloseFd", RpcCloseFd}, + {"HLT_RpcTlsSetMtu", RpcTlsSetMtu}, + {"HLT_RpcTlsGetErrorCode", RpcTlsGetErrorCode}, + {"HLT_RpcDataChannelBind", RpcDataChannelBind}, + {"HLT_RpcTlsVerifyClientPostHandshake", RpcTlsVerifyClientPostHandshake}, +}; + +RpcFunList *GetRpcFuncList(void) +{ + return g_rpcFuncList; +} + +int GetRpcFuncNum(void) +{ + return sizeof(g_rpcFuncList) / sizeof(g_rpcFuncList[0]); +} + +int RpcTlsNewCtx(CmdData *cmdData) +{ + int id, ret; + TLS_VERSION tlsVersion; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + tlsVersion = atoi(cmdData->paras[0]); + // Invoke the corresponding function. + void* ctx = HLT_TlsNewCtx(tlsVersion); + if (ctx == NULL) { + LOG_ERROR("HLT_TlsNewCtx Return NULL"); + id = ERROR; + goto ERR; + } + + // Insert to CTX linked list + id = InsertCtxToList(ctx); + +ERR: + // Return Result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, id); + if (ret <= 0) { + return ERROR; + } + return SUCCESS; +} + +int RpcTlsSetCtx(CmdData *cmdData) +{ + int ret; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + // Find the corresponding CTX. + ResList *ctxList = GetCtxList(); + int ctxId = atoi(cmdData->paras[0]); + void *ctx = GetTlsResFromId(ctxList, ctxId); + if (ctx == NULL) { + LOG_ERROR("GetResFromId Error"); + ret = ERROR; + goto ERR; + } + + // Configurations related to parsing + HLT_Ctx_Config ctxConfig = {0}; + ret = ParseCtxConfigFromString(cmdData->paras, &ctxConfig); + if (ret != SUCCESS) { + LOG_ERROR("ParseCtxConfigFromString Error"); + ret = ERROR; + goto ERR; + } + + // Configure the data + ret = HLT_TlsSetCtx(ctx, &ctxConfig); + +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsNewSsl(CmdData *cmdData) +{ + int id, ret; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + // Invoke the corresponding function. + ResList *ctxList = GetCtxList(); + int ctxId = atoi(cmdData->paras[0]); + void *ctx = GetTlsResFromId(ctxList, ctxId); + if (ctx == NULL) { + LOG_ERROR("Not Find Ctx"); + id = ERROR; + goto ERR; + } + + void *ssl = HLT_TlsNewSsl(ctx); + if (ssl == NULL) { + LOG_ERROR("HLT_TlsNewSsl Return NULL"); + id = ERROR; + goto ERR; + } + + // Insert to the SSL linked list. + id = InsertSslToList(ctx, ssl); + +ERR: + // Return the result. + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, id); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsSetSsl(CmdData *cmdData) +{ + int ret; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + int sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + ret = ERROR; + goto ERR; + } + + HLT_Ssl_Config sslConfig = {0}; + sslConfig.sockFd = atoi(cmdData->paras[1]); // The first parameter indicates the FD value. + sslConfig.connType = atoi(cmdData->paras[2]); // The second parameter indicates the link type. + // The third parameter of indicates the Ctrl command that needs to register the hook. + sslConfig.connPort = atoi(cmdData->paras[3]); + ret = HLT_TlsSetSsl(ssl, &sslConfig); +ERR: + // Return the result. + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsListen(CmdData *cmdData) +{ + int ret; + int sslId; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + ResList *sslList = GetSslList(); + sslId = strtol(cmdData->paras[0], NULL, 10); // Convert to a decimal number + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + ret = ERROR; + goto ERR; + } + + ret = HLT_TlsListenBlock(ssl); + +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsAccept(CmdData *cmdData) +{ + int ret; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + ResList *sslList = GetSslList(); + int sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + ret = ERROR; + goto ERR; + } + + // If there is a problem, the user must use non-blocking, and the remote call must use blocking + ret = HLT_TlsAcceptBlock(ssl); + +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsConnect(CmdData *cmdData) +{ + int ret; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + int sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + ret = ERROR; + goto ERR; + } + + ret = HLT_TlsConnect(ssl); + +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsRead(CmdData *cmdData) +{ + int ret = SUCCESS; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + ResList *sslList = GetSslList(); + int sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + ret = ERROR; + goto ERR; + } + + int dataLen = atoi(cmdData->paras[1]); + uint32_t readLen = 0; + if (dataLen == 0) { + LOG_ERROR("dataLen is 0"); + ret = ERROR; + goto ERR; + } + uint8_t *data = (uint8_t *)calloc(1u, dataLen); + if (data == NULL) { + LOG_ERROR("Calloc Error"); + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + } + (void)memset_s(data, dataLen, 0, dataLen); + ret = HLT_TlsRead(ssl, data, dataLen, &readLen); + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d|%u|%s", + cmdData->id, cmdData->funcId, ret, readLen, data); + free(data); + return SUCCESS; +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d|", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsWrite(CmdData *cmdData) +{ + int ret; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + int sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + ret = ERROR; + goto ERR; + } + + int dataLen = atoi(cmdData->paras[1]); // The first parameter indicates the data length. + if (dataLen == 0) { + LOG_ERROR("dataLen is 0"); + ret = ERROR; + goto ERR; + } + uint8_t *data = (uint8_t *)calloc(1u, dataLen); + if (data == NULL) { + LOG_ERROR("Calloc Error"); + ret = ERROR; + goto ERR; + } + if (dataLen >= CONTROL_CHANNEL_MAX_MSG_LEN) { + free(data); + goto ERR; + } + // The second parameter of indicates the content of the write data. + ret = memcpy_s(data, dataLen, cmdData->paras[2], dataLen); + if (ret != EOK) { + LOG_ERROR("memcpy_s Error"); + free(data); + goto ERR; + } + ret = HLT_TlsWrite(ssl, data, dataLen); + free(data); + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsRenegotiate(CmdData *cmdData) +{ + int ret = ERROR; + ResList *sslList = GetSslList(); + int sslId = (int)strtol(cmdData->paras[0], NULL, 10); // Convert to a decimal number + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + goto ERR; + } + + ret = HLT_TlsRenegotiate(ssl); + +ERR: + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsVerifyClientPostHandshake(CmdData *cmdData) +{ + int ret = ERROR; + ResList *sslList = GetSslList(); + int sslId = (int)strtol(cmdData->paras[0], NULL, 10); // Convert to a decimal number + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl == NULL) { + LOG_ERROR("Not Find Ssl"); + goto ERR; + } + + ret = HLT_TlsVerifyClientPostHandshake(ssl); + +ERR: + // Return Result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcProcessExit(CmdData *cmdData) +{ + int ret; + // If 1 is returned, the process needs to exit + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, getpid()); + ASSERT_RETURN(ret > 0); + return 1; +} + +int RpcDataChannelAccept(CmdData *cmdData) +{ + int sockFd, ret; + DataChannelParam channelParam; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + (void)memset_s(&channelParam, sizeof(DataChannelParam), 0, sizeof(DataChannelParam)); + + channelParam.type = atoi(cmdData->paras[0]); + channelParam.port = atoi(cmdData->paras[1]); // The first parameter of indicates the port number + channelParam.isBlock = atoi(cmdData->paras[2]); // The second parameter of indicates whether to block + channelParam.bindFd = atoi(cmdData->paras[3]); // The third parameter of indicates whether the cis blocked. + + // Invoke the blocking interface + sockFd = RunDataChannelAccept(&channelParam); + + // Return the result. + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, sockFd); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcDataChannelBind(CmdData *cmdData) +{ + int sockFd, ret; + DataChannelParam channelParam; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + (void)memset_s(&channelParam, sizeof(DataChannelParam), 0, sizeof(DataChannelParam)); + + channelParam.type = atoi(cmdData->paras[0]); + channelParam.port = atoi(cmdData->paras[1]); // The first parameter of indicates the port number + channelParam.isBlock = atoi(cmdData->paras[2]); // The second parameter of indicates whether to block + channelParam.bindFd = atoi(cmdData->paras[3]); // The third parameter of indicates whether the cis blocked. + + // Invoke the blocking interface + sockFd = RunDataChannelBind(&channelParam); + + // Return the result. + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d|%d", cmdData->id, cmdData->funcId, + sockFd, channelParam.port); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + + +int RpcDataChannelConnect(CmdData *cmdData) +{ + int ret, sockFd; + DataChannelParam channelParam; + + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + (void)memset_s(&channelParam, sizeof(DataChannelParam), 0, sizeof(DataChannelParam)); + + channelParam.type = atoi(cmdData->paras[0]); + channelParam.port = atoi(cmdData->paras[1]); // The first parameter of indicates the port number. + channelParam.isBlock = atoi(cmdData->paras[2]); // The second parameter of indicates whether the is blocked + + sockFd = HLT_DataChannelConnect(&channelParam); + + // Return the result. + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, sockFd); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsRegCallback(CmdData *cmdData) +{ + int ret; + TlsCallbackType type; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + type = atoi(cmdData->paras[0]); + // Invoke the corresponding function + ret = HLT_TlsRegCallback(type); + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsGetStatus(CmdData *cmdData) +{ + int ret, sslId; + uint32_t sslState = 0; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl != NULL) { + sslState = ((HITLS_Ctx *)ssl)->state; + } + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%u", cmdData->id, cmdData->funcId, sslState); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsGetAlertFlag(CmdData *cmdData) +{ + int ret, sslId; + ALERT_Info alertInfo = {0}; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl != NULL) { + ALERT_GetInfo(ssl, &alertInfo); + } + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", + cmdData->id, cmdData->funcId, alertInfo.flag); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsGetAlertLevel(CmdData *cmdData) +{ + int ret, sslId; + ALERT_Info alertInfo = {0}; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl != NULL) { + ALERT_GetInfo(ssl, &alertInfo); + } + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", + cmdData->id, cmdData->funcId, alertInfo.level); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsGetAlertDescription(CmdData *cmdData) +{ + int ret, sslId; + ALERT_Info alertInfo = {0}; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + sslId = atoi(cmdData->paras[0]); + void *ssl = GetTlsResFromId(sslList, sslId); + if (ssl != NULL) { + ALERT_GetInfo(ssl, &alertInfo); + } + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", + cmdData->id, cmdData->funcId, alertInfo.description); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsClose(CmdData *cmdData) +{ + int ret, sslId; + void *ssl = NULL; + char *endPtr = NULL; + + ASSERT_RETURN(memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)) == EOK); + ResList *sslList = GetSslList(); + sslId = (int)strtol(cmdData->paras[0], &endPtr, 0); + ssl = GetTlsResFromId(sslList, sslId); + ASSERT_RETURN(ssl != NULL); + + ret = HLT_TlsClose(ssl); + + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcFreeResFormSsl(CmdData *cmdData) +{ + int ret, sslId; + void *ssl = NULL; + char *endPtr = NULL; + + ASSERT_RETURN(memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)) == EOK); + ResList *sslList = GetSslList(); + sslId = (int)strtol(cmdData->paras[0], &endPtr, 0); + ssl = GetTlsResFromId(sslList, sslId); + ASSERT_RETURN(ssl != NULL); + + ret = HLT_FreeResFromSsl(ssl); + + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcSctpClose(CmdData *cmdData) +{ + int ret, fd; + char *endPtr = NULL; + + ASSERT_RETURN(memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)) == EOK); + fd = (int)strtol(cmdData->paras[0], &endPtr, 0); + + SctpClose(fd); + + // Return the result + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, SUCCESS); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcCloseFd(CmdData *cmdData) +{ + int ret, fd, linkType; + char *endPtr = NULL; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + fd = (int)strtol(cmdData->paras[0], &endPtr, 0); + linkType = (int)strtol(cmdData->paras[1], &endPtr, 0); + + ret = SUCCESS; + HLT_CloseFd(fd, linkType); + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsSetMtu(CmdData *cmdData) +{ + int ret, sslId; + uint16_t mtu; + void *ssl = NULL; + char *endPtr = NULL; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + sslId = (int)strtol(cmdData->paras[0], &endPtr, 0); + mtu = (int)strtol(cmdData->paras[1], &endPtr, 0); + ssl = GetTlsResFromId(sslList, sslId); + ASSERT_RETURN(ssl != NULL); + + ret = HLT_TlsSetMtu(ssl, mtu); + + ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, ret); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} + +int RpcTlsGetErrorCode(CmdData *cmdData) +{ + int sslId; + int errorCode; + void *ssl = NULL; + char *endPtr = NULL; + (void)memset_s(cmdData->result, sizeof(cmdData->result), 0, sizeof(cmdData->result)); + + ResList *sslList = GetSslList(); + sslId = (int)strtol(cmdData->paras[0], &endPtr, 0); + ssl = GetTlsResFromId(sslList, sslId); + ASSERT_RETURN(ssl != NULL); + + errorCode = HLT_TlsGetErrorCode(ssl); + + int ret = sprintf_s(cmdData->result, sizeof(cmdData->result), "%s|%s|%d", cmdData->id, cmdData->funcId, errorCode); + ASSERT_RETURN(ret > 0); + return SUCCESS; +} \ No newline at end of file diff --git a/testcode/framework/tls/transfer/include/control_channel.h b/testcode/framework/tls/transfer/include/control_channel.h new file mode 100644 index 00000000..e7cf62a9 --- /dev/null +++ b/testcode/framework/tls/transfer/include/control_channel.h @@ -0,0 +1,58 @@ +/* + * 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 CONTROL_CHANNEL_H +#define CONTROL_CHANNEL_H + +#include "channel_res.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the control channel + */ +int ControlChannelInit(ControlChannelRes *info); + +/** + * @brief Close the control channel + */ +int ControlChannelClose(ControlChannelRes *info); + +/** + * @brief Read data from the control channel + */ +int ControlChannelRead(int32_t sockFd, ControlChannelBuf *dataBuf); + +/** + * @brief Write data to the control channel + */ +int ControlChannelWrite(int32_t sockFd, char *peerDomainPath, ControlChannelBuf *dataBuf); + +/** + * @brief Control channel initiation + */ +int ControlChannelConnect(ControlChannelRes *info); + +/** + * @brief The control channel waits for a connection + */ +int ControlChannelAccept(ControlChannelRes *info); + +#ifdef __cplusplus +} +#endif + +#endif // CONTROL_CHANNEL_H \ No newline at end of file diff --git a/testcode/framework/tls/transfer/include/sctp_channel.h b/testcode/framework/tls/transfer/include/sctp_channel.h new file mode 100644 index 00000000..fc444b40 --- /dev/null +++ b/testcode/framework/tls/transfer/include/sctp_channel.h @@ -0,0 +1,68 @@ +/* + * 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 SCTP_CHANNEL_H +#define SCTP_CHANNEL_H + +#include +#include +#include "hitls.h" +#include "bsl_uio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initiate an SCTP connection + */ +int32_t SctpConnect(char *targetIP, int32_t targetPort, bool isBlock); + +/** + * @brief Waiting for SCTP connection + */ +int32_t SctpAccept(char *ip, int listenFd, bool isBlock); + +/** + * @brief Disable the SCTP connection + */ +void SctpClose(int fd); + +/** + * @brief Obtain the default SCTP method + */ +BSL_UIO_Method *SctpGetDefaultMethod(void); + +/** + * @brief Set the Ctrl command for registering the hook + */ +void SetNeedCbSctpCtrlCmd(int cmd); + +int32_t SctpBind(int port); + +// Default SCTP connection method +int32_t SctpDefaultWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen); +int32_t SctpDefaultRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen); +int32_t SctpDefaultCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param); + +// Change the SCTP connection of the message +int32_t SctpFrameWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen); +int32_t SctpFrameRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen); + +#ifdef __cplusplus +} +#endif + +#endif // SCTP_CHANNEL_H diff --git a/testcode/framework/tls/transfer/include/socket_common.h b/testcode/framework/tls/transfer/include/socket_common.h new file mode 100644 index 00000000..79848b48 --- /dev/null +++ b/testcode/framework/tls/transfer/include/socket_common.h @@ -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 SOCKET_COMMON_H +#define SOCKET_COMMON_H + +#include +#include "hlt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Sock Set the block + */ +int32_t SetBlockMode(int32_t sd, bool isBlock); + +/** + * @brief Check whether there are fatal I/O errors + */ +bool IsNonFatalErr(int32_t err); + +/** + * @brief Set the message injection parameter, which must be used with the CleantFrameHandle + */ +int32_t SetFrameHandle(HLT_FrameHandle *frameHandle); + +/** + * @brief Clear message injection parameters + */ +void CleanFrameHandle(void); + +/** + * @brief Obtain message injection parameters + */ +HLT_FrameHandle *GetFrameHandle(void); + +/** + * @brief Obtain the newbuf by parsing the buf. Constraint: The input parameter of packLen cannot be empty + */ +uint8_t *GetNewBuf(const void *buf, uint32_t len, uint32_t *packLen); + +/** + * @brief Release the newbuf applied by GetNewBuf + */ +void FreeNewBuf(void *newBuf); + +#ifdef __cplusplus +} +#endif + +#endif // SOCKET_COMMON_H \ No newline at end of file diff --git a/testcode/framework/tls/transfer/include/tcp_channel.h b/testcode/framework/tls/transfer/include/tcp_channel.h new file mode 100644 index 00000000..8969f4df --- /dev/null +++ b/testcode/framework/tls/transfer/include/tcp_channel.h @@ -0,0 +1,50 @@ +/* + * 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 TCP_CHANNEL_H +#define TCP_CHANNEL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Connects to the peer and returns a socket descriptor. */ +int TcpConnect(const char *targetIP, const int targetPort); + +/* listen */ +int TcpBind(const int localPort); + +/* accept */ +int TcpAccept(char *ip, int listenFd, bool isBlock, bool needClose); + +/* write */ +int32_t TcpFrameWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen); + +/* + * When the Windows TCP server is used, the socket that is closed accept cannot be cleaned up. + * Otherwise, the next accept operation will fail + */ +void TcpClose(int sd); + +/* Default TCP method based on Linux */ +void *TcpGetDefaultMethod(void); + +#ifdef __cplusplus +} +#endif + +#endif // TCP_CHANNEL_H diff --git a/testcode/framework/tls/transfer/src/control_channel.c b/testcode/framework/tls/transfer/src/control_channel.c new file mode 100644 index 00000000..5530ece9 --- /dev/null +++ b/testcode/framework/tls/transfer/src/control_channel.c @@ -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 +#include "channel_res.h" +#include "logger.h" +#include "securec.h" + +#define SUCCESS 0 +#define ERROR (-1) + +int ControlChannelInit(ControlChannelRes *channelInfo) +{ + int len; + int sockFd; + struct timeval timeOut; + + unlink(channelInfo->srcDomainPath); + // Create a socket. + sockFd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (sockFd < 0) { + LOG_ERROR("Get SockFd Error"); + return ERROR; + } + // Set the non-blocking mode. + timeOut.tv_sec = 0; // Second + timeOut.tv_usec = 10000; // 10000 microseconds + if (setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) == -1) { + LOG_ERROR("Setsockopt Fail"); + return ERROR; + } + // Binding ports. + len = offsetof(struct sockaddr_un, sun_path) + strlen(channelInfo->srcDomainPath) + 1; + if (bind(sockFd, (struct sockaddr *)&(channelInfo->srcAddr), len) < 0) { + LOG_ERROR("Bind Error\n"); + return ERROR; + } + channelInfo->sockFd = sockFd; + return 0; +} + +int ControlChannelAcept(ControlChannelRes *channelInfo) +{ + (void)channelInfo; + return SUCCESS; +} + +int ControlChannelConnect(ControlChannelRes *channelInfo) +{ + (void)channelInfo; + return SUCCESS; +} + +int ControlChannelWrite(int32_t sockFd, char *peerDomainPath, ControlChannelBuf *dataBuf) +{ + int ret; + uint32_t dataLen; + uint32_t addrLen; + struct sockaddr_un peerAddr; + + peerAddr.sun_family = AF_UNIX; + ret = strcpy_s(peerAddr.sun_path, strlen(peerDomainPath) + 1, peerDomainPath); + if (ret != EOK) { + LOG_ERROR("strcpy_s Error"); + return ERROR; + } + addrLen = offsetof(struct sockaddr_un, sun_path) + strlen(peerDomainPath) + 1; + dataLen = sendto(sockFd, dataBuf->data, dataBuf->dataLen, 0, (struct sockaddr *)&peerAddr, addrLen); + if (dataLen != dataBuf->dataLen) { + LOG_ERROR("Send Msg Error: %s\n", dataBuf->data); + return ERROR; + } + return SUCCESS; +} + +int ControlChannelRead(int32_t sockFd, ControlChannelBuf *dataBuf) +{ + struct sockaddr_un peerAddr; + int dataLen; + socklen_t addrLen = sizeof(struct sockaddr_un); + (void)memset_s(dataBuf->data, CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN); + + dataLen = recvfrom(sockFd, dataBuf->data, CONTROL_CHANNEL_MAX_MSG_LEN, 0, + (struct sockaddr *)(&peerAddr), &(addrLen)); + if (dataLen < 0) { + return ERROR; + } + dataBuf->dataLen = dataLen; + return SUCCESS; +} \ No newline at end of file diff --git a/testcode/framework/tls/transfer/src/sctp_channel.c b/testcode/framework/tls/transfer/src/sctp_channel.c new file mode 100644 index 00000000..119aa5de --- /dev/null +++ b/testcode/framework/tls/transfer/src/sctp_channel.c @@ -0,0 +1,403 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "logger.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls.h" +#include "tls.h" +#include "hs_ctx.h" +#include "bsl_errno.h" +#include "uio_base.h" +#include "hlt_type.h" +#include "socket_common.h" + +#define SUCCESS 0 +#define ERROR (-1) + +#define SCTP_DATA_CHUNK_TYPE 0x00 +#define SCTP_FORWARD_TSN_CHUNK_TYPE 0xc0 +#define SCTP_LISTEN_MAX 5 +#define SCTP_GAUTH_CHUNKS_SIZE 256 +#define SCTP_AUTH_ENABLE "echo 1 > /proc/sys/net/sctp/auth_enable" + +int g_NeedCbsctpCtrlCmd; +int32_t SctpCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg); + +/* +To enable the RFC 4895 about authenticating chunks: +$ sudo echo 1 > /proc/sys/net/sctp/auth_enable +To enable the RFC 5061 about dynamic address reconfiguration: +$ sudo echo 1 > /proc/sys/net/sctp/addip_enable +You may also want to use the dynamic address reconfiguration without necessarily enabling the chunk authentication: +$ sudo echo 1 > /proc/sys/net/sctp/addip_noauth_enable +*/ +int32_t SctpEnableAuth(int32_t fd) +{ + /* To enable the RFC 4895 authentication block */ + system(SCTP_AUTH_ENABLE); + /* data chunks */ + struct sctp_authchunk auth; + auth.sauth_chunk = SCTP_DATA_CHUNK_TYPE; + int32_t ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); + if (ret < 0) { + LOG_ERROR("error while setsockopt SCTP_AUTH_CHUNK. ret is %d\n", ret); + return ERROR; + } + /* FORWARD-TSN chunks */ + auth.sauth_chunk = SCTP_FORWARD_TSN_CHUNK_TYPE; + ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, + sizeof(struct sctp_authchunk)); + if (ret < 0) { + LOG_ERROR("error while setsockopt SCTP_AUTH_CHUNK. ret is %d\n", ret); + return ERROR; + } + LOG_DEBUG("SctpEnableAuth Success"); + return SUCCESS; +} + +/* Obtain the number of transmitted streams */ +static int32_t SctpGetSendStreamNum(int32_t fd, uint16_t *sendStreamNum) +{ + struct sctp_status status; + socklen_t statusLen = sizeof(status); + int32_t ret = getsockopt(fd, IPPROTO_SCTP, SCTP_STATUS, &status, &statusLen); + if (ret < 0) { + LOG_ERROR("error while geting socket option.\n"); + return ret; + } + *sendStreamNum = status.sstat_outstrms; + return 0; +} + +/* Connects to the peer and returns a socket descriptor. + Currently, only one IP function is designed. If required, SCTP_Connect can be rewritten. + */ +int32_t SctpConnect(char *targetIP, int targetPort, bool isBlock) +{ + int32_t fd = 0; + int32_t ret; + struct sockaddr_in sockAddr; + // Create a socket + if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) { + LOG_ERROR("Create Sock Fail"); + return ERROR; + } + + int32_t option = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { + LOG_ERROR("Set Sock Opt Fail"); + goto ERR; + } + + struct linger so_linger; + so_linger.l_onoff = true; + so_linger.l_linger = 0; + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 0) { + close(fd); + LOG_ERROR("setsockopt() linger fail\n"); + return -1; + } + + /* Enable SCTP auth */ + ret = SctpEnableAuth(fd); + if (ret != 0) { + LOG_ERROR("SctpEnableAuth."); + goto ERR; + } + + /* Enable SCTP Events */ + struct sctp_event_subscribe events = {0}; + events.sctp_data_io_event = 1; + ret = setsockopt(fd, SOL_SCTP, SCTP_EVENTS, (void *)&events, sizeof(events)); + if (ret < 0) { + LOG_ERROR("setsockopt SCTP_EVENTS."); + goto ERR; + } + + // Set the protocol and port number + memset_s(&sockAddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(targetPort); + // Set the IP address + sockAddr.sin_addr.s_addr = inet_addr(targetIP); + + // Connection + int16_t tryNum = 0; + sctp_assoc_t assoc_id; + LOG_DEBUG("Try Sctp Connect..."); + do { + ret = sctp_connectx(fd, (struct sockaddr*)&sockAddr, 1, &assoc_id); + tryNum++; + usleep(1000); // 1000microseconds + } while ((ret != 0) && (tryNum < 6000)); // 6000 indicates that the connection is attempted within 6 seconds + if (ret != 0) { + LOG_ERROR("Sctp Connect Fail, ret is %d error id: %d\n", ret, errno); + goto ERR; + } + LOG_DEBUG("SCTP Connect Success"); + uint16_t sendStreamNum; + ret = SctpGetSendStreamNum(fd, &sendStreamNum); + if (ret != 0) { + LOG_ERROR("SctpGetSendStreamNum error."); + goto ERR; + } + // Whether to set the blocking interface + ret = SetBlockMode(fd, isBlock); + return fd; + +ERR: + close(fd); + return ERROR; +} + +int32_t SctpBind(int port) +{ + int32_t lisentFd; + struct sockaddr_in serverAddr; + int32_t ret; + + // Create a socket + lisentFd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (lisentFd == -1) { + LOG_ERROR("create socket() fail."); + return ERROR; + } + + int32_t option = 1; + if (setsockopt(lisentFd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { + LOG_ERROR("setsockopt fail."); + goto ERR; + } + + struct linger so_linger; + so_linger.l_onoff = true; + so_linger.l_linger = 0; + if (setsockopt(lisentFd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 0) { + close(lisentFd); + LOG_ERROR("setsockopt() linger fail\n"); + return -1; + } + + // Set the protocol and port number + memset_s(&serverAddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(port); + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + const int32_t addr_count = 1; + int32_t tryNum = 0; + // Bind fails. Continue to bind + LOG_DEBUG("Bind Ing..."); + do { + ret = sctp_bindx(lisentFd, (struct sockaddr*)&serverAddr, addr_count, SCTP_BINDX_ADD_ADDR); + usleep(1000); // 1000 microseconds, that is, 1 ms + tryNum++; + } while ((ret != 0) && (tryNum < 6000)); // 6000: indicates that the binding attempt is 6 seconds + if (ret != 0) { + LOG_ERROR("sctp_bindx socket fail error id: %d\n", errno); + goto ERR; + } + LOG_DEBUG("SCTP BIND SUCCESS"); + /* Enable SCTP auth */ + ret = SctpEnableAuth(lisentFd); + if (ret == ERROR) { + LOG_ERROR("SctpEnableAuth Error"); + goto ERR; + } + + /* Enable SCTP Events */ + struct sctp_event_subscribe events = {0}; + events.sctp_data_io_event = 1; + ret = setsockopt(lisentFd, SOL_SCTP, SCTP_EVENTS, (void *)&events, sizeof(events)); + if (ret < 0) { + LOG_ERROR("setsockopt SCTP_EVENTS error."); + goto ERR; + } + + if (listen(lisentFd, SCTP_LISTEN_MAX) != 0) { + LOG_ERROR("listen socket fail, error id is %d\n", errno); + goto ERR; + } + + return lisentFd; + +ERR: + close(lisentFd); + return ERROR; +} + +int32_t SctpAccept(char* ip, int listenFd, bool isBlock) +{ + (void)ip; + int32_t ret; + struct sockaddr_in sockAddr; + + uint32_t len = sizeof(struct sockaddr_in); + int32_t fd; + uint32_t tryNum; + tryNum = 0; + do { + fd = accept(listenFd, (struct sockaddr *)&sockAddr, &len); + tryNum++; + usleep(1000); // 1000 microseconds, that is, 1 ms + // 10000: indicates that the system attempts to listen on the system for 10 seconds + } while ((fd < 0) && (tryNum < 10000)); + if (fd < 0) { + LOG_ERROR("SCTP Accept Fail, error id is %d\n", errno); + close(listenFd); + return ERROR; + } + + LOG_DEBUG("SCTP Accept Success"); + uint16_t sendStreamNum; + ret = SctpGetSendStreamNum(fd, &sendStreamNum); + if (ret != 0) { + LOG_ERROR("SctpGetSendStreamNum error."); + close(listenFd); + close(fd); + return ERROR; + } + + // Indicates whether to block the interface + ret = SetBlockMode(fd, isBlock); + if (ret != SUCCESS) { + close(listenFd); + close(fd); + LOG_ERROR("SetBlockMode ERROR"); + } + // Disable listenFd + close(listenFd); + return fd; +} + +/* closes the given socket descriptor. */ +void SctpClose(int32_t fd) +{ + close(fd); +} + +void SetNeedCbSctpCtrlCmd(int cmd) +{ + g_NeedCbsctpCtrlCmd = cmd; +} + + + +int32_t SctpFrameWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + int32_t ret; + uint8_t *newBuf = NULL; + const void *sendBuf = buf; + uint32_t sendLen = len; + HLT_FrameHandle *frameHandle = GetFrameHandle(); + + if (frameHandle->frameCallBack != NULL && frameHandle->pointType == POINT_SEND) { + newBuf = GetNewBuf(buf, len, &sendLen); + if (sendLen == 0) { // when sendLen changes and becomes 0, the value is IO_BUSY + *writeLen = 0; + return BSL_SUCCESS; + } + if (newBuf != NULL) { + sendBuf = (void *)newBuf; + } + } + ret = BSL_UIO_SctpMethod()->write(uio, sendBuf, sendLen, writeLen); + if (sendLen != len && *writeLen != 0) { + *writeLen = len; + } + FreeNewBuf(newBuf); + return ret; +} + +int32_t SctpFrameRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + int ret; + ret = BSL_UIO_SctpMethod()->read(uio, buf, len, readLen); + if (ret != BSL_SUCCESS) { + return ret; + } + + uint8_t *newBuf = NULL; + uint32_t packLen = *readLen; + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->frameCallBack != NULL && frameHandle->pointType == POINT_RECV) { + newBuf = GetNewBuf(buf, len, &packLen); + if (packLen == 0) { // when packLen changes and becomes 0, the value is IO_BUSY + *readLen = 0; + return BSL_SUCCESS; + } + if (newBuf != NULL) { + if (memcpy_s(buf, len, (uint8_t *)newBuf, packLen) != EOK) { + FreeNewBuf(newBuf); + return BSL_UIO_IO_EXCEPTION; + } + *readLen = packLen; + } + FreeNewBuf(newBuf); + } + return BSL_SUCCESS; +} + +int32_t SelectSctpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->method.write != NULL) { + return frameHandle->method.write(uio, buf, len, writeLen); + } + return SctpFrameWrite(uio, buf, len, writeLen); +} + +int32_t SelectSctpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->method.read != NULL) { + return frameHandle->method.read(uio, buf, len, readLen); + } + return SctpFrameRead(uio, buf, len, readLen); +} + +int32_t SelectSctpCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param) +{ + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->method.ctrl != NULL) { + return frameHandle->method.ctrl(uio, cmd, larg, param); + } + return BSL_UIO_SctpMethod()->ctrl(uio, cmd, larg, param); +} + +static BSL_UIO_Method g_SctpUioMethodDefault; + +/* Provide the default Linux implementation method */ +BSL_UIO_Method *SctpGetDefaultMethod(void) +{ + const BSL_UIO_Method *ori = BSL_UIO_SctpMethod(); + memcpy(&g_SctpUioMethodDefault, ori, sizeof(g_SctpUioMethodDefault)); + g_SctpUioMethodDefault.write = SelectSctpWrite; + g_SctpUioMethodDefault.read = SelectSctpRead; + g_SctpUioMethodDefault.ctrl = SelectSctpCtrl; + return &g_SctpUioMethodDefault; +} diff --git a/testcode/framework/tls/transfer/src/socket_common.c b/testcode/framework/tls/transfer/src/socket_common.c new file mode 100644 index 00000000..580cbc32 --- /dev/null +++ b/testcode/framework/tls/transfer/src/socket_common.c @@ -0,0 +1,256 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls.h" +#include "tls.h" +#include "hs_ctx.h" +#include "bsl_errno.h" +#include "uio_base.h" + +#include "frame_msg.h" +#include "logger.h" +#include "hlt_type.h" + +#define SUCCESS 0 +#define ERROR (-1) + +#define MAX_LEN (20 * 1024) + +/* set block mode. */ +int32_t SetBlockMode(int32_t sd, bool isBlock) +{ + if (isBlock) { + LOG_DEBUG("Socket Set Block Mode"); + int flag; + flag = fcntl(sd, F_GETFL, 0); + flag &= ~O_NONBLOCK; + if (fcntl(sd, F_SETFL, flag) < 0) { + LOG_ERROR("fcntl fail"); + return ERROR; + } + } else { + LOG_DEBUG("Socket Set Unblock Mode"); + int flag; + flag = fcntl(sd, F_GETFL, 0); + flag |= O_NONBLOCK; + if (fcntl(sd, F_SETFL, flag) < 0) { + LOG_ERROR("fcntl fail"); + return ERROR; + } + } + return SUCCESS; +} + +/** + * @brief Check whether there are fatal I/O errors + * + * @param err [IN] Error type + * + * @return true :A fatal error occurs + * false:No fatal error occurs + */ +bool IsNonFatalErr(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; +} + +static HLT_FrameHandle g_frameHandle; + +int32_t SetFrameHandle(HLT_FrameHandle *frameHandle) +{ + if (frameHandle == NULL || frameHandle->ctx == NULL) { + return HITLS_NULL_INPUT; + } + g_frameHandle.ctx = frameHandle->ctx; + g_frameHandle.frameCallBack = frameHandle->frameCallBack; + g_frameHandle.userData = frameHandle->userData; + g_frameHandle.expectHsType = frameHandle->expectHsType; + g_frameHandle.expectReType = frameHandle->expectReType; + g_frameHandle.ioState = frameHandle->ioState; + g_frameHandle.pointType = frameHandle->pointType; + g_frameHandle.method.write = frameHandle->method.write; + g_frameHandle.method.read = frameHandle->method.read; + g_frameHandle.method.ctrl = frameHandle->method.ctrl; + + return HITLS_SUCCESS; +} + +void CleanFrameHandle(void) +{ + g_frameHandle.ctx = NULL; + g_frameHandle.frameCallBack = NULL; + g_frameHandle.userData = NULL; + g_frameHandle.expectHsType = 0; + g_frameHandle.expectReType = 0; + g_frameHandle.ioState = 0; + g_frameHandle.pointType = 0; + g_frameHandle.method.write = NULL; + g_frameHandle.method.read = NULL; + g_frameHandle.method.ctrl = NULL; +} + +HLT_FrameHandle *GetFrameHandle(void) +{ + return &g_frameHandle; +} + +/* Obtain the frameType. The input parameters frameHandle and frameType must not be empty */ +static int32_t GetFrameType(HLT_FrameHandle *frameHandle, FRAME_Type *frameType) +{ + if (frameHandle->ctx == NULL) { + return HITLS_NULL_INPUT; + } + TLS_Ctx *tmpCtx = (TLS_Ctx *)frameHandle->ctx; + frameType->versionType = tmpCtx->negotiatedInfo.version > 0 ? + tmpCtx->negotiatedInfo.version : tmpCtx->config.tlsConfig.maxVersion; + frameType->keyExType = tmpCtx->hsCtx->kxCtx->keyExchAlgo; + frameType->recordType = frameHandle->expectReType; + frameType->handshakeType = frameHandle->expectHsType; + return HITLS_SUCCESS; +} + +/* Verify whether the parsed msg meets the requirements. Restrict the msg input parameter */ +static bool CheckHandleType(FRAME_Msg *msg) +{ + if (msg->recType.data != REC_TYPE_HANDSHAKE) { + if ((int32_t)msg->recType.data == g_frameHandle.expectReType) { + return true; + } + } else { + if ((int32_t)msg->recType.data == g_frameHandle.expectReType && + (int32_t)msg->body.hsMsg.type.data == g_frameHandle.expectHsType) { + return true; + } + } + return false; +} + +/* Release the newbuf */ +void FreeNewBuf(void *newBuf) +{ + if (newBuf != NULL) { + free(newBuf); + } +} + +/* Obtain the newbuf by parsing the buffer. The input parameter of the packageLen constraint is not empty */ +uint8_t *GetNewBuf(const void *buf, uint32_t len, uint32_t *packLen) +{ + uint32_t packLenTmp = 0; + /* Obtain the frameType */ + FRAME_Type frameType = { 0 }; + if (GetFrameType(&g_frameHandle, &frameType) != HITLS_SUCCESS) { + return NULL; + } + /* Unpack the buffer into the msg structure */ + uint32_t parseLen = 0; + FRAME_Msg msg = { 0 }; + uint32_t offset = 0; + uint8_t *newBuf = (uint8_t *)calloc(MAX_LEN, sizeof(uint8_t)); + uint32_t newOffset = 0; + + while (offset < *packLen) { + /* Currently, encryption and decryption are not performed. + * Therefore, the return value is not determined + * because the encrypted messages such as finished messages will fail to be parsed + */ + (void)FRAME_ParseMsg(&frameType, &((uint8_t*)buf)[offset], len - offset, &msg, &parseLen); + + if (CheckHandleType(&msg)) { + if (g_frameHandle.ioState == EXP_IO_BUSY) { + FRAME_CleanMsg(&frameType, &msg); + /* Set I/O to busy */ + *packLen = 0; + FreeNewBuf(newBuf); + return NULL; + } + if (g_frameHandle.userData == NULL) { + g_frameHandle.userData = (void *)&frameType; + } + g_frameHandle.frameCallBack(&msg, g_frameHandle.userData); + /* Pack the newly constructed msg into a buffer */ + if (FRAME_PackMsg(&frameType, &msg, &newBuf[newOffset], MAX_LEN - newOffset, &packLenTmp) != HITLS_SUCCESS) { + FRAME_CleanMsg(&frameType, &msg); + FreeNewBuf(newBuf); + return NULL; + } + newOffset += packLenTmp; + } else { + memcpy_s(&newBuf[newOffset], MAX_LEN - newOffset, &((uint8_t*)buf)[offset], parseLen); + newOffset += parseLen; + } + offset += parseLen; + FRAME_CleanMsg(&frameType, &msg); + } + + /* Check whether the package is reassembled. If not, *packLen should not be changed */ + if (packLenTmp == 0) { + FreeNewBuf(newBuf); + return NULL; + } + + *packLen = newOffset; + return newBuf; +} \ No newline at end of file diff --git a/testcode/framework/tls/transfer/src/tcp_channel.c b/testcode/framework/tls/transfer/src/tcp_channel.c new file mode 100644 index 00000000..aff39534 --- /dev/null +++ b/testcode/framework/tls/transfer/src/tcp_channel.c @@ -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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "bsl_uio.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls.h" +#include "tls.h" +#include "hs_ctx.h" +#include "bsl_errno.h" +#include "uio_base.h" + +#include "logger.h" +#include "hlt_type.h" +#include "socket_common.h" +#include "tcp_channel.h" + +/** + * @brief Connects to the peer and returns a socket descriptor. + * + * @return -1 is returned when an error occurs + * */ +int TcpConnect(const char *targetIP, const int targetPort) +{ + (void)targetIP; + int fd; + struct sockaddr_in serverAddr; + + // Create a socket + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + LOG_ERROR("socket() fail\n"); + return -1; + } + int option = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { + close(fd); + LOG_ERROR("setsockopt() fail\n"); + return -1; + } + + struct linger so_linger; + so_linger.l_onoff = true; + so_linger.l_linger = 0; + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 0) { + close(fd); + LOG_ERROR("setsockopt() linger fail\n"); + return -1; + } + + // Set the protocol and port number + (void)memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr)); + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(targetPort); + + // Set the IP address + serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + // Connection + int index = 0; + const int maxConnTime = 8000; + do { + if (connect(fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == 0) { + break; + } + usleep(1000); // Delay 100000 us + LOG_ERROR("Connect error try again\n"); + } while (index++ < maxConnTime); + if (index >= maxConnTime) { + close(fd); + LOG_ERROR("Connect error\n"); + return -1; + } + SetBlockMode(fd, false); + return fd; +} + +int TcpBind(const int localPort) +{ + int lisentFd, ret; + struct sockaddr_in serverAddr; + + // Create a socket + if ((lisentFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + LOG_ERROR("create socket fail\n"); + return -1; + } + + int option = 1; + if (setsockopt(lisentFd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { + close(lisentFd); + LOG_ERROR("setsockopt fail\n"); + return -1; + } + + struct linger so_linger; + so_linger.l_onoff = true; + so_linger.l_linger = 0; + if (setsockopt(lisentFd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 0) { + close(lisentFd); + LOG_ERROR("setsockopt() linger fail\n"); + return -1; + } + + // Set the protocol and port number + (void)memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr)); + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(localPort); + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + uint32_t tryNum = 0; + LOG_DEBUG("bind socket ing...\n"); + do { + ret = bind(lisentFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); + usleep(1000); // 1000 microseconds, that is, 1 ms + tryNum++; + } while ((ret != 0) && (tryNum < 8000)); // 8000: indicates that the binding attempt is 8 seconds + if (ret != 0) { + close(lisentFd); + LOG_DEBUG("bind socket fail\n"); + return -1; + } + + if (listen(lisentFd, 5) != 0) { // core should queue for the corresponding socket5 + close(lisentFd); + LOG_DEBUG("listen socket fail\n"); + return -1; + } + SetBlockMode(lisentFd, false); + return lisentFd; +} + +int TcpAccept(char *ip, int listenFd, bool isBlock, bool needClose) +{ + (void)ip; + int32_t ret; + + struct sockaddr_in clientAddr; + unsigned int len = sizeof(struct sockaddr_in); + int fd = -1; + uint32_t tryNum = 0; + LOG_DEBUG("tcp Accept ing...\n"); + do { + fd = accept(listenFd, (struct sockaddr *)&clientAddr, &len); + tryNum++; + usleep(1000); // 1000 microseconds, that is, 1 ms + // 10000: indicates that the system attempts to listen on the system for 10 seconds + } while ((fd == -1) && (tryNum < 10000)); + if (fd == -1) { + LOG_DEBUG("TCP accept fail\n"); + return -1; + } + + // Whether to block the interface + ret = SetBlockMode(fd, isBlock); + if (ret != 0) { + close(listenFd); + close(fd); + LOG_DEBUG("SetBlockMode ERROR"); + } + // Disable listenFd + if (needClose) { + close(listenFd); + } + + struct linger so_linger; + so_linger.l_onoff = 1; + so_linger.l_linger = 1; + setsockopt(fd,SOL_SOCKET,SO_LINGER, &so_linger,sizeof(so_linger)); + + LOG_DEBUG("accept a fd:%d\n", fd); + return fd; +} + +/* Disable the specified socket */ +void TcpClose(int sd) +{ + close(sd); +} + +int32_t TcpFrameWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + int32_t ret; + uint8_t *newBuf = NULL; + const void *sendBuf = buf; + uint32_t sendLen = len; + HLT_FrameHandle *frameHandle = GetFrameHandle(); + + if (frameHandle->frameCallBack != NULL && frameHandle->pointType == POINT_SEND) { + newBuf = GetNewBuf(buf, len, &sendLen); + if (sendLen == 0) { // sendLen value changes and becomes 0, the value is IO_BUSY + *writeLen = 0; + return BSL_SUCCESS; + } + if (newBuf != NULL) { + sendBuf = (void *)newBuf; + } + } + ret = BSL_UIO_TcpMethod()->write(uio, sendBuf, sendLen, writeLen); + if (sendLen != len && *writeLen != 0) { + *writeLen = len; + } + FreeNewBuf(newBuf); + return ret; +} + +int32_t TcpFrameRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + int ret; + ret = BSL_UIO_TcpMethod()->read(uio, buf, len, readLen); + if (ret != BSL_SUCCESS) { + return ret; + } + + uint8_t *newBuf = NULL; + uint32_t packLen = *readLen; + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->frameCallBack != NULL && frameHandle->pointType == POINT_RECV) { + newBuf = GetNewBuf(buf, len, &packLen); + if (packLen == 0) { // packLen changes and becomes 0, the value is IO_BUSY + *readLen = 0; + return BSL_SUCCESS; + } + if (newBuf != NULL) { + if (memcpy_s(buf, len, (uint8_t *)newBuf, packLen) != EOK) { + FreeNewBuf(newBuf); + return BSL_UIO_IO_EXCEPTION; + } + *readLen = packLen; + } + FreeNewBuf(newBuf); + } + return BSL_SUCCESS; +} + +int32_t SelectTcpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->method.write != NULL) { + return frameHandle->method.write(uio, buf, len, writeLen); + } + return TcpFrameWrite(uio, buf, len, writeLen); +} + +int32_t SelectTcpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + HLT_FrameHandle *frameHandle = GetFrameHandle(); + if (frameHandle->method.read != NULL) { + return frameHandle->method.read(uio, buf, len, readLen); + } + return TcpFrameRead(uio, buf, len, readLen); +} + +static BSL_UIO_Method g_TcpUioMethodDefault; + +/* Provide the default Linux implementation method */ +void *TcpGetDefaultMethod(void) +{ + const BSL_UIO_Method *ori = BSL_UIO_TcpMethod(); + memcpy(&g_TcpUioMethodDefault, ori, sizeof(g_TcpUioMethodDefault)); + g_TcpUioMethodDefault.write = SelectTcpWrite; + g_TcpUioMethodDefault.read = SelectTcpRead; + return &g_TcpUioMethodDefault; +} diff --git a/testcode/output/.gitignore b/testcode/output/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/testcode/script/all_mini_test.sh b/testcode/script/all_mini_test.sh new file mode 100644 index 00000000..ed37a34c --- /dev/null +++ b/testcode/script/all_mini_test.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# 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. +# Build different miniaturized targets and perform basic functional testing. + +set -eu + +PARAM_LIST=$@ + +ENABLE_C="off" +ASM_TYPE="" + +parse_option() +{ + for i in $PARAM_LIST + do + case "${i}" in + "c") + ENABLE_C="on" + ;; + "armv8") + ASM_TYPE=$i + ;; + *) + echo "Wrong parameter: $i" + exit 1 + ;; + esac + done +} + +test_bsl() +{ + bash mini_build_test.sh no-crypto no-tls enable=err test=err + bash mini_build_test.sh no-crypto no-tls enable=init + bash mini_build_test.sh no-crypto no-tls enable=list test=list + bash mini_build_test.sh no-crypto no-tls enable=log test=log + bash mini_build_test.sh no-crypto no-tls enable=sal test=sal + bash mini_build_test.sh no-crypto no-tls enable=sal_mem test=sal_mem + bash mini_build_test.sh no-crypto no-tls enable=sal_thread test=sal_thread + bash mini_build_test.sh no-crypto no-tls enable=sal_net test=sal_net + bash mini_build_test.sh no-crypto no-tls enable=sal_lock test=sal_lock + bash mini_build_test.sh no-crypto no-tls enable=sal_time test=sal_time + bash mini_build_test.sh no-crypto no-tls enable=sal_file test=sal_file + bash mini_build_test.sh no-crypto no-tls enable=sal_str test=sal_str + bash mini_build_test.sh no-crypto no-tls enable=tlv test=tlv + bash mini_build_test.sh no-crypto no-tls enable=uio_buffer + bash mini_build_test.sh no-crypto no-tls enable=uio_sctp + bash mini_build_test.sh no-crypto no-tls enable=uio_tcp + bash mini_build_test.sh no-crypto no-tls enable=uio test=uio + bash mini_build_test.sh no-crypto no-tls enable=usrdata +} + +test_md() +{ + bash mini_build_test.sh no-tls enable=sha1,eal test=sha1 + bash mini_build_test.sh no-tls enable=sha2,eal test=sha2 + bash mini_build_test.sh no-tls enable=sha224,eal test=sha224 + bash mini_build_test.sh no-tls enable=sha256,eal test=sha256 + bash mini_build_test.sh no-tls enable=sha384,eal test=sha384 + bash mini_build_test.sh no-tls enable=sha512,eal test=sha512 + bash mini_build_test.sh no-tls enable=sha3,eal test=sha3 + bash mini_build_test.sh no-tls enable=sm3,eal test=sm3 + bash mini_build_test.sh no-tls enable=md5,eal test=md5 +} + +test_mac() +{ + bash mini_build_test.sh no-tls enable=hmac,sha1,eal test=hmac + bash mini_build_test.sh no-tls enable=hmac,sha2,eal test=hmac + bash mini_build_test.sh no-tls enable=hmac,sha3,eal test=hmac + bash mini_build_test.sh no-tls enable=hmac,md5,eal test=hmac +} + +test_kdf() +{ + bash mini_build_test.sh no-tls enable=scrypt,eal test=scrypt + bash mini_build_test.sh no-tls enable=hkdf,sha2,eal test=hkdf + bash mini_build_test.sh no-tls enable=pbkdf2,sha2,eal test=pbkdf2 + bash mini_build_test.sh no-tls enable=kdftls12,sha2,eal test=kdftls12 +} + +test_cipher() +{ + bash mini_build_test.sh no-tls enable=aes,cbc,eal test=aes + bash mini_build_test.sh no-tls enable=aes,ctr,eal test=aes + bash mini_build_test.sh no-tls enable=aes,ccm,eal test=aes + bash mini_build_test.sh no-tls enable=aes,gcm,eal test=aes + bash mini_build_test.sh no-tls enable=aes,cfb,eal test=aes + bash mini_build_test.sh no-tls enable=aes,ofb,eal test=aes + + bash mini_build_test.sh no-tls enable=sm4,xts,eal test=sm4 + bash mini_build_test.sh no-tls enable=sm4,cbc,eal test=sm4 + bash mini_build_test.sh no-tls enable=sm4,ctr,eal test=sm4 + bash mini_build_test.sh no-tls enable=sm4,gcm,eal test=sm4 + bash mini_build_test.sh no-tls enable=sm4,cfb,eal test=sm4 + bash mini_build_test.sh no-tls enable=sm4,ofb,eal test=sm4 + + bash mini_build_test.sh no-tls enable=chacha20,eal test=chacha20 +} + +test_pkey() +{ + bash mini_build_test.sh no-tls enable=rsa,sha1,sha2,eal,drbg,entropy test=rsa + + bash mini_build_test.sh no-tls enable=dsa,sha2,eal,drbg,entropy test=dsa + + bash mini_build_test.sh no-tls enable=dh,sha2,eal,drbg,entropy test=dh + + bash mini_build_test.sh no-tls enable=ecdh,sha2,eal,drbg,entropy test=ecdh + + bash mini_build_test.sh no-tls enable=ecdsa,sha2,eal,drbg,entropy test=ecdsa + + bash mini_build_test.sh no-tls enable=x25519,sha2,eal,drbg,entropy test=x25519 + bash mini_build_test.sh no-tls enable=ed25519,eal,drbg,entropy test=ed25519 # ed25519 depends on sha512 by default. + + # sm2 depends on sm3 by default. + bash mini_build_test.sh no-tls enable=sm2_crypt,eal,drbg,entropy test=sm2_crypt + bash mini_build_test.sh no-tls enable=sm2_exch,eal,drbg,entropy test=sm2_exch + bash mini_build_test.sh no-tls enable=sm2_sign,eal,drbg,entropy test=sm2_sign +} + +test_drbg() +{ + bash mini_build_test.sh no-tls enable=entropy,drbg_hmac,sha256,eal test=entropy + bash mini_build_test.sh no-tls enable=drbg_ctr,eal test=drbg_ctr + bash mini_build_test.sh no-tls enable=drbg_hash,eal,sha2 test=drbg_hash + bash mini_build_test.sh no-tls enable=drbg_hmac,eal,sha2 test=drbg_hmac +} + +test_bn() +{ + bash mini_build_test.sh no-tls enable=bn test=bn +} + +test_asm_armv8() +{ + bash mini_build_test.sh no-tls enable=sm3,eal armv8 test=sm3 + + bash mini_build_test.sh no-tls enable=aes,gcm,eal test=aes armv8 + + bash mini_build_test.sh no-tls enable=sm4,cbc,eal test=sm4 armv8 + bash mini_build_test.sh no-tls enable=sm4,xts,eal test=sm4 armv8 + bash mini_build_test.sh no-tls enable=sm4,ctr,eal test=sm4 armv8 + bash mini_build_test.sh no-tls enable=sm4,gcm,eal test=sm4 armv8 + + bash mini_build_test.sh no-tls enable=sm2_crypt,eal,drbg,entropy test=sm2_crypt armv8 + bash mini_build_test.sh no-tls enable=sm2_exch,eal,drbg,entropy test=sm2_exch armv8 + bash mini_build_test.sh no-tls enable=sm2_sign,eal,drbg,entropy test=sm2_sign armv8 +} + +parse_option + +if [ "${ENABLE_C}" = "on" ]; then + test_bsl + test_md + test_mac + test_kdf + test_cipher + test_pkey + test_drbg + test_bn +fi + +case "${ASM_TYPE}" in + "armv8") + test_asm_armv8 + ;; + *) + ;; +esac diff --git a/testcode/script/build_hitls.sh b/testcode/script/build_hitls.sh new file mode 100644 index 00000000..92464b34 --- /dev/null +++ b/testcode/script/build_hitls.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +# 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. +set -e +cd ../../ +HITLS_ROOT_DIR=`pwd` + +hitls_compile_option=() + +paramList=$@ +paramNum=$# +add_options="" +del_options="" +get_arch=`arch` + +LIB_TYPE="static" +enable_sctp="--enable-sctp" +BITS=64 + +clean() +{ + rm -rf ${HITLS_ROOT_DIR}/build + mkdir ${HITLS_ROOT_DIR}/build +} + +down_depend_code() +{ + if [ ! -d "${HITLS_ROOT_DIR}/platform" ]; then + cd ${HITLS_ROOT_DIR} + mkdir platform + fi + + if [ ! -d "${HITLS_ROOT_DIR}/platform/Secure_C" ]; then + cd ${HITLS_ROOT_DIR}/platform + git clone https://gitee.com/openeuler/libboundscheck.git Secure_C + fi +} + +build_depend_code() +{ + if [ ! -d "${HITLS_ROOT_DIR}/platform/Secure_C/lib" ]; then + mkdir -p ${HITLS_ROOT_DIR}/platform/Secure_C/lib + cd ${HITLS_ROOT_DIR}/platform/Secure_C + make -j + fi +} + +build_hitls_code() +{ + bsl_features="err hash init list log sal sal_mem sal_thread sal_lock sal_time sal_file sal_net sal_str tlv \ + uio_plt uio_buffer uio_sctp uio_tcp usrdata asn1 obj base64 pem" + + # Compile openHiTLS + cd ${HITLS_ROOT_DIR}/build + add_options="${add_options} -DHITLS_EAL_INIT_OPTS=1 -DHITLS_CRYPTO_ASM_CHECK" # Get CPU capability + python3 ../configure.py --enable ${bsl_features} hitls_crypto hitls_tls hitls_x509 --bits=$BITS --system=linux ${enable_sctp} + if [[ $get_arch = "x86_64" ]]; then + echo "Compile: env=x86_64, c, little endian, 64bits" + python3 ../configure.py --lib_type ${LIB_TYPE} --asm_type x8664 --add_options="$add_options" --del_options="$del_options" ${enable_sctp} + elif [[ $get_arch = "armv8_be" ]]; then + echo "Compile: env=armv8, asm + c, big endian, 64bits" + python3 ../configure.py --lib_type ${LIB_TYPE} --endian big --asm_type armv8 --add_options="$add_options" --del_options="$del_options" ${enable_sctp} + elif [[ $get_arch = "armv8_le" ]]; then + echo "Compile: env=armv8, asm + c, little endian, 64bits" + python3 ../configure.py --lib_type ${LIB_TYPE} --asm_type armv8 --add_options="$add_options" --del_options="$del_options" ${enable_sctp} + else + echo "Compile: env=$get_arch, c, little endian, 64bits" + python3 ../configure.py --lib_type ${LIB_TYPE} --add_options="$add_options" --del_options="$del_options" ${enable_sctp} + fi + cmake .. + make -j +} + +parse_option() +{ + for i in $paramList + do + key=${i%%=*} + value=${i#*=} + case "${key}" in + "gcov") + add_options="${add_options} -fno-omit-frame-pointer -fprofile-arcs -ftest-coverage -fdump-rtl-expand" + ;; + "debug") + add_options="${add_options} -O0 -g3 -gdwarf-2" + del_options="${del_options} -O2 -D_FORTIFY_SOURCE=2" + ;; + "asan") + add_options="${add_options} -fsanitize=address -fsanitize-address-use-after-scope -O0 -g3 -fno-stack-protector -fno-omit-frame-pointer -fgnu89-inline" + del_options="${del_options} -fstack-protector-strong -fomit-frame-pointer -O2 -D_FORTIFY_SOURCE=2" + ;; + "armv8_be") + get_arch="armv8_be" + ;; + "armv8_le") + get_arch="armv8_le" + ;; + "pure_c") + get_arch="C" + ;; + "no_sctp") + enable_sctp="" + ;; + "bits") + BITS="$value" + ;; + "shared") + LIB_TYPE="shared" + ;; + "help") + printf "%-50s %-30s\n" "Build openHiTLS Code" "sh build_hitls.sh" + printf "%-50s %-30s\n" "Build openHiTLS Code With Gcov" "sh build_hitls.sh gcov" + printf "%-50s %-30s\n" "Build openHiTLS Code With Debug" "sh build_hitls.sh debug" + printf "%-50s %-30s\n" "Build openHiTLS Code With Asan" "sh build_hitls.sh asan" + exit 0 + ;; + *) + echo "${i} option is not recognized, Please run get supported options." + exit -1 + ;; + esac + done +} + +clean +parse_option +down_depend_code +build_depend_code +build_hitls_code diff --git a/testcode/script/build_sdv.sh b/testcode/script/build_sdv.sh new file mode 100644 index 00000000..b841f85c --- /dev/null +++ b/testcode/script/build_sdv.sh @@ -0,0 +1,234 @@ +#!/bin/bash + +# 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. +set -e + +usage() +{ + printf "\n" + printf "%-05s %-30s\n" "* Script :" "${BASH_SOURCE[0]}" + printf "%-50s %-30s\n" "* Usage Option :" "" + printf "%-50s %-30s\n" "* --help|-h : Help information." "" + printf "%-50s %-30s\n" "* tls-debug : Enable the debug mode." "bash ${BASH_SOURCE[0]} tls-debug" + printf "%-50s %-30s\n" "* no-crypto : Custom crypto testcase." "bash ${BASH_SOURCE[0]} no-crypto" + printf "%-50s %-30s\n" "* no-bsl : Custom bsl testcase." "bash ${BASH_SOURCE[0]} no-bsl" + printf "%-50s %-30s\n" "* no-tls : Custom tls testcase." "bash ${BASH_SOURCE[0]} no-tls" + printf "%-50s %-30s\n" "* no-x509 : Custom x509 testcase." "bash ${BASH_SOURCE[0]} no-x509" + printf "%-50s %-30s\n" "* verbose : Show detailse." "bash ${BASH_SOURCE[0]} verbose" + printf "%-50s %-30s\n" "* gcov : Enable the coverage capability." "bash ${BASH_SOURCE[0]} gcov" + printf "%-50s %-30s\n" "* asan : Enabling the ASAN capability." "bash ${BASH_SOURCE[0]} asan" + printf "%-50s %-30s\n" "* big-endian : Specify the platform endianness." "bash ${BASH_SOURCE[0]} big-endian" + printf "%-50s %-30s\n\n" "* run-tests : Creating a custom test suite." "bash ${BASH_SOURCE[0]} run-tests=xxx1|xxx2|xxx3" +} + +export_env() +{ + HITLS_ROOT_DIR=${HITLS_ROOT_DIR:=$(cd $(dirname ${BASH_SOURCE[0]})/../..;pwd)} + LOCAL_ARCH=${LOCAL_ARCH:=`arch`} + ENABLE_GCOV=${ENABLE_GCOV:=OFF} + ENABLE_ASAN=${ENABLE_ASAN:=OFF} + ENABLE_PRINT=${ENABLE_PRINT:=ON} + ENABLE_FAIL_REPEAT=${ENABLE_FAIL_REPEAT:=OFF} + CUSTOM_CFLAGS=${CUSTOM_CFLAGS:=''} + ENABLE_TLS=${ENABLE_TLS:=ON} + BIG_ENDIAN=${BIG_ENDIAN:=OFF} + ENABLE_CRYPTO=${ENABLE_CRYPTO:=ON} + ENABLE_BSL=${ENABLE_BSL:=ON} + ENABLE_X509=${ENABLE_X509:=ON} + ENABLE_UIO_SCTP=${ENABLE_UIO_SCTP:=ON} + ENABLE_VERBOSE=${ENABLE_VERBOSE:=''} + RUN_TESTS=${RUN_TESTS:=''} + DEBUG=${DEBUG:=ON} + if [ -f ${HITLS_ROOT_DIR}/build/macro.txt ];then + CUSTOM_CFLAGS=$(cat ${HITLS_ROOT_DIR}/build/macro.txt) + fi + if [[ ! -e "${HITLS_ROOT_DIR}/testcode/output/log" ]]; then + mkdir ${HITLS_ROOT_DIR}/testcode/output/log + fi +} + +down_depend_code() +{ + if [ ! -d "${HITLS_ROOT_DIR}/platform/Secure_C/lib" ]; then + cd ${HITLS_ROOT_DIR}/platform/Secure_C + make -j + fi +} + +find_test_suite() +{ + if [[ ${ENABLE_CRYPTO} == "ON" ]]; then + crypto_testsuite=$(find ${HITLS_ROOT_DIR}/testcode/sdv/testcase/crypto -name "*.data" | sed -e "s/.data//" | tr -s "\n" " ") + fi + if [[ ${ENABLE_BSL} == "ON" ]]; then + bsl_testsuite=$(find ${HITLS_ROOT_DIR}/testcode/sdv/testcase/bsl -name "*.data" | sed -e "s/.data//" | tr -s "\n" " ") + fi + if [[ ${ENABLE_X509} == "ON" ]]; then + x509_testsuite=$(find ${HITLS_ROOT_DIR}/testcode/sdv/testcase/x509 -name "*.data" | sed -e "s/.data//" | tr -s "\n" " ") + fi + if [[ ${ENABLE_TLS} == "ON" ]]; then + proto_testsuite=$(find ${HITLS_ROOT_DIR}/testcode/sdv/testcase/tls -name "*.data" | sed -e "s/.data//" | tr -s "\n" " ") + fi + RUN_TEST_SUITES="${crypto_testsuite}${bsl_testsuite}${x509_testsuite}${proto_testsuite}" +} + +build_generate() +{ + cd ${HITLS_ROOT_DIR}/testcode && rm -rf ./build && mkdir build && cd build + cmake -DENABLE_GCOV=${ENABLE_GCOV} -DENABLE_ASAN=${ENABLE_ASAN} \ + -DCUSTOM_CFLAGS="${CUSTOM_CFLAGS}" -DDEBUG=${DEBUG} -DENABLE_UIO_SCTP=${ENABLE_UIO_SCTP} \ + -DGEN_TEST_FILES=${TEST_SUITE} -DENABLE_TLS=${ENABLE_TLS} \ + -DENABLE_CRYPTO=${ENABLE_CRYPTO} -DENABLE_X509=${ENABLE_X509} -DTLS_DEBUG=${TLS_DEBUG} \ + -DOS_BIG_ENDIAN=${BIG_ENDIAN} -DPRINT_TO_TERMINAL=${ENABLE_PRINT} -DENABLE_FAIL_REPEAT=${ENABLE_FAIL_REPEAT} .. + make GEN_TESTCASE ${ENABLE_VERBOSE} -j +} + +build_test_suite() +{ + procNum=$(grep -c ^processor /proc/cpuinfo) + echo "procNum = $procNum" + tmpPipe="$$.fifo" + mkfifo $tmpPipe + exec 7<>$tmpPipe + rm -f $tmpPipe + for((i=0; i<$procNum; i++)); do + echo + done >&7 + retPipe=$tmpPipe.ret + mkfifo $retPipe + exec 8<>$retPipe + rm -f $retPipe + echo "0" >&8 + [[ -n ${CASES} ]] && RUN_TEST_SUITES=${CASES} + cd ${HITLS_ROOT_DIR}/testcode && rm -rf build && mkdir build && cd build + for TEST_SUITE in ${RUN_TEST_SUITES} + do + { + read -u7 + local tmp_dir=${TEST_SUITE##*/} + rm -rf ./${tmp_dir} && mkdir ${tmp_dir} && cd ${tmp_dir} + cmake -DENABLE_GCOV=${ENABLE_GCOV} -DENABLE_ASAN=${ENABLE_ASAN} \ + -DCUSTOM_CFLAGS="${CUSTOM_CFLAGS}" -DDEBUG=${DEBUG} -DENABLE_UIO_SCTP=${ENABLE_UIO_SCTP} \ + -DGEN_TEST_FILES=${TEST_SUITE} -DTESTFILE=${tmp_dir} \ + -DENABLE_CRYPTO=${ENABLE_CRYPTO} -DENABLE_X509=${ENABLE_X509} -DENABLE_TLS=${ENABLE_TLS} \ + -DTLS_DEBUG=${TLS_DEBUG} -DOS_BIG_ENDIAN=${BIG_ENDIAN} \ + -DPRINT_TO_TERMINAL=${ENABLE_PRINT} -DENABLE_FAIL_REPEAT=${ENABLE_FAIL_REPEAT} ../.. + make TESTCASE ${ENABLE_VERBOSE} -j || (read -u8 && echo "1" >&8) + echo >&7 + } & + done + wait + exec 7<&- + read -u8 ret + exec 8<&- +} + +process_custom_cases() +{ + if [[ -n "${RUN_TESTS}" ]];then + local tmp=($(echo "${RUN_TESTS}" | tr -s "|" " ")) + for i in ${!tmp[@]} + do + local suite=$(find ${HITLS_ROOT_DIR}/testcode/sdv -name "${tmp[i]}.data" | sed -e "s/.data//") + [[ -z "${suite}" ]] && echo "not found testsuite:${tmp[i]}" + [[ -n "${suite}" ]] && CASES="${suite} ${CASES}" + done + fi +} + +clean() +{ + rm -rf ${HITLS_ROOT_DIR}/testcode/output/log + rm -rf ${HITLS_ROOT_DIR}/testcode/output/test_suite* + rm -rf ${HITLS_ROOT_DIR}/testcode/output/asan.* + rm -rf ${HITLS_ROOT_DIR}/testcode/output/*.log + rm -rf ${HITLS_ROOT_DIR}/testcode/output/*.xml + rm -rf ${HITLS_ROOT_DIR}/testcode/output/gen_testcase + rm -rf ${HITLS_ROOT_DIR}/testcode/output/process + rm -rf ${HITLS_ROOT_DIR}/testcode/framework/tls/build + rm -rf ${HITLS_ROOT_DIR}/testcode/build + rm -rf ${HITLS_ROOT_DIR}/testcode/sdv/build + rm -rf ${HITLS_ROOT_DIR}/testcode/framework/process/build + rm -rf ${HITLS_ROOT_DIR}/testcode/framework/gen_test/build + mkdir ${HITLS_ROOT_DIR}/testcode/output/log +} + +options() +{ + while [[ -n $1 ]] + do + key=${1%%=*} + value=${1#*=} + case ${key} in + tls-debug) + TLS_DEBUG=ON + ;; + gcov) + ENABLE_GCOV=ON + ;; + asan) + ENABLE_ASAN=ON + ;; + no-print) + ENABLE_PRINT=OFF + ;; + no-crypto) + ENABLE_CRYPTO=OFF + ;; + no-x509) + ENABLE_X509=OFF + ;; + no-bsl) + ENABLE_BSL=OFF + ;; + no-tls) + ENABLE_TLS=OFF + ;; + no-sctp) + ENABLE_UIO_SCTP=OFF + ENABLE_TLS=OFF + ;; + verbose) + ENABLE_VERBOSE='VERBOSE=1' + ;; + fail-repeat) + ENABLE_FAIL_REPEAT=ON + ;; + run-tests) + RUN_TESTS=${value} + ;; + big-endian) + BIG_ENDIAN=ON + ;; + --help|-h) + usage + exit 0 + ;; + *) + usage + exit 1 + ;; + esac + shift + done +} + +export_env +options "$@" +clean +down_depend_code +find_test_suite +process_custom_cases +build_generate +build_test_suite diff --git a/testcode/script/execute_sdv.sh b/testcode/script/execute_sdv.sh new file mode 100644 index 00000000..cbb390c0 --- /dev/null +++ b/testcode/script/execute_sdv.sh @@ -0,0 +1,239 @@ +#!/bin/bash + +# 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. +elapsed=0 + +cd ../../ +HITLS_ROOT_DIR=`pwd` + +paramList=$@ +paramNum=$# +is_concurrent=1 + +testsuite_array=() +testcase_array=() +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$(realpath ${HITLS_ROOT_DIR}/build):$(realpath ${HITLS_ROOT_DIR}/platform/Secure_C/lib) + +# Check whether an ASAN alarm is generated. +generate_asan_log() { + ASAN_LOG=$(find ../output -name "asan.log*") + if [ ! -z "$ASAN_LOG" ]; then + for i in $ASAN_LOG + do + if grep -q "ASan doesn't fully support makecontext/swapcontext" $i + then + line_count=$(wc -l < "$i") + if [ "$line_count" -eq 1 ]; then + echo "The ASAN log contains only ucontext warning content. Ignore it." + else + echo "ASAN ERROR. Exit with ucontext check failure." + exit 1 + fi + continue + else + echo "ASAN ERROR. Exit with failure." + exit 1 + fi + done + fi +} +# Run the specified test suites or test cases in the output directory. +run_test() { + cd ${HITLS_ROOT_DIR}/testcode/output + export ASAN_OPTIONS=detect_stack_use_after_return=1:strict_string_checks=1:detect_leaks=1:halt_on_error=0:log_path=asan.log + + echo "" + echo "Begin Test" + echo ".................................................." + start_time=$(date +%s) + + # Run the specified test suite. + if [ ${#testsuite_array[*]} -ne 0 ] && [ ${#testcase_array[*]} -eq 0 ];then + for i in ${testsuite_array[@]} + do + ./${i} NO_DETAIL + done + fi + + # Run the specified test case. + if [ ${#testcase_array[*]} -ne 0 ];then + num=0 + for i in ${testcase_array[@]} + do + ./${testsuite_array[num]} ${i} + let num+=1 + done + fi + + end_time=$(date +%s) + elapsed=$((end_time - start_time)) + + generate_asan_log +} + +gen_test_report() +{ + cd ${HITLS_ROOT_DIR}/testcode/output + ./gen_testcase GenReport + testcase_num=0 + pass_num=0 + skip_num=0 + while read line + do + array=(${line}) + last_index=$((${#array[@]}-1)) + if [ "${array[last_index]}" = "PASS" ]; then + let pass_num+=1 + elif [ "${array[last_index]}" = "SKIP" ]; then + let skip_num+=1 + fi + let testcase_num+=1 + done < result.log + fail_num=`expr $testcase_num - $pass_num - $skip_num` + SumTime=`echo "$elapsed 60" |awk '{printf("%.2f",$1/$2)}'` + echo "SumTime is ${SumTime} mintues TestCase Num is ${testcase_num} Pass is ${pass_num} Skip is ${skip_num} Fail is ${fail_num}" + if [ ${fail_num} -ne 0 ]; then + exit 1 + fi +} + +# Run all tests in the output directory. +run_all() { + start_time=$(date +%s) + echo "Test: $1" >> ${HITLS_ROOT_DIR}/testcode/output/time.txt + echo "Start: $(date)" >> ${HITLS_ROOT_DIR}/testcode/output/time.txt + + cd ${HITLS_ROOT_DIR}/testcode/output + SUITES=$(ls ./ | grep .datax | sed -e "s/.datax//") + export ASAN_OPTIONS=detect_stack_use_after_return=1:strict_string_checks=1:detect_leaks=1:halt_on_error=0:log_path=asan.log + + echo "" + echo "Begin Test" + echo ".................................................." + if [ $is_concurrent = 1 ]; then + mkfifo tmppipe + exec 5<>tmppipe + rm -f tmppipe + procNum=$(grep -c ^processor /proc/cpuinfo) + let procNum=$procNum+5 + echo "procNum = $procNum" + # procNum indicates the maximum number of concurrent processes. + for ((i=1;i<=$procNum;i++)); do + echo >&5 + done + retPipe=$tmpPipe.ret + mkfifo $retPipe + exec 8<>$retPipe + rm -f $retPipe + echo "0" >&8 + for i in $SUITES + do + # Run tests in parallel. + read -u5 + { + ./$i NO_DETAIL || (read -u8 && echo "1 $i" >&8) + echo >&5 + } & + done + wait + + exec 5>&- + exec 5<&- + read -u8 ret + exec 8<&- + if [ "$ret" != "0" ];then + echo "some case failed $ret" + gen_test_report + generate_asan_log + exit 1 + fi + else + for i in $SUITES + do + ./$i NO_DETAIL + done + fi + + end_time=$(date +%s) + echo "End: $(date)" >> time.txt + elapsed=$((end_time - start_time)) + eval "echo Elapsed time: $(date -ud "@$elapsed" +'$((%s/3600/24)) days %H hr %M min %S sec') >> time.txt" + + generate_asan_log +} + +parse_testsuite_testcase() +{ + cd ${HITLS_ROOT_DIR}/testcode/output + testsuite_name="test_suite" + if [[ "$1" == *$testsuite_name* ]]; then + if [ -f "$1" ]; then + testsuite_array[${#testsuite_array[*]}]=$i + return 1 + fi + return 0 + else + testsuite=`grep -l $1 *.c` + if [ "${testsuite}" = "" ]; then + return 0 + else + array=(${testsuite//./ }) + testsuite_array[${#testcase_array[*]}]="${array[0]}" + testcase_array[${#testcase_array[*]}]="$1" + return 1 + fi + fi +} + +parse_option() +{ + for i in $paramList + do + case "$i" in + "help") + printf "Note: Before Run , Please Fisrt Run " + printf "%-50s %-30s\n" "Run All Testsuites Of The Output" "sh ${BASH_SOURCE[0]}" + printf "%-50s %-30s\n" "Run The Specified Testsuite" "sh ${BASH_SOURCE[0]} test_suites_xxx test_suites_xxx" + printf "%-50s %-30s\n" "Run The Specified Testcase" "sh ${BASH_SOURCE[0]} UT_CRYPTO_xxx SDV_CRYPTO_xxx" + exit 0 + ;; + *) + parse_testsuite_testcase $i + if [ $? -eq 0 ]; then + echo "Not Find This Testsuite or Testcase : ${i}" + exit 1 + fi + ;; + esac + done +} + +clean() +{ + rm -rf ${HITLS_ROOT_DIR}/testcode/output/log/* + rm -rf ${HITLS_ROOT_DIR}/testcode/output/result.log + rm -rf ${HITLS_ROOT_DIR}/testcode/output/*.sock* + rm -rf ${HITLS_ROOT_DIR}/testcode/output/asan* +} + +clean +parse_option +if [ ${paramNum} -eq 0 ]; then + run_all +elif [ ${paramNum} -eq 1 ] && [ $is_concurrent = 0 ]; then + run_all +else + run_test +fi +gen_test_report diff --git a/testcode/script/mini_build_test.sh b/testcode/script/mini_build_test.sh new file mode 100644 index 00000000..8b49c19b --- /dev/null +++ b/testcode/script/mini_build_test.sh @@ -0,0 +1,418 @@ +#!/bin/bash + +# 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. +# Build different miniaturized targets and perform basic functional testing. + +set -eu + +PARAM_LIST=$@ + +CUR_DIR=`pwd` +HITLS_ROOT_DIR=`realpath $CUR_DIR/../../` +HITLS_BUILD_DIR=$HITLS_ROOT_DIR/build + +FEATURES=() +TEST_FEATURE="" +BUILD_HITLS="on" +SHOW_SIZE="on" # size libhitls_*.a +SHOW_MACRO="off" + +NO_CRYPTO="" +NO_TLS="" + +ARMV8="off" + +LIB_TYPE="static shared object" +DEBUG="off" +ADD_OPTIONS="" +DEL_OPTIONS="" + +declare -A feature_testfiles +declare -A testfile_testcases +feature_testfiles=( + # bsl + ["init"]="" + ["err"]="test_suite_sdv_err" + ["list"]="test_suite_sdv_list" + ["log"]="test_suite_sdv_log" + ["sal"]="test_suite_sdv_sal" + ["sal_mem"]="test_suite_sdv_sal" + ["sal_thread"]="test_suite_sdv_sal" + ["sal_lock"]="test_suite_sdv_sal" + ["sal_time"]="test_suite_sdv_sal_time" + ["sal_file"]="test_suite_sdv_sal_file" + ["sal_net"]="test_suite_sdv_sal_socket" + ["sal_str"]="test_suite_sdv_sal" + ["tlv"]="" + ["uio"]="test_suite_sdv_uio" + ["uio_buffer"]="" + ["uio_sctp"]="" + ["uio_tcp"]="" + ["usrdata"]="" + # eal + ["eal"]="" + # md + ["md5"]="test_suite_sdv_eal_md5" + ["sm3"]="test_suite_sdv_eal_sm3" + ["sha1"]="test_suite_sdv_eal_md_sha1" + ["sha2"]="test_suite_sdv_eal_md_sha2" + ["sha224"]="test_suite_sdv_eal_md_sha2" + ["sha256"]="test_suite_sdv_eal_md_sha2" + ["sha384"]="test_suite_sdv_eal_md_sha2" + ["sha512"]="test_suite_sdv_eal_md_sha2" + ["sha3"]="test_suite_sdv_eal_md_sha3" + ["md"]="test_suite_sdv_eal_md5 test_suite_sdv_eal_sm3 test_suite_sdv_eal_md_sha1 test_suite_sdv_eal_md_sha2 test_suite_sdv_eal_md_sha3" + # mac + ["mac"]="" + ["hmac"]="test_suite_sdv_eal_mac_hmac" + # kdf + ["scrypt"]="test_suite_sdv_eal_kdf_scrypt" + ["hkdf"]="test_suite_sdv_eal_kdf_hkdf" + ["pbkdf2"]="test_suite_sdv_eal_kdf_pbkdf2" + ["kdftls12"]="test_suite_sdv_eal_kdf_tls12" + ["kdf"]="test_suite_sdv_eal_kdf_scrypt test_suite_sdv_eal_kdf_hkdf test_suite_sdv_eal_kdf_pbkdf2 test_suite_sdv_eal_kdf_tls12" + # bn + ["bn"]="test_suite_sdv_bn" + # drbg + ["drbg_hash"]="test_suite_sdv_drbg" + ["drbg_hmac"]="test_suite_sdv_drbg" + ["drbg_ctr"]="test_suite_sdv_drbg" + ["drbg"]="test_suite_sdv_drbg" + ["entropy"]="test_suite_sdv_entropy" + # cipher + ["cbc"]="" + ["ctr"]="" + ["ccm"]="" + ["gcm"]="" + ["cfb"]="" + ["ofb"]="" + ["xts"]="" + ["chacha20"]="" + ["aes"]="test_suite_sdv_eal_aes_ccm test_suite_sdv_eal_aes_gcm test_suite_sdv_eal_aes" + ["sm4"]="test_suite_sdv_eal_sm4" + ["chacha20"]="test_suite_sdv_eal_chachapoly" + ["cipher"]="test_suite_sdv_eal_aes_ccm test_suite_sdv_eal_aes_gcm test_suite_sdv_eal_aes test_suite_sdv_eal_sm4 test_suite_sdv_eal_chachapoly" + # pkey + ["rsa"]="test_suite_sdv_eal_rsa_sign_verify test_suite_sdv_eal_rsa_encrypt_decrypt" + ["dh"]="test_suite_sdv_eal_dh" + ["dsa"]="test_suite_sdv_eal_dsa" + ["ecdsa"]="test_suite_sdv_eal_ecdsa" + ["ecdh"]="test_suite_sdv_eal_ecdh" + ["curve25519"]="test_suite_sdv_eal_curve25519" + ["x25519"]="test_suite_sdv_eal_curve25519" + ["ed25519"]="test_suite_sdv_eal_curve25519" + ["sm2"]="test_suite_sdv_eal_sm2_exchange test_suite_sdv_eal_sm2_sign test_suite_sdv_eal_sm2_crypt" + ["sm2_exch"]="test_suite_sdv_eal_sm2_exchange" + ["sm2_sign"]="test_suite_sdv_eal_sm2_sign" + ["sm2_crypt"]="test_suite_sdv_eal_sm2_crypt" +) + +testfile_testcases=( + # bsl + ["test_suite_sdv_err"]="" + ["test_suite_sdv_list"]="" + ["test_suite_sdv_log"]="" + ["test_suite_sdv_sal"]="" + ["test_suite_sdv_sal_time"]="" + ["test_suite_sdv_sal_file"]="" + ["test_suite_sdv_sal_socket"]="" + ["test_suite_sdv_sal"]="" + ["test_suite_sdv_uio"]="" + # md + ["test_suite_sdv_eal_md_sha1"]="SDV_CRYPT_EAL_SHA1_FUN_TC001" + ["test_suite_sdv_eal_md_sha2"]="SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003" + ["test_suite_sdv_eal_md_sha3"]="SDV_CRYPT_EAL_SHA3_FUNC_TC003" + ["test_suite_sdv_eal_md5"]="SDV_CRYPTO_MD5_FUNC_TC002" + ["test_suite_sdv_eal_sm3"]="SDV_CRYPT_EAL_SM3_FUNC_TC002" + # mac + ["test_suite_sdv_eal_mac_hmac"]="SDV_CRYPT_EAL_HMAC_FUN_TC001" + # kdf + ["test_suite_sdv_eal_kdf_pbkdf2"]="SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001" + ["test_suite_sdv_eal_kdf_hkdf"]="SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001" + ["test_suite_sdv_eal_kdf_scrypt"]="SDV_CRYPT_EAL_KDF_SCRYPT_FUN_TC001" + ["test_suite_sdv_eal_kdf_tls12"]="SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001" + # cipher + ["test_suite_sdv_eal_aes"]="SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001 SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002 SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004 SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006" + ["test_suite_sdv_eal_aes_ccm"]="SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001 SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002" + ["test_suite_sdv_eal_aes_gcm"]="SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002" + ["test_suite_sdv_eal_sm4"]="SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004" + ["test_suite_sdv_eal_chachapoly"]="SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001" + # bn + ["test_suite_sdv_bn"]="" + # drbg + ["test_suite_sdv_entropy"]="" + ["test_suite_sdv_drbg"]="SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001 SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 SDV_CRYPT_EAL_DRBG_BYTES_FUNC_TC001" + # pkey + ["test_suite_sdv_eal_rsa_sign_verify"]="SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002 SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001 SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001 SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002 SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001 SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC001 SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PSS_FUNC_TC001 SDV_CRYPTO_RSA_BLINDING_FUNC_TC001 SDV_CRYPTO_RSA_BLINDING_FUNC_TC002" + ["test_suite_sdv_eal_rsa_encrypt_decrypt"]="SDV_CRYPTO_RSA_CRYPT_FUNC_TC001 SDV_CRYPTO_RSA_CRYPT_FUNC_TC003" + ["test_suite_sdv_eal_dh"]="SDV_CRYPTO_DH_FUNC_TC001 SDV_CRYPTO_DH_FUNC_TC002 SDV_CRYPTO_DH_FUNC_TC003" + ["test_suite_sdv_eal_dsa"]="SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001" + ["test_suite_sdv_eal_ecdsa"]="SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002" + ["test_suite_sdv_eal_ecdh"]="SDV_CRYPTO_ECDH_EXCH_FUNC_TC001" + ["test_suite_sdv_eal_curve25519"]="SDV_CRYPTO_X25519_EXCH_FUNC_TC001 SDV_CRYPTO_X25519_EXCH_FUNC_TC002 SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001" + ["test_suite_sdv_eal_sm2_exchange"]="SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001 SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003" + ["test_suite_sdv_eal_sm2_sign"]="SDV_CRYPTO_SM2_SIGN_FUNC_TC001 SDV_CRYPTO_SM2_VERIFY_FUNC_TC001 SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC001" + ["test_suite_sdv_eal_sm2_crypt"]="SDV_CRYPTO_SM2_ENC_FUNC_TC001 SDV_CRYPTO_SM2_DEC_FUNC_TC001 SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC001" +) + +print_usage() { + printf "Usage: $0\n" + printf " %-10s %s\n" "help" "Print this help." + printf " %-10s %s\n" "no-build" "Do not build openHiTLS." + printf " %-10s %s\n" "no-size" "Do not list the detail of the object files in static libraries." + printf " %-10s %s\n" "macro" "Obtains the macro of the openHiTLS." + printf " %-10s %s\n" "armv8" "Specify the type of assembly to build." + printf " %-10s %s\n" "debug" "Build openHiTLS with debug flags." + printf " %-10s %s\n" "asan" "Build openHiTLS with asan flags." + printf " %-10s %s\n" "enable=a;b;c" "Specify the features of the build." + printf " %-10s %s\n" "test=a" "Specify the feature for which the test is to be performed." + printf "\nexample:\n" + printf " %-50s %-30s\n" "sh mini_build_test.sh enable=sha1,sha2 test=sha1" "Build sha1 and sha2 and test sha1." + printf " %-50s %-30s\n" "sh mini_build_test.sh enable=sha1,sm3 armv8 " "Build sha1 and sm3 and enable armv8 assembly." +} + +parse_enable_features() +{ + features=(${1//,/ }) + for i in ${features[@]} + do + find=0 + for feature in ${!feature_testfiles[*]} + do + if [ "$i" = "$feature" ]; then + FEATURES[${#FEATURES[*]}]=$i + find=1 + break + fi + done + if [ $find -ne 1 ]; then + echo "Wrong feature: $i" + exit 1 + fi + done +} + +parse_option() +{ + for i in $PARAM_LIST + do + key=${i%%=*} + value=${i#*=} + case "${key}" in + "help") + print_usage + ;; + "no-build") + BUILD_HITLS="off" + ;; + "no-size") + SHOW_SIZE="off" + ;; + "no-tls") + NO_TLS="no-tls" + ;; + "no-crypto") + NO_CRYPTO="no-crypto" + ;; + "macro") + SHOW_MACRO="on" + ADD_OPTIONS="${ADD_OPTIONS} -E -dM" + LIB_TYPE="static" + ;; + "armv8") + ARMV8="on" + ;; + "debug") + ADD_OPTIONS="$ADD_OPTIONS -O0 -g3 -gdwarf-2" + DEL_OPTIONS="$DEL_OPTIONS -O2 -D_FORTIFY_SOURCE=2" + ;; + "asan") + ADD_OPTIONS="$ADD_OPTIONS -fsanitize=address -fsanitize-address-use-after-scope -O0 -g3 -fno-stack-protector -fno-omit-frame-pointer -fgnu89-inline" + DEL_OPTIONS="$DEL_OPTIONS -fstack-protector-strong -fomit-frame-pointer -O2 -D_FORTIFY_SOURCE=2" + ;; + "enable") + parse_enable_features "$value" + ;; + "test") + LIB_TYPE="static" + TEST_FEATURE=$value + ;; + *) + echo "Wrong parameter: $key" + exit 1 + ;; + esac + done +} + +show_size() +{ + cd $HITLS_BUILD_DIR + libs=`find -name '*.a'` + + array=(${libs//\n/ }) + for lib in ${array[@]} + do + ls -lh ${lib} + size ${lib} | grep -v "0 0 0 0 0" + echo -e "" + done +} + +show_macro() +{ + cd ${HITLS_BUILD_DIR} + grep "#define HITLS_" libhitls_bsl.a | grep -v OPENHITLS_VERSION_S |awk '{print $2}' > macro_new.txt + sort macro_new.txt | uniq >unique_macro.txt + cat unique_macro.txt +} + +mini_config() +{ + enables="" + bits=0 + system="" + + for feature in ${FEATURES[@]} + do + enables="$enables $feature" + case $feature in + "sal"|"sal_mem"|"sal_thread"|"sal_lock"|"sal_time"|"sal_file"|"sal_net"|"sal_str"|\ + "uio"|"uio_tcp"|"uio_sctp") + # uio_tcp|uio depends on sal_net. To enable sal_net, you need to specify the system. + system="linux" + ;; + "bn"|\ + "rsa"|"dsa"|"dh"|"ecdsa"|"ecdh"|"curve25519"|"x25519"|\ + "ed25519"|"sm2"|"sm2_exch"|"sm2_sign"|"sm2_crypt") + # To enable bn, you need to specify the number of platform bits. + bits=64 + ;; + esac + done + + echo + echo "python3 configure.py --lib_type $LIB_TYPE --enable $enables" + python3 $HITLS_ROOT_DIR/configure.py --lib_type $LIB_TYPE --enable $enables + + if [ "$ARMV8" == "on" ]; then + echo "python3 configure.py --asm_type armv8" + python3 $HITLS_ROOT_DIR/configure.py --asm_type armv8 + fi + + if [ "$system" != "" ]; then + echo "python3 configure.py --linux $system" + python3 $HITLS_ROOT_DIR/configure.py --system $system + fi + + if [ $bits -ne 0 ]; then + echo "python3 configure.py --bits $bits" + python3 $HITLS_ROOT_DIR/configure.py --bits $bits + fi + + if [ "$ADD_OPTIONS" != "" -o "$DEL_OPTIONS" != "" ]; then + echo "python3 configure.py --add_options=\"$ADD_OPTIONS\" --del_options=\"$DEL_OPTIONS\"" + python3 $HITLS_ROOT_DIR/configure.py --add_options="$ADD_OPTIONS" --del_options="$DEL_OPTIONS" + fi +} + +check_cmd_res() +{ + if [ "$?" -ne "0" ]; then + echo "Error: $1" + exit 1 + fi +} + +build_hitls() +{ + # cleanup + cd $HITLS_ROOT_DIR + rm -rf $HITLS_BUILD_DIR + mkdir $HITLS_BUILD_DIR + cd $HITLS_BUILD_DIR + + # config + mini_config + check_cmd_res "configure.py" + + # cmake .. + cmake .. > cmake.txt + check_cmd_res "cmake .." + + # make + make -j 32 > make.txt + check_cmd_res "make -j" +} + +exe_file_testcases() +{ + cd $HITLS_ROOT_DIR/testcode/output + + test_file=$1 + # Get test cases according to test file. + test_cases=${testfile_testcases[$test_file]} + + if [ "$test_cases" = "" ]; then + # Execute all test cases when no test case is specified. + ./$test_file NO_DETAIL + else + array=(${test_cases// / }) + for case in ${array[@]} + do + echo "test case: $case" + ./$test_file $case NO_DETAIL + done + fi +} + +test_feature() +{ + feature=$1 + + # Get test files according to feature. + if [ "${feature_testfiles[$feature]}" == "" ]; then + return 0 + fi + files=${feature_testfiles[$feature]} + + cd $HITLS_ROOT_DIR/testcode/script + files2=`echo ${files// /|}` # Separate test files with vertical bars (|). + sh build_sdv.sh run-tests=$files2 $NO_TLS $NO_CRYPTO + + file_array=(${files// / }) + for file in ${file_array[@]} + do + exe_file_testcases $file + done +} + +parse_option + +if [ "${BUILD_HITLS}" = "on" ]; then + build_hitls +fi + +if [ "${SHOW_SIZE}" = "on" ]; then + show_size +fi + +if [ "${SHOW_MACRO}" = "on" ]; then + show_macro + exit 0 +fi + +if [ "$TEST_FEATURE" != "" ]; then + test_feature $TEST_FEATURE +fi diff --git a/testcode/sdv/CMakeLists.txt b/testcode/sdv/CMakeLists.txt new file mode 100644 index 00000000..9c1585ce --- /dev/null +++ b/testcode/sdv/CMakeLists.txt @@ -0,0 +1,212 @@ +# 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_TEST) + +set(openHiTLS_SRC "${PROJECT_SOURCE_DIR}/../..") +set(TEST_SOURCE_SRC + ${openHiTLS_SRC}/testcode/framework/gen_test/helper.c + ${openHiTLS_SRC}/testcode/framework/gen_test/test.c + ${openHiTLS_SRC}/testcode/framework/crypto/alg_check.c + ${openHiTLS_SRC}/testcode/framework/crypto/crypto_test_util.c + ${openHiTLS_SRC}/testcode/framework/stub/stub_replace.c +) + +if(GEN_TEST_FILES) + execute_process(COMMAND ./gen_testcase ${GEN_TEST_FILES} + WORKING_DIRECTORY ${openHiTLS_SRC}/testcode/output + RESULT_VARIABLE retval + ) + if(${retval} EQUAL 0) + message(STATUS "Generate ${GEN_TEST_FILES} success") + set(TEST_FILES "${GEN_TEST_FILES}") + else() + message(WARNING "Generate ${GEN_TEST_FILES} failed") + endif() +else() + message(STATUS "No file needs to be generated") +endif() + +message(STATUS "Enable bsl: ${ENABLE_BSL}") +message(STATUS "Enable fail repeat: ${ENABLE_FAIL_REPEAT}") +message(STATUS "Enable print: ${ENABLE_PRINT}") + +set(EXECUTABLE_OUTPUT_PATH ${openHiTLS_SRC}/testcode/output) +get_filename_component(sdv_exe ${TEST_FILES} NAME) +add_executable(${sdv_exe} ${openHiTLS_SRC}/testcode/output/${sdv_exe}.c ${TEST_SOURCE_SRC}) +target_compile_options(${sdv_exe} PUBLIC -D__FILENAME__="${sdv_exe}.c") +if(ENABLE_PRINT) + target_compile_options(${sdv_exe} PUBLIC -DPRINT_TO_TERMINAL) +endif() +if(ENABLE_FAIL_REPEAT) + target_compile_options(${sdv_exe} PUBLIC -DFAIL_REPEAT_RUN) +endif() +target_link_directories(${sdv_exe} + PUBLIC + ${openHiTLS_SRC}/build + ${openHiTLS_SRC}/testcode/framework/tls/lib + ${openHiTLS_SRC}/platform/Secure_C/lib + ) +if(ENABLE_X509) + target_link_libraries(${sdv_exe} + -lhitls_x509 + ) +endif() + +if(ENABLE_TLS) + target_link_libraries(${sdv_exe} + -ltls_hlt + -ltls_frame + -lhitls_tls + -lhitls_x509 + -lrec_wrapper + ) +endif() + +if(ENABLE_CRYPTO OR ENABLE_TLS) + target_link_libraries(${sdv_exe} + -lhitls_crypto + ) +endif() + +target_link_libraries(${sdv_exe} + -lhitls_bsl + -lboundscheck + -lpthread +) +if(ENABLE_UIO_SCTP OR ENABLE_TLS) + target_link_libraries(${sdv_exe} -lsctp) +endif() +target_include_directories(${sdv_exe} + PRIVATE + ${openHiTLS_SRC}/platform/Secure_C/include + ${openHiTLS_SRC}/include + ${openHiTLS_SRC}/testcode/framework/include + ${openHiTLS_SRC}/testcode/framework/crypto + ${openHiTLS_SRC}/testcode/framework/stub + ${openHiTLS_SRC}/testcode/framework/tls/func_wrapper/include + ${openHiTLS_SRC}/testcode/framework/tls/include + ${openHiTLS_SRC}/testcode/framework/tls/callback/include + ${openHiTLS_SRC}/testcode/framework/tls/base/include + ${openHiTLS_SRC}/testcode/framework/tls/resource/include + ${openHiTLS_SRC}/testcode/framework/tls/rpc/include + ${openHiTLS_SRC}/testcode/framework/tls/process/include + ${openHiTLS_SRC}/testcode/framework/tls/crypt/include + ${openHiTLS_SRC}/testcode/framework/tls/transfer/include + ${openHiTLS_SRC}/testcode/framework/tls/frame/src + ${openHiTLS_SRC}/testcode/framework/tls/msg/include + ${openHiTLS_SRC}/testcode/framework/tls/io/include + ${openHiTLS_SRC}/testcode/framework/tls/io/src + ${openHiTLS_SRC}/bsl/sal/include + ${openHiTLS_SRC}/bsl/tlv/include + ${openHiTLS_SRC}/include/bsl + ${openHiTLS_SRC}/include/tls + ${openHiTLS_SRC}/bsl/log/include + ${openHiTLS_SRC}/bsl/hash/include + ${openHiTLS_SRC}/bsl/base64/include + ${openHiTLS_SRC}/bsl/pem/include + ${openHiTLS_SRC}/bsl/list/include + ${openHiTLS_SRC}/bsl/usrdata/include + ${openHiTLS_SRC}/bsl/obj/include + ${openHiTLS_SRC}/bsl/include + ${openHiTLS_SRC}/include/crypto/ + ${openHiTLS_SRC}/crypto/bn/include/ + ${openHiTLS_SRC}/crypto/bn/src/ + ${openHiTLS_SRC}/crypto/entropy/include/ + ${openHiTLS_SRC}/crypto/sm3/include + ${openHiTLS_SRC}/crypto/sha3/include + ${openHiTLS_SRC}/crypto/sha2/include + ${openHiTLS_SRC}/crypto/sha2/src + ${openHiTLS_SRC}/crypto/sha1/include + ${openHiTLS_SRC}/crypto/md5/include + ${openHiTLS_SRC}/crypto/pbkdf2/include + ${openHiTLS_SRC}/crypto/hkdf/include + ${openHiTLS_SRC}/crypto/kdf/include + ${openHiTLS_SRC}/crypto/scrypt/include + ${openHiTLS_SRC}/crypto/hmac/include + ${openHiTLS_SRC}/crypto/aes/include + ${openHiTLS_SRC}/crypto/sm4/include + ${openHiTLS_SRC}/crypto/drbg/include + ${openHiTLS_SRC}/crypto/drbg/src + ${openHiTLS_SRC}/crypto/include + ${openHiTLS_SRC}/crypto/rsa/include + ${openHiTLS_SRC}/crypto/rsa/src + ${openHiTLS_SRC}/crypto/eal/src + ${openHiTLS_SRC}/crypto/eal/include + ${openHiTLS_SRC}/crypto/ealinit/include + ${openHiTLS_SRC}/crypto/ealinit/src + ${openHiTLS_SRC}/crypto/dsa/src + ${openHiTLS_SRC}/crypto/curve25519/src + ${openHiTLS_SRC}/crypto/curve25519/include + ${openHiTLS_SRC}/crypto/chacha20/include + ${openHiTLS_SRC}/crypto/dsa/include + ${openHiTLS_SRC}/crypto/dsa/src + ${openHiTLS_SRC}/crypto/dh/include + ${openHiTLS_SRC}/crypto/dh/src + ${openHiTLS_SRC}/crypto/ecc/include + ${openHiTLS_SRC}/crypto/ecc/src + ${openHiTLS_SRC}/crypto/ecdh/include + ${openHiTLS_SRC}/crypto/ecdsa/include + ${openHiTLS_SRC}/crypto/modes/include + ${openHiTLS_SRC}/crypto/modes/src + ${openHiTLS_SRC}/crypto/ecdh/include + ${openHiTLS_SRC}/crypto/ecdsa/include + ${openHiTLS_SRC}/crypto/sm2/include + ${openHiTLS_SRC}/crypto/sm2/src + ${openHiTLS_SRC}/crypto/paillier/include + ${openHiTLS_SRC}/crypto/paillier/src + ${openHiTLS_SRC}/crypto/encode/include + ${openHiTLS_SRC}/bsl/err/include + ${openHiTLS_SRC}/bsl/err/src + ${openHiTLS_SRC}/include/tls + ${openHiTLS_SRC}/tls/include + ${openHiTLS_SRC}/tls/cert/include + ${openHiTLS_SRC}/tls/cm/include + ${openHiTLS_SRC}/tls/config/include + ${openHiTLS_SRC}/tls/crypt/include + ${openHiTLS_SRC}/tls/app/include + ${openHiTLS_SRC}/tls/app/src + ${openHiTLS_SRC}/tls/ccs/include + ${openHiTLS_SRC}/tls/alert/include + ${openHiTLS_SRC}/bsl/uio/include + ${openHiTLS_SRC}/tls/record/include + ${openHiTLS_SRC}/tls/record/src + ${openHiTLS_SRC}/bsl/uio/src + ${openHiTLS_SRC}/bsl/asn1/include + ${openHiTLS_SRC}/x509/include + ${openHiTLS_SRC}/x509/x509_cert/include + ${openHiTLS_SRC}/x509/x509_csr/include + ${openHiTLS_SRC}/x509/x509_common/include + ${openHiTLS_SRC}/x509/x509_crl/include + ${openHiTLS_SRC}/x509/pkcs12/include + ${openHiTLS_SRC}/x509/cms/include + ${openHiTLS_SRC}/x509/x509_verify/include + ${openHiTLS_SRC}/config/macro_config + ${openHiTLS_SRC}/tls/handshake/include + ${openHiTLS_SRC}/tls/handshake/common/include + ${openHiTLS_SRC}/tls/handshake/cookie/include + ${openHiTLS_SRC}/tls/handshake/parse/include + ${openHiTLS_SRC}/tls/handshake/pack/include + ${openHiTLS_SRC}/tls/handshake/send/src + ${openHiTLS_SRC}/tls/handshake/recv/src + ${openHiTLS_SRC}/tls/handshake/recv/include + ${openHiTLS_SRC}/tls/feature/session/src + ${openHiTLS_SRC}/tls/cert/include + ${openHiTLS_SRC}/tls/cert/cert_adapt + ${openHiTLS_SRC}/tls/cert/hitls_x509_adapt + ${openHiTLS_SRC}/tls/crypt/crypt_self + ${openHiTLS_SRC}/config/macro_config + ${openHiTLS_SRC}/tls/handshake/parse/src + ${openHiTLS_SRC}/config/macro_config) + diff --git a/testcode/sdv/log/.gitignore b/testcode/sdv/log/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/testcode/sdv/report/.gitignore b/testcode/sdv/report/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/testcode/sdv/testcase/bsl/asn1/test_suite_sdv_asn1.c b/testcode/sdv/testcase/bsl/asn1/test_suite_sdv_asn1.c new file mode 100644 index 00000000..235b0b2a --- /dev/null +++ b/testcode/sdv/testcase/bsl/asn1/test_suite_sdv_asn1.c @@ -0,0 +1,1198 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "bsl_sal.h" +#include "bsl_asn1.h" +#include "bsl_err.h" +#include "bsl_log.h" +#include "sal_time.h" +#include "sal_file.h" +#include "bsl_obj_internal.h" +#include "hitls_x509_local.h" + +/* END_HEADER */ + +/* They are placed in their respective implementations and belong to specific applications, not asn1 modules */ +#define BSL_ASN1_CTX_SPECIFIC_TAG_VER 0 +#define BSL_ASN1_CTX_SPECIFIC_TAG_ISSUERID 1 +#define BSL_ASN1_CTX_SPECIFIC_TAG_SUBJECTID 2 +#define BSL_ASN1_CTX_SPECIFIC_TAG_EXTENSION 3 + +BSL_ASN1_TemplateItem certTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* x509 */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* tbs */ + /* 2: version */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CTX_SPECIFIC_TAG_VER, BSL_ASN1_FLAG_DEFAULT, 2}, + {BSL_ASN1_TAG_INTEGER, 0, 3}, + /* 2: serial number */ + {BSL_ASN1_TAG_INTEGER, 0, 2}, + /* 2: signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 3}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 3}, // 8 + /* 2: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, BSL_ASN1_FLAG_SAME, 3}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 4}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 5}, + {BSL_ASN1_TAG_ANY, 0, 5}, + /* 2: validity */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_CHOICE, 0, 3}, + {BSL_ASN1_TAG_CHOICE, 0, 3}, // 16 + /* 2: subject ref: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, BSL_ASN1_FLAG_SAME, 3}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 4}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 5}, + {BSL_ASN1_TAG_ANY, 0, 5}, + /* 2: subject public key info ref signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 3}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 4}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 4}, // 25 + {BSL_ASN1_TAG_BITSTRING, 0, 3}, + /* 2: issuer id, subject id */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_CTX_SPECIFIC_TAG_ISSUERID, BSL_ASN1_FLAG_OPTIONAL, 2}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_CTX_SPECIFIC_TAG_SUBJECTID, BSL_ASN1_FLAG_OPTIONAL, 2}, + /* 2: extension */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 3}, + {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 3}, + {BSL_ASN1_TAG_OCTETSTRING, 0, 3}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */ + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2}, // 35 + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ +}; + +BSL_ASN1_TemplateItem maxDepthTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 7}, +}; + +static BSL_ASN1_TemplateItem g_rsaPub[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* ignore seq */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* n */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* e */ + }; + +static BSL_ASN1_TemplateItem g_rsaPrv[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* ignore seq header */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* version */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* n */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* e */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* p */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* q */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d mod (p-1) */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d mod (q-1) */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* q^-1 mod p */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 1}, /* OtherPrimeInfos OPTIONAL */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, /* OtherPrimeInfo */ + {BSL_ASN1_TAG_INTEGER, 0, 3}, /* ri */ + {BSL_ASN1_TAG_INTEGER, 0, 3}, /* di */ + {BSL_ASN1_TAG_INTEGER, 0, 3} /* ti */ +}; + +typedef struct { + BSL_ASN1_TemplateItem *items; + uint32_t itemNum; + uint32_t asnNum; +} TestAsn1Param; + +static TestAsn1Param g_tests[] = { + {g_rsaPub, sizeof(g_rsaPub) / sizeof(g_rsaPub[0]), 2}, + {g_rsaPrv, sizeof(g_rsaPrv) / sizeof(g_rsaPrv[0]), 10}, +}; + +typedef enum { + BSL_ASN1_TAG_VERSION_IDX = 0, + BSL_ASN1_TAG_SERIAL_IDX = 1, + BSL_ASN1_TAG_SIGNINFO_OID_IDX = 2, + BSL_ASN1_TAG_SIGNINFO_ANY_IDX = 3, + BSL_ASN1_TAG_ISSUER_IDX = 4, + BSL_ASN1_TAG_BEFORE_VALID_IDX = 5, + BSL_ASN1_TAG_AFTER_VALID_IDX = 6, + BSL_ASN1_TAG_SUBJECT_IDX = 7, + BSL_ASN1_TAG_SUBKEYINFO_IDX = 8, + BSL_ASN1_TAG_SUBKEYINFO_ANY_IDX = 9, + BSL_ASN1_TAG_SUBKEYINFO_BITSTRING_IDX = 10, + BSL_ASN1_TAG_ISSUERID_IDX = 11, + BSL_ASN1_TAG_SUBJECTID_IDX = 12, + BSL_ASN1_TAG_EXT_IDX = 13, + BSL_ASN1_TAG_SIGNALG_IDX = 14, + BSL_ASN1_TAG_SIGNALG_ANY_IDX = 15, + BSL_ASN1_TAG_SIGN_IDX = 16 +} CERT_TEMPL_IDX; + +#define BSL_ASN1_TIME_UTC_1 14 +#define BSL_ASN1_TIME_UTC_2 15 + +#define BSL_ASN1_ID_ANY_1 7 +#define BSL_ASN1_ID_ANY_2 24 +#define BSL_ASN1_ID_ANY_3 34 + +char *g_oidEcc = "\x2a\x86\x48\xce\x3d\x02\01"; +char *g_oidRsaPss = "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0a"; + +int32_t BSL_ASN1_CertTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + BSL_ASN1_Buffer *param = NULL; + uint32_t len = 0; + switch (type) { + case BSL_ASN1_TYPE_CHECK_CHOICE_TAG: + if (idx == BSL_ASN1_TIME_UTC_1 || idx == BSL_ASN1_TIME_UTC_2) { + uint8_t tag = *(uint8_t *) data; + if ((tag & BSL_ASN1_TAG_UTCTIME) || (tag & BSL_ASN1_TAG_GENERALIZEDTIME)) { + *(uint8_t *) expVal = tag; + return BSL_SUCCESS; + } + } + return BSL_ASN1_FAIL; + case BSL_ASN1_TYPE_GET_ANY_TAG: + param = (BSL_ASN1_Buffer *) data; + len = param->len; + if (idx == BSL_ASN1_ID_ANY_1 || idx == BSL_ASN1_ID_ANY_3) { + if (strlen(g_oidRsaPss) == len && memcmp(param->buff, g_oidRsaPss, len) == 0) { + // note: any It can be encoded empty or it can be null + *(uint8_t *) expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + return BSL_SUCCESS; + } else { + *(uint8_t *) expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + } + if (idx == BSL_ASN1_ID_ANY_2) { + if (strlen(g_oidEcc) == len && memcmp(param->buff, g_oidEcc, len) == 0) { + // note: any It can be encoded empty or it can be null + *(uint8_t *) expVal = BSL_ASN1_TAG_OBJECT_ID; + return BSL_SUCCESS; + } else { // + *(uint8_t *) expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + } + return BSL_ASN1_FAIL; + default: + break; + } + return BSL_ASN1_FAIL; +} + +static int32_t ReadCert(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); + 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; + } + + *buff = fileBuff; + *len = (uint32_t)fileLen; + return ret; + } while (0); + BSL_SAL_FREE(fileBuff); + return ret; +} + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para1, para2, para3, para4); + printf("\n"); +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para); + printf("\n"); +} + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DecodeTemplate_TC001(char *path) +{ + BSL_LOG_BinLogFuncs func = {0}; + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + uint32_t fileLen = 0; + uint8_t *fileBuff = NULL; + int32_t ret = ReadCert(path, &fileBuff, &fileLen); + ASSERT_EQ(ret, BSL_SUCCESS); + uint8_t *rawBuff = fileBuff; + BSL_ASN1_Buffer asnArr[BSL_ASN1_TAG_SIGN_IDX + 1] = {0}; + BSL_ASN1_Template templ = {certTempl, sizeof(certTempl) / sizeof(certTempl[0])}; + ret = BSL_ASN1_DecodeTemplate(NULL, BSL_ASN1_CertTagGetOrCheck, &fileBuff, &fileLen, asnArr, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &fileBuff, &fileLen, asnArr, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_ASN1_ERR_NO_CALLBACK); + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, NULL, &fileLen, asnArr, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, &fileBuff, NULL, asnArr, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, &fileBuff, &fileLen, NULL, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, &fileBuff, &fileLen, asnArr, 0); + ASSERT_EQ(ret, BSL_NULL_INPUT); +exit: + BSL_SAL_FREE(rawBuff); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DECODE_TEMPLATE_TC002(char *path) +{ + BSL_LOG_BinLogFuncs func = {0}; + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + uint32_t fileLen = 0; + uint8_t *fileBuff = NULL; + int32_t ret = ReadCert(path, &fileBuff, &fileLen); + ASSERT_EQ(ret, BSL_SUCCESS); + uint8_t *rawBuff = fileBuff; + BSL_ASN1_Buffer asnArr[BSL_ASN1_TAG_SIGN_IDX + 1] = {0}; + BSL_ASN1_Template templ = {maxDepthTempl, sizeof(maxDepthTempl) / sizeof(maxDepthTempl[0])}; + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, &fileBuff, &fileLen, asnArr, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_ASN1_ERR_MAX_DEPTH); +exit: + BSL_SAL_FREE(rawBuff); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_CERT_FUNC_TC001(char *path, Hex *version, Hex *serial, Hex *algId, Hex *anyAlgId, + Hex *issuer, Hex *before, Hex *after, Hex *subject, Hex *pubId, Hex *pubAny, Hex *pubKey, Hex *issuerId, + Hex *subjectId, Hex *ext, Hex *signAlg, Hex *signAlgAny, Hex *sign) +{ + BSL_LOG_BinLogFuncs func = {0}; + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + uint32_t fileLen = 0; + uint8_t *fileBuff = NULL; + int32_t ret = ReadCert(path, &fileBuff, &fileLen); + ASSERT_EQ(ret, BSL_SUCCESS); + uint8_t *rawBuff = fileBuff; + BSL_ASN1_Buffer asnArr[BSL_ASN1_TAG_SIGN_IDX + 1] = {0}; + BSL_ASN1_Template templ = {certTempl, sizeof(certTempl) / sizeof(certTempl[0])}; + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, + &fileBuff, &fileLen, asnArr, BSL_ASN1_TAG_SIGN_IDX + 1); + ASSERT_EQ(ret, BSL_SUCCESS); + ASSERT_EQ(fileLen, 0); + // 证书对比 + if (version->len != 0) { + ASSERT_EQ_LOG("version compare tag", asnArr[BSL_ASN1_TAG_VERSION_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("version compare", version->x, version->len, + asnArr[BSL_ASN1_TAG_VERSION_IDX].buff, asnArr[BSL_ASN1_TAG_VERSION_IDX].len); + } + + ASSERT_EQ_LOG("serial compare tag", asnArr[BSL_ASN1_TAG_SERIAL_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("serial compare", serial->x, serial->len, + asnArr[BSL_ASN1_TAG_SERIAL_IDX].buff, asnArr[BSL_ASN1_TAG_SERIAL_IDX].len); + + ASSERT_EQ_LOG("algid compare tag", asnArr[BSL_ASN1_TAG_SIGNINFO_OID_IDX].tag, BSL_ASN1_TAG_OBJECT_ID); + ASSERT_COMPARE("algid compare", algId->x, algId->len, + asnArr[BSL_ASN1_TAG_SIGNINFO_OID_IDX].buff, asnArr[BSL_ASN1_TAG_SIGNINFO_OID_IDX].len); + + if (anyAlgId->len != 0) { + ASSERT_COMPARE("any algid compare", anyAlgId->x, anyAlgId->len, + asnArr[BSL_ASN1_TAG_SIGNINFO_ANY_IDX].buff, asnArr[BSL_ASN1_TAG_SIGNINFO_ANY_IDX].len); + } else { + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SIGNINFO_ANY_IDX].buff, NULL); + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SIGNINFO_ANY_IDX].len, 0); + } + + ASSERT_EQ_LOG("issuer compare tag", asnArr[BSL_ASN1_TAG_ISSUER_IDX].tag, + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE); + ASSERT_COMPARE("issuer compare", issuer->x, issuer->len, + asnArr[BSL_ASN1_TAG_ISSUER_IDX].buff, asnArr[BSL_ASN1_TAG_ISSUER_IDX].len); + + ASSERT_COMPARE("before compare", before->x, before->len, + asnArr[BSL_ASN1_TAG_BEFORE_VALID_IDX].buff, asnArr[BSL_ASN1_TAG_BEFORE_VALID_IDX].len); + + ASSERT_COMPARE("after compare", after->x, after->len, + asnArr[BSL_ASN1_TAG_AFTER_VALID_IDX].buff, asnArr[BSL_ASN1_TAG_AFTER_VALID_IDX].len); + + ASSERT_EQ_LOG("subject compare tag", asnArr[BSL_ASN1_TAG_SUBJECT_IDX].tag, + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE); + ASSERT_COMPARE("subject compare", subject->x, subject->len, + asnArr[BSL_ASN1_TAG_SUBJECT_IDX].buff, asnArr[BSL_ASN1_TAG_SUBJECT_IDX].len); + + ASSERT_EQ_LOG("subject pub key compare tag", asnArr[BSL_ASN1_TAG_SUBKEYINFO_IDX].tag, BSL_ASN1_TAG_OBJECT_ID); + ASSERT_COMPARE("subject pub key id compare", pubId->x, pubId->len, + asnArr[BSL_ASN1_TAG_SUBKEYINFO_IDX].buff, asnArr[BSL_ASN1_TAG_SUBKEYINFO_IDX].len); + + if (pubAny->len != 0) { + ASSERT_COMPARE("any pub key compare", pubAny->x, pubAny->len, + asnArr[BSL_ASN1_TAG_SUBKEYINFO_ANY_IDX].buff, asnArr[BSL_ASN1_TAG_SUBKEYINFO_ANY_IDX].len); + } else { + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SUBKEYINFO_ANY_IDX].buff, NULL); + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SUBKEYINFO_ANY_IDX].len, 0); + } + + ASSERT_EQ_LOG("subject pub key compare tag", asnArr[BSL_ASN1_TAG_SUBKEYINFO_BITSTRING_IDX].tag, + BSL_ASN1_TAG_BITSTRING); + ASSERT_COMPARE("subject pub key compare", pubKey->x, pubKey->len, + asnArr[BSL_ASN1_TAG_SUBKEYINFO_BITSTRING_IDX].buff, asnArr[BSL_ASN1_TAG_SUBKEYINFO_BITSTRING_IDX].len); + + if (issuerId->len != 0) { + ASSERT_COMPARE("issuerId compare", issuerId->x, issuerId->len, + asnArr[BSL_ASN1_TAG_ISSUERID_IDX].buff, asnArr[BSL_ASN1_TAG_ISSUERID_IDX].len); + } else { + ASSERT_EQ(asnArr[BSL_ASN1_TAG_ISSUERID_IDX].buff, NULL); + ASSERT_EQ(asnArr[BSL_ASN1_TAG_ISSUERID_IDX].len, 0); + } + if (subjectId->len != 0) { + ASSERT_COMPARE("subjectId compare", subjectId->x, subjectId->len, + asnArr[BSL_ASN1_TAG_SUBJECTID_IDX].buff, asnArr[BSL_ASN1_TAG_SUBJECTID_IDX].len); + } else { + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SUBJECTID_IDX].buff, NULL); + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SUBJECTID_IDX].len, 0); + } + + if (ext->len != 0) { // v1 没有ext + ASSERT_EQ_LOG("ext compare tag", asnArr[BSL_ASN1_TAG_EXT_IDX].tag, + BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CTX_SPECIFIC_TAG_EXTENSION); + ASSERT_COMPARE("ext compare", ext->x, ext->len, + asnArr[BSL_ASN1_TAG_EXT_IDX].buff, asnArr[BSL_ASN1_TAG_EXT_IDX].len); + } + + ASSERT_EQ_LOG("signAlg compare tag", asnArr[BSL_ASN1_TAG_SIGNALG_IDX].tag, BSL_ASN1_TAG_OBJECT_ID); + ASSERT_COMPARE("signAlg compare", signAlg->x, signAlg->len, + asnArr[BSL_ASN1_TAG_SIGNALG_IDX].buff, asnArr[BSL_ASN1_TAG_SIGNALG_IDX].len); + + if (signAlgAny->len != 0) { + ASSERT_COMPARE("signAlgAny compare", signAlgAny->x, signAlgAny->len, + asnArr[BSL_ASN1_TAG_SIGNALG_ANY_IDX].buff, asnArr[BSL_ASN1_TAG_SIGNALG_ANY_IDX].len); + } else { + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SIGNALG_ANY_IDX].buff, NULL); + ASSERT_EQ(asnArr[BSL_ASN1_TAG_SIGNALG_ANY_IDX].len, 0); + } + + ASSERT_EQ_LOG("sign compare tag", asnArr[BSL_ASN1_TAG_SIGN_IDX].tag, BSL_ASN1_TAG_BITSTRING); + ASSERT_COMPARE("sign compare", sign->x, sign->len, + asnArr[BSL_ASN1_TAG_SIGN_IDX].buff, asnArr[BSL_ASN1_TAG_SIGN_IDX].len); +exit: + BSL_SAL_FREE(rawBuff); +} +/* END_CASE */ + + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC001(Hex *val) +{ + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BOOLEAN, val->len, val->x}; + bool res; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(NULL, &res); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodePrimitiveItem(&asn, NULL); + ASSERT_EQ(ret, BSL_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC002(int tag, Hex *val) +{ + BSL_ASN1_Buffer asn = {(uint8_t)tag, val->len, val->x}; + int32_t res; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(NULL, &res); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodePrimitiveItem(&asn, NULL); + ASSERT_EQ(ret, BSL_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC003(Hex *val) +{ + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, val->len, val->x}; + BSL_ASN1_BitString res; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(NULL, &res); + ASSERT_EQ(ret, BSL_NULL_INPUT); + ret = BSL_ASN1_DecodePrimitiveItem(&asn, NULL); + ASSERT_EQ(ret, BSL_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC(Hex *val, int expectVal) +{ + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BOOLEAN, val->len, val->x}; + bool res; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(&asn, &res); + ASSERT_EQ(ret, BSL_SUCCESS); + ASSERT_EQ((bool)expectVal, res); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC(int tag, Hex *val, int result, int expectVal) +{ + BSL_ASN1_Buffer asn = {(uint8_t)tag, val->len, val->x}; + int32_t res; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(&asn, &res); + ASSERT_EQ(ret, result); + if (ret == BSL_SUCCESS) { + ASSERT_EQ((uint32_t)expectVal, res); + } + +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_BITSTRING_PRIMITIVEITEM_FUNC(Hex *val, int result, int unusedBits) +{ + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, val->len, val->x}; + BSL_ASN1_BitString res; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(&asn, &res); + ASSERT_EQ(ret, result); + if (ret == BSL_SUCCESS) { + ASSERT_EQ((uint32_t)unusedBits, res.unusedBits); + ASSERT_EQ(val->len - 1, res.len); + ASSERT_COMPARE("bit string", res.buff, res.len, val->x + 1, val->len - 1); + } + +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC(int tag, Hex *val, int result, + int year, int month, int day, int hour, int minute, int second) +{ + BSL_ASN1_Buffer asn = {tag, val->len, val->x}; + BSL_TIME res = {0}; + int32_t ret = BSL_ASN1_DecodePrimitiveItem(&asn, &res); + ASSERT_EQ(ret, result); + if (ret == BSL_SUCCESS) { + ASSERT_EQ(res.year, year); + ASSERT_EQ(res.month, month); + ASSERT_EQ(res.day, day); + ASSERT_EQ(res.hour, hour); + ASSERT_EQ(res.minute, minute); + ASSERT_EQ(res.second, second); + } +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DECODELEN_FUNC(int flag, Hex *val, int res) +{ + uint8_t *encode = val->x; + uint32_t encodeLen = val->len; + uint32_t len = 0; + ASSERT_EQ(BSL_ASN1_DecodeLen(&encode, &encodeLen, flag, &len), res); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC(Hex *val, int ecpLen, int res) +{ + uint8_t *encode = val->x; + uint32_t encodeLen = val->len; + ASSERT_EQ(BSL_ASN1_GetCompleteLen(encode, &encodeLen), res); + if (res == BSL_SUCCESS) { + ASSERT_EQ(encodeLen, ecpLen); + } +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_API_TC001(void) +{ + BSL_ASN1_TemplateItem item[] = {{BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + BSL_ASN1_Buffer asnArr[1] = {0}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + /* templ */ + ASSERT_EQ(BSL_ASN1_EncodeTemplate(NULL, asnArr, 1, &encode, &encodeLen), BSL_INVALID_ARG); + templ.templItems = NULL; + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 1, &encode, &encodeLen), BSL_INVALID_ARG); + templ.templItems = item; + templ.templNum = 0; + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 1, &encode, &encodeLen), BSL_INVALID_ARG); + templ.templNum = 1; + + /* asnArr */ + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, NULL, 1, &encode, &encodeLen), BSL_INVALID_ARG); + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 0, &encode, &encodeLen), BSL_INVALID_ARG); + + /* encode */ + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 1, NULL, &encodeLen), BSL_INVALID_ARG); + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 1, &encode, NULL), BSL_INVALID_ARG); + encode = (uint8_t*)&encodeLen; + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 1, &encode, &encodeLen), BSL_INVALID_ARG); + +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC001(void) +{ + BSL_ASN1_Template templ = {maxDepthTempl, sizeof(maxDepthTempl) / sizeof(maxDepthTempl[0])}; + BSL_ASN1_Buffer asnArr[1] = {0}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asnArr, 1, &encode, &encodeLen), BSL_ASN1_ERR_MAX_DEPTH); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC002(int tag, int len, int ret) +{ + BSL_ASN1_TemplateItem item[] = {{tag, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + uint8_t data = 1; + BSL_ASN1_Buffer asn = {tag, len, &data}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), ret); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC003(Hex *data) +{ + BSL_ASN1_TemplateItem items[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_ANY, 0, 1}, + {BSL_ASN1_TAG_CHOICE, 0, 1} + }; + BSL_ASN1_Template templ = {items, sizeof(items) / sizeof(items[0])}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_INTEGER, data->len, data->x}; + BSL_ASN1_Buffer asns[] = {asn, asn, asn, asn}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + uint32_t expectAsnNum = 3; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asns, expectAsnNum - 1, &encode, &encodeLen), + BSL_ASN1_ERR_ENCODE_ASN_LACK); + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asns, expectAsnNum + 1, &encode, &encodeLen), + BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC004(void) +{ + BSL_ASN1_TemplateItem items[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + }; + BSL_ASN1_Template templ = {items, sizeof(items) / sizeof(items[0])}; + int iData = 256; + BSL_ASN1_Buffer asn[] = {{BSL_ASN1_TAG_ENUMERATED, sizeof(int), (uint8_t *)&iData}}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asn, sizeof(asn) / sizeof(asn[0]), &encode, &encodeLen), + BSL_ASN1_ERR_TAG_EXPECTED); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_BOOL_FUNC(int data, Hex *expect) +{ + BSL_ASN1_TemplateItem item[] = {{BSL_ASN1_TAG_BOOLEAN, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BOOLEAN, 1, (uint8_t *)&data}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode bool", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC(int ret, int data, Hex *expect) +{ + BSL_ASN1_TemplateItem item[] = {{BSL_ASN1_TAG_INTEGER, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + BSL_ASN1_Buffer asn = {0}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, data, &asn), BSL_SUCCESS); + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), ret); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode int", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(asn.buff); + if (ret == BSL_SUCCESS) { + BSL_SAL_Free(encode); + } +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_INT_BN_FUNC(Hex *bn, Hex *expect) +{ + BSL_ASN1_TemplateItem item[] = {{BSL_ASN1_TAG_INTEGER, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_INTEGER, bn->len, bn->x}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode int", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC(int ret, Hex *data, int unusedBits, Hex *expect) +{ + BSL_ASN1_TemplateItem item[] = {{BSL_ASN1_TAG_BITSTRING, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + BSL_ASN1_BitString bs = {data->x, data->len, unusedBits}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, + data->len == 0 ? 0 : sizeof(BSL_ASN1_BitString), + data->len == 0 ? NULL : (uint8_t *)&bs}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), ret); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode bitstring", expect->x, expect->len, encode, encodeLen); +exit: + if (ret == BSL_SUCCESS) { + BSL_SAL_Free(encode); + } +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TIME_FUNC(int tag, int ret, int year, int month, int day, int hour, int minute, int second, + Hex *expect) +{ + BSL_ASN1_TemplateItem item[] = {{tag, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + BSL_TIME time = {year, month, day, hour, minute, 0, second, 0}; + BSL_ASN1_Buffer asn = {tag, sizeof(BSL_TIME), (uint8_t *)&time}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), ret); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode time", expect->x, expect->len, encode, encodeLen); +exit: + if (ret == BSL_SUCCESS) { + BSL_SAL_Free(encode); + } +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_NULL_FUNC_TC001(Hex *expect) +{ + BSL_ASN1_TemplateItem item[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_NULL, 0, 1}, + {BSL_ASN1_TAG_NULL, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_NULL, BSL_ASN1_FLAG_DEFAULT, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_NULL, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_NULL, 0, 2}, + }; + BSL_ASN1_Template templ = {item, sizeof(item) / sizeof(item[0])}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_NULL, 0, NULL}; + BSL_ASN1_Buffer asns[] = {asn, asn, asn, asn, asn}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asns, sizeof(asns) / sizeof(asn), &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode null", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_NULL_FUNC_TC002(Hex *expect) +{ + uint8_t data = 1; + BSL_ASN1_TemplateItem item[] = {{BSL_ASN1_TAG_NULL, 0, 0}}; + BSL_ASN1_Template templ = {item, sizeof(item) / sizeof(item[0])}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_NULL, 1, &data}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode null", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC001(Hex *expect) +{ + BSL_ASN1_TemplateItem items[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_INTEGER, 0, 3}, + {BSL_ASN1_TAG_INTEGER, 0, 3}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + }; + BSL_ASN1_Template templ = {items, sizeof(items) / sizeof(items[0])}; + uint8_t iData[] = {0x01, 0x00}; + uint8_t data = 0x12; + BSL_ASN1_Buffer asns[] = { + {BSL_ASN1_TAG_INTEGER, sizeof(iData) / sizeof(uint8_t), iData}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 1, &data}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 1, &data}, + {BSL_ASN1_TAG_INTEGER, sizeof(iData) / sizeof(uint8_t), iData}, + }; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asns, sizeof(asns) / sizeof(asns[0]), &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode headonly", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC002(Hex *data, Hex *expect) +{ + BSL_ASN1_TemplateItem items[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_DEFAULT, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_DEFAULT, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 2}, + }; + BSL_ASN1_Template templ = {items, sizeof(items) / sizeof(items[0])}; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_INTEGER, data->len, data->x}; + BSL_ASN1_Buffer asns[] = {asn, asn, asn, asn, asn, asn}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asns, sizeof(asns) / sizeof(asn), &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode optional|default", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +static BSL_ASN1_TemplateItem g_templItem1[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 2}, +}; + +static BSL_ASN1_TemplateItem g_templItem2[] = { + {BSL_ASN1_TAG_INTEGER, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 0}, +}; + +static BSL_ASN1_TemplateItem g_templItem3[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 2}, + {BSL_ASN1_TAG_INTEGER, 0, 0}, + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_OPTIONAL, 0}, +}; + +static BSL_ASN1_Template g_templ[] = { + {g_templItem1, sizeof(g_templItem1) / sizeof(g_templItem1[0])}, + {g_templItem2, sizeof(g_templItem2) / sizeof(g_templItem2[0])}, + {g_templItem3, sizeof(g_templItem3) / sizeof(g_templItem3[0])}, +}; + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC003(Hex *data, int templIdx, Hex *expect) +{ +#define MAX_INT_ASN_NUM 4 + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_INTEGER, data->len, data->x}; + BSL_ASN1_Buffer asns[MAX_INT_ASN_NUM] = {asn, asn, asn, asn}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(g_templ + templIdx, asns, MAX_INT_ASN_NUM, &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode", expect->x, expect->len, encode, encodeLen); +exit: + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_LIST_API_TC001(void) +{ + BSL_ASN1_TemplateItem item[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_NULL, 0, 1}, + {BSL_ASN1_TAG_NULL, 0, 1}, + }; + BSL_ASN1_Template templ = {item, sizeof(item) / sizeof(item[0])}; + BSL_ASN1_Buffer asnArr[] = { + {BSL_ASN1_TAG_NULL, 0, NULL}, + {BSL_ASN1_TAG_NULL, 0, NULL}, + }; + uint32_t arrNum = sizeof(asnArr) / sizeof(asnArr[0]); + BSL_ASN1_Buffer out = {0}; + + /* tag */ + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_TIME, 1, &templ, asnArr, arrNum, &out), BSL_INVALID_ARG); + + /* listSize */ + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_TIME, 0, &templ, asnArr, arrNum, &out), BSL_INVALID_ARG); + + /* templ */ + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, NULL, asnArr, arrNum, &out), BSL_INVALID_ARG); + templ.templItems = NULL; + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, 1, &templ, asnArr, arrNum, &out), BSL_INVALID_ARG); + templ.templItems = item; + templ.templNum = 0; + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, arrNum, &out), BSL_INVALID_ARG); + templ.templNum = sizeof(item) / sizeof(item[0]); + + /* asnArr */ + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, NULL, arrNum, &out), BSL_INVALID_ARG); + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, 0, &out), BSL_INVALID_ARG); + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, arrNum + 1, &templ, asnArr, arrNum, &out), BSL_INVALID_ARG); + + /* out */ + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, arrNum, NULL), BSL_INVALID_ARG); + out.buff = (uint8_t *)&arrNum; + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, arrNum, &out), BSL_INVALID_ARG); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_LIST_ERROR_TC001(void) +{ + BSL_ASN1_TemplateItem item[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_NULL, 0, 1}, + }; /* The expected number of asns in the current template is 1. */ + BSL_ASN1_Template templ = {item, sizeof(item) / sizeof(item[0])}; + BSL_ASN1_Buffer asnArr[] = {{BSL_ASN1_TAG_INTEGER, 0, NULL}}; + BSL_ASN1_Buffer out = {0}; + + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, 1, &out), BSL_ASN1_ERR_TAG_EXPECTED); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_LIST_ERROR_TC002(void) +{ + BSL_ASN1_TemplateItem item[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_NULL, 0, 1}, + {BSL_ASN1_TAG_NULL, 0, 1}, + }; /* The expected number of asns in the current template is 2. */ + BSL_ASN1_Template templ = {item, sizeof(item) / sizeof(item[0])}; + BSL_ASN1_Buffer asnArr[] = { + {BSL_ASN1_TAG_NULL, 0, NULL}, + {BSL_ASN1_TAG_NULL, 0, NULL}, + {BSL_ASN1_TAG_NULL, 0, NULL}, + }; + uint32_t arrNum = sizeof(asnArr) / sizeof(asnArr[0]); + BSL_ASN1_Buffer out = {0}; + + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, 1, &out), BSL_ASN1_ERR_ENCODE_ASN_LACK); + + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, asnArr, arrNum, &out), + BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_LIST_ERROR_TC003(int tag, int ret) +{ + BSL_ASN1_TemplateItem item[] = {{tag, 0, 0}}; + BSL_ASN1_Template templ = {item, 1}; + uint8_t data = 1; + BSL_ASN1_Buffer asn = {tag, 1, &data}; + BSL_ASN1_Buffer out = {0}; + + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, 1, &templ, &asn, 1, &out), ret); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_LIST_TC001(int listSize, Hex *encode) +{ + BSL_ASN1_TemplateItem x509Name[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, 0, 2} + }; + BSL_ASN1_Template templ = {x509Name, sizeof(x509Name) / sizeof(x509Name[0])}; + BslOidString *o = BSL_OBJ_GetOidFromCID(BSL_CID_ORGANIZATIONNAME); + char *oName = "Energy TEST"; + BslOidString *cn = BSL_OBJ_GetOidFromCID(BSL_CID_COMMONNAME); + char *cnName = "Energy ECC Equipment Root CA 1"; + BSL_ASN1_Buffer in[] = { + {BSL_ASN1_TAG_OBJECT_ID, o->octetLen, (uint8_t *)o->octs}, + {BSL_ASN1_TAG_PRINTABLESTRING, strlen(oName), (uint8_t *)oName}, + {BSL_ASN1_TAG_OBJECT_ID, cn->octetLen, (uint8_t *)cn->octs}, + {BSL_ASN1_TAG_PRINTABLESTRING, strlen(cnName), (uint8_t *)cnName}, + }; + BSL_ASN1_Buffer out = {0}; + + ASSERT_EQ(BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, listSize, &templ, in, sizeof(in) / sizeof(in[0]), &out), + BSL_SUCCESS); + ASSERT_EQ(encode->len, out.len); + ASSERT_COMPARE("Encode list", encode->x, encode->len, out.buff, out.len); +exit: + BSL_SAL_FREE(out.buff); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_DECODE_THEN_ENCODE_FUNC_TC001(int testIdx, char *path) +{ + BSL_ASN1_Template templ = {g_tests[testIdx].items, g_tests[testIdx].itemNum}; + uint32_t asnNum = g_tests[testIdx].asnNum; + uint8_t *rawData = NULL; + uint32_t dataLen = 0; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + BSL_ASN1_Buffer *decodeAsns = (BSL_ASN1_Buffer *)BSL_SAL_Calloc(asnNum, sizeof(BSL_ASN1_Buffer)); + ASSERT_TRUE(decodeAsns != NULL); + + /* Decode */ + ASSERT_EQ(BSL_SAL_ReadFile(path, &rawData, &dataLen), BSL_SUCCESS); + uint8_t *decode = rawData; + uint32_t decodeLen = dataLen; + ASSERT_EQ(BSL_ASN1_DecodeTemplate(&templ, NULL, &decode, &decodeLen, decodeAsns, asnNum), + BSL_SUCCESS); + ASSERT_EQ(decodeLen, 0); + + /* Encode */ + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, decodeAsns, asnNum, &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, dataLen); + ASSERT_COMPARE("Decode then encode", rawData, dataLen, encode, encodeLen); +exit: + BSL_SAL_Free(decodeAsns); + BSL_SAL_Free(rawData); + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_THEN_DECODE_FUNC_TC001(int boolData, int number, Hex *bitString, int unusedBits, Hex *utf8, + int year, int month, int day, int hour, int minute, int second, Hex *headonly, Hex *expect) +{ + BSL_ASN1_TemplateItem items[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_BOOLEAN, 0, 1}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_BITSTRING, 0, 1}, + {BSL_ASN1_TAG_NULL, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_UTF8STRING, 0, 1}, + {BSL_ASN1_TAG_UTCTIME, 0, 1}, + {BSL_ASN1_TAG_UTCTIME, BSL_ASN1_FLAG_OPTIONAL, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, + {BSL_ASN1_TAG_NULL, 0, 2}, + }; + BSL_ASN1_Buffer integer = {0}; + ASSERT_EQ(BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, number, &integer), BSL_SUCCESS); + BSL_ASN1_BitString bs = {bitString->x, bitString->len, unusedBits}; + BSL_TIME time = {year, month, day, hour, minute, 0, second, 0}; + BSL_ASN1_Buffer asns[] = { + {BSL_ASN1_TAG_BOOLEAN, sizeof(bool), (uint8_t *)&boolData}, // 0 + integer, // 1 + {BSL_ASN1_TAG_BITSTRING, sizeof(BSL_ASN1_BitString), (uint8_t *)&bs}, // 2 + {BSL_ASN1_TAG_NULL, 0, NULL}, // 3 + {BSL_ASN1_TAG_UTF8STRING, utf8->len, utf8->x}, // 4 + {BSL_ASN1_TAG_UTCTIME, sizeof(BSL_TIME), (uint8_t *)&time}, // 5 + {BSL_ASN1_TAG_UTCTIME, 0, NULL}, // 6 + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, headonly->len, headonly->x}, // 7 + }; + uint32_t asnNum = sizeof(asns) / sizeof(asns[0]); + BSL_ASN1_Template templ = {items, sizeof(items) / sizeof(items[0])}; + uint8_t *encode = NULL; + uint32_t encodeLen = 0; + + ASSERT_EQ(BSL_ASN1_EncodeTemplate(&templ, asns, asnNum, &encode, &encodeLen), BSL_SUCCESS); + ASSERT_EQ(encodeLen, expect->len); + ASSERT_COMPARE("Encode", expect->x, expect->len, encode, encodeLen); + + uint8_t *tmp = encode; + uint32_t tmpLen = encodeLen; + BSL_ASN1_Buffer decAns[8] = {0}; // 8 is asnNum + ASSERT_EQ(BSL_ASN1_DecodeTemplate(&templ, NULL, &tmp, &tmpLen, decAns, asnNum), BSL_SUCCESS); + ASSERT_EQ(tmpLen, 0); + + bool bRes; + ASSERT_EQ(BSL_ASN1_DecodePrimitiveItem(decAns + 0, &bRes), BSL_SUCCESS); // Check the decoded data with index 0. + ASSERT_EQ(bRes, boolData); + + int iRes; + ASSERT_EQ(BSL_ASN1_DecodePrimitiveItem(decAns + 1, &iRes), BSL_SUCCESS); // Check the decoded data with index 1. + ASSERT_EQ(iRes, number); + + BSL_ASN1_BitString bs2 = {0}; + ASSERT_EQ(BSL_ASN1_DecodePrimitiveItem(decAns + 2, &bs2), BSL_SUCCESS); // Check the decoded data with index 2. + ASSERT_EQ(bs.unusedBits, unusedBits); + + BSL_TIME time2 = {0}; + ASSERT_EQ(BSL_ASN1_DecodePrimitiveItem(decAns + 5, &time2), BSL_SUCCESS); // Check the decoded data with index 5. + ASSERT_EQ(time2.year, year); + ASSERT_EQ(time2.month, month); + ASSERT_EQ(time2.day, day); + ASSERT_EQ(time2.hour, hour); + ASSERT_EQ(time2.minute, minute); + ASSERT_EQ(time2.second, second); + +exit: + BSL_SAL_Free(integer.buff); + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/** + * For test bmpString. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_BMPSTRING_TC001(Hex *enc, char *dec) +{ + int32_t ret; + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BMPSTRING, enc->len, enc->x}; + BSL_ASN1_Buffer decode = {BSL_ASN1_TAG_BMPSTRING, 0, NULL}; + BSL_ASN1_Buffer encode = {0}; + + ret = BSL_ASN1_DecodePrimitiveItem(&asn, &decode); + ASSERT_EQ(ret, BSL_SUCCESS); + uint32_t decLen = (uint32_t)strlen(dec); + ASSERT_COMPARE("Decode String", decode.buff, decode.len, dec, decLen); + + BSL_ASN1_TemplateItem testTempl[] = { + {BSL_ASN1_TAG_BMPSTRING, 0, 0} + }; + BSL_ASN1_Template templ = {testTempl, sizeof(testTempl) / sizeof(testTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, &decode, 1, &encode.buff, &encode.len); + ASSERT_EQ(ret, BSL_SUCCESS); + ASSERT_COMPARE("Encode String", encode.buff + 2, encode.len - 2, enc->x, enc->len); // skip 2 bytes header +exit: + BSL_SAL_FREE(decode.buff); + BSL_SAL_FREE(encode.buff); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/bsl/asn1/test_suite_sdv_asn1.data b/testcode/sdv/testcase/bsl/asn1/test_suite_sdv_asn1.data new file mode 100644 index 00000000..34ffbea7 --- /dev/null +++ b/testcode/sdv/testcase/bsl/asn1/test_suite_sdv_asn1.data @@ -0,0 +1,350 @@ +SDV_BSL_ASN1_DecodeTemplate_TC001 +SDV_BSL_ASN1_DecodeTemplate_TC001:"../testdata/cert/asn1/nist384ca.crt" + +SDV_BSL_ASN1_DECODE_TEMPLATE_TC002 +SDV_BSL_ASN1_DECODE_TEMPLATE_TC002:"../testdata/cert/asn1/nist384ca.crt" + +SDV_BSL_ASN1_PARSE_CERT_FUNC_TC001 parse ecdsa p384 ca, x509 v3, pub info any is not null, any is encoded as none +SDV_BSL_ASN1_PARSE_CERT_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":"02":"54eb174cce5c701873bcdca33db9811f63676d06":"2a8648ce3d040302":"":"310B300906035504061302434E310D300B06035504080C046F70656E310D300B06035504070C047869616E31123010060355040A0C096F70656E6869746C73310D300B060355040B0C0461736E313114301206035504030C0B63612E61736E312E636F6D":"3234303230343037303334315a":"3334303230313037303334315a":"310B300906035504061302434E310D300B06035504080C046F70656E310D300B06035504070C047869616E31123010060355040A0C096F70656E6869746C73310D300B060355040B0C0461736E313114301206035504030C0B63612E61736E312E636F6D":"2A8648CE3D0201":"2B81040022":"0004A12213C48AAD4DAFFE8A7AC6C6FA8F6883F4A768383DE9AA602DFCAA0AA3143D54AA8E2C1650A25B18AC9C78E33FEA4F41F63DB0FBF7263242F0B924EE09F37E96CC34BBFB7859E578878E6561C771002047D59C088FADFD0E8403914AB580C1":"":"":"307A301D0603551D0E041604145ED3DB0A721F214C362744058AC56767ADA683DB301F0603551D230418301680145ED3DB0A721F214C362744058AC56767ADA683DB300F0603551D130101FF040530030101FF30270603551D110420301E82096C6F63616C686F7374820B63612E61736E312E636F6D87047F000001":"2A8648CE3D040302":"":"003066023100B001D965386ECE3947F3BC16843524B0019B0FCAF238948C16A8200421C7BBCD33A519AD5CF1B3E5865C2A3CA016E3DF023100FABA58E2AE3CC388E021568CC46275DF0E90FCCA002AE43ABCB1ECED2EDA9159BAFFA9567DFE8CD2300576EFB6082703" + +SDV_BSL_ASN1_PARSE_CERT_FUNC_TC001 parse sha256 rsa ca, x509 v1, any is encoded as null +SDV_BSL_ASN1_PARSE_CERT_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":"":"06EBB33555449776551BFEEDF985C33D42FE50D2":"2A864886F70D01010B":"":"310B300906035504061302434E3110300E06035504080C07536861616E7869310D300B06035504070C047869616E31123010060355040A0C096F70656E4869544C533122302006092A864886F70D01090116136F70656E4869544C5340656D61696C2E636F6D":"3234303230363036313831305A":"3334303230333036313831305A":"310B300906035504061302434E3110300E06035504080C07536861616E7869310D300B06035504070C047869616E31123010060355040A0C096F70656E4869544C533122302006092A864886F70D01090116136F70656E4869544C5340656D61696C2E636F6D":"2A864886F70D010101":"":"0030818902818100CC1536AAA0682949ECAF624C19E4E35314F29278BFD25A8D37DA627A8445DDCFDC5F11B3F6D41287EF6E89D0A64C68590A0191096E232655F579B02C69A6A14DBEFB9D7D6345373CE5ECA372A9546B228A995A518830BA9EA1589D484D2EAE092459E39A3716BBC82075F0F97F8791344D0F951023433705A817D1CA5F3116870203010001":"":"":"":"2A864886F70D01010B":"":"00466A30D010DD0DDA7B7EE26FBED50D4798A485AE02E90D9899FE709630A2E80E2D3E9E15FCA1755A4201019DEF14F3C9D3AA7B4ABFA8F564D76F850D3A58BD8C50636EECC39466D7472CE0F9DC61389D307A5A4D85715D5D612D2EE9C9F3E6681D7557DB04107771F6B7DD9B8C54C67D828219E530BBD1DD948DE3016D056F5F" + +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC001 +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC001:"01" + +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC002 +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC002:BSL_ASN1_TAG_INTEGER:"02" + +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC002 +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC002:BSL_ASN1_TAG_ENUMERATED:"7F" + +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC003 +SDV_BSL_ASN1_DecodePrimitiveItem_FUNC_TC003:"040A3B5F291CD0" + +SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC:"01":1 + +SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC:"FF":1 + +SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_BOOL_PRIMITIVEITEM_FUNC:"00":0 + +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_INTEGER:"02":BSL_SUCCESS:2 + +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC Negative numbers not supported +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_ENUMERATED:"FF":BSL_ASN1_ERR_DECODE_INT:255 + +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_ENUMERATED:"7F":BSL_SUCCESS:127 + +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_INTEGER:"01234576":BSL_SUCCESS:19088758 + +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC Exceeded the maximum supported length +SDV_BSL_ASN1_PARSE_INT_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_INTEGER:"1101234576":BSL_ASN1_ERR_DECODE_INT:19088758 + +SDV_BSL_ASN1_PARSE_BITSTRING_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_BITSTRING_PRIMITIVEITEM_FUNC:"040A3B5F291CD0":BSL_SUCCESS:4 + +SDV_BSL_ASN1_PARSE_BITSTRING_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_BITSTRING_PRIMITIVEITEM_FUNC:"080A3B5F291C00":BSL_ASN1_ERR_DECODE_BIT_STRING:4 + +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_UTCTIME:"3234303230343037303334315A":BSL_SUCCESS:2024:2:4:7:3:41 + +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:"32303234303230343037303334315A":BSL_SUCCESS:2024:2:4:7:3:41 + +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_UTCTIME:"3234303230343037303334315A5A":BSL_ASN1_ERR_DECODE_UTC_TIME:2024:2:4:7:3:41 + +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC +SDV_BSL_ASN1_PARSE_TIME_PRIMITIVEITEM_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:"32303234303230343037303334315A5A":BSL_ASN1_ERR_DECODE_GENERAL_TIME:2024:2:4:7:3:41 + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"00":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"7F":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"7F0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789AB":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"7F0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCD":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"85":BSL_ASN1_ERR_MAX_LEN_NUM + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"81":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"8100":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"8200":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"820000":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"830000":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"83000000":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"84000000":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"8400000000":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"81FF":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"82FFFF":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"83FFFFFF":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"84FFFFFFFF":BSL_ASN1_ERR_MAX_LEN_NUM + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"81":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"8100":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"8200":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"820000":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"830000":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"83000000":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:0:"84000000":BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"8400000000":BSL_SUCCESS + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"81FF":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"82FFFF":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"83FFFFFF":BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODELEN_FUNC +SDV_BSL_ASN1_DECODELEN_FUNC:1:"84FFFFFFFF":BSL_ASN1_ERR_MAX_LEN_NUM + +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC:"":0:BSL_ASN1_ERR_BUFF_NOT_ENOUGH + +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC:"80":0:BSL_ASN1_ERR_DECODE_LEN + +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC:"3000":2:BSL_SUCCESS + +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC +SDV_BSL_ASN1_DECODECOMPLETELEN_FUNC:"30020101":4:BSL_SUCCESS + +EncodeTemplate: Test for illegal parameters. +SDV_BSL_ASN1_ENCODE_TEMPLATE_API_TC001: + +EncodeTemplate: depth is too large +SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC001: + +EncodeTemplate: length of bitstring buffer is invalid +SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC002:BSL_ASN1_TAG_BITSTRING:1:BSL_ASN1_ERR_ENCODE_BIT_STRING + +EncodeTemplate: length of time buffer is invalid +SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC002:BSL_ASN1_TAG_UTCTIME:1:BSL_ASN1_ERR_CHECK_TIME + +EncodeTemplate: length of bool buffer is invalid +SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC002:BSL_ASN1_TAG_BOOLEAN:0:BSL_ASN1_ERR_ENCODE_BOOL + +EncodeTemplate: asnNum is too small or too large +SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC003:"FF" + +EncodeTemplate: tag is not expected +SDV_BSL_ASN1_ENCODE_TEMPLATE_ERROR_TC004: + +EncodeTemplate BOOL: true +SDV_BSL_ASN1_ENCODE_BOOL_FUNC:1:"0101FF" + +EncodeTemplate BOOL: false +SDV_BSL_ASN1_ENCODE_BOOL_FUNC:0:"010100" + +EncodeTemplate INTEGER: 0 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:0:"020100" + +EncodeTemplate INTEGER: 1 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:1:"020101" + +EncodeTemplate INTEGER: 255 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:255:"020200FF" + +EncodeTemplate INTEGER: 256 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:256:"02020100" + +EncodeTemplate INTEGER: 65535 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:65535:"020300FFFF" + +EncodeTemplate INTEGER: 65536 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:65536:"0203010000" + +EncodeTemplate INTEGER: 16777215 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:16777215:"020400FFFFFF" + +EncodeTemplate INTEGER: 16777216 +SDV_BSL_ASN1_ENCODE_INT_LIMB_FUNC:BSL_SUCCESS:16777216:"020401000000" + +EncodeTemplate BigNumber: high bit is not 1 #1 +SDV_BSL_ASN1_ENCODE_INT_BN_FUNC:"7321":"02027321" + +EncodeTemplate BigNumber: high bit is not 1 #2 +SDV_BSL_ASN1_ENCODE_INT_BN_FUNC:"0000007321":"02027321" + +EncodeTemplate BigNumber: high bit is 1 #1 +SDV_BSL_ASN1_ENCODE_INT_BN_FUNC:"A321":"020300A321" + +EncodeTemplate BigNumber: high bit is 1 #2 +SDV_BSL_ASN1_ENCODE_INT_BN_FUNC:"000000A321":"020300A321" + +EncodeTemplate BigNumber: high bit is 1 #3 +SDV_BSL_ASN1_ENCODE_INT_BN_FUNC:"a54e1b3861b07e97d99f1746cb0fd4b626e69b8d2c6332492de37429ede5c8910211dd2031e67c7404fa58d97e3df21468af6a92fa60a86a042058d47a19fdea653ce2133ebfa0f6bf2ef2df20dfbdd0ded3cf79de8e1cc1a748af9f7d435a4a08b0579d1a2fdcb7f0e4a4770fb6860d22a8b03709ef80811592a792ea7d58185725d78787f05f83210b42b012b6557ebdb8fe46c6f3f5a78b26840cd951d89681180cc817307eb673edd3e699508456c834112e7e9f121376e5f5060635a9660f50dd938ccd643a61d3cfcd3e1d4c1d751576f029e88a522237d25a7376ab1b8133b75caed8389339613fd39387170137c589a2c5bbafb5b9ab0c48804d2e21":"0282010100a54e1b3861b07e97d99f1746cb0fd4b626e69b8d2c6332492de37429ede5c8910211dd2031e67c7404fa58d97e3df21468af6a92fa60a86a042058d47a19fdea653ce2133ebfa0f6bf2ef2df20dfbdd0ded3cf79de8e1cc1a748af9f7d435a4a08b0579d1a2fdcb7f0e4a4770fb6860d22a8b03709ef80811592a792ea7d58185725d78787f05f83210b42b012b6557ebdb8fe46c6f3f5a78b26840cd951d89681180cc817307eb673edd3e699508456c834112e7e9f121376e5f5060635a9660f50dd938ccd643a61d3cfcd3e1d4c1d751576f029e88a522237d25a7376ab1b8133b75caed8389339613fd39387170137c589a2c5bbafb5b9ab0c48804d2e21" + +EncodeTemplate BITSTRING: unusedBits > 7, fail +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_ASN1_ERR_ENCODE_BIT_STRING:"FF":8:"" + +EncodeTemplate BITSTRING: dataLen = 0 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"":0:"0300" + +EncodeTemplate BITSTRING: unusedBits = 1 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":1:"03030112FE" + +EncodeTemplate BITSTRING: unusedBits = 2 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":2:"03030212FC" + +EncodeTemplate BITSTRING: unusedBits = 3 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":3:"03030312F8" + +EncodeTemplate BITSTRING: unusedBits = 4 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":4:"03030412F0" + +EncodeTemplate BITSTRING: unusedBits = 5 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":5:"03030512E0" + +EncodeTemplate BITSTRING: unusedBits = 6 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":6:"03030612C0" + +EncodeTemplate BITSTRING: unusedBits = 7 +SDV_BSL_ASN1_ENCODE_BITSTRING_FUNC:BSL_SUCCESS:"12FF":7:"0303071280" + +EncodeTemplate UTCTIME: year < 1970, fail +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_UTCTIME:BSL_ASN1_ERR_CHECK_TIME:1969:1:1:1:1:1:"" + +EncodeTemplate UTCTIME: year < 2000, fail +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_UTCTIME:BSL_ASN1_ERR_ENCODE_UTC_TIME:1999:1:1:1:1:1:"" + +EncodeTemplate UTCTIME: year > 2049, fail +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_UTCTIME:BSL_ASN1_ERR_ENCODE_UTC_TIME:2050:1:1:1:1:1:"" + +EncodeTemplate UTCTIME: 2000-1-1 00:00:00 +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_UTCTIME:BSL_SUCCESS:2000:1:1:0:0:0:"170D3030303130313030303030305A" + +EncodeTemplate UTCTIME: 2000-12-12 12:59:59 +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_UTCTIME:BSL_SUCCESS:2000:12:12:12:59:59:"170D3030313231323132353935395A" + +EncodeTemplate UTCTIME: 2048-12-12 12:59:59 +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_UTCTIME:BSL_SUCCESS:2048:12:12:12:59:59:"170D3438313231323132353935395A" + +EncodeTemplate GENERALIZEDTIME: year < 1970, fail +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:BSL_ASN1_ERR_CHECK_TIME:1969:1:1:1:1:1:"" + +EncodeTemplate GENERALIZEDTIME: year > 9999, fail +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:BSL_ASN1_ERR_ENCODE_GENERALIZED_TIME:10000:1:1:1:1:1:"" + +EncodeTemplate GENERALIZEDTIME: 2000-1-1 00:00:00 +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:BSL_SUCCESS:2000:1:1:0:0:0:"180F32303030303130313030303030305A" + +EncodeTemplate GENERALIZEDTIME: 2000-12-12 12:59:59 +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:BSL_SUCCESS:2000:12:12:12:59:59:"180F32303030313231323132353935395A" + +EncodeTemplate GENERALIZEDTIME: 2048-12-12 12:59:59 +SDV_BSL_ASN1_ENCODE_TIME_FUNC:BSL_ASN1_TAG_GENERALIZEDTIME:BSL_SUCCESS:2048:12:12:12:59:59:"180F32303438313231323132353935395A" + +EncodeTemplate multi NULL +SDV_BSL_ASN1_ENCODE_NULL_FUNC_TC001:"300E0500050005003002050030020500" + +EncodeTemplate single NULL +SDV_BSL_ASN1_ENCODE_NULL_FUNC_TC002:"0500" + +EncodeTemplate: test headonly +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC001:"300E0202010030011230011202020100" + +EncodeTemplate: test optional|default #1 +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC002:"":"3006020030020200" + +EncodeTemplate: test optional|default #2 +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC002:"7F":"301802017F02017F02017F300302017F300302017F300302017F" + +EncodeTemplate: Test multi item of depth 0 #1 +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC003:"7F":0:"301002017F02017F300302017F300302017F" + +EncodeTemplate: Test multi item of depth 0 #2 +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC003:"7F":1:"02017F02017F02017F02017F" + +EncodeTemplate: Test multi item of depth 0 #3 +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC003:"7F":2:"300302017F3005300302017F02017F02017F" + +EncodeTemplate: Test multi item of depth 0 #4 +SDV_BSL_ASN1_ENCODE_TEMPLATE_FUNC_TC003:"":2:"30003004300202000200" + +EncodeListItem: Test for illegal parameters. +SDV_BSL_ASN1_ENCODE_LIST_API_TC001: + +EncodeListItem: tag is not expected +SDV_BSL_ASN1_ENCODE_LIST_ERROR_TC001: + +EncodeListItem: asnNum is too small or too large +SDV_BSL_ASN1_ENCODE_LIST_ERROR_TC002: + +EncodeListItem: x509 Name +SDV_BSL_ASN1_ENCODE_LIST_TC001:2:"31143012060355040a130b456e657267792054455354312730250603550403131e456e65726779204543432045717569706d656e7420526f6f742043412031" + +Decode then Encode: rsa pub key +SDV_BSL_ASN1_DECODE_THEN_ENCODE_FUNC_TC001:0:"../testdata/cert/asn1/rsa2048pub_pkcs1.der" + +Decode then Encode: rsa priv key +SDV_BSL_ASN1_DECODE_THEN_ENCODE_FUNC_TC001:1:"../testdata/cert/asn1/rsa2048key_pkcs1.der" + +Encode then Decode: 0101FF 02020100 03030112FE 0500 0C025354 170D3030313231323132353935395A 3003123456 +SDV_BSL_ASN1_ENCODE_THEN_DECODE_FUNC_TC001:1:256:"12FF":1:"5354":2000:12:12:12:59:59:"123456":"30260101FF0202010003030112FE05000C025354170D3030313231323132353935395A3003123456" + +SDV_PKCS7_BMPSTRING_TC001 +SDV_PKCS7_BMPSTRING_TC001:"0055007300650072":"User" + +SDV_PKCS7_BMPSTRING_TC001 +SDV_PKCS7_BMPSTRING_TC001:"0043006500720074006900660069006300610074006500540065006d0070006c006100740065":"CertificateTemplate" + +SDV_PKCS7_BMPSTRING_TC001 +SDV_PKCS7_BMPSTRING_TC001:"0066007200690065006E0064006C0079004E0061006D0065":"friendlyName" diff --git a/testcode/sdv/testcase/bsl/base64/test_suite_sdv_base64.c b/testcode/sdv/testcase/bsl/base64/test_suite_sdv_base64.c new file mode 100644 index 00000000..c5232ccd --- /dev/null +++ b/testcode/sdv/testcase/bsl/base64/test_suite_sdv_base64.c @@ -0,0 +1,898 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_errno.h" +#include "bsl_base64.h" +#include "bsl_uio.h" +#include "bsl_base64.h" + +/* END_HEADER */ +static const uint8_t src_01[] = "123"; +static const char encodeResult_01[] = "MTIz"; + +static const uint8_t src_02[] = "a"; +static const char encodeResult_02[] = "YQ=="; + +static const uint8_t src_03[] = " "; +static const char encodeResult_03[] = "IA=="; + +static const uint8_t src_04[] = "\r"; +static const char encodeResult_04[] = "DQ=="; + +static const uint8_t src_05[] = "\n"; +static const char encodeResult_05[] = "Cg=="; + +static const uint8_t src_06[] = "\r\n"; +static const char encodeResult_06[] = "DQo="; + +static const uint8_t src_07[] = "bas64eVBFH2 46 JF \n 3274jg891 \n 12974"; +static const char encodeResult_07[] = "YmFzNjRlVkJGSDIgNDYgSkYgICAKICAzMjc0amc4OTEgICAgCiAgMTI5NzQ="; + +static const uint8_t src_08[] = "EIR234hdi234 0 idd3 12EH9kfhwu0914l 39u14109u4 8214 klhr184yu h " + "0923174 hfweh7e0124W R2342E\nWF9\niofh392 281h236891FHWY1990hf732"; +static const char encodeResult_08[] = + "RUlSMjM0aGRpMjM0IDAgIGlkZDMgICAgIDEyRUg5a2Zod3UwOTE0bCAgIDM5dTE0MTA5dTQgICAgICAgIDgyMTQga2xocjE4NHl1IGggICAgMDkyMz" + "E3NCBoZndlaDdlMDEyNFcgIFIyMzQyRQpXRjkKaW9maDM5MiAgIDI4MWgyMzY4OTFGSFdZMTk5MGhmNzMy"; +static const char encodeResult_08_withNL[] = + "RUlSMjM0aGRpMjM0IDAgIGlkZDMgICAgIDEyRUg5a2Zod3UwOTE0bCAgIDM5dTE0\nMTA5dTQgICAgICAgIDgyMTQga2xocjE4NHl1IGggICAgMDky" + "MzE3NCBoZndlaDdl\nMDEyNFcgIFIyMzQyRQpXRjkKaW9maDM5MiAgIDI4MWgyMzY4OTFGSFdZMTk5MGhm\nNzMy\n"; +static const char encodeResult_09[] = + "YUVJUjIzNGhkaTIzNCAwICBpZGQzICAgICAxMkVIOWtmaHd1MDkxNGwgICAzOXUx\nNDEwOXU0ICAgICAgICA4MjE0IGtsaHIxODR5dSBoICAgIDA5" + "MjMxNzQgaGZ3ZWg3\nZTAxMjRXICBSMjM0MkUKV0Y5CmlvZmgzOTIgICAyODFoMjM2ODkxRkhXWTE5OTBo\nZjczMmJhczY0ZVZCRkgyIDQ2IEpGIC" + "AgCiAgMzI3NGpnODkxICAgIAogIDEyOTc0\n"; +static const uint8_t src_09[] = "Base64编码和解码测试ChineseVersion"; +static const uint8_t src_10[] = "ZnUzeWU4R0hFNzEzMjY0RU5EUUlZSFI4OWhoODlURjczVUhGRElVSDMyOThZZk5FMzE4aGQyODNlajMwNEg0"; +static const uint8_t src_11[] = + "aEVXVURKRFE5MkVVMTkwMzcxMzBSSkkyM1VSMDkyMzIzNEQyMUUxMjhZM0UxODI5NEVZM05SRDMyUjI0MjM0RkdG"; +static const uint8_t src_12[] = + "ZnUzeWU4R0hFNzEzMjY0RU5EUUlZSFI4OWhoODlURjczVUhGRElVSDMyOThZZk5FMzE4aGQyODNlajMwNEg0emY="; +static const uint8_t src_13[] = "fu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298Yf"; +static const uint8_t src_14[] = "fu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298Yf2"; +static const uint8_t src_15[] = "fu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298Yf2k"; +static const uint8_t src_16[] = "fu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298YfNE318hd283ej304H"; +static const uint8_t src_17[] = "fu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298YfNE318hd283ej304Hf"; +static const uint8_t src_18[] = "fu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298YfNE318hd283ej304Hfe"; +static const uint8_t src_19[] = + "HD13fdwCr23r2t4UI3QW1t2vs23F432R1FChfu3ye8GHE713264ENDQIYHR89hh89TF73UHFDIUH3298Yf23hoifdh3f9832yf3ihnfdkJM32RE832" + "URDOjdjOWIHFD9832RDJkwmdcOJD38E12U38RDHi3ndewifdh3uiry298398r3843nhrdkncihfhHR2398RE2RFQ32"; +typedef struct { + const uint8_t *src; + const uint32_t srcLen; + const char *encodeResult; + const uint32_t encodeResultLen; +} BASE64_TEST_DATA; + +static const BASE64_TEST_DATA testData[] = { + { + .src = src_01, + .srcLen = (const uint32_t)sizeof(src_01) - 1, + .encodeResult = encodeResult_01, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_01) - 1, + }, + { + .src = src_02, + .srcLen = (const uint32_t)sizeof(src_02) - 1, + .encodeResult = encodeResult_02, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_02) - 1, + }, + { + .src = src_03, + .srcLen = (const uint32_t)sizeof(src_03) - 1, + .encodeResult = encodeResult_03, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_03) - 1, + }, + { + .src = src_04, + .srcLen = (const uint32_t)sizeof(src_04) - 1, + .encodeResult = encodeResult_04, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_04) - 1, + }, + { + .src = src_05, + .srcLen = (const uint32_t)sizeof(src_05) - 1, + .encodeResult = encodeResult_05, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_05) - 1, + }, + { + .src = src_06, + .srcLen = (const uint32_t)sizeof(src_06) - 1, + .encodeResult = encodeResult_06, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_06) - 1, + }, + { + .src = src_07, + .srcLen = (const uint32_t)sizeof(src_07) - 1, + .encodeResult = encodeResult_07, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_07) - 1, + }, + { + .src = src_08, + .srcLen = (const uint32_t)sizeof(src_08) - 1, + .encodeResult = encodeResult_08, + .encodeResultLen = (const uint32_t)sizeof(encodeResult_08) - 1, + }, + { + .src = src_09, + .srcLen = (const uint32_t)sizeof(src_09) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_10, + .srcLen = (const uint32_t)sizeof(src_10) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_11, + .srcLen = (const uint32_t)sizeof(src_11) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_12, + .srcLen = (const uint32_t)sizeof(src_12) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_13, + .srcLen = (const uint32_t)sizeof(src_13) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_14, + .srcLen = (const uint32_t)sizeof(src_14) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_15, + .srcLen = (const uint32_t)sizeof(src_15) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_16, + .srcLen = (const uint32_t)sizeof(src_16) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_17, + .srcLen = (const uint32_t)sizeof(src_17) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_18, + .srcLen = (const uint32_t)sizeof(src_18) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, + { + .src = src_19, + .srcLen = (const uint32_t)sizeof(src_19) - 1, + .encodeResult = NULL, + .encodeResultLen = 0, + }, +}; + +static const int32_t testCnt = sizeof(testData) / sizeof(testData[0]); + +/** + * @test SDV_BSL_BASE64_FUNC_TC001 + * @spec - + * @title Block coding/decoding test + * @precon nan + * @brief 1. Call BSL_Base64Encode + 2. Check whether the encoded result is correct. + 3. Call BSL_Base64Decode + 4. Check whether the decoded buffer is the same as the original buffer. + 5. Check whether the decoded buffer length is the same as the original buffer length. + + * @expect 1. BSL_SUCCESS + 2. same + 3. BSL_SUCCESS + 4. same + 5. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC001(void) +{ + TestMemInit(); + for (int32_t i = 0; i < 7; i++) { + const uint8_t *srcBuf = testData[i].src; + const uint32_t srcLen = testData[i].srcLen; + + uint32_t encodeBufLen = HITLS_BASE64_ENCODE_LENGTH(srcLen); + char encodeBuf[encodeBufLen]; + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(encodeBufLen); + uint8_t decodeBuf[decodeBufLen]; + + ASSERT_TRUE(BSL_BASE64_Encode(srcBuf, srcLen, encodeBuf, &encodeBufLen) == BSL_SUCCESS); + ASSERT_TRUE(memcmp((const char *)encodeBuf, testData[i].encodeResult, testData[i].encodeResultLen) == 0); + ASSERT_TRUE(encodeBufLen == testData[i].encodeResultLen); + + ASSERT_TRUE(BSL_BASE64_Decode((const char *)encodeBuf, testData[i].encodeResultLen, decodeBuf, + &decodeBufLen) == BSL_SUCCESS); + ASSERT_TRUE(memcmp((const uint8_t *)decodeBuf, srcBuf, srcLen) == 0); + ASSERT_TRUE(decodeBufLen == srcLen); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC002 + * @spec - + * @title Encoding and decoding test for short input streams without line breaks + * @precon nan + * @brief 1. Call BSL_Base64EncodeInit + 2. Call BSL_Base64EncodeUpdate + 3. Call BSL_Base64EncodeFinal + 4. Check whether the encoded result is correct. + 5. Check whether the encoded length is correct. + 6. Call BSL_Base64DecodeInit + 7. Call BSL_Base64DecodeUpdate + 8. Call BSL_Base64DecodeFinal + 9. Check whether the decoded buffer is the same as the original buffer. + 10. Check whether the decoded buffer length is the same as the original buffer length. + + * @expect 1. BSL_SUCCESS + 2. BSL_SUCCESS + 3. handling the tail + 4. same + 5. same + 6. BSL_SUCCESS + 7. BSL_SUCCESS + 8. BSL_SUCCESS + 9. same + 10. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC002(void) +{ + for (int32_t i = 0; i < 6; i++) { + const uint8_t *srcBuf = testData[i].src; + const uint32_t srcLen = testData[i].srcLen; + + uint32_t encodeBufLen = HITLS_BASE64_ENCODE_LENGTH(srcLen); + char *encodeBuf = malloc(encodeBufLen); + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(encodeBufLen); + uint8_t *decodeBuf = malloc(HITLS_BASE64_DECODE_LENGTH(encodeBufLen)); + + uint32_t tmpLen = encodeBufLen; + uint32_t total = 0; + + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + ASSERT_TRUE(encodeBuf != NULL); + ASSERT_TRUE(decodeBuf != NULL); + BSL_BASE64_EncodeInit(ctx); + BSL_BASE64_SetFlags(ctx, BSL_BASE64_FLAGS_NO_NEWLINE); + ASSERT_TRUE(BSL_BASE64_EncodeUpdate(ctx, srcBuf, srcLen, encodeBuf, &tmpLen) == BSL_SUCCESS); + encodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = encodeBufLen; + ASSERT_TRUE(BSL_BASE64_EncodeFinal(ctx, encodeBuf + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + ASSERT_TRUE(total == testData[i].encodeResultLen); + ASSERT_TRUE(memcmp((const char *)encodeBuf, testData[i].encodeResult, testData[i].encodeResultLen) == 0); + + BSL_BASE64_CtxClear(ctx); + + tmpLen = decodeBufLen; + BSL_BASE64_DecodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, encodeBuf, (const uint32_t)total, decodeBuf, &tmpLen) == BSL_SUCCESS); + total = 0; + decodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = decodeBufLen; + ASSERT_TRUE(BSL_BASE64_DecodeFinal(ctx, decodeBuf + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + ASSERT_TRUE(total == srcLen); + ASSERT_TRUE(memcmp((const uint8_t *)decodeBuf, srcBuf, srcLen) == 0); + + free(encodeBuf); + free(decodeBuf); + BSL_BASE64_CtxFree(ctx); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC003 + * @spec - + * @title Encoding test for long input streams that require line breaks + * @precon nan + * @brief 1. Call BSL_Base64EncodeInit + 2. Call BSL_Base64EncodeUpdate + 3. Call BSL_Base64EncodeFinal + 4. Check whether the encoded result is correct. + 5. Check whether the encoded length is correct. + * @expect 1. BSL_SUCCESS + 2. BSL_SUCCESS + 3. handling the tail + 4. same + 5. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC003(void) +{ + const uint8_t *srcBuf = src_08; + const uint32_t srcLen = (const uint32_t)sizeof(src_08) - 1; + + uint32_t encodeBufLen = HITLS_BASE64_ENCODE_LENGTH(srcLen); + char *encodeBuf = malloc(encodeBufLen); + uint32_t tmpLen = encodeBufLen; + uint32_t total = 0; + + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + ASSERT_TRUE(encodeBuf != NULL); + BSL_BASE64_EncodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_EncodeUpdate(ctx, srcBuf, srcLen, encodeBuf, &tmpLen) == BSL_SUCCESS); + encodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = encodeBufLen; + // encode and check tail for consistency, encodeBuf tail has\n + ASSERT_TRUE(BSL_BASE64_EncodeFinal(ctx, encodeBuf + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + ASSERT_TRUE(total == sizeof(encodeResult_08_withNL) - 1); + ASSERT_TRUE(memcmp((const char *)encodeBuf, encodeResult_08_withNL, total) == 0); +exit: + free(encodeBuf); + BSL_BASE64_CtxFree(ctx); +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC004 + * @spec - + * @title Decoding test for long input streams that require line breaks + * @precon nan + * @brief 1. Call BSL_Base64DecodeInit + 2. Call BSL_Base64DecodeUpdate + 3. Call BSL_Base64DecodeFinal + 4. Check whether the decoded buffer is the same as the original buffer. + 5. Check whether the decoded buffer length is the same as the original buffer length. + * @expect 1. BSL_SUCCESS + 2. BSL_SUCCESS + 3. BSL_SUCCESS + 4. same + 5. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC004(void) +{ + const uint8_t *srcBuf = src_08; + const uint32_t srcLen = (const uint32_t)sizeof(src_08) - 1; + uint32_t encodeBufLen = sizeof(encodeResult_08_withNL) - 1; + + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(encodeBufLen); + uint8_t *decodeBuf = malloc(decodeBufLen); + uint32_t tmpLen = decodeBufLen; + uint32_t total = 0; + + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + ASSERT_TRUE(decodeBuf != NULL); + BSL_BASE64_DecodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, encodeResult_08_withNL, encodeBufLen, decodeBuf, &tmpLen) == BSL_SUCCESS); + encodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = encodeBufLen; + ASSERT_TRUE(BSL_BASE64_DecodeFinal(ctx, decodeBuf + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + ASSERT_TRUE(total == srcLen); + ASSERT_TRUE(memcmp((const uint8_t *)decodeBuf, srcBuf, total) == 0); +exit: + free(decodeBuf); + BSL_BASE64_CtxFree(ctx); +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC005 + * @spec - + * @title Encoding and decoding test of the block that generates errors + * @precon nan + * @brief 1. Call BSL_Base64Encode + 2. Check whether the encoded result is correct. + 3. Call BSL_Base64Decode + 4. Check whether the decoded buffer is the same as the original buffer. + 5. Check whether the decoded buffer length is the same as the original buffer length. + + * @expect 1. BSL_SUCCESS + 2. same + 3. BSL_SUCCESS + 4. same + 5. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC005(void) +{ + const char illEncodeResult[] = "MT-1"; + uint8_t decodeBuf[4] = {0}; + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(4); + ASSERT_TRUE(BSL_BASE64_Decode(illEncodeResult, 4, decodeBuf, &decodeBufLen) != BSL_SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC006 + * @spec - + * @title Stream Decoding Test with Errors + * @precon nan + * @brief 1. Call BSL_Base64DecodeInit + 2. Call BSL_Base64DecodeUpdate + 3. Call BSL_Base64DecodeUpdate + + * @expect 1. BSL_SUCCESS + 2. data after padding error + 3. EOF Error in Middle of Block + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC006(void) +{ + const char illEncodeResult_1[] = "MT=1"; + const char illEncodeResult_2[] = "MT-1"; + const char illEncodeResult_3[] = "MT#1"; + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(4); + uint8_t *decodeBuf = malloc(decodeBufLen); + ASSERT_TRUE(decodeBuf != NULL); + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + BSL_BASE64_SetFlags(ctx, BSL_BASE64_FLAGS_NO_NEWLINE); + + BSL_BASE64_DecodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, illEncodeResult_1, sizeof(illEncodeResult_1), + decodeBuf, &decodeBufLen) == BSL_BASE64_DATA_AFTER_PADDING); + + BSL_BASE64_CtxClear(ctx); + BSL_BASE64_DecodeInit(ctx); + /* If the BSL interface is not invoked to parse the PEM file, the returned value is an error code. */ + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, illEncodeResult_2, sizeof(illEncodeResult_2), + decodeBuf, &decodeBufLen) == BSL_BASE64_HEADER); + + BSL_BASE64_CtxClear(ctx); + BSL_BASE64_DecodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, illEncodeResult_3, sizeof(illEncodeResult_3), + decodeBuf, &decodeBufLen) == BSL_INVALID_ARG); +exit: + free(decodeBuf); + BSL_BASE64_CtxFree(ctx); +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC007 + * @spec - + * @title Empty input test + * @precon nan + * @brief 1. Call BSL_Base64Encode + 2. Call BSL_Base64Encode + 3. Call BSL_Base64Decode + 4. Call BSL_Base64Decode + 5. Call BSL_Base64EncodeUpdate + 6. Call BSL_Base64EncodeFinal + 7. Call BSL_Base64DecodeUpdate + 8. Call BSL_Base64DecodeFinal + + * @expect 1. BSL_NULL_INPUT + 2. dstBufLen is insufficient:BSL_BASE64_BUF_NOT_ENOUGH + 3. BSL_NULL_INPUT + 4. dstBufLen is insufficient:BSL_BASE64_BUF_NOT_ENOUGH + 5. BSL_NULL_INPUT + 6. BSL_SUCCESS + 7. BSL_NULL_INPUT + 8. BSL_SUCCESS + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC007(void) +{ + uint32_t zeroLen = 0; + const uint32_t srcLen = (const uint32_t)sizeof(src_01); + + uint32_t encodeBufLen = HITLS_BASE64_ENCODE_LENGTH(srcLen); + char *encodeBuf = malloc(encodeBufLen); + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(encodeBufLen); + uint8_t *decodeBuf = malloc(decodeBufLen); + ASSERT_TRUE(encodeBuf != NULL); + ASSERT_TRUE(decodeBuf != NULL); + /* Block codec empty input test */ + ASSERT_TRUE(BSL_BASE64_Encode(NULL, zeroLen, encodeBuf, &encodeBufLen) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_BASE64_Encode(src_01, sizeof(src_01) - 1, encodeBuf, &zeroLen) == BSL_BASE64_BUF_NOT_ENOUGH); + ASSERT_TRUE(BSL_BASE64_Decode(NULL, 0, decodeBuf, &decodeBufLen) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_BASE64_Decode(encodeResult_01, 4, decodeBuf, &zeroLen) == BSL_BASE64_BUF_NOT_ENOUGH); + + /* Stream encoding/decoding empty input test */ + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + BSL_BASE64_EncodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_EncodeUpdate(ctx, NULL, zeroLen, encodeBuf, &encodeBufLen) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_BASE64_EncodeFinal(ctx, encodeBuf, &encodeBufLen) == BSL_SUCCESS); + + BSL_BASE64_CtxClear(ctx); + BSL_BASE64_DecodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, NULL, (const uint32_t)encodeBufLen, + decodeBuf, &decodeBufLen) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_BASE64_DecodeFinal(ctx, decodeBuf, &decodeBufLen) == BSL_SUCCESS); +exit: + free(encodeBuf); + free(decodeBuf); + BSL_BASE64_CtxFree(ctx); +} +/* END_CASE */ + +/** + * @test SDV_BSL_BASE64_FUNC_TC008 + * @spec - + * @title Multiple update tests + * @precon nan + * @brief 1. Call BSL_Base64EncodeUpdate + 2. Call BSL_Base64EncodeUpdate + 3. Call BSL_Base64EncodeUpdate + 4. Call BSL_Base64EncodeFinal + 5. Call BSL_Base64DecodeUpdate + 6. Call BSL_Base64DecodeUpdate + 7. Call BSL_Base64DecodeUpdate + 8. Call BSL_Base64DecodeFinal + + * @expect 1. BSL_SUCCESS -> The data is not encoded and is cached in the buffer. dstBufLen is set to 0. + 2. BSL_SUCCESS + 3. BSL_SUCCESS -> 3 + 44 < 48, The srcBuf is shorter than the length of a buffer. The data is cached in the + buffer, and dstBufLen is set to 0. + 4. BSL_SUCCESS -> Handles 3 + 44 characters + 5. BSL_SUCCESS -> Data that is not decoded is stored in the buffer, and dstBufLen is set to 0. + 6. BSL_SUCCESS + 7. BSL_SUCCESS + 8. BSL_SUCCESS + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC008(void) +{ + uint32_t srcLen = testData[0].srcLen + testData[7].srcLen + testData[6].srcLen; + uint32_t encodeBufLen = HITLS_BASE64_ENCODE_LENGTH(srcLen); + char *encodeBuf = malloc(encodeBufLen); + uint32_t decodeBufLen = HITLS_BASE64_DECODE_LENGTH(encodeBufLen); + uint8_t *decodeBuf = malloc(HITLS_BASE64_DECODE_LENGTH(encodeBufLen)); + + /* + * The output parameter dstBufLen needs to be updated in real time when the update operation is performed for + * multiple times. + */ + uint32_t tmpLen = encodeBufLen; + uint32_t total = 0; + ASSERT_TRUE(encodeBuf != NULL); + ASSERT_TRUE(decodeBuf != NULL); + /* encode */ + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + BSL_BASE64_EncodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_EncodeUpdate(ctx, testData[1].src, testData[1].srcLen, encodeBuf, &tmpLen) == + BSL_SUCCESS); /* 1bytes */ + encodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = encodeBufLen; + ASSERT_TRUE(BSL_BASE64_EncodeUpdate(ctx, testData[7].src, testData[7].srcLen, encodeBuf + total, &tmpLen) == + BSL_SUCCESS); /* 147bytes */ + encodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = encodeBufLen; + ASSERT_TRUE(BSL_BASE64_EncodeUpdate(ctx, testData[6].src, testData[6].srcLen, encodeBuf + total, &tmpLen) == + BSL_SUCCESS); /* 44bytes */ + encodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = encodeBufLen; + ASSERT_TRUE(BSL_BASE64_EncodeFinal(ctx, encodeBuf + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + ASSERT_TRUE((sizeof(encodeResult_09) - 1) == total); + ASSERT_TRUE(memcmp((const char *)encodeBuf, encodeResult_09, total) == 0); + + BSL_BASE64_CtxClear(ctx); + + /* decode */ + tmpLen = decodeBufLen; + total = 0; + BSL_BASE64_DecodeInit(ctx); + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, testData[0].encodeResult, + (const uint32_t)testData[0].encodeResultLen, decodeBuf, &tmpLen) == BSL_SUCCESS); /* 4bytes */ + decodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = decodeBufLen; + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, testData[7].encodeResult, + (const uint32_t)testData[7].encodeResultLen, decodeBuf + total, &tmpLen) == BSL_SUCCESS); /* 196bytes */ + decodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = decodeBufLen; + ASSERT_TRUE(BSL_BASE64_DecodeUpdate(ctx, testData[6].encodeResult, + (const uint32_t)testData[6].encodeResultLen, decodeBuf + total, &tmpLen) == BSL_SUCCESS); /* 60bytes */ + decodeBufLen -= tmpLen; + total += tmpLen; + tmpLen = decodeBufLen; + ASSERT_TRUE(BSL_BASE64_DecodeFinal(ctx, decodeBuf + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + ASSERT_TRUE(srcLen == total); +exit: + free(encodeBuf); + free(decodeBuf); + BSL_BASE64_CtxFree(ctx); +} +/* END_CASE */ + +void Base64BlockEncDec(const uint8_t *buf, const uint32_t len) +{ + const uint8_t *src = buf; + const uint32_t srcLen = len; + + uint32_t hitlsEncLen = HITLS_BASE64_ENCODE_LENGTH(len); + char *hitlsEncResult = BSL_SAL_Malloc(hitlsEncLen); + + uint32_t hitlsDecLen = HITLS_BASE64_DECODE_LENGTH(hitlsEncLen); + uint8_t *hitlsDecResult = BSL_SAL_Malloc(hitlsDecLen); + TRUE_OR_EXIT(BSL_BASE64_Encode(src, srcLen, hitlsEncResult, &hitlsEncLen) == BSL_SUCCESS); + + TRUE_OR_EXIT(BSL_BASE64_Decode(hitlsEncResult, hitlsEncLen, hitlsDecResult, &hitlsDecLen) == BSL_SUCCESS); + TRUE_OR_EXIT(hitlsDecLen == srcLen); +exit: + BSL_SAL_Free(hitlsEncResult); + BSL_SAL_Free(hitlsDecResult); +} + +/** + * @test SDV_BSL_BASE64_FUNC_TC009 + * @spec - + * @title Block coding/decoding test + * @precon nan + * @brief 1. Call BSL_Base64Encode/EVP_EncodeBlock + 2. Check whether the encoded result is correct. + 3. Call BSL_Base64Decode/EVP_DecodeBlock + 4. Check whether the decoded buffer is the same as the original buffer. + 5. Check whether the decoded buffer length is the same as the original buffer length. + + * @expect 1. Succeeded + 2. same + 3. Succeeded + 4. same + 5. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC009(void) +{ + Base64BlockEncDec(testData[0].src, testData[0].srcLen); + for (int i = 8; i < testCnt; i++) { + Base64BlockEncDec(testData[i].src, testData[i].srcLen); + } +} +/* END_CASE */ + +void Base64Stream(const uint8_t *buf, const uint32_t len) +{ + const uint8_t *src = buf; + const uint32_t srcLen = len; + + uint32_t hitlsEncLen = HITLS_BASE64_ENCODE_LENGTH(len); + char *hitlsEncResult = BSL_SAL_Malloc(hitlsEncLen); + + uint32_t hitlsDecLen = HITLS_BASE64_DECODE_LENGTH(hitlsEncLen); + uint8_t *hitlsDecResult = BSL_SAL_Malloc(hitlsDecLen); + + /* encode */ + // hitls stream encoding + uint32_t tmpLen = hitlsEncLen; + uint32_t total = 0; + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + BSL_BASE64_EncodeInit(ctx); + TRUE_OR_EXIT(BSL_BASE64_EncodeUpdate(ctx, src, srcLen, hitlsEncResult, &tmpLen) == BSL_SUCCESS); + hitlsEncLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsEncLen; + TRUE_OR_EXIT(BSL_BASE64_EncodeFinal(ctx, hitlsEncResult + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + /* decode */ + // hitls stream encoding + BSL_BASE64_CtxClear(ctx); + tmpLen = hitlsDecLen; + BSL_BASE64_DecodeInit(ctx); + TRUE_OR_EXIT(BSL_BASE64_DecodeUpdate(ctx, hitlsEncResult, (const uint32_t)total, hitlsDecResult, &tmpLen) == + BSL_SUCCESS); + total = 0; + hitlsDecLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsDecLen; + TRUE_OR_EXIT(BSL_BASE64_DecodeFinal(ctx, hitlsDecResult + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + +exit: + BSL_SAL_Free(hitlsEncResult); + BSL_SAL_Free(hitlsDecResult); + BSL_BASE64_CtxFree(ctx); +} + +/** + * @test SDV_BSL_BASE64_FUNC_TC010 + * @spec - + * @title Single-flow encoding/decoding test + * @precon nan + * @brief 1. Call BSL_Base64EncodeInit/EVP_EncodeInit + 2. Call BSL_Base64EncodeUpdate/EVP_EncodeUpdate + 3. Call BSL_Base64EncodeFinal/EVP_EncodeFinal + 4. Check whether the encoded result is correct. + 5. Check whether the encoded length is correct. + 6. Call BSL_Base64DecodeInit/EVP_DecodeInit + 7. Call BSL_Base64DecodeUpdate/EVP_DecodeUpdate + 8. Call BSL_Base64DecodeFinal/EVP_DecodeFinal + 9. Check whether the decoded buffer is the same as the original buffer. + 10. Check whether the decoded buffer length is the same as the original buffer length. + + * @expect 1. Succeeded + 2. BSL_SUCCESS + 3. handling the tail + 4. same + 5. same + 6. Succeeded + 7. BSL_SUCCESS + 8. BSL_SUCCESS + 9. same + 10. same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC010(void) +{ + for (int i = 0; i < testCnt; i++) { + Base64Stream(testData[i].src, testData[i].srcLen); + } +} +/* END_CASE */ + +void Base64StreamMultiUpdate(const BASE64_TEST_DATA data[]) +{ + uint32_t hitlsEncLen = HITLS_BASE64_ENCODE_LENGTH(512); + char *hitlsEncResult = malloc(hitlsEncLen); + + uint32_t hitlsDecLen = HITLS_BASE64_DECODE_LENGTH(hitlsEncLen); + uint8_t *hitlsDecResult = malloc(hitlsDecLen); + /* encode */ + // hitls stream encoding + uint32_t tmpLen = hitlsEncLen; + uint32_t total = 0; + BSL_Base64Ctx *ctx = BSL_BASE64_CtxNew(); + ASSERT_TRUE(hitlsEncResult != NULL); + ASSERT_TRUE(hitlsDecResult != NULL); + BSL_BASE64_EncodeInit(ctx); + TRUE_OR_EXIT(BSL_BASE64_EncodeUpdate(ctx, data[12].src, data[12].srcLen, hitlsEncResult, &tmpLen) == BSL_SUCCESS); + hitlsEncLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsEncLen; + TRUE_OR_EXIT(BSL_BASE64_EncodeUpdate(ctx, data[13].src, data[13].srcLen, hitlsEncResult + total, &tmpLen) == + BSL_SUCCESS); + hitlsEncLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsEncLen; + TRUE_OR_EXIT(BSL_BASE64_EncodeUpdate(ctx, data[14].src, data[14].srcLen, hitlsEncResult + total, &tmpLen) == + BSL_SUCCESS); + hitlsEncLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsEncLen; + TRUE_OR_EXIT(BSL_BASE64_EncodeFinal(ctx, hitlsEncResult + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + + /* decode */ + // hitls stream encoding + BSL_BASE64_CtxClear(ctx); + total = 0; + tmpLen = hitlsDecLen; + BSL_BASE64_DecodeInit(ctx); + TRUE_OR_EXIT(BSL_BASE64_DecodeUpdate(ctx, (const char *)data[9].src, data[9].srcLen, hitlsDecResult, &tmpLen) == + BSL_SUCCESS); + hitlsDecLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsDecLen; + TRUE_OR_EXIT(BSL_BASE64_DecodeUpdate(ctx, (const char *)data[10].src, data[10].srcLen, hitlsDecResult + total, + &tmpLen) == BSL_SUCCESS); + hitlsDecLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsDecLen; + TRUE_OR_EXIT(BSL_BASE64_DecodeUpdate(ctx, (const char *)data[11].src, data[11].srcLen, hitlsDecResult + total, + &tmpLen) == BSL_SUCCESS); + hitlsDecLen -= tmpLen; + total += tmpLen; + tmpLen = hitlsDecLen; + TRUE_OR_EXIT(BSL_BASE64_DecodeFinal(ctx, hitlsDecResult + total, &tmpLen) == BSL_SUCCESS); + total += tmpLen; + +exit: + free(hitlsEncResult); + free(hitlsDecResult); + BSL_BASE64_CtxFree(ctx); +} + +/** + * @test SDV_BSL_BASE64_FUNC_TC011 + * @spec - + * @title Multiple update tests + * @precon nan + * @brief 1. Call BSL_Base64EncodeUpdate/EVP_EncodeUpdate + 2. Call BSL_Base64EncodeUpdate/EVP_EncodeUpdate + 3. Call BSL_Base64EncodeUpdate/EVP_EncodeUpdate + 4. Call BSL_Base64EncodeFinal/EVP_EncodeFinal + 5. memcmp encode result + 6. Call BSL_Base64DecodeUpdate/EVP_DecodeUpdate + 7. Call BSL_Base64DecodeUpdate/EVP_DecodeUpdate + 8. Call BSL_Base64DecodeUpdate/EVP_DecodeUpdate + 9. Call BSL_Base64DecodeFinal/EVP_DecodeFinal + 10. memcmp decode result + * @expect 1.2.3.4. succeeded + 5.same + 6.7.8.9. succeeded + 10.same + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC011(void) +{ + Base64StreamMultiUpdate(testData); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_BASE64_FUNC_TC012(char *src, int expectRes) +{ + uint32_t srcBufLen = strlen(src); + uint32_t dstBufLen = HITLS_BASE64_DECODE_LENGTH(srcBufLen); + uint8_t *dst = BSL_SAL_Malloc(dstBufLen); + ASSERT_TRUE(dst != NULL); + ASSERT_EQ(BSL_BASE64_Decode(src, srcBufLen, dst, &dstBufLen), (int32_t)expectRes); +exit: + BSL_SAL_Free(dst); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/base64/test_suite_sdv_base64.data b/testcode/sdv/testcase/bsl/base64/test_suite_sdv_base64.data new file mode 100644 index 00000000..55a3a1e6 --- /dev/null +++ b/testcode/sdv/testcase/bsl/base64/test_suite_sdv_base64.data @@ -0,0 +1,47 @@ +SDV_BSL_BASE64_FUNC_TC001 +SDV_BSL_BASE64_FUNC_TC001: + +SDV_BSL_BASE64_FUNC_TC002 +SDV_BSL_BASE64_FUNC_TC002: + +SDV_BSL_BASE64_FUNC_TC003 +SDV_BSL_BASE64_FUNC_TC003: + +SDV_BSL_BASE64_FUNC_TC004 +SDV_BSL_BASE64_FUNC_TC004: + +SDV_BSL_BASE64_FUNC_TC005 +SDV_BSL_BASE64_FUNC_TC005: + +SDV_BSL_BASE64_FUNC_TC006 +SDV_BSL_BASE64_FUNC_TC006: + +SDV_BSL_BASE64_FUNC_TC007 +SDV_BSL_BASE64_FUNC_TC007: + +SDV_BSL_BASE64_FUNC_TC008 +SDV_BSL_BASE64_FUNC_TC008: + +SDV_BSL_BASE64_FUNC_TC009 +SDV_BSL_BASE64_FUNC_TC009: + +SDV_BSL_BASE64_FUNC_TC010 +SDV_BSL_BASE64_FUNC_TC010: + +SDV_BSL_BASE64_FUNC_TC011 +SDV_BSL_BASE64_FUNC_TC011: + +SDV_BSL_BASE64_FUNC_TC012 +SDV_BSL_BASE64_FUNC_TC012:"aEVXVURKRFE5MkVVMTkwMzcxMzBSSkkyM1VSMDkyMzIzNEQy":BSL_SUCCESS + +SDV_BSL_BASE64_FUNC_TC012 +SDV_BSL_BASE64_FUNC_TC012:"aEVXVURKRFE5MkVVMTkwMzcxMzBSSkkyM1VSMDkyMzIzNEQyMU":BSL_BASE64_INVALID_ENCODE + +SDV_BSL_BASE64_FUNC_TC012 +SDV_BSL_BASE64_FUNC_TC012:"aEVXVURKRFE5MkVVMTkwMzcxMzBSSkkyM1VSMDkyMzIzNEQyMU==":BSL_SUCCESS + +SDV_BSL_BASE64_FUNC_TC012 +SDV_BSL_BASE64_FUNC_TC012:"aEVXVURKRFE5MkVVMTkwMzcxMzBSSkkyM1VSMDkyMzIzNEQyMU=\n =":BSL_BASE64_INVALID_CHARACTER + +SDV_BSL_BASE64_FUNC_TC012 +SDV_BSL_BASE64_FUNC_TC012:"aEVXVURKRFE5MkVVMTkwMzcxMzBSSkkyM1VSMDkyMzIzNEQyMU=":BSL_BASE64_INVALID_CHARACTER diff --git a/testcode/sdv/testcase/bsl/err/test_suite_sdv_err.c b/testcode/sdv/testcase/bsl/err/test_suite_sdv_err.c new file mode 100644 index 00000000..9bdb1282 --- /dev/null +++ b/testcode/sdv/testcase/bsl/err/test_suite_sdv_err.c @@ -0,0 +1,639 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_err.h" +#include "avl.h" +#include "bsl_uio.h" + +static int32_t PthreadRWLockNew(BSL_SAL_ThreadLockHandle *lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + pthread_rwlock_t *newLock; + newLock = (pthread_rwlock_t *)BSL_SAL_Malloc(sizeof(pthread_rwlock_t)); + if (newLock == NULL) { + return BSL_MALLOC_FAIL; + } + if (pthread_rwlock_init(newLock, NULL) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + *lock = newLock; + return BSL_SUCCESS; +} + +static void PthreadRWLockFree(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return; + } + pthread_rwlock_destroy((pthread_rwlock_t *)lock); + BSL_SAL_FREE(lock); +} + +static int32_t PthreadRWLockReadLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_rdlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t PthreadRWLockWriteLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_wrlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t PthreadRWLockUnlock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_unlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static uint64_t PthreadGetId(void) +{ + return (uint64_t)pthread_self(); +} + +static void PushErrorFixTimes(int32_t times) +{ + while (times) { + BSL_ERR_PUSH_ERROR(times); + times--; + } +} + +static void RegThreadFunc(void) +{ + BSL_SAL_ThreadCallback cb; + cb.pfThreadLockNew = PthreadRWLockNew; + cb.pfThreadLockFree = PthreadRWLockFree; + cb.pfThreadReadLock = PthreadRWLockReadLock; + cb.pfThreadWriteLock = PthreadRWLockWriteLock; + cb.pfThreadUnlock = PthreadRWLockUnlock; + cb.pfThreadGetId = PthreadGetId; + BSL_SAL_RegThreadCallback(&cb); +} + +/* END_HEADER */ + +/** + * @test SDV_BSL_ERR_FUNC_TC001 + * @title Error code test in single-thread mode + * @precon Set the memory allocation and release functions. + * @brief + * 1. Initializes BSL_ERR. Expected result 1 is obtained. + * 2. Invoke the interface to obtain the error when no error is pushed. Expected result 2 is obtained. + * 3. Push an BSL_UIO_FAIL error when no memory function is registered. Expected result 3 is obtained. + * 4. Push the BSL_UIO_FAIL and BSL_UIO_IO_EXCEPTION error and obtain last error. Expected result 4 is obtained. + * 5. Peek last error file and error line. Expected result 5 is obtained. + * 6. Get last error file and error line. Expected result 6 is obtained. + * 7. Push an error after clear the error stack, and then obtain the error. Expected result 7 is obtained. + * 8. Delete the error stack of the thread. Expected result 8 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_SUCCESS + * 3. BSL_UIO_FAIL + * 4. BSL_UIO_IO_EXCEPTION + * 5. BSL_UIO_FAIL + * 6. BSL_UIO_FAIL + * 7. BSL_SUCCESS + * 8. BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_FUNC_TC001(void) +{ + TestMemInit(); + int32_t err; + + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + + /* no error is pushed */ + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); + + /* If no memory function is registered, push an error and allocate an error stack. */ + BSL_ERR_PushError(BSL_UIO_FAIL, __FILENAME__, __LINE__); + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_UIO_FAIL); + + /* Push the BSL_UIO_FAIL and BSL_UIO_IO_EXCEPTION error to the error stack. */ + BSL_ERR_PushError(BSL_UIO_FAIL, __FILENAME__, __LINE__); + BSL_ERR_PushError(BSL_UIO_IO_EXCEPTION, __FILENAME__, __LINE__); + err = BSL_ERR_GetLastError(); + ASSERT_TRUE(err == BSL_UIO_IO_EXCEPTION); + + const char *file = NULL; + uint32_t line = 0; + err = BSL_ERR_PeekLastErrorFileLine(&file, &line); + ASSERT_TRUE(err == BSL_UIO_FAIL); + ASSERT_TRUE(strcmp(file, __FILENAME__) == 0); + + file = NULL; + line = 0; + err = BSL_ERR_GetLastErrorFileLine(&file, &line); + ASSERT_TRUE(err == BSL_UIO_FAIL); + ASSERT_TRUE(strcmp(file, __FILENAME__) == 0); + + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); + + BSL_ERR_PushError(BSL_UIO_FAIL, __FILENAME__, __LINE__); + BSL_ERR_ClearError(); + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); + + BSL_ERR_RemoveErrorStack(false); + + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); +exit: + BSL_ERR_DeInit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_STACK_FUNC_TC001 + * @title After stacks are not pushed or cleared, call BSL_ERR_GetLastError to query all error stacks. + * @precon nan + * @brief + * 1. Call BSL_SAL_RegMemCallback to initialize the memory. Expected result 1 is obtained. + * 2. Call BSL_SAL_RegThreadCallback to initialize the thread. Expected result 2 is obtained. + * 3. Call BSL_ERR_Init for initialization. Expected result 3 is obtained. + * 4. Call BSL_ERR_GetLastError to obtain stack information. Expected result 4 is obtained. + * 5. Call ERR_PUSH_ERROR to push stack layer 5. Expected result 5 is obtained. + * 6. Call BSL_ERR_ClearError to clear the stack. Expected result 6 is obtained. + * 7. Call BSL_ERR_GetLastError to obtain stack information. Expected result 7 is obtained. + * 8. Call BSL_ERR_RemoveErrorStack to delete the stack. Expected result 8 is obtained. + * 9. Call BSL_ERR_GetLastError to obtain stack information. Expected result 9 is obtained. + * 10. Call BSL_ERR_DeInit to deinitialize. Expected result 10 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_SUCCESS + * 3. BSL_SUCCESS + * 4. BSL_SUCCESS is returned when the error code is obtained. + * 5. BSL_SUCCESS + * 6. BSL_SUCCESS + * 7. BSL_SUCCESS is returned when the error code is obtained. + * 8. BSL_SUCCESS + * 9. BSL_SUCCESS is returned when the error code is obtained. + * 10. BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_STACK_FUNC_TC001(int isRemoveAll) +{ + TestMemInit(); + BSL_SAL_ThreadCallback cb; + cb.pfThreadLockNew = PthreadRWLockNew; + cb.pfThreadLockFree = PthreadRWLockFree; + cb.pfThreadReadLock = PthreadRWLockReadLock; + cb.pfThreadWriteLock = PthreadRWLockWriteLock; + cb.pfThreadUnlock = PthreadRWLockUnlock; + cb.pfThreadGetId = PthreadGetId; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SUCCESS); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); + PushErrorFixTimes(5); + ASSERT_TRUE(BSL_ERR_PeekLastErrorFileLine(NULL, NULL) == 1); + ASSERT_TRUE(BSL_ERR_GetLastErrorFileLine(NULL, NULL) == 1); + ASSERT_TRUE(BSL_ERR_GetErrorFileLine(NULL, NULL) == 5); + BSL_ERR_ClearError(); + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); + BSL_ERR_RemoveErrorStack((isRemoveAll == 1) ? true : false); + ASSERT_TRUE(BSL_ERR_GetLastError() == BSL_SUCCESS); + + BSL_ERR_PushError(1, "2", 3); + uint32_t lineNo = 0; + char *file = NULL; + ASSERT_TRUE(BSL_ERR_PeekLastErrorFileLine(NULL, &lineNo) == 1); + ASSERT_TRUE(lineNo == 0); + ASSERT_TRUE(BSL_ERR_PeekErrorFileLine(NULL, &lineNo) == 1); + ASSERT_TRUE(lineNo == 0); + ASSERT_TRUE(BSL_ERR_PeekLastErrorFileLine((const char **)&file, &lineNo) == 1); + ASSERT_TRUE(strcmp(file, "2") == 0); + ASSERT_TRUE(lineNo == 3); + lineNo = 0; + ASSERT_TRUE(BSL_ERR_PeekErrorFileLine((const char **)&file, &lineNo) == 1); + ASSERT_TRUE(strcmp(file, "2") == 0); + ASSERT_TRUE(lineNo == 3); + ASSERT_TRUE(BSL_ERR_GetError() == 1); + BSL_ERR_PUSH_ERROR(BSL_SUCCESS); + + lineNo = 0; + BSL_ERR_PushError(1, NULL, 3); + ASSERT_TRUE(BSL_ERR_PeekLastErrorFileLine(NULL, &lineNo) == 1); + ASSERT_TRUE(lineNo == 0); + ASSERT_TRUE(BSL_ERR_PeekErrorFileLine(NULL, &lineNo) == 1); + ASSERT_TRUE(lineNo == 0); + ASSERT_TRUE(BSL_ERR_PeekLastErrorFileLine((const char **)&file, &lineNo) == 1); + ASSERT_TRUE(strcmp(file, "NA") == 0); + ASSERT_TRUE(lineNo == 0); + ASSERT_TRUE(BSL_ERR_PeekErrorFileLine((const char **)&file, &lineNo) == 1); + ASSERT_TRUE(strcmp(file, "NA") == 0); + ASSERT_TRUE(lineNo == 0); +exit: + BSL_ERR_ClearError(); + BSL_ERR_DeInit(); +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_COMPATIBILITY_FUNC_TC001 + * @title Test the compatibility of the err module in different CMake versions. + * @precon Set the memory allocation and release functions. + * @brief + * 1. Initializes BSL_ERR. Expected result 1 is obtained. + * 2. Construct an exception to trigger the ERR module to push the stack. Expected result 2 is obtained. + * 3. Obtains the push-stack information, Expected result 3 and 4 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_NULL_INPUT + * 3. "uio_abstraction.c" + * 4. BSL_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_COMPATIBILITY_FUNC_TC001(void) +{ +#ifndef HITLS_BSL_UIO_PLT + SKIP_TEST(); +#else + TestMemInit(); + BSL_SAL_ThreadCallback cb; + cb.pfThreadLockNew = PthreadRWLockNew; + cb.pfThreadLockFree = PthreadRWLockFree; + cb.pfThreadReadLock = PthreadRWLockReadLock; + cb.pfThreadWriteLock = PthreadRWLockWriteLock; + cb.pfThreadUnlock = PthreadRWLockUnlock; + cb.pfThreadGetId = PthreadGetId; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SUCCESS); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + // Construct an exception to trigger the error code module to push the stack. + ASSERT_TRUE(BSL_UIO_SetMethodType(NULL, 1) == BSL_NULL_INPUT); + char *file = NULL; + uint32_t line = 0; + int32_t err = BSL_ERR_GetLastErrorFileLine((const char **)&file, &line); + ASSERT_TRUE(strcmp(file, "uio_abstraction.c") == 0); + ASSERT_TRUE(err == BSL_NULL_INPUT); +exit: + BSL_ERR_ClearError(); + BSL_ERR_DeInit(); +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_STACK_API_TC001 + * @title BSL_ERR_ClearError interface testing + * @precon nan + * @brief + * 1.Call BSL_ERR_RemoveErrorStack to delete the stack. Expected result 2 is obtained. + * 2.Call BSL_ERR_ClearError to clear the stack. Expected result 3 is obtained. + * 3.Call BSL_ERR_ClearError repeatedly to clear the stack. Expected result 4 is obtained. + * @expect + * 1.BSL_SUCCESS + * 2.SUCCESS + * 3.SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_STACK_API_TC001(int isRemoveAll) +{ + TestMemInit(); + BSL_SAL_ThreadCallback cb; + cb.pfThreadLockNew = PthreadRWLockNew; + cb.pfThreadLockFree = PthreadRWLockFree; + cb.pfThreadReadLock = PthreadRWLockReadLock; + cb.pfThreadWriteLock = PthreadRWLockWriteLock; + cb.pfThreadUnlock = PthreadRWLockUnlock; + cb.pfThreadGetId = PthreadGetId; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SUCCESS); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + + BSL_ERR_RemoveErrorStack((isRemoveAll == 1) ? true : false); + BSL_ERR_ClearError(); + BSL_ERR_ClearError(); +exit: + BSL_ERR_DeInit(); +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_MARK_FUNC_TC001 + * @title Registering and Obtaining Error Descriptions + * @precon nan + * @brief + * 1. Set flags. Expected result 1 is obtained. + * 2. Push the error code on the stack. If no flag is set, invoke the pop to mark interface + * and obtain the latest error code. Expected result 2 is obtained. + * 3. Push three error codes into the stack and set a flag for the second error code. Expected result 3 is obtained. + * 4. Push three error codes into the stack, set flags for the second and third error codes, clear the latest flag, + * and invoke pop to mark to obtain the latest error code. Expected result 4 is obtained. + * @expect + * 1. Return BSL_ERR_ERR_NO_ERROR. + * 2. Return BSL_ERR_ERR_NO_MARK, and the error code is 0. + * 3. The flag is set successfully. The second error code is returned + * when the latest error code is obtained for the first time. + * The first error code is returned when the latest error code is obtained for the second time. + * 4. The latest error code is the second error code. + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_MARK_FUNC_TC001(void) +{ + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + int32_t ret; + + ret = BSL_ERR_SetMark(); + ASSERT_TRUE(ret == BSL_ERR_ERR_NO_STACK); + + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_BUSY); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + ret = BSL_ERR_PopToMark(); + ASSERT_TRUE(ret == BSL_ERR_ERR_NO_MARK); + ret = BSL_ERR_GetLastError(); + ASSERT_TRUE(ret == BSL_SUCCESS); + + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_BUSY); + ret = BSL_ERR_SetMark(); + ASSERT_TRUE(ret == BSL_SUCCESS); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + ret = BSL_ERR_PopToMark(); + ASSERT_TRUE(ret == BSL_SUCCESS); + ret = BSL_ERR_GetLastError(); + ASSERT_TRUE(ret == BSL_UIO_IO_BUSY); + ret = BSL_ERR_GetLastError(); + ASSERT_TRUE(ret == BSL_UIO_FAIL); + ret = BSL_ERR_GetLastError(); + ASSERT_TRUE(ret == BSL_SUCCESS); + + BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_BUSY); + ret = BSL_ERR_SetMark(); + ASSERT_TRUE(ret == BSL_SUCCESS); + BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION); + ret = BSL_ERR_SetMark(); + ASSERT_TRUE(ret == BSL_SUCCESS); + ret = BSL_ERR_ClearLastMark(); + ASSERT_TRUE(ret == BSL_SUCCESS); + ret = BSL_ERR_PopToMark(); + ASSERT_TRUE(ret == BSL_SUCCESS); + ret = BSL_ERR_GetLastError(); + ASSERT_TRUE(ret == BSL_UIO_IO_BUSY); +exit: + BSL_ERR_DeInit(); +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_STRING_FUNC_TC001 + * @title Registering and Obtaining Error Descriptions + * @precon nan + * @brief + * 1. The registration list is empty. Expected result 1 is obtained. + * 2. The registration list is not empty. The number of registrations is 0. Expected result 2 is obtained. + * 3. The registration list is not empty, and the number of registrations is 2. Expected result 3 is obtained. + * 4. Obtains the first error description. Expected result 4 is obtained. + * 5. Obtains the second error description. Expected result 5 is obtained. + * @expect + * 1. Return BSL_NULL_INPUT. + * 2. Return BSL_NULL_INPUT. + * 3. Return BSL_SUCCESS. + * 4. The result is the first error description. + * 5. The result is the second error description. + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_STRING_FUNC_TC001(void) +{ + RegThreadFunc(); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + + ASSERT_TRUE(BSL_ERR_AddErrStringBatch(NULL, 0) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_ERR_AddErrStringBatch((void *)-1, 0) == BSL_NULL_INPUT); + + const char *uioFail = "uio is failed"; + const char *tlvFail = "tlv needed type"; + const BSL_ERR_Desc descList[] = { + {BSL_UIO_FAIL, uioFail}, + {BSL_TLV_ERR_NO_WANT_TYPE, tlvFail}, + }; + ASSERT_TRUE(BSL_ERR_AddErrStringBatch(descList, 2) == BSL_SUCCESS); + ASSERT_TRUE(BSL_ERR_GetString(BSL_UIO_FAIL) == uioFail); + ASSERT_TRUE(BSL_ERR_GetString(BSL_TLV_ERR_NO_WANT_TYPE) == tlvFail); +exit: + BSL_ERR_RemoveErrStringBatch(); + BSL_ERR_DeInit(); +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_AVLLR_FUNC_TC001 + * @title A balanced binary tree is unbalanced due to insertion of nodes into the right subtree of the left subtree, and thus rotated to balance the test. + * @brief + * 1. insert 100 + * 2. insert 120 + * 3. insert 80 + * 4. insert 70 + * 5. insert 90 + * 6. insert 85 + * 7. delete 90 + * 8. delete 200 + * 9. delete 100 + * 10. delete 120 + * @expect + * 1. root node is 100 + * 2. root node is 100 + * 3. root node is 100 + * 4. root node is 100 + * 5. root node is 100 + * 6. root node is 90 + * 7. root node is 85 + * 8. root node is 85 + * 9. root node is 85 + * 10. root node is 80 + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_AVLLR_FUNC_TC001(void) +{ + TestMemInit(); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + + BSL_AvlTree *root = NULL; + + root = BSL_AVL_InsertNode(root, 100, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 120, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 80, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 70, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 90, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 85, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 90); + + root = BSL_AVL_DeleteNode(root, 90, NULL); + ASSERT_TRUE(root->nodeId == 85); + root = BSL_AVL_DeleteNode(root, 200, NULL); + ASSERT_TRUE(root->nodeId == 85); + root = BSL_AVL_DeleteNode(root, 100, NULL); + ASSERT_TRUE(root->nodeId == 85); + root = BSL_AVL_DeleteNode(root, 120, NULL); + ASSERT_TRUE(root->nodeId == 80); + + BSL_AVL_DeleteTree(root, NULL); + +exit: + BSL_ERR_DeInit(); +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_AVLLL_FUNC_TC001 + * @title A balanced binary tree is unbalanced due to insertion of nodes into the left subtree of the left subtree, and thus rotated to balance the test. + * @brief + * 1. insert 100 + * 2. insert 120 + * 3. insert 80 + * 4. insert 70 + * 5. insert 90 + * 6. insert 65 + * 7. find 90 + * 8. find 67 + * 9. delete 70 + * 10. delete 65 + * @expect + * 1. root node is 100 + * 2. root node is 100 + * 3. root node is 100 + * 4. root node is 100 + * 5. root node is 100, the structure of the tree is + 100 + / \ + / \ + 80 120 + / \ + 70 90 + * 6. root node is 80, the structure of the tree is + 80 + / \ + / \ + 70 100 + / / \ + 65 90 120 + * 7. find + * 8. Couldn't find + * 9. root node is 80 + * 10. root node is 100 + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_AVLLL_FUNC_TC001(void) +{ + TestMemInit(); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + BSL_AvlTree *root = NULL; + + root = BSL_AVL_InsertNode(root, 100, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 120, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 80, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 70, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 90, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 65, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 80); + + ASSERT_TRUE(BSL_AVL_SearchNode(root, 90) != NULL); + ASSERT_TRUE(BSL_AVL_SearchNode(root, 67) == NULL); + + root = BSL_AVL_DeleteNode(root, 70, NULL); + ASSERT_TRUE(root->nodeId == 80); + root = BSL_AVL_DeleteNode(root, 65, NULL); + ASSERT_TRUE(root->nodeId == 100); + + BSL_AVL_DeleteTree(root, NULL); + +exit: + BSL_ERR_DeInit(); +} +/* END_CASE */ + +/** + * @test SDV_BSL_ERR_AVLRL_FUNC_TC001 + * @title A balanced binary tree is unbalanced due to insertion of nodes into the left subtree of the right subtree, and thus rotated to balance the test. + * @brief + * 1. insert 100 + * 2. insert 80 + * 3. insert 120 + * 4. insert 110 + * 5. insert 130 + * 6. insert 105 + * @expect + * 1. root node is 100 + * 2. root node is 100 + * 3. root node is 100 + * 4. root node is 100 + * 5. root node is 100 + * 6. root node is 110 + */ +/* BEGIN_CASE */ +void SDV_BSL_ERR_AVLRL_FUNC_TC001(void) +{ + TestMemInit(); + ASSERT_TRUE(BSL_ERR_Init() == BSL_SUCCESS); + BSL_AvlTree *root = NULL; + + root = BSL_AVL_InsertNode(root, 100, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 80, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 120, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 110, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 130, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 100); + root = BSL_AVL_InsertNode(root, 105, BSL_AVL_MakeLeafNode(NULL)); + ASSERT_TRUE(root->nodeId == 110); + + BSL_AVL_DeleteTree(root, NULL); + +exit: + BSL_ERR_DeInit(); +} +/* END_CASE */ + + diff --git a/testcode/sdv/testcase/bsl/err/test_suite_sdv_err.data b/testcode/sdv/testcase/bsl/err/test_suite_sdv_err.data new file mode 100644 index 00000000..ca2090ce --- /dev/null +++ b/testcode/sdv/testcase/bsl/err/test_suite_sdv_err.data @@ -0,0 +1,32 @@ +SDV_BSL_ERR_FUNC_TC001 +SDV_BSL_ERR_FUNC_TC001: + +After the stack is not pushed or cleared, call BSL_ERR_GetLastError to query all error stacks. +SDV_BSL_ERR_STACK_FUNC_TC001:0 + +After the stack is not pushed or cleared, call BSL_ERR_GetLastError to query all error stacks. +SDV_BSL_ERR_STACK_FUNC_TC001:1 + +Testing CMake Compatibility +SDV_BSL_ERR_COMPATIBILITY_FUNC_TC001: + +BSL_ERR_ClearError Interface Test +SDV_BSL_ERR_STACK_API_TC001:0 + +BSL_ERR_ClearError Interface Test +SDV_BSL_ERR_STACK_API_TC001:1 + +SDV_BSL_ERR_MARK_FUNC_TC001 +SDV_BSL_ERR_MARK_FUNC_TC001: + +SDV_BSL_ERR_STRING_FUNC_TC001 +SDV_BSL_ERR_STRING_FUNC_TC001: + +AVL LL test +SDV_BSL_ERR_AVLLL_FUNC_TC001: + +AVL LR test +SDV_BSL_ERR_AVLLR_FUNC_TC001: + +AVL RL test +SDV_BSL_ERR_AVLRL_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/hash/test_suite_sdv_hash.c b/testcode/sdv/testcase/bsl/hash/test_suite_sdv_hash.c new file mode 100644 index 00000000..80ae9e2d --- /dev/null +++ b/testcode/sdv/testcase/bsl/hash/test_suite_sdv_hash.c @@ -0,0 +1,346 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "bsl_errno.h" +#include "list_base.h" +#include "bsl_hash.h" +#include "bsl_hash_list.h" +#include "bsl_sal.h" + +#define BACKET_SIZE 64 +#define MAX_NAME_LEN 64 + +typedef struct userData { + int id; + const char name[MAX_NAME_LEN]; +} UserData; + +void *UserHashKeyDupFunc(void *src, size_t size) +{ + char *retKey; + char *tmpKey = (char *)src; + + if (size > MAX_NAME_LEN) { + return NULL; + } + + retKey = (char *)BSL_SAL_Calloc(1, size); + ASSERT_TRUE((char *)retKey != (char *)NULL); + ASSERT_TRUE(strcpy_s(retKey, size, tmpKey) == EOK); + +exit: + return (void *)retKey; +} + +void *UserHashDataDupFunc(void *src, size_t size) +{ + UserData *ret = NULL; + UserData *tmpSrc = (UserData *)src; + + ret = (UserData *)BSL_SAL_Calloc(1, sizeof(UserData)); + ASSERT_TRUE(ret != (UserData *)NULL); + ASSERT_TRUE(memcpy_s(ret, size + 1, tmpSrc, size) == EOK); + +exit: + return ret; +} + +int UserDataCmpFunc(uintptr_t data1, uintptr_t data2) +{ + return strcmp((const char*)data1, (const char*)data2); +} + +void BslListFreeFunc(void *data) +{ + if (data != NULL) { + BSL_SAL_Free(data); + } +} + +bool ListNodeCmpFunc(const void *node, uintptr_t data) +{ + const ListRawNode *t = (ListRawNode *)node; + return (uintptr_t)(t->prev) == data; +} + +/* END_HEADER */ + +/** + * @test SDV_BSL_HASH_LIST_FUNC_TC001 + * @title Hash list normal capability test + * @precon nan + * @brief + * 1. Call BSL_HASH_Create to create a hash list header. Expected result 1 is obtained. + * 2. Call BSL_HASH_Insert to add data to the hash list. Expected result 2 is obtained. + * 3. Call BSL_HASH_Size get list size. Expected result 3 is obtained. + * 4. Call BSL_CstlHashErase BSL_CstlHashClear BSL_CstlHashDestory delete data, + * Expected result 4 is obtained. + * @expect + * 1. success + * 2. BSL_SUCCESS + * 3. size is 6 + * 4. success + */ +/* BEGIN_CASE */ +void SDV_BSL_HASH_LIST_FUNC_TC001(void) +{ + int i; + BSL_HASH_Hash *hash; + uintptr_t tmpValue; + UserData *userValue; + BSL_HASH_Iterator it; + uintptr_t tmpKey; + uint8_t key[6] = {28, 29, 30, 31, 32, 33}; + UserData value[6] = {{16, "bsl_cstl001"}, + {18, "bsl_cstl002"}, + {15, "bsl_cstl003"}, + {17, "bsl_cstl004"}, + {17, "bsl_cstl005"}, + {16, "bsl_cstl001"}}; + ListDupFreeFuncPair valueFunc = {UserHashDataDupFunc, BSL_SAL_Free}; + hash = BSL_HASH_Create(BACKET_SIZE, NULL, NULL, NULL, &valueFunc); + ASSERT_TRUE(hash != (BSL_HASH_Hash *)NULL); + + for (i = 0; i < 5; i++) { + ASSERT_TRUE(BSL_HASH_Insert(hash, key[i], 0, (uintptr_t)&value[i], sizeof(UserData)) == BSL_SUCCESS); + } + ASSERT_TRUE(BSL_HASH_Put(hash, key[i], 0, (uintptr_t)&value[i], sizeof(UserData)) == BSL_SUCCESS); + + ASSERT_TRUE(BSL_HASH_Size(hash) == (size_t)6); + + ASSERT_TRUE(BSL_HASH_At(hash, key[4], &tmpValue) == BSL_SUCCESS); + userValue = (UserData *)tmpValue; + ASSERT_TRUE(userValue->id == value[4].id); + ASSERT_TRUE(strcmp(userValue->name, value[4].name) == 0); + + it = BSL_HASH_Find(hash, key[4]); + ASSERT_TRUE(it != BSL_HASH_IterEnd(hash)); + ASSERT_TRUE(BSL_HASH_HashIterKey(hash, it) == (uintptr_t)key[4]); + + userValue = (UserData *)BSL_HASH_IterValue(hash, it); + ASSERT_TRUE(userValue != (UserData *)NULL); + ASSERT_TRUE(userValue->id == value[4].id); + ASSERT_TRUE(strcmp(userValue->name, value[4].name) == 0); + + (void)BSL_HASH_Erase(hash, key[4]); + ASSERT_TRUE(BSL_HASH_Size(hash) == (size_t)5); + + for (it = BSL_HASH_IterBegin(hash); it != BSL_HASH_IterEnd(hash);) { + tmpKey = BSL_HASH_HashIterKey(hash, it); + it = BSL_HASH_Erase(hash, tmpKey); + } + + ASSERT_TRUE(BSL_HASH_Size(hash) == (size_t)0); + BSL_HASH_Destory(hash); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_HASH_LIST_FUNC_TC002 + * @title Hash list normal capability test, key type is string. + * @precon nan + * @brief + * 1. Call BSL_HASH_Create to create a hash list header. Expected result 1 is obtained. + * 2. Call BSL_HASH_Insert to add data to the hash list. Expected result 2 is obtained. + * 3. Call BSL_HASH_Size get list size. Expected result 3 is obtained. + * 4. Call BSL_CstlHashErase BSL_CstlHashClear BSL_CstlHashDestory delete data, + * Expected result 4 is obtained. + * @expect + * 1. success + * 2. BSL_SUCCESS + * 3. size is 6 + * 4. success + */ +/* BEGIN_CASE */ +void SDV_BSL_HASH_LIST_FUNC_TC002(void) +{ + uint32_t i; + BSL_HASH_Hash *hash; + const char *key[6] = {"7201028", "7201029", "7201030", "7201031", "7201032", "7201033"}; + UserData value[6] = {{16, "bsl_cstl001"}, + {18, "bsl_cstl002"}, + {15, "bsl_cstl003"}, + {17, "bsl_cstl004"}, + {17, "bsl_cstl005"}, + {16, "bsl_cstl001"}}; + char *tmpKey; + uintptr_t tmpValue; + UserData *userValue; + BSL_HASH_Iterator it; + ListDupFreeFuncPair keyFunc = {UserHashKeyDupFunc, BSL_SAL_Free}; + ListDupFreeFuncPair valueFunc = {UserHashDataDupFunc, BSL_SAL_Free}; + + hash = BSL_HASH_Create(BACKET_SIZE, BSL_HASH_CodeCalcStr, BSL_HASH_MatchStr, &keyFunc, &valueFunc); + ASSERT_TRUE(hash != (BSL_HASH_Hash *)NULL); + + for (i = 0; i < 6; i++) { + ASSERT_TRUE( + BSL_HASH_Insert(hash, (uintptr_t)key[i], strlen(key[i]) + 1, (uintptr_t)&value[i], sizeof(UserData)) == + BSL_SUCCESS); + } + + ASSERT_TRUE(BSL_HASH_Put(hash, (uintptr_t)key[1], strlen(key[1]) + 1, (uintptr_t)&value[1], sizeof(UserData)) + == BSL_SUCCESS); + ASSERT_TRUE(BSL_HASH_Empty(hash) == false); + ASSERT_TRUE(BSL_HASH_Size(hash) == (size_t)6); + ASSERT_TRUE(BSL_HASH_At(hash, (uintptr_t)key[4], &tmpValue) == BSL_SUCCESS); + userValue = (UserData *)tmpValue; + ASSERT_TRUE(userValue->id == value[4].id); + ASSERT_TRUE(strcmp(userValue->name, value[4].name) == 0); + + it = BSL_HASH_Find(hash, (uintptr_t)key[4]); + ASSERT_TRUE(it != BSL_HASH_IterEnd(hash)); + ASSERT_TRUE(strcmp((const char *)BSL_HASH_HashIterKey(hash, it), key[4]) == 0); + + userValue = (UserData *)BSL_HASH_IterValue(hash, it); + ASSERT_TRUE(userValue != (UserData *)NULL); + ASSERT_TRUE(userValue->id == value[4].id); + ASSERT_TRUE(strcmp(userValue->name, value[4].name) == 0); + + (void)BSL_HASH_Erase(hash, (uintptr_t)key[4]); + ASSERT_TRUE(BSL_HASH_Size(hash) == (size_t)5); + + for (it = BSL_HASH_IterBegin(hash); it != BSL_HASH_IterEnd(hash);) { + tmpKey = (char *)BSL_HASH_HashIterKey(hash, it); + it = BSL_HASH_Erase(hash, (uintptr_t)tmpKey); + } + + ASSERT_TRUE(BSL_HASH_Size(hash) == (size_t)0); + BSL_HASH_Destory(hash); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_HASH_LIST_FUNC_TC003 + * @title bsl list normal capability test, key type is string. + * @precon nan + * @brief + * 1. Call BSL_ListInit to create a hash list header. Expected result 1 is obtained. + * 2. Call BSL_ListPushFront and BSL_ListPushBack to add data to the hash list. Expected result 2 is obtained. + * 3. Perform find and delete. Expected result 3 is obtained. + * 4. Call BSL_ListIterErase delete data. Expected result 4 is obtained. + * @expect + * 1. success + * 2. BSL_SUCCESS + * 3. success + * 4. success + */ +/* BEGIN_CASE */ +void SDV_BSL_HASH_LIST_FUNC_TC003(void) +{ + uint32_t i; + BSL_List *list = BSL_SAL_Calloc(1, sizeof(BSL_List)); + ASSERT_TRUE(list != NULL); + const char *data[7] = {"7201028", "7201029", "7201030", "7201031", "7201032", "7201033", "777888"}; + + BSL_ListIterator it = NULL; + ListDupFreeFuncPair valueFunc = {UserHashKeyDupFunc, BSL_SAL_Free}; + + ASSERT_EQ(BSL_ListInit(list, &valueFunc), BSL_SUCCESS); + + for (i = 0; i < 5; i++) { + ASSERT_EQ( BSL_ListPushFront(list, (uintptr_t)data[i], strlen(data[i]) + 1), BSL_SUCCESS); + } + + ASSERT_EQ(BSL_ListPushBack(list, (uintptr_t)data[i], strlen(data[i]) + 1), BSL_SUCCESS); + + ASSERT_TRUE(BSL_ListSize(list) == (size_t)i + 1); + + ASSERT_TRUE(strcmp((const char* )BSL_ListFront(list), data[4]) == 0); + ASSERT_TRUE(strcmp((const char* )BSL_ListBack(list), data[5]) == 0); + + it = BSL_ListIterFind(list, UserDataCmpFunc, (uintptr_t)data[1]); + ASSERT_TRUE(it != BSL_ListIterEnd(list)); + + ASSERT_TRUE(strcmp((const char* )BSL_ListIterData(it), data[1]) == 0); + ASSERT_TRUE(BSL_ListInsert(list, it, (uintptr_t)data[6], strlen(data[6]) + 1) == BSL_SUCCESS); + + ASSERT_TRUE(BSL_ListIterPrev(list, it) != NULL); + ASSERT_TRUE(BSL_ListIterNext(list, it) != NULL); + ASSERT_TRUE(BSL_ListIterBegin(list) != NULL); + ASSERT_TRUE(BSL_ListIterEnd(list) != NULL); + + ASSERT_TRUE(BSL_ListPopFront(list) == BSL_SUCCESS); + ASSERT_TRUE(BSL_ListPopBack(list) == BSL_SUCCESS); + + ASSERT_TRUE(BSL_ListIterErase(list, it) != NULL); + +exit: + BSL_ListDeinit(list); + BSL_SAL_Free(list); + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_HASH_LIST_FUNC_TC004 + * @title raw list normal capability test. + * @precon nan + * @brief + * 1. Call ListRawInit to create a raw list header. Expected result 1 is obtained. + * 2. Call ListRawPushFront to add node to the list. Expected result 2 is obtained. + * 3. Perform find and delete. Expected result 3 is obtained. + * 4. Call ListRawDeinit delete list. Expected result 4 is obtained. + * @expect + * 1. create success + * 2. add success + * 3. success + * 4. success + */ +/* BEGIN_CASE */ +void SDV_BSL_HASH_LIST_FUNC_TC004(void) +{ + uint32_t i; + ListRawNode *node = BSL_SAL_Calloc(6, sizeof(ListRawNode)); + ASSERT_TRUE(node != NULL); + RawList *list = BSL_SAL_Calloc(1, sizeof(RawList)); + ASSERT_TRUE(list != NULL); + + ASSERT_EQ(ListRawInit(list, NULL), BSL_SUCCESS); + + for (i = 0; i < 6; i++) { + ASSERT_EQ(ListRawPushFront(list, &node[i]), BSL_SUCCESS); + } + + ListRawNode *it = ListRawBack(list); + ASSERT_TRUE(it != NULL); + ASSERT_TRUE(it->prev != NULL); + + it = ListRawGetPrev(list, &node[1]); + ASSERT_TRUE(it != NULL); + ASSERT_TRUE(it->next != NULL); + + it = ListRawFindNode(list, ListNodeCmpFunc, (uintptr_t)&node[1]); + ASSERT_TRUE(it != NULL); + + ASSERT_EQ(ListRawPopFront(list), BSL_SUCCESS); + ASSERT_EQ(ListRawPopBack(list), BSL_SUCCESS); + + ASSERT_EQ(ListRawDeinit(list), BSL_SUCCESS); +exit: + BSL_SAL_Free(list); + BSL_SAL_Free(node); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/bsl/hash/test_suite_sdv_hash.data b/testcode/sdv/testcase/bsl/hash/test_suite_sdv_hash.data new file mode 100644 index 00000000..8c847667 --- /dev/null +++ b/testcode/sdv/testcase/bsl/hash/test_suite_sdv_hash.data @@ -0,0 +1,11 @@ +Bsl hash list test #1 +SDV_BSL_HASH_LIST_FUNC_TC001: + +Bsl hash list test #2 +SDV_BSL_HASH_LIST_FUNC_TC002: + +Bsl hash list test #3 +SDV_BSL_HASH_LIST_FUNC_TC003: + +Bsl hash list test #4 +SDV_BSL_HASH_LIST_FUNC_TC004: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/list/test_suite_sdv_list.c b/testcode/sdv/testcase/bsl/list/test_suite_sdv_list.c new file mode 100644 index 00000000..274c24dc --- /dev/null +++ b/testcode/sdv/testcase/bsl/list/test_suite_sdv_list.c @@ -0,0 +1,1020 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include "securec.h" +#include "bsl_errno.h" +#include "bsl_list.h" +#include "bsl_list_internal.h" + +/* END_HEADER */ + +typedef struct { + int value; + int key; +} LIST_NODE; + +#define MAX_NAME_LEN 64 + +/* User Structure Definition */ +typedef struct userListData { + int id; + char name[MAX_NAME_LEN]; +} UserData; + +static void EmptyFree(void *data) +{ + (void)data; +} + +void UserDataFree(void *data) +{ + (void)data; + return; +} + +static int Compare(const void *data1, const void *data2) +{ + return **(int **)data1 > **(int **)data2; +} + +static int32_t UserDataCompare(const void *data1, const void *data2) +{ + if (data1 == NULL || data2 == NULL) { + return 1; + } + UserData *tmp1 = (UserData *)data1; + UserData *tmp2 = (UserData *)data2; + + if (tmp1->id != tmp2->id) { + return -1; + } + + if (strlen(tmp1->name) != strlen(tmp2->name)) { + return -1; + } + + if (memcmp(tmp1->name, tmp2->name, strlen(tmp1->name)) != 0) { + return -1; + } + return 0; +} + +// data1:(pList)->curr->data, data2:pSearchFor +static int32_t UserDataCompareByName(const void *data1, const void *data2) +{ + if (data1 == NULL || data2 == NULL) { + return 1; + } + UserData *tmp1 = (UserData *)data1; + char *tmp2 = (char *)data2; + + if (strlen(tmp1->name) != strlen(tmp2)) { + return -1; + } + + if (memcmp(tmp1->name, tmp2, strlen(tmp2)) != 0) { + return -1; + } + return 0; +} + +static int32_t UserDataSort(const void *a, const void *b) +{ + if (a == NULL || b == NULL) { + return -1; + } + UserData *tmp1 = *(UserData **)a; + UserData *tmp2 = *(UserData **)b; + return (tmp1->id - tmp2->id); +} + +static void *UserDataCopy(const void *a) +{ + if (a == NULL) { + return NULL; + } + UserData *src = (UserData *)a; + UserData *dest = (UserData *)BSL_SAL_Malloc(sizeof(UserData)); + if (dest == NULL) { + return NULL; + } + (void)memset_s(dest, sizeof(UserData), 0, sizeof(UserData)); + dest->id = src->id; + if (memcpy_s(dest->name, MAX_NAME_LEN, src->name, strlen(src->name)) != EOK) { + BSL_SAL_FREE(dest); + return NULL; + } + return dest; +} + +/** + * @test SDV_BSL_LIST_FUNC_TC001 + * @title Linked list normal capability test + * @precon nan + * @brief + * 1. Call BSL_LIST_New to create a linked list header. Expected result 1 is obtained. + * 2. Call BSL_LIST_AddElement to add data to the linked list. Expected result 2 is obtained. + * 3. Repeat step 2 twice. Expected result 2 is obtained. + * 4. Call BSL_LIST_COUNT to obtain the number of data records in the current linked list. + * Expected result 3 is obtained. + * 5. Get the number of nodes in the list after delete the current element of list. Expected result 4 is obtained. + * 6. Call BSL_LIST_Copy to copy data to the new linked list. Expected result 5 is obtained. + * @expect + * 1. success + * 2. BSL_SUCCESS + * 3. 3 + * 4. 2 + * 5. success + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_FUNC_TC001(void) +{ + TestMemInit(); + + BslList *listHeader = BSL_LIST_New(sizeof(LIST_NODE)); + ASSERT_TRUE(listHeader != NULL); + + LIST_NODE *node1 = (LIST_NODE *)BSL_SAL_Malloc(sizeof(LIST_NODE)); + ASSERT_TRUE(node1 != NULL); + + node1->key = 1; + node1->value = 2; + + int ret = BSL_LIST_AddElement(listHeader, node1, BSL_LIST_POS_END); + ASSERT_TRUE(ret == BSL_SUCCESS); + + LIST_NODE *node2 = (LIST_NODE *)BSL_SAL_Malloc(sizeof(LIST_NODE)); + ASSERT_TRUE(node2 != NULL); + + node2->key = 1; + node2->value = 2; + + ret = BSL_LIST_AddElement(listHeader, node2, BSL_LIST_POS_END); + ASSERT_TRUE(ret == BSL_SUCCESS); + + LIST_NODE *node3 = (LIST_NODE *)BSL_SAL_Malloc(sizeof(LIST_NODE)); + ASSERT_TRUE(node3 != NULL); + + node3->key = 1; + node3->value = 2; + + ret = BSL_LIST_AddElement(listHeader, node3, BSL_LIST_POS_END); + ASSERT_TRUE(ret == BSL_SUCCESS); + + int num = BSL_LIST_COUNT(listHeader); + ASSERT_TRUE(num == 3); + + BSL_LIST_DeleteCurrent(listHeader, NULL); + + num = BSL_LIST_COUNT(listHeader); + ASSERT_TRUE(num == 2); + + BslList *destHeader = BSL_LIST_Copy(listHeader, NULL, NULL); + ASSERT_TRUE(destHeader != NULL); + + num = BSL_LIST_COUNT(destHeader); + ASSERT_TRUE(num == 2); + BSL_LIST_FREE(destHeader, NULL); + + BSL_LIST_FREE(listHeader, NULL); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_FUNC_TC002 + * @title SDV_BSL_LIST_FUNC_TC002 + * @precon None + * @brief List maximum element test. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_FUNC_TC002(void) +{ + int arr[] = {0}; + BslList *list = NULL; + + list = BSL_LIST_New(sizeof(int)); + ASSERT_TRUE(list != NULL); + + ASSERT_EQ(BSL_LIST_SetMaxElements(65535), BSL_SUCCESS); + for (int i = 0; i < 65535; i++) { + ASSERT_EQ(BSL_LIST_AddElement(list, arr, BSL_LIST_POS_AFTER), BSL_SUCCESS); + } + ASSERT_EQ(BSL_LIST_COUNT(list), 65535); + ASSERT_EQ(BSL_LIST_AddElement(list, arr, BSL_LIST_POS_AFTER), BSL_LIST_FULL); + +exit: + BSL_LIST_FREE(list, EmptyFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_MAX_ELEMENTS_FUNC_TC001 + * @title list max elements test + * @precon nan + * @brief + * 1. Call BSL_LIST_New to create the head node of the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_SetMaxElements to set the maximum number of data records stored in the linked list to 65535. + * Expected result 2 is obtained. + * 3. Add 65535 records to the linked list. Expected result 3 is obtained. + * 4. Obtain the maximum data volume supported by the current linked list. Expected result 4 is obtained. + * 5. Obtain the number of data records in the current linked list. Expected result 5 is obtained. + * 6. Add data to the linked list again. Expected result 6 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_SUCCESS + * 3. BSL_SUCCESS + * 4. 65535 + * 5. 65535 + * 6. BSL_LIST_FULL + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_MAX_ELEMENTS_FUNC_TC001(void) +{ + int arr[] = {0}; + BslList *list = NULL; + + list = BSL_LIST_New(-1); + ASSERT_TRUE(list == NULL); + + list = BSL_LIST_New(sizeof(int)); + ASSERT_TRUE(list != NULL); + + ASSERT_EQ(BSL_LIST_SetMaxElements(65535), BSL_SUCCESS); + for (int i = 0; i < 65535; i++) { + ASSERT_EQ(BSL_LIST_AddElement(list, arr, BSL_LIST_POS_AFTER), BSL_SUCCESS); + } + ASSERT_EQ(BSL_LIST_GetMaxElements(), 65535); + ASSERT_EQ(BSL_LIST_COUNT(list), 65535); + ASSERT_EQ(BSL_LIST_AddElement(list, arr, BSL_LIST_POS_AFTER), BSL_LIST_FULL); + +exit: + BSL_LIST_FREE(list, EmptyFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_DETACH_FUNC_TC001 + * @title list detach test + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_DetachCurrent to detach the current. Expected result 2 is obtained. + * 3. Call BSL_LIST_DetachNode to detach a node. Expected result 3 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. success + * 3. success + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_DETACH_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[9] = { + {1, "Alice"}, + {2, "Bob"}, + {3, "Celina"}, + {4, "Dave"}, + {5, "Emma"}, + {6, "Frank"}, + {7, "Grace"}, + {8, "Helen"}, + {9, "Iris"} + }; + // Linked list IDs range from 1 to 9. + for (int i = 0; i < 9; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + /* + * The curr is the last node. After the node is detached and released, + * last is the last but one node in the original linked list. + */ + BSL_LIST_DetachCurrent(testList); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 8); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_LAST(testList), &data[7]) == 0); + // Delete Dave. + BslListNode *detachNode = testList->first->next->next->next; + BSL_LIST_DetachNode(testList, &detachNode); + ASSERT_TRUE(UserDataCompare(detachNode->data, &data[4]) == 0); // Dave's position became Emma. +exit: + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_SEARCH_FUNC_TC001 + * @title list search test + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_Search to search for specified data. Expected result 2 is obtained. + * 3. Call BSL_LIST_Search to search for specified data. Expected result 3 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. Data search succeeded. + * 3. Data search succeeded. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_SEARCH_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[5] = { + {1, "Alice"}, + {2, "Bob"}, + {3, "Celina"}, + {4, "Dave"}, + {5, "Emma"} + }; + // The sequence of linked list IDs is 1 - 2 - 3 - 4 - 5. + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[2], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[1], BSL_LIST_POS_BEFORE) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[0], BSL_LIST_POS_BEGIN) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[4], BSL_LIST_POS_END) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[3], BSL_LIST_POS_BEFORE) == BSL_SUCCESS); + + int errNum = 0; + UserData *tmp1 = BSL_LIST_Search(testList, "Celina", UserDataCompareByName, NULL); + ASSERT_TRUE(UserDataCompare(tmp1, &data[2]) == 0); + + UserData *tmp2 = BSL_LIST_Search(testList, "Dave", UserDataCompareByName, &errNum); + ASSERT_TRUE(UserDataCompare(tmp2, &data[3]) == 0); +exit: + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_GET_NODE_FUNC_TC001 + * @title list GET NODE interface testing + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_FirstNode to get the first node in the linked list. Expected result 2 is obtained. + * 3. Call BSL_LIST_GetData to get data from the node. Expected result 3 is obtained. + * 4. Call BSL_LIST_GetNextNode to get the next node. Expected result 4 is obtained. + * 5. Call BSL_LIST_GetData to get data from the node. Expected result 5 is obtained. + * 6. Call BSL_LIST_GetNextNode to get the next node. Expected result 6 is obtained. + * 7. Call BSL_LIST_GetData to get data from the node. Expected result 7 is obtained. + * 8. Call BSL_LIST_GetNextNode to get the prev node. Expected result 8 is obtained. + * 9. Call BSL_LIST_GetData to get data from the node. Expected result 9 is obtained. + * 10. Call BSL_LIST_Curr to get the current element in the list. Expected result 10 is obtained. + * 11. Call BSL_LIST_GetIndexNode to get the node at the given index in the list. + * Expected result 11 is obtained. + * 12. Call BSL_LIST_Curr to get the current element in the list. Expected result 12 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. The first node is obtained successfully. + * 3. Succeeded in obtaining data from the node, which is the same as the original data. + * 4. The next node is obtained successfully. + * 5. Succeeded in obtaining data from the node, which is the same as the original data. + * 6. The next node is obtained successfully. + * 7. Succeeded in obtaining data from the node, which is the same as the original data. + * 8. The prev node is obtained successfully. + * 9. Succeeded in obtaining data from the node, which is the same as the original data. + * 10. The current node is obtained successfully, which is the same as the original data. + * 11. The index node is obtained successfully, which is the same as the original data. + * 12. The current node is obtained successfully, which is the same as the original data. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_GET_NODE_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[5] = { + {1, "Alice"}, + {2, "Bob"}, + {3, "Celina"}, + {4, "Dave"}, + {5, "Emma"} + }; + for (int i = 0; i < 5; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + + BslListNode *tmp = BSL_LIST_FirstNode(NULL); + ASSERT_TRUE(tmp == NULL); + tmp = BSL_LIST_FirstNode(testList); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GetData(tmp), &data[0]) == 0); + tmp = BSL_LIST_GetNextNode(NULL, (const BslListNode *)BSL_LIST_FirstNode(testList)); + ASSERT_TRUE(tmp == NULL); + tmp = BSL_LIST_GetNextNode(testList, (const BslListNode *)BSL_LIST_FirstNode(testList)); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GetData(tmp), &data[1]) == 0); + tmp = BSL_LIST_GetNextNode(testList, (const BslListNode *)tmp); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GetData(tmp), &data[2]) == 0); + tmp = BSL_LIST_GetPrevNode(tmp); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GetData(tmp), &data[1]) == 0); + + // curr points to 4. + UserData *curTmp = *(UserData **)BSL_LIST_Curr(testList); + ASSERT_TRUE(UserDataCompare(curTmp, &data[4]) == 0); + // The subscript of the list starts from 0. + UserData *getTmp = BSL_LIST_GetIndexNode(3, testList); + ASSERT_TRUE(UserDataCompare(&data[3], getTmp) == 0); + // BSL_LIST_GetIndexNode changes the curr point to 3. + curTmp = *(UserData **)BSL_LIST_Curr(testList); + ASSERT_TRUE(UserDataCompare(curTmp, &data[3]) == 0); +exit: + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_COPY_FUNC_TC001 + * @title list Copy test + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_Copy to copy the linked list to the new linked list + * and check whether the data in the two linked lists is the same. Expected result 2 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. The data in the two linked lists is the same. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_COPY_FUNC_TC001(void) +{ + BslList *srcList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(srcList != NULL); + + UserData data[3] = { {1, "Alice"}, {2, "Bob"}, {3, "Celina"} }; + for (int i = 0; i < 3; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(srcList, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + + BslList *destList = BSL_LIST_Copy(srcList, UserDataCopy, UserDataFree); + + UserData *srcTmp = BSL_LIST_GET_FIRST(srcList); + UserData *destTmp = BSL_LIST_GET_FIRST(destList); + ASSERT_TRUE(UserDataCompare((const void *)srcTmp, (const void *)destTmp) == 0); + srcTmp = BSL_LIST_GET_LAST(srcList); + destTmp = BSL_LIST_GET_LAST(destList); + ASSERT_TRUE(UserDataCompare((const void *)srcTmp, (const void *)destTmp) == 0); + ASSERT_TRUE(UserDataCompare(destList->first->next->data, srcList->first->next->data) == 0); +exit: + BSL_LIST_FREE(destList, NULL); + BSL_LIST_FREE(srcList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_SORT_FUNC_TC001 + * @title list sort test + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_Sort to sort the linked list and view the sorting result. Expected result 2 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. Linked list sorting succeeded. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_SORT_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[6] = { {3, "Celina"}, {2, "Bob"}, {1, "Alice"}, {6, "Frank"}, {4, "Dave"}, {5, "Emma"} }; + for (int i = 0; i < 6; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + + BSL_LIST_Sort(testList, UserDataSort); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_FIRST(testList), &data[2]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_LAST(testList), &data[3]) == 0); + ASSERT_TRUE(UserDataCompare(testList->first->next->next->next->data, &data[4]) == 0); +exit: + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_SORT_FUNC_TC002 + * @title list sort test + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_GetMaxQsortCount to get max qsort count. Expected result 2 is obtained. + * 3. Call BSL_LIST_SetMaxQsortCount to set max qsort count. Expected result 3 is obtained. + * 4. Call BSL_LIST_GetMaxQsortCount to get max qsort count. Expected result 4 is obtained. + * 5. Call BSL_LIST_Sort to sort the linked list and view the sorting result. Expected result 5 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. The obtained count is the same as the default count. + * 3. Succeeded in setting the max qsort count. + * 4. The obtained count is the same as the count. + * 5. Linked list sorting succeeded. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_SORT_FUNC_TC002(void) +{ + int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + BslList *list1 = NULL; + + list1 = BSL_LIST_New(sizeof(int)); + ASSERT_TRUE(list1 != NULL); + + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 4, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 3, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 2, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 1, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 7, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 5, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 8, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_AddElement(list1, arr + 6, BSL_LIST_POS_AFTER), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_GetMaxQsortCount(), 100000); + ASSERT_EQ(BSL_LIST_SetMaxQsortCount(67108865), BSL_INVALID_ARG); + ASSERT_EQ(BSL_LIST_SetMaxQsortCount(10000), BSL_SUCCESS); + ASSERT_EQ(BSL_LIST_GetMaxQsortCount(), 10000); + + list1 = BSL_LIST_Sort(list1, Compare); + ASSERT_TRUE(list1 != NULL); + + int *p = BSL_LIST_GET_FIRST(list1); + ASSERT_TRUE(p != NULL && *p == 1); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 2); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 3); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 4); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 5); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 6); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 7); + p = BSL_LIST_GET_NEXT(list1); + ASSERT_TRUE(p != NULL && *p == 8); + +exit: + BSL_LIST_FREE(list1, EmptyFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_ADD_GET_FUNC_TC001 + * @title The list add and GET* interfaces testing. + * @precon nan + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_CURR_ELMT. Expected result 2 is obtained. + * 3. Call BSL_LIST_NEXT_ELMT. Expected result 3 is obtained. + * 4. Call BSL_LIST_PREV_ELMT. Expected result 4 is obtained. + * 5. Call BSL_LIST_LAST_ELMT. Expected result 5 is obtained. + * 6. Call BSL_LIST_FIRST_ELMT. Expected result 6 is obtained. + * 7. Call BSL_LIST_GET_FIRST. Expected result 7 is obtained. + * 8. Call BSL_LIST_GET_LAST. Expected result 8 is obtained. + * 9. Call BSL_LIST_GET_CURRENT. Expected result 9 is obtained. + * 10. Call BSL_LIST_GET_NEXT. Expected result 10 is obtained. + * 11. Call BSL_LIST_GET_PREV. Expected result 11 is obtained. + * 12. Call BSL_LIST_GetIndexNode. Expected result 12 is obtained. + * 13. Call BSL_LIST_GetElmtIndex. Expected result 13 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2~13. SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_ADD_GET_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 0); + + UserData data[4] = { + {1, "bsl_list_001"}, + {2, "bsl_list_002"}, + {3, "bsl_list_003"}, + {4, "bsl_list_004"}, + }; + // The sequence of linked list IDs is 3 - 2 - 1 - 4. + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[0], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[1], BSL_LIST_POS_BEFORE) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[2], BSL_LIST_POS_BEGIN) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[3], BSL_LIST_POS_END) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 4); + + // Obtaining the macro of a node does not change the value of curr. + ASSERT_TRUE(UserDataCompare(BSL_LIST_CURR_ELMT(testList), &data[3]) == 0); + ASSERT_TRUE(BSL_LIST_NEXT_ELMT(testList) == NULL); + ASSERT_TRUE(UserDataCompare(BSL_LIST_PREV_ELMT(testList), &data[0]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_LAST_ELMT(testList), &data[3]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_FIRST_ELMT(testList), &data[2]) == 0); + // Note that the Get function changes the value of curr. + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_FIRST(testList), &data[2]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_LAST(testList), &data[3]) == 0); + UserData *curTmp = *(UserData **)BSL_LIST_Curr(testList); + ASSERT_TRUE(UserDataCompare(curTmp, &data[3]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_PREV(testList), &data[0]) == 0); + // Therefore, this is the next of curr->prev. + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_NEXT(testList), &data[3]) == 0); + // The curr points to 3 + curTmp = *(UserData **)BSL_LIST_Curr(testList); + ASSERT_TRUE(UserDataCompare(curTmp, &data[3]) == 0); + + // The subscript of the list starts from 0. + UserData *tmp = BSL_LIST_GetIndexNode(2, testList); + ASSERT_TRUE(UserDataCompare(&data[0], tmp) == 0); + + // BSL_LIST_GetIndexNode changes curr to 2. + curTmp = *(UserData **)BSL_LIST_Curr(testList); + ASSERT_TRUE(UserDataCompare(curTmp, &data[0]) == 0); + + ASSERT_TRUE(BSL_LIST_GetElmtIndex(&data[1], testList) == 1); +exit: + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_CONCAT_FUNC_TC001 + * @title list concat test + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_Concat to combine two linked lists and compare whether the data in the linked lists is correct. + * Expected result 2 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. Linked list combination succeeded. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_CONCAT_FUNC_TC001(void) +{ + BslList *destList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(destList != NULL); + BslList *srcList1 = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(srcList1 != NULL); + BslList *srcList2 = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(srcList2 != NULL); + + UserData data[6] = { {1, "Alice"}, {2, "Bob"}, {3, "Celina"}, {4, "Dave"}, {5, "Emma"}, {6, "Frank"} }; + for (int i = 0; i < 3; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(srcList1, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + for (int i = 3; i < 6; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(srcList2, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + // Add to an empty linked list + destList = BSL_LIST_Concat(destList, srcList1); + // Add to non-empty linked list + destList = BSL_LIST_Concat(destList, srcList2); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_FIRST(destList), &data[0]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_LAST(destList), &data[5]) == 0); + ASSERT_TRUE(UserDataCompare(destList->first->next->next->next->data, &data[3]) == 0); +exit: + BSL_LIST_FREE(destList, UserDataFree); + BSL_SAL_FREE(srcList1); + BSL_SAL_FREE(srcList2); // The nodes are free, so just use the free linked list itself. +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_REVERSE_FUNC_TC001 + * @title list reverse test + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_RevList to reverse the linked list. Expected result 2 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. Succeeded in reversing the linked list. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_REVERSE_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[3] = { {1, "Alice"}, {2, "Bob"}, {3, "Celina"} }; + + for (int i = 0; i < 3; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + + BSL_LIST_RevList(testList); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_FIRST(testList), &data[2]) == 0); + ASSERT_TRUE(UserDataCompare(BSL_LIST_GET_LAST(testList), &data[0]) == 0); +exit: + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_DETELE_NODE_FUNC_TC001 + * @title list delete test + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_FirstNode to get the first node in the linked list. Expected result 2 is obtained. + * 3. Call BSL_LIST_DeleteNode to delete the first node. Expected result 3 is obtained. + * 4. Call BSL_LIST_DeleteAll to delete all node. Expected result 4 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. Succeeded in reversing the linked list. + * 3. The deletion is successful, and the number of nodes decreases by 1. + * 4. The deletion is successful. The number of nodes is 0. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_DELETE_NODE_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[3] = { {1, "Alice"}, {2, "Bob"}, {3, "Celina"} }; + + UserData *data1 = BSL_SAL_Malloc(sizeof(UserData) * 3); + ASSERT_TRUE(data1 != NULL); + memcpy_s(data1, sizeof(UserData) * 3, data, sizeof(UserData) *3); + + for (int i = 0; i < 3; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data1[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + + BslListNode *tmp = BSL_LIST_FirstNode(testList); + BSL_LIST_DeleteNode(testList, tmp, UserDataFree); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 2); + BSL_LIST_DeleteAll(testList, UserDataFree); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 0); +exit: + free(data1); + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_DETELE_NODE_FUNC_TC002 + * @title list delete test + * @brief + * 1. Call BSL_LIST_AddElement to add data to the linked list. Expected result 1 is obtained. + * 2. Call BSL_LIST_DeleteAllAfterSort to delete all node. Expected result 2 is obtained. + * @expect + * 1. Data added successfully. return BSL_SUCCESS. + * 2. The deletion is successful. The number of nodes is 0. + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_DELETE_NODE_FUNC_TC002(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + UserData data[3] = { {1, "Alice"}, {2, "Bob"}, {3, "Celina"} }; + + UserData *data1 = BSL_SAL_Malloc(sizeof(UserData) * 3); + ASSERT_TRUE(data1 != NULL); + memcpy_s(data1, sizeof(UserData) * 3, data, sizeof(UserData) *3); + + for (int i = 0; i < 3; i++) { + ASSERT_TRUE(BSL_LIST_AddElement(testList, &data1[i], BSL_LIST_POS_AFTER) == BSL_SUCCESS); + } + + BSL_LIST_DeleteAllAfterSort(testList); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 0); +exit: + free(data1); + BSL_LIST_FREE(testList, UserDataFree); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_LIST_API_TC001 + * @title list previous node test + * @brief + * 1. Check if previous element is NULL. Expected result 1 is obtained. + * 2. Call BSL_LIST_AddElement to add data to the linked list. Expected result 2 is obtained. + * 3. Check if previous element is NULL. Expected result 3 is obtained. + * @expect + * 1. The previous node is NULL. + * 2. Data added successfully. return BSL_SUCCESS. + * 3. The previous node is not NULL. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_LIST_Pre_API_TC001() +{ + int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + + /* when list is NULL */ + int **prv = BSL_LIST_Prev(NULL); + ASSERT_EQ(prv, NULL); + + /* pstList->curr == NULL */ + BslList *list = BSL_LIST_New(sizeof(int)); + ASSERT_TRUE(list != NULL); + prv = BSL_LIST_Prev(list); + ASSERT_EQ(prv, NULL); + + /* pstList->curr != NULL, pstList->curr->prev == NULL */ + ASSERT_EQ(BSL_LIST_AddElement(list, arr + 0, BSL_LIST_POS_AFTER), BSL_SUCCESS); + prv = BSL_LIST_Prev(list); + ASSERT_EQ(prv, NULL); + + /* pstList->curr != NULL, pstList->curr->prev != NULL */ + ASSERT_EQ(BSL_LIST_AddElement(list, arr + 1, BSL_LIST_POS_AFTER), BSL_SUCCESS); + prv = BSL_LIST_Prev(list); + ASSERT_TRUE(prv != NULL && **prv == 0); + + /* pstList->curr == NULL, pstList->last != NULL */ + prv = BSL_LIST_Prev(list); + ASSERT_EQ(prv, NULL); + prv = BSL_LIST_Prev(list); + ASSERT_TRUE(prv != NULL && **prv == 1); + +exit: + BSL_LIST_FREE(list, EmptyFree); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_LIST_Next_API_TC002 + * @title list next node test + * @brief + * 1. Check if next node is NULL. Expected result 1 is obtained. + * 2. Call BSL_LIST_AddElement to add data to the linked list. Expected result 2 is obtained. + * 3. Check if next node is NULL. Expected result 3 is obtained. + * @expect + * 1. The next node is NULL. + * 2. Data added successfully. return BSL_SUCCESS. + * 3. The next node is not NULL. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_LIST_Next_API_TC002() +{ + int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + + /* when list is NULL */ + int **next = BSL_LIST_Prev(NULL); + ASSERT_EQ(next, NULL); + + /* pstList->curr == NULL */ + BslList *list = BSL_LIST_New(sizeof(int)); + ASSERT_TRUE(list != NULL); + next = BSL_LIST_Next(list); + ASSERT_EQ(next, NULL); + + /* pstList->curr != NULL, pstList->curr->next == NULL */ + ASSERT_EQ(BSL_LIST_AddElement(list, arr + 0, BSL_LIST_POS_BEFORE), BSL_SUCCESS); + next = BSL_LIST_Next(list); + ASSERT_EQ(next, NULL); + + /* pstList->curr != NULL, pstList->curr->next != NULL */ + ASSERT_EQ(BSL_LIST_AddElement(list, arr + 1, BSL_LIST_POS_BEFORE), BSL_SUCCESS); + next = BSL_LIST_Next(list); + ASSERT_TRUE(next != NULL && **next == 0); + + /* pstList->curr == NULL, pstList->first != NULL */ + next = BSL_LIST_Next(list); + ASSERT_EQ(next, NULL); + next = BSL_LIST_Next(list); + ASSERT_TRUE(next != NULL && **next == 1); + +exit: + BSL_LIST_FREE(list, EmptyFree); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_SET_MAX_FUNC_TC001 + * @title list is* Interface test + * @brief 1. BSL_LIST_SetMaxQsortCount + 2. BSL_LIST_GetMaxQsortCount + 3. BSL_LIST_SetMaxElements + 4. BSL_LIST_GetMaxElements + * @expect 1. BSL_SUCCESS + 2. g_maxQsortElem = 100001 + 3. BSL_SUCCESS + 4. g_maxListCount = 65536 + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_SET_MAX_FUNC_TC001(void) +{ + ASSERT_TRUE(BSL_LIST_SetMaxQsortCount(100001) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_GetMaxQsortCount() == 100001); + ASSERT_TRUE(BSL_LIST_SetMaxElements((1 << 16)) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_GetMaxElements() == (1 << 16)); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_INVALID_INPUT_FUNC_TC001 + * @title list invalid or empty input parameter value test + * @brief 0. BSL_LIST_AddElement + 1. BSL_LIST_AddElement + 2. BSL_LIST_Search + 3. BSL_LIST_Concat + 4. BSL_LIST_Sort + 5. BSL_LIST_Copy + 6. BSL_LIST_Copy + 7. BSL_LIST_GetData + 8. BSL_LIST_FirstNode + 9. BSL_LIST_GetNextNode + 10. BSL_LIST_GetPrevNode + 11. BSL_LIST_SetMaxQsortCount + 12. BSL_LIST_SetMaxElements + * @expect 0. BSL_INVALID_ARG + 1. BSL_LIST_DATA_NOT_AVAILABLE + 2. NULL + 3. NULL + 4. NULL + 5. NULL + 6. NULL + 7. NULL + 8. NULL + 9. NULL + 10. BSL_LIST_GetPrevNode + 11. BSL_INVALID_ARG + 12. BSL_INVALID_ARG + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_INVALID_INPUT_FUNC_TC001(void) +{ + ASSERT_TRUE(BSL_LIST_AddElement(NULL, NULL, BSL_LIST_POS_BEFORE) == BSL_INVALID_ARG); + + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + ASSERT_TRUE(BSL_LIST_AddElement(testList, NULL, BSL_LIST_POS_BEFORE) == BSL_LIST_DATA_NOT_AVAILABLE); + + ASSERT_TRUE(BSL_LIST_Search(NULL, NULL, UserDataCompare, NULL) == NULL); + ASSERT_TRUE(BSL_LIST_Concat(NULL, NULL) == NULL); + ASSERT_TRUE(BSL_LIST_Sort(NULL, NULL) == NULL); + ASSERT_TRUE(BSL_LIST_Copy(NULL, UserDataCopy, UserDataFree) == NULL); + ASSERT_TRUE(BSL_LIST_Copy(testList, UserDataCopy, UserDataFree) == NULL); + ASSERT_TRUE(BSL_LIST_GetData(NULL) == NULL); + ASSERT_TRUE(BSL_LIST_FirstNode(NULL) == NULL); + ASSERT_TRUE(BSL_LIST_GetNextNode(NULL, NULL) == NULL); + ASSERT_TRUE(BSL_LIST_GetPrevNode(NULL) == NULL); + ASSERT_TRUE(BSL_LIST_SearchEx(NULL, NULL, NULL) == NULL); + ASSERT_TRUE(BSL_LIST_GetIndexNodeEx(0, NULL, NULL) == NULL); + + ASSERT_TRUE(BSL_LIST_SetMaxQsortCount(10) == BSL_INVALID_ARG); + ASSERT_TRUE(BSL_LIST_SetMaxElements(10) == BSL_INVALID_ARG); +exit: + BSL_SAL_FREE(testList); +} +/* END_CASE */ + +/** + * @test SDV_BSL_LIST_DELETE_FUNC_TC001 + * @title test the function of deleting a node. + * @brief + * @prior Level 1 + * @auto TRUE + */ +/* BEGIN_CASE */ +void SDV_BSL_LIST_DELETE_FUNC_TC001(void) +{ + BslList *testList = BSL_LIST_New(MAX_NAME_LEN); + ASSERT_TRUE(testList != NULL); + + ASSERT_TRUE(BSL_LIST_AddElement(testList, "aaaa", BSL_LIST_POS_BEFORE) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_AddElement(testList, "bbbb", BSL_LIST_POS_BEFORE) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 2); + BslListNode *tmpNode = NULL; + for (BslListNode *node = BSL_LIST_FirstNode(testList); node != NULL;) { + tmpNode = node; + char *name = BSL_LIST_GetData(tmpNode); + if (name == NULL) { + continue; + } + node = BSL_LIST_GetNextNode(testList, tmpNode); + if (strcmp(name, "aaaa") == 0) { + BSL_LIST_DeleteNode(testList, (const BslListNode *)tmpNode, UserDataFree); + continue; + } + if (strcmp(name, "bbbb") == 0) { + BSL_LIST_DeleteNode(testList, (const BslListNode *)tmpNode, UserDataFree); + continue; + } + } + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 0); + ASSERT_TRUE(BSL_LIST_AddElement(testList, "cccc", BSL_LIST_POS_BEFORE) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LIST_COUNT(testList) == 1); + BSL_LIST_DeleteCurrent(testList, UserDataFree); +exit: + BSL_SAL_FREE(testList); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/list/test_suite_sdv_list.data b/testcode/sdv/testcase/bsl/list/test_suite_sdv_list.data new file mode 100644 index 00000000..98b18679 --- /dev/null +++ b/testcode/sdv/testcase/bsl/list/test_suite_sdv_list.data @@ -0,0 +1,53 @@ +SDV_BSL_LIST_FUNC_TC001 +SDV_BSL_LIST_FUNC_TC001: + +SDV_BSL_LIST_FUNC_TC002 +SDV_BSL_LIST_FUNC_TC002: + +SDV_BSL_LIST_DETACH_FUNC_TC001 +SDV_BSL_LIST_DETACH_FUNC_TC001: + +SDV_BSL_LIST_SEARCH_FUNC_TC001 +SDV_BSL_LIST_SEARCH_FUNC_TC001: + +SDV_BSL_LIST_GET_NODE_FUNC_TC001 +SDV_BSL_LIST_GET_NODE_FUNC_TC001: + +SDV_BSL_LIST_COPY_FUNC_TC001 +SDV_BSL_LIST_COPY_FUNC_TC001: + +SDV_BSL_LIST_SORT_FUNC_TC001 +SDV_BSL_LIST_SORT_FUNC_TC001: + +SDV_BSL_LIST_SORT_FUNC_TC002 +SDV_BSL_LIST_SORT_FUNC_TC002: + +SDV_BSL_LIST_ADD_GET_FUNC_TC001 +SDV_BSL_LIST_ADD_GET_FUNC_TC001: + +SDV_BSL_LIST_CONCAT_FUNC_TC001 +SDV_BSL_LIST_CONCAT_FUNC_TC001: + +SDV_BSL_LIST_REVERSE_FUNC_TC001 +SDV_BSL_LIST_REVERSE_FUNC_TC001: + +SDV_BSL_LIST_DELETE_NODE_FUNC_TC001 +SDV_BSL_LIST_DELETE_NODE_FUNC_TC001: + +SDV_BSL_LIST_DELETE_NODE_FUNC_TC002 +SDV_BSL_LIST_DELETE_NODE_FUNC_TC002: + +SDV_CRYPTO_LIST_Pre_API_TC001 +SDV_CRYPTO_LIST_Pre_API_TC001: + +SDV_CRYPTO_LIST_Next_API_TC002 +SDV_CRYPTO_LIST_Next_API_TC002: + +SDV_BSL_LIST_SET_MAX_FUNC_TC001 +SDV_BSL_LIST_SET_MAX_FUNC_TC001: + +SDV_BSL_LIST_INVALID_INPUT_FUNC_TC001 +SDV_BSL_LIST_INVALID_INPUT_FUNC_TC001: + +SDV_BSL_LIST_DELETE_FUNC_TC001 +SDV_BSL_LIST_DELETE_FUNC_TC001: diff --git a/testcode/sdv/testcase/bsl/log/test_suite_sdv_log.c b/testcode/sdv/testcase/bsl/log/test_suite_sdv_log.c new file mode 100644 index 00000000..3b9640b0 --- /dev/null +++ b/testcode/sdv/testcase/bsl/log/test_suite_sdv_log.c @@ -0,0 +1,443 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "bsl_sal.h" +#include "bsl_errno.h" +#include "bsl_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" + +static uintptr_t g_binlogFlag = 0; + +// Binlog fixed-length callback +static void BinLogFix(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logId; + (void)logLevel; + (void)logType; + (void)format; + (void)para2; + (void)para3; + (void)para4; + g_binlogFlag = (uintptr_t)para1; +} + +// Binlog variable-length callback +static void BinLogVar(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para) +{ + (void)logId; + (void)logLevel; + (void)logType; + (void)format; + g_binlogFlag = (uintptr_t)para; +} + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logId; + (void)logLevel; + (void)logType; + (void)format; + (void)para1; + (void)para2; + (void)para3; + (void)para4; +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para) +{ + (void)logId; + (void)logLevel; + (void)logType; + (void)format; + (void)para; +} + +static FILE *g_LogOutput = NULL; + +// Binlog fixed-length callback, output to a file +static void BinLogFixFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + uint8_t *pucFormat = (uint8_t *)format; + uint8_t ucTemp; + uint8_t ucNo = 0; + + fprintf(g_LogOutput, "HITLS_BIN_LOG[FIXLEN]: logId=%u, logLevel=%u, logType=%u.\n", logId, logLevel, logType); + + /* Search for all format specifiers */ + while (*pucFormat != '\0') { + if (*pucFormat == '%') { + /* Get the second character */ + ucTemp = *(pucFormat + 1); + if ((ucTemp == 'd') || (ucTemp == 'l') || (ucTemp == 'p') || (ucTemp == 'u') || (ucTemp == 'x')) { + ucNo++; + } + } + pucFormat++; + } + + switch(ucNo) { + case 0: // Pure character strings are not output. + break; + case 1: // Output parameters only + fprintf(g_LogOutput, "0x%lX\n", (uint64_t)para1); + break; + case 2: // Output parameters only + fprintf(g_LogOutput, "0x%lX 0x%lX\n", (uint64_t)para1, (uint64_t)para2); + break; + case 3: // Output parameters only + fprintf(g_LogOutput, "0x%lX 0x%lX 0x%lX\n", (uint64_t)para1, (uint64_t)para2, (uint64_t)para3); + break; + case 4: // Output parameters only + fprintf(g_LogOutput, "0x%lX 0x%lX 0x%lX 0x%lX\n", (uint64_t)para1, (uint64_t)para2, (uint64_t)para3, + (uint64_t)para4); + break; + default: // The number of parameters is incorrect. + fprintf(g_LogOutput, "Invalid Number of Format Specifiers in LOG\n"); + return; + } +} + +// Binlog variable-length callback, output to a file +static void BinLogVarFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para) +{ + uint8_t *pucFormat = (uint8_t *)format; + uint8_t ucTemp; + uint8_t ucValidNo = 0; + + fprintf(g_LogOutput, "HITLS_BIN_LOG[VARLEN]: logId=%u, logLevel=%u, logType=%u.\n", logId, logLevel, logType); + + while (*pucFormat != '\0') { + if (*pucFormat == '%') { + /* Get the second character */ + ucTemp = *(pucFormat + 1); + if (ucTemp == 's') { // Only the %s parameter can be contained. + ucValidNo++; + } + } + pucFormat++; + } + + if (ucValidNo != 1) { + fprintf(g_LogOutput, "Invalid Number of %%s present in Var Len LOG\n"); + } + + fprintf(g_LogOutput, "%s\n", (const char *)para); +} + +/* END_HEADER */ + +/** + * @test SDV_BSL_LOG_VERSION_API_TC001 + * @title Obtaining the HiTLS version number of the log submodule of the BSL module + * @precon nan + * @brief + * 1. The buffer of the received version string is empty + * or the buffer length of the received version string is empty. Expected result 1 is obtained. + * 2. The buffer length of the received version string is less than the minimum length. + * Expected result 2 is obtained. + * 3. Received version and length of memory application. Expected result 3 is obtained. + * @expect + * 1. Return BSL_LOG_ERR_BAD_PARAM + * 2. Return BSL_LOG_ERR_BAD_PARAM + * 3. Succeeded. The version length is equal to the current version length, +* and the version string content is equal to the current version string content. + */ +/* BEGIN_CASE */ +void SDV_BSL_LOG_VERSION_API_TC001(void) +{ + char version[200]; + uint32_t versionLen = 100; + ASSERT_TRUE(BSL_LOG_GetVersion(NULL, NULL) == BSL_LOG_ERR_BAD_PARAM); + ASSERT_TRUE(BSL_LOG_GetVersion((char *)version, &versionLen) == BSL_LOG_ERR_BAD_PARAM); + + versionLen = 200; + ASSERT_TRUE(BSL_LOG_GetVersion((char *)version, &versionLen) == BSL_SUCCESS); + ASSERT_TRUE(versionLen == strlen("openHiTLS 0.1.0 25 12 2023")); + ASSERT_TRUE(memcmp(version, "openHiTLS 0.1.0 25 12 2023", versionLen) == 0); + uint32_t versionNum = BSL_LOG_GetVersionNum(); + ASSERT_TRUE(versionNum == 0x00001000U); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_REG_BIN_LOG_FUNC_TC001 + * @title Setting the Log Callback Hook + * @precon nan + * @brief + * 1. Call the BSL_LOG_RegBinLogFunc interface and leave the input parameter empty. Expected result 1 is obtained. + * 2. Call BSL_LOG_RegBinLogFunc. If funcs is not empty, fixLenFunc is empty, + * and varLenFunc is empty, expected result 2 is obtained. + * 3. Call BSL_LOG_RegBinLogFunc. If funcs is not empty, fixLenFunc is empty, + * and varLenFunc is not empty, expected result 3 is obtained. + * 4. Call BSL_LOG_RegBinLogFunc. If funcs, fixLenFunc, and varLenFunc are not empty, expected result 4 is obtained. + * 5. Call BSL_LOG_RegBinLogFunc. Ensure that funcs and fixLenFunc are not empty, + * and varLenFunc are empty. Expected result 5 is obtained. + * 6. Call BSL_LOG_RegBinLogFunc repeatedly. If funcs, fixLenFunc, and varLenFunc are not empty. + * Expected result 6 is obtained. + * @expect + * 1.BSL_NULL_INPUT + * 2.BSL_NULL_INPUT + * 3.BSL_NULL_INPUT + * 4.BSL_SUCCESS + * 5.BSL_NULL_INPUT + * 6.BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_REG_BIN_LOG_FUNC_TC001(void) +{ + TestMemInit(); + + BSL_LOG_BinLogFuncs func = {0}; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(NULL) == BSL_NULL_INPUT); + + func.fixLenFunc = NULL; + func.varLenFunc = NULL; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_NULL_INPUT); + + func.fixLenFunc = NULL; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_NULL_INPUT); + + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = NULL; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_NULL_INPUT); + + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_BIN_LOG_API_TC001 + * @title Testing the Log Recording of the Log Submodule of the BSL Module + * @precon + * @brief + * 1. Setting an invalid dotting log level. Expected result 1 is obtained. + * 2. Set a valid dotting log level and obtain the dotting log level. Expected result 2 is obtained. + * 3. Set the parameter of the dotting log callback function to NULL. Expected result 3 is obtained. + * 4. The parameter and member of the callback function for setting dotting logs are not NULL. + * Expected result 4 is obtained. + * 5. The parameter of the callback function for setting dotting logs is not NULL. + * The callback function for four parameters is not NULL, and the callback function for one parameter is NULL. + * Expected result 5 is obtained. + * 6. The parameter of the callback function for setting dotting logs is not NULL. + * The value 1 of the callback function is not NULL. The value 4 of the callback function is NULL. + * Expected result 6 is obtained. + * 7. The parameter and member of the callback function for setting dotting logs are not NULL. + * Expected result 7 is obtained. + * 8. Overwrite the callback function for setting dotting logs. Expected result 8 is obtained. + * 9. Invoke the 4 parameter dotting to filter logs by log level. Expected result 9 is obtained. + * 10. Invoke the 4 parameter dotting, and the log level is not filtered. Expected result 10 is obtained. + * 11. Invoke variable parameter dotting and log level filtering. Expected result 11 is obtained. + * 12. Invoke variable parameter dotting, and log level filtering is not performed. Expected result 12 is obtained. + * @expect + * 1. BSL_LOG_ERR_BAD_PARAM + * 2. BSL_LOG_LEVEL_ERR + * 3. BSL_LOG_LEVEL_ERR + * 4. BSL_LOG_ERR_BAD_PARAM + * 5. BSL_LOG_LEVEL_ERR + * 6. BSL_NULL_INPUT + * 7. BSL_SUCCESS + * 8. BSL_SUCCESS + * 9. The global return value is not modified. + * 10. The global return value is changed to para1. + * 11. The global return value is not modified. + * 12. The global return value is changed to para. + */ +/* BEGIN_CASE */ +void SDV_BSL_BIN_LOG_API_TC001(void) +{ + int32_t ret; + int32_t retlevel; + + ret = BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_DEBUG + 1); + ASSERT_TRUE(ret != BSL_SUCCESS); + /* + * The get loglevel command is used to obtain the default value + * when the loglevel command fails to be set for the first time. + */ + retlevel = BSL_LOG_GetBinLogLevel(); + ASSERT_TRUE(retlevel == BSL_LOG_LEVEL_ERR); + + ret = BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_ERR); + ASSERT_TRUE(ret == BSL_SUCCESS); + // The BSL_LOG_GetBinLogLevel function is replaced. + retlevel = BSL_LOG_GetBinLogLevel(); + ASSERT_TRUE(retlevel == BSL_LOG_LEVEL_ERR); + + // If the set loglevel operation fails, get loglevel to obtain the original value. + ret = BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_DEBUG + 1); + ASSERT_TRUE(ret != BSL_SUCCESS); + retlevel = BSL_LOG_GetBinLogLevel(); + ASSERT_TRUE(retlevel == BSL_LOG_LEVEL_ERR); + + ret = BSL_LOG_RegBinLogFunc(NULL); + ASSERT_TRUE(ret != BSL_SUCCESS); + + BSL_LOG_BinLogFuncs funcs = {NULL, NULL}; + ret = BSL_LOG_RegBinLogFunc(&funcs); + ASSERT_TRUE(ret != BSL_SUCCESS); + + funcs.fixLenFunc = BinLogFix; + funcs.varLenFunc = NULL; + ret = BSL_LOG_RegBinLogFunc(&funcs); + ASSERT_TRUE(ret != BSL_SUCCESS); + + funcs.fixLenFunc = NULL; + funcs.varLenFunc = BinLogVar; + ret = BSL_LOG_RegBinLogFunc(&funcs); + ASSERT_TRUE(ret != BSL_SUCCESS); + + funcs.fixLenFunc = BinLogFix; + funcs.varLenFunc = BinLogVar; + ret = BSL_LOG_RegBinLogFunc(&funcs); + ASSERT_TRUE(ret == BSL_SUCCESS); + + g_binlogFlag = 0; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05001, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, "this is test %d %d", 1, 2, 0, 0); + ASSERT_TRUE(g_binlogFlag == 0); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "this is test %d %d", 1, 2, 0, 0); + ASSERT_TRUE(g_binlogFlag == 1); + + const char *s = "abc"; + g_binlogFlag = 0; + BSL_LOG_BINLOG_VARLEN(BINLOG_ID05001, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "this is test %s", s); + ASSERT_TRUE(g_binlogFlag == 0); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID05001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "this is test %s", s); + ASSERT_TRUE(g_binlogFlag == (uintptr_t)s); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SET_BIN_LOG_LEVEL_API_TC001 + * @title Setting the log level + * @precon nan + * @brief + * 1. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_SEC - 1. + * Expected result 1 is obtained. + * 2. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_SEC. + * Expected result 2 is obtained. + * 3. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_FATAL. + * Expected result 3 is obtained. + * 4. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_ERR. + * Expected result 4 is obtained. + * 5. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_WARN. + * Expected result 5 is obtained. + * 6. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_INFO. + * Expected result 6 is obtained. + * 7. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_DEBUG. + * Expected result 7 is obtained. + * 8. Call the BSL_LOG_SetBinLogLevel interface with the input parameter BSL_LOG_LEVEL_DEBUG + 1. + * Expected result 8 is obtained. + * @expect + * 1.BSL_LOG_ERR_BAD_PARAM + * 2.BSL_SUCCESS + * 3.BSL_SUCCESS + * 4.BSL_SUCCESS + * 5.BSL_SUCCESS + * 6.BSL_SUCCESS + * 7.BSL_SUCCESS + * 8.BSL_LOG_ERR_BAD_PARAM + */ +/* BEGIN_CASE */ +void SDV_BSL_SET_BIN_LOG_LEVEL_API_TC001(void) +{ + TestMemInit(); + + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_SEC - 1) == BSL_LOG_ERR_BAD_PARAM); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_SEC) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_FATAL) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_ERR) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_WARN) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_INFO) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_DEBUG) == BSL_SUCCESS); + ASSERT_TRUE(BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_DEBUG + 1) == BSL_LOG_ERR_BAD_PARAM); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_BIN_LOG_FUNC_TC001 + * @title Demo of dotting logs of the BSL module. The log file is /tmp/HITLS_binlog_test.log. + * @precon nan + * @brief + * 1. Clean up and reopen the file. Expected result 1 is obtained. + * 2. Setting the log level. Expected result 2 is obtained. + * 3. Registering the Dotting Log Function. Expected result 3 is obtained. + * 4. Invoke the 4 parameter dotting to filter logs by log level. Expected result 4 is obtained. + * 5. Invoke the four-parameter dot. Expected result 5 is obtained. + * 6. Invoke the 1 parameter measurement point. + * @expect + * 1. Succeeded in clearing the remaining log files. + * 2. BSL_SUCCESS + * 3. BSL_SUCCESS + * 4. No output is generated in the log file. + * 5. The log file has output. + * 6. The log file has output. + */ +/* BEGIN_CASE */ +void SDV_BSL_BIN_LOG_FUNC_TC001(void) +{ + int32_t ret; + const char *filename = "./HITLS_binlog_test.log"; + remove(filename); + + g_LogOutput = fopen(filename, "w"); + ASSERT_TRUE(g_LogOutput != NULL); + + ret = BSL_LOG_SetBinLogLevel(BSL_LOG_LEVEL_ERR); + ASSERT_TRUE(ret == BSL_SUCCESS); + + BSL_LOG_BinLogFuncs funcs = {BinLogFixFunc, BinLogVarFunc}; + ret = BSL_LOG_RegBinLogFunc(&funcs); + ASSERT_TRUE(ret == BSL_SUCCESS); + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05001, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "this is test %d %d", 1, 2, 0, 0); + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "this is test %d %d", 1, 2, 2147483647, 4294967295); + + BSL_LOG_BINLOG_VARLEN(BINLOG_ID05003, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN, + "this is test msg: %s", "hello world"); + +exit: + fclose(g_LogOutput); // flush and close +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/log/test_suite_sdv_log.data b/testcode/sdv/testcase/bsl/log/test_suite_sdv_log.data new file mode 100644 index 00000000..44018cc6 --- /dev/null +++ b/testcode/sdv/testcase/bsl/log/test_suite_sdv_log.data @@ -0,0 +1,14 @@ +SDV_BSL_LOG_VERSION_API_TC001 +SDV_BSL_LOG_VERSION_API_TC001: + +SDV_BSL_REG_BIN_LOG_FUNC_TC001 +SDV_BSL_REG_BIN_LOG_FUNC_TC001: + +SDV_BSL_BIN_LOG_API_TC001 +SDV_BSL_BIN_LOG_API_TC001: + +SDV_BSL_SET_BIN_LOG_LEVEL_API_TC001 +SDV_BSL_SET_BIN_LOG_LEVEL_API_TC001: + +SDV_BSL_BIN_LOG_FUNC_TC001 +SDV_BSL_BIN_LOG_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/obj/test_suite_sdv_obj.c b/testcode/sdv/testcase/bsl/obj/test_suite_sdv_obj.c new file mode 100644 index 00000000..20439122 --- /dev/null +++ b/testcode/sdv/testcase/bsl/obj/test_suite_sdv_obj.c @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "securec.h" +#include "bsl_errno.h" +#include "bsl_obj.h" +#include "bsl_obj_internal.h" +/* END_HEADER */ + +extern BslOidInfo g_oidTable[]; +extern uint32_t g_tableSize; +/** + * @test SDV_BSL_OBJ_CID_OID_FUNC_TC001 + * @title check whether the relative sequence of cid and oid tables is corrent + * @expect success + */ +/* BEGIN_CASE */ +void SDV_BSL_OBJ_CID_OID_FUNC_TC001() +{ + int32_t cidIndex = 0; + int32_t oidIndex = 0; + int32_t ret = 0; + while (cidIndex < BSL_CID_MAX && oidIndex < (int32_t)g_tableSize) { + if ((int32_t)g_oidTable[oidIndex].cid == cidIndex) { + ret++; + cidIndex++; + oidIndex++; + continue; + } + if ((int32_t)g_oidTable[oidIndex].cid > cidIndex) { + cidIndex++; + continue; + } + oidIndex++; + } + ASSERT_TRUE(ret == (int32_t)g_tableSize); +exit: + return; +} + +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/obj/test_suite_sdv_obj.data b/testcode/sdv/testcase/bsl/obj/test_suite_sdv_obj.data new file mode 100644 index 00000000..e37f2f84 --- /dev/null +++ b/testcode/sdv/testcase/bsl/obj/test_suite_sdv_obj.data @@ -0,0 +1,2 @@ +SDV_BSL_OBJ_CID_OID_FUNC_TC001 +SDV_BSL_OBJ_CID_OID_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/pem/test_suite_sdv_pem.c b/testcode/sdv/testcase/bsl/pem/test_suite_sdv_pem.c new file mode 100644 index 00000000..dc26ce57 --- /dev/null +++ b/testcode/sdv/testcase/bsl/pem/test_suite_sdv_pem.c @@ -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. + */ +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "securec.h" +#include "bsl_errno.h" +#include "bsl_sal.h" +#include "bsl_pem_internal.h" + +/* END_HEADER */ + +/* BEGIN_CASE */ +void SDV_BSL_PEM_ISPEM_FUNC_TC001(char *data, int expflag) +{ + char *encode = data; + uint32_t encodeLen = strlen(data); + bool isPem = BSL_PEM_IsPemFormat(encode, encodeLen); + ASSERT_TRUE(isPem == (bool)expflag); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_PEM_ISPEM_FUNC_TC002(void) +{ + char *aa = "aaaaaaaa"; + ASSERT_TRUE(BSL_PEM_IsPemFormat(NULL, 0) == false); + ASSERT_TRUE(BSL_PEM_IsPemFormat(aa, strlen(aa)) == false); +exit: + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_PEM_PARSE_FUNC_TC001(char *encode, char *head, char *tail, int expRes) +{ + BSL_PEM_Symbol sym = {head, tail}; + char *pemdata = encode; + uint32_t len = strlen(encode); + uint8_t *asn1Encode = NULL; + uint32_t asn1Len; + ASSERT_TRUE(BSL_PEM_ParsePem2Asn1(&pemdata, &len, &sym, &asn1Encode, &asn1Len) == expRes); +exit: + BSL_SAL_Free(asn1Encode); + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_PEM_PARSE_FUNC_TC002(void) +{ + BSL_PEM_Symbol sym = {BSL_PEM_EC_PIR_KEY_BEGIN_STR, BSL_PEM_EC_PIR_KEY_END_STR}; + char *pemdata = "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEIAadtjyegBKXLH9xvNDvH24j7cn3PsaNSXSMIVmvJZM7oAoGCCqGSM49\n" + "AwEHoUQDQgAEPFKNDGyE7HES1hPd8mXydX4QunGvk37ISPOhXJStzxTt8sWdcEtV\n" + "gaXhArNx9Dz8pKIhoGcviy8xML3wPICv9Q==\n" + "-----END EC PRIVATE KEY-----\n" + "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEIAadtjyegBKXLH9xvNDvH24j7cn3PsaNSXSMIVmvJZM7oAoGCCqGSM49\n" + "AwEHoUQDQgAEPFKNDGyE7HES1hPd8mXydX4QunGvk37ISPOhXJStzxTt8sWdcEtV\n" + "gaXhArNx9Dz8pKIhoGcviy8xML3wPICv9Q==\n" + "-----END EC PRIVATE KEY-----\n"; + int32_t len = strlen(pemdata); + char *next = pemdata; + uint32_t nextLen = len; + uint8_t *asn1Encode = NULL; + uint32_t asn1Len; + ASSERT_TRUE(BSL_PEM_ParsePem2Asn1(&next, &nextLen, &sym, &asn1Encode, &asn1Len) == BSL_SUCCESS); + BSL_SAL_Free(asn1Encode); + ASSERT_TRUE(BSL_PEM_ParsePem2Asn1(&next, &nextLen, &sym, &asn1Encode, &asn1Len) == BSL_SUCCESS); +exit: + BSL_SAL_Free(asn1Encode); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/bsl/pem/test_suite_sdv_pem.data b/testcode/sdv/testcase/bsl/pem/test_suite_sdv_pem.data new file mode 100644 index 00000000..a48693a6 --- /dev/null +++ b/testcode/sdv/testcase/bsl/pem/test_suite_sdv_pem.data @@ -0,0 +1,47 @@ +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----BEGIN":0 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----END----------END----------END----------END----------END-----":0 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----BEGIN aaaaENDaaaaaaaaaaENDaaaaaaaaaENDaaaaaaaENDaaaaaaa-":0 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----BEGIN aaaaa-----\n----ENDaaaaaaENaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----BEGIN aaaaa-----\n-----ENDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----BEGIN aaaaa-----\n-----END aaa ----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"-----BEGIN aaaaa-----\n-----END aaa -----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":1 + +SDV_BSL_PEM_ISPEM_FUNC_TC001 +SDV_BSL_PEM_ISPEM_FUNC_TC001:"aaaa-----BEGIN aaaaa-----\n-----END aaa -----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":1 + +SDV_BSL_PEM_ISPEM_FUNC_TC002 +SDV_BSL_PEM_ISPEM_FUNC_TC002: + +SDV_BSL_PEM_PARSE_FUNC_TC001 +SDV_BSL_PEM_PARSE_FUNC_TC001:"aaaaaaaaaaaaaaaa":"-----BEGIN CERTIFICATE-----":"-----END CERTIFICATE-----":BSL_PEM_INVALID + +SDV_BSL_PEM_PARSE_FUNC_TC001 +SDV_BSL_PEM_PARSE_FUNC_TC001:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"-----BEGIN CERTIFICATE-----":"-----END CERTIFICATE-----":BSL_PEM_INVALID + +SDV_BSL_PEM_PARSE_FUNC_TC001 +SDV_BSL_PEM_PARSE_FUNC_TC001:"-----BEGIN CERTIFICATE-----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"-----BEGIN CERTIFICATE-----":"-----END CERTIFICATE-----":BSL_PEM_INVALID + +SDV_BSL_PEM_PARSE_FUNC_TC001 +SDV_BSL_PEM_PARSE_FUNC_TC001:"-----BEGIN CERTIFICATE-----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-----END CERTIFICATE-----\n":"-----BEGIN CERTIFICATE-----":"-----END CERTIFICATE-----":BSL_SUCCESS + +SDV_BSL_PEM_PARSE_FUNC_TC001 +SDV_BSL_PEM_PARSE_FUNC_TC001:"-----BEGIN RSA PRIVATE KEY-----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-----END RSA PRIVATE KEY-----\n":"-----BEGIN CERTIFICATE-----":"-----END CERTIFICATE-----":BSL_PEM_SYMBOL_NOT_FOUND + +SDV_BSL_PEM_PARSE_FUNC_TC001 +SDV_BSL_PEM_PARSE_FUNC_TC001:"-----BEGIN CERTIFICATE-----aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-----END RSA PRIVATE KEY-----\n":"-----BEGIN CERTIFICATE-----":"-----END CERTIFICATE-----":BSL_PEM_SYMBOL_NOT_FOUND + +SDV_BSL_PEM_PARSE_FUNC_TC002 +SDV_BSL_PEM_PARSE_FUNC_TC002: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal.c b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal.c new file mode 100644 index 00000000..4ca0c240 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal.c @@ -0,0 +1,787 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_errno.h" +#include "sal_atomic.h" + +#define TEST_THREAD_DEFAULT_TC001_WRITE_CNT 100000 +#define TEST_WRITE_PID_CNT 2 +#define TEST_READ_PID_CNT 2 + +int g_threadDefaultWrite001 = 0; +int g_threadDefaultRead001 = 0; +uint64_t g_threadDefaultId001 = 0; + +static void *StdMalloc(uint32_t len) +{ + return malloc((size_t)len); +} + +static int32_t pthreadRWLockNew(BSL_SAL_ThreadLockHandle *lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + pthread_rwlock_t *newLock; + newLock = (pthread_rwlock_t *)BSL_SAL_Malloc(sizeof(pthread_rwlock_t)); + if (newLock == NULL) { + return BSL_MALLOC_FAIL; + } + if (pthread_rwlock_init(newLock, NULL) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + *lock = newLock; + return BSL_SUCCESS; +} + +static void pthreadRWLockFree(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return; + } + pthread_rwlock_destroy((pthread_rwlock_t *)lock); + BSL_SAL_FREE(lock); +} + +static int32_t pthreadRWLockReadLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_rdlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t pthreadRWLockWriteLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_wrlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t pthreadRWLockUnlock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_unlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static uint64_t pthreadGetId(void) +{ + return (uint64_t)pthread_self(); +} + +#ifdef HITLS_BSL_SAL_THREAD +static void *TEST_Read(void *arg) +{ + BSL_SAL_ThreadLockHandle lock = (BSL_SAL_ThreadLockHandle)arg; + int32_t ret = BSL_SAL_ThreadReadLock(lock); + g_threadDefaultRead001 = g_threadDefaultWrite001; + BSL_SAL_ThreadUnlock(lock); + ASSERT_TRUE(ret == BSL_SUCCESS); +exit: + return NULL; +} + +static void *TEST_Write(void *arg) +{ + BSL_SAL_ThreadLockHandle lock = (BSL_SAL_ThreadLockHandle)arg; + int32_t ret = BSL_SUCCESS; + for (size_t i = 0; i < TEST_THREAD_DEFAULT_TC001_WRITE_CNT; i++) { + if (BSL_SAL_ThreadWriteLock(lock) != BSL_SUCCESS) { + ret = BSL_SAL_ERR_UNKNOWN; + } + g_threadDefaultWrite001++; + g_threadDefaultId001 = BSL_SAL_ThreadGetId(); + BSL_SAL_ThreadUnlock(lock); + } + + ASSERT_TRUE(ret == BSL_SUCCESS); +exit: + return NULL; +} +#endif + +/* END_HEADER */ + +/** + * @test SDV_BSL_SAL_REGMEM_API_TC001 + * @title Registering memory-related functions + * @precon nan + * @brief + * 1. Call BSL_SAL_Malloc to allocate 0-byte space. Expected result 1 is obtained. + * 2. Call BSL_SAL_Malloc to allocate 1-byte space. Expected result 2 is obtained. + * 3. Call BSL_SAL_Calloc to allocate a large memory space. Expected result 3 is obtained. + * 4. Call BSL_SAL_RegMemCallback to transfer an exception parameter. Expected result 4 is obtained. + * 5. Call BSL_SAL_RegMemCallback to transfer an normal parameter. Expected result 5 is obtained. + * 6. Call BSL_SAL_Malloc to allocate 8-byte space. Expected result 6 is obtained. + * 7. Call BSL_SAL_FREE to free 8-byte space. Expected result 7 is obtained. + * @expect + * 1. Failed to apply for the memory. NULL is returned. + * 2. Memory application succeeded. + * 3. Failed to apply for the memory. NULL is returned. + * 4. Failed to register the callback, return BSL_SAL_ERR_BAD_PARAM + * 5. Registration callback succeeded, return BSL_SUCCESS. + * 6. Memory application succeeded. + * 7. The memory is released successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_REGMEM_API_TC001(void) +{ + void *ptr = NULL; + + ptr = BSL_SAL_Malloc(0); + ASSERT_TRUE(ptr == NULL); +#ifdef HITLS_BSL_SAL_MEM + ptr = BSL_SAL_Malloc(1); + ASSERT_TRUE(ptr != NULL); + BSL_SAL_FREE(ptr); +#endif + + ptr = BSL_SAL_Calloc(0xFFFFFFFF, 0xFFFFFFFF); + ASSERT_TRUE(ptr == NULL); + + ASSERT_TRUE(BSL_SAL_RegMemCallback(NULL) == BSL_SAL_ERR_BAD_PARAM); + + BSL_SAL_MemCallback cb = {NULL, NULL}; + ASSERT_TRUE(BSL_SAL_RegMemCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfMalloc = StdMalloc; + cb.pfFree = NULL; + ASSERT_TRUE(BSL_SAL_RegMemCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfMalloc = NULL; + cb.pfFree = free; + ASSERT_TRUE(BSL_SAL_RegMemCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfMalloc = StdMalloc; + cb.pfFree = free; + ASSERT_TRUE(BSL_SAL_RegMemCallback(&cb) == BSL_SUCCESS); + + ptr = BSL_SAL_Malloc(0); + ASSERT_TRUE(ptr != NULL); + + BSL_SAL_FREE(ptr); + ASSERT_TRUE(ptr == NULL); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_REG_THREAD_API_TC001 + * @title Register thread-related functions. + * @precon nan + * @brief + * 1. Call BSL_SAL_RegThreadCallback to transfer an exception parameter. Expected result 1 is obtained. + * 2. Call BSL_SAL_RegMemCallback to transfer an normal parameter. Expected result 2 is obtained. + * 3. Call BSL_SAL_ThreadLockNew to transfer an exception parameter. Expected result 3 is obtained. + * 4. Call BSL_SAL_ThreadReadLock to transfer an exception parameter. Expected result 4 is obtained. + * 5. Call BSL_SAL_ThreadWriteLock to transfer an exception parameter. Expected result 5 is obtained. + * 6. Call BSL_SAL_ThreadUnlock to transfer an exception parameter. Expected result 6 is obtained. + * 7. Call BSL_SAL_ThreadLockFree to transfer an exception parameter. Expected result 7 is obtained. + * @expect + * 1. Failed to register the callback, return BSL_SAL_ERR_BAD_PARAM + * 2. Registration callback succeeded, return BSL_SUCCESS. + * 9. Failed to create the new lock, return BSL_SAL_ERR_BAD_PARAM + * 10. Failed to create the read lock, return BSL_SAL_ERR_BAD_PARAM + * 11. Failed to create the write lock, return BSL_SAL_ERR_BAD_PARAM + * 12. Failed to unlock, return BSL_SAL_ERR_BAD_PARAM + * 13. No return value + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_REG_THREAD_API_TC001(void) +{ + ASSERT_TRUE(BSL_SAL_RegThreadCallback(NULL) == BSL_SAL_ERR_BAD_PARAM); + + BSL_SAL_ThreadCallback cb = { 0 }; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfThreadLockNew = pthreadRWLockNew; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfThreadLockFree = pthreadRWLockFree; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfThreadReadLock = pthreadRWLockReadLock; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfThreadWriteLock = pthreadRWLockWriteLock; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfThreadUnlock = pthreadRWLockUnlock; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SAL_ERR_BAD_PARAM); + + cb.pfThreadGetId = pthreadGetId; + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SUCCESS); + + // Cannot create a lock handle because the pointer of the pointer is NULL. + ASSERT_TRUE(BSL_SAL_ThreadLockNew(NULL) == BSL_SAL_ERR_BAD_PARAM); + ASSERT_TRUE(BSL_SAL_ThreadReadLock(NULL) == BSL_SAL_ERR_BAD_PARAM); + ASSERT_TRUE(BSL_SAL_ThreadWriteLock(NULL) == BSL_SAL_ERR_BAD_PARAM); + ASSERT_TRUE(BSL_SAL_ThreadUnlock(NULL) == BSL_SAL_ERR_BAD_PARAM); + BSL_SAL_ThreadLockFree(NULL); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_MEM_API_TC001 + * @title Test the memory application function when the memory registration callback function is not invoked. + * @precon nan + * @brief + * 1. Call BSL_SAL_Malloc to allocate 100-byte space. Expected result 1 is obtained. + * 2. Call BSL_SAL_ClearFree to free 100-byte space. Expected result 2 is obtained. + * @expect + * 1. Memory application succeeded. + * 2. The memory is released successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_MEM_API_TC001(void) +{ +#ifndef HITLS_BSL_SAL_MEM + SKIP_TEST(); +#else + // 1 + void *obj = BSL_SAL_Malloc(100); + ASSERT_TRUE(obj != NULL); + + memset_s(obj, 100, 0x1, 100); + + BSL_SAL_ClearFree(obj, 100); +exit: + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_MEM_API_TC001 + * @title Test the memory application function when the memory registration callback function is not invoked. + * @precon nan + * @brief + * 1. Call BSL_SAL_Malloc to allocate 1-byte space. Expected result 1 is obtained. + * 2. Call BSL_SAL_Calloc to allocate 1000-byte space. Expected result 2 is obtained. + * @expect + * 1. Memory application succeeded. + * 2. Memory application succeeded. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_MEM_API_TC002(void) +{ +#ifndef HITLS_BSL_SAL_MEM + SKIP_TEST(); +#else + // 1 + void *obj = BSL_SAL_Malloc(1); + ASSERT_TRUE(obj != NULL); + BSL_SAL_FREE(obj); + + uint8_t objZero3[1000] = {0}; + uint8_t *obj3 = (uint8_t *)BSL_SAL_Calloc(1000, sizeof(uint8_t)); + ASSERT_TRUE(obj3 != NULL); + ASSERT_TRUE(memcmp(objZero3, obj3, 1000) == 0); + BSL_SAL_FREE(obj3); +exit: + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_DUMP_API_TC001 + * @title Test the function of the dump interface when the memory-related callback is not registered. + * @precon nan + * @brief + * 1. Call BSL_SAL_Dump with the source memory address set to NULL. Expected result 1 is obtained. + * 2. Call BSL_SAL_Dump to set the total memory size to 0. Expected result 2 is obtained. + * 3. Call BSL_SAL_Dump interface to transfer normal parameters. Expected result 3 is obtained. + * @expect + * 1. Failed to duplicate the memory space. Return NULL. + * 2. Failed to duplicate the memory space. Return NULL. + * 3. Succeeded in duplicate the memory space. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_DUMP_API_TC001(void) +{ +#ifndef HITLS_BSL_SAL_MEM + SKIP_TEST(); +#else + uint32_t memLen = 1024U; + void *testPtr = NULL; + void *srcPtr = BSL_SAL_Malloc(memLen); + ASSERT_TRUE(srcPtr != NULL); + + // 1 + ASSERT_TRUE(BSL_SAL_Dump(NULL, memLen) == NULL); + + // 2 + ASSERT_TRUE(BSL_SAL_Dump(srcPtr, 0) == NULL); + + // 3 + testPtr = BSL_SAL_Dump(srcPtr, memLen); + ASSERT_TRUE(testPtr != NULL); + + ASSERT_TRUE(memcmp(testPtr, srcPtr, memLen) == 0); +exit: + BSL_SAL_FREE(srcPtr); + BSL_SAL_FREE(testPtr); +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_REALLOC_API_TC001 + * @title Test functions related to reallocation when the memory-related callback is not registered. + * @precon nan + * @brief + * 1. The size of the extended memory is smaller than the original size. Expected result 1 is obtained. + * 2. The size of the extended memory is smaller than the original size. Expected result 2 is obtained. + * @expect + * 1. Success. The extended memory address is returned. + * 2. Success. The extended memory address is returned. No ASAN alarm is generated for realloc memory read/write. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_REALLOC_API_TC001(void) +{ +#ifndef HITLS_BSL_SAL_MEM + SKIP_TEST(); +#else + uint32_t originSize = 2000u; + uint32_t biggerSize = 3000u; + uint32_t smallerSize = 1000u; + void *obj = BSL_SAL_Malloc(originSize); + ASSERT_TRUE(obj != NULL); + + // 1 + void *obj2 = BSL_SAL_Realloc(obj, smallerSize, originSize); + + // 2 + uint8_t *obj3 = (uint8_t *)BSL_SAL_Realloc(obj2, biggerSize, smallerSize); + ASSERT_TRUE(obj3 != NULL); + ASSERT_TRUE(memset_s(obj3, biggerSize, 1, biggerSize) == EOK); + ASSERT_TRUE(obj3[biggerSize - 1] == 1); + + // The realloc releases the obj. Therefore, the obj does not need to be released. + // The value of realloc size to 0 is an implementation definition. Therefore, the test is not performed. +exit: + BSL_SAL_FREE(obj3); +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_THREAD_CREATE_FUNC_TC001 + * @title Creating and Closing Threads test + * @precon nan + * @brief + * 1. Unregistered thread-related callback and create a thread lock. Expected result 1 is obtained. + * 2. Call BSL_SAL_ThreadCreate to transfer abnormal parameters. Expected result 2 is obtained. + * 3. Call BSL_SAL_ThreadCreate to transfer normal parameters. Expected result 3 is obtained. + * 4. Call BSL_SAL_ThreadClose to transfer normal parameters. Expected result 4 is obtained. + * 5. Call BSL_SAL_ThreadClose to transfer abnormal parameters. Expected result 5 is obtained. + * 6. Release the lock. Expected result 6 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_SAL_ERR_BAD_PARAM + * 3. BSL_SUCCESS + * 4. The thread is closed successfully. + * 5. No return value + * 6. Lock released successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_THREAD_CREATE_FUNC_TC001(void) +{ +#ifndef HITLS_BSL_SAL_THREAD + SKIP_TEST(); +#else + BSL_SAL_ThreadLockHandle lock = NULL; + ASSERT_TRUE(BSL_SAL_ThreadLockNew(&lock) == BSL_SUCCESS); + BSL_SAL_ThreadId thread = NULL; + int32_t ret = BSL_SAL_ThreadCreate(&thread, NULL, NULL); + ASSERT_TRUE(ret == BSL_SAL_ERR_BAD_PARAM); + ret = BSL_SAL_ThreadCreate(NULL, TEST_Read, NULL); + ASSERT_TRUE(ret == BSL_SAL_ERR_BAD_PARAM); + ret = BSL_SAL_ThreadCreate(&thread, TEST_Read, lock); + ASSERT_TRUE(ret == BSL_SUCCESS); + BSL_SAL_ThreadClose(thread); + BSL_SAL_ThreadClose(NULL); + BSL_SAL_ThreadLockFree(lock); +exit: + return; +#endif +} +/* END_CASE */ + +static void TestRunOnce(void) +{ + return; +} +/** + * @test SDV_BSL_SAL_THREAD_API_TC001 + * @title Creating and Disabling Condition Variable Test + * @precon nan + * @brief + * 1. Call BSL_SAL_ThreadRunOnce to transfer abnormal parameters. Expected result 1 is obtained. + * 2. Call BSL_SAL_ThreadRunOnce to transfer normal parameters. Expected result 2 is obtained. + * @expect + * 1. BSL_SAL_ERR_BAD_PARAM + * 2. BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_THREAD_API_TC001(void) +{ + uint32_t isErrInit = 0; + ASSERT_EQ(BSL_SAL_ThreadRunOnce(NULL, TestRunOnce), BSL_SAL_ERR_BAD_PARAM); + ASSERT_EQ(BSL_SAL_ThreadRunOnce(&isErrInit, NULL), BSL_SAL_ERR_BAD_PARAM); + ASSERT_EQ(BSL_SAL_ThreadRunOnce(&isErrInit, TestRunOnce), BSL_SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_CONDVAR_CREATE_FUNC_TC001 + * @title Creating and Disabling Condition Variable Test + * @precon nan + * @brief + * 1. Call BSL_SAL_CreateCondVar to transfer abnormal parameters. Expected result 1 is obtained. + * 2. Call BSL_SAL_CreateCondVar to transfer normal parameters. Expected result 2 is obtained. + * 3. Call BSL_SAL_CondSignal to transfer abnormal parameters. Expected result 3 is obtained. + * 4. Call BSL_SAL_CondSignal to transfer normal parameters. Expected result 4 is obtained. + * 5. Call BSL_SAL_DeleteCondVar to transfer abnormal parameters. Expected result 5 is obtained. + * 6. Call BSL_SAL_DeleteCondVar to transfer normal parameters. Expected result 6 is obtained. + * 7. Call BSL_SAL_DeleteCondVar to delete the deleted condVar. Expected result 7 is obtained. + * @expect + * 1. BSL_SAL_ERR_BAD_PARAM + * 2. BSL_SUCCESS + * 3. BSL_SAL_ERR_BAD_PARAM + * 4. BSL_SUCCESS + * 5. BSL_SAL_ERR_BAD_PARAM + * 6. BSL_SUCCESS + * 7. BSL_SAL_ERR_UNKNOWN + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_CONDVAR_CREATE_FUNC_TC001(void) +{ +#ifndef HITLS_BSL_SAL_THREAD + SKIP_TEST(); +#else + BSL_SAL_CondVar condVar = NULL; + int32_t ret = BSL_SAL_CreateCondVar(NULL); + ASSERT_TRUE(ret == BSL_SAL_ERR_BAD_PARAM); + ret = BSL_SAL_CreateCondVar(&condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + ret = BSL_SAL_CondSignal(NULL); + ASSERT_TRUE(ret == BSL_SAL_ERR_BAD_PARAM); + ret = BSL_SAL_CondSignal(condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + ret = BSL_SAL_DeleteCondVar(NULL); + ASSERT_TRUE(ret == BSL_SAL_ERR_BAD_PARAM); + ret = BSL_SAL_DeleteCondVar(condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); +exit: + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_CONDVAR_WAIT_API_TC001 + * @title Creating and Disabling Condition Variable Test + * @precon nan + * @brief + * 1. Call BSL_SAL_CreateCondVar to create a condition variable. Expected result 1 is obtained. + * 2. Unregistered thread-related callback and create a thread lock. Expected result 2 is obtained. + * 3. Call BSL_SAL_CondTimedwaitMs to transfer abnormal parameters. Expected result 3 is obtained. + * 4. Call BSL_SAL_CondTimedwaitMs to transfer normal parameters. Expected result 4 is obtained. + * 5. Release the lock. Expected result 5 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_SUCCESS + * 3. BSL_SAL_ERR_BAD_PARAM + * 4. BSL_SUCCESS + * 5. Lock released successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_CONDVAR_WAIT_API_TC001(void) +{ +#ifndef HITLS_BSL_SAL_THREAD + SKIP_TEST(); +#else + BSL_SAL_ThreadLockHandle lock = NULL; + ASSERT_TRUE(BSL_SAL_ThreadLockNew(&lock) == BSL_SUCCESS); + + BSL_SAL_CondVar condVar = NULL; + int32_t ret = BSL_SAL_CreateCondVar(&condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + + ret = BSL_SAL_CondTimedwaitMs(NULL, condVar, 10); + ASSERT_TRUE(ret == BSL_SAL_ERR_BAD_PARAM); + + ret = BSL_SAL_CondTimedwaitMs(lock, condVar, 1); + ASSERT_TRUE(ret == BSL_SAL_ERR_UNKNOWN); + ret = BSL_SAL_DeleteCondVar(condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + BSL_SAL_ThreadLockFree(lock); +exit: + return; +#endif +} +/* END_CASE */ + +#ifdef HITLS_BSL_SAL_THREAD +static BSL_SAL_CondVar g_condVar = NULL; +static pthread_mutex_t g_lock; + +static void *ThreadTest(void *arg) +{ + (void)arg; + int32_t ret1 = BSL_SAL_CondTimedwaitMs(&g_lock, g_condVar, 10000000); + ASSERT_TRUE(ret1 == BSL_SUCCESS); +exit: + return NULL; +} +#endif + +/** + * @test SDV_BSL_SAL_CONDVAR_WAIT_FUNC_TC001 + * @title Creating and Disabling Condition Variable Test + * @precon nan + * @brief + * 1. Call BSL_SAL_CreateCondVar to create a condition variable. Expected result 1 is obtained. + * 2. Call BSL_SAL_ThreadCreate to create the timedwait thread. Expected result 2 is obtained. + * 3. Call BSL_SAL_CondSignal to transfer normal parameters. Expected result 3 is obtained. + * 4. Call BSL_SAL_DeleteCondVar to transfer normal parameters. Expected result 4 is obtained. + * 5. Release the lock. Expected result 5 is obtained. + * @expect + * 1. BSL_SUCCESS + * 2. BSL_SUCCESS + * 3. BSL_SUCCESS + * 4. BSL_SUCCESS + * 5. Lock released successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_CONDVAR_WAIT_FUNC_TC001(void) +{ +#ifndef HITLS_BSL_SAL_THREAD + SKIP_TEST(); +#else + int32_t ret = BSL_SAL_CreateCondVar(&g_condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + pthread_mutex_init(&g_lock, NULL); + + BSL_SAL_ThreadId thread = NULL; + ret = BSL_SAL_ThreadCreate(&thread, ThreadTest, NULL); + ASSERT_TRUE(ret == BSL_SUCCESS); + + sleep(1); // Wait one seconds to send the signal + pthread_mutex_lock(&g_lock); + ret = BSL_SAL_CondSignal(g_condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + pthread_mutex_unlock(&g_lock); + + BSL_SAL_ThreadClose(thread); + ret = BSL_SAL_DeleteCondVar(g_condVar); + ASSERT_TRUE(ret == BSL_SUCCESS); + pthread_mutex_destroy(&g_lock); +exit: + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_STR_API_TC001 + * @title Test on the function of inputting abnormal parameters for character string processing of the BSL module + * @precon nan + * @brief + * 1. Call BSL_SAL_StrcaseCmp to transfer abnormal parameters. Expected result 1 is obtained. + * 2. Call BSL_SAL_Memchr to transfer abnormal parameters. Expected result 2 is obtained. + * 3. Call BSL_SAL_Atoi to transfer abnormal parameters. Expected result 3 is obtained. + * 4. Call BSL_SAL_Strnlen to transfer abnormal parameters. Expected result 4 is obtained. + * @expect + * 1. BSL_NULL_INPUT + * 2. NULL + * 3. 0 + * 4. 0 + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_STR_API_TC001(void) +{ +#ifndef HITLS_BSL_SAL_STR + SKIP_TEST(); +#else + char *str1 = "aaastr1"; + char *str2 = "aaastr2"; + ASSERT_TRUE(BSL_SAL_StrcaseCmp(str1, NULL) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_SAL_StrcaseCmp(NULL, str2) == BSL_NULL_INPUT); + ASSERT_TRUE(BSL_SAL_Memchr(NULL, 's', 10) == NULL); + ASSERT_TRUE(BSL_SAL_Atoi(NULL) == 0); + ASSERT_TRUE(BSL_SAL_Strnlen(NULL, 0) == 0); +exit: + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_STR_FUNC_TC001 + * @title Character string processing function of the BSL module + * @precon nan + * @brief + * 1. Call BSL_SAL_StrcaseCmp to transfer normal parameters. Expected result 1 is obtained. + * 2. Call BSL_SAL_Memchr to transfer normal parameters. Expected result 2 is obtained. + * 3. Call BSL_SAL_Atoi to transfer normal parameters. Expected result 3 is obtained. + * 4. Call BSL_SAL_Strnlen to transfer normal parameters. Expected result 4 is obtained. + * @expect + * 1. String comparison succeeded. + * 2. Searching for the corresponding character succeeded. + * 3. Succeeded in converting a character string to a number. + * 4. Obtaining the length of the given string succeeded. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_STR_FUNC_TC001(void) +{ +#ifndef HITLS_BSL_SAL_STR + SKIP_TEST(); +#else + char *str1 = "aaastr1"; + char *str2 = "aaastr2"; + char *str3 = " aaastr3"; + ASSERT_TRUE(BSL_SAL_StrcaseCmp(str1, str1) == 0); + ASSERT_TRUE(BSL_SAL_StrcaseCmp(str1, str2) == -1); + ASSERT_TRUE(BSL_SAL_StrcaseCmp(str2, str1) == 1); + + ASSERT_TRUE(BSL_SAL_Memchr(str1, 's', strlen(str1)) != NULL); + ASSERT_TRUE(BSL_SAL_Memchr(str1, '1', 5) == NULL); + ASSERT_TRUE(BSL_SAL_Memchr(str1, '1', strlen(str1)) != NULL); + ASSERT_TRUE(BSL_SAL_Memchr(str1, 'b', strlen(str1)) == NULL); + ASSERT_TRUE(BSL_SAL_Memchr(str3, ' ', strlen(str3)) != NULL); + + ASSERT_TRUE(BSL_SAL_Atoi("-100") == -100); + ASSERT_TRUE(BSL_SAL_Atoi("123") == 123); + ASSERT_TRUE(BSL_SAL_Atoi("123.456") == 123); + ASSERT_TRUE(BSL_SAL_Atoi(" 123 ") == 123); + ASSERT_TRUE(BSL_SAL_Atoi("000123") == 123); + ASSERT_TRUE(BSL_SAL_Atoi(" 1 23") == 1); + ASSERT_TRUE(BSL_SAL_Atoi("\n1 23") == 1); + ASSERT_TRUE(BSL_SAL_Atoi("1\n23") == 1); + ASSERT_TRUE(BSL_SAL_Atoi("0\n23") == 0); + + ASSERT_TRUE(BSL_SAL_Strnlen(str1, strlen(str1)) == 7); + ASSERT_TRUE(BSL_SAL_Strnlen(str1, 100) == 7); + ASSERT_TRUE(BSL_SAL_Strnlen(str1, 3) == 3); +exit: + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_THREAD_DEFAULT_FUNC_TC001 + * @title Default Thread Related Functions + * @precon nan + * @brief + * 1. Unregistered thread-related callback and create a thread lock. Expected result 1 is obtained. + * 2. Create two read threads and two write threads, read and write concurrent threads, + * and obtain IDs from the threads. Expected result 2 is obtained. + * 3. Obtain the process ID and compare it with the subthread ID. Expected result 3 is obtained. + * 4. Obtain the subprocess ID and compare it with the current process ID. Expected result 4 is obtained. + * 5. Release the lock. Expected result 5 is obtained. + * @expect + * 1. Thread lock created successfully. + * 2. The read thread and write thread are successfully created. + * 3. The process ID and subthread ID are different. + * 4. The current subprocess ID is the same as the current process ID. + * 5. Lock released successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_THREAD_DEFAULT_FUNC_TC001(void) +{ +#ifndef HITLS_BSL_SAL_THREAD + SKIP_TEST(); +#else + g_threadDefaultWrite001 = 0; + g_threadDefaultRead001 = 0; + g_threadDefaultId001 = 0; + + // 1 + BSL_SAL_ThreadLockHandle lock = NULL; + ASSERT_TRUE(BSL_SAL_ThreadLockNew(&lock) == BSL_SUCCESS); + + // 2 + BSL_SAL_ThreadId pid[TEST_WRITE_PID_CNT]; + BSL_SAL_ThreadId pid2[TEST_READ_PID_CNT]; + size_t i = 0; + size_t m = 0; + for (i = 0u; i < TEST_WRITE_PID_CNT; i++) { + ASSERT_TRUE(BSL_SAL_ThreadCreate(&pid[i], TEST_Write, (void *)lock) == BSL_SUCCESS); + } + for (m = 0u; m < TEST_READ_PID_CNT; m++) { + ASSERT_TRUE(BSL_SAL_ThreadCreate(&pid2[m], TEST_Read, (void *)lock) == BSL_SUCCESS); + } + for (size_t j = 0; j < i; j++) { + BSL_SAL_ThreadClose(pid[j]); + } + for (size_t n = 0; n < m; n++) { + BSL_SAL_ThreadClose(pid[n]); + } + ASSERT_EQ(g_threadDefaultWrite001, TEST_READ_PID_CNT * TEST_THREAD_DEFAULT_TC001_WRITE_CNT); + // Concurrent reads. The read result is uncertain and does not determine whether to perform the read operation. + + // 3 + uint64_t mainId = BSL_SAL_ThreadGetId(); + ASSERT_TRUE(mainId != g_threadDefaultId001); + + // 4 + uint64_t childId = 0; + pid_t pidFork = fork(); + if (pidFork == 0) { + // The child process + childId = BSL_SAL_ThreadGetId(); + } else { + // The parent process + goto exit; + } + // The default implementation uses pthread_self. Therefore, the IDs of the parent and child processes are the same. + ASSERT_EQ(childId, mainId); +exit: + // 5 + BSL_SAL_ThreadLockFree(lock); + g_threadDefaultWrite001 = 0; + g_threadDefaultRead001 = 0; + g_threadDefaultId001 = 0; +#endif +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal.data b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal.data new file mode 100644 index 00000000..03dec383 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal.data @@ -0,0 +1,44 @@ +SDV_BSL_SAL_REGMEM_API_TC001 +SDV_BSL_SAL_REGMEM_API_TC001: + +SDV_BSL_SAL_REG_THREAD_API_TC001 +SDV_BSL_SAL_REG_THREAD_API_TC001: + +SDV_BSL_SAL_REG_THREAD_API_TC001 +SDV_BSL_SAL_REG_THREAD_API_TC001: + +SDV_BSL_SAL_MEM_API_TC001 +SDV_BSL_SAL_MEM_API_TC001: + +SDV_BSL_SAL_MEM_API_TC002 +SDV_BSL_SAL_MEM_API_TC002: + +SDV_BSL_SAL_DUMP_API_TC001 +SDV_BSL_SAL_DUMP_API_TC001: + +SDV_BSL_SAL_REALLOC_API_TC001 +SDV_BSL_SAL_REALLOC_API_TC001: + +SDV_BSL_SAL_THREAD_CREATE_FUNC_TC001 +SDV_BSL_SAL_THREAD_CREATE_FUNC_TC001: + +SDV_BSL_SAL_THREAD_API_TC001 +SDV_BSL_SAL_THREAD_API_TC001: + +SDV_BSL_SAL_CONDVAR_CREATE_FUNC_TC001 +SDV_BSL_SAL_CONDVAR_CREATE_FUNC_TC001: + +SDV_BSL_SAL_CONDVAR_WAIT_API_TC001 +SDV_BSL_SAL_CONDVAR_WAIT_API_TC001: + +SDV_BSL_SAL_CONDVAR_WAIT_FUNC_TC001 +SDV_BSL_SAL_CONDVAR_WAIT_FUNC_TC001: + +SDV_BSL_SAL_STR_API_TC001 +SDV_BSL_SAL_STR_API_TC001: + +SDV_BSL_SAL_STR_FUNC_TC001 +SDV_BSL_SAL_STR_FUNC_TC001: + +SDV_BSL_SAL_THREAD_DEFAULT_FUNC_TC001 +SDV_BSL_SAL_THREAD_DEFAULT_FUNC_TC001: diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_atomic.c b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_atomic.c new file mode 100644 index 00000000..c0fec82d --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_atomic.c @@ -0,0 +1,108 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "bsl_sal.h" +#include "bsl_errno.h" +#include "sal_atomic.h" + +#define TEST_THREAD_ATOMICADD_CNT 1000000 +#define TEST_ATOMIC_ADD_PID_CNT 3 +#define TEST_ATOMIC_SUB_PID_CNT 3 +int g_threadStartNum = 0; +static BSL_SAL_ThreadLockHandle g_lock = NULL; + +static void *TestAtomicAdd(void *arg) +{ + (void)arg; + int ref = 0; + int ret = 0; + for (int i = 0; i < TEST_THREAD_ATOMICADD_CNT; i++) { + ret = BSL_SAL_AtomicAdd(&g_threadStartNum, 1, &ref, g_lock); + if (ret != BSL_SUCCESS) { + return NULL; + } + } + return NULL; +} + +static void *TestAtomicSub(void *arg) +{ + (void)arg; + int ref = 0; + int ret = 0; + for (int i = 0; i < TEST_THREAD_ATOMICADD_CNT; i++) { + ret = BSL_SAL_AtomicAdd(&g_threadStartNum, -1, &ref, g_lock); + if (ret != BSL_SUCCESS) { + return NULL; + } + } + return NULL; +} +/* END_HEADER */ + +/** + * @test SDV_BSL_SAL_ATOMIC_ADD_TC001 + * @title atomic add test. + * @precon nan + * @brief + * 1. Create thread lock. Expected result 1 is obtained. + * 2. Create 3 threads to perform addition and one thread to perform subtraction. Expected result 2 is obtained. + * 3. Check whether the value after execution is consistent with the expected value. Expected result 3 is obtained. + * 4. Create 2 threads to perform subtraction. Expected result 4 is obtained. + * @expect + * 1. create success + * 2. create success + * 3. The value at the end of the thread is the same as expected. + * 4. The value at the end of the thread is the same as expected. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_ATOMIC_ADD_TC001(void) +{ + ASSERT_TRUE(BSL_SAL_ThreadLockNew(&g_lock) == BSL_SUCCESS); + + pthread_t pid[TEST_ATOMIC_ADD_PID_CNT]; + pthread_t pid2[TEST_ATOMIC_SUB_PID_CNT]; + size_t i; + for (i = 0u; i < TEST_ATOMIC_ADD_PID_CNT; i++) { + pthread_create(&pid[i], NULL, TestAtomicAdd, NULL); + } + pthread_create(&pid2[0], NULL, TestAtomicSub, NULL); + + for (i = 0u; i < TEST_ATOMIC_ADD_PID_CNT; i++) { + pthread_join(pid[i], NULL); + } + pthread_join(pid2[0], NULL); + + ASSERT_EQ(g_threadStartNum, (TEST_ATOMIC_ADD_PID_CNT - 1) * TEST_THREAD_ATOMICADD_CNT); + + for (i = 1; i < TEST_ATOMIC_SUB_PID_CNT; i++) { + pthread_create(&pid2[i], NULL, TestAtomicSub, NULL); + } + + for (i = 1; i < TEST_ATOMIC_SUB_PID_CNT; i++) { + pthread_join(pid2[i], NULL); + } + ASSERT_EQ(g_threadStartNum, 0); + +exit: + g_threadStartNum = 0; + BSL_SAL_ThreadLockFree(g_lock); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_atomic.data b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_atomic.data new file mode 100644 index 00000000..75d71812 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_atomic.data @@ -0,0 +1,2 @@ +SDV_BSL_SAL_ATOMIC_ADD_TC001 +SDV_BSL_SAL_ATOMIC_ADD_TC001: diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_file.c b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_file.c new file mode 100644 index 00000000..bee427e2 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_file.c @@ -0,0 +1,152 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "bsl_errno.h" +#include "bsl_sal.h" + +#define MAX_PATH_LEN 4096 +#define MAX_FILE_LEN 4096 + +void CreateFile(const char *fileName) +{ + FILE *fp = fopen(fileName, "rb"); + if (fp == NULL) { + fp = fopen(fileName, "wb"); + } + fclose(fp); +} + +void RemoveFile(const char *fileName) +{ + remove(fileName); +} + +/* END_HEADER */ + +static void *TestFileOpenFunc(void *args) +{ + bsl_sal_file_handle stream = NULL; + char mode[] = "rb"; + char path[MAX_PATH_LEN]; + (void)args; + (void)strcpy(path, ""); + int ret; + + // 1.If the setting path is empty, the system fails to open the path, and BSL_NULL_INPUT is returned. + ret = BSL_SAL_FileOpen(&stream, path, mode); + ASSERT_EQ(ret, BSL_NULL_INPUT); + + // 2.If the build does not exist, the file path fails to be opened and BSL_SAL_ERR_FILE_Open is returned. + (void)strcpy(path, "ret/sd/s.s"); + ret = BSL_SAL_FileOpen(&stream, path, mode); + ASSERT_EQ(ret, BSL_SAL_ERR_FILE_OPEN); + + // 3.Create a new file and open it. If the operation is successful, BSL_SUCCESS is returned. + (void)strcpy(path, "test.txt"); + CreateFile(path); + ret = BSL_SAL_FileOpen(&stream, path, mode); + ASSERT_EQ(ret, BSL_SUCCESS); + + BSL_SAL_FileClose(stream); + +exit: + RemoveFile(path); + return NULL; +} + +/** + * @test SDV_BSL_SAL_FILE_OPEN_FUNC_TC001 + * @title Test the file opening operation. + * @precon nan + * @brief + * 1. Open the file and leave the path empty. Expected result 1 is obtained. + * 2. Open the file but the file does not exist. Expected result 2 is obtained. + * 3. Create a file and then open the file. The operation is successful. Expected result 3 is obtained. + * @expect + * 1. BSL_NULL_INPUT + * 2. BSL_SAL_ERR_FILE_OPEN + * 3. BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_FILE_OPEN_FUNC_TC001(void) +{ + TestFileOpenFunc(NULL); +} +/* END_CASE */ + +static void *TestFileLengthFunc(void *args) +{ + bsl_sal_file_handle stream = NULL; + char path[MAX_PATH_LEN]; + char writeBuffer[MAX_FILE_LEN] = "we come from same country!"; + char readBuffer[MAX_FILE_LEN]; + int ret; + size_t len = 0; + (void)args; + (void)strcpy(path, "test.txt"); + CreateFile(path); + + ret = BSL_SAL_FileOpen(&stream, path, "wb"); + ASSERT_EQ(ret, BSL_SUCCESS); + + ret = BSL_SAL_FileWrite(stream, writeBuffer, 1, 10); + ASSERT_EQ(ret, BSL_SUCCESS); + + BSL_SAL_FileClose(stream); + + ret = BSL_SAL_FileOpen(&stream, path, "rb"); + ASSERT_EQ(ret, BSL_SUCCESS); + + ret = BSL_SAL_FileRead(stream, readBuffer, 1, 10, &len); // Reads the file content to the buffer. + ASSERT_TRUE(len > 0); // The read length is greater than 0. + ASSERT_EQ(ret, BSL_SUCCESS); + + ret = BSL_SAL_FileLength(path, &len); + + ASSERT_TRUE(len > 0); // The length of the existing file is greater than 0. + ASSERT_EQ(ret, BSL_SUCCESS); + +exit: + BSL_SAL_FileClose(stream); + RemoveFile(path); + return NULL; +} +/** + * @test SDV_BSL_SAL_FILE_LENGTH_FUNC_TC001 + * @title Write content to a file and obtain the file length. + * @precon nan + * @brief + * 1. Create a file. Expected result 1 is obtained. + * 2. Write data to a file. After the write operation is performed, + * perform the close operation to write the buffer data to the file. Expected result 2 is obtained. + * 3. Open the file again and read the file content. Because the file contains information, + * the read length is greater than 0. Expected result 3 is obtained. + * 4. Obtain the file length, which is greater than 0. Expected result 4 is obtained. + * @expect + * 1. File created successfully. + * 2. BSL_SUCCESS + * 3. BSL_SUCCESS + * 4. BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_FILE_LENGTH_FUNC_TC001(void) +{ + TestFileLengthFunc(NULL); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_file.data b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_file.data new file mode 100644 index 00000000..72b574d3 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_file.data @@ -0,0 +1,5 @@ +SDV_BSL_SAL_FILE_OPEN_FUNC_TC001 +SDV_BSL_SAL_FILE_OPEN_FUNC_TC001: + +SDV_BSL_SAL_FILE_LENGTH_FUNC_TC001 +SDV_BSL_SAL_FILE_LENGTH_FUNC_TC001: diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_socket.c b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_socket.c new file mode 100644 index 00000000..c9f06b8d --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_socket.c @@ -0,0 +1,197 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bsl_sal.h" +#include "bsl_errno.h" + +#define READ_TIME_OUT_SEC 3 // 3s timeout + +/* END_HEADER */ + +/** + * @test SDV_BSL_SAL_SOCKET_FUNC_TC001 + * @title Socket-related function test + * @precon nan + * @brief + * 1. Call BSL_SAL_Socket to create a TCP socket. Expected result 1 is displayed. + * 2. Set the TCP timeout period. Expected result 2 is obtained. + * 3. Close tcp socket. Expected result 3 is obtained. + * 4. Call BSL_SAL_Socket to create a UDP socket. Expected result 4 is displayed. + * 5. Set the UDP timeout period. Expected result 5 is obtained. + * 6. Close UDP socket. Expected result 6 is obtained. + * @expect + * 1. Created successfully. + * 2. Setting successfully. + * 3. Closed successfully. + * 4. Created successfully. + * 5. Setting successfully. + * 6. Closed successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_SOCKET_FUNC_TC001(void) +{ + int32_t tcp = BSL_SAL_Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ASSERT_TRUE(tcp != -1); + struct timeval timeOut = { 0 }; + timeOut.tv_sec = READ_TIME_OUT_SEC; + ASSERT_TRUE(BSL_SAL_SetSockopt(tcp, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeOut, sizeof(timeOut)) == 0); + ASSERT_TRUE(BSL_SAL_SockClose(tcp) == 0); + int32_t udp = BSL_SAL_Socket(AF_INET, SOCK_DGRAM, 0); + ASSERT_TRUE(udp != -1); + ASSERT_TRUE(BSL_SAL_SetSockopt(udp, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeOut, sizeof(timeOut)) == 0); + ASSERT_TRUE(BSL_SAL_SockClose(udp) == 0); +exit: + return; +} +/* END_CASE */ + +#ifdef HITLS_BSL_SAL_THREAD +static uint16_t GetPort() +{ + uint16_t port = 8888; + char *userPort = getenv("FIXED_PORT"); + if (userPort == NULL) { + const uint32_t basePort = 10000; + port = basePort + getpid(); + } + return port; +} + +static void *TestTcpClient(void *args) +{ + (void)args; + struct sockaddr_in remoteAddr; + remoteAddr.sin_family = AF_INET; + remoteAddr.sin_port = htons(GetPort()); + remoteAddr.sin_addr.s_addr = htonl(INADDR_ANY); + int32_t socketRemote = BSL_SAL_Socket(AF_INET, SOCK_STREAM, 0); + ASSERT_TRUE(socketRemote != -1); + while(true) { + int32_t ret = BSL_SAL_SockConnect(socketRemote, (BSL_SAL_SockAddr)&remoteAddr, sizeof(remoteAddr)); + if (ret == 0) { + char *msg = "Hello,TCP!!"; + ASSERT_TRUE(BSL_SAL_SockSend(socketRemote, msg, strlen(msg), 0) >= 0); + goto exit; + } + ASSERT_TRUE(BSL_SAL_SockGetLastSocketError() != 0); + } +exit: + BSL_SAL_SockClose(socketRemote); + return NULL; +} + +static void *TestTcpServer(void *args) +{ + (void)args; + uint8_t buff[32] = {0}; + int serConn = -1; + struct sockaddr_in localAddr = {0}; + struct sockaddr_in cliAddr = {0}; + localAddr.sin_family = AF_INET; + localAddr.sin_port = htons(GetPort()); + localAddr.sin_addr.s_addr = htonl(INADDR_ANY); + int32_t socketLocal = BSL_SAL_Socket(AF_INET, SOCK_STREAM, 0); + ASSERT_TRUE(socketLocal != -1); + ASSERT_TRUE(BSL_SAL_SockBind(socketLocal, (BSL_SAL_SockAddr)&localAddr, sizeof(localAddr)) == 0); + ASSERT_TRUE(BSL_SAL_SockListen(socketLocal, 5) == 0); + socklen_t len = sizeof(cliAddr); + serConn = accept(socketLocal, (struct sockaddr *)&cliAddr, &len); + ASSERT_TRUE(serConn != -1); + while(true) { + if (BSL_SAL_SockRecv(serConn, buff, 32, 0) > 0) { + goto exit; + } + ASSERT_TRUE(BSL_SAL_SockGetLastSocketError() != 0); + } +exit: + BSL_SAL_SockClose(socketLocal); + BSL_SAL_SockClose(serConn); + return NULL; +} +#endif + +/** + * @test SDV_BSL_SAL_SOCKET_FUNC_TC002 + * @title Socket-related function test + * @precon nan + * @brief + * 1. Creating a TCP Server. Expected result 1 is obtained. + * 2. Creating a TCP Client. Expected result 2 is obtained. + * @expect + * 1. Created successfully. + * 2. Created successfully. + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_SOCKET_FUNC_TC002(void) +{ +#ifndef HITLS_BSL_SAL_THREAD + SKIP_TEST(); +#else + BSL_SAL_ThreadId serverThread = NULL; + ASSERT_EQ(BSL_SAL_ThreadCreate(&serverThread, TestTcpServer, NULL), BSL_SUCCESS); + BSL_SAL_ThreadId clientThread = NULL; + ASSERT_EQ(BSL_SAL_ThreadCreate(&clientThread, TestTcpClient, NULL), BSL_SUCCESS); +exit: + BSL_SAL_ThreadClose(serverThread); + BSL_SAL_ThreadClose(clientThread); +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_SELECT_FUNC_TC001 + * @title Socket-related function test + * @precon nan + * @brief + * 1. Open the /dev/urandom file only. Expected result 1 is obtained. + * 2. Call BSL_SAL_Select to check the number of open read-only descriptors. + Expected result 2 is obtained. + * @expect + * 1. Opened successfully. + * 2. Read-only descriptor open count is greater than 0 + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_SELECT_FUNC_TC001(void) +{ + const char *path = "/dev/urandom"; + int fd = open(path, O_RDONLY); + ASSERT_TRUE(fd != -1); + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); + struct timeval tv; + tv.tv_sec = 2; + tv.tv_usec = 0; + ASSERT_TRUE(BSL_SAL_Select(fd + 1, &fds, NULL, NULL, &tv) > 0); +exit: + close(fd); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_socket.data b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_socket.data new file mode 100644 index 00000000..6c3a353d --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_socket.data @@ -0,0 +1,8 @@ +SDV_BSL_SAL_SOCKET_FUNC_TC001 +SDV_BSL_SAL_SOCKET_FUNC_TC001: + +SDV_BSL_SAL_SOCKET_FUNC_TC002 +SDV_BSL_SAL_SOCKET_FUNC_TC002: + +SDV_BSL_SAL_SELECT_FUNC_TC001 +SDV_BSL_SAL_SELECT_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_time.c b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_time.c new file mode 100644 index 00000000..ec137925 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_time.c @@ -0,0 +1,696 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "bsl_sal.h" +#include "sal_time.h" +#include "bsl_errno.h" + +static int64_t TestBslSysTimeFunc(void) +{ + return (time_t)1; +} + +static int64_t TestBslSysTimeFunc1(void) +{ + return time(NULL); +} + +static void TestBslSysTimeInit(BSL_TIME *dateTime) +{ + dateTime->year = 1990; + dateTime->month = 6; + dateTime->day = 12; + dateTime->hour = 10; + dateTime->minute = 3; + dateTime->microSec = 1; + dateTime->millSec = 1; +} + +static void TestBslSysTimeAndTmCompare(BSL_TIME *dateTime, struct tm *tempTime) +{ + ASSERT_EQ(dateTime->year, tempTime->tm_year + 1900); /* 1900 is base year */ + ASSERT_EQ(dateTime->month, tempTime->tm_mon + 1U); + ASSERT_EQ(dateTime->day, tempTime->tm_mday); + ASSERT_EQ(dateTime->hour, tempTime->tm_hour); + ASSERT_EQ(dateTime->minute, tempTime->tm_min); + ASSERT_EQ(dateTime->second, tempTime->tm_sec); +exit: + return; +} +/* END_HEADER */ + +/** + * @test SDV_BSL_TIME_FUNC_GET_DATETIME_TC001 + * @title Function test of obtaining the date as a character string. + * @precon + * @brief 1.The input parameter dateTime, timeStr, or len is invalid (less than the storage length). + * 2.Invalid time. + * 3.The time is legal. + * @expect 1.Fail, return BSL_ERR + * 2.Fail, return BSL_ERR + * 3.Success, return BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_FUNC_GET_DATETIME_TC001(void) +{ + BSL_TIME dateTime = {0}; + char timeStr[26]; + + timeStr[0] = '\0'; + dateTime.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateTime.month = 1; + dateTime.day = 1; + dateTime.hour = 0; + dateTime.minute = 0; + dateTime.second = 0; + + /* 1.The input parameter dateaTime or timeStr is invalid. */ + ASSERT_EQ(BSL_DateToStrConvert(NULL, timeStr, 26), (uint32_t)BSL_INTERNAL_EXCEPTION); + ASSERT_EQ(BSL_DateToStrConvert(&dateTime, NULL, 26), (uint32_t)BSL_INTERNAL_EXCEPTION); + + /* 2.Invalid time. */ + dateTime.month = 13; + ASSERT_EQ(BSL_DateToStrConvert(&dateTime, timeStr, 26), (uint32_t)BSL_INTERNAL_EXCEPTION); + dateTime.month = 1; + + /* 3.The time is legal. */ + ASSERT_EQ(BSL_DateToStrConvert(&dateTime, timeStr, 26), (uint32_t)BSL_SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_FUNC_REGISTER_TC001 + * @title Obtaining the current system time + * @precon + * @brief + * 1. Registering System Time Hooks, obtain the Unix time. Expected result 1 is obtained. + * 2. Unregistered system time hook, Obtain the Unix time. Expected result 2 is obtained. + * 3. Unregister System Time Hook, Obtain the Unix time. Expected result 3 is obtained. + * @expect + * 1. The operation is successful, 0 is returned. + * 2. The operation is successful, 0 is returned. The hook has not changed + * 3. The operation is successful, a non-zero value is returned. + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_FUNC_REGISTER_TC001(void) +{ + /* 1.Registering System Time Hooks */ + BSL_SAL_SysTimeFuncReg(TestBslSysTimeFunc); + ASSERT_EQ(BSL_SAL_CurrentSysTimeGet(), 1); + + /* 2.Unregistered system time hook */ + BSL_SAL_SysTimeFuncReg(NULL); + ASSERT_EQ(BSL_SAL_CurrentSysTimeGet(), 1); + + BSL_SysTimeFuncUnReg(); + + ASSERT_NE(BSL_SAL_CurrentSysTimeGet(), 1); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_TIME_CMP_TIME_API_TC001 + * @title Time comparison function test + * @precon + * @brief + * 1. The existence time is invalid. Expected result 1 is obtained. + * 2. The two dates are consistent. Expected result 2 is obtained. + * 3. The first date is before the second date. Expected result 3 is obtained. + * 4. The first date is after the second. Expected result 3 is obtained. + * @expect + * 1. Fail, return BSL_TIME_CMP_ERROR + * 2. Success, return BSL_TIME_CMP_EQUAL + * 3. Success, return BSL_TIME_DATE_BEFORE + * 4. Success, return BSL_TIME_DATE_AFTER + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_TIME_CMP_TIME_API_TC001(void) +{ + int64_t diffSec; + BSL_TIME dateA = {0}; + BSL_TIME dateB = {0}; + + dateA.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateA.month = 1; + dateA.day = 1; + + dateB.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateB.month = 1; + dateB.day = 1; + + /* 1.The existence time is invalid */ + ASSERT_EQ(BSL_SAL_DateTimeCompare(NULL, &dateB, &diffSec), BSL_TIME_CMP_ERROR); + + /* 2.The two dates are consistent */ + ASSERT_EQ(BSL_SAL_DateTimeCompare(&dateA, &dateB, &diffSec), BSL_TIME_CMP_EQUAL); + ASSERT_EQ(diffSec, 0); + + /* 3.The first date is before the second date */ + dateB.second = 1; + ASSERT_EQ(BSL_SAL_DateTimeCompare(&dateA, &dateB, &diffSec), BSL_TIME_DATE_BEFORE); + ASSERT_EQ(diffSec, -1); + dateB.second = 0; + + /* 4.The first date is after the second */ + dateA.second = 1; + ASSERT_EQ(BSL_SAL_DateTimeCompare(&dateA, &dateB, &diffSec), BSL_TIME_DATE_AFTER); + ASSERT_EQ(diffSec, 1); + dateA.second = 0; +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_TIME_CMP_TIME_API_TC002 + * @title Time comparison function test + * @precon + * @brief + * 1. The existence time is invalid. Expected result 1 is obtained. + * 2. The two dates are consistent. Expected result 2 is obtained. + * 3. The first date is before the second date. Expected result 3 is obtained. + * 4. The first date is after the second. Expected result 3 is obtained. + * @expect + * 1. Fail, return BSL_TIME_CMP_ERROR + * 2. Success, return BSL_TIME_CMP_EQUAL + * 3. Success, return BSL_TIME_DATE_BEFORE + * 4. Success, return BSL_TIME_DATE_AFTER + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_TIME_CMP_TIME_API_TC002(void) +{ + BSL_TIME dateA = {0}; + BSL_TIME dateB = {0}; + + dateA.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateA.month = 1; + dateA.day = 1; + dateA.millSec = 2; + dateA.microSec = 3; + + dateB.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateB.month = 1; + dateB.day = 1; + dateB.millSec = 2; + dateB.microSec = 3; + + /* 1.The existence time is invalid. */ + ASSERT_EQ(BSL_SAL_DateTimeCompareByUs(NULL, &dateB), BSL_TIME_CMP_ERROR); + + /* 2.The two dates are consistent. */ + ASSERT_EQ(BSL_SAL_DateTimeCompareByUs(&dateA, &dateB), BSL_TIME_CMP_EQUAL); + + /* 3.The first date is before the second date. */ + dateB.millSec = 1; + ASSERT_EQ(BSL_SAL_DateTimeCompareByUs(&dateA, &dateB), BSL_TIME_DATE_AFTER); + dateB.millSec = 2; + + /* 4.The first date is after the second */ + dateA.microSec = 1; + ASSERT_EQ(BSL_SAL_DateTimeCompareByUs(&dateA, &dateB), BSL_TIME_DATE_BEFORE); + dateA.microSec = 0; +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_SYSTIME_API_TC001 + * @title Obtaining the System Time + * @precon + * @brief + * 1. Call BSL_SAL_SysTimeGet to transfer the NULL parameter. Expected result 1 is obtained. + * 2. Call BSL_SAL_SysTimeGet to transfer the normal parameter. Expected result 2 is obtained. + * @expect + * 1. Return BSL_SAL_ERR_BAD_PARAM. + * 2. The obtained time is the same as the expected value. Return BSL_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_SYSTIME_API_TC001(void) +{ + BSL_TIME systime; + uint32_t ret; + + /* The time obtaining interface is registered as time. */ + BSL_SAL_SysTimeFuncReg(TestBslSysTimeFunc1); + + ret = BSL_SAL_SysTimeGet(NULL); + ASSERT_EQ(ret, BSL_SAL_ERR_BAD_PARAM); + + ret = BSL_SAL_SysTimeGet(&systime); + ASSERT_TRUE(ret == BSL_SUCCESS); + + /* Get the current time. */ + int64_t curtime = time(NULL); + + int64_t timestamp = 0; + ret = BSL_SAL_DateToUtcTimeConvert(&systime, ×tamp); + + ASSERT_TRUE(curtime >= timestamp && curtime - 5 <= timestamp); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_CONVERT_TIME_FUNC_TC001 + * @title UTC time conversion + * @precon + * @brief + * 1. Call BSL_SAL_DateToUtcTimeConvert to transfer the NULL parameter. Expected result 1 is obtained. + * 2. Call BSL_SAL_DateToUtcTimeConvert to transfer an exception parameter. Expected result 1 is obtained. + * 3. Call BSL_SAL_DateToUtcTimeConvert to transfer normal parameters. Expected result 2 is obtained. + * @expect + * 1. Fail, return BSL_ERR + * 2. Fail, return BSL_ERR + * 3. Success, return BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_CONVERT_TIME_FUNC_TC001(void) +{ + int64_t utcTime; + BSL_TIME dateTime = {0}; + + /* 1.The input parameter dateTime or utcTime is empty. */ + ASSERT_TRUE(BSL_SAL_DateToUtcTimeConvert(NULL, &utcTime) == BSL_INTERNAL_EXCEPTION); + ASSERT_TRUE(BSL_SAL_DateToUtcTimeConvert(&dateTime, NULL) == BSL_INTERNAL_EXCEPTION); + + /* 2.Failed to convert the time. */ + ASSERT_TRUE(BSL_SAL_DateToUtcTimeConvert(&dateTime, &utcTime) != BSL_SUCCESS); + + /* 3.Time conversion succeeded. */ + dateTime.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateTime.month = 1; + dateTime.day = 1; + dateTime.hour = 0; + dateTime.minute = 0; + dateTime.second = 0; + ASSERT_TRUE(BSL_SAL_DateToUtcTimeConvert(&dateTime, &utcTime) == (uint32_t)BSL_SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_SAL_CONVERT_TIME_API_TC002 + * @title Converting BslSysTime to BslUnixTime + * @precon + * @brief + * 1. The value of utcTime is 0. Expected result 1 is obtained. + * 2. The value of utcTime is a negative number. Expected result 2 is obtained. + * 3. The value of utcTime is INT32_MAX - 1. Expected result 3 is obtained. + * 4. The value of utcTime is INT32_MAX. Expected result 4 is obtained. + * 5. The value of utcTime is INT32_MAX + 1. Expected result 5 is obtained. + * 6. The value of utcTime is BSL_UTCTIME_MAX. Expected result 6 is obtained. + * @expect + * 1. Success, return BSL_SUCCESS + * 2. Success, return BSL_SUCCESS + * 3. Success, return BSL_SUCCESS + * 4. Success, return BSL_SUCCESS + * 5. Success, return BSL_SUCCESS + * 6. Success, return BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_SAL_CONVERT_TIME_API_TC001(void) +{ + int64_t utcTime; + BSL_TIME dateTime = {0}; + struct tm tempTime; + + utcTime = 0; + ASSERT_TRUE(BSL_SAL_UtcTimeToDateConvert(utcTime, &dateTime) == BSL_SUCCESS); + ASSERT_TRUE(gmtime_r((const time_t *)&utcTime, &tempTime) != NULL); + TestBslSysTimeAndTmCompare(&dateTime, &tempTime); + + utcTime = -1; + ASSERT_TRUE(BSL_SAL_UtcTimeToDateConvert(utcTime, &dateTime) == BSL_SUCCESS); + ASSERT_TRUE(gmtime_r((const time_t *)&utcTime, &tempTime) != NULL); + TestBslSysTimeAndTmCompare(&dateTime, &tempTime); + + utcTime = INT32_MAX; + ASSERT_TRUE(BSL_SAL_UtcTimeToDateConvert(utcTime, &dateTime) == BSL_SUCCESS); + ASSERT_TRUE(gmtime_r((const time_t *)&utcTime, &tempTime) != NULL); + TestBslSysTimeAndTmCompare(&dateTime, &tempTime); + + utcTime = INT32_MAX - 1; + ASSERT_TRUE(BSL_SAL_UtcTimeToDateConvert(utcTime, &dateTime) == BSL_SUCCESS); + ASSERT_TRUE(gmtime_r((const time_t *)&utcTime, &tempTime) != NULL); + TestBslSysTimeAndTmCompare(&dateTime, &tempTime); + + utcTime = (int64_t)INT32_MAX + 1; + ASSERT_TRUE(BSL_SAL_UtcTimeToDateConvert(utcTime, &dateTime) == BSL_SUCCESS); + ASSERT_TRUE(gmtime_r((const time_t *)&utcTime, &tempTime) != NULL); + TestBslSysTimeAndTmCompare(&dateTime, &tempTime); + + utcTime = BSL_UTCTIME_MAX; + ASSERT_TRUE(BSL_SAL_UtcTimeToDateConvert(utcTime, &dateTime) == BSL_SUCCESS); + ASSERT_TRUE(gmtime_r((const time_t *)&utcTime, &tempTime) != NULL); + TestBslSysTimeAndTmCompare(&dateTime, &tempTime); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_FUNC_DATETIME_CHECK_TC001 + * @title BSL_DateTimeCheck the test of the year + * @precon nan + * @brief + * 1.Year illegal (<1970). Expected result 1 is obtained. + * 2.Year legal (1990). Expected result 2 is obtained. + * @expect + * 1.Return false + * 2.Return true + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC001(void) +{ + bool ret; + BSL_TIME dateTime = {0}; + + TestBslSysTimeInit(&dateTime); + + /* 1.Year illegal (<1970) */ + dateTime.year = 1969; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 2.Year legal (=1970) */ + dateTime.year = 1970; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_FUNC_DATETIME_CHECK_TC002 + * @title BSL_DateTimeCheck the test of the month + * @precon nan + * @brief + * 1.Month illegal (== 0 or > 12). Expected result 1 is obtained. + * 2.Month legal (== 1 or == 12). Expected result 2 is obtained. + * @expect + * 1.Return false + * 2.Return true + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC002(void) +{ + bool ret; + BSL_TIME dateTime = {0}; + + TestBslSysTimeInit(&dateTime); + + /* 1.Month illegal (== 0 or > 12) */ + dateTime.month = 0; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + dateTime.month = 13; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 2.Month legal (== 1 or == 12) */ + dateTime.month = 1; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + dateTime.month = 12; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_FUNC_DATETIME_CHECK_TC003 + * @title BSL_DateTimeCheck the test of the day + * @precon + * @brief + * 1.Day illegal (== 0). Expected result 1 is obtained. + * 2.Day legal (== 1). Expected result 2 is obtained. + * 3.Day illegal (More than 28 days in February). Expected result 3 is obtained. + * 4.Day legal (February equals 28 days). Expected result 4 is obtained. + * 5.Day illegal (More than 31 days in January). Expected result 5 is obtained. + * 6.Day legal (January equals 31 days). Expected result 6 is obtained. + * 7.Day illegal (More than 30 in April). Expected result 7 is obtained. + * 8.Day legal (April equals 30 days). Expected result 8 is obtained. + * 9.Day illegal (Leap year February greater than 29 days). Expected result 9 is obtained. + * 10.Day legal (Leap year February equals 29 days). Expected result 10 is obtained. + * @expect + * 1.Return false + * 2.Return true + * 3.Return false + * 4.Return true + * 5.Return false + * 6.Return true + * 7.Return false + * 8.Return true + * 9.Return false + * 10.Return true + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC003(void) +{ + bool ret; + BSL_TIME dateTime = {0}; + + TestBslSysTimeInit(&dateTime); + + /* 1.Day illegal (== 0) */ + dateTime.day = 0; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 2.Day legal (== 1) */ + dateTime.day = 1; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 3.Day illegal (More than 28 days in February) */ + dateTime.month = 2; + dateTime.day = 29; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 4.Day legal (February equals 28 days) */ + dateTime.month = 2; + dateTime.day = 28; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 5.Day illegal (More than 31 days in January) */ + dateTime.month = 1; + dateTime.day = 32; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 6.Day legal (January equals 31 days) */ + dateTime.month = 1; + dateTime.day = 31; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 7.Day illegal (More than 30 days in April) */ + dateTime.month = 4; + dateTime.day = 31; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 8.Day legal (April equals 30 days) */ + dateTime.month = 4; + dateTime.day = 30; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 9.Day illegal (Leap year February greater than 29) */ + dateTime.year = 2020; + dateTime.month = 2; + dateTime.day = 30; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 10.Day legal (Leap year February equals 29) */ + dateTime.year = 2020; + dateTime.month = 2; + dateTime.day = 29; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_FUNC_DATETIME_CHECK_TC004 + * @title BSL_DateTimeCheck hour minute second test + * @precon nan + * @brief + * 1. hour is illegal ( > 23). Expected result 1 is obtained. + * 2. hour is legal ( == 23). Expected result 2 is obtained. + * 3. minute is illegal ( > 59). Expected result 3 is obtained. + * 4. minute is legal ( == 59). Expected result 4 is obtained. + * 5. second is illegal( > 59). Expected result 5 is obtained. + * 6. second is legal ( == 59). Expected result 6 is obtained. + * 7. millisecond is illegal ( > 999). Expected result 7 is obtained. + * 8. millisecond is legal ( == 999). Expected result 8 is obtained. + * 9. call BSL_DateToStrConvert to convert legal time. Expected result 9 is obtained. + * @expect + * 1. Return false + * 2. Return true + * 3. Return false + * 4. Return true + * 5. Return false + * 6. Return true + * 7. Return false + * 8. Return true + * 9. Return BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC004(void) +{ + bool ret; + BSL_TIME dateTime = {0}; + + TestBslSysTimeInit(&dateTime); + + /* 1.hour is illegal ( > 23) */ + dateTime.hour = 24; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 2.hour is legal ( == 23) */ + dateTime.hour = 23; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 3.minute is illegal ( > 59) */ + dateTime.minute = 60; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 4.minute is legal ( == 59) */ + dateTime.minute = 59; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 5.second is illegal ( > 59) */ + dateTime.second = 60; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 6.second is legal ( == 59) */ + dateTime.second = 59; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + + /* 7.millisecond is illegal ( > 999) */ + dateTime.millSec = 1000; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, false); + + /* 8.millisecond is legal ( == 999) */ + dateTime.millSec = 59; + ret = BSL_DateTimeCheck(&dateTime); + ASSERT_EQ(ret, true); + char buf[256] = {0}; + ASSERT_EQ(BSL_DateToStrConvert(&dateTime, buf, 256), BSL_SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_FUNC_TICK_TC001 + * @title Test of functions related to the number of ticks in the system + * @precon + * @brief + * 1. Call BSL_SAL_Tick to obtain the number of ticks that the system has experienced since startup. + * Expected result 1 is obtained. + * 2. Call BSL_SAL_TicksPerSec to obtain the number of system ticks per second. Expected result 2 is obtained. + * @expect + * 1. Succeeded in obtaining the number of ticks that have been experienced since the system is started. + * 2. Succeeded in obtaining the number of system ticks per second. + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_FUNC_TICK_TC001(void) +{ + long res = BSL_SAL_Tick(); + ASSERT_TRUE(res != 0); + res = BSL_SAL_TicksPerSec(); + ASSERT_EQ(res, sysconf(_SC_CLK_TCK)); + BSL_SAL_Sleep(1); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_TIME_ADD_TIME_TC001 + * @title Time comparison function test. + * @tprecon + * @brief 1.Adding succeeded. + * 2.The two dates are consistent. + * 3.One of them is empty. Adding failed. + * @texpect 1.Sucessful, return BSL_SUCCESS + * 2.Sucessful, return BSL_TIME_CMP_EQUAL + * 3.Fail, return BSL_ERR + */ +/* BEGIN_CASE */ +void SDV_BSL_TIME_ADD_TIME_TC001(void) +{ + BSL_TIME dateA = {0}; + BSL_TIME dateB = {0}; + BSL_TIME dateC = {0}; + + dateA.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateA.month = 1; + dateA.day = 1; + dateA.millSec = 1; + + dateB.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateB.month = 2; + dateB.day = 1; + dateB.millSec = 2; + + dateC.year = BSL_TIME_SYSTEM_EPOCH_YEAR; + dateC.month = 1; + dateC.day = 1; + dateC.millSec = 3; + + /* Dates add up */ + ASSERT_TRUE(BSL_DateTimeAddUs(&dateA, &dateC, 0) == BSL_SUCCESS); + + /* 2.Comparison of two dates */ + ASSERT_NE(BSL_SAL_DateTimeCompareByUs(&dateA, &dateB), BSL_TIME_CMP_EQUAL); + ASSERT_EQ(BSL_SAL_DateTimeCompareByUs(&dateA, &dateC), BSL_TIME_CMP_EQUAL); + + /* Exceptions */ + ASSERT_TRUE(BSL_DateTimeAddUs(&dateA, NULL, 0) == BSL_INTERNAL_EXCEPTION); +exit: + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_time.data b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_time.data new file mode 100644 index 00000000..3b7a24e5 --- /dev/null +++ b/testcode/sdv/testcase/bsl/sal/test_suite_sdv_sal_time.data @@ -0,0 +1,38 @@ +SDV_BSL_TIME_FUNC_GET_DATETIME_TC001 +SDV_BSL_TIME_FUNC_GET_DATETIME_TC001: + +SDV_BSL_TIME_FUNC_REGISTER_TC001 +SDV_BSL_TIME_FUNC_REGISTER_TC001: + +SDV_BSL_SAL_TIME_CMP_TIME_API_TC001 +SDV_BSL_SAL_TIME_CMP_TIME_API_TC001: + +SDV_BSL_SAL_TIME_CMP_TIME_API_TC002 +SDV_BSL_SAL_TIME_CMP_TIME_API_TC002: + +SDV_BSL_TIME_SYSTIME_API_TC001 +SDV_BSL_TIME_SYSTIME_API_TC001: + +SDV_BSL_TIME_CONVERT_TIME_FUNC_TC001 +SDV_BSL_TIME_CONVERT_TIME_FUNC_TC001: + +SDV_BSL_SAL_CONVERT_TIME_API_TC001 +SDV_BSL_SAL_CONVERT_TIME_API_TC001: + +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC001 +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC001: + +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC002 +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC002: + +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC003 +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC003: + +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC004 +SDV_BSL_TIME_DATETIME_CHECK_FUNC_TC004: + +SDV_BSL_TIME_FUNC_TICK_TC001 +SDV_BSL_TIME_FUNC_TICK_TC001: + +SDV_BSL_TIME_ADD_TIME_TC001 +SDV_BSL_TIME_ADD_TIME_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/tlv/test_suite_sdv_tlv.c b/testcode/sdv/testcase/bsl/tlv/test_suite_sdv_tlv.c new file mode 100644 index 00000000..9a43280c --- /dev/null +++ b/testcode/sdv/testcase/bsl/tlv/test_suite_sdv_tlv.c @@ -0,0 +1,64 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "tlv.h" +#include "bsl_errno.h" + +/* END_HEADER */ + +/** + * @test SDV_BSL_TLV_Find_API_TC001 + * @title Find tlv value pos test + * @precon nan + * @brief + * 1. Invoke BSL_TLV_Pack to construct a tlv buffer. Expected result 1 is obtained. + * 2. Invoke BSL_TLV_FindValuePos to find a type which valid. Expected result 2 is obtained. + * 3. Invoke BSL_TLV_FindValuePos to find a type which invalid. Expected result 3 is obtained. + * @expect + * 1. Expected success + * 2. Expected success + * 3. Expected failure + */ +/* BEGIN_CASE */ +void SDV_BSL_TLV_Find_API_TC001(void) +{ + int ret; + uint32_t type = 0x0101; + uint16_t version = 1; + + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(version); + tlv.value = (uint8_t *)&version; + + uint32_t encLen = 0; + uint8_t data[1024] = {0}; + ret = BSL_TLV_Pack(&tlv, data, sizeof(data), &encLen); + ASSERT_TRUE(ret == BSL_SUCCESS); + + uint32_t offset = 0; + uint32_t length = 0; + ret = BSL_TLV_FindValuePos(type, data, encLen, &offset, &length); + ASSERT_TRUE(ret == BSL_SUCCESS); + + uint32_t invalidType = 0x0102; + ret = BSL_TLV_FindValuePos(invalidType, data, encLen, &offset, &length); + ASSERT_TRUE(ret == BSL_TLV_ERR_NO_WANT_TYPE); +exit: + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/tlv/test_suite_sdv_tlv.data b/testcode/sdv/testcase/bsl/tlv/test_suite_sdv_tlv.data new file mode 100644 index 00000000..83400498 --- /dev/null +++ b/testcode/sdv/testcase/bsl/tlv/test_suite_sdv_tlv.data @@ -0,0 +1,2 @@ +SDV_BSL_TLV_Find_API_TC001 +SDV_BSL_TLV_Find_API_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/uio/test_suite_sdv_uio.c b/testcode/sdv/testcase/bsl/uio/test_suite_sdv_uio.c new file mode 100644 index 00000000..344664f8 --- /dev/null +++ b/testcode/sdv/testcase/bsl/uio/test_suite_sdv_uio.c @@ -0,0 +1,1108 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "stub_replace.h" +#include "bsl_sal.h" +#include "sal_net.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "uio_base.h" +#include "uio_sctp.h" +#include "sal_atomic.h" +#include "uio_abstraction.h" + +/* END_HEADER */ + +#define MAX_BUF_SIZE 255 +#define IP_V4_LEN 4 +#define IP_V6_LEN 16 + +static int32_t g_writeRet; +static uint32_t g_writeLen; +static int32_t STUB_Write(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + (void)uio; + (void)buf; + (void)len; + + *writeLen = g_writeLen; + return g_writeRet; +} + +static int32_t g_readRet; +static uint32_t g_readLen; +static int32_t STUB_Read(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + (void)uio; + (void)buf; + (void)len; + + *readLen = g_readLen; + return g_readRet; +} + +static int32_t g_ctrlRet1; +static int32_t g_ctrlRet2; +static int32_t g_ctrlRet3; +static BSL_UIO_CtrlParameter g_ctrlCmd1; +static BSL_UIO_CtrlParameter g_ctrlCmd2; +static BSL_UIO_CtrlParameter g_ctrlCmd3; +static uint16_t g_shareKeyId; +static uint16_t g_delShareKeyId; +static uint8_t g_isEmpty; +static int32_t STUB_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param) +{ + (void)larg; + (void)uio; + (void)param; + if (cmd == BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY) { + BSL_UIO_SctpAuthKey *key = (BSL_UIO_SctpAuthKey *)param; + g_shareKeyId = key->shareKeyId; + } + + if (cmd == BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY) { + g_delShareKeyId = *(uint16_t*)param; + } + + if (cmd == BSL_UIO_SCTP_SND_BUFF_IS_EMPTY) { + *(uint8_t *)param = g_isEmpty; + } + + if ((int32_t)g_ctrlCmd1 == cmd) { + return g_ctrlRet1; + } + + if ((int32_t)g_ctrlCmd2 == cmd) { + return g_ctrlRet2; + } + + if ((int32_t)g_ctrlCmd3 == cmd) { + return g_ctrlRet3; + } + + return BSL_UIO_FAIL; +} + +const BSL_UIO_Method * GetUioMethodByType(int uioType) +{ + switch (uioType) { + case BSL_UIO_TCP: + return BSL_UIO_TcpMethod(); +#ifdef HITLS_BSL_UIO_SCTP + case BSL_UIO_SCTP: + return BSL_UIO_SctpMethod(); +#endif + case BSL_UIO_BUFFER: + return BSL_UIO_BufferMethod(); + default: + return NULL; + } +} + +typedef struct { + int32_t len; + uint8_t index; + uint8_t *buff; +} CustomLowCtx; + +static int32_t BslUioCreate(BSL_UIO *uio) +{ + int32_t len = 20; + int32_t ret; + CustomLowCtx *lowCtx = BSL_SAL_Calloc(1, sizeof(CustomLowCtx)); + if (lowCtx == NULL) { + ret = BSL_MALLOC_FAIL; + goto exit; + } + lowCtx->buff = BSL_SAL_Malloc(len); + if (lowCtx->buff == NULL) { + ret = BSL_MALLOC_FAIL; + goto exit; + } + lowCtx->len = len; + BSL_UIO_SetCtx(uio, (void *)lowCtx); + BSL_UIO_SetInit(uio, 1); + return BSL_SUCCESS; +exit: + if(lowCtx != NULL) { + BSL_SAL_FREE(lowCtx->buff); + BSL_SAL_FREE(lowCtx); + } + return ret; +} + +static int32_t BslUioDestroy(BSL_UIO *uio) +{ + CustomLowCtx *lowCtx = BSL_UIO_GetCtx(uio); + if (lowCtx == NULL) { + return BSL_INVALID_ARG; + } + BSL_SAL_FREE(lowCtx->buff); + BSL_SAL_FREE(lowCtx); + BSL_UIO_SetCtx(uio, NULL); + return BSL_SUCCESS; +} + +static int32_t BslUioWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + CustomLowCtx *lowCtx = BSL_UIO_GetCtx(uio); + if (lowCtx == NULL) { + return BSL_INVALID_ARG; + } + uint32_t reslen = lowCtx->len - lowCtx->index; + if (reslen < len) { + return BSL_INVALID_ARG; + } + memcpy_s(lowCtx->buff + lowCtx->index, len, buf, len); + lowCtx->index += len; + *writeLen = len; + return BSL_SUCCESS; +} + +static int32_t BslUioRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + CustomLowCtx *lowCtx = BSL_UIO_GetCtx(uio); + if (lowCtx == NULL) { + return BSL_INVALID_ARG; + } + if (lowCtx->index == 0) { + return BSL_INVALID_ARG; + } + + int copyLen = (lowCtx->index > len) ? len : lowCtx->index; + (void)memcpy_s(buf, copyLen, lowCtx->buff, copyLen); + *readLen = copyLen; + lowCtx->index -= copyLen; + return BSL_SUCCESS; +} + +#define BSL_CUSTOM_UIO_GET_INDEX 0x100 + +static int32_t BslUioCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg) +{ + (void)larg; + CustomLowCtx *lowCtx = BSL_UIO_GetCtx(uio); + if (lowCtx == NULL) { + return BSL_INVALID_ARG; + } + if (cmd == BSL_CUSTOM_UIO_GET_INDEX) { + *(uint32_t *)parg = lowCtx->index; + return BSL_SUCCESS; + } + return BSL_INVALID_ARG; +} + +static int32_t BslUioPuts(BSL_UIO *uio, const char *buf, uint32_t *writeLen) +{ + (void) uio; + (void) buf; + (void) writeLen; + return BSL_INVALID_ARG; +} + +static int32_t BslUioGets(BSL_UIO *uio, char *buf, uint32_t *readLen) +{ + (void) uio; + (void) buf; + (void) readLen; + return BSL_INVALID_ARG; +} + +/** + * @test SDV_BSL_UIO_NEW_API_TC001 + * @title Input parameter test + * @precon nan + * @brief + * 1. Construct the tcp/sctp method structure, and invoke BSL_UIO_New. + * 2. Invoke the BSL_UIO_GetTransportType interface. + * @expect + * 1. Expected the uio is not NULL, and transport type is the target type + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_NEW_API_TC001(void) +{ + TestMemInit(); + /* Set method to NULL */ + BSL_UIO *uio = BSL_UIO_New(NULL); + ASSERT_TRUE(uio == NULL); +#ifdef HITLS_BSL_UIO_SCTP + /* Set transportType to sctp and construct a method structure. */ + { + const BSL_UIO_Method *ori = BSL_UIO_SctpMethod(); + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_Write; + method.read = STUB_Read; + method.ctrl = STUB_Ctrl; + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL && BSL_UIO_GetTransportType(uio) == BSL_UIO_SCTP); + BSL_UIO_Free(uio); + } +#endif + /* Set transportType to tcp and construct the method structure. */ + { + const BSL_UIO_Method *ori = BSL_UIO_TcpMethod(); + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_Write; + method.read = STUB_Read; + method.ctrl = STUB_Ctrl; + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL && BSL_UIO_GetTransportType(uio) == BSL_UIO_TCP); + BSL_UIO_Free(uio); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_NEW_API_TC002 + * @title BSL uio and meth parameter test + * @precon Registering memory-related functions. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_NEW_API_TC002(void) +{ + TestMemInit(); + + BSL_UIO *uio = BSL_UIO_New(NULL); + ASSERT_EQ(uio, NULL); + BSL_UIO_Method *ori = BSL_UIO_NewMethod(); + ASSERT_NE(ori, NULL); + int32_t customType = BSL_UIO_EXTEND + 3; + + ASSERT_EQ(BSL_UIO_SetMethodType(ori, customType), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_READ_CB, BslUioRead), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_WRITE_CB, BslUioWrite), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_CTRL_CB, BslUioCtrl), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_CREATE_CB, BslUioCreate), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_DESTROY_CB, BslUioDestroy), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_PUTS_CB, BslUioPuts), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_GETS_CB, BslUioGets), BSL_SUCCESS); + + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_READ_CB, NULL), BSL_NULL_INPUT); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_GETS_CB + 1, BslUioGets), BSL_INVALID_ARG); + + uio = BSL_UIO_New(ori); + ASSERT_NE(uio, NULL); + + ASSERT_EQ(BSL_UIO_GetTransportType(uio), customType); + + char *test = "test "; + uint32_t len = 0; + ASSERT_EQ(BSL_UIO_Gets(uio, test, &len), BSL_INVALID_ARG); + + ASSERT_EQ(BSL_UIO_Puts(uio, test, &len), BSL_INVALID_ARG); + +exit: + BSL_UIO_Free(uio); + BSL_UIO_FreeMethod(ori); +} +/* END_CASE */ + + +/** + * @test SDV_BSL_UIO_NEW_API_TC001 + * @title BSL uio and meth functional test + * @precon Registering memory-related functions. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_NEW_FUNC_TC001(void) +{ + uint8_t test[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + TestMemInit(); + + BSL_UIO_Method *ori = BSL_UIO_NewMethod(); + ASSERT_NE(ori, NULL); + int32_t customType = BSL_UIO_EXTEND + 3; + + ASSERT_EQ(BSL_UIO_SetMethodType(ori, customType), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_READ_CB, BslUioRead), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_WRITE_CB, BslUioWrite), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_CTRL_CB, BslUioCtrl), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_CREATE_CB, BslUioCreate), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_DESTROY_CB, BslUioDestroy), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_PUTS_CB, BslUioPuts), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_SetMethod(ori, BSL_UIO_GETS_CB, BslUioGets), BSL_SUCCESS); + BSL_UIO *uio = BSL_UIO_New(ori); + ASSERT_NE(uio, NULL); + + ASSERT_EQ(BSL_UIO_GetTransportType(uio), customType); + + uint32_t len = 0; + ASSERT_EQ(BSL_UIO_Write(uio, test, 3, &len), BSL_SUCCESS); + ASSERT_EQ(len, 3); + + ASSERT_EQ(BSL_UIO_Write(uio, &test[3], 7, &len), BSL_SUCCESS); + ASSERT_EQ(len, 7); + + uint32_t index = 0; + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_CUSTOM_UIO_GET_INDEX, sizeof(index), &index), BSL_SUCCESS); + ASSERT_EQ(index, 10); + + uint8_t readBuff[20] = {0}; + ASSERT_EQ(BSL_UIO_Read(uio, readBuff, 8, &len), BSL_SUCCESS); + ASSERT_EQ(len, 8); + + ASSERT_EQ(BSL_UIO_Read(uio, &readBuff[7], 8, &len), BSL_SUCCESS); + ASSERT_EQ(len, 2); + + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_CUSTOM_UIO_GET_INDEX, sizeof(index), &index), BSL_SUCCESS); + ASSERT_EQ(index, 0); + +exit: + BSL_UIO_Free(uio); + BSL_UIO_FreeMethod(ori); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_INIT_FUNC_TC001 + * @title Init status value test: The uio type of the FD can be set. + * @precon nan + * @brief + * 1.BSL_UIO_New,Expected result 1 is obtained. + * 2.BSL_UIO_GET_INIT,Expected result 2 is obtained. + * 3.BSL_UIO_GET_FD,Expected result 3 is obtained. + * 4.BSL_UIO_SET_FD,Expected result 4 is obtained. + * 5.BSL_UIO_GET_INIT,Expected result 5 is obtained. + * 6.BSL_UIO_GET_FD,Expected result 6 is obtained. + * @expect + * 1.Expected success + * 2.The value of init is 0. + * 3.Expected failure, The error code is BSL_UIO_UNINITIALIZED,fd is - 1. + * 4.Expected success + * 5.The value of init is 1. + * 6.Expected success + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_INIT_FUNC_TC001(int uioType) +{ + BSL_UIO *uio = NULL; + int32_t fd = 5; + uint8_t init = 0; + int32_t getFd = 0; + + const BSL_UIO_Method *ori = NULL; + switch (uioType) { + case BSL_UIO_TCP: + ori = GetUioMethodByType(uioType); + break; + case BSL_UIO_SCTP: +#ifdef HITLS_BSL_UIO_SCTP + ori = GetUioMethodByType(uioType); +#else + SKIP_TEST(); +#endif + break; + default: // The uio of the FD cannot be set. + ASSERT_TRUE(false); + } + ASSERT_TRUE(ori != NULL); + + uio = BSL_UIO_New(ori); + ASSERT_TRUE(uio != NULL); + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_GET_INIT, (int32_t)sizeof(init), &init), BSL_SUCCESS); + ASSERT_EQ(init, 0); + + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_SET_FD, (int32_t)sizeof(fd), &fd), BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_GET_INIT, (int32_t)sizeof(init), &init), BSL_SUCCESS); + ASSERT_EQ(init, 1); + + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_GET_FD, (int32_t)sizeof(fd), &getFd), BSL_SUCCESS); + ASSERT_EQ(getFd, fd); + +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_INIT_FUNC_TC002 + * @title Init status value test: Test the UIO type whose init is set to 1 during create. + * @precon nan + * @brief + * 1.Call BSL_UIO_New. Expected result 1 is obtained. + * 2.Call BSL_UIO_GET_INIT. Expected result 1 is obtained. + * @expect + * 1.Success + * 2.init is 1 + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_INIT_FUNC_TC002(int uioType) +{ + BSL_UIO *uio = NULL; + uint8_t init = 0; + + const BSL_UIO_Method *ori = NULL; + switch (uioType) { + case BSL_UIO_BUFFER: + ori = GetUioMethodByType(uioType); + break; + default: + ASSERT_TRUE(false); + } + ASSERT_TRUE(ori != NULL); + + uio = BSL_UIO_New(ori); + ASSERT_TRUE(uio != NULL); + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_GET_INIT, (int32_t)sizeof(init), &init), BSL_SUCCESS); + ASSERT_EQ(init, 1); + +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test UT_BSL_UIO_FREE_API_TC001 + * @title Input parameter test + * @precon nan + * @brief + * 1. Set UIO to null and invoke BSL_UIO_Free. Expected result 1 is obtained. + * @expect + * 1. It is expected that the program does not dump code. No memory leakage occurs. + */ +/* BEGIN_CASE */ +void UT_BSL_UIO_FREE_API_TC001(void) +{ + /* The test UIO is empty. */ + BSL_UIO_Free(NULL); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_SETUSERDATA_API_TC001 + * @title Input parameter test + * @precon nan + * @brief + * 1.The specified uio is empty, Invoke BSL_UIO_SetUserData,Expected result 1 is obtained. + * 2.Construct the uio object, the user data is empty, invoke the BSL_UIO_SetUserData interface. + Expected result 2 is obtained. + * 3.Invoke BSL_UIO_SetUserData to specify that data1 is not null, Expected result 3 is obtained. + * 4.User data2 is not empty, call BSL_UIO_SetUserData again, Expected result 4 is obtained. + * 5.Releasing a UIO Object, Expected result 5 is obtained. + * @expect + * 1.Expected return failure + * 2.Expected success + * 3.Expected success + * 4.Expected success + * 5.It is expected that the program does not have code dump and no memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_SETUSERDATA_API_TC001(void) +{ + BSL_UIO *uio = NULL; + void *userData1 = (void *)STUB_Write; + void *userData2 = (void *)STUB_Read; + /* The test UIO is empty. */ + int32_t ret = BSL_UIO_SetUserData(NULL, userData1); + ASSERT_TRUE(ret == BSL_NULL_INPUT); + + uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(uio != NULL); + + ret = BSL_UIO_SetUserData(uio, NULL); + ASSERT_TRUE(ret == BSL_SUCCESS); + + ret = BSL_UIO_SetUserData(uio, userData1); + ASSERT_TRUE(ret == BSL_SUCCESS); + + ret = BSL_UIO_SetUserData(uio, userData2); + ASSERT_TRUE(ret == BSL_SUCCESS); + +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_GETUSERDATA_API_TC001 + * @title Input parameter test + * @precon nan + * @brief + * 1.The specified uio is empty., invoke BSL_UIO_GetUserData. Expected result 1 is obtained. + * 2.Construct the uio object, invoke BSL_UIO_GetUserData. Expected result 2 is obtained. + * 3.Construct user data, invoke BSL_UIO_SetUserData. Expected result 3 is obtained. + * 4.Invoke BSL_UIO_GetUserData. Expected result 4 is obtained. + * 5.Invoke BSL_UIO_Free. Expected result 5 is obtained. + * @expect + * 1.Expected return NULL + * 2.Expected return NULL + * 3.Expected success + * 4.The expected return value is the same as the data pointer. + * 5.It is expected that the program does not have code dump and no memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_GETUSERDATA_API_TC001(void) +{ + BSL_UIO *uio = NULL; + void *userData = (void *)STUB_Write; + /* The test UIO is empty. */ + void *data = BSL_UIO_GetUserData(NULL); + ASSERT_TRUE(data == NULL); + + uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(uio != NULL); + + int32_t ret = BSL_UIO_SetUserData(uio, userData); + ASSERT_TRUE(ret == BSL_SUCCESS); + + data = BSL_UIO_GetUserData(uio); + ASSERT_TRUE(data == userData); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_FLAGS_FUNC_TC001 + * @title UIO Setting the Status Test + * @precon nan + * @brief + * 1.BSL_UIO_New. Expected result 1 is obtained. + * 2.BSL_UIO_SetFlags. Expected result 2 is obtained. + * @expect + * 1.Expected success + * 2.If the flags are invalid, BSL_INVALID_ARG is returned. If the flags are valid, BSL_SUCCESS is returned. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_FLAGS_FUNC_TC001(int uioType) +{ + if (uioType == BSL_UIO_SCTP) { +#ifndef HITLS_BSL_UIO_SCTP + SKIP_TEST(); +#endif + } + BSL_UIO *uio = NULL; + + const BSL_UIO_Method *ori = GetUioMethodByType(uioType); + ASSERT_TRUE(ori != NULL); + + uio = BSL_UIO_New(ori); + ASSERT_TRUE(uio != NULL); + + // 0000 0001 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_READ), BSL_SUCCESS); + // 0000 0010 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE), BSL_SUCCESS); + // 0000 0100 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_IO_SPECIAL), BSL_SUCCESS); + // 0000 0111 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_RWS), BSL_SUCCESS); + // 0000 1000 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_SHOULD_RETRY), BSL_SUCCESS); + // 0001 0000 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_MEM_READ_ONLY), BSL_INVALID_ARG); + // 0010 0000 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_BASE64_NO_NEWLINE), BSL_SUCCESS); + // 0100 0000 + ASSERT_EQ(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_BASE64_PEM), BSL_SUCCESS); + // 0111 1111 + ASSERT_EQ(BSL_UIO_SetFlags(uio, 0b01111111), BSL_INVALID_ARG); + // 0110 1111 + ASSERT_EQ(BSL_UIO_SetFlags(uio, 0b01101111), BSL_SUCCESS); + // 1110 1111 + ASSERT_EQ(BSL_UIO_SetFlags(uio, 0b11101111), BSL_INVALID_ARG); + + ASSERT_EQ(BSL_UIO_SetFlags(uio, -1), BSL_INVALID_ARG); + ASSERT_EQ(BSL_UIO_SetFlags(uio, INT_MAX), BSL_INVALID_ARG); + ASSERT_EQ(BSL_UIO_SetFlags(uio, 0), BSL_INVALID_ARG); + +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_FLAGS_FUNC_TC002 + * @title UIO flags interface test + * @precon +* @brief +* 1. uio new. Expected result 1 is obtained. +* 2. Set two flags A and B. Expected result 2 is obtained. +* 3. Detection mark A. Expected result 3 is obtained. +* 4. Clear mark A. Expected result 4 is obtained. +* 5. Detection mark A. Expected result 5 is obtained. +* 6. Detection mark B. Expected result 6 is obtained. +* @expect +* 1. The success is not null. +* 2. Success +* 3. Successful and flag A detected +* 4. Success +* 5. Succeeded and Flag A Not Detected +* 6. Successful and Mark B detected + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_FLAGS_FUNC_TC002(void) +{ + BSL_UIO *uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(uio != NULL); + + ASSERT_TRUE(BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_SHOULD_RETRY) == BSL_SUCCESS); + + uint32_t out = 0; + ASSERT_TRUE(BSL_UIO_TestFlags(uio, BSL_UIO_FLAGS_WRITE, &out) == BSL_SUCCESS); + ASSERT_TRUE(out == BSL_UIO_FLAGS_WRITE); + + ASSERT_TRUE(BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_WRITE) == BSL_SUCCESS); + + ASSERT_TRUE(BSL_UIO_TestFlags(uio, BSL_UIO_FLAGS_WRITE, &out) == BSL_SUCCESS); + ASSERT_TRUE(out == 0); + + ASSERT_TRUE(BSL_UIO_TestFlags(uio, BSL_UIO_FLAGS_SHOULD_RETRY, &out) == BSL_SUCCESS); + ASSERT_TRUE(out == BSL_UIO_FLAGS_SHOULD_RETRY); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_UPREF_API_TC001 + * @title Input Parameter test + * @precon nan + * @brief + * 1.The specified uio is empty, invoke UIO_UpRef. Expected result 1 is obtained. + * 2.Construct the uio object(BSL_UIO_New), invoke UIO_UpRef. Expected result 2 is obtained. + * 3.BSL_UIO_Free is invoked twice. Expected result 3 is obtained. + * @expect + * 1.Expected return failure + * 2.Expected success + * 3.It is expected that the program does not have code dump and no memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_UPREF_API_TC001(void) +{ +#ifndef HITLS_BSL_UIO_SCTP + SKIP_TEST(); +#else + BSL_UIO *uio = NULL; + /* The test UIO is empty. */ + int32_t ret = BSL_UIO_UpRef(NULL); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + uio = BSL_UIO_New(BSL_UIO_SctpMethod()); + ASSERT_TRUE(uio != NULL); + + ret = BSL_UIO_UpRef(uio); + ASSERT_TRUE(ret == BSL_SUCCESS); + +exit: + BSL_UIO_Free(uio); + BSL_UIO_Free(uio); +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_WRITE_API_TC001 + * @title Input parameter test + * @precon nan + * @brief + * 1. Call BSL_UIO_TcpMethod to create a tcp method. Expected result 1 is obtained. + * 2. The value of the input parameter UIO is NULL when BSL_UIO_Write is invoked. Expected result 2 is obtained. + * 3. The value of the input parameter data is NULL when BSL_UIO_Write is invoked. Expected result 2 is obtained. + * 4. The value of the input parameter data len is 0 when BSL_UIO_Write is invoked. Expected result 2 is obtained. + * 5. The value of the input parameter write len is NULL when BSL_UIO_Write is invoked. Expected result 2 is obtained. + * @expect + * 1. The TCP method is successfully created. + * 2. Return HITLS_INTERNAL_EXCEPTION + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_WRITE_API_TC001(void) +{ + BSL_UIO *uio = NULL; + uint8_t data[MAX_BUF_SIZE] = {0}; + const uint32_t len = 1; + uint32_t writeLen; + + const BSL_UIO_Method *ori = BSL_UIO_TcpMethod(); + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_Write; + method.read = STUB_Read; + + /* The test UIO is empty. */ + int32_t ret = BSL_UIO_Write(NULL, data, len, &writeLen); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL); + + /* The test data is null. */ + ret = BSL_UIO_Write(uio, NULL, len, &writeLen); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + /* Test the case when the write length is 0. */ + ret = BSL_UIO_Write(uio, data, 0, &writeLen); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + /* Test that writeLen is NULL. */ + ret = BSL_UIO_Write(uio, data, len, NULL); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_READ_API_TC001 + * @title Input parameter test + * @precon nan + * @brief + * 1. Call BSL_UIO_TcpMethod to create a tcp method. Expected result 1 is obtained. + * 2. The value of the input parameter UIO is NULL when BSL_UIO_Read is invoked. Expected result 2 is obtained. + * 3. The value of the input parameter data is NULL when BSL_UIO_Read is invoked. Expected result 3 is obtained. + * 4. The value of the input parameter data len is 0 when BSL_UIO_Read is invoked. Expected result 4 is obtained. + * 5. The value of the input parameter write len is NULL when BSL_UIO_Read is invoked. Expected result 4 is obtained. + * @expect + * 1. The TCP method is successfully created. + * 2. Return BSL_INTERNAL_EXCEPTION + * 3. Return BSL_INTERNAL_EXCEPTION + * 4. Return BSL_INTERNAL_EXCEPTION + * 5. Return BSL_INTERNAL_EXCEPTION + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_READ_API_TC001(void) +{ + BSL_UIO *uio = NULL; + uint8_t data[MAX_BUF_SIZE] = {0}; + const uint32_t len = 1; + uint32_t readLen; + + const BSL_UIO_Method *ori = BSL_UIO_TcpMethod(); + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_Write; + method.read = STUB_Read; + + /* The test UIO is empty. */ + int32_t ret = BSL_UIO_Read(NULL, data, len, &readLen); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL); + + /* The test data is null. */ + ret = BSL_UIO_Read(uio, NULL, len, &readLen); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + /* Test the case when the write length is 0. */ + ret = BSL_UIO_Read(uio, data, 0, &readLen); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); + + /* Test that writeLen is NULL. */ + ret = BSL_UIO_Read(uio, data, len, NULL); + ASSERT_TRUE(ret == BSL_INTERNAL_EXCEPTION); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_SET_USERDATA_FREE_TC001 + * @title Set userData free test + * @precon nan + * @brief + * 1. Call BSL_UIO_New to create a tcp uio. Expected result 1 is obtained. + * 2. Apply for space for userData. Expected result 2 is obtained. + * 3. Call BSL_UIO_SetUserData to set userData for UIO. Expected result 3 is obtained. + * 4. Call BSL_UIO_SetUserDataFreeFunc when uio is NULL. Expected result 4 is obtained. + * 5. Call BSL_UIO_SetUserDataFreeFunc when uio is not null. Expected result 5 is obtained. + * @expect + * 1. The TCP UIO is successfully created. + * 2. The value of userData is not empty. + * 3. Return BSL_SUCCESS and the userdata of the UIO is not empty. + * 4. Return BSL_NULL_INPUT + * 5. Return BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_SET_USERDATA_FREE_TC001(void) +{ + BSL_UIO *uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(uio != NULL); + void *userData = BSL_SAL_Malloc(MAX_BUF_SIZE); + ASSERT_TRUE(userData != NULL); + + int32_t ret = BSL_UIO_SetUserData(uio, userData); + ASSERT_TRUE(ret == BSL_SUCCESS); + ASSERT_TRUE(uio->userData != NULL); + + ret = BSL_UIO_SetUserDataFreeFunc(NULL, BSL_SAL_Free); + ASSERT_TRUE(ret == BSL_NULL_INPUT); + + ret = BSL_UIO_SetUserDataFreeFunc(uio, BSL_SAL_Free); + ASSERT_TRUE(ret == BSL_SUCCESS); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_GET_METHOD_TC001 + * @title Get uio method test + * @precon nan + * @brief + * 1. Call BSL_UIO_New to create a tcp uio. Expected result 1 is obtained. + * 2. Call BSL_UIO_TcpMethod to create a tcp method. Call BSL_UIO_GetMethod to obtain the method of TCP_UIO. + * Compare the two methods. Expected result 2 is obtained. + * @expect + * 1. The TCP UIO is successfully created. + * 2. The two methods are equal. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_GET_METHOD_TC001(void) +{ + const BSL_UIO_Method *ori = BSL_UIO_TcpMethod(); + BSL_UIO *uio = BSL_UIO_New(ori); + ASSERT_TRUE(uio != NULL); + + const BSL_UIO_Method *method = BSL_UIO_GetMethod(uio); + int ret = memcmp(method, ori, sizeof(BSL_UIO_Method)); + ASSERT_TRUE(ret == 0); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_GET_READANDWRITE_NUM_TC001 + * @title Get read and written num test + * @precon nan + * @brief + * 1. Call BSL_UIO_TcpMethod to create a tcp method. Expected result 1 is obtained. + * 2. Call BSL_UIO_New to create a tcp uio. Expected result 2 is obtained. + * 3. Call BSL_UIO_Ctrl and transfer the BSL_UIO_GET_WRITE_NUM parameter to obtain the number of written + * bytes. Expected result 3 is obtained. + * 4. Call BSL_UIO_Ctrl and transfer the BSL_UIO_GET_READ_NUM parameter to obtain the number of read bytes. + * Expected result 4 is obtained. + * @expect + * 1. The TCP METHOD is successfully created. + * 2. The TCP UIO is successfully created. + * 3. The value of writeNum is the same as the number of written bytes. + * 4. The value of readNum is the same as the number of read bytes. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_GET_READANDWRITE_NUM_TC001(void) +{ + BSL_UIO *uio = NULL; + uint8_t data[10] = {'0', '1', '2', '3', '4'}; + uint8_t readBuf[10] = {0}; + const uint32_t dataLen = 5; + uint32_t writeLen = 0; + uint32_t readLen = 0; + int64_t writeNum = 0; + int64_t readNum = 0; + + const BSL_UIO_Method *ori = BSL_UIO_TcpMethod(); + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_Write; + method.read = STUB_Read; + + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL); + BSL_UIO_SetInit(uio, 1); + + ASSERT_TRUE(BSL_UIO_Write(uio, data, dataLen, &writeLen) == BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_GET_WRITE_NUM, (int32_t)sizeof(writeNum), &writeNum), BSL_SUCCESS); + ASSERT_EQ(writeNum, writeLen); + + ASSERT_TRUE(BSL_UIO_Read(uio, readBuf, dataLen, &readLen) == BSL_SUCCESS); + ASSERT_EQ(BSL_UIO_Ctrl(uio, BSL_UIO_GET_READ_NUM, (int32_t)sizeof(readNum), &readNum), BSL_SUCCESS); + ASSERT_EQ(readNum, readLen); +exit: + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_SET_FD_TC001 + * @title Set fd test + * @precon nan + * @brief + * 1. Call BSL_UIO_New to create a tcp uio. Expected result 1 is obtained. + * 2. Call BSL_UIO_SetFd to set fd to uio. Call BSL_UIO_Ctrl and transfer the BSL_UIO_GET_FD parameter to obtain + * the fd1 of uio. Compare the two fds. Expected result 2 is obtained. + * @expect + * 1. The TCP UIO is successfully created. + * 2. The two fds are equal. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_SET_FD_TC001(void) +{ + char *filename = "fd_test_file.txt"; + int fd = open(filename, O_RDWR | O_CREAT, 0060); + const char *data = "012345678\nabcdef"; + write(fd, data, strlen(data)); + BSL_UIO *uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(uio != NULL); + BSL_UIO_SetIsUnderlyingClosedByUio(uio, true); + + BSL_UIO_SetFd(uio, fd); + int32_t fd1 = -1; + ASSERT_TRUE(BSL_UIO_Ctrl(uio, BSL_UIO_GET_FD, (int32_t)sizeof(fd1), &fd1) == BSL_SUCCESS); + ASSERT_TRUE(fd == fd1); +exit: + BSL_UIO_Free(uio); + remove(filename); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_NEXT_TC001 + * @title Uio next test + * @precon nan + * @brief + * 1. Call BSL_UIO_New to create a tcp uio named tcp1. Expected result 1 is obtained. + * 2. Call BSL_UIO_New to create a tcp uio named tcp2. Expected result 2 is obtained. + * 3. Append tcp2 to tcp1. Expected result 3 is obtained. + * 4. Check the next uio of tcp1 and the next uio of tcp2. Expected result 4 is obtained. + * @expect + * 1. The tcp1 is successfully created. + * 2. The tcp2 is successfully created. + * 3. Return BSL_SUCCESS. + * 4. The next uio of tcp1 is tcp2 and the next uio of tcp2 is NULL. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_NEXT_TC001(void) +{ + BSL_UIO *tcp1 = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(tcp1 != NULL); + BSL_UIO *tcp2 = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(tcp2 != NULL); + + ASSERT_TRUE(BSL_UIO_Append(tcp1, tcp2) == BSL_SUCCESS); + ASSERT_TRUE(BSL_UIO_Next(tcp1) == tcp2); + ASSERT_TRUE(BSL_UIO_Next(tcp2) == NULL); +exit: + BSL_UIO_Free(tcp1); + BSL_UIO_Free(tcp2); +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_SCTP_API_TC001 + * @title SCTP ctrl test + * @precon nan + * @brief + * 1. Call BSL_UIO_SctpMethod to create a SCTP method. Expected result 1 is obtained. + * 2. The input cmd is BSL_UIO_SET_PEER_IP_ADDR when BSL_UIO_Ctrl is invoked. Expected result 2 is obtained. + * 3. The input cmd is BSL_UIO_GET_PEER_IP_ADDR when BSL_UIO_Ctrl is invoked. Expected result 3 is obtained. + * 4. The input cmd is BSL_UIO_SCTP_SET_APP_STREAM_ID when BSL_UIO_Ctrl is invoked. Expected result 4 is obtained. + * @expect + * 1. The SCTP method is successfully created. + * 2. Return BSL_SUCCESS + * 3. Return BSL_SUCCESS + * 4. Return BSL_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_SCTP_API_TC001(void) +{ +#ifndef HITLS_BSL_UIO_SCTP + SKIP_TEST(); +#else + BSL_UIO *uio = NULL; + int ret; + uint8_t ipAddr[256] = {0}; + BSL_UIO_CtrlGetPeerIpAddrParam param = {ipAddr, sizeof(ipAddr)}; + uint8_t data[IP_ADDR_V4_LEN] = {0}; + uint16_t sendAppStreamId = 1; + + const BSL_UIO_Method *ori = BSL_UIO_SctpMethod(); + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_Write; + method.read = STUB_Read; + + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL); + + ret = BSL_UIO_Ctrl(uio, BSL_UIO_SET_PEER_IP_ADDR, sizeof(data), data); + ASSERT_TRUE(ret == BSL_SUCCESS); + + ret = BSL_UIO_Ctrl(uio, BSL_UIO_GET_PEER_IP_ADDR, sizeof(param), ¶m); + ASSERT_TRUE(ret == BSL_SUCCESS); + + ret = BSL_UIO_Ctrl(uio, BSL_UIO_SCTP_SET_APP_STREAM_ID, sizeof(uint16_t), &sendAppStreamId); + ASSERT_TRUE(ret == BSL_SUCCESS); +exit: + BSL_UIO_Free(uio); +#endif +} +/* END_CASE */ + +/** + * @test SDV_BSL_UIO_BUFFER_RESET_TC001 + * @title Buffer reset test + * @precon nan + * @brief + * 1. Call BSL_UIO_New to create a buffer uio named buffer. Expected result 1 is obtained. + * 2. Call BSL_UIO_New to create a tcp uio named tcp. Expected result 2 is obtained. + * 3. Append tcp to buffer. Expected result 3 is obtained. + * 4. Write 2048-length data to the buffer uio. Expected result 4 is obtained. + * 5. Call BSL_UIO_Ctrl and transfer the BSL_UIO_RESET parameter to reset the buffer uio. Expected result 5 is + * obtained. + * @expect + * 1. The buffer is successfully created. + * 2. The tcp is successfully created. + * 3. Return BSL_SUCCESS and the next uio of buffer is tcp. + * 4. Return BSL_SUCCESS and writeLen is 2048. + * 5. Return BSL_UIO_FAIL. + */ +/* BEGIN_CASE */ +void SDV_BSL_UIO_BUFFER_RESET_TC001(void) +{ + BSL_UIO *buffer = BSL_UIO_New(BSL_UIO_BufferMethod()); + ASSERT_TRUE(buffer != NULL); + BSL_UIO *tcp = BSL_UIO_New(BSL_UIO_TcpMethod()); + ASSERT_TRUE(tcp != NULL); + + int32_t ret = BSL_UIO_Append(buffer, tcp); + ASSERT_TRUE(ret == BSL_SUCCESS); + ASSERT_TRUE(BSL_UIO_Next(buffer) == tcp); + ASSERT_TRUE(BSL_UIO_Next(tcp) == NULL); + + uint8_t buf[8192]; + uint32_t writeLen = 0; + ret = BSL_UIO_Write(buffer, buf, 2048, &writeLen); + ASSERT_TRUE(ret == BSL_SUCCESS); + ASSERT_TRUE(writeLen == 2048); + + ret = BSL_UIO_Ctrl(buffer, BSL_UIO_RESET, 0, NULL); + ASSERT_TRUE(ret = BSL_UIO_FAIL); +exit: + BSL_UIO_Free(buffer); + BSL_UIO_Free(tcp); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/uio/test_suite_sdv_uio.data b/testcode/sdv/testcase/bsl/uio/test_suite_sdv_uio.data new file mode 100644 index 00000000..c120eb2c --- /dev/null +++ b/testcode/sdv/testcase/bsl/uio/test_suite_sdv_uio.data @@ -0,0 +1,68 @@ +SDV_BSL_UIO_NEW_API_TC001 +SDV_BSL_UIO_NEW_API_TC001: + +SDV_BSL_UIO_NEW_API_TC002 +SDV_BSL_UIO_NEW_API_TC002: + +SDV_BSL_UIO_NEW_FUNC_TC001 +SDV_BSL_UIO_NEW_FUNC_TC001: + +SDV_BSL_UIO_INIT_FUNC_TC001 BSL_UIO_TCP +SDV_BSL_UIO_INIT_FUNC_TC001:BSL_UIO_TCP + +SDV_BSL_UIO_INIT_FUNC_TC001 BSL_UIO_SCTP +SDV_BSL_UIO_INIT_FUNC_TC001:BSL_UIO_SCTP + +SDV_BSL_UIO_INIT_FUNC_TC002 BSL_UIO_BUFFER +SDV_BSL_UIO_INIT_FUNC_TC002:BSL_UIO_BUFFER + +UT_BSL_UIO_FREE_API_TC001 +UT_BSL_UIO_FREE_API_TC001: + +SDV_BSL_UIO_SETUSERDATA_API_TC001 +SDV_BSL_UIO_SETUSERDATA_API_TC001: + +SDV_BSL_UIO_GETUSERDATA_API_TC001 +SDV_BSL_UIO_GETUSERDATA_API_TC001: + +uio flags test: BSL_UIO_TCP +SDV_BSL_UIO_FLAGS_FUNC_TC001:BSL_UIO_TCP + +uio flags test: BSL_UIO_SCTP +SDV_BSL_UIO_FLAGS_FUNC_TC001:BSL_UIO_SCTP + +uio flags test: BSL_UIO_BUFFER +SDV_BSL_UIO_FLAGS_FUNC_TC001:BSL_UIO_BUFFER + +SDV_BSL_UIO_FLAGS_FUNC_TC002 +SDV_BSL_UIO_FLAGS_FUNC_TC002: + +SDV_BSL_UIO_UPREF_API_TC001 +SDV_BSL_UIO_UPREF_API_TC001: + +SDV_BSL_UIO_WRITE_API_TC001 +SDV_BSL_UIO_WRITE_API_TC001: + +SDV_BSL_UIO_READ_API_TC001 +SDV_BSL_UIO_READ_API_TC001: + +SDV_BSL_UIO_SET_USERDATA_FREE_TC001 +SDV_BSL_UIO_SET_USERDATA_FREE_TC001: + +SDV_BSL_UIO_GET_METHOD_TC001 +SDV_BSL_UIO_GET_METHOD_TC001: + +SDV_BSL_UIO_GET_READANDWRITE_NUM_TC001 +SDV_BSL_UIO_GET_READANDWRITE_NUM_TC001: + +SDV_BSL_UIO_SET_FD_TC001 +SDV_BSL_UIO_SET_FD_TC001: + +SDV_BSL_UIO_NEXT_TC001 +SDV_BSL_UIO_NEXT_TC001: + +SDV_BSL_UIO_SCTP_API_TC001 +SDV_BSL_UIO_SCTP_API_TC001: + +SDV_BSL_UIO_BUFFER_RESET_TC001 +SDV_BSL_UIO_BUFFER_RESET_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/bsl/usr/test_suite_sdv_usr.c b/testcode/sdv/testcase/bsl/usr/test_suite_sdv_usr.c new file mode 100644 index 00000000..b0b6db1e --- /dev/null +++ b/testcode/sdv/testcase/bsl/usr/test_suite_sdv_usr.c @@ -0,0 +1,71 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_user_data.h" +#include "bsl_sal.h" +#include "bsl_errno.h" + +/* END_HEADER */ + +void Stub_BSL_USER_ExDataFree(void *parent, void *ptr, BSL_USER_ExData *ad, int idx, long argl, void *argp) +{ + (void)parent; + (void)idx; + (void)argl; + (void)argp; + for (int32_t i = 0; i < BSL_MAX_EX_DATA; i++) { + if (ad->sk[i] == ptr) { + BSL_SAL_FREE(ad->sk[i]); + } + } + return; +} + +/** + * @test SDV_BSL_USERDATA_API_TC001 + * @title Find tlv value pos test + * @precon nan + * @brief + * 1. Invoke BSL_USER_GetExDataNewIndex to new a index. Expected result 1 is obtained. + * 2. Invoke BSL_USER_SetExData to set a userdata. Expected result 2 is obtained. + * 3. Invoke BSL_USER_FreeExDataIndex to free userdata, and invoke to get userdata. Expected result 3 is obtained. + * @expect + * 1. Expected -1 + * 2. Expected success + * 3. Expected NULL + */ +/* BEGIN_CASE */ +void SDV_BSL_USERDATA_API_TC001(void) +{ + int ret; + void *ctx = NULL; + void *newCtx = NULL; + BSL_USER_ExData exdata = { 0 }; + int idx = BSL_USER_GetExDataNewIndex(BSL_USER_DATA_EX_INDEX_SSL, 0, NULL, NULL, NULL, Stub_BSL_USER_ExDataFree); + ASSERT_TRUE(idx != -1); + + ctx = BSL_SAL_Calloc(1u, 1024); + ret = BSL_USER_SetExData(&exdata, idx, ctx); + ASSERT_TRUE(ret == BSL_SUCCESS); + + BSL_USER_FreeExDataIndex(BSL_USER_DATA_EX_INDEX_SSL, NULL, &exdata); + newCtx = BSL_USER_GetExData(&exdata, idx); + ASSERT_TRUE(newCtx == NULL); +exit: + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/bsl/usr/test_suite_sdv_usr.data b/testcode/sdv/testcase/bsl/usr/test_suite_sdv_usr.data new file mode 100644 index 00000000..7e428bc4 --- /dev/null +++ b/testcode/sdv/testcase/bsl/usr/test_suite_sdv_usr.data @@ -0,0 +1,2 @@ +SDV_BSL_USERDATA_API_TC001 +SDV_BSL_USERDATA_API_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes.c b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes.c new file mode 100644 index 00000000..a11f7af3 --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes.c @@ -0,0 +1,1198 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "crypt_errno.h" +#include "crypt_eal_cipher.h" +#include "eal_cipher_local.h" +#include "bsl_sal.h" +#include "securec.h" + +#define MAX_OUTPUT 5000 +#define MCT_INNER_LOOP 1000 +#define AES_BLOCKSIZE 16 + +#define MAX_DATA_LEN 1024 +#define AES_TAG_LEN 16 + +static void Test_CipherOverLap(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc, uint32_t inOffset, uint32_t outOffset) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + memcpy_s(outTmp + inOffset, sizeof(outTmp) - inOffset, in->x, in->len); + ret = CRYPT_EAL_CipherUpdate(ctx, outTmp + inOffset, in->len, outTmp + outOffset, &len); + if (outOffset > 0 && outOffset < in->len) { + ASSERT_TRUE(ret == CRYPT_EAL_ERR_PART_OVERLAP); + } else { + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - len; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + totalLen + outOffset, &len); + totalLen += len; + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp + outOffset, out->x, out->len) == 0); + } + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} + +void reportLog(CRYPT_EVENT_TYPE oper, CRYPT_ALGO_TYPE type, int32_t id, int32_t err) +{ +#ifdef PRINT_TO_TERMINAL + printf("CRYPT_EVENT_TYPE=%d, CRYPT_ALGO_TYPE=%d, algId=%d, errorCode=%d\n", oper, type, id, err); +#else + (void)oper; + (void)type; + (void)id; + (void)err; +#endif +} +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_AES_NEW_CTX_API_TC001 + * @title Impact of the invalid algorithm ID on the New interface + * @brief + * 1.Create the context ctx with the input parameter CRYPT_CIPHER_MAX. Expected result 1 is obtained. + * @expect + * 1.Failed. NULL is returned. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_NEW_CTX_API_TC001(void) +{ + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_MAX); + ASSERT_TRUE(ctx == NULL); +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_INIT_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherInit Interface + * @precon Registering memory-related functions. + * @brief + * 1.Call the New interface with param CRYPT_CIPHER_AES192_CBC. Expected result 1 is obtained. + * 2.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is not 0, + * iv is not NULL, and ivLen is not 0. Expected result 2 is obtained. + * 3.Call the Init interface, ctx is NULL, key is not NULL, keyLen is not 0, + * iv is not NULL, and ivLen is not 0. Expected result 3 is obtained. + * 4.Call the Init interface, ctx is not NULL, key is NULL, keyLen is not 0, + * iv is not NULL, and ivLen is not 0. Expected result 4 is obtained. + * 5.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is 0, + * iv is not NULL, and ivLen is not 0. Expected result 5 is obtained. + * 6.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is not 0, + * iv is NULL, and ivLen is not 0. Expected result 6 is obtained. + * 7.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is not 0, + * iv is not NULL, and ivLen is 0. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Init succeeded. + * 3.Init failed. + * 4.Init failed. + * 5.Init failed. + * 6.Init failed. + * 7.Init failed. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_INIT_API_TC001(Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(NULL, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherInit(ctx, NULL, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherInit(ctx, key->x, 0, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_AES_ERR_KEYLEN); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, NULL, iv->len, true); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, 0, true); + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_DEINIT_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherDeinit Interface + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Deinit interface, ctx is not NULL. Expected result 2 is obtained. + * 3.Call the Deinit interface, ctx is NULL. Expected result 3 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The function is executed successfully. + * 3.The function is executed successfully. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_DEINIT_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherDeinit(NULL); +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_REINIT_API_TC001 + * @title CRYPT_EAL_CipherReinit Interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is not 0. Expected result 3 is obtained. + * 4.Call the Reinit interface, ctx is NULL, iv is not NULL, and ivLen is not 0. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is NULL, and ivLen is not 0. Expected result 5 is obtained. + * 6.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 0. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Failed. Return CRYPT_NULL_INPUT. + * 6.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_REINIT_API_TC001(Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_EAL_ERR_STATE); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherReinit(NULL, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherReinit(ctx, NULL, iv->len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, 0); + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_UPDATE_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherUpdate Interface + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface, ctx is NULL, in is not NULL, and in len is not 0, out is not NULL, and out len is not NULL. Expected result 3 is obtained. + * 4.Call the Update interface, ctx is not NULL, in is NULL, and in len is not 0, out is not NULL, and out len is not NULL. Expected result 4 is obtained. + * 5.Call the Update interface, ctx is not NULL, in is not NULL, and in len is 0, out is not NULL, and out len is not NULL. Expected result 5 is obtained. + * 6.Call the Update interface, ctx is not NULL, in is not NULL, and in len is not 0, out is NULL, and out len is not NULL. Expected result 6 is obtained. + * 7.Call the Update interface, ctx is not NULL, in is not NULL, and in len is not 0, out is not NULL, and out len is NULL. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_NULL_INPUT. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Failed. Return CRYPT_NULL_INPUT. + * 7.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_UPDATE_API_TC001(Hex *key, Hex *iv, Hex *in) +{ + TestMemInit(); + int32_t ret; + uint8_t out[AES_BLOCKSIZE] = {0}; + uint32_t len = AES_BLOCKSIZE; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(len == AES_BLOCKSIZE); + ret = CRYPT_EAL_CipherUpdate(NULL, in->x, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherUpdate(ctx, NULL, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, 0, out, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, NULL, &len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, out, NULL); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_FINAL_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherFinal Interface + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * 4.Call the Final interface, ctx is NULL, out is not NULL, and out len is not 0. Expected result 4 is obtained. + * 5.Call the Final interface, ctx is not NULL, out is NULL, and out len is not 0. Expected result 5 is obtained. + * 6.Call the Final interface, ctx is not NULL, out is not NULL, and out len is 0. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.The update is successful and return CRYPT_SUCCESS. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Failed. Return CRYPT_NULL_INPUT. + * 6.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_FINAL_API_TC001(Hex *key, Hex *iv, Hex *in) +{ + TestMemInit(); + int32_t ret; + uint8_t out[AES_BLOCKSIZE] = {0}; + uint32_t len = AES_BLOCKSIZE; + uint32_t finLen = AES_BLOCKSIZE; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherFinal(ctx, out, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherFinal(NULL, out, &finLen); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherFinal(ctx, NULL, &finLen); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherFinal(ctx, out, NULL); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CTRL_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherCtrl Interface + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and type is get iv, iv is not NULL, and iv len is not 0. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and type is get blocksize, data is not NULL, and len is not 0. Expected result 4 is obtained. + * 5.Call the Ctrl interface, ctx is not NULL, and type is get iv, iv is NULL, and iv len is not 0. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and type is get iv, iv is not NULL, and iv len is 0. Expected result 6 is obtained. + * 7.Call the Ctrl interface, ctx is not NULL, and type is get blocksize, data is not NULL, and len is 0. Expected result 7 is obtained. + * 8.Call the Ctrl interface, ctx is not NULL, and type is invalid. Expected result 8 is obtained. + * 9.Call the Ctrl interface, ctx is not NULL, and type is get blocksize, data is NULL, and len is not 0. Expected result 9 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Failed. Return CRYPT_NULL_INPUT. + * 6.Failed. Return CRYPT_MODE_ERR_INPUT_LEN. + * 7.Failed. Return CRYPT_MODE_ERR_INPUT_LEN. + * 8.Failed. Return CRYPT_MODES_METHODS_NOT_SUPPORT. + * 9.Failed. Return CRYPT_MODE_ERR_INPUT_LEN. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CTRL_API_TC001(int id, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + uint8_t *ivGet[AES_BLOCKSIZE] = {0}; + const uint32_t len = AES_BLOCKSIZE; + uint32_t blockSizeGet = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, ivGet, len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, (uint8_t *)&blockSizeGet, sizeof(uint32_t)); + if (id == CRYPT_CIPHER_AES128_CBC) { + ASSERT_TRUE(blockSizeGet == AES_BLOCKSIZE); + } else { + ASSERT_TRUE(blockSizeGet == 1); + } + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, NULL, len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, ivGet, 0); + ASSERT_TRUE(ret == CRYPT_MODE_ERR_INPUT_LEN); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, (uint8_t *)&blockSizeGet, 0); + ASSERT_TRUE(ret == CRYPT_MODE_ERR_INPUT_LEN); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_MAX, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_MODES_CTRL_TYPE_ERROR); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, NULL, sizeof(uint32_t)); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_SET_PADDING_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherSetPadding Interface + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the CRYPT_EAL_CipherSetPadding interface with ctx is NULL, and type set to a normal value. Expected result 3 is obtained. + * 4.Call the CRYPT_EAL_CipherSetPadding interface with ctx is not NULL, and type set to a invalid value. Expected result 4 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_NULL_INPUT. + * 4.Failed. Return CRYPT_MODES_METHODS_NOT_SUPPORT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_SET_PADDING_API_TC001(Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctxCBC = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + CRYPT_EAL_CipherCtx *ctxCCM = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CCM); + CRYPT_EAL_CipherCtx *ctxCTR = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CTR); + ASSERT_TRUE(ctxCBC != NULL); + ASSERT_TRUE(ctxCCM != NULL); + ASSERT_TRUE(ctxCTR != NULL); + ret = CRYPT_EAL_CipherInit(ctxCBC, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxCBC, CRYPT_PADDING_ZEROS); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(NULL, CRYPT_PADDING_ZEROS); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherSetPadding(ctxCBC, CRYPT_PADDING_MAX_COUNT); + ASSERT_TRUE(ret == CRYPT_EAL_PADDING_NOT_SUPPORT); + ret = CRYPT_EAL_CipherSetPadding(ctxCCM, CRYPT_PADDING_ZEROS); + ASSERT_TRUE(ret == CRYPT_EAL_PADDING_NOT_SUPPORT); + ret = CRYPT_EAL_CipherSetPadding(ctxCTR, CRYPT_PADDING_ZEROS); + ASSERT_TRUE(ret == CRYPT_EAL_PADDING_NOT_SUPPORT); + +exit: + CRYPT_EAL_CipherDeinit(ctxCBC); + CRYPT_EAL_CipherFreeCtx(ctxCBC); + CRYPT_EAL_CipherFreeCtx(ctxCCM); + CRYPT_EAL_CipherFreeCtx(ctxCTR); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_GET_PADDING_API_TC001 + * @title Impact of Input Parameters on the CRYPT_EAL_CipherGetPadding Interface + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the CRYPT_EAL_CipherGetPadding interface with ctx is NULL. Expected result 3 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_GET_PADDING_API_TC001(Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_ZEROS); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherGetPadding(ctx); + ASSERT_TRUE(ret == CRYPT_PADDING_ZEROS); + ret = CRYPT_EAL_CipherGetPadding(NULL); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001 + * @title Impact of multiple blocks on AES calculation_KAT, MMT Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the SetPadding interface to set the padding mode CRYPT_PADDING_NONE. Expected result 2 is obtained. + * 3.Call the Init interface. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The init is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. The calculation result is consistent with the vector value. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + if (IsAesAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - len; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + totalLen, &len); + totalLen += len; + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002 + * @title Multiple update_MCT tests + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the SetPadding interface to set the padding mode. Expected result 2 is obtained. + * 3.Call the Init interface. Expected result 3 is obtained. + * 4.Call the Update interface for multiple times. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The init is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. The calculation result is consistent with the vector value. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + if (IsAesAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + int32_t ret; + uint32_t len = AES_BLOCKSIZE; + uint8_t mctResult[MCT_INNER_LOOP][AES_BLOCKSIZE] = {0}; + uint8_t *inputTmp = in->x; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + for (uint32_t i = 0; i < MCT_INNER_LOOP; i++) { + ret = CRYPT_EAL_CipherUpdate(ctx, inputTmp, AES_BLOCKSIZE, mctResult[i], &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + if (i == 0) { + inputTmp = iv->x; + } else { + inputTmp = mctResult[i - 1]; + } + } + + ASSERT_TRUE(memcmp(mctResult[MCT_INNER_LOOP - 1], out->x, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003 + * @title After reinit, re-encrypt and decrypt data Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the SetPadding interface to set the padding mode. Expected result 2 is obtained. + * 3.Call the Init interface. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Call the Reinit interface. Expected result 6 is obtained. + * 7.Call the Update interface. Expected result 7 is obtained. + * 8.Call the Final interface. Expected result 8 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The init is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. The calculation result is consistent with the vector value. + * 6.The reinit is successful, return CRYPT_SUCCESS. + * 7.The update is successful, return CRYPT_SUCCESS. + * 8.The final is successful, return CRYPT_SUCCESS. The calculation result is consistent with the vector value. +@ */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t finLen; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + finLen = MAX_OUTPUT - len; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + len, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + + (void)memset_s(outTmp, MAX_OUTPUT, 0, MAX_OUTPUT); + len = MAX_OUTPUT; + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + finLen = MAX_OUTPUT - len; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + len, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_STATE_CHANGE_API_TC001 + * @title New, init, update, and final state transition Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx twice. Expected result 1 is obtained. + * 2.Call the Free interface twice. Expected result 2 is obtained. + * 3.Create the context ctx. Expected result 3 is obtained. + * 4.Call the Init interface twice. Expected result 4 is obtained. + * 5.Call the Update interface twice. Expected result 5 is obtained. + * 6.Call the Final interface twice. Expected result 6 is obtained. + * 7.Call the Update interface. Expected result 7 is obtained. + * 8.Call the Deinit interface twice and call Free interface. Expected result 8 is obtained. + * 9.Create the context ctx. Expected result 9 is obtained. + * 10.Call the Update interface. Expected result 10 is obtained. + * 11.Call the Free interface and create the context ctx. Expected result 11 is obtained. + * 12.Call the Final interface. Expected result 12 is obtained. + * 13.Call the Free interface and create the context ctx. Expected result 13 is obtained. + * 14.Call the Init interface. Expected result 14 is obtained. + * 15.Call the Update interface. Expected result 15 is obtained. + * 16.Call the Init interface. Expected result 16 is obtained. + * 17.Call the Free interface and create the context ctx. Expected result 17 is obtained. + * 18.Call the Reinit interface. Expected result 18 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The free function is successfully executed. + * 3.The creation is successful and the ctx is not empty. + * 4.The init is successful, return CRYPT_SUCCESS. + * 5.The update is successful, return CRYPT_SUCCESS. + * 6.The first final is successful, the second final is failed, return CRYPT_EAL_ERR_STATE. + * 7.Failed. return CRYPT_EAL_ERR_STATE. + * 8.The deinit adn free function is successfully executed. + * 9.The creation is successful and the ctx is not empty. + * 10.Failed. return CRYPT_EAL_ERR_STATE. + * 11.The creation is successful and the ctx is not empty. + * 12.Failed. return CRYPT_EAL_ERR_STATE. + * 13.The creation is successful and the ctx is not empty. + * 14.The init is successful, return CRYPT_SUCCESS. + * 15.The update is successful, return CRYPT_SUCCESS. + * 16.The init is successful, return CRYPT_SUCCESS. + * 17.The creation is successful and the ctx is not empty. + * 18.Failed. return CRYPT_EAL_ERR_STATE. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_STATE_CHANGE_API_TC001(Hex *key, Hex *iv, Hex *in, int enc) +{ + TestMemInit(); + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + + // multi new + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + CRYPT_EAL_CipherCtx *ctx1 = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(ctx1 != NULL); + CRYPT_EAL_CipherFreeCtx(ctx); + CRYPT_EAL_CipherFreeCtx(ctx1); + ctx = NULL; + ctx1 = NULL; + + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + // multi init + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc) == CRYPT_SUCCESS); + // multi update + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len) == CRYPT_SUCCESS); + // multi final + ASSERT_TRUE(CRYPT_EAL_CipherFinal(ctx, outTmp, &len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherFinal(ctx, outTmp, &len) == CRYPT_EAL_ERR_STATE); + // update after final + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len) == CRYPT_EAL_ERR_STATE); + // multi deinit + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); + + // update after new + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len) == CRYPT_EAL_ERR_STATE); + CRYPT_EAL_CipherFreeCtx(ctx); + + // final after new + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherFinal(ctx, outTmp, &len) == CRYPT_EAL_ERR_STATE); + CRYPT_EAL_CipherFreeCtx(ctx); + + // init after new + len = MAX_OUTPUT; + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len) == CRYPT_SUCCESS); + // init after update + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc) == CRYPT_SUCCESS); + CRYPT_EAL_CipherFreeCtx(ctx); + + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len) == CRYPT_EAL_ERR_STATE); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004 + * @title Encryption and decryption in different padding modes Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call SetPadding interface setting padding mode to CRYPT_PADDING_ISO7816, CRYPT_PADDING_ZEROS, + * CRYPT_PADDING_X923, CRYPT_PADDING_PKCS5, CRYPT_PADDING_PKCS7. Expected result 2 is obtained. + * 3.Call the Init interface. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Call the init, update, and final interfaces to decrypt and verifiy the result. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The init is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The verification is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004(int algId, Hex *key, Hex *iv, Hex *in, int padding) +{ + if (IsAesAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint8_t result[MAX_OUTPUT] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_OUTPUT; + uint32_t len = MAX_OUTPUT; + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen = leftLen - len; + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + len = MAX_OUTPUT; + leftLen = MAX_OUTPUT; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, totalLen, result, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + leftLen -= len; + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(in->x, result, in->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherDeinit(ctxDec); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005 + * @title Multiple update calculation encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Call the Init interface. Expected result 1 is obtained. + * 2.Call the update interface to update the first message. Expected result 2 is obtained. + * 3.Call the update interface to update the second message. Expected result 3 is obtained. + * 4.Call the update interface to update the third message. Expected result 4 is obtained. + * 5.Call the final interface. Expected result 5 is obtained. + * 6.Check whether the result is consistent with the test vector. Expected result 6 is obtained. + * @expect + * 1.The init is successful, return CRYPT_SUCCESS. + * 2.The update is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The verification is successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005(int algId, Hex *key, Hex *iv, Hex *in1, Hex *in2, Hex *in3, Hex *out, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ret = CRYPT_EAL_CipherUpdate(ctx, in1->x, in1->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherUpdate(ctx, in2->x, in2->len, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherUpdate(ctx, in3->x, in3->len, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006 + * @title Encryption and decryption for multiple updates in CFB mode + * @precon Registering memory-related functions. + * @brief + * 1.Call the Init interface. Expected result 1 is obtained. + * 2.Call the Ctrl interface to set feedback. + * 3.Call the Ctrl interface to get feedback. Expected result 2 is obtained. + * 4.Call the update interface to update the first message. Expected result 3 is obtained. + * 5.Call the update interface to update the second message. Expected result 4 is obtained. + * 6.Call the update interface to update the third message. Expected result 5 is obtained. + * 7.Call the final interface. Expected result 6 is obtained. + * 8.Check whether the result is consistent with the test vector. Expected result 7 is obtained. + * @expect + * 1.The init is successful, return CRYPT_SUCCESS. + * 2.The get is successful, and getting FeedBack is equal to setting. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The update is successful, return CRYPT_SUCCESS. + * 6.The final is successful, return CRYPT_SUCCESS. + * 7.The verification is successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006(int algId, int feed, Hex *key, Hex *iv, Hex *in1, Hex *in2, Hex *in3, Hex *out, int enc) +{ + if (IsAesAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + uint32_t feedBack = feed; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_FEEDBACKSIZE, (uint32_t *)&feedBack, sizeof(uint32_t)) == CRYPT_SUCCESS); + uint32_t tmpFeedBack = 0; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_FEEDBACKSIZE, (uint32_t *)&tmpFeedBack, sizeof(uint32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(tmpFeedBack == (uint32_t)feed); + ret = CRYPT_EAL_CipherUpdate(ctx, in1->x, in1->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherUpdate(ctx, in2->x, in2->len, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherUpdate(ctx, in3->x, in3->len, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007 + * @title The input and output use the same buffer Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The final is successful, return CRYPT_SUCCESS. The result is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + TestMemInit(); + int32_t ret; + uint32_t len = in->len; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, in->x, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen = totalLen + len; + len = in->len - totalLen; + ret = CRYPT_EAL_CipherFinal(ctx, in->x + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(in->x, out->x, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +typedef struct { + int algId; + uint8_t *key; + uint32_t keyLen; + uint8_t *iv; + uint32_t ivLen; + uint8_t *in; + uint32_t inLen; + uint8_t *out; + uint32_t outLen; + int enc; +} TestVector; + +void AES_MultiThreadTest(void *arg) +{ + TestVector *pTestVector = (TestVector *)arg; + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(pTestVector->algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, pTestVector->key, pTestVector->keyLen, pTestVector->iv, + pTestVector->ivLen, pTestVector->enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, pTestVector->in, pTestVector->inLen, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen = totalLen + len; + len = MAX_OUTPUT - totalLen; + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, pTestVector->out, pTestVector->outLen) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} + +/** + * @test SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001 + * @title Multi-thread Test + * @precon Registering memory-related functions. + * @brief + * 1.Create three threads for synchronous encryption and decryption. Expected result 1 is obtained. + * 2.Create the context ctx. Expected result 2 is obtained. + * 3.Call the Init interface. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Waiting for the thread to exit normally. Expected result 6 is obtained. + * @expect + * 1.The thread is created successfully. + * 2.The creation is successful and the ctx is not empty. + * 3.The init is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. The result is consistent with the test vector. + * 6.The thread exits successfully. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ +#define THREAD_NUM 3 + TestMemInit(); + int32_t ret; + pthread_t thrd[THREAD_NUM]; + TestVector testVt = {.algId = algId, + .key = key->x, + .keyLen = key->len, + .iv = iv->x, + .ivLen = iv->len, + .in = in->x, + .inLen = in->len, + .out = out->x, + .outLen = out->len, + .enc = enc}; + + for (uint32_t i = 0; i < THREAD_NUM; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)AES_MultiThreadTest, &testVt); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < THREAD_NUM; i++) { + pthread_join(thrd[i], NULL); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_OVERLAP_FUNC_TC001 + * @title The in and out memory partially overlaps during update + * @precon Registering memory-related functions. + * @brief + * 1.The in and out buff are partially overlaps. If out > in, Expected result 1 is obtained. + * 2.The in and out buff are partially overlaps. If in > out, Expected result 2 is obtained. + * @expect + * 1.Failed. Return RYPT_EAL_ERR_PART_OVERLAP + * 2.The operation is normal. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_OVERLAP_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + for (uint32_t i = 0; i <= in->len + EAL_MAX_BLOCK_LENGTH; i++) { + Test_CipherOverLap(algId, key, iv, in, out, enc, i, 0); + } + for (uint32_t i = 0; i < in->len + EAL_MAX_BLOCK_LENGTH + EAL_MAX_BLOCK_LENGTH; i++) { + Test_CipherOverLap(algId, key, iv, in, out, enc, 0, i); + } +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008 + * @title Encryption in different padding modes Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call SetPadding interface setting padding mode to CRYPT_PADDING_ISO7816, + * CRYPT_PADDING_X923, CRYPT_PADDING_PKCS7. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Call the init, update, and final interfaces to decrypt and verifiy the result. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The setting is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The verification is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int padding) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_OUTPUT; + uint32_t len = MAX_OUTPUT; + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen = leftLen - len; + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(memcmp(out->x, outTmp, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxEnc); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009 + * @title Decryption in different padding modes Test + * @precon Registering memory-related functions and report-log functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call SetPadding interface setting padding mode to CRYPT_PADDING_ISO7816, + * CRYPT_PADDING_X923, CRYPT_PADDING_PKCS7. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Call the init, update, and final interfaces to decrypt and verifiy the result. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The setting is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The verification is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int padding) +{ + TestMemInit(); + CRYPT_EAL_RegEventReport(reportLog); + int32_t ret; + uint8_t result[MAX_OUTPUT] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_OUTPUT; + uint32_t len = MAX_OUTPUT; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + len = MAX_OUTPUT; + leftLen = MAX_OUTPUT; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, in->x, in->len, result, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen = leftLen - len; + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + totalLen += leftLen; + + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(memcmp(out->x, result, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctxDec); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes.data b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes.data new file mode 100644 index 00000000..3dfde74a --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes.data @@ -0,0 +1,539 @@ +CRYPT_EAL_CipherNewCtx interface test +SDV_CRYPTO_AES_NEW_CTX_API_TC001: + +CRYPT_EAL_CipherInit interface test #from NIST +SDV_CRYPTO_AES_INIT_API_TC001:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8" + +CRYPT_EAL_CipherDeinit interface test +SDV_CRYPTO_AES_DEINIT_API_TC001: + +CRYPT_EAL_CipherReinit interface test #from NIST +SDV_CRYPTO_AES_REINIT_API_TC001:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8" + +CRYPT_EAL_CipherUpdate interface test #from NIST +SDV_CRYPTO_AES_UPDATE_API_TC001:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8":"45cf12964fc824ab76616ae2f4bf0822" + +CRYPT_EAL_CipherFinal interface test #from NIST +SDV_CRYPTO_AES_FINAL_API_TC001:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8":"45cf12964fc824ab76616ae2f4bf0822" + +CRYPT_EAL_CipherCtrl interface test #from NIST +SDV_CRYPTO_AES_CTRL_API_TC001:CRYPT_CIPHER_AES128_CBC:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8" + +CRYPT_EAL_CipherSetPadding interface test #from NIST +SDV_CRYPTO_AES_SET_PADDING_API_TC001:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8" + +CRYPT_EAL_CipherGetPadding interface test #from NIST +SDV_CRYPTO_AES_GET_PADDING_API_TC001:"1f8e4973953f3fb0bd6b16662e9a3c17":"2fe2b333ceda8f98f4a99b40d2cd34a8" + +AES-CBC KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"00000000000000000000000000000000":"00000000000000000000000000000000":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":true + +AES-CBC KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES192_CBC:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1b077a6af4b7f98229de786d7516b639":"275cfc0413d8ccb70513c3859b1d0f72":true + +AES-CBC KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"014730f80ac625fe84f026c60bfd547d":"5c9d844ed46f9885085e5d6a4f94c7d7":true + +AES-CBC KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"00000000000000000000000000000000":"00000000000000000000000000000000":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":false + +AES-CBC KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES192_CBC:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":false + +AES-CBC KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":false + +AES-CTR KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"874d6191b620e3261bef6864990db6ce":true + +AES-CTR KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"1abc932417521ca24f2b0459fe7e6e0b":true + +AES-CTR KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"601ec313775789a5b7a7f504bbf3d228":true + +AES-CTR KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"874d6191b620e3261bef6864990db6ce":"6bc1bee22e409f96e93d7e117393172a":false + +AES-CTR KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1abc932417521ca24f2b0459fe7e6e0b":"6bc1bee22e409f96e93d7e117393172a":false + +AES-CTR KAT test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"601ec313775789a5b7a7f504bbf3d228":"6bc1bee22e409f96e93d7e117393172a":false + +AES-CBC MMT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5e1847a6ad5d54127a399ab07ee3599":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded97818e1f127a28d72db5652749f0c6afee5":true + +AES-CBC MMT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"625eefa18a4756454e218d8bfed56e36":"73d9d0e27c2ec568fbc11f6a0998d7c8":"5d6fed86f0c4fe59a078d6361a142812514b295dc62ff5d608a42ea37614e6a1":"360dc1896ce601dfb2a949250067aad96737847a4580ede2654a329b842fe81e":false + +AES-CBC MMT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b9590178cbe69d7ad7919608cb03af13bbe04f3506b718a301ea0":"ed6a50e0c6921d52d6647f75d67b4fd56ace1fedb8b5a6a997b4d131640547d22c5d884a75e6752b5846b5b33a5181f4":true + +AES-CBC MMT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES192_CBC:"3915d786c786731cfe35abe39fac714f5fa32c7ef3c6681b":"a2d326a8226576e32e48f62b3da96c40":"a9968021d6df78ff2c4c236bdd9a55bc727b0dc506f44958b2041f0948860a3444588242ffbdcf2726001e2f6b5bd5fb":"4a7a4dca5c555d3f0358be7db4af14f1322a8861a3cb977f029fdcbd8ee4a8d451f32d7865e6a2376edf67e4d1092e15":false + +AES-CBC MMT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4567dd68e8ccd4c38ac563b13639c":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364c389fd639bdda647daa3bdadab2eb5594":true + +AES-CBC MMT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"7482c47004aef406115ca5fd499788d582efc0b29dc9e951b1f959406693a54f":"485ebf2215d20b816ea53944829717ce":"6c24f19b9c0b18d7126bf68090cb8ae72db3ca7eabb594f506aae7a2493e5326a5afae4ec4d109375b56e2b6ff4c9cf639e72c63dc8114c796df95b3c6b62021":"82fec664466d585023821c2e39a0c43345669a41244d05018a23d7159515f8ff4d88b01cd0eb83070d0077e065d74d7373816b61505718f8d4f270286a59d45e":false + +AES-CBC MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES128_CBC:"8809e7dd3a959ee5d8dbb13f501f2274":"e5c0bb535d7d54572ad06d170a0e58ae":"1fd4ee65603e6130cfc2a82ab3d56c24":"b127a5b4c4692d87483db0c3b0d11e64":true + +AES-CBC MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES128_CBC:"287b07c78f8e3e1be7c41b3d96c04e6e":"41b461f9464fd515d25413b4241002b8":"7c54923b0490a9d4de4ec1ce6790aa4d":"2805d10b127fcd1da528faad4eb2e10b":false + +AES-CBC MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES192_CBC:"dea64f83cfe6a0a183ddbe865cfca059b3c615c1623d63fc":"426fbc087b50b395c0fc81ef9fd6d1aa":"cd0b8c8a8179ecb171b64c894a4d60fd":"ae6302d22da9458117f5681431fc80df":true + +AES-CBC MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES192_CBC:"a24ebd4d7a080c28caae984b5098a9ea38cf7280e2c5f122":"c5aeb9b51ad5108371c59d0b90816310":"eb2c4e2712591ff13b8ac7870c9c404c":"886dc6ee8774e7a5b378ac8a2b637e50":false + +AES-CBC MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES256_CBC:"632bac4fe4db44cfcf18cfa90b43f86f378611b8d968595eb89e7ae98624564a":"ff8127621be616803e3f002377730185":"90ed17475f0a62bc381ba1f3ffbfff33":"4494030b1e828f57e349cbde6499abf3":true + +AES-CBC MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES256_CBC:"31397ad8cc79c519e0f46e0f70303587e38958d70723b771552336b7771f6311":"4139cb54eeac3fcf36ed72941122c40f":"27a1d5c10fe45b801d15f56e654a70f0":"f0e50e036baf80cef566d3f9eaa2a9a7":false + +AES-OFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES128_OFB:"89f6806368c130627a98bfb6bb5b1fd7":"b24d13affed86717df32a5b43fa9b859":"056f3063170450a5ac72c15caa54c690":"b0e7562dac92f90d5935c57baf336204":true + +AES-OFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES128_OFB:"6ec8f8db4b5eec1f64a799c1bb29b9aa":"b2321765f48eddc7f84b9423a540003c":"0dda834adaec203904d288f43263c4b7":"9c1037b77f32bd314929cea95a39bcdc":false + +AES-OFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES192_OFB:"3264e48dc08e22e3d83f664c3a81a7b9a46da5b70093c2f2":"cd5db293836a44f55647eb8844ccad8d":"be25385d443c3eab7c6f4fb4eac7a5db":"394655a878ac85fee108f3cb5cbb4350":true + +AES-OFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES192_OFB:"c79765ec6ed647aa5023c730e71cde2989d225534820e078":"4f032ffe0b2ae69847987b82cd7caa99":"9983ce048f19ef4043054c03aa010bee":"280dab0a264179ddc7a5564518ddf641":false + +AES-OFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES256_OFB:"b46129976d3fb9a83b10d3f6bb928a5b2e8fd00ec10fdf7513ccd83af1e6aaa1":"39c6a3ab26ae170921c503fc62ec0ba9":"7a644b53ef2cb607328c63dd61321515":"0e865252917d7a10547480988fe3f80e":true + +AES-OFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES256_OFB:"8eda005a16f5d0cc62727e92ded412e8e7d9e01f98000043e049fffcd83cd4b2":"57d404ae6da97c9ed315a13739954cf9":"53de1c313745ecf39963059435541fba":"e68ee3c8cabb00e41be436499ac47d5c":false + +AES-CFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES128_CFB:"3d2013d183970f00d3551281f2543fbd":"953eb9921a7ae4b9ec6d115eb720f7f0":"2590ad2e5455a6a5fe61a09ea4033c81":"72beed95ea2239d3d087cba751e3769e":true + +AES-CFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES128_CFB:"57c4964283ddaa25c2b2ba8b0aad92e3":"de5916c8a620a4b462ab01d9771fd613":"33d89bb0043e1f432e5c37e2d60e61e6":"59cdd6cdff128f0a8edca9c8b67abb3a":false + +AES-CFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES192_CFB:"178490e1450339b39fbfe93e780fa73344e5b3aa50aed221":"f36c375fbcd9d41a16698b03715ce889":"d6666b2bad548b51eebd0ed0a0595cba":"3bfa4b5759346aaae16ff6f8d2500027":true + +AES-CFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES192_CFB:"67c2eda508ad0513d736c8f4f9bea15260422bae9cdea4a0":"0f126257f517711445d665e121bc8a2e":"237b9d266edcf5eee7438721d137cf1d":"cf7b24a39dd5442e25b20f29e8a2ef8d":false + +AES-CFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES256_CFB:"3bfe82b841d969e462c9e0e95146d120d28ecfdac49b42f45e53c5abb900ccb2":"bea7ae84b0d16bd65e1fc05d74186601":"08cb9f7ebf92c4df696de5a2edb7c313":"61a721d192b0ad2ad2c33afe742fec48":true + +AES-CFB MCT #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_AES256_CFB:"37664842a5f64779a06bfb640ae88cdb6ea3e7634beab552b0648d34099a686e":"bb1802f8eac784ff66dbf2fbe63f5755":"b20d5526aa68bfb5d2afed5d80ef8aae":"3d273aa41e658d8ab5bc681d43b595c2":false + +AES128_CBC Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5e1847a6ad5d54127a399ab07ee3599":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded97818e1f127a28d72db5652749f0c6afee5":true + +AES128_CBC Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_CBC:"625eefa18a4756454e218d8bfed56e36":"73d9d0e27c2ec568fbc11f6a0998d7c8":"5d6fed86f0c4fe59a078d6361a142812514b295dc62ff5d608a42ea37614e6a1":"360dc1896ce601dfb2a949250067aad96737847a4580ede2654a329b842fe81e":false + +AES192_CBC Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_CBC:"ba75f4d1d9d7cf7f551445d56cc1a8ab2a078e15e049dc2c":"531ce78176401666aa30db94ec4a30eb":"c51fc276774dad94bcdc1d2891ec8668":"70dd95a14ee975e239df36ff4aee1d5d":true + +AES192_CBC Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_CBC:"8e2740fba157aef2422e442312d15c14d312553684fcdc15":"324015878cdc82bfae59a2dc1ff34ea6":"39a9b42de19e512ab7f3043564c3515a":"aa41179d880e6fe3b14818d6e4a62eb5":false + +AES256_CBC Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_CBC:"6ed76d2d97c69fd1339589523931f2a6cff554b15f738f21ec72dd97a7330907":"851e8764776e6796aab722dbb644ace8":"6282b8c05c5c1530b97d4816ca434762":"6acc04142e100a65f51b97adf5172c41":true + +AES256_CBC Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_CBC:"54682728db5035eb04b79645c64a95606abb6ba392b6633d79173c027c5acf77":"2eb94297772851963dd39a1eb95d438f":"e4046d05385ab789c6a72866e08350f93f583e2a005ca0faecc32b5cfc323d461c76c107307654db5566a5bd693e227c":"0faa5d01b9afad3bb519575daaf4c60a5ed4ca2ba20c625bc4f08799addcf89d19796d1eff0bd790c622dc22c1094ec7":false + +AES128_OFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_OFB:"cde9b69eea2b6a5588457e35e0a08803":"52323b54d69a62fec0689baee1b3ec63":"967798995af6f435b3a6f92bff77a11fa44d1426ae0f6e7dbafac27b123c5fc419be52c0ea412c4b3cac05ae89a4c0ce6f5e91a456b1bded5370a1234cf6f6ab5d0253507bc6f3f0573ab97585b67107dec059812323e021e341ad839ea9e3d02aeca43356add48ccef81f693ed53d32ba1c74a35e8a5f7f3115ef834f7daf9948244c4fc31f5487678d3e70fb27abb5":"6a5747276037643bbd0013c265d8d9a80b0299b283514d5256fecb5c787002a291a18a765fa046c3243418b02eebfc0c599576e52dd8c30291c97ceaa8bd2d7dbee3e66db7b585ea2b67f46f6711df28456b801556e233a96da1a8c34cd4d6154b20f43ae27b8ae83d907f9355c87aa021a280232265e99b4e189f4a3ccaa6b5e04153961e8e427a2dd53e5ec6f5112a":true + +AES128_OFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_OFB:"01963d44aea026b2205238454d5bb73f":"9442a6e0f3a53f10b0ccf5b0ccc1793a":"a1452e63a52fd294009482289812735166117f5427a6759154b8b4be5561f873f29673eb0a0b200987515499914196d9029eb0371af6065d75c9276b39eea283":"c54cfacd953736a2d8db0b8b63b555253a0ca6f6e05f2e918d18be95669fa85609f827d6da014add2964626670c202b195248fc986372c92adbb10c0e7c36e04":false + +AES192_OFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_OFB:"66c7d31359eac09056d597816542bffe4bb33e475dfb2d62":"426042dc81a7a069251972b91fb35058":"2f2178a285e61932c0b75d7be0a6e23afe78248330fc8bb3ad9ca9a73232bc2ba41d7bb5f6930f544d385fe362f0908228f2cc47b01f43304991705ceb769e7b":"863aa235c8ec3d7e8b24244f9eb797a610d0814cf15b2bdc2b17e90e02e15e2b4b73affc0d5983aa9e9b63fc5004629b1e337129cd3e4f3cc48b7f174544e30e":true + +AES192_OFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_OFB:"6c98ed90354af277df6c64d3f4f7af72d94317959bbf9f46":"e80bbd08f6ed38755132a0d0c58cb765":"564af9b8c99e33a668c10f86a89fd55327b423009a2c85bb06494573340685985ffa8a222f7e5bd4eb128bc2eafd53114a34e4fee57dfa2181d4b5f3470ea58f":"40aa6ef1f783d1187c1fe998c08373ca9b3021b112f03bff57179f10bbb987750c22b1ed65a18340033d35a7527200dc244ade241989eac950892897c77c7f5d":false + +AES256_OFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_OFB:"318aa7c73006ff95840f17f2b9cf01fe7f031105ff01daa66ff95834e47b6f5c":"0e28bd0603b31c26250345a118408ffc":"257f3fc84537158b68c8af111b1e9eb41f8841686ab1e94c6fd13a7f9f24d535309c340a1dd3d4966e439a41b9b97058e9072f613ef9c1ac958b872bea59f8831b578b63eec2d7155657f953f2c2375b":"ba4ebcdc894e6de54f8f1d7ccbb19e13d2ae0ca66c05c10e2f90bad2e9b8db94ee7770c3557927029d49fd2b3f80a01025af0e7a343237fb625dbdee85367ddfbd7f6664b511cdc7e832b2c4d91f1c0e":true + +AES256_OFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_OFB:"75be95a6a54400b2e1b485e24ead18ed20a6261fba82d397166486b268c4a7c7":"3b395ad3450c56c8f1accab2a47be11e":"52647fa67c0675753f725a8fd446622a2dff2841e61a46dc79792491b1090d4b61a2884a552ee56b890e16aa99b9c0e579a692e3666dd6941c29459a4a202009":"6892fc5c3d48f4e68a2c318f8157ee986fcf6c85a2ece70c0fdc709c504f0ab0b91606c4f13bc9bce5f1a1e0ce46960be86c35bc5982418097ba282d887608ea":false + +AES128_CFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_CFB:"b9ba9fa32cc491d8ac2beb5f99193d57":"95511452b71e53e93afad07ba1aa4d98":"b40382705aaeea41097c309da6cd06010f15e09c0130fa4b3af69cc8da109d1f0f0a2661f1a8b89bab7e7009dcbb8a883d46254a830c45cd87981e0ea4e490fa":"800bf8840a73c9279a9cdb61436f8af20ae17c5a9b95bf25e456f48cc3cc2f9dffd86c48645fa187cac5becd058e46554ae3b4825a1ef4467849c9d13536adfc":true + +AES128_CFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_CFB:"ff01aa4f7106c6bd24399076f901a530":"089b4f6054eeeef76d4e13f75de64f7e":"228377c8fae0edfae8cc43e5a07ceefa5d8f1b84d33842e5649efe2396831ca4c524f1361561f153ab1e7ea21de9fec026dd30419fc6c0f2aa86196131b77aa0":"ae9cb9dfa305af83e95a3b2099f70907edcd49fbc6efc5ebe744184c76b4f56bf35774f3fe215e1c8ee42172a2dd3e6f9ccd3d9bb044325e61a6bb97e48e9986":false + +AES192_CFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_CFB:"9b4c9e6410828173019caad0a2cd13dce21f318bf8b428c3":"10ba56e67d96a0b25b71ec7461bc3b3b":"5174f3f2eec0e7c894955401ac4b7fde3f5169690121f6088f734e53f5b1842373ac76eb818df44c100e24e313ea2466":"cd9967de6341671ddc172db19d0a1d432f57accfa6e931706f5f73caf78b4c8af0ad7ef9fe6a1e9b58b0fea85818b747":true + +AES192_CFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_CFB:"a2621ee7c5eedad2e331760e3c3e49e8fa63f7c009afe8b2":"2bebd19cfa12e025798209811dac8751":"efb41a379f1eaf41674fbb7fca14e7c4dd78270942e547b55a8bc71cb705e845d03a07f0f9822ad7920bd9357e7a2f85d7d5308cdfa05d993a46860c5bbbe015":"a070b01f48ad5e440017c94c77cb3af654aef9094bce94796c75c5d6f66d2172d7231cc92ca273381f3b15166b82ee6dba8810422f3cb5e3ceeb42f40ae25675":false + +AES256_CFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_CFB:"ae59254c66d8f533e7f5002ced480c33984a421d7816e27be66c34c19bfbc2a8":"821dd21653ece3af675cd25d26017ae3":"3cb4f17e775c2d6d06dd60f15d6c3a103e5131727f9c6cb80d13e00f316eb904":"ae375db9f28148c460f6c6b6665fcc2ff6b50b8eaf82c64bba8c649efd4731bc":true + +AES256_CFB Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_CFB:"9cc541d52c5dd9291a185eb952fb4f5474fc5f35e2c026e317a915553a10af5a":"ba61991716e0a2af80517bd728396d4b":"78fb1c2f440bd0a46e33a9658809f651860759582b30d53ac1f627910d5c5a1282589610b57b394111d328c5cc116864":"37b085dc650ed9110ab62c6d1394325a4d4ce583ba171c87fd09638fd933d356c96d3f392ff2174fb9aaa8083c05057c":false + +AES128_CTR Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"874d6191b620e3261bef6864990db6ce":true + +AES128_CTR Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"874d6191b620e3261bef6864990db6ce":"6bc1bee22e409f96e93d7e117393172a":false + +AES192_CTR Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"1abc932417521ca24f2b0459fe7e6e0b":true + +AES192_CTR Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1abc932417521ca24f2b0459fe7e6e0b":"6bc1bee22e409f96e93d7e117393172a":false + +AES256_CTR Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"601ec313775789a5b7a7f504bbf3d228":true + +AES256_CTR Reinit function test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"601ec313775789a5b7a7f504bbf3d228":"6bc1bee22e409f96e93d7e117393172a":false + +work state test #from NIST +SDV_CRYPTO_AES_STATE_CHANGE_API_TC001:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5e1847a6ad5d54127a399ab07ee3599":true + +AES128_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5e1847a6ad5d54127a399ab07ee3599":CRYPT_PADDING_NONE + +AES128_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_ZEROS + +AES128_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_ISO7816 + +AES128_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_X923 + +AES128_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_PKCS5 + +AES128_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_PKCS7 + +AES192_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b9590178cbe69d7ad7919608cb03af13bbe04f3506b718a301ea0":CRYPT_PADDING_NONE + +AES192_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_ZEROS + +AES192_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_ISO7816 + +AES192_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_X923 + +AES192_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_PKCS5 + +AES192_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_PKCS7 + +AES256_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4567dd68e8ccd4c38ac563b13639c":CRYPT_PADDING_NONE + +AES256_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_ZEROS + +AES256_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_ISO7816 + +AES256_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_X923 + +AES256_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_PKCS5 + +AES256_CBC padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_PKCS7 + +AES128-CBC multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES128_CBC:"2c14413751c31e2730570ba3361c786b":"1dbbeb2f19abb448af849796244a19d7":"40d930f9a05334d9816fe204999c3f82a03f6a0457a8c475c94553d1d116693adc618049f0a769a2eed6a6cb14c0143ec5cccdbc8dec4ce560cfd206225709":"326d4de7948e54d603d01b12d7fed752fb23f1aa4494fbb00130e9ded4e77e37":"c079042d828040c325b1a5efd15fc842e44014ca4374bf38f3c3fc3ee327733b0c8aee1abcd055772f18dc04603f7b2c1ea69ff662361f2be0a171bbdcea1e5d3f":"6be8a12800455a320538853e0cba31bd2d80ea0c85164a4c5c261ae485417d93effe2ebc0d0a0b51d6ea18633d210cf63c0c4ddbc27607f2e81ed9113191ef86d56f3b99be6c415a4150299fb846ce7160b40b63baf1179d19275a2e83698376d28b92548c68e06e6d994e2c1501ed297014e702cdefee2f656447706009614d801de1caaf73f8b7fa56cf1ba94b631933bbe577624380850f117435a0355b2b":true + +AES128-CBC multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES128_CBC:"97a1025529b9925e25bbe78770ca2f99":"d4b4eab92aa9637e87d366384ed6915c":"22cdc3306fcd4d31ccd32720cbb61bad28d855670657c48c7b88c31f4fa1f93c01b57da90be63ead67d6a325525e6ed45083e6fb70a53529d1fa0f55653b942af59d78a2660361d63a7290155ac5c43312a25b235dacbb":"c863faf00940c99624076dfa44068e7c554c9038176953e571":"751dfc0954d41d113771b06466b1c8d13e0d4cb675ed58d1a619e1540970983781dc11d2dd8525ab5745958d615defda":"e8b89150d8438bf5b17449d6ed26bd72127e10e4aa57cad85283e8359e089208e84921649f5b60ea21f7867cbc9620560c4c6238db021216db453c9943f1f1a60546173daef2557c3cdd855031b353d4bf176f28439e48785c37d38f270aa4a6faad2baabcb0c0b2d1dd5322937498ce803ba1148440a52e227ddba4872fe4d81d2d76a939d24755adb8a7b8452ceed2d179e1a5848f316f5c016300a390bfa7":false + +AES192-CBC multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES192_CBC:"162ad50ee64a0702aa551f571dedc16b2c1b6a1e4d4b5eee":"24408038161a2ccae07b029bb66355c1":"be8abf00901363987a82cc77d0ec91697ba3857f9e4f84bd79406c138d02698f003276d0449120bef4578d78":"fecabe8e070e11710b3f0a2744bd52434ec70015884c181ebdfd":"51c604a71c52e4c0e110bc408cd462b248a80b8a8ac06bb952ac1d7faed144807f1a731b7febcaf7835762defe92eccfc7a9944e1c702cffe6bc86733ed321423121085ac02df8962bcbc1937092eebf0e90a8b20e3dd8c244ae":"c82cf2c476dea8cb6a6e607a40d2f0391be82ea9ec84a537a6820f9afb997b76397d005424faa6a74dc4e8c7aa4a8900690f894b6d1dca80675393d2243adac762f159301e357e98b724762310cd5a7bafe1c2a030dba46fd93a9fdb89cc132ca9c17dc72031ec6822ee5a9d99dbca66c784c01b0885cbb62e29d97801927ec415a5d215158d325f9ee689437ad1b7684ad33c0d92739451ac87f39ff8c31b84":true + +AES192-CBC multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES192_CBC:"c6680fe9a1968f899479eca1092beaac18ad945a42ce8f93":"54130eea9e96a1199d3c090f690a479f":"8a21ea1381284bcdf818c2d4dfa976c13e5a3c253164ba1d30eccc27947c263457b43bff1c3d5e9c6fff27544d9419b0e7fc81d4a392a10e643e0eaf0bed571a3e3ee71a687e2d7900d7face0fc42a96ecc886864a":"60e9207536a285d9971a8ac427b70d6dd4ff8a340801e92b23f09ad62812e42fb6d87aed3b4f500664":"b7ac73d8708033251ef792fa054eab98b5e5":"c970a819cfb715f777e8b63167999ebe17c71ff505c3ff24cc6995430fad4013e1fc69ba5123072a7123e376d1f7de8cc610ada3fdd905a1476bc23724861e85dcf950db2b4982b60271752b49e438a20ef4e8e09cac0dc49ed15b84e32627e243814fee0430744ac675c7e5673d3f57a52360ec6ff8d18ed4b5bd8f1456c1f688825cb999789cad5e1b37a4b92ace3b":false + +AES256-CBC multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34":"c9bff096a94fedd6823526abc27a8e0b16":"616eee254ab4567dd68e8ccd4c38ac563b13639c":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364c389fd639bdda647daa3bdadab2eb5594":true + +AES256-CBC multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES256_CBC:"d30bfc0b2a19d5b8b6f8f46ab7f444ee136a7fa3fbdaf530cc3e8976339afcc4":"80be76a7f885d2c06b37d6a528fae0cd":"31e4677a17aed120bd3af69fbb0e4b645b9e8c104e280b799ddd49f1e241c3ccb7d40e1c6ff226bf04f8049c51a86e2981cf1331c824d7d451746ccf77fc22fd3717001ee51913":"d81f7a06fb0037f30995":"7579f695670f2c4c7397d2d990374e":"0b6e2a8213169b3b78db6de324e286f0366044e035c6970afbf0a1a5c32a05b24ba706cd9c6609737651a81b2bcf4c681dc0861983a5aec76e6c8b244112d64d489e84328974737394b83a39459011727162652b7aa793bfb1b71488b7dec96b":false + +AES128-CTR multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee2":"2e409f96e93d7e11":"7393172a":"874d6191b620e3261bef6864990db6ce":true + +AES128-CTR multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"874d6191b620e326":"1bef":"6864990db6ce":"6bc1bee22e409f96e93d7e117393172a":false + +AES192-CTR multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"ae2d8a571e03ac9c9eb76fac45af8e51":"30c81c46a35ce411e5fbc1191a0a52ef":"1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf7":true + +AES192-CTR multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1abc932417521ca24f2b0459fe7e6e0b":"090339ec0aa6faefd5ccc2c6f4ce8e94":"1e36b26bd1ebc670d1bd1d665620abf7":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52ef":false + +AES256-CTR multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e":"409f96e93d":"7e117393172a":"601ec313775789a5b7a7f504bbf3d228":true + +AES256-CTR multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"601ec3137757":"89a5b7a7f5":"04bbf3d228":"6bc1bee22e409f96e93d7e117393172a":false + +AES128-OFB multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES128_OFB:"939aac71e337709855715a57e3a4648f":"493509b56a92f14040eb9b66a188bc57":"9c22efddc7de496a916d15d710de374d57478126ed64c9ad7e823e24d19bfc0cfac3dda0d1c292a3a203f35b26ad94deb20f998caf41cb":"dd4a08eb5d6cfb46f4ede4896b0569d72c03ec1949":"41af95c0573cc3fe8f045ba19946b382803248f3dd4f9a454b1a3e8e1af02ea8482d637dac96a68275f4a382d3023f9df4892b9032cab9378b1cef5051d6db81226f259d1be4eb23495ac807600536b5b0481754":"7c0217d4f990342be5a35e2bdd4756ae7f461add633a7b0f5174ee107a7c0c53b1c787cb83e5ddb876e251a23caf7959d952638c2aa28b2b08928c9b88e4c0e0fd0d8154690c3638ce692f20905e7263ff359bcc17e3b43d2276ef1fc4c882282f9a453bc03eb29e9c95986318c19150acf1bf33270752d32488543f598f8ed4db3ccb990c8bfdf64cae0d1c6011042acda8c2687a758c2ba8080720990be88d":true + +AES128-OFB multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES128_OFB:"e30b4c874c4c4f6e0cf1f8ef58e5d375":"7e26f07f8024343cec35409e71e0cd8c":"5dcaa173ede14fd2d658973926168ff34fd6df9bce3280d40b00c43b80e2979a1e19045fec9afb4cf264516f55100855c3aad17b11bfcf0523b79eb20d65941077dd46ec46864e0d79704c2250e72bf8b448":"a6f0d3130ab10b423d1a09d9ff7a32bf700441ccd27d3223913860c28044ea5766e45a55b93f8948a959bd6661421566898e":"27950f04e726279bcbc990a22c80193ef0ae65196671eb59713240cf":"8ceca4dc346cfd6b15774e082db1a89497b7d85d6b5b7102e77417f7a243fafe17118b7a3bb49d1657cf61b866da395a5b3f349183a53dfa11fc0ac053bddff49dd472ee55f5e43a2f8bc785e2bc420300694919ff7bb43feb75a9cac44ece96f679e618db5d7433af12dcc7e0963ff10b45d835f9a8f42627e7f3fd5038932685965ad0e183f5955e671fc2b878dd51051eedaf85310d1e4e8f75f2decf36c7":false + +AES128-OFB multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES192_OFB:"17b0f9915f6b541e1d3fec5b9c5dfe1cb05a9dbc9983b20f":"eaf17cec9714d2e6f266f283618494eb":"0d4e7f3f732bf9d8d2d3f648968fe84175d1c7f5ac6d6be48c0539f336c501bfa3512730e7fc0151b63b815f27591420b86cc9759287b6330f31982f7a16b99816fd":"178a61fac2df99e58649800aca9e5d22b87243839eeb959394d1ca8260":"e56e399674698d042b84b94c2d290bd3636addda1346c7ebb527137702ae71bd4db3eced16881d8edd7e9f1d34abc3f718ea84798122bd6538cc9987e9af4b9979":"05f6ec0f2e2215cc4518750c4c6adb0b4e0b28b0889b33528cc3865a44d8f3680d838ff3da8d57d18df22187a716ad24630645732b7510aa77f5e3181f402b72df2543f825ff06ad5993324524a917093867ae5b59ae439697fd53fb9605eed3cc6b5c89fee0b6bdfe62e1444290f3dd71ff6aa1b60a8abdbc70b2ae3aee999739d7e6952a18fcf43151b65a5c9504fe3bf166917a264ab0c048cdfc40d4e0bf":true + +AES128-OFB multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES192_OFB:"753c1f7f39afd286ff051339c45d57c848850393b4112fe5":"d3ee0d8de5080eda4c26f5a3b9ca8a9f":"a91409fa694a4ad34a9cb1c1534a94979a5beb390083a6a61b4a4436746ba120f37a0f3e97caa9156a8ee410b53e670c703d1d19fcb8887f15d1580002fd3c5d0eaaf81c3c26b887":"37bca3f88820b4540b0dc5d6a42ced0e2e380c29b460a472e4eceb19c0241e3397":"6d170334b6227855120df65fa67e5a4fc68938f45b82665c8810bf8c8d832173eb68b821c95a7f35961b0394f0e36b61c4f7b529b77e42":"ad3ccda264343130bf1db3703e27127176fbaa7b6a5da2718783baf9f28fcdd3ed9cd31adcc79427fe4df03f1672a5e55cab0db0f4d434d860340d2fa05bfeb07e924157064a24d0f10e3293f78a2676e3c53734f22d4ea33e89384bd17f4a0f59354179ce48a7d1c1ba35e7f77735f58680f0e89bf9242a4f087322d99e507336a8e9037b6f1bfbe45614abeb2f71516b94caf618851ddcfac7429a2177be40":false + +AES128-OFB multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES256_OFB:"1d6fab8e8e49d623cfc8d105f04dcfab60175d7db4fd452ea463b34c56679615":"2aff323645f8aecf9204e7450952264f":"581d511bbd441d3531e77a910ad194f40d8a69b63cd6396cef7f37c5265485b21e725fca22c297eca4c341268c8aafd5d007a00e4589b43d":"b584230c3193af87a8b9d77db9ec4e29c6d4ab114ad0622f6c3af34f":"d4ec61b8bd02e60e4be2e5771f7a20fd2ac92b34bea1211cebab954808abcb40900528253081e8931d4b0fcbab3ea2121c611654b5b2090d1823306acde391ab22def2cb358791634fd515cc":"6ca579544f243cb2074feb19edc128faa33635d6eed0c850502669860d7ea66842298154ab455f79db45fd72e0ce88d49210226c489e9c15fe09216218707bcb96e1e59aa8d7fcd99728f71a478f9fedc109a111622a63b8e6e736207b37adbf0e6f4990ed76b42434473f90bb8c75ca7df47d72dab61fb0c67d265502217c4e590b3536d8d7c7a03a64735e87799423f40b123b8e431e3bba45bf193b6c4af0":true + +AES128-OFB multi update test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC005:CRYPT_CIPHER_AES256_OFB:"98a9971e86806ccc3495116fd06dc9d1522fe88060fdddc36e846fd329d24748":"9983ce048f19ef4043054c03aa010bee":"4b0767fec0d4bd07c79c0f5652dafadf10cfce89e3259dea94d39252c640840c28abcbe0efca53dc84b1ef5579f6ef":"28c213f445220b036fe351d93dcae57e654ac01d39f8721372":"3f0a462d5536b8336dab5c7d2fc728f865756b85f7526144190e0412c3142650616dbde7cde17e887a60ad39f2a1330d8209f13233ce5431fd5c297238f8b3ff53a3fb89c84168b04ffa8f7f53e14c36a2d3124d68a27fb5":"00caa233198f51bbf593404f59826997b4ea387385cf744c93cfa00e702e8f16ff5aa7e17a9a6020df0f0de4ea6abb38bcf1d777810a8318f69b5e8305f6d727f06f008b4bec2d65cd4c516ca49f62fb2f916f273c45bb722bec78c316f90b5ed5de6ef1d366603ced303c10e33dd5c99eb0f994db5a7867da9b530fc4d0b9ce224c6eab7810359c9733cf933c573611d31fcdf3f1db87cfd17be7f4a470a0b4":false + +AES128-CFB multi update test feedback 128 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES128_CFB:128:"7cb81fc4b203b0fa9bec49759bd515c2":"4d5e2fa3bf73f488b3e7e125f03dfbbe":"362789b376d85eb8181d4eeea52d42e873ce7741c11a2f820383a7457b15489b09fb21ac4445959dc9e851b7d40682c50d7044bda46a5da39fae2bab73b3db9ed22edc7ec5da93":"6dfa7451cb5f0a829ff0762738cc2686148f1e1f00dc3fe38139c9a173201fc1":"f052ca34736fc1ab3dc4e707f864d6119b7adb6c8ddd41c80de5d357d17e9c85ed7af1e4f72cb2656932ccce469202680109eef89a9f42f10a":"ac23259f68d4f82604cabd2e4237821c8b6c0aad0dfb1120b6b057223c994d62b5c6f63a25edbb797cd299f81ccb86d50134ad26107865142004c2d9d52fe3f91acf7b9b8111c8b4e14b05b173730e7b812036029846f1c1c6ffb30f6abcfc3e1ea631480e0d0bda106bb87319fdae09a11b89e8dde625d53a19c65ae58fbe3f4bcbc3c99af05cb0a7cc4b793d8cdb1cfa3173ede595c8c561f92c3fe3638b8d":true + +AES128-CFB multi update test feedback 128 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES128_CFB:128:"aef49da33f538ee66e178d4b6121055d":"842566e68b61ff7bf001f2642da62f64":"6625811419bdee71535f597f7c228bafd890fd69b805a699ed58116a82bdb251abea7a4ef879a96fce8ee49518b9877a3a1e3cf346d3cd73738936d1cb6fff4b2353c8ca500a26689813ad2f67774e2343f3e483":"0259094d3b342e00faabeba5b8a893108a390c649836ddd5d12489b2dd591ca25361032e2da1":"207f793a1e69513002a90ccc036bb63e9c10be87df2def960cd7a1b1621e311735d7aee4419f":"415991f65e1a95040cef9960556f61e617827c30c74bf353cdd86173dbe4cc983a2ee6bc8ca6cfb71121e7b0d0178f2e13445c710dcc176b781201971171f7489f18faf110f39accd1cf08c85a958d7698b116f1c0d75812ac9b0b39aee7f7159ccad8fdae9b99f2d695eacf12c6469d5b51a34de26eac73613dcb2f77122cb1f8dd5162786a12052dc7b6dea6acc4989dcc7eafd9374f6c29697c74749ef16d":false + +AES192-CFB multi update test feedback 128 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES192_CFB:128:"68bb0d29ce68ae8c0bb7ed8a285e391f3bee720039555838":"13c78c4bd70b595e7106492d654389c2":"49172017ac70ca3a1bd9b0644c7c66a795a710675e727719d7a35c49e6ce0ce264c134aa881ff70ca34a3e1a0e864fd2615ca2a0e63def":"254e688c37a20ef6297cb3ae4c76d746b5e3d6bb41bd0d05d7df3eeded74":"351f4eb0ac801abe6dc10ef9b635055ee1dfbf4144d0e24057b03e":"29a4dff0abebae9648e1f609e7d47005a0dfa9bda922082d38df365c48320db28f9b7b4b00e98adc82ced09223532d44c9e46317529602b2603e208d275547a85f5713a4f07d6ec31755eb71b5aabf3433901f73cbfea640c589875d2b93c32a412f05a853059ecee7166bc8a4932f96":true + +AES192-CFB multi update test feedback 128 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES192_CFB:128:"5cd37a0f9e38067f5d165ddd4e599387af5967cae6f60e9b":"79d74d29105a3080444de5f56d7b9e3e":"151e5ad05d9830b8a21130c2abc4ee3f53accf0cd5af716746174700634184538d993b3612c6c4aeae216107526c212423c10513c6c862e4db2d86bcc7519e25b740d8a8e2e4c49e0e780043553e14":"0c29759b3b9686a4b0c77e5702ccc0dcce9afc784f535b":"f92fc8fc559d3da48ea06cb1d8abcc50fe7112f002faf8f704f7":"e1f3aabbdd40d63ae1f4f2ac1abe9284ebcadfc0df1542d8ef5ba5010f89ab584c8f2c09e4f495e7f55e4085fa5fd43a279c11eb3fa4cccc84d45956a39b9ba9c5693cde86d8bc2b68278bd4afe9d4a57ff479639b8a92b4f2c5268950aeb4fe513397bd45a27bfba94bd26ede389850d5320db3472e3533ad5c134162c224d0":false + +AES256-CFB multi update test feedback 128 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES256_CFB:128:"d8feeb749dc688fb28008f11af560b5bcb4e81262b2938648a0cd8f0de5d371a":"327beda3900f6fa33d3c8ba572295ea5":"3398dc27b0ce77e120d97f8c1654333ce2a182f605881d71e820d11dcdf31465055dde316335bab0f2af1c54e381f51ec945851b091f702f8b9f1511b6e91b979c134c34":"71cea7bf4249b075e3520b422abf493c5a0c0270e24524e248":"268acf6082d135c1e16796796de4f8000f9e30":"3c912c51ecf32a3efda9f828e5445b4950ce099eca9feeaba4f48bba2dfea031786872054d4021a18330e95b54246228fbad1263581943e071006f799d25ba235a4f271bab056b6918e9e89950508e2c9a0197d71834d163f0dc8bdbf3bed5809e24ff1617a702ac40de9ec62541776e":true + +AES256-CFB multi update test feedback 128 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES256_CFB:128:"1154d523b8ad1b9ea21e837723b4b34cb31a7e384f6a63481c4356334e1cc445":"f46557dda8e63c34d01fbb79f9fb640d":"30cd5e5f6e7f4300df71db26dd6478305c4ec46f7ba2f88759d14e182a11b89e8a5dd29610bd15e3":"27c74e6f19664f156ddae5bf73000acb1dd45bb41034":"cceefbe79a1128dd813a51b830aeb48cfac169e3cef7f40569681776ca69eabfe6682d719e18dc68eecf044d672cd65edffc":"eff0ac9c78bcad5f2a288d0bedf5dbc7075f626b6d07bf04737723c5c5ec99acf650382cd4d8ed0337afa6d43a02ca5d66709630334a662ae6f794a1e1e62551a7234364cd9da2005513934ec5743e08fa9772ddc0f3f9451a3260d94a5e96b27adbfcf7a18ad98946f2f592639e8ccf":false + +AES128-CFB multi update test feedback 8 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES128_CFB:8:"3a6f9159263fa6cef2a075caface5817":"0fc23662b7dbf73827f0c7de321ca36e":"87efeb8d":"559ed33677":"28":"8e9c50425614d540ce11":true + +AES128-CFB multi update test feedback 8 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES128_CFB:8:"6399c1dc068ba3509845628fa9ed1a96":"1157c2766c86b754df485be9dd5851df":"c9c284":"e9ab":"bfe6fb11fe":"feff4e2e2458addf2a54":false + +AES192-CFB multi update test feedback 8 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES192_CFB:8:"537e7bf661fd4024a024613f15b13690f7d0c847c1e18965":"3a81f9d9d3c155b0caad5d73349476fc":"d3d8b9":"b984":"adc24237ee":"3879fea72ac99929e53a":true + +AES192-CFB multi update test feedback 8 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES192_CFB:8:"baf08b76317a65c5f07ae6f57eb0e65488659324d29709e3":"0a02846b62abb693ef31d754842eed29":"729c0b6d":"eb":"75fa6eb5e8":"9895932402393dc33a60":false + +AES256-CFB multi update test feedback 8 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES256_CFB:8:"ebbb4566b5e182e0f072466b0b311df38f9175bc0213a5530bce2ec4d74f400d":"0956a48e01002c9e16376d6e308dbad1":"b0fe":"25":"ac8d3d28a2f471":"638c6823e7256fb5626e":true + +AES256-CFB multi update test feedback 8 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES256_CFB:8:"ec13062551e4d7291e320f565b749eea1809b663b26f2c4d53b52058b833e0ad":"fbfa5a528e20863012790c2abafb5a0c":"2bfc":"3f020930":"7140101a":"547bfd642cf6e12ed942":false + +AES128-CFB multi update test feedback 1 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES128_CFB:1:"68dedc2e02194fb0349db1fa43ec9232":"56399132416f426516e833bfc7d79b25":"1100":"00":"0011":"d41c08c958":true + +AES128-CFB multi update test feedback 1 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES128_CFB:1:"68dedc2e02194fb0349db1fa43ec9232":"56399132416f426516e833bfc7d79b25":"d41c":"08":"c958":"1100000011":false + +AES192-CFB multi update test feedback 1 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES192_CFB:1:"7cb626aa159f92325a77525aeaf494aafa07d6b79a0e4bf7":"0614379debaae28e84e46f7e2fb0da0a":"1011":"11":"0011":"011f048bda":true + +AES192-CFB multi update test feedback 1 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES192_CFB:1:"7cb626aa159f92325a77525aeaf494aafa07d6b79a0e4bf7":"0614379debaae28e84e46f7e2fb0da0a":"011f":"04":"8bda":"1011110011":false + +AES256-CFB multi update test feedback 1 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES256_CFB:1:"f6fae4f15d91fc5088784f84a537127e3263559c62738820c2cf3de11c2a3040":"632e9f831fa3805e5202bce06d04f9a0":"0100":"00":"0111":"8c65c606cf":true + +AES256-CFB multi update test feedback 1 #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_AES256_CFB:1:"f6fae4f15d91fc5088784f84a537127e3263559c62738820c2cf3de11c2a3040":"632e9f831fa3805e5202bce06d04f9a0":"8c65":"c6":"06cf":"0100000111":false + +AES256-CBC output and input at same address test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_AES256_CBC:"dce26c6b4cfb286510da4eecd2cffe6cdf430f33db9b5f77b460679bd49d13ae":"fdeaa134c8d7379d457175fd1a57d3fc":"50e9eee1ac528009e8cbcd356975881f957254b13f91d7c6662d10312052eb00":"2fa0df722a9fd3b64cb18fb2b3db55ff2267422757289413f8f657507412a64c":true + +AES256-CBC output and input at same address test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_AES256_CBC:"addf88c1ab997eb58c0455288c3a4fa320ada8c18a69cc90aa99c73b174dfde6":"60cc50e0887532e0d4f3d2f20c3c5d58":"6cb4e2f4ddf79a8e08c96c7f4040e8a83266c07fc88dd0074ee25b00d445985a":"98a8a9d84356bf403a9ccc384a06fe043dfeecb89e59ce0cb8bd0a495ef76cf0":false + +AES256-CTR output and input at same address test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"601ec313775789a5b7a7f504bbf3d228":true + +AES256-CTR output and input at same address test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"601ec313775789a5b7a7f504bbf3d228":"6bc1bee22e409f96e93d7e117393172a":false + +AES256_OFB output and input at same address test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_AES256_OFB:"318aa7c73006ff95840f17f2b9cf01fe7f031105ff01daa66ff95834e47b6f5c":"0e28bd0603b31c26250345a118408ffc":"257f3fc84537158b68c8af111b1e9eb41f8841686ab1e94c6fd13a7f9f24d535309c340a1dd3d4966e439a41b9b97058e9072f613ef9c1ac958b872bea59f8831b578b63eec2d7155657f953f2c2375b":"ba4ebcdc894e6de54f8f1d7ccbb19e13d2ae0ca66c05c10e2f90bad2e9b8db94ee7770c3557927029d49fd2b3f80a01025af0e7a343237fb625dbdee85367ddfbd7f6664b511cdc7e832b2c4d91f1c0e":true + +AES256_OFB output and input at same address test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_AES256_OFB:"75be95a6a54400b2e1b485e24ead18ed20a6261fba82d397166486b268c4a7c7":"3b395ad3450c56c8f1accab2a47be11e":"52647fa67c0675753f725a8fd446622a2dff2841e61a46dc79792491b1090d4b61a2884a552ee56b890e16aa99b9c0e579a692e3666dd6941c29459a4a202009":"6892fc5c3d48f4e68a2c318f8157ee986fcf6c85a2ece70c0fdc709c504f0ab0b91606c4f13bc9bce5f1a1e0ce46960be86c35bc5982418097ba282d887608ea":false + +AES128_CBC multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5e1847a6ad5d54127a399ab07ee3599":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded97818e1f127a28d72db5652749f0c6afee5":true + +AES128_CBC multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"625eefa18a4756454e218d8bfed56e36":"73d9d0e27c2ec568fbc11f6a0998d7c8":"5d6fed86f0c4fe59a078d6361a142812514b295dc62ff5d608a42ea37614e6a1":"360dc1896ce601dfb2a949250067aad96737847a4580ede2654a329b842fe81e":false + +AES192_CBC multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CBC:"ba75f4d1d9d7cf7f551445d56cc1a8ab2a078e15e049dc2c":"531ce78176401666aa30db94ec4a30eb":"c51fc276774dad94bcdc1d2891ec8668":"70dd95a14ee975e239df36ff4aee1d5d":true + +AES192_CBC multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CBC:"8e2740fba157aef2422e442312d15c14d312553684fcdc15":"324015878cdc82bfae59a2dc1ff34ea6":"39a9b42de19e512ab7f3043564c3515a":"aa41179d880e6fe3b14818d6e4a62eb5":false + +AES256-CBC multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"dce26c6b4cfb286510da4eecd2cffe6cdf430f33db9b5f77b460679bd49d13ae":"fdeaa134c8d7379d457175fd1a57d3fc":"50e9eee1ac528009e8cbcd356975881f957254b13f91d7c6662d10312052eb00":"2fa0df722a9fd3b64cb18fb2b3db55ff2267422757289413f8f657507412a64c":true + +AES256-CBC multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"addf88c1ab997eb58c0455288c3a4fa320ada8c18a69cc90aa99c73b174dfde6":"60cc50e0887532e0d4f3d2f20c3c5d58":"6cb4e2f4ddf79a8e08c96c7f4040e8a83266c07fc88dd0074ee25b00d445985a":"98a8a9d84356bf403a9ccc384a06fe043dfeecb89e59ce0cb8bd0a495ef76cf0":false + +AES128_CTR multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"874d6191b620e3261bef6864990db6ce":true + +AES128_CTR multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"874d6191b620e3261bef6864990db6ce":"6bc1bee22e409f96e93d7e117393172a":false + +AES192_CTR multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"1abc932417521ca24f2b0459fe7e6e0b":true + +AES192_CTR multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1abc932417521ca24f2b0459fe7e6e0b":"6bc1bee22e409f96e93d7e117393172a":false + +AES256-CTR multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"601ec313775789a5b7a7f504bbf3d228":true + +AES256-CTR multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"601ec313775789a5b7a7f504bbf3d228":"6bc1bee22e409f96e93d7e117393172a":false + +AES128_OFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_OFB:"cde9b69eea2b6a5588457e35e0a08803":"52323b54d69a62fec0689baee1b3ec63":"967798995af6f435b3a6f92bff77a11fa44d1426ae0f6e7dbafac27b123c5fc419be52c0ea412c4b3cac05ae89a4c0ce6f5e91a456b1bded5370a1234cf6f6ab5d0253507bc6f3f0573ab97585b67107dec059812323e021e341ad839ea9e3d02aeca43356add48ccef81f693ed53d32ba1c74a35e8a5f7f3115ef834f7daf9948244c4fc31f5487678d3e70fb27abb5":"6a5747276037643bbd0013c265d8d9a80b0299b283514d5256fecb5c787002a291a18a765fa046c3243418b02eebfc0c599576e52dd8c30291c97ceaa8bd2d7dbee3e66db7b585ea2b67f46f6711df28456b801556e233a96da1a8c34cd4d6154b20f43ae27b8ae83d907f9355c87aa021a280232265e99b4e189f4a3ccaa6b5e04153961e8e427a2dd53e5ec6f5112a":true + +AES128_OFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_OFB:"01963d44aea026b2205238454d5bb73f":"9442a6e0f3a53f10b0ccf5b0ccc1793a":"a1452e63a52fd294009482289812735166117f5427a6759154b8b4be5561f873f29673eb0a0b200987515499914196d9029eb0371af6065d75c9276b39eea283":"c54cfacd953736a2d8db0b8b63b555253a0ca6f6e05f2e918d18be95669fa85609f827d6da014add2964626670c202b195248fc986372c92adbb10c0e7c36e04":false + +AES192_OFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_OFB:"66c7d31359eac09056d597816542bffe4bb33e475dfb2d62":"426042dc81a7a069251972b91fb35058":"2f2178a285e61932c0b75d7be0a6e23afe78248330fc8bb3ad9ca9a73232bc2ba41d7bb5f6930f544d385fe362f0908228f2cc47b01f43304991705ceb769e7b":"863aa235c8ec3d7e8b24244f9eb797a610d0814cf15b2bdc2b17e90e02e15e2b4b73affc0d5983aa9e9b63fc5004629b1e337129cd3e4f3cc48b7f174544e30e":true + +AES192_OFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_OFB:"6c98ed90354af277df6c64d3f4f7af72d94317959bbf9f46":"e80bbd08f6ed38755132a0d0c58cb765":"564af9b8c99e33a668c10f86a89fd55327b423009a2c85bb06494573340685985ffa8a222f7e5bd4eb128bc2eafd53114a34e4fee57dfa2181d4b5f3470ea58f":"40aa6ef1f783d1187c1fe998c08373ca9b3021b112f03bff57179f10bbb987750c22b1ed65a18340033d35a7527200dc244ade241989eac950892897c77c7f5d":false + +AES256-OFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_OFB:"7c4424cf1ac4d75aceebdb2238a9f0383438f453afa55772b98ccfc3dc234dc4":"34838273c7848b70c6e1abad79ce1325":"cb9ac89b78902ce09d8467291181a702fd9a0430e2dca944de8135702b66619ae8c0e2af1c0a913af842c9355c54101e9dd7fa4e86f74b879cb25ccca648c075":"5df03b8d91cb0e5da86ba108ead87ec762c90767ace96be60598b4efe8f3d3f8383827a599180ffdddb3e94151e22feeda3c90651a697f3834e036e44d0506b2":true + +AES256-OFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_OFB:"75be95a6a54400b2e1b485e24ead18ed20a6261fba82d397166486b268c4a7c7":"3b395ad3450c56c8f1accab2a47be11e":"52647fa67c0675753f725a8fd446622a2dff2841e61a46dc79792491b1090d4b61a2884a552ee56b890e16aa99b9c0e579a692e3666dd6941c29459a4a202009":"6892fc5c3d48f4e68a2c318f8157ee986fcf6c85a2ece70c0fdc709c504f0ab0b91606c4f13bc9bce5f1a1e0ce46960be86c35bc5982418097ba282d887608ea":false + +AES128_CFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CFB:"b9ba9fa32cc491d8ac2beb5f99193d57":"95511452b71e53e93afad07ba1aa4d98":"b40382705aaeea41097c309da6cd06010f15e09c0130fa4b3af69cc8da109d1f0f0a2661f1a8b89bab7e7009dcbb8a883d46254a830c45cd87981e0ea4e490fa":"800bf8840a73c9279a9cdb61436f8af20ae17c5a9b95bf25e456f48cc3cc2f9dffd86c48645fa187cac5becd058e46554ae3b4825a1ef4467849c9d13536adfc":true + +AES128_CFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CFB:"ff01aa4f7106c6bd24399076f901a530":"089b4f6054eeeef76d4e13f75de64f7e":"228377c8fae0edfae8cc43e5a07ceefa5d8f1b84d33842e5649efe2396831ca4c524f1361561f153ab1e7ea21de9fec026dd30419fc6c0f2aa86196131b77aa0":"ae9cb9dfa305af83e95a3b2099f70907edcd49fbc6efc5ebe744184c76b4f56bf35774f3fe215e1c8ee42172a2dd3e6f9ccd3d9bb044325e61a6bb97e48e9986":false + +AES192_CFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CFB:"9b4c9e6410828173019caad0a2cd13dce21f318bf8b428c3":"10ba56e67d96a0b25b71ec7461bc3b3b":"5174f3f2eec0e7c894955401ac4b7fde3f5169690121f6088f734e53f5b1842373ac76eb818df44c100e24e313ea2466":"cd9967de6341671ddc172db19d0a1d432f57accfa6e931706f5f73caf78b4c8af0ad7ef9fe6a1e9b58b0fea85818b747":true + +AES192_CFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CFB:"a2621ee7c5eedad2e331760e3c3e49e8fa63f7c009afe8b2":"2bebd19cfa12e025798209811dac8751":"efb41a379f1eaf41674fbb7fca14e7c4dd78270942e547b55a8bc71cb705e845d03a07f0f9822ad7920bd9357e7a2f85d7d5308cdfa05d993a46860c5bbbe015":"a070b01f48ad5e440017c94c77cb3af654aef9094bce94796c75c5d6f66d2172d7231cc92ca273381f3b15166b82ee6dba8810422f3cb5e3ceeb42f40ae25675":false + +AES256-CFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CFB:"151a6d82846dd562dfb14d7096236cf5a36b8bf4c9cd2a0319a3905abb0bb22a":"d1481313203fbda4fe35700b84a93e62":"bacfb585c07fa2098e3e23826e01f31107a208202f710eff00eb13cf2ec984a0973d58d61c788bd1b06fcecdaedf7d06708ed1201dd557c7c25ba093a5233a2e":"eb3f304da9aadbea00b40072f0c3afda70e2fe45c2387dd03f7919ad2731efbd9ca81dcaa8e13ce15acefecae6d680ac47d7419f3740db68a8e67ce121d366fb":true + +AES256-CFB multi thread test #from NIST +SDV_CRYPTO_AES_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CFB:"764b93d185178639cef303ca426490c4b046a78a80b309a5a326560ccae0dba2":"557d3d096f0a461de7cace679b314b1a":"34e31cce15de96667b603a3cf15499b124475adaa21e24d6e204be5f85a7749edba4bd44a93f1cd629584448539b7fce5bf650ef7b5057dbf27876fe4d5b32d5":"b39b2a4a580168582b4e2f6afbd334d55235b611bf2178e00a6ca4536647a602243c51f410191d6b81606f90a0826e514ba1d3adbd12d1fd80f38405dcabe3c6":false + +AES-CTR KAT test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"874d6191b620e3261bef6864990db6ce":true + +AES-CTR KAT test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES128_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"874d6191b620e3261bef6864990db6ce":"6bc1bee22e409f96e93d7e117393172a":false + +AES-CTR KAT test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"1abc932417521ca24f2b0459fe7e6e0b":true + +AES-CTR KAT test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES192_CTR:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"1abc932417521ca24f2b0459fe7e6e0b":"6bc1bee22e409f96e93d7e117393172a":false + +AES-CTR KAT test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172a":"601ec313775789a5b7a7f504bbf3d228":true + +AES-CTR KAT test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES256_CTR:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"601ec313775789a5b7a7f504bbf3d228":"6bc1bee22e409f96e93d7e117393172a":false + +CBC_AES128 test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES128_CBC:"97a1025529b9925e25bbe78770ca2f99":"d4b4eab92aa9637e87d366384ed6915c":"e8b89150d8438bf5b17449d6ed26bd72127e10e4aa57cad85283e8359e089208e84921649f5b60ea21f7867cbc9620560c4c6238db021216db453c9943f1f1a60546173daef2557c3cdd855031b353d4bf176f28439e48785c37d38f270aa4a6faad2baabcb0c0b2d1dd5322937498ce803ba1148440a52e227ddba4872fe4d81d2d76a939d24755adb8a7b8452ceed2d179e1a5848f316f5c016300a390bfa7":"22cdc3306fcd4d31ccd32720cbb61bad28d855670657c48c7b88c31f4fa1f93c01b57da90be63ead67d6a325525e6ed45083e6fb70a53529d1fa0f55653b942af59d78a2660361d63a7290155ac5c43312a25b235dacbbc863faf00940c99624076dfa44068e7c554c9038176953e571751dfc0954d41d113771b06466b1c8d13e0d4cb675ed58d1a619e1540970983781dc11d2dd8525ab5745958d615defda":true + +CBC_AES256 test OVERLAPPING #from NIST +SDV_CRYPTO_AES_OVERLAP_FUNC_TC001:CRYPT_CIPHER_AES256_CBC:"87725bd43a45608814180773f0e7ab95a3c859d83a2130e884190e44d14c6996":"e49651988ebbb72eb8bb80bb9abbca34":"bfe5c6354b7a3ff3e192e05775b9b75807de12e38a626b8bf0e12d5fff78e4f1775aa7d792d885162e66d88930f9c3b2cdf8654f56972504803190386270f0aa43645db187af41fcea639b1f8026ccdd0c23e0de37094a8b941ecb7602998a4b2604e69fc04219585d854600e0ad6f99a53b2504043c08b1c3e214d17cde053cbdf91daa999ed5b47c37983ba3ee254bc5c793837daaa8c85cfc12f7f54f699f":"5b97a9d423f4b97413f388d9a341e727bb339f8e18a3fac2f2fb85abdc8f135deb30054a1afdc9b6ed7da16c55eba6b0d4d10c74e1d9a7cf8edfaeaa684ac0bd9f9d24ba674955c79dc6be32aee1c260b558ff07e3a4d49d24162011ff254db8be078e8ad07e648e6bf5679376cb4321a5ef01afe6ad8816fcc7634669c8c4389295c9241e45fff39f3225f7745032daeebe99d4b19bcb215d1bfdb36eda2c24":true + +AES128_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded978cb9f327a0aa53fd532eb1be6d2ae8fd3":CRYPT_PADDING_ISO7816 + +AES128_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded9786d1816f7c5649d5937876ba0ef567a5d":CRYPT_PADDING_X923 + +AES128_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded9780568af8935f1f764ed78e90f71189e4b":CRYPT_PADDING_PKCS7 + +AES192_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":"ed6a50e0c6921d52d6647f75d67b4fd5bc347477b3e501d4dadcdee7980a29c2":CRYPT_PADDING_ISO7816 + +AES192_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":"ed6a50e0c6921d52d6647f75d67b4fd59371dfd343de75b79660c1f75c188ce9":CRYPT_PADDING_X923 + +AES192_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":"ed6a50e0c6921d52d6647f75d67b4fd5cf4d9d94bcbd8b5915af4751d816d5aa":CRYPT_PADDING_PKCS7 + +AES256_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364cb1cd108e438552872a0ac79df78f4e3b":CRYPT_PADDING_ISO7816 + +AES256_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364ce30c66a3ab285c6b09641f3afc57d81f":CRYPT_PADDING_X923 + +AES256_CBC encrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364c9696766e185b4fe717da75c7b1f88312":CRYPT_PADDING_PKCS7 + +AES128_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded978cb9f327a0aa53fd532eb1be6d2ae8fd3":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_ISO7816 + +AES128_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded9786d1816f7c5649d5937876ba0ef567a5d":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_X923 + +AES128_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES128_CBC:"3348aa51e9a45c2dbe33ccc47f96e8de":"19153c673160df2b1d38c28060e59b96":"d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded9780568af8935f1f764ed78e90f71189e4b":"9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5":CRYPT_PADDING_PKCS7 + +AES192_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"ed6a50e0c6921d52d6647f75d67b4fd5bc347477b3e501d4dadcdee7980a29c2":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_ISO7816 + +AES192_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"ed6a50e0c6921d52d6647f75d67b4fd59371dfd343de75b79660c1f75c188ce9":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_X923 + +AES192_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES192_CBC:"16c93bb398f1fc0cf6d68fc7a5673cdf431fa147852b4a2d":"eaaeca2e07ddedf562f94df63f0a650f":"ed6a50e0c6921d52d6647f75d67b4fd5cf4d9d94bcbd8b5915af4751d816d5aa":"c5ce958613bf741718c17444484ebaf1050ddcacb59b959017":CRYPT_PADDING_PKCS7 + +AES256_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364cb1cd108e438552872a0ac79df78f4e3b":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_ISO7816 + +AES256_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364ce30c66a3ab285c6b09641f3afc57d81f":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_X923 + +AES256_CBC decrypy padding mode test #from NIST +SDV_CRYPTO_AES_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_AES256_CBC:"0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5":"c0cd2bebccbb6c49920bd5482ac756e8":"05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364c9696766e185b4fe717da75c7b1f88312":"8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4":CRYPT_PADDING_PKCS7 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_ccm.c b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_ccm.c new file mode 100644 index 00000000..0ae593e7 --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_ccm.c @@ -0,0 +1,851 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "hitls_build.h" +#include "crypt_errno.h" +#include "crypt_eal_cipher.h" +#include "bsl_sal.h" +#include "securec.h" + +typedef struct { + uint8_t *key; + uint8_t *iv; + uint8_t *aad; + uint8_t *pt; + uint8_t *ct; + uint8_t *tag; + uint32_t keyLen; + uint32_t ivLen; + uint32_t aadLen; + uint32_t ptLen; + uint32_t ctLen; + uint32_t tagLen; + int algId; +} ThreadParameter; + +void MultiThreadTest(void *arg) +{ + ThreadParameter *threadParameter = (ThreadParameter *)arg; + uint32_t outLen = threadParameter->ctLen; + uint64_t msgLen = threadParameter->ctLen; + uint32_t tagLen = threadParameter->tagLen; + uint8_t out[threadParameter->ctLen]; + uint8_t tag[threadParameter->tagLen]; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(threadParameter->algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, threadParameter->key, threadParameter->keyLen, threadParameter->iv, + threadParameter->ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &msgLen, sizeof(msgLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, threadParameter->aad, threadParameter->aadLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, threadParameter->pt, threadParameter->ptLen, (uint8_t *)out, &outLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Ct", out, threadParameter->ctLen, threadParameter->ct, threadParameter->ctLen); + ASSERT_COMPARE("Compare Enc Tag", tag, tagLen, threadParameter->tag, threadParameter->tagLen); + + CRYPT_EAL_CipherDeinit(ctx); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, threadParameter->key, threadParameter->keyLen, threadParameter->iv, + threadParameter->ivLen, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &msgLen, sizeof(msgLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, threadParameter->aad, threadParameter->aadLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, threadParameter->ct, threadParameter->ctLen, (uint8_t *)out, &outLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Pt", out, threadParameter->ptLen, threadParameter->pt, threadParameter->ptLen); + ASSERT_COMPARE("Compare Dec Tag", tag, tagLen, threadParameter->tag, threadParameter->tagLen); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} + +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_AES_CCM_REINIT_API_TC001 + * @title CRYPT_EAL_CipherReinit different iv length Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 6. Expected result 3 is obtained. + * 4.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 7. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 13. Expected result 5 is obtained. + * 6.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 14. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Failed. Return CRYPT_MODES_IVLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_REINIT_API_TC001(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[14] = { 0 }; + uint32_t ivLen = 0; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ivLen = 13; + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, (uint8_t *)iv, ivLen, true) == CRYPT_SUCCESS); + ivLen = 6; + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, ivLen) == CRYPT_MODES_IVLEN_ERROR); + ivLen = 7; + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, ivLen) == CRYPT_SUCCESS); + ivLen = 13; + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, ivLen) == CRYPT_SUCCESS); + ivLen = 14; + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, ivLen) == CRYPT_MODES_IVLEN_ERROR); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_CTRL_API_TC001 + * @title Relationship between CRYPT_CTRL_SET_MSGLEN and ivlen of the CRYPT_EAL_CipherCtrl interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and msg len is 0. Expected result 3 is obtained. + * 4.Call the Update interface, ctx is not NULL, and plain len is 0. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 13. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and msg len is 0. Expected result 6 is obtained. + * 7.Call the Update interface, ctx is not NULL, and plain len is 1. Expected result 7 is obtained. + * 8.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 8. Expected result 8 is obtained. + * 9.Call the Ctrl interface, ctx is not NULL, and msg len is 1 << ((15 - 8) * 8)) - 1. Expected result 9 is obtained. + * 10.Call the Ctrl interface, ctx is not NULL, and msg len is 1 << ((15 - 8) * 8)). Expected result 10 is obtained. + * 11.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 12. Expected result 11 is obtained. + * 12.Call the Ctrl interface, ctx is not NULL, and msg len is 1 << ((15 - 12) * 8)) - 1. Expected result 12 is obtained. + * 13.Call the Ctrl interface, ctx is not NULL, and msg len is 1 << ((15 - 12) * 8)). Expected result 13 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Success. Return CRYPT_SUCCESS. + * 8.Success. Return CRYPT_SUCCESS. + * 9.Success. Return CRYPT_SUCCESS. + * 10.Failed. Return CRYPT_MODES_CTRL_MSGLEN_ERROR. + * 11.Success. Return CRYPT_SUCCESS. + * 12.Success. Return CRYPT_SUCCESS. + * 13.Failed. CRYPT_MODES_CTRL_MSGLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC001(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[13] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t data[16] = { 0 }; + uint8_t out[16] = { 0 }; + uint32_t outLen = sizeof(out); + uint64_t count = 0; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + outLen = sizeof(out); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 1, out, &outLen) == CRYPT_MODES_MSGLEN_OVERFLOW); + ivLen = 8; + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + count = ((uint64_t)1 << ((15 - 8) * 8)) - 1; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + count = (uint64_t)1 << ((15 - 8) * 8); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == + CRYPT_MODES_CTRL_MSGLEN_ERROR); + ivLen = 12; + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + count = ((uint64_t)1 << ((15 - 12) * 8)) - 1; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + count = (uint64_t)1 << ((15 - 12) * 8); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == + CRYPT_MODES_CTRL_MSGLEN_ERROR); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_UPDATE_API_TC001 + * @title Relationship between the CRYPT_CTRL_SET_MSGLEN and the update length of the CRYPT_EAL_CipherCtrl interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and msg len is 10. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and msg len is 20. Expected result 4 is obtained. + * 5.Call the Update interface, ctx is not NULL, and plain len is 20. Expected result 5 is obtained. + * 6.Call the Update interface, ctx is not NULL, and plain len is 0. Expected result 6 is obtained. + * 7.Call the Update interface, ctx is not NULL, and plain len is 10. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Failed. Return CRYPT_MODES_MSGLEN_OVERFLOW. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_UPDATE_API_TC001(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[13] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t data[20] = { 0 }; + uint32_t dataLen = 0; + uint8_t out[20] = { 0 }; + uint32_t outLen = sizeof(out); + uint64_t count = 0; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + count = 10; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + count = 20; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + dataLen = 20; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, dataLen, out, &outLen) == CRYPT_SUCCESS); + outLen = sizeof(out); + dataLen = 0; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, dataLen, out, &outLen) == CRYPT_SUCCESS); + outLen = sizeof(out); + dataLen = 10; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, dataLen, out, &outLen) == CRYPT_MODES_MSGLEN_OVERFLOW); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_UPDATE_API_TC001 + * @title Test after AAD is set for the CRYPT_EAL_CipherCtrl interface, msglen cannot be set. + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and set msglen. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 13. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and set msglen. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Failed. Return CRYPT_EAL_ERR_STATE. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC002(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[13] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t aad[16] = { 0 }; + uint64_t count = 0; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_EAL_ERR_STATE); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_CTRL_API_TC003 + * @title CRYPT_EAL_CipherCtrl interface set aad Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 13. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Failed. Return CRYPT_EAL_ERR_STATE. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC003(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[13] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t aad[16] = { 0 }; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, 0) == CRYPT_EAL_ERR_STATE); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, 0) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_CTRL_API_TC004 + * @title CRYPT_EAL_CipherCtrl interface set tag len Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and tag len is 4. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and tag len is 6. Expected result 4 is obtained. + * 5.Call the Ctrl interface, ctx is not NULL, and tag len is 8. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and tag len is 10. Expected result 6 is obtained. + * 7.Call the Ctrl interface, ctx is not NULL, and tag len is 12. Expected result 7 is obtained. + * 8.Call the Ctrl interface, ctx is not NULL, and tag len is 14. Expected result 8 is obtained. + * 9.Call the Ctrl interface, ctx is not NULL, and tag len is 16. Expected result 9 is obtained. + * 10.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 1. Expected result 10 is obtained. + * 11.Call the Ctrl interface, ctx is not NULL, and tag len is 2. Expected result 11 is obtained. + * 12.Call the Ctrl interface, ctx is not NULL, and tag len is 18. Expected result 12 is obtained. + * 13.Call the Ctrl interface, ctx is not NULL, and tag len is 0. Expected result 13 is obtained. + * 14.Call the Ctrl interface, ctx is not NULL, and tag len is 5. Expected result 14 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Success. Return CRYPT_SUCCESS. + * 8.Success. Return CRYPT_SUCCESS. + * 9.Success. Return CRYPT_SUCCESS. + * 10.Success. Return CRYPT_SUCCESS. + * 11.Failed. Return CRYPT_MODES_CTRL_TAGLEN_ERROR. + * 12.Failed. Return CRYPT_MODES_CTRL_TAGLEN_ERROR. + * 13.Failed. Return CRYPT_MODES_CTRL_TAGLEN_ERROR. + * 14.Failed. Return CRYPT_MODES_CTRL_TAGLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC004(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[13] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint32_t tagLen; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + tagLen = 4; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + tagLen = 6; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + tagLen = 8; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + tagLen = 10; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + tagLen = 12; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + tagLen = 14; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + tagLen = 16; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + + tagLen = 2; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == + CRYPT_MODES_CTRL_TAGLEN_ERROR); + tagLen = 18; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == + CRYPT_MODES_CTRL_TAGLEN_ERROR); + tagLen = 0; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == + CRYPT_MODES_CTRL_TAGLEN_ERROR); + tagLen = 5; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == + CRYPT_MODES_CTRL_TAGLEN_ERROR); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_CTRL_API_TC005 + * @title CRYPT_EAL_CipherCtrl interface get tag Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and tag len is 8. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and msg len is 7. Expected result 4 is obtained. + * 5.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 5 is obtained. + * 6.Call the Update interface, ctx is not NULL, and plain len is 7. Expected result 6 is obtained. + * 7.Call the Ctrl interface, ctx is not NULL, and get tag. Expected result 7 is obtained. + * 8.Call the Ctrl interface, ctx is not NULL, and get tag. Expected result 8 is obtained. + * 9.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 8. Expected result 9 is obtained. + * 10.Call the Ctrl interface, ctx is not NULL, and get tag. Expected result 10 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Success. Return CRYPT_SUCCESS. + * 8.Failed. Return CRYPT_EAL_ERR_STATE. + * 9.Success. Return CRYPT_SUCCESS. + * 10.Success. Return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC005(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[8] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t aad[10] = { 0 }; + uint8_t tag[16] = { 0 }; + uint32_t tagLen; + uint64_t count = 0; + uint8_t data[20] = { 0 }; + uint8_t out[16] = { 0 }; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + tagLen = 8; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + count = 7; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 7, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_EAL_ERR_STATE); + + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_CTRL_API_TC006 + * @title CRYPT_EAL_CipherCtrl interface get tag Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and msg len is 20. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and plain len is 20. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is not NULL, and ivLen is 8. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and msg len is 40. Expected result 6 is obtained. + * 7.Call the Ctrl interface, ctx is not NULL, and plain len is 30. Expected result 7 is obtained. + * 8.Call the Ctrl interface, ctx is not NULL, and tag len is 10. Expected result 8 is obtained. + * 9.Call the Ctrl interface, ctx is not NULL, and get tag. Expected result 9 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Success. Return CRYPT_SUCCESS. + * 8.Failed. Return CRYPT_EAL_ERR_STATE. + * 9.Failed. Return CRYPT_MODES_MSGLEN_LEFT_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC006(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[8] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t tag[16] = { 0 }; + uint32_t tagLen = sizeof(tag); + uint64_t count = 0; + uint8_t data[40] = { 0 }; + uint32_t dataLen = 0; + uint8_t out[40] = { 0 }; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + count = 20; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + dataLen = 20; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, dataLen, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + count = 40; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + outLen = sizeof(out); + dataLen = 30; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, dataLen, out, &outLen) == CRYPT_SUCCESS); + tagLen = 10; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_EAL_ERR_STATE); + tagLen = 16; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_MODES_MSGLEN_LEFT_ERROR); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001 + * @title AES CCM update encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. + * 3.Call the Reinit interface. + * 4.Call the Ctrl interface, set msg len, tag len and aad. + * 5.Call the Update interface, ctx is not NULL, and encrypt data. Expected result 1 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, and get tag. Expected result 2 is obtained. + * 7.Call the Init interface. + * 8.Call the Reinit interface. + * 9.Call the Ctrl interface, set msg len, tag len and aad. + * 10.Call the Update interface, ctx is not NULL, and decrypt data. Expected result 3 is obtained. + * 11.Call the Ctrl interface, ctx is not NULL, and get tag. Expected result 4 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001(int id, Hex *key, Hex *iv, Hex *aad, Hex *plaintext, Hex *ciphertext) +{ +#ifndef HITLS_CRYPTO_CCM + SKIP_TEST(); +#endif + TestMemInit(); + uint8_t iv0[8] = { 0 }; + uint8_t tag[16] = { 0 }; + uint32_t tagLen = sizeof(tag); + uint64_t count; + uint8_t out[1024] = { 0 }; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + // encrypt + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv0, sizeof(iv0), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len) == CRYPT_SUCCESS); + count = plaintext->len; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + tagLen = ciphertext->len - plaintext->len; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, plaintext->x, plaintext->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out, ciphertext->x, outLen) == 0); + ASSERT_TRUE(memcmp(tag, ciphertext->x + outLen, tagLen) == 0); + + // decrypt + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv0, sizeof(iv0), false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len) == CRYPT_SUCCESS); + count = plaintext->len; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + tagLen = ciphertext->len - plaintext->len; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, ciphertext->x, plaintext->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out, plaintext->x, outLen) == 0); + ASSERT_TRUE(memcmp(tag, ciphertext->x + outLen, tagLen) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + + +/** + * @test SDV_CRYPTO_AES_CCM_CTRL_API_TC007 + * @title CRYPT_EAL_CipherCtrl state switching Test + * @precon Registering memory-related functions. + * @brief + * 1.Call the Reinit interface and then Call the Ctrl interface to get tag. Expected result 1 is obtained. + * 2.Call the update interface and then Call the Ctrl interface to get tag. Expected result 2 is obtained. + * 3.Call the Init interface and then Call the Ctrl interface to get tag. Expected result 3 is obtained. + * 4.Call the Init and the Deinit interface, and then Call the Init interface. Expected result 4 is obtained. + * 5.Call the Ctrl interface to get tag. Expected result 5 is obtained. + * 6.Call the Init and the Deinit interface, and then Call the Ctrl interface to get tag. Expected result 6 is obtained. + * 7.Call the Init interface and the Reinit interface, then Call the Deinit interface, + * and then Call the Ctrl interface to get tag. Expected result 7 is obtained. + * 8.Call the Init interface, call the Ctrl interface set aad, set tag len. Expected result 8 is obtained. + * 9.Call the Init interface, call the Ctrl interface set msglen, and call Update interface and Reinit interface, + * and then call the Ctrl interface get tag. Expected result 9 is obtained. + * 10.Call the Init interface, call the Ctrl interface set msglen, call the update interface for encryption, + * and then call the Ctrl interface set msglen. Expected result 10 is obtained, + * 11.Call the Ctrl interface get tag. Expected result 11 is obtained. + * 12.Call the Init interface, call the Ctrl interface set msglen, call the update interface for encryption, + * and then call the Ctrl interface set aad. Expected result 12 is obtained, + * 13.Call the Ctrl interface get tag. Expected result 13 is obtained. + * 14.Call the Init interface, call the ctrl interface set msglen, call the update interface for encryption, + * and then call the Ctrl interface set taglen. Expected result 14 is obtained, + * 15.Call the Ctrl interface get tag. Expected result 15 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Failed. Return CRYPT_EAL_ERR_STATE. + * 5.Failed. Return CRYPT_EAL_ERR_STATE. + * 6.Failed. Return CRYPT_EAL_ERR_STATE. + * 7.Failed. Return CRYPT_EAL_ERR_STATE. + * 9.Success. Return CRYPT_SUCCESS. + * 10.Failed. Return CRYPT_EAL_ERR_STATE. + * 11.Success. Return CRYPT_SUCCESS. + * 12.Failed. Return CRYPT_EAL_ERR_STATE. + * 13.Success. Return CRYPT_SUCCESS. + * 14.Failed. Return CRYPT_EAL_ERR_STATE. + * 15.Success. Return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_CTRL_API_TC007(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; + uint8_t iv[8] = { 0 }; + uint32_t ivLen = sizeof(iv); + uint8_t tag[16] = { 0 }; + uint32_t tagLen = sizeof(tag); + uint64_t count = 0; + uint8_t data[40] = { 0 }; + uint8_t out[40] = { 0 }; + uint8_t aad[40] = { 0 }; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + CRYPT_EAL_CipherDeinit(ctx); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_EAL_ERR_STATE); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_EAL_ERR_STATE); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + CRYPT_EAL_CipherDeinit(ctx); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_EAL_ERR_STATE); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + CRYPT_EAL_CipherDeinit(ctx); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_EAL_ERR_STATE); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_EAL_ERR_STATE); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_EAL_ERR_STATE); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_EAL_ERR_STATE); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, keyLen, iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_EAL_ERR_STATE); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 + * @title Test on the same address in plaintext and ciphertext + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and set tag len. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and set msg len. Expected result 4 is obtained. + * 5.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 5 is obtained. + * 6.Call the Update interface, ctx is not NULL, and encrypt data. Expected result 6 is obtained. + * 7.Compare the ciphertext. Expected result 7 is obtained. + * 8.Compare the tag. Expected result 8 is obtained. + * 9.Call the Deinit interface and Call the Init interface. Expected result 9 is obtained. + * 10.Call the Ctrl interface set tag len. Expected result 10 is obtained. + * 11.Call the Ctrl interface set msg len. Expected result 11 is obtained. + * 12.Call the Ctrl interface set aad. Expected result 12 is obtained. + * 13.Call the Update interface to decrypt data. Expected result 13 is obtained. + * 14.Compare the plaintext. Expected result 14 is obtained. + * 15.Compare the tag. Expected result 15 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Consistent with expected vector. + * 8.Consistent with expected vector. + * 9.Success, Return CRYPT_SUCCESS + * 10.Success, Return CRYPT_SUCCESS + * 11.Success, Return CRYPT_SUCCESS + * 12.Success, Return CRYPT_SUCCESS + * 13.Success, Return CRYPT_SUCCESS + * 14.Consistent with expected vector. + * 15.Consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag) +{ +#ifndef HITLS_CRYPTO_CCM + SKIP_TEST(); +#endif + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + uint8_t *outTag = NULL; + uint8_t *out = NULL; + uint32_t tagLen = tag->len; + uint32_t outLen = pt->len; + uint64_t msgLen = pt->len; + out = (uint8_t *)malloc(outLen * sizeof(uint8_t)); + ASSERT_TRUE(out != NULL); + outTag = (uint8_t *)malloc(sizeof(uint8_t) * tagLen); + ASSERT_TRUE(outTag != NULL); + ASSERT_TRUE(memcpy_s(out, outLen, pt->x, pt->len) == EOK); + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &msgLen, sizeof(msgLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, out, pt->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Ct", out, ct->len, ct->x, ct->len); + ASSERT_COMPARE("Compare Enc Tag", outTag, tagLen, tag->x, tag->len); + + CRYPT_EAL_CipherDeinit(ctx); + ASSERT_TRUE(memcpy_s(out, outLen, ct->x, ct->len) == EOK); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &msgLen, sizeof(msgLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, out, ct->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Pt", out, pt->len, pt->x, pt->len); + ASSERT_COMPARE("Compare Dec Tag", outTag, tagLen, tag->x, tag->len); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + free(out); + free(outTag); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 + * @title Multi-thread Test + * @precon Registering memory-related functions. + * @brief + * 1.Start three threads. Expected result 1 is obtained. + * 2.Call the eal interface in the thread for encryption. Expected result 2 is obtained. + * 3.Call the eal interface in the thread for decryption. Expected result 2 is obtained. + * @expect + * 1.Success. + * 2.The encryption is successful. The ciphertext and tag are the same as the vector. + * 3.The decryption is successful. The plaintext and tag are consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag) +{ + int ret; + TestMemInit(); + const uint32_t threadNum = 3; // Number of threads. + pthread_t thrd[threadNum]; + ThreadParameter arg[3] = { + // 3 Threads + {.key = key->x, .iv = iv->x, .aad = aad->x, .pt = pt->x, .ct = ct->x, .tag = tag->x, + .keyLen = key->len, .ivLen = iv->len, .aadLen = aad->len, + .ptLen = pt->len, .ctLen = ct->len, .tagLen = tag->len, + .algId = algId}, + {.key = key->x, .iv = iv->x, .aad = aad->x, .pt = pt->x, .ct = ct->x, .tag = tag->x, + .keyLen = key->len, .ivLen = iv->len, .aadLen = aad->len, + .ptLen = pt->len, .ctLen = ct->len, .tagLen = tag->len, + .algId = algId}, + {.key = key->x, .iv = iv->x, .aad = aad->x, .pt = pt->x, .ct = ct->x, .tag = tag->x, + .keyLen = key->len, .ivLen = iv->len, .aadLen = aad->len, + .ptLen = pt->len, .ctLen = ct->len, .tagLen = tag->len, + .algId = algId}, + }; + for (uint32_t i = 0; i < threadNum; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)MultiThreadTest, &arg[i]); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < threadNum; i++) { + pthread_join(thrd[i], NULL); + } + +exit: + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_ccm.data b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_ccm.data new file mode 100644 index 00000000..8cb6f00a --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_ccm.data @@ -0,0 +1,134 @@ +SDV_CRYPTO_AES_CCM_REINIT_API_TC001_AESCCM128 +SDV_CRYPTO_AES_CCM_REINIT_API_TC001:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_REINIT_API_TC001_AESCCM192 +SDV_CRYPTO_AES_CCM_REINIT_API_TC001:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_REINIT_API_TC001_AESCCM256 +SDV_CRYPTO_AES_CCM_REINIT_API_TC001:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC001_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC001:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC001_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC001:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC001_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC001:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_UPDATE_API_TC001_AESCCM128 +SDV_CRYPTO_AES_CCM_UPDATE_API_TC001:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_UPDATE_API_TC001_AESCCM192 +SDV_CRYPTO_AES_CCM_UPDATE_API_TC001:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_UPDATE_API_TC001_AESCCM256 +SDV_CRYPTO_AES_CCM_UPDATE_API_TC001:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC002_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC002:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC002_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC002:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC002_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC002:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC003_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC003:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC003_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC003:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC003_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC003:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC004_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC004:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC004_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC004:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC004_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC004:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC005_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC005:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC005_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC005:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC005_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC005:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC006_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC006:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC006_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC006:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC006_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC006:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001_AESCCM128 #1 from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_CCM:"f9fdca4ac64fe7f014de0f43039c7571":"5a8aa485c316e9":"3796cf51b8726652a4204733b8fbb047cf00fb91a9837e22ec22b1a268f88e2c":"a265480ca88d5f536db0dc6abc40faf0d05be7a966977768":"6be31860ca271ef448de8f8d8b39346daf4b81d7e92d65b338f125fa" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001_AESCCM128 #2 from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_CCM:"4bb3c4a4f893ad8c9bdc833c325d62b3":"5a8aa485c316e9":"":"":"75d582db43ce9b13ab4b6f7f14341330" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001_AESCCM192 #3 from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_CCM:"4bb3c4a4f893ad8c9bdc833c325d62b3d3ad1bccf9282a65":"5a8aa485c316e9":"":"":"17223038fa99d53681ca1beabe78d1b4" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001_AESCCM192 #4 from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_CCM:"a7aa635ea51b0bb20a092bd5573e728ccd4b3e8cdd2ab33d":"5a8aa485c316e9":"3796cf51b8726652a4204733b8fbb047cf00fb91a9837e22ec22b1a268f88e2c":"a265480ca88d5f536db0dc6abc40faf0d05be7a966977768":"6aab64c4787599d8f213446beadb16e08dba60e97f56dbd14d1d980d6fe0fb44b421992662b97975" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001_AESCCM256 #5 from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_CCM:"af063639e66c284083c5cf72b70d8bc277f5978e80d9322d99f2fdc718cda569":"a544218dadd3c10583db49cf39":"":"":"97e1a8dd4259ccd2e431e057b0397fcf" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001_AESCCM256 #6 from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_CCM:"705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe":"a544218dadd3c10583db49cf39":"3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907":"e8de970f6ee8e80ede933581b5bcf4d837e2b72baa8b00c3":"c0ea400b599561e7905b99262b4565d5c3dc49fad84d7c69ef891339" + +SDV_CRYPTO_AES_CCM_CTRL_API_TC007_AESCCM128 +SDV_CRYPTO_AES_CCM_CTRL_API_TC007:CRYPT_CIPHER_AES128_CCM:16 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC007_AESCCM192 +SDV_CRYPTO_AES_CCM_CTRL_API_TC007:CRYPT_CIPHER_AES192_CCM:24 + +SDV_CRYPTO_AES_CCM_CTRL_API_TC007_AESCCM256 +SDV_CRYPTO_AES_CCM_CTRL_API_TC007:CRYPT_CIPHER_AES256_CCM:32 + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES128_CCM Ciphertext plaintext same address #from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_CCM:"a7aa635ea51b0bb20a092bd5573e728c":"5a8aa485c316e9403aff859fbb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982":"8739b4bea1a099fe547499cbc6d1b13d849b8084c9b6acc5":"934f893824e880f743d196b22d1f340a52608155087bd28a":"c25e5329" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES128_CCM Ciphertext plaintext same address #from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_CCM:"f9fdca4ac64fe7f014de0f43039c7571":"5a8aa485c316e9":"3796cf51b8726652a4204733b8fbb047cf00fb91a9837e22ec22b1a268f88e2c":"a265480ca88d5f536db0dc6abc40faf0d05be7a966977768":"6be31860ca271ef448de8f8d8b39346daf4b81d7e92d65b3":"38f125fa" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES192_CCM Ciphertext plaintext same address #from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_CCM:"f9fdca4ac64fe7f014de0f43039c757194d544ce5d15eed4":"5a8aa485c316e9":"3796cf51b8726652a4204733b8fbb047cf00fb91a9837e22ec22b1a268f88e2c":"a265480ca88d5f536db0dc6abc40faf0d05be7a966977768":"9f6ca4af9b159148c889a6584d1183ea26e2614874b05045":"75dea8d1" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES192_CCM Ciphertext plaintext same address #from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_CCM:"26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886":"5a8aa485c316e9403aff859fbb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982":"8739b4bea1a099fe547499cbc6d1b13d849b8084c9b6acc5":"c5b0b2ef17498c5570eb335df4588032958ba3d69bf6f317":"8464a6f7fa2b76744e8e8d95691cecb8" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES256_CCM Ciphertext plaintext same address #from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_CCM:"705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe":"a544218dadd3c1":"d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab":"78c46e3249ca28e1ef0531d80fd37c124d9aecb7be6668e3":"3341168eb8c48468c414347fb08f71d2086f7c2d1bd581ce":"1ac68bd42f5ec7fa7e068cc0ecd79c2a" + +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES256_CCM Ciphertext plaintext same address #from NIST +SDV_CRYPTO_AES_CCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_CCM:"314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e":"a544218dadd3c10583db49cf39":"3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907":"e8de970f6ee8e80ede933581b5bcf4d837e2b72baa8b00c3":"8d34cdca37ce77be68f65baf3382e31efa693e63f914a781":"367f30f2eaad8c063ca50795acd90203" + +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 CRYPT_CIPHER_AES128_CCM Multithreading test #from NIST +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CCM:"a7aa635ea51b0bb20a092bd5573e728c":"5a8aa485c316e9403aff859fbb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982":"8739b4bea1a099fe547499cbc6d1b13d849b8084c9b6acc5":"934f893824e880f743d196b22d1f340a52608155087bd28a":"c25e5329" + +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 CRYPT_CIPHER_AES128_CCM Multithreading test #from NIST +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES128_CCM:"f9fdca4ac64fe7f014de0f43039c7571":"5a8aa485c316e9":"3796cf51b8726652a4204733b8fbb047cf00fb91a9837e22ec22b1a268f88e2c":"a265480ca88d5f536db0dc6abc40faf0d05be7a966977768":"6be31860ca271ef448de8f8d8b39346daf4b81d7e92d65b3":"38f125fa" + +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 CRYPT_CIPHER_AES192_CCM Multithreading test #from NIST +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CCM:"f9fdca4ac64fe7f014de0f43039c757194d544ce5d15eed4":"5a8aa485c316e9":"3796cf51b8726652a4204733b8fbb047cf00fb91a9837e22ec22b1a268f88e2c":"a265480ca88d5f536db0dc6abc40faf0d05be7a966977768":"9f6ca4af9b159148c889a6584d1183ea26e2614874b05045":"75dea8d1" + +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 CRYPT_CIPHER_AES192_CCM Multithreading test #from NIST +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES192_CCM:"26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886":"5a8aa485c316e9403aff859fbb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982":"8739b4bea1a099fe547499cbc6d1b13d849b8084c9b6acc5":"c5b0b2ef17498c5570eb335df4588032958ba3d69bf6f317":"8464a6f7fa2b76744e8e8d95691cecb8" + +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 CRYPT_CIPHER_AES256_CCM Multithreading test #from NIST +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CCM:"705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe":"a544218dadd3c1":"d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab":"78c46e3249ca28e1ef0531d80fd37c124d9aecb7be6668e3":"3341168eb8c48468c414347fb08f71d2086f7c2d1bd581ce":"1ac68bd42f5ec7fa7e068cc0ecd79c2a" + +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001 CRYPT_CIPHER_AES256_CCM Multithreading test #from NIST +SDV_CRYPTO_AES_CCM_MULTI_THREAD_FUNC_TC001:CRYPT_CIPHER_AES256_CCM:"314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e":"a544218dadd3c10583db49cf39":"3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e09a1005e024f6907":"e8de970f6ee8e80ede933581b5bcf4d837e2b72baa8b00c3":"8d34cdca37ce77be68f65baf3382e31efa693e63f914a781":"367f30f2eaad8c063ca50795acd90203" diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_gcm.c b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_gcm.c new file mode 100644 index 00000000..16dc3632 --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_gcm.c @@ -0,0 +1,168 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_modes_gcm.h" +#include "crypt_local_types.h" +#include "crypt_aes.h" +#include "crypt_eal_cipher.h" + +#define FREE(res) \ + do { \ + if ((res) != NULL) { \ + free(res); \ + } \ + } while (0) + +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 + * @title AES-GCM decryption full vector test + * @precon Registering memory-related functions. + * @brief + * 1.Call the Init interface. Expected result 1 is obtained. + * 2.Call the Ctrl interface to set parameters. Expected result 2 is obtained. + * 3.Call the update interface to update message. Expected result 3 is obtained. + * 4.Call the Ctrl interface to get tag. Expected result 4 is obtained. + * 5.Compare the plaintext data. Expected result 5 is obtained. + * 6.Compare the tag data. Expected result 6 is obtained. + * @expect + * 1.The init is successful, return CRYPT_SUCCESS. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The getting is successful, return CRYPT_SUCCESS. + * 5.Plaintext is consistent with the test vector. + * 6.Tag is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag, int result) +{ +#ifndef HITLS_CRYPTO_GCM + SKIP_TEST(); +#endif + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + uint8_t *outTag = NULL; + uint8_t *out = NULL; + uint32_t tagLen = tag->len; + uint32_t outLen; + + if (ct->len > 0) { + out = (uint8_t *)BSL_SAL_Malloc(ct->len * sizeof(uint8_t)); + outLen = ct->len * sizeof(uint8_t); + ASSERT_TRUE(out != NULL); + } else { + out = (uint8_t *)BSL_SAL_Malloc(1 * sizeof(uint8_t)); + outLen = 1 * sizeof(uint8_t); + ASSERT_TRUE(out != NULL); + } + + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, ct->x, ct->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + outTag = (uint8_t *)BSL_SAL_Malloc(sizeof(uint8_t) * tagLen); + ASSERT_TRUE(outTag != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + if (pt->x != NULL) { + ASSERT_TRUE(memcmp(out, pt->x, pt->len) == 0); + } + + if (result == 0) { + ASSERT_COMPARE("Compare Tag", outTag, tagLen, tag->x, tag->len); + } else { + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) != 0); + } + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + FREE(out); + FREE(outTag); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 + * @title AES-GCM encryption full vector test + * @precon Registering memory-related functions. + * @brief + * 1.Call the Init interface. Expected result 1 is obtained. + * 2.Call the Ctrl interface to set parameters. Expected result 2 is obtained. + * 3.Call the update interface to update message. Expected result 3 is obtained. + * 4.Call the Ctrl interface to get tag. Expected result 4 is obtained. + * 5.Compare the ciphertext data. Expected result 5 is obtained. + * 6.Compare the tag data. Expected result 6 is obtained. + * @expect + * 1.The init is successful, return CRYPT_SUCCESS. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The getting is successful, return CRYPT_SUCCESS. + * 5.Ciphertext is consistent with the test vector. + * 6.Tag is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag) +{ +#ifndef HITLS_CRYPTO_GCM + SKIP_TEST(); +#endif + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + uint8_t *outTag = NULL; + uint8_t *out = NULL; + uint32_t tagLen = tag->len; + uint32_t outLen; + + if (ct->len > 0) { + out = (uint8_t *)BSL_SAL_Malloc(ct->len * sizeof(uint8_t)); + outLen = ct->len * sizeof(uint8_t); + ASSERT_TRUE(out != NULL); + } else { + out = (uint8_t *)BSL_SAL_Malloc(1 * sizeof(uint8_t)); + outLen = 1 * sizeof(uint8_t); + ASSERT_TRUE(out != NULL); + } + + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt->x, pt->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + outTag = (uint8_t *)BSL_SAL_Malloc(sizeof(uint8_t) * tagLen); + ASSERT_TRUE(outTag != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + if (ct->x != NULL) { + ASSERT_TRUE(memcmp(out, ct->x, ct->len) == 0); + } + ASSERT_COMPARE("Compare Tag", outTag, tagLen, tag->x, tag->len); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + FREE(out); + FREE(outTag); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_gcm.data b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_gcm.data new file mode 100644 index 00000000..ace2ffa5 --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_aes_gcm.data @@ -0,0 +1,198 @@ +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 1 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"11754cd72aec309bf52f7687212e8957":"3c819d9a9bed087615030b65":"":"":"":"250327c674aaf477aef2675748cf6971":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 2 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"ca47248ac0b6f8372a97ac43508308ed":"ffd2b598feabc9019262d2be":"":"":"":"60d20404af527d248d893ae495707d1b":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 3 Keylen=128 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"09dc161766e7fadd5202a661745a7dde":"9b9d586fc84a525cbef2750c":"":"":"":"15963536":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 4 Keylen=128 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"f6814505e28527374cad6b90ef638a09":"68f8ce421247b9f1330a37fe":"":"":"":"e133d34e":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 5 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"910385f6f07f9e57e483c47dd5206bcc":"518f56e33658df311d42d9fe":"5d157909a2a4607117e77da0e4493b88":"":"":"a7041ea4a1d74d9e66b9571b59b6a1d8":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 6 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"cab3af7a15b430e034e793bb30db8ab2":"963a56e2e12f387062e18498":"a094a1dd1121d3aa52c81e8f10bf9f0c":"":"":"1a31d295601eb3c82a54b234984ffdf6":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 7 Keylen=128 IVlen=96 PTlen=0 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"2955ebf56e1310a309c8c2ed49e2bf26":"82c4f52740829745a416baed":"2f456b43a670474da515f14056f2d030":"":"":"407a7369a5a94288":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 8 Keylen=128 IVlen=96 PTlen=0 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"13d7b6ed593d7edd82871a85cf645812":"54695be8fff4c304f4337b15":"4f3a340075ad5cbbefa329d9f0851ea6":"":"":"896b97b4e9151401":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 9 Keylen=128 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"183aa33c3d5e0a33f79ce6b3dc75215e":"6f83a294e0d52cc1315488de":"ae73f1e18297256f15cf14a240976244":"":"":"dde53390":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 10 Keylen=128 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"4c72d44f9728849c9675c99002d5d71c":"e2a1058cc5df93dd79564e26":"6fc63a2979ad06718e73eb3b76f7a83c":"":"":"7ffc7cbe":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 11 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"7f6453b39bde018560a16a2704217543":"0f3eecf48d68353226a77fe4":"11e4ecb256ebff56453fa2e75e43eb9d641049e6":"":"":"b512623a12d5492b7d76d39be0df5777":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 12 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"9332e433bf6100c6cc23b08710627c40":"aab3db3015b29d24f329beb4":"bd843a08f0a822f8f4f76c3648380aab7622e719":"":"":"e54f1d18c61d8be15484727605b5a5dd":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 13 Keylen=128 IVlen=96 PTlen=0 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"e5d017d52747f60d1b4bc45d54e7a165":"92c2de0fe4352deb16f826c8":"ddd55ed8a36d255491a127bf324aa40178f37f07088aedd814f796ce046d895084e4b8c4bc0ad3cb302a5a11dd3b0bd8":"":"":"8d6b5ca578f7fba6dc549e6eea":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 14 Keylen=128 IVlen=96 PTlen=0 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"42c2c2ca4ee5a0dde1df5c44704f9029":"695aef2d3e105db869555cb2":"3afeb407e3b1a45c1a0c23d1677c05f3190173e441a3cf025801531a83bc133ff66d10dbd035c1dbeaabd190b61fa243":"":"":"ee79f099410c2d4757a9f5fe3c":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 15 Keylen=128 IVlen=96 PTlen=128 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"3a422ad95edcb470d0524c12ddc5415e":"02f338926aa8cc00ccd8ea05":"":"80da029efbbe3fd1f553aa48f78edffd":"0cd0921a851b26436e83e5dd7e1df26c":"21a2926d5341e566a465785d8f":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 16 Keylen=128 IVlen=96 PTlen=128 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"a6eecf615a8583a1f3f230980b6003f4":"19b26ea23602e6f5c809b8a3":"":"7fb3a4ea62de8961d5e9f50cfa594c1d":"98b6a0f27895538e99f94ff0596e226b":"625609061910158b5d1816130b":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 17 Keylen=128 IVlen=96 PTlen=128 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"af2904e234458af8ce0d616866c981fc":"ef6381fdeb7877845f46edcd":"41946f4a8304875ab3db0dec08d6c990":"13836338abcfc03b89dd93f1dd691b01":"b13b49e06b9e615a86d4c17ac10da212":"ac8af4dc584da9a6":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 18 Keylen=128 IVlen=96 PTlen=128 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"65a142738ac72760a10d60c13cdb0de2":"3bb2dda03371caf1d8a30af3":"9c4e4d98d39f096840355d997209ea45":"85ae8bd8cb76bf469084e84602fa80d6":"b876fe300167c8b59f530d238e28d417":"876a0ef30397b12d":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 19 Keylen=128 IVlen=96 PTlen=128 Taglen=102 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"d3a8345c572023ca9bdc94641ff201a1":"180bd185a5ed15e731d3f388":"e4db3122dd3e4b9874ae296f9d9dc4e16da01ec6fd9278e8f4f8c2cfab00a8291fe7f4ae30e87244a78a010684adf8ae":"dff19c6af6684ed1f6f6e478d42564ac":"3cbbbd725fdb28ead07d35aca52e9e21":"9046680683ce1faf7a932a314b":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 20 Keylen=128 IVlen=96 PTlen=0 Taglen=102 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"4886d83c5e022668ce504c804fb4c149":"fa4cc13a51ef7e920f92d3c4":"0ab83c57500d90a093fff407f96f1eecbad8ac606e088feec74707351301b75a28b87d4305887b76b0af1ae43212e2bc":"":"a2d2caa75449c86e5bc71e8d43616bd0":"2b5740a1f089ab184f0154a14c":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 21 Keylen=128 IVlen=1024 PTlen=128 Taglen=112 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"5c47f3e1dda536efd7c5a5339eca6fbf":"cf319c9189eb5bc78cf9976228976ea5dfb1b929e7fdb73cbc6ed95b142ee806f7e2b63895fac955509df1d387335cd6e0d71f71ed794ba64321175bc932a8004ac796c986159c63de45a02e07b601ef7a633172dbc04da1abfa8cb1ebd3bd69c8fa1bad9f4383882449fa47713f9d8cd12554656d497049bbb9d3c45d54215a":"ef0509caf26f9f3f313c2962182feb2e565ec253ced60821b7eb67738e83dbbdab2d3b1b0cff5d55e94726cf37a08b7bea12f5c0c406e4d528f9b3dc46668c70b08e742eae242a17a36b6d04f10d175703c2c0928bf8d525c97f":"043183e2b0e52b8acaf147b4a4c399ba":"ee79deeafdeb82d3e9a2f590cbf9cbb7":"4306ec87c10884233b4955d819ff":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 22 Keylen=128 IVlen=1024 PTlen=128 Taglen=112 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"925d66b4110aea5e7a53cdf1647efa4f":"e5a6ea354867b6c438bbfe2c143941dedae10657abf4274a90ae9d44ece4be8c192b68412626fda4e9cbfef02753decf2b7a6563cfb90103e27fea8036eec99bbc97e3fe23d8d68a9b1c55f48cfbec2f8c6cbfad02679929d99a9c57a3bae95770a1ce7387339eff6a180ac7c078484284c80f8a2c4a0d16c350d12548b4b92a":"2bdae681727005651eba650691697ee96b83ca4782e5e17f7e2e0a2951b4a5236635c40be526cd2ad4950ccec8b7dbc5f2c3ff4fe45cb684e9a47055d4f7fca09fd605c646b28837039b8ad9639f124b22e61e5e4cbc8e1e7858":"d6060c538b156ed902b635bcf3e3c59b":"4637a3ecc35f7927a439c28462d2243a":"8f93140874629544ade63158fe8c":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 23 Keylen=128 IVlen=1024 PTlen=408 Taglen=112 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"357e9c3ab5323ff141bdf17228b80a61":"de8cd40a5db81e8b7083807a8a5c16d4808f48c52a56c68b77edb01b563f80513518eac2672c8f5524aa6e3850337233c693dec99a547cf6599dc33a6d89763e5f91d9a74715c9a635ed1931403b2fbec8be85f287506ed4bd7da3c6e2b25e29becf9466f4abdf3b0daa4818a7f31563fb5be7aba7cbd53c6522331fc04d4573":"863ebc2231af641f620f618567007847057146db69b1066dc1c4464d251729eb6ea3871d3e997e71a963439e9d81691a7196ddd439748e795a2cc62b8382a61e79863259cb643851f9a271130e0f9f54e15f0dc3ec8b27084c39":"995142af8870fd1c805aa9919f76485dc1fed5ead1e8366633ef09db5595c1a305bd10d945409148744d3998aba6434172087f":"fc12b78280d4a9eef7d536f2f5b3b3d63cf641e07f6b91332b9200d224632c5b1ee41ee136693bf0c26d569e998d9a09ad24f8":"c0f7d0e6":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 24 Keylen=128 IVlen=1024 PTlen=408 Taglen=112 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"0e00c76561d2bd9b40c3c15427e2b08f":"492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e74cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496":"d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba8f1f56c0":"fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956ca9c0195721476b85":"4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2cf4fc97416ee52abe":"e20b6656":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 25 Keylen=192 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":"ab2265b4c168955561f04315":"":"":"":"f149e2b5f0adaa9842ca5f45b768a8fc":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 26 Keylen=192 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"1bb1d6a3bfc748786f3951e43c18054bfc8ce6ab3dc3d398":"fea56a5ce5f7d4c81680195d":"":"":"":"0b0bc0768b02f126a29bcb144abc6e4c":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 27 Keylen=192 IVlen=1 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"2d302c528ccafabb4aed0c5efdde4245d1a3173285198a74":"87":"":"":"":"821a99d4":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 28 Keylen=192 IVlen=1 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"e903b22c57b7aa856ad3ee65595752e14bb1b6037f6505d0":"81":"":"":"":"fc491a6b":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 29 Keylen=192 IVlen=1 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"75023350d2957aff638a1b828b537aebe09a7215ea4ba710":"02":"320cd5fceafbcb412aef1dbc92ae7034fc54a2a1":"":"":"8b0a87241985085363837d54c47ae3b6":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 30 Keylen=192 IVlen=1 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"7128c8edaa25aff70fcce333c1e83d0707580f206ad42976":"3c":"a2dbf9479da6f2f539c522e77c8736b75d9e23b4":"":"":"f4808844b666d57be068bd33398f04e5":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 31 Keylen=192 IVlen=1024 PTlen=0 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"7ea7992be6a1d8a5441cc0ae83295cc9ad118db828342e20":"dda6db32559f01be6b9aeeef9366393137e06323afdc9376c29fc5eb16c72958450fec510c0e2c0e36c3e94f85c1120506333ccc812c4b6fe231def459dd10fcc81d0c8807ca012e7a621be5aa9574a189f3c3185a81a262181bf7e5ae93fa96cd81bfddae44eaefc4ec6e4530ebaa57c594146268dbedfd6a0701ecbd916ba0":"1cce943c868d7c585a1ea119a3964136401d9846":"":"":"abbe23f645f24f48b99899cffb":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 32 Keylen=192 IVlen=1024 PTlen=0 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"5d93bacbfe219a193f0a8001de6503cde5e69af9bc37e828":"f8f8ac065723e732fc17a127fade16bbeb25099696dcda346d4c1a9b947c977eeb81169c5c9d98b4a0eb2ba9f47a3ced76ea811384701feb35b58eb2969a81b0c977258ecc7a8fd5f35f68c6ecfd11e0162e2e4ec25680f61ff309e4445ce4159dfba1f0348e5d004f4b88f6234d4089f651e70e456c0802315ba6079efc8db1":"0e2e267071713c12dcbdffc2c21c670a694c05df":"":"":"df85dac2b5d574803f545a7ea2":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 33 Keylen=192 IVlen=1024 PTlen=720 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"78936a61415870c1b80288a60c11fe20c430f0377fddaed9":"f6588eacb6ca862252dd19501b1ca6453cf2f518aa38ed17b3439a4793146d8319aef31e709b4596ba4004003e367b581c5d4d859adaf64fd8eeac1cdf5c664ffca5e76ee66b3886a37a744e00b3bfc776f1f8e44ea04040d1fb84ec9e7c70a5b70397f2e46e69d916d758174e5614776bb25a36b6bae2451da33de69dc74c82":"110b28a64c7931dfeab4374cbc8b459f3ce0911aa8ff8c74a345da52195ab5b311e2dbc03f9483689f5352a12822a7f91d851197351d410400642b8f827837e518787f34c32229b73a7bb98a1dab6229dffdf87d4f380a743db6":"fed60be040c1bccd3556bc3ce6811d53668cc1b20b53b48bae405fa92b211523407b7558ba794a8e697943484253ac6d9d0c2e":"0ecd930de3884d827e99e7f13f36d179b5f09bdba67a267abdbfa42eacc318bc98da6eac8ceb05f35b586375ca89e0176fc9d7":"de05bf27":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 34 Keylen=192 IVlen=1024 PTlen=720 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"b19e797782ea3464922b167057b236f60e4a8bcdaf6b7f3c":"833fdc70610b218f2da6715f9601a7f3fa3d6c3f159da3ee9b0108f3a3e332c90dab53364c5529840ad635fccd6c994c48344e40ebbfc871bf6088d8d07f8a7594411f4b4da85be9a6a6829eb48ca2ab9fe95991a16c3d9b5a4ab582310cb81e426752af2d9cfdc15fa0ee5593b55d62d9a782db0b01c58eeb3a411b5f6d8f37":"8a4eddba874b2c414c6ce55f50e3f8e74f856c145f1305dc5e1013be880c13bb5c2e2e20b5d631b5129f7193385383670413accd992489b9f3d64bc3cf4c00a858fc28fff64cdf296a79f868c7ee445a19b64ed4ca968d9024a2":"655b51c194a4b0bc7956a880c0dba7a17f41011a893717fe7d9499adaef9bf4b2580f8d9e7c9f729bda14c33ecddca9ead2b6a":"9686e8222293e155bed1ff76987a1fe0bb9658fbb3b0c369b2d61a9cac1e114be2f8e9caa03243ec9e7a522815df5fe420ca3a":"2454e4ac":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 35 Keylen=256 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4":"516c33929df5a3284ff463d7":"":"":"":"bdc1ac884d332457a1d2664f168c76f0":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 36 Keylen=256 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f":"770ac1a5a3d476d5d96944a1":"":"":"":"196d691e1047093ca4b3d2ef4baba217":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 37 Keylen=256 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"28c0ce6335c4f2db381c983d674eed78a5a912431d68a3ef0243c33de53f66d2":"3aac8e3550c4ba9882cd72f1":"":"":"":"7c12c543":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 38 Keylen=256 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"0f8a57408083e09301aecbe51687a74517e743e9eb03adaed4305ce3378454db":"7c0c25eae76aa0f761507e56":"":"":"":"a70a123c":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 39 Keylen=256 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"aa93adef2c80d27ecb4226106f41ffc6f934dab86c9e6e9b52e0ae14132c3652":"deddca07ffe8ab20a814806b":"340d2571dd9b2223b6575f5ddff31fe0":"":"":"47c215ec7c6330855dd5788c02f7":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 40 Keylen=256 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"db1ff13ff9ceabd8cf116625d2c0378a811d561f63941a7755d9be7948d067fa":"e808c1bc91bf8b5cb7c3105e":"e551c1cd7cc01d750a28c09dad782efe":"":"":"e5f092264f3d55f51cc3c58081c2":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 41 Keylen=256 IVlen=1 PTlen=408 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"04c45ff622008bedfc3a77f763e8d251f7394e79b1e0feabec45697098f9b5b9":"98":"":"2fd5f7fe0d95810e6c24ba6539cbb0ab7cde765c829aa59d97dea6a70e8b8f0aa93b651e1a301998d44bf0138bdd5472c484da":"6f404c410090dc368f6f183de9a70af9d85a644edfe649f6438a617d9e01c9de1e45722a4e5648a8dedace0c3aec1e8feec1df":"6e10e7e432bac9a665acfb8141":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 42 Keylen=256 IVlen=1 PTlen=408 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"d2bd5e6e13f91381abb10e6eede3ea17fb1fd88a82a6189dcaa9fbed00bfbf09":"7a":"":"be2b204981042832cb29cdc6f68be00e19460d1c091fa5aa0d6893552347fb3f7b88b44a593d8ea67acf8353c9d8616f0dc871":"a4b5c37b6ea846cf7c4074ca99b3bd261043537d76042f3e3224a800f3bba6b41b37bdc8e1958054271ab722c367a01bcf0cfc":"f8c84ff8f69043d09cf554cf35":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 43 Keylen=256 IVlen=1024 PTlen=432 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"65b7171b55b22edd711a076f2eb6a125e873993e8d54564cd62d03c665cd6374":"54d118d32a56138f04212684b1e47c5d6808c128996e1d6ebf739ef9ff138aac1181fcde820a5f68749e1fed791314c73c54169aee5556bf206998d95432719fc9ffe22fbbc4925f32774d31e075393c0907e27c3f40da02c424b402eff596f6300b881b8f561d5ae4535a1fa9d4bafe86dd6751b0da245ae7b74ddcc3f5033c":"4a3b04decbec0a549666e87036e78433b896270792e7932810c38eb063139ade6a4befd4dfdb38d53cdb95accbdee7ad5478c3bc55a21226c2b0fa79fe7c30262fa5383de3d3b45e951d7ef955f3a18b9689783898bedb66f0b8":"0521e41d827d6104ecdab1f8e7fb70cd8abca87500ecd36e65906194327b1b61014fd310f4e1bf7d5bf356a5d731c0d0d47c7e":"2ecf7a3a35abb50d212588c2ef50880212b53c052738767c9ea215709208afae6e94acd68980207bf63382495be1acde784b92":"49563e12797eefbee2fd75a1e844869b":0 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001 Vector 44 Keylen=256 IVlen=1024 PTlen=432 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"e175c46cb437fd92fbb91ef33b9c92545368a3068ab22ae48e97cb05c84231f5":"9ecac402b7342c2d55849b1068562ac78b2626e3346393b6587372afbac81cd7c13cf6dc3a479d61b9fc530b243ad80dd5516ea9b0c550b61fec571712cde93fa5265fb9a7f92eba7f846940e053a62324f002118867173490ccdbb04df41ca8e2c2c79f5ced7a815ab60e2b058f98e26c2a57424c02b923bea76bca75fc0d3a":"89d72ae1054e1b863d7188f462325d04d3a4afb2839a6c1d292d61c60980744b654fa2ac384cea33cdc5736395a606bc5be4e6ee9c0cb6c3e7b21eee8f599d773881ecce3c6ecca395cfbf226e3f36629f01d7fced0152dceec9":"d115a6e65ba9fb4435c059e675bedb73e28447e315727390f38c618e434e7056d2b92a53822e6b04dd3c71c274c1c00360f887":"c66a5c6900a9c132b2375129841df87238c88f1c59278c22126f1a59c0018f6526d1745dce387d23aebfa66aab1c153d3d0e1d":"b56663e0d82c0363b999864ea3d65bc5":1 + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 1 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"11754cd72aec309bf52f7687212e8957":"3c819d9a9bed087615030b65":"":"":"":"250327c674aaf477aef2675748cf6971" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 2 Keylen=128 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"09dc161766e7fadd5202a661745a7dde":"9b9d586fc84a525cbef2750c":"":"":"":"15963536" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 3 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"910385f6f07f9e57e483c47dd5206bcc":"518f56e33658df311d42d9fe":"5d157909a2a4607117e77da0e4493b88":"":"":"a7041ea4a1d74d9e66b9571b59b6a1d8" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 4 Keylen=128 IVlen=96 PTlen=0 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"2955ebf56e1310a309c8c2ed49e2bf26":"82c4f52740829745a416baed":"2f456b43a670474da515f14056f2d030":"":"":"407a7369a5a94288" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 5 Keylen=128 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"183aa33c3d5e0a33f79ce6b3dc75215e":"6f83a294e0d52cc1315488de":"ae73f1e18297256f15cf14a240976244":"":"":"dde53390" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 6 Keylen=128 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"7f6453b39bde018560a16a2704217543":"0f3eecf48d68353226a77fe4":"11e4ecb256ebff56453fa2e75e43eb9d641049e6":"":"":"b512623a12d5492b7d76d39be0df5777" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 7 Keylen=128 IVlen=96 PTlen=0 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"e5d017d52747f60d1b4bc45d54e7a165":"92c2de0fe4352deb16f826c8":"ddd55ed8a36d255491a127bf324aa40178f37f07088aedd814f796ce046d895084e4b8c4bc0ad3cb302a5a11dd3b0bd8":"":"":"8d6b5ca578f7fba6dc549e6eea" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 8 Keylen=128 IVlen=96 PTlen=128 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"3a422ad95edcb470d0524c12ddc5415e":"02f338926aa8cc00ccd8ea05":"":"80da029efbbe3fd1f553aa48f78edffd":"0cd0921a851b26436e83e5dd7e1df26c":"21a2926d5341e566a465785d8f" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 9 Keylen=128 IVlen=96 PTlen=128 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"af2904e234458af8ce0d616866c981fc":"ef6381fdeb7877845f46edcd":"41946f4a8304875ab3db0dec08d6c990":"13836338abcfc03b89dd93f1dd691b01":"b13b49e06b9e615a86d4c17ac10da212":"ac8af4dc584da9a6" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 10 Keylen=128 IVlen=96 PTlen=128 Taglen=102 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"d3a8345c572023ca9bdc94641ff201a1":"180bd185a5ed15e731d3f388":"e4db3122dd3e4b9874ae296f9d9dc4e16da01ec6fd9278e8f4f8c2cfab00a8291fe7f4ae30e87244a78a010684adf8ae":"dff19c6af6684ed1f6f6e478d42564ac":"3cbbbd725fdb28ead07d35aca52e9e21":"9046680683ce1faf7a932a314b" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 11 Keylen=128 IVlen=1024 PTlen=128 Taglen=112 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"5c47f3e1dda536efd7c5a5339eca6fbf":"cf319c9189eb5bc78cf9976228976ea5dfb1b929e7fdb73cbc6ed95b142ee806f7e2b63895fac955509df1d387335cd6e0d71f71ed794ba64321175bc932a8004ac796c986159c63de45a02e07b601ef7a633172dbc04da1abfa8cb1ebd3bd69c8fa1bad9f4383882449fa47713f9d8cd12554656d497049bbb9d3c45d54215a":"ef0509caf26f9f3f313c2962182feb2e565ec253ced60821b7eb67738e83dbbdab2d3b1b0cff5d55e94726cf37a08b7bea12f5c0c406e4d528f9b3dc46668c70b08e742eae242a17a36b6d04f10d175703c2c0928bf8d525c97f":"043183e2b0e52b8acaf147b4a4c399ba":"ee79deeafdeb82d3e9a2f590cbf9cbb7":"4306ec87c10884233b4955d819ff" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 12 Keylen=128 IVlen=1024 PTlen=408 Taglen=112 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"357e9c3ab5323ff141bdf17228b80a61":"de8cd40a5db81e8b7083807a8a5c16d4808f48c52a56c68b77edb01b563f80513518eac2672c8f5524aa6e3850337233c693dec99a547cf6599dc33a6d89763e5f91d9a74715c9a635ed1931403b2fbec8be85f287506ed4bd7da3c6e2b25e29becf9466f4abdf3b0daa4818a7f31563fb5be7aba7cbd53c6522331fc04d4573":"863ebc2231af641f620f618567007847057146db69b1066dc1c4464d251729eb6ea3871d3e997e71a963439e9d81691a7196ddd439748e795a2cc62b8382a61e79863259cb643851f9a271130e0f9f54e15f0dc3ec8b27084c39":"995142af8870fd1c805aa9919f76485dc1fed5ead1e8366633ef09db5595c1a305bd10d945409148744d3998aba6434172087f":"fc12b78280d4a9eef7d536f2f5b3b3d63cf641e07f6b91332b9200d224632c5b1ee41ee136693bf0c26d569e998d9a09ad24f8":"c0f7d0e6" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 13 Keylen=192 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"aa740abfadcda779220d3b406c5d7ec09a77fe9d94104539":"ab2265b4c168955561f04315":"":"":"":"f149e2b5f0adaa9842ca5f45b768a8fc" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 14 Keylen=192 IVlen=1 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"2d302c528ccafabb4aed0c5efdde4245d1a3173285198a74":"87":"":"":"":"821a99d4" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 15 Keylen=192 IVlen=1 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"75023350d2957aff638a1b828b537aebe09a7215ea4ba710":"02":"320cd5fceafbcb412aef1dbc92ae7034fc54a2a1":"":"":"8b0a87241985085363837d54c47ae3b6" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 16 Keylen=192 IVlen=1024 PTlen=0 Taglen=104 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"7ea7992be6a1d8a5441cc0ae83295cc9ad118db828342e20":"dda6db32559f01be6b9aeeef9366393137e06323afdc9376c29fc5eb16c72958450fec510c0e2c0e36c3e94f85c1120506333ccc812c4b6fe231def459dd10fcc81d0c8807ca012e7a621be5aa9574a189f3c3185a81a262181bf7e5ae93fa96cd81bfddae44eaefc4ec6e4530ebaa57c594146268dbedfd6a0701ecbd916ba0":"1cce943c868d7c585a1ea119a3964136401d9846":"":"":"abbe23f645f24f48b99899cffb" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 17 Keylen=192 IVlen=1024 PTlen=720 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"78936a61415870c1b80288a60c11fe20c430f0377fddaed9":"f6588eacb6ca862252dd19501b1ca6453cf2f518aa38ed17b3439a4793146d8319aef31e709b4596ba4004003e367b581c5d4d859adaf64fd8eeac1cdf5c664ffca5e76ee66b3886a37a744e00b3bfc776f1f8e44ea04040d1fb84ec9e7c70a5b70397f2e46e69d916d758174e5614776bb25a36b6bae2451da33de69dc74c82":"110b28a64c7931dfeab4374cbc8b459f3ce0911aa8ff8c74a345da52195ab5b311e2dbc03f9483689f5352a12822a7f91d851197351d410400642b8f827837e518787f34c32229b73a7bb98a1dab6229dffdf87d4f380a743db6":"fed60be040c1bccd3556bc3ce6811d53668cc1b20b53b48bae405fa92b211523407b7558ba794a8e697943484253ac6d9d0c2e":"0ecd930de3884d827e99e7f13f36d179b5f09bdba67a267abdbfa42eacc318bc98da6eac8ceb05f35b586375ca89e0176fc9d7":"de05bf27" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 18 Keylen=256 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4":"516c33929df5a3284ff463d7":"":"":"":"bdc1ac884d332457a1d2664f168c76f0" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 19 Keylen=256 IVlen=96 PTlen=0 Taglen=32 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"28c0ce6335c4f2db381c983d674eed78a5a912431d68a3ef0243c33de53f66d2":"3aac8e3550c4ba9882cd72f1":"":"":"":"7c12c543" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 20 Keylen=256 IVlen=96 PTlen=0 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"aa93adef2c80d27ecb4226106f41ffc6f934dab86c9e6e9b52e0ae14132c3652":"deddca07ffe8ab20a814806b":"340d2571dd9b2223b6575f5ddff31fe0":"":"":"47c215ec7c6330855dd5788c02f7" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 21 Keylen=256 IVlen=1 PTlen=408 Taglen=64 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"04c45ff622008bedfc3a77f763e8d251f7394e79b1e0feabec45697098f9b5b9":"98":"":"2fd5f7fe0d95810e6c24ba6539cbb0ab7cde765c829aa59d97dea6a70e8b8f0aa93b651e1a301998d44bf0138bdd5472c484da":"6f404c410090dc368f6f183de9a70af9d85a644edfe649f6438a617d9e01c9de1e45722a4e5648a8dedace0c3aec1e8feec1df":"6e10e7e432bac9a665acfb8141" + +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002 Vector 22 Keylen=256 IVlen=1024 PTlen=432 Taglen=128 #from NIST +SDV_CRYPTO_AES_GCM_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"65b7171b55b22edd711a076f2eb6a125e873993e8d54564cd62d03c665cd6374":"54d118d32a56138f04212684b1e47c5d6808c128996e1d6ebf739ef9ff138aac1181fcde820a5f68749e1fed791314c73c54169aee5556bf206998d95432719fc9ffe22fbbc4925f32774d31e075393c0907e27c3f40da02c424b402eff596f6300b881b8f561d5ae4535a1fa9d4bafe86dd6751b0da245ae7b74ddcc3f5033c":"4a3b04decbec0a549666e87036e78433b896270792e7932810c38eb063139ade6a4befd4dfdb38d53cdb95accbdee7ad5478c3bc55a21226c2b0fa79fe7c30262fa5383de3d3b45e951d7ef955f3a18b9689783898bedb66f0b8":"0521e41d827d6104ecdab1f8e7fb70cd8abca87500ecd36e65906194327b1b61014fd310f4e1bf7d5bf356a5d731c0d0d47c7e":"2ecf7a3a35abb50d212588c2ef50880212b53c052738767c9ea215709208afae6e94acd68980207bf63382495be1acde784b92":"49563e12797eefbee2fd75a1e844869b" + diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_cipher.c b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_cipher.c new file mode 100644 index 00000000..180c8f9d --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_cipher.c @@ -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. + */ + +/* BEGIN_HEADER */ + +#include +#include + +#include "securec.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_modes_gcm.h" +#include "crypt_local_types.h" +#include "crypt_aes.h" +#include "crypt_eal_cipher.h" +#include "eal_cipher_local.h" + +#define DATA_LEN 16 +#define DATA_MAX_LEN 1024 +#define MAX_OUTPUT 50000 + +/* END_HEADER */ + + +/** + * @test SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 + * @title Impact of two updates on the encryption and decryption functions + * @precon Registering memory-related functions. + * @brief + * 1.Call the EAL interface to encrypt a piece of data twice, and then verify the encryption result and tag. Expected result 1 is obtained. + * 2.Call the EAL interface to decrypt a piece of data twice, and check the decryption result and tag. Expected result 2 is obtained. + * @expect + * 1.The encryption result and tag value are the same as expected, the verification is successful. + * 2.The decryption result and tag value are the same as expected, the verification is successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt1, Hex *pt2, Hex *ct, Hex *tag) +{ + if (IsCipherAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + uint32_t tagLen = tag->len; + uint8_t result[DATA_MAX_LEN]; + uint8_t tagResult[DATA_LEN]; + uint32_t outLen = DATA_MAX_LEN; + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt1->x, pt1->len, result, &outLen) == CRYPT_SUCCESS); + outLen = DATA_MAX_LEN - pt1->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt2->x, pt2->len, result + pt1->len, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tagResult, tag->len) == CRYPT_SUCCESS); + ASSERT_COMPARE("enc result", (uint8_t *)result, pt1->len + pt2->len, ct->x, ct->len); + ASSERT_COMPARE("enc tagResult", (uint8_t *)tagResult, tag->len, tag->x, tag->len); + + CRYPT_EAL_CipherFreeCtx(ctx); + + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + + (void)memset_s(result, sizeof(result), 0, sizeof(result)); + (void)memset_s(tagResult, sizeof(tagResult), 0, sizeof(tagResult)); + outLen = DATA_MAX_LEN; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, ct->x, pt1->len, result, &outLen) == CRYPT_SUCCESS); + outLen = DATA_MAX_LEN - pt1->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, ct->x + pt1->len, pt2->len, result + pt1->len, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tagResult, tag->len) == CRYPT_SUCCESS); + + ASSERT_COMPARE("dec result1", (uint8_t *)result, pt1->len, pt1->x, pt1->len); + ASSERT_COMPARE("dec result2", (uint8_t *)result + pt1->len, pt2->len, pt2->x, pt2->len); + ASSERT_COMPARE("dec tagResult", (uint8_t *)tagResult, tag->len, tag->x, tag->len); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 + * @title Impact of three updates on the encryption function + * @precon Registering memory-related functions. + * @brief + * 1.Call the EAL interface to encrypt a piece of data for three times, and then verify the encryption result and tag. Expected result 1 is obtained. + * 2.Call the EAL interface to decrypt a piece of data for three times, and then verify the decryption result and tag. Expected result 2 is obtained. + * @expect + * 1.The encryption result and tag value are the same as expected, the verification is successful. + * 2.The decryption result and tag value are the same as expected, the verification is successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt1, Hex *pt2, Hex *pt3, Hex *ct, + Hex *tag) +{ + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + CRYPT_EAL_CipherCtx *decCtx = NULL; + uint32_t tagLen = tag->len; + uint8_t result[DATA_MAX_LEN]; + uint8_t tagResult[tagLen]; + uint32_t outLen = DATA_MAX_LEN; + uint64_t count; + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + if (algId == CRYPT_CIPHER_AES128_CCM || algId == CRYPT_CIPHER_AES192_CCM || algId == CRYPT_CIPHER_AES256_CCM) { + count = pt1->len + pt2->len + pt3->len; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + } + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt1->x, pt1->len, result, &outLen) == CRYPT_SUCCESS); + outLen = DATA_MAX_LEN - pt1->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt2->x, pt2->len, result + pt1->len, &outLen) == CRYPT_SUCCESS); + outLen = DATA_MAX_LEN - pt1->len - pt2->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt3->x, pt3->len, result + pt1->len + pt2->len, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tagResult, tag->len) == CRYPT_SUCCESS); + ASSERT_COMPARE("enc result", (uint8_t *)result, pt1->len + pt2->len + pt3->len, ct->x, ct->len); + ASSERT_COMPARE("enc tagResult", (uint8_t *)tagResult, tag->len, tag->x, tag->len); + + (void)memset_s(result, sizeof(result), 0, sizeof(result)); + (void)memset_s(tagResult, sizeof(tagResult), 0, sizeof(tagResult)); + outLen = DATA_MAX_LEN; + tagLen = tag->len; + // decrypt + decCtx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(CRYPT_EAL_CipherInit(decCtx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + if (algId == CRYPT_CIPHER_AES128_CCM || algId == CRYPT_CIPHER_AES192_CCM || algId == CRYPT_CIPHER_AES256_CCM) { + count = ct->len; + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(decCtx, CRYPT_CTRL_SET_MSGLEN, &count, sizeof(count)) == CRYPT_SUCCESS); + } + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(decCtx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(decCtx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(decCtx, ct->x, pt1->len, result, &outLen) == CRYPT_SUCCESS); + outLen = DATA_MAX_LEN - pt1->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(decCtx, ct->x + pt1->len, pt2->len, result + pt1->len, &outLen) == CRYPT_SUCCESS); + outLen = DATA_MAX_LEN - pt1->len - pt2->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(decCtx, ct->x + pt1->len + pt2->len, pt3->len, result + pt1->len + pt2->len, &outLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(decCtx, CRYPT_CTRL_GET_TAG, (uint8_t *)tagResult, tag->len) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(result, pt1->x, pt1->len) == 0); + ASSERT_TRUE(memcmp(result + pt1->len, pt2->x, pt2->len) == 0); + ASSERT_TRUE(memcmp(result + pt1->len + pt2->len, pt3->x, pt3->len) == 0); + ASSERT_TRUE(memcmp(tagResult, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + CRYPT_EAL_CipherFreeCtx(decCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_AES_GETINFO_API_TC001 + * @title CRYPT_EAL_CipherGetInfo Checking the Algorithm Grouping Mode Function Test + * @precon Registering memory-related functions. + * @brief + * 1.Call the GetInfo interface with a correct ID, set type to CRYPT_INFO_IS_AEAD, and set infoStatus to NULL. Expected result 1 is obtained. + * 2.Call the GetInfo interface with a wrong ID, set type to CRYPT_INFO_IS_AEAD, and set infoStatus to not NULL. Expected result 2 is obtained. + * 3.Call the GetInfo interface with ID CRYPT_CIPHER_AES128_CCM, set type to CRYPT_INFO_MAX, and set infoStatus to not NULL. Expected result 3 is obtained. + * 4.Call the GetInfo interface with ID CRYPT_CIPHER_AES128_CCM, set type to CRYPT_INFO_IS_AEAD, and set infoStatus to not NULL. Expected result 4 is obtained. + * 5.Call the GetInfo interface with ID CRYPT_CIPHER_AES128_CFB, set type to CRYPT_INFO_IS_AEAD, and set infoStatus to not NULL. Expected result 5 is obtained. + * 6.Call the GetInfo interface with ID CRYPT_CIPHER_AES128_CCM, set type to CRYPT_INFO_IS_STREAM, and set infoStatus to not NULL. Expected result 6 is obtained. + * 7.Call the GetInfo interface with ID CRYPT_CIPHER_SM4_CBC, set type to CRYPT_INFO_IS_STREAM, and set infoStatus to not NULL. Expected result 7 is obtained. + * 8.Call the GetInfo interface with ID CRYPT_CIPHER_AES128_CBC, set type to CRYPT_INFO_IV_LEN. Expected result 8 is obtained. + * 9.Call the GetInfo interface with ID CRYPT_CIPHER_AES192_CBC, set type to CRYPT_INFO_KEY_LEN. Expected result 9 is obtained. + * @expect + * 1.Failed. Return CRYPT_INVALID_ARG. + * 2.Failed. Return CRYPT_ERR_ALGID. + * 3.Failed. Return CRYPT_EAL_INTO_TYPE_NOT_SUPPORT. + * 4.Success. Return CRYPT_SUCCESS, infoStatus is 0. + * 5.Success. Return CRYPT_SUCCESS, infoStatus is 1. + * 6.Success. Return CRYPT_SUCCESS, infoStatus is 1. + * 7.Success. Return CRYPT_SUCCESS, infoStatus is 0. + * 8.Success. Return CRYPT_SUCCESS, ivLen is 16. + * 9.Success. Return CRYPT_SUCCESS, keyLen is 24. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_AES_GETINFO_API_TC001(void) +{ + TestMemInit(); + uint32_t infoStatus = 0; + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES128_CCM, CRYPT_INFO_IS_AEAD, NULL) == CRYPT_INVALID_ARG); + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_MAX, CRYPT_INFO_IS_AEAD, &infoStatus) == CRYPT_ERR_ALGID); + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES128_CCM, CRYPT_INFO_MAX, + &infoStatus) == CRYPT_EAL_INTO_TYPE_NOT_SUPPORT); + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES128_CCM, CRYPT_INFO_IS_AEAD, &infoStatus) == CRYPT_SUCCESS); + ASSERT_TRUE(infoStatus == 1); + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES128_CFB, CRYPT_INFO_IS_AEAD, &infoStatus) == CRYPT_SUCCESS); + ASSERT_TRUE(infoStatus == 0); + + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES128_CCM, CRYPT_INFO_IS_STREAM, &infoStatus) == CRYPT_SUCCESS); + ASSERT_TRUE(infoStatus == 1); + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_SM4_CBC, CRYPT_INFO_IS_STREAM, &infoStatus) == CRYPT_SUCCESS); + ASSERT_TRUE(infoStatus == 0); + uint32_t ivLen = 0; + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES128_CBC, CRYPT_INFO_IV_LEN, &ivLen) == CRYPT_SUCCESS); + ASSERT_TRUE(ivLen == 16); + uint32_t keyLen = 0; + ASSERT_TRUE(CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AES192_CBC, CRYPT_INFO_KEY_LEN, &keyLen) == CRYPT_SUCCESS); + ASSERT_TRUE(keyLen == 24); +exit: + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_cipher.data b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_cipher.data new file mode 100644 index 00000000..10a97690 --- /dev/null +++ b/testcode/sdv/testcase/crypto/aes/test_suite_sdv_eal_cipher.data @@ -0,0 +1,173 @@ +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM iv 1 bytes #1 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"71ec6b47a9ffbf029954639e9afd87d1":"ce":"a4ec7b8f76d03bd91b34b0626f41df0750aff0b46d63946c05b51698232583e68db0fa25aef9b44eea774d3c9041013dcc5c753905fd068753ce36d34624d7dd100984c1668b8e19fca7dfbfee2262a25788660ce18b1acba8c5":"e50a45fbea6a3acbb5dc8ab2ddaa6d1d6249f339e1ef":"8484dbcb0c1cb63277322e60ff9d2416b7782f03eb7e3835042e3fae7f":"74a26e7c3af4c329629c54827ff6469401d642b426fb52a5ca7342c7874a69dbe2b9ff035d599c9d3cf1a0c0885bd6113a6b47":"cff5c6af208bc567ab8e5408c9edbbaa" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM iv 12 bytes #2 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"55c8bcb0021090e4b2c785c79cb966b8":"5e9f1313282f73d7ffb92837":"f7e14a57e3bb6b99866b90573d7bc355baeb7ac347e43d0b65d97ecc2eb9c772401a8e3c7e9e2871c2b79579d44c139e62c33b42a9e0c87686960009d659d5e3874e168c334b6650c6d36168633757a7c20764232ce94a0de1a5":"2d7c1b689189bbfa2be26ad5c1f296dee4c0f61456":"ffc94cf8e70aad0f09d0608c4115aa6ed5eba93ed5820b3f3426bbf4d64a":"ba59002df3394c5b80983519dc163eca5c44df80f8c4c4e15d3ff73f13c170c80a59d87a2165a7b450be01031a8e41c505c89f":"28418c564731bddf3d504d8ed32e66ee" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM iv 256 bytes #3 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"582852124b2b7e4cfc654e355b3c2bd6":"daa938dece40bbe3f0b28a8b3533b52e57cc2ae780967fe22db6d0943b8d8216cafe870661a8d4832673f4c7319fb7e49b41f0e0a05bd6ec1a2b9e29e7fb1868b6dc21826a90d7a2407a5226e80ab41482cf371892335bdfd0bd82b9de2c65bd572d9d5a03951bb5b020e9e8b20b6412cdbaf4efa1e832a1bbe865859fc6f62e":"aa2db227922e706564879adf4373e02419f037c8":"735519a3f923d194":"db26c4ae90c04255":"414c1bf480110fec1c6668759842c16e":"ab3b314e5cd83521c2ff22ec54e7e0a8" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM tag 4 bytes #4 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"9eecfbbc96a6b7714198acc8e3552ca6":"c9a9e65ec7e3e97a8703b9ae":"55db7c0f956f195f1ceeb8718eafe814":"8e14d8f1043e758a729b26":"a73f3c91783241e86b8566619e4774cc68629ea063":"2cbfb1e294c6cda1755a95935dd0c1018ed5a41657327def97b340f7f05e6403":"d8cc1616" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM tag 8 bytes #5 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"635a0f7eab3c71e3ad48e5c4506f7742":"994861fcc7ef50645b3aac55":"3b2e26969bf03f21e1280f4e82a83fe1":"830954b9e4f4fcdbaeb0f5bc2a52004d64":"9923e980cc9c94e341856c8331312e":"da59b59985f8c60ee12f3e26efa733a4bece1779a93178bbb6ac72aaaa86afb5":"359dc33fa9d449b2" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM tag 12 bytes #6 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"b69335719fc1e6b957c5dc83ccf4752b":"ba89a407245bf4bb36a4b3aa":"b1a25cc6c1600b2e067f45317a74e2428b124a17":"ae63559354f2e4e1e8714e67963599":"0d3bc3146d9ce1cd3060c5e3aa916e75fd":"705a5716ec3a82893b226e19620e8c4726a26121e7cd91a6db74cb2b62938132":"203c4da43660aeacdf16a3f8" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM tag 15 bytes #7 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"2a7980403aed3182ef9192d2328f9f44":"737b795c21601c01ba7c2b49":"580e1fcfb4e868d1cd744963217c0fe8ed5aa1bac7c3c16afd0bac383d167fbb1108a9c85cff465fa8c960a0c34bc764":"30792c17821d876ce6b4dd7fd9dde2aa":"0bafbcc979f615b1e0f8b6492d0a5dbc":"a87ac267c27b8831314d2a80c439f0e17c3960c43453309d1751f6642ab99f29":"c352e158bb308a586c706f4fd1d543" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM aad 0 bytes #8 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"27f4738cfa2673ff652db8a718f51d88":"487472e57544c9fcb3ff7f46":"":"f5a02afebd2abf":"46619a0687607ce5c1":"ffd71804a0f01465d30f2a4c3c50bd14":"379b9e525850b511250baf28e461" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM aad 16 bytes #9 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"077162da5ac279569ce56712bd0c2277":"3b40263ce7383e8ece9904c1577cfef1bbbe8f3e0af164a233aded941d7434e9744743ec97ca2ec67ef54b6256f734c7202cc8474f399ca59afddffdf60c40fac64e4acfb49c0d5ca1d35d85fd79c1cfeb88ddd2c61dd2baae1e995dfbc63d8e21029a76784d24f5b67b70d6a65dbbdfd6084ab05da556e7a3d4170b9b6cee7a":"30a67fb5838bd324a35c646d5091c5e0":"7a56c9394cc444":"7daee936fbe63efe0c":"01bf4ddc12dee1e6b437d512a8bd44f2":"0bea45a8" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM aad 20 bytes #10 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"47556bfe1af810c45cc17e240a02e414":"6c1b80f937d0e4f29a928da82bd4184d935d14568da57699f028a4485f55a3fb380998e4a5e923d31d5511dc6802e0a82e8e30c1b8d6d06f1ffbdf93a39df854e5877ea811ace228298f80f972555942082007a464dfc9d63c54afbb3b1fa68ed888d339e33b959e69a2134f460e00fec6a0ffd8a84780e403853eeb9fc46266":"35728eda89d47115f18edbc4f42258fcc141ded1":"73ae28b3d790ecd6":"aed7f634c471571a":"ee35b098558f4cc9da03d8f3e05e6aff":"072303ad6abc235176a85f1b826ca187" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM aad 48 bytes #11 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"ffb9121327f14a5ef45538183c00632a":"d9b33e7db0cab3fec7a0eb6e50c9d2dabc4f106e8e8019916a7d7a923652f48c2a728bc9e20e49533ae90797cec2f81bf69c0e26cf4b8ac7f2ba5ca1a2d0236cd072d8827df5dc9e0d637630c95d8f9b551ae6db39b331d8fc913d1f5464813bed0e99e91338f75a94cab8d67d6f290e959f4d6679319062f97449b1cd2543cd":"f9a525714be54a31d5ed04f7f05eaaf160940948a625fd9dc5ebec6039e9c67c9459f73bc4b6b50affb232a51ed7f0a0":"8462f4d698278c7f":"da0035c6c1d9efbf":"e944a942fe0c9fafbb69742438fcebf4":"a5a5fd08e6dc463e15f6070f" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM aad 90 bytes #12 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"66bbadef259666cb3800267d52ce9070":"c26a06675350e411359ba64a3de998885fe9e856e15f3d64cfb038f62287dd4d2f95fb9e968a6ea375ee9b8472861c9a958b9df74c13520c478bc74ce821efda7ea11b9a1cd4f1a74fc9c7c3613db80e989977612892d862f75519ea8bc6441f01c598ac98639bc4d1b09d11bf40c92e0dabfba4008e067e525840478456ebc4":"c27ca115cdcf014a0633fb2e7646b6ba84181f001fd94c2b8342d79d53d1049802eef973f5c40c0aafca8564fa820a7caa128792d20add75ee9b5c458e286d53c21fc6c129c21d9f51bbe8c2aa4374c4abeb9bba7290bdee60e7":"8cfbc3c949d75f":"62e369dd88e6e33eb0":"be09fb3a97ae42c1172aaad7ac6b53ad":"3facf16628d406423dc879e948cad068" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM encrypt1 8 bytes encrypt2 8 bytes #13 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"84d3fd6f867f08362a4c2d6620467853":"d2":"ffd5826c17d003143a667d55c37b0a95fd13e8dc":"70e939ac3a071bcf":"be62227b59f939d2":"ef8cd3481a939b2539f5d0c0d7575ada":"784de38f" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM encrypt1 17 bytes encrypt2 15 bytes #14 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"7f2eefda5aa4bf77660232ff68b6267e":"3c":"4d4361e8eeda1142e0df0ce16a598ae1edde3fc5":"8d4d1c34169435463da030a593a0580a26":"01e56688697bd50499c16574edac95":"455fef6abdf58f3dc6cb0a67ee30f7ed852857a629450ba18c6e310b5b5c518f":"1d20211cb233cc29754ae2ecbb2f" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES128_GCM encrypt1 25 bytes encrypt2 26 bytes #15 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"3db93df51159d0e03de2a340029a7d47":"4d":"d24e7ae349bb9c094eb2254ff7ea1679":"8070c70be4a901e51d9ff6317a681eca79f2f7c3c25740b55b":"ecfc1440af349c066a055d68bd090cc9ecd8fc36d236756df029":"0fed81c9ddf4373bbee77b7e2b74d3a189c4819b431b7362626e363ea11ae9c4a1f56acab706dd2f5ffc472085bac93e2711d0":"6e7a78dd38237abab2e34335a4670f" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM iv 1 bytes #16 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"d04529567ae6e9cced3ca2cf5f82c2a77c4f3da8f1211cf6":"c5":"df0172be23b4d5baf88ee0a8bf0f255c1cad0b7b543697dd4892b59d42d1113fc01ca03566a3c01102a76ae0e3e291d8":"f31945431601eda93663e7e0f9a3bd1b23ea57f113ef6e":"c44c27b397b4c964f8587ca06c4f823ba2cce85b5996be64822592eb":"fda6a93b8ec3108c2d5ca3dc7b24bdf9dcf4c9bf793027b491fede54ef918b6a28e6603fc29dd68047107acd0d32ea9c48d04e":"10857efe" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM iv 12 bytes #17 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"8f1da93e1ea876d9ebeb079c40763448f6b20bebc378a1fe":"739eca541d96c6e1167cf6cb":"a574bd8150d376b20d09e752df5d778f":"92c5566b3b4afcb076f50495ba7c2e71205a0ea7b7a630":"8f8cfdca69fec8b5ce1352d9e62c225545384cd079530fb359f596b2":"4dc3d7a170380d7f4719b38670b7433cc12564f8865c2e018cae13fd31852c49cb2b4b9068ce2dc0f71e4e8431de2242b80e8c":"3c8083baeb7dfd0d7e2aab679a5bd9" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM iv 256 bytes #18 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"cfff5791abb31f69b818f1b2555dfd3025cfb34f6eba80b8":"36df8cdeb7c201cc7c0b57843039bade7acac1ba433ca5b853ae755fe717f7cbd9b292cb17ce97641452b40d4f587431b893b2aeac757c52f7aed405b8228f58b4e1b3ecad6f34ff263092b33017fbf00c0228be6fc59f9a7b46b3429dc24047cf230c61ac2ccc241a8e0868fe01951566ac56fa9a572dfbc461d5acc38995a8":"88edfa8f30612e1f0543622450869616fad3315e":"b60632a2bcab2c787b":"9dea7ef52d3ac5":"936b746d0c4f5f31aeb8fd9978834a97":"b4225079e9b3bdb5bb549386bb4935" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM tag 4 bytes #19 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"7b9ba9ad82928d25bd56e88ed385696af88aa92a7ccc39ad":"61bf1787db54a4267d299b0b":"d585c4497c207a058823fcec3e09a6ccbe98a10c":"6d2f376a4a4fc7bbcd":"93ead9e9222227":"6b31526d7d2c5e940bf13acad7840437":"f9862143" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM tag 8 bytes #20 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"d93a469ca1bddbb69e65397766510f71b66f18906a3355a8":"08b00a23d9e23256b2549494":"b4a5aadea29985349da0e7f5385c8591":"ca6b60ab56f72fb9c670c7c3a7d0fbd97b0748c0eba519":"664eb0c3325cff4f971816de215b84c9a40fcd29267778ee94655f00":"cb47ab9254b46a42930e9b44579121a5c9a429eeb4d97895d9706ae4fad838a424d67480de0d59f9fdfc4c7e471e11d4893e99":"85029eb9534ac4e0" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM tag 12 bytes #21 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"7f093d043333ecc0a55c64c191cf2df1865dede82c95a9ea":"842c72a014748bd4dd93cf47":"b9e79df905d53a9da39c02a34c75e5f6":"6d6a9aa271e24d14224eb02dac1fe9a023b721e7":"be19f8a8b5c4be14fea6bbb0c14ecde309affafc8541989b5da71343e3fc6e":"555c46837822cae3a4de14e85b62124848f081e47b167a39213ab9eb94999a76831bd8895b7e9d7a18980c325ab97ef3544346":"833760fa5f233c883975eacb" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM tag 15 bytes #22 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"0d9592ced9045d04e8da97cc27f3aaeeaf1250a741290399":"acb68da9411fd43a5f44124d":"ee9d67a14553bbf488866f9b052bba0a7bf09463":"97e9243c9b8a84a7009007e62ff976156669bdd412f8256027afad9869eb25":"3410f0e7d037eaec4b96a79d03ee35e3c3d2fb4a":"0aec7a89008a7480bde000f4047b3c3edb996f94f3c42f46b088c66aa960f18c7629f3bab2d21d2bf38711a9af10f4f25e7a16":"f4620a1804cfeb9b986e85cd834b0d" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM aad 0 bytes #23 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"62f890798656e93f6f864139927a1b2ea74ec04bcda761b9":"c431c5739014251ec77dcefa":"":"a345c02b9742416caaa3e2":"24003f38a9":"124981026aceecdcf4616a744fe9a9e9":"0da3a70f3346af9da65eac826b582a" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM aad 16 bytes #24 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"a675822b5bd67d9143009305b6b5d45ab16fecb8ba82f254":"c0e2e0e74dcba8e43fd14405":"2572fc4de6d1e9c3de169dadbdb92238":"886b79958d85ad5d8f8d33":"49dbb9581bf43069705f72e10555f978673e0aa9e9":"e51989f3cb101a365c8e279dd0d785a007bcdd7bf19e7d5065b7bcb3d911a0bc":"f2b877cc7411773751014a5f3c0f" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM aad 20 bytes #25 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"9f4eb52727f936b410aa1d4d40d1a98cf0606c4dbe0ea60e":"9ee32ef124384cf93aee03aa":"5897c9c4150fe0e29a4ce001e218a02a19934c21":"97348920686da0e1361d36ad3d3f7d90":"52112a494beefbba8bfef054a1ff903c":"d42d308886f99eb083f86a1b5d68e60f8a250e7a7a05cbc1b94428f171cc6949":"f9f68ba56630b065783398d9735f7d" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM aad 48 bytes #26 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"5916a792fd543bed4ba2ebd855ddd01bf62349356171746a":"49ec5907d12dc29ef64ea87a":"e22a9ef66a6ade86c81de9246ae30f5d8ff86033796450c0e0e4501161acdcfa6d93eaeef2238273e0b771dff0e62476":"85051097d4357a88dc386a950a864959b06f59d48b7a":"860e17515f5b71b71bddcf7a34811050fe905f12b97ef21c0f6c6de524":"2e11d9c73b9b3d92e75e3c2ee2bea89bc6a6f5cc51f77cc4236199efb66ac5f58f8683852142c535caf597eebe340cb5b17d70":"e94218c49d86e280c18fa02c7670" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM aad 90 bytes #27 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"e4c235d520d3d2aa1dcf8ace2555fcd2a43731fbdde35b1b":"27fb77d2a20f69c981c091ca":"9e09f134cac886036fbe60eaa32f3a0032358795b8422671dcc9d5e0f5ab82c0aa09a4ace5a3377a35378459fbee50f5367e136dcdf1a20b07d4669b9d85d6a4be5b125e9a620d503664c83956e9bb294743c05c26154c74b934":"13194ff89d45291ac7d9e8883d5af8c03b542f22c888b0":"36dba42b8608c7153ef097402b5dfac5baa53337f640d3b6824f0d01":"9c0cd80ee0f79065c74bf45ec68d30e6e27e108f30146cecafe0dc18c8a7c4475dc25a381e5d068a4c45a1e99d28bd1fb04b0e":"0dfeab2ae542416d" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM encrypt1 8 bytes encrypt2 8 bytes #28 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"a310267f0db958b383dabefb0f53727afa6560fe347dfb68":"39e1bcb37cdfd55103a76ffb":"b9c440ac5643035ee941628735edda19":"9c816250c1ef2997":"0f4360e6f02ea62e":"36510344e4bfd72c2d6fb51353c11e26":"3e8db9fbcfeac08ea69360cc79e2" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM encrypt1 17 bytes encrypt2 15 bytes #29 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"b33c5528be7443a7d1cf3ffeabd4d7cf6e70cefabcac45d5":"6fd2bf3432507327b020a5fb":"f8f268c69aacdde208c34cdb4a92f087":"1fc260366c9bc23f74ffdbe1bda3e4528c":"b932252f96c05b55477d354b12311c":"edc274c5bf4def24dd4bf06bb9762084f325a98abfedea7e73cb84bfec1d1f13":"d1849885e92692ad8dbaeb691c2754" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 AES192_GCM encrypt1 25 bytes encrypt2 26 bytes #30 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"ca488c540de5c82adbc75e2e2702d386f05103e2246618ad":"0942f31a9f35516b70cf6c9e":"8085a482236c94e16cd88bdc8ed5816c":"a690be1a3a94efcafe610f135706cc8d8cea80b01b5e":"3402250884975fe4baa4d740c83c7980f6cebd4fe8c7e05a9f028bd418":"01ac6435020453939e3d80da26028d72a9172668e690d198f830bc2333e71d97b106e70db4683c276e3beb8971d882295f55c0":"930a2c0d3697cafe2822f6373f74af49" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM iv 1 bytes #31 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"44ccba277644bc95a53ee833a89a59398e1c3037f631b3962d524e6b74d0f6e7":"f8":"0a978477b38819dafb4915e2feb8b373933cb58396e1622b9a6dd612730c709eaeb76da354c1e77eda526300431a51743ceb8cbf7d794804cc58647f1f0cd3e389918f41a3d09f25e215df18c7340287a65d68bb526d6dd55059":"2ebbfeb80afcf665fc5c741ca8ba91b696d49d3bbc":"048a205b6cb93d699a1c5abea81b3c58aaaac69c3bd54b6b6f2b8307d2f7":"d6049403fada8207d4c37356c4ffd84555d46198b1209762da71b3177a9af5e12e96e9abced023d063858a502c48bf3ed44141":"15b05b53633c98d374b872619e2cd6" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM iv 12 bytes #32 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"52d0f20b0ca7a6f9e5c5b8549d5910f1b5b344fc6852392f983558e3c593be24":"d5c618a940a5a5d9cc813f27":"61823f7e39ed76143ca7249d149bdf57":"a9fed8a29355685321f978e59c4013":"5309306cd41b25349fe671dc7990951c68":"509c540e558d0bf0a3b776cddfbfddc15486748a7f9952b17c1cbd6869c263f4":"42e35ee3f7119f87fb52b5d75b8ab8ec" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM iv 256 bytes #33 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"bcd2b2caafb88ffb26484202a07617ba15f2d5cf94f3d22d12bb221a32d8f3e8":"a082ee045c541bcfc09f661f8204e22c427e370af6934d5f8f7d2048a38dc2d7d37dca88c77a135c3c650e5feb58322d375de2511eb65043578e5067a921d946c6b03aaf859cef50a1c9574ec638f0314df2c4d00364f68936fc0deb1af4b6b742bda0678d6355d83188cdf05111240e028f29cabf2cd5ea603b5c9e8d6b73f2":"be0a7311d148432ef66a2868b607982a":"319e480d026b8b64b69a9d279c3224":"0544077eed32580bec72bcb7ab2101ce53":"e8b7a2f00e48e4c31113d799a66b6c69e57db08a66d2adb65ce8c5afd283f36a":"0833522710cbb4db" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM tag 4 bytes #34 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"501721500b9c5a4a650f9be174e98075417e5116f839199344a5a8fae1d344f1":"d8e29505f294ac2bf390f6a9":"ea5d97424deb24c55b00df3e367f45b8":"c2b1c4bf71e92cd5868b":"3ef3576528c396df8f54fe7ff1a43397cc4b40f42ca5":"8bebb57f138c8ee7f91261e9fc48241ee0528e68a059b4515baa3cc5d744f7d3":"94e435ee" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM tag 8 bytes #35 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"60d1f05ae0631fac68d81a464364e94dceb830d535bc2ef8234ea2c593041556":"e042ef82d8d39fdd7d40448d":"983ae48965c6d04e9db65c7055932ebb":"227b04d4b7abd0db1850c046c174":"131e4f4a09bd9b6492ea729d7153e811d6de":"69f1704740c1d4ccc74d7e7e9c82ae08393275932b894f400869a77d4b120946":"3ffdaff74cea6327" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM tag 12 bytes #36 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"657a7dcbf4b5473139dbfb00f67e0f83d4b26f7a565cf80597ad34c92d7bb9c2":"19811d472b698c9dd5d6bd02":"6976c13fa64244e2529fc89192ed8845762fc04a":"0d3672de07f20e36733fd324ec1fc25e":"3968a9a9466bbd12e6002de528fd5fd1":"42221edd9dac0cef340c9ec6902054ac1a0712690af03d6ece54ae662f613b26":"fc4c9882ae256a6ee1b41f40" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM tag 15 bytes #37 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"0bde71108869fa4c933d91647af84339f711315f21a0bfabc19d76f9ddbb32ad":"1eb019d8ec43069cea0eebaa":"90510d59e410dca586835a39daa0a31966c7994a0170a0995473e802a62760bc1dfbc87b7df14769e4202185350a21ab":"08890cd73f8949e588f01ab00fd9":"32aa30a3f6bf8e8bc120391ba6cf03ac5047":"a06ec3ef3ab5b3ff1f36c69b7dcb301f60b316cb51a240108834d3fdc07c5c20":"08fc98dfabd7aaad2b5c5ba4fbac4b" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM aad 0 bytes #38 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"a11c01bfe13775982ac35d9573c97c31241e0803a230b35c5ac49de92fe6f897":"5c4f01533096adeea21e5272":"":"60a39f755a9c490a2afcf497843f6d":"330145cf0b9d8823358630be2a1e2c8260":"e929f3be8dc874a9aeb87c1d1046ee2e517c67b96e23d641388df91f0b3095b8":"fd4d29be18addf2eedb6146cb565" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM aad 16 bytes #39 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"6627aedfc0090778f1fa9aad4a8f0af66d916425344cad0c3b524c81008dbb55":"25e1bb07e976a2b0c78000a0":"fb46d320e8ff521b886f3729d8defa3b":"f629177f502051a1d3c703dd7f2fb076":"3d8519e7b3a4438d0512ae3664d6e4ad":"b6193464d5885c0d88d767ede0c602fe1f11cb7a829da4df9c66cbff5c998cbe":"9124e6c0476c11292abdb93a" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM aad 20 bytes #40 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"3b4eb08d27ae0b77605ae628a1b54a5402026550679fab0a20752bee510d3d92":"28a20c40f49a00493da3488a":"0591390e2d14ebe62aeb1741c26448ce55b28cab":"c8a47edcf84872f53f96ef41ce05":"ca37cbc3854b556d6e606f0a8a32d0861907":"a3e8cbf84df8529838f79315c7f1a0b7bb3ad4c4d036ec317b1810b274ee3080":"0a8f66daeb7f0a88756909c4e93fcd36" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM aad 48 bytes #41 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"92204eb6d03da31a1387ef75505b3caf13004fde641a8767a0297a4099b5c363":"d4d922e747a61697e4db77fc":"2a506fdbc1677fb94d72c13cca8867eddfa6de62407fa12c368eb939f30cf3e199359257e370de6d524f7a322c027e63":"60852da492cb4daefb5ec0aafb05975cf497c6b77415f8":"c00e1730a5dd7a43ea":"fcc9eaef762d86f6e4062bd78d34e37f869d7447cf5ece35268435d1d12c4f24":"fdfe89ce30d61c3c730047e2f56718" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM aad 90 bytes #42 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"4330c98957d9f2ed1481f60a3a9fa7f3789a037bd4d75d1ffe079106e30c247c":"ac228ff45f48e30c080199ac":"3bcfb30547108dc707fb9362f6dab4422f394fbad68400ac5abf367912f7272106a34193b3ec73ec2e2efebac555cb364065a7a14a9eef6ac42f2519ebfc62d9c8762adf2bd6721d156b8023a3b6e915fae59ed480f840f230d9":"ad162e78bb63150bbb289b66b83047b7":"5c2bd83f03f57f281f4b788a34689112":"da3810c8edbea5992ef6dc9f304febc55239587f821b444bad4612601662781b":"bb690e2c" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM encrypt1 8 bytes encrypt2 8 bytes #43 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"47d19aa8f7ca6157961a46f2231bab041e16c077c566cbf557c7b671df5da45c":"514c97e7cb8ede27f220edb9":"432ebd5ad8879e39e7bd9caa7da5b9b67c23baf4369217e68df55dfbd0d1a7de633eabb0ab13da2b95ac0a1055a10eac":"17fcafb0d7f2ad04":"f35e2f4667dba3e8":"bf2d3fe5419dddcd755f49eba32641d8":"63bb16623f40d7d4e1ecf769" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM encrypt1 17 bytes encrypt2 15 bytes #44 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"84bacc03141d08469dbb813e808f81e7259547ca94fa438c8b9bfc059f4132dc":"d8aa7c28d2ebcd530dc245db":"fb1f489585052724baa76eb32c5bced6":"46072c60af248317750f9b4b6d2e4c44d6":"4f1bfb60c51594fe7fa94eea6b7737":"7b6bc3c5c4ba7419313a71a61b0136b9147a8838a69d86939f5d897c47064186":"3ae659f3ec1dc919389fbf9b" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001 CRYPT_CIPHER_AES256_GCM encrypt1 25 bytes encrypt2 26 bytes #45 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"9c746799e960d48292cced44c01a85f12e970545a210b6dadf0beb729acc14ff":"49b75f5959bf67de3a4f7e10":"db40921f33b51f43a9da59142661b034":"14d3779aedfcecec4d03f7d5a5dc3009e6874cff300fe6666d":"adb2c20235e0b5b9732b2e2124c5e1b811cd4ec1d83ac5d4d160":"6f1be9be8d3fe88d1c89069b7925bdb31885deeb3353109b6f56ef0528be8a2c4ae355efeb06f64361c8cced758cb95ccf2a70":"ec6c6d462338c7b4a7986f43d7858f" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES128_GCM encrypt1 7 bytes encrypt2 4 bytes encrypt3 2 bytes #1 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"0f4b821cc9356e7c3a22e28d268d1ef6":"4e1993e705ef1aa50e5763df":"df5aa8998919a2847eed89741608c119":"e0c38c248b3eb4":"f04a1238":"d3f9":"0dd424ff00848413577cee97cf":"745976a2e3de25919a88643a" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES128_GCM encrypt1 21 bytes encrypt2 8 bytes encrypt3 3 bytes #2 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"55190de13cfbbedf4a0787f9ecc34e45":"87803bcf6a69962abae929e5":"067c3857cc240c6bb5f628bcc7cf5559":"ee5da0026ce103140873226149b75fa734888b0051":"8aeac0224466bbb0":"d23d0c":"06362d236e9618037d31d4f1ea0df6064e0bf06b6c5904530e1002e8479c16fb":"342a27aea0ef0aa26ad92ea3a92afa37" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES128_GCM encrypt1 48 bytes encrypt2 1 bytes encrypt3 2 bytes #3 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"7796d479bcb213f19e2ed73ef1069fe6":"f0ebb6fb1df60069b00a34c7":"87563b4d72e2f2c0094bff678e3b7975":"f72603b6e74bafc20f423bea2a1036ab44461b5e5a5631b013573d953e1fb073b855511860d1782c1f3b146b5c41eb94":"6e":"2fca":"44c4d7ba2af1be22daa6352b58bf8cda28999bc33c420f8881001719fe639a9e9e5c48df120f7cbe73af4c1513a637b9de33e8":"8b7002219f586318150132e0e5cbf2e9" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES192_GCM encrypt1 7 bytes encrypt2 4 bytes encrypt3 2 bytes #4 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"fcc2d46f0a06aa9c4a0ac28f5b30878f58d98b866d1dd9fb":"8b605a115f733d8000409b20":"fdbba5169522c370ee013186ce783f8f":"e5725fd5cc0f02":"bd86622a":"04d3":"2e25ad23334b310e33a60ff669":"97a6dcc6059fe5c7e5efb4b85c1c9bab" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES192_GCM encrypt1 21 bytes encrypt2 8 bytes encrypt3 3 bytes #5 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"e59dca3ca76903aa5e021466e30f641a40a7d209c0d46586":"a8943f7977125730a70f8099":"ec5295547824dc0fc09ac0eecaa4f512ca099f87":"8bb73e0b51be58d9e1253cf5d143ff2b95821ae7b6":"b903654c4e78beb7":"b2a0cd":"195ea977ba471eefa4a88623dbbe46073e2072b7183b83e342e01104acface82":"74c3cda8c9de81f9f7b7bca35a54c1" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES192_GCM encrypt1 48 bytes encrypt2 1 bytes encrypt3 2 bytes #6 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"3952f85b310d4db315f74065433e68093c72607310a682cc":"3c2702b721dd9bbb56dffb3b":"b3aa73ce1f8d13a98f29a5c70c4f869d":"b8d4705e1a24d724c8919a5a46705d9e68eeaf6b9a9d1e1714c1034095ef0e8f28aaec08efd116a730772c1b7dc2c861":"99":"64f9":"f26be49a3de8250b99ddc43961e7870dc3315cc6fa35df29a98fdc64aca9f742c599ede857bd75cbc2cd6c0ffc1e1f9a15995d":"d8503dce4c7ca73cfb91ef78644450de" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES256_GCM encrypt1 7 bytes encrypt2 4 bytes encrypt3 2 bytes #7 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"bfd5d64724e82b10595900670ede92f0ee12431b0a394abeb6fd17bdf26e15d2":"697ad97643d047884eb892283024770543918e54fb6ace4cbc65e662f5d31a44699f994a849138373db00f457e88ca16e30b3c36a76efcb67357a6567c3a922866205983c7740d07b3a602f34c94c5b3d91e8521674ec921fc0ea92174df8fbc8f2acf88fceff9290272392c9c9f915f06277f83ca21f6ab0da78ab47124333c":"e1f77c363d1cdf278a1efc5151ff19ae6103b8fa5cd34e367005f4d0fd35de46201bbef5953fd634de746d28ee781796":"568aec6c3560ab":"4303b9e1":"34a7":"baa61d866174cf2c7a0c7d8cf6":"e8c075352f052f03f726ffed9df7" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES256_GCM encrypt1 21 bytes encrypt2 8 bytes encrypt3 3 bytes #8 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"74f0988ac845fc795491cd7ae08c6f4c094e2497fc2872dbf65c54158a0751bb":"69fe1846b0fb6afb7ea3d10c":"69631879ae1f0f614f98a88f2e8720fc":"fabd94856b3a965178bb7f2c9d3310ab2afbcd8417":"443644b66e673db6":"3c6f74":"a06d064d19320c5e29a9265fe8f8b92ae07f7c82e4601194bcd3e8d8a17dd4f6":"d4919b8c540152973b20db6482470a" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES256_GCM encrypt1 48 bytes encrypt2 1 bytes encrypt3 2 bytes #9 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"a0eb9b59203ab2e62ed0d31a824ba505f4fe0cd7b81a2ecfcdfb58c086ce814f":"a45b962d6c9625c8029497d2":"c4ee2e4bcbfec1a8b0acd489c7478ba3":"dd522f79b36868f2bcab6e637dd3c722c373ba3c3918a8dad2f3d3b79da82f5c444aa43db3b8b864380026d1fc0245dc":"7f":"721d":"803c9b6147e93f345fbd698f5adf3a3c7b250fb4be22c7b87fb03c55620cbe7de1230d040bf026906a9b182e86a8d77b70f2ae":"a1c4cac704bd592c789ed6395c" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES128_CCM encrypt1 8 bytes encrypt2 6 bytes encrypt3 10 bytes #10 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES128_CCM:"f9fdca4ac64fe7f014de0f43039c7571":"0bbc177019321e":"f6e02678820f5ccbede6cbded02d6dd58d486166d7b18ee975a688af421fb795":"72a70954d22ad722":"fc32756afce6":"7b344b2f3c55fe1d9eed":"d4741814466a23e26107d773f103a4c83db9d772dbd5fdc1":"c2eaf895" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES192_CCM encrypt1 8 bytes encrypt2 6 bytes encrypts 10bytes #11 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES192_CCM:"a7aa635ea51b0bb20a092bd5573e728ccd4b3e8cdd2ab33d":"5a8aa485c316e9403aff859fbb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982":"8739b4bea1a099fe":"547499cbc6d1":"b13d849b8084c9b6acc5":"16e543d0e20615ff0df15acd9927ddfe40668a54bb854ccc":"c25e9fce" + +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002 CRYPT_CIPHER_AES256_CCM encrypt1 8 bytes encrypt2 6 bytes encrypts 10bytes #12 from NIST +SDV_CRYPTO_AES_MULTI_UPDATE_FUNC_TC002:CRYPT_CIPHER_AES256_CCM:"705334e30f53dd2f92d190d2c1437c8772f940c55aa35e562214ed45bd458ffe":"a544218dadd3c1":"d3d5424e20fbec43ae495353ed830271515ab104f8860c988d15b6d36c038eab":"78c46e3249ca28e1":"ef0531d80fd3":"7c124d9aecb7be6668e3":"3341168eb8c48468c414347fb08f71d2086f7c2d1bd581ce":"1ac68bd42f5ec7fa7e068cc0ecd79c2a" + +SDV_CRYPTO_AES_GETINFO_API_TC001 +SDV_CRYPTO_AES_GETINFO_API_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/bn/test_suite_sdv_bn.c b/testcode/sdv/testcase/crypto/bn/test_suite_sdv_bn.c new file mode 100644 index 00000000..89e9433a --- /dev/null +++ b/testcode/sdv/testcase/crypto/bn/test_suite_sdv_bn.c @@ -0,0 +1,1909 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "securec.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_bn.h" +#include "bn_basic.h" +#include "crypt_eal_rand.h" +#include "crypt_util_rand.h" + +#if defined(HITLS_SIXTY_FOUR_BITS) +#define BN_UINT_MAX UINT64_MAX +#elif defined(HITLS_THIRTY_TWO_BITS) +#define BN_UINT_MAX UINT32_MAX +#else +#error +#endif + +#define BITS_OF_BYTE 8 +#define BIGNUM_REDUNDANCY_BITS 64 +#define LONG_BN_BYTES_32 32 +#define SHORT_BN_BITS_128 128 +#define LONG_BN_BITS_256 256 +#define UINT8_MAX_NUM 255 +#define BN_SIZE 1024 + +extern int32_t ModExpInputCheck( + const BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, const BN_BigNum *m, const BN_Optimizer *opt); +extern int32_t ModExpCore(BN_BigNum *x, BN_BigNum *y, const BN_BigNum *e, const BN_BigNum *m, BN_Optimizer *opt); +extern int32_t BnGcdCheckInput(const BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_Optimizer *opt); +extern int32_t InverseInputCheck(const BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *m, const BN_Optimizer *opt); + +static int32_t TEST_Random(uint8_t *r, uint32_t randLen) +{ + for (uint32_t i = 0; i < randLen; i++) { + r[i] = rand() % UINT8_MAX_NUM; + } + return 0; +} + +uint32_t TEST_GetMax(uint32_t num1, uint32_t num2, uint32_t num3) +{ + uint32_t res = num1; + res = (res > num2) ? res : num2; + res = (res > num3) ? res : num3; + return res; +} + +BN_BigNum *TEST_VectorToBN(int sign, uint8_t *buff, uint32_t length) +{ + if (length == 0) { + return NULL; + } + BN_BigNum *bn = BN_Create(length * 8); // 8 bits per byte + if (bn != NULL) { + if (BN_Bin2Bn(bn, buff, length) != CRYPT_SUCCESS) { + BN_Destroy(bn); + bn = NULL; + } else { + BN_SetSign(bn, sign != 0); + } + } + return bn; +} +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_BN_CREATE_API_TC001 + * @title BN_Create: Invalid parameter. + * @precon nan + * @brief + * 1. Call the BN_Create method, input parameter is BN_MAX_BITS + 1, expected result 1 + * 2. Call the BN_Create method, input parameter is 0, expected result 2 + * @expect + * 1. Return NULL. + * 2. Return non-NULL. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_CREATE_API_TC001(void) +{ + BN_BigNum *bn = NULL; + TestMemInit(); + + bn = BN_Create((1u << 29) + 1); // BN_MAX_BITS + 1 + ASSERT_TRUE(bn == NULL); + + bn = BN_Create(0); + ASSERT_TRUE(bn != NULL); +exit: + BN_Destroy(bn); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SETSIGN_API_TC001 + * @title BN_SetSign: Test invalid parameters and normal functions. + * @precon nan + * @brief + * 1. Create BN_BigNum bn, the initial value is 0. + * 2. Call the BN_SetSign method, a is null, expected result 1 + * 3. Call the BN_SetSign method, a is bn, sign is true, expected result 2 + * 4. Set bn to 1, expected result 3 + * 5. Call the BN_SetSign method, a is bn, sign is true/false, expected result 4 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_BN_NO_NEGATIVE_ZERO + * 3-4. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SETSIGN_API_TC001(void) +{ + BN_BigNum *bn = NULL; + TestMemInit(); + ASSERT_TRUE(BN_SetSign(NULL, 0) == CRYPT_NULL_INPUT); + + bn = BN_Create(BN_MAX_BITS); + ASSERT_TRUE(bn != NULL); + ASSERT_TRUE(BN_SetSign(bn, true) == CRYPT_BN_NO_NEGATIVE_ZERO); + + ASSERT_TRUE(BN_SetLimb(bn, 1) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(bn, false) == CRYPT_SUCCESS); +exit: + BN_Destroy(bn); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_COPY_API_TC001 + * @title BN_Copy: The dest parameter space is smaller than src parameter. + * @precon nan + * @brief + * 1. Call the BN_Copy method, parameters are all, expected result 1 + * 2. Create BN_BigNum bn a and r, the size of r is half of a, expected result 2 + * 3. Call the BN_Copy method, copy a to r, expected result 3 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS(Big number can be automatically expanded.) + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_COPY_API_TC001(void) +{ + BN_BigNum *r = NULL; + BN_BigNum *a = NULL; + uint8_t buff[LONG_BN_BYTES_32] = {'F'}; + + TestMemInit(); + ASSERT_TRUE(BN_Copy(NULL, NULL) == CRYPT_NULL_INPUT); + + // r.room < a.bits + r = BN_Create(SHORT_BN_BITS_128); + ASSERT_TRUE(r != NULL); + // SHORT_BN_BYTES 16 = 32 / 2 + ASSERT_TRUE(BN_Bin2Bn(r, buff, sizeof(buff) / 2) == CRYPT_SUCCESS); + + a = BN_Create(LONG_BN_BITS_256); + ASSERT_TRUE(a != NULL); + ASSERT_TRUE(BN_Bin2Bn(a, buff, sizeof(buff)) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + +exit: + BN_Destroy(r); + BN_Destroy(a); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_ZEROIZE_API_TC001 + * @title BN_Zeroize: Invalid parameter. + * @precon nan + * @brief + * 1. Call the BN_Zeroize, parameter is null, expected result 1 + * @expect + * 1. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_ZEROIZE_API_TC001(void) +{ + ASSERT_TRUE(BN_Zeroize(NULL) == CRYPT_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SETLIMB_API_TC001 + * @title BN_SetLimb: Test invalid parameters and normal functions. + * @precon nan + * @brief + * 1. Create BN_BigNum bn. + * 2. Call the BN_SetLimb method, r is null, w is 0, expected result 1 + * 3. Call the BN_SetLimb method, r is bn, w is 0, expected result 2 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SETLIMB_API_TC001(void) +{ + TestMemInit(); + BN_BigNum *bn = BN_Create(1); + + ASSERT_TRUE(BN_SetLimb(NULL, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_SetLimb(bn, 0) == CRYPT_SUCCESS); +exit: + BN_Destroy(bn); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SETBIT_API_TC001 + * @title BN_SetBit: Test invalid parameters and normal functions. + * @precon nan + * @brief + * 1. Create BN_BigNum bn. + * 2. Call the BN_SetBit method, a is null, n is 0, expected result 1 + * 3. Call the BN_SetBit method, a is bn, n is invalid, expected result 2 + * 4. Call the BN_SetBit method, a is bn, n is valid, expected result 3 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_BN_SPACE_NOT_ENOUGH + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SETBIT_API_TC001(void) +{ + TestMemInit(); + BN_BigNum *bn = BN_Create(1); + + ASSERT_TRUE(BN_SetBit(NULL, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_SetBit(bn, (uint32_t)sizeof(BN_UINT) << 3) == CRYPT_BN_SPACE_NOT_ENOUGH); + ASSERT_TRUE(BN_SetBit(bn, ((uint32_t)sizeof(BN_UINT) << 3) - 1) == CRYPT_SUCCESS); +exit: + BN_Destroy(bn); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_GETBIT_API_TC001 + * @title BN_GetBit: Test invalid parameters and normal functions. + * @precon nan + * @brief + * 1. Call the BN_GetBit method, a is null, n is 0, expected result 1 + * 2. Create BN_BigNum bn, bn = 0, expected result 2 + * 3. Call the BN_GetBit method, get the first bit of bn, expected result 3 + * 4. Set limb of bn to BN_UINT_MAX, expected result 4 + * 5. Call the BN_GetBit method, Check whether the number of the specified bit is 1: + * (1) bit = limbBits - 1, expected result 5 + * (1) bit = limbBits, expected result 6 + * (1) bit = limbBits + 1, expected result 7 + * @expect + * 1. Return 0. + * 2. CRYPT_SUCCESS + * 3. The first bit of bn is 0. + * 4. CRYPT_SUCCESS. The number of bits in the limb is limbBits. + * 5. true + * 6. false + * 7. false + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_GETBIT_API_TC001(void) +{ + BN_BigNum *bn = NULL; + const int limbBits = sizeof(BN_UINT) * BITS_OF_BYTE; + + ASSERT_TRUE(BN_GetBit(NULL, 0) == 0); + + TestMemInit(); + bn = BN_Create(SHORT_BN_BITS_128); + ASSERT_TRUE(bn != NULL); + + // a = 0 , n = 0 + ASSERT_TRUE(BN_SetLimb(bn, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_GetBit(bn, 0) == 0); + + ASSERT_TRUE(BN_SetLimb(bn, BN_UINT_MAX) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_GetBit(bn, limbBits - 1) == true); + ASSERT_TRUE(BN_GetBit(bn, limbBits) == false); + ASSERT_TRUE(BN_GetBit(bn, limbBits + 1) == false); +exit: + BN_Destroy(bn); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_CLRBIT_API_TC001 + * @title BN_ClrBit: Test invalid parameters and normal functions. + * @precon nan + * @brief + * 1. Call the BN_ClrBit method, a is null, n is 0, expected result 1 + * 2. Create BN_BigNum bn, and set bn to -1, expected result 2 + * 3. Call the BN_ClrBit method, set the lowest bit to 0, expected result 3 + * 4. Set bn to 1, expected result 4 + * 5. Call the BN_ClrBit method, a is bn, n is BN_UINT_BITS, expected result 5 + * 6. Call the BN_ClrBit method, a is bn, n is valid, expected result 6 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS, bn changed from - 1 to 0. + * 4. CRYPT_SUCCESS + * 5. CRYPT_BN_SPACE_NOT_ENOUGH + * 6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_CLRBIT_API_TC001(void) +{ + BN_BigNum *bn = NULL; + ASSERT_TRUE(BN_ClrBit(NULL, 0) == CRYPT_NULL_INPUT); + + TestMemInit(); + bn = BN_Create(BN_MAX_BITS); + + /* bn = -1 */ + ASSERT_TRUE(BN_SetLimb(bn, 1) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(bn, 1) == CRYPT_SUCCESS); + + /* Set the lowest bit to 0. */ + ASSERT_TRUE(BN_ClrBit(bn, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_IsZero(bn)); + ASSERT_TRUE(BN_IsNegative(bn) == false); + + /* bn = 1 */ + ASSERT_TRUE(BN_SetLimb(bn, 1) == CRYPT_SUCCESS); + + ASSERT_EQ(BN_ClrBit(bn, ((uint32_t)sizeof(BN_UINT) << 3)), CRYPT_BN_SPACE_NOT_ENOUGH); // BN_UINT_BITS + ASSERT_TRUE(BN_ClrBit(bn, ((uint32_t)sizeof(BN_UINT) << 3) - 1) == CRYPT_SUCCESS); // BN_UINT_BITS - 1 +exit: + BN_Destroy(bn); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_RSHIFT_FUNC_TC001 + * @title BN_Rshift test. + * @precon Vectors: hex and its result after right-shifting n bits. + * @brief + * 1. Convert vectors to bn. + * 2. Call BN_Rshift, and compared the result with vector, expected result 1: + * (1) Pointer addresses for parameters are different from each other. + * (2) The address of the output parameter pointer r is the same as that of the input parameter pointer a. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_RSHIFT_FUNC_TC001(int sign, Hex *hex, int n, int signRes, Hex *result) +{ + TestMemInit(); + BN_BigNum *r = NULL; + BN_BigNum *q = NULL; + BN_BigNum *p = NULL; + BN_BigNum *a = TEST_VectorToBN(sign, hex->x, hex->len); + BN_BigNum *res = TEST_VectorToBN(signRes, result->x, result->len); + ASSERT_TRUE(a != NULL && res != NULL); + + r = BN_Create(BN_Bits(a) + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + ASSERT_EQ(BN_Rshift(r, a, n), CRYPT_SUCCESS); // r != a + ASSERT_TRUE(BN_Cmp(r, res) == 0); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + ASSERT_EQ(BN_Rshift(r, r, n), CRYPT_SUCCESS); // r == a + ASSERT_TRUE(BN_Cmp(r, res) == 0); + + /* Test the scenario where the output parameter space of q is insufficient */ + q = BN_Create(0); + ASSERT_TRUE(q != NULL); + ASSERT_EQ(BN_Rshift(q, a, n), CRYPT_SUCCESS); // r != a + ASSERT_TRUE(BN_Cmp(r, res) == 0); + +exit: + BN_Destroy(a); + BN_Destroy(r); + BN_Destroy(q); + BN_Destroy(p); + BN_Destroy(res); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODINV_API_TC001 + * @title BN_ModInv test. + * @precon nan + * @brief + * 1. Call BN_ModInv method: + * (1) all parameters are valid, expected result 1. + * (2) r is null, expected result 2. + * (3) a is null, expected result 3. + * (4) m is null, expected result 4. + * (5) opt is null, expected result 5. + * (6) a is zero or m is zero, expected result 6. + * (7) r.room.bits < m.bits, expected result 7. + * (8) r.room.bits = m.bits, expected result 8. + * (9) r.room.bits > m.bits, expected result 9. + * @expect + * 1. CRYPT_SUCCESS + * 2-5. CRYPT_NULL_INPUT + * 6. CRYPT_BN_ERR_DIVISOR_ZERO + * 7-9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODINV_API_TC001(void) +{ + TestMemInit(); + uint8_t buff[LONG_BN_BYTES_32]; + BN_BigNum *a = BN_Create(LONG_BN_BITS_256); + BN_BigNum *m = BN_Create(LONG_BN_BITS_256); + BN_BigNum *zero = BN_Create(LONG_BN_BITS_256); + BN_BigNum *r128 = BN_Create(SHORT_BN_BITS_128); + BN_BigNum *r256 = BN_Create(LONG_BN_BITS_256); + BN_BigNum *r257 = BN_Create(LONG_BN_BITS_256 + 1); + BN_Optimizer *opt = BN_OptimizerCreate(); + ASSERT_TRUE(a != NULL && m != NULL && r128 != NULL && r256 != NULL && zero != NULL && opt != NULL); + ASSERT_TRUE(BN_IsZero(zero) == true); + + // a = FF...FF (32 bytes) + ASSERT_TRUE(memset_s(buff, sizeof(buff), 0xFF, LONG_BN_BYTES_32) == EOK); + ASSERT_TRUE(BN_Bin2Bn(a, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + // m == FF...FD (32 bytes) + buff[LONG_BN_BYTES_32 - 1] = (uint8_t)0xFD; + ASSERT_TRUE(BN_Bin2Bn(m, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + + // NULL + ASSERT_TRUE(BN_ModInv(r256, a, m, opt) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModInv(NULL, a, m, opt) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_ModInv(r256, NULL, m, opt) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_ModInv(r256, a, NULL, opt) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_ModInv(r256, a, m, NULL) == CRYPT_NULL_INPUT); + + // zero + ASSERT_TRUE(BN_ModInv(r256, a, zero, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); + ASSERT_TRUE(BN_ModInv(r256, zero, m, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); + + // r.room.bits < m.bits + ASSERT_TRUE(BN_ModInv(r128, a, m, opt) == CRYPT_SUCCESS); + + // r.room.bits == m.bits + ASSERT_TRUE(BN_ModInv(r256, a, m, opt) == CRYPT_SUCCESS); + + // r.room.bits > m.bits + ASSERT_TRUE(BN_ModInv(r257, a, m, opt) == CRYPT_SUCCESS); + +exit: + BN_Destroy(a); + BN_Destroy(m); + BN_Destroy(zero); + BN_Destroy(r128); + BN_Destroy(r256); + BN_Destroy(r257); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODINV_FUNC_TC002 + * @title BN_ModInv test. + * @precon Vectors: hex1^(-1) mod modulo = result + * @brief + * 1. Convert vectors to bn. + * 2. Call BN_ModInv, and compared the result with vector, expected result 1. + * 3. If success is returned in the previous step, continue to test BN_ModInv when the output parameter address + * is the same as the input parameter address. expected result 2: + * (1) The address of the output parameter pointer r is the same as that of the input parameter pointer a. + * (2) The address of the output parameter pointer r is the same as that of the input parameter pointer m. + * 4. Test the scenario where the output parameter space is insufficient, expected result 2. + * @expect + * 1. Reutrn CRYPT_BN_ERR_NO_INVERSE on result is null. Otherwise, CRYPT_SUCCESS and result is same with vector. + * 2. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODINV_FUNC_TC002(int sign, Hex *hex, Hex *modulo, Hex *result) +{ + TestMemInit(); + int32_t ret; + BN_BigNum *res = NULL; + BN_BigNum *r = NULL; + BN_Optimizer *opt = BN_OptimizerCreate(); + BN_BigNum *a = TEST_VectorToBN(sign, hex->x, hex->len); + BN_BigNum *m = TEST_VectorToBN(0, modulo->x, modulo->len); + ASSERT_TRUE(a != NULL && m != NULL && opt != NULL); + + r = BN_Create(BN_Bits(a) + BN_Bits(m) + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + + ret = BN_ModInv(r, a, m, opt); // r != a + if (result->len == 0) { + ASSERT_TRUE(ret == CRYPT_BN_ERR_NO_INVERSE); // No results exist + } else { + ASSERT_TRUE(ret == CRYPT_SUCCESS); + res = BN_Create(result->len * BITS_OF_BYTE); + ASSERT_TRUE(res != NULL); + + ASSERT_TRUE(BN_Bin2Bn(res, result->x, result->len) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Cmp(r, res) == 0); + + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModInv(r, r, m, opt) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); + + ASSERT_TRUE(BN_Copy(r, m) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModInv(r, a, r, opt) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == m", BN_Cmp(r, res) == 0); + BN_Destroy(r); + + /* Test the scenario where the output parameter space is insufficient. */ + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(BN_ModInv(r, a, m, opt) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Cmp(r, res) == 0); + BN_Destroy(r); + + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModInv(r, r, m, opt) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); + BN_Destroy(r); + + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(BN_Copy(r, m) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModInv(r, a, r, opt) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == m", BN_Cmp(r, res) == 0); + } + +exit: + BN_Destroy(a); + BN_Destroy(m); + BN_Destroy(r); + BN_Destroy(res); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MOD_EXP_INPUT_CHECK_API_TC001 + * @title ModExpInputCheck: Test invalid parameters and normal functions. + * @precon nan + * @brief + * 1. Call the ModExpInputCheck method, parameters are null,expected result 1 + * 2. Call the ModExpInputCheck method, the size of r is smaller then m, expected result 2 + * 3. Call the ModExpInputCheck method, m is 0, expected result 3 + * 4. Call the ModExpInputCheck method, e is a negative number, expected result 4 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_ERR_DIVISOR_ZERO + * 4. CRYPT_BN_ERR_EXP_NO_NEGATIVE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MOD_EXP_INPUT_CHECK_API_TC001(void) +{ + BN_BigNum *bn = NULL; + BN_BigNum *r = NULL; + BN_BigNum *a = NULL; + BN_BigNum *e = NULL; + BN_BigNum *m = NULL; + BN_Optimizer *opt = NULL; + TestMemInit(); + + ASSERT_TRUE(ModExpInputCheck(NULL, NULL, NULL, NULL, NULL) == CRYPT_NULL_INPUT); + + bn = BN_Create(1); + a = BN_Create(BN_MAX_BITS); + e = BN_Create(BN_MAX_BITS); + opt = BN_OptimizerCreate(); + r = BN_Create(1); + m = BN_Create(BN_MAX_BITS); + ASSERT_TRUE(BN_SetBit(m, BN_SIZE) == CRYPT_SUCCESS); + ASSERT_TRUE(ModExpInputCheck(r, a, e, m, opt) == CRYPT_SUCCESS); + + BN_Destroy(r); + r = BN_Create(BN_MAX_BITS); + ASSERT_TRUE(ModExpInputCheck(r, a, e, bn, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); + + ASSERT_TRUE(BN_SetBit(e, BN_SIZE) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(e, true) == CRYPT_SUCCESS); + ASSERT_TRUE(ModExpInputCheck(r, a, e, m, opt) == CRYPT_BN_ERR_EXP_NO_NEGATIVE); + +exit: + BN_Destroy(bn); + BN_Destroy(r); + BN_Destroy(a); + BN_Destroy(e); + BN_Destroy(m); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODEXP_API_TC001 + * @title BN_ModExp: Test invalid parameters. + * @precon nan + * @brief + * 1. Call the BN_ModExp method, parameters are null, expected result 1 + * 2. Call the BN_ModExp method, the size of r is smaller then m, expected result 2 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODEXP_API_TC001(void) +{ + uint8_t buff[LONG_BN_BYTES_32]; + TestMemInit(); + + BN_BigNum *a = BN_Create(LONG_BN_BITS_256); + BN_BigNum *e = BN_Create(LONG_BN_BITS_256); + BN_BigNum *r = BN_Create(LONG_BN_BITS_256); + BN_BigNum *m = BN_Create(LONG_BN_BITS_256); + BN_Optimizer *opt = BN_OptimizerCreate(); + ASSERT_TRUE(a != NULL); + ASSERT_TRUE(e != NULL); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(m != NULL); + ASSERT_TRUE(opt != NULL); + ASSERT_TRUE(memset_s(buff, sizeof(buff), 0xFF, LONG_BN_BYTES_32) == EOK); + + ASSERT_TRUE(BN_Bin2Bn(a, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Bin2Bn(e, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Bin2Bn(m, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + + // NULL + ASSERT_TRUE(BN_ModExp(NULL, NULL, NULL, NULL, NULL) == CRYPT_NULL_INPUT); + + BN_Destroy(r); + r = BN_Create(LONG_BN_BITS_256 - BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(BN_ModExp(r, a, e, m, opt) == CRYPT_SUCCESS); + +exit: + BN_Destroy(a); + BN_Destroy(e); + BN_Destroy(r); + BN_Destroy(m); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODEXP_API_TC002 + * @title BN_ModExp: Invalid parameter and function test. + * @precon nan + * @brief + * 1. Call the BN_ModExp method, the divisor is 0, expected result 1 + * 2. Call the BN_ModExp method, the value of the exponent is negative, expected result 2 + * 3. Call the BN_ModExp method, all parameters are valid, expected result 3 + * @expect + * 1. CRYPT_BN_ERR_DIVISOR_ZERO + * 2. CRYPT_BN_ERR_EXP_NO_NEGATIVE + * 3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODEXP_API_TC002(void) +{ + uint8_t buff[LONG_BN_BYTES_32]; + BN_BigNum *a = BN_Create(LONG_BN_BYTES_32 * 8); + BN_BigNum *e = BN_Create(LONG_BN_BYTES_32 * 8); + BN_BigNum *m = BN_Create(LONG_BN_BYTES_32 * 8); + BN_BigNum *r = BN_Create(LONG_BN_BITS_256); + BN_BigNum *zero = BN_Create(LONG_BN_BITS_256); + BN_BigNum *one = BN_Create(LONG_BN_BITS_256); + BN_BigNum *negOne = BN_Create(LONG_BN_BITS_256); + BN_Optimizer *opt = BN_OptimizerCreate(); + TestMemInit(); + + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(zero != NULL); + ASSERT_TRUE(one != NULL); + ASSERT_TRUE(negOne != NULL); + ASSERT_TRUE(opt != NULL); + + ASSERT_TRUE(memset_s(buff, sizeof(buff), 0xFF, LONG_BN_BYTES_32) == EOK); + + ASSERT_TRUE(a != NULL); + ASSERT_TRUE(BN_Bin2Bn(a, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(a, false) == CRYPT_SUCCESS); + + ASSERT_TRUE(e != NULL); + ASSERT_TRUE(BN_Bin2Bn(e, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(e, false) == CRYPT_SUCCESS); + + ASSERT_TRUE(m != NULL); + ASSERT_TRUE(BN_Bin2Bn(m, buff, LONG_BN_BYTES_32) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(m, false) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Zeroize(zero) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetLimb(one, 1) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetLimb(negOne, 1) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(negOne, true) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_ModExp(r, a, e, zero, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); + ASSERT_TRUE(BN_ModExp(r, a, negOne, m, opt) == CRYPT_BN_ERR_EXP_NO_NEGATIVE); + ASSERT_TRUE(BN_ModExp(r, zero, zero, m, opt) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Cmp(r, one) == 0); + ASSERT_TRUE(BN_ModExp(r, zero, zero, one, opt) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Cmp(r, zero) == 0); + ASSERT_TRUE(BN_ModExp(r, a, e, negOne, opt) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Cmp(r, zero) == 0); + +exit: + BN_Destroy(a); + BN_Destroy(e); + BN_Destroy(r); + BN_Destroy(m); + BN_Destroy(zero); + BN_Destroy(one); + BN_Destroy(negOne); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODEXP_FUNC_TC001 + * @title BN_ModExp test. + * @precon Vectors: two big numbers, mod, result. + * @brief + * 1. Convert vectors to big numbers. + * 2. Call BN_ModExp to calculate the modular exponentiation, and compared to the vector value, expected result 1: + * (1) Pointer addresses for parameters are different from each other. + * (2) The address of the output parameter pointer r is the same as that of the input parameter pointer a. + * (3) The address of the output parameter pointer r is the same as that of the input parameter pointer e. + * (4) The address of the output parameter pointer r is the same as that of the input parameter pointer m. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODEXP_FUNC_TC001(int sign1, Hex *hex1, Hex *hex2, Hex *modulo, Hex *result) +{ + TestMemInit(); + BN_BigNum *r = NULL; + BN_Optimizer *opt = NULL; + uint32_t maxBits; + BN_BigNum *res = TEST_VectorToBN(0, result->x, result->len); + BN_BigNum *a = TEST_VectorToBN(sign1, hex1->x, hex1->len); + BN_BigNum *e = TEST_VectorToBN(0, hex2->x, hex2->len); + BN_BigNum *m = TEST_VectorToBN(0, modulo->x, modulo->len); + ASSERT_TRUE(res != NULL && a != NULL && e != NULL && m != NULL); + + maxBits = TEST_GetMax(BN_Bits(a), BN_Bits(e), BN_Bits(m)); + r = BN_Create(maxBits + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + + opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, a, e, m, opt) == CRYPT_SUCCESS); // r != a + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(r, res) == 0); + + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, r, e, m, opt) == CRYPT_SUCCESS); // r == a + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); + + ASSERT_TRUE(BN_Copy(r, e) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, a, r, m, opt) == CRYPT_SUCCESS); // r == e + ASSERT_TRUE_AND_LOG("r == e", BN_Cmp(r, res) == 0); + + ASSERT_TRUE(BN_Copy(r, m) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, a, e, r, opt) == CRYPT_SUCCESS); // r == m + ASSERT_TRUE_AND_LOG("r == m", BN_Cmp(r, res) == 0); + + // Test the scenario where the output parameter space is insufficient. + BN_Destroy(r); + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + + ASSERT_TRUE(BN_ModExp(r, a, e, m, opt) == CRYPT_SUCCESS); // r != a + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(r, res) == 0); + + BN_Destroy(r); + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, r, e, m, opt) == CRYPT_SUCCESS); // r == a + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); + + BN_Destroy(r); + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(BN_Copy(r, e) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, a, r, m, opt) == CRYPT_SUCCESS); // r == e + ASSERT_TRUE_AND_LOG("r == e", BN_Cmp(r, res) == 0); + + BN_Destroy(r); + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + ASSERT_TRUE(BN_Copy(r, m) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_ModExp(r, a, e, r, opt) == CRYPT_SUCCESS); // r == m + ASSERT_TRUE_AND_LOG("r == m", BN_Cmp(r, res) == 0); + +exit: + BN_Destroy(a); + BN_Destroy(e); + BN_Destroy(m); + BN_Destroy(r); + BN_Destroy(res); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODEXPCORE_API_TC001 + * @title ModExpCore: Invalid parameter. + * @precon nan + * @brief + * 1. Call the ModExpCore method, the divisor is 0, expected result 1 + * @expect + * 1. CRYPT_BN_ERR_DIVISOR_ZERO + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODEXPCORE_API_TC001(void) +{ + TestMemInit(); + BN_BigNum *a = BN_Create(LONG_BN_BITS_256); + BN_BigNum *e = BN_Create(LONG_BN_BITS_256); + BN_BigNum *r = BN_Create(LONG_BN_BITS_256); + BN_BigNum *m = BN_Create(LONG_BN_BITS_256); + BN_Optimizer *opt = BN_OptimizerCreate(); + ASSERT_TRUE(BN_SetLimb(e, 10) == CRYPT_SUCCESS); + ASSERT_TRUE(ModExpCore(r, a, e, m, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); + +exit: + BN_Destroy(a); + BN_Destroy(e); + BN_Destroy(r); + BN_Destroy(m); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MOD_API_TC001 + * @title BN_Mod: Invalid parameter. + * @precon nan + * @brief + * 1. Call the BN_Mod method, all parameters are null, expected result 1 + * 2. Call the BN_Mod method, mod is UINT8_MAX_NUM, expected result 2 + * 3. Call the BN_Mod method, mod is 0, expected result 3 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_ERR_DIVISOR_ZERO + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MOD_API_TC001(void) +{ + TestMemInit(); + BN_BigNum *a = BN_Create(LONG_BN_BITS_256); + BN_BigNum *r = BN_Create(SHORT_BN_BITS_128); + BN_BigNum *m = BN_Create(LONG_BN_BITS_256); + BN_Optimizer *opt = BN_OptimizerCreate(); + + ASSERT_TRUE(BN_Mod(NULL, NULL, NULL, NULL) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(BN_SetBit(m, UINT8_MAX_NUM) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Mod(r, a, m, opt) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_SetLimb(m, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Mod(r, a, m, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); + +exit: + BN_Destroy(a); + BN_Destroy(r); + BN_Destroy(m); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MOD_FUNC_TC001 + * @title BN_Mod test. + * @precon Vectors: hex1 mod module = result + * @brief + * 1. Convert vectors to bn. + * 2. Call BN_Mod, and compared the result with vector, expected result 1: + * (1) Pointer addresses for parameters are different from each other. + * (2) The address of the output parameter pointer r is the same as that of the input parameter pointer a. + * (3) The address of the output parameter pointer r is the same as that of the input parameter pointer m. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MOD_FUNC_TC001(int sign1, Hex *hex1, int sign2, Hex *modulo, Hex *result) +{ + TestMemInit(); + BN_BigNum *r = NULL; + BN_Optimizer *opt = NULL; + + BN_BigNum *res = TEST_VectorToBN(0, result->x, result->len); + BN_BigNum *a = TEST_VectorToBN(sign1, hex1->x, hex1->len); + BN_BigNum *m = TEST_VectorToBN(sign2, modulo->x, modulo->len); + ASSERT_TRUE(a != NULL && m != NULL && res != NULL); + + r = BN_Create(BN_Bits(a) + BN_Bits(m) + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + + opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + ASSERT_EQ(BN_Mod(r, a, m, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(r, res) == 0); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + ASSERT_EQ(BN_Mod(r, r, m, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); + + ASSERT_EQ(BN_Copy(r, m), CRYPT_SUCCESS); + ASSERT_EQ(BN_Mod(r, a, r, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == m", BN_Cmp(r, res) == 0); + + /* Test the scenario where the output parameter space is insufficient. */ + BN_Destroy(r); + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + + ASSERT_EQ(BN_Mod(r, a, m, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(r, res) == 0); + + ASSERT_EQ(BN_Copy(r, m), CRYPT_SUCCESS); + ASSERT_EQ(BN_Mod(r, a, r, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == m", BN_Cmp(r, res) == 0); + + BN_Destroy(r); + r = BN_Create(0); + ASSERT_TRUE(r != NULL); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + ASSERT_EQ(BN_Mod(r, r, m, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); +exit: + BN_Destroy(a); + BN_Destroy(m); + BN_Destroy(r); + BN_Destroy(res); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_PRIMECHECK_API_TC001 + * @title BN_PrimeCheck: Invalid parameter. + * @precon nan + * @brief + * 1. Create BN_BigNum bn, set the value of bn to 10, expected result 1 + * 2. Call the BN_PrimeCheck to check bn, expected result 2 + * @expect + * 1. CRYPT_SUCCESS + * 1. CRYPT_BN_NOR_CHECK_PRIME + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_PRIMECHECK_API_TC001(void) +{ + TestMemInit(); + BN_BigNum *bn = BN_Create(LONG_BN_BITS_256); + BN_Optimizer *opt = BN_OptimizerCreate(); + + ASSERT_TRUE(BN_SetLimb(bn, 10) == CRYPT_SUCCESS); // bn == 10 + ASSERT_TRUE(BN_PrimeCheck(bn, opt) == CRYPT_BN_NOR_CHECK_PRIME); + +exit: + BN_Destroy(bn); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001 + * @title BN_PrimeCheck method test. + * @precon A big number and information about whether the big number is prime. + * @brief + * 1. Convert hex to bn. + * 2. Init the drbg. + * 3. Call the BN_PrimeCheck method to check whether the big number is prime, expected result 1 + * @expect + * 1. Return CRYPT_SUCCESS on isPrime != 0, CRYPT_BN_NOR_CHECK_PRIME otherwise. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001(Hex *hex, int isPrime) +{ +#ifndef HITLS_CRYPTO_DRBG + (void)hex; + (void)isPrime; + SKIP_TEST(); +#else + TestMemInit(); + int32_t ret; + BN_BigNum *bn = BN_Create(hex->len * BITS_OF_BYTE); + BN_Optimizer *opt = BN_OptimizerCreate(); + ASSERT_TRUE(bn != NULL && opt != NULL); + + ASSERT_EQ(BN_Bin2Bn(bn, hex->x, hex->len), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ret = BN_PrimeCheck(bn, opt); + if (isPrime != 0) { + ASSERT_EQ(ret, CRYPT_SUCCESS); + } else { + ASSERT_EQ(ret, CRYPT_BN_NOR_CHECK_PRIME); + } + +exit: + CRYPT_EAL_RandDeinit(); + BN_Destroy(bn); + BN_OptimizerDestroy(opt); +#endif +} +/* END_CASE */ + +static int32_t PrimeGenCb(BN_CbCtx *callBack, int32_t process, int32_t target) +{ + if (callBack == NULL) + return CRYPT_SUCCESS; + + int32_t *limit = BN_CbCtxGetArg(callBack); + if (process < *limit) { + return CRYPT_SUCCESS; + } + (void)target; + printf("now try tims is %d, gen failed\n", process); + return -1; +} + +/** + * @test SDV_CRYPTO_BN_GENPRIMELIMB_API_TC001 + * @title BN_GenPrime method test. + * @precon nan + * @brief + * 1. Create BN_CbCtx and call the BN_CbCtxSet method to register BN_CallBack method. + * 2. Init the drbg. + * 3. Call the BN_GenPrime method to generate prime, bits is LONG_BN_BITS_256, half is false, expected result 1 + * 4. Call the BN_GenPrime method to generate prime, bits < 14, half is true, expected result 2 + * 5. Call the BN_GenPrime method to generate prime, bits is 10, expected result 3 + * @expect + * 1-3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_GENPRIMELIMB_API_TC001(void) +{ + TestMemInit(); + BN_Optimizer *opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + BN_CbCtx *cb = BN_CbCtxCreate(); + ASSERT_TRUE(cb != NULL); + int32_t limit = 256; + BN_CbCtxSet(cb, PrimeGenCb, &limit); + const uint32_t bits = LONG_BN_BITS_256; + bool half = false; + BN_BigNum *r = BN_Create(LONG_BN_BITS_256); + ASSERT_TRUE(r != NULL); + + CRYPT_RandRegist(TEST_Random); + + ASSERT_TRUE(BN_GenPrime(r, bits, half, opt, cb) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_GenPrime(r, 13, true, opt, cb) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_GenPrime(r, 10, half, opt, cb) == CRYPT_SUCCESS); + +exit: + BN_CbCtxDestroy(cb); + BN_Destroy(r); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001 + * @title BN_AddLimb method test. + * @precon nan + * @brief + * 1. Convert vectors to big numbers. + * 2. Call the BN_AddLimb method to calculate the sum of two numbers, expected result 1. + * 3. If expectRet=CRYPT_SUCCESS, call the BN_Cmp to compare r and resHex, expected result 3. + * @expect + * 1. The return value is the same as 'expectRet'. + * 2. The calculated sum is 0. + * 3. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001(int sign, Hex *rHex, int limb, int resSign, Hex *resHex, int expectRet) +{ + TestMemInit(); + BN_BigNum *resBn = NULL; + BN_BigNum *a = TEST_VectorToBN(sign, rHex->x, rHex->len); + BN_BigNum *r = TEST_VectorToBN(resSign, resHex->x, resHex->len); + /* a and r can be null. */ + + resBn = BN_Create(SHORT_BN_BITS_128); + ASSERT_TRUE(resBn != NULL); + + ASSERT_EQ(BN_AddLimb(resBn, a, limb), expectRet); + if (expectRet == CRYPT_SUCCESS) { + ASSERT_EQ(BN_Cmp(resBn, r), 0); + } + +exit: + BN_Destroy(a); + BN_Destroy(r); + BN_Destroy(resBn); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SUB_FUNC_TC001 + * @title BN_Sub test. + * @precon Vectors: hex1 - hex2 = result + * @brief + * 1. Convert vectors to big numbers. + * 2. Call BN_Sub to calculate hex1 minus hex2, and compared the result with vector, expected result 1: + * (1) Pointer addresses for parameters are different from each other. + * (2) The address of the output parameter pointer r is the same as that of the input parameter pointer a. + * (3) The address of the output parameter pointer r is the same as that of the input parameter pointer b. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SUB_FUNC_TC001(int sign1, Hex *hex1, int sign2, Hex *hex2, int signRes, Hex *result) +{ + TestMemInit(); + BN_BigNum *r = NULL; + BN_BigNum *n = NULL; + uint32_t maxBits; + + BN_BigNum *res = TEST_VectorToBN(signRes, result->x, result->len); + BN_BigNum *a = TEST_VectorToBN(sign1, hex1->x, hex1->len); + BN_BigNum *b = TEST_VectorToBN(sign2, hex2->x, hex2->len); + ASSERT_TRUE(res != NULL && a != NULL && b != NULL); + + maxBits = TEST_GetMax(BN_Bits(a), BN_Bits(b), 0); + r = BN_Create(maxBits + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + ASSERT_EQ(BN_Sub(r, a, b), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(r, res) == 0); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + ASSERT_EQ(BN_Sub(r, r, b), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(r, res) == 0); + + ASSERT_EQ(BN_Copy(r, b), CRYPT_SUCCESS); + ASSERT_EQ(BN_Sub(r, a, r), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == b", BN_Cmp(r, res) == 0); + + /* Test the scenario where the output parameter space is insufficient. */ + n = BN_Create(0); + ASSERT_TRUE(n != NULL); + + ASSERT_EQ(BN_Sub(n, a, b), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("n != a", BN_Cmp(n, res) == 0); + + ASSERT_EQ(BN_Sub(a, a, b), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("a == a", BN_Cmp(a, res) == 0); + +exit: + BN_Destroy(a); + BN_Destroy(b); + BN_Destroy(r); + BN_Destroy(n); + BN_Destroy(res); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SUBLIMB_API_TC001 + * @title BN_SubLimb method test. + * @precon nan + * @brief + * 1. Create BN_BigNum r and a. + * 2. Call the BN_SubLimb method, parameters are null, expected result 1 + * 3. Call the BN_AddLimb method to subtract a from 2, expected result 2 + * 4. Call the BN_AddLimb method to subtract a from 1, expected result 3 + * 5. Call the BN_AddLimb method to subtract a from 0, expected result 4 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SUBLIMB_API_TC001(void) +{ + BN_BigNum *r = NULL; + BN_BigNum *a = NULL; + + TestMemInit(); + + r = BN_Create(LONG_BN_BITS_256); + a = BN_Create(LONG_BN_BITS_256); + ASSERT_TRUE(r != NULL && a != NULL); + + ASSERT_TRUE(BN_SubLimb(NULL, NULL, 0) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(BN_SubLimb(r, a, 2) == CRYPT_SUCCESS); // r == LONG_BN_BITS_256 - 2 + + ASSERT_TRUE(BN_SetBit(a, 1) == CRYPT_SUCCESS); // a->size == 1 + ASSERT_TRUE(BN_SetSign(a, true) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SubLimb(r, a, 1) == CRYPT_SUCCESS); // r == LONG_BN_BITS_256 - 1 + + ASSERT_TRUE(BN_SetBit(a, SHORT_BN_BITS_128 - 1) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SubLimb(r, a, 0) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_SetBit(a, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SubLimb(r, a, 0) == CRYPT_SUCCESS); + + BN_Destroy(a); + a = NULL; + a = BN_Create(0); + ASSERT_TRUE(a != NULL); + ASSERT_TRUE(BN_SubLimb(r, a, 10) == CRYPT_SUCCESS); + +exit: + BN_Destroy(r); + BN_Destroy(a); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001 + * @title BN_SubLimb test. + * @precon Vectors: hex1 - hex2 = result + * @brief + * 1. Convert vectors to big numbers. + * 2. Call BN_SubLimb to calculate hex1 minus hex2, and compared the result with vector, expected result 1. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001(int sign1, Hex *hex1, Hex *hex2, int signRes, Hex *result) +{ + TestMemInit(); + BN_BigNum *r = NULL; + BN_BigNum *n = NULL; + BN_UINT w = 0; + + BN_BigNum *res = TEST_VectorToBN(signRes, result->x, result->len); + BN_BigNum *a = TEST_VectorToBN(sign1, hex1->x, hex1->len); + ASSERT_TRUE(res != NULL && a != NULL); + + // w + ASSERT_TRUE(sizeof(BN_UINT) >= hex2->len); + for (uint32_t i = 0; i < hex2->len; i++) { + w <<= BITS_OF_BYTE; + w += hex2->x[i]; + } + + // r + r = BN_Create(BN_Bits(a) + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + + ASSERT_EQ(BN_Copy(r, a), CRYPT_SUCCESS); + + ASSERT_EQ(BN_SubLimb(r, a, w), CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Cmp(r, res) == 0); + + /* Test the scenario where the output parameter space is insufficient. */ + n = BN_Create(0); + ASSERT_TRUE(n != NULL); + + ASSERT_EQ(BN_Zeroize(a), CRYPT_SUCCESS); + + ASSERT_TRUE(BN_SubLimb(n, a, w) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_SetLimb(res, w) == CRYPT_SUCCESS); + if (w != 0) { + res->flag |= CRYPT_BN_FLAG_ISNEGTIVE; + } + ASSERT_TRUE(BN_Cmp(n, res) == 0); + +exit: + BN_Destroy(a); + BN_Destroy(r); + BN_Destroy(n); + BN_Destroy(res); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_DIV_FUNC_TC001 + * @title BN_Div test. + * @precon Vectors: hex1 / hex2 = resultQ, hex1 % hex2 = resultR + * @brief + * 1. Convert vectors to big numbers. + * 2. Call BN_Div method, and compared the result with vector, expected result 1: + * (1) Pointer addresses for parameters are different from each other. + * (2) q == x, r == y. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_DIV_FUNC_TC001( + int sign1, Hex *hex1, int sign2, Hex *hex2, int signQ, Hex *resultQ, int signR, Hex *resultR) +{ + TestMemInit(); + BN_BigNum *q = NULL; + BN_BigNum *r = NULL; + BN_BigNum *q1 = NULL; + BN_BigNum *n = NULL; + BN_Optimizer *opt = NULL; + uint32_t maxBits; + + BN_BigNum *resQ = TEST_VectorToBN(signQ, resultQ->x, resultQ->len); + BN_BigNum *resR = TEST_VectorToBN(signR, resultR->x, resultR->len); + BN_BigNum *x = TEST_VectorToBN(sign1, hex1->x, hex1->len); + BN_BigNum *y = TEST_VectorToBN(sign2, hex2->x, hex2->len); + ASSERT_TRUE(resQ != NULL && resR != NULL && x != NULL && y != NULL); + + maxBits = TEST_GetMax(BN_Bits(x), BN_Bits(y), 0); + // q + q = BN_Create(maxBits + BIGNUM_REDUNDANCY_BITS); + r = BN_Create(maxBits + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(q != NULL && r != NULL); + + opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + + ASSERT_EQ(BN_Copy(q, x), CRYPT_SUCCESS); + ASSERT_EQ(BN_Copy(r, y), CRYPT_SUCCESS); + ASSERT_EQ(BN_Div(q, r, x, y, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("q != x, r != y", BN_Cmp(q, resQ) == 0); + ASSERT_TRUE_AND_LOG("q != x, r != y", BN_Cmp(r, resR) == 0); + + ASSERT_EQ(BN_Copy(q, x), CRYPT_SUCCESS); + ASSERT_EQ(BN_Copy(r, y), CRYPT_SUCCESS); + ASSERT_EQ(BN_Div(q, r, q, r, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("q == x, r == y", BN_Cmp(q, resQ) == 0); + ASSERT_TRUE_AND_LOG("q == x, r == y", BN_Cmp(r, resR) == 0); + + /* Test the scenario where the output parameter space is insufficient. */ + n = BN_Create(0); + q1 = BN_Create(0); + ASSERT_TRUE(n != NULL); + ASSERT_TRUE(q1 != NULL); + + ASSERT_EQ(BN_Div(q1, n, x, y, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("q1 != x, n != y", BN_Cmp(q1, resQ) == 0); + ASSERT_TRUE_AND_LOG("q1 != x, n != y", BN_Cmp(n, resR) == 0); +exit: + BN_Destroy(x); + BN_Destroy(y); + BN_Destroy(q); + BN_Destroy(r); + BN_Destroy(n); + BN_Destroy(q1); + BN_Destroy(resQ); + BN_Destroy(resR); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SQR_API_TC001 + * @title BN_Sqr method test. + * @precon nan + * @brief + * 1. Call the BN_Sqr method, parameters are null, expected result 1 + * 2. Call the BN_Sqr method, parameters are valid, expected result 2 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SQR_API_TC001(void) +{ + uint8_t buff[LONG_BN_BYTES_32]; + BN_BigNum *a = NULL; + BN_BigNum *r = NULL; + BN_BigNum *zero = NULL; + BN_Optimizer *opt = NULL; + TestMemInit(); + + a = BN_Create(SHORT_BN_BITS_128); + r = BN_Create(SHORT_BN_BITS_128); + ASSERT_TRUE(a != NULL && r != NULL); + opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + + ASSERT_TRUE(BN_Sqr(NULL, NULL, NULL) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(BN_Sqr(r, a, opt) == CRYPT_SUCCESS); + + memset_s(buff, sizeof(buff), 0xFF, LONG_BN_BYTES_32); + ASSERT_TRUE(BN_Bin2Bn(a, buff, sizeof(buff)) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Sqr(r, a, opt) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Bin2Bn(a, buff, sizeof(buff) / 2) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Sqr(r, a, opt) == CRYPT_SUCCESS); + +exit: + BN_Destroy(a); + BN_Destroy(r); + BN_Destroy(zero); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_SQR_FUNC_TC001 + * @title BN_Sqr method test. + * @precon nan + * @brief + * 1. Call the BN_Copy method, Compute (-1)*(-1) or 1*1, expected result 1 + * 2. Compare r and result, expected result 2 + * @expect + * 1. CRYPT_SUCCESS + * 2. r = result + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_SQR_FUNC_TC001(int sign1, Hex *hex1, Hex *result) +{ + TestMemInit(); + BN_BigNum *a; + BN_BigNum *res = NULL; + BN_BigNum *r = NULL; + BN_Optimizer *opt = NULL; + + a = BN_Create(hex1->len * BITS_OF_BYTE); + res = BN_Create(result->len * BITS_OF_BYTE); + ASSERT_TRUE(a != NULL && res != NULL); + + ASSERT_TRUE(BN_Bin2Bn(res, result->x, result->len) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Bin2Bn(a, hex1->x, hex1->len) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(a, sign1 != 0) == CRYPT_SUCCESS); + + // r.bits > a.bits * 2 + r = BN_Create(BN_Bits(a) * 2 + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(r != NULL); + + opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + + ASSERT_TRUE(BN_Copy(r, a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Sqr(r, a, opt) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Cmp(r, res) == 0); + +exit: + BN_Destroy(a); + BN_Destroy(r); + BN_Destroy(res); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_RAND_API_TC001 + * @title BN_Rand: Invalid parameter. + * @precon nan + * @brief + * 1. Call the BN_Rand, parameters are null and 0, expected result 1 + * 2. Call the BN_Rand, top is out of maximum value(BN_RAND_TOP_TWOBIT + 1), expected result 2 + * 3. Call the BN_Rand, bottom is out of maximum value(BN_RAND_BOTTOM_TWOBIT + 1), expected result 3 + * 4. Call the BN_Rand, bit is 0, top and bottom are not 0, expected result 4 + * 5. Call the BN_Rand, bit > BN_MAX_BITS, expected result 5 + * 6. Call the BN_Rand, bit, top and bottom is 0, expected result 6 + * @expect + * 1. CRYPT_NULL_INPUT + * 2-3. CRYPT_BN_ERR_RAND_TOP_BOTTOM + * 4. CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH + * 5. CRYPT_BN_BITS_TOO_MAX + * 6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_RAND_API_TC001(void) +{ +#ifndef HITLS_CRYPTO_DRBG + SKIP_TEST(); +#else + BN_BigNum *bn = NULL; + TestMemInit(); + bn = BN_Create(BITS_OF_BYTE); + + ASSERT_TRUE(BN_Rand(NULL, 0, 0, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE( + BN_Rand(bn, BITS_OF_BYTE, BN_RAND_TOP_TWOBIT + 1, BN_RAND_BOTTOM_TWOBIT) == CRYPT_BN_ERR_RAND_TOP_BOTTOM); + ASSERT_TRUE( + BN_Rand(bn, BITS_OF_BYTE, BN_RAND_TOP_TWOBIT, BN_RAND_BOTTOM_TWOBIT + 1) == CRYPT_BN_ERR_RAND_TOP_BOTTOM); + ASSERT_TRUE(BN_Rand(bn, 0, BN_RAND_TOP_TWOBIT, BN_RAND_BOTTOM_TWOBIT) == CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH); + + ASSERT_TRUE(BN_Rand(bn, BN_MAX_BITS + 1, BN_RAND_TOP_TWOBIT, BN_RAND_BOTTOM_TWOBIT) == CRYPT_BN_BITS_TOO_MAX); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_TRUE(BN_Rand(bn, 0, 0, 0) == CRYPT_SUCCESS); +exit: + BN_Destroy(bn); + return; +#endif +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_RANDRANGE_API_TC001 + * @title BN_RandRange: Invalid parameter. + * @precon nan + * @brief + * 1. Call the BN_RandRange method, parameters are null, expected result 1 + * 2. Call the BN_RandRange method, parameters are 0, expected result 2 + * 3. Call the BN_RandRange method, parameters are -1, expected result 3 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_BN_ERR_RAND_ZERO + * 3. CRYPT_BN_ERR_RAND_NEGATIVE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_RANDRANGE_API_TC001(void) +{ + BN_BigNum *bn = NULL; + TestMemInit(); + bn = BN_Create(BITS_OF_BYTE); + + ASSERT_TRUE(BN_RandRange(NULL, NULL) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_RandRange(bn, bn) == CRYPT_BN_ERR_RAND_ZERO); + ASSERT_TRUE(BN_SetLimb(bn, 1) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetSign(bn, true) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_RandRange(bn, bn) == CRYPT_BN_ERR_RAND_NEGATIVE); +exit: + BN_Destroy(bn); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_BNGCDCHECKINPUT_API_TC001 + * @title BnGcdCheckInput: Invalid parameter. + * @precon nan + * @brief + * 1. Call the BnGcdCheckInput method, parameters are null, expected result 1 + * 2. Call the BnGcdCheckInput method, a and b are BN_MAX_BITS, expected result 2 + * 3. Call the BnGcdCheckInput method, a and b are 0, expected result 3 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_ERR_GCD_NO_ZERO + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_BNGCDCHECKINPUT_API_TC001(void) +{ + BN_BigNum *r; + BN_BigNum *a; + BN_BigNum *b; + BN_Optimizer *opt = NULL; + + TestMemInit(); + r = BN_Create(BITS_OF_BYTE); + a = BN_Create(LONG_BN_BITS_256); + b = BN_Create(LONG_BN_BITS_256); + opt = BN_OptimizerCreate(); + + ASSERT_TRUE(BnGcdCheckInput(NULL, NULL, NULL, NULL) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_SetLimb(a, BN_MAX_BITS) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetLimb(b, BN_MAX_BITS) == CRYPT_SUCCESS); + ASSERT_TRUE(BnGcdCheckInput(r, a, b, opt) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Zeroize(a) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Zeroize(b) == CRYPT_SUCCESS); + ASSERT_TRUE(BnGcdCheckInput(r, a, b, opt) == CRYPT_BN_ERR_GCD_NO_ZERO); +exit: + BN_Destroy(r); + BN_Destroy(a); + BN_Destroy(b); + BN_OptimizerDestroy(opt); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_MODINVINPUTCHECK_API_TC001 + * @title InverseInputCheck: Invalid parameter. + * @precon nan + * @brief + * 1. Call the InverseInputCheck method, parameters are null, expected result 1 + * 2. Call the InverseInputCheck method, x and m are BN_MAX_BITS, expected result 2 + * 3. Call the InverseInputCheck method, x and m are 0, expected result 3 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_ERR_DIVISOR_ZERO + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_MODINVINPUTCHECK_API_TC001(void) +{ + BN_BigNum *r; + BN_BigNum *x; + BN_BigNum *m; + BN_Optimizer *opt = NULL; + + TestMemInit(); + r = BN_Create(BITS_OF_BYTE); + x = BN_Create(LONG_BN_BITS_256); + m = BN_Create(LONG_BN_BITS_256); + opt = BN_OptimizerCreate(); + ASSERT_TRUE(r != NULL && x != NULL && m != NULL && opt != NULL); + + ASSERT_TRUE(InverseInputCheck(NULL, NULL, NULL, NULL) == CRYPT_NULL_INPUT); + ASSERT_TRUE(BN_SetLimb(x, BN_MAX_BITS) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_SetLimb(m, BN_MAX_BITS) == CRYPT_SUCCESS); + ASSERT_TRUE(InverseInputCheck(r, x, m, opt) == CRYPT_SUCCESS); + + ASSERT_TRUE(BN_Zeroize(x) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Zeroize(m) == CRYPT_SUCCESS); + ASSERT_TRUE(InverseInputCheck(r, x, m, opt) == CRYPT_BN_ERR_DIVISOR_ZERO); +exit: + BN_Destroy(r); + BN_Destroy(x); + BN_Destroy(m); + BN_OptimizerDestroy(opt); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_U64_FUNC_TC001 + * @title BN_U64Array2Bn/BN_Bn2U64Array test. + * @precon nan + * @brief + * 1. Randomly generate a 64-bit unsigned array. + * 2. Convert the array to a big number, and then convert the big number to array, expected result 1. + * 3. compare whether the arrays are the same, expected result 2 + * @expect + * 1. CRYPT_SUCCESS + * 2. The two arrays are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_U64_FUNC_TC001(int len) +{ + TestMemInit(); + BN_BigNum *a = BN_Create(0); + uint64_t *input = calloc(1, len * sizeof(uint64_t)); + uint64_t *output = calloc(1, len * sizeof(uint64_t)); + uint32_t outlen = len; + for (int i = 0; i < len; i++) { + input[i] = rand(); + } + input[len - 1] = 1; + + ASSERT_TRUE(BN_U64Array2Bn(a, input, (uint32_t)len) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Bn2U64Array(a, output, &outlen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(input, output, outlen * sizeof(uint64_t)) == 0); + input[len - 1] = 0; + + ASSERT_TRUE(BN_U64Array2Bn(a, input, len) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Bn2U64Array(a, output, &outlen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(input, output, outlen * sizeof(uint64_t)) == 0); +exit: + BN_Destroy(a); + free(input); + free(output); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_UINT_FUNC_TC001 + * @title BN_Array2BN/BN_BN2Array test. + * @precon nan + * @brief + * 1. Randomly generate a BN_UINT unsigned array. + * 2. Convert the array to a big number, and then convert the big number to array, expected result 1. + * 3. compare whether the arrays are the same, expected result 2 + * @expect + * 1. CRYPT_SUCCESS + * 2. The two arrays are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_UINT_FUNC_TC001(int len) +{ + TestMemInit(); + BN_BigNum *a = BN_Create(0); + BN_UINT *input = calloc(1, len * sizeof(BN_UINT)); + BN_UINT *output = calloc(1, len * sizeof(BN_UINT)); + for (int i = 0; i < len; i++) { + input[i] = rand(); + } + + ASSERT_TRUE(BN_Array2BN(a, input, len) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_BN2Array(a, output, len) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(input, output, len * sizeof(BN_UINT)) == 0); +exit: + BN_Destroy(a); + free(input); + free(output); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_GCD_FUNC_TC001 + * @title BN_Gcd test. + * @precon Vectors: two big numbers, result. + * @brief + * 1. Convert vectors to big numbers. + * 2. Call BN_Gcd to calculate the modular exponentiation, and compared to the vector value, expected result 1: + * (1) Pointer addresses for parameters are different from each other. + * (2) The address of the output parameter pointer r is the same as that of the input parameter pointer a. + * (3) The address of the output parameter pointer r is the same as that of the input parameter pointer b. + * 3. Test the scenario where the output parameter space is insufficient, expected result 1. + * @expect + * 1. The calculation result is consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_GCD_FUNC_TC001(int sign1, Hex *hex1, int sign2, Hex *hex2, Hex *result) +{ + TestMemInit(); + BN_BigNum *out = NULL; + BN_Optimizer *opt = NULL; + uint32_t maxBits; + + BN_BigNum *bn = TEST_VectorToBN(sign1, hex1->x, hex1->len); + BN_BigNum *bn2 = TEST_VectorToBN(sign2, hex2->x, hex2->len); + BN_BigNum *res = TEST_VectorToBN(0, result->x, result->len); + ASSERT_TRUE(bn != NULL && bn2 != NULL && res != NULL); + + maxBits = TEST_GetMax(BN_Bits(bn), BN_Bits(bn2), 0); + out = BN_Create(maxBits + BIGNUM_REDUNDANCY_BITS); + ASSERT_TRUE(out != NULL); + + opt = BN_OptimizerCreate(); + ASSERT_TRUE(opt != NULL); + + ASSERT_EQ(BN_Copy(out, bn), CRYPT_SUCCESS); + ASSERT_EQ(BN_Gcd(out, bn, bn2, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(out, res) == 0); + + ASSERT_EQ(BN_Copy(out, bn), CRYPT_SUCCESS); + ASSERT_EQ(BN_Gcd(out, out, bn2, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(out, res) == 0); + + ASSERT_EQ(BN_Copy(out, bn2), CRYPT_SUCCESS); + ASSERT_EQ(BN_Gcd(out, bn, out, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == b", BN_Cmp(out, res) == 0); + BN_Destroy(out); + + /* Test the scenario where the output parameter space is insufficient. */ + out = BN_Create(0); + ASSERT_TRUE(out != NULL); + + ASSERT_EQ(BN_Gcd(out, bn, bn2, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r != a", BN_Cmp(out, res) == 0); + BN_Destroy(out); + + out = BN_Create(0); + ASSERT_TRUE(out != NULL); + ASSERT_EQ(BN_Copy(out, bn), CRYPT_SUCCESS); + ASSERT_EQ(BN_Gcd(out, out, bn2, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == a", BN_Cmp(out, res) == 0); + BN_Destroy(out); + + out = BN_Create(0); + ASSERT_TRUE(out != NULL); + ASSERT_EQ(BN_Copy(out, bn2), CRYPT_SUCCESS); + ASSERT_EQ(BN_Gcd(out, bn, out, opt), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("r == b", BN_Cmp(out, res) == 0); + +exit: + BN_Destroy(bn); + BN_Destroy(bn2); + BN_Destroy(res); + BN_Destroy(out); + BN_OptimizerDestroy(opt); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_CMP_FUNC_TC001 + * @title BN_Cmp test. + * @precon Vectors: two big numbers, result. + * @brief + * 1. Convert vectors to big numbers. + * 2. Call the BN_Cmp method to compare two large numbers, expected result 1. + * @expect + * 1. The comparison results are the same as 'result'. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_CMP_FUNC_TC001(int sign1, Hex *hex1, int sign2, Hex *hex2, int result) +{ + TestMemInit(); + + BN_BigNum *bn1 = TEST_VectorToBN(sign1, hex1->x, hex1->len); + BN_BigNum *bn2 = TEST_VectorToBN(sign2, hex2->x, hex2->len); + /* bn1 and bn2 can be null. */ + + ASSERT_EQ(BN_Cmp(bn1, bn2), result); + +exit: + BN_Destroy(bn1); + BN_Destroy(bn2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_ADD_FUNC_TC001 + * @title BN_Add test. + * @precon a + b = r + * @brief + * 1. Convert vectors to big numbers. + * 2. Call the BN_Add method to calculate the sum of two large numbers, expected result 1. + * 3. If expectRet=CRYPT_SUCCESS and r=null(i.e.a=-b), call BN_IsZero to check whether sum is 0, expected result 2. + * 4. If expectRet=CRYPT_SUCCESS, call the BN_Cmp to compare r and resBn, expected result 3. + * @expect + * 1. The return value is the same as 'expectRet'. + * 2. The calculated sum is 0. + * 3. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_ADD_FUNC_TC001(int sign1, int sign2, int sign3, Hex *a, Hex *b, Hex *r, int expectRet) +{ + TestMemInit(); + BN_BigNum *resBn = NULL; + + BN_BigNum *bn1 = TEST_VectorToBN(sign1, a->x, a->len); + BN_BigNum *bn2 = TEST_VectorToBN(sign2, b->x, b->len); + BN_BigNum *sum = TEST_VectorToBN(sign3, r->x, r->len); + /* bn1, bn2 and sum can be null. */ + + resBn = BN_Create(SHORT_BN_BITS_128); + ASSERT_TRUE(resBn != NULL); + + ASSERT_EQ(BN_Add(resBn, bn1, bn2), expectRet); + if (expectRet == CRYPT_SUCCESS) { + if (r->len == 0) { + ASSERT_EQ(BN_IsZero(resBn), 1); + } else { + ASSERT_EQ(BN_Cmp(resBn, sum), 0); + } + } + +exit: + BN_Destroy(bn1); + BN_Destroy(bn2); + BN_Destroy(sum); + BN_Destroy(resBn); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_BN_TO_BIN_FIX_ZERO_API_TC001 + * @title BN_Bn2BinFixZero test. + * @precon nan + * @brief + * 1. Call the BN_Create method to create bn, parameter is 0, expected result 1. + * 2. Call the BN_Bn2BinFixZero method, expected result 2: + * (1) bn is null + * (2) bin is null + * (3) binLen is 0 + * 3. Call the BN_Bn2BinFixZero method, all parameters are valid, expected result 3 + * 4. Destroy bn and recreate bn, bits is 128, expected result 4. + * 5. Set the highest bit of bn to 1, expected result 5. + * 6. Call the BN_Bn2BinFixZero method, binLen is 1, expected result 6. + * @expect + * 1. Success. + * 2. CRYPT_NULL_INPUT. + * 3. CRYPT_SUCCESS. + * 4. Success. + * 5. CRYPT_SUCCESS. + * 6. CRYPT_BN_BUFF_LEN_NOT_ENOUGH. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_BN_TO_BIN_FIX_ZERO_API_TC001(void) +{ + TestMemInit(); + uint8_t bin[1] = {0}; + BN_BigNum *bn = BN_Create(0); + ASSERT_TRUE(bn != NULL); + + ASSERT_EQ(BN_Bn2BinFixZero(NULL, bin, 1), CRYPT_NULL_INPUT); + ASSERT_EQ(BN_Bn2BinFixZero(bn, NULL, 1), CRYPT_NULL_INPUT); + ASSERT_EQ(BN_Bn2BinFixZero(bn, bin, 0), CRYPT_NULL_INPUT); + + // bn bytes is 0 + ASSERT_EQ(BN_Bn2BinFixZero(bn, bin, 1), CRYPT_SUCCESS); + BN_Destroy(bn); + + bn = BN_Create(SHORT_BN_BITS_128); + ASSERT_TRUE(bn != NULL); + ASSERT_EQ(BN_SetBit(bn, SHORT_BN_BITS_128 - 1), CRYPT_SUCCESS); + + ASSERT_EQ(BN_Bn2BinFixZero(bn, bin, 1), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + +exit: + BN_Destroy(bn); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/bn/test_suite_sdv_bn.data b/testcode/sdv/testcase/crypto/bn/test_suite_sdv_bn.data new file mode 100644 index 00000000..08256502 --- /dev/null +++ b/testcode/sdv/testcase/crypto/bn/test_suite_sdv_bn.data @@ -0,0 +1,930 @@ + +SDV_CRYPTO_BN_CREATE_API_TC001 +SDV_CRYPTO_BN_CREATE_API_TC001: + +SDV_CRYPTO_BN_SETSIGN_API_TC001 +SDV_CRYPTO_BN_SETSIGN_API_TC001: + +SDV_CRYPTO_BN_COPY_API_TC001 +SDV_CRYPTO_BN_COPY_API_TC001: + +SDV_CRYPTO_BN_ZEROIZE_API_TC001 +SDV_CRYPTO_BN_ZEROIZE_API_TC001: + +SDV_CRYPTO_BN_SETLIMB_API_TC001 +SDV_CRYPTO_BN_SETLIMB_API_TC001: + +SDV_CRYPTO_BN_SETBIT_API_TC001 +SDV_CRYPTO_BN_SETBIT_API_TC001: + +BN_GetBit Arguments Test +SDV_CRYPTO_BN_GETBIT_API_TC001: + +SDV_CRYPTO_BN_CLRBIT_API_TC001 +SDV_CRYPTO_BN_CLRBIT_API_TC001: + +BN_Rshift Verification Test vec #1 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":1:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39e4e395" + +BN_Rshift Verification Test vec #2 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":2:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9cf271ca" + +BN_Rshift Verification Test vec #3 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":3:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce7938e5" + +BN_Rshift Verification Test vec #4 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":4:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72" + +BN_Rshift Verification Test vec #5 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":5:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39e4e39" + +BN_Rshift Verification Test vec #6 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":6:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9cf271c" + +BN_Rshift Verification Test vec #7 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":7:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce7938e" + +BN_Rshift Verification Test vec #8 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":8:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c7" + +BN_Rshift Verification Test vec #9 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":9:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39e4e3" + +BN_Rshift Verification Test vec #10 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":10:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9cf271" + +BN_Rshift Verification Test vec #11 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":11:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce7938" + +BN_Rshift Verification Test vec #12 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":12:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c" + +BN_Rshift Verification Test vec #13 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":13:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39e4e" + +BN_Rshift Verification Test vec #14 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":14:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9cf27" + +BN_Rshift Verification Test vec #15 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":15:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce793" + +BN_Rshift Verification Test vec #16 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":16:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9" + +BN_Rshift Verification Test vec #17 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":17:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39e4" + +BN_Rshift Verification Test vec #18 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":18:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9cf2" + +BN_Rshift Verification Test vec #19 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":19:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce79" + +BN_Rshift Verification Test vec #20 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":20:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c" + +BN_Rshift Verification Test vec #21 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":21:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39e" + +BN_Rshift Verification Test vec #22 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":22:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9cf" + +BN_Rshift Verification Test vec #23 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":23:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce7" + +BN_Rshift Verification Test vec #24 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":24:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73" + +BN_Rshift Verification Test vec #25 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":25:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff39" + +BN_Rshift Verification Test vec #26 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":26:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9c" + +BN_Rshift Verification Test vec #27 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":27:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffce" + +BN_Rshift Verification Test vec #28 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":28:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe7" + +BN_Rshift Verification Test vec #29 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":29:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff3" + +BN_Rshift Verification Test vec #30 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":30:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff9" + +BN_Rshift Verification Test vec #31 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":31:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce7938ffc" + +BN_Rshift Verification Test vec #32 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":32:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe" + +BN_Rshift Verification Test vec #33 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":33:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4e3ff" + +BN_Rshift Verification Test vec #34 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":34:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf271ff" + +BN_Rshift Verification Test vec #35 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":35:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce7938ff" + +BN_Rshift Verification Test vec #36 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":36:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7f" + +BN_Rshift Verification Test vec #37 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":37:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e4e3f" + +BN_Rshift Verification Test vec #38 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":38:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf271f" + +BN_Rshift Verification Test vec #39 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":39:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce7938f" + +BN_Rshift Verification Test vec #40 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":40:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7" + +BN_Rshift Verification Test vec #41 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":41:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4e3" + +BN_Rshift Verification Test vec #42 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":42:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf271" + +BN_Rshift Verification Test vec #43 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":43:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce7938" + +BN_Rshift Verification Test vec #44 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":44:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c9c" + +BN_Rshift Verification Test vec #45 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":45:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e4e" + +BN_Rshift Verification Test vec #46 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":46:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf27" + +BN_Rshift Verification Test vec #47 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":47:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce793" + +BN_Rshift Verification Test vec #48 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":48:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9" + +BN_Rshift Verification Test vec #49 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":49:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39e4" + +BN_Rshift Verification Test vec #50 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":50:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9cf2" + +BN_Rshift Verification Test vec #51 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":51:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce79" + +BN_Rshift Verification Test vec #52 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":52:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe73c" + +BN_Rshift Verification Test vec #53 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":53:0:"022d711adff39e4e3d2f4c7bdb09ad9adff39e" + +BN_Rshift Verification Test vec #54 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":54:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9cf" + +BN_Rshift Verification Test vec #55 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":55:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fce7" + +BN_Rshift Verification Test vec #56 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":56:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73" + +BN_Rshift Verification Test vec #57 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":57:0:"22d711adff39e4e3d2f4c7bdb09ad9adff39" + +BN_Rshift Verification Test vec #58 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":58:0:"116b88d6ff9cf271e97a63ded84d6cd6ff9c" + +BN_Rshift Verification Test vec #59 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":59:0:"08b5c46b7fce7938f4bd31ef6c26b66b7fce" + +BN_Rshift Verification Test vec #60 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":60:0:"045ae235bfe73c9c7a5e98f7b6135b35bfe7" + +BN_Rshift Verification Test vec #61 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":61:0:"022d711adff39e4e3d2f4c7bdb09ad9adff3" + +BN_Rshift Verification Test vec #62 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":62:0:"0116b88d6ff9cf271e97a63ded84d6cd6ff9" + +BN_Rshift Verification Test vec #63 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":63:0:"8b5c46b7fce7938f4bd31ef6c26b66b7fc" + +BN_Rshift Verification Test vec #64 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":64:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe" + +BN_Rshift Verification Test vec #65 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":65:0:"22d711adff39e4e3d2f4c7bdb09ad9adff" + +BN_Rshift Verification Test vec #66 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":66:0:"116b88d6ff9cf271e97a63ded84d6cd6ff" + +BN_Rshift Verification Test vec #67 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":67:0:"08b5c46b7fce7938f4bd31ef6c26b66b7f" + +BN_Rshift Verification Test vec #68 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":68:0:"045ae235bfe73c9c7a5e98f7b6135b35bf" + +BN_Rshift Verification Test vec #69 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":69:0:"022d711adff39e4e3d2f4c7bdb09ad9adf" + +BN_Rshift Verification Test vec #70 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":70:0:"0116b88d6ff9cf271e97a63ded84d6cd6f" + +BN_Rshift Verification Test vec #71 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":71:0:"8b5c46b7fce7938f4bd31ef6c26b66b7" + +BN_Rshift Verification Test vec #72 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":72:0:"45ae235bfe73c9c7a5e98f7b6135b35b" + +BN_Rshift Verification Test vec #73 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":73:0:"22d711adff39e4e3d2f4c7bdb09ad9ad" + +BN_Rshift Verification Test vec #74 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":74:0:"116b88d6ff9cf271e97a63ded84d6cd6" + +BN_Rshift Verification Test vec #75 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":75:0:"08b5c46b7fce7938f4bd31ef6c26b66b" + +BN_Rshift Verification Test vec #76 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":76:0:"045ae235bfe73c9c7a5e98f7b6135b35" + +BN_Rshift Verification Test vec #77 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":77:0:"022d711adff39e4e3d2f4c7bdb09ad9a" + +BN_Rshift Verification Test vec #78 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":78:0:"0116b88d6ff9cf271e97a63ded84d6cd" + +BN_Rshift Verification Test vec #79 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":79:0:"8b5c46b7fce7938f4bd31ef6c26b66" + +BN_Rshift Verification Test vec #80 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":80:0:"45ae235bfe73c9c7a5e98f7b6135b3" + +BN_Rshift Verification Test vec #81 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":81:0:"22d711adff39e4e3d2f4c7bdb09ad9" + +BN_Rshift Verification Test vec #82 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":82:0:"116b88d6ff9cf271e97a63ded84d6c" + +BN_Rshift Verification Test vec #83 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":83:0:"08b5c46b7fce7938f4bd31ef6c26b6" + +BN_Rshift Verification Test vec #84 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":84:0:"045ae235bfe73c9c7a5e98f7b6135b" + +BN_Rshift Verification Test vec #85 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":85:0:"022d711adff39e4e3d2f4c7bdb09ad" + +BN_Rshift Verification Test vec #86 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":86:0:"0116b88d6ff9cf271e97a63ded84d6" + +BN_Rshift Verification Test vec #87 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":87:0:"8b5c46b7fce7938f4bd31ef6c26b" + +BN_Rshift Verification Test vec #88 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":88:0:"45ae235bfe73c9c7a5e98f7b6135" + +BN_Rshift Verification Test vec #89 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":89:0:"22d711adff39e4e3d2f4c7bdb09a" + +BN_Rshift Verification Test vec #90 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":90:0:"116b88d6ff9cf271e97a63ded84d" + +BN_Rshift Verification Test vec #91 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":91:0:"08b5c46b7fce7938f4bd31ef6c26" + +BN_Rshift Verification Test vec #92 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":92:0:"045ae235bfe73c9c7a5e98f7b613" + +BN_Rshift Verification Test vec #93 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":93:0:"022d711adff39e4e3d2f4c7bdb09" + +BN_Rshift Verification Test vec #94 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":94:0:"0116b88d6ff9cf271e97a63ded84" + +BN_Rshift Verification Test vec #95 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":95:0:"8b5c46b7fce7938f4bd31ef6c2" + +BN_Rshift Verification Test vec #96 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":96:0:"45ae235bfe73c9c7a5e98f7b61" + +BN_Rshift Verification Test vec #97 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":97:0:"22d711adff39e4e3d2f4c7bdb0" + +BN_Rshift Verification Test vec #98 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":98:0:"116b88d6ff9cf271e97a63ded8" + +BN_Rshift Verification Test vec #99 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":99:0:"08b5c46b7fce7938f4bd31ef6c" + +BN_Rshift Verification Test vec #100 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"45ae235bfe73c9c7a5e98f7b6135b35bfe73c9c7fe73c9c72b":100:0:"045ae235bfe73c9c7a5e98f7b6" + +BN_Rshift Verification Test vec #101 +SDV_CRYPTO_BN_RSHIFT_FUNC_TC001:0:"d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701":1000:0:"00" + +_BN_ModInv Arguments Test +SDV_CRYPTO_BN_MODINV_API_TC001: + +BN_ModInv Verification Test #1 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"03":"03":"" + +BN_ModInv Verification Test #2 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"0f":"03":"" + +BN_ModInv Verification Test #3 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"0f":"06":"" + +BN_ModInv Verification Test #4 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"06":"0f":"" + +BN_ModInv Verification Test #5 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"05":"08":"05" + +BN_ModInv Verification Test #6 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"08":"05":"02" + +BN_ModInv Verification Test #7 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"08":"05":"03" + +BN_ModInv Verification Test #8 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"20":"0b":"0a" + +BN_ModInv Verification Test #9 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"20":"0b":"01" + +BN_ModInv Verification Test #10 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"03":"0B":"04" + +BN_ModInv Verification Test #11 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"64a5d6e7a7c3a6b4e6f76f29a98d0c8e8b6f":"f423bfe7a476a8d8be976e56fb6c521c3134ca":"41f3be966528ef2502504a387f2f1c120fcaed" + +BN_ModInv Verification Test #12 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"64a5d6e7a7c3a6b4e6f76f29a98d0c8e8b6f":"f423bfe7a476a8d8be976e56fb6c521c3134ca":"b23001513f4db9b3bc47241e7c3d360a2169dd" + +BN_ModInv Verification Test #13 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"ffffffffffffffffffffffffffffffff":"fffffffffffffffffffffffffffffffe":"01" + +BN_ModInv Verification Test #14 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"01":"ffffffffffffffffffffffffffffffff":"fffffffffffffffffffffffffffffffe" + +BN_ModInv Verification Test #15 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"01":"ffffffffffffffffffffffffffffffff":"01" + +BN_ModInv Verification Test #16 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"ffffffffffffffffffffffffffffffff":"11111111111111111111111111111111":"" + +BN_ModInv Verification Test #17 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"11111111111111111111111111111111":"ffffffffffffffffffffffffffffffff":"" + +BN_ModInv Verification Test #18 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:0:"05efb6544b3c5a90a8c65c64a5f423bc64a5d6d6e7a7c3a6b4e6f76f29a98d0c8e8b6f":"f423bc64a5d6e7a7c3a6b4e6f76fe7a476a8d8be976e56fb6c521c3134ca":"c7bec42a971b574baa7b6ffb19cc852cc65063973f7ebe4470f092bc6797" + +BN_ModInv Verification Test #19 +SDV_CRYPTO_BN_MODINV_FUNC_TC002:1:"05efb6544b3c5a90a8c65c64a5f423bc64a5d6d6e7a7c3a6b4e6f76f29a98d0c8e8b6f":"f423bc64a5d6e7a7c3a6b4e6f76fe7a476a8d8be976e56fb6c521c3134ca":"2c64f83a0ebb905c192b44ebdda36277b058752757ef98b6fb618974cd33" + +SDV_CRYPTO_BN_MOD_EXP_INPUT_CHECK_API_TC001 +SDV_CRYPTO_BN_MOD_EXP_INPUT_CHECK_API_TC001: + +SDV_CRYPTO_BN_MODEXP_API_TC001 +SDV_CRYPTO_BN_MODEXP_API_TC001: + +SDV_CRYPTO_BN_MODEXP_API_TC002 +SDV_CRYPTO_BN_MODEXP_API_TC002: + +BN_ModExp Verification Test #1: a=0 +SDV_CRYPTO_BN_MODEXP_FUNC_TC001:0:"00":"bb3ba6d03be8f8d8e8419826":"de459be6a8a92b":"00" + +BN_ModExp Verification Test #2: e=0 +SDV_CRYPTO_BN_MODEXP_FUNC_TC001:0:"bb3ba6d03be8f8d8e8419826":"00":"54e3322b846a9dbc38de459be6a8a92b":"01" + +BN_ModExp Verification Test #3: +SDV_CRYPTO_BN_MODEXP_FUNC_TC001:0:"03b35da4a98e73":"0d53b1c94ca26d745000":"03e6a7d8c3b4d6a3e597":"0347604f2fdbde7b24d5" + +SDV_CRYPTO_BN_MODEXPCORE_API_TC001 +SDV_CRYPTO_BN_MODEXPCORE_API_TC001: + +SDV_CRYPTO_BN_MOD_API_TC001 +SDV_CRYPTO_BN_MOD_API_TC001: + +BN_Mod Verification Test vec #1 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"05":0:"07":"05" + +BN_Mod Verification Test vec #2 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"07":0:"05":"02" + +BN_Mod Verification Test vec #3 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"00":0:"06":"00" + +BN_Mod Verification Test vec #4 +SDV_CRYPTO_BN_MOD_FUNC_TC001:1:"0f":0:"02":"01" + +BN_Mod Verification Test vec #4 +SDV_CRYPTO_BN_MOD_FUNC_TC001:1:"31388af50a23886231eaccd8bb47e606ae73707b37bda88c6206e78b18d1cee88fd87ef47b84b62d71c386":1:"018aec343fe0":"0137ef1fc5da" + +BN_Mod Verification Test vec #5 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0b2612136e5bf46c475a30732c36532ba0cc360833a77e84bc0e70":0:"03e2bca81ee33b31d1f6463ee520ed5a4c242d76457a2d4d2e5c4cb4d8df25663c6187":"0b2612136e5bf46c475a30732c36532ba0cc360833a77e84bc0e70" + +BN_Mod Verification Test vec #6 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0326226f070e3fc8c7345feee1518efdc3a8cb77b61e7d0857bf15":0:"0a278f271a304f0437d6bc08f770e10e52b21c4b75c53cee7bdf6c0431261fa3cd234b4b":"0326226f070e3fc8c7345feee1518efdc3a8cb77b61e7d0857bf15" + +BN_Mod Verification Test vec #7 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"064a024fbeb74cda60eddae0b48ffacc4dc5ed4b2e1bcfa820a2bad0f5eb5d10b6de5f74f725c777132b5f48347315813f826fe61d33873ed5ca8e6bb6eb7bec":0:"caefe1e17a32da8d5db3d511276bf2d7ed7bc70c27d6cf85a1d770d8436cc58d42a8703d5acacab77d2148a40cda847fd7cb0586a34e":"6d2f127cf3461318d8b42bb862944717faf6fbffc828ba494a366df64437af5224a46d0e08f0a15402c682f51450d75614e7c6b57202" + +BN_Mod Verification Test vec #8 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"14d772d8f5e6ce2e8af505d25ba65bdf317ea121b465ced0364f1638bb86b031dda38f748ad722156ea6684fcc43a27d4245fe76":0:"06":"02" + +BN_Mod Verification Test vec #9 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0dada6fc24686ea23f3c127121a12c2757ce8e2eed58e84abbf0d7a6bb7e2bd8ac5175d0bae37273200564c1a61168865777344dc71df70cadeeb2e8":1:"0efd421a27b76a6ffb5ddc3ce2427d8f53e58732ddc4772e61f73a87066c7874cf3a0e78717fe10e56374a3f8147":"0acb48d64e57070725044d1a06f03fc42c0f9c9b8cbb12f3fc98335629af1b7133145af90e249e0311f83adb25d3" + +BN_Mod Verification Test vec #10 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"47736d12bc7cabb1331d34e84515d5f75728dd":0:"02e577047be70c72d175e3477c583c0e15b8bf46ec54bad5fb872cb2665410a0bf1025b57731a8ca260dff2265d5307f0eea417ac03b515d4b7d10b151a0":"47736d12bc7cabb1331d34e84515d5f75728dd" + +BN_Mod Verification Test vec #11 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"018f62e74ce1d7b74f6824f5d47db840aaead25e0c728d6c13f5725a0fd248575caacea88da7e756108b6b640f":0:"a4a4338e76f1faeafe":"33d2c3ef2a4cfe048f" + +BN_Mod Verification Test vec #12 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"06183ef04ba8":0:"7b7ecabeb1170d3e7f73a1e078ccfef427b776e77527f542071c5ac5aca56e28243fe6d6d873":"06183ef04ba8" + +BN_Mod Verification Test vec #13 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"6365bdccf4ee776f1e7af70d21814ba75e00df084b3e85854b15b7ae4843a7ac2f6d7fbd5c71287fec378607407636fe761027dd":0:"ceac6335411be40fde14350881a7cefda16dd60e2ddc1d6dd3548c4be3b32f33d70de7a0a7cc2f86e0578ee107d4be30c1153eee72dbdc46a7":"6365bdccf4ee776f1e7af70d21814ba75e00df084b3e85854b15b7ae4843a7ac2f6d7fbd5c71287fec378607407636fe761027dd" + +BN_Mod Verification Test vec #14 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"01303523812a77":0:"0147dd1dfd7364410d783866ddaf1f505f717773630352d1c38387668431dd12783caef62713583d0c1023efbf3c3a142eb1081135df6378dc6ad762fb3d73":"01303523812a77" + +BN_Mod Verification Test vec #15 +SDV_CRYPTO_BN_MOD_FUNC_TC001:1:"1b50eb544f745b22f30b8a14b346e4ffdbe0f4610773c1ef8e2102fc47746aaecc71666823f47e8f8e2c7aa80d847ef8b837d17a117858326d4d4a3d5da0d5fa5662314bc70512323be83ea174bdce523f3b2b16b8a8d53287036d2d61e65fb13165b3c7b44b105fad8d75757a65c207e56137170c2773a05af22dba856e2eb8":0:"d32737e724b77e1341b2d5c0d150a81b584bb3132bed278d5262864afcbf730a738be4485f8d413a172e7b802c21ac71c11c520c2726a471dcad212eac7ca3fd":"56fff26486134caad6c7718846e86eb57824fed4c07132236bce5e13410cd3ba72eb79599af271ecfc3ba5499835c661ef7c0bf69170d44e81fff247ff205e54" + +BN_Mod Verification Test vec #16 +SDV_CRYPTO_BN_MOD_FUNC_TC001:1:"184dceffef5ed3337b516b3fb7dbaa8320562a707f102030164b7ce4a176e71b57c501b17275fd8aeee771bc52d441b7b7b0d26b4bcf7bfc2c3c007526d7f65b":0:"f62eddcc36fcba8ebb260ee6b6a126df346e38c5":"ec69d3ea4ee5e046de6b5d186021f69735f96532" + +BN_Mod Verification Test vec #17 +SDV_CRYPTO_BN_MOD_FUNC_TC001:1:"40148f89da93e8d3f21a11e66d2f08f445babb8ab8c3c2ef1b94312e6cbf348dc65831f8c49ee202f8e6f88233fb3ef8e462d5e4d3c81da2cbc9335f9b1a8f51":0:"962f88cc369cba8fbb260ff6b6a12689346f38c5":"7bf75c06120f3754c7019da1b9f6423d6d21ae48" + +BN_Mod Verification Test vec #18 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"30000000000000000030303030000000000000000000000000":0:"30000000000000000000000000":"00" + +BN_Mod Verification Test vec #19 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"381c7c4c0034df5cda4d7a3dac384544c36a7e4c0e4b6b44454abff3ff132dd127affd275d788c":0:"784584b5713ebab503a5":"411544e9e59aa5c0e20a" + +BN_Mod Verification Test vec #20 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"035d":0:"6341a178572c77cdcdfa35e2f3":"035d" + +BN_Mod Verification Test vec #21 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"01b25f08a724ddfac8":0:"4b61a7d18feed48f7d0ec650e7aff1387e08d6cf37f7a271782a1ffd87b3e54bf4f5c11e04f62781a46d510c176244166afa572f":"01b25f08a724ddfac8" + +BN_Mod Verification Test vec #22 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0324db51eb03ef8b7c5f8bae4ef7ee42c447b8c0bf2a51":0:"076ed7e7c0c68a78c3ae54":"037c8307bbc0a53581665d" + +BN_Mod Verification Test vec #23 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"7afb406dfa4b4d87e70ae11cbb77a4e7a70b38635bcc422b73473686a32e77ddcab7cae48b18eb72a2cd07dd45b34d753e85d8fa52fa45c56a7a":0:"0c0e2a4c6b748b37d817cec40b7012ffce574e1ccc0ca12624b340eabfaae686b8f052":"45061171e46f0e6f4e3bbace9fd8ed93302bf973e0597ee64b7b06c665d93f3ac978" + +BN_Mod Verification Test vec #24 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"30a7c63f2c4ac4b1be8778ccda5a64cce13cc4405a18":0:"1c88fb7ab36165defed57ca407afeeeffb2ddcf47a386e5705c71ccf1075627d7e7d773257dc873db205e141ae50f64a7e735e782c4d58b01d":"30a7c63f2c4ac4b1be8778ccda5a64cce13cc4405a18" + +BN_Mod Verification Test vec #25 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"36da73b4b2d7adbc8a7a27d88e577fa635a8628e8ddfbbea0475e10f1627658c8fd8c13cb14b7fbbeaa0f47f":0:"37":"14" + +BN_Mod Verification Test vec #26 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"02c736e6f2a4daf3d758b4cb781c370c365f":0:"03504ba214b81fe3738bde7cd533448b1ad6b075eaf04df75cc5bc1bd17275":"02c736e6f2a4daf3d758b4cb781c370c365f" + +BN_Mod Verification Test vec #27 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"04040e116524bd444fa68bbe5ac53cdfc50e36e52be65fed61":0:"08e14582730a5e771870dcbeed2187142d476e7203c838117e1e3d64b6":"04040e116524bd444fa68bbe5ac53cdfc50e36e52be65fed61" + +BN_Mod Verification Test vec #28 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"035c703571ac16bc3c66427fc43c73b8b61712efef685ea2233ca5cd5d6dca1eca3b533c4b6f7823":0:"043b1d1576f14eada86017f2cf7635ec325bba074805":"03e375b3b31eff5c83b9959fa6c03fe435532a793756" + +BN_Mod Verification Test vec #29 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"31ada3a5c325e4eca4b7fd86e3370bc732a6e4b83021d72d78f2874eea76a5dda4cf0368eee8d41328721f8b2fa45b5b":0:"2bc1537ae3342fdb4630af":"1faecf16d9434cd338ade5" + +BN_Mod Verification Test vec #30 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"01a6de4c0107eca8dd71fcff4f7d4cfebcd58c753e73151777dffc35":0:"376efec40c3df08c4c7c35af6e51c3b85010578c656402a4d7f63bc771d70630bce37448a184d56d820b1870dcdb2f2d6b013fd0653b74bc":"01a6de4c0107eca8dd71fcff4f7d4cfebcd58c753e73151777dffc35" + +BN_Mod Verification Test vec #31 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"c34264a2c65a7e12f57587d7c0877c":0:"03c158cfe4d1c05d4a158a0d860bab":"03bdb33830912b7d332b07260c346b" + +BN_Mod Verification Test vec #32 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"6cd4c4afaaf17fd20beef35bea":0:"02886bd702b32bc0fac6a6b1d3bb633b6cb5a7427f516c8b4b3717b01271fb757f86ef7bba00bdd447e386faa06aef8cf77c4effcdbaa5":"6cd4c4afaaf17fd20beef35bea" + +BN_Mod Verification Test vec #34 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"3761b265ae5064462bba7cae2773f1acf41403068a307fb04df75bc72e4ae42d2b17f25f6877f7f3b11dc1e0f0540e25e711aa73c1":0:"0ca307c37ed7714844fe735c314cc428ecd7da8ffa3b1a6e4f3756da6f4ffc0eec":"828107d534218e1345ec0777d179253abe73fc609a1d434eac80abf064b512b5" + +BN_Mod Verification Test vec #35 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"057ae837700d4cb5f27717dd80":0:"047dd378877ef7407842a36f6e4b6356":"057ae837700d4cb5f27717dd80" + +BN_Mod Verification Test vec #36 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"03c875d742770ea7617a75618d3b50f53b5de5a7a743":0:"ed52f44fda23d1d8fa4222871a6407a8146f238f4ab145fa478077aca72070157184":"03c875d742770ea7617a75618d3b50f53b5de5a7a743" + +BN_Mod Verification Test vec #37 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"01330707ef812777e076c7777b237da6ea8ea72eb71c3eb020084baaddf3ef":0:"06c4bf45fb7a75135b6be3da66865f0d70e735202751dd5772e6a2fc44b684ba7c77":"01330707ef812777e076c7777b237da6ea8ea72eb71c3eb020084baaddf3ef" + +BN_Mod Verification Test vec #38 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"2b4dad5d1ac8f00057eb77c530a274b1b76eda0480eaa44e751a":0:"7235c6d2717221f7503be760bb404cba857c5d7b6ef5ef4fffea3537b82bd82cd7177ed1121771e1":"2b4dad5d1ac8f00057eb77c530a274b1b76eda0480eaa44e751a" + +BN_Mod Verification Test vec #39 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"04c801068741cb7effbb5fdf3072":0:"028326fa4e71eecb7bdfe7aba76fc3304adb784c61888d2d7de66fd641ffcfa3fde7bdebe02cb75c062888b6f1cb66dc275e2f88e6363664fcf7bbddb8850156":"04c801068741cb7effbb5fdf3072" + +BN_Mod Verification Test vec #40 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"1435711e75ab8c0a276a4006cfa28f2f8df7d0c4f7b0c83bf284b7e5c0eb76e422e703f7f3":0:"0821437fe04fc38452ecf1":"046b1abb39b184de1e8603" + +BN_Mod Verification Test vec #41 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"7be73d7e8c176c7626df":0:"1bd7622a7438f50eb6070c57015ca7a0181504b6418024be7e33fdeb2ac3c536fca7d7f0d775f7f705ab768687fe":"7be73d7e8c176c7626df" + +BN_Mod Verification Test vec #42 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"2008f3716153f778251c887c":0:"08e413efce":"03d0532cf0" + +BN_Mod Verification Test vec #43 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"376dcaf603e62fd35ecc84ee717b085ab583aeb1762c4b544774bfc5e88da6c77a715e7dd808d13754d526c651ad2107b0503fa77c287c43fe758887":0:"2330477d222e7b7ab5cd320aa3d7507505727cb54235ddbe5d5a027c508b04533bd3d0dc02ccd737fa8fc037e012b465":"0626fa3f6c21bac3dc83fa2a949fde1b2efe388b65b0713c74872b015907215df96c9d6ebffa8cefcd3a53b5b33c8442" + +BN_Mod Verification Test vec #44 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"d0e2cfef5ebca60722a070b8237521af64":0:"0f3ea1ace36fb3fdd2534f2823c478858e62e3ca88eaec2a5c254dd14776bef035d77cf84130":"d0e2cfef5ebca60722a070b8237521af64" + +BN_Mod Verification Test vec #45 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0b4076e5c321dd04b70a7271c13f32120a130a238cfd1b80d2b06fa084c36cd7846345c704234e7bacc0ed4b7fa001":0:"44b30b27b728c1b77a72":"20dd8e30f68f97a594ab" + +BN_Mod Verification Test vec #46 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"05ad40a06d6d805f1bdf285df641d3e4da612734e3a3e207a0c74bf1756b10fa1fc7bb073d":0:"02d7d7f588352ccf8ff1a46ac0584e64baef848b2017018c271b2576d62cb3f20d0c2ff5c0d4de4a6683b4275b048c":"05ad40a06d6d805f1bdf285df641d3e4da612734e3a3e207a0c74bf1756b10fa1fc7bb073d" + +BN_Mod Verification Test vec #47 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"2e076e478ff7d127ad737284bf27ed6a7bbe7171":0:"0bd7a2612a87a10e1e5b7bab63ea7a6c8acd1bb7410dbd3b3c2ba5376ff628ad77ca8e21df3027778baba36e16":"2e076e478ff7d127ad737284bf27ed6a7bbe7171" + +BN_Mod Verification Test vec #48 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"2723dcb53eb7e6f5d3e173733da80d124822efe46a7f5130a3de28405c16b4243f11df76d1c08ca5a3":0:"211f602f":"1003de43" + +BN_Mod Verification Test vec #49 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"05c0bec752ab52e1ef4bb6d0317710b0ba76a2eb86e562df7b5fe2":0:"3f775debc4fe2a8c70d65e5240c60f11":"391f4c74757df5a5022d644d57bd402c" + +BN_Mod Verification Test vec #50 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"50d7e538b5fbe3aaed876f":0:"02":"01" + +BN_Mod Verification Test vec #51 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"1576bbe17040d4c52f3c24b3dfdd":0:"02b2ab7b0be86e7cd75a757b":"37a3c28d54a98d11b5761b" + +BN_Mod Verification Test vec #52 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0dbf56f56207ccef3042cbb5760786ff17fe87c3f0a3ea34bc71b7bdb47fd52233abb71533056b6347b6ff3dbef757ef3ee61a4e0a":0:"02":"00" + +BN_Mod Verification Test vec #53 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"30dcd7ce05c38c14878f4bd5be1b3228386b14a2acc30c":0:"62000b450ec7560777336647b82ad34cb25df7081d33ba45ea26d88d52fc1a341c25":"30dcd7ce05c38c14878f4bd5be1b3228386b14a2acc30c" + +BN_Mod Verification Test vec #54 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"07856e778ef1b7":0:"133574b7d207c2d0fe72f4e77b48ab757f6bb357e7a2eec0cf74ae41834081f4b57716c786d8ff25cb2e8cc776b8bd70":"07856e778ef1b7" + +BN_Mod Verification Test vec #55 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"0efbe14c717f0117c54d7d4476aaad724b256a50bd5b4048fcab787365a4b7d4b71f237113a40f5871061ce730cfdaf74bc4":0:"4b2d20b075bcdb6ea741f2e61f1201bb04f3d78c6c51f208bfc252":"133621b1279ace6daae0e9859410defa644c2f00dacc27210e446a" + +BN_Mod Verification Test vec #56 +SDV_CRYPTO_BN_MOD_FUNC_TC001:0:"57a74b3d623aa8d8f07de3578d44160cec548245f4fd62ba308effdc7c8d86efb5751218a7":0:"3a704038d4f7":"2e6271af6cfd" + +SDV_CRYPTO_BN_PRIMECHECK_API_TC001 +SDV_CRYPTO_BN_PRIMECHECK_API_TC001: + +BN_PrimeCheck Verification Test #1 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"0a":0 + +BN_PrimeCheck Verification Test #2 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"0b":1 + +BN_PrimeCheck Verification Test #3 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"0c":0 + +BN_PrimeCheck Verification Test #4 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"0d":1 + +BN_PrimeCheck Verification Test #5 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"0e":0 + +BN_PrimeCheck Verification Test #6 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"0f":0 + +BN_PrimeCheck Verification Test #7 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"3d75a9b3c0":0 + +BN_PrimeCheck Verification Test #8 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"3d75a9b37123":1 + +BN_PrimeCheck Verification Test #9 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d64f":1 + +BN_PrimeCheck Verification Test #10 +SDV_CRYPTO_BN_PRIME_CHECK_FUNC_TC001:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e7":0 + +SDV_CRYPTO_BN_GENPRIMELIMB_API_TC001 +SDV_CRYPTO_BN_GENPRIMELIMB_API_TC001: + +BN_AddLimb test #1: a=NULL +SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001:0:"":0:0:"00":CRYPT_NULL_INPUT + +BN_AddLimb test #21: a=0, limb=1 +SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001:0:"00":1:0:"01":CRYPT_SUCCESS + +BN_AddLimb test #3: a is positive, a.size=1, alimb +SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001:0:"02":1:0:"03":CRYPT_SUCCESS + +BN_AddLimb test #6: a is negative, a.size=1, alimb +SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001:1:"02":1:1:"01":CRYPT_SUCCESS + +BN_AddLimb test #9: a +SDV_CRYPTO_BN_ADDLIMB_FUNC_TC001:0:"ffffffffffffffffffffffffffffffff":1:0:"0100000000000000000000000000000000":CRYPT_SUCCESS + +BN_Sub Test vec #1: 0 - 0 = 0 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"00":0:"00":0:"00" + +BN_Sub Test vec #2: 0 - 1 = -1 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"00":0:"01":1:"01" + +BN_Sub Test vec #3: 0 - (-1) = 1 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"00":1:"01":0:"01" + +BN_Sub Test vec #4: 1 - 1 = 0 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"01":0:"01":0:"00" + +BN_Sub Test vec #5: 1 - (-1) = 2 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"01":1:"01":0:"02" + +BN_Sub Test vec #6: 1 - 2 = -1 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"01":0:"02":1:"01" + +BN_Sub Test vec #7: 1 - (-2) = 3 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"01":1:"02":0:"03" + +BN_Sub Test vec #8: -1 - 1 = -2 +SDV_CRYPTO_BN_SUB_FUNC_TC001:1:"01":0:"01":1:"02" + +BN_Sub Test vec #9: -1 - (-1) = 0 +SDV_CRYPTO_BN_SUB_FUNC_TC001:1:"01":1:"01":0:"00" + +BN_Sub Test vec #10: -1 - 2 = -3 +SDV_CRYPTO_BN_SUB_FUNC_TC001:1:"01":0:"02":1:"03" + +BN_Sub Test vec #11: -1 - (-2) = 1 +SDV_CRYPTO_BN_SUB_FUNC_TC001:1:"01":1:"02":0:"01" + +BN_Sub Test vec #12: +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"43":1:"43":0:"86" + +BN_Sub Test vec #13 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"00":0:"0100":1:"0100" + +BN_Sub Test vec #14 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"010000000000":1:"010000000000":0:"020000000000" + +BN_Sub Test vec #15 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"ffffffff":0:"ffffffff":0:"00" + +BN_Sub Test vec #16 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"ffffff":1:"ffffff":0:"01fffffe" + +BN_Sub Test vec #17 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:"00" + +BN_Sub Test vec #18 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":1:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:"01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + +BN_Sub Test vec #19 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5":0:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5":0:"00" + +BN_Sub Test vec #20 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5":1:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5":0:"012970ba1921804740edabcadecf16bab4c4d8fd1f0e7647b49a7057b1ce77aa" + +BN_Sub Test vec #21 +SDV_CRYPTO_BN_SUB_FUNC_TC001:1:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5":0:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5":1:"012970ba1921804740edabcadecf16bab4c4d8fd1f0e7647b49a7057b1ce77aa" + +BN_Sub Test vec #22 +SDV_CRYPTO_BN_SUB_FUNC_TC001:0:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e7":0:"94b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e794b85d0c90c023a076d5e56f678b5d5a626c7e8f873b23da4d382bd8e73bd5d5f7e8":1:"01" + +SDV_CRYPTO_BN_SUBLIMB_API_TC001 +SDV_CRYPTO_BN_SUBLIMB_API_TC001: + +BN_SubLimb Verification 02 Test #1: 0 - 0 = 0 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"00":"00":0:"00" + +BN_SubLimb Verification 02 Test #2: 0 -11 = -1 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"00":"01":1:"01" + +BN_SubLimb Verification 02 Test #3 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"010000000000000000":"01":0:"ffffffffffffffff" + +BN_SubLimb Verification 02 Test #4 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:1:"ffffffffffffffFE":"01":1:"ffffffffffffffff" + +BN_SubLimb Verification 02 Test #5 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"ffffffff":"ffffffff":0:"00" + +BN_SubLimb Verification 02 Test #6 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"0100000000000000000000000000000000000000000000000000":"4000":0:"ffffffffffffffffffffffffffffffffffffffffffffffc000" + +BN_SubLimb Verification 02 Test #7: 1 - 1 = 0 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"01":"01":0:"00" + +BN_SubLimb Verification 02 Test #8: 1 - 2 = -1 +SDV_CRYPTO_BN_SUB_LIMB_FUNC_TC001:0:"01":"02":1:"01" + +BN_Div Verification 02 Test #1 +SDV_CRYPTO_BN_DIV_FUNC_TC001:1:"01":0:"02":0:"00":1:"01" + +BN_Div Verification 02 Test #2 +SDV_CRYPTO_BN_DIV_FUNC_TC001:0:"3b2bdbeb1b21f787ab8ddeb25bdfe51732be89a8d8c8e8f8b9":0:"d0c90c023a076d5e56f678b5d5a626c7":0:"488d644ee12a87d97a":0:"8843b9eed9cb559abc3c5c3507eacee3" + +BN_Div Verification 02 Test #3 +SDV_CRYPTO_BN_DIV_FUNC_TC001:0:"63b2bdb456deeb1b21f787ab8ddeb25bdfe51732b9":0:"23b2bdb456deeb1b21f787ab8ddeb25bdfe51732":0:"02ca":0:"22389b5c952f61753b2747142f94e7a170248145" + +BN_Div Verification 02 Test #4 +SDV_CRYPTO_BN_DIV_FUNC_TC001:0:"63b2bdb456deeb1b21f787ab8ddeb25bdfe51732b9":1:"23b2bdb456deeb1b21f787ab8ddeb25bdfe51732":1:"02ca":0:"22389b5c952f61753b2747142f94e7a170248145" + +BN_Div Verification 02 Test #5 +SDV_CRYPTO_BN_DIV_FUNC_TC001:0:"00":0:"51e5bdef3e6b21491e6e80e977bfa6":0:"00":0:"00" + +BN_Div Verification 02 Test #6 +SDV_CRYPTO_BN_DIV_FUNC_TC001:0:"00":1:"51e5bdef3e6b21491e6e80e977bfa6":0:"00":0:"00" + +BN_Div Verification 02 Test #7 +SDV_CRYPTO_BN_DIV_FUNC_TC001:0:"ffffffffffffffffffffffffffffffffffffffffffffffff":0:"ffffffffffffffff":0:"0100000000000000010000000000000001":0:"00" + +SDV_CRYPTO_BN_SQR_API_TC001 +SDV_CRYPTO_BN_SQR_API_TC001: + +SDV_CRYPTO_BN_SQR_FUNC_TC001 +SDV_CRYPTO_BN_SQR_FUNC_TC001:0:"01":"01" + +SDV_CRYPTO_BN_SQR_FUNC_TC001 +SDV_CRYPTO_BN_SQR_FUNC_TC001:1:"01":"01" + +SDV_CRYPTO_BN_RAND_API_TC001 +SDV_CRYPTO_BN_RAND_API_TC001: + +SDV_CRYPTO_BN_RANDRANGE_API_TC001 +SDV_CRYPTO_BN_RANDRANGE_API_TC001: + +SDV_CRYPTO_BN_BNGCDCHECKINPUT_API_TC001 +SDV_CRYPTO_BN_BNGCDCHECKINPUT_API_TC001: + +SDV_CRYPTO_BN_MODINVINPUTCHECK_API_TC001 +SDV_CRYPTO_BN_MODINVINPUTCHECK_API_TC001: + +BN_U64Array2Bn Test 1 +SDV_CRYPTO_BN_U64_FUNC_TC001:1 + +BN_U64Array2Bn Test 2 +SDV_CRYPTO_BN_U64_FUNC_TC001:2 + +BN_U64Array2Bn Test 3 +SDV_CRYPTO_BN_U64_FUNC_TC001:3 + +BN_U64Array2Bn Test 4 +SDV_CRYPTO_BN_U64_FUNC_TC001:11 + +BN_U64Array2Bn Test 5 +SDV_CRYPTO_BN_U64_FUNC_TC001:12 + +BN_U64Array2Bn Test 6 +SDV_CRYPTO_BN_U64_FUNC_TC001:13 + +BN_U64Array2Bn Test 7 +SDV_CRYPTO_BN_U64_FUNC_TC001:14 + +BN_U64Array2Bn Test 8 +SDV_CRYPTO_BN_U64_FUNC_TC001:15 + +BN_U64Array2Bn Test 9 +SDV_CRYPTO_BN_U64_FUNC_TC001:100 + +BN_U64Array2Bn Test 10 +SDV_CRYPTO_BN_U64_FUNC_TC001:101 + +BN_U64Array2Bn Test 11 +SDV_CRYPTO_BN_U64_FUNC_TC001:102 + +BN_U64Array2Bn Test 12 +SDV_CRYPTO_BN_U64_FUNC_TC001:103 + +BN_U64Array2Bn Test 13 +SDV_CRYPTO_BN_U64_FUNC_TC001:104 + +BN_U64Array2Bn Test 14 +SDV_CRYPTO_BN_U64_FUNC_TC001:105 + +BN_U64Array2Bn Test 15 +SDV_CRYPTO_BN_U64_FUNC_TC001:106 + +BN_U64Array2Bn Test 16 +SDV_CRYPTO_BN_U64_FUNC_TC001:107 + +BN_Array2BN Test 1 +SDV_CRYPTO_BN_UINT_FUNC_TC001:1 + +BN_Array2BN Test 2 +SDV_CRYPTO_BN_UINT_FUNC_TC001:2 + +BN_Array2BN Test 3 +SDV_CRYPTO_BN_UINT_FUNC_TC001:3 + +BN_Array2BN Test 4 +SDV_CRYPTO_BN_UINT_FUNC_TC001:18 + +BN_Array2BN Test 5 +SDV_CRYPTO_BN_UINT_FUNC_TC001:19 + +BN_Array2BN Test 6 +SDV_CRYPTO_BN_UINT_FUNC_TC001:20 + +BN_Array2BN Test 7 +SDV_CRYPTO_BN_UINT_FUNC_TC001:21 + +BN_Array2BN Test 8 +SDV_CRYPTO_BN_UINT_FUNC_TC001:100 + +BN_Array2BN Test 9 +SDV_CRYPTO_BN_UINT_FUNC_TC001:101 + +BN_Array2BN Test 10 +SDV_CRYPTO_BN_UINT_FUNC_TC001:102 + +BN_Array2BN Test 11 +SDV_CRYPTO_BN_UINT_FUNC_TC001:103 + +BN_Gcd Verification Test #1 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"11":0:"01":"01" + +BN_Gcd Verification Test #2 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"31":0:"3100":"31" + +BN_Gcd Verification Test #3 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"01":0:"01":"01" + +BN_Gcd Verification Test #4 +SDV_CRYPTO_BN_GCD_FUNC_TC001:1:"01":1:"01":"01" + +BN_Gcd Verification Test #5 +SDV_CRYPTO_BN_GCD_FUNC_TC001:1:"e9":1:"0122":"01" + +BN_Gcd Verification Test #6 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"23b2bdb456deeb1b21f787ab8ddeb25bdfe51732":0:"3b2bdbeb1b21f787ab8ddeb25bdfe51732be89a8d8c8e8f8b9":"01" + +BN_Gcd Verification Test #7 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"0fffffffffffffffffffffffff":0:"03ffffffffffff":"03ffffffffffff" + +BN_Gcd Verification Test #8 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"0fffffffffffffffffffffffff":0:"05600000000001":"03" + +BN_Gcd Verification Test #9 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"3fffffffffffffffffffffffff":0:"02ffffffffffff":"01" + +BN_Gcd Verification Test #10 +SDV_CRYPTO_BN_GCD_FUNC_TC001:0:"ffffffffffffffffffffffffffffffffffffffffffffffffffff":0:"ffffffffffffffffffffffffffffffffffffffffffffffff":"ffff" + +BN_Cmp Verification Test #1: a=NULL, b=NULL +SDV_CRYPTO_BN_CMP_FUNC_TC001:0:"":0:"":0 + +BN_Cmp Verification Test #2: a=NULL, b != NULL +SDV_CRYPTO_BN_CMP_FUNC_TC001:0:"":0:"01":1 + +BN_Cmp Verification Test #3: a != NULL, b=NULL +SDV_CRYPTO_BN_CMP_FUNC_TC001:0:"01":0:"":-1 + +BN_Cmp Verification Test #4: a, b have different sign, a > 0 +SDV_CRYPTO_BN_CMP_FUNC_TC001:0:"01":1:"01":1 + +BN_Cmp Verification Test #5: a, b have different sign, a < 0 +SDV_CRYPTO_BN_CMP_FUNC_TC001:1:"01":0:"01":-1 + +BN_Cmp Verification Test #6: a=b, sign=true +SDV_CRYPTO_BN_CMP_FUNC_TC001:1:"01":1:"01":0 + +BN_Add Verification Test #1: a=NULL +SDV_CRYPTO_BN_ADD_FUNC_TC001:0:0:0:"":"01":"01":CRYPT_NULL_INPUT + +BN_Add Verification Test #2: b=NULL +SDV_CRYPTO_BN_ADD_FUNC_TC001:0:0:0:"01":"":"01":CRYPT_NULL_INPUT + +BN_Add Verification Test #3: +SDV_CRYPTO_BN_ADD_FUNC_TC001:0:0:0:"20fbe39821a8":"10a7ec5034":"210c8b8471dc":CRYPT_SUCCESS + +BN_Add Verification Test #4: +SDV_CRYPTO_BN_ADD_FUNC_TC001:0:0:0:"1b489f0e13275986e8058079981ec820":"0561bf73bbb8dcdce4d4dba895dca56a":"20aa5e81cee03663ccda5c222dfb6d8a":CRYPT_SUCCESS + +BN_Add Verification Test #5: +SDV_CRYPTO_BN_ADD_FUNC_TC001:0:0:0:"0aea67":"010312f1df4bd01479eb481147d92cf0010a061eebf679d5c3f40f515044eb68d30706dcf4c1fd2206171d20":"010312f1df4bd01479eb481147d92cf0010a061eebf679d5c3f40f515044eb68d30706dcf4c1fd2206220787":CRYPT_SUCCESS + +BN_Add Verification Test #6: +SDV_CRYPTO_BN_ADD_FUNC_TC001:1:0:1:"010312f1df4bd01479eb481147d92cf0010a061eebf679d5c3f40f515044eb68d30706dcf4c1fd2206171d20":"0aea67":"010312f1df4bd01479eb481147d92cf0010a061eebf679d5c3f40f515044eb68d30706dcf4c1fd22060c32b9":CRYPT_SUCCESS + +BN_Add Verification Test #7: a=-b, a+b=0 +SDV_CRYPTO_BN_ADD_FUNC_TC001:0:1:0:"7b":"7b":"":CRYPT_SUCCESS + +BN_Bn2BinFixZero api test +SDV_CRYPTO_BN_TO_BIN_FIX_ZERO_API_TC001 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/chacha-poly/test_suite_sdv_eal_chachapoly.c b/testcode/sdv/testcase/crypto/chacha-poly/test_suite_sdv_eal_chachapoly.c new file mode 100644 index 00000000..f2af73c7 --- /dev/null +++ b/testcode/sdv/testcase/crypto/chacha-poly/test_suite_sdv_eal_chachapoly.c @@ -0,0 +1,1214 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "crypt_errno.h" +#include "crypt_eal_cipher.h" +#include "bsl_sal.h" +#include "securec.h" + +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC001 + * @title CRYPT_EAL_CipherInit Invalid input parameter + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface, ctx is NULL, other parameters are normal. Expected result 1 is obtained. + * 3.Call the Init interface, key is NULL, other parameters are normal. Expected result 2 is obtained. + * 4.Call the Init interface, iv is NULL, other parameters are normal. Expected result 2 is obtained. + * @expect + * 1.Failed. Return CRYPT_NULL_INPUT. + * 2.Failed. Return CRYPT_NULL_INPUT. + * 3.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(NULL, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, NULL, sizeof(key), iv, sizeof(iv), true) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), NULL, sizeof(iv), true) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC002 + * @title CRYPT_EAL_CipherInit Invalid input parameter + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface with keyLen is 33, other parameters are normal. Expected result 1 is obtained. + * 3.Call the Init interface with keyLen is 31, other parameters are normal. Expected result 2 is obtained. + * 4.Call the Init interface with ivLen is 11, other parameters are normal. Expected result 3 is obtained. + * 5.Call the Init interface with ivLen is 13, other parameters are normal. Expected result 4 is obtained. + * 6.Call the Init interface with ivLen is 9, other parameters are normal. Expected result 5 is obtained. + * 7.Call the Init interface with ivLen is 7, other parameters are normal. Expected result 6 is obtained. + * @expect + * 1.Failed. Return CRYPT_CHACHA20_KEYLEN_ERROR. + * 2.Failed. Return CRYPT_CHACHA20_KEYLEN_ERROR. + * 3.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 4.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 5.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 6.Failed. Return CRYPT_MODES_IVLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC002(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, 33, iv, sizeof(iv), true) == + CRYPT_CHACHA20_KEYLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, 31, iv, sizeof(iv), true) == + CRYPT_CHACHA20_KEYLEN_ERROR); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), (uint8_t *)iv, 13, true) == + CRYPT_MODES_IVLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), (uint8_t *)iv, 11, true) == + CRYPT_MODES_IVLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), (uint8_t *)iv, 9, true) == + CRYPT_MODES_IVLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), (uint8_t *)iv, 7, true) == + CRYPT_MODES_IVLEN_ERROR); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC001 + * @title CRYPT_EAL_CipherReinit Invalid input parameter Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. Expected result 1 is obtained. + * 3.Call the Reinit interface with iv is NULL, and set other parameters correctly. Expected result 2 is obtained. + * 4.Call the Reinit interface with ctx is NULL, and set other parameters correctly. Expected result 3 is obtained. + * @expect + * 1.The init is successful and return CRYPT_SUCCESS. + * 2.Failed. Return CRYPT_NULL_INPUT. + * 3.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, NULL, sizeof(iv)) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(NULL, iv, sizeof(iv)) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC002 + * @title CRYPT_EAL_CipherReinit Invalid input parameter Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. Expected result 1 is obtained. + * 3.Call the Reinit interface with ivLen is 11, and set other parameters correctly. Expected result 2 is obtained. + * 4.Call the Reinit interface with ivLen is 13, and set other parameters correctly. Expected result 3 is obtained. + * 5.Call the Reinit interface with ivLen is 9, and set other parameters correctly. Expected result 4 is obtained. + * 6.Call the Reinit interface with ivLen is 7, and set other parameters correctly. Expected result 5 is obtained. + * @expect + * 1.The init is successful and return CRYPT_SUCCESS. + * 2.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 3.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 4.Failed. Return CRYPT_MODES_IVLEN_ERROR. + * 5.Failed. Return CRYPT_MODES_IVLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC002(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, 13) == CRYPT_MODES_IVLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, 11) == CRYPT_MODES_IVLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, 9) == CRYPT_MODES_IVLEN_ERROR); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, 7) == CRYPT_MODES_IVLEN_ERROR); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC003 + * @title Call sequence error Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Reinit interface. All parameters are normal. Expected result 1 is obtained. + * @expect + * 1.Failed. Return CRYPT_EAL_ERR_STATE. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC003(void) +{ + TestMemInit(); + uint8_t iv[12] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv, sizeof(iv)) == CRYPT_EAL_ERR_STATE); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC001 + * @title Invalid input parameter of CRYPT_EAL_CipherUpdate Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. Expected result 2 is obtained. + * 4.Call the Update interface, ctx is NULL, and other parameters are normal. Expected result 3 is obtained. + * 4.Call the Update interface, in is NULL, and other parameters are normal. Expected result 4 is obtained. + * 5.Call the Update interface, inLen is 0, and other parameters are normal. Expected result 5 is obtained. + * 6.Call the Update interface, out is NULL, and other parameters are normal. Expected result 6 is obtained. + * 7.Call the Update interface, outLen is NULL, and other parameters are normal. Expected result 7 is obtained. + * @expect + * 1.The init is successful and return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_NULL_INPUT. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Failed. Return CRYPT_NULL_INPUT. + * 7.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t data[100] = {0}; + uint8_t aad[20] = {0}; + uint8_t out[100]; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(NULL, data, sizeof(data), out, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, NULL, sizeof(data), out, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, 0, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, sizeof(data), NULL, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, sizeof(data), (uint8_t *)out, NULL) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC002 + * @title CRYPT_EAL_CipherUpdate Invalid input parameter Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. Expected result 2 is obtained. + * 4.Call the Update interface, outLen is inLen - 1, and other parameters are normal. Expected result 3 is obtained. + * @expect + * 1.The init is successful and return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Failed. The buffer is not enough. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC002(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t data[100] = {0}; + uint8_t aad[20] = {0}; + uint8_t out[100]; + uint32_t outLen = sizeof(data) - 1; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, sizeof(data), (uint8_t *)out, &outLen) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC003 + * @title CRYPT_EAL_CipherUpdate Error State Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Update interface. All parameters are normal. Expected result 1 is obtained. + * @expect + * 1.Failed. return CRYPT_EAL_ERR_STATE. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC003(void) +{ + TestMemInit(); + uint8_t data[100] = {0}; + uint8_t out[100]; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, sizeof(data), out, &outLen) == CRYPT_EAL_ERR_STATE); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC001 + * @title CRYPT_EAL_CipherCtrl set aad invalid parameter Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad with aad is NULL and aadLen is not 0. Expected result 2 is obtained. + * 4.Call the Ctrl interface to set aad with ctx is NULL. Expected result 3 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Failed. Return CRYPT_NULL_INPUT. + * 3.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t aad[20] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, NULL, sizeof(aad)) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(NULL, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC002 + * @title CRYPT_EAL_CipherCtrl get tag invalid parameter Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. Expected result 2 is obtained. + * 4.Call the Ctrl interface to get tag with ctx is NULL. Expected result 3 is obtained. + * 5.Call the Ctrl interface to get tag with data is NULL. Expected result 4 is obtained. + * 6.Call the Ctrl interface to get tag with dataLen is 15. Expected result 5 is obtained. + * 7.Call the Ctrl interface to get tag with dataLen is 17. Expected result 6 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_NULL_INPUT. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Failed. Return CRYPT_MODES_TAGLEN_ERROR. + * 6.Failed. Return CRYPT_MODES_TAGLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC002(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t aad[20] = {0}; + uint8_t out[16]; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(NULL, CRYPT_CTRL_GET_TAG, out, sizeof(out)) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, NULL, sizeof(out)) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, out, sizeof(out) - 1) == CRYPT_MODES_TAGLEN_ERROR); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, out, sizeof(out) + 1) == CRYPT_MODES_TAGLEN_ERROR); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC003 + * @title Invalid Algorithms to call Ctrl Interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set iv. Expected result 2 is obtained. + * 4.Call the Ctrl interface to get iv. Expected result 3 is obtained. + * 5.Call the Ctrl interface to get blockSize. Expected result 4 is obtained. + * 6.Call the Ctrl interface to set tag len. Expected result 5 is obtained. + * 7.Call the Ctrl interface to set msg len. Expected result 6 is obtained. + * @expect + * 1.The init is successful and return CRYPT_SUCCESS. + * 2.Setting failed. + * 3.Getting failed. + * 4.Getting failed. + * 5.Setting failed. The algorithm is not supported. + * 6.Setting failed. The algorithm is not supported. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC003(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t buf[100] = {0}; + uint8_t num = 0; + uint32_t num32 = 0; + uint64_t num64 = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_IV, (uint8_t *)buf, 12) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, (uint8_t *)buf, 12) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, &num, sizeof(uint8_t)) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &num32, sizeof(uint32_t)) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &num64, sizeof(uint64_t)) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC004 + * @title Set aad but not initialized Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Ctrl interface to set iv. Expected result 1 is obtained. + * @expect + * 1.Failed. Return CRYPT_EAL_ERR_STATE. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC004(void) +{ + TestMemInit(); + uint8_t aad[20] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_EAL_ERR_STATE); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC005 + * @title Set aad repeatedly Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. Expected result 2 is obtained. + * 4.Call the Ctrl interface to set aad. Expected result 3 is obtained. + * @expect + * 1.The init is successful and return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Failed. The Aad has been set. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC005(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t aad[20] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC006 + * @title Get tag but not initialized Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Ctrl interface to get tag. Expected result 1 is obtained. + * @expect + * 1.Failed. Has not been initialized. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC006(void) +{ + TestMemInit(); + uint8_t tag[16] = {0}; + const uint32_t tagLen = 16; // chacha-poly tag len is 16 + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE_AND_LOG("get tag after new", + CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_FINAL_API_TC001 + * @title Invalid Algorithms to call Final Interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. All parameters are normal. Expected result 2 is obtained. + * 4.Call the Update interface. All parameters are normal. Expected result 3 is obtained. + * 5.Call the Final interface. Expected result 4 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Failed. The algorithm is not supported. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_FINAL_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t aad[20] = {0}; + uint8_t data[100] = {0}; + uint32_t dataLen = sizeof(data); + uint8_t out[100]; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, dataLen, out, &outLen) == CRYPT_SUCCESS); + + outLen = sizeof(out); + ASSERT_TRUE(CRYPT_EAL_CipherFinal(ctx, out, &outLen) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_SETPADDING_API_TC001 + * @title Invalid Algorithms to call set padding Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. All parameters are normal. Expected result 2 is obtained. + * 4.Call the Getpadding interface. Expected result 3 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Failed. The algorithm is not supported. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_SETPADDING_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t aad[20] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_ZEROS) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_GETPADDING_API_TC001 + * @title Invalid Algorithms to call get padding Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. + * 2.Call the Init interface. All parameters are normal. Expected result 1 is obtained. + * 3.Call the Ctrl interface to set aad. All parameters are normal. Expected result 2 is obtained. + * 4.Call the Setpadding interface. Expected result 3 is obtained. + * @expect + * 1.Success. Return CRYPT_SUCCESS. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Failed. The algorithm is not supported. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_GETPADDING_API_TC001(void) +{ + TestMemInit(); + uint8_t key[32] = {0}; + uint8_t iv[12] = {0}; + uint8_t aad[20] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad, sizeof(aad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherGetPadding(ctx) == CRYPT_PADDING_NONE); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001 + * @title Encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface and set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set aad. All parameters are normal. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt data. Expected result 4 is obtained. + * 5.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 5 is obtained. + * 6.Call the deinit interface to deinitialize the ctx. + * 7.Call the Init interface and set to decrypt. Expected result 6 is obtained. + * 8.Call the Ctrl interface to set aad. All parameters are normal. Expected result 7 is obtained. + * 9.Call the Update interface to decrypt data. Expected result 8 is obtained. + * 10.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 9 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful and consistent with expected vector. + * 5.Tag is consistent with expected vector. + * 6.The init is successful and return CRYPT_SUCCESS. + * 7.Succeeded in setting the AAD. + * 8.The decryption is successful and consistent with origin plain data. + * 9.Tag is consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint32_t tagLen = tag->len; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, data->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == cipher->len); + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + + CRYPT_EAL_CipherDeinit(ctx); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + outLen = sizeof(out); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x, cipher->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == data->len); + ASSERT_TRUE(memcmp(out, data->x, data->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002 + * @title Multi segment encryption and decryption + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface and set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set aad. All parameters are normal. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt partial data. Expected result 4 is obtained. + * 5.Call the Update interface to encrypt remaining data. Expected result 5 is obtained. + * 6.Compare the ciphertext with the test vector. Expected result 6 is obtained. + * 7.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 7 is obtained. + * 8.Call the deinit interface to deinitialize the ctx. + * 9.Call the Init interface and set to decrypt. Expected result 8 is obtained. + * 10.Call the Ctrl interface to set aad. All parameters are normal. Expected result 9 is obtained. + * 11.Call the Update interface to decrypt partial data. Expected result 10 is obtained. + * 12.all the Update interface to decrypt remaining data. Expected result 11 is obtained. + * 13.Compare the plaintext with the test vector. Expected result 12 is obtained. + * 14.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 13 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful. + * 5.The encryption is successful. + * 6.Ciphertext is consistent with expected vector. + * 7.Tag is consistent with expected vector. + * 8.The init is successful and return CRYPT_SUCCESS. + * 9.Succeeded in setting the AAD. + * 10.The decryption is successful. + * 11.The decryption is successful. + * 12.Decryption result is consistent with origin plain data. + * 13.Tag is consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint32_t tagLen = tag->len; + uint32_t first = data->len / 2; + uint32_t outLen; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + outLen = first; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, first, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + outLen = data->len - first; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x + first, data->len - first, out + first, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + + CRYPT_EAL_CipherDeinit(ctx); + + outLen = first; + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x, first, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + outLen = cipher->len - first; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x + first, cipher->len - first, out + first, &outLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out, data->x, data->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC003 + * @title Encryption and decryption with reinitialization Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt with the test vector key and non-vector IV. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set non-vector AAD. Expected result 3 is obtained. + * 4.Call the Reinit interface with the test vector IV. Expected result 4 is obtained. + * 5.Call the Ctrl interface to set the test vector AAD. Expected result 5 is obtained. + * 6.Call the Update interface to encrypt data. Expected result 6 is obtained. + * 7.Compare the ciphertext with the test vector. Expected result 7 is obtained. + * 8.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 8 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The reinitialization is successful. + * 5.Succeeded in setting the AAD. + * 6.The encryption is successful. + * 7.Ciphertext is consistent with expected vector. + * 8.Tag is consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC003(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint8_t badIv[12] = {0}; + uint8_t badAad[30] = {0}; + uint32_t tagLen = tag->len; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, badIv, sizeof(badIv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, badAad, sizeof(badAad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, data->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == cipher->len); + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/* + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC004 + * @title Repeated init Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt with the non-vector key and non-vector IV. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set non-vector AAD. Expected result 3 is obtained. + * 4.Call the init interface to set to encrypt with the test vector key and IV. Expected result 4 is obtained. + * 5.Call the Ctrl interface to set the test vector AAD. Expected result 5 is obtained. + * 6.Call the Update interface to encrypt data. Expected result 6 is obtained. + * 7.Compare the ciphertext with the test vector. Expected result 7 is obtained. + * 8.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 8 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The init is successful. + * 5.Succeeded in setting the AAD. + * 6.The encryption is successful. + * 7.Ciphertext is consistent with expected vector. + * 8.Tag is consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC004(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint8_t badIv[12] = {0}; + uint8_t badAad[30] = {0}; + uint8_t badKey[32] = {0}; + uint32_t tagLen = tag->len; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, badKey, sizeof(badKey), badIv, sizeof(badIv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, badAad, sizeof(badAad)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, data->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == cipher->len); + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC005 + * @title No message scenario Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt with the test vector key and IV. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set AAD. Expected result 3 is obtained. + * 4.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 4 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.Tag is consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC005(Hex *key, Hex *iv, Hex *aad, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint32_t tagLen = tag->len; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("tag equal", outTag, tagLen, tag->x, tag->len); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC006 + * @title Obtaining tag repeatedly Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set AAD. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt data. Expected result 4 is obtained. + * 5.Compare the ciphertext with the test vector. Expected result 5 is obtained. + * 6.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 6 is obtained. + * 7.Call the Ctrl interface again to obtain the tag and compare with test vector. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful. + * 5.Ciphertext is consistent with expected vector. + * 6.Tag is consistent with expected vector. + * 7.Failed to obtain the tag for the second time. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC006(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint32_t tagLen = tag->len; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, data->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == cipher->len); + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC007 + * @title Memory overlap in plaintext and ciphertext Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set AAD. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt data. The plaintext and ciphertext memory completely overlap. Expected result 4 is obtained. + * 5.Compare the ciphertext with the test vector. Expected result 5 is obtained. + * 6.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful. + * 5.Ciphertext is consistent with expected vector. + * 6.Tag is consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC007(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t buf[300]; + uint32_t tagLen = tag->len; + uint32_t bufLen = sizeof(buf); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(memcpy_s(buf, bufLen, data->x, data->len) == 0); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, buf, data->len, buf, &bufLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(bufLen == cipher->len); + ASSERT_TRUE(memcmp(buf, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC008 + * @title 64-bit IV encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set AAD. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt data. Expected result 4 is obtained. + * 5.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 5 is obtained. + * 6.Call the deinit interface to deinitialize the ctx. + * 7.Call the init interface to set to decrypt. Expected result 6 is obtained. + * 8.Call the Ctrl interface to set AAD. Expected result 7 is obtained. + * 9.Call the Update interface to decrypt data. Expected result 8 is obtained. + * 10.Compare the plaintext with the test vector. Expected result 9 is obtained. + * 11.Call the Ctrl interface to obtain the tag and compare with encryption tag. Expected result 10 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful. + * 5.The getting tag is successful. + * 6.The init is successful and return CRYPT_SUCCESS. + * 7.Succeeded in setting the AAD. + * 8.The decryption is successful. + * 9.Decryption result is consistent with origin plaintext. + * 10.Tag is consistent with expected value. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC008(Hex *key, Hex *aad, Hex *data) +{ + TestMemInit(); + uint8_t outTag1[16]; + uint8_t outTag2[16]; + uint8_t out[300]; + const uint32_t tagLen = sizeof(outTag1); + uint32_t outLen = sizeof(out); + uint8_t iv[8]; + (void)memset_s(iv, sizeof(iv), 'A', sizeof(iv)); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, data->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag1, tagLen) == CRYPT_SUCCESS); + + CRYPT_EAL_CipherDeinit(ctx); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv, sizeof(iv), false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, out, outLen, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag2, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == data->len); + ASSERT_TRUE(memcmp(out, data->x, data->len) == 0); + ASSERT_TRUE(memcmp(outTag1, outTag2, tagLen) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC009 + * @title Invalid tag in the encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set AAD. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt data. Expected result 4 is obtained. + * 5.Compare the ciphertext with the test vector. Expected result 5 is obtained. + * 6.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 6 is obtained. + * 7.Call the deinit interface to deinitialize the ctx. + * 8.Call the init interface to set to decrypt. Expected result 7 is obtained. + * 9.Call the Ctrl interface to set AAD. Expected result 8 is obtained. + * 10.Call the Update interface to decrypt data. Expected result 9 is obtained. + * 11.Compare the plaintext with the test vector. Expected result 10 is obtained. + * 12.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 11 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful. + * 5.Ciphertext is consistent with expected vector. + * 6.Tag is not consistent with expected vector. + * 7.The init is successful and return CRYPT_SUCCESS. + * 8.Succeeded in setting the AAD. + * 9.The decryption is successful. + * 10.Decryption result is consistent with origin plain data. + * 11.Tag is not consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC009(Hex *key, Hex *iv, Hex *aad, Hex *data, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint32_t tagLen = tag->len; + uint32_t outLen = sizeof(out); + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data->x, data->len, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == cipher->len); + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) != 0); + + CRYPT_EAL_CipherDeinit(ctx); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + outLen = sizeof(out); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x, cipher->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == data->len); + ASSERT_TRUE(memcmp(out, data->x, data->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) != 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + + +/** + * @test SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002 + * @title Encryption and decryption of multiple segments with different lengths Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the init interface to set to encrypt. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set AAD. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt data 1. Expected result 4 is obtained. + * 5.Call the Update interface to encrypt data 2. Expected result 5 is obtained. + * 6.Call the Update interface to encrypt data 3. Expected result 6 is obtained. + * 7.Compare the ciphertext with the test vector. Expected result 7 is obtained. + * 8.Call the Ctrl interface to obtain the tag and compare with test vector. Expected result 8 is obtained. + * 9.Call the deinit interface to deinitialize the ctx. + * 10.Call the init interface to set to decrypt. Expected result 9 is obtained. + * 11.Call the Ctrl interface to set AAD. Expected result 10 is obtained. + * 12.Call the Update interface to decrypt data 1. Expected result 11 is obtained. + * 13.Call the Update interface to decrypt data 2. Expected result 12 is obtained. + * 14.Call the Update interface to decrypt data 3. Expected result 13 is obtained. + * 15.Compare the plaintext with the test vector. Expected result 14 is obtained. + * 16.Call the Ctrl interface to obtain the tag and compare with test vector tag. Expected result 15 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the AAD. + * 4.The encryption is successful. + * 5.The encryption is successful. + * 6.The encryption is successful. + * 7.Ciphertext is consistent with expected vector. + * 8.Tag is consistent with expected value. + * 9.The init is successful and return CRYPT_SUCCESS. + * 10.Succeeded in setting the AAD. + * 11.The decryption is successful. + * 12.The decryption is successful. + * 13.The decryption is successful. + * 14.Decryption result is consistent with origin plaintext. + * 15.Tag is consistent with expected value. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC010(Hex *key, Hex *iv, Hex *aad, Hex *pt1, Hex *pt2, Hex *pt3, Hex *cipher, Hex *tag) +{ + TestMemInit(); + uint8_t outTag[16]; + uint8_t out[300]; + uint32_t tagLen = tag->len; + uint32_t outLen; + uint32_t totalLen = 0; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_CHACHA20_POLY1305); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + outLen = sizeof(out); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt1->x, pt1->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + totalLen += outLen; + outLen = sizeof(out) - pt1->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt2->x, pt2->len, out + totalLen, &outLen) == CRYPT_SUCCESS); + totalLen += outLen; + outLen = sizeof(out) - pt1->len - pt2->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt3->x, pt3->len, out + totalLen, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(out, cipher->x, cipher->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + + CRYPT_EAL_CipherDeinit(ctx); + + outLen = sizeof(out); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x, pt1->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + outLen = cipher->len - pt1->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x + pt1->len, pt2->len, out + pt1->len, &outLen) == + CRYPT_SUCCESS); + outLen = cipher->len - pt1->len - pt2->len; + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, cipher->x + pt1->len + pt2->len, pt3->len, out + pt1->len + pt2->len, &outLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out, pt1->x, pt1->len) == 0); + ASSERT_TRUE(memcmp(out + pt1->len, pt2->x, pt2->len) == 0); + ASSERT_TRUE(memcmp(out + pt1->len + pt2->len, pt3->x, pt3->len) == 0); + ASSERT_TRUE(memcmp(outTag, tag->x, tag->len) == 0); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/chacha-poly/test_suite_sdv_eal_chachapoly.data b/testcode/sdv/testcase/crypto/chacha-poly/test_suite_sdv_eal_chachapoly.data new file mode 100644 index 00000000..68e65606 --- /dev/null +++ b/testcode/sdv/testcase/crypto/chacha-poly/test_suite_sdv_eal_chachapoly.data @@ -0,0 +1,113 @@ +SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC001 chacha-poly init null +SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC002 chacha-poly init invalid value +SDV_CRYPTO_CHACHA20POLY1305_INIT_API_TC002: + +SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC001 chacha-poly reinit null +SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC002 chacha-poly reinit invalid value +SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC002: + +SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC003 chacha-poly reinit err state +SDV_CRYPTO_CHACHA20POLY1305_REINIT_API_TC003: + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC001 chacha-poly update null +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC002 chacha-poly update bad outLen +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC002: + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC003 chacha-poly update err state +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_API_TC003: + +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC001 chacha-poly set aad null +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC002 chacha-poly get tag invalid value +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC002: + +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC003 chacha-poly ctrl unsupport operation +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC003: + +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC004 chacha-poly set aad no init +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC004: + +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC005 chacha-poly aad repeat set +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC005: + +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC006 chacha-poly get tag no init +SDV_CRYPTO_CHACHA20POLY1305_CTRL_API_TC006: + +SDV_CRYPTO_CHACHA20POLY1305_FINAL_API_TC001 chacha-poly final +SDV_CRYPTO_CHACHA20POLY1305_FINAL_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_SETPADDING_API_TC001 chacha-poly set padding +SDV_CRYPTO_CHACHA20POLY1305_SETPADDING_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_GETPADDING_API_TC001 chacha-poly get padding +SDV_CRYPTO_CHACHA20POLY1305_GETPADDING_API_TC001: + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001 chacha-poly enc/dec vector #1 from RFC7539 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001 chacha-poly enc/dec vector #2 from RFC7539 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC001:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002 chacha-poly enc/dec multi update vector #0 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047":"d31a8d34648e60db7b86afbc":"e516436df59bdf1f04ff6e44734896ed" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002 chacha-poly enc/dec multi update vector #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002 chacha-poly enc/dec multi update vector #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC002:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC003 chacha-poly reinit vector #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC003:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC003 chacha-poly reinit vector #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC003:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC004 chacha-poly double init vector #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC004:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC004 chacha-poly double init vector #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC004:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC005 chacha-poly no msg no aad get tag +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC005:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"":"a0784d7a4716f3feb4f64e7f4b39bf04" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC005 chacha-poly no msg get tag +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC005:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"66f09890d77129cc79e1ed577bd95c04" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC006 chacha-poly repeat get tag #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC006:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC006 chacha-poly repeat get tag #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC006:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC007 chacha-poly memory full overlap #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC007:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC007 chacha-poly memory full overlap #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC007:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC008 chachapoly 64 bits iv #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC008:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC008 chachapoly 64 bits iv #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC008:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC009 chachapoly invalid tag vector #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC009:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600692" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC009 chachapoly invalid tag vector #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC009:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f39" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC010 chacha-poly enc/dec multi update diff len #1 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC010:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a20496620":"4920636f756c64206f6666657220796f75206f6e6c79206f6e65":"2074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC010 chacha-poly enc/dec multi update diff len #2 +SDV_CRYPTO_CHACHA20POLY1305_UPDATE_FUNC_TC010:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d65":"6e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473":"206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" diff --git a/testcode/sdv/testcase/crypto/curve25519/test_suite_sdv_eal_curve25519.c b/testcode/sdv/testcase/crypto/curve25519/test_suite_sdv_eal_curve25519.c new file mode 100644 index 00000000..5380e606 --- /dev/null +++ b/testcode/sdv/testcase/crypto/curve25519/test_suite_sdv_eal_curve25519.c @@ -0,0 +1,919 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include + +#include "crypt_bn.h" +#include "bsl_sal.h" +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "crypt_curve25519.h" +#include "eal_pkey_local.h" +#include "crypt_eal_rand.h" +#include "securec.h" + +void *malloc_fail(uint32_t size) +{ + (void)size; + return NULL; +} + +static void Set_Curve25519_Prv(CRYPT_EAL_PkeyPrv *prv, int id, uint8_t *key, uint32_t keyLen) +{ + prv->id = id; + prv->key.curve25519Prv.data = key; + prv->key.curve25519Prv.len = keyLen; +} + +static void Set_Curve25519_Pub(CRYPT_EAL_PkeyPub *pub, int id, uint8_t *key, uint32_t keyLen) +{ + pub->id = id; + pub->key.curve25519Pub.data = key; + pub->key.curve25519Pub.len = keyLen; +} +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_CURVE25519_SET_PARA_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeySetPara test. + * @precon nan + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method, where parameter para.id is CRYPT_PKEY_*25519, expected result 2. + * 3. Call the CRYPT_EAL_PkeySetPara method, where parameter para.id is not CRYPT_PKEY_*25519, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_EAL_ALG_NOT_SUPPORT + * 3. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_SET_PARA_API_TC001(int id) +{ + TestMemInit(); + CRYPT_EAL_PkeyPara para; + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + para.id = id; + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_EAL_ALG_NOT_SUPPORT); + para.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_EAL_ERR_ALGID); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_SET_PRV_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeySetPrv test. + * @precon Create a valid private key prv. + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPrv method: + * (1). pkey = NULL, expected result 2. + * (2). prv = NULL, expected result 2. + * (3). prv.data = NULL, expected result 2. + * (4). prv.len = 0, expected result 2. + * (5). prv.id != pkey.id, expected result 3. + * (6). prv.len = 33|31, expected result 4. + * (7). All parameters are valid, expected result 5. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_EAL_ERR_ALGID + * 4. CRYPT_CURVE25519_KEYLEN_ERROR + * 5. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_SET_PRV_API_TC001(int id) +{ + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + Set_Curve25519_Prv(&prv, id, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(NULL, &prv), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, NULL), CRYPT_NULL_INPUT); + prv.key.curve25519Prv.data = NULL; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_NULL_INPUT); + prv.key.curve25519Prv.data = key; + prv.key.curve25519Prv.len = 0; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(NULL, &prv), CRYPT_NULL_INPUT); + + prv.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_EAL_ERR_ALGID); + + prv.id = id; + prv.key.curve25519Prv.len = CRYPT_CURVE25519_KEYLEN - 1; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_CURVE25519_KEYLEN_ERROR); + prv.key.curve25519Prv.len = CRYPT_CURVE25519_KEYLEN + 1; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_CURVE25519_KEYLEN_ERROR); + prv.key.curve25519Prv.len = CRYPT_CURVE25519_KEYLEN; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_SET_PUB_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeySetPub test. + * @precon Create a valid public key pub. + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPub method: + * (1). pkey = NULL, expected result 2. + * (2). pub = NULL, expected result 2. + * (3). pub.data = NULL, expected result 2. + * (4). pub.len = 0, expected result 2. + * (5). pub.id != pkey.id, expected result 3. + * (6). pub.len = 33|31, expected result 4. + * (7). All parameters are valid, expected result 5. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_EAL_ERR_ALGID + * 4. CRYPT_CURVE25519_KEYLEN_ERROR + * 5. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_SET_PUB_API_TC001(int id) +{ + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_Curve25519_Pub(&pub, id, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(NULL, &pub), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, NULL), CRYPT_NULL_INPUT); + pub.key.curve25519Pub.data = NULL; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_NULL_INPUT); + pub.key.curve25519Pub.data = key; + pub.key.curve25519Pub.len = 0; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(NULL, &pub), CRYPT_NULL_INPUT); + + pub.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_EAL_ERR_ALGID); + + pub.id = id; + pub.key.curve25519Pub.len = CRYPT_CURVE25519_KEYLEN - 1; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_CURVE25519_KEYLEN_ERROR); + pub.key.curve25519Pub.len = CRYPT_CURVE25519_KEYLEN + 1; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_CURVE25519_KEYLEN_ERROR); + pub.key.curve25519Pub.len = CRYPT_CURVE25519_KEYLEN; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_GET_PRV_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeyGetPrv test. + * @precon Create a valid private key prv. + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetPrv method, where all parameters are valid, expected result 2. + * 3. Call the CRYPT_EAL_PkeySetPrv method to set private key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyGetPrv method, where other parameters are valid, but: + * (1). pkey = NULL, expected result 4. + * (2). prv = NULL, expected result 4. + * (5). prv.id != pkey.id, expected result 5. + * (6). prv.len = 31, expected result 6. + * (6). prv.len = 33, expected result 7. + * (7). All parameters are valid, expected result 7. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_CURVE25519_NO_PRVKEY + * 3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_EAL_ERR_ALGID + * 6. CRYPT_CURVE25519_KEYLEN_ERROR + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_GET_PRV_API_TC001(int id) +{ + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + Set_Curve25519_Prv(&prv, id, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_CURVE25519_NO_PRVKEY); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(NULL, &prv), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, NULL), CRYPT_NULL_INPUT); + + prv.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_EAL_ERR_ALGID); + + prv.id = id; + prv.key.curve25519Prv.len = CRYPT_CURVE25519_KEYLEN - 1; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_CURVE25519_KEYLEN_ERROR); + prv.key.curve25519Prv.len = CRYPT_CURVE25519_KEYLEN; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_SUCCESS); + prv.key.curve25519Prv.len = CRYPT_CURVE25519_KEYLEN + 1; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_GET_PUB_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeyGetPub test. + * @precon Create a valid public key pub. + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetPub method, where all parameters are valid, expected result 2. + * 3. Call the CRYPT_EAL_PkeySetPub method to set private key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyGetPub method, where other parameters are valid, but : + * (1). pkey = NULL, expected result 4. + * (2). pub = NULL, expected result 4. + * (5). pub.id != pkey.id, expected result 5. + * (6). pub.len = 31, expected result 6. + * (6). pub.len = 33, expected result 7. + * (7). All parameters are valid, expected result 7. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_CURVE25519_NO_PUBKEY + * 3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_EAL_ERR_ALGID + * 6. CRYPT_CURVE25519_KEYLEN_ERROR + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_GET_PUB_API_TC001(int id) +{ + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPub pub; + Set_Curve25519_Pub(&pub, id, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_CURVE25519_NO_PUBKEY); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(NULL, &pub), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, NULL), CRYPT_NULL_INPUT); + + pub.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_EAL_ERR_ALGID); + + pub.id = id; + pub.key.curve25519Pub.len = CRYPT_CURVE25519_KEYLEN - 1; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_CURVE25519_KEYLEN_ERROR); + pub.key.curve25519Pub.len = CRYPT_CURVE25519_KEYLEN; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_SUCCESS); + pub.key.curve25519Pub.len = CRYPT_CURVE25519_KEYLEN + 1; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_GET_KEY_LEN_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeyGetKeyLen test. + * @precon nan + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetKeyLen method, where pkey is NULL, expected result 1. + * 3. Call the CRYPT_EAL_PkeyGetKeyLen method, where pkey is valid, expected result 2. + * @expect + * 1. Success, and context is not NULL. + * 2. Reutrn 0. + * 3. Return CRYPT_CURVE25519_KEYLEN(32) + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_GET_KEY_LEN_API_TC001(int id) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyGetKeyLen(NULL), 0); + ASSERT_EQ(CRYPT_EAL_PkeyGetKeyLen(pkey), CRYPT_CURVE25519_KEYLEN); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeyGen test. + * @precon nan + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGen method, where pkey is NULL, expected result 1. + * 3. Call the CRYPT_EAL_PkeyGen method, where pkey is valid, expected result 2. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_NO_REGIST_RAND + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC001(int id) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(NULL), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_NO_REGIST_RAND); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC002 + * @title CURVE25519: CRYPT_EAL_PkeyGen test. + * @precon nan + * @brief + * 1. Create the context of the curve25519 algorithm, expected result 1. + * 2. Init the drbg, expected result 2. + * 3. Generate a key pair, expected result 2. + * 4. Call the CRYPT_EAL_PkeyGetPub method to get public key, expected result 2. + * 5. Call the CRYPT_EAL_PkeyGetPub method to get private key, expected result 2. + * @expect + * 1. Success, and context is not NULL. + * 2. Success + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC002(int id) +{ + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPub pub; + Set_Curve25519_Pub(&pub, id, key, CRYPT_CURVE25519_KEYLEN); + CRYPT_EAL_PkeyPrv prv = {0}; + Set_Curve25519_Prv(&prv, id, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + /* Sets the entropy source. */ + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_SUCCESS); +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_SIGN_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeySign test. + * @precon Prepare data for signature. + * @brief + * 1. Create the context of the ed25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySign method, where all parameters are valid, expected result 2. + * 3. Call the CRYPT_EAL_PkeySetPrv method to set private key, expected result 3. + * 4. Call the CRYPT_EAL_PkeySign method, where other parameters are valid, but : + * (1) hashId != CRYPT_MD_SHA512, expected result 4 + * (2) data = NULL, expected result 5 + * (3) sign = NULL, expected result 5 + * (4) signLen = NULL, expected result 5 + * (5) signLen = 0 | 63, expected result 6 + * (6) signLen = 64 | 65, expected result 7 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_CURVE25519_NO_PRVKEY + * 3. CRYPT_SUCCESS + * 4. CRYPT_CURVE25519_HASH_METH_ERROR + * 5. CRYPT_NULL_INPUT + * 6. CRYPT_CURVE25519_SIGNLEN_ERROR + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_SIGN_API_TC001(void) +{ + int hashId = CRYPT_MD_SHA512; + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + uint8_t data[CRYPT_CURVE25519_KEYLEN] = {0}; + uint8_t sign[CRYPT_CURVE25519_SIGNLEN] = {0}; + uint32_t signLen = sizeof(sign); + CRYPT_EAL_PkeyPrv prv = {0}; + Set_Curve25519_Prv(&prv, CRYPT_PKEY_ED25519, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), sign, &signLen), CRYPT_CURVE25519_NO_PRVKEY); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, CRYPT_MD_SHA256, data, sizeof(data), sign, &signLen), + CRYPT_CURVE25519_HASH_METH_ERROR); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, NULL, sizeof(data), sign, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), NULL, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), (uint8_t *)sign, NULL), CRYPT_NULL_INPUT); + + signLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), sign, &signLen), CRYPT_CURVE25519_SIGNLEN_ERROR); + signLen = CRYPT_CURVE25519_SIGNLEN - 1; + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), sign, &signLen), CRYPT_CURVE25519_SIGNLEN_ERROR); + + signLen = CRYPT_CURVE25519_SIGNLEN; + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), sign, &signLen), CRYPT_SUCCESS); + signLen = CRYPT_CURVE25519_SIGNLEN + 1; + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), sign, &signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_VERIFY_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeyVerify test. + * @precon Prepare data for verify. + * @brief + * 1. Create the context of the ed25519 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPrv method to set private key, expected result 2. + * 3. Call the CRYPT_EAL_PkeySign method to sign, expected result 2. + * 4. Call the CRYPT_EAL_PkeyVerify method, where all parameters are valid, expected result 2 + * 5. Call the CRYPT_EAL_PkeyVerify method, where other parameters are valid, but : + * (1) hashId != CRYPT_MD_SHA512, expected result 3 + * (2) data = NULL, expected result 4 + * (3) sign = NULL, expected result 4 + * (4) signLen = 0 | 63 | 65, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_CURVE25519_HASH_METH_ERROR + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_CURVE25519_SIGNLEN_ERROR + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_VERIFY_API_TC001(void) +{ + int hashId = CRYPT_MD_SHA512; + uint8_t data[CRYPT_CURVE25519_KEYLEN] = {0}; + uint8_t sign[CRYPT_CURVE25519_SIGNLEN] = {0}; + uint32_t signLen = sizeof(sign); + uint8_t key[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + Set_Curve25519_Prv(&prv, CRYPT_PKEY_ED25519, key, CRYPT_CURVE25519_KEYLEN); + CRYPT_EAL_PkeyPub pub = {0}; + Set_Curve25519_Pub(&pub, CRYPT_PKEY_ED25519, key, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, data, sizeof(data), sign, &signLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, CRYPT_MD_SHA256, data, sizeof(data), sign, signLen), + CRYPT_CURVE25519_HASH_METH_ERROR); + + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, data, sizeof(data), sign, signLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, NULL, sizeof(data), sign, signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, data, sizeof(data), NULL, signLen), CRYPT_NULL_INPUT); + + signLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, data, sizeof(data), sign, signLen), CRYPT_CURVE25519_SIGNLEN_ERROR); + signLen = CRYPT_CURVE25519_SIGNLEN - 1; + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, data, sizeof(data), sign, signLen), CRYPT_CURVE25519_SIGNLEN_ERROR); + signLen = CRYPT_CURVE25519_SIGNLEN + 1; + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, data, sizeof(data), sign, signLen), CRYPT_CURVE25519_SIGNLEN_ERROR); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_DUP_CTX_API_TC001 + * @title CURVE25519: CRYPT_EAL_PkeyDupCtx test. + * @precon nan + * @brief + * 1. Create the context of the ed25519 algorithm, expected result 1. + * 2. Init the drbg, expected result 2. + * 3. Generate a key pair, expected result 2. + * 4. Call the CRYPT_EAL_PkeyDupCtx method to dup ed25519 context, expected result 2. + * 5. Call the CRYPT_EAL_PkeyGetPub method to obtain the public key from the contexts, expected result 2. + * 6. Compare public keys, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. The two public keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_DUP_CTX_API_TC001(int id) +{ + uint8_t key1[CRYPT_CURVE25519_KEYLEN] = {0}; + uint8_t key2[CRYPT_CURVE25519_KEYLEN] = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_Curve25519_Pub(&pub, id, key1, CRYPT_CURVE25519_KEYLEN); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + CRYPT_EAL_PkeyCtx *newPkey = CRYPT_EAL_PkeyDupCtx(pkey); + ASSERT_TRUE(newPkey != NULL); + ASSERT_EQ(newPkey->references.count, 1); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pub), CRYPT_SUCCESS); + pub.key.curve25519Pub.data = key2; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(newPkey, &pub), CRYPT_SUCCESS); + + ASSERT_COMPARE("curve25519 copy ctx", key1, CRYPT_CURVE25519_KEYLEN, key2, CRYPT_CURVE25519_KEYLEN); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(newPkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ED25519_SIGN_FUNC_TC001 + * @title ED25519 signature test: set the key and sign. + * @precon Test Vectors for Ed25519: SECRET KEY, MESSAGE(different length), SIGNATURE + * @brief + * 1. Create the context of the ed25519 algorithm, expected result 1. + * 2. Set the private key for ed25519, expected result 2. + * 3. Compute the signature of ed25519, expected result 2. + * 4. Compare the signature computed by step 3 and the signature vector, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. Success. + * 3. The signature calculation result is the same as the signature vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ED25519_SIGN_FUNC_TC001(Hex *key, Hex *msg, Hex *sign) +{ + uint8_t *out = NULL; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyPrv prv = {0}; + Set_Curve25519_Prv(&prv, CRYPT_PKEY_ED25519, key->x, key->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_PkeyGetSignLen(ctx); + out = calloc(1u, outLen); + ASSERT_TRUE(out != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SHA512, msg->x, msg->len, out, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(memcmp(out, sign->x, sign->len), 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + free(out); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001 + * @title ED25519 signature verification test: set the public key and verify the signature. + * @precon Test Vectors for Ed25519: PUBLIC KEY, MESSAGE(different length), SIGNATURE + * @brief + * 1. Create the context of the ed25519 algorithm, expected result 1. + * 2. Set the public key for ed25519, expected result 2. + * 3. Verify the signature of ed25519, expected result 2. + * @expect + * 1. Success, and context is not NULL. + * 2. Success. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001(Hex *key, Hex *msg, Hex *sign) +{ + CRYPT_EAL_PkeyPub pub = {0}; + Set_Curve25519_Pub(&pub, CRYPT_PKEY_ED25519, key->x, key->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, CRYPT_MD_SHA512, msg->x, msg->len, sign->x, sign->len), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001 + * @title ED25519: Set(or copy) the key, sign, and verify the signature. + * @precon Test Vectors for Ed25519: SECRET KEY, PUBLIC KEY, MESSAGE(different length), SIGNATURE + * @brief + * 1. Create the context of the ed25519 algorithm, expected result 1 + * 2. Set the private key for ed25519, expected result 2 + * 3. Set the public key for ed25519(Public key and private key can coexist.), expected result 2 + * 4. Compute the signature of ed25519, expected result 2 + * 5. Compare Signatures, expected result 3. + * 6. Verify the signature of ed25519, expected result 2. + * 7. Copy the context of ed25519, expected result 2. + * 8. Repeat steps 4 through 6 above. + * @expect + * 1. Success, and context is not NULL. + * 2. Success. + * 3. The signature calculation result is the same as the signature vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001(Hex *prvKey, Hex *pubKey, Hex *msg, Hex *sign) +{ +#ifndef HITLS_CRYPTO_ED25519 + SKIP_TEST(); +#endif + uint8_t out[CRYPT_CURVE25519_SIGNLEN] = {0}; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + + Set_Curve25519_Pub(&pub, CRYPT_PKEY_ED25519, pubKey->x, pubKey->len); + Set_Curve25519_Prv(&prv, CRYPT_PKEY_ED25519, prvKey->x, prvKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, CRYPT_MD_SHA512, msg->x, msg->len, out, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(memcmp(out, sign->x, sign->len), 0); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, CRYPT_MD_SHA512, msg->x, msg->len, sign->x, sign->len), CRYPT_SUCCESS); + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, pkey), CRYPT_SUCCESS); + outLen = sizeof(out); + ASSERT_EQ(CRYPT_EAL_PkeySign(cpyCtx, CRYPT_MD_SHA512, msg->x, msg->len, out, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(memcmp(out, sign->x, sign->len), 0); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(cpyCtx, CRYPT_MD_SHA512, msg->x, msg->len, sign->x, sign->len), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_X25519_EXCH_FUNC_TC001 + * @title X25519 key exchange test: generate key pair and key exchange. + * @precon nan + * @brief + * 1. Create two contexts(pkey1, pkey2) of the ed25519 algorithm, expected result 1. + * 2. Init the drbg, expected result 2. + * 3. Generate a key pair, expected result 2. + * 4. Compute the shared key from the privite value in pkey1 and the public vlaue in pkey2, expected result 2. + * 5. Compute the shared key from the privite value in pkey2 and the public vlaue in pkey1, expected result 2. + * 6. Compare the shared keys computed in the preceding two steps, expected result 3. + * @expect + * 1. Success, and two contexts are not NULL. + * 2. Success. + * 3. The two shared keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_X25519_EXCH_FUNC_TC001(void) +{ +#ifndef HITLS_CRYPTO_X25519 + SKIP_TEST(); +#endif + uint8_t share1[CRYPT_CURVE25519_KEYLEN] = {0}; + uint8_t share2[CRYPT_CURVE25519_KEYLEN] = {0}; + uint32_t share1Len = sizeof(share1); + uint32_t share2Len = sizeof(share2); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_X25519); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_X25519); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + // Sets the entropy source. + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey2), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len), CRYPT_SUCCESS); + ASSERT_EQ(share1Len, share2Len); + ASSERT_EQ(memcmp(share1, share2, share1Len), 0); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_X25519_EXCH_FUNC_TC002 + * @title X25519 key exchange test: set the key or copy the context, and exchange the key. + * @precon Test Vectors for X25519: One's public key, The other's private key, Their shared key + * @brief + * 1. Create two contexts(pkey1, pkey2) of the X25519 algorithm, expected result 1. + * 2. Set the public key and private key for pkey1 and pkey2, expected result 2. + * 3. Compute the shared key from the privite value in pkey1 and the public vlaue in pkey2, expected result 2. + * 4. Compare the shared key computed by step 5 and the share secret vector, expected result 3. + * 5. Copy the two contexts, expected result 2. + * 6. Repeat steps 3 and 4 above. + * @expect + * 1. Success, and two contexts are not NULL. + * 2. Success. + * 3. The two shared keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_X25519_EXCH_FUNC_TC002(Hex *pubkey, Hex *prvkey, Hex *share) +{ +#ifndef HITLS_CRYPTO_X25519 + SKIP_TEST(); +#endif + uint8_t shareKey[CRYPT_CURVE25519_KEYLEN]; + uint32_t shareLen = sizeof(shareKey); + CRYPT_EAL_PkeyCtx *cpyCtx1 = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx2 = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + + Set_Curve25519_Pub(&pub, CRYPT_PKEY_X25519, pubkey->x, pubkey->len); + Set_Curve25519_Prv(&prv, CRYPT_PKEY_X25519, prvkey->x, prvkey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_X25519); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_X25519); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey1, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey1, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey2, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey2, &prv), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareKey, &shareLen), CRYPT_SUCCESS); + ASSERT_EQ(shareLen, share->len); + ASSERT_EQ(memcmp(shareKey, share->x, shareLen), 0); + + cpyCtx1 = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + cpyCtx2 = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx1 != NULL && cpyCtx2 != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx1, pkey1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx2, pkey2), CRYPT_SUCCESS); + shareLen = sizeof(shareKey); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(cpyCtx1, cpyCtx2, shareKey, &shareLen), CRYPT_SUCCESS); + ASSERT_EQ(shareLen, share->len); + ASSERT_EQ(memcmp(shareKey, share->x, shareLen), 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); + CRYPT_EAL_PkeyFreeCtx(cpyCtx1); + CRYPT_EAL_PkeyFreeCtx(cpyCtx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_CMP_FUNC_TC001 + * @title Curve25519: The input and output parameters address are the same. + * @precon Vector: private key and public key. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the curve25519 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set public key for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set public key for ctx2, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 3. CRYPT_SUCCESS + * 4. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 5-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_CMP_FUNC_TC001(int algId, Hex *pubKey) +{ + CRYPT_EAL_PkeyPub pub = {0}; + Set_Curve25519_Pub(&pub, algId, pubKey->x, pubKey->len); + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(algId); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_CURVE25519_NO_PUBKEY); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_CURVE25519_NO_PUBKEY); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ED25519_KEY_PAIR_CHECK_FUNC_TC001 + * @title Ed25519: key pair check. + * @precon Registering memory-related functions. + * @brief + * 1. Create two contexts(pubCtx, prvCtx) of the ed25519 algorithm, expected result 1 + * 2. Set public key for pubCtx, expected result 2 + * 3. Set private key for prvCtx, expected result 3 + * 4. Check whether the public key matches the private key, expected result 4 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS + * 4. Return CRYPT_SUCCESS when expect is 1, CRYPT_CURVE25519_VERIFY_FAIL otherwise. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ED25519_KEY_PAIR_CHECK_FUNC_TC001(Hex *pubkey, Hex *prvkey, int expect) +{ + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + int expectRet = expect == 1 ? CRYPT_SUCCESS : CRYPT_CURVE25519_VERIFY_FAIL; + + Set_Curve25519_Prv(&prv, CRYPT_PKEY_ED25519, prvkey->x, prvkey->len); + Set_Curve25519_Pub(&pub, CRYPT_PKEY_ED25519, pubkey->x, pubkey->len); + + TestMemInit(); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ED25519); + ASSERT_TRUE(pubCtx != NULL && prvCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pubCtx, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(prvCtx, &prv), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyPairCheck(pubCtx, prvCtx), expectRet); +exit: + CRYPT_EAL_PkeyFreeCtx(pubCtx); + CRYPT_EAL_PkeyFreeCtx(prvCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CURVE25519_GET_KEY_BITS_FUNC_TC001 + * @title CURVE25519: get key bits. + * @brief + * 1. Create a context of the Curve25519 algorithm, expected result 1 + * 2. Get key bits, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. Equal to keyBits. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CURVE25519_GET_KEY_BITS_FUNC_TC001(int id, int keyBits) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(pkey) == (uint32_t)keyBits); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/curve25519/test_suite_sdv_eal_curve25519.data b/testcode/sdv/testcase/crypto/curve25519/test_suite_sdv_eal_curve25519.data new file mode 100644 index 00000000..1cb9ea9f --- /dev/null +++ b/testcode/sdv/testcase/crypto/curve25519/test_suite_sdv_eal_curve25519.data @@ -0,0 +1,138 @@ + +SDV_CRYPTO_CURVE25519_SET_PARA1_WITH_ED25519 +SDV_CRYPTO_CURVE25519_SET_PARA_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_SET_PARA1_WITH_X25519 +SDV_CRYPTO_CURVE25519_SET_PARA_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_SET_PRVKEY_WITH_ED25519 +SDV_CRYPTO_CURVE25519_SET_PRV_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_SET_PRVKEY_WITH_X25519 +SDV_CRYPTO_CURVE25519_SET_PRV_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_SET_PUBKEY_WITH_ED25519 +SDV_CRYPTO_CURVE25519_SET_PUB_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_SET_PUBKEY_WITH_X25519 +SDV_CRYPTO_CURVE25519_SET_PUB_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_GET_PRVKEY_WITH_ED25519 +SDV_CRYPTO_CURVE25519_GET_PRV_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_GET_PRVKEY_WITH_X25519 +SDV_CRYPTO_CURVE25519_GET_PRV_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_GET_PUBKEY_WITH_ED25519 +SDV_CRYPTO_CURVE25519_GET_PUB_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_GET_PUBKEY_WITH_X25519 +SDV_CRYPTO_CURVE25519_GET_PUB_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_GET_KEYLEN_WITH_ED25519 +SDV_CRYPTO_CURVE25519_GET_KEY_LEN_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_GET_KEYLEN_WITH_X25519 +SDV_CRYPTO_CURVE25519_GET_KEY_LEN_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_KEYGEN_WITH_ED25519 +SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_KEYGEN_WITH_X25519 +SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_KEYGEN002_WITH_ED25519 +SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC002:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_CURVE25519_KEYGEN002_WITH_X25519 +SDV_CRYPTO_CURVE25519_KEY_GEN_API_TC002:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_SIGN_WITH_ED25519 +SDV_CRYPTO_CURVE25519_SIGN_API_TC001: + +SDV_CRYPTO_CURVE25519_VERIFY_WITH_ED25519 +SDV_CRYPTO_CURVE25519_VERIFY_API_TC001: + +SDV_CRYPTO_CURVE25519_DUP_CTX_API_TC001 curve25519 copy ctx 1 +SDV_CRYPTO_CURVE25519_DUP_CTX_API_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_CURVE25519_DUP_CTX_API_TC001 curve25519 copy ctx 2 +SDV_CRYPTO_CURVE25519_DUP_CTX_API_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001 #1: RFC8032 7.1 -----TEST1 +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001:"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60":"":"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b" + +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001 #2: RFC8032 7.1 -----TEST2 +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001:"4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb":"72":"92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00" + +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001 #3: RFC8032 7.1 -----TEST3 +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001:"c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7":"af82":"6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a" + +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001 #4: RFC8032 7.1 -----TEST SHA(abc) +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001:"833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42":"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704" + +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001 #5: RFC8032 7.1 -----TEST 1024 +SDV_CRYPTO_ED25519_SIGN_FUNC_TC001:"f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5":"08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0":"0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03" + +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001 #1: RFC8032 7.1 -----TEST1 +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001:"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a":"":"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b" + +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001 #2: RFC8032 7.1 -----TEST2 +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001:"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c":"72":"92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00" + +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001 #3: RFC8032 7.1 -----TEST3 +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001:"fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025":"af82":"6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a" + +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001 #4: RFC8032 7.1 -----TEST SHA(abc) +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001:"ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf":"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704" + +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001 #5: RFC8032 7.1 -----TEST 1024 +SDV_CRYPTO_ED25519_VERIFY_FUNC_TC001:"278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e":"08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0":"0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03" + +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001 #1: RFC8032 7.1 -----TEST1 +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001:"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60":"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a":"":"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b" + +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001 #2: RFC8032 7.1 -----TEST2 +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001:"4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb":"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c":"72":"92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00" + +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001 #3: RFC8032 7.1 -----TEST3 +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001:"c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7":"fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025":"af82":"6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a" + +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001 #4: RFC8032 7.1 -----TEST SHA(abc) +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001:"833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42":"ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf":"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f":"dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704" + +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001 #5: RFC8032 7.1 -----TEST 1024 +SDV_CRYPTO_ED25519_SIGN_VERIFY_FUNC_TC001:"f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5":"278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e":"08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0":"0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03" + +SDV_CRYPTO_X25519_COMPUTE_SHARE_KEY_WITH_X25519 +SDV_CRYPTO_X25519_EXCH_FUNC_TC001: + +SDV_CRYPTO_X25519_EXCH_FUNC_TC002 x25519 vector #1 : RFC 7748, 5.2 +SDV_CRYPTO_X25519_EXCH_FUNC_TC002:"e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c":"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":"c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552" + +SDV_CRYPTO_X25519_EXCH_FUNC_TC002 x25519 vector #2 : RFC 7748, 5.2 +SDV_CRYPTO_X25519_EXCH_FUNC_TC002:"e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a413":"4866e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba4d":"95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957" + +SDV_CRYPTO_X25519_EXCH_FUNC_TC002 x25519 vector #3: RFC 7748, 6.1 (Bob's public key, Alice's private key) +SDV_CRYPTO_X25519_EXCH_FUNC_TC002:"de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":"77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" + +SDV_CRYPTO_X25519_EXCH_FUNC_TC002 x25519 vector #4: RFC 7748, 6.1 (Alice's public key, Bob's private key) +SDV_CRYPTO_X25519_EXCH_FUNC_TC002:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb":"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" + +SDV_CRYPTO_CURVE25519_CMP_FUNC_TC001: x25519 public key compare +SDV_CRYPTO_CURVE25519_CMP_FUNC_TC001:CRYPT_PKEY_X25519:"e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c" + +SDV_CRYPTO_CURVE25519_CMP_FUNC_TC001: ed25519 public key compare +SDV_CRYPTO_CURVE25519_CMP_FUNC_TC001:CRYPT_PKEY_ED25519:"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a" + +Ed25519 key pair check: RFC8032 7.1, Pass +SDV_CRYPTO_ED25519_KEY_PAIR_CHECK_FUNC_TC001:"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a":"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60":1 + +Ed25519 key pair check: RFC8032 7.1, Fail +SDV_CRYPTO_ED25519_KEY_PAIR_CHECK_FUNC_TC001:"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a":"4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb":0 + +SDV_CRYPTO_CURVE25519_GET_KEY_BITS_FUNC_TC001_WITH_ED25519 +SDV_CRYPTO_CURVE25519_GET_KEY_BITS_FUNC_TC001:CRYPT_PKEY_ED25519:256 + +SDV_CRYPTO_CURVE25519_GET_KEY_BITS_FUNC_TC001_WITH_X25519 +SDV_CRYPTO_CURVE25519_GET_KEY_BITS_FUNC_TC001:CRYPT_PKEY_X25519:256 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/dh/test_suite_sdv_eal_dh.c b/testcode/sdv/testcase/crypto/dh/test_suite_sdv_eal_dh.c new file mode 100644 index 00000000..10e39a45 --- /dev/null +++ b/testcode/sdv/testcase/crypto/dh/test_suite_sdv_eal_dh.c @@ -0,0 +1,1540 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" + +#include "bsl_sal.h" +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "crypt_eal_rand.h" +#include "crypt_util_rand.h" + +#define UINT8_MAX_NUM 255 + +static int32_t RandFunc(uint8_t *randNum, uint32_t randLen) +{ + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % UINT8_MAX_NUM); + } + return 0; +} + +static void Set_DH_Para( + CRYPT_EAL_PkeyPara *para, uint8_t *p, uint8_t *q, uint8_t *g, uint32_t pLen, uint32_t qLen, uint32_t gLen) +{ + para->id = CRYPT_PKEY_DH; + para->para.dhPara.p = p; + para->para.dhPara.q = q; + para->para.dhPara.g = g; + para->para.dhPara.pLen = pLen; + para->para.dhPara.qLen = qLen; + para->para.dhPara.gLen = gLen; +} + +static void Set_DH_Prv(CRYPT_EAL_PkeyPrv *prv, uint8_t *key, uint32_t keyLen) +{ + prv->id = CRYPT_PKEY_DH; + prv->key.dhPrv.data = key; + prv->key.dhPrv.len = keyLen; +} + +static void Set_DH_Pub(CRYPT_EAL_PkeyPub *pub, uint8_t *key, uint32_t keyLen) +{ + pub->id = CRYPT_PKEY_DH; + pub->key.dhPub.data = key; + pub->key.dhPub.len = keyLen; +} +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_DH_FUNC_TC001 + * @title DH Key exchange vector test. + * @precon Registering memory-related functions. + * NIST test vectors. + * @brief + * 1. Create the contexts(pkey1, pkey2) of the dh algorithm, expected result 1 + * 2. Set parameters for pkey1, expected result 2 + * 3. Call the CRYPT_EAL_PkeyComputeShareKey method: pkey1(A.prvKey) and pkey2(B.pubKey), expected result 3 + * 4. Check whether the generated key is consistent with the vector, expected result 4 + * 5. Call the CRYPT_EAL_PkeyComputeShareKey method: pkey1(B.prvKey) and pkey2(A.pubKey), expected result 5 + * 6. Check whether the generated key is consistent with the vector, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS + * 4. Both are consistent. + * 5. CRYPT_SUCCESS + * 6. Both are consistent. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_FUNC_TC001(Hex *p, Hex *g, Hex *q, Hex *prv1, Hex *pub1, Hex *prv2, Hex *pub2, Hex *share) +{ + CRYPT_RandRegist(RandFunc); + uint8_t shareLocal[1030]; + uint32_t shareLen = sizeof(shareLocal); + + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prv1->x, prv1->len); + Set_DH_Pub(&pub, pub2->x, pub2->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen) == CRYPT_SUCCESS); + ASSERT_TRUE(shareLen == share->len); + ASSERT_TRUE(memcmp(shareLocal, share->x, shareLen) == 0); + + Set_DH_Prv(&prv, prv2->x, prv2->len); + Set_DH_Pub(&pub, pub1->x, pub1->len); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen) == CRYPT_SUCCESS); + ASSERT_TRUE(shareLen == share->len); + ASSERT_TRUE(memcmp(shareLocal, share->x, shareLen) == 0); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_FUNC_TC002 + * @title DH Key exchange test: Generate key pairs. + * @precon Registering memory-related functions. + * Nist test vectors: DH parameters. + * @brief + * 1. Create the contexts(pkey1, pkey2) of the dh algorithm, expected result 1 + * 2. Set parameters for pkey1 and pkey2, expected result 2 + * 3. Generate key pairs, expected result 2 + * 4. Compute the shared key from the privite value in pkey1 and the public vlaue in peky2, expected result 2. + * 5. Compute the shared key from the privite value in pkey2 and the public vlaue in pkey1, expected result 2. + * 6. Compare the shared keys computed in the preceding two steps, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. The two shared keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_FUNC_TC002(Hex *p, Hex *g, Hex *q) +{ + CRYPT_RandRegist(RandFunc); + uint8_t share1[1030]; + uint8_t share2[1030]; + uint32_t share1Len = sizeof(share1); + uint32_t share2Len = sizeof(share2); + + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey2) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len) == CRYPT_SUCCESS); + ASSERT_TRUE(share1Len == share2Len); + ASSERT_TRUE(memcmp(share1, share2, share1Len) == 0); +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_FUNC_TC003 + * @title DH Key exchange test: Set parameters based on the ID to generate key pairs. + * @precon Registering memory-related functions. + * @brief + * 1. Create the contexts(pkey1, pkey2) of the dh algorithm, expected result 1 + * 2. Set parameters byt id for pkey1 and pkey2, expected result 2 + * 3. Generate key pairs, expected result 2 + * 4. Compute the shared key from the privite value in pkey1 and the public vlaue in peky2, expected result 2. + * 5. Compute the shared key from the privite value in pkey2 and the public vlaue in pkey1, expected result 2. + * 6. Compare the shared keys computed in the preceding two steps, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. The two shared keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_FUNC_TC003(int id) +{ + uint8_t share1[1030]; + uint8_t share2[1030]; + uint32_t share1Len = sizeof(share1); + uint32_t share2Len = sizeof(share2); + + CRYPT_RandRegist(RandFunc); + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(pkey1, id) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(pkey2, id) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey2) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len) == CRYPT_SUCCESS); + ASSERT_TRUE(share1Len == share2Len); + ASSERT_TRUE(memcmp(share1, share2, share1Len) == 0); +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_FUNC_TC004 + * @title DH Key exchange test: Generate a key pair repeatedly. + * @precon Registering memory-related functions. + * Nist test vectors: DH parameters. + * @brief + * 1. Create the contexts(pkey1, pkey2) of the dh algorithm, expected result 1 + * 2. Set parameters for pkey1 and pkey2, expected result 2 + * 3. Generate a key pair repeatedly, expected result 2 + * 4. Compute the shared key from the privite value in pkey1 and the public vlaue in peky2, expected result 2. + * 5. Compute the shared key from the privite value in pkey2 and the public vlaue in pkey1, expected result 2. + * 6. Compare the shared keys computed in the preceding two steps, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. The two shared keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_FUNC_TC004(Hex *p, Hex *g, Hex *q) +{ + CRYPT_RandRegist(RandFunc); + uint8_t share1[1030]; + uint8_t share2[1030]; + uint32_t share1Len = sizeof(share1); + uint32_t share2Len = sizeof(share2); + + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey2) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey2) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share1, &share1Len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey2, pkey1, share2, &share2Len) == CRYPT_SUCCESS); + ASSERT_TRUE(share1Len == share2Len); + ASSERT_TRUE(memcmp(share1, share2, share1Len) == 0); +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_FUNC_TC005 + * @title DH Key exchange failed. The public key is invalid. + * @precon Registering memory-related functions. + * Nist test vectors: DH parameters, private key, public key. + * @brief + * 1. Create the contexts(pkey1, pkey2) of the dh algorithm, expected result 1. + * 2. Set parameters for pkey1, expected result 2 + * 3. Call the CRYPT_EAL_PkeyComputeShareKey method: + * (1) pkey1(valid prvKey), pkey2(pubKey = p - 1), expected result 3 + * (2) pkey1(valid prvKey), pkey2(pubKey ^ q mod p != 1), expected result 3 + * (3) pkey1(valid prvKey), pkey2(pubKey = 0), expected result 3 + * (4) pkey1(valid prvKey), pkey2(pubKey = 1), expected result 3 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_DH_KEYINFO_ERROR + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_FUNC_TC005(Hex *p, Hex *g, Hex *q, Hex *prv1, Hex *pub1) +{ + uint8_t shareLocal[1030]; + uint32_t shareLen = sizeof(shareLocal); + + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + uint8_t *tmpPub = (uint8_t *)malloc(sizeof(uint8_t) * p->len); + ASSERT_TRUE(tmpPub != NULL); + ASSERT_TRUE(memcpy_s(tmpPub, p->len, p->x, p->len) == 0); + int last = p->len - 1; + tmpPub[last] -= 1; // pubKey = p - 1 + + Set_DH_Prv(&prv, prv1->x, prv1->len); + Set_DH_Pub(&pub, tmpPub, p->len); + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR); + + ASSERT_TRUE(memcpy_s(tmpPub, p->len, pub1->x, pub1->len) == 0); + last = pub1->len - 1; + tmpPub[last] += 1; // pubKey ^ q mod p != 1 + pub.key.dhPub.len = pub1->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR); + + ASSERT_TRUE(memset_s(tmpPub, p->len, 0, p->len) == 0); // pubKey = 0; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR); + + tmpPub[last] = 1; // pubKey = 1 + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen), CRYPT_DH_KEYINFO_ERROR); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); + if (tmpPub != NULL) { + free(tmpPub); + } +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_FUNC_TC006 + * @title Key exchange failure vector test, invalid vector. + * @precon Registering memory-related functions. + * NIST test vectors. + * @brief + * 1. Create the contexts(pkey1, pkey2) of the dh algorithm, expected result 1. + * 2. Set parameters for pkey1, expected result 2 + * 3. Call the CRYPT_EAL_PkeyComputeShareKey method: pkey1(A.prvKey) and pkey2(B.pubKey) + * 4. Check whether the generated shared key is consistent with the vector + * 5. Call the CRYPT_EAL_PkeyComputeShareKey method: pkey1(B.prvKey) and pkey2(A.pubKey) + * 6. Check whether the generated key is consistent with the vector + * 7. Check the values returned in steps 3 to 6, expected result 3 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_SUCCESS + * 3. At least one failure or the generated key and vector are not equal. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_FUNC_TC006(Hex *p, Hex *g, Hex *q, Hex *prv1, Hex *pub1, Hex *prv2, Hex *pub2, Hex *share) +{ + uint8_t shareLocal[1030]; + uint32_t shareLen = sizeof(shareLocal); + int ret1, ret2; + int cmpRet1, cmpRet2; + + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prv1->x, prv1->len); + Set_DH_Pub(&pub, pub2->x, pub2->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ret1 = CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen); + cmpRet1 = memcmp(shareLocal, share->x, share->len); + + Set_DH_Prv(&prv, prv2->x, prv2->len); + Set_DH_Pub(&pub, pub1->x, pub1->len); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ret2 = CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen); + + ret2 = CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, shareLocal, &shareLen); + cmpRet2 = memcmp(shareLocal, share->x, share->len); + + ASSERT_TRUE(ret1 != CRYPT_SUCCESS || cmpRet1 != 0 || ret2 != CRYPT_SUCCESS || cmpRet2 != 0); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PARA_API_TC001 + * @title DH CRYPT_EAL_PkeySetPara: Invalid parameter (NULL). + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method: p = null, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method: pLen = 0, expected result 2 + * 4. Call the CRYPT_EAL_PkeySetPara method: g = null, expected result 2 + * 5. Call the CRYPT_EAL_PkeySetPara method: gLen = 0, expected result 2 + * 6. Call the CRYPT_EAL_PkeySetPara method: q = null, qLen != 0, expected result 2 + * 7. Call the CRYPT_EAL_PkeySetPara method: ctx = null, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_EAL_ERR_NEW_PARA_FAIL + * 3. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PARA_API_TC001(Hex *p, Hex *g, Hex *q) +{ + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, NULL, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE_AND_LOG("p is null", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.p = p->x; + para.para.dhPara.pLen = 0; + ASSERT_TRUE_AND_LOG("pLen is zero", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.pLen = p->len; + para.para.dhPara.g = NULL; + ASSERT_TRUE_AND_LOG("g is null", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.g = g->x; + para.para.dhPara.gLen = 0; + ASSERT_TRUE_AND_LOG("gLen is zero", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.gLen = g->len; + para.para.dhPara.q = NULL; + ASSERT_TRUE_AND_LOG("q is null but qLen != 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.q = q->x; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(NULL, ¶) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PARA_API_TC002 + * @title DH CRYPT_EAL_PkeySetPara: Invalid parameter(length). + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method: pLen > 8192, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method: pLen < 768, expected result 2 + * 4. Call the CRYPT_EAL_PkeySetPara method: pLen > 768, but actual data Len < 768, expected result 3 + * 5. Call the CRYPT_EAL_PkeySetPara method: qLen < 160, expected result 3 + * 6. Call the CRYPT_EAL_PkeySetPara method: qLen > pLen, expected result 2 + * 7. Call the CRYPT_EAL_PkeySetPara method: qLen > 160, but actual data Len < 160, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_EAL_ERR_NEW_PARA_FAIL + * 3. CRYPT_DH_PARA_ERROR + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PARA_API_TC002(Hex *p, Hex *g, Hex *q) +{ + uint8_t longBuf[1030] = {0}; + uint32_t bufLen = sizeof(longBuf); + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, longBuf, q->x, g->x, bufLen, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + longBuf[0] = 1; + longBuf[1024] = 1; + + ASSERT_TRUE_AND_LOG("p greater than 8192", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.p = p->x; + para.para.dhPara.pLen = 95; // 768 / 8 = 96, 96 - 1 = 95 + ASSERT_TRUE_AND_LOG("p smaller than 768", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + (void)memset_s(longBuf, sizeof(longBuf), 0, sizeof(longBuf)); + longBuf[p->len - 1] = 1; + para.para.dhPara.p = longBuf; + para.para.dhPara.pLen = p->len; + ASSERT_TRUE_AND_LOG("p greater than 768 but value smaller than 768 bits", + CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + para.para.dhPara.p = p->x; + para.para.dhPara.pLen = p->len; + para.para.dhPara.qLen = 19; // 160 / 8 = 20, 19 < 20 + para.para.dhPara.q = longBuf; + (void)memset_s(longBuf, sizeof(longBuf), 0, sizeof(longBuf)); + longBuf[18] = 1; + ASSERT_TRUE_AND_LOG("q smaller than 160", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + para.para.dhPara.qLen = p->len + 1; + ASSERT_TRUE_AND_LOG("q longer than p", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + (void)memset_s(longBuf, sizeof(longBuf), 0, sizeof(longBuf)); + longBuf[20] = 1; + para.para.dhPara.qLen = 21; + ASSERT_TRUE_AND_LOG("q greater than 160 but value smaller than 160 bits", + CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PARA_API_TC003 + * @title DH CRYPT_EAL_PkeySetPara: Invalid parameter (value). + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method: p is an even number, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method: q is an even number, expected result 2 + * 4. Call the CRYPT_EAL_PkeySetPara method: g=0, expected result 2 + * 5. Call the CRYPT_EAL_PkeySetPara method: g=1, expected result 2 + * 6. Call the CRYPT_EAL_PkeySetPara method: g=p-1, expected result 2 + * 7. Call the CRYPT_EAL_PkeySetPara method: q=p-1, expected result 2 + * 8. Call the CRYPT_EAL_PkeySetPara method: q=p-2, expected result 2 + * 9. Call the CRYPT_EAL_PkeySetPara method: q=p+2>p, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_DH_PARA_ERROR + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PARA_API_TC003(Hex *p, Hex *g, Hex *q) +{ + uint8_t buf[1030]; + uint32_t bufLen = sizeof(buf); + CRYPT_EAL_PkeyPara para = {0}; + + Set_DH_Para(¶, NULL, q->x, g->x, 0, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + int last = p->len - 1; + ASSERT_TRUE(memcpy_s(buf, bufLen, p->x, p->len) == 0); + buf[last] += 1; // p is even + + para.para.dhPara.p = buf; + para.para.dhPara.pLen = p->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + ASSERT_TRUE(memcpy_s(buf, bufLen, q->x, q->len) == 0); + last = q->len - 1; + buf[last] += 1; // q is even + para.para.dhPara.p = p->x; + para.para.dhPara.q = buf; + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); // g = 0 + para.para.dhPara.q = q->x; + para.para.dhPara.g = buf; + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + last = g->len - 1; + buf[last] = 1; // g = 1 + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + last = p->len - 1; + para.para.dhPara.gLen = p->len; + ASSERT_TRUE(memcpy_s(buf, bufLen, p->x, p->len) == 0); + buf[last] -= 1; // g = p - 1 + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + // q = p - 1 + para.para.dhPara.g = g->x; + para.para.dhPara.gLen = g->len; + para.para.dhPara.q = buf; + para.para.dhPara.qLen = p->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + buf[last] -= 1; // q = p - 2 + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + + buf[last] += 4; // q = p - 2 + 4 = p + 2 > p + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_DH_PARA_ERROR); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PARA_API_TC004 + * @title DH CRYPT_EAL_PkeySetPara: Repeated call. + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method with normal parameters, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method with normal parameters again, expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPara method: pLen < 768, expected result 4 + * 5. Call the CRYPT_EAL_PkeySetPara method with normal parameters again, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS + * 4. CRYPT_EAL_ERR_NEW_PARA_FAIL + * 5. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PARA_API_TC004(Hex *p, Hex *g, Hex *q) +{ + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + para.para.dhPara.pLen = 95; // 768 / 8 = 96, 95 < 96 + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dhPara.pLen = p->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PRV_API_TC001 + * @title DH: CRYPT_EAL_PkeySetPrv test. + * @precon Registering memory-related functions. + * DH parameters and private key. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPrv method before CRYPT_EAL_PkeySetPara, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method to set para, expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPrv method: + * (1). pkey = NULL, expected result 4. + * (2). prv = NULL, expected result 4. + * (3). prv.data = NULL, expected result 4. + * (4). prv.len = 0, expected result 4. + * (5). prv.id != pkey.id, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_DH_PARA_ERROR + * 3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PRV_API_TC001(Hex *p, Hex *g, Hex *q, Hex *prvKey) +{ + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_DH_PARA_ERROR); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(NULL, &prv) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, NULL) == CRYPT_NULL_INPUT); + + prv.key.dhPrv.data = NULL; + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_NULL_INPUT); + + prv.key.dhPrv.data = prvKey->x; + prv.key.dhPrv.len = 0; + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PRV_API_TC002 + * @title DH: CRYPT_EAL_PkeySetPrv test. Boundary value test for the private key. + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method to set para(q = NULL), expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPrv method: + * (1) prvKey = p - 1, expected result 3 + * (2) prvKey = p - 2, expected result 4 + * 4. Call the CRYPT_EAL_PkeySetPara method to set para(q != NULL), expected result 5 + * 5. Call the CRYPT_EAL_PkeySetPrv method: + * (1) prvKey = q, expected result 6 + * (1) prvKey = 0, expected result 7 + * (1) prvKey = 1, expected result 8 + * (1) prvKey = q - 1, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_DH_KEYINFO_ERROR + * 4. CRYPT_SUCCESS + * 5. CRYPT_SUCCESS + * 6. CRYPT_DH_KEYINFO_ERROR + * 7. CRYPT_SUCCESS + * 8. CRYPT_DH_KEYINFO_ERROR + * 9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PRV_API_TC002(Hex *p, Hex *g, Hex *q) +{ + uint8_t *tmpPrv = NULL; + int last; + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, p->x, NULL, g->x, p->len, 0, g->len); + + CRYPT_EAL_PkeyPrv prv = {0}; + prv.id = CRYPT_PKEY_DH; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + tmpPrv = (uint8_t *)malloc(sizeof(uint8_t) * p->len); + ASSERT_TRUE(memcpy_s(tmpPrv, p->len, p->x, p->len) == 0); + last = p->len - 1; + tmpPrv[last] -= 1; // tmpPrv = p - 1, Vectors are guaranteed not to wrap around. + + prv.key.dhPrv.data = tmpPrv; + prv.key.dhPrv.len = p->len; + + ASSERT_TRUE_AND_LOG("prvKey = p - 1", CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_DH_KEYINFO_ERROR); + + tmpPrv[last] -= 1; // tmpPrv = p - 2, Vectors are guaranteed not to wrap around. + ASSERT_TRUE_AND_LOG("prvKey = p - 2", CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_SUCCESS); + + para.para.dhPara.q = q->x; + para.para.dhPara.qLen = q->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + /* In normal para, p>q does not exceed the threshold. */ + ASSERT_TRUE(memcpy_s(tmpPrv, p->len, q->x, q->len) == 0); + prv.key.dhPrv.len = q->len; + ASSERT_TRUE_AND_LOG("prvKey = q", CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_DH_KEYINFO_ERROR); + + last = q->len - 1; + tmpPrv[last] -= 1; + ASSERT_TRUE_AND_LOG("prvKey = q - 1", CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_SUCCESS); + + (void)memset_s(tmpPrv, p->len, 0, p->len); + ASSERT_TRUE_AND_LOG("prvKey = 0", CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_DH_KEYINFO_ERROR); + + last = q->len - 1; + tmpPrv[last] = 1; + ASSERT_TRUE_AND_LOG("prvKey = 1", CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + if (tmpPrv != NULL) { + free(tmpPrv); + } +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PUB_API_TC001 + * @title DH CRYPT_EAL_PkeySetPub: Invalid parameter(NULL). + * @precon Registering memory-related functions. + * Public key. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPub method: + * (1) pkey = null, expected result 2 + * (2) pubKey = null, expected result 2 + * (3) pubKeyLen = 0, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PUB_API_TC001(Hex *pubKey) +{ + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Pub(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(NULL, &pub) == CRYPT_NULL_INPUT); + + pub.key.dhPub.data = NULL; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pub) == CRYPT_NULL_INPUT); + + pub.key.dhPub.data = pubKey->x; + pub.key.dhPub.len = 0; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pub) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PUB_API_TC002 + * @title DH CRYPT_EAL_PkeySetPub: Invalid parameter(Overlong public key). + * @precon Registering memory-related functions. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPub method: + * (1) pub array Len > 8192, actual Len > 8192, expected result 2 + * (2) pub array Len > 8192, actual Len < 8192, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_DH_KEYINFO_ERROR + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PUB_API_TC002(void) +{ + uint8_t pubKey[1025] = {0}; // 8192/8 + 1 = 1025 + uint32_t pubLen = sizeof(pubKey); + pubKey[0] = 1; + pubKey[1024] = 5; // 1024 is last block + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Pub(&pub, pubKey, pubLen); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pub) == CRYPT_DH_KEYINFO_ERROR); + + pubKey[0] = 0; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pub) == CRYPT_DH_KEYINFO_ERROR); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_GET_PRV_API_TC001 + * @title DH CRYPT_EAL_PkeyGetPrv: Invalid parameter. + * @precon Registering memory-related functions. + * DH parameters and private key. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Set para, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPrv method: all parameters are valid, expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPrv method: all parameters are valid, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetPrv method: prv.data=NULL, expected result 5 + * 6. Call the CRYPT_EAL_PkeyGetPrv method: prv.len < prvKeyLen, expected result 6 + * 7. Compare the setted public key with the obtained public key, expected result 7 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_DH_KEYINFO_ERROR + * 4. CRYPT_SUCCESS + * 5. CRYPT_NULL_INPUT + * 6. CRYPT_DH_BUFF_LEN_NOT_ENOUGH + * 7. The two private keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_GET_PRV_API_TC001(Hex *p, Hex *g, Hex *q, Hex *prvKey) +{ + uint8_t output[1030]; + uint32_t outLen = sizeof(output); + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, output, outLen); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prv) == CRYPT_DH_KEYINFO_ERROR); + + prv.key.dhPrv.data = prvKey->x; + prv.key.dhPrv.len = prvKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_SUCCESS); + + prv.key.dhPrv.data = NULL; + prv.key.dhPrv.len = outLen; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prv) == CRYPT_NULL_INPUT); + + prv.key.dhPrv.data = output; + prv.key.dhPrv.len = prvKey->len - 1; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prv) == CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + + prv.key.dhPrv.len = p->len > q->len ? p->len : q->len; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prv), CRYPT_SUCCESS); + ASSERT_TRUE(prv.key.dhPrv.len == prvKey->len); + ASSERT_TRUE(memcmp(output, prvKey->x, prvKey->len) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_GET_PUB_API_TC001 + * @title DH CRYPT_EAL_PkeyGetPub: Invalid parameter. + * @precon Registering memory-related functions. + * Public key. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetPub method: all parameters are valid, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPub method: all parameters are valid, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGetPub method: pub.data=NULL, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetPub method: pub.len < pubKeyLen, expected result 5 + * 6. Compare the setted public key with the obtained public key, expected result 6. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_DH_KEYINFO_ERROR + * 3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_DH_BUFF_LEN_NOT_ENOUGH + * 6. The two public keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_GET_PUB_API_TC001(Hex *pubKey) +{ + uint8_t output[1030]; + uint32_t outLen = sizeof(output); + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Pub(&pub, output, outLen); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pub) == CRYPT_DH_KEYINFO_ERROR); + + pub.key.dhPub.data = pubKey->x; + pub.key.dhPub.len = pubKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pub) == CRYPT_SUCCESS); + + pub.key.dhPub.data = NULL; + pub.key.dhPub.len = outLen; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pub) == CRYPT_NULL_INPUT); + + pub.key.dhPub.data = output; + pub.key.dhPub.len = pubKey->len - 1; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pub) == CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + + pub.key.dhPub.len = pubKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(pub.key.dhPub.len == pubKey->len); + ASSERT_TRUE(memcmp(output, pubKey->x, pubKey->len) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_GET_KEY_LEN_API_TC001 + * @title CRYPT_EAL_PkeyGetKeyLen test. + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetKeyLen, expected result 2 + * 3. Set para, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGetKeyLen, expected result 4 + * @expect + * 1. Success, and context is not NULL. + * 2. 0 is returned because the parameter is not set. + * 3. CRYPT_SUCCESS + * 4. The obtained length is equal to p->len. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_GET_KEY_LEN_API_TC001(Hex *p, Hex *g, Hex *q) +{ + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyGetKeyLen(pkey), 0); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetKeyLen(pkey), p->len); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_GEN_API_TC001 + * @title DH CRYPT_EAL_PkeyGen test. + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGen method: pkey = NULL, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGen method: pkey != NULL, expected result 3 + * 4. Set para, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGen method: pkey != NULL, expected result 5 + * 6. Initializes the random number, expected result 6 + * 7. Call the CRYPT_EAL_PkeyGen method: pkey != NULL, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_DH_PARA_ERROR + * 4. CRYPT_SUCCESS + * 5. CRYPT_NO_REGIST_RAND + * 6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_GEN_API_TC001(Hex *p, Hex *g, Hex *q) +{ + CRYPT_EAL_PkeyPara para = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyGen(NULL) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_DH_PARA_ERROR); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_NO_REGIST_RAND); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_SET_PARA_BY_ID_API_TC001 + * @title DH CRYPT_EAL_PkeySetParaById test: invalid pkey or wrong ID. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context(pkey) of the dh algorithm, expected result 1 + * 2. Call the PkeySetParaById method: pkey = NULL, expected result 2 + * 3. Call the PkeySetParaById method: invalid id, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_EAL_ERR_NEW_PARA_FAIL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_SET_PARA_BY_ID_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(NULL, CRYPT_DH_RFC3526_2048) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(pkey, 100) == CRYPT_EAL_ERR_NEW_PARA_FAIL); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_EXCH_API_TC001 + * @title DH CRYPT_EAL_PkeyComputeShareKey test: Invalid parameter(NULL). + * @precon Registering memory-related functions. + * DH vectors. + * @brief + * 1. Create two contexts(pkey1, pkey2) of the dh algorithm, expected result 1 + * 2. Set the correct public key for pkey2, expected result 2 + * 3. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 3 + * 4. Set the correct para and private key for pkey1, expected result 4 + * 5. Call the CRYPT_EAL_PkeyComputeShareKey method: pkey=null, expected result 5 + * 6. Call the CRYPT_EAL_PkeyComputeShareKey method: pubKey=null, expected result 5 + * 7. Call the CRYPT_EAL_PkeyComputeShareKey method: share=null, expected result 5 + * 8. Call the CRYPT_EAL_PkeyComputeShareKey method: shareLen=null, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_DH_PARA_ERROR + * 4. CRYPT_SUCCESS + * 5. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_EXCH_API_TC001(Hex *p, Hex *g, Hex *q, Hex *pubKey, Hex *prvKey) +{ + uint8_t share[1030]; + uint32_t shareLen = sizeof(share); + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prvKey->x, prvKey->len); + Set_DH_Pub(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share, &shareLen) == CRYPT_DH_PARA_ERROR); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(NULL, pkey2, share, &shareLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, NULL, share, &shareLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, NULL, &shareLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, (uint8_t *)share, NULL) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_EXCH_API_TC002 + * @title DH CRYPT_EAL_PkeyComputeShareKey test: Invalid parameter(The public key or private key is missing). + * @precon Registering memory-related functions. + * DH vectors. + * @brief + * 1. Create the contexts of the dh algorithm, expected result 1. + * 2. Set the correct para, expected result 2 + * 3. Call the CRYPT_EAL_PkeyComputeShareKey method: no private key, expected result 3 + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method: no public key, expected result 4 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_DH_KEYINFO_ERROR + * 4. CRYPT_DH_KEYINFO_ERROR + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_EXCH_API_TC002(Hex *p, Hex *g, Hex *q, Hex *pubKey, Hex *prvKey) +{ + uint8_t share[1030]; + uint32_t shareLen = sizeof(share); + + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prvKey->x, prvKey->len); + Set_DH_Pub(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey3 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL && pkey3 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey3, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, share, &shareLen) == CRYPT_DH_KEYINFO_ERROR); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(pkey3, pkey2, share, &shareLen) == CRYPT_DH_KEYINFO_ERROR); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); + CRYPT_EAL_PkeyFreeCtx(pkey3); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_EXCH_API_TC003 + * @title DH CRYPT_EAL_PkeyComputeShareKey test: Invalid parameter(The length of the output parameter is insufficient). + * @precon Registering memory-related functions. + * DH vectors. + * @brief + * 1. Create the contexts of the dh algorithm, expected result 1. + * 2. Set the correct para and keys, expected result 2 + * 3. Call the CRYPT_EAL_PkeyComputeShareKey method: shareLen=keyLen-1, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_DH_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_EXCH_API_TC003(Hex *p, Hex *g, Hex *q, Hex *pubKey, Hex *prvKey) +{ + uint8_t share[1030]; + uint32_t shareLen; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prvKey->x, prvKey->len); + Set_DH_Pub(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, &pub) == CRYPT_SUCCESS); + + shareLen = CRYPT_EAL_PkeyGetKeyLen(pkey1) - 1; + + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(pkey1, pkey2, (uint8_t *)share, &shareLen), CRYPT_DH_BUFF_LEN_NOT_ENOUGH); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_GET_PARA_API_TC001 + * @title DH CRYPT_EAL_PkeyGetPara test. + * @precon Registering memory-related functions. + * DH parameters. + * @brief + * 1. Create the contexts of the dh algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method with correct parameters, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method: para.id != pkey.id, expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPara method: pkey=NULL or para=NULL, expected result 4 + * 5. Call the CRYPT_EAL_PkeySetPara method with correct parameters, expected result 5 + * 6. Check whether the configured parameters are the same as the obtained parameters, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_EAL_ERR_ALGID + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_SUCCESS + * 6. Parameters are equal. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_GET_PARA_API_TC001(Hex *p, Hex *q, Hex *g) +{ + uint8_t buf_p[1030] = {0}; + uint32_t bufLen = sizeof(buf_p); + uint8_t buf_q[1030] = {0}; + uint8_t buf_g[1030] = {0}; + + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPara para2 = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Para(¶2, buf_p, buf_q, buf_g, bufLen, bufLen, bufLen); + para2.id = CRYPT_PKEY_RSA; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pKey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pKey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pKey, ¶) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(pKey, ¶2) == CRYPT_EAL_ERR_ALGID); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(NULL, ¶2) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(pKey, NULL) == CRYPT_NULL_INPUT); + + para2.id = CRYPT_PKEY_DH; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(pKey, ¶2) == CRYPT_SUCCESS); + ASSERT_TRUE(para.para.dhPara.pLen == para2.para.dhPara.pLen); + ASSERT_TRUE(memcmp(para.para.dhPara.p, para2.para.dhPara.p, para.para.dhPara.pLen) == 0); + ASSERT_TRUE(para.para.dhPara.qLen == para2.para.dhPara.qLen); + ASSERT_TRUE(memcmp(para.para.dhPara.q, para2.para.dhPara.q, para.para.dhPara.qLen) == 0); + ASSERT_TRUE(para.para.dhPara.gLen == para2.para.dhPara.gLen); + ASSERT_TRUE(memcmp(para.para.dhPara.g, para2.para.dhPara.g, para.para.dhPara.gLen) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pKey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_CMP_API_TC001 + * @title DH: CRYPT_EAL_PkeyCmp invalid parameter test. + * @precon Registering memory-related functions. + * para id and public key. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the dh algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set public key for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set public key for ctx2, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 3. CRYPT_SUCCESS + * 4. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 5-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_CMP_API_TC001(int paraId, Hex *pubKey) +{ + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Pub(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DH_KEYINFO_ERROR); // no key and no para + + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ctx1, paraId), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DH_KEYINFO_ERROR); // ctx2 no pubkey + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DH_PARA_ERROR); // ctx2 no para + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_CTRL_API_TC001 + * @title DH: CRYPT_EAL_PkeyCtrl test. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context(ctx) of the dh algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method: + * (1) val = NULL, expected result 2 + * (2) len = 0, expected result 3 + * (3) opt = CRYPT_CTRL_SET_RSA_PADDING, expected result 4 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_DH_UNSUPPORTED_CTRL_OPTION + * 4. CRYPT_DH_UNSUPPORTED_CTRL_OPTION + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_CTRL_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *ctx = NULL; + int32_t ref = 1; + + TestMemInit(); + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_UP_REFERENCES, NULL, sizeof(uint32_t)), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_UP_REFERENCES, &ref, 0), CRYPT_DH_UNSUPPORTED_CTRL_OPTION); + ASSERT_EQ( + CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_PADDING, &ref, sizeof(int32_t)), CRYPT_DH_UNSUPPORTED_CTRL_OPTION); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_CHECK_FUNC_TC001 + * @title Verify the consistency of the DH key pair. + * @precon Registering memory-related functions. + * DH vectors. + * @brief + * 1. Create the contexts of the dh algorithm, expected result 1. + * 2. Set parameters, public key, and private key, expected result 2 + * 3. Check the consistency of key pairs, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. The returned value is the same as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_CHECK_FUNC_TC001(Hex *p, Hex *g, Hex *q, Hex *prvBuf, Hex *pubBuf, int ret) +{ + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_DH_Para(¶, p->x, q->x, g->x, p->len, q->len, g->len); + Set_DH_Prv(&prv, prvBuf->x, prvBuf->len); + Set_DH_Pub(&pub, pubBuf->x, pubBuf->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCheck(pkey) == ret); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_DUP_CTX_FUNC_TC001 + * @title DH: CRYPT_EAL_PkeyDupCtx test. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context of the dh algorithm, expected result 1. + * 2. Init the drbg, expected result 2. + * 3. Set para by CRYPT_DH_RFC7919_8192 and, generate a key pair, expected result 3. + * 4. Call the CRYPT_EAL_PkeyDupCtx method to dup dh context, expected result 4. + * 5. Call the CRYPT_EAL_PkeyCmp method to compare public key, expected result 5. + * 6. Call the CRYPT_EAL_PkeyGetKeyBits to get keyLen from contexts, expected result 6. + * 7. Call the CRYPT_EAL_PkeyGetPub method to obtain the public key from the contexts, expected result 7. + * 8. Compare public keys, expected result 8. + * 9. Get para id from dupCtx, expected result 9. + * @expect + * 1. Success, and context is not NULL. + * 2-5. CRYPT_SUCCESS + * 6. The key length obtained from both contexts is the same. + * 7. CRYPT_SUCCESS + * 8. The two public keys are the same. + * 9. Para id is CRYPT_DH_RFC7919_8192. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_DUP_CTX_FUNC_TC001(void) +{ + uint8_t *pubKey1 = NULL; + uint8_t *pubKey2 = NULL; + uint32_t keyLen1; + uint32_t keyLen2; + CRYPT_PKEY_ParaId paraId = CRYPT_DH_RFC7919_8192; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyCtx *dupCtx = NULL; + + TestMemInit(); + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ctx, paraId), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(ctx), CRYPT_SUCCESS); + + dupCtx = CRYPT_EAL_PkeyDupCtx(ctx); + ASSERT_TRUE(dupCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx, dupCtx), CRYPT_SUCCESS); + + keyLen1 = CRYPT_EAL_PkeyGetKeyBits(ctx); + keyLen2 = CRYPT_EAL_PkeyGetKeyBits(dupCtx); + ASSERT_EQ(keyLen1, keyLen2); + + pubKey1 = calloc(1u, keyLen1); + pubKey2 = calloc(1u, keyLen2); + ASSERT_TRUE(pubKey1 != NULL && pubKey2 != NULL); + + Set_DH_Pub(&pub, pubKey1, keyLen1); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub), CRYPT_SUCCESS); + Set_DH_Pub(&pub, pubKey2, keyLen2); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(dupCtx, &pub), CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare dup key", pubKey1, keyLen1, pubKey2, keyLen2); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetParaId(dupCtx) == paraId); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_PkeyFreeCtx(dupCtx); + BSL_SAL_Free(pubKey1); + BSL_SAL_Free(pubKey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DH_GET_KEY_BITS_FUNC_TC001 + * @title DH: get key bits. + * @brief + * 1. Create a context of the DH algorithm, expected result 1 + * 2. Get key bits, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. Equal to keyBits. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DH_GET_KEY_BITS_FUNC_TC001(int id, int keyBits, Hex *p, Hex *g, Hex *q) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + + CRYPT_EAL_PkeyPara para; + para.id = id; + para.para.dhPara.p = p->x; + para.para.dhPara.pLen = p->len; + para.para.dhPara.q = q->x; + para.para.dhPara.qLen = q->len; + para.para.dhPara.g = g->x; + para.para.dhPara.gLen = g->len; + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(pkey) == (uint32_t)keyBits); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/dh/test_suite_sdv_eal_dh.data b/testcode/sdv/testcase/crypto/dh/test_suite_sdv_eal_dh.data new file mode 100644 index 00000000..2a2db524 --- /dev/null +++ b/testcode/sdv/testcase/crypto/dh/test_suite_sdv_eal_dh.data @@ -0,0 +1,281 @@ +SDV_CRYPTO_DH_FUNC_TC005 DH exchange bad pubKey +SDV_CRYPTO_DH_FUNC_TC005:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"3abef2371deeb26adfd40c1788b514c5f420eb09fa5e1bc0f9a552b1":"6088cd6a9308c4418d17f3c2764c5ac98d62c5655a3128b6bd2d81a6f2937347ad8d8dc6d01ca6a231bee08c187261ca963470e0cce76c14cf05e9b7b391642ae9d5c5cfe99d49d352d5f8e772815355800550c76c1072098216183e580f973c1aca1244a3a0cdd322ef6a70bb3d9d6067b8405191c7c217e11e47eee85adee1ef73b4aa565233eb323da013b9fa00b0664de3aa289ff70fc6339ef2b94ecd2bdba9017e9503b149559348d1cf461f41e8a12937157b71b14b7e514f907d07e95496874b559ce25eb6c6318b4ba050ffaa521b8b8233ce5c93cf0c2aafd4a59b27268f943feabc81e15daee6ac847036cc962d28b4d1d40f3968c695432881bd" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #1 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"3abef2371deeb26adfd40c1788b514c5f420eb09fa5e1bc0f9a552b1":"6088cd6a9308c4418d17f3c2764c5ac98d62c5655a3128b6bd2d81a6f2937347ad8d8dc6d01ca6a231bee08c187261ca963470e0cce76c14cf05e9b7b391642ae9d5c5cfe99d49d352d5f8e772815355800550c76c1072098216183e580f973c1aca1244a3a0cdd322ef6a70bb3d9d6067b8405191c7c217e11e47eee85adee1ef73b4aa565233eb323da013b9fa00b0664de3aa289ff70fc6339ef2b94ecd2bdba9017e9503b149559348d1cf461f41e8a12937157b71b14b7e514f907d07e95496874b559ce25eb6c6318b4ba050ffaa521b8b8233ce5c93cf0c2aafd4a59b27268f943feabc81e15daee6ac847036cc962d28b4d1d40f3968c695432881bd":"6f01b4a219e081b50f856aebc011e41680692e805a498df408960dba":"e796a148656a2b391a6f81dd7f83ad4a3a72f629a87fad6ec9f4616e0ae0b3de34cfb0640c0c92c1e8d845c517258bebcc9d8ae7fdd77dc72c6edc0ee05c2561294c0ef50ab90ba3b740bac32c9a2df17294f22bf5fea474e7ff48daea6abf48dba6f6c7562a6ddfaaf9c2146d3ae2f1de8b9e68092ad76caa767a2c96975fc8b1a88e8848eb089c438d5f932d633e79da19808fa3a1e411ad260565c4954ad32bb0d94b0b746f5266241928f3f0a4441f318700d9e93c6d0f7d57e883eb8b373f4e7893285967028e9e09c774344c05418d6359236fb092f2e3a454483656817317abf309cd7f8016c501133bb8b40875a0ff3b04580abe4d4e717151105bd2":"b5f47d4a7dabd5e69c2890df50c0cd6f4ab9568fc66779381fae5385b80d7577d5eae00f307ab39b7efc68f885c365e19f0a30c65ecb46b95fd08e0ebeac55d3d012b9f70294a268a254069574fb07a31625077b720cc1b943ab205e7a29e3dbefaa4701a5afbb05e3d90ffe7c5f1b9ca9ad77d14a7d4448d7b7f552ec18aba47dc034a8268b0438cc2ee4f1dad9f08000bf371dffeb8be77a7521e786add03144be775ce1c3425a62226b1aacef10476e6936b831828d9c545ddd9d6c4e76861ba1825deff55d4bd3b0c4a9a938fdef3adbbea48206902b5665b9bed6b7c12eb5fd8c0b6da425654b41235d7852e139073bfb2cb7dce01294eec20f85847cac" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #2 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"13309c3a9d824a4fb0e6c103bcf33504e98a4e52474a62a28e68269e":"4ede61e9c7444400fcacf1d91e4a6d1bdbb68166668a60b2f54593ee9cd9861cae788e0d8c1deb8e109f4f051cc339477acc08b77d5540bbbeb290dbe1f560b6c4d35223a8ffea34d91c5075e11e2439f58ba2ef606347588250ecfc909e27d8b43c4d8765e51ee9a147fdcf829062dfe99b342e0e3a253561ea6107236760b7334b46749aa85e96493f5c1e1e52177840aaedcb64b98987571154095130ceb249de8f2410e6ab511273b02dbf733bdb8134d5a19a28690b38ba8e0802cf9414d28c1db4864a5c65876aa364aa80dae00df7ecd01fa2089f1dcd843a9f6d87dd018dfdb171e7d5b4e67d0e9d8564019367bf726ce21f08aa52bf0bdd619523f7":"2cefac774b820ffff233f843981f00feb396095bc4dc6462398d5251":"97dffa91e261f7d56ce9d3cf014de4fe76f101ab02c63966cf2a4aaeb26f8c5006d4a9c664c472c24c683b26852a8dc89fcc517261ada6f365bc625f2e5d223e6f6e81ce451a97143e6d8c5c6db5ca62af32a6eb178ac027504c03f96f5c5448ee527ad639dd4e54de239ac9e2104672af2b0884ef951cc0b50a5af225457cb7364d90dcbc0e357d46309203a387769ca6dc24903bf108d01d975546405863e0d1ff61460e158254fd4af495badffc167742df5be8c8228fe038fea95342f762769cddb74b109f90d60b2a5e2a17c791ad3ea71fb48f064e1a0ae1f901953294394a7cd54a08de0ae52c9c0805c0d862c830c60d4ac66551e5dbdcbb439de29e":"9731a340d8511a83cfee6497b5bb9cc089678e0be85df16b4afb36bc597a949f8bf49941f3cd514faba6a2cf41928ed87b4aafd4d0febc3774c868e02e0bbf644c2f675573a048583babfb4eb11d41921d392c4f10bd81f096af9510a76eeab652fede4ba4288e876122e265aa7f9415830f8274958f106d24246b488cd0d80ad117bc631d800db5e059db630769a86f99e87d483006358a6faeb44a8e1646d7e9c44a60d8d8a1a36106f01484fa3da93b56e4145c7f156ce848939f79069cbef22bb52df7008adb32880d4da2e803fce901498d8cdcb7fc317ab129ea1a743870b82ab4c5b5acb20dbd4e7f0dbda93ca5faa84aeb556237d25fe56ee21d6b5d" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #3 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"4cf95a7305b4b0d1b2965dd137731cefed71767b0fd5f1f73a0d6f6e":"c8166918575aca44e2192e03aa3da5cc2466e8da2d0ccd515491772347f9e09f3ba11d674873f3bd327f7cdb834ac201b20a3063bfdff79ecc784cf94935faa820238ccd30192d6494184106f1e4ad98ba1edea220743de1e9a4ae9fd79cc1063d6eee36d9519078edcd1ad0a7c2527621db5c89c2054e76a9378e614b6c7ea9330b42f0556f53bd17faf708072083e745b3bee24c1a22cb5df9af0436d52b7dbf0a943353c501498445b5ed372c42fdd236505059384489f6dee70522426f8395df885ec5accd61a357727584aa336b6abf2737263561fb0c76935de661213a307da11a319cc7c5c2a8466c25c4d19bc10ce4d0f7b51c9fdfe58f4a24db28a9":"288a4a953c0d9a34fc2059e8e209af977bb112c476561b76b4a98ec2":"9ac9fb7e09dc14faeb67b708cfc9b9dec878e796f24258247e49e6966ef06804378168ec266edfae99b7a09f4545c71a2ff5a054a2b9fdfb1713b4f8021c52f90d0a68a6a364d15a22644f6ac8434d3da9d0e8a80b3fffd040d09ae8b51a8193fd990372aaaed8fcc322884aacf1e1d9625126dae5f78b970e4bd182208fe89295f85f31566403a989c224b1bb20fceef3fab1e160f88de6e34f01289b65dddc27d79d5e9821e1e7dec731ec5f5f51d685d5c30ea8b55edd618d162d2e67160fdbd379bd280284a8b060be3fdf8609ceb1974ad2a0e55062b4db3abf4f873f523c73f2bf8aca4c812d05a3e0790a7421e01b430b88a63a26379035f6aa9175e5":"68ad9aa3a839e457b9ddf0db8ec81c2395697e1aa7164fe3e707912af0dfefd16fb94d92cfaf932594e3bde79e1104ef7466cd85eac97f4903226fd980393cdceabaf56ed5fbd401a6db09cc227d3b1cefe0b121316d4014fbe2bae71bda7c07b48285d840e6bbbfef8a21220f3a9757191353d4c6801321261981fd1b70d4f4826f178a9bdf7db7dc6477cb29ea52af2080e24913069fe1e2b0eb118b745f8a93a6c039ff4d6d4e0fc53c4f597b4a204865c0ef36087e74231519df1fa7b58c89b236c65c92148635ca00f0e474cb7b37146d7ef0f1398459abfbeee246c3e52a91f3c5b1019b60c7ab087564ef5c7c5219aa2dcd1e31b5c6d36693b6690e25" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #4 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"24509fb497f7d8abaf56f01706d516e66ebfbc8a206754d9fd45443a":"d39379dab9986259bf17ed6b70b049c2765228584cd760d5ca50d09423e1d041f15697a9c392dca3f39b96f3a3c0f6ca14dd77ba74f006ccb89fefc588a8a894fabb421b6cdadc39f4f2dd41709537dbe72c2770624cda2692fa330401d6bb19695a811100a4b8604c6108b307b3d05c414b74ac3d1eda7fd3fe110d3c5d97b27c480a838163c6e2ae564b067c551e0c0ce03685176a7ae97d8b5d4d53b1f1d8b0004a2cf88502f97d42bf7c4991a05d4b54579772a040e30cd7115828eaaeb6905cccbedbfc2c3563ff2099a55ac6eb5df321de20dd047721974c3d0aa2d015853601f07c83ce91c4035303431f38a8b6a40b828faaaabaf81e859eda7d8089":"870e101989d9da4960d25fa194701ade55136dca732958c26433ccc8":"1c64339bd3c6ba960643ce14ac8922a26a9ec2c12b459ccf6556e990b2749b9035be152cefadfdcced660d8cd369111bd62d14756e4bd4391dd6814d7e0dcc66dd3c42b29e3f3d58f23222bca5e35e527f97e7ed84df9f2addd3754176bc2ab5f5c3b41f0fda53b844367f98f8c96b8f2a25b8370c0a4dee9f8ed9b300e55bb328d0e7937b404798c7f9f783a533b12401601cf65c79af9a9f7b1c5169f23bf3a6807e173758640cb7db1327a7118d4634e5c7065aa9e24ee018566a880106337e188bfca782f2c5af12293c145b6d7253e55f415f7a613ab22ce6387b4192ae1204eb03632ab7a908d3d27a6232ac1a519ac15d4b03bd1520be94c429bbbf2b":"66d69ba1f73ebb23790a7d575d4ba1765f67421d8f92c73fe57000c491863d1f752121c705b3be816ed9de9dbb30e4a942890edbc2ad095c248df8fc5230f2b382831b8e2d6aa6784fa7a7a2a2fd960819856531158fa1c680066b6d151d8bdda74f5ea0c1b39748b25256a239f664e1c5c9b098f389e1365309dc995d7d761bb1129794a916d99b3ec266375d834f6ccefd4e58cf46ce2c7a481506fa3de6f67eed3e7cc8b2df88813d39fe744f9aadad18f88baf959f7b0428f4560453d048fd450cb9b41b7d2328227aa2fc371de1c81c0663d6b542de10f4c1bf5f99369f73dfb7de53fbc153cb7d24358ff392dd954dca5eb0527aeb36998eed7b97fb82" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #5 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"991b062bd3d604203eeba196d94642150c07e9ea17ebe6b571f5bc9e":"93e4cb6d5f2fa98600ca6e99d2e1882f8fcbe55adc15bdc71df925427f1b832b80e545abd9022b65fe691846c1cc0400bd13e54aacde58f1067c73d67fb252b4d789acd65d899ffeb6fb32e9ec6e0de882f108345fd2c653c1d212e84d78937360a2da6f3bff24ffd5f30915dfaae84ba91b17e9dafd9bbe39a56cc53c932ad72fb7dd45538bc9e4faf13b21843e04d5dc86681db97d6b9cd83c6d39c8c67cf9385ae05c55f3669f7fee7f18736b7fb6a1d8ff55210485f777d7ef5aca6c5af3e2a2f2975e5c9f9ecad22f88181bbf77f16e8c45bfe7934fc81a554295c6fbd18d2e5b7cf3370b746a17a1010c3f1466594649bce01a13f805a36d24dd7bc7c6":"77227c7376005860f62b3d1269e339f0f62f3a57efedb5636835d613":"5cdf1e3247c60fc224eacfdc5a6753224d029eb0680a4cf855e4da86b0d92efd3fe59292871cd16fee4afa89d525b40218d4971241297a9e1f2490b58fa0d6c746e2e324a0855dc7fffdc30dc1704e946f143ffa208ead22496482faeef5649546d7e82412f3e7e590a60832c2ba44f359aa2ffcdf6e9201037353346052ffe5f8532c9b3b0bebd0bf03247f07c3cff5167aeb7e8d842cb810f15f62a3460aeafa63c208e4189acfdb3ea3f9476a8df1dbe9cc2265f41c78c6a7fe02708313fe151f0e38a70cead01cfc1df1c54975f97ab21e2f0b09582034e9799e04f42aea04c2f496ddc2b1ff4bae0c4a84e1468c15e4b0a2fe8f7d7bbb553a00eafddb19":"66257222d2cc3a25f7f5a6174fb11362875e74aba8d342a782dd981f677bc9d4f98387c835c3de999f80b077866098c7939d58f1253a76f9f92dae298b42ff60c7e5e03bc685458d5637b17f6f8f80710ea3887061d621fe18ad7335f31aa4d87eee568d90c3c1c4924136152ac166e13cb4c56ee19d2b0f4acd6930cfcdaca23be49781e88d28d6e172f656b08fb4f32303b60ff8bd8b7b61d4e22e427e1fb9498123285535effd9c74af7af7fc6fb431013363be8b85627a51edf45470fd369ea7300156dac3465ede79f91c0f0c2c3563f1e151b20567c97aac3033e55068f91afaa0f39f84436c179c5c2f27588b982c5c9dfeb3675bdd600c46a736a997" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #6 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"90304ebe3fe2cfc052fa7a8e8907c9d53b9c95fee2a7934ccabd15bd":"d9bda4c8d4d7d678ed57d5fa534ebe302a1537ca1006b6b271a9ed76feff75baf70b162724ac53a7282b59c7ba4e03efb0b8c2112f8e5b7af6f9ddb40d67b065db9576c6fad05db4dd4ebd66fb9b61ac26c9118ea919faf4ab1e956759d149ea809fed69200bff850f3fc94498956ba5e84cd091925b0e8b0495bfbf0fbfec14b52512809a675bd7982a19f3a9bd9791fb23934adbd2625789a53f3baca53dc71837c7f949d7dd37f1ee61fa2a6910df7674db49f48e3725f7a6828270d89b75716f6ad1831008e405c547ee218c38816f253bf773ad046389516bdae7e440026a02bf42c56c22323ab6fdeeee8cd8ba9cd01e096aab87bd264c6499e5640bad":"48561d8c5f969cb0b70c037d119bbdd339e900bc075d82e54a3a2187":"c65d07a6ede99c32713b8b20a2f29b52c81a3c68c0230a190836b7a129c35f79c0ecf70787846bd36f7ea910498b94bbe2a1e47fadca535ab4ec26e41de4f43dde4430598638054b08cf547009c8fb780695133a1f424c885cce914efcc3bb81d4cc97b2ab44f1bf1824639f264d6647cb3a5aeedf6f743ea768c1a96a01376f64c251fd9669c9a64dd330020bd15039f9bb68666b646e1fd1f1d24f7b214043140968b66fe2ccec9c653584dc8adbaabdf232a86dcf7fc9f675b35fe0689768a88614af3ef8e0b18ee5e50c8575aa62f1af5bd17f34d133f13bf4e7dc7eaed212ac6760946a0163caddabad68d3dd9561c0f66ccd75068d50bc93a642c6dd53":"b288765f0c306ad3f439f0eff63667795c53929bcb885ec61522d6caa8f43fb86f135dfe6efd0357a738802af8b87bce442c8673d4dab0dcf28c005aee821d17b281fe7d7376c7b0a7c634d53f06b67acc9795baeee72cf95fad97ff4dc6b6454f0af157fc9ad5b5aa8e21cda68c90fa0839c3dcc1dd51550b7c926f455ae663f97fff135376dedf0fd22c2d4366c474c03e1a559f3858c35b3f01e7f53b7456c7efeef2abc039cf97a4fbed6e144de09f9d1426bf76cf1b17f3195acde1d40f59be6e126a87c59a414afb392b1f8af6d78b0dd8c598bad5a55a5dcf4660f0a852a43a1a4d4a8f11d91c82ed47b658d03917e88b8dc3cdda938a1f5075634d8e" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #7 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"45e344e143fd629e6dbc9ea3856227e9bc85a05bf204cc076bca0d14":"1e7eeeb1f82425b04fec5268e50f123bb9bcb00c4dd5d154a869f4f0e9cbfc7c3cc2220764a7da885148f0b621a72aff827dca426572d500e22e36cb76eb1db50adfdec678271c4a811b25dbe653801a1ce5f3744a75a3b8a5c3b252f2c70275d3995fad65daca10f6056dea8122ecca1b7ad5814b623e4ab1fbf7254b3b25b8c4a47639d7d3887cc627b4f89291dfdf8d8fb60630b370ebd944d528e44f6682d62f1438a86f5ea339ed511258d230f7b5eeab8263ee6522c98a6bd1261321d05e77dabce970ca062ea199bd3383e89cc61de4057a737207933bf32ea418fab424ba7b608b5d3991833ee5742e9417b11f5f41c9aa420563e9f654ef6b751bf5":"21b48fa77080e8fe23887a8b5539c821c8cfb0023993a145f9380e09":"502c9154b03197a8d992d7c63f3e3e140b00a8bf49d8d3c4e79d0f2a3163bc0f3b73fe6e72b92bfa9abc1d4f9f81190e89383383b709c1352f328c524bd036a54a685fc6e231d9addcc20069e5a972d0372f362285e41a099345ccf7e3460afe2482b0bc41558f7e887b58ceb3ddb9a77d42aaaedac7565d8f4201f338fe87d27b9438058fd342740a30ce776f40266b019acf3ced9b414b842a0322821d171cbfdba711410ce7c3f3a5225344088f9c581033cb382aedbcd964841dece56376495ff1d1525aaf6f46c045ed7719f723d4bff6a3abb030fa7f625e4eb8199692c9a83a9278a294dfdbb1ce3ddc9f33064b5b061704d9fe7478bfe755ddaa1f4d":"231073548f845acfffe37aaf04af10ecf4dede34508521ddf8800dbdb637cfaff9ac47870050eb0be7a4cb44173528dc37ca1d696ce227067fc628bb0d8634df38ef8a2aa913d7d72260aac7aa2f8aec0814fba0477e2812d689f785e2ca4e84db29612f95a668c25c9cfb932fc307f63e0fa6ecc7d0778d486cf29c322d12c5afac31b5779d86ed9f696c1b6235a09f6fe29207defd4be2bdfafe9f9f8d5698f8193ca852d49e9dfda293fd5ff872c23e71874bb0b897019ce7e1d6a5e208dccb1b541158c70a5be029283fa26d5a5d311d9f82cf4714782ddeb4bba48f716bc8ca812557e78cb2244e5a1fd98f67e1bbade66efc8c2119db3b090a6d5717f4" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #8 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"4469eca2306b2a9f031f88051a317398b9059e65aa078cbbe116b945":"9092b36fd2aedaa947194c14913a28e517aef7be1144668843539c3ebd84449f71088c4d732a61ee49e861f27e9109a5189e9ae006181dbb2d7cd9be730c85e4fb14d03b53a059901fae727bf028a417c8b8185a9f239b4c58fc441014f7d7dacb79adf6870f5f59e22d0a0720829ea90064c6127e073af39b00ce2b6542be74f99ccbe3099c9f277b9b06528b7d74b0f419b30be0c022044daeca0dec0ace309c7fe038ef6f14e7358d5deb5b99e761bdcfddd45eece8933178f0094da3d3bae81b17c65bdcf2d7f735869990d0e403ee241d2789112828d54e12919eba8f0b38ea0e0533d3db38996a6895dd8401779654df0dbd21a37566cdb4e46eb40bbd":"bf712a2ffe36c07b028a507c2d13fe7c97a80b89b51d6cea33f138cc":"d732c3fca17be8aaa6886119696a244ab7f5609cc8fc5f05f385d0e153a2962aa6fb141aae8ba430506a673654fffb5d5124605e28703b88499aef5f3e38a326e9659e925f2b8747c7dceae7b236cd284aca8f349d61788a906ddc07f6c4232f6349352fd3b1b2776813a5e3b13fb719694c76d1a6e775e10d2296b5c36560e6591e381cc82143f64f0c737295c8420a83045452c610482f77f38fb85e1cd86ec886aa6ea292626ed9b0f14921ede109c8a432d07c6e1b4cd86fe4dd46f765cddf1ab0e6df7ea073828342ae90a2d224a209cc1bd6dc3686a8576f6547cc27dceb8e2edfff25f4ddea180ffc0f6085d585996c52b5dd85099623cbb23d45928b":"6727953c8255043c3ee24a62f47438f3a5d5f488722f4da9099e8ce64ee122db9ed710cc0d7bbb033949d9978d3781e29c74f5ca954c89745eca35948c0f674243ba60873caee24c85b48d6a800bbb4378082b719c43b81d3973d3ebd84a0509c0d49976e53e8e56c1ae1aff2c1c051c265f1bf0aeb21f8d3a0ef1eb467bea10c0d2bc9abbfc3c4a14a45d82aa1e71cc85c1ec8623ac78b8dfc8dd4f81cbaaa3ab9b766a50e8993855473449deb819fe5e5f6868b2cd8d77baa4a43a73a6a04d249e721532e8e4e7152729e6e4f5e2dce31ec97d2152d024719b64b3c8607243b837642aa28053b5cbfc3247396adc1ac1d4219f5a58a86b7295f3c99900b4a8" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #9 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"70363e2718c887be1ef3c1bfc1acd4f4c78ab32ea2c51b51e7746b1a":"0cc2dcf4a923ba4ce99436ea6a3c63411b1e2d391a5a82dadba13ef39e7e1f1e3cd0a81dd84576f5f0f5951cde7cebb907f6ace7f65db051f71c3d6a97bd4465f25f56e809f3185d87ff9c9b7132f09d2f7ea49dc969a3c516a717034fae082550a0ece45f4742dbffe5bf128b28cc3b690cde62da00c73293ad1b61bb1a979728b9cb4751ad69b2422601f2c0f66e28aeefefc0aebc5a22e21ecd6289e369fc8e736eff730cc04d79c846c4e93b7ae8775f074b97e15fd179d78240b97b2798586e9ade0dd23fdb92a5fbbbc7ed7d9f2d9360b52f304d44fdbb08e67c353f2d4944cbb8ab44d0cc2b34e93f39a9f3854f1fbaa1b6356278be9a6e7b5a488675":"1abb6ed18ddc18a0aa6d49e19d0c76076ea22d89173bb57c18f54b6c":"9a0551d93f376d3606e174c9018809d75636a84b0bfe3a08461aa63706aaa79282f39604e26475adace87d4f0ed94e31c2d033aacb957c6d48560b726aa2906a3ed5c65ed4545a449542b55a6c9805aa896b17ac788dbb42c5aa18c7f1dd653678ba84982e96c3044031ec05d4231dd761fb14e9a1be6645c51823cd6c97b4609020e00f07b8ef8eec48b0f1fa609db6374faa59ce3d94c24318bc12e015636c1318586265a66bd6329653d4e4bc2fa971ca0fb057e7064bff5ab05419c3abd11ed2ee2a98918b653bd803c27e446cedaa27341ae6e13f2096eafcc81fe44895ab0caad47c92cf6a279bf2ffcb02932eeb6212dbdce3b0e0990b8ef5a5388506":"e4406cac2d4a3780e37a14603601a502871e490526ae27c697a51e53374f43e27729d2e67e65ade3bded5c811570e84269e266c3be7312f02384839a6b95ee9ca7097baf67cd9fc1a49654166c1e1f5caae1ac69c55e3542ae4e9a3096132ef775a24cf2a71825355c83cd083b2ed145bbbcab7a167b89c472f8ff5696232afe354e7d5b8becfb275182efdc97623f82d273c67f58b46abae854f31f92db248ff3ed7e4311e5a6159f7b796b060b8a0fdf357563b2ac9c50364f7b500f181086a27dd1195aea554fb6b9944a0fd7b68769c879e5337b1f36ffb1b19e09aa6498b83dc04c6e485b421004ac5b9c4bda16282aba58aac6d8656eb6d801177e4f8c" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #10 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"5bd7c169c1cc43821db7de4e3c608ae2742d7e842cf5376549bf59c5":"d8e8c3d5da328080f421f721b5809a893d21875cc3bffbf5a91bc41b234271b1b617a413dd9a803d70203eea5108a01f0ba50e63107a138815cbe28cb3db9b06b5c7c51833384e2720d5d4ea7decf7d2f67b6fc37f7ca6af2673274b5e7bf8a2c9accac155e6e8e52e07efa32edb85c75a2eb01065c426ee89bc7cbcbeeacdcdfb15e0caa060460a5536c73f435f0fa0d457d40d212385302b5c87523798d2c920e1bf43fcf77ee3e88639a0d2bbd4b33cab791924ab2c350fe4414cd36d404580f43c640dcd7c84740b0c0ecd06e355396328804a6e57abeae9105723aa2170deadce4426a6a9aa520171521456dc9b4ad101e67e2863c1a7c975b02754861c":"04d7c47400a38071b46b9c70d641051dccfbb42a26976c81bbb3815f":"5c513fa40880ac7895c79d7ddfdee894252bb8d8afa4e53635713554ead12e85caa0a5e15ee671f0055404b0d7b803234cdab70d7c6d7b2b213af413a331b0e4147c0b2ce1d6c21a41cf9276ca497d6caef097c1d15bc2ed0e705b6033869a1bef40ce72d090deed3d116f345570e96d17c41812dbe1ce8f0a88d7609c999739b40bb5c07ce02d5fa5464ff385bb4225300d618949fe22882d78256ae72324ff37db88c16f575925fbb7e4a45918b664fd9186bc52f08f30f9e8ddac7754510f761682fd0141824ed8f3e68f0104faa1084e33e5fedcf3021e9a9713253b81560b3631554f8a7e7a2477aa025a2c1217ad7137af6899a50d5f7d1fc3694da099":"c3287d13a4ea1cc293db801a69c94bae7bc70dfda3c6f8548306278f8581e2e487bce9b46fb42a65b59191f3e71aa2383968e3f2b482a05ac918d62bad2fdc6438e7e475cd676477bde6590edd1124e81c91044dd33da07219341d1387b501c8220677e324408d1dfb289ac0bc2c6f002e8e80c054939de27ef78e607f115982d058f847373cab5c0107c06e663914bc94372a33f12c105d90248d6eee60535e0156fa0d4464941645fd9d440bb2c65a0f343c75ff31e1d03f232ff4ff535446b2e8632e4e1ae873653e1f45d6fd2140260db0e1751202ecde4aae4eaf6c461e350a36dd5dfcdf46a94120066603bae5f2e36b5294c28f7640f967eac5cee35c" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #11 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"088f8a0be8379c396c848a245f464f11581718497b69e1adb36e141d":"ab194a6a7eb48212fb4e08a0f0d370f3e10ca65939c0536166c1b692409ce6bb75001c4439097a16389b65ec0061fe1b1c69b8e55e15dab126c1679b4aea6cab378f75237cfe899999f7a9852877950507ae82925a02f7fdd830b2eb514711bf24c56d55a11dcec25cfbef0ac7a0722546fbd401ad803654562f99033c128afcc47b0262cc427af120f6be2895a4dd70f2e7f9cc147ec8ccb73a41f12ca039e98de8153272d1f2535cfb9c6252ffe7b77c4d24a9713b1d1f11411acd0ab73e73c2568d3bb56ad431805470c3155d97224feaea592f23567f6654f1de6b8cba104e00551533c89f77e31b4754f8206899e164faf4355b9807580fd3563ef0f278":"37b3ab1ef7364008cc479d5f5e4f6c3f3bdb6a2603c320a718b536bf":"72118df889db250dcc1f1c2a30e804b3f4c1664419aa9fefc82b01159140b9e510825c0674cef2fd59057aa3991a474db51dfdf864eb57fdfea5abec8673de75f7f58131ec00752e11a2402574b8dfea62a86218b7a1de729f4a129d3f7ce5990676f39416f48e2c8d1e4292335242ca39ca874f528928861dcc37e522eeec5ad929f76267f6238a528032cd5fc6d72017ab9580180c4b1d52d764776ee8ac9065c11c35d3e0aaac730fd0a90503cdd08e41c806432d60a940aa3decca4594f246e7f2228791ddaaa1456bffb62bd4664ca7be458680fcc5f54289001ae2e2e00f06c83e2c32082d0873a4254652b265b79d0dcf602bea26a168389017e31a01":"34f0fe6843209eafbf58a1b89dc57213daaf1a2718ba10934a0799105c8f8f19df9283ad38adeba7646defa6f217bd2c1e220cfe498b995519c0098399b672a98fbdda0516f4c2cd260610b2b04294d9b6c79929171d4ef66a1b0d1c40e5863402808d81b882df0ca76457469028c0c182f07849914b90229b90d6210f5591ac8524e9aab073cd104989d933dbcd1b2bb1e87a3e323e76dc008952668bdef286b70d0cf39866f070727a852068bd35c3dcd70ea84248961aedf0ece434deae9669a846d6eaba399d508108eb175d5b9a4a6d97f0824227cb6316be129128d1343358a8c1359f4a01f7f2faa22122107dfdff91674699635539878a7c4626cc1c" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #12 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"6ab353245b6619606694bb36631f6b71a945f523c6548e32f0e3b943":"6f86d0d29a539f35351d06d3cb41d3d4eb786804c77194b44007916ae106583fbae84f4a48a318e4013eeb4c6e8fb79fe96f466305ee5a7fe07137e56861dfeb6519cb1c174ca3193bc0230b97b76cb0fbd8744e0b2c8aa945e709ae6825236bd690e46d3a5cc4a823ae0047c6f8052c2b9362f82746e4515fc28f6dd2d8d35e53c08fdcb57a56f7b68d7edfda1f88c8e52b4ba3dbc7b07028b2ec41f9bcbeab6de0fb31af4950b6a8136fd21445834d544b9a91f7fb006d7bcd6d66789a8958fb24562a16fa91ce6288521d5e7ff5b554685354ac505cdfa1956eb3e1c00c8900df8d2185402db49bc4ffc77ec50ef42ab6b16bdfdef63587e12e876936be9e":"27116f19cabd2165e517906134a3810f036cd03fd8a721f198d41576":"d5a25b7ecb718aaa1b31c69790de4ac35d44ac48a13e6dc7a50fc429efcc5e7fb8d2da0af244304ee51875a91e3ae16e478b21d062aca19f1d5f9f6ad1121e6f91a7cfa1662f064d80ce10a690ec66cdcad48eaed4970cba325c393bd291d5a1fdd0638006880bd91de58a29017c14cd7e2dc6b2d13bbf2265f5cc3c6f7843888f326e884b3ed0b7a7dfb60c0da479b6bb2a8ec9bd56c6b13ee38b26144dd5a7529fdfe2c4dd9234526473db9cfee937631bae812d1de1266f99150048d1beb58af4b09f769be752361c4c2151c927190225eaa72a3a69b12f0ad1e81159cc8fcccb53d56b980c8a49451e99fb5903ab4ccc87c581e6efa7e25d49343f854e79":"551d8ea234c658e54e2b3d55a4102de487aa86a8ac7f754c460cfe4b16112bd88d13362f45775ed290647b94c615d88c0146ab1d92783501ac69b57cc396c734a2158dbbc6c6ca95731d9dfd4cd55a67df3ad29bd603a323cb119f30950737e4bf2d2e8151fa0dfe96dad9884ca1c254b60cff54d79ffa27fa7a0f89c12ad1d43b7130730426798c51e452eb06b37d0f694d2e428774680051b14f8678b5f36d7ed539d16b557ed19b927ed967e6653e4bdfd6d2bf5469f8f68344c8a7c30232a387840ca01f4937516ae4113492faf9c5b15b00139ca736e2ae52d5ce5b88f19feef4fdc7e83ac8c7e780ca2aaeeb0f99c8efe988349c90fe92e5be7661fba8" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #13 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"55becdf81be67fecf78e7f51279e64d04ea548c7f61be2adbfb0b260":"b82bc2627c3282e4b467a21ce1be624d82bef26fdd319aa1d4dc7e2995e4c5406d8ab07fbd2b418b41f804033ed40658754643364fec4abb1d71d6ca1e82de0e0e90db751a539d0fad9e987a0d42e635d19d81e0787c933e4e4792b22bdd6645e74ab809217005e17d58e29a0d601492cfb1d7e61359a907ee692f126d4feaf396dd1c8daaf01f31654d42fdc3c6cc23ba2cdca4ab9140ef1c0d797f88b742699a651980eec97d79984367d52b33e4ec144ed16039222d415221128f443ec86d806268ca96785820fc18eb2ebdd192a5fdd0db62fb4de5e719f4f3960cb035aec0c08fc670a131164ce8a37409c4f41f58d74ed0e72c4b99dd6c7a0d7ed29746":"815299835ad8ffff127e9c47e054787aeda4891011927030cb06f719":"7f1371aa6422dfb85e42ef5968be20cff31134324152e47cf975818e1075bc5539bc8a0d431335d31ed1d1ac7d1663bedd079e46f357a77b1ddf7973508d15914ec5d0379577a205c5d1e42728c0ca6aed68dbe24505d9021451c8f58541d013f0de8db8f676fc1fa246d92f149d956145e4332ece5aac74b4e58c268986db3012cae450edd8f9ccf6810a1b7a7092cd3325aef111701d1e17998532deac77d6736e27726116fd486ebb125b5c891cfa7a945466ea8568f5d82c5053c2f51b4759edb80150a7e1edd384ed5ec206aea9997d925fd6c0b714f59c848fd079ecacbaf44e792d4b8c2e76f24ce3fabfd20c5ace9ad9fb4943217fddb68051f21258":"1b432f63044589f5924fe535f2f8214bbc0b1e404d5bd882ed3da0a931cded3b9e73ec977d06024597253d6aa9133c9b6f3b2becfeed2a8c943c98f8e2460745a3c04f01b8351d9b5917ba0a8388365be3229b9ac592c0f5a6ce7459e088d5ed133ef56ec5ada4c53f094029d3c97985943f6c7af824b2191cad3f35841bd7960cfb280ec710392d9ee2181aa3559280a1ae38495d8716c2dfc84d5233606a31dee5e986382915bea9c55e52f4c07f38c9d44b011b50342a4772090421fa5801d9ffe4e146aaa42e9b7af2bf88b9f34e3066950b28d505afead7b0b9d7f8d0c0319375e541460a2d17c23d18670f33c89aa71cdb42a0408c2ce77b6b7510fc81" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #14 +SDV_CRYPTO_DH_FUNC_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"298290645ed01ee2500f0182b2adbc2bb949f4598cceddc4aa5f2e8b":"8237d24972072b9f7288e7f284d0d4b69054457fcb74ea4cdcb294b80fef6742fd0d288562d82718f34995d1980530aad9cd9d8ab2577e0ee67f1bd50d1a07cbb80f4b353bf893b5cd2bd6df70e589013d819680111ea71fdde7a9802df7c61d23aa303cd4b0256be42d99b63f063a4abeb9034b6f2f8f558a5d53c6aad27c39f608943c238e7484bae69fd3d31273a9cfb3492c4befb7906a2692e3b35bb549c6e51e8aed5c4f29e4e6b1a0decbe5aba360c6c60acc82c2a3bb1637af8b8efd37525362e371e49873d9e661ea1a98464a5e4bd20256b41427812f61618eac0a55594f79f314f88dc1fc80a87f91eef9d03816666390d06ceb5e02282338ddf8":"348e08853d7b9f86f8027c789977eea8cbcfad28fd7fb8ce9e3f1a69":"20a5ea5edffc9a5bddaa6dde9053d2032fc9c7e44c6f1d4e9da52c084cf6b8562cc513f73538407a095ff5b3b0df40fc2ba89536a73b48c3b212aa90ac1bba9ebb5da33d5d35637ba744091ba97d7204f82422ef723b20183d8dd02bf5294a2797a811a187e3a5cad0ddeecc3af92f139925a355f737226242cffc74bf4bad64009963e565955a904d16c4338d8efa80c6330474fbed6d40b40e42c4344aa36c6ae4fa1bc3186fa6b1b40cd8b9a8eff0e918c6350b92258f28964121cfeafaea48d89e2e1fc3dd5182422d8663bf0b1cc8d97b920bb65166b94208a048e11e3467061aa98429c9caa34a9f131429c17ce0bfa963d5a86f79f90fdd23301a56ef":"7a1244a1e92eb080ede707ecc7e081c7edea740a8c43fc6968c1cf2ebb6a3bfeb98b7c8b408a2d2de6268e83383fec1cc2032d76d054d37440ce39327beb9d5974875366b974bf01f5a2ec15965e15d3efec98986f7aee4f528c4d7fe23b9ea1d5f4b76a3f2ef5ecf2d4f30d4c82db39c0b09b5041ccce97c09fcb51038736000055f75a21db0a9abfe4ea7d2dbc066653dcf58d81d8eb2eb49fb5dfd3146765bb7878a781db58b06812ea8275a692826cc2dcef06a570d977e9e932725f7505c25d14b45e4e3e33faa6217bd61a0b8e9e60c5d00f04c15813754afb1a33d356530433bdcc6e40edc7da978ecdd14a4dac9ba5caf55bf6ff4a9dd1a2bdabeac2" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #15 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"d72a8b812b227a7e0ec1be32fedcdaf4da4ee2e36e73402872f94620b6d4b1dc":"b40d9a6860c30f0c2ad3304f4b548126b9ba583ceb7745e110c6faceb9c69155213bea8a86cd5b9fc19f64cc0d66fe332128bc7ffeafd3188c5273b4e7ba505e981eac7db5f12ad95047fb6f1e34aa9dff3120b8550fc571b9349f2339cd96de9c119d0e6be10f690a77c75aedc52a9590c79294f80381aafc343cec6b624d037a6a7c92f72c3884337ef3fdae20b0c660765360f37750960dbc40e499fce579da3b6598fe286868c687bbc8127c1d0b42e9b46cd91b23ba34593b866045b62548537cc7f824b8f671b54298de8c6e617e1bf9ab524f03d1de30b485a73b97da975fbe8ad62e199129b4666d037343be134782208021f23ebc66a607387177e4":"641f5aa7c7394af1b21a975dfb692094078eee35cafce0f5605863431a6da681":"43888d2ef03e8b1e709fe5803b7f258b785515547151e5a91805344e6f0fbd7cdfe5c21b77404fc70989e635c7215ce5e5116884efe29818bbc0ee95d1858b3c9734d4595dee0ac275b1cee1ad119595666a420ac170b2bdf973671d6772eaaafc8a310422852eb16d1fe2f278dc70f0baddeb5cba5ad7b8c2d7a60fb485bc9da9d35d954d1ce469f211136fa2001d7864a57effb00857891d810b8f36d46847414575d0538eedc46dc991eda739f42a9b7f362717795e586ab95105946429f10f00456771387d65a8923da9969559742bf265b683e001fe65c3ee0598979565b49e8393a761be8a8a5a254d3b391257a7dcf4204d58152aced1ee0be943e211":"8ad927defbd51c3f0010486493a6016c91f7b462552a1688e4f6b49747da924cb8eacace8efa194cd563397e0bb5e38b7248992b7fb51579e12ea85061e6688b302e9a5e2e0d61e55ac08b30f7a63276d79e65249a473f3f852b7caadb3ff44d5561b27a24d43f850e2065c39bb8d187fcb6e8c8c37a9f5e8b00fa5e8f33732857d49b591884fa50bf55e24dd0d63a9b586da470dc51509b884956a373d9bb0e0fec33602793d514aba435e8b5bcffc93f32f92b22ed995c54483abf1bf202e97b51eb985c19efb41ad371784494b788f318144e793faab766c9bfadcafcb858a0a4c279539e0d5064fe8e78b70d8e866132d62c35fd779f725a1123596db8c4" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #16 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"415952df4fa2a1909150431ba20fa7a09f724de7a043439c215323195fe5527c":"9176a83c753a6c4783d0b693c1d479ac212bafc783a819f804cddb0d72f00ea343bd187081adbdc07b5bd2e10642a3a307a074a863fc4a90e0084b8dc8f02e1e9e9e3886913694d04e4dc189c3a12cf43e618a78937b4da77ea46b323b3e5cc0674950deffcd81782d55230fe7c3e791133da2fae5419cc1b72f61faa7660749694306d4df711dbe2eec2baf45cb2b880f3d5e0592b952b139a621b816c967dd7a2ed510d2719dbd436b275780c96f655786fa91aedebc315db711272e3842f1a5b92ea344021d30c8f6b75c419ce93a23f88e4340aeae0bf36ea4355f0da16d04b1f52881ae1936038a8605d7aad1b67da8329f08825210939a159f66388a1d":"4b0ad36a4fb1844a0d9df59daea1380b8393949102b1f5640d1f2d7b58d28761":"7158105d26ad6edf485444d10bf64fd87983e1b4562c405577a71b3f8ba4897b0d4d06d54c46e5b080efa427b5895fdb47c043e197db47a212ab3651f849dc556ffbbe2637b0d66bbbe021d38428483ce5192de450dd2fbb70bb5551d4989706c2dba6085ff24fdd10aa93c3c07a60d36532b1e73a583622f994adbc111ce47045cc9d00577436427baf7144e50c98918f5920febce91c416f20d354197f2ba618ac16371eb9f455106dd52b5811393ef2a2beb0d2ab9d7be38d9fe47ad9646e2176f257b174db52a8c93a6bb6c31851b0acd83c74ced94c627c09d103889da8ade2679b541ef50b6c3f440ac841169d20f9962117e03d21f835433c7aa38c4e":"815640ff465222b9f5b3773fffd8aa57aca2e71764581f91c35c7719e682781d03c5070887f22f592ee9fafcd3d335e31fd8fce50e8e32d6b85904e264ce7d19d772f74f9abb1ab019441914724994335ed54a9d8bc8273dfd0a263b494c278669d02b9e36fe497698734a685523462f1abefc71b7f8b1dc787d46c59d9b160aff174ab2271ac49604fc98fd5215a3d06d13985f7f11c385230bd3f8bc273d54c17ff7bf2d38aa625d39ba2ab24cf26dbbde2dd09fb3efdf867a99923205179427c815eb6f211e6e3e616607b6bb71ab8519706d2444a88ecdd9d5d89169c797197f611f126c10860089963ddc652e3e36e70c8425634096c1860979fd12c965" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #17 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"bb3d973fb0a15ed76a46c0961fd605247cacadcd2c965e59be5846fed243932c":"455340e95e82104dce0009c2b1ec743aacdb11583903e66e80a8c074a683d56b887b6bcd4ae1f09e93315c2e7f63e7e3e645669839a46ac894de22cdf145300eab38846394fa8e5c4d4b3a8d9c27db13ff7876160b804c2c5f7c931c43c02f0a72b78324e479fd0a5fa9c4e044923651ee2ad548a483b73c98e4e806ae979c1fe08d4362ebebbe38ab6e94e2aac5dceef8a6d013c71f91769cc57f7292dc3ebd0be9b289ee742db428896ba09bd033727566eabd8e6ec750f9fc80c88a2d79dc3ce80ede7cc527e630b8e7a09386c1c7fcd21382586853b30e4998880b30798bb4f4ca7a1962820bf7b3af73dc0b74992d09a9a57217d24230e8d10b3099ada3":"05404b6f91a4b747746884d23394f3c7788e3e8bdc4d10fb3354b4c615722c71":"5fe94a8be8e81fb8a7a3f383a908f3f8b4fcc52712410314002c5f5a92c8201001d7ca1f67599762c3c86e9925b5929c1425696511cf43a62fb3b425ff2ae83fdb6b34ccca97dc0fcc392a5e1aee8f7fd26b1510841e65fa3a989c8f7aa206d9249f58c51ca9252ccb9443672ee0e43e39af64c7c73dd577a582be5a802eca0ed9d9a28371a316b26f7299c83fc9edcbdb3c508d1afd61d24029d7b9b84c96549f766fa50cdc4255ee57e9ece17d1f14d04d82f877202cbd7ff69843ae19f6e9c9cc441681d25b31a335fe1557e7fa84bbbc170d5c5d67b53b6105db750527ee627c0b6b192bba4aa9eba2b3b032a100b39d6483ec5fddc2227db94cd9623db3":"5e2d84443eadc5fd3bbfc08c3bd20cdcd3cf82d200a9def1e5f7d377b911a8733a914e5641ac46ce73802bd65d30a07aaba4b310dcba0c320fe397bf9f50edeba5610de56a41237d8bab67b13171c2f4e29bba3367d90a5a43d5eda15aed15721ebd425a4d29ea219f945720324040c9906c7daf97e8fcec5a623f34946052aff09da35b23a6112dd89e52169bf06f3b809b3301c47ca9ee1c83e9cba9e89fe7cb70a954d5b06dc8df8c49730ac33a2e32c9ddd638e384e4b0da3f170f0f0082fea324b8058edbcd99764e6065538d6ad544d1a568d0cd84a927e00bb63d50e8faafa1b551cac0a2fc63bb3d642af095db2c72a3a1c271a979c397b04000ab7a" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #18 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"38beeda09596a9c25e84b604deb1b1df5738580840d80c1ebd7e91c4c2a648f8":"38a88ae5aafb639eae3bcb0119ea583fe92752084e136625e662866596604c1ca843d9e516754fe11e8c21dc49ba9f3df1bc653a7508024a71293d4c676136f5e85037aa7bcd46a9e8c0e7d27ca953fe9b2bda876a9828055130dde5cefd1c8732dab7cdf82ca8cf9e570977d4882ae91704e3fdb2153b2db03d94ab2d835cf94ce02c42adc843a585b33d8fc19eff18021522f89491a5bea1f0ceeb5dd7ed50ffadbcadb23da47c309b132f8770170f8ce317d33c6c263f3edb1114553f5775ce59d2e64c306d73acc30ee205d580cae11afd127de5ce3c2d22615a353bf7f110dac8a80e8c880157ddbeac9aa041d846880fa4cc9dc699221e35d71cacfaf3":"720e78c8fe0ad1f9cd33f6aafae0233e56e19a75f96e2e86faaf5ca1314d8ce5":"3520cf5056cacf5459063ec16c917b1c2f77afd6401ddbb31e977701162ee9a7707f15173c733272a9e375b21c433829c21dbddbe9e97ef0849850a41d3de645b230b5161fb81df0bc024255fc03a2cbc3b250e7a66312a8724ac4167d44750fb911b6e9ca8bccbb41e3af99b34c02ac06d639af950eb363ed60bc21e25515e7c65585c47063c173d91ac4db834b5d278370881b5b49d1f99e91d77284bb4e04bbfe3fab2c6af8ea9432cd3b1f4df76f6293f5fe3f38142f82884846c7358482c0f86776fed29af861bf2a7498e802275c72dcafe832dffe7b26be567baabfbe87e603384ddfc2c5ce31af47b691dd97b082ec2d9e7deae4a2234c67467f7575":"b75e4fffa7b658244f19f7ad2a493fa30b2b299f3c6bcf27c8843962b020647a2d6809fad624b493bc011c8606eaa1f8da5ff93fea1df01a81366b7d28b70939ebf264971158a8553e986ae63b5440efc4d8793a077bdd2858c913222fee6cc73c27dedb47e278cc90b1a9e201b4fc387ef154227130394e972d0a0bd52906aa162646b82d6caa6eff8dd6ff1b7d3d62c2ca3a1fa5d08ab2366b8291830a2c3947883ddfa08a0d673d8c313d168643981d2e684f813677f342078052ae825d7b0f69882732cff9e406373953234d5a222c7e74c256d429835bed874a2a8f971a9b28faba6f6a1d343716505f086ff43e3ec29b54a502b1b07a808c379f380d3b" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #19 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"355a0057bf8b9a768a03826877c539a1708f9b168e6d27cf4130f933687d5ca2":"af93399311624f0183f64a52532d65bd00c6c3f0b54c3b08d0ca57e62d13fce954ebcd086359379c915d45b5e495010decb4552441a35e50bd95137005f11f45921cdf316b6d4cca4d4f24a60ed4cdc00f08b2b52839384044bdd5fa0a06aba2fdcdb61e275771d63f912ce2032eaa9012007240129f033a588e9699865f9e72a2cab3257e196ba22a0849ca99643fe49b7df64f735d0f98ce4d63231c62104a99112bde240526d0cc58e12d39b3ebc849ded8c985b30c6811d79cafa483951266c6080be463e519b99e2354dee12d317f62dbbd9aef3e2366f3dca9d9a54d7e66824fe2abb6790a0da375ce6e60883e058a69a979a352a192cfb2a5aeb6983c":"14bc8f5db8c7ef9749bf4f1ca361f9fb66c7c7039870f2fb9e72d3d1978a2f4d":"a3a0862e4401381fb39965352fbac358d361b72eb8b45d7b3bb22fd489d369883685409b4600538783fab9fb212aa0908a58915d6c1a7b04e90c19f686cbe00902e04f40ba28fbeed6f2838150760bdbd34e5b5d95c7bc48299a77d4bbc50c22afcdf8f4574352180d6bc18f15653e3304e28e91667037a41da9347db5c959236a4f8540da601f0ad4ee7426ca178efc10f2002824f2d30f5bc688a64c3b7ab47d10bd7482edd0045fed0093586b485bd196a882c97821afd96bf568618f5336a071d63f12928ec75c12ee229feed7baafd6a67aec623b6ec66176726a7a19516f9a27cd9a6131616e6286e4a0eebdbf92fded200ea4d0fe4854b94ca2a0dce4":"abb24d65a0de0735aa69756d66ab3f5b85f9f251023325644b6e796758a307ef86a8176c48b9cb06e60eb0e40a817fa6f95fc205cc10a3d43c4c3c1c9dd3825fb2ab86716548a6d37691752a04197a213c713fcbcaa1837033d0e6d8028353f019f2f1f023f5bd6c4b903a92f56950c61ea74beab6016a4168a669b5ab3210af2d54aeb97541189ad18fd35fabd618b52bb16dfb6cdf535cdcf0b7f7373586086a5472914f8924cfd6b018c24122b3c4881661f5e26cc1f268cdaf768536827f8f09a284928a75921152d530d0da9794579499852d5f38902caa91a0dd905e856c06bc39d93dc4339a7e1a2883f531b3b9a20016066c82e42635594d52ea3554" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #20 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"327f4989c4b76dd69815fc8b44093eb0584457be58df65c0d83844509940177c":"9af0cebe2e1855bd4f103c7ca378ec119fb607706966ed025d8a4b1dbed2256dfbf8309d6d3a669626e9eef2e88be81b76e648560659d3141fbedd4269c55937dcbee9b1d455e585ed1948f2302e640ea7132893608a0e528fe25248a4fa6919f27555a49de438c9a9f561b7ac502b787c9f1b54e9f9e4abe896a9212e327edb44cc1d6a86cd06ac54a0fca1ae70043c2c751669f66529b494fb63782044bbbb1ac0ed283c41ee5be0ba204c205f17e7845bcc2a3ed69108a261b0795244ce61cdcb4db5f51f93598bc410d22438f677cac96a031d6e9d7be2ae7c014b773e350270f85ec90acf5544d0d3e012ae0b96290f3cc279f281784759ca516b302782":"0042f9e139f10d1b15eba4a652cff945050852bf69c7945b9f7c618881f26db2":"1c714dc197415c6bcf6efcdd0aec72053c0a3b17264c39e763ce4a4f7a13da27247615a6602187cc3a8f6e354c1744c7c6448bbcac50b4626b01b0058c7b14b8c5ee277ddf333e9fcbae62bd85fe3ba480a74b518baee109554f29f8bcb55c4f0604331b2cdd7586228d845fc4cdb45daf382d52079abe69d6148e3485ef99e0bf79f697f0f5aa4122052ddb8b5adb536fd03a6ff64b096c277b859664c031e4c38d0e3a92771996e4489e83989a011b13f0df50306c871fb3e35a01ab2ebd3ee847a748a2ae86a4a69b2f931d94fb6b93f625b25309b7da1f20ccf80556dfa1364d209d705795984e874245f9af6aeaf96fd79b0dcbf51de1f09dba4ae63f71":"1897e7b2368d242ec351dd195891e0938cfa12bdc1e70ba41900cc274cc91d7ebd488e34ff2612826b2cba781eff6cb7406b7b0cc2910077b4bbe0a1baff8e7acf242d8c5187de10d6fa76f7cf8b8e9c784482ad469b6d4b4cff355903f1a414925dc1762d90b4d5b818689e97f8932ad10db30a735ea1fda6301a6c4877a2bad418bee0bbac44689c2842aba762f7642e15dbda899b6b40e947b4c33fdfba843e2bd4411b9a733fae5982eb5366939d62211095c802eb103ae079f1de7693af51d21dda55b1382d751fe9d1b87bdd1dbea40b5cd91f90c237128219737ea1e3de5bafb18821418d102158cd439bfdfded374e6e947b8c2c2ec44e6f98933a4d" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #21 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"77a3a94ce0481ccce9e781a4316afa0654c117cc63af46973b3d0d569e0ff70a":"33d6d331a0230f4250e2f7ff687db71bbfc99e0b18da14dc353e584fe09c8ab0bf042b79f8ffc2a66f3da71bac80b98fbe9465d1fe2ab6ac3885a5d0934996092f077c367ba39bd151dad21616d836c5c5c9a9ba876ce42669e5d0d81fea51037e01c7d62b206db91e2b081eb2de33d3078c20bd40bc5b8df2f9a393da636a2ef7ba818bd1aba840092a5ea93cd06cb087102ba317365bf397118561217d43fb74e5d317a52989857f3cea369e3bf14d967190cd3b9a266992e0b165f113aeabed4d1c3c88f5f68648ba93301fa0a9f86a034bce7df49349c7c2245e7fde1f748e4874910272f972187a796f74ea204207b5d22627a992ae7b83b9c208b8298c":"32954232cff445b8bf155f5c6f4fc6a5a7b4712fbea320078d065ef92391861a":"42ce4735c9887614a2b0806dee1e3a0f2e68c0b76ef552267e66f0c5c14fd7f6217e8c0dd360978fd483f9d5f9f6b228c95404ef75d6aaf0dd6074849cce25854722f5038ffb9f6e926dd38b0aecfe28c4e7a603d3ef127ad167686c1ad4811931906b7a909e33eb62cbf244fcf06ff74507e7b93aec4818f56443e2f902c08b966a29d94ce77f813185cc1a9dd74e62f5aecd887a1ee78a6dfcdcc6202d83479da3c8eef85127638ae93fe3339d4bd5440ce4d60b3d9b690751704f18ccba0d8b7f9129ff1230aaf03a811a19719730070c5ccbdc64c1be3582a629b3861778b6eafc3bf1cf6e75a56db549aaf65bd13ac4813ef352250b5dfe438f50a11d11":"bb6245d129e6bc23346cd8663279719ed8fc56c6ba108e565bda31116902d0ca91c45f7344e13730adb85ad91b2ef98d715856ac5f6ada46836f1474adaf0529f1277fe8dfbb40b7af20c4e3d2a0fc26ec5a75abe084f169bb59680f1def30f56e685805202af6d7b216de447be25c473e0e7714fee20258ce12babbda8fb6af8bdd211bfbbbf5885ae4aea07e633c7efc89d5a3db35ee314185194841b8918ff945cacffddcfc122749a44536a84b33ac0c908f147e2fef8b91b06349e8743ba816ba751b481bf4b7bd153eeefb761f920409cd26ed1d8d74b073f88ed7015b6c90975a8c1bb24c04893c4efc5e8803759902878f7f4d6b4cd5080a163c06e1" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #22 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"cfff85ec5427db152d9c585676a43c2ea3a2be952cecc20c960dd5fa884f049e":"86fac3b6b5f595471c5800bdd592a7f40cbafc04f9f358f341133d7761b00dd891f9459ca52ce82c88fca1d3cceb1419fcf0cb268615c6a02917914d6afe3af22408c2fa9a209e4648c39b6251728c8ceca441a75a63237ca125922a4e58e741686505072cf3f16843ec291329638a043c3823ee9c1bf5b1ff2055399d91f40bc0dbbd1fac40c4d85460b20aad6461308898ce27221dd8b8702cabef4116b77480e52afd0cf3ce17d5256314548fe07287f832d5c2adfb37da421870bc15c56a0c05183d6d9f9914708545729ddcb709144bf980a078235cf71a2ae20d3ca6c6a3d458f6b04886e3e8a5b7ff176336555a69123b77d77b95163ab1ddd58bfefd":"17ed62da1a5ba4e0a6abe4b9e10b36fa92c5b2e5893d1d50b9ac0711ac407a95":"7564a353d3c4d1b371702ddedc1917304fb5b3b99dad2ed2ced1096710c7810343245851435b9813319c5e02ce355627e449d5a9ecce993966677206b49b68031e36fe3a604e8bcc15570d2ab73dd26debe0893b9f63191e21d4fd54135b05436be389a8264c9118f44a41c3d6f557303a1cb40e1a5eb2c07db30ee5eb9458ccf4ee84e0aa0d3b1a33c589bc7be29d209e5ed1839fdbcc10b47baaf64a3f6063ee9ee4e06bd6366aca0c3b23e32e9b049c22cb32781baad4f39575e688c41284d830d1bf042cb18c8722b95a619bfe8be8b90fd1e0356d0496261af97096da20737ec7143ee52dea4c8dac7dce8a42ba327d1174304991acbec1338d8f400f15":"b250aab88a989862203284c4ef597ab9d136d5fbf0fa2aaab73af809e0820dbe8c0298a35e7885166342564dd041e51a9223d2a2469cbeba63948579ec97d8646d7edd6b4b962b265eb450ef0bac1c87322aca3224ac8887c06c695203e04741819905fed639360a2d274aae9eca71072c4dcbbc45117b5d9bf49275956d80ec6e4b0687bd86d3d3a63688fea545113d60921e1e0f77722b203a0ba3019c2c2027bac96c5624bf56e52305c305e7e48c399ab5b6ff60de7de847185d39e545b01a58dfbe5dff978539069dcb8333ba4d251c23993f60b78a9cfebb1f8e7a5475bd0e8cda96b57145234d6a3b7fe70886f7a574f314935c66ba6043d5ff530648" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #23 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"4924a16552360ddc70c6af5f234540257ac2b70c93f5df5ab0874c7134d46603":"6d1a8a34a75d83829087a15a0264ad0301623309e1456947f7946218f98e69b3f42c03863d04606eb3e70ccf978c1d4b2a8cbc5d75b0a25e348a6e5d07f4f27a44018b9adf6a1da191f01dcc09cf895869c602243f52e46ee9488f058ec79388b9056ed3c65ad80440b19a0f01c16a9c831bd9b8901479c5ab0bed11450c257fc1c515b9a017836ebd900c082883ff7057b9b09e13b91e667954c9ce13cb87c990b6cf0f9c7310ccbd772557905673def545fb2b93983090bf54cd30ccf8cf2b9aae2c01e864d2f15d67f4f5af9c07449a8f27607b3061104fa34617a9d1eab5a62fd16c447324d416f258b2c6734a8b258082306c8e5e5cc0e01741dcdcabe1":"07434fe3f4a6015ef7b666dbe87c68ff7b9f1acf9402926238f4d5ae21a59ec4":"ba9e7f17d8f28e34b82fd8921ed9a890d30e24dd7d5871d6829d2bcbe8c2806e0b592763dc062104d392c74dc23dda0e68c80c40b00d249ab420ada3a495c518760da3703c39bf82213cae2d4d0a61b20146571fc1e4a7c51c0a37da9360278b8c6867a5f9395a5b918d3fa178f8839b950b753a3d17cdab887fcf8d4ab825bf8ff1bb25a301fd50d1a3e188c2c1b6be74f3a284aad7d162485d340289f5930634c718ae187ae574c2926a1749710e53b4bfbc138b4140dbb7ca9544ff82b49be96ac311996de39a96911baf829b626f8572c9ad74a2a33d4737895b58fc5b80c5b661c779a7415ec5ebb90ed7c0e73f9260ce36c523b74b26b8d44c33be3367":"04b8a753472150e20f648abdba73824926b1458bf9f0f92f8e217e0abab83671855a81914d59f4cbcc41ccc2d27b31635fc1396e0635d77567abc3cf853abb0e52749969d92bf546a0574c4ae98633cda216b3598886a8e97d7254891f8e74bf9347616af61fccbb321857a3676a06f4f0201ad3c6fdc2062672d6ebd20aa26a599ccdffca98f2004c2dda2feec9ca41b987742096dbe8dcb66c99a2eb75ef29e28680297085f5039e52b50c737bae322984498fddfdba4bdf6a7c42a2ad29bcd8e817c775c2c8549faca925325ca5221ca4060269bb9a868fb25d869d0efec381c2bd2e464aff1388b459362742cb00852c9068551bf4195706d315418552dd" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #24 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"6b67e1f6f9eb47e1496699f791edd7c4959702f3d3538b8bba95ea0a8beb046e":"5140d66d4deaf8a20c5ed32db2fddfe3f879aa997be576953462276f34d70704fe7c544aa659b4fdf76458f2cf5dd7380392c9712107a145d44b09b56d5dd42881f6913d30fdfdb63c456aed7ad61a0ad0908077fe66a1ce381c291bfd1b603a8b282d70d411f60678f698ab592a8e2c77a70e2ab12cbfd939162db2156d3cda6095865888ffac7ac2732bd43a66f51291ebaa52cd5e5e271e72aeb6164c0d73d13a956cfb964d7fe0852a638fb743cd215ccfb0c84a7c951dab414b7bc219c03cbc33fa9d7cc88ebc8df62ab6de36536664802f4d949f84408e549883cb4d8394ee1149d82e3e98b312e811cbba09ff091dfd38e3bc60acb3e6caa7a32573a3":"2e24154815a70317dc6a6f03c52cb936e102588106f6be9bad3747df3aa175a2":"66d989dee3a9fef32595ff1ea330cb97dd91c57a9d2590b082bbc2c2404875f99260a937e4bfe9d4538b951fee1aa99691760f95da8e3b9e5514a0bc1146255ac72aa19666d2acfa1ebc2708d0c43d081d99c1db8faba959a308452742069720fc1ddea4e8671ac76396229d65e46109169097ab0d9d98f4267db14c26227b2da491542cccb778dd3997edaed044b8ebf12123ca86419b3a52a62047ee2ceca6c87b34e4d74178c3773e65cb084f25f809a1ac641eff8f3319b12a06bdde619c2e5774de7942d714ac69ce677b43ff3543eb303f593103bc706acf6a053714da8417323863d45e92663557fa7bb0dbdf25568de60aeb90d9f0ac59998a783ae5":"7b0e659aa0db1a7791ce8dd5321d19315ca27e878e12d3abfec8fde85ba880ef65d6d914137150ba0152a7d990831e60227622d0c10884d5520bfa51fd881040d073d80c1786cd57f9583879d93697b14f61e37307ad1df5249bacca9ec29192873b8d719ee6de199b0f7c235d5883aec38e37e5f36aec8481de11d386e3450e8fee8551c62682b12aa86c3d016beb5982b9140d6bce8f054cb79a214f9acabf1238e90d88fce74b9a1d7ade6238c2795f2f01671896b365b35596d0cda2225a4090151d0e7648a70edaa2269a8d9aa8eb7576e70b0ce809bdb0aeca9cb123fbf9834078969867a9944e4424e40f2cd25d47c0456d3b91daac5fd4493138d58c" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #25 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"d49502edc00aab4e2efe0171af0cbb9b9d80a53c1f5671819388af243187c496":"af03717cb786a241b052a0b8adcc113c6d735178fa9414f1f2d0eac35c925328116194192007fbf5719fd35ce83bdac537542a77ad4b4ea6a3b5c8539fe1ff0d06c70a1e51caa4128a3161518a78d2f47ca5dc538bc8605fd41b7d2d9c4591728fc8dd776e7f5c43cea479430bdf9f0bd3909b576ca40b0b8af4bc2c35dbf3e370573899d605b8a9ec456f3d7aaf616c91d3474ee9d2d2b00f7605c544213d8df26d971ab30573b00a92e96ac8320786fb0a2c3287aa6c0c2367170d39680ba0434e7cd77f554fcf5031372db5dd9b0ba27f07fa31daac1f4381077ca98428df7c9d6ce2e4392ffa9966b38d353bdeb7e8ac8d2436513531b4b0a26f8aa6dce7":"db0539cfbd20de2f665c1a4e9b5b5cbff18cccd4be1134f2d22f8f0ded58f6da":"358fde6ac7347332b77a4411c779113e326036bee71c11094264d6fe9df18e0a13f8da103057d3b380c5ece837a9097b1ed406ffc4a625916a688617e118d09f959c1487d128c471a32c015891ec7d6a63522b0cbea3b54541d0519be20de45f9f7be167e6e9d2b72a731608491dd864712b4070bb857af5574d34d83a9c5e16d7bbaa02e67068379575d70887a6d4e686c87a0a007e5a43d853279b9597a60b1c8f13cc4f5d7369fae0e458230c3586ef7025c4eb940e6260e666c6fa42c572fb00d70aa8cf4067e4c54e269ff458631e8cf97b0d21858661022d63626beb86dba0938ef834de48584a32dfdac040c893972cba640a51333790518133fdac49":"8b1e315438cc4085a926a3f2ce90267d03c4f326d9eb2faa13e80bf43127efde6003597e336d6fbe54bd726bd9589e6c1431cd754874bb7a0ad141324865be289bbe32919352256c74d166b9a4802155c4cf3d6cba95be42f20a1d0e54397ebdab5b794af463c138b6a0a25a90cf948fbe1a2d654b55430fb674cf31f010671ac32cea2e48c1b924dee3c66027526f2d37e84a5289ebdcebce7b00594c78d699fc8d5b36ffabf3a7643f0d292b399d9ca81bd5e262daf51af4a88e8ef1adc136dcf8a137fb48927edcb543449fd76ca5b7d8b5b41ad8dc448960f846d0862b32036a8c6da3ad9fd58ca6e1c44c47299d2184bc2cb682e2e25cc970180cd8c12e" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #26 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"17f82c6d08944392cb358a5b1d7f21c83e755487a013c260af84626f2ebeec1e":"65dc5939737aaf8eece9f804f10169f18e183423cd568e9ef6e82c5ef8fd522e20e37c5c6698e7159a86b07294d979b252a7c928f76f754fde3b053368a40520680af8926be670c0f4248a0d5a5a1dbaa967815421753ffdcb4374b60e2d0b4595bd728f84fa4385b1976b03f81ece6be8ffd030946982badd1bc38b14dbe8a1d2e82907aaf2910e76203368b137edd2a655c325d9ab564535b8221b2265df04c13e6b4b966924528d15e575990e28aa890bc31b24239084f3fb19ad5884afb5cceff8da497fe3a997e31f4784b99d2161da1b7a32ac69e248d6f2b40614065821f08c25d89186f58cecf54a975bc444494d0405dfa8207b52882c87e5bcc4ad":"ad173df90f1fd90997c6bd00f0ec52fbcae8fff84bb353197864f0c5c0022218":"a140b7f160196c614a51bb56d2a972fc26878c3cf59166f1f53b8fb5d9aa3b7262503b2bee4e147bf636d64ff3cf41d35927f6be69b16bbbd1469c877e221eb6fc2ade3e50e6b9fbf660a153b9a105e2f92f231d08be0150a043573527efce5c152643f86914a09e4b9142f27e39c8fbb6c8ccde8d955b7b612c92bac96da15b14810809fb0a07c23642b8739b4a092f4153cbe7823eb51838c945e6db50cf99a53cfdf6dd531f22cae48b014cbfc294c0643ee6a2219ced591fd874b87db5487ea70f5dd546a385817d81e04a84f8cc499a5ca79f58fa50ef3d2c1d5111967e7003a5e99e418ef826571aeec969d022995c87e7cdd4718aba098faf7a834ee2":"05c047f26ee410ffac75b493f126cd1737270aabf3b755142eb9a718bda8a12c51fbf144e9c2144013148dcedde05811b04c01698999dba67357c0d5be2ba1fdd61ca1c17744418ea93d186bffcee1a34ef65f65eca50ee9241b3c2b54eb37ff8453aad227dde4fb2a8524522384626d20f574913dd8ad1a5688572624f520a789f1a29e4b3aa7ba4b7d10d4386771e4af4984af8d53129418350b8a4cbaeeaa98f723c3afe275fc2a4ecd29c41803d553cd6178f7a2107286e29077d51ba66bd88ac3a4c2653c0367ffe98c61f1b042f304ce00dbfd392aff5409d77a6a0483edf22ae348fbe1702a00a526139cfe19ecb06cc8cef3bf53d630893cec1ad5bf" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #27 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"081cd4d283c479be3660e139c2d92b24e7bbfc634b73ce5e16504700d5e58d22":"b35b9585dae0cf8f2597f8ac17340cc9a041925cfa200174a4f463c6ed9a0a748b2109f2308becf722880a89ef14157a95a8234ade4d36c04c20267ca1fef4cbbfd347eeeb7099ce547e376850e31e797a2c094a5278dfb87f427c94a38cbd87fbfebd5526d9cf2033ef258b7868c43968cc58e2f089a658516fb09f5ee0474c60e5b60f67a58e90bb05be55e59a513a7e0ce9495e12f5f49dacef852b772df3f90a5b0595d345edc469cbeb5b69209e85d8cb86d540c911e6046830c31186b8b2d1908eac1588bb7ac55976c5dfea360840e5caf7c3f27e69ac023c68107453b64d82a38801d34d60176a250e38f4497c88138d2c251a04ab142a32f31b7344":"11270f8721afd39a14ce80dabd2fdfcd4fdc7dc994c1855b6b1f59d019fda337":"1a11d470095faf7e3df62806c6adf88688f737ee77f05472ea0b1df6f0650e0b4f7d807672a58c8cd4615b986e45605ebf37c28b703fe6e9487991a439bc89122694b6d9559d67c144d54f6aa46b8ceebeed2a2962a153ccb2d0e2d726e7a760652c5a297b40a1cc0f960c2d327e74cff9811af4dcd7d398a92be870a48e22a76e7c08ac30e00d0bbdf415c6646d6b042c33025c797f1f04f9a81be7c8e973b6ba66170ee846a05c393fab1e1814ddf5bbde7ab840002c02636bd608066b050061d605666ef2ba3711d2f3a54de8a5a275007eb3f0bf6d74ad21d2d3a3717f7510d2cd788530f6ddfa7aafc12f3a671a4890328713afa87907a7630c5c342edb":"69a3ea81fbd9cbd733fa6e0cf8873bee3d22a27429ce41872326bd50cd7e13e3d01a9ae53e1dc310351adb719f6142cfa0eee7a01ba2723edd70ae54be4b7be4d222ecf03b89722d9312a62714893646b0b21ea85d9bde2b29d519ff8c03f56d860805f4822c81e6681b9ed064fe73b767420649554e801ffa62288feece8790be4fda04861d861f7cd5a3c29403deff7c51676f8262fa1b4020eeeea62d3f70c5f49f6092db06b8d835cf5f44d7e4ef87268916418fbdfeb7944e2b2564653799e2714333b532bbbed68a009f616d4ca03d83c84562596ab66771a7059256daaa6a42e4dd9365ba374cc80d7d9b364a9aee8d37cc2f90c0b8ab575d972c11e8" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #28 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"c1c77ae45b2175615ca7a8375716afd9b867e73a908f1f7bc9c3c8c010f2ee28":"58c79abbc5aa8e755bc44bc93e317ddf3fd1761c5ebcff4c741d4d9158cb5d939ba4a18faa8010a99f773b9b9c59744b078e4a54a910439e9e7e184edc2442a7ae4213f39d2e7223d40cbab60d9f1636629f071df67b4695ac9522105f0f2f07ba6c13539eb36ed9f58d62098502af4f8b8e48bb6781c4ed288b837bd58923ad6e4d5a3603652e5bbea70e48c872d529a34b52aec8b6f8eff0582667835468543654554d58357423579e52268aba8c528a4bdad04ab7c1affcee41a0d5938c176dc293c40a092579445777960a589606b19a59dccf9fd8f6f1976dd5e84c70c72adeffac47f229d6c3eeb9be3d65266d098f95b73dbc0d9cb6bd75ed636fbc2c":"0b5e36f6a9b8b943c2c479c2f9858a03bd1ff8605524365d2d6dea6e60eef289":"93dc1e6eb3bb1f9c800f08a59c1206c3124f216fc1bfef38f9d0d6ed7fc8be32e7fcd691e06e16d74993525c51ba798c457f9efbd511fb6af85cafd7a91462586732e09bbd83a446a4cabcc5486b365080d2e823bc2be7d29c4580c70495634e954f53d11aa964ab5a5378053e832f48e792b807d0997646ccca42d2a0a0f0532ea12b3972979dadfb29d9a2f5ab393fec2445890dff19d3458c8ac5eeb67bb993594982405fe7472528c7d98ae9ba2e5ed9b977eb5f53b8e7346ba92a54631a83a3310334a47363ea433d8b3bcb9f75d25d29b3a12c728737aefa980e11cddcd8f7c92f4c1c82da1ad36ef498a0cbb21585ba28657de723a4e0c3b359a5df63":"35b8ca4ca33871a0a6a9fd86b391dbff281763f8e12d8838572d01c2b7f1f229250a76c765b172b5a22884f03e8018debcf9903ec8c46889bb896a4f1408ecc7b7f54bae15c72fdebd124a65d218f40b33edd1449164e8165d59ad03ae7718c4dbe431159d39203fa5907d922c8f2262631680c651e168e5693468e93eb5d66cfde24c45b3826e5e35446c61333e6fe5510069239a246fcc04df303a0caa9a009644a2e9ce98504c77b5418bbb94eedc909e923e4fc21be9d4ad66d27b5fde9004ec273c8b84781459ab01964c1b066220b15948d238d072eea0fa08d5809c909accdb9fdf248a10d0abb8445c28af2d1f88bc72562fbce2ef9d09eb2e2d8872" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #29 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"2e8f5b66488755966a5ecf8d23a3bdc7f34b15548712d54ab1abddb029c9e580":"52cd362323e817d06d3fe87574bdbb290583cc952d3be93bca19914fe0e4e3bc8d735a332cabf1e66af16d41e01b0184ef55c6953e66125dea1b0db2c873a50e96828be9e38d03f8657ad4a0a44b484ed6fd17e4bc8b1808a2cb4ef52ec2e95143ec2c0565f4dfa3151231aea3bf10d1e7ff07eeab4fc9cccd87ad7c038e5366c7242d9f2b72ce3183f1e8707b286471c4dc610c721cd9c1425472cb6e9e085fb8334cd0ed4a085306756466be07c58b9f0582d803d32aaca0b3ca82ab334518afbbda648b3e239c4a8e70464c6aacbc36b87c4654e5e0d8a947c59c91f121cd1854a848448612be73357f8df2223135b21f38676dc30b4c6af92f497887712f":"d7792a79560a8fc7f60de3390772a0dfc2c9d1795ecdafe484613f5684099b55":"9988199cd0c74fe62fc69d0a73c4239e84abf9b61c81599b7766625725f65bf87685f8c5d4f0b3365e83c8430cb951d1033f6a6ce3aaff8cbc910d81a951f307e8dff4b1f60c30d4357fe5a34b4f9ddb9c79e3663e01de45e408ebcb8b0c64392a4cfe05613aceb97c2565c66c3640e9658501937be4cb16f7683127e98882022afbe93c7622d780a35a1084c64ea80a08f0b02cde5080ef0f51e164903e9cc6f142f59132ba510fbfeb46fe3f187eed212749ba87edccd639e124fd17013d255889dc7654ac8be831d0240ae63f1d6aea2b78669f3a1bca19e3e05901d4a9782182a99c017bf7e9934b56f7f597fb3ec37db4a5687b61bf568c24275a2ba324":"04c3d19eb7919254d640747eb9d24ec033598bc271b8add4b48d71e8ab4ef82fc68b4b19a8645a88d21a9ef0b8c4542dc0fb555490f622fa51ddb6ce4ff84a17ffd87cfb38a259155d6c265d70ca6d04c12680598e218c865b2990c6c5730c17bb93bc620b79cd1ebe94cf15c7358c4a0ea73ef6e3271d31638335251ba1092d01962cb851d24d494f4fbb82c9b7ee036e5c6427d6d205d8d146db9f61757f537f043e419f0250e2c1b74041e21ca854c6489513f3a2b58e3ff70d19c96a7f26ac9c29a5f16faed83d1fb7850b41792e5646bce6a21aa586d068f642087c54f3317941e617790bb03f3ee31c6a52922ecb6ba80493c3d8efd4f8bb3b7cd4810c" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #30 +SDV_CRYPTO_DH_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"8247776d9562de20d47bdb53a90aae76ad99d7830a0fae27bbeeb42fcab63be8":"a0f1ba2640663ffb1a6358541db85e0df7fca7c0aaac32ffefc819d743d9aae8791c060a5ba3e74b661485dbfc96824ccc2baf3805967d2ffa25269446c6aff6615aea564c41a9694780c965880c0b97ff55d05254a8ba58014e365dc72a42a9cd9d6468d0a33e50465bbce445fd98b7f0436c4f66a227b82c380173717c3164d95a994b7fe5130928db7e9e26ed69e2c294b1a91599e7ad36711318fab7cec8da86bfabba99d14e01b034e4caed3e782ac542ef54ac210c340f2f25c24ad984afe552bae80a114dbfe8ec70e043219104678ac58406c13a874bdbedfbc09fbe1a0828f2bd6166b0dbb8617b636be4f68fb9e5f2561b5a10f9dc139dde862dd6":"c1c327cbe6f534b60b0631ec2f0c147b57d379d7dd25078fbe5ed110f315d61d":"7b3c8d89aeb65359575883bc7e0357d8e836580274f84aae2875e20d988a2c71c3157dbc2f69b75db1a9cfcabd44770105bc83d269159d3b9f37f38f6e23dfdc7443f4513218418b7408a26eb7d78fff014df4ce53d48e2d6394451dd690c6c88d3c2b4a83359f866510af2a82c57ef1ad9adc1e93d24dcec5e7be7a97071d3f9dde174cb3ec683c6d2a5e43c1895866dbc58f4a8bedafdf076ad7e2043b56e8fc2bff935638b223fbbf23f85ba927f43be2a3a850b97b7a2b745e03e187e37dd7e09d7ce646902994277164cd20b77bcf08a47800cf178fc1159c7d176392cc69d1aca2afbeeef91acf7511e374d40e983ed3727543b56ac42044fac728430d":"0a81c3e0977bade7395a9006211ca6ecdcf2e2190f08096c9f24aec8c5c378642fc1d635a7c531c8c11d4bb38b890aacf5de2805446e561035c4eb270c7564ed7cb4c9b5f1eb134b08ea2bb061801030e6ff83bf10a213705e23793e79f06aab5acb03c0d45d80ce47dd2195d607fa8c484f93fd7ce72cfda197535b9defac47fb3b857ea5e5c25a73c7a6f00bae383aa6c4fb4e308c02ad89787f3e035e67f9493bfe8c0b7c2fb4d81fd58de90fa529bb5d37ad6081a97b8fc476022842d4ddc9eb9b27bbc192ee533f2d6123e81b809e40cd1d9e59d77c4a2021aae56b79663cf06ff8ad04f3fa194f238be7357efe4c2525fa105b9f956a3adb577137f932" + +SDV_CRYPTO_DH_FUNC_TC001: Nist, DH Compute Shared Key #31 +SDV_CRYPTO_DH_FUNC_TC001:"c170a05419ed997cfe34143808f447a982c91cfa8238ba3fc12d1bfb717843aa99a4a27e1d1a9797440be156391be3bb2636c2bbbdf60aa3b80bf9df700fe58322b6c6c18e813b213d64709b4178a54ebc8feb39766c1b7d93fd55db01b8e284ba68f528f0b004aa436a9e3b7fb30f4b86d050aba98cdb17556eeb4e6c2c963b00da63d739185d0cc4ac52232d288945dd1c50e02930c3b186869325e987defa04d6e5363a2f5b5e7e1b9246199f493fbb4cd018c06777f5138a21c0fa8b111248520977b472ca4c95456979bce3dcf483102a58b1dc21f78a5f23a13c72458aeebd0b685497c91a66b70d3ad2f2f009c22cf60f23e5a47985cd4f5731094515":"0b3eb89f51aee5f9008b0712d0b8312985f864f1e2cd112fd945ed82928a688dbaf83a23e73ea84dff0ad532b8d9e04df8103ed771a6342f0ecb5e4364cacca3d1a1aa41f12444f1fbd4c6a0d7620fdcd378affeb9802db0730c3ac82ec99641d733450360cb84c7150b07ba7b6a3247eeb63b5d35b16ebc026f32bfd8bdef1e3cc2c41abecf36f39909d9e3d1fe7e6eac0b94b925249b7a4c1cdab82e5937d993c960d8fd88860b999691bea622fd2850c72d1c10b35a32c7a7b662523750da17b6d6992606f179467c36aa6b2a1777843c3e72e066c77ccce82f3791e7ecf85ca3d5a41a5695e7e7ae333ab1d6f6cbd23d2ee0956346c31f67b4a0c9ae04c5":"cb948c28ed58de1b8ced8cf451aa0f1d8c6e1ca14caaa09bd31ae1467f9683e3":"ba55f824ff37b9e2ca94d2f5b5756c592a74aed1895e2a64b8ee47cd6b6e8c05":"b7896bad94401daf346901f6b3b48d6d82bb86fac1f7038dc795d7d131494b2d6957fc4a85476a9ea28659c00371e8b81f83a9d55506488dc7f964f5a7cf747906262e8940b9359c623af445a9d82478b6a9946c6e28d55e2f29827179715b8ce0269eb21dce3a112ed3e38091559adb7f4cc5bc8cc719c3cad6adbba9a0201932a3589476d69171ae6c18354a6cc5f7ed8aa60d5239b20fa852c65ae57801c0867be164ca7c199a88fe5fcb33b81601761340d7e124a7a3b70b7fd371e933750a43bb741d631e4dde965a373895e0be090838585f3698beab147675519d9b36cab1265d8ea550a1a9ef018bfb2d222ed4da99880ab54e321f98e65bbea72575":"65fae866df2f463bd596159fe88efdfc9bf76bb47ded413a176902bb8fe1b9ff":"0aef33da26c75f03261b2ce928765ac3a546eef8d07242fd8a7e3bad8760a5349c90db18880e9165fbd11631c6b07f88cdad2be71f21dbb95be744ad7b62d4a4a226d16429877dc60ecba4067a398a2d434ab9e63195987ba1d73a9b9d0dbd0fbd6c938084657bc35b3b5c2d4037789969344c58f452654057421486355c806bc8f6d2c3ee6b0694b012241f2d739a349043d46342e72e2da8ad15e92005986ecfc90b93c2c1100081dc2eedcf8f9180d53c1d7a81e3a4dfe71f233a04db0f10680c0fa2d087c647b9758f2f1e347388524b8865479da7aa2f736ee8f828fa157f405d6abb762f62a6d83deaf7092ba06996018455234d1673b86a63320ff9ba":"00ca89b9c87e4233aabda6cf39cb3ad74c02ba29fc7a35ee6d7a3ee05261704d1834c24f42a695d470494f66e373f87dfeaa414478150ea54560db0dee5f4a47011a6a2e522c23a33aeeb567f881ea05522de1b1173d3713e6ebd7e63d8939afedc728021e2ea613d4899e3187391d4c838f3ac979fa11cb704b71f9d586cf1134e039546cd243c935f19ef04614f7d58c808bbe33aa71578019cc5b665aa4c7e6d23249fc7202046c059386c0e85076dd4f2371c6ce16df7804d8002561c69fab27160316f45cfa9b3b3645014ed22ea38eb8720dfcc2616cf32cd6454c911c64a4cbf3b38f6608d2604a7e6549184391c52348c14b2e5f282cecea583dc65d" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #1 (Z changed) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"afc02bed59a56d3afcfa34251ae7d169433407a4be5d43ff3dc3f2e6":"017b4fc17763edde285de27fb72f932f330405ab9e6b0cdf9c2876386c15c2a3df2e1efea8df9b5f8da11f518be5d4674500eb770f6ff8f462264391ba75c737515b6c3da1e4bfe8cfaaba7990359e3d8664fcb2335a701a4071a84e1c867120860d7f5b40a3804c479975f91439c378fc78dc0fa1cddda6f124594324a2135a94fc61098d2cc24eaef811f0f25b22545a0dda117731308203e6d1620fddc6547883bdf3bab578b0b1acbf948ce3cfe48502ab864a9a6aae89e7bec0d1be1e38173bdd9346ff0c5e84c9a6cd7fc67e469dbd82fb8483b1054d68e1637b8e73c654f377730a50ca878d928c5c0011c215648bd2e3ada1b6ac9f98ac25769c7eed":"862e856f6ff58fdabc3007fd0149e9c3d22346e5a4a97471c06f5bc3":"908e1cac89472f0823092ea7f91b240394cbb1de63d79a3b5a1d2f0c4597bc6cfc4ed1884130efb58364a8b474a9061ed425ac27f1e13a4ed549334e4d8ab675f532f612a1d8e4b5b2fde8833c6bf607e7fc44744bf042d22bf48e84d07eb1bf569f8e6bea08298f1b8769d90558dbd855317ddc6a1b5355ca2304010399ff5f9406a7365ec3539063e92c92e16db4b098e36e100b608dcefb7235d60f898a0b2cb7173321ea3cd390f1a8cbc5b39668041b9f3d9d7abec2d3e6a5708c23a42177b597fd27fedf0ec83482762a20576962b8f4c34ac92e35138b991b813d2dd2fe80d3356a351c616e13ed3b7680ad8f314321cda7c57d69e2268ea1f19dbf8c":"b4857900d94d17d5567a5cf189f6456c911490d80a2eb8a7a1f5a3f633e8651d84949ec1966a56fd7e21afc3c87acc2ce42b88f1adf315d381ba4d40379d5c25170fb8141433d1832f079d1acebdfeb0878010ea767b9b822e99b5293e7d0516fea6170b3ec6e6b438158d7873793089126df98534e31f5993f54185304effdba4ec16470b488e17d00704cca8399612da1a0bf907cedc7502bef04563f2c7c540c50034918741d4483ad1699088f86cb161c8efbebfa1aec7c969533c0ed91544cbac873501df677a027f1fc7e6bb62ad91be09963c3b38f046ebf2cafb2068b8eb5fbfc45a71ebdc5ae5ded4e30604651250b8a18db8f7b10a08e06e8006da" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #2 (IUT's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"62048fd3ad852e1303d32b29ab761f9d42dbc8158f545c1a245eeca1":"0ec29e941c22a4dd49e733b506694701920e0d76f05aa6cd5e1670c9a4d501b35cb065b70953e10aa184bde823b8133d0c409b9a959f102e75031cfcca996103dc61503e84b46c31fd033e7ef694125a2cbf0041b3867e887a34ee46a7a59d83b2d915a1b1fe8f1f208ff5ecb5f6134f8c2f70124d1986bff8a26dba28ea0515a112029ab76b8b77bec6b1b6dfd1cdf7a1d03b634325bf44829176529f4f0610966c3457ea2d5f601a6482d997db2bca20c3f242632ae58f22f4bf5b48fe294f42715520242b33c8957f5afb9e1f87eb1d373f2b95fcaf07b03bf9ebbe95ca1d09c1c6d59e231a2565f087d9a48e1f1ed89dea2e0078a66068616416ee7c36da":"85451ca8548530f68d9de6717567a5fcfc71aa37c3b58755ce2e8567":"9ebabb17521db0653da73593b6b315786941ee21ff53df6d48c1419c515553240d10dd39930c6fb190cef8794c14034d05382bee8e0d254573d73bafbfcff9bb4f0262477cc9d5280fade542ac516bf755d148a90d3fb8bc132ee35213c2d541e4ceb70f7d3a60665966b81465b53fe2f48c5009ef599a438e4b434d563e8abb835ae9fbe7527f4510f848719a0d2fa8360ca0d883fa492b4a842ac7b83f19b1d247030219ca6d39255f2e939230dbc3e05cc6d298cdb45738b61b3dde7ada53344ee722c3c28444dec1d64ea25c90c03347456a86dca3395fea1c3bf32ca424c5ce70de4fe9d3f1badde99dd60b11255e469d7693b1f54a817a0f9edf1e5070":"0b0cddd491275acf6166bc5a52df28c4282a8b417a168b4778afb71e149a5aed52c8ed1a2cfe78a3e578d63ac07f201a5e54448318108da143c4073f2958d84cb4a3dd6ecd14a593422f646b3bbabc07c14d6979edf6b41da8b975d1746824d672a4b66d77bf728db6fcee381650cd7849bfea3b259fbe2881cdcb38541b5685ca8fdb3aa7a7277d437f6ea3c79e634461f8dfbc9dca836492cc6d831e9b6593a383cae90ada2d13e1d491cc482ee96eb374b26d943d9045a692a10f84ce769493c8e14a7683f4f222c7369e6654e4e573acda677708d5280d83a33a6eeb5c0693034a4a8aa67374341f99c72d66f5151a939cd10057789fc465cf7aa928361f" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #3 (IUT's Static private key changed-prikey validity) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"40d992e7b563e329a7a4b1701246e7e05fd364902fa4facc3c0efae8":"a9eb9f16550fa7aa6943c8533ba75cacafe478da47656e8fe615b7495792da8ab180e306952668ad1363ecceef401a20509c636fd97c664ccceb660905ad4b557687d646df41376dbf447676ab860fba588b5e7b498b9aec815494ffad1382acd0772f284a3c7347d313c7ffe8c5ab08c4d85628bdae69d13b8998f402971aa1b1a507a0dbd799de379d200bbefc71f57f87e5aa99080ffadb2cb0d23b6dcaeecf8655c22e45ef8c6daf158b8482b787d427c02bd09ffcdae20cf0281bd7739de6e9a91bb4c72697a90a2ade148774301f7cd6de22cdcf493925f59c5b0cf2b9ba609bdbd3308d4153d44444aa88e62c51f9be5cff3aefbee068e44ad5a6ce5a":"27fc582b32dea8494f2a1b7a0a81608da65ece26a284861d7e78b5c3":"6d717f88c8c21eeaf06350462f22e41259f7e3e99de5ccd6c6c21e1ed70083640154331e6d7a320c56222231923df5fd344a1726004e14f64b6d2fe0c9746d0f44d48bcc2b34b33b90b3c4e49c3f3f7770f3ec469cbd31f7b1330be42d851c4f13003c967e617a3537865c30912ec3d8ca3c078843c804da5e6130b7b6886c98677c9269727c09471deebd46834bd34d8b25cac89a9f91f175c61dbe055671dc8d264d71551e549dea30b1a9a0e5ec52a842f5c194e32cc0a20ba1070cec69429d86a566960cb85035c9344ce50be5c96bc7b7bcb5f2620ba5790292d8e0744e9f01a3b0033cce143e166d4806d6384da3bcfea3e898e53765f4f159b6aef20f":"9bba760bcf15ed1b39efd53185835bb7085a10efe1ca88adaf81c437872d61dcbd9bfc51bde0c73caf2157472af18d06ef5ca049cb149d1608982dd0e126031daba3dc298f6a8b43605bcfa37bac3df036cbbd583a126a037d79f1b2c591ba4e44a55e1efd81dfca8db962dad4a4eecde0538252df9d411c8fce03c5e1ce638da2b2bdc4e33a71ac6e2b1a9573653b6d73429e9f5380a3001d2d5696105696bff2b0947244ccaa2c526f04aa13239bef800e29fb60f65ea139668daa9eb2648c36a6b1ad4c7d9638baa1cab838d9e63651c9e802948de374865d7d37462f50c08f93a24a6185d3e0ce20a5ac1c713d16d4725ecace93345acf9a482f9e531a59" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #4 (CAVS's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"68ccda42a881a961f1f51ea5fbe434f0c41355feab06fb52bb4e444e":"cd72620b7be991592f5e23ad76e586678c0e50e024602c76757e38c37c26db0524e3fef9402b18e9ff2c073628d03ba6e19b7d33037b24eb079af6a488f9e071d603b0d139e0463a9230766e8d0dc0482f30a21004b31c1471586e2d49e00b4460793dfb3ceb5179a349bc5ddaebfde5b27dce38c84f86fa4c4e8a1c46c6d825ad93b55124f3f52bc5790eb3383a3670a5de47f08b2808992794c7f6dbd3d7d611c5d82a230b4a573cc8dd1491b4dee245df7ae4cc2b394dcd6ce98e489968cd47bb8b06bd42707c0f0e5377763a5eb237bd50192effe4ed99f097933aacdbf8f7e5bed86ac7f3a912819e18c6e24da407d973245e85a53e9be1ad6cd0777968":"87d42fd0e5ebe185e81be9d8df15d8051d92cb42ed17a37c027a3605":"554b0c1f2b40f50dd79718d22ac9be91f70abdb83d0c9a26be4d86ce9a096e3769d3a1c6d7be4c5671ca75e05fd049a8b6bc9071c52d380b430838a36cf0174401e77b4495ec826f2fb8512b4d899bae4b5ae46d0a57663dfe7d178cbde1d3f47ecd07b1045f651e332ebf6e187fdfe10ed4bc5354dde016712c38e90be2484e68ec210b214c14049a55f3b6ef0abb0712063146319c9ebc897010604fbca3fe30ac421a4e2ad61519090729ef6fc862b4f112256d5a86573ef21338b76d4a9fdbee52f27117db2ad473783b41a95382ebb4b5b9873987f6df873fe57764ec628dfd1889b17159b43915e80b474628686f97ea9a5e6528df1b4525e7af9d978b":"7e086071b356514b24f2f00aa0be07c7d89d795173e33f4286878d226bd741ab8d5c25aa19eaec2878c89749d652df31824a43b3ac3dbeb6ce8a21eec558dd9d78911ead494311938f7b5488b29ea7128c63b45580ca78e027fd632470b58ce626bbe0be0ea329b87d774408b0613e2fa17df86b6c270567a1fb46500532a16f2cd7375d7dd8b6b86ebfdaa5270349e53247724e475cd545d875d857e07f6a3932cc9b1f1ef41febc03244170ebe843b899615b3143d8cbc2ee5c41140ce2189f9a6b4248089e99652fa96e000043b4b8a26a4ea53022c8af9aba1c23da8a9107ab157b8c7e4629ce7af2426e3e514d62e069fe74534c9e858b0da42eb0b6f9c" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #5 (IUT's Static private key changed-prikey validity) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"13fbeab2ec2be1a3c6618d981a2cf14b946a5cb56b93cba79dc5f171":"93a5a26413e03865ede51f2abcb60ab48753fa2a7ddf145eb4dc002cc48aa46e62b2991ef1d9d2fdb7acd5c434107030349398cadadf56edcf9b23feabbfcdb10b5f35cd51f789c33703a232e2b3df204a6af3340d94acadb1d0a3cd77889787d1a0e2ff678d538272c37878dcb3ccb1d1503d948e0396af14c9e6a6abbf7eba59855bb715e421d3fdf1c24007a407267d1ab441617f20e3d482d08bd292eafd17b57464bdc158f8b0d7a6eef3db9d781a74fbc5f1b87215bd5c29946de17addf8e7587354ebc2ec1bb807aa0fbe473be6b74c7a05219c48e7f374b88e5f4ebbab641d29aaf692f0fc09dfe48405631d1310d76fe2a5f08b78673ad9e5d4b6bb":"b093527dbef289e6a8949864c47c61b771fb4f5a21f7ef377f890641":"32338419bf115fadc4e59c1cbc6a8479b9e75bc2a0038fbeab17ac5ca4d00050b525d46cbe44f01ecfdc20ea3f060d39931bc53ae5de7c942299dd2867714e3c59bd2fb4e87c88fae9b21070246c9c975ff77723d7299ad750c9c7917c14d4d57c3e8d094f57ade942f2ee5762f704ae1504ad42dc7e17fc23501e74d403949592b3bc76851ae92ce174d44c6f32c2cd65ee334ce1663c4938e7301d2b7fd3141f19caac89c2be394d0f0c0ff1267384f35bab48f23b37964de674685b1813ad5847eb15c53de8e88b301b081e1b2cff21616a0f870b2e65844270ff73e5b03b3991b1ae973f85fbcd02d9bb1b0e784a6f3e2e64ba344a1d6790c60d02091297":"1e7f3180b6a5ce0af683b8f978808a63c1e4a14c016b433055c89b12b534a80da1d48dccce1f2a5ef11d2f9f58c22fe72cc043edd213799b4273c206dd7b4c05ccb7288cd924b49a09c49729257c1677cc2e1484f1c7bfdd57cf7093c6b04369dd23b43df04c1ff142cd1b94074b13190ee3a1ccf98c730c82c969ee4c05f05f741b1620f5d2e5562a18d811be517c48c69f4f2794a735214c5951b50e40224f9a85dcabe120ea6a878f8044fce95231e148721afbab2935fa0b8f6b8e89878a503ba9356fe18b767eb1fbf8e27ca4ca79ffb5c1355aafcce2d97762e3707501340a65241c2565f0048f16ee058411560b46da78e50ef0612a14c10ddcd685cf" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #6 (IUT's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"2c47d7d326907bd836dd54f58d956bd3dc9a3d3dde00c0637c56f3d2":"18d8415c25cce5d69c709ca1a45e4451776b670e7d8a857e999b969d22b3eab5976a04e42f8cce9a3df273364c41e0dc1e8e0d7e811484cc24df3288eea091ac2b9a479e4821565ddc789fb2b005deff09f43fe80a0e45f673ee96a3f9243a28b27d283aed8c0a8c7725627ff53d514592300c75b0c5c24e8c961a79c8de28e14b850ecb49fce39d149d606a163cfac2368d3bd3fa7926a91f1bf5afcf37523b74645cdd4f5a98482f732103d790c560fc69384670ca8055a91d6726dc6591f1fce2e0c63b83878da3a9ad6fa1b4691cfefa281568a966f1447d7dcf57a92d8d401df51c759d614c9e6d6c5c2838b9d706c6e22103931116da5bd9cc6ad91505":"2397f8977506adbd9a99838e820b6b034cd09fd7f3bdfe3eb91a947f":"bc78012439f4f6ca2b9f9673144dd17a45dceb0bfa7cf296319e38e4d64418cc7b629fd733137553bed9306a14c1d0479d7cf3666bccac038539cec44c4bdaa6201701bf48f45aaa0dc7a880b65ca3a69089e9bf1a25ab34108f1dd323e2ea07a3e31274d3e6a05c43c0896f3f85edda97767c79521a8a857f12aeea039cd8c9d611d3a9b8b2e394c8e8e5bdadbb727a10e100b2abd726c35800e7e91277a5f824ea9fca6ab9f3ea8d5c39a8eb975f20d0dcffe018499cd1352a9b5ca84b2d1fb1850baef7a681614413687841c56a47fba15929a091c21f7761a12763e8ce5631d8875c042c3b5ce2a09a1920484a62ce50588f88c2b239ba29119949bf2281":"97fb7ce73adc55e221acb1863b56eb97f9d0f28792f26b61a71addd98017e60fcf7d33fcdcc2482bf6c93c4a8fb8e7feeacf6c4de3d8de63659b4d8c57fdab1d89d1510fefbe3a6ca013ee61d46a62afb4b81ba6389f09d14f26ac25dc22fda2bd8c596b89fb36f850ae2491545b41e5e575d7e0fa6fa4df0f568203d8a1b38fa2f6e03991f9774cfd1dfd1d9171c189768856a3a31a84555d5fa74e866db88e24eda5dc58e6f2d1f6faba17dbf838bb97682123c6855400c1381247f618c1451380f4ac01a109a4eb75efc8b2577e35f98fe1d1d9e45f0cbcce15eeb8fcce59264e76673dd432a893a000557d6480d76ccb32484d6a298503db3e93535e61dd" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #7 (Z changed) +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"93b6dfa79f9f48c6fda84b8df509e08d5c41b851244f98606063492a":"0279da2ead7154e13eda84ea17c35586a5c6d6275c069d6d5ed0baeb3965f6bb73e3b9e37b41bca43a80076fd990832d3311d9f14d7b9e2c73284834a413213049deb3fff38ef7dfc26853d302f3011c18f3321f1dd3ed739e750e02558e4e6f4a27797e3ae90e3ba0126f620b0d59260483aa8da7249f836f07bf9644ed5c8ea4eee11c96612b02bd87e3f156521571c4aa158ab415d64ee0611a9189f20638b7db9eacd12560809242c32f2c250ff840e64c5f7912d32280708f6c32e7f989f1369820e2cbd673af0aa8df9eb15aec22114d5c489864d11faad262d3f476afcbe7d77c99d59571e11bcfe3e7aaf6053712df63a840d1fb514982857c222966":"ac46d9896525ec5e0720519ffa423a7dc78b6e29bb26c2de573a8ff7":"02fc5c032c938e3155175ba7a51ceff642fc408dc262859f49603154ff28d958ffd2d47e57b2ef1be2bcca2fe1e5fca26558a47a432fac81de2c906d761b02a98c5ed225d6772aab6f98beb7de684ba36c70fdce201cfaa63d6b25a6b60603f59e0e8f460fe93eef3979bf5b27e5da6c22d79a7bba06d7703a1249e533982bbf654f4d76fc45c6965cbf30725fdb871325dbe70f0d14f04ef9127792482a88eac4296d28df4d9f0a2bf9b8ac7603846624bf4860aede8730954f80f02345b041cce2c8e20427d4ce6a023573acb1319f9b295c23325b60572970227de765944614eb1f00a65def8c79babe9ee0f893bbe960611b82e19cc31ecb208548f06bb8":"abb7715d16b6b47816688584b8bdcf7ad4a2211b58517fc28fbd1fa6c46b183f8b786242dc6bbd90088c54483d7491c49f5ecd7b011ab4549c84b2a3bcc07afb3810d6fb410fcbe6f3f5b7d0b1dcd1a1d36d435c4588a152bf38cc22f698b0d7c38a0b6d703797648bfcc36eaad2880a795741972c7ed7a5be435505c8e5792a8e262b6c1383bbec7fe24269a7afeba36400a6b59f29670e203e88c4745a23a6a140b76c283ca74e06790d47cd37e56ef459a92f54827a611185956347e67a89e1d4291be7ec0df94f4ef28cb92278763c8abdb3a9f7153005811a512257c16593f01a7e28006639c6186e23b3ae961f64d4155e34ca59241fafa9a58b4b80ac" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #8 +SDV_CRYPTO_DH_FUNC_TC006:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b":"763d133c698fc662f790cf636d78712f00ba40eb2b8b20bfdb581f60":"885520aaf629e8ce594a3c493fb58df778fa5edc0ba379e6d33e7c8839cfec659e2adc63bdf5f896fbe554e3df9632a1a5b71a836871d5db84920011c393245f0fce943d57a15891586db60a7cc41c82a068dd77511c63ca3d37e9234cc753aa3132e3ccfba70a54998354f6385d2ed8eeec2df678087f31a7056acd72393138cffb3ccd0d95318dd17884217b1cf18fc8f13695a05e0a39f74e3e5411c8a85d5797b0f9c23b547fb5a991e017e7039d2669481345412f9166145cf199a5bd0ed3ef2c5e179c68f10f2ad6aae447a4d2cbed455d8e86707939521c887f42da7fb79d4e7778711a859382eaaf5cea8d085e2609ee7a442aa54844a8d47bc4a00a":"0a4d2cc4d45557a9640ffc0bc4361995fdcdf371d783cbb0ad88386d":"c0bbea890abf71c1c665c14064b8bfaea5df1bdc16cd5fc63b61ec90cf971384f3b1b7e8f718a0495d5006882cfb9ddb828227022f799022b956d0878c41c86ad54c1a5c47ae450c5f7edfb516944ba078b5dc6d8b5a33b9e92654146a10d0e2bb9d001546d94b055c215f8c30b496ff0c9b56ea75cf50c52f26ff67bdf5a78941319552db7f5f06f58862889438bed4e589d4902636b27e9aafc135ec0555e0512a6c7bba935f1598f6a2d2f95d36278a0ef8f94a985cb89e05d38e37c2b1e690f7e90eb1a6f215842564274546d8fe0294067a632ae3af9af7c5d4a8057b673cd5eec4224f54018ba25cb0fab91d3df8b8fec01849142c0dcba1448531af44":"56d05feed5373450a4e60585ad6ede13ee4e87f757b115134c76e54e3fe96dbb76640d347b71e8f488cda345af5fde5bad8e3abfa786d467b38ef8b9c7a5d5ac38cbdb07515af6bce9c3248d8476bdfde3f0b5fbe797dc41c76f61f4f1cb5c52a2beff30ee9315cc3f836972db5d50fa9b57b1941dd9877929ca3657671b0187ce97de4f146c0a26435732c25d9503b8f6d334030006a40c10e8a5c3c92b5fe198024a4d7421360331df3b6838810f42390c42152517b84fdd10f99c32b22189066ab0b276db60c258f36add1d359a5686b7b9ed4309d628e0b06b6d127bb94c2c6a042e78efd228bb43e65e8f81d132c39b9c3a3dfa4f3878a3922827c1bc86" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #9 (CAVS's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"99bf1768efedd2a5bbe7c6dd15ac9782609c18cbad48b69f1b1156b300da5173":"4b16bdd9f9b72a1cd54c2f732e3ccf584ca68591e0b10a1caba045030e6edc936536600a5765e91c69cdfc1066767d501a6b8054eaf0ea046d3c4415d3d1d2845b4f4173a608ff50bc7a717e28437855f5f9c06177981d8e6b4b077cc01a43c781f735937c457fc74270e6a5d69392e0a6c8bc1513f4792ad8a3b098226411e06ede834c48c391cbe1479e066580d2dd1f8065a9fc0903c5afdf13c7e22917ccbef8693eb35f4366501c5c88fa029d943f0759fa49f98b366c18694e8eca06d34396cee39a52a17952e285e173423585c708cc642e01de27f5095b7390f6f9f87d53929a31a40e5b9791981f2567dfc33c41905a93b288c0df13368b744978d7":"203b8933badad437d97ddda3d243120df54d53f06b840cefba73405b68468a92":"07ce314e48cedd4da9729fe5adf5d4c52ba1025ed362fedb2519c7762aa281d8adc8cd6ddd297e50fe69222488b49732d2064fd13261e04d18697b4c266acbb7d9adfa632a2833b68e926e7b4d013aeeab936a807f71aed4f2c7a6197016138681ecaff0f990def56ea7397093d39a86a46add91ac116b51ac1bfafba6294c6e7e5541d638a102637a49d79471da926ee3e53e1ac54fd40d2867902f143ceff707c07fad16cc79cdb9104a22eb16ec2f0cfabd91da6a603991d8ef7b2fc4cecc933376334c9d87424ea0495bd0c6d73757657b305874d6402c4bccb081dad685640af9616776d7d5164f11c2384b3f8246d8983caf11b1efea43e2098c0564a7":"b44c0778b094874a8158ace3a6e4d8ffb8ae1b078b06912f6205f1a339de2c9d25afa4430b5c1761d699340800266a8466e76244b9a21b6eafea98fb09f50c6c06c8126ed6fde4a1f9a4c7a24c6989b6e4a9f0ee487e545f55be805ab4ddf32f75e0787a456852d4e8809dbce0daee60669e9ea5e195153fd90ed9eb7173329aa5775f90c708c636f12f007092e734c984a206f9372666ac341e7e906491d269463fea2b6ebb7c9c16646b03490ca4c7387eb9d274fac77b410a3bff0d2e532af75c89f647d0c76e945f480496cd9c44fc4efb151c718ed6663b66a8c5a07e83f2bda3a7d20c7a6640552d1fe69ce5cf0482c3aad1f295b9e1ad0ce5c4b872ef" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #10 (Z changed) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"c9d7bebc4cbfb2ac37dfe2d8ad3d040cfb8ce1dc57db10364b94d74990b982b6":"6f77d81414d2e66d2dba3f58d7be9d3846470ef2b5c7ae42c1b5d4733635220d127e28fa2132d3b3ebcceaae5b361e524d63de8c38a352c6722333176098c6473075e2ab29f999b1c73970f40d73e28cf04083441aa65b4c930df4221e86c6d7329843ddb52af5c54774a804e7d513f7af2665cfc8ceba97a793d42502a3595752d1e7e490ad187d13da183ed212f339d57495bc1d424cede5b780fc537afa942d083a53e5661b52cc69082154f346ea4f90f9b5a9e3f8e15d5731cd5a52eeed673ba8857926d826fd55a4b9d9155f37830424d7a890bfa7537b6ff0a9a2ddde6706f7821cb210b27840fb05df7fa0fda984d156160ea72c57f835382e560328":"4c48d6ea8c9a94d460cec17d0e3a26fb2530590634db6e0859b5c8d77c76ac50":"b9a2cb85daea8f550e41b05d7d892dbdd2c4f2955d29ed82888b87b26c9ee727b9adbb4c9d2a255b2516fe3dcb6948701dbdb16746130aa671d0be2232bf1744b5a2306eb72a6bee87c6f4236a0da1132ecc000adfe0092f98696b3566b8e76672b863984b8c02a65476049dc3cd384d725127a7ffcb33bdad0c99774db8f1221bc7570d251276460ea9a3df13cbfd775014de94cd634ce18b6714e4f655409098a2404768d1dfaf63fa1a7d20380c222905b5d9467b25e4cffec5f4c5c356e6b4fffa893b76ff257bd16b4b6e7b5fa598284faf0a05f23a9e01218fda21bb7128203f11209cd2e3d254155edf2b7913b073c85e5975de7241eab078309d7d36":"40191f4bafbd07147f0fd03bfc6823b4d7e77339cabb40c98fefdf087d6e812ce91d39cb4a8b78c28a96f38dd0e0dd6f473b0a50bee346b8dae3eaa34a1c54a7af46057c9a6f8ab9addfdbef0287327002112832ee1dbb20d2fb0748a159036682170237d8e83b6e0dacc9f20c9dcad871c575ba2ee504b3caf3195e56b29be98f75fd3f3e6547e270f5317798da2ad2fea486f44e2e9e298fbe76eda74ef0c0947ad1d0a678af94709624fd3e3913759ce34ff57e2ffe0c047350dfdf93ff4bac5bdf8f3f676987013f1a971716e9ac78f491a332e863888eb0925b79fb974f184b5c7685390b93bf40f688b02bd2d07292515cb969b9c52ad3797dfca16fae" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #11 (IUT's Static private key changed-prikey validity) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"9b14f9773f0ebdc6077efbf61ad0ff8487d0d7c0fb5b59ddfc6f5a2decc9271d":"b9a7e60623b61b3a2240a75af45ccff21c2800e0cfe7348b49fc1febaccc1ef121fb40781c07b7bc659c45702059c6a6481ee770a89dd70cd8c61c1150bb17c0d424d98cc5ba61213cbd096525dda52c41af7c9e9d536afd203c642160f8b69409f68c0e9cf8222020eb95917178e337fa9cc588585ff8c62b9d76de8b5da13cc58226c9df4cb80e1a1aa09f1dafdcd67a8ca8c5b266f1a3c853f6d526557e97c94c9e063fcd538f08c9db00710cb90e835514c70cd42eb5d865b49c269750fc77e4360c8071d7f9d65d2d874fcda8cd23d8ef3b2e904cc01d80505293d503ce92558171948824b3b0fdfa8dbae68eb638d3619a51258a0701e2176143eba8a3":"47b5bc492362a4c7c0bf8ef51b3a033cac7e7165150329b5c23395a63d6fa84a":"1a7175256874978e73d5c3b26842362005e4dc50d51f69413c20f2d632a9b35e7f6a64810409d8f78e64af8dee42a8b63ae5a0cd76c0ff5ad6fb7462ac5890de4051110806f3b2a63c2918971bdfb5060896b5698d1645d336d1cf5a3e90538855cbc5462a23caaa83f066a1f40240e843b5794d88ce938dc9712f91d233e92dd2c5dd076da72f89ab08fa9f5289ef6dc8f584933fcf5943ad4c8b81b6021caf8eff4c23bddf5bc4138b0f3cf2e65ebbf850d9cd81ef1e20e69e997f312020cd4feabf8013eec9f3f66511a8c3dcb0847e6466c5b5a5f919d7dc4f6a9f863365b6e016bf1e0d40ae22d3b255042610343483f99696bb877dd4908c4bdc27a492":"7b0f5f0795989f250393d3c38aaef1c5768e5eb72607948c0465583a9189951cfb84fcb64bcdfc32786a7753460ff7fb173f2de0a2e6f5b82f3c288e0cbe503033a8f51a6a8cb4a9e47e07cd82eaa8a80472506c6aa87137c4fce860552d79a9f46000b7501442eea4d3a34c94f90d8bf98bb45f4bb893f974ef2cd29371b671cf219eddf08f911eca6bc8d56d8b5e7acd23ab79d159f695af8ebd3afb69c273c9db1c9074476ecd9b8882a95d805ed9fd2ea19c26f2affe9584190946d64885b5fe914236584ad10700fadfd934716e3cadbebb3a479332a6bacd547d104eb534716fbe34de5fb10dabbf2a3e584b215676af24e26e2f3d224210ac7b333389" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #12 (IUT's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"21fbe182d9e7e3e5c298f0c2c282c5f6079c9861786a17f4b593e9b0d1495b53":"0404d8df34aad60bf4ec5b2780f612e4b055c95f8829e5d34f784701b8e95ee8e5000e537e84dd382ffb3598dc082abfb9249fa98dd1503513a9aba6f6c637b8a25e620d2d561219f4ec3cdee0f4e6fc017f21e88cfd56004e74065c952738505ecd29bc5920dcb042139af9710ae6cafc8c8211d097e010337a7972348cf0cbd2db760fbddce7798cdd45aa650ac34c9a3e991e6d2cda5039bba14a6da8aea15e1f61530c25d6dd6df55747e4229e646cf4e24695efdf6387f5c1b9bea52d83f702cfdc6147181ee6989e4d89e0287d292700753561e4fda2e29bdf2f9d4bffc27046bc24b2a9659e263b040c8e49a4a200af860772382dbbd1cd2ad7747144":"4d956ff9761978890340133f774b2380a242f858772929249d9ccad06f727bf8":"41f29770829c8e0f1df630fa7312d625a8fb8aa8efdca7fe1b6894f3570f39d4ae46ff9491b8aaafe7207f84e9eb75c4e7eb099c33ce72db33282675eca6930d7f261c6dc061c39ccc01caafbfcca1cd733de1adbb718913322c6f7c7c467fbb9d4bd60aebc0dfbe232d0a7deaf57ceb054d5893f8a72d89599e10e1682ae2b59d746680bd9b1f4cb2cb1ebe649a3aa3cf30fa8fd1e212a696ab5a115080a817c3aa77e56b46f503ba35cb9d3fe09092f0ab9435c34d94ab7e1d0a736165d0ba9cb696fe41f320f6b925ae05a4a2f9333058f4339426d34f8b98ce96b587a512b22caf0d6dd9c027ddd8c508faf51ec0f3877c248c5a9c5e3048eb810b3e659e":"3e8e0e019ec2a3b71a3cd3b7099c3af96ad8c96ff82e823795d90c95c0c3b1954c4df6a6877b08b434f34479caf597e55e804a42b835f39b1a0c2069297e554b4f039db918172eb70210b5553275ad500ae357c5a370f15d2e8dabde018a26b1af6e9287ab94d8353fb5e6d62fe8715cd5cd226f2d4e554e5a2e1516b9923b7cb5211fa4a5adde16ff9d355986c8c523ffe293866c9ab7c04079ebaa9964ac2e1e863829de635f7d1ad65d747fb417df6466341fdf3f9511c53a2d588fea44b18e7efd99f291ba55bd7f4fac97ef654dabe17b738ca4bdd6dd664ddc605bfc7af9ad959f1ae6223d95344c5cb5de3fdc37955441c98823829bcde555ae89ca20" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #13 (CAVS's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"5955c0d85652e90c16ff7edfc29b65f5600bb4d347d443bb55e1290831d7b279":"8a38f0608acb982f235db8ffe1072ee2786645e07f0a3b7e872eeda5ef7a28a32e30582f9e338497da1ded14de4665acce65b7338fc3b6ea4fb7f8ef2f341197a3438539a6d5b08726b0361406c21d2d53a43e486e39fcd567cab124c9b3ea9b3a8335f283c67cb150b3f357779fa759f4a509f7839de572de7e89fca79be29e6cddac4274c9ec73542edf99a2099a313d4ecff7755e30f873712e6f598a568a73d66229505ac8459f19ff05f117b11f65141113d95f00de3f8f796bf7adcff502d1f0cea095a1ec93eb980ae117899fca057b98ffe89c4a680cdcf09b0c8310d8c6a76b54561f6e2a5f98ef98de2495c239a2b7ba9087570df9e85887ca1900":"2c55162edf332498f817eab0d0d86b5c75b4528d9d1396192f7c4e8f39362454":"87d93559cf6c5a1cdfccade4e3f14adbe76d110b328bec38c51e2329cd7e98bfae8138474ae7c603fc1241a17a1294924960344ab019ca00a6c502549ede11c2aa8db5578529f92ef34d0fe1434ea9426a9892e046cc7fb0a722648af36393176e07e1f3674f443911a861c1257252e8c9f688ed18ef12821843d4af4d1e011c5c3c15f576698bf6bfe0c85de1d930e1b2f248a4d617c72bc7f203eb17ce0e3cb1631cec631b41b001c82c23c953e0e531444c73a350a9d3314fc6f57cc0b2d288ed1c1bf769b1428d7ec3b3ead54b7a38ff86c68a514edb8a2d89ccccc251c5362e1f0307cb952a7f152c3833d3102210e4f49f65228743e57d41b47f0c7303":"57ef5894c8e88671c5aa125ea8917a799bfaef87b2d1368328e73fe285feb6d0aec8039a8883d7884ee25ac31a885dd2995545a6432acbef94d8e99429bdd61788f0da4a1590524f7d24ddd5df2cee9af25ed988c7e0b29898587bd6914c64f5c1adbb087cc708f4cb6381bd278c8bae410f92cb062c8bc5445f732bd54c1a77c1a02f4577618aeaf658e2c85744b284f4d54f167c71fc1e65cdeeab34e5325d2c95ff609f4c88bea635e7b98cf9d9207abc0c5382d920d74252acd536b8ad332c995513a2cbc7a17b212cac63dd8624ef83f7f517b41826c2e26c3686ad61e9ff069309855cda8826e229beeba5f0c13ebfabe3ca5d8561a2bd3530b936d42f" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #14 (IUT's Static public key fails PKV 5.6.2.4) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"cad5b21ecc9e1a6b48a8b03b0df2cfb18a31b5c5d0a416fd2918d38bcacb061e":"a4641db09973ce88a2b3415230b355481175fefd2cc79035f0c501a79950f0f45fc9b98b19651a408e5d036ecaf3b863b7156dd88f381e550b7fb6e18d8b6e220050dffb33952c4246d972bde0d7442454fdf4f2fb9598ecbd7d9edcf746f02510329677a7173fe965dcc20241b557b1d9fb4228f91c3e524b7a5d8ad7eba85f4d4903a9f3806c537811e6a8f6951d0f9061c8dc5ed44f879fdadb6e05381a4441088368b87b6d262638d0c507eb6f3d0580d35c9ec8fe4bf2f9d5f55cb7e82ec3097083998dbbf5c09357937f67dc307b36999f1e3aa3a469cf5b8dc33297719bf1b07b6c2031f69c2689598894c373f2c1bfdc074d32be7e665357159ece2b":"3bf1a562acba0c3d3ee36528aa98ee456e4e1161852c4fdf9a42a67354ba1ecd":"17a573cf63bacfd79ec59fab54685b24ed632bd16f6e0131ea3a9bdaf2914622aa94f15ce4ee9919e51ecefb3345423afe36c9a38ee8c6a48f4773aa3fbada6eb332b1657ebf865b1632be847fa1c33a7fe6e699af6cb0c995344a369ebdad97b21d168b0e3f261df1aacddfbae1fd9784137741d82dd9df7ec6d2cb6c45fe8894e24d55a983cb9ac9820ffde0badd45f3f00300890fb50ae5718daa029b9f7f985270b61f462c7fe60e00b89b2363d8d58ba4d11b63729ecc3226c8a60e7711dd5f635019397a32965b3753bdf1f5d51c669dec41aeb6184de7d87aa57c75c9bfda44a2d6f65d3cde264d6a40d87fb290b15c943464d1fd4b807be35800ffb3":"b93ae6dc7b01186939e3a897707ed4923a83fc08e1f9b777f08d267d10fc34ce65ce95540201f0f52558f6efb72287a5e0a6fc53af96e702d1e162775679b69ede31a05217868274987eefbe2015f66953a34c4b5390a5e671cddba5977991b187b326caaf42f407f14fdadf539e70b4c20859981e11bc7892addb8c1f701f487f08a80c5d35abc83b889794073331ce6ad1367d3865f7d225e8c828774e7d56c6ff947e4018223f56b1beffc0079fceb965cdb6519416a709831e919a847b93daf9b15db288d7697a389efda0380c9d411c3bd3132a0e04791c5117a49e68444e2ecee98b40cbf7bd3ab22a31ac0a3d12c391d28269a46670a02bd34534f0bb" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #15 (Z changed) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"3216fae47159917182c09dc08fc11c77d8921be4fb6970d6c095027e7ad53c1c":"4ed0b6f75af48a8a8e634d1cbe5c00a771d090ea1746a397af8317374429969ba2af6c4b4d2dff2530dd86f6790d4d0268e955c58a725c9cfa7500d030d12fa9f07884b078305714426dd70a6a572e828567662c48bdab14543a3d62f8f1d1866859f659581bc819d9e93ea9557c7a9ace63797ec2b09bbf68987c6de4cb29d588659fe84d4dbd1360d41c315ff890adf03f03121fde4df9366fc8f74220efe76dd11eb609da67b416971009cf5a176957173d7824243ae67e1d0e7a0e97e21b1af1b51e06320c04be6d1ab3209fa89781386ac538d46717907cd6cd9d68627d171ced654ac7343f2dd3dc255aba472cde506d62620c72a2b026580b19f9f79b":"17443b1a3115da56fc2372bdc755b8aaea8cc1ed636ccc3f6a722e6dc0642fdb":"738921a16c7395f3f2b65ffb656a7c9c95113145e59c5f19e619511badd39526535833ea220ad8aa6e369925202f7d471750852bbbbf9e33312ba77d6a47e72181c2baacb80973a9fb36144c8544eddcb0f632b8af7463ab27340c9ca96f3991b7f484a77216dacf6d97879ca4c531a812a9dfdbd5be0e49e7989cad7825b4426fbc5fa0301f882543bca26326af5e3f1827abf8eea9601cc0d57d42fd30be3c04a897b531b0323c33a67a3931cfaada84cbd0d74f3ee40a6a89d8d70a90b6af87516dcf5b7ff79031b571f53aa95c13aeda343fbc83072cfccfbde6594abc295b485b1c54155bb725e2d0cfcf7e9a87fe5aa174ff917c1bbb90d72b652de5c7":"a858d8b3928a49a094d178177e4d280e0506d83bc4382c08b75ce809f8b2fe2dc6a714a684edb56e788e1c3dd0f32e6b097563162dc7e21cf6389d90a5d127b738f8f3bae9e6310e21b19964890f8e808705eb5e5a4e87a847448dfb96872fc63539d6b64ad5712e833db5e422bceeb25bd55381a894388d3efafaf9a292c42973f40e878bb2656c5307dfc61d0ad228dd19f10b4d12177adbdff03fcddcc521f56b9f4d92a4aded5afdb4adf76ceaee135bc34bf5dbe3e6ef83d904bb09d2c06fe488419e1246226cfffb51713217e1a393640d78114407418d5c71712f695e96d529ff98541381f358c0005cccc4c8d97d9928ab97a6c14cb6356cdb70b96a" + +SDV_CRYPTO_DH_FUNC_TC006: Nist, DH Compute Shared Key fail vector #16 (IUT's Static private key changed-prikey validity) +SDV_CRYPTO_DH_FUNC_TC006:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"c66b8c351832ea01a5092c59be148b499a5951b78c8ec3e6eea84183fb5f5ded":"2e656f3bed7bb2d71da7ef3d43fd031bde0b3fa00c718ac96b1a1c61863a0053cf84a8bacd5705a5a2e4d398e1daf3a80c995dcbffc682e3a44c2c191d3fd8155f52eea3a9d7f420d7a3557177297f5b87b9429d910277ee62757e2bd3b3f7c1b680bf6a9971116560e1f91bc902e31235933d14df5875e06c11946d133bfcfc9944a4f46501127a9b850febb32c86a8de6eb8e66f3c8abd2ba3ecd190862a83d120a98c64501d92ccde1c3ee376bdc99b55f53fbe8d8969ff22b421997b6a88b6c917ffd11f29a22e59377e750c11a9e0e06e3e3b05441aa2e2ac606812f8583ff0fd8a02f45fe0a1024d9f8884a6987ca81e2226736e239bc96194b044dc73":"3d802f12c01ff8f0b59c08b986ce7f8472336565a2151d3556a48813bb8046ed":"176d1ddb56ada49bc1582b2774065b83d097f80375be555a15e0a79be5e87a3687ac0c1680afca79216f387856beee345c5d3c6cf99f72f0fe0adc694ed0257efdfa96b6061b3c87cf30907ab90c26161a7d4d1a6130ef7529f6e2fd131440f9c87b070bec8e6d00d7625b2532147a380ef80035424df83eeb6ff8cd334ba0550232d0772ea326c310d11fa016c434e7dd806a2b980740cdb678d50a03b4114a148fe3d57eee2796e7493541659bcd7181412d461c0ca726343fdf2c841d8953c4c64fd346e096f434e665b21eecf86f0fa6fcfd3695cbb7dbdb8c064f6dc09dd33cb28ac38c3ac9bf5b02be4b6f227ae8e7d9d32b3cb827f4011be82412dc5d":"492258710fa5a3f17908db78595e00d329c7e020c54cc19be86ff41c0ed8838f6e797b38bb239e601dc09e7faf0ed5df534939ef5dca0fef3b50e87d0cf4b9f202c24df7922596378763f30df987d2aa4453fbd473e835db268bec714bbc1d43ab9f2700c3b5227fa653ebdb6f69d35a14cd9872d512b1c58542c976f2513690bf214ed3115d0016fb25cacdf6838a972a54dfbe1fab44c6c8c4be0d1f0949a1bfd1962f3c06ef0acfb3913939d31ff4b15ff91fda318332562d981cdabd52e9a12ab75159f434d7bfe4a071cf9cb646e2c6c9e71423f039b747e332b6c5dcbbfbf6ebfc1885915561a70306fdb03c6890c05ade9b624b831e4612b0dd013ed2" + +SDV_CRYPTO_DH_FUNC_TC002 DH Gen Key success #1 +SDV_CRYPTO_DH_FUNC_TC002:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" + +SDV_CRYPTO_DH_FUNC_TC002 DH Gen Key success #2 +SDV_CRYPTO_DH_FUNC_TC002:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103" + +SDV_CRYPTO_DH_FUNC_TC002 DH Gen Key success no q #1 +SDV_CRYPTO_DH_FUNC_TC002:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"" + +SDV_CRYPTO_DH_FUNC_TC002 DH Gen Key success no q #2 +SDV_CRYPTO_DH_FUNC_TC002:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"" + +SDV_CRYPTO_DH_FUNC_TC004 DH Repeat Gen Key success #1 +SDV_CRYPTO_DH_FUNC_TC004:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" + +SDV_CRYPTO_DH_FUNC_TC004 DH Repeat Gen Key success #2 +SDV_CRYPTO_DH_FUNC_TC004:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103" + +SDV_CRYPTO_DH_FUNC_TC004 DH Repeat Gen Key success no q #1 +SDV_CRYPTO_DH_FUNC_TC004:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"" + +SDV_CRYPTO_DH_FUNC_TC004 DH Repeat Gen Key success no q #2 +SDV_CRYPTO_DH_FUNC_TC004:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"" + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #1 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC2409_768 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #2 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC2409_1024 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #3 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC3526_1536 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #4 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC3526_2048 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #5 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC3526_3072 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #6 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC3526_4096 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #7 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC3526_6144 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #8 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC3526_8192 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #9 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC7919_2048 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #10 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC7919_3072 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #11 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC7919_4096 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #12 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC7919_6144 + +SDV_CRYPTO_DH_FUNC_TC003 DH Gen with para id #13 +SDV_CRYPTO_DH_FUNC_TC003:CRYPT_DH_RFC7919_8192 + +SDV_CRYPTO_DH_SET_PARA_API_TC001 SetPara NULL +SDV_CRYPTO_DH_SET_PARA_API_TC001:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23" + +SDV_CRYPTO_DH_SET_PARA_API_TC002 SetPara bad len +SDV_CRYPTO_DH_SET_PARA_API_TC002:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" + +SDV_CRYPTO_DH_SET_PARA_API_TC003 SetPara bad value +SDV_CRYPTO_DH_SET_PARA_API_TC003:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" + +SDV_CRYPTO_DH_SET_PARA_API_TC004 SetPara Repeat set +SDV_CRYPTO_DH_SET_PARA_API_TC004:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" + +SDV_CRYPTO_DH_SET_PRV_API_TC001 DH setPrv Null input +SDV_CRYPTO_DH_SET_PRV_API_TC001:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23":"1ea26e8b4b0061e1dccefb2f56b0dadd9d0fc297e215578823a07e97" + +SDV_CRYPTO_DH_GET_KEY_LEN_API_TC001 DH Get KeyLen success #1 +SDV_CRYPTO_DH_GET_KEY_LEN_API_TC001:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" + +SDV_CRYPTO_DH_GET_KEY_LEN_API_TC001 DH Get KeyLen success #2 +SDV_CRYPTO_DH_GET_KEY_LEN_API_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103" + +SDV_CRYPTO_DH_SET_PARA_BY_ID_API_TC001: invalid pkey or wrong ID +SDV_CRYPTO_DH_SET_PARA_BY_ID_API_TC001: + +SDV_CRYPTO_DH_SET_PRV_API_TC002 DH setPrv edge value +SDV_CRYPTO_DH_SET_PRV_API_TC002:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23" + +SDV_CRYPTO_DH_SET_PUB_API_TC001 DH setPub null input +SDV_CRYPTO_DH_SET_PUB_API_TC001:"4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010" + +SDV_CRYPTO_DH_GET_PRV_API_TC001 DH getPrv fail +SDV_CRYPTO_DH_GET_PRV_API_TC001:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23":"1ea26e8b4b0061e1dccefb2f56b0dadd9d0fc297e215578823a07e97" + +SDV_CRYPTO_DH_GET_PRV_API_TC001 DH getPrv fail no q +SDV_CRYPTO_DH_GET_PRV_API_TC001:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"":"1ea26e8b4b0061e1dccefb2f56b0dadd9d0fc297e215578823a07e97" + +SDV_CRYPTO_DH_GET_PUB_API_TC001 DH getPub fail +SDV_CRYPTO_DH_GET_PUB_API_TC001:"4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010" + +SDV_CRYPTO_DH_SET_PUB_API_TC002 DH get pub bad len +SDV_CRYPTO_DH_SET_PUB_API_TC002: + +SDV_CRYPTO_DH_GEN_API_TC001 +SDV_CRYPTO_DH_GEN_API_TC001:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23" + +SDV_CRYPTO_DH_EXCH_API_TC001 DH exchange null input +SDV_CRYPTO_DH_EXCH_API_TC001:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23":"4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010":"6822bde050fcddf90ba8c398d6c973552be0f8f4b48c86dfdda2c187" + +SDV_CRYPTO_DH_EXCH_API_TC002 DH exchange no key +SDV_CRYPTO_DH_EXCH_API_TC002:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23":"4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010":"6822bde050fcddf90ba8c398d6c973552be0f8f4b48c86dfdda2c187" + +SDV_CRYPTO_DH_EXCH_API_TC003 DH exchange outLen not enough +SDV_CRYPTO_DH_EXCH_API_TC003:"92ac82b2885b174d243d1e7d5bed4b6bac61bd7132301be5f1e669436d409295ee9c7005e5a16f8478fb6fd214a196c98ef9e591e45cd93317703a2aec5b106ed7cc4a987ba1aef7f621348f002ba98755e010f0327cb538ec9b1aec01dfaf26f1ac33b917a989bc7398f1234c2552dcdac65e4cabc37b5b24917dc166464b7aff2689138879cffa2a9e7c11abfff11917779bad99fd3169447ef5087fb61e1a9295552db761e06787fa44ce83dfd5229f0bd12a8673d0fc9055be0594898b5b0310fdc50ba13f7900d5fff1e81fbc9042bf204d5f0aaa6966f725a4b6c4848a8d8168e3389d7dfeca6acd89de55f42d911b749bb5b82d61ef463216d669ac73":"2ef437fb4f8ded561db4fe588153a3be42587270a0ecf64205018759eb0bc060f62777297b3a99f48953fdce34a0e966dc9f79bc3bee43bead12d593729130eff22ad7e83514798fbffc9cccb34a8793aa95afd2686247b5c17802c1d6e646337bad88118b740744713ad84bf482a650364cf0c44be2e64242f29898af722fecf39a49aba0befc3db68cc789f6076fe900856c01b1fd1e70ce0eceaee1717fff948ad9d66d76280a5f3e64aa4a373951e89dd17853e081b6a890dd79b147817534f46fc38e7da729c6d45f5e254fa1e190b385fbe9f160654a14e5b3c283667f5f2e0ad144bf10bfd3f912370e81243549acd4483daa43f14abc08fcafa0be29":"b1a173f76ce1555ec2ba7640e82e506d0f6d7ba24c9d148621fa3f23":"4d7cea099b64db3ddc8d3f8bd8b1cbead7e071e41c58cf08da3da18c0b7cac6f76a4d8a991ec9e743452024355a9a1f6d5c867ad4d98eb8ef4729520d47b384aa38b219b854d05f19489a3349d9eaa2397ac7eb2e87f9e1e595ee0eacfff86568022c9036c058c196daa82dd47abbf24e6eab8c9c19e64d17bee9bed99d2903a4b90c3bbf5a449b5fca86e079a27fb0f67a1140e30804e60df0162258fb71814565e7614e91535db52ef346022013c75012713e90aa76705b5ec7a60dcb5dddcc99dbb107b3dd98f31ff26ce7c7824a8e7a56db4c29866acac064ea38563d6f7a45391e5167414fe9161951f30dbbc8ef1f3088b0e8ac86fe05e48196be67010":"6822bde050fcddf90ba8c398d6c973552be0f8f4b48c86dfdda2c187" + +SDV_CRYPTO_DH_CMP_API_TC001 +SDV_CRYPTO_DH_CMP_API_TC001:CRYPT_DH_RFC7919_2048:"84ADA2846AA8E9E487AE91CA237249195A854A7F5ACD3DEBB72F53F37C0D69616B84DB55B2D1247D74F34132889D53C2F367D2C5FB025CA0EEDF5D57E9951831DF9D2A856F0D3F01B848FF90AE9563A09EBBA3E9E8607562BC498E15C30D2DB9849CB131B40F8823CEFE54E461F5E730B7BAE2BD59C3BE735F10300110F0B48F60B5E2EDDFBAC028C110070164DBE51C3FAB06E354CA84757B8A11B9AEF775C4676DDAC74FE119E28CCA1BF126C04D85A8406DE95AE18B38AFE6932B29B6AFB2E0E2699AD26BC8E65CC22E2B607A1FC2C5AF966F27FB71C67E024193F186C3A874AF68B0ABC70869DCB59550B5A0C9236E2A4712A836A486780EE7D53C4FB3F1" + +SDV_CRYPTO_DH_CTRL_API_TC001 +SDV_CRYPTO_DH_CTRL_API_TC001: + +SDV_CRYPTO_DH_GET_PARA_API_TC001 +SDV_CRYPTO_DH_GET_PARA_API_TC001:"da3a8085d372437805de95b88b675122f575df976610c6a844de99f1df82a06848bf7a42f18895c97402e81118e01a00d0855d51922f434c022350861d58ddf60d65bc6941fc6064b147071a4c30426d82fc90d888f94990267c64beef8c304a4b2b26fb93724d6a9472fa16bc50c5b9b8b59afb62cfe9ea3ba042c73a6ade35":"f2ca7621eb250aa5f22cef1907011295defc50a7":"a51883e9ac0539859df3d25c716437008bb4bd8ec4786eb4bc643299daef5e3e5af5863a6ac40a597b83a27583f6a658d408825105b16d31b6ed088fc623f648fd6d95e9cefcb0745763cddf564c87bcf4ba7928e74fd6a3080481f588d535e4c026b58a21e1e5ec412ff241b436043e29173f1dc6cb943c09742de989547288" + +SDV_CRYPTO_DH_CHECK_FUNC_TC001 Key pairing consistency succeeded. +SDV_CRYPTO_DH_CHECK_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"8247776d9562de20d47bdb53a90aae76ad99d7830a0fae27bbeeb42fcab63be8":"a0f1ba2640663ffb1a6358541db85e0df7fca7c0aaac32ffefc819d743d9aae8791c060a5ba3e74b661485dbfc96824ccc2baf3805967d2ffa25269446c6aff6615aea564c41a9694780c965880c0b97ff55d05254a8ba58014e365dc72a42a9cd9d6468d0a33e50465bbce445fd98b7f0436c4f66a227b82c380173717c3164d95a994b7fe5130928db7e9e26ed69e2c294b1a91599e7ad36711318fab7cec8da86bfabba99d14e01b034e4caed3e782ac542ef54ac210c340f2f25c24ad984afe552bae80a114dbfe8ec70e043219104678ac58406c13a874bdbedfbc09fbe1a0828f2bd6166b0dbb8617b636be4f68fb9e5f2561b5a10f9dc139dde862dd6":CRYPT_SUCCESS + +SDV_CRYPTO_DH_CHECK_FUNC_TC001 Key pairing consistency fail. +SDV_CRYPTO_DH_CHECK_FUNC_TC001:"bbe983d501d1c8f328ff361a82c89b9f72be14205e1513a02489790a6744d90559905183f0edb57d1a9af4696d82c35fe2979459b9b27a7bac6dba21e9b4e964d9885ce0bf625bd44c0ec90dab62e6f323f0a1d1da836606d3771400761121b6a56ac54d38bc506a9f89d69173ee2f7745ebcf0266d5d6c994246b99880d5fe61953303d01409f4c75ae7bfdd8ea2d776d0a3a6161cb284da6c92cbe459ec5ee42cfde8668014234c363ddeb5244e25eefdd96176690c4c9d8524508c2c26a447316ad12bf90ac48d3d0658a18c96c2324614201c5e58e1d85b74072536d3c155152093805c7f58e9da0f0b9415054c67046313ec64d6f4885a46b161586a699":"34499084ea17683867394ada44d286ac8c9c755050dd7e8f1f4235b0466e40a02f55a09eb8f68bc862437f5f45b69fb12a923eff93d1a96c0a55513591cca8377ca2ddb50da0bd4adda14d8ba21e59734958b723f2673e5007abce8e4ef6df09984004652598a2939b1e151b8dbf0c8780eea40fd9e808b6ae1ecffa730d193f78c9eb7fd728391fa6ec6515d284c08c2ac11b273dc9709dd763b3e18dbb9d5e611bc783c337382aea6a6622e7045b878b3dc58c45d6502280beca16637cdc0bad352eb59bf736fc6b17f0e28cb68f816dfa498c5e706e5d5fdd4981e4752fe371b42d10b5a27e25422e7c70005efc2ec03f21026fe5008bdeee9b1a5a8a1940":"de60767d2719637b0262c14147fbdbca97b6e226f5b9cc71735564fd2fc3c103":"2e8f5b66488755966a5ecf8d23a3bdc7f34b15548712d54ab1abddb029c9e580":"a0f1ba2640663ffb1a6358541db85e0df7fca7c0aaac32ffefc819d743d9aae8791c060a5ba3e74b661485dbfc96824ccc2baf3805967d2ffa25269446c6aff6615aea564c41a9694780c965880c0b97ff55d05254a8ba58014e365dc72a42a9cd9d6468d0a33e50465bbce445fd98b7f0436c4f66a227b82c380173717c3164d95a994b7fe5130928db7e9e26ed69e2c294b1a91599e7ad36711318fab7cec8da86bfabba99d14e01b034e4caed3e782ac542ef54ac210c340f2f25c24ad984afe552bae80a114dbfe8ec70e043219104678ac58406c13a874bdbedfbc09fbe1a0828f2bd6166b0dbb8617b636be4f68fb9e5f2561b5a10f9dc139dde862dd6":CRYPT_DH_PAIRWISE_CHECK_FAIL + +SDV_CRYPTO_DH_DUP_CTX_FUNC_TC001 +SDV_CRYPTO_DH_DUP_CTX_FUNC_TC001: + +SDV_CRYPTO_DH_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_DH_GET_KEY_BITS_FUNC_TC001:CRYPT_PKEY_DH:2048:"ec6d9f4922c4b88d8d1918ced6f9eb56bcfd2bf5ab4578c0074918d9196ea9b90b9d56c23d981646953ce04afe702fa10d4190e676fa9e37330ca0aa0c79bd1f271cbcbf8f8d4e27d3078113aed0f7f9b6514f1d70e88392ce3675577cf20d29a9bac7297be781bf8b27ffa3e862b4f17a99c5881fbf473fa277219322859b2d6caf73704f4d5c2f5d6aa53e5debec4c580a717f51e1e654f1d7334900c3e7c88b08fff04e4eb3a17552b671c6ec44556008bb65bdd7ee82c1f614bd8060bafbda7f6f2fd8b53a2c2a00edf2d5b1f3283393d196567feeae5ea8d2ceeabe53fdc9edfc9a2483d9ba47c79b54da03dd884ec447b367161efd6b3cc62e3ed9977d":"aecb0bce4bfc90dadda6353533f7214ad4f9abc2e2fa67da3e7785c26f9b44c33c46caa99f1ade901d6af729d437b9500df739047de7d92f751d49a622569d5f1c882f28bd5b54e8ffe57fc43675bf58c40becb93fb988b7eea49b6fb5d63cd7f7a96572ce4e2b2da9b9e46ff70ac4e68b90684602d882363925f0b836062f7f12c3e639d09e3ea34251ff30b9ea1f4bd19199d371ef41d8017dff39cffb2b56dc2d7f20cb8ea074421d9f083e2e5a340454877459d8ee82c5d2eed9b6d6d99c245b9ab1fc76e99363eab561bf110288c470a23cc6f415bff26f3d808ebf06442da31c100fce731c282477184c1a8fd2d27bcab967e33bd3ce3d2a6dd57f3bff":"c10e58977458db8ebdd43255bf47ac20ada711211aece07523908d6b" \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/drbg/test_suite_sdv_drbg.c b/testcode/sdv/testcase/crypto/drbg/test_suite_sdv_drbg.c new file mode 100644 index 00000000..0c65c1d5 --- /dev/null +++ b/testcode/sdv/testcase/crypto/drbg/test_suite_sdv_drbg.c @@ -0,0 +1,1800 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "crypt_method.h" +#include "securec.h" +#include "bsl_errno.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_eal_rand.h" +#include "drbg_local.h" +#include "eal_md_local.h" +#include "eal_drbg_local.h" +#include "bsl_err_internal.h" +#include "bsl_err.h" +/* END_HEADER */ + +#define CTR_AES128_SEEDLEN (32) +#define AES_BLOCK_LEN (16) +#define TEST_DRBG_DATA_SIZE (256) +#define DRBG_OUTPUT_SIZE (1024) +#define DRBG_MAX_OUTPUT_SIZE (65536) +#define DRBG_MAX_ADIN_SIZE (65536) + +typedef struct { + bool entropyState; + bool nonceState; +} CallBackCtl_t; + +typedef enum { + RAND_AES128_KEYLEN = 16, + RAND_AES192_KEYLEN = 24, + RAND_AES256_KEYLEN = 32, +} RAND_AES_KeyLen; + +CallBackCtl_t g_callBackCtl = { 0 }; + +typedef struct { + CRYPT_Data *entropy; + CRYPT_Data *nonce; + CRYPT_Data *pers; + + CRYPT_Data *addin1; + CRYPT_Data *entropyPR1; + + CRYPT_Data *addin2; + CRYPT_Data *entropyPR2; + + CRYPT_Data *retBits; +} DRBG_Vec_t; + +#define DRBG_FREE(ptr) \ + do { \ + if ((ptr) != NULL) { \ + free(ptr); \ + } \ + } while (0) + +static int32_t PthreadRWLockNew(BSL_SAL_ThreadLockHandle *lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + pthread_rwlock_t *newLock; + newLock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); + if (newLock == NULL) { + return BSL_MALLOC_FAIL; + } + if (pthread_rwlock_init(newLock, NULL) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + *lock = newLock; + return BSL_SUCCESS; +} + +static void PthreadRWLockFree(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return; + } + pthread_rwlock_destroy((pthread_rwlock_t *)lock); + DRBG_FREE(lock); +} + +static int32_t PthreadRWLockReadLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_rdlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t PthreadRWLockWriteLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_wrlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t PthreadRWLockUnlock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_unlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static uint64_t PthreadGetId(void) +{ + return (uint64_t)pthread_self(); +} + +static void RegThreadFunc(void) +{ + BSL_SAL_ThreadCallback cb; + cb.pfThreadLockNew = PthreadRWLockNew; + cb.pfThreadLockFree = PthreadRWLockFree; + cb.pfThreadReadLock = PthreadRWLockReadLock; + cb.pfThreadWriteLock = PthreadRWLockWriteLock; + cb.pfThreadUnlock = PthreadRWLockUnlock; + cb.pfThreadGetId = PthreadGetId; + BSL_SAL_RegThreadCallback(&cb); +} + +static void seedCtxFree(DRBG_Vec_t *seedCtx) +{ + if (seedCtx != NULL) { + DRBG_FREE(seedCtx->entropy); + DRBG_FREE(seedCtx->entropyPR1); + DRBG_FREE(seedCtx->entropyPR2); + DRBG_FREE(seedCtx->addin1); + DRBG_FREE(seedCtx->addin2); + DRBG_FREE(seedCtx->nonce); + DRBG_FREE(seedCtx->retBits); + DRBG_FREE(seedCtx->pers); + } + free(seedCtx); +} + +static DRBG_Vec_t *seedCtxMem(void) +{ + DRBG_Vec_t *seedCtx; + + seedCtx = calloc(1u, sizeof(DRBG_Vec_t)); + ASSERT_TRUE(seedCtx != NULL); + seedCtx->entropy = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->entropy != NULL); + seedCtx->entropyPR1 = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->entropyPR1 != NULL); + seedCtx->entropyPR2 = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->entropyPR2 != NULL); + seedCtx->addin1 = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->addin1 != NULL); + seedCtx->addin2 = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->addin2 != NULL); + seedCtx->nonce = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->nonce != NULL); + seedCtx->retBits = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->retBits != NULL); + seedCtx->pers = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_TRUE(seedCtx->pers != NULL); + + return seedCtx; +exit: + seedCtxFree(seedCtx); + return NULL; +} + +/* Initializes the drbg context seed. Internally, ensure that the parameters are correct. */ +static void seedCtxCfg(DRBG_Vec_t *seedCtx, Hex *entropy, Hex *nonce, Hex *pers, Hex *addin1, Hex *entropyPR1, + Hex *addin2, Hex *entropyPR2, Hex *retBits) +{ + seedCtx->entropy->data = entropy->x; + seedCtx->entropy->len = entropy->len; + seedCtx->nonce->data = nonce->x; + seedCtx->nonce->len = nonce->len; + seedCtx->pers->data = pers->x; + seedCtx->pers->len = pers->len; + seedCtx->addin1->data = addin1->x; + seedCtx->addin1->len = addin1->len; + seedCtx->entropyPR1->data = entropyPR1->x; + seedCtx->entropyPR1->len = entropyPR1->len; + seedCtx->addin2->data = addin2->x; + seedCtx->addin2->len = addin2->len; + seedCtx->entropyPR2->data = entropyPR2->x; + seedCtx->entropyPR2->len = entropyPR2->len; + seedCtx->retBits->data = retBits->x; + seedCtx->retBits->len = retBits->len; +} + +static int32_t getEntropyError(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)strength; + (void)lenRange; + CallBackCtl_t *state = (CallBackCtl_t *)ctx; + if (state->entropyState != 0) { + entropy = NULL; + return CRYPT_DRBG_FAIL_GET_ENTROPY; + } + uint32_t entroyLen = sizeof(uint8_t) * TEST_DRBG_DATA_SIZE; + entropy->data = calloc(1u, entroyLen); + entropy->len = entroyLen; + return CRYPT_SUCCESS; +} + +static void cleanEntropyError(void *ctx, CRYPT_Data *entropy) +{ + (void)ctx; + if (entropy != NULL && entropy->data != NULL) { + free(entropy->data); + } + return; +} + +static int32_t getNonceError(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)strength; + (void)lenRange; + CallBackCtl_t *state = (CallBackCtl_t *)ctx; + if (state->nonceState != 0) { + nonce = NULL; + return CRYPT_DRBG_FAIL_GET_NONCE; + } + uint32_t nonceLen = sizeof(uint8_t) * TEST_DRBG_DATA_SIZE; + nonce->data = calloc(1u, nonceLen); + nonce->len = nonceLen; + return CRYPT_SUCCESS; +} + +static void cleanNonceError(void *ctx, CRYPT_Data *nonce) +{ + (void)ctx; + if (nonce != NULL && nonce->data != NULL) { + free(nonce->data); + } + return; +} + +static int32_t getEntropy(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)strength; + if (ctx == NULL || entropy == NULL || lenRange == NULL) { + return CRYPT_NULL_INPUT; + } + DRBG_Vec_t *seedCtx = (DRBG_Vec_t *)ctx; + + if (seedCtx->entropy->len > lenRange->max || seedCtx->entropy->len < lenRange->min) { + return CRYPT_DRBG_INVALID_LEN; + } + + entropy->data = seedCtx->entropy->data; + entropy->len = seedCtx->entropy->len; + + return CRYPT_SUCCESS; +} + +static void cleanEntropy(void *ctx, CRYPT_Data *entropy) +{ + if (ctx == NULL || entropy == NULL) { + return; + } + return; +} + +static int32_t getNonce(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)strength; + if (ctx == NULL || nonce == NULL || lenRange == NULL) { + return CRYPT_NULL_INPUT; + } + + DRBG_Vec_t *seedCtx = (DRBG_Vec_t *)ctx; + + if (seedCtx->nonce->len > lenRange->max || seedCtx->nonce->len < lenRange->min) { + return CRYPT_DRBG_INVALID_LEN; + } + + nonce->data = seedCtx->nonce->data; + nonce->len = seedCtx->nonce->len; + + return CRYPT_SUCCESS; +} + +static void cleanNonce(void *ctx, CRYPT_Data *nonce) +{ + if (ctx == NULL || nonce == NULL) { + return; + } + return; +} + +static int32_t getEntropyUnCheckPara(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)strength; + (void)lenRange; + DRBG_Vec_t *seedCtx = (DRBG_Vec_t *)ctx; + entropy->data = seedCtx->entropy->data; + entropy->len = seedCtx->entropy->len; + + return CRYPT_SUCCESS; +} + +static int32_t getNonceUnCheckPara(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)strength; + (void)lenRange; + DRBG_Vec_t *seedCtx = (DRBG_Vec_t *)ctx; + + nonce->data = seedCtx->nonce->data; + nonce->len = seedCtx->nonce->len; + + return CRYPT_SUCCESS; +} + +static void regSeedMeth(CRYPT_RandSeedMethod *seedMeth) +{ + seedMeth->getEntropy = getEntropy; + seedMeth->cleanEntropy = cleanEntropy; + seedMeth->getNonce = getNonce; + seedMeth->cleanNonce = cleanNonce; +} + +static void drbgDataInit(CRYPT_Data *data, uint32_t size) +{ + uint8_t *dataTmp = NULL; + if (size != 0) { + dataTmp = malloc(sizeof(uint8_t) * size); + if (dataTmp == NULL) { + return; + } + (void)memset_s(dataTmp, size, 0, size); + } + data->data = dataTmp; + data->len = size; +} + +static void drbgDataFree(CRYPT_Data *data) +{ + if (data != NULL) { + if (data->data != NULL) { + free(data->data); + } + } +} + +/* Mapping between RAND and specific random number generation algorithms */ +static const int g_drbgMethodMap[] = { + CRYPT_MD_SHA1, + CRYPT_MD_SHA224, + CRYPT_MD_SHA256, + CRYPT_MD_SHA384, + CRYPT_MD_SHA512, + CRYPT_MAC_HMAC_SHA1, + CRYPT_MAC_HMAC_SHA224, + CRYPT_MAC_HMAC_SHA256, + CRYPT_MAC_HMAC_SHA384, + CRYPT_MAC_HMAC_SHA512, + CRYPT_SYM_AES128, + CRYPT_SYM_AES192, + CRYPT_SYM_AES256, + CRYPT_SYM_AES128, + CRYPT_SYM_AES192, + CRYPT_SYM_AES256 +}; + +static uint32_t GetAesKeyLen(int id, uint32_t *keyLen) +{ + switch (id) { + case CRYPT_SYM_AES128: + *keyLen = RAND_AES128_KEYLEN; + break; + case CRYPT_SYM_AES192: + *keyLen = RAND_AES192_KEYLEN; + break; + case CRYPT_SYM_AES256: + *keyLen = RAND_AES256_KEYLEN; + break; + default: + return CRYPT_DRBG_ALG_NOT_SUPPORT; + } + return CRYPT_SUCCESS; +} + +static void InitSeedCtx(CRYPT_RAND_AlgId id, DRBG_Vec_t *seedCtx, CRYPT_Data *data) +{ + if (id < CRYPT_RAND_AES128_CTR || id > CRYPT_RAND_AES256_CTR) { + drbgDataInit(data, TEST_DRBG_DATA_SIZE); + seedCtx->entropy = data; + seedCtx->nonce = data; + } else { + uint32_t keyLen = 0; + GetAesKeyLen(g_drbgMethodMap[id - CRYPT_RAND_SHA1], &keyLen); + drbgDataInit(data, (AES_BLOCK_LEN + keyLen)); + seedCtx->entropy = data; + } + return; +} + +static int sdvCryptEalRandSeedAdinApiTest(uint8_t *addin, uint32_t addinLen) +{ + int ret; + uint8_t *output = NULL; + + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, &seedCtx, NULL, 0), CRYPT_SUCCESS); + + output = malloc(sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + (void)memset_s(output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE, 0, sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ret = CRYPT_EAL_RandbytesWithAdin(output, DRBG_OUTPUT_SIZE, NULL, 0); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_RandSeedWithAdin(addin, addinLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_RandSeed(); + ASSERT_EQ(ret, CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + free(output); + return ret; +} + +static int sdvCryptEalDrbgSeedAdinApiTest(uint8_t *addin, uint32_t addinLen) +{ + int ret; + uint8_t *output = NULL; + + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + void *drbgCtx = NULL; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + drbgCtx = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbgCtx != NULL); + + output = malloc(sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + (void)memset_s(output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE, 0, sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ret = CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, DRBG_OUTPUT_SIZE, NULL, 0); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_DrbgSeedWithAdin(drbgCtx, addin, addinLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_DrbgSeed(drbgCtx); + ASSERT_EQ(ret, CRYPT_SUCCESS); + +exit: + CRYPT_EAL_DrbgDeinit(drbgCtx); + drbgDataFree(&data); + free(output); + return ret; +} + +static void sdvCryptEalThreadTest(void *drbgCtx) +{ + int i = 0; + int ret; + uint8_t *output = NULL; + + output = malloc(sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + + for (i = 0; i < 100; i++) { // Perform 100 * 2 times random number generation in the thread. + ret = CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE, NULL, 0); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_DrbgSeedWithAdin(drbgCtx, NULL, 0); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE, NULL, 0); + ASSERT_EQ(ret, CRYPT_SUCCESS); + } + +exit: + DRBG_FREE(output); + return; +} + +static void sdvCryptGlobalThreadTest(void) +{ + int i = 0; + uint8_t *output = NULL; + + output = malloc(sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + + for (i = 0; i < 100; i++) { // Perform 100 times random number generation in the thread. + ASSERT_EQ(CRYPT_EAL_Randbytes(output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE), CRYPT_SUCCESS); + } + +exit: + DRBG_FREE(output); + return; +} + +/** + * @test SDV_CRYPT_DRBG_RAND_INIT_API_TC001 + * @title Use different algorithm ID to initialize the DRBG. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandInit, expected result 2. + * 3.Call CRYPT_EAL_DrbgInit, expected result 3. + * @expect + * 1.successful. + * 2.Success with or without a random number seed. + * 3.successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_INIT_API_TC001(int algId) +{ + if (IsRandAlgDisabled(algId)) { + SKIP_TEST(); + } + void *drbg = NULL; + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + seedMeth.getEntropy = getEntropy; + seedMeth.cleanEntropy = cleanEntropy; + + InitSeedCtx(algId, &seedCtx, &data); + ASSERT_EQ(CRYPT_EAL_RandInit(algId, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_SUCCESS); + CRYPT_EAL_RandDeinit(); + ASSERT_EQ(CRYPT_EAL_RandInit(algId, NULL, NULL, NULL, 0), CRYPT_SUCCESS); + CRYPT_EAL_RandDeinit(); + drbg = CRYPT_EAL_DrbgInit(algId, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbg != NULL); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_DrbgDeinit(drbg); + drbgDataFree(&data); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_INIT_API_TC002 + * @title DRBG initialization test,the value of data is 0 or 255. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandInit, expected result 2. + * 3.Call CRYPT_EAL_DrbgInit, expected result 3. + * @expect + * 1.successful. + * 2.successful. + * 3.successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_INIT_API_TC002(int agId, int value, int size) +{ + uint8_t *pers = malloc(size); + ASSERT_TRUE(pers != NULL); + ASSERT_EQ(memset_s(pers, size, value, size), 0); + void *drbg = NULL; + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, size); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + + ASSERT_EQ(CRYPT_EAL_RandInit(agId, &seedMeth, (void *)&seedCtx, pers, size), CRYPT_SUCCESS); + CRYPT_EAL_RandDeinit(); + drbg = CRYPT_EAL_DrbgInit(agId, &seedMeth, &seedCtx, pers, size); + ASSERT_TRUE(drbg != NULL); + CRYPT_EAL_DrbgDeinit(drbg); + +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + free(pers); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_INIT_API_TC003 + * @title Test the impact of persLen on DRGB initialization. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandInit, expected result 2. + * 3.Call CRYPT_EAL_DrbgInit, expected result 3. + * @expect + * 1.successful. + * 2.successful. + * 3.successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_INIT_API_TC003(int agId, int size) +{ + uint8_t *pers = malloc(TEST_DRBG_DATA_SIZE); + ASSERT_TRUE(pers != NULL); + void *drbg = NULL; + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, size); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + + ASSERT_EQ(CRYPT_EAL_RandInit(agId, &seedMeth, (void *)&seedCtx, pers, size), CRYPT_SUCCESS); + CRYPT_EAL_RandDeinit(); + drbg = CRYPT_EAL_DrbgInit(agId, &seedMeth, &seedCtx, pers, size); + ASSERT_TRUE(drbg != NULL); + CRYPT_EAL_DrbgDeinit(drbg); + +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + free(pers); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_INIT_API_TC004 + * @title DRBG is initialized repeatedly. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandInit, expected result 2. + * 3.Call CRYPT_EAL_RandInit again, expected result 3. + * @expect + * 1.successful. + * 2.successful. + * 3.return failed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_INIT_API_TC004(int algId) +{ + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + + ASSERT_EQ(CRYPT_EAL_RandInit(algId, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_RandInit(algId, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_REPEAT_INIT); + +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_INIT_API_TC005 + * @title DRBG initialization test,the configuration context parameter is empty. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandInit, expected result 2. + * 3.Call CRYPT_EAL_DrbgInit, expected result 3. + * @expect + * 1.successful. + * 2.successful. + * 3.return NULL. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_INIT_API_TC005(int algId) +{ + DRBG_Vec_t seedCtx = { 0 }; + void *drbg = NULL; + + ASSERT_EQ(CRYPT_EAL_RandInit(algId, NULL, NULL, NULL, 0), CRYPT_SUCCESS); + CRYPT_EAL_RandDeinit(); + ASSERT_EQ(CRYPT_EAL_RandInit(algId, NULL, &seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + drbg = CRYPT_EAL_DrbgInit(algId, NULL, NULL, NULL, 0); + ASSERT_TRUE(drbg != NULL); + CRYPT_EAL_DrbgDeinit(drbg); + drbg = CRYPT_EAL_DrbgInit(algId, NULL, &seedCtx, NULL, 0); + ASSERT_TRUE(drbg == NULL); +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_DrbgDeinit(drbg); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_INIT_API_TC006 + * @title DRBG initialization test,use the abnormal persLen. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandInit, expected result 2. + * 3.Call CRYPT_EAL_DrbgInit, expected result 3. + * @expect + * 1.successful. + * 2.return failed. + * 3.return NULL. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_INIT_API_TC006(int algId, int keyLen) +{ + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + uint8_t *pers = NULL; + void *drbg = NULL; + + pers = malloc(TEST_DRBG_DATA_SIZE + keyLen); + ASSERT_TRUE(pers != NULL); + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, keyLen + 16); + seedCtx.entropy = &data; + seedCtx.nonce = &data; + ASSERT_EQ(CRYPT_EAL_RandInit(algId, &seedMeth, (void *)&seedCtx, pers, keyLen + 16 + 1), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + CRYPT_EAL_RandDeinit(); + drbg = CRYPT_EAL_DrbgInit(algId, &seedMeth, &seedCtx, pers, keyLen + 16 + 1); + ASSERT_TRUE(drbg == NULL); + ASSERT_EQ(CRYPT_EAL_RandInit(algId, &seedMeth, (void *)&seedCtx, pers, keyLen + 16), CRYPT_SUCCESS); + drbg = CRYPT_EAL_DrbgInit(algId, &seedMeth, &seedCtx, pers, keyLen + 16); + ASSERT_TRUE(drbg != NULL); +exit: + CRYPT_EAL_DrbgDeinit(drbg); + CRYPT_EAL_RandDeinit(); + free(data.data); + free(pers); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC001 +* @title When the RAND is initialized and a random number has been generated, + the counter is reset when the random number is obtained from personal data. + * @precon nan + * @brief + * 1.Call sdvCryptEalRandSeedAdinApiTest,addinData is NULL, expected result 1. + * 2.Call sdvCryptEalRandSeedAdinApiTest,addinData not NULL, expected result 2. + * @expect + * 1.All operations succeeded. + * 2.All operations succeeded. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC001(void) +{ + uint8_t *addinData = NULL; + + ASSERT_EQ(sdvCryptEalRandSeedAdinApiTest(NULL, 0), CRYPT_SUCCESS); + + addinData = malloc(sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE); + ASSERT_TRUE(addinData != NULL); + ASSERT_EQ(sdvCryptEalRandSeedAdinApiTest(addinData, sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE), CRYPT_SUCCESS); + +exit: + free(addinData); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_DRBG_SEED_ADIN_API_TC001 +* @title When the DRBG is initialized and a random number has been generated, + the counter is reset when the random number is obtained from personal data. + * @precon nan + * @brief + * 1.Call sdvCryptEalDrbgSeedAdinApiTest,addinData is NULL, expected result 1. + * 2.Call sdvCryptEalDrbgSeedAdinApiTest,addinData not NULL, expected result 2. + * @expect + * 1.All operations succeeded. + * 2.All operations succeeded. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_DRBG_SEED_ADIN_API_TC001(void) +{ + uint8_t *addinData = NULL; + + ASSERT_EQ(sdvCryptEalDrbgSeedAdinApiTest(NULL, 0), CRYPT_SUCCESS); + + addinData = malloc(sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE); + ASSERT_TRUE(addinData != NULL); + ASSERT_EQ(sdvCryptEalDrbgSeedAdinApiTest(addinData, sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE), CRYPT_SUCCESS); + +exit: + free(addinData); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC002 +* @title Call random interface before CRYPT_EAL_RandInit. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_RandbytesWithAdin, expected result 1. + * 2.Call CRYPT_EAL_Randbytes, expected result 2. + * 3.Call CRYPT_EAL_RandSeedWithAdin, expected result 3. + * 4.Call CRYPT_EAL_RandSeed, expected result 4. + * @expect + * 1.return CRYPT_EAL_ERR_GLOBAL_DRBG_NULL. + * 2.return CRYPT_EAL_ERR_GLOBAL_DRBG_NULL. + * 3.return CRYPT_EAL_ERR_GLOBAL_DRBG_NULL. + * 4.return CRYPT_EAL_ERR_GLOBAL_DRBG_NULL. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC002(void) +{ + uint8_t data[TEST_DRBG_DATA_SIZE] = {0}; + ASSERT_EQ(CRYPT_EAL_RandbytesWithAdin(data, TEST_DRBG_DATA_SIZE, NULL, 0), CRYPT_EAL_ERR_GLOBAL_DRBG_NULL); + ASSERT_EQ(CRYPT_EAL_Randbytes(data, TEST_DRBG_DATA_SIZE), CRYPT_EAL_ERR_GLOBAL_DRBG_NULL); + ASSERT_EQ(CRYPT_EAL_RandSeedWithAdin(NULL, 0), CRYPT_EAL_ERR_GLOBAL_DRBG_NULL); + ASSERT_EQ(CRYPT_EAL_RandSeed(), CRYPT_EAL_ERR_GLOBAL_DRBG_NULL); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001 + * @title CRYPT_EAL_RandbytesWithAdin abnormal parameter test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_DrbgbytesWithAdin,use normal parameters, expected result 1. + * 2.Call CRYPT_EAL_DrbgbytesWithAdin,the array length is abnormal, expected result 2. + * @expect + * 1.All interface succeeded. + * 2.The interface returns an exception. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001(int algId) +{ + uint8_t *output = malloc(sizeof(uint8_t) * DRBG_MAX_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + uint8_t *addin = malloc(sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE); + ASSERT_TRUE(addin != NULL); + + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + seedCtx.entropy = &data; + seedCtx.nonce = &data; + + TestMemInit(); + CRYPT_EAL_RndCtx *drbgCtx = CRYPT_EAL_DrbgInit(algId, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbgCtx != NULL); + + memset_s(addin, DRBG_MAX_ADIN_SIZE, 0, DRBG_MAX_ADIN_SIZE); + ASSERT_EQ(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, DRBG_MAX_OUTPUT_SIZE, addin, DRBG_MAX_ADIN_SIZE), + CRYPT_SUCCESS); + + memset_s(addin, DRBG_MAX_ADIN_SIZE, 'F', DRBG_MAX_ADIN_SIZE); + ASSERT_EQ(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, DRBG_MAX_OUTPUT_SIZE, addin, DRBG_MAX_ADIN_SIZE), + CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, DRBG_MAX_OUTPUT_SIZE, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, DRBG_MAX_OUTPUT_SIZE, addin, 0), CRYPT_SUCCESS); + + memset_s(addin, DRBG_MAX_ADIN_SIZE, 0, DRBG_MAX_ADIN_SIZE); + ASSERT_NE(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, 0, addin, DRBG_MAX_ADIN_SIZE), CRYPT_SUCCESS); + ASSERT_NE(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, DRBG_MAX_OUTPUT_SIZE + 1, addin, DRBG_MAX_ADIN_SIZE), + CRYPT_SUCCESS); + ASSERT_NE(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, NULL, 0, addin, DRBG_MAX_ADIN_SIZE), CRYPT_SUCCESS); + +exit: + free(addin); + free(output); + CRYPT_EAL_DrbgDeinit(drbgCtx); + drbgDataFree(&data); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_BYTES_ERR_PARA_API_TC001 + * @title Test the CRYPT_EAL_Randbytes interface for generating random numbers. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_Randbytes,use normal parameters, expected result 2. + * 3.Call CRYPT_EAL_Randbytes,the array length is abnormal, expected result 3. + * @expect + * 1.successful. + * 2.All interface succeeded. + * 3.The interface returns an exception. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_BYTES_ERR_PARA_API_TC001(void) +{ + uint8_t *output = malloc(DRBG_MAX_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.nonce = &data; + seedCtx.entropy = &data; + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_Randbytes(output, DRBG_OUTPUT_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Randbytes(output, DRBG_MAX_OUTPUT_SIZE), CRYPT_SUCCESS); + + ASSERT_NE(CRYPT_EAL_Randbytes(output, 0), CRYPT_SUCCESS); + ASSERT_NE(CRYPT_EAL_Randbytes(output, DRBG_MAX_OUTPUT_SIZE + 1), CRYPT_SUCCESS); // MAX SIZE + 1 + ASSERT_EQ(CRYPT_EAL_Randbytes(NULL, 0), CRYPT_NULL_INPUT); +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + free(output); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_BYTES_ERR_PARA_API_TC001 + * @title Test the CRYPT_EAL_Drbgbytes interface for generating random numbers. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_Drbgbytes,use normal parameters, expected result 2. + * 3.Call CRYPT_EAL_Drbgbytes,the array length is abnormal, expected result 3. + * @expect + * 1.successful. + * 2.All interface succeeded. + * 3.The interface returns an exception. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_BYTES_ERR_PARA_API_TC001(void) +{ + uint8_t *output = malloc(DRBG_MAX_OUTPUT_SIZE + 1); + ASSERT_TRUE(output != NULL); + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + void *drbg = NULL; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.nonce = &data; + seedCtx.entropy = &data; + drbg = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbg != NULL); + + ASSERT_EQ(CRYPT_EAL_Drbgbytes(drbg, output, DRBG_OUTPUT_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Drbgbytes(drbg, output, DRBG_MAX_OUTPUT_SIZE), CRYPT_SUCCESS); + + ASSERT_NE(CRYPT_EAL_Drbgbytes(drbg, output, 0), CRYPT_SUCCESS); + ASSERT_NE(CRYPT_EAL_Drbgbytes(drbg, output, DRBG_MAX_OUTPUT_SIZE + 1), CRYPT_SUCCESS); // MAX SIZE + 1 + ASSERT_NE(CRYPT_EAL_Drbgbytes(drbg, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Drbgbytes(NULL, output, DRBG_OUTPUT_SIZE), CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_DrbgDeinit(drbg); + drbgDataFree(&data); + free(output); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_RAND_SEED_ADIN_ERR_PARA_API_TC001 + * @title Test the CRYPT_EAL_RandSeedWithAdin interface. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandSeedWithAdin,use exception parameters, expected result 2. + * @expect + * 1.successful. + * 2.The interface returns an exception. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_SEED_ADIN_ERR_PARA_API_TC001(void) +{ + uint32_t addinLen = sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE; + uint8_t *addin = malloc(addinLen); + ASSERT_TRUE(addin != NULL); + memset_s(addin, addinLen, 0, addinLen); + + TestMemInit(); + ASSERT_NE(CRYPT_EAL_RandSeedWithAdin(addin, 0), CRYPT_SUCCESS); + + ASSERT_NE(CRYPT_EAL_RandSeedWithAdin(addin, addinLen), CRYPT_SUCCESS); + + ASSERT_NE(CRYPT_EAL_RandSeedWithAdin(NULL, addinLen), CRYPT_SUCCESS); + + ASSERT_NE(CRYPT_EAL_RandSeedWithAdin(NULL, 0), CRYPT_SUCCESS); + +exit: + free(addin); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_SEED_ADIN_ERR_PARA_API_TC001 + * @title Test the CRYPT_EAL_DrbgSeedWithAdin interface. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_DrbgSeedWithAdin,use normal parameters, expected result 2. + * 3.Call CRYPT_EAL_DrbgSeedWithAdin,the array length is abnormal, expected result 3. + * @expect + * 1.successful. + * 2.All interface succeeded. + * 3.The interface returns an exception. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_SEED_ADIN_ERR_PARA_API_TC001(void) +{ + uint8_t *addin; + uint32_t addinLen = sizeof(uint8_t) * DRBG_MAX_ADIN_SIZE; + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + void *drbg = NULL; + + addin = malloc(addinLen); + ASSERT_TRUE(addin != NULL); + memset_s(addin, addinLen, 0, addinLen); + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.nonce = &data; + seedCtx.entropy = &data; + drbg = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbg != NULL); + + ASSERT_EQ(CRYPT_EAL_DrbgSeedWithAdin(drbg, addin, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_DrbgSeedWithAdin(drbg, addin, addinLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_DrbgSeedWithAdin(drbg, NULL, 0), CRYPT_SUCCESS); + + ASSERT_NE(CRYPT_EAL_DrbgSeedWithAdin(NULL, addin, addinLen), CRYPT_SUCCESS); + ASSERT_NE(CRYPT_EAL_DrbgSeedWithAdin(drbg, NULL, addinLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_DrbgDeinit(drbg); + free(addin); + free(data.data); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_SEED_ADIN_ERR_PARA_API_TC001 + * @title Random number generation test. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandbytesWithAdin num times, expected result 2. + * @expect + * 1.successful. + * 2.All interface succeeded. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001(int agId, int num, int dataSize) +{ + if (IsRandAlgDisabled(agId)) { + SKIP_TEST(); + } + int i; + uint8_t *output = NULL; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + CRYPT_Data data = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, dataSize); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + ASSERT_EQ(CRYPT_EAL_RandInit(agId, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_SUCCESS); + + output = malloc(sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + for (i = 0; i < num; i++) { + ASSERT_EQ(CRYPT_EAL_RandbytesWithAdin(output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE, NULL, 0), CRYPT_SUCCESS); + } + +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + free(output); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_NUM_FUNC_TC001 + * @title Random number generation test. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_DrbgbytesWithAdin num times, expected result 2. + * @expect + * 1.successful. + * 2.All interface succeeded. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_NUM_FUNC_TC001(int agId, int num, int dataSize) +{ + if (IsRandAlgDisabled(agId)) { + SKIP_TEST(); + } + int i; + uint8_t *output = NULL; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + CRYPT_Data data = { 0 }; + void *drbgCtx = NULL; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, dataSize); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + drbgCtx = CRYPT_EAL_DrbgInit(agId, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbgCtx != NULL); + + output = malloc(sizeof(uint8_t) * DRBG_OUTPUT_SIZE); + ASSERT_TRUE(output != NULL); + for (i = 0; i < num; i++) { + ASSERT_EQ(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, sizeof(uint8_t) * DRBG_OUTPUT_SIZE, NULL, 0), CRYPT_SUCCESS); + } + +exit: + CRYPT_EAL_DrbgDeinit(drbgCtx); + drbgDataFree(&data); + free(output); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 + * @title DRGB multi-thread function test. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Create 10 threads for execute CRYPT_EAL_Randbytes, expected result 2. + * @expect + * 1.init successful. + * 2.All threads are executed successfully.. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001(int agId) +{ + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + RegThreadFunc(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + + ASSERT_EQ(CRYPT_EAL_RandInit(agId, &seedMeth, &seedCtx, NULL, 0), CRYPT_SUCCESS); + for(uint32_t iter = 0; iter < 10; iter++) { + pthread_t thrd; + ASSERT_EQ(pthread_create(&thrd, NULL, (void *)sdvCryptGlobalThreadTest, NULL), 0); + pthread_join(thrd, NULL); + } + +exit: + CRYPT_EAL_RandDeinit(); + drbgDataFree(&data); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 + * @title Failed to obtain the entropy source test. + * @precon nan + * @brief + * 1.Register the interface that fails to obtain the entropy source, expected result 1. + * 2.Initialize the random number seed, expected result 2. + * @expect + * 1.register successful. + * 2.Failed to initialize the random number seed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001(int agId) +{ + CallBackCtl_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = getEntropyError, + .cleanEntropy = cleanEntropyError, + .getNonce = getNonceError, + .cleanNonce = cleanNonceError, + }; + + TestMemInit(); + seedCtx.entropyState = 1; + ASSERT_EQ(CRYPT_EAL_RandInit(agId, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + ASSERT_TRUE(CRYPT_EAL_DrbgInit(agId, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); +exit: + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 + * @title Failed to obtain the entropy source test. + * @precon nan + * @brief + * 1.Do not register the entropy source obtaining function., expected result 1. + * 2.Initialize the random number seed, expected result 2. + * @expect + * 1.register successful. + * 2.Failed to initialize the random number seed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001(int agId) +{ + CallBackCtl_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = NULL, + .cleanEntropy = cleanEntropyError, + .getNonce = getNonceError, + .cleanNonce = cleanNonceError, + }; + + TestMemInit(); + ASSERT_EQ(CRYPT_EAL_RandInit(agId, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + + ASSERT_TRUE(CRYPT_EAL_DrbgInit(agId, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); +exit: + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC002 + * @title To verify that the entropy data is empty and the length is 0 or a non-zero value. + * @precon nan + * @brief + * 1.Registering the callback function, expected result 1. + * 2.The entropy->data is empty and the length is 0,initialize the random number seed, expected result 2. + * 2.The entropy->data is empty and the length not 0,initialize the random number seed, expected result 3. + * @expect + * 1.Register successful. + * 2.Failed to initialize the random number seed. + * 3.Failed to initialize the random number seed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC002(void) +{ + DRBG_Vec_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = getEntropyUnCheckPara, + .cleanEntropy = cleanEntropy, + .getNonce = NULL, + .cleanNonce = NULL, + }; + + TestMemInit(); + seedCtx.entropy = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + CRYPT_EAL_RandDeinit(); + ASSERT_TRUE(CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); + seedCtx.entropy->len = 1; // Set the entropy length to 1 verify that the data is empty but the data length is not 0. + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + ASSERT_TRUE(CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); + +exit: + CRYPT_EAL_RandDeinit(); + DRBG_FREE(seedCtx.entropy); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_GETNONCE_FUNC_TC001 + * @title Test that the nonce data is empty and the length is 0 or a non-zero value. + * @precon nan + * @brief + * 1.Registering the callback function, expected result 1. + * 2.The nonce->data is empty and the length is 0,initialize the random number seed, expected result 2. + * 2.The nonce->data is empty and the length not 0,initialize the random number seed, expected result 3. + * @expect + * 1.Register successful. + * 2.Failed to initialize the random number seed. + * 3.Failed to initialize the random number seed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_GETNONCE_FUNC_TC001(void) +{ + DRBG_Vec_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = getEntropyError, + .cleanEntropy = cleanEntropyError, + .getNonce = getNonceUnCheckPara, + .cleanNonce = cleanNonceError, + }; + + TestMemInit(); + seedCtx.nonce = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + CRYPT_EAL_RandDeinit(); + ASSERT_TRUE(CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); + seedCtx.nonce->len = 1; // Set the nonce length to 1 verify that the data is empty but the data length is not 0. + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + ASSERT_TRUE(CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); + +exit: + CRYPT_EAL_RandDeinit(); + DRBG_FREE(seedCtx.nonce); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_GETNONCE_FUNC_TC002 + * @title Failed to obtain nonce during DRBG initialization. + * @precon nan + * @brief + * 1.Registering the interface for failed to obtain the nonce, expected result 1. + * 2.Initializing the DRBG, expected result 2. + * @expect + * 1.Register successful. + * 2.Failed to initialize the random number seed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_GETNONCE_FUNC_TC002(void) +{ + DRBG_Vec_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = getEntropyError, + .cleanEntropy = cleanEntropyError, + .getNonce = getNonce, + .cleanNonce = cleanNonce, + }; + + TestMemInit(); + seedCtx.nonce = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0), CRYPT_EAL_ERR_DRBG_INIT_FAIL); + + ASSERT_TRUE(CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); + +exit: + CRYPT_EAL_RandDeinit(); + DRBG_FREE(seedCtx.nonce); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_GETNONCE_FUNC_TC003 + * @title Failed to obtain nonce during DRBG instantiation. + * @precon nan + * @brief + * 1.Registering the interface for failed to obtain the nonce, expected result 1. + * 2.Initializing the DRBG, expected result 2. + * @expect + * 1.Register successful. + * 2.Failed to initialize the random number seed. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_GETNONCE_FUNC_TC003(void) +{ + CallBackCtl_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getNonce = getNonceError, + .cleanNonce = cleanNonceError, + .getEntropy = getEntropyError, + .cleanEntropy = cleanEntropyError, + }; + TestMemInit(); + + seedCtx.nonceState = 1; + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_SHA224, &seedMeth, (void *)&seedCtx, NULL, 0) != CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA224, &seedMeth, (void *)&seedCtx, NULL, 0) == NULL); +exit: + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_INSTANTIATE_FUNC_TC001 + * @title The personal data provided during DRBG instantiation is empty. + * @precon nan + * @brief + * 1.set the personal data is empty. + * 2.Initializing the DRBG, expected result 1. + * @expect + * 1.The DRBG is successfully initialized regardless of whether the data field is empty. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_INSTANTIATE_FUNC_TC001(void) +{ + CRYPT_Data *pers = NULL; + DRBG_Vec_t seedCtx = { 0 }; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = getEntropyError, + .cleanEntropy = cleanEntropyError, + .getNonce = getNonceError, + .cleanNonce = cleanNonceError, + }; + + TestMemInit(); + pers = calloc(1u, sizeof(CRYPT_Data)); + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, pers->data, pers->len), + CRYPT_SUCCESS); + CRYPT_EAL_RandDeinit(); + void *drbg = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, pers->data, pers->len); + ASSERT_TRUE(drbg != NULL); + CRYPT_EAL_DrbgDeinit(drbg); + drbg = NULL; + pers->data = calloc(DRBG_MAX_ADIN_SIZE + 1, sizeof(uint8_t)); + pers->len = DRBG_MAX_ADIN_SIZE + 1; + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, pers->data, pers->len), + CRYPT_SUCCESS); + drbg = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, &seedMeth, (void *)&seedCtx, pers->data, pers->len); + ASSERT_TRUE(drbg != NULL); + +exit: + CRYPT_EAL_DrbgDeinit(drbg); + CRYPT_EAL_RandDeinit(); + DRBG_FREE(pers->data); + DRBG_FREE(pers); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_DUP_API_TC001 + * @title Test the DRBG dup interface. + * @precon nan + * @brief + * 1.Call DRBG_NewHashCtx create ctx, expected result 1. + * 2.Call dup function,give an empty input parameter, expected result 2. + * 3.Call dup function,give the correct DRBG context, expected result 3. + * @expect + * 1.successful. + * 2.The interface returns a null pointer. + * 3.The interface returns new ctx. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_DUP_API_TC001(int algId) +{ + CRYPT_RandSeedMethod seedMeth = { 0 }; + CRYPT_Data data = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.nonce = &data; + seedCtx.entropy = &data; + CRYPT_EAL_RndCtx *drbg = CRYPT_EAL_DrbgInit(algId, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbg != NULL); + DRBG_Ctx *ctx = (DRBG_Ctx*)(drbg->ctx); + DRBG_Ctx *newCtx = ctx->meth->dup(ctx); + ASSERT_TRUE(newCtx != NULL); + ASSERT_TRUE(ctx->meth->dup(NULL) == NULL); + +exit: + CRYPT_EAL_DrbgDeinit(drbg); + DRBG_Free(newCtx); + drbgDataFree(&data); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 + * @title DRGB multi-thread function test. + * @precon nan + * @brief + * 1.Initialize 10 drbgCtx, expected result 1. + * 2.Create 10 threads for execute CRYPT_EAL_DrbgbytesWithAdin, expected result 2. + * @expect + * 1.init successful. + * 2.All threads are executed successfully.. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002(int agId) +{ + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + RegThreadFunc(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + for (uint32_t iter = 0; iter < 10; iter++) { + pthread_t thrd; + void *drbgCtx = CRYPT_EAL_DrbgInit(agId, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbgCtx != NULL); + ASSERT_EQ(pthread_create(&thrd, NULL, (void *)sdvCryptEalThreadTest, drbgCtx), 0); + pthread_join(thrd, NULL); + CRYPT_EAL_DrbgDeinit(drbgCtx); + drbgCtx = NULL; + } +exit: + drbgDataFree(&data); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 + * @title DRGB multi-thread function test. + * @precon nan + * @brief + * 1.Initialize drbgCtx, expected result 1. + * 2.Create 10 threads for execute CRYPT_EAL_DrbgbytesWithAdin, expected result 2. + * @expect + * 1.init successful. + * 2.All threads are executed successfully.. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003(int agId) +{ + CRYPT_Data data = { 0 }; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t seedCtx = { 0 }; + + TestMemInit(); + RegThreadFunc(); + regSeedMeth(&seedMeth); + drbgDataInit(&data, TEST_DRBG_DATA_SIZE); + + seedCtx.entropy = &data; + seedCtx.nonce = &data; + void *drbgCtx = CRYPT_EAL_DrbgInit(agId, &seedMeth, &seedCtx, NULL, 0); + ASSERT_TRUE(drbgCtx != NULL); + for (uint32_t iter = 0; iter < 10; iter++) { + pthread_t thrd; + ASSERT_EQ(pthread_create(&thrd, NULL, (void *)sdvCryptEalThreadTest, drbgCtx), 0); + pthread_join(thrd, NULL); + } +exit: + CRYPT_EAL_DrbgDeinit(drbgCtx); + drbgDataFree(&data); + return; +} +/* END_CASE */ + +static int32_t getEntropyWithoutSeedCtx(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)ctx; + (void)strength; + (void)lenRange; + uint32_t entroyLen = sizeof(uint8_t) * TEST_DRBG_DATA_SIZE; + entropy->data = calloc(1u, entroyLen); + entropy->len = entroyLen; + return CRYPT_SUCCESS; +} + +static int32_t getEntropyWithoutSeedCtxSpecial(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)ctx; + (void)strength; + (void)lenRange; + uint32_t entroyLen = sizeof(uint8_t) * CTR_AES128_SEEDLEN; + entropy->data = calloc(1u, entroyLen); + entropy->len = entroyLen; + return CRYPT_SUCCESS; +} + +static int32_t getNonceWithoutSeedCtx(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange) +{ + (void)ctx; + (void)strength; + (void)lenRange; + uint32_t nonceLen = sizeof(uint8_t) * TEST_DRBG_DATA_SIZE; + nonce->data = calloc(1u, nonceLen); + nonce->len = nonceLen; + return CRYPT_SUCCESS; +} + +/** + * @test SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001 + * @title Generating random numbers based on entropy sources. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandbytesWithAdin, expected result 2. + * 3.Call CRYPT_EAL_Randbytes get random numbers, expected result 3. + * @expect + * 1.init successful. + * 2.successful. + * 3.Random number generated successfully. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001(int id, Hex *entropy, Hex *nonce, Hex *pers, Hex *addin1, Hex *entropyPR1, + Hex *addin2, Hex *entropyPR2, Hex *retBits) +{ + if (IsRandAlgDisabled(id)){ + SKIP_TEST(); + } + uint8_t output[DRBG_MAX_OUTPUT_SIZE]; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t *seedCtx; + regSeedMeth(&seedMeth); + + TestMemInit(); + + seedCtx = seedCtxMem(); + ASSERT_TRUE(seedCtx != NULL); + seedCtxCfg(seedCtx, entropy, nonce, pers, addin1, entropyPR1, addin2, entropyPR2, retBits); + + ASSERT_EQ(CRYPT_EAL_RandInit((CRYPT_RAND_AlgId)id, &seedMeth, (void *)seedCtx, seedCtx->pers->data, + seedCtx->pers->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_RandbytesWithAdin(output, sizeof(uint8_t) * retBits->len, addin1->x, addin1->len), + CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_Randbytes(output, sizeof(uint8_t) * retBits->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_RandIsValidAlgId(id), true); +exit: + CRYPT_EAL_RandDeinit(); + seedCtxFree(seedCtx); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_DRBG_BYTES_FUNC_TC001 + * @title Generating random numbers based on entropy sources. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_DrbgbytesWithAdin, expected result 2. + * 3.Call CRYPT_EAL_Drbgbytes get random numbers, expected result 3. + * @expect + * 1.Init successful. + * 2.Successful. + * 3.Random number generated successfully. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_DRBG_BYTES_FUNC_TC001(int id, Hex *entropy, Hex *nonce, Hex *pers, Hex *addin1, Hex *entropyPR1, + Hex *addin2, Hex *entropyPR2, Hex *retBits) +{ + if (IsRandAlgDisabled(id)){ + SKIP_TEST(); + } + uint8_t *output = NULL; + CRYPT_RandSeedMethod seedMeth = { 0 }; + DRBG_Vec_t *seedCtx; + void *drbgCtx = NULL; + regSeedMeth(&seedMeth); + + TestMemInit(); + + seedCtx = seedCtxMem(); + ASSERT_TRUE(seedCtx != NULL); + seedCtxCfg(seedCtx, entropy, nonce, pers, addin1, entropyPR1, addin2, entropyPR2, retBits); + drbgCtx = CRYPT_EAL_DrbgInit(id, &seedMeth, seedCtx, NULL, 0); + ASSERT_TRUE(drbgCtx != NULL); + + output = malloc(sizeof(uint8_t) * retBits->len); + ASSERT_TRUE(output != NULL); + + ASSERT_EQ(CRYPT_EAL_DrbgbytesWithAdin(drbgCtx, output, sizeof(uint8_t) * retBits->len, addin1->x, addin1->len), + CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_Drbgbytes(drbgCtx, output, sizeof(uint8_t) * retBits->len), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_DrbgDeinit(drbgCtx); + seedCtxFree(seedCtx); + free(output); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 + * @title Generating random numbers based on entropy sources,the user only provides the seed method, + not the seed context. + * @precon nan + * @brief + * 1.Initialize the random number seed, expected result 1. + * 2.Call CRYPT_EAL_RandSeed, expected result 2. + * 3.Call CRYPT_EAL_Randbytes get random numbers, expected result 3. + * @expect + * 1.init successful. + * 2.successful. + * 3.Random number generated successfully. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002(int id) +{ + if (IsRandAlgDisabled(id)){ + SKIP_TEST(); + } + uint8_t output[DRBG_MAX_OUTPUT_SIZE]; + CRYPT_RandSeedMethod seedMeth = { + .getEntropy = getEntropyWithoutSeedCtx, + .cleanEntropy = cleanEntropyError, + .getNonce = getNonceWithoutSeedCtx, + .cleanNonce = cleanNonceError, + }; + + TestMemInit(); + + /* The DRBG-CTR mode requires the entropy source length of a specific length, and seedMeth needs to generate + entropy of the corresponding length.(DRBG-CTR AES128/AES192/AES256 length is 32, 40, 48). + */ + if (id == CRYPT_RAND_AES128_CTR || id == CRYPT_RAND_AES192_CTR || id == CRYPT_RAND_AES256_CTR) { + seedMeth.getEntropy = getEntropyWithoutSeedCtxSpecial; + seedMeth.getNonce = NULL; + seedMeth.cleanNonce = NULL; + } + ASSERT_EQ(CRYPT_EAL_RandInit((CRYPT_RAND_AlgId)id, &seedMeth, NULL, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_RandSeed(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Randbytes(output, DRBG_MAX_OUTPUT_SIZE), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/drbg/test_suite_sdv_drbg.data b/testcode/sdv/testcase/crypto/drbg/test_suite_sdv_drbg.data new file mode 100644 index 00000000..8266b696 --- /dev/null +++ b/testcode/sdv/testcase/crypto/drbg/test_suite_sdv_drbg.data @@ -0,0 +1,392 @@ +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_SHA1 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_SHA224 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_SHA224 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_SHA256 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_SHA256 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_SHA384 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_SHA384 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_SHA512 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_HMAC_SHA1 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_HMAC_SHA224 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_HMAC_SHA224 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_HMAC_SHA256 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_HMAC_SHA256 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_HMAC_SHA384 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_HMAC_SHA384 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_HMAC_SHA512 +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_AES128_CTR +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_AES128_CTR + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_AES192_CTR +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_AES192_CTR + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_AES256_CTR +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_AES256_CTR + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_AES192_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_AES192_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC001 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC001:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_SHA1 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_SHA1:0:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_SHA512 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_SHA512:0:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_HMAC_SHA1 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_HMAC_SHA1:0:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_HMAC_SHA512 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_HMAC_SHA512:0:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_AES128_CTR_DF:0:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_AES256_CTR_DF:0:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_SHA1 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_SHA1:255:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_SHA512 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_SHA512:255:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_HMAC_SHA1 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_HMAC_SHA1:255:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_HMAC_SHA512 +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_HMAC_SHA512:255:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_AES128_CTR_DF:255:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC002 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC002:CRYPT_RAND_AES256_CTR_DF:255:255 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC003 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC003:CRYPT_RAND_AES128_CTR_DF:32 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC003 CRYPT_RAND_AES192_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC003:CRYPT_RAND_AES192_CTR_DF:40 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC003 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC003:CRYPT_RAND_AES256_CTR_DF:48 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC003 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC003:CRYPT_RAND_AES128_CTR_DF:31 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC003 CRYPT_RAND_AES192_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC003:CRYPT_RAND_AES192_CTR_DF:39 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC003 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC003:CRYPT_RAND_AES256_CTR_DF:47 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC004 +SDV_CRYPT_DRBG_RAND_INIT_API_TC004:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC004 +SDV_CRYPT_DRBG_RAND_INIT_API_TC004:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC004 +SDV_CRYPT_DRBG_RAND_INIT_API_TC004:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC004 +SDV_CRYPT_DRBG_RAND_INIT_API_TC004:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC004 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC004:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC004 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_RAND_INIT_API_TC004:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC005 +SDV_CRYPT_DRBG_RAND_INIT_API_TC005:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC005 +SDV_CRYPT_DRBG_RAND_INIT_API_TC005:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC005 +SDV_CRYPT_DRBG_RAND_INIT_API_TC005:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC005 +SDV_CRYPT_DRBG_RAND_INIT_API_TC005:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC005 +SDV_CRYPT_DRBG_RAND_INIT_API_TC005:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC005 +SDV_CRYPT_DRBG_RAND_INIT_API_TC005:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_RAND_INIT_API_TC006 +SDV_CRYPT_DRBG_RAND_INIT_API_TC006:CRYPT_RAND_AES128_CTR:16 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC006 +SDV_CRYPT_DRBG_RAND_INIT_API_TC006:CRYPT_RAND_AES192_CTR:24 + +SDV_CRYPT_DRBG_RAND_INIT_API_TC006 +SDV_CRYPT_DRBG_RAND_INIT_API_TC006:CRYPT_RAND_AES256_CTR:32 + +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001:CRYPT_RAND_SHA256 + +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001:CRYPT_RAND_AES192_CTR_DF + +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_RAND_BYTES_ADIN_ERR_PARA_API_TC001:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_RAND_BYTES_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_RAND_BYTES_ERR_PARA_API_TC001: + +SDV_CRYPT_DRBG_BYTES_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_BYTES_ERR_PARA_API_TC001: + +SDV_CRYPT_DRBG_RAND_SEED_ADIN_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_RAND_SEED_ADIN_ERR_PARA_API_TC001: + +SDV_CRYPT_DRBG_SEED_ADIN_ERR_PARA_API_TC001 +SDV_CRYPT_DRBG_SEED_ADIN_ERR_PARA_API_TC001: + +SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC001 +SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC001: + +SDV_CRYPT_DRBG_DRBG_SEED_ADIN_API_TC001 +SDV_CRYPT_DRBG_DRBG_SEED_ADIN_API_TC001: + +SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC002 +SDV_CRYPT_DRBG_RAND_SEED_ADIN_API_TC002: + +SDV_CRYPT_DRBG_DUP_API_TC001 SHA256 +SDV_CRYPT_DRBG_DUP_API_TC001:CRYPT_RAND_SHA256 + +SDV_CRYPT_DRBG_DUP_API_TC001 HMAC_SHA256 +SDV_CRYPT_DRBG_DUP_API_TC001:CRYPT_RAND_HMAC_SHA256 + +SDV_CRYPT_DRBG_DUP_API_TC001 AES256_CTR_DF +SDV_CRYPT_DRBG_DUP_API_TC001:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001:CRYPT_RAND_SHA1:10:256 + +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001:CRYPT_RAND_HMAC_SHA1:10:256 + +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001:CRYPT_RAND_AES128_CTR_DF:10:32 + +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_RAND_NUM_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF:10001:48 + +SDV_CRYPT_DRBG_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_NUM_FUNC_TC001:CRYPT_RAND_SHA1:10:256 + +SDV_CRYPT_DRBG_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_NUM_FUNC_TC001:CRYPT_RAND_HMAC_SHA1:10001:256 + +SDV_CRYPT_DRBG_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_NUM_FUNC_TC001:CRYPT_RAND_AES128_CTR_DF:10001:256 + +SDV_CRYPT_DRBG_NUM_FUNC_TC001 +SDV_CRYPT_DRBG_NUM_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF:10:256 + +SDV_CRYPT_DRBG_NUM_FUNC_TC001 CRYPT_RAND_AES256_CTR:10 +SDV_CRYPT_DRBG_NUM_FUNC_TC001:CRYPT_RAND_AES256_CTR:10:48 + +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_CLEANENTROPY_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC002 +SDV_CRYPT_DRBG_GETENTROPY_FUNC_TC002: + +SDV_CRYPT_DRBG_GETNONCE_FUNC_TC001 +SDV_CRYPT_DRBG_GETNONCE_FUNC_TC001: + +SDV_CRYPT_DRBG_GETNONCE_FUNC_TC002 +SDV_CRYPT_DRBG_GETNONCE_FUNC_TC002: + +SDV_CRYPT_DRBG_GETNONCE_FUNC_TC003 +SDV_CRYPT_DRBG_GETNONCE_FUNC_TC003: + +SDV_CRYPT_DRBG_INSTANTIATE_FUNC_TC001 +SDV_CRYPT_DRBG_INSTANTIATE_FUNC_TC001: + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC002:CRYPT_RAND_AES256_CTR_DF + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003:CRYPT_RAND_SHA1 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003:CRYPT_RAND_SHA512 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003:CRYPT_RAND_HMAC_SHA512 + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 CRYPT_RAND_AES128_CTR_DF +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003:CRYPT_RAND_AES128_CTR_DF + +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003 CRYPT_RAND_AES256_CTR_DF +SDV_CRYPT_DRBG_PTHREAD_FUNC_TC003:CRYPT_RAND_AES256_CTR_DF + +Vector Test for NIST Hash_DRBG.rsp #1 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_SHA1:"212956390783381dbfc6362dd0da9a09":"5280987fc5e27a49":"5280987fc5e27a49":"5280987fc5e27a49":"2edb396eeb8960f77943c2a59075a786":"5280987fc5e27a49":"30b565b63a5012676940d3ef17d9e996":"ca50ec95c7c38a58129fd37523d1f2598ce6de98a6f107724c5546beadaa5bafbf1e62d274843f1107c345b1288163f1dd24afb27a63d39ee2aa770dfca668eb134abe080578b2f8d1a3a899f5a00af7" + +Vector Test for NIST Hash_DRBG.rsp #2 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_SHA224:"5c15931a3b7ebf15a91c57400ef17a1fb4908be2dd4eacf8":"f7509949b418907fbf323436":"f7509949b418907fbf323436":"f7509949b418907fbf323436":"89e54e748721b0052f0a6331afce09628b82c3e014cbaf0e":"f7509949b418907fbf323436":"c519812b53cbea72900306a24b59a06e573de63071d427b0":"4b43a14b3b7d076f463e66df26269596e34d8bcc7a683d63baf0b2be97ae3d9764b6f91349184a9eafda8859d33c632db2250bff95497adc8250d6ef7d70b919fd6591bda1b7311bde7969665f3b9d9fcbb023db75d55ad177c79979a15dd2056f2265839192ab300921e3bb53076895" + +Vector Test for NIST Hash_DRBG.rsp #3 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_SHA256:"4a4e743f877ea6e94e545a56ccb5a1f99efc7eb1e8191929152a56d41dc92425":"33b7ab9356acf7da03d3d6773b61f8d9":"33b7ab9356acf7da03d3d6773b61f8d9":"33b7ab9356acf7da03d3d6773b61f8d9":"2e148f9269d00a162e897a91f3aca46fed1e2adbab4f848218f288650dab8b1e":"33b7ab9356acf7da03d3d6773b61f8d9":"2566475353ec8ced47d03b76fca779d0668c95136cf7866259d9e3b7e0d1f74f":"924b74d6ba3d56dffc0de00711e3010ccbdb730718743f0cc0631931434b0ffc4ad6d5ef96fd81f16e51a10206f674987d1b52f0cf15d294c98bc4a877f4716c0ff2c2484d3f057eafd09154874aa2a213a2641da1a3d7be6988616b6bb483cd9213ed750858ce85811b8f708dcfd607b383eda845c87f60084db7a0500643b1" + +Vector Test for NIST Hash_DRBG.rsp #4 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_SHA384:"836ea258e97db514dcfaccc24dfe63708027a33074e8d41443b745703b345c81":"0f04035844f6aae9444486511d129f7c":"0f04035844f6aae9444486511d129f7c":"0f04035844f6aae9444486511d129f7c":"84395a07713093916cf9c2463ab9b99831273bcd5d21f30c1ae47aa6218f7ca2":"0f04035844f6aae9444486511d129f7c":"ed21839bfe8027478872d04b68a276d841fdd87cbf58a3b77fd8ba3d2853940c":"87a918cb5eb0c5a0ae3ed3031d2a39904af0b33814b7f3e2188e057cb2b2c44144a5facb094c334e6ec70d4366f8615ccf98cdf3392d0d644159f721daf2a77ad7dbec72de6a59360ecd4fad6015e59170adb96ada2caf3951df3c6fd8936c7d9862d9b81c84a9a1e6df423d743d157ee50aa8b92fedd42052ce4f17cf629eae7dc2a2d9f48d7373f30ce53dfe2e2e5febe9718a8787d3e1f3941d0e9c4723332545d1a99e946cf5e3b335f95491226982891de75f3167d880cada8a1e76b20e" + +Vector Test for NIST Hash_DRBG.rsp #5 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_SHA512:"73c9b115b7efb0a63244d7493ae5820599d7cee5ca054db2f7269ba7f621bdca":"c204e6de789b0394fbbe6663466efcea":"c204e6de789b0394fbbe6663466efcea":"c204e6de789b0394fbbe6663466efcea":"cfcef3776b37649a7f6d2b48f443da79a2f2f81d04f3af9853a9e696c4487440":"c204e6de789b0394fbbe6663466efcea":"d0638e28cae8d1c0f57209d677d889d195a672023cb8ade39f794989e1daee34":"04744d1d42601995fa3b101ded3d2531cbf45afd83120d58eb26594a863bd8318311b08d3df4c571a9c26dff63a3e9913a9a17a7c455186fdfdd90c664a84b73a1106a5a82f741bd4c7a48bd046c268d8919efc941f8b45a3c3d89cf37141b5c41b10ff543a6926272d623ad8eccd026552090adcfacb124f47c4ad62be90ea5a0a7087d81458445813af88ffb5a8c3519f977131cc851cb4454b0a756c8373f052382435ab934718c955177363389c06b0b5073478e84d253ff02a3f1bef1bbf1338f77f92f029f638a4691c48c470d30d230f007f545e022f66c78a130697814aa55d2000a49553bef35fab5808e2f3cbb38c405611fa81444124e3f89e1e8" + +Vector Test for NIST HMAC_DRBG.rsp #1 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_HMAC_SHA1:"a0c9ab58f1e2e5a4de3ebd4ff73e9c5b":"64efd8ca028cf811":"64efd8ca028cf811":"64efd8ca028cf811":"48a584fe69ab5aee42aa4d42176099d4":"64efd8ca028cf811":"5e1397dc404d86a37bf55954756951e4":"9a00a2d00ed59bfe31ecb1399b608148d1969d250d3c1e94101098129325cab8fccc2d54731970c0107aa4892519955e4bc6001d7f4e6a2bf8a301ab46055c09a67188f1a740eef3e15c029b44af0344" + +Vector Test for NIST HMAC_DRBG.rsp #2 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_HMAC_SHA224:"f3a709bb47a36838cb998fb6986ff074c57932a669670570":"ff6cd1b202ee1da014a011f4":"ff6cd1b202ee1da014a011f4":"ff6cd1b202ee1da014a011f4":"3fc02c51ffcb4048cc060763f2c58de2edd494275da14118":"ff6cd1b202ee1da014a011f4":"c9cb7fd50475c66cc7e792406213a7d00cf7623d931a5947":"bbe3daefa61fe302bdaa6d4d379680acfd0d456b5d35f137c145b72626f2fcf39fdf7f3708d9e88c1710408a3d7ece3b0261ff538846fd5452149960215c0c22beafe6cd24a7c392d5845774b87528912c322119a2adf4d35a0ba61dd36ffc8a7e7475afec58ad4a8cf343afb677f087" + +Vector Test for NIST HMAC_DRBG.rsp #3 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_HMAC_SHA256:"9969e54b4703ff31785b879a7e5c0eae0d3e309559e9fe96b0676d49d591ea4d":"07d20d46d064757d3023cac2376127ab":"07d20d46d064757d3023cac2376127ab":"07d20d46d064757d3023cac2376127ab":"c60f2999100f738c10f74792676a3fc4a262d13721798046e29a295181569f54":"07d20d46d064757d3023cac2376127ab":"c11d4524c9071bd3096015fcf7bc24a607f22fa065c937658a2a77a8699089f4":"abc015856094803a938dffd20da94843870ef935b82cfec17706b8f551b8385044235dd44b599f94b39be78dd476e0cf11309c995a7334e0a78b37bc9586235086fa3b637ba91cf8fb65efa22a589c137531aa7b2d4e2607aac27292b01c698e6e01ae679eb87c01a89c7422d4372d6d754ababb4bf896fcb1cd09d692d0283f" + +Vector Test for NIST HMAC_DRBG.rsp #4 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_HMAC_SHA384:"51ec4987ddacbcf6348e4a891fa571c6e3aec02879eb0181a121a4846344a687":"cdff9798761875320256e5a59bc94663":"cdff9798761875320256e5a59bc94663":"cdff9798761875320256e5a59bc94663":"faab8864cc0bb1e64343c0b978fcc0d6e84d0d17c1c1f4093fac3b4c01837c6b":"cdff9798761875320256e5a59bc94663":"37d189d7608f0c335eb38fe1f43573e0c525093f60ef618bab297b8a4d9d8c16":"ade04730059471b1829bec8dfbb0ec708be7b4e77d688ce7cfba9ddde059a52f969407291440aa79492f827fe1a2f6568989fd36b4fd84e6699152536bff15388af319fb306f07de4309eb92ba3da5f7007948335993698d398bac42029912bec6ba39226c2bf238733b5081aa0a2ca392a719385184be619d9ca56771d8e3716a46cfb339f93ff48abe406ef788db2ada45ab5fcb7f689bd801a5ccad855b52cd4bf1d6e338f2c3eac94ce9fdd0dd06632d01ded3753e87957e8569a67eccad" + +Vector Test for NIST HMAC_DRBG.rsp #5 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_HMAC_SHA512:"64a8afb71975256b6196f3f93038ba8b7a4d7089f7f268134cb3f5926868e4d1":"04c60b44fbf3bc198f4bc58bf1260d12":"04c60b44fbf3bc198f4bc58bf1260d12":"04c60b44fbf3bc198f4bc58bf1260d12":"3a5aaf8749136a86c4e5aba81692d587133d29d3b7a63fa6204ed84e93be6aeb":"04c60b44fbf3bc198f4bc58bf1260d12":"f50472d313ef5797d1a290a7cae086052b57e8d5a20ed22ec7702dd424d935ea":"4f61f6b5d46ea351dc6f8ff55bcb915d998c8e871b5e122dd95196da241c49a1170b1fc16ffa31a6dc4f0c4068ecc6e5cc0fa6966aedf72bcb19e666b191979f22580b6505c09a784e76f58d30af3abcbe840497ad88621a893ffe13af6aef0f8276f9540068943bb6bc51498a465129880df4c517f7fe70ec239c055102a78b8b0f26d36bc2634a0e61a1431850980c258326197cc80d07c3cafc49a20316a0fa2703f850b66ce274e839d6dddba4d3e744306d768b7437ec9c54ed864c7bca4ea8d0987d815e64f685e0726eb4223aa5eac1a0979fb335248ee59819c36c7c94dadf14474c7e2f10678da59f255474ea50c3ed5ccf86a399ba7f54ae96bff0" + +Vector Test for NIST CTR_DRBG.rsp #1 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_AES128_CTR:"f1893be2bc86c80d6422f3d586c0a8ce9bad6486f23123f02ba01403384b83fe":"":"":"":"79dde8e1502818df744e1afe8e5ecb3b8d19365182c7957260d1794e54912620":"":"cf684fd0eebba77901efcbe3cc5297ba9f04367fd54fe6af9463ad2ebcfedbf4":"fdb97f0eb27279b8d885f2462e8968dc4c9266f81167359d89df4c327642eae1b3131f90d64c1b5a0e71950284fc3fd026201094e8ab3f3760184d7184c90a34" + +Vector Test for NIST CTR_DRBG.rsp #2 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_AES192_CTR:"eddb79f0fb5a5dd6b5e46112a7d705270ceecefdcc2e8db2721c42f3e6358683610d40d0f67092cc":"":"":"":"7e963554e90e20a6d851ba8678552d3cc4e8ad738dba17fde8b3c51f65f2c05b6b3825d8c4fa8e9c":"":"42ca453ebdc7e392156718a856d4fdedf324aab01156431e49edcb44d916906d789fc2e0d8d52797":"e198bfc6cc3a026a143d3560b70b69832a4d0864ac2b97134bb64876de80b085f05483e82ad4b50defd37f77be7e1a0310b71ff7df6e7fe0c22dc5a77806e094" + +Vector Test for NIST CTR_DRBG.rsp #3 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_AES256_CTR:"faf346c9c8afbc5ab6e33ce492247fac6db9a7ba4297557f587a42563ddf56c90e41c6afb56233815b74e091bac7d8e5":"":"":"":"dfc111252d7146922713720ae1e348a07ae403b5238fefb4e8592f6f6cc4a61c94828db84c6faecd1502261008011f2c":"":"4528bac5b99c772347d44f4ece79bc811ca8ebea9483fa5f5040c02f77069dad1aec7adaa8a9a6a9ddabab045d328a90":"bc013dc891db12c34ad11944805bf13dfd67ff2c23176d83f5b396b69e400042252e11816c3095421137181a5d0ee37c83a339c58d080946ca90aa437d50d9cf" + +Vector Test for NIST CTR_DRBG.rsp #4 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_AES128_CTR_DF:"5d4041942bcf68864a4997d8171f1f9f":"d4f1f4ae08bcb3e1":"d4f1f4ae08bcb3e1":"d4f1f4ae08bcb3e1":"ef55a769b7eaf03fe082029bb32a2b9d":"d4f1f4ae08bcb3e1":"8239e865c0a42e14b964b9c09de85a20":"4155320287eedcf7d484c2c2a1e2eb64b9c9ce77c87202a1ae1616c7a5cfd1c687c7a0bfcc85bda48fdd4629fd330c22d0a76076f88fc7cd04037ee06b7af602" + +Vector Test for NIST CTR_DRBG.rsp #5 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_AES192_CTR_DF:"965fa6a2c4009c045cff728f244238262508bf008dccef30":"1d22591b097873d124c3f8c408f89161":"1d22591b097873d124c3f8c408f89161":"1d22591b097873d124c3f8c408f89161":"9718b88042a4b60767cae0ffc797e688b0fe3819db2a4bcb":"1d22591b097873d124c3f8c408f89161":"73e3f0fdf380e5e6126ff9f3adb34ff5bcc45fba0ce1d248":"909fd2c971921c77322e1df273a07d19f527133e56a9be388c298ca6830873d1e847b8cc654dd3c57c1c8b25fd3909be847c1a281108940fe7f06d9db60ad7b4" + +Vector Test for NIST CTR_DRBG.rsp #6 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF:"16a1f035388cd8d956026e3b0117cb524dd3eb563f9a7720bb7dcb0fc6fbe743":"a2d015f22d854e29de278d910c573de5":"a2d015f22d854e29de278d910c573de5":"a2d015f22d854e29de278d910c573de5":"cf140bcd4d7130e7e3ea14046c56442b57c43b34ad219553e7105c18f6e561af":"a2d015f22d854e29de278d910c573de5":"e27c9f0be60d82d6cc474efb7fc737b16a6895d9a3a45b971d19b743c1a4ac8f":"b4e8395bcb7503410a94633f70e9904a5b30e62c35bc6dd2a03496c4a49932e184fbffdbcf1de1c72c50d36dc2ae8f04f40f96aae159c3fb816ca16df99b6c3e" + +Vector Test for NIST Hash_DRBG.rsp #1 +SDV_CRYPT_EAL_DRBG_BYTES_FUNC_TC001:CRYPT_RAND_SHA256:"4a4e743f877ea6e94e545a56ccb5a1f99efc7eb1e8191929152a56d41dc92425":"33b7ab9356acf7da03d3d6773b61f8d9":"":"":"2e148f9269d00a162e897a91f3aca46fed1e2adbab4f848218f288650dab8b1e":"":"2566475353ec8ced47d03b76fca779d0668c95136cf7866259d9e3b7e0d1f74f":"924b74d6ba3d56dffc0de00711e3010ccbdb730718743f0cc0631931434b0ffc4ad6d5ef96fd81f16e51a10206f674987d1b52f0cf15d294c98bc4a877f4716c0ff2c2484d3f057eafd09154874aa2a213a2641da1a3d7be6988616b6bb483cd9213ed750858ce85811b8f708dcfd607b383eda845c87f60084db7a0500643b1" + +Vector Test for NIST HMAC_DRBG.rsp #1 +SDV_CRYPT_EAL_DRBG_BYTES_FUNC_TC001:CRYPT_RAND_SHA256:"9969e54b4703ff31785b879a7e5c0eae0d3e309559e9fe96b0676d49d591ea4d":"07d20d46d064757d3023cac2376127ab":"":"":"c60f2999100f738c10f74792676a3fc4a262d13721798046e29a295181569f54":"":"c11d4524c9071bd3096015fcf7bc24a607f22fa065c937658a2a77a8699089f4":"abc015856094803a938dffd20da94843870ef935b82cfec17706b8f551b8385044235dd44b599f94b39be78dd476e0cf11309c995a7334e0a78b37bc9586235086fa3b637ba91cf8fb65efa22a589c137531aa7b2d4e2607aac27292b01c698e6e01ae679eb87c01a89c7422d4372d6d754ababb4bf896fcb1cd09d692d0283f" + +Vector Test for NIST CTR_DRBG.rsp #1 +SDV_CRYPT_EAL_DRBG_BYTES_FUNC_TC001:CRYPT_RAND_AES256_CTR_DF:"a31337e0cbf2ee3e8d1d39324c978e714b5acc678920d5839fe95477ca3b8741":"a7f8b770a506acfc79b2c431660d310f":"":"5494597f0e8644d6028495c6599911cf30fc96a1b92a3a5dc862fecfc353c43d":"c2e44d8b2c97f4c14e39c8137cc62818f1a223dde1dfe9def8672c2a6fab8c04":"e7635b6f9e63c08942c4b5c86b5e60bbe3e89ea3809fb3939985c93eedd17f8d":"923405e7878b3e203cb531f688c10725d7a55edacc2b9f195f7137080b278ea1":"5dbd55ed2f6d6c1749096b40f6a97d9cf42c0841b27ce0efd7433110d8118955c8cefeb9db8e1c7961eb3f517f2047d27281261760a5e2b24535bb6f565bb971" + +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 #1 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002:CRYPT_RAND_SHA1 + +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 #2 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002:CRYPT_RAND_SHA224 + +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 #3 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002:CRYPT_RAND_HMAC_SHA1 + +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 #4 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002:CRYPT_RAND_AES128_CTR + +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002 #5 +SDV_CRYPT_EAL_RAND_BYTES_FUNC_TC002:CRYPT_RAND_AES128_CTR_DF \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/dsa/test_suite_sdv_eal_dsa.c b/testcode/sdv/testcase/crypto/dsa/test_suite_sdv_eal_dsa.c new file mode 100644 index 00000000..21f70d49 --- /dev/null +++ b/testcode/sdv/testcase/crypto/dsa/test_suite_sdv_eal_dsa.c @@ -0,0 +1,753 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "securec.h" +#include "bsl_err.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_dsa.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_rand.h" +#include "crypt_bn.h" +#include "eal_pkey_local.h" +#include "stub_replace.h" +#include "crypt_util_rand.h" + +#include "crypt_encode.h" +#include "crypt_eal_md.h" +/* END_HEADER */ + +#define SUCCESS 0 +#define ERROR (-1) +#define BITS_OF_BYTE 8 +static uint8_t g_kRandBuf[64]; +static uint32_t g_kRandBufLen = 0; + +int32_t STUB_RandRangeK(BN_BigNum *r, const BN_BigNum *p) +{ + (void)p; + BN_Bin2Bn(r, g_kRandBuf, g_kRandBufLen); + return CRYPT_SUCCESS; +} + +int Compute_Md(CRYPT_MD_AlgId mdId, Hex *msgIn, Hex *mdOut) +{ + uint32_t outLen; + CRYPT_EAL_MdCTX *mdCtx = NULL; + uint32_t mdOutLen = CRYPT_EAL_MdGetDigestSize(mdId); + ASSERT_TRUE(mdOutLen != 0); + mdOut->x = (uint8_t *)malloc(mdOutLen); + ASSERT_TRUE(mdOut->x != NULL); + mdOut->len = mdOutLen; + outLen = mdOutLen; + mdCtx = CRYPT_EAL_MdNewCtx(mdId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdNewCtx", mdCtx != NULL); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdInit", CRYPT_EAL_MdInit(mdCtx) == 0); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdUpdate", CRYPT_EAL_MdUpdate(mdCtx, msgIn->x, msgIn->len) == 0); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdFinal", CRYPT_EAL_MdFinal(mdCtx, mdOut->x, &outLen) == 0); + mdOut->len = outLen; + CRYPT_EAL_MdFreeCtx(mdCtx); + return SUCCESS; + +exit: + CRYPT_EAL_MdFreeCtx(mdCtx); + free(mdOut->x); + mdOut->x = NULL; + return ERROR; +} + +void Set_DSA_Para( + CRYPT_EAL_PkeyPara *para, CRYPT_EAL_PkeyPrv *prv, CRYPT_EAL_PkeyPub *pub, Hex *P, Hex *Q, Hex *G, Hex *X, Hex *Y) +{ + para->id = CRYPT_PKEY_DSA; + para->para.dsaPara.p = P->x; + para->para.dsaPara.pLen = P->len; + para->para.dsaPara.q = Q->x; + para->para.dsaPara.qLen = Q->len; + para->para.dsaPara.g = G->x; + para->para.dsaPara.gLen = G->len; + + if (prv && X) { + prv->id = CRYPT_PKEY_DSA; + prv->key.dsaPrv.data = X->x; + prv->key.dsaPrv.len = X->len; + } + if (pub && Y) { + pub->id = CRYPT_PKEY_DSA; + pub->key.dsaPub.data = Y->x; + pub->key.dsaPub.len = Y->len; + } +} + +static void Set_DSA_Pub(CRYPT_EAL_PkeyPub *pub, uint8_t *key, uint32_t keyLen) +{ + pub->id = CRYPT_PKEY_DSA; + pub->key.dsaPub.data = key; + pub->key.dsaPub.len = keyLen; +} + +static void Set_DSA_Prv(CRYPT_EAL_PkeyPrv *prv, uint8_t *key, uint32_t keyLen) +{ + prv->id = CRYPT_PKEY_DSA; + prv->key.dsaPrv.data = key; + prv->key.dsaPrv.len = keyLen; +} + +int SignEncode( + DSA_Sign *dsaSign, uint8_t *vectorSign, uint32_t *vectorSignLen, Hex *R, Hex *S, BN_BigNum **bn_r, BN_BigNum **bn_s) +{ + *bn_r = BN_Create(R->len * BITS_OF_BYTE); + *bn_s = BN_Create(S->len * BITS_OF_BYTE); + ASSERT_EQ(BN_Bin2Bn(*bn_r, R->x, R->len), CRYPT_SUCCESS); + ASSERT_EQ(BN_Bin2Bn(*bn_s, S->x, S->len), CRYPT_SUCCESS); + dsaSign->r = *bn_r; + dsaSign->s = *bn_s; + ASSERT_EQ(ASN1_SignDataEncode(dsaSign, vectorSign, vectorSignLen), CRYPT_SUCCESS); + return CRYPT_SUCCESS; + +exit: + return ERROR; +} + +/** + * @test SDV_CRYPTO_DSA_SET_PARA_API_TC001 + * @title DSA: CRYPT_EAL_PkeySetPara test. + * @precon Registering memory-related functions. + * Dsa para vertors. + * @brief + * 1. Create the context of the dsa algorithm, expected result 1. + * 2. CRYPT_EAL_PkeySetPara: para = NULL, expected result 2. + * 3. CRYPT_EAL_PkeySetPara, expected result 3, the parameters are as follows: + * (1) p != NULL, pLen = 0 + * (2) p = NULL, pLen != 0 + * (3) q != NULL, qLen = 0 + * (4) q = NULL, qLen != 0 + * (5) g != NULL, gLen = 0 + * (6) g = NULL, gLen != 0 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_EAL_ERR_NEW_PARA_FAIL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_SET_PARA_API_TC001(Hex *p, Hex *q, Hex *g) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + uint8_t tmp[1]; + CRYPT_EAL_PkeyPara para; + para.id = CRYPT_PKEY_DSA; + para.para.dsaPara.p = p->x; + para.para.dsaPara.pLen = p->len; + para.para.dsaPara.q = q->x; + para.para.dsaPara.qLen = q->len; + para.para.dsaPara.g = g->x; + para.para.dsaPara.gLen = g->len; + + TestMemInit(); + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, NULL), CRYPT_NULL_INPUT); + + if (p->x == NULL) { + para.para.dsaPara.p = tmp; + ASSERT_TRUE_AND_LOG("p != NULL, pLen = 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dsaPara.p = p->x; + para.para.dsaPara.pLen = 128; + ASSERT_TRUE_AND_LOG("p = NULL, pLen != 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + para.para.dsaPara.pLen = p->len; + } + if (q->x == NULL) { + para.para.dsaPara.q = tmp; + ASSERT_TRUE_AND_LOG("q != NULL, qLen = 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dsaPara.q = q->x; + para.para.dsaPara.qLen = 20; + ASSERT_TRUE_AND_LOG("q == NULL, qLen != 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + para.para.dsaPara.qLen = q->len; + } + if (g->x == NULL) { + para.para.dsaPara.g = tmp; + ASSERT_TRUE_AND_LOG("g != NULL, gLen = 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.dsaPara.g = g->x; + para.para.dsaPara.gLen = 128; + ASSERT_TRUE_AND_LOG("g!= NULL, gLen != 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + } +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_CMP_API_TC001 + * @title DSA: CRYPT_EAL_PkeyCmp test. + * @precon Registering memory-related functions. + * Dsa para vertors. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the dsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set public key and para for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set public key and para for ctx2, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_DSA_ERR_KEY_INFO + * 3. CRYPT_SUCCESS + * 4. CRYPT_DSA_ERR_KEY_INFO + * 5. CRYPT_SUCCESS + * 6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_CMP_API_TC001(Hex *p, Hex *q, Hex *g, Hex *y) +{ + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_DSA_Para(¶, NULL, &pub, p, q, g, NULL, y); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DSA_ERR_KEY_INFO); // no key and no para + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(ctx1, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_DSA_ERR_KEY_INFO); // ctx2 no pubkey + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(ctx2, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_CTRL_API_TC001 + * @title DSA: CRYPT_EAL_PkeyCtrl test. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context(ctx) of the dsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method: + * (1) val = NULL, expected result 2 + * (2) len = 0, expected result 3 + * (3) opt = CRYPT_CTRL_SET_RSA_PADDING, expected result 4 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_DSA_UNSUPPORTED_CTRL_OPTION + * 4. CRYPT_DSA_UNSUPPORTED_CTRL_OPTION + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_CTRL_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *ctx = NULL; + int32_t ref = 1; + + TestMemInit(); + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_UP_REFERENCES, NULL, sizeof(uint32_t)), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_UP_REFERENCES, &ref, 0), CRYPT_DSA_UNSUPPORTED_CTRL_OPTION); + ASSERT_EQ( + CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_PADDING, &ref, sizeof(int32_t)), CRYPT_DSA_UNSUPPORTED_CTRL_OPTION); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_GET_PARA_API_TC001 + * @title DSA: CRYPT_EAL_PkeyGetPara test. + * @precon Registering memory-related functions. + * Dsa para vertors. + * @brief + * 1. Create the contexts of the dsa algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeySetPara method with correct parameters, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method: para.id != pkey.id, expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPara method: pkey=NULL or para=NULL, expected result 4 + * 5. Call the CRYPT_EAL_PkeySetPara method with correct parameters, expected result 5 + * 6. Check whether the configured parameters are the same as the obtained parameters, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_EAL_ERR_ALGID + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_SUCCESS + * 6. Parameters are equal. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_GET_PARA_API_TC001(Hex *p, Hex *q, Hex *g) +{ + uint8_t buf_p[1030] = {0}; + uint32_t bufLen = sizeof(buf_p); + uint8_t buf_q[1030] = {0}; + uint8_t buf_g[1030] = {0}; + Hex getP = {buf_p, bufLen}; + Hex getQ = {buf_q, bufLen}; + Hex getG = {buf_g, bufLen}; + + CRYPT_EAL_PkeyPara para1 = {0}; + CRYPT_EAL_PkeyPara para2 = {0}; + Set_DSA_Para(¶1, NULL, NULL, p, q, g, NULL, NULL); + Set_DSA_Para(¶2, NULL, NULL, &getP, &getQ, &getG, NULL, NULL); + TestMemInit(); + CRYPT_EAL_PkeyCtx *pKey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(pKey != NULL); + + para2.id = CRYPT_PKEY_RSA; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pKey, ¶1) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(pKey, ¶2) == CRYPT_EAL_ERR_ALGID); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(NULL, ¶2) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(pKey, NULL) == CRYPT_NULL_INPUT); + + para2.id = CRYPT_PKEY_DSA; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPara(pKey, ¶2) == CRYPT_SUCCESS); + ASSERT_TRUE(para1.para.dsaPara.pLen == para2.para.dsaPara.pLen); + ASSERT_TRUE(memcmp(para1.para.dsaPara.p, para2.para.dsaPara.p, para1.para.dsaPara.pLen) == 0); + ASSERT_TRUE(para1.para.dsaPara.qLen == para2.para.dsaPara.qLen); + ASSERT_TRUE(memcmp(para1.para.dsaPara.q, para2.para.dsaPara.q, para1.para.dsaPara.qLen) == 0); + ASSERT_TRUE(para1.para.dsaPara.gLen == para2.para.dsaPara.gLen); + ASSERT_TRUE(memcmp(para1.para.dsaPara.g, para2.para.dsaPara.g, para1.para.dsaPara.gLen) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pKey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001 + * @title DSA: Set(or copy) the key, sign, and verify the signature. + * @precon Registering memory-related functions. + * Dsa vertors. + * @brief + * 1. Mock BN_RandRange method to generate vector K. + * 2. Create the context of the dsa algorithm, expected result 1. + * 3. Set para, private key and public key, expected result 2. + * 4. Call the CRYPT_EAL_PkeyGetSignLen method to get sign length, expected result 3. + * 5. Allocate the memory for the signature, expected result 4. + * 6. Encoding r and s vectors, expected result 5. + * 7. Sign and compare the signatures of hitls and vector, expected result 6. + * 8. Verify, expected result 7. + * 9. Copy the ctx and repeat steps 7 through 8. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. signLen > 0 + * 4. Success + * 5. Success + * 6. CRYPT_SUCCESS, the two signatures are the same. + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001( + int hashId, Hex *P, Hex *Q, Hex *G, Hex *Msg, Hex *X, Hex *Y, Hex *K, Hex *R, Hex *S) +{ + if (IsMdAlgDisabled(hashId)) { + SKIP_TEST(); + } + uint32_t signLen; + uint8_t *vectorSign = NULL; + uint8_t *hitlsSign = NULL; + uint32_t vectorSignLen, hitlsSignOutLen; + BN_BigNum *bn_r = NULL; + BN_BigNum *bn_s = NULL; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + Set_DSA_Para(¶, &prv, &pub, P, Q, G, X, Y); + + FuncStubInfo tmpRpInfo; + ASSERT_EQ(memcpy_s(g_kRandBuf, sizeof(g_kRandBuf), K->x, K->len), 0); + g_kRandBufLen = K->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + TestMemInit(); + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); + + signLen = CRYPT_EAL_PkeyGetSignLen(pkey); + ASSERT_TRUE(signLen > 0); + + /* Encoding r and s vectors */ + DSA_Sign dsaSign = {0}; + vectorSign = (uint8_t *)malloc(signLen); + vectorSignLen = signLen; + ASSERT_EQ(SignEncode(&dsaSign, vectorSign, &vectorSignLen, R, S, &bn_r, &bn_s), CRYPT_SUCCESS); + + /* Sign */ + hitlsSign = (uint8_t *)malloc(signLen); + hitlsSignOutLen = signLen; + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, hashId, Msg->x, Msg->len, hitlsSign, &hitlsSignOutLen), CRYPT_SUCCESS); + + /* Compare the signatures of hitls and vector. */ + ASSERT_EQ(hitlsSignOutLen, vectorSignLen); + ASSERT_EQ(memcmp(vectorSign, hitlsSign, hitlsSignOutLen), 0); + + /* Verify */ + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, hashId, Msg->x, Msg->len, hitlsSign, hitlsSignOutLen), CRYPT_SUCCESS); + + /* Copy the ctx and verify the signature. */ + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, pkey), CRYPT_SUCCESS); + hitlsSignOutLen = signLen; + ASSERT_EQ(CRYPT_EAL_PkeySign(cpyCtx, hashId, Msg->x, Msg->len, hitlsSign, &hitlsSignOutLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(cpyCtx, hashId, Msg->x, Msg->len, hitlsSign, hitlsSignOutLen), CRYPT_SUCCESS); +exit: + STUB_Reset(&tmpRpInfo); + free(vectorSign); + free(hitlsSign); + BN_Destroy(bn_r); + BN_Destroy(bn_s); + BSL_ERR_RemoveErrorStack(true); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001 + * @title DSA sets the key and performs signature and signature verification tests on the hash data. + * @precon Registering memory-related functions. + * Dsa vertors. + * @brief + * 1. Mock BN_RandRange method to generate vector K. + * 2. Create the context of the dsa algorithm, expected result 1. + * 3. Set para, private key and public key, expected result 2. + * 4. Call the CRYPT_EAL_PkeyGetSignLen method to get sign length, expected result 3. + * 5. Allocate the memory for the signature, expected result 4. + * 6. Encoding r and s vectors, expected result 5. + * 7. Compute the hash of the msg, sign and compare the signatures of hitls and vector, expected result 6. + * 8. Verify, expected result 7. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. signLen > 0 + * 4. Success + * 5. Success + * 6. CRYPT_SUCCESS, the two signatures are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001( + int hashId, Hex *P, Hex *Q, Hex *G, Hex *Msg, Hex *X, Hex *Y, Hex *K, Hex *R, Hex *S) +{ + if (IsMdAlgDisabled(hashId)) { + SKIP_TEST(); + } + uint32_t signLen; + uint8_t *vectorSign = NULL; + uint8_t *hitlsSign = NULL; + uint32_t vectorSignLen, hitlsSignOutLen; + BN_BigNum *bn_r = NULL; + BN_BigNum *bn_s = NULL; + CRYPT_EAL_PkeyCtx *pkey = NULL; + Hex mdOut = {0}; + + FuncStubInfo tmpRpInfo; + ASSERT_EQ(memcpy_s(g_kRandBuf, sizeof(g_kRandBuf), K->x, K->len), 0); + g_kRandBufLen = K->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + CRYPT_EAL_PkeyPara para; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub; + Set_DSA_Para(¶, &prv, &pub, P, Q, G, X, Y); + + TestMemInit(); + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); + + signLen = CRYPT_EAL_PkeyGetSignLen(pkey); + ASSERT_TRUE(signLen > 0); + + /* Encoding r and s vectors */ + DSA_Sign dsaSign; + vectorSign = (uint8_t *)malloc(signLen); + vectorSignLen = signLen; + ASSERT_EQ(SignEncode(&dsaSign, vectorSign, &vectorSignLen, R, S, &bn_r, &bn_s), CRYPT_SUCCESS); + + /* Calculates the hash of the msg. */ + ASSERT_EQ(Compute_Md(hashId, Msg, &mdOut), SUCCESS); + + /* Sign */ + hitlsSign = (uint8_t *)malloc(signLen); + hitlsSignOutLen = signLen; + ASSERT_EQ(CRYPT_EAL_PkeySignData(pkey, mdOut.x, mdOut.len, hitlsSign, &hitlsSignOutLen), CRYPT_SUCCESS); + + /* Compare the signatures of hitls and vector. */ + ASSERT_EQ(hitlsSignOutLen, vectorSignLen); + ASSERT_EQ(memcmp(vectorSign, hitlsSign, hitlsSignOutLen), 0); + + /* Verify the signature of the hash data. */ + ASSERT_EQ(CRYPT_EAL_PkeyVerifyData(pkey, mdOut.x, mdOut.len, hitlsSign, hitlsSignOutLen), CRYPT_SUCCESS); +exit: + STUB_Reset(&tmpRpInfo); + if (mdOut.x != NULL) { + free(mdOut.x); + } + free(vectorSign); + free(hitlsSign); + BN_Destroy(bn_r); + BN_Destroy(bn_s); + BSL_ERR_RemoveErrorStack(true); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_GEN_FUNC_TC001 + * @title DSA function test (gen a key pair). + * @precon Registering memory-related functions. + * Dsa vertors. + * @brief + * 1. Init the drbg, expected result 1. + * 2. Create the context(ctx) of the DSA algorithm, expected result 2. + * 3. Set para for dsa, expected result 3. + * 4. Generate a key pair, expected result 4. + * 5. Call the CRYPT_EAL_PkeyGetSignLen method to get sign length, expected result 5. + * 6. Allocate the memory for the signature, expected result 6. + * 7. Sign, expected result 7. + * 8. Verify, expected result 8. + * @expect + * 1. CRYPT_SUCCESS + * 2. Success, and two contexts are not NULL. + * 3. CRYPT_SUCCESS + * 4. CRYPT_SUCCESS + * 5. signLen > 0 + * 6. Success + * 7. CRYPT_SUCCESS + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_GEN_FUNC_TC001(Hex *p, Hex *q, Hex *g, Hex *data) +{ + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPara para = {0}; + uint8_t *sign = NULL; + uint32_t signLen; + + Set_DSA_Para(¶, NULL, NULL, p, q, g, NULL, NULL); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(ctx, ¶), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(ctx), CRYPT_SUCCESS); + + signLen = CRYPT_EAL_PkeyGetSignLen(ctx); + ASSERT_TRUE(signLen > 0); + sign = (uint8_t *)malloc(signLen); + + ASSERT_EQ(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SHA256, data->x, data->len, sign, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SHA256, data->x, data->len, sign, signLen), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + free(sign); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_DUP_CTX_FUNC_TC001 + * @title DSA: CRYPT_EAL_PkeyDupCtx test. + * @precon Registering memory-related functions. + * Dsa vertors. + * @brief + * 1. Create the context of the dsa algorithm, expected result 1. + * 2. Init the drbg, expected result 2. + * 3. Set para and generate a key pair, expected result 3. + * 4. Call the CRYPT_EAL_PkeyDupCtx method to dup dsa context, expected result 4. + * 5. Call the CRYPT_EAL_PkeyCmp method to compare public key, expected result 5. + * 6. Call the CRYPT_EAL_PkeyGetKeyBits to get keyLen from contexts, expected result 6. + * 7. Call the CRYPT_EAL_PkeyGetPub method to obtain the public key from the contexts, expected result 7. + * 8. Compare public keys, expected result 8. + * 9. Call the CRYPT_EAL_PkeyGetPrv method to obtain the private key from the contexts, expected result 9. + * 10. Compare privates keys, expected result 10. + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Success, and context is not NULL. + * 5. CRYPT_SUCCESS + * 6. The key length obtained from both contexts is the same. + * 7. CRYPT_SUCCESS + * 8. The two public keys are the same. + * 9. CRYPT_SUCCESS + * 10. The two private keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_DUP_CTX_FUNC_TC001(Hex *p, Hex *q, Hex *g) +{ + uint8_t *key1 = NULL; + uint8_t *key2 = NULL; + uint32_t keyLen1, keyLen2; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pub1, pub2; + CRYPT_EAL_PkeyPrv prv1, prv2; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyCtx *dupCtx = NULL; + + Set_DSA_Para(¶, NULL, NULL, p, q, g, NULL, NULL); + + TestMemInit(); + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(ctx, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(ctx), CRYPT_SUCCESS); + + dupCtx = CRYPT_EAL_PkeyDupCtx(ctx); + ASSERT_TRUE(dupCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx, dupCtx), CRYPT_SUCCESS); + + keyLen1 = CRYPT_EAL_PkeyGetKeyBits(ctx); + keyLen2 = CRYPT_EAL_PkeyGetKeyBits(dupCtx); + ASSERT_EQ(keyLen1, keyLen2); + + key1 = calloc(1u, keyLen1); + key2 = calloc(1u, keyLen2); + ASSERT_TRUE(key1 != NULL && key2 != NULL); + + Set_DSA_Pub(&pub1, key1, keyLen1); + Set_DSA_Pub(&pub2, key2, keyLen2); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(dupCtx, &pub2), CRYPT_SUCCESS); + ASSERT_COMPARE("Compare public key", key1, pub1.key.dsaPub.len, key2, pub2.key.dsaPub.len); + + Set_DSA_Prv(&prv1, key1, keyLen1); + Set_DSA_Prv(&prv2, key2, keyLen2); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(ctx, &prv1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(dupCtx, &prv2), CRYPT_SUCCESS); + ASSERT_COMPARE("Compare private key", key1, prv1.key.dsaPrv.len, key2, prv2.key.dsaPrv.len); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_PkeyFreeCtx(dupCtx); + BSL_SAL_Free(key1); + BSL_SAL_Free(key2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_KEY_PAIR_CHECK_FUNC_TC001 + * @title DSA: key pair check. + * @precon Registering memory-related functions. + * @brief + * 1. Create two contexts(pubCtx, prvCtx) of the dsa algorithm, expected result 1 + * 2. Set para and public key for pubCtx, expected result 2 + * 3. Set para and private key for prvCtx, expected result 3 + * 4. Init the drbg, expected result 5, expected result 4 + * 5. Check whether the public key matches the private key, expected result 5 + * @expect + * 1. Success, and contexts are not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Return CRYPT_SUCCESS when expect is 1, CRYPT_DSA_VERIFY_FAIL otherwise. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_KEY_PAIR_CHECK_FUNC_TC001(Hex *P, Hex *Q, Hex *G, Hex *X, Hex *Y, int expect) +{ + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + int expectRet = expect == 1 ? CRYPT_SUCCESS : CRYPT_DSA_VERIFY_FAIL; + + Set_DSA_Para(¶, &prv, &pub, P, Q, G, X, Y); + + TestMemInit(); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(pubCtx != NULL && prvCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pubCtx, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pubCtx, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(prvCtx, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(prvCtx, &prv), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyPairCheck(pubCtx, prvCtx), expectRet); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pubCtx); + CRYPT_EAL_PkeyFreeCtx(prvCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_DSA_GET_KEY_BITS_FUNC_TC001 + * @title DSA: get key bits. + * @brief + * 1. Create a context of the DSA algorithm, expected result 1 + * 2. Get key bits, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. Equal to keyBits. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_DSA_GET_KEY_BITS_FUNC_TC001(int id, int keyBits, Hex *P, Hex *Q, Hex *G) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + CRYPT_EAL_PkeyPara para; + para.id = CRYPT_PKEY_DSA; + para.para.dsaPara.p = P->x; + para.para.dsaPara.pLen = P->len; + para.para.dsaPara.q = Q->x; + para.para.dsaPara.qLen = Q->len; + para.para.dsaPara.g = G->x; + para.para.dsaPara.gLen = G->len; + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(pkey) == (uint32_t)keyBits); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/dsa/test_suite_sdv_eal_dsa.data b/testcode/sdv/testcase/crypto/dsa/test_suite_sdv_eal_dsa.data new file mode 100644 index 00000000..1604bf24 --- /dev/null +++ b/testcode/sdv/testcase/crypto/dsa/test_suite_sdv_eal_dsa.data @@ -0,0 +1,1384 @@ +NiST Vector: CRYPT_EAL_PkeySetPara bad arguments paraNULL test1 +SDV_CRYPTO_DSA_SET_PARA_API_TC001:"":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33" + +NiST Vector: CRYPT_EAL_PkeySetPara bad arguments paraNULL test2 +SDV_CRYPTO_DSA_SET_PARA_API_TC001:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33" + +NiST Vector: CRYPT_EAL_PkeySetPara bad arguments paraNULL test3 +SDV_CRYPTO_DSA_SET_PARA_API_TC001:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"" + +NiST Vector: Dsa public key compare +SDV_CRYPTO_DSA_CMP_API_TC001:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"313fd9ebca91574e1c2eebe1517c57e0c21b0209872140c5328761bbb2450b33f1b18b409ce9ab7c4cd8fda3391e8e34868357c199e16a6b2eba06d6749def791d79e95d3a4d09b24c392ad89dbf100995ae19c01062056bb14bce005e8731efde175f95b975089bdcdaea562b32786d96f5a31aedf75364008ad4fffebb970b" + +SDV_CRYPTO_DSA_CTRL_API_TC001 +SDV_CRYPTO_DSA_CTRL_API_TC001: + +SDV_CRYPTO_DSA_GET_PARA_API_TC001 +SDV_CRYPTO_DSA_GET_PARA_API_TC001:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33" + +Nist_Vector_1 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"3b46736d559bd4e0c2c1b2553a33ad3c6cf23cac998d3d0c0e8fa4b19bca06f2f386db2dcff9dca4f40ad8f561ffc308b46c5f31a7735b5fa7e0f9e6cb512e63d7eea05538d66a75cd0d4234b5ccf6c1715ccaaf9cdc0a2228135f716ee9bdee7fc13ec27a03a6d11c5c5b3685f51900b1337153bc6c4e8f52920c33fa37f4e7":"c53eae6d45323164c7d07af5715703744a63fc3a":"313fd9ebca91574e1c2eebe1517c57e0c21b0209872140c5328761bbb2450b33f1b18b409ce9ab7c4cd8fda3391e8e34868357c199e16a6b2eba06d6749def791d79e95d3a4d09b24c392ad89dbf100995ae19c01062056bb14bce005e8731efde175f95b975089bdcdaea562b32786d96f5a31aedf75364008ad4fffebb970b":"98cbcc4969d845e2461b5f66383dd503712bbcfa":"50ed0e810e3f1c7cb6ac62332058448bd8b284c0":"c6aded17216b46b7e4b6f2a97c1ad7cc3da83fde" +Nist_Vector_2 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"d2bcb53b044b3e2e4b61ba2f91c0995fb83a6a97525e66441a3b489d9594238bc740bdeea0f718a769c977e2de003877b5d7dc25b182ae533db33e78f2c3ff0645f2137abc137d4e7d93ccf24f60b18a820bc07c7b4b5fe08b4f9e7d21b256c18f3b9d49acc4f93e2ce6f3754c7807757d2e1176042612cb32fc3f4f70700e25":"e65131d73470f6ad2e5878bdc9bef536faf78831":"29bdd759aaa62d4bf16b4861c81cf42eac2e1637b9ecba512bdbc13ac12a80ae8de2526b899ae5e4a231aef884197c944c732693a634d7659abc6975a773f8d3cd5a361fe2492386a3c09aaef12e4a7e73ad7dfc3637f7b093f2c40d6223a195c136adf2ea3fbf8704a675aa7817aa7ec7f9adfb2854d4e05c3ce7f76560313b":"87256a64e98cf5be1034ecfa766f9d25d1ac7ceb":"a26c00b5750a2d27fe7435b93476b35438b4d8ab":"61c9bfcb2938755afa7dad1d1e07c6288617bf70" +Nist_Vector_3 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"d5431e6b16fdae31481742bd394758beb8e24f31947e19b7ea7b458521882270c1f43192aa050f4485145af8f3f9c5142d68b85018d2ec9cb7a37ba12ed23e73b95fd680fba3c61265e9f5a0a027d70fad0c8aa08a3cbfbe99018d0045386173e5fae225faebe0cef5dd45910f400a86c2be4e15252a16de4120a267be2b594d":"20bcabc6d9347a6e79b8e498c60c44a19c73258c":"23b4f404aa3c575e550bb320fdb1a085cd396a10e5ebc6771da62f037cab19eacd67d8222b6344038c4f7af45f5e62b55480cbe2111154ca9697ca76d87b56944138084e74c6f90a05cf43660dff8b8b3fabfcab3f0e4416775fdf40055864be102b4587392e77752ed2aeb182ee4f70be4a291dbe77b84a44ee34007957b1e0":"7d9bcfc9225432de9860f605a38d389e291ca750":"3f0a4ad32f0816821b8affb518e9b599f35d57c2":"ea06638f2b2fc9d1dfe99c2a492806b497e2b0ea" +Nist_Vector_4 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"85662b697550e4915c29e338b624b912845d6d1a920d9e4c1604dd47d692bc7c0ffb95ae614e852bebaf1573758ad01c713cac0b476e2f121745a3cfeeffb2441ff6abfb9bbeb98aa634ca6ff541947dcc9927659d44f95c5ff9170fdc3c86473cb601ba31b487fe5936bac5d9c632cbcc3db06246ba01c55a038d797fe3f6c3":"52d1fbe687aa0702a51a5bf9566bd51bd569424c":"6bc36cb3fa61cecc157be08639a7ca9e3de073b8a0ff23574ce5ab0a867dfd60669a56e60d1c989b3af8c8a43f5695d503e3098963990e12b63566784171058eace85c728cd4c08224c7a6efea75dca20df461013c75f40acbc23799ebee7f3361336dadc4a56f305708667bfe602b8ea75a491a5cf0c06ebd6fdc7161e10497":"960c211891c090d05454646ebac1bfe1f381e82b":"3bc29dee96957050ba438d1b3e17b02c1725d229":"0af879cf846c434e08fb6c63782f4d03e0d88865" +Nist_Vector_5 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"87b6e75b9f8e99c4dd62adb693dd5890edff1bd0028f4ef849df0f1d2ce6b181fc3a55aea6d0a1f0aecab8ed9e248a00e96be794a7cfba1246efb710ef4b37471cef0a1bcf55cebc8d5ad071612bd237efedd5102362db07a1e2c7a6f15e09fe64ba42b60a2628d869ae05ef611fe38d9ce15eeec9bb3decc8dc17809f3b6e95":"c86a54ec5c4ec63d7332cf43ddb082a34ed6d5f5":"014ac746d3605efcb8a2c7dae1f54682a262e27662b252c09478ce87d0aaa522d7c200043406016c0c42896d21750b15dbd57f9707ec37dcea5651781b67ad8d01f5099fe7584b353b641bb159cc717d8ceb18b66705e656f336f1214b34f0357e577ab83641969e311bf40bdcb3ffd5e0bb59419f229508d2f432cc2859ff75":"6c445cee68042553fbe63be61be4ddb99d8134af":"637e07a5770f3dc65e4506c68c770e5ef6b8ced3":"7dfc6f83e24f09745e01d3f7ae0ed1474e811d47" +Nist_Vector_6 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"2259eead2d6bbc76d49213ea0dc8b7350a97699f22341044c3940782364ac9ea683179a438a5ea45998df97c2972dae03851f5be23fa9f04182e79ddb2b56dc8652393ecb27f3f3b7c8a8d761a86b3b8f4d41a07b4be7d02fddefc42b928124a5a45b9f4609042209b3a7f585bd514cc39c00effcc42c7fe70fa83edf8a32bf4":"aee6f213b9903c8069387e64729a08999e5baf65":"0fe74045d7b0d472411202831d4932396f242a9765e92be387fd81bbe38d845054528b348c03984179b8e505674cb79d88cc0d8d3e8d7392f9aa773b29c29e54a9e326406075d755c291fcedbcc577934c824af988250f64ed5685fce726cff65e92d708ae11cbfaa958ab8d8b15340a29a137b5b4357f7ed1c7a5190cbf98a4":"e1704bae025942e2e63c6d76bab88da79640073a":"83366ba3fed93dfb38d541203ecbf81c363998e2":"1fe299c36a1332f23bf2e10a6c6a4e0d3cdd2bf4" +Nist_Vector_7 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"219e8df5bf881590430ece608250f7670dc56537249302429e28ecfeb9ceaaa54910a69490f765f3df82e8b01cd7d76e561d0f6ce226ef3cf752cada6febdc5bf00d67947f92d420516b9e37c96c8f1f2da0b075097c3bda758a8d91bd2ebe9c75cf147f254c256963b33b67d02b6aa09e7d7465d038e50195ece4189b41e768":"699f1c07aa458c6786e770b40197235fe49cf21a":"3a41b0678ff3c4dde20fa39772bac31a2f18bae4bedec9e12ee8e02e30e556b1a136013bef96b0d30b568233dcecc71e485ed75c922afb4d0654e709bee84993792130220e3005fdb06ebdfc0e2df163b5ec424e836465acd6d92e243c86f2b94b26b8d73bd9cf722c757e0b80b0af16f185de70e8ca850b1402d126ea60f309":"5bbb795bfa5fa72191fed3434a08741410367491":"579761039ae0ddb81106bf4968e320083bbcb947":"503ea15dbac9dedeba917fa8e9f386b93aa30353" +Nist_Vector_8 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"2da79d067885eb3ccf5e293ae3b1d8225322203abb5adfde3b0f53bbe24c4fe001541e1183d870a997f1f9460100b5d711923180154345287a0214cf1cac37b7a47dfbb2a0e8ce4916f94ebd6fa54e315b7a8eb5b63cd954c5ba05c1bf7e33a4e8a151f32d2877b01729c1ad0e7c01bb8ae723c995183803e45636520ea38ca1":"d6e08c20c82949ddba93ea81eb2fea8c595894dc":"56f7272210f316c51af8bfc45a421fd4e9b1043853271b7e79f40936f0adcf262a86097aa86e19e6cb5307685d863dba761342db6c973b3849b1e060aca926f41fe07323601062515ae85f3172b8f34899c621d59fa21f73d5ae97a3deb5e840b25a18fd580862fd7b1cf416c7ae9fc5842a0197fdb0c5173ff4a4f102a8cf89":"6d72c30d4430959800740f2770651095d0c181c2":"5dd90d69add67a5fae138eec1aaff0229aa4afc4":"47f39c4db2387f10762f45b80dfd027906d7ef04" +Nist_Vector_9 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"ba30d85be357e7fb29f8a07e1f127baaa24b2ee027f64cb5efeec6aaeabcc7345c5d556ebf4bdc7a61c77c7b7ea43c73babc18f7b4807722da239e45ddf249849cbbfe3507112ebf87d7ef560c2e7d391ed8424f8710cea41685143e3006f81b68fbb4d5f9644c7cd10f7092ef2439b8d18c0df655e00289372a4166385d640c":"50018482864c1864e9db1f04bde8dbfd3875c76d":"0942a5b7a72ab116ead29308cf658dfe3d55d5d61afed9e3836e64237f9d6884fdd827d2d5890c9a41ae88e7a69fc9f345ade9c480c6f08cff067c183214c227236cedb6dd1283ca2a602574e8327510221d4c27b162143b7002d8c726916826265937b87be9d5ec6d7bd28fb015f84e0ab730da7a4eaf4ef3174bf0a22a6392":"df3a9348f37b5d2d4c9176db266ae388f1fa7e0f":"448434b214eee38bde080f8ec433e8d19b3ddf0d":"0c02e881b777923fe0ea674f2621298e00199d5f" +Nist_Vector_10 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"83499efb06bb7ff02ffb46c278a5e92630ac5bc3f9e53dd2e78ff15e368c7e31aad77cf771f35fa02d0b5f135208a4afdd867bb2ec26ea2e7dd64cdef237508a38b27f39d8b22d45cac5a68a90b6ea76058645f6356a9344d36f00ec6652eaa4e9bae7b694f9f1fc8c6c5e86fadc7b27a219b5c1b2ae80a725e5f61165fe2edc":"ae56f66b0a9405b9cca54c60ec4a3bb5f8be7c3f":"a01542c3da410dd57930ca724f0f507c4df43d553c7f69459939685941ceb95c7dcc3f175a403b359621c0d4328e98f15f330a63865baf3e7eb1604a0715e16eed64fd14b35d3a534259a6a7ddf888c4dbb5f51bbc6ed339e5bb2a239d5cfe2100ac8e2f9c16e536f25119ab435843af27dc33414a9e4602f96d7c94d6021cec":"8857ff301ad0169d164fa269977a116e070bac17":"8c2fab489c34672140415d41a65cef1e70192e23":"3df86a9e2efe944a1c7ea9c30cac331d00599a0e" +Nist_Vector_11 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"f23ee79eb4fce5cbf3b08d65a1803d2e3e191d3580a44d177d8ff069f90784d012ca5746e6dd6638dfe8413f1db3d8fe282c2160f5dd96607dd63d610f791dfc10abad18721587101cec8a2a12913cfbada3a5b7593958b9bfa6e9af3af5d71ff17ec72aaaeecaaffc5d174e629a090297e94cdfe988d9bf6c80827c23df5137":"a62079b4f45772bf17b85d7560e3be4e521439eb":"229a26dcaff29ed1a7264ed0f77d676239b9ba1ef4778e7dd640e8aa6fabdc1f1bd3f582e211bd01c26b3d9d3bffe7199f9ed45d764cd9d0e844b385cb34e6de22370ebc6ba41db409d63f50c1ac09bed00cdc2b7c55223c596b7e133ba25ba9e78f33502f8dd52f32a667a7683e504047817963238d9629a918a0ceebaad518":"c01acd36910f2f2bff608386b81c35a0a7c0b378":"8d388ec7f2863dd5b7c99ac93505d1580bf2e0c7":"76ae9317696d37f2d8bd61c47733e9455b61d347" +Nist_Vector_12 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"6836255e6e659de4ffb535892d466a3bea09693e587eb5bd50f44f8a22f11697057d68660bc6562400d587baac1c19d330ff794a70df5300a5211c72541a56d0ff2af02a278ed2db1df94ccb2026d3138b2d924245021ee835d3c17b0b3b7677def85611227f6ce2913e7cb446a479b95acfd0105c25e4656fbc56c2a10a22b3":"7861e82e66b6caea54b159c59c887ec27b2e915f":"a7bbc35423510edfebf79c4e2e56986f2806d11116bcae90a716f05dcbfc46dcbfebe2ec946c40f9cc8c1a7439cdd04e270122ec1c3baca83811a9f1bdaed9b1172150af1c8ce1c5d502dfe5f4e8467e50605087a8f8c5f45ca672fd049eec0a06f5e01f782d51f3ba56404bf1388065552fc87ad21ac0fa4027a145d0b0d9e6":"4e22cfa2e8ca2b33a9fd91ff4837fc205864e8b1":"c0ab43d309a5e94b6ef4db9943306e6d966fc9b5":"07ec5aa1928f19fc3a420f29b935bac46124c0e2" +Nist_Vector_13 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"4b0845c99db348294f1d83166b27f448ec29ab7965464477f45444f44672a409ddcafaf35e91faf401eca7498e3268caa2d96bf1aa840c0e1ed43a5ab60888fcf02b2f8a2c89daa598adf0b7d2dace9210efd41ab496a1e73a182da430c1d043e249a1289c91809c8c7298cfdbb0ae438b00936c283a0ec2d79cdc81c9ce3c2d":"6f2d3b09fae6910dd975870db3a2c19d97169491":"541a9c45e165d3d91e71bb1370d7c032c360322aa15e99d8c1c16ea35c8c193224a06467ab77a65478c467b3f20cb0c5fdb8c84cefa69566a594a2aa54c3a948ebc1ea7e6c3d28d380cbd01740634c96b76d6a03cc6eba0afa7226f23fc10a18b0b6f97270dfa038160960b5b839ba66af50fda07245810e80d38b6693e8a9ce":"8588557c12ec6fe176b0be7bbd8b482ad78f1fef":"44286019c1d53103980616940c028bad3217f78d":"4b372bf527c515f58025699a45f2021ef18e11b9" +Nist_Vector_14 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"4597c1ca0b0764be31fa73ccc589116cc8d0a31605f2550eb37fa569b2496c4f34321d61bb8e49f858c8671b7437fc15f269dd2d4146470b817dfe3069225ddd3cd4a6c977fb6cfc0d43264a7bf6659283e140e4c89ab2e8a4d0ede6274961d655bd79c7e47880a741fb0180c325b5b7d2f7b8a57aed52d0206a83bb69a9d7a4":"49f6c1ac8e639bcc99b2d9d1f1e325713f29b97c":"5315adf90e196946be6b04c5414da1fafd98b0d17c3a39000a00091b7b56574b1ecd026eabb25be9ecd0ad691df2b7bf7eecd6ad95bb4d7d17ac747060ee7e3eb5c6fb7557cf7e8003a620e43e587d0612854472c3ad851839f744159411a33876aec365eb0491dec80ba14cba2d11dec42af4a4bf9c99312a2ae7e5462a2adf":"8ef1c5976ac8caf74df65d9ecdbe78a6490bc220":"90d547712bc0cebbd3ebd18a63d9b92a03953050":"34ea6176b4c63043295f129a4895e14ee5816563" +Nist_Vector_15 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"18c62a40b52347a473f57aa668eebb4484beb5f10fdc51779e6770106c0d122eb6356ae53a3379e270edca39015da3005770c7b2a5afd11217993153ff43a0b26db01aa2a493de061492a0aa3f229b5abd1aff29395e31b063504eb35620219ba29997f92a52e1b2e6ff207480fd13d58ff0290eec5aabf23b84943eea20a43c":"396cbe3e71d74f6db795c38d49c32d78eab03397":"3b738246f9e38cebf4542ced3fc0c0096aeb9e9a3ad928f4dd4745d875fe6e20fb65556d06696432ecffd55b334940c6e23c903f0aa4a1335f7394c55070586baac86c38cc198ebaf15401259528c55192e9298d2a0c8914daf2ad00259fe72555c3c0442e38c1e6e5020928c6e6571a0a98f6f485e43791ae8aaab180461fa4":"04bfe51616f5c244d2e01648362f5bbe5fa73501":"29b7c0f90d624f8d587efd3f49f97da70f6e63e7":"222a3d9ffca0dcf57937e89c92538e32e7a8680f" +Nist_Vector_16 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"fb2128052509488cad0745ed3e6312850dd96ddaf791f1e624e22a6b9beaa65319c325c78ef59cacba0ccfa722259f24f92c17b77a8f6d8e97c93d880d2d8dbbbedcf6acefa06b0e476ca2013d0394bd90d56c10626ef43cea79d1ef0bc7ac452bf9b9acaef70325e055ac006d34024b32204abea4be5faae0a6d46d365ed0d9":"6e2e31bbfc670944d7a7120e39a981520614d8a8":"7e339f3757450390160e02291559f30bed0b2d758c5ccc2d8d456232bb435ae49de7e7957e3aad9bfdcf6fd5d9b6ee3b521bc2229a8421dc2aa59b9952345a8fc1de49b348003a9b18da642d7f6f56e3bc665131ae9762088a93786f7b4b72a4bcc308c67e2532a3a5bf09652055cc26bf3b18833598cffd7011f2285f794557":"8cb35d255505a4c41421e562d10827266aa68663":"afee719e7f848b54349ccc3b4fb26065833a4d8e":"734efe992256f31325e749bc32a24a1f957b3a1b" +Nist_Vector_17 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"02971e0cdd48ae2331db9c6285e9880e96104fa7a9f378dfea718e63efe98352fe4d35a2bc94b3a888cfb88b8b7d9f6c8c54e48613f32c9946ffe6e9a4b7108ececdda41bc151b3d8724b61f5b83a4e27476914387b0488e41be54f63aa773175eb373a3641e6e7950eee8faf048a841f107d30cf9be268493231545d8984694":"0b448f49a085a52a03d7f668a1d6fb87f2e221ac":"633bb757b3c0e3b7867bf845301ea4e39f75c9759c223f46ce266d406b9df5db501fb826b6e61cba6104c604458c90799f2a36ab51166d0e83b770840624fedc35ebfb9853419e7e09b32b4bd652da4f1ce973ac2620c966b61e35a3f216439a8de1a104f172e1b6e2878112a66c34d16a9aef3ac24a34af5edbf39818a3e2ef":"4481a4be9db6821e3b0a08c9c82603631971a682":"92c65e07462d668b06dd45b608784965897838bc":"2e40adf41cafb8048c793c7092a7e823515b6cfa" +Nist_Vector_18 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"062e82fb43236ee17ebfaa3d363b9b873d0fe41444c74cef7f7e3bd81f723fd90fd148a28e997585413695113757758aa4dd275f70b375f8903c7be46e3a3ad3190cd04971abd2f1db192ef0d2b98bbb80181a721a5809928b5bca5c118a2911132ad233cd27c7e41adfccfeb4e952874bfa819661182975e44d37c61734759c":"a4a25a8bb1c2ba69f9611939b591032b96333fa3":"3b0a091dfca05dce61e9f05b15b07487d2e3ea4f568dc9ac752d42c0aa771ae0ccc372ce9774fb9fd16a30cb3759bb1989488ce85db7cdfa506476acec644c21168f2db1f36efe0230c6fb8f1f2ae4eaf1799d5e29e212467b11bfbc1eebed142d7a017262cd8735e3e29d8e0c4a6e766c07d7aa9f8d176f536087bfecf4c414":"a7135820910f041b27321534a17bb1f33ac51aca":"ba554124874d06a6cef62740e15821ccddbfe6f3":"5962be757d75b0f17d15482ebb595ca4e9fbfe22" +Nist_Vector_19 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"4fca074844eae247d19c06e92032ae8e773043e2e1f45d400e9dcebbde5d65e7c1423b0390161991c026f38a0e2bfeef40dae18741737b1d535ab46b566a1b672fc22dec86747a7c7638fa65047f1ede36ad43f6aedf51b5bf2979adf4d9a94ed802a29de5603b704770b32c8b946a32e1b6054cd70c3add025cc9371d1e404d":"1f15cafca282083e82d7e54258647b2914418986":"40b638c94b1e719a337d83358699c70cd867ff888c655a5f5a1de8732d058bf027d4747efe3b8dedca3276de5a58f136ed35cff03030f672da65c71f18e58278ddfc7b9b50a248eff9236874ee3cb0d0a35b7b2ee185b139ea84eed7bffc5094ab8743a75374bc36c7d69d5f3e6fe5f3ef1f9358f00a3c5892fff41ed6afee3b":"128ab9677c7ade5e1c02a8427650ff054db6390e":"651a389d8ca50d6e3273cabbe71cd84cccd02361":"3401fe47b3812daa8c020c9bd42609cbebdfa728" +Nist_Vector_20 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"4d9630fe058998ca5b80ae62f3f73dc85bee291509843ac00240d13d55251ae53b37794783b97d53e042cab26f8c84de0a70f5b43051fbefb3e43f08f5d2e8aad9e2de2717412dbb902acc8849adc04d06fed8c1421c4cfe8b81ee7f5ac5d4f0c0b68e80b6f88fd3c7d5b32022572b0a681bd2d4df2d047b0b23b6887145afe1":"1485f719b8be77c78829baa0d2c322df60174476":"727b6528357d6705c20d31358f641934fdec63cc66df98837d2f378164e15fa0842207acf3220c8023a9f4f8d2057165b3c849eaeb5376e3fad11785f1d0261779aaedd53b1e52798007eb4c8e83b1ff321b620d883391a14fa47fec4901d96ec232eabb4a0bb4453368fef5176c67135649979d3214d3fb67a1319ac54feb01":"8f4cc1254c787ec8cbf54405105f7ef83ffdeee0":"9ca3e433504c557ba1aac66469781175cdfb4ad5":"72145dfa5279dd82ae99604d16a2b8df71b95320" +Nist_Vector_21 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"62b9d601e30b42a279c7e04df3ca8d8140a55cd5876c7e9181c73575e4c4f921a94e4e2d0bdd7ba98600d652e5df5be9464e7a9011ab486960f69d57ece1d2c4af9324457c1e3d83fba4265beb47407e4761dbc949d5bd67fee4a476a4d5a93d77acda96a221a0a31e0f024b3f0b8234c015238f3258daa085ae9f4e1aa7b1cc":"43c76a9a00045cdfb2e7927b5c8730e006423c05":"5f6dfb064caddf644af399e33a672565766761d55ac0b84bead42c3980e7e396043744361778f04dcb698e4563853420fecacd594af828f57df541d9e4de899d61f04f6379c1c96246d152369395242a1c2e70eef8f35417a0ffdb039282516ce21b85687904c511087f113e5142f027f1179712edcbce27939ab15ec49c085f":"5e4b5e4595e31397422c7a4487ae51051289be61":"331920a7b79e3cfa7638e409d9702aafd08fbec6":"071d06e6cd301515f37b60690afa219fe5083d96" +Nist_Vector_22 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"0006e09c20376442e689bf2d34268fd69109c1301ea66cbe90394cc0f41f94822c28845819b9a98764d2f7262e98891487ff55b05bd69e18b7cad41bd98e137566b6041c739db11f78e567cac02f33f140d19a4805002545375daebfd7dcbea33242e73c8e269149d7eb9db9f9006e17acb736b5e977645ab651b81225c5e543":"16f89d97dd3b31c191495173ae0e145c6ce185d6":"1b1f725664d75bdcb2a5a4c653061c460799dd48bf1e6b03e13c71d83e3fdb506fa94e6cafb5dbdead88a33d23d4e9287b4707e1fba871b97c9a48f930cdccba0dc06a4f0a8bfbb4e14d0b4d5a0871fa1341caec7bc08138713121d419769f31203508df71947265644fdc6137d8e466c8cb0ce985340cb2e279b4ce9315a772":"475b5aa12ff77d49e4c8171f80d3d1f15147ed12":"b6aa833b825184729af308f81bf5e58e2d7e9284":"5453b4b2e3fc802b2f977d0cf6eb7f5c16673fa3" +Nist_Vector_23 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"e04a71f2b5c176a0db17a983a17dec588c00f42c9aa3026b5eb440f07a2140c2ed84024e0531ea7788dfeaa91883fb6a9841c17dcfd312968adb00e556bc7eb3021f57b7a16894fa4fe12ec93dfd494a0a1c693d6ade154ef648c05552da41224d4922d1861d9f7671b8ce6ce448e895ea0eed25802e3350ec08ae79f2d61e0f":"3eda44e3c38380df7a4f47d8e1024596238bcef1":"687e16309b06817b93236dd990faef9e232eb81cb9c7d6dae4fdd4f8e7ca933e185b1da622d7c7fa35e0a3906f915ded14ba96d6035b46bd6ca5fe172af94e081fb0b9a9583a458bd206c1e87f97a57d00d6eade19ec56ac2e9bbd8c15df356ee7b12c91311a38fc3315cfde9ff462ca6adff2808b3f8e805ee915ae885ca957":"aeaa655b6febfec50b05562c3f358865533e4736":"14892b1ec7fc716c75a17f7ad2e41ec6faa78836":"72cc56a9890e8bdf1a53d3acc6f89137264f9ff8" +Nist_Vector_24 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"5e8eb96b5c6ad75d3dab1e28bb2ce751ecc31611a019e8d4b561c7e4533cc7ab73bd9de931e8c54c51c5711e6c276a8ed92f4bb457ddf28233da2ca3e3013c56e3cd2bc61d4d4e0e22cf6361304e56d68b315ca5d3fcc472a7eef8cca575204dd084a21a99ba67fddbf90df7c6c658761734bce13c3d22d80b6fb9bece551492":"0b55f99ad958a766eaf5ac20a127a4df1b946bae":"50b0f7605911bce6ed5ecff1e3c1816fbbf03a1479a0820603ffa715aef9ffbccbd067579cbbc8c87c392e85bbe929a0b5e1059faae6f9121df49c66a049a98a90d84c70a21312bf837f4723993d0ec0ac4c2a7ffb9d400957b39fb83e951ef41362452cf458d784c43fe822ea7a7abbea0a6998321a93819d2d282c7884f5c2":"9e9b9afb43a7157761f6c2011138d2f65ac1cba9":"7399b120d4bfbd6dc4064d2f3f8f0ca5c362b2d8":"2302d81d7ebb2417eef45d88941b070ecab11cab" +Nist_Vector_25 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"da91c692cdb0a59562e2b664dcfe7554ac589d57f82246c4a8a3f9573bf47b257eb8f93447c1ebab13dce53d6f4416fb2c6c36303ed97885cf7a6caef055f7e3145ef3838c31877fad7a8883ffc84ebd973f8c06d17cdd339bb3371f9d3d4f2d9f0b80ae2bcc878b4af78f845eac4f2aacee6a9451daf814a44e927bb5428820":"ac701252c773ba36711b9731afdc077c5d3f9271":"678b3958ed24fc84942054f49d9e6f27bbac7de3a4a52af9ffcb9ce6c1fb8bdd99db0e80c868ac547c4cfc782de7ebcf6943b2e46433c670178de0104bd6fc25dc3054db9c48c12706e1dea35e163be36a4ab721950c028b0546f1719ff2edd81b2b7974fb9b121224ccfaabc47e9e629a97bc6ba42691ca3f649ccac47d0f1e":"6cabf2c0e2890b2b393da3ea6aac2782216efa73":"6f1579edcf437584d3e939fa5b002eee83e3b614":"71208a87a4cf2b3a9b65477773b0096d452dae60" +Nist_Vector_26 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"0f2edc87f4d2942c4693b064a511b93f790c60dc149a1b0b7041af5183bc0f42234134b284270e4c7e53614f7ecfe711de0efb28336d0bb359c86e8be8839f583211e9174832b3d41ee6d21864ac6186fd1db920dda65b25966c5951ab8a2050dda87d1d72e3032852ad43da9fb430e850022b4bb6cc9cb90e428f3a5ca32a62":"588f40e3eb813cd22a41c9cdeadb6895a348db3c":"3a978e9022a8f7a0caa91f275bf9cf7648e1b9a31a0702d8acdbf59affb5467fb07a8f7e5b4c86775ac4efb609b946f05a3f13034db94acc64057f906d1854910de538f84367181c618e96c3f922547d408ee6408b7a70acedc75de8ae445c5d4dd5def4a352d2528234070cc720700c14ce12d2f36990d36b29d7b00596e34b":"8ac2fe7bcd690a7239d294b22725b818d262a446":"b6ea9cdb211c4560b3d592e93af6d5f133b64b9b":"6242e45a472fa8147cb5253dbddebae31ef31e4e" +Nist_Vector_27 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"d12fc1983e0095e9e2b6b8743fb34386cc4821540e3efe1a29f84cf7e63e2a0668d551f912ad2221b5a3d6b9ebd12136def5e6690e1d32aae919f9f1cf5d24d62a46a9a9a604bae11b9c0866350367204a920b589a317ddfbb877f9fad6b0d3629af9635da46933151c0d9a20aaabddd3df5d049659b2860ddb8b20963261ea0":"67cd81c7d6ac2d8bd44ef26297ac02ecba41f73f":"10b7b14ad29fb34d7a39f3e953051f456a0cd1233ef54d90a4adc82dfbd9fa7a85628f11039632b47ba9daeca6e463ec4644f5e2a2a4bf95d392e8c9c9f287a20ba45a198815ca0e9ba854d7f3c79d9037fa1417724fb7f02799b1c2b2bcc79d64367b90c06d1789dcc6de57ca19fcefafc04fcce29c8f495ed564f5d9a112ca":"1341e376e8919e01991e5e48b8e0c7255929b3d2":"360617965f65a68abcb83dbf2d886a1a10ca05de":"71abb6acbf7e653d2ebc3cb7149b51cc0c92fba8" +Nist_Vector_28 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"87a6dfb8487f16f6fef1d68bc31469ac210ea55387965bb4458ca0d00d6c46858be28a019ce914c39c2479f321f0252ca4a8bd681a5b358a093fc8341c31bc47c618403f93322b443084ce5818490b74e83c3866b8164bbcf79bf82539f428c9351c40b10d773cbe1cbaa8c9800a6dcf38d85515e2dff5d4f8a965ecaef37e38":"22bbb8468f3e90768d347cb3492f64db2a23f721":"75ef5d5f67022426f531e9b8ca9115921d5a5c446bcdf1af701b605bae687dff8d1e7b3c4f8b289537eb09a7461d6688a3711974371a5b73a2082e991410118666ccd94f444977d0c89ba36162de023aa519037a6ba6305417dad3f2dc38756a40046491e8ee80c4f147825b8c021b5d09a2422d39d7c4abc395f6c2d7903c66":"9c609e56c19f74ddc46eb2e2cfe26b1519ff0d1b":"5409cd62f5539306ae8c936082eef932c6505c39":"07c0ccb30ec90b1481409cbfa2f5de6cfaf1efc5" +Nist_Vector_29 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"a332b38e642bcad8bd271f776fff24a731724a43400c1614f5e21296db04f725eebad28d62e20ca3f7f18328a76b8092d97b632bb78718f0f2f9ecc7c12cc36b505959917b5c54312ad4717be84fa840b9f06de005c792af3e9ea72b7ae2e3423d07c781c9c2553f899554a0d8dec9a285c1ee25160fa278489474a0e4379516":"bbb1854e9b0942cb5d1eb71e8cc6fc7e0f4cfcb5":"41cc1d6d9e0cf5f158dab599114f3ee4738f197cf2c956b6bb0ddd6dfdcf5e4db399aacc16c538948c4b50de85bad6d916dbc415bad2f6737023fc7063c133bd0c4231d6b33ce813c0d6024d1315269571b2554bbb2edf2a99108a4359e8e23bf8a143bfc538ab9f8842cd4e925968f49ac56a02e3f067e26001e5207bcb56d4":"336e458fc213c0b2775537ae61decc034ccb1d32":"a16a7308a6824d929b6a9a3bdb280d151a6eed81":"7a42addab7ddb98000286044d9993d5cf818f2b1" +Nist_Vector_30 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"79b144d50e0047596cf06bfcb3e9ce3959ec4b8cc9ba01434fc3f68f47c868cea048b990e62cd7a50eee288b35ae62aa797924c9dcab76409b869b33de28885e62f17db7a7758973482968b9f960eb2dba84ae85101aa6c6141b3f0839a4185a4c496eae876ecdc45627330d36f01a67cbb7faef834357330aac36c7c6f47ac9":"754b24ea5c8cb8e88e370074e79cb62605530018":"74db7460c51919a9e87b430d105d86362ee4acd9682bf6c9fe87d9956c2f5ff17d95930ccc12f7e92d8bcb6af5f7ef1848da8d15c9152082477de99594781b998daafbf8ae4af23772125c19e166421f806bd0fbeac365076ecd9e15432ad4ac2523418f6e410cbfcbc5a71a0edf22e694a67d14b9cfc9722bc4bd8c43e22a91":"1b50341e94f4498b92cce4d17ab9d4016fb2e074":"021a3de98c3da698b477b4c3d50b2169e65f5e91":"afd764318dd0fee04fd6b07f550320789cd9bfa5" +Nist_Vector_31 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"812172f09cbae62517804885754125fc6066e9a902f9db2041eeddd7e8da67e4a2e65d0029c45ecacea6002f9540eb1004c883a8f900fd84a98b5c449ac49c56f3a91d8bed3f08f427935fbe437ce46f75cd666a0707265c61a096698dc2f36b28c65ec7b6e475c8b67ddfb444b2ee6a984e9d6d15233e25e44bd8d7924d129d":"2eac4f4196fedb3e651b3b00040184cfd6da2ab4":"4cd6178637d0f0de1488515c3b12e203a3c0ca652f2fe30d088dc7278a87affa634a727a721932d671994a958a0f89223c286c3a9b10a96560542e2626b72e0cd28e5133fb57dc238b7fab2de2a49863ecf998751861ae668bf7cad136e6933f57dfdba544e3147ce0e7370fa6e8ff1de690c51b4aeedf0485183889205591e8":"85976c5610a74959531040a5512b347eac587e48":"76683a085d6742eadf95a61af75f881276cfd26a":"3b9da7f9926eaaad0bebd4845c67fcdb64d12453" +Nist_Vector_32 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"c1b1f1472f08df38a52a55ba55827ba3b7cdd6beded904fcd52610c899eda3c61682656873bbfaab0d907495dacf458ea3450afd93be967a37434d412b6325669ad84b4eaa278a24870ecc2df0da13ad526a9e6669958d4e52dbfba2803ae9ae135d0c0acca86a04c42ba9cafb09b7af96347188880b086169ebdf9f1f5f3173":"1a220585a989ef2c12bbfa9fc0d258713556fe38":"99187498534f313dc7cd7f3a48d62b2335bcdc36f0dc98dbf845dc6085c267474c36fdfca38854219830e614bbcab2bb9decb81e86124bd78f86d471bd84be06ac1f0f41fe5b4b3740b2107e0c9c48f81e31e9bf550d96564dd380ca47a11d72f0d0a3275f075f95bbd59869c14dc912a1cbcf01db9fb7f71015cc149986825e":"8fef50b7121a04a24755b6f3e1cdc93848a9081c":"54ed4efaecdfc78d026471b65cfefc6529945bbf":"6d6dac296ebde3f873b751c6b14843f0b7befdff" +Nist_Vector_33 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"b80a47071d1376fe617e59fdc005a890369a4ca5e678ff46eb9b205d6ec09cbd49373bb341fe7813ee442a6ece17e720bf71a74557ac9a375c059e5535e773a45e79e1bff3465a3886c86e2a2bc882f0beceefffb2ae1a522f13c82def4cfd0cfca6fceeb4cece71869e90cd10d0aff27a84b5601daae061cbeb3aa62b37fd3a":"4247e7e4dc4270fc7680bc05746807c183e0dd98":"91f50270a754055e5da611c720a4262f3cb8bd4161f77d07401604d3d1165e45518f7e1901adef6628f23dc48271d35ff492af8d62aa538c0e77e042f23a522f2214e62114bfeea46ae8888bdadacdaa0a9a5b503d79c23e4c20c98bd4ebb36f95bf4451ccb0b5bb44dfd011341cfa29a9e156a3cd828e126e68cb911e8f9dc0":"3aeb3383a3c0f53217c0d7077c3cd66d2ef74a2e":"1fc2d1cb80bf6e0e78b25fac293b752cbff2b5ac":"75bcc772f773d5fd98dde1f907e7ec2cba201dfb" +Nist_Vector_34 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"a9603054465887df15db07c0709a8c878d2f1abdcfc6195eabf3e9b3ad07e8558b99cc4a7aa076daf67e9b7d8480f11e8afb18e2ac56a9547b48453fedca32da9eb0c29271eb60f0a1d95c18f42d992394b3264ff3e21e606e0beac08a7ba71b8e5795a8da985118e432cf5b30b6cd3a603d8b0d580f06c626ee937c6cd05f40":"4d2a5462ebccc5d19bc6c1cabb609c08ad088e08":"a2c4569a301473ae4f164d68b9a3c6eb705ae81f75d6e5cc3070a559cccb8b1a2d8c21090ed70e61670c7e9dbf5f755a37d58d3abb34c2dfd40db9f26f6868d0dd91be98f395ac0ebdc37e1b5423802bea7a6cb196d7e0f93db92f663b6c9c726e80feb2e9227154ce1c15f8e8df93ec0d37fa47e5fa112bb0a48f4a239d6052":"36a3cd0101358a4d30c5b7117bc239fb4f6ce2e7":"48539523815bd8d73ce702367c7712b9b13867f2":"20ff4cfef8a668829feae73b520e8aa4d02c8168" +Nist_Vector_35 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"19eb088c3229a44f9586f00421cfe7423a486d5f7e28ad2c9119dd2e1395df1acc06cb28e9069cee62f09f48e4ca29269dd89df9fec1ffdf64b1fe2717fe52b1421fcf6c705c0cf39930f90ecb339b51ef95b2ef38a6d96a575f7b36f5edf4f2cbd6d261e1fdd77d4459288c02e68c82a3910ff8ca1747c86bb187d5205f51a8":"0842ddd5a04161e4579797b5d8eda0002dd847ad":"49e606aad5d2e54e1bae2517915c660ba30ec4fd28d718613a7c84464b0f44bc6d546e5a9bc1dc60423b45dd01ec295564ec08f29d6887e69f689d6b3488f9da5d5a60f39cdd5a158d51a3d073b2225fea559e58bb222e29a87b5f0f5ab31dd7c0ceaad887070dac955d28973607a99e46ddd7737beab65199f250d7f03b6583":"712eed73c8d2567809b4d9ec2f59e77d39290b2b":"6bf4f5d3251201059ee85edb99a67a706f37197d":"3125c5af397759996b876cb5857be2632aaaf3b6" +Nist_Vector_36 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"addb5a045c9f4f4fb9eb5e5db44d6515980c9e088015b68593d8bcbffc6ff57f18865ab824d3d1586425cb5081197e9e01cb7297b06b64103cea437eeeec9c50798679fb869ec306a72575057fd368aeb0f674a29c3ac248b6a08f91331d8456d062025347c12a0a61c61f76e5206fe6ca437735af430dea7cc8f39f1a5b7505":"1f1cfc682048375915fb483b77037c81c05ed728":"221ced57a91325b10f8dcd1220b1af68f8daf397f419a43bbd8fbe644311755b111aae5257c642fafd83b047a1f56f2a829fcdf4df3e5dccb23645b28c0a34c6e8a650efcdfadd48fea467cc943ca4e7378829300713838b6c710962ba72e790c10ab879a01fe1457ea3dd4b7c3c3a542e3522a75d0db261e576cd3f22c998e4":"703154f6c6e12f163ecad0494897dfcf5657fbe2":"7cc662e352e0eede85140107a7773ad8663e70bd":"15c17b9d245872844eaac3d46bb08c3e08597423" +Nist_Vector_37 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"02709d2be0d9dc1dc0ebc55f630d91fa23609f61b513c2275766034d8f40e819aaf9326c8db37c35c5a17e96bc956df6d11b558d16d91871afc010b3119c5798c2e29411ff4f0d7196e7e476bf0ad03bf72e897fed873c10613dd255d15243870b81cd87d0abc16e140d032fe5bd1c8eeb2f66e04d13d49269fc7da6b65a7c1c":"1d9cf98dc0c1d7bf8dec98962ac6ef6e9406ce76":"9e93bc03e6e815308734e3b8f1d106961bebdff10a525303257a053dea4da6dcf504c7839b54d57522f2acb3aac959ff4ae8610022ca5a1e688232336ca1ee8fd7028bf7b6e9eedf8a4b0d098969f5e5fd3d9300c340e7f19fd471a451afb92ed4829fa4d90249144aa363dc18807b3e29d27e6ec3da736c33b185511bb3aaa0":"68ae16534c5f6225fc7ef980f0063de483a76903":"72b0bcc6defa66fa8bab029676a1c7703f9608f2":"69d911e05acd7be52f2834c0aa005128e7fa85b8" +Nist_Vector_38 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"cc061edb31c34d3981517f4d89afbe980f74185260cf48b3043bc13a144944ad43e0e576d2a58bf589cc021dc1c1d332c4d76896ea77dda197f683e51eed71b4d6df46666a1b142e679b0283cf339e5bca90e2ff9c34dd5fd7cc4917d66704fee4364f7693101dc766707104efb2b933c4848b93e13f94855f75e4fd756cb6e3":"78ffb40fd89416388804e56444c9a642cb5e98e8":"5d7d2e342154983ebc2015bc6750f9876f5689ca0ada8529908ed4fdbc596b972c5cc6d53e80a8ad8a8cedf3ce64b62a75db441c96207fc7477e3f7b9f10df28e0cc2fb77383e7ca4c5150f712dd823c2309f0161be0bd5eedd60cf6ba230861a08b9d9a7468438b4d6ec673d28a54d83c7010d50631e55f0a02832abc5a0a46":"07c6857486160ef4003470411573399fc4e5f7af":"21f512425670943477534e9075ceb5b7d63f20df":"73c6f6f8de3aaea520a083b2264299e81cfc91c5" +Nist_Vector_39 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"79d529e40c2ba4e5b9c7d77d72076f1fd9490928ff4419c824e64db8fb9a051e01e8e173c6f214e0e9e645ed250b6daaa6f8c1a5cc900d52cf3e1efbfea25748e89a1a548c73e2d110b25f5308bcf757b2135216c91dca2783332c0d7903eb21c226dbd33a69eef575aa8a41cbbdcd1b3d94928aa8f8ba58c5ce0d317786e87b":"784b9db2d19ef0ca8e696884c7711dc2f8ce150a":"282decc0e37994c2856e61f36b831b61bdc02b7ca675dbc3c2032800b7efd3b711acf14c8869968831e145361bf2182b060e4838f07dc61f76584cf102a913bb28a52c7317af5f9d2322927c9666e5e87c2f2bfd2f181dd32612d7b2b2a645bf1a47c0ebfd79a940f627a668a8f2eb729fd051aa2c659abc918e5571994e6593":"1bfcf3290fa84652a476655506b145743213e1b4":"929a4851be0ae4ba91da0e6c7376d71df7592dbb":"7e6b6504b748ef0024d9d2a2e6f3bcd7cf135ac7" +Nist_Vector_40 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"f5516410706323549b20c52dafa2f2f90799786c0ddb85048892ccc18720dce5c129a10eb4388788a3d97a03b0001799cb65a79c880836bc9f3204ea75a577204dc1e2894c572a258f9e517ca37c5b791e48b27c8dc1c821b34ebb1f29858c4a72a0d5172c565e9dbe1bdddf6e024891cd6291faa81ed565746c61c2eda2011f":"673a384687ef29ebfa66e331866bd206ca2f7664":"74ccc6eb83adbcbad0fc37144d9bfb85fdcc85ab92c9f8877c9cda66251d1aff2fb224888dddb7d772a8b738c53e03ecad9903796fa3c9c6024d06367e0870ad797694f598708d08912c0fe09881763a0a722dda95d94eee8824927cbfa6761a79a038aa6d331da34d9bd5c5833c94c526a86af1cdfb2d4079d2db6d0b9a1238":"52ee4510675f0da529684fa60f6848ce63c4689f":"27b3f235e4afc18c6613b4fa7f27d7a8262ba4c0":"8b22634e4d45b71a84eabaa1e5a4bf1e37337a59" +Nist_Vector_41 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"55bd1526e08f6443b255acd32c286807542d34c0f3d79892713f9d6d6d6b3be707e4af6e71f7dab4a2c5f6bd25f5ae1f514b2644a4cdafcece1e58f7576f82e2ab0af2326c71279e9bcef1e1c54a76fa77ec2b2d056717645764e7991b520b0e5a1b049109519b22aa5204e3ed53b1e0957dab5ec32479d06ac3e11a5d1cbd03":"495009f3a92548be4c9a562ff703187b0ec2cc86":"5d6edf6db6e6c27e80a7f02597237919170b4936489d6f15f598b820cd917e172509b7e287b88b0cc14e1a0186793886809ab4170209987095092234b4fdc44b3d1fc16eeb2efaf852ed3916698cf9eca4612b4961bb6e20c32e188469883f97f49e29a8197c30d0723babb06dea704f7704b2788e57d76d6d9a3cfa68f6c783":"423308bb414ef959025bf1a4b27db278f904241d":"621a290930ac436737a72fb4c62bf5c4b67481af":"62db20f82a5754f109f7a2ce581d4c8d71c68d29" +Nist_Vector_42 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"62789a89f0d708e21a121fc34009af884133681b9d4a66cc36c0365c34be72a4982eb0961ce257f35e6e7183f0204a96a545193001023d3309a8997e7c4b762ab4f4c40e03e13f4edb328b23cf00c09119deb40addf6567b3b74acef5ceff045304d618421e873c41a72d31e451d213b060829b286f64013d4d9342ae7ab8064":"2b8dd3965992fcffd158a0816a5987f80908b84c":"ad590590a82e8929ca86f405516c32913bf5282f70309c6d4a88ccf165ce15fcf11e140c366bb273839a711cb6ae52bb717859570fdbf9fc26726728596e6fc71923deadb35a9d57cdb213c0f29c1375f8b1d3c6b52690c428f7481c14aad82fba7f24eea8cd8da7f0ef7ae781c1a926671a61d4e5ffc8ddf1bc10d688a904c6":"58ccff88958d5fc48d671ba22ed71f5f82370ac6":"89dcbca7c8cd6b90aa906a4c547153762fcfffd6":"23e8926b18cfd4b67c53fac4a2d5321e5c3d880c" +Nist_Vector_43 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"4eafcc6874ae2a6d525738967afb3054357a39670d1e5555d7dc55be24dd5a32a0c7ca3f1b5c6d948c9ce391013abeb47f7e24cd2c54e1fc7c0e92c4ab77f5973a7054bd1c6c845b802b7937d6520508ae018ae14b27ff4b1e340a4b9f6f6b4814d07e90cb8f19b15e915d6ad1834c0f7a3c3e1e45206772a0eec2d3f9160897":"6b3acee42276bba155156f23dfb7cdf64e4b1ae8":"b93d79472f049893779a3a0e83b3853f78b3cf69b75961a60e950f0c00f498f3eaa2384325f74ddd38292fbdbdb199212e90b14ec9e554727df81e06eb7783adda38691c63a7cb00cd76d8e18e3d29c793e9f1fe8337f1598b89651f634cb703f218e1906319f82ac6d58e6786da7aecfbca5939f03a13e7b4d5a8ac812d7829":"1c48f62bd097d7686879d33ee5771558e453bb3d":"633e9812a0657cec3326aa5415340c46362fcd4b":"6b201f0c3fd44247f6c28c01d1217eb99146c040" +Nist_Vector_44 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"86d9892b48f5954101482742c0dafb68dc97122483b9e459f97495cc970e056d2162c7c71db167229fb7f45209e0c01eb06ff924b823eda51a7e990f3c986eb9af2a7a073f754cb84db453a9e8c0ae7fa5c05a2655d261ad7ec5612876fa7df09522e0b69ae92477f63def1992c96ce95ee7bd630ec1614621da6a512ab53dd7":"836d90fd90d21b84bb012da7b2168ea8f05202cf":"ae264ea96bf093ef2de27381738219e3bfdb08616967cd13e9415f475c4a794c19f12a607b898db1e3e6bc5402327585d32841ae15e3462880850e9e4136a4751b64a729ea27b72ce36128a44fa53752a08d73584faa44fb14120f47a04c47e989eadabc7e5cdb15d27c2b0ea4257cec229a2c7bf7c93c571e8d22aeaa2e38be":"7956ea15111ff392d6a9359067bfd8c21f0bfc0b":"77b480885c70c1fee2056237d1b79cfd9fb54a1f":"2283f4c0640ff6daacbdfbbef7224afa59ca3959" +Nist_Vector_45 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"8b60b9b6ba375448de4f00de51d18706ef8c4f97ba34c9cce2b0abb0698436009d1d2bafcbef73a8b5dff6a3cd5db5258ac84ef724b28d8a62d715da6e111939735366a7c66470364557f546377d5c0e7ea9064731cb7149e1051d66a7bed14aa205bdc5d4b9ca029a1e68a6fa2c1db22d27fb79d83877cfaa6742119229a493":"5a4ae9f8fc82c9198d9400c51f282493b194a07b":"87032f263de2bf2f268a093f33c366d6bcda772ca959fa17cfe948f1dca3e75ec94276de91d9bc60fc6ab9224861c55dc9ccc5f715c251dd508bd438681cab205059050f8e11e8a5468da42d20aefac53d7a9fb71f6424d7bdc65db873ee4f9dcd918091aa724b261b6056f320ca7724518e14cb8dba0b713f54a0fe44ff1597":"662351e9b8c3a607afdf3ee599b46681e27b83c0":"5d159f894d250db90d7fccd49329e44d1112db47":"37231bc15195ecb6badb7c3fe80380ff912baeda" +Nist_Vector_46 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"b0dbbf4a421ba5c5b0e52f09629801c113258c252f29898c3354706e39ec5824be523d0e2f8cfe022cd61165301274d5d621a59755f50404d8b802371ce616defa962e3636ae934ec34e4bcf77a16c7eff8cf4cc08a0f4849d6ad4307e9f8df83f24ad16ab46d1a61d2d7d4e21681eb2ae281a1a5f9bca8573a3f5281d308a5a":"649820168eb594f59cd9b28b9aefe8cc106a6c4f":"43a27b740f422cb2dc3eaa232315883a2f6a22927f997d024f5a638b507b17d3b1cbd3ec691cc674470960a0146efdecb95bb5fe249749e3c806cd5cc3e7f7bab845dadbe1f50b3366fb827a942ce6246dda7bd2c13e1b4a926c0c82c884639552d9d46036f9a4bc2a9e51c2d76e3074d1f53a63224c4279e0fa460474d4ffde":"33c7ba88ff69707971b25ac344ae4a566e195f99":"77c4d99f62b3ad7dd1fe6498db45a5da73ce7bde":"23871a002ae503fdabaa6a84dcc8f38769737f01" +Nist_Vector_47 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"ec84bed09ecb4a6feeec3a7071b65a4c1267a03cac8b5a0500c237b20dc058514da798335a21b23d7e8cbb15efcf92e6060a13fb77f4998147dec1d0fa0edd418b0aae8eb0056fc7d4008b198bd40b969dc10d79e15b2300820323bd5e1b7d894ce8e7bc8f7ceca129b5e511ee1c8caec25514f537353a912a971b8070e3f141":"952b61ea90df3f788eab61d95be16ca28001800c":"d7a0950d0e6362b0c942ad8af67161df07debca59a4cfa728f93d49b6e296a23969a65a92b2e05398a114d73d5a52b73b71ebb28571cf6b6002f853a8f594b5c93b9a84233f3c552823619e0aa847d60203db15d2a916ad02228325e15783988f4159e05c8ca088360e6ea7ace51b055102153c00adf335ff6affd1754f2a8aa":"7982f6b8956c2bc0a2c2d02ecdb9e47d23a7ba81":"b2570e0e19935438d32686c478473a0e45dad023":"39a02e9803624f7e90feab8714cddc41e01f8fce" +Nist_Vector_48 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"80f757fc06409b70d733efdb68b520f3f9078ab936c4479fb98d0beb1631d8303324470824862224b439bc85decfccb8de8fbf36a2bc4ce3a092688249ab4eb9febfad268245fbd7e72e0f240500af71292ea23c8ad4b71e032106f587f4611663137690cb25241912763c5e1879b3ab67e2187f92d821fc81f552e2c355bd73":"2a5f637f4b886a3d37c4369cab04d78c79f1a3a8":"1f03013e66fd1e633ff743894c37f6964839a52cfbb6e849cfb4eac9a3c9cdb55c28e14788865c212be62047cb39c6365780bb2e627957d34e99232f69170a8efb894d8029d1b8bea8b911cebcd43b86bd536693f18bfe50c84b99911181ace14c3fab9fb6acd98786f9d2ad129c5efeb8cd0941a3d89098d5721d435343cb76":"b7c75c380bce0fffd59dfc3993e1d0724da877b6":"c7db4a9f54d882ec5f561705396c94834dd53c5a":"6752cb6be9b87265d76d69b382299678f96a5faf" +Nist_Vector_49 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"36a25659a7f1de66b4721b48855cdebe98fe6113241b7beddc2691493ed0add0b6a9fbbf9fb870a1bc68a901b932f47ded532f93493b1c081408165807b38efce7acc7dbc216bef74ed59e20973326553cc83779f742e3f469a7278eeb1537dd71cd8f15114d84693c2e6bbf62814a08e82ba71539f4cb4bf08c869d7db9dea9":"bb318987a043158b97fdbbc2707471a38316ce58":"c9003995b014afad66de25fc0a2210b1f1b22d275da51a27faacda042fd7645686ec8b1b62d58d8af2e1063ab8e146d11e3a07710bc4521228f35f5173443bbfd089f642cd16641c57199c9ab6e0d9b0c01931c2d162f5e20dbe7365c93adc62fd5a461bea5956d7c11ac67647bedcead5bb311224a496aa155992aee74e45ad":"2ff654b680e722ce65a560e785e8ce0b4773c86d":"17cc53b5b9558cc41df946055b8d7e1971be86d7":"003c21503971c03b5ef4edc804d2f7d33f9ea9cc" +Nist_Vector_50 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"65a3c92453f961de7f576d5a1e3106c38b7f20813994b5dd201546dc455065dde59edcd84d0fa17a85c0f9f99171d67a34475cef4f311951f2eef7f6b64a5bbc6da6d1b622480cde56a07a77aa6040ebc1fcb265b3b624881fd27203dcfe8a12492198474a990cb9f34a1943356fde5bce3fd83516da8bf780f8cb1851b3b954":"59d92aba23f50ad08b1d7c2ad560ded36b94ebc8":"0fc514ca160f34f2f6ede1ba5914d5844c9de514208c72569a0b36ec92c8b2c8fdfb7d68127486e58a04a32d0d150e51bb05e66624cb622edae19a6b4b1d8317689baafa30168ef3759ee82e614e4761900182df90e9cd2d931153771b8be30d89c2fbb95be7e05a4b29da968ffebbda5c0c9839354bb59dc697a269063f2f50":"3d0ea569b4dc69342955f5b240af66d228791e50":"77ffaf4290c41eb089c1d7be5c8d3833027702ef":"cb753a2d4ce0e59851f814779f343beb615f2770" +Nist_Vector_51 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"1526b64ce41cc8e2cef26f3706be530a36ac9cd16ff69f05773e9447ed9452064b7751f3a64919bfa3a7e1020dfc175a10acfdf096fd41c03372e4d2abd7ba887e0076716ce9552f2c7c8eddb1b3fca1bdcd23300ce2b1677d4a2debeaa7053466e59b098771bfb9218e0fb4ab6b7418abebcc34d681e14c4a8975000d83bb44":"716290d0ff2ad2329be2cccf825f2075be659743":"d30eed739f46479364d4c2bec18cf4c75c324f8db8184d9c3c175556a00acfb0a6813887b68706e70c167f4063bc0046396ba1bb3226c29221bd64ec4cebc990a7b404e26e2cf042304a7c57ab7de418ba671e17f7f502b9e1bb5984469b304ebc0c3c3a5a69cff7abff4110130316651e0f93ebd2834dd044eae1fd6f045102":"919d698fe37c027e3e40cdf6e77f81e96d8bfffb":"31abe8e7458ce363a5f3985111b239bc8df8dcb9":"1d967be0116128699d167fc16e5e920a41311669" +Nist_Vector_52 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"d7852ee90b3f1120bb11249808c7e7be14fe577bff1886be3c42589a6eeb06a1834110862b65d26cc5a2e5d903ed24328d684c96e3babb37ae31f96d32f57657a3bd7798aafae86f44ad8981e7cd47d7f31bb4564a757c925c64da9820963c1c5148f589d6393004a6a58aa2c8a578f4db7595f886170e79e9d57bf7ff8fd0a7":"0531cb42f45bb813f401bd239044df2d3d1968b2":"0dd37985163f93618fdea8e3975419fcf7446ff980851e18932d7494f809c0ae9c03cc39779ff0422cb2248ae1986f9aad2a43d6fa6878d244b429aac5ea80157980577e5ba0d11b1fa340a283fa0a2d651e024331e6bbe7d01ac034db37b008b91f9f88d135fad23af8c22765d833a9c9eff7accf668e17f9a8bdf59317c202":"739dbd1f84b6be2efdb921a0dfb76dbc6136915c":"44c2d6509874ace71acd1dcc32335b394c4e41e0":"37e78f13aec052eb7b07a8b9f6d54dbc77829006" +Nist_Vector_53 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"9ab91448a0dc9694be173ce6d9b522ce0e2f75fcb57720fc5eb8f92d8fb0e195030063968925a568636f4aea1edf6c5fcb86dcedd204539d8c291757fb8a51620abda59aa8f8502e6904bce0667d92c8cb3fcf1a61b1fb0bb4e9383b37eb469bd5c2f5a77680da62f907c2e263cb48402b4b12985eaab90451885e819b3e8c3a":"6d764cf62a268b0070bf80308622bb31941d4763":"49d7f08fde0a83cfb8116c9b7cdcab29751fca5ffe310760fea713c30e95e7755e65ce60928893c65020ee9b61f6c9c89c07e0fc503b7b031368f069578a9e6b451fef369ef90c26dd660ee1a6b8b714d1cc28245e9f13f187122de26ac2fbf5bccb7caff59f1de910551104d3a0e8fa9fe6b7eacc9a5fd556b7bf7139d6edf9":"c66ea7177cd6edf6b9079fbcf6737d3890469b19":"95da25d06ff9c02bc893fb032508304c17ebcf08":"617adb8de10da1a87413d64466b482409d27bce7" +Nist_Vector_54 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"c9c0e69f840cb6deb984c2575d7f6816fa35af03b4429c703a5aec90e7cb26e52413587f3bc5a0772be7b5e589c9a76071c1739833f4611fa951d375820b48d740626c665534d60487bf3e0a84eb6389e099fe621f269491c3b8942e03bbad2a5220caf51e7b4a2650e4b300024a0a96f0861b3206fffca83d0850f2a3e2a06c":"38a62d234e1aea0e847621e79dd17ee9d08bd9c6":"26f73219d0e7dd3a80e7fbc079d9baad4512891aadfd2416b1859f41adac31171ec624d8a4d6a10d5de1b93959bc49953f23492f18ab765f963a98584807d66629e5a1e057d77d42e3363458641a0469166a0d853b27798bd848aa0d3ccdbb40fa21b9fe62824cb2c7cc62425978e672aff0bbd8c8cd08e46385b0d6219dc56e":"5f5755dce464174adfe00affb55a71222d83da85":"b6b25a9da110b5d57675889eae75ab58a4d8e281":"5a60c2b0adbea4c5be065bbd0fd0e3ce4bf29200" +Nist_Vector_55 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"4002de825bb87ac346bd8487cf6be053cb30ee67c66434217107a8b0b52e5726900615edd2fd0acdf88a7e65e7dd3ba6abbbb371a1c840250d9ce809e7b1111f16daf5194211715ff5fe631e378408749848a0c81a289b4338bccd8d1053f863197ad02920fcbca514e2dfd94a8b00f90cf034adfd776f4dcaef2c8dce3b0539":"c8f0d697bbcbcc0e31864f8319984125f52ff5aa":"149bcbb4f5983db56fbe998fcd02d736e6d2f18fcf96468cd7e99bc647436fbd74fd7a2cc2f0d8866952b97b44ff644b5665cd1065b07a2c33d9151deb335e3522c1b77da1443a1373c93bfa040da5a1353b88a78e3a5a084e6c442db03f7fbb4bdbd30b1af3963f8c5d3e83453294e3a07ddacfd43dc8f9e83032fef78420c4":"b4281920a775fbeefb89615b236217fd1046f2cf":"d3cde170d82154ec1bbd9077c486971120600376":"b008fcd01b5e49a85a921bee1ddd706212799086" +Nist_Vector_56 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"f7018ff0af6776ed4234c1fb9cca1f8cff31295cb9f76d8b73898430097c49a40028441771ea1de08ffd5cec7eaa59e32b3a170329139227ba86e0c5efcaee382bfff962249da853dee418413f201a28fe45b8293c262089d2ceeb9af67529ab011f04f5eeaf82ba32dce9a9821762c3351b00206591a3f87c5260a4263659f0":"9dbd262da7a529f80aa667b27a29d6a52671fb89":"6c206e71fed8b363fcf571786ce1b4e52a404de7eda7031e5d93a47ea668de43dc7073e31d3b6b125ae3e8ee45aed273bc878c73423b225a1526bbb149a0ce5e9a2d2962bd6d332375860f84ce0e787a0af93f44e64edaa2dce6ca22bcc6d48b84b0affba342753b1842941067d5b8414c356138e625bb506566a27b335094b0":"0f0e02596ce6674684e7ec448d2938de12842fe2":"079b08bc016c543d09d6b276c023347a3aace9ae":"164c3c380f209feaf8ffcf53691ee3031c3b3fff" +Nist_Vector_57 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"4a18bdcccd46bb89567ceb9c1e2e500a3baed24ff2c5fc7f83cb3cf6a6f38859a1a927fab5e2fd7ea1e1a4154739301cb1957709103af886c929cf88d25ced5cd6f8cf3ffee7b088edc2f6abd1114398a3ab00fc21bec02e8e539ba12df70a587fbfba63195c6449b2b849547c42277834e1ec086b5e53d949846769e89715bf":"5b3e9cc0e0be3d714d1bb2d95e5146d27a58f2ee":"8e668dd1527b5d1e56aae4a6ca225e677368412324a79d98bfdad9a84d9f87c1357518c9a5056ea6a0882e94d4ffadd97d89bcf2f32ff442b25dd2af2a78ddade46b75aa8a5b1a1471764ab699d700cb2a28b959a3848edbbd6c9514ee849f833c43008531365a01541f9c0b65d5e7d3c21dc8bef1369a41c0405f3723f67910":"3d9b8166860e18a9306026ba669a3620c2954ad4":"b22c00fe0bc2fae7a4ab74edcd496c64a999c7d3":"85ba8dbbc93ab94a76133d479e3f79576944e6ca" +Nist_Vector_58 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"75474711821766b065e2448601e82b88153a41bfb5c6b6a9ddcf73170ee374a6625de19c560bcbd2020bfeab5cbfad8fc60ccfc95a1b94fbefdf815d9bfc43fa59315e7093d5685274b8afc3139b925ebf697fe2699b0feb1e42bca65e5d4eb0b4514af92dfab85e7f2666c87e9789395f354ce33938e9623061113465a4e2b9":"9b4a2536a108892240fc40c8c69a4b9b903ac760":"74a93c73d75500ca4305ca3184475b53d96c6fdd417ef23d9dc61b80bbc1108228d2543c1c3a9f2e7783ca69b019c0cd9a6d2b62b0ed93d4229da87bfc21f9e4bd0dea2c4e6d4d2f88201ab0504b31f4ef1558adf493e470adfc572ca68debc46123589ae913b967983dbcac6bf3bd8611137e39d5870057ae18cb84a76aae30":"a993b059a49855e359014151700d02e8292ae708":"1ed131c96a2c310e1f7976d3082a69a5af45bdd0":"70663e9ad7113ae57d4af6907712e0aaf88bc07a" +Nist_Vector_59 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"340df708d457df9413ef2bda225c5f558b90966cdd531a0b5aa745d5c3ea790debea224861ef12fb1638bff0121ff26dbdcffc299bf9f3a9c1fe6027400ff14c34fb06f67db9c30a1dcbfd996903523d85046382ff280418d974a3ece6b5fafe305e2e79b1d07a7c1eeb7a1277a82282be62831df7fee38841462602986a8e9b":"067e6e55be4744723b6f056b76629e93c297a585":"6150a68d64adda3d3fb5a973c62b992ad3fe538af7161bae41ea2f1799304fe5b8c864e061d133d94c16a4c6b0ed8dffdf2cefa7394015e75c57b181419dcfefe3409d3b53d86911c749f9f28f7c1de99f7e4b2ea22a48817ace4fd9974fa53b8d4f05f5731488813803d7f3aaf1cfa138bc73c4d27ca1621e9226661883e9dd":"77857e6de8f37eeb6925a87c027a3cd88b9d3584":"4f182ad42cb5671d3162bb9d04a06cd20edbc558":"a6c5417947447718ed1cb89a6efce2d3116e50d1" +Nist_Vector_60 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"9f23c82563ab7c0ba86bbb989335000a493b291e5dc17ce729494958903623ed99df344230ffb626b1dbefcce059ae16c2ee7ee6fd2a7807336cb71b8853e2ed3b74b2faac82a831d53e03d7bbb96d38df98fd19bd4c1a6248cd507c89f7995f59579afe5319731b443d6871e558f5b77f2f9a4dd99efb305e27916594524e02":"b457e1756ee9056fda7207616cf7c04a33afa66a":"96d7451181fb253fbc3f441409be5e5e0144972610e37fa82bc2af246637a4c918023097875255a217ea895daddf46bfbb174749b04c59fefa6289684f2f9aeadf5ce7ca47f0032e384b7d50597901181501cb5915fb4686a6ad7bcd5b46862411a4df22b1ed2a56905e07c0a936c9944213194ebefd4ec68597cca036338b3c":"b29f28659dffea28449435b5a044487e29d82d6a":"b6599fbddb4856276df448cf09d62fd7657de6c3":"4b49589099be5578322d829b87b43ac07f62e35d" +Nist_Vector_61 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"3a84a5314e90fd33bb7cd6ca68720c69058da1da1b359046ae8922cac8afc5e025771635fb4735491521a728441b5cb087d60776ee0ecc2174a41985a82cf46d8f8d8b274a0cc439b00971077c745f8cf701cf56bf9914cc57209b555dc87ca8c13da063270c60fc2c988e692b75a7f2a669903b93d2e14e8efb6fb9f8694a78":"07ce8862e64b7f6c7482046dbfc93907123e5214":"60f5341e48ca7a3bc5decee61211dd2727cd8e2fc7635f3aabea262366e458f5c51c311afda916cb0dcdc5d5a5729f573a532b594743199bcfa7454903e74b33ddfe65896306cec20ebd8427682fa501ee06bc4c5d1425cbe31828ba008b19c9da68136cf71840b205919e783a628a5a57cf91cf569b2854ffef7a096eda96c9":"2f170907ac69726b14f22056dcb37b4df85f7424":"a53f1f8f20b8d3d4720f14a8bab5226b079d9953":"11f53f6a4e56b51f60e20d4957ae89e162aea616" +Nist_Vector_62 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"6f39973fd225167a7673cd71ab3534d2686687c332f93fd66db5f1ca99678efd2825a84cd7a7107adf96501dd1d05e7bbc8d113e087bba77b2346b4364132125245e9aace3a146b576f654c86e07fc1914cafa209dd6d04845575dbb279cd1b23296d01ef505b5e1ce7f2194f18988f355c9b34f920ab35152e03bcf792ac529":"8d75294b56262e42a82db41a4039615396574dbf":"110e398e36c9d2726e77deb465dd23303f9e387778b549700a52b9a5468512ee377ce3d7dcbfc6b64ee353eac6a43898b26484058ba1b24b229cd69c994d976d43344c181ea6c47df0062c09a16b23ab6075c04a0899bac3e4f034a983bf90438f6ac26855d8a5fded90172e7e8c196a2ce7e1fc0dac94278aff1653c3ae09f5":"66a1322607ab98aaa57c12a5cc3f59dce8d7d0cc":"1b9ed39bcc4b46ed0007679ce9c3f6dc7c4157b9":"258d4136ad95b704a7959d04096dcd781eb54bde" +Nist_Vector_63 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"7f59744c790c0f985a9ae101d9fa00da3b95d2473d792805ec1d6d1e95222a6f30ee6ab8fc5a632057153f237ad3aa2fae8f1e51eae75906d07e576dd0021ac1711b1c8853e62d27fe6b098766b8ce3e76d347c8e49be0ab05d0d12fd777a85cffc7ad1207a9aa75643d7b415ba4b1b97dc0ee19d05a607ba063a0341f176104":"25b7fedcba71eda85fe189bf0d0c43214ab6388a":"3ead9cf211f3859d5baa5155fb62331bca3fff9ecbe182ebf8b04db0ebb19eda548c86db4cbb5eca98ce449cfd51f1c460d7848326eee22fcac7247fb889ee415c4933a909c78ce9bc50ee190116da9ae2547ae6242a340ddbb9a15ac818c4677f2919c64509d03c49d1307bb2cd78e01ce5b25a9f47d828fc7584ebce366c2f":"8fd754defb1274bb7ddea0fc13fdc76722442d86":"38f52df78b0e454d3583208a0fce03b904eec816":"5cdc57a943ab1f269ca11c63bcb1059ee76f9c2e" +Nist_Vector_64 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"16250c74ccb40443625a37c4b7e2b3615255768241f254a506fa819efbb8698ade38fc75946b3af09055578f28a181827dda311bd4038fd47f6d86cceb1bbbef2df20bf595a0ad77afd39c84877434ade3812f05ec541e0403abadc778d116fd077c95c6ec0f47241f4db813f31986b7504c1cd9ddb496ac6ed22b45e7df72cc":"3fee04cc08624f3a7f34c538d87692209dd74797":"6e8c85150c5c9ca6dcb04806671db1b672fc1087c995311d7087ad12ab18f2c14b612cea13bf79518d2b570b8b696b3e4efcd0fda522a253bbcb7dbb711d984c598fa201c21a8a9e2774bc15020920cd8c27c2875c779b08ef95093caac2c9cea37ec498c23dd24b684abcb467ec952a202cbd2df7960c1ef929cc2b611ca6c8":"934552738360670c98b9c5384b639c46cdecfa83":"00018f0fdc16d914971c8f310f1af7796c6f662a":"62b7aecc75cbc6db00dd0c24339f7bdb5ae966a5" +Nist_Vector_65 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"a2ce90b51a480c0668b55936bbeebe3679f8d406a0b694b90345749e3b9c67776cae9a62c25cc011cdb3180263ddd73aa2090ec7a749092f6c7816c26744c5393acb08c6b7b359bb3a3c7543684f8050ecc6422234ff24978ae06b91d6a24c086d71eb1761caf14176d8bacdcad53b7895bdb0e053c616b147ff73d2d86ba3bc":"2d667bebf445cd3ee45d5815e07ca5735b858ada":"0e6b419da8b4db802d938873e3b105ab3eff432d8a1376602059cf2e510f696a2a4e42025670db0011e9be31e8b1403615b9a339ce654a89a2d462ee20c080c4479648c5c00e172ecd537c934e7534af7002bd6fdafab56506680c019ced38779d954091645fedf5d0057a23ff634919fc56a96771ce21fa99ecd9aa7f7985f1":"4aeb4911d38f1f634ddf5fe6c970d943ea51b266":"5b13f1337ac72e419867c92f9387f9df62883aa5":"90ab5b68fd8253b6bb64c61759164a97834c39e1" +Nist_Vector_66 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"3b6eeaedc5fb38ce8691686c89993caf17c9e24fa565a9e8d48436b87db62fab839c42d81fb1f8b8968c826e78d333b1d99d5c36e08a9a0ec7554c2bde07fd8ec422af128246ba3beae18ef2be755db22a869202951cd95796fc2ff7ba2a6967d19e5ca2304655bfdf879b7747f80a59b1dac0461cf6e490378e56ab378584f2":"71dbbac59768e1e3093f0c60404731a2ead482c3":"4a7ff667f7ab2891a8a69ab5d15d93d1fd833906c9b629fcb9b49e84d8ecb35b397d93839d7985590326cffb55a70e4a51a2829e387290f6fafb7d226151c282470224fd717f3d526589c6eed9611c5bdf4bde63fcc9204c8007b0b143c49d1981835658bcf800a2157c5c143d76369fd6e78d0a3f800b8a3a8f0e11c9059dcd":"8f78910d1e8a9daad9523626ee7ab1d0a5b4d977":"61380ca86798fc5fb61c35675af08d5cc13c25aa":"54ddf68f476884af3e0e6536f3a80925ee63a402" +Nist_Vector_67 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"01197ae960de90a93d9736896fe136bc561f0550c6b1cc3631b31df683017c2ab8c6f41d2745f1a797e0e89dc3d5878866c3694a080366757e6fd892d26668fd2d860ea2a2b67fdaca96e32297758787ecc0a7e1d304cc719803272e72e339b3f34c347e47b91a1ed69ca8062cd350dccc9c2264732b9fdd8462d9f6fc76850c":"45963a0771456d6ae897edf7579091f5f8c76747":"373081770a9f4dae8df5dfa70503e149d759ca37408549aa34d1b49b3176a39d7c4661e421a1f5d61e3f77b3c4b39bb2e63cd24919a2910a8b155e1758f5a375da60f19d2bf4020e828f4237eb3e2a36124a6a3914469d6833695b83b9377fb285b27bd2689933c189c7fde42e1e0e20308331fd56ed0db2efbc77ea3ac7121f":"1f68d020331b81fc1aea51907e94f7d62ace9135":"41ed170c8bf6f20fd1ce18faac97565fdb4fe6f4":"7c8c6feace68c97ca43780741fae58f2f61bf765" +Nist_Vector_68 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"0d5ab27b2b7e18cfce4ccda13aa1a5a8c18baaf39b14e642b8f81b30cd5418a1dd05df22599fbbb3bae4fee1e4b2c150a23e216c133fe2d8235485e34f80685c66bc0c190af67a0a49930b476b2803e12274cd43090921bf668fdfef155072a3cdf17901427afa51318afdda937e283e2c60d85e3bfe07f3da5f992c1fca4b98":"95bc588bb848751ba57d7a9ab340cb00e79e06d8":"1ca36e3505ee70a56afd5dc40a48e97979e984dd2d896abc7a491d3461c6931668a0cef11e45bb66c611137999907ad7e1f7cfea7f7ed49aae935bfc41443293e71dd2fec29f37a9544672ab9250caa28188f390b5d4af13bb05e9692c1c6a4d6aafebddaf7eef1834fffe0f5391bce243789a2d55d29e2b90ce120429f2a075":"07a4f8000f0ecddb72302cf4d7975c7efc41c143":"66015e5fb3abe9d78523770f7ba0990031065ad7":"4b8b153d5b01ddfa91f2dec6f0faff02e6e87218" +Nist_Vector_69 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"906a933bc823a307e2ab29a4a8f7f1510d5d303504fde38169ded168913e3bf81d53a4389a3e73a3efebd5e42cf402bf9fdc5da5ef46878165ada6d2e07299035a3987ed6c2c6c8becc44ea131a9493e72aee28242cf7cfac38ee870e54eb95a6efa9fad74354b281cb63ea71652eba1ad73f841dba7778f3a03d3e00190ed68":"8295ed7e125a65ea1762aaaada34602a7bc76845":"4f3ade3ea4f7066107321e8bfb12eeaf9b3c7bdcc6147908754231156b46e0639c9db9d5447abd2d0a9223c85d63d8b1dfa69742ebf7e0419e608c4b18c3ad9f55f5d2848edbec4e7180e34bfbb1f6b6ebbb68649714b5fbfa6cfab4a01f655008a95a7eedcdc2f7171094563a3c1831e81f5ca075c6e853beeae87a67ff9022":"8148e40362a255d240a3e6af746a8880162d78ad":"99c91e0794723bcde34594dd2268418dfb353443":"42e9c49d60ad8f9b41f290ae6b772f44be62cea9" +Nist_Vector_70 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"1d6ba43a0ff677cf8cf68d6a1d3304d99490a7cae56fe35318f38ed0f5879fe254703fa77458c45e8a698469b899a215c25e869fd28741101d27dc111ffad6980f8ebd748f6977d5d60438e6edec37a49d3011f8f0f08525156ae60bc91abe661638f4b9c6c365c3af1713bf7f7225d4afad7a1b531a331133d8b8fd238598a4":"8d3c302da7b77ece9ce6e280e603bd260d2dc144":"08ad77f233334c04ca2282f6dac0b0d8a00d596e02e836a767a146ef80624b33fdba8b35204b20bee8ff2be9a82bd80131c0aa898b17eeab5af24c20551d5d636a11548fdd2e6c616b09df86b057e5702146ecc4fa2d44d85bb1427e7e3576f698b4f21645a1e00479d08982b0573dd1981bbd405c2a45d7de9242afae8f95c9":"79989e8eb43520091706039415794d2306329861":"a2b42cca55bc1ba33f8252d1a89c8d89b00b3950":"2ec5166e35e63f0fa116b3db1bd18681a4399c04" +Nist_Vector_71 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"3bd0c5b759cb710c52b81fba48b6771cab17bf1b67eafd08f4ee1777dd473064dd0bec98d3582ee1e991ab9a91a6fe558a41db9ae6b21a057932811440d64c786b22d150e3d38c71900ad5b61e0530744e765b5c2ef30bcb96e726e3079e440086ef300bae9000df3403c33a79849f8f83d6c03f77eae98052578d82d628e65c":"4d3e42ef42a60630edcc842f25a1b33c8851c742":"3a1ed976b7934bee3e80d69fbcdd35f82051ccc214bde6fa756be67017ff60ac6847cf8d1f823f890d26af8cd351716ad2d4eefd7f06c1951ea4a7db5caf250f407b78f21fff425d0cba1b5fb35a5b5dcf062a1cdf2507af74789326710e334faf3c501bd8c8347225f94f8973adb7a8b5def9896109d1efe550325dd89f31d6":"6c59f3cec7e34db174dcbd6bfe224d52226c56cd":"77d62ec2a95beba6c672d8422ee663d1d18049d0":"2a339cc8f567c12149a8917375ec6ca4b47254a1" +Nist_Vector_72 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"8dc582a2b5af65e66ebdf5b533d8e22b38b5c1977e578d3213a110e9d4837a74d4b7bf7d71875690b5b71c8e8afab89434c46a8641cced1a130e21cd0c805ee45c134c7c0df75d5cd30c41818f7ae475dd6022877c743d09d54f0c94581ae7bd4b423f02e19397be7bd4a904b88cbd2f814b1dff1e796d9f2d1c8470b796c69a":"6a6a9874f0f89f04cbeaebde3833ae179ade3f5a":"5d6dc1749f28cb8f7c014d5c5516cf5bc222c6d9337ac0089b19b90b321956cf6192f3255d0eec45840810c21fe91cf5308948852a57cd0189f15bd96af8380d19cb821b1c56afdc38a94b2c32feb18213939693b69f2bcbae7e70ab09ead3b6a8b7dad3c4f521ad0455dd4e872b3627d4fed20d5efc78f6ae467fb9267ab1d4":"27b2661922214411aec66e58cb36142ab3e5a256":"05363bcca193d726cd20e03489e1b13b7df3bc98":"31bdaccb29e4a60023929f182199c070b71ac575" +Nist_Vector_73 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"477af8c025181b557732b9568634b1324e6669b4c28a0bcd4c653d4c81ed68b2a2043a800a314ba95e50deeacc5ee9c2ba6f6f62fdba0e86aca227d727377552a3abdbab601c2601846ec27a192a3f33e7ffdbe4a4aa7beb2b3ff6c91bd5cd5c890bcb6f4c908ff5b9b555e2a0a7df8c3ef6770136bbf009755bf6c3e6307310":"17949e838d7c93e1d837be65b3c4482433a1b208":"2cceddc9e2cebbc1e99b83b03053bb14a9cfaf072b45e4746d18cb3901f6a2c3cf72da66b0b9b3e105bd4cd0e5427d7e9b657ed71884cd49f51fe8fa18a366018a3eafac3381e07a5b19f6d3862ed2916094906e75286eaf1d13c485744b270404ff9adc8e177833043bdc34c307e6fc9c55c53d8ff84a6e251038dbeb5ef774":"620f07d7e7ced030e669685ab8c39174d88c79eb":"3591c521b2a56cf46051c0cb3d444b9a22fff63f":"7ac78ee252440cf9e8510494d1fad8b518f1e128" +Nist_Vector_74 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"bb6593ff219c9f20aa47e1e157e88ed59ae29c8940a527c82e0e0f2e855fa98e94e07be1f6bce3832b7ea1e60a5c9ef583f2ec7b179227e4afdcf829d673e1377f832ae38e7cadede415964f12baf775d38ce38e945563e72861519197c2d08f28d8b6466562e059ec41741de349ed5de2c7d6cc7518a87720a248b301733a47":"301c11a34edce1f7ab040754e0b2d4fd88572187":"15d9e20c3f39cc9e3b8fb65feb64fb1568f6efdef6457d231c491ed51731d58f06e45ea5d665d04969823da4e6750a2c3d16c5ff6080ecd09aa39c006eedceb4dbc16ebd64bc5b1e44b831a6bb25afbcb3000fa6b6c2000860014011189c22542c145e407e7b59f6d3fb1e136295ec850b14ff2f4994ea37481e80199910be8e":"117e12f88d6e44fc7f4d51d5384fc31b2e3419a2":"61e727716cc96914509740a7cba6e74a9dec6406":"2e77c14f01f22180bcda5725cf0eaac9ad13a7d1" +Nist_Vector_75 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"565f19244468515e8463d07b425b4d5f81ff2efab5156ba19a63734219c226ccca5903bf9c35dbca0961db7c2e3f6944d057edfa6c2394c39a00f1c42596e7ee72ed644c6a182115bdc44b9010c86e7b0ec2e3bdf7016c5e04f455b4cb693e32490b8f494bb4103b3b5ea6808222452841b733faf735f10a95fb283dd86ce593":"07dfca41446b2f4e1af2a67bc8468db9a9c2dfe0":"664245aaebcf5c055c32109b2159a17473043087915f14e959dddc0c9b20c726f0124f1ecbaf202fe2676afdabd346a7b5bef769a25c6f733612d7378df1b2d4c518a2da5b3a4cd0252bb8180838a46389a84693be8cc24fbdc639b62cb21d8abe1272b5aa06222fe2133fc5556d24e75496a53e1934d3b5848e510b69da04a4":"4522d27cd17a6ee739873d69f107d872ed7e2db5":"5ca07bc7cd9f7a60cf79391d873b6fddf5a48cca":"9799c74a806fc196e0223fb1a613fd178cafbd99" +Nist_Vector_76 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"edc6fd9b6c6e8a59f283016f7f29ee16deeaa609b5737927162aef34fed985d0bcb550275637ba67831a2d4efccb35296dfe730f4a0b4f4728d1d7d1bb8f4a36238a5c94311fa1134a93a6b4de39c085e9f60ae4e237c0416d58042bb36baa38cba8c896295b745d5376fd8ce42eb6ee5a1b38f87716b265b76e58cfb24a9170":"6132e551cdac88409183bd37ee1452cd247d4834b08814b275be3ff5":"289ff18c32a56bb0b8839370647683a38a5a7e291410b93207212adc8088d30f93e9e4abc523f3d46936e7d5c90d88742b36afd37563408f15c8c1a4f7ac24bf05f01008ffee70c8825d57c3a9308bad8a095af2b53b2dda3cbed846d95e301eb9b84766415d11f6c33209a0d28571096ab04a79aa0dc465997529686b68e887cd8a205c2dc8195aef0422eba9979f549ac85548e419413643b7244361153ada1480d238cd00dc16527938955548dd5d027ded1029eeeb8ed6c61b4cd59341d8b15466e9da890a989996f4d7691e6072de136af28b5874bf08bd1f8a60cfb1c00888132909f515e04bce81b02951aa41baac68ffdb8c5dc77a1d32d8f2c10dd7":"7197392d32d0af6a7183cc3398556f8f687d86a8ff742be6ad38562f":"45df2f423e94bf155dd4e1d9e63f315ea606dd38527d4cf6328738c8":"59b3e8efa5bc0ccbf4a3cbb6515c4b9bf784cfacdcc101dc9f81d31f" +Nist_Vector_77 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"3bd2ab08217878e6774ec7797deb75d5c94c40e24ddf1fac8dde3a29c86b26f57157d329aac31a6622e1d6dac97e22695d7d1f8e20aa26b06795c2f878ba5d2b9cc4b16d5fa60a5fa5c24c09031de2f970a9b57ea24af17192ece21a4d120fdb52e62b8238f778ff8552fa453c0a8891243fc8757188e9c4e0e749f7e9cdf1c1":"32d53ad2620c156e4617a8680c543839c9be93103e80cc0fefa44ce5":"b9b0e1cd37bafbedeed173fd709983f53c2c427f9f61c895fac9eb549bd6201d05efd551aecb98b2df80142dea7a35491d474a3adc83f0da8dc4eacd7f6d7201c6fc0ab798abe89dcd7d0310d5f00fa10d211f18ea853579e2fe31ee55371d1c9fc4cfb050786586659bdc0f1aac4c109b9e4f9416d22c42b39a471311e28a8ed62f1f41bcfe06e074bb2f1acd29597953c3b69d3a78831fb2f83665d04a1395775ea3a2a6ea142ec00507badd4de0d9c102eac7bb894f7453e6a8e0dd3f14978377d1ddb1fdf1c55835b9924f42ad45c847c79b3f83fbf924f80b78f50329731016763e01ba8ef69e81523e181584f45c21e3c8edfed4e2ec56fb7b02aa4ee9":"2e8e4625de74e31bea9e480a5de92890095b6ce36897a2337ff97d53":"6d19fe3c415d6b07d6a1039a1fe34b106daa2eea4cbca971cb669eac":"14d7decc2cc05a1700fa256e4d2994bc4bd957bed0baf9a18bda7090" +Nist_Vector_78 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"c67fa77cd7351d100c7624e25418481f8fa499d75f5949a5cae60f96a0f7bfcdda7dba373f9f7512a5f1460a95213077cebd912e2662c43ac6bbe38c4479b04151a5e2d2880902d031aa0dff3f41126dd09fba5c0507634ed16c3938fbd3a96473a8b1ebdc37d32c767fd5932efa235555f3825a1595369238675453604d278e":"062bd01487e413074126d9d47258b5c7c77790a9db0af952ce799eb0":"31939ccdd393f747541a5c69f8e509761dd67eddb42e0bdfc412d4cc30d368d878d26d856c5290ec746b59c5e5af65ef3fd62c9a2dccfc1558dfbfb62cfecd7838e6d59495b20db5ad9d78e82f046f9f1598113aae0a79601d6b94a32e05f6ecfdf2b9c4cfa720debfc212221b14b0dd6f7078205a4f218cd4b8f10bea8fa481eca5254f365d01f3c86520bf254323d5634b96920a13b8f29d734e07fde8064eb0c9f8ebb6ae0b40b4aa7d26bb8d80868231d4558a278045cb5f2951cbfe0dc97bbdcee7af8c9b1e3b63cb49dc29f300775cdbe4d2d27894e27e0e7c9eada13a359f0b92b449e9d069b95bdc2aa7c85e56811c07207a150e598735996a6e5349":"7439c7aa4446ed540ba50b9c817792b08fc0278fa0af2daded03756b":"7924b76ee76ad7ff2ab327dabbbd31336750fc7663df4b5b94eeb62d":"5914cf965490b0bf8192fc6e169754bdfd31c48d716361dd15f45bf7" +Nist_Vector_79 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"fde7434c41666022d6d7dabc7a67315b1ff49a2a85a6168f2b6063e3036a4f35e66d2872af3d97e5beba239698d88e13bd036ef08cf0e83a41664c3d0d21863c24129a6a9b27b8e96c8029ec673e07af7246ab77a56c21ca208df4b1818deda906b553b2b23a37b5a05e29825ebeb47f53986c2bf26d731a5b731fffc353258c":"6e6bae97e3b37a402eca050d666b6483cf7d700419c5ab1eed1bed05":"59a14e36c9ededdce8000f04c6f7401ad987f1c7a5a070b80e0aaed7751d1d50d99a580cf205dbcc3797a0a0406b04776d80f2f2df418cee249b98672de7e61cda85cfbe903690e54642dc2a12a90ecf88c59256a4d77c4c0cb54e13fa3647b11431e1734f3ceeea04fbf3459665e999fc0f7a754683e48cefeb4a95fe473911ffe0de0f738960753dac33666c53ed2893bc63dd4162d7a6328739a252cdaea7a948c97d024153b55d14fd5304e3575048418808a952675fafb95fad84b1156b24e98e048aa777a745324ec13ba378e83b2384bc2e96c6095aa786bd28fc3be6bfa4db0c3c44fed4c351bd88a19e179a6a7bc12fc014f17de46fd12ef1287f72":"08544a6237ac967e5d11f2eccc6618399818b891df7a04d08cbc5e74":"49ea82713aaad799e263809e161b0655f1e74323a06041836f676980":"76b3f6c1647f8d17718ffb92d6e1424606ba9724e5290daa4ee95efb" +Nist_Vector_80 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"6676a3a131cef7e5647ea7590da3c704a0f5dc3f37f26913a70d430609cc2497c45e68b7bd6f5893dba26287ff0d240bab8a0761936aa709a2162ebf1c20a6136a748352dc39ba4403cbe4b0a5a54a729286dd193eac1a2e6bdc150fb06369be4443a60e75e5330083ff009eabb05232c52368a26fd237c7c3185c1c7e7d5955":"18faf583215bc4fa71791f6f34e682ab3529aa9a1a71c1fc7bd456a8":"ddcdf4c616fd6e4016099fb34ebc4ec507290762c5ee6876f10c6a2dedec97ba86a6063aa8ff069f3f3db40c9464afb1ba7ed691773afd6083586b14e35694a9ddc376ddc39dac57132a05bf88a0a6085c72a80a21c13e590c68c4e98eedb67f1e16c8cc7e9e25ff37c87ee3be9adf1ad0b838651b0fddf8d026969d4a16bbb828fcaf00efa306fcedd5ae19ca1a1abf44a2bdf6f994123ce941fd3523bc1335f51fa8dc5d525358bddf0c55fe2ce07ce974408d9090488837976f16845eb7a82d04c43a704be2dee1be2c8683b2d9e5c44f1833f5c46c65b6e62c2a720421bb35843fead7b9e0b3fc04c646be39e890e370b982bde91f2fc18442b650ae602f":"11b25b09408bb5dd784ad70264e585c978dc02cc1df8bb95a28aedfe":"1658a7ef2f444b014a1885b1eda8dad3605b96c3948e544e4c8825eb":"602150f67b19a5e3e39fc53abea02dd8f3b30d25c0b4ea0bcddcbdb0" +Nist_Vector_81 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"071f06a11588584da5576013029b5a14712581a48408bbfdbe34e17568c0a0e4d12c1e9c3fb227101440dd8dcdc415e3b49f68a26a0ec7612a10bbc64ddb8f7ec9e9750d1efc9c0574700875fcf52d00d37b9dd744ca841ecf7566977c1b5799dc4105d0b7a92551c5b33a50133fa300a5908b18f4c01936347c6049447abf29":"58882f1a41e08bf6c8dad091a299af0fbbd14515c1550906ff77f6ae":"b1f4dfc9c83455f279a3e7522734d6b120ab8ed36ccba7854e26504c707983d2a9c075045723f441abfc7b36fbb5d4bf0447678f5b709ca5129b74888a0723e905769836b9dac1303f1b9ace26554342b6e6d032ac4b477e011a4ddd3e2978fc0c449c64a66efe7d4e22e5a5fa2b01bb17fcdbec7185dd4115a19d972fb01a06b33bb18b9349ff95fb10dbbf2dcf899b1817d30ad48a99a614d57770ba764a11a84a8db3af3041ec362614f807196ea3b90d05b014054ff4e18524c795e6722c0fa1f6d1205d532d94347633eb132e6cbb596d8b341e65f2b2f955872ebd4d3006c45ac33da11167fa46869c7ee70e9cf147b23368b3aacd9c1880b09ac86a8d":"5ff04e754fe3246f35b3400b87a450192a7bfd9b3c03f3ece93449f4":"07bd3f6718e39839304ef54ac48bda8d9ac8ee051a49bb9131dcc918":"6496b2469bfb5845485004702b0c79941bc3c3007007ba169d8307ce" +Nist_Vector_82 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"71279b848c00208fb4e4d87979cf973b321b20d098dea912a3b4b5789cdd3b7ccd8f3993a9c92c34b70e9b0bd57520db56f2ded3a612a6169d2a1cc6350905ed0202a25c113b7bf8faec4edd2ea3b8f447ca75d15a712b4b4394c22de0c2554b9aa07ec8466727e7ef6f1f04ac4568d7726d9d77f50a2fd551ac29e42f8dda23":"292b1666d0b1fb361da268de725b11310000705964705ee975d4ebae":"7c8d63b9d55f59290b02a0fcea6d98c6c545e2c0d4b109a069694d80cb034dbdbd9edb6b4d9b152849cabd655fc77071644bbf4a0c7ea4edfe864a43c44fded163dd899c21cc2f9c33cbf56e8caf84394b24f8c14e84f22c3b0f747129d9aef41b6f1b1fa8ff5a8f680b496595dbc7b7b63a7790e3628747011b3277b06e80de0b67942f602eada60b518f282cde69cd717a5f6a19c8e169449e0d32a9d8ce8f09a5ada23c12a02dccfcdc0290a8bd46e8b7eb397494f32a0ecb49fa5a8edd41845eb417fbb8cdb89a9f18b9ad1b41dd4122ab349bb3c44951e4f9604360fcb1b795311545a61cfd67c287a7c9d4d3530214988e7616979e2ce907d5c7f3e9ad":"6b1b752bb180d8787c71505be758c0ce41fef428ac10591502c9a04b":"4cf5c26c4c2cd48c05508e52d743ef48685f6324141adef23d79a396":"59f64755a04c90a14b187ae142ec483c4600b6fbbe19f04a49e9ff88" +Nist_Vector_83 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"3ea03e9b005ec1954fee0c73326d8aca1a4f63648eb4cc59265528ee8e969ecefecf2797a0144c8336500e26a1c7cb1a642b1ec65201416e5deb355201de2bda695d1beba8dee62772f4d5914a245be9ffecf39408ae7bf1bff7c2451029c4ba0c522516e89955ad3bd699cce94c744081a9f2d60f5c5127ec722fa57316cede":"087e432b1c29c00508d768fda7c4b279fc088c48439f09980bfa159c":"1239c347be4ce6f1daa721fbbb141ee6e2f7c73098effe8e71beb9f1ab72d1b5bd3e78df770f7fbd4b3a9505702dacf102eeb8a16f11b4f809ca002ae3774ac0407e2572ae3ee1716458e5f45c493f4b921144e858d87d63773d023745512b0cc02b31ebfe5c24ad37efe539cd393cfc2b951fe1b6ffad2a2824c0f54bd776aa0afcf9c1ef427afc6cf4c4b17f66355d68574132e1d88ade3722513e395fc62d65e9485157c82064c90803a1a91f9e6b10af2f80699d917daa6b81415e508193152b4ccded593dde35f645e54b7cba445775eb16c5e19073f0a9eb5369bf2513b92158165b94dea511e938fb6a8798e040a05da94fdb5a4d44bee943b95b39d9":"0a8a45ce2412cb84e4e0174d7ecd2eb5b37ad0a53b474fa9bcf56d9a":"5ca2e971f21b70127a70c655eb87e20b2517976228a2c4e648d549b2":"44036b34667136a5140dd1948ddc2fb2bf679efee21f29b7ad87af7c" +Nist_Vector_84 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"a3f7033958c5b779072b0548baedf4f88d14f11a6dd6eec0181b399943d7246a45d50c4f7b5295dae4cd3ba7c4c181fa201581ad5c4b38793bcf454f176868e9cbe0997aa41987b1aa3d5ddc046be7b022fb5130594c8a9df03cfaa7acef817e3ba5e192c69a120299492baa52a9be83b8e871abe318b4a1f588f9edcddafc17":"5831abf9843eee928944e3dbb759dc7224910e1adab827a04f596e3c":"62de2465edbc1ef8458beaa205f45f9dc0fc3db77bae0f2b13bef6d803db689b8f5c747e3a041c08d326cd7e1891675b022a9da3bbaef8007784c56c86c4176c0ac876351d1062d9c270d548c8f4ec39a4556c66e76e507fc5f2540abfa77c178a9bae153435a7caaa008f36b9cab213ecf5e19a0f7b1e62fb9a9c8223bb689e8547b5ec915b04a85b2f53ccc792dc0a7a41d172e6f59f5b5e7c440350ac6a72ca9c06562d4cf8c60e70870a978312e19bf54c2481c582296b64554bd871accc8b251a7617ca5e5d2aadc19d484d76bc3826841f88fad1491d80679243e1527197d02a406348b247ae786108e5400975a38f3961758adc07ce740d8d442f152f":"36b3d1d36d1a8c41442b6fffd46bcd7977a306b53dcf7fa590538194":"1823f0a807fb9e71ad69b8e9fc674cf76f67c42cadbea6d34cf1f1cc":"667fc57a44b289fc34a198556117afd696dcbd96bf1baacb40d3f8b2" +Nist_Vector_85 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"680d878ca6eeb87e4ae158dddc3732784013ebb1da89401acdd6109089e5601d695f9e4e6ebf16026aa746dee80a01235033f242079af1b7fa6965c87eae8b3291a009e4f19d5b8f1394d866e7c9b72073a95652c0eed98e9484a15c9244764d8cbaabd49d24c207c705703cc35ebfc7683f4a0e6abf23fa07678350a6a00cde":"738a8bfc478e462c4bef8d5633e0793475206551bbddd08507f005f5":"511a3608c4bda7c82d7d68a5d30bd4c71e457b0f323027d601d6324a94893ab3d62878b12d98c44dcf30adab4352b70f4daa772df6aed3c07587e96c68f8a847a335051481d53903d1d1ae0cf99a54387b00169a1c9704bb62f1d98047dba8a0fdda734cd41611584d50554ad77890720c8ac29932097cf2bb1a8d0daf8663241e23640cc396f9e6877348f014073f4fdc5bebd115a0d74c2ce857e100ae3dc0707b95effa4a2cd8629fdd9bce72091c0e2612d2b30320420f42ecb0986ac3289251b4ae54e51ed83d0195deda9d4e5b398b037213d2f8f0ffdbf727214085534a324d4fefc1653642035ebdbe8167b150bd92b7cdf276fcf5e0bffce956a47e":"58d8b64bc8c2da02a294e9db46bfefb273e74870651e19d6cd017c55":"7ceb71480b5a7133401b5227fa2253332e04f78ea5d0fe237c8525d1":"484800e81f7b5692b79eb21ac2fff83c49c9f0d409c756c73fbdd2f0" +Nist_Vector_86 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"697f9efc8653fedb898c77f90f124bea5c3b893c49d7f1b116479e83d35cb6c3940797501e7f52887d18ae9f4055e1bdd124b572f7a6fad101f58b52b30ca30d9743a9016af891896d25356e44f982d406ea26a9b25fc4f903092d7e8e8713774a8be7aaac93a6942c1f2c48e9dea64984ae54f7ef99961bfd9b8d93226af776":"550c8755237857a0c8fc8a63525d4025713b89bdb127d1c330c3324a":"64b588499c9db3e5864192464d32fa3547f648fe676c150a8f9e153c5af57925c76dda4b419d60b22fa5cdea0fb6f0b8479c988a324d275bd42ef10d8998c36039eb4021fc0d2788b59a75cf25ed6ee4d44882b0c5c5cb8dcc1002c0baa4798107e0b57cd26debbcd0ba41d1b1b860b8eb90f6f30500b2e4be7a00b67d93c87d3ff7a6ce53b977a930999807fcbef57d8dc67a8f366124991389328ce7e70f9e5c22ffdedb28498282b4a9a9c68534a238322e0db6088ed0afa8bc77ce998c814471ab56767b35d07b94290ea106ff0c998b51f02222738ef9301f290c6b485dbc4f12b472a1192fd93f2d23527a02d95af0b422be7640a9702ecaac26c9e004":"0b4329f9e5ac4a117689883db2ca8e968d30a3aced61e27ba27c6242":"62054d11529b993a6f19a0d5481b99b4b4461a49866c29534a361a8b":"7a7fd0982e4e2118d1a069787a80b902493465f6620a355c86a94867" +Nist_Vector_87 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"d080a7dff1ef20e33832b99cf83c6c919c07620bf608e080aa301831ca6178e44ef7a4c115e93ab6d877e96652171610a51d927d2034f42f280fe87d7c1747c480ebccbf565a150f3240f6d4ce5d6eb0b2e964416791376ed22b3559cf93a019676e9e0be3c8d34f0e0d1152ec6c326d3dbf1d3303beadd188c3aa0d77e8a117":"2171d5e7cdda9a691dd27f0524f24ca41d5d801eb2ab0dcdbe6014ad":"41767ce26c780e3f2019f5a49a701570148e9ff3382203833d1b18e9d8d6a00c0b2258f2e567db31ad4e8cfb2621794bac87d9b3b53b79199a775058febc190d00adedae0fd3021291bc2d1ff0508bf019eca0c573fd863722f367d5d02bd9fa0d07f75406ac204fd3a5ca16325c661fe854fd00fb26654752febbe439096dd2284d5ab13de9eb004847d1d8599fee687cb2ecd0e5b761d91a7e9c58e6921f103024215e74f3de3cc12f5ed7703def041dd3267f1cde0d4fda8dd5ccc9c07b65de59482c4784b4f6fa85667186e2df6c5dc8b495be8ec61379f20923576f17680c4dab99312d0b6441306ae717c95d3f352ba4c096f01d14a7dc05b28ba9a3ca":"0f6626008e50c19def9bd694c00522cc861eb7069d55892e08ddff58":"44e70d2ead3c51dd0c5461dd4186825e23b4e751d8ab17d0b7edfaac":"48ffade27531db478f22fa0ec92bcfd2ffeb6db67715dcdc79bcb028" +Nist_Vector_88 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"f6a9afe241dd984e3bc265787dcc49491b3bca67feef32fc1e07fdaf0af6c5d06dccb47cdb6907511cb30c109f62e66718c5c4bb43d4b00b51235df43223d60ce1f9be3493a4dcb02e25ed3ddae10d131b481a61aef334b690c7a1ec74865954b39ccfa7a51a9a1e62e654bb89270c774f082adf09b579c8358dacb9db7ca1c2":"77207cf0963f1e961c3539d7d0f678fce517f67b728bf15e0cab3ae6":"b4138fa4e1dc6772b47e5a3ed130a13b822394c3ce8a0193d1dde4c90e7da1178e1126dd296252fa7d2f139a148ac44dc06a058b84ecb03ad827e66892e85529c362ceac2e7104b797b2e9826054de350596ab581765e9a5c9ff5143332c2f3bfd249a87fe1e30efd6fc057e234a1cd4c19e072bd71b32d55ef122ea930911081e26d998490376e3b721cc32fed92b82d545a7e6ba6e4eb434063c87db848df4ef02eda3fdf4f9d2905b78f7b16b5ea0b5998f1fbb0aaf62a1735591600f9801977b1b947f61a91ff2afb8727c55268972c87216aae900617a56f535ed18c4c5ddf8d7a54463256d09144d889c149e5b09bdd9d8509314b103b846f3e6fa1bb2":"57585204d88d73c21f66a150991531973978dfeaedd8024e268f18d5":"555a454880084f6cb2522daf3399fb4a501a943a9b6aacd58e2c7d37":"730fedb3a5911844146098ac5603e2baaae76962b33a327b50420a50" +Nist_Vector_89 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"2d1c573bf324028dc2fe00928f55f7fac79037d4d99eb185f3b997e042cdf808b5382d50a6aa8085c5d1958e67283df66986b93471c12e3045ba146ed5965c8ac5b44668f61984d21736cf1c276754b848e9fa636b6315b2272c19e65626bf8b1214d70989a623b5fff7803d28a663bbbbebb84c839b42720fd0e62246b3b034":"789375055f94b9ade40b0af8f70640336f5de213571ca1c645ca468f":"5ccdca35551cf355ec85db8d68010ded63583255b1d5fd2a522e29513ad3ce6157be30ea1c305d87de6c27fbe3a3fa5007128275d6e6183a65cec5b694bc6c027335066e01273fd6981cc5f60c3e33751386ce792ccb6e6a6db5d7f073800329f9cc46d19f422923b9748dcca4971e43a9d1f59d1c749788a8527ad524df74150b39eafa7f4d5608d1c97255654456eadd4d382ac54fdd12538b2f2ef75a50980171a04d4054b4cd79c71e1c4deb3bc6af4c874f5cf0273896d4fdc5847fefdcc97f5402c7e76484d3d2d70ac16bda41996cadcd83ad92cb37c0c1e9d64fa1abd9a2cf005c2c29a1737cdd6d63aa2fdaa560799b9f07d448760678477629f22f":"325b1562d5c9c61f95e6944fb12a4bb08d227c4dc0c8e9a79e391b08":"7bf3c0c547e21846212bf4cf3e38362dd4d359b7af6420f90da57907":"5ebd5d2d88cae40b37a9a5a84e6218d2453afa146c79a5d5f5df44f4" +Nist_Vector_90 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"bab4db55bf6d3abefd1bb4e0f7bcec65ee6c6d8eb04b7c480df4e9e39150f10c38f1abb63dfe1bb9755c41b38955ba38ba938b6ceedfec02001fa870070c59df1fd2d72a814104c5143376a3136b8118f7b47bd1ffab53359e53f95c66ee12705e31a462a8caae481556ceff607ccc8bf1450772cd68081d3f15a710e656ae56":"6f4a94c9254a557787de9afa08215414db5a0dbc67c66cde1c1e6f04":"53c0b0b0269fcf2948667e28b11ccda9cbb9275463f21ee30da33c4575be5e111a182a6f38b890f20b8f2d224f5981895310db7c4703c1cec2b257f452d964be50c014b752360ee24f2fe1bcc023477a2d7085f58214df866b13a8d8af913146dc0bee078aea1ce645999b579498eae9277ed7e8b2c75f494efaa73a973f32232f08ce7f0afcba316623b94158de39bd4c0d513234ee1a481d5b72f4eea37749b40fff12ab620f11aaa01e3558e7a4c550707b71c16cb8cda98f46bf71769a476c3385a8caf7c886ae47d228b1771a8bd4b7f19e6f53047f62f029c339fe7575be93080ac748289149a57a0ddced54d72f6d4d344fb874ccc85ea7f3dd2164df":"14fe2a5a75756885240ff29abd19d346b2e7e5dfa76d2430f0d069d6":"118d2227be4bd91e98a2efde15609b2b9124b2e83c274b632300432b":"3a447461944b2a59278a8e1118b406bd3ff416775d65530e54f9e623" +Nist_Vector_91 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"e920fc1610718f2b0213d301c0092a51f3c6b0107bbbd8243a9689c044e2d142f202d9d195a5faef4be5acadc9ff6f7d2261e58b517139bcb9489b110423c2e59eb181294ffdae8aad0e624fab974c97f9f5e7dc19d678a9cb3429cf05ec509072856f5adfec6e29bafe8e5ba95593e612843e343111d88a1eaff7dc0a2e277f":"7b489021578e79e7bd3ee7ab456f659f3dc07c88f5c9a39e4f8cee81":"1ae10c786ad0902c5c685dae5c7121418a377b888b5f2f2bc76623570fd62bcb190b471ad5359c5f062f8819289e956d8aa6f90d1f8cf1ee72d3a1bdfd56c478dc29a19c4569b5a60e3a8f34f60656eac5b25dde5514a5c67b675423204f6ccaf0990617cc7355b9d3ed868978a252020a769ed59a6edaa6efe3377eef45f3f6f3e64179cc7db8b143fb835c5d71bfcfa1e2a9049bccf7fe9ab57546220fe3f4b7521c861739d138507e81a46a6993605441dcb90d6ee4afbc42cabe90a254444968109d7edd9694a023239f1d56175dd1fac115915e24fab563f4fc3f269bed2f300832d112596485a711417aa73bb4ac72a651a1fa5baed3636c720d397008":"37fadd419fcbd2b073a06ae96b9eceb63e29aee9ac5fa2bdb31ab85d":"65102e8f64ecb11f06017b1a0c0def3c29897c277c4a948b1f4da6b9":"21ad0abb27bd3c21166cb96aef70c0dbd5f3079cab0dd543d4125bd1" +Nist_Vector_92 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"da5e7b051c1859d22f2a3163335d277951973c172e06697c0490ff15b592c1ebd0fa5efa2463119804a3fea224b96b463e30083e002949a24e922031764bb3daff8101fa088af5457af36654c668f234a00cd828cc740a898c0cd3df09315da9b346b325b2fbec475210b75482affa61a3eff50c83c3a039fae5cfa8d971fddd":"9d8bba124417c126c1c011115906a7bdb7a493661d8a945e32cb283c":"5e276987b847b852cc372e986e8aba0633dd46c461bab58acae056d4d1a9df03a19df114f648b28e038506fd09ad0d95449d9d8058aa1b241b2acd3badbf9882697331de45b452345c051c2cd830f7cdd7486b1166b93891a72a8b7dc6228bad708720ef33235801c4d4c3c4f28036df6029a195d0019124d16fe8f76c525b7e8f04bf4b8d8ba6ef608e623224fa8d988420f40526c25ae3e4c79d5ae7fee69793e02bad9651ea0fefd3eadc5ff1ca2d142930355b1f3aea102221fa17b735a18af3b83327c8f33efb9a49b70211014eba43fa65eeaf25ebf452bc4b7dc1f407d0cf1b834619b5f73c6cab7051c92070aa06f7f9406c507d1a15d12c11bc839a":"1abaec5b4efaa83403fa970ff6027fdb596359df930a02baa12ed854":"313615836f0d338d81b670f116a5414d2ce90ea5ca5308ba4f0c8a7d":"dc1d4c3c06203fd598a476c891dfe5934162d0d35f37f1c09dd6395d" +Nist_Vector_93 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"f49895b3290d9aaeb4af611c5e30afc0047dd42c07216211d54977d1497fa4ee6abe11000d6ac04d24b4c50f31e06ee8a74774d3d304137cc6b114d145250ee7e94a12a1ab592ae307ef5d930cf39170e9756adc5e7ba62a54abb6f047b4500b6121e1f4a95d3c6a96f7f8333cbb1ebeed8b4db1a7fe75f4071cebfbbdfdab90":"b9174a6cb4d3b2e7e4d168078e920ecb651343223575dd37c0677371":"6d622525ecf54dbecaa811939ee07ef2975d9da9f7a3c58bbb893ce3880677404f2c6e5963b8c0b4492601f15bc6fdfd747a00ab8334e9053201e1c9fba55fbfde36ec54237501b87416992771cb5ab8781d0a967b7f14f3d5de6b1665f662885878e50ad37827b95c8f0e21d6bbebc9dfd47b2957d2fcdd1a2b25a616e698129b45998b6b6aa2a99c1ebf4275493e28eef1ae34e9ca63cd8886da58572907aa9b714e89bd3644a7ea029fa3a4ae9c26e665c85296204fdf86b7b1dd7866bc8e9385e9518a270248292594c54a4a03dc1492664ddae53277c6fbb9dd0cdd99bf11eaf6ae31923e4f979a7f581799dc432b1940f613a7a7ea6855237f776e91d4":"1c52eec9523245bd82707f2ebdb05fee6d34749f23023ba72a5a60ef":"79d544cdecfd1ec1b7d1ba6322a5e0eb858aeb4b76d5b3202cea233a":"0ea53dea4ccb25978a0af5529598911b47c25e0ba3b2a0505fd1d7fc" +Nist_Vector_94 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"31d739566914549eb25726bf6d4b6c674f479ba7a406acd108a106f36c7f5214976dcf3adf2c83fd26b37d52c0b5ff51e6b3811a8dcb026a1fbb52f95027ea6034d91149b30ab4928ede26ddd692ddb8ddd929fbff83fc673788faa0ba5d967fd1339299e55be51cea80609d2b3c3433cf713a9686e229336cfa7e720fd5303d":"4cb56c8acb9c107087837ef5e021f77cb015023c8ac1ec73575e5289":"386cbb8f7e728751d4f6a75f890502989b51228d3039dd1af7f2dd0186bf97a9ff763b40323b30ab0dc81bf09ef48db72c0cfbe772b3d314927ed19badee7b88b49ee294923714adae30c955d37b99c1dadc4a29f0f8c2b9d1038d17059c586a212a9748720fdec95b428971df1923f08a01d35893d12ed17e0b142ed8e9ef77d440a01d77905b92c51dace1b345cd19f91623a6964288ddee6e9908197f91da9a26f806bb14e2371742f849cdc6ce7a045a704a792e5760d6644eadb7cffaba806b0545fae3b9fadae4e36bdf3b69c6dbbf0d8b053da38b904e9c4b949325b2a005b249276ac36927b31793f80115b5e2f2107f987710380708e2c322894fa8":"d223b9e9c662ba6651cdbad84f2616fa223fa8742f783c87c2fb9e8e":"c8b8a92e8c101505a1991bcb02fb6e382a3ecbaec8f4374501b657be":"20d161cefd584979224379f28d827aa219c572f9600147f4048ba7cf" +Nist_Vector_95 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"d0a8a1ca0ff2b44b37ff860007334b23be4934ff89051d787ce69d3d7fa734b9779e2f0b38c235391a897fb8514b857b991d10e34a00dc25b0c4382dfb6d53aa87ec1784f1cae2599259406d4756539867679d3088913a138871e2a434747222fcfab079d9e655ba254463cb0c5786b9858dc429ffdadf4c3b6a253f90eeba24":"2286424f368e5e64bac0c977ff0d92a560b78e4f21b49f3aee7cdec6":"7247d4e1253f0b52a1388b794815db61c1a354cb0f73fd19fede615c1c3025840fff204b0c6e610ebef1113df56f67406badeb99445891dcafe18d28f597126064ddf7aaf203b2fb0d35d2f458bb74341ad937211edc394ec1a3f7909a3f972db27aa135d31bbd7e36c2bbc360585e7bb6e83276406b9525f688ee5995e7aa8ef7a72c27e990d64016b99a0ae4d04b2f1b7d238af88ac4c2e4e0f3294cfee9be2457e48955948cf4bb3a445a1d778cedfa4b86f59f156118034b2b834a9aa121e9d482d6922292823be2991b3b5b42c23925da294d5ea37406eaf78b7dc72519d8f261482d6afff0e567bf6e673dd89960ce734f092d98956352429a91845694":"c2795f65f0f077e32c022a703f7eb8e5dc068fa67cb087ef366b243a":"9dabff22a43012dbf47d56b9ae5a09f4d739dd69fe907725afcd84f4":"b60c44728e4b1390f30238fba1dc1003fdd39507ff5d6ba7e609f2ae" +Nist_Vector_96 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"e4ffe72c77c3a43af8a61f58f9240e1a07b5c2894d5bdb654b2b994dc0c987bad9b704075d3d0a969cecfc98b1dc20e76cd8e012285819462226a84dcdd67895f6ea278266f1575ea785a2c359f8f4593bef31a58091b64afb84cdfd23e4aaff29d9626f0c823d934283a4faafc9c6cc18622328cad96f77d79b9ba35a43d825":"86b0e564ef08e089c4c85675b6e5281daa4e82bc2fc0e27668052e4e":"7146009d12b03b2f32305f495fafcc4d452efb85cc80d671ff4249492c6699fb26a89ca4b224d56f6b8e745df9fbc7352ca583222f4deab118f9fec0b34e334060bdc28db872e0090649149499e7a1c197878d3c7262439303b90201d0b7f5be94d0a7c4eb15182935296c3e3fa2d77d74d78f41cadaa40eafd40d017888caa02a474868e40f496b7bc1ce367f503435e0d9a6375aab03c231d9cdaa15de23c48ac0878ef649eb144ce6be4d2de11da202fae82090673c83b32840a32df6176e1d55027d7a1c1c56e642f51aaeccb3c990898061bfa16b3dc1461073c333337fd76a3103f3fde821bc994ebedd6ffd7974d0ca1b54961d7df5b9eebbfa26c3d6":"5aba2fdf6b24bf24151943a4f32d2794e44d1f62e8c968ceb5b073c7":"4a2abc689d2a63e8b23214a3212a5d20a7386882d5e11c5d5daa66bc":"08e0c6547087b58bc94fae247e962da1a2897888d1bc9c8cbf3ad6af" +Nist_Vector_97 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"f8fec19288f3a8bd1d0d573bbbc180106065697481bed912f8752750d331e3a097775a12276bc4293a78a80748b2b2c37d20b800335c1d1b430a71bbdfd8f7afeeec82ceff2fd33f2624e49d37457f262cf5dedef9025ce96e0b7d499fcc7a7ff06c02590ea821dd8ed060cabcf4feec9592aceddfd32b4c09e4d44938435b82":"e5ada29e91ccae11fd060112540eac31d9651b34b2754ee51620624c":"7e50011d422986eae01ae68943dca0c87af44f7b879bd1256d4caffa0eb1925029c0633a7ac67487a7b6f98ad77ee7e1442d129d06db475a4f7804fd8c6a038151911f81397e963594b9c91e3bfe94328f056e9bdbb9b11f54939d7e237aafb0c950e0581cabfe94bc26f0e0d5560997bfb0f6357bbf2cadb0108ec0095646e4caa22f71e1f17a9f34e8a8c4b71cf0b1265e001554fa91f18a17562bc0948c431f25945962ba7faf7dcb64ff0b8bdde701e1df620a11aad07196d67a956ebe498ae6f82324f75cafbe80edaabef0037b79c3ed658d9ba1b5422c4ac053ba69bbaf7fa9db990e8b5e7f9af57a79f3e31c07611f502b3015962b02b6b425706e0a":"cf0544a08823ea2ad5f13716b43b154aa4bf80d6bbcafe6040ad91c3":"2f38c5cf86aa0e53d1fea0e65dd03813640404b8d9a8cd6d264d9285":"47603880f3d67ba1a6eabc20137dc4882e417304cb95d622177df511" +Nist_Vector_98 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"7559465af5ca04c1e74deb9f8e46b0ef17de4d7a2ae0faf4e903a2998bcaa09b7f1730393320ebc57d052d2e98f5486e8e92bd1ee6bb0ffd02d69e5d4591e2fa12e4ebff8b6b9d3270fc75274f8f82e1c60edb2a21f8d5531a2380cbebb24f6457176e54769a136601a9b81da68ff196ff8cc78cf059c04ae22459cec7da89b6":"6ba814fb6c1d9fe5d282008dcc9af2761d1b03eb1fd02e2499c1b509":"5bcd42e586ca180f743395fc39e2bd393820f5b4c49c7cb76921ec38bb53e864fbe809a033775f16c7f5c64872fedde6abc560488e572955edd3f9569092071e56df211564f33185dbff180e7ab2297700c64db6e220701cb8a21ead2ea809f06a16554319b2739de2aca8057a62d4caa7957a2b9f039b3c7d4fb0761a73302a6fbb583100b239d727158b4cdc9765fe0485afb6a1b0ac0db504a947f3d87faa5542c6eef7a681c5fcd28f4636360f5593bff7e433b6a338d77e3d63f6ceff69536e2a3ff77ace745b65a5160d7fbf9105a90f46ce1c54fa353c8aeebe16fb238c8ed998617b63287511208d9db3f66d503374bbda48a552d04b2c304a15bac0":"70af9c79fad2b3a0677fccadd95e6f72eb8a51464e443d1e5c007f98":"c5d33f5a4fe2280a9b96d7a9b5530dc17cd1054bf1e8cf6f4aa3e2ac":"c9bf1c062bd1e86f3bd3c1ff582c33270537fa7769b9592aef12e104" +Nist_Vector_99 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"1674823896c5a764c61fd19b125a7d6cd58c883d86794391477349f03616d75b6925e9dcc553dea37047f0cd153168eb26e5ad4b8fe7cc65e4fa275514c842af63507f901fd110b98249133d3d1266d2f967c85b7f88dd76c7f76b786b5572dcae68cc646e458b8278db346b2e970c7870cffd8457fbec06bbb5141575f40fde":"b5a607136e5dfa76645f4fee9db17bbcd260b1f6023f28474921714b":"5c34135c90f97ebc9bf1ed986eba563e32ce8c25ae7141dfefca8600ad2f3cbe8e45b4a010ae4997820a38b4888187bf207bde438a1ec7befff81a64265a4ce9900b37a38e4fc23613887b638a113ef41665ad2b1f15764cb53607d0eec303ac48c055f5aadabcfbe2c5faa85e029c43e1607a3a29f65802959b686b468e8107c466a7317b5063e038021975b2f017f1f3bad07cd0ebb487964151e4f82bb5277c35a218ec570cb568ad0404a3713ab7fcc1297b1ea9743f85ac5d5a7ec818e5f90a4a58f2c2192bba6dffecbcd39f245cc932953190ee353a0ca99dc61eac4b4f834618140c9a32eca31d718c95ee03b2992c63a683b0628883a5c222fddef0":"02e860266b3b7919a3d74f37f4fa9054f62f37959ee1ce66baea3b15":"b1a946fa42a36d836daab56fe015c9f29c4544a4a47d482ea2d9cc5b":"e2905ee70a5dc099b7e0baec5566b229e9ca8e7e00840966cf56c4d5" +Nist_Vector_100 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"281fd14ae2e702dbd25f77d8ba8af09fdd77b1839648ab9c880bd119d4475378fcd0d12415abb9f26bfb8e26f108b1298859235ed12e7f9e915628e3ca36c5986d18811a5905aef7878c6300a95ea87182016ec595d32e4dfc274adb47c3ed0f6c38ec893b331f7092f19b724b9fe43f0ef8dec14fb7bf8b9041b5390beb4408":"272b54a77c97fdfaaadf12ee05e1279f65e8748ef873c407372aaf80":"48ed8fa89d07deb5f8ee6d38748a4e66002020f79ff22d66fa53ad913d596860d4dbcb7c3a6633cd4224a80e5e95908f87b18acc2e364c14b51de6bdda7ad8961dfda454ef4798d0f7a30ef10eae87de40867764b84bc55d7c0283f9c7cd2be08e1852487512ff43a8d1e68a951197c771f9e6c2ffdf2c00ed2163f86dff5241f9e2ff1cdb05a0b3e647e6fd23ccada83b9c5961e6e2fef3297493ddb0e990295d38405a24448e249627c0a7998cc4072dd29139c5336d9856016642992cd245c758a3031ec2807b171abaeef14c82a3dab201752351de2bffa5085c137656e469581f63f86379d62868ac3e3aa24df9826a833314bd41e0d9a0ae5680e6a4d2":"bc06f559baf16de28e915dd27485338abf2bd0e62cdda5b3f1ad05f5":"5a77639663664e3f0b19fd583bab6e680688cd89d5e012ddcb1e06bc":"d41c784b583cbc525bce87c6caa44062eac847bca8b005c12ab5e554" +Nist_Vector_101 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"503f2042358f7e414296ab2d41f3a1f3f11182eca6c82b2ae6ee833dd737bcb34691793e30110036ae54d403a5ea45cbf3e5515bbf80b1af139853f506792df7ff5235995e080f82b562326adaf321159adeef20388024509f225e8c5235368a7b045d69e472e6b2ad7d470a11f6aa8d4ca6c6cdb0f3ed4e06fb9a95e2cf200c":"c3ff27ecdb6a7de642fb2d2f9d93ccb51dd09b543a77fb2e7a22a29f":"7e514a04bb575ab93e71b3555cdbac634d475c58c1d9b4802e153a858d027804ea748c2907eb9987f78e41c6757ed5cbf102544a714699a02a9ef14768f96dbbdf48f3b2b3792efb973a7f91f260e0dea28034c915d9d5a87a8f986a15f5d6f98d7d6d35bee7e059aedb59fe595ba7da17ce0db895f3411b832a1e221a831f706587841d9323e0c7f4435703127084b20eda9c6a2497280190a2b5273b231b44482c9253501c66ef1122253be4ea3477ff6186af871869af1ba10f6a15d1c432940317d119dd761ca0342ab606d532c471783a4dcd6fac9b8a67a6bae187c7dc64c7611ded7273dc348cd7613a52d02670e877e18d0b60c8bbdd1adb04eff213":"ac8009b8bc2503f5a68d667696c7fbf66ebba6f88ed3db3504c0c9b6":"8486ab31c8278fad0691fdd6cac2f5fd790b2f3fed52b09986766042":"b6967b9eacde5f4883710eba387b3c6fedfc91944ea51f6ffab72531" +Nist_Vector_102 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"650c3c409a885fa6d1ac1ff41e15f9001f6cd6a152c376fd22e2851c9cbaa5350d8a92b7401030809395cf0b1a0cb03a24dc3b4347050e8553da0e61d81dee4402b1cec97d898dc6886601024f6bfbc48d2f2c40bf96de9bc0e078e440c771f74e7115ad22ba994ae2f857c7fb865ea750b18c79e7b048563becef8898ced3dd":"d39e52c39ea46d6ce274670d3e8a22875cb9873daf4c2ed83bd3be37":"55186de39e6a0131adb7d84170a8d36ac4bf313616e750220de356fbb1899dbaaa650d8de9a7afabf3c4dd6a3c8bac241922acbcc4bb7fa4ce5fcdb5f231cb17a8c0978c8e69fb82d44683ebb9fb17898e0ba4939196ed9980ebecabbaad7b5b34cd9ec0ea6df96243823b1d170efccb4d59bcba24ce5faad32d591ad6ece0440d2b62a212059e000fb5005abfec127c1e9fa7d3469c72b89a96976eb4702f09f9c0a0971b30dfc339072b5e3a6ce40bfea2d52f2c930a11dd655dd36ac9fad86fc3986b4871e7c90459a2eaa3b3d22dd04cb824173ccc087d429bb2a188e05d8af0ac2911c907fd957b2bb330a6f3987a595930b312053c4bdf856de7293858":"78683cfccca3e13d49999e7bacccb43fa33e11547014baf66b987b83":"a0c49d3c47240d30d26f0c20e4508b360a841285de3fc1986f1ef9f6":"97caa2b76d15b1f9f177e209004a2b1fdd23a3945034584c2c15bfa2" +Nist_Vector_103 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"64129153eb9ccc74cc3aae1d5999c6e90d986be6fa40c6c4bc00b1c3f8072d10a9d8e6c314d82a7641f8a3ae29d3e7dd1942dbf0dc52b4b4b35bb67a994942aff029ca6fa18709915ff720ab8f65f231155cb1d0dbcba04fc5193afc71a5eddb4a03867e5c4bb92d37b7ef771da954ec6754d5fbe2e372b92df6a3ea8c3a4aff":"a7d5664e781c28f4859f5c126cbe8d87f9b2aa0027149f8b0a921d46":"23f538d4ec345faa906eff12f6c5942ac166914baf8e737dafc71e47285512ebc57ebf3ec666342abc059b0ebddb021ceaff6ef75828c7be3766257f7247a67e1408239fa4dd1caac2b7229e8c1bcfd57aeea4c04e1586764e28669c3612d8a006582cf8f82910482691c10e4113216fc24feb299f84ba58700a3bb6fdefa17a7fac9aa9bb410fe411fb294d6294396f7f627dca0452ef595dc24170c147d3863fc16e23645019aca63fcc1152b0f766f5f651c9bb699e2f5047fa1e9603972d2c7551b18f3b16c106ddd6cc2e24d2d05e79687efe655102e6bc15bc3a57f60c1a6ad20bf1cbe62052ad0947437b92b2c932af5d72775d43183bbc6f359a4df6":"85adc235c0060b510825ed2b436bdf003f4d63e299e973b5ddc81fc8":"3d728962aec35822fff99e1b5217d8a6264a7c608d8066f4fcc9008a":"ca5c8e178a14ba006e93cf4ad119f045bbf82b828767d3e583d0bd15" +Nist_Vector_104 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"9fd2791c41a2ffa6df26109804eaf070122e20bbb62ecd9811551136aa956dc1c321327893a0dde6dd1d5b3a0d2a5aa97ed754e5bc066753338dddfc68eba217d2483505b0d7c0a437732f8046cf3bf5930a11efd3f6599c0f8d465fca7676ce1f39102cc0cdf13281b2c7b9cf7a7afcde681005e5a2e4e38cf82e421357a41f":"ddffa0c5aafa1acf98290ce6aa7a48db2ddfec48d6ea881745f2373a":"147aa8d9e4ccac906d6a5a0b65bfeb59d4d66037ad40d288d7534fc9ae33c5aa701ca18e60f0b68908280562110af7d1d1bfb538c59d9100980384ae93b77be0332a03cc567d4d634f7648a1b9fd25daf250b2869683e9426d75561a5e1787c2bab71132757dffc4b7665143e7d87d50f12d01075bef5f4b0f14cb3f109d1599e5bf94de0111a01af57e8c13f583be4dc90089619c72d22a495c45256ec787a5832d2e4c4a42f0001837a975ac8fbb8c565f77b253303b1a873306fa5cf6a5dab62d7b1ba3d70dc11b4e4f875e3edae50ee8e5178dd09a334cf9260c3e0a10911d381d7f5601c0b3f26946682018629922946dd73f81240816ae9606911cbfd6":"3ee8b1f03687b9726de846f54618ac45f8e2d6e8957ce6996bf50c2d":"a7cc7486f47fe62fe3254ed655e1c994902d797f0d7ca93fb97df9c1":"914bf7d15ce2c9ecc5ae150d6308fc557d94e1ef18c0860aa68ad48e" +Nist_Vector_105 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"6b78b4de5f7526dbed08ee0ff4e43335b60cd3bc371b70cd4fd9ce45bf06508391085d142cc3891b179167c76a1350ca8ef8ce754ab1d624572e437195660f004cb7bed2ff3b0f7c7e53f853305a3821dfbaec33e220df3c3ef7a79f34e82cc8fff8415f108c000f21c3bb21a4c33267a213cb4a558e3b370d17c639247bffeb":"9da093f73c714e0b9994078b6cc748a675cf4f3bbc502a23895097b3":"9147670f64aedfa246938ba77fb9c1ac271ca1091d863f32f00d5ccdebe7022d268ba9051d80fe55dfc5f64b0716c4bb8da4b11e9e283448ed8be4278e93b52d675649abb45956522f92634c92a09ac5a5d603aae2a6d04a435239538de303fc05b9ed5fcb843f0536a8ab942d9c3bdc90feed97449ce309be8ab119676a96c2a60a06692e8cd59e55e6ff8d91fa462966555526c987fc44ba420bbff768f7a7fd363638d5ce4d9ea1edd7fd399d6c65627bbc337f131c7345b3d79b4db7412562547ca2a7c8ea55ebdddd05a4b4200c72ab2b83311152b71c99306c1d3b3d446657be65e58d7cf8a062b225ce937802590546853f192a6a8c8b3ff7a62fcf80":"bdd792b1ece3d0ce428cc1294b9d7497208de86929a2aad2ef481557":"2f85ee5c32d546c68f0aa2698beae53e2848c375517a570e0f1b5546":"547667e8b13f21635a0b106d324d06c85b74a64ce9225cc5e0843581" +Nist_Vector_106 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"cec8d2843dee7cb5f9119b75562585e05c5ce2f4e6457e9bcc3c1c781ccd2c0442b6282aea610f7161dcede176e774861f7d2691be6c894ac3ebf80c0fab21e52a3e63ae0b35025762ccd6c9e1fecc7f9fe00aa55c0c3ae33ae88f66187f9598eba9f863171f3f56484625bf39d883427349b8671d9bb7d396180694e5b546ae":"551595eccbb003b0bf8ddda184a59da51e459a0d28205e5592ca4cb1":"748a40237211a2d9852596e7a891f43d4eb0ee48826c9cfb336bbb68dbe5a5e16b2e1271d4d13de03644bb85ef6be523a4d4d88415bcd596ba8e0a3c4f6439e981ed013d7d9c70336febf7d420cfed02c267457bb3f3e7c82145d2af54830b942ec74a5d503e4226cd25dd75decd3f50f0a858155d7be799410836ddc559ce99e1ae513808fdaeac34843dd7258f16f67f19205f6f139251a4186da8496d5e90d3fecf8ed10be6c25ff5eb33d960c9a8f4c581c8c724ca43b761e9fdb5af66bffb9d2ebb11a6b504a1fbe4f834ecb6ac254cab513e943b9a953a7084b3305c661bfad434f6a835503c9ade7f4a57f5c965ec301ecde938ee31b4deb038af97b3":"6f326546aa174b3d319ef7331ec8dfd363dd78ae583a920165ff7e54":"9c5fa46879ddaf5c14f07dfb5320715f67a6fec179e3ad53342fb6d1":"c3e17e7b3c4d0ac8d49f4dd0f04c16a094f42da0afcc6c90f5f1bbc8" +Nist_Vector_107 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"f3bb27bf9d412f13229a56d2d1533eae63f40004c143c6b92f6e606d263dd2da7581e5eb20b6cd021e3ab63b498abafce01b4ad7ac8628f7a1849c4e454f1168ae97adfab1fadbd313fca7381726f5045752dabaad6ea3250d303a5496bba2fa4895ae49f06a9aa6451ae70cf33b5f06fa17cac0144f28bd19fb2ac041a578ed":"027d0171598e7ecf23f2922d0257e604291cefa77b5cfaf1b3e31ac4":"00c7aabe30fa4c3d1ba85e7ae0aae79360e5eab3041bcaaa5d321c92f3471e4194c10484cff152bade6b7d619cf286773475298f883efdf64c08b692583de31be0a4e2b8e8d508ec145c65a369ce6195446c52d02372eba562f9a9d7cb24d2ec3b0a1ab833e4d7623b0455a41eec759d07a3c8a20d88a926408c20f1675601be53cffd65617b66fd4eb353a1f2db31f66343b07faf60de0b6a680809c6166adbf5e504c5c61babb84be72c02d3ebeee066d9eab0d0ecdfe01b8ccd6728ee9123b9d21154b2bc9a134363566402291ac8a484ee32eb884046d40fde7cabbf51d1d1206df1c5ecf290ab7ea72abb5bd3be8d91c02bb63f809718ba1d380af88331":"7494772f199ab7a7e9a248f6c2df918c9da62dc2d4176b7db9419b37":"79a6aed73ce177ed3581f5d181a77f000d6358514ea95cb0388a6add":"2b8597a694564e267b6f250a4c76361f8cdf49863a7902afa48fd6d8" +Nist_Vector_108 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"e714c01631704e9447390f5c315c9615a7a52863b143706583f661595c505aec477eeb5ad6d640ca812ce11750b67bc8bede2e4f9618dbe7376cab6231b21248ec914ae182df8753362d2118a65e66f64018810804ad97fcc1a87b8c9f349d1001e4b09b046991e6abe6338fbef7be48f1c80c350d2962eb6b8fce25b69f8dc9":"6911c21a3da88d54ff9ab58ae2075a2affa3f3eb656978ea26bfa702":"04d301f001821b03c91394c520839ab6aaa95325c108a02dad9db48b3c8033d6443bcbf05045230ca88aaf98a8c4cb6b095b352d91b4c416f632fab49d45ac90699a5a419630a81d473bc89122eb5bacb91c40caa4e4bcc476f3ca77bf6a21037a06be24f11c645b0c21b857fdc5c04fbbf0a26efc569cdbb0ea989ba0e037c23f22b0c5f1643d77d98f2de248ccc36672d397d30c1c5e1319fc7e5842ae1a9fcd9e96fe890a74ddee91a39ce732e4c0eaf7094b53b7b409303860b0b4944cc81b4a42d40538cfe512b9680e0a281b1fbbf639139e8066ad638cf846c9ea51fb4c4ef84921f16a6ca3f2bd158157c551739c9d023e270b3de7c2f1d7683cf809":"bfb79665f7d6df843d2c39357173e415724c83e1a10932efb9e22676":"790b4dcae31fe45cd3a7bb6fa10dcf9ede1f067123f93baad7edb489":"71e3e46dfe040496ce4c5e490f6944a23cd5e66ce9b4d9acbe4130ce" +Nist_Vector_109 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"3f6e482fd484ed3d07f1d0761f2d60fc96d46eb0ecd10a59dd4f392e3d3b2cbe184010e132685578b1f6303239798a5303a81169d4f52fba0d20a42834de293e3a7b32848b65dd308eef5350d633297465425b7b1595ffc8ea7b125896f89e2844561635f52ec62fab2ecfea288d23f0a771cd6311806103135172cf9fef1455":"20328083aa86511140324fd0357067a1d6abfc316e77fe3d260f0ef2":"9fc1b292ebe15531579f35dda8d706bee0da857cd696a10af770dc356232736cf893f7411a9d2718b39f388118d177cd8d0fd7ca3b3c220f3aa743d8b167219d3c2c783e1f09d8b8df8ec7e17578c5329488c87a89678d2818a99366b785d53f6ca6995e193ba5ca26c00b849f9027ca5df5bb7ec87fe78735ae880f1a97dabc3ca7985d8cbc81be824c1ffb953f1096bf926226fb5e9d4ad43e9363da5e6b738c9a2f951ab3294e2b2822cf5282bb4134158aa90ab9c8f0f64d05a0d625a75bc2d6a4ae3dd11fc05ede7b6647ae7c0750ddb273fe5f8828318a91db3172ad59166aacf2da4f3704d169ebc860d9e1c6464abc2b653013774d29375b77bac1ec":"8f4398bb9fe1b393c1d90a62e178899261fa0501c98bd9a8178b364c":"3b5d8034c4b8ad9701bf29b10006db69d017fde8638079dd7bbface7":"cde01df54a66cef3c0538648525b250cb1f08707f5ff114bdebff8f7" +Nist_Vector_110 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"31a278f881fdd375565c0f28ff7575f216110486d6fe08dae8fd072950978bdff601ded1ef226b5d904c47f7142a8f4665e03efe5870da2dd1ab80e449f5c757b3b6996a9dc0b5b2750b97bbad2f553fbaff2aedecfc9ff6a970d156e4fe3852979dc913bdb296a321f766367239de45e47cbef4d79bfa3d576887c65f7f8a60":"b75ee80c896b42148eeb7d185d45f5872a3758e983b4fdd8c2e71ca0":"7ec0a5418828159e3ec829f793b96ea3460328dea21ba157d71ac306f9bcde617db67368d592bf46d46918b130fc7e3d1189eeb7996d5f660ace30be509a26b218d865d9e56ba7f61942e567d8cdab96a78ca303c6b01d989b1e78ae956423e35b5a466c16074e0bc9e8372340d2c12516c22d5e1ff65abd5d448215b6baf565de18201c1fd5ba3de87e5d5b437d2f48deee72a12e655f8c7fa313d24bd0c8c20e59c90edfbf5dfc057c6b679850ae41826178f2f304ca3b92a9bac31ab3cf74dfb8ee5b643b4a341ebbdb5dbd24d0b782c5b450596abfc3df9ee05f45d0ea2e8ff4357cd3605f3506ce58a5394f1f2444c26359299af153532bc90daaf954ae":"ba98b478a9e12a1d03b6aca65c0acb265764357cca67d04d782fded9":"2b47e257bf72adf34d618d3a6c46142881bdd0689a46f1cb3199ee6c":"cc1ff2fa3755a0e81edfc753bcf14e637413eaee0f22d7886b058dcc" +Nist_Vector_111 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"a6d76047bd18deefe70dc0a4bd082a10fa521dffda782a9364b9e2b11e147e1a36a11c4300672144d9b974132b4975f27ea6e8e46b55aedd6723e53e7bc9b40dce2449285a690885c3223b636cb5c4873c5ddaebb0b6dc5b69438d881a525905a51bdb97b051dbfec6dd4a7b580297b08f2ba60f2ead3a07531cf299977413af":"1c0e4c78a4ad4f5046f929e7cd3db3f48b86e5eab4a5e2be61a08dfe":"8b2662775bb7f19252204594a84b469f3dc8d66eb7993bed122d8a065f59ea81d4c484cee5bd766a5c137dd57e43e941339852150509acbde6f7957a1b04ece718565ce8b637ea031bfa3410a580744b3d4959a5e75e315dd33c02b52c7c56218b7cdfdc24f51ddb4e7849faf289cf806c4d3c6b877c63dbfab569920a2b219c39215c5e3e638a3ebeebfb52c8b38e8285a85d625fc1b42fbf0e518c58eb8f45fa54676ed8b009415d2696ee9b5153dddc5eebef49cc7659810a98d4b5e8b9695fb2d9e4bf192093747c878a9565b47cba053c48ba7c0b9b1ce77f8a3e1043e87fcc6132cbe8fad7c738e9bf79bccb414ef24907675ba7cb059a8389eee7ebbe":"5135933094326e3953250a29d5f5c4c9a1033ccb844ab35a14c19d31":"b8674d1ba6f13398f5e8944b82150d9e9bc9b210a81495b335947e64":"75fcfe96926186efa12c007c0985205147cf65abd108363d8b891190" +Nist_Vector_112 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"f0d5b33327695536e351b37cd3feea693f10377a5f8bdd913402c2ed67a0fc1e7bcaab002fa779935950c76e42a491a68fa6fe445cd35575cfce5f376c29c4e8c0fed5a5487ef418b96fa5752a033ad07959653d1b8af6702dcce40efef21b2d64cf06bd8b03dadb2fdaaa73fb2d3d75b0985e9aefa1f94442a5491ae46d7c51":"269055de62d0742324803624522e678234c3600ae7bc3996c8d17bc9":"a448b0d448249a0e54a94586882985a08e19972281d10d9e7fb57f95dfeebf971f6d9dfe88dbd0a4950f528200be7b605865eefd8ec274ac53e4ed5b288c6a00721e028881b9725fb0a9ce4153dcc1fe7b5ce7259f16ea8b32456cb03bae81be77f3f6e8b39f52587bc9dd47a264278d5d8ecbe1ba574269696a7bb1e167a3ae7110ec057f4291a1bae8257d69c10ae095f3271621c6d6b5607925c3498189d751b7c9bf30e65683cb39fb51bd592f1f98279f2e7b2b53ad546816a8508c93f03496de7c47165f5cf297687ad7d60f010ab9faad0153432ec1ccdf26d4f441df625394e2104208bb675e7f972b6c66ed7028a1e3f45a671ab2716c60feabcc22":"0d9d0b3e1f24cbb18320f9ce896cfca2a5a6bb28ceec83e1ff3218d3":"01a4f4bc633ebf842a28d045184d250529920df280545cba00501cad":"09fceb2df200b7c0a56ae7969f5473b7a1f6b703f743f954a4fbdbe3" +Nist_Vector_113 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"f58e039d666ef064cccc7ed015017c68393d1455300d0c4fd4f0d302c43a0022363a7cb01bf0673d325293bd50b27f8187d88ee2b553b159a97d15ac543421446c2aec39566315211b9b4108cacf9085dacdb4de94bce84097c0892b1cc65f2e10d74e5293a04a837b616d4181f3fe4caa4cc2e744916e770ff0ab1368c86cfc":"3752b20033843d1ea4f48018bede79f39c15de33df64140259aebb82":"4052534a7726cbe17e34555648e5f297b963f22d3aca249785ad932f6ea1fb5df31d379b68522f8eebedfc9b5c5277e91574fa79ecf03780cc44351f3e3bfa1a0587c88d0e04e0a02cd1ee9ae210b3c9aacc65c71cf1b86463367e2be25ccadd9d5a4d1fcbd58772f7a117f3673c76ee2a8d93446ffd7cda7f8430490502c16b1a5022e12a3a95a7a9f20e98d3b285abe30e8de42a11c517c14ef3b6e5b6c47114a961d858c6875561c7d5d21b7c93f373cb330800728ea188b2578a6df34772a7acddb829c09b3acf9bc5b06140b9b035267a40e86c1af5577b3d02a89b20a46573c87500a2ebed4b00b1fb13a86f143e356702d791379a90dfcc26b80719ad":"1220ac99b9124f1dc2212ade5691fd330d6d868f3e90694236d44b70":"31fde5f22ebb426f256b175057a76125c40136974ad58e681ec2c4a9":"77b0614dd99acbbf4c43aa926b3f0be1cd52d52775f22a408c4e0304" +Nist_Vector_114 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"1477aa0b9f1b199b6aa0931d4d3f766d80a3af10c9ff7315391f15edc4e92632f9d4d21a8033215d5e99cff170d9888f020b0db0e5b97e123a2889898c5b0ef7c832d028afd5e385004531ff9989797c3bd954b1ac729066577667567884cd4bc5d055a3f645583d29cf4758507c883c5bbfa74444b9c5b9b495072c3261b6ec":"83770784916227ab2a73edaac5a95f7538fd94f89650841d79a37d7a":"4675f19b0095faf8ec96888e483f3a0aa675f5b425910765069ab57c97a12b7c506437c8757fef54ecc6d310921d7159ff39f2f1cd9535b64f27f136913715775a238fbe01237e181adebe551ffe5d21e3c35774e7ade8c79df741c52dabd8be4782ee5a3b607a39d1b455dc848301847312980566f55eba080621e3c123142a1a2074e2e39f6c0630b36831f074869d46a68429f62573cd2c671726131fbfd566a6d07193db4f367802d7de8f4e830aa878ee2cdfb86d8537746b71c70fbcb6a1fad66213d6fbea68241eb9f617478adcc9faaab26cf81b912089da0c4b187b496a17d886cef571e393d6f1f857ebf517c801f9231e95db661e8cb2095456a3":"6406035023c5e150e8758baeb00a9b858ebd0e4090334c69e2fd2377":"a2380b5ece76672669e26187a17da45ad89de1726c826e57378af707":"9cc26c3456c0a409f4cc98c83ea5176eb293ec7157e51370726429ce" +Nist_Vector_115 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"fc82372566ef2c626b2145549a5db973118dff4c6d1d7c4a2e16ecc31b43c14ad3683173535b0b82331f15a183e6a50200fd1e88ff903ecfc50bdd4f5875e264a4499eadbdaf807f974f8d8104477a0e4d30463dfc61cdac5bf44eab96c770a7db912eee2db248cdd2b9b36211f93870beae6bdf8e0aed0097519ecde3470cdd":"8d2855e4ea3e5085a5c145e324e5d5a5f8f23756284669279728ec9c":"3884ab23ab93d9d1b716712c8daa080b26af01657f0dab715ebe6bd766deca7612bea6a4cf1ff7d08abb2d4442ac0eaab01e68570bdcc222f84bc3dd6d8c5490132d1c36e23913f00d11c803b703a69a51a1b475f56db00fca47d234aac307b9e798e9fd891dff9c1257bee556314b021fbf93f75ed8c43433afa715b82d5ec6af8ef9471e9b02f9554ed7957c1f46d8db35a5921f4a83727f754e82b6ffa6d1b82595220876d22e18fbafa5333b26c2cfd47d894aaa7164a2630294d0a385fc8a8cf57d10ed0fc53f21f1fd6b4c27e9c69e65a288444619a3c248bcc44ec25605028325243274d72100edf560cd382babee1ca532b7f06a4388f181dbbb5db5":"5cc12f090fd965c719efa2ee907a43b3643ca8f9ef7c537adcb09189":"5461b20704453b6c51837f7b9ef5836131b501f2539145ca3481e6af":"b65f69d291ffae2d16e3108d69aeb01b4f9202afa01382e53dea4d54" +Nist_Vector_116 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"e66aad54048bececa5682644d5274c18068363e968e37e6c11c1f8a0d7e320578514e1874e9d4eaf1bd02da6b722ed22acfca48c3acb670a6f9ee62e3aa71deb18097508f431b05214c199c166fa42cd6a0797bc7b4d1a2f330cb62c2c95182fef0d06862542845e430d778c82076387adad4355c258e6c543cd656fe3cd2332":"2c984e8464cf5716053520b6a72c69798b9eec1e115b0a1e30e2e44e":"06245bc509b4955440b0e401710ddb2c4ea2e559598361a3666c4ab12e766b439f21b953962f6ef5a11dbee5677ab7f8906d8b325180ef4e45d05c1294fce5dcaf6360f71b10b70556f306993d295b695ffe5729c5c5bbb6cb4834ad037bd8364a12c992c2598e8ee6beb1606ebc0ac0ff00c0ea2eb8aed75dca01a890085a400ebf993e5879382ff91abf1be2ceedd1fc4a874342b77b6c55ffe7f676a1c95ee4ecc32358a080c92361cfcd2e3426f78c217ae29556709ed029b287e71feae0608cf3938857040d7f06b0f91b3b4da8929df4b5698e734a37316879c308a81c096b723bf2089910d5ab30b8eff38858aff6ecf764e268ed698b70e8fb7f3c66":"b20370d79e097e7c65e956d76aea1e288b668dacb8e7944aba5fbadd":"86d5bac3aeee9b501f91f2fa71b1066760df2e0ee147383f145bb0d3":"8d6a207802d6fd6e534e1b8a1edb997b7cc9a25a97a9e4b6eebd0e23" +Nist_Vector_117 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"c85747cdd2ac9da0999b7e5d7f64d11dce7673df5bc605051316b4b94bc7fc776fb1d3da5a4395a674aa8a0798a341b31b11e63cdfac5f854346f6a4b74b49f2d089cbb86fae54ebfd95eb9f05a1b5e84306e930461ad7f827cfb910014a3af4dae0d46ece912bc26870a433f70f0a38bf23b15d98cc658848f4bad9c84e89f0":"4076f4abf4d3c9a55b3f063535f6a69c221199581e72c5a8c31f1a71":"2972787dcbd67e5bddaaf1bd3f05ebd66949601dda44237ec9361591ce9b809f8722fb399e6b9b8109a79ea7b83fe98359a07a27e232cdea8f6533e34e37db3ae53309f62f108b2ee7b489a933e4ef58dd4db8c0108a3670c675b98b75798ac0884cf5a461af281f6dd8e7ea3d41396f049601a9af2e39088ae0a1ec0d2d10fae1dc1de962d84d8cf04215fc6d6262ac432541af2c48c09cd4e15bd9460e9a7bae17e0035af0b13d8de707870c54bc851112f4ae1d69074712c212bc7e13f199ffc8f37723cd6dcf539f8df8cf0cf1ed4c10eeaf0f444804f1eb9d9c329d6f19973eec273222fa04b5f1f0e17971ce399869582027b1c454dc1addd484902cb0":"7149f49e3d07c45c97db09632740560e5b0e843240255da43ae97ec1":"28e3dd71098ff04d1ca885c2774f78ecb3ecea708fab2e16bd5cece1":"ac8b6ee498ee383e28404ba4b53e64aca0fcd26790713264fe3cf6a1" +Nist_Vector_118 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"a7a59da62a9391cfe628697548b05f8af39ea9821d76c314478e210fbcd27fbf6b0bf460a65dbcbadcddfc0178ece135264a7d7c5b7053208bfbde54e3338d901927e95e1dc8eeb73d299e6fa6584555cfeafd1925e95e0b3558ddec641175fc7293c0310266ace18bbb16f9084fd4ac22ad2dc8528c3f3f332684039e74b390":"22fdd44afd372e15842413c0829c9a894ce61a3f0b135c1546f57fb0":"0aa040bbb23c337d58874d95efe9277080862ea0888d9209ecc2f5d7e0d56b3e8444ca933800450f10b8124ff8812f87e1becf1a317ace0c3a1376d624938cab617bb546d0aad4f1d0aa23c6670cfae0da28660393a90911b3dbe3847eab4ebb7dd0504aeb0269126655d135d2e9149cd8ac5221151640914d480569b383e98364cc41cec56ea157ce8d7e73a949b348e5ffd3ceefea7f7625f599aa9afe2db4cf3b0d59f2700f6cecc54f8bf7853892f07337dbe76be781994ef4e14df2f0cf7cb342ee1c8b188a7dcc317a097c9f9e33ff89462c26465bb53eec05d1085fc6156cad0f7c9b80d2a68953501a97acb746ac3a2b9bdcf18dfceaa196716ec773":"b93120b594e8994f533c1811d61495f2ebf32fde9e7ecec856033f20":"84934f3f56d64815fc66b0dbf3b1fa56d1387be7611a1e571c405100":"431f11346950e77c9e9ed0127c50bf620f6f69a699cd017c7d87368a" +Nist_Vector_119 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"d4c5b439a1ccf5d98cf0b931f253f733037921d4efb02cf87b2509e732a56ccb49e0c83b1409cc009f1d2d1cb4c0c7ab00c402ee018ec5098031ac9e7197d4395d491721708a41ff5cda5a03be6a1169bf459470b1aaf53c8a9668acae1385b921f5a26c73365444515c3c126c6940b4bf57591a0bfd6c2c74c724426cb2ad3f":"c9ed82462158cc9c99231fd48a81e4f8318a88735c35b9f2c08ad280":"37c5f029816322da5161c4e20dc4f5abde9f04f5f9dff5d581b253109191b38424dde75febac32d6ce31b116063494a70c5c1d9d8b7351252ed377ea38fbe85b9f614eca1346bff65345d57e646bfb032e9befa9e6e5a89c16d715420e24129b6f70e4f681bc1d38ad1737db79655d244b4d67ad3d2bd80fd9d80c2e15240214859fdc0b6c43dd1e805dcdd2a5b9781397bd4a4e8bc4d6f9a1664036e90cac550e83d6641367613707d0de4f2dee55e9a5be6d3de893d61561f4ba90d387b7ab48801086016c842f3e0ce60e6b46aa980191cba147407aa4ccbe19b00b0ac71648d5296d13e48c75d52848bbd39f1ded988c3616faaf64f91a30742506316893":"9f1fc151bcf8fe18bde1ac505737dc6868c34be605bf2ead6ae3294b":"1b51b8d2d3eeb3d6218da3494714d0e88cd7366f387e6ede00f653e0":"844203a81fb38f57505bf83bc8c1da002a39e81abbdd2f99ab6a4d65" +Nist_Vector_120 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"40d4d9736b54993c1bcee7071c682390d34d47c35f177939ca5b70f457b3458fd5eca4cb03f0efe1aec10bf794b841216056a155dab58a3dbfc19ddf05d45861bae6eea2bd7ffb87a6fd0fd2394e847dc36c94c81561dee120779bbecbc32206327febaa17c96505ecb97d560c934c386f6f766a2f5154f545f22181c19fc698":"5a050bfae63d347d64379ad01441b0ef9ab06ec5842c952f7a1c29ce":"24aa1c7c6a041f6d2c533006cebcc2ad048b3dc08fa86282f5879a237231d230cd854aa10158cebb45f387923fada8c5f4b91a7bc2dc3e2c39463797e6eb1958abc9b9e748bbfe80e360233e96952279959a6b80619100f6f1876fadeb790491462f5917da36cea3793c44db90908cb9da18f696ced90f2acb826355104c4c8f06c737d48acf985d6b8c2abf31807282b6e651d2967a16907be3d8e4b7f32ed34eba8c262d6c0ecb131946d2546362c217ae195d05656a4fcfac73717ae85a571d811cbc99e0b3124bba767fead605266d99021cdd8cb4c081bef102431007ee12523b48bb838698a5971e517252d6d93e1c7fe9fbe07bf434164baaa1026da4":"5de3d5e6b78c888ba4185c1547272fe562b44e507c871a0524765aea":"325aa7b173cac96d5865aa50ea54e5df45a10e72fd5dd1fb265aae09":"0a7203f6b8fbf668b8f6435e929fd52f52e23ad4b8a156ae5f3c9c47" +Nist_Vector_121 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"df5d564db83592c1128be5d29b7036880d55e834a291a745ed8dcd438c4da6b1b9f39412b2c5110730db83c1ccdfe9059dd96ec7ea2bbcb34e3eba72ef0a1d4721c7c0221e29279f014d63facc5bc8f18c539b92ff2af89e568225d6b4cf599cb3dff5e3c6ddfac0a27f10f636ec220abb72630bae9a39c18fd3663e4651ccac":"4efa5136eb6aa74e92bbfc913b0bfebb613db7a47221fb7b64f42e6f":"647979b7960ce7b971ff0e5f6435f42a41b18c9de09a301114a013a7cd01183f176f88838379dcb4efb67daea79def3f042cbcf9cc503b4c2151a2364f7c9437b19643e67e24a36bac4a4cfa293deedf8ec6b154a32aa72985f7d8de235334b546c29def458c55d0c5c0ac5d74e2024ec7d4abc2fda516a2a0b1a4d886ad92c204707828a4fc7794f60ee8a4be1101c9e5518f7e19eebd475f2de6f6ba89c28bd129f13993befe5818440319a79549833196342a31dbaf7d79497dec65ee7dbef70e58f99d0595f6a711409ade3151d45563d53c1cd0a8ab1a18beff6502cbb0c069b114ea7be77898d0f4e549991ba0b368971b1072ece4afc380e9ae329a50":"7e0f1ce21d185ae65c0a00395567ea9cf217462b58b9c89c4e5ff9cf":"5ab43ede66a15688146d1f4cd7164702c0c4457bd4fddebac0482953":"6c58e8ab27d28512c46063c96bf5bceb8fbad232d8f5b39c4755d0b1" +Nist_Vector_122 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"ebeb9e2b692ec6c9afad2a0c2b908939943fdf4bb7438e3bd9288e7681984087ffdcf86502079c291236d7f1adb504e67e0f88bee61b61717014cf06b5fad5cb36f1b223b63912cdcd2b9416524d37f5d7b05c37d1789669e141aff6670db2e0de31673b2055f6799ac887937e5664a659ea0254a8d4ba6f204df2a38c2a77e4":"1c84c5c065ff165a0e1d276c2ea9fdbf8423c12aa1c73844d6c64942":"31d31a5bb82874bdc76cabae3ec85690aa5103cacbe5234e0d5ef645eef380d3ae2f6239144b82b101a7ef4744aadb8fc98e82b41372e99d6c905ca974b81c9fa521f920a1dffab4e2ee15f61e03b742f42470dc2fa9ab257f1136f9fe4b5aa2ece5207230c4906d67a156a3ffef470cbf3a65e3189b389ddc66c6040a7995c68ae1df2085941b5b1df7d957fbcf366824e0291df88eae55d8d3040d8d09f4f6ffee34ccbd1961852a5a62b26c8daaaa56a8ff7fa863b63c6d604fd3378262e815f55171dca35d04761fe3d9eddc6d32657a96d643d4608ef2143b19f1c9d8c00ed265471b245b60f31f8c7ed48dd6b18b5bec1a6ede145dea40283230724ec8":"6f399d636570476f7a2013efdc74a1bb75f5b35ce835079c4e19cc4d":"82c3747a0658df006a7a205a6ae2aedd5d2948488559fc3cfd643a64":"8636796df622d13f070fbed4184c8138358c21db30c606b8f9be521a" +Nist_Vector_123 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"dbd2516b03fdc58b32c0233080ffeea41c0d9c156b30332ec42be5e10584be3e3db85ffd5b5bae16fc876a0c9217627d84011223fab57d176def61e40d912e7eeb2bf868734ae8f276a96ab13de558ec42614167c5aa4c60357f71fac58980e579440f69968d2280bc970d0066b5bd6a6f5002481510256b3eb21bbb92ef2cdd":"383585098edd867a8522dfad08997095aa23539b9c816a5e28359b51":"6e6ee0319af8fafd7ae02013f4227e266244ae5d87fe156cefd4518bcd71aa73f9364bff35d4d23d45b0f47dfe93a607d9f8b399b424ba75072fdced6c3ed2110606fa48ed633faef2064fb336069eec7ebd8ae475978389e6e433d5a435d6529a66c489ce153940d2b1b8c886c8110d8b0aeb641a40e285d6751ce71027c30ec62f4b1fc14f4da20b1d505742cada201cea81930c381f8a6f13dd0a42aac1e0bd7fcd19c6bdd170fac6a423767b831c1e289e0a29ef85d817ad238d91ac3ace2f40a163b0a9bbddc6f05d0bdcd8cc274a74d0743c9fb56556ec1cb8e9cba982c15a9a66fa6b6999b8485db1a86ee18be16e068e12a8a165e3599df96669a1b7":"0183d11f1597ec9db32db21c1e910fa2be2f276f35d0583ce8b8f6ab":"040405136a1220adbb64ab751db3307fafad5447ab2d9bcc52f79be3":"1d35f3269c77c577243f1db8dfdbc4cc4531574276f0da1f7a44acd4" +Nist_Vector_124 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"34c45435d0cc29269272a93d43320698e454a7c287db9d062092acacd7ca086455e583baee1276caba068fdeeb52183396d5444c5a14ad52a5c2bc082cd87452aa8f9b23056b5f8af2638d965ef4fe6e4e68e88b0f50e01248fe6a6a1d9d6d93b03cd55d16fd83cd4e06763d926f7c50f20f0ed6730613f0f4db571e22d288e4":"0f115fc7073262e2f93a9d46b407b0f1bc29292aa09cd1a98a34a219":"5ebd8152935ff2a3f9a61b275e9808a041aad5650f593f612af33bc462b8c994169372e8f80f51b15f5ce966ea3e76a912c653978337e962219e323b6e922dea4bcc23c646a22eecde02433126fbace0e3a01fa6d0b9fdea9245d67899a7b745b8847c8087fa7f6c0f3edafab4c3b47220821fe46f1bcb00a323dff3dee47ee1de2ece44e1fdf3e64aa20c9e6b58e534482e7313dace1c617d8ea9a65dd51fd33024f735c3844c5c6b4a3f447e714ab0c17dc88e33f08b142b72e811e6da00299c82898aaf2bed5ae5170c1dd005678d2b576b9ce3e6bc6b2aeb04c9f04e444e2a9808405ff5926548b59304dddca8972631f7fb136808e213ecd93af98e2e54":"835a744aa418a297b7e11febe7f3bba590752e58fa1ae12ffa3bfacc":"66481f241f6b443148f0b1f2459be5ca16413d947d0981628717c108":"2cdaa73500d0ad291252d07ceff9cfeab87a739752291eb5dcefea87" +Nist_Vector_125 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"d7ac5cc8a4c3f38cfe5c0e1068ea28f0f95d3250d1aeae5f66bdc4d22e23e246ff30429cbcbad3b02a62a0a179d4d107130fa3a780c0092c329c2b026e12e6735a75c495b097aa69ebe98a96ff891234ff379511149e07c6e2411e58976ee93fba7d3d570c911f6f208375783ff5d947a3af0c839d210a8e4a8c8fa41efbc57e":"5339ec1f86a0dfd81324fca6a0d3e102b12fba8fe8c1bca45d8ddf10":"7b5fb022b55fb61f8ef8cdbfee46c0fc61e59fc62dee5c14d0c3134b4f2659112e3f4e7017f9574a2724188ba6a1ce777a8915bc1171d738754b5ac1df923103ad7b198511ed36272668ae0c2e3142ba011cb45f893ddbf7b38625818cba9a9b78aef8d06007ed505e6dd6e20c92d2500234f104c1283f7c00cf2a3a32458d97f7bd17090f76235c6c4f8ae194d52d67c74a854973fd124751f7f5804b67879b023bb6eeac76e96fe676daebbcb1bc94d5d851d7bc56bfb3d2a0a6d992313786d9fb38ad29b762349451d149d0e5fde6ad497183e352828e251bcc7c3a918be4d03b17af60f3f3ef6d9fb2455df7e8b6b169475e5f89db9908541b567d0f299b":"7c62eb8fd725a453fdb2d1e75bbe22f0c5d27a5835135c788061ddfb":"5b6be6bad725afa442f29ab7d343d2f8b4b4941cbd23d69164b3c5fd":"3a1b94634e313fc4df8292e038c6e876336cef88d691b894c0eccd3f" +Nist_Vector_126 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"7a96873f0777e8ada9867532ae5f51938bae2d56fb471e0fefa693b71a2aea2571c0108ba59e634401bbaf20a848ad8c305848420cee654a3040007f055d4e975807894b5618b9392363bc7f8c88d526bc491adbd892a93751a21d137ceede8a04423a4d0ca1557bcf334e4f855b04474544212929a81dc71fb3fc41f70d6b18":"494b68624728aaae9898c3ca22c1bce810a052e25c881a185af43cd1":"0531518177087dff8d04a0666c1301a9b38427c2ea1b162e6fca520181ef22a2d205ceffffb1549c9707805560c6c4b31943d52556bf301c5e0e75924fbe6b5c362fc9801753e630433a9a348f53e62c0746b26e348dfb85853d1ef6eca02cf3f343e77c1769ffc1c109b88ecea16ab6cf476e54312500983622df41e695ec27a41ca7a63121ba97bee7b0e9d547bf420f647d0f8671bf4107a712a7dbc1af3aa8d15b98548d3909f72b9a27f81c46e3defa95eaff7590c626b9ba10974ae8b9f58535d09ca30f9f523539cf584f9bc6c74185c2ff12504f5598ffde6f86021ae514562fed3881197fca22db5590fcf9522ef760ed0e3631a6bd79f29000b42b":"065a3ebed489d78ad676afb5373c7028f843816fa97c30169149897f":"76bd6ff4cdc4fe37f6705e77efdcac6fbb9d54fc0b220643c662acbf":"8a124a3640ad73280f305afc2bc3e57f7a2e074081be7bc90b5b1faa" +Nist_Vector_127 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"d69694bf9a93ac0cc3915973d40e351247c3bcaca98069cd9c1e7a3c5850636a592ea75fae7bfd38b1290e3f4d0aae8ee689ce4137ea868aaebb17dafb255c4a20e0fac1f4666612f90c46320a62002ede3167a34dff74a306a0842427cb9d2c61599b05c67b673144f6c08232d771f2e0af38253f36e122870e04ebc54a512f":"044b1bcb76db64ab7500741f43989d3d878991788947b679bf22c088":"9c588b76269b2f087f7e7af4ec4c0ef263e9636f45e73e604502d62fae90a25101bc2bad2a002127d4b60f5c4a1388880cade9463ab5f7997d54a02c24e7d51a4b8a7d91cdf6afca2b433768094533a0de08dec1f19eccb46df1800f53d3dfeefbfb769a80e1686e8d53c60e8c1511a6dd4f42a155bd85f75740bcbb7b1127591822926d1682982375ea5ec29fd1ef4f283b94e02423a830b35e973caf12377ee18d2c6ee7771184d7a94e7a0c4a01044afc4efb2ffecb695e233aeb80c516c77d1c730d30d1aa4f39da51bcc48f44d07abfbe75f228abec2e7273593c98f323a9b003562a168752e837a1232f462a23d3b185ea8a05361570455aadd1037063":"4707e611f7d2dbb66f5ff083bab786a525884b49390213300b088fde":"108a082d2bf6358a737465624320c4fa9d3719744c2db69d18963d75":"420f3537fa6858657db7a21e72e11ec0ec8cc85a09a0d1a445944980" +Nist_Vector_128 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"17455bfbb128df0f96544bbf83ca0ff374bc086b2de18f74f59049f73eff3c8ef32a48429a4038256304636f3032192795ba2807407ef52b8d59b40bfd517583f998810279c0211771d9e54f2b84e898f9892ef77beba33ff31a2868693f1f0978b89895e350d5ded259fb1397e9c6989986452a0d77df99048fff84b6eb150e":"2bca3c613be53a6aab121de91db4fa06b468fc6550c82eeec4bce9b1":"850c0fcac073c56318a92104654e6a8ae7678fc4014728304649bf1070277706fbd32ea4d41f77f80a80c88f2701e3665be73f59f914a915d66b411bb05ae5c18b00bc216251399732fdc2a68be6a21b3b088797416ae05ce876b6802e4f941a21b1c661e3f06d501ef2a17659f088d2195dd161f06404487a27b79df1ec574ac3abc30ece2a1428c5e0c1d4c49803398d0714cacd9853854b08746fa453561545e6f0d96cd2c7ce1b89bcace1c697ec4d616bf14d1889a79a806a3699f84f19efe690fa13a3b4383ebf77261400fcbe309c2e5eab0b24b197cb856aa27d7d71d92d32aab656faec5ff792ece53874c4069f540d948f8b2e5599082e21f02d72":"4b528d2b2bdfa4f2fce09dc9806ed5302e41cc52f35962653d7f222c":"423de9e112ec38e3a034f5d9675c76f9dc8536b30d05678a2963ec16":"74051e79699fa44de18e36ab116873593a310e4e09dce18b833fc2f5" +Nist_Vector_129 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"de1f9606261ff82218c8c145aa4d5847673b459eb55fe7e6454c0443266bbf800c1d09051f5e3141c4370d1b990cf5fea9d2683986c3bdd2823107829ace6ed7034caeb2f657a07b25b7d60240a0205026c2e3018141d479c07787a14e702622f8e6df709b636c6d3d0b5fd54f5516dbad97038e5c0eb31f54db1264d600efc6":"366a49173a1783b99550d84c7fa02b6cccab12ee9a306bed7bb81ba7":"4d6e89b022c278f3bf8932e706e418ecb20c1bbab13ea8c90b6bd84384f38b311e8fb2c4c0a94ba7d3afca1ba94252a4c1ac1187622cd9c16aa73bb1b4a5cf55b5aa34bd93526f187beeb11700e4afb88c816eda50a50e81860c87fa66a1b63f5ffec3c3ae39bdc009d38fa13da863ca5ec134a7ffcf5dc3ca85cc34d61c5df8f9d9bdbe6a541045b45cb512ef64d1ad3db7b37dba33c6e3c96180cfb26f48c63373a0f0003ae6582679da4850ad2a0b899e0e8a1847df07fef3a4330a72f8a802c06e8e95707e0c7dc1915f6e1731fe650f1ae352e782d2dd77f54e5dac52539a10a22bbc2eea31efb94438a030c4b2451bbff6901b5fb3016cd162af6bf0fb":"13894dda6721bf3af8a40603a3d97af240976a8ecb3ead998eee0ff0":"5f3839eb663f026f792912d1cb0b448f5e2e593139001e839f71c942":"6b07edb6a034d084a61bf3c0a36e7ee6911948ad8f6e50ac6844b1f3" +Nist_Vector_130 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"c1edd86151af66c6223e413f17e734b2bc024ff066578c55308f1388a91ab87270cd25ca2efbc2867eb715ebed6d10012b6f4808f2de1986ff7f4c369daf46c80a618707888ae3f86e38e7f25d6caa509104d4851cbeefbb75692aad499a33aa35b11409300e495fe007524b4af2c20d33f1c8c04516b6973ac1e07df3f160dd":"841ba91e273f1c57847ad336cea47c643335e68f611482a30d6c0bb7":"90dbbe4741a76a5ff222ddc833c0e2dd445ad01726bbea25cac247f9ef9da643932736db07cd9aeffeb45119351e00332d9dfc89f5903a541e74e2e9709d0f852ad65240d06159fe54436dd8201f8c56926e8d23c2ecadeb8cbc9aebf12d52be6489e0acb0e7526fba3754b7ec163dc7e2fa9193319124f0cbb61c2ab7ab1a28c14e7d581dfb8de23f53364d204190a58fcb9ea5b6f61a7979b86bb7a7a4263a1066f0516e5870de423a7e3b906d90313d1ff9322450f72ddda4733ac74fca5d4ad2be22c2667b92212069446b42a391233d85216a88c25b76c947d8d56591003df2532fcd7b18f923ed482d464fb76f2c85617840d370ab99e320e88cf9ef8d":"5ed84fb90761dc03a5e60f3b396d6cc7f8c16c77f065a6ec0049fa51":"836d84d86271e1648466d1955c2b60b2a04cc021405083626347aef9":"63c7eeb5e06e81d8923356f799810a26af67c0faa18b392258e4a9a0" +Nist_Vector_131 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"2b5fb613598c02916bf6b4b0fd7a6b5426ac5b56954392fba32de00bdf4b70953be196ad51ff2c097a81e6ce1d17cf837d2444752be92bd4a9d1a8b41327527ff6bdc0e5c3e0cf46f7e37966aae18a29ce1981f212d714dd6c0cbb410d3a5f3d006ba9b593da150ce422b5cc420f3b561bfdf11dcb9910005709eeb129e20665":"220947396c2de85d480bae730298df67283d0d0694950f5efa4ea5d6":"95947fbc50d5a80299c90dd27cf3910091420d8af849240ebb541a21b49e528b0f3317acc10493d50e6bce676c433c31147f81286789e6a41f4b2603bac0f6e5ee7affdb44cceb42864358607d45f4655a709d7d67f716d7367bb5eab334f61cef3720c080cab17512329e6d99925b47e4960c85031bfddb13f0c61af80ea46b7b8702f8ad348d57d481efe821054fc83b5266782756a42dd431881ea6cfeb7f7900d8f747aac9976be8945952afb8a274dad03428088310a2456ec254d1ccfb63eedea5d374ed8cc637a7baabf8f422e1a12d5ff316dff8a082068931490a4706503d19f93554f25243751dfe62cd87cb856f644fbb6fc46fb9cf89af5aea1a":"2697349761cc4ccbdb4550bb9ca73654280ade31f577ef86100ff4cf":"7b455fae1002fa87f36cf6f345716225d4aa1407802af4082bfbb14a":"235d8be4ceb0176f5d0c47c1199afc7e3041c7d7508b9feddcaa0d74" +Nist_Vector_132 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"bd7d69bcc2e4f8a42e627fa21c7fa9fdd3e574b6dc5ad20217e80bcc9997b4c5efb31c7b65dbe8a0a394f0af580387b9917888152dc4f63ce52d3ec4b723bfea8114825f9f1e259f67b5d13bcaa66c97de725fae4ad247bb922497ebed0f092bbac12f2cbd9b71b229087378e8be0626b8d5e8950b0a6e69e05129f0d3842d27":"42777374114519bf323bd03b6e0ec238660dc863b1a3b85e0cf8f8a5":"6fa6dedc84a1479be43906f2f68df0e93234ca2230c832db079d9cbd9342b2df13de4bff10bdd831313453b33b725cd616acf1fe2f7927ea32d46ff10ef1154e503f71165adeaffdd500a83bf1001ed36ca65bb6974d0372cb0f2118278466fe1286adff3c7ef719c2a02cff9ed9374fbbe6051814d26848b7d970fbecfbbffedf40a03083fe33d3067838ace22854a8e88bfcb02ecd76c378bb5c8babd22dfbe090753abf9e97cb6ba708ce00ffea5c550b09f24930698df115c020b1301d571a470e5a8a6ccfc74ad18949a57f614fcb0f7e8bf7530a731bb6091a7301af42899d9ee9e45aa62ca4903e66733e47d01e26b299746da75c7a57dc00bceb4d6c":"3ad0d788fbfaf4caef4beec9c1566a8c7a1de26bf75dba82a8243270":"16a2a48578a0b5b57553cd20005b7e8400e1061c4fef20d033f72f8a":"6c34d176e95dd49271ee48a3802edf4238401084bc3930201405693a" +Nist_Vector_133 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"7766e1ab7638bcda3e6fdbd4c85b3661acb2763d411376b2eedb4b2c6bff5d8fa20c0ae5b3cbed20796a6d8b81a1096dc36a39826a18ffb897d36bfb16363cca7632ecb71d2f996cf7cac66669bf4c83114bd53be3be3305efc99d22769188f84289cb1d11501f040b85d15890d29af2c8eae614f74beeeeb5fc915afa4322c2":"364bdce93df0eaad45ee0ef5c18828bfe2e381db607e5b6a77ffc6e9":"4c2b559024f1b3ff5c7167270cd1f33bbf0f40b9efa25e137441ab4698154e74da3cad34236da4bd1c57d7638e4277278b508e85e3a98d30388ab8638f553e2a700011923e5d154f8c1407452dc4f80770c9c31c368a21e499d5dfb6f05fd67791e761a494200710af8c2188892c2d1c3195be4a0a1d67551ad466fee80d7edc435379a72c3bffad271de31ad2ed107d784f40e24c5a6e8d5aae8f2405964fe3c28cc3652dc3c9523b39d4b083ee65e9a07ce897a17b02b354766f1b19c2b1229ab468b0148ca8fe89484b7b360024218086af56403707bec65c52281cb8aa5346cb6f6481430e8e057146f390607c572b5bd8426b90ef3a827cb0d58bd438d1":"576f8454ff45df954d123bd1384cbe004413c8f85493ed7d6425bfaa":"09c61878a9917177058e9dff27106bdca7d06c500e09099306668cbf":"7b8b6c4c5615976d7a735ac3e184cde96154ffc87b458924d4602895" +Nist_Vector_134 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"84095278f7f1d578e798399af0bc9f4695f9302ea5972479adf90c95fc25d59e576d97b89b73dec629cef05d6173b55d015a3fb1d8191ae540d552409b03a7a8db511bad0951896db949fcc28870f9d17314734ca6a3472683d02fdc8defa7b9d3762ae9357ca2a6ab623b046350fa211d5213787127d2711cbd91405abbe50d":"161fff26a7b9d7ddc15237edbab3c1f99b7294c70feb96f962df8973":"4b52c56fc64922ac04ee7a80fc5c224013e2ffdaa167381257e00c597b433641ceadbc9b16568bbc9c6d31d02c8e36db2e3987520ce8590856bd4a841b725ec95a4659a61a0086f66a6bfdbf1e4bf92b441928cf319f929a6428f5e3ba7c89123dbb0cacc16bb0e2b80854b0f60dfaa99f9c4caa412c443a073b7a51259125f012d98f0f6699d70ade66df9c5e18185672e0e2830e0585413da2956c89d2320faac03aaa83fe718a0d6cf7feb38a194e4362d7c89e4a13967e3a2d4493f4ec09ac2fc89d56a595472e60332448548d91cd6aac84a2f9b4d7a80462dc154779be5f9e1f709b9d9a156273033fe6e4842ec47521964d2e2fe262280fddec6403e8":"7cbe0c1c29b955fa1fdafcab79c02177c15ec5789a4dd53a6ad29ce8":"0c4d4527815a94bc2d77063ea69049be6a2b3b3a3a0badd5e62a8f9a":"5787ced7081fad3fe19ab5b9028e9e8df18639e4991ab6e1e243416e" +Nist_Vector_135 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"30eedc9d630b632082c196b969d24f6eb9cf1b1e2c53d244e8d8b50a40982ab53c4d57ff995fa8458908a743890382da6513cfe9c1991824873615a8a16374a5e5dc2fab3f5cd25652ec8aa3939f4884f74ac737989b6ac2e43f45b885206a31e797fd8576357e4b4baa566291815dac2f546f4abf8ba1de1120fd804284e959":"0209c00edad10594f7cd7878472169d512a7e8dc3fc1cd69285e69d5":"8920f6ab95b1dc6b93e08ead6b08141cc2a8f1ffbb71d5ec5964f6b2c3d72ff3adade52254370f130990b43487775c2fe017a8200d8119818a15ed7e5636bfbf3164042f27bb1ea418698b6756f75a8fdaebf0f6e5423e460287f4fdd2a0ef305e658741373d3baecce79063962f883398c314e36230ba8c570e667c30cac8fbaa4e70202a9157d22708ca605403066d0fc84845bce9b8c3b41ec32f40c845a532fdff4dd10cf62a714121ea8a6188500645afa9316fb3e11628b163d35d8cfcc55272b650e8072c237645600150bbb66d393c1c97345d5820f178dd405b5d46fc4ac8a5f3929e6b1627944093178a8d65101059fbbbb7081174f2308b2653ce":"36454e085b6b3dcc7c755b65ff46697b099485abd6ceb00cbf5dceed":"45212d1c8c128002fcb3ce35583ff8d08363711c1598307d9ec6a108":"4858105649db5992764dd32b102d9b9d2bc6af64c6a81595611e3e20" +Nist_Vector_136 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"e9f59c6a5cbe8f5b0cf75008d06a076a6739bdddb39b82143cd03939aa4738a287c2a6f31829bbe15f02cc2ee7d7122dbd132825970daddd8a4d851da86e7edc8940cb1188319218b8e0248a103eae34bc68d85f5a32830d7e5dc7718f74db5e4224c0debe1e841e1eea1a88fee0f85d9fb087cbcee55f86037a646e38346d2b":"6a5b4ffc44238d1852fb9b74e4c1661be85984043cfeee023f57cac6":"af6721bf75dec6a1b76ad35ca3750def31117c5b441c15a306835a1db74c003b86ae9099ebfb745b0aa9cb000cf43fb021513b8f197bc865b22bf949b491809ad752ffc1ca8e54bea16dc7f539e4c55fb70a7743dd28f262f60ef0f2fcaac29e8021a7938c18ffe03075d0b7e0a2b4dcabe46ed1953d33e37f113af519ab0bf0b6186c12b5f6488437f5193096e2fd6a6a1835604794c66b42ae5265c1cf1cb53ae84997975e0318a93ce41e3902e4ef54de3c56555bd19491acd53f3e57464e1f460389dbc5fa80648fa5a5a0f2956e9ec3b8dc441b535c641c362eed770da828649bfd146472b0f46a4c064e459f88bff90dede7ec56177a9a71d167948712":"9ced89ea5050982222830efef26e7394f5ab7d837d4549962d285fae":"9da9966500de9d3b6b7f441ca550233fc450944bc507e01cd4acb030":"2d72f1f6681e867f7d8beaebeba4bc5b23287604a64cfee1c164595a" +Nist_Vector_137 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"971d16d111c96de0f7098b256af213f4475aef31007e12e2974c5f64b2f335e0183c196c33d50f6445c5f614649549770b1874dd0756a9a8e39971dfecc3f267ebcc1f5301703f88743b0f376482cfc06d5948bd7926d96ec4d731a44b0c0eee5e85da26687265de5a66cb1a73a7e4f3236f60647bee5c163340e19505577cf6":"9053ec8ab1f9700c2ab59259bf2e07892904f03c844cd58a7ff59c79":"290517297e4249fc3212bad67269e032818d760b0ee0525dc5a17c97116ee29eb3b450b41d15cea405d5e983a8558184067f424acc498676415e17506a351c124b5404f1d17153272619df713ce34d03f1f9ee28592f22f829a31993b106c785fa6dbe57d0049c815db5ee2dfe948ddedd1a5e2cd2346cf2f66f04fbad619cd983a1b069b471ef9adb4df6ceaea23d09f0a548c3c7209634c8a05e5897445906dea08a52e4074be22d8485f20eaaeadbaab397199b067aa860056991ee088480b4921267a698a8f7a03777f56bac84e50903e88d07261f24d0a4f317128e01fe8a9224f12293949cb6c3f095afd19aecb16b209a99487dcc2a1b83c49d75e351":"901632e0b8ffea7efebe2fc9ea0d1a52442817fe1e1b5455bd39a687":"1f44f6eac218236a1d99cf7625abcf5c964b0a0c5d88b8d05d74a3c0":"71015cbe8622d2a34fbb5e7cca8c59e828adee71f50524482d9e7904" +Nist_Vector_138 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"08ea09fa5efde215bd8b3c4d6a9c90ee9387ffb7bd65becdb88b40132c6384106aa619b7c66ca92034d284608593864ce6b92877112aa139240cb44b388fe68a8fe0501ca584f6a2de27c0fb658e72bb13fddb8d039a6bf85d63a6c073b2668013ce8fe589a0150e46d5b1d9b0cbb5a14c100ae4b20d6ce81a987a50a949f434":"a2cdf2515cb098559fa13cb70b6a897e89df120a971064bb377988ee":"b3e2b7e0641721d69616679596cc75091fade2da0558e310b8d14db0f4686f1fed48d0fb7f0b3b27bf6e1981eafa7737a3e651828d1fcbf88387d06f78404a7afaeaaf8fae1893bea3a09a118893937ae2a8fdef3320942a158463de4fddc11987f23fee9633e06ac239c06610bc45319abafe517ce4aeae6247ea789d7da60d3eeddfdc4b232b4d7a069bcc0eac7b99fc088fb7ec1946034a98d7e69cab0cb2b06b3d9deacd1b433ebe94f547a322895cca9b0ed319b1d458c3bfb260beb641a5345dbe3d01ce800ec2c6bd430ce3e3f5f78fcabf91a29658661c573b9f6fd3812e560d888b6cdf3d57673c1630e00ca841ee994958b250dafbc3e83bcb8be5":"077b3adce42ba0622772eaaa8cabd16107c92f7a134c715a4dda5ebd":"6c03637d253a8dcd0907d6de93926bdb3e1ea3135a709da2309a8da6":"236e5163f2c2ebe0eccdbd3351e4285531a4f53e45284e41db37e266" +Nist_Vector_139 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"957cef163b16d8073d5d3fe158fa0c7338bd107c6a653cb0f11ebe41402607b822abe30e36ca9ee4c9de00cf72db97f57d78f3db49a8e1093285563c68b0f4e124830b9febfa3e75ce2ea59cba2cc6d71e908b5e6d8f463954922b82bb55a69fb2ff143ffcae6b5656143c8b6cc24f57b17cfb020f6e15bdc5f25436d07b7f8a":"15ea86b973ef146f03cc701b17b589b0ffdd318b64827d49ee3c0044":"3fcb8e44d6880f9eebaedfb75994605c9ec001f0595aeb5f2bcaf6b3987bc28a7ca905e1fed7e3c715401b5c608d12076938a18013473d8a433277fd9ce5a5cae038281e768ff909aebe4d257dcb5d93488022d07d4c2862afb2bf8a2b1e974a8e7b6e176b1b0b7ad6f63bda1b7142e46f504dcccca7d1e2e7662758f760e624e59528c5a0c9563ed517c691fba2abf66899241178223ba20013ed0ab21f91f3e6bef755c8100c51ee947b7a9ba38570f880b5e42f24b72d5321132e031b985a0db825bf3bb00a7771a03007387e03ce020fc358e65ed3de8d847f5be60720917c0616a450aa341ae00abe0a809c38e97314f303fe9b0c6cde446d0217cc4eab":"9af96c995f0b7b8283e2ea288e3c3a6f751a56b38041297e2bc34cd7":"150362da792701694e23f0b0a9b7035437cc8f4faa45c6df8f7982fb":"6df4321c61738743a9fe78ec76b4952692aaa372d1c8530fba0fcdec" +Nist_Vector_140 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"204d9cde24a2f0de02aff020f6363fd68f70420dc1a9b5138216201363f832da0aa801865a75a243427d9d6c78dc5e6041b27d033660e1e405abe1be27c909994bd6fb57180c3d6b498ce8793bee8ecf51e06b96411d00996209f44a380926c7b195e84e78f01fe02e0bc7032ca462a5182683475222f9dd8f3ade1ab8fea318":"524a63cc5acada8557609a5f0d88fd3e9c6e63719704cd8bab8fe301":"99b8fc6e64cce262ed741c30cd586986aa2e8f6371b848a2617c619897de23726bb54536ece4b460cc7f1f39e0c184eb19291e930dc9140e4b7735541eeef8ca8ebc81790fed37a5f08e9da9abc66a3a2e909902a4212106927d08abec01f27c6056b6e0381150bd742d409f6810fa5818ffcb3f182adf894ba7f80678ce883c1089a6ae71db3a115c386dd9153f4191fc365461ac86838ecf2f3f81ccf283297a6fbc644f52aae664901ae30c96fe4df930cf1a41757241cc4d9adfccdd9a6bd5004b05757443598856400dd771dc089095c7dcde82f721f986af636638eea2c71770856c2ba80315e8696142a11e51ebd7559e9da6a00be3f9f38c614ef207":"028091483753f5643b61e4093a7e0a5135d71c5fa318d6e8bb0efc66":"9c023331751c79d5da355bb58e2bbe2e973e3e4b4f52743ce1f1eec2":"96ad0e8ca90627fb7ac4540c9b58a016ee6c4e0a6f0aa1e7def81a51" +Nist_Vector_141 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"1e4e58afb34c5d6f645a82645be358a2e228cc7b9c23dd7f3aa79595814d054b923b9cbc6c9e6c6f94848c1a4d215679023a96976a44e9b59136241fdf26f8f71fe5a9bf366e4912b5931e1c8f63c37fae2bf1d55ba3943a650bb463cded9a7b062ae55aa57d9c5ceed323fd9a7555e48b834d3ad4441c35d9e07c7c6e4d5d0f":"33b25c6bbbf816addad05e48b72ca560c5191214d903a978b6708a30":"b4dea0d5b671cc815382d0ec6dce661c30ff93719dc7f56e7e61df6eb6a3207a05617938c874bc3ab093bcdbbc983a4b0b587d60fdeb7b87f7b0be4a656883f5443ca7864541ccbfe0d0835636ef08a936b2321a51503be1eec5f7bccd0c73c9cd52397cc214318b30e8be1eab57200a4d4df78af991bde183e0164e694d8308b7d20d067bfcabdcb50f7a2c190c66ce3dd0e18960939cb57fc3a2e5a604f3d9bd6fa440d54e9cc0383958a0d6aa2ab670970f9b2caf866ee507067343f7513e0a981f3a344f2f753af44fda26d661796032bda0f6cc30a9a789db8d3d546f02f898116805180c6f0d2f5388ab5110a521077d88d214fbb32eed2664406cde9b":"989d87703853c4133b6d273686bf672492e90ce2a91b3c72a4188a1c":"0434ef1c127207d0c884701e75d801725c451ce67d2e71534638b231":"0c625e4a334db07825a46b55da9c2e8a5f600a36b71606834097e777" +Nist_Vector_142 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"5a470a38b2ebbead08e010efef7461f6f859257d91a61e2f0ba809e28c0ea3d410e4f41477a398d593df58039c4336260ea7d8e98c9d7daad0c31ecd1567c7db730179e2a9a62007bd56f9d9da48deaa657ac92293e5bfafbdebad1afe25c41e1aa09db61fcc191971c37549155b3e67956913aae3a5f6245cfcb9aad5dc1e15":"13411c1a6fe0063e7f9b2467ccebf2be5cf30e742f9a35d715558ba7":"06a20d5571296eeb87e79eb274036d819e8623b15de44c2697dadecab2996f51a75aa088490e683f34d5e0e71d9fb8734bcfb71e9d19cbda3caca5cec417fa37a06142bfc0682de56f0dce6e826ee9f30d01279859d3ffbd4433bf4a1057ba0ad75060d41f968f6da822c33cbda9f772c2b77bc1b29305cb697182c0d39b132868932c64016bc9071b30920eb385c5ae41c5d4f631bf5f54b1eb4b373bb3e0bf6e448ad8c988fea16e643790307b8b85f009fb67317217d9148c6cd7a46136eece1950a119e5a416a197e00d0e929b04a5bbf6c988d8595a0b2a5ca71926ba351a5f7674af4183b5a68979bedd6491295b0f172e7373eca7e62d78d744fdccec":"7406254d3cfe3d55267236ff63b0f42b2e3b55d1cee7ed1ca3f06ce0":"74dddfa35b25d0c0b285a5d21719ee39d6e3f443445ceb90556b0186":"474865d3ef07f5df49e0a6ebfb5ab5c2ede47c4c6314be4ccf455e21" +Nist_Vector_143 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"0849d67ead3e8c44ad3b2f949be1cd9f9a4bf8b5785bd00ca66038e9a8b93727a652a415c1d8a1ecfcad77782d87d912623c2fef45b2083ec0f79a264ef7c5bfb76fde5b22b9845392e759a1ec05fa6387ccd2943ef1277c2e060337f82aa562cee5bd7c158258f2e779d51e47e000a7b0706077490976a07763e2efb275b5bf":"5631c7dfd3f5adc0b7b542a8d121a07bb8251b6a1bf3a8cba771c724":"b1c61442d8aedae0a04daef7b6f8a49c6d07bd958e8ec561906ddf31f3b4ffd481da5443fe8788056c4ea7b5dfa2cee6474e3fdc83fc043a2bba333d503a2a938865ec3f118640e8457c7d974e2a65659cef5b7ae4f49a054d94ae5e2eb6345f5bdaf92148beecc109c55031fccd90cef88213b69ddb754b40ca8d8f0a4bfc81a287637a38c21807f727a67025ff67b7fcc54418adad408a5c7d1ce05a1de7e30988d560e779fdea1b78753314b0b80fdacb6246faa4b4c4ee8acc5ae24b82312040134cd8cc2fd4fcb191fe43f64d140624a8c6c2ac5fa4bfdba5d625d7d21e3c3f6acd8a153a04fb22f8d3b244ae8c6a1dd0e6e3b2f73c064ffabfad6cc461":"9c353ace0ae52501bbb98a2d1c9e28f3a833c2b0eaca49cd12c57ec7":"2aeb7fce1b7764d32cfb7d85254ceed9f3a6337ee8dab42c8ab7a415":"17cce13bcb917cdbefe0c566318fc974204b700c5cddc5b2b499a78e" +Nist_Vector_144 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"e74639f2bad42fd6393f9b350d6e19cd4c1ce0f41e8c902684ef6f86790ffc8311acd9b57d6521e80339b3243f6ec6b01a06ea899fd75da91e1080fdf06129dd851a895d74b1efb9837289c11d68e1308c47bb8c59d5eb895db53bba29102a5b48b1e75c73387ff22e6c0461196a7d48615ffdb9c8ff4ec6587b4f68d260ad86":"7319bdf79a4c8dbc115e3780c818f6e2a3243ab47263e84ba259bd3d":"9e1b77243aba0886f9baeca6c11bd2c5c55547cc502e731d9c4725da8777ab6050e3399e25577704cfc66163f6df8d749142a7e974e49b7315ab7c8b85ad5d5cb271cf207eb72e1c3476b0d863721c967be15ecbfbf06eadc27de338eaa3cac1dde642d52aa5359198d8909d23d87d827090a8ada7b7a5553642d586603ea2464dabd2ef5e18db3a623be65be7b5a469890f9dde54a27ca723b4e05d56b7181b28d5c1f65415688ee41d5337a9952d92ede4d192b9091639caaa6033e4749418dde15abe4bad62c37fab05e3bef4cd7398a4977e07e121fef2aac56be7e0546e40fca885696a3850c9a28709e699d52611c9b7926e7ad18149040582c997db71":"6defbce0e72f014526c8ab02c6fc320a4bbd85365d99fc5d3423fa4c":"515b9ce53eb10c3e47890556e0f0fd19adb207b9c01f12ef5c6caaad":"0900e3acc4c378bdfe9cda4db8f8ab54436931c73d8d3171c6dc8bb8" +Nist_Vector_145 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"4a145dd5cc4a12ea43617ec9790f1038190ed3d8af24bbec14da3ecf5f387ca9764a8b9cbc5f6292a53a9da9533c751140f8da5fb6f3d48eba1e7b98662734d9a8b120dd515408ba756f75a5755212764ad92c3f2263835211add5b4cc0eca8d4fc7a843f49c38ce80868faf8b498fb414d3080ed41e3674e285d3e40d62f305":"7944fa1a2a938ffabb234ca385916e01a89220cd16f06a474b9d4ac4":"b3f6d44da86a515d7185b70c5adaa3f6059c0bb7995a53910761fea362d9843f92f2271ddb0bca0d4519e33fdb13af49d855cd0b9ab0b970267243e468d3c41677ac588fdfcb1cb9aa4d233f7ae017e67094f4f4d904e1575e76bdc6bd8299b42a2f39adef63ce047862aaa0bb8ba32ec2733493648406f54f5d8e2eb19eea837f4d5963ad3192917f5fe3b6d027b22bc1bf0dce8401d622ca72b1d73a89e888de1e62bead2e4e1da6b5d04b2a3694c76fe07ad3c66426343d67be12b2a72c3f76225573fc054f3b7d735915238d7bdbcb03ba6dde3edc00f8c983b0b50129fab426004a27a038139f2d3295b5b032701face34a7523559485fa631c219237f6":"8ab9322319a138489eb773f3220d712d05cd14eed9aae402a8aa767b":"5cfd4b9f92ca727d513ac14143b125148655f1642c53b73cc25131c9":"2adef94aae372d579c99629ca0786362cb0247aa6d99957074cd7d43" +Nist_Vector_146 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"428a20790cad1c7ba82118ae5841bd5380ee50be5b64b8040935ef3d6da37a26e6f02035fb1937c7a6bcd88c894fad7d8aa48abb89e0c64287cdc637454db89eaf0a7e692734c8a243856dd75690bdcefe554e39a0df84e6e0c96b2c5774a3e4e2afed028fb43d7998d3cdc9a6409322cf3bfa4d1e36f5e707203b59c49a753e":"43dea1b4e5c2f22548074d7dddbdcb94a235a3dbbfdb7b3bfc5923d3":"47a9340ac513585c83bb20a2fba946971811184fd20065fb95cbb20625b47b216f75e1f3d89797f540a0485cfbf07b1716a3ece7027d86f4940ab90bbfdd8ebf15137bcf8805f93cea259c4bea5a2d3bb3dddf83aa290d3573e91aa300bbf1afb9b525542d67a8d86051aed8ff8a2cfc225a9e51eb374c31fe103ae8f4a0c8911421d225c019e1b5c07dc149babc26b708fc0fc0c13c3b35390317c409faae81aac9ab5d01ce85add24917d94cd1b2141b638de3a253bfca6b7f1a8104518d1572211ba52dd175632c8f3f6748265a4bf6c2b8363d9810ba1f1e584794f62319f0451da831d457b5269bbe67784c474ffff692bbe2baaca32d3f85f4fe39e03f":"5615520867828ae7dbc8e9b116e7661e18f09e5cdae17518ead1484f":"8a96c419e0f391daa29fb162a1b9570f48a00810aa480cde0f27cfb0":"028ed9165522fc59aeeb79c491a95ed8427fd1b695f3dedf4228a328" +Nist_Vector_147 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"2a07e28fc102dfe17c79b9368e0ba92414d2fcb407d34e903a0a53370f7d2d33aa13c02e527587718c3b39666125eca2e8fd4c94b9867fb6ef16d555549d8dd0f6e10417ebecf48f992ad84b5d9774540785ddcd264c55796bc2162898ecef4027c34187f8c0b1c20d4daa108b70d76c40ddbebc1e0f50f4dc904dbfbe6beb9d":"5f4f3c4f95efb91c6b49f43afbde6d0f9b5a1324b4926f3276bc913e":"05f27ec035627860c31aa597c96837084605f270d15a3fbbdda1c3853db2ea6f6c9de4e11a6fbd773c300ebad0f9dbc33608f9c4c5cedede0c26791cbea35af0322a607739e97c3242f0ae7d36afe269aae64b5fb2db265cd756ced45d888eaab0465e509ab7f83d623f69e73cdc0c7670675ce0c29f49a19d7038623bde36e29fb854e6fe6ffdb916abb7d61fab4b620dc739a5cbd9608a45e86c2bbfb41b8699166822e832bb6cac66e004e93d190b951424edaf34bf6bd343bf60154f739c43562b03aeb4d23de1f76c18f74b5f7a73c805b22af8cc6bdc9b55779ccf6d441cfd3154616cda18807a9f5e2d7659e9e21329755157dabc622bd1ae2d5097c6":"97861b777e2a8cffc4c2d24e2df9eedf0b65ea2c9373c1085ba44efb":"91a4576931ed621a0342f14ee2ba8fa8e1bbdf894c1251afdf72146f":"56755ca163f7dc89458a7a75d4dd3ce3adec42b4aa7d04b2858c47f6" +Nist_Vector_148 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"7e96385816c97bd9de81de30e67db72436fb42faa9b6ccfeab1fa528c69e6351b2012a1097fb86d8c5cc60256ef11be18f16137617f8cdd29e3bab9468c12ae34336ba0e0eb6c828177d1d55b06698ddf753756af830a10ce9c99f1d13682668e3eb336a80618e666280096417c1e2b005b9351f5ea306b8c63fd184a59132b5":"914e5d6d95ec12443f73c127b797229544971177f645b8dac5f6911d":"2b69bf21bf689a1f5ed7096b27e447c1d52fc2473e9e4353dbf185632022fc605cefe5489102f7cbe984f00c1ab32f2def1a84f1bedddbc15f87aed0a2b1e912e9edd74edbe2c15a4c37533014b9d32b05f5a44d323def1cebae0e216bc35a1ca8a4265c3db5574eb23e17f1838e225e467a9426e8798c5a2e896536c48c4e24cd2ee9da1b61aed2e25b98e4c1f4ee55e0b4705feb2bb1694cb18a6414bcdc1a7489b4bf8967985489316b3e57ea281204ced3ed88ad1b207be7d294127bca86a9b861ccca192c15c815e2328cbdaa5899c9dd271fcd6eea0d2ab009a8ba001e6725139be26c5151875cdca7f91434443b9e5e47a45cdc8b7399bc5e8bed9300":"7d00160fa1ebb10b0465321748eba9ca6e1b3b5216c0c51dc34b98f7":"1bcaa2caf483abc80b75f670252faa2a8e18c32301ba6fc06f37c08e":"909a7852b8d5c8813e17c040779ad0dc5e9e0556612056835e68d2b8" +Nist_Vector_149 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"24ed7a16782b5c34beb58bab6a7d2028719f9738e5d1ba6978efac4b53b37c88e7ea02e0cf0fd82a3e50046052a9049541d12993254a46fe401f402d38943e94918bf7a6fecb08ed1309b7b0f2185967ef289a2efa6c2e37a74d6592a2eb7401ca5e98bb8645a94e57499d362e0f3133ef336e119561cee1b558c15508781868":"3a42f9927b4eb39ee3a910e4418987d1af1ffc1f3d5df0c4920e05d0":"9dccc137197bb29824b1c10e9e8dedd714efc936cff83f42634d64391f9b7f4fc3a231954a8c3bfe4ae0f82225fd52b5dde6dcd14c0ce5085971c515da38183427c7e2a8d76e40efb671af797e0c576e3881d434ca809dd553ccb0f7cd9f73c7aea2268f36c84170ab0ae03b2b46a219547564fd21c540b1603ad7306d22a9eb8ef37ca08c2b28d16c5b9c54a328ebb3c0f9505095c612270d52637cb5584ed08bad7138d3388c634b6502fa6473a2f594040b9acc1480b343d2287fdc70d16ba14b1c2117612dcc5860dbef8387af9aa5e1621d37a38f6cbe5935673ea3cbcde4f32a249eb6a5eed41cfdcaa4c87e8bcabaa6bd1fe5a879d17e9ae35837ce0f":"23dda49474ec6cd13e1b0249ab24f50e9d69e40c6b5c07430780c44f":"5f4f5449b8d0dda3ac590ba1640df9772ff08cec08528bc2d70d7ac9":"5bea04bfd33248f26aee98ca8596774e95ce685465174d1caed7d920" +Nist_Vector_150 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"4906dbdd9da6ddffa152fa2e250eead3c6ef708387a3ad64d34a0e057459471f48752fde0786db28a4bbf58114d8dc91b69e56be3c49ec1b9880d9917c73abc895754a60779b18bc951550b957a77c8cefa159908126cc801c665d1b01109ba604bb9e797c7a37660bfc0593bab0924df5806ca803381b24b03de3d03b484d49":"0c53e5311c104f11f6eba646e4840d1960a92118204a49e3ec8ddec4":"072cb5612596aa716142f5f756c9542013f3f1628cfc5497eb1ba0aa51bd5adb8eb8adfe059c0e0882e3c09a17d1f51accb687b243fd3052bbcb81b063c1e7d5be066587ebca078006f6d6ee71a69ef59b6365cbcf64d4cf1b9299e7403009272026fc1665ed403ab8dee40eea4ee7d562af001951926dc8bf0c783984664ffef629cb59d709b3d9aa06805d62afd794541a2b4ce0c59043acf73e18e74453e86a082f17914ba6b2b0fa80da8353c7ed9162609575ed41f8eb78dbafaa7b518de0c85b1720e7f493b914d5a3d2d0748273d169d55c45556bcae670575c96a444fc1d789f5bacfc8b24132bfbd75b3061fbacf2935a219b0f2ac5dcad718516a9":"3523465a8417b3a05ba1032bf6c42511591f2830b55144f9662bf6c9":"77475900fc7f3e0b80f3884af8604eef60ffe484bc6cd3de123f7959":"26ca927da0d10b43dc1521bfeb58ff347ee143fc38db451c11a03510" +Nist_Vector_151 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"de3605dbefde353cbe05e0d6098647b6d041460dfd4c000312be1afe7551fd3b93fed76a9763c34e004564b8f7dcacbd99e85030632c94e9b0a032046523b7aacdf934a2dbbdcfceefe66b4e3d1cb29e994ff3a4648a8edd9d58ed71f12399d90624789c4e0eebb0fbd5080f7d730f875a1f290749334cb405e9fd2ae1b4ed65":"5a42e77248358f06ae980a2c64f6a22bea2bf7b4fc0015745053c432b7132a67":"880e17c4ae8141750609d8251c0bbd7acf6d0b460ed3688e9a5f990e6c4b5b00875da750e0228a04102a35f57e74b8d2f9b6950f0d1db8d302c5c90a5b8786a82c68ff5b17a57a758496c5f8053e4484a253d9942204d9a1109f4bd2a3ec311a60cf69c685b586d986f565d33dbf5aab7091e31aa4102c4f4b53fbf872d700156465b6c075e7f778471a23502dc0fee41b271c837a1c26691699f3550d060a331099f64837cddec69caebf51bf4ec9f36f2a220fe773cb4d3c02d0446ddd46133532ef1c3c69d432e303502bd05a75279a7809a742ac4a7872b07f1908654049419350e37a95f2ef33361d8d8736d4083dc14c0bb972e14d4c7b97f3ddfccaef":"2cb9c1d617e127a4770d0a946fb947c5100ed0ca59454ea80479f6885ec10534":"363e01c564f380a27d7d23b207af3f961d48fc0995487f60052775d724ab3d10":"4916d91b2927294e429d537c06dd2463d1845018cca2873e90a6c837b445fdde" +Nist_Vector_152 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"49707b655b6d168c70baede03866b0fba60239ad4cf82f53b46e11b26fa8f6276ff6687d09e8ed1e5d963c11e4763b2e59a0927f01e8fffd1894a6262327c84bbb4298d7d7fbca660673128bb7dea46178146485539f9a8f88dac761d0d5d45cb557cdac960be23dd9199acd99cb64d1fee2ca68e423461a02abb34c1dc45011":"62177a5b2f0b44352f643a9e69c1adb4a0b292a5ea52fa8065e94ad043d46218":"385349ecf99ce783d4e7a80a7dd2c533a3623c38260243ac392d4eab6deda5b79b8f9167922e8b60468623e4603fa7681f535e20de673531255e108f542a26d5c87f19e063372d142869c5eef1325281fee7f1c74d2a96255d420f2713864d55d36f8139194f643a6e98b5bf9732c8597445af5a71e23e2ac5cae3604323f7bf09449786974ed53a5717f9aec14dd01bd1cf276bf3c63dec43c3ec8ea6557de469916412f0456c90f01291bb7125e9f855f455b360c03d4a7b4a8d4090e47aaf1111f382dd2605734fb54f4b8ffe23c9ded2900b3121b497bd46d0458a09a5df4aa9cf1be906f5542313384f93d377ba9e0a762b4793403b914e52865afabb67":"2bae4225836dcbbcad976ed47ecb5f3fc05439358791be244e74d2cf0617fc26":"0fdc5a5a4a2c2f3df50c868383ba800396ae25265be1a14762d3110cbeb34819":"4b41841cad45fedea5aad0a16b053e88353b6f0102df74c9fce09e38f5e6c277" +Nist_Vector_153 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"763c1f15c5dd8a93aac4e048651c4ea84af18aee255b56959eaeb1876699be75271af0da6c3ca936e99be4ff4436410f69ae7018b6c843dce9d8b71a91efa53c39be55f285fb8ad8543952fd3ca89271ec23d342cfd557bfb72db43b434d0ed5b30763037754bb0f782ab08235a64abb7f0a828f892cde7e05e301da7c21c096":"5d169761a3887a9eca0f7e59d77b75671ae02210006e754bf2f12091fc3275b0":"0becd917eed0be9cb58ff9d259a8fa415b816da4a25d3f569d7b9f317b3f47e4244cdef35796fb455c05c156452f1c8660f5346fba169276221446f82bbb2027b056b537cfd59c57299166a6f20871c74e6c1d3f5a37b75e8dad6cadcf12c909586a32f150c68e332306abef8be1abd56c42d3c36936cf8f2acaceb707994a3d4c0555a015de892037aac68e33813bf3050f0f3a8df5e81465852f6a195ea688ac5d258eee2076a6b236362e3d792e7f358c6ba994da7a64b18263969655473aaa37cb3cfb00a27f8fb24a4b73b025c96335438484e958ad0848277df950847d46a9874f1039fbea7e08bc79675ef1df6ef21230a79a3b161308a0a4600b5347":"66011bdefe8cc4a04fbd5d69252bb72da8f9a8d6e00bb7ca75719133ecd86f1d":"76e9b6ef7e8d48fbfc43bf465281592223fa7e0d9978392d355868c8a20209bb":"7f9c8deab51c60bb6f866c76450138e0d2946aca6c5f88dfe35a0c1ba493ee47" +Nist_Vector_154 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"67851de982fc70f969d82f65d85b0332d667114f27b58bb9e565d2e40ad011983d936049cc97a216260fa2e410ad6d6c98a548759aa8e2d022c1fbc1b16b10d83fbbbd126ec43d5fedc407c831461c7f33ed94740031ecd0f701c7b1df88a249265b3f60c38f4285bbc9bae164bc38e162c235c9a9dfc1b150eaeb1482ebed48":"4f3e2c5901b656118d88a47fe2bd52f85cbf828dbf9b67365e2013a937f0f2d9":"ab9a99ff87899bd6657b3a9e9b7206996bbc7799dde57dcfff8098875dc4650d791e90bc4cee10989bf49eb5e6230857f96841ae8362e4ee5cc8602f6a1a2c6f8f2f680ad3a72b0e07511ead301f575278a074138aa4eaa53919e34f001cbe2dcbc345c77f5687d071981a4dca29d026bb53ec9cf03a88d63c52206d351f8fca10239e84f4915ce347f48d650aaaa6b02d3164973f82fc0e0f83a2d458af65736d7e0dbb264fd779ffd5a3f066584494598526cd67e12d6c67965a70ec3f09e2cc447f177ec87604b531486683025e3b520a26e69c958cf8435f7c6ce564f0a72d1fc47205a50b39d516b14a476f6c2dcace50339cae20cd3421a75f6d377b8b":"72bd0808076af461353d98cb0191ec76a7c04fbe3a7f793e390cc773434c1d4f":"763e89fc8b2a090b75812aefa55de7b7cd61ec3fdf8730ce16b05a7b9456fd2d":"4a97086b6717a73a6be6d4a95b8343bd20b0d7b51c3da1d86c5852350871379b" +Nist_Vector_155 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"616de9dd23ebede428e032db7838108a224f7aca57b1df87f031fe1d86083d688c5c3ef078e64d8d5a9e612d3983460ca1f816f787c03ca43a1fd8ce138655df677056364c0eab8e0493c07bd4b2b05022190932de794f195dbef297093e7da1c4304db40b63ca53e1b8bcdad913d7a902af025c367c48de387f1a9bcd7ca42e":"4d0240a34dd45aacaab9e24e4838223ccb759f1d93fa8791f28fc7c2e8318820":"584eaeed2dc785d8e2b8c85fd0e5ec251f134958bd9eeae4f79f862b62cf602ab10d22eca499042f2c875f2708ba0d697af39f23f5e0b7de4ff7964bab1279efa2aa797a2d21e788d249f42693cdbfd71fdcb1aa93b79bac0dbcb587bbff4ef15a3799a5fca8b1589838e30096069ca7931f7408815b585d140a747de43bd92cac3f9a9b1862fd704673e1e58710c16ddbe7e52d31a7df15974958b1288116ed98ff247f5028cec86d9eb97b126a48adc952e90dc52f2bd7810355aa9075051f26129c2d2fb0ba8066e414989d92e29e689960e33ee56ca62d714a42cb7487f70c0c0ba643fa9dd5f85259fdecd49fa970c8322682b114f2647837637abc0ed2":"325e19d8b7ee8c8d9cb7e70bb5417035a8183bdf73149a45f0e83f3af68decc0":"748f466b7fdcdfa77017c865a33b1dad4db99dbd63efa1c87345c4833b0632ac":"0bf9938e7972ebb00fb0a3c0c2476d2509db23afcaecb17dc571905317eb8ca7" +Nist_Vector_156 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"115f0a8be34e84d09bdcca69d19ce17dd67df739aa4fc6e8077076535f39af8302881471a5fb0e1839a3aa76dfda4bde2f9fa25fa582b756a4966d75320ac1995472271666156ea86c19a239895e5578a3c39b0ba3258827a01df1f30db22ddbc267c9e290d5d457d0a94d8aa73f8e79f3acd31bdeee7aa32c792c22acb807ba":"0800394a2ccdd1f55800565374d46be9bbc1190b55eee26502bf5f2459ac5cc0":"2e06073f59196d3e29ba718e84489b6f447fd6f67a9ee6357c5e8a58fa3c4fb6ac8314ebdc3b4d6127f2b4d2112c27799f0c1ac5f7946b5607212d796741cc3be127212a125edc3a7a91a525cd62152199b18b4f1dc332215d65d64ad06098ff2180ab47bb5728720c937e1207649ed19c883331ea415faa51c556d12649665f1ece880d055a2a793adc74b38f15f50aa9b46786d907017b1d6235c43b37c2036a1640f6bfe3bec2b95b4300a3bd78f471f6aa56e5e6347571996f778670ad94efaf20991c555924fd55cd518df0bd558faac3f9826a865a3ced0f59cbea45c65412bddf8f2a8aab3dfca1dff50374163fa899cc7f7f108b194fc955cabe9ca4":"617d00444047d8e943e429947d28b4718a8b7603475e5453cacb80fa704f90f1":"5c8d76440735055c1b36698da73903b332d64ca5603046144fb7668b1acac337":"11c54efbd492a7147a1c50b287377b52d2193907d5bb636159c15318a480ca6a" +Nist_Vector_157 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"3c1f2b92db1b4315837baa863043a9b4496a78143ca74f6e67181facf50a6e08d27945d00e7b06f9c57c0e2f1527c94bcecea6993175d0f09bab4f15af55ab7aa9b16b48c94a6a99c2d7e477b744cd27cdb9b0bbf810756bc6376fa15bfbea3c9376ca6979752fdb3a655affd6c0186d1a34355daea8cc75acf96b8847dbdb8d":"59edd0348ca6a85c408816549e9c58338ef92f56edd8fa753226acc0e181751c":"a4742d3c7e7681b01cd6aae17423cc780491d08df73b4a71edf7bd2ee29c698cd66dba0491688fc7eefb4d709147bfd4c8c4b797ab9197573b5d36599c4a592c466955e80ae5d2122bcaa5d0e1d94b4ed2a99b1af5d08eec86c37753a3c3656c0fef0d2c471e4ffa0fb163174a4df1707879fe083655291127a3bbb0597e23802e424efe4016360364506c8ab4081f0a95692c2629537f05306181db669bcfaf01c15395614238a2309429199555142639b3443ef85af74b5e88b7c70a8167334f27294a8ba1266695a369372badcba7623aa58cbcf25b4bbe663d4eced1a18e7753391d6c53854c4a8d0ee1a790a1a21071f1386c235ac26182d01a1e81ecf8":"0a96189b8740005f215ae5c5a8aa8686dbb4c353d2c55deb3904bccc4f9a9b9b":"31c1c6aee7ed541a281f37632b27ba88536f36bcd92fcc360da041f4197f7f95":"45e1019b2a1702b5df1eef4fb7df6a53aaa66ecb8be5cd2e28b353c870e01f41" +Nist_Vector_158 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"ad389f53235deb068f7097780330746493607fdb7e1170bd1fe0da012714b8f1b128c69a53d7dd2646b09720883e2387dd15d46564adff6642372c838287bafa5f4343a27ec8069770e5c367548833fddcc5f8617aaf41289d96dd40f1098ded9fbb110aeb14d69272dfb2dd7d75e7a88dc4147f27c64eb1bf0aa0569bbda320":"19ff4eec2e47301d0b70a826dad822b609c997bc1b3a9d7cbd3d1d2252e8acda":"bf4aa2d867b433f934d1d567010dbe067905f4e35d7ce568b55aba694d12dfba95c235078461aaab81f1e4df32319e5759c5263ebfbebf7960c57aed79bf2de38948f8ff79ef26d66a7f98384117dce1f386aecc4369afb2e0de77ccd2e7dec328614243effac607c8d5fc5c7c0b1143963573d9f106fcecf2e15c67a3bff6908b286d0e4131fb81622fff9e10f5771afede2276e8344d9ae2f493fb4856d1ba5760ddae38af7ddca409e7907268691baa33dfcbfd69e9aa9faa79cf303ac8b1fa07c1d40d1cea01e8ba0d65265f4c6aabb16ebe2f6ef5aaac25c0c2730cbeedc177667ee02bf4523418a986d5b87a9b75ec201af0f1961cd51b85879147e607":"7ff51bb8946842c7e2f7245e73461e2b0820528548f7ecb53bcadc7a20e826b7":"2f9484aaeda9dcb88d2d3644db2c58eefe2e7695a6c8be9abe97173efc9c0bc3":"0166a7bf4e8bda6b86396943a74a8ebfc603a85ed287bf3f5a30dd0bbe49cd8b" +Nist_Vector_159 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"12f9582e3a1a76f299d72d9b1502b99060802660226bc47b71e54ec9388eac325902acbe2bd7109e19f377c9d2b4d280cdfaa48888b9cf4ed06ccf5ad866d6932d402592f6be6e6876db5a62beeaf373b60238ab96829243759bdb586f45ec4ae2cb22248ab0b6aa7a7583a61dd3b8f119cd840479a4a9af8a439db904ac14ec":"7142b195eb2417bc234cf32c6fd7cae470cb48c74dbdb469a264c1988eb3e52d":"72d8100692e1a30a32e37c909eb6c7baea7258b0b78668e75915070037479b884fa9f18066df89b490f9a2696a8505036977604dad268e90552835fdca3339b32360c94358ffcd0b1ea11066122efd017cd6fe1ecd0dd6678081b84cb6e144471dae7636b4a0929ca71aa47b4086665d66d4034c188d64d38b69f0ca171c85925cad2840277d2887a7f7b81e6b12870cc3c69e18ca9c22c3d3a39ee286ca65d23f3e8111aa7c6ea9a0d14c84ddf76abd44db3b9833d69cb99b524c98fdb9d0ff20c9d268e8e7175f13c11c5795d0fe0b3899b74c0dca91476febcb509f7fd507023988145242dfc809ce95c6f1b31f67e01650dd45878efc7ea89cf6e3171e43":"1043805a13045a36e1b6498db97d163571c61cc4a719e506173b5e6df33fc81d":"38cf6b8cbae82e6295f83316a9c49d2dc7c92cb90b19a2c2d45649949354d930":"356a5850d07aec6e9d4a4d7f79d9b0352b087d7ef48394128c5ae4993e8259b8" +Nist_Vector_160 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"b6ac84c49f6bd601d5868ba06d49b8cba87a9d6e7905247541fd332c2b0374cf57d4a0dc0b5a6c3f8f7e24be3a1eedc4a8c575847c02e4edd4745040685670058996250f73e298a43b391a4ad567f0c9bc4b6abf6d1e5c56b22f4eab36aa1a812a1dae8d2873cb2c2a521d320019c7cab1efb11fa4595c534ce527d43ba605f7":"1332c3c6e2d1b7b16f501b6d48c7b866628f0c82bf33354535df99a843dd68ce":"06dab48a076e8cec27d4c4fb98e7c00f36bed73f11e491d913864cae0fdf883468d735deee5251dd38a1f8b1d2bc19d37f3187a4ef69c33dc9528801a23a98d96fd3f129b8ca2941421ba1828e0c4f8d88c53193930292a0df1147b07c20aa726c7177ef660ddd4ecdd73315d4b9356013e115f067e843c896c1a54c81ffab1bfe7c785edec32fba652babfdaaa039b0568c6beb7d13fb4e4588140ed626b18749b0f79f669f6e7045738cf50a6d0028ba11fe1845a2dcbd9c1b02336fb30eaaa397418fe17e149829cab13d2c2e6b90e5cc81834e32fca8a173634e01f9a973e029644f0165b3033dfb054dd21d65e0c0e137b48c34d42134c47b972433ccde":"167b97578e52869f49730df464f7e8d786594bb830d72db9af2cc88324ded288":"1d600a745a1dec933868dc535a19ee9f1af8bf09b5abee15dc4f7cbcb95ac8c5":"23b81097d583342ebe4aed364a7af9882f74e64518aaedce346c91d6d7ac470b" +Nist_Vector_161 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"a92e2ddbfd18cd307373fcb39dffc33e0b91a48c62071f2f7a8e50dbf2c290889307975b6acd642c8e3d3444acac98c22ed06551fec5dc7c9f2243b681cc9fa4fcc12c318237e9a5df0a77ac22402039cef31b1e623af58212a22e7e60419bb36b777cf6ce65dd1f56963eb28b7706f137c0f7363a002d827e45badc20233c16":"119ab8a63a22a89baf4eb8f016dcce9423d5f40a677b258fab072a8cb622ebe5":"5141223f4697de272269f3d99437c48dba5ab7f1373fc6bad8161018c5d6fce2bccc40ca78e4d73b6eeb096f175c4cd0c8e9f3e9311951d51ea244fd33d9e47de75f1000248fdc003bc07b501ce58f6ec1aed1754c36826cd91976b408eb7aa9bc42448058ffd3b4e513c6589f8e1bc145a47b2470e7241e2325e54302255c3d6d97abc5c6056266a9523d461fc744146da35c04a4fc0b095881cb94fc4c03bb8623953928490dbe7f84ef68667f23d4cb3ed887449f77aeb158a26d1b39b4e6297f23d49f5b41f170e72f7213ee40364c1c9a63985f69e44eacdfdcb58c35dace8b935d0789a8c0669a23d673929b2a582d6d3b2f9e67be891890da1236c6f0":"77cefd7a6b0fcd0237ff8f51c458e5e8a79116eba6f11ea1af7f29aa608393e5":"34a65e99bf01698b5a68f215b9c292115d17b3c202ea1fda17fcd8a0cd74b636":"7e67d442b8f9ac2974e84ba65aeff0df5f83c271ece792a8dab9c4aee87bfea8" +Nist_Vector_162 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"b5aa1cfe2348d57f0e5333fc70276d2418ddda49122f4a88e8010f6f78dc829ba5c7cc68db664080945c43eeb705c2ef13de6e4b8f4de1d04fb33d5bcd7893d8ca8bfde38c9feca6c4ec03b2ce7b35ed60a6a43f7fc9ed08061a099b3eeeae7f0f1516149d175a953f52c8c518f3ad247c9fba23f1f829d5cae62673ee201ada":"4b75db034ed0b84dfcc60b493a00940e805feb78575fd256b24d146b05a9500c":"0b66ef2c7a34205d70fc36404957043cf46b28ac4f083ebac3787f55e8dd1f75d9193a842759376f0508c94cc7528d6611b50a73261a4a5cff730d9985bb341dfd739a4e963d1c40f114d7a7ace89e81dd70861efef2ba9d1c6425d5f85809059e8ef31f453c97743fcc94d3b1bd62084e975790b37193eb4058454ab283fe2bafaae803de892879554a340b9a3e2532931eb95d3ac5eb3f290a3f56936951288e1c05bda1fa74dc78d631c2e7a56367ec5781019dfee71453ea6bbd90778e92fea8c26bd6a823fbca71577b6335f3bdf40a30836e948db032db5a4603dd31b851ecbbdf76b4a6c9951d2192b97ff01daa5cb030e15ad1d4cff367f700e79ffb":"654aa8be3b7bfc32f9b560b57a88a8aec1cfda276661283b7f44dd3b0944c20f":"517f7df4831fbd01908b9218b17ae1c40e00c53404b3bd72b64f67cee75215f2":"1903434a727c8ef0e80a43dce2834b807839ef43c22afb502b35a381782bb639" +Nist_Vector_163 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"27aa81d2bc49601c3f6bceb0870bb55dd10e7ba6d1f8acada70b5f902a0f4062eb93ae72cdfd3f943099cc2a10a3da7bdc9f24b00bf36a29d75136af10bb71ec9c1932058e22ec9c0600d173d37970d58ae1f66cefd27e2905afdde4223979b4041fd7d7166ea326befd5dd896ef47abc6d045c1ca23c1953a6e12cc3c54b4f6":"7e6b77d4bc9220c3352e91abea67e33a335ace34ec4516646e8a4ff098166ff4":"932b9c0f2d310b6bfee800c074a0969efa246244fb062a745a9a3cfe6f5336a313192e92a2027e1d2c3cfa93aac53dfe05cb8f8321ac882a63bd375af0f3d9ecc73aeebe1267f473a9f90b94f5b6de4357b74eb30cd41aeafc259e85cac7d365ee33382a584eec63719ea325a2414e116f84d2af9654268ec44d6ea2e981581d45d805b383d85c130d2dcd1c71fa68d9c76d79aa8196152c1d9440c33d99de451a359e0d2c51d6aaecb26795406e528f5de3e00947d3dacc695c08a960889a2e94ecf0a461c02afc58b51e00369c73c8140e8b92388caabd1f37a62d1b210e0f314127f46b576a4b8edeb34713aa4136b8a1875bba8a5937066544e34c206aa4":"73c28bca3c8067da792f6312153b298a8f714cad70bb2349803b6dad024f6bc1":"05057a982ab4a2e32238ef2e3edba07fd193d90c5f053c83a9f176e21a9d5208":"03c2b26cf46b7f72691a72d7cbf33653df347f02b0683ebc6cb7ea7e72dc8a0a" +Nist_Vector_164 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"7527533f2d10c18078f5a8dec350cdfad06d3157871e4ff7d7c2b7ab11dff232d34f07699278f075442e1d4ee00cd6e87c1931333841c399576f4e587a251684e731f7c8369f712656bc1e6c2d209f511179da09368d93290e058e0ce9b6530ac6c5e4cf0a1b22d588d98f32b34e85206e09aac04a0e1f2ae2a5cfdac4e6e2b3":"40792e5ab46518c6ffcf5357f0c5de5d9e2de99c92aebea82a307ab0f5ad252b":"72c46505e4b071f46ed6b6d530801664a4fd518e4c6be8468a38c22bf74ed966fdc7bfd7c572218998fc4c144b59462af7e294bdf5797ecea5cb2edf8c8d2dabba88d0b84cf28524369c5040b58f090772dac0fe453c32907e9b6c740fb24ed4dacb8fdd25e0661bc0d79d41f103fbc8f96b3e3a4708a5a7f5dbffc98f344bb7ccf0d5ed07af2c2f0d5f407bcfefb54d9b947604e7a78356874c01b8c1fdd749f6a3d619d1090c83725e725706846c16bf9dfdf39f2180623f4f585402cc7d6e2c10b57c8300543686a386056a931be6336bb6173d9fda8b102cf32989cf0978f956d9ae0d8f30752f156f9f92d2954ef13100a75d9f7ff96fe15df07e7993e3":"0c9fe826a7618108684ba2d74f10ca39168feb85f74d2737fd12d18cf27a2f16":"6aa6c4d7afda30ff2d7178b52a3e437ed5b0745a247c9c9e120bd3e833a1dfac":"26e0887911bb5edb6a566a2a1276353391b1e4ab8ae0b259c1bbb3af3d85b439" +Nist_Vector_165 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"994a49e5e8a5698fdac9a7faac01fb09b2c6113a186677676d11e6049dc98c93c51eb5144af181e1efbf44439a13d295653854813671f032aa62258c14195c4864afae0b5d154f97565cef075bbb6d97e34181410309ffe98b45c1f874326343c36c14f55fa058489dff3b49dc7888f45a099c3c919b25edac1706bb90f164ca":"266cfbe6060134ece2c8b9e6aa25bd6cc935e49c23fdd4fb6adb2ecde63a4960":"05e233ac49c1fda2a0c3c78b0bc72fa39674055d188a124a58ab3850d9a888861c2fe4d046c3e7c75ee254de70cdb1c3150201c2e04733ebcc25b88770fc2aa82f60526bc664047a026c2290fad8e9f81cedddde7fe3ba406535bf2710d79da01bd2d42bb5f4099c3f8bc2ac864be7892aeb6a1f3402c81474da23e0795cd6c21367509a541591ee1e6364f7e755b1419e90af869930152f34de51f0f06ca3076e68c3e3ea7f4f1bf1d3cde3a0dff0cffa1b5842752347082dda3475992f15a74d298524e636220bc9faed08af7aa5e481ba78d2d2fd8e51942cfd084efe0ebddd7500efc95a6cad37fc4923f9bf65297805840876c689ee079b7fa6169768fa":"60f8416735fa49ab567c0bf1b6da434e1df41579699c1a92a3e70e1d90705379":"3cc269bc7b895864a03231318cf39379ae33c7180a18c08b5aef7414fdac058f":"6a6eb83c5fab10e34f0416628c821a6de0ad0c202443c6df032cc9d8e4948ac6" +Nist_Vector_166 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"39f2d8d503aae8cd17854456ecfad49a18900d4375412bc689181ed9c2ccafea98dca689a72dc75e5367d3d3abfc2169700d5891cff70f69d9aca093b061b9f5057f94636bc2783115254344fb12e33b167272e198838a8728e7744ea9a2e8248e34d5906e298302472637b879de91c1a6f9f331a5cf98a5af29132990d27416":"6ba81e6cd4367798aaab8b7af1135183a37c42a766dbd68cd2dce78f2670ef0f":"7bb31e98c7a0437f978a73d5dcfbdfbb09cc2499dfaf1eb5256bccd6358cabb5f67d04a42823463b7e957f2b9213f1fa8e5a98d614484701abb8c7d67641fe6ed06fa4527b493ddab2e74640fde3de70da693f1db2b8e26417040af0eea6cab451a795a52e187d2ee241b93f65c86c6d66f45834cce165ac5eb670d4f0095c23ce9757e3bdc636f991ee0073d90a09202edb35cc3ea1cf9adca1617fa0bffd9c126229a604a1d3bf4931ddf0b9942dfc8a2f8c09fcc97032564a79ae1ebe1e2ce49ff57839e7c43fa60b1603d15a450898aa4e4a1ee8065794126d64f013367096a83686b9f158c33b10f5f3b36cf1f6358b3f34f84b101dc26d3db68bcc95c8":"45030b79a395b1632700cbaffead97998d02bed8e0656876fc0174e4bdb96f79":"059bee9e708b7f20c3f791a640edee964e0aa672893c484799715817b3a8f6d4":"4bd41c84a724cc86e4f0194ec0fbf379e654d0d7f6a1f08bd468139422a5c353" +Nist_Vector_167 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"0577ee4a9b8dbe3c6fb9725174e89940b27e8a989217b64417e66f396a35e5824f21e58236b27910a3be6b57d311aa778bef63dd025d9435301aefc92223c1aabb03d3d5d385b1a3d1f937f0f1f7f8baba91a011207480b5c23a78ebaea69ae8ad4373b2b052d60c5461111479591f8330123bf74370fba66bc7e2b400192c47":"7bd811cf6056c1a821a85a3169113639d775247bc6578c9eeb28d4b09503ac0b":"c54a57b08f255db1c776bb2126ea3c1e60229f1e1981e43f1d6b9110f950edd8245eeca7d55ba06468040855b736db502f01d6b3cb2d9d621c4db44cf8cb390ab2ae332bca219e09bbbbc225541d4a0ec0b4f11a591c077f2382f04bd93b364c94fb1c6147ff7784e82558e5fb68427459fa9a69d78a9f6051bd9431887ace46fa4970f0e22d75d2befa5a228e489e009af97ce9211408b4e5bfe37d3e0700b258b54174a5125eb6bbeca38805da53b1f5829dfdec8c4c9376bf235b7b0eb7119d3d69768b80ee02234589b8d95faf8062a8e1e9c3a686b6350e30fa535eaae71d753b7c3b048f8e9722254dedbc220ac9c9af0784532032ab65e48ccfcfd623":"7ce602ece3f821390641dec7ae01b44df0fc822de1c013496bade2e3e44fff0b":"33c198ea68bec4a7fedaf0309c317d336b97d1eb1f1dc44ebaf5c85c5a3afa98":"5c9b23c13bb607be5473b32ae2b5e8f2a1e18f59df8ca7fd9303f76ed8e680e3" +Nist_Vector_168 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"c643695d29b28210017aa5a7d16ebed81ba00a869d6681d1c0fe90a5e8be9d597329ea15d24ba12d77e4c3f2160bcbe808840c6e77b0528bf9ae588738e22f41910a80a7c6e3340c127b9de17945e7f9229953e2850217b6d486f7cc804e720de214cef02df4a892f7e42898f15caad26bb30bfaf4b0551aeea14035cb756b11":"3ff2653cbc1f27253400a9b6b1f064247053c9816cfdcb704b14bdece2a8558b":"17ff2a5eff3926ee1520d5a63a13b4f701dceed25a653966f525450b3a63b03229d615ec54cf4f6ddb868b54df363feecc95eb8a3ab2587fc4de9c93dc8f8d7f38f99082d2867b23d073584c831baa0961651e071b43f9d5da97b60e7b5b7a935f6c1dc88279608e2bec5cac6162488085d092a97c6b6f24536589b801b6b48d478796b52c05564e904bc58ac1505074db3734fcf3575f79952ba0a2a0697e55e579d508a400ebfb2d4694b720804a9d00f8845ef0a8e690e675b4c1ce07996d64e666b0d6a1d6fc6bbc3cd9b5cc3864e5e888e3c335e05e83c67c0033ba5efc3dcdec0446d3b40793236ca074c54d2a74dad296d7c639dec938e3bf1ca085dc":"356b49268eb799dc4db7781a06be0f8b96d28f6a13b7523c0ecbe70cb3eea1aa":"4ddd2a1f411b570fef6d9184409b4fd55d12c5e4bddc2ac7211235873322155d":"4043952c108ef84a25a168ea5b64a4386f7a483366054c5dfbfc5fa98579432a" +Nist_Vector_169 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"2f64d11e290275987b7d7430242289afd54f1be028cf36f8f55db54be70b8dd5ad74ae26e079d0ed31a361c116951bde94d686abf15ac5ed1470c3e902461cea8e5d58f407d2e0c072ee61567da7b353f6c47e694cd607f3ae894a9705e8ea2bf9ceec3acfa6d20b238bf0a7a7eac76c4462b7e4e4e868174a88a6a6c9476cdf":"4800e9ecd9bef5a4d46aca60aca96955d8565e1b85d84dd8141d4f597e178bff":"41cdb2c1bdfa3652ee49695d5e5eeec00f64b54b5676ee27f043b43f24133f61425b0cebaa1f88da072cc68865c12790c43285b7e19c3844fc7d81d064423ff1e19266f69f7dcb3d0203739f84d73bf00c52d60b2875171216678d59fb557553edc9eba6b84127169fe5dd2f81fc902c970d1d8d9c4779dfa1b14309f81006ee641776a6fa36339e963117447aceb823c9ca3367172eddaf6e361829dae43c4038cdb90ebb68b53c0a22d410b6f1bfa7c47496ea3aeddc36bf24f219b85917a24d30847c77d87d22a7f7486c6684755e045ddf72d41650e97b64a64becadfc47d53555127f8b7ab78d480529571996eede4618882d838bd695efc87e74d68ca5":"460410eaeb111a18cf894468e10a88b8de8ef9dfd9a2ea1882a9fb696fd7823d":"4fe6e2a75d9c72e81ac60dd33d31180df829b31a0dbd5fd20b7e28c4fee27d5b":"3ce4a06bfaf70cb6cc93f33f95a43ad77ed7ad7c77a1674bf849e9ebbc5eda29" +Nist_Vector_170 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"173c4a23621c32c3e4b157ef96b02fc1bb466a2537d3f6e51a58e510c4aef3aae4bce4c0b4d59bb1c00e7a35f98945ca9d7fdf1f0bac732d425043062bc6d32015233dfb295ae08a324ac7c1e02a117ce436d77d4e46d0b794af04b1db82a2709da1c4449c29ccba93db8ec48eb17921cb389f6e0ae32995d7fee1fa07177a7a":"3e696f226f21916455f8ccc861b1845303867b75303ed92f9ac79088f56ea708":"673e349cf6d05caa16751d97ba6e344e40e158e6a7fc53ea2db87891341e6499825b5b9edbce9190bd87c3eadf7c6d5bf0a793af2c3a1c8ded790bc319449394c64384305864723a8a7bfef26c082030ab360bf9abb11117e61b00549726d772221f6f67c4a6a110cd9a9658781ea8f7ef2f176c6e8816a865af396db95d8415b541cf0f83e45a417374cf3acf5c6b4a98390522e7140cc8aa3f9d2dd26341d4eb79e4d931a178e3d57dc52bfdf90115e01b76094ad0294979d35d92b574ce7b0c627f08be66f99effadc33aed0f634f6a89507455d7341ee64183aa610d8bb3237147bd90dcd9c1a03d89b26ee31dbef5ae7e764ba9f77b6a7434ad2a8f966c":"2837f7fa85efafb433093231983ccef5d82080e6063f67c68ff93465b59d581e":"393d681c3edba28f7cb0f30593b94fc15cca659a80cfbcb3b236453722d5b402":"44f7421bce1e5273a30ec016bb9969b757197987548e434e395ab3de1b0e7ba2" +Nist_Vector_171 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"7d6f2a97e1eb085cb9e83aa24047af9ba30a05d7bab564a149b9cd2366518e8f199134fc2ca403947f2a614c0363ed4bc1349dc496a8ec74d880578475e47427628bb023f0272208876a3a7333307a596c158eba64ce42a3c790e7167ba4a327ac71aabad2f36341edea12ce5b2b735807b34b714a49a0aa476893578f0645db":"660898413f7a71804432ecfa11cc68f85a34fdf75012c965259ea6ca0bbcd976":"777c251067c8ab16cce2c4a4d784c7e806fd296cbbbab0132e2ab91623acecd830e7cc7cde03e544b51fb1d8f0b2eec09f559539aa9d63ebc0c1e32579f095473d12717ce88f6671ec7e3d2581f61bfde66cf9be216d6a208086cd7bea770150a9bb0a5a7a0dace82b464180241202a30b26ad5fb933c8235ac2918e29bc53a5c01ebc1e30b1b46e37124aec596f8d1a73baeae588ce7d4aef1ae84e9a9766c24367321c047c3caba629f5d9185f0ffb3af7e50eebd1ba0eb77eb121b98073794cbc6622b678262ed3e229c6ceeb607274ce3496f370b482bf8f68c27366818486b72adfc810b2f579779adc9c25002e277641dd9ffbc5db5239f677ba1a9c1d":"4abaf5c6f8e28356fd0dc6f096e9354baac1c2049170b2db05c81bacf02092f2":"463b1fd6ef2986f75f9620779bb6f47e0beafa9340e3e5ee589d92428acd4f2c":"27edd33917e49bf771f3fa1355cd3928d0bd401aa7bf0541f3af1643efd7b677" +Nist_Vector_172 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"7f8785e1c4f82bc0bb75f78d8c4113e0887e761a86b48dfa43a3683b2bb886ba53f5603c8d94a052af3671c5c1e7c232908e10faa6cd54efc79ccfd64811131acd7d60a9309729455aa70443ae8f32a34580f9a1aa7d89e5fa8cd4e95809a573ec6dfe9fe35b1130571982a0dd46eeebb6a16f85ee6314931839e3a4c29dc700":"4be0926fe24da1667d71d2abc2bc0bf87172c05d7c363a324ec61b4642777e57":"28c06e5ab3c860be8c13f74f28b5792b39487b79547f4afaf6f77a5c3a43e88132edf944ee00150a78b58a78cf92ed941578ec679e106767014e5b279c0eae9c408e6ed60687ee1464988ea545f55be3673ecda10c63fb0b1908e796d6715abd5451843da6e63bf8802ccada32c7c5342374ab26ee701f9db3d34fc96de9d23021b98a93df6877f84fad6741164055696f3b72050343ea3e5cca01a3d57e29727ebcf8583118146c27f42adaf62365b9697cf03bddc69d0bd151f715b23bfaaa27a368114b3dfb54c084e06d4343ffde1cd22058e9623a70e9942e090edc73db06dd3180bb960f0d7fed005b149b69d6d45f40368fc25ae04321eda46d52a592":"057cca710c8e4998e9fe154cc57847bf35a512e6caf3cd338372b5becc66e8e1":"3165b1cf3ca9bb89154ad684e089364f91b6e5d594526072f7b9db3b2358e711":"49e1c8c34724ac5532fff1c7d243b486a2cdc0872ab84fda6cf2ba96f958f46a" +Nist_Vector_173 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"3e17ea8b9feb2f4e55c103e58c4ead96b5cb892d0982ab2b0cb1eeb9e1ddde9990233a22588473421aadf52767a8df524bc6e6ed857a9fd5942ef976b1fd8bcad31e403b1febb865d2872a7b34ecdbab8b245ada45243a49c7be67aa09788029779d619de30dead9f7d8c9c42153b865b1a9e81180380e27a305a6392f4b2a0b":"75c9b6c63c80755f7a7bf38eabc58e1bc2e0cc5cb4f2274f2d63058157656608":"b71d0ab2d405a5012d694e0a4a82769256cbdb49c18112efee8153c8e816310486a17bce19748b11f3d5d18cb44998eb329b951c23a57cac47ec9973839b130f3a980e62705c0702e4d68425845d54e152e2e83646b56a6757cde06f85ba3779eea585dfe8302f12ae77fa58cbc6dcca70b461024b7d176510a393ec027c769cfe49b698e575fcf99c60293af2ade3dc4df23ff3386f13777306c52de97ed1a886b824788863ff7263bbbb5b5fa0d4681c16942272f5e441bdf49eec7556c1fd409c78e3aaffeb95c1267dee12c24c045ef67aa70e9a3d9244f2cf1ac68cd918df5f62a3dd3de7bcdeaa3f61de51cc01af636bd665c0099d13938eb4fc289b42":"568b8f5049c2c411f05d74e1781be5718ff921026728d285f2a77025208dbd41":"11b7ecfeb339d6014948de5ad4c96f4ba517a2cddca611c8887fc44f14ac9a63":"13287a22cffd825302b0fdc0955458d918727092c7bfb3ec4c3d7a838ea6c491" +Nist_Vector_174 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"c3e1903ceccb2af5b0dc6b1fbaaf1b2e96477e001c43eee3046eed06128c4c81eb2bc917aa8ac30d07e66c9a9469518e3cabc264d6936e5d724a613bf9a44d60797b890cc5ce0d04629e5faa1dd53e7a125a14a26df3cdd9878d9c67e7e18a4655a188885363ddabd73a17659d191e51fafb6d4171ff6c4b651168ce167ada01":"5feba370a58c16f34e931b65c042e6bfe794309cf30105d2fdac4d9fb3e14303":"429e6ba20b02cd69a29b4a97a6ea564e5b8874ada195a49c3a5293c9bc8d19e0a3a3c4ac8547bfdc7a209bf3a6037e5b0bb7aa291d5940d235c787a2af79a9cd7f83084ba7df85c036ad8ea23c4fdbf91d285c7caa6497af388017bd581ff308d9b56799029e21400c0c99d103a2caec195e40c90d244dac897bd418ae016d25f71e989af516d5e2491e1e4bc25914ec3ad0a9f85968a6777fbebdc73b1ac6814496d9421d2b7cdf17d53f00624010ed6618f1258da194f77c28286225d1b16da3fab76c9b70db1f7dbcbacf4e60b6b91a1f475007ee4d2c5e37fc31e89a0fa808f89e8a4e546bc90e696f454721be71c0731f99ee368afc6998761af9dd9d6d":"7ba86d55b8b5a465f661944832862baf5f565ff0d9195986c809956db2872da9":"77470f0d3923ff407e71a86f0336811bdd63e179891fd30e3452dac1e5175081":"4b969f77c70b5e6ff9350ca25e7d951acaaee907fa7b830a32dce4f91a89afa4" +Nist_Vector_175 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"4b7c0828b715ec2da1e092204f55ddd65d13f1cdd64c109478d3847487bc48a8cb0299222a7495efffa63ea158253faedcb5314881ab41b5e773337662cc2f50dbccc736974e31b3d080467589951d511032e4cba6647f94c679aa269fca6db92715a4da28ff9803a1dc61675fa5ac114e376fa4dadb37c1b09ed5c31bc5aee8":"1ba85c9c8f4f4ae97013bc9f7fab372e733f3445fd9a68f8e015c375df3b5515":"09a16e0a6003f45aaaa3c6311aa9866217d4a7c8cb5093514976f6a341260e5aba7cb00ab2adb7462a47a8cfee4fdcae5accda6d42a3144792a14631bbe85534c111d2ffcdbc15b6db9dbfc4bc71d300324fd310c465443cb2a6f2ae33701f39668b118c38ef562e8554fea661a3ef80455699c23430d28ba6dcf042fc920a677c2971b2df8c6729c5b3b1be6c5a047ac1bcc8cd8dc519ada221bd92ca6893c1cc1dc158f9d472f89a8e02649440dded0f723485558effe8cf9df121c969a2d1b76a37dcbffb17edf3121d4338d4ab68b154226c0072d8bd51f23e5659a2afe520dd5e91005a6fc1157f07973610c5577824bf1666ccf851d69efde347f0b996":"11d09ab8f3140f98dd4076d398a9aafb9c98656dd7185567a562cd108932eb77":"1b8b8d67b640afda26fbe67cfd4bea521375526ad58a22d4d97d7af134384f4a":"66d6c240992256eebe078265c3029a88c34095142134dfc31ff0a2d8bbd609b5" +Nist_Vector_176 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"baea89dcc102cd649135d63a5f52df437af7840d699a9daf131eaac381348d45b4e60477fea88803fca31b54829c5806c703eb8fdf412306ff7a79b55aab9064bc37cb26bffaa671debb74c228ba2d2a06da362f613b78e5b1f0a0b5c5febf6bc326b021bd7fc70471b25e153ea51de1010b87110e01497a7f1ac39cf4d424c3":"2c0a2b700ea43f5fd589e665817339b60f837ca0b7dbab50d2ca7e4c362a14e6":"cbd465ce9c3d0a137ee3d582a5172183b8a63cfe414070b247da367456203f986e6786ffb83ad764aba309c2ef7442ce38735f492c0ce6d92eaf9ae6b1cc873ab6ff58317cd166a510c3ffd8d4e6008825b58cae217fa35c94c9bbd12a4d638c20116398b21b5929dca1d49a7b748970e45de0d432fc912f76199137f1bb0c0d2c95bdcba0d303ecdbf489849be8e630ffff0603948c87a7e58131655c9f407708e8a9d675e28e9b57729f0346c0287f43ed67f9c0c0ce1542984851cc3b521afa5b9b8fa53680bdb2d73c2b6b090ef085a7e7c6f76a2e501064c852591df60439a96dd8d663b564c9e5c253ee8d8ee58ab27d8332113bdd51d8b41ac73c143a":"05c7a20e6e4ddb833c4e30a564436fd66716f349af551e9943bac61572e04107":"7689b5249f1943e685095106d3f68359cdb76be5d9a50ebfdf36e731575f8bda":"049da42de51e617cdcdef17cdf6059345b8e181bac64c47123d47b5efe105ebb" +Nist_Vector_177 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"b1303768be174d83578407dde1ab91cf021124a34c4a35eafa4512707a3660d1f884fa6c3d7df299598018dca22f273f602bab371592b11f4574885741ab3fe2af5b71237d0057ae59f37b61dfd1ad5ea27cf8f05f5b69f2936ec79d104f4a46c902fb6790dfdc75b9768cc7dfbae011c795e646f9a234728707fb112c461007":"247fccb44c2c0cb1f1e58d1033eabd203d8d874d0bf18ba70f04b75bd6495bad":"5602dd579fbe37f187d49d76fd5936fcdef2369f7af29da43c6456a6ac8317b39e4cd679143a4d97751b80ce1cb45186da7bee991e25eb9a1aed1490fd74f6ab507940821a1adfbc30e19a933cc4d21769ccdfc57c96f0d21944f8a0f131626ed013b3e5c01313a1756b67b7d2a21edac486cbc3cd1d2b6fcf20c82dd70b4f72929c1499ad796de894db8af103d9b91c25737073d9df62e6b624b90fb352db781c7f2ff8d3a20a7063fb51272395cc7d35ef79c27b7634e39f74eb152975fdf3b903c23990eede8aa58df9a29954333a3f525d5baafd379dd57fe396a51876f25d9e8265cf6971edc6278ce996bdee206883448af184fae23af2a69572b20090":"0b94ed40c05a4ef445309afb5583cba8d411ff4092452c0a064dbbe6e3ccd1a5":"1800b6bd5c94a031d977b9d017541790a9fe7e414c90fa4d3803d56ef16a6479":"07ece1b64711c9b3eca489e75f2e63438e097498e2890dd0273729a55df0d2df" +Nist_Vector_178 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"25ca3dc8e6ea4ebb936fa01b1ccc08bb1de923be6292421ff9f773af9cc7393510df2fcb6ec188b27c2688c72fdc2ff6c90f0ab0ed59c9c3a6503f53e32778b954eae582c95803c511ff3918adda02e68e2c3e73f8a6ad607a89d8eba0059eb87f4d9b0081f296961ec6ea78853aa53d24a470a74acf16a2f86748a8da34fb90":"32b6f7ce3ce99770b888c1ef23a86377f3e00adf5dab2e380ef8c4298d20a1ee":"bf2e140f8b8d99d2df1052e981fa0ac533c0d4ea9f266f9267cde7ba03cf10015da1cc13612dcfc92030b7c7d1c057e28a6fb45748eeb9c4bd2e6e79b217f4b68ef03f9659c8e84a20ee920d29711381ce39fe0afc9a7fe2fbdfce63249651230f3e72eed579f0d3659c2bffc70fb5d8be889a34bb67f1a904c318568394b946fd40383782cb5e4809d0c6019d20afad09f29fbbc994d28f4e41daf4666298f351898d8def404712c409745a88962e4a618c234976645559c90c54fe764eea46fa03543e4c4f25c8d2c3c1979f952458177dc6963e3f346a7fddbe0cdf23ddc7d2fa8a3455cd5b546e47169912ce7f333ac6f01e64aec596080b5d3e0f25adb9":"73418db52c6594dd0956d9e3616a205de8204220648addd4bfd3a9fee412462a":"7b1dfcf39b624d64db08a3974c8e14173105010f2bd5135e926f2884e30b46fa":"697eeab669677469f62cca46d3e68c849f447881e2c9f74294f4e8ada4426c7d" +Nist_Vector_179 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"d58a8f5ab44f9df9ed936a1318657c324fb1399c251054986d19214c15ce951f87ccb3510aed9085411d9c5a6740df5160f3e57ea8c942d33547317c7a387c60c7ac2f0e14171f0b7719aba76ac418d157a4e3bec6b799b5da10bd3ecddae0857a29670c99d37810349b82b7bb37c0937b0dd2734da08b8b1cb7beecd43cb615":"23a1290f8acbadc352a282015713d6cf5a88e8901cb9588a57151772619f5ae6":"baa13652642d950d8bcec16c624a07999fb557fb40a266297c15659755fd615cc7e2125d4e8c8af8c43335539005e9e2f2d40428e7c8cc055ff3f6fe3b3df604ac128d995cfb9c867e2a9607aa3b77cf0f691738b784d4be2fea4739fda1f0674260f21f666acef5bd56a7800bbe950792ba05eee42e80a2578d2c50ec28d44afb6b687652bb9452408fcaf257c4b5cd564ddc4e63ce9ca13d4c7473f51b01ac8e4c3f799afc908eaeaccad062b0f97d958a3008cae22062bb166c7300df0b4386baecd599fa8b083fba6e7e4e5ba119860268517d79ebdcbe02437bf4eb5d91a843725db0eda66eedd46d66b781aced0dcc23154e4b8a8f0453b2f466033bd9":"25f8923843d757ee4b7571b42de58925b0c2678ec89df07248b4cf34d83db926":"1876b20926d8ede78d28174eeb4cb0c1af8ee206fc8db4a8cdebb5dbfb0c15cf":"231af07aeba99ffd00659394ab6ed19a5e9f9e60e2197f65fc88c815beae7fe0" +Nist_Vector_180 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"aa134e9db73982e7a37a1034aab82b50d5e58e034a5637081dc880a6e265ebc7b353df210304ba00771c5bab445dc6c24999fe8eafdefabcdd46f7a91f30721a6896333c3f301e197f961944f545e4fe0730cd967790504c49b0ab5b890809be5c7c1c3f8a2e52d92a2c199b981b648fdd528e768e6ab392579b54c72c41617d":"02ef078e61df318237c9a217b5ddbda12ab9ffde68a201971782b61b73214cae":"691dfea144e51b9e0ff7536557b58ace8716263a70554e2f4676d172332aedaa67736d72667d328170aca070e1bb89868bf4cc98962d87eb0599f10828c6ea24cffede8ed7b39abba666bd6d0d35024ade6aaa06fe6ae45dc4b3a91c219d472db0efed469d69cb5f11d40158ea81672b1ae116ff2c3016f245254e984a59945e4e3b3d37ad12058d84082955c768643e7d80c055c1703a883f2abb075a24c2e93056697340931c25894d1d2ffac4b1022012c15cb707fb359683ad0408b668779e9d9ba21989baa6a6b0b256a34efb4751bcaf4285b15635d409fda993c0438acddc9da006c390360304ab12da76b444d64e11ccf05d963ffb7f389bee831dc7":"013e35ddd416e092335f3bb24a5e826e3e06cb90daad599a42cb5ae8da830b24":"041d229349cec75fb2bd8c35c249f9196a18962ca75ebdb42dca61d21cb0e910":"77bb7975a544c51bf249dee2359523072863934497d1a479d6e4b245d456eb2a" +Nist_Vector_181 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"4e3a28bcf90d1d2e75f075d9fbe55b36c5529b17bc3a9ccaba6935c9e20548255b3dfae0f91db030c12f2c344b3a29c4151c5b209f5e319fdf1c23b190f64f1fe5b330cb7c8fa952f9d90f13aff1cb11d63181da9efc6f7e15bfed4862d1a62c7dcf3ba8bf1ff304b102b1ec3f1497dddf09712cf323f5610a9d10c3d9132659":"446969025446247f84fdea74d02d7dd13672b2deb7c085be11111441955a377b":"5a55dceddd1134ee5f11ed85deb4d634a3643f5f36dc3a70689256469a0b651ad22880f14ab85719434f9c0e407e60ea420e2a0cd29422c4899c416359dbb1e592456f2b3cce233259c117542fd05f31ea25b015d9121c890b90e0bad033be1368d229985aac7226d1c8c2eab325ef3b2cd59d3b9f7de7dbc94af1a9339eb430ca36c26c46ecfa6c5481711496f624e188ad7540ef5df26f8efacb820bd17a1f618acb50c9bc197d4cb7ccac45d824a3bf795c234b556b06aeb929173453252084003f69fe98045fe74002ba658f93475622f76791d9b2623d1b5fff2cc16844746efd2d30a6a8134bfc4c8cc80a46107901fb973c28fc553130f3286c1489da":"117a529e3fdfc79843a5a4c07539036b865214e014b4928c2a31f47bf62a4fdb":"633055e055f237c38999d81c397848c38cce80a55b649d9e7905c298e2a51447":"2bbf68317660ec1e4b154915027b0bc00ee19cfc0bf75d01930504f2ce10a8b0" +Nist_Vector_182 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"a733b3f588d5ac9b9d4fe2f804df8c256403a9f8eef6f191fc48e1267fb5b4d546ba11e77b667844e489bf0d5f72990aeb061d01ccd7949a23def74a803b7d92d51abfadeb4885ffd8ffd58ab87548a15c087a39b8993b2fa64c9d31a594eeb7512da16955834336a234435c5a9d0dd9b15a94e116154dea63fdc8dd7a512181":"853f75ac81b3a842c999448562c584d1cd0277896ec2f93c05c337eed414367a":"356ed47537fbf02cb30a8cee0537f300dff1d0c467399ce70b87a8758d5ec9dd256246fccaeb9dfe109f2a984f2ddaa87aad54ce0d31f907e504521baf4207d7073b0a4a9fc67d8ddda99f87aed6e0367cec27f9c608af743bf1ee6e11d55a182d43b024ace534029b866f6422828bb81a39aae9601ee81c7f81dd358e69f4e2edfa4654d8a65bc64311dc86aac4abc1fc7a3f65159661a0d8e288eb8d665cb0adf5ac3d6ba8e9453facf7542393ae24fd50451d3828086558f7ec528e284935a53f67a1aa8e25d8ad5c4ad55d83aef883a4d9eeb6297e6a53f65049ba9e2c6b7953a760bc1dc46f78ceaaa2c02f5375dd82e708744aa40b15799eb81d7e5b1a":"d41b335753e1ff3f828f57b797ff5b2db5cd79f6a1abeaa137a2a830e24ed4b5":"bcd490568c0a89ba311bef88ea4f4b03d273e793722722327095a378dd6f3522":"74498fc43091fcdd2d1ef0775f8286945a01cd72b805256b0451f9cbd943cf82" +Nist_Vector_183 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"ac30fb155104954b9d7139de9346d54ca05178954053fd361c9719cea530d2d2e1737fc46b0ee27357cecbd47e0fd47ada0d5236a9d77dd61a1b0db52e628b14588fdba8774882866b04b49cf5205db49445a8a202a5fc3fcc36efe0bd0c1e51eb08616c4a7afe120077ea08caf167e90446862298011ad9a1f11cefb5f74335":"d692d2c653bfcab2e7492ec56e512724c912227d793a59882800d37ad260bfd9":"84741bef3d9f9dab0e3fae7839d39c1a1966ab82798d71aa46b7def465e39ea5e7adaeed2dfc92c9bea72d65268b8df955f9b7e7b6923d2bf00e7e43f83a0e54ca944275dc39c0fb0c8a00ccd0b29b790d9d8f3496054390410b4ae5c6eaf2e21bdb52421179970fa13e0948280a06a576cdffae6fdb239ebd486bf4699270e2bc0879be25a6a0c2f7280ea33eeb32c5d2ea6093381fc4c83c8f9a591b0b0e72fcc149c685b01381a74af4ccb902c0050e05baf732bacd1606533e2acc6308c777201eecdcdcbe935149c4e572a15a205d2b80e75ef2473160f85e642d28370c0f19464125c687c969665b13b095aa87ba476802d72c354ebcbcd89f28ef001c":"39335e9193222c7ae3caf8e5ad77b751e9847c37b9016d355ac7520407c91e87":"28c6bfcadb5f52324e39903bf7a04faefb89383f473daa432cab9178f2470d3c":"4e88f65ff776940bafbbfb35643bcdaeb43b25b45de2de3c011ff1449c8b8b32" +Nist_Vector_184 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"2225031fd26a6bb4fd9990347bc2c8ea4ba45bd75df68476f983dffb5531899f1317d95f7cbb493de45cd2f11904cd5c5d5a748b4aa127ca730f89a928ddcd250a6551c2f7cce109e64d3ab74afb2d4f4f7e3494eb7d557060a1f29ecb5b75f64848370902bd6ae2fbf6802b2f9c37f34836ad71dd2e2abf6a0a47df4fd5573d":"87bd74c5d70a292914d96b47dc5e9e97a6799c3b788014e7f106ce7ce7e17a95":"04964c093fdb852c97b165e179f7ef3b39350c2588e60a0177bc2e890ab08ffd73d8a5a6692cfebd0c912de2d50bf02139bf017ec715c2dd7be1aad9d0b96c47d6465d4eb0ea0247ff655959d94a3409e9f9262d877075f6f0c7783a8df3cc115c5287c69bdbf0ffe0ed3719e418ff99b5dcd5f0cfc1065e404a216e095086a6e2197a69c47774377203d99a234e7be61cc4a95a809f9b9dd0a550b712bce5d1cfdafda232d7c831ec52884701155a3df2b086be870af8e875557518b035c84957c1742b8c02b0d46b64a773012809bfa4c5407c3fbfed3b960816604cf42b2defb4feeabc172afbfcbc82836b44b927e0cd4ca63a1daeb3eeb30d1de608127b":"64f504110193cc4a3f400b6fcfd71d64a1e166c048829d23206da12a7dc1423a":"5568d810ba664a08b301266d08c69eacccec5aae870a6d579eda51a31b184655":"9e818868e06787fb9519b50546ee21d0546e16bb1b5920311ba44769dc69c7a6" +Nist_Vector_185 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"4b1f9335fdfe88c0866bb648c05857b79c2fda92a987b359282bbf0822db747a3940fee05aeb3cc081231e29b9d460ef30a55f0f88702a4ecdcb842beeb36a976136c9241f2eb5c2d93fe38a1580cd58fb93ed137a7d05ea22d5e87345633a0e393feea616eaf83684c3baca4fc5bf80a87dbec3a9787daccec479661af0b968":"afa080287898b0787f5d06d5826cc285ae5bee41768098750419a5c8863ae729":"57767c348ab0c61eab4f2e0894bb6223645a331c5be2490d764839fa4dac814e05e70925d720d0e0ab5faa3db6dc58ba573b4e0b7bc13e4c044b96259385fcd1eade0d7c5174498c70ba8fb8661ed524fa8171570fd52faac9915d947b51f6cf5b74e3edfa064a5161c7623ec6e80d29960b573fb98de9e710c56ee45aabc4022357f6c3712962ad19e43a4148957cc6b9c8f691877a59f43162d8f98f2472699ea510109305f8f98aa3f3f31e4302eb05e5f1a462d0f3bfdcd0c84e76bfdd14b7c90b982b8c0ec7c78cf3e6c216ed1d20b52a132f53c9747c7fbe39092d5ccfcc01a119c92faa3f13d4643e5db22ca1681d6536bc7b704bb09bf6c621c2ff06":"d23656910f6e8ea72cdb979cfd8c8f6676c47c6161c3aa14f2338392891d1afe":"7ac95d3e0936cde441e4a290711cc044e6e98e8a8de68298bf7fb90eef589eb2":"140e9de37ec5aeb3fb795b016f51ea3e92d6f198c5a0e5a5d236671c91042c94" +Nist_Vector_186 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"3b87109bf21571fcfae92b859649bf37dd23d59f76d50cf26f4b2ebf7c5f4ae0b377bf3bf2c7e015a74efc808433047a71bf1ed4ba9025f4561dcb94bef2c2a2c94b3f55ed611c432f98a683abadc2c31d002eaca9b070f2b21319d072df75c62385d7d02897a00f863c2882b2897a331332bb9568b2fdfaccf50b3de4b42e8a":"668606f4a82b50876abd7f3dc0ed580a10344c1dd092c5bc1b26c427028cc5f3":"7c16a9644c18257911b826da10b5b10115ff77675bdc3c9f77097162fc059e86b04c1faeed3c66306c7e5fe2d5c63e8fa5fa2b82565ac6065445de5819a2e4a56925bdcce138654dfb490ac624a38ad65849be4ba74d14c829ef102248a18193933335eaf0c73b7bfe77d669f857ef3addb1f4ca424dbfdedb9e2de1fc0cc2d9777ee834a0ac7d0cac1b2a613890071490efe5cb2097ac830fbc27881f9fa51d3b0247c5e1b7f6be13c30dd31c2c59b7683ce60a0ebd6663de97870af2dd17d91431323a4686bf32e1e39732dae1300c57bd600be790593b2efa045bbfca956768157b4724ca0a1472fe6c8dcd82a38024766341d1f548ad8f36dc676676fbe3":"a3d781e5385d66989b38034171da11594b20f15733fd4701a63cf24bb58ec341":"1e219eefd616caac549a859d45186b5c528627573958fe55cf57fbbd1661f7b8":"b09545843dc0f6299b48f14311503605502868859e8c43867f80df3c2391c762" +Nist_Vector_187 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"042365b1256931a111facc6c40f618c428801b03e4f222a1e1b7763c3b02a6214e4c517beb587a4ea69fdbd4ea2d5d5f45afded96ddac87dc89955613aeff7644fc6a58bb859a85221318fbc5e175c6985b19a1d16ab6ad3ca8fa1903acca42bc6d9efbe88fd6f2a8650425be97bab9cb670b2e39f36d526278e0bcfcbffc3c6":"1c08570d1e1ac0857f649e4ba20de0e9aca97374acba6bae350104f1fce20be0":"815411ac6aa1b495c4bac802806a1a3592924fd9c0a3cca41e076db293d815c2f2b0a53e97cf657c8951b856cca1166ad433be5829b0b636ca9de49111ce5ceccededf36d795edefefee1d553250fbcd5bd05b4d99de55f147773ab3a0f754d090ca7b6ff75c160eefd1709a5df3cd8a0cae3e341f2275faaee3e3e31737e7e9c7e74845651f4f839c9d08da6bfd00f2c2b9c6ed9acb78d11175fa6ded7ab95dbb2bfef18feb149bc94f6de05a205221ba0406c96f63972aefec1beef030137011e6796af2e4ebaa100150d58caf408217acb1183a1a46e06368cff6fd744da7019e7ca109acf1244a763cc2b2186f49272ba3ae0425f2ebcd30e77e9f7c957a":"0bc8f6e0b01bcb55a4d134c967f3a9411737103d400a33a968f9036292d6e3bd":"e7145c70e0038ae7e7d901b48828b0b8bc960cc4fa29a52e11ffc9ab08eee726":"b9c54ef6cb3e1b0498952299d1465ed2c5d4e670cdfd2506462466c3b0fcc538" +Nist_Vector_188 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"98ffb2899f17c80a83e82ca6265e6f361733a6bbc63cdf8880dc756bc768b35b90db7390cfff745ec1b56f1655d8d9a29a6e8a63be0b1b2f9aa7436209a1fa061a7aec28622c472b3d0285a701655a496546e891a8ab29d9f40d2e748d0aa2babc06cfca641b300b7a219caa9e5bae3bf689f60567f922e7796fe47bb72ffb64":"79885ff112bdb326577abf52db67784768742b36e575f06b8d1e4f0d2d49a3a3":"14111dca30c0138761fd2f55972b9846041e5ca8b9bc6b2dc820f2a2f5100abaab337c7e0d1bc59de5ae586bbdcf4d4b14aa23be40095293123badbb11919b78cd6412548d9f9d15f614b6928713344148fd7d30985fd2c509b44d396c5672a082de4183fee03e45a90eef6a08b0d9d47132c82a2ccfef05e2ad0f340dcc06d9e2e979ecc43844c6054e4fa5fb8a73a1e3873f2145b0fd40f3ec7946f1f43de8b8057c1be5bf04630a12453d623c9b8d9f0e30c88c30434215d48f77348e6b047f16934ea09743dd3b009cebc49dbc3a3d3567c3321555ec96b2160caf7870970ac3cd8294477a0643ad52c23d9d987dbfff64aed1a883c30a49f14ff0620095":"13ab2945ab2a40067a93ed8c1a4b305182cb070022b79a56740238e55b07e8a2":"4551b096446db6761b708f35209edb91cc51ee4ef96a7495407ab4167a05c791":"cfe4c58bdbf61caf09a42adb1aa5d98b4c459c0112c57823bc15b5b990d92ff1" +Nist_Vector_189 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"5898cc0b422bb89f066dabbd30f59e9a35a392bdd7ad315ec8ad32b8f0f3d02864e70ea36e9076c395f0ba9de1ab6080df3cf4a1470e2b9990b8e7614bb8312b075c0b2a132d7e47ded9e4c0a1368455b9d1a67bc44af2f37428f48f7e089ab41d046378b6d48d9cb135eee4574072abea93bda7eb4f15a206cdaf3bbbebd318":"416634f9b7722188c2a5266cfd9baf1bdd508c0c068010fb228c099fca7cec11":"766d7e4f8bc3254d92cf6a64abd504d01cdcf6c239178b0aeb3f69c9bf202bff7566eca09f29cf5d6fa4736d57c08205500d648336409df06e7f2cf99178b20a7ec2b5124bcffc61adb66f6fafc51e32521dea2124e5781c383b116d06a6a6e89dec46b5e4ad69f5a1e8dd7ac5e160da336c11860b601e7e6d58895e6797db5aa92deb7b942f2edf58d43d3dac9209557a6aa07b228e73a80ff0e92e4ec4603d362e1cca7e928d9459c21405aa0f6548732c0fc501ce50f0896f0763f633c8c1a8531321e1a0f47134a0d2d8676f45f13ea576e64c7870028033a4261bdfcec948ebb1aa25b02134d0259d73024a01da0cad1ce67571e36963dc130496160ebf":"b057bf5a5ae4204f941ff5a01560cbc29033dc6a2e06ad168403cbc6512646df":"a237d2c3d23706caf004a2e94de29f04c748936b62ab5431fe73c72485814265":"b48b9ef9cbd8bdf799b70605f00550b81b309c157332153be9707a399fbdd67f" +Nist_Vector_190 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"0418e01236caed0f80241ce8c6307d026f5e25f4a922bbdb4aafb8d9db95a18175f9dcea9acb4d376f36ff7b7cb598e073de95ad2012eb9d11e15cb3941c6dd0dd69422e78512ebffb19cc8a403a9a7d1f1720ab0f2d25627580366093e21ac1537f93de90a94508f1d7a7a1db5a7b13c9fd00b82be044c3a35ec0451c309b82":"6ad92911dd4fce033d7a50875e4660be08c44957b874339c2a70d915cc03e27f":"4cf4cee4d5abc2c92db522928b6d7e436ea00884009497ed588e93281cf05b3747ca0048b917708279cd0277ce8560c22775d2aa0e7eed1bba77be45417fa7afd776b8e560679c493a520a0e626acdc83df021351669bdf9da19b12bef2926b525fa4c8e3d1f2083ea6bbb489880f594e67934d1f35581ad18e0db462a1ac944066c65dd743f35741c6cf588918d8336702329c62113e9486bfa49ca5425914526a965e3c1975824f4b39fa5fef89cf6f9ea512f7ffc9138e72dbd0f71b01a70975312eacab11118471115ee3fc810522936c9df35977509b196d867fa11f607b7ef9ab78cb748213a6763439ce5e7641b05359670612203a47d4de9c5388405":"5aed2d19239189cd0bc8cfa3c329748c0555d8eafd5e80ff931966680e3ea454":"83ee960e6f9026fe2454d859462ac334a13896e75179858ef40e2e9a065c536a":"7ce8699c6ccb184d4240b8709da11451328cf1a7e0cafe6e1c8ab53d7de67d9e" +Nist_Vector_191 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"92c949fe2342f91a387b67c1b12b1d04d0721203caed593c9c464e5fda09fdcc91d3321d2985eec08ab2026d1ec3fcfa838cb6af45290c08dc30b9c14c4445d783b6f48409a00490f4e308dbc87fd1b2f878385212e1f4c3e1cf81c56d71e73fd7a095b56b4abec15c57107420fbdfa44477078ccf4519f9f6044f0744052035":"b0d23aab4d95446f8c6c5d496d477dd9486f50b2827f7cd19728bc96f82840c7":"256d231ac2bae650d25999b2706d4cb63a89b1468e0df36d677535fa7a0ea890590d3290d4b50bdb399f33dc415e4469c97c6c0cee8205eec962d7153c4c85ab88f7cf80979d4a1ffd8c74e681c1d28da07732116c3210ee4b693309333686246d667074c7172035fd6091b2840b113970b45983d474f54b95d26394b7a43e81b449a2ee9423aa1c27f4592b516c12d5433e2ba724f5463b4169a2b0940e1bccd60ccab9b5a38248acb60582ab8bbc01c5e75f9ef7474273fb51aa6316e649f4f22452dc70bfd4c3da072c03ea82ee009d4272a84961c98e517ab947741d812116011dec0373ca8fbac5576c2069b067f8b005d60a36eca44f56019a64835d76":"17a199bd383a84e22029fb90d5abc9a8a7ccd3f0a33720ca80e3161971793526":"84cace71a80ed47494570fc84839f2e350191b74f0eefff2d7ab2c689db77bae":"9cac33594e1934b68f62aca05ca040f3c82110c10b7379878b7894b0919a0f2f" +Nist_Vector_192 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"df6a4eb7cad4ff9bdd8356d3568fcf0285c1a4e3c3109faa091b58a9bd907c629d54aa7a23a74870545a0942a2d23914f2f167d96573f06f35ea05ef704cac8014dd21b961d3dacf7b930bbd7e35550f721094c86333e03ed4dab7bc1b6416add9578d279edaee37504fd25ec0c5e8a37ac9ec19bfb1e3778ed6d9c6b6e35ec7":"679ef48b643be394677d17e837a0be6d4d8027a900b686aed7c4b12634fea76a":"2f4b0c01e4b15eb5ee7afa9824093330738be2f3f06c42b2b7c6968fa54b987c184e7fa89eff16da02b93ff61b9ce48eebe7eab0f7e203ad11c71e7b297d23f2d5a5998272c30c2e1724b5e963bfd6f83239f874d88ea089435b896dd2109b6a14b2d848f9ed7e92143c0649f97f4f2eb05b8c5a07e99e497dbc752d443eba93d7f3dcdc3240a2714ea0e3e7627f216e4701148dd21192f274f1ed5df05c60b1576d3a0b7f69a776b5010404acd5afafd3d70f57763f2b778d0c361e5f7f0bbe17aafaa5cd393329171d06ec032039a9ffb37c3ab8cd858ea788a7b9f501996baf959ca85c7dafe0cd3e30957640eff105894c43f866bcc422698d128dca0887":"3cf9da6f182bade870946d3ed3b078208ea8153c45515d64f589bca72b703ebf":"1dd2daeaf3e89fd644c6cc942311ea5056413d8a24087787675ceffd3d6c15e4":"3e12781396558560455c4e70f610522ab2b10fc25343296818ef7ffb0378fa47" +Nist_Vector_193 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"4f16681eaa5d97673a7cca02ee8a7374b75411e0b5704a947f04d1a5b14be0b506f31c2fa329e3ca516fa4f1626a9b5e080bda7f353f850365eac7c3d2596f502a5d70b1542276c12d4ea4a22b5325b9eb3e942e556769b796c4f524595f1cc6ce17f99f9dbf51331453228ead327b614f4438d35d61428429f78c8c9377aaaa":"e0e576432913bc75a2e0de3b33bf3094148298612a9dc56fedd47aa569af8ac8":"2e33604ed9e6c0f1ba403a8c3c3fe8e8f488591813aa3d2fcccdf88fe808f70adf173f0f143abdaad43b80769e30ffc5749e8ad35999953deff4f61f4ca07313609e23acae7b35f77934fdbbe1c380b2727b1c3899250af5b4399b658b7908676d64d11763785373b2169836611d72a957319936c84efd72b72f92bdd2dbe0000d8841ab6d8d0d666e79361abb23b6007348dbbe7a94936dc6b026f3b7100081f547b994e0e0778cb761ebd43a29d8764c7f962a747ecc92e4a2a628f52d8abf43f6e3278a0d32ea67c2d79d04c83387ddc709365c0a0bacc83d75c946e283e0739233581441aeddb0d7d76503d621405d27ef66fa8b5379d178617d4bb5ad59":"53cb2d046b391193efb14a4dfafa296c2ec92293c7b3c7d19a20e68c4a1141d9":"e2ff3fc441db4540194a7f5da1ead849c2c3c48dccf8b2c1b3b359a7b16e16ab":"52fbdcd5c62a999aab46147fef9e18cbfc7daf680a7ddb892edfa44d285e2158" +Nist_Vector_194 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"09e48a36523b5289ec41859faa141e2a29b3e88ab2d6351e20de001e6424b85337675f0ce26be224fa4f8df0ef9710ea285635b27b297d688e338b5461820b57be4bee21645b04957ca2f6cd7af9a6a52b3c97c5b9db1c2f7ea817cd6d3c8522d4e6a9de869aef26ec0dbdd269c79b38806927bd3a5100735e6f9f655ca94dae":"7891b05e24823f283126d7d175a4e8c8124b3776f4f296d0ffc4b5e21bb64d70":"7e38cb668d647ee15f71ac5d2b55c11fd4731e1a6c031dd7594d614f2f1ed25623fffdc5956f5256e635c914205a2937a6074cfe1f3e443bbeb323a23b0f0fbccf8c1770ad18ba97d0acbea1e846e12cf12c370625b1555d710905eee943539f2241b8fb490c9d6b44f36139226b4c1f00e95ffe595014f61bf579836a14212c07231a5e9e87de4a9aaf0f46f34c9229f2eabb71d40de26a1cbe10db0645cec37d48575a1154bb5acc947becb2a74b07e2a0e45b903be37502f91b07fb4ecd7f21fb130c6d639ef0fd8444fa12de859abe95548801f6a3c40e7a65fd1518221a274d7b65ed4175f66c04d919c86d2ae8c374b14709e9c8a39e1d0c4e9935540b":"dc24b379ee2d26d5db792839795ad0d4b9622c0e3fd518df541a5f6e9cefba0f":"e550dc65af275e47be480fd647366e2b055c79ea33ded4f5a9557121e082af26":"e26b1a5f27cc6c87863e31ef7f1e61bea476fc5d7c25fdf22fe740f23aa9a752" +Nist_Vector_195 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"8837bbceef577511f2d0c08f790d5d2e8562d93df3d82dd4c2827cd9a9115308114a18c452db2785561081eb523685ae2b3c8b090e0d44dd40d2fc0cdfc88d6f9063a7707df609edf0a8c55034815ea9f1d8b0bcbc92fba513ba81ee646bf98ad4eb22be26a4582b1be2899c91eebcbc9fba5825e021e99be0c9d28642d13fa4":"116d1836a131310644aaaee6ac39b3643cd50026a6b486167cb4daac242a4e7a":"77d7a40a7bab3f5778f85d4fc48b3e28ce28b2df9eb87cc9cf394ef28e8064f39a9690103980a66da219cb5022c101f22011a8157a7568c5ff2e978ba2201367d17c22a867865d00c2a437385627bd088bfcf7219251bf6ae158269f4ef35da7095a53c24f37d61bcfb7c043feb6e93832343f9e90ee7104c80486ecd087be1b67f18cdaaa375e039cb7ad603cb0cd855623e9fb48e4eede14ea3c76a0364aac006650d3b5cd9b474b56f8584be58a721bf34dd0808d334cd8632e808536791fcbea961f7163dad28353c115eb3e856737dbbee03436721637a47754a8a1fe0fedf547b358a73d05b769a95bde3440007c0773a3c7c8dc9714e11c3a10ee01d7":"4a6febb624c8ebd411cfb30c6db055dec3d0d17456dc0c54bd1b43531d4f2649":"7b6b3eaef6cd5fe6daede86d63943478c771582483be0b926ee3022d22ef912e":"39d928b59a690450d13359a29efe20cb98bfd3fc9726f80e5148f059663ffd08" +Nist_Vector_196 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"8c78cffdcf25d8230b835b30512684c9b252115870b603d1b4ba2eb5d35b33f26d96b684126ec34fff67dfe5c8c856acfe3a9ff45ae11d415f30449bcdc3bf9a9fb5a7e48afeaba6d0b0fc9bce0197eb2bf7a840249d4e550c5a25dc1c71370e67933edad2362fae6fad1efba5c08dc1931ca2841b44b78c0c63a1665ffac860":"459eb1588e9f7dd4f286677a7415cb25a1b46e7a7cfadc8a45100383e20da69d":"5ca7151bca0e457bbc46f59f71d81ab16688dc0eb7e4d17b166c3326c5b12c5bdebb3613224d1a754023c50b83cb5ecc139096cef28933b3b12ca31038e4089383597c59cc27b902be5da62cae7da5f4af90e9410ed1604082e2e38e25eb0b78dfac0aeb2ad3b19dc23539d2bcd755db1cc6c9805a7dd109e1c98667a5b9d52b21c2772121b8d0d2b246e5fd3da80728e85bbf0d7067d1c6baa64394a29e7fcbf80842bd4ab02b35d83f59805a104e0bd69d0079a065f59e3e6f21573a00da990b72ea537fa98caaa0a58800a7e7a0623e263d4fca65ebb8eded46efdfe7db92c9ebd38062d8f12534f015b186186ee2361d62c24e4f22b3e95da0f9062ce04d":"2368037a1c7647c683d7e301ac79b7feebc736effe3ab1644b68308b4b28620d":"4fd8f25c059030027381d4167c3174b6be0088c15f0a573d7ebd05960f5a1eb2":"5f56869cee7bf64fec5d5d6ea15bb1fa1169003a87eccc1621b90a1b892226f2" +Nist_Vector_197 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"02bb64d2d5032f54f1ac9e9ee164db83af0cb036d88d41e9b2118cfc39d1b4b4dc2c497549c7982ccacf665d1b0011268246c7c17f562ecba25e265489873e0dd9268e9b06880ba74e74b56f50c7324d29373853e3a0f3ff787eba4e5e7f9437f8ec8a5e868324e9c17fb3d0e12de2d31d438c5bf38b27167d43ae4311b11062":"521f08c10774077ac15bc85f2f6a03d84207b4ed7bffecc35d730cdd1126877f":"11f3a716fbda7af35bdb62d128af6f21ec2ed4896aa81e8769c6eea9c21c81aef23ae0f525269dc405accef098377f652730968a33b50f0a4c7784345280651caa034df87342ca8973ad86ff7f0f8773a94f95dd2bfa802d268dbf3a2103b1276e06db2d734399f2ab7bdcca097616fc46ed2478e52cef049d19444586e7b75d6a56741da2270f54d2c739ec8db996c71f06a39af2383c611499be0fb34809b171254ef273516c33e17e14048ef2d21d600aa153bcf7377fba9405c6b2e5f2aaf0f2f3467d7461f62e814a2c461e8ac9db0df370e18ec6eed8212acaecf1e7241bcbcbca671060e50c29f966f1ea1e92af6903f81c7ab9ee09f60577bf30c186":"08b161571ed031152677136b54e87119133f7de56268aec07cba07667b98bcd8":"7a5d2016afe87883491bd6cd166edddf138c1c89961e4af6876be08b0e06ad74":"34efbda1849dedd0d1aa775dab2aa2b14c9ba0206592fbc34eb47b844646adc2" +Nist_Vector_198 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"4f1c0053984ab55a491f3618db1be2379174a4385974825fcbe584e2b6d0702abb8298dd9184eef1740b90a5eae850e9452b4e4ab219e187860f0fb4ad2be390ef2ba7d76cdedcaf10aeaf4f25e497b4da951375b687a8d67012d3f99c7b5ca82e9bd0630dffcd635ecd8209cddb872da5bf4736309783345a35376b4fce4b91":"6ba8f6638316dd804a24b7390f31023cd8b26e9325be90941b90d5fd3155115a":"10e6f50fd6dbb1ca16f2df5132a4a4eabc51da4a58fe619b2225d7adab0cea3afc2db90b158b6231c8b0774e0f0d9074517f336ca053ae115671aee3c1de0f85728cff99deebc07ffc9a63631989a9277e64c54d9c25a7e739ae92f706ee237b98b8700a9df0de12d2124e2cfd81d9ec7b0469ee3a718ab15305de099d9a2f8cecb79527d016447c8f6fe4905c3718ce5234d13bf4edd7169b9d0db9a6b0fc77b7d53bdd32b07dc15bc829620db085114581608ac9e0937752095951d289855d0bcc9d421b945cc4f37f80b0cb25f1ffee9c61e567f49d21f889ecbc3f4ed337bca666ba3ba684874c883fe228ac44952a8513e12d9f0c4ed43c9b60f35225b2":"2a4a4e014c94d8546c62f0db2fd488f5fac03073a11c3760376114ab3201930d":"006b759fb718c34f1a6e518f834053b9f1825dd3eb8d719465c7bcc830322f4b":"47fa59852c9ae5e181381e3457a33b25420011d6f911efa90f3eaced1dee1329" +Nist_Vector_199 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"42199186434d6c55bcef269bee685c4e1580e243027ed128ca99492033a52954bd1ca8ecc5043820725a3c0d71a181a05aabcb4ecda7180d86855e7b4dfa9a44c7af4c98fbf1f0624058804fd8eaae4990d4d7bb75f01741ce36cfc9c137254cab065a4617d0d0cd5f58ea56868a40f3e0baf7db5d2557f4b9775c1820dc1d41":"46d690ca6b9cc01e9a8c7bfdedc59a97eba52f097b8fdc19bc1f8c0ab5d4bfdb":"6364a35ae994f27703319c36d90793c8f26511846ba06038995b6556e4443aa61eb0f8efcc3d47f7c5f85276ea921da0784a67998253c992975f9e13847ccad099d9c1e5c94cfb195488e1293e23b74db00603e8bd6814c94690bf0cccc1c0e47f0c6609a48e144587ece178f72c8514a43590bc4c219da95cbe8966f4404fe9c288f23cd0f973e77ec84b4b0f163b50a3c556cd1d3951faebd982af44447e60d7834b93b6d9c3ff0961fccb908312a24376eedc508f806668d6617b77491a01d5d069d6ccd5f21b5eb3c3a3d4a0479593845c72f720157b188d2dfae4401c57a600b142b6bde2a69f1a0afba2f507a63cd6df056bb5b34fdfcee012d341b3f1":"638e5fd0885f4c9f7e5f4e6a103b2d2d9d1368c493f9822ef431f54e65a7a3be":"2551d4f855174f7b28a782b89697d48fbc314cfeb17ec4c9902a8e557cc6f6b9":"278b786f9e28eeccd00586b445e75f48cf2649f3f1b7bff72b0e767f3443dc58" +Nist_Vector_200 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"4fdd888756ac68f4c29cd5b1de42756794570ca8f18ff795f6f0fc856772b6a2189b5ed4a9b7547328075b56c28ddf50b84c27205cee57b29d0b387970e89a6a2236293bbc9e399013d1dd3bd5a10ab0d259f7fda704f71cbe3b8b8752806a0c84668d85e4d739cec628dff63371d24a4b14137382759ba400df0e2c25947d18":"49da89d1673704d1f24ac7dc799bf006aa7d606c590e5e37e38032ec51a70376":"5b619845ba969f1ca5963fcf04c03aa40e989222774e957a54191acf9ddc407a54a161e22a5ac50ca5d61e6601cc7995bf0db38ff0fa1f77b244fe98148c81f208dca29ffa30f1131c76dbbe4303425e9180b4a48f22c757ed8e388b61bdc6d55519523d00c31a5f8376640d4688e60dcc172deece73de28437e900cb19a5311a0c9ca9af6cc6eeb6844e9b8359e3ef1cbe03784107d2d0aebec7c1d70d9385a4d2b8033851f5d5b7aa18ef570aa037fcbd3e30f2fc2013ffbfa0787be6d59ffa1616eed5e121ee4dbee04a9ede004956075465a7688701e04ec9b2153f52cafbff7ff9226e69397c7083c3aa536d7109ee430a65448b10c1818c70510a339c1":"14dca45937cfdbca5c799f2ca50de2a44d8051e6d80af242c9f4d614419e6e07":"4b90993d707f3371d0a0cc87255e99a8fba18c3b58ddddc1067cd394172366cc":"4b2612d506fb85e5aff9fcd56c09bd12bf60f78ab7dfd021a742ff85dc507ae2" +Nist_Vector_201 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"8507db5f1df9d22f447c20e4320f90d9b30722197196d1a2418d06dca41b3305f6fbe52ab58cc0b60ef1a1d257fc2fb2062fe6c5f2a25f0293ca39d0c083cfd5e4bdadf2169ad4ed178c88ecb5554ffa2b53aa4398115cde627d30144ace9325b2d79d7dce951509d734afb0ff6d9265b902672eb5884e9d8acff0ea22c76938":"82ab2908e3d2335e07c1002764b07b1ca46d039a95b59b450b16d37ed4838872":"438831cb0eb09aab24275454354ce42b9a2eedb31f421219def74687e6f9c92f0b1982355cadb26e095b7ca25de530aaba63e64fc23acc3d1d1f1b70cb726156ca0a799b59094bcc3b8998a4ae7744d215d63b887082f4c84128e74b9b9999c60cad3bc6bb6f727284b4311a929bbd964c9a7074e86062224dcedb58b9b598546ac95b3b434ea114ab0d678541d6caec0c56009bc347a425f167cd32a34eecb7192424d57b0e54b4a9e82f425138703ce89b189039e92a770b51497f8f10eae9c3459ed87e5101f5ab1b6271485fdb2dd3dbc4217fcf67c7e92d0096dc7da9727f5a434b7545284cd8a283070b5a49d711dffa85904311e0345a99147a168ea0":"1ea475584982b639ada8c84e51ef72738390ed6fa44395f11428dc5fd794a81e":"1d2781f5f9d08ab2feb1683942c2c29a66318839a7dfef9aee9cd7a89efe2ab0":"3adc7be968502ead10feec191e212ea0e07d449006e7f22ddf869a9fae711834" +Nist_Vector_202 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"c7844960966584c8e3a59dc37df37b7eb3ad333148a32b86c1ec18072f3b316c59cdef98ba4dc46f532a4280200c225fac6cd1adf0a45382c2d88054e447740454976e5272330c7487eb42a095f7314139938c7419193b1c128054c1bbf10d0634e22c6e02d8e12279cac0bfa01d3058e0f8d5547ba0f71529c27e0084d4bde7":"0c76bd647c6fafe7da1029b9bf36a9f042195691a26f36bbe0eca3d4b1e6cbb4":"2de9d27f1a030199ffbba770e08aeb1ff3708edf8ebb3a8e664e3bd1511db126ed87bc44c2d2af40b9d512c50a4d6c10b23e3ca61819f5841cbf5d0bd6c88d46f1ac6474ec20b9100b328cc155879166f46b6d71140b0cfb2b0725b64a38d70a91ca8f0e3baeec6125262c52a95d5ca5d5ff6f4482b1825006cd469f9e7f31769a73eddb5f7017f18bc747ae4fce450c4274f4abb960577d13b6a77dd99e67d11edb413e428e50726f7052e53565fa1d6fde91859573c9289289ffef0598802808ecc5501cb300e06405ed0febc3df23f40a1f6532410f7d9049b920216f7d5c7a728c8dd63a8d0060fb53b3543d62a636661750fd43775e80b509004351475f":"71e12996d8aaa7cb1e730713fa441098347ca95eb39362c5a78ee6e847469c7c":"09e654b17ab775959628e7cad0e27053ee495bcc29cc2a5e3b029660a77b1330":"261ad41d6bce6d04d891a43c16ec2a8114e51f0e47b48b1dd1f3d626150338fb" +Nist_Vector_203 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"6f3f74388cc90b29c109ecbda08c79349dffdeb90722974d79d640620949448f66ae673eaf4d4af8c43da673a45ed152ea66fc97166baa7ce8beb666bd57ca43da6801c0ee5a5a9b50c5047935d7a8552c381d93eaf03cbbbb88ed0d3b5a2521b67612a4405120ef0205e89aeb48d577bcda3ad20e0a7cd07f8c9b215c845dd8":"34c0d0de98c85be291b68a5b8c7fb3536b6f7447e8565ead9b002417f56f4616":"080ca412bd197c5aafa2c6df5933a6210fa54089826828d5496b453609a56b7d55d232fbe650dd9f62c05c050c026a8717a78b5db01614a19301c610d2b9964a7e3357c722a4c553273bf27f871b4b9241678c334e20827a5f511fe9319a075d12753ac0960df60870a08a12f09b9d3593781781a0cd75e9d81cc6b9b0d506d100fe972165b68297e6070db2d8b6ea32176d1562084f6a06e08e2929155b255d33853de6549e79f8b56049a1d02f29166d5f91cfbde5aaf6bcae56f5d2d90a9b4e8f6f450080cae8256c6619e9155523c2b2052255a8f6d9f53d8a897be5b0476002410bf798256f62bb1a81827c2c3fc4ecf9abfd77e74174787370864f05f9":"8086cc691e7e793a5c2a81bd3d5a1ff5ae261d9336b33f103d983a817f7eaf7b":"43993b68e847f6ba61d5ad4dc8f5ad70dabc317a7b6811c23e7f215f95415ed5":"1ea727afdb907d1d5b2337c1ecea46c71eb0fc8363af23865a345202a762a7c5" +Nist_Vector_204 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"74a433c2d313f66232324df875b82563805d7ed682b266eaf962375e422b3abbfe3dce7f3c1960a1e4100f333e168d021968b48397e8cce9005e951fdcb096a9abea342cb5b08bab79ef0c431dd3a43de7d5bd6b86bea8872ba038b43a236a7356b03f89b09004ba2def663e6d299763b6cafcb6b150a57f82b890ff6d56f832":"5c1a80e926de194995195c4cee9a2e874c7f6af0fa8a4b2df5432f9cfc86b643":"444fafab58db4d6f5283c3443d6478b5b78daa631bd4c3d9a28ed17281da4c1c2ef4d5ed576d66bfe5314e11fe68abffe4df406f6033edb84f36a38a3ce614601bc25841f9419afb2867d991e87b44c4b744e39b64079d9aad4b585d79c8e21c8f90990540fec8ae981f7483dc5523d216088a55cf2380ea8eb5246781290559ea1b208ad4d0f5871cb4d13cdca6ef34fdf2de63e209aa320cdf14185b8f5f60ccf93f398c1a6cf8b3ce3d98daf05e4cf90c39801ce35f01ec76a9f6035ce1b5ba107a5f66cf253b71fba3833e9969c314eb6d500005749231f799b0c79a555a10cdd69f8eec4c117d7c8b4ec6f60a1ee557b70c0dea380af53b92fdde8823ca":"13dcb7c12aeb75a417a93a22ce94618716996c3350909cfbff6d38b603d377f6":"3bda5b0c9e3da22f0b3e29356a2f7ddace6e9b24a063eb3f5a7d755f2eeaffb5":"4cbb815320314a06538d2a6740e6bf9d022eac9aa25c7508f659f0f7c1f59c45" +Nist_Vector_205 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"f4eadfea117fd3d670cea28aa9d2602c951ed843e2e8cb2864074c8c9bccb0606ced83ae2980598cc3e1b047fca8659127406d8f59f5b7bbfe8ece6d3e42f87f4e42ebe92adaa1e6e92ced3dcacc2e0b2c98eade7c9c99da887e74db5a59132c1d7df7cde866cb2f3ca750852ba53e265e62bf7a93fd693e4a13751e186e9d6b":"6abf7cc887544bf8d3256fb210848eb46281526b1e8cdf6c9204c4c46a747435":"104f44fd7669607644ec55e6ca4096c9a279472752a1753dbb9f2a6941b8122274c87d16f63d75dda9ebcfd6584b0cb374fd17581353d2a246ec0b378de60e9613131683c0568bb54d74457ad73de859a4f02445344d13ee928f3cda5134202a9388e64cf05f8190049df4e777709838d0c9d3bcb37eecdc38c1a5d2b471c4b910cfaa9a9ba81f69b4b45c40344029958fa40000e56881bc6a14864330d5b351c161208676cb852bf47970268d37d4bfe97b3b26ef5b785f50ebc8c47949dc9bd0b2e673fb040e26789f3f5cdbce8e4b78389992bb83eeb2b063e9e1db06a9ede933faef7e635effe5e1b1e21153dc6934197efa1fd68f18a40ed569746c8374":"0711c4621a8bcd40ff3e8b95728ce67a000e1fa33741246d420b046bdec48657":"36c086070368265f736e7bbad54aaf2482d26161f8057a97a4b8cd2b4ddd7855":"31d99d736ea67014fe59cb2212c47eb920f2af44e32b65db15af83cbe8e6aa70" +Nist_Vector_206 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"cbc37afc75177a8386dce2c40c33b8f5dedc23113b4512cb96790f2dd74066103e0c45a9c6176ff96b7d719162003cee10fad6ccc198550a389275d21e708b6961523272ecd5efab5680ed741c2de025b02bbdc56315a442e437c43e3b378e6d62ea8878fd9789858a8c68a504bff49516e762a22ae513a2dceba9253b36f553":"7c6ee86f45ddf8b87f8884f59aad9e320b73b246a80b26a645188a40a9bca62d":"356cc7370c840fa26b0d106c47a626e028a0c967c093810b520639bdda0d339b7fc29adc0d9036b9710358ef9f8c6c05252b278281b2afe7953886429e85d228fb5474acfd65213151e9da0aef86a66f9f9c59fa88fd48cc3addc83d7adf4afb1665049ed094020219c01958b697f22e652152e53bf4e8f68f476a58181ddd3f64344e9b87a08c5d0de49e7b3c2995840c200084e90a76d2c05f8b5c68e77192d0676b4219d4579cb2de0f2a93a916b4f9cfe0d8113dc4bbd97ed12d8ce0447fcf9df12e922c6383ca69c9de9ad320f9c5331adb6eb1d223079196a2939cc0a7259c512c478c943fe05736710e273e4b5867174de72e703b5e7bf7afdbc06427":"685a19da2ee3dd94fe9726a32e712fac05eeffe11e3dd9f60e6f90af7c13e23a":"5645ef65e8e9236d874d459e7a5809923c05d64b22757bfc5b5621079e84819c":"65f4c8febaf3e9d46581b17685c4f2ec9b956421d034a2c1aaabee94b787a4f1" +Nist_Vector_207 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"8eb3685c3f406c5615e88accf4c0c7d2071b6c7bde5244994f73dc04f3cc0ab7e2b6664a1994e6eec52b62790a04328e436a2b4af3cbe3ba6e4c8f363a39b2529ef554c0c627f9f6b255928a39a465e60ac50ccf01f32c7ba483640344b6a8f583c90876b84d19554b0a4baabc2c240e296b12c819410cacffe7a7464419bee0":"7e5e3d7255a629c39f88b6046fe0039159e44c2d2309b112ab05c61561d9e44a":"94ba486977f5982f2ae75e986b7e194461cc3d65cdbf26f936805d12d7f850aad7580206d7dc544cd12ca1891c9dc406c949e52b9febfa88836f1566d521a110bb545e07ba28caf07e1bbfa3b176cc917cc4bb45dae7f873b72dfa9000e9ab6083e705c0167d853dda114c429fd812a05961fc2e78ba9e68ccdb9dc67b116f10532034d9f0f7d39901dc643127c4309058f8ebf43b28a5ce534e29d6227c4ec27ccf777b0008df5ce8b8a19b5771725cb0f9f2a62bb41f0106c390803a307c60acbed6c2e1e0db5036e0e79ddcc3f718b29ca5aa022f2f0bbe815f9c0eb504fc9ff8d18a2da999023af8105cddfc6794dfdcc41333bccd446ad7b82a0a7bfe38":"3966daabf7854949475ff47f3932393a73f21e275b3baad861a92a3ab322e376":"27b4e3c3a45efa6131c3d005ca924dff11fdccf409c2a6993fcb505477b6e400":"68a085bd130c4ec08aa9673c495ba5afd46c9ddad2052ba7ab396329d900d86c" +Nist_Vector_208 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"f2b02ac627b3f66baf4ebaa52b899adfd7071af53e78923182d8b4d5f3a9474251308b4dbd15fb6b657be65028a189353912d7c16d6d4989985c15cedc4343f0ceb680617bc7278511f9068abd613718a862513ee514fdf80cd25b6f84c48851e6a7850feaea57ea20deb1123ca4206bde8a93ff999ef789583e2c850d9e0635":"7e52070b03aba0af4cad1cba0a733618e3adb7de873efba013878fa76331b5e1":"4e160d6970683f4d84eb88c55ba2da58d77f6374fc5127273d65e8ef96ccfff51df69b0e2fdf3e98f6d35e6a3dd9f7edd90bbae4c6581cd02ad01336c0086d4248eb1373480789f7d8333b831db3bae0bdb49789aab93cde1faf1ce88dcdc7a1a4f86143ce44f851ace459a5528c96195f4438ee7c1856ac61fd5035d839d62e48a1ab6bd23ad52f1f6ffed19826b6d7f6491cfb05003176f29079455443f0ab482150fac8e32a3902a4096775f342edee2daf4c4f338d455b4ea35d3975f72be85e98e87158486b4c3d6ec37a3703f63a3e19272ba5255089aacd30fa3979b458df616f57b7502b4291384562041f6188db503f3df7f5981da5705eb0f1d242":"57c141f543386db3bd6a97121f93b47e38891796f02565058ec6a5ce65f7a212":"6433bd33db0ac8261c691af3a27f52cdd4a65d799939faf279ac41788e7528a6":"04cfdcb993382e8fd2db8d90dca80e94b17b432009852cd3f86625159e837c19" +Nist_Vector_209 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"2b4365a4ac6854c972da7347af1cecc6edcbae9d533b74fbe6db5712163a6ce984f9d7a4c54b44dd7555e5c2d2f3d098f31d517f8ebd330199a54b15297e5adee1bdf391581f1019b1ad72dcccd5484b51d275a368c69a7662e79f9b29c9a3084c94ae76da04f958c7d36cecc5d41d77f2302ff28f2ed9c66a0662cabf51c842":"35b701b7d59aad55eb4299e0f9e0348baec875eaf62d2174bce92dd23302a81a":"58e635eec80bde1eb7bf2da20600617af29f0a191705676bc10f7553f7611126e4c4d44bcf14f7a9f48da6e1b1e54d0a715724af5bca93867090f9bfc92741dfe1dd4f06075ec2a9262da81e0dcabfcab9e694ddca86d0e1cfaa321e2b5818182eb620bd5d16bc27a2da035d4bc17807cfe8ae3038c5bbb8a023fb232814b91b99749f519de39aa0f434313323b1b58202c59119b0be217617047c9e2ea453d608562cb96c4f0851a7965b164f9bbe151f9c508ca209f1af659e363804c8d8fa1ad700e20866ec9a1e505b74bbab70cb472308431a3e87272febf7cce2c20ec37f5d68b4e47bf3741013723936db7c9b0f3ded964acb7f8ac9c5a6b4f28de198":"1c6ceff82adebf8c81bb4842b90dbe2a12c9d07c3a9d4990d44106a1768bb082":"00a7c664c544cd7b61749410dda33bb3a47c3eb5a9a7be5fba201a390cecfaef":"6fbbda967b584bd9ec6a0ae76e0c552b3d42bf0e9cf2939caf6123f6e86046f6" +Nist_Vector_210 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"cab1d17666b0c9658cc78cfcba17a08e2989d3c202c8b5085531404d928c618b6e230b25c46a5b58437e4335fc040020ba00c863182325940f00aad330145e666d07e9e9d876137010932ae520d9188ca3d7993c905395219c55846d19b8fcdb1d0c1586b9b51097afd6972ae1472b0e20453f8fbd5d6aa9e4a9a9b3dc37dd8f":"1ca2b291707ce4f70e366ee97b5da158a1c985ba4f252c572f0fb329e43f9cb9":"5022c8a6fa79b7aa11a3d7af5acebb2ef8c50b28d8f0e3a556196562d34131fb44f22c3be3f9895e35eee70aa53b6c67920c540ba6c1085b0ea818b12aea811f2dfaeb6daed976e362430798fdcca3912a0891e7d1c83b748af1e7689e038b490eb73f7fe6e0612e8f238580e78833b20727a602768ab2d59dda36e75146fa4d3664f7b0cef7be877afdcdba23004ee313a69fd61c326759e7e779ad750f7a5cad9fb2dd80a8eea6dcbda0195dcc17b38ad6f0e2ab68cfc69b15c572f85f20c3679c15a83099cf08a379055f8fbdd8f590d43bd12f75baf0eccd6c077ac7589aab8171e8875db0122e6c78617c13586143a7ebe904a7822bacf48a7527f7fa4e":"4f1e2aae323c5309b3ee5d3b73e5d4090c75da17765559e118bfd1460c312859":"7b8b75ac8514c68de0caa98e9de0b9607253d8088d3feadf92b83ffc26e088ce":"4b10e17ff64a0eb72f70a863d00a9bf331bbb515ba3a9fef72753ad7f0df0be5" +Nist_Vector_211 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"8ab01510cfa33cfa5bcff003bba39996fa727693abf6ac010bb959b0b59a15306c0c3a1921af2a76717aa55b39fa3723f4c3229ca9acf6b741614bb551cde8a7220ab97d4b453bec1e05a0eaa42e382bbc7b9b84f8237dc8964ee5b66e9b2a4ca61cf675140efef54fb327a665def8d57ab097e8c53c643fcb58209c4215b608":"5f6e545daef6cd1b8d9848dd98758807236ac0b7ff053b32c703eaa3b1147557":"41197ce2233d7e48c803cd64c78f657923b9e36b871401f8661c21d8ba38c6b9b3239db767b11d1d401e5faecbf7a45860cc5f1a54d60286b7d6e1c99fd5b8c84ed851c5357d41ad60163f224d78c996143fff89dd3a8fe123dae1f621427fd8cce76ed138d68fa248f374ae233249625b93f3dd5937d15e541b7effa4df4fea7d52faced615bfe0348418ff93e69a20a52e55c76cc30f307f84e71e4aabc0825eca3a95b4bd58ebfb0029d23a169e9d80ba7d1c5fd35395e6602e089aa9918f08bae35ae1cac7af33694129e98f0dadadd90eaeb6eed25024390b1a60af794734c397b0f509865b134b2867c115d6f489b6dd7e3c82994b45dce2a23c6bc902":"5fe61afddbdf04449b24295a52a1a037d3f31441a3cec138b7f0102db86ef132":"6a47ea57ceaecc116d7190ff6c6dd9831ab75b4bf6cb291083e4268b486ed245":"017355f698a32abe9a4d4a7dda7c85950cddc348ab8a6751e72fddc01aa5d1f0" +Nist_Vector_212 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"b2f56948a336982a5bcb4bb5d79e3fe5c36081bd286e6e021ab29b522f0be5ff5e81e638f23d0781c268a89b09332575cb31c0804bbd34c80589fb11570fc65b3f67612605a9411cdab3ac00ff3fce33ab22c46d26bf9c3fc5ad2d9018deb9b669b50fbfbaf8bed6230c7bd621d564fb1af953f0e82c5b5520ab97baccf58d6e":"91e01626208863a954eb8987f8e987c8e6213536bb18f5afe3bd66a525bbadfc":"72b84eb6a60c686f74f376e26b2e47e44a6d5dd92c06fde49faad0af9b11e43147ce9308ef3501a752e7bf18e9e6df3c0a49c44cd2515a05508f8060a61e6e6f1b2ecf14b338cf0fd8b7ccbe678d52dbdf20352c155a2bd517d827d6cefbf48c5679c998298e2186ef1098160dfb65914506a177943a4a058282382d327ad36f88301be693c02000c72463e682421a0237804dbb27335c78e8495fac7842d2aafebf90f3c3605f758615df989fdbd06e23e4ad6974b62384f0aa01027db89ac3dcb01cb5258cdbd9c19372a6c4aadf27298062ac9a16de2eb076e167ad7c65d0505c8fcecf359bb5d05cd22e7d48629af539fe7f60e23e957c84c7a61ac92bf8":"6aff566d97cc48ef6bac507d64973c95da14fd704d3a5332aaaca2bdf21e894e":"43704e96cc8d63e6f5b7e118cb7c030d0bd563b8f7a1a304b368a6c66d7e7fa8":"490da43fd0f19fec4ee081cce25df6b2720b1a76b023c15704dd03ef1c3e48a7" +Nist_Vector_213 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"9ae8479327b8b8a57f570f6ec76a1ac6f02b198c6048a1f096e6ce5630b6caf363176413d88033b1cd07f4d3960a12dbae8a659174bb87c37aca6ec56ed5a6619b8ba676b650d97c6a21af023985dc361fa234b2b3c17e77703ba99ae3211260da10a60f240eeef478f2641184a281716ae57888117dba992853f494ac3caa45":"8a5624694a25209a5fb3983ecac3fedf508e0b23e878f60a18ec0e897c379f7b":"ce348b5cb3d36808422a5016dd5873df79f3cbb5e1b458e8c1110226047543d965769a112adb4fced0d146230962a8d413225cc70d810d40e6a72e6dc80db509400c09d263d66206966ed51ab65930a2aac99fcce3a398b64d59097683d2baa57682705abc32eb8c32d6f1e7d94ca17ed7067822cd20fba3795ed1843c01b0d7551c7c4c759d53a4191483bdc6e3121c2bc12607701f43e3ba382c6766819db07ef9c59586937514772c2eccde4c54d92575734c45a8e832c4417b43a92c9abd152259cc0a969bac64b237bb3a0826ae72919d7c2dd2efdf03e83701980c2a8f50ce6e44d7cc8848645bf40aefdf24fa7a6dce5a3b9aca6f017618a64d91ce4b":"86c3ce567e7995a61bc00e088ff2f2a425433a453252b1a729d8d85ed506bdec":"0091d750ad9a4f29573fd457a5891b68d4b6c15703a2bc192c7c620c4e4c4529":"92c409c8977975a417d9f5e0e2dc70683a53a95662ad270ae35d496567a9a2fc" +Nist_Vector_214 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"e5a1a344c25ba0cbbcffe6800135f2ede81049180fb2759fd9e1af3b816ad5436a24faf29cf3ad91cf413332f454f74a9d4f5efe76cf02512c273cd525f04afdb5c24b0588d611d72153680d1e3995e0aa750e9077b0752bd4442bf7bfa8dba38e1c5e7ddd687f55aa54c138c7e6d5f064f3ec55942dc192dd996e553633afd6":"976fb067157b214a80658e7ed2f566911b35b1671e5c0bdd55ff5811e822bf82":"3859d4735c14baeec14b79cc2693ffcac900a2c26ec634a8e977d206ad6ec7b13f2d450ef04782ec0abb0da48f000628cec1f6e9a727bb59d7c0f0d743f513ac0925beb61bf3ad75824fffae1eb783eb1b68fc40d28770e280fde23844a144d4b1a95409b755c7ff2e5c67811f3b1c2eb96cb159a642d84dd7b5dccc2c0aef06d1cd54eac94a11273f9498f1e7a7cd79c108e496dcf573ef3a6610b7731ab14c162ce8377cb9b90788e356f51f4b51a1ec8bd86bd88fd4c38e62cad619ab8941bcb98a2f35ee512f4f8ffdd5ee70caed8467156b893b3532a0a2aa5199ceaecc5b194bc057964cf450668c44f27ec80de21ea1a415ee6a6569832394f6b405d1":"1ef4f08defdb5c59a3df3358e083ce804c969d046ab67f2f938eb1a8f06a5d0a":"443644e127e381b17bb66c53509718a58a30f927425806a62840119e78c293b7":"3f01e5d1e9fdb1cfda25eff3caccf4edf599fea277201cf2b01ffd7cb1a9a727" +Nist_Vector_215 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"b88c212070be398a1f81e85dfd71dc2424a38ae38a9d61085186504f4c2cbfa492b76dbcc051cefde0616a7e3310b4bf17244de7d10f847ce2a9f665948e76724d8f1f4bb3a61919b2ec7dc47ad8a72cb5998b79fe3a156395e4ae88e682b1dd16c52d64cb4b31c39d4a42a21e6242dc0cdbb0acf3d47182638c5f216dc6e8b1":"02163cda612e84eb5ea9e4e068b14c10dad073409154d86fea6aaede59538d2e":"541c690f4ca0c42e5267646f78ef42fd68c363375b2e983be444e4819e63cdc129018bd3b8c6da8b707c196c35c93eabee10e875c41fd925bb3ce80696935d16313fd3a26858eccf2d507fc2a10950525c670dadc883dc6779ac1ce866d8820395f3541c863018337a6be944ddc644aaa6c007197d7a5f9aa53a5e1180ad51c98be9d561a85fe9734160ca35e4fadb02527ba0fa58041b4d96385f7f8ff6ae756add4968c0c2799c0d680f66c8ce96f498228738e3e87b7c866344db7d5a4ec3282431aee5951d9b4c83ec2a0cda36cb2e2c437363ceba4e8e9f6128439d12c51868d0cb1f61e53a68d4e71c5a9e7de43c6dfca26f1741aca916e4282653bfc1":"42cc30e9591b42486ce9998ab7594ddabc5328ca2e931e08c75b76bbe1f8b978":"078a7146a2c509b97a6a8c963baf1fbfbd1a2a5aa214a15ea45763f0e7930beb":"2979cbf59adb70f28ac4fcb69297498f8163764c62b31963da9c8f9c0c43e075" +Nist_Vector_216 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"4adf1ed4fbb5b82d7a2b1a2938430753a6207da1cc049574f0a19314272f9a80c6a53498b78e5c0b7401ce485fd4baebc966da6c1fcb025816cfae32b58aa87f5e8885054735f93df19ed32c819786d4109dbda047d68c0589330715e10522643bbe27e32c0dc9c58336be305b4c0c981b40e0eeda0de461d8441c02c18ceac5":"5b44bfbb69277fbe497ec729838886e7a787f336c246551526b660a7603d167e":"8b6927fe293ac9111ba406125d6ebfbc30f96cbfd696fcac7dded42305c6105453accb1b0ca6f0f31601f8c34f96bb8ee4ccf149923a12821dfaa2a3859a39cf82567609b2060ff609232e90261d66cf31fb9264671f3f1bff6c8a958e5cd015dcc02dfd2f02fb6a443c2bf45abf13862059df98066e00311bb6438b7fe2d91e287553d25411f0fba47417c2902f978c57257ae4eaa3f99317d5adee0f9adf4d41e41072552b3f51eb9936a7f63cc28b466fab6429d06868d18ca09aba634093767192049b02bcb752eb674c98a86869d6726f742e57ef8c3d4531171c64f03e10a4e44039a44d407ebfc6b56a7cdf6b17394b53b5604347c51cf375551b7306":"5f02472e007874056abe7194e80845b81baeaf4f6f564d3640373757f4252f57":"5b201116d8bbc87db99001707b567e7c3451d802fa6c679bf3db3456711a1913":"5be7e4c493fd5d19b771373141294daad97656a3dbe3fd2abbd3b6c62c166126" +Nist_Vector_217 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"bd491cf68b34f7ba9afe0c6ef5f2b7956ef964465f28b2797bc1d6e670a6d81730ee2993d0b4aa96905157025d775ba104e7c19b3b372e852026b1286cbc6a48a10cb9378e97ad966f9cf03917ee8db75b6264e9b0a48a0ae10c2f46444710d4234126ce456b9fd11ab7a3504948d046d5f438d893d9b1052b8fac9547415472":"609a372d3844ca8224dfe780b425e1a7c00d09957a862de6f640af57c086dd6d":"a92e446510764ee1cf81c6b59b5160a7608ff8952d045dd69f034fdfef93f633607ec209b106c6ac8f0cc6ffa64bb9a4484560b838d6f24c993a954efc9d5ee16656aaba2a0d5a94e7a346c7e501af83f131db9e0cab8789fab19bd591ec227f39b349be7f8d0df58ca0396efb1e76549335904b88ec21cd3265c543c4e80e9dde7cb5c9ea8cdda23d96ef1c3839ade8ed4a5cd5fd98b79bceeed9c641c5a7758d0529aceaf27b5014f13dfcaa267a14a0841b36897b6e1e8917b7f7cbf7cff1d1953ac43cc04ab06cf111e006497eb42f28cbc905d6f1cd5d8394857983e1c9e552015a451d0c13a6848a8fc56b79dec1723a8067ff18931c852ceb81affec1":"8c70ac971b83f159d2e6ec26bca1463aadbc8e9987593f49a9258f7f0de9cb38":"0cf526d8a0f9c912d143f3f8afded4598b2a5aaf200e0749ea27defeb7f28f3a":"877a9066f6c5ae78251d9d140bcf39ae912d18bf131bdc7e9d61012daaa4292c" +Nist_Vector_218 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"c00a8a2fffd10bc2eab63b8e375d0c10f9dfae2848ba42afe6085aeec26e21af3eaa493ce4b3d95a31fa502a60ab88e805f4fdf889ed91c15421718084cd0d644795749b1a6b183d74782d52c7babf7400393cee698af5dc010c0ff7f5acdf0208f93ee7e4ef58da123dfde7f0a34e209bbaec61007293fd11afa60b6522c45d":"683e924893dbbd751e0a3f910867471a6410fef562cca9f464943abd88e0430f":"7560105b8586c4532bf1b51e0d2cf9a713a5ea5d40e262ce01ebdaf1ee53d857129e1529a0f8dff63e86202c111c6eb289439cb15cd59fc218abe619c9516250f127fafe9a53076274f306f0b7871cffbd156b1a8819795f0a9955864756650274b83e67caa4e215f833afd5a77d0594b21b4b54356a98a56a0bf6177faffb9fdfd888d6538a1ce76059854bd1f0a20761281d7b751757c6ecc9b1e8131196d0669597213ae73edb9965da9ff372420851155011f691a03a7f1e2040291575b86f595998a06ef79f4eadbae2bd9e2e477dd72684d8efdc1e835f7f0f5c93635c181b96cc7c0eaa27ee62c9227ed9485a8c822b3224e9e2b7acc10956f3d49a6f":"3bf5f524e3a3903c149958d10ae68f0a87a03821445a98b0b9d08a3689738853":"98fee10c85ab46d334758734819e68b5046439cd0b66be26d43760613ac77b8c":"665fab98dd437e06a4f877ee218986e37c2cb2d237e598d98f1b7d4e829a846b" +Nist_Vector_219 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"27f01b47d15f7d196f2667b75ed15b89d7443fb4fab068f4adb67175ca70071d52e270f68964f9fb0e0e14ed5d2954a33d93807acf3c82500e8b9f5fc5510cc3bd6aaa1daac8309128ef4c0b4cac026425aefdd7e69c22c32e5f8d2a6e8f2ea291ac33da6c71a1953e443c0ea206568aadef2b96466cbf76bf149d89d86f529f":"285dcba140162fc203651c5ff7f1155341436c5c5c98e1e9df192b3c948a16ca":"38fa994a1f61ab79ee7a7e6f689c38f6c2826f06647b1663cd812adb36d7fd7ccc50e9a90d02bf7c3f12a228c692c056fb3bd608f51aa401022c839791e6a678185cd31d88cc661af29e5d238142181dd3f6e7c8b05785221e62fdb36c71e07f51d732e7e0cab520a7f2fc5b1831b0a6ba280e00321cb9a025db6538abd672463dbff5ca81993676bcbaf0f6e9c754f24d654ee7879bc03d7d4bc8e8ca58fb9b3929a3c38365cd2e205729e9def0a00108dffe9407271e17d355ec4b29003e0caf0c5b2acb9bd8e52d4410baa9b97a49874c14beebf03abf28a9ec59bc1738b8dd4223d47aa336acbca7662fc69a6fefeecffd47f6737ecda331d1ba5cdf023d":"4029e06b437cbcf8e0788a393ba3aad0d182564ab6a53565eec1755c4f4b6e2f":"8dad02c02ad34fe4e758ff5c81d5384c40d2c49d0ac777bad1cdebc58ec01cfd":"0fe4e1f6875c113f1c17a0f0ed228d44213f8d7e2f15567e57ceb2e8b1098f7d" +Nist_Vector_220 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"73cc5e4a188d2814466941389014ea45a1a06525d2069cf4883ebcb5f22ab128c00f041cf69fd94b33fdade78548f6523c838b87ccd868f3d3d0a9a000f278ba54048b9cadac7a99d98def51713191ad83e5232e3e86497245c80bc710fdd7faaad88ce92c894f8cad3de0075caba337a222cb7a3d7c2d937bcfe4b6e69d388d":"742242f1cde89559dadae5e2cea28cf402c60ea9af2a5282202281f55a0d4d04":"5266427ad4c1cf3ea229377ad397c7d5613512fc27f2ce37407d2cea8e1999aebb8f3767ee96cb927ebdd43b8dbc10ba2c47843d3f43368d9e442bf51ebcf20b48b543a4c388bb3ae3e4027acb657d1bf74abeb8b998421308770f70b3f7b1d910219a1210260340123b95dba187e00cb067f7e37792341202554bfc8a235fc01ecb099ec3615a67a3610d4d8c2dad16087024f5973eb18400c29c05d6984d1c15c159422827c0dbb2bf4509d710c4972ee93be7283aadd991ae8ef0e97312118f195d304fbe96d5aebfb21203eae6117831f9be9099d3d476b83f65ab225f8be493a8ad21620f259d8a44200810c8e562aea8e7a6bc238c129b19f2531a6af0":"57d9723e0d17ed96a3a77ad47be6eafc06a5aa01b59b89be70a756d37dd0df2b":"77236b33b04285425775ee3f658b3761295cbff8e4bc05abdd22e3d78b1b6da2":"43fdbd936ab40459f6843056ca77e125b6ec5ad945041c1f6a2770be9dfcc682" +Nist_Vector_221 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"c0746befd2afc6ca15cdb145c18462c515bd42794c4c7ee513cd9aeb0fc6fc3048b6c7231634984a1be824c775f9c9b028255f5b3c3d8fa08d47aba07755b5f1b5b008933eff35838f15a02ba9366c1036d3ff19e88199ef86a88227272cf4e4e00ffad9c36bebac30578b00214fb29bae43cf555ed431a2f24922430b1496fb":"47c0c6f4e6b56cdf1e1d9b63ff3739edec9c3d5a7c990492a1c72aa1494fcf9c":"431eee49090ad58f4a874c2eb5897969fafe3274bd7486b65e3519e4309d636ace6864d5ca4d8448a357cafac15ac3cb3bd7b2755b3cb6db0af1a4e91b2d1fcb28561b170faf2e0690071bc0f6e42b2d82abe5646ddb8f9b99ee1daf5906036f395d824d080bfaea103048b3f44d0636bc7a6a88e9b004a363b99d24a89b6e97379b20bacf48c7ae2e9bf7e281fe3b4d7eb947a102396d523a1e85ce17fd25f271f3c221a5681e9fb77d64d6241039ac8a85da32741bacf00660e421fe850a0fe73a08ee3a9b069c6d9114c1975272127468f9008552ea4cdf9d96561ea69a646695242500f2318bda82da633ef1ae0497014a637b15a572ddddec070d19d884":"3598a6006fa3f8b8f9b7ff96ba06bf3837a1a1a92892e4a268c75285bfa6d660":"796d7dba322d92a083da7a588fb6238dc86b1fc5104ed600c9b4c688edf805e9":"012c1ff4de8ee386b951275e250581d661d030a4d8fe115432288ab0a4bd46cb" +Nist_Vector_222 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"b8b915cf4ea3b0c4cdcd8b2a06479e71bb4797294b6c41ca870d3cb2ec2cb5a49f6bfe5bcd10be609ed3e1882a312395fc991345aba5b566e67960b42913db669041ea30c29947edde7bdcfc0896b97660740d6c79f0088665f51dadcfa07f7be44821d60a8ffde4e5cb1f98139ff91c9c6f3126596344c5f7eff40049d3f9ae":"0eb74b5186697af279ce72da74f1ebf59921ed425da0f3eea17517eadddb7c90":"1b3722764264e17994f3343bf260c73575d106f6307f2eaa3f7dcd5af804463ddb6bbe38a38f5ab5a8ae6701317cf6c267049fc9b84078241f82d3c6b7e5beba5c1427030297f1df258148e5f9eb41eb20a86877fcc06e5373cd50562613d307649539d28cb52418d42fd59758b61185e792992b5a581229b43403d793b04d878eb9b9d12ea10d2e64d153d3fa41881fe79a67ac408a5348d79239567dca96e1ead3c6ac22dbcdbcb5185bf8ace57660a4252104e5047cac87851d2815b12ae8ae96ab2f33345ea1cf5f2e58a4ddcba26265c06df65afcc6e852b3f910c8778de28a9f098158ed0eca652dda2f9f4ac8a17a9b252410ec5973a6063b642568f1":"37128d19b2108a8e8fdf2cac984d45851078a194bb9946a4db260f27b4650439":"6b4b0e1e7cbdefedb1df1f529ece47891f7b9e959a3f8556ba4bef7bb9856560":"7e933b44ede6b2e941b60c37dcd1568284def229c0a2bb9093f4829000c4409a" +Nist_Vector_223 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"dffd458a808f1889d7f3d6197f0e41920ad731124cee308cb90d2361b23fee969c0e105835549e5d0a3f7690d5862d4cd6ccb33ad18094c85c9650d75b248496390a0b89e7dc7dc0d3a6130dd97789ebf105f8e55d8f0a1162fb3c6b529e2a80dd51e9045ef8ec42ca4bc46abb6539588b531c9799560cf4ea806c3d93d043e5":"36ff71ed608f351c736042f3b638a89666007cefe8ab487e512d76fedce1ff35":"ea437ad0ee9264de8792b677207e547090b32d6ab460b4d589d842ed0a0b4fb4c635e4443bf60e46cba8d226f659c76d2ca01c69707ba6d977255c4584b74740a7cdec4c973e3d16ab6af60cd3123ca12ed5971e69eaffa3da0770d8e1228889cd6825e1b85846f4f7ecdb33f1e5c7acd6b2add1308c5cec439728d0cc625eb89df34fb9c0dd4568f979deead286c50145903a0dccca7239874b4683d367ed31696eecada90dced8a9b1e01364b8794660c60f40590794c95a614c04563c92d444b5ecf01286b1bffe9ed9ef915b4db820ea5c9a5b3dedcf89a3e2c37871d21b763990c7bbf44418f91cdbce4361eeb227516cb344409d2c651f0dc29ec82623":"91797ee940a167a57de7619334638f1b3ba63f9065b69f56dc04e4020a1682eb":"3152fc286fed44f28b1af2d537592c5691d6798caed90591b5888b0d6fe6bb07":"7bff61a8676f0df189654f25c5812b341dd17f4f44667789cc887c191bf47202" +Nist_Vector_224 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"a6516019727d95639db038f90306a8d94fac5243dc7b67c3568d63d85dead1cfddbb2b330b619589bd582af15f0811177504fd5b7aad7b298647a3f64797e3da5fe5bf87b65c2ddec576a8f40660686b808ba42e54bfd0e9e48082d6904f8e19050e54ea4797a2f401ff7c9f3d217b526c03be9201c0dc1b0e8e054bbb32c382":"396102ad116ca2e419b9229667a31737344d0d7854cac8930af18e12a9e2d63e":"9779eb5338dcae7377b1847018ce72c1ed4c55292a963f81608ef332050f0a484519aa96b18bcce8e1b49c11a200c1ab4a75726bcc842485df6314e5c39fec622d819434294dbe1eb647885ce841527c03481b7f22ee586d8c2b1a8471a2757bffbdd9c26f125065685509ff0e4c8b826d73c6e12f6d4b9319cdfa72c069e07b2d2c254b330c06f488d6598c7476ce0f3330c97ec36b7c10871388472451a34afb7b4d4e251f9f72a4a38a6851aab86507b283e890c31ba96d0a1e5572637b2d8467060c0736d11d0744e332a19f59ae2920894e9cffacfeda64ae1ff4869882df3b690c7ce8fe0eb88171e4f2ab8624e6ac77dc8907613235163e0a2c7d9fd6":"79753fbd43773b6757c01663b8f5ef642801aa5ccbf32082c780f71a22c4cb0d":"7222d5eb392460defe8fe3df18fa534f3060235f1e8dce5370762ec6fc11e690":"4351c428031cd9af567b1163037a4e376962620c4ec23c43b7105879f95bf614" +Nist_Vector_225 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"1ffa7cf55f92f234a24bd3296744d543a433c907c1f77d8b706f4b6262d096e2dfe713fa9ca80e68579396fc11a12c0331cfb7745d96b005204e483fbf8f9fdc458e2ca8613406069df5f44918eff8c5f54b8b4d972e07a4b8e06d8426a70874cefe6e93404c1eb381c2d0701c37f85afb1601a09fff8ecfdaf6cb64ad9bd8b7":"24039963cc5ac26a977728b852414f60a287174186ea812e00a5c8a8a5355daf":"18e298e6301389d48644674f8339487a8651b0768dee425905e803ab357c7f9fa05dd5e2ee84bfe105a092716274557e063d086e78b781a43c56a4e0ea115c5cfeac57a4c9b7e1effb89413689928f1546feb30738586d36ffe338083ee2bf5c5bd344bc3db2a7977de2b1ab5ba006d9ee93ef8688a7d10cafe27af3e671013a816984196bfacf002335fe7414423ed8bdc80327372b0d460866480bdf073c9def7977131b06e28d14ae1a816d3222ebaadcc8d7c300aa820e0328af66f742061aff5d4b7176a994ad69b390bbdd619fce047dc7d15a48ea71afa72040bb14eeaf4a2b23d99b4d977beb6d806101021eb0c3a0e31e54579e58c953b55b6e3245":"2ae1af11ff810141c37b1c23796e54f027b4eb7c2f0c412b6c83076de3d4aba1":"21d70ed955b09ea302fb792978d12501071a2e8e2cc8f659decd3df24e37c466":"2cdaaee2a5a3dd74a67795f93ac1d8416223836c76f7fe31c72ec6170925fd73" + +Nist Vector 3072 SHA-1 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"ca84af5c9adbc0044db00d7acfb1b493aab0388ffbad47b38cd3e9e3111cfe2cda2a45f751c46862f05bdcec4b698adfd2e1606e484c3be4ac0c379d4fbc7c2cda43e922811d7f6c33040e8e65d5f317684b90e26387cf931fe7c2f515058d753b08137ff2c6b79c910de8283149e6872cb66f7e02e66f2371785129569362f1":"433cfd0532ccfd8cdd1b25920d2bb7396987b766240379035b0e86527ce9c52d":"e7c2ee18c3aa362c0182c6a56c2584628083c73e045beda8d653690c9c2f6544edf9702c57c455273905336a5f5171107a313cd7d0b0f50f8d3342c60219f22a9023394059d05f464c4496d55dab6eb0898527ff4cf5678e7b5bfb5e18d92c4a9d73288cce14530fc4702f6d0397ec39a880c4a72d358730c56633386ede028023c1791f3164d1574e7823c79b8a3ca1343ea166ba6f02b7ff7e9ef2198db107f7cc159f3b6a1c00a78c355c566deb0ac6fde3f633cb9177a1fbc6c1766ca021d5fec470101abb440d2f06982181a8c92b7cdd765336b9a1e1ab70283d6db0a963fb648c37c4e29a74c37577291049ab47cdbc104c04db966681ea8ebb9f00cf4c4a5462117379575fbda4b801979451fa94b19b4e93656705c0f734f3e0914bb96c1e2b8a0fb68faf14296efdf3300ad95bcde8b67cc4b26e6488eef925cfaeac6f0d6567e8b41355f89d1c2b8fe687bfa2df5e287e1305b89b8c388c26196090ac0351abc561aadc797da8ccea4146c3e96095ebce353e0da4c55019052caa":"40f503abd70fd49a76c67a83e08b062b3fd465ad92be433c080e5f295bb9f559":"21ca148cdf44be4ae93b2f353b8e512d03ad96dafa80623fde4922a95f032732":"73e48b77a3aa44307483c2dd895cb51db2112177c185c59cb1dcff32fda02a4f" + +Nist Vector 3072 SHA-1 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"3ccad0018519a898f87d8ce5f28c0d93ab16c51addf4173322cbc49d48ca9ea37ebe8bc9d8c1b3f783f8cf59cf3fcba10a393eb2ddd989ce258e73788ce74b0ce8223d24e993cfeafa49cc8ec1b8ecee017d83a11bb7034c779206c364ac463cfed3047e1a2bf5c591773b1d882b310bfba2db87893c89a5442c0845bf644e21":"306c1304b380b7c3e09e7a4b489c64a295582bb3e03ce526f13d7482ef8263f0":"3750d36353bfd2e9973e26a555bcf0d834d3d6620cb66579199e040ce8eccfaee660046e78df66e8ff641523046adcf425b8319db2447680194c3a386b5201dd1ac6bf3e66394e939eaaaca4fd3f386fcfe1d5ef4524b06c5ed9a15746f24baef1eec41e683bf35371084495d4da8e727aeba307fba000a769a234e3c4609704b3ba4dfd6a8644fba56083dac848751b52a8c2cdc47946cd21ea24383cc6244f000918e9a23276b606c5688565c44ddf7788181b789565a6becd257123bb81a2cbf9db7fa384e0ca41804ed7cd3c9ca0e1f8bb390bff50213b0629682409933770f6e03a5c4e7e89ade90255609786f6b2fc5a7aa7566bcf7f725aead4cf456c5f5ed7dc3e91e20d94d1aa2f6568c97abdf21e0ba8cbfb6561305cb45175b1abd7f39b9a11c797926b944f5d13c3d70e0b2a8ca18e1f5cda8ce6ac43ecbc1fef881f5eef5a842fd5984ad1e321a317005ad478cb47c9cff61267f1d496fded0a48328d629b7b200c441634ee908879011745bcab6660e15583748014d6de2fe2":"223e52fc516c0a79f55a5474321264fcce78c050cf79b3d9961b37e24d7f32d3":"1ef7723345b2013b71104ceedbe7a9cad430018968bb295b672c2b57b9a108b9":"72852da485c0836a8ebdbc4c996f7f6cb65e99391ce06b19a7187618e9a95584" + +Nist Vector 3072 SHA-1 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"1fc98288857fb3a83ab507465a53c079ed66679cafdfb8653bfdebb03020fe86a943182d4f1377d58eca3c7710d32e210d8d03728bc69e1b8003944ffedaa1b69ae6cc506302bd6917019f588cc29501cc8263572ebc0feb153877174bcfdbad4a58659175d2de71d5f5019c46d112b6631cf0c3f912aac83140cd56cdf903ee":"047a5e52039da40523feffe63312887e4d1ecdf64f32abb31dfe680bd1513077":"335372770c0e8e591a367de99833bde6f01240bc6e236a5b4e36233e120b8ee6d1c19c77f4cdbc294d3278c3d4cf73ed9e8ea5032b0524a391cf293b35ee7e023430222216d9f18b45022f4d5f9385f6384d9faf1a0ffa4a800da23b937651a09e82c22285b9de6a408e23386ffa67abb9d1c71cda7bc0c93525fcd79e83153e746070782467858b697ad14914673033fedb2d7a105ad2d438daaa35b503b518314ac370fc5b1112d4fe514e5835d9a86de25e6b35691392d1cd04836d4126b295b8a89f217d581258af95277b8b91c31e6b0d23a7c52b0ce2641cf1a252838b6e28e226cfc4fa9dc914c5f675fc900ed680dc1aa9e1d17193c432af4032ebab954191327083c59a5f64c1ea18107ce4d7211d1c22f04805ed548fc22df4b162f30b6ff3a7f7c38a5a95fe824d2961180e98b30208dc7ea7071f792261d45c7bb7b911f3b19c3ee0171a326c033cf5fc2bf79de7d5115ac568e04789cb44e08f3a8627a1b1f3762342b49b7679bd7edbe47bc3ee9c3f02db15d53256a5ea2847":"69a22d61b152af35c1b43deda88d5ad456d38df75b318b82712b2690a5f2f647":"5dd0c7e8a3993b9de0676a579c897ea39943a43dbec5996e58c1985b541d7c1a":"67971001822a08a2148a6b1adb50274a57dafe896fb04a12a6f99707555306ac" + +Nist Vector 3072 SHA-1 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"fda9765cc91a9db922aec7b13fc32ac4ec4e3b8534f9e95af96e8ebeab89d847dcd150444868cfaf4213f8d8baa6b1d0886224e2afd0aeb93d59b886572088d05bf721c7adfb54da47c6c4851204a7a92a11deb39ba17cf6c07fb7ce8ba350a99d018d4ea64bd56d1d9f8f7d88157f190fcb372acf6f8d31cf7b795b36c10f5e":"7f6ce353841963c8a6ff3405713e361ef9f1e0765e665195e7c147dd98120c4f":"0539cc992ca70f913537b1211dd326d85f7531baa6be0583ba45b9571baa81cd5828050dcd9ab7a203bc4fe1d874f76ec1f34d935579ed2132255789d7e6010cf504b4c7f586d44a716600acf8a04ad30cb7ca055d7223f9761cdaebfdf7ef72bdea3dfcd020069a969c560160f0534676beff5ea611fcbc0fd47c867f3163e1371e1de67a1a3c3e37168bf0be79c09f45f2bc43517aeea0100a2a25d148ff1990c06143fa253d8306f48d77362224bc3efe93389e922def0fd11d1992f550ed8294b6136547ffd612b0bc8e4ee90b3100bb89922177147be0083281bf663f8370417fa790d4105eb98cc126f5005b7c08bc211dea2898aa653c3d2b51fc67732bff5644e804aae69200c416035aa0ba5a14cc439b569f462117b7dfcf3f2cc13e723a93ff9533208f20241daf36cd16066be3dba20117cb145d756f5a6f79ce2356a051647aedd645bfa6faf8f80a6fdf3eec42ddd42bb2e7b7738296e23978c8bd63b8045953e06cef1263bfe03be2f61b16007df1eb198567a7bc6bff274e":"01cd3cdd3feb4d1a995103b1520fef17f60cd9370ad59b3efe9383a2c0126f00":"55c2b27e769fac99b47bc0a54ff1821c7a46be6001ab664fb68fb1bafc04446f":"3059db42a399c428f3cfbb102d6c0409b06f20068d1ca8cbea4858ac6e5de1d3" + +Nist Vector 3072 SHA-1 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"e49a12b8d761ef7afbcb1c377eedf629d08cc509a8753a5b92e26a2397365156e7c081bcb4686695575c6a64f5d77dfd550b04df390aa55e0d051c759f197a751a6041e2dd0959f902f2e359a167d880c49cfa81e7196fa1604ad32a8017071f098d4cb346b39266fbe75659dfc6607bf0d829640782cf3e12e38376c5a99282":"28d9bc1d9aaba882427ee26c262bd4003aaeba422bf053b0dde14bb6d6d74bdc":"ee7fff18822ff454a207f9db542d24298bb5edb11d80ddc6ddb9bfae0c952d4fe8d9db0f1a86e8a0f2193af7caaee7264d74106de5af0a6c14f710bb863eb7dc167a1e4378b6cdb7ab6841c664e9824529119773578ef55b7c35ed221ef070dd4690b4c12f27673e5d1fe964ffe29da57e2d1acd21ef13e0669fa97668bb199b56a3a53e10469133022081cdf62648100dca267c4f6a3ca3a75b573bb1b39c8a4e1fcf81269e9e1b10c63f5ba4fe75cf7139d038d02f5f534aa081fce732cd5051609bc06f18874dd01121d3c179f0c3f0399c185eebdc34635b3139f1ca50fbffb3b0ad12e481c1a64682143793f072c7db8b5b9eef41ccdd66b904139d644442a92f6255edb9bc1234e27d07a6ba32b1f14cdf98a22c6a12300dff50ac1b65568b6e915541bb386ec725da444467ca25e81448cb78375146ad2078a830e7d905de9ad7d89559c9d430cf5f419ce945704a426ab264016ed87c90d97f51a7d6e1ee2f51bbb3a8de81391697b0e422df9e5d3551e93374e5f38016b296d53bc2":"0650ebc3e21bf1d90ffb3ef5a707013dfce78fbd2c21a0da9c8106d1fa98a46f":"21d34df605237975db31b864f98c9ab6e465dbf0b3fc5868d67cd6cb3a13963b":"70c48807d62d1fe74d58959347ab12c97b500d20607ed2a95d8a388fee265812" + +Nist Vector 3072 SHA-1 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"28f7a067a0ea7f0a4d797cea3939f66b281ed19cc98b8563ef375798b40614f4dd85ac2fcfccbc5ebf0ac93228c0b72937a481ca4f9df7a7e5d2e5da9af04874dcec35035f6a7db493793aa2361fb66ef2eedb7574d04e2147c357298a2adf99aca1eebe00cefa44b39157eb1e94aa8aa98d545151fbb4de67070b3904cce930":"0c5088f5d337802770e6f98349d53461f13161020ab9a241efed4faed2e569ee":"cdb9922d69e99c7f34a9210e2afc5be0115da4aaf682d9ea37788e0b6caa6fde13c88e51f558820668b59d14c06d2cbe6549d3f06d10dbeee46f59154cd467ae19e16be25e6f6cd238ccd1947fc581562d30ca329bb327258ca4aeb901f814414058b6f169a45ff55e40232d7870499ae78c0513777140752d55f0a470761bdcff5a6609cca2d1809f184b298718071d216a14ad01f56cccced23969607b62d4d140c9ef28507674f59fecc7e7ce8ad2636a5c53f070ad317c8cd0231f500a790ef69ac786000faf68e7b7854d6eb26499a9d524cbf8f373ca41dd6a2fa5198eba2a8e228f5ab29be9f6d450f7f5a149aeb20d8a277971fa6e64a0de36c8750afc381961756975621f287a3950f88402c5081fe0c54f44f9fa7c50df906b264098853646b3d05a4f04c6f1bbc6c440f7e7358d3a72b29f7643f4406b7db173690d40aa2938eaf01874d2ba8094cc5be1145b2b2ee9e7cf15bf398e50832d95017430b1869938732cdd1df593f5db2b2bd71308d8c253d254ef39b475e249d890":"2be962ca1f82b879255e20d6971e633ba68582a5137bc55058fa42b48ddf0566":"12de252da2593c5969a6496ae808d851cad1ded2959ea89057a92e5ec91c5f95":"165338075e6a4fea0b238f9fac904b7b33dbee5a552646dfbed827f6d28d6492" + +Nist Vector 3072 SHA-1 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"0e156b0bd84595155ef4fc213dfc7e46bf27a89c275723e0984076b027c49cb2eee6ac866d75333581cca6f897e11418fb37ba5cab1391cd237e2c6ab3f11a055d3bd03f425baaabe5a6a34eba4b118af73edd610787cb8eaf476bd217048208ea4c1d0591372947a1c0ef94696568983424fd1d802fc911e7bf71224afdbdd9":"2c4d972bb3539876b8f32cc645cff0d4be877175f31a028b9bfe973f0651789a":"d0973641d56d8baaa2c2d430501dff44eaf9a3657478799134b0f335ae94ff2791dfd494401332486ba637683e704bd985f526919e661a2280d99bd48262b6c9305e0c8fd879cd0a836128d88eddae51fcfb51f744b23d2d2d27a2cc1ea5a9d5e0a7faf4227a2adbfb7ed45d6aa9c33798abf07bc69efc5fdde5dc5c780196257093eca75468b161cba44bcd142b21fae9edc6ab327830c28e1b3d2d7c812d8aec3a1952627a040110872e148e15de5c7b4ca24f086336daecbbf9816cdb9dc730db8a66a1929abecd4b09a039a19bffa45ffc85ddf0be3277bf075bbb46f07bf0daea24897e07044b5ee37f9f44fee757188170da22924fa15ed9c07f113cdf37a8c48648e586fb55a0c35f3b63a69667244193c70d94bbe36d043b25a041fba92a2042e2eef767e7cd18dd1c1b5ca4878fe774c833cb5c5aff9f67bfd6cfbf2dfc63b8842ad2d49cebcaff4c3927f3199c106d0c149a9b1b49bef1d6f8143d93d25df9db1b5b37d522e723ff64d9ee52e476206712a38246dd926271f5590e":"5e12de89504bc84836c14fc47628a517e898fa46769eba2b36e7c69e580a6473":"5ef5d78c421ae5a63978bcbf7d2037b5022bc47be7b293806580ad5b4de27a4e":"67ccb2833c1d32c68e91ae3890b4c9a6e5229b22a5799168c0046ead92573c85" + +Nist Vector 3072 SHA-1 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"849c5337d88b3b247df573eb0d665548b6423763d5571f8acb5e61e316d7cdc208cda5b39a1944a717587e58e21b86ed222b8ee265105a32baff3692dcf7b8713d0b539262a5bd9a954cb7143ee66f8764db6236136cb1cb3b34a87cbd3fee3b11288bc94ac99179c681a469d62d9bcd91d40332a650a5bce33b6026884ef94a":"680878e382b713d4dc9bed8b7eae880f1054f58e70cda2717577fed3c63393dc":"1e8d4d6fef9905d639e2564d87dcbe0d8f99bde38082ff091a977f2affcab86505aeffe6ef1ddbacf15d9165b006ac0517434aaa65db210452fb2ff4c990b87f25fee7ad5b26ad87749575190089a56cdbceee6782ceaaf569814bb9e658ff50aebf6f3c9791893e5d6ada5fdf8c4720fafa184cc84a84f5fca79d899636e007bd0e1a89da094a378edb6d72240cc2d1d7098b53ba4837a5d0d7d02019b952712e4f1420e58af23d1377cd6d5f3989b3d60b5fc572043b96c4f7beb7137c0894fa99d727a5a88a5d5dcbf2da7b0b2d83db88747fb0ccaa8991d24fccdef42111ff402ed0d9bdb8a4ad13f8fcff6a1df56c82a5f88f575f49a06275a9e66067f15daec402ed877048499909b9e76e5fde52feac944e1de7894cf13c515299acc6442d90f027317b0713805a9512256bcaa7963b9429a510c5869792c1e29082921d0e7d0cefffc34d30762fb83e2abb7821fab4ca89d08b497f75e3149a5cd3d23b29bc52137d8be9c4a95c6376f62ed64fdc159b1bb6c842bd07f8cf03f7f2eb":"48ea48cad85abe488665eb75359217b63387427093318bdfb5d7d8092d342caa":"11b16351f8f72031ba2a772000ac8726a479e1be4523a9eefabe23947a1df0d9":"2660fbb44e29e7687c10e29de96fa1ab03c087ccce086cddab48ec63774141c1" + +Nist Vector 3072 SHA-1 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"4c37a4c8b41109240c4f53d87277d3c790b2f071105d15aa10bd0f7709da274ccea1961e0b99635b31acd2c80530d2b403d7110ad7cd0e3572518909c136e73e57d38c1c7443e58a257f0736b9f6f51da8fd1ae9213e8193003d69583381f020cce7fc59ba1b1ed5541dbef6b59925750d50b6515a977aa4325d5fade42f8287":"6bc051fba93b92859a8a06eb361f348f5e50d091c55b998476ecaa1777f26fb8":"88a4dd593b64a4ebcb27ffea3de9a7ed7801f9672b5c8dc27b383d6cba58b4f00181634d05eb490282ce4e57f0940373d3a7bd7e9ccaa9bb2965322ab5fb21b4327b47ef4e2b42424c1383bbd8558b506a7bf5537b049fff35c558bcc739b760443728c090c34d6d4eba81e24e42394f8fb826f7c92ca71a9dab16e999274726b0c5d8f72fb9141870dac0bb9ec0429802b629ad71ae0560e5862ecf3eaba9c2a584885b32c684f6d55fd1b090d93d036a4e9858a4d89b9b5750849d926c519120131d456fce9d247341eb17336ca9729a9080ac5b1272fbf707526afc8ae6a8c661ef3c151845f6ee0902de9abb4322afe585e59d6d418e87d7cdce4897ccac81d013fd72dae1a5557762527312587ca676f0e0676000fc0c76b8265842f2db7e18e621c0e3c2ca9295e9e36ec8ce1c85097ca5fffa62e7b896bb16836d063386b1e663ef29ec1702965a7e0562d2d282f80952d7476b322ffa7929a453a638ea3bede802ff5f8f566085a6e2a2414ef7a6f117ac8628486b23603b1408faae":"40c6be904308e25af6616fe77c23e6e6570ac32ba5bf54aa81f6773a5071a904":"23e13a35777c189ae56509c7afb411b31307737e2ffc8db3f208940c5e76edb3":"0544758362cbb61d66b66826958aca63af1b8ad615a49ba557923959b68f8228" + +Nist Vector 3072 SHA-1 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"443473d615bedcba2c8d9a9a45a28c428d7f1a26ab14705627d9ad13f53b767cbb60be523fc21a99c373bd7761817b314290f2f6a80e06e12cce238954c648ace50f3b0dfdf71dc308e1a8ee1159fc1f19b73ab6015d186d9b6bad965a9ad62e440a9ced13550a444b5f0400b96e2d238e9e3dc6e6de12f44205d4fd57f60e9d":"0bdf6ed048358dcc9a2dc555c3d45ac394571135ab36168d9fc4ffe4a3529a80":"0f4ec6e2baaea9c81e90700519f2f05f545ddc0ae9bd3a091e8b6ba5255c15fce5ef3c046771c5f31bb01de4377e142831ac1749903f9317c7b01a990714985f9251198c829073205924c568050acd6dcca757618cd2809bb7aab64db1e86ca92eeb854120c9d89fb9363596be9cbbaf8eacae2f18f3ed483589eb466a5144824feb1f88c30cfcbb7628f7cb4159ce32e7c2ed04d0ff0481c958e5ff744522944cf32020389b32959b5e12f80f08064908a270f8695a3f99e75e7e85ba3b3c773f04ef9e09e76b6c47302e41d50ead04541e0fca4a42502722265f82ff60ef46aa7547f9de249135dd077f24a4e7e03be2e3094772767a9760883c520816fae637c030956ea25f0a869e4a00a4a8017bcb72b2f2fd83643bdc01d8ff2868d3caf100ae8b818b926c96a850bd69d8931dbfdcff31c67c537c4f5959d04b744a346647066dcc61f63be6251b590d688ae3c9b53f392007d8584e4624ffd2941650a31dcd5abfae7ca120b11c8d0194be96e8dd09b643d5685d1065d98f39b6ed7c":"63066e05d16e79fd013a6ae456aa3f036e9d58675b3c9e08a412420a64c1f977":"76bb0ecb9faec7c971137ea6feacf1792073ae80be1ca8ed9cec2a5ca6cd510f":"34920246730e0974fb0faa57e77fc50ab78726c8e51579a0ef5ebe3fce3ba7cb" + +Nist Vector 3072 SHA-1 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"cee06f792332080d6e73b3f02f5ec16996b66995beab4a2ba092f40d85c8ac1accf54fba068128c8cdbada209360776a7706455015e73e92c624ada1dfa62ec794cf2a1a9294f3fb55994bc5211add1c685d9a54acd5bcd830d9a4fcff29aec5001c3b2b2a9706046f38bfe48e8522768f1c6f08a8e240e123ed30e20fc46c19":"530e54bf51b3ea012e76206b5ff53c1d5ae6f3433f2a50b66b6947e84dd52171":"5c9205fb649d3b4ba2d44c80a925e30d27b05bd339f1ce35e0d0419a91ed31fd108c51a2a62cf9d0adfd877d27cf5575e43ac7bfcfceec5673736cae089516df8eb1ea6b563198b24a6e2522f320b123bfb250d43b600df9298e121b6c5d2e637a989215e095e603ee6d4e8a2dcd17b908918aa514c86a33d8c717578d861261da43f73250ff2be746c6916fc72871fb42a279d22595051b8ac04afbf2013063e31661b117c5d094b4c232b22f21d2c65d6361290c08f12befd1f5a2b9b5259af0435b97b4328297c252d813499f5209dfa35e9198de68501af4ca8658942d059bb62b8e55a3ce6120a78ee098132e8d2dc3757f7e60f8c08c4e43feac67abcddd1ea2f016839fb1a0f797b8b137ab43b64508ef69f6ae0f3abc4ed682aa7e38fa5146fec62e01e0951a6e81152de43171ca8869fa1a42a4fb2d8ae512c005fd97d12bb13f299ab9f5321ee2fc39b28e61c9ebcb91ecd2b610fd8291f538a00d06d057c3e79422a931279fed9d93b0b6533fae441e98413025fb4fa73cdefa80":"4e500b513c2e24ad17fcb8cc0d6a8c54e654e00a892545a33cb5af8877589520":"6d02536db546f2bb1f65ff0b91b964802b38d171e678054ee41f2b8563809cfa":"6bc51120e35c955ab8f717f8930d8cc8def8505415cf159d2516f96578842f31" + +Nist Vector 3072 SHA-1 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"58aba24e9481d1151b574b146ac21b17110ed0b9bfaa55a4e2e06dcdc18bd10cdfafac047189f5ba9f10377affb40a514d528a3483fe8e64b831ea0cd076ce583942b938a4b257d0b5a92412e01dfda8217d5f8054596a61d5737d8ad8112ae228220e3bff60e2e891d03d53fb14f14dd91975dc15d6b7bd62e99d74ef3839fd":"7bc2316b6301b772b6742d0c50f2c1c39bbede01448026b6a201793bfe7dc3e3":"2adbc07d8aee284ec982c4b95e1ec3ec3f5fd5172368ddf83f9a3c69655291dee6b99ed713e5a1fec338239b8199c5a3bb2b5e2e7f23fc795058a9ac70ebdff2b3daaffa389e97fee35f174961f12d634e8b8250b8b770b8d7113d0fbc020b7b108f8d6b2d7cb6c59e2e151015145a8e374f9b7396e970d91e3c1f85ce23dcae12b2f53741cfc2350b582ca87f0ff9ab50ad0ca2879e216e61a5c358970a3c3528dcd9ece6b83d525b31fe687696a2a2c65e34f2854fea6ff92244d27500f7da946c37169756f4a4664b2909611549ad2b93ebacebfc270ecf4204e6641dbce05da2c000a4ca5ac885406ba155807494706180d54cc012ce06e734024f4ccd882bddd2257afb5c287bc3a8570edf21a20afeda0c762ad696fba177a5f2f9d609355cb91d72ccac8bb9e7c3cff1834d86b0772aec741d7b4b3c3e43bb26ec9f5e86b8685ea5c625b6aea450a46e85e380b158de6aaa2701ffad0c7d1ed0df355d09d06fe1758b2f27a5d02aa283aec9fd12d3b62d504dca0b6632e89fc55fb083":"0c2a0d2b326ad63e869384e3e2e32fcff8db83285fa0a5b9a7b13589a7dd7fc1":"2c462d49344f3ad03b6798f96452f7d66351cead919e8201b7665c877f8255bb":"50e8908a1c6684a2caa8aafb432cda4b7699008c72d8d622c3da4171e51cfdbf" + +Nist Vector 3072 SHA-1 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"e10604ca00728e533621dbb6618b0c877c4902a2ed79aaf40a4daa34d6cc216ad4648daab6cc1e18451bb94e6a1c0c6f9d0d883962eebd507da099788008da23205e3b4e90fad9ae857074ffeac63430c0facbae489c54c957db09d53e12b656cc278615a3a5612af4c2f168bdeb118a42a2a67103fac321adf5688b05848f7c":"6dd500e2aece9ae331df269c26a4e5d58fc6be3963f5002e36bd9cd04c1adbbd":"b0448d43c520377b7df214969f59ffd4e0010c12d7e5fa8f241e9ce1c634439c94700ed5742a8322d405dd05de9953447831c7674e5ae1b89041fb8f2ec1054b928c64ab862f021a55ebce838d2a3d2c7645ec7c0a1a4603617e4f508929144c1ef2b039bc78b59362d5ba9537906e66c8e9c9a3c68e71b35d88b8bac86cacbebd962c66e18129637fad2d98d21e45a32672649492f131bae88c9989bd6372e17492bedff4d9b091b3dd00ebca6bcc49148480589f9593e32795299f3de7e09d88bc0ed27b7ef22ef7d202207fb5ce8c91712c3bd5e758d2822809ea5d2cb288332aa0760368259281a34447ff5a98c9c97c1d58383cd14f6d59bb5e5763217b2337ec2321268197f02cecd0d9fd93db39f8059a38bbb35792ba0d4ed1bad95a05b481c39f6adc9017dec1d662b0803f2ecf0845935765f9356db536c8c11887d9e44b73b6996ae7ac24fcad9c23017e5c2aca88b5a136b6307298b85ff010f964b7477a4f980800e69d3cc0f438aff7f2df8ac61d64435ffaf5e46633609e87":"65243ccac0a014b9e52638171b4a88b02a8c6e617ab9467da523487122e6650c":"56ab9947ac94fe3df7e35801660f68753b0b620a26594cb8fd375be3ea4dbf05":"608ed1835139af29a2e3d874df465edd8d6428f40357d9ae4904efe8bccbd035" + +Nist Vector 3072 SHA-1 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"8af31f66772fb0c31a8c5b28e568e6368cb66b591edfb0db867fd99e83feb3638bc80f0b14483d069e8f2e167c8b0f10cd6b45d039b7d6f833bd58d99b00597aeef82fa3aae2e55ded62ab660810de0fe1c92d53adf98c838c18fd76a273ea12119d675af727011869943d765b96ef266270b4f89ac72edadcf707a4a21b7533":"145abce3eaa8fa6b670afd658ba0c14fa98d2d20e1422367d4455967f9844858":"22f3db9ea369938ed750d5ed3781368d594e62635c6b6e103d6db489a9972f398203abb973d5ad9c0dc110586978d2061483c0202738ceb01a665dd22fc568cbdff2148ae664dffbf888e4dda5a04fd3e89398b4f1ffc3a3813ae94da1f8965efbe7f300948749e9757cc7c05f6e53fdbff994c223aba2c137151b6a320f5b7f8cdd6003baa66020162990624099f3cf56d68b74e96ee09240f2cf11e3954e75b261ef9e8e3551c6c00f41e9eb17421203a4565388c321c1325f72eb10c28a9deeddcb4806f625382b37f0becf77936b7f83d26bf1ee1fe05e8a0005a4058c678eb569e339423e7c844305f4a18b1160a0c430513fad715896b62b9d6e2468232ae375f5f3c0056245eb4616ba11a6029410a955af09f07595fefa03e5516c95a4cfcd66046be2a4f7b3ab274b21c0a4f126c482c934c79dcbbd6916f3b887b2600472495c8335de121c7720f29ae56f5ccf9b99c9ce5655c5e1d15d67895af0dee586bc491a97241f7eff434bb79aad831db0695781e6b512e8702407a7d748":"06f085f77088ec97cebe5397a588369e3dc15b70f2a5316a6dd5f94967fe3dbc":"0fda7a8a3e5d324fc0a1c2841cd22f98757a0c6a2a465b0d9d65bda9b23b3c1a":"40860265229085453fe58487a933edf3c28433694c7b85f6370d9a4783168237" + +Nist Vector 3072 SHA-1 #16 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"e2456ef5d465731b976f2ad1fc94634c0569a0ff7566a49d47d69e60b3b6d7eb2ab25cd49c931299796bff7e9774075ea20a972e3949a29dfb50b2b5613b45c596ca5dab282ff183f564a06311a49601a1e8560d43c6a481ce713f46c6ea85bf4c16489fbd72cf552b26516298bc66942a05d5a8e6d0f6a88f3e678d310e297b":"286d3cec1d2ad2a85f0f163245267438f7d7d62149ba9e59a18dfffaefe44358":"dc9d68b53f35c29f7ca003a2583ec8f8ef5d78a0e45db3c884d35df4fb531a080ee3831bffd3c756ea5042c7614570fba2f6ca4870db4a453d0f793fb4d0225d94f27412dbdf43432f52cb8f867fe5f492a8876d7bd850d899ba2f0a53820c440841fe0cb76fe0444bd6c3235785a3da3081fef99f53a195314aefe955f2964c56506fcc969b67b323766d299c0b02981c72a2ce3d7524ae6f08458795fd32e31b47aa1f974e356081163cb23efd73a9e655deefe5e734ceb58e88a9dbb524eff7e11c3e30680702d8560dd8b6ad9f61e7246c6dde164e914951d6a0573152ec8bdea679dca1985bcf267304d5f1bce2f32bb9946a056857359afbaffa59bee61ad960c567efe3f1145a8a87c2491fa6b33f7e71fcdd8f1ffbcd2b89920907d1144a8cf0573f5b89217bc0598c6e1754f1ae7d9d42a608a051621419da91d11bda9bb9dfa7118e4b663e7bffe6e9946c77ce9f8086dfc822a7ef728888b31654a19b6debd2ca62f5e3b4e289810435b363ecab511f47e9e157f0f4198862ca13":"183ca3afd082bf3de19e89faffc5cfa7dd713a873c02c723279b3091f9bc627c":"778640ce75da584a6a83f9794c4ffdbe30411be43027758c74f89f7ccc7f3983":"6125481e103f7803b2f16d9a4d00f881e0b367024df5822f7cbeb5711e0e4401" + +Nist Vector 3072 SHA-224 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"957973fc3f3fe3f559065be5d4a0c281cf17959018b9a670d2b3706d41d5812e37301005f8b70ebd2fba3c40a3f377a751b6cb9693e3cb00d92888247d07921d3c1e9257ce08733b8926e0df7bdb6e855f1f851075d4e628d110d42b643b54876e5faa3611477ee68371562555269ed62a9271bad50cc4d46038de2dd41920c2":"524a7ea5977f8102b3552930477f5f042401165d4637dcd8b9d13df4f3aae5d0":"42243539e49db9ea19d98d97f6f2a94b23529812df889eaabcfeda01ce4c759487fb89bc82da75fe1c9134361f86de47d16d8eee80e56ac502178e8ed8129477af8bfbd8262c5edd937e1a86c0f0e7b2afe7bcbddfcb5814ced0b756a76ca178423bb4d578c5da183712d968582640aa0ec7e9fb56bfd960d7a57549747d8fb7ade47cfe816c1e57da6633dacc537de060813964bb5b2757a312f9da3d84e60aff98170051d3d90e380b8bcc1986c58ff9dc91e8827d4f9f5fc4b2b2e743cf9389ff02dec01f5d434b430d162e891c3355f91855339f8df58300e4c993ae4df8c4318b5c4bd05283ca4b46b7d2fb0f6476bf15907f50dd4141aa7acac9daa62eccd3a67357122060b6cece0446a93eb230ad93bc9a4d1b1efeeca1e3fc83c119785035b439509ffb7968b1a448b7bd8315753fdf04a256eca1562a11b096c90a36b353659cbde4420e17e90b94c43c7519c60641ceec056f897b97d6bb1861268e0dc79b7c3b6b7639c255bf06865737459126cb465bc1da4a043a1963da7d63":"29e4d7790e181b4767903fe0eb37757f33f13337c33588c1fdbfba0e655ab621":"2e59d5f30f73781d38255b70dedeeb38ae78df4f002c1f747c08deadc6530155":"615c55b2df0ca28c60a6b385c58fa036df8c4b2f4f1935730bf8f4f0bed13610" + +Nist Vector 3072 SHA-224 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"54071aca28969749ce2e2dc855052019bec27d0dd6a310219311b4b6d822467b22b3f02fb8313993fc77c4af1d76ab9db99b0b2b78204aa45f4032a7d945f93d55bcb8a6bbd47f98299a0929710461419edbe1132dc22575f5afbe7078cf5f05b231000f4a0f9f367d9025ed3ae1786e0183eac93ea96b55304a8c2dbf690821":"4b2d62d0e7b88436737d03d6f64dd6a6dd0757021817169ba373e3a31bc12cb7":"ef78152efd88130a4fecfe235037de2309b1e2f322d4f4154756caa8f0b3e41be45c80d895de56389257c391307286be8e8709b80186e2724172b0f2974be591584916fc0e750c0caf83d839b5c248f5de658668665f004bab8ad310118835957c02da6ae9a2a79da039adc884f9eb8b62e379e27f549e7f8aff8ad2fc276ece15f0423528a09e31b26421df93573bec7a4d6c2cbfbe5ce0fce0702088fb384ad1dc35bb2c1c742d43d79ad136e71057cb9f22ca042e61d2c5cc4ccf5b75a7379922bc4fd88372d2a8f6a2750865f91c143412a3fc61e4ad4abd03dc1ca0fc4297ab107a1963533a3d80a24ae2ec4146e8265acfd4446fc28103c5047c17796c4148b8e658e44e9b1c259d63c97f0e766fba8d9a7394cdb734508bfa09ae42d2da3068e2c85af2065f618ec3f3c73d73a750c13644c96e3dbbb7474325af48d1d145c28d69f22cbb4a9073059a9c40891804c73a229f01cef0678cf4855d18f900f0253acd6b3ee53dd96c4c92afff1f3087eeb4fba86d2e9495c5f734a46ca2":"5af719a9e5d8567dc26576782e8f247517fad5ac5de0f7115c5158748fc73b40":"0debcf6c88504a882a0191e6fa4c774c10858362629428aff24c22e3364baa15":"53d8c1dbb3a2c1023521b705005ce6350bcf66c093588c35d768fca295a4a9ce" + +Nist Vector 3072 SHA-224 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"49d5f20acf1e9d59a656bd163fe46fc868476ccd926377a40ed3d7476e9eb7a8a70c4b88b16e799148d25fa23bd0c91611b76c9665f5722f404fd90efdb8ad14b759c349ff6c830642d51076ccbdc57f152fba41c6a7f3cd3905fa7c857265ffc7596a64dc69490a932b95adbc79a3b4f21b2c6fb5d5835d8bcae5d44d912a0a":"4abef24f715cfb3ba6e39c26b07ca46b700aac69fb8df3c0e09be08df90e44e2":"8ff13022080316bea49b89a06dd5a971d86e0c9a3af414258a8f485088b66cc38cdea02cdd62096c00eb0d1c2ee662cff16f6d2d30440b2ad9e897b9eb939b1299ff879557f163f17c8ac60d0c6e998b3a044b43fbfac7b0cc30a579a6bda1b4ff598a531f9e37cc1901a7b08e794a7401d0f8ca4be55bff7b176321828575a477686a98b4b17266e101601f436e554b9e4288057970fa3463343e7e52a58ca145ec9befd7be31ea766ed74ac178bccdfee9d29565e7935e8d70c3eb091e3e3b3e6e77716931ed729c49b96443606098bd0810989e0e6f253cf3ec38294231b711b09a941609acc8976819076543926ec4e06f3e4d7f123c2b8771e54589e04524e3b4f950da560a25d12172d4ebdadc1719400d91cf0264708714479200c50ef00ec0e604909a546c95eb2fa53c65ee72ad53f149c938dc2193496db07af3b30a1f439708aa115c8dd47c81c1bc68ea3abd9026113c01eb05558b8a2be9093476f01247bfbeb3f2858b13e6228b98205fa710b6af1c5f71480dee401d7472d7":"5472e89286e6ccbed316fe7564e3eae899ed7bfc55ca7fb6fbc392d191304bfa":"19a73b049b164dbf7fb2826f4253617cf1c5bb46ffc5204efa00002a79e23c0b":"7be137c109e68f337b5a21cb591a87af1cb8681419f875ff8f041e829991fe28" + +Nist Vector 3072 SHA-224 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"1190853efb7e04cd4947c1ea5b1b5d9e0ac5e6df1dd050877308f1b2c7e0a4917e588103d28c0f6e8b72d967aa06aca68a986d807740f2dddde7281e550af4f637eadf61f880c7351b486615096f6ba50d8754bbf9ba1c49a3485815ef06b3cd761b5586c3fc2b464c6fe12c160ab0f6f446fabf74212430cec15e75a57b102e":"7b2510c73ea6447bc319de79afebcf45482917042a3ca3c1cb1c97d1a1216b2b":"9bb81c80d2b8a601a09e22475d70d1dc5513409fb4668b176c76b3aa1af8630ac7790a4444ab823787f6f569bdf02b9eef5e7bb21a88e3d3296857e91919f3c473add16bcd763f31a2f9844d7cbd8d480672a036c4b104be66acd66e6ef0e8a744b3d878090d1de9f105560247c62153e117efa55ec61c177cd82f8d72c51d253f4dc7336f79826025619fb2103f91144f90f6a689abcc51c68affd28462578b183eec942058f48abf546f738940a6c26d301c4b90ca40ea49c117d61147e8683989baed7a221c4f22092f72b1ed604b6aa94ff6a574b4215bd6f8e9d7b638afa435a3346589a61b1d1db2989d7b45f3234545e8a22d605ad6cb036ef791f625d2c6a995eda3e0cafce704a2bf15ab5dfad0162104592d23f52aa0fea1f432f0a308d16a45e1f41f823262074e9173754ceba70cd8a370dbab1a14f84159116da73d3a9cf82594cb3af95797cf444272850589acc6bca471d076335d67c461db602395bfb17c39bfa24df140c0ac4388db0534a50dfd261374f81b310f751d16":"0fd7617bfdc671127a1d7465f683b98d8951a741f85d43cf5a5bef9232a16ae8":"587d7f4454d59418a7527570f28f1b07451f3baf28f5cabe0310c4d79e4253a5":"18839404aaad59ff24d6accec3b7cc6ac7003dd4adf96b77bab068ae72f25f61" + +Nist Vector 3072 SHA-224 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"b1cb430c5a1d72788c795ab567a84c7f5977965933a5bf238058f2fc818880d25b4ddef9635481fd9fdd4598aecec3764fa73093a225d4e4ebcf01e4b75bdc1841dc01652c4d9916afa24b89c2d6854b72eaa7b1f3089d1a919210831ac80f99835790ce64abc34270cd4551d31b8f5348ce8a70df60b88e085a984acac665a7":"403b2137ade39c1e5b817ffbd0bc3448024089fc1925550b5b860403e7ba65bc":"a81a54be0685f33505aed9591f333a74a842995da5135fa48f5053fac29fff08afd9b901c3df1347204a3f133a7dff6b1adbab077526b638a63837d7844339d48fe107af08ed62e87de547ced84df9a2ccc45876b29bc5361ce8a9a21b81d4f85d3b671c9b44b5483f2610efa01751d3a07fd694e46653ac47ac64a910b7fc421f07e5de54e898789989091e9ed58b7c04e9e1dced60475dc693a0eb4015ed658110b82f8e720dc7afff69cea7b8e56b8a9755bf1e2933d083608377504cab52d38cce1ba82f84c26265e693f18cf52e930dc0d8bc9d41f4d28b32b7405cb1fce88a55be40dca1b1a351aa7d77fa6ef84c776fa301dba2e236933d89c8b944f53403414df0d434db72caa749fbcd566d76f4f6f0bc40e42a29aebe6210e89fa0ca8b6ac08a4cac65c590503533c3e4f1b3c5bde868e79d9da918b72d1b098a7278769546b78450e00e46dd400efe97c884db9612baaaeee2486f64cd8302a4c32d8fdb873fe0afffd7bb74811220b01339dfc5e567c766af2805ec1c30126399":"2c1ca8b5ce7247dca6173fbaf854d00020ded6300311f53ebec8eccef9570d07":"60d2763f0138076e9e0e20f83e4aa2e9aa352c19ca79e3726303fe89b12e27f2":"07e08d916c8a10ba269dc460ee9d83f86a7b3d98621bb7324a6a7e607238baa3" + +Nist Vector 3072 SHA-224 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"3bb9430eea6979129be745d5ae6babd4966e3abf7d9ee5856f2caae6014cb340eebd28bd9f391eb46b3a2b8a4cdc224e5508532ca08cb104aff677133cf4393a20fe4499967dfa64515455930c659d43bbee2340b14a3b3342d4b9a466b889e850dff4b2a51d389ca32fb6a5f433ed93032be4e563695797b8c1e1e019184172":"0d3fc8fc4c59971a963e8e41d26a86499c962615c64abe011e88e590bddd3b0b":"75b765eca4ebde0b6564c3137f16cdae00eeadd2d0b2cb83cd1500cd05ed0dd16730c9501c8a353a64634d065f6137ffcf9563d96127906fb17d5a79ad291024a4a6fb7e7d080219a6231ca158b65f5202912ddcb8dd1f018c9b0e76b3a476336c5041bc502f8acb748f136c3d78cb2c429c8f1ac17b63dd7e9e57b607f9debe571459df3688cf4c11fa1e84533aecda2dfece05f4bdb268cc7b0c8fe7af5a633a83515ada95f31824d6a3c7122fdcd12f54992cbe64d1d6bdbd0ab5ae4d19aa52609750a1de186afab5a16398da473d128882b065e873809fae0bbdc01a9c73b5c6ee65857fa794a15058ddfb24a9a17a0408646f2009dda610c8291ae148a18c173f836b197c78ede5654895b45a3419e9c3177f2503a93ce526be14ad919939ebe3f2d07f006a0b022d6a623c6017f0c76619f0780531d5390d4239b2f900efb44c9530c7d9b3e84a70c904b179ad0c4f909250f7ccf83c5f42d6437cbc9f03fbae8131a12d33e01721e650aee91e1c893f5e7e039e0d585cd7cd7495c40d":"32d9aa04b104b5d7b59a122b368fe0cf476e28098b898662a78efee764545ea5":"7416729a1f60208b7f837480fba81840e45b338ab9846e9bbb9168229f64bcea":"58eb904076a3ac6907d750ff6cdfaa465435e9982ecbdf72197b09bb6df1373a" + +Nist Vector 3072 SHA-224 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"55a69fc16f6b753d0bf65e844d067859f51dd329279980196063fb59f89bd778a9244f932c2adb6811183612105d1c527e8302dfee5042cfce5dbeab165a396f5a4c21339be1021b7ecec66f2177f94243ef6261608c56919679d44863cf9d2afc6010fc2bf821b931ca3970d69b1e622a908389db5049d718e357071063aef8":"3dd224f00ee1d4648c600b10ba05ff36ad2c06ddc5a9f0112e0331ae958f36af":"6146a51deb79957a83b2c7a3204b5c34ae4f8e0db60f0c07e70803f22bf99a39647263db9e285d72f6270ee10f18584c39081d2544d40502c50df1e35a457600b5569d61e8126c055f7b964572e9f3282e4d9745006955c24261c68d7c0cb3f08b0b0d8eaa971e1a631c68a3a914d35efe89f76b9c2116afb7bd1989e202e092b5b570eaefcc933542e650d92c033b5973821d6d77cfc243f744da80b56eaea7650bf50802516228ad6d5b0d4e889c575e3678ffdb1c289e59d9ff7f84a3d63d39d6888dbe213e2c3b3114085e006ad74505739fce826f963284dc4e2b01ec2f9233d3470e82d872ed944e62961f64134e8080daf2df494a76240ac0cd22f9afae7e80d3cf3efbe055147f62ff8c6192e388b49e47d9feaf19eccd65dca9991638ebd7b048077707adab1cb2a4358eefc4aab8251fb0f9d5f0b09f299c720d3a8c00a5a4d84feec040057040b709cc0ed185a832537bc4b2df0ec1f77169ac96e91282de21f342d5429ec3d66ad9d336c440949a1211217bf54aad93bb4b0a43":"7969d08c0cafe4019b64ad3e6614be0aaabc2c2be61b3b3dcdd10d5f75fa24bb":"136f93dcc7d33e559b8db0af13e00c7190928bff5086eedfd11706e6f2349ad0":"32b95b9b147c7d1ac2a2f0057fc0538a4b7c9cd4652e6783e5d7e3534655631a" + +Nist Vector 3072 SHA-224 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"1567890c69e578a27d6208913dfbc20eddc61f5feed457400693dd170f8067bf290b11150780684c20d5cfd2bf1d536dd3b70025883fb41703436fd09c0a141125784f9091151303ef80cd345e5a7d2854335c2984538c5cd739b007248cd99f1dbcd3148cb0ff0db633f8cafc7a0b99c61e784d0303a5120307d3fb3c4c219e":"3ac374b2a4940d92ab35ebb8e59677fbf95980fe632ffbb1db4f385ee4e13a15":"5c53d13a1bee17a28720b7089646d07a3fd58b9b2b23ec94af3144830746177b0d2073707b6b84901ffaa7a4165ceff2425640fcfe5d17650a44a168ebd769c833445f1b2d26434c228c1e2edf1704d711a86257be25235a7cea1e5cbac412235b7596d1dfa0398081a4f18151cbb51dc62c226a2abcaf3335e86ab54608040ee814e443b64398213ba60d7b5a3c8ea78ec6b98934c89aca05b97df5f65bc574a30acddd09f73cec14528be49a2fbeca70291b1b29f7042c594994da128fda22b3ed3a935a1a00575ff1ffd193c4cac53a2a2d4b0c510228a76a74333607d15b568614427144b4174da358e383f658c60b45710036f54f93f17bc808b302674e838c1dfd7f816f7ea44b0d97386e4e1634c9539568dd6ae1c28f25b27aa94499ae389a0926c8fa62956c6e24dced0afb0491dd9fac0516d27fd4d2dd0150ee6b4cff7bfd575043d701daad0f1b942a0e4c61956b32a68c9078f6077fa9945198d447a5bf3c47b7288427edc6f99655aeadf8de18515714c6b9c0d4ce5ab092c2":"7ca690c92c8d4a3ac1d5255a2e5a12922093b8b2ee95906eab29b67f84fd21cc":"4947d36e7426f1441be5a75dc9cd845450c61104f19ed40ce33e252fa2c26268":"356879deb1daef01da04750d58e598db47aaaff50b1cf42d87334a615780ff8c" + +Nist Vector 3072 SHA-224 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"4f7d894dfb7d82040a9fed6c26a7d27a9a1511388c113c64715a06dc46fcf4f904070a6ed95bdd8dc1730a27645d37eb3b02847cb1c631ec0c67b2ee07b8805b34dd9b84e6ab3f9afb9246994ea579567a8f4af7feb86898cc9cb534c387993c6ec16584ac85bed36bbc2c305770f21163686167dd53fe562362ff549d903539":"2c14cd975bc163f9740dcb4a5ba9d8529c5a075016e02400dbfede8dd4f0d245":"00967478358d7c1696ceb92be850f5538ad8543e151aadd84caba1b72f3636a2092a86b6462873903d5bf17f612b45b5133eac1630bf07c0371423d2e5d7147ceacc9baa8cb3b04cbc3cbda429ab40d7e592730dc477b0a95f1fb5ed5d91e14b9d5a1ac8d403a55a658d1c383bb598053be238cd82386968aedb811586fa2a14119324896f2111b9bc7cff666d37affe76041d98f362daa09ff65e82e865eb29c5d4710ca7800886887d383da0cb599b225fdd210a3d70929d35fb9ca807e56c91c0851252b95c07b6b120b3b650418e0f54f45736f82018d09294462dde6eeafcb15a2a728577faf3ef3eb13db044965ea3892f7eb0884e47766089d2a43abc62a3c375831c20848dfde8f83c249a8e27f2897cafcf5a06b7c3591e09b42f82849d498664f485de26c788e559ad5b15f999db927f81f54b96e997b9096b2a7e3e756f5a9aab54c160cfc2e64492179487c98d0aa38308d67428f3a113228bc6dcdf7ab93cbb1da225c72c636f49d27442cf3cf2f9c49b90ac8bafe740dbbfd5":"141936264e075533a96952808935238d715e7cbd840c016ee7a9f508608e4808":"0940724855a0671d60147dc61fd283190134a68c178114d59ab58da73a1c8182":"43f194b97078dc9b84c8e8e867a74bafdc2211706ae110b5aec0b99ede1ffed8" + +Nist Vector 3072 SHA-224 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"9b62a74bc49ef4ff5c62165e7d25521f135c836bc4ef023fb4bb1d6b42c6291071eae0b465c59231cb297cac6d145875fd84f5729f79f92218522b9e55cb70d471030d36291a24925ab731a2d4458cff677079d207ce865b3d5526009238861d64506a92b76baff59b37b863087558d5965d76685f0fbd1fab1b1f9561f8f69c":"70e12e51a254831bdec081a8882e5a24d78b48b6dd163727b93f803734e06a3e":"75d7d9a5dbdd47cecd12f69ab212dfe08a9656e2bca92c81db2d268a293a325e511cd5aa1ba59deef2ab6311665dda58230d48f1416371de1a8364b38f5ad599c472d363a18a2c13d572cf849be2fef9a166e838aa58b721ecfc4b361fdab1d0876b78e2e8f23ef1c82cc0e1700fa015a4007b1d7b535c82d23c129d1d1c9c4afe875a06c05f71f078cb8d9060f4d936671faee217d4045525d570b0c8ca0c4e8b55dfe9b780ba69c9d8cda10c50fd61c4e7214b943c1c29797b099f57a4c648597cedd9d909bc584a9b754b209515dbfa0fecce2ad05c848e99dca21a6d0d5f2dac2361e4c0eaf96df199ad2888d671974ef05d65c92788434ab42f1f1f79edc49ec1fa921395bd0feb6a9e6a0622e8255b0ef6937b89d0cccd5852872d2b0ab5d79c2f198bff6b8aa38acee21d6c3add5562d84d968758d93e8c1d611f7d6182b62e44f57df342899bb564a794d13915882143d9df45f8f21cc030af3397e9e949683ddd8d8da9909cc1139619e4b7b252aadd02c66a5e20105adf26f2f021":"5de7fe70b5c60ec0ba66ade4fb6b0c925d1d56d26d6f57c5d12d07b5f6f800ed":"01e3de398b018a694780ddc6ca12b78dc55e7ad9fdddb5a3f5b2cad0103253dd":"03c98280abe3050a67f88ef29fb214a80124f47321c62e41e3905b8532f4936c" + +Nist Vector 3072 SHA-224 #11 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"6c66051e04c2e6aaa43de9aa42cd9f61e8329c124ed3031b67452db4c435db291d756ba6ef90ab06307cb8d70f3496792e633bf5ac985c37c43bdb4e455c7f761a5ee450567f85cc977e968e7fa42a428c1a7e915c82874865631d8078899377255947c344618297b83c96114d11d74d8cd579b553667cac1d97aea4d1684987":"11d2f10293c3884b1e28a600dd71b2ed37bea133255a0f97e641f9530bb4693c":"ed2e10a44316d677467d79947bec9e405d30f32d860a1ce46b366845df9ad222b0f992f5844571b196a310d587fffa74bd510215f3bdafa1c93d1b1315246fd2f794c4da07bd722a98dda9a02ad4255b6d5267738256cb8639a145c28404562add2bc7691dac12600ba9f8ebe00614ee3fc6e6b2484d9c5c7090b3f3b134ba19909864563040fe8752d6c6ab95111fe1014bf7bbe4e674c9d03bb8d229e4b5f6a6e471c678b0265e88ccad7960fffae700f3a75e61a24ea882b970535eb7017e16c48ce9e2bc8357f7f0889c871d0b4ce29d279afd1d114998d1eb6fe4a5661e429b1327f0a39e9ef00a41a74fe479b90fdda21d9315555afe227274c11a71c0d10c9e5dfc89750eda53c6a8b52a5272c75526375e5fb91ff75d028df7aa2bceb5fdf6f8e3bc1ec3f1e226d04df1d842e4c8f458988cb7415f0d2ca4498b0cd67e8b085b008fc4ca064393a0df517f0b4833ea4051ac3f1de5686dccb7bba8bd939092d6d78fa08f5bf9bf6f13d7aef72f047fcc47a88223df6e1a62d218169f":"2621703fb8f5094bc68eea72d5b5caf26f8ea3a173158b8d3e7f9565296767f0":"31f2c86287e572ff4d07421a58dc7b3d727de113769952b6d8d736088b36a825":"30acbd1c4cd6aa666ee52b0bdc41fc3b239b60d57e279b3f5483c4d54bdd97a6" + +Nist Vector 3072 SHA-224 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"5f8d7f283af00384a519769029d208b61eee0e1cb21ce9fb80e9d8596b894580da7ab3457429e72dfa64e7cb839414de344da21cff55b1b3a83189d208ad2089b35abd78e2416bceb66466762fd7ab9c234c4aec3872cbc8443c92b8ce4ee4595425e746e4b6f7972ebd5d065fb3fdc5e329e8a87ed3cddbe279d57227ae4b13":"1de925bf532a50dc7a10984bd1dbd90500ec9ad22df0f2d6f185fd1ba8060d37":"aa4d065270c38bdf996b1f5f1ee4b67a76ef1e7b134ea21fd0a6137521245052e74954b96544c700d40f36248ff29a712a098d80ca12e28fdd7901a622dd0988e1c4d67de4c497a957882ce992fcb08c5b85c6858447ed6fcbad26d8c40485f0a89d9d020fe233e89319038455644c828d608df9707c63170dd0618c0baef3eca8d1455460a2eb25faff444f803bca297bb680e5f0fd06e887ed50c8060f55d0160ec64517086f4e1d624ab7d12df1b5947017e622ebbcd6f4eddb0a41dcba82743efdc5804288d2863f54003eea12753246e6e0357df05501b195fdf3a7761c4c3acf26537bf98b32f2e72ff1e0159d046bbc053171e3d518344f0537f2e7200bcdd957ec96365caf55fcd246afe771709ecec28348a356a1d4eb136a176adb5fa102f5fa5c969f90896462e0677afc606a948b25587c10316d22e1269fc64f915a796c965b8be97e5beab047ca5198bf2ff856df740afbbc1aefafefb1ed47278b150e6a7222417d3a86494bdb51edd0616899526c27acc2a818e83baf579b":"5f0d6676776f40cfd5ca255fd8e32b10bf3472b193818914876d4c3be68a83b9":"7187cae836823618f9a6e847055ca2bc38c86e726d02d38f4950eb6b71b36bcb":"21f6ff4175765430e2dbed342a85d30056b28905744ece5dad79755ee3d7bbbd" + +Nist Vector 3072 SHA-224 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"b216a035b0ff29feaf7d4c34eeb1604155c90338006753ee2b36062d72f62b524504659f70b976c68952a62c2b9a2a00cf0066a5e5098a632df2ee56dd1a140a98f7b3ac12db3576b610d76563e4621637da1098aa20f3c83247b7278860417cecf7e137194cf1bae12bbc63a7bae02c906d503f694dea3bd534718e37704962":"3bae9330b47aab85cec948f944ac13221ad35d859de56db56c31aae88345cbea":"7d6b3b71b1415807d15901427e6ab002ee985ce7c8d844969c6e7294a2167b4c26171bcd646f0d1bce14df05e4ce58a3ae50b2aba5fb74455233fa6d179a0794cb26e92ca910cd1c16e5464e8fa7ba936341d3ac211ac1f8a2f2a19c148a1c3d6b00ac44c35ea345a3ff73ae9d5abcc6ab65162a53daabdf6da25f96958eaf89f559895cbec52351394f9132c9564d61aac792640f11e09aa6f6cde9ee9ca5e05fd902911163817177bf054cf2eabf7ce8f34bb1c4aded8dad93411fb276d2d0a296799661307de579641e607fdad058d9a3f194574ea76f4bec46bef8adc5d62c7390da1c45f6fc5d9a784f696f24ae7e6b27a809029418dd18a420455c2cc9695e7c0fe00219a1711468e2866b71f3f9c538789ed2843f44f2a821773c52d211dd1333b5f164ecdf6c3ffd71de6678b0c272f92355d5974eb21c3c8fbd0bca7538bbd9894750b1dd0142bea85104356f9a515ef1ab69daed98d94803ac912c770e26efa2fa0b04e11051ced2f70f06f2f05eac8029d68e12261657cf4dbcc1":"248048e6fc52c48398f5cd2ccd8a659c4b7b76dedf54f3fb90c5bb173c5d24f7":"67df1d510d063c9067e9759180be470c71fe09c4f133aca181bdb47bb87b2097":"7328b887bf0d520abe6f24aff2153f40de009e2706ae043dd3aa55521d9572d6" + +Nist Vector 3072 SHA-224 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"6c67116fbd21a0e3ed16b3c4ca58ac49661918bfc6a7c3a6acdbcd53dd4087034fca164df8d38f7ef7db03363701409246382ee053c69c84fafa3c77ad2ce08dc7f41c34a31da496d070a99435799f269dc8effd06d31f85879c299cf7241b37b9a4cfd545086393156737cd9da2d282e7d569fcfa5cbde4bba51bd89fdcc913":"7fa66120c5acd5bac132d07083d07968b210cd9c26c2c56d9b16d98066f5df6e":"6a50d1125f9f3fc2f7e023c093b3608e6972acefe29c0c6ba07a2f61ed747153ada4a9b680622a842b9a820119675620c11688700b855d4b8d13bf726c36acf923256fef1b53093622d1bcbcf023848b8b8f4abf43bb6e87b84d061deb75236224ceda914b18f7ceb72708789dfb94070413b0e65c1231ad02db42decbe0e558aea06c310aa1a8d113be1f071482fc61913225f007b569b6e867cfb392725776ad71f50dc97b834a71375bac18fabf781126d06df62124064e6a723b48635e6754fc767a5094d0645974041591d0ad4828f63783356696af7ff77cd00107949fbff4709dff8a660a413f5b6c0df37ade84fcbc1d3253ba617265a10cc087606130290909a4f813341efdb611696feb5bea3d7d00a53a81f3a2043b887a776075d250c1a010ec47660087f3ef05782dd21d298d6d37559cd473008f474d8deca6817c1390180276097a81f462c0527928f93a461f4ac2d6ed8c9d6d101a2a9a29201a83d0589f57be28a727484518c7425cf5744df396a0e14a4d260a5c8d29bf":"5771223a25f539c80481baebe7b2862156fcf26220d6e953c37f2a22bce77c0e":"7d489ab0d44bc73271ef42e28a60e1b7ef7dd27af4045546047085da408bccc7":"310151d943f088bb7dfdcd52d82884a7f1ee64d46f9d600d23f52f4cea4d2862" + +Nist Vector 3072 SHA-224 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"c8d416c1efe686637078122f798d8804f64a6e85e05f7e8e07634a309a98e92abd54061cccc319f1acd4a087b1d7dbf0b6bf2a09c5dc508ed14dcd5442056eade7691b7fb65b678ec2e137b5fbe875208a427c2a7ad90665426fbcbc7655e48a8965d23fdef11ca8092f511207a607359f94e91b197fcc993ee6ce3c37ad3b71":"1f4a3cf1fb60360db3790a03fe55194985977c6884a5fc05a6fb5eafd53587f5":"cc9b9d0292915d631aa0d9eb6161f924705c566ee09e74e418d88e6b67b7f57aff5170f6c42a839ba839402bfe517c287781dc97df2e0550b3862484d253152f6cff895f092358b5c4459048581309eff2f689230b4c4951db8413573b6eae85c2dc50fd6134461328e5b6439f41442b91e3a34204428d1e2c22412b012242b14f92e2d1bad626af95051bf06c74da4081b0d619e136a99c8da3a91adb3b8cf8bc5964ff655d45c75ada253aba91c64095394c701c53ddc11f388d61984c32d4326a8c627df845b4100f171bbdb252d3e28494ac173432dd5531e03040302aac8c07c9ea92a9ab67faf0c78b3ad8d454dcd428f942d8ce6e29873049fdbfa1df0e6ec224c9dd066b981a400b1f5194fee13cc5ca7ffbeca98ed0a0221377a1ae612740fce774eeed68382b32b686a25ffc016682186448207c4d9783e83da20a5e8b228a134dc3f44ecc565ab9ae162b855ecd37e6407e714045f4e83b971a5f4e304cd778f3d34137745fc6ea15b4b74d60176ef807410b1b26f68ea14f8f91":"589da8a8ac79ad6b62b353422691f35e6474e9c605d877670dd95738b4935f06":"7fa51231bc845fa8b668393b78a7b0408113fb77c1e36f3c78c67d65715a8b58":"730c9e3483811c52cf295bad042acb5dd6ee90083857bee95b6392b080b5041d" + +Nist Vector 3072 SHA-256 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"cb06e02234263c22b80e832d6dc5a1bee5ea8af3bc2da752441c04027f176158bfe68372bd67f84d489c0d49b07d4025962976be60437be1a2d01d3be0992afa5abe0980e26a9da4ae72f827b423665195cc4eed6fe85c335b32d9c03c945a86e7fa99373f0a30c6eca938b3afb6dff67adb8bece6f8cfec4b6a12ea281e2323":"3470832055dade94e14cd8777171d18e5d06f66aeff4c61471e4eba74ee56164":"456a105c713566234838bc070b8a751a0b57767cb75e99114a1a46641e11da1fa9f22914d808ad7148612c1ea55d25301781e9ae0c9ae36a69d87ba039ec7cd864c3ad094873e6e56709fd10d966853d611b1cff15d37fdee424506c184d62c7033358be78c2250943b6f6d043d63b317de56e5ad8d1fd97dd355abe96452f8e435485fb3b907b51900aa3f24418df50b4fcdafbf6137548c39373b8bc4ba3dabb4746ebd17b87fcd6a2f197c107b18ec5b465e6e4cb430d9c0ce78da5988441054a370792b730da9aba41a3169af26176f74e6f7c0c9c9b55b62bbe7ce38d4695d48157e660c2acb63f482f55418150e5fee43ace84c540c3ba7662ae80835c1a2d51890ea96ba206427c41ef8c38aa07d2a365e7e58380d8f4782e22ac2101af732ee22758337b253637838e16f50f56d313d07981880d685557f7d79a6db823c61f1bb3dbc5d50421a4843a6f29690e78aa0f0cff304231818b81fc4a243fc00f09a54c466d6a8c73d32a55e1abd5ec8b4e1afa32a79b01df85a81f3f5cfe":"3d7c068a3978b2d8fe9034bcad65ad7c300c4440e4085de280e577eea72c1207":"53bae6c6f336e2eb311c1e92d95fc449a929444ef81ec4279660b200d59433de":"49f3a74e953e77a7941af3aefeef4ed499be209976a0edb3fa5e7cb961b0c112" + +Nist Vector 3072 SHA-256 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"0661c1bf79eed78ad4879e240a46b95a0db2b29bf81263b9b1676daa2554aad7222c9eb7a893048e46fbd2826ab6e8cf42ab0cd631c4c4a1a819560f73cc861a5b6465cf2880a730635ed7f49e28f7b565768f029db2a443ba0a1bd10773f26f752c83da40fcd33f32f78d24ac9820d0bf70dae568a12538affa867160c81e39":"807675fbaaf0b6d6ba3d82063cc07327cca3f3522d396fe5d2c6599045d668c5":"54b6818054cc000c3af61b62ef4189ba35e04845dee0015be6273392c67332e2e04510cd5b2bbf4723cd8196e025511f6623f03607e566484c330751d03c713068a77e08bde907fc57b3c021e37303373d9d811e38f14b547d2bd87d981269c677dac6ade6acbbae3014ebd381b4008637031c9b6d49ca908765472b05962f55aa361f7dd5a4260705ff5ecf7b317db1fe5d33fdbf48e6a33b3c78b14e620d93806b52e86e082fe4f54d5265e8df623b0c9a259f61b7fa2c0455fadf39693ef3977440f302067c3affbc4574224d5a22044e9bfe11d0d6ede2739c7ffe9277c8644d46beecb946f81775c116388fd6c24af02ec59f621233efe8792d6d0cd2c84333b11f07657333da4e274b8cd3914d977706e786f325e18a339b805c51b45eacb3ce241845970acb9fd1a482a564b2aeecdaeb0a0db39f33ad2991f25cf622bf22f0c4430cf94df1db59aa2d7c2004b5177b9ea69ff556dd4c07edec6259ee139b421573a11cf85d11e245e251190ba869c9cb4daf9f49451a85f38b9b903e":"6215e72ef2d6f6e040b7b6ef4cf566a21fcc4f37783a68db445c1ddf3042a150":"519fe4c5f9b7707ae4b36217ea1707a1871d8fce98eee9e643c45cd3eb50c5d3":"1df224af0b51519e11d8422999b1d3ab0972064180ffc3f1114c9f876a1de3b1" + +Nist Vector 3072 SHA-256 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"1597353f24aaf515fd7c0b0a7453444d5f329d6c3f099113bb3a13309b053e6c123a56227a81e8b1a0c8ab4b46160cc5380df591b19d8a386d29a8e43ccab5d8c0e547fba21bffcf5ef42efb9fb2e9be6297c03d57da0b5889b3b9742ddc2c54b8373fed1f2195f5bb2329a8f1f3f8afcec25eb152e7fa819e5d36cfd3625239":"169b11d03cba7e817da27d889cdb147ae9cb0459359bbf85a367c64c2ab556ad":"5062aa1fdc67294cd57623cedd2808303ceb43537e3abfa1bdbc492b1aeecee61b1fd96cc055d1459ab52ddc3f2344389e5f21448a90cb36e448e60787b1ff5ab6e5549a3921496e8354646bc1fd6cd5f2359ae299c0a047fac3920512a1f411c438bafd03e95e538c6e21d1dd1f15a89d38d48f26305c2534fa8e31d054dcb00774138fb8fc61c6a8d4ae1ca46430d0e31b4b92dfb15bd6b8739fd537101e77334e6f3ce5469e82a8dbc58b3be5ca370359f4a6132fe03360b8f6be248c34220a8003772648664059f1f6a322e0c122f427efdb7d640eb5bb7f3db2d967a2159092d8f8df333ff5ba135602b9ee7e9db6ae0b95886df38d4b4a26a4b2d790c24fa214cd68d0a7ede63e7dfacaeae14d9785be693ad78d88242dfad988b7122adf5afa9efdd0c2047470c607d47b30089ff8bfc4cf5d7a8ba69a7d0ab6c54c05280d66aa4019f6362ea24a1d3f8fcd80c3eb20831b6e0db010faf826488f015f63f0b9ac6df72883efd286f0532b5beff1b9e810ff6a2b2d328af675eafc2f56":"467e04dcd564f36cfe47c8fb9fa09cb142a99417a61797e047fcfd51e16e3e00":"0502a6e1d8c8dfdf56eb67f9a6f6605735e4d1b0076c8b08b61daf8e7c2bf2d6":"7c67abdcf4e580812b13d0a4edbae8a2786d6612bc866e3c13bc09f3e96616e0" + +Nist Vector 3072 SHA-256 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"715f296930312368a2a98d3f42810da57115f00ffc4a12029c276b10629e6bddd60bca2c535b79a5f4a006817791f7f3ad2e01a00216672ee5adec579deb07e9d2b0db222c4e01e1f819c1a52d101b1ef678cfca85655dd6b2426f1ac379a92a9c69b0f8987432d109cd9a7bc04ef287c2afb663444688601ce3c55fd90d0fa3":"4ee80e4cf46b4e072e976893a2d1e34c03d20f3aa1785a74564d6b4654b11a54":"b63340d6a1955731283064f6f22ad7f0e28199f6a58c57ddcb44a026c61e441318c4f8755dfd71b295e9e7babe000849c972f68d4be00954a3c29cd4b4e83ad51830080e29e7619e45d3abbf9d82fd87e97581fe909d3da1e3e96cb3f0c893af9d07f418df902e76b0bbc1c97139cbd51226ac442b3d0b0525c784ba138131421c60543e6e296069f611b9c37cf6030636eecaf41c3b4838f506c02cc84cde6b99cabd2ca578449cc1718aa418ca12a2b76f78259c1691e0b49f09dbdaf585f626cf74d73212b3427845c66f2283b60703adf1a262bb8b10ac7ac5d1ec73614fdd37ee51b71cd1fb4e6db8938382643c721fbc4cfc987bc5efbc81299b375a560cde5adae62831ca4138c399d82f1f8bc680f9c6b47eb464a1e0aac448fe3b5c25bd8c0b7afb701b0680db87ab51738f19f5b965375dd48daca07bff3885632175700c678619f194e4ee5f55aa448aeca7f7b3322f64a547315c5cee045122549fb38b8acc95da5e833022b3b894f03ccb7f73b91c1fe82ce414e1219411780e":"3d7728ce25def9a31dfbe442fef8b162b30544065d9cb7bcc4914662a282bc10":"4c5e990a6e24feddab48d0af4a08b45ae8092594bfb3c012fa1c325c977a3cc0":"820b6cafa89b41c4ccbec842d7c408c65d4998ab1ac6b6bce8d4d569cdf04726" + +Nist Vector 3072 SHA-256 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"1fe5ad49e11c207d3d5e1923060832afbfc0aa0cb29fc0b22b3be59a598f8c703b9bf2c7347f8abde25677ea9cc60af9307d21d301fdd23c28277fce11400310033962c04ecd377fd446358a3449efd6bc05721b784ddf0e238f28608e86bd4c3d7ac631fff8be0678d37bfbac16b75bc15a50ce1397dd4ba3bffcf94d341274":"0d690f2c87fe2cebc9f15546f05afaf6dc843b80abd2046f33de30c2e806358f":"53fcd07399e4d31b09abeff2f096a7b2cc5cf417dee1207d8a5aabf9e8f9fb0f66be48826a3dc11e39beba2ff47b76544bcf55485acf1e3d49e19057015e49ed012a4877be741607749b6f4bf95c44ec3c9e8b893aae8d80e369978a3580371cc13de8e714092bb892e4a956ad3654032f7758fb9454a1cb56406e1bf45855108ee960107a65d45453cb482dc19049b6c83bac111756caf65bdbe5e6b270d5875b997a1722ee9d58384941aa40e810b60b83412eafd0a7428a0abb55df45680cf22656711db6bfce8bdcbb4c083a401cdb68284e0c7ec00f7de74e57146adae221e54cc4a566b05a113ddb22cbc19d881a41cd75de8cf6c7b89a5fae650df585aa70c045b84b2cbbccd0e7ab720c5896abfd356a66f3dcbbb5386be6d02ea9b3191ca275d22248aedc360ecd4057ae06ab2c2aafb50657a91c62e038eac9f5c4d88106db4c6926fb5dd2de1ec7e4e005ce184570e7e97d76422fa037621a6f6d46cb83ab6f4d434b6a8f073900cb03a7810455d19e77d4df624d08e782090ffa":"796cef38518aed8644ec5a1b3389da5ee9b063b88e7fb4602af0709999f9a938":"41a2c955f41413a7ab067b4f50c61e396f9febff61c1500b1a4bc69e50a51935":"79edd751a9dc2372b40580fa4d538fbe2cda4149f6b11939ddad92c574740883" + +Nist Vector 3072 SHA-256 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"a326973093ce502c16473d89ba196507d92281504759cb34c6cc353d45197f915b5e736b8ff857a8b2ec99649a3224f857401898c9ea607e6a2c1d320f27564ccff5dbdacfd87a145f1a029425d76502c081ac0f6a14de5b2cad1c23a61d4e9ec6a04e1a455fd710c3c78c096753c0b7f1511e8ba5f5f1af4f0741fee88b77eb":"37d0fa99e5eed0fb51c6e690f0ac556ae74cab9a84d887a07363599b198475dd":"92915db21c2c3e57fcccb7dfdce28a12aaf6dd10581193b98b7d51a728c38516e39ef5cfb1ff9fa1659c9bee56d4ebc1cd69646c3cc3f7caae0c42d9cca9219148e4998c2ddc89eb9a3edcfa6f457129007a9344013dd123aff197bfcd3db1d9e2199bcea16165a4c34ed2ac32167abd167704ead31d5fc2860b834d44f86cb530dad9e887013ca4d6e883008c286d206b6c7cb252d1328b503ae0679b502ec1646f69f2602d5e3d631d4a5a63fc7a5d06f27926a4d6b1ef2f77ddff3d850d3d9f58a958c3f4f12cf029f148386c5b8a71bae9094dec85279b1e387799d26b2a6a0e0dbf06497366e4903e559e70975dedc7d4934d4e2d3d2cd305ab826402ea8f2778e26625119e7b0c24c45dd9c05a3890dd1d9d930bd0bb409366b07a47ce572ed5bcd5f63c467d49c56811fc3e401341b9a4531f776debdea540a34c7cca3c3fb2ea99c5fa9f9fdfde918a94f74e080d1986b68fc1e3fb978054872ced97bafd96731e6d4f1c4a91278c383d4761c974100974522f7b6e8a2884d5b3bbf6":"0b5c9b613708ea26bea151a0dd4222bb573d950588483483cd2b8ab537469e53":"73f1922e26d9b8068b68f83c2bd5dbbb5960403b49223c02a42ce6cf3810db66":"3ad30be9a60f6d4227039456c9827d5424858a02a8e6d3891772cf80a5e4ee21" + +Nist Vector 3072 SHA-256 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"7504382fb7fba1dab3c93bd31b16e73d9ae1d027dd23166b3b94c7124183faf3963c420be5205a1f44a9a9026c6ef77e7c4ef1ec4845fef6e5ea2487ce012ff53f9450fceb0d3ac62f2102d717e3287db3714717a28cd8b7fc64556a86173e6e7f479f8a8dcd895429cd7f0f5304ef6aaf275d94a7f4b30acc1071787ca5f062":"1c21aa2ef3b11d31f3c94a278859cb74bc40daf5993dbd774b32ea3ca24bf162":"2055bbe89da0a0c488c3dbf29531f1f7cd3fb55a26efc540c2eddcccea1615dd923fea4c8d0c95a5af7e1e7816048f2ae85323a96411e7d1ad62c4ca675b63df9dba31c1c76803fb1c8292465ad0a7e49ba3756a8ad4c6ce86fd30b8b28e08c4b4777e079faff10ff852f7d891a984198dd04977972108c52ce8bdb115646224a79337746e3647213198f1127430f5608733d88204a62be6eaee84629fc7282acef4c4f5d3adbe72410b1edfb74be16b2d675cca891bd8cef205178902b99271b48041abe33ac119ad6b756a477a63063aae8a17ccfbe2acae3c0a3c630c13ade197cf3d05a9fa9d6899c0a3f9487e6148732dc63e907ef79488df3373b8a213705d69dcce6ed9a2209f59ebc58bbbeb08054510b5a65169d0fc1d4d10bda68aa7eceae2e72f0339a2eaaea08303064dd6588414ee7705df3ab974debef588f4e31fd6a8f25979c9f521d2343120e40794f41a4601be579183b877e6a8f6c0ab7ce8480e7fbff467a581df570af89929bc4b56397b787df4d729e65f9b98ee7e":"44efaf7a15a1eb2a7ba04fd4717e938fe738666040b3d81560497ce166f31e86":"56e21a7ab61f9eabbff47c75e5f68c31873a9e1f2e1db662731182f9a029b8f6":"2f24c52f7baae29c0b4633a3855233180eba80611dbc7e88e23548a520b60f66" + +Nist Vector 3072 SHA-256 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"0c0f7b0f9955bb54f16e4e39ad9bfd1deb04b8e8b38e674da455696bdf7cf28e24114ad00513d8dd4e5c895d351ea913fee516b646820087721d9a0b5ecd769b3825739123544e7058b66d2342b04462d5d173cdb00ef6aca604aaa438b8868d15dd6624abb8d19384db48bdaa66471413a894d3610bc97d848a59e2c69c0c0a":"34651f5844cbf85960e987190eda4ca1fcf32d8cbe1ad08dd5aa36fbd0d42000":"45ef384ed817386668e1b90b42f1d423ad9b17ea870119c0932ac2f515f546a3b6b80a612ee66dfc00cc4d9e3b5dd15303d5ebc0aa40cbcd7746f54a3ffea23aea0704ae9cf5ad6145629c61d158db6ee39ac899bbda59794b1769a92982082b77a1d48856427b78bb6e077e27335f115bb842e53251f699f04488beaf83a6c4aa6a4b76370cefc9099c0a45bcf973242df2a01ef68e66c87effd7f98f441e94a09a2830076c2895f997afd0a909b45b3c059177000236c501bfaa56da800ecf08701d212016b525f30d63ccf3afea09df39e1cfab7bf45de1a39ac7f28de0037ec552e2ea10c6b56a5db8c13fcbf73d2e50d58b4f3cf278506f1eaf0873e9ee9465cbaff4ae626f3aa109fce49e55d57fe881c50f7279262621282adcf379141c9b2c39813faf823a7ec077c6e6bf953f130aca58f36e7a87ab1aaeea5eeb4402fa9e26ef8938c8f38a6c040809f4d04c81e2948387d7be813a973a9c95176700117de2f33e61940387f851a73dfa4ac5c984ec97918c967bfedd886d1bb705":"52c16c3e7b17f3e73d7965f584bfd7ca036423b0d42cc00e58d1ccbc419d33b2":"77563b3b48fc9ee0dbea79fc74dd6c69b72c4270918e6a1be2c998177023b40f":"099cdd62dc044a57ea25d1b5c1f6ed84d11bacbb0975976d5821c414b5416bde" + +Nist Vector 3072 SHA-256 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"c67735698ae7bbaeb6f321a1088617382a5c92092151ec364582962c9c0ed9ed8fc790cde0d9744d4e38970a8482401c0f61e91805f4984b8cfdf9dc8093a5c6681dac13809bc41d167d3e11bc99698a4bc07fd248a67491e8641081ff1e97871745157cf930195a35a14d0883a26db442e4edb962aa6187b8d1c7791d61bd25":"2ad20d2e78a9ec234f99a4b2ff52faf492c3e3242ae6c04ea8a37d5f10fce6db":"0d3b3c3df072b5f5129118132bb7bca3c52f51df36767f1152387ec00df65c728f0cffc1cb6f224258cb6d3e90f79dd976b5a180b83903d210f0c4dab82eb72a1f8997bf09301d0f7c89075d552c81fd9585b0b1b1291744d21bd1edcb511217c2962e1a6de9bb01c2b9698ff55ea75dcfe456be481cb6f064fed4bff874eb1c9b7451979f7de7011baf5a47c976a179aee909d25ca87fd5e3c75df778e21272937c5ba7806aefa70647221e5f7cc32ab8015921a5a95ecbb3ca4b667249d0f34dd2d8ba86dc158f9e8425176e988048efd9f7b7cc53e9fcdb29ad2412ab4ca6ebbde6f4efca5945b53b2753bfc4eabe6280235620c4464f6940acca1a94659a527aa14cc7c5467382a54fe479656dfbc11923094fe8019a08c3ce7e99a28f086bdaaf0faac6ee16190dca8e94bf87657058495ad07931c89008ca1e565076256a93cb2468aa7122758b8e174f6a80f41a90fc92f05bf1f1f47da185b2f25a1abf5e0ccc6613e3aef87193400d751b4c87b44d9bdf5c0e207f0f6a7dc2113799":"654dff8f0500b52adbb70fb7bb7aec4b4820963706964c19c8320e161c3ba365":"42c902c5826874774550464c4bb736f2af7fd2a347f27c65bae11820eeb752aa":"6411b45947a43c5b01c2f6cefcd41cab73fcb6ea0f2a35a21475563055316e3e" + +Nist Vector 3072 SHA-256 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"eb6a0359c6e46e09a42c554705bcfc5c0c022670b2f6c1a5bfe14ea805759ca2256153fdf815057ca9bd5f4cf837e14fdba3ad17612ccd19fde00764ba2e8ecd8f5a185cb26512f7457259c2f0670852741e7393b40c8bab673be2fa519b48a95dee6552365fdb7ddb632b1b33f1a5290b828da5965e82d874f79cdb928814fb":"0d06d405d228c0ed860b9e21bae570a6fd940cc702dd6e9a0846e7b2a4be47a5":"6db83b06c698ed80122ec4a2183370ed7dbd6ea44dbb4542149568570c53521d3399ab44fe2babd49068e11953c5d38f7ffe3bcbe4cbceb91c155ac8741dcf226a59ede10b050b9f3743f29689266ce6ee020ca17f9fa0e75b3f7158a65cef9fac76c88786b5e377afeacb9b3dda55be922da0ef958aa556abfb43067a414e915e31af5f5370881ed97b25b4bfecbe082a145d02717af800e77e28963cc0a6a1c11b02835e14bdba1a8c9ce4bfeb06aaebd760d7c43cf56ba212d0c75da026176535f982e8d749f20c2a8d5f53875d893374d859b7cee58b0eb319d3313cb8d17602f47e120d1a24a0f8a63cfe45a5028cc0937bbe89f6b3b7cdcaa7dcd5ec5f3ed2aa9f3aa8e91a496a8bad7874dd34bd8f2a9591997d54f92d5864216c953646840b378c7a05215ecd97b6ba944ca18597b7a54832ec98c1cac0003d50d5a05312cbc852d507cc973ecb56f424e8a1c198bcdbafaa6f928fd27a7c91f84bc234f2532639a8aa2196f8fc2b7111b3d0b1153165a0e0525d4ea595f89aec33b6":"521906f186797e7f5ce85112ab2457ddc030d6f34be361929f4d373dda576e08":"0493db0c18a3882709b3cc9f8dbe05454506c04c3a12a41d599d201d7615b6d8":"7494b4d1b2f3ae22797255a1d0662746352a3d0532290402068594cfe48c23a3" + +Nist Vector 3072 SHA-256 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"5c59b209bbc0a1e010cb108db4101b8e2d04ced91299a8742322102e0d578c3698422b43d19d331608188bed4c7edc03a442f89aae60f4e7ee9b6325de3a8bb702918c21343bc9b266f2ebcf5a620336a7bc99ae3685f19080db46f24a501228c5bbfd9c0b4b0abecbfbd676c359607ce292cffd52d26af80b22e3c4d516ba0f":"4214d55b0a058c3dee2751407d9296168fed9f255e5c68273e1e5aeb3e504e67":"be31fd5d62db690bcdbc09e453d4417f82e8621ad717cab94648201a74f6ffdfab965311e8ff35c4a0b5dda339b435f17317175ac642f785129e151694ea8b244627e300ceb0f3be08f91c0f527f2e0df7c9f55492d1329b7d9689634c8a4f5210157e2419e615d9431736f804b1641103371e7ffe7200e74296127d59a8f97d41af11d70c3fd02531f7b811daa7516aa2f2a9ba70dcb704f3fee47f2cbed65c1e3d06c8814e1b28abe29f3d056792efdf9ac9307ed0106c5a328721af0e202b6df737ec4d82143dd2505e103ad845863c45869e69abd9e02c7b6eaaff9e2e12bc188138688c0be3e6941c37c7ddc9b6d289f7cc8fde42bc3c14e3ee521635f32f54280d119ccedfc51090a0ad006b2427604014ea4d0e0cd1efbce09c7f8e9981f969aed6d481cafb329f995343541d36686de6cb8e4b1e7e3727abd5c1e3ffa6936ad44b926063561512c0e9ac787f8eb791f963f790ba1b21dfe1b8d31d4c16b152a6de65bf54ab0f0d1e3d450317b1cf0c4e331d18587accb6960ccd04dd":"574cca3bd87ec1994449da2f2324a3945fa3047791274367bac0f12d4c064343":"7fc9bab3505adcd1b1c8127e2d1fbcd0e15eaac314250dc1c684fcc47fda2993":"70f2007edd68fb9dfe19a63eee4d5a977291abd235ed26e4291476ca5d0c8171" + +Nist Vector 3072 SHA-256 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"c805d18c0bb53d32b57cb652f5b0e5293be492a1c88dfbec5baf47ee093e2df06918994e5cacbc3dfff229abd31fab7a95ade2fb53adaa7dff51f6c8581c69eb5b090baec38607ee9435447ad8137455b6ba179fc53ac094f97e3e29d0724cd10811f142d67d1cfcd5c3d1e9b411dac38f6e1c0c14dc9a50d84bcf00ece8a603":"3cc7e58577382500cb461c0ab8ff01ece8fa766b66f8be746e347ed2ebc18ebb":"2b6e1a8d4482b41697bbbe50b55b3dcdecea8d2e2eb5cf27b892bcbcabfb253c19486fa77c98c15add4149925b5501e5a5ef45b32ad09a872462a0f41d048af4e530660a3864937ba6a9eb0734e90fda3c9b6fcd30c9078771295a93802d9e1992a4eee9af7a0413880f33bc0b62036203286844bc384187ec51a33d390eaac0cc3328098a847509129bda735909fc7a11893ad0ec61276b7a5dcd4e626d9ba67610eaf0af876afc0419fa4f009aa5f913a1c73798c2707eeb8fa77f4ee058229a0ad37e845739668d95de226760898c02d06f155f82dc16360c3abca3780bcdb79446c8343583dc0f6925434b0dae7b59cb26b10008f86570ca0350de340b275524f00551310f1d095db8480b4acc489cf5e2947eb92904ebfd0d978bbfb5d0c6a1a9db50cc6917949c71854632b4408bade5195d40dcaf61fe950eff0c8997c374f1d465c80bc65adda636433e94f22c5fbcf09e99666a535919ee6f88154934f11377a9a9e021f2d7ecaba32510e92bf5ad67fa8b3d70dd2092b1389e3193":"179c02ec8f18fd88146120fcc51628f23e250ad694aa47bd691c0f442a63a92d":"38208c0985624bb9d62713bc7150942cbc92b8e8a36ef6d1ec4d08d1d9a5715f":"65d2ba787ed4c08beabf24343d06ed61872d6d684a3bc70307fcb7e20df931da" + +Nist Vector 3072 SHA-256 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"9e0c66a4f120e85aea064e7a8ba132cf30a45de2889f3547384e4e84f45b3572bb0423b834de9f2c9636faffdb6331924f0d2f5b6876145d9cae110ab0cf6fc90c2eeff98c61fa186cc3952b57299a73678f4585bb18fbb84ef4166779ff10eed14d47ae528e03298dbb97cf4f88b7e6d0959b5894550a3e2e356947d25ffe73":"5c5791dd648703f29099736146f5b1b5e35dc71a74d6eed312d37aeb6d389ef0":"a62adbdaa5a55a2d1e439b5489cd6c8fcb23e9c64fbfae7c83e9d5599319bf3f06c3c290b989a638940b1d0b7e8bf6741319ab4c38d46e77ebd4945e25cb89cbb64e44b9474bc7c9d9f61a36e57eb6afab6c7a149afe02c1cd685483208c55feecb0d0bd96697b437991059267d76a488465faab4a7e17592329567005faa421e011d67f4da75accb627537e933e9ef0be3c70f21ed3f8c3b3d7d769bb611f82f2baa10fbc7313ad0819048d353d679736c4d14bca9985ecd37041afffb291a7d909c7458181d01592e6c90c0e34b49461ede66c5ac002671a4985546a6075df95b523f166d2e0d1f5da77baff5a24df775cc9d367f2a0728c4802d797041788c56cb871290332c1361f8da8897b5b8e25d4a93594ac648bc53c9d85b4fcdd7ab0f5a3ee9c25cc14ba6543b078859524ec7f0b61cdb209cc51c40aa9af082ea9c1d4b91b2c1f6dc11cd879fb3865d879fe000f0e0b4b233dbd01c9c98d01a664746577a64bf28d88256b76de2babf14961113733b1bb555325c09d8ec9189fca":"8327daa2fbd001858dea53d2dc0cb005e0ae5fb15bebc0c5efd33371637ef318":"4e35f586fad4f512863c485ec61ed01629aa1399b16fef4d80cb332752b1da92":"262dfe6ac72a2f6044f62698e42dd2f92b1f9a91be42b5fdd293b1bf9a145f00" + +Nist Vector 3072 SHA-256 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"ed88d7076c5f6a5e0f947543d5fe746afca9b2c4d06655da4607685c799c210be4aaee0e6ed19713814182c7f7d584ddbed488c8e3239ddd810555ad6316d1db37fd9553ad74e3ceef9eeefaf54563602f5547aad4161e9384edab655a898416db53f71237ac5a1485711182bc5bfff72460252784ab1bba23634a36be77533f":"22b44bd6d23ee65ebc2e88030f837ef65593eeef0966239a92d5126cde867a13":"3e1ce8780f39444c2130dbf9d80ca4b25817dc16d08e2cdaca0b56cd2abdb9ef5adb741ccc1abecf62806ad7e87636f52831c6dea48e0729b904e5a0615d7ab4450104208a5ddfdb2f2569146ee83ac9aa27b4d066355fc53dc1a3683211ad3efad1ae69b8a7737bbd89f5ff48482e2c56edaa776e43b2a0ba62e513862da290288f07f84ca5a06837d19e9b186dc8d36952966e08f7213340186d31fd41a2d1455a083aee62127a28dfe4da6c876a5a6f36c45245dee6f6566b8318d3d01943b2adf8ce94ea01a01ba41a6e286820a96707cbd4002875b79d9fe2db6cc3f808ef0f71380ea9a73fc7e36850d022ffac131636367886a6e9965759d73f03ace69704b52144f67b678e2fa201c19bb37b00377daabc9377adcbddea2816cbb50b26ad2e429ea0576e7721b3b75c4fedb31fdf1f0c6c2eaa135f52c9a97f0df5fb25ef28848bdd7390cd054003722582d94e90a3bbe85beb34701271b4bb48bdf9b3d0e1bb5623445c7828c937a423be512c1177c9c0b5b0b6b0e1f639d330e051":"0c37eecd48682f897accf43b3e4a538cccdfd784625a6cc046dc54b093d16162":"2e7cb404a6daaa8e00760dafc95b4eb5545683224a61a1bcd6128bc4e7ac535e":"3a70b3a97e06e63b89d56ed5232346461c1a3b6b145d89043a48d666de0256d5" + +Nist Vector 3072 SHA-256 #16 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"9e440052ed927321948388776d3719be068739dc2d6c64c5937176b2005c2d70a9389e6a655663366c0970a8e2e3117ecef257e951ac81c0731dfcd4fbdb1241bc249adde9cb398c7d15e381368ad3d24edee23397c15a5a356e787d8f2fe9be76260bd363e17006281c199fe5b710f9dfcac52895e392f7384d71bb83053ffc":"680883caf23665e813572c1e4230218edf53b3a5167f56a7d80e53e7d3ad1df9":"89e859fc63a263bcc051bc2ef58cc919ee537385cb3636d83a624a4230d4b0024ec5e28bcb884667cd2bf8c28451b64de097f2194cbb8c6e1cecbd6f9fbd576481555d0f0e8f13752f2472f7619d052318424310f69d50de78ad6c457b98c611f8481d4543031a73f83d1e852c1f2038a6435e571f776bbb5cf978a9b2c88f05d134fd5ff4656a69d6fe6b667da6da54be48386250394c75b495689fd4628f666424eb080094448d41b706292e51e75386543e5fcce6a6f3aac03a7d6d5c2551ca6b5b85fadc86bff14c79a1602fb0c1d43d88d5679021e826062ecf186aaaaefc312eab9f9e2da120a8d7d08ba09aa9abf4e34f6d88c4c314c59c36ba57f928d88d5d70fe48ac6700f5cf607a55e3646dd03d47e96ad869f7ba2bcc7d65a99c3221d4909d1f22e4ccba815fa5b720570e42f8626c31d99f60cd6a015391fab3537446f747c0111293c5bd6b5dab2bc3d5137d2124029eed12db71bdf794de1a2ec5070d83f87195264ff09cb48cddb5e852b233570f1b70cd457cf864e2ef3b":"69e6cb5bcf8cae88c96e464a9b26c6e1bbac1e229909e27542278a50c66959f1":"37c34f9cce916df3deff26be08a4e6bbae0661fbbb5d81d6039f00b1e5632b67":"3f4a2932917e6bb088599a269d7b590769acf9807dc5a9420a95e12c7364c5fa" + +Nist Vector 3072 SHA-384 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"ed9a64d3109ef8a9292956b946873ca4bd887ce624b81be81b82c69c67aaddf5655f70fe4768114db2834c71787f858e5165da1a7fa961d855ad7e5bc4b7be31b97dbe770798ef7966152b14b86ae35625a28aee5663b9ef3067cbdfbabd87197e5c842d3092eb88dca57c6c8ad4c00a19ddf2e1967b59bd06ccaef933bc28e7":"6d4c934391b7f6fb6e19e3141f8c0018ef5726118a11064358c7d35b37737377":"1f0a5c75e7985d6e70e4fbfda51a10b925f6accb600d7c6510db90ec367b93bb069bd286e8f979b22ef0702f717a8755c18309c87dae3fe82cc3dc8f4b7aa3d5f3876f4d4b3eb68bfe910c43076d6cd0d39fc88dde78f09480db55234e6c8ca59fe2700efec04feee6b4e8ee2413721858be7190dbe905f456edcab55b2dc2916dc1e8731988d9ef8b619abcf8955aa960ef02b3f02a8dc649369222af50f1338ed28d667f3f10cae2a3c28a3c1d08df639c81ada13c8fd198c6dae3d62a3fe9f04c985c65f610c06cb8faea68edb80de6cf07a8e89c00218185a952b23572e34df07ce5b4261e5de427eb503ee1baf5992db6d438b47434c40c22657bc163e7953fa33eff39dc2734607039aadd6ac27e4367131041f845ffa1a13f556bfba2307a5c78f2ccf11298c762e08871968e48dc3d1569d09965cd09da43cf0309a16af1e20fee7da3dc21b364c4615cd5123fa5f9b23cfc4ffd9cfdcea670623840b062d4648d2eba786ad3f7ae337a4284324ace236f9f7174fbf442b99043002f":"40b5cc685c3d1f59072228af9551683b5b8c8ff65240114ad2dacfccf3928057":"7695698a14755db4206e850b4f5f19c540b07d07e08aac591e20081646e6eedc":"3dae01154ecff7b19007a953f185f0663ef7f2537f0b15e04fb343c961f36de2" + +Nist Vector 3072 SHA-384 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"4bfd28a0a79c94dbd667c275ef77a235d8ead7c698d42fb7f7c1fd3c8c2dc48d0dda2408dea56325d69283692a523d281ffea856ffd9f8417eafbea606d862dc5897bdf241f3e8e49aded5eadc7295e5afbf96b3975d0e25daa2433612e120f659036b807c1853c03c90fade2c19dcd923492ecc906cafc57a95da6f20dd59d6":"95fded7e5e949602c1123d80f89503cc5fb7454be3173af495a18709c1c2506e":"6c778bcb146582277633931bfd029e69c9e8c0ae9e24913fa734554f24f64aa64fd9bc608ef677a1d4829aa8a8564c2ff0ffa2fa6a0c1a2ccb606dda018bf095f8c897d7a43349beb9807b7b118f8de8856b164b8d8babdc17b48f3a2b972ce537ab4e7a7d9ba5d7e6fa3698aca91973cd1787ef7b6b4d0410de59cd3143e0f3acfdaabe56b371b4354d0d32dbd1b5ca6a872054f3e6566319d5d50b2cf54c123ffc929007ad1857ba13b7c403f551c2fa4109c44e19ef97afb62a6103356fcc2ef451e736261010b0ef58ae07a0c801ff75ebaf6cdd763f8df2f83f0ebbda40845b2f42d3feeac071fc626ee5b51f9bc1a130514f2204971b4b7261b4bd783ff75775aa73a63d7ebe990b939b0f44a909ec390036f297c3563f64d142c14ea43c5d3c6def4a3a9ccf6274182b939b886501aeb4efb23d0073434cec6a915a67e24cbb2354c9bb1089af487eab5d8e499a632e6c61492ea15d2c444c269de33271a90042468de2767f0dcf7a66424a3a40a63eebd19cb89c8d74c58504c4e103":"6bd1eede564ecb1b3fbbf2d96e334ab4cc002e6624e2cb8448d8608fe0e8c43b":"37c3f7556d6e5acf7989f0baa770c2450deebd4d5f58b61e17b4b2b926b58031":"a61d86365f10ca5e1ee2c4bf276f2374e88b5a2d1acd8ecc11e97785b4fd9931" + +Nist Vector 3072 SHA-384 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"e3fc751b6978fcf40f09606ee4263e1660ff20e9c63a7138f078ae3e3e603dfcad172f3c7cb3f3545fc23bc30c37c8439c7b238341f29148276ea2122ea8ed0feacb149de17cfd33b8c9408aee8ab0ea8ba4a2b2ea237418bc3165369c8cd420242f8d32bcabe0c352e21f65de80d587ba2713cea6e53ca524aec365bdf21adc":"3a09006faedec91446995a393b034b0c7ff3fcd05cda2e9e3b2f98e3a4bbb9f5":"1349bbf16d375c392a9acd5bdce655f14d616274388a45cd372925c507ac129fe61b998e25127f210926ad1191583eee8c4190026ba0a95894be3f0ad5d05886c59a3c7a0044f7e2bd9bbe28bf9366d034db424f34960e30a8e7888f927d0bf984b0ff99ea271871124aa12e0c0e19624e533cb4149cedb3e11d321600dc07b32e531a615c8f7fd7f33a071caaa76433d1aab0b710fa7ba3ddb0175ced4e558d5117afc7542b9b07a8fe8e4b08a1de456443553fe87a4c2455ded72f98544d6c41d6ef66b7142a4aa9aa1d3d20f700010389e417840782fad682153d569f944d3d3ad1d88db5bfba3499e4c3660b76b44da4b0e6727ebc3f22b2a0aaf62dc2a29db8babcacc2169c2b8674054c89fd770db98b12af2d933becbeca9f22444b527aa894b3765292dcffaf3408e699495df79b98d957fdba7e4c8e7ace3f987a95dcb2e777fa2d1304479a6d137efcb0c404e6d8ed39d6afba2549f3ee2b9a45f324567c0227319dc59bcadfcfdf1566f356f7c2ba6db21cca2a8fb2fbeaf31cb7":"4212971feb32e25fbb22845ab8c9333cb2a265f003542838a128a25108a88365":"2d3f3c605eca8fec37a76d606d20fde89cb6f971a44796095a01dcf8e900f5b2":"6a43168334e5b0ea07cfa5978609e86f969d1005528ebb3ee9073d5655d54b44" + +Nist Vector 3072 SHA-384 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"45f656a1ef0e61de46df2ca2d8ea26640a994c30380c0cfd66be3998d89849161bbcf3bee77ad30e769f10e23aad5b4df4edc19a86fbb5abdeec8779b76be279532d7692bc586c62692fa1e3dbcce33ffddc9f97589172f64a48535693ded6bc73b2ca32469d0eaf6706d2a5f58f8d28a745dc328bcc75b3415ca93e29eabb1e":"9f35b1038686bde07a5f517d68f562739cb7150fa47ebaf7ffd29306afd4688a":"31a989601f32b205943a841887df3c6814cfb2258e5204d04d3928ddfaba0dffad43151e27d666d2928bedc67275440fb502ed3eafc3adc11009ee703f01eaa034aa724fcc63c59a8a5963f3352f7293ea2425ea89bbf1e41724b69f383bf10a973146ed02f55208b04833d1bb5399a67f04081590acfcfbb12105423e26091d09078c45007d436eb19f952f8798b001a3c64a3baa5496c9dbe6580781d4020bb7e4e7ae2380ce79658c10a2e57bbb8cac12087728ce43ba2b9f380e3abc2dd12a682488c6b4fb2f8dd7f3846b6a26f913ac156879ee6a1ae0ada9568521a4428ed9f741e0e79a842880019c01b34e988a7cf7e63524e8cd025453223a2660273e491968af7f4b1dc2123961de3753ab16eca5b1859a4f71172538f05a2a82a34f98ba07c1e531d82ef592e5493533416bd6c6a4c7ca3b0d2a2fff88a8f073a76c691802aaaece4e852d6650871a17cca0f5251ef22dfc8e3b261bfcbd5a22b2732aa17d7df1f7b82f6b222e5f6065bf80d04c2e5774094084e4d5ce0d3e8917":"55d1ffc73b52b6364d660fa4658a6351142ac538fd3cfb4eec40ba07bef5418b":"3ced0ea5f7fd588668a41efe0e90954c0930afb6be18d90752831f683cd92a9c":"9e46ca12941745ea1a12c5a2d609884cb5792f46afaacff07237137400366868" + +Nist Vector 3072 SHA-384 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"c737d5ae248a96062d6afa8dcacc0384c5fbfb9d8b6052b52493c60d3edfc524b567b1f896e7447d0e24019403ed83e4889c0c4de57c70fada6c8b5a09904350a44dfaf77d60af62de3edfd8760d077473f26df2837cfc2015f227dd7d351a5350f1428f2699fd3f518326fea8aef98fc4ea673130c8079fac3895fe856c77f8":"40dbd496fc4644be7ccb24d9dc55895c1b923a05f4da5610589d564ee8aac33f":"6112d3cd3191d17dee7788f568815a0aab50006002c9de2bd1a9bba245ba02894b02e9247517ace698ae0a05176b62b3a025a563dda8deb7f2fc3e177ae3477448d39ae4ebe7ae8ec65a4421f754667fd6d7c2eb93f1a18d3d1a6235736bcdb74746f46d88e65dc07c2591e1f95dda5e5e20e105ee8b4ddcaaf36021290d6b6493671d8aafae145d9b90bec3cc60179bb8fc30f143c575d5d861623721b6547d3aaaade455f05fef9318abcd29bd19b12c35ca756de5108c185ece4aa1bf1a8e38809797067bd1f52b6cf2c415e73f9246bd5bfadd7b9a9d2b5369701e72147e22da7e092d9b578fb0c044a36effcbd709258500a00cff230962c44225712fc43f9e802baead7f9cb46ab4931f663c6e3ed4082d59610f01741b5f24566b01b3e3933b29e028c54bd2fc75b549fd05e64c58c9ae0ba417a9e98581db77be75233a42f771c99f0a49b494f0955202b19d6c740e866066104e463e65e4bad9a081636d05367426153f04bcb2712186dca6834388e82520d34efd8a89313b2c7e60":"aa63e91cb3fa545c447a8b8309a569d48104e14d5d05b8951033ac8a7d711c3f":"0041b1c756dd2e42714f9ee7edce21ea33ef49dbf452ccd9357d5f45ffab08f9":"102c6eaad38d39c0d036335ae19dd0d75e8dcabae59b120f69cbd2b5cf48abdb" + +Nist Vector 3072 SHA-384 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"a6fc89a223022ee9e508725278582f56db9cd24c0d75d072a528d0c60f27171ea376e2dc28a9dc0b12e668af77dcbb381737e1ba7d9e80b9bec80bf9061b8fa10e43a7403a291624a600dd4f5c2b50c52d5c6155d52be5a325f6ad813fb3ecaf6d1f92e98cc87c26c68cbd15d548a3782bffdd1116c7c11fcabde4025fec5154":"1b41c29364947768876ad4e7abcae59c8e61373d25274ba42ceb3d876d6ce672":"6c1d4d6b52aa4bff35f4302330052777f51f6a0849161f906ef217b04b18545ce52ae4ae423ad1b4f8b1735ae00ab0c044a56f945da84d1cdc26e082d7acd772dfabcd18b5e13c05c2791a8dc16146e151323e4ef2ce5d64389f69d9347aa2a5bd0114de0eecdf990a440d1bf9890dd95fd640d2fb1789ca6a6dbee1836ad7cb47370b7456e49f3bac03310f8cbe61dd1cc06d78c76fec6397e608a4cac4e2c38983ce5aa9dcba074a206fa608db35f2ad3d63d95b2cb7a01c33d498767e8e68578e4e99538bf3d703e63863a25091452e73b96a3716e9cc109b66008fa5cafdbf96b7fc10c3bb89d79d45ffefc01908d247ef1d4fcb903bf5e7917af88618a52a12004798890540a5a75c65fbc057d860f4b65d8b08b8d215f056d8e5e38bf0b319e294db242a4fc79b2e106feca2556d146f5203fd72adc73a48e3a5aadbb293a2ef5862654c31539ad856a16e5716c437b474f3339cd84f0ac92bc2ca6fac10c751d099a90408def6106ca83893d87e32818d7634537a4ef667ce7f26a5cb":"4c9ace2c908648032151f638e3c909d1f0646fe018a1c9c22a170eff64447fbe":"48bd010c1af77b3c40db50349706d64d16cbb72db51943d345151deacd4a4133":"0f1c4bdb4758ab3b5518d4605b9864805723d33a36116ea650546feef11c4a5e" + +Nist Vector 3072 SHA-384 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"2ae4ac7ce29ae7d32490d3a54b715db3f47306f84b59b33b21622a18aa2c060a4434adfa01ff1686b5d1dd3035308e92f7acc76dea969deefb98c2972b42a596e1055a5aa2c661f0b734ba4f0b341c77827d88915a5e89f95a98d63d7729874fce4ff75d7add74f4313dff784e417b2ee1fcd270c038dbbbb96a7768484b8854":"87980da0684558f87e5864ae585864625aed61b1309c1d5f30f6477f947c44fb":"0a84298f4768e9d7bf796d06585e8b75fbde658398a224a8ac3a49fb91235eaaa183aa8827cc2af79ea334dc8be4cc729029ab5f8161f718f7bfbe90ad2a159888523982b6d4932d8159495ba84d0ab35d7e395d14dba906a1679ae3cbb72c10ed6fa14da4d60077b0bfb591a3dec643996c396338a51d446bde6224aea16aef41f354e09a9dce9f3a00cb445a5c9cae4a6c3c1919c9e0c53082173d0ec00ae5e15aa7260750b6a03ef05a518a48615340ac20984073cea5fc990d489858949aaf6e9e347b4802afbe25a0669472bd9316ba2c23a61cc3aadf1b70d9fd9761bb035f0ca51edb2b12fcfd651cb92363ef48005a2683fd2ed8665d70588fd9a1be3aa51c958b81f13e4acfaf0d2a90aaaef21b2cc9ef2ed37bce3c47c8bcbfc1fb9f94e49bd2f1a30a88df22735a0fdf0ac6028a008b062c9560c42a476997dd21100692ef6396d5f3fb2c155328257e7b7d2bc05fabd54a81a2272993d342bec8577c64d51b4cdbe3654dae568c4da018618c3047aee06bf2621e056b335d044b":"25b9d8fbe7e3ab7017f2b1e53da579df460dfb72ba5fe4ae4c85b8c23472bc8c":"6b7ed3a4c2a4f78500c7e947e6175c5ca857c9d613e7790b9be0d14ec8403e5f":"a116f3de166260d110e20e84eb8c97c3f018178608a2ea3e3e2f5ed91d43de11" + +Nist Vector 3072 SHA-384 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"3eade9a10fb59af36a540170737fbc536e4c5230b8f6c4b216eddd3ea92342123a3374d0c751b24b627f9ead4de26e9a7897d9bc5d58a6a3ac74cd4575b3286ec15f8453224f37179e51d9c4ad8a60bf37d71c62ad7fc53e5c7b12f4aaa2d428e5c889fd7f062c913d9b574f4b5db516c976bad588302f219fd83e18bee8e68e":"6cf453178db0dd7f2f94f9a1f518c622c1ddee46d4b090462812e9f7b862265b":"08a15b2384dff4f3033c87168673c567059870c8e78d2fddc7540afda8058df384d3182a42615432ff93777d3fce49c117c7bbe821e6789b5137ddf084656098aa7b0516fd30a42c8c86d94e6b268b6e13011d25eba018ca40cf8a35e1963135d5cd65a57aca8b007988a5ea75adb4d01cc0f0838ab42d3df643a7d2561cfd1fdebe3ad86ad03de317027533d523351be532bc731aaf43b8642a7da80873b80dc61b7a249e5860fd1a3eae0f8f0cf21e205d6f403cb0a103290c9e69d38cbed9e092b69f71f9172b3676f29a97133fc3e18746fedc653fbfb62c5e0afe89a8e1b8724b1a3314c4cacc4bb8f390439701a614ae9bcdafd472b0ab131667dbbf1c790f73ab9046a58932691a930b3c42e908b4d1f47ed6e2ff18d6b70bb16d1af7993bdb2ca3cb359a0b43f8dc844dea6aebaa34b8d2b6fc288419780ff980908926c46c3b0e595fa308f4e894ecb683c804c93140d91769132d37e93791b9f89d595e698f049b3a9502abc488bdd9472f1131a757f3d54b149067507d1b04a976":"a3fb61e544d59206d334049e8554d97b6699db616871fd2b421229c28e84f73c":"9e833ec3ded9d81ea7422bdac78422274fa35348e3fce3bbc93b3c10d70b4f1e":"653756594eac681d48a2358a0f82a10faa7929b00fd9cd4394c32679060f96e3" + +Nist Vector 3072 SHA-384 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"33decfc1e06b92ed81cd30ee3771470b59e22c1564647f1aae8510729715a8ce94624a11554ac909c924aec853df64327546db85d3df597916a39353388a8b3363765281a4352701ff1af43fba6d03664127c15da7b84c04d5409c364094dc62e37983a8eb066880de8136701406e67250679300d2b97d228327c1514c0bc1ea":"3bf2be01d154c23ccae92ae93f78ea36f70efcf7fb7eb43cdcaeb9ffb8471b10":"16ea2e795c636c9d312159a579b8df329ffc28fecc4a4c13b16a290bd1525a53a97d72315be251d11d23ca78bbec45c0e243279b1eb6e206a9273c1e766e213648bdf90c40479df48acfd9c209a523c8b4a99a481ca8df4774b3bb29f82526520c2dc28ab314fe14140f2be1792e1ac3c759ad44f7845a2012f64ecab0b1fec0ed166bd175955704f62d9401111ffc04f804e48fe774dfd346bb41f4beca2b34a83134a3884a01729cce1abc5b8d0de3fe2654c374deb246d96ffaffc7aa2055b74e819bbeec137eb3caed1fc71f129c8ea8b763f2f57e88de0845f76ceb1841559019872a5b5a969c9cf385d6578b4f27b5b76be3ef0a8fd3ee47eed695e16f14e2a3b791f2a016d6b86ff8ec2343c6a5c80ab6224b6502eb374c8fa6510bce990d70efdfa9a0b702585595184514c78f7e905b6fd6c237333d560fcc06303637ac0b2c7f7c4da559e31f531df2e5d6c651591771d7ea4575888afc4011fa1124fbd1a282a41d933989eff91a51cd39bce7fb0d569fedcc42de48bf18ee755f":"a0c97f80ca449fd8f69733e046664408da590dbbab6865c3275c389a478aa248":"6f77a52169a2e880a3b55aa278f6463032dc5f81c38468224d5532f6a601f2d9":"96b753efb4abbc8c179d03cc2a1a0c1256e23d1fa2e97cfbf55d2bb69812d100" + +Nist Vector 3072 SHA-384 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"6ae5a6da794f923f6d8032549b81d04ae7aa35c2099dffbdd83bb94db574faf8f95c7126db2db60fed50f740e87c359544dc2ebfbcafb094ddca69c914d27e5f3d10fa0ce32d2a1355bcf61a2574c755d7c324a2e0ed6f7719ba2f2c9f113df8d04025f4abd2e1c4b7bc18d8acec9f6d8d797cd7b042f50348eeb3f7a2922da7":"3b4a52c8b5c386f26ac6ffabcef2df3bf8b25e6108ab540d314dd3d9245c075d":"93106fb000c67f1111c6fd3da0f44b4ae4cb3695de2e35b241dfe88d3269b8fda25bf348008725fd613cd61aa826bd8f1aaaee22b4dc0a02842290bb7dad91af0b2854ffab16932208d272f2c081c13889db3ed0b24646c665af9f4b723898eb1ac0053f2a0f4cf22fd4e12940b5b52269484ebb8abc484c06eddbd9b1a426132f402efdcd88ab29e7e510961af8ec83a642e34015858ac3f32197601a888e16c759c94ec5b8dec0da30643b9d9db2574af29e78f9d3f6a7b4c76f45cd0b2ab5e8524935b886918b5d9e9ccb5a6853e62efad2dff83a8520985ee8442f2bdd1c5f9d48062ade6b288c8ad82a41db6c34e2deba541aaac3cd3156c975efbbc718ebd4961996b3ed1cc5c2987ab779052cdbecf51d17661b498e84371ff859f89906f426f563572f66c279ef3d036a427778463f67f8d4de623fb4b2803007871d0a349ec202a9aa1cffef70137e009303497214ada786357a4d8046255e40f89ea588000634e7f0aaf64d92aa21fff8fbe078baa96961699738b268237eab606c":"39f68875cade6ae208d3043b010541624679df649cc5d97b09a3ebbe2c9d59be":"8636d4d3203aa0912fbfc938be4370077ea9c75195cd2f67e6ee427cde531c40":"93023d97efb4327e9e886e7b783741e9d2c397af9c67b91cdb8aa27f83bb025d" + +Nist Vector 3072 SHA-384 #11 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"86e03bc3f4ddea6a93888ee389b15eb690822c71f9b85efaaffc52e486b1144ad7fcff3f53bf97da2481e85e0983ee1d5279e27a364d0e690f587a31535fb94eece747f8b605724adfb258c9983c9002e0c11b7976627690d58281305ea9308db74c491a28192e354b600e8376811ccefb751bb10c7d97b42ffe304bee97ecaf":"7f56c74b495a12db963e03cfafe60ac95e8019cb212c332d1f19c64615568119":"23ed5445391a5bb94e00c76ec80d83728d5d461be425da79f921bca27d625cb42b323971022ad4c3f05bca109910fd06ba39e95bebe794ed108d2ead297ad794f99c32c219e65fb726532715b1bc2075dd4b6949297712f91d5ba061196fb25754c34377bbbe6a37f61787ea844d359285c78e733eb65f665a6b157f832b5638d74ebe1d5dce66d528925e44eef13bf23f807da35f34d169a687758229b99a313acecfb20b142b534926d59aaa7643a79030e9335ef28abeddac8ac9471da4997e33f3e491db8668a2c3920a3b3a37225179361d5539beb33f3252244267465e48faf575cdac938133effe9d1f69f19f1b44b245a447b1fc2b859244e2e39053595cf7978933c3d468c65c231663070aeaf2ec23138d1660081a55bdc3dd3f2446176b1d6d9977a14ebd0ed4d8dfcdfc4a433118401f2c2632095ce7ae6200c74bda5d2fd3854524c3081741975a076a1b4f933ec32a2bac9171bebfdf3b355eddb1f455ecaf73396e85fb04797558ba4f2bbc49d9f2329a23b393301ae0db92":"407180cc311aebdc1cdcb4685241597783f34076672362a24a21193c0d45d24d":"68efaa05eb90c48c6a7a45337c29175f8ee5b19b53db4ebd83a02f53c5b2104b":"145f13f1ae3675c521b334ce6a49fc6f502e3ac6b2b5143be0641d0d57b3c722" + +Nist Vector 3072 SHA-384 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"1d0954ee0de1e9ceee0532597ee434c73fe4f66635f7e72d38b67763c66817f53cf36ca0f613e01896cebc9f77a772607f4aeedd3856c73fc2f19100aa7b540ccd057f26cd9564d673228c68088e5f1abf1254a97ed1453ee558e062711ceb7643b345ad33b649affbe8a62067f9d84ed4c8506fcff578d2eba596a205267387":"0b48499625f0c2548bf8a2fed1f6696f59df8fbe6eaf91b82385994209c2d04f":"2f0d89ac78a61fb74f81142b17766656d1788940077808e3d880ce10ec60e2bbb158d54e020dbc5f6786c0b43cca2cb002c8ce13b291b250f399e8e02f195926978f6c5b007d4f0a66048996a9932a918b2363c4008f547adcaa7d12694baee4fbca34bc6d7e29c5049cda13698fcce61bd3b3db05d2158132dd380cf653cccdf279aa164134bfbddd7ea347760041f92c3a4cfde0092d5cb96bb8c24e98259475596f3377d59f11661bcc0d47e83cb31aae9dcb4a6f25619a29054b62aa8b421e529e61ac95a0de01c50b09e119516c2c5b3563d47eed679a1cf80ba70a50254d851a13a778e1a08da8667e46e35979c15df45cf7886dde5af9d744624b981acd252ec5ba46870b8ee4b32b1be1b944802d91d8148d38f54315a7ad4e38079ea2bed9df8fa59414ddded3a1d2308ba769ae2a652f10c2d96917edfe5874885f3c99d6912f69ae3fc3b4de82decc30edc9314f7ec9e567b7e00de21959486a887d74a5b2180293df5dbeae1e35a6e937b2506d205092cc4c3595db92fc255af5":"1c020abb0e1d52b3ad95467f7baaf665e2281f34c342401ef1fb4c1fc2d7b2bd":"a67210341a04cd3a4b63ebc7e6208f37e487a8c6f1134cd2601b844d6903203f":"6b972c622cab48d85a2dde355f947a8151a17a0acf06b7f3659f868d5ece92d9" + +Nist Vector 3072 SHA-384 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"14f566c5fe44aaad6e8b3c627570aabdd4efb7fcfa1ab1bb74f2c6d8795e88233dac4e7d240abd5e9bbd8e1fb03a3bf50c0ca92c9aef1894f2aed600fc5873d23451d3204d75ab9581cbcf82ae8c0df0dfbd3a1f149f70660865726cdc73c015d5ddbf7513eedcd1ef17578d2719fea1e5ba39aef3fa6f00846f0fb8d9a1a436":"7928d3edc11a890fe332c0d3759bc6ecb822438d7f604da76b4fd78590720ddb":"a36a333900035d3453139b28356bf0124e571f55a5e4259b8b2ee1457cc3588056d6c6a645d422cac72474c5901d0a7f410df7f9b4e22f8684867d9332e2d4266a6e595e515becff7fb94d21a8a9ad7211572e44ce8448317b34c3c0b89b3097ab2ec134ec7c178c2278309cf9152b223bb937e68682f1f680c17ee59ecd0698a05c24c135d2b0238e71f807e079f175e11671308f5bd9e5a69712a9c508b3b50925d1276d552bda51cef3bd0fbd00a9d2dddf0e5ecb6b328378ea637b493846480ed75a3152d9e6a4884eebad12b07cad8d101b3d001bc99fb1eee4e98fd6fc920cb5765ec24e62abd32f975a47d50f61553e1c14775193b53b05b7d02024aace818ab659d717d11deacc9877b818a51689d239b60f7f9ed4caf7325ac0b31b316c036599ea66959d525fd16f5c1a2a809f2866ee9e99f6d8a3c42b58d33d0e5d38055c55c7bccdef310ccd3426207dbbc60faf9f2a219ab367ce84623b81104822e2c77ec5b133ce7050caed090946c1f1355d878a1317de694e686c62ffdf":"01f77e5f125a9a1385349f77d7a32f26b1efa5b0a5d4a212753bb54d300d088e":"12b40bd1c866ce38e7da0764d807ae82512b33b51dc908e5a5b3d7c16f0d08a5":"5caccee2bc85e28d506a9bc6d260dbd08205b75d20690e26aa6bed30d7327099" + +Nist Vector 3072 SHA-384 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"60c29d99753d0847bb52e906c862a1b0628496416c14df5dcfbb5e2804f502cb0a2d163e9bc2d84122c0b3f5d0609b82ac16aa15efd55f55c8caa3d1114ac0cb83e5ff3db12a24b89aca5f0514d2ceb09b14fa916000c0f4deb016db755e88b326172144e4f1a705a800559b3da3c27af55cb32b1147460c31186d99dc1cf2e5":"3dd64db4bd8e28e701235ad83a5d5e9dd13ee8a3b3dcb4c99c1bc95b6ae25291":"a37397e6eafbdcf1e0158f1f4ea1cb3a1ebd739c8559a500def3b7551799d652b327101cfea0b87016db591522b9b34ed267132c5255e77653c4eb935ce0c822b4b10a5e8f3cce39ad1b9606de5be2b2d36e1c5411f06aba0461ea8dc48b649f108eba88def44daa2a5c653dccf1d8ae29205dd5c340e34b7bd698eccdcd345bd4aa5eee3c08b9162ca1804872de3c575d572f34dd48b41f8235d0f511c8dc65daeb07095c3b5dbd3a076f8eb24412f3621f492126737a9d73014defa5f5d57bdc6faf53142eb191606f2fd3dc035f4b8ae84d655cb6daaaf889005c3c334ffd7e3b0498fae2a6f8dc1bc62f3704c8f8c005c8019e0bf45b7aa8e0803b93a992675e381f61a898582950b9ce40e7cdb0300f4b26f9b44484e89c9234179b60a372fe9476f84de0ed4b93497216fb96bae43297dcdc8496c634100cf066402c7d290a7cd28cbcf8b08ad4c136db2fe992ffa045bf8cb249234f29a674762a56d20897ea5538c674a14353db64ba60fe4052a0528eb0b25887e3c5ea69b41f68b3":"453b64f2dedfeb1419b5dbeb726a2c92b1a37ef11a7732c911d9a96184285f40":"72cf0e18e4bc3749647cdfa62dcbd2513c7c2b1d397c1fcbc7f6a425ebb897ce":"7b7d0a9e93340941bb55f6afa6cd63f7364963671008ede457d05b6545fab1f1" + +Nist Vector 3072 SHA-384 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"b3dea62a20a9ed9da990465bebe18aa71f08f93fbaee4fe5d581ffaa6fd55cbe272a115d7fa18fb9cf5662f595b7cb9bdb97a81bdc078ee3bdceb2c03722610134c3bbfd7a6f8b79ecc6a9a7709265687f9c236fc68b02203ba666e9eced5161de90c110ee7af9bf54d84a22181f17b4329348bdeefbb324962e63569f07c285":"6327d3818c87e4c99b7e5116fc091a9da1e4c02aab9b207d61e859dda8d859ed":"45013318b941a710b8ab1010d818c3103634658d2e3e2f413165860805e08d5c1e80add9969a3d3a0d23432c8a48cce836b24a410892099bbf53cc5a84a95e1eb3b682d2754e721efc86d3f4248baa337d6f6e5dac4759b296165918a71b31ced25bf1b05d675bfa222980608fda8f9d0eba9aa08475512d04c612133c88253bf3e27e9ffe3a8570be204f54bf8ff1c7fe42aece832050aabdd9415764b8c872697f9c8e78e2f56bd235ebbbb4b9cf8f054b60292963764536d6fd4c6cfaa1baea53546c6ffb56a04fbfaee001228280aec40e66d9dc192f9ba743bd3ffc0eaf277b6ba3d33c3697024892b0b35419534873fb7a3d594dd6ae0751a2fa430ba46237f4a55e4a678072c651fe6ad314a010fdfe8f8b5342bdabe9ae5910c6f44a51f47524a6fe8216830ccaeded26ce1f13f7f216e0b7809e9272563cab3352b8ed766650227bfe16e981b505609c41f03dca98e219d02aa7d91921edb3a89229e78c30161cc13973b35de3c87779378b8d607a19320405661312432dd8d07af2":"94a0f6f58f004e45ce5ffffa6e63abca8daf7768cdafd517f3a5e399828b1e72":"3ec677e91c63e65aaa174aee2791dc409244cb80c0220991dcb497397a3c5e9b":"1de0ec466b2ad4ed1adce3bc38ee521803dc87085e2fbfc561d63844c1a9a2e6" + +Nist Vector 3072 SHA-512 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"494180eed0951371bbaf0a850ef13679df49c1f13fe3770b6c13285bf3ad93dc4ab018aab9139d74200808e9c55bf88300324cc697efeaa641d37f3acf72d8c97bff0182a35b940150c98a03ef41a3e1487440c923a988e53ca3ce883a2fb532bb7441c122f1dc2f9d0b0bc07f26ba29a35cdf0da846a9d8eab405cbf8c8e77f":"150b5c51ea6402276bc912322f0404f6d57ff7d32afcaa83b6dfde11abb48181":"6da54f2b0ddb4dcce2da1edfa16ba84953d8429ce60cd111a5c65edcf7ba5b8d9387ab6881c24880b2afbdb437e9ed7ffb8e96beca7ea80d1d90f24d546112629df5c9e9661742cc872fdb3d409bc77b75b17c7e6cfff86261071c4b5c9f9898be1e9e27349b933c34fb345685f8fc6c12470d124cecf51b5d5adbf5e7a2490f8d67aac53a82ed6a2110686cf631c348bcbc4cf156f3a6980163e2feca72a45f6b3d68c10e5a2283b470b7292674490383f75fa26ccf93c0e1c8d0628ca35f2f3d9b6876505d118988957237a2fc8051cb47b410e8b7a619e73b1350a9f6a260c5f16841e7c4db53d8eaa0b4708d62f95b2a72e2f04ca14647bca6b5e3ee707fcdf758b925eb8d4e6ace4fc7443c9bc5819ff9e555be098aa055066828e21b818fedc3aac517a0ee8f9060bd86e0d4cce212ab6a3a243c5ec0274563353ca7103af085e8f41be524fbb75cda88903907df94bfd69373e288949bd0626d85c1398b3073a139d5c747d24afdae7a3e745437335d0ee993eef36a3041c912f7eb58":"b599111b9f78402cefe7bde8bf553b6ca00d5abaf9a158aa42f2607bf78510bc":"a40a6c905654c55fc58e99c7d1a3feea2c5be64823d4086ce811f334cfdc448d":"6478050977ec585980454e0a2f26a03037b921ca588a78a4daff7e84d49a8a6c" + +Nist Vector 3072 SHA-512 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"c01c47bfa208e2f19ddda5cde5833325d16a83fbda29e666fe67ff3489803a6478a5ac17ff01edc7973d15fe4998f63bbc095fc1ac07534241c643a44444dc9a356fa812d5ca191a2f6ed162a2d5fd6d0aa898a20563d993830254db8a4bf65ba86099cc6b58a1bf6ebb01a19c79304308acebe1da09f1753a195e9ef586c7e1":"9f11370ddb3c43e2f4162dc61f7e08dfc6e86d5d71742c6adcb5340f7bea2ada":"970d38cd8b3f16659ec42a46a19ff06ce8495b9f477d9b7e35ae1035b08b0ee17a0c3ceedf029846e3aeb912f850881c2277f82281e7c0741d2f87e9fa5c30677fe7268cc5fd9aed29f308d9be8de92b961e39c1dbc46790c99b7e29579daf888176d5ce16db5cabfcbe4209ac4753b0e96b15d0b82c7eefb42a10de88f8a7723492a2be5451c1c6ec68ca759d8b4ee418826e71f39cd07654d00d0e0f88d0924bdb97aaca5a6346ad69fc223cd57f5bb0300477b594aa445e5ea8896cdf3bc882e8fa5523b8a332fd98e9d0a924578944d24a41cbeae3ed7b37dffb2f60c0084eaf005c1251823da41d2a5d977d8e483ddb33f73fbc27254a814b616d6a390513f0567a563ac053a76667197b4558f871b69cbf2c116ce457513f60b4f528e2dcdaa71a9a3a4cccb3738a22937bca2a042bef8a74a600acd26975c891466d7e57cc930984212ee0eaf174ebcbafbeb8cc12bc43bfdb00fd11576c439513ef5b59a88fa5a9ae963d94dafd78f81ee7b0d7fab53e41bbf65f8449a4f58b44f9e3":"ab53984e0b154992ace73bba548185b49719bcc3b11fb150b5da279529750078":"5bb50e4f538a6e4638206be119dbf712776154acfb4c06d65d66c80212341739":"7b7e640cd76086d3f640d18ceb26bb53e30282afb17401e7b48aa6818934dc5c" + +Nist Vector 3072 SHA-512 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"47e7af22c9298ad3bfef9bee5086bedbdc513d67416d5f4e7981cddb1002cba24700c45dd6d4dcef4f81d003f0513dab4e04eb4c70d944042e1b726d8a33050d0e4f70c0a8341b75fd4e27c7948754e441208eb93fc7b7c37354252f73b838fd02d078c6a1ae073ef1233aa1c8aa2781e193ba2897ccdd8cf617ca23541ce1c5":"232c1c88d571492779172ce6650524cb6d91174e8a23780d0fdf7c44ffd80c1a":"75163af15cd6b228251504ba024df51df32f638e37f0f2f9d08837f8c6ecfba43eb515ccbabea11b01e1e1fd3cfe7e405fc7f8142b07315e1dc37b08c78668421e2a21fc5d811d26558c504abc4e6fddf03740b8a27fa2ebcda5460ad785706c53cd2d14093d923df942051cbba2586b4d54709d24babe2f7c61a50da8451895999166e80c0fab892a37eb6782745596b49f96e11e9a957c8ec650d2d9a40aa4b014d2e9a4c08b9d7bfeaf1ecd42785b95c0172ae21cf25c4d368bb5100b6e6d92310b28b7b1afe64d496b9c60b763cac08ac46a6bce1bbd3ac8bb76bb55b649b7594820ab6ef7dd1b09bb12852816b61e6dbefab742e0ea2cda47eac7d9d913ddd4bfd8b2eb5f01951caa4f413eb5e7a41a0685695f8331a394e06b1495c170f30ac294660e8909843f9f11c4bfa64e8792df677da0a08aae32a8a4e7067fc35eee03964e8afbdb6a421b8248add284789e4ed3cace7106c23fe6666c4b12b836e7307a55ab24d92d58ac84e71f81dc9b0b7436ad07f74994af7d0b049bd09a":"101acd88a048a6a87c13ff23225dc2c4d2fe3fff039e072fbb268ef2dbfab9c3":"6175473d7aa7d5ce55590c952a19897206086887fd84bf2b566926e47981c2a3":"71d7857b6ff06ca67885fa9c9c71b8cc246d0339b6c2725247172a297e26a7b5" + +Nist Vector 3072 SHA-512 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"9311d8f951141713f459eb65f01880b961c0a590b36f785f1aeb880ee71300c0cbc601b3a6072193dad6ddf2028eca4c8bd7b8575187928f84bd69c5dcfb0b9d320003c3a863c09ee503e38abe07ce2e0d46b3cec926231a57defa0aebd1a6e01eef4f9b537ae1fcdf64e01434d40ab5019f3965c735411a5c19941f41febf4f":"87bde6350da15832966fe70300e5dc66b96ec263344bcfb5de051be34d76262b":"287ddc1969156c18420743ade0fa1271ea346c3329f9ca9b5d54ebfa21f676f9e013616239f4bbe60eaf8e1902ed9ac742d8df918876770894b512aaa25c068bde961f56c9b5b87806d7d0a9de7843d3cb0797903126a47bd9422337e3b46bb1f4f4a79fdf9cf6762157118aeee1e71116f34dafce0047f05d43c7f2cbd4cd52d614b7a945d48be44cfebf784332fe99c1ee1aa8310867df20b280da855b19029fa79ecd6dd6919a4d22b5a1400c30e62ce7acc4b28efbdb94ea23afbb64d6e5f7b3975d2ac63b1d048feea835c7f50b425ce3cb418afdf4dc84008473606574e20db5ebf86cb1ad27737d46494b2e485b26b8c95d829cf656f80f96b1a62e7c03c8f20f18dc58bf59916682e6dcc68d34c89c1b1bd6e6b1e15a7dc325e23fd7a35099831dbd75989c738020bf4dc4079ccb0bf12faf3b9d6494a379aacb1b66d07cbcebbf77a6e29aef22f4baa3df40d270b457dde64f00b53759ae57811b64e040cbd42ea90f4e2808bc81dfd663b28584cdb8199da96d3e03d03fb4133e2f":"7d1b5d39e51af0c22a56bc57ba6bf8bb6de18f2c256bb2d6fea684add38b1f6f":"66f729716456a2781bdb8578fa18d1e64af0edf8ec1dee0a50d25981912fc45a":"8c3cccfe6f0cfdc0ac3a542c8e8c85210bbd7f95134c8f035d1ce16f44ab7a06" + +Nist Vector 3072 SHA-512 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"808603f7f8439441277913b21bef4e01c89e4113e07cacc33f65ac9849db1ad1a1cb7dd2fecd88ee4139b1638355c623821309f326c16bc658bb4821518238982e5251f7cd37807292153d2b07dddc066e003c6069c371155d2d191f15111f2089ce423f5c2a1f8534e301313c69623f62ba635adce8551733a82a8fac1a66b1":"9464ce029452e8602214c5236d9637ce7e59f92536a07ac5ba30f639e09814d4":"389672ec6de0b86655cb10f1199f857013b6320d52c8728fbbb5360a9701b1d6ca4f9eecb8487fb879690f85430c582d3d91ef184c8247d162b94d6dfdfe7c4ae867ac1672827970415aa67a1406ac1a6e2c6c13167719e1d1a536d10078427c211cf682051a75ee8322c1408b89d963bd8e85f9eff7bb8ce05ca42225b4bdfead6b897b0feab76c2272b487d27d4e8dcde0f19e4615f7e1114541f61d43533ce788cc4505600b83266b1bea665912196c2c84c36aa93baf5b7464a6ddf547183e2cd058bb50a12765536f0a4d3524af4f31acc609fc447e1729aab97b5a36b01764b84bc5f77f6cc584866d1a6cfb3aa8437895f777f2dc6897499f6c5f02fa1e6c1ead68f3385b733387c6b58f2d11284a63ae7c7cfee42c3f44a3c926adad8107cca1c3f944f9b9e237d9ab35c81391d7c5f5292d1a322f7a12ce108a86237ba4de3c612fa738f53194ba67bed843cd2d4330a5d194d67cf45fa05183e0cb46c2d23a1bae76755c309fa1c31605c88a9214227ce02fe915bcf0d34bce8c8e":"5c2bb856c4d87b27e01e2ac1ae6f2fc526ab8bb49a67eda5c1d8cd4253610df3":"98fe587e43aa96f9a9bbe8af404a08b02307b36053db87f6db25a3aa36fcc3db":"5c94ea70f99f9ff14b8e5dd4a6688398260907176ea80e19c39b14621149f0d6" + +Nist Vector 3072 SHA-512 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"ce2aa3ed12c1b8843a3e11b06b5f0e5e63fe8e19c1a38ac446a48eeca8dac6d8b769d7809442c32ac82e93f686ec64347e9444c3f452823c840e8d0cd334b4152002148da16ac8859d189d87d67164c5db16195c081d2edd7d8157e2bf3b97a90b4b4784324eb8ceac4261809f674256daf007c4ab1f222f5fd28398a5b824de":"b887c14673cbc63f04f0839ea56a76154027d7eecf41d8d0b53d4892353ae9a4":"584fe0eb314afb866c0466c3980a2df54598d8a705dc2d1bf5102eac86312784eebd019b81a7642d4a3c4cc65dbedd8187e3593f0a9bcc06ea367009b7eb4d29b0450061378edbe163efd3f344bb36234fc86fe1c32f2c9995a07c6e957d195e8105f5179c2bd976b3127067c80ca93456c16b98dfcc7de355790f0b15cfd2ff91db09345532d46096c06b40a2304681d62857675ac50e22c7d1ab47589235419cbedd4b7d24b90531e5bfd853e88a28836ac46b6df26760985b962c6a2445809866b46126212aa263ab2a4603ff41a852c7988c2d4386241655a7222fa4e9f6eac6a144a16b059ea25b71a2138491d54ee95a9d6819977f90fe6a59e0cad81b329eba3e68277df04f9828ef6f081610b4595a92113ec6d069ffe97196d956191daabe9877377ad0416b0ee0658663377e07adb24644e8a0e3ce5fc178f152be0cd9b04071890427c6b001d59262f38fe897ce32040daa7807821c40ac8c63505bed0af070443337c9e9a64e44203c36a8ca5064d87aa0d3cd1d403aa6a24ecc":"49548238215fed6525693bc3cca3872944a97790087fb35f329b206e6046b32a":"54c99b21f28feee27f0e999aac6b49b6b07633e1db18a45952fcf7e73b166bdb":"7a18588ea1456f67562d677878346fb34b684b9a8a61a721b3db0e95695ab43a" + +Nist Vector 3072 SHA-512 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"17b925e2a1a51c2036e225715f2f771d8f0a6d98c7ed9cacf5aa4cd30ab16afb94e21a7c953e01ca211c28782a06073fdad27713aa8c26ae9ec449aaaa8ccfda8c947172de94b3f20b54af98df152d5d3a636c736ff01bfa699d6214002dc76dbb3f3860d94e0e34edaba5f2bfd6b2bf660086be876451a50f6a2dc7c2b098b7":"0684a8fad551c8d08beb05033185e3b4b6b6f6f4920ef9982d72d0a9c7549855":"42a93bf44ec7d2fbd651cc1d1ac391d63cab00971a7ff7a56166768b22e611dc4d729faf8c94e7ed4d6f82b7020b7b4d2fb3591cf2295cc6e1b4be2c256c2fdda43e00051114645da91cbed5cc087085f7cecd8bace67889100bcce7928220266fd3faf2ead9c21e423c9948ec70c2d31b668cdc360ddcebdf429720607f96d851235515d6dbdf163f7ea5ddf351baa76f38663fdbfbd5871bb2157df0a43420648c10e4827f54065614623ed3abad10d317be9d49a4c66564f20dcac176b6605a2e3c3c01c362220f352e477419f2b4b238affbc3920e5bb57cebb9a74746d62cdd070f4a13af001d262def014f29b7f754fac84e02d29285b73bb20ac0c8624123a577be8d6a6b9739185e4458090ddb42b005ea4fa8b51007bd9ca5b4cf2a3dca446a87ec83c9548dab46cf3daf86db3bc69a99baed459d6a197f9bf5032c1dc3a877dd7e5c1161124a6d701324e9a9712b824a4fc3b1b353259af225813c27e820b0ba72fb4e78f5c78673924e7fa2f486030284f26cb6fa31da56f49d3f":"4a258c125db1f7b775432b53c7a0ff47c00bf7af27abec7fcd42a2916e95e26d":"726e4d3baf00b259f4bdca8b0a5e1cbfd37827c48373ef5029f7601a7769478c":"903079439ebde1f766d1a8ff33e0f778d77b5e8b7b0d687443c271e8a63b5975" + +Nist Vector 3072 SHA-512 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"1c1169f0e790053cd7df780b5c832c64147694b4a6448ba14a426d9def7ddc78e3ed36a12da81cf9c3f245d64c859b6b4d8121d112851974df178defc977db691234d142dff99bea1957891b5d6fe8a787e96369d93c24682debd1cf3fdb64379b8c1b3b73e1bc2467dcb08b86cbd494c01477be24d7900f5a578930f4bddcb6":"3fa44778b414ff27436e276ca4904546d3542d128f73c4463c69ff9cea2b7a41":"7fca2268fba33bf94e76416a9e3869f8a90c3b0d2d37aacecd3f6785b9a95aeefe9324c3ab09ce61ffde37b50f82b699413f3b54f24d6c52eca62325029523deb05db138778447bc3d0d05aff7d85b5525f2b863d26486e84cde13e2e2117d3fa38a38d1073aaa794ed8eaa7b3d1daa4ac3e808c3738a9cbef3546cd79eccb4faa28b50fce57cdc24015fec390f0e7a7dc9f9c471d22b30c3e4174358f1ad0734cf79a09a639bdf3f3eabda2b47b81f92e2a4f9004dd641370338c02029bbf4971aa67483eea7a4bf7dff3889f84faa5765617ccab37d190a94c57f99d792807a6965e2113586c6c5d1a81abfd372e1c7954e2e09064df4d2d8288f5cdd8106ed84ffa798819a09a732bc204a812c0352e4e39d2ceb88f8e7d3624a5a5f3dc56ea0f9c5290788e12dc463161601ff3ab681bd0403ee03af45d5e586d84d9c901986718193e661256f402de735d2ca696ef6b594868950ae173f22d95856656a9d00610fe8c2bd725ae55d791277b1317085b67188da00645ce91bbe62e324311":"a05b9ca1c9532bc050cd0c1150c27bc192154cf64d59dc9a949906f1ded57e35":"1026ecee0ac31bdcdbd6103b1343f84b441fc326e1d86ad0903d0b17cfb2ff9c":"a5d3cb2e7c39d87640c4547ac6c33afccbfc1820905ba1e5be5b262313277cb9" + +Nist Vector 3072 SHA-512 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"805baabdd018d9e5ebb4dc51435be632d2387869756d743788442790d55bb183e26655ae3aac86dc16a48ddd268dd15e18d8320df9a1a0a6cb2b49bc701d7a15e3fe8ddd584a75c8c9aaaecd1efe17324d6261881f3d34685b04f62e968505966c9a5feb0c39b5095e5568e40f20aa21cb2505356dc9049ce56182d94a2d94a9":"770b99935d393eb90b583d1251696007cbeb1b35e6c3f4f9bcb62879070e0940":"434d0612b2a8332b0ab15614e3ee9fa245131712fb2ba84f71396fff9488dca340a37e820f44c13aa87fc9df0b7aabeae2ed85a9622b8defad474ac362a7039abde33d1df732a052446aff7857bc24d8f61d258015ed2a3060a8bf9d447e7d83d7b497a8e654731969e437b3f46f83eb58f7884ff2a2390f5d821ecaa7fd09a146c55fc1180073cc5aaa607cabb944f6078a4486cf206ddc5635242def2d3e2edcbc026bb84e849518f197399c22a9009dde9afcd8769b241c75d4ccce7f93900b5f488333df47c026c4f2b2767e70d2d9dde78405e226c9952f6db1a2e55829bc8a76c7de5c2b588f3f3e93ce72fadabacb75c7c14669701e0a2ba127bac56863c8c4e7205cc0a73c429a801e9797da4f26e848982306cc3c3439f9e394ddc80b0f13e0d528190638d8b96bba3af889de373b3549fc90a6822964c22171e7601fdefbe5708988b84f3ea554d621600a876415d5bc1e557e948caace563b3702f0915a90a13aada77709eeba8c50a8629351a4787d0d58808ffb8b217c1d164f":"424a43cfd90f7b84e9e375572f82ebce7ffb197bd3237a353bf15ddc1a17095f":"2d63e6d2568571acfe4a931580a04b974c7aae4ca9aa9610d87be1a91c657c31":"574b10d14dcb8f079461b29ae1b91ed6c5ef32f93cbad306697552c11748fe0c" + +Nist Vector 3072 SHA-512 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"be8ca5ed4c22a050d8309c7a31acf667f0c0fbaadc64a34d2b63074a763a2b8db73b24cdbaad26cc6f2c3e90df4b25bfa724fce587faa0fd65ffb719f0a0351648230d5354d721d8fa6d0d686c37f257d7d9dbd15f555d5073f8bc71c92139d1f627d743f7d6586d510d19d0d8a555d0bf79ec70596e712183880c89caf69d6f":"9886138d837d20e8c6be853cd7de1a66a25748c7a33fd55121a27237623d68d6":"afaff7a4d438b464f27415d2e03ed9c416db2bebfbe0ab34f14ee10644885b5a4588877150f46327c2c7a6f712670bfd6237a29452494859948f5e37c0e586656b119a0e01c81acee57c1775a3a146e8fbafc99cd203fc98195687fb94a88a4f44280b03f0895e0eca84db087c1bf7c4843c85597368e839841131e027109daa7b8172a25e11355fa9a9205ac324941a9fe492c48421f0681a47e280803e8bd91b113e0fa1597607430bcb0ad50b9408de0066d6a2324d09cf6e99133654dd64e8c8f70cd6445343758b5cd5a0e77e2d3fa1cb3f7efed76124b2881dfd2028ab5918c389b9c3978271db54a5171515ab2e85eeb10ab307130159bca5fe13cc4a959e88e9267221ac8d14ee6938e149f52ec59125b449cb55c5a0029f018770b31f08440ce6876e6600a32411722f58e6263339bd9d34e17aa574b921228926ff668ce90362c4391ecd0c037454e12fdf80c96bb7a840cd866e8570bb7d6586fbe3d1eae5332931198ba1d5d902d6b7a122dfa77018553a2dd3680a809bb06053":"1689eba0aac66b3d0cca9ae1911602f9638937b6be17c23a187be323d0dec7be":"9c7d40e214082bd5e71f3bf4be99789303f38e851a76f88cb90aff713080c587":"24ca23be94c624b9d736328b53782b5feb384dc9fe6370016cc3f97d8f48b6d0" + +Nist Vector 3072 SHA-512 #11 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"62f0cb1bb07f6497a1dc7a66955765a9cc403bde03fef4e16b09d7ec545b4c75d08b6e9c4c5af7232548d45445638d7194a199ef1534e81241eaa9c7e767fd54e2caceea4d2f7215d37baad6b05e28ea093497e2e8e1db6e41a5eb13ffa4caa27108f2263a74cf54bd5b6a6b62284bac99fd7977aaa8ffff18fa8a70ab0debdf":"badece34257da3d7b8713f8f0f9f0107b1909c7f99a765ad8405d8c2a20310ee":"73554a69e1a09f6191f0aded542a077ee8c814265d745d9ae5c792f442c5fa47b34643d3ba1d5147161898de5188a80714ee36512a618a33e40300ff1187e553f54433e17466af486472bc0778af55ba7346c961d7f13ac6d8d6ac9a42092c01579ee2170590cbc3b45eef795b5d9e5d0a8449439ab307c14c5674c4a7a3eaf8b240ef36dd21f43cced58c2dcf23c314364e8e314e9671e80813d185801358d5df61d7e7ec0dd69e90c2cc75c1c3543efeca82b2ec6ec59e6c99bcd1a8631c6228e216884082da119125cb0a80c8fe344afe66e0f20646432465f3e0096a17725a8867b3bdba3c69a1aacbb8d64755b7f2a3df0a49ba0b2114e112d4cae0ad6d8d0fd618e54d53f07ba109b75a54a989618b2863e4415e176e0bfd88dbf36553ca853bb36316c66eb93da34ff3ae74cd5f187f49bf38af0f393b2d7f854df192ade2df6b39a176d2152c912bba248d84a5b0aa4084a18bb64fd136973f73b413d77db275ea5ece93ce2fa00d7c8887b7e50b00649d0353a7f58cc63f6b5fbdfc":"2d468a99e315c158a1af18abd4d58872d6e281dcd4c9b0b43298eddf346496d7":"54ff5d3dc8767856a10f54088882e28c110980ef9b204eb5f162dbef73a37c73":"57ed0748427c089d6395528b2b4555c01b4c1341ab5fb99c64d1cc247a41c3a8" + +Nist Vector 3072 SHA-512 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"baeb12a1ebd8057a99a0137ee60f60eed10d26f1eab22ae2d9adbc3e5ffc3252abf62b614707ad2546141bed779f0cfad9544a74e562da549e2f7b286efb615449b0946dc7c498d8f12150b2eacbd27157966f592ad5f3e43a24c60b7e06630b82a4fdb699119dbd878b13a98bf22a7b3dc7efdd992ce6b8a950e61299c5663b":"bd3006cf5d3ac04a8a5128140df6025d9942d78544e9b27efe28b2ca1f79e313":"00728e23e74bb82de0e1315d58164a5cecc8951d89e88da702f5b878020fd8d2a1791b3e8ab770e084ac2397d297971ca8708a30a4097d86740153ee2db6ab6343c5b6cc2c8a7fa59082a8d659931cc48a0433a033dbb2fff3aa545686f922c7063da1d52d9688142ec64a1002948e5da89165d9df8eed9aa469b61ee0210b4033562333097ba8659944e5f7924e04a21bc3edc6d551e202e4c543e97518f91e0cab49111029b29c3aa1bed5f35e5c90feb9d3c745953dbf859defce4537b4a09801fdc8fe6999fbde39908079811b4b992c2e8333b9f800ea0d9f0a5f53607e308942e68efef01e03d7cca6f196872bf01f436d4a8e05fc59d8fbc6b88a166f57a4e99d67ddaece844653be77819747dd2e07d581c518cb9779e9f7960c17ff0bae710ecf575b09591b013b4805c88b235df262e61a4c94f46bf9a08284611df44eadd94f44cef6225a808e211e4d3af5e96bce64a90f8013874f10749a8382a6026a855d90853440bfce31f258b3a258f7b5e659b43e702dee7c24c02d2284":"16aedfbe554de17a3e5b83e942702bd60702d9823ba154baa6d1e7e94308324d":"8d357b0b956fb90e8e0b9ff284cedc88a04d171a90c5997d8ee1e9bc4d0b35ff":"ab37329c50145d146505015704fdc4fb0fd7207e0b11d8becbad934e6255c30c" + +Nist Vector 3072 SHA-512 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"184e599a4c1de86c4151205754df0b1912c2b3c532552c51a61c6459db98c83e59d4a40806c6a2c6b3fe74e3bb9e720d7d0a3cc11ef88959a8990c0fa057a3915fe0dd9a138aa0ec1cb1ab69d93910d8d6f9e14f3b8a135d3f031a56c76a9dc3aed1962bdf05815c2492d14f2324d2da491810d1672b633f2419da4e7ebdef24":"a29e90d33f200b1faf61bee5d92ca8a392b1eaeeaa0817cec98b40c97e25018c":"60159720021fd2d5a2f575b3220905788d328d0c46895a46bb985942467209ec28d8ddfdc97ec34da65b164cf48652ac475d8978959cfc4330743ed98137559391b1204da6b26b451211407e8fc77d819934c48709c8eadc620f6db2592b65483265149a324467d93c375d97230f2b1a682897cf6d280df61a34f20f0c7c729a40141958044876c44e595d2378a7d22c6cda9ab816486c294e4eddea7ada88b15eca5371da164471edafcdefc654e64a1f995068fa85dbbb5516137bc442f60717fe59c629081c234f27195d5f9c2bf85cdc1ea4cae57aa908cbff9b2a53353b13e9f6fe45daa5174cd956236d447b52011d688cd22f23018409b39a36079cb53e03b6d3a752733297fea4ca27c6395becef4081d201f41d4a00e99d95f42281dcf44b9ef6754998d94231937c82594218a78463cc837193de6bf1d3c3ec31d8dc5468cb56defc9c70d08b95b029d97aa043d557f6286b87ee4098442df495c0ad8ae4d4ae037312c5f7239032c03b088c1036fad7774b1519709242c9511e6e":"78e781b2874ca2441e2ce74a2a2a16417b51537eca876831f6593ae25fbd796c":"079d4df14ad703a435b21bc70a03456ca822b876c9accb018bddd674bd6392d7":"6c7765e1f1eddf915a56a57390db45636e52f083ce440766ad4f32580f722483" + +Nist Vector 3072 SHA-512 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"b189dd34f58f3efa85b6f97677edfb82664cbe43a2550c336ffa08705bbda2545ef244a275014c6a265971f4c3658e5e8d6a3fafc889f3c4eda6b5616092954b15c60435efd76806e28557c05faaaa8a05c262657840865ff69c511a68d13022a712d35bde138eb7a2f8f1a87b342c7caf388c1a8b95079bc4a8003eef84b899":"9759c24820670eaeaf92370197d0037f9f71dcc283970f341117fb56a1764001":"05e280310810715d29ea1ca00a700378bd5979493b9803174c932b7dadb7029a9a9f9c91cf8f938af2bceaa052f2273f0de393b0f7544490d693f529a68b812e2e589cc092b83ef847c5306039aa8eaf225128926145893a51551db382fda4b63e5abc10fd076100684d4ca657c89b2265de6e0f0473f01bb222b2bc50ec1c5fcde9161831018aab3014a956033bb0a83866df11915808f9e7461645c89c6e17ab65dbf97cbf4ac1164d671a1516ca81645bc3e09913a03f30641bd0920083578ca84df71f62eb756ba445a0dc44f85a9e4f72ce5f6bf82ccbd674d2ce3c4afc300562a7dbd3e8ab838993f9decc9933dc07dc01b502fee5b390461a8c82c4e69615f121b3f9fd4f0c8b7620a25996df43d7cf355f15be09e2c82178c6f8836c36c1d3ef26ad05219fb57e85ef162c8dd8f0e55014769d53cba478a2aa66d90d8acd6cb0489d1eea46c2c41bd5495ab8def43b2cd5bb2673945c21c80a4833fd75d884c7675c09e7191fb26e92c54c7c8208d0a0e8dee75c2968e962de4493e8":"86050bf276a649b13c18814430eadcff54edf7416f1a8b1559c6c2c808e8dc9f":"9fd105c74a0d36973740867ccc1c731cf1c50c7935d5c09e92f574d7a569157e":"501f50c32b0288672e02aca78f90f446acf92626365957a375550c77980c3c17" + +Nist Vector 3072 SHA-512 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"42c065fadd56d6a1fe68dd4e86c17efd76d0f9db87036bd7b609159d66847f46de01b8ae43590360fa324559a2d709d45cf01034f5facb7f52324e60dd464a583d42e412659d8420f7265e30cf82bbbcb2c99b0f00ca6a46d28556428789f415000dc31babbd67ccc8fbaa84a880466bca4783eaf00b7f78231c667126433e6a":"307555893610e15549a5bfb2b446251f9595eb0c16df5fe3b784ebfc3fc30140":"b265edfed77b3ad511e56d583129b12e5796d659d484a2fce350661f79e545dd0a06c23774c8ba2fb5101a2848c413dfc5b374a7c5ff3acc7332f0ff8bd6f5fa882c0a67689308be7154c4efc51835f349525419ed722a90bf26ddded65bc8962ba11de9e734442571affc2d42b9f3f54a46535ae9eb01361adf03fc28410abf41db3ae4113da4c40e9a368f9cd029be4d98c66d835d034e3c86544b60bcb01feb383b2add9afe7b6251a17ad4e5439a9cd2d1bf62b6cf5377c097b7268bd736cca9ceb822e5d1844a09fa69c78217c3d6737f0bf45e3236508b5a3f5c466dd0d75ace95d447f9bd7aa9ee57bd10ee3c5e8389a06c00857e699794f5cacc7dc5bb1504421dc920565618bef05dc1713b6f08bc00681c5a1c0685359729fe4b544090ccceaa82f4fefa9f1117bf1e371b99fe4ed71635dad415017a62341d704227ee7cfb64a8deae90d86c0cfd37ed363d91a4a06fd06f64dbd8142c12503f49eeb1b9a971aeb343f15cd27d279b99d4cfa51f121259b3c1b55d28d994bb3299":"5359fe067eb9d98ec2217500de743b0dbe88e8d94552b53a0117aac4d3390083":"6ed82af8e89e38c49a58010f0564165a16a76a2bfb348466d9b4a91e5ce53ab2":"8c466a8b3e4c90886f29986a4d513904f31db43a68ce880311403cc755466604" + +Nist_Vector_1 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"3b46736d559bd4e0c2c1b2553a33ad3c6cf23cac998d3d0c0e8fa4b19bca06f2f386db2dcff9dca4f40ad8f561ffc308b46c5f31a7735b5fa7e0f9e6cb512e63d7eea05538d66a75cd0d4234b5ccf6c1715ccaaf9cdc0a2228135f716ee9bdee7fc13ec27a03a6d11c5c5b3685f51900b1337153bc6c4e8f52920c33fa37f4e7":"c53eae6d45323164c7d07af5715703744a63fc3a":"313fd9ebca91574e1c2eebe1517c57e0c21b0209872140c5328761bbb2450b33f1b18b409ce9ab7c4cd8fda3391e8e34868357c199e16a6b2eba06d6749def791d79e95d3a4d09b24c392ad89dbf100995ae19c01062056bb14bce005e8731efde175f95b975089bdcdaea562b32786d96f5a31aedf75364008ad4fffebb970b":"98cbcc4969d845e2461b5f66383dd503712bbcfa":"50ed0e810e3f1c7cb6ac62332058448bd8b284c0":"c6aded17216b46b7e4b6f2a97c1ad7cc3da83fde" +Nist_Vector_2 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"d2bcb53b044b3e2e4b61ba2f91c0995fb83a6a97525e66441a3b489d9594238bc740bdeea0f718a769c977e2de003877b5d7dc25b182ae533db33e78f2c3ff0645f2137abc137d4e7d93ccf24f60b18a820bc07c7b4b5fe08b4f9e7d21b256c18f3b9d49acc4f93e2ce6f3754c7807757d2e1176042612cb32fc3f4f70700e25":"e65131d73470f6ad2e5878bdc9bef536faf78831":"29bdd759aaa62d4bf16b4861c81cf42eac2e1637b9ecba512bdbc13ac12a80ae8de2526b899ae5e4a231aef884197c944c732693a634d7659abc6975a773f8d3cd5a361fe2492386a3c09aaef12e4a7e73ad7dfc3637f7b093f2c40d6223a195c136adf2ea3fbf8704a675aa7817aa7ec7f9adfb2854d4e05c3ce7f76560313b":"87256a64e98cf5be1034ecfa766f9d25d1ac7ceb":"a26c00b5750a2d27fe7435b93476b35438b4d8ab":"61c9bfcb2938755afa7dad1d1e07c6288617bf70" +Nist_Vector_3 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"d5431e6b16fdae31481742bd394758beb8e24f31947e19b7ea7b458521882270c1f43192aa050f4485145af8f3f9c5142d68b85018d2ec9cb7a37ba12ed23e73b95fd680fba3c61265e9f5a0a027d70fad0c8aa08a3cbfbe99018d0045386173e5fae225faebe0cef5dd45910f400a86c2be4e15252a16de4120a267be2b594d":"20bcabc6d9347a6e79b8e498c60c44a19c73258c":"23b4f404aa3c575e550bb320fdb1a085cd396a10e5ebc6771da62f037cab19eacd67d8222b6344038c4f7af45f5e62b55480cbe2111154ca9697ca76d87b56944138084e74c6f90a05cf43660dff8b8b3fabfcab3f0e4416775fdf40055864be102b4587392e77752ed2aeb182ee4f70be4a291dbe77b84a44ee34007957b1e0":"7d9bcfc9225432de9860f605a38d389e291ca750":"3f0a4ad32f0816821b8affb518e9b599f35d57c2":"ea06638f2b2fc9d1dfe99c2a492806b497e2b0ea" +Nist_Vector_4 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"85662b697550e4915c29e338b624b912845d6d1a920d9e4c1604dd47d692bc7c0ffb95ae614e852bebaf1573758ad01c713cac0b476e2f121745a3cfeeffb2441ff6abfb9bbeb98aa634ca6ff541947dcc9927659d44f95c5ff9170fdc3c86473cb601ba31b487fe5936bac5d9c632cbcc3db06246ba01c55a038d797fe3f6c3":"52d1fbe687aa0702a51a5bf9566bd51bd569424c":"6bc36cb3fa61cecc157be08639a7ca9e3de073b8a0ff23574ce5ab0a867dfd60669a56e60d1c989b3af8c8a43f5695d503e3098963990e12b63566784171058eace85c728cd4c08224c7a6efea75dca20df461013c75f40acbc23799ebee7f3361336dadc4a56f305708667bfe602b8ea75a491a5cf0c06ebd6fdc7161e10497":"960c211891c090d05454646ebac1bfe1f381e82b":"3bc29dee96957050ba438d1b3e17b02c1725d229":"0af879cf846c434e08fb6c63782f4d03e0d88865" +Nist_Vector_5 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"87b6e75b9f8e99c4dd62adb693dd5890edff1bd0028f4ef849df0f1d2ce6b181fc3a55aea6d0a1f0aecab8ed9e248a00e96be794a7cfba1246efb710ef4b37471cef0a1bcf55cebc8d5ad071612bd237efedd5102362db07a1e2c7a6f15e09fe64ba42b60a2628d869ae05ef611fe38d9ce15eeec9bb3decc8dc17809f3b6e95":"c86a54ec5c4ec63d7332cf43ddb082a34ed6d5f5":"014ac746d3605efcb8a2c7dae1f54682a262e27662b252c09478ce87d0aaa522d7c200043406016c0c42896d21750b15dbd57f9707ec37dcea5651781b67ad8d01f5099fe7584b353b641bb159cc717d8ceb18b66705e656f336f1214b34f0357e577ab83641969e311bf40bdcb3ffd5e0bb59419f229508d2f432cc2859ff75":"6c445cee68042553fbe63be61be4ddb99d8134af":"637e07a5770f3dc65e4506c68c770e5ef6b8ced3":"7dfc6f83e24f09745e01d3f7ae0ed1474e811d47" +Nist_Vector_6 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"2259eead2d6bbc76d49213ea0dc8b7350a97699f22341044c3940782364ac9ea683179a438a5ea45998df97c2972dae03851f5be23fa9f04182e79ddb2b56dc8652393ecb27f3f3b7c8a8d761a86b3b8f4d41a07b4be7d02fddefc42b928124a5a45b9f4609042209b3a7f585bd514cc39c00effcc42c7fe70fa83edf8a32bf4":"aee6f213b9903c8069387e64729a08999e5baf65":"0fe74045d7b0d472411202831d4932396f242a9765e92be387fd81bbe38d845054528b348c03984179b8e505674cb79d88cc0d8d3e8d7392f9aa773b29c29e54a9e326406075d755c291fcedbcc577934c824af988250f64ed5685fce726cff65e92d708ae11cbfaa958ab8d8b15340a29a137b5b4357f7ed1c7a5190cbf98a4":"e1704bae025942e2e63c6d76bab88da79640073a":"83366ba3fed93dfb38d541203ecbf81c363998e2":"1fe299c36a1332f23bf2e10a6c6a4e0d3cdd2bf4" +Nist_Vector_7 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"219e8df5bf881590430ece608250f7670dc56537249302429e28ecfeb9ceaaa54910a69490f765f3df82e8b01cd7d76e561d0f6ce226ef3cf752cada6febdc5bf00d67947f92d420516b9e37c96c8f1f2da0b075097c3bda758a8d91bd2ebe9c75cf147f254c256963b33b67d02b6aa09e7d7465d038e50195ece4189b41e768":"699f1c07aa458c6786e770b40197235fe49cf21a":"3a41b0678ff3c4dde20fa39772bac31a2f18bae4bedec9e12ee8e02e30e556b1a136013bef96b0d30b568233dcecc71e485ed75c922afb4d0654e709bee84993792130220e3005fdb06ebdfc0e2df163b5ec424e836465acd6d92e243c86f2b94b26b8d73bd9cf722c757e0b80b0af16f185de70e8ca850b1402d126ea60f309":"5bbb795bfa5fa72191fed3434a08741410367491":"579761039ae0ddb81106bf4968e320083bbcb947":"503ea15dbac9dedeba917fa8e9f386b93aa30353" +Nist_Vector_8 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"2da79d067885eb3ccf5e293ae3b1d8225322203abb5adfde3b0f53bbe24c4fe001541e1183d870a997f1f9460100b5d711923180154345287a0214cf1cac37b7a47dfbb2a0e8ce4916f94ebd6fa54e315b7a8eb5b63cd954c5ba05c1bf7e33a4e8a151f32d2877b01729c1ad0e7c01bb8ae723c995183803e45636520ea38ca1":"d6e08c20c82949ddba93ea81eb2fea8c595894dc":"56f7272210f316c51af8bfc45a421fd4e9b1043853271b7e79f40936f0adcf262a86097aa86e19e6cb5307685d863dba761342db6c973b3849b1e060aca926f41fe07323601062515ae85f3172b8f34899c621d59fa21f73d5ae97a3deb5e840b25a18fd580862fd7b1cf416c7ae9fc5842a0197fdb0c5173ff4a4f102a8cf89":"6d72c30d4430959800740f2770651095d0c181c2":"5dd90d69add67a5fae138eec1aaff0229aa4afc4":"47f39c4db2387f10762f45b80dfd027906d7ef04" +Nist_Vector_9 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"ba30d85be357e7fb29f8a07e1f127baaa24b2ee027f64cb5efeec6aaeabcc7345c5d556ebf4bdc7a61c77c7b7ea43c73babc18f7b4807722da239e45ddf249849cbbfe3507112ebf87d7ef560c2e7d391ed8424f8710cea41685143e3006f81b68fbb4d5f9644c7cd10f7092ef2439b8d18c0df655e00289372a4166385d640c":"50018482864c1864e9db1f04bde8dbfd3875c76d":"0942a5b7a72ab116ead29308cf658dfe3d55d5d61afed9e3836e64237f9d6884fdd827d2d5890c9a41ae88e7a69fc9f345ade9c480c6f08cff067c183214c227236cedb6dd1283ca2a602574e8327510221d4c27b162143b7002d8c726916826265937b87be9d5ec6d7bd28fb015f84e0ab730da7a4eaf4ef3174bf0a22a6392":"df3a9348f37b5d2d4c9176db266ae388f1fa7e0f":"448434b214eee38bde080f8ec433e8d19b3ddf0d":"0c02e881b777923fe0ea674f2621298e00199d5f" +Nist_Vector_10 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"83499efb06bb7ff02ffb46c278a5e92630ac5bc3f9e53dd2e78ff15e368c7e31aad77cf771f35fa02d0b5f135208a4afdd867bb2ec26ea2e7dd64cdef237508a38b27f39d8b22d45cac5a68a90b6ea76058645f6356a9344d36f00ec6652eaa4e9bae7b694f9f1fc8c6c5e86fadc7b27a219b5c1b2ae80a725e5f61165fe2edc":"ae56f66b0a9405b9cca54c60ec4a3bb5f8be7c3f":"a01542c3da410dd57930ca724f0f507c4df43d553c7f69459939685941ceb95c7dcc3f175a403b359621c0d4328e98f15f330a63865baf3e7eb1604a0715e16eed64fd14b35d3a534259a6a7ddf888c4dbb5f51bbc6ed339e5bb2a239d5cfe2100ac8e2f9c16e536f25119ab435843af27dc33414a9e4602f96d7c94d6021cec":"8857ff301ad0169d164fa269977a116e070bac17":"8c2fab489c34672140415d41a65cef1e70192e23":"3df86a9e2efe944a1c7ea9c30cac331d00599a0e" +Nist_Vector_11 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"f23ee79eb4fce5cbf3b08d65a1803d2e3e191d3580a44d177d8ff069f90784d012ca5746e6dd6638dfe8413f1db3d8fe282c2160f5dd96607dd63d610f791dfc10abad18721587101cec8a2a12913cfbada3a5b7593958b9bfa6e9af3af5d71ff17ec72aaaeecaaffc5d174e629a090297e94cdfe988d9bf6c80827c23df5137":"a62079b4f45772bf17b85d7560e3be4e521439eb":"229a26dcaff29ed1a7264ed0f77d676239b9ba1ef4778e7dd640e8aa6fabdc1f1bd3f582e211bd01c26b3d9d3bffe7199f9ed45d764cd9d0e844b385cb34e6de22370ebc6ba41db409d63f50c1ac09bed00cdc2b7c55223c596b7e133ba25ba9e78f33502f8dd52f32a667a7683e504047817963238d9629a918a0ceebaad518":"c01acd36910f2f2bff608386b81c35a0a7c0b378":"8d388ec7f2863dd5b7c99ac93505d1580bf2e0c7":"76ae9317696d37f2d8bd61c47733e9455b61d347" +Nist_Vector_12 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"6836255e6e659de4ffb535892d466a3bea09693e587eb5bd50f44f8a22f11697057d68660bc6562400d587baac1c19d330ff794a70df5300a5211c72541a56d0ff2af02a278ed2db1df94ccb2026d3138b2d924245021ee835d3c17b0b3b7677def85611227f6ce2913e7cb446a479b95acfd0105c25e4656fbc56c2a10a22b3":"7861e82e66b6caea54b159c59c887ec27b2e915f":"a7bbc35423510edfebf79c4e2e56986f2806d11116bcae90a716f05dcbfc46dcbfebe2ec946c40f9cc8c1a7439cdd04e270122ec1c3baca83811a9f1bdaed9b1172150af1c8ce1c5d502dfe5f4e8467e50605087a8f8c5f45ca672fd049eec0a06f5e01f782d51f3ba56404bf1388065552fc87ad21ac0fa4027a145d0b0d9e6":"4e22cfa2e8ca2b33a9fd91ff4837fc205864e8b1":"c0ab43d309a5e94b6ef4db9943306e6d966fc9b5":"07ec5aa1928f19fc3a420f29b935bac46124c0e2" +Nist_Vector_13 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"4b0845c99db348294f1d83166b27f448ec29ab7965464477f45444f44672a409ddcafaf35e91faf401eca7498e3268caa2d96bf1aa840c0e1ed43a5ab60888fcf02b2f8a2c89daa598adf0b7d2dace9210efd41ab496a1e73a182da430c1d043e249a1289c91809c8c7298cfdbb0ae438b00936c283a0ec2d79cdc81c9ce3c2d":"6f2d3b09fae6910dd975870db3a2c19d97169491":"541a9c45e165d3d91e71bb1370d7c032c360322aa15e99d8c1c16ea35c8c193224a06467ab77a65478c467b3f20cb0c5fdb8c84cefa69566a594a2aa54c3a948ebc1ea7e6c3d28d380cbd01740634c96b76d6a03cc6eba0afa7226f23fc10a18b0b6f97270dfa038160960b5b839ba66af50fda07245810e80d38b6693e8a9ce":"8588557c12ec6fe176b0be7bbd8b482ad78f1fef":"44286019c1d53103980616940c028bad3217f78d":"4b372bf527c515f58025699a45f2021ef18e11b9" +Nist_Vector_14 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"4597c1ca0b0764be31fa73ccc589116cc8d0a31605f2550eb37fa569b2496c4f34321d61bb8e49f858c8671b7437fc15f269dd2d4146470b817dfe3069225ddd3cd4a6c977fb6cfc0d43264a7bf6659283e140e4c89ab2e8a4d0ede6274961d655bd79c7e47880a741fb0180c325b5b7d2f7b8a57aed52d0206a83bb69a9d7a4":"49f6c1ac8e639bcc99b2d9d1f1e325713f29b97c":"5315adf90e196946be6b04c5414da1fafd98b0d17c3a39000a00091b7b56574b1ecd026eabb25be9ecd0ad691df2b7bf7eecd6ad95bb4d7d17ac747060ee7e3eb5c6fb7557cf7e8003a620e43e587d0612854472c3ad851839f744159411a33876aec365eb0491dec80ba14cba2d11dec42af4a4bf9c99312a2ae7e5462a2adf":"8ef1c5976ac8caf74df65d9ecdbe78a6490bc220":"90d547712bc0cebbd3ebd18a63d9b92a03953050":"34ea6176b4c63043295f129a4895e14ee5816563" +Nist_Vector_15 [mod = L=1024, N=160, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283":"f85f0f83ac4df7ea0cdf8f469bfeeaea14156495":"2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33":"18c62a40b52347a473f57aa668eebb4484beb5f10fdc51779e6770106c0d122eb6356ae53a3379e270edca39015da3005770c7b2a5afd11217993153ff43a0b26db01aa2a493de061492a0aa3f229b5abd1aff29395e31b063504eb35620219ba29997f92a52e1b2e6ff207480fd13d58ff0290eec5aabf23b84943eea20a43c":"396cbe3e71d74f6db795c38d49c32d78eab03397":"3b738246f9e38cebf4542ced3fc0c0096aeb9e9a3ad928f4dd4745d875fe6e20fb65556d06696432ecffd55b334940c6e23c903f0aa4a1335f7394c55070586baac86c38cc198ebaf15401259528c55192e9298d2a0c8914daf2ad00259fe72555c3c0442e38c1e6e5020928c6e6571a0a98f6f485e43791ae8aaab180461fa4":"04bfe51616f5c244d2e01648362f5bbe5fa73501":"29b7c0f90d624f8d587efd3f49f97da70f6e63e7":"222a3d9ffca0dcf57937e89c92538e32e7a8680f" +Nist_Vector_16 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"fb2128052509488cad0745ed3e6312850dd96ddaf791f1e624e22a6b9beaa65319c325c78ef59cacba0ccfa722259f24f92c17b77a8f6d8e97c93d880d2d8dbbbedcf6acefa06b0e476ca2013d0394bd90d56c10626ef43cea79d1ef0bc7ac452bf9b9acaef70325e055ac006d34024b32204abea4be5faae0a6d46d365ed0d9":"6e2e31bbfc670944d7a7120e39a981520614d8a8":"7e339f3757450390160e02291559f30bed0b2d758c5ccc2d8d456232bb435ae49de7e7957e3aad9bfdcf6fd5d9b6ee3b521bc2229a8421dc2aa59b9952345a8fc1de49b348003a9b18da642d7f6f56e3bc665131ae9762088a93786f7b4b72a4bcc308c67e2532a3a5bf09652055cc26bf3b18833598cffd7011f2285f794557":"8cb35d255505a4c41421e562d10827266aa68663":"afee719e7f848b54349ccc3b4fb26065833a4d8e":"734efe992256f31325e749bc32a24a1f957b3a1b" +Nist_Vector_17 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"02971e0cdd48ae2331db9c6285e9880e96104fa7a9f378dfea718e63efe98352fe4d35a2bc94b3a888cfb88b8b7d9f6c8c54e48613f32c9946ffe6e9a4b7108ececdda41bc151b3d8724b61f5b83a4e27476914387b0488e41be54f63aa773175eb373a3641e6e7950eee8faf048a841f107d30cf9be268493231545d8984694":"0b448f49a085a52a03d7f668a1d6fb87f2e221ac":"633bb757b3c0e3b7867bf845301ea4e39f75c9759c223f46ce266d406b9df5db501fb826b6e61cba6104c604458c90799f2a36ab51166d0e83b770840624fedc35ebfb9853419e7e09b32b4bd652da4f1ce973ac2620c966b61e35a3f216439a8de1a104f172e1b6e2878112a66c34d16a9aef3ac24a34af5edbf39818a3e2ef":"4481a4be9db6821e3b0a08c9c82603631971a682":"92c65e07462d668b06dd45b608784965897838bc":"2e40adf41cafb8048c793c7092a7e823515b6cfa" +Nist_Vector_18 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"062e82fb43236ee17ebfaa3d363b9b873d0fe41444c74cef7f7e3bd81f723fd90fd148a28e997585413695113757758aa4dd275f70b375f8903c7be46e3a3ad3190cd04971abd2f1db192ef0d2b98bbb80181a721a5809928b5bca5c118a2911132ad233cd27c7e41adfccfeb4e952874bfa819661182975e44d37c61734759c":"a4a25a8bb1c2ba69f9611939b591032b96333fa3":"3b0a091dfca05dce61e9f05b15b07487d2e3ea4f568dc9ac752d42c0aa771ae0ccc372ce9774fb9fd16a30cb3759bb1989488ce85db7cdfa506476acec644c21168f2db1f36efe0230c6fb8f1f2ae4eaf1799d5e29e212467b11bfbc1eebed142d7a017262cd8735e3e29d8e0c4a6e766c07d7aa9f8d176f536087bfecf4c414":"a7135820910f041b27321534a17bb1f33ac51aca":"ba554124874d06a6cef62740e15821ccddbfe6f3":"5962be757d75b0f17d15482ebb595ca4e9fbfe22" +Nist_Vector_19 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"4fca074844eae247d19c06e92032ae8e773043e2e1f45d400e9dcebbde5d65e7c1423b0390161991c026f38a0e2bfeef40dae18741737b1d535ab46b566a1b672fc22dec86747a7c7638fa65047f1ede36ad43f6aedf51b5bf2979adf4d9a94ed802a29de5603b704770b32c8b946a32e1b6054cd70c3add025cc9371d1e404d":"1f15cafca282083e82d7e54258647b2914418986":"40b638c94b1e719a337d83358699c70cd867ff888c655a5f5a1de8732d058bf027d4747efe3b8dedca3276de5a58f136ed35cff03030f672da65c71f18e58278ddfc7b9b50a248eff9236874ee3cb0d0a35b7b2ee185b139ea84eed7bffc5094ab8743a75374bc36c7d69d5f3e6fe5f3ef1f9358f00a3c5892fff41ed6afee3b":"128ab9677c7ade5e1c02a8427650ff054db6390e":"651a389d8ca50d6e3273cabbe71cd84cccd02361":"3401fe47b3812daa8c020c9bd42609cbebdfa728" +Nist_Vector_20 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"4d9630fe058998ca5b80ae62f3f73dc85bee291509843ac00240d13d55251ae53b37794783b97d53e042cab26f8c84de0a70f5b43051fbefb3e43f08f5d2e8aad9e2de2717412dbb902acc8849adc04d06fed8c1421c4cfe8b81ee7f5ac5d4f0c0b68e80b6f88fd3c7d5b32022572b0a681bd2d4df2d047b0b23b6887145afe1":"1485f719b8be77c78829baa0d2c322df60174476":"727b6528357d6705c20d31358f641934fdec63cc66df98837d2f378164e15fa0842207acf3220c8023a9f4f8d2057165b3c849eaeb5376e3fad11785f1d0261779aaedd53b1e52798007eb4c8e83b1ff321b620d883391a14fa47fec4901d96ec232eabb4a0bb4453368fef5176c67135649979d3214d3fb67a1319ac54feb01":"8f4cc1254c787ec8cbf54405105f7ef83ffdeee0":"9ca3e433504c557ba1aac66469781175cdfb4ad5":"72145dfa5279dd82ae99604d16a2b8df71b95320" +Nist_Vector_21 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"62b9d601e30b42a279c7e04df3ca8d8140a55cd5876c7e9181c73575e4c4f921a94e4e2d0bdd7ba98600d652e5df5be9464e7a9011ab486960f69d57ece1d2c4af9324457c1e3d83fba4265beb47407e4761dbc949d5bd67fee4a476a4d5a93d77acda96a221a0a31e0f024b3f0b8234c015238f3258daa085ae9f4e1aa7b1cc":"43c76a9a00045cdfb2e7927b5c8730e006423c05":"5f6dfb064caddf644af399e33a672565766761d55ac0b84bead42c3980e7e396043744361778f04dcb698e4563853420fecacd594af828f57df541d9e4de899d61f04f6379c1c96246d152369395242a1c2e70eef8f35417a0ffdb039282516ce21b85687904c511087f113e5142f027f1179712edcbce27939ab15ec49c085f":"5e4b5e4595e31397422c7a4487ae51051289be61":"331920a7b79e3cfa7638e409d9702aafd08fbec6":"071d06e6cd301515f37b60690afa219fe5083d96" +Nist_Vector_22 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"0006e09c20376442e689bf2d34268fd69109c1301ea66cbe90394cc0f41f94822c28845819b9a98764d2f7262e98891487ff55b05bd69e18b7cad41bd98e137566b6041c739db11f78e567cac02f33f140d19a4805002545375daebfd7dcbea33242e73c8e269149d7eb9db9f9006e17acb736b5e977645ab651b81225c5e543":"16f89d97dd3b31c191495173ae0e145c6ce185d6":"1b1f725664d75bdcb2a5a4c653061c460799dd48bf1e6b03e13c71d83e3fdb506fa94e6cafb5dbdead88a33d23d4e9287b4707e1fba871b97c9a48f930cdccba0dc06a4f0a8bfbb4e14d0b4d5a0871fa1341caec7bc08138713121d419769f31203508df71947265644fdc6137d8e466c8cb0ce985340cb2e279b4ce9315a772":"475b5aa12ff77d49e4c8171f80d3d1f15147ed12":"b6aa833b825184729af308f81bf5e58e2d7e9284":"5453b4b2e3fc802b2f977d0cf6eb7f5c16673fa3" +Nist_Vector_23 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"e04a71f2b5c176a0db17a983a17dec588c00f42c9aa3026b5eb440f07a2140c2ed84024e0531ea7788dfeaa91883fb6a9841c17dcfd312968adb00e556bc7eb3021f57b7a16894fa4fe12ec93dfd494a0a1c693d6ade154ef648c05552da41224d4922d1861d9f7671b8ce6ce448e895ea0eed25802e3350ec08ae79f2d61e0f":"3eda44e3c38380df7a4f47d8e1024596238bcef1":"687e16309b06817b93236dd990faef9e232eb81cb9c7d6dae4fdd4f8e7ca933e185b1da622d7c7fa35e0a3906f915ded14ba96d6035b46bd6ca5fe172af94e081fb0b9a9583a458bd206c1e87f97a57d00d6eade19ec56ac2e9bbd8c15df356ee7b12c91311a38fc3315cfde9ff462ca6adff2808b3f8e805ee915ae885ca957":"aeaa655b6febfec50b05562c3f358865533e4736":"14892b1ec7fc716c75a17f7ad2e41ec6faa78836":"72cc56a9890e8bdf1a53d3acc6f89137264f9ff8" +Nist_Vector_24 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"5e8eb96b5c6ad75d3dab1e28bb2ce751ecc31611a019e8d4b561c7e4533cc7ab73bd9de931e8c54c51c5711e6c276a8ed92f4bb457ddf28233da2ca3e3013c56e3cd2bc61d4d4e0e22cf6361304e56d68b315ca5d3fcc472a7eef8cca575204dd084a21a99ba67fddbf90df7c6c658761734bce13c3d22d80b6fb9bece551492":"0b55f99ad958a766eaf5ac20a127a4df1b946bae":"50b0f7605911bce6ed5ecff1e3c1816fbbf03a1479a0820603ffa715aef9ffbccbd067579cbbc8c87c392e85bbe929a0b5e1059faae6f9121df49c66a049a98a90d84c70a21312bf837f4723993d0ec0ac4c2a7ffb9d400957b39fb83e951ef41362452cf458d784c43fe822ea7a7abbea0a6998321a93819d2d282c7884f5c2":"9e9b9afb43a7157761f6c2011138d2f65ac1cba9":"7399b120d4bfbd6dc4064d2f3f8f0ca5c362b2d8":"2302d81d7ebb2417eef45d88941b070ecab11cab" +Nist_Vector_25 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"da91c692cdb0a59562e2b664dcfe7554ac589d57f82246c4a8a3f9573bf47b257eb8f93447c1ebab13dce53d6f4416fb2c6c36303ed97885cf7a6caef055f7e3145ef3838c31877fad7a8883ffc84ebd973f8c06d17cdd339bb3371f9d3d4f2d9f0b80ae2bcc878b4af78f845eac4f2aacee6a9451daf814a44e927bb5428820":"ac701252c773ba36711b9731afdc077c5d3f9271":"678b3958ed24fc84942054f49d9e6f27bbac7de3a4a52af9ffcb9ce6c1fb8bdd99db0e80c868ac547c4cfc782de7ebcf6943b2e46433c670178de0104bd6fc25dc3054db9c48c12706e1dea35e163be36a4ab721950c028b0546f1719ff2edd81b2b7974fb9b121224ccfaabc47e9e629a97bc6ba42691ca3f649ccac47d0f1e":"6cabf2c0e2890b2b393da3ea6aac2782216efa73":"6f1579edcf437584d3e939fa5b002eee83e3b614":"71208a87a4cf2b3a9b65477773b0096d452dae60" +Nist_Vector_26 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"0f2edc87f4d2942c4693b064a511b93f790c60dc149a1b0b7041af5183bc0f42234134b284270e4c7e53614f7ecfe711de0efb28336d0bb359c86e8be8839f583211e9174832b3d41ee6d21864ac6186fd1db920dda65b25966c5951ab8a2050dda87d1d72e3032852ad43da9fb430e850022b4bb6cc9cb90e428f3a5ca32a62":"588f40e3eb813cd22a41c9cdeadb6895a348db3c":"3a978e9022a8f7a0caa91f275bf9cf7648e1b9a31a0702d8acdbf59affb5467fb07a8f7e5b4c86775ac4efb609b946f05a3f13034db94acc64057f906d1854910de538f84367181c618e96c3f922547d408ee6408b7a70acedc75de8ae445c5d4dd5def4a352d2528234070cc720700c14ce12d2f36990d36b29d7b00596e34b":"8ac2fe7bcd690a7239d294b22725b818d262a446":"b6ea9cdb211c4560b3d592e93af6d5f133b64b9b":"6242e45a472fa8147cb5253dbddebae31ef31e4e" +Nist_Vector_27 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"d12fc1983e0095e9e2b6b8743fb34386cc4821540e3efe1a29f84cf7e63e2a0668d551f912ad2221b5a3d6b9ebd12136def5e6690e1d32aae919f9f1cf5d24d62a46a9a9a604bae11b9c0866350367204a920b589a317ddfbb877f9fad6b0d3629af9635da46933151c0d9a20aaabddd3df5d049659b2860ddb8b20963261ea0":"67cd81c7d6ac2d8bd44ef26297ac02ecba41f73f":"10b7b14ad29fb34d7a39f3e953051f456a0cd1233ef54d90a4adc82dfbd9fa7a85628f11039632b47ba9daeca6e463ec4644f5e2a2a4bf95d392e8c9c9f287a20ba45a198815ca0e9ba854d7f3c79d9037fa1417724fb7f02799b1c2b2bcc79d64367b90c06d1789dcc6de57ca19fcefafc04fcce29c8f495ed564f5d9a112ca":"1341e376e8919e01991e5e48b8e0c7255929b3d2":"360617965f65a68abcb83dbf2d886a1a10ca05de":"71abb6acbf7e653d2ebc3cb7149b51cc0c92fba8" +Nist_Vector_28 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"87a6dfb8487f16f6fef1d68bc31469ac210ea55387965bb4458ca0d00d6c46858be28a019ce914c39c2479f321f0252ca4a8bd681a5b358a093fc8341c31bc47c618403f93322b443084ce5818490b74e83c3866b8164bbcf79bf82539f428c9351c40b10d773cbe1cbaa8c9800a6dcf38d85515e2dff5d4f8a965ecaef37e38":"22bbb8468f3e90768d347cb3492f64db2a23f721":"75ef5d5f67022426f531e9b8ca9115921d5a5c446bcdf1af701b605bae687dff8d1e7b3c4f8b289537eb09a7461d6688a3711974371a5b73a2082e991410118666ccd94f444977d0c89ba36162de023aa519037a6ba6305417dad3f2dc38756a40046491e8ee80c4f147825b8c021b5d09a2422d39d7c4abc395f6c2d7903c66":"9c609e56c19f74ddc46eb2e2cfe26b1519ff0d1b":"5409cd62f5539306ae8c936082eef932c6505c39":"07c0ccb30ec90b1481409cbfa2f5de6cfaf1efc5" +Nist_Vector_29 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"a332b38e642bcad8bd271f776fff24a731724a43400c1614f5e21296db04f725eebad28d62e20ca3f7f18328a76b8092d97b632bb78718f0f2f9ecc7c12cc36b505959917b5c54312ad4717be84fa840b9f06de005c792af3e9ea72b7ae2e3423d07c781c9c2553f899554a0d8dec9a285c1ee25160fa278489474a0e4379516":"bbb1854e9b0942cb5d1eb71e8cc6fc7e0f4cfcb5":"41cc1d6d9e0cf5f158dab599114f3ee4738f197cf2c956b6bb0ddd6dfdcf5e4db399aacc16c538948c4b50de85bad6d916dbc415bad2f6737023fc7063c133bd0c4231d6b33ce813c0d6024d1315269571b2554bbb2edf2a99108a4359e8e23bf8a143bfc538ab9f8842cd4e925968f49ac56a02e3f067e26001e5207bcb56d4":"336e458fc213c0b2775537ae61decc034ccb1d32":"a16a7308a6824d929b6a9a3bdb280d151a6eed81":"7a42addab7ddb98000286044d9993d5cf818f2b1" +Nist_Vector_30 [mod = L=1024, N=160, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff":"bc550e965647fb3a20f245ec8475624abbb26edd":"11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17":"79b144d50e0047596cf06bfcb3e9ce3959ec4b8cc9ba01434fc3f68f47c868cea048b990e62cd7a50eee288b35ae62aa797924c9dcab76409b869b33de28885e62f17db7a7758973482968b9f960eb2dba84ae85101aa6c6141b3f0839a4185a4c496eae876ecdc45627330d36f01a67cbb7faef834357330aac36c7c6f47ac9":"754b24ea5c8cb8e88e370074e79cb62605530018":"74db7460c51919a9e87b430d105d86362ee4acd9682bf6c9fe87d9956c2f5ff17d95930ccc12f7e92d8bcb6af5f7ef1848da8d15c9152082477de99594781b998daafbf8ae4af23772125c19e166421f806bd0fbeac365076ecd9e15432ad4ac2523418f6e410cbfcbc5a71a0edf22e694a67d14b9cfc9722bc4bd8c43e22a91":"1b50341e94f4498b92cce4d17ab9d4016fb2e074":"021a3de98c3da698b477b4c3d50b2169e65f5e91":"afd764318dd0fee04fd6b07f550320789cd9bfa5" +Nist_Vector_31 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"812172f09cbae62517804885754125fc6066e9a902f9db2041eeddd7e8da67e4a2e65d0029c45ecacea6002f9540eb1004c883a8f900fd84a98b5c449ac49c56f3a91d8bed3f08f427935fbe437ce46f75cd666a0707265c61a096698dc2f36b28c65ec7b6e475c8b67ddfb444b2ee6a984e9d6d15233e25e44bd8d7924d129d":"2eac4f4196fedb3e651b3b00040184cfd6da2ab4":"4cd6178637d0f0de1488515c3b12e203a3c0ca652f2fe30d088dc7278a87affa634a727a721932d671994a958a0f89223c286c3a9b10a96560542e2626b72e0cd28e5133fb57dc238b7fab2de2a49863ecf998751861ae668bf7cad136e6933f57dfdba544e3147ce0e7370fa6e8ff1de690c51b4aeedf0485183889205591e8":"85976c5610a74959531040a5512b347eac587e48":"76683a085d6742eadf95a61af75f881276cfd26a":"3b9da7f9926eaaad0bebd4845c67fcdb64d12453" +Nist_Vector_32 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"c1b1f1472f08df38a52a55ba55827ba3b7cdd6beded904fcd52610c899eda3c61682656873bbfaab0d907495dacf458ea3450afd93be967a37434d412b6325669ad84b4eaa278a24870ecc2df0da13ad526a9e6669958d4e52dbfba2803ae9ae135d0c0acca86a04c42ba9cafb09b7af96347188880b086169ebdf9f1f5f3173":"1a220585a989ef2c12bbfa9fc0d258713556fe38":"99187498534f313dc7cd7f3a48d62b2335bcdc36f0dc98dbf845dc6085c267474c36fdfca38854219830e614bbcab2bb9decb81e86124bd78f86d471bd84be06ac1f0f41fe5b4b3740b2107e0c9c48f81e31e9bf550d96564dd380ca47a11d72f0d0a3275f075f95bbd59869c14dc912a1cbcf01db9fb7f71015cc149986825e":"8fef50b7121a04a24755b6f3e1cdc93848a9081c":"54ed4efaecdfc78d026471b65cfefc6529945bbf":"6d6dac296ebde3f873b751c6b14843f0b7befdff" +Nist_Vector_33 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"b80a47071d1376fe617e59fdc005a890369a4ca5e678ff46eb9b205d6ec09cbd49373bb341fe7813ee442a6ece17e720bf71a74557ac9a375c059e5535e773a45e79e1bff3465a3886c86e2a2bc882f0beceefffb2ae1a522f13c82def4cfd0cfca6fceeb4cece71869e90cd10d0aff27a84b5601daae061cbeb3aa62b37fd3a":"4247e7e4dc4270fc7680bc05746807c183e0dd98":"91f50270a754055e5da611c720a4262f3cb8bd4161f77d07401604d3d1165e45518f7e1901adef6628f23dc48271d35ff492af8d62aa538c0e77e042f23a522f2214e62114bfeea46ae8888bdadacdaa0a9a5b503d79c23e4c20c98bd4ebb36f95bf4451ccb0b5bb44dfd011341cfa29a9e156a3cd828e126e68cb911e8f9dc0":"3aeb3383a3c0f53217c0d7077c3cd66d2ef74a2e":"1fc2d1cb80bf6e0e78b25fac293b752cbff2b5ac":"75bcc772f773d5fd98dde1f907e7ec2cba201dfb" +Nist_Vector_34 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"a9603054465887df15db07c0709a8c878d2f1abdcfc6195eabf3e9b3ad07e8558b99cc4a7aa076daf67e9b7d8480f11e8afb18e2ac56a9547b48453fedca32da9eb0c29271eb60f0a1d95c18f42d992394b3264ff3e21e606e0beac08a7ba71b8e5795a8da985118e432cf5b30b6cd3a603d8b0d580f06c626ee937c6cd05f40":"4d2a5462ebccc5d19bc6c1cabb609c08ad088e08":"a2c4569a301473ae4f164d68b9a3c6eb705ae81f75d6e5cc3070a559cccb8b1a2d8c21090ed70e61670c7e9dbf5f755a37d58d3abb34c2dfd40db9f26f6868d0dd91be98f395ac0ebdc37e1b5423802bea7a6cb196d7e0f93db92f663b6c9c726e80feb2e9227154ce1c15f8e8df93ec0d37fa47e5fa112bb0a48f4a239d6052":"36a3cd0101358a4d30c5b7117bc239fb4f6ce2e7":"48539523815bd8d73ce702367c7712b9b13867f2":"20ff4cfef8a668829feae73b520e8aa4d02c8168" +Nist_Vector_35 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"19eb088c3229a44f9586f00421cfe7423a486d5f7e28ad2c9119dd2e1395df1acc06cb28e9069cee62f09f48e4ca29269dd89df9fec1ffdf64b1fe2717fe52b1421fcf6c705c0cf39930f90ecb339b51ef95b2ef38a6d96a575f7b36f5edf4f2cbd6d261e1fdd77d4459288c02e68c82a3910ff8ca1747c86bb187d5205f51a8":"0842ddd5a04161e4579797b5d8eda0002dd847ad":"49e606aad5d2e54e1bae2517915c660ba30ec4fd28d718613a7c84464b0f44bc6d546e5a9bc1dc60423b45dd01ec295564ec08f29d6887e69f689d6b3488f9da5d5a60f39cdd5a158d51a3d073b2225fea559e58bb222e29a87b5f0f5ab31dd7c0ceaad887070dac955d28973607a99e46ddd7737beab65199f250d7f03b6583":"712eed73c8d2567809b4d9ec2f59e77d39290b2b":"6bf4f5d3251201059ee85edb99a67a706f37197d":"3125c5af397759996b876cb5857be2632aaaf3b6" +Nist_Vector_36 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"addb5a045c9f4f4fb9eb5e5db44d6515980c9e088015b68593d8bcbffc6ff57f18865ab824d3d1586425cb5081197e9e01cb7297b06b64103cea437eeeec9c50798679fb869ec306a72575057fd368aeb0f674a29c3ac248b6a08f91331d8456d062025347c12a0a61c61f76e5206fe6ca437735af430dea7cc8f39f1a5b7505":"1f1cfc682048375915fb483b77037c81c05ed728":"221ced57a91325b10f8dcd1220b1af68f8daf397f419a43bbd8fbe644311755b111aae5257c642fafd83b047a1f56f2a829fcdf4df3e5dccb23645b28c0a34c6e8a650efcdfadd48fea467cc943ca4e7378829300713838b6c710962ba72e790c10ab879a01fe1457ea3dd4b7c3c3a542e3522a75d0db261e576cd3f22c998e4":"703154f6c6e12f163ecad0494897dfcf5657fbe2":"7cc662e352e0eede85140107a7773ad8663e70bd":"15c17b9d245872844eaac3d46bb08c3e08597423" +Nist_Vector_37 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"02709d2be0d9dc1dc0ebc55f630d91fa23609f61b513c2275766034d8f40e819aaf9326c8db37c35c5a17e96bc956df6d11b558d16d91871afc010b3119c5798c2e29411ff4f0d7196e7e476bf0ad03bf72e897fed873c10613dd255d15243870b81cd87d0abc16e140d032fe5bd1c8eeb2f66e04d13d49269fc7da6b65a7c1c":"1d9cf98dc0c1d7bf8dec98962ac6ef6e9406ce76":"9e93bc03e6e815308734e3b8f1d106961bebdff10a525303257a053dea4da6dcf504c7839b54d57522f2acb3aac959ff4ae8610022ca5a1e688232336ca1ee8fd7028bf7b6e9eedf8a4b0d098969f5e5fd3d9300c340e7f19fd471a451afb92ed4829fa4d90249144aa363dc18807b3e29d27e6ec3da736c33b185511bb3aaa0":"68ae16534c5f6225fc7ef980f0063de483a76903":"72b0bcc6defa66fa8bab029676a1c7703f9608f2":"69d911e05acd7be52f2834c0aa005128e7fa85b8" +Nist_Vector_38 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"cc061edb31c34d3981517f4d89afbe980f74185260cf48b3043bc13a144944ad43e0e576d2a58bf589cc021dc1c1d332c4d76896ea77dda197f683e51eed71b4d6df46666a1b142e679b0283cf339e5bca90e2ff9c34dd5fd7cc4917d66704fee4364f7693101dc766707104efb2b933c4848b93e13f94855f75e4fd756cb6e3":"78ffb40fd89416388804e56444c9a642cb5e98e8":"5d7d2e342154983ebc2015bc6750f9876f5689ca0ada8529908ed4fdbc596b972c5cc6d53e80a8ad8a8cedf3ce64b62a75db441c96207fc7477e3f7b9f10df28e0cc2fb77383e7ca4c5150f712dd823c2309f0161be0bd5eedd60cf6ba230861a08b9d9a7468438b4d6ec673d28a54d83c7010d50631e55f0a02832abc5a0a46":"07c6857486160ef4003470411573399fc4e5f7af":"21f512425670943477534e9075ceb5b7d63f20df":"73c6f6f8de3aaea520a083b2264299e81cfc91c5" +Nist_Vector_39 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"79d529e40c2ba4e5b9c7d77d72076f1fd9490928ff4419c824e64db8fb9a051e01e8e173c6f214e0e9e645ed250b6daaa6f8c1a5cc900d52cf3e1efbfea25748e89a1a548c73e2d110b25f5308bcf757b2135216c91dca2783332c0d7903eb21c226dbd33a69eef575aa8a41cbbdcd1b3d94928aa8f8ba58c5ce0d317786e87b":"784b9db2d19ef0ca8e696884c7711dc2f8ce150a":"282decc0e37994c2856e61f36b831b61bdc02b7ca675dbc3c2032800b7efd3b711acf14c8869968831e145361bf2182b060e4838f07dc61f76584cf102a913bb28a52c7317af5f9d2322927c9666e5e87c2f2bfd2f181dd32612d7b2b2a645bf1a47c0ebfd79a940f627a668a8f2eb729fd051aa2c659abc918e5571994e6593":"1bfcf3290fa84652a476655506b145743213e1b4":"929a4851be0ae4ba91da0e6c7376d71df7592dbb":"7e6b6504b748ef0024d9d2a2e6f3bcd7cf135ac7" +Nist_Vector_40 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"f5516410706323549b20c52dafa2f2f90799786c0ddb85048892ccc18720dce5c129a10eb4388788a3d97a03b0001799cb65a79c880836bc9f3204ea75a577204dc1e2894c572a258f9e517ca37c5b791e48b27c8dc1c821b34ebb1f29858c4a72a0d5172c565e9dbe1bdddf6e024891cd6291faa81ed565746c61c2eda2011f":"673a384687ef29ebfa66e331866bd206ca2f7664":"74ccc6eb83adbcbad0fc37144d9bfb85fdcc85ab92c9f8877c9cda66251d1aff2fb224888dddb7d772a8b738c53e03ecad9903796fa3c9c6024d06367e0870ad797694f598708d08912c0fe09881763a0a722dda95d94eee8824927cbfa6761a79a038aa6d331da34d9bd5c5833c94c526a86af1cdfb2d4079d2db6d0b9a1238":"52ee4510675f0da529684fa60f6848ce63c4689f":"27b3f235e4afc18c6613b4fa7f27d7a8262ba4c0":"8b22634e4d45b71a84eabaa1e5a4bf1e37337a59" +Nist_Vector_41 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"55bd1526e08f6443b255acd32c286807542d34c0f3d79892713f9d6d6d6b3be707e4af6e71f7dab4a2c5f6bd25f5ae1f514b2644a4cdafcece1e58f7576f82e2ab0af2326c71279e9bcef1e1c54a76fa77ec2b2d056717645764e7991b520b0e5a1b049109519b22aa5204e3ed53b1e0957dab5ec32479d06ac3e11a5d1cbd03":"495009f3a92548be4c9a562ff703187b0ec2cc86":"5d6edf6db6e6c27e80a7f02597237919170b4936489d6f15f598b820cd917e172509b7e287b88b0cc14e1a0186793886809ab4170209987095092234b4fdc44b3d1fc16eeb2efaf852ed3916698cf9eca4612b4961bb6e20c32e188469883f97f49e29a8197c30d0723babb06dea704f7704b2788e57d76d6d9a3cfa68f6c783":"423308bb414ef959025bf1a4b27db278f904241d":"621a290930ac436737a72fb4c62bf5c4b67481af":"62db20f82a5754f109f7a2ce581d4c8d71c68d29" +Nist_Vector_42 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"62789a89f0d708e21a121fc34009af884133681b9d4a66cc36c0365c34be72a4982eb0961ce257f35e6e7183f0204a96a545193001023d3309a8997e7c4b762ab4f4c40e03e13f4edb328b23cf00c09119deb40addf6567b3b74acef5ceff045304d618421e873c41a72d31e451d213b060829b286f64013d4d9342ae7ab8064":"2b8dd3965992fcffd158a0816a5987f80908b84c":"ad590590a82e8929ca86f405516c32913bf5282f70309c6d4a88ccf165ce15fcf11e140c366bb273839a711cb6ae52bb717859570fdbf9fc26726728596e6fc71923deadb35a9d57cdb213c0f29c1375f8b1d3c6b52690c428f7481c14aad82fba7f24eea8cd8da7f0ef7ae781c1a926671a61d4e5ffc8ddf1bc10d688a904c6":"58ccff88958d5fc48d671ba22ed71f5f82370ac6":"89dcbca7c8cd6b90aa906a4c547153762fcfffd6":"23e8926b18cfd4b67c53fac4a2d5321e5c3d880c" +Nist_Vector_43 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"4eafcc6874ae2a6d525738967afb3054357a39670d1e5555d7dc55be24dd5a32a0c7ca3f1b5c6d948c9ce391013abeb47f7e24cd2c54e1fc7c0e92c4ab77f5973a7054bd1c6c845b802b7937d6520508ae018ae14b27ff4b1e340a4b9f6f6b4814d07e90cb8f19b15e915d6ad1834c0f7a3c3e1e45206772a0eec2d3f9160897":"6b3acee42276bba155156f23dfb7cdf64e4b1ae8":"b93d79472f049893779a3a0e83b3853f78b3cf69b75961a60e950f0c00f498f3eaa2384325f74ddd38292fbdbdb199212e90b14ec9e554727df81e06eb7783adda38691c63a7cb00cd76d8e18e3d29c793e9f1fe8337f1598b89651f634cb703f218e1906319f82ac6d58e6786da7aecfbca5939f03a13e7b4d5a8ac812d7829":"1c48f62bd097d7686879d33ee5771558e453bb3d":"633e9812a0657cec3326aa5415340c46362fcd4b":"6b201f0c3fd44247f6c28c01d1217eb99146c040" +Nist_Vector_44 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"86d9892b48f5954101482742c0dafb68dc97122483b9e459f97495cc970e056d2162c7c71db167229fb7f45209e0c01eb06ff924b823eda51a7e990f3c986eb9af2a7a073f754cb84db453a9e8c0ae7fa5c05a2655d261ad7ec5612876fa7df09522e0b69ae92477f63def1992c96ce95ee7bd630ec1614621da6a512ab53dd7":"836d90fd90d21b84bb012da7b2168ea8f05202cf":"ae264ea96bf093ef2de27381738219e3bfdb08616967cd13e9415f475c4a794c19f12a607b898db1e3e6bc5402327585d32841ae15e3462880850e9e4136a4751b64a729ea27b72ce36128a44fa53752a08d73584faa44fb14120f47a04c47e989eadabc7e5cdb15d27c2b0ea4257cec229a2c7bf7c93c571e8d22aeaa2e38be":"7956ea15111ff392d6a9359067bfd8c21f0bfc0b":"77b480885c70c1fee2056237d1b79cfd9fb54a1f":"2283f4c0640ff6daacbdfbbef7224afa59ca3959" +Nist_Vector_45 [mod = L=1024, N=160, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483":"95031b8aa71f29d525b773ef8b7c6701ad8a5d99":"45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c":"8b60b9b6ba375448de4f00de51d18706ef8c4f97ba34c9cce2b0abb0698436009d1d2bafcbef73a8b5dff6a3cd5db5258ac84ef724b28d8a62d715da6e111939735366a7c66470364557f546377d5c0e7ea9064731cb7149e1051d66a7bed14aa205bdc5d4b9ca029a1e68a6fa2c1db22d27fb79d83877cfaa6742119229a493":"5a4ae9f8fc82c9198d9400c51f282493b194a07b":"87032f263de2bf2f268a093f33c366d6bcda772ca959fa17cfe948f1dca3e75ec94276de91d9bc60fc6ab9224861c55dc9ccc5f715c251dd508bd438681cab205059050f8e11e8a5468da42d20aefac53d7a9fb71f6424d7bdc65db873ee4f9dcd918091aa724b261b6056f320ca7724518e14cb8dba0b713f54a0fe44ff1597":"662351e9b8c3a607afdf3ee599b46681e27b83c0":"5d159f894d250db90d7fccd49329e44d1112db47":"37231bc15195ecb6badb7c3fe80380ff912baeda" +Nist_Vector_46 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"b0dbbf4a421ba5c5b0e52f09629801c113258c252f29898c3354706e39ec5824be523d0e2f8cfe022cd61165301274d5d621a59755f50404d8b802371ce616defa962e3636ae934ec34e4bcf77a16c7eff8cf4cc08a0f4849d6ad4307e9f8df83f24ad16ab46d1a61d2d7d4e21681eb2ae281a1a5f9bca8573a3f5281d308a5a":"649820168eb594f59cd9b28b9aefe8cc106a6c4f":"43a27b740f422cb2dc3eaa232315883a2f6a22927f997d024f5a638b507b17d3b1cbd3ec691cc674470960a0146efdecb95bb5fe249749e3c806cd5cc3e7f7bab845dadbe1f50b3366fb827a942ce6246dda7bd2c13e1b4a926c0c82c884639552d9d46036f9a4bc2a9e51c2d76e3074d1f53a63224c4279e0fa460474d4ffde":"33c7ba88ff69707971b25ac344ae4a566e195f99":"77c4d99f62b3ad7dd1fe6498db45a5da73ce7bde":"23871a002ae503fdabaa6a84dcc8f38769737f01" +Nist_Vector_47 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"ec84bed09ecb4a6feeec3a7071b65a4c1267a03cac8b5a0500c237b20dc058514da798335a21b23d7e8cbb15efcf92e6060a13fb77f4998147dec1d0fa0edd418b0aae8eb0056fc7d4008b198bd40b969dc10d79e15b2300820323bd5e1b7d894ce8e7bc8f7ceca129b5e511ee1c8caec25514f537353a912a971b8070e3f141":"952b61ea90df3f788eab61d95be16ca28001800c":"d7a0950d0e6362b0c942ad8af67161df07debca59a4cfa728f93d49b6e296a23969a65a92b2e05398a114d73d5a52b73b71ebb28571cf6b6002f853a8f594b5c93b9a84233f3c552823619e0aa847d60203db15d2a916ad02228325e15783988f4159e05c8ca088360e6ea7ace51b055102153c00adf335ff6affd1754f2a8aa":"7982f6b8956c2bc0a2c2d02ecdb9e47d23a7ba81":"b2570e0e19935438d32686c478473a0e45dad023":"39a02e9803624f7e90feab8714cddc41e01f8fce" +Nist_Vector_48 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"80f757fc06409b70d733efdb68b520f3f9078ab936c4479fb98d0beb1631d8303324470824862224b439bc85decfccb8de8fbf36a2bc4ce3a092688249ab4eb9febfad268245fbd7e72e0f240500af71292ea23c8ad4b71e032106f587f4611663137690cb25241912763c5e1879b3ab67e2187f92d821fc81f552e2c355bd73":"2a5f637f4b886a3d37c4369cab04d78c79f1a3a8":"1f03013e66fd1e633ff743894c37f6964839a52cfbb6e849cfb4eac9a3c9cdb55c28e14788865c212be62047cb39c6365780bb2e627957d34e99232f69170a8efb894d8029d1b8bea8b911cebcd43b86bd536693f18bfe50c84b99911181ace14c3fab9fb6acd98786f9d2ad129c5efeb8cd0941a3d89098d5721d435343cb76":"b7c75c380bce0fffd59dfc3993e1d0724da877b6":"c7db4a9f54d882ec5f561705396c94834dd53c5a":"6752cb6be9b87265d76d69b382299678f96a5faf" +Nist_Vector_49 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"36a25659a7f1de66b4721b48855cdebe98fe6113241b7beddc2691493ed0add0b6a9fbbf9fb870a1bc68a901b932f47ded532f93493b1c081408165807b38efce7acc7dbc216bef74ed59e20973326553cc83779f742e3f469a7278eeb1537dd71cd8f15114d84693c2e6bbf62814a08e82ba71539f4cb4bf08c869d7db9dea9":"bb318987a043158b97fdbbc2707471a38316ce58":"c9003995b014afad66de25fc0a2210b1f1b22d275da51a27faacda042fd7645686ec8b1b62d58d8af2e1063ab8e146d11e3a07710bc4521228f35f5173443bbfd089f642cd16641c57199c9ab6e0d9b0c01931c2d162f5e20dbe7365c93adc62fd5a461bea5956d7c11ac67647bedcead5bb311224a496aa155992aee74e45ad":"2ff654b680e722ce65a560e785e8ce0b4773c86d":"17cc53b5b9558cc41df946055b8d7e1971be86d7":"003c21503971c03b5ef4edc804d2f7d33f9ea9cc" +Nist_Vector_50 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"65a3c92453f961de7f576d5a1e3106c38b7f20813994b5dd201546dc455065dde59edcd84d0fa17a85c0f9f99171d67a34475cef4f311951f2eef7f6b64a5bbc6da6d1b622480cde56a07a77aa6040ebc1fcb265b3b624881fd27203dcfe8a12492198474a990cb9f34a1943356fde5bce3fd83516da8bf780f8cb1851b3b954":"59d92aba23f50ad08b1d7c2ad560ded36b94ebc8":"0fc514ca160f34f2f6ede1ba5914d5844c9de514208c72569a0b36ec92c8b2c8fdfb7d68127486e58a04a32d0d150e51bb05e66624cb622edae19a6b4b1d8317689baafa30168ef3759ee82e614e4761900182df90e9cd2d931153771b8be30d89c2fbb95be7e05a4b29da968ffebbda5c0c9839354bb59dc697a269063f2f50":"3d0ea569b4dc69342955f5b240af66d228791e50":"77ffaf4290c41eb089c1d7be5c8d3833027702ef":"cb753a2d4ce0e59851f814779f343beb615f2770" +Nist_Vector_51 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"1526b64ce41cc8e2cef26f3706be530a36ac9cd16ff69f05773e9447ed9452064b7751f3a64919bfa3a7e1020dfc175a10acfdf096fd41c03372e4d2abd7ba887e0076716ce9552f2c7c8eddb1b3fca1bdcd23300ce2b1677d4a2debeaa7053466e59b098771bfb9218e0fb4ab6b7418abebcc34d681e14c4a8975000d83bb44":"716290d0ff2ad2329be2cccf825f2075be659743":"d30eed739f46479364d4c2bec18cf4c75c324f8db8184d9c3c175556a00acfb0a6813887b68706e70c167f4063bc0046396ba1bb3226c29221bd64ec4cebc990a7b404e26e2cf042304a7c57ab7de418ba671e17f7f502b9e1bb5984469b304ebc0c3c3a5a69cff7abff4110130316651e0f93ebd2834dd044eae1fd6f045102":"919d698fe37c027e3e40cdf6e77f81e96d8bfffb":"31abe8e7458ce363a5f3985111b239bc8df8dcb9":"1d967be0116128699d167fc16e5e920a41311669" +Nist_Vector_52 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"d7852ee90b3f1120bb11249808c7e7be14fe577bff1886be3c42589a6eeb06a1834110862b65d26cc5a2e5d903ed24328d684c96e3babb37ae31f96d32f57657a3bd7798aafae86f44ad8981e7cd47d7f31bb4564a757c925c64da9820963c1c5148f589d6393004a6a58aa2c8a578f4db7595f886170e79e9d57bf7ff8fd0a7":"0531cb42f45bb813f401bd239044df2d3d1968b2":"0dd37985163f93618fdea8e3975419fcf7446ff980851e18932d7494f809c0ae9c03cc39779ff0422cb2248ae1986f9aad2a43d6fa6878d244b429aac5ea80157980577e5ba0d11b1fa340a283fa0a2d651e024331e6bbe7d01ac034db37b008b91f9f88d135fad23af8c22765d833a9c9eff7accf668e17f9a8bdf59317c202":"739dbd1f84b6be2efdb921a0dfb76dbc6136915c":"44c2d6509874ace71acd1dcc32335b394c4e41e0":"37e78f13aec052eb7b07a8b9f6d54dbc77829006" +Nist_Vector_53 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"9ab91448a0dc9694be173ce6d9b522ce0e2f75fcb57720fc5eb8f92d8fb0e195030063968925a568636f4aea1edf6c5fcb86dcedd204539d8c291757fb8a51620abda59aa8f8502e6904bce0667d92c8cb3fcf1a61b1fb0bb4e9383b37eb469bd5c2f5a77680da62f907c2e263cb48402b4b12985eaab90451885e819b3e8c3a":"6d764cf62a268b0070bf80308622bb31941d4763":"49d7f08fde0a83cfb8116c9b7cdcab29751fca5ffe310760fea713c30e95e7755e65ce60928893c65020ee9b61f6c9c89c07e0fc503b7b031368f069578a9e6b451fef369ef90c26dd660ee1a6b8b714d1cc28245e9f13f187122de26ac2fbf5bccb7caff59f1de910551104d3a0e8fa9fe6b7eacc9a5fd556b7bf7139d6edf9":"c66ea7177cd6edf6b9079fbcf6737d3890469b19":"95da25d06ff9c02bc893fb032508304c17ebcf08":"617adb8de10da1a87413d64466b482409d27bce7" +Nist_Vector_54 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"c9c0e69f840cb6deb984c2575d7f6816fa35af03b4429c703a5aec90e7cb26e52413587f3bc5a0772be7b5e589c9a76071c1739833f4611fa951d375820b48d740626c665534d60487bf3e0a84eb6389e099fe621f269491c3b8942e03bbad2a5220caf51e7b4a2650e4b300024a0a96f0861b3206fffca83d0850f2a3e2a06c":"38a62d234e1aea0e847621e79dd17ee9d08bd9c6":"26f73219d0e7dd3a80e7fbc079d9baad4512891aadfd2416b1859f41adac31171ec624d8a4d6a10d5de1b93959bc49953f23492f18ab765f963a98584807d66629e5a1e057d77d42e3363458641a0469166a0d853b27798bd848aa0d3ccdbb40fa21b9fe62824cb2c7cc62425978e672aff0bbd8c8cd08e46385b0d6219dc56e":"5f5755dce464174adfe00affb55a71222d83da85":"b6b25a9da110b5d57675889eae75ab58a4d8e281":"5a60c2b0adbea4c5be065bbd0fd0e3ce4bf29200" +Nist_Vector_55 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"4002de825bb87ac346bd8487cf6be053cb30ee67c66434217107a8b0b52e5726900615edd2fd0acdf88a7e65e7dd3ba6abbbb371a1c840250d9ce809e7b1111f16daf5194211715ff5fe631e378408749848a0c81a289b4338bccd8d1053f863197ad02920fcbca514e2dfd94a8b00f90cf034adfd776f4dcaef2c8dce3b0539":"c8f0d697bbcbcc0e31864f8319984125f52ff5aa":"149bcbb4f5983db56fbe998fcd02d736e6d2f18fcf96468cd7e99bc647436fbd74fd7a2cc2f0d8866952b97b44ff644b5665cd1065b07a2c33d9151deb335e3522c1b77da1443a1373c93bfa040da5a1353b88a78e3a5a084e6c442db03f7fbb4bdbd30b1af3963f8c5d3e83453294e3a07ddacfd43dc8f9e83032fef78420c4":"b4281920a775fbeefb89615b236217fd1046f2cf":"d3cde170d82154ec1bbd9077c486971120600376":"b008fcd01b5e49a85a921bee1ddd706212799086" +Nist_Vector_56 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"f7018ff0af6776ed4234c1fb9cca1f8cff31295cb9f76d8b73898430097c49a40028441771ea1de08ffd5cec7eaa59e32b3a170329139227ba86e0c5efcaee382bfff962249da853dee418413f201a28fe45b8293c262089d2ceeb9af67529ab011f04f5eeaf82ba32dce9a9821762c3351b00206591a3f87c5260a4263659f0":"9dbd262da7a529f80aa667b27a29d6a52671fb89":"6c206e71fed8b363fcf571786ce1b4e52a404de7eda7031e5d93a47ea668de43dc7073e31d3b6b125ae3e8ee45aed273bc878c73423b225a1526bbb149a0ce5e9a2d2962bd6d332375860f84ce0e787a0af93f44e64edaa2dce6ca22bcc6d48b84b0affba342753b1842941067d5b8414c356138e625bb506566a27b335094b0":"0f0e02596ce6674684e7ec448d2938de12842fe2":"079b08bc016c543d09d6b276c023347a3aace9ae":"164c3c380f209feaf8ffcf53691ee3031c3b3fff" +Nist_Vector_57 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"4a18bdcccd46bb89567ceb9c1e2e500a3baed24ff2c5fc7f83cb3cf6a6f38859a1a927fab5e2fd7ea1e1a4154739301cb1957709103af886c929cf88d25ced5cd6f8cf3ffee7b088edc2f6abd1114398a3ab00fc21bec02e8e539ba12df70a587fbfba63195c6449b2b849547c42277834e1ec086b5e53d949846769e89715bf":"5b3e9cc0e0be3d714d1bb2d95e5146d27a58f2ee":"8e668dd1527b5d1e56aae4a6ca225e677368412324a79d98bfdad9a84d9f87c1357518c9a5056ea6a0882e94d4ffadd97d89bcf2f32ff442b25dd2af2a78ddade46b75aa8a5b1a1471764ab699d700cb2a28b959a3848edbbd6c9514ee849f833c43008531365a01541f9c0b65d5e7d3c21dc8bef1369a41c0405f3723f67910":"3d9b8166860e18a9306026ba669a3620c2954ad4":"b22c00fe0bc2fae7a4ab74edcd496c64a999c7d3":"85ba8dbbc93ab94a76133d479e3f79576944e6ca" +Nist_Vector_58 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"75474711821766b065e2448601e82b88153a41bfb5c6b6a9ddcf73170ee374a6625de19c560bcbd2020bfeab5cbfad8fc60ccfc95a1b94fbefdf815d9bfc43fa59315e7093d5685274b8afc3139b925ebf697fe2699b0feb1e42bca65e5d4eb0b4514af92dfab85e7f2666c87e9789395f354ce33938e9623061113465a4e2b9":"9b4a2536a108892240fc40c8c69a4b9b903ac760":"74a93c73d75500ca4305ca3184475b53d96c6fdd417ef23d9dc61b80bbc1108228d2543c1c3a9f2e7783ca69b019c0cd9a6d2b62b0ed93d4229da87bfc21f9e4bd0dea2c4e6d4d2f88201ab0504b31f4ef1558adf493e470adfc572ca68debc46123589ae913b967983dbcac6bf3bd8611137e39d5870057ae18cb84a76aae30":"a993b059a49855e359014151700d02e8292ae708":"1ed131c96a2c310e1f7976d3082a69a5af45bdd0":"70663e9ad7113ae57d4af6907712e0aaf88bc07a" +Nist_Vector_59 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"340df708d457df9413ef2bda225c5f558b90966cdd531a0b5aa745d5c3ea790debea224861ef12fb1638bff0121ff26dbdcffc299bf9f3a9c1fe6027400ff14c34fb06f67db9c30a1dcbfd996903523d85046382ff280418d974a3ece6b5fafe305e2e79b1d07a7c1eeb7a1277a82282be62831df7fee38841462602986a8e9b":"067e6e55be4744723b6f056b76629e93c297a585":"6150a68d64adda3d3fb5a973c62b992ad3fe538af7161bae41ea2f1799304fe5b8c864e061d133d94c16a4c6b0ed8dffdf2cefa7394015e75c57b181419dcfefe3409d3b53d86911c749f9f28f7c1de99f7e4b2ea22a48817ace4fd9974fa53b8d4f05f5731488813803d7f3aaf1cfa138bc73c4d27ca1621e9226661883e9dd":"77857e6de8f37eeb6925a87c027a3cd88b9d3584":"4f182ad42cb5671d3162bb9d04a06cd20edbc558":"a6c5417947447718ed1cb89a6efce2d3116e50d1" +Nist_Vector_60 [mod = L=1024, N=160, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f":"da065a078ddb56ee5d2ad06cafab20820d2c4755":"47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a":"9f23c82563ab7c0ba86bbb989335000a493b291e5dc17ce729494958903623ed99df344230ffb626b1dbefcce059ae16c2ee7ee6fd2a7807336cb71b8853e2ed3b74b2faac82a831d53e03d7bbb96d38df98fd19bd4c1a6248cd507c89f7995f59579afe5319731b443d6871e558f5b77f2f9a4dd99efb305e27916594524e02":"b457e1756ee9056fda7207616cf7c04a33afa66a":"96d7451181fb253fbc3f441409be5e5e0144972610e37fa82bc2af246637a4c918023097875255a217ea895daddf46bfbb174749b04c59fefa6289684f2f9aeadf5ce7ca47f0032e384b7d50597901181501cb5915fb4686a6ad7bcd5b46862411a4df22b1ed2a56905e07c0a936c9944213194ebefd4ec68597cca036338b3c":"b29f28659dffea28449435b5a044487e29d82d6a":"b6599fbddb4856276df448cf09d62fd7657de6c3":"4b49589099be5578322d829b87b43ac07f62e35d" +Nist_Vector_61 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"3a84a5314e90fd33bb7cd6ca68720c69058da1da1b359046ae8922cac8afc5e025771635fb4735491521a728441b5cb087d60776ee0ecc2174a41985a82cf46d8f8d8b274a0cc439b00971077c745f8cf701cf56bf9914cc57209b555dc87ca8c13da063270c60fc2c988e692b75a7f2a669903b93d2e14e8efb6fb9f8694a78":"07ce8862e64b7f6c7482046dbfc93907123e5214":"60f5341e48ca7a3bc5decee61211dd2727cd8e2fc7635f3aabea262366e458f5c51c311afda916cb0dcdc5d5a5729f573a532b594743199bcfa7454903e74b33ddfe65896306cec20ebd8427682fa501ee06bc4c5d1425cbe31828ba008b19c9da68136cf71840b205919e783a628a5a57cf91cf569b2854ffef7a096eda96c9":"2f170907ac69726b14f22056dcb37b4df85f7424":"a53f1f8f20b8d3d4720f14a8bab5226b079d9953":"11f53f6a4e56b51f60e20d4957ae89e162aea616" +Nist_Vector_62 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"6f39973fd225167a7673cd71ab3534d2686687c332f93fd66db5f1ca99678efd2825a84cd7a7107adf96501dd1d05e7bbc8d113e087bba77b2346b4364132125245e9aace3a146b576f654c86e07fc1914cafa209dd6d04845575dbb279cd1b23296d01ef505b5e1ce7f2194f18988f355c9b34f920ab35152e03bcf792ac529":"8d75294b56262e42a82db41a4039615396574dbf":"110e398e36c9d2726e77deb465dd23303f9e387778b549700a52b9a5468512ee377ce3d7dcbfc6b64ee353eac6a43898b26484058ba1b24b229cd69c994d976d43344c181ea6c47df0062c09a16b23ab6075c04a0899bac3e4f034a983bf90438f6ac26855d8a5fded90172e7e8c196a2ce7e1fc0dac94278aff1653c3ae09f5":"66a1322607ab98aaa57c12a5cc3f59dce8d7d0cc":"1b9ed39bcc4b46ed0007679ce9c3f6dc7c4157b9":"258d4136ad95b704a7959d04096dcd781eb54bde" +Nist_Vector_63 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"7f59744c790c0f985a9ae101d9fa00da3b95d2473d792805ec1d6d1e95222a6f30ee6ab8fc5a632057153f237ad3aa2fae8f1e51eae75906d07e576dd0021ac1711b1c8853e62d27fe6b098766b8ce3e76d347c8e49be0ab05d0d12fd777a85cffc7ad1207a9aa75643d7b415ba4b1b97dc0ee19d05a607ba063a0341f176104":"25b7fedcba71eda85fe189bf0d0c43214ab6388a":"3ead9cf211f3859d5baa5155fb62331bca3fff9ecbe182ebf8b04db0ebb19eda548c86db4cbb5eca98ce449cfd51f1c460d7848326eee22fcac7247fb889ee415c4933a909c78ce9bc50ee190116da9ae2547ae6242a340ddbb9a15ac818c4677f2919c64509d03c49d1307bb2cd78e01ce5b25a9f47d828fc7584ebce366c2f":"8fd754defb1274bb7ddea0fc13fdc76722442d86":"38f52df78b0e454d3583208a0fce03b904eec816":"5cdc57a943ab1f269ca11c63bcb1059ee76f9c2e" +Nist_Vector_64 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"16250c74ccb40443625a37c4b7e2b3615255768241f254a506fa819efbb8698ade38fc75946b3af09055578f28a181827dda311bd4038fd47f6d86cceb1bbbef2df20bf595a0ad77afd39c84877434ade3812f05ec541e0403abadc778d116fd077c95c6ec0f47241f4db813f31986b7504c1cd9ddb496ac6ed22b45e7df72cc":"3fee04cc08624f3a7f34c538d87692209dd74797":"6e8c85150c5c9ca6dcb04806671db1b672fc1087c995311d7087ad12ab18f2c14b612cea13bf79518d2b570b8b696b3e4efcd0fda522a253bbcb7dbb711d984c598fa201c21a8a9e2774bc15020920cd8c27c2875c779b08ef95093caac2c9cea37ec498c23dd24b684abcb467ec952a202cbd2df7960c1ef929cc2b611ca6c8":"934552738360670c98b9c5384b639c46cdecfa83":"00018f0fdc16d914971c8f310f1af7796c6f662a":"62b7aecc75cbc6db00dd0c24339f7bdb5ae966a5" +Nist_Vector_65 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"a2ce90b51a480c0668b55936bbeebe3679f8d406a0b694b90345749e3b9c67776cae9a62c25cc011cdb3180263ddd73aa2090ec7a749092f6c7816c26744c5393acb08c6b7b359bb3a3c7543684f8050ecc6422234ff24978ae06b91d6a24c086d71eb1761caf14176d8bacdcad53b7895bdb0e053c616b147ff73d2d86ba3bc":"2d667bebf445cd3ee45d5815e07ca5735b858ada":"0e6b419da8b4db802d938873e3b105ab3eff432d8a1376602059cf2e510f696a2a4e42025670db0011e9be31e8b1403615b9a339ce654a89a2d462ee20c080c4479648c5c00e172ecd537c934e7534af7002bd6fdafab56506680c019ced38779d954091645fedf5d0057a23ff634919fc56a96771ce21fa99ecd9aa7f7985f1":"4aeb4911d38f1f634ddf5fe6c970d943ea51b266":"5b13f1337ac72e419867c92f9387f9df62883aa5":"90ab5b68fd8253b6bb64c61759164a97834c39e1" +Nist_Vector_66 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"3b6eeaedc5fb38ce8691686c89993caf17c9e24fa565a9e8d48436b87db62fab839c42d81fb1f8b8968c826e78d333b1d99d5c36e08a9a0ec7554c2bde07fd8ec422af128246ba3beae18ef2be755db22a869202951cd95796fc2ff7ba2a6967d19e5ca2304655bfdf879b7747f80a59b1dac0461cf6e490378e56ab378584f2":"71dbbac59768e1e3093f0c60404731a2ead482c3":"4a7ff667f7ab2891a8a69ab5d15d93d1fd833906c9b629fcb9b49e84d8ecb35b397d93839d7985590326cffb55a70e4a51a2829e387290f6fafb7d226151c282470224fd717f3d526589c6eed9611c5bdf4bde63fcc9204c8007b0b143c49d1981835658bcf800a2157c5c143d76369fd6e78d0a3f800b8a3a8f0e11c9059dcd":"8f78910d1e8a9daad9523626ee7ab1d0a5b4d977":"61380ca86798fc5fb61c35675af08d5cc13c25aa":"54ddf68f476884af3e0e6536f3a80925ee63a402" +Nist_Vector_67 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"01197ae960de90a93d9736896fe136bc561f0550c6b1cc3631b31df683017c2ab8c6f41d2745f1a797e0e89dc3d5878866c3694a080366757e6fd892d26668fd2d860ea2a2b67fdaca96e32297758787ecc0a7e1d304cc719803272e72e339b3f34c347e47b91a1ed69ca8062cd350dccc9c2264732b9fdd8462d9f6fc76850c":"45963a0771456d6ae897edf7579091f5f8c76747":"373081770a9f4dae8df5dfa70503e149d759ca37408549aa34d1b49b3176a39d7c4661e421a1f5d61e3f77b3c4b39bb2e63cd24919a2910a8b155e1758f5a375da60f19d2bf4020e828f4237eb3e2a36124a6a3914469d6833695b83b9377fb285b27bd2689933c189c7fde42e1e0e20308331fd56ed0db2efbc77ea3ac7121f":"1f68d020331b81fc1aea51907e94f7d62ace9135":"41ed170c8bf6f20fd1ce18faac97565fdb4fe6f4":"7c8c6feace68c97ca43780741fae58f2f61bf765" +Nist_Vector_68 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"0d5ab27b2b7e18cfce4ccda13aa1a5a8c18baaf39b14e642b8f81b30cd5418a1dd05df22599fbbb3bae4fee1e4b2c150a23e216c133fe2d8235485e34f80685c66bc0c190af67a0a49930b476b2803e12274cd43090921bf668fdfef155072a3cdf17901427afa51318afdda937e283e2c60d85e3bfe07f3da5f992c1fca4b98":"95bc588bb848751ba57d7a9ab340cb00e79e06d8":"1ca36e3505ee70a56afd5dc40a48e97979e984dd2d896abc7a491d3461c6931668a0cef11e45bb66c611137999907ad7e1f7cfea7f7ed49aae935bfc41443293e71dd2fec29f37a9544672ab9250caa28188f390b5d4af13bb05e9692c1c6a4d6aafebddaf7eef1834fffe0f5391bce243789a2d55d29e2b90ce120429f2a075":"07a4f8000f0ecddb72302cf4d7975c7efc41c143":"66015e5fb3abe9d78523770f7ba0990031065ad7":"4b8b153d5b01ddfa91f2dec6f0faff02e6e87218" +Nist_Vector_69 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"906a933bc823a307e2ab29a4a8f7f1510d5d303504fde38169ded168913e3bf81d53a4389a3e73a3efebd5e42cf402bf9fdc5da5ef46878165ada6d2e07299035a3987ed6c2c6c8becc44ea131a9493e72aee28242cf7cfac38ee870e54eb95a6efa9fad74354b281cb63ea71652eba1ad73f841dba7778f3a03d3e00190ed68":"8295ed7e125a65ea1762aaaada34602a7bc76845":"4f3ade3ea4f7066107321e8bfb12eeaf9b3c7bdcc6147908754231156b46e0639c9db9d5447abd2d0a9223c85d63d8b1dfa69742ebf7e0419e608c4b18c3ad9f55f5d2848edbec4e7180e34bfbb1f6b6ebbb68649714b5fbfa6cfab4a01f655008a95a7eedcdc2f7171094563a3c1831e81f5ca075c6e853beeae87a67ff9022":"8148e40362a255d240a3e6af746a8880162d78ad":"99c91e0794723bcde34594dd2268418dfb353443":"42e9c49d60ad8f9b41f290ae6b772f44be62cea9" +Nist_Vector_70 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"1d6ba43a0ff677cf8cf68d6a1d3304d99490a7cae56fe35318f38ed0f5879fe254703fa77458c45e8a698469b899a215c25e869fd28741101d27dc111ffad6980f8ebd748f6977d5d60438e6edec37a49d3011f8f0f08525156ae60bc91abe661638f4b9c6c365c3af1713bf7f7225d4afad7a1b531a331133d8b8fd238598a4":"8d3c302da7b77ece9ce6e280e603bd260d2dc144":"08ad77f233334c04ca2282f6dac0b0d8a00d596e02e836a767a146ef80624b33fdba8b35204b20bee8ff2be9a82bd80131c0aa898b17eeab5af24c20551d5d636a11548fdd2e6c616b09df86b057e5702146ecc4fa2d44d85bb1427e7e3576f698b4f21645a1e00479d08982b0573dd1981bbd405c2a45d7de9242afae8f95c9":"79989e8eb43520091706039415794d2306329861":"a2b42cca55bc1ba33f8252d1a89c8d89b00b3950":"2ec5166e35e63f0fa116b3db1bd18681a4399c04" +Nist_Vector_71 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"3bd0c5b759cb710c52b81fba48b6771cab17bf1b67eafd08f4ee1777dd473064dd0bec98d3582ee1e991ab9a91a6fe558a41db9ae6b21a057932811440d64c786b22d150e3d38c71900ad5b61e0530744e765b5c2ef30bcb96e726e3079e440086ef300bae9000df3403c33a79849f8f83d6c03f77eae98052578d82d628e65c":"4d3e42ef42a60630edcc842f25a1b33c8851c742":"3a1ed976b7934bee3e80d69fbcdd35f82051ccc214bde6fa756be67017ff60ac6847cf8d1f823f890d26af8cd351716ad2d4eefd7f06c1951ea4a7db5caf250f407b78f21fff425d0cba1b5fb35a5b5dcf062a1cdf2507af74789326710e334faf3c501bd8c8347225f94f8973adb7a8b5def9896109d1efe550325dd89f31d6":"6c59f3cec7e34db174dcbd6bfe224d52226c56cd":"77d62ec2a95beba6c672d8422ee663d1d18049d0":"2a339cc8f567c12149a8917375ec6ca4b47254a1" +Nist_Vector_72 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"8dc582a2b5af65e66ebdf5b533d8e22b38b5c1977e578d3213a110e9d4837a74d4b7bf7d71875690b5b71c8e8afab89434c46a8641cced1a130e21cd0c805ee45c134c7c0df75d5cd30c41818f7ae475dd6022877c743d09d54f0c94581ae7bd4b423f02e19397be7bd4a904b88cbd2f814b1dff1e796d9f2d1c8470b796c69a":"6a6a9874f0f89f04cbeaebde3833ae179ade3f5a":"5d6dc1749f28cb8f7c014d5c5516cf5bc222c6d9337ac0089b19b90b321956cf6192f3255d0eec45840810c21fe91cf5308948852a57cd0189f15bd96af8380d19cb821b1c56afdc38a94b2c32feb18213939693b69f2bcbae7e70ab09ead3b6a8b7dad3c4f521ad0455dd4e872b3627d4fed20d5efc78f6ae467fb9267ab1d4":"27b2661922214411aec66e58cb36142ab3e5a256":"05363bcca193d726cd20e03489e1b13b7df3bc98":"31bdaccb29e4a60023929f182199c070b71ac575" +Nist_Vector_73 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"477af8c025181b557732b9568634b1324e6669b4c28a0bcd4c653d4c81ed68b2a2043a800a314ba95e50deeacc5ee9c2ba6f6f62fdba0e86aca227d727377552a3abdbab601c2601846ec27a192a3f33e7ffdbe4a4aa7beb2b3ff6c91bd5cd5c890bcb6f4c908ff5b9b555e2a0a7df8c3ef6770136bbf009755bf6c3e6307310":"17949e838d7c93e1d837be65b3c4482433a1b208":"2cceddc9e2cebbc1e99b83b03053bb14a9cfaf072b45e4746d18cb3901f6a2c3cf72da66b0b9b3e105bd4cd0e5427d7e9b657ed71884cd49f51fe8fa18a366018a3eafac3381e07a5b19f6d3862ed2916094906e75286eaf1d13c485744b270404ff9adc8e177833043bdc34c307e6fc9c55c53d8ff84a6e251038dbeb5ef774":"620f07d7e7ced030e669685ab8c39174d88c79eb":"3591c521b2a56cf46051c0cb3d444b9a22fff63f":"7ac78ee252440cf9e8510494d1fad8b518f1e128" +Nist_Vector_74 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"bb6593ff219c9f20aa47e1e157e88ed59ae29c8940a527c82e0e0f2e855fa98e94e07be1f6bce3832b7ea1e60a5c9ef583f2ec7b179227e4afdcf829d673e1377f832ae38e7cadede415964f12baf775d38ce38e945563e72861519197c2d08f28d8b6466562e059ec41741de349ed5de2c7d6cc7518a87720a248b301733a47":"301c11a34edce1f7ab040754e0b2d4fd88572187":"15d9e20c3f39cc9e3b8fb65feb64fb1568f6efdef6457d231c491ed51731d58f06e45ea5d665d04969823da4e6750a2c3d16c5ff6080ecd09aa39c006eedceb4dbc16ebd64bc5b1e44b831a6bb25afbcb3000fa6b6c2000860014011189c22542c145e407e7b59f6d3fb1e136295ec850b14ff2f4994ea37481e80199910be8e":"117e12f88d6e44fc7f4d51d5384fc31b2e3419a2":"61e727716cc96914509740a7cba6e74a9dec6406":"2e77c14f01f22180bcda5725cf0eaac9ad13a7d1" +Nist_Vector_75 [mod = L=1024, N=160, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5":"a665689b9e5b9ce82fd1676006cf4cf67ecc56b7":"267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82":"565f19244468515e8463d07b425b4d5f81ff2efab5156ba19a63734219c226ccca5903bf9c35dbca0961db7c2e3f6944d057edfa6c2394c39a00f1c42596e7ee72ed644c6a182115bdc44b9010c86e7b0ec2e3bdf7016c5e04f455b4cb693e32490b8f494bb4103b3b5ea6808222452841b733faf735f10a95fb283dd86ce593":"07dfca41446b2f4e1af2a67bc8468db9a9c2dfe0":"664245aaebcf5c055c32109b2159a17473043087915f14e959dddc0c9b20c726f0124f1ecbaf202fe2676afdabd346a7b5bef769a25c6f733612d7378df1b2d4c518a2da5b3a4cd0252bb8180838a46389a84693be8cc24fbdc639b62cb21d8abe1272b5aa06222fe2133fc5556d24e75496a53e1934d3b5848e510b69da04a4":"4522d27cd17a6ee739873d69f107d872ed7e2db5":"5ca07bc7cd9f7a60cf79391d873b6fddf5a48cca":"9799c74a806fc196e0223fb1a613fd178cafbd99" +Nist_Vector_76 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"edc6fd9b6c6e8a59f283016f7f29ee16deeaa609b5737927162aef34fed985d0bcb550275637ba67831a2d4efccb35296dfe730f4a0b4f4728d1d7d1bb8f4a36238a5c94311fa1134a93a6b4de39c085e9f60ae4e237c0416d58042bb36baa38cba8c896295b745d5376fd8ce42eb6ee5a1b38f87716b265b76e58cfb24a9170":"6132e551cdac88409183bd37ee1452cd247d4834b08814b275be3ff5":"289ff18c32a56bb0b8839370647683a38a5a7e291410b93207212adc8088d30f93e9e4abc523f3d46936e7d5c90d88742b36afd37563408f15c8c1a4f7ac24bf05f01008ffee70c8825d57c3a9308bad8a095af2b53b2dda3cbed846d95e301eb9b84766415d11f6c33209a0d28571096ab04a79aa0dc465997529686b68e887cd8a205c2dc8195aef0422eba9979f549ac85548e419413643b7244361153ada1480d238cd00dc16527938955548dd5d027ded1029eeeb8ed6c61b4cd59341d8b15466e9da890a989996f4d7691e6072de136af28b5874bf08bd1f8a60cfb1c00888132909f515e04bce81b02951aa41baac68ffdb8c5dc77a1d32d8f2c10dd7":"7197392d32d0af6a7183cc3398556f8f687d86a8ff742be6ad38562f":"45df2f423e94bf155dd4e1d9e63f315ea606dd38527d4cf6328738c8":"59b3e8efa5bc0ccbf4a3cbb6515c4b9bf784cfacdcc101dc9f81d31f" +Nist_Vector_77 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"3bd2ab08217878e6774ec7797deb75d5c94c40e24ddf1fac8dde3a29c86b26f57157d329aac31a6622e1d6dac97e22695d7d1f8e20aa26b06795c2f878ba5d2b9cc4b16d5fa60a5fa5c24c09031de2f970a9b57ea24af17192ece21a4d120fdb52e62b8238f778ff8552fa453c0a8891243fc8757188e9c4e0e749f7e9cdf1c1":"32d53ad2620c156e4617a8680c543839c9be93103e80cc0fefa44ce5":"b9b0e1cd37bafbedeed173fd709983f53c2c427f9f61c895fac9eb549bd6201d05efd551aecb98b2df80142dea7a35491d474a3adc83f0da8dc4eacd7f6d7201c6fc0ab798abe89dcd7d0310d5f00fa10d211f18ea853579e2fe31ee55371d1c9fc4cfb050786586659bdc0f1aac4c109b9e4f9416d22c42b39a471311e28a8ed62f1f41bcfe06e074bb2f1acd29597953c3b69d3a78831fb2f83665d04a1395775ea3a2a6ea142ec00507badd4de0d9c102eac7bb894f7453e6a8e0dd3f14978377d1ddb1fdf1c55835b9924f42ad45c847c79b3f83fbf924f80b78f50329731016763e01ba8ef69e81523e181584f45c21e3c8edfed4e2ec56fb7b02aa4ee9":"2e8e4625de74e31bea9e480a5de92890095b6ce36897a2337ff97d53":"6d19fe3c415d6b07d6a1039a1fe34b106daa2eea4cbca971cb669eac":"14d7decc2cc05a1700fa256e4d2994bc4bd957bed0baf9a18bda7090" +Nist_Vector_78 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"c67fa77cd7351d100c7624e25418481f8fa499d75f5949a5cae60f96a0f7bfcdda7dba373f9f7512a5f1460a95213077cebd912e2662c43ac6bbe38c4479b04151a5e2d2880902d031aa0dff3f41126dd09fba5c0507634ed16c3938fbd3a96473a8b1ebdc37d32c767fd5932efa235555f3825a1595369238675453604d278e":"062bd01487e413074126d9d47258b5c7c77790a9db0af952ce799eb0":"31939ccdd393f747541a5c69f8e509761dd67eddb42e0bdfc412d4cc30d368d878d26d856c5290ec746b59c5e5af65ef3fd62c9a2dccfc1558dfbfb62cfecd7838e6d59495b20db5ad9d78e82f046f9f1598113aae0a79601d6b94a32e05f6ecfdf2b9c4cfa720debfc212221b14b0dd6f7078205a4f218cd4b8f10bea8fa481eca5254f365d01f3c86520bf254323d5634b96920a13b8f29d734e07fde8064eb0c9f8ebb6ae0b40b4aa7d26bb8d80868231d4558a278045cb5f2951cbfe0dc97bbdcee7af8c9b1e3b63cb49dc29f300775cdbe4d2d27894e27e0e7c9eada13a359f0b92b449e9d069b95bdc2aa7c85e56811c07207a150e598735996a6e5349":"7439c7aa4446ed540ba50b9c817792b08fc0278fa0af2daded03756b":"7924b76ee76ad7ff2ab327dabbbd31336750fc7663df4b5b94eeb62d":"5914cf965490b0bf8192fc6e169754bdfd31c48d716361dd15f45bf7" +Nist_Vector_79 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"fde7434c41666022d6d7dabc7a67315b1ff49a2a85a6168f2b6063e3036a4f35e66d2872af3d97e5beba239698d88e13bd036ef08cf0e83a41664c3d0d21863c24129a6a9b27b8e96c8029ec673e07af7246ab77a56c21ca208df4b1818deda906b553b2b23a37b5a05e29825ebeb47f53986c2bf26d731a5b731fffc353258c":"6e6bae97e3b37a402eca050d666b6483cf7d700419c5ab1eed1bed05":"59a14e36c9ededdce8000f04c6f7401ad987f1c7a5a070b80e0aaed7751d1d50d99a580cf205dbcc3797a0a0406b04776d80f2f2df418cee249b98672de7e61cda85cfbe903690e54642dc2a12a90ecf88c59256a4d77c4c0cb54e13fa3647b11431e1734f3ceeea04fbf3459665e999fc0f7a754683e48cefeb4a95fe473911ffe0de0f738960753dac33666c53ed2893bc63dd4162d7a6328739a252cdaea7a948c97d024153b55d14fd5304e3575048418808a952675fafb95fad84b1156b24e98e048aa777a745324ec13ba378e83b2384bc2e96c6095aa786bd28fc3be6bfa4db0c3c44fed4c351bd88a19e179a6a7bc12fc014f17de46fd12ef1287f72":"08544a6237ac967e5d11f2eccc6618399818b891df7a04d08cbc5e74":"49ea82713aaad799e263809e161b0655f1e74323a06041836f676980":"76b3f6c1647f8d17718ffb92d6e1424606ba9724e5290daa4ee95efb" +Nist_Vector_80 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"6676a3a131cef7e5647ea7590da3c704a0f5dc3f37f26913a70d430609cc2497c45e68b7bd6f5893dba26287ff0d240bab8a0761936aa709a2162ebf1c20a6136a748352dc39ba4403cbe4b0a5a54a729286dd193eac1a2e6bdc150fb06369be4443a60e75e5330083ff009eabb05232c52368a26fd237c7c3185c1c7e7d5955":"18faf583215bc4fa71791f6f34e682ab3529aa9a1a71c1fc7bd456a8":"ddcdf4c616fd6e4016099fb34ebc4ec507290762c5ee6876f10c6a2dedec97ba86a6063aa8ff069f3f3db40c9464afb1ba7ed691773afd6083586b14e35694a9ddc376ddc39dac57132a05bf88a0a6085c72a80a21c13e590c68c4e98eedb67f1e16c8cc7e9e25ff37c87ee3be9adf1ad0b838651b0fddf8d026969d4a16bbb828fcaf00efa306fcedd5ae19ca1a1abf44a2bdf6f994123ce941fd3523bc1335f51fa8dc5d525358bddf0c55fe2ce07ce974408d9090488837976f16845eb7a82d04c43a704be2dee1be2c8683b2d9e5c44f1833f5c46c65b6e62c2a720421bb35843fead7b9e0b3fc04c646be39e890e370b982bde91f2fc18442b650ae602f":"11b25b09408bb5dd784ad70264e585c978dc02cc1df8bb95a28aedfe":"1658a7ef2f444b014a1885b1eda8dad3605b96c3948e544e4c8825eb":"602150f67b19a5e3e39fc53abea02dd8f3b30d25c0b4ea0bcddcbdb0" +Nist_Vector_81 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"071f06a11588584da5576013029b5a14712581a48408bbfdbe34e17568c0a0e4d12c1e9c3fb227101440dd8dcdc415e3b49f68a26a0ec7612a10bbc64ddb8f7ec9e9750d1efc9c0574700875fcf52d00d37b9dd744ca841ecf7566977c1b5799dc4105d0b7a92551c5b33a50133fa300a5908b18f4c01936347c6049447abf29":"58882f1a41e08bf6c8dad091a299af0fbbd14515c1550906ff77f6ae":"b1f4dfc9c83455f279a3e7522734d6b120ab8ed36ccba7854e26504c707983d2a9c075045723f441abfc7b36fbb5d4bf0447678f5b709ca5129b74888a0723e905769836b9dac1303f1b9ace26554342b6e6d032ac4b477e011a4ddd3e2978fc0c449c64a66efe7d4e22e5a5fa2b01bb17fcdbec7185dd4115a19d972fb01a06b33bb18b9349ff95fb10dbbf2dcf899b1817d30ad48a99a614d57770ba764a11a84a8db3af3041ec362614f807196ea3b90d05b014054ff4e18524c795e6722c0fa1f6d1205d532d94347633eb132e6cbb596d8b341e65f2b2f955872ebd4d3006c45ac33da11167fa46869c7ee70e9cf147b23368b3aacd9c1880b09ac86a8d":"5ff04e754fe3246f35b3400b87a450192a7bfd9b3c03f3ece93449f4":"07bd3f6718e39839304ef54ac48bda8d9ac8ee051a49bb9131dcc918":"6496b2469bfb5845485004702b0c79941bc3c3007007ba169d8307ce" +Nist_Vector_82 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"71279b848c00208fb4e4d87979cf973b321b20d098dea912a3b4b5789cdd3b7ccd8f3993a9c92c34b70e9b0bd57520db56f2ded3a612a6169d2a1cc6350905ed0202a25c113b7bf8faec4edd2ea3b8f447ca75d15a712b4b4394c22de0c2554b9aa07ec8466727e7ef6f1f04ac4568d7726d9d77f50a2fd551ac29e42f8dda23":"292b1666d0b1fb361da268de725b11310000705964705ee975d4ebae":"7c8d63b9d55f59290b02a0fcea6d98c6c545e2c0d4b109a069694d80cb034dbdbd9edb6b4d9b152849cabd655fc77071644bbf4a0c7ea4edfe864a43c44fded163dd899c21cc2f9c33cbf56e8caf84394b24f8c14e84f22c3b0f747129d9aef41b6f1b1fa8ff5a8f680b496595dbc7b7b63a7790e3628747011b3277b06e80de0b67942f602eada60b518f282cde69cd717a5f6a19c8e169449e0d32a9d8ce8f09a5ada23c12a02dccfcdc0290a8bd46e8b7eb397494f32a0ecb49fa5a8edd41845eb417fbb8cdb89a9f18b9ad1b41dd4122ab349bb3c44951e4f9604360fcb1b795311545a61cfd67c287a7c9d4d3530214988e7616979e2ce907d5c7f3e9ad":"6b1b752bb180d8787c71505be758c0ce41fef428ac10591502c9a04b":"4cf5c26c4c2cd48c05508e52d743ef48685f6324141adef23d79a396":"59f64755a04c90a14b187ae142ec483c4600b6fbbe19f04a49e9ff88" +Nist_Vector_83 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"3ea03e9b005ec1954fee0c73326d8aca1a4f63648eb4cc59265528ee8e969ecefecf2797a0144c8336500e26a1c7cb1a642b1ec65201416e5deb355201de2bda695d1beba8dee62772f4d5914a245be9ffecf39408ae7bf1bff7c2451029c4ba0c522516e89955ad3bd699cce94c744081a9f2d60f5c5127ec722fa57316cede":"087e432b1c29c00508d768fda7c4b279fc088c48439f09980bfa159c":"1239c347be4ce6f1daa721fbbb141ee6e2f7c73098effe8e71beb9f1ab72d1b5bd3e78df770f7fbd4b3a9505702dacf102eeb8a16f11b4f809ca002ae3774ac0407e2572ae3ee1716458e5f45c493f4b921144e858d87d63773d023745512b0cc02b31ebfe5c24ad37efe539cd393cfc2b951fe1b6ffad2a2824c0f54bd776aa0afcf9c1ef427afc6cf4c4b17f66355d68574132e1d88ade3722513e395fc62d65e9485157c82064c90803a1a91f9e6b10af2f80699d917daa6b81415e508193152b4ccded593dde35f645e54b7cba445775eb16c5e19073f0a9eb5369bf2513b92158165b94dea511e938fb6a8798e040a05da94fdb5a4d44bee943b95b39d9":"0a8a45ce2412cb84e4e0174d7ecd2eb5b37ad0a53b474fa9bcf56d9a":"5ca2e971f21b70127a70c655eb87e20b2517976228a2c4e648d549b2":"44036b34667136a5140dd1948ddc2fb2bf679efee21f29b7ad87af7c" +Nist_Vector_84 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"a3f7033958c5b779072b0548baedf4f88d14f11a6dd6eec0181b399943d7246a45d50c4f7b5295dae4cd3ba7c4c181fa201581ad5c4b38793bcf454f176868e9cbe0997aa41987b1aa3d5ddc046be7b022fb5130594c8a9df03cfaa7acef817e3ba5e192c69a120299492baa52a9be83b8e871abe318b4a1f588f9edcddafc17":"5831abf9843eee928944e3dbb759dc7224910e1adab827a04f596e3c":"62de2465edbc1ef8458beaa205f45f9dc0fc3db77bae0f2b13bef6d803db689b8f5c747e3a041c08d326cd7e1891675b022a9da3bbaef8007784c56c86c4176c0ac876351d1062d9c270d548c8f4ec39a4556c66e76e507fc5f2540abfa77c178a9bae153435a7caaa008f36b9cab213ecf5e19a0f7b1e62fb9a9c8223bb689e8547b5ec915b04a85b2f53ccc792dc0a7a41d172e6f59f5b5e7c440350ac6a72ca9c06562d4cf8c60e70870a978312e19bf54c2481c582296b64554bd871accc8b251a7617ca5e5d2aadc19d484d76bc3826841f88fad1491d80679243e1527197d02a406348b247ae786108e5400975a38f3961758adc07ce740d8d442f152f":"36b3d1d36d1a8c41442b6fffd46bcd7977a306b53dcf7fa590538194":"1823f0a807fb9e71ad69b8e9fc674cf76f67c42cadbea6d34cf1f1cc":"667fc57a44b289fc34a198556117afd696dcbd96bf1baacb40d3f8b2" +Nist_Vector_85 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"680d878ca6eeb87e4ae158dddc3732784013ebb1da89401acdd6109089e5601d695f9e4e6ebf16026aa746dee80a01235033f242079af1b7fa6965c87eae8b3291a009e4f19d5b8f1394d866e7c9b72073a95652c0eed98e9484a15c9244764d8cbaabd49d24c207c705703cc35ebfc7683f4a0e6abf23fa07678350a6a00cde":"738a8bfc478e462c4bef8d5633e0793475206551bbddd08507f005f5":"511a3608c4bda7c82d7d68a5d30bd4c71e457b0f323027d601d6324a94893ab3d62878b12d98c44dcf30adab4352b70f4daa772df6aed3c07587e96c68f8a847a335051481d53903d1d1ae0cf99a54387b00169a1c9704bb62f1d98047dba8a0fdda734cd41611584d50554ad77890720c8ac29932097cf2bb1a8d0daf8663241e23640cc396f9e6877348f014073f4fdc5bebd115a0d74c2ce857e100ae3dc0707b95effa4a2cd8629fdd9bce72091c0e2612d2b30320420f42ecb0986ac3289251b4ae54e51ed83d0195deda9d4e5b398b037213d2f8f0ffdbf727214085534a324d4fefc1653642035ebdbe8167b150bd92b7cdf276fcf5e0bffce956a47e":"58d8b64bc8c2da02a294e9db46bfefb273e74870651e19d6cd017c55":"7ceb71480b5a7133401b5227fa2253332e04f78ea5d0fe237c8525d1":"484800e81f7b5692b79eb21ac2fff83c49c9f0d409c756c73fbdd2f0" +Nist_Vector_86 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"697f9efc8653fedb898c77f90f124bea5c3b893c49d7f1b116479e83d35cb6c3940797501e7f52887d18ae9f4055e1bdd124b572f7a6fad101f58b52b30ca30d9743a9016af891896d25356e44f982d406ea26a9b25fc4f903092d7e8e8713774a8be7aaac93a6942c1f2c48e9dea64984ae54f7ef99961bfd9b8d93226af776":"550c8755237857a0c8fc8a63525d4025713b89bdb127d1c330c3324a":"64b588499c9db3e5864192464d32fa3547f648fe676c150a8f9e153c5af57925c76dda4b419d60b22fa5cdea0fb6f0b8479c988a324d275bd42ef10d8998c36039eb4021fc0d2788b59a75cf25ed6ee4d44882b0c5c5cb8dcc1002c0baa4798107e0b57cd26debbcd0ba41d1b1b860b8eb90f6f30500b2e4be7a00b67d93c87d3ff7a6ce53b977a930999807fcbef57d8dc67a8f366124991389328ce7e70f9e5c22ffdedb28498282b4a9a9c68534a238322e0db6088ed0afa8bc77ce998c814471ab56767b35d07b94290ea106ff0c998b51f02222738ef9301f290c6b485dbc4f12b472a1192fd93f2d23527a02d95af0b422be7640a9702ecaac26c9e004":"0b4329f9e5ac4a117689883db2ca8e968d30a3aced61e27ba27c6242":"62054d11529b993a6f19a0d5481b99b4b4461a49866c29534a361a8b":"7a7fd0982e4e2118d1a069787a80b902493465f6620a355c86a94867" +Nist_Vector_87 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"d080a7dff1ef20e33832b99cf83c6c919c07620bf608e080aa301831ca6178e44ef7a4c115e93ab6d877e96652171610a51d927d2034f42f280fe87d7c1747c480ebccbf565a150f3240f6d4ce5d6eb0b2e964416791376ed22b3559cf93a019676e9e0be3c8d34f0e0d1152ec6c326d3dbf1d3303beadd188c3aa0d77e8a117":"2171d5e7cdda9a691dd27f0524f24ca41d5d801eb2ab0dcdbe6014ad":"41767ce26c780e3f2019f5a49a701570148e9ff3382203833d1b18e9d8d6a00c0b2258f2e567db31ad4e8cfb2621794bac87d9b3b53b79199a775058febc190d00adedae0fd3021291bc2d1ff0508bf019eca0c573fd863722f367d5d02bd9fa0d07f75406ac204fd3a5ca16325c661fe854fd00fb26654752febbe439096dd2284d5ab13de9eb004847d1d8599fee687cb2ecd0e5b761d91a7e9c58e6921f103024215e74f3de3cc12f5ed7703def041dd3267f1cde0d4fda8dd5ccc9c07b65de59482c4784b4f6fa85667186e2df6c5dc8b495be8ec61379f20923576f17680c4dab99312d0b6441306ae717c95d3f352ba4c096f01d14a7dc05b28ba9a3ca":"0f6626008e50c19def9bd694c00522cc861eb7069d55892e08ddff58":"44e70d2ead3c51dd0c5461dd4186825e23b4e751d8ab17d0b7edfaac":"48ffade27531db478f22fa0ec92bcfd2ffeb6db67715dcdc79bcb028" +Nist_Vector_88 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"f6a9afe241dd984e3bc265787dcc49491b3bca67feef32fc1e07fdaf0af6c5d06dccb47cdb6907511cb30c109f62e66718c5c4bb43d4b00b51235df43223d60ce1f9be3493a4dcb02e25ed3ddae10d131b481a61aef334b690c7a1ec74865954b39ccfa7a51a9a1e62e654bb89270c774f082adf09b579c8358dacb9db7ca1c2":"77207cf0963f1e961c3539d7d0f678fce517f67b728bf15e0cab3ae6":"b4138fa4e1dc6772b47e5a3ed130a13b822394c3ce8a0193d1dde4c90e7da1178e1126dd296252fa7d2f139a148ac44dc06a058b84ecb03ad827e66892e85529c362ceac2e7104b797b2e9826054de350596ab581765e9a5c9ff5143332c2f3bfd249a87fe1e30efd6fc057e234a1cd4c19e072bd71b32d55ef122ea930911081e26d998490376e3b721cc32fed92b82d545a7e6ba6e4eb434063c87db848df4ef02eda3fdf4f9d2905b78f7b16b5ea0b5998f1fbb0aaf62a1735591600f9801977b1b947f61a91ff2afb8727c55268972c87216aae900617a56f535ed18c4c5ddf8d7a54463256d09144d889c149e5b09bdd9d8509314b103b846f3e6fa1bb2":"57585204d88d73c21f66a150991531973978dfeaedd8024e268f18d5":"555a454880084f6cb2522daf3399fb4a501a943a9b6aacd58e2c7d37":"730fedb3a5911844146098ac5603e2baaae76962b33a327b50420a50" +Nist_Vector_89 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"2d1c573bf324028dc2fe00928f55f7fac79037d4d99eb185f3b997e042cdf808b5382d50a6aa8085c5d1958e67283df66986b93471c12e3045ba146ed5965c8ac5b44668f61984d21736cf1c276754b848e9fa636b6315b2272c19e65626bf8b1214d70989a623b5fff7803d28a663bbbbebb84c839b42720fd0e62246b3b034":"789375055f94b9ade40b0af8f70640336f5de213571ca1c645ca468f":"5ccdca35551cf355ec85db8d68010ded63583255b1d5fd2a522e29513ad3ce6157be30ea1c305d87de6c27fbe3a3fa5007128275d6e6183a65cec5b694bc6c027335066e01273fd6981cc5f60c3e33751386ce792ccb6e6a6db5d7f073800329f9cc46d19f422923b9748dcca4971e43a9d1f59d1c749788a8527ad524df74150b39eafa7f4d5608d1c97255654456eadd4d382ac54fdd12538b2f2ef75a50980171a04d4054b4cd79c71e1c4deb3bc6af4c874f5cf0273896d4fdc5847fefdcc97f5402c7e76484d3d2d70ac16bda41996cadcd83ad92cb37c0c1e9d64fa1abd9a2cf005c2c29a1737cdd6d63aa2fdaa560799b9f07d448760678477629f22f":"325b1562d5c9c61f95e6944fb12a4bb08d227c4dc0c8e9a79e391b08":"7bf3c0c547e21846212bf4cf3e38362dd4d359b7af6420f90da57907":"5ebd5d2d88cae40b37a9a5a84e6218d2453afa146c79a5d5f5df44f4" +Nist_Vector_90 [mod = L=2048, N=224, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5":"8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1":"e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c":"bab4db55bf6d3abefd1bb4e0f7bcec65ee6c6d8eb04b7c480df4e9e39150f10c38f1abb63dfe1bb9755c41b38955ba38ba938b6ceedfec02001fa870070c59df1fd2d72a814104c5143376a3136b8118f7b47bd1ffab53359e53f95c66ee12705e31a462a8caae481556ceff607ccc8bf1450772cd68081d3f15a710e656ae56":"6f4a94c9254a557787de9afa08215414db5a0dbc67c66cde1c1e6f04":"53c0b0b0269fcf2948667e28b11ccda9cbb9275463f21ee30da33c4575be5e111a182a6f38b890f20b8f2d224f5981895310db7c4703c1cec2b257f452d964be50c014b752360ee24f2fe1bcc023477a2d7085f58214df866b13a8d8af913146dc0bee078aea1ce645999b579498eae9277ed7e8b2c75f494efaa73a973f32232f08ce7f0afcba316623b94158de39bd4c0d513234ee1a481d5b72f4eea37749b40fff12ab620f11aaa01e3558e7a4c550707b71c16cb8cda98f46bf71769a476c3385a8caf7c886ae47d228b1771a8bd4b7f19e6f53047f62f029c339fe7575be93080ac748289149a57a0ddced54d72f6d4d344fb874ccc85ea7f3dd2164df":"14fe2a5a75756885240ff29abd19d346b2e7e5dfa76d2430f0d069d6":"118d2227be4bd91e98a2efde15609b2b9124b2e83c274b632300432b":"3a447461944b2a59278a8e1118b406bd3ff416775d65530e54f9e623" +Nist_Vector_91 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"e920fc1610718f2b0213d301c0092a51f3c6b0107bbbd8243a9689c044e2d142f202d9d195a5faef4be5acadc9ff6f7d2261e58b517139bcb9489b110423c2e59eb181294ffdae8aad0e624fab974c97f9f5e7dc19d678a9cb3429cf05ec509072856f5adfec6e29bafe8e5ba95593e612843e343111d88a1eaff7dc0a2e277f":"7b489021578e79e7bd3ee7ab456f659f3dc07c88f5c9a39e4f8cee81":"1ae10c786ad0902c5c685dae5c7121418a377b888b5f2f2bc76623570fd62bcb190b471ad5359c5f062f8819289e956d8aa6f90d1f8cf1ee72d3a1bdfd56c478dc29a19c4569b5a60e3a8f34f60656eac5b25dde5514a5c67b675423204f6ccaf0990617cc7355b9d3ed868978a252020a769ed59a6edaa6efe3377eef45f3f6f3e64179cc7db8b143fb835c5d71bfcfa1e2a9049bccf7fe9ab57546220fe3f4b7521c861739d138507e81a46a6993605441dcb90d6ee4afbc42cabe90a254444968109d7edd9694a023239f1d56175dd1fac115915e24fab563f4fc3f269bed2f300832d112596485a711417aa73bb4ac72a651a1fa5baed3636c720d397008":"37fadd419fcbd2b073a06ae96b9eceb63e29aee9ac5fa2bdb31ab85d":"65102e8f64ecb11f06017b1a0c0def3c29897c277c4a948b1f4da6b9":"21ad0abb27bd3c21166cb96aef70c0dbd5f3079cab0dd543d4125bd1" +Nist_Vector_92 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"da5e7b051c1859d22f2a3163335d277951973c172e06697c0490ff15b592c1ebd0fa5efa2463119804a3fea224b96b463e30083e002949a24e922031764bb3daff8101fa088af5457af36654c668f234a00cd828cc740a898c0cd3df09315da9b346b325b2fbec475210b75482affa61a3eff50c83c3a039fae5cfa8d971fddd":"9d8bba124417c126c1c011115906a7bdb7a493661d8a945e32cb283c":"5e276987b847b852cc372e986e8aba0633dd46c461bab58acae056d4d1a9df03a19df114f648b28e038506fd09ad0d95449d9d8058aa1b241b2acd3badbf9882697331de45b452345c051c2cd830f7cdd7486b1166b93891a72a8b7dc6228bad708720ef33235801c4d4c3c4f28036df6029a195d0019124d16fe8f76c525b7e8f04bf4b8d8ba6ef608e623224fa8d988420f40526c25ae3e4c79d5ae7fee69793e02bad9651ea0fefd3eadc5ff1ca2d142930355b1f3aea102221fa17b735a18af3b83327c8f33efb9a49b70211014eba43fa65eeaf25ebf452bc4b7dc1f407d0cf1b834619b5f73c6cab7051c92070aa06f7f9406c507d1a15d12c11bc839a":"1abaec5b4efaa83403fa970ff6027fdb596359df930a02baa12ed854":"313615836f0d338d81b670f116a5414d2ce90ea5ca5308ba4f0c8a7d":"dc1d4c3c06203fd598a476c891dfe5934162d0d35f37f1c09dd6395d" +Nist_Vector_93 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"f49895b3290d9aaeb4af611c5e30afc0047dd42c07216211d54977d1497fa4ee6abe11000d6ac04d24b4c50f31e06ee8a74774d3d304137cc6b114d145250ee7e94a12a1ab592ae307ef5d930cf39170e9756adc5e7ba62a54abb6f047b4500b6121e1f4a95d3c6a96f7f8333cbb1ebeed8b4db1a7fe75f4071cebfbbdfdab90":"b9174a6cb4d3b2e7e4d168078e920ecb651343223575dd37c0677371":"6d622525ecf54dbecaa811939ee07ef2975d9da9f7a3c58bbb893ce3880677404f2c6e5963b8c0b4492601f15bc6fdfd747a00ab8334e9053201e1c9fba55fbfde36ec54237501b87416992771cb5ab8781d0a967b7f14f3d5de6b1665f662885878e50ad37827b95c8f0e21d6bbebc9dfd47b2957d2fcdd1a2b25a616e698129b45998b6b6aa2a99c1ebf4275493e28eef1ae34e9ca63cd8886da58572907aa9b714e89bd3644a7ea029fa3a4ae9c26e665c85296204fdf86b7b1dd7866bc8e9385e9518a270248292594c54a4a03dc1492664ddae53277c6fbb9dd0cdd99bf11eaf6ae31923e4f979a7f581799dc432b1940f613a7a7ea6855237f776e91d4":"1c52eec9523245bd82707f2ebdb05fee6d34749f23023ba72a5a60ef":"79d544cdecfd1ec1b7d1ba6322a5e0eb858aeb4b76d5b3202cea233a":"0ea53dea4ccb25978a0af5529598911b47c25e0ba3b2a0505fd1d7fc" +Nist_Vector_94 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"31d739566914549eb25726bf6d4b6c674f479ba7a406acd108a106f36c7f5214976dcf3adf2c83fd26b37d52c0b5ff51e6b3811a8dcb026a1fbb52f95027ea6034d91149b30ab4928ede26ddd692ddb8ddd929fbff83fc673788faa0ba5d967fd1339299e55be51cea80609d2b3c3433cf713a9686e229336cfa7e720fd5303d":"4cb56c8acb9c107087837ef5e021f77cb015023c8ac1ec73575e5289":"386cbb8f7e728751d4f6a75f890502989b51228d3039dd1af7f2dd0186bf97a9ff763b40323b30ab0dc81bf09ef48db72c0cfbe772b3d314927ed19badee7b88b49ee294923714adae30c955d37b99c1dadc4a29f0f8c2b9d1038d17059c586a212a9748720fdec95b428971df1923f08a01d35893d12ed17e0b142ed8e9ef77d440a01d77905b92c51dace1b345cd19f91623a6964288ddee6e9908197f91da9a26f806bb14e2371742f849cdc6ce7a045a704a792e5760d6644eadb7cffaba806b0545fae3b9fadae4e36bdf3b69c6dbbf0d8b053da38b904e9c4b949325b2a005b249276ac36927b31793f80115b5e2f2107f987710380708e2c322894fa8":"d223b9e9c662ba6651cdbad84f2616fa223fa8742f783c87c2fb9e8e":"c8b8a92e8c101505a1991bcb02fb6e382a3ecbaec8f4374501b657be":"20d161cefd584979224379f28d827aa219c572f9600147f4048ba7cf" +Nist_Vector_95 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"d0a8a1ca0ff2b44b37ff860007334b23be4934ff89051d787ce69d3d7fa734b9779e2f0b38c235391a897fb8514b857b991d10e34a00dc25b0c4382dfb6d53aa87ec1784f1cae2599259406d4756539867679d3088913a138871e2a434747222fcfab079d9e655ba254463cb0c5786b9858dc429ffdadf4c3b6a253f90eeba24":"2286424f368e5e64bac0c977ff0d92a560b78e4f21b49f3aee7cdec6":"7247d4e1253f0b52a1388b794815db61c1a354cb0f73fd19fede615c1c3025840fff204b0c6e610ebef1113df56f67406badeb99445891dcafe18d28f597126064ddf7aaf203b2fb0d35d2f458bb74341ad937211edc394ec1a3f7909a3f972db27aa135d31bbd7e36c2bbc360585e7bb6e83276406b9525f688ee5995e7aa8ef7a72c27e990d64016b99a0ae4d04b2f1b7d238af88ac4c2e4e0f3294cfee9be2457e48955948cf4bb3a445a1d778cedfa4b86f59f156118034b2b834a9aa121e9d482d6922292823be2991b3b5b42c23925da294d5ea37406eaf78b7dc72519d8f261482d6afff0e567bf6e673dd89960ce734f092d98956352429a91845694":"c2795f65f0f077e32c022a703f7eb8e5dc068fa67cb087ef366b243a":"9dabff22a43012dbf47d56b9ae5a09f4d739dd69fe907725afcd84f4":"b60c44728e4b1390f30238fba1dc1003fdd39507ff5d6ba7e609f2ae" +Nist_Vector_96 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"e4ffe72c77c3a43af8a61f58f9240e1a07b5c2894d5bdb654b2b994dc0c987bad9b704075d3d0a969cecfc98b1dc20e76cd8e012285819462226a84dcdd67895f6ea278266f1575ea785a2c359f8f4593bef31a58091b64afb84cdfd23e4aaff29d9626f0c823d934283a4faafc9c6cc18622328cad96f77d79b9ba35a43d825":"86b0e564ef08e089c4c85675b6e5281daa4e82bc2fc0e27668052e4e":"7146009d12b03b2f32305f495fafcc4d452efb85cc80d671ff4249492c6699fb26a89ca4b224d56f6b8e745df9fbc7352ca583222f4deab118f9fec0b34e334060bdc28db872e0090649149499e7a1c197878d3c7262439303b90201d0b7f5be94d0a7c4eb15182935296c3e3fa2d77d74d78f41cadaa40eafd40d017888caa02a474868e40f496b7bc1ce367f503435e0d9a6375aab03c231d9cdaa15de23c48ac0878ef649eb144ce6be4d2de11da202fae82090673c83b32840a32df6176e1d55027d7a1c1c56e642f51aaeccb3c990898061bfa16b3dc1461073c333337fd76a3103f3fde821bc994ebedd6ffd7974d0ca1b54961d7df5b9eebbfa26c3d6":"5aba2fdf6b24bf24151943a4f32d2794e44d1f62e8c968ceb5b073c7":"4a2abc689d2a63e8b23214a3212a5d20a7386882d5e11c5d5daa66bc":"08e0c6547087b58bc94fae247e962da1a2897888d1bc9c8cbf3ad6af" +Nist_Vector_97 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"f8fec19288f3a8bd1d0d573bbbc180106065697481bed912f8752750d331e3a097775a12276bc4293a78a80748b2b2c37d20b800335c1d1b430a71bbdfd8f7afeeec82ceff2fd33f2624e49d37457f262cf5dedef9025ce96e0b7d499fcc7a7ff06c02590ea821dd8ed060cabcf4feec9592aceddfd32b4c09e4d44938435b82":"e5ada29e91ccae11fd060112540eac31d9651b34b2754ee51620624c":"7e50011d422986eae01ae68943dca0c87af44f7b879bd1256d4caffa0eb1925029c0633a7ac67487a7b6f98ad77ee7e1442d129d06db475a4f7804fd8c6a038151911f81397e963594b9c91e3bfe94328f056e9bdbb9b11f54939d7e237aafb0c950e0581cabfe94bc26f0e0d5560997bfb0f6357bbf2cadb0108ec0095646e4caa22f71e1f17a9f34e8a8c4b71cf0b1265e001554fa91f18a17562bc0948c431f25945962ba7faf7dcb64ff0b8bdde701e1df620a11aad07196d67a956ebe498ae6f82324f75cafbe80edaabef0037b79c3ed658d9ba1b5422c4ac053ba69bbaf7fa9db990e8b5e7f9af57a79f3e31c07611f502b3015962b02b6b425706e0a":"cf0544a08823ea2ad5f13716b43b154aa4bf80d6bbcafe6040ad91c3":"2f38c5cf86aa0e53d1fea0e65dd03813640404b8d9a8cd6d264d9285":"47603880f3d67ba1a6eabc20137dc4882e417304cb95d622177df511" +Nist_Vector_98 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"7559465af5ca04c1e74deb9f8e46b0ef17de4d7a2ae0faf4e903a2998bcaa09b7f1730393320ebc57d052d2e98f5486e8e92bd1ee6bb0ffd02d69e5d4591e2fa12e4ebff8b6b9d3270fc75274f8f82e1c60edb2a21f8d5531a2380cbebb24f6457176e54769a136601a9b81da68ff196ff8cc78cf059c04ae22459cec7da89b6":"6ba814fb6c1d9fe5d282008dcc9af2761d1b03eb1fd02e2499c1b509":"5bcd42e586ca180f743395fc39e2bd393820f5b4c49c7cb76921ec38bb53e864fbe809a033775f16c7f5c64872fedde6abc560488e572955edd3f9569092071e56df211564f33185dbff180e7ab2297700c64db6e220701cb8a21ead2ea809f06a16554319b2739de2aca8057a62d4caa7957a2b9f039b3c7d4fb0761a73302a6fbb583100b239d727158b4cdc9765fe0485afb6a1b0ac0db504a947f3d87faa5542c6eef7a681c5fcd28f4636360f5593bff7e433b6a338d77e3d63f6ceff69536e2a3ff77ace745b65a5160d7fbf9105a90f46ce1c54fa353c8aeebe16fb238c8ed998617b63287511208d9db3f66d503374bbda48a552d04b2c304a15bac0":"70af9c79fad2b3a0677fccadd95e6f72eb8a51464e443d1e5c007f98":"c5d33f5a4fe2280a9b96d7a9b5530dc17cd1054bf1e8cf6f4aa3e2ac":"c9bf1c062bd1e86f3bd3c1ff582c33270537fa7769b9592aef12e104" +Nist_Vector_99 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"1674823896c5a764c61fd19b125a7d6cd58c883d86794391477349f03616d75b6925e9dcc553dea37047f0cd153168eb26e5ad4b8fe7cc65e4fa275514c842af63507f901fd110b98249133d3d1266d2f967c85b7f88dd76c7f76b786b5572dcae68cc646e458b8278db346b2e970c7870cffd8457fbec06bbb5141575f40fde":"b5a607136e5dfa76645f4fee9db17bbcd260b1f6023f28474921714b":"5c34135c90f97ebc9bf1ed986eba563e32ce8c25ae7141dfefca8600ad2f3cbe8e45b4a010ae4997820a38b4888187bf207bde438a1ec7befff81a64265a4ce9900b37a38e4fc23613887b638a113ef41665ad2b1f15764cb53607d0eec303ac48c055f5aadabcfbe2c5faa85e029c43e1607a3a29f65802959b686b468e8107c466a7317b5063e038021975b2f017f1f3bad07cd0ebb487964151e4f82bb5277c35a218ec570cb568ad0404a3713ab7fcc1297b1ea9743f85ac5d5a7ec818e5f90a4a58f2c2192bba6dffecbcd39f245cc932953190ee353a0ca99dc61eac4b4f834618140c9a32eca31d718c95ee03b2992c63a683b0628883a5c222fddef0":"02e860266b3b7919a3d74f37f4fa9054f62f37959ee1ce66baea3b15":"b1a946fa42a36d836daab56fe015c9f29c4544a4a47d482ea2d9cc5b":"e2905ee70a5dc099b7e0baec5566b229e9ca8e7e00840966cf56c4d5" +Nist_Vector_100 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"281fd14ae2e702dbd25f77d8ba8af09fdd77b1839648ab9c880bd119d4475378fcd0d12415abb9f26bfb8e26f108b1298859235ed12e7f9e915628e3ca36c5986d18811a5905aef7878c6300a95ea87182016ec595d32e4dfc274adb47c3ed0f6c38ec893b331f7092f19b724b9fe43f0ef8dec14fb7bf8b9041b5390beb4408":"272b54a77c97fdfaaadf12ee05e1279f65e8748ef873c407372aaf80":"48ed8fa89d07deb5f8ee6d38748a4e66002020f79ff22d66fa53ad913d596860d4dbcb7c3a6633cd4224a80e5e95908f87b18acc2e364c14b51de6bdda7ad8961dfda454ef4798d0f7a30ef10eae87de40867764b84bc55d7c0283f9c7cd2be08e1852487512ff43a8d1e68a951197c771f9e6c2ffdf2c00ed2163f86dff5241f9e2ff1cdb05a0b3e647e6fd23ccada83b9c5961e6e2fef3297493ddb0e990295d38405a24448e249627c0a7998cc4072dd29139c5336d9856016642992cd245c758a3031ec2807b171abaeef14c82a3dab201752351de2bffa5085c137656e469581f63f86379d62868ac3e3aa24df9826a833314bd41e0d9a0ae5680e6a4d2":"bc06f559baf16de28e915dd27485338abf2bd0e62cdda5b3f1ad05f5":"5a77639663664e3f0b19fd583bab6e680688cd89d5e012ddcb1e06bc":"d41c784b583cbc525bce87c6caa44062eac847bca8b005c12ab5e554" +Nist_Vector_101 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"503f2042358f7e414296ab2d41f3a1f3f11182eca6c82b2ae6ee833dd737bcb34691793e30110036ae54d403a5ea45cbf3e5515bbf80b1af139853f506792df7ff5235995e080f82b562326adaf321159adeef20388024509f225e8c5235368a7b045d69e472e6b2ad7d470a11f6aa8d4ca6c6cdb0f3ed4e06fb9a95e2cf200c":"c3ff27ecdb6a7de642fb2d2f9d93ccb51dd09b543a77fb2e7a22a29f":"7e514a04bb575ab93e71b3555cdbac634d475c58c1d9b4802e153a858d027804ea748c2907eb9987f78e41c6757ed5cbf102544a714699a02a9ef14768f96dbbdf48f3b2b3792efb973a7f91f260e0dea28034c915d9d5a87a8f986a15f5d6f98d7d6d35bee7e059aedb59fe595ba7da17ce0db895f3411b832a1e221a831f706587841d9323e0c7f4435703127084b20eda9c6a2497280190a2b5273b231b44482c9253501c66ef1122253be4ea3477ff6186af871869af1ba10f6a15d1c432940317d119dd761ca0342ab606d532c471783a4dcd6fac9b8a67a6bae187c7dc64c7611ded7273dc348cd7613a52d02670e877e18d0b60c8bbdd1adb04eff213":"ac8009b8bc2503f5a68d667696c7fbf66ebba6f88ed3db3504c0c9b6":"8486ab31c8278fad0691fdd6cac2f5fd790b2f3fed52b09986766042":"b6967b9eacde5f4883710eba387b3c6fedfc91944ea51f6ffab72531" +Nist_Vector_102 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"650c3c409a885fa6d1ac1ff41e15f9001f6cd6a152c376fd22e2851c9cbaa5350d8a92b7401030809395cf0b1a0cb03a24dc3b4347050e8553da0e61d81dee4402b1cec97d898dc6886601024f6bfbc48d2f2c40bf96de9bc0e078e440c771f74e7115ad22ba994ae2f857c7fb865ea750b18c79e7b048563becef8898ced3dd":"d39e52c39ea46d6ce274670d3e8a22875cb9873daf4c2ed83bd3be37":"55186de39e6a0131adb7d84170a8d36ac4bf313616e750220de356fbb1899dbaaa650d8de9a7afabf3c4dd6a3c8bac241922acbcc4bb7fa4ce5fcdb5f231cb17a8c0978c8e69fb82d44683ebb9fb17898e0ba4939196ed9980ebecabbaad7b5b34cd9ec0ea6df96243823b1d170efccb4d59bcba24ce5faad32d591ad6ece0440d2b62a212059e000fb5005abfec127c1e9fa7d3469c72b89a96976eb4702f09f9c0a0971b30dfc339072b5e3a6ce40bfea2d52f2c930a11dd655dd36ac9fad86fc3986b4871e7c90459a2eaa3b3d22dd04cb824173ccc087d429bb2a188e05d8af0ac2911c907fd957b2bb330a6f3987a595930b312053c4bdf856de7293858":"78683cfccca3e13d49999e7bacccb43fa33e11547014baf66b987b83":"a0c49d3c47240d30d26f0c20e4508b360a841285de3fc1986f1ef9f6":"97caa2b76d15b1f9f177e209004a2b1fdd23a3945034584c2c15bfa2" +Nist_Vector_103 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"64129153eb9ccc74cc3aae1d5999c6e90d986be6fa40c6c4bc00b1c3f8072d10a9d8e6c314d82a7641f8a3ae29d3e7dd1942dbf0dc52b4b4b35bb67a994942aff029ca6fa18709915ff720ab8f65f231155cb1d0dbcba04fc5193afc71a5eddb4a03867e5c4bb92d37b7ef771da954ec6754d5fbe2e372b92df6a3ea8c3a4aff":"a7d5664e781c28f4859f5c126cbe8d87f9b2aa0027149f8b0a921d46":"23f538d4ec345faa906eff12f6c5942ac166914baf8e737dafc71e47285512ebc57ebf3ec666342abc059b0ebddb021ceaff6ef75828c7be3766257f7247a67e1408239fa4dd1caac2b7229e8c1bcfd57aeea4c04e1586764e28669c3612d8a006582cf8f82910482691c10e4113216fc24feb299f84ba58700a3bb6fdefa17a7fac9aa9bb410fe411fb294d6294396f7f627dca0452ef595dc24170c147d3863fc16e23645019aca63fcc1152b0f766f5f651c9bb699e2f5047fa1e9603972d2c7551b18f3b16c106ddd6cc2e24d2d05e79687efe655102e6bc15bc3a57f60c1a6ad20bf1cbe62052ad0947437b92b2c932af5d72775d43183bbc6f359a4df6":"85adc235c0060b510825ed2b436bdf003f4d63e299e973b5ddc81fc8":"3d728962aec35822fff99e1b5217d8a6264a7c608d8066f4fcc9008a":"ca5c8e178a14ba006e93cf4ad119f045bbf82b828767d3e583d0bd15" +Nist_Vector_104 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"9fd2791c41a2ffa6df26109804eaf070122e20bbb62ecd9811551136aa956dc1c321327893a0dde6dd1d5b3a0d2a5aa97ed754e5bc066753338dddfc68eba217d2483505b0d7c0a437732f8046cf3bf5930a11efd3f6599c0f8d465fca7676ce1f39102cc0cdf13281b2c7b9cf7a7afcde681005e5a2e4e38cf82e421357a41f":"ddffa0c5aafa1acf98290ce6aa7a48db2ddfec48d6ea881745f2373a":"147aa8d9e4ccac906d6a5a0b65bfeb59d4d66037ad40d288d7534fc9ae33c5aa701ca18e60f0b68908280562110af7d1d1bfb538c59d9100980384ae93b77be0332a03cc567d4d634f7648a1b9fd25daf250b2869683e9426d75561a5e1787c2bab71132757dffc4b7665143e7d87d50f12d01075bef5f4b0f14cb3f109d1599e5bf94de0111a01af57e8c13f583be4dc90089619c72d22a495c45256ec787a5832d2e4c4a42f0001837a975ac8fbb8c565f77b253303b1a873306fa5cf6a5dab62d7b1ba3d70dc11b4e4f875e3edae50ee8e5178dd09a334cf9260c3e0a10911d381d7f5601c0b3f26946682018629922946dd73f81240816ae9606911cbfd6":"3ee8b1f03687b9726de846f54618ac45f8e2d6e8957ce6996bf50c2d":"a7cc7486f47fe62fe3254ed655e1c994902d797f0d7ca93fb97df9c1":"914bf7d15ce2c9ecc5ae150d6308fc557d94e1ef18c0860aa68ad48e" +Nist_Vector_105 [mod = L=2048, N=224, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad":"ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11":"2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9":"6b78b4de5f7526dbed08ee0ff4e43335b60cd3bc371b70cd4fd9ce45bf06508391085d142cc3891b179167c76a1350ca8ef8ce754ab1d624572e437195660f004cb7bed2ff3b0f7c7e53f853305a3821dfbaec33e220df3c3ef7a79f34e82cc8fff8415f108c000f21c3bb21a4c33267a213cb4a558e3b370d17c639247bffeb":"9da093f73c714e0b9994078b6cc748a675cf4f3bbc502a23895097b3":"9147670f64aedfa246938ba77fb9c1ac271ca1091d863f32f00d5ccdebe7022d268ba9051d80fe55dfc5f64b0716c4bb8da4b11e9e283448ed8be4278e93b52d675649abb45956522f92634c92a09ac5a5d603aae2a6d04a435239538de303fc05b9ed5fcb843f0536a8ab942d9c3bdc90feed97449ce309be8ab119676a96c2a60a06692e8cd59e55e6ff8d91fa462966555526c987fc44ba420bbff768f7a7fd363638d5ce4d9ea1edd7fd399d6c65627bbc337f131c7345b3d79b4db7412562547ca2a7c8ea55ebdddd05a4b4200c72ab2b83311152b71c99306c1d3b3d446657be65e58d7cf8a062b225ce937802590546853f192a6a8c8b3ff7a62fcf80":"bdd792b1ece3d0ce428cc1294b9d7497208de86929a2aad2ef481557":"2f85ee5c32d546c68f0aa2698beae53e2848c375517a570e0f1b5546":"547667e8b13f21635a0b106d324d06c85b74a64ce9225cc5e0843581" +Nist_Vector_106 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"cec8d2843dee7cb5f9119b75562585e05c5ce2f4e6457e9bcc3c1c781ccd2c0442b6282aea610f7161dcede176e774861f7d2691be6c894ac3ebf80c0fab21e52a3e63ae0b35025762ccd6c9e1fecc7f9fe00aa55c0c3ae33ae88f66187f9598eba9f863171f3f56484625bf39d883427349b8671d9bb7d396180694e5b546ae":"551595eccbb003b0bf8ddda184a59da51e459a0d28205e5592ca4cb1":"748a40237211a2d9852596e7a891f43d4eb0ee48826c9cfb336bbb68dbe5a5e16b2e1271d4d13de03644bb85ef6be523a4d4d88415bcd596ba8e0a3c4f6439e981ed013d7d9c70336febf7d420cfed02c267457bb3f3e7c82145d2af54830b942ec74a5d503e4226cd25dd75decd3f50f0a858155d7be799410836ddc559ce99e1ae513808fdaeac34843dd7258f16f67f19205f6f139251a4186da8496d5e90d3fecf8ed10be6c25ff5eb33d960c9a8f4c581c8c724ca43b761e9fdb5af66bffb9d2ebb11a6b504a1fbe4f834ecb6ac254cab513e943b9a953a7084b3305c661bfad434f6a835503c9ade7f4a57f5c965ec301ecde938ee31b4deb038af97b3":"6f326546aa174b3d319ef7331ec8dfd363dd78ae583a920165ff7e54":"9c5fa46879ddaf5c14f07dfb5320715f67a6fec179e3ad53342fb6d1":"c3e17e7b3c4d0ac8d49f4dd0f04c16a094f42da0afcc6c90f5f1bbc8" +Nist_Vector_107 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"f3bb27bf9d412f13229a56d2d1533eae63f40004c143c6b92f6e606d263dd2da7581e5eb20b6cd021e3ab63b498abafce01b4ad7ac8628f7a1849c4e454f1168ae97adfab1fadbd313fca7381726f5045752dabaad6ea3250d303a5496bba2fa4895ae49f06a9aa6451ae70cf33b5f06fa17cac0144f28bd19fb2ac041a578ed":"027d0171598e7ecf23f2922d0257e604291cefa77b5cfaf1b3e31ac4":"00c7aabe30fa4c3d1ba85e7ae0aae79360e5eab3041bcaaa5d321c92f3471e4194c10484cff152bade6b7d619cf286773475298f883efdf64c08b692583de31be0a4e2b8e8d508ec145c65a369ce6195446c52d02372eba562f9a9d7cb24d2ec3b0a1ab833e4d7623b0455a41eec759d07a3c8a20d88a926408c20f1675601be53cffd65617b66fd4eb353a1f2db31f66343b07faf60de0b6a680809c6166adbf5e504c5c61babb84be72c02d3ebeee066d9eab0d0ecdfe01b8ccd6728ee9123b9d21154b2bc9a134363566402291ac8a484ee32eb884046d40fde7cabbf51d1d1206df1c5ecf290ab7ea72abb5bd3be8d91c02bb63f809718ba1d380af88331":"7494772f199ab7a7e9a248f6c2df918c9da62dc2d4176b7db9419b37":"79a6aed73ce177ed3581f5d181a77f000d6358514ea95cb0388a6add":"2b8597a694564e267b6f250a4c76361f8cdf49863a7902afa48fd6d8" +Nist_Vector_108 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"e714c01631704e9447390f5c315c9615a7a52863b143706583f661595c505aec477eeb5ad6d640ca812ce11750b67bc8bede2e4f9618dbe7376cab6231b21248ec914ae182df8753362d2118a65e66f64018810804ad97fcc1a87b8c9f349d1001e4b09b046991e6abe6338fbef7be48f1c80c350d2962eb6b8fce25b69f8dc9":"6911c21a3da88d54ff9ab58ae2075a2affa3f3eb656978ea26bfa702":"04d301f001821b03c91394c520839ab6aaa95325c108a02dad9db48b3c8033d6443bcbf05045230ca88aaf98a8c4cb6b095b352d91b4c416f632fab49d45ac90699a5a419630a81d473bc89122eb5bacb91c40caa4e4bcc476f3ca77bf6a21037a06be24f11c645b0c21b857fdc5c04fbbf0a26efc569cdbb0ea989ba0e037c23f22b0c5f1643d77d98f2de248ccc36672d397d30c1c5e1319fc7e5842ae1a9fcd9e96fe890a74ddee91a39ce732e4c0eaf7094b53b7b409303860b0b4944cc81b4a42d40538cfe512b9680e0a281b1fbbf639139e8066ad638cf846c9ea51fb4c4ef84921f16a6ca3f2bd158157c551739c9d023e270b3de7c2f1d7683cf809":"bfb79665f7d6df843d2c39357173e415724c83e1a10932efb9e22676":"790b4dcae31fe45cd3a7bb6fa10dcf9ede1f067123f93baad7edb489":"71e3e46dfe040496ce4c5e490f6944a23cd5e66ce9b4d9acbe4130ce" +Nist_Vector_109 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"3f6e482fd484ed3d07f1d0761f2d60fc96d46eb0ecd10a59dd4f392e3d3b2cbe184010e132685578b1f6303239798a5303a81169d4f52fba0d20a42834de293e3a7b32848b65dd308eef5350d633297465425b7b1595ffc8ea7b125896f89e2844561635f52ec62fab2ecfea288d23f0a771cd6311806103135172cf9fef1455":"20328083aa86511140324fd0357067a1d6abfc316e77fe3d260f0ef2":"9fc1b292ebe15531579f35dda8d706bee0da857cd696a10af770dc356232736cf893f7411a9d2718b39f388118d177cd8d0fd7ca3b3c220f3aa743d8b167219d3c2c783e1f09d8b8df8ec7e17578c5329488c87a89678d2818a99366b785d53f6ca6995e193ba5ca26c00b849f9027ca5df5bb7ec87fe78735ae880f1a97dabc3ca7985d8cbc81be824c1ffb953f1096bf926226fb5e9d4ad43e9363da5e6b738c9a2f951ab3294e2b2822cf5282bb4134158aa90ab9c8f0f64d05a0d625a75bc2d6a4ae3dd11fc05ede7b6647ae7c0750ddb273fe5f8828318a91db3172ad59166aacf2da4f3704d169ebc860d9e1c6464abc2b653013774d29375b77bac1ec":"8f4398bb9fe1b393c1d90a62e178899261fa0501c98bd9a8178b364c":"3b5d8034c4b8ad9701bf29b10006db69d017fde8638079dd7bbface7":"cde01df54a66cef3c0538648525b250cb1f08707f5ff114bdebff8f7" +Nist_Vector_110 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"31a278f881fdd375565c0f28ff7575f216110486d6fe08dae8fd072950978bdff601ded1ef226b5d904c47f7142a8f4665e03efe5870da2dd1ab80e449f5c757b3b6996a9dc0b5b2750b97bbad2f553fbaff2aedecfc9ff6a970d156e4fe3852979dc913bdb296a321f766367239de45e47cbef4d79bfa3d576887c65f7f8a60":"b75ee80c896b42148eeb7d185d45f5872a3758e983b4fdd8c2e71ca0":"7ec0a5418828159e3ec829f793b96ea3460328dea21ba157d71ac306f9bcde617db67368d592bf46d46918b130fc7e3d1189eeb7996d5f660ace30be509a26b218d865d9e56ba7f61942e567d8cdab96a78ca303c6b01d989b1e78ae956423e35b5a466c16074e0bc9e8372340d2c12516c22d5e1ff65abd5d448215b6baf565de18201c1fd5ba3de87e5d5b437d2f48deee72a12e655f8c7fa313d24bd0c8c20e59c90edfbf5dfc057c6b679850ae41826178f2f304ca3b92a9bac31ab3cf74dfb8ee5b643b4a341ebbdb5dbd24d0b782c5b450596abfc3df9ee05f45d0ea2e8ff4357cd3605f3506ce58a5394f1f2444c26359299af153532bc90daaf954ae":"ba98b478a9e12a1d03b6aca65c0acb265764357cca67d04d782fded9":"2b47e257bf72adf34d618d3a6c46142881bdd0689a46f1cb3199ee6c":"cc1ff2fa3755a0e81edfc753bcf14e637413eaee0f22d7886b058dcc" +Nist_Vector_111 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"a6d76047bd18deefe70dc0a4bd082a10fa521dffda782a9364b9e2b11e147e1a36a11c4300672144d9b974132b4975f27ea6e8e46b55aedd6723e53e7bc9b40dce2449285a690885c3223b636cb5c4873c5ddaebb0b6dc5b69438d881a525905a51bdb97b051dbfec6dd4a7b580297b08f2ba60f2ead3a07531cf299977413af":"1c0e4c78a4ad4f5046f929e7cd3db3f48b86e5eab4a5e2be61a08dfe":"8b2662775bb7f19252204594a84b469f3dc8d66eb7993bed122d8a065f59ea81d4c484cee5bd766a5c137dd57e43e941339852150509acbde6f7957a1b04ece718565ce8b637ea031bfa3410a580744b3d4959a5e75e315dd33c02b52c7c56218b7cdfdc24f51ddb4e7849faf289cf806c4d3c6b877c63dbfab569920a2b219c39215c5e3e638a3ebeebfb52c8b38e8285a85d625fc1b42fbf0e518c58eb8f45fa54676ed8b009415d2696ee9b5153dddc5eebef49cc7659810a98d4b5e8b9695fb2d9e4bf192093747c878a9565b47cba053c48ba7c0b9b1ce77f8a3e1043e87fcc6132cbe8fad7c738e9bf79bccb414ef24907675ba7cb059a8389eee7ebbe":"5135933094326e3953250a29d5f5c4c9a1033ccb844ab35a14c19d31":"b8674d1ba6f13398f5e8944b82150d9e9bc9b210a81495b335947e64":"75fcfe96926186efa12c007c0985205147cf65abd108363d8b891190" +Nist_Vector_112 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"f0d5b33327695536e351b37cd3feea693f10377a5f8bdd913402c2ed67a0fc1e7bcaab002fa779935950c76e42a491a68fa6fe445cd35575cfce5f376c29c4e8c0fed5a5487ef418b96fa5752a033ad07959653d1b8af6702dcce40efef21b2d64cf06bd8b03dadb2fdaaa73fb2d3d75b0985e9aefa1f94442a5491ae46d7c51":"269055de62d0742324803624522e678234c3600ae7bc3996c8d17bc9":"a448b0d448249a0e54a94586882985a08e19972281d10d9e7fb57f95dfeebf971f6d9dfe88dbd0a4950f528200be7b605865eefd8ec274ac53e4ed5b288c6a00721e028881b9725fb0a9ce4153dcc1fe7b5ce7259f16ea8b32456cb03bae81be77f3f6e8b39f52587bc9dd47a264278d5d8ecbe1ba574269696a7bb1e167a3ae7110ec057f4291a1bae8257d69c10ae095f3271621c6d6b5607925c3498189d751b7c9bf30e65683cb39fb51bd592f1f98279f2e7b2b53ad546816a8508c93f03496de7c47165f5cf297687ad7d60f010ab9faad0153432ec1ccdf26d4f441df625394e2104208bb675e7f972b6c66ed7028a1e3f45a671ab2716c60feabcc22":"0d9d0b3e1f24cbb18320f9ce896cfca2a5a6bb28ceec83e1ff3218d3":"01a4f4bc633ebf842a28d045184d250529920df280545cba00501cad":"09fceb2df200b7c0a56ae7969f5473b7a1f6b703f743f954a4fbdbe3" +Nist_Vector_113 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"f58e039d666ef064cccc7ed015017c68393d1455300d0c4fd4f0d302c43a0022363a7cb01bf0673d325293bd50b27f8187d88ee2b553b159a97d15ac543421446c2aec39566315211b9b4108cacf9085dacdb4de94bce84097c0892b1cc65f2e10d74e5293a04a837b616d4181f3fe4caa4cc2e744916e770ff0ab1368c86cfc":"3752b20033843d1ea4f48018bede79f39c15de33df64140259aebb82":"4052534a7726cbe17e34555648e5f297b963f22d3aca249785ad932f6ea1fb5df31d379b68522f8eebedfc9b5c5277e91574fa79ecf03780cc44351f3e3bfa1a0587c88d0e04e0a02cd1ee9ae210b3c9aacc65c71cf1b86463367e2be25ccadd9d5a4d1fcbd58772f7a117f3673c76ee2a8d93446ffd7cda7f8430490502c16b1a5022e12a3a95a7a9f20e98d3b285abe30e8de42a11c517c14ef3b6e5b6c47114a961d858c6875561c7d5d21b7c93f373cb330800728ea188b2578a6df34772a7acddb829c09b3acf9bc5b06140b9b035267a40e86c1af5577b3d02a89b20a46573c87500a2ebed4b00b1fb13a86f143e356702d791379a90dfcc26b80719ad":"1220ac99b9124f1dc2212ade5691fd330d6d868f3e90694236d44b70":"31fde5f22ebb426f256b175057a76125c40136974ad58e681ec2c4a9":"77b0614dd99acbbf4c43aa926b3f0be1cd52d52775f22a408c4e0304" +Nist_Vector_114 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"1477aa0b9f1b199b6aa0931d4d3f766d80a3af10c9ff7315391f15edc4e92632f9d4d21a8033215d5e99cff170d9888f020b0db0e5b97e123a2889898c5b0ef7c832d028afd5e385004531ff9989797c3bd954b1ac729066577667567884cd4bc5d055a3f645583d29cf4758507c883c5bbfa74444b9c5b9b495072c3261b6ec":"83770784916227ab2a73edaac5a95f7538fd94f89650841d79a37d7a":"4675f19b0095faf8ec96888e483f3a0aa675f5b425910765069ab57c97a12b7c506437c8757fef54ecc6d310921d7159ff39f2f1cd9535b64f27f136913715775a238fbe01237e181adebe551ffe5d21e3c35774e7ade8c79df741c52dabd8be4782ee5a3b607a39d1b455dc848301847312980566f55eba080621e3c123142a1a2074e2e39f6c0630b36831f074869d46a68429f62573cd2c671726131fbfd566a6d07193db4f367802d7de8f4e830aa878ee2cdfb86d8537746b71c70fbcb6a1fad66213d6fbea68241eb9f617478adcc9faaab26cf81b912089da0c4b187b496a17d886cef571e393d6f1f857ebf517c801f9231e95db661e8cb2095456a3":"6406035023c5e150e8758baeb00a9b858ebd0e4090334c69e2fd2377":"a2380b5ece76672669e26187a17da45ad89de1726c826e57378af707":"9cc26c3456c0a409f4cc98c83ea5176eb293ec7157e51370726429ce" +Nist_Vector_115 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"fc82372566ef2c626b2145549a5db973118dff4c6d1d7c4a2e16ecc31b43c14ad3683173535b0b82331f15a183e6a50200fd1e88ff903ecfc50bdd4f5875e264a4499eadbdaf807f974f8d8104477a0e4d30463dfc61cdac5bf44eab96c770a7db912eee2db248cdd2b9b36211f93870beae6bdf8e0aed0097519ecde3470cdd":"8d2855e4ea3e5085a5c145e324e5d5a5f8f23756284669279728ec9c":"3884ab23ab93d9d1b716712c8daa080b26af01657f0dab715ebe6bd766deca7612bea6a4cf1ff7d08abb2d4442ac0eaab01e68570bdcc222f84bc3dd6d8c5490132d1c36e23913f00d11c803b703a69a51a1b475f56db00fca47d234aac307b9e798e9fd891dff9c1257bee556314b021fbf93f75ed8c43433afa715b82d5ec6af8ef9471e9b02f9554ed7957c1f46d8db35a5921f4a83727f754e82b6ffa6d1b82595220876d22e18fbafa5333b26c2cfd47d894aaa7164a2630294d0a385fc8a8cf57d10ed0fc53f21f1fd6b4c27e9c69e65a288444619a3c248bcc44ec25605028325243274d72100edf560cd382babee1ca532b7f06a4388f181dbbb5db5":"5cc12f090fd965c719efa2ee907a43b3643ca8f9ef7c537adcb09189":"5461b20704453b6c51837f7b9ef5836131b501f2539145ca3481e6af":"b65f69d291ffae2d16e3108d69aeb01b4f9202afa01382e53dea4d54" +Nist_Vector_116 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"e66aad54048bececa5682644d5274c18068363e968e37e6c11c1f8a0d7e320578514e1874e9d4eaf1bd02da6b722ed22acfca48c3acb670a6f9ee62e3aa71deb18097508f431b05214c199c166fa42cd6a0797bc7b4d1a2f330cb62c2c95182fef0d06862542845e430d778c82076387adad4355c258e6c543cd656fe3cd2332":"2c984e8464cf5716053520b6a72c69798b9eec1e115b0a1e30e2e44e":"06245bc509b4955440b0e401710ddb2c4ea2e559598361a3666c4ab12e766b439f21b953962f6ef5a11dbee5677ab7f8906d8b325180ef4e45d05c1294fce5dcaf6360f71b10b70556f306993d295b695ffe5729c5c5bbb6cb4834ad037bd8364a12c992c2598e8ee6beb1606ebc0ac0ff00c0ea2eb8aed75dca01a890085a400ebf993e5879382ff91abf1be2ceedd1fc4a874342b77b6c55ffe7f676a1c95ee4ecc32358a080c92361cfcd2e3426f78c217ae29556709ed029b287e71feae0608cf3938857040d7f06b0f91b3b4da8929df4b5698e734a37316879c308a81c096b723bf2089910d5ab30b8eff38858aff6ecf764e268ed698b70e8fb7f3c66":"b20370d79e097e7c65e956d76aea1e288b668dacb8e7944aba5fbadd":"86d5bac3aeee9b501f91f2fa71b1066760df2e0ee147383f145bb0d3":"8d6a207802d6fd6e534e1b8a1edb997b7cc9a25a97a9e4b6eebd0e23" +Nist_Vector_117 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"c85747cdd2ac9da0999b7e5d7f64d11dce7673df5bc605051316b4b94bc7fc776fb1d3da5a4395a674aa8a0798a341b31b11e63cdfac5f854346f6a4b74b49f2d089cbb86fae54ebfd95eb9f05a1b5e84306e930461ad7f827cfb910014a3af4dae0d46ece912bc26870a433f70f0a38bf23b15d98cc658848f4bad9c84e89f0":"4076f4abf4d3c9a55b3f063535f6a69c221199581e72c5a8c31f1a71":"2972787dcbd67e5bddaaf1bd3f05ebd66949601dda44237ec9361591ce9b809f8722fb399e6b9b8109a79ea7b83fe98359a07a27e232cdea8f6533e34e37db3ae53309f62f108b2ee7b489a933e4ef58dd4db8c0108a3670c675b98b75798ac0884cf5a461af281f6dd8e7ea3d41396f049601a9af2e39088ae0a1ec0d2d10fae1dc1de962d84d8cf04215fc6d6262ac432541af2c48c09cd4e15bd9460e9a7bae17e0035af0b13d8de707870c54bc851112f4ae1d69074712c212bc7e13f199ffc8f37723cd6dcf539f8df8cf0cf1ed4c10eeaf0f444804f1eb9d9c329d6f19973eec273222fa04b5f1f0e17971ce399869582027b1c454dc1addd484902cb0":"7149f49e3d07c45c97db09632740560e5b0e843240255da43ae97ec1":"28e3dd71098ff04d1ca885c2774f78ecb3ecea708fab2e16bd5cece1":"ac8b6ee498ee383e28404ba4b53e64aca0fcd26790713264fe3cf6a1" +Nist_Vector_118 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"a7a59da62a9391cfe628697548b05f8af39ea9821d76c314478e210fbcd27fbf6b0bf460a65dbcbadcddfc0178ece135264a7d7c5b7053208bfbde54e3338d901927e95e1dc8eeb73d299e6fa6584555cfeafd1925e95e0b3558ddec641175fc7293c0310266ace18bbb16f9084fd4ac22ad2dc8528c3f3f332684039e74b390":"22fdd44afd372e15842413c0829c9a894ce61a3f0b135c1546f57fb0":"0aa040bbb23c337d58874d95efe9277080862ea0888d9209ecc2f5d7e0d56b3e8444ca933800450f10b8124ff8812f87e1becf1a317ace0c3a1376d624938cab617bb546d0aad4f1d0aa23c6670cfae0da28660393a90911b3dbe3847eab4ebb7dd0504aeb0269126655d135d2e9149cd8ac5221151640914d480569b383e98364cc41cec56ea157ce8d7e73a949b348e5ffd3ceefea7f7625f599aa9afe2db4cf3b0d59f2700f6cecc54f8bf7853892f07337dbe76be781994ef4e14df2f0cf7cb342ee1c8b188a7dcc317a097c9f9e33ff89462c26465bb53eec05d1085fc6156cad0f7c9b80d2a68953501a97acb746ac3a2b9bdcf18dfceaa196716ec773":"b93120b594e8994f533c1811d61495f2ebf32fde9e7ecec856033f20":"84934f3f56d64815fc66b0dbf3b1fa56d1387be7611a1e571c405100":"431f11346950e77c9e9ed0127c50bf620f6f69a699cd017c7d87368a" +Nist_Vector_119 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"d4c5b439a1ccf5d98cf0b931f253f733037921d4efb02cf87b2509e732a56ccb49e0c83b1409cc009f1d2d1cb4c0c7ab00c402ee018ec5098031ac9e7197d4395d491721708a41ff5cda5a03be6a1169bf459470b1aaf53c8a9668acae1385b921f5a26c73365444515c3c126c6940b4bf57591a0bfd6c2c74c724426cb2ad3f":"c9ed82462158cc9c99231fd48a81e4f8318a88735c35b9f2c08ad280":"37c5f029816322da5161c4e20dc4f5abde9f04f5f9dff5d581b253109191b38424dde75febac32d6ce31b116063494a70c5c1d9d8b7351252ed377ea38fbe85b9f614eca1346bff65345d57e646bfb032e9befa9e6e5a89c16d715420e24129b6f70e4f681bc1d38ad1737db79655d244b4d67ad3d2bd80fd9d80c2e15240214859fdc0b6c43dd1e805dcdd2a5b9781397bd4a4e8bc4d6f9a1664036e90cac550e83d6641367613707d0de4f2dee55e9a5be6d3de893d61561f4ba90d387b7ab48801086016c842f3e0ce60e6b46aa980191cba147407aa4ccbe19b00b0ac71648d5296d13e48c75d52848bbd39f1ded988c3616faaf64f91a30742506316893":"9f1fc151bcf8fe18bde1ac505737dc6868c34be605bf2ead6ae3294b":"1b51b8d2d3eeb3d6218da3494714d0e88cd7366f387e6ede00f653e0":"844203a81fb38f57505bf83bc8c1da002a39e81abbdd2f99ab6a4d65" +Nist_Vector_120 [mod = L=2048, N=224, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57":"ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43":"8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07":"40d4d9736b54993c1bcee7071c682390d34d47c35f177939ca5b70f457b3458fd5eca4cb03f0efe1aec10bf794b841216056a155dab58a3dbfc19ddf05d45861bae6eea2bd7ffb87a6fd0fd2394e847dc36c94c81561dee120779bbecbc32206327febaa17c96505ecb97d560c934c386f6f766a2f5154f545f22181c19fc698":"5a050bfae63d347d64379ad01441b0ef9ab06ec5842c952f7a1c29ce":"24aa1c7c6a041f6d2c533006cebcc2ad048b3dc08fa86282f5879a237231d230cd854aa10158cebb45f387923fada8c5f4b91a7bc2dc3e2c39463797e6eb1958abc9b9e748bbfe80e360233e96952279959a6b80619100f6f1876fadeb790491462f5917da36cea3793c44db90908cb9da18f696ced90f2acb826355104c4c8f06c737d48acf985d6b8c2abf31807282b6e651d2967a16907be3d8e4b7f32ed34eba8c262d6c0ecb131946d2546362c217ae195d05656a4fcfac73717ae85a571d811cbc99e0b3124bba767fead605266d99021cdd8cb4c081bef102431007ee12523b48bb838698a5971e517252d6d93e1c7fe9fbe07bf434164baaa1026da4":"5de3d5e6b78c888ba4185c1547272fe562b44e507c871a0524765aea":"325aa7b173cac96d5865aa50ea54e5df45a10e72fd5dd1fb265aae09":"0a7203f6b8fbf668b8f6435e929fd52f52e23ad4b8a156ae5f3c9c47" +Nist_Vector_121 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"df5d564db83592c1128be5d29b7036880d55e834a291a745ed8dcd438c4da6b1b9f39412b2c5110730db83c1ccdfe9059dd96ec7ea2bbcb34e3eba72ef0a1d4721c7c0221e29279f014d63facc5bc8f18c539b92ff2af89e568225d6b4cf599cb3dff5e3c6ddfac0a27f10f636ec220abb72630bae9a39c18fd3663e4651ccac":"4efa5136eb6aa74e92bbfc913b0bfebb613db7a47221fb7b64f42e6f":"647979b7960ce7b971ff0e5f6435f42a41b18c9de09a301114a013a7cd01183f176f88838379dcb4efb67daea79def3f042cbcf9cc503b4c2151a2364f7c9437b19643e67e24a36bac4a4cfa293deedf8ec6b154a32aa72985f7d8de235334b546c29def458c55d0c5c0ac5d74e2024ec7d4abc2fda516a2a0b1a4d886ad92c204707828a4fc7794f60ee8a4be1101c9e5518f7e19eebd475f2de6f6ba89c28bd129f13993befe5818440319a79549833196342a31dbaf7d79497dec65ee7dbef70e58f99d0595f6a711409ade3151d45563d53c1cd0a8ab1a18beff6502cbb0c069b114ea7be77898d0f4e549991ba0b368971b1072ece4afc380e9ae329a50":"7e0f1ce21d185ae65c0a00395567ea9cf217462b58b9c89c4e5ff9cf":"5ab43ede66a15688146d1f4cd7164702c0c4457bd4fddebac0482953":"6c58e8ab27d28512c46063c96bf5bceb8fbad232d8f5b39c4755d0b1" +Nist_Vector_122 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"ebeb9e2b692ec6c9afad2a0c2b908939943fdf4bb7438e3bd9288e7681984087ffdcf86502079c291236d7f1adb504e67e0f88bee61b61717014cf06b5fad5cb36f1b223b63912cdcd2b9416524d37f5d7b05c37d1789669e141aff6670db2e0de31673b2055f6799ac887937e5664a659ea0254a8d4ba6f204df2a38c2a77e4":"1c84c5c065ff165a0e1d276c2ea9fdbf8423c12aa1c73844d6c64942":"31d31a5bb82874bdc76cabae3ec85690aa5103cacbe5234e0d5ef645eef380d3ae2f6239144b82b101a7ef4744aadb8fc98e82b41372e99d6c905ca974b81c9fa521f920a1dffab4e2ee15f61e03b742f42470dc2fa9ab257f1136f9fe4b5aa2ece5207230c4906d67a156a3ffef470cbf3a65e3189b389ddc66c6040a7995c68ae1df2085941b5b1df7d957fbcf366824e0291df88eae55d8d3040d8d09f4f6ffee34ccbd1961852a5a62b26c8daaaa56a8ff7fa863b63c6d604fd3378262e815f55171dca35d04761fe3d9eddc6d32657a96d643d4608ef2143b19f1c9d8c00ed265471b245b60f31f8c7ed48dd6b18b5bec1a6ede145dea40283230724ec8":"6f399d636570476f7a2013efdc74a1bb75f5b35ce835079c4e19cc4d":"82c3747a0658df006a7a205a6ae2aedd5d2948488559fc3cfd643a64":"8636796df622d13f070fbed4184c8138358c21db30c606b8f9be521a" +Nist_Vector_123 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"dbd2516b03fdc58b32c0233080ffeea41c0d9c156b30332ec42be5e10584be3e3db85ffd5b5bae16fc876a0c9217627d84011223fab57d176def61e40d912e7eeb2bf868734ae8f276a96ab13de558ec42614167c5aa4c60357f71fac58980e579440f69968d2280bc970d0066b5bd6a6f5002481510256b3eb21bbb92ef2cdd":"383585098edd867a8522dfad08997095aa23539b9c816a5e28359b51":"6e6ee0319af8fafd7ae02013f4227e266244ae5d87fe156cefd4518bcd71aa73f9364bff35d4d23d45b0f47dfe93a607d9f8b399b424ba75072fdced6c3ed2110606fa48ed633faef2064fb336069eec7ebd8ae475978389e6e433d5a435d6529a66c489ce153940d2b1b8c886c8110d8b0aeb641a40e285d6751ce71027c30ec62f4b1fc14f4da20b1d505742cada201cea81930c381f8a6f13dd0a42aac1e0bd7fcd19c6bdd170fac6a423767b831c1e289e0a29ef85d817ad238d91ac3ace2f40a163b0a9bbddc6f05d0bdcd8cc274a74d0743c9fb56556ec1cb8e9cba982c15a9a66fa6b6999b8485db1a86ee18be16e068e12a8a165e3599df96669a1b7":"0183d11f1597ec9db32db21c1e910fa2be2f276f35d0583ce8b8f6ab":"040405136a1220adbb64ab751db3307fafad5447ab2d9bcc52f79be3":"1d35f3269c77c577243f1db8dfdbc4cc4531574276f0da1f7a44acd4" +Nist_Vector_124 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"34c45435d0cc29269272a93d43320698e454a7c287db9d062092acacd7ca086455e583baee1276caba068fdeeb52183396d5444c5a14ad52a5c2bc082cd87452aa8f9b23056b5f8af2638d965ef4fe6e4e68e88b0f50e01248fe6a6a1d9d6d93b03cd55d16fd83cd4e06763d926f7c50f20f0ed6730613f0f4db571e22d288e4":"0f115fc7073262e2f93a9d46b407b0f1bc29292aa09cd1a98a34a219":"5ebd8152935ff2a3f9a61b275e9808a041aad5650f593f612af33bc462b8c994169372e8f80f51b15f5ce966ea3e76a912c653978337e962219e323b6e922dea4bcc23c646a22eecde02433126fbace0e3a01fa6d0b9fdea9245d67899a7b745b8847c8087fa7f6c0f3edafab4c3b47220821fe46f1bcb00a323dff3dee47ee1de2ece44e1fdf3e64aa20c9e6b58e534482e7313dace1c617d8ea9a65dd51fd33024f735c3844c5c6b4a3f447e714ab0c17dc88e33f08b142b72e811e6da00299c82898aaf2bed5ae5170c1dd005678d2b576b9ce3e6bc6b2aeb04c9f04e444e2a9808405ff5926548b59304dddca8972631f7fb136808e213ecd93af98e2e54":"835a744aa418a297b7e11febe7f3bba590752e58fa1ae12ffa3bfacc":"66481f241f6b443148f0b1f2459be5ca16413d947d0981628717c108":"2cdaa73500d0ad291252d07ceff9cfeab87a739752291eb5dcefea87" +Nist_Vector_125 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"d7ac5cc8a4c3f38cfe5c0e1068ea28f0f95d3250d1aeae5f66bdc4d22e23e246ff30429cbcbad3b02a62a0a179d4d107130fa3a780c0092c329c2b026e12e6735a75c495b097aa69ebe98a96ff891234ff379511149e07c6e2411e58976ee93fba7d3d570c911f6f208375783ff5d947a3af0c839d210a8e4a8c8fa41efbc57e":"5339ec1f86a0dfd81324fca6a0d3e102b12fba8fe8c1bca45d8ddf10":"7b5fb022b55fb61f8ef8cdbfee46c0fc61e59fc62dee5c14d0c3134b4f2659112e3f4e7017f9574a2724188ba6a1ce777a8915bc1171d738754b5ac1df923103ad7b198511ed36272668ae0c2e3142ba011cb45f893ddbf7b38625818cba9a9b78aef8d06007ed505e6dd6e20c92d2500234f104c1283f7c00cf2a3a32458d97f7bd17090f76235c6c4f8ae194d52d67c74a854973fd124751f7f5804b67879b023bb6eeac76e96fe676daebbcb1bc94d5d851d7bc56bfb3d2a0a6d992313786d9fb38ad29b762349451d149d0e5fde6ad497183e352828e251bcc7c3a918be4d03b17af60f3f3ef6d9fb2455df7e8b6b169475e5f89db9908541b567d0f299b":"7c62eb8fd725a453fdb2d1e75bbe22f0c5d27a5835135c788061ddfb":"5b6be6bad725afa442f29ab7d343d2f8b4b4941cbd23d69164b3c5fd":"3a1b94634e313fc4df8292e038c6e876336cef88d691b894c0eccd3f" +Nist_Vector_126 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"7a96873f0777e8ada9867532ae5f51938bae2d56fb471e0fefa693b71a2aea2571c0108ba59e634401bbaf20a848ad8c305848420cee654a3040007f055d4e975807894b5618b9392363bc7f8c88d526bc491adbd892a93751a21d137ceede8a04423a4d0ca1557bcf334e4f855b04474544212929a81dc71fb3fc41f70d6b18":"494b68624728aaae9898c3ca22c1bce810a052e25c881a185af43cd1":"0531518177087dff8d04a0666c1301a9b38427c2ea1b162e6fca520181ef22a2d205ceffffb1549c9707805560c6c4b31943d52556bf301c5e0e75924fbe6b5c362fc9801753e630433a9a348f53e62c0746b26e348dfb85853d1ef6eca02cf3f343e77c1769ffc1c109b88ecea16ab6cf476e54312500983622df41e695ec27a41ca7a63121ba97bee7b0e9d547bf420f647d0f8671bf4107a712a7dbc1af3aa8d15b98548d3909f72b9a27f81c46e3defa95eaff7590c626b9ba10974ae8b9f58535d09ca30f9f523539cf584f9bc6c74185c2ff12504f5598ffde6f86021ae514562fed3881197fca22db5590fcf9522ef760ed0e3631a6bd79f29000b42b":"065a3ebed489d78ad676afb5373c7028f843816fa97c30169149897f":"76bd6ff4cdc4fe37f6705e77efdcac6fbb9d54fc0b220643c662acbf":"8a124a3640ad73280f305afc2bc3e57f7a2e074081be7bc90b5b1faa" +Nist_Vector_127 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"d69694bf9a93ac0cc3915973d40e351247c3bcaca98069cd9c1e7a3c5850636a592ea75fae7bfd38b1290e3f4d0aae8ee689ce4137ea868aaebb17dafb255c4a20e0fac1f4666612f90c46320a62002ede3167a34dff74a306a0842427cb9d2c61599b05c67b673144f6c08232d771f2e0af38253f36e122870e04ebc54a512f":"044b1bcb76db64ab7500741f43989d3d878991788947b679bf22c088":"9c588b76269b2f087f7e7af4ec4c0ef263e9636f45e73e604502d62fae90a25101bc2bad2a002127d4b60f5c4a1388880cade9463ab5f7997d54a02c24e7d51a4b8a7d91cdf6afca2b433768094533a0de08dec1f19eccb46df1800f53d3dfeefbfb769a80e1686e8d53c60e8c1511a6dd4f42a155bd85f75740bcbb7b1127591822926d1682982375ea5ec29fd1ef4f283b94e02423a830b35e973caf12377ee18d2c6ee7771184d7a94e7a0c4a01044afc4efb2ffecb695e233aeb80c516c77d1c730d30d1aa4f39da51bcc48f44d07abfbe75f228abec2e7273593c98f323a9b003562a168752e837a1232f462a23d3b185ea8a05361570455aadd1037063":"4707e611f7d2dbb66f5ff083bab786a525884b49390213300b088fde":"108a082d2bf6358a737465624320c4fa9d3719744c2db69d18963d75":"420f3537fa6858657db7a21e72e11ec0ec8cc85a09a0d1a445944980" +Nist_Vector_128 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"17455bfbb128df0f96544bbf83ca0ff374bc086b2de18f74f59049f73eff3c8ef32a48429a4038256304636f3032192795ba2807407ef52b8d59b40bfd517583f998810279c0211771d9e54f2b84e898f9892ef77beba33ff31a2868693f1f0978b89895e350d5ded259fb1397e9c6989986452a0d77df99048fff84b6eb150e":"2bca3c613be53a6aab121de91db4fa06b468fc6550c82eeec4bce9b1":"850c0fcac073c56318a92104654e6a8ae7678fc4014728304649bf1070277706fbd32ea4d41f77f80a80c88f2701e3665be73f59f914a915d66b411bb05ae5c18b00bc216251399732fdc2a68be6a21b3b088797416ae05ce876b6802e4f941a21b1c661e3f06d501ef2a17659f088d2195dd161f06404487a27b79df1ec574ac3abc30ece2a1428c5e0c1d4c49803398d0714cacd9853854b08746fa453561545e6f0d96cd2c7ce1b89bcace1c697ec4d616bf14d1889a79a806a3699f84f19efe690fa13a3b4383ebf77261400fcbe309c2e5eab0b24b197cb856aa27d7d71d92d32aab656faec5ff792ece53874c4069f540d948f8b2e5599082e21f02d72":"4b528d2b2bdfa4f2fce09dc9806ed5302e41cc52f35962653d7f222c":"423de9e112ec38e3a034f5d9675c76f9dc8536b30d05678a2963ec16":"74051e79699fa44de18e36ab116873593a310e4e09dce18b833fc2f5" +Nist_Vector_129 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"de1f9606261ff82218c8c145aa4d5847673b459eb55fe7e6454c0443266bbf800c1d09051f5e3141c4370d1b990cf5fea9d2683986c3bdd2823107829ace6ed7034caeb2f657a07b25b7d60240a0205026c2e3018141d479c07787a14e702622f8e6df709b636c6d3d0b5fd54f5516dbad97038e5c0eb31f54db1264d600efc6":"366a49173a1783b99550d84c7fa02b6cccab12ee9a306bed7bb81ba7":"4d6e89b022c278f3bf8932e706e418ecb20c1bbab13ea8c90b6bd84384f38b311e8fb2c4c0a94ba7d3afca1ba94252a4c1ac1187622cd9c16aa73bb1b4a5cf55b5aa34bd93526f187beeb11700e4afb88c816eda50a50e81860c87fa66a1b63f5ffec3c3ae39bdc009d38fa13da863ca5ec134a7ffcf5dc3ca85cc34d61c5df8f9d9bdbe6a541045b45cb512ef64d1ad3db7b37dba33c6e3c96180cfb26f48c63373a0f0003ae6582679da4850ad2a0b899e0e8a1847df07fef3a4330a72f8a802c06e8e95707e0c7dc1915f6e1731fe650f1ae352e782d2dd77f54e5dac52539a10a22bbc2eea31efb94438a030c4b2451bbff6901b5fb3016cd162af6bf0fb":"13894dda6721bf3af8a40603a3d97af240976a8ecb3ead998eee0ff0":"5f3839eb663f026f792912d1cb0b448f5e2e593139001e839f71c942":"6b07edb6a034d084a61bf3c0a36e7ee6911948ad8f6e50ac6844b1f3" +Nist_Vector_130 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"c1edd86151af66c6223e413f17e734b2bc024ff066578c55308f1388a91ab87270cd25ca2efbc2867eb715ebed6d10012b6f4808f2de1986ff7f4c369daf46c80a618707888ae3f86e38e7f25d6caa509104d4851cbeefbb75692aad499a33aa35b11409300e495fe007524b4af2c20d33f1c8c04516b6973ac1e07df3f160dd":"841ba91e273f1c57847ad336cea47c643335e68f611482a30d6c0bb7":"90dbbe4741a76a5ff222ddc833c0e2dd445ad01726bbea25cac247f9ef9da643932736db07cd9aeffeb45119351e00332d9dfc89f5903a541e74e2e9709d0f852ad65240d06159fe54436dd8201f8c56926e8d23c2ecadeb8cbc9aebf12d52be6489e0acb0e7526fba3754b7ec163dc7e2fa9193319124f0cbb61c2ab7ab1a28c14e7d581dfb8de23f53364d204190a58fcb9ea5b6f61a7979b86bb7a7a4263a1066f0516e5870de423a7e3b906d90313d1ff9322450f72ddda4733ac74fca5d4ad2be22c2667b92212069446b42a391233d85216a88c25b76c947d8d56591003df2532fcd7b18f923ed482d464fb76f2c85617840d370ab99e320e88cf9ef8d":"5ed84fb90761dc03a5e60f3b396d6cc7f8c16c77f065a6ec0049fa51":"836d84d86271e1648466d1955c2b60b2a04cc021405083626347aef9":"63c7eeb5e06e81d8923356f799810a26af67c0faa18b392258e4a9a0" +Nist_Vector_131 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"2b5fb613598c02916bf6b4b0fd7a6b5426ac5b56954392fba32de00bdf4b70953be196ad51ff2c097a81e6ce1d17cf837d2444752be92bd4a9d1a8b41327527ff6bdc0e5c3e0cf46f7e37966aae18a29ce1981f212d714dd6c0cbb410d3a5f3d006ba9b593da150ce422b5cc420f3b561bfdf11dcb9910005709eeb129e20665":"220947396c2de85d480bae730298df67283d0d0694950f5efa4ea5d6":"95947fbc50d5a80299c90dd27cf3910091420d8af849240ebb541a21b49e528b0f3317acc10493d50e6bce676c433c31147f81286789e6a41f4b2603bac0f6e5ee7affdb44cceb42864358607d45f4655a709d7d67f716d7367bb5eab334f61cef3720c080cab17512329e6d99925b47e4960c85031bfddb13f0c61af80ea46b7b8702f8ad348d57d481efe821054fc83b5266782756a42dd431881ea6cfeb7f7900d8f747aac9976be8945952afb8a274dad03428088310a2456ec254d1ccfb63eedea5d374ed8cc637a7baabf8f422e1a12d5ff316dff8a082068931490a4706503d19f93554f25243751dfe62cd87cb856f644fbb6fc46fb9cf89af5aea1a":"2697349761cc4ccbdb4550bb9ca73654280ade31f577ef86100ff4cf":"7b455fae1002fa87f36cf6f345716225d4aa1407802af4082bfbb14a":"235d8be4ceb0176f5d0c47c1199afc7e3041c7d7508b9feddcaa0d74" +Nist_Vector_132 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"bd7d69bcc2e4f8a42e627fa21c7fa9fdd3e574b6dc5ad20217e80bcc9997b4c5efb31c7b65dbe8a0a394f0af580387b9917888152dc4f63ce52d3ec4b723bfea8114825f9f1e259f67b5d13bcaa66c97de725fae4ad247bb922497ebed0f092bbac12f2cbd9b71b229087378e8be0626b8d5e8950b0a6e69e05129f0d3842d27":"42777374114519bf323bd03b6e0ec238660dc863b1a3b85e0cf8f8a5":"6fa6dedc84a1479be43906f2f68df0e93234ca2230c832db079d9cbd9342b2df13de4bff10bdd831313453b33b725cd616acf1fe2f7927ea32d46ff10ef1154e503f71165adeaffdd500a83bf1001ed36ca65bb6974d0372cb0f2118278466fe1286adff3c7ef719c2a02cff9ed9374fbbe6051814d26848b7d970fbecfbbffedf40a03083fe33d3067838ace22854a8e88bfcb02ecd76c378bb5c8babd22dfbe090753abf9e97cb6ba708ce00ffea5c550b09f24930698df115c020b1301d571a470e5a8a6ccfc74ad18949a57f614fcb0f7e8bf7530a731bb6091a7301af42899d9ee9e45aa62ca4903e66733e47d01e26b299746da75c7a57dc00bceb4d6c":"3ad0d788fbfaf4caef4beec9c1566a8c7a1de26bf75dba82a8243270":"16a2a48578a0b5b57553cd20005b7e8400e1061c4fef20d033f72f8a":"6c34d176e95dd49271ee48a3802edf4238401084bc3930201405693a" +Nist_Vector_133 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"7766e1ab7638bcda3e6fdbd4c85b3661acb2763d411376b2eedb4b2c6bff5d8fa20c0ae5b3cbed20796a6d8b81a1096dc36a39826a18ffb897d36bfb16363cca7632ecb71d2f996cf7cac66669bf4c83114bd53be3be3305efc99d22769188f84289cb1d11501f040b85d15890d29af2c8eae614f74beeeeb5fc915afa4322c2":"364bdce93df0eaad45ee0ef5c18828bfe2e381db607e5b6a77ffc6e9":"4c2b559024f1b3ff5c7167270cd1f33bbf0f40b9efa25e137441ab4698154e74da3cad34236da4bd1c57d7638e4277278b508e85e3a98d30388ab8638f553e2a700011923e5d154f8c1407452dc4f80770c9c31c368a21e499d5dfb6f05fd67791e761a494200710af8c2188892c2d1c3195be4a0a1d67551ad466fee80d7edc435379a72c3bffad271de31ad2ed107d784f40e24c5a6e8d5aae8f2405964fe3c28cc3652dc3c9523b39d4b083ee65e9a07ce897a17b02b354766f1b19c2b1229ab468b0148ca8fe89484b7b360024218086af56403707bec65c52281cb8aa5346cb6f6481430e8e057146f390607c572b5bd8426b90ef3a827cb0d58bd438d1":"576f8454ff45df954d123bd1384cbe004413c8f85493ed7d6425bfaa":"09c61878a9917177058e9dff27106bdca7d06c500e09099306668cbf":"7b8b6c4c5615976d7a735ac3e184cde96154ffc87b458924d4602895" +Nist_Vector_134 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"84095278f7f1d578e798399af0bc9f4695f9302ea5972479adf90c95fc25d59e576d97b89b73dec629cef05d6173b55d015a3fb1d8191ae540d552409b03a7a8db511bad0951896db949fcc28870f9d17314734ca6a3472683d02fdc8defa7b9d3762ae9357ca2a6ab623b046350fa211d5213787127d2711cbd91405abbe50d":"161fff26a7b9d7ddc15237edbab3c1f99b7294c70feb96f962df8973":"4b52c56fc64922ac04ee7a80fc5c224013e2ffdaa167381257e00c597b433641ceadbc9b16568bbc9c6d31d02c8e36db2e3987520ce8590856bd4a841b725ec95a4659a61a0086f66a6bfdbf1e4bf92b441928cf319f929a6428f5e3ba7c89123dbb0cacc16bb0e2b80854b0f60dfaa99f9c4caa412c443a073b7a51259125f012d98f0f6699d70ade66df9c5e18185672e0e2830e0585413da2956c89d2320faac03aaa83fe718a0d6cf7feb38a194e4362d7c89e4a13967e3a2d4493f4ec09ac2fc89d56a595472e60332448548d91cd6aac84a2f9b4d7a80462dc154779be5f9e1f709b9d9a156273033fe6e4842ec47521964d2e2fe262280fddec6403e8":"7cbe0c1c29b955fa1fdafcab79c02177c15ec5789a4dd53a6ad29ce8":"0c4d4527815a94bc2d77063ea69049be6a2b3b3a3a0badd5e62a8f9a":"5787ced7081fad3fe19ab5b9028e9e8df18639e4991ab6e1e243416e" +Nist_Vector_135 [mod = L=2048, N=224, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd":"8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b":"43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3":"30eedc9d630b632082c196b969d24f6eb9cf1b1e2c53d244e8d8b50a40982ab53c4d57ff995fa8458908a743890382da6513cfe9c1991824873615a8a16374a5e5dc2fab3f5cd25652ec8aa3939f4884f74ac737989b6ac2e43f45b885206a31e797fd8576357e4b4baa566291815dac2f546f4abf8ba1de1120fd804284e959":"0209c00edad10594f7cd7878472169d512a7e8dc3fc1cd69285e69d5":"8920f6ab95b1dc6b93e08ead6b08141cc2a8f1ffbb71d5ec5964f6b2c3d72ff3adade52254370f130990b43487775c2fe017a8200d8119818a15ed7e5636bfbf3164042f27bb1ea418698b6756f75a8fdaebf0f6e5423e460287f4fdd2a0ef305e658741373d3baecce79063962f883398c314e36230ba8c570e667c30cac8fbaa4e70202a9157d22708ca605403066d0fc84845bce9b8c3b41ec32f40c845a532fdff4dd10cf62a714121ea8a6188500645afa9316fb3e11628b163d35d8cfcc55272b650e8072c237645600150bbb66d393c1c97345d5820f178dd405b5d46fc4ac8a5f3929e6b1627944093178a8d65101059fbbbb7081174f2308b2653ce":"36454e085b6b3dcc7c755b65ff46697b099485abd6ceb00cbf5dceed":"45212d1c8c128002fcb3ce35583ff8d08363711c1598307d9ec6a108":"4858105649db5992764dd32b102d9b9d2bc6af64c6a81595611e3e20" +Nist_Vector_136 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"e9f59c6a5cbe8f5b0cf75008d06a076a6739bdddb39b82143cd03939aa4738a287c2a6f31829bbe15f02cc2ee7d7122dbd132825970daddd8a4d851da86e7edc8940cb1188319218b8e0248a103eae34bc68d85f5a32830d7e5dc7718f74db5e4224c0debe1e841e1eea1a88fee0f85d9fb087cbcee55f86037a646e38346d2b":"6a5b4ffc44238d1852fb9b74e4c1661be85984043cfeee023f57cac6":"af6721bf75dec6a1b76ad35ca3750def31117c5b441c15a306835a1db74c003b86ae9099ebfb745b0aa9cb000cf43fb021513b8f197bc865b22bf949b491809ad752ffc1ca8e54bea16dc7f539e4c55fb70a7743dd28f262f60ef0f2fcaac29e8021a7938c18ffe03075d0b7e0a2b4dcabe46ed1953d33e37f113af519ab0bf0b6186c12b5f6488437f5193096e2fd6a6a1835604794c66b42ae5265c1cf1cb53ae84997975e0318a93ce41e3902e4ef54de3c56555bd19491acd53f3e57464e1f460389dbc5fa80648fa5a5a0f2956e9ec3b8dc441b535c641c362eed770da828649bfd146472b0f46a4c064e459f88bff90dede7ec56177a9a71d167948712":"9ced89ea5050982222830efef26e7394f5ab7d837d4549962d285fae":"9da9966500de9d3b6b7f441ca550233fc450944bc507e01cd4acb030":"2d72f1f6681e867f7d8beaebeba4bc5b23287604a64cfee1c164595a" +Nist_Vector_137 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"971d16d111c96de0f7098b256af213f4475aef31007e12e2974c5f64b2f335e0183c196c33d50f6445c5f614649549770b1874dd0756a9a8e39971dfecc3f267ebcc1f5301703f88743b0f376482cfc06d5948bd7926d96ec4d731a44b0c0eee5e85da26687265de5a66cb1a73a7e4f3236f60647bee5c163340e19505577cf6":"9053ec8ab1f9700c2ab59259bf2e07892904f03c844cd58a7ff59c79":"290517297e4249fc3212bad67269e032818d760b0ee0525dc5a17c97116ee29eb3b450b41d15cea405d5e983a8558184067f424acc498676415e17506a351c124b5404f1d17153272619df713ce34d03f1f9ee28592f22f829a31993b106c785fa6dbe57d0049c815db5ee2dfe948ddedd1a5e2cd2346cf2f66f04fbad619cd983a1b069b471ef9adb4df6ceaea23d09f0a548c3c7209634c8a05e5897445906dea08a52e4074be22d8485f20eaaeadbaab397199b067aa860056991ee088480b4921267a698a8f7a03777f56bac84e50903e88d07261f24d0a4f317128e01fe8a9224f12293949cb6c3f095afd19aecb16b209a99487dcc2a1b83c49d75e351":"901632e0b8ffea7efebe2fc9ea0d1a52442817fe1e1b5455bd39a687":"1f44f6eac218236a1d99cf7625abcf5c964b0a0c5d88b8d05d74a3c0":"71015cbe8622d2a34fbb5e7cca8c59e828adee71f50524482d9e7904" +Nist_Vector_138 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"08ea09fa5efde215bd8b3c4d6a9c90ee9387ffb7bd65becdb88b40132c6384106aa619b7c66ca92034d284608593864ce6b92877112aa139240cb44b388fe68a8fe0501ca584f6a2de27c0fb658e72bb13fddb8d039a6bf85d63a6c073b2668013ce8fe589a0150e46d5b1d9b0cbb5a14c100ae4b20d6ce81a987a50a949f434":"a2cdf2515cb098559fa13cb70b6a897e89df120a971064bb377988ee":"b3e2b7e0641721d69616679596cc75091fade2da0558e310b8d14db0f4686f1fed48d0fb7f0b3b27bf6e1981eafa7737a3e651828d1fcbf88387d06f78404a7afaeaaf8fae1893bea3a09a118893937ae2a8fdef3320942a158463de4fddc11987f23fee9633e06ac239c06610bc45319abafe517ce4aeae6247ea789d7da60d3eeddfdc4b232b4d7a069bcc0eac7b99fc088fb7ec1946034a98d7e69cab0cb2b06b3d9deacd1b433ebe94f547a322895cca9b0ed319b1d458c3bfb260beb641a5345dbe3d01ce800ec2c6bd430ce3e3f5f78fcabf91a29658661c573b9f6fd3812e560d888b6cdf3d57673c1630e00ca841ee994958b250dafbc3e83bcb8be5":"077b3adce42ba0622772eaaa8cabd16107c92f7a134c715a4dda5ebd":"6c03637d253a8dcd0907d6de93926bdb3e1ea3135a709da2309a8da6":"236e5163f2c2ebe0eccdbd3351e4285531a4f53e45284e41db37e266" +Nist_Vector_139 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"957cef163b16d8073d5d3fe158fa0c7338bd107c6a653cb0f11ebe41402607b822abe30e36ca9ee4c9de00cf72db97f57d78f3db49a8e1093285563c68b0f4e124830b9febfa3e75ce2ea59cba2cc6d71e908b5e6d8f463954922b82bb55a69fb2ff143ffcae6b5656143c8b6cc24f57b17cfb020f6e15bdc5f25436d07b7f8a":"15ea86b973ef146f03cc701b17b589b0ffdd318b64827d49ee3c0044":"3fcb8e44d6880f9eebaedfb75994605c9ec001f0595aeb5f2bcaf6b3987bc28a7ca905e1fed7e3c715401b5c608d12076938a18013473d8a433277fd9ce5a5cae038281e768ff909aebe4d257dcb5d93488022d07d4c2862afb2bf8a2b1e974a8e7b6e176b1b0b7ad6f63bda1b7142e46f504dcccca7d1e2e7662758f760e624e59528c5a0c9563ed517c691fba2abf66899241178223ba20013ed0ab21f91f3e6bef755c8100c51ee947b7a9ba38570f880b5e42f24b72d5321132e031b985a0db825bf3bb00a7771a03007387e03ce020fc358e65ed3de8d847f5be60720917c0616a450aa341ae00abe0a809c38e97314f303fe9b0c6cde446d0217cc4eab":"9af96c995f0b7b8283e2ea288e3c3a6f751a56b38041297e2bc34cd7":"150362da792701694e23f0b0a9b7035437cc8f4faa45c6df8f7982fb":"6df4321c61738743a9fe78ec76b4952692aaa372d1c8530fba0fcdec" +Nist_Vector_140 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"204d9cde24a2f0de02aff020f6363fd68f70420dc1a9b5138216201363f832da0aa801865a75a243427d9d6c78dc5e6041b27d033660e1e405abe1be27c909994bd6fb57180c3d6b498ce8793bee8ecf51e06b96411d00996209f44a380926c7b195e84e78f01fe02e0bc7032ca462a5182683475222f9dd8f3ade1ab8fea318":"524a63cc5acada8557609a5f0d88fd3e9c6e63719704cd8bab8fe301":"99b8fc6e64cce262ed741c30cd586986aa2e8f6371b848a2617c619897de23726bb54536ece4b460cc7f1f39e0c184eb19291e930dc9140e4b7735541eeef8ca8ebc81790fed37a5f08e9da9abc66a3a2e909902a4212106927d08abec01f27c6056b6e0381150bd742d409f6810fa5818ffcb3f182adf894ba7f80678ce883c1089a6ae71db3a115c386dd9153f4191fc365461ac86838ecf2f3f81ccf283297a6fbc644f52aae664901ae30c96fe4df930cf1a41757241cc4d9adfccdd9a6bd5004b05757443598856400dd771dc089095c7dcde82f721f986af636638eea2c71770856c2ba80315e8696142a11e51ebd7559e9da6a00be3f9f38c614ef207":"028091483753f5643b61e4093a7e0a5135d71c5fa318d6e8bb0efc66":"9c023331751c79d5da355bb58e2bbe2e973e3e4b4f52743ce1f1eec2":"96ad0e8ca90627fb7ac4540c9b58a016ee6c4e0a6f0aa1e7def81a51" +Nist_Vector_141 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"1e4e58afb34c5d6f645a82645be358a2e228cc7b9c23dd7f3aa79595814d054b923b9cbc6c9e6c6f94848c1a4d215679023a96976a44e9b59136241fdf26f8f71fe5a9bf366e4912b5931e1c8f63c37fae2bf1d55ba3943a650bb463cded9a7b062ae55aa57d9c5ceed323fd9a7555e48b834d3ad4441c35d9e07c7c6e4d5d0f":"33b25c6bbbf816addad05e48b72ca560c5191214d903a978b6708a30":"b4dea0d5b671cc815382d0ec6dce661c30ff93719dc7f56e7e61df6eb6a3207a05617938c874bc3ab093bcdbbc983a4b0b587d60fdeb7b87f7b0be4a656883f5443ca7864541ccbfe0d0835636ef08a936b2321a51503be1eec5f7bccd0c73c9cd52397cc214318b30e8be1eab57200a4d4df78af991bde183e0164e694d8308b7d20d067bfcabdcb50f7a2c190c66ce3dd0e18960939cb57fc3a2e5a604f3d9bd6fa440d54e9cc0383958a0d6aa2ab670970f9b2caf866ee507067343f7513e0a981f3a344f2f753af44fda26d661796032bda0f6cc30a9a789db8d3d546f02f898116805180c6f0d2f5388ab5110a521077d88d214fbb32eed2664406cde9b":"989d87703853c4133b6d273686bf672492e90ce2a91b3c72a4188a1c":"0434ef1c127207d0c884701e75d801725c451ce67d2e71534638b231":"0c625e4a334db07825a46b55da9c2e8a5f600a36b71606834097e777" +Nist_Vector_142 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"5a470a38b2ebbead08e010efef7461f6f859257d91a61e2f0ba809e28c0ea3d410e4f41477a398d593df58039c4336260ea7d8e98c9d7daad0c31ecd1567c7db730179e2a9a62007bd56f9d9da48deaa657ac92293e5bfafbdebad1afe25c41e1aa09db61fcc191971c37549155b3e67956913aae3a5f6245cfcb9aad5dc1e15":"13411c1a6fe0063e7f9b2467ccebf2be5cf30e742f9a35d715558ba7":"06a20d5571296eeb87e79eb274036d819e8623b15de44c2697dadecab2996f51a75aa088490e683f34d5e0e71d9fb8734bcfb71e9d19cbda3caca5cec417fa37a06142bfc0682de56f0dce6e826ee9f30d01279859d3ffbd4433bf4a1057ba0ad75060d41f968f6da822c33cbda9f772c2b77bc1b29305cb697182c0d39b132868932c64016bc9071b30920eb385c5ae41c5d4f631bf5f54b1eb4b373bb3e0bf6e448ad8c988fea16e643790307b8b85f009fb67317217d9148c6cd7a46136eece1950a119e5a416a197e00d0e929b04a5bbf6c988d8595a0b2a5ca71926ba351a5f7674af4183b5a68979bedd6491295b0f172e7373eca7e62d78d744fdccec":"7406254d3cfe3d55267236ff63b0f42b2e3b55d1cee7ed1ca3f06ce0":"74dddfa35b25d0c0b285a5d21719ee39d6e3f443445ceb90556b0186":"474865d3ef07f5df49e0a6ebfb5ab5c2ede47c4c6314be4ccf455e21" +Nist_Vector_143 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"0849d67ead3e8c44ad3b2f949be1cd9f9a4bf8b5785bd00ca66038e9a8b93727a652a415c1d8a1ecfcad77782d87d912623c2fef45b2083ec0f79a264ef7c5bfb76fde5b22b9845392e759a1ec05fa6387ccd2943ef1277c2e060337f82aa562cee5bd7c158258f2e779d51e47e000a7b0706077490976a07763e2efb275b5bf":"5631c7dfd3f5adc0b7b542a8d121a07bb8251b6a1bf3a8cba771c724":"b1c61442d8aedae0a04daef7b6f8a49c6d07bd958e8ec561906ddf31f3b4ffd481da5443fe8788056c4ea7b5dfa2cee6474e3fdc83fc043a2bba333d503a2a938865ec3f118640e8457c7d974e2a65659cef5b7ae4f49a054d94ae5e2eb6345f5bdaf92148beecc109c55031fccd90cef88213b69ddb754b40ca8d8f0a4bfc81a287637a38c21807f727a67025ff67b7fcc54418adad408a5c7d1ce05a1de7e30988d560e779fdea1b78753314b0b80fdacb6246faa4b4c4ee8acc5ae24b82312040134cd8cc2fd4fcb191fe43f64d140624a8c6c2ac5fa4bfdba5d625d7d21e3c3f6acd8a153a04fb22f8d3b244ae8c6a1dd0e6e3b2f73c064ffabfad6cc461":"9c353ace0ae52501bbb98a2d1c9e28f3a833c2b0eaca49cd12c57ec7":"2aeb7fce1b7764d32cfb7d85254ceed9f3a6337ee8dab42c8ab7a415":"17cce13bcb917cdbefe0c566318fc974204b700c5cddc5b2b499a78e" +Nist_Vector_144 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"e74639f2bad42fd6393f9b350d6e19cd4c1ce0f41e8c902684ef6f86790ffc8311acd9b57d6521e80339b3243f6ec6b01a06ea899fd75da91e1080fdf06129dd851a895d74b1efb9837289c11d68e1308c47bb8c59d5eb895db53bba29102a5b48b1e75c73387ff22e6c0461196a7d48615ffdb9c8ff4ec6587b4f68d260ad86":"7319bdf79a4c8dbc115e3780c818f6e2a3243ab47263e84ba259bd3d":"9e1b77243aba0886f9baeca6c11bd2c5c55547cc502e731d9c4725da8777ab6050e3399e25577704cfc66163f6df8d749142a7e974e49b7315ab7c8b85ad5d5cb271cf207eb72e1c3476b0d863721c967be15ecbfbf06eadc27de338eaa3cac1dde642d52aa5359198d8909d23d87d827090a8ada7b7a5553642d586603ea2464dabd2ef5e18db3a623be65be7b5a469890f9dde54a27ca723b4e05d56b7181b28d5c1f65415688ee41d5337a9952d92ede4d192b9091639caaa6033e4749418dde15abe4bad62c37fab05e3bef4cd7398a4977e07e121fef2aac56be7e0546e40fca885696a3850c9a28709e699d52611c9b7926e7ad18149040582c997db71":"6defbce0e72f014526c8ab02c6fc320a4bbd85365d99fc5d3423fa4c":"515b9ce53eb10c3e47890556e0f0fd19adb207b9c01f12ef5c6caaad":"0900e3acc4c378bdfe9cda4db8f8ab54436931c73d8d3171c6dc8bb8" +Nist_Vector_145 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"4a145dd5cc4a12ea43617ec9790f1038190ed3d8af24bbec14da3ecf5f387ca9764a8b9cbc5f6292a53a9da9533c751140f8da5fb6f3d48eba1e7b98662734d9a8b120dd515408ba756f75a5755212764ad92c3f2263835211add5b4cc0eca8d4fc7a843f49c38ce80868faf8b498fb414d3080ed41e3674e285d3e40d62f305":"7944fa1a2a938ffabb234ca385916e01a89220cd16f06a474b9d4ac4":"b3f6d44da86a515d7185b70c5adaa3f6059c0bb7995a53910761fea362d9843f92f2271ddb0bca0d4519e33fdb13af49d855cd0b9ab0b970267243e468d3c41677ac588fdfcb1cb9aa4d233f7ae017e67094f4f4d904e1575e76bdc6bd8299b42a2f39adef63ce047862aaa0bb8ba32ec2733493648406f54f5d8e2eb19eea837f4d5963ad3192917f5fe3b6d027b22bc1bf0dce8401d622ca72b1d73a89e888de1e62bead2e4e1da6b5d04b2a3694c76fe07ad3c66426343d67be12b2a72c3f76225573fc054f3b7d735915238d7bdbcb03ba6dde3edc00f8c983b0b50129fab426004a27a038139f2d3295b5b032701face34a7523559485fa631c219237f6":"8ab9322319a138489eb773f3220d712d05cd14eed9aae402a8aa767b":"5cfd4b9f92ca727d513ac14143b125148655f1642c53b73cc25131c9":"2adef94aae372d579c99629ca0786362cb0247aa6d99957074cd7d43" +Nist_Vector_146 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"428a20790cad1c7ba82118ae5841bd5380ee50be5b64b8040935ef3d6da37a26e6f02035fb1937c7a6bcd88c894fad7d8aa48abb89e0c64287cdc637454db89eaf0a7e692734c8a243856dd75690bdcefe554e39a0df84e6e0c96b2c5774a3e4e2afed028fb43d7998d3cdc9a6409322cf3bfa4d1e36f5e707203b59c49a753e":"43dea1b4e5c2f22548074d7dddbdcb94a235a3dbbfdb7b3bfc5923d3":"47a9340ac513585c83bb20a2fba946971811184fd20065fb95cbb20625b47b216f75e1f3d89797f540a0485cfbf07b1716a3ece7027d86f4940ab90bbfdd8ebf15137bcf8805f93cea259c4bea5a2d3bb3dddf83aa290d3573e91aa300bbf1afb9b525542d67a8d86051aed8ff8a2cfc225a9e51eb374c31fe103ae8f4a0c8911421d225c019e1b5c07dc149babc26b708fc0fc0c13c3b35390317c409faae81aac9ab5d01ce85add24917d94cd1b2141b638de3a253bfca6b7f1a8104518d1572211ba52dd175632c8f3f6748265a4bf6c2b8363d9810ba1f1e584794f62319f0451da831d457b5269bbe67784c474ffff692bbe2baaca32d3f85f4fe39e03f":"5615520867828ae7dbc8e9b116e7661e18f09e5cdae17518ead1484f":"8a96c419e0f391daa29fb162a1b9570f48a00810aa480cde0f27cfb0":"028ed9165522fc59aeeb79c491a95ed8427fd1b695f3dedf4228a328" +Nist_Vector_147 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"2a07e28fc102dfe17c79b9368e0ba92414d2fcb407d34e903a0a53370f7d2d33aa13c02e527587718c3b39666125eca2e8fd4c94b9867fb6ef16d555549d8dd0f6e10417ebecf48f992ad84b5d9774540785ddcd264c55796bc2162898ecef4027c34187f8c0b1c20d4daa108b70d76c40ddbebc1e0f50f4dc904dbfbe6beb9d":"5f4f3c4f95efb91c6b49f43afbde6d0f9b5a1324b4926f3276bc913e":"05f27ec035627860c31aa597c96837084605f270d15a3fbbdda1c3853db2ea6f6c9de4e11a6fbd773c300ebad0f9dbc33608f9c4c5cedede0c26791cbea35af0322a607739e97c3242f0ae7d36afe269aae64b5fb2db265cd756ced45d888eaab0465e509ab7f83d623f69e73cdc0c7670675ce0c29f49a19d7038623bde36e29fb854e6fe6ffdb916abb7d61fab4b620dc739a5cbd9608a45e86c2bbfb41b8699166822e832bb6cac66e004e93d190b951424edaf34bf6bd343bf60154f739c43562b03aeb4d23de1f76c18f74b5f7a73c805b22af8cc6bdc9b55779ccf6d441cfd3154616cda18807a9f5e2d7659e9e21329755157dabc622bd1ae2d5097c6":"97861b777e2a8cffc4c2d24e2df9eedf0b65ea2c9373c1085ba44efb":"91a4576931ed621a0342f14ee2ba8fa8e1bbdf894c1251afdf72146f":"56755ca163f7dc89458a7a75d4dd3ce3adec42b4aa7d04b2858c47f6" +Nist_Vector_148 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"7e96385816c97bd9de81de30e67db72436fb42faa9b6ccfeab1fa528c69e6351b2012a1097fb86d8c5cc60256ef11be18f16137617f8cdd29e3bab9468c12ae34336ba0e0eb6c828177d1d55b06698ddf753756af830a10ce9c99f1d13682668e3eb336a80618e666280096417c1e2b005b9351f5ea306b8c63fd184a59132b5":"914e5d6d95ec12443f73c127b797229544971177f645b8dac5f6911d":"2b69bf21bf689a1f5ed7096b27e447c1d52fc2473e9e4353dbf185632022fc605cefe5489102f7cbe984f00c1ab32f2def1a84f1bedddbc15f87aed0a2b1e912e9edd74edbe2c15a4c37533014b9d32b05f5a44d323def1cebae0e216bc35a1ca8a4265c3db5574eb23e17f1838e225e467a9426e8798c5a2e896536c48c4e24cd2ee9da1b61aed2e25b98e4c1f4ee55e0b4705feb2bb1694cb18a6414bcdc1a7489b4bf8967985489316b3e57ea281204ced3ed88ad1b207be7d294127bca86a9b861ccca192c15c815e2328cbdaa5899c9dd271fcd6eea0d2ab009a8ba001e6725139be26c5151875cdca7f91434443b9e5e47a45cdc8b7399bc5e8bed9300":"7d00160fa1ebb10b0465321748eba9ca6e1b3b5216c0c51dc34b98f7":"1bcaa2caf483abc80b75f670252faa2a8e18c32301ba6fc06f37c08e":"909a7852b8d5c8813e17c040779ad0dc5e9e0556612056835e68d2b8" +Nist_Vector_149 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"24ed7a16782b5c34beb58bab6a7d2028719f9738e5d1ba6978efac4b53b37c88e7ea02e0cf0fd82a3e50046052a9049541d12993254a46fe401f402d38943e94918bf7a6fecb08ed1309b7b0f2185967ef289a2efa6c2e37a74d6592a2eb7401ca5e98bb8645a94e57499d362e0f3133ef336e119561cee1b558c15508781868":"3a42f9927b4eb39ee3a910e4418987d1af1ffc1f3d5df0c4920e05d0":"9dccc137197bb29824b1c10e9e8dedd714efc936cff83f42634d64391f9b7f4fc3a231954a8c3bfe4ae0f82225fd52b5dde6dcd14c0ce5085971c515da38183427c7e2a8d76e40efb671af797e0c576e3881d434ca809dd553ccb0f7cd9f73c7aea2268f36c84170ab0ae03b2b46a219547564fd21c540b1603ad7306d22a9eb8ef37ca08c2b28d16c5b9c54a328ebb3c0f9505095c612270d52637cb5584ed08bad7138d3388c634b6502fa6473a2f594040b9acc1480b343d2287fdc70d16ba14b1c2117612dcc5860dbef8387af9aa5e1621d37a38f6cbe5935673ea3cbcde4f32a249eb6a5eed41cfdcaa4c87e8bcabaa6bd1fe5a879d17e9ae35837ce0f":"23dda49474ec6cd13e1b0249ab24f50e9d69e40c6b5c07430780c44f":"5f4f5449b8d0dda3ac590ba1640df9772ff08cec08528bc2d70d7ac9":"5bea04bfd33248f26aee98ca8596774e95ce685465174d1caed7d920" +Nist_Vector_150 [mod = L=2048, N=224, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1":"aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949":"8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0":"4906dbdd9da6ddffa152fa2e250eead3c6ef708387a3ad64d34a0e057459471f48752fde0786db28a4bbf58114d8dc91b69e56be3c49ec1b9880d9917c73abc895754a60779b18bc951550b957a77c8cefa159908126cc801c665d1b01109ba604bb9e797c7a37660bfc0593bab0924df5806ca803381b24b03de3d03b484d49":"0c53e5311c104f11f6eba646e4840d1960a92118204a49e3ec8ddec4":"072cb5612596aa716142f5f756c9542013f3f1628cfc5497eb1ba0aa51bd5adb8eb8adfe059c0e0882e3c09a17d1f51accb687b243fd3052bbcb81b063c1e7d5be066587ebca078006f6d6ee71a69ef59b6365cbcf64d4cf1b9299e7403009272026fc1665ed403ab8dee40eea4ee7d562af001951926dc8bf0c783984664ffef629cb59d709b3d9aa06805d62afd794541a2b4ce0c59043acf73e18e74453e86a082f17914ba6b2b0fa80da8353c7ed9162609575ed41f8eb78dbafaa7b518de0c85b1720e7f493b914d5a3d2d0748273d169d55c45556bcae670575c96a444fc1d789f5bacfc8b24132bfbd75b3061fbacf2935a219b0f2ac5dcad718516a9":"3523465a8417b3a05ba1032bf6c42511591f2830b55144f9662bf6c9":"77475900fc7f3e0b80f3884af8604eef60ffe484bc6cd3de123f7959":"26ca927da0d10b43dc1521bfeb58ff347ee143fc38db451c11a03510" +Nist_Vector_151 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"de3605dbefde353cbe05e0d6098647b6d041460dfd4c000312be1afe7551fd3b93fed76a9763c34e004564b8f7dcacbd99e85030632c94e9b0a032046523b7aacdf934a2dbbdcfceefe66b4e3d1cb29e994ff3a4648a8edd9d58ed71f12399d90624789c4e0eebb0fbd5080f7d730f875a1f290749334cb405e9fd2ae1b4ed65":"5a42e77248358f06ae980a2c64f6a22bea2bf7b4fc0015745053c432b7132a67":"880e17c4ae8141750609d8251c0bbd7acf6d0b460ed3688e9a5f990e6c4b5b00875da750e0228a04102a35f57e74b8d2f9b6950f0d1db8d302c5c90a5b8786a82c68ff5b17a57a758496c5f8053e4484a253d9942204d9a1109f4bd2a3ec311a60cf69c685b586d986f565d33dbf5aab7091e31aa4102c4f4b53fbf872d700156465b6c075e7f778471a23502dc0fee41b271c837a1c26691699f3550d060a331099f64837cddec69caebf51bf4ec9f36f2a220fe773cb4d3c02d0446ddd46133532ef1c3c69d432e303502bd05a75279a7809a742ac4a7872b07f1908654049419350e37a95f2ef33361d8d8736d4083dc14c0bb972e14d4c7b97f3ddfccaef":"2cb9c1d617e127a4770d0a946fb947c5100ed0ca59454ea80479f6885ec10534":"363e01c564f380a27d7d23b207af3f961d48fc0995487f60052775d724ab3d10":"4916d91b2927294e429d537c06dd2463d1845018cca2873e90a6c837b445fdde" +Nist_Vector_152 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"49707b655b6d168c70baede03866b0fba60239ad4cf82f53b46e11b26fa8f6276ff6687d09e8ed1e5d963c11e4763b2e59a0927f01e8fffd1894a6262327c84bbb4298d7d7fbca660673128bb7dea46178146485539f9a8f88dac761d0d5d45cb557cdac960be23dd9199acd99cb64d1fee2ca68e423461a02abb34c1dc45011":"62177a5b2f0b44352f643a9e69c1adb4a0b292a5ea52fa8065e94ad043d46218":"385349ecf99ce783d4e7a80a7dd2c533a3623c38260243ac392d4eab6deda5b79b8f9167922e8b60468623e4603fa7681f535e20de673531255e108f542a26d5c87f19e063372d142869c5eef1325281fee7f1c74d2a96255d420f2713864d55d36f8139194f643a6e98b5bf9732c8597445af5a71e23e2ac5cae3604323f7bf09449786974ed53a5717f9aec14dd01bd1cf276bf3c63dec43c3ec8ea6557de469916412f0456c90f01291bb7125e9f855f455b360c03d4a7b4a8d4090e47aaf1111f382dd2605734fb54f4b8ffe23c9ded2900b3121b497bd46d0458a09a5df4aa9cf1be906f5542313384f93d377ba9e0a762b4793403b914e52865afabb67":"2bae4225836dcbbcad976ed47ecb5f3fc05439358791be244e74d2cf0617fc26":"0fdc5a5a4a2c2f3df50c868383ba800396ae25265be1a14762d3110cbeb34819":"4b41841cad45fedea5aad0a16b053e88353b6f0102df74c9fce09e38f5e6c277" +Nist_Vector_153 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"763c1f15c5dd8a93aac4e048651c4ea84af18aee255b56959eaeb1876699be75271af0da6c3ca936e99be4ff4436410f69ae7018b6c843dce9d8b71a91efa53c39be55f285fb8ad8543952fd3ca89271ec23d342cfd557bfb72db43b434d0ed5b30763037754bb0f782ab08235a64abb7f0a828f892cde7e05e301da7c21c096":"5d169761a3887a9eca0f7e59d77b75671ae02210006e754bf2f12091fc3275b0":"0becd917eed0be9cb58ff9d259a8fa415b816da4a25d3f569d7b9f317b3f47e4244cdef35796fb455c05c156452f1c8660f5346fba169276221446f82bbb2027b056b537cfd59c57299166a6f20871c74e6c1d3f5a37b75e8dad6cadcf12c909586a32f150c68e332306abef8be1abd56c42d3c36936cf8f2acaceb707994a3d4c0555a015de892037aac68e33813bf3050f0f3a8df5e81465852f6a195ea688ac5d258eee2076a6b236362e3d792e7f358c6ba994da7a64b18263969655473aaa37cb3cfb00a27f8fb24a4b73b025c96335438484e958ad0848277df950847d46a9874f1039fbea7e08bc79675ef1df6ef21230a79a3b161308a0a4600b5347":"66011bdefe8cc4a04fbd5d69252bb72da8f9a8d6e00bb7ca75719133ecd86f1d":"76e9b6ef7e8d48fbfc43bf465281592223fa7e0d9978392d355868c8a20209bb":"7f9c8deab51c60bb6f866c76450138e0d2946aca6c5f88dfe35a0c1ba493ee47" +Nist_Vector_154 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"67851de982fc70f969d82f65d85b0332d667114f27b58bb9e565d2e40ad011983d936049cc97a216260fa2e410ad6d6c98a548759aa8e2d022c1fbc1b16b10d83fbbbd126ec43d5fedc407c831461c7f33ed94740031ecd0f701c7b1df88a249265b3f60c38f4285bbc9bae164bc38e162c235c9a9dfc1b150eaeb1482ebed48":"4f3e2c5901b656118d88a47fe2bd52f85cbf828dbf9b67365e2013a937f0f2d9":"ab9a99ff87899bd6657b3a9e9b7206996bbc7799dde57dcfff8098875dc4650d791e90bc4cee10989bf49eb5e6230857f96841ae8362e4ee5cc8602f6a1a2c6f8f2f680ad3a72b0e07511ead301f575278a074138aa4eaa53919e34f001cbe2dcbc345c77f5687d071981a4dca29d026bb53ec9cf03a88d63c52206d351f8fca10239e84f4915ce347f48d650aaaa6b02d3164973f82fc0e0f83a2d458af65736d7e0dbb264fd779ffd5a3f066584494598526cd67e12d6c67965a70ec3f09e2cc447f177ec87604b531486683025e3b520a26e69c958cf8435f7c6ce564f0a72d1fc47205a50b39d516b14a476f6c2dcace50339cae20cd3421a75f6d377b8b":"72bd0808076af461353d98cb0191ec76a7c04fbe3a7f793e390cc773434c1d4f":"763e89fc8b2a090b75812aefa55de7b7cd61ec3fdf8730ce16b05a7b9456fd2d":"4a97086b6717a73a6be6d4a95b8343bd20b0d7b51c3da1d86c5852350871379b" +Nist_Vector_155 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"616de9dd23ebede428e032db7838108a224f7aca57b1df87f031fe1d86083d688c5c3ef078e64d8d5a9e612d3983460ca1f816f787c03ca43a1fd8ce138655df677056364c0eab8e0493c07bd4b2b05022190932de794f195dbef297093e7da1c4304db40b63ca53e1b8bcdad913d7a902af025c367c48de387f1a9bcd7ca42e":"4d0240a34dd45aacaab9e24e4838223ccb759f1d93fa8791f28fc7c2e8318820":"584eaeed2dc785d8e2b8c85fd0e5ec251f134958bd9eeae4f79f862b62cf602ab10d22eca499042f2c875f2708ba0d697af39f23f5e0b7de4ff7964bab1279efa2aa797a2d21e788d249f42693cdbfd71fdcb1aa93b79bac0dbcb587bbff4ef15a3799a5fca8b1589838e30096069ca7931f7408815b585d140a747de43bd92cac3f9a9b1862fd704673e1e58710c16ddbe7e52d31a7df15974958b1288116ed98ff247f5028cec86d9eb97b126a48adc952e90dc52f2bd7810355aa9075051f26129c2d2fb0ba8066e414989d92e29e689960e33ee56ca62d714a42cb7487f70c0c0ba643fa9dd5f85259fdecd49fa970c8322682b114f2647837637abc0ed2":"325e19d8b7ee8c8d9cb7e70bb5417035a8183bdf73149a45f0e83f3af68decc0":"748f466b7fdcdfa77017c865a33b1dad4db99dbd63efa1c87345c4833b0632ac":"0bf9938e7972ebb00fb0a3c0c2476d2509db23afcaecb17dc571905317eb8ca7" +Nist_Vector_156 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"115f0a8be34e84d09bdcca69d19ce17dd67df739aa4fc6e8077076535f39af8302881471a5fb0e1839a3aa76dfda4bde2f9fa25fa582b756a4966d75320ac1995472271666156ea86c19a239895e5578a3c39b0ba3258827a01df1f30db22ddbc267c9e290d5d457d0a94d8aa73f8e79f3acd31bdeee7aa32c792c22acb807ba":"0800394a2ccdd1f55800565374d46be9bbc1190b55eee26502bf5f2459ac5cc0":"2e06073f59196d3e29ba718e84489b6f447fd6f67a9ee6357c5e8a58fa3c4fb6ac8314ebdc3b4d6127f2b4d2112c27799f0c1ac5f7946b5607212d796741cc3be127212a125edc3a7a91a525cd62152199b18b4f1dc332215d65d64ad06098ff2180ab47bb5728720c937e1207649ed19c883331ea415faa51c556d12649665f1ece880d055a2a793adc74b38f15f50aa9b46786d907017b1d6235c43b37c2036a1640f6bfe3bec2b95b4300a3bd78f471f6aa56e5e6347571996f778670ad94efaf20991c555924fd55cd518df0bd558faac3f9826a865a3ced0f59cbea45c65412bddf8f2a8aab3dfca1dff50374163fa899cc7f7f108b194fc955cabe9ca4":"617d00444047d8e943e429947d28b4718a8b7603475e5453cacb80fa704f90f1":"5c8d76440735055c1b36698da73903b332d64ca5603046144fb7668b1acac337":"11c54efbd492a7147a1c50b287377b52d2193907d5bb636159c15318a480ca6a" +Nist_Vector_157 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"3c1f2b92db1b4315837baa863043a9b4496a78143ca74f6e67181facf50a6e08d27945d00e7b06f9c57c0e2f1527c94bcecea6993175d0f09bab4f15af55ab7aa9b16b48c94a6a99c2d7e477b744cd27cdb9b0bbf810756bc6376fa15bfbea3c9376ca6979752fdb3a655affd6c0186d1a34355daea8cc75acf96b8847dbdb8d":"59edd0348ca6a85c408816549e9c58338ef92f56edd8fa753226acc0e181751c":"a4742d3c7e7681b01cd6aae17423cc780491d08df73b4a71edf7bd2ee29c698cd66dba0491688fc7eefb4d709147bfd4c8c4b797ab9197573b5d36599c4a592c466955e80ae5d2122bcaa5d0e1d94b4ed2a99b1af5d08eec86c37753a3c3656c0fef0d2c471e4ffa0fb163174a4df1707879fe083655291127a3bbb0597e23802e424efe4016360364506c8ab4081f0a95692c2629537f05306181db669bcfaf01c15395614238a2309429199555142639b3443ef85af74b5e88b7c70a8167334f27294a8ba1266695a369372badcba7623aa58cbcf25b4bbe663d4eced1a18e7753391d6c53854c4a8d0ee1a790a1a21071f1386c235ac26182d01a1e81ecf8":"0a96189b8740005f215ae5c5a8aa8686dbb4c353d2c55deb3904bccc4f9a9b9b":"31c1c6aee7ed541a281f37632b27ba88536f36bcd92fcc360da041f4197f7f95":"45e1019b2a1702b5df1eef4fb7df6a53aaa66ecb8be5cd2e28b353c870e01f41" +Nist_Vector_158 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"ad389f53235deb068f7097780330746493607fdb7e1170bd1fe0da012714b8f1b128c69a53d7dd2646b09720883e2387dd15d46564adff6642372c838287bafa5f4343a27ec8069770e5c367548833fddcc5f8617aaf41289d96dd40f1098ded9fbb110aeb14d69272dfb2dd7d75e7a88dc4147f27c64eb1bf0aa0569bbda320":"19ff4eec2e47301d0b70a826dad822b609c997bc1b3a9d7cbd3d1d2252e8acda":"bf4aa2d867b433f934d1d567010dbe067905f4e35d7ce568b55aba694d12dfba95c235078461aaab81f1e4df32319e5759c5263ebfbebf7960c57aed79bf2de38948f8ff79ef26d66a7f98384117dce1f386aecc4369afb2e0de77ccd2e7dec328614243effac607c8d5fc5c7c0b1143963573d9f106fcecf2e15c67a3bff6908b286d0e4131fb81622fff9e10f5771afede2276e8344d9ae2f493fb4856d1ba5760ddae38af7ddca409e7907268691baa33dfcbfd69e9aa9faa79cf303ac8b1fa07c1d40d1cea01e8ba0d65265f4c6aabb16ebe2f6ef5aaac25c0c2730cbeedc177667ee02bf4523418a986d5b87a9b75ec201af0f1961cd51b85879147e607":"7ff51bb8946842c7e2f7245e73461e2b0820528548f7ecb53bcadc7a20e826b7":"2f9484aaeda9dcb88d2d3644db2c58eefe2e7695a6c8be9abe97173efc9c0bc3":"0166a7bf4e8bda6b86396943a74a8ebfc603a85ed287bf3f5a30dd0bbe49cd8b" +Nist_Vector_159 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"12f9582e3a1a76f299d72d9b1502b99060802660226bc47b71e54ec9388eac325902acbe2bd7109e19f377c9d2b4d280cdfaa48888b9cf4ed06ccf5ad866d6932d402592f6be6e6876db5a62beeaf373b60238ab96829243759bdb586f45ec4ae2cb22248ab0b6aa7a7583a61dd3b8f119cd840479a4a9af8a439db904ac14ec":"7142b195eb2417bc234cf32c6fd7cae470cb48c74dbdb469a264c1988eb3e52d":"72d8100692e1a30a32e37c909eb6c7baea7258b0b78668e75915070037479b884fa9f18066df89b490f9a2696a8505036977604dad268e90552835fdca3339b32360c94358ffcd0b1ea11066122efd017cd6fe1ecd0dd6678081b84cb6e144471dae7636b4a0929ca71aa47b4086665d66d4034c188d64d38b69f0ca171c85925cad2840277d2887a7f7b81e6b12870cc3c69e18ca9c22c3d3a39ee286ca65d23f3e8111aa7c6ea9a0d14c84ddf76abd44db3b9833d69cb99b524c98fdb9d0ff20c9d268e8e7175f13c11c5795d0fe0b3899b74c0dca91476febcb509f7fd507023988145242dfc809ce95c6f1b31f67e01650dd45878efc7ea89cf6e3171e43":"1043805a13045a36e1b6498db97d163571c61cc4a719e506173b5e6df33fc81d":"38cf6b8cbae82e6295f83316a9c49d2dc7c92cb90b19a2c2d45649949354d930":"356a5850d07aec6e9d4a4d7f79d9b0352b087d7ef48394128c5ae4993e8259b8" +Nist_Vector_160 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"b6ac84c49f6bd601d5868ba06d49b8cba87a9d6e7905247541fd332c2b0374cf57d4a0dc0b5a6c3f8f7e24be3a1eedc4a8c575847c02e4edd4745040685670058996250f73e298a43b391a4ad567f0c9bc4b6abf6d1e5c56b22f4eab36aa1a812a1dae8d2873cb2c2a521d320019c7cab1efb11fa4595c534ce527d43ba605f7":"1332c3c6e2d1b7b16f501b6d48c7b866628f0c82bf33354535df99a843dd68ce":"06dab48a076e8cec27d4c4fb98e7c00f36bed73f11e491d913864cae0fdf883468d735deee5251dd38a1f8b1d2bc19d37f3187a4ef69c33dc9528801a23a98d96fd3f129b8ca2941421ba1828e0c4f8d88c53193930292a0df1147b07c20aa726c7177ef660ddd4ecdd73315d4b9356013e115f067e843c896c1a54c81ffab1bfe7c785edec32fba652babfdaaa039b0568c6beb7d13fb4e4588140ed626b18749b0f79f669f6e7045738cf50a6d0028ba11fe1845a2dcbd9c1b02336fb30eaaa397418fe17e149829cab13d2c2e6b90e5cc81834e32fca8a173634e01f9a973e029644f0165b3033dfb054dd21d65e0c0e137b48c34d42134c47b972433ccde":"167b97578e52869f49730df464f7e8d786594bb830d72db9af2cc88324ded288":"1d600a745a1dec933868dc535a19ee9f1af8bf09b5abee15dc4f7cbcb95ac8c5":"23b81097d583342ebe4aed364a7af9882f74e64518aaedce346c91d6d7ac470b" +Nist_Vector_161 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"a92e2ddbfd18cd307373fcb39dffc33e0b91a48c62071f2f7a8e50dbf2c290889307975b6acd642c8e3d3444acac98c22ed06551fec5dc7c9f2243b681cc9fa4fcc12c318237e9a5df0a77ac22402039cef31b1e623af58212a22e7e60419bb36b777cf6ce65dd1f56963eb28b7706f137c0f7363a002d827e45badc20233c16":"119ab8a63a22a89baf4eb8f016dcce9423d5f40a677b258fab072a8cb622ebe5":"5141223f4697de272269f3d99437c48dba5ab7f1373fc6bad8161018c5d6fce2bccc40ca78e4d73b6eeb096f175c4cd0c8e9f3e9311951d51ea244fd33d9e47de75f1000248fdc003bc07b501ce58f6ec1aed1754c36826cd91976b408eb7aa9bc42448058ffd3b4e513c6589f8e1bc145a47b2470e7241e2325e54302255c3d6d97abc5c6056266a9523d461fc744146da35c04a4fc0b095881cb94fc4c03bb8623953928490dbe7f84ef68667f23d4cb3ed887449f77aeb158a26d1b39b4e6297f23d49f5b41f170e72f7213ee40364c1c9a63985f69e44eacdfdcb58c35dace8b935d0789a8c0669a23d673929b2a582d6d3b2f9e67be891890da1236c6f0":"77cefd7a6b0fcd0237ff8f51c458e5e8a79116eba6f11ea1af7f29aa608393e5":"34a65e99bf01698b5a68f215b9c292115d17b3c202ea1fda17fcd8a0cd74b636":"7e67d442b8f9ac2974e84ba65aeff0df5f83c271ece792a8dab9c4aee87bfea8" +Nist_Vector_162 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"b5aa1cfe2348d57f0e5333fc70276d2418ddda49122f4a88e8010f6f78dc829ba5c7cc68db664080945c43eeb705c2ef13de6e4b8f4de1d04fb33d5bcd7893d8ca8bfde38c9feca6c4ec03b2ce7b35ed60a6a43f7fc9ed08061a099b3eeeae7f0f1516149d175a953f52c8c518f3ad247c9fba23f1f829d5cae62673ee201ada":"4b75db034ed0b84dfcc60b493a00940e805feb78575fd256b24d146b05a9500c":"0b66ef2c7a34205d70fc36404957043cf46b28ac4f083ebac3787f55e8dd1f75d9193a842759376f0508c94cc7528d6611b50a73261a4a5cff730d9985bb341dfd739a4e963d1c40f114d7a7ace89e81dd70861efef2ba9d1c6425d5f85809059e8ef31f453c97743fcc94d3b1bd62084e975790b37193eb4058454ab283fe2bafaae803de892879554a340b9a3e2532931eb95d3ac5eb3f290a3f56936951288e1c05bda1fa74dc78d631c2e7a56367ec5781019dfee71453ea6bbd90778e92fea8c26bd6a823fbca71577b6335f3bdf40a30836e948db032db5a4603dd31b851ecbbdf76b4a6c9951d2192b97ff01daa5cb030e15ad1d4cff367f700e79ffb":"654aa8be3b7bfc32f9b560b57a88a8aec1cfda276661283b7f44dd3b0944c20f":"517f7df4831fbd01908b9218b17ae1c40e00c53404b3bd72b64f67cee75215f2":"1903434a727c8ef0e80a43dce2834b807839ef43c22afb502b35a381782bb639" +Nist_Vector_163 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"27aa81d2bc49601c3f6bceb0870bb55dd10e7ba6d1f8acada70b5f902a0f4062eb93ae72cdfd3f943099cc2a10a3da7bdc9f24b00bf36a29d75136af10bb71ec9c1932058e22ec9c0600d173d37970d58ae1f66cefd27e2905afdde4223979b4041fd7d7166ea326befd5dd896ef47abc6d045c1ca23c1953a6e12cc3c54b4f6":"7e6b77d4bc9220c3352e91abea67e33a335ace34ec4516646e8a4ff098166ff4":"932b9c0f2d310b6bfee800c074a0969efa246244fb062a745a9a3cfe6f5336a313192e92a2027e1d2c3cfa93aac53dfe05cb8f8321ac882a63bd375af0f3d9ecc73aeebe1267f473a9f90b94f5b6de4357b74eb30cd41aeafc259e85cac7d365ee33382a584eec63719ea325a2414e116f84d2af9654268ec44d6ea2e981581d45d805b383d85c130d2dcd1c71fa68d9c76d79aa8196152c1d9440c33d99de451a359e0d2c51d6aaecb26795406e528f5de3e00947d3dacc695c08a960889a2e94ecf0a461c02afc58b51e00369c73c8140e8b92388caabd1f37a62d1b210e0f314127f46b576a4b8edeb34713aa4136b8a1875bba8a5937066544e34c206aa4":"73c28bca3c8067da792f6312153b298a8f714cad70bb2349803b6dad024f6bc1":"05057a982ab4a2e32238ef2e3edba07fd193d90c5f053c83a9f176e21a9d5208":"03c2b26cf46b7f72691a72d7cbf33653df347f02b0683ebc6cb7ea7e72dc8a0a" +Nist_Vector_164 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"7527533f2d10c18078f5a8dec350cdfad06d3157871e4ff7d7c2b7ab11dff232d34f07699278f075442e1d4ee00cd6e87c1931333841c399576f4e587a251684e731f7c8369f712656bc1e6c2d209f511179da09368d93290e058e0ce9b6530ac6c5e4cf0a1b22d588d98f32b34e85206e09aac04a0e1f2ae2a5cfdac4e6e2b3":"40792e5ab46518c6ffcf5357f0c5de5d9e2de99c92aebea82a307ab0f5ad252b":"72c46505e4b071f46ed6b6d530801664a4fd518e4c6be8468a38c22bf74ed966fdc7bfd7c572218998fc4c144b59462af7e294bdf5797ecea5cb2edf8c8d2dabba88d0b84cf28524369c5040b58f090772dac0fe453c32907e9b6c740fb24ed4dacb8fdd25e0661bc0d79d41f103fbc8f96b3e3a4708a5a7f5dbffc98f344bb7ccf0d5ed07af2c2f0d5f407bcfefb54d9b947604e7a78356874c01b8c1fdd749f6a3d619d1090c83725e725706846c16bf9dfdf39f2180623f4f585402cc7d6e2c10b57c8300543686a386056a931be6336bb6173d9fda8b102cf32989cf0978f956d9ae0d8f30752f156f9f92d2954ef13100a75d9f7ff96fe15df07e7993e3":"0c9fe826a7618108684ba2d74f10ca39168feb85f74d2737fd12d18cf27a2f16":"6aa6c4d7afda30ff2d7178b52a3e437ed5b0745a247c9c9e120bd3e833a1dfac":"26e0887911bb5edb6a566a2a1276353391b1e4ab8ae0b259c1bbb3af3d85b439" +Nist_Vector_165 [mod = L=2048, N=256, SHA-1] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab":"8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7":"aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f":"994a49e5e8a5698fdac9a7faac01fb09b2c6113a186677676d11e6049dc98c93c51eb5144af181e1efbf44439a13d295653854813671f032aa62258c14195c4864afae0b5d154f97565cef075bbb6d97e34181410309ffe98b45c1f874326343c36c14f55fa058489dff3b49dc7888f45a099c3c919b25edac1706bb90f164ca":"266cfbe6060134ece2c8b9e6aa25bd6cc935e49c23fdd4fb6adb2ecde63a4960":"05e233ac49c1fda2a0c3c78b0bc72fa39674055d188a124a58ab3850d9a888861c2fe4d046c3e7c75ee254de70cdb1c3150201c2e04733ebcc25b88770fc2aa82f60526bc664047a026c2290fad8e9f81cedddde7fe3ba406535bf2710d79da01bd2d42bb5f4099c3f8bc2ac864be7892aeb6a1f3402c81474da23e0795cd6c21367509a541591ee1e6364f7e755b1419e90af869930152f34de51f0f06ca3076e68c3e3ea7f4f1bf1d3cde3a0dff0cffa1b5842752347082dda3475992f15a74d298524e636220bc9faed08af7aa5e481ba78d2d2fd8e51942cfd084efe0ebddd7500efc95a6cad37fc4923f9bf65297805840876c689ee079b7fa6169768fa":"60f8416735fa49ab567c0bf1b6da434e1df41579699c1a92a3e70e1d90705379":"3cc269bc7b895864a03231318cf39379ae33c7180a18c08b5aef7414fdac058f":"6a6eb83c5fab10e34f0416628c821a6de0ad0c202443c6df032cc9d8e4948ac6" +Nist_Vector_166 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"39f2d8d503aae8cd17854456ecfad49a18900d4375412bc689181ed9c2ccafea98dca689a72dc75e5367d3d3abfc2169700d5891cff70f69d9aca093b061b9f5057f94636bc2783115254344fb12e33b167272e198838a8728e7744ea9a2e8248e34d5906e298302472637b879de91c1a6f9f331a5cf98a5af29132990d27416":"6ba81e6cd4367798aaab8b7af1135183a37c42a766dbd68cd2dce78f2670ef0f":"7bb31e98c7a0437f978a73d5dcfbdfbb09cc2499dfaf1eb5256bccd6358cabb5f67d04a42823463b7e957f2b9213f1fa8e5a98d614484701abb8c7d67641fe6ed06fa4527b493ddab2e74640fde3de70da693f1db2b8e26417040af0eea6cab451a795a52e187d2ee241b93f65c86c6d66f45834cce165ac5eb670d4f0095c23ce9757e3bdc636f991ee0073d90a09202edb35cc3ea1cf9adca1617fa0bffd9c126229a604a1d3bf4931ddf0b9942dfc8a2f8c09fcc97032564a79ae1ebe1e2ce49ff57839e7c43fa60b1603d15a450898aa4e4a1ee8065794126d64f013367096a83686b9f158c33b10f5f3b36cf1f6358b3f34f84b101dc26d3db68bcc95c8":"45030b79a395b1632700cbaffead97998d02bed8e0656876fc0174e4bdb96f79":"059bee9e708b7f20c3f791a640edee964e0aa672893c484799715817b3a8f6d4":"4bd41c84a724cc86e4f0194ec0fbf379e654d0d7f6a1f08bd468139422a5c353" +Nist_Vector_167 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"0577ee4a9b8dbe3c6fb9725174e89940b27e8a989217b64417e66f396a35e5824f21e58236b27910a3be6b57d311aa778bef63dd025d9435301aefc92223c1aabb03d3d5d385b1a3d1f937f0f1f7f8baba91a011207480b5c23a78ebaea69ae8ad4373b2b052d60c5461111479591f8330123bf74370fba66bc7e2b400192c47":"7bd811cf6056c1a821a85a3169113639d775247bc6578c9eeb28d4b09503ac0b":"c54a57b08f255db1c776bb2126ea3c1e60229f1e1981e43f1d6b9110f950edd8245eeca7d55ba06468040855b736db502f01d6b3cb2d9d621c4db44cf8cb390ab2ae332bca219e09bbbbc225541d4a0ec0b4f11a591c077f2382f04bd93b364c94fb1c6147ff7784e82558e5fb68427459fa9a69d78a9f6051bd9431887ace46fa4970f0e22d75d2befa5a228e489e009af97ce9211408b4e5bfe37d3e0700b258b54174a5125eb6bbeca38805da53b1f5829dfdec8c4c9376bf235b7b0eb7119d3d69768b80ee02234589b8d95faf8062a8e1e9c3a686b6350e30fa535eaae71d753b7c3b048f8e9722254dedbc220ac9c9af0784532032ab65e48ccfcfd623":"7ce602ece3f821390641dec7ae01b44df0fc822de1c013496bade2e3e44fff0b":"33c198ea68bec4a7fedaf0309c317d336b97d1eb1f1dc44ebaf5c85c5a3afa98":"5c9b23c13bb607be5473b32ae2b5e8f2a1e18f59df8ca7fd9303f76ed8e680e3" +Nist_Vector_168 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"c643695d29b28210017aa5a7d16ebed81ba00a869d6681d1c0fe90a5e8be9d597329ea15d24ba12d77e4c3f2160bcbe808840c6e77b0528bf9ae588738e22f41910a80a7c6e3340c127b9de17945e7f9229953e2850217b6d486f7cc804e720de214cef02df4a892f7e42898f15caad26bb30bfaf4b0551aeea14035cb756b11":"3ff2653cbc1f27253400a9b6b1f064247053c9816cfdcb704b14bdece2a8558b":"17ff2a5eff3926ee1520d5a63a13b4f701dceed25a653966f525450b3a63b03229d615ec54cf4f6ddb868b54df363feecc95eb8a3ab2587fc4de9c93dc8f8d7f38f99082d2867b23d073584c831baa0961651e071b43f9d5da97b60e7b5b7a935f6c1dc88279608e2bec5cac6162488085d092a97c6b6f24536589b801b6b48d478796b52c05564e904bc58ac1505074db3734fcf3575f79952ba0a2a0697e55e579d508a400ebfb2d4694b720804a9d00f8845ef0a8e690e675b4c1ce07996d64e666b0d6a1d6fc6bbc3cd9b5cc3864e5e888e3c335e05e83c67c0033ba5efc3dcdec0446d3b40793236ca074c54d2a74dad296d7c639dec938e3bf1ca085dc":"356b49268eb799dc4db7781a06be0f8b96d28f6a13b7523c0ecbe70cb3eea1aa":"4ddd2a1f411b570fef6d9184409b4fd55d12c5e4bddc2ac7211235873322155d":"4043952c108ef84a25a168ea5b64a4386f7a483366054c5dfbfc5fa98579432a" +Nist_Vector_169 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"2f64d11e290275987b7d7430242289afd54f1be028cf36f8f55db54be70b8dd5ad74ae26e079d0ed31a361c116951bde94d686abf15ac5ed1470c3e902461cea8e5d58f407d2e0c072ee61567da7b353f6c47e694cd607f3ae894a9705e8ea2bf9ceec3acfa6d20b238bf0a7a7eac76c4462b7e4e4e868174a88a6a6c9476cdf":"4800e9ecd9bef5a4d46aca60aca96955d8565e1b85d84dd8141d4f597e178bff":"41cdb2c1bdfa3652ee49695d5e5eeec00f64b54b5676ee27f043b43f24133f61425b0cebaa1f88da072cc68865c12790c43285b7e19c3844fc7d81d064423ff1e19266f69f7dcb3d0203739f84d73bf00c52d60b2875171216678d59fb557553edc9eba6b84127169fe5dd2f81fc902c970d1d8d9c4779dfa1b14309f81006ee641776a6fa36339e963117447aceb823c9ca3367172eddaf6e361829dae43c4038cdb90ebb68b53c0a22d410b6f1bfa7c47496ea3aeddc36bf24f219b85917a24d30847c77d87d22a7f7486c6684755e045ddf72d41650e97b64a64becadfc47d53555127f8b7ab78d480529571996eede4618882d838bd695efc87e74d68ca5":"460410eaeb111a18cf894468e10a88b8de8ef9dfd9a2ea1882a9fb696fd7823d":"4fe6e2a75d9c72e81ac60dd33d31180df829b31a0dbd5fd20b7e28c4fee27d5b":"3ce4a06bfaf70cb6cc93f33f95a43ad77ed7ad7c77a1674bf849e9ebbc5eda29" +Nist_Vector_170 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"173c4a23621c32c3e4b157ef96b02fc1bb466a2537d3f6e51a58e510c4aef3aae4bce4c0b4d59bb1c00e7a35f98945ca9d7fdf1f0bac732d425043062bc6d32015233dfb295ae08a324ac7c1e02a117ce436d77d4e46d0b794af04b1db82a2709da1c4449c29ccba93db8ec48eb17921cb389f6e0ae32995d7fee1fa07177a7a":"3e696f226f21916455f8ccc861b1845303867b75303ed92f9ac79088f56ea708":"673e349cf6d05caa16751d97ba6e344e40e158e6a7fc53ea2db87891341e6499825b5b9edbce9190bd87c3eadf7c6d5bf0a793af2c3a1c8ded790bc319449394c64384305864723a8a7bfef26c082030ab360bf9abb11117e61b00549726d772221f6f67c4a6a110cd9a9658781ea8f7ef2f176c6e8816a865af396db95d8415b541cf0f83e45a417374cf3acf5c6b4a98390522e7140cc8aa3f9d2dd26341d4eb79e4d931a178e3d57dc52bfdf90115e01b76094ad0294979d35d92b574ce7b0c627f08be66f99effadc33aed0f634f6a89507455d7341ee64183aa610d8bb3237147bd90dcd9c1a03d89b26ee31dbef5ae7e764ba9f77b6a7434ad2a8f966c":"2837f7fa85efafb433093231983ccef5d82080e6063f67c68ff93465b59d581e":"393d681c3edba28f7cb0f30593b94fc15cca659a80cfbcb3b236453722d5b402":"44f7421bce1e5273a30ec016bb9969b757197987548e434e395ab3de1b0e7ba2" +Nist_Vector_171 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"7d6f2a97e1eb085cb9e83aa24047af9ba30a05d7bab564a149b9cd2366518e8f199134fc2ca403947f2a614c0363ed4bc1349dc496a8ec74d880578475e47427628bb023f0272208876a3a7333307a596c158eba64ce42a3c790e7167ba4a327ac71aabad2f36341edea12ce5b2b735807b34b714a49a0aa476893578f0645db":"660898413f7a71804432ecfa11cc68f85a34fdf75012c965259ea6ca0bbcd976":"777c251067c8ab16cce2c4a4d784c7e806fd296cbbbab0132e2ab91623acecd830e7cc7cde03e544b51fb1d8f0b2eec09f559539aa9d63ebc0c1e32579f095473d12717ce88f6671ec7e3d2581f61bfde66cf9be216d6a208086cd7bea770150a9bb0a5a7a0dace82b464180241202a30b26ad5fb933c8235ac2918e29bc53a5c01ebc1e30b1b46e37124aec596f8d1a73baeae588ce7d4aef1ae84e9a9766c24367321c047c3caba629f5d9185f0ffb3af7e50eebd1ba0eb77eb121b98073794cbc6622b678262ed3e229c6ceeb607274ce3496f370b482bf8f68c27366818486b72adfc810b2f579779adc9c25002e277641dd9ffbc5db5239f677ba1a9c1d":"4abaf5c6f8e28356fd0dc6f096e9354baac1c2049170b2db05c81bacf02092f2":"463b1fd6ef2986f75f9620779bb6f47e0beafa9340e3e5ee589d92428acd4f2c":"27edd33917e49bf771f3fa1355cd3928d0bd401aa7bf0541f3af1643efd7b677" +Nist_Vector_172 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"7f8785e1c4f82bc0bb75f78d8c4113e0887e761a86b48dfa43a3683b2bb886ba53f5603c8d94a052af3671c5c1e7c232908e10faa6cd54efc79ccfd64811131acd7d60a9309729455aa70443ae8f32a34580f9a1aa7d89e5fa8cd4e95809a573ec6dfe9fe35b1130571982a0dd46eeebb6a16f85ee6314931839e3a4c29dc700":"4be0926fe24da1667d71d2abc2bc0bf87172c05d7c363a324ec61b4642777e57":"28c06e5ab3c860be8c13f74f28b5792b39487b79547f4afaf6f77a5c3a43e88132edf944ee00150a78b58a78cf92ed941578ec679e106767014e5b279c0eae9c408e6ed60687ee1464988ea545f55be3673ecda10c63fb0b1908e796d6715abd5451843da6e63bf8802ccada32c7c5342374ab26ee701f9db3d34fc96de9d23021b98a93df6877f84fad6741164055696f3b72050343ea3e5cca01a3d57e29727ebcf8583118146c27f42adaf62365b9697cf03bddc69d0bd151f715b23bfaaa27a368114b3dfb54c084e06d4343ffde1cd22058e9623a70e9942e090edc73db06dd3180bb960f0d7fed005b149b69d6d45f40368fc25ae04321eda46d52a592":"057cca710c8e4998e9fe154cc57847bf35a512e6caf3cd338372b5becc66e8e1":"3165b1cf3ca9bb89154ad684e089364f91b6e5d594526072f7b9db3b2358e711":"49e1c8c34724ac5532fff1c7d243b486a2cdc0872ab84fda6cf2ba96f958f46a" +Nist_Vector_173 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"3e17ea8b9feb2f4e55c103e58c4ead96b5cb892d0982ab2b0cb1eeb9e1ddde9990233a22588473421aadf52767a8df524bc6e6ed857a9fd5942ef976b1fd8bcad31e403b1febb865d2872a7b34ecdbab8b245ada45243a49c7be67aa09788029779d619de30dead9f7d8c9c42153b865b1a9e81180380e27a305a6392f4b2a0b":"75c9b6c63c80755f7a7bf38eabc58e1bc2e0cc5cb4f2274f2d63058157656608":"b71d0ab2d405a5012d694e0a4a82769256cbdb49c18112efee8153c8e816310486a17bce19748b11f3d5d18cb44998eb329b951c23a57cac47ec9973839b130f3a980e62705c0702e4d68425845d54e152e2e83646b56a6757cde06f85ba3779eea585dfe8302f12ae77fa58cbc6dcca70b461024b7d176510a393ec027c769cfe49b698e575fcf99c60293af2ade3dc4df23ff3386f13777306c52de97ed1a886b824788863ff7263bbbb5b5fa0d4681c16942272f5e441bdf49eec7556c1fd409c78e3aaffeb95c1267dee12c24c045ef67aa70e9a3d9244f2cf1ac68cd918df5f62a3dd3de7bcdeaa3f61de51cc01af636bd665c0099d13938eb4fc289b42":"568b8f5049c2c411f05d74e1781be5718ff921026728d285f2a77025208dbd41":"11b7ecfeb339d6014948de5ad4c96f4ba517a2cddca611c8887fc44f14ac9a63":"13287a22cffd825302b0fdc0955458d918727092c7bfb3ec4c3d7a838ea6c491" +Nist_Vector_174 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"c3e1903ceccb2af5b0dc6b1fbaaf1b2e96477e001c43eee3046eed06128c4c81eb2bc917aa8ac30d07e66c9a9469518e3cabc264d6936e5d724a613bf9a44d60797b890cc5ce0d04629e5faa1dd53e7a125a14a26df3cdd9878d9c67e7e18a4655a188885363ddabd73a17659d191e51fafb6d4171ff6c4b651168ce167ada01":"5feba370a58c16f34e931b65c042e6bfe794309cf30105d2fdac4d9fb3e14303":"429e6ba20b02cd69a29b4a97a6ea564e5b8874ada195a49c3a5293c9bc8d19e0a3a3c4ac8547bfdc7a209bf3a6037e5b0bb7aa291d5940d235c787a2af79a9cd7f83084ba7df85c036ad8ea23c4fdbf91d285c7caa6497af388017bd581ff308d9b56799029e21400c0c99d103a2caec195e40c90d244dac897bd418ae016d25f71e989af516d5e2491e1e4bc25914ec3ad0a9f85968a6777fbebdc73b1ac6814496d9421d2b7cdf17d53f00624010ed6618f1258da194f77c28286225d1b16da3fab76c9b70db1f7dbcbacf4e60b6b91a1f475007ee4d2c5e37fc31e89a0fa808f89e8a4e546bc90e696f454721be71c0731f99ee368afc6998761af9dd9d6d":"7ba86d55b8b5a465f661944832862baf5f565ff0d9195986c809956db2872da9":"77470f0d3923ff407e71a86f0336811bdd63e179891fd30e3452dac1e5175081":"4b969f77c70b5e6ff9350ca25e7d951acaaee907fa7b830a32dce4f91a89afa4" +Nist_Vector_175 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"4b7c0828b715ec2da1e092204f55ddd65d13f1cdd64c109478d3847487bc48a8cb0299222a7495efffa63ea158253faedcb5314881ab41b5e773337662cc2f50dbccc736974e31b3d080467589951d511032e4cba6647f94c679aa269fca6db92715a4da28ff9803a1dc61675fa5ac114e376fa4dadb37c1b09ed5c31bc5aee8":"1ba85c9c8f4f4ae97013bc9f7fab372e733f3445fd9a68f8e015c375df3b5515":"09a16e0a6003f45aaaa3c6311aa9866217d4a7c8cb5093514976f6a341260e5aba7cb00ab2adb7462a47a8cfee4fdcae5accda6d42a3144792a14631bbe85534c111d2ffcdbc15b6db9dbfc4bc71d300324fd310c465443cb2a6f2ae33701f39668b118c38ef562e8554fea661a3ef80455699c23430d28ba6dcf042fc920a677c2971b2df8c6729c5b3b1be6c5a047ac1bcc8cd8dc519ada221bd92ca6893c1cc1dc158f9d472f89a8e02649440dded0f723485558effe8cf9df121c969a2d1b76a37dcbffb17edf3121d4338d4ab68b154226c0072d8bd51f23e5659a2afe520dd5e91005a6fc1157f07973610c5577824bf1666ccf851d69efde347f0b996":"11d09ab8f3140f98dd4076d398a9aafb9c98656dd7185567a562cd108932eb77":"1b8b8d67b640afda26fbe67cfd4bea521375526ad58a22d4d97d7af134384f4a":"66d6c240992256eebe078265c3029a88c34095142134dfc31ff0a2d8bbd609b5" +Nist_Vector_176 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"baea89dcc102cd649135d63a5f52df437af7840d699a9daf131eaac381348d45b4e60477fea88803fca31b54829c5806c703eb8fdf412306ff7a79b55aab9064bc37cb26bffaa671debb74c228ba2d2a06da362f613b78e5b1f0a0b5c5febf6bc326b021bd7fc70471b25e153ea51de1010b87110e01497a7f1ac39cf4d424c3":"2c0a2b700ea43f5fd589e665817339b60f837ca0b7dbab50d2ca7e4c362a14e6":"cbd465ce9c3d0a137ee3d582a5172183b8a63cfe414070b247da367456203f986e6786ffb83ad764aba309c2ef7442ce38735f492c0ce6d92eaf9ae6b1cc873ab6ff58317cd166a510c3ffd8d4e6008825b58cae217fa35c94c9bbd12a4d638c20116398b21b5929dca1d49a7b748970e45de0d432fc912f76199137f1bb0c0d2c95bdcba0d303ecdbf489849be8e630ffff0603948c87a7e58131655c9f407708e8a9d675e28e9b57729f0346c0287f43ed67f9c0c0ce1542984851cc3b521afa5b9b8fa53680bdb2d73c2b6b090ef085a7e7c6f76a2e501064c852591df60439a96dd8d663b564c9e5c253ee8d8ee58ab27d8332113bdd51d8b41ac73c143a":"05c7a20e6e4ddb833c4e30a564436fd66716f349af551e9943bac61572e04107":"7689b5249f1943e685095106d3f68359cdb76be5d9a50ebfdf36e731575f8bda":"049da42de51e617cdcdef17cdf6059345b8e181bac64c47123d47b5efe105ebb" +Nist_Vector_177 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"b1303768be174d83578407dde1ab91cf021124a34c4a35eafa4512707a3660d1f884fa6c3d7df299598018dca22f273f602bab371592b11f4574885741ab3fe2af5b71237d0057ae59f37b61dfd1ad5ea27cf8f05f5b69f2936ec79d104f4a46c902fb6790dfdc75b9768cc7dfbae011c795e646f9a234728707fb112c461007":"247fccb44c2c0cb1f1e58d1033eabd203d8d874d0bf18ba70f04b75bd6495bad":"5602dd579fbe37f187d49d76fd5936fcdef2369f7af29da43c6456a6ac8317b39e4cd679143a4d97751b80ce1cb45186da7bee991e25eb9a1aed1490fd74f6ab507940821a1adfbc30e19a933cc4d21769ccdfc57c96f0d21944f8a0f131626ed013b3e5c01313a1756b67b7d2a21edac486cbc3cd1d2b6fcf20c82dd70b4f72929c1499ad796de894db8af103d9b91c25737073d9df62e6b624b90fb352db781c7f2ff8d3a20a7063fb51272395cc7d35ef79c27b7634e39f74eb152975fdf3b903c23990eede8aa58df9a29954333a3f525d5baafd379dd57fe396a51876f25d9e8265cf6971edc6278ce996bdee206883448af184fae23af2a69572b20090":"0b94ed40c05a4ef445309afb5583cba8d411ff4092452c0a064dbbe6e3ccd1a5":"1800b6bd5c94a031d977b9d017541790a9fe7e414c90fa4d3803d56ef16a6479":"07ece1b64711c9b3eca489e75f2e63438e097498e2890dd0273729a55df0d2df" +Nist_Vector_178 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"25ca3dc8e6ea4ebb936fa01b1ccc08bb1de923be6292421ff9f773af9cc7393510df2fcb6ec188b27c2688c72fdc2ff6c90f0ab0ed59c9c3a6503f53e32778b954eae582c95803c511ff3918adda02e68e2c3e73f8a6ad607a89d8eba0059eb87f4d9b0081f296961ec6ea78853aa53d24a470a74acf16a2f86748a8da34fb90":"32b6f7ce3ce99770b888c1ef23a86377f3e00adf5dab2e380ef8c4298d20a1ee":"bf2e140f8b8d99d2df1052e981fa0ac533c0d4ea9f266f9267cde7ba03cf10015da1cc13612dcfc92030b7c7d1c057e28a6fb45748eeb9c4bd2e6e79b217f4b68ef03f9659c8e84a20ee920d29711381ce39fe0afc9a7fe2fbdfce63249651230f3e72eed579f0d3659c2bffc70fb5d8be889a34bb67f1a904c318568394b946fd40383782cb5e4809d0c6019d20afad09f29fbbc994d28f4e41daf4666298f351898d8def404712c409745a88962e4a618c234976645559c90c54fe764eea46fa03543e4c4f25c8d2c3c1979f952458177dc6963e3f346a7fddbe0cdf23ddc7d2fa8a3455cd5b546e47169912ce7f333ac6f01e64aec596080b5d3e0f25adb9":"73418db52c6594dd0956d9e3616a205de8204220648addd4bfd3a9fee412462a":"7b1dfcf39b624d64db08a3974c8e14173105010f2bd5135e926f2884e30b46fa":"697eeab669677469f62cca46d3e68c849f447881e2c9f74294f4e8ada4426c7d" +Nist_Vector_179 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"d58a8f5ab44f9df9ed936a1318657c324fb1399c251054986d19214c15ce951f87ccb3510aed9085411d9c5a6740df5160f3e57ea8c942d33547317c7a387c60c7ac2f0e14171f0b7719aba76ac418d157a4e3bec6b799b5da10bd3ecddae0857a29670c99d37810349b82b7bb37c0937b0dd2734da08b8b1cb7beecd43cb615":"23a1290f8acbadc352a282015713d6cf5a88e8901cb9588a57151772619f5ae6":"baa13652642d950d8bcec16c624a07999fb557fb40a266297c15659755fd615cc7e2125d4e8c8af8c43335539005e9e2f2d40428e7c8cc055ff3f6fe3b3df604ac128d995cfb9c867e2a9607aa3b77cf0f691738b784d4be2fea4739fda1f0674260f21f666acef5bd56a7800bbe950792ba05eee42e80a2578d2c50ec28d44afb6b687652bb9452408fcaf257c4b5cd564ddc4e63ce9ca13d4c7473f51b01ac8e4c3f799afc908eaeaccad062b0f97d958a3008cae22062bb166c7300df0b4386baecd599fa8b083fba6e7e4e5ba119860268517d79ebdcbe02437bf4eb5d91a843725db0eda66eedd46d66b781aced0dcc23154e4b8a8f0453b2f466033bd9":"25f8923843d757ee4b7571b42de58925b0c2678ec89df07248b4cf34d83db926":"1876b20926d8ede78d28174eeb4cb0c1af8ee206fc8db4a8cdebb5dbfb0c15cf":"231af07aeba99ffd00659394ab6ed19a5e9f9e60e2197f65fc88c815beae7fe0" +Nist_Vector_180 [mod = L=2048, N=256, SHA-224] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9":"8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb":"778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848":"aa134e9db73982e7a37a1034aab82b50d5e58e034a5637081dc880a6e265ebc7b353df210304ba00771c5bab445dc6c24999fe8eafdefabcdd46f7a91f30721a6896333c3f301e197f961944f545e4fe0730cd967790504c49b0ab5b890809be5c7c1c3f8a2e52d92a2c199b981b648fdd528e768e6ab392579b54c72c41617d":"02ef078e61df318237c9a217b5ddbda12ab9ffde68a201971782b61b73214cae":"691dfea144e51b9e0ff7536557b58ace8716263a70554e2f4676d172332aedaa67736d72667d328170aca070e1bb89868bf4cc98962d87eb0599f10828c6ea24cffede8ed7b39abba666bd6d0d35024ade6aaa06fe6ae45dc4b3a91c219d472db0efed469d69cb5f11d40158ea81672b1ae116ff2c3016f245254e984a59945e4e3b3d37ad12058d84082955c768643e7d80c055c1703a883f2abb075a24c2e93056697340931c25894d1d2ffac4b1022012c15cb707fb359683ad0408b668779e9d9ba21989baa6a6b0b256a34efb4751bcaf4285b15635d409fda993c0438acddc9da006c390360304ab12da76b444d64e11ccf05d963ffb7f389bee831dc7":"013e35ddd416e092335f3bb24a5e826e3e06cb90daad599a42cb5ae8da830b24":"041d229349cec75fb2bd8c35c249f9196a18962ca75ebdb42dca61d21cb0e910":"77bb7975a544c51bf249dee2359523072863934497d1a479d6e4b245d456eb2a" +Nist_Vector_181 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"4e3a28bcf90d1d2e75f075d9fbe55b36c5529b17bc3a9ccaba6935c9e20548255b3dfae0f91db030c12f2c344b3a29c4151c5b209f5e319fdf1c23b190f64f1fe5b330cb7c8fa952f9d90f13aff1cb11d63181da9efc6f7e15bfed4862d1a62c7dcf3ba8bf1ff304b102b1ec3f1497dddf09712cf323f5610a9d10c3d9132659":"446969025446247f84fdea74d02d7dd13672b2deb7c085be11111441955a377b":"5a55dceddd1134ee5f11ed85deb4d634a3643f5f36dc3a70689256469a0b651ad22880f14ab85719434f9c0e407e60ea420e2a0cd29422c4899c416359dbb1e592456f2b3cce233259c117542fd05f31ea25b015d9121c890b90e0bad033be1368d229985aac7226d1c8c2eab325ef3b2cd59d3b9f7de7dbc94af1a9339eb430ca36c26c46ecfa6c5481711496f624e188ad7540ef5df26f8efacb820bd17a1f618acb50c9bc197d4cb7ccac45d824a3bf795c234b556b06aeb929173453252084003f69fe98045fe74002ba658f93475622f76791d9b2623d1b5fff2cc16844746efd2d30a6a8134bfc4c8cc80a46107901fb973c28fc553130f3286c1489da":"117a529e3fdfc79843a5a4c07539036b865214e014b4928c2a31f47bf62a4fdb":"633055e055f237c38999d81c397848c38cce80a55b649d9e7905c298e2a51447":"2bbf68317660ec1e4b154915027b0bc00ee19cfc0bf75d01930504f2ce10a8b0" +Nist_Vector_182 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"a733b3f588d5ac9b9d4fe2f804df8c256403a9f8eef6f191fc48e1267fb5b4d546ba11e77b667844e489bf0d5f72990aeb061d01ccd7949a23def74a803b7d92d51abfadeb4885ffd8ffd58ab87548a15c087a39b8993b2fa64c9d31a594eeb7512da16955834336a234435c5a9d0dd9b15a94e116154dea63fdc8dd7a512181":"853f75ac81b3a842c999448562c584d1cd0277896ec2f93c05c337eed414367a":"356ed47537fbf02cb30a8cee0537f300dff1d0c467399ce70b87a8758d5ec9dd256246fccaeb9dfe109f2a984f2ddaa87aad54ce0d31f907e504521baf4207d7073b0a4a9fc67d8ddda99f87aed6e0367cec27f9c608af743bf1ee6e11d55a182d43b024ace534029b866f6422828bb81a39aae9601ee81c7f81dd358e69f4e2edfa4654d8a65bc64311dc86aac4abc1fc7a3f65159661a0d8e288eb8d665cb0adf5ac3d6ba8e9453facf7542393ae24fd50451d3828086558f7ec528e284935a53f67a1aa8e25d8ad5c4ad55d83aef883a4d9eeb6297e6a53f65049ba9e2c6b7953a760bc1dc46f78ceaaa2c02f5375dd82e708744aa40b15799eb81d7e5b1a":"d41b335753e1ff3f828f57b797ff5b2db5cd79f6a1abeaa137a2a830e24ed4b5":"bcd490568c0a89ba311bef88ea4f4b03d273e793722722327095a378dd6f3522":"74498fc43091fcdd2d1ef0775f8286945a01cd72b805256b0451f9cbd943cf82" +Nist_Vector_183 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"ac30fb155104954b9d7139de9346d54ca05178954053fd361c9719cea530d2d2e1737fc46b0ee27357cecbd47e0fd47ada0d5236a9d77dd61a1b0db52e628b14588fdba8774882866b04b49cf5205db49445a8a202a5fc3fcc36efe0bd0c1e51eb08616c4a7afe120077ea08caf167e90446862298011ad9a1f11cefb5f74335":"d692d2c653bfcab2e7492ec56e512724c912227d793a59882800d37ad260bfd9":"84741bef3d9f9dab0e3fae7839d39c1a1966ab82798d71aa46b7def465e39ea5e7adaeed2dfc92c9bea72d65268b8df955f9b7e7b6923d2bf00e7e43f83a0e54ca944275dc39c0fb0c8a00ccd0b29b790d9d8f3496054390410b4ae5c6eaf2e21bdb52421179970fa13e0948280a06a576cdffae6fdb239ebd486bf4699270e2bc0879be25a6a0c2f7280ea33eeb32c5d2ea6093381fc4c83c8f9a591b0b0e72fcc149c685b01381a74af4ccb902c0050e05baf732bacd1606533e2acc6308c777201eecdcdcbe935149c4e572a15a205d2b80e75ef2473160f85e642d28370c0f19464125c687c969665b13b095aa87ba476802d72c354ebcbcd89f28ef001c":"39335e9193222c7ae3caf8e5ad77b751e9847c37b9016d355ac7520407c91e87":"28c6bfcadb5f52324e39903bf7a04faefb89383f473daa432cab9178f2470d3c":"4e88f65ff776940bafbbfb35643bcdaeb43b25b45de2de3c011ff1449c8b8b32" +Nist_Vector_184 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"2225031fd26a6bb4fd9990347bc2c8ea4ba45bd75df68476f983dffb5531899f1317d95f7cbb493de45cd2f11904cd5c5d5a748b4aa127ca730f89a928ddcd250a6551c2f7cce109e64d3ab74afb2d4f4f7e3494eb7d557060a1f29ecb5b75f64848370902bd6ae2fbf6802b2f9c37f34836ad71dd2e2abf6a0a47df4fd5573d":"87bd74c5d70a292914d96b47dc5e9e97a6799c3b788014e7f106ce7ce7e17a95":"04964c093fdb852c97b165e179f7ef3b39350c2588e60a0177bc2e890ab08ffd73d8a5a6692cfebd0c912de2d50bf02139bf017ec715c2dd7be1aad9d0b96c47d6465d4eb0ea0247ff655959d94a3409e9f9262d877075f6f0c7783a8df3cc115c5287c69bdbf0ffe0ed3719e418ff99b5dcd5f0cfc1065e404a216e095086a6e2197a69c47774377203d99a234e7be61cc4a95a809f9b9dd0a550b712bce5d1cfdafda232d7c831ec52884701155a3df2b086be870af8e875557518b035c84957c1742b8c02b0d46b64a773012809bfa4c5407c3fbfed3b960816604cf42b2defb4feeabc172afbfcbc82836b44b927e0cd4ca63a1daeb3eeb30d1de608127b":"64f504110193cc4a3f400b6fcfd71d64a1e166c048829d23206da12a7dc1423a":"5568d810ba664a08b301266d08c69eacccec5aae870a6d579eda51a31b184655":"9e818868e06787fb9519b50546ee21d0546e16bb1b5920311ba44769dc69c7a6" +Nist_Vector_185 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"4b1f9335fdfe88c0866bb648c05857b79c2fda92a987b359282bbf0822db747a3940fee05aeb3cc081231e29b9d460ef30a55f0f88702a4ecdcb842beeb36a976136c9241f2eb5c2d93fe38a1580cd58fb93ed137a7d05ea22d5e87345633a0e393feea616eaf83684c3baca4fc5bf80a87dbec3a9787daccec479661af0b968":"afa080287898b0787f5d06d5826cc285ae5bee41768098750419a5c8863ae729":"57767c348ab0c61eab4f2e0894bb6223645a331c5be2490d764839fa4dac814e05e70925d720d0e0ab5faa3db6dc58ba573b4e0b7bc13e4c044b96259385fcd1eade0d7c5174498c70ba8fb8661ed524fa8171570fd52faac9915d947b51f6cf5b74e3edfa064a5161c7623ec6e80d29960b573fb98de9e710c56ee45aabc4022357f6c3712962ad19e43a4148957cc6b9c8f691877a59f43162d8f98f2472699ea510109305f8f98aa3f3f31e4302eb05e5f1a462d0f3bfdcd0c84e76bfdd14b7c90b982b8c0ec7c78cf3e6c216ed1d20b52a132f53c9747c7fbe39092d5ccfcc01a119c92faa3f13d4643e5db22ca1681d6536bc7b704bb09bf6c621c2ff06":"d23656910f6e8ea72cdb979cfd8c8f6676c47c6161c3aa14f2338392891d1afe":"7ac95d3e0936cde441e4a290711cc044e6e98e8a8de68298bf7fb90eef589eb2":"140e9de37ec5aeb3fb795b016f51ea3e92d6f198c5a0e5a5d236671c91042c94" +Nist_Vector_186 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"3b87109bf21571fcfae92b859649bf37dd23d59f76d50cf26f4b2ebf7c5f4ae0b377bf3bf2c7e015a74efc808433047a71bf1ed4ba9025f4561dcb94bef2c2a2c94b3f55ed611c432f98a683abadc2c31d002eaca9b070f2b21319d072df75c62385d7d02897a00f863c2882b2897a331332bb9568b2fdfaccf50b3de4b42e8a":"668606f4a82b50876abd7f3dc0ed580a10344c1dd092c5bc1b26c427028cc5f3":"7c16a9644c18257911b826da10b5b10115ff77675bdc3c9f77097162fc059e86b04c1faeed3c66306c7e5fe2d5c63e8fa5fa2b82565ac6065445de5819a2e4a56925bdcce138654dfb490ac624a38ad65849be4ba74d14c829ef102248a18193933335eaf0c73b7bfe77d669f857ef3addb1f4ca424dbfdedb9e2de1fc0cc2d9777ee834a0ac7d0cac1b2a613890071490efe5cb2097ac830fbc27881f9fa51d3b0247c5e1b7f6be13c30dd31c2c59b7683ce60a0ebd6663de97870af2dd17d91431323a4686bf32e1e39732dae1300c57bd600be790593b2efa045bbfca956768157b4724ca0a1472fe6c8dcd82a38024766341d1f548ad8f36dc676676fbe3":"a3d781e5385d66989b38034171da11594b20f15733fd4701a63cf24bb58ec341":"1e219eefd616caac549a859d45186b5c528627573958fe55cf57fbbd1661f7b8":"b09545843dc0f6299b48f14311503605502868859e8c43867f80df3c2391c762" +Nist_Vector_187 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"042365b1256931a111facc6c40f618c428801b03e4f222a1e1b7763c3b02a6214e4c517beb587a4ea69fdbd4ea2d5d5f45afded96ddac87dc89955613aeff7644fc6a58bb859a85221318fbc5e175c6985b19a1d16ab6ad3ca8fa1903acca42bc6d9efbe88fd6f2a8650425be97bab9cb670b2e39f36d526278e0bcfcbffc3c6":"1c08570d1e1ac0857f649e4ba20de0e9aca97374acba6bae350104f1fce20be0":"815411ac6aa1b495c4bac802806a1a3592924fd9c0a3cca41e076db293d815c2f2b0a53e97cf657c8951b856cca1166ad433be5829b0b636ca9de49111ce5ceccededf36d795edefefee1d553250fbcd5bd05b4d99de55f147773ab3a0f754d090ca7b6ff75c160eefd1709a5df3cd8a0cae3e341f2275faaee3e3e31737e7e9c7e74845651f4f839c9d08da6bfd00f2c2b9c6ed9acb78d11175fa6ded7ab95dbb2bfef18feb149bc94f6de05a205221ba0406c96f63972aefec1beef030137011e6796af2e4ebaa100150d58caf408217acb1183a1a46e06368cff6fd744da7019e7ca109acf1244a763cc2b2186f49272ba3ae0425f2ebcd30e77e9f7c957a":"0bc8f6e0b01bcb55a4d134c967f3a9411737103d400a33a968f9036292d6e3bd":"e7145c70e0038ae7e7d901b48828b0b8bc960cc4fa29a52e11ffc9ab08eee726":"b9c54ef6cb3e1b0498952299d1465ed2c5d4e670cdfd2506462466c3b0fcc538" +Nist_Vector_188 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"98ffb2899f17c80a83e82ca6265e6f361733a6bbc63cdf8880dc756bc768b35b90db7390cfff745ec1b56f1655d8d9a29a6e8a63be0b1b2f9aa7436209a1fa061a7aec28622c472b3d0285a701655a496546e891a8ab29d9f40d2e748d0aa2babc06cfca641b300b7a219caa9e5bae3bf689f60567f922e7796fe47bb72ffb64":"79885ff112bdb326577abf52db67784768742b36e575f06b8d1e4f0d2d49a3a3":"14111dca30c0138761fd2f55972b9846041e5ca8b9bc6b2dc820f2a2f5100abaab337c7e0d1bc59de5ae586bbdcf4d4b14aa23be40095293123badbb11919b78cd6412548d9f9d15f614b6928713344148fd7d30985fd2c509b44d396c5672a082de4183fee03e45a90eef6a08b0d9d47132c82a2ccfef05e2ad0f340dcc06d9e2e979ecc43844c6054e4fa5fb8a73a1e3873f2145b0fd40f3ec7946f1f43de8b8057c1be5bf04630a12453d623c9b8d9f0e30c88c30434215d48f77348e6b047f16934ea09743dd3b009cebc49dbc3a3d3567c3321555ec96b2160caf7870970ac3cd8294477a0643ad52c23d9d987dbfff64aed1a883c30a49f14ff0620095":"13ab2945ab2a40067a93ed8c1a4b305182cb070022b79a56740238e55b07e8a2":"4551b096446db6761b708f35209edb91cc51ee4ef96a7495407ab4167a05c791":"cfe4c58bdbf61caf09a42adb1aa5d98b4c459c0112c57823bc15b5b990d92ff1" +Nist_Vector_189 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"5898cc0b422bb89f066dabbd30f59e9a35a392bdd7ad315ec8ad32b8f0f3d02864e70ea36e9076c395f0ba9de1ab6080df3cf4a1470e2b9990b8e7614bb8312b075c0b2a132d7e47ded9e4c0a1368455b9d1a67bc44af2f37428f48f7e089ab41d046378b6d48d9cb135eee4574072abea93bda7eb4f15a206cdaf3bbbebd318":"416634f9b7722188c2a5266cfd9baf1bdd508c0c068010fb228c099fca7cec11":"766d7e4f8bc3254d92cf6a64abd504d01cdcf6c239178b0aeb3f69c9bf202bff7566eca09f29cf5d6fa4736d57c08205500d648336409df06e7f2cf99178b20a7ec2b5124bcffc61adb66f6fafc51e32521dea2124e5781c383b116d06a6a6e89dec46b5e4ad69f5a1e8dd7ac5e160da336c11860b601e7e6d58895e6797db5aa92deb7b942f2edf58d43d3dac9209557a6aa07b228e73a80ff0e92e4ec4603d362e1cca7e928d9459c21405aa0f6548732c0fc501ce50f0896f0763f633c8c1a8531321e1a0f47134a0d2d8676f45f13ea576e64c7870028033a4261bdfcec948ebb1aa25b02134d0259d73024a01da0cad1ce67571e36963dc130496160ebf":"b057bf5a5ae4204f941ff5a01560cbc29033dc6a2e06ad168403cbc6512646df":"a237d2c3d23706caf004a2e94de29f04c748936b62ab5431fe73c72485814265":"b48b9ef9cbd8bdf799b70605f00550b81b309c157332153be9707a399fbdd67f" +Nist_Vector_190 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"0418e01236caed0f80241ce8c6307d026f5e25f4a922bbdb4aafb8d9db95a18175f9dcea9acb4d376f36ff7b7cb598e073de95ad2012eb9d11e15cb3941c6dd0dd69422e78512ebffb19cc8a403a9a7d1f1720ab0f2d25627580366093e21ac1537f93de90a94508f1d7a7a1db5a7b13c9fd00b82be044c3a35ec0451c309b82":"6ad92911dd4fce033d7a50875e4660be08c44957b874339c2a70d915cc03e27f":"4cf4cee4d5abc2c92db522928b6d7e436ea00884009497ed588e93281cf05b3747ca0048b917708279cd0277ce8560c22775d2aa0e7eed1bba77be45417fa7afd776b8e560679c493a520a0e626acdc83df021351669bdf9da19b12bef2926b525fa4c8e3d1f2083ea6bbb489880f594e67934d1f35581ad18e0db462a1ac944066c65dd743f35741c6cf588918d8336702329c62113e9486bfa49ca5425914526a965e3c1975824f4b39fa5fef89cf6f9ea512f7ffc9138e72dbd0f71b01a70975312eacab11118471115ee3fc810522936c9df35977509b196d867fa11f607b7ef9ab78cb748213a6763439ce5e7641b05359670612203a47d4de9c5388405":"5aed2d19239189cd0bc8cfa3c329748c0555d8eafd5e80ff931966680e3ea454":"83ee960e6f9026fe2454d859462ac334a13896e75179858ef40e2e9a065c536a":"7ce8699c6ccb184d4240b8709da11451328cf1a7e0cafe6e1c8ab53d7de67d9e" +Nist_Vector_191 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"92c949fe2342f91a387b67c1b12b1d04d0721203caed593c9c464e5fda09fdcc91d3321d2985eec08ab2026d1ec3fcfa838cb6af45290c08dc30b9c14c4445d783b6f48409a00490f4e308dbc87fd1b2f878385212e1f4c3e1cf81c56d71e73fd7a095b56b4abec15c57107420fbdfa44477078ccf4519f9f6044f0744052035":"b0d23aab4d95446f8c6c5d496d477dd9486f50b2827f7cd19728bc96f82840c7":"256d231ac2bae650d25999b2706d4cb63a89b1468e0df36d677535fa7a0ea890590d3290d4b50bdb399f33dc415e4469c97c6c0cee8205eec962d7153c4c85ab88f7cf80979d4a1ffd8c74e681c1d28da07732116c3210ee4b693309333686246d667074c7172035fd6091b2840b113970b45983d474f54b95d26394b7a43e81b449a2ee9423aa1c27f4592b516c12d5433e2ba724f5463b4169a2b0940e1bccd60ccab9b5a38248acb60582ab8bbc01c5e75f9ef7474273fb51aa6316e649f4f22452dc70bfd4c3da072c03ea82ee009d4272a84961c98e517ab947741d812116011dec0373ca8fbac5576c2069b067f8b005d60a36eca44f56019a64835d76":"17a199bd383a84e22029fb90d5abc9a8a7ccd3f0a33720ca80e3161971793526":"84cace71a80ed47494570fc84839f2e350191b74f0eefff2d7ab2c689db77bae":"9cac33594e1934b68f62aca05ca040f3c82110c10b7379878b7894b0919a0f2f" +Nist_Vector_192 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"df6a4eb7cad4ff9bdd8356d3568fcf0285c1a4e3c3109faa091b58a9bd907c629d54aa7a23a74870545a0942a2d23914f2f167d96573f06f35ea05ef704cac8014dd21b961d3dacf7b930bbd7e35550f721094c86333e03ed4dab7bc1b6416add9578d279edaee37504fd25ec0c5e8a37ac9ec19bfb1e3778ed6d9c6b6e35ec7":"679ef48b643be394677d17e837a0be6d4d8027a900b686aed7c4b12634fea76a":"2f4b0c01e4b15eb5ee7afa9824093330738be2f3f06c42b2b7c6968fa54b987c184e7fa89eff16da02b93ff61b9ce48eebe7eab0f7e203ad11c71e7b297d23f2d5a5998272c30c2e1724b5e963bfd6f83239f874d88ea089435b896dd2109b6a14b2d848f9ed7e92143c0649f97f4f2eb05b8c5a07e99e497dbc752d443eba93d7f3dcdc3240a2714ea0e3e7627f216e4701148dd21192f274f1ed5df05c60b1576d3a0b7f69a776b5010404acd5afafd3d70f57763f2b778d0c361e5f7f0bbe17aafaa5cd393329171d06ec032039a9ffb37c3ab8cd858ea788a7b9f501996baf959ca85c7dafe0cd3e30957640eff105894c43f866bcc422698d128dca0887":"3cf9da6f182bade870946d3ed3b078208ea8153c45515d64f589bca72b703ebf":"1dd2daeaf3e89fd644c6cc942311ea5056413d8a24087787675ceffd3d6c15e4":"3e12781396558560455c4e70f610522ab2b10fc25343296818ef7ffb0378fa47" +Nist_Vector_193 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"4f16681eaa5d97673a7cca02ee8a7374b75411e0b5704a947f04d1a5b14be0b506f31c2fa329e3ca516fa4f1626a9b5e080bda7f353f850365eac7c3d2596f502a5d70b1542276c12d4ea4a22b5325b9eb3e942e556769b796c4f524595f1cc6ce17f99f9dbf51331453228ead327b614f4438d35d61428429f78c8c9377aaaa":"e0e576432913bc75a2e0de3b33bf3094148298612a9dc56fedd47aa569af8ac8":"2e33604ed9e6c0f1ba403a8c3c3fe8e8f488591813aa3d2fcccdf88fe808f70adf173f0f143abdaad43b80769e30ffc5749e8ad35999953deff4f61f4ca07313609e23acae7b35f77934fdbbe1c380b2727b1c3899250af5b4399b658b7908676d64d11763785373b2169836611d72a957319936c84efd72b72f92bdd2dbe0000d8841ab6d8d0d666e79361abb23b6007348dbbe7a94936dc6b026f3b7100081f547b994e0e0778cb761ebd43a29d8764c7f962a747ecc92e4a2a628f52d8abf43f6e3278a0d32ea67c2d79d04c83387ddc709365c0a0bacc83d75c946e283e0739233581441aeddb0d7d76503d621405d27ef66fa8b5379d178617d4bb5ad59":"53cb2d046b391193efb14a4dfafa296c2ec92293c7b3c7d19a20e68c4a1141d9":"e2ff3fc441db4540194a7f5da1ead849c2c3c48dccf8b2c1b3b359a7b16e16ab":"52fbdcd5c62a999aab46147fef9e18cbfc7daf680a7ddb892edfa44d285e2158" +Nist_Vector_194 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"09e48a36523b5289ec41859faa141e2a29b3e88ab2d6351e20de001e6424b85337675f0ce26be224fa4f8df0ef9710ea285635b27b297d688e338b5461820b57be4bee21645b04957ca2f6cd7af9a6a52b3c97c5b9db1c2f7ea817cd6d3c8522d4e6a9de869aef26ec0dbdd269c79b38806927bd3a5100735e6f9f655ca94dae":"7891b05e24823f283126d7d175a4e8c8124b3776f4f296d0ffc4b5e21bb64d70":"7e38cb668d647ee15f71ac5d2b55c11fd4731e1a6c031dd7594d614f2f1ed25623fffdc5956f5256e635c914205a2937a6074cfe1f3e443bbeb323a23b0f0fbccf8c1770ad18ba97d0acbea1e846e12cf12c370625b1555d710905eee943539f2241b8fb490c9d6b44f36139226b4c1f00e95ffe595014f61bf579836a14212c07231a5e9e87de4a9aaf0f46f34c9229f2eabb71d40de26a1cbe10db0645cec37d48575a1154bb5acc947becb2a74b07e2a0e45b903be37502f91b07fb4ecd7f21fb130c6d639ef0fd8444fa12de859abe95548801f6a3c40e7a65fd1518221a274d7b65ed4175f66c04d919c86d2ae8c374b14709e9c8a39e1d0c4e9935540b":"dc24b379ee2d26d5db792839795ad0d4b9622c0e3fd518df541a5f6e9cefba0f":"e550dc65af275e47be480fd647366e2b055c79ea33ded4f5a9557121e082af26":"e26b1a5f27cc6c87863e31ef7f1e61bea476fc5d7c25fdf22fe740f23aa9a752" +Nist_Vector_195 [mod = L=2048, N=256, SHA-256] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f":"e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb":"5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561":"8837bbceef577511f2d0c08f790d5d2e8562d93df3d82dd4c2827cd9a9115308114a18c452db2785561081eb523685ae2b3c8b090e0d44dd40d2fc0cdfc88d6f9063a7707df609edf0a8c55034815ea9f1d8b0bcbc92fba513ba81ee646bf98ad4eb22be26a4582b1be2899c91eebcbc9fba5825e021e99be0c9d28642d13fa4":"116d1836a131310644aaaee6ac39b3643cd50026a6b486167cb4daac242a4e7a":"77d7a40a7bab3f5778f85d4fc48b3e28ce28b2df9eb87cc9cf394ef28e8064f39a9690103980a66da219cb5022c101f22011a8157a7568c5ff2e978ba2201367d17c22a867865d00c2a437385627bd088bfcf7219251bf6ae158269f4ef35da7095a53c24f37d61bcfb7c043feb6e93832343f9e90ee7104c80486ecd087be1b67f18cdaaa375e039cb7ad603cb0cd855623e9fb48e4eede14ea3c76a0364aac006650d3b5cd9b474b56f8584be58a721bf34dd0808d334cd8632e808536791fcbea961f7163dad28353c115eb3e856737dbbee03436721637a47754a8a1fe0fedf547b358a73d05b769a95bde3440007c0773a3c7c8dc9714e11c3a10ee01d7":"4a6febb624c8ebd411cfb30c6db055dec3d0d17456dc0c54bd1b43531d4f2649":"7b6b3eaef6cd5fe6daede86d63943478c771582483be0b926ee3022d22ef912e":"39d928b59a690450d13359a29efe20cb98bfd3fc9726f80e5148f059663ffd08" +Nist_Vector_196 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"8c78cffdcf25d8230b835b30512684c9b252115870b603d1b4ba2eb5d35b33f26d96b684126ec34fff67dfe5c8c856acfe3a9ff45ae11d415f30449bcdc3bf9a9fb5a7e48afeaba6d0b0fc9bce0197eb2bf7a840249d4e550c5a25dc1c71370e67933edad2362fae6fad1efba5c08dc1931ca2841b44b78c0c63a1665ffac860":"459eb1588e9f7dd4f286677a7415cb25a1b46e7a7cfadc8a45100383e20da69d":"5ca7151bca0e457bbc46f59f71d81ab16688dc0eb7e4d17b166c3326c5b12c5bdebb3613224d1a754023c50b83cb5ecc139096cef28933b3b12ca31038e4089383597c59cc27b902be5da62cae7da5f4af90e9410ed1604082e2e38e25eb0b78dfac0aeb2ad3b19dc23539d2bcd755db1cc6c9805a7dd109e1c98667a5b9d52b21c2772121b8d0d2b246e5fd3da80728e85bbf0d7067d1c6baa64394a29e7fcbf80842bd4ab02b35d83f59805a104e0bd69d0079a065f59e3e6f21573a00da990b72ea537fa98caaa0a58800a7e7a0623e263d4fca65ebb8eded46efdfe7db92c9ebd38062d8f12534f015b186186ee2361d62c24e4f22b3e95da0f9062ce04d":"2368037a1c7647c683d7e301ac79b7feebc736effe3ab1644b68308b4b28620d":"4fd8f25c059030027381d4167c3174b6be0088c15f0a573d7ebd05960f5a1eb2":"5f56869cee7bf64fec5d5d6ea15bb1fa1169003a87eccc1621b90a1b892226f2" +Nist_Vector_197 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"02bb64d2d5032f54f1ac9e9ee164db83af0cb036d88d41e9b2118cfc39d1b4b4dc2c497549c7982ccacf665d1b0011268246c7c17f562ecba25e265489873e0dd9268e9b06880ba74e74b56f50c7324d29373853e3a0f3ff787eba4e5e7f9437f8ec8a5e868324e9c17fb3d0e12de2d31d438c5bf38b27167d43ae4311b11062":"521f08c10774077ac15bc85f2f6a03d84207b4ed7bffecc35d730cdd1126877f":"11f3a716fbda7af35bdb62d128af6f21ec2ed4896aa81e8769c6eea9c21c81aef23ae0f525269dc405accef098377f652730968a33b50f0a4c7784345280651caa034df87342ca8973ad86ff7f0f8773a94f95dd2bfa802d268dbf3a2103b1276e06db2d734399f2ab7bdcca097616fc46ed2478e52cef049d19444586e7b75d6a56741da2270f54d2c739ec8db996c71f06a39af2383c611499be0fb34809b171254ef273516c33e17e14048ef2d21d600aa153bcf7377fba9405c6b2e5f2aaf0f2f3467d7461f62e814a2c461e8ac9db0df370e18ec6eed8212acaecf1e7241bcbcbca671060e50c29f966f1ea1e92af6903f81c7ab9ee09f60577bf30c186":"08b161571ed031152677136b54e87119133f7de56268aec07cba07667b98bcd8":"7a5d2016afe87883491bd6cd166edddf138c1c89961e4af6876be08b0e06ad74":"34efbda1849dedd0d1aa775dab2aa2b14c9ba0206592fbc34eb47b844646adc2" +Nist_Vector_198 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"4f1c0053984ab55a491f3618db1be2379174a4385974825fcbe584e2b6d0702abb8298dd9184eef1740b90a5eae850e9452b4e4ab219e187860f0fb4ad2be390ef2ba7d76cdedcaf10aeaf4f25e497b4da951375b687a8d67012d3f99c7b5ca82e9bd0630dffcd635ecd8209cddb872da5bf4736309783345a35376b4fce4b91":"6ba8f6638316dd804a24b7390f31023cd8b26e9325be90941b90d5fd3155115a":"10e6f50fd6dbb1ca16f2df5132a4a4eabc51da4a58fe619b2225d7adab0cea3afc2db90b158b6231c8b0774e0f0d9074517f336ca053ae115671aee3c1de0f85728cff99deebc07ffc9a63631989a9277e64c54d9c25a7e739ae92f706ee237b98b8700a9df0de12d2124e2cfd81d9ec7b0469ee3a718ab15305de099d9a2f8cecb79527d016447c8f6fe4905c3718ce5234d13bf4edd7169b9d0db9a6b0fc77b7d53bdd32b07dc15bc829620db085114581608ac9e0937752095951d289855d0bcc9d421b945cc4f37f80b0cb25f1ffee9c61e567f49d21f889ecbc3f4ed337bca666ba3ba684874c883fe228ac44952a8513e12d9f0c4ed43c9b60f35225b2":"2a4a4e014c94d8546c62f0db2fd488f5fac03073a11c3760376114ab3201930d":"006b759fb718c34f1a6e518f834053b9f1825dd3eb8d719465c7bcc830322f4b":"47fa59852c9ae5e181381e3457a33b25420011d6f911efa90f3eaced1dee1329" +Nist_Vector_199 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"42199186434d6c55bcef269bee685c4e1580e243027ed128ca99492033a52954bd1ca8ecc5043820725a3c0d71a181a05aabcb4ecda7180d86855e7b4dfa9a44c7af4c98fbf1f0624058804fd8eaae4990d4d7bb75f01741ce36cfc9c137254cab065a4617d0d0cd5f58ea56868a40f3e0baf7db5d2557f4b9775c1820dc1d41":"46d690ca6b9cc01e9a8c7bfdedc59a97eba52f097b8fdc19bc1f8c0ab5d4bfdb":"6364a35ae994f27703319c36d90793c8f26511846ba06038995b6556e4443aa61eb0f8efcc3d47f7c5f85276ea921da0784a67998253c992975f9e13847ccad099d9c1e5c94cfb195488e1293e23b74db00603e8bd6814c94690bf0cccc1c0e47f0c6609a48e144587ece178f72c8514a43590bc4c219da95cbe8966f4404fe9c288f23cd0f973e77ec84b4b0f163b50a3c556cd1d3951faebd982af44447e60d7834b93b6d9c3ff0961fccb908312a24376eedc508f806668d6617b77491a01d5d069d6ccd5f21b5eb3c3a3d4a0479593845c72f720157b188d2dfae4401c57a600b142b6bde2a69f1a0afba2f507a63cd6df056bb5b34fdfcee012d341b3f1":"638e5fd0885f4c9f7e5f4e6a103b2d2d9d1368c493f9822ef431f54e65a7a3be":"2551d4f855174f7b28a782b89697d48fbc314cfeb17ec4c9902a8e557cc6f6b9":"278b786f9e28eeccd00586b445e75f48cf2649f3f1b7bff72b0e767f3443dc58" +Nist_Vector_200 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"4fdd888756ac68f4c29cd5b1de42756794570ca8f18ff795f6f0fc856772b6a2189b5ed4a9b7547328075b56c28ddf50b84c27205cee57b29d0b387970e89a6a2236293bbc9e399013d1dd3bd5a10ab0d259f7fda704f71cbe3b8b8752806a0c84668d85e4d739cec628dff63371d24a4b14137382759ba400df0e2c25947d18":"49da89d1673704d1f24ac7dc799bf006aa7d606c590e5e37e38032ec51a70376":"5b619845ba969f1ca5963fcf04c03aa40e989222774e957a54191acf9ddc407a54a161e22a5ac50ca5d61e6601cc7995bf0db38ff0fa1f77b244fe98148c81f208dca29ffa30f1131c76dbbe4303425e9180b4a48f22c757ed8e388b61bdc6d55519523d00c31a5f8376640d4688e60dcc172deece73de28437e900cb19a5311a0c9ca9af6cc6eeb6844e9b8359e3ef1cbe03784107d2d0aebec7c1d70d9385a4d2b8033851f5d5b7aa18ef570aa037fcbd3e30f2fc2013ffbfa0787be6d59ffa1616eed5e121ee4dbee04a9ede004956075465a7688701e04ec9b2153f52cafbff7ff9226e69397c7083c3aa536d7109ee430a65448b10c1818c70510a339c1":"14dca45937cfdbca5c799f2ca50de2a44d8051e6d80af242c9f4d614419e6e07":"4b90993d707f3371d0a0cc87255e99a8fba18c3b58ddddc1067cd394172366cc":"4b2612d506fb85e5aff9fcd56c09bd12bf60f78ab7dfd021a742ff85dc507ae2" +Nist_Vector_201 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"8507db5f1df9d22f447c20e4320f90d9b30722197196d1a2418d06dca41b3305f6fbe52ab58cc0b60ef1a1d257fc2fb2062fe6c5f2a25f0293ca39d0c083cfd5e4bdadf2169ad4ed178c88ecb5554ffa2b53aa4398115cde627d30144ace9325b2d79d7dce951509d734afb0ff6d9265b902672eb5884e9d8acff0ea22c76938":"82ab2908e3d2335e07c1002764b07b1ca46d039a95b59b450b16d37ed4838872":"438831cb0eb09aab24275454354ce42b9a2eedb31f421219def74687e6f9c92f0b1982355cadb26e095b7ca25de530aaba63e64fc23acc3d1d1f1b70cb726156ca0a799b59094bcc3b8998a4ae7744d215d63b887082f4c84128e74b9b9999c60cad3bc6bb6f727284b4311a929bbd964c9a7074e86062224dcedb58b9b598546ac95b3b434ea114ab0d678541d6caec0c56009bc347a425f167cd32a34eecb7192424d57b0e54b4a9e82f425138703ce89b189039e92a770b51497f8f10eae9c3459ed87e5101f5ab1b6271485fdb2dd3dbc4217fcf67c7e92d0096dc7da9727f5a434b7545284cd8a283070b5a49d711dffa85904311e0345a99147a168ea0":"1ea475584982b639ada8c84e51ef72738390ed6fa44395f11428dc5fd794a81e":"1d2781f5f9d08ab2feb1683942c2c29a66318839a7dfef9aee9cd7a89efe2ab0":"3adc7be968502ead10feec191e212ea0e07d449006e7f22ddf869a9fae711834" +Nist_Vector_202 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"c7844960966584c8e3a59dc37df37b7eb3ad333148a32b86c1ec18072f3b316c59cdef98ba4dc46f532a4280200c225fac6cd1adf0a45382c2d88054e447740454976e5272330c7487eb42a095f7314139938c7419193b1c128054c1bbf10d0634e22c6e02d8e12279cac0bfa01d3058e0f8d5547ba0f71529c27e0084d4bde7":"0c76bd647c6fafe7da1029b9bf36a9f042195691a26f36bbe0eca3d4b1e6cbb4":"2de9d27f1a030199ffbba770e08aeb1ff3708edf8ebb3a8e664e3bd1511db126ed87bc44c2d2af40b9d512c50a4d6c10b23e3ca61819f5841cbf5d0bd6c88d46f1ac6474ec20b9100b328cc155879166f46b6d71140b0cfb2b0725b64a38d70a91ca8f0e3baeec6125262c52a95d5ca5d5ff6f4482b1825006cd469f9e7f31769a73eddb5f7017f18bc747ae4fce450c4274f4abb960577d13b6a77dd99e67d11edb413e428e50726f7052e53565fa1d6fde91859573c9289289ffef0598802808ecc5501cb300e06405ed0febc3df23f40a1f6532410f7d9049b920216f7d5c7a728c8dd63a8d0060fb53b3543d62a636661750fd43775e80b509004351475f":"71e12996d8aaa7cb1e730713fa441098347ca95eb39362c5a78ee6e847469c7c":"09e654b17ab775959628e7cad0e27053ee495bcc29cc2a5e3b029660a77b1330":"261ad41d6bce6d04d891a43c16ec2a8114e51f0e47b48b1dd1f3d626150338fb" +Nist_Vector_203 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"6f3f74388cc90b29c109ecbda08c79349dffdeb90722974d79d640620949448f66ae673eaf4d4af8c43da673a45ed152ea66fc97166baa7ce8beb666bd57ca43da6801c0ee5a5a9b50c5047935d7a8552c381d93eaf03cbbbb88ed0d3b5a2521b67612a4405120ef0205e89aeb48d577bcda3ad20e0a7cd07f8c9b215c845dd8":"34c0d0de98c85be291b68a5b8c7fb3536b6f7447e8565ead9b002417f56f4616":"080ca412bd197c5aafa2c6df5933a6210fa54089826828d5496b453609a56b7d55d232fbe650dd9f62c05c050c026a8717a78b5db01614a19301c610d2b9964a7e3357c722a4c553273bf27f871b4b9241678c334e20827a5f511fe9319a075d12753ac0960df60870a08a12f09b9d3593781781a0cd75e9d81cc6b9b0d506d100fe972165b68297e6070db2d8b6ea32176d1562084f6a06e08e2929155b255d33853de6549e79f8b56049a1d02f29166d5f91cfbde5aaf6bcae56f5d2d90a9b4e8f6f450080cae8256c6619e9155523c2b2052255a8f6d9f53d8a897be5b0476002410bf798256f62bb1a81827c2c3fc4ecf9abfd77e74174787370864f05f9":"8086cc691e7e793a5c2a81bd3d5a1ff5ae261d9336b33f103d983a817f7eaf7b":"43993b68e847f6ba61d5ad4dc8f5ad70dabc317a7b6811c23e7f215f95415ed5":"1ea727afdb907d1d5b2337c1ecea46c71eb0fc8363af23865a345202a762a7c5" +Nist_Vector_204 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"74a433c2d313f66232324df875b82563805d7ed682b266eaf962375e422b3abbfe3dce7f3c1960a1e4100f333e168d021968b48397e8cce9005e951fdcb096a9abea342cb5b08bab79ef0c431dd3a43de7d5bd6b86bea8872ba038b43a236a7356b03f89b09004ba2def663e6d299763b6cafcb6b150a57f82b890ff6d56f832":"5c1a80e926de194995195c4cee9a2e874c7f6af0fa8a4b2df5432f9cfc86b643":"444fafab58db4d6f5283c3443d6478b5b78daa631bd4c3d9a28ed17281da4c1c2ef4d5ed576d66bfe5314e11fe68abffe4df406f6033edb84f36a38a3ce614601bc25841f9419afb2867d991e87b44c4b744e39b64079d9aad4b585d79c8e21c8f90990540fec8ae981f7483dc5523d216088a55cf2380ea8eb5246781290559ea1b208ad4d0f5871cb4d13cdca6ef34fdf2de63e209aa320cdf14185b8f5f60ccf93f398c1a6cf8b3ce3d98daf05e4cf90c39801ce35f01ec76a9f6035ce1b5ba107a5f66cf253b71fba3833e9969c314eb6d500005749231f799b0c79a555a10cdd69f8eec4c117d7c8b4ec6f60a1ee557b70c0dea380af53b92fdde8823ca":"13dcb7c12aeb75a417a93a22ce94618716996c3350909cfbff6d38b603d377f6":"3bda5b0c9e3da22f0b3e29356a2f7ddace6e9b24a063eb3f5a7d755f2eeaffb5":"4cbb815320314a06538d2a6740e6bf9d022eac9aa25c7508f659f0f7c1f59c45" +Nist_Vector_205 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"f4eadfea117fd3d670cea28aa9d2602c951ed843e2e8cb2864074c8c9bccb0606ced83ae2980598cc3e1b047fca8659127406d8f59f5b7bbfe8ece6d3e42f87f4e42ebe92adaa1e6e92ced3dcacc2e0b2c98eade7c9c99da887e74db5a59132c1d7df7cde866cb2f3ca750852ba53e265e62bf7a93fd693e4a13751e186e9d6b":"6abf7cc887544bf8d3256fb210848eb46281526b1e8cdf6c9204c4c46a747435":"104f44fd7669607644ec55e6ca4096c9a279472752a1753dbb9f2a6941b8122274c87d16f63d75dda9ebcfd6584b0cb374fd17581353d2a246ec0b378de60e9613131683c0568bb54d74457ad73de859a4f02445344d13ee928f3cda5134202a9388e64cf05f8190049df4e777709838d0c9d3bcb37eecdc38c1a5d2b471c4b910cfaa9a9ba81f69b4b45c40344029958fa40000e56881bc6a14864330d5b351c161208676cb852bf47970268d37d4bfe97b3b26ef5b785f50ebc8c47949dc9bd0b2e673fb040e26789f3f5cdbce8e4b78389992bb83eeb2b063e9e1db06a9ede933faef7e635effe5e1b1e21153dc6934197efa1fd68f18a40ed569746c8374":"0711c4621a8bcd40ff3e8b95728ce67a000e1fa33741246d420b046bdec48657":"36c086070368265f736e7bbad54aaf2482d26161f8057a97a4b8cd2b4ddd7855":"31d99d736ea67014fe59cb2212c47eb920f2af44e32b65db15af83cbe8e6aa70" +Nist_Vector_206 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"cbc37afc75177a8386dce2c40c33b8f5dedc23113b4512cb96790f2dd74066103e0c45a9c6176ff96b7d719162003cee10fad6ccc198550a389275d21e708b6961523272ecd5efab5680ed741c2de025b02bbdc56315a442e437c43e3b378e6d62ea8878fd9789858a8c68a504bff49516e762a22ae513a2dceba9253b36f553":"7c6ee86f45ddf8b87f8884f59aad9e320b73b246a80b26a645188a40a9bca62d":"356cc7370c840fa26b0d106c47a626e028a0c967c093810b520639bdda0d339b7fc29adc0d9036b9710358ef9f8c6c05252b278281b2afe7953886429e85d228fb5474acfd65213151e9da0aef86a66f9f9c59fa88fd48cc3addc83d7adf4afb1665049ed094020219c01958b697f22e652152e53bf4e8f68f476a58181ddd3f64344e9b87a08c5d0de49e7b3c2995840c200084e90a76d2c05f8b5c68e77192d0676b4219d4579cb2de0f2a93a916b4f9cfe0d8113dc4bbd97ed12d8ce0447fcf9df12e922c6383ca69c9de9ad320f9c5331adb6eb1d223079196a2939cc0a7259c512c478c943fe05736710e273e4b5867174de72e703b5e7bf7afdbc06427":"685a19da2ee3dd94fe9726a32e712fac05eeffe11e3dd9f60e6f90af7c13e23a":"5645ef65e8e9236d874d459e7a5809923c05d64b22757bfc5b5621079e84819c":"65f4c8febaf3e9d46581b17685c4f2ec9b956421d034a2c1aaabee94b787a4f1" +Nist_Vector_207 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"8eb3685c3f406c5615e88accf4c0c7d2071b6c7bde5244994f73dc04f3cc0ab7e2b6664a1994e6eec52b62790a04328e436a2b4af3cbe3ba6e4c8f363a39b2529ef554c0c627f9f6b255928a39a465e60ac50ccf01f32c7ba483640344b6a8f583c90876b84d19554b0a4baabc2c240e296b12c819410cacffe7a7464419bee0":"7e5e3d7255a629c39f88b6046fe0039159e44c2d2309b112ab05c61561d9e44a":"94ba486977f5982f2ae75e986b7e194461cc3d65cdbf26f936805d12d7f850aad7580206d7dc544cd12ca1891c9dc406c949e52b9febfa88836f1566d521a110bb545e07ba28caf07e1bbfa3b176cc917cc4bb45dae7f873b72dfa9000e9ab6083e705c0167d853dda114c429fd812a05961fc2e78ba9e68ccdb9dc67b116f10532034d9f0f7d39901dc643127c4309058f8ebf43b28a5ce534e29d6227c4ec27ccf777b0008df5ce8b8a19b5771725cb0f9f2a62bb41f0106c390803a307c60acbed6c2e1e0db5036e0e79ddcc3f718b29ca5aa022f2f0bbe815f9c0eb504fc9ff8d18a2da999023af8105cddfc6794dfdcc41333bccd446ad7b82a0a7bfe38":"3966daabf7854949475ff47f3932393a73f21e275b3baad861a92a3ab322e376":"27b4e3c3a45efa6131c3d005ca924dff11fdccf409c2a6993fcb505477b6e400":"68a085bd130c4ec08aa9673c495ba5afd46c9ddad2052ba7ab396329d900d86c" +Nist_Vector_208 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"f2b02ac627b3f66baf4ebaa52b899adfd7071af53e78923182d8b4d5f3a9474251308b4dbd15fb6b657be65028a189353912d7c16d6d4989985c15cedc4343f0ceb680617bc7278511f9068abd613718a862513ee514fdf80cd25b6f84c48851e6a7850feaea57ea20deb1123ca4206bde8a93ff999ef789583e2c850d9e0635":"7e52070b03aba0af4cad1cba0a733618e3adb7de873efba013878fa76331b5e1":"4e160d6970683f4d84eb88c55ba2da58d77f6374fc5127273d65e8ef96ccfff51df69b0e2fdf3e98f6d35e6a3dd9f7edd90bbae4c6581cd02ad01336c0086d4248eb1373480789f7d8333b831db3bae0bdb49789aab93cde1faf1ce88dcdc7a1a4f86143ce44f851ace459a5528c96195f4438ee7c1856ac61fd5035d839d62e48a1ab6bd23ad52f1f6ffed19826b6d7f6491cfb05003176f29079455443f0ab482150fac8e32a3902a4096775f342edee2daf4c4f338d455b4ea35d3975f72be85e98e87158486b4c3d6ec37a3703f63a3e19272ba5255089aacd30fa3979b458df616f57b7502b4291384562041f6188db503f3df7f5981da5705eb0f1d242":"57c141f543386db3bd6a97121f93b47e38891796f02565058ec6a5ce65f7a212":"6433bd33db0ac8261c691af3a27f52cdd4a65d799939faf279ac41788e7528a6":"04cfdcb993382e8fd2db8d90dca80e94b17b432009852cd3f86625159e837c19" +Nist_Vector_209 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"2b4365a4ac6854c972da7347af1cecc6edcbae9d533b74fbe6db5712163a6ce984f9d7a4c54b44dd7555e5c2d2f3d098f31d517f8ebd330199a54b15297e5adee1bdf391581f1019b1ad72dcccd5484b51d275a368c69a7662e79f9b29c9a3084c94ae76da04f958c7d36cecc5d41d77f2302ff28f2ed9c66a0662cabf51c842":"35b701b7d59aad55eb4299e0f9e0348baec875eaf62d2174bce92dd23302a81a":"58e635eec80bde1eb7bf2da20600617af29f0a191705676bc10f7553f7611126e4c4d44bcf14f7a9f48da6e1b1e54d0a715724af5bca93867090f9bfc92741dfe1dd4f06075ec2a9262da81e0dcabfcab9e694ddca86d0e1cfaa321e2b5818182eb620bd5d16bc27a2da035d4bc17807cfe8ae3038c5bbb8a023fb232814b91b99749f519de39aa0f434313323b1b58202c59119b0be217617047c9e2ea453d608562cb96c4f0851a7965b164f9bbe151f9c508ca209f1af659e363804c8d8fa1ad700e20866ec9a1e505b74bbab70cb472308431a3e87272febf7cce2c20ec37f5d68b4e47bf3741013723936db7c9b0f3ded964acb7f8ac9c5a6b4f28de198":"1c6ceff82adebf8c81bb4842b90dbe2a12c9d07c3a9d4990d44106a1768bb082":"00a7c664c544cd7b61749410dda33bb3a47c3eb5a9a7be5fba201a390cecfaef":"6fbbda967b584bd9ec6a0ae76e0c552b3d42bf0e9cf2939caf6123f6e86046f6" +Nist_Vector_210 [mod = L=2048, N=256, SHA-384] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213":"8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895":"6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c":"cab1d17666b0c9658cc78cfcba17a08e2989d3c202c8b5085531404d928c618b6e230b25c46a5b58437e4335fc040020ba00c863182325940f00aad330145e666d07e9e9d876137010932ae520d9188ca3d7993c905395219c55846d19b8fcdb1d0c1586b9b51097afd6972ae1472b0e20453f8fbd5d6aa9e4a9a9b3dc37dd8f":"1ca2b291707ce4f70e366ee97b5da158a1c985ba4f252c572f0fb329e43f9cb9":"5022c8a6fa79b7aa11a3d7af5acebb2ef8c50b28d8f0e3a556196562d34131fb44f22c3be3f9895e35eee70aa53b6c67920c540ba6c1085b0ea818b12aea811f2dfaeb6daed976e362430798fdcca3912a0891e7d1c83b748af1e7689e038b490eb73f7fe6e0612e8f238580e78833b20727a602768ab2d59dda36e75146fa4d3664f7b0cef7be877afdcdba23004ee313a69fd61c326759e7e779ad750f7a5cad9fb2dd80a8eea6dcbda0195dcc17b38ad6f0e2ab68cfc69b15c572f85f20c3679c15a83099cf08a379055f8fbdd8f590d43bd12f75baf0eccd6c077ac7589aab8171e8875db0122e6c78617c13586143a7ebe904a7822bacf48a7527f7fa4e":"4f1e2aae323c5309b3ee5d3b73e5d4090c75da17765559e118bfd1460c312859":"7b8b75ac8514c68de0caa98e9de0b9607253d8088d3feadf92b83ffc26e088ce":"4b10e17ff64a0eb72f70a863d00a9bf331bbb515ba3a9fef72753ad7f0df0be5" +Nist_Vector_211 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"8ab01510cfa33cfa5bcff003bba39996fa727693abf6ac010bb959b0b59a15306c0c3a1921af2a76717aa55b39fa3723f4c3229ca9acf6b741614bb551cde8a7220ab97d4b453bec1e05a0eaa42e382bbc7b9b84f8237dc8964ee5b66e9b2a4ca61cf675140efef54fb327a665def8d57ab097e8c53c643fcb58209c4215b608":"5f6e545daef6cd1b8d9848dd98758807236ac0b7ff053b32c703eaa3b1147557":"41197ce2233d7e48c803cd64c78f657923b9e36b871401f8661c21d8ba38c6b9b3239db767b11d1d401e5faecbf7a45860cc5f1a54d60286b7d6e1c99fd5b8c84ed851c5357d41ad60163f224d78c996143fff89dd3a8fe123dae1f621427fd8cce76ed138d68fa248f374ae233249625b93f3dd5937d15e541b7effa4df4fea7d52faced615bfe0348418ff93e69a20a52e55c76cc30f307f84e71e4aabc0825eca3a95b4bd58ebfb0029d23a169e9d80ba7d1c5fd35395e6602e089aa9918f08bae35ae1cac7af33694129e98f0dadadd90eaeb6eed25024390b1a60af794734c397b0f509865b134b2867c115d6f489b6dd7e3c82994b45dce2a23c6bc902":"5fe61afddbdf04449b24295a52a1a037d3f31441a3cec138b7f0102db86ef132":"6a47ea57ceaecc116d7190ff6c6dd9831ab75b4bf6cb291083e4268b486ed245":"017355f698a32abe9a4d4a7dda7c85950cddc348ab8a6751e72fddc01aa5d1f0" +Nist_Vector_212 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"b2f56948a336982a5bcb4bb5d79e3fe5c36081bd286e6e021ab29b522f0be5ff5e81e638f23d0781c268a89b09332575cb31c0804bbd34c80589fb11570fc65b3f67612605a9411cdab3ac00ff3fce33ab22c46d26bf9c3fc5ad2d9018deb9b669b50fbfbaf8bed6230c7bd621d564fb1af953f0e82c5b5520ab97baccf58d6e":"91e01626208863a954eb8987f8e987c8e6213536bb18f5afe3bd66a525bbadfc":"72b84eb6a60c686f74f376e26b2e47e44a6d5dd92c06fde49faad0af9b11e43147ce9308ef3501a752e7bf18e9e6df3c0a49c44cd2515a05508f8060a61e6e6f1b2ecf14b338cf0fd8b7ccbe678d52dbdf20352c155a2bd517d827d6cefbf48c5679c998298e2186ef1098160dfb65914506a177943a4a058282382d327ad36f88301be693c02000c72463e682421a0237804dbb27335c78e8495fac7842d2aafebf90f3c3605f758615df989fdbd06e23e4ad6974b62384f0aa01027db89ac3dcb01cb5258cdbd9c19372a6c4aadf27298062ac9a16de2eb076e167ad7c65d0505c8fcecf359bb5d05cd22e7d48629af539fe7f60e23e957c84c7a61ac92bf8":"6aff566d97cc48ef6bac507d64973c95da14fd704d3a5332aaaca2bdf21e894e":"43704e96cc8d63e6f5b7e118cb7c030d0bd563b8f7a1a304b368a6c66d7e7fa8":"490da43fd0f19fec4ee081cce25df6b2720b1a76b023c15704dd03ef1c3e48a7" +Nist_Vector_213 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"9ae8479327b8b8a57f570f6ec76a1ac6f02b198c6048a1f096e6ce5630b6caf363176413d88033b1cd07f4d3960a12dbae8a659174bb87c37aca6ec56ed5a6619b8ba676b650d97c6a21af023985dc361fa234b2b3c17e77703ba99ae3211260da10a60f240eeef478f2641184a281716ae57888117dba992853f494ac3caa45":"8a5624694a25209a5fb3983ecac3fedf508e0b23e878f60a18ec0e897c379f7b":"ce348b5cb3d36808422a5016dd5873df79f3cbb5e1b458e8c1110226047543d965769a112adb4fced0d146230962a8d413225cc70d810d40e6a72e6dc80db509400c09d263d66206966ed51ab65930a2aac99fcce3a398b64d59097683d2baa57682705abc32eb8c32d6f1e7d94ca17ed7067822cd20fba3795ed1843c01b0d7551c7c4c759d53a4191483bdc6e3121c2bc12607701f43e3ba382c6766819db07ef9c59586937514772c2eccde4c54d92575734c45a8e832c4417b43a92c9abd152259cc0a969bac64b237bb3a0826ae72919d7c2dd2efdf03e83701980c2a8f50ce6e44d7cc8848645bf40aefdf24fa7a6dce5a3b9aca6f017618a64d91ce4b":"86c3ce567e7995a61bc00e088ff2f2a425433a453252b1a729d8d85ed506bdec":"0091d750ad9a4f29573fd457a5891b68d4b6c15703a2bc192c7c620c4e4c4529":"92c409c8977975a417d9f5e0e2dc70683a53a95662ad270ae35d496567a9a2fc" +Nist_Vector_214 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"e5a1a344c25ba0cbbcffe6800135f2ede81049180fb2759fd9e1af3b816ad5436a24faf29cf3ad91cf413332f454f74a9d4f5efe76cf02512c273cd525f04afdb5c24b0588d611d72153680d1e3995e0aa750e9077b0752bd4442bf7bfa8dba38e1c5e7ddd687f55aa54c138c7e6d5f064f3ec55942dc192dd996e553633afd6":"976fb067157b214a80658e7ed2f566911b35b1671e5c0bdd55ff5811e822bf82":"3859d4735c14baeec14b79cc2693ffcac900a2c26ec634a8e977d206ad6ec7b13f2d450ef04782ec0abb0da48f000628cec1f6e9a727bb59d7c0f0d743f513ac0925beb61bf3ad75824fffae1eb783eb1b68fc40d28770e280fde23844a144d4b1a95409b755c7ff2e5c67811f3b1c2eb96cb159a642d84dd7b5dccc2c0aef06d1cd54eac94a11273f9498f1e7a7cd79c108e496dcf573ef3a6610b7731ab14c162ce8377cb9b90788e356f51f4b51a1ec8bd86bd88fd4c38e62cad619ab8941bcb98a2f35ee512f4f8ffdd5ee70caed8467156b893b3532a0a2aa5199ceaecc5b194bc057964cf450668c44f27ec80de21ea1a415ee6a6569832394f6b405d1":"1ef4f08defdb5c59a3df3358e083ce804c969d046ab67f2f938eb1a8f06a5d0a":"443644e127e381b17bb66c53509718a58a30f927425806a62840119e78c293b7":"3f01e5d1e9fdb1cfda25eff3caccf4edf599fea277201cf2b01ffd7cb1a9a727" +Nist_Vector_215 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"b88c212070be398a1f81e85dfd71dc2424a38ae38a9d61085186504f4c2cbfa492b76dbcc051cefde0616a7e3310b4bf17244de7d10f847ce2a9f665948e76724d8f1f4bb3a61919b2ec7dc47ad8a72cb5998b79fe3a156395e4ae88e682b1dd16c52d64cb4b31c39d4a42a21e6242dc0cdbb0acf3d47182638c5f216dc6e8b1":"02163cda612e84eb5ea9e4e068b14c10dad073409154d86fea6aaede59538d2e":"541c690f4ca0c42e5267646f78ef42fd68c363375b2e983be444e4819e63cdc129018bd3b8c6da8b707c196c35c93eabee10e875c41fd925bb3ce80696935d16313fd3a26858eccf2d507fc2a10950525c670dadc883dc6779ac1ce866d8820395f3541c863018337a6be944ddc644aaa6c007197d7a5f9aa53a5e1180ad51c98be9d561a85fe9734160ca35e4fadb02527ba0fa58041b4d96385f7f8ff6ae756add4968c0c2799c0d680f66c8ce96f498228738e3e87b7c866344db7d5a4ec3282431aee5951d9b4c83ec2a0cda36cb2e2c437363ceba4e8e9f6128439d12c51868d0cb1f61e53a68d4e71c5a9e7de43c6dfca26f1741aca916e4282653bfc1":"42cc30e9591b42486ce9998ab7594ddabc5328ca2e931e08c75b76bbe1f8b978":"078a7146a2c509b97a6a8c963baf1fbfbd1a2a5aa214a15ea45763f0e7930beb":"2979cbf59adb70f28ac4fcb69297498f8163764c62b31963da9c8f9c0c43e075" +Nist_Vector_216 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"4adf1ed4fbb5b82d7a2b1a2938430753a6207da1cc049574f0a19314272f9a80c6a53498b78e5c0b7401ce485fd4baebc966da6c1fcb025816cfae32b58aa87f5e8885054735f93df19ed32c819786d4109dbda047d68c0589330715e10522643bbe27e32c0dc9c58336be305b4c0c981b40e0eeda0de461d8441c02c18ceac5":"5b44bfbb69277fbe497ec729838886e7a787f336c246551526b660a7603d167e":"8b6927fe293ac9111ba406125d6ebfbc30f96cbfd696fcac7dded42305c6105453accb1b0ca6f0f31601f8c34f96bb8ee4ccf149923a12821dfaa2a3859a39cf82567609b2060ff609232e90261d66cf31fb9264671f3f1bff6c8a958e5cd015dcc02dfd2f02fb6a443c2bf45abf13862059df98066e00311bb6438b7fe2d91e287553d25411f0fba47417c2902f978c57257ae4eaa3f99317d5adee0f9adf4d41e41072552b3f51eb9936a7f63cc28b466fab6429d06868d18ca09aba634093767192049b02bcb752eb674c98a86869d6726f742e57ef8c3d4531171c64f03e10a4e44039a44d407ebfc6b56a7cdf6b17394b53b5604347c51cf375551b7306":"5f02472e007874056abe7194e80845b81baeaf4f6f564d3640373757f4252f57":"5b201116d8bbc87db99001707b567e7c3451d802fa6c679bf3db3456711a1913":"5be7e4c493fd5d19b771373141294daad97656a3dbe3fd2abbd3b6c62c166126" +Nist_Vector_217 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"bd491cf68b34f7ba9afe0c6ef5f2b7956ef964465f28b2797bc1d6e670a6d81730ee2993d0b4aa96905157025d775ba104e7c19b3b372e852026b1286cbc6a48a10cb9378e97ad966f9cf03917ee8db75b6264e9b0a48a0ae10c2f46444710d4234126ce456b9fd11ab7a3504948d046d5f438d893d9b1052b8fac9547415472":"609a372d3844ca8224dfe780b425e1a7c00d09957a862de6f640af57c086dd6d":"a92e446510764ee1cf81c6b59b5160a7608ff8952d045dd69f034fdfef93f633607ec209b106c6ac8f0cc6ffa64bb9a4484560b838d6f24c993a954efc9d5ee16656aaba2a0d5a94e7a346c7e501af83f131db9e0cab8789fab19bd591ec227f39b349be7f8d0df58ca0396efb1e76549335904b88ec21cd3265c543c4e80e9dde7cb5c9ea8cdda23d96ef1c3839ade8ed4a5cd5fd98b79bceeed9c641c5a7758d0529aceaf27b5014f13dfcaa267a14a0841b36897b6e1e8917b7f7cbf7cff1d1953ac43cc04ab06cf111e006497eb42f28cbc905d6f1cd5d8394857983e1c9e552015a451d0c13a6848a8fc56b79dec1723a8067ff18931c852ceb81affec1":"8c70ac971b83f159d2e6ec26bca1463aadbc8e9987593f49a9258f7f0de9cb38":"0cf526d8a0f9c912d143f3f8afded4598b2a5aaf200e0749ea27defeb7f28f3a":"877a9066f6c5ae78251d9d140bcf39ae912d18bf131bdc7e9d61012daaa4292c" +Nist_Vector_218 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"c00a8a2fffd10bc2eab63b8e375d0c10f9dfae2848ba42afe6085aeec26e21af3eaa493ce4b3d95a31fa502a60ab88e805f4fdf889ed91c15421718084cd0d644795749b1a6b183d74782d52c7babf7400393cee698af5dc010c0ff7f5acdf0208f93ee7e4ef58da123dfde7f0a34e209bbaec61007293fd11afa60b6522c45d":"683e924893dbbd751e0a3f910867471a6410fef562cca9f464943abd88e0430f":"7560105b8586c4532bf1b51e0d2cf9a713a5ea5d40e262ce01ebdaf1ee53d857129e1529a0f8dff63e86202c111c6eb289439cb15cd59fc218abe619c9516250f127fafe9a53076274f306f0b7871cffbd156b1a8819795f0a9955864756650274b83e67caa4e215f833afd5a77d0594b21b4b54356a98a56a0bf6177faffb9fdfd888d6538a1ce76059854bd1f0a20761281d7b751757c6ecc9b1e8131196d0669597213ae73edb9965da9ff372420851155011f691a03a7f1e2040291575b86f595998a06ef79f4eadbae2bd9e2e477dd72684d8efdc1e835f7f0f5c93635c181b96cc7c0eaa27ee62c9227ed9485a8c822b3224e9e2b7acc10956f3d49a6f":"3bf5f524e3a3903c149958d10ae68f0a87a03821445a98b0b9d08a3689738853":"98fee10c85ab46d334758734819e68b5046439cd0b66be26d43760613ac77b8c":"665fab98dd437e06a4f877ee218986e37c2cb2d237e598d98f1b7d4e829a846b" +Nist_Vector_219 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"27f01b47d15f7d196f2667b75ed15b89d7443fb4fab068f4adb67175ca70071d52e270f68964f9fb0e0e14ed5d2954a33d93807acf3c82500e8b9f5fc5510cc3bd6aaa1daac8309128ef4c0b4cac026425aefdd7e69c22c32e5f8d2a6e8f2ea291ac33da6c71a1953e443c0ea206568aadef2b96466cbf76bf149d89d86f529f":"285dcba140162fc203651c5ff7f1155341436c5c5c98e1e9df192b3c948a16ca":"38fa994a1f61ab79ee7a7e6f689c38f6c2826f06647b1663cd812adb36d7fd7ccc50e9a90d02bf7c3f12a228c692c056fb3bd608f51aa401022c839791e6a678185cd31d88cc661af29e5d238142181dd3f6e7c8b05785221e62fdb36c71e07f51d732e7e0cab520a7f2fc5b1831b0a6ba280e00321cb9a025db6538abd672463dbff5ca81993676bcbaf0f6e9c754f24d654ee7879bc03d7d4bc8e8ca58fb9b3929a3c38365cd2e205729e9def0a00108dffe9407271e17d355ec4b29003e0caf0c5b2acb9bd8e52d4410baa9b97a49874c14beebf03abf28a9ec59bc1738b8dd4223d47aa336acbca7662fc69a6fefeecffd47f6737ecda331d1ba5cdf023d":"4029e06b437cbcf8e0788a393ba3aad0d182564ab6a53565eec1755c4f4b6e2f":"8dad02c02ad34fe4e758ff5c81d5384c40d2c49d0ac777bad1cdebc58ec01cfd":"0fe4e1f6875c113f1c17a0f0ed228d44213f8d7e2f15567e57ceb2e8b1098f7d" +Nist_Vector_220 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"73cc5e4a188d2814466941389014ea45a1a06525d2069cf4883ebcb5f22ab128c00f041cf69fd94b33fdade78548f6523c838b87ccd868f3d3d0a9a000f278ba54048b9cadac7a99d98def51713191ad83e5232e3e86497245c80bc710fdd7faaad88ce92c894f8cad3de0075caba337a222cb7a3d7c2d937bcfe4b6e69d388d":"742242f1cde89559dadae5e2cea28cf402c60ea9af2a5282202281f55a0d4d04":"5266427ad4c1cf3ea229377ad397c7d5613512fc27f2ce37407d2cea8e1999aebb8f3767ee96cb927ebdd43b8dbc10ba2c47843d3f43368d9e442bf51ebcf20b48b543a4c388bb3ae3e4027acb657d1bf74abeb8b998421308770f70b3f7b1d910219a1210260340123b95dba187e00cb067f7e37792341202554bfc8a235fc01ecb099ec3615a67a3610d4d8c2dad16087024f5973eb18400c29c05d6984d1c15c159422827c0dbb2bf4509d710c4972ee93be7283aadd991ae8ef0e97312118f195d304fbe96d5aebfb21203eae6117831f9be9099d3d476b83f65ab225f8be493a8ad21620f259d8a44200810c8e562aea8e7a6bc238c129b19f2531a6af0":"57d9723e0d17ed96a3a77ad47be6eafc06a5aa01b59b89be70a756d37dd0df2b":"77236b33b04285425775ee3f658b3761295cbff8e4bc05abdd22e3d78b1b6da2":"43fdbd936ab40459f6843056ca77e125b6ec5ad945041c1f6a2770be9dfcc682" +Nist_Vector_221 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"c0746befd2afc6ca15cdb145c18462c515bd42794c4c7ee513cd9aeb0fc6fc3048b6c7231634984a1be824c775f9c9b028255f5b3c3d8fa08d47aba07755b5f1b5b008933eff35838f15a02ba9366c1036d3ff19e88199ef86a88227272cf4e4e00ffad9c36bebac30578b00214fb29bae43cf555ed431a2f24922430b1496fb":"47c0c6f4e6b56cdf1e1d9b63ff3739edec9c3d5a7c990492a1c72aa1494fcf9c":"431eee49090ad58f4a874c2eb5897969fafe3274bd7486b65e3519e4309d636ace6864d5ca4d8448a357cafac15ac3cb3bd7b2755b3cb6db0af1a4e91b2d1fcb28561b170faf2e0690071bc0f6e42b2d82abe5646ddb8f9b99ee1daf5906036f395d824d080bfaea103048b3f44d0636bc7a6a88e9b004a363b99d24a89b6e97379b20bacf48c7ae2e9bf7e281fe3b4d7eb947a102396d523a1e85ce17fd25f271f3c221a5681e9fb77d64d6241039ac8a85da32741bacf00660e421fe850a0fe73a08ee3a9b069c6d9114c1975272127468f9008552ea4cdf9d96561ea69a646695242500f2318bda82da633ef1ae0497014a637b15a572ddddec070d19d884":"3598a6006fa3f8b8f9b7ff96ba06bf3837a1a1a92892e4a268c75285bfa6d660":"796d7dba322d92a083da7a588fb6238dc86b1fc5104ed600c9b4c688edf805e9":"012c1ff4de8ee386b951275e250581d661d030a4d8fe115432288ab0a4bd46cb" +Nist_Vector_222 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"b8b915cf4ea3b0c4cdcd8b2a06479e71bb4797294b6c41ca870d3cb2ec2cb5a49f6bfe5bcd10be609ed3e1882a312395fc991345aba5b566e67960b42913db669041ea30c29947edde7bdcfc0896b97660740d6c79f0088665f51dadcfa07f7be44821d60a8ffde4e5cb1f98139ff91c9c6f3126596344c5f7eff40049d3f9ae":"0eb74b5186697af279ce72da74f1ebf59921ed425da0f3eea17517eadddb7c90":"1b3722764264e17994f3343bf260c73575d106f6307f2eaa3f7dcd5af804463ddb6bbe38a38f5ab5a8ae6701317cf6c267049fc9b84078241f82d3c6b7e5beba5c1427030297f1df258148e5f9eb41eb20a86877fcc06e5373cd50562613d307649539d28cb52418d42fd59758b61185e792992b5a581229b43403d793b04d878eb9b9d12ea10d2e64d153d3fa41881fe79a67ac408a5348d79239567dca96e1ead3c6ac22dbcdbcb5185bf8ace57660a4252104e5047cac87851d2815b12ae8ae96ab2f33345ea1cf5f2e58a4ddcba26265c06df65afcc6e852b3f910c8778de28a9f098158ed0eca652dda2f9f4ac8a17a9b252410ec5973a6063b642568f1":"37128d19b2108a8e8fdf2cac984d45851078a194bb9946a4db260f27b4650439":"6b4b0e1e7cbdefedb1df1f529ece47891f7b9e959a3f8556ba4bef7bb9856560":"7e933b44ede6b2e941b60c37dcd1568284def229c0a2bb9093f4829000c4409a" +Nist_Vector_223 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"dffd458a808f1889d7f3d6197f0e41920ad731124cee308cb90d2361b23fee969c0e105835549e5d0a3f7690d5862d4cd6ccb33ad18094c85c9650d75b248496390a0b89e7dc7dc0d3a6130dd97789ebf105f8e55d8f0a1162fb3c6b529e2a80dd51e9045ef8ec42ca4bc46abb6539588b531c9799560cf4ea806c3d93d043e5":"36ff71ed608f351c736042f3b638a89666007cefe8ab487e512d76fedce1ff35":"ea437ad0ee9264de8792b677207e547090b32d6ab460b4d589d842ed0a0b4fb4c635e4443bf60e46cba8d226f659c76d2ca01c69707ba6d977255c4584b74740a7cdec4c973e3d16ab6af60cd3123ca12ed5971e69eaffa3da0770d8e1228889cd6825e1b85846f4f7ecdb33f1e5c7acd6b2add1308c5cec439728d0cc625eb89df34fb9c0dd4568f979deead286c50145903a0dccca7239874b4683d367ed31696eecada90dced8a9b1e01364b8794660c60f40590794c95a614c04563c92d444b5ecf01286b1bffe9ed9ef915b4db820ea5c9a5b3dedcf89a3e2c37871d21b763990c7bbf44418f91cdbce4361eeb227516cb344409d2c651f0dc29ec82623":"91797ee940a167a57de7619334638f1b3ba63f9065b69f56dc04e4020a1682eb":"3152fc286fed44f28b1af2d537592c5691d6798caed90591b5888b0d6fe6bb07":"7bff61a8676f0df189654f25c5812b341dd17f4f44667789cc887c191bf47202" +Nist_Vector_224 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"a6516019727d95639db038f90306a8d94fac5243dc7b67c3568d63d85dead1cfddbb2b330b619589bd582af15f0811177504fd5b7aad7b298647a3f64797e3da5fe5bf87b65c2ddec576a8f40660686b808ba42e54bfd0e9e48082d6904f8e19050e54ea4797a2f401ff7c9f3d217b526c03be9201c0dc1b0e8e054bbb32c382":"396102ad116ca2e419b9229667a31737344d0d7854cac8930af18e12a9e2d63e":"9779eb5338dcae7377b1847018ce72c1ed4c55292a963f81608ef332050f0a484519aa96b18bcce8e1b49c11a200c1ab4a75726bcc842485df6314e5c39fec622d819434294dbe1eb647885ce841527c03481b7f22ee586d8c2b1a8471a2757bffbdd9c26f125065685509ff0e4c8b826d73c6e12f6d4b9319cdfa72c069e07b2d2c254b330c06f488d6598c7476ce0f3330c97ec36b7c10871388472451a34afb7b4d4e251f9f72a4a38a6851aab86507b283e890c31ba96d0a1e5572637b2d8467060c0736d11d0744e332a19f59ae2920894e9cffacfeda64ae1ff4869882df3b690c7ce8fe0eb88171e4f2ab8624e6ac77dc8907613235163e0a2c7d9fd6":"79753fbd43773b6757c01663b8f5ef642801aa5ccbf32082c780f71a22c4cb0d":"7222d5eb392460defe8fe3df18fa534f3060235f1e8dce5370762ec6fc11e690":"4351c428031cd9af567b1163037a4e376962620c4ec23c43b7105879f95bf614" +Nist_Vector_225 [mod = L=2048, N=256, SHA-512] +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079":"9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907":"972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7":"1ffa7cf55f92f234a24bd3296744d543a433c907c1f77d8b706f4b6262d096e2dfe713fa9ca80e68579396fc11a12c0331cfb7745d96b005204e483fbf8f9fdc458e2ca8613406069df5f44918eff8c5f54b8b4d972e07a4b8e06d8426a70874cefe6e93404c1eb381c2d0701c37f85afb1601a09fff8ecfdaf6cb64ad9bd8b7":"24039963cc5ac26a977728b852414f60a287174186ea812e00a5c8a8a5355daf":"18e298e6301389d48644674f8339487a8651b0768dee425905e803ab357c7f9fa05dd5e2ee84bfe105a092716274557e063d086e78b781a43c56a4e0ea115c5cfeac57a4c9b7e1effb89413689928f1546feb30738586d36ffe338083ee2bf5c5bd344bc3db2a7977de2b1ab5ba006d9ee93ef8688a7d10cafe27af3e671013a816984196bfacf002335fe7414423ed8bdc80327372b0d460866480bdf073c9def7977131b06e28d14ae1a816d3222ebaadcc8d7c300aa820e0328af66f742061aff5d4b7176a994ad69b390bbdd619fce047dc7d15a48ea71afa72040bb14eeaf4a2b23d99b4d977beb6d806101021eb0c3a0e31e54579e58c953b55b6e3245":"2ae1af11ff810141c37b1c23796e54f027b4eb7c2f0c412b6c83076de3d4aba1":"21d70ed955b09ea302fb792978d12501071a2e8e2cc8f659decd3df24e37c466":"2cdaaee2a5a3dd74a67795f93ac1d8416223836c76f7fe31c72ec6170925fd73" + +Nist Vector 3072 sign data SHA-1 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"ca84af5c9adbc0044db00d7acfb1b493aab0388ffbad47b38cd3e9e3111cfe2cda2a45f751c46862f05bdcec4b698adfd2e1606e484c3be4ac0c379d4fbc7c2cda43e922811d7f6c33040e8e65d5f317684b90e26387cf931fe7c2f515058d753b08137ff2c6b79c910de8283149e6872cb66f7e02e66f2371785129569362f1":"433cfd0532ccfd8cdd1b25920d2bb7396987b766240379035b0e86527ce9c52d":"e7c2ee18c3aa362c0182c6a56c2584628083c73e045beda8d653690c9c2f6544edf9702c57c455273905336a5f5171107a313cd7d0b0f50f8d3342c60219f22a9023394059d05f464c4496d55dab6eb0898527ff4cf5678e7b5bfb5e18d92c4a9d73288cce14530fc4702f6d0397ec39a880c4a72d358730c56633386ede028023c1791f3164d1574e7823c79b8a3ca1343ea166ba6f02b7ff7e9ef2198db107f7cc159f3b6a1c00a78c355c566deb0ac6fde3f633cb9177a1fbc6c1766ca021d5fec470101abb440d2f06982181a8c92b7cdd765336b9a1e1ab70283d6db0a963fb648c37c4e29a74c37577291049ab47cdbc104c04db966681ea8ebb9f00cf4c4a5462117379575fbda4b801979451fa94b19b4e93656705c0f734f3e0914bb96c1e2b8a0fb68faf14296efdf3300ad95bcde8b67cc4b26e6488eef925cfaeac6f0d6567e8b41355f89d1c2b8fe687bfa2df5e287e1305b89b8c388c26196090ac0351abc561aadc797da8ccea4146c3e96095ebce353e0da4c55019052caa":"40f503abd70fd49a76c67a83e08b062b3fd465ad92be433c080e5f295bb9f559":"21ca148cdf44be4ae93b2f353b8e512d03ad96dafa80623fde4922a95f032732":"73e48b77a3aa44307483c2dd895cb51db2112177c185c59cb1dcff32fda02a4f" + +Nist Vector 3072 sign data SHA-1 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"3ccad0018519a898f87d8ce5f28c0d93ab16c51addf4173322cbc49d48ca9ea37ebe8bc9d8c1b3f783f8cf59cf3fcba10a393eb2ddd989ce258e73788ce74b0ce8223d24e993cfeafa49cc8ec1b8ecee017d83a11bb7034c779206c364ac463cfed3047e1a2bf5c591773b1d882b310bfba2db87893c89a5442c0845bf644e21":"306c1304b380b7c3e09e7a4b489c64a295582bb3e03ce526f13d7482ef8263f0":"3750d36353bfd2e9973e26a555bcf0d834d3d6620cb66579199e040ce8eccfaee660046e78df66e8ff641523046adcf425b8319db2447680194c3a386b5201dd1ac6bf3e66394e939eaaaca4fd3f386fcfe1d5ef4524b06c5ed9a15746f24baef1eec41e683bf35371084495d4da8e727aeba307fba000a769a234e3c4609704b3ba4dfd6a8644fba56083dac848751b52a8c2cdc47946cd21ea24383cc6244f000918e9a23276b606c5688565c44ddf7788181b789565a6becd257123bb81a2cbf9db7fa384e0ca41804ed7cd3c9ca0e1f8bb390bff50213b0629682409933770f6e03a5c4e7e89ade90255609786f6b2fc5a7aa7566bcf7f725aead4cf456c5f5ed7dc3e91e20d94d1aa2f6568c97abdf21e0ba8cbfb6561305cb45175b1abd7f39b9a11c797926b944f5d13c3d70e0b2a8ca18e1f5cda8ce6ac43ecbc1fef881f5eef5a842fd5984ad1e321a317005ad478cb47c9cff61267f1d496fded0a48328d629b7b200c441634ee908879011745bcab6660e15583748014d6de2fe2":"223e52fc516c0a79f55a5474321264fcce78c050cf79b3d9961b37e24d7f32d3":"1ef7723345b2013b71104ceedbe7a9cad430018968bb295b672c2b57b9a108b9":"72852da485c0836a8ebdbc4c996f7f6cb65e99391ce06b19a7187618e9a95584" + +Nist Vector 3072 sign data SHA-1 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"1fc98288857fb3a83ab507465a53c079ed66679cafdfb8653bfdebb03020fe86a943182d4f1377d58eca3c7710d32e210d8d03728bc69e1b8003944ffedaa1b69ae6cc506302bd6917019f588cc29501cc8263572ebc0feb153877174bcfdbad4a58659175d2de71d5f5019c46d112b6631cf0c3f912aac83140cd56cdf903ee":"047a5e52039da40523feffe63312887e4d1ecdf64f32abb31dfe680bd1513077":"335372770c0e8e591a367de99833bde6f01240bc6e236a5b4e36233e120b8ee6d1c19c77f4cdbc294d3278c3d4cf73ed9e8ea5032b0524a391cf293b35ee7e023430222216d9f18b45022f4d5f9385f6384d9faf1a0ffa4a800da23b937651a09e82c22285b9de6a408e23386ffa67abb9d1c71cda7bc0c93525fcd79e83153e746070782467858b697ad14914673033fedb2d7a105ad2d438daaa35b503b518314ac370fc5b1112d4fe514e5835d9a86de25e6b35691392d1cd04836d4126b295b8a89f217d581258af95277b8b91c31e6b0d23a7c52b0ce2641cf1a252838b6e28e226cfc4fa9dc914c5f675fc900ed680dc1aa9e1d17193c432af4032ebab954191327083c59a5f64c1ea18107ce4d7211d1c22f04805ed548fc22df4b162f30b6ff3a7f7c38a5a95fe824d2961180e98b30208dc7ea7071f792261d45c7bb7b911f3b19c3ee0171a326c033cf5fc2bf79de7d5115ac568e04789cb44e08f3a8627a1b1f3762342b49b7679bd7edbe47bc3ee9c3f02db15d53256a5ea2847":"69a22d61b152af35c1b43deda88d5ad456d38df75b318b82712b2690a5f2f647":"5dd0c7e8a3993b9de0676a579c897ea39943a43dbec5996e58c1985b541d7c1a":"67971001822a08a2148a6b1adb50274a57dafe896fb04a12a6f99707555306ac" + +Nist Vector 3072 sign data SHA-1 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"fda9765cc91a9db922aec7b13fc32ac4ec4e3b8534f9e95af96e8ebeab89d847dcd150444868cfaf4213f8d8baa6b1d0886224e2afd0aeb93d59b886572088d05bf721c7adfb54da47c6c4851204a7a92a11deb39ba17cf6c07fb7ce8ba350a99d018d4ea64bd56d1d9f8f7d88157f190fcb372acf6f8d31cf7b795b36c10f5e":"7f6ce353841963c8a6ff3405713e361ef9f1e0765e665195e7c147dd98120c4f":"0539cc992ca70f913537b1211dd326d85f7531baa6be0583ba45b9571baa81cd5828050dcd9ab7a203bc4fe1d874f76ec1f34d935579ed2132255789d7e6010cf504b4c7f586d44a716600acf8a04ad30cb7ca055d7223f9761cdaebfdf7ef72bdea3dfcd020069a969c560160f0534676beff5ea611fcbc0fd47c867f3163e1371e1de67a1a3c3e37168bf0be79c09f45f2bc43517aeea0100a2a25d148ff1990c06143fa253d8306f48d77362224bc3efe93389e922def0fd11d1992f550ed8294b6136547ffd612b0bc8e4ee90b3100bb89922177147be0083281bf663f8370417fa790d4105eb98cc126f5005b7c08bc211dea2898aa653c3d2b51fc67732bff5644e804aae69200c416035aa0ba5a14cc439b569f462117b7dfcf3f2cc13e723a93ff9533208f20241daf36cd16066be3dba20117cb145d756f5a6f79ce2356a051647aedd645bfa6faf8f80a6fdf3eec42ddd42bb2e7b7738296e23978c8bd63b8045953e06cef1263bfe03be2f61b16007df1eb198567a7bc6bff274e":"01cd3cdd3feb4d1a995103b1520fef17f60cd9370ad59b3efe9383a2c0126f00":"55c2b27e769fac99b47bc0a54ff1821c7a46be6001ab664fb68fb1bafc04446f":"3059db42a399c428f3cfbb102d6c0409b06f20068d1ca8cbea4858ac6e5de1d3" + +Nist Vector 3072 sign data SHA-1 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"e49a12b8d761ef7afbcb1c377eedf629d08cc509a8753a5b92e26a2397365156e7c081bcb4686695575c6a64f5d77dfd550b04df390aa55e0d051c759f197a751a6041e2dd0959f902f2e359a167d880c49cfa81e7196fa1604ad32a8017071f098d4cb346b39266fbe75659dfc6607bf0d829640782cf3e12e38376c5a99282":"28d9bc1d9aaba882427ee26c262bd4003aaeba422bf053b0dde14bb6d6d74bdc":"ee7fff18822ff454a207f9db542d24298bb5edb11d80ddc6ddb9bfae0c952d4fe8d9db0f1a86e8a0f2193af7caaee7264d74106de5af0a6c14f710bb863eb7dc167a1e4378b6cdb7ab6841c664e9824529119773578ef55b7c35ed221ef070dd4690b4c12f27673e5d1fe964ffe29da57e2d1acd21ef13e0669fa97668bb199b56a3a53e10469133022081cdf62648100dca267c4f6a3ca3a75b573bb1b39c8a4e1fcf81269e9e1b10c63f5ba4fe75cf7139d038d02f5f534aa081fce732cd5051609bc06f18874dd01121d3c179f0c3f0399c185eebdc34635b3139f1ca50fbffb3b0ad12e481c1a64682143793f072c7db8b5b9eef41ccdd66b904139d644442a92f6255edb9bc1234e27d07a6ba32b1f14cdf98a22c6a12300dff50ac1b65568b6e915541bb386ec725da444467ca25e81448cb78375146ad2078a830e7d905de9ad7d89559c9d430cf5f419ce945704a426ab264016ed87c90d97f51a7d6e1ee2f51bbb3a8de81391697b0e422df9e5d3551e93374e5f38016b296d53bc2":"0650ebc3e21bf1d90ffb3ef5a707013dfce78fbd2c21a0da9c8106d1fa98a46f":"21d34df605237975db31b864f98c9ab6e465dbf0b3fc5868d67cd6cb3a13963b":"70c48807d62d1fe74d58959347ab12c97b500d20607ed2a95d8a388fee265812" + +Nist Vector 3072 sign data SHA-1 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"28f7a067a0ea7f0a4d797cea3939f66b281ed19cc98b8563ef375798b40614f4dd85ac2fcfccbc5ebf0ac93228c0b72937a481ca4f9df7a7e5d2e5da9af04874dcec35035f6a7db493793aa2361fb66ef2eedb7574d04e2147c357298a2adf99aca1eebe00cefa44b39157eb1e94aa8aa98d545151fbb4de67070b3904cce930":"0c5088f5d337802770e6f98349d53461f13161020ab9a241efed4faed2e569ee":"cdb9922d69e99c7f34a9210e2afc5be0115da4aaf682d9ea37788e0b6caa6fde13c88e51f558820668b59d14c06d2cbe6549d3f06d10dbeee46f59154cd467ae19e16be25e6f6cd238ccd1947fc581562d30ca329bb327258ca4aeb901f814414058b6f169a45ff55e40232d7870499ae78c0513777140752d55f0a470761bdcff5a6609cca2d1809f184b298718071d216a14ad01f56cccced23969607b62d4d140c9ef28507674f59fecc7e7ce8ad2636a5c53f070ad317c8cd0231f500a790ef69ac786000faf68e7b7854d6eb26499a9d524cbf8f373ca41dd6a2fa5198eba2a8e228f5ab29be9f6d450f7f5a149aeb20d8a277971fa6e64a0de36c8750afc381961756975621f287a3950f88402c5081fe0c54f44f9fa7c50df906b264098853646b3d05a4f04c6f1bbc6c440f7e7358d3a72b29f7643f4406b7db173690d40aa2938eaf01874d2ba8094cc5be1145b2b2ee9e7cf15bf398e50832d95017430b1869938732cdd1df593f5db2b2bd71308d8c253d254ef39b475e249d890":"2be962ca1f82b879255e20d6971e633ba68582a5137bc55058fa42b48ddf0566":"12de252da2593c5969a6496ae808d851cad1ded2959ea89057a92e5ec91c5f95":"165338075e6a4fea0b238f9fac904b7b33dbee5a552646dfbed827f6d28d6492" + +Nist Vector 3072 sign data SHA-1 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"0e156b0bd84595155ef4fc213dfc7e46bf27a89c275723e0984076b027c49cb2eee6ac866d75333581cca6f897e11418fb37ba5cab1391cd237e2c6ab3f11a055d3bd03f425baaabe5a6a34eba4b118af73edd610787cb8eaf476bd217048208ea4c1d0591372947a1c0ef94696568983424fd1d802fc911e7bf71224afdbdd9":"2c4d972bb3539876b8f32cc645cff0d4be877175f31a028b9bfe973f0651789a":"d0973641d56d8baaa2c2d430501dff44eaf9a3657478799134b0f335ae94ff2791dfd494401332486ba637683e704bd985f526919e661a2280d99bd48262b6c9305e0c8fd879cd0a836128d88eddae51fcfb51f744b23d2d2d27a2cc1ea5a9d5e0a7faf4227a2adbfb7ed45d6aa9c33798abf07bc69efc5fdde5dc5c780196257093eca75468b161cba44bcd142b21fae9edc6ab327830c28e1b3d2d7c812d8aec3a1952627a040110872e148e15de5c7b4ca24f086336daecbbf9816cdb9dc730db8a66a1929abecd4b09a039a19bffa45ffc85ddf0be3277bf075bbb46f07bf0daea24897e07044b5ee37f9f44fee757188170da22924fa15ed9c07f113cdf37a8c48648e586fb55a0c35f3b63a69667244193c70d94bbe36d043b25a041fba92a2042e2eef767e7cd18dd1c1b5ca4878fe774c833cb5c5aff9f67bfd6cfbf2dfc63b8842ad2d49cebcaff4c3927f3199c106d0c149a9b1b49bef1d6f8143d93d25df9db1b5b37d522e723ff64d9ee52e476206712a38246dd926271f5590e":"5e12de89504bc84836c14fc47628a517e898fa46769eba2b36e7c69e580a6473":"5ef5d78c421ae5a63978bcbf7d2037b5022bc47be7b293806580ad5b4de27a4e":"67ccb2833c1d32c68e91ae3890b4c9a6e5229b22a5799168c0046ead92573c85" + +Nist Vector 3072 sign data SHA-1 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"849c5337d88b3b247df573eb0d665548b6423763d5571f8acb5e61e316d7cdc208cda5b39a1944a717587e58e21b86ed222b8ee265105a32baff3692dcf7b8713d0b539262a5bd9a954cb7143ee66f8764db6236136cb1cb3b34a87cbd3fee3b11288bc94ac99179c681a469d62d9bcd91d40332a650a5bce33b6026884ef94a":"680878e382b713d4dc9bed8b7eae880f1054f58e70cda2717577fed3c63393dc":"1e8d4d6fef9905d639e2564d87dcbe0d8f99bde38082ff091a977f2affcab86505aeffe6ef1ddbacf15d9165b006ac0517434aaa65db210452fb2ff4c990b87f25fee7ad5b26ad87749575190089a56cdbceee6782ceaaf569814bb9e658ff50aebf6f3c9791893e5d6ada5fdf8c4720fafa184cc84a84f5fca79d899636e007bd0e1a89da094a378edb6d72240cc2d1d7098b53ba4837a5d0d7d02019b952712e4f1420e58af23d1377cd6d5f3989b3d60b5fc572043b96c4f7beb7137c0894fa99d727a5a88a5d5dcbf2da7b0b2d83db88747fb0ccaa8991d24fccdef42111ff402ed0d9bdb8a4ad13f8fcff6a1df56c82a5f88f575f49a06275a9e66067f15daec402ed877048499909b9e76e5fde52feac944e1de7894cf13c515299acc6442d90f027317b0713805a9512256bcaa7963b9429a510c5869792c1e29082921d0e7d0cefffc34d30762fb83e2abb7821fab4ca89d08b497f75e3149a5cd3d23b29bc52137d8be9c4a95c6376f62ed64fdc159b1bb6c842bd07f8cf03f7f2eb":"48ea48cad85abe488665eb75359217b63387427093318bdfb5d7d8092d342caa":"11b16351f8f72031ba2a772000ac8726a479e1be4523a9eefabe23947a1df0d9":"2660fbb44e29e7687c10e29de96fa1ab03c087ccce086cddab48ec63774141c1" + +Nist Vector 3072 sign data SHA-1 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"4c37a4c8b41109240c4f53d87277d3c790b2f071105d15aa10bd0f7709da274ccea1961e0b99635b31acd2c80530d2b403d7110ad7cd0e3572518909c136e73e57d38c1c7443e58a257f0736b9f6f51da8fd1ae9213e8193003d69583381f020cce7fc59ba1b1ed5541dbef6b59925750d50b6515a977aa4325d5fade42f8287":"6bc051fba93b92859a8a06eb361f348f5e50d091c55b998476ecaa1777f26fb8":"88a4dd593b64a4ebcb27ffea3de9a7ed7801f9672b5c8dc27b383d6cba58b4f00181634d05eb490282ce4e57f0940373d3a7bd7e9ccaa9bb2965322ab5fb21b4327b47ef4e2b42424c1383bbd8558b506a7bf5537b049fff35c558bcc739b760443728c090c34d6d4eba81e24e42394f8fb826f7c92ca71a9dab16e999274726b0c5d8f72fb9141870dac0bb9ec0429802b629ad71ae0560e5862ecf3eaba9c2a584885b32c684f6d55fd1b090d93d036a4e9858a4d89b9b5750849d926c519120131d456fce9d247341eb17336ca9729a9080ac5b1272fbf707526afc8ae6a8c661ef3c151845f6ee0902de9abb4322afe585e59d6d418e87d7cdce4897ccac81d013fd72dae1a5557762527312587ca676f0e0676000fc0c76b8265842f2db7e18e621c0e3c2ca9295e9e36ec8ce1c85097ca5fffa62e7b896bb16836d063386b1e663ef29ec1702965a7e0562d2d282f80952d7476b322ffa7929a453a638ea3bede802ff5f8f566085a6e2a2414ef7a6f117ac8628486b23603b1408faae":"40c6be904308e25af6616fe77c23e6e6570ac32ba5bf54aa81f6773a5071a904":"23e13a35777c189ae56509c7afb411b31307737e2ffc8db3f208940c5e76edb3":"0544758362cbb61d66b66826958aca63af1b8ad615a49ba557923959b68f8228" + +Nist Vector 3072 sign data SHA-1 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"443473d615bedcba2c8d9a9a45a28c428d7f1a26ab14705627d9ad13f53b767cbb60be523fc21a99c373bd7761817b314290f2f6a80e06e12cce238954c648ace50f3b0dfdf71dc308e1a8ee1159fc1f19b73ab6015d186d9b6bad965a9ad62e440a9ced13550a444b5f0400b96e2d238e9e3dc6e6de12f44205d4fd57f60e9d":"0bdf6ed048358dcc9a2dc555c3d45ac394571135ab36168d9fc4ffe4a3529a80":"0f4ec6e2baaea9c81e90700519f2f05f545ddc0ae9bd3a091e8b6ba5255c15fce5ef3c046771c5f31bb01de4377e142831ac1749903f9317c7b01a990714985f9251198c829073205924c568050acd6dcca757618cd2809bb7aab64db1e86ca92eeb854120c9d89fb9363596be9cbbaf8eacae2f18f3ed483589eb466a5144824feb1f88c30cfcbb7628f7cb4159ce32e7c2ed04d0ff0481c958e5ff744522944cf32020389b32959b5e12f80f08064908a270f8695a3f99e75e7e85ba3b3c773f04ef9e09e76b6c47302e41d50ead04541e0fca4a42502722265f82ff60ef46aa7547f9de249135dd077f24a4e7e03be2e3094772767a9760883c520816fae637c030956ea25f0a869e4a00a4a8017bcb72b2f2fd83643bdc01d8ff2868d3caf100ae8b818b926c96a850bd69d8931dbfdcff31c67c537c4f5959d04b744a346647066dcc61f63be6251b590d688ae3c9b53f392007d8584e4624ffd2941650a31dcd5abfae7ca120b11c8d0194be96e8dd09b643d5685d1065d98f39b6ed7c":"63066e05d16e79fd013a6ae456aa3f036e9d58675b3c9e08a412420a64c1f977":"76bb0ecb9faec7c971137ea6feacf1792073ae80be1ca8ed9cec2a5ca6cd510f":"34920246730e0974fb0faa57e77fc50ab78726c8e51579a0ef5ebe3fce3ba7cb" + +Nist Vector 3072 sign data SHA-1 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"cee06f792332080d6e73b3f02f5ec16996b66995beab4a2ba092f40d85c8ac1accf54fba068128c8cdbada209360776a7706455015e73e92c624ada1dfa62ec794cf2a1a9294f3fb55994bc5211add1c685d9a54acd5bcd830d9a4fcff29aec5001c3b2b2a9706046f38bfe48e8522768f1c6f08a8e240e123ed30e20fc46c19":"530e54bf51b3ea012e76206b5ff53c1d5ae6f3433f2a50b66b6947e84dd52171":"5c9205fb649d3b4ba2d44c80a925e30d27b05bd339f1ce35e0d0419a91ed31fd108c51a2a62cf9d0adfd877d27cf5575e43ac7bfcfceec5673736cae089516df8eb1ea6b563198b24a6e2522f320b123bfb250d43b600df9298e121b6c5d2e637a989215e095e603ee6d4e8a2dcd17b908918aa514c86a33d8c717578d861261da43f73250ff2be746c6916fc72871fb42a279d22595051b8ac04afbf2013063e31661b117c5d094b4c232b22f21d2c65d6361290c08f12befd1f5a2b9b5259af0435b97b4328297c252d813499f5209dfa35e9198de68501af4ca8658942d059bb62b8e55a3ce6120a78ee098132e8d2dc3757f7e60f8c08c4e43feac67abcddd1ea2f016839fb1a0f797b8b137ab43b64508ef69f6ae0f3abc4ed682aa7e38fa5146fec62e01e0951a6e81152de43171ca8869fa1a42a4fb2d8ae512c005fd97d12bb13f299ab9f5321ee2fc39b28e61c9ebcb91ecd2b610fd8291f538a00d06d057c3e79422a931279fed9d93b0b6533fae441e98413025fb4fa73cdefa80":"4e500b513c2e24ad17fcb8cc0d6a8c54e654e00a892545a33cb5af8877589520":"6d02536db546f2bb1f65ff0b91b964802b38d171e678054ee41f2b8563809cfa":"6bc51120e35c955ab8f717f8930d8cc8def8505415cf159d2516f96578842f31" + +Nist Vector 3072 sign data SHA-1 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"58aba24e9481d1151b574b146ac21b17110ed0b9bfaa55a4e2e06dcdc18bd10cdfafac047189f5ba9f10377affb40a514d528a3483fe8e64b831ea0cd076ce583942b938a4b257d0b5a92412e01dfda8217d5f8054596a61d5737d8ad8112ae228220e3bff60e2e891d03d53fb14f14dd91975dc15d6b7bd62e99d74ef3839fd":"7bc2316b6301b772b6742d0c50f2c1c39bbede01448026b6a201793bfe7dc3e3":"2adbc07d8aee284ec982c4b95e1ec3ec3f5fd5172368ddf83f9a3c69655291dee6b99ed713e5a1fec338239b8199c5a3bb2b5e2e7f23fc795058a9ac70ebdff2b3daaffa389e97fee35f174961f12d634e8b8250b8b770b8d7113d0fbc020b7b108f8d6b2d7cb6c59e2e151015145a8e374f9b7396e970d91e3c1f85ce23dcae12b2f53741cfc2350b582ca87f0ff9ab50ad0ca2879e216e61a5c358970a3c3528dcd9ece6b83d525b31fe687696a2a2c65e34f2854fea6ff92244d27500f7da946c37169756f4a4664b2909611549ad2b93ebacebfc270ecf4204e6641dbce05da2c000a4ca5ac885406ba155807494706180d54cc012ce06e734024f4ccd882bddd2257afb5c287bc3a8570edf21a20afeda0c762ad696fba177a5f2f9d609355cb91d72ccac8bb9e7c3cff1834d86b0772aec741d7b4b3c3e43bb26ec9f5e86b8685ea5c625b6aea450a46e85e380b158de6aaa2701ffad0c7d1ed0df355d09d06fe1758b2f27a5d02aa283aec9fd12d3b62d504dca0b6632e89fc55fb083":"0c2a0d2b326ad63e869384e3e2e32fcff8db83285fa0a5b9a7b13589a7dd7fc1":"2c462d49344f3ad03b6798f96452f7d66351cead919e8201b7665c877f8255bb":"50e8908a1c6684a2caa8aafb432cda4b7699008c72d8d622c3da4171e51cfdbf" + +Nist Vector 3072 sign data SHA-1 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"e10604ca00728e533621dbb6618b0c877c4902a2ed79aaf40a4daa34d6cc216ad4648daab6cc1e18451bb94e6a1c0c6f9d0d883962eebd507da099788008da23205e3b4e90fad9ae857074ffeac63430c0facbae489c54c957db09d53e12b656cc278615a3a5612af4c2f168bdeb118a42a2a67103fac321adf5688b05848f7c":"6dd500e2aece9ae331df269c26a4e5d58fc6be3963f5002e36bd9cd04c1adbbd":"b0448d43c520377b7df214969f59ffd4e0010c12d7e5fa8f241e9ce1c634439c94700ed5742a8322d405dd05de9953447831c7674e5ae1b89041fb8f2ec1054b928c64ab862f021a55ebce838d2a3d2c7645ec7c0a1a4603617e4f508929144c1ef2b039bc78b59362d5ba9537906e66c8e9c9a3c68e71b35d88b8bac86cacbebd962c66e18129637fad2d98d21e45a32672649492f131bae88c9989bd6372e17492bedff4d9b091b3dd00ebca6bcc49148480589f9593e32795299f3de7e09d88bc0ed27b7ef22ef7d202207fb5ce8c91712c3bd5e758d2822809ea5d2cb288332aa0760368259281a34447ff5a98c9c97c1d58383cd14f6d59bb5e5763217b2337ec2321268197f02cecd0d9fd93db39f8059a38bbb35792ba0d4ed1bad95a05b481c39f6adc9017dec1d662b0803f2ecf0845935765f9356db536c8c11887d9e44b73b6996ae7ac24fcad9c23017e5c2aca88b5a136b6307298b85ff010f964b7477a4f980800e69d3cc0f438aff7f2df8ac61d64435ffaf5e46633609e87":"65243ccac0a014b9e52638171b4a88b02a8c6e617ab9467da523487122e6650c":"56ab9947ac94fe3df7e35801660f68753b0b620a26594cb8fd375be3ea4dbf05":"608ed1835139af29a2e3d874df465edd8d6428f40357d9ae4904efe8bccbd035" + +Nist Vector 3072 sign data SHA-1 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"8af31f66772fb0c31a8c5b28e568e6368cb66b591edfb0db867fd99e83feb3638bc80f0b14483d069e8f2e167c8b0f10cd6b45d039b7d6f833bd58d99b00597aeef82fa3aae2e55ded62ab660810de0fe1c92d53adf98c838c18fd76a273ea12119d675af727011869943d765b96ef266270b4f89ac72edadcf707a4a21b7533":"145abce3eaa8fa6b670afd658ba0c14fa98d2d20e1422367d4455967f9844858":"22f3db9ea369938ed750d5ed3781368d594e62635c6b6e103d6db489a9972f398203abb973d5ad9c0dc110586978d2061483c0202738ceb01a665dd22fc568cbdff2148ae664dffbf888e4dda5a04fd3e89398b4f1ffc3a3813ae94da1f8965efbe7f300948749e9757cc7c05f6e53fdbff994c223aba2c137151b6a320f5b7f8cdd6003baa66020162990624099f3cf56d68b74e96ee09240f2cf11e3954e75b261ef9e8e3551c6c00f41e9eb17421203a4565388c321c1325f72eb10c28a9deeddcb4806f625382b37f0becf77936b7f83d26bf1ee1fe05e8a0005a4058c678eb569e339423e7c844305f4a18b1160a0c430513fad715896b62b9d6e2468232ae375f5f3c0056245eb4616ba11a6029410a955af09f07595fefa03e5516c95a4cfcd66046be2a4f7b3ab274b21c0a4f126c482c934c79dcbbd6916f3b887b2600472495c8335de121c7720f29ae56f5ccf9b99c9ce5655c5e1d15d67895af0dee586bc491a97241f7eff434bb79aad831db0695781e6b512e8702407a7d748":"06f085f77088ec97cebe5397a588369e3dc15b70f2a5316a6dd5f94967fe3dbc":"0fda7a8a3e5d324fc0a1c2841cd22f98757a0c6a2a465b0d9d65bda9b23b3c1a":"40860265229085453fe58487a933edf3c28433694c7b85f6370d9a4783168237" + +Nist Vector 3072 sign data SHA-1 #16 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA1:"fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1":"800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75":"99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d":"e2456ef5d465731b976f2ad1fc94634c0569a0ff7566a49d47d69e60b3b6d7eb2ab25cd49c931299796bff7e9774075ea20a972e3949a29dfb50b2b5613b45c596ca5dab282ff183f564a06311a49601a1e8560d43c6a481ce713f46c6ea85bf4c16489fbd72cf552b26516298bc66942a05d5a8e6d0f6a88f3e678d310e297b":"286d3cec1d2ad2a85f0f163245267438f7d7d62149ba9e59a18dfffaefe44358":"dc9d68b53f35c29f7ca003a2583ec8f8ef5d78a0e45db3c884d35df4fb531a080ee3831bffd3c756ea5042c7614570fba2f6ca4870db4a453d0f793fb4d0225d94f27412dbdf43432f52cb8f867fe5f492a8876d7bd850d899ba2f0a53820c440841fe0cb76fe0444bd6c3235785a3da3081fef99f53a195314aefe955f2964c56506fcc969b67b323766d299c0b02981c72a2ce3d7524ae6f08458795fd32e31b47aa1f974e356081163cb23efd73a9e655deefe5e734ceb58e88a9dbb524eff7e11c3e30680702d8560dd8b6ad9f61e7246c6dde164e914951d6a0573152ec8bdea679dca1985bcf267304d5f1bce2f32bb9946a056857359afbaffa59bee61ad960c567efe3f1145a8a87c2491fa6b33f7e71fcdd8f1ffbcd2b89920907d1144a8cf0573f5b89217bc0598c6e1754f1ae7d9d42a608a051621419da91d11bda9bb9dfa7118e4b663e7bffe6e9946c77ce9f8086dfc822a7ef728888b31654a19b6debd2ca62f5e3b4e289810435b363ecab511f47e9e157f0f4198862ca13":"183ca3afd082bf3de19e89faffc5cfa7dd713a873c02c723279b3091f9bc627c":"778640ce75da584a6a83f9794c4ffdbe30411be43027758c74f89f7ccc7f3983":"6125481e103f7803b2f16d9a4d00f881e0b367024df5822f7cbeb5711e0e4401" + +Nist Vector 3072 sign data SHA-224 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"957973fc3f3fe3f559065be5d4a0c281cf17959018b9a670d2b3706d41d5812e37301005f8b70ebd2fba3c40a3f377a751b6cb9693e3cb00d92888247d07921d3c1e9257ce08733b8926e0df7bdb6e855f1f851075d4e628d110d42b643b54876e5faa3611477ee68371562555269ed62a9271bad50cc4d46038de2dd41920c2":"524a7ea5977f8102b3552930477f5f042401165d4637dcd8b9d13df4f3aae5d0":"42243539e49db9ea19d98d97f6f2a94b23529812df889eaabcfeda01ce4c759487fb89bc82da75fe1c9134361f86de47d16d8eee80e56ac502178e8ed8129477af8bfbd8262c5edd937e1a86c0f0e7b2afe7bcbddfcb5814ced0b756a76ca178423bb4d578c5da183712d968582640aa0ec7e9fb56bfd960d7a57549747d8fb7ade47cfe816c1e57da6633dacc537de060813964bb5b2757a312f9da3d84e60aff98170051d3d90e380b8bcc1986c58ff9dc91e8827d4f9f5fc4b2b2e743cf9389ff02dec01f5d434b430d162e891c3355f91855339f8df58300e4c993ae4df8c4318b5c4bd05283ca4b46b7d2fb0f6476bf15907f50dd4141aa7acac9daa62eccd3a67357122060b6cece0446a93eb230ad93bc9a4d1b1efeeca1e3fc83c119785035b439509ffb7968b1a448b7bd8315753fdf04a256eca1562a11b096c90a36b353659cbde4420e17e90b94c43c7519c60641ceec056f897b97d6bb1861268e0dc79b7c3b6b7639c255bf06865737459126cb465bc1da4a043a1963da7d63":"29e4d7790e181b4767903fe0eb37757f33f13337c33588c1fdbfba0e655ab621":"2e59d5f30f73781d38255b70dedeeb38ae78df4f002c1f747c08deadc6530155":"615c55b2df0ca28c60a6b385c58fa036df8c4b2f4f1935730bf8f4f0bed13610" + +Nist Vector 3072 sign data SHA-224 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"54071aca28969749ce2e2dc855052019bec27d0dd6a310219311b4b6d822467b22b3f02fb8313993fc77c4af1d76ab9db99b0b2b78204aa45f4032a7d945f93d55bcb8a6bbd47f98299a0929710461419edbe1132dc22575f5afbe7078cf5f05b231000f4a0f9f367d9025ed3ae1786e0183eac93ea96b55304a8c2dbf690821":"4b2d62d0e7b88436737d03d6f64dd6a6dd0757021817169ba373e3a31bc12cb7":"ef78152efd88130a4fecfe235037de2309b1e2f322d4f4154756caa8f0b3e41be45c80d895de56389257c391307286be8e8709b80186e2724172b0f2974be591584916fc0e750c0caf83d839b5c248f5de658668665f004bab8ad310118835957c02da6ae9a2a79da039adc884f9eb8b62e379e27f549e7f8aff8ad2fc276ece15f0423528a09e31b26421df93573bec7a4d6c2cbfbe5ce0fce0702088fb384ad1dc35bb2c1c742d43d79ad136e71057cb9f22ca042e61d2c5cc4ccf5b75a7379922bc4fd88372d2a8f6a2750865f91c143412a3fc61e4ad4abd03dc1ca0fc4297ab107a1963533a3d80a24ae2ec4146e8265acfd4446fc28103c5047c17796c4148b8e658e44e9b1c259d63c97f0e766fba8d9a7394cdb734508bfa09ae42d2da3068e2c85af2065f618ec3f3c73d73a750c13644c96e3dbbb7474325af48d1d145c28d69f22cbb4a9073059a9c40891804c73a229f01cef0678cf4855d18f900f0253acd6b3ee53dd96c4c92afff1f3087eeb4fba86d2e9495c5f734a46ca2":"5af719a9e5d8567dc26576782e8f247517fad5ac5de0f7115c5158748fc73b40":"0debcf6c88504a882a0191e6fa4c774c10858362629428aff24c22e3364baa15":"53d8c1dbb3a2c1023521b705005ce6350bcf66c093588c35d768fca295a4a9ce" + +Nist Vector 3072 sign data SHA-224 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"49d5f20acf1e9d59a656bd163fe46fc868476ccd926377a40ed3d7476e9eb7a8a70c4b88b16e799148d25fa23bd0c91611b76c9665f5722f404fd90efdb8ad14b759c349ff6c830642d51076ccbdc57f152fba41c6a7f3cd3905fa7c857265ffc7596a64dc69490a932b95adbc79a3b4f21b2c6fb5d5835d8bcae5d44d912a0a":"4abef24f715cfb3ba6e39c26b07ca46b700aac69fb8df3c0e09be08df90e44e2":"8ff13022080316bea49b89a06dd5a971d86e0c9a3af414258a8f485088b66cc38cdea02cdd62096c00eb0d1c2ee662cff16f6d2d30440b2ad9e897b9eb939b1299ff879557f163f17c8ac60d0c6e998b3a044b43fbfac7b0cc30a579a6bda1b4ff598a531f9e37cc1901a7b08e794a7401d0f8ca4be55bff7b176321828575a477686a98b4b17266e101601f436e554b9e4288057970fa3463343e7e52a58ca145ec9befd7be31ea766ed74ac178bccdfee9d29565e7935e8d70c3eb091e3e3b3e6e77716931ed729c49b96443606098bd0810989e0e6f253cf3ec38294231b711b09a941609acc8976819076543926ec4e06f3e4d7f123c2b8771e54589e04524e3b4f950da560a25d12172d4ebdadc1719400d91cf0264708714479200c50ef00ec0e604909a546c95eb2fa53c65ee72ad53f149c938dc2193496db07af3b30a1f439708aa115c8dd47c81c1bc68ea3abd9026113c01eb05558b8a2be9093476f01247bfbeb3f2858b13e6228b98205fa710b6af1c5f71480dee401d7472d7":"5472e89286e6ccbed316fe7564e3eae899ed7bfc55ca7fb6fbc392d191304bfa":"19a73b049b164dbf7fb2826f4253617cf1c5bb46ffc5204efa00002a79e23c0b":"7be137c109e68f337b5a21cb591a87af1cb8681419f875ff8f041e829991fe28" + +Nist Vector 3072 sign data SHA-224 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"1190853efb7e04cd4947c1ea5b1b5d9e0ac5e6df1dd050877308f1b2c7e0a4917e588103d28c0f6e8b72d967aa06aca68a986d807740f2dddde7281e550af4f637eadf61f880c7351b486615096f6ba50d8754bbf9ba1c49a3485815ef06b3cd761b5586c3fc2b464c6fe12c160ab0f6f446fabf74212430cec15e75a57b102e":"7b2510c73ea6447bc319de79afebcf45482917042a3ca3c1cb1c97d1a1216b2b":"9bb81c80d2b8a601a09e22475d70d1dc5513409fb4668b176c76b3aa1af8630ac7790a4444ab823787f6f569bdf02b9eef5e7bb21a88e3d3296857e91919f3c473add16bcd763f31a2f9844d7cbd8d480672a036c4b104be66acd66e6ef0e8a744b3d878090d1de9f105560247c62153e117efa55ec61c177cd82f8d72c51d253f4dc7336f79826025619fb2103f91144f90f6a689abcc51c68affd28462578b183eec942058f48abf546f738940a6c26d301c4b90ca40ea49c117d61147e8683989baed7a221c4f22092f72b1ed604b6aa94ff6a574b4215bd6f8e9d7b638afa435a3346589a61b1d1db2989d7b45f3234545e8a22d605ad6cb036ef791f625d2c6a995eda3e0cafce704a2bf15ab5dfad0162104592d23f52aa0fea1f432f0a308d16a45e1f41f823262074e9173754ceba70cd8a370dbab1a14f84159116da73d3a9cf82594cb3af95797cf444272850589acc6bca471d076335d67c461db602395bfb17c39bfa24df140c0ac4388db0534a50dfd261374f81b310f751d16":"0fd7617bfdc671127a1d7465f683b98d8951a741f85d43cf5a5bef9232a16ae8":"587d7f4454d59418a7527570f28f1b07451f3baf28f5cabe0310c4d79e4253a5":"18839404aaad59ff24d6accec3b7cc6ac7003dd4adf96b77bab068ae72f25f61" + +Nist Vector 3072 sign data SHA-224 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"b1cb430c5a1d72788c795ab567a84c7f5977965933a5bf238058f2fc818880d25b4ddef9635481fd9fdd4598aecec3764fa73093a225d4e4ebcf01e4b75bdc1841dc01652c4d9916afa24b89c2d6854b72eaa7b1f3089d1a919210831ac80f99835790ce64abc34270cd4551d31b8f5348ce8a70df60b88e085a984acac665a7":"403b2137ade39c1e5b817ffbd0bc3448024089fc1925550b5b860403e7ba65bc":"a81a54be0685f33505aed9591f333a74a842995da5135fa48f5053fac29fff08afd9b901c3df1347204a3f133a7dff6b1adbab077526b638a63837d7844339d48fe107af08ed62e87de547ced84df9a2ccc45876b29bc5361ce8a9a21b81d4f85d3b671c9b44b5483f2610efa01751d3a07fd694e46653ac47ac64a910b7fc421f07e5de54e898789989091e9ed58b7c04e9e1dced60475dc693a0eb4015ed658110b82f8e720dc7afff69cea7b8e56b8a9755bf1e2933d083608377504cab52d38cce1ba82f84c26265e693f18cf52e930dc0d8bc9d41f4d28b32b7405cb1fce88a55be40dca1b1a351aa7d77fa6ef84c776fa301dba2e236933d89c8b944f53403414df0d434db72caa749fbcd566d76f4f6f0bc40e42a29aebe6210e89fa0ca8b6ac08a4cac65c590503533c3e4f1b3c5bde868e79d9da918b72d1b098a7278769546b78450e00e46dd400efe97c884db9612baaaeee2486f64cd8302a4c32d8fdb873fe0afffd7bb74811220b01339dfc5e567c766af2805ec1c30126399":"2c1ca8b5ce7247dca6173fbaf854d00020ded6300311f53ebec8eccef9570d07":"60d2763f0138076e9e0e20f83e4aa2e9aa352c19ca79e3726303fe89b12e27f2":"07e08d916c8a10ba269dc460ee9d83f86a7b3d98621bb7324a6a7e607238baa3" + +Nist Vector 3072 sign data SHA-224 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"3bb9430eea6979129be745d5ae6babd4966e3abf7d9ee5856f2caae6014cb340eebd28bd9f391eb46b3a2b8a4cdc224e5508532ca08cb104aff677133cf4393a20fe4499967dfa64515455930c659d43bbee2340b14a3b3342d4b9a466b889e850dff4b2a51d389ca32fb6a5f433ed93032be4e563695797b8c1e1e019184172":"0d3fc8fc4c59971a963e8e41d26a86499c962615c64abe011e88e590bddd3b0b":"75b765eca4ebde0b6564c3137f16cdae00eeadd2d0b2cb83cd1500cd05ed0dd16730c9501c8a353a64634d065f6137ffcf9563d96127906fb17d5a79ad291024a4a6fb7e7d080219a6231ca158b65f5202912ddcb8dd1f018c9b0e76b3a476336c5041bc502f8acb748f136c3d78cb2c429c8f1ac17b63dd7e9e57b607f9debe571459df3688cf4c11fa1e84533aecda2dfece05f4bdb268cc7b0c8fe7af5a633a83515ada95f31824d6a3c7122fdcd12f54992cbe64d1d6bdbd0ab5ae4d19aa52609750a1de186afab5a16398da473d128882b065e873809fae0bbdc01a9c73b5c6ee65857fa794a15058ddfb24a9a17a0408646f2009dda610c8291ae148a18c173f836b197c78ede5654895b45a3419e9c3177f2503a93ce526be14ad919939ebe3f2d07f006a0b022d6a623c6017f0c76619f0780531d5390d4239b2f900efb44c9530c7d9b3e84a70c904b179ad0c4f909250f7ccf83c5f42d6437cbc9f03fbae8131a12d33e01721e650aee91e1c893f5e7e039e0d585cd7cd7495c40d":"32d9aa04b104b5d7b59a122b368fe0cf476e28098b898662a78efee764545ea5":"7416729a1f60208b7f837480fba81840e45b338ab9846e9bbb9168229f64bcea":"58eb904076a3ac6907d750ff6cdfaa465435e9982ecbdf72197b09bb6df1373a" + +Nist Vector 3072 sign data SHA-224 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"55a69fc16f6b753d0bf65e844d067859f51dd329279980196063fb59f89bd778a9244f932c2adb6811183612105d1c527e8302dfee5042cfce5dbeab165a396f5a4c21339be1021b7ecec66f2177f94243ef6261608c56919679d44863cf9d2afc6010fc2bf821b931ca3970d69b1e622a908389db5049d718e357071063aef8":"3dd224f00ee1d4648c600b10ba05ff36ad2c06ddc5a9f0112e0331ae958f36af":"6146a51deb79957a83b2c7a3204b5c34ae4f8e0db60f0c07e70803f22bf99a39647263db9e285d72f6270ee10f18584c39081d2544d40502c50df1e35a457600b5569d61e8126c055f7b964572e9f3282e4d9745006955c24261c68d7c0cb3f08b0b0d8eaa971e1a631c68a3a914d35efe89f76b9c2116afb7bd1989e202e092b5b570eaefcc933542e650d92c033b5973821d6d77cfc243f744da80b56eaea7650bf50802516228ad6d5b0d4e889c575e3678ffdb1c289e59d9ff7f84a3d63d39d6888dbe213e2c3b3114085e006ad74505739fce826f963284dc4e2b01ec2f9233d3470e82d872ed944e62961f64134e8080daf2df494a76240ac0cd22f9afae7e80d3cf3efbe055147f62ff8c6192e388b49e47d9feaf19eccd65dca9991638ebd7b048077707adab1cb2a4358eefc4aab8251fb0f9d5f0b09f299c720d3a8c00a5a4d84feec040057040b709cc0ed185a832537bc4b2df0ec1f77169ac96e91282de21f342d5429ec3d66ad9d336c440949a1211217bf54aad93bb4b0a43":"7969d08c0cafe4019b64ad3e6614be0aaabc2c2be61b3b3dcdd10d5f75fa24bb":"136f93dcc7d33e559b8db0af13e00c7190928bff5086eedfd11706e6f2349ad0":"32b95b9b147c7d1ac2a2f0057fc0538a4b7c9cd4652e6783e5d7e3534655631a" + +Nist Vector 3072 sign data SHA-224 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"1567890c69e578a27d6208913dfbc20eddc61f5feed457400693dd170f8067bf290b11150780684c20d5cfd2bf1d536dd3b70025883fb41703436fd09c0a141125784f9091151303ef80cd345e5a7d2854335c2984538c5cd739b007248cd99f1dbcd3148cb0ff0db633f8cafc7a0b99c61e784d0303a5120307d3fb3c4c219e":"3ac374b2a4940d92ab35ebb8e59677fbf95980fe632ffbb1db4f385ee4e13a15":"5c53d13a1bee17a28720b7089646d07a3fd58b9b2b23ec94af3144830746177b0d2073707b6b84901ffaa7a4165ceff2425640fcfe5d17650a44a168ebd769c833445f1b2d26434c228c1e2edf1704d711a86257be25235a7cea1e5cbac412235b7596d1dfa0398081a4f18151cbb51dc62c226a2abcaf3335e86ab54608040ee814e443b64398213ba60d7b5a3c8ea78ec6b98934c89aca05b97df5f65bc574a30acddd09f73cec14528be49a2fbeca70291b1b29f7042c594994da128fda22b3ed3a935a1a00575ff1ffd193c4cac53a2a2d4b0c510228a76a74333607d15b568614427144b4174da358e383f658c60b45710036f54f93f17bc808b302674e838c1dfd7f816f7ea44b0d97386e4e1634c9539568dd6ae1c28f25b27aa94499ae389a0926c8fa62956c6e24dced0afb0491dd9fac0516d27fd4d2dd0150ee6b4cff7bfd575043d701daad0f1b942a0e4c61956b32a68c9078f6077fa9945198d447a5bf3c47b7288427edc6f99655aeadf8de18515714c6b9c0d4ce5ab092c2":"7ca690c92c8d4a3ac1d5255a2e5a12922093b8b2ee95906eab29b67f84fd21cc":"4947d36e7426f1441be5a75dc9cd845450c61104f19ed40ce33e252fa2c26268":"356879deb1daef01da04750d58e598db47aaaff50b1cf42d87334a615780ff8c" + +Nist Vector 3072 sign data SHA-224 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"4f7d894dfb7d82040a9fed6c26a7d27a9a1511388c113c64715a06dc46fcf4f904070a6ed95bdd8dc1730a27645d37eb3b02847cb1c631ec0c67b2ee07b8805b34dd9b84e6ab3f9afb9246994ea579567a8f4af7feb86898cc9cb534c387993c6ec16584ac85bed36bbc2c305770f21163686167dd53fe562362ff549d903539":"2c14cd975bc163f9740dcb4a5ba9d8529c5a075016e02400dbfede8dd4f0d245":"00967478358d7c1696ceb92be850f5538ad8543e151aadd84caba1b72f3636a2092a86b6462873903d5bf17f612b45b5133eac1630bf07c0371423d2e5d7147ceacc9baa8cb3b04cbc3cbda429ab40d7e592730dc477b0a95f1fb5ed5d91e14b9d5a1ac8d403a55a658d1c383bb598053be238cd82386968aedb811586fa2a14119324896f2111b9bc7cff666d37affe76041d98f362daa09ff65e82e865eb29c5d4710ca7800886887d383da0cb599b225fdd210a3d70929d35fb9ca807e56c91c0851252b95c07b6b120b3b650418e0f54f45736f82018d09294462dde6eeafcb15a2a728577faf3ef3eb13db044965ea3892f7eb0884e47766089d2a43abc62a3c375831c20848dfde8f83c249a8e27f2897cafcf5a06b7c3591e09b42f82849d498664f485de26c788e559ad5b15f999db927f81f54b96e997b9096b2a7e3e756f5a9aab54c160cfc2e64492179487c98d0aa38308d67428f3a113228bc6dcdf7ab93cbb1da225c72c636f49d27442cf3cf2f9c49b90ac8bafe740dbbfd5":"141936264e075533a96952808935238d715e7cbd840c016ee7a9f508608e4808":"0940724855a0671d60147dc61fd283190134a68c178114d59ab58da73a1c8182":"43f194b97078dc9b84c8e8e867a74bafdc2211706ae110b5aec0b99ede1ffed8" + +Nist Vector 3072 sign data SHA-224 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"9b62a74bc49ef4ff5c62165e7d25521f135c836bc4ef023fb4bb1d6b42c6291071eae0b465c59231cb297cac6d145875fd84f5729f79f92218522b9e55cb70d471030d36291a24925ab731a2d4458cff677079d207ce865b3d5526009238861d64506a92b76baff59b37b863087558d5965d76685f0fbd1fab1b1f9561f8f69c":"70e12e51a254831bdec081a8882e5a24d78b48b6dd163727b93f803734e06a3e":"75d7d9a5dbdd47cecd12f69ab212dfe08a9656e2bca92c81db2d268a293a325e511cd5aa1ba59deef2ab6311665dda58230d48f1416371de1a8364b38f5ad599c472d363a18a2c13d572cf849be2fef9a166e838aa58b721ecfc4b361fdab1d0876b78e2e8f23ef1c82cc0e1700fa015a4007b1d7b535c82d23c129d1d1c9c4afe875a06c05f71f078cb8d9060f4d936671faee217d4045525d570b0c8ca0c4e8b55dfe9b780ba69c9d8cda10c50fd61c4e7214b943c1c29797b099f57a4c648597cedd9d909bc584a9b754b209515dbfa0fecce2ad05c848e99dca21a6d0d5f2dac2361e4c0eaf96df199ad2888d671974ef05d65c92788434ab42f1f1f79edc49ec1fa921395bd0feb6a9e6a0622e8255b0ef6937b89d0cccd5852872d2b0ab5d79c2f198bff6b8aa38acee21d6c3add5562d84d968758d93e8c1d611f7d6182b62e44f57df342899bb564a794d13915882143d9df45f8f21cc030af3397e9e949683ddd8d8da9909cc1139619e4b7b252aadd02c66a5e20105adf26f2f021":"5de7fe70b5c60ec0ba66ade4fb6b0c925d1d56d26d6f57c5d12d07b5f6f800ed":"01e3de398b018a694780ddc6ca12b78dc55e7ad9fdddb5a3f5b2cad0103253dd":"03c98280abe3050a67f88ef29fb214a80124f47321c62e41e3905b8532f4936c" + +Nist Vector 3072 sign data SHA-224 #11 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"6c66051e04c2e6aaa43de9aa42cd9f61e8329c124ed3031b67452db4c435db291d756ba6ef90ab06307cb8d70f3496792e633bf5ac985c37c43bdb4e455c7f761a5ee450567f85cc977e968e7fa42a428c1a7e915c82874865631d8078899377255947c344618297b83c96114d11d74d8cd579b553667cac1d97aea4d1684987":"11d2f10293c3884b1e28a600dd71b2ed37bea133255a0f97e641f9530bb4693c":"ed2e10a44316d677467d79947bec9e405d30f32d860a1ce46b366845df9ad222b0f992f5844571b196a310d587fffa74bd510215f3bdafa1c93d1b1315246fd2f794c4da07bd722a98dda9a02ad4255b6d5267738256cb8639a145c28404562add2bc7691dac12600ba9f8ebe00614ee3fc6e6b2484d9c5c7090b3f3b134ba19909864563040fe8752d6c6ab95111fe1014bf7bbe4e674c9d03bb8d229e4b5f6a6e471c678b0265e88ccad7960fffae700f3a75e61a24ea882b970535eb7017e16c48ce9e2bc8357f7f0889c871d0b4ce29d279afd1d114998d1eb6fe4a5661e429b1327f0a39e9ef00a41a74fe479b90fdda21d9315555afe227274c11a71c0d10c9e5dfc89750eda53c6a8b52a5272c75526375e5fb91ff75d028df7aa2bceb5fdf6f8e3bc1ec3f1e226d04df1d842e4c8f458988cb7415f0d2ca4498b0cd67e8b085b008fc4ca064393a0df517f0b4833ea4051ac3f1de5686dccb7bba8bd939092d6d78fa08f5bf9bf6f13d7aef72f047fcc47a88223df6e1a62d218169f":"2621703fb8f5094bc68eea72d5b5caf26f8ea3a173158b8d3e7f9565296767f0":"31f2c86287e572ff4d07421a58dc7b3d727de113769952b6d8d736088b36a825":"30acbd1c4cd6aa666ee52b0bdc41fc3b239b60d57e279b3f5483c4d54bdd97a6" + +Nist Vector 3072 sign data SHA-224 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"5f8d7f283af00384a519769029d208b61eee0e1cb21ce9fb80e9d8596b894580da7ab3457429e72dfa64e7cb839414de344da21cff55b1b3a83189d208ad2089b35abd78e2416bceb66466762fd7ab9c234c4aec3872cbc8443c92b8ce4ee4595425e746e4b6f7972ebd5d065fb3fdc5e329e8a87ed3cddbe279d57227ae4b13":"1de925bf532a50dc7a10984bd1dbd90500ec9ad22df0f2d6f185fd1ba8060d37":"aa4d065270c38bdf996b1f5f1ee4b67a76ef1e7b134ea21fd0a6137521245052e74954b96544c700d40f36248ff29a712a098d80ca12e28fdd7901a622dd0988e1c4d67de4c497a957882ce992fcb08c5b85c6858447ed6fcbad26d8c40485f0a89d9d020fe233e89319038455644c828d608df9707c63170dd0618c0baef3eca8d1455460a2eb25faff444f803bca297bb680e5f0fd06e887ed50c8060f55d0160ec64517086f4e1d624ab7d12df1b5947017e622ebbcd6f4eddb0a41dcba82743efdc5804288d2863f54003eea12753246e6e0357df05501b195fdf3a7761c4c3acf26537bf98b32f2e72ff1e0159d046bbc053171e3d518344f0537f2e7200bcdd957ec96365caf55fcd246afe771709ecec28348a356a1d4eb136a176adb5fa102f5fa5c969f90896462e0677afc606a948b25587c10316d22e1269fc64f915a796c965b8be97e5beab047ca5198bf2ff856df740afbbc1aefafefb1ed47278b150e6a7222417d3a86494bdb51edd0616899526c27acc2a818e83baf579b":"5f0d6676776f40cfd5ca255fd8e32b10bf3472b193818914876d4c3be68a83b9":"7187cae836823618f9a6e847055ca2bc38c86e726d02d38f4950eb6b71b36bcb":"21f6ff4175765430e2dbed342a85d30056b28905744ece5dad79755ee3d7bbbd" + +Nist Vector 3072 sign data SHA-224 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"b216a035b0ff29feaf7d4c34eeb1604155c90338006753ee2b36062d72f62b524504659f70b976c68952a62c2b9a2a00cf0066a5e5098a632df2ee56dd1a140a98f7b3ac12db3576b610d76563e4621637da1098aa20f3c83247b7278860417cecf7e137194cf1bae12bbc63a7bae02c906d503f694dea3bd534718e37704962":"3bae9330b47aab85cec948f944ac13221ad35d859de56db56c31aae88345cbea":"7d6b3b71b1415807d15901427e6ab002ee985ce7c8d844969c6e7294a2167b4c26171bcd646f0d1bce14df05e4ce58a3ae50b2aba5fb74455233fa6d179a0794cb26e92ca910cd1c16e5464e8fa7ba936341d3ac211ac1f8a2f2a19c148a1c3d6b00ac44c35ea345a3ff73ae9d5abcc6ab65162a53daabdf6da25f96958eaf89f559895cbec52351394f9132c9564d61aac792640f11e09aa6f6cde9ee9ca5e05fd902911163817177bf054cf2eabf7ce8f34bb1c4aded8dad93411fb276d2d0a296799661307de579641e607fdad058d9a3f194574ea76f4bec46bef8adc5d62c7390da1c45f6fc5d9a784f696f24ae7e6b27a809029418dd18a420455c2cc9695e7c0fe00219a1711468e2866b71f3f9c538789ed2843f44f2a821773c52d211dd1333b5f164ecdf6c3ffd71de6678b0c272f92355d5974eb21c3c8fbd0bca7538bbd9894750b1dd0142bea85104356f9a515ef1ab69daed98d94803ac912c770e26efa2fa0b04e11051ced2f70f06f2f05eac8029d68e12261657cf4dbcc1":"248048e6fc52c48398f5cd2ccd8a659c4b7b76dedf54f3fb90c5bb173c5d24f7":"67df1d510d063c9067e9759180be470c71fe09c4f133aca181bdb47bb87b2097":"7328b887bf0d520abe6f24aff2153f40de009e2706ae043dd3aa55521d9572d6" + +Nist Vector 3072 sign data SHA-224 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"6c67116fbd21a0e3ed16b3c4ca58ac49661918bfc6a7c3a6acdbcd53dd4087034fca164df8d38f7ef7db03363701409246382ee053c69c84fafa3c77ad2ce08dc7f41c34a31da496d070a99435799f269dc8effd06d31f85879c299cf7241b37b9a4cfd545086393156737cd9da2d282e7d569fcfa5cbde4bba51bd89fdcc913":"7fa66120c5acd5bac132d07083d07968b210cd9c26c2c56d9b16d98066f5df6e":"6a50d1125f9f3fc2f7e023c093b3608e6972acefe29c0c6ba07a2f61ed747153ada4a9b680622a842b9a820119675620c11688700b855d4b8d13bf726c36acf923256fef1b53093622d1bcbcf023848b8b8f4abf43bb6e87b84d061deb75236224ceda914b18f7ceb72708789dfb94070413b0e65c1231ad02db42decbe0e558aea06c310aa1a8d113be1f071482fc61913225f007b569b6e867cfb392725776ad71f50dc97b834a71375bac18fabf781126d06df62124064e6a723b48635e6754fc767a5094d0645974041591d0ad4828f63783356696af7ff77cd00107949fbff4709dff8a660a413f5b6c0df37ade84fcbc1d3253ba617265a10cc087606130290909a4f813341efdb611696feb5bea3d7d00a53a81f3a2043b887a776075d250c1a010ec47660087f3ef05782dd21d298d6d37559cd473008f474d8deca6817c1390180276097a81f462c0527928f93a461f4ac2d6ed8c9d6d101a2a9a29201a83d0589f57be28a727484518c7425cf5744df396a0e14a4d260a5c8d29bf":"5771223a25f539c80481baebe7b2862156fcf26220d6e953c37f2a22bce77c0e":"7d489ab0d44bc73271ef42e28a60e1b7ef7dd27af4045546047085da408bccc7":"310151d943f088bb7dfdcd52d82884a7f1ee64d46f9d600d23f52f4cea4d2862" + +Nist Vector 3072 sign data SHA-224 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA224:"f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d":"80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1":"8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a":"c8d416c1efe686637078122f798d8804f64a6e85e05f7e8e07634a309a98e92abd54061cccc319f1acd4a087b1d7dbf0b6bf2a09c5dc508ed14dcd5442056eade7691b7fb65b678ec2e137b5fbe875208a427c2a7ad90665426fbcbc7655e48a8965d23fdef11ca8092f511207a607359f94e91b197fcc993ee6ce3c37ad3b71":"1f4a3cf1fb60360db3790a03fe55194985977c6884a5fc05a6fb5eafd53587f5":"cc9b9d0292915d631aa0d9eb6161f924705c566ee09e74e418d88e6b67b7f57aff5170f6c42a839ba839402bfe517c287781dc97df2e0550b3862484d253152f6cff895f092358b5c4459048581309eff2f689230b4c4951db8413573b6eae85c2dc50fd6134461328e5b6439f41442b91e3a34204428d1e2c22412b012242b14f92e2d1bad626af95051bf06c74da4081b0d619e136a99c8da3a91adb3b8cf8bc5964ff655d45c75ada253aba91c64095394c701c53ddc11f388d61984c32d4326a8c627df845b4100f171bbdb252d3e28494ac173432dd5531e03040302aac8c07c9ea92a9ab67faf0c78b3ad8d454dcd428f942d8ce6e29873049fdbfa1df0e6ec224c9dd066b981a400b1f5194fee13cc5ca7ffbeca98ed0a0221377a1ae612740fce774eeed68382b32b686a25ffc016682186448207c4d9783e83da20a5e8b228a134dc3f44ecc565ab9ae162b855ecd37e6407e714045f4e83b971a5f4e304cd778f3d34137745fc6ea15b4b74d60176ef807410b1b26f68ea14f8f91":"589da8a8ac79ad6b62b353422691f35e6474e9c605d877670dd95738b4935f06":"7fa51231bc845fa8b668393b78a7b0408113fb77c1e36f3c78c67d65715a8b58":"730c9e3483811c52cf295bad042acb5dd6ee90083857bee95b6392b080b5041d" + +Nist Vector 3072 sign data SHA-256 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"cb06e02234263c22b80e832d6dc5a1bee5ea8af3bc2da752441c04027f176158bfe68372bd67f84d489c0d49b07d4025962976be60437be1a2d01d3be0992afa5abe0980e26a9da4ae72f827b423665195cc4eed6fe85c335b32d9c03c945a86e7fa99373f0a30c6eca938b3afb6dff67adb8bece6f8cfec4b6a12ea281e2323":"3470832055dade94e14cd8777171d18e5d06f66aeff4c61471e4eba74ee56164":"456a105c713566234838bc070b8a751a0b57767cb75e99114a1a46641e11da1fa9f22914d808ad7148612c1ea55d25301781e9ae0c9ae36a69d87ba039ec7cd864c3ad094873e6e56709fd10d966853d611b1cff15d37fdee424506c184d62c7033358be78c2250943b6f6d043d63b317de56e5ad8d1fd97dd355abe96452f8e435485fb3b907b51900aa3f24418df50b4fcdafbf6137548c39373b8bc4ba3dabb4746ebd17b87fcd6a2f197c107b18ec5b465e6e4cb430d9c0ce78da5988441054a370792b730da9aba41a3169af26176f74e6f7c0c9c9b55b62bbe7ce38d4695d48157e660c2acb63f482f55418150e5fee43ace84c540c3ba7662ae80835c1a2d51890ea96ba206427c41ef8c38aa07d2a365e7e58380d8f4782e22ac2101af732ee22758337b253637838e16f50f56d313d07981880d685557f7d79a6db823c61f1bb3dbc5d50421a4843a6f29690e78aa0f0cff304231818b81fc4a243fc00f09a54c466d6a8c73d32a55e1abd5ec8b4e1afa32a79b01df85a81f3f5cfe":"3d7c068a3978b2d8fe9034bcad65ad7c300c4440e4085de280e577eea72c1207":"53bae6c6f336e2eb311c1e92d95fc449a929444ef81ec4279660b200d59433de":"49f3a74e953e77a7941af3aefeef4ed499be209976a0edb3fa5e7cb961b0c112" + +Nist Vector 3072 sign data SHA-256 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"0661c1bf79eed78ad4879e240a46b95a0db2b29bf81263b9b1676daa2554aad7222c9eb7a893048e46fbd2826ab6e8cf42ab0cd631c4c4a1a819560f73cc861a5b6465cf2880a730635ed7f49e28f7b565768f029db2a443ba0a1bd10773f26f752c83da40fcd33f32f78d24ac9820d0bf70dae568a12538affa867160c81e39":"807675fbaaf0b6d6ba3d82063cc07327cca3f3522d396fe5d2c6599045d668c5":"54b6818054cc000c3af61b62ef4189ba35e04845dee0015be6273392c67332e2e04510cd5b2bbf4723cd8196e025511f6623f03607e566484c330751d03c713068a77e08bde907fc57b3c021e37303373d9d811e38f14b547d2bd87d981269c677dac6ade6acbbae3014ebd381b4008637031c9b6d49ca908765472b05962f55aa361f7dd5a4260705ff5ecf7b317db1fe5d33fdbf48e6a33b3c78b14e620d93806b52e86e082fe4f54d5265e8df623b0c9a259f61b7fa2c0455fadf39693ef3977440f302067c3affbc4574224d5a22044e9bfe11d0d6ede2739c7ffe9277c8644d46beecb946f81775c116388fd6c24af02ec59f621233efe8792d6d0cd2c84333b11f07657333da4e274b8cd3914d977706e786f325e18a339b805c51b45eacb3ce241845970acb9fd1a482a564b2aeecdaeb0a0db39f33ad2991f25cf622bf22f0c4430cf94df1db59aa2d7c2004b5177b9ea69ff556dd4c07edec6259ee139b421573a11cf85d11e245e251190ba869c9cb4daf9f49451a85f38b9b903e":"6215e72ef2d6f6e040b7b6ef4cf566a21fcc4f37783a68db445c1ddf3042a150":"519fe4c5f9b7707ae4b36217ea1707a1871d8fce98eee9e643c45cd3eb50c5d3":"1df224af0b51519e11d8422999b1d3ab0972064180ffc3f1114c9f876a1de3b1" + +Nist Vector 3072 sign data SHA-256 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"1597353f24aaf515fd7c0b0a7453444d5f329d6c3f099113bb3a13309b053e6c123a56227a81e8b1a0c8ab4b46160cc5380df591b19d8a386d29a8e43ccab5d8c0e547fba21bffcf5ef42efb9fb2e9be6297c03d57da0b5889b3b9742ddc2c54b8373fed1f2195f5bb2329a8f1f3f8afcec25eb152e7fa819e5d36cfd3625239":"169b11d03cba7e817da27d889cdb147ae9cb0459359bbf85a367c64c2ab556ad":"5062aa1fdc67294cd57623cedd2808303ceb43537e3abfa1bdbc492b1aeecee61b1fd96cc055d1459ab52ddc3f2344389e5f21448a90cb36e448e60787b1ff5ab6e5549a3921496e8354646bc1fd6cd5f2359ae299c0a047fac3920512a1f411c438bafd03e95e538c6e21d1dd1f15a89d38d48f26305c2534fa8e31d054dcb00774138fb8fc61c6a8d4ae1ca46430d0e31b4b92dfb15bd6b8739fd537101e77334e6f3ce5469e82a8dbc58b3be5ca370359f4a6132fe03360b8f6be248c34220a8003772648664059f1f6a322e0c122f427efdb7d640eb5bb7f3db2d967a2159092d8f8df333ff5ba135602b9ee7e9db6ae0b95886df38d4b4a26a4b2d790c24fa214cd68d0a7ede63e7dfacaeae14d9785be693ad78d88242dfad988b7122adf5afa9efdd0c2047470c607d47b30089ff8bfc4cf5d7a8ba69a7d0ab6c54c05280d66aa4019f6362ea24a1d3f8fcd80c3eb20831b6e0db010faf826488f015f63f0b9ac6df72883efd286f0532b5beff1b9e810ff6a2b2d328af675eafc2f56":"467e04dcd564f36cfe47c8fb9fa09cb142a99417a61797e047fcfd51e16e3e00":"0502a6e1d8c8dfdf56eb67f9a6f6605735e4d1b0076c8b08b61daf8e7c2bf2d6":"7c67abdcf4e580812b13d0a4edbae8a2786d6612bc866e3c13bc09f3e96616e0" + +Nist Vector 3072 sign data SHA-256 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"715f296930312368a2a98d3f42810da57115f00ffc4a12029c276b10629e6bddd60bca2c535b79a5f4a006817791f7f3ad2e01a00216672ee5adec579deb07e9d2b0db222c4e01e1f819c1a52d101b1ef678cfca85655dd6b2426f1ac379a92a9c69b0f8987432d109cd9a7bc04ef287c2afb663444688601ce3c55fd90d0fa3":"4ee80e4cf46b4e072e976893a2d1e34c03d20f3aa1785a74564d6b4654b11a54":"b63340d6a1955731283064f6f22ad7f0e28199f6a58c57ddcb44a026c61e441318c4f8755dfd71b295e9e7babe000849c972f68d4be00954a3c29cd4b4e83ad51830080e29e7619e45d3abbf9d82fd87e97581fe909d3da1e3e96cb3f0c893af9d07f418df902e76b0bbc1c97139cbd51226ac442b3d0b0525c784ba138131421c60543e6e296069f611b9c37cf6030636eecaf41c3b4838f506c02cc84cde6b99cabd2ca578449cc1718aa418ca12a2b76f78259c1691e0b49f09dbdaf585f626cf74d73212b3427845c66f2283b60703adf1a262bb8b10ac7ac5d1ec73614fdd37ee51b71cd1fb4e6db8938382643c721fbc4cfc987bc5efbc81299b375a560cde5adae62831ca4138c399d82f1f8bc680f9c6b47eb464a1e0aac448fe3b5c25bd8c0b7afb701b0680db87ab51738f19f5b965375dd48daca07bff3885632175700c678619f194e4ee5f55aa448aeca7f7b3322f64a547315c5cee045122549fb38b8acc95da5e833022b3b894f03ccb7f73b91c1fe82ce414e1219411780e":"3d7728ce25def9a31dfbe442fef8b162b30544065d9cb7bcc4914662a282bc10":"4c5e990a6e24feddab48d0af4a08b45ae8092594bfb3c012fa1c325c977a3cc0":"820b6cafa89b41c4ccbec842d7c408c65d4998ab1ac6b6bce8d4d569cdf04726" + +Nist Vector 3072 sign data SHA-256 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"1fe5ad49e11c207d3d5e1923060832afbfc0aa0cb29fc0b22b3be59a598f8c703b9bf2c7347f8abde25677ea9cc60af9307d21d301fdd23c28277fce11400310033962c04ecd377fd446358a3449efd6bc05721b784ddf0e238f28608e86bd4c3d7ac631fff8be0678d37bfbac16b75bc15a50ce1397dd4ba3bffcf94d341274":"0d690f2c87fe2cebc9f15546f05afaf6dc843b80abd2046f33de30c2e806358f":"53fcd07399e4d31b09abeff2f096a7b2cc5cf417dee1207d8a5aabf9e8f9fb0f66be48826a3dc11e39beba2ff47b76544bcf55485acf1e3d49e19057015e49ed012a4877be741607749b6f4bf95c44ec3c9e8b893aae8d80e369978a3580371cc13de8e714092bb892e4a956ad3654032f7758fb9454a1cb56406e1bf45855108ee960107a65d45453cb482dc19049b6c83bac111756caf65bdbe5e6b270d5875b997a1722ee9d58384941aa40e810b60b83412eafd0a7428a0abb55df45680cf22656711db6bfce8bdcbb4c083a401cdb68284e0c7ec00f7de74e57146adae221e54cc4a566b05a113ddb22cbc19d881a41cd75de8cf6c7b89a5fae650df585aa70c045b84b2cbbccd0e7ab720c5896abfd356a66f3dcbbb5386be6d02ea9b3191ca275d22248aedc360ecd4057ae06ab2c2aafb50657a91c62e038eac9f5c4d88106db4c6926fb5dd2de1ec7e4e005ce184570e7e97d76422fa037621a6f6d46cb83ab6f4d434b6a8f073900cb03a7810455d19e77d4df624d08e782090ffa":"796cef38518aed8644ec5a1b3389da5ee9b063b88e7fb4602af0709999f9a938":"41a2c955f41413a7ab067b4f50c61e396f9febff61c1500b1a4bc69e50a51935":"79edd751a9dc2372b40580fa4d538fbe2cda4149f6b11939ddad92c574740883" + +Nist Vector 3072 sign data SHA-256 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"a326973093ce502c16473d89ba196507d92281504759cb34c6cc353d45197f915b5e736b8ff857a8b2ec99649a3224f857401898c9ea607e6a2c1d320f27564ccff5dbdacfd87a145f1a029425d76502c081ac0f6a14de5b2cad1c23a61d4e9ec6a04e1a455fd710c3c78c096753c0b7f1511e8ba5f5f1af4f0741fee88b77eb":"37d0fa99e5eed0fb51c6e690f0ac556ae74cab9a84d887a07363599b198475dd":"92915db21c2c3e57fcccb7dfdce28a12aaf6dd10581193b98b7d51a728c38516e39ef5cfb1ff9fa1659c9bee56d4ebc1cd69646c3cc3f7caae0c42d9cca9219148e4998c2ddc89eb9a3edcfa6f457129007a9344013dd123aff197bfcd3db1d9e2199bcea16165a4c34ed2ac32167abd167704ead31d5fc2860b834d44f86cb530dad9e887013ca4d6e883008c286d206b6c7cb252d1328b503ae0679b502ec1646f69f2602d5e3d631d4a5a63fc7a5d06f27926a4d6b1ef2f77ddff3d850d3d9f58a958c3f4f12cf029f148386c5b8a71bae9094dec85279b1e387799d26b2a6a0e0dbf06497366e4903e559e70975dedc7d4934d4e2d3d2cd305ab826402ea8f2778e26625119e7b0c24c45dd9c05a3890dd1d9d930bd0bb409366b07a47ce572ed5bcd5f63c467d49c56811fc3e401341b9a4531f776debdea540a34c7cca3c3fb2ea99c5fa9f9fdfde918a94f74e080d1986b68fc1e3fb978054872ced97bafd96731e6d4f1c4a91278c383d4761c974100974522f7b6e8a2884d5b3bbf6":"0b5c9b613708ea26bea151a0dd4222bb573d950588483483cd2b8ab537469e53":"73f1922e26d9b8068b68f83c2bd5dbbb5960403b49223c02a42ce6cf3810db66":"3ad30be9a60f6d4227039456c9827d5424858a02a8e6d3891772cf80a5e4ee21" + +Nist Vector 3072 sign data SHA-256 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"7504382fb7fba1dab3c93bd31b16e73d9ae1d027dd23166b3b94c7124183faf3963c420be5205a1f44a9a9026c6ef77e7c4ef1ec4845fef6e5ea2487ce012ff53f9450fceb0d3ac62f2102d717e3287db3714717a28cd8b7fc64556a86173e6e7f479f8a8dcd895429cd7f0f5304ef6aaf275d94a7f4b30acc1071787ca5f062":"1c21aa2ef3b11d31f3c94a278859cb74bc40daf5993dbd774b32ea3ca24bf162":"2055bbe89da0a0c488c3dbf29531f1f7cd3fb55a26efc540c2eddcccea1615dd923fea4c8d0c95a5af7e1e7816048f2ae85323a96411e7d1ad62c4ca675b63df9dba31c1c76803fb1c8292465ad0a7e49ba3756a8ad4c6ce86fd30b8b28e08c4b4777e079faff10ff852f7d891a984198dd04977972108c52ce8bdb115646224a79337746e3647213198f1127430f5608733d88204a62be6eaee84629fc7282acef4c4f5d3adbe72410b1edfb74be16b2d675cca891bd8cef205178902b99271b48041abe33ac119ad6b756a477a63063aae8a17ccfbe2acae3c0a3c630c13ade197cf3d05a9fa9d6899c0a3f9487e6148732dc63e907ef79488df3373b8a213705d69dcce6ed9a2209f59ebc58bbbeb08054510b5a65169d0fc1d4d10bda68aa7eceae2e72f0339a2eaaea08303064dd6588414ee7705df3ab974debef588f4e31fd6a8f25979c9f521d2343120e40794f41a4601be579183b877e6a8f6c0ab7ce8480e7fbff467a581df570af89929bc4b56397b787df4d729e65f9b98ee7e":"44efaf7a15a1eb2a7ba04fd4717e938fe738666040b3d81560497ce166f31e86":"56e21a7ab61f9eabbff47c75e5f68c31873a9e1f2e1db662731182f9a029b8f6":"2f24c52f7baae29c0b4633a3855233180eba80611dbc7e88e23548a520b60f66" + +Nist Vector 3072 sign data SHA-256 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"0c0f7b0f9955bb54f16e4e39ad9bfd1deb04b8e8b38e674da455696bdf7cf28e24114ad00513d8dd4e5c895d351ea913fee516b646820087721d9a0b5ecd769b3825739123544e7058b66d2342b04462d5d173cdb00ef6aca604aaa438b8868d15dd6624abb8d19384db48bdaa66471413a894d3610bc97d848a59e2c69c0c0a":"34651f5844cbf85960e987190eda4ca1fcf32d8cbe1ad08dd5aa36fbd0d42000":"45ef384ed817386668e1b90b42f1d423ad9b17ea870119c0932ac2f515f546a3b6b80a612ee66dfc00cc4d9e3b5dd15303d5ebc0aa40cbcd7746f54a3ffea23aea0704ae9cf5ad6145629c61d158db6ee39ac899bbda59794b1769a92982082b77a1d48856427b78bb6e077e27335f115bb842e53251f699f04488beaf83a6c4aa6a4b76370cefc9099c0a45bcf973242df2a01ef68e66c87effd7f98f441e94a09a2830076c2895f997afd0a909b45b3c059177000236c501bfaa56da800ecf08701d212016b525f30d63ccf3afea09df39e1cfab7bf45de1a39ac7f28de0037ec552e2ea10c6b56a5db8c13fcbf73d2e50d58b4f3cf278506f1eaf0873e9ee9465cbaff4ae626f3aa109fce49e55d57fe881c50f7279262621282adcf379141c9b2c39813faf823a7ec077c6e6bf953f130aca58f36e7a87ab1aaeea5eeb4402fa9e26ef8938c8f38a6c040809f4d04c81e2948387d7be813a973a9c95176700117de2f33e61940387f851a73dfa4ac5c984ec97918c967bfedd886d1bb705":"52c16c3e7b17f3e73d7965f584bfd7ca036423b0d42cc00e58d1ccbc419d33b2":"77563b3b48fc9ee0dbea79fc74dd6c69b72c4270918e6a1be2c998177023b40f":"099cdd62dc044a57ea25d1b5c1f6ed84d11bacbb0975976d5821c414b5416bde" + +Nist Vector 3072 sign data SHA-256 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"c67735698ae7bbaeb6f321a1088617382a5c92092151ec364582962c9c0ed9ed8fc790cde0d9744d4e38970a8482401c0f61e91805f4984b8cfdf9dc8093a5c6681dac13809bc41d167d3e11bc99698a4bc07fd248a67491e8641081ff1e97871745157cf930195a35a14d0883a26db442e4edb962aa6187b8d1c7791d61bd25":"2ad20d2e78a9ec234f99a4b2ff52faf492c3e3242ae6c04ea8a37d5f10fce6db":"0d3b3c3df072b5f5129118132bb7bca3c52f51df36767f1152387ec00df65c728f0cffc1cb6f224258cb6d3e90f79dd976b5a180b83903d210f0c4dab82eb72a1f8997bf09301d0f7c89075d552c81fd9585b0b1b1291744d21bd1edcb511217c2962e1a6de9bb01c2b9698ff55ea75dcfe456be481cb6f064fed4bff874eb1c9b7451979f7de7011baf5a47c976a179aee909d25ca87fd5e3c75df778e21272937c5ba7806aefa70647221e5f7cc32ab8015921a5a95ecbb3ca4b667249d0f34dd2d8ba86dc158f9e8425176e988048efd9f7b7cc53e9fcdb29ad2412ab4ca6ebbde6f4efca5945b53b2753bfc4eabe6280235620c4464f6940acca1a94659a527aa14cc7c5467382a54fe479656dfbc11923094fe8019a08c3ce7e99a28f086bdaaf0faac6ee16190dca8e94bf87657058495ad07931c89008ca1e565076256a93cb2468aa7122758b8e174f6a80f41a90fc92f05bf1f1f47da185b2f25a1abf5e0ccc6613e3aef87193400d751b4c87b44d9bdf5c0e207f0f6a7dc2113799":"654dff8f0500b52adbb70fb7bb7aec4b4820963706964c19c8320e161c3ba365":"42c902c5826874774550464c4bb736f2af7fd2a347f27c65bae11820eeb752aa":"6411b45947a43c5b01c2f6cefcd41cab73fcb6ea0f2a35a21475563055316e3e" + +Nist Vector 3072 sign data SHA-256 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"eb6a0359c6e46e09a42c554705bcfc5c0c022670b2f6c1a5bfe14ea805759ca2256153fdf815057ca9bd5f4cf837e14fdba3ad17612ccd19fde00764ba2e8ecd8f5a185cb26512f7457259c2f0670852741e7393b40c8bab673be2fa519b48a95dee6552365fdb7ddb632b1b33f1a5290b828da5965e82d874f79cdb928814fb":"0d06d405d228c0ed860b9e21bae570a6fd940cc702dd6e9a0846e7b2a4be47a5":"6db83b06c698ed80122ec4a2183370ed7dbd6ea44dbb4542149568570c53521d3399ab44fe2babd49068e11953c5d38f7ffe3bcbe4cbceb91c155ac8741dcf226a59ede10b050b9f3743f29689266ce6ee020ca17f9fa0e75b3f7158a65cef9fac76c88786b5e377afeacb9b3dda55be922da0ef958aa556abfb43067a414e915e31af5f5370881ed97b25b4bfecbe082a145d02717af800e77e28963cc0a6a1c11b02835e14bdba1a8c9ce4bfeb06aaebd760d7c43cf56ba212d0c75da026176535f982e8d749f20c2a8d5f53875d893374d859b7cee58b0eb319d3313cb8d17602f47e120d1a24a0f8a63cfe45a5028cc0937bbe89f6b3b7cdcaa7dcd5ec5f3ed2aa9f3aa8e91a496a8bad7874dd34bd8f2a9591997d54f92d5864216c953646840b378c7a05215ecd97b6ba944ca18597b7a54832ec98c1cac0003d50d5a05312cbc852d507cc973ecb56f424e8a1c198bcdbafaa6f928fd27a7c91f84bc234f2532639a8aa2196f8fc2b7111b3d0b1153165a0e0525d4ea595f89aec33b6":"521906f186797e7f5ce85112ab2457ddc030d6f34be361929f4d373dda576e08":"0493db0c18a3882709b3cc9f8dbe05454506c04c3a12a41d599d201d7615b6d8":"7494b4d1b2f3ae22797255a1d0662746352a3d0532290402068594cfe48c23a3" + +Nist Vector 3072 sign data SHA-256 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"5c59b209bbc0a1e010cb108db4101b8e2d04ced91299a8742322102e0d578c3698422b43d19d331608188bed4c7edc03a442f89aae60f4e7ee9b6325de3a8bb702918c21343bc9b266f2ebcf5a620336a7bc99ae3685f19080db46f24a501228c5bbfd9c0b4b0abecbfbd676c359607ce292cffd52d26af80b22e3c4d516ba0f":"4214d55b0a058c3dee2751407d9296168fed9f255e5c68273e1e5aeb3e504e67":"be31fd5d62db690bcdbc09e453d4417f82e8621ad717cab94648201a74f6ffdfab965311e8ff35c4a0b5dda339b435f17317175ac642f785129e151694ea8b244627e300ceb0f3be08f91c0f527f2e0df7c9f55492d1329b7d9689634c8a4f5210157e2419e615d9431736f804b1641103371e7ffe7200e74296127d59a8f97d41af11d70c3fd02531f7b811daa7516aa2f2a9ba70dcb704f3fee47f2cbed65c1e3d06c8814e1b28abe29f3d056792efdf9ac9307ed0106c5a328721af0e202b6df737ec4d82143dd2505e103ad845863c45869e69abd9e02c7b6eaaff9e2e12bc188138688c0be3e6941c37c7ddc9b6d289f7cc8fde42bc3c14e3ee521635f32f54280d119ccedfc51090a0ad006b2427604014ea4d0e0cd1efbce09c7f8e9981f969aed6d481cafb329f995343541d36686de6cb8e4b1e7e3727abd5c1e3ffa6936ad44b926063561512c0e9ac787f8eb791f963f790ba1b21dfe1b8d31d4c16b152a6de65bf54ab0f0d1e3d450317b1cf0c4e331d18587accb6960ccd04dd":"574cca3bd87ec1994449da2f2324a3945fa3047791274367bac0f12d4c064343":"7fc9bab3505adcd1b1c8127e2d1fbcd0e15eaac314250dc1c684fcc47fda2993":"70f2007edd68fb9dfe19a63eee4d5a977291abd235ed26e4291476ca5d0c8171" + +Nist Vector 3072 sign data SHA-256 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"c805d18c0bb53d32b57cb652f5b0e5293be492a1c88dfbec5baf47ee093e2df06918994e5cacbc3dfff229abd31fab7a95ade2fb53adaa7dff51f6c8581c69eb5b090baec38607ee9435447ad8137455b6ba179fc53ac094f97e3e29d0724cd10811f142d67d1cfcd5c3d1e9b411dac38f6e1c0c14dc9a50d84bcf00ece8a603":"3cc7e58577382500cb461c0ab8ff01ece8fa766b66f8be746e347ed2ebc18ebb":"2b6e1a8d4482b41697bbbe50b55b3dcdecea8d2e2eb5cf27b892bcbcabfb253c19486fa77c98c15add4149925b5501e5a5ef45b32ad09a872462a0f41d048af4e530660a3864937ba6a9eb0734e90fda3c9b6fcd30c9078771295a93802d9e1992a4eee9af7a0413880f33bc0b62036203286844bc384187ec51a33d390eaac0cc3328098a847509129bda735909fc7a11893ad0ec61276b7a5dcd4e626d9ba67610eaf0af876afc0419fa4f009aa5f913a1c73798c2707eeb8fa77f4ee058229a0ad37e845739668d95de226760898c02d06f155f82dc16360c3abca3780bcdb79446c8343583dc0f6925434b0dae7b59cb26b10008f86570ca0350de340b275524f00551310f1d095db8480b4acc489cf5e2947eb92904ebfd0d978bbfb5d0c6a1a9db50cc6917949c71854632b4408bade5195d40dcaf61fe950eff0c8997c374f1d465c80bc65adda636433e94f22c5fbcf09e99666a535919ee6f88154934f11377a9a9e021f2d7ecaba32510e92bf5ad67fa8b3d70dd2092b1389e3193":"179c02ec8f18fd88146120fcc51628f23e250ad694aa47bd691c0f442a63a92d":"38208c0985624bb9d62713bc7150942cbc92b8e8a36ef6d1ec4d08d1d9a5715f":"65d2ba787ed4c08beabf24343d06ed61872d6d684a3bc70307fcb7e20df931da" + +Nist Vector 3072 sign data SHA-256 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"9e0c66a4f120e85aea064e7a8ba132cf30a45de2889f3547384e4e84f45b3572bb0423b834de9f2c9636faffdb6331924f0d2f5b6876145d9cae110ab0cf6fc90c2eeff98c61fa186cc3952b57299a73678f4585bb18fbb84ef4166779ff10eed14d47ae528e03298dbb97cf4f88b7e6d0959b5894550a3e2e356947d25ffe73":"5c5791dd648703f29099736146f5b1b5e35dc71a74d6eed312d37aeb6d389ef0":"a62adbdaa5a55a2d1e439b5489cd6c8fcb23e9c64fbfae7c83e9d5599319bf3f06c3c290b989a638940b1d0b7e8bf6741319ab4c38d46e77ebd4945e25cb89cbb64e44b9474bc7c9d9f61a36e57eb6afab6c7a149afe02c1cd685483208c55feecb0d0bd96697b437991059267d76a488465faab4a7e17592329567005faa421e011d67f4da75accb627537e933e9ef0be3c70f21ed3f8c3b3d7d769bb611f82f2baa10fbc7313ad0819048d353d679736c4d14bca9985ecd37041afffb291a7d909c7458181d01592e6c90c0e34b49461ede66c5ac002671a4985546a6075df95b523f166d2e0d1f5da77baff5a24df775cc9d367f2a0728c4802d797041788c56cb871290332c1361f8da8897b5b8e25d4a93594ac648bc53c9d85b4fcdd7ab0f5a3ee9c25cc14ba6543b078859524ec7f0b61cdb209cc51c40aa9af082ea9c1d4b91b2c1f6dc11cd879fb3865d879fe000f0e0b4b233dbd01c9c98d01a664746577a64bf28d88256b76de2babf14961113733b1bb555325c09d8ec9189fca":"8327daa2fbd001858dea53d2dc0cb005e0ae5fb15bebc0c5efd33371637ef318":"4e35f586fad4f512863c485ec61ed01629aa1399b16fef4d80cb332752b1da92":"262dfe6ac72a2f6044f62698e42dd2f92b1f9a91be42b5fdd293b1bf9a145f00" + +Nist Vector 3072 sign data SHA-256 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"ed88d7076c5f6a5e0f947543d5fe746afca9b2c4d06655da4607685c799c210be4aaee0e6ed19713814182c7f7d584ddbed488c8e3239ddd810555ad6316d1db37fd9553ad74e3ceef9eeefaf54563602f5547aad4161e9384edab655a898416db53f71237ac5a1485711182bc5bfff72460252784ab1bba23634a36be77533f":"22b44bd6d23ee65ebc2e88030f837ef65593eeef0966239a92d5126cde867a13":"3e1ce8780f39444c2130dbf9d80ca4b25817dc16d08e2cdaca0b56cd2abdb9ef5adb741ccc1abecf62806ad7e87636f52831c6dea48e0729b904e5a0615d7ab4450104208a5ddfdb2f2569146ee83ac9aa27b4d066355fc53dc1a3683211ad3efad1ae69b8a7737bbd89f5ff48482e2c56edaa776e43b2a0ba62e513862da290288f07f84ca5a06837d19e9b186dc8d36952966e08f7213340186d31fd41a2d1455a083aee62127a28dfe4da6c876a5a6f36c45245dee6f6566b8318d3d01943b2adf8ce94ea01a01ba41a6e286820a96707cbd4002875b79d9fe2db6cc3f808ef0f71380ea9a73fc7e36850d022ffac131636367886a6e9965759d73f03ace69704b52144f67b678e2fa201c19bb37b00377daabc9377adcbddea2816cbb50b26ad2e429ea0576e7721b3b75c4fedb31fdf1f0c6c2eaa135f52c9a97f0df5fb25ef28848bdd7390cd054003722582d94e90a3bbe85beb34701271b4bb48bdf9b3d0e1bb5623445c7828c937a423be512c1177c9c0b5b0b6b0e1f639d330e051":"0c37eecd48682f897accf43b3e4a538cccdfd784625a6cc046dc54b093d16162":"2e7cb404a6daaa8e00760dafc95b4eb5545683224a61a1bcd6128bc4e7ac535e":"3a70b3a97e06e63b89d56ed5232346461c1a3b6b145d89043a48d666de0256d5" + +Nist Vector 3072 sign data SHA-256 #16 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA256:"c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9":"876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b":"110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7":"9e440052ed927321948388776d3719be068739dc2d6c64c5937176b2005c2d70a9389e6a655663366c0970a8e2e3117ecef257e951ac81c0731dfcd4fbdb1241bc249adde9cb398c7d15e381368ad3d24edee23397c15a5a356e787d8f2fe9be76260bd363e17006281c199fe5b710f9dfcac52895e392f7384d71bb83053ffc":"680883caf23665e813572c1e4230218edf53b3a5167f56a7d80e53e7d3ad1df9":"89e859fc63a263bcc051bc2ef58cc919ee537385cb3636d83a624a4230d4b0024ec5e28bcb884667cd2bf8c28451b64de097f2194cbb8c6e1cecbd6f9fbd576481555d0f0e8f13752f2472f7619d052318424310f69d50de78ad6c457b98c611f8481d4543031a73f83d1e852c1f2038a6435e571f776bbb5cf978a9b2c88f05d134fd5ff4656a69d6fe6b667da6da54be48386250394c75b495689fd4628f666424eb080094448d41b706292e51e75386543e5fcce6a6f3aac03a7d6d5c2551ca6b5b85fadc86bff14c79a1602fb0c1d43d88d5679021e826062ecf186aaaaefc312eab9f9e2da120a8d7d08ba09aa9abf4e34f6d88c4c314c59c36ba57f928d88d5d70fe48ac6700f5cf607a55e3646dd03d47e96ad869f7ba2bcc7d65a99c3221d4909d1f22e4ccba815fa5b720570e42f8626c31d99f60cd6a015391fab3537446f747c0111293c5bd6b5dab2bc3d5137d2124029eed12db71bdf794de1a2ec5070d83f87195264ff09cb48cddb5e852b233570f1b70cd457cf864e2ef3b":"69e6cb5bcf8cae88c96e464a9b26c6e1bbac1e229909e27542278a50c66959f1":"37c34f9cce916df3deff26be08a4e6bbae0661fbbb5d81d6039f00b1e5632b67":"3f4a2932917e6bb088599a269d7b590769acf9807dc5a9420a95e12c7364c5fa" + +Nist Vector 3072 sign data SHA-384 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"ed9a64d3109ef8a9292956b946873ca4bd887ce624b81be81b82c69c67aaddf5655f70fe4768114db2834c71787f858e5165da1a7fa961d855ad7e5bc4b7be31b97dbe770798ef7966152b14b86ae35625a28aee5663b9ef3067cbdfbabd87197e5c842d3092eb88dca57c6c8ad4c00a19ddf2e1967b59bd06ccaef933bc28e7":"6d4c934391b7f6fb6e19e3141f8c0018ef5726118a11064358c7d35b37737377":"1f0a5c75e7985d6e70e4fbfda51a10b925f6accb600d7c6510db90ec367b93bb069bd286e8f979b22ef0702f717a8755c18309c87dae3fe82cc3dc8f4b7aa3d5f3876f4d4b3eb68bfe910c43076d6cd0d39fc88dde78f09480db55234e6c8ca59fe2700efec04feee6b4e8ee2413721858be7190dbe905f456edcab55b2dc2916dc1e8731988d9ef8b619abcf8955aa960ef02b3f02a8dc649369222af50f1338ed28d667f3f10cae2a3c28a3c1d08df639c81ada13c8fd198c6dae3d62a3fe9f04c985c65f610c06cb8faea68edb80de6cf07a8e89c00218185a952b23572e34df07ce5b4261e5de427eb503ee1baf5992db6d438b47434c40c22657bc163e7953fa33eff39dc2734607039aadd6ac27e4367131041f845ffa1a13f556bfba2307a5c78f2ccf11298c762e08871968e48dc3d1569d09965cd09da43cf0309a16af1e20fee7da3dc21b364c4615cd5123fa5f9b23cfc4ffd9cfdcea670623840b062d4648d2eba786ad3f7ae337a4284324ace236f9f7174fbf442b99043002f":"40b5cc685c3d1f59072228af9551683b5b8c8ff65240114ad2dacfccf3928057":"7695698a14755db4206e850b4f5f19c540b07d07e08aac591e20081646e6eedc":"3dae01154ecff7b19007a953f185f0663ef7f2537f0b15e04fb343c961f36de2" + +Nist Vector 3072 sign data SHA-384 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"4bfd28a0a79c94dbd667c275ef77a235d8ead7c698d42fb7f7c1fd3c8c2dc48d0dda2408dea56325d69283692a523d281ffea856ffd9f8417eafbea606d862dc5897bdf241f3e8e49aded5eadc7295e5afbf96b3975d0e25daa2433612e120f659036b807c1853c03c90fade2c19dcd923492ecc906cafc57a95da6f20dd59d6":"95fded7e5e949602c1123d80f89503cc5fb7454be3173af495a18709c1c2506e":"6c778bcb146582277633931bfd029e69c9e8c0ae9e24913fa734554f24f64aa64fd9bc608ef677a1d4829aa8a8564c2ff0ffa2fa6a0c1a2ccb606dda018bf095f8c897d7a43349beb9807b7b118f8de8856b164b8d8babdc17b48f3a2b972ce537ab4e7a7d9ba5d7e6fa3698aca91973cd1787ef7b6b4d0410de59cd3143e0f3acfdaabe56b371b4354d0d32dbd1b5ca6a872054f3e6566319d5d50b2cf54c123ffc929007ad1857ba13b7c403f551c2fa4109c44e19ef97afb62a6103356fcc2ef451e736261010b0ef58ae07a0c801ff75ebaf6cdd763f8df2f83f0ebbda40845b2f42d3feeac071fc626ee5b51f9bc1a130514f2204971b4b7261b4bd783ff75775aa73a63d7ebe990b939b0f44a909ec390036f297c3563f64d142c14ea43c5d3c6def4a3a9ccf6274182b939b886501aeb4efb23d0073434cec6a915a67e24cbb2354c9bb1089af487eab5d8e499a632e6c61492ea15d2c444c269de33271a90042468de2767f0dcf7a66424a3a40a63eebd19cb89c8d74c58504c4e103":"6bd1eede564ecb1b3fbbf2d96e334ab4cc002e6624e2cb8448d8608fe0e8c43b":"37c3f7556d6e5acf7989f0baa770c2450deebd4d5f58b61e17b4b2b926b58031":"a61d86365f10ca5e1ee2c4bf276f2374e88b5a2d1acd8ecc11e97785b4fd9931" + +Nist Vector 3072 sign data SHA-384 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"e3fc751b6978fcf40f09606ee4263e1660ff20e9c63a7138f078ae3e3e603dfcad172f3c7cb3f3545fc23bc30c37c8439c7b238341f29148276ea2122ea8ed0feacb149de17cfd33b8c9408aee8ab0ea8ba4a2b2ea237418bc3165369c8cd420242f8d32bcabe0c352e21f65de80d587ba2713cea6e53ca524aec365bdf21adc":"3a09006faedec91446995a393b034b0c7ff3fcd05cda2e9e3b2f98e3a4bbb9f5":"1349bbf16d375c392a9acd5bdce655f14d616274388a45cd372925c507ac129fe61b998e25127f210926ad1191583eee8c4190026ba0a95894be3f0ad5d05886c59a3c7a0044f7e2bd9bbe28bf9366d034db424f34960e30a8e7888f927d0bf984b0ff99ea271871124aa12e0c0e19624e533cb4149cedb3e11d321600dc07b32e531a615c8f7fd7f33a071caaa76433d1aab0b710fa7ba3ddb0175ced4e558d5117afc7542b9b07a8fe8e4b08a1de456443553fe87a4c2455ded72f98544d6c41d6ef66b7142a4aa9aa1d3d20f700010389e417840782fad682153d569f944d3d3ad1d88db5bfba3499e4c3660b76b44da4b0e6727ebc3f22b2a0aaf62dc2a29db8babcacc2169c2b8674054c89fd770db98b12af2d933becbeca9f22444b527aa894b3765292dcffaf3408e699495df79b98d957fdba7e4c8e7ace3f987a95dcb2e777fa2d1304479a6d137efcb0c404e6d8ed39d6afba2549f3ee2b9a45f324567c0227319dc59bcadfcfdf1566f356f7c2ba6db21cca2a8fb2fbeaf31cb7":"4212971feb32e25fbb22845ab8c9333cb2a265f003542838a128a25108a88365":"2d3f3c605eca8fec37a76d606d20fde89cb6f971a44796095a01dcf8e900f5b2":"6a43168334e5b0ea07cfa5978609e86f969d1005528ebb3ee9073d5655d54b44" + +Nist Vector 3072 sign data SHA-384 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"45f656a1ef0e61de46df2ca2d8ea26640a994c30380c0cfd66be3998d89849161bbcf3bee77ad30e769f10e23aad5b4df4edc19a86fbb5abdeec8779b76be279532d7692bc586c62692fa1e3dbcce33ffddc9f97589172f64a48535693ded6bc73b2ca32469d0eaf6706d2a5f58f8d28a745dc328bcc75b3415ca93e29eabb1e":"9f35b1038686bde07a5f517d68f562739cb7150fa47ebaf7ffd29306afd4688a":"31a989601f32b205943a841887df3c6814cfb2258e5204d04d3928ddfaba0dffad43151e27d666d2928bedc67275440fb502ed3eafc3adc11009ee703f01eaa034aa724fcc63c59a8a5963f3352f7293ea2425ea89bbf1e41724b69f383bf10a973146ed02f55208b04833d1bb5399a67f04081590acfcfbb12105423e26091d09078c45007d436eb19f952f8798b001a3c64a3baa5496c9dbe6580781d4020bb7e4e7ae2380ce79658c10a2e57bbb8cac12087728ce43ba2b9f380e3abc2dd12a682488c6b4fb2f8dd7f3846b6a26f913ac156879ee6a1ae0ada9568521a4428ed9f741e0e79a842880019c01b34e988a7cf7e63524e8cd025453223a2660273e491968af7f4b1dc2123961de3753ab16eca5b1859a4f71172538f05a2a82a34f98ba07c1e531d82ef592e5493533416bd6c6a4c7ca3b0d2a2fff88a8f073a76c691802aaaece4e852d6650871a17cca0f5251ef22dfc8e3b261bfcbd5a22b2732aa17d7df1f7b82f6b222e5f6065bf80d04c2e5774094084e4d5ce0d3e8917":"55d1ffc73b52b6364d660fa4658a6351142ac538fd3cfb4eec40ba07bef5418b":"3ced0ea5f7fd588668a41efe0e90954c0930afb6be18d90752831f683cd92a9c":"9e46ca12941745ea1a12c5a2d609884cb5792f46afaacff07237137400366868" + +Nist Vector 3072 sign data SHA-384 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"c737d5ae248a96062d6afa8dcacc0384c5fbfb9d8b6052b52493c60d3edfc524b567b1f896e7447d0e24019403ed83e4889c0c4de57c70fada6c8b5a09904350a44dfaf77d60af62de3edfd8760d077473f26df2837cfc2015f227dd7d351a5350f1428f2699fd3f518326fea8aef98fc4ea673130c8079fac3895fe856c77f8":"40dbd496fc4644be7ccb24d9dc55895c1b923a05f4da5610589d564ee8aac33f":"6112d3cd3191d17dee7788f568815a0aab50006002c9de2bd1a9bba245ba02894b02e9247517ace698ae0a05176b62b3a025a563dda8deb7f2fc3e177ae3477448d39ae4ebe7ae8ec65a4421f754667fd6d7c2eb93f1a18d3d1a6235736bcdb74746f46d88e65dc07c2591e1f95dda5e5e20e105ee8b4ddcaaf36021290d6b6493671d8aafae145d9b90bec3cc60179bb8fc30f143c575d5d861623721b6547d3aaaade455f05fef9318abcd29bd19b12c35ca756de5108c185ece4aa1bf1a8e38809797067bd1f52b6cf2c415e73f9246bd5bfadd7b9a9d2b5369701e72147e22da7e092d9b578fb0c044a36effcbd709258500a00cff230962c44225712fc43f9e802baead7f9cb46ab4931f663c6e3ed4082d59610f01741b5f24566b01b3e3933b29e028c54bd2fc75b549fd05e64c58c9ae0ba417a9e98581db77be75233a42f771c99f0a49b494f0955202b19d6c740e866066104e463e65e4bad9a081636d05367426153f04bcb2712186dca6834388e82520d34efd8a89313b2c7e60":"aa63e91cb3fa545c447a8b8309a569d48104e14d5d05b8951033ac8a7d711c3f":"0041b1c756dd2e42714f9ee7edce21ea33ef49dbf452ccd9357d5f45ffab08f9":"102c6eaad38d39c0d036335ae19dd0d75e8dcabae59b120f69cbd2b5cf48abdb" + +Nist Vector 3072 sign data SHA-384 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"a6fc89a223022ee9e508725278582f56db9cd24c0d75d072a528d0c60f27171ea376e2dc28a9dc0b12e668af77dcbb381737e1ba7d9e80b9bec80bf9061b8fa10e43a7403a291624a600dd4f5c2b50c52d5c6155d52be5a325f6ad813fb3ecaf6d1f92e98cc87c26c68cbd15d548a3782bffdd1116c7c11fcabde4025fec5154":"1b41c29364947768876ad4e7abcae59c8e61373d25274ba42ceb3d876d6ce672":"6c1d4d6b52aa4bff35f4302330052777f51f6a0849161f906ef217b04b18545ce52ae4ae423ad1b4f8b1735ae00ab0c044a56f945da84d1cdc26e082d7acd772dfabcd18b5e13c05c2791a8dc16146e151323e4ef2ce5d64389f69d9347aa2a5bd0114de0eecdf990a440d1bf9890dd95fd640d2fb1789ca6a6dbee1836ad7cb47370b7456e49f3bac03310f8cbe61dd1cc06d78c76fec6397e608a4cac4e2c38983ce5aa9dcba074a206fa608db35f2ad3d63d95b2cb7a01c33d498767e8e68578e4e99538bf3d703e63863a25091452e73b96a3716e9cc109b66008fa5cafdbf96b7fc10c3bb89d79d45ffefc01908d247ef1d4fcb903bf5e7917af88618a52a12004798890540a5a75c65fbc057d860f4b65d8b08b8d215f056d8e5e38bf0b319e294db242a4fc79b2e106feca2556d146f5203fd72adc73a48e3a5aadbb293a2ef5862654c31539ad856a16e5716c437b474f3339cd84f0ac92bc2ca6fac10c751d099a90408def6106ca83893d87e32818d7634537a4ef667ce7f26a5cb":"4c9ace2c908648032151f638e3c909d1f0646fe018a1c9c22a170eff64447fbe":"48bd010c1af77b3c40db50349706d64d16cbb72db51943d345151deacd4a4133":"0f1c4bdb4758ab3b5518d4605b9864805723d33a36116ea650546feef11c4a5e" + +Nist Vector 3072 sign data SHA-384 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"2ae4ac7ce29ae7d32490d3a54b715db3f47306f84b59b33b21622a18aa2c060a4434adfa01ff1686b5d1dd3035308e92f7acc76dea969deefb98c2972b42a596e1055a5aa2c661f0b734ba4f0b341c77827d88915a5e89f95a98d63d7729874fce4ff75d7add74f4313dff784e417b2ee1fcd270c038dbbbb96a7768484b8854":"87980da0684558f87e5864ae585864625aed61b1309c1d5f30f6477f947c44fb":"0a84298f4768e9d7bf796d06585e8b75fbde658398a224a8ac3a49fb91235eaaa183aa8827cc2af79ea334dc8be4cc729029ab5f8161f718f7bfbe90ad2a159888523982b6d4932d8159495ba84d0ab35d7e395d14dba906a1679ae3cbb72c10ed6fa14da4d60077b0bfb591a3dec643996c396338a51d446bde6224aea16aef41f354e09a9dce9f3a00cb445a5c9cae4a6c3c1919c9e0c53082173d0ec00ae5e15aa7260750b6a03ef05a518a48615340ac20984073cea5fc990d489858949aaf6e9e347b4802afbe25a0669472bd9316ba2c23a61cc3aadf1b70d9fd9761bb035f0ca51edb2b12fcfd651cb92363ef48005a2683fd2ed8665d70588fd9a1be3aa51c958b81f13e4acfaf0d2a90aaaef21b2cc9ef2ed37bce3c47c8bcbfc1fb9f94e49bd2f1a30a88df22735a0fdf0ac6028a008b062c9560c42a476997dd21100692ef6396d5f3fb2c155328257e7b7d2bc05fabd54a81a2272993d342bec8577c64d51b4cdbe3654dae568c4da018618c3047aee06bf2621e056b335d044b":"25b9d8fbe7e3ab7017f2b1e53da579df460dfb72ba5fe4ae4c85b8c23472bc8c":"6b7ed3a4c2a4f78500c7e947e6175c5ca857c9d613e7790b9be0d14ec8403e5f":"a116f3de166260d110e20e84eb8c97c3f018178608a2ea3e3e2f5ed91d43de11" + +Nist Vector 3072 sign data SHA-384 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"3eade9a10fb59af36a540170737fbc536e4c5230b8f6c4b216eddd3ea92342123a3374d0c751b24b627f9ead4de26e9a7897d9bc5d58a6a3ac74cd4575b3286ec15f8453224f37179e51d9c4ad8a60bf37d71c62ad7fc53e5c7b12f4aaa2d428e5c889fd7f062c913d9b574f4b5db516c976bad588302f219fd83e18bee8e68e":"6cf453178db0dd7f2f94f9a1f518c622c1ddee46d4b090462812e9f7b862265b":"08a15b2384dff4f3033c87168673c567059870c8e78d2fddc7540afda8058df384d3182a42615432ff93777d3fce49c117c7bbe821e6789b5137ddf084656098aa7b0516fd30a42c8c86d94e6b268b6e13011d25eba018ca40cf8a35e1963135d5cd65a57aca8b007988a5ea75adb4d01cc0f0838ab42d3df643a7d2561cfd1fdebe3ad86ad03de317027533d523351be532bc731aaf43b8642a7da80873b80dc61b7a249e5860fd1a3eae0f8f0cf21e205d6f403cb0a103290c9e69d38cbed9e092b69f71f9172b3676f29a97133fc3e18746fedc653fbfb62c5e0afe89a8e1b8724b1a3314c4cacc4bb8f390439701a614ae9bcdafd472b0ab131667dbbf1c790f73ab9046a58932691a930b3c42e908b4d1f47ed6e2ff18d6b70bb16d1af7993bdb2ca3cb359a0b43f8dc844dea6aebaa34b8d2b6fc288419780ff980908926c46c3b0e595fa308f4e894ecb683c804c93140d91769132d37e93791b9f89d595e698f049b3a9502abc488bdd9472f1131a757f3d54b149067507d1b04a976":"a3fb61e544d59206d334049e8554d97b6699db616871fd2b421229c28e84f73c":"9e833ec3ded9d81ea7422bdac78422274fa35348e3fce3bbc93b3c10d70b4f1e":"653756594eac681d48a2358a0f82a10faa7929b00fd9cd4394c32679060f96e3" + +Nist Vector 3072 sign data SHA-384 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"33decfc1e06b92ed81cd30ee3771470b59e22c1564647f1aae8510729715a8ce94624a11554ac909c924aec853df64327546db85d3df597916a39353388a8b3363765281a4352701ff1af43fba6d03664127c15da7b84c04d5409c364094dc62e37983a8eb066880de8136701406e67250679300d2b97d228327c1514c0bc1ea":"3bf2be01d154c23ccae92ae93f78ea36f70efcf7fb7eb43cdcaeb9ffb8471b10":"16ea2e795c636c9d312159a579b8df329ffc28fecc4a4c13b16a290bd1525a53a97d72315be251d11d23ca78bbec45c0e243279b1eb6e206a9273c1e766e213648bdf90c40479df48acfd9c209a523c8b4a99a481ca8df4774b3bb29f82526520c2dc28ab314fe14140f2be1792e1ac3c759ad44f7845a2012f64ecab0b1fec0ed166bd175955704f62d9401111ffc04f804e48fe774dfd346bb41f4beca2b34a83134a3884a01729cce1abc5b8d0de3fe2654c374deb246d96ffaffc7aa2055b74e819bbeec137eb3caed1fc71f129c8ea8b763f2f57e88de0845f76ceb1841559019872a5b5a969c9cf385d6578b4f27b5b76be3ef0a8fd3ee47eed695e16f14e2a3b791f2a016d6b86ff8ec2343c6a5c80ab6224b6502eb374c8fa6510bce990d70efdfa9a0b702585595184514c78f7e905b6fd6c237333d560fcc06303637ac0b2c7f7c4da559e31f531df2e5d6c651591771d7ea4575888afc4011fa1124fbd1a282a41d933989eff91a51cd39bce7fb0d569fedcc42de48bf18ee755f":"a0c97f80ca449fd8f69733e046664408da590dbbab6865c3275c389a478aa248":"6f77a52169a2e880a3b55aa278f6463032dc5f81c38468224d5532f6a601f2d9":"96b753efb4abbc8c179d03cc2a1a0c1256e23d1fa2e97cfbf55d2bb69812d100" + +Nist Vector 3072 sign data SHA-384 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"6ae5a6da794f923f6d8032549b81d04ae7aa35c2099dffbdd83bb94db574faf8f95c7126db2db60fed50f740e87c359544dc2ebfbcafb094ddca69c914d27e5f3d10fa0ce32d2a1355bcf61a2574c755d7c324a2e0ed6f7719ba2f2c9f113df8d04025f4abd2e1c4b7bc18d8acec9f6d8d797cd7b042f50348eeb3f7a2922da7":"3b4a52c8b5c386f26ac6ffabcef2df3bf8b25e6108ab540d314dd3d9245c075d":"93106fb000c67f1111c6fd3da0f44b4ae4cb3695de2e35b241dfe88d3269b8fda25bf348008725fd613cd61aa826bd8f1aaaee22b4dc0a02842290bb7dad91af0b2854ffab16932208d272f2c081c13889db3ed0b24646c665af9f4b723898eb1ac0053f2a0f4cf22fd4e12940b5b52269484ebb8abc484c06eddbd9b1a426132f402efdcd88ab29e7e510961af8ec83a642e34015858ac3f32197601a888e16c759c94ec5b8dec0da30643b9d9db2574af29e78f9d3f6a7b4c76f45cd0b2ab5e8524935b886918b5d9e9ccb5a6853e62efad2dff83a8520985ee8442f2bdd1c5f9d48062ade6b288c8ad82a41db6c34e2deba541aaac3cd3156c975efbbc718ebd4961996b3ed1cc5c2987ab779052cdbecf51d17661b498e84371ff859f89906f426f563572f66c279ef3d036a427778463f67f8d4de623fb4b2803007871d0a349ec202a9aa1cffef70137e009303497214ada786357a4d8046255e40f89ea588000634e7f0aaf64d92aa21fff8fbe078baa96961699738b268237eab606c":"39f68875cade6ae208d3043b010541624679df649cc5d97b09a3ebbe2c9d59be":"8636d4d3203aa0912fbfc938be4370077ea9c75195cd2f67e6ee427cde531c40":"93023d97efb4327e9e886e7b783741e9d2c397af9c67b91cdb8aa27f83bb025d" + +Nist Vector 3072 sign data SHA-384 #11 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"86e03bc3f4ddea6a93888ee389b15eb690822c71f9b85efaaffc52e486b1144ad7fcff3f53bf97da2481e85e0983ee1d5279e27a364d0e690f587a31535fb94eece747f8b605724adfb258c9983c9002e0c11b7976627690d58281305ea9308db74c491a28192e354b600e8376811ccefb751bb10c7d97b42ffe304bee97ecaf":"7f56c74b495a12db963e03cfafe60ac95e8019cb212c332d1f19c64615568119":"23ed5445391a5bb94e00c76ec80d83728d5d461be425da79f921bca27d625cb42b323971022ad4c3f05bca109910fd06ba39e95bebe794ed108d2ead297ad794f99c32c219e65fb726532715b1bc2075dd4b6949297712f91d5ba061196fb25754c34377bbbe6a37f61787ea844d359285c78e733eb65f665a6b157f832b5638d74ebe1d5dce66d528925e44eef13bf23f807da35f34d169a687758229b99a313acecfb20b142b534926d59aaa7643a79030e9335ef28abeddac8ac9471da4997e33f3e491db8668a2c3920a3b3a37225179361d5539beb33f3252244267465e48faf575cdac938133effe9d1f69f19f1b44b245a447b1fc2b859244e2e39053595cf7978933c3d468c65c231663070aeaf2ec23138d1660081a55bdc3dd3f2446176b1d6d9977a14ebd0ed4d8dfcdfc4a433118401f2c2632095ce7ae6200c74bda5d2fd3854524c3081741975a076a1b4f933ec32a2bac9171bebfdf3b355eddb1f455ecaf73396e85fb04797558ba4f2bbc49d9f2329a23b393301ae0db92":"407180cc311aebdc1cdcb4685241597783f34076672362a24a21193c0d45d24d":"68efaa05eb90c48c6a7a45337c29175f8ee5b19b53db4ebd83a02f53c5b2104b":"145f13f1ae3675c521b334ce6a49fc6f502e3ac6b2b5143be0641d0d57b3c722" + +Nist Vector 3072 sign data SHA-384 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"1d0954ee0de1e9ceee0532597ee434c73fe4f66635f7e72d38b67763c66817f53cf36ca0f613e01896cebc9f77a772607f4aeedd3856c73fc2f19100aa7b540ccd057f26cd9564d673228c68088e5f1abf1254a97ed1453ee558e062711ceb7643b345ad33b649affbe8a62067f9d84ed4c8506fcff578d2eba596a205267387":"0b48499625f0c2548bf8a2fed1f6696f59df8fbe6eaf91b82385994209c2d04f":"2f0d89ac78a61fb74f81142b17766656d1788940077808e3d880ce10ec60e2bbb158d54e020dbc5f6786c0b43cca2cb002c8ce13b291b250f399e8e02f195926978f6c5b007d4f0a66048996a9932a918b2363c4008f547adcaa7d12694baee4fbca34bc6d7e29c5049cda13698fcce61bd3b3db05d2158132dd380cf653cccdf279aa164134bfbddd7ea347760041f92c3a4cfde0092d5cb96bb8c24e98259475596f3377d59f11661bcc0d47e83cb31aae9dcb4a6f25619a29054b62aa8b421e529e61ac95a0de01c50b09e119516c2c5b3563d47eed679a1cf80ba70a50254d851a13a778e1a08da8667e46e35979c15df45cf7886dde5af9d744624b981acd252ec5ba46870b8ee4b32b1be1b944802d91d8148d38f54315a7ad4e38079ea2bed9df8fa59414ddded3a1d2308ba769ae2a652f10c2d96917edfe5874885f3c99d6912f69ae3fc3b4de82decc30edc9314f7ec9e567b7e00de21959486a887d74a5b2180293df5dbeae1e35a6e937b2506d205092cc4c3595db92fc255af5":"1c020abb0e1d52b3ad95467f7baaf665e2281f34c342401ef1fb4c1fc2d7b2bd":"a67210341a04cd3a4b63ebc7e6208f37e487a8c6f1134cd2601b844d6903203f":"6b972c622cab48d85a2dde355f947a8151a17a0acf06b7f3659f868d5ece92d9" + +Nist Vector 3072 sign data SHA-384 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"14f566c5fe44aaad6e8b3c627570aabdd4efb7fcfa1ab1bb74f2c6d8795e88233dac4e7d240abd5e9bbd8e1fb03a3bf50c0ca92c9aef1894f2aed600fc5873d23451d3204d75ab9581cbcf82ae8c0df0dfbd3a1f149f70660865726cdc73c015d5ddbf7513eedcd1ef17578d2719fea1e5ba39aef3fa6f00846f0fb8d9a1a436":"7928d3edc11a890fe332c0d3759bc6ecb822438d7f604da76b4fd78590720ddb":"a36a333900035d3453139b28356bf0124e571f55a5e4259b8b2ee1457cc3588056d6c6a645d422cac72474c5901d0a7f410df7f9b4e22f8684867d9332e2d4266a6e595e515becff7fb94d21a8a9ad7211572e44ce8448317b34c3c0b89b3097ab2ec134ec7c178c2278309cf9152b223bb937e68682f1f680c17ee59ecd0698a05c24c135d2b0238e71f807e079f175e11671308f5bd9e5a69712a9c508b3b50925d1276d552bda51cef3bd0fbd00a9d2dddf0e5ecb6b328378ea637b493846480ed75a3152d9e6a4884eebad12b07cad8d101b3d001bc99fb1eee4e98fd6fc920cb5765ec24e62abd32f975a47d50f61553e1c14775193b53b05b7d02024aace818ab659d717d11deacc9877b818a51689d239b60f7f9ed4caf7325ac0b31b316c036599ea66959d525fd16f5c1a2a809f2866ee9e99f6d8a3c42b58d33d0e5d38055c55c7bccdef310ccd3426207dbbc60faf9f2a219ab367ce84623b81104822e2c77ec5b133ce7050caed090946c1f1355d878a1317de694e686c62ffdf":"01f77e5f125a9a1385349f77d7a32f26b1efa5b0a5d4a212753bb54d300d088e":"12b40bd1c866ce38e7da0764d807ae82512b33b51dc908e5a5b3d7c16f0d08a5":"5caccee2bc85e28d506a9bc6d260dbd08205b75d20690e26aa6bed30d7327099" + +Nist Vector 3072 sign data SHA-384 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"60c29d99753d0847bb52e906c862a1b0628496416c14df5dcfbb5e2804f502cb0a2d163e9bc2d84122c0b3f5d0609b82ac16aa15efd55f55c8caa3d1114ac0cb83e5ff3db12a24b89aca5f0514d2ceb09b14fa916000c0f4deb016db755e88b326172144e4f1a705a800559b3da3c27af55cb32b1147460c31186d99dc1cf2e5":"3dd64db4bd8e28e701235ad83a5d5e9dd13ee8a3b3dcb4c99c1bc95b6ae25291":"a37397e6eafbdcf1e0158f1f4ea1cb3a1ebd739c8559a500def3b7551799d652b327101cfea0b87016db591522b9b34ed267132c5255e77653c4eb935ce0c822b4b10a5e8f3cce39ad1b9606de5be2b2d36e1c5411f06aba0461ea8dc48b649f108eba88def44daa2a5c653dccf1d8ae29205dd5c340e34b7bd698eccdcd345bd4aa5eee3c08b9162ca1804872de3c575d572f34dd48b41f8235d0f511c8dc65daeb07095c3b5dbd3a076f8eb24412f3621f492126737a9d73014defa5f5d57bdc6faf53142eb191606f2fd3dc035f4b8ae84d655cb6daaaf889005c3c334ffd7e3b0498fae2a6f8dc1bc62f3704c8f8c005c8019e0bf45b7aa8e0803b93a992675e381f61a898582950b9ce40e7cdb0300f4b26f9b44484e89c9234179b60a372fe9476f84de0ed4b93497216fb96bae43297dcdc8496c634100cf066402c7d290a7cd28cbcf8b08ad4c136db2fe992ffa045bf8cb249234f29a674762a56d20897ea5538c674a14353db64ba60fe4052a0528eb0b25887e3c5ea69b41f68b3":"453b64f2dedfeb1419b5dbeb726a2c92b1a37ef11a7732c911d9a96184285f40":"72cf0e18e4bc3749647cdfa62dcbd2513c7c2b1d397c1fcbc7f6a425ebb897ce":"7b7d0a9e93340941bb55f6afa6cd63f7364963671008ede457d05b6545fab1f1" + +Nist Vector 3072 sign data SHA-384 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA384:"a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877":"abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045":"867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930":"b3dea62a20a9ed9da990465bebe18aa71f08f93fbaee4fe5d581ffaa6fd55cbe272a115d7fa18fb9cf5662f595b7cb9bdb97a81bdc078ee3bdceb2c03722610134c3bbfd7a6f8b79ecc6a9a7709265687f9c236fc68b02203ba666e9eced5161de90c110ee7af9bf54d84a22181f17b4329348bdeefbb324962e63569f07c285":"6327d3818c87e4c99b7e5116fc091a9da1e4c02aab9b207d61e859dda8d859ed":"45013318b941a710b8ab1010d818c3103634658d2e3e2f413165860805e08d5c1e80add9969a3d3a0d23432c8a48cce836b24a410892099bbf53cc5a84a95e1eb3b682d2754e721efc86d3f4248baa337d6f6e5dac4759b296165918a71b31ced25bf1b05d675bfa222980608fda8f9d0eba9aa08475512d04c612133c88253bf3e27e9ffe3a8570be204f54bf8ff1c7fe42aece832050aabdd9415764b8c872697f9c8e78e2f56bd235ebbbb4b9cf8f054b60292963764536d6fd4c6cfaa1baea53546c6ffb56a04fbfaee001228280aec40e66d9dc192f9ba743bd3ffc0eaf277b6ba3d33c3697024892b0b35419534873fb7a3d594dd6ae0751a2fa430ba46237f4a55e4a678072c651fe6ad314a010fdfe8f8b5342bdabe9ae5910c6f44a51f47524a6fe8216830ccaeded26ce1f13f7f216e0b7809e9272563cab3352b8ed766650227bfe16e981b505609c41f03dca98e219d02aa7d91921edb3a89229e78c30161cc13973b35de3c87779378b8d607a19320405661312432dd8d07af2":"94a0f6f58f004e45ce5ffffa6e63abca8daf7768cdafd517f3a5e399828b1e72":"3ec677e91c63e65aaa174aee2791dc409244cb80c0220991dcb497397a3c5e9b":"1de0ec466b2ad4ed1adce3bc38ee521803dc87085e2fbfc561d63844c1a9a2e6" + +Nist Vector 3072 sign data SHA-512 #1 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"494180eed0951371bbaf0a850ef13679df49c1f13fe3770b6c13285bf3ad93dc4ab018aab9139d74200808e9c55bf88300324cc697efeaa641d37f3acf72d8c97bff0182a35b940150c98a03ef41a3e1487440c923a988e53ca3ce883a2fb532bb7441c122f1dc2f9d0b0bc07f26ba29a35cdf0da846a9d8eab405cbf8c8e77f":"150b5c51ea6402276bc912322f0404f6d57ff7d32afcaa83b6dfde11abb48181":"6da54f2b0ddb4dcce2da1edfa16ba84953d8429ce60cd111a5c65edcf7ba5b8d9387ab6881c24880b2afbdb437e9ed7ffb8e96beca7ea80d1d90f24d546112629df5c9e9661742cc872fdb3d409bc77b75b17c7e6cfff86261071c4b5c9f9898be1e9e27349b933c34fb345685f8fc6c12470d124cecf51b5d5adbf5e7a2490f8d67aac53a82ed6a2110686cf631c348bcbc4cf156f3a6980163e2feca72a45f6b3d68c10e5a2283b470b7292674490383f75fa26ccf93c0e1c8d0628ca35f2f3d9b6876505d118988957237a2fc8051cb47b410e8b7a619e73b1350a9f6a260c5f16841e7c4db53d8eaa0b4708d62f95b2a72e2f04ca14647bca6b5e3ee707fcdf758b925eb8d4e6ace4fc7443c9bc5819ff9e555be098aa055066828e21b818fedc3aac517a0ee8f9060bd86e0d4cce212ab6a3a243c5ec0274563353ca7103af085e8f41be524fbb75cda88903907df94bfd69373e288949bd0626d85c1398b3073a139d5c747d24afdae7a3e745437335d0ee993eef36a3041c912f7eb58":"b599111b9f78402cefe7bde8bf553b6ca00d5abaf9a158aa42f2607bf78510bc":"a40a6c905654c55fc58e99c7d1a3feea2c5be64823d4086ce811f334cfdc448d":"6478050977ec585980454e0a2f26a03037b921ca588a78a4daff7e84d49a8a6c" + +Nist Vector 3072 sign data SHA-512 #2 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"c01c47bfa208e2f19ddda5cde5833325d16a83fbda29e666fe67ff3489803a6478a5ac17ff01edc7973d15fe4998f63bbc095fc1ac07534241c643a44444dc9a356fa812d5ca191a2f6ed162a2d5fd6d0aa898a20563d993830254db8a4bf65ba86099cc6b58a1bf6ebb01a19c79304308acebe1da09f1753a195e9ef586c7e1":"9f11370ddb3c43e2f4162dc61f7e08dfc6e86d5d71742c6adcb5340f7bea2ada":"970d38cd8b3f16659ec42a46a19ff06ce8495b9f477d9b7e35ae1035b08b0ee17a0c3ceedf029846e3aeb912f850881c2277f82281e7c0741d2f87e9fa5c30677fe7268cc5fd9aed29f308d9be8de92b961e39c1dbc46790c99b7e29579daf888176d5ce16db5cabfcbe4209ac4753b0e96b15d0b82c7eefb42a10de88f8a7723492a2be5451c1c6ec68ca759d8b4ee418826e71f39cd07654d00d0e0f88d0924bdb97aaca5a6346ad69fc223cd57f5bb0300477b594aa445e5ea8896cdf3bc882e8fa5523b8a332fd98e9d0a924578944d24a41cbeae3ed7b37dffb2f60c0084eaf005c1251823da41d2a5d977d8e483ddb33f73fbc27254a814b616d6a390513f0567a563ac053a76667197b4558f871b69cbf2c116ce457513f60b4f528e2dcdaa71a9a3a4cccb3738a22937bca2a042bef8a74a600acd26975c891466d7e57cc930984212ee0eaf174ebcbafbeb8cc12bc43bfdb00fd11576c439513ef5b59a88fa5a9ae963d94dafd78f81ee7b0d7fab53e41bbf65f8449a4f58b44f9e3":"ab53984e0b154992ace73bba548185b49719bcc3b11fb150b5da279529750078":"5bb50e4f538a6e4638206be119dbf712776154acfb4c06d65d66c80212341739":"7b7e640cd76086d3f640d18ceb26bb53e30282afb17401e7b48aa6818934dc5c" + +Nist Vector 3072 sign data SHA-512 #3 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"47e7af22c9298ad3bfef9bee5086bedbdc513d67416d5f4e7981cddb1002cba24700c45dd6d4dcef4f81d003f0513dab4e04eb4c70d944042e1b726d8a33050d0e4f70c0a8341b75fd4e27c7948754e441208eb93fc7b7c37354252f73b838fd02d078c6a1ae073ef1233aa1c8aa2781e193ba2897ccdd8cf617ca23541ce1c5":"232c1c88d571492779172ce6650524cb6d91174e8a23780d0fdf7c44ffd80c1a":"75163af15cd6b228251504ba024df51df32f638e37f0f2f9d08837f8c6ecfba43eb515ccbabea11b01e1e1fd3cfe7e405fc7f8142b07315e1dc37b08c78668421e2a21fc5d811d26558c504abc4e6fddf03740b8a27fa2ebcda5460ad785706c53cd2d14093d923df942051cbba2586b4d54709d24babe2f7c61a50da8451895999166e80c0fab892a37eb6782745596b49f96e11e9a957c8ec650d2d9a40aa4b014d2e9a4c08b9d7bfeaf1ecd42785b95c0172ae21cf25c4d368bb5100b6e6d92310b28b7b1afe64d496b9c60b763cac08ac46a6bce1bbd3ac8bb76bb55b649b7594820ab6ef7dd1b09bb12852816b61e6dbefab742e0ea2cda47eac7d9d913ddd4bfd8b2eb5f01951caa4f413eb5e7a41a0685695f8331a394e06b1495c170f30ac294660e8909843f9f11c4bfa64e8792df677da0a08aae32a8a4e7067fc35eee03964e8afbdb6a421b8248add284789e4ed3cace7106c23fe6666c4b12b836e7307a55ab24d92d58ac84e71f81dc9b0b7436ad07f74994af7d0b049bd09a":"101acd88a048a6a87c13ff23225dc2c4d2fe3fff039e072fbb268ef2dbfab9c3":"6175473d7aa7d5ce55590c952a19897206086887fd84bf2b566926e47981c2a3":"71d7857b6ff06ca67885fa9c9c71b8cc246d0339b6c2725247172a297e26a7b5" + +Nist Vector 3072 sign data SHA-512 #4 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"9311d8f951141713f459eb65f01880b961c0a590b36f785f1aeb880ee71300c0cbc601b3a6072193dad6ddf2028eca4c8bd7b8575187928f84bd69c5dcfb0b9d320003c3a863c09ee503e38abe07ce2e0d46b3cec926231a57defa0aebd1a6e01eef4f9b537ae1fcdf64e01434d40ab5019f3965c735411a5c19941f41febf4f":"87bde6350da15832966fe70300e5dc66b96ec263344bcfb5de051be34d76262b":"287ddc1969156c18420743ade0fa1271ea346c3329f9ca9b5d54ebfa21f676f9e013616239f4bbe60eaf8e1902ed9ac742d8df918876770894b512aaa25c068bde961f56c9b5b87806d7d0a9de7843d3cb0797903126a47bd9422337e3b46bb1f4f4a79fdf9cf6762157118aeee1e71116f34dafce0047f05d43c7f2cbd4cd52d614b7a945d48be44cfebf784332fe99c1ee1aa8310867df20b280da855b19029fa79ecd6dd6919a4d22b5a1400c30e62ce7acc4b28efbdb94ea23afbb64d6e5f7b3975d2ac63b1d048feea835c7f50b425ce3cb418afdf4dc84008473606574e20db5ebf86cb1ad27737d46494b2e485b26b8c95d829cf656f80f96b1a62e7c03c8f20f18dc58bf59916682e6dcc68d34c89c1b1bd6e6b1e15a7dc325e23fd7a35099831dbd75989c738020bf4dc4079ccb0bf12faf3b9d6494a379aacb1b66d07cbcebbf77a6e29aef22f4baa3df40d270b457dde64f00b53759ae57811b64e040cbd42ea90f4e2808bc81dfd663b28584cdb8199da96d3e03d03fb4133e2f":"7d1b5d39e51af0c22a56bc57ba6bf8bb6de18f2c256bb2d6fea684add38b1f6f":"66f729716456a2781bdb8578fa18d1e64af0edf8ec1dee0a50d25981912fc45a":"8c3cccfe6f0cfdc0ac3a542c8e8c85210bbd7f95134c8f035d1ce16f44ab7a06" + +Nist Vector 3072 sign data SHA-512 #5 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"808603f7f8439441277913b21bef4e01c89e4113e07cacc33f65ac9849db1ad1a1cb7dd2fecd88ee4139b1638355c623821309f326c16bc658bb4821518238982e5251f7cd37807292153d2b07dddc066e003c6069c371155d2d191f15111f2089ce423f5c2a1f8534e301313c69623f62ba635adce8551733a82a8fac1a66b1":"9464ce029452e8602214c5236d9637ce7e59f92536a07ac5ba30f639e09814d4":"389672ec6de0b86655cb10f1199f857013b6320d52c8728fbbb5360a9701b1d6ca4f9eecb8487fb879690f85430c582d3d91ef184c8247d162b94d6dfdfe7c4ae867ac1672827970415aa67a1406ac1a6e2c6c13167719e1d1a536d10078427c211cf682051a75ee8322c1408b89d963bd8e85f9eff7bb8ce05ca42225b4bdfead6b897b0feab76c2272b487d27d4e8dcde0f19e4615f7e1114541f61d43533ce788cc4505600b83266b1bea665912196c2c84c36aa93baf5b7464a6ddf547183e2cd058bb50a12765536f0a4d3524af4f31acc609fc447e1729aab97b5a36b01764b84bc5f77f6cc584866d1a6cfb3aa8437895f777f2dc6897499f6c5f02fa1e6c1ead68f3385b733387c6b58f2d11284a63ae7c7cfee42c3f44a3c926adad8107cca1c3f944f9b9e237d9ab35c81391d7c5f5292d1a322f7a12ce108a86237ba4de3c612fa738f53194ba67bed843cd2d4330a5d194d67cf45fa05183e0cb46c2d23a1bae76755c309fa1c31605c88a9214227ce02fe915bcf0d34bce8c8e":"5c2bb856c4d87b27e01e2ac1ae6f2fc526ab8bb49a67eda5c1d8cd4253610df3":"98fe587e43aa96f9a9bbe8af404a08b02307b36053db87f6db25a3aa36fcc3db":"5c94ea70f99f9ff14b8e5dd4a6688398260907176ea80e19c39b14621149f0d6" + +Nist Vector 3072 sign data SHA-512 #6 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"ce2aa3ed12c1b8843a3e11b06b5f0e5e63fe8e19c1a38ac446a48eeca8dac6d8b769d7809442c32ac82e93f686ec64347e9444c3f452823c840e8d0cd334b4152002148da16ac8859d189d87d67164c5db16195c081d2edd7d8157e2bf3b97a90b4b4784324eb8ceac4261809f674256daf007c4ab1f222f5fd28398a5b824de":"b887c14673cbc63f04f0839ea56a76154027d7eecf41d8d0b53d4892353ae9a4":"584fe0eb314afb866c0466c3980a2df54598d8a705dc2d1bf5102eac86312784eebd019b81a7642d4a3c4cc65dbedd8187e3593f0a9bcc06ea367009b7eb4d29b0450061378edbe163efd3f344bb36234fc86fe1c32f2c9995a07c6e957d195e8105f5179c2bd976b3127067c80ca93456c16b98dfcc7de355790f0b15cfd2ff91db09345532d46096c06b40a2304681d62857675ac50e22c7d1ab47589235419cbedd4b7d24b90531e5bfd853e88a28836ac46b6df26760985b962c6a2445809866b46126212aa263ab2a4603ff41a852c7988c2d4386241655a7222fa4e9f6eac6a144a16b059ea25b71a2138491d54ee95a9d6819977f90fe6a59e0cad81b329eba3e68277df04f9828ef6f081610b4595a92113ec6d069ffe97196d956191daabe9877377ad0416b0ee0658663377e07adb24644e8a0e3ce5fc178f152be0cd9b04071890427c6b001d59262f38fe897ce32040daa7807821c40ac8c63505bed0af070443337c9e9a64e44203c36a8ca5064d87aa0d3cd1d403aa6a24ecc":"49548238215fed6525693bc3cca3872944a97790087fb35f329b206e6046b32a":"54c99b21f28feee27f0e999aac6b49b6b07633e1db18a45952fcf7e73b166bdb":"7a18588ea1456f67562d677878346fb34b684b9a8a61a721b3db0e95695ab43a" + +Nist Vector 3072 sign data SHA-512 #7 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"17b925e2a1a51c2036e225715f2f771d8f0a6d98c7ed9cacf5aa4cd30ab16afb94e21a7c953e01ca211c28782a06073fdad27713aa8c26ae9ec449aaaa8ccfda8c947172de94b3f20b54af98df152d5d3a636c736ff01bfa699d6214002dc76dbb3f3860d94e0e34edaba5f2bfd6b2bf660086be876451a50f6a2dc7c2b098b7":"0684a8fad551c8d08beb05033185e3b4b6b6f6f4920ef9982d72d0a9c7549855":"42a93bf44ec7d2fbd651cc1d1ac391d63cab00971a7ff7a56166768b22e611dc4d729faf8c94e7ed4d6f82b7020b7b4d2fb3591cf2295cc6e1b4be2c256c2fdda43e00051114645da91cbed5cc087085f7cecd8bace67889100bcce7928220266fd3faf2ead9c21e423c9948ec70c2d31b668cdc360ddcebdf429720607f96d851235515d6dbdf163f7ea5ddf351baa76f38663fdbfbd5871bb2157df0a43420648c10e4827f54065614623ed3abad10d317be9d49a4c66564f20dcac176b6605a2e3c3c01c362220f352e477419f2b4b238affbc3920e5bb57cebb9a74746d62cdd070f4a13af001d262def014f29b7f754fac84e02d29285b73bb20ac0c8624123a577be8d6a6b9739185e4458090ddb42b005ea4fa8b51007bd9ca5b4cf2a3dca446a87ec83c9548dab46cf3daf86db3bc69a99baed459d6a197f9bf5032c1dc3a877dd7e5c1161124a6d701324e9a9712b824a4fc3b1b353259af225813c27e820b0ba72fb4e78f5c78673924e7fa2f486030284f26cb6fa31da56f49d3f":"4a258c125db1f7b775432b53c7a0ff47c00bf7af27abec7fcd42a2916e95e26d":"726e4d3baf00b259f4bdca8b0a5e1cbfd37827c48373ef5029f7601a7769478c":"903079439ebde1f766d1a8ff33e0f778d77b5e8b7b0d687443c271e8a63b5975" + +Nist Vector 3072 sign data SHA-512 #8 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"1c1169f0e790053cd7df780b5c832c64147694b4a6448ba14a426d9def7ddc78e3ed36a12da81cf9c3f245d64c859b6b4d8121d112851974df178defc977db691234d142dff99bea1957891b5d6fe8a787e96369d93c24682debd1cf3fdb64379b8c1b3b73e1bc2467dcb08b86cbd494c01477be24d7900f5a578930f4bddcb6":"3fa44778b414ff27436e276ca4904546d3542d128f73c4463c69ff9cea2b7a41":"7fca2268fba33bf94e76416a9e3869f8a90c3b0d2d37aacecd3f6785b9a95aeefe9324c3ab09ce61ffde37b50f82b699413f3b54f24d6c52eca62325029523deb05db138778447bc3d0d05aff7d85b5525f2b863d26486e84cde13e2e2117d3fa38a38d1073aaa794ed8eaa7b3d1daa4ac3e808c3738a9cbef3546cd79eccb4faa28b50fce57cdc24015fec390f0e7a7dc9f9c471d22b30c3e4174358f1ad0734cf79a09a639bdf3f3eabda2b47b81f92e2a4f9004dd641370338c02029bbf4971aa67483eea7a4bf7dff3889f84faa5765617ccab37d190a94c57f99d792807a6965e2113586c6c5d1a81abfd372e1c7954e2e09064df4d2d8288f5cdd8106ed84ffa798819a09a732bc204a812c0352e4e39d2ceb88f8e7d3624a5a5f3dc56ea0f9c5290788e12dc463161601ff3ab681bd0403ee03af45d5e586d84d9c901986718193e661256f402de735d2ca696ef6b594868950ae173f22d95856656a9d00610fe8c2bd725ae55d791277b1317085b67188da00645ce91bbe62e324311":"a05b9ca1c9532bc050cd0c1150c27bc192154cf64d59dc9a949906f1ded57e35":"1026ecee0ac31bdcdbd6103b1343f84b441fc326e1d86ad0903d0b17cfb2ff9c":"a5d3cb2e7c39d87640c4547ac6c33afccbfc1820905ba1e5be5b262313277cb9" + +Nist Vector 3072 sign data SHA-512 #9 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"805baabdd018d9e5ebb4dc51435be632d2387869756d743788442790d55bb183e26655ae3aac86dc16a48ddd268dd15e18d8320df9a1a0a6cb2b49bc701d7a15e3fe8ddd584a75c8c9aaaecd1efe17324d6261881f3d34685b04f62e968505966c9a5feb0c39b5095e5568e40f20aa21cb2505356dc9049ce56182d94a2d94a9":"770b99935d393eb90b583d1251696007cbeb1b35e6c3f4f9bcb62879070e0940":"434d0612b2a8332b0ab15614e3ee9fa245131712fb2ba84f71396fff9488dca340a37e820f44c13aa87fc9df0b7aabeae2ed85a9622b8defad474ac362a7039abde33d1df732a052446aff7857bc24d8f61d258015ed2a3060a8bf9d447e7d83d7b497a8e654731969e437b3f46f83eb58f7884ff2a2390f5d821ecaa7fd09a146c55fc1180073cc5aaa607cabb944f6078a4486cf206ddc5635242def2d3e2edcbc026bb84e849518f197399c22a9009dde9afcd8769b241c75d4ccce7f93900b5f488333df47c026c4f2b2767e70d2d9dde78405e226c9952f6db1a2e55829bc8a76c7de5c2b588f3f3e93ce72fadabacb75c7c14669701e0a2ba127bac56863c8c4e7205cc0a73c429a801e9797da4f26e848982306cc3c3439f9e394ddc80b0f13e0d528190638d8b96bba3af889de373b3549fc90a6822964c22171e7601fdefbe5708988b84f3ea554d621600a876415d5bc1e557e948caace563b3702f0915a90a13aada77709eeba8c50a8629351a4787d0d58808ffb8b217c1d164f":"424a43cfd90f7b84e9e375572f82ebce7ffb197bd3237a353bf15ddc1a17095f":"2d63e6d2568571acfe4a931580a04b974c7aae4ca9aa9610d87be1a91c657c31":"574b10d14dcb8f079461b29ae1b91ed6c5ef32f93cbad306697552c11748fe0c" + +Nist Vector 3072 sign data SHA-512 #10 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"be8ca5ed4c22a050d8309c7a31acf667f0c0fbaadc64a34d2b63074a763a2b8db73b24cdbaad26cc6f2c3e90df4b25bfa724fce587faa0fd65ffb719f0a0351648230d5354d721d8fa6d0d686c37f257d7d9dbd15f555d5073f8bc71c92139d1f627d743f7d6586d510d19d0d8a555d0bf79ec70596e712183880c89caf69d6f":"9886138d837d20e8c6be853cd7de1a66a25748c7a33fd55121a27237623d68d6":"afaff7a4d438b464f27415d2e03ed9c416db2bebfbe0ab34f14ee10644885b5a4588877150f46327c2c7a6f712670bfd6237a29452494859948f5e37c0e586656b119a0e01c81acee57c1775a3a146e8fbafc99cd203fc98195687fb94a88a4f44280b03f0895e0eca84db087c1bf7c4843c85597368e839841131e027109daa7b8172a25e11355fa9a9205ac324941a9fe492c48421f0681a47e280803e8bd91b113e0fa1597607430bcb0ad50b9408de0066d6a2324d09cf6e99133654dd64e8c8f70cd6445343758b5cd5a0e77e2d3fa1cb3f7efed76124b2881dfd2028ab5918c389b9c3978271db54a5171515ab2e85eeb10ab307130159bca5fe13cc4a959e88e9267221ac8d14ee6938e149f52ec59125b449cb55c5a0029f018770b31f08440ce6876e6600a32411722f58e6263339bd9d34e17aa574b921228926ff668ce90362c4391ecd0c037454e12fdf80c96bb7a840cd866e8570bb7d6586fbe3d1eae5332931198ba1d5d902d6b7a122dfa77018553a2dd3680a809bb06053":"1689eba0aac66b3d0cca9ae1911602f9638937b6be17c23a187be323d0dec7be":"9c7d40e214082bd5e71f3bf4be99789303f38e851a76f88cb90aff713080c587":"24ca23be94c624b9d736328b53782b5feb384dc9fe6370016cc3f97d8f48b6d0" + +Nist Vector 3072 sign data SHA-512 #11 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"62f0cb1bb07f6497a1dc7a66955765a9cc403bde03fef4e16b09d7ec545b4c75d08b6e9c4c5af7232548d45445638d7194a199ef1534e81241eaa9c7e767fd54e2caceea4d2f7215d37baad6b05e28ea093497e2e8e1db6e41a5eb13ffa4caa27108f2263a74cf54bd5b6a6b62284bac99fd7977aaa8ffff18fa8a70ab0debdf":"badece34257da3d7b8713f8f0f9f0107b1909c7f99a765ad8405d8c2a20310ee":"73554a69e1a09f6191f0aded542a077ee8c814265d745d9ae5c792f442c5fa47b34643d3ba1d5147161898de5188a80714ee36512a618a33e40300ff1187e553f54433e17466af486472bc0778af55ba7346c961d7f13ac6d8d6ac9a42092c01579ee2170590cbc3b45eef795b5d9e5d0a8449439ab307c14c5674c4a7a3eaf8b240ef36dd21f43cced58c2dcf23c314364e8e314e9671e80813d185801358d5df61d7e7ec0dd69e90c2cc75c1c3543efeca82b2ec6ec59e6c99bcd1a8631c6228e216884082da119125cb0a80c8fe344afe66e0f20646432465f3e0096a17725a8867b3bdba3c69a1aacbb8d64755b7f2a3df0a49ba0b2114e112d4cae0ad6d8d0fd618e54d53f07ba109b75a54a989618b2863e4415e176e0bfd88dbf36553ca853bb36316c66eb93da34ff3ae74cd5f187f49bf38af0f393b2d7f854df192ade2df6b39a176d2152c912bba248d84a5b0aa4084a18bb64fd136973f73b413d77db275ea5ece93ce2fa00d7c8887b7e50b00649d0353a7f58cc63f6b5fbdfc":"2d468a99e315c158a1af18abd4d58872d6e281dcd4c9b0b43298eddf346496d7":"54ff5d3dc8767856a10f54088882e28c110980ef9b204eb5f162dbef73a37c73":"57ed0748427c089d6395528b2b4555c01b4c1341ab5fb99c64d1cc247a41c3a8" + +Nist Vector 3072 sign data SHA-512 #12 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"baeb12a1ebd8057a99a0137ee60f60eed10d26f1eab22ae2d9adbc3e5ffc3252abf62b614707ad2546141bed779f0cfad9544a74e562da549e2f7b286efb615449b0946dc7c498d8f12150b2eacbd27157966f592ad5f3e43a24c60b7e06630b82a4fdb699119dbd878b13a98bf22a7b3dc7efdd992ce6b8a950e61299c5663b":"bd3006cf5d3ac04a8a5128140df6025d9942d78544e9b27efe28b2ca1f79e313":"00728e23e74bb82de0e1315d58164a5cecc8951d89e88da702f5b878020fd8d2a1791b3e8ab770e084ac2397d297971ca8708a30a4097d86740153ee2db6ab6343c5b6cc2c8a7fa59082a8d659931cc48a0433a033dbb2fff3aa545686f922c7063da1d52d9688142ec64a1002948e5da89165d9df8eed9aa469b61ee0210b4033562333097ba8659944e5f7924e04a21bc3edc6d551e202e4c543e97518f91e0cab49111029b29c3aa1bed5f35e5c90feb9d3c745953dbf859defce4537b4a09801fdc8fe6999fbde39908079811b4b992c2e8333b9f800ea0d9f0a5f53607e308942e68efef01e03d7cca6f196872bf01f436d4a8e05fc59d8fbc6b88a166f57a4e99d67ddaece844653be77819747dd2e07d581c518cb9779e9f7960c17ff0bae710ecf575b09591b013b4805c88b235df262e61a4c94f46bf9a08284611df44eadd94f44cef6225a808e211e4d3af5e96bce64a90f8013874f10749a8382a6026a855d90853440bfce31f258b3a258f7b5e659b43e702dee7c24c02d2284":"16aedfbe554de17a3e5b83e942702bd60702d9823ba154baa6d1e7e94308324d":"8d357b0b956fb90e8e0b9ff284cedc88a04d171a90c5997d8ee1e9bc4d0b35ff":"ab37329c50145d146505015704fdc4fb0fd7207e0b11d8becbad934e6255c30c" + +Nist Vector 3072 sign data SHA-512 #13 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"184e599a4c1de86c4151205754df0b1912c2b3c532552c51a61c6459db98c83e59d4a40806c6a2c6b3fe74e3bb9e720d7d0a3cc11ef88959a8990c0fa057a3915fe0dd9a138aa0ec1cb1ab69d93910d8d6f9e14f3b8a135d3f031a56c76a9dc3aed1962bdf05815c2492d14f2324d2da491810d1672b633f2419da4e7ebdef24":"a29e90d33f200b1faf61bee5d92ca8a392b1eaeeaa0817cec98b40c97e25018c":"60159720021fd2d5a2f575b3220905788d328d0c46895a46bb985942467209ec28d8ddfdc97ec34da65b164cf48652ac475d8978959cfc4330743ed98137559391b1204da6b26b451211407e8fc77d819934c48709c8eadc620f6db2592b65483265149a324467d93c375d97230f2b1a682897cf6d280df61a34f20f0c7c729a40141958044876c44e595d2378a7d22c6cda9ab816486c294e4eddea7ada88b15eca5371da164471edafcdefc654e64a1f995068fa85dbbb5516137bc442f60717fe59c629081c234f27195d5f9c2bf85cdc1ea4cae57aa908cbff9b2a53353b13e9f6fe45daa5174cd956236d447b52011d688cd22f23018409b39a36079cb53e03b6d3a752733297fea4ca27c6395becef4081d201f41d4a00e99d95f42281dcf44b9ef6754998d94231937c82594218a78463cc837193de6bf1d3c3ec31d8dc5468cb56defc9c70d08b95b029d97aa043d557f6286b87ee4098442df495c0ad8ae4d4ae037312c5f7239032c03b088c1036fad7774b1519709242c9511e6e":"78e781b2874ca2441e2ce74a2a2a16417b51537eca876831f6593ae25fbd796c":"079d4df14ad703a435b21bc70a03456ca822b876c9accb018bddd674bd6392d7":"6c7765e1f1eddf915a56a57390db45636e52f083ce440766ad4f32580f722483" + +Nist Vector 3072 sign data SHA-512 #14 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"b189dd34f58f3efa85b6f97677edfb82664cbe43a2550c336ffa08705bbda2545ef244a275014c6a265971f4c3658e5e8d6a3fafc889f3c4eda6b5616092954b15c60435efd76806e28557c05faaaa8a05c262657840865ff69c511a68d13022a712d35bde138eb7a2f8f1a87b342c7caf388c1a8b95079bc4a8003eef84b899":"9759c24820670eaeaf92370197d0037f9f71dcc283970f341117fb56a1764001":"05e280310810715d29ea1ca00a700378bd5979493b9803174c932b7dadb7029a9a9f9c91cf8f938af2bceaa052f2273f0de393b0f7544490d693f529a68b812e2e589cc092b83ef847c5306039aa8eaf225128926145893a51551db382fda4b63e5abc10fd076100684d4ca657c89b2265de6e0f0473f01bb222b2bc50ec1c5fcde9161831018aab3014a956033bb0a83866df11915808f9e7461645c89c6e17ab65dbf97cbf4ac1164d671a1516ca81645bc3e09913a03f30641bd0920083578ca84df71f62eb756ba445a0dc44f85a9e4f72ce5f6bf82ccbd674d2ce3c4afc300562a7dbd3e8ab838993f9decc9933dc07dc01b502fee5b390461a8c82c4e69615f121b3f9fd4f0c8b7620a25996df43d7cf355f15be09e2c82178c6f8836c36c1d3ef26ad05219fb57e85ef162c8dd8f0e55014769d53cba478a2aa66d90d8acd6cb0489d1eea46c2c41bd5495ab8def43b2cd5bb2673945c21c80a4833fd75d884c7675c09e7191fb26e92c54c7c8208d0a0e8dee75c2968e962de4493e8":"86050bf276a649b13c18814430eadcff54edf7416f1a8b1559c6c2c808e8dc9f":"9fd105c74a0d36973740867ccc1c731cf1c50c7935d5c09e92f574d7a569157e":"501f50c32b0288672e02aca78f90f446acf92626365957a375550c77980c3c17" + +Nist Vector 3072 sign data SHA-512 #15 +SDV_CRYPTO_DSA_SIGN_VERIFY_DATA_FUNC_TC001:CRYPT_MD_SHA512:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"42c065fadd56d6a1fe68dd4e86c17efd76d0f9db87036bd7b609159d66847f46de01b8ae43590360fa324559a2d709d45cf01034f5facb7f52324e60dd464a583d42e412659d8420f7265e30cf82bbbcb2c99b0f00ca6a46d28556428789f415000dc31babbd67ccc8fbaa84a880466bca4783eaf00b7f78231c667126433e6a":"307555893610e15549a5bfb2b446251f9595eb0c16df5fe3b784ebfc3fc30140":"b265edfed77b3ad511e56d583129b12e5796d659d484a2fce350661f79e545dd0a06c23774c8ba2fb5101a2848c413dfc5b374a7c5ff3acc7332f0ff8bd6f5fa882c0a67689308be7154c4efc51835f349525419ed722a90bf26ddded65bc8962ba11de9e734442571affc2d42b9f3f54a46535ae9eb01361adf03fc28410abf41db3ae4113da4c40e9a368f9cd029be4d98c66d835d034e3c86544b60bcb01feb383b2add9afe7b6251a17ad4e5439a9cd2d1bf62b6cf5377c097b7268bd736cca9ceb822e5d1844a09fa69c78217c3d6737f0bf45e3236508b5a3f5c466dd0d75ace95d447f9bd7aa9ee57bd10ee3c5e8389a06c00857e699794f5cacc7dc5bb1504421dc920565618bef05dc1713b6f08bc00681c5a1c0685359729fe4b544090ccceaa82f4fefa9f1117bf1e371b99fe4ed71635dad415017a62341d704227ee7cfb64a8deae90d86c0cfd37ed363d91a4a06fd06f64dbd8142c12503f49eeb1b9a971aeb343f15cd27d279b99d4cfa51f121259b3c1b55d28d994bb3299":"5359fe067eb9d98ec2217500de743b0dbe88e8d94552b53a0117aac4d3390083":"6ed82af8e89e38c49a58010f0564165a16a76a2bfb348466d9b4a91e5ce53ab2":"8c466a8b3e4c90886f29986a4d513904f31db43a68ce880311403cc755466604" + +SDV_CRYPTO_DSA_GEN_FUNC_TC001: Nist dsa para: Gen a key pair, sign and verify +SDV_CRYPTO_DSA_GEN_FUNC_TC001:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34":"42c065fadd56d6a1fe68dd4e86c17efd76d0f9db87036bd7b609159d66847f46de01b8ae43590360fa324559a2d709d45cf01034f5facb7f52324e60dd464a583d42e412659d8420f7265e30cf82bbbcb2c99b0f00ca6a46d28556428789f415000dc31babbd67ccc8fbaa84a880466bca4783eaf00b7f78231c667126433e6a" + +Nist Vector: Dup context test +SDV_CRYPTO_DSA_DUP_CTX_FUNC_TC001:"c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61":"bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1":"c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34" + +Dsa key pair check: Nist [mod = L=1024, N=160], Pass +SDV_CRYPTO_DSA_KEY_PAIR_CHECK_FUNC_TC001:"d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d4b725ef341eabb47cf8a7a8a41e792a156b7ce97206c4f9c5ce6fc5ae7912102b6b502e59050b5b21ce263dddb2044b652236f4d42ab4b5d6aa73189cef1ace778d7845a5c1c1c7147123188f8dc551054ee162b634d60f097f719076640e20980a0093113a8bd73":"96c5390a8b612c0e422bb2b0ea194a3ec935a281":"06b7861abbd35cc89e79c52f68d20875389b127361ca66822138ce4991d2b862259d6b4548a6495b195aa0e0b6137ca37eb23b94074d3c3d300042bdf15762812b6333ef7b07ceba78607610fcc9ee68491dbc1e34cd12615474e52b18bc934fb00c61d39e7da8902291c4434a4e2224c3f4fd9f93cd6f4f17fc076341a7e7d9":"8185fee9cc7c0e91fd85503274f1cd5a3fd15a49":"6f26d98d41de7d871b6381851c9d91fa03942092ab6097e76422070edb71db44ff568280fdb1709f8fc3feab39f1f824adaeb2a298088156ac31af1aa04bf54f475bdcfdcf2f8a2dd973e922d83e76f016558617603129b21c70bf7d0e5dc9e68fe332e295b65876eb9a12fe6fca9f1a1ce80204646bf99b5771d249a6fea627":1 + +Dsa key pair check: Nist [mod = L=1024, N=160], Fail +SDV_CRYPTO_DSA_KEY_PAIR_CHECK_FUNC_TC001:"d38311e2cd388c3ed698e82fdf88eb92b5a9a483dc88005d4b725ef341eabb47cf8a7a8a41e792a156b7ce97206c4f9c5ce6fc5ae7912102b6b502e59050b5b21ce263dddb2044b652236f4d42ab4b5d6aa73189cef1ace778d7845a5c1c1c7147123188f8dc551054ee162b634d60f097f719076640e20980a0093113a8bd73":"96c5390a8b612c0e422bb2b0ea194a3ec935a281":"06b7861abbd35cc89e79c52f68d20875389b127361ca66822138ce4991d2b862259d6b4548a6495b195aa0e0b6137ca37eb23b94074d3c3d300042bdf15762812b6333ef7b07ceba78607610fcc9ee68491dbc1e34cd12615474e52b18bc934fb00c61d39e7da8902291c4434a4e2224c3f4fd9f93cd6f4f17fc076341a7e7d9":"8185fee9cc7c0e91fd85503274f1cd5a3fd15a49":"21f8690f717c9f4dcb8f4b6971de2f15b9231fcf41b7eeb997d781f240bfdddfd2090d22083c26cca39bf37c9caf1ec89518ea64845a50d747b49131ffff6a2fd11ea7bacbb93c7d05137383a06365af82225dd3713ca5a45006316f53bd12b0e260d5f79795e5a4c9f353f12867a1d3202394673ada8563b71555e53f415254":0 + +SDV_CRYPTO_DSA_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_DSA_GET_KEY_BITS_FUNC_TC001:CRYPT_PKEY_DSA:3072:"f335666dd1339165af8b9a5e3835adfe15c158e4c3c7bd53132e7d5828c352f593a9a787760ce34b789879941f2f01f02319f6ae0b756f1a842ba54c85612ed632ee2d79ef17f06b77c641b7b080aff52a03fc2462e80abc64d223723c236deeb7d201078ec01ca1fbc1763139e25099a84ec389159c409792080736bd7caa816b92edf23f2c351f90074aa5ea2651b372f8b58a0a65554db2561d706a63685000ac576b7e4562e262a14285a9c6370b290e4eb7757527d80b6c0fd5df831d36f3d1d35f12ab060548de1605fd15f7c7aafed688b146a02c945156e284f5b71282045aba9844d48b5df2e9e7a5887121eae7d7b01db7cdf6ff917cd8eb50c6bf1d54f90cce1a491a9c74fea88f7e7230b047d16b5a6027881d6f154818f06e513faf40c8814630e4e254f17a47bfe9cb519b98289935bf17673ae4c8033504a20a898d0032ee402b72d5986322f3bdfb27400561f7476cd715eaabb7338b854e51fc2fa026a5a579b6dcea1b1c0559c13d3c1136f303f4b4d25ad5b692229957":"d3eba6521240694015ef94412e08bf3cf8d635a455a398d6f210f6169041653b":"ce84b30ddf290a9f787a7c2f1ce92c1cbf4ef400e3cd7ce4978db2104d7394b493c18332c64cec906a71c3778bd93341165dee8e6cd4ca6f13afff531191194ada55ecf01ff94d6cf7c4768b82dd29cd131aaf202aefd40e564375285c01f3220af4d70b96f1395420d778228f1461f5d0b8e47357e87b1fe3286223b553e3fc9928f16ae3067ded6721bedf1d1a01bfd22b9ae85fce77820d88cdf50a6bde20668ad77a707d1c60fcc5d51c9de488610d0285eb8ff721ff141f93a9fb23c1d1f7654c07c46e58836d1652828f71057b8aff0b0778ef2ca934ea9d0f37daddade2d823a4d8e362721082e279d003b575ee59fd050d105dfd71cd63154efe431a0869178d9811f4f231dc5dcf3b0ec0f2b0f9896c32ec6c7ee7d60aa97109e09224907328d4e6acd10117e45774406c4c947da8020649c3168f690e0bd6e91ac67074d1d436b58ae374523deaf6c93c1e6920db4a080b744804bb073cecfe83fa9398cf150afa286dc7eb7949750cf5001ce104e9187f7e16859afa8fd0d775ae" \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/eal/test_suite_sdv_eal.c b/testcode/sdv/testcase/crypto/eal/test_suite_sdv_eal.c new file mode 100644 index 00000000..ae8ac373 --- /dev/null +++ b/testcode/sdv/testcase/crypto/eal/test_suite_sdv_eal.c @@ -0,0 +1,481 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "eal_md_local.h" +#include "eal_pkey_local.h" +#include "crypt_eal_md.h" +#include "crypt_eal_mac.h" +#include "crypt_eal_cipher.h" +#include "crypt_eal_pkey.h" +#include "eal_common.h" + +static bool IsMacAlgIdValid(int id) +{ + int algList[] = { + CRYPT_MAC_HMAC_MD5, + CRYPT_MAC_HMAC_SHA1, + CRYPT_MAC_HMAC_SHA224, + CRYPT_MAC_HMAC_SHA256, + CRYPT_MAC_HMAC_SHA384, + CRYPT_MAC_HMAC_SHA512, + CRYPT_MAC_HMAC_SHA3_224, + CRYPT_MAC_HMAC_SHA3_256, + CRYPT_MAC_HMAC_SHA3_384, + CRYPT_MAC_HMAC_SHA3_512, + CRYPT_MAC_HMAC_SM3, + }; + int algIdCnt = sizeof(algList) / sizeof(int); + for (int i = 0; i < algIdCnt; i++) { + if (id == algList[i]) { + return true; + } + } + return false; +} + +static bool IsCipherAlgIdValid(int id) +{ + int algList[] = { + CRYPT_CIPHER_AES128_CBC, + CRYPT_CIPHER_AES192_CBC, + CRYPT_CIPHER_AES256_CBC, + CRYPT_CIPHER_AES128_CTR, + CRYPT_CIPHER_AES192_CTR, + CRYPT_CIPHER_AES256_CTR, + CRYPT_CIPHER_AES128_CCM, + CRYPT_CIPHER_AES192_CCM, + CRYPT_CIPHER_AES256_CCM, + CRYPT_CIPHER_AES128_GCM, + CRYPT_CIPHER_AES192_GCM, + CRYPT_CIPHER_AES256_GCM, + CRYPT_CIPHER_CHACHA20_POLY1305, + CRYPT_CIPHER_SM4_XTS, + CRYPT_CIPHER_SM4_CBC, + CRYPT_CIPHER_SM4_CTR, + CRYPT_CIPHER_SM4_GCM, + CRYPT_CIPHER_SM4_CFB, + CRYPT_CIPHER_SM4_OFB, + CRYPT_CIPHER_AES128_CFB, + CRYPT_CIPHER_AES192_CFB, + CRYPT_CIPHER_AES256_CFB, + CRYPT_CIPHER_AES128_OFB, + CRYPT_CIPHER_AES192_OFB, + CRYPT_CIPHER_AES256_OFB, + }; + int algIdCnt = sizeof(algList) / sizeof(int); + for (int i = 0; i < algIdCnt; i++) { + if (id == algList[i]) { + return true; + } + } + return false; +} + +static bool IsPkeyAlgIdValid(int id) +{ + int algList[] = { + CRYPT_PKEY_DSA, + CRYPT_PKEY_ED25519, + CRYPT_PKEY_X25519, + CRYPT_PKEY_RSA, + CRYPT_PKEY_DH, + CRYPT_PKEY_ECDSA, + CRYPT_PKEY_ECDH, + CRYPT_PKEY_SM2 + }; + int algIdCnt = sizeof(algList) / sizeof(int); + for (int i = 0; i < algIdCnt; i++) { + if (id == algList[i]) { + return true; + } + } + return false; +} + +#define MD_OUTPUT_MAXSIZE 128 + +static int32_t MdTest(CRYPT_EAL_MdCTX *ctx, Hex *msg, Hex *hash) +{ + (void)msg; + (void)hash; + uint8_t output[MD_OUTPUT_MAXSIZE]; + uint32_t outLen = MD_OUTPUT_MAXSIZE; + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, msg->x, msg->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, output, &outLen), CRYPT_SUCCESS); + if (ctx->id != CRYPT_MD_SHAKE128 && ctx->id != CRYPT_MD_SHAKE256) { + ASSERT_TRUE(outLen == hash->len); + } + ASSERT_EQ(memcmp(output, hash->x, hash->len), 0); + return 0; +exit: + return -1; +} +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_MAC_ALG_CHECK_TC001 + * @title Check the validity of the mac algorithm ID. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_MacIsValidAlgId method, compare the returned value with 'isValid', expected result 1 + * @expect + * 1. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MAC_ALG_CHECK_TC001(int algId) +{ + int isValid = IsMacAlgIdValid(algId); + ASSERT_TRUE(CRYPT_EAL_MacIsValidAlgId(algId) == isValid); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CIPHER_ALG_CHECK_TC001 + * @title Check the validity of the symmetric algorithm ID. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_CipherIsValidAlgId method, compare the returned value with 'isValid', expected result 1 + * @expect + * 1. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CIPHER_ALG_CHECK_TC001(int algId) +{ + int isValid = IsCipherAlgIdValid(algId); + ASSERT_TRUE(CRYPT_EAL_CipherIsValidAlgId(algId) == isValid); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_MD_COPY_FUNC_TC001 + * @title CRYPT_EAL_MdCopyCtx function test. + * @precon nan + * @brief + * 1. Create the context ctx of md algorithm, expected result 1 + * 2. Calculate the hash of msg, and compare the calculated result with hash vector, expected result 2 + * 3. Call to CRYPT_EAL_MdCopyCtx method to copy ctx, expected result 3 + * 4. Calculate the hash of msg, and compare the calculated result with hash vector, expected result 4 + * @expect + * 1. Success, the context is not null. + * 2. Success, the hashs are the same. + * 3. CRYPT_SUCCESS + * 4. Success, the hashs are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD_COPY_FUNC_TC001(int id, Hex *msg, Hex *hash) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *cpyCtx = NULL; + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(MdTest(ctx, msg, hash), 0); + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_MdCopyCtx(cpyCtx, ctx), CRYPT_SUCCESS); + ASSERT_EQ(MdTest(cpyCtx, msg, hash), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); + CRYPT_EAL_MdFreeCtx(cpyCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_NEW_CTX_API_TC001 + * @title CRYPT_EAL_PkeyNewCtx test. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method, algId is CRYPT_PKEY_MAX, expected result 1 + * @expect + * 1. Return null. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_NEW_CTX_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_MAX); + ASSERT_TRUE(pkey == NULL); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_FREE_CTX_API_TC001 + * @title CRYPT_EAL_PkeyFreeCtx test. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyFreeCtx method, ctx is null, expected result 1 + * @expect + * 1. No memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_FREE_CTX_API_TC001(void) +{ + CRYPT_EAL_PkeyFreeCtx(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_SET_PARA_API_TC001 + * @title Check the validity of the asymmetric algorithm ID. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeySetPara method: + * (1) pkey = NULL, expected result 1 + * (2) para = NULL, expected result 1 + * (3) pkey.id != para.id, expected result 2 + * @expect + * 1. CRYPT_NULL_INPUT. + * 2. CRYPT_EAL_ERR_ALGID. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_SET_PARA_API_TC001(void) +{ + CRYPT_EAL_PkeyPara para = {0}; + + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(NULL, ¶) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, NULL) == CRYPT_NULL_INPUT); + + para.id = CRYPT_PKEY_RSA; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_ALGID); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001 + * @title Check the validity of the asymmetric algorithm ID. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyIsValidAlgId method, compare the returned value with 'isValid', expected result 1 + * @expect + * 1. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001(int algId) +{ + int isValid = IsPkeyAlgIdValid(algId); + ASSERT_TRUE(CRYPT_EAL_PkeyIsValidAlgId(algId) == isValid); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_SET_PRV_API_TC001 + * @title CRYPT_EAL_PkeySetPrv bad arguments. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeySetPrv: + * (1) pkey=NULL, expected result 1 + * (2) prv=NULL, expected result 1 + * (3) pkey.id != prv.id, expected result 2 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_SET_PRV_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPrv prv = {0}; + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(NULL, &prv), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, NULL), CRYPT_NULL_INPUT); + + prv.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prv), CRYPT_EAL_ERR_ALGID); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_SET_PUB_API_TC001 + * @title CRYPT_EAL_PkeySetPub bad arguments. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeySetPub: + * (1) pkey=NULL, expected result 1 + * (2) prv=NULL, expected result 1 + * (3) pkey.id != prv.id, expected result 2 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_SET_PUB_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(NULL, &pub), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, NULL), CRYPT_NULL_INPUT); + + pub.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_EAL_ERR_ALGID); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_GEN_API_TC001 + * @title CRYPT_EAL_PkeyGen bad arguments. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeySetPub: peky = NULL, expected result 1 + * @expect + * 1. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_GEN_API_TC001(void) +{ + ASSERT_EQ(CRYPT_EAL_PkeyGen(NULL), CRYPT_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_CMP_TC001 + * @title CRYPT_EAL_PkeyCmp Test. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyCmp, ctx1=NULL, ctx2=NULL, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp, ctx1=NULL, ctx2!=NULL or ctx1=NULL, ctx2!=NULL, expected result 2 + * 3. Call the CRYPT_EAL_PkeyCmp, ctx1!=NULL, ctx2!=NULL, the content in ctx1 and ctx2 is empty, expected result 2 + * 4. Call the CRYPT_EAL_PkeyCmp, ctx1!=NULL, ctx2!=NULL, ctx1.id!=ctx2.id, expected result 3 + * 5. Call the CRYPT_EAL_PkeyCmp, ctx1->pkey=NULL, expected result 2 + * @expect + * 1. CRYPT_SUCCESS + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_CMP_TC001(void) +{ + CRYPT_EAL_PkeyCtx ctx1 = {0}; + CRYPT_EAL_PkeyCtx ctx2 = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(NULL, NULL), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(NULL, &ctx2), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(&ctx1, NULL), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(&ctx1, &ctx2), CRYPT_NULL_INPUT); + + ctx1.id = CRYPT_PKEY_DH; + ctx2.id = CRYPT_PKEY_DSA; + ASSERT_EQ(CRYPT_EAL_PkeyCmp(&ctx1, &ctx2), CRYPT_EAL_PKEY_CMP_DIFF_KEY_TYPE); + + ctx2.id = CRYPT_PKEY_DH; + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + ASSERT_TRUE(pkey != NULL); + ASSERT_TRUE(pkey->method != NULL); + ctx1.method = pkey->method; + ctx2.method = pkey->method; + ASSERT_EQ(CRYPT_EAL_PkeyCmp(&ctx1, &ctx2), CRYPT_NULL_INPUT); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_GET_ID_API_TC001 + * @title CRYPT_EAL_PkeyGetId Test. + * @precon nan + * @brief + * 1. Create the context(ctx) of pkeyId, expected result 1 + * 2. Call the CRYPT_EAL_PkeyGetId to get id of ctx, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetId to get id of NULL, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. The getted id and pkeyId are the same. + * 3. Get id: CRYPT_PKEY_MAX + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_GET_ID_API_TC001(void) +{ + int pkeyId = CRYPT_PKEY_DSA; + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(pkeyId); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyGetId(ctx), pkeyId); + ASSERT_EQ(CRYPT_EAL_PkeyGetId(NULL), CRYPT_PKEY_MAX); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_EAL_PKEY_EXT_DATA_API_TC001 + * @title CRYPT_EAL_PkeySetExtData/CRYPT_EAL_PkeyGetExtData Test. + * @precon nan + * @brief + * 1. Create the context(ctx) of pkeyId, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetExtData to set ext data, ctx is null, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetExtData to set ext data, all parameters are valid, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGetExtData to get ext data, ctx is null, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetExtData to get ext data, all parameters are valid, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + * 4. Return null. + * 5. The returned value is not null and the value is correct. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_EAL_PKEY_EXT_DATA_API_TC001(void) +{ + int pkeyId = CRYPT_PKEY_DSA; + int data = 1; + void *ptr = NULL; + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(pkeyId); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetExtData(NULL, &data), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetExtData(ctx, &data), CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetExtData(NULL) == NULL); + ptr = CRYPT_EAL_PkeyGetExtData(ctx); + ASSERT_TRUE(ptr != NULL); + ASSERT_EQ(*(int *)ptr, data); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/eal/test_suite_sdv_eal.data b/testcode/sdv/testcase/crypto/eal/test_suite_sdv_eal.data new file mode 100644 index 00000000..0c7985ac --- /dev/null +++ b/testcode/sdv/testcase/crypto/eal/test_suite_sdv_eal.data @@ -0,0 +1,206 @@ +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_MD5 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_MD5 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA1 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA224 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA256 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA384 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA512 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_224 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_256 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_384 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_512 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SM3 +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_HMAC_SM3 + +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_MAX +SDV_CRYPTO_MAC_ALG_CHECK_TC001:CRYPT_MAC_MAX + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CBC +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CBC + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CBC +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CBC + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CBC +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CBC + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CTR +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CTR + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CTR +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CTR + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CTR +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CTR + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_GCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_GCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_GCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_GCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_GCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_GCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_CHACHA20_POLY1305 +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_CHACHA20_POLY1305 + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_XTS +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_XTS + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_CBC +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_CBC + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_CTR +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_CTR + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_GCM +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_GCM + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_CFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_CFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_OFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_SM4_OFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_CFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_CFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_CFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_OFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES128_OFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_OFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES192_OFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_OFB +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_AES256_OFB + +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_MAX +SDV_CRYPTO_CIPHER_ALG_CHECK_TC001:CRYPT_CIPHER_MAX + +SDV_CRYPTO_MD_COPY_FUNC_TC001: md5 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_MD5:"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890":"a2fa77aa832a0d01c636a2e508130741" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: sm3 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SM3:"616263":"66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: sha1 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA1:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"4d01e80edcd47add75c3d2d38a1a5b6eba065c5c" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA224 NIST Vector +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA224:"a4bc10b1a62c96d459fbaf3a5aa3face73":"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA256 NIST Vector +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA256:"1b503fb9a73b16ada3fcf1042623ae7610":"d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA384 NIST Vector +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA384:"bb84a014cd17cc232c98ae8b0709917e9d":"85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA512 NIST Vector +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA512:"6ba004fd176791efb381b862e298c67b08":"112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA3_224 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA3_224:"01":"488286d9d32716e5881ea1ee51f36d3660d70f0db03b3f612ce9eda4" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA3_256 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA3_256:"e9":"f0d04dd1e6cfc29a4460d521796852f25d9ef8d28b44ee91ff5b759d72c1e6d6" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA3_384 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA3_384:"80":"7541384852e10ff10d5fb6a7213a4a6c15ccc86d8bc1068ac04f69277142944f4ee50d91fdc56553db06b2f5039c8ab7" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHA3_512 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHA3_512:"e5":"150240baf95fb36f8ccb87a19a41767e7aed95125075a2b2dbba6e565e1ce8575f2b042b62e29a04e9440314a821c6224182964d8b557b16a492b3806f4c39c1" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHAKE128 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHAKE128:"0e":"fa996dafaa208d72287c23bc4ed4bfd5" + +SDV_CRYPTO_MD_COPY_FUNC_TC001: SHAKE256 +SDV_CRYPTO_MD_COPY_FUNC_TC001:CRYPT_MD_SHAKE256:"0f":"aabb07488ff9edd05d6a603b7791b60a16d45093608f1badc0c9cc9a9154f215" + +CRYPT_EAL_PkeyNewCtx bad arguments test1 +SDV_CRYPTO_EAL_PKEY_NEW_CTX_API_TC001: + +CRYPT_EAL_PkeyFreeCtx bad arguments test1 +SDV_CRYPTO_EAL_PKEY_FREE_CTX_API_TC001: + +CRYPT_EAL_PkeySetPara different id test +SDV_CRYPTO_EAL_PKEY_SET_PARA_API_TC001 + +CRYPT_EAL_PkeySetPrv bad arguments +SDV_CRYPTO_EAL_PKEY_SET_PRV_API_TC001 + +CRYPT_EAL_PkeySetPub bad arguments +SDV_CRYPTO_EAL_PKEY_SET_PUB_API_TC001 + +SDV_CRYPTO_EAL_PKEY_GEN_API_TC001 +SDV_CRYPTO_EAL_PKEY_GEN_API_TC001 + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_DSA +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_DSA + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_ED25519 +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_X25519 +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_X25519 + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_RSA +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_RSA + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_DH +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_DH + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_ECDSA +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_ECDSA + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_ECDH +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_ECDH + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_SM2 +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_SM2 + +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_MAX +SDV_CRYPTO_EAL_PKEY_ALG_CHECK_TC001:CRYPT_PKEY_MAX + +SDV_CRYPTO_EAL_PKEY_CMP_TC001 +SDV_CRYPTO_EAL_PKEY_CMP_TC001: + +SDV_CRYPTO_EAL_PKEY_GET_ID_API_TC001 +SDV_CRYPTO_EAL_PKEY_GET_ID_API_TC001: + +SDV_CRYPTO_EAL_PKEY_EXT_DATA_API_TC001 +SDV_CRYPTO_EAL_PKEY_EXT_DATA_API_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/ealinit/test_suite_sdv_ealinit.c b/testcode/sdv/testcase/crypto/ealinit/test_suite_sdv_ealinit.c new file mode 100644 index 00000000..1056eb8f --- /dev/null +++ b/testcode/sdv/testcase/crypto/ealinit/test_suite_sdv_ealinit.c @@ -0,0 +1,309 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "stub_replace.h" +#include "crypt_errno.h" +#include "crypt_utils.h" +#include "bsl_init.h" +#include "bsl_err.h" +#include "bsl_err_internal.h" +#include "crypt_eal_rand.h" +#include "crypt_eal_md.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_mac.h" +#include "crypt_eal_kdf.h" +#include "crypt_eal_cipher.h" +#include "asmcap_local.h" +/* END_HEADER */ + +#define DATA_LEN (64) +void ResetStatus(void) +{ + CRYPT_EAL_RandDeinit(); + BSL_GLOBAL_DeInit(); +} + +bool STUB_IsSupportAVX() +{ + return false; +} + +bool STUB_CRYPT_AES_AsmCheck() +{ + return false; +} + +bool STUB_IsSupportNEON() +{ + return false; +} + +bool STUB_IsSupportBMI1() +{ + return false; +} + +bool STUB_IsSupportMOVBE() +{ + return false; +} + +bool STUB_IsSupportAES() +{ + return false; +} + +int32_t STUB_CRYPT_GHASH_AsmCheck() +{ + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; +} + +int32_t STUB_CRYPT_POLY1305_AsmCheck() +{ + return CRYPT_EAL_ALG_ASM_NOT_SUPPORT; +} + +#define CRYPT_INIT_ABILITY_CPU_POS 0 +#define CRYPT_INIT_ABILITY_BSL_POS 1 +#define CRYPT_INIT_ABILITY_RAND_POS 2 + +#define CRYPT_INIT_ABILITY_BITMAP(value, pos) (((value) >> (pos)) & 0x1) +#define CRYPT_INIT_SUPPORT_ABILITY(cap, pos) (CRYPT_INIT_ABILITY_BITMAP(cap, pos) != 0) + +#define DRBG_MAX_OUTPUT_SIZE (1 << 16) + + +/* @ +* @test SDV_CRYPT_INIT_FUNC_TC001 +* @spec - +* @title CRYPT_EAL_Init functional test as constructor +* @precon nan +* @brief 1. CRYPT_EAL_Init called as constructor + 2. check if DRBG is initialized. + 3、check if BSL is initialized. +* @expect 1. DRBG is initialized + 2、BSL is initialized +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void SDV_CRYPT_INIT_FUNC_TC001() +{ + uint8_t output[DATA_LEN]; + uint32_t len = DATA_LEN; + int32_t ret = CRYPT_SUCCESS; +#if defined(HITLS_EAL_INIT_OPTS) + if(CRYPT_INIT_SUPPORT_ABILITY(HITLS_EAL_INIT_OPTS, CRYPT_INIT_ABILITY_RAND_POS)) { + ret = CRYPT_EAL_ERR_DRBG_REPEAT_INIT; + } + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_AES128_CTR, NULL, NULL, NULL, 0) == ret); + ASSERT_TRUE(CRYPT_EAL_Randbytes(output, len) == CRYPT_SUCCESS); +#endif + +exit: + ResetStatus(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CRYPT_EAL_Init_TC002 + * @title Check if cpu capability is called at entry point. + * @precon nan + * @brief + * 1. STUB function + * 1. call CRYPT_EAL_CipherNewCtx + * @expect + * 1. CRYPT_EAL_CipherNewCtx returns NULL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CRYPT_EAL_Init_TC002() +{ + FuncStubInfo tmpStubInfo = {0}; + CRYPT_EAL_CipherCtx *ctx = NULL; + STUB_Init(); + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_CipherFreeCtx(ctx); +#if defined(HITLS_CRYPTO_ASM_CHECK) +#if defined(__x86_64__) +#if defined(HITLS_CRYPTO_AES_ASM) + STUB_Replace(&tmpStubInfo, IsSupportAVX, STUB_IsSupportAVX); + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx == NULL); +#endif +#if defined(HITLS_CRYPTO_SM4_ASM) + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC); + ASSERT_TRUE(ctx == NULL); +#endif + STUB_Reset(&tmpStubInfo); +#elif defined(__aarch64__) +#if defined(HITLS_CRYPTO_AES_ASM) + STUB_Replace(&tmpStubInfo, IsSupportAES, STUB_IsSupportAES); + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AES128_CBC); + ASSERT_TRUE(ctx == NULL); +#endif +#endif +#endif +exit: + STUB_Reset(&tmpStubInfo); + ResetStatus(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CRYPT_EAL_Init_TC003 + * @title Check if cpu capability is called at entry point. + * @precon nan + * @brief + * 1. STUB function + * 1. call CRYPT_EAL_MdNewCtx + * @expect + * 1. CRYPT_EAL_CipherNewCtx returns NULL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CRYPT_EAL_Init_TC003() +{ + CRYPT_EAL_MdCTX *ctx = NULL; + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_MdFreeCtx(ctx); +#if defined(HITLS_CRYPTO_ASM_CHECK) +#if defined(__x86_64__) +#if defined(HITLS_CRYPTO_SM2_ASM) + FuncStubInfo tmpStubInfo = {0}; + STUB_Init(); + STUB_Replace(&tmpStubInfo, IsSupportMOVBE, STUB_IsSupportMOVBE); + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx == NULL); + STUB_Reset(&tmpStubInfo); +#endif +#endif +#endif +exit: + ResetStatus(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CRYPT_EAL_Init_TC004 + * @title Check if cpu capability is called at entry point. + * @precon nan + * @brief + * 1. STUB function + * 1. call CRYPT_EAL_MdNewCtx + * @expect + * 1. CRYPT_EAL_CipherNewCtx returns NULL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CRYPT_EAL_Init_TC004() +{ + ResetStatus(); + FuncStubInfo tmpStubInfo = {0}; + STUB_Init(); + uint32_t keyLen = DATA_LEN; + uint8_t key[keyLen]; + uint32_t saltLen = DATA_LEN; + uint8_t salt[saltLen]; + uint32_t it = 1024; + uint32_t outLen = DATA_LEN; + uint8_t out[outLen]; + ASSERT_TRUE(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, keyLen, salt, saltLen, it, out, outLen) == CRYPT_SUCCESS); +#if defined(HITLS_CRYPTO_ASM_CHECK) +#if defined(__x86_64__) +#if defined(HITLS_CRYPTO_SHA2_ASM) + STUB_Replace(&tmpStubInfo, IsSupportAVX, STUB_IsSupportAVX); + ASSERT_TRUE(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, keyLen, salt, saltLen, it, out, outLen) != CRYPT_SUCCESS); + STUB_Reset(&tmpStubInfo); +#endif +#if defined(HITLS_CRYPTO_MD5_ASM) + STUB_Replace(&tmpStubInfo, IsSupportBMI1, STUB_IsSupportBMI1); + ASSERT_TRUE(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_MD5, key, keyLen, salt, saltLen, it, out, outLen) != CRYPT_SUCCESS); + STUB_Reset(&tmpStubInfo); +#endif +#if defined(HITLS_CRYPTO_SM3_ASM) + STUB_Replace(&tmpStubInfo, IsSupportMOVBE, STUB_IsSupportMOVBE); + ASSERT_TRUE(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SM3, key, keyLen, salt, saltLen, it, out, outLen) != CRYPT_SUCCESS); + STUB_Reset(&tmpStubInfo); +#endif +#endif +#endif +exit: + STUB_Reset(&tmpStubInfo); + ResetStatus(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_CRYPT_EAL_Init_TC005 + * @title Check if cpu capability is called at entry point. + * @precon nan + * @brief + * 1. STUB function + * 1. call CRYPT_EAL_MdNewCtx + * @expect + * 1. CRYPT_EAL_CipherNewCtx returns NULL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_CRYPT_EAL_Init_TC005() +{ + ResetStatus(); + FuncStubInfo tmpStubInfo = {0}; + CRYPT_EAL_RndCtx *ctx = NULL; + STUB_Init(); + ctx = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_DrbgDeinit(ctx); +#if defined(HITLS_CRYPTO_ASM_CHECK) +#if defined(__x86_64__) +#if defined(HITLS_CRYPT_SHA1_ASM) + STUB_Replace(&tmpStubInfo, IsSupportAVX, STUB_IsSupportAVX); + ctx = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA1, NULL, NULL, NULL, 0); + ASSERT_TRUE(ctx == NULL); + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_SHA1, NULL, NULL, NULL, 0) == CRYPT_EAL_ERR_DRBG_INIT_FAIL); +#endif +#if defined(HITLS_CRYPT_SHA2_ASM) + ctx = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + ASSERT_TRUE(ctx == NULL); + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0) == CRYPT_EAL_ERR_DRBG_INIT_FAIL); +#endif +#if defined(HITLS_CRYPT_AES_ASM) + ctx = CRYPT_EAL_DrbgInit(CRYPT_RAND_AES128_CTR, NULL, NULL, NULL, 0); + ASSERT_TRUE(ctx == NULL); + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_AES128_CTR, NULL, NULL, NULL, 0) == CRYPT_EAL_ERR_DRBG_INIT_FAIL); + STUB_Reset(&tmpStubInfo); +#endif +#if defined(HITLS_CRYPT_SHA2_ASM) + STUB_Replace(&tmpStubInfo, IsSupportMOVBE, STUB_IsSupportMOVBE); + ctx = CRYPT_EAL_DrbgInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0); + ASSERT_TRUE(ctx == NULL); + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0) == CRYPT_EAL_ERR_DRBG_INIT_FAIL); +#endif +#elif defined(__aarch64__) +#if defined(HITLS_CRYPT_AES_ASM) + STUB_Replace(&tmpStubInfo, IsSupportAES, STUB_IsSupportAES); + ctx = CRYPT_EAL_DrbgInit(CRYPT_RAND_AES128_CTR, NULL, NULL, NULL, 0); + ASSERT_TRUE(ctx == NULL); + ASSERT_TRUE(CRYPT_EAL_RandInit(CRYPT_RAND_AES128_CTR, NULL, NULL, NULL, 0) == CRYPT_EAL_ERR_DRBG_INIT_FAIL); + STUB_Reset(&tmpStubInfo); +#endif +#endif +#endif +exit: + STUB_Reset(&tmpStubInfo); + ResetStatus(); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/ealinit/test_suite_sdv_ealinit.data b/testcode/sdv/testcase/crypto/ealinit/test_suite_sdv_ealinit.data new file mode 100644 index 00000000..160be200 --- /dev/null +++ b/testcode/sdv/testcase/crypto/ealinit/test_suite_sdv_ealinit.data @@ -0,0 +1,14 @@ +SDV_CRYPT_INIT_FUNC_TC001 +SDV_CRYPT_INIT_FUNC_TC001: + +SDV_CRYPTO_CRYPT_EAL_Init_TC002 +SDV_CRYPTO_CRYPT_EAL_Init_TC002: + +SDV_CRYPTO_CRYPT_EAL_Init_TC003 +SDV_CRYPTO_CRYPT_EAL_Init_TC003: + +SDV_CRYPTO_CRYPT_EAL_Init_TC005 +SDV_CRYPTO_CRYPT_EAL_Init_TC005: + +SDV_CRYPTO_CRYPT_EAL_Init_TC004 +SDV_CRYPTO_CRYPT_EAL_Init_TC004: \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecc.base.c b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecc.base.c new file mode 100644 index 00000000..5fea9b73 --- /dev/null +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecc.base.c @@ -0,0 +1,814 @@ +/* + * 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 +#include +#include +#include +#include "securec.h" +#include "crypt_bn.h" +#include "bsl_err.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_dsa.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_rand.h" +#include "stub_replace.h" +#include "crypt_util_rand.h" +#include "crypt_encode.h" +#include "crypt_eal_md.h" +#include "crypt_dsa.h" +#include "crypt_ecdh.h" +#include "crypt_ecdsa.h" +#include "crypt_ecc.h" +#include "eal_pkey_local.h" + +#define SUCCESS 0 +#define ERROR (-1) +#define BITS_OF_BYTE 8 +#define KEY_MAX_LEN 133 +#define PUBKEY_MAX_LEN 133 // 521(The public key length of the longest curve.) * 2 + 1 1043 +#define PRVKEY_MAX_LEN 65 +#define ECC_MAX_BIT_LEN 521 +static uint8_t gkRandBuf[80]; +static uint32_t gkRandBufLen = 0; + +typedef struct { + uint8_t data[KEY_MAX_LEN]; + uint32_t len; +} KeyData; + +static int32_t RandFunc(uint8_t *randNum, uint32_t randLen) +{ + const int maxNum = 255; + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % maxNum); + } + return 0; +} + +static int32_t STUB_RandRangeK(BN_BigNum *r, const BN_BigNum *p) +{ + (void)p; + BN_Bin2Bn(r, gkRandBuf, gkRandBufLen); + return CRYPT_SUCCESS; +} + +static int32_t EccPointToBuffer(Hex *pubKeyX, Hex *pubKeyY, CRYPT_PKEY_PointFormat pointFormat, KeyData *pubKey) +{ + uint8_t value; + value = *(uint8_t *)(pubKeyY->x + pubKeyY->len - 1); + int sign = 0; /* The value 0 indicates an odd number.*/ + if (value % 2 == 0) { + sign = 1; + } + switch (pointFormat) { + case CRYPT_POINT_COMPRESSED: { + pubKey->data[0] = (sign == 1) ? 0x02 : 0x03; + ASSERT_TRUE_AND_LOG( + "memcpy_s", memcpy_s(pubKey->data + 1, pubKey->len - 1, pubKeyX->x, pubKeyX->len) == EOK); + pubKey->len = pubKeyX->len + 1; + } break; + case CRYPT_POINT_UNCOMPRESSED: { + pubKey->data[0] = 0x04; + ASSERT_TRUE_AND_LOG( + "memcpy_s", memcpy_s(pubKey->data + 1, pubKey->len - 1, pubKeyX->x, pubKeyX->len) == EOK); + ASSERT_TRUE_AND_LOG("memcpy_s", + memcpy_s(pubKey->data + 1 + pubKeyX->len, pubKey->len - 1 - pubKeyX->len, pubKeyY->x, pubKeyY->len) == + EOK); + pubKey->len = pubKeyX->len + pubKeyY->len + 1; + } break; + case CRYPT_POINT_HYBRID: { + pubKey->data[0] = (sign == 1) ? 0x06 : 0x07; + ASSERT_TRUE_AND_LOG( + "memcpy_s", memcpy_s(pubKey->data + 1, pubKey->len - 1, pubKeyX->x, pubKeyX->len) == EOK); + ASSERT_TRUE_AND_LOG("memcpy_s", + memcpy_s(pubKey->data + 1 + pubKeyX->len, pubKey->len - 1 - pubKeyX->len, pubKeyY->x, pubKeyY->len) == + EOK); + pubKey->len = pubKeyX->len + pubKeyY->len + 1; + } break; + default: + return ERROR; + } + return SUCCESS; + +exit: + return -1; /* -1 indicates an exception. */ +} + +static int GetPubKeyLen(int eccId) +{ + switch (eccId) { + case CRYPT_ECC_NISTP224: + return 57; /* SECP224R1 */ + case CRYPT_ECC_NISTP256: /* (32 * 2) + 1 SECP256R1, brainpoolP256r1 */ + case CRYPT_ECC_BRAINPOOLP256R1: + return 65; + case CRYPT_ECC_NISTP384: /* (48 * 2) + 1 SECP384R1, brainpoolP384r1 */ + case CRYPT_ECC_BRAINPOOLP384R1: + return 97; + case CRYPT_ECC_BRAINPOOLP512R1: + return 129; /* brainpoolP512r1 */ + case CRYPT_ECC_NISTP521: + return 133; /* (66 * 2) + 1 SECP521R1 */ + default: + return SUCCESS; + } +} + +static int GetPrvKeyLen(int eccId) +{ + switch (eccId) { + case CRYPT_ECC_NISTP224: + return 28; + case CRYPT_ECC_NISTP256: + case CRYPT_ECC_BRAINPOOLP256R1: + return 32; + case CRYPT_ECC_NISTP384: + case CRYPT_ECC_BRAINPOOLP384R1: + return 48; + case CRYPT_ECC_BRAINPOOLP512R1: + return 64; + case CRYPT_ECC_NISTP521: + return 66; + default: + return SUCCESS; + } +} + +static void Ecc_SetPubKey(CRYPT_EAL_PkeyPub *pub, int id, uint8_t *key, uint32_t len) +{ + pub->id = id; + pub->key.eccPub.data = key; + pub->key.eccPub.len = len; +} + +static void Ecc_SetPrvKey(CRYPT_EAL_PkeyPrv *prv, int id, uint8_t *key, uint32_t len) +{ + prv->id = id; + prv->key.eccPrv.data = key; + prv->key.eccPrv.len = len; +} + +static int Ecc_GenKey(int algId, int eccId, Hex *prvKeyVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat) +{ + int ret; + FuncStubInfo tmpRpInfo; + CRYPT_EAL_PkeyCtx *pkey = NULL; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + CRYPT_EAL_PkeyPub ecdsaPubKey = {0}; + CRYPT_EAL_PkeyPrv ecdsaPrvKey = {0}; + + /* Init the DRBG */ + TestMemInit(); + + /* Create a key structure. */ + pkey = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(pkey, eccId), CRYPT_SUCCESS); + + /* Mock BN_RandRange to STUB_RandRangeK */ + ASSERT_TRUE(memcpy_s(gkRandBuf, sizeof(gkRandBuf), prvKeyVector->x, prvKeyVector->len) == 0); + gkRandBufLen = prvKeyVector->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + /* Generate a key pair */ + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + /* Set point format*/ + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, 4, &pointFormat, sizeof(uint32_t)), CRYPT_SUCCESS); + + /* Get public key */ + ecdsaPubKey.id = algId; + ecdsaPubKey.key.eccPub.data = (uint8_t *)malloc(GetPubKeyLen(eccId)); + ASSERT_TRUE(ecdsaPubKey.key.eccPub.data != NULL); + ecdsaPubKey.key.eccPub.len = GetPubKeyLen(eccId); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &ecdsaPubKey), CRYPT_SUCCESS); + + /* Get private key */ + ecdsaPrvKey.id = algId; + ecdsaPrvKey.key.eccPrv.data = (uint8_t *)malloc(GetPrvKeyLen(eccId)); + ASSERT_TRUE(ecdsaPrvKey.key.eccPrv.data != NULL); + ecdsaPrvKey.key.eccPrv.len = GetPrvKeyLen(eccId); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &ecdsaPrvKey), CRYPT_SUCCESS); + + /* Convert the point to buffer */ + ret = EccPointToBuffer(pubKeyX, pubKeyY, pointFormat, &pubKeyVector); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", ret == CRYPT_SUCCESS); + ASSERT_COMPARE("Compare PubKey", + pubKeyVector.data, + ecdsaPubKey.key.eccPub.len, + ecdsaPubKey.key.eccPub.data, + ecdsaPubKey.key.eccPub.len); + + ASSERT_COMPARE("Compare PrvKey", + prvKeyVector->x, + ecdsaPrvKey.key.eccPrv.len, + ecdsaPrvKey.key.eccPrv.data, + ecdsaPrvKey.key.eccPrv.len); + + free(ecdsaPubKey.key.eccPub.data); + free(ecdsaPrvKey.key.eccPrv.data); + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + return SUCCESS; +exit: + free(ecdsaPubKey.key.eccPub.data); + free(ecdsaPrvKey.key.eccPrv.data); + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + return ERROR; +} + +int EAL_PkeyNewCtx_Api_TC001(int algId) +{ + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + + /* Registers memory functions. */ + TestMemInit(); + pkeyCtx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyNewCtx", pkeyCtx != NULL); + + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return ERROR; +} + +int EAL_PkeyFreeCtx_Api_TC001(int algId) +{ + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + TestMemInit(); + pkeyCtx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyNewCtx", pkeyCtx != NULL); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + pkeyCtx = NULL; + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return ERROR; +} + +int EAL_PkeySetParaById_Api_TC001(int algId) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + TestMemInit(); + pkeyCtx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyNewCtx", pkeyCtx != NULL); + ASSERT_TRUE_AND_LOG("Invalid Pkey", CRYPT_EAL_PkeySetParaById(NULL, CRYPT_ECC_NISTP224) == CRYPT_NULL_INPUT); + ASSERT_TRUE_AND_LOG("CRYPT_ECC_NISTP224", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("CRYPT_ECC_NISTP256", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_NISTP256) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("CRYPT_ECC_NISTP384", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_NISTP384) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("CRYPT_ECC_NISTP521", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_NISTP521) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG( + "CRYPT_ECC_BRAINPOOLP256R1", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_BRAINPOOLP256R1) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG( + "CRYPT_ECC_BRAINPOOLP384R1", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_BRAINPOOLP384R1) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG( + "CRYPT_ECC_BRAINPOOLP512R1", CRYPT_EAL_PkeySetParaById(pkeyCtx, CRYPT_ECC_BRAINPOOLP512R1) == CRYPT_SUCCESS); + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return ret; +} + +int EAL_PkeyCtrl_Api_TC001(int algId, int type, int expect) +{ + int ret = ERROR; + int32_t value = 1; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyNewCtx", pkeyCtx != NULL); + + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyCtrl", CRYPT_EAL_PkeyCtrl(pkeyCtx, type, &value, sizeof(int32_t)) == expect); + + ret = SUCCESS; + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return ret; +} + +int EAL_PkeyCtrl_Api_TC002(int algId) +{ + uint32_t ret, pointFormat; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyNewCtx", pkeyCtx != NULL); + + pointFormat = 1; + ret = CRYPT_EAL_PkeyCtrl(NULL, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("pkey = null", ret == CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, NULL, 0); + ASSERT_TRUE_AND_LOG("val = null, len = 0", ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, NULL, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("val = null, len != 0", ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, 0); + ASSERT_TRUE_AND_LOG("val != null, len = 0", ret == CRYPT_ECC_PKEY_ERR_CTRL_LEN); + + pointFormat = CRYPT_POINT_MAX; + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("PointFormat = CRYPT_POINT_MAX", ret == CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT); + pointFormat = CRYPT_POINT_COMPRESSED; + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("PointFormat = CRYPT_POINT_COMPRESSED", ret == CRYPT_SUCCESS); + pointFormat = CRYPT_POINT_UNCOMPRESSED; + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("PointFormat = CRYPT_POINT_UNCOMPRESSED", ret == CRYPT_SUCCESS); + pointFormat = CRYPT_POINT_HYBRID; + ret = CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("PointFormat = CRYPT_POINT_HYBRID", ret == CRYPT_SUCCESS); + + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + return ERROR; +} + +int EAL_PkeyCtrl_Api_TC003(int algId, int eccId, Hex *pubKeyX, Hex *pubKeyY) +{ + uint32_t ret, pointFormat; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPub pub1 = {0}; + CRYPT_EAL_PkeyPub pub2 = {0}; + KeyData pubKeyVector1 = {{0}, KEY_MAX_LEN}; + KeyData pubKeyVector2 = {{0}, KEY_MAX_LEN}; + KeyData pubKeyVector3 = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeySetParaById", CRYPT_EAL_PkeySetParaById(ctx, eccId) == CRYPT_SUCCESS); + + /* Convert the format of point to compressed. */ + ret = EccPointToBuffer(pubKeyX, pubKeyY, CRYPT_POINT_COMPRESSED, &pubKeyVector1); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", ret == CRYPT_SUCCESS); + + /* Set public key. */ + Ecc_SetPubKey(&pub1, algId, pubKeyVector1.data, pubKeyVector1.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub1), CRYPT_SUCCESS); + + /* Set the point format to compressed. */ + pointFormat = CRYPT_POINT_COMPRESSED; + ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("Set CRYPT_POINT_COMPRESSED", ret == CRYPT_SUCCESS); + /* Set the point format to hybrid. */ + pointFormat = CRYPT_POINT_HYBRID; + ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_ECC_POINT_FORMAT, &pointFormat, sizeof(uint32_t)); + ASSERT_TRUE_AND_LOG("Set CRYPT_POINT_HYBRID", ret == CRYPT_SUCCESS); + + /* Get the public key. */ + Ecc_SetPubKey(&pub2, algId, pubKeyVector2.data, GetPubKeyLen(eccId)); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub2), CRYPT_SUCCESS); + + /* Convert the format of point to hybrid. */ + ret = EccPointToBuffer(pubKeyX, pubKeyY, pointFormat, &pubKeyVector3); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", ret == CRYPT_SUCCESS); + + /* Compare */ + ASSERT_TRUE_AND_LOG("Compare PubKey Len", pub2.key.eccPub.len == pubKeyVector3.len); + ASSERT_TRUE_AND_LOG("Compare PubKey", memcmp(pub2.key.eccPub.data, pubKeyVector3.data, pubKeyVector3.len) == 0); + + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_RandDeinit(); + return SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_RandDeinit(); + return ERROR; +} + +int EAL_PkeyGetPrv_Api_TC001(int algId, Hex *prvKey) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPrv prv1 = {0}; + CRYPT_EAL_PkeyPrv prv2 = {0}; + KeyData prvKeyBuffer = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + ASSERT_TRUE_AND_LOG("SetParaById", CRYPT_EAL_PkeySetParaById(ctx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Get the private key when there is no private key. */ + Ecc_SetPrvKey(&prv2, algId, prvKeyBuffer.data, GetPrvKeyLen(CRYPT_ECC_NISTP224)); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(ctx, &prv2), CRYPT_ECC_PKEY_ERR_EMPTY_KEY); + + /* Set the private key. */ + Ecc_SetPrvKey(&prv1, algId, prvKey->x, prvKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv1), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyGetPrv. */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(NULL, &prv2), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(ctx, NULL), CRYPT_NULL_INPUT); + prv2.id = CRYPT_PKEY_DH; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(ctx, &prv2), CRYPT_EAL_ERR_ALGID); + prv2.id = algId; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(ctx, &prv2), CRYPT_SUCCESS); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + return ret; +} + +int EAL_PkeyGetPub_Api_TC001(int algId, Hex *pubKeyX, Hex *pubKeyY) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPub pub1, pub2; + KeyData pubKeyVector1 = {{0}, KEY_MAX_LEN}; + KeyData pubKeyVector2 = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + ASSERT_TRUE_AND_LOG("SetParaById", CRYPT_EAL_PkeySetParaById(ctx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Get the public key when there is no public key. */ + Ecc_SetPubKey(&pub2, algId, pubKeyVector2.data, GetPubKeyLen(CRYPT_ECC_NISTP224)); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub2), CRYPT_ECC_PKEY_ERR_EMPTY_KEY); + + /* Set the public key. */ + ASSERT_TRUE_AND_LOG("EccPointToBuffer", + EccPointToBuffer(pubKeyX, pubKeyY, CRYPT_POINT_UNCOMPRESSED, &pubKeyVector1) == CRYPT_SUCCESS); + Ecc_SetPubKey(&pub1, algId, pubKeyVector1.data, pubKeyVector1.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub1), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyGetPub. */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(NULL, &pub2), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, NULL), CRYPT_NULL_INPUT); + pub2.id = CRYPT_PKEY_DH; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub2), CRYPT_EAL_ERR_ALGID); + pub2.id = algId; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub2), CRYPT_SUCCESS); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + return ret; +} + +int EAL_PkeySetPrv_Api_TC001(int algId, Hex *prvKey, Hex *errorPrvKey) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPrv prv = {0}; + + TestMemInit(); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + + /* Set the key without curve */ + Ecc_SetPrvKey(&prv, algId, prvKey->x, prvKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ctx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeySetPrv. */ + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(NULL, &prv), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, NULL), CRYPT_NULL_INPUT); + prv.id = CRYPT_PKEY_DH; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_EAL_ERR_ALGID); + prv.id = algId; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_SUCCESS); + prv.key.eccPrv.data = errorPrvKey->x; + prv.key.eccPrv.len = errorPrvKey->len; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + + return ret; +} + +int EAL_PkeySetPrv_Api_TC002(int algId, Hex *prvKey, Hex *pubKeyX, Hex *pubKeyY) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub1, pub2; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + KeyData pubKeyVector2 = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ctx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Set the public key. */ + ASSERT_TRUE_AND_LOG("EccPointToBuffer", + EccPointToBuffer(pubKeyX, pubKeyY, CRYPT_POINT_UNCOMPRESSED, &pubKeyVector) == CRYPT_SUCCESS); + Ecc_SetPubKey(&pub1, algId, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub1), CRYPT_SUCCESS); + + /* Set the private key. */ + Ecc_SetPrvKey(&prv, algId, prvKey->x, prvKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_SUCCESS); + + /* Get the public key. */ + Ecc_SetPubKey(&pub2, algId, pubKeyVector2.data, pubKeyVector2.len); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(ctx, &pub2), CRYPT_SUCCESS); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + return ret; +} + +int EAL_PkeySetPub_Api_TC001(int algId, Hex *pubKeyVector) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPub pub; + + TestMemInit(); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + + Ecc_SetPubKey(&pub, algId, pubKeyVector->x, pubKeyVector->len); + + /* Set the pubilc key without curve. */ + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub), CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ctx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeySetPub. */ + ASSERT_EQ(CRYPT_EAL_PkeySetPub(NULL, &pub), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, NULL), CRYPT_NULL_INPUT); + pub.id = CRYPT_PKEY_DH; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub), CRYPT_EAL_ERR_ALGID); + pub.id = algId; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub), CRYPT_SUCCESS); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + + return ret; +} + +int EAL_PkeySetPub_Api_TC002(int algId, Hex *prvKey, Hex *pubKey) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPrv prv1, prv2; + (void)memset_s(&prv1.key.rsaPrv, sizeof(prv1.key.rsaPrv), 0, sizeof(prv1.key.rsaPrv)); + (void)memset_s(&prv2.key.rsaPrv, sizeof(prv2.key.rsaPrv), 0, sizeof(prv2.key.rsaPrv)); + CRYPT_EAL_PkeyPub ecdsaPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + + /* Create a key structure. */ + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ctx, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Set the private key. */ + Ecc_SetPrvKey(&prv1, algId, prvKey->x, prvKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv1), CRYPT_SUCCESS); + + /* Set the public key. */ + Ecc_SetPubKey(&ecdsaPubkey, algId, pubKey->x, pubKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &ecdsaPubkey), CRYPT_SUCCESS); + + /* Get the private key. */ + Ecc_SetPrvKey(&prv2, algId, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(ctx, &prv2), CRYPT_SUCCESS); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + return ret; +} + +int EAL_PkeySetPub_Api_TC003(int algId, int eccId, Hex *pubKey, Hex *errorPubKey) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + + TestMemInit(); + /* Create a key structure. */ + pkey = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE_AND_LOG("NewCtx", pkey != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(pkey, eccId) == CRYPT_SUCCESS); + + /* Constructing a public key that is too long. */ + pub.id = algId; + pub.key.eccPub.data = (uint8_t *)malloc(GetPubKeyLen(eccId) + 1); // Allocate for 1 more byte. + ASSERT_TRUE(pub.key.eccPub.data != NULL); + pub.key.eccPub.len = GetPubKeyLen(eccId) + 1; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_ECC_ERR_POINT_CODE); + free(pub.key.eccPub.data); + + /* Constructing a public key that is too short. */ + pub.id = algId; + pub.key.eccPub.data = (uint8_t *)malloc(GetPubKeyLen(eccId) - 1); // Allocate 1 byte less. + ASSERT_TRUE(pub.key.eccPub.data != NULL); + pub.key.eccPub.len = GetPubKeyLen(eccId) - 1; + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_ECC_ERR_POINT_CODE); + free(pub.key.eccPub.data); + pub.key.eccPub.data = NULL; + + /* Abnormal public key point: The length is abnormal. */ + if (pubKey->x != NULL) { + Ecc_SetPubKey(&pub, algId, pubKey->x, pubKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_ECC_ERR_POINT_CODE); + } + + if (errorPubKey->x != NULL) { + Ecc_SetPubKey(&pub, algId, errorPubKey->x, errorPubKey->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_ECC_POINT_NOT_ON_CURVE); + } + + CRYPT_EAL_PkeyFreeCtx(pkey); + return SUCCESS; +exit: + if (pub.key.eccPub.data != NULL) { + free(pub.key.eccPub.data); + } + CRYPT_EAL_PkeyFreeCtx(pkey); + + return ERROR; +} + +int EAL_PkeyGetParaId_Api_TC001(int algId, int paraId) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + TestMemInit(); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetParaId(pkey) == CRYPT_PKEY_PARAID_MAX); + + pkey = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetParaId(pkey) == CRYPT_PKEY_PARAID_MAX); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(pkey, (CRYPT_PKEY_ParaId)paraId) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetParaId(pkey) == (CRYPT_PKEY_ParaId)paraId); + + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + return ret; +} + +int EAL_PkeyCmp_Api_TC001(int algId, Hex *pubKeyX, Hex *pubKeyY) +{ + int ret = ERROR; + CRYPT_EAL_PkeyPub pub = {0}; + KeyData pubkey = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(algId); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL); + + ASSERT_EQ(EccPointToBuffer(pubKeyX, pubKeyY, CRYPT_POINT_COMPRESSED, &pubkey), CRYPT_SUCCESS); + Ecc_SetPubKey(&pub, algId, pubkey.data, pubkey.len); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ctx1, CRYPT_ECC_NISTP224), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL); + + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ctx2, CRYPT_ECC_NISTP256), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_ECC_ERR_POINT_CODE); + + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ctx2, CRYPT_ECC_NISTP224), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_SUCCESS); + ret = SUCCESS; +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + return ret; +} + +int EAL_PkeyGetPara_Func_TC001(int algId, Hex *p, Hex *a, Hex *b, Hex *x, Hex *y, Hex *n, Hex *h) +{ + int ret = ERROR; + CRYPT_EAL_PkeyCtx *ctx = NULL; + uint8_t pData[ECC_MAX_BIT_LEN] = {0}; + uint8_t aData[ECC_MAX_BIT_LEN] = {0}; + uint8_t bData[ECC_MAX_BIT_LEN] = {0}; + uint8_t nData[ECC_MAX_BIT_LEN] = {0}; + uint8_t xData[ECC_MAX_BIT_LEN] = {0}; + uint8_t yData[ECC_MAX_BIT_LEN] = {0}; + uint8_t hData[ECC_MAX_BIT_LEN] = {0}; + CRYPT_EAL_PkeyPara eccPara = { + .id = algId, + .para.eccPara.a = a->x, + .para.eccPara.aLen = a->len, + .para.eccPara.b = b->x, + .para.eccPara.bLen = b->len, + .para.eccPara.n = n->x, + .para.eccPara.nLen = n->len, + .para.eccPara.p = p->x, + .para.eccPara.pLen = p->len, + .para.eccPara.x = x->x, + .para.eccPara.xLen = x->len, + .para.eccPara.y = y->x, + .para.eccPara.yLen = y->len, + .para.eccPara.h = h->x, + .para.eccPara.hLen = h->len, + }; + CRYPT_EAL_PkeyPara para = {.id = algId, + .para.eccPara.a = aData, + .para.eccPara.aLen = ECC_MAX_BIT_LEN, + .para.eccPara.b = bData, + .para.eccPara.bLen = ECC_MAX_BIT_LEN, + .para.eccPara.n = nData, + .para.eccPara.nLen = ECC_MAX_BIT_LEN, + .para.eccPara.p = pData, + .para.eccPara.pLen = ECC_MAX_BIT_LEN, + .para.eccPara.x = xData, + .para.eccPara.xLen = ECC_MAX_BIT_LEN, + .para.eccPara.y = yData, + .para.eccPara.yLen = ECC_MAX_BIT_LEN, + .para.eccPara.h = hData, + .para.eccPara.hLen = ECC_MAX_BIT_LEN}; + + TestMemInit(); + ctx = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + + /* Set and get elliptic curve */ + ASSERT_EQ(CRYPT_EAL_PkeySetPara(ctx, &eccPara), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPara(ctx, ¶), CRYPT_SUCCESS); + + ASSERT_TRUE(para.para.eccPara.aLen == a->len); + ASSERT_TRUE(memcmp(aData, a->x, a->len) == 0); + + ASSERT_TRUE(para.para.eccPara.bLen == b->len); + ASSERT_TRUE(memcmp(bData, b->x, b->len) == 0); + + ASSERT_TRUE(para.para.eccPara.nLen == n->len); + ASSERT_TRUE(memcmp(nData, n->x, n->len) == 0); + + ASSERT_TRUE(para.para.eccPara.pLen == p->len); + ASSERT_TRUE(memcmp(pData, p->x, p->len) == 0); + + ASSERT_TRUE(para.para.eccPara.xLen == x->len); + ASSERT_TRUE(memcmp(xData, x->x, x->len) == 0); + + ASSERT_TRUE(para.para.eccPara.yLen == y->len); + ASSERT_TRUE(memcmp(yData, y->x, y->len) == 0); + + ASSERT_TRUE(para.para.eccPara.hLen == h->len); + ASSERT_TRUE(memcmp(hData, h->x, h->len) == 0); + ret = SUCCESS; +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + return ret; +} diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c new file mode 100644 index 00000000..ceb74ef1 --- /dev/null +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c @@ -0,0 +1,686 @@ +/* + * 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_BASE test_suite_sdv_eal_ecc */ + +/* BEGIN_HEADER */ +/* END_HEADER */ +#define ECDH_MAX_BIT_LEN 521 + +/** + * @test SDV_CRYPTO_ECDH_NEW_CTX_API_TC001 + * @title ECDH CRYPT_EAL_PkeyNewCtx test. + * @precon Registering memory-related functions. + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method to create a pkey structure, algId is CRYPT_PKEY_ECDH, expected result 1 + * 2. Releases the pkey structure, expected result 2 + * @expect + * 1. Success, and the structure is not NULL. + * 2. No memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_NEW_CTX_API_TC001(void) +{ + ASSERT_TRUE(EAL_PkeyNewCtx_Api_TC001(CRYPT_PKEY_ECDH) == SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_SET_PARA_BY_ID_API_TC001 + * @title ECDH CRYPT_EAL_PkeySetParaById: Test the validity of input parameters. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetParaById method: + * (1) context = NULL, expected result 2. + * (2) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP224, expected result 3. + * (3) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP256, expected result 3. + * (4) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP384, expected result 3. + * (5) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP521, expected result 3. + * (6) CRYPT_PKEY_ParaId = CRYPT_ECC_BRAINPOOLP256R1, expected result 3. + * (7) CRYPT_PKEY_ParaId = CRYPT_ECC_BRAINPOOLP384R1, expected result 3. + * (8) CRYPT_PKEY_ParaId = CRYPT_ECC_BRAINPOOLP512R1, expected result 3. + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_SET_PARA_BY_ID_API_TC001(void) +{ + ASSERT_TRUE(EAL_PkeySetParaById_Api_TC001(CRYPT_PKEY_ECDH) == SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_EXCH_API_TC001 + * @title ECDH CRYPT_EAL_PkeyComputeShareKey: Test the validity of parameters. + * @precon Registering memory-related functions. + * Test Vectors for ECDH : public key, private key, share secret + * @brief + * 1. Create two contexts(ecdhPkey, ecdhPkey2, peerEcdhPkey) of the ECDH algorithm, expected result 1 + * 2. ecdhPkey: Set elliptic curve type and private key, expected result 2 + * 3. peerEcdhPkey: Set elliptic curve type and public key, expected result 3 + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method before init the drbg, expected result 4: + * 5. Call the CRYPT_EAL_PkeyComputeShareKey method: + * (1) pkey = NULL, expected result 5 + * (2) pubPkey = NULL, expected result 6 + * (3) share = NULL, shareLen != 0, expected result 7 + * (4) share != NULL, shareLen = NULL, expected result 8 + * (5) share != NULL, shareLen = 1, expected result 9 + * (6) all parameters are valid, but the local ctx does not have a private key, expected result 10 + * (7) pkey.id != pubPkey.id, expected result 11 + * (8) all parameters are valid, expected result 12 + * @expect + * 1. Success, and contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. CRYPT_NO_REGIST_RAND + * 5-8. CRYPT_NULL_INPUT + * 9. CRYPT_ECC_BUFF_LEN_NOT_ENOUGH + * 10. CRYPT_ECDH_ERR_EMPTY_KEY + * 11. CRYPT_EAL_ERR_ALGID + * 12. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_EXCH_API_TC001(Hex *prvKeyVector, Hex *peerPubKeyVector, Hex *shareKeyVector) +{ + CRYPT_EAL_PkeyCtx *ecdhPkey = NULL; + CRYPT_EAL_PkeyCtx *ecdhPkey2 = NULL; + CRYPT_EAL_PkeyCtx *peerEcdhPkey = NULL; + CRYPT_EAL_PkeyPrv ecdhPrvkey = {0}; + CRYPT_EAL_PkeyPub peerEcdhPubkey; + uint8_t *shareKey = NULL; + uint32_t shareKeyLen; + + TestMemInit(); + + ecdhPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + ecdhPkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + peerEcdhPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + ASSERT_TRUE(ecdhPkey != NULL && ecdhPkey2 != NULL && peerEcdhPkey != NULL); + + /* Local: Set elliptic curve type and private key. */ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdhPkey, CRYPT_ECC_NISTP256), CRYPT_SUCCESS); + Ecc_SetPrvKey(&ecdhPrvkey, CRYPT_PKEY_ECDH, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdhPkey, &ecdhPrvkey), CRYPT_SUCCESS); + + /* Peer: Set elliptic curve type and public key. */ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(peerEcdhPkey, CRYPT_ECC_NISTP256), CRYPT_SUCCESS); + Ecc_SetPubKey(&peerEcdhPubkey, CRYPT_PKEY_ECDH, peerPubKeyVector->x, peerPubKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(peerEcdhPkey, &peerEcdhPubkey), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyComputeShareKey. */ + shareKey = (uint8_t *)malloc(shareKeyVector->len); + ASSERT_TRUE(shareKey != NULL); + shareKeyLen = shareKeyVector->len; + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPkey, shareKey, &shareKeyLen), CRYPT_NO_REGIST_RAND); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(NULL, peerEcdhPkey, shareKey, &shareKeyLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, NULL, shareKey, &shareKeyLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPkey, NULL, &shareKeyLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPkey, shareKey, NULL), CRYPT_NULL_INPUT); + + shareKeyLen = 1; // 1 is invalid + ASSERT_EQ( + CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPkey, shareKey, &shareKeyLen), CRYPT_ECC_BUFF_LEN_NOT_ENOUGH); + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey2, peerEcdhPkey, shareKey, &shareKeyLen), CRYPT_ECDH_ERR_EMPTY_KEY); + + ecdhPkey->id = CRYPT_PKEY_DH; + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPkey, shareKey, &shareKeyLen), CRYPT_EAL_ERR_ALGID); + ecdhPkey->id = CRYPT_PKEY_ECDH; + shareKeyLen = shareKeyVector->len; + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPkey, shareKey, &shareKeyLen), CRYPT_SUCCESS); +exit: + free(shareKey); + CRYPT_EAL_PkeyFreeCtx(ecdhPkey); + CRYPT_EAL_PkeyFreeCtx(ecdhPkey2); + CRYPT_EAL_PkeyFreeCtx(peerEcdhPkey); + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_CTRL_API_TC001 + * @title ECDH CRYPT_EAL_PkeyCtrl: Test the validity of opt. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method: + * (1) opt = CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, expected result 2 + * (2) opt = CRYPT_CTRL_SET_ED25519_HASH_METHOD, expected result 3 + * (3) opt = CRYPT_CTRL_SET_ECC_POINT_FORMAT, expected result 4 + * (4) opt = CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE, expected result 5 + * (5) opt = CRYPT_CTRL_SET_SM2_USER_ID, expected result 6 + * (6) opt = CRYPT_CTRL_SET_RSA_PADDING, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + * 3. CRYPT_EAL_ALG_NOT_SUPPORT + * 4. CRYPT_SUCCESS + * 5. CRYPT_SUCCESS + * 6. CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + * 7. CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_CTRL_API_TC001(int type, int expect) +{ + ASSERT_TRUE(EAL_PkeyCtrl_Api_TC001(CRYPT_PKEY_ECDH, type, expect) == SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_CTRL_API_TC002 + * @title ECDH CRYPT_EAL_PkeyCtrl: Test the validity of pkey and value. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method: + * (1) pkey = null, expected result 2 + * (2) val = null, len = 0, expected result 3 + * (3) val = null, len != 0, expected result 4 + * (4) val != null, len = 0, expected result 5 + * (5) PointFormat = CRYPT_POINT_MAX, expected result 6 + * (6) PointFormat = CRYPT_POINT_COMPRESSED, expected result 7 + * (7) PointFormat = CRYPT_POINT_UNCOMPRESSED, expected result 8 + * (8) PointFormat = CRYPT_POINT_HYBRID, expected result 9 + * @expect + * 1. Success, and the context is not NULL. + * 2-4. CRYPT_NULL_INPUT + * 5. CRYPT_ECC_PKEY_ERR_CTRL_LEN + * 6. CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT + * 7-9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_CTRL_API_TC002(void) +{ + ASSERT_TRUE(EAL_PkeyCtrl_Api_TC002(CRYPT_PKEY_ECDH) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_CTRL_API_TC003 + * @title ECDH CRYPT_EAL_PkeyCtrl: Test the effect of the point format on the key. + * @precon Registering memory-related functions. + * public key point + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224/256/384/512, bp256r1/384r1/512/r1), expected result 2 + * 3. Convert the format of the public key vector to COMPRESSED, expected result 3 + * 4. Set the public key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyCtrl method to set point format to COMPRESSED, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCtrl method to set point format to HYBRID, expected result 6 + * 7. Get the public key, expected result 7 + * 8. Convert the format of the public key vector to HYBRID, expected result 8 + * 9. Compare the output of the preceding two steps, expected result 9 + * @expect + * 1. Success, and the context is not NULL. + * 2-8. CRYPT_SUCCESS + * 9. The two are same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_CTRL_API_TC003(int eccId, Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeyCtrl_Api_TC003(CRYPT_PKEY_ECDH, eccId, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_GET_PRV_API_TC001 + * @title ECDH CRYPT_EAL_PkeyGetPrv: Test the validity of parameters. + * @precon Registering memory-related functions. + * private key + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Get the private key when there is no private key, expected result 3 + * 4. Set the private key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetPrv method: + * (1) pkey = null, expected result 5 + * (2) prv = null, expected result 6 + * (3) pkey.id != prv.id, expected result 7 + * (4) Correct parameters., expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECC_PKEY_ERR_EMPTY_KEY + * 4. CRYPT_SUCCESS + * 5-6. CRYPT_NULL_INPUT + * 7. CRYPT_EAL_ERR_ALGID + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_GET_PRV_API_TC001(Hex *prvKey) +{ + ASSERT_TRUE(EAL_PkeyGetPrv_Api_TC001(CRYPT_PKEY_ECDH, prvKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_GET_PUB_API_TC001 + * @title ECDH CRYPT_EAL_PkeyGetPub: Test the validity of parameters. + * @precon Registering memory-related functions. + * public key point + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Get the public key when there is no public key, expected result 3 + * 4. Set the public key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetPub method: + * (1) pkey = null, expected result 5 + * (2) pub = null, expected result 6 + * (3) pkey.id != pub.id, expected result 7 + * (4) Correct parameters, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECC_PKEY_ERR_EMPTY_KEY + * 4. CRYPT_SUCCESS + * 5-6. CRYPT_NULL_INPUT + * 7. CRYPT_EAL_ERR_ALGID + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_GET_PUB_API_TC001(Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeyGetPub_Api_TC001(CRYPT_PKEY_ECDH, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_SET_PRV_API_TC001 + * @title ECDH CRYPT_EAL_PkeySetPrv: Test the validity of parameters. + * @precon Registering memory-related functions. + * Prepare valid private key and invalid private key. + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the the valid private key before setting the curve, expected result 2 + * 3. Set the para by eccId(p-224), expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPrv method: + * (1) pkey = null, expected result 4 + * (2) prv = null, expected result 5 + * (3) pkey.id != prv.id, expected result 6 + * (4) Set the valid private key, expected result 7 + * (5) Set the invalid private key, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + * 4-5. CRYPT_NULL_INPUT + * 6. CRYPT_EAL_ERR_ALGID + * 7. CRYPT_SUCCESS + * 8. CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_SET_PRV_API_TC001(Hex *prvKey, Hex *errorPrvKey) +{ + ASSERT_TRUE(EAL_PkeySetPrv_Api_TC001(CRYPT_PKEY_ECDH, prvKey, errorPrvKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_SET_PRV_API_TC002 + * @title Check whether the public key is cleared when the private key is set. + * @precon Registering memory-related functions. + * private key, public key point + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Set the the public key, expected result 3 + * 4. Set the the private key, expected result 4 + * 5. Get the the public key, expected result 5 + * @expect + * 1. Success, and the context is not NULL. + * 2-5. CRYPT_SUCCESSY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_SET_PRV_API_TC002(Hex *prvKey, Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeySetPrv_Api_TC002(CRYPT_PKEY_ECDH, prvKey, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_SET_PUB_API_TC001 + * @title ECDH CRYPT_EAL_PkeySetPub: Test the validity of parameters. + * @precon Prepare valid public key. + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the the public key before setting the curve, expected result 2 + * 3. Set the para by eccId(p-224), expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPub method: + * (1) pkey = null, expected result 4 + * (2) pub = null, expected result 5 + * (3) pkey.id != pub.id, expected result 6 + * (4) Set the valid public key, expected result 7 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + * 4-5. CRYPT_NULL_INPUT + * 6. CRYPT_EAL_ERR_ALGID + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_SET_PUB_API_TC001(Hex *pubKeyVector) +{ + ASSERT_TRUE(EAL_PkeySetPub_Api_TC001(CRYPT_PKEY_ECDH, pubKeyVector) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_SET_PUB_API_TC002 + * @title Check whether the private key is cleared when the public key is set. + * @precon Registering memory-related functions. + * public key, private key + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Set the the private key, expected result 3 + * 4. Set the the public key, expected result 4 + * 5. Get the the private key, expected result 5 + * @expect + * 1. Success, and the context is not NULL. + * 2-5. CRYPT_SUCCESSY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_SET_PUB_API_TC002(Hex *prvKey, Hex *pubKey) +{ + ASSERT_TRUE(EAL_PkeySetPub_Api_TC002(CRYPT_PKEY_ECDH, prvKey, pubKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_SET_PUB_API_TC003 + * @title Test the function of setting public keys of different lengths. + * @precon Public keys of different lengths. + * @brief + * 1. Create the context of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224/256/384/512, bp256r1/384r1/512/r1), expected result 2 + * 3. Set public keys of different lengths, expected result 3 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESSY + * 3. CRYPT_ECC_ERR_POINT_CODE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_SET_PUB_API_TC003(int eccId, Hex *pubKey, Hex *errorPubKey) +{ + ASSERT_TRUE(EAL_PkeySetPub_Api_TC003(CRYPT_PKEY_ECDSA, eccId, pubKey, errorPubKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001 + * @title ECDH CRYPT_EAL_PkeyGetParaId test. + * @precon Registering memory-related functions. + * @brief + * 1. Get para id before creating context, expected result 1 + * 1. Create the context of the ecdh algorithm, expected result 2 + * 2. Set para id(p-224/256/384/512), expected result 3 + * 3. Get para id, expected result 4 + * @expect + * 1. CRYPT_PKEY_PARAID_MAX + * 2. Success, and the context is not NULL. + * 3. CRYPT_SUCCESS + * 4. The obtained id is the same as the set id. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001(int id) +{ + ASSERT_TRUE(EAL_PkeyGetParaId_Api_TC001(CRYPT_PKEY_ECDH, id) == 0); + +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_DUP_CTX_API_TC001 + * @title ECDH CRYPT_EAL_PkeyDupCtx test. + * @precon Registering memory-related functions. + * @brief + * 1. Create the context(pKeyCtx) of the ecdh algorithm, expected result 1 + * 2. Set the para by eccId(p-224/256/384/512, bp256r1/384r1/512/r1), expected result 2 + * 3. Call the CRYPT_EAL_PkeyDupCtx to dup context where the parameter is null, expected result 3 + * 4. Call the CRYPT_EAL_PkeyDupCtx to dup context(newCtx), expected result 4 + * 5. Get the reference count, expected result 5 + * 6. Compare the pkey ids obtained from pKeyCtx and newCtx, , expected result 6 + * 7. Compare the curve ids obtained from pKeyCtx and newCtx, expected result 7 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESSY + * 3. Return null. + * 4. Return non-null. + * 5. The reference count is 1. + * 6-7. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_DUP_CTX_API_TC001(int paraId) +{ + CRYPT_EAL_PkeyCtx *pKeyCtx = NULL; + CRYPT_EAL_PkeyCtx *newCtx = NULL; + + pKeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + ASSERT_TRUE(pKeyCtx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(pKeyCtx, (CRYPT_PKEY_ParaId)paraId) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyDupCtx(NULL) == NULL); + + newCtx = CRYPT_EAL_PkeyDupCtx(pKeyCtx); + ASSERT_TRUE(newCtx != NULL); + + ASSERT_EQ(newCtx->references.count, 1); + ASSERT_TRUE(CRYPT_EAL_PkeyGetId(pKeyCtx) == CRYPT_EAL_PkeyGetId(newCtx)); + ASSERT_TRUE(CRYPT_EAL_PkeyGetParaId(pKeyCtx) == CRYPT_EAL_PkeyGetParaId(newCtx)); +exit: + CRYPT_EAL_PkeyFreeCtx(pKeyCtx); + CRYPT_EAL_PkeyFreeCtx(newCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_CMP_FUNC_TC001 + * @title ECDH: CRYPT_EAL_PkeyCmp test. + * @precon Registering memory-related functions. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the ecdh algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set para id CRYPT_ECC_NISTP224 and public key for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set para id CRYPT_ECC_NISTP256 for ctx2, expected result 5 + * 6. Set public key for ctx2, expected result 6 + * 7. Set para id CRYPT_ECC_NISTP224 and public key for ctx2, expected result 7 + * 8. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 8 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 3. CRYPT_SUCCESS + * 4. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 5. CRYPT_SUCCESS + * 6. CRYPT_ECC_ERR_POINT_CODE + * 7. CRYPT_SUCCESS + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_CMP_FUNC_TC001(Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeyCmp_Api_TC001(CRYPT_PKEY_ECDH, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 + * @title ECDH key exchange test: set the key and exchange the key. + * @precon Registering memory-related functions. + * @brief + * 1. Create two contexts(ecdhPkey, peerEcdhPubPkey) of the ECDH algorithm, expected result 1 + * 2. Init the drbg, expected result 2 + * 3. ecdhPkey: Set elliptic curve type(p-224/256/384/512, bp256r1/384r1/512/r1) and private key, expected result 3 + * 4. peerEcdhPubPkey: Set elliptic curve type(p-224/256/384/512, bp256r1/384r1/512/r1) and public key(compressed/ + * uncompressed/hybrid), expected result 4 + * 5. Compute the shared key, expected result 5 + * 6. Compare the output shared secret and shared secret vector, expected result 6 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-5. CRYPT_SUCCESS + * 6. The two shared secrets are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_EXCH_FUNC_TC001( + int eccId, Hex *prvKeyVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat, Hex *shareKeyVector) +{ + int ret; + CRYPT_EAL_PkeyCtx *ecdhPkey = NULL; + CRYPT_EAL_PkeyCtx *peerEcdhPubPkey = NULL; + CRYPT_EAL_PkeyPrv ecdhPrvkey = {0}; + CRYPT_EAL_PkeyPub peerEcdhPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + uint8_t *shareKey = NULL; + uint32_t shareKeyLen; + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + ecdhPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + peerEcdhPubPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + ASSERT_TRUE(ecdhPkey != NULL && peerEcdhPubPkey != NULL); + + /* Local: Set elliptic curve type and private key. */ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdhPkey, eccId), CRYPT_SUCCESS); + Ecc_SetPrvKey(&ecdhPrvkey, CRYPT_PKEY_ECDH, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdhPkey, &ecdhPrvkey), CRYPT_SUCCESS); + + /* Peer: Set elliptic curve type and public key. */ + /* Create a key structure to store the public key. */ + ret = EccPointToBuffer(pubKeyX, pubKeyY, pointFormat, &pubKeyVector); + ASSERT_TRUE_AND_LOG("EccPointToVector", ret == CRYPT_SUCCESS); + Ecc_SetPubKey(&peerEcdhPubkey, CRYPT_PKEY_ECDH, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(peerEcdhPubPkey, eccId), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(peerEcdhPubPkey, &peerEcdhPubkey), CRYPT_SUCCESS); + + /* Compute share secret. */ + shareKeyLen = CRYPT_EAL_PkeyGetKeyLen(ecdhPkey); + ASSERT_TRUE(shareKeyLen > shareKeyVector->len); + shareKey = (uint8_t *)malloc(shareKeyVector->len); + ASSERT_TRUE(shareKey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ecdhPkey, peerEcdhPubPkey, shareKey, &shareKeyLen), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("Compare ShareKey Len", shareKeyLen == shareKeyVector->len); + ASSERT_COMPARE("Compare ShareKey", shareKey, shareKeyLen, shareKeyVector->x, shareKeyVector->len); +exit: + CRYPT_EAL_PkeyFreeCtx(ecdhPkey); + CRYPT_EAL_PkeyFreeCtx(peerEcdhPubPkey); + CRYPT_EAL_RandDeinit(); + free(shareKey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_GET_PARA_FUNC_TC001 + * @title ECDH CRYPT_EAL_PkeyGetPara test. + * @precon Registering memory-related functions. + * @brief + * 1. Create context of the ECDH algorithm, expected result 1 + * 2. Set para, expected result 2 + * 3. Get para, expected result 3 + * 4. Check whether the set parameters and the obtained parameters are the same, expected result 4 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. The parameters are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_GET_PARA_FUNC_TC001(Hex *p, Hex *a, Hex *b, Hex *x, Hex *y, Hex *n, Hex *h) +{ + ASSERT_TRUE(EAL_PkeyGetPara_Func_TC001(CRYPT_PKEY_ECDH, p, a, b, x, y, n, h) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 + * @title ECDH CRYPT_EAL_PkeyGen test. + * @precon Registering memory-related functions. + * @brief + * 1. Create context of the ECDH algorithm, expected result 1 + * 2. Set elliptic curve type, expected result 2 + * 3. Mock BN_RandRange to STUB_RandRangeK, expected result 3 + * 4. Init the drbg, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGen method to generate a key pair, expected result 5 + * 6. Get public key and private key, expected result 6 + * 7. Compare the getted key and vector, expected result 7 + * @expect + * 1. Success, and two contexts are not NULL. + * 2. CRYPT_SUCCESS + * 3. SUccess. + * 4-6. CRYPT_SUCCESS + * 7. The getted key and vector are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001(int eccId, Hex *prvKeyVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat) +{ + Ecc_GenKey(CRYPT_PKEY_ECDH, eccId, prvKeyVector, pubKeyX, pubKeyY, pointFormat); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001 + * @title ECDH: get key bits. + * @brief + * 1. Create a context of the ECDH algorithm, expected result 1 + * 2. Get key bits, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. Equal to keyBits. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001(int paraid, int keyBits) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(pkey, paraid), CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(pkey) == (uint32_t)keyBits); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data new file mode 100644 index 00000000..6c184ffd --- /dev/null +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data @@ -0,0 +1,317 @@ +SDV_CRYPTO_ECDH_NEW_CTX_API_TC001 +SDV_CRYPTO_ECDH_NEW_CTX_API_TC001: + +SDV_CRYPTO_ECDH_SET_PARA_BY_ID_API_TC001 +SDV_CRYPTO_ECDH_SET_PARA_BY_ID_API_TC001: + +SDV_CRYPTO_ECDH_EXCH_API_TC001: Nist +SDV_CRYPTO_ECDH_EXCH_API_TC001:"7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534":"04700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac":"46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" + +SDV_CRYPTO_ECDH_CTRL_API_TC001: CRYPT_CTRL_SET_RSA_RSAES_PKCSV15 +SDV_CRYPTO_ECDH_CTRL_API_TC001:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDH_CTRL_API_TC001: CRYPT_CTRL_SET_ED25519_HASH_METHOD +SDV_CRYPTO_ECDH_CTRL_API_TC001:CRYPT_CTRL_SET_ED25519_HASH_METHOD:CRYPT_EAL_ALG_NOT_SUPPORT + +SDV_CRYPTO_ECDH_CTRL_API_TC001: CRYPT_CTRL_SET_ECC_POINT_FORMAT +SDV_CRYPTO_ECDH_CTRL_API_TC001:CRYPT_CTRL_SET_ECC_POINT_FORMAT:CRYPT_SUCCESS + +SDV_CRYPTO_ECDH_CTRL_API_TC001: CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE +SDV_CRYPTO_ECDH_CTRL_API_TC001:CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE:CRYPT_SUCCESS + +SDV_CRYPTO_ECDH_CTRL_API_TC001: CRYPT_CTRL_SET_SM2_USER_ID +SDV_CRYPTO_ECDH_CTRL_API_TC001:CRYPT_CTRL_SET_SM2_USER_ID:CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDH_CTRL_API_TC001: CRYPT_CTRL_SET_RSA_PADDING +SDV_CRYPTO_ECDH_CTRL_API_TC001:CRYPT_CTRL_SET_RSA_PADDING:CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDH_CTRL_API_TC002 +SDV_CRYPTO_ECDH_CTRL_API_TC002: + +SDV_CRYPTO_ECDH_CTRL_API_TC003 P-224: Nist +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_NISTP224:"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDH_CTRL_API_TC003 P-256: Nist +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_NISTP256:"29578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab":"08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800" + +SDV_CRYPTO_ECDH_CTRL_API_TC003 P-384: Nist +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_NISTP384:"de92ff09af2950854a70f2178d2ed50cc7042a7188301a1ea81d9629ad3c29795cb7f0d56630a401e4d6e5bed0068d1e":"6135adbd8624130735e64e65ecbd43770dcc12b28e737b5ed033666f34c918eb5589508e4a13b9243374a118a628dd0b" + +SDV_CRYPTO_ECDH_CTRL_API_TC003 P-521: Nist +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_NISTP521:"01a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e7":"0184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b" + +SDV_CRYPTO_ECDH_CTRL_API_TC003: RFC 6932, brainpool p256r1 +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_BRAINPOOLP256R1:"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B" + +SDV_CRYPTO_ECDH_CTRL_API_TC003: RFC 6932, brainpool p384r1 +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_BRAINPOOLP384R1:"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859" + +SDV_CRYPTO_ECDH_CTRL_API_TC003: RFC 6932, brainpool p512r1 +SDV_CRYPTO_ECDH_CTRL_API_TC003:CRYPT_ECC_BRAINPOOLP512R1:"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E" + +SDV_CRYPTO_ECDH_GET_PRV_API_TC001: Nist +SDV_CRYPTO_ECDH_GET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615" + +SDV_CRYPTO_ECDH_GET_PUB_API_TC001: Nist +SDV_CRYPTO_ECDH_GET_PUB_API_TC001:"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDH_SET_PRV_API_TC001: Nist +SDV_CRYPTO_ECDH_SET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3f" + +SDV_CRYPTO_ECDH_SET_PRV_API_TC001: Nist +SDV_CRYPTO_ECDH_SET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"00000000000000000000000000000000000000000000000000000000" + +SDV_CRYPTO_ECDH_SET_PRV_API_TC001: prvKey > n +SDV_CRYPTO_ECDH_SET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" + +SDV_CRYPTO_ECDH_SET_PRV_API_TC002: Nist +SDV_CRYPTO_ECDH_SET_PRV_API_TC002:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC001: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC001:"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC002: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC002:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP256R1:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP384R1:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP512R1:"":"" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"05605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc666a" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"06605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc666a" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"07ac635fe00e8b7a3c8ef5655bdfb7f83e8532e59c0cc0b6534d810ffa1d067aebeba66e79b28ecfe59ac6fdf5e1970dc3a84499c9d90cd8e2":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc666a" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"0529578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":"0429578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4801" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"066b738de3398b6ac57b9591f9d7985dd4f32137ad3460dcf8970c1390cb9eaf8d83bc61e26d2bbbd3cf2d2ab445a2bc4ab5dde41f4a13078fd1d3cc36ab596d57":"0429578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4801" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"0729578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":"0429578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4801" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"0500ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3e":"0400ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3f" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"06fb937e4a303617b71b6c1a25f2ac786087328a3e26bdef55e52d46ab5e69e5411bf9fc55f5df9994d2bf82e8f39a153ea97d9075e92fa5bfe67e6ec18e21cc4d11fde59a68aef72c0e46a28f31a9d60385f41f39da468f4e6c3d3fbac9046765":"0400ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3f" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"0700ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3e":"0400ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3f" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"0501a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b":"0401a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027c" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"0601a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b":"0401a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027c" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"0700156cd2c485012ea5d5aadad724fb87558637de37b34485c4cf7c8cbc3e4f106cb1efd3e64f0adf99ddb51e3ac991bdd90785172386cdaf2c582cc46d6c99b0fed101edeeda717554252b9f1e13553d4af028ec9e158dbe12332684fc1676dc731f39138a5d301376505a9ab04d562cc1659b0be9cb2b5e03bad8b412f2699c245b0ba2":"0400156cd2c485012ea5d5aadad724fb87558637de37b34485c4cf7c8cbc3e4f106cb1efd3e64f0adf99ddb51e3ac991bdd90785172386cdaf2c582cc46d6c99b0fed101edeeda717554252b9f1e13553d4af028ec9e158dbe12332684fc1676dc731f39138a5d301376505a9ab04d562cc1659b0be9cb2b5e03bad8b412f2699c245b0ba3" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: FRC 7072 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP256R1:"8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A":"0678028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92C" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: FRC 7072 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP384R1:"68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF06855BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59":"0645CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC85A" + +SDV_CRYPTO_ECDH_SET_PUB_API_TC003: FRC 7072 +SDV_CRYPTO_ECDH_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP512R1:"0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7":"070562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDAA7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642F" + +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP224 + +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP256 + +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP384 + +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDH_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP521 + +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001 +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001:CRYPT_ECC_NISTP224 + +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001 +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001:CRYPT_ECC_NISTP256 + +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001 +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001:CRYPT_ECC_NISTP384 + +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001 +SDV_CRYPTO_ECDH_DUP_CTX_API_TC001:CRYPT_ECC_NISTP521 + +SDV_CRYPTO_ECDH_CMP_FUNC_TC001 Nist, P-224 COMPRESS +SDV_CRYPTO_ECDH_CMP_FUNC_TC001:"af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280":"882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-224 COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP224:"8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd":"af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280":"882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7":CRYPT_POINT_COMPRESSED:"7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-224 UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP224:"8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd":"af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280":"882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7":CRYPT_POINT_UNCOMPRESSED:"7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-224 HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP224:"8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd":"af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280":"882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7":CRYPT_POINT_HYBRID:"7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-256 COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP256:"7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534":"700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287":"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac":CRYPT_POINT_COMPRESSED:"46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-256 UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP256:"7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534":"700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287":"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac":CRYPT_POINT_UNCOMPRESSED:"46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-256 HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP256:"7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534":"700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287":"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac":CRYPT_POINT_HYBRID:"46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-384 COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP384:"3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1":"a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066":"ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a":CRYPT_POINT_COMPRESSED:"5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-384 UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP384:"3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1":"a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066":"ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a":CRYPT_POINT_UNCOMPRESSED:"5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-384 HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP384:"3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1":"a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066":"ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a":CRYPT_POINT_HYBRID:"5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-521 COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP521:"017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47":"00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d":"01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676":CRYPT_POINT_COMPRESSED:"005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-521 UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP521:"017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47":"00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d":"01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676":CRYPT_POINT_UNCOMPRESSED:"005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 Nist, P-521 HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_NISTP521:"017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47":"00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d":"01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676":CRYPT_POINT_HYBRID:"005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p256r1, COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"8E07E219BA588916C5B06AA30A2F464C2F2ACFC1610A3BE2FB240B635341F0DB":"148EA1D7D1E7E54B9555B6C9AC90629C18B63BEE5D7AA6949EBBF47B24FDE40D":CRYPT_POINT_COMPRESSED:"05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2E23708" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p256r1, UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"8E07E219BA588916C5B06AA30A2F464C2F2ACFC1610A3BE2FB240B635341F0DB":"148EA1D7D1E7E54B9555B6C9AC90629C18B63BEE5D7AA6949EBBF47B24FDE40D":CRYPT_POINT_UNCOMPRESSED:"05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2E23708" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p256r1, HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"8E07E219BA588916C5B06AA30A2F464C2F2ACFC1610A3BE2FB240B635341F0DB":"148EA1D7D1E7E54B9555B6C9AC90629C18B63BEE5D7AA6949EBBF47B24FDE40D":CRYPT_POINT_HYBRID:"05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2E23708" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p384r1, COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"01BF92A92EE4BE8DED1A911125C209B03F99E3161CFCC986DC7711383FC30AF9CE28CA3386D59E2C8D72CE1E7B4666E8":"3289C4A3A4FEE035E39BDB885D509D224A142FF9FBCC5CFE5CCBB30268EE47487ED8044858D31D848F7A95C635A347AC":CRYPT_POINT_COMPRESSED:"04CC4FF3DCCCB07AF24E0ACC529955B36D7C807772B92FCBE48F3AFE9A2F370A1F98D3FA73FD0C0747C632E12F1423EC" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p384r1, UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"01BF92A92EE4BE8DED1A911125C209B03F99E3161CFCC986DC7711383FC30AF9CE28CA3386D59E2C8D72CE1E7B4666E8":"3289C4A3A4FEE035E39BDB885D509D224A142FF9FBCC5CFE5CCBB30268EE47487ED8044858D31D848F7A95C635A347AC":CRYPT_POINT_UNCOMPRESSED:"04CC4FF3DCCCB07AF24E0ACC529955B36D7C807772B92FCBE48F3AFE9A2F370A1F98D3FA73FD0C0747C632E12F1423EC" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p384r1, HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"01BF92A92EE4BE8DED1A911125C209B03F99E3161CFCC986DC7711383FC30AF9CE28CA3386D59E2C8D72CE1E7B4666E8":"3289C4A3A4FEE035E39BDB885D509D224A142FF9FBCC5CFE5CCBB30268EE47487ED8044858D31D848F7A95C635A347AC":CRYPT_POINT_HYBRID:"04CC4FF3DCCCB07AF24E0ACC529955B36D7C807772B92FCBE48F3AFE9A2F370A1F98D3FA73FD0C0747C632E12F1423EC" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 6932, brainpool p512r1, COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE159559E357581825391175FC195D28BAC0CF03A7841A383B95C262B983782874CCE6FE333":"5A7954E32663DFF11AE24712D87419F26B708AC2B92877D6BFEE2BFC43714D89BBDB6D24D807BBD3AEB7F0C325F862E8BADE4F74636B97EAACE739E11720D323":"96D14621A9283A1BED84DE8DD64836B2C0758B11441179DC0C54C0D49A47C03807D171DD544B72CAAEF7B7CE01C7753E2CAD1A861ECA55A71954EE1BA35E04BE":CRYPT_POINT_COMPRESSED:"1EE8321A4BBF93B9CF8921AB209850EC9B7066D1984EF08C2BB723236208AC8F1A483E79461A00E0D5F6921CE9D360502F85C812BEDEE23AC5B210E5811B191E" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 7027, brainpool p256r1, COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D":"8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B":"990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A":CRYPT_POINT_COMPRESSED:"89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 7027, brainpool p384r1, COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042":"4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4":"62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48":CRYPT_POINT_COMPRESSED:"0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 7027, brainpool p512r1, COMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422":"9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F":"2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA":CRYPT_POINT_COMPRESSED:"A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 7027, brainpool p512r1, UNCOMPRESS +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422":"9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F":"2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA":CRYPT_POINT_UNCOMPRESSED:"A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F" + +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001 RFC 7027, brainpool p512r1, HYBID +SDV_CRYPTO_ECDH_EXCH_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422":"9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F":"2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA":CRYPT_POINT_HYBRID:"A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F" + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-224 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP224:"e7c92383846a4e6887a10498d8eaca2bd0487d985bd7d3f92ce3ab30":"0a3682d2aaa4dd931bee042d32e95755507ab164b12f84843f4b7b96":"a6313a938eff7a293222e0e3c7b4c6132489b33255a61c3fc1ce2256":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-224 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP224:"e7c92383846a4e6887a10498d8eaca2bd0487d985bd7d3f92ce3ab30":"0a3682d2aaa4dd931bee042d32e95755507ab164b12f84843f4b7b96":"a6313a938eff7a293222e0e3c7b4c6132489b33255a61c3fc1ce2256":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-224 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP224:"e7c92383846a4e6887a10498d8eaca2bd0487d985bd7d3f92ce3ab30":"0a3682d2aaa4dd931bee042d32e95755507ab164b12f84843f4b7b96":"a6313a938eff7a293222e0e3c7b4c6132489b33255a61c3fc1ce2256":2 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-256 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP256:"c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357":"d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f":"9681b517b1cda17d0d83d335d9c4a8a9a9b0b1b3c7106d8f3c72bc5093dc275f":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-256 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP256:"c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357":"d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f":"9681b517b1cda17d0d83d335d9c4a8a9a9b0b1b3c7106d8f3c72bc5093dc275f":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-256 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP256:"c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357":"d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f":"9681b517b1cda17d0d83d335d9c4a8a9a9b0b1b3c7106d8f3c72bc5093dc275f":2 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-384 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP384:"5394f7973ea868c52bf3ff8d8ceeb4db90a683653b12485d5f627c3ce5abd8978fc9673d14a71d925747931662493c37":"fd3c84e5689bed270e601b3d80f90d67a9ae451cce890f53e583229ad0e2ee645611fa9936dfa45306ec18066774aa24":"b83ca4126cfc4c4d1d18a4b6c21c7f699d5123dd9c24f66f833846eeb58296196b42ec06425db5b70a4b81b7fcf705a0":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-384 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP384:"5394f7973ea868c52bf3ff8d8ceeb4db90a683653b12485d5f627c3ce5abd8978fc9673d14a71d925747931662493c37":"fd3c84e5689bed270e601b3d80f90d67a9ae451cce890f53e583229ad0e2ee645611fa9936dfa45306ec18066774aa24":"b83ca4126cfc4c4d1d18a4b6c21c7f699d5123dd9c24f66f833846eeb58296196b42ec06425db5b70a4b81b7fcf705a0":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-384 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP384:"5394f7973ea868c52bf3ff8d8ceeb4db90a683653b12485d5f627c3ce5abd8978fc9673d14a71d925747931662493c37":"fd3c84e5689bed270e601b3d80f90d67a9ae451cce890f53e583229ad0e2ee645611fa9936dfa45306ec18066774aa24":"b83ca4126cfc4c4d1d18a4b6c21c7f699d5123dd9c24f66f833846eeb58296196b42ec06425db5b70a4b81b7fcf705a0":2 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-512 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP521:"0184258ea667ab99d09d4363b3f51384fc0acd2f3b66258ef31203ed30363fcda7661b6a817daaf831415a1f21cb1cda3a74cc1865f2ef40f683c14174ea72803cff":"019ee818048f86ada6db866b7e49a9b535750c3673cb61bbfe5585c2df263860fe4d8aa8f7486aed5ea2a4d733e346eaefa87ac515c78b9a986ee861584926ce4860":"01b6809c89c0aa7fb057a32acbb9ab4d7b06ba39dba8833b9b54424add2956e95fe48b7fbf60c3df5172bf386f2505f1e1bb2893da3b96d4f5ae78f2544881a238f7":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-512 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP521:"0184258ea667ab99d09d4363b3f51384fc0acd2f3b66258ef31203ed30363fcda7661b6a817daaf831415a1f21cb1cda3a74cc1865f2ef40f683c14174ea72803cff":"019ee818048f86ada6db866b7e49a9b535750c3673cb61bbfe5585c2df263860fe4d8aa8f7486aed5ea2a4d733e346eaefa87ac515c78b9a986ee861584926ce4860":"01b6809c89c0aa7fb057a32acbb9ab4d7b06ba39dba8833b9b54424add2956e95fe48b7fbf60c3df5172bf386f2505f1e1bb2893da3b96d4f5ae78f2544881a238f7":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 Nist, P-512 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP521:"0184258ea667ab99d09d4363b3f51384fc0acd2f3b66258ef31203ed30363fcda7661b6a817daaf831415a1f21cb1cda3a74cc1865f2ef40f683c14174ea72803cff":"019ee818048f86ada6db866b7e49a9b535750c3673cb61bbfe5585c2df263860fe4d8aa8f7486aed5ea2a4d733e346eaefa87ac515c78b9a986ee861584926ce4860":"01b6809c89c0aa7fb057a32acbb9ab4d7b06ba39dba8833b9b54424add2956e95fe48b7fbf60c3df5172bf386f2505f1e1bb2893da3b96d4f5ae78f2544881a238f7":2 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p256r1 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p256r1 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p256r1 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B":2 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p384r1 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p384r1 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p384r1 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859":2 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p512r1 COMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE159559E357581825391175FC195D28BAC0CF03A7841A383B95C262B983782874CCE6FE333":"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E":0 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p512r1 UNCOMPRESS +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE159559E357581825391175FC195D28BAC0CF03A7841A383B95C262B983782874CCE6FE333":"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E":1 + +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p512r1 HYBID +SDV_CRYPTO_ECDH_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE159559E357581825391175FC195D28BAC0CF03A7841A383B95C262B983782874CCE6FE333":"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E":2 + +SDV_CRYPTO_ECDH_GET_PARA_FUNC_TC001 +SDV_CRYPTO_ECDH_GET_PARA_FUNC_TC001:"ffffffffffffffffffffffffffffffff000000000000000000000001":"fffffffffffffffffffffffffffffffefffffffffffffffffffffffe":"b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4":"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21":"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34":"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d":"01" + +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001:CRYPT_ECC_NISTP256:520 + +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001:CRYPT_ECC_NISTP384:776 + +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001:CRYPT_ECC_NISTP521:1064 + +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_ECDH_GET_KEY_BITS_FUNC_TC001:CRYPT_ECC_NISTP224:456 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdsa.c b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdsa.c new file mode 100644 index 00000000..5118359e --- /dev/null +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdsa.c @@ -0,0 +1,1414 @@ +/* + * 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_BASE test_suite_sdv_eal_ecc */ + +/* BEGIN_HEADER */ +int SignEncode(Hex *R, Hex *S, uint8_t *vectorSign, uint32_t *vectorSignLen) +{ + int ret = CRYPT_INVALID_ARG; + BN_BigNum *bn_r = NULL; + BN_BigNum *bn_s = NULL; + DSA_Sign dsaSign; + bn_r = BN_Create(R->len * BITS_OF_BYTE); + bn_s = BN_Create(S->len * BITS_OF_BYTE); + ASSERT_TRUE(bn_s != NULL && bn_r != NULL); + ASSERT_TRUE(BN_Bin2Bn(bn_r, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(BN_Bin2Bn(bn_s, S->x, S->len) == CRYPT_SUCCESS); + dsaSign.r = bn_r; + dsaSign.s = bn_s; + ret = ASN1_SignDataEncode(&dsaSign, vectorSign, vectorSignLen); +exit: + BN_Destroy(bn_r); + BN_Destroy(bn_s); + return ret; +} +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_ECDSA_NEW_CTX_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyNewCtx test. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method to create a pkey structure, algId is CRYPT_PKEY_ECDSA, expected result 1 + * 2. Releases the pkey structure, expected result 2 + * @expect + * 1. Success, and the structure is not NULL. + * 1. No memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_NEW_CTX_API_TC001(void) +{ + ASSERT_TRUE(EAL_PkeyNewCtx_Api_TC001(CRYPT_PKEY_ECDSA) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC001 + * @title ECDSA CRYPT_EAL_PkeySetParaById: Test the validity of input parameters. + * @precon + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetParaById method: + * (1) context = NULL, expected result 2. + * (2) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP224, expected result 3. + * (3) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP256, expected result 3. + * (4) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP384, expected result 3. + * (5) CRYPT_PKEY_ParaId = CRYPT_ECC_NISTP521, expected result 3. + * (6) CRYPT_PKEY_ParaId = CRYPT_ECC_BRAINPOOLP256R1, expected result 3. + * (7) CRYPT_PKEY_ParaId = CRYPT_ECC_BRAINPOOLP384R1, expected result 3. + * (8) CRYPT_PKEY_ParaId = CRYPT_ECC_BRAINPOOLP512R1, expected result 3. + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC001(void) +{ + ASSERT_TRUE(EAL_PkeySetParaById_Api_TC001(CRYPT_PKEY_ECDSA) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC002 + * @title Repeat to set different curves. + * @precon nan + * @brief + * 1. Create context(ecdsaPkey) of the ECDSA algorithm, expected result 1 + * 2. Set elliptic curve type to P224, expected result 2 + * 3. Set elliptic curve type to paraId, expected result 3 + * 4. Set private key, expected result 4 + * 5. Take over random numbers, mock BN_RandRange to generate randVector. + * 6. Compute the signature by ecdsaPkey, expected result 5 + * 7. Compares the hitls signature, expected result 6 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-5. CRYPT_SUCCESS + * 6. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC002( + int paraId, int mdId, Hex *prvKeyVector, Hex *plainText, Hex *signR, Hex *signS, Hex *randVector) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + FuncStubInfo tmpRpInfo; + int ret, vectorSignLen, hitlsSginLen; + uint8_t *vectorSign = NULL; + uint8_t *hitlsSign = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + + TestMemInit(); + + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(ecdsaPkey != NULL); + ASSERT_TRUE_AND_LOG( + "SetParaById NISTP224", CRYPT_EAL_PkeySetParaById(ecdsaPkey, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("SetParaById", CRYPT_EAL_PkeySetParaById(ecdsaPkey, paraId) == CRYPT_SUCCESS); + + /* Take over random numbers. */ + ASSERT_TRUE(memcpy_s(gkRandBuf, sizeof(gkRandBuf), randVector->x, randVector->len) == 0); + gkRandBufLen = randVector->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + /* Set private key */ + Ecc_SetPrvKey(&ecdsaPrvkey, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + + /* Signature */ + hitlsSginLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + hitlsSign = (uint8_t *)malloc(hitlsSginLen); + ASSERT_TRUE(hitlsSign != NULL); + ret = CRYPT_EAL_PkeySign(ecdsaPkey, mdId, plainText->x, plainText->len, hitlsSign, (uint32_t *)&hitlsSginLen); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeySign", ret == CRYPT_SUCCESS); + + /* Encode the R and S of the vector. */ + vectorSignLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + vectorSign = (uint8_t *)malloc(vectorSignLen); + ASSERT_TRUE(vectorSign != NULL); + ret = SignEncode(signR, signS, vectorSign, (uint32_t *)&vectorSignLen); + ASSERT_TRUE_AND_LOG("SignEncode", ret == CRYPT_SUCCESS); + + /* Compare the results of HiTLS vs. Vector. */ + ASSERT_EQ(hitlsSginLen, vectorSignLen); + ASSERT_TRUE(memcmp(vectorSign, hitlsSign, hitlsSginLen) == 0); + +exit: + STUB_Reset(&tmpRpInfo); + free(hitlsSign); + free(vectorSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SIGN_API_TC001 + * @title ECDSA CRYPT_EAL_PkeySign: Test the validity of parameters. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id(P-224) and set private key, expected result 2 + * 3. Call the CRYPT_EAL_PkeySign method: + * (1) pkey = null, expected result 3 + * (2) msg = null, expected result 4 + * (3) sign = NULL, signLen != 0, expected result 5 + * (4) sign != NULL, signLen = 0, expected result 6 + * (5) sign != NULL, signLen = 1, expected result 7 + * (6) msg != NULL, msgLen = 0, expected result 8 + * (7) Correct parameters, expected result 9 + * 4. Compare the signgures of HiTLS and vector, expected result 10 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3-5. CRYPT_NULL_INPUT + * 6-7. CRYPT_DSA_BUFF_LEN_NOT_ENOUGH + * 8-9. CRYPT_SUCCESS + * 10. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SIGN_API_TC001(int mdId, Hex *prvKeyVector, Hex *msg, Hex *signR, Hex *signS, Hex *randVector) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + FuncStubInfo tmpRpInfo; + int vectorSignLen; + uint32_t signLen; + uint8_t *vectorSign = NULL; + uint8_t *sign = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + + /* Register memory */ + TestMemInit(); + /* Take over random numbers. */ + ASSERT_TRUE(memcpy_s(gkRandBuf, sizeof(gkRandBuf), randVector->x, randVector->len) == 0); + gkRandBufLen = randVector->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(ecdsaPkey != NULL); + /* Set para by curve id and set private key. */ + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ecdsaPkey, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + Ecc_SetPrvKey(&ecdsaPrvkey, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeySign. */ + signLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + sign = (uint8_t *)malloc(signLen); + ASSERT_TRUE(sign != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(NULL, mdId, msg->x, msg->len, sign, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(ecdsaPkey, mdId, NULL, msg->len, sign, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(ecdsaPkey, mdId, msg->x, msg->len, NULL, &signLen), CRYPT_NULL_INPUT); + signLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeySign(ecdsaPkey, mdId, msg->x, msg->len, sign, &signLen), CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH); + signLen = 1; + ASSERT_EQ(CRYPT_EAL_PkeySign(ecdsaPkey, mdId, msg->x, msg->len, sign, &signLen), CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH); + + signLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + /* The plaintext length is 0 and the other parameters are normal, and it is expected to succeed. */ + ASSERT_EQ(CRYPT_EAL_PkeySign(ecdsaPkey, mdId, msg->x, 0, sign, &signLen), CRYPT_SUCCESS); + signLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ecdsaPkey, mdId, msg->x, msg->len, sign, (uint32_t *)&signLen) == CRYPT_SUCCESS); + + /* Encode the R and S of the vector. */ + vectorSignLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + vectorSign = (uint8_t *)malloc(vectorSignLen); + ASSERT_TRUE(vectorSign != NULL); + ASSERT_TRUE_AND_LOG( + "SignEncode", SignEncode(signR, signS, vectorSign, (uint32_t *)&vectorSignLen) == CRYPT_SUCCESS); + + /* Compare the results of HiTLS vs. Vector. */ + ASSERT_EQ(signLen, vectorSignLen); + ASSERT_TRUE(memcmp(vectorSign, sign, signLen) == 0); + +exit: + STUB_Reset(&tmpRpInfo); + free(sign); + free(vectorSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SIGN_API_TC002 + * @title ECDSA CRYPT_EAL_PkeySign: Missing private key. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id(P-224), expected result 2 + * 3. Call the CRYPT_EAL_PkeySign method to compute signature,expected result 3 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECDSA_ERR_EMPTY_KEY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SIGN_API_TC002(int mdId, Hex *plainText) +{ + uint32_t hitlsSignLen; + uint8_t *hitlsSign = NULL; + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + + TestMemInit(); + + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(ecdsaPkey != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ecdsaPkey, CRYPT_ECC_NISTP224) == CRYPT_SUCCESS); + + /* Signature */ + hitlsSignLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + hitlsSign = (uint8_t *)malloc(hitlsSignLen); + ASSERT_TRUE(hitlsSign != NULL); + + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeySign No PrvKey", + CRYPT_EAL_PkeySign(ecdsaPkey, mdId, plainText->x, plainText->len, hitlsSign, &hitlsSignLen) == + CRYPT_ECDSA_ERR_EMPTY_KEY); + +exit: + free(hitlsSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SIGN_API_TC003 + * @title ECDSA CRYPT_EAL_PkeySign: Missing private key. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id(P-224) and set private key, expected result 2 + * 3. Call the CRYPT_EAL_PkeySign method to compute signature,expected result 3 + * 4. Mock BN_RandRange to STUB_RandRangeK + * 5. Call the CRYPT_EAL_PkeySign method to compute signature,expected result 4 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_NO_REGIST_RAND + * 4. CRYPT_ECDSA_ERR_TRY_CNT on randVector is 0, otherwise CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SIGN_API_TC003(int mdId, Hex *prvKeyVector, Hex *plainText, Hex *randVector, int result) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + FuncStubInfo tmpRpInfo; + int ret, hitlsSginLen; + uint8_t *hitlsSign = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + + /* Register memory */ + TestMemInit(); + + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(ecdsaPkey != NULL); + + /* Set para by curve id and set private key */ + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ecdsaPkey, CRYPT_ECC_NISTP256) == CRYPT_SUCCESS); + Ecc_SetPrvKey(&ecdsaPrvkey, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + + /* Signature */ + hitlsSginLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + hitlsSign = (uint8_t *)malloc(hitlsSginLen); + ASSERT_TRUE(hitlsSign != NULL); + ret = CRYPT_EAL_PkeySign(ecdsaPkey, mdId, plainText->x, plainText->len, hitlsSign, (uint32_t *)&hitlsSginLen); + ASSERT_EQ(ret, CRYPT_NO_REGIST_RAND); + + /* Take over random numbers. */ + ASSERT_TRUE(memcpy_s(gkRandBuf, sizeof(gkRandBuf), randVector->x, randVector->len) == 0); + gkRandBufLen = randVector->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + ret = CRYPT_EAL_PkeySign(ecdsaPkey, mdId, plainText->x, plainText->len, hitlsSign, (uint32_t *)&hitlsSginLen); + if (result == 1) { + ASSERT_EQ(ret, CRYPT_SUCCESS); + } else { + ASSERT_EQ(ret, CRYPT_ECDSA_ERR_TRY_CNT); + } + +exit: + STUB_Reset(&tmpRpInfo); + free(hitlsSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SIGN_DATA_API_TC001 + * @title ECDSA CRYPT_EAL_PkeySign: Test the validity of parameters. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id(P-224) and set private key, expected result 2 + * 3. Call the CRYPT_EAL_PkeySignData method: + * (1) pkey = null, expected result 3 + * (2) msg = null, msgLen != 0, expected result 4 + * (3) msg != NULL, msgLen = 0, expected result 5 + * (4) sign = NULL, signLen != 0, expected result 6 + * (5) sign != NULL, signLen = NULL, expected result 7 + * (6) Correct parameters, expected result 8 + * (7) sign != NULL, signLen = 0, expected result 9 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3-7. CRYPT_NULL_INPUT + * 8. CRYPT_NO_REGIST_RAND + * 9. CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SIGN_DATA_API_TC001(Hex *prvKeyVector, Hex *msg) +{ + uint32_t hitlsSignLen; + uint8_t *hitlsSign = NULL; + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + + TestMemInit(); + + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(ecdsaPkey != NULL); + + /* Set para by curve id and set private key */ + ASSERT_TRUE(CRYPT_EAL_PkeySetParaById(ecdsaPkey, CRYPT_ECC_NISTP256) == CRYPT_SUCCESS); + Ecc_SetPrvKey(&ecdsaPrvkey, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + + /* Signature */ + hitlsSignLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + hitlsSign = (uint8_t *)malloc(hitlsSignLen); + ASSERT_TRUE(hitlsSign != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySignData(NULL, msg->x, msg->len, hitlsSign, &hitlsSignLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySignData(ecdsaPkey, NULL, msg->len, hitlsSign, &hitlsSignLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySignData(ecdsaPkey, msg->x, 0, hitlsSign, &hitlsSignLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySignData(ecdsaPkey, msg->x, msg->len, NULL, &hitlsSignLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySignData(ecdsaPkey, msg->x, msg->len, hitlsSign, NULL), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySignData(ecdsaPkey, msg->x, msg->len, hitlsSign, &hitlsSignLen), CRYPT_NO_REGIST_RAND); + hitlsSignLen = 0; + ASSERT_EQ( + CRYPT_EAL_PkeySignData(ecdsaPkey, msg->x, msg->len, hitlsSign, &hitlsSignLen), CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH); + +exit: + free(hitlsSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_CTRL_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyCtrl: Test the validity of opt. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method: + * (1) opt = CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, expected result 2 + * (2) opt = CRYPT_CTRL_SET_ED25519_HASH_METHOD, expected result 3 + * (3) opt = CRYPT_CTRL_SET_ECC_POINT_FORMAT, expected result 4 + * (4) opt = CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE, expected result 5 + * (5) opt = CRYPT_CTRL_SET_SM2_USER_ID, expected result 6 + * (6) opt = CRYPT_CTRL_SET_RSA_PADDING, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + * 3. CRYPT_EAL_ALG_NOT_SUPPORT + * 4. CRYPT_SUCCESS + * 5. CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION + * 6. CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + * 7. CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_CTRL_API_TC001(int type, int expect) +{ + ASSERT_TRUE(EAL_PkeyCtrl_Api_TC001(CRYPT_PKEY_ECDSA, type, expect) == SUCCESS); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_CTRL_API_TC002 + * @title ECDSA CRYPT_EAL_PkeyCtrl: Test the validity of pkey and value. + * @precon nan + * @brief + * 1. Create the context of the ECDSA algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method: + * (1) pkey = null, expected result 2 + * (2) val = null, len = 0, expected result 3 + * (3) val = null, len != 0, expected result 4 + * (4) val != null, len = 0, expected result 5 + * (5) PointFormat = CRYPT_POINT_MAX, expected result 6 + * (6) PointFormat = CRYPT_POINT_COMPRESSED, expected result 7 + * (7) PointFormat = CRYPT_POINT_UNCOMPRESSED, expected result 8 + * (8) PointFormat = CRYPT_POINT_HYBRID, expected result 9 + * @expect + * 1. Success, and the context is not NULL. + * 2-4. CRYPT_NULL_INPUT + * 5. CRYPT_ECC_PKEY_ERR_CTRL_LEN + * 6. CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT + * 7-9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_CTRL_API_TC002(void) +{ + ASSERT_TRUE(EAL_PkeyCtrl_Api_TC002(CRYPT_PKEY_ECDSA) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_CTRL_API_TC003 + * @title ECDSA CRYPT_EAL_PkeyCtrl: Test the effect of the point format on the key. + * @precon public key point + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId(p-224/256/384/512, bp256r1/384r1/512/r1), expected result 2 + * 3. Convert the format of the public key vector to COMPRESSED, expected result 3 + * 4. Set the public key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyCtrl method to set point format to COMPRESSED, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCtrl method to set point format to HYBRID, expected result 6 + * 7. Get the public key, expected result 7 + * 8. Convert the format of the public key vector to HYBRID, expected result 8 + * 9. Compare the output of the preceding two steps, expected result 9 + * @expect + * 1. Success, and the context is not NULL. + * 2-7. CRYPT_SUCCESS + * 9. The two are same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_CTRL_API_TC003(int eccId, Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeyCtrl_Api_TC003(CRYPT_PKEY_ECDSA, eccId, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GET_PRV_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyGetPrv: Test the validity of parameters. + * @precon private key + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Get the private key when there is no private key, expected result 3 + * 4. Set the private key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetPrv method: + * (1) pkey = null, expected result 5 + * (2) prv = null, expected result 6 + * (3) pkey.id != prv.id, expected result 7 + * (4) Correct parameters, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECC_PKEY_ERR_EMPTY_KEY + * 4. CRYPT_SUCCESS + * 5-6. CRYPT_NULL_INPUT + * 7. CRYPT_EAL_ERR_ALGID + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GET_PRV_API_TC001(Hex *prvKey) +{ + ASSERT_TRUE(EAL_PkeyGetPrv_Api_TC001(CRYPT_PKEY_ECDSA, prvKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GET_PUB_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyGetPub: Test the validity of parameters. + * @precon public key point + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Get the public key when there is no public key, expected result 3 + * 4. Set the public key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGetPub method: + * (1) pkey = null, expected result 5 + * (2) pub = null, expected result 6 + * (3) pkey.id != pub.id, expected result 7 + * (4) Correct parameters, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECC_PKEY_ERR_EMPTY_KEY + * 4. CRYPT_SUCCESS + * 5-6. CRYPT_NULL_INPUT + * 7. CRYPT_EAL_ERR_ALGID + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GET_PUB_API_TC001(Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeyGetPub_Api_TC001(CRYPT_PKEY_ECDSA, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PRV_API_TC001 + * @title ECDSA CRYPT_EAL_PkeySetPrv: Test the validity of parameters. + * @precon Prepare valid private key and invalid private key. + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the the valid private key before setting the curve, expected result 2 + * 3. Set the para by eccId(p-224), expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPrv method: + * (1) pkey = null, expected result 4 + * (2) prv = null, expected result 5 + * (3) pkey.id != prv.id, expected result 6 + * (4) Set the valid private key, expected result 7 + * (5) Set the invalid private key, expected result 8 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + * 4-5. CRYPT_NULL_INPUT + * 6. CRYPT_EAL_ERR_ALGID + * 7. CRYPT_SUCCESS + * 8. CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PRV_API_TC001(Hex *prvKey, Hex *errorPrvKey) +{ + ASSERT_TRUE(EAL_PkeySetPrv_Api_TC001(CRYPT_PKEY_ECDSA, prvKey, errorPrvKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PRV_API_TC002 + * @title Check whether the public key is cleared when the private key is set. + * @precon private key, public key point + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Set the the public key, expected result 3 + * 4. Set the the private key, expected result 4 + * 5. Get the the public key, expected result 5 + * @expect + * 1. Success, and the context is not NULL. + * 2-5. CRYPT_SUCCESSY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PRV_API_TC002(Hex *prvKey, Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeySetPrv_Api_TC002(CRYPT_PKEY_ECDSA, prvKey, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PUB_API_TC001 + * @title ECDSA CRYPT_EAL_PkeySetPub: Test the validity of parameters. + * @precon Prepare valid public key. + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the the public key before setting the curve, expected result 2 + * 3. Set the para by eccId(p-224), expected result 3 + * 4. Call the CRYPT_EAL_PkeySetPub method: + * (1) pkey = null, expected result 4 + * (2) pub = null, expected result 5 + * (3) pkey.id != pub.id, expected result 6 + * (4) Set the valid public key, expected result 7 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_SUCCESS + * 4-5. CRYPT_NULL_INPUT + * 6. CRYPT_EAL_ERR_ALGID + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PUB_API_TC001(Hex *pubKeyVector) +{ + ASSERT_TRUE(EAL_PkeySetPub_Api_TC001(CRYPT_PKEY_ECDSA, pubKeyVector) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PUB_API_TC002 + * @title Check whether the private key is cleared when the public key is set. + * @precon public key, private key + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId(p-224), expected result 2 + * 3. Set the the private key, expected result 3 + * 4. Set the the public key, expected result 4 + * 5. Get the the private key, expected result 5 + * @expect + * 1. Success, and the context is not NULL. + * 2-5. CRYPT_SUCCESSY + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PUB_API_TC002(Hex *prvKey, Hex *pubKey) +{ + ASSERT_TRUE(EAL_PkeySetPub_Api_TC002(CRYPT_PKEY_ECDSA, prvKey, pubKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 + * @title Test the function of setting public keys of different lengths. + * @precon Public keys of different lengths. + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId(p-224/256/384/512, bp256r1/384r1/512/r1), expected result 2 + * 3. Set public keys of different lengths, expected result 3 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESSY + * 3. CRYPT_ECC_ERR_POINT_CODE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PUB_API_TC003(int eccId, Hex *pubKey, Hex *errorPubKey) +{ + ASSERT_TRUE(EAL_PkeySetPub_Api_TC003(CRYPT_PKEY_ECDSA, eccId, pubKey, errorPubKey) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyGetParaId test. + * @precon Registering memory-related functions. + * @brief + * 1. Get para id before creating context, expected result 1 + * 2. Create the context of the ECDSA algorithm, expected result 2 + * 3. Set para id(p-224/256/384/512), expected result 3 + * 4. Get para id, expected result 4 + * @expect + * 1. CRYPT_PKEY_PARAID_MAX + * 2. Success, and the context is not NULL. + * 3. CRYPT_SUCCESS + * 4. The obtained id is the same as the set id. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001(int id) +{ + ASSERT_TRUE(EAL_PkeyGetParaId_Api_TC001(CRYPT_PKEY_ECDSA, id) == 0); + +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_CMP_FUNC_TC001 + * @title ECDSA: CRYPT_EAL_PkeyCmp test. + * @precon Registering memory-related functions. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the ecdsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set para id CRYPT_ECC_NISTP224 and public key for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set para id CRYPT_ECC_NISTP256 for ctx2, expected result 5 + * 6. Set public key for ctx2, expected result 6 + * 7. Set para id CRYPT_ECC_NISTP224 and public key for ctx2, expected result 7 + * 8. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 8 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 3. CRYPT_SUCCESS + * 4. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 5. CRYPT_SUCCESS + * 6. CRYPT_ECC_ERR_POINT_CODE + * 7. CRYPT_SUCCESS + * 8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_CMP_FUNC_TC001(Hex *pubKeyX, Hex *pubKeyY) +{ + ASSERT_TRUE(EAL_PkeyCmp_Api_TC001(CRYPT_PKEY_ECDSA, pubKeyX, pubKeyY) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_VERIFY_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyVerify: Test the validity of parameters. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id(P-224), expected result 2 + * 3. Verify when there is no public key, expected result 3 + * 4. Set public key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyVerify method: + * (1) pkey = null, expected result 5 + * (2) data = null, dataLen != 0, expected result 6 + * (3) data = null or data != null, and dataLen = 0, expected result 7 + * (4) sign = null, signLen != 0 or signLen = 0, expected result 8 + * (5) sign != null, signLen = 0, expected result 9 + * (6) sign != null, signLen = 1, expected result 10 + * (7) Correct parameters, expected result 11 + * @expect + * 1. Success, and the context is not null. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECDSA_ERR_EMPTY_KEY + * 4. CRYPT_SUCCESS + * 5-6. CRYPT_NULL_INPUT + * 7. CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH + * 8-9. CRYPT_NULL_INPUT + * 10. CRYPT_DSA_DECODE_FAIL + * 11. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_VERIFY_API_TC001(Hex *data, Hex *pubKeyX, Hex *pubKeyY, Hex *sign) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub ecdsaPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + CRYPT_MD_AlgId mdId = CRYPT_MD_SHA224; + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("New ECDSA Pkey", pkey != NULL); + + /* Set para by curve id. */ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(pkey, CRYPT_ECC_NISTP224), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", EccPointToBuffer(pubKeyX, pubKeyY, 1, &pubKeyVector) == CRYPT_SUCCESS); + + /* Verify when there is no public key. */ + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, data->len, sign->x, sign->len) == CRYPT_ECDSA_ERR_EMPTY_KEY); + + /* Set public key. */ + Ecc_SetPubKey(&ecdsaPubkey, CRYPT_PKEY_ECDSA, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &ecdsaPubkey), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyVerify. */ + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(NULL, mdId, data->x, data->len, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, NULL, data->len, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, NULL, 0, sign->x, sign->len) == CRYPT_ECDSA_VERIFY_FAIL); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, 0, sign->x, sign->len) == CRYPT_ECDSA_VERIFY_FAIL); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, data->len, NULL, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, data->len, NULL, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, data->len, sign->x, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, data->len, sign->x, 1) == CRYPT_DSA_DECODE_FAIL); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, mdId, data->x, data->len, sign->x, sign->len) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002 + * @title ED25519 sets the keys and performs signature and verifiy tests on the hash data. + * @precon nan + * @brief + * 1. Create context(ecdsaPkey) of the ECDSA algorithm, expected result 1 + * 2. Set elliptic curve type, private key, expected result 2 + * 3. Take over random numbers, mock BN_RandRange to generate randVector. + * 4. Sign the hash data(all 0x00 or all 0xFF) using ecdsaPkey, expected result 3 + * 5. Reset the stubbed function. + * 6. Create context(ecdsaPkey2) of the ECDSA algorithm, expected result 4 + * 7. Set elliptic curve type, public key, expected result 5 + * 9. Verify the signature by ecdsaPkey2, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Success, and context is not NULL. + * 5-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002( + int eccId, Hex *prvKeyVector, Hex *hashData, Hex *randVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat) +{ + uint32_t hitlsSignLen; + FuncStubInfo tmpRpInfo; + uint8_t *hitlsSign = NULL; + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + CRYPT_EAL_PkeyCtx *ecdsaPkey2 = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + CRYPT_EAL_PkeyPub ecdsaPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + + /* Register memory */ + TestMemInit(); + + /* Create an ECDSA context for signing*/ + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(ecdsaPkey != NULL); + + /* Set para by curve id and set private key */ + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeySetParaById", CRYPT_EAL_PkeySetParaById(ecdsaPkey, eccId) == CRYPT_SUCCESS); + Ecc_SetPrvKey(&ecdsaPrvkey, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + + /* Take over random numbers. */ + ASSERT_TRUE(memcpy_s(gkRandBuf, sizeof(gkRandBuf), randVector->x, randVector->len) == 0); + gkRandBufLen = randVector->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + /* Sign hash data */ + hitlsSignLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + hitlsSign = (uint8_t *)malloc(hitlsSignLen); + ASSERT_TRUE(hitlsSign != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySignData(ecdsaPkey, hashData->x, hashData->len, hitlsSign, &hitlsSignLen), CRYPT_SUCCESS); + + /* Reset the stubbed function */ + STUB_Reset(&tmpRpInfo); + + /* Create an ESA context for signature verification. */ + ecdsaPkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyNewCtx", ecdsaPkey2 != NULL); + + /* Set para by curve id and set public key */ + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeySetParaById", CRYPT_EAL_PkeySetParaById(ecdsaPkey2, eccId) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG( + "EccPointToBuffer", EccPointToBuffer(pubKeyX, pubKeyY, pointFormat, &pubKeyVector) == CRYPT_SUCCESS); + Ecc_SetPubKey(&ecdsaPubkey, CRYPT_PKEY_ECDSA, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ecdsaPkey2, &ecdsaPubkey), CRYPT_SUCCESS); + + /* Verify hash data */ + ASSERT_EQ(CRYPT_EAL_PkeyVerifyData(ecdsaPkey2, hashData->x, hashData->len, hitlsSign, hitlsSignLen), CRYPT_SUCCESS); + +exit: + free(hitlsSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey2); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_VERIFY_DATA_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyVerifyData: Test the validity of parameters. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id, expected result 2 + * 3. Verify when there is no public key, expected result 3 + * 4. Set public key, expected result 4 + * 5. Call the CRYPT_EAL_PkeyVerify method: + * (1) pkey = null, expected result 5 + * (2) data = null, dataLen != 0, expected result 6 + * (3) data = null or data != null, and dataLen = 0, expected result 7 + * (4) sign = null, signLen != 0 or signLen = 0, expected result 8 + * (5) sign != null, signLen = 0, expected result 9 + * @expect + * 1. Success, and the context is not null. + * 2. CRYPT_SUCCESS + * 3. CRYPT_ECDSA_ERR_EMPTY_KEY + * 4. CRYPT_SUCCESS + * 5-9. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_VERIFY_DATA_API_TC001(int paraId, Hex *hashData, Hex *pubKeyX, Hex *pubKeyY, Hex *sign) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub ecdsaPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(pkey != NULL); + + /* Set para by curve id */ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(pkey, paraId), CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", EccPointToBuffer(pubKeyX, pubKeyY, 1, &pubKeyVector) == CRYPT_SUCCESS); + + ASSERT_TRUE( + CRYPT_EAL_PkeyVerifyData(pkey, hashData->x, hashData->len, sign->x, sign->len) == CRYPT_ECDSA_ERR_EMPTY_KEY); + + /* Set public key */ + Ecc_SetPubKey(&ecdsaPubkey, CRYPT_PKEY_ECDSA, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &ecdsaPubkey), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyVerifyData. */ + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(NULL, hashData->x, hashData->len, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(pkey, NULL, hashData->len, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(pkey, hashData->x, 0, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(pkey, NULL, 0, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(pkey, hashData->x, hashData->len, NULL, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(pkey, hashData->x, hashData->len, NULL, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerifyData(pkey, hashData->x, hashData->len, sign->x, 0) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyGetSecurityBits: Test the validity of parameters. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id, expected result 2 + * 3. Call the CRYPT_EAL_PkeyVerify method and set the parameter to null, expected result 3 + * 4. Call the CRYPT_EAL_PkeyVerify method and the parameter is correct, expected result 4 + * @expect + * 1. Success, and the context is not null. + * 2. CRYPT_SUCCESS + * 3. The return value is 0. + * 4. The return value is not 0. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001(int paraId, int securitybits) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + + TestMemInit(); + + /* Create an ECDSA context */ + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("New ECDSA Pkey", ecdsaPkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdsaPkey, paraId), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyGetSecurityBits. */ + ASSERT_TRUE(CRYPT_EAL_PkeyGetSecurityBits(NULL) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyGetSecurityBits(ecdsaPkey) == (uint32_t)securitybits); + +exit: + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001 + * @title ECDSA CRYPT_EAL_PkeyGetKeyBits: Test the validity of parameters. + * @precon nan + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set para by curve id, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetKeyBits method and set the parameter to null, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGetKeyBits method and the parameter is correct, expected result 4 + * @expect + * 1. Success, and the context is not null. + * 2. CRYPT_SUCCESS + * 3. The return value is 0. + * 4. The return value is not 0. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001(int paraId, int keyBitsLen) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + + TestMemInit(); + + /* Create an ECDSA context */ + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("New ECDSA Pkey", ecdsaPkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdsaPkey, paraId), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeyGetKeyBits. */ + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(NULL) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(ecdsaPkey) == (uint32_t)keyBitsLen); + +exit: + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PARA_API_TC001 + * @title ECDSA CRYPT_EAL_PkeySetPara: Test the validity of parameters. + * @precon Prepare valid private key and invalid private key. + * @brief + * 1. Create the context of the ecdsa algorithm, expected result 1 + * 2. Set the para by eccId, expected result 2 + * 3. Call the CRYPT_EAL_PkeySetPara method: + * (1) pkey = null, expected result 3 + * (2) para = null, expected result 4 + * (3) pkey.id != para.id, expected result 5 + * (4) The parameter structure is empty, expected result 6 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3-4. CRYPT_NULL_INPUT + * 5. CRYPT_EAL_ERR_ALGID + * 6. CRYPT_EAL_ERR_NEW_PARA_FAIL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PARA_API_TC001(int paraId) +{ + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(pkey, paraId), CRYPT_SUCCESS); + + /* Input parameter test of CRYPT_EAL_PkeySetPara. */ + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(NULL, ¶) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, NULL) == CRYPT_NULL_INPUT); + para.id = CRYPT_PKEY_DSA; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_ALGID); + para.id = CRYPT_PKEY_ECDSA; + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 + * @title ECDSA sign and verify test: different hash and curve. + * @precon nan + * @brief + * 1. Init the drbg, expected result 1 + * 2. Create context(ecdsaPkey) of the ECDSA algorithm, expected result 2 + * 3. Set elliptic curve type, private key and public key, expected result 3 + * 4. Take over random numbers, mock BN_RandRange to generate randVector. + * 5. Compute the signature by ecdsaPkey, expected result 4 + * 6. Compares the hitls signature, expected result 5 + * 7. Verify the signature by ecdsaPkey, expected result 6 + * 8. Call the CRYPT_EAL_PkeyCopyCtx method to copy the context, expected result 7 + * 9. Use the copied context for signing and verification, expected result 8 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Both are the same. + * 6-8. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001(int eccId, int mdId, Hex *prvKeyVector, Hex *msg, Hex *signR, Hex *signS, + Hex *randVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat) +{ + if (IsMdAlgDisabled(mdId)) { + SKIP_TEST(); + } + int ret, vectorSignLen, hitlsSginLen; + uint8_t *vectorSign = NULL; + uint8_t *hitlsSign = NULL; + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + CRYPT_EAL_PkeyPub ecdsaPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + FuncStubInfo tmpRpInfo; + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("New ECDSA Pkey", ecdsaPkey != NULL); + + /* Set para by curve id */ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdsaPkey, eccId), CRYPT_SUCCESS); + /* Set private key */ + Ecc_SetPrvKey(&ecdsaPrvkey, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + /* Set public key */ + ret = EccPointToBuffer(pubKeyX, pubKeyY, pointFormat, &pubKeyVector); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", ret == CRYPT_SUCCESS); + Ecc_SetPubKey(&ecdsaPubkey, CRYPT_PKEY_ECDSA, pubKeyVector.data, pubKeyVector.len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ecdsaPkey, &ecdsaPubkey), CRYPT_SUCCESS); + + /* Take over random numbers. */ + ASSERT_TRUE(memcpy_s(gkRandBuf, sizeof(gkRandBuf), randVector->x, randVector->len) == 0); + gkRandBufLen = randVector->len; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + /* Signature */ + hitlsSginLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + hitlsSign = (uint8_t *)malloc(hitlsSginLen); + ASSERT_TRUE(hitlsSign != NULL); + ret = CRYPT_EAL_PkeySign(ecdsaPkey, mdId, msg->x, msg->len, hitlsSign, (uint32_t *)&hitlsSginLen); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeySign", ret == CRYPT_SUCCESS); + + /* Encode the R and S of the vector. */ + vectorSignLen = CRYPT_EAL_PkeyGetSignLen(ecdsaPkey); + vectorSign = (uint8_t *)malloc(vectorSignLen); + ASSERT_TRUE(vectorSign != NULL); + ret = SignEncode(signR, signS, vectorSign, (uint32_t *)&vectorSignLen); + ASSERT_TRUE_AND_LOG("SignEncode", ret == CRYPT_SUCCESS); + + /* Compare the results of HiTLS vs. Vector. */ + ASSERT_EQ(hitlsSginLen, vectorSignLen); + ASSERT_TRUE(memcmp(vectorSign, hitlsSign, hitlsSginLen) == 0); + + STUB_Reset(&tmpRpInfo); + + /* Verify */ + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ecdsaPkey, mdId, msg->x, msg->len, hitlsSign, hitlsSginLen) == CRYPT_SUCCESS); + + /* Copy the contexts: sign and verify */ + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, ecdsaPkey), CRYPT_SUCCESS); + hitlsSginLen = CRYPT_EAL_PkeyGetSignLen(cpyCtx); + ASSERT_EQ(CRYPT_EAL_PkeySign(cpyCtx, mdId, msg->x, msg->len, hitlsSign, (uint32_t *)&hitlsSginLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(cpyCtx, mdId, msg->x, msg->len, hitlsSign, hitlsSginLen), CRYPT_SUCCESS); + +exit: + STUB_Reset(&tmpRpInfo); + free(hitlsSign); + free(vectorSign); + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001 + * @title Test set public key. + * @precon nan + * @brief + * 1. Init the drbg, expected result 1 + * 2. Create context(ecdsaPkey) of the ECDSA algorithm, expected result 2 + * 3. Set elliptic curve type, private key and public key, expected result 3 + * 4. Convert the format of the public key vector to COMPRESSED, expected result 4 + * 5. Call the CRYPT_EAL_PkeySetPub to set public key, expected result 5 + * @expect + * 1. CRYPT_SUCCESS + * 2. Success, and context is not NULL. + * 3. CRYPT_SUCCESS + * 4. CRYPT_SUCCESS + * 5. CRYPT_SUCCESS on result=1 + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001(int eccId, Hex *publicX, Hex *publicY, int result, int pointFormat) +{ + int ret; + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + CRYPT_EAL_PkeyPub ECDSAPubkey; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("New ECDSA Pkey", ecdsaPkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdsaPkey, eccId), CRYPT_SUCCESS); + + ret = EccPointToBuffer(publicX, publicY, pointFormat, &pubKeyVector); + ASSERT_TRUE_AND_LOG("EccPointToBuffer", ret == CRYPT_SUCCESS); + Ecc_SetPubKey(&ECDSAPubkey, CRYPT_PKEY_ECDSA, pubKeyVector.data, pubKeyVector.len); + if (result == 1) { + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ecdsaPkey, &ECDSAPubkey), CRYPT_SUCCESS); + } else { + ASSERT_NE(CRYPT_EAL_PkeySetPub(ecdsaPkey, &ECDSAPubkey), CRYPT_SUCCESS); + } + +exit: + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + CRYPT_EAL_RandDeinit(); + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GET_PARA_FUNC_TC001 + * @title ECD CRYPT_EAL_PkeyGetPara test. + * @precon Registering memory-related functions. + * @brief + * 1. Create context of the ECDSA algorithm, expected result 1 + * 2. Set para, expected result 2 + * 3. Get para, expected result 3 + * 4. Check whether the set parameters and the obtained parameters are the same, expected result 4 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. The parameters are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GET_PARA_FUNC_TC001(Hex *p, Hex *a, Hex *b, Hex *x, Hex *y, Hex *n, Hex *h) +{ + ASSERT_TRUE(EAL_PkeyGetPara_Func_TC001(CRYPT_PKEY_ECDSA, p, a, b, x, y, n, h) == 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 + * @title ECDSA CRYPT_EAL_PkeyGen test. + * @precon nan + * @brief + * 1. Create context of the ECDSA algorithm, expected result 1 + * 2. Set elliptic curve type, expected result 2 + * 3. Mock BN_RandRange to STUB_RandRangeK + * 4. Init the drbg, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGen method to generate a key pair, expected result 5 + * 6. Get public key and private key, expected result 6 + * 7. Compare the getted key and vector, expected result 7 + * @expect + * 1. Success, and two contexts are not NULL. + * 2. non + * 4-6. CRYPT_SUCCESS + * 7. The getted key and vector are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001(int eccId, Hex *prvKeyVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat) +{ + Ecc_GenKey(CRYPT_PKEY_ECDSA, eccId, prvKeyVector, pubKeyX, pubKeyY, pointFormat); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_ECDSA_KEY_PAIR_CHECK_FUNC_TC001 + * @title ECDSA: key pair check. + * @precon Registering memory-related functions. + * @brief + * 1. Create two contexts(pubCtx, prvCtx) of the ecdsa algorithm, expected result 1 + * 2. Init the drbg, expected result 2 + * 3. Set para for pubCtx, expected result 3 + * 4. Set public key for pubCtx, expected result 4 + * 5. Set para and private key for prvCtx, expected result 5 + * 6. Check whether the public key matches the private key, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2-5. CRYPT_SUCCESS + * 6. Return CRYPT_SUCCESS when expect is 1, CRYPT_ECDSA_VERIFY_FAIL otherwise. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_KEY_PAIR_CHECK_FUNC_TC001( + int eccId, Hex *prvKeyVector, Hex *pubKeyX, Hex *pubKeyY, int pointFormat, int expect) +{ + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + KeyData pubKeyVector = {{0}, KEY_MAX_LEN}; + int expectRet = expect == 1 ? CRYPT_SUCCESS : CRYPT_ECDSA_VERIFY_FAIL; + + ASSERT_EQ(EccPointToBuffer(pubKeyX, pubKeyY, pointFormat, &pubKeyVector), CRYPT_SUCCESS); + Ecc_SetPubKey(&pub, CRYPT_PKEY_ECDSA, pubKeyVector.data, pubKeyVector.len); + Ecc_SetPrvKey(&prv, CRYPT_PKEY_ECDSA, prvKeyVector->x, prvKeyVector->len); + + TestMemInit(); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE(pubCtx != NULL && prvCtx != NULL); + + /* pubCtx*/ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(pubCtx, eccId), CRYPT_SUCCESS); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pubCtx, &pub), CRYPT_SUCCESS); + + /* prvCtx*/ + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(prvCtx, eccId), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(prvCtx, &prv), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyPairCheck(pubCtx, prvCtx), expectRet); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pubCtx); + CRYPT_EAL_PkeyFreeCtx(prvCtx); +} +/* END_CASE */ + +/* @ +* @test SDV_CRYPTO_ECDSA_API_TC026 +* @title ECDSA get key length +* @brief +1.create ECDSA context. Expect result 1 +2.set curve,expect result 2 +3.get key length, expect result 3 +* @expect 1.context created successfully +2.Success +3.Success +@ */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_API_TC026(int paraId, int keyLen) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdsaPkey, paraId), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetKeyLen(ecdsaPkey), keyLen); +exit: + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); +} +/* END_CASE */ + +/* @ +* @test SDV_CRYPTO_ECDSA_API_TC027 +* @title ECDSA pkey check test +* @brief +1.create ECDSA context. Expect result 1 +2.set curve. expect result 2 +3.get key length. expect result 3 +* @expect 1. context created successfully +2. CRYPT_EAL_ALG_NOT_SUPPORT +@ */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECDSA_API_TC027(int algId) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + pkey = CRYPT_EAL_PkeyNewCtx(algId); + ASSERT_EQ(CRYPT_EAL_PkeyCheck(pkey), CRYPT_EAL_ALG_NOT_SUPPORT); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_GETSECURITYBITS_API_TC001 + * @title Get security bits test + * @brief + * 1. Create context of the ECDSA algorithm, expected result 1 + * 2. Set curve type, expected result 2 + * 3. Get para, expected result 3 + * 4. Obtain security bits are the same, expected result 4 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. The security bits are correct. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_GETSECURITYBITS_API_TC001(int eccId, Hex *prvKeyVector, int secBits) +{ + CRYPT_EAL_PkeyCtx *ecdsaPkey = NULL; + CRYPT_EAL_PkeyPrv ecdsaPrvkey = {0}; + + ecdsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_TRUE_AND_LOG("New ECDH Pkey", ecdsaPkey != NULL); + // Set elliptic curve type CRYPT_ECC_NISTP224 = 13 + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(ecdsaPkey, eccId), CRYPT_SUCCESS); + // Set private key + ecdsaPrvkey.id = CRYPT_PKEY_ECDSA; + ecdsaPrvkey.key.eccPrv.data = prvKeyVector->x; + ecdsaPrvkey.key.eccPrv.len = prvKeyVector->len; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ecdsaPkey, &ecdsaPrvkey), CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetSecurityBits(ecdsaPkey) == (uint32_t)secBits); + +exit: + CRYPT_EAL_PkeyFreeCtx(ecdsaPkey); + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdsa.data b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdsa.data new file mode 100644 index 00000000..f5cb59c6 --- /dev/null +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdsa.data @@ -0,0 +1,494 @@ +SDV_CRYPTO_ECDSA_NEW_CTX_API_TC001 +SDV_CRYPTO_ECDSA_NEW_CTX_API_TC001: + +SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC001 +SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC001: + +SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC002: Nist [P-256,SHA-224] +SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC002:CRYPT_ECC_NISTP256:CRYPT_MD_SHA224:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2":"4a19274429e40522234b8785dc25fc524f179dcc95ff09b3c9770fc71f54ca0d":"58982b79a65b7320f5b92d13bdaecdd1259e760f0f718ba933fd098f6f75d4b7":"58f741771620bdc428e91a32d86d230873e9140336fcfb1e122892ee1d501bdc" + +SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC002: Nist [P-384,SHA-224] +SDV_CRYPTO_ECDSA_SET_PARA_BY_ID_API_TC002:CRYPT_ECC_NISTP384:CRYPT_MD_SHA224:"0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727":"39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938":"c36e5f0d3de71411e6e519f63e0f56cff432330a04fefef2993fdb56343e49f2f7db5fcab7728acc1e33d4692553c02e":"0d4064399d58cd771ab9420d438757f5936c3808e97081e457bc862a0c905295dca60ee94f4537591c6c7d217453909b":"e2f0ce83c5bbef3a6eccd1744f893bb52952475d2531a2854a88ff0aa9b12c65961e2e517fb334ef40e0c0d7a31ed5f5" + +SDV_CRYPTO_ECDSA_SIGN_API_TC001: Nist +SDV_CRYPTO_ECDSA_SIGN_API_TC001:CRYPT_MD_SHA224:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d":"2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6":"8d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb":"d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0" + +SDV_CRYPTO_ECDSA_SIGN_API_TC002: Nist +SDV_CRYPTO_ECDSA_SIGN_API_TC002:CRYPT_MD_SHA224:"699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d" + +SDV_CRYPTO_ECDSA_SIGN_API_TC003: Nist [P-256,SHA-224] +SDV_CRYPTO_ECDSA_SIGN_API_TC003:CRYPT_MD_SHA224:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2":"0000000000000000000000000000000000000000000000000000000000000000":0 + +SDV_CRYPTO_ECDSA_SIGN_API_TC003: Nist [P-256,SHA-224] +SDV_CRYPTO_ECDSA_SIGN_API_TC003:CRYPT_MD_SHA224:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":1 + +SDV_CRYPTO_ECDSA_SIGN_DATA_API_TC001: Nist +SDV_CRYPTO_ECDSA_SIGN_DATA_API_TC001:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2" + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002 P-224 msg IS ALL 0X00 +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002:CRYPT_ECC_NISTP224:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002 P-224 msg IS ALL 0XFF +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002:CRYPT_ECC_NISTP224:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002 P-256 msg IS ALL 0X00 +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002:CRYPT_ECC_NISTP256:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"58f741771620bdc428e91a32d86d230873e9140336fcfb1e122892ee1d501bdc":"29578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab":"08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002 P-256 msg IS ALL 0XFF +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC002:CRYPT_ECC_NISTP256:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"58f741771620bdc428e91a32d86d230873e9140336fcfb1e122892ee1d501bdc":"29578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab":"08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":1 + +SDV_CRYPTO_ECDSA_CTRL_API_TC001: CRYPT_CTRL_SET_RSA_RSAES_PKCSV15 +SDV_CRYPTO_ECDSA_CTRL_API_TC001:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDSA_CTRL_API_TC001: CRYPT_CTRL_SET_ED25519_HASH_METHOD +SDV_CRYPTO_ECDSA_CTRL_API_TC001:CRYPT_CTRL_SET_ED25519_HASH_METHOD:CRYPT_EAL_ALG_NOT_SUPPORT + +SDV_CRYPTO_ECDSA_CTRL_API_TC001: CRYPT_CTRL_SET_ECC_POINT_FORMAT +SDV_CRYPTO_ECDSA_CTRL_API_TC001:CRYPT_CTRL_SET_ECC_POINT_FORMAT:CRYPT_SUCCESS + +SDV_CRYPTO_ECDSA_CTRL_API_TC001: CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE +SDV_CRYPTO_ECDSA_CTRL_API_TC001:CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE:CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDSA_CTRL_API_TC001: CRYPT_CTRL_SET_SM2_USER_ID +SDV_CRYPTO_ECDSA_CTRL_API_TC001:CRYPT_CTRL_SET_SM2_USER_ID:CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDSA_CTRL_API_TC001: CRYPT_CTRL_SET_RSA_PADDING +SDV_CRYPTO_ECDSA_CTRL_API_TC001:CRYPT_CTRL_SET_RSA_PADDING:CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION + +SDV_CRYPTO_ECDSA_CTRL_API_TC002 +SDV_CRYPTO_ECDSA_CTRL_API_TC002: + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: Nist P-224 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_NISTP224:"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: Nist P-256 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_NISTP256:"29578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab":"08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800" + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: Nist P-384 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_NISTP384:"de92ff09af2950854a70f2178d2ed50cc7042a7188301a1ea81d9629ad3c29795cb7f0d56630a401e4d6e5bed0068d1e":"6135adbd8624130735e64e65ecbd43770dcc12b28e737b5ed033666f34c918eb5589508e4a13b9243374a118a628dd0b" + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: Nist P-521 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_NISTP521:"01a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e7":"0184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b" + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: RFC 6932, brainpool p256r1 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_BRAINPOOLP256R1:"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B" + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: RFC 6932, brainpool p384r1 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_BRAINPOOLP384R1:"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859" + +SDV_CRYPTO_ECDSA_CTRL_API_TC003: RFC 6932, brainpool p512r1 +SDV_CRYPTO_ECDSA_CTRL_API_TC003:CRYPT_ECC_BRAINPOOLP512R1:"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E" + +SDV_CRYPTO_ECDSA_GET_PRV_API_TC001: Nist +SDV_CRYPTO_ECDSA_GET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615" + +SDV_CRYPTO_ECDSA_GET_PUB_API_TC001: Nist +SDV_CRYPTO_ECDSA_GET_PUB_API_TC001:"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDSA_SET_PRV_API_TC001: Nist +SDV_CRYPTO_ECDSA_SET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3f" + +SDV_CRYPTO_ECDSA_SET_PRV_API_TC001: Nist +SDV_CRYPTO_ECDSA_SET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"00000000000000000000000000000000000000000000000000000000" + +SDV_CRYPTO_ECDSA_SET_PRV_API_TC001 prvKey > n +SDV_CRYPTO_ECDSA_SET_PRV_API_TC001:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" + +SDV_CRYPTO_ECDSA_SET_PRV_API_TC002: Nist +SDV_CRYPTO_ECDSA_SET_PRV_API_TC002:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC001: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC001:"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC002: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC002:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP256R1:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP384R1:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP512R1:"":"" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"05605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc666a" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"06605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc666a" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP224:"07ac635fe00e8b7a3c8ef5655bdfb7f83e8532e59c0cc0b6534d810ffa1d067aebeba66e79b28ecfe59ac6fdf5e1970dc3a84499c9d90cd8e2":"04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc666a" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"0529578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":"0429578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4801" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"066b738de3398b6ac57b9591f9d7985dd4f32137ad3460dcf8970c1390cb9eaf8d83bc61e26d2bbbd3cf2d2ab445a2bc4ab5dde41f4a13078fd1d3cc36ab596d57":"0429578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4801" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP256:"0729578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":"0429578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4801" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"0500ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3e":"0400ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3f" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"06fb937e4a303617b71b6c1a25f2ac786087328a3e26bdef55e52d46ab5e69e5411bf9fc55f5df9994d2bf82e8f39a153ea97d9075e92fa5bfe67e6ec18e21cc4d11fde59a68aef72c0e46a28f31a9d60385f41f39da468f4e6c3d3fbac9046765":"0400ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3f" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP384:"0700ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3e":"0400ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3f" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"0501a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b":"0401a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027c" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"0601a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b":"0401a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e70184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027c" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: Nist +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_NISTP521:"0700156cd2c485012ea5d5aadad724fb87558637de37b34485c4cf7c8cbc3e4f106cb1efd3e64f0adf99ddb51e3ac991bdd90785172386cdaf2c582cc46d6c99b0fed101edeeda717554252b9f1e13553d4af028ec9e158dbe12332684fc1676dc731f39138a5d301376505a9ab04d562cc1659b0be9cb2b5e03bad8b412f2699c245b0ba2":"0400156cd2c485012ea5d5aadad724fb87558637de37b34485c4cf7c8cbc3e4f106cb1efd3e64f0adf99ddb51e3ac991bdd90785172386cdaf2c582cc46d6c99b0fed101edeeda717554252b9f1e13553d4af028ec9e158dbe12332684fc1676dc731f39138a5d301376505a9ab04d562cc1659b0be9cb2b5e03bad8b412f2699c245b0ba3" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: FRC 7072 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP256R1:"8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A":"0678028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92C" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: FRC 7072 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP384R1:"68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF06855BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59":"0645CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC85A" + +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003: FRC 7072 +SDV_CRYPTO_ECDSA_SET_PUB_API_TC003:CRYPT_ECC_BRAINPOOLP512R1:"0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7":"070562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDAA7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642F" + +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP224 + +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP256 + +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP384 + +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001 +SDV_CRYPTO_ECDSA_GET_PARA_ID_API_TC001:CRYPT_ECC_NISTP521 + +SDV_CRYPTO_ECDSA_CMP_FUNC_TC001 Nist, P-224 COMPRESS +SDV_CRYPTO_ECDSA_CMP_FUNC_TC001:"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669" + +SDV_CRYPTO_ECDSA_VERIFY_API_TC001: Nist +SDV_CRYPTO_ECDSA_VERIFY_API_TC001:"699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":"303d021c2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6021d008d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb" + +SDV_CRYPTO_ECDSA_VERIFY_DATA_API_TC001: Nist +SDV_CRYPTO_ECDSA_VERIFY_DATA_API_TC001:CRYPT_ECC_NISTP224:"699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":"303d021c2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6021d008d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb" + +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001:CRYPT_ECC_NISTP224:112 + +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001:CRYPT_ECC_NISTP256:128 + +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001:CRYPT_ECC_NISTP384:192 + +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_SECURITY_BITS_API_TC001:CRYPT_ECC_NISTP521:256 + +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001:CRYPT_ECC_NISTP224:456 + +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001:CRYPT_ECC_NISTP256:520 + +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001:CRYPT_ECC_NISTP384:776 + +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001 +SDV_CRYPTO_ECDSA_GET_KEY_BITS_API_TC001:CRYPT_ECC_NISTP521:1064 + +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001 +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001:CRYPT_ECC_NISTP224 + +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001 +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001:CRYPT_ECC_NISTP256 + +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001 +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001:CRYPT_ECC_NISTP384 + +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001 +SDV_CRYPTO_ECDSA_SET_PARA_API_TC001:CRYPT_ECC_NISTP256 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-224,SHA-224] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP224:CRYPT_MD_SHA224:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d":"2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6":"8d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb":"d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":0 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-224,SHA-256] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP224:CRYPT_MD_SHA256:"888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa":"2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e":"0909c9b9cae8d2790e29db6afdb45c04f5b072c4c20410c7dc9b6772":"298f4fcae1fe271da1e0345d11d07a1fca43f58af4c113b909eedea0":"06f7a56007825433c4c61153df1a135eee2f38ec687b492ed40d9c90":"4c741e4d20103670b7161ae72271082155838418084335338ac38fa4":"db7919151ac28587b72bad7ab180ec8e95ab9e2c8d81d9b9d7e2e383":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-224,SHA-384] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP224:CRYPT_MD_SHA384:"62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd":"25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec":"aac0ea27e129f544abcc77f110e70bbdd5aa3e425dc39d5e8887025d":"10e5dd06aee6b8419a04aa33d9d5678b0039c3acc3c4b61fe106bfdc":"0f0bb1e428bcdebf4dc62a5278068efc0f8ce75f89e89b3630f102b2":"bd6ba605639b98fa8113a16a3bb004ddfaec901c98a931206165f4a5":"a3190b10ef39e88abd60b2293b4707512b45c6c5ed5794cc11454427":2 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-224,SHA-512] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP224:CRYPT_MD_SHA512:"ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6":"7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5":"f83d54945997584c923c09662c34cf9ad1e987da8bfd9be600e7a098":"4ff2dba9dba992c98a095b1144a539310e1a570e20c88b7d0aa1955c":"187ed1f45c466cbafcd4b9577fb222408c011225dcccfd20f08b8d89":"ac635fe00e8b7a3c8ef5655bdfb7f83e8532e59c0cc0b6534d810ffa":"1d067aebeba66e79b28ecfe59ac6fdf5e1970dc3a84499c9d90cd8e2":0 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-256,SHA-224] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP256:CRYPT_MD_SHA224:"708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590":"ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2":"4a19274429e40522234b8785dc25fc524f179dcc95ff09b3c9770fc71f54ca0d":"58982b79a65b7320f5b92d13bdaecdd1259e760f0f718ba933fd098f6f75d4b7":"58f741771620bdc428e91a32d86d230873e9140336fcfb1e122892ee1d501bdc":"29578c7ab6ce0d11493c95d5ea05d299d536801ca9cbd50e9924e43b733b83ab":"08c8049879c6278b2273348474158515accaa38344106ef96803c5a05adc4800":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-256,SHA-256] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP256:CRYPT_MD_SHA256:"519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464":"5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8":"f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac":"8bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903":"94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de":"1ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83":"ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9":0 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-256,SHA-384] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP256:CRYPT_MD_SHA384:"b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced":"e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306":"f5087878e212b703578f5c66f434883f3ef414dc23e2e8d8ab6a8d159ed5ad83":"306b4c6c20213707982dffbb30fba99b96e792163dd59dbe606e734328dd7c8a":"9980b9cdfcef3ab8e219b9827ed6afdd4dbf20bd927e9cd01f15762703487007":"e0e7b99bc62d8dd67883e39ed9fa0657789c5ff556cc1fd8dd1e2a55e9e3f243":"63fbfd0232b95578075c903a4dbf85ad58f8350516e1ec89b0ee1f5e1362da69":2 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-256,SHA-512] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP256:CRYPT_MD_SHA512:"9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499":"6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded":"275fa760878b4dc05e9d157fedfd8e9b1c9c861222a712748cb4b7754c043fb1":"699d906bb8435a05345af3b37e3b357786939e94caae257852f0503adb1e0f7e":"9106192170ccb3c64684d48287bb81bbed51b40d503462c900e5c7aae43e380a":"6b738de3398b6ac57b9591f9d7985dd4f32137ad3460dcf8970c1390cb9eaf8d":"83bc61e26d2bbbd3cf2d2ab445a2bc4ab5dde41f4a13078fd1d3cc36ab596d57":0 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-384,SHA-224] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP384:CRYPT_MD_SHA224:"0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727":"39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938":"c36e5f0d3de71411e6e519f63e0f56cff432330a04fefef2993fdb56343e49f2f7db5fcab7728acc1e33d4692553c02e":"0d4064399d58cd771ab9420d438757f5936c3808e97081e457bc862a0c905295dca60ee94f4537591c6c7d217453909b":"e2f0ce83c5bbef3a6eccd1744f893bb52952475d2531a2854a88ff0aa9b12c65961e2e517fb334ef40e0c0d7a31ed5f5":"00ea9d109dbaa3900461a9236453952b1f1c2a5aa12f6d500ac774acdff84ab7cb71a0f91bcd55aaa57cb8b4fbb3087d":"0fc0e3116c9e94be583b02b21b1eb168d8facf3955279360cbcd86e04ee50751054cfaebcf542538ac113d56ccc38b3e":2 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-384,SHA-256] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP384:CRYPT_MD_SHA256:"c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b":"663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997":"b11db00cdaf53286d4483f38cd02785948477ed7ebc2ad609054551da0ab0359978c61851788aa2ec3267946d440e878":"16007873c5b0604ce68112a8fee973e8e2b6e3319c683a762ff5065a076512d7c98b27e74b7887671048ac027df8cbf2":"c10b5c25c4683d0b7827d0d88697cdc0932496b5299b798c0dd1e7af6cc757ccb30fcd3d36ead4a804877e24f3a32443":"0400193b21f07cd059826e9453d3e96dd145041c97d49ff6b7047f86bb0b0439e909274cb9c282bfab88674c0765bc75":"f70d89c52acbc70468d2c5ae75c76d7f69b76af62dcf95e99eba5dd11adf8f42ec9a425b0c5ec98e2f234a926b82a147":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-384,SHA-384] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP384:CRYPT_MD_SHA384:"201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97":"6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe":"50835a9251bad008106177ef004b091a1e4235cd0da84fff54542b0ed755c1d6f251609d14ecf18f9e1ddfe69b946e32":"0475f3d30c6463b646e8d3bf2455830314611cbde404be518b14464fdb195fdcc92eb222e61f426a4a592c00a6a89721":"dcedabf85978e090f733c6e16646fa34df9ded6e5ce28c6676a00f58a25283db8885e16ce5bf97f917c81e1f25c9c771":"c2b47944fb5de342d03285880177ca5f7d0f2fcad7678cce4229d6e1932fcac11bfc3c3e97d942a3c56bf34123013dbf":"37257906a8223866eda0743c519616a76a758ae58aee81c5fd35fbf3a855b7754a36d4a0672df95d6c44a81cf7620c2d":0 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-384,SHA-512] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP384:CRYPT_MD_SHA512:"217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c":"67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f":"c269d9c4619aafdf5f4b3100211dddb14693abe25551e04f9499c91152a296d7449c08b36f87d1e16e8e15fee4a7f5c8":"77ffed5c61665152d52161dc13ac3fbae5786928a3d736f42d34a9e4d6d4a70a02d5af90fa37a23a318902ae2656c071":"90338a7f6ffce541366ca2987c3b3ca527992d1efcf1dd2723fbd241a24cff19990f2af5fd6419ed2104b4a59b5ae631":"fb937e4a303617b71b6c1a25f2ac786087328a3e26bdef55e52d46ab5e69e5411bf9fc55f5df9994d2bf82e8f39a153e":"a97d9075e92fa5bfe67e6ec18e21cc4d11fde59a68aef72c0e46a28f31a9d60385f41f39da468f4e6c3d3fbac9046765":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-521,SHA-224] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP521:CRYPT_MD_SHA224:"01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46":"58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853":"006b973a638bde22d8c1c0d804d94e40538526093705f92c0c4dac2c72e7db013a9c89ffc5b12a396886305ddf0cbaa7f10cdd4cd8866334c8abfc800e5cca365391":"00b0a01eca07a3964dd27d9ba6f3750615ea36434979dc73e153cd8ed1dbcde2885ead5757ebcabba117a64fcff9b5085d848f107f0c9ecc83dfa2fa09ada3503028":"0141f679033b27ec29219afd8aa123d5e535c227badbe2c86ff6eafa5116e9778000f538579a80ca4739b1675b8ff8b6245347852aa524fe9aad781f9b672e0bb3ff":"01a7596d38aac7868327ddc1ef5e8178cf052b7ebc512828e8a45955d85bef49494d15278198bbcc5454358c12a2af9a3874e7002e1a2f02fcb36ff3e3b4bc0c69e7":"0184902e515982bb225b8c84f245e61b327c08e94d41c07d0b4101a963e02fe52f6a9f33e8b1de2394e0cb74c40790b4e489b5500e6804cabed0fe8c192443d4027b":0 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-521,SHA-256] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP521:CRYPT_MD_SHA256:"01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a":"8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c":"009dd1f2a716843eedec7a6645ac834d4336e7b18e35701f06cae9d6b290d41491424735f3b57e829ad5de055eaeef1778f051c1ee152bf2131a081e53df2a567a8a":"002148e8428d70a72bc9fa986c38c2c97deda0420f222f9dc99d32c0acba699dc7ba0a2b79ce5999ff61bd0b233c744a893bc105bca5c235423e531612da65d72e62":"00dc8daaacddb8fd2ff5c34a5ce183a42261ad3c64dbfc095e58924364dc47ea1c05e2599aae917c2c95f47d6bb37da008af9f55730ddbe4d8ded24f9e8daa46db6a":"007d042ca19408524e68b981f1419351e3b84736c77fe58fee7d11317df2e850d960c7dd10d10ba714c8a609d163502b79d682e8bbecd4f52591d2748533e45a867a":"0197ac6416111ccf987d290459ebc8ad9ec56e49059c992155539a36a626631f4a2d89164b985154f2dddc0281ee5b5178271f3a76a0914c3fcd1f97be8e8376efb3":1 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-521,SHA-384] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP521:CRYPT_MD_SHA384:"0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950":"dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe":"002128f77df66d16a604ffcd1a515e039d49bf6b91a215b814b2a1c88d32039521fbd142f717817b838450229025670d99c1fd5ab18bd965f093cae7accff0675aae":"0008dc65a243700a84619dce14e44ea8557e36631db1a55de15865497dbfd66e76a7471f78e510c04e613ced332aa563432a1017da8b81c146059ccc7930153103a6":"00a8d90686bd1104627836afe698effe22c51aa3b651737a940f2b0f9cd72c594575e550adb142e467a3f631f4429514df8296d8f5144df86faa9e3a8f13939ad5b3":"013b4ab7bc1ddf7fd74ca6f75ac560c94169f435361e74eba1f8e759ac70ab3af138d8807aca3d8e73b5c2eb787f6dcca2718122bd94f08943a686b115d869d3f406":"00f293c1d627b44e7954d0546270665888144a94d437679d074787959d0d944d8223b9d4b5d068b4fbbd1176a004b476810475cd2a200b83eccd226d08b444a71e71":2 + +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001 nist, [P-521,SHA-512] +SDV_CRYPTO_ECDSA_SIGN_VERIFY_FUNC_TC001:CRYPT_ECC_NISTP521:CRYPT_MD_SHA512:"01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6":"b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf":"01a3c4a6386c4fb614fba2cb9e74201e1aaa0001aa931a2a939c92e04b8344535a20f53c6e3c69c75c2e5d2fe3549ed27e6713cb0f4a9a94f6189eb33bff7d453fce":"016a997f81aa0bea2e1469c8c1dab7df02a8b2086ba482c43af04f2174831f2b1761658795adfbdd44190a9b06fe10e578987369f3a2eced147cff89d8c2818f7471":"00bc2c0f37155859303de6fa539a39714e195c37c6ea826e224c8218584ae09cd0d1cc14d94d93f2d83c96e4ef68517fdb3f383da5404e5a426bfc5d424e253c181b":"004d5c8afee038984d2ea96681ec0dccb6b52dfa4ee2e2a77a23c8cf43ef19905a34d6f5d8c5cf0981ed804d89d175b17d1a63522ceb1e785c0f5a1d2f3d15e51352":"0014368b8e746807b2b68f3615cd78d761a464ddd7918fc8df51d225962fdf1e3dc243e265100ff0ec133359e332e44dd49afd8e5f38fe86133573432d33c02fa0a3":0 + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"7fb5f1881188022d9b0a8b808834dfdc0c7388459350983e4aee1412":"661c3e17be24b038b1532d90675747482c238911093fb7035cc9b2cd":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"007a9369e2173bbf29589bf47e3ae0ccf47df6d2268c2292f906cc9261":"011afc53c7c1b085029f53b41fcd5a336bafb35b89d302f2bd04df44e6":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"4946a9935f9e416fdaf8bebdbc2ac454db06c6bba64b9d18b2b4f758":"2a69cc394e21b913244e01a4c45ff00f1b6d0a63ec2a738955cd1714":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"01803faeef9b40957f59ab97d543f86690afd7471dfb8b04b84ea31085":"00738cc29474ca048930b7f1a29db3773d11839ed83a6993e3f23692d7":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"9ec284178ce9605003e67662caaf19049f784fbe20d0bdbfd38e762d":"7f59ec5820f0ac70148ec71000b806a928704ea270254e529e05828b":1:CRYPT_POINT_COMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"c01795a001b6b8a5b3db9acbdb55c2f97f4a50aa0a0cfed1d50a4c28":"b79dbe52a47a4640100cc939b435377f0bcb8db4ec52ecaadac5d919":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"fbe3bff58dc58ca1ef9dc942fd43cdadbd060d70e0b1e6b9583a2228":"ca844b43c237d497c34b986c681bf3cc54f968c0db74b2e1d9fe9d94":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"cbe83c33848dd5a89ea8c45d23b99f23254e2077bd9ab26f6b5bed9f":"c0d09533d78a96e39028162534d74b097364095e2dc60776938af83b":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"491e8d6c73708104c9530878f866e585cba008ef70baa46a809a2c03":"924a28ace8db9a88f7f874a1f24ac7f0bf56484f2130d5be5a8a1721":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"01a89dc6a91002c9d25a3c4621fb5606b52531fd8e48a44119f442f749":"0062f556641faa83059425026ca18ecbd219fe6d5df3b7713ce8b168cd":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"fcaef937ce0075a8adbff9ceb504357313ca150f6c402625832f22f0":"55b249ced1fa80dae295a532b8e54880c9d5b11921f1ab2f64f8da13":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-224], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP224:"0182a4cee32c06292556f4e29950f5b2db9ad627a56e92680358d6cac4":"00fa2a87aa3757ae9fa00d11db57089632c4f9e33fb214b9324cf75bd9":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"e0f7449c5588f24492c338f2bc8f7865f755b958d48edb0f2d0056e50c3fd5b7":"86d7e9255d0f4b6f44fa2cd6f8ba3c0aa828321d6d8cc430ca6284ce1d5b43a0":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"00d17c446237d9df87266ba3a91ff27f45abfdcb77bfd83536e92903efb861a9a9":"01eabb6a349ce2cd447d777b6739c5fc066add2002d2029052c408d0701066231c":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"017875397ae87369365656d490e8ce956911bd97607f2aff41b56f6f3a61989826":"00980a3c4f61b9692633fbba5ef04c9cb546dd05cdec9fa8428b8849670e2fba92":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"f2d1c0dc0852c3d8a2a2500a23a44813ccce1ac4e58444175b440469ffc12273":"32bfe992831b305d8c37b9672df5d29fcb5c29b4a40534683e3ace23d24647dd":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"010b0ca230fff7c04768f4b3d5c75fa9f6c539bea644dffbec5dc796a213061b58":"00f5edf37c11052b75f771b7f9fa050e353e464221fec916684ed45b6fead38205":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"2c1052f25360a15062d204a056274e93cbe8fc4c4e9b9561134ad5c15ce525da":"ced9783713a8a2a09eff366987639c625753295d9a85d0f5325e32dedbcada0b":1:CRYPT_POINT_COMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"a40d077a87dae157d93dcccf3fe3aca9c6479a75aa2669509d2ef05c7de6782f":"503d86b87d743ba20804fd7e7884aa017414a7b5b5963e0d46e3a9611419ddf3":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"2633d398a3807b1895548adbb0ea2495ef4b930f91054891030817df87d4ac0a":"d6b2f738e3873cc8364a2d364038ce7d0798bb092e3dd77cbdae7c263ba618d2":1:CRYPT_POINT_COMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"014bf57f76c260b51ec6bbc72dbd49f02a56eaed070b774dc4bad75a54653c3d56":"7a231a23bf8b3aa31d9600d888a0678677a30e573decd3dc56b33f365cc11236":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"2fa74931ae816b426f484180e517f5050c92decfc8daf756cd91f54d51b302f1":"5b994346137988c58c14ae2152ac2f6ad96d97decb33099bd8a0210114cd1141":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"f8c6dd3181a76aa0e36c2790bba47041acbe7b1e473ff71eee39a824dc595ff0":"9c965f227f281b3072b95b8daf29e88b35284f3574462e268e529bbdc50e9e52":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-256], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP256:"7a81a7e0b015252928d8b36e4ca37e92fdc328eb25c774b4f872693028c4be38":"08862f7335147261e7b1c3d055f9a316e4cab7daf99cc09d1c647f5dd6e7d5bb":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"e87cc868cdf196471d3fc78c324be2c4a0de8dbde182afea88baa51666f3cc9993eae5f1d60d4aec58894f0357273c48":"187219b0adc398c835791798053cc6a0bcc6e43228ac23101ee93dfce0e508be988a55fa495eb93b832064dc035e7720":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"6e9c7e92ee23713fabb05d0b50e088eb534fd1e2b257c03304cfa33598f88a07c7e31a13e24707a7057ca2919323058e":"a218a485e22eae08c3618cfd73befcfcd13c3f196c08df99d7f79ebffe9f127b896aa0cb36cfdf2fc4818b8cd766f185":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"452eb75736ac00974f953a0ce6060c19911a3463b045cb15ad6c0fa5045d66b04252a9001e8c4a9a6a0293f127bd20d9":"a1da4fbf8f0726fb9e04cf3ed0404af6cafb028b924c1951165f0ffe7caf04c05444cc7defb8cb62381727b6c1589f13":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"25e5509a54f5fa62f94551dff3dfe210db1bb2bbc8fd4e672fbd5a211f9fd2f7eadc2b83fcd4198b7f857d9a2dc39c11":"98a4a13bc2f2d04bebd6d4e04412a9d306e57b90364583a6ec25bf6f0175bb5b397b8cfea83fd5d1e0ad052852b4aba7":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"011a14be72dd023667047c260dd1960dd16555289d9570001d53ea3e494c1c107800dc5b24dd4de8490a071658702a0962":"78d65f6975d10df838b96a16cba873b59c28f2c7d05654b8c8b78bd193694ae45d6c6e046a20b984c3467c72d49395fe":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"a953eafd9dae3862d1049dd99cf628745bfb8f1024aaa567c51e9da01eb9bda996a7b1c906b3bb44a94649df2bcef304":"2f66dda137d3a408e2498d532f652e668f09b86bc056ff699efcc71ed1f22967ca7a99c8bf64f246b93c1982f856ed27":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"01bf2238026a2489fb6ac1a8d6b82fdb33b05e8d01f1e2671eb22e61734031cc63efbf7e14d23e81fd432fc9935c627cdd":"6b377c8b187d568b782a28b38a7861b69e3d016f9f9ebb7eff2e7732a5132785b5a32e069dcef12875a995908a8b72f1":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"a999b80932ea62b4689769225b3ff34b0709c4e32342a824799ca63dcce1f3ed8819e080fc7fa130c1881c8131f4bcb5":"b8c77d0868c2c159e1be6bcd60ec488ab31531c21e1cb8fe2493ed26ac848fde7d27823a9a4912650511a3d460e25ef2":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"5cbaa8088b0804fe14c2a6fa54b1adee1690fd17a682ea9ec5202ba7575e217c37e98565b7e95e7c882bb6eef76a3df1":"79d8c7e96ae7a7668496317c596b24ebe56e6ea5bc64b74c38867eb2c419d8277d20b9c27a2d5c75d1c7a47885d38d0e":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"cfb4dbdcb1a8c6e8c6b4a9dd091eed015476ebd20837de1f6261a27999a08cff345f0d4627eb7778fc3495916a6d017b":"01c08f7a421bc0731321374f9b31ecf5ca820c006180da4c496f29f0d0e4947f368808fd3052ee4f1afb8c2005fd0c0ee8":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"1adaff25f37c8dfd33ecf216691a2107e522c21c99e29a76d8c1757ef84cc37c73ec5c2aa3be2fb0d5f1d372e08fbf9e":"01f39c8f86a20c130c34f767e085217232599541516e2d79d8e526fa03082bed2a5dc5fde6fd410c30245212e7816dd014":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-384], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP384:"31951643c18400593f2d7cb32a3acf6071b4d95b8ab80a0535aa5edc9e01145f6dcc91a9977eb450eb077112edf887b2":"098a9e569684ca517bfdd5bc4b57876b210c3d7598e4f989e8f88f9f103b5d90d6baaa1a6617d524001c44a677bd13d0":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"0165252970b786685babd0463f7314275c44ac1b558ab5a8e4bde60a441623b204982dcba2d3c0e7d379d5b637fd3edc0b0d2e0b7a33f7b36c03bb8bf3c6c5469ebe":"01300db0f0bc9b21ecff15eff4ed3bbe3dc1ac403dc96c89344d0030304da7ce57f1dc757af6816279464c61a0ab33645c3cd6583842cff0928081660b30775f594f":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"0089a576c7b31c5848afb9eaeb92bb28ab2fc3bdd58338438051680e4cf0fede6caa63135fb7b6f5d7f2f0743f3d141fd1d67ef55f200d9cfb5fa7ef004929d1b938":"000868b8e12a141d97eb3b8c500eb211d6e70b661665edcadb7a7f989d174fd4ed5d148f6588769122b8ce8a784b3027c5777520a20a368983b01743c27e42c49039":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"01a39c4c5d5f6af8285931694b030f6b8bbc0a012ab73c3947c72a6210643cc63673947f5847f2503bb81ae1c8b6a0d7cb0ee5675f9027ca75445aee2b6d7beb78ea":"0148beebbe6e298779e59d8fc88cfc28f4aa784d927e5127813894b6d593760608539d2eb9db9cc8b39813a5e5e03a7d39be67c9c8a566fa8d65ff25b5bee83b0a9b":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"00f516be607274ad187f6e064eef542f28e93010598575174bed6741c9602a16f05e2a871de673f369c35b01749557c3211c21b77c95d0d2b3451683c36546ae8386":"00277086ba2919d478b0d147543ab823e5dce17b8faa2d9c035ec4db8423f844891e28c8bde0c585b511b3e2a98684deed119c34657d934e9d8400e4d3ddab6f8139":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"00602d4e6955c52cacb2451b8a465d9345703a0a2a723e953156c07524d701f3f5f696c5be70c092210bb163e0d5df75151cf48f7ee0edc360f61cc8a94be560683d":"00eb13acba7b5bc7d32626d6499c5906ac73de240dd7766cef84d53525cb98c4dd852ed8dab8c1b440bacacccb8f2d4024c5e6a3de80840803a0bc11e5750b53c878":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"00bec1326722dd943f750fda964cb485f31469095e5b4b5c4fa02041e2f443693ac36c09f371aea7d501881fc4e369f68e071bb14c5003b31dce504bd14338eb8104":"036cd502b0a4e91e1080a5b94886a819a823687693ce878408b59183730c69e5ab2d6e05ea5f3d32855cf8c7c20da59a28913025a1fa6835a3751ec6da69502f0547":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"03e064e446ce29891240b02948288bedc37a4e4163a78702f942728e2d530cfecdc0362cf2209a706a9d4db24c1dd6aba7ad81d6ddecdf6e12073a1c31e2dacd185d":"012d0363dbdc4d157afd517beaecf2e6c93896a288c7cec5f9ba9394524fb6d4f647a9937fe440fda73f2e31410517ed5a814eed038356699085f9983f2ea5faccd0":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"0164ce2e2fa873f5648c22ed37f26c13d3da3180a0f6c3aa4b68d0a13293784a5f1356fc2495217065de4f3b504ee5218747ef96180e102879363fa5393fe6fc5fbe":"023126d6903cbd7735291d77599cfe7f5e45056250c37deba2642dc0b7163ce0cf763d0d353bb9974cf15195c4bc4421bdae274492cfca739a8b8341235cc2268bc0":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"00dc2c4a23433293a771300ec79a3cd0f2e627110a97da85a82f4f85e7be9c280213048a3ad01b3e72bf54555a1b5da9945adcfed94ed8f6ed405c77506b5e00f45a":"018f746aacd6ed4eaaf9b038789927a30125691bc525b29592abb13cf98f64c03cb36a477dc53971563ee74f3a7614677ab6817f6e5f22ceb02c90826a33fe7c94cd":0:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (2 - Point not on curve) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"016e0383adc2986d01c18d7bde3b89eb5f732b56a6424c9394ec556a4660c3b88ddbc8654345ba6cff94bb002d16bc92e5907035f933785f633698e711738160d842":"01cf24be44e919e1576ecf51abdea113f8bb7121d670b86d8ee93ce1e6f79b17a6394987d74e6787facef5ca655196603468afd76e5cdf54ebb1331ce183cfe28c9e":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], F (1 - Q_x or Q_y out o0range_) +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"03d68ed9ce2bcb68f12ac37385ccdb6ee445f7b0a8f257593735abdf8bc0b98bc5ab5c5750e2e111fec2ecde6be321522ddc90d2b54634d30d28f43024f76e4653a7":"003f6f5f224d6aee43d781e3ad723062a61729a6ed959cd18c75d4982961ba8033767ed1168674a545b0a693d3587fbeaebc9b116143dbe1155ead48de89d980d617":0:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001: nist, [P-521], P +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_NISTP521:"00fa01f87597bb9710346da572a4804ec01c56260c2ce23bc397b3822e5b6f0b75709d58a74e2f7bc8d1021b9c5fccecc3abf2314360bfcf6643593167e6d3641852":"01ead5db7ddd86f2bea66d9b7dfa941ed1409fcdbf7fdd976792a69ccda08c5fdc8e7d392f5921891de5fe6336fde535b468109bba424dba3db926e4d7b1b9cf4cfe":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001 RFC 6932, brainpool p256r1 +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B":1:CRYPT_POINT_COMPRESSED + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001 RFC 6932, brainpool p384r1 +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859":1:CRYPT_POINT_HYBRID + +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001 RFC 6932, brainpool p512r1 +SDV_CRYPTO_ECDSA_SET_PUB_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E":1:CRYPT_POINT_UNCOMPRESSED + +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 Nist, P-224 COMPRESS +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP224:"e7c92383846a4e6887a10498d8eaca2bd0487d985bd7d3f92ce3ab30":"0a3682d2aaa4dd931bee042d32e95755507ab164b12f84843f4b7b96":"a6313a938eff7a293222e0e3c7b4c6132489b33255a61c3fc1ce2256":0 + +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 Nist, P-256 UNCOMPRESS +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP256:"c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357":"d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f":"9681b517b1cda17d0d83d335d9c4a8a9a9b0b1b3c7106d8f3c72bc5093dc275f":1 + +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 Nist, P-384 HYBID +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP384:"5394f7973ea868c52bf3ff8d8ceeb4db90a683653b12485d5f627c3ce5abd8978fc9673d14a71d925747931662493c37":"fd3c84e5689bed270e601b3d80f90d67a9ae451cce890f53e583229ad0e2ee645611fa9936dfa45306ec18066774aa24":"b83ca4126cfc4c4d1d18a4b6c21c7f699d5123dd9c24f66f833846eeb58296196b42ec06425db5b70a4b81b7fcf705a0":2 + +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 Nist, P-512 HYBID +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_NISTP521:"0184258ea667ab99d09d4363b3f51384fc0acd2f3b66258ef31203ed30363fcda7661b6a817daaf831415a1f21cb1cda3a74cc1865f2ef40f683c14174ea72803cff":"019ee818048f86ada6db866b7e49a9b535750c3673cb61bbfe5585c2df263860fe4d8aa8f7486aed5ea2a4d733e346eaefa87ac515c78b9a986ee861584926ce4860":"01b6809c89c0aa7fb057a32acbb9ab4d7b06ba39dba8833b9b54424add2956e95fe48b7fbf60c3df5172bf386f2505f1e1bb2893da3b96d4f5ae78f2544881a238f7":2 +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p256r1 COMPRESS +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP256R1:"041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699":"78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206":"A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B":0 + +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p384r1 HYBID +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP384R1:"014EC0755B78594BA47FB0A56F6173045B4331E74BA1A6F47322E70D79D828D97E095884CA72B73FDABD5910DF0FA76A":"45CB26E4384DAF6FB776885307B9A38B7AD1B5C692E0C32F0125332778F3B8D3F50CA358099B30DEB5EE69A95C058B4E":"8173A1C54AFFA7E781D0E1E1D12C0DC2B74F4DF58E4A4E3AF7026C5D32DC530A2CD89C859BB4B4B768497F49AB8CC859":2 + +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001 RFC 6932, brainpool p512r1 COMPRESS +SDV_CRYPTO_ECDSA_GEN_KEY_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"636B6BE0482A6C1C41AA7AE7B245E983392DB94CECEA2660A379CFE159559E357581825391175FC195D28BAC0CF03A7841A383B95C262B983782874CCE6FE333":"0562E68B9AF7CBFD5565C6B16883B777FF11C199161ECC427A39D17EC2166499389571D6A994977C56AD8252658BA8A1B72AE42F4FB7532151AFC3EF0971CCDA":"A7CA2D8191E21776A89860AFBC1F582FAA308D551C1DC6133AF9F9C3CAD59998D70079548140B90B1F311AFB378AA81F51B275B2BE6B7DEE978EFC7343EA642E":0 + +SDV_CRYPTO_ECDSA_GET_PARA_FUNC_TC001 +SDV_CRYPTO_ECDSA_GET_PARA_FUNC_TC001:"ffffffffffffffffffffffffffffffff000000000000000000000001":"fffffffffffffffffffffffffffffffefffffffffffffffffffffffe":"b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4":"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21":"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34":"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d":"01" + +Ecdsa key pair check: Nist, [P-224,SHA-224], Pass +SDV_CRYPTO_ECDSA_KEY_PAIR_CHECK_FUNC_TC001:CRYPT_ECC_NISTP224:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":CRYPT_POINT_COMPRESSED:1 + +Ecdsa key pair check: Nist, [P-224,SHA-224], Fail +SDV_CRYPTO_ECDSA_KEY_PAIR_CHECK_FUNC_TC001:CRYPT_ECC_NISTP224:"cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5":"605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab":"f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669":CRYPT_POINT_COMPRESSED:0 + + +SDV_CRYPTO_ECDSA_API_TC026 ecdsa key len +SDV_CRYPTO_ECDSA_API_TC026:CRYPT_ECC_NISTP224:57 + +SDV_CRYPTO_ECDSA_API_TC026 ecdsa key len +SDV_CRYPTO_ECDSA_API_TC026:CRYPT_ECC_NISTP256:65 + +SDV_CRYPTO_ECDSA_API_TC026 ecdsa key len +SDV_CRYPTO_ECDSA_API_TC026:CRYPT_ECC_NISTP384:97 + +SDV_CRYPTO_ECDSA_API_TC026 ecdsa key len +SDV_CRYPTO_ECDSA_API_TC026:CRYPT_ECC_NISTP521:133 + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_DSA + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_ED25519 + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_X25519 + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_RSA + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_ECDSA + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_ECDH + +SDV_CRYPTO_ECDSA_API_TC027 pkey check +SDV_CRYPTO_ECDSA_API_TC027:CRYPT_PKEY_SM2 + +SDV_CRYPTO_GETSECURITYBITS_API_TC001 P-224 CRYPT_MD_SHA224 +SDV_CRYPTO_GETSECURITYBITS_API_TC001:CRYPT_ECC_NISTP224:"16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615":112 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/encode/test_suite_sdv_asn1_certkey.c b/testcode/sdv/testcase/crypto/encode/test_suite_sdv_asn1_certkey.c new file mode 100644 index 00000000..d9883117 --- /dev/null +++ b/testcode/sdv/testcase/crypto/encode/test_suite_sdv_asn1_certkey.c @@ -0,0 +1,618 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include + +#include "bsl_sal.h" +#include "bsl_asn1.h" +#include "bsl_err.h" +#include "bsl_log.h" +#include "bsl_init.h" +#include "sal_file.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "crypt_eal_encode.h" +#include "crypt_encode.h" +#include "crypt_util_rand.h" +#include "bsl_obj_internal.h" +#include "crypt_eal_rand.h" + +/* END_HEADER */ + +// clang-format off +/* They are placed in their respective implementations and belong to specific applications, not asn1 modules */ +#define BSL_ASN1_CTX_SPECIFIC_TAG_VER 0 +#define BSL_ASN1_CTX_SPECIFIC_TAG_ISSUERID 1 +#define BSL_ASN1_CTX_SPECIFIC_TAG_SUBJECTID 2 +#define BSL_ASN1_CTX_SPECIFIC_TAG_EXTENSION 3 + +BSL_ASN1_TemplateItem rsaPrvTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* seq */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* version */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* n */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* e */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* p */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* q */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d mod (p-1) */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* d mod (q-1) */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* q^-1 mod p */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 1}, /* OtherPrimeInfos OPTIONAL */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, /* OtherPrimeInfo */ + {BSL_ASN1_TAG_INTEGER, 0, 3}, /* ri */ + {BSL_ASN1_TAG_INTEGER, 0, 3}, /* di */ + {BSL_ASN1_TAG_INTEGER, 0, 3} /* ti */ +}; + +typedef enum { + RSA_PRV_VERSION_IDX = 0, + RSA_PRV_N_IDX = 1, + RSA_PRV_E_IDX = 2, + RSA_PRV_D_IDX = 3, + RSA_PRV_P_IDX = 4, + RSA_PRV_Q_IDX = 5, + RSA_PRV_DP_IDX = 6, + RSA_PRV_DQ_IDX = 7, + RSA_PRV_QINV_IDX = 8, + RSA_PRV_OTHER_PRIME_IDX = 9 +} RSA_PRV_TEMPL_IDX; +// clang-format on + +#define BSL_ASN1_TIME_UTC_1 14 +#define BSL_ASN1_TIME_UTC_2 15 + +#define BSL_ASN1_ID_ANY_1 7 +#define BSL_ASN1_ID_ANY_2 24 +#define BSL_ASN1_ID_ANY_3 34 + +int32_t BSL_ASN1_CertTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + switch (type) { + case BSL_ASN1_TYPE_CHECK_CHOICE_TAG: { + if (idx == BSL_ASN1_TIME_UTC_1 || idx == BSL_ASN1_TIME_UTC_2) { + uint8_t tag = *(uint8_t *)data; + if (tag & BSL_ASN1_TAG_UTCTIME || tag & BSL_ASN1_TAG_GENERALIZEDTIME) { + *(uint8_t *)expVal = tag; + return BSL_SUCCESS; + } + } + return BSL_ASN1_FAIL; + } + case BSL_ASN1_TYPE_GET_ANY_TAG: { + BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data; + BslOidString oidStr = {param->len, (char *)param->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (idx == BSL_ASN1_ID_ANY_1 || idx == BSL_ASN1_ID_ANY_3) { + if (cid == BSL_CID_RSASSAPSS) { + // note: any It can be encoded empty or it can be null + *(uint8_t *)expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + return BSL_SUCCESS; + } else { + *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + } + if (idx == BSL_ASN1_ID_ANY_2) { + if (cid == BSL_CID_EC_PUBLICKEY) { + // note: any It can be encoded empty or it can be null + *(uint8_t *)expVal = BSL_ASN1_TAG_OBJECT_ID; + return BSL_SUCCESS; + } else { // + *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + return BSL_ASN1_FAIL; + } + } + default: + break; + } + return BSL_ASN1_FAIL; +} + +int32_t BSL_ASN1_SubKeyInfoTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + switch (type) { + case BSL_ASN1_TYPE_CHECK_CHOICE_TAG: { + if (idx == BSL_ASN1_TIME_UTC_1 || idx == BSL_ASN1_TIME_UTC_2) { + uint8_t tag = *(uint8_t *)data; + if (tag & BSL_ASN1_TAG_UTCTIME || tag & BSL_ASN1_TAG_GENERALIZEDTIME) { + return BSL_SUCCESS; + } + } + return BSL_ASN1_FAIL; + } + case BSL_ASN1_TYPE_GET_ANY_TAG: { + BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data; + BslOidString oidStr = {param->len, (char *)param->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_EC_PUBLICKEY) { + // note: any It can be encoded empty or it can be null + *(uint8_t *)expVal = BSL_ASN1_TAG_OBJECT_ID; + return BSL_SUCCESS; + } else { // + *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + } + default: + break; + } + return BSL_ASN1_FAIL; +} + +static int32_t ReadCert(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); + 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; + } + + *buff = fileBuff; + *len = (uint32_t)fileLen; + return ret; + } while (0); + BSL_SAL_FREE(fileBuff); + return ret; +} + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para1, void *para2, + void *para3, void *para4) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para1, para2, para3, para4); + printf("\n"); +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para); + printf("\n"); +} + +static void RegisterLogFunc() +{ + BSL_LOG_BinLogFuncs func = {0}; + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + BSL_LOG_RegBinLogFunc(&func); + BSL_GLOBAL_Init(); +} + +static int32_t RandFunc(uint8_t *randNum, uint32_t randLen) +{ + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)rand(); + } + + return 0; +} + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_RSA_PRV_TC001(char *path, Hex *version, Hex *n, Hex *e, Hex *d, Hex *p, Hex *q, Hex *dp, + Hex *dq, Hex *qinv, int mdId, Hex *msg, Hex *sign) +{ + RegisterLogFunc(); + + uint32_t fileLen = 0; + uint8_t *fileBuff = NULL; + int32_t ret = ReadCert(path, &fileBuff, &fileLen); + ASSERT_EQ(ret, BSL_SUCCESS); + uint8_t *rawBuff = fileBuff; + uint8_t *signdata = NULL; + + BSL_ASN1_Buffer asnArr[RSA_PRV_OTHER_PRIME_IDX + 1] = {0}; + BSL_ASN1_Template templ = {rsaPrvTempl, sizeof(rsaPrvTempl) / sizeof(rsaPrvTempl[0])}; + ret = BSL_ASN1_DecodeTemplate(&templ, BSL_ASN1_CertTagGetOrCheck, &fileBuff, &fileLen, asnArr, + RSA_PRV_OTHER_PRIME_IDX + 1); + ASSERT_EQ(ret, BSL_SUCCESS); + ASSERT_EQ(fileLen, 0); + // version + if (version->len != 0) { + ASSERT_EQ_LOG("version compare tag", asnArr[RSA_PRV_VERSION_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("version compare", version->x, version->len, asnArr[RSA_PRV_VERSION_IDX].buff, + asnArr[RSA_PRV_VERSION_IDX].len); + } + + // n + ASSERT_EQ_LOG("n compare tag", asnArr[RSA_PRV_N_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("n compare", n->x, n->len, asnArr[RSA_PRV_N_IDX].buff, asnArr[RSA_PRV_N_IDX].len); + + // e + ASSERT_EQ_LOG("e compare tag", asnArr[RSA_PRV_E_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("e compare", e->x, e->len, asnArr[RSA_PRV_E_IDX].buff, asnArr[RSA_PRV_E_IDX].len); + + // d + ASSERT_EQ_LOG("d compare tag", asnArr[RSA_PRV_D_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("d compare", d->x, d->len, asnArr[RSA_PRV_D_IDX].buff, asnArr[RSA_PRV_D_IDX].len); + // p + ASSERT_EQ_LOG("p compare tag", asnArr[RSA_PRV_P_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("p compare", p->x, p->len, asnArr[RSA_PRV_P_IDX].buff, asnArr[RSA_PRV_P_IDX].len); + // q + ASSERT_EQ_LOG("q compare tag", asnArr[RSA_PRV_Q_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("q compare", q->x, q->len, asnArr[RSA_PRV_Q_IDX].buff, asnArr[RSA_PRV_Q_IDX].len); + // d mod (p-1) + ASSERT_EQ_LOG("dp compare tag", asnArr[RSA_PRV_DP_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("dp compare", dp->x, dp->len, asnArr[RSA_PRV_DP_IDX].buff, asnArr[RSA_PRV_DP_IDX].len); + // d mod (q-1) + ASSERT_EQ_LOG("dq compare tag", asnArr[RSA_PRV_DQ_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("dq compare", dq->x, dq->len, asnArr[RSA_PRV_DQ_IDX].buff, asnArr[RSA_PRV_DQ_IDX].len); + // qinv + ASSERT_EQ_LOG("qinv compare tag", asnArr[RSA_PRV_QINV_IDX].tag, BSL_ASN1_TAG_INTEGER); + ASSERT_COMPARE("qinv compare", qinv->x, qinv->len, asnArr[RSA_PRV_QINV_IDX].buff, asnArr[RSA_PRV_QINV_IDX].len); + + // create + CRYPT_EAL_PkeyPrv rsaPrv = {0}; + rsaPrv.id = CRYPT_PKEY_RSA; + rsaPrv.key.rsaPrv.d = asnArr[RSA_PRV_D_IDX].buff; + rsaPrv.key.rsaPrv.dLen = asnArr[RSA_PRV_D_IDX].len; + rsaPrv.key.rsaPrv.n = asnArr[RSA_PRV_N_IDX].buff; + rsaPrv.key.rsaPrv.nLen = asnArr[RSA_PRV_N_IDX].len; + rsaPrv.key.rsaPrv.e = asnArr[RSA_PRV_E_IDX].buff; + rsaPrv.key.rsaPrv.eLen = asnArr[RSA_PRV_E_IDX].len; + rsaPrv.key.rsaPrv.p = asnArr[RSA_PRV_P_IDX].buff; + rsaPrv.key.rsaPrv.pLen = asnArr[RSA_PRV_P_IDX].len; + rsaPrv.key.rsaPrv.q = asnArr[RSA_PRV_Q_IDX].buff; + rsaPrv.key.rsaPrv.qLen = asnArr[RSA_PRV_Q_IDX].len; + rsaPrv.key.rsaPrv.dP = asnArr[RSA_PRV_DP_IDX].buff; + rsaPrv.key.rsaPrv.dPLen = asnArr[RSA_PRV_DP_IDX].len; + rsaPrv.key.rsaPrv.dQ = asnArr[RSA_PRV_DQ_IDX].buff; + rsaPrv.key.rsaPrv.dQLen = asnArr[RSA_PRV_DQ_IDX].len; + rsaPrv.key.rsaPrv.qInv = asnArr[RSA_PRV_QINV_IDX].buff; + rsaPrv.key.rsaPrv.qInvLen = asnArr[RSA_PRV_QINV_IDX].len; + + CRYPT_EAL_PkeyCtx *pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &rsaPrv), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, sizeof(CRYPT_RSA_PkcsV15Para)), 0); + + /* Malloc signature buffer */ + uint32_t signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + signdata = (uint8_t *)BSL_SAL_Malloc(signLen); + ASSERT_TRUE(signdata != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + ASSERT_COMPARE("CRYPT_EAL_PkeySign Compare", sign->x, sign->len, signdata, signLen); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(signdata); + BSL_SAL_FREE(rawBuff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001(char *path, int fileType, int mdId, Hex *msg, Hex *sign) +{ + RegisterLogFunc(); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + if (fileType == CRYPT_PUBKEY_RSA) { + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, sizeof(CRYPT_RSA_PkcsV15Para)), + 0); + } + + /* verify signature */ + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkeyCtx, mdId, msg->x, msg->len, sign->x, sign->len), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001(int encodeType, Hex *subKeyInfo) +{ + RegisterLogFunc(); + (void)encodeType; + CRYPT_EAL_PkeyCtx *pctx = NULL; + ASSERT_EQ(CRYPT_EAL_ParseAsn1SubPubkey(subKeyInfo->x, subKeyInfo->len, (void **)&pctx, false), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pctx); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001(char *path, int fileType, int mdId, Hex *msg, Hex *sign) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + uint8_t *signdata = NULL; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + if (fileType == CRYPT_PRIKEY_RSA || CRYPT_EAL_PkeyGetId(pkeyCtx) == CRYPT_PKEY_RSA) { + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, sizeof(CRYPT_RSA_PkcsV15Para)), + 0); + } + + /* Malloc signature buffer */ + uint32_t signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + signdata = (uint8_t *)BSL_SAL_Malloc(signLen); + ASSERT_TRUE(signdata != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + + if (sign->len != 0) { + ASSERT_COMPARE("Signature Compare", sign->x, sign->len, signdata, signLen); + } + +exit: + BSL_SAL_Free(signdata); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001(char *path, int fileType, int mdId, Hex *msg, int alg, + Hex *rawKey, int paraId) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + uint8_t rawPriKey[100] = {0}; + uint32_t rawPriKeyLen = 100; + uint8_t *signdata = NULL; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + CRYPT_EAL_PkeyPrv pkeyPrv = {0}; + pkeyPrv.id = alg; + pkeyPrv.key.eccPrv.data = rawPriKey; + pkeyPrv.key.eccPrv.len = rawPriKeyLen; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkeyCtx, &pkeyPrv), CRYPT_SUCCESS); + ASSERT_COMPARE("key cmp", rawKey->x, rawKey->len, rawPriKey, rawKey->len); + ASSERT_EQ(CRYPT_EAL_PkeyGetId(pkeyCtx), alg); + if (alg != CRYPT_PKEY_SM2) { // sm2 is null + ASSERT_EQ(CRYPT_EAL_PkeyGetParaId(pkeyCtx), paraId); + } + /* Malloc signature buffer */ + uint32_t signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + signdata = (uint8_t *)BSL_SAL_Malloc(signLen); + ASSERT_TRUE(signdata != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + +exit: + BSL_SAL_Free(signdata); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_ENCPK8_TC001(char *path, int fileType, Hex *pass, int mdId, Hex *msg, Hex *sign) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + uint8_t *signdata = NULL; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, fileType, path, pass->x, pass->len, &pkeyCtx), + CRYPT_SUCCESS); + if (fileType == CRYPT_PRIKEY_RSA || CRYPT_EAL_PkeyGetId(pkeyCtx) == CRYPT_PKEY_RSA) { + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, sizeof(CRYPT_RSA_PkcsV15Para)), + 0); + } + + /* Malloc signature buffer */ + uint32_t signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + signdata = (uint8_t *)BSL_SAL_Malloc(signLen); + ASSERT_TRUE(signdata != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + + if (sign->len != 0) { + ASSERT_COMPARE("Signature Compare", sign->x, sign->len, signdata, signLen); + } + +exit: + BSL_SAL_Free(signdata); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_PARSE_BUFF_TC001(int type, Hex *pass, Hex *data) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_ASN1, type, (BSL_Buffer *)data, + pass->x, pass->len, &pkeyCtx), CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001(char *path, int fileType, int isComplete, Hex *asn1) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + BSL_Buffer encodeAsn1 = {0}; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_UNKNOWN, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodePubKeyBuffInternal(pkeyCtx, BSL_FORMAT_ASN1, + fileType, isComplete, &encodeAsn1), CRYPT_SUCCESS); + + ASSERT_COMPARE("asn1 compare.", encodeAsn1.data, encodeAsn1.dataLen, asn1->x, asn1->len); +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(encodeAsn1.data); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_PEM_ENCODE_PUBKEY_BUFF_TC001(char *path, int fileType, int isComplete, char *pemPath) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + BSL_Buffer encodePem = {0}; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_UNKNOWN, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodePubKeyBuffInternal(pkeyCtx, BSL_FORMAT_PEM, + fileType, isComplete, &encodePem), CRYPT_SUCCESS); + + uint8_t *pem = NULL; + uint32_t pemLen = 0; + ASSERT_EQ(BSL_SAL_ReadFile(pemPath, &pem, &pemLen), CRYPT_SUCCESS); + ASSERT_COMPARE("pem compare.", encodePem.data, encodePem.dataLen, pem, pemLen); +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(encodePem.data); + BSL_SAL_FREE(pem); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001(char *path, int fileType, Hex *asn1) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + BSL_Buffer encodeAsn1 = {0}; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_UNKNOWN, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodeBuffKey(pkeyCtx, NULL, BSL_FORMAT_ASN1, fileType, &encodeAsn1), CRYPT_SUCCESS); + ASSERT_COMPARE("asn1 compare.", encodeAsn1.data, encodeAsn1.dataLen, asn1->x, asn1->len); +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(encodeAsn1.data); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001(char *path, int fileType, int hmacId, int symId, int saltLen, + Hex *pwd, int itCnt, Hex *asn1) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + BSL_Buffer encodeAsn1 = {0}; + BSL_Buffer encodeAsn1Out = {0}; + CRYPT_Pbkdf2Param param = {0}; + param.pbesId = BSL_CID_PBES2; + param.pbkdfId = BSL_CID_PBKDF2; + param.hmacId = hmacId; + param.symId = symId; + param.pwd = pwd->x; + param.saltLen = saltLen; + param.pwdLen = pwd->len; + param.itCnt = itCnt; + CRYPT_EncodeParam paramEx = {CRYPT_DERIVE_PBKDF2, ¶m}; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_UNKNOWN, fileType, path, pwd->x, pwd->len, &pkeyCtx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodeBuffKey(pkeyCtx, ¶mEx, BSL_FORMAT_ASN1, fileType, &encodeAsn1), CRYPT_SUCCESS); + CRYPT_EAL_PkeyCtx *decodeCtx = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_ASN1, fileType, &encodeAsn1, pwd->x, pwd->len, &decodeCtx), + CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodeBuffKey(decodeCtx, NULL, BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_UNENCRYPT, &encodeAsn1Out), + CRYPT_SUCCESS); + ASSERT_COMPARE("asn1 compare.", encodeAsn1Out.data, encodeAsn1Out.dataLen, asn1->x, asn1->len); + CRYPT_EAL_RandDeinit(); +exit: + CRYPT_EAL_PkeyFreeCtx(decodeCtx); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(encodeAsn1.data); + BSL_SAL_FREE(encodeAsn1Out.data); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001(char *path, int fileType, int saltLen, int mdId, int mgfId, Hex *asn1) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + BSL_Buffer encodeAsn1 = {0}; + CRYPT_RSA_PssPara rsaPssParam = {saltLen, mdId, mgfId}; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_UNKNOWN, fileType, path, NULL, 0, &pkeyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &rsaPssParam, sizeof(rsaPssParam)), + CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodeBuffKey(pkeyCtx, NULL, BSL_FORMAT_ASN1, fileType, &encodeAsn1), CRYPT_SUCCESS); + ASSERT_COMPARE("asn1 compare.", encodeAsn1.data, encodeAsn1.dataLen, asn1->x, asn1->len); +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(encodeAsn1.data); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_BSL_ASN1_ENCODE_RSAPSS_PUBLICKEY_BUFF_TC001(char *path, Hex *asn1) +{ + RegisterLogFunc(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + BSL_Buffer encodeAsn1 = {0}; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_UNKNOWN, CRYPT_PUBKEY_SUBKEY, path, NULL, 0, &pkeyCtx), + CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_EncodeBuffKey(pkeyCtx, NULL, BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY, &encodeAsn1), CRYPT_SUCCESS); + ASSERT_COMPARE("asn1 compare.", encodeAsn1.data, encodeAsn1.dataLen, asn1->x, asn1->len); +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + BSL_SAL_FREE(encodeAsn1.data); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/encode/test_suite_sdv_asn1_certkey.data b/testcode/sdv/testcase/crypto/encode/test_suite_sdv_asn1_certkey.data new file mode 100644 index 00000000..ae45d186 --- /dev/null +++ b/testcode/sdv/testcase/crypto/encode/test_suite_sdv_asn1_certkey.data @@ -0,0 +1,179 @@ +SDV_BSL_ASN1_PARSE_RSA_PRV_TC001 parse rsa pkcs1 +SDV_BSL_ASN1_PARSE_RSA_PRV_TC001:"../testdata/cert/asn1/rsa2048key_pkcs1.der":"00":"00a54e1b3861b07e97d99f1746cb0fd4b626e69b8d2c6332492de37429ede5c8910211dd2031e67c7404fa58d97e3df21468af6a92fa60a86a042058d47a19fdea653ce2133ebfa0f6bf2ef2df20dfbdd0ded3cf79de8e1cc1a748af9f7d435a4a08b0579d1a2fdcb7f0e4a4770fb6860d22a8b03709ef80811592a792ea7d58185725d78787f05f83210b42b012b6557ebdb8fe46c6f3f5a78b26840cd951d89681180cc817307eb673edd3e699508456c834112e7e9f121376e5f5060635a9660f50dd938ccd643a61d3cfcd3e1d4c1d751576f029e88a522237d25a7376ab1b8133b75caed8389339613fd39387170137c589a2c5bbafb5b9ab0c48804d2e21":"010001":"49d5512325bf074c1bcf8b3dfb84dea55d4ab33fa30bcb721424fbc59e947bb9090ba190b7b912ed5f2bd27392876890e51134b0e1543ae4df62f34a341f57e251c597d4b0ba36d2ff21a129382db7428bc45f6f379092178cf852391261fafa06577d4a965fba5e0e2291b2fc39b2363bbcccb8489fc8eddf0cd9fc2cf03f602715761c4d272edadbf3d49c947b378b580f04998e7578f9aa4ebb1a9b1c9abe8f093e497e86942a6145c677f35e9542e3a4c7d473dbf91234e13bbf24c950c5b98dacc46d07bf65f9d45329c86eddc18d74f753c2fb466f59fced9f634e8cecaa2e8eb3a011bf257748f37440f850e50c833e3beed0c84aa3b23510f110bf61":"00e3b6ecd39561b6aef8fc8eecffbcba7678b841ecc99cc6f595f85bde95178d1a309cad85c2f8cc127b45f70384ded7782b1a7fa5377a5d1c94a2aee016c62fbf6d376f4248e931c5306a9a2c1eee1035c1913f6111936f30c106b5c54de5002d2e09d315e6149cf7eeb5466d6c1dfae3f9276503f9d9d7298a29c4af2270df1f":"00b9d6a0f1e84fddc62397567eeb4e93c4c1de69941a744ae5fb8b29917de2a5ec0835d9d01ad897b22064e8bb1d33d237bd90f7ac7011a228ed25ac6ed567972f2efa61a2b028eef6444800aecdab93a309b9c499d9715bf6e85365cc335ebb46472be9b6f2b21fa2ee78f23796c109f24f20767c66529103947dc658e0308abf":"00a090848f70beb4b4cde62fd59741f96cbe14968fa35dc3c0b95da551de68fbdaa2ba6774711543b8286a1e11c227eb60d56bdae3a1a9cb6bf2b67f7e8d3073cc93f349a5408a05c91829a2ca4788efaf27ed05f6a910ff8f2e1c50216e9a71b469c90da95c51de98c81dd42a25d941e66bf1c63db6784f4a001d118db848445b":"06d9d2b5184b5971a47e3fc20e0aa787e95db9a6ac12fd6fdd06145238c1d23c11516ae631172b007611424323a0756f789d8f83dbddca8c97b17bd9da24277ea5ccb52cba31c81d6c06fb7f76358d0bc5a0038f6864b56f34c15e4f58d57531f20dbc5ff2327ed812d2829b6a0353ca8b00375dfea7ac90e5387dc768fc6121":"00900dcd99b19d9dbfcf7da489fcb856fd218eaa3e17303802f7105a766a98c663937020963836b8c228da3099302a5497606b72a1d6dd062332d90f1369acca755c0352623cac276e9537a80c0e4e8644ff8ed44dc4466fc2d7c925f5badef657776e4b7e7c0cc26fa82736f469dda248e6f3d3a4e8d03a02f6ec78e08439ce84":CRYPT_MD_SHA256:"00010203040506070809":"2a4054ff8a8fbc4d035cbcda43a114db28b19a5190d58a794600d898e6d396ebef5af7ee91764cea4c1d65c0581950bf7463da1dc0b844c0f7439f2f2583f386609157e9a9a3a57a5cae537f418435275d745dd2b5c4c871571d99711ef1baf640be1743c7ada6c28113ebdf1f5171d54b2f83707e159d2dbecfa26a3c7a9a9dcfc83b6cba1bb8db0d55a5f1875fb7e2b21d58da1f8ebe128e979008800361a770745fadafc9cfd62bc1b4424d3fdeec531621d52cb231c69790dc7a1be5393d7b3417b0a88a93fc472eb718f7ed7800c537f1c55adc5f22f963bb199dfefa4fc1ff27510442e2e86526eaa29773e2560ab2c3bfe6a56ff7b7c72dff78a00fad" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse rsa2048 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/rsa2048pub_pkcs1.der":CRYPT_PUBKEY_RSA:CRYPT_MD_SHA256:"00010203040506070809":"2a4054ff8a8fbc4d035cbcda43a114db28b19a5190d58a794600d898e6d396ebef5af7ee91764cea4c1d65c0581950bf7463da1dc0b844c0f7439f2f2583f386609157e9a9a3a57a5cae537f418435275d745dd2b5c4c871571d99711ef1baf640be1743c7ada6c28113ebdf1f5171d54b2f83707e159d2dbecfa26a3c7a9a9dcfc83b6cba1bb8db0d55a5f1875fb7e2b21d58da1f8ebe128e979008800361a770745fadafc9cfd62bc1b4424d3fdeec531621d52cb231c69790dc7a1be5393d7b3417b0a88a93fc472eb718f7ed7800c537f1c55adc5f22f963bb199dfefa4fc1ff27510442e2e86526eaa29773e2560ab2c3bfe6a56ff7b7c72dff78a00fad" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse rsa3072 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/rsa3072pub_pkcs1.der":CRYPT_PUBKEY_RSA:CRYPT_MD_SHA256:"00010203040506070809":"24a9b351774bfd2ba4d1c8ddaad351880fef4fae8c63e69b8121923890049185504f74123e54e1c4d9d559c924e9fb8fd167485689a5dff2632230b2c3c2dcac1953514458be3a79f57518f6176d10424cece98f850aa79716371aa374288d76819f97c502729b69f973220ae9315b956aeb4c14ad430bafd569219f25291ad28826247566ee14169ff498bcc9ac834be1c8f8c7c0e9117a7a198ebd96da2afd11fbd911f62bd4c37ee967f0608c18fecc9bf4abe7b5012f36045e422686951fa0ba9cd17a40bf3b0bdeea4bdd798975cd107f4488ed6858714372b35e520bd9bf09d11b63cde8bfb56361b8e2379652d66e33aa6f30ad3b03abab54f0ef191e278a4b8777011bcd7af9de29067c1396ba85120df640d668811c90c63b096c56e4f1daf46fc4a75db3e7dbcb80b0b7a90a813dbf15d39e3d3b4e42111cea2bdcb026ea887b8c90fc4b50634c72a7e58d86c028a3ee296f1c14ba29c9c74c352fd9b31fc81d488d38f785e21aecc7ec80eba352abd8ddde7b93e3a34880a13bfe" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse rsa4096 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/rsa4096pub_pkcs1.der":CRYPT_PUBKEY_RSA:CRYPT_MD_SHA256:"00010203040506070809":"52b83ba5f352aaa2bdcce579f55bc3665f7794169198c49ffcc3a8a6ad220e480b20010e2bbdbb66e5df08a9b54bc10af33c03b39a81bec743dd48ac281f8037e071fd800b9d429ec2f0c029a35fd65d8c6adc884cd7bae1bf0dc10631a7c8968a4e5cb29774b803a5fbd62a3386183b6faee7c4b0cf409c88f349073ae47d92cd8b70b1e9c8f12219869d7fc5e330d98bd825933cb63739d95f8c1ced7f9aa3da20caa9bb07bbc9acaad29805960350a7df3b5d45c9a9bef99efb49f926da543336fbc680868efae2f9cd36c3be6dec7ae3a27038a445753adeae0f12245d2654b882fbd40255b56019865f7db30d2c14e25710ef12025de18d26b54ea474e36116cba2a2f929d210cee259802ee9555f26e30f0f92b2db3871e840dc7fd999cfe255ff313cbfaa81325549e56bff4fbcefd3981a810554d421bf428c210b5958a80127a7ff7a7cbd2a9d1899b620faa7a3fc4de62c816d81d6521a86406c3b4e3d24ab2dec26385b8c4ac73d8719c6bd642242386f52aab92426e90be8cb53a343e341963e0ce421b90d635cffff6733dc0c5d97809eafbf0c5a6f231a51f5c67e598b1ee8b9ab9ab0260647038bd89b77694aa09ba8b7cefd9d78722ed9213a11a9c38c8d1894002e3e7fbae36e6229b758866af72b10b93f8cc8c85101d57a3c7ef57cc3cb80837041742cd97a20388378cd662ece1cca37dabe06d1db65" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse prime256v1 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/prime256v1pub.der":CRYPT_PUBKEY_SUBKEY:CRYPT_MD_SHA256:"00010203040506070809":"304402207e82bdc8d6e0ab55aa1c989867afd473bb057e48213b33d368105cd87f65027b022018c4ce1dfa13bf89b555c4fbf3e5a19bfbf6b14d33b2fd34991541283e4badca" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse secp384r1 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/secp384r1pub.der":CRYPT_PUBKEY_SUBKEY:CRYPT_MD_SHA256:"00010203040506070809":"3065023071d0f5a933be677b6abe7b736d9f389c7c35f5387e4c3fde75abf6e7c946653431fa9ea8e30a58f8ac4a068b88ac0689023100d31c6ecdbeab9b1db9eae28032fbc99d66ed5b69ff393df5e625f503a34c9de43f43a74627e6d3dfd7d0e66eda7aec34" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse secp521r1 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/secp521r1pub.der":CRYPT_PUBKEY_SUBKEY:CRYPT_MD_SHA256:"00010203040506070809":"30818702417c3fc2e31636b9f8ea192a1d0d1db1d382fe2d3e351d69a2a1c3a59f5943e2985cc2734e951229118ffe6fc2c17c4e174ca670138d92b7977c268c0f924a0f07ce024201d4d8d8c6ee1ee519e8cb828d0e672b8462bf9eb275d67423853f504423b594aa69f73bb847890ee33877bb4a032bf6927377bbfc7143dd83b51e103e13ef201c30" + +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001 parse sm2 pubkey file and verify signature +SDV_BSL_ASN1_PARSE_PUBKEY_FILE_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2pub_pkcs1.der":CRYPT_PUBKEY_SUBKEY:CRYPT_MD_SM3:"00010203040506070809":"30440220333dab877c3ecba400f17bc54ce16d80aab54a8cb6dc948f73fb55e5e7b06e8102205a9f71db493f51aaa175d8c3a5fda3fbce7aac9ab7deddb15cd3944e6702fb66" + +SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001 parse ECDSA P384 +SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001:CRYPT_PUBKEY_SUBKEY:"301006072a8648ce3d020106052b8104002203620004a12213c48aad4daffe8a7ac6c6fa8f6883f4a768383de9aa602dfcaa0aa3143d54aa8e2c1650a25b18ac9c78e33fea4f41f63db0fbf7263242f0b924ee09f37e96cc34bbfb7859e578878e6561c771002047d59c088fadfd0e8403914ab580c1" + +SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001 parse rsa 2048 +SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001:CRYPT_PUBKEY_SUBKEY:"300b06092a864886f70d01010a0382010f003082010a0282010100c7aa3aeaa5b9996bc61720bc67f0f092a0429240bce8175f88caf8c097f5c775381c0284f2347d8cd111a2c541c058b26d04c4064d11128ddf7ea1be7340fb09adc74e1a57add94f03c8242cb3207431a96fa0e827ce1ac4cabb8f0fdb105464aaa9be849b5e64d4b9eaa9f230577ffc66846c340deaec3784d0306c3cbe33de06657775a7d3a46119d5be6b9579ddb14e60c197fb621371e3b3304ff53ceb69f9f985065cd0c53b9d738e38a39d6c7a6215e5b403a77247903f643f3c348424107267a200f94a497fd897a0d16fa2fc1139514b9130f984f999e494d992d1368c640f2b0618aa6d252a483d9dc577e795c8d599cbe2ff477a73b4dbc799505f0203010001" + +SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001 parse SM2 +SDV_BSL_ASN1_PARSE_SUBPUBKEY_TC001:CRYPT_PUBKEY_SUBKEY:"301306072A8648CE3D020106082A811CCF5501822D03420004B5E144EA96A23365DC0E4AB8683826275D262DFA368D7C6E4CA4838507365CA9F80DEC6DAA4DC431326F310F25756B34FA0804B2C89443C888CA17A99C2BC4CE" + +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001 parse rsa2048 prikey file and sign data +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001:"../testdata/cert/asn1/rsa2048key_pkcs1.der":CRYPT_PRIKEY_RSA:CRYPT_MD_SHA256:"00010203040506070809":"2a4054ff8a8fbc4d035cbcda43a114db28b19a5190d58a794600d898e6d396ebef5af7ee91764cea4c1d65c0581950bf7463da1dc0b844c0f7439f2f2583f386609157e9a9a3a57a5cae537f418435275d745dd2b5c4c871571d99711ef1baf640be1743c7ada6c28113ebdf1f5171d54b2f83707e159d2dbecfa26a3c7a9a9dcfc83b6cba1bb8db0d55a5f1875fb7e2b21d58da1f8ebe128e979008800361a770745fadafc9cfd62bc1b4424d3fdeec531621d52cb231c69790dc7a1be5393d7b3417b0a88a93fc472eb718f7ed7800c537f1c55adc5f22f963bb199dfefa4fc1ff27510442e2e86526eaa29773e2560ab2c3bfe6a56ff7b7c72dff78a00fad" + +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001 parse rsa3072 prikey file and sign data +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001:"../testdata/cert/asn1/rsa3072key_pkcs1.der":CRYPT_PRIKEY_RSA:CRYPT_MD_SHA256:"00010203040506070809":"24a9b351774bfd2ba4d1c8ddaad351880fef4fae8c63e69b8121923890049185504f74123e54e1c4d9d559c924e9fb8fd167485689a5dff2632230b2c3c2dcac1953514458be3a79f57518f6176d10424cece98f850aa79716371aa374288d76819f97c502729b69f973220ae9315b956aeb4c14ad430bafd569219f25291ad28826247566ee14169ff498bcc9ac834be1c8f8c7c0e9117a7a198ebd96da2afd11fbd911f62bd4c37ee967f0608c18fecc9bf4abe7b5012f36045e422686951fa0ba9cd17a40bf3b0bdeea4bdd798975cd107f4488ed6858714372b35e520bd9bf09d11b63cde8bfb56361b8e2379652d66e33aa6f30ad3b03abab54f0ef191e278a4b8777011bcd7af9de29067c1396ba85120df640d668811c90c63b096c56e4f1daf46fc4a75db3e7dbcb80b0b7a90a813dbf15d39e3d3b4e42111cea2bdcb026ea887b8c90fc4b50634c72a7e58d86c028a3ee296f1c14ba29c9c74c352fd9b31fc81d488d38f785e21aecc7ec80eba352abd8ddde7b93e3a34880a13bfe" + +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001 parse rsa4096 prikey file and sign data +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001:"../testdata/cert/asn1/rsa4096key_pkcs1.der":CRYPT_PRIKEY_RSA:CRYPT_MD_SHA256:"00010203040506070809":"52b83ba5f352aaa2bdcce579f55bc3665f7794169198c49ffcc3a8a6ad220e480b20010e2bbdbb66e5df08a9b54bc10af33c03b39a81bec743dd48ac281f8037e071fd800b9d429ec2f0c029a35fd65d8c6adc884cd7bae1bf0dc10631a7c8968a4e5cb29774b803a5fbd62a3386183b6faee7c4b0cf409c88f349073ae47d92cd8b70b1e9c8f12219869d7fc5e330d98bd825933cb63739d95f8c1ced7f9aa3da20caa9bb07bbc9acaad29805960350a7df3b5d45c9a9bef99efb49f926da543336fbc680868efae2f9cd36c3be6dec7ae3a27038a445753adeae0f12245d2654b882fbd40255b56019865f7db30d2c14e25710ef12025de18d26b54ea474e36116cba2a2f929d210cee259802ee9555f26e30f0f92b2db3871e840dc7fd999cfe255ff313cbfaa81325549e56bff4fbcefd3981a810554d421bf428c210b5958a80127a7ff7a7cbd2a9d1899b620faa7a3fc4de62c816d81d6521a86406c3b4e3d24ab2dec26385b8c4ac73d8719c6bd642242386f52aab92426e90be8cb53a343e341963e0ce421b90d635cffff6733dc0c5d97809eafbf0c5a6f231a51f5c67e598b1ee8b9ab9ab0260647038bd89b77694aa09ba8b7cefd9d78722ed9213a11a9c38c8d1894002e3e7fbae36e6229b758866af72b10b93f8cc8c85101d57a3c7ef57cc3cb80837041742cd97a20388378cd662ece1cca37dabe06d1db65" + +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001 parse rsa2048 pkcs8 prikey file and sign data +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001:"../testdata/cert/asn1/rsa2048key_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"00010203040506070809":"2a4054ff8a8fbc4d035cbcda43a114db28b19a5190d58a794600d898e6d396ebef5af7ee91764cea4c1d65c0581950bf7463da1dc0b844c0f7439f2f2583f386609157e9a9a3a57a5cae537f418435275d745dd2b5c4c871571d99711ef1baf640be1743c7ada6c28113ebdf1f5171d54b2f83707e159d2dbecfa26a3c7a9a9dcfc83b6cba1bb8db0d55a5f1875fb7e2b21d58da1f8ebe128e979008800361a770745fadafc9cfd62bc1b4424d3fdeec531621d52cb231c69790dc7a1be5393d7b3417b0a88a93fc472eb718f7ed7800c537f1c55adc5f22f963bb199dfefa4fc1ff27510442e2e86526eaa29773e2560ab2c3bfe6a56ff7b7c72dff78a00fad" + +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001 parse rsa3072 pkcs8 prikey file and sign data +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001:"../testdata/cert/asn1/rsa3072key_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"00010203040506070809":"24a9b351774bfd2ba4d1c8ddaad351880fef4fae8c63e69b8121923890049185504f74123e54e1c4d9d559c924e9fb8fd167485689a5dff2632230b2c3c2dcac1953514458be3a79f57518f6176d10424cece98f850aa79716371aa374288d76819f97c502729b69f973220ae9315b956aeb4c14ad430bafd569219f25291ad28826247566ee14169ff498bcc9ac834be1c8f8c7c0e9117a7a198ebd96da2afd11fbd911f62bd4c37ee967f0608c18fecc9bf4abe7b5012f36045e422686951fa0ba9cd17a40bf3b0bdeea4bdd798975cd107f4488ed6858714372b35e520bd9bf09d11b63cde8bfb56361b8e2379652d66e33aa6f30ad3b03abab54f0ef191e278a4b8777011bcd7af9de29067c1396ba85120df640d668811c90c63b096c56e4f1daf46fc4a75db3e7dbcb80b0b7a90a813dbf15d39e3d3b4e42111cea2bdcb026ea887b8c90fc4b50634c72a7e58d86c028a3ee296f1c14ba29c9c74c352fd9b31fc81d488d38f785e21aecc7ec80eba352abd8ddde7b93e3a34880a13bfe" + +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001 parse rsa4096 pkcs8 prikey file and sign data +SDV_BSL_ASN1_PARSE_PRIKEY_FILE_TC001:"../testdata/cert/asn1/rsa4096key_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"00010203040506070809":"52b83ba5f352aaa2bdcce579f55bc3665f7794169198c49ffcc3a8a6ad220e480b20010e2bbdbb66e5df08a9b54bc10af33c03b39a81bec743dd48ac281f8037e071fd800b9d429ec2f0c029a35fd65d8c6adc884cd7bae1bf0dc10631a7c8968a4e5cb29774b803a5fbd62a3386183b6faee7c4b0cf409c88f349073ae47d92cd8b70b1e9c8f12219869d7fc5e330d98bd825933cb63739d95f8c1ced7f9aa3da20caa9bb07bbc9acaad29805960350a7df3b5d45c9a9bef99efb49f926da543336fbc680868efae2f9cd36c3be6dec7ae3a27038a445753adeae0f12245d2654b882fbd40255b56019865f7db30d2c14e25710ef12025de18d26b54ea474e36116cba2a2f929d210cee259802ee9555f26e30f0f92b2db3871e840dc7fd999cfe255ff313cbfaa81325549e56bff4fbcefd3981a810554d421bf428c210b5958a80127a7ff7a7cbd2a9d1899b620faa7a3fc4de62c816d81d6521a86406c3b4e3d24ab2dec26385b8c4ac73d8719c6bd642242386f52aab92426e90be8cb53a343e341963e0ce421b90d635cffff6733dc0c5d97809eafbf0c5a6f231a51f5c67e598b1ee8b9ab9ab0260647038bd89b77694aa09ba8b7cefd9d78722ed9213a11a9c38c8d1894002e3e7fbae36e6229b758866af72b10b93f8cc8c85101d57a3c7ef57cc3cb80837041742cd97a20388378cd662ece1cca37dabe06d1db65" + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse prime256v1 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/prime256v1.der":CRYPT_PRIKEY_ECC:CRYPT_MD_SHA256:"00010203040506070809":CRYPT_PKEY_ECDSA:"069db63c9e8012972c7f71bcd0ef1f6e23edc9f73ec68d49748c2159af25933b":CRYPT_ECC_NISTP256 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse secp384r1 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/secp384r1.der":CRYPT_PRIKEY_ECC:CRYPT_MD_SHA256:"00010203040506070809":CRYPT_PKEY_ECDSA:"11f1ad7fd68d2bdc0fe972b521d6416b1c2d0d6ea82875b1ae97b05be297d9e7990db33f08882fdee4a285c1d87472c8":CRYPT_ECC_NISTP384 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse secp521r1 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/secp521r1.der":CRYPT_PRIKEY_ECC:CRYPT_MD_SHA256:"00010203040506070809":CRYPT_PKEY_ECDSA:"01ca8409961a7ae942d2a65f0abc9fbdd23e55b9a9e1d9bed72c9e91f2e62ceb431fa2788c10b32e412f9a9412c4d2b436fa396a7bd1b5e7b143aa426dddfe27d438":CRYPT_ECC_NISTP521 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse sm2 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2_pkcs1.der":CRYPT_PRIKEY_ECC:CRYPT_MD_SM3:"00010203040506070809":CRYPT_PKEY_SM2:"c5983f142e49d2e2f2c55e216ac7a32803df0a0c5eb5134238e16204579cbea0":CRYPT_ECC_SM2 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse prime256v1 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/prime256v1_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"00010203040506070809":CRYPT_PKEY_ECDSA:"069db63c9e8012972c7f71bcd0ef1f6e23edc9f73ec68d49748c2159af25933b":CRYPT_ECC_NISTP256 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse secp384r1 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/secp384r1_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"00010203040506070809":CRYPT_PKEY_ECDSA:"11f1ad7fd68d2bdc0fe972b521d6416b1c2d0d6ea82875b1ae97b05be297d9e7990db33f08882fdee4a285c1d87472c8":CRYPT_ECC_NISTP384 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse secp521r1 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/secp521r1_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"00010203040506070809":CRYPT_PKEY_ECDSA:"01ca8409961a7ae942d2a65f0abc9fbdd23e55b9a9e1d9bed72c9e91f2e62ceb431fa2788c10b32e412f9a9412c4d2b436fa396a7bd1b5e7b143aa426dddfe27d438":CRYPT_ECC_NISTP521 + +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001 parse sm2 pkcs8 prikey file and sign data +SDV_BSL_ASN1_PARSE_ECCPRIKEY_FILE_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SM3:"00010203040506070809":CRYPT_PKEY_SM2:"c5983f142e49d2e2f2c55e216ac7a32803df0a0c5eb5134238e16204579cbea0":CRYPT_ECC_SM2 + +SDV_BSL_ASN1_PARSE_ENCPK8_TC001 parse prime256v1 pkcs8 encrypted prikey file and sign data, prf hmac256, aes256 cbc +SDV_BSL_ASN1_PARSE_ENCPK8_TC001:"../testdata/cert/asn1/prime256v1_pkcs8_enc.der":CRYPT_PRIKEY_PKCS8_ENCRYPT:"31323334":CRYPT_MD_SHA256:"00010203040506070809":"" + +SDV_BSL_ASN1_PARSE_ENCPK8_TC001 parse rsa2048 pkcs8 prikey encrypted prikey file and sign data, prf hmac1 optional, aes256 cbc +SDV_BSL_ASN1_PARSE_ENCPK8_TC001:"../testdata/cert/asn1/rsa2048key_pkcs8_enc.der":CRYPT_PRIKEY_PKCS8_ENCRYPT:"31323334":CRYPT_MD_SHA256:"00010203040506070809":"2a4054ff8a8fbc4d035cbcda43a114db28b19a5190d58a794600d898e6d396ebef5af7ee91764cea4c1d65c0581950bf7463da1dc0b844c0f7439f2f2583f386609157e9a9a3a57a5cae537f418435275d745dd2b5c4c871571d99711ef1baf640be1743c7ada6c28113ebdf1f5171d54b2f83707e159d2dbecfa26a3c7a9a9dcfc83b6cba1bb8db0d55a5f1875fb7e2b21d58da1f8ebe128e979008800361a770745fadafc9cfd62bc1b4424d3fdeec531621d52cb231c69790dc7a1be5393d7b3417b0a88a93fc472eb718f7ed7800c537f1c55adc5f22f963bb199dfefa4fc1ff27510442e2e86526eaa29773e2560ab2c3bfe6a56ff7b7c72dff78a00fad" + +SDV_BSL_ASN1_PARSE_ENCPK8_TC001 parse rsa2048 pkcs8 prikey encrypted prikey file and sign data, prf hmac1 optional, sm4 cbc +SDV_BSL_ASN1_PARSE_ENCPK8_TC001:"../testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.der":CRYPT_PRIKEY_PKCS8_ENCRYPT:"31323334":CRYPT_MD_SHA256:"00010203040506070809":"2a4054ff8a8fbc4d035cbcda43a114db28b19a5190d58a794600d898e6d396ebef5af7ee91764cea4c1d65c0581950bf7463da1dc0b844c0f7439f2f2583f386609157e9a9a3a57a5cae537f418435275d745dd2b5c4c871571d99711ef1baf640be1743c7ada6c28113ebdf1f5171d54b2f83707e159d2dbecfa26a3c7a9a9dcfc83b6cba1bb8db0d55a5f1875fb7e2b21d58da1f8ebe128e979008800361a770745fadafc9cfd62bc1b4424d3fdeec531621d52cb231c69790dc7a1be5393d7b3417b0a88a93fc472eb718f7ed7800c537f1c55adc5f22f963bb199dfefa4fc1ff27510442e2e86526eaa29773e2560ab2c3bfe6a56ff7b7c72dff78a00fad" + +SDV_BSL_ASN1_PARSE_BUFF_TC001 parse buffer failed +SDV_BSL_ASN1_PARSE_BUFF_TC001:CRYPT_PRIKEY_ECC:"1234":"306f0201010420069db63c9e8012972c7f71bcd0ef1f6e23edc9f73ec68d49748c2159af25933ba00a0600a144034200043c528d0c6c84ec7112d613ddf265f2757e10ba71af937ec848f3a15c94adcf14edf2c59d704b5581a5e102b371f43cfca4a221a0672f8b2f3130bdf03c80aff5" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 rsa pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/publicpkcs8.pem":CRYPT_PUBKEY_SUBKEY:1:"30820122300D06092A864886F70D01010105000382010F003082010A0282010100A54E1B3861B07E97D99F1746CB0FD4B626E69B8D2C6332492DE37429EDE5C8910211DD2031E67C7404FA58D97E3DF21468AF6A92FA60A86A042058D47A19FDEA653CE2133EBFA0F6BF2EF2DF20DFBDD0DED3CF79DE8E1CC1A748AF9F7D435A4A08B0579D1A2FDCB7F0E4A4770FB6860D22A8B03709EF80811592A792EA7D58185725D78787F05F83210B42B012B6557EBDB8FE46C6F3F5A78B26840CD951D89681180CC817307EB673EDD3E699508456C834112E7E9F121376E5F5060635A9660F50DD938CCD643A61D3CFCD3E1D4C1D751576F029E88A522237D25A7376AB1B8133B75CAED8389339613FD39387170137C589A2C5BBAFB5B9AB0C48804D2E210203010001" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 rsa pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/publicpkcs8.pem":CRYPT_PUBKEY_SUBKEY:0:"300D06092A864886F70D01010105000382010F003082010A0282010100A54E1B3861B07E97D99F1746CB0FD4B626E69B8D2C6332492DE37429EDE5C8910211DD2031E67C7404FA58D97E3DF21468AF6A92FA60A86A042058D47A19FDEA653CE2133EBFA0F6BF2EF2DF20DFBDD0DED3CF79DE8E1CC1A748AF9F7D435A4A08B0579D1A2FDCB7F0E4A4770FB6860D22A8B03709EF80811592A792EA7D58185725D78787F05F83210B42B012B6557EBDB8FE46C6F3F5A78B26840CD951D89681180CC817307EB673EDD3E699508456C834112E7E9F121376E5F5060635A9660F50DD938CCD643A61D3CFCD3E1D4C1D751576F029E88A522237D25A7376AB1B8133B75CAED8389339613FD39387170137C589A2C5BBAFB5B9AB0C48804D2E210203010001" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 rsa pkcs1 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/rsa2048pub.pem":CRYPT_PUBKEY_RSA:1:"3082010A0282010100A54E1B3861B07E97D99F1746CB0FD4B626E69B8D2C6332492DE37429EDE5C8910211DD2031E67C7404FA58D97E3DF21468AF6A92FA60A86A042058D47A19FDEA653CE2133EBFA0F6BF2EF2DF20DFBDD0DED3CF79DE8E1CC1A748AF9F7D435A4A08B0579D1A2FDCB7F0E4A4770FB6860D22A8B03709EF80811592A792EA7D58185725D78787F05F83210B42B012B6557EBDB8FE46C6F3F5A78B26840CD951D89681180CC817307EB673EDD3E699508456C834112E7E9F121376E5F5060635A9660F50DD938CCD643A61D3CFCD3E1D4C1D751576F029E88A522237D25A7376AB1B8133B75CAED8389339613FD39387170137C589A2C5BBAFB5B9AB0C48804D2E210203010001" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/secp384r1pub.pem":CRYPT_PUBKEY_SUBKEY:1:"3076301006072A8648CE3D020106052B8104002203620004AEBF47BD84A597CB41F09E1F28E13813993476C2840084DAB242737516D1231B5DB3CD30DF7159E04ABE5A6BED2F36016C2FDABB9A6F28EA558CCDD4B8E8AACA9E8ACA0F55C04DAD4F0F1028E4D4B0185E55C37CB25FCDFADA182F0355B4AAAD" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/secp384r1pub.pem":CRYPT_PUBKEY_SUBKEY:0:"301006072A8648CE3D020106052B8104002203620004AEBF47BD84A597CB41F09E1F28E13813993476C2840084DAB242737516D1231B5DB3CD30DF7159E04ABE5A6BED2F36016C2FDABB9A6F28EA558CCDD4B8E8AACA9E8ACA0F55C04DAD4F0F1028E4D4B0185E55C37CB25FCDFADA182F0355B4AAAD" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/secp521r1pub.der":CRYPT_PUBKEY_SUBKEY:1:"30819B301006072A8648CE3D020106052B81040023038186000400A4142D36E1BA9805684E2F795D174C0DACD3BB06D9B593B8473408A78F2AD8CC1D1A1B66F480F49346C4C579F15B0E3F4C4C6EB896354CF1B7EE3BE7E7E04011AC01462B5AA9A717A4E08A43AFAF37BF6AF782747FFE88AE813BF9FC5B37DF224E0C2AAB6566623CE7E6FDB3657E6C97FDFA3A1921B84D5662C85921298B90504DC0CA" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/secp521r1pub.der":CRYPT_PUBKEY_SUBKEY:0:"301006072A8648CE3D020106052B81040023038186000400A4142D36E1BA9805684E2F795D174C0DACD3BB06D9B593B8473408A78F2AD8CC1D1A1B66F480F49346C4C579F15B0E3F4C4C6EB896354CF1B7EE3BE7E7E04011AC01462B5AA9A717A4E08A43AFAF37BF6AF782747FFE88AE813BF9FC5B37DF224E0C2AAB6566623CE7E6FDB3657E6C97FDFA3A1921B84D5662C85921298B90504DC0CA" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/prime256v1pub.der":CRYPT_PUBKEY_SUBKEY:1:"3059301306072A8648CE3D020106082A8648CE3D030107034200043C528D0C6C84EC7112D613DDF265F2757E10BA71AF937EC848F3A15C94ADCF14EDF2C59D704B5581A5E102B371F43CFCA4A221A0672F8B2F3130BDF03C80AFF5" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/prime256v1pub.der":CRYPT_PUBKEY_SUBKEY:0:"301306072A8648CE3D020106082A8648CE3D030107034200043C528D0C6C84EC7112D613DDF265F2757E10BA71AF937EC848F3A15C94ADCF14EDF2C59D704B5581A5E102B371F43CFCA4A221A0672F8B2F3130BDF03C80AFF5" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 sm2 pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2pub_pkcs1.der":CRYPT_PUBKEY_SUBKEY:1:"3059301306072A8648CE3D020106082A811CCF5501822D03420004A6A52DF225C7064B5DAF8DEFB3902E24E80A090ABD1F74D60556F924BEF62CD8083D73107EAE27BED467ED642C2781643AD0F557D089930503CBD1AB36584371" + +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001 sm2 pkcs8 +SDV_BSL_ASN1_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2pub_pkcs1.der":CRYPT_PUBKEY_SUBKEY:0:"301306072A8648CE3D020106082A811CCF5501822D03420004A6A52DF225C7064B5DAF8DEFB3902E24E80A090ABD1F74D60556F924BEF62CD8083D73107EAE27BED467ED642C2781643AD0F557D089930503CBD1AB36584371" + +SDV_BSL_PEM_ENCODE_PUBKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_PEM_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/secp384r1pub.der":CRYPT_PUBKEY_SUBKEY:1:"../testdata/cert/asn1/secp384r1pub.pem" + +SDV_BSL_PEM_ENCODE_PUBKEY_BUFF_TC001 rsa pkcs1 +SDV_BSL_PEM_ENCODE_PUBKEY_BUFF_TC001:"../testdata/cert/asn1/rsa2048pub_pkcs1.der":CRYPT_PUBKEY_RSA:1:"../testdata/cert/asn1/rsa2048pub.pem" + +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001 ecc pkcs8 +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/secp384r1_pkcs8.pem":CRYPT_PRIKEY_PKCS8_UNENCRYPT:"3081B6020100301006072A8648CE3D020106052B8104002204819E30819B020101043011F1AD7FD68D2BDC0FE972B521D6416B1C2D0D6EA82875B1AE97B05BE297D9E7990DB33F08882FDEE4A285C1D87472C8A16403620004AEBF47BD84A597CB41F09E1F28E13813993476C2840084DAB242737516D1231B5DB3CD30DF7159E04ABE5A6BED2F36016C2FDABB9A6F28EA558CCDD4B8E8AACA9E8ACA0F55C04DAD4F0F1028E4D4B0185E55C37CB25FCDFADA182F0355B4AAAD" + +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001 rsa pkcs8 +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa3072key_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:"308206FE020100300D06092A864886F70D0101010500048206E8308206E40201000282018100AADA19940C11E9E4195B10F3810333FB9DFBDA704DC4296AA52991588DE6AC1C80D743ADE09A8FDAC9998CA5D4F827ED441CE94AAA76A63170CF68517EBAC1965E8368FFD07D763500FAF3E112EC7F449E2F3E1EA3ADCAD16CDDCF7503C13E14D878AE37E49A4442532A1A2DCD68A87DFF94CF3C4EA535244902C0CFE4058C87748F0257D8EC9961145B4384C1EDD7060121AFE5EA9918F82E781D43175A736022418392AC1A6E3BD9ACC689BB4190400DC3F815CA63C1413B33B913A16B14F4C1FF4A6CA8E64C1B8CE97561C2516EB09D6FFCEB8816257108BBC3A780443EF699A78339ABAEDAD58FE67F6893B578CBA14BA588E23ACE22F27E5620B89CA3516354A64C20510CDA6DB3DBB6449C05D889A83BD1D69BE95B99FB464A397120224AC8120216E95B8E99F744CF8D810E1D818F2C149ECDE87B20842AD696C2C15E4A75F99C478F91FFCDB84C16AC329922231357AEF95DD5C50B32CD4E2E043CC691D612911D8A67C2014C89B892EA2EC6B53C819DD712D87786B0B6CBCB2FFAF3020301000102820180117D025C96CBB29EF2EAD1166120A723DCAD03540C31C5C7867675CBE9B7DB4038FEA537D978C366DD77468AA6FD1676814AB04FEB43A534045C714CD390619BCC65892193AC1EA5C2F442731F266EC9E2F894FEE5398C9183F799C7B185B34970F5BC12393D2D3AD8C66E283D66B6C5DC4680315274DE0C03C930B156F6D671506B5F0DB245030233E78F9C0EE468912871294F25DA06A5F37914B861B33ED76FF4E2CC92FF4AEF52130F13841916F4923425631D9F63BB13489D1636FCA8B2A6061A92B6DB0B3BE9812EA2F1C74B3ED0F2F9E7D6BB47AA853C740C311282B83F41234B839EDFF15ED821FCB3E55A4EA95953013BAD3634B8CAC4BD799C5B01129645DD3E035409F01A2264CC86BBF47E6E7CE527F90117E0A2382096FC455BCC6B7918AD74006ED1E0B7654C8A1EBACF64B5192E8383160BB22EB371D79D03142AE9F5353C908D578DFEA1188910A5B1EFADA3C33D5C704A29500100D452DC568F73BC5AD3AFE7287787407C40C85969400B8727CF4EB4A86BA745D15524010281C100E66DFA686B07257C667E18C302CAD6AD2049F75ED72527C0FFE52649DE938E5C4978221B3520F475EA28D3230AAD8E7E6BA81F386AAADA56614ECCBD67874015D8B1F5F0ED2B121D368541281B5A2C65B37351043785E3B3FA1795C2782563F14784645AD0B81AFAD04A5EBA1DF42D4A22BB935C1A8A4C4D06C11C826955A777E130CAF69744E47033DA46AD9279D0B9D634E9AE25DB896421295A7FC3E650379A2009D7E3B9E51602FF8A20292B8D03A953C09148174C8696B4E9A4AB0680F30281C100BDCFA549FC0A248985C183288BD210481F0998CF21A735AA5A295686B054832964F4A73F6652215623FF82087B3A20C52D4B6F37D3AE0DB357AB9AD4C86BC645505304135BEF16A9C5F442E6A2A0EAB059DD52F8E38DE90684658FEF58B35497D40917ED6B62FB249608FF5896F7C560A3B9F8B03CD9A6A0B539200CCB7360C092D752BE4B9E1EA995BEE657F8EF58C810374C6E02C60C1A3DDE10B4DD8AFD1BA72900DB5F22845E9CF9BA61F337B1FFA306259C122D46DEC48B3FD929FF1E010281C032755CC326C4AED9B9DBDCF23F1749C12973E8FE54A0673F2509F9C36D40E488A2F1F28E00A951BECC62DA312F32682498D07CDDAEC5F0FFBF59310E3CB06A411E6D81CC9B32B649BD599AB5FC9F575F81D73BA36FC11AE69B5A34CA1BE31C2A869DA0181EE261CE1074689FDAD550618E8F82AA45898941C8BBDAD157DD90C9787F65C26FC77F3A6EB05A8FC1A679256899B79E11DE2C0CC81235260B30D0DA0C1EFDE8CF8E32730A7F08B11832D833380E05FA0A4E47CCA50DC2A7F3677E2F0281C100B2FFDB3486475A65868A13926D2950C972DBAE0BC804D40B2EB3C53187A06B80E20006A93769449EE39BD59901FCB362BF70601619BE0E958E9BFA8BA7E65B388AA37F38727E6AB4F8457DC1DAA43E2EC8D07BAAD38DC4AFACB3CAA540D4FD75A1346228381944162097A3967BE8756EC9785C1A77881A277C3FBF05D1E7A0DA7AA02D1BE05BE136B44D2F14CF61882C437EA2C92C3C70B55E9AC8CE880EC6DB092D15EDCB2DD5FF13B23E1E992B70E54F6C40938A60C070DC9125493ADDA8010281C1008B44F1D6EFA2FCCC2AA5A51CD1D44928784325799E4408DCEAFA09E0D7742FB9D8C1CE94209808DEB1739CDE3AC0BE17E979C65C1A1EB1FB7F8B572EBC5C749FCFC05D6D6D3F05E4D33822AE9AA027848B5F5626B649461E042EBFAEA2359AEF063939A83E8C099B4ED93D50C2685CC2686D48BC5FE8891EE8FABBBEEC0A75E1D3843AEF3067205B0CDD90241F3CA25C38A0EC51E9EB7DD1CDC1AE61F6F69067DA91769DB3B15E8BAD3EE33CB63C974ACDE255BD75CD23163C57650046207536" + +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001 ecc pkcs1 +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/secp384r1.pem":CRYPT_PRIKEY_ECC:"3081A4020101043011F1AD7FD68D2BDC0FE972B521D6416B1C2D0D6EA82875B1AE97B05BE297D9E7990DB33F08882FDEE4A285C1D87472C8A00706052B81040022A16403620004AEBF47BD84A597CB41F09E1F28E13813993476C2840084DAB242737516D1231B5DB3CD30DF7159E04ABE5A6BED2F36016C2FDABB9A6F28EA558CCDD4B8E8AACA9E8ACA0F55C04DAD4F0F1028E4D4B0185E55C37CB25FCDFADA182F0355B4AAAD" + +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001 rsa pkcs1 +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa3072key_pkcs1.der":CRYPT_PRIKEY_RSA:"308206E40201000282018100AADA19940C11E9E4195B10F3810333FB9DFBDA704DC4296AA52991588DE6AC1C80D743ADE09A8FDAC9998CA5D4F827ED441CE94AAA76A63170CF68517EBAC1965E8368FFD07D763500FAF3E112EC7F449E2F3E1EA3ADCAD16CDDCF7503C13E14D878AE37E49A4442532A1A2DCD68A87DFF94CF3C4EA535244902C0CFE4058C87748F0257D8EC9961145B4384C1EDD7060121AFE5EA9918F82E781D43175A736022418392AC1A6E3BD9ACC689BB4190400DC3F815CA63C1413B33B913A16B14F4C1FF4A6CA8E64C1B8CE97561C2516EB09D6FFCEB8816257108BBC3A780443EF699A78339ABAEDAD58FE67F6893B578CBA14BA588E23ACE22F27E5620B89CA3516354A64C20510CDA6DB3DBB6449C05D889A83BD1D69BE95B99FB464A397120224AC8120216E95B8E99F744CF8D810E1D818F2C149ECDE87B20842AD696C2C15E4A75F99C478F91FFCDB84C16AC329922231357AEF95DD5C50B32CD4E2E043CC691D612911D8A67C2014C89B892EA2EC6B53C819DD712D87786B0B6CBCB2FFAF3020301000102820180117D025C96CBB29EF2EAD1166120A723DCAD03540C31C5C7867675CBE9B7DB4038FEA537D978C366DD77468AA6FD1676814AB04FEB43A534045C714CD390619BCC65892193AC1EA5C2F442731F266EC9E2F894FEE5398C9183F799C7B185B34970F5BC12393D2D3AD8C66E283D66B6C5DC4680315274DE0C03C930B156F6D671506B5F0DB245030233E78F9C0EE468912871294F25DA06A5F37914B861B33ED76FF4E2CC92FF4AEF52130F13841916F4923425631D9F63BB13489D1636FCA8B2A6061A92B6DB0B3BE9812EA2F1C74B3ED0F2F9E7D6BB47AA853C740C311282B83F41234B839EDFF15ED821FCB3E55A4EA95953013BAD3634B8CAC4BD799C5B01129645DD3E035409F01A2264CC86BBF47E6E7CE527F90117E0A2382096FC455BCC6B7918AD74006ED1E0B7654C8A1EBACF64B5192E8383160BB22EB371D79D03142AE9F5353C908D578DFEA1188910A5B1EFADA3C33D5C704A29500100D452DC568F73BC5AD3AFE7287787407C40C85969400B8727CF4EB4A86BA745D15524010281C100E66DFA686B07257C667E18C302CAD6AD2049F75ED72527C0FFE52649DE938E5C4978221B3520F475EA28D3230AAD8E7E6BA81F386AAADA56614ECCBD67874015D8B1F5F0ED2B121D368541281B5A2C65B37351043785E3B3FA1795C2782563F14784645AD0B81AFAD04A5EBA1DF42D4A22BB935C1A8A4C4D06C11C826955A777E130CAF69744E47033DA46AD9279D0B9D634E9AE25DB896421295A7FC3E650379A2009D7E3B9E51602FF8A20292B8D03A953C09148174C8696B4E9A4AB0680F30281C100BDCFA549FC0A248985C183288BD210481F0998CF21A735AA5A295686B054832964F4A73F6652215623FF82087B3A20C52D4B6F37D3AE0DB357AB9AD4C86BC645505304135BEF16A9C5F442E6A2A0EAB059DD52F8E38DE90684658FEF58B35497D40917ED6B62FB249608FF5896F7C560A3B9F8B03CD9A6A0B539200CCB7360C092D752BE4B9E1EA995BEE657F8EF58C810374C6E02C60C1A3DDE10B4DD8AFD1BA72900DB5F22845E9CF9BA61F337B1FFA306259C122D46DEC48B3FD929FF1E010281C032755CC326C4AED9B9DBDCF23F1749C12973E8FE54A0673F2509F9C36D40E488A2F1F28E00A951BECC62DA312F32682498D07CDDAEC5F0FFBF59310E3CB06A411E6D81CC9B32B649BD599AB5FC9F575F81D73BA36FC11AE69B5A34CA1BE31C2A869DA0181EE261CE1074689FDAD550618E8F82AA45898941C8BBDAD157DD90C9787F65C26FC77F3A6EB05A8FC1A679256899B79E11DE2C0CC81235260B30D0DA0C1EFDE8CF8E32730A7F08B11832D833380E05FA0A4E47CCA50DC2A7F3677E2F0281C100B2FFDB3486475A65868A13926D2950C972DBAE0BC804D40B2EB3C53187A06B80E20006A93769449EE39BD59901FCB362BF70601619BE0E958E9BFA8BA7E65B388AA37F38727E6AB4F8457DC1DAA43E2EC8D07BAAD38DC4AFACB3CAA540D4FD75A1346228381944162097A3967BE8756EC9785C1A77881A277C3FBF05D1E7A0DA7AA02D1BE05BE136B44D2F14CF61882C437EA2C92C3C70B55E9AC8CE880EC6DB092D15EDCB2DD5FF13B23E1E992B70E54F6C40938A60C070DC9125493ADDA8010281C1008B44F1D6EFA2FCCC2AA5A51CD1D44928784325799E4408DCEAFA09E0D7742FB9D8C1CE94209808DEB1739CDE3AC0BE17E979C65C1A1EB1FB7F8B572EBC5C749FCFC05D6D6D3F05E4D33822AE9AA027848B5F5626B649461E042EBFAEA2359AEF063939A83E8C099B4ED93D50C2685CC2686D48BC5FE8891EE8FABBBEEC0A75E1D3843AEF3067205B0CDD90241F3CA25C38A0EC51E9EB7DD1CDC1AE61F6F69067DA91769DB3B15E8BAD3EE33CB63C974ACDE255BD75CD23163C57650046207536" + +SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001 ecc pkcs8 enc +SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/prime256v1_pkcs8_enc.der":CRYPT_PRIKEY_PKCS8_ENCRYPT:CRYPT_MAC_HMAC_SHA256:CRYPT_CIPHER_AES256_CBC:16:"31323334":2048:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420069DB63C9E8012972C7F71BCD0EF1F6E23EDC9F73EC68D49748C2159AF25933BA144034200043C528D0C6C84EC7112D613DDF265F2757E10BA71AF937EC848F3A15C94ADCF14EDF2C59D704B5581A5E102B371F43CFCA4A221A0672F8B2F3130BDF03C80AFF5" + +SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001 rsa pkcs8 enc +SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa2048key_pkcs8_enc.der":CRYPT_PRIKEY_PKCS8_ENCRYPT:CRYPT_MAC_HMAC_SHA1:CRYPT_CIPHER_AES256_CBC:16:"31323334":2048:"308204BE020100300D06092A864886F70D0101010500048204A8308204A40201000282010100A54E1B3861B07E97D99F1746CB0FD4B626E69B8D2C6332492DE37429EDE5C8910211DD2031E67C7404FA58D97E3DF21468AF6A92FA60A86A042058D47A19FDEA653CE2133EBFA0F6BF2EF2DF20DFBDD0DED3CF79DE8E1CC1A748AF9F7D435A4A08B0579D1A2FDCB7F0E4A4770FB6860D22A8B03709EF80811592A792EA7D58185725D78787F05F83210B42B012B6557EBDB8FE46C6F3F5A78B26840CD951D89681180CC817307EB673EDD3E699508456C834112E7E9F121376E5F5060635A9660F50DD938CCD643A61D3CFCD3E1D4C1D751576F029E88A522237D25A7376AB1B8133B75CAED8389339613FD39387170137C589A2C5BBAFB5B9AB0C48804D2E2102030100010282010049D5512325BF074C1BCF8B3DFB84DEA55D4AB33FA30BCB721424FBC59E947BB9090BA190B7B912ED5F2BD27392876890E51134B0E1543AE4DF62F34A341F57E251C597D4B0BA36D2FF21A129382DB7428BC45F6F379092178CF852391261FAFA06577D4A965FBA5E0E2291B2FC39B2363BBCCCB8489FC8EDDF0CD9FC2CF03F602715761C4D272EDADBF3D49C947B378B580F04998E7578F9AA4EBB1A9B1C9ABE8F093E497E86942A6145C677F35E9542E3A4C7D473DBF91234E13BBF24C950C5B98DACC46D07BF65F9D45329C86EDDC18D74F753C2FB466F59FCED9F634E8CECAA2E8EB3A011BF257748F37440F850E50C833E3BEED0C84AA3B23510F110BF6102818100E3B6ECD39561B6AEF8FC8EECFFBCBA7678B841ECC99CC6F595F85BDE95178D1A309CAD85C2F8CC127B45F70384DED7782B1A7FA5377A5D1C94A2AEE016C62FBF6D376F4248E931C5306A9A2C1EEE1035C1913F6111936F30C106B5C54DE5002D2E09D315E6149CF7EEB5466D6C1DFAE3F9276503F9D9D7298A29C4AF2270DF1F02818100B9D6A0F1E84FDDC62397567EEB4E93C4C1DE69941A744AE5FB8B29917DE2A5EC0835D9D01AD897B22064E8BB1D33D237BD90F7AC7011A228ED25AC6ED567972F2EFA61A2B028EEF6444800AECDAB93A309B9C499D9715BF6E85365CC335EBB46472BE9B6F2B21FA2EE78F23796C109F24F20767C66529103947DC658E0308ABF02818100A090848F70BEB4B4CDE62FD59741F96CBE14968FA35DC3C0B95DA551DE68FBDAA2BA6774711543B8286A1E11C227EB60D56BDAE3A1A9CB6BF2B67F7E8D3073CC93F349A5408A05C91829A2CA4788EFAF27ED05F6A910FF8F2E1C50216E9A71B469C90DA95C51DE98C81DD42A25D941E66BF1C63DB6784F4A001D118DB848445B02818006D9D2B5184B5971A47E3FC20E0AA787E95DB9A6AC12FD6FDD06145238C1D23C11516AE631172B007611424323A0756F789D8F83DBDDCA8C97B17BD9DA24277EA5CCB52CBA31C81D6C06FB7F76358D0BC5A0038F6864B56F34C15E4F58D57531F20DBC5FF2327ED812D2829B6A0353CA8B00375DFEA7AC90E5387DC768FC612102818100900DCD99B19D9DBFCF7DA489FCB856FD218EAA3E17303802F7105A766A98C663937020963836B8C228DA3099302A5497606B72A1D6DD062332D90F1369ACCA755C0352623CAC276E9537A80C0E4E8644FF8ED44DC4466FC2D7C925F5BADEF657776E4B7E7C0CC26FA82736F469DDA248E6F3D3A4E8D03A02F6EC78E08439CE84" + +SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001 sm4 pkcs8 enc +SDV_BSL_ASN1_ENCODE_ENCRYPTED_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.der":CRYPT_PRIKEY_PKCS8_ENCRYPT:CRYPT_MAC_HMAC_SHA1:CRYPT_CIPHER_SM4_CBC:16:"31323334":2048:"308204BE020100300D06092A864886F70D0101010500048204A8308204A40201000282010100A54E1B3861B07E97D99F1746CB0FD4B626E69B8D2C6332492DE37429EDE5C8910211DD2031E67C7404FA58D97E3DF21468AF6A92FA60A86A042058D47A19FDEA653CE2133EBFA0F6BF2EF2DF20DFBDD0DED3CF79DE8E1CC1A748AF9F7D435A4A08B0579D1A2FDCB7F0E4A4770FB6860D22A8B03709EF80811592A792EA7D58185725D78787F05F83210B42B012B6557EBDB8FE46C6F3F5A78B26840CD951D89681180CC817307EB673EDD3E699508456C834112E7E9F121376E5F5060635A9660F50DD938CCD643A61D3CFCD3E1D4C1D751576F029E88A522237D25A7376AB1B8133B75CAED8389339613FD39387170137C589A2C5BBAFB5B9AB0C48804D2E2102030100010282010049D5512325BF074C1BCF8B3DFB84DEA55D4AB33FA30BCB721424FBC59E947BB9090BA190B7B912ED5F2BD27392876890E51134B0E1543AE4DF62F34A341F57E251C597D4B0BA36D2FF21A129382DB7428BC45F6F379092178CF852391261FAFA06577D4A965FBA5E0E2291B2FC39B2363BBCCCB8489FC8EDDF0CD9FC2CF03F602715761C4D272EDADBF3D49C947B378B580F04998E7578F9AA4EBB1A9B1C9ABE8F093E497E86942A6145C677F35E9542E3A4C7D473DBF91234E13BBF24C950C5B98DACC46D07BF65F9D45329C86EDDC18D74F753C2FB466F59FCED9F634E8CECAA2E8EB3A011BF257748F37440F850E50C833E3BEED0C84AA3B23510F110BF6102818100E3B6ECD39561B6AEF8FC8EECFFBCBA7678B841ECC99CC6F595F85BDE95178D1A309CAD85C2F8CC127B45F70384DED7782B1A7FA5377A5D1C94A2AEE016C62FBF6D376F4248E931C5306A9A2C1EEE1035C1913F6111936F30C106B5C54DE5002D2E09D315E6149CF7EEB5466D6C1DFAE3F9276503F9D9D7298A29C4AF2270DF1F02818100B9D6A0F1E84FDDC62397567EEB4E93C4C1DE69941A744AE5FB8B29917DE2A5EC0835D9D01AD897B22064E8BB1D33D237BD90F7AC7011A228ED25AC6ED567972F2EFA61A2B028EEF6444800AECDAB93A309B9C499D9715BF6E85365CC335EBB46472BE9B6F2B21FA2EE78F23796C109F24F20767C66529103947DC658E0308ABF02818100A090848F70BEB4B4CDE62FD59741F96CBE14968FA35DC3C0B95DA551DE68FBDAA2BA6774711543B8286A1E11C227EB60D56BDAE3A1A9CB6BF2B67F7E8D3073CC93F349A5408A05C91829A2CA4788EFAF27ED05F6A910FF8F2E1C50216E9A71B469C90DA95C51DE98C81DD42A25D941E66BF1C63DB6784F4A001D118DB848445B02818006D9D2B5184B5971A47E3FC20E0AA787E95DB9A6AC12FD6FDD06145238C1D23C11516AE631172B007611424323A0756F789D8F83DBDDCA8C97B17BD9DA24277EA5CCB52CBA31C81D6C06FB7F76358D0BC5A0038F6864B56F34C15E4F58D57531F20DBC5FF2327ED812D2829B6A0353CA8B00375DFEA7AC90E5387DC768FC612102818100900DCD99B19D9DBFCF7DA489FCB856FD218EAA3E17303802F7105A766A98C663937020963836B8C228DA3099302A5497606B72A1D6DD062332D90F1369ACCA755C0352623CAC276E9537A80C0E4E8644FF8ED44DC4466FC2D7C925F5BADEF657776E4B7E7C0CC26FA82736F469DDA248E6F3D3A4E8D03A02F6EC78E08439CE84" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:20:CRYPT_MD_SHA1:CRYPT_MD_SHA1:"30820274020100300B06092A864886F70D01010A048202603082025C02010002818100A0643A54FE3D1A4C60F062AB2E9E25513E97CAFEA8515C333AA9543D35DBF1B1C8FAA623ABB528EAE0DEC87779311D1C57C7BED5260B5519E1902A932B6CC74FD3E7AC57197E608A2AE8ACBFDBE6F606F18D0655EE789E152E88827F2A760F14BD0681B3E8DEA0C8E4477268AA40CC2213F5BF006275672F55C4D2F2C3C34009020301000102818041114824D0DB42FEF758ADFE9A33E819B495E9F133A18610F65C596357A539C11132B611C48802E87E7F82BE0D396280EC0F8998790DA1E1950362723FECAA5250B906A113E769369C107D0B691F2532FEFC0ACB6C7570AE37B6478198D27C6A0B0F69692B3BF141B8C3DC6A8B0C0BCC57E140FF8DD3BB831315DE1C8BA5566D024100D1981EB734FBD5D65B04C6025271713E42D37F872C39CDE9C89802576F5007FFC1F6BAC15F8F16C706D1B1306BFDB70A91DE83B5336A105DB6218992051B0B93024100C3E747A93547EBB6463C88775287FE425229BB941421340FC7746E8E14E837E50B4D0CD1597464AE06F6C74AA3AAA1B26B39EF531735D8CCA63E64FFB558DF7302405AEDB3E5A786D9EE74EE4D3914AB4285D058112B83745070EC25865E885C201C44F9D56BAF1954B863ACF5421C97A5A1604738BC93E19FD807FBE4C30494072102404F01F4BDC2564A330DEA95E301AF05153C4BC671F7185905D01C1E06415A524896A1317D3105A721247FDC6A36CDB73EDCCDD5BE7E0AE26FCED0352D87B6DB0F024100B525031764B4C9E7D73231157B93B6260E4DD79796D99F4C275899A158FF6720FB84C84D5762BAAB26900EF59F8223EF9303A80E055D21AD287762C126E4F674" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss saltLen:10 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_salt10.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:10:CRYPT_MD_SHA1:CRYPT_MD_SHA1:"3082027D020100301206092A864886F70D01010A3005A20302010A048202623082025E02010002818100CA17F70DF1AA88E9B6F061CDEAC8AE67F7A9D119101412BA65F5403692B3E541CEF83C45D9BEAF0F4EA8B911CC606B763DBF1FDDD53466A65C34E22BD67D3B7DCA4894FAE6CF3D551595063283E2FAD9EA63353D296F5ABA2D7649142A7FC6454CFF611EFEA337B336287E7498A701729FB47C93240EDC030193826BED50242D02030100010281803FB948CC9BCC5339A6D6AB705BBD05C980BD8A5265D07E8B4A0508476D00CEA46E97B5A1ACE4449D06078BBBC1FF11438A7ACE988B56E79B436DE5773F3DE3D8D9267D8412CD39632DB263CD262E54F73BF37B782E9599837E87BAA207E363335700860C54E3DBFE88330ADE5428F5B09B53026ABCB081110E4B0A26354A307D024100FAA02B898414925440C5EC8516BD7988652797396138E7175C4FF70D6A21254280C0B10206AD71DF0B96DA4D2C0DEFC080359B8EA2613000405E75263334407F024100CE6D5FD5CCB4A520554A90F7D784623DF91A2D3356DD44C21F04BBF8EB7CC7CD2AD139E20A082BA7715F45382C2D1F0187D20E4C9A9CD6EA8B3E566243834553024100C0F10FB35538551281AF1D8FB3DAF835F5D1CDCCC1B901C6ED2D2E7F6845CE1E6D6A6A9AA9B35B27A00F694DE1ED74B658BD6C5D194B029E1EEFD8F628934057024100A3D460640184392D7123ADEC558A86A1E2CAA8A6FF40BB2A498DEB558227D536FACD74DFF5D0483D2B184E8A675D242785D0EB72569F355E8E465A2EC0A0356B024100E8F54870A8C7F3B769676D1AC64C06D43856FA9C0133B695808039F7521DF743940A89FAA45BDF7B7C6ABC1E73FFD5BF38134FE88105AC24555EF318B33516B5" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss mdId:sha256 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_salt10.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:20:CRYPT_MD_SHA256:CRYPT_MD_SHA1:"30820289020100301E06092A864886F70D01010A3011A00F300D06096086480165030402010500048202623082025E02010002818100CA17F70DF1AA88E9B6F061CDEAC8AE67F7A9D119101412BA65F5403692B3E541CEF83C45D9BEAF0F4EA8B911CC606B763DBF1FDDD53466A65C34E22BD67D3B7DCA4894FAE6CF3D551595063283E2FAD9EA63353D296F5ABA2D7649142A7FC6454CFF611EFEA337B336287E7498A701729FB47C93240EDC030193826BED50242D02030100010281803FB948CC9BCC5339A6D6AB705BBD05C980BD8A5265D07E8B4A0508476D00CEA46E97B5A1ACE4449D06078BBBC1FF11438A7ACE988B56E79B436DE5773F3DE3D8D9267D8412CD39632DB263CD262E54F73BF37B782E9599837E87BAA207E363335700860C54E3DBFE88330ADE5428F5B09B53026ABCB081110E4B0A26354A307D024100FAA02B898414925440C5EC8516BD7988652797396138E7175C4FF70D6A21254280C0B10206AD71DF0B96DA4D2C0DEFC080359B8EA2613000405E75263334407F024100CE6D5FD5CCB4A520554A90F7D784623DF91A2D3356DD44C21F04BBF8EB7CC7CD2AD139E20A082BA7715F45382C2D1F0187D20E4C9A9CD6EA8B3E566243834553024100C0F10FB35538551281AF1D8FB3DAF835F5D1CDCCC1B901C6ED2D2E7F6845CE1E6D6A6A9AA9B35B27A00F694DE1ED74B658BD6C5D194B029E1EEFD8F628934057024100A3D460640184392D7123ADEC558A86A1E2CAA8A6FF40BB2A498DEB558227D536FACD74DFF5D0483D2B184E8A675D242785D0EB72569F355E8E465A2EC0A0356B024100E8F54870A8C7F3B769676D1AC64C06D43856FA9C0133B695808039F7521DF743940A89FAA45BDF7B7C6ABC1E73FFD5BF38134FE88105AC24555EF318B33516B5" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss mgfId:sha256 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_salt10.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:20:CRYPT_MD_SHA1:CRYPT_MD_SHA256:"30820296020100302B06092A864886F70D01010A301EA11C301A06092A864886F70D010108300D06096086480165030402010500048202623082025E02010002818100CA17F70DF1AA88E9B6F061CDEAC8AE67F7A9D119101412BA65F5403692B3E541CEF83C45D9BEAF0F4EA8B911CC606B763DBF1FDDD53466A65C34E22BD67D3B7DCA4894FAE6CF3D551595063283E2FAD9EA63353D296F5ABA2D7649142A7FC6454CFF611EFEA337B336287E7498A701729FB47C93240EDC030193826BED50242D02030100010281803FB948CC9BCC5339A6D6AB705BBD05C980BD8A5265D07E8B4A0508476D00CEA46E97B5A1ACE4449D06078BBBC1FF11438A7ACE988B56E79B436DE5773F3DE3D8D9267D8412CD39632DB263CD262E54F73BF37B782E9599837E87BAA207E363335700860C54E3DBFE88330ADE5428F5B09B53026ABCB081110E4B0A26354A307D024100FAA02B898414925440C5EC8516BD7988652797396138E7175C4FF70D6A21254280C0B10206AD71DF0B96DA4D2C0DEFC080359B8EA2613000405E75263334407F024100CE6D5FD5CCB4A520554A90F7D784623DF91A2D3356DD44C21F04BBF8EB7CC7CD2AD139E20A082BA7715F45382C2D1F0187D20E4C9A9CD6EA8B3E566243834553024100C0F10FB35538551281AF1D8FB3DAF835F5D1CDCCC1B901C6ED2D2E7F6845CE1E6D6A6A9AA9B35B27A00F694DE1ED74B658BD6C5D194B029E1EEFD8F628934057024100A3D460640184392D7123ADEC558A86A1E2CAA8A6FF40BB2A498DEB558227D536FACD74DFF5D0483D2B184E8A675D242785D0EB72569F355E8E465A2EC0A0356B024100E8F54870A8C7F3B769676D1AC64C06D43856FA9C0133B695808039F7521DF743940A89FAA45BDF7B7C6ABC1E73FFD5BF38134FE88105AC24555EF318B33516B5" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss mdId:sha256 mgfId:sha256 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_salt10.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:20:CRYPT_MD_SHA256:CRYPT_MD_SHA256:"308202A7020100303C06092A864886F70D01010A302FA00F300D06096086480165030402010500A11C301A06092A864886F70D010108300D06096086480165030402010500048202623082025E02010002818100CA17F70DF1AA88E9B6F061CDEAC8AE67F7A9D119101412BA65F5403692B3E541CEF83C45D9BEAF0F4EA8B911CC606B763DBF1FDDD53466A65C34E22BD67D3B7DCA4894FAE6CF3D551595063283E2FAD9EA63353D296F5ABA2D7649142A7FC6454CFF611EFEA337B336287E7498A701729FB47C93240EDC030193826BED50242D02030100010281803FB948CC9BCC5339A6D6AB705BBD05C980BD8A5265D07E8B4A0508476D00CEA46E97B5A1ACE4449D06078BBBC1FF11438A7ACE988B56E79B436DE5773F3DE3D8D9267D8412CD39632DB263CD262E54F73BF37B782E9599837E87BAA207E363335700860C54E3DBFE88330ADE5428F5B09B53026ABCB081110E4B0A26354A307D024100FAA02B898414925440C5EC8516BD7988652797396138E7175C4FF70D6A21254280C0B10206AD71DF0B96DA4D2C0DEFC080359B8EA2613000405E75263334407F024100CE6D5FD5CCB4A520554A90F7D784623DF91A2D3356DD44C21F04BBF8EB7CC7CD2AD139E20A082BA7715F45382C2D1F0187D20E4C9A9CD6EA8B3E566243834553024100C0F10FB35538551281AF1D8FB3DAF835F5D1CDCCC1B901C6ED2D2E7F6845CE1E6D6A6A9AA9B35B27A00F694DE1ED74B658BD6C5D194B029E1EEFD8F628934057024100A3D460640184392D7123ADEC558A86A1E2CAA8A6FF40BB2A498DEB558227D536FACD74DFF5D0483D2B184E8A675D242785D0EB72569F355E8E465A2EC0A0356B024100E8F54870A8C7F3B769676D1AC64C06D43856FA9C0133B695808039F7521DF743940A89FAA45BDF7B7C6ABC1E73FFD5BF38134FE88105AC24555EF318B33516B5" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss saltLen:10 mdId:sha256 mgfId:sha256 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_salt10.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:10:CRYPT_MD_SHA256:CRYPT_MD_SHA256:"308202AC020100304106092A864886F70D01010A3034A00F300D06096086480165030402010500A11C301A06092A864886F70D010108300D06096086480165030402010500A20302010A048202623082025E02010002818100CA17F70DF1AA88E9B6F061CDEAC8AE67F7A9D119101412BA65F5403692B3E541CEF83C45D9BEAF0F4EA8B911CC606B763DBF1FDDD53466A65C34E22BD67D3B7DCA4894FAE6CF3D551595063283E2FAD9EA63353D296F5ABA2D7649142A7FC6454CFF611EFEA337B336287E7498A701729FB47C93240EDC030193826BED50242D02030100010281803FB948CC9BCC5339A6D6AB705BBD05C980BD8A5265D07E8B4A0508476D00CEA46E97B5A1ACE4449D06078BBBC1FF11438A7ACE988B56E79B436DE5773F3DE3D8D9267D8412CD39632DB263CD262E54F73BF37B782E9599837E87BAA207E363335700860C54E3DBFE88330ADE5428F5B09B53026ABCB081110E4B0A26354A307D024100FAA02B898414925440C5EC8516BD7988652797396138E7175C4FF70D6A21254280C0B10206AD71DF0B96DA4D2C0DEFC080359B8EA2613000405E75263334407F024100CE6D5FD5CCB4A520554A90F7D784623DF91A2D3356DD44C21F04BBF8EB7CC7CD2AD139E20A082BA7715F45382C2D1F0187D20E4C9A9CD6EA8B3E566243834553024100C0F10FB35538551281AF1D8FB3DAF835F5D1CDCCC1B901C6ED2D2E7F6845CE1E6D6A6A9AA9B35B27A00F694DE1ED74B658BD6C5D194B029E1EEFD8F628934057024100A3D460640184392D7123ADEC558A86A1E2CAA8A6FF40BB2A498DEB558227D536FACD74DFF5D0483D2B184E8A675D242785D0EB72569F355E8E465A2EC0A0356B024100E8F54870A8C7F3B769676D1AC64C06D43856FA9C0133B695808039F7521DF743940A89FAA45BDF7B7C6ABC1E73FFD5BF38134FE88105AC24555EF318B33516B5" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss mdId:sha256 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_mdsha256.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:20:CRYPT_MD_SHA256:CRYPT_MD_SHA1:"308204CE020100301E06092A864886F70D01010A3011A00F300D06096086480165030402010500048204A7308204A302010002820101009C8B2F5F9716A5E7F0A6C6E730348F333AE9CDF955C57BF3FC9B0304E3736C99C4E1134809B5B7EF3ABB1F4CC558C0B1BDFD3C9ED97722535E8EC4D2A5F1A66E376706E5CDCC36876C72C2FC5EB5604D64981F6C501CD3505CFD4ED60C306697D867B2FC3E0ED7FF0B93915F71B541DC96DF638360F21B3BFA7D582F94414362E675CD212093312B9F08B58DAE67038B3C761C41752824BB6DF526B9F8F23A8DF9F693B568256461CF6F57DEA137983D11FD5692A1E783357483C7F2FA542AF83F3222D58CF7596C7F8700B4A5F2C599DCE8C8AE167A611657A36777BB4C47213F0467C5ACC73C82C968E1BA20D27279D342338DAA9A400C2EAF5A1EF3F7E3E7020301000102820100126C50FACB7C675C636BDA9C6A5B17D546CED850F536AF794DEBC2505E2254901E3B023ABD5077B6A859F850DFD2D64EB4C0D65462DC774634D526E071962868EFE2934DBD496B761C4869F3D5D8E65E0558DFD883EF233161D83A8C77551A3B2EEFE4011FF3E84359A342D31193418E8A94FCBB01504CEDE348C2CAF559899557F17014345B04B61C565E7FA8C69EDCD1DF4CEB67DB2B8657B2B53B2140ACA6C312161F7C9F33C581E6C77EAB6753CA0D50263A4BE30B27C3F3B5D649518F678848A27233E876A58BB4C195B18DF76598424FD5CD4F11E494A7A541F3516BA4BF7267FB4A36CA0DBF46A75C42F80FE8C8B661B05030D28D3223472030CC028102818100DC1A7E0A6410D62FC84C65227AD58C0028F1ECC7582AF7E3D84ED07700B8CB039A211CB92265E7662619527E9D148810AD7B88D931D45129C74E6AA62C3C53AE4434A756999152498B10DB1C5170B94E3CC7210EAFC800E24AD38B448F20CA89FC8A0E8137EDAB7570759B1765C813266FD372DB2D44320982D5FF1DF1F8886702818100B613046B826C1D6BA03DD0E2A04CB36684E65B2501BC7D2FE64ACD88ED38ECA6F788E868C18D228349783A6C15A9827E86E5D31BD47A95DD37519E0BA964DEF2963011D07234D8F07584319B41E4B33ACDA817F3236C07EA25D1D95907C79D6C33ACCA7E548D4E51CE0EF9A539C406F3FF6A7257A60D502D4CA55489C69298810281810083778B7B5763BB1B954F1445710B26715E038AC353056F45778933F930C42FF6B9D4375CD98FF6944C036A03D87D4FFC6E32D07DB2C6B7A7F5B4FFFCBB85591249090E3EAAC1635E2C23684CD4D438CAE380A95D255F982F92342306535B69BEDBC9F679F6570EC7B9E1753E977BD6FC6964EA40C21BEEAB41ABE2931759B4D70281805018619361D669C2D4C51CC4F53B88980AD2C339AE5FDABA5D967E8043CB0CE00E789DB4A7A08C943097C12B9703F0B1F469D9CA9E5826E11FDAB9A9EBA4C226F946C02F706E2B18ECB970911A159F7AB8C9BF6F681FB8039B0B8B8F8CCA9547EA1B9320ABD555A4CAFEEF776DC7FC3F0E1727A1C31C8C2EC14EE1B792311F0102818005B4F89DD75341F7E2A3D43A34F82632AE581BA48492E2AA7F2BF88E68EC8DB9476EE7A5EC683D7179EBBC8E3EA278AA80C702F22D33D3CE49C54164D7E410C3F914D7011A24D6C5A2872DB6CB5F46EB0C89157E4F6B69BAA9CAAE9A0C0A25C3FE7E5F0A2CECCCD10E068CCADEB51CC33699273A61ECA287D54B25B83B53B077" + +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001 rsa-pss mgfId:sha256 pkcs8 +SDV_BSL_ASN1_ENCODE_PRAPSSPRIKEY_BUFF_TC001:"../testdata/cert/asn1/rsa_pss_mgfsha256.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:20:CRYPT_MD_SHA1:CRYPT_MD_SHA256:"308204DB020100302B06092A864886F70D01010A301EA11C301A06092A864886F70D010108300D06096086480165030402010500048204A7308204A30201000282010100B4BC35641D4E271C31D48112C7F72BE1C1FE9CB90CAE4C6E2AB5C19EFE51020F9BA4BCE986E9D6D579149A9C58D463721452A3E7B0EA44AF6926F8315301D8679984417CD2BF9BF8C54EB50850937651C0B60A446E7301315F5A903AFDB3DDE235805C71B44960352B436F4C2CA125E292CD40D9743B44E56FB0004887FF7A1B6029D2FD3C9BA7E450F371912C10470056AB132674D04A7471007CBC5258B95C5E378B67284EBDEE96633DB472AEB155E8EDA50DF3AE4F4107A1F2C8E3711FB86DE8838861ACF6EEBBE9B4F8FC1DC72255CA8E1C9EE5259AA968AEBB23EFF8467377914BD4FA39A3A74928CE5E48E6860F8CE69B573BAADCEDF1D418CC0D9DB7020301000102820100226D2D505E22AA617CFE68FDAE585F23F8236B2FF681E6EE1F3592E599B4CD8B328F0D2B00775F6437559CE3C629E2AD72C091170B847C43DB68406388D7B3A47C420C855DD180C0C0B8AED420210EAB20E5AC0BFFEBE920C1F48ABFA9DECE978DB05F2B8B77649B8C1BA2C2244827E2C22AD5BCF61E6A0FB81812DDBE0604788B25E7DE968E2B9BF140174CE449544D994AF73BB14140740E87DD412BDD03BBB351749750E3171D241C0F89B321A15426C62209268B1F109830AD9E22D53793E9ACA4C0848308343A147AD35009997D12DD8ABACE149C64A5E783EC013D6FD105E741353E42ABEE01128CBFD766AE51D2D95A2343DDE1BD40D3A068BE1D2DF902818100EC962D509AE79702B934EDB57BFA824B4B3CCAD1A6114B621092C9CC8D22F10E1FA0C984CD7C03DB71CB7F5C41DADAA41094AA607489ACD7A9EC4E26BA9D0B812D90840FD52990724A1936ECAEF6664993AB12C19B228A41F0B030CD7C90CAFF060E6B4229C6B00417BB1EE2B030F1892828E013D9A6E08CE1EAAF0647F56EF902818100C390CBDBCF490942B254B7D2CBD639B39630C803EAEF2728228F70003450468D91BB4AE588A88B361CF8614C6FCC45B9761CE5BBF3D7DFCE29CF9166D0236C32E0CF769FB8E3BA558EAF23BA9AA19ED366107A9ED3409F90D2A364C947FBFE4713028767C6BE7AB606B5C65CC0C12AA261D85784FFB4AFD5D570C83AB059AE2F02818100E008E6286A47DC2C6C0DBEFC18C7041320D0148FAADEBDAFC359FD568260103CFB9E5AB6338FB86759BF067FEAACC056948CF33A1BA133D795C57BCC18F3162DE163F46AB9C47E507BF29C9C4CA27002449FBF472F0CEA37BF2059567D1AEFDFC7706809635E0ED81150D4D27D5E1B9B723822D9294669657F99A8DC1DD040A102818012432B46538D16784BFEED4B9A0D5F460DF870352D7337CCDFAD55602F826F9438CFACA6D2A42A9BDB08B6CD548356DF82D02003F5396B84ED129D1964C66A0C36422969B0F2532C3A2ED0BF5441537B9A445FAF053B3BAB62802FA13C3FA3F72F27454DC399760C19845009C956408CF966228620FAD690B965D6CCE43AFBB1028180126D090A6FD3B184E64CBE8ABED12F7A3EE6E436C5AF913E8D4DB478C0767C031D65C32BEAA4BB1BB5501B9F9AEB512C6E28A68185074DA45F01311BB32019ED3EAEDF6EE3A9AE916062D7FE4A4E32A789EFC49552138293874D325AA51FBEFCA282EAB5D87B05ABA5B926A6218ADCE3B796C08E89D75D489AB4877955F83155" + +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001 sm2 pkcs1 +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2_pkcs1.der":CRYPT_PRIKEY_ECC:"30770201010420C5983F142E49D2E2F2C55E216AC7A32803DF0A0C5EB5134238E16204579CBEA0A00A06082A811CCF5501822DA14403420004A6A52DF225C7064B5DAF8DEFB3902E24E80A090ABD1F74D60556F924BEF62CD8083D73107EAE27BED467ED642C2781643AD0F557D089930503CBD1AB36584371" + +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001 sm2 pkcs8 +SDV_BSL_ASN1_ENCODE_PRIKEY_BUFF_TC001:"../testdata/cert/asn1/sm2_pkcs8/sm2_pkcs8.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:"308187020100301306072A8648CE3D020106082A811CCF5501822D046D306B0201010420C5983F142E49D2E2F2C55E216AC7A32803DF0A0C5EB5134238E16204579CBEA0A14403420004A6A52DF225C7064B5DAF8DEFB3902E24E80A090ABD1F74D60556F924BEF62CD8083D73107EAE27BED467ED642C2781643AD0F557D089930503CBD1AB36584371" + +SDV_BSL_ASN1_ENCODE_RSAPSS_PUBLICKEY_BUFF_TC001 encode rsa-pss public key test +SDV_BSL_ASN1_ENCODE_RSAPSS_PUBLICKEY_BUFF_TC001:"../testdata/cert/asn1/rsapsspubkey.pem":"30820156304106092A864886F70D01010A3034A00F300D06096086480165030402010500A11C301A06092A864886F70D010108300D06096086480165030402010500A20302010A0382010F003082010A0282010100C3E1967BD6EB4C62B8DF1C84A5106173FE0423C69B82C5132E3231B68A16CAEE6FEA33A53BC496F96AA4FD04A200C73472BB7873C9B97C83355238377CDA3F430A33500E10C223395361462EAC6F79FC6E3B0AF24EDAE1A7CC287DEFADD2D0F0FDD414BF1F42A4DD0AC648E5E5EB4FE8DE6E8451FFDD18A36A5324C1AB593F33C98D2DC08197E43F74DD4F2273213D463288470252487783051656F9FE0E6F8DD2443E35E40384DC522B7F056B38F442C8D9ADC4C0A35F32AE05FEDE9B8EB48E62D5B7D7A9EE16F71268A48438F29862FF50889953775BA7AC99C33213A8AEA51BEB471FDA85A969969E32D3FAA216E7C5671BA49F4C4133A507B0E209FF86ED0203010001" diff --git a/testcode/sdv/testcase/crypto/entropy/test_suite_sdv_entropy.c b/testcode/sdv/testcase/crypto/entropy/test_suite_sdv_entropy.c new file mode 100644 index 00000000..874b5cc2 --- /dev/null +++ b/testcode/sdv/testcase/crypto/entropy/test_suite_sdv_entropy.c @@ -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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "entropy.h" +#include "eal_entropy.h" +#include "crypt_algid.h" + +/* END_HEADER */ + +/** + * @test UT_CRYPTO_ENTROPY_GetCtx + * @title Get the seedCtx of the corresponding algorithm. + * @precon nan + * @brief + * 1.Call ENTROPY_GetCtx get seedCtx, expected result 1. + * 2.Call ENTROPY_GetCtx get seedCtx,conFunc is NULL or algid is 0, expected result 2. + * @expect + * 1.Return seedCtx. + * 2.Return NULL. + */ +/* BEGIN_CASE */ +void UT_CRYPTO_ENTROPY_GetCtx(void) +{ + ASSERT_TRUE(ENTROPY_GetCtx(EAL_EntropyGetECF(CRYPT_MAC_HMAC_SHA256), CRYPT_MAC_HMAC_SHA256) != NULL); + ASSERT_TRUE(ENTROPY_GetCtx(NULL, CRYPT_MAC_HMAC_SHA256) == NULL); + ASSERT_TRUE(ENTROPY_GetCtx(EAL_EntropyGetECF(CRYPT_MAC_HMAC_SHA256), 0) == NULL); +exit: + return; +} +/* END_CASE */ + +/** + * @test UT_CRYPTO_ENTROPY_GetFei + * @title Get the seedCtx of the corresponding algorithm. + * @precon nan + * @brief + * 1.Call ENTROPY_GetCtx get seedCtx, expected result 1. + * 2.Call ENTROPY_GetFullEntropyInput get entropy, expected result 2. + * @expect + * 1.Return seedCtx. + * 2.Get entropy successful. + */ +/* BEGIN_CASE */ +void UT_CRYPTO_ENTROPY_GetFei(void) +{ + TestMemInit(); + void *seedCtx = ENTROPY_GetCtx(EAL_EntropyGetECF(CRYPT_MAC_HMAC_SHA256), CRYPT_MAC_HMAC_SHA256); + ASSERT_TRUE(seedCtx != NULL); + uint8_t data[32] = {0}; + ASSERT_EQ(ENTROPY_GetFullEntropyInput(seedCtx, data, 32), CRYPT_SUCCESS); + +exit: + return; +} +/* END_CASE */ + diff --git a/testcode/sdv/testcase/crypto/entropy/test_suite_sdv_entropy.data b/testcode/sdv/testcase/crypto/entropy/test_suite_sdv_entropy.data new file mode 100644 index 00000000..c912081d --- /dev/null +++ b/testcode/sdv/testcase/crypto/entropy/test_suite_sdv_entropy.data @@ -0,0 +1,5 @@ +UT_CRYPTO_ENTROPY_GetCtx +UT_CRYPTO_ENTROPY_GetCtx: + +UT_CRYPTO_ENTROPY_GetFei +UT_CRYPTO_ENTROPY_GetFei: \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/gcm/test_suite_sdv_gcm.c b/testcode/sdv/testcase/crypto/gcm/test_suite_sdv_gcm.c new file mode 100644 index 00000000..58443e89 --- /dev/null +++ b/testcode/sdv/testcase/crypto/gcm/test_suite_sdv_gcm.c @@ -0,0 +1,326 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "securec.h" +#include "bsl_err.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_dsa.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_rand.h" +#include "crypt_bn.h" +#include "crypt_util_rand.h" +#include "crypt_eal_md.h" +#include "crypt_eal_cipher.h" +/* END_HEADER */ + +#define SUCCESS 0 +#define ERROR (-1) + +typedef struct { + uint8_t *key; + uint8_t *iv; + uint8_t *aad; + uint8_t *pt; + uint8_t *ct; + uint8_t *tag; + uint32_t keyLen; + uint32_t ivLen; + uint32_t aadLen; + uint32_t ptLen; + uint32_t ctLen; + uint32_t tagLen; + int algId; +} ThreadParameter; + +void MultiThreadTest(void *arg) +{ + ThreadParameter *threadParameter = (ThreadParameter *)arg; + uint32_t outLen = threadParameter->ctLen; + uint32_t tagLen = threadParameter->tagLen; + uint8_t out[threadParameter->ctLen]; + uint8_t tag[threadParameter->tagLen]; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(threadParameter->algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, threadParameter->key, threadParameter->keyLen, threadParameter->iv, + threadParameter->ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, threadParameter->aad, threadParameter->aadLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, threadParameter->pt, threadParameter->ptLen, (uint8_t *)out, &outLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Ct", out, threadParameter->ctLen, threadParameter->ct, threadParameter->ctLen); + ASSERT_COMPARE("Compare Enc Tag", tag, tagLen, threadParameter->tag, threadParameter->tagLen); + + CRYPT_EAL_CipherDeinit(ctx); + + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, threadParameter->key, threadParameter->keyLen, threadParameter->iv, + threadParameter->ivLen, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, threadParameter->aad, threadParameter->aadLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, threadParameter->ct, threadParameter->ctLen, (uint8_t *)out, &outLen) == + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)tag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Pt", out, threadParameter->ptLen, threadParameter->pt, threadParameter->ptLen); + ASSERT_COMPARE("Compare Dec Tag", tag, tagLen, threadParameter->tag, threadParameter->tagLen); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} + +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_API_TC001(int id, int keyLen, int ivLen) +{ + uint8_t key[32] = { 0 }; // The maximum length of the key is 32 bytes. + uint8_t iv[256] = { 0 }; // The maximum length of the iv is 256 bytes. + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, (uint8_t *)iv, ivLen, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, 0) != CRYPT_SUCCESS); + // Repeat the settings. + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, (uint8_t *)iv, ivLen) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_API_TC002(int id, int keyLen) +{ + CRYPT_EAL_CipherCtx *ctx = NULL; + uint8_t key[32] = { 0 }; // The maximum length of the key is 32 bytes. + uint8_t iv[256] = { 0 }; // The maximum length of the iv is 256 bytes. + TestMemInit(); + ASSERT_TRUE(CRYPT_EAL_CipherNewCtx(99) == NULL); // 99 Indicates an invalid algorithm ID. + ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + + // 256 indicates the IV length. + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, NULL, keyLen, (uint8_t *)iv, 256, true) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, 0, (uint8_t *)iv, 256, true) != + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, NULL, 256, true) != + CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, (uint8_t *)iv, 0, true) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(NULL, (uint8_t *)iv, 256) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(ctx, NULL, 256) != CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherReinit(NULL, (uint8_t *)iv, 0) != CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_API_TC003(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; // The maximum length of the key is 32 bytes. + uint8_t iv[256] = { 0 }; // The maximum length of the iv is 256 bytes. + uint8_t data[256]; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, data, sizeof(data)) != CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_API_TC004(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; // The maximum length of the key is 32 bytes. + uint8_t iv[13] = { 0 }; + uint8_t data[256] = { 0 }; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, NULL, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, data, sizeof(data)) != CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_API_TC005(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; // The maximum length of the key is 32 bytes. + uint8_t iv[13] = { 0 }; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, NULL, 0) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, NULL, 0) != CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_API_TC006(int id, int keyLen) +{ + TestMemInit(); + uint8_t key[32] = { 0 }; // The maximum length of the key is 32 bytes. + uint8_t iv[13] = { 0 }; + uint8_t data[256] = { 0 }; + uint8_t out[256] = { 0 }; + uint32_t outLen = sizeof(out); + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, (uint8_t *)key, keyLen, iv, sizeof(iv), true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, data, sizeof(data), out, &outLen) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_GCM_FUNC_TC001 + * @title Test on the same address in plaintext and ciphertext + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, and set tag len. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, and set aad. Expected result 4 is obtained. + * 5.Call the Update interface, ctx is not NULL, and encrypt data. Expected result 5 is obtained. + * 6.Compare the ciphertext. Expected result 6 is obtained. + * 7.Compare the tag. Expected result 7 is obtained. + * 8.Call the Deinit interface and Call the Init interface. Expected result 8 is obtained. + * 9.Call the Ctrl interface set tag len. Expected result 9 is obtained. + * 10.Call the Ctrl interface set aad. Expected result 10 is obtained. + * 11.Call the Update interface to decrypt data. Expected result 11 is obtained. + * 12.Compare the plaintext. Expected result 12 is obtained. + * 13.Compare the tag. Expected result 13 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Success. Return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Success. Return CRYPT_SUCCESS. + * 6.Consistent with expected vector. + * 7.Consistent with expected vector. + * 8.Success, Return CRYPT_SUCCESS + * 9.Success, Return CRYPT_SUCCESS + * 10.Success, Return CRYPT_SUCCESS + * 11.Success, Return CRYPT_SUCCESS + * 12.Consistent with expected vector. + * 13.Consistent with expected vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_FUNC_TC001(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag) +{ + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + uint8_t *outTag = NULL; + uint8_t *out = NULL; + uint32_t tagLen = tag->len; + uint32_t outLen = ct->len; + + out = (uint8_t *)malloc(outLen * sizeof(uint8_t)); + ASSERT_TRUE(out != NULL); + outTag = (uint8_t *)malloc(sizeof(uint8_t) * tagLen); + ASSERT_TRUE(outTag != NULL); + ASSERT_TRUE(memcpy_s(out, outLen, pt->x, pt->len) == EOK); + ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, out, pt->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Ct", out, ct->len, ct->x, ct->len); + ASSERT_COMPARE("Compare Enc Tag", outTag, tagLen, tag->x, tag->len); + + CRYPT_EAL_CipherDeinit(ctx); + ASSERT_TRUE(memcpy_s(out, outLen, ct->x, ct->len) == EOK); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, out, ct->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + ASSERT_COMPARE("Compare Pt", out, pt->len, pt->x, pt->len); + ASSERT_COMPARE("Compare Dec Tag", outTag, tagLen, tag->x, tag->len); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + free(out); + free(outTag); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_GCM_FUNC_TC002 + * @title Multi-thread Test + * @precon Registering memory-related functions. + * @brief + * 1.Start three threads. Expected result 1 is obtained. + * 2.Call the eal interface in the thread for encryption. Expected result 2 is obtained. + * 3.Call the eal interface in the thread for decryption. Expected result 2 is obtained. + * @expect + * 1.Success. + * 2.The encryption is successful. The ciphertext and tag are the same as the vector. + * 3.The decryption is successful. The plaintext and tag are consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_GCM_FUNC_TC002(int algId, Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag) +{ + int ret; + TestMemInit(); + const uint32_t threadNum = 3; // Number of threads. + pthread_t thrd[threadNum]; + ThreadParameter arg[3] = { + // 3 threads. + {.key = key->x, .iv = iv->x, .aad = aad->x, .pt = pt->x, .ct = ct->x, .tag = tag->x, + .keyLen = key->len, .ivLen = iv->len, .aadLen = aad->len, + .ptLen = pt->len, .ctLen = ct->len, .tagLen = tag->len, + .algId = algId}, + {.key = key->x, .iv = iv->x, .aad = aad->x, .pt = pt->x, .ct = ct->x, .tag = tag->x, + .keyLen = key->len, .ivLen = iv->len, .aadLen = aad->len, + .ptLen = pt->len, .ctLen = ct->len, .tagLen = tag->len, + .algId = algId}, + {.key = key->x, .iv = iv->x, .aad = aad->x, .pt = pt->x, .ct = ct->x, .tag = tag->x, + .keyLen = key->len, .ivLen = iv->len, .aadLen = aad->len, + .ptLen = pt->len, .ctLen = ct->len, .tagLen = tag->len, + .algId = algId}, + }; + for (uint32_t i = 0; i < threadNum; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)MultiThreadTest, &arg[i]); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < threadNum; i++) { + pthread_join(thrd[i], NULL); + } + +exit: + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/gcm/test_suite_sdv_gcm.data b/testcode/sdv/testcase/crypto/gcm/test_suite_sdv_gcm.data new file mode 100644 index 00000000..2984dca8 --- /dev/null +++ b/testcode/sdv/testcase/crypto/gcm/test_suite_sdv_gcm.data @@ -0,0 +1,71 @@ +SDV_CRYPTO_GCM_API_TC001_AESGCM128 +SDV_CRYPTO_GCM_API_TC001:CRYPT_CIPHER_AES128_GCM:16:1 + +SDV_CRYPTO_GCM_API_TC001_AESGCM192 +SDV_CRYPTO_GCM_API_TC001:CRYPT_CIPHER_AES192_GCM:24:4 + +SDV_CRYPTO_GCM_API_TC001_AESGCM256 +SDV_CRYPTO_GCM_API_TC001:CRYPT_CIPHER_AES256_GCM:32:256 + +SDV_CRYPTO_GCM_API_TC002_AESGCM128 +SDV_CRYPTO_GCM_API_TC002:CRYPT_CIPHER_AES128_GCM:16 + +SDV_CRYPTO_GCM_API_TC002_AESGCM192 +SDV_CRYPTO_GCM_API_TC002:CRYPT_CIPHER_AES192_GCM:24 + +SDV_CRYPTO_GCM_API_TC002_AESGCM256 +SDV_CRYPTO_GCM_API_TC002:CRYPT_CIPHER_AES256_GCM:32 + +SDV_CRYPTO_GCM_API_TC003_AESGCM256 +SDV_CRYPTO_GCM_API_TC003:CRYPT_CIPHER_AES128_GCM:16 + +SDV_CRYPTO_GCM_API_TC003_AESGCM256 +SDV_CRYPTO_GCM_API_TC003:CRYPT_CIPHER_AES192_GCM:24 + +SDV_CRYPTO_GCM_API_TC003_AESGCM256 +SDV_CRYPTO_GCM_API_TC003:CRYPT_CIPHER_AES256_GCM:32 + +SDV_CRYPTO_GCM_API_TC004_AESGCM128 +SDV_CRYPTO_GCM_API_TC004:CRYPT_CIPHER_AES128_GCM:16 + +SDV_CRYPTO_GCM_API_TC004_AESGCM192 +SDV_CRYPTO_GCM_API_TC004:CRYPT_CIPHER_AES192_GCM:24 + +SDV_CRYPTO_GCM_API_TC004_AESGCM256 +SDV_CRYPTO_GCM_API_TC004:CRYPT_CIPHER_AES256_GCM:32 + +SDV_CRYPTO_GCM_API_TC005_AESGCM128 +SDV_CRYPTO_GCM_API_TC005:CRYPT_CIPHER_AES128_GCM:16 + +SDV_CRYPTO_GCM_API_TC005_AESGCM192 +SDV_CRYPTO_GCM_API_TC005:CRYPT_CIPHER_AES192_GCM:24 + +SDV_CRYPTO_GCM_API_TC005_AESGCM256 +SDV_CRYPTO_GCM_API_TC005:CRYPT_CIPHER_AES256_GCM:32 + +SDV_CRYPTO_GCM_API_TC006_AESGCM128 +SDV_CRYPTO_GCM_API_TC006:CRYPT_CIPHER_AES128_GCM:16 + +SDV_CRYPTO_GCM_API_TC006_AESGCM192 +SDV_CRYPTO_GCM_API_TC006:CRYPT_CIPHER_AES192_GCM:24 + +SDV_CRYPTO_GCM_API_TC006_AESGCM256 +SDV_CRYPTO_GCM_API_TC006:CRYPT_CIPHER_AES256_GCM:32 + +SDV_CRYPTO_GCM_FUNC_TC001 CRYPT_CIPHER_AES128_GCM Ciphertext plaintext same address +SDV_CRYPTO_GCM_FUNC_TC001:CRYPT_CIPHER_AES128_GCM:"eeb31627acc233b046bc2847121ff579":"ad":"a51530c16bbb3d8a2b60e2d313beb194":"4e43d4466dd53525c758572e3f1d245212ee1d1096372fa838525bce09cd8ca8":"fa05a2ecfe305c9a6bdebcf7a853162bc78988eb167250080f613d09f1f44f71":"b7edf498dc307deb8a4d7e659f111f81" + +SDV_CRYPTO_GCM_FUNC_TC001 CRYPT_CIPHER_AES192_GCM Ciphertext plaintext same address +SDV_CRYPTO_GCM_FUNC_TC001:CRYPT_CIPHER_AES192_GCM:"163d8abb58a367fa86e8cd334c74389c7cdaea4f2acbc0fb":"94":"bf8c1a912204e882e544bdb3b82a256a":"acb1ea7147d18bd39f2fe1f74c8518bedf64e52ba3ca53cb8d6414268f40ffa5":"8ecab49ea32d4ef743756fcc83236ee234ea20a26ce2bf804a3f1a28a33d6f07":"661c00551896bbfe870aedf439ca02d8" + +SDV_CRYPTO_GCM_FUNC_TC001 CRYPT_CIPHER_AES256_GCM Ciphertext plaintext same address +SDV_CRYPTO_GCM_FUNC_TC001:CRYPT_CIPHER_AES256_GCM:"30551beb92cc71dff765b64797045516dce5d95baf67c74f16b54478f6687cb6":"23":"05ceecf51d61f37edb8fa5f161792749":"b31b6b3502b32b931dab75690f0044926929743b4834592a3f899612ef351c41":"ccbf68c602c7bebac9845ae5aee1cd55fd02961c7abc25c1f6d6198e6bd70084":"9eded0f68a956059f4f9545cc95e9007" + +SDV_CRYPTO_GCM_FUNC_TC002 CRYPT_CIPHER_AES128_GCM Multithreading test +SDV_CRYPTO_GCM_FUNC_TC002:CRYPT_CIPHER_AES128_GCM:"eeb31627acc233b046bc2847121ff579":"ad":"a51530c16bbb3d8a2b60e2d313beb194":"4e43d4466dd53525c758572e3f1d245212ee1d1096372fa838525bce09cd8ca8":"fa05a2ecfe305c9a6bdebcf7a853162bc78988eb167250080f613d09f1f44f71":"b7edf498dc307deb8a4d7e659f111f81" + +SDV_CRYPTO_GCM_FUNC_TC002 CRYPT_CIPHER_AES192_GCM Multithreading test +SDV_CRYPTO_GCM_FUNC_TC002:CRYPT_CIPHER_AES192_GCM:"163d8abb58a367fa86e8cd334c74389c7cdaea4f2acbc0fb":"94":"bf8c1a912204e882e544bdb3b82a256a":"acb1ea7147d18bd39f2fe1f74c8518bedf64e52ba3ca53cb8d6414268f40ffa5":"8ecab49ea32d4ef743756fcc83236ee234ea20a26ce2bf804a3f1a28a33d6f07":"661c00551896bbfe870aedf439ca02d8" + +SDV_CRYPTO_GCM_FUNC_TC002 CRYPT_CIPHER_AES256_GCM Multithreading test +SDV_CRYPTO_GCM_FUNC_TC002:CRYPT_CIPHER_AES256_GCM:"30551beb92cc71dff765b64797045516dce5d95baf67c74f16b54478f6687cb6":"23":"05ceecf51d61f37edb8fa5f161792749":"b31b6b3502b32b931dab75690f0044926929743b4834592a3f899612ef351c41":"ccbf68c602c7bebac9845ae5aee1cd55fd02961c7abc25c1f6d6198e6bd70084":"9eded0f68a956059f4f9545cc95e9007" diff --git a/testcode/sdv/testcase/crypto/hkdf/test_suite_sdv_eal_kdf_hkdf.c b/testcode/sdv/testcase/crypto/hkdf/test_suite_sdv_eal_kdf_hkdf.c new file mode 100644 index 00000000..351e5981 --- /dev/null +++ b/testcode/sdv/testcase/crypto/hkdf/test_suite_sdv_eal_kdf_hkdf.c @@ -0,0 +1,138 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "securec.h" +#include "crypt_eal_kdf.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +/* END_HEADER */ + +#define DATA_LEN (64) + +static uint32_t GetMaxKeyLen(int algId) +{ + switch (algId) { + case CRYPT_MAC_HMAC_SHA1: + return 5100; + case CRYPT_MAC_HMAC_SHA224: + return 7140; + case CRYPT_MAC_HMAC_SHA256: + return 8160; + case CRYPT_MAC_HMAC_SHA384: + return 12240; + case CRYPT_MAC_HMAC_SHA512: + return 16320; + default: + return 0; + } +} + +/** + * @test SDV_CRYPT_EAL_KDF_HKDF_API_TC001 + * @title pbkdf2 api test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_Hkdf and set the key length to 0, expected result 1. + * 2.Call CRYPT_EAL_Hkdf and set the key is null but keyLen not 0, expected result 2. + * 3.Call CRYPT_EAL_Hkdf and set the salt length to 0, expected result 3. + * 4.Call CRYPT_EAL_Hkdf and set the salt is null but saltLen not 0, expected result 4. + * 5.Call CRYPT_EAL_Hkdf and set the info length to 0, expected result 5. + * 6.Call CRYPT_EAL_Hkdf and set the info is null but infoLen not 0, expected result 6. + * 7.Call CRYPT_EAL_Hkdf and output is null or outlen is 0, expected result 7. + * 8.Call CRYPT_EAL_Hkdf length of the derived key exceeds the maximum, expected result 8. + * 9.Call CRYPT_EAL_Hkdf using an incorrect id, expected result 9. + * @expect + * 1.Return CRYPT_SUCCESS. + * 2.Return CRYPT_NULL_INPUT. + * 3.Return CRYPT_SUCCESS. + * 4.Return CRYPT_NULL_INPUT. + * 5.Return CRYPT_SUCCESS. + * 6.Return CRYPT_NULL_INPUT. + * 7.return CRYPT_NULL_INPUT. + * 8.Return CRYPT_HKDF_DKLEN_OVERFLOW. + * 9.Return CRYPT_EAL_ERR_ALGID. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_HKDF_API_TC001(int algId) +{ + TestMemInit(); + uint32_t keyLen = DATA_LEN; + uint8_t key[DATA_LEN]; + uint32_t saltLen = DATA_LEN; + uint8_t salt[DATA_LEN]; + uint32_t infoLen = DATA_LEN; + uint8_t info[DATA_LEN]; + uint32_t outLen = DATA_LEN; + uint8_t out[DATA_LEN]; + + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, NULL, 0, salt, saltLen, info, infoLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, 0, salt, saltLen, info, infoLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, NULL, keyLen, salt, saltLen, info, infoLen, out, outLen), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, NULL, 0, info, infoLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, 0, info, infoLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, NULL, saltLen, info, infoLen, out, outLen), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, NULL, 0, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, info, 0, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, NULL, infoLen, out, outLen), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, info, infoLen, NULL, outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, info, infoLen, out, 0), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, info, infoLen, out, outLen), CRYPT_SUCCESS); + + outLen = GetMaxKeyLen(algId) + 1; + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key, keyLen, salt, saltLen, info, infoLen, out, outLen), + CRYPT_HKDF_DKLEN_OVERFLOW); + outLen = DATA_LEN; + ASSERT_EQ(CRYPT_EAL_Hkdf(CRYPT_MAC_MAX, key, keyLen, salt, saltLen, info, infoLen, out, outLen), + CRYPT_EAL_ERR_ALGID); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001 + * @title Perform the vector test to check whether the calculation result is consistent with the standard output. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_Hkdf get output, expected result 1. +* 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Successful. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001(int algId, Hex *key, Hex *salt, Hex *info, Hex *result) +{ + if (IsHmacAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + uint32_t outLen = result->len; + uint8_t *out = malloc(outLen * sizeof(uint8_t)); + ASSERT_TRUE(out != NULL); + ASSERT_EQ(CRYPT_EAL_Hkdf(algId, key->x, key->len, salt->x, salt->len, info->x, info->len, out, outLen), + CRYPT_SUCCESS); + ASSERT_COMPARE("result cmp", out, outLen, result->x, result->len); +exit: + if (out != NULL) { + free(out); + } +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/hkdf/test_suite_sdv_eal_kdf_hkdf.data b/testcode/sdv/testcase/crypto/hkdf/test_suite_sdv_eal_kdf_hkdf.data new file mode 100644 index 00000000..8b3bbbb9 --- /dev/null +++ b/testcode/sdv/testcase/crypto/hkdf/test_suite_sdv_eal_kdf_hkdf.data @@ -0,0 +1,35 @@ +SDV_CRYPT_EAL_KDF_HKDF_API_TC001 api CRYPT_MAC_HMAC_SHA1 test +SDV_CRYPT_EAL_KDF_HKDF_API_TC001:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_KDF_HKDF_API_TC001 api CRYPT_MAC_HMAC_SHA224 test +SDV_CRYPT_EAL_KDF_HKDF_API_TC001:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_KDF_HKDF_API_TC001 api CRYPT_MAC_HMAC_SHA256 test +SDV_CRYPT_EAL_KDF_HKDF_API_TC001:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_KDF_HKDF_API_TC001 api CRYPT_MAC_HMAC_SHA384 test +SDV_CRYPT_EAL_KDF_HKDF_API_TC001:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_KDF_HKDF_API_TC001 api CRYPT_MAC_HMAC_SHA512 test +SDV_CRYPT_EAL_KDF_HKDF_API_TC001:CRYPT_MAC_HMAC_SHA512 + +Vector test for rfc5869 SHA-256 #1 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865" + +Vector test for rfc5869 SHA-256 #2 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87" + +Vector test for rfc5869 SHA-256 #3 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8" + +Vector test for rfc5869 SHA-1 #1 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896" + +Vector test for rfc5869 SHA-1 #2 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4" + +Vector test for rfc5869 SHA-1 #3 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918" + +Vector test for rfc5869 SHA-1 #4 +SDV_CRYPT_EAL_KDF_HKDF_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48" diff --git a/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.base.c b/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.base.c new file mode 100644 index 00000000..e9a72303 --- /dev/null +++ b/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.base.c @@ -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 +#include "securec.h" +#include "crypt_eal_mac.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +#include "crypt_sha1.h" +#include "crypt_sha2.h" +#include "crypt_sha3.h" +#include "crypt_sm3.h" +#include "crypt_md5.h" + +#define TEST_FAIL (-1) +#define TEST_SUCCESS (0) +#define DATA_MAX_LEN (65538) + +uint32_t GetMacLen(int algId) +{ + switch (algId) { +#ifdef HITLS_CRYPTO_MD5 + case CRYPT_MAC_HMAC_MD5: + return CRYPT_MD5_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SHA1 + case CRYPT_MAC_HMAC_SHA1: + return CRYPT_SHA1_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SHA224 + case CRYPT_MAC_HMAC_SHA224: + return CRYPT_SHA2_224_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SHA256 + case CRYPT_MAC_HMAC_SHA256: + return CRYPT_SHA2_256_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SHA384 + case CRYPT_MAC_HMAC_SHA384: + return CRYPT_SHA2_384_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SHA512 + case CRYPT_MAC_HMAC_SHA512: + return CRYPT_SHA2_512_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SM3 + case CRYPT_MAC_HMAC_SM3: + return CRYPT_SM3_DIGESTSIZE; +#endif +#ifdef HITLS_CRYPTO_SHA3 + case CRYPT_MAC_HMAC_SHA3_224: + return CRYPT_SHA3_224_DIGESTSIZE; + case CRYPT_MAC_HMAC_SHA3_256: + return CRYPT_SHA3_256_DIGESTSIZE; + case CRYPT_MAC_HMAC_SHA3_384: + return CRYPT_SHA3_384_DIGESTSIZE; + case CRYPT_MAC_HMAC_SHA3_512: + return CRYPT_SHA3_512_DIGESTSIZE; +#endif + default: + return 0; + } +} + +typedef struct { + uint8_t *data; + uint8_t *mac; + uint8_t *key; + uint32_t dataLen; + uint32_t macLen; + uint32_t keyLen; + int algId; +} ThreadParameter; + +void MultiThreadTest(void *arg) +{ + ThreadParameter *threadParameter = (ThreadParameter *)arg; + uint32_t outLen = GetMacLen(threadParameter->algId); + uint8_t out[outLen]; + CRYPT_EAL_MacCtx *ctx = NULL; + ctx = CRYPT_EAL_MacNewCtx(threadParameter->algId); + ASSERT_TRUE(ctx != NULL); + for (uint32_t i = 0; i < 10; i++) { + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, threadParameter->key, threadParameter->keyLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, threadParameter->data, threadParameter->dataLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, out, &outLen), CRYPT_SUCCESS); + ASSERT_COMPARE("hash result cmp", out, outLen, threadParameter->mac, threadParameter->macLen); + } + +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} diff --git a/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.c b/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.c new file mode 100644 index 00000000..d437bbb7 --- /dev/null +++ b/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.c @@ -0,0 +1,422 @@ +/* + * 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_BASE test_suite_sdv_eal_mac_hmac */ + +/* BEGIN_HEADER */ + +/* END_HEADER */ + +#define HMAC_MAX_BUFF_LEN (64 + 1) // CRYPT_SHA2_512_DIGESTSIZE + 1 +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC001 + * @title Create hmac context test. + * @precon nan + * @brief + * 1.Create context with invalid id, expected result 1. + * 2.Create context using CRYPT_MAC_AlgId, expected result 2. + * @expect + * 1.The result is NULL. + * 2.Create successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC001(void) +{ + TestMemInit(); + CRYPT_MAC_AlgId testIds[] = { CRYPT_MAC_HMAC_MD5, CRYPT_MAC_HMAC_SHA1, CRYPT_MAC_HMAC_SHA224, + CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512, CRYPT_MAC_HMAC_SM3, + CRYPT_MAC_HMAC_SHA3_224, CRYPT_MAC_HMAC_SHA3_256, CRYPT_MAC_HMAC_SHA3_384, CRYPT_MAC_HMAC_SHA3_512 }; + + CRYPT_EAL_MacCtx *ctx = NULL; + + for (int i = 0; i < (int)(sizeof(testIds) / sizeof(CRYPT_MAC_AlgId)); i++) { + ctx = CRYPT_EAL_MacNewCtx(testIds[i]); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_MacFreeCtx(ctx); + } + + ctx = CRYPT_EAL_MacNewCtx(CRYPT_MAC_MAX); + ASSERT_TRUE(ctx == NULL); + +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC002 + * @title hmac init test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MacInit,ctx is NULL or key is NULL but keylen not 0, expected result 2. + * 3.Call CRYPT_EAL_MacInit,key is NULL and keyLen is 0, expected result 3. + * 4.Call CRYPT_EAL_MacInit normally, expected result 4. + * @expect + * 1.Create successful. + * 2.Return CRYPT_NULL_INPUT. + * 3.Successful. + * 4.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC002(int algId) +{ + TestMemInit(); + const uint32_t len = GetMacLen(algId); + uint8_t key[HMAC_MAX_BUFF_LEN]; + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MacInit(NULL, key, len), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, NULL, len), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, (uint8_t *)key, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC003 + * @title hmac init test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MacInit repeatedly, expected result 2. + * 3.Call CRYPT_EAL_MacInit after update, expected result 3. + * 4.Call CRYPT_EAL_MacReinit, expected result 4. + * @expect + * 1.Create successful. + * 2.Successful. + * 3.Successful. + * 4.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC003(int algId) +{ + TestMemInit(); + const uint32_t len = GetMacLen(algId); + uint32_t macLen = len; + const uint32_t dataLen = HMAC_MAX_BUFF_LEN; + uint8_t key[HMAC_MAX_BUFF_LEN]; + uint8_t mac[HMAC_MAX_BUFF_LEN]; + uint8_t data[HMAC_MAX_BUFF_LEN]; + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data, dataLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + + CRYPT_EAL_MacDeinit(ctx); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacReinit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC004 + * @title hmac init test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MacUpdate before init, expected result 2. + * 3.Call CRYPT_EAL_MacUpdate,ctx or data is NULL, expected result 3. + * 4.Call CRYPT_EAL_MacUpdate,dataLen is 0, expected result 4. + * 5.Call CRYPT_EAL_MacUpdate normally, expected result 5. + * @expect + * 1.Create successful. + * 2.Return CRYPT_EAL_ERR_STATE. + * 3.Return CRYPT_NULL_INPUT. + * 4.Successful. + * 5.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC004(int algId) +{ + TestMemInit(); + const uint32_t len = GetMacLen(algId); + const uint32_t dataLen = HMAC_MAX_BUFF_LEN; + uint8_t key[HMAC_MAX_BUFF_LEN]; + uint8_t data[HMAC_MAX_BUFF_LEN]; + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data, dataLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacUpdate(NULL, data, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, NULL, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data, dataLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC005 + * @title hmac final test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MacFinal before init, expected result 2. + * 3.Call CRYPT_EAL_MacFinal,ctx or mac is NULL, expected result 3. + * 4.Call CRYPT_EAL_MacFinal,macLen not enough, expected result 4. + * 5.Call CRYPT_EAL_MacFinal normally, expected result 5. + * @expect + * 1.Create successful. + * 2.Return CRYPT_EAL_ERR_STATE. + * 3.Return CRYPT_NULL_INPUT. + * 4.Return CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH. + * 5.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC005(int algId) +{ + TestMemInit(); + const uint32_t len = GetMacLen(algId); + uint32_t macLen = len; + uint8_t key[HMAC_MAX_BUFF_LEN]; + uint8_t mac[HMAC_MAX_BUFF_LEN]; + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacFinal(NULL, mac, &macLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, NULL, &macLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, NULL), CRYPT_NULL_INPUT); + macLen = GetMacLen(algId) - 1; + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH); + macLen = GetMacLen(algId) + 1; + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_EAL_ERR_STATE); + +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC006 + * @title get mac len test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the ctx and init, expected result 1. + * 2.Call CRYPT_EAL_GetMacLen,the input parameter is null, expected result 2. + * 3.Call CRYPT_EAL_GetMacLen after init,update final and deinit, expected result 3. + * @expect + * 1.Create successful. + * 2.Return 0. + * 3.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC006(int algId) +{ + TestMemInit(); + const uint32_t len = GetMacLen(algId); + uint8_t key[HMAC_MAX_BUFF_LEN]; + const uint32_t dataLen = HMAC_MAX_BUFF_LEN; + uint8_t data[HMAC_MAX_BUFF_LEN]; + uint32_t macLen = len; + uint8_t mac[HMAC_MAX_BUFF_LEN]; + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_EQ(CRYPT_EAL_GetMacLen(NULL), 0); + ASSERT_EQ(CRYPT_EAL_GetMacLen(ctx), GetMacLen(algId)); + + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_GetMacLen(ctx), GetMacLen(algId)); + + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data, dataLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_GetMacLen(ctx), GetMacLen(algId)); + + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_GetMacLen(ctx), GetMacLen(algId)); + + CRYPT_EAL_MacDeinit(ctx); + ASSERT_EQ(CRYPT_EAL_GetMacLen(ctx), GetMacLen(algId)); +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_API_TC007 + * @title reinit ctx test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the ctx and init, expected result 1. + * 2.Call CRYPT_EAL_MacReinit,the input parameter is null, expected result 2. + * 3.Call CRYPT_EAL_MacReinit after init,update final, expected result 3. + * 3.Call CRYPT_EAL_MacReinit after deinit, expected result 4. + * @expect + * 1.Create successful. + * 2.Return 0. + * 3.Successful. + * 4.Return CRYPT_EAL_ERR_STATE. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_API_TC007(int algId) +{ + TestMemInit(); + const uint32_t len = GetMacLen(algId); + uint32_t macLen = len; + const uint32_t dataLen = HMAC_MAX_BUFF_LEN; + uint8_t key[HMAC_MAX_BUFF_LEN]; + uint8_t mac[HMAC_MAX_BUFF_LEN]; + uint8_t data[HMAC_MAX_BUFF_LEN]; + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MacReinit(NULL), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MacReinit(ctx), CRYPT_EAL_ERR_STATE); + + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key, len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacReinit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data, dataLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacReinit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacReinit(ctx), CRYPT_SUCCESS); + + CRYPT_EAL_MacDeinit(ctx); + ASSERT_EQ(CRYPT_EAL_MacReinit(ctx), CRYPT_EAL_ERR_STATE); +exit: + CRYPT_EAL_MacFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_FUN_TC001 + * @title Perform the vector test to check whether the calculation result is consistent with the standard output. + * @precon nan + * @brief + * 1.Calculate the hmac of each group of data, expected result 1. +* 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hmac calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_FUN_TC001(int algId, Hex *key, Hex *data, Hex *vecMac) +{ + if (IsHmacAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + uint32_t macLen = GetMacLen(algId); + uint8_t *mac = malloc(macLen); + ASSERT_TRUE(mac != NULL); + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key->x, key->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data->x, data->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_SUCCESS); + ASSERT_COMPARE("mac1 result cmp", mac, macLen, vecMac->x, vecMac->len); +exit: + CRYPT_EAL_MacFreeCtx(ctx); + free(mac); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_HMAC_FUN_TC002 + * @title Hash calculation for multiple updates,comparison with standard results. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MacNewCtx to create a ctx and initialize, expected result 1. + * 2.Call CRYPT_EAL_MacUpdate to calculate the hash of a data segmentxpected result 2. + * 3.Call CRYPT_EAL_MacUpdate to calculate the next data segmentxpected result 3. + * 4.Call CRYPT_EAL_MacUpdate to calculate the next data segmentxpected result 4. + * 5.Call CRYPT_EAL_MacFinal get the result, expected result 5. + * @expect + * 1.Successful + * 2.Successful + * 3.Successful + * 4.Successful + * 5.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_FUN_TC002(int algId, Hex *key, Hex *data1, Hex *data2, Hex *data3, Hex *vecMac) +{ + TestMemInit(); + uint32_t macLen = GetMacLen(algId); + uint8_t *mac = malloc(macLen); + ASSERT_TRUE(mac != NULL); + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MacInit(ctx, key->x, key->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data1->x, data1->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data2->x, data2->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacUpdate(ctx, data3->x, data3->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MacFinal(ctx, mac, &macLen), CRYPT_SUCCESS); + ASSERT_COMPARE("mac1 result cmp", mac, macLen, vecMac->x, vecMac->len); + CRYPT_EAL_MacDeinit(ctx); +exit: + CRYPT_EAL_MacFreeCtx(ctx); + free(mac); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA1_FUN_TC003 + * @title Test multi-thread hmac calculation. + * @precon nan + * @brief + * 1.Create two threads and calculate the hmac, expected result 1. + * 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hmac calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_HMAC_FUN_TC003(int algId, Hex *key1, Hex *data1, Hex *vecMac1, Hex *key2, Hex *data2, Hex *vecMac2) +{ + int ret; + TestMemInit(); + const uint32_t threadNum = 2; // 2 threads + pthread_t thrd[2]; + ThreadParameter arg[2] = { + {.data = data1->x, .key = key1->x, .mac = vecMac1->x, .dataLen = data1->len, + .keyLen = key1->len, .macLen = vecMac1->len, .algId = algId}, + {.data = data2->x, .key = key2->x, .mac = vecMac2->x, .dataLen = data2->len, + .keyLen = key2->len, .macLen = vecMac2->len, .algId = algId}, + }; + for (uint32_t i = 0; i < threadNum; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)MultiThreadTest, &arg[i]); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < threadNum; i++) { + pthread_join(thrd[i], NULL); + } + +exit: + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.data b/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.data new file mode 100644 index 00000000..6d358d84 --- /dev/null +++ b/testcode/sdv/testcase/crypto/hmac/test_suite_sdv_eal_mac_hmac.data @@ -0,0 +1,356 @@ +SDV_CRYPT_EAL_HMAC_API_TC001 create context test +SDV_CRYPT_EAL_HMAC_API_TC001: + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA1 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA224 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA256 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA384 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA512 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA3_224 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA3_256 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA3_384 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA3_512 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA3_512 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC002 CRYPT_MAC_HMAC_SHA3_512 init test +SDV_CRYPT_EAL_HMAC_API_TC002:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA1 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA224 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA256 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA384 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA512 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA3_224 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA3_256 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA3_384 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPT_EAL_HMAC_API_TC003 CRYPT_MAC_HMAC_SHA3_512 Impact of ctx status on init +SDV_CRYPT_EAL_HMAC_API_TC003:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA1 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA224 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA256 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA384 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA512 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA3_224 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA3_256 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA3_384 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPT_EAL_HMAC_API_TC004 CRYPT_MAC_HMAC_SHA3_512 uptade test +SDV_CRYPT_EAL_HMAC_API_TC004:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA1 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA224 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA256 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA384 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA512 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA3_224 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA3_256 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA3_384 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPT_EAL_HMAC_API_TC005 CRYPT_MAC_HMAC_SHA3_512 final test +SDV_CRYPT_EAL_HMAC_API_TC005:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA1 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA224 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA256 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA384 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA512 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA3_224 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA3_256 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA3_384 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPT_EAL_HMAC_API_TC006 CRYPT_MAC_HMAC_SHA3_512 get Mac Len test +SDV_CRYPT_EAL_HMAC_API_TC006:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA1 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA1 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA224 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA224 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA256 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA384 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA512 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA512 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA3_224 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA3_224 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA3_256 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA3_256 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA3_384 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA3_384 + +SDV_CRYPT_EAL_HMAC_API_TC007 CRYPT_MAC_HMAC_SHA3_512 reinit test +SDV_CRYPT_EAL_HMAC_API_TC007:CRYPT_MAC_HMAC_SHA3_512 + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #1,all data from rfc2202 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"9294727a3638bb1c13f48ef8158bfc9d" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"750c783e6ab0b503eaa86e310a5db738" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"56be34521d144c88dbb8c733f0e8b3f6" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"697eaf0aca3a3aea3a75164746ffaa79" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"546573742057697468205472756e636174696f6e":"56461ef2342edc00f9bab995690efd4c" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #6 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_MD5 Vector test #7 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_MD5:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d53697a652044617461":"6f630fad67cda0ee1fb1f562db3aa53e" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #1,all data from rfc2202 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"b617318655057264e28bc0b6fb378c8ef146be00" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"effcdf6ae5eb2fa2d27416d5f184df9c259a7c79" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"125d7342b9ac11cd91a39af48aa17b4f63f175d3" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"4c9007f4026250c6bc8414f9bf50c86c2d7235da" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"546573742057697468205472756e636174696f6e":"4c1a03424b55e07fe7f27be1d58bb9324a9a5a04" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #6 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"aa4ae5e15272d00e95705637ce8a3b55ed402112" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA1 Vector test #7 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d53697a652044617461":"e8e99d0f45237d786d6bbaa7965c7808bbff1a91" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA224 Vector test #1,all data from rfc4231 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA224:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA256 Vector test #1 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA384 Vector test #1 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA512 Vector test #1 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA224 Vector test #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA224:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA256 Vector test #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA384 Vector test #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA512 Vector test #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA224 Vector test #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA224:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA256 Vector test #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA384 Vector test #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA512 Vector test #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA224 Vector test #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA224:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA256 Vector test #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA384 Vector test #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA512 Vector test #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA224 Vector test #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA224:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA256 Vector test #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA384 Vector test #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA512 Vector test #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA224 Vector test #6 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA224:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA256 Vector test #6 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA384 Vector test #6 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA512 Vector test #6 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA3_224 Vector test,all data from nist +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA3_224:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"332cfd59347fdb8e576e77260be4aba2d6dc53117b3bfb52c6d18c04" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA3_256 Vector test +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA3_256:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA3_384 Vector test +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA3_384:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"d588a3c51f3f2d906e8298c1199aa8ff6296218127f6b38a90b6afe2c5617725bc99987f79b22a557b6520db710b7f42" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SHA3_512 Vector test +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SHA3_512:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"4efd629d6c71bf86162658f29943b1c308ce27cdfa6db0d9c3ce81763f9cbce5f7ebe9868031db1a8f8eb7b6b95e5c5e3f657a8996c86a2f6527e307f0213196" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SM3 #1 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SM3:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"51b00d1fb49832bfb01c3ce27848e59f871d9ba938dc563b338ca964755cce70" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SM3 #2 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SM3:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"2e87f1d16862e6d964b50a5200bf2b10b764faa9680a296a2405f24bec39f882" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SM3 #3 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SM3:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"7bfeba1b1518329f73aad171e89009fc41d43b66de11e779b5615bfbf0b85973" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SM3 #4 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SM3:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"b4fd844e13342002f0b2e0690ea7741f1497d993a70494cea601e657bedf67a0" + +SDV_CRYPT_EAL_HMAC_FUN_TC001 CRYPT_MAC_HMAC_SM3 #5 +SDV_CRYPT_EAL_HMAC_FUN_TC001:CRYPT_MAC_HMAC_SM3:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"dad342089a24eaa650975de2701754ff513b504f829bac67964915f9efb7c3f1" + +SDV_CRYPT_EAL_HMAC_FUN_TC002 CRYPT_MAC_HMAC_MD5 multiple update +SDV_CRYPT_EAL_HMAC_FUN_TC002:CRYPT_MAC_HMAC_MD5:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcd":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"697eaf0aca3a3aea3a75164746ffaa79" + +SDV_CRYPT_EAL_HMAC_FUN_TC002 CRYPT_MAC_HMAC_SHA1 multiple update +SDV_CRYPT_EAL_HMAC_FUN_TC002:CRYPT_MAC_HMAC_SHA1:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"5465737420":"5573696e67204c6172676572205468616e20426c6f636b2d":"53697a65204b6579202d2048617368204b6579204669727374":"aa4ae5e15272d00e95705637ce8a3b55ed402112" + +SDV_CRYPT_EAL_HMAC_FUN_TC002 CRYPT_MAC_HMAC_SHA512 multiple update +SDV_CRYPT_EAL_HMAC_FUN_TC002:CRYPT_MAC_HMAC_SHA512:"4a656665":"77686174":"20646f2079612077616e742066":"6f72206e6f7468696e673f":"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737" + +SDV_CRYPT_EAL_HMAC_FUN_TC002 CRYPT_MAC_HMAC_SHA3_512 multiple update +SDV_CRYPT_EAL_HMAC_FUN_TC002:CRYPT_MAC_HMAC_SHA3_512:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":"53616d70":"6c65206d65737361676520666f72206b65":"796c656e3c626c6f636b6c656e":"4efd629d6c71bf86162658f29943b1c308ce27cdfa6db0d9c3ce81763f9cbce5f7ebe9868031db1a8f8eb7b6b95e5c5e3f657a8996c86a2f6527e307f0213196" + +SDV_CRYPT_EAL_HMAC_FUN_TC002 CRYPT_MAC_HMAC_SM3 multiple update +SDV_CRYPT_EAL_HMAC_FUN_TC002:CRYPT_MAC_HMAC_SM3:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"53616d706c65206d65737361676520":"666f72206b65796c656e3c62":"6c6f636b6c656e":"dad342089a24eaa650975de2701754ff513b504f829bac67964915f9efb7c3f1" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA1 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA1:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"b617318655057264e28bc0b6fb378c8ef146be00":"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"effcdf6ae5eb2fa2d27416d5f184df9c259a7c79" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA224 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA224:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA256 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA256:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7":"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA384 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA384:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6":"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA512 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA512:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA3_224 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA3_224:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"332cfd59347fdb8e576e77260be4aba2d6dc53117b3bfb52c6d18c04":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"332cfd59347fdb8e576e77260be4aba2d6dc53117b3bfb52c6d18c04" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA3_256 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA3_256:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA3_384 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA3_384:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"d588a3c51f3f2d906e8298c1199aa8ff6296218127f6b38a90b6afe2c5617725bc99987f79b22a557b6520db710b7f42":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"d588a3c51f3f2d906e8298c1199aa8ff6296218127f6b38a90b6afe2c5617725bc99987f79b22a557b6520db710b7f42" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SHA3_512 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SHA3_512:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"4efd629d6c71bf86162658f29943b1c308ce27cdfa6db0d9c3ce81763f9cbce5f7ebe9868031db1a8f8eb7b6b95e5c5e3f657a8996c86a2f6527e307f0213196":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":"53616d706c65206d65737361676520666f72206b65796c656e3c626c6f636b6c656e":"4efd629d6c71bf86162658f29943b1c308ce27cdfa6db0d9c3ce81763f9cbce5f7ebe9868031db1a8f8eb7b6b95e5c5e3f657a8996c86a2f6527e307f0213196" + +SDV_CRYPT_EAL_HMAC_FUN_TC003 CRYPT_MAC_HMAC_SM3 Multithreading test +SDV_CRYPT_EAL_HMAC_FUN_TC003:CRYPT_MAC_HMAC_SM3:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"7bfeba1b1518329f73aad171e89009fc41d43b66de11e779b5615bfbf0b85973":"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"2e87f1d16862e6d964b50a5200bf2b10b764faa9680a296a2405f24bec39f882" diff --git a/testcode/sdv/testcase/crypto/kdf_tls12/test_suite_sdv_eal_kdf_tls12.c b/testcode/sdv/testcase/crypto/kdf_tls12/test_suite_sdv_eal_kdf_tls12.c new file mode 100644 index 00000000..d40f07e5 --- /dev/null +++ b/testcode/sdv/testcase/crypto/kdf_tls12/test_suite_sdv_eal_kdf_tls12.c @@ -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. + */ + +/* BEGIN_HEADER */ + +#include "securec.h" +#include "crypt_eal_kdf.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +/* END_HEADER */ + +#define DATA_LEN (64) + +/** + * @test SDV_CRYPT_EAL_KDF_TLS12_API_TC001 + * @title CRYPT_EAL_KdfTls12 interface test. + * @precon nan + * @brief + * 1.Normal parameter test,the key and label can be empty,parameter limitation see unction declaration, + expected result 1. + * @expect + * 1.The results are as expected, algId only supported CRYPT_MAC_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384, + and CRYPT_MAC_HMAC_SHA512. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_TLS12_API_TC001(int algId) +{ + TestMemInit(); + uint32_t keyLen = DATA_LEN; + uint8_t key[DATA_LEN]; + uint32_t labelLen = DATA_LEN; + uint8_t label[DATA_LEN]; + uint32_t seedLen = DATA_LEN; + uint8_t seed[DATA_LEN]; + uint32_t outLen = DATA_LEN; + uint8_t out[DATA_LEN]; + ASSERT_EQ(CRYPT_EAL_KdfTls12(CRYPT_MAC_HMAC_SHA224, key, keyLen, label, labelLen, seed, seedLen, out, outLen), + CRYPT_EAL_ERR_ALGID); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, labelLen, seed, seedLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, NULL, 0, label, labelLen, seed, seedLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, 0, label, labelLen, seed, seedLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, NULL, keyLen, label, labelLen, seed, seedLen, out, outLen), + CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, NULL, 0, seed, seedLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, 0, seed, seedLen, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, NULL, labelLen, seed, seedLen, out, outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, labelLen, NULL, 0, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, labelLen, seed, 0, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, labelLen, NULL, seedLen, out, outLen), + CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, labelLen, seed, seedLen, NULL, outLen), + CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key, keyLen, label, labelLen, seed, seedLen, out, 0), CRYPT_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001 + * @title CRYPT_EAL_Scrypt vector test. + * @precon nan + * @brief + * 1.Calculate the output using the given parameters, expected result 1. + * 2.Compare the calculated result with the standard value, expected result 2. + * @expect + * 1.Calculation succeeded. + * 2.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001(int algId, Hex *key, Hex *label, Hex *seed, Hex *result) +{ + if (IsHmacAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + uint32_t outLen = result->len; + uint8_t *out = malloc(outLen * sizeof(uint8_t)); + ASSERT_TRUE(out != NULL); + ASSERT_EQ(CRYPT_EAL_KdfTls12(algId, key->x, key->len, label->x, label->len, seed->x, seed->len, out, outLen), + CRYPT_SUCCESS); + ASSERT_COMPARE("result cmp", out, outLen, result->x, result->len); +exit: + if (out != NULL) { + free(out); + } +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/kdf_tls12/test_suite_sdv_eal_kdf_tls12.data b/testcode/sdv/testcase/crypto/kdf_tls12/test_suite_sdv_eal_kdf_tls12.data new file mode 100644 index 00000000..ecd16e81 --- /dev/null +++ b/testcode/sdv/testcase/crypto/kdf_tls12/test_suite_sdv_eal_kdf_tls12.data @@ -0,0 +1,26 @@ +SDV_CRYPT_EAL_KDF_TLS12_API_TC001 api HMAC_SHA256 test +SDV_CRYPT_EAL_KDF_TLS12_API_TC001:CRYPT_MAC_HMAC_SHA256 + +SDV_CRYPT_EAL_KDF_TLS12_API_TC001 api HMAC_SHA384 test +SDV_CRYPT_EAL_KDF_TLS12_API_TC001:CRYPT_MAC_HMAC_SHA384 + +SDV_CRYPT_EAL_KDF_TLS12_API_TC001 api HMAC_SHA512 test +SDV_CRYPT_EAL_KDF_TLS12_API_TC001:CRYPT_MAC_HMAC_SHA512 + +Vector Test for NIST tls.txt HMAC_SHA256 #1 +SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf":"6b657920657870616e73696f6eae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f3986862e1fd91":"f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616":"d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928" + +Vector Test for NIST tls.txt HMAC_SHA256 #2 +SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"918b60d280f8471784392edbb9dd1fef7a78f823672a78fdb62822707e717a6d1ef54ca58f0b3b84a6fa092eb27089dd":"6b657920657870616e73696f6ed2ec44801e16c23e9d4cfe4c5c238523860dcca2b3f7dea5409fb31fceefa713284806ac208958e6fff30ebf99d908cb00fc5af915a19a5b34cac30340031f65":"":"1910e1496131f7ef05a7a568fffe7a3d3073e4f08500c97fce69d1c42a4ccf7553e52bc1ce84b760214f2632fee46ab0c4fb2bbe1214a560c7b041cbf4be44162d559ed8e8b34ab847f66aa5e948bef5a336d9d5c1e58b9ec4484f2024c4c453d87f1e9542556fe4f4615e2bdc20f74af7cf2311bd2a02bd415868339d50414d" + +Vector Test for NIST tls.txt HMAC_SHA384 #1 +SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"b4d49bfa87747fe815457bc3da15073d6ac73389e703079a3503c09e14bd559a5b3c7c601c7365f6ea8c68d3d9596827":"6b657920657870616e73696f6e1b1c8568344a65c30828e7483c0e353e2c68641c9551efae6927d9cd627a107c954b5fe1849c2ede177438261f099a2fcd884d001b9fe1de754364b1f6a6dd8e":"":"10fd89ef689c7ef033387b8a8f3e5e8e7c11f680f6bdd71fbac3246a73e98d45d03185dde686e6b2369e4503e9dc5a6d2cee3e2bf2fa3f41d3de57dff3e197c8a9d5f74cc2d277119d894f8584b07a0a5822f0bd68b3433ec6adaf5c9406c5f3ddbb71bbe17ce98f3d4d5893d3179ef369f57aad908e2bf710639100c3ce7e0c" + +Vector Test for NIST tls.txt HMAC_SHA384 #2 +SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001:CRYPT_MAC_HMAC_SHA384:"2a1d6063b37a458b07746a7b04ed54c9ddeef5f2e488050dfb4b0f38cc5b178e3c20e6a72307efc859bd2e1c24f790c7":"6b657920657870616e73696f6ec68423e2743b91bf9e2e10":"78bab5c5c884bd70983e0272343279e41738e943b5dce4c7973f3b0468d944de1870025bcc130e7832fd3fbfcd40ad287b13ee28f9":"de9f2ce42403605743e84e71b2fba535bbb2020e5899d98773c140c27abbfef4b4754ff01ea10e38604ec621f48a4af14715ee81b0ba10bdbebb5104bbc2411004a2962b0e7f5c2ebb27590678510c06cf880f9f529b164e75be0b7481881089944744bc33a0b8fd35d7f7a4f1dcc1bea500919e42aabb7f84d821fb1f018a4b" + +Vector Test for NIST tls.txt HMAC_SHA512 #1 +SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"a70c5fe8d34b645a20ce98969bd30858e729c77c8a5f05d3e289219d6b5752b75b75e1ca00d3329658d7f188ed1ab7e0":"6b657920657870616e73696f6e11cfbd3b45e5e917c4edbabc27b9feac833bbbacabd079465b2759fab3063330b5c41ac5ebd55d136d916547fee741bc1b509f766d50b29d7378b0cebace3c8a":"":"a56650076e6bdaad7e1ea42d68a0f5ffead9b6b5232ba538767e4cc6a3ae9abcae897b068645496cd620f865ce0879081a98901fb98b112ce1f00165e7d6b3288eb4d4ed9811fdbbc24e290b8e448c71da72498449ea67cfdafd66adc31a89d83cc44cf01c749fb531494ff8cb9a677762a7220e32b7f251fde09841bf97110e" + +Vector Test for NIST tls.txt HMAC_SHA512 #2 +SDV_CRYPT_EAL_KDF_TLS12_FUN_TC001:CRYPT_MAC_HMAC_SHA512:"74348710df03212b648663bd0a2b9940190e59bdb592876c747656b26f36ce0843505b999138459cf921503ab1c2bffb":"6b657920657870616e73696f6e8e111a579904a5c79e6db0832c":"cb8190ee88db5fd722d8b3f96379286a19f94a00ac1cf7a2a6376548eba6b6f69ba9e10ab93cedca87521df83e84269628e45f":"edeed5638bda76490ff7a3d39f8bb8bc25c9811dd8b2bcd67ddd9c588bd7f05fb8c3328bc6a3252d5a4fc6b07444f5bbb39f67a6e193adc45e282e2e40d5ffe77342101f7e414b28babb94e727cbafa0bf2fc1895ca1c3045a6b75e4d0612345988b54821072432a5b835699bba58bf7cbeb1496461fd99bd76bc82e738794b2" diff --git a/testcode/sdv/testcase/crypto/md5/test_suite_sdv_eal_md5.c b/testcode/sdv/testcase/crypto/md5/test_suite_sdv_eal_md5.c new file mode 100644 index 00000000..535c13f4 --- /dev/null +++ b/testcode/sdv/testcase/crypto/md5/test_suite_sdv_eal_md5.c @@ -0,0 +1,275 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "crypt_eal_md.h" +#include "bsl_sal.h" +#include "eal_md_local.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_md5.h" +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_MD5_API_TC001 + * @title update and final test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal before initialization, expected result 2. + * 3.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal use null pointer, expected result 3. + * 4.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal normally, expected result 4. + * @expect + * 1.Create successful. + * 2.Return CRYPT_EAL_ERR_STATE. + * 3.Return CRYPT_NULL_INPUT. + * 4.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD5_API_TC001(void) +{ + TestMemInit(); + uint8_t data[100]; + uint32_t dataLen = sizeof(data); + uint8_t output[CRYPT_MD5_DIGESTSIZE + 1]; + uint32_t outputLen = CRYPT_MD5_DIGESTSIZE; + CRYPT_EAL_MdCTX *md5Ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_MD5); + ASSERT_TRUE(md5Ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_MD5), CRYPT_MD5_DIGESTSIZE); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, data, dataLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outputLen), CRYPT_EAL_ERR_STATE); + + ASSERT_EQ(CRYPT_EAL_MdInit(md5Ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, NULL, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, data, dataLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(NULL, output, &outputLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, NULL, &outputLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, NULL), CRYPT_NULL_INPUT); + + outputLen = CRYPT_MD5_DIGESTSIZE - 1; + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outputLen), CRYPT_MD5_OUT_BUFF_LEN_NOT_ENOUGH); + outputLen = CRYPT_MD5_DIGESTSIZE; + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outputLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdInit(md5Ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, data, dataLen), CRYPT_SUCCESS); + outputLen = CRYPT_MD5_DIGESTSIZE + 1; + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outputLen), CRYPT_SUCCESS); +exit: + CRYPT_EAL_MdFreeCtx(md5Ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_MD5_FUNC_TC001 + * @title CRYPT_EAL_MdFinal test without update. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create ctx, expected result 1. + * 2.Call CRYPT_EAL_MdFinal get results. expected result 2. + * 3.Compare with expected results. expected result 3. + * @expect + * 1.The ctx is created successfully. + * 2.Successful. + * 2.Consistent with expected results. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD5_FUNC_TC001(Hex *hash) +{ + TestMemInit(); + uint8_t output[CRYPT_MD5_DIGESTSIZE]; + uint32_t outLen = CRYPT_MD5_DIGESTSIZE; + + CRYPT_EAL_MdCTX *md5Ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_MD5); + ASSERT_TRUE(md5Ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(md5Ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(outLen, CRYPT_MD5_DIGESTSIZE); + ASSERT_COMPARE("md5", output, outLen, hash->x, hash->len); + +exit: + CRYPT_EAL_MdFreeCtx(md5Ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_MD5_FUNC_TC002 + * @title Perform the vector test to check whether the calculation result is consistent with the standard output. + * @precon nan + * @brief + * 1.Calculate the hash of each group of data, expected result 1. +* 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hash calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD5_FUNC_TC002(Hex *msg, Hex *hash) +{ + TestMemInit(); + uint8_t output[CRYPT_MD5_DIGESTSIZE]; + uint32_t outLen = CRYPT_MD5_DIGESTSIZE; + + CRYPT_EAL_MdCTX *md5Ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_MD5); + ASSERT_TRUE(md5Ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdInit(md5Ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, msg->x, msg->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(outLen, CRYPT_MD5_DIGESTSIZE); + ASSERT_COMPARE("md5", output, outLen, hash->x, hash->len); +exit: + CRYPT_EAL_MdFreeCtx(md5Ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_MD5_FUNC_TC003 + * @title Split the data and update test. + * @precon nan + * @brief + * 1.Create two ctx and initialize them, expected result 1. + * 2.Use ctx1 to update data 100 times, expected result 2. + * 3.Use ctx2 to update all data at once, expected result 3. + * 4.Compare two outputs, expected result 4. + * @expect + * 1.Successful. + * 2.Successful. + * 3.Successful. + * 4.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD5_FUNC_TC003(void) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx1 = NULL; + CRYPT_EAL_MdCTX *ctx2 = NULL; + + ctx1 = CRYPT_EAL_MdNewCtx(CRYPT_MD_MD5); + ASSERT_TRUE(ctx1 != NULL); + + ctx2 = CRYPT_EAL_MdNewCtx(CRYPT_MD_MD5); + ASSERT_TRUE(ctx2 != NULL); + + uint8_t input[5050]; + uint32_t inLenTotal = 0; + uint32_t inLenBase; + uint8_t out1[CRYPT_MD5_DIGESTSIZE]; + uint8_t out2[CRYPT_MD5_DIGESTSIZE]; + uint32_t outLen = CRYPT_MD5_DIGESTSIZE; + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx2), CRYPT_SUCCESS); + + for (inLenBase = 1; inLenBase <= 100; inLenBase++) { + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx1, input + inLenTotal, inLenBase), CRYPT_SUCCESS); + inLenTotal += inLenBase; + } + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx1, out1, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(outLen, CRYPT_MD5_DIGESTSIZE); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx2, input, inLenTotal), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx2, out2, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(outLen, CRYPT_MD5_DIGESTSIZE); + + ASSERT_COMPARE("md5", out1, outLen, out2, outLen); +exit: + CRYPT_EAL_MdFreeCtx(ctx1); + CRYPT_EAL_MdFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_MD5_FUNC_TC004 + * @title Hash calculation for multiple updates,comparison with standard results. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create a ctx and initialize, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate to calculate the hash of a data segmentxpected result 2. + * 3.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 3. + * 4.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 4. + * 5.Call CRYPT_EAL_MdFinal get the result, expected result 5. + * @expect + * 1.Successful + * 2.Successful + * 3.Successful + * 4.Successful + * 5.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD5_FUNC_TC004(Hex *data1, Hex *data2, Hex *data3, Hex *hash) +{ + TestMemInit(); + uint8_t output[CRYPT_MD5_DIGESTSIZE]; + uint32_t outLen = CRYPT_MD5_DIGESTSIZE; + CRYPT_EAL_MdCTX *md5Ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_MD5); + ASSERT_TRUE(md5Ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdInit(md5Ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, data1->x, data1->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, data2->x, data2->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(md5Ctx, data3->x, data3->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(md5Ctx, output, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(outLen, CRYPT_MD5_DIGESTSIZE); + ASSERT_COMPARE("md5", output, outLen, hash->x, hash->len); +exit: + CRYPT_EAL_MdFreeCtx(md5Ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_MD5_COPY_CTX_FUNC_TC001 + * @title MD5 copy ctx function test. + * @precon nan + * @brief + * 1. Create the context ctx of md algorithm, expected result 1 + * 2. Call to CRYPT_EAL_MdCopyCtx method to copy ctx, expected result 2 + * 3. Calculate the hash of msg, and compare the calculated result with hash vector, expected result 3 + * @expect + * 1. Success, the context is not null. + * 2. CRYPT_SUCCESS + * 3. Success, the hashs are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_MD5_COPY_CTX_FUNC_TC001(int id, Hex *msg, Hex *hash) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *cpyCtx = NULL; + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + uint8_t output[CRYPT_MD5_DIGESTSIZE]; + uint32_t outLen = CRYPT_MD5_DIGESTSIZE; + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_MdCopyCtx(cpyCtx, ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdInit(cpyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(cpyCtx, msg->x, msg->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(cpyCtx, output, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(id, cpyCtx->id); + ASSERT_EQ(memcmp(output, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); + CRYPT_EAL_MdFreeCtx(cpyCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/md5/test_suite_sdv_eal_md5.data b/testcode/sdv/testcase/crypto/md5/test_suite_sdv_eal_md5.data new file mode 100644 index 00000000..5be2899c --- /dev/null +++ b/testcode/sdv/testcase/crypto/md5/test_suite_sdv_eal_md5.data @@ -0,0 +1,35 @@ +SDV_CRYPTO_MD5_API_TC001 +SDV_CRYPTO_MD5_API_TC001: + +SDV_CRYPTO_MD5_FUNC_TC001 +SDV_CRYPTO_MD5_FUNC_TC001:"d41d8cd98f00b204e9800998ecf8427e" + +Vector Test for rfc1321 #1 +SDV_CRYPTO_MD5_FUNC_TC002:"":"d41d8cd98f00b204e9800998ecf8427e" + +Vector Test for rfc1321 #2 +SDV_CRYPTO_MD5_FUNC_TC002:"61":"0cc175b9c0f1b6a831c399e269772661" + +Vector Test for rfc1321 #3 +SDV_CRYPTO_MD5_FUNC_TC002:"616263":"900150983cd24fb0d6963f7d28e17f72" + +Vector Test for rfc1321 #4 +SDV_CRYPTO_MD5_FUNC_TC002:"6d65737361676520646967657374":"f96b697d7cb7938d525a2f31aaf161d0" + +Vector Test for rfc1321 #5 +SDV_CRYPTO_MD5_FUNC_TC002:"6162636465666768696a6b6c6d6e6f707172737475767778797a":"c3fcd3d76192e4007dfb496cca67e13b" + +Vector Test for rfc1321 #6 +SDV_CRYPTO_MD5_FUNC_TC002:"4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839":"d174ab98d277d9f5a5611c2c9f419d9f" + +Vector Test for rfc1321 #7 +SDV_CRYPTO_MD5_FUNC_TC002:"3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930":"57edf4a22be3c955ac49da2e2107b67a" + +MD5 100 times updates then final test +SDV_CRYPTO_MD5_FUNC_TC003: + +SDV_CRYPTO_MD5_FUNC_TC004 Multi block vector test +SDV_CRYPTO_MD5_FUNC_TC004:"313233343536373839":"30313233343536373839303132333435363738393031323334353637383930313233343536":"37383930313233343536373839303132333435363738393031323334353637383930":"57edf4a22be3c955ac49da2e2107b67a" + +SDV_CRYPTO_MD5_COPY_CTX_FUNC_TC001 +SDV_CRYPTO_MD5_COPY_CTX_FUNC_TC001:CRYPT_MD_MD5:"6d65737361676520646967657374":"f96b697d7cb7938d525a2f31aaf161d0" \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/paillier/test_suite_sdv_eal_paillier.c b/testcode/sdv/testcase/crypto/paillier/test_suite_sdv_eal_paillier.c new file mode 100644 index 00000000..ea2f41e7 --- /dev/null +++ b/testcode/sdv/testcase/crypto/paillier/test_suite_sdv_eal_paillier.c @@ -0,0 +1,987 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +#include +#include +#include +#include +#include "bsl_err.h" +#include "bsl_sal.h" +#include "crypt_errno.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_rand.h" +#include "crypt_bn.h" +#include "eal_pkey_local.h" +#include "stub_replace.h" +#include "crypt_util_rand.h" +#include "crypt_paillier.h" +#include "paillier_local.h" +#include "bn_basic.h" +#include "securec.h" + +#include "crypt_encode.h" +/* END_HEADER */ + +void *malloc_fail(uint32_t size) +{ + (void)size; + return NULL; +} + +void SetPaillierPara(CRYPT_EAL_PkeyPara *para, Hex *p, Hex *q, uint32_t bits) +{ + para->id = CRYPT_PKEY_PAILLIER; + para->para.paillierPara.p = p->x; + para->para.paillierPara.q = q->x; + para->para.paillierPara.pLen = p->len; + para->para.paillierPara.qLen = q->len; + para->para.paillierPara.bits = bits; +} + +void SetPaillierPubKey(CRYPT_EAL_PkeyPub *pubKey, uint8_t *g, uint32_t gLen, uint8_t *n, uint32_t nLen, uint8_t *n2, uint32_t n2Len) +{ + pubKey->id = CRYPT_PKEY_PAILLIER; + pubKey->key.paillierPub.g = g; + pubKey->key.paillierPub.gLen = gLen; + pubKey->key.paillierPub.n = n; + pubKey->key.paillierPub.nLen = nLen; + pubKey->key.paillierPub.n2 = n2; + pubKey->key.paillierPub.n2Len = n2Len; +} + +void SetPaillierPrvKey(CRYPT_EAL_PkeyPrv *prvKey, uint8_t *lambda, uint32_t lambdaLen, uint8_t *mu, uint32_t muLen) +{ + prvKey->id = CRYPT_PKEY_PAILLIER; + prvKey->key.paillierPrv.lambda = lambda; + prvKey->key.paillierPrv.lambdaLen = lambdaLen; + prvKey->key.paillierPrv.mu = mu; + prvKey->key.paillierPrv.muLen = muLen; +} + +int32_t RandFunc(uint8_t *randNum, uint32_t randLen) +{ + const int maxNum = 255; + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % maxNum); + } + return 0; +} + +/** + * @test SDV_CRYPTO_PAILLIER_NEW_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyNewCtx test. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method to create ctx, algId is CRYPT_PKEY_PAILLIER, expected result 1. + * 2. Release the ctx. + * 3. Repeat steps 1 to 2 for 100 times. + * @expect + * 1. The returned result is not empty. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_NEW_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = NULL; + + /* Run 100 times */ + for (int i = 0; i < 100; i++) { + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + CRYPT_EAL_PkeyFreeCtx(pkey); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_NEW_API_TC002 + * @title PAILLIER CRYPT_EAL_PkeyNewCtx test: Malloc failed. + * @precon Mock BSL_SAL_Malloc to malloc_fail. + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method to create ctx, algId is CRYPT_PKEY_PAILLIER, expected result 1. + * 2. Release the ctx. + * 3. Reset the BSL_SAL_Malloc. + * @expect + * 1. Failed to create the ctx. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_NEW_API_TC002(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + FuncStubInfo tmpRpInfo = {0}; + + STUB_Init(); + ASSERT_TRUE(STUB_Replace(&tmpRpInfo, BSL_SAL_Malloc, malloc_fail) == 0); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey == NULL); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_SET_PARA_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeySetPara test. + * @precon Create the context of the paillier algorithm. + * + * @brief + * 1. Call the CRYPT_EAL_PkeySetPara method: + * (1) para = NULL, expected result 1. + * (2) pLen != BN_BITS_TO_BYTES(bits), expected result 2. + * (3) qLen != BN_BITS_TO_BYTES(bits), expected result 2. + * (4) p = NULL, q = NULL, bits = 0, expected result 2. + * (4) pLen = BN_BITS_TO_BYTES(bits) qLen = BN_BITS_TO_BYTES(bits), bits != 0, expected result 3. + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_EAL_ERR_NEW_PARA_FAIL + * 3. CRYPT_SUCCESS +*/ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_SET_PARA_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPara para = {0}; + + SetPaillierPara(¶, p, q, bits); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, NULL), CRYPT_NULL_INPUT); + + uint32_t bytes = BN_BITS_TO_BYTES(bits); + if (p->len != bytes) + { + ASSERT_TRUE_AND_LOG("pLen != BN_BITS_TO_BYTES(bits)", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + } + if (q->len != bytes) + { + ASSERT_TRUE_AND_LOG("qLen != BN_BITS_TO_BYTES(bits)", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + } + if (p->len == bytes && q->len == bytes && bits == 0) + { + ASSERT_TRUE_AND_LOG("p = NULL, q = NULL, bits = 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + } + if (p->len == bytes && q->len == bytes && bits != 0) + { + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + } + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_GEN_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyGen: No regist rand. + * @precon Create the contexts of the paillier algorithm and set para. + * @brief + * 1. Call the CRYPT_EAL_PkeyGen method to generate a key pair, expected result 1. + * @expect + * 1. Failed to generate a key pair, the return value is CRYPT_NO_REGIST_RAND. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_GEN_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyPara para = {0}; + SetPaillierPara(¶, p, q, bits); + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_NO_REGIST_RAND); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_GET_PUB_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyGetPub test. + * @precon 1. Create the context of the paillier algorithm. + * 2. Initialize the DRBG. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPub method without public key, expected result 1 + * 2. Set para and generate a key pair, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPub method: + * (1) pkey = NULL, expected result 1. + * (2) pub = NULL, expected result 1. + * (3) n = NULL, expected result 1. + * (4) n != NULL and nLen = 0, expected result 3. + * (5) g = NULL, expected result 1. + * (6) g != NULL, gLen = 0, expected result 3. + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_GET_PUB_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + uint8_t pubG[600]; + uint8_t pubN[600]; + uint8_t pubN2[600]; + + SetPaillierPara(¶, p, q, bits); + SetPaillierPubKey(&pubKey, pubG, 600, pubN, 600, pubN2, 600); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + /* Missing public key */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(NULL, &pubKey), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, NULL), CRYPT_NULL_INPUT); + + /* n = NULL */ + pubKey.key.paillierPub.n = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_NULL_INPUT); + pubKey.key.paillierPub.n = pubN; + + /* n != NULL and nLen = 0 */ + pubKey.key.paillierPub.nLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + pubKey.key.paillierPub.nLen = 600; + + /* g = NULL */ + pubKey.key.paillierPub.g = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_NULL_INPUT); + pubKey.key.paillierPub.g = pubG; + + /* g != NULL, gLen = 0 */ + pubKey.key.paillierPub.gLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_GET_PRV_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyGetPrv: Bad private key. + * @precon 1. Create the context of the paillier algorithm. + * 2. Initialize the DRBG. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPrv method without private key, expected result 1 + * 2. Set para and generate a key pair, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPrv method: + * (1) pkey = NULL, expected result 1. + * (2) prv = NULL, expected result 1. + * (3) lambda = NULL, expected result 1. + * (4) lambda != NULL and lambdaLen = 0, expected result 3. + * (5) mu = NULL, expected result 1. + * (6) mu != NULL, muLen = 0, expected result 3. + * (7) lambda != NULL, mu != NULL, lambdaLen != 0, muLen != 0, expected result 2. + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_GET_PRV_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPrv prvKey = {0}; + + CRYPT_EAL_PkeyPara para = {0}; + uint8_t prvLambda[600]; + uint8_t prvMu[600]; + + SetPaillierPrvKey(&prvKey, prvLambda, 600, prvMu, 600); + SetPaillierPara(¶, p, q, bits); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + /* Missing private key */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(NULL, &prvKey), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, NULL), CRYPT_NULL_INPUT); + + /* lambda = NULL */ + prvKey.key.paillierPrv.lambda = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_NULL_INPUT); + prvKey.key.paillierPrv.lambda = prvLambda; + + /* lambda != NULL and lambdaLen = 0 */ + prvKey.key.paillierPrv.lambdaLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + prvKey.key.paillierPrv.lambdaLen = 600; + + /* mu = NULL */ + prvKey.key.paillierPrv.mu = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_NULL_INPUT); + prvKey.key.paillierPrv.mu = prvMu; + + /* mu != NULL, muLen = 0 */ + prvKey.key.paillierPrv.muLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + prvKey.key.paillierPrv.muLen = 600; + + /* lambda != NULL, mu != NULL, lambdaLen != 0, muLen != 0 */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_SET_PRV_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeySetPrv: Bad private key. + * @precon Create the contexts of the paillier algorithm and set para: + * pkey1: Generate a key pair. + * pkey2: set the private key. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPrv method: + * (1) pKey is NULL, expected result 1. + * (2) prv is NULL, expected result 1. + * (3) n = NULL, expected result 2. + * (4) lambda = NULL, expected result 2. + * (5) mu = NULL, expected result 2. + * (6) n2 = NULL, expected result 2. + * (7) lambdaLen = 0, expected result 2. + * (8) muLen = 0, expected result 2. + * (9) n2Len = 0, expected result 2. + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_PAILLIER_ERR_INPUT_VALUE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_SET_PRV_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + uint8_t prvMu[600]; + uint8_t prvLambda[600]; + uint8_t prvN[600]; + uint8_t prvN2[600]; + + SetPaillierPrvKey(&prvKey, prvLambda, 600, prvMu, 600); + SetPaillierPara(¶, p, q, bits); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + + /*pKey is NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(NULL, &prvKey) == CRYPT_NULL_INPUT); + + /*prvKey is NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey2, NULL) == CRYPT_NULL_INPUT); + + prvKey.key.paillierPrv.n = prvN; + prvKey.key.paillierPrv.nLen = 600; + + prvKey.key.paillierPrv.n2 = prvN2; + prvKey.key.paillierPrv.n2Len = 600; + + /*n = NULL*/ + prvKey.key.paillierPrv.n = NULL; + ASSERT_TRUE_AND_LOG("n is NULL", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.n = prvN; + + /*lambda = NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.paillierPrv.lambda = NULL; + ASSERT_TRUE_AND_LOG("lambda is NULL", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.lambda = prvLambda; + + /*mu = NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.paillierPrv.mu = NULL; + ASSERT_TRUE_AND_LOG("mu is NULL", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.mu = prvMu; + + /*n2 = NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.paillierPrv.n2 = NULL; + ASSERT_TRUE_AND_LOG("n2 is NULL", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.n2 = prvN2; + + /*lambdaLen = 0*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.paillierPrv.lambdaLen = 0; + ASSERT_TRUE_AND_LOG("lambdaLen is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.lambdaLen = 600; + + /*muLen = 0*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.paillierPrv.muLen = 0; + ASSERT_TRUE_AND_LOG("muLen is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.muLen = 600; + + /*n2Len = 0*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.paillierPrv.n2Len = 0; + ASSERT_TRUE_AND_LOG("n2Len is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + prvKey.key.paillierPrv.n2Len = 600; +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_SET_PRV_API_TC002 + * @title PAILLIER CRYPT_EAL_PkeySetPrv: Specification test. + * @precon Create the contexts of the paillier algorithm and set para: + * pkey1: Generate a key pair. + * pkey2: set the private key. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPrv method: + * (1) n2 is not equal to n^2, expected result 1. + * (2) n2 is equal to n^2, expceted result 2. + * @expect + * 1. CRYPT_PAILLIER_ERR_INPUT_VALUE + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_SET_PRV_API_TC002(Hex *p, Hex *q, Hex *n, Hex *n2, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + uint8_t prvMu[256]; + uint8_t prvLambda[256]; + + SetPaillierPrvKey(&prvKey, prvLambda, 256, prvMu, 256); + SetPaillierPara(¶, p, q, bits); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + + prvKey.key.paillierPrv.n = n->x; + prvKey.key.paillierPrv.nLen = n->len; + + prvKey.key.paillierPrv.n2 = n->x; + prvKey.key.paillierPrv.n2Len = n->len; + + ASSERT_TRUE_AND_LOG("n2 is not equal to n^2", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + + prvKey.key.paillierPrv.n2 = n2->x; + prvKey.key.paillierPrv.n2Len = n2->len; + ASSERT_TRUE_AND_LOG("set success", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_SET_PUB_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyGetPub: Bad public key. + * @precon Create the contexts of the paillier algorithm and set para: + * pkey1: Generate a key pair. + * pkey2: Set the public key. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPub method: + * (1) pKey is NULL, expected result 1. + * (2) prv is NULL, expected result 1. + * (3) n = NULL, expected result 1. + * (4) g = NULL, expected result 1. + * (5) n2 = NULL, expected result 1. + * @expect + * 1. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_SET_PUB_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey; + uint8_t pubG[600]; + uint8_t pubN[600]; + uint8_t pubN2[600]; + SetPaillierPara(¶, p, q, bits); + SetPaillierPubKey(&pubKey, pubN, 600, pubG, 600, pubN2, 600); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + + /*pKey is NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(NULL, &pubKey) == CRYPT_NULL_INPUT); + + /*pubKey is NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey2, NULL) == CRYPT_NULL_INPUT); + + /*n = NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + pubKey.key.paillierPub.n = NULL; + ASSERT_TRUE_AND_LOG("lambda is NULL", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_NULL_INPUT); + pubKey.key.paillierPub.n = pubN; + + /*g = NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + pubKey.key.paillierPub.g = NULL; + ASSERT_TRUE_AND_LOG("mu is NULL", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_NULL_INPUT); + pubKey.key.paillierPub.g = pubG; + + /*n2 = NULL*/ + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + pubKey.key.paillierPub.n2 = NULL; + ASSERT_TRUE_AND_LOG("n2 is NULL", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_NULL_INPUT); + pubKey.key.paillierPub.n2 = pubN2; + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + + ASSERT_TRUE_AND_LOG("set prvKey success", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_SET_PUB_API_TC002 + * @title PAILLIER CRYPT_EAL_PkeyGetPub: Bad public key. + * @precon Create the contexts of the paillier algorithm and set para: + * pkey1: Generate a key pair. + * pkey2: Set the public key. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPub method: + * (1) n2 is not equal to n^2, expected result 1. + * (2) n2 is equal to n^2, expceted result 2. + * @expect + * 1. CRYPT_PAILLIER_ERR_INPUT_VALUE + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_SET_PUB_API_TC002(Hex *p, Hex *q, Hex *n, Hex *n2, int bits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey; + uint8_t pubG[128]; + SetPaillierPara(¶, p, q, bits); + SetPaillierPubKey(&pubKey, pubG, 128, n->x, n->len, n2->x, n2->len); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + + pubKey.key.paillierPub.n2 = n->x; + pubKey.key.paillierPub.n2Len = n->len; + ASSERT_TRUE_AND_LOG("n2 is not equal to n^2", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_PAILLIER_ERR_INPUT_VALUE); + + pubKey.key.paillierPub.n2 = n2->x; + pubKey.key.paillierPub.n2Len = n2->len; + ASSERT_TRUE_AND_LOG("set success", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_ENC_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyEncrypt: Test the validity of input parameters. + * @precon Create the context of the paillier algorithm: + * @brief + * 1. Call the CRYPT_EAL_PkeyEncrypt method without public key, expected result 1 + * 2. Set pubkey, expected result 2 + * 3. Call the CRYPT_EAL_PkeyEncrypt method: + * (1) pkey = NULL, expected result 3 + * (2) data = NULL, expected result 3 + * (3) data != NULL dataLen > bytes of ctx, expected result 4 + * (4) out = NULL, expected result 3 + * (5) outLen = NULL, expected result 3 + * (6) outLen = 0, expected result 5 + * (7) no modification, expected result 2 + * @expect + * 1. CRYPT_PAILLIER_NO_KEY_INFO + * 2. CRYPT_SUCCESS + * 3. CRYPT_NULL_INPUT + * 4. CRYPT_PAILLIER_ERR_ENC_BITS + * 5. CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_ENC_API_TC001(Hex *n, Hex *g, Hex *n2, Hex *in) +{ + uint8_t crypt[512]; + uint32_t cryptLen = 512; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pubkey = {0}; + + SetPaillierPubKey(&pubkey, g->x, g->len, n->x, n->len, n2->x, n2->len); + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, &cryptLen), CRYPT_PAILLIER_NO_KEY_INFO); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pubkey) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(NULL, in->x, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, NULL, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, 257, crypt, &cryptLen) == CRYPT_PAILLIER_ERR_ENC_BITS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, NULL, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, NULL) == CRYPT_NULL_INPUT); + cryptLen = 0; + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH); + + cryptLen = 512; + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_DEC_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyDecrypt: Test the validity of input parameters. + * @precon Create the context of the paillier algorithm: + * @brief + * 1. Call the CRYPT_EAL_PkeyDecrypt method without private key, expected result 1 + * 2. Set private key, expected result 2 + * 4. Call the CRYPT_EAL_PkeyDecrypt method: + * (1) pkey = NULL, expected result 3 + * (2) data = NULL, expected result 3 + * (3) data != NULL, dataLen = 0, expected result 4 + * (4) data != NULL, dataLen is invalid , expected result 4 + * (5) out = NULL, expected result 3 + * (6) outLen = NULL, expected result 3 + * (7) outLen = 0, expected result 5 + * (8) no modification, expected result 2 + * @expect + * 1. CRYPT_PAILLIER_NO_KEY_INFO + * 2. CRYPT_SUCCESS + * 3. CRYPT_NULL_INPUT + * 4. CRYPT_PAILLIER_ERR_DEC_BITS + * 5. CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_DEC_API_TC001(Hex *Lambda, Hex *mu, Hex *n, Hex *n2, Hex *in) +{ + uint8_t crypt[256]; + uint32_t cryptLen = 256; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + SetPaillierPrvKey(&prvkey, Lambda->x, Lambda->len, mu->x, mu->len); + prvkey.key.paillierPrv.n = n->x; + prvkey.key.paillierPrv.nLen = n->len; + prvkey.key.paillierPrv.n2 = n2->x; + prvkey.key.paillierPrv.n2Len = n2->len; + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_PAILLIER_NO_KEY_INFO); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prvkey) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(NULL, in->x, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, NULL, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, 0, crypt, &cryptLen) == CRYPT_PAILLIER_ERR_DEC_BITS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, 257, crypt, &cryptLen) == CRYPT_PAILLIER_ERR_DEC_BITS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, NULL, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, NULL) == CRYPT_NULL_INPUT); + + cryptLen = 0; + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_PAILLIER_BUFF_LEN_NOT_ENOUGH); + + cryptLen = 256; + ASSERT_EQ(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +int Compare_PubKey(CRYPT_EAL_PkeyPub *pubKey1, CRYPT_EAL_PkeyPub *pubKey2) +{ + if (pubKey1->key.paillierPub.nLen != pubKey2->key.paillierPub.nLen || pubKey1->key.paillierPub.gLen != pubKey2->key.paillierPub.gLen) { + return -1; // -1 indicates failure + } + if (memcmp(pubKey1->key.paillierPub.n, pubKey2->key.paillierPub.n, pubKey1->key.paillierPub.nLen) != 0 || + memcmp(pubKey1->key.paillierPub.g, pubKey2->key.paillierPub.g, pubKey1->key.paillierPub.gLen) != 0) { + return -1; // -1 indicates failure + } + return 0; +} + +int Compare_PrvKey(CRYPT_EAL_PkeyPrv *prvKey1, CRYPT_EAL_PkeyPrv *prvKey2) +{ + if (prvKey1->key.paillierPrv.nLen != prvKey2->key.paillierPrv.nLen || prvKey1->key.paillierPrv.muLen != prvKey2->key.paillierPrv.muLen || + prvKey1->key.paillierPrv.lambdaLen != prvKey2->key.paillierPrv.lambdaLen) { + return -1; // -1 indicates failure + } + if (memcmp(prvKey1->key.paillierPrv.lambda, prvKey2->key.paillierPrv.lambda, prvKey1->key.paillierPrv.lambdaLen) != 0 || + memcmp(prvKey1->key.paillierPrv.mu, prvKey2->key.paillierPrv.mu, prvKey1->key.paillierPrv.muLen) != 0 || + memcmp(prvKey1->key.paillierPrv.n, prvKey2->key.paillierPrv.n, prvKey1->key.paillierPrv.nLen) != 0) { + return -1; // -1 indicates failure + } + return 0; +} + +/** + * @test SDV_CRYPTO_PAILLIER_SET_KEY_API_TC001 + * @title PAILLIER Set the public key and private key multiple times. + * @precon Create the contexts of the paillier algorithm and: + * pkey1: Set paran and generate a key pair: test obtaining the key. + * pkey2: Test set keys, and verify that the public and private keys can exist at the same time. + * @brief + * 1. pkey1: Get public key and get private key, expected result 1 + * 2. pkey2: + * (1) Set public key and set private key, expected result 1 + * (2) Get public key, get private key and check private key, expected result 2 + * (3) Set private key and set public key, expected result 3 + * (4) Get private key, get public key and check public key, expected result 4 + * @expect + * 1. CRYPT_SUCCESS + * 2. The obtained private key is equal to the set private key. + * 3. CRYPT_SUCCESS + * 4. The obtained public key is equal to the set public key. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_SET_KEY_API_TC001(Hex *p, Hex *q, int bits) +{ + uint8_t pubN[600]; + uint8_t pubG[600]; + uint8_t pubN2[600]; + uint8_t prvN[600]; + uint8_t prvLambda[600]; + uint8_t prvMu[600]; + uint8_t prvN2[600]; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + + SetPaillierPara(¶, p, q, bits); + SetPaillierPubKey(&pubKey, pubG, 600, pubN, 600, pubN2, 600); + SetPaillierPrvKey(&prvKey, prvLambda, 600, prvMu, 600); + prvKey.key.paillierPrv.n = prvN; + prvKey.key.paillierPrv.nLen = 600; + prvKey.key.paillierPrv.n2 = prvN2; + prvKey.key.paillierPrv.n2Len = 600; + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + /* pkey1 */ + /* Generate a key pair. */ + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS); + + /* Get keys. */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey1, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey1, &prvKey), CRYPT_SUCCESS); + + /* pkey2 */ + /* Set public key and set private key. */ + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey2, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + + /* Get public key, get private key and check private key.*/ + SetPaillierPubKey(&pubKey, pubG, 600, pubN, 600, pubN2, 600); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey2, &pubKey), CRYPT_SUCCESS); + SetPaillierPrvKey(&prvKey, prvLambda, 600, prvMu, 600); + prvKey.key.paillierPrv.n = prvN; + prvKey.key.paillierPrv.nLen = 600; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + ASSERT_EQ(Compare_PrvKey(&prvKey, &prvKey), 0); + + /* Set private key and set public key. */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey2, &pubKey), CRYPT_SUCCESS); + /* Get private key, get public key and check public key.*/ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + SetPaillierPubKey(&pubKey, pubG, 600, pubN, 600, pubN2, 600); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey2, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(Compare_PubKey(&pubKey, &pubKey), 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_DUP_CTX_API_TC001 + * @title PAILLIER CRYPT_EAL_PkeyDupCtx test. + * @precon Create the contexts of the paillier algorithm, set para and generate a key pair. + * @brief + * 1. Call the CRYPT_EAL_PkeyDupCtx mehod to dup paillier, expected result 1 + * @expect + * 1. Success. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_DUP_CTX_API_TC001(Hex *p, Hex *q, int bits) +{ + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyCtx *newPkey = NULL; + CRYPT_EAL_PkeyCtx *pkey = NULL; + SetPaillierPara(¶, p, q, bits); + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), 0); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + CRYPT_PAILLIER_Ctx *paillierCtx = (CRYPT_PAILLIER_Ctx *)pkey->key; + ASSERT_TRUE(paillierCtx != NULL); + + newPkey = CRYPT_EAL_PkeyDupCtx(pkey); + ASSERT_TRUE(newPkey != NULL); + ASSERT_EQ(newPkey->references.count, 1); + CRYPT_PAILLIER_Ctx *paillierCtx2 = (CRYPT_PAILLIER_Ctx *)newPkey->key; + ASSERT_TRUE(paillierCtx2 != NULL); + + ASSERT_COMPARE("paillier compare lambda", + paillierCtx->prvKey->lambda->data, + paillierCtx->prvKey->lambda->size * sizeof(BN_UINT), + paillierCtx2->prvKey->lambda->data, + paillierCtx2->prvKey->lambda->size * sizeof(BN_UINT)); + + ASSERT_COMPARE("paillier compare mu", + paillierCtx->prvKey->mu->data, + paillierCtx->prvKey->mu->size * sizeof(BN_UINT), + paillierCtx2->prvKey->mu->data, + paillierCtx2->prvKey->mu->size * sizeof(BN_UINT)); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(newPkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_PAILLIER_GET_SECURITY_BITS_FUNC_TC001 + * @title PAILLIER CRYPT_EAL_PkeyGetSecurityBits test. + * @precon nan + * @brief + * 1. Create the context of the paillier algorithm, expected result 1 + * 2. Set public key, expected result 2 + * 3. Call the CRYPT_EAL_PkeyVerify method and the parameter is correct, expected result 3 + * @expect + * 1. Success, and the context is not null. + * 2. CRYPT_SUCCESS + * 3. The return value is not 0. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_PAILLIER_GET_SECURITY_BITS_FUNC_TC001(Hex *n, Hex *g, Hex *n2, int securityBits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pubkey = {0}; + SetPaillierPubKey(&pubkey, g->x, g->len, n->x, n->len, n2->x, n2->len); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_PAILLIER); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pubkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetSecurityBits(pkey), securityBits); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} diff --git a/testcode/sdv/testcase/crypto/paillier/test_suite_sdv_eal_paillier.data b/testcode/sdv/testcase/crypto/paillier/test_suite_sdv_eal_paillier.data new file mode 100644 index 00000000..cca2ad49 --- /dev/null +++ b/testcode/sdv/testcase/crypto/paillier/test_suite_sdv_eal_paillier.data @@ -0,0 +1,54 @@ +CRYPT_EAL_PkeyNewCtx: Repeat call +SDV_CRYPTO_PAILLIER_NEW_API_TC001: + +CRYPT_EAL_PKEY_NewCtx: Malloc Fail +SDV_CRYPTO_PAILLIER_NEW_API_TC002: + +CRYPT_EAL_PkeySetPara: pLen != BN_BITS_TO_BYTES(bits) +SDV_CRYPTO_PAILLIER_SET_PARA_API_TC001:"":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeySetPara: qLen != BN_BITS_TO_BYTES(bits) +SDV_CRYPTO_PAILLIER_SET_PARA_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"":1024 + +CRYPT_EAL_PkeySetPara: p = NULL, q = NULL, bits = 0 +SDV_CRYPTO_PAILLIER_SET_PARA_API_TC001:"":"":0 + +CRYPT_EAL_PkeySetPara: pLen = BN_BITS_TO_BYTES(bits) qLen = BN_BITS_TO_BYTES(bits), bits != 0 +SDV_CRYPTO_PAILLIER_SET_PARA_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeyGen: +SDV_CRYPTO_PAILLIER_GEN_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeyGetPub: +SDV_CRYPTO_PAILLIER_GET_PUB_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeyGetPrv: +SDV_CRYPTO_PAILLIER_GET_PRV_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeySetPrv: +SDV_CRYPTO_PAILLIER_SET_PRV_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeySetPrv: +SDV_CRYPTO_PAILLIER_SET_PRV_API_TC002:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"b98dec7c2753f74fc14bbf17cc1ff646eb12e06a69668171df92fa5769803b9f901c0e51a7c37a93c25ed6bb14f0adfe32fa3addf1745a94b3aeb4b6aa70669f82e2f1d31fd78b0ada66ad5dd2f944d009987bb328dca4835e608cd034bdb8670e80537c1644e5cfa8a9368fd122af18a535e479f04f543a71acc5cc5817931cfe72b9907d06ce26fc45d3121f3904cbd7e4d8cbb3defc784eddf018022f55a6dbffcf6fe5b27ae02237f113fc2ac8d6b3eff3b397ea5ceeae4cd98433cc1916c7283920ea80ba130186bfed51cce07073a8e998478897e23df673142f3b478a8a3f12df6e59dc07e4261500c08416ffb73189f24568083d7772563ea5e0d31d2a048916b52094ee0c1b3512dbc319afe56881adb40327a545b08b2825ba09732bb4925a19efe75188154a1a1c1e90ce2818f3bc16cbe17b80b26f665926276a9c47abc41772fa7c602a5d2aba39b592aa7c59e88e2296aea3a5c16a5b59b1a90309f63d9cdb0b6c0115348f348a33851f98782f6ff1089325620865cf3c29fc8926c900e2058f882cfcc139ae1998f3f0aec64e1f656575af7fd2644977c4860a66394b5ff67aefd6bbae698c7ce0aa4fc9f4d2d9edf06635e3c45c58fbcb32237892fd27435d19a68e88739ff8f0d55064e6e4703e975da9fa4e7880ec33607ffd02ab60f22e40e98d359780cd80aa38dd743c8c1da4032f731d4099183f99":1024 + +CRYPT_EAL_PkeySetPub: +SDV_CRYPTO_PAILLIER_SET_PUB_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeySetPub: +SDV_CRYPTO_PAILLIER_SET_PUB_API_TC002:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"b98dec7c2753f74fc14bbf17cc1ff646eb12e06a69668171df92fa5769803b9f901c0e51a7c37a93c25ed6bb14f0adfe32fa3addf1745a94b3aeb4b6aa70669f82e2f1d31fd78b0ada66ad5dd2f944d009987bb328dca4835e608cd034bdb8670e80537c1644e5cfa8a9368fd122af18a535e479f04f543a71acc5cc5817931cfe72b9907d06ce26fc45d3121f3904cbd7e4d8cbb3defc784eddf018022f55a6dbffcf6fe5b27ae02237f113fc2ac8d6b3eff3b397ea5ceeae4cd98433cc1916c7283920ea80ba130186bfed51cce07073a8e998478897e23df673142f3b478a8a3f12df6e59dc07e4261500c08416ffb73189f24568083d7772563ea5e0d31d2a048916b52094ee0c1b3512dbc319afe56881adb40327a545b08b2825ba09732bb4925a19efe75188154a1a1c1e90ce2818f3bc16cbe17b80b26f665926276a9c47abc41772fa7c602a5d2aba39b592aa7c59e88e2296aea3a5c16a5b59b1a90309f63d9cdb0b6c0115348f348a33851f98782f6ff1089325620865cf3c29fc8926c900e2058f882cfcc139ae1998f3f0aec64e1f656575af7fd2644977c4860a66394b5ff67aefd6bbae698c7ce0aa4fc9f4d2d9edf06635e3c45c58fbcb32237892fd27435d19a68e88739ff8f0d55064e6e4703e975da9fa4e7880ec33607ffd02ab60f22e40e98d359780cd80aa38dd743c8c1da4032f731d4099183f99":1024 + +CRYPT_EAL_PkeyEncrypt: +SDV_CRYPTO_PAILLIER_ENC_API_TC001:"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c6":"b98dec7c2753f74fc14bbf17cc1ff646eb12e06a69668171df92fa5769803b9f901c0e51a7c37a93c25ed6bb14f0adfe32fa3addf1745a94b3aeb4b6aa70669f82e2f1d31fd78b0ada66ad5dd2f944d009987bb328dca4835e608cd034bdb8670e80537c1644e5cfa8a9368fd122af18a535e479f04f543a71acc5cc5817931cfe72b9907d06ce26fc45d3121f3904cbd7e4d8cbb3defc784eddf018022f55a6dbffcf6fe5b27ae02237f113fc2ac8d6b3eff3b397ea5ceeae4cd98433cc1916c7283920ea80ba130186bfed51cce07073a8e998478897e23df673142f3b478a8a3f12df6e59dc07e4261500c08416ffb73189f24568083d7772563ea5e0d31d2a048916b52094ee0c1b3512dbc319afe56881adb40327a545b08b2825ba09732bb4925a19efe75188154a1a1c1e90ce2818f3bc16cbe17b80b26f665926276a9c47abc41772fa7c602a5d2aba39b592aa7c59e88e2296aea3a5c16a5b59b1a90309f63d9cdb0b6c0115348f348a33851f98782f6ff1089325620865cf3c29fc8926c900e2058f882cfcc139ae1998f3f0aec64e1f656575af7fd2644977c4860a66394b5ff67aefd6bbae698c7ce0aa4fc9f4d2d9edf06635e3c45c58fbcb32237892fd27435d19a68e88739ff8f0d55064e6e4703e975da9fa4e7880ec33607ffd02ab60f22e40e98d359780cd80aa38dd743c8c1da4032f731d4099183f99":"414243444546474849404a4b4c4d4e4f" + +CRYPT_EAL_PkeyDecrypt: +SDV_CRYPTO_PAILLIER_DEC_API_TC001:"24532c3733bb3756455c7af0e3c2b382bf0c006fb448a11aeb895952bb50426904acb897b8ffdcbfb8a3ab49de4c7489ecd6a95c701d4fc7e8b5aa29136764a1c7077a5eec7935249a08acb554c6398330eafc7ed3ba034d5d3360f18870a5a9cf39832938dfcfcb80bfb78278127c152aa0e1a598cded011e89c3da1903c1740dea0bec8763180b19ab8068b9883c809ed4af90d59ada1e22a1cfeb89612d19bcb057ccb781882ebfa139e7ff2dceb003961977f0f3e82882e999621697c3c3cb5831af064357dcd4f0c3a336b08b16905fca58dd22529fb531594972aa4fa787c1bfa4b258ef03d4374cb736bdf6cbee34aa2f4923fb4bbb85166ba3dc2052":"c4e1a9667b7a9024236a749e8e908671475414b7c65a1849d702cb2e1a596b4ff403a2d752219e5fb029a147faa6587f60fdbfa65209726c6069807350b1a8d5ea64c5e585edc11fa691d6e88a8a3be8894a13a40e62802fa2b1dfd2b6593ba83930c9c0fb34883ad74da69b49f7fb058ecb28b825c4d59e2eeb3e4a661799cc3b945e88a75712d17febb83a11c94b61bf190899581a4396a2506019f58717eee82d8f33cd822d548c9a629a194e3aae373f8476a290c5271bca17e2256d02064359016292e793e91f42bcc60405cabdcd8cbd5bb44d5042e7f2a6ed3e909d7591cea28bc4c1ffab7a467345bdb48914b54b52d9ef16d2419c73033f89acfd35":"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"b98dec7c2753f74fc14bbf17cc1ff646eb12e06a69668171df92fa5769803b9f901c0e51a7c37a93c25ed6bb14f0adfe32fa3addf1745a94b3aeb4b6aa70669f82e2f1d31fd78b0ada66ad5dd2f944d009987bb328dca4835e608cd034bdb8670e80537c1644e5cfa8a9368fd122af18a535e479f04f543a71acc5cc5817931cfe72b9907d06ce26fc45d3121f3904cbd7e4d8cbb3defc784eddf018022f55a6dbffcf6fe5b27ae02237f113fc2ac8d6b3eff3b397ea5ceeae4cd98433cc1916c7283920ea80ba130186bfed51cce07073a8e998478897e23df673142f3b478a8a3f12df6e59dc07e4261500c08416ffb73189f24568083d7772563ea5e0d31d2a048916b52094ee0c1b3512dbc319afe56881adb40327a545b08b2825ba09732bb4925a19efe75188154a1a1c1e90ce2818f3bc16cbe17b80b26f665926276a9c47abc41772fa7c602a5d2aba39b592aa7c59e88e2296aea3a5c16a5b59b1a90309f63d9cdb0b6c0115348f348a33851f98782f6ff1089325620865cf3c29fc8926c900e2058f882cfcc139ae1998f3f0aec64e1f656575af7fd2644977c4860a66394b5ff67aefd6bbae698c7ce0aa4fc9f4d2d9edf06635e3c45c58fbcb32237892fd27435d19a68e88739ff8f0d55064e6e4703e975da9fa4e7880ec33607ffd02ab60f22e40e98d359780cd80aa38dd743c8c1da4032f731d4099183f99":"1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff9f4fbecba3db8ed94267be31df360feaffb1151ef5b5a8e51777f09d38072bcb1b1ad15d80d5448fd0edb41cc499f8eebae2af26569427a26d0afeaa833173d6ae4e5f84eb88c0c68c29baecf7ec5af2c1c5577336ca9482690f1c94597654afda84c6fb74df95cdd08fa9a66296126b4061b0530d124f3797426a08f72e90ef4994eeb348f5e92bd12d41cd3343a9e271a2f73d2cc7ffbd65bf64fb63e759f312e615aae01ae9f4573a21f1a70f56a61cfbb94d8f96fcf06c2b3216ed9574f6888df86cd5e471b641507ac6815ca781f6d31e69d6848e542a7c57dc21109b5574b63365a19273783fafc93639c414b9475ea5ea82e73958ff5fdba967d52721ff71209e5a3db3c580e1bfd142ba4b8ab77eb16cb488d46a04a672662cd108b7e9c58ba13dfb850653208f81956539475ffce85e0b0da59e5bd8d90051be9b2cc99e37c060ce09814e1524458bfb5427d7a16b672682be448fa16464fcb3e7f1dca6812a2c5a9814b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae6565ff2815c2c09b1a1f5" + +CRYPT_EAL_PkeySetPrv/Pub: +SDV_CRYPTO_PAILLIER_SET_KEY_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeyDupCtx: +SDV_CRYPTO_PAILLIER_DUP_CTX_API_TC001:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":1024 + +CRYPT_EAL_PkeyGetSecurityBits: +SDV_CRYPTO_PAILLIER_GET_SECURITY_BITS_FUNC_TC001:"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c6":"b98dec7c2753f74fc14bbf17cc1ff646eb12e06a69668171df92fa5769803b9f901c0e51a7c37a93c25ed6bb14f0adfe32fa3addf1745a94b3aeb4b6aa70669f82e2f1d31fd78b0ada66ad5dd2f944d009987bb328dca4835e608cd034bdb8670e80537c1644e5cfa8a9368fd122af18a535e479f04f543a71acc5cc5817931cfe72b9907d06ce26fc45d3121f3904cbd7e4d8cbb3defc784eddf018022f55a6dbffcf6fe5b27ae02237f113fc2ac8d6b3eff3b397ea5ceeae4cd98433cc1916c7283920ea80ba130186bfed51cce07073a8e998478897e23df673142f3b478a8a3f12df6e59dc07e4261500c08416ffb73189f24568083d7772563ea5e0d31d2a048916b52094ee0c1b3512dbc319afe56881adb40327a545b08b2825ba09732bb4925a19efe75188154a1a1c1e90ce2818f3bc16cbe17b80b26f665926276a9c47abc41772fa7c602a5d2aba39b592aa7c59e88e2296aea3a5c16a5b59b1a90309f63d9cdb0b6c0115348f348a33851f98782f6ff1089325620865cf3c29fc8926c900e2058f882cfcc139ae1998f3f0aec64e1f656575af7fd2644977c4860a66394b5ff67aefd6bbae698c7ce0aa4fc9f4d2d9edf06635e3c45c58fbcb32237892fd27435d19a68e88739ff8f0d55064e6e4703e975da9fa4e7880ec33607ffd02ab60f22e40e98d359780cd80aa38dd743c8c1da4032f731d4099183f99":112 + diff --git a/testcode/sdv/testcase/crypto/pbkdf2/test_suite_sdv_eal_kdf_pbkdf2.c b/testcode/sdv/testcase/crypto/pbkdf2/test_suite_sdv_eal_kdf_pbkdf2.c new file mode 100644 index 00000000..1810d4e0 --- /dev/null +++ b/testcode/sdv/testcase/crypto/pbkdf2/test_suite_sdv_eal_kdf_pbkdf2.c @@ -0,0 +1,123 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "securec.h" +#include "crypt_eal_kdf.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +/* END_HEADER */ + +#define DATA_LEN (64) +#define ITERATION_COUNT (1024) +#define DATA_MAX_LEN (512) +#define TEST_FAIL (-1) +#define TEST_SUCCESS (0) + +/** + * @test SDV_CRYPT_EAL_KDF_PBKDF2_API_TC001 + * @title pbkdf2 api test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_Pbkdf2 and set the key length to 0, expected result 1. + * 2.Call CRYPT_EAL_Pbkdf2 and set the key is null but keyLen not 0, expected result 2. + * 3.Call CRYPT_EAL_Pbkdf2 and set the salt length to 0, expected result 3. + * 4.Call CRYPT_EAL_Pbkdf2 and set the salt is null but saltLen not 0, expected result 4. + * 5.Call CRYPT_EAL_Pbkdf2 and set number of iterations to 0, expected result 5. + * 6.Call CRYPT_EAL_Pbkdf2 and output is null or outlen is 0, expected result 6. + * 7.Call CRYPT_EAL_Pbkdf2 use all mac algorithm ID, expected result 7. + * @expect + * 1.Return CRYPT_SUCCESS. + * 2.Return CRYPT_NULL_INPUT. + * 3.Return CRYPT_SUCCESS. + * 4.Return CRYPT_NULL_INPUT. + * 5.Return CRYPT_PBKDF2_PARAM_ERROR. + * 6.Return CRYPT_PBKDF2_PARAM_ERROR. + * 7.All successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_PBKDF2_API_TC001(void) +{ + TestMemInit(); + uint32_t keyLen = DATA_LEN; + uint8_t key[DATA_LEN]; + uint32_t saltLen = DATA_LEN; + uint8_t salt[DATA_LEN]; + uint32_t it = ITERATION_COUNT; // The number of iterations cannot be less than 1024.. GM/T 0091-2020 + uint32_t outLen = DATA_LEN; + uint8_t out[DATA_LEN]; + + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, NULL, 0, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, 0, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, NULL, keyLen, salt, saltLen, it, out, outLen), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, NULL, 0, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, salt, 0, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, NULL, saltLen, it, out, outLen), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, salt, saltLen, 0, out, outLen), + CRYPT_PBKDF2_PARAM_ERROR); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, salt, saltLen, it, NULL, outLen), + CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, salt, saltLen, it, out, 0), + CRYPT_PBKDF2_PARAM_ERROR); + + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_MD5, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA1, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA224, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA384, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA512, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SM3, key, keyLen, salt, saltLen, it, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_HkdfIsValidAlgId(CRYPT_MAC_HMAC_MD5), true); + ASSERT_EQ(CRYPT_EAL_Pbkdf2IsValidAlgId(CRYPT_MAC_HMAC_MD5), true); + ASSERT_EQ(CRYPT_EAL_Kdftls12IsValidAlgId(CRYPT_MAC_HMAC_SHA256), true); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001 + * @title Perform the vector test to check whether the calculation result is consistent with the standard output. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_Pbkdf2 get output, expected result 1. +* 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Successful. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001(int algId, Hex *key, Hex *salt, int it, Hex *result) +{ + if (IsHmacAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + uint32_t outLen = result->len; + uint8_t *out = malloc(outLen * sizeof(uint8_t)); + + ASSERT_TRUE(out != NULL); + ASSERT_EQ(CRYPT_EAL_Pbkdf2(algId, key->x, key->len, salt->x, salt->len, it, out, outLen), CRYPT_SUCCESS); + ASSERT_COMPARE("result cmp", out, outLen, result->x, result->len); +exit: + if (out != NULL) { + free(out); + } +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/pbkdf2/test_suite_sdv_eal_kdf_pbkdf2.data b/testcode/sdv/testcase/crypto/pbkdf2/test_suite_sdv_eal_kdf_pbkdf2.data new file mode 100644 index 00000000..9044eb44 --- /dev/null +++ b/testcode/sdv/testcase/crypto/pbkdf2/test_suite_sdv_eal_kdf_pbkdf2.data @@ -0,0 +1,23 @@ +SDV_CRYPT_EAL_KDF_PBKDF2_API_TC001 api test +SDV_CRYPT_EAL_KDF_PBKDF2_API_TC001: + +Test vectors for rfc6070 HMAC-SHA-1 #1 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"70617373776f7264":"73616c74":1:"0c60c80f961f0e71f3a9b524af6012062fe037a6" + +Test vectors for rfc6070 HMAC-SHA-1 #2 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"70617373776f7264":"73616c74":2:"ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957" + +Test vectors for rfc6070 HMAC-SHA-1 #3 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"70617373776f7264":"73616c74":4096:"4b007901b765489abead49d926f721d065a429c1" + +Test vectors for rfc6070 HMAC-SHA-1 #5 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:"3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038" + +Test vectors for rfc6070 HMAC-SHA-1 #6 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA1:"7061737300776f7264":"7361006c74":4096:"56fa6aa75548099dcc37d7f03425e0c3" + +Test vectors for rfc7914 HMAC-SHA-256 #1 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"706173737764":"73616c74":1:"55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783" + +Test vectors for rfc7914 HMAC-SHA-256 #2 +SDV_CRYPT_EAL_KDF_PBKDF2_FUN_TC001:CRYPT_MAC_HMAC_SHA256:"50617373776f7264":"4e61436c":80000:"4ddcd8f60b98be21830cee5ef22701f9641a4418d04c0414aeff08876b34ab56a1d425a1225833549adb841b51c9b3176a272bdebba1d078478f62b397f33c8d" diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa.base.c b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa.base.c new file mode 100644 index 00000000..df797bca --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa.base.c @@ -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. + */ + +#include +#include +#include +#include + +#include "crypt_bn.h" +#include "bsl_sal.h" +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "stub_replace.h" +#include "crypt_eal_rand.h" +#include "crypt_util_rand.h" +#include "eal_pkey_local.h" +#include "crypt_rsa.h" +#include "rsa_local.h" +#include "bn_basic.h" +#include "securec.h" + +#define SUCCESS 0 +#define FAIL (-1) + +#define PKCSV15_SIZE ((uint32_t)sizeof(CRYPT_RSA_PkcsV15Para)) +#define OAEP_SIZE ((uint32_t)sizeof(CRYPT_RSA_OaepPara)) +#define PSS_SIZE ((uint32_t)sizeof(CRYPT_RSA_PssPara)) + +#define RSA_MAX_KEYLEN 2048 +#define RSA_MIN_KEYLEN 128 + +#define MAX_PARAM_LEN 2048 +#define MAX_CIPHERTEXT_LEN 2048 + +#define PUB_EXP 3 +#define KEYLEN_IN_BYTES(keyLen) ((keyLen) >> 3) + +int32_t RandFunc(uint8_t *randNum, uint32_t randLen) +{ + const int maxNum = 255; + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % maxNum); + } + return 0; +} + +void *malloc_fail(uint32_t size) +{ + (void)size; + return NULL; +} + +void PubkeyFree(CRYPT_EAL_PkeyPub *pubkey) +{ + if (pubkey == NULL) { + return; + } + free(pubkey); +} + +void PrvkeyFree(CRYPT_EAL_PkeyPrv *prvkey) +{ + if (prvkey == NULL) { + return; + } + free(prvkey); +} + +#define TMP_BUFF_LEN 2048 +static uint8_t g_RandBuf[TMP_BUFF_LEN]; +int32_t STUB_ReplaceRandom(uint8_t *r, uint32_t randLen) +{ + if (randLen > TMP_BUFF_LEN) { + return -1; + } + for (uint32_t i = 0; i < randLen; i++) { + r[i] = g_RandBuf[i]; + } + return 0; +} + +void SetRsaPara(CRYPT_EAL_PkeyPara *para, uint8_t *e, uint32_t eLen, uint32_t bits) +{ + para->id = CRYPT_PKEY_RSA; + para->para.rsaPara.e = e; + para->para.rsaPara.eLen = eLen; + para->para.rsaPara.bits = bits; +} + +void SetRsaPubKey(CRYPT_EAL_PkeyPub *pubKey, uint8_t *n, uint32_t nLen, uint8_t *e, uint32_t eLen) +{ + pubKey->id = CRYPT_PKEY_RSA; + pubKey->key.rsaPub.n = n; + pubKey->key.rsaPub.nLen = nLen; + pubKey->key.rsaPub.e = e; + pubKey->key.rsaPub.eLen = eLen; +} + +void SetRsaPrvKey(CRYPT_EAL_PkeyPrv *prvKey, uint8_t *n, uint32_t nLen, uint8_t *d, uint32_t dLen) +{ + prvKey->id = CRYPT_PKEY_RSA; + prvKey->key.rsaPrv.n = n; + prvKey->key.rsaPrv.nLen = nLen; + prvKey->key.rsaPrv.d = d; + prvKey->key.rsaPrv.dLen = dLen; +} diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_api.c b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_api.c new file mode 100644 index 00000000..068edfdd --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_api.c @@ -0,0 +1,1443 @@ +/* + * 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_BASE test_suite_sdv_eal_rsa */ + +/* BEGIN_HEADER */ +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_RSA_NEW_API_TC001 + * @title RSA CRYPT_EAL_PkeyNewCtx test. + * @precon nan + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method to create ctx, algId is CRYPT_PKEY_RSA, expected result 1. + * 2. Release the ctx. + * 3. Repeat steps 1 to 2 for 100 times. + * @expect + * 1. The returned result is not empty. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_NEW_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *pkey = NULL; + + /* Run 100 times */ + for (int i = 0; i < 100; i++) { + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + CRYPT_EAL_PkeyFreeCtx(pkey); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_NEW_API_TC002 + * @title RSA CRYPT_EAL_PkeyNewCtx test: Malloc failed. + * @precon Mock BSL_SAL_Malloc to malloc_fail. + * @brief + * 1. Call the CRYPT_EAL_PkeyNewCtx method to create ctx, algId is CRYPT_PKEY_RSA, expected result 1. + * 2. Release the ctx. + * 3. Reset the BSL_SAL_Malloc. + * @expect + * 1. Failed to create the ctx. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_NEW_API_TC002(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + FuncStubInfo tmpRpInfo = {0}; + + STUB_Init(); + ASSERT_TRUE(STUB_Replace(&tmpRpInfo, BSL_SAL_Malloc, malloc_fail) == 0); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey == NULL); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_PARA_API_TC001 + * @title RSA CRYPT_EAL_PkeySetPara: The e value of para is invalid. + * @precon Create the contexts of the rsa algorithm. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPara method: + * (1) e = NULL, expected result 1. + * (2) e len = 0, expected result 1. + * (3) e = 0, expected result 2. + * (4) e is even, expected result 2. + * (5) e len = 1025, expected result 1. + * @expect + * 1. CRYPT_EAL_ERR_NEW_PARA_FAIL + * 2. CRYPT_RSA_ERR_E_VALUE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_PARA_API_TC001(void) +{ + uint8_t e[] = {1, 0, 1}; + uint8_t e2[] = {1, 0}; + uint8_t e0[] = {0, 0, 0}; + uint8_t longE[1025] = {0}; + longE[0] = 0x01; + longE[1024] = 0x01; // The tail of 1024 is set to 1. + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + SetRsaPara(¶, e, 3, 1024); // bits: 1024 is valid + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + para.para.rsaPara.e = NULL; + ASSERT_TRUE_AND_LOG("e = NULL", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.rsaPara.eLen = 0; + ASSERT_TRUE_AND_LOG("e len = 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + + para.para.rsaPara.e = e0; + para.para.rsaPara.eLen = 1; + ASSERT_TRUE_AND_LOG("e = 0", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_RSA_ERR_E_VALUE); + + para.para.rsaPara.eLen = 2; + para.para.rsaPara.e = e2; + ASSERT_TRUE_AND_LOG("e is even", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_RSA_ERR_E_VALUE); + + para.para.rsaPara.eLen = 1025; // 1025 is invalid, but the length is sufficient. + para.para.rsaPara.e = longE; + ASSERT_TRUE_AND_LOG("e len = 1025", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_EAL_ERR_NEW_PARA_FAIL); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_PARA_API_TC002 + * @title RSA CRYPT_EAL_PkeySetPara: The bits value of para is invalid. + * @precon Create the contexts of the rsa algorithm. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPara method with invalid bits, expected result 1. + * @expect + * 1. CRYPT_EAL_ERR_NEW_PARA_FAIL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_PARA_API_TC002(int bits) +{ + uint8_t e[] = {1, 0, 1}; + CRYPT_EAL_PkeyPara para = {0}; + + SetRsaPara(¶, e, 3, bits); // eLen = 3 + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_EAL_ERR_NEW_PARA_FAIL); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_PARA_API_TC003 + * @title RSA CRYPT_EAL_PkeySetPara: Success. + * @precon Create the contexts of the rsa algorithm. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPara method, key len is 1024|1025|5120|16384 bits, expected result 1. + * @expect + * 1. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_PARA_API_TC003(void) +{ + uint8_t e3[] = {1, 0, 1}; + uint8_t e5[] = {1, 0, 0, 0, 1}; + uint8_t e7[] = {1, 0, 0, 0, 0, 0, 1}; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + SetRsaPara(¶, e3, 3, 1024); // Valid parameters: elen = 3, bits =1024 + ASSERT_TRUE_AND_LOG("1k key", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + para.para.rsaPara.bits = 1025; + ASSERT_TRUE_AND_LOG("1025 bits key", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + SetRsaPara(¶, e5, 5, 5120); + ASSERT_TRUE_AND_LOG("5k key", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + SetRsaPara(¶, e7, 7, 16384); + ASSERT_TRUE_AND_LOG("16k key", CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GEN_API_TC001 + * @title RSA CRYPT_EAL_PkeyGen: No regist rand. + * @precon Create the contexts of the rsa algorithm and set para. + * @brief + * 1. Call the CRYPT_EAL_PkeyGen method to generate a key pair, expected result 1. + * @expect + * 1. Failed to genrate a key pair, the return value is CRYPT_NO_REGIST_RAND. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GEN_API_TC001(void) +{ + uint8_t e[] = {1, 0, 1}; + CRYPT_EAL_PkeyPara para = {0}; + + SetRsaPara(¶, e, 3, 1024); // Valid parameters: elen = 3, bits =1024 + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_NO_REGIST_RAND); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GET_PUB_API_TC001 + * @title RSA CRYPT_EAL_PkeyGetPub test. + * @precon 1. Create the context of the rsa algorithm. + * 2. Initialize the DRBG. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPub method without public key, expected result 1 + * 2. Set para and generate a key pair, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPub method: + * (1) pkey = NULL, expected result 1. + * (2) pub = NULL, expected result 1. + * (3) n = NULL, expected result 1. + * (4) n != NULL and nLen = 0, expected result 3. + * (5) e = NULL, expected result 1. + * (6) e != NULL, eLen = 0, expected result 3. + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_BN_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GET_PUB_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + uint8_t e[] = {1, 0, 1}; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + uint8_t pubE[600]; + uint8_t pubN[600]; + + SetRsaPara(¶, e, 3, 1024); + SetRsaPubKey(&pubKey, pubE, 600, pubN, 600); // 600 bytes > 1024 bits + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + /* Missing public key */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(NULL, &pubKey), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, NULL), CRYPT_NULL_INPUT); + + /* n = NULL */ + pubKey.key.rsaPub.n = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_NULL_INPUT); + pubKey.key.rsaPub.n = pubN; + + /* n != NULL and nLen = 0 */ + pubKey.key.rsaPub.nLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + pubKey.key.rsaPub.nLen = 600; + + /* e = NULL */ + pubKey.key.rsaPub.e = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_NULL_INPUT); + pubKey.key.rsaPub.e = pubE; + + /* e != NULL, eLen = 0 */ + pubKey.key.rsaPub.eLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GET_PRV_API_TC001 + * @title RSA CRYPT_EAL_PkeyGetPrv: Bad private key. + * @precon 1. Create the context of the rsa algorithm. + * 2. Initialize the DRBG. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPrv method without private key, expected result 1 + * 2. Set para and generate a key pair, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPrv method: + * (1) pkey = NULL, expected result 1. + * (2) prv = NULL, expected result 1. + * (3) p = NULL and q = NULL, expected result 2. + * (4) p = NULL and q != NULL, expected result 1. + * (5) p != NULL and q != NULL, expected result 2. + * (6) d = NULL, expected result 1. + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GET_PRV_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPrv prvKey = {0}; + + CRYPT_EAL_PkeyPara para = {0}; + uint8_t e[] = {1, 0, 1}; + uint8_t prvD[600]; + uint8_t prvN[600]; + uint8_t prvP[600]; + uint8_t prvQ[600]; + + SetRsaPrvKey(&prvKey, prvN, 600, prvD, 600); + SetRsaPara(¶, e, 3, 1024); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + /* Missing private key */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_NULL_INPUT); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(NULL, &prvKey), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, NULL), CRYPT_NULL_INPUT); + + /* p is NULL and q is NULL */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_SUCCESS); + + /* p = NULL and q != NULL */ + prvKey.key.rsaPrv.q = prvQ; + prvKey.key.rsaPrv.qLen = 600; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_NULL_INPUT); + + /* p != NULL and q != NULL */ + prvKey.key.rsaPrv.p = prvP; + prvKey.key.rsaPrv.pLen = 600; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_SUCCESS); + + /* d = NULL */ + prvKey.key.rsaPrv.d = NULL; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SET_PRV_API_TC001 + * @title RSA CRYPT_EAL_PkeySetPrv: Bad private key. + * @precon Create the contexts of the rsa algorithm and set para: + * pkey1: Generate a key pair. + * pkey2: set the private key. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPrv method: + * (1) d is 0, expected result 1. + * (2) d is 1, expected result 1. + * (3) n is 0, expected result 2. + * (4) p is 0, expected result 1. + * (5) q is 0, expected result 1. + * (6) nLen is 2049, expected result 2. + * (7) p is null, expected result 3. + * @expect + * 1. CRYPT_RSA_ERR_INPUT_VALUE + * 2. CRYPT_RSA_ERR_KEY_BITS + * 3. CRYPT_RSA_NO_KEY_INFO + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SET_PRV_API_TC001(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + uint8_t e[] = {1, 0, 1}; + uint8_t prvD[600]; + uint8_t prvN[2500]; + uint8_t prvP[600]; + uint8_t prvQ[600]; + uint8_t prvE[600]; + + SetRsaPrvKey(&prvKey, prvN, 600, prvD, 600); + SetRsaPara(¶, e, 3, 1024); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + + (void)memset_s(prvD, sizeof(prvD), 0x00, sizeof(prvD)); + ASSERT_TRUE_AND_LOG("d is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + prvD[sizeof(prvD) - 1] = 1; + ASSERT_TRUE_AND_LOG("d is 1", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + (void)memset_s(prvN, sizeof(prvN), 0x00, sizeof(prvN)); + ASSERT_TRUE_AND_LOG("n is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_ERR_KEY_BITS); + + prvKey.key.rsaPrv.q = prvQ; + prvKey.key.rsaPrv.qLen = 600; // 600 bytes > 1024 bits + prvKey.key.rsaPrv.p = prvP; + prvKey.key.rsaPrv.pLen = 600; // 600 bytes > 1024 bits + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + (void)memset_s(prvP, sizeof(prvP), 0x00, sizeof(prvP)); + ASSERT_TRUE_AND_LOG("p is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + (void)memset_s(prvQ, sizeof(prvQ), 0x00, sizeof(prvQ)); + ASSERT_TRUE_AND_LOG("q is 0", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.rsaPrv.nLen = 2049; // 2049 > MAx n len + ASSERT_TRUE_AND_LOG("nLen is 2049", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_ERR_KEY_BITS); + + prvKey.key.rsaPrv.nLen = 600; // 600 bytes > 1024 bits + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + prvKey.key.rsaPrv.p = NULL; + ASSERT_TRUE_AND_LOG("p is NULL", CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_RSA_NO_KEY_INFO); + prvKey.key.rsaPrv.p = prvP; + + prvKey.key.rsaPrv.e = prvE; + prvKey.key.rsaPrv.eLen = 600; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_SUCCESS); + ASSERT_COMPARE("rsa e", prvKey.key.rsaPrv.e, prvKey.key.rsaPrv.eLen, e, 3); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey2, &prvKey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey) == CRYPT_SUCCESS); + ASSERT_COMPARE("rsa e", prvKey.key.rsaPrv.e, prvKey.key.rsaPrv.eLen, e, 3); +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SET_PRV_API_TC002 + * @title RSA CRYPT_EAL_PkeySetPrv: Specification test. + * @precon Create the context(pkey) of the rsa algorithm. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPrv method: + * (1) d = n, expected result 1 + * (2) n less than 1024 bits, expected result 2 + * (3) n greater than 16384 bits, expected result 2 + * (4) d greater than 16384 bits, expected result 2 + * (5) d greater than n, expected result 2 + * (6) Min len success case, expected result 3 + * (7) Max len success case, expected result 3 + * @expect + * 1. CRYPT_RSA_ERR_INPUT_VALUE + * 2. CRYPT_RSA_ERR_KEY_BITS + * 3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SET_PRV_API_TC002(void) +{ + uint8_t prvD[2050]; // max rsa key len is 16384 bits, 16384/8 = 2048, 2050 > 2048 + uint8_t prvN[2050]; // max rsa key len is 16384 bits, 16384/8 = 2048, 2050 > 2048 + CRYPT_EAL_PkeyPrv prvKey = {0}; + + (void)memset_s(prvD, sizeof(prvD), 0xff, sizeof(prvD)); + (void)memset_s(prvN, sizeof(prvN), 0xff, sizeof(prvN)); + SetRsaPrvKey(&prvKey, prvN, RSA_MIN_KEYLEN, prvD, RSA_MIN_KEYLEN); + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE_AND_LOG("d = n", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + prvKey.key.rsaPrv.nLen = RSA_MIN_KEYLEN - 1; + ASSERT_TRUE_AND_LOG("n less than 1024 bits", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_RSA_ERR_KEY_BITS); + + prvKey.key.rsaPrv.nLen = RSA_MAX_KEYLEN + 1; + ASSERT_TRUE_AND_LOG("n greater than 16384 bits", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_RSA_ERR_KEY_BITS); + + prvKey.key.rsaPrv.nLen = RSA_MAX_KEYLEN; + prvKey.key.rsaPrv.dLen = RSA_MAX_KEYLEN + 1; + ASSERT_TRUE_AND_LOG("d greater than 16384 bits", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_RSA_ERR_KEY_BITS); + + prvKey.key.rsaPrv.nLen = RSA_MIN_KEYLEN; + prvKey.key.rsaPrv.dLen = RSA_MIN_KEYLEN + 1; + ASSERT_TRUE_AND_LOG("d greater than n", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_RSA_ERR_KEY_BITS); + + prvKey.key.rsaPrv.dLen = RSA_MIN_KEYLEN; + prvD[0] = 0; + ASSERT_TRUE_AND_LOG("Min len success case", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_SUCCESS); + + prvKey.key.rsaPrv.nLen = RSA_MAX_KEYLEN; + prvKey.key.rsaPrv.dLen = RSA_MAX_KEYLEN; + ASSERT_TRUE_AND_LOG("Max len success case", CRYPT_EAL_PkeySetPrv(pkey, &prvKey) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SET_PUB_API_TC001 + * @title RSA CRYPT_EAL_PkeyGetPub: Bad public key. + * @precon Create the contexts of the rsa algorithm and set para: + * pkey1: Generate a key pair. + * pkey2: Set the public key.. + * @brief + * 1. Call the CRYPT_EAL_PkeyGetPub method: + * (1) nLen > maxNLen, expected result 1 + * (2) n is Null, expected result 2 + * (3) n is 0, expected result 1 + * (4) e is NULL, expected result 2 + * (5) e is 0, expected result 3 + * @ex pect + * 1. CRYPT_RSA_ERR_KEY_BITS + * 2. CRYPT_NULL_INPUT + * 3. CRYPT_RSA_ERR_INPUT_VALUE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SET_PUB_API_TC001(void) +{ + uint8_t e[] = {1, 0, 1}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey; + uint8_t pubE[600]; + uint8_t pubN[2500]; + SetRsaPara(¶, e, 3, 1024); + SetRsaPubKey(&pubKey, pubN, 600, pubE, 600); + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey2, ¶) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(pkey) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + pubKey.key.rsaPub.nLen = 2049; + ASSERT_TRUE_AND_LOG("nLen > maxNLen", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + pubKey.key.rsaPub.nLen = 600; // 600 bytes > 1024 bits + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + pubKey.key.rsaPub.n = NULL; + ASSERT_TRUE_AND_LOG("n is Null", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_NULL_INPUT); + + pubKey.key.rsaPub.n = pubN; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + (void)memset_s(pubN, sizeof(pubN), 0x00, sizeof(pubN)); + ASSERT_TRUE_AND_LOG("n is 0", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + pubKey.key.rsaPub.e = NULL; + ASSERT_TRUE_AND_LOG("e is Null", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_NULL_INPUT); + + pubKey.key.rsaPub.e = pubE; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(pkey, &pubKey) == CRYPT_SUCCESS); + (void)memset_s(pubE, sizeof(pubE), 0x00, sizeof(pubE)); + ASSERT_TRUE_AND_LOG("e is 0", CRYPT_EAL_PkeySetPub(pkey2, &pubKey) == CRYPT_RSA_ERR_INPUT_VALUE); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SET_PUB_API_TC002 + * @title RSA CRYPT_EAL_PkeySetPub: Specification test. + * @precon Create the context(pkey) of the rsa algorithm. + * @brief + * 1. Call the CRYPT_EAL_PkeySetPub method: + * (1) e = n, expected result 1 + * (2) nLen < 1024 bits, expected result 2 + * (3) eLen > 16384 bits, expected result 2 + * (3) nLen > 16384 bits, expected result 2 + * (4) e > n, expected result 2 + * (6) Min len success case, expected result 3 + * (7) Max len success case, expected result 3 + * (8) e = 1, expected result 1 + * (9) n = 1, expected result 1 + * @expect + * 1. CRYPT_RSA_ERR_INPUT_VALUE + * 2. CRYPT_RSA_ERR_KEY_BITS + * 3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SET_PUB_API_TC002(void) +{ + uint8_t pubE[2050]; // max rsa key len is 16384 bits, 16384/8 = 2048, 2050 > 2048 + uint8_t pubN[2050]; // max rsa key len is 16384 bits, 16384/8 = 2048, 2050 > 2048 + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pubKey = {0}; + + SetRsaPubKey(&pubKey, pubN, RSA_MIN_KEYLEN, pubE, RSA_MIN_KEYLEN); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + (void)memset_s(pubE, sizeof(pubE), 0xff, sizeof(pubE)); + (void)memset_s(pubN, sizeof(pubN), 0xff, sizeof(pubN)); + ASSERT_TRUE_AND_LOG("e = n", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + pubKey.key.rsaPub.nLen = RSA_MIN_KEYLEN - 1; + ASSERT_TRUE_AND_LOG("n less than 1024 bits", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + pubKey.key.rsaPub.nLen = RSA_MAX_KEYLEN; + pubKey.key.rsaPub.eLen = RSA_MAX_KEYLEN + 1; + ASSERT_TRUE_AND_LOG("e greater than 16384 bits", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + pubKey.key.rsaPub.nLen = RSA_MAX_KEYLEN + 1; + pubKey.key.rsaPub.eLen = RSA_MAX_KEYLEN; + ASSERT_TRUE_AND_LOG("n greater than 16384 bits", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + pubKey.key.rsaPub.nLen = RSA_MIN_KEYLEN; + pubKey.key.rsaPub.eLen = RSA_MIN_KEYLEN + 1; + ASSERT_TRUE_AND_LOG("e greater than n", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + pubE[0] = 0; + pubKey.key.rsaPub.eLen = RSA_MIN_KEYLEN; + ASSERT_TRUE_AND_LOG("Min len success case", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_SUCCESS); + + pubKey.key.rsaPub.nLen = RSA_MAX_KEYLEN; + pubKey.key.rsaPub.eLen = RSA_MAX_KEYLEN; + ASSERT_TRUE_AND_LOG("Max len failed case", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_KEY_BITS); + + (void)memset_s(pubE, sizeof(pubE), 0, sizeof(pubE)); + ASSERT_TRUE_AND_LOG("e = 0", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_INPUT_VALUE); + + pubE[RSA_MAX_KEYLEN - 1] = 1; + ASSERT_TRUE_AND_LOG("e = 1", CRYPT_EAL_PkeySetPub(pkey, &pubKey) == CRYPT_RSA_ERR_INPUT_VALUE); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_ENC_API_TC001 + * @title RSA CRYPT_EAL_PkeyEncrypt: Test the validity of input parameters. + * @precon Create the context of the rsa algorithm: + * @brief + * 1. Call the CRYPT_EAL_PkeyEncrypt method without public key, expected result 1 + * 2. Set pubkey and call the CRYPT_EAL_PkeyEncrypt method, expected result 2 + * 3. Set the oaep paading mode, expected result 3 + * 4. Call the CRYPT_EAL_PkeyEncrypt method: + * (1) pkey = NULL, expected result 4 + * (2) data = NULL, expected result 4 + * (3) data != NULL, dataLen = 0, expected result 3 + * (4) data != NULL dataLen > k - 2*hashLen - 2, expected result 5 + * (5) out = NULL, expected result 4 + * (6) outLen = NULL, expected result 4 + * (7) outLen = 0, expected result 6 + * @expect + * 1. CRYPT_RSA_NO_KEY_INFO + * 2. CRYPT_RSA_PAD_NO_SET_ERROR + * 3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_RSA_ERR_ENC_BITS + * 6. CRYPT_RSA_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_ENC_API_TC001(Hex *n, Hex *e, int hashId, Hex *in) +{ + uint8_t crypt[TMP_BUFF_LEN]; + uint32_t cryptLen = TMP_BUFF_LEN; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pubkey = {0}; + CRYPT_RSA_OaepPara pad = {.mdId = hashId, .mgfId = hashId}; + + SetRsaPubKey(&pubkey, n->x, n->len, e->x, e->len); + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, &cryptLen), CRYPT_RSA_NO_KEY_INFO); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pubkey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_RSA_PAD_NO_SET_ERROR); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &pad, OAEP_SIZE) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(NULL, in->x, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, NULL, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyEncrypt(pkey, in->x, 0, crypt, &cryptLen), CRYPT_SUCCESS); + // inLen > k-2hashLen-2 , 87 = (128 - 2 * 20 - 2) + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, 87, crypt, &cryptLen) == CRYPT_RSA_ERR_ENC_BITS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, NULL, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, NULL) == CRYPT_NULL_INPUT); + cryptLen = 0; + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_DEC_API_TC001 + * @title RSA CRYPT_EAL_PkeyDecrypt: Test the validity of input parameters. + * @precon Create the context of the rsa algorithm: + * @brief + * 1. Call the CRYPT_EAL_PkeyDecrypt method without private key, expected result 1 + * 2. Set private and call the CRYPT_EAL_PkeyDecrypt method, expected result 2 + * 3. Set the oaep paading mode, expected result 3 + * 4. Call the CRYPT_EAL_PkeyDecrypt method: + * (1) pkey = NULL, expected result 4 + * (2) data = NULL, expected result 4 + * (3) data != NULL, dataLen = 0, expected result 3 + * (4) data != NULL, dataLen iis invalid , expected result 5 + * (5) out = NULL, expected result 4 + * (6) outLen = NULL, expected result 4 + * (7) outLen = 0, expected result 6 + * (8) outLen = 2049(invalid), expected result 6 + * @expect + * 1. CRYPT_RSA_NO_KEY_INFO + * 2. CRYPT_RSA_PAD_NO_SET_ERROR + * 3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + * 5. CRYPT_RSA_ERR_DEC_BITS + * 6. CRYPT_RSA_ERR_INPUT_VALUE + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_DEC_API_TC001(Hex *n, Hex *d, int hashId, Hex *in) +{ + uint8_t crypt[TMP_BUFF_LEN]; + uint32_t cryptLen = TMP_BUFF_LEN; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_RSA_OaepPara pad = {.mdId = hashId, .mgfId = hashId}; + + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_RSA_NO_KEY_INFO); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prvkey) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen), CRYPT_RSA_PAD_NO_SET_ERROR); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &pad, OAEP_SIZE) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(NULL, in->x, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, NULL, in->len, crypt, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, 0, crypt, &cryptLen) == CRYPT_RSA_ERR_DEC_BITS); + const uint32_t invalidInLen = 1025; // 1025: invalid data length + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, invalidInLen, crypt, &cryptLen) == CRYPT_RSA_ERR_DEC_BITS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, NULL, &cryptLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, NULL) == CRYPT_NULL_INPUT); + + cryptLen = 0; + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_RSA_ERR_INPUT_VALUE); + cryptLen = 2049; // 2049 is an invalid data length. + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, in->x, in->len, crypt, &cryptLen) == CRYPT_RSA_ERR_INPUT_VALUE); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_CTRL_API_TC001 + * @title Rsa CRYPT_EAL_PkeyCtrl test. + * @precon Create the context of the rsa algorithm and set the private key(n, d). + * @brief + * 1. Call the CRYPT_EAL_PkeyCtrl method: + * (1) opt = CRYPT_CTRL_SET_RSA_RSAES_OAEP, val is null, len!=0, expected result 1 + * (2) opt = CRYPT_CTRL_SET_RSA_RSAES_OAEP, val is a valid value, len=0, expected result 2 + * (3) opt = CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, valis n, len!=0, expected result 3 + * (4) opt = CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, val is a valid value, len=0, expected result 4 + * (5) opt = CRYPT_CTRL_SET_RSA_EMSA_PSS, val is null, len!=0, expected result 5 + * (6) opt = CRYPT_CTRL_SET_RSA_EMSA_PSS, val is a valid value, len=0, expected result 6 + * (7) opt = CRYPT_CTRL_SET_RSA_EMSA_PSS, pss.saltLen is -4, expected result 7 + * (8) opt = CRYPT_CTRL_SET_RSA_SALT, expected result 8 + * (9) opt = CRYPT_CTRL_SET_RSA_EMSA_PSS, expected result 9 + * (10) opt = CRYPT_CTRL_SET_RSA_SALT, saltLen is 2500, expected result 10 + * (11) opt = CRYPT_CTRL_SET_RSA_SALT, expected result 11 + * (12) opt = CRYPT_CTRL_SET_RSA_PADDING, val is null, expected result 1 + * (13) opt = CRYPT_CTRL_SET_RSA_PADDING, len is 2, expected result 12 + * (14) opt = CRYPT_CTRL_SET_RSA_PADDING, val out of range, expected result 12 + * (15) opt = CRYPT_CTRL_SET_RSA_PADDING, val does not exceed range, expected result 9 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_EAL_PKEY_CTRL_ERROR + * 3. CRYPT_NULL_INPUT + * 4. CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR + * 5. CRYPT_NULL_INPUT + * 6. CRYPT_EAL_PKEY_CTRL_ERROR + * 7. CRYPT_RSA_ERR_SALT_LEN + * 8. CRYPT_RSA_SET_SALT_NOT_PSS_ERROR + * 9. CRYPT_SUCCESS + * 10. CRYPT_RSA_ERR_SALT_LEN + * 11. CRYPT_SUCCESS + * 12. CRYPT_RSA_SET_FLAG_LEN_ERROR + * 13. CRYPT_INVALID_ARG + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CTRL_API_TC001(Hex *n, Hex *d, Hex *salt, int hashId) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_RSA_OaepPara oaep = {.mdId = hashId, .mgfId = hashId}; + CRYPT_RSA_PssPara pss = {.saltLen = salt->len, .mdId = hashId, .mgfId = hashId}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {hashId}; + uint8_t badSalt[2500]; + (void)memset_s(badSalt, sizeof(badSalt), 'A', sizeof(badSalt)); + const uint32_t badSaltLen = 2500; // 2500 is greater than the maximum length. + + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + TestMemInit(); + CRYPT_RandRegist(STUB_ReplaceRandom); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prvkey), CRYPT_SUCCESS); + + // OAEP The parameter is a null pointer. + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, NULL, OAEP_SIZE), CRYPT_NULL_INPUT); + // OAEP The parameter length is 0. + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &oaep, 0), CRYPT_EAL_PKEY_CTRL_ERROR); + + // PKCS1.5 The parameter is a null pointer. + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, NULL, PKCSV15_SIZE), CRYPT_NULL_INPUT); + // PKCS1.5 The parameter length is 0. + ASSERT_EQ( + CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, &pkcsv15, 0), CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PSS, NULL, PSS_SIZE), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pss, 0), CRYPT_EAL_PKEY_CTRL_ERROR); + + /* PSS saltLen: - 1 - 2 - 3 0 are valid values, -4 is invalid. */ + pss.saltLen = -4; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pss, PSS_SIZE), CRYPT_RSA_ERR_SALT_LEN); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_SALT, salt->x, salt->len), CRYPT_RSA_SET_SALT_NOT_PSS_ERROR); + pss.saltLen = salt->len; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pss, PSS_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_SALT, badSalt, badSaltLen), CRYPT_RSA_ERR_SALT_LEN); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_SALT, salt->x, salt->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_PADDING, NULL, PSS_SIZE), CRYPT_NULL_INPUT); + int32_t pad = CRYPT_PKEY_EMSA_PKCSV15; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_PADDING, &pad, 2), CRYPT_RSA_SET_FLAG_LEN_ERROR); + pad = 0; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_PADDING, &pad, sizeof(pad)), CRYPT_INVALID_ARG); + pad = CRYPT_PKEY_RSA_PADDINGMAX; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_PADDING, &pad, sizeof(pad)), CRYPT_INVALID_ARG); + pad = CRYPT_PKEY_EMSA_PKCSV15; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_PADDING, &pad, sizeof(pad)), CRYPT_SUCCESS); + pad = CRYPT_PKEY_RSA_NO_PAD; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_PADDING, &pad, sizeof(pad)), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_CTRL_API_TC002 + * @title Rsa CRYPT_EAL_PkeyCtrl test. + * @precon Create the context of the rsa algorithm, set the private key(n, d) and set the padding type to pss. + * @brief + * 1. Call the CRYPT_EAL_PkeyCtrl method: + * (1) opt = CRYPT_CTRL_GET_RSA_PADDING, val is null, expected result 1 + * (2) opt = CRYPT_CTRL_GET_RSA_PADDING, expected result 2 + * (3) opt = CRYPT_CTRL_GET_RSA_MD, val is null, expected result 3 + * (4) opt = CRYPT_CTRL_GET_RSA_MD, expected result 4 + * (5) opt = CRYPT_CTRL_GET_RSA_MGF, val is null, expected result 5 + * (6) opt = CRYPT_CTRL_GET_RSA_MGF, expected result 6 + * (7) opt = CRYPT_CTRL_GET_RSA_SALT, val is null, expected result 7 + * (8) opt = CRYPT_CTRL_GET_RSA_SALT, expected result 8 + * (9) opt = CRYPT_CTRL_CLR_RSA_FLAG, val is null, expected result 9 + * (10) opt = CRYPT_CTRL_CLR_RSA_FLAG, expected result 10 + * @expect + * 1. CRYPT_NULL_INPUT + * 2. The return value is CRYPT_SUCCESS, and the output parameter(padType) value is pss. + * 3. CRYPT_NULL_INPUT + * 4. The return value is CRYPT_SUCCESS, and the output parameter(mdType) value is hashId. + * 5. CRYPT_NULL_INPUT + * 6. The return value is CRYPT_SUCCESS, and the output parameter(mgfId) value is hashId. + * 7. CRYPT_NULL_INPUT + * 8. The return value is CRYPT_SUCCESS, and the output parameter(saltLen) value is para.saltLen. + * 9. CRYPT_NULL_INPUT + * 10. CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CTRL_API_TC002(Hex *n, Hex *d, int hashId) +{ + uint32_t flag = CRYPT_RSA_BLINDING; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_RSA_PssPara para = {.saltLen = 10, .mdId = hashId, .mgfId = hashId}; // 10 is valid + + CRYPT_EAL_PkeyCtx *pkey = NULL; + + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prvkey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PSS, ¶, PSS_SIZE), CRYPT_SUCCESS); + + RSA_PadType padType = 0; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_PADDING, NULL, sizeof(RSA_PadType)), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(RSA_PadType)), CRYPT_SUCCESS); + ASSERT_EQ(padType, CRYPT_PKEY_EMSA_PSS); + + CRYPT_MD_AlgId mdType = 0; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_MD, NULL, sizeof(CRYPT_MD_AlgId)), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_MD, &mdType, sizeof(CRYPT_MD_AlgId)), CRYPT_SUCCESS); + ASSERT_EQ(mdType, hashId); + + CRYPT_MD_AlgId mgfId = 0; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_MGF, NULL, sizeof(CRYPT_MD_AlgId)), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_MGF, &mgfId, sizeof(CRYPT_MD_AlgId)), CRYPT_SUCCESS); + ASSERT_EQ(mgfId, hashId); + + int32_t saltLen = 0; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_SALT, NULL, sizeof(int32_t)), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_SALT, &saltLen, sizeof(int32_t)), CRYPT_SUCCESS); + ASSERT_EQ(saltLen, para.saltLen); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_CLR_RSA_FLAG, NULL, sizeof(uint32_t)) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_CLR_RSA_FLAG, (void *)&flag, sizeof(uint32_t)) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_CTRL_API_TC003 + * @title Rsa CRYPT_EAL_PkeyCtrl test: Set unsupported hash id to padding. + * @precon Create the context of the rsa algorithm, set the public key(n, e). + * @brief + * 1. Call the CRYPT_EAL_PkeyCtrl method: + * (1) opt = CRYPT_CTRL_SET_RSA_EMSA_PSS, the hash algorithm is md4, expected result 1 + * (2) opt = CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, the hash algorithm is md4,expected result 2 + * (3) opt = CRYPT_CTRL_SET_RSA_RSAES_OAEP, the hash algorithm is md4, expected result 3 + * (4) opt = CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, the hash algorithm is md4, expected result 4 + * @expect + * 1. CRYPT_EAL_ERR_ALGID + * 2. CRYPT_RSA_ERR_MD_ALGID + * 3. CRYPT_EAL_ERR_ALGID + * 4. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CTRL_API_TC003(int mdAlgId, Hex *n, Hex *e) +{ + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyPub publicKey; + CRYPT_RSA_PssPara padPss = {.saltLen = -1, .mdId = mdAlgId, .mgfId = mdAlgId}; + CRYPT_RSA_OaepPara padOaep = {.mdId = mdAlgId, .mgfId = mdAlgId}; + CRYPT_RSA_PkcsV15Para padPkcs = {.mdId = mdAlgId}; + + SetRsaPubKey(&publicKey, n->x, n->len, e->x, e->len); + + // Register memory and thread hooks. + TestMemInit(); + + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &publicKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &padPss, PSS_SIZE), CRYPT_EAL_ERR_ALGID); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &padPkcs, PKCSV15_SIZE), CRYPT_RSA_ERR_MD_ALGID); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &padOaep, OAEP_SIZE), CRYPT_EAL_ERR_ALGID); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, &padPkcs, PKCSV15_SIZE), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +int Compare_PubKey(CRYPT_EAL_PkeyPub *pubKey1, CRYPT_EAL_PkeyPub *pubKey2) +{ + if (pubKey1->key.rsaPub.nLen != pubKey2->key.rsaPub.nLen || pubKey1->key.rsaPub.eLen != pubKey2->key.rsaPub.eLen) { + return -1; // -1 indicates failure + } + if (memcmp(pubKey1->key.rsaPub.n, pubKey2->key.rsaPub.n, pubKey1->key.rsaPub.nLen) != 0 || + memcmp(pubKey1->key.rsaPub.e, pubKey2->key.rsaPub.e, pubKey1->key.rsaPub.eLen) != 0) { + return -1; // -1 indicates failure + } + return 0; +} + +int Compare_PrvKey(CRYPT_EAL_PkeyPrv *prvKey1, CRYPT_EAL_PkeyPrv *prvKey2) +{ + if (prvKey1->key.rsaPrv.dLen != prvKey2->key.rsaPrv.dLen || prvKey1->key.rsaPrv.nLen != prvKey2->key.rsaPrv.nLen || + prvKey1->key.rsaPrv.pLen != prvKey2->key.rsaPrv.pLen || prvKey1->key.rsaPrv.qLen != prvKey2->key.rsaPrv.qLen) { + return -1; // -1 indicates failure + } + if (memcmp(prvKey1->key.rsaPrv.d, prvKey2->key.rsaPrv.d, prvKey1->key.rsaPrv.dLen) != 0 || + memcmp(prvKey1->key.rsaPrv.n, prvKey2->key.rsaPrv.n, prvKey1->key.rsaPrv.nLen) != 0 || + memcmp(prvKey1->key.rsaPrv.p, prvKey2->key.rsaPrv.p, prvKey1->key.rsaPrv.pLen) != 0 || + memcmp(prvKey1->key.rsaPrv.q, prvKey2->key.rsaPrv.q, prvKey1->key.rsaPrv.qLen) != 0) { + return -1; // -1 indicates failure + } + return 0; +} + +/** + * @test SDV_CRYPTO_RSA_SET_KEY_API_TC001 + * @title Rsa: Set the public key and private key multiple times. + * @precon Create the contexts of the rsa algorithm and: + * pkey1: Set paran and generate a key pair: test obtaining the key. + * pkey2: Test set keys, and verify that the public and private keys can exist at the same time. + * @brief + * 1. pkey1: Get public key and get private key, expected result 1 + * 2. pkey2: + * (1) Set public key and set private key, expected result 1 + * (2) Get public key, get private key and check private key, expected result 2 + * (3) Set private key and set public key, expected result 3 + * (4) Get private key, get public key and check public key, expected result 4 + * @expect + * 1. CRYPT_SUCCESS + * 2. The obtained private key is equal to the set private key. + * 3. CRYPT_SUCCESS + * 4. The obtained public key is equal to the set public key. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SET_KEY_API_TC001(void) +{ + uint8_t e[] = {1, 0, 1}; + uint8_t pubE[600]; + uint8_t pubN[600]; + uint8_t prvD[600]; + uint8_t prvN[600]; + uint8_t prvP[600]; + uint8_t prvQ[600]; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + + SetRsaPubKey(&pubKey, pubE, 600, pubN, 600); // 600 bytes > 1024 bits + SetRsaPrvKey(&prvKey, prvN, 600, prvD, 600); + prvKey.key.rsaPrv.p = prvP; + prvKey.key.rsaPrv.pLen = 600; + prvKey.key.rsaPrv.q = prvQ; + prvKey.key.rsaPrv.qLen = 600; + SetRsaPara(¶, e, 3, 1024); + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *pkey1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + CRYPT_EAL_PkeyCtx *pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey1 != NULL && pkey2 != NULL); + + /* pkey1 */ + /* Generate a key pair. */ + ASSERT_TRUE(CRYPT_EAL_PkeySetPara(pkey1, ¶) == CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey1), CRYPT_SUCCESS); + + /* Get keys. */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey1, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey1, &prvKey), CRYPT_SUCCESS); + + /* pkey2 */ + /* Set public key and set private key. */ + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey2, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + + /* Get public key, get private key and check private key.*/ + SetRsaPubKey(&pubKey, pubE, 600, pubN, 600); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey2, &pubKey), CRYPT_SUCCESS); + SetRsaPrvKey(&prvKey, prvN, 600, prvD, 600); + prvKey.key.rsaPrv.p = prvP; + prvKey.key.rsaPrv.pLen = 600; + prvKey.key.rsaPrv.q = prvQ; + prvKey.key.rsaPrv.qLen = 600; + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + ASSERT_EQ(Compare_PrvKey(&prvKey, &prvKey), 0); + + /* Set private key and set public key. */ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey2, &pubKey), CRYPT_SUCCESS); + /* Get private key, get public key and check public key.*/ + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + SetRsaPubKey(&pubKey, pubE, 600, pubN, 600); + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey2, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(Compare_PubKey(&pubKey, &pubKey), 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_DUP_CTX_API_TC001 + * @title RSA CRYPT_EAL_PkeyDupCtx test. + * @precon Create the contexts of the rsa algorithm, set para and generate a key pair. + * @brief + * 1. Call the CRYPT_EAL_PkeyDupCtx mehod to dup rsa, expected result 1 + * @expect + * 1. Success. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_DUP_CTX_API_TC001(Hex *e, int bits) +{ + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyCtx *newPkey = NULL; + CRYPT_EAL_PkeyCtx *pkey = NULL; + SetRsaPara(¶, e->x, e->len, bits); + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), 0); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + CRYPT_RSA_Ctx *rsaCtx = (CRYPT_RSA_Ctx *)pkey->key; + ASSERT_TRUE(rsaCtx != NULL); + + newPkey = CRYPT_EAL_PkeyDupCtx(pkey); + ASSERT_TRUE(newPkey != NULL); + ASSERT_EQ(newPkey->references.count, 1); + CRYPT_RSA_Ctx *rsaCtx2 = (CRYPT_RSA_Ctx *)newPkey->key; + ASSERT_TRUE(rsaCtx2 != NULL); + + ASSERT_COMPARE("rsa compare n", + rsaCtx->prvKey->n->data, + rsaCtx->prvKey->n->size * sizeof(BN_UINT), + rsaCtx2->prvKey->n->data, + rsaCtx2->prvKey->n->size * sizeof(BN_UINT)); + + ASSERT_COMPARE("rsa compare d", + rsaCtx->prvKey->d->data, + rsaCtx->prvKey->d->size * sizeof(BN_UINT), + rsaCtx2->prvKey->d->data, + rsaCtx2->prvKey->d->size * sizeof(BN_UINT)); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(newPkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_CMP_API_TC001 + * @title RSA: CRYPT_EAL_PkeyCmp invalid parameter test. + * @precon para id and public key. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the rsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set public key for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set different public key for ctx2, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_RSA_NO_KEY_INFO + * 3. CRYPT_SUCCESS + * 4. CRYPT_RSA_NO_KEY_INFO + * 5. CRYPT_SUCCESS + * 6. CRYPT_RSA_PUBKEY_NOT_EQUAL + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CMP_API_TC001(Hex *n, Hex *e) +{ + uint8_t tmpE[] = {1, 0, 1}; + CRYPT_EAL_PkeyPub pub = {0}; + SetRsaPubKey(&pub, n->x, n->len, e->x, e->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_RSA_NO_KEY_INFO); // no key + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_RSA_NO_KEY_INFO); // ctx2 no pubkey + + SetRsaPubKey(&pub, n->x, n->len, tmpE, 3); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_RSA_PUBKEY_NOT_EQUAL); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001 + * @title RSA CRYPT_EAL_PkeyGetSecurityBits test. + * @precon nan + * @brief + * 1. Create the context of the rsa algorithm, expected result 1 + * 2. Set public key, expected result 2 + * 3. Call the CRYPT_EAL_PkeyVerify method and the parameter is correct, expected result 3 + * @expect + * 1. Success, and the context is not null. + * 2. CRYPT_SUCCESS + * 3. The return value is not 0. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001(Hex *n, Hex *e, int securityBits) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + SetRsaPubKey(&pub, n->x, n->len, e->x, e->len); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pub), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetSecurityBits(pkey), securityBits); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +#define RSA_TEST_REFERENCE_COUNT 10000 +static void *RsaTestAtomic(void *arg) +{ + CRYPT_EAL_PkeyCtx *pkey = (CRYPT_EAL_PkeyCtx *)arg; + int ref = 0; + for (int i = 0; i < RSA_TEST_REFERENCE_COUNT; i++) { + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_UP_REFERENCES, &ref, sizeof(int)), CRYPT_SUCCESS); + CRYPT_RSA_Ctx *ctx = (CRYPT_RSA_Ctx *)pkey->key; + ASSERT_EQ(CRYPT_RSA_GetBits(ctx), 2048); // RSA2048 + CRYPT_RSA_FreeCtx(ctx); + } +exit: + return NULL; +} + +static int32_t pthreadRWLockNew(BSL_SAL_ThreadLockHandle *lock) +{ + pthread_rwlock_t *newLock; + newLock = (pthread_rwlock_t *)BSL_SAL_Malloc(sizeof(pthread_rwlock_t)); + if (newLock == NULL) { + return BSL_MALLOC_FAIL; + } + if (pthread_rwlock_init(newLock, NULL) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + *lock = newLock; + return BSL_SUCCESS; +} + +static void pthreadRWLockFree(BSL_SAL_ThreadLockHandle lock) +{ + pthread_rwlock_destroy((pthread_rwlock_t *)lock); + BSL_SAL_FREE(lock); +} + +static int32_t pthreadRWLockReadLock(BSL_SAL_ThreadLockHandle lock) +{ + if (lock == NULL) { + return BSL_SAL_ERR_BAD_PARAM; + } + if (pthread_rwlock_rdlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t pthreadRWLockWriteLock(BSL_SAL_ThreadLockHandle lock) +{ + if (pthread_rwlock_wrlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static int32_t pthreadRWLockUnlock(BSL_SAL_ThreadLockHandle lock) +{ + if (pthread_rwlock_unlock((pthread_rwlock_t *)lock) != 0) { + return BSL_SAL_ERR_UNKNOWN; + } + return BSL_SUCCESS; +} + +static uint64_t pthreadGetId(void) +{ + return (uint64_t)pthread_self(); +} + +/** + * @test SDV_CRYPTO_RSA_REFERENCES_API_TC001 + * @title Multi-threaded reference counting test. + * @precon Create the context of the rsa algorithm, set the private key(n, d). + * @brief + * 1. Create multiple threads to use ctx at the same time. + * 2. Check whether the CTX is finally released. + * @expect + * 1. The reference counting is as expected. + * 2. The memory is released successfully, and no memory leakage occurs. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_REFERENCES_API_TC001(Hex *n, Hex *d) +{ + pthread_t pid1; + pthread_t pid2; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey1 = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + + BSL_SAL_ThreadCallback cb = { + .pfThreadLockNew = pthreadRWLockNew, + .pfThreadLockFree = pthreadRWLockFree, + .pfThreadReadLock = pthreadRWLockReadLock, + .pfThreadWriteLock = pthreadRWLockWriteLock, + .pfThreadUnlock = pthreadRWLockUnlock, + .pfThreadGetId = pthreadGetId, + }; + TestMemInit(); + ASSERT_TRUE(BSL_SAL_RegThreadCallback(&cb) == BSL_SUCCESS); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + ASSERT_EQ(pkey->references.count, 1); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prvkey) == CRYPT_SUCCESS); + + pkey1 = pkey; + ASSERT_TRUE(CRYPT_EAL_PkeyUpRef(pkey1) == CRYPT_SUCCESS); + + pkey2 = pkey; + ASSERT_TRUE(CRYPT_EAL_PkeyUpRef(pkey2) == CRYPT_SUCCESS); + ASSERT_EQ(pkey->references.count, 3); // The pkey is referenced three times. + + pthread_create(&pid1, NULL, RsaTestAtomic, (void *)pkey1); + pthread_create(&pid2, NULL, RsaTestAtomic, (void *)pkey2); + + pthread_join(pid1, NULL); // Wait for all child threads to end. + pthread_join(pid2, NULL); + + CRYPT_EAL_PkeyFreeCtx(pkey1); + CRYPT_EAL_PkeyFreeCtx(pkey2); + ASSERT_EQ(pkey->references.count, 1); + CRYPT_RSA_Ctx *ctx = (CRYPT_RSA_Ctx *)pkey->key; + ASSERT_EQ(ctx->references.count, 1); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GET_KEY_BITS_FUNC_TC001 + * @title RSA: get key bits. + * @brief + * 1. Create a context of the RSA algorithm, expected result 1 + * 2. Get key bits, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. Equal to keyBits. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GET_KEY_BITS_FUNC_TC001(int id, int keyBits) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + uint8_t e3[] = {1, 0, 1}; + + CRYPT_EAL_PkeyPara para; + + para.id = id; + para.para.rsaPara.e = e3; + para.para.rsaPara.eLen = 3; // 3 is valid. + para.para.rsaPara.bits = 1024; // 1024 is valid. + + ASSERT_TRUE_AND_LOG("1k key", CRYPT_EAL_PkeySetPara(pkey, ¶) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(pkey) == (uint32_t)keyBits); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_api.data b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_api.data new file mode 100644 index 00000000..4e495f93 --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_api.data @@ -0,0 +1,90 @@ +CRYPT_EAL_PkeyNewCtx: Repeat call +SDV_CRYPTO_RSA_NEW_API_TC001: + +CRYPT_EAL_PKEY_NewCtx: Malloc Fail +SDV_CRYPTO_RSA_NEW_API_TC002: + +CRYPT_EAL_PkeySetPara: Bad e len +SDV_CRYPTO_RSA_PARA_API_TC001: + +CRYPT_EAL_PkeySetPara: Invalid bits 1023 +SDV_CRYPTO_RSA_PARA_API_TC002:1023 + +CRYPT_EAL_PkeySetPara: Invalid bits 78 +SDV_CRYPTO_RSA_PARA_API_TC002:78 + +CRYPT_EAL_PkeySetPara: Invalid bits 16385 +SDV_CRYPTO_RSA_PARA_API_TC002:16385 + +CRYPT_EAL_PkeySetPara: success set +SDV_CRYPTO_RSA_PARA_API_TC003: + +CRYPT_EAL_PKEY_Gen: No regist rand +SDV_CRYPTO_RSA_GEN_API_TC001: + +CRYPT_EAL_PkeyGetPub: Null Para +SDV_CRYPTO_RSA_GET_PUB_API_TC001: + +CRYPT_EAL_PkeyGetPrv: Null Para +SDV_CRYPTO_RSA_GET_PRV_API_TC001: + +CRYPT_EAL_PkeySetPrv: Invalid set +SDV_CRYPTO_RSA_SET_PRV_API_TC001: + +CRYPT_EAL_PkeySetPub: Invalid set +SDV_CRYPTO_RSA_SET_PUB_API_TC001: + +CRYPT_EAL_PkeySetPub: range test +SDV_CRYPTO_RSA_SET_PUB_API_TC002: + +CRYPT_EAL_PkeySetPrv: range test +SDV_CRYPTO_RSA_SET_PRV_API_TC002: + +CRYPT_EAL_PkeyEncrypt interface test: vectors from nist +SDV_CRYPTO_RSA_ENC_API_TC001:"909d1c40da8b0840be7d0e626539c5884f907b505d7e573deeee1d66c5b73e6a38f376aaf4cdd97441034e9a7f055d5b53f93567393364cdc591b8f86668cae2a5fb1432eac3883381e7cd299c7dbaaba74a22a02263678be43ccc01cb936b20f7c968284524691f1ffa28ad8f00a8a929da99bc4b3bd757743912e5de708851":"010001":CRYPT_MD_SHA1:"d436e99569fd32a7c8a05bbc90d32c49" + +CRYPT_EAL_PkeyDecrypt interface test: vectors from nist +SDV_CRYPTO_RSA_DEC_API_TC001:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":CRYPT_MD_SHA1:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +CRYPT_EAL_PkeyCtrl interface test: vectors from nist +SDV_CRYPTO_RSA_CTRL_API_TC001:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"463729b3eaf43502d9cff129925681":CRYPT_MD_SHA224 + +CRYPT_EAL_PkeyCtrl interface test: vectors from nist +SDV_CRYPTO_RSA_CTRL_API_TC002:"a674f0f2a01fa0a987d0ef355f36cbd7eda5a931d5eca30b18fc237a481fcea435fe514166db877ca1e645204b0e1e2a8e5f7fcf28a98306c70424f0f4025c7d8c6d89063ac7847bf52eb1f2852bdd5cc03c1cbf63875b5062f4d22b290526a5fecfe343d39c3b46626b63e91670802b4d7a066973474a757d3e5957ddc020afddbeef963643b237651f7bd58d9af4ea67da7de5620539fb904c5a0243388498013470de777c8f11924add97fa1fb11b51cab46ea38adf995ad5efd0958a98cbf022dfb0d4b128917e4b513f120629051307b4d9d1014a28c55c93aaff59f47a7c0472a8b7a1ad5dbf07252c4b2602278fe18a77ec8acb8798f9f8b720dafe03":"19f9641ecc4e21405d238542fc633a35a33f3ddc84dfb8dc000c27bdfbb5128c0ae3b561ca615aabf7223824d6415a8a6285ca781683aa76ab9c8542dc02bc50ce60770246fa565a1975f6ce508d3cfc30b24b7eccc02183c5bf6a9b7900d621cb3e97fe57031574ab9e54b0eb2040415262cb7f354e032c39453ac38c51d9f9d98bccde0b866d5bbb4013b84054d55ecf8677a3af7308898ef03d30c796cb020aab69002ac00e820fd0bdb176c20589eee572f8699c27353dea73f7ea9b6c83a55d05f7eec7bb77244f11895ff0f462893ead61d8e51c55eea2ffc5b522c0b86fcde09c785f418570d071ddd39d8c3c3a05d80ef51a081ed3749180b973f24f":CRYPT_MD_SHA1 + +CRYPT_EAL_PkeyCtrl: PSS MD4 Bad Pad bits, vectors from nist +SDV_CRYPTO_RSA_CTRL_API_TC003:CRYPT_MD_MD4:"dab9c7d28a2b1e4995c12bcae3c9f580a2dd5372441888dc83aae5b515ebce3b95786c43b5811ebaee6ad90bff9e55ae1edccfc0fcafb4cfc43743749307ec0c36886c88a174d0156a2f88a25a5c594c558bf1a947335b1ab02e77bfeee5ab0cc25455819397f74d30ca31074d4612d9d928b66477ddf7b83c0cf4ee279c9071":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b8267" + +CRYPT_EAL_PkeySetPrv/Pub: Called multiple times. +SDV_CRYPTO_RSA_SET_KEY_API_TC001: + +CRYPT_EAL_PkeyDupCtx RSA1024 test +SDV_CRYPTO_RSA_DUP_CTX_API_TC001:"010001":1024 +CRYPT_EAL_PkeyDupCtx RSA2048 test +SDV_CRYPTO_RSA_DUP_CTX_API_TC001:"010001":2048 +CRYPT_EAL_PkeyDupCtx RSA3072 test +SDV_CRYPTO_RSA_DUP_CTX_API_TC001:"010001":3072 + +NiST Vector: Rsa public key compare: vectors from nist +SDV_CRYPTO_RSA_CMP_API_TC001:"a674f0f2a01fa0a987d0ef355f36cbd7eda5a931d5eca30b18fc237a481fcea435fe514166db877ca1e645204b0e1e2a8e5f7fcf28a98306c70424f0f4025c7d8c6d89063ac7847bf52eb1f2852bdd5cc03c1cbf63875b5062f4d22b290526a5fecfe343d39c3b46626b63e91670802b4d7a066973474a757d3e5957ddc020afddbeef963643b237651f7bd58d9af4ea67da7de5620539fb904c5a0243388498013470de777c8f11924add97fa1fb11b51cab46ea38adf995ad5efd0958a98cbf022dfb0d4b128917e4b513f120629051307b4d9d1014a28c55c93aaff59f47a7c0472a8b7a1ad5dbf07252c4b2602278fe18a77ec8acb8798f9f8b720dafe03":"f3e7af" + +Rsa CRYPT_EAL_PkeyGetSecurityBits test #1: vectors from nist, mod = 1024 +SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001:"d0b750c8554b64c7a9d34d068e020fb52fea1b39c47971a359f0eec5da0437ea3fc94597d8dbff5444f6ce5a3293ac89b1eebb3f712b3ad6a06386e6401985e19898715b1ea32ac03456fe1796d31ed4af389f4f675c23c421a125491e740fdac4322ec2d46ec945ddc349227b492191c9049145fb2f8c2998c486a840eac4d3":"859e499b8a186c8ee6196954170eb8068593f0d764150a6d2e5d3fea7d9d0d33ac553eecd5c3f27a310115d283e49377820195c8e67781b6f112a625b14b747fa4cc13d06eba0917246c775f5c732865701ae9349ea8729cde0bbade38204e63359a46e672a8d0a2fd530069":80 + +Rsa CRYPT_EAL_PkeyGetSecurityBits test #2: vectors from nist, mod = 1563 +SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001:"adb33c254aab23eed9e215a65b097ccf6a913fea1facf5ec558bf97863511f271721bfdbf1b4c1a37ffb48554e35c06d3e656c3cbec10e434302dc52c76cd4a306c86c35798d31b4bb2ab00a80567e7dd44d541e44d1c496e3c3ac798d11624a962a4218ab184f065fbbea1c6d085764e1be8ee7bafe4cd02e06d7fb98ddd2ec6a2283867a5293f2fbaacc2552a9b3f96de6cbc625ffa8132f0eb98ddf215d3bd5ee4195b6acfb8e015d286d47462d76723dd82926b2521503c6240699ce590f":"010001":80 + +Rsa CRYPT_EAL_PkeyGetSecurityBits test #3: vectors from nist, mod = 2048 +SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001:"d9a098da000ac58efb7d6c989b7468444d369d9865eec8696a4bc54ef47f4d04bb5fb531134d9edc1254c9665f96462c190a1c47ccf970b3a00a922a37e5ceb548ad638c425ee96310db234a97ed04342de813b5b6a4eb1ace5fef5b0c22e2330e4f285a76fb3d955ef13df1e2288c7e8974220f773b436029e5a8b03f7c9d1c8743ad2e6edab6604fae212244039c0bc2dffe1fb8a37fa8b935fb314764c76f5aba87e9d5466ec413ce3a72af0eebd0b483f2c298b35248538823d527f40e221557c8b25257a131adc7f81adf9b481c8c24405356ea42009676bd6606e7fede6b76a6a264a97507f15f0f12dec9d7bd473af9e0ae86399cf1f2d4021f13325d":"d107cf43a692284dbe81e069739b0fa121f605eecc587c058405146906b56e1042a19196663e14b4d6d13288b708cd998db8aa5ad53966d547509426a2e28946ae2eae99c9fd7478de2dfed90b185414b2a83d184147cfdcc184314053e655aa7c5af0e065f2eb139dfd0ddd64d878fb87fd39596a804d48403e12a1aee476e8db65a9bb15f50881eb2355531549c1f26832ab8812aa10858b24832e5f8498b43249707d14b88fac7c238b2baa010058c2454aa891f5dba11ff450afcd26afc571858df2230ee7c33e86e814c52780128400e8efd60a3980557b3e95e8e6b01ce80d9a3a08faf1730d065ef1":112 + +Rsa CRYPT_EAL_PkeyGetSecurityBits test #4: vectors from nist, mod = 3072 +SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001:"dca98304b729e819b340e26cecb730aecbd8930e334c731493b180de970e6d3bc579f86c8d5d032f8cd33c4397ee7ffd019d51b0a7dbe4f52505a1a34ae35d23cfaaf594419d509f469b1369589f9c8616a7d698513bc1d423d70070d3d72b996c23abe68b22ccc39aabd16507124042c88d4da6a7451288ec87c9244be226aac02d1817682f80cc34c6eaf37ec84d247aaedebb56c3bbcaffb5cf42f61fe1b7f3fc89748e213973bf5f679d8b8b42a47ac4afd9e51e1d1214dfe1a7e1169080bd9ad91758f6c0f9b22ae40af6b41403d8f2d96db5a088daa5ef8683f86f501f7ad3f358b6337da55c6cfc003197420c1c75abdb7be1403ea4f3e64259f5c6da3325bb87d605b6e14b5350e6e1455c9d497d81046608e38795dc85aba406c9de1f4f9990d5153b98bbabbdcbd6bb18854312b2da48b411e838f26ae3109f104dfd1619f991824ec819861e5199f26bb9b3b299bfa9ec2fd691271b58a8adecbf0ff627b54336f3df7003d70e37d11ddbd930d9aba7e88ed401acb44092fd53d5":"eaf05d":128 + +Rsa CRYPT_EAL_PkeyGetSecurityBits test #5: vectors from nist, mod = 4096 +SDV_CRYPTO_RSA_GET_SECURITY_BITS_FUNC_TC001:"c1526d64ca835a94a6a3d52178bb1e1aadcaf4e034966bec672f8aa409f6bfe680c94a100b014a6f7526c0d61d3eaa085ba8b1031596f58d6c67843372ca04b4031a205013ec9e7ae02279385aa7df4749f94e362aa1feb2c853ced6e6756212d9b738fd035f46bda5e72a4032f89c34baca642a7a7bab2409042e41c277e38d22a694d7c196ccd62d3bd4e784e0b47595bd20ac045c58e29fc24aca7b1af4b640674d9ecbe11bc2b5297ca8f64b443a3496c69686c9ba5596aa6ed59083fd3b551659ca7105acf668bd30b30b635ccd39a0d5da1f1bc35be300b58ae28f9ce843c23653cafd7d7ed6a280e87202e023404c2767b2ccc0ecfe8cdf330256949b910a8559b27a239b3e75beba4fee0a1f8a158cf94cc810191aae7f77d7751773a75ad7270f92d7bf523a66e700b9c4568602462e7e575932fa4ddb8afc9c80765a4493f0e238ac982ba60b9422e86d3775a3b8b483715706302fabc26490ef8fe2b379efaf775cbd763faa9a9d183ce0d84b8f594e7d4dacadf2647828ddfa8bf6ea9e301009d7c2f06030c5c45715d32e4dc1278f1bae6cdbfe0ebc10b302b1a8642a3d9b1e375d7bd61b6dc1a85b5470b81fddd66827869563e6c6cb1f4b5fe3515138a32901ee3f161433a0acbed1960bb2f619497c485e3cd9cb17087442b8a5924b69bf5bec08d4ca9d2fd16e7d3ee5c9848f3710f82f2b7caf98525605":"010001":128 + +Rsa CRYPT_EAL_PkeyCtrl references test: vectors from nist +SDV_CRYPTO_RSA_REFERENCES_API_TC001:"a674f0f2a01fa0a987d0ef355f36cbd7eda5a931d5eca30b18fc237a481fcea435fe514166db877ca1e645204b0e1e2a8e5f7fcf28a98306c70424f0f4025c7d8c6d89063ac7847bf52eb1f2852bdd5cc03c1cbf63875b5062f4d22b290526a5fecfe343d39c3b46626b63e91670802b4d7a066973474a757d3e5957ddc020afddbeef963643b237651f7bd58d9af4ea67da7de5620539fb904c5a0243388498013470de777c8f11924add97fa1fb11b51cab46ea38adf995ad5efd0958a98cbf022dfb0d4b128917e4b513f120629051307b4d9d1014a28c55c93aaff59f47a7c0472a8b7a1ad5dbf07252c4b2602278fe18a77ec8acb8798f9f8b720dafe03":"19f9641ecc4e21405d238542fc633a35a33f3ddc84dfb8dc000c27bdfbb5128c0ae3b561ca615aabf7223824d6415a8a6285ca781683aa76ab9c8542dc02bc50ce60770246fa565a1975f6ce508d3cfc30b24b7eccc02183c5bf6a9b7900d621cb3e97fe57031574ab9e54b0eb2040415262cb7f354e032c39453ac38c51d9f9d98bccde0b866d5bbb4013b84054d55ecf8677a3af7308898ef03d30c796cb020aab69002ac00e820fd0bdb176c20589eee572f8699c27353dea73f7ea9b6c83a55d05f7eec7bb77244f11895ff0f462893ead61d8e51c55eea2ffc5b522c0b86fcde09c785f418570d071ddd39d8c3c3a05d80ef51a081ed3749180b973f24f" + +SDV_CRYPTO_RSA_GET_KEY_BITS_FUNC_TC001_WITH_RSA +SDV_CRYPTO_RSA_GET_KEY_BITS_FUNC_TC001:CRYPT_PKEY_RSA:1024 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_encrypt_decrypt.c b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_encrypt_decrypt.c new file mode 100644 index 00000000..b60919ef --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_encrypt_decrypt.c @@ -0,0 +1,244 @@ +/* + * 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_BASE test_suite_sdv_eal_rsa */ + +/* BEGIN_HEADER */ +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_RSA_CRYPT_FUNC_TC001 + * @title RSA: public key encryption and private key + * @precon Vectors: a rsa key pair. + * @brief + * 1. Create the context(pkey) of the rsa algorithm, expected result 1 + * 2. Initialize the DRBG. + * 3. Set private key and padding mode, expected result 2 + * 4. Call the CRYPT_EAL_PkeyDecrypt to decrypt ciphertext, expected result 3 + * 5. Compare the decrypted output with the expected output, expected result 4 + * 6. Set public key and padding mode, expected result 5 + * 7. Call the CRYPT_EAL_PkeyEncrypt to encrypt plaintext, expected result 6 + * 8. Check the length of output data, expected result 7 + * 9. Call the CRYPT_EAL_PkeyDecrypt to decrypt the output data of step 6, expected result 8 + * 10. Compare the output data of step 8 with the output data of step 6, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Both are the same. + * 5-6. CRYPT_SUCCESS + * 7. It is equal to ciphertext->len. + * 8. CRYPT_SUCCESS + * 9. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CRYPT_FUNC_TC001( + int keyLen, int padMode, int hashId, Hex *n, Hex *e, Hex *d, Hex *plaintext, Hex *ciphertext) +{ + if (IsMdAlgDisabled(hashId)) { + SKIP_TEST(); + } + int paraSize; + void *paraPtr; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_EAL_PkeyPub pubkey = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_RSA_OaepPara oaepPara = {.mdId = hashId, .mgfId = hashId}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {hashId}; + uint8_t pt[MAX_CIPHERTEXT_LEN] = {0}; + uint32_t ptLen = MAX_CIPHERTEXT_LEN; + uint8_t ct[MAX_CIPHERTEXT_LEN] = {0}; + uint32_t ctLen = MAX_CIPHERTEXT_LEN; + int32_t noPad = CRYPT_PKEY_RSA_NO_PAD; + + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + SetRsaPubKey(&pubkey, n->x, n->len, e->x, e->len); + if (padMode == CRYPT_CTRL_SET_RSA_RSAES_OAEP) { + paraSize = OAEP_SIZE; + paraPtr = &oaepPara; + } else if (padMode == CRYPT_CTRL_SET_RSA_RSAES_PKCSV15) { + paraSize = PKCSV15_SIZE; + paraPtr = &pkcsv15; + } else if (padMode == CRYPT_CTRL_SET_RSA_PADDING) { + paraSize = sizeof(noPad); + paraPtr = &noPad; + } + + ASSERT_TRUE(ciphertext->len == KEYLEN_IN_BYTES((uint32_t)keyLen)); + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + if (padMode != CRYPT_CTRL_SET_RSA_PADDING) { + CRYPT_RandRegist(RandFunc); + } + + /* HiTLS private key decrypts the data. */ + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey, &prvkey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, padMode, paraPtr, paraSize), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyDecrypt(pkey, ciphertext->x, ciphertext->len, pt, &ptLen), CRYPT_SUCCESS); + ASSERT_EQ(ptLen, plaintext->len); + ASSERT_EQ(memcmp(pt, plaintext->x, ptLen), 0); + + /* HiTLS public key encrypt */ + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey, &pubkey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, padMode, paraPtr, paraSize), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyEncrypt(pkey, plaintext->x, plaintext->len, ct, &ctLen), CRYPT_SUCCESS); + ASSERT_EQ(ctLen, ciphertext->len); + + /* HiTLS private key decrypt */ + ASSERT_EQ(CRYPT_EAL_PkeyDecrypt(pkey, ct, ctLen, pt, &ptLen), CRYPT_SUCCESS); + ASSERT_EQ(ptLen, plaintext->len); + ASSERT_EQ(memcmp(pt, plaintext->x, ptLen), 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_CRYPT_FUNC_TC002 + * @title RSA EAL abnormal test: The encryption and decryption padding modes do not match. + * @precon Vectors: a rsa key pair, plaintext + * @brief + * 1. Create the context(pkey) of the rsa algorithm, expected result 1 + * 2. Initialize the DRBG. + * 3. Set public key, and set padding mode to OAEP, expected result 2 + * 4. Call the CRYPT_EAL_PkeyEncrypt to encrypt plaintext, expected result 3 + * 5. Set private key, and set padding mode to PKCSV15, expected result 4 + * 6. Call the CRYPT_EAL_PkeyDecrypt to decrypt the output of step 4, expected result 5 + * 7. Set private key, and set padding mode to OAEP, expected result 6 + * 8. Call the CRYPT_EAL_PkeyDecrypt to decrypt the output of step 4, expected result 7 + * 9. Compare the output data of step 8 with plaintext, expected result 8 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + * 5. CRYPT_RSA_NOR_VERIFY_FAIL + * 6-7. CRYPT_SUCCESS + * 8. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CRYPT_FUNC_TC002(Hex *n, Hex *e, Hex *d, Hex *plaintext) +{ + TestMemInit(); + uint8_t ct[MAX_CIPHERTEXT_LEN] = {0}; + uint8_t pt[MAX_CIPHERTEXT_LEN] = {0}; + uint32_t msgLen = MAX_CIPHERTEXT_LEN; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_EAL_PkeyPub pubkey = {0}; + CRYPT_RSA_OaepPara oaepPara = {.mdId = CRYPT_MD_SHA1, .mgfId = CRYPT_MD_SHA1}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {CRYPT_MD_SHA1}; + + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + SetRsaPubKey(&pubkey, n->x, n->len, e->x, e->len); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + CRYPT_RandRegist(RandFunc); + + /* HiTLS public key encrypt: OAEP */ + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pubkey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &oaepPara, OAEP_SIZE) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, plaintext->x, plaintext->len, ct, &msgLen) == CRYPT_SUCCESS); + + /* HiTLS private key encrypt: PKCSV15 */ + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prvkey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, &pkcsv15, PKCSV15_SIZE) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, ct, msgLen, pt, &msgLen) == CRYPT_RSA_NOR_VERIFY_FAIL); + + /* HiTLS private key encrypt: OAEP */ + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &oaepPara, OAEP_SIZE) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, ct, msgLen, pt, &msgLen) == CRYPT_SUCCESS); + ASSERT_TRUE(msgLen == plaintext->len); + ASSERT_TRUE(memcmp(pt, plaintext->x, msgLen) == 0); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_CRYPT_FUNC_TC003 + * @title RSA: Label test for OAP encryption and decryption + * @precon Vectors: a rsa key pair, plaintext and label. + * @brief + * 1. Create the context(pkey) of the rsa algorithm, expected result 1 + * 2. Initialize the DRBG. + * 3. Set public key and private key, expected result 2 + * 4. Set padding type to OAEP and set oaep-label, expected result 3 + * 5. Call the CRYPT_EAL_PkeyEncrypt to encrypt plaintext, expected result 4 + * 6. Call the CRYPT_EAL_PkeyDecrypt to decrypt the output of step 6, expected result 5 + * 7. Compare the output data of step 6 with plaintext, expected result 6 + * 8. Call the CRYPT_EAL_PkeyCopyCtx to copy pkey, expected result 7 + * 9. Call the CRYPT_EAL_PkeyEncrypt to encrypt plaintext, expected result 8 + * 10. Call the CRYPT_EAL_PkeyDecrypt to decrypt the output of step 8, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2-5. CRYPT_SUCCESS + * 6. Both are the same. + * 7-9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_CRYPT_FUNC_TC003(Hex *n, Hex *e, Hex *d, Hex *plaintext, Hex *label) +{ +#ifndef HITLS_CRYPTO_SHA2 + SKIP_TEST(); +#endif + uint8_t ct[MAX_CIPHERTEXT_LEN] = {0}; + uint8_t pt[MAX_CIPHERTEXT_LEN] = {0}; + uint32_t msgLen = MAX_CIPHERTEXT_LEN; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + CRYPT_EAL_PkeyPrv prvkey = {0}; + CRYPT_EAL_PkeyPub pubkey = {0}; + CRYPT_RSA_OaepPara oaepPara = {.mdId = CRYPT_MD_SHA256, .mgfId = CRYPT_MD_SHA256}; + + SetRsaPubKey(&pubkey, n->x, n->len, e->x, e->len); + SetRsaPrvKey(&prvkey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + CRYPT_RandRegist(RandFunc); + + /* HiTLS pubenc, prvdec */ + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(pkey, &pubkey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(pkey, &prvkey) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_RSAES_OAEP, &oaepPara, OAEP_SIZE) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_OAEP_LABEL, label->x, label->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(pkey, plaintext->x, plaintext->len, ct, &msgLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(pkey, ct, msgLen, pt, &msgLen) == CRYPT_SUCCESS); + ASSERT_TRUE(msgLen == plaintext->len); + ASSERT_TRUE(memcmp(pt, plaintext->x, msgLen) == 0); + + /* HiTLS copy ctx, pubenc, prvdec */ + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, pkey), CRYPT_SUCCESS); + + msgLen = MAX_CIPHERTEXT_LEN; + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(cpyCtx, plaintext->x, plaintext->len, ct, &msgLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(cpyCtx, ct, msgLen, pt, &msgLen) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_encrypt_decrypt.data b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_encrypt_decrypt.data new file mode 100644 index 00000000..26441d3d --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_encrypt_decrypt.data @@ -0,0 +1,47 @@ +HiTLS PrvKey decrypt: OAEP, keyLen = 1024, hash = SHA1, msgLen = 4 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:1024:CRYPT_CTRL_SET_RSA_RSAES_OAEP:CRYPT_MD_SHA1:"cf473a4d9bfffc47b4512f26e4498928cc9f27349badaf115e76be7d08941d6a2bb6aa54767af279a7087edbed9bbc23176ea6862dadf79ab0af34a8c5b4b453c037093bbb432376234fe9d3954a764c2a05f91d505fd18a6223eca1c4e3c926e72684d4c9148ba6ef3e448b27a4576240363ce8d850a9d4cff67a6affd1008b":"03":"8a2f7c33bd5552da78361f6f42dbb0c5ddbf6f7867c91f60e9a47efe05b8139c1d24718da451f6fbc4b054929e67d2c20f9f19aec91ea511cb1f787083cdcd8bf60989f1d650d42c40d201d9c70fb408fe8b6fc661712af3a0ae006c5d90fa5dee974dade64873c9ba430b18ecd18bdd2995731dead6c30e816b69e27dc20f0b":"54657374":"c904ed383f834085134fcdc2d2042fa487a56c6816c334ebf9f3d852e435714fa60f42741cc9982694b2ec34fb21df553a9e8d70513650cdaa72ddecd9533ef34f7364c8bd3e5c20c5aef490ad5be0612b7e7c9f9a6d579a6ad38446f9eb3ab5ffe56ee34f27c510e4a871f0ad1479d0a641402f46efa1cf700ef0a1c06139ad" + +HiTLS PrvKey decrypt: OAEP, keyLen = 2048, hash = SHA1, msgLen = 4 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:2048:CRYPT_CTRL_SET_RSA_RSAES_OAEP:CRYPT_MD_SHA1:"c1c37d104ad39a6a41979b7bc2d696481e2c55564204c26631ee726c7d75fa3a3887948c84307e96564fcfcdf3c7df9c441547449e656b9e60542ac18557991dfe0a5977ec3b652b9791e4e6e2afa790d4d6fa178070084b638cbee8ab2554f3b3db6789c5cd0abd6fa8c8e6026fcceb0a20f1513a80a98ad8be464f0e8a1bb3753d384ba0bca778aec4c5b24e7b41fc305298f0add734fc5f2fbcf5ac4703954673256a4b6bae93e9f2434185327df046aabc4e56989c6e32aafb03fecd19db519db5236f4445da2d1bcf99a916250fe8b6678f19ab48f1d62c2e1fd031305cc0bd4ee15ea1695d2f5d8ca5dd99064f31b8ae61c3617e0f1b6974aafbfea71f":"03":"812cfe0adc8d119c2bba67a7d739b9856972e38ed6add6eecbf44c4853a3fc26d05a630858205464398a8a894d2fea682d6384d86998f269958d71d658e510bea95c3ba5482798c7ba614344971fc50b388f5165004ab032425dd49b1cc38df7cd3cefb12e88b1d39fc5db44019fddf206c0a0e0d1ab1bb1e5d42edf5f06bd2124292795701b469e508288f5e62beda7d2569777d0262705be9f1633280133c75dd54987d5361d0068d055e0ed2c012ca5ac1d6bd5641a495abdb6c68fb4b20f007713f120130bf66283620231d9cfe8da81e5bbcdc98e3c8c31addca80847c377e7094f75cf1a5dde0c134078782a5cf9492506ebd21e8a82b17e3eb019667b":"54657374":"2b2754e78c89fd44f0dde4781e58f1f2c115dbd1fec6be2d9c189db77619f5ef5cb57fd40f71124a35a5048ce633ba4d590fcb0660555acb9e040db3913aa1439755c922a395aa43711f77685f613613a9507e42d09d26837173b35f76aff877c036ffcf7d8736d6f9c52ebe594ab0f95f571083b88a24d48d701bb321bf387cda53224a4096dd42c9effcbc6535b2ff4802be62a06db7eaadbaafb7f787a466c766d96c8b084d532d2065100b13f465f500f03d8e76a4d415cc69e969cf7eef24cb153347d6e53257c4d69165f86caa04d26d8cb72712fd07e6264e109d8316fe4c2949c94ac0ba9ea75dd64e704710f9655620c5335a2e9c07ffe07f9f8d62" + +HiTLS PrvKey decrypt: OAEP, keyLen = 3072, hash = SHA1, msgLen = 4 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:3072:CRYPT_CTRL_SET_RSA_RSAES_OAEP:CRYPT_MD_SHA1:"b10f2427606bc476864c97060c4738d8cce100596baa54517bc5965bf8867901be733dca7c29a8e0cd91bc085d954dc0f8ae1f2a9c136928613c8b51013f8383df1d9f6b73ff449d990e18d007ca244d922811c06e90d639442d6363d3b9094d5884cae7d31cd833a1e543c5c1fe3c288bccbbd245ff9036c39756f7ed687c3d233c87dd6f538be7c375eb3c4199a8231e386fd97bd86de245a57eceb8623d2644d283a6e4d486e231b3e13dc857396e9a47e70e5fd99cf2d3185224679743db4aab4c7a8c030505d92f9f50940176439428e20e8caff3007340b8be2ff570ba1e23693b31ea542c527d6f4e8eeb95a21989beaa393382aa276aa7feebb378d0e18300bf481cea0856762d4b70f378224c13998854566eddfcb89489e814d7022242e4deada4a58707aa38046ea42292399c13c0af60a4b0acb0936b874274692906ffd53702536f49afa7e574ca325e93b61154b2871a9c527feaa539439b23ee0de7962d2dba5101add1155be79842fab2dc0697849f7fa61c06908cac7323":"03":"760a181a4047d84f04330f595d84d0908896003b9d1c38365283b992a5aefb567ef77e86fd711b40890bd2b03e63892b507414c712b79b7040d3078b562a57ad3f6914f24d54d86910b4108aafdc1833b6c5612af4608ed0d81e42428d26063390588745376890226bee2d2e8154281b07ddd28c2eaa60248264e4a548f052d36cd3053e4a37b29a824e9cd2d6667017697af53ba7e59e96d918ff347aec28c42de1ad19ede30496cbcd40d3dae4d0f466da9a09953bbdf737658c18450f829115771a0aadfc9c5f69248379ef968e44353689103d41ef5405ca7475280d2c259c42d43c88fc992c54a51a17c7982a7d5d404b399478a16f1ea5b5de9ea171ac579ad1e2e8c75b86f37ca9f030642b155d6e9d67e27c99f3f78d515402133e6aa6408ebe92754f8fd4e70aedb6dc9b0cad9585109908ddb5af9b872ac7ed4247f82b8fd4cda2578533a58f0fc8bb1c5c7ebec7b3ce193462aa5efe5e5cf9eb02e3ff8a09baf7fbbfa0a155406396f141ed50d84c089ad1e8b579956b728a7c0b":"54657374":"9b5eb3fec17cd558ba0ef9137805348ae014f3483a3a1597bf08fafcfe8f0d75cf586f0b495c799cc3179754c63fd306b430a8b624ba52e1c00bf1dafdbdb709538a4f2737a8073b5e97114c49acd4e7fe364cb55bca754c1babe4487bbf4d96f812a3989ce1932a82385957c5ee5b71d14fe2e8d6cc4bced40d067d456ca1df097a93ace293dfeb57371ad56003c7eeb37127a53de99ac4e7a1dd52a3afdee4d1b996f4a9db8d9685c864f96e85d857d696998d702b200a83c90afdb2a01c18413d095c53f5b4d139312f881cfa315e901474030b13f53e2ead1ebcaf0f22adf09aa188fb297b8688f2628b28331a322d460c851eba418ab770491165b420722ae3c2750c48c9b7c42dc861590b0906abb6978f24a24dca56cd3e5a06812a76cad20e6545768f2d315e98fe1be8a02042c7be81207b808dcfe2f1ec476437fd3c7c52a188ab0379ae4567f104c39db5c1bacf6aeec56dc29df29ac7dcdf363b1faddd56d2377b897ca715a65cfdc5b2551d5882c9a7f37d59947ead032d2b2c" + +HiTLS PrvKey decrypt: OAEP, keyLen = 4096, hash = SHA1, msgLen = 4 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:4096:CRYPT_CTRL_SET_RSA_RSAES_OAEP:CRYPT_MD_SHA1:"b8b2266f82b03e0ae3f75461f264a23521719f7ed92db85758db6d6fa78db7fb94781522e7494f228daf8af2c98b785facb7c32bfba2f8d609d13e80aaffea5f910ff0e3c2e3d6ea2a0801e741f718188022b776e71cdbe7f5adb41abb2b86fe8875eb527bfb4e1d57e42e7694a0cff8a037788647d82c2c6bbf7f623aa0393bb11678a9f50dbf96c566ce4f0b26d49e2e49097519bd9b86848cd386fa5377f596819497c1db24fcd3c369874f7061b4e91b39caf9cf8ef80506c7f56f6619d6f0a4226238a295936d7f5d4b4806e4c15a8b459cd31184b59508cf9b404988487083fa58b5847e0d29a64f854277e1314c89f39833441a866644af757adae6423444c10f65c6cb51cd26394cb0ed6a238336fec471539b943692f3fdcc712b967813a2a71f5a437e33384314fb02b9656a08d59be930f9337f6cac177bf714092b9b5981b2ab4e9e6d1f2f6d8f31687415341103f6f78330c12f86db1c232da3daaa9a1d5792c9e9e94e93acb05f34468d50ff435949174cd4c211db5ca190358ad33ced3f5e3ffc7d8158f48cc94b52d1d85adb725c9e3903705871a6e4a84f72f3f51fe70e422e3a63050497750e52e1e27bc9e0862e4dfaec6c5d6e44773afddb4d12b2964cf1a89a804c5734c73f58a08107ae8c57ee2260604ff77d60a28490d8b4c558ff298ada5ada896d16eee89a9948cc0263ca50db6131fdced449":"03":"7b216ef501cad40742a4e2ebf6edc178c0f66a5490c9258f909248f51a5e7aa7b8500e1744db8a17091fb1f73107a5951dcfd772a7c1fb395be0d455c75546ea60b54b4281ed39f1715aabef814f6565aac1cfa49a133d454e73cd67277259ff05a3f236fd5234138fed744f0dc08aa5c024fb042fe572c847d4ff96d1c02627cb6450714e092a648399dedf5cc48dbec986064e11291259adb337af518cfaa3b9abb8652be76dfde282465a34f596789b677bdca68a5f500359daa39f99668f4b1816ec25c1b90cf3aa3e3230049880e70783bde20badce635b35122adbb0304b02a6e5ce585408c66edfae2c4feb763306a2657782bc5999831fa3a73c9980558ec57e442a5c73126b30843d0c153b36238f1bae3a26da4f77c1fd4acc0ec7fec9e48eca2bf494e5c3bf3cd65cb73900d93f876abeef8865b5a2a3877cc1aabdefa7b6bb7c7175050abddd5ca5901c928e4cab5df49038402377972d79338a40c59b5d37e2914bf191be440db793fe070ebaaa23686044e7a1f164c813ea7626ddefb738301a4d8e4ed18df8e2cc5748f7efc39e224df0c2cdf3a1054ddea0a8d7dfa4671a9843edf31700b28391d3bd690dbca05945068bbf22bbc6c5178332f961a9a7a83551752bd3c7041c6c5987faf3443a89847eebdc53aeb77c6573e65c675d3e71752bf10dd2d11c15804c8128924ef8f90bebab3472a17664920b":"54657374":"2336c74430608f924a7858f5134283e346131794b59fcae01c2fcfeaeda90aea1a6f5fb3d74a6f1008c6b791d6ecdb41a582a556d4617a88ecbbacd8c95f91059237e576ae6392aca39e9a222dd103492196abaada486be0343fa80803e0891449b03626d5a9f86f3bd9cb234d2988fe33cbf81ef46bd57e9719ea2292178cc487b025ea5f11823ffffcf99359ecccb9d00806370549a73e7a67165f1dce6b408ada3d8aae6307fbb41922ccd80e6ab1d96d8cf0678083c5ccb3367682dbc375ebeaf9624aaae9c9481c83ba7cb91d10f100e7fd23f94c3be196e8701d4dd6c117cf73e7bd8d27630d091862aa9af7695dcce821b9314241a85cd238a27ddd68085e087ce485b5e4bd5b5caa0525a2cf46f999a668d0c45442330e0f009ece0cfd3e025dad13f26fdab206d9445f8bddd17c0228acfae75b03dab42597b6d113ecb09411c11c36503a2d7db7fab579e25b3031b9d609618bd8f664d0d8760e9b6a8705b87890dff8fe7ce72dc0bfae53f22f5c994d379e089bf7de01b092ae328d0926fce2e5ddc4381daf2cea7bf6a8a75c45ea5487e435d2b4ea9ffa7f9c8387a0783f2f349f4bd9abd6d8b97f604e35252cab40253bcec7f98c26817a976c27a8cea58cfb2d96b602226260f132a85f95f39aa8b4f542287cc7b8126ec8c8d9916fc6cf0b9f17f72dd50605277d283cf5b734989b91cfdf2b14ea737bd8dd" + +HiTLS PrvKey decrypt: PKCSV15, keyLen = 1024, hash = SHA1, msgLen = 80 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:1024:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_MD_SHA1:"b8a1d57c120046e1d889be1548c14c9768a3f503e0813e369eee1c5c6dc775c70ccad62eb0be48c143e1786fdae35291818e35c9620db6299eccc34fe8dd8f8f1f1b0e1547fc6c7be8f3687ac58dd6f3a4b41aae9c965d3386ccb6087d3be63fa0fc2e6cf0ddcf84f51d2a1ade096f07e3140f1b1ab08897e0b69246f975b251":"03":"7b168e52b6aad9ebe5b1296385d6330f9b17f8ad40562979bf49683d9e84f92f5ddc8ec9cb2985d62d40faf53c978c6101097930ec09241bbf332cdff093b508f18ea897df42cab2bc5395dc9879b5e5ed1551d768c5970ca7ce36e56837b14f31f6d08afa359e6839bd597c05d23eb572eaf4fe15b96a695cd8bcc09329c1c3":"0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b4382":"3ff4bb04905691356e627f29a0aa2ea98ae6f778c11b6f746a6f636ab3420f1e4692efb66c8ab4d436a30b14f0b4c0403a0fc12585e4724d000f8a29054c785f51b38fdae5ba2e3d2de4cfe7f3c01eb1a0d8564a0f7f8cbe83c51024680767350fe0cf7cceab2bb8ec8fda1afbf651029e83bca93a7c6003a876835cd0b8ad74" + +HiTLS PrvKey decrypt: PKCSV15, keyLen = 2048, hash = SHA1, msgLen = 4 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:2048:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_MD_SHA1:"a01b12f4f85e165338f307fa12b80a15d400b2c41de93368ec64be7308ea4dba3902256172edfdf0bef6bad0105806fcacca64b8dbb79f7546302d35f4adb03ed8d01f794a2faa2ec509593724a7963c3f60944dbd1d1a685d3f73e39ec956df3291319dd8697fd0f94a807ae2ebc6846a8d98ff80112a7f372e820f8cc7467703d5718cce913cee5312facfa98635eec50d9f1c286e7d388e6f0da456852fc51095b8e50ad7d9340ab177a5503ca7559928193a7cfe070c80dd1a0388383b79c857b4d16261b84b4e82adf109041561fffd866e9b84e286117796734abebbf3dadb7e8d5356fc1214ecc7074de5f14956ef077fdff21e0093c5cbda50c52821":"03":"6abcb74dfae964377b4caffc0c7ab163e2ab21d813f0ccf09d987ef75b46de7c26016e40f74953f5d4a47c8ab59004a87331987b3d2514f8d97573794dc92029e5e014fb86ca7174835b90cf6dc50ed2d4eb0d8928be119ae8d4f7ed148639ea21b62113e59baa8b50dc55a741f28458470910aa5560c6ff7a1f015fb32f844e49f06beb68f7e6490fdf2c90e19f91fbd8ed8e42e6a8d0d1bf4086208e4b269a4b8378584c43cfc2027a174066615f8f47c9a36b2c9931ad556b047906939513f2194d4d39cc05ae4d8040d186d0d84773b9ace785fb9705bb12c595da22cd4fb15f715a40dbfa9c9d06724af23302dd534925829ed0fe3ccae268bb811c1583":"54657374":"931a0c8083ce1289b232a0d41523a4d50b5610ab47bfe5b95f40667fd3c9a3b4ec7915828461d09f826d241c1ee056ea7ce41d00c04490269aff9158643e4a4b1deea7b6139f65a9eec3bd1c692206002670e46b4ffbf9521fe08cb74aa3d3ac16beb5d594f25c01e9b5d6eebe5df8b9812e90b602f4a3311b63282e63b0f76ef16f5d8c46d7202cd2da7cb8fd7b9df73bfb1ac61929f5e69dc28ec23304d15ccf5ec9e14c5fd9a5914e88876c26180616a8fe6d33b7694aa79b72dcac80eca5d31e6c65470b2d520631701288869c37f4494ce35dabb7fbf946526d0ed611038fe62c934c320348015a6a415eccec9049dfc1cc6feba33f18a49751037b2694" + +HiTLS PrvKey decrypt: PKCSV15, keyLen = 3072, hash = SHA1, msgLen = 80 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:3072:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_MD_SHA1:"a863f275f36d454a21a3abb9ada2cfc93300065352de66155e32f5fbc2917f83b469f4a3d41c0891994a467df51a723d1d0ca4e04346f9cfec56774e4d1f96fc37d885fde675387de98e732c41755ffa305f138b713b98b88b63a2c5cf1adce5fd1bd4857b136cbb6ab27a6f0f37dc0658279fc0af07ce0f9ddff5a89dc692498c3d2fcfb3a58a7072e5f017af9e24ce7ada68cc0f1c56d7f47dd82d779532fa09e7820c449f642566fe2f2d3a5bbc609db8c09fc7b5839a6398c49063dc96456f27ba108c5ea8bd4d477357081dc2258e5f5c2d4306d946a136d66baaa3e0d6955664ecbfb0140d9ceb87c8212a49cc276a1112518685e30b5b3147a92b6c0d135c0b205d52b5b42c7d46741c0d4d712763a3bb952d8df43b79e10002d285a1ba4d8b2f535d16baf112041b3227e2d06011fef83347b7f10e5128767c5127f7a73de53b5988c94383a91d5c0f24eaa2267394d84c9e18912b1991c3f54675f81abf7ae356b1fbf55b825f0e8eec03937327a866a2b4fd7e01a6c025550664b1":"03":"7042a1a3f79e2e316bc2727bc9173530ccaaaee2373eeeb8e9774ea7d70baa57cd9bf86d3812b06110dc2efea366f6d368b31895822f51354839a4dede150f52cfe5aea9444e25a9465ef772d64e3ffc203f625cf627bb25b2426c83df673deea8bd3858fcb79dd24721a6f4b4cfe8043ac5152b1f5a895fbe954e70692f0c310828ca8a77c3b1a04c994aba75141889a73c45dd5f6839e54da93ac8fa6377515befac082dbf9818ef541f737c3d28406925d5bfda790266ed10830aed3db9828a825489613116ec8c16819630b207fb8e72129dcc53a53a8babf6045090550393859a83fd5945248964b2ce996398bce0e3e88b58bed6b678002a800a183138534757c54c45b82389a51c854137fdf92f2821571778c1c94e416e064af1c595034ec2817a12cf20c785630660c24f4d2b683b28dca8334138e0637db57ee7df38c7fe5f4bc4a3efc1a323ed55ffe34b90bf8c32d424e03ab5eacaf7e0697a843384f1bd43dec0db67d9f7f85678d25ba04f6dbcdbfca2ed5b836760e23bc6ab":"0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b4382":"85f5ab60296a8c7fa5219cfae92959c1bbc186f83c0d85d8f256a44112dba28333261d6c3e5eb31a874a9c481d807217d2855e916f350e47afb08ff2c4a0b7250d98000fb36e0fef84a2e99cc50cf1c5578fee983177e23ecaaa43c830113bb25dca7ac3c410aea87cd18f92e84d02ef5665d1b45649bb39b11a4bb894c9821504bcd47b84f9262bf367f1693898c31021c233b15473473e32f3978d76bc7b8dfda50ede2867f795c591fa28a45e7e64783f80367057c25bce74b409fc8ca797b01717b3510d3b028b5d47c4ef8564c97a1753e36c89ea92043bea752dadd9229b5d41148111d08771b42762c2781482a4df552daddff2d0d71aaafa9991956003288625c187531b42a88418c6c23bbf935a20aac43858f26ccbb1d862277da2d84e1076aa38f24f468e1d11bfa72a5d89d726a9e65c146a129766a4c14ea1ddd1d465f14a27c89f86b90c1fdedc0b776442504c08abed17fcebcb3243882b6a7df1ea534ccccd3f55fd693b9866ba167a2f1dab5863e0a1d8e87f8a85fccf70" + +HiTLS PrvKey decrypt: PKCSV15, keyLen = 4096, hash = SHA1, msgLen = 4 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:4096:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_MD_SHA1:"a1e40cd0d2acefd97d50653dad7a3295c21fcb5a38e3ca375e4346ee280ba78560a2cf497abcd129d5065cd25de48dbb33870a381977b7891b54fed2c6212cb5dfc9b4ac2b4f65f625dc69e54a23ba4b3d9450de7d4b3c6dd6c1368ccb7c7bc4778a152362a7341a488a9f17958889999040c04a964b78e203e79eefbc2de6a97e618c351314351b898e2bef2bf37fbfc2a7fadf0125bae892e57c7fc27e2d6b2d24d0ec913f0e68cd03fb86e4e59364ba20f1d519d36ec3a350a4b450db899aafd182473348757423c8abf767e8e1aaa74283c9c3387ad925952fc2511b2b3ab54280bb1f94d9c41f2cdb6ae3428981294ed5d0827071b85136c8a850ce6286bb702f852f064af3f6675a2f18ec6c0ee6544d98ceaa748136f4042fecf718ddc9d8ac4abed0392a27fb5fc854038cfe5584ca3f99ae7016ecad1b9908d0512c908c81a15e1fb6789ba6b73de08984f6cd188a9846287a23ad92269bbe21bfad0f3616f963a0b64232112482d231257335b422517540cb50c7a7dbd12da95f0de823823c044f16ae72e05b2646f0c068b7f70c83a9d86468b3d6ff473e7da727ec707dc5b7f9d6e3603c0897c5b9ca3f0f04ae3250571bff180fdcf58f9d1d44138d5f2c840787922b1aa750896b19e5042961ea1dae3f28047d0053d9686995bc9e33590f64fe07fb60d9ee6268b943aae3a0bab266f0c633a773218c46f1ef":"03":"6bed5de08c734a90fe3598d3c8fc21b92c15323c25ed317a3ed7849ec55d1a58eb1734dba7288b7138aee88c3e985e7ccd04b17abba525061238a9e1d96b7323ea867872c78a43f96e92f14386c27c32290d8b3efe32284939d6245ddcfda7d84fb1636cec6f781185b1bf650e5b0666602b2adc64325096ad45149fd2c94470feebb2ce0cb82367b109729f72a2552a81c551ea00c3d1f061ee52ffd6fec8f21e188b4860d4b445de02a7af4343b7987c15f68e11379f2d178b187835e7b111ca8bac2f7785a3a2c285c7fa4545ebc71a2c57dbd77afc90c3b8ca818b6772272381ab276a633bd814c89247422c5bab70df3935ac4af67ae0cf307035deec58c2d17e582d327a2d1e3fae1228d2d1558822ef04e05d33861c47c9ca73443f94f9786bbe172070fcd5acf45017e67d40c307354589433cffe3264edfd2dc07d8973d397e5908606c76168ba9655c332bfd7b86ce2d785734a9ddd32834f93e56a02a5378040585663b0cf3846d602f38cdabc081fb02e2e3a137c6c386926ed9a24d05a41aaac6d10d61ce9c1f38a4c1c03f3f37da4c36b33550907ab131444c11c38298df12b6d8d89c2c2aaaf0280c1ec55d1ba4f8d4b50ca94d1da889f6f413cfc6943c3feae067cafcd554c03b1973d2ee9f53414b3703d15b6782218e01657d5b192c431374ab8f2441d84897b749c600c8004235d40094b9f2516bb8db":"54657374":"0a13b3abc2fb196212045827ce3e21d564b8959e7cf09783ce7b3f2dce9e4488359d9e647232b1280fcc8106392bf8bfc2daffc1f4d97002ed8b9dcc21768d29df342b8d02e0912af351e8267ad4ac9a11d84e8f238b6a389779157f7be3ebfc5b42dfff00539d302a86701b1f2d1f566b667723b219854f26a7da37b05a0362ce96f0aacdd3fa6d7186115df0ab0ba75afc2ae0f6688d6771d9be59e1d17fd45a5cd865485f7d818f253e22a3d4d93662f63238c1a92ab79446616e62bfa05c59c386fdc0ecec97aa5045517b8c6d0e4898237189f3aa61c21632dc93ff4c87d6201752842f1f0e2541bc3d11e8ed7dc25bb8dfc80e4bbd4f40e2728bce7909aa9cb19aea66e86b29c512b773f30399314d7929c26445812095a93eeb65382395c8a14a13f3fb73a64ae7afbe2c7dfac79ae2a40b1789a48daaebea1c0d39a32ff411d199c2532b4512ad3ba67fb7a02b8f5e762bf7d1b3b9207234306b230ea5c9640cb2d034c1ff24edefc98e1c4df8f7821a2a0d718bbe44b9d0896fd346b3bb9b0be69d95005b27153ba1f1609c2426822f80975fd342900648f7d53dc82bc1bc9bf247a4bbc8a84ca253a9204d286ecaf33bf67d06934a9f63ccdaa6142d6932854185a844d68cad7cc9852aaa5bd26c7762b7e4e978b2e09d567f196942b133c45b6d14c3227f5646cf6657bdbc85fc684fcfcd2963bdac98f4713349" + +HiTLS PrvKey decrypt: NO_PADDING, keyLen = 1024, hash = SHA1, msgLen = 128 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:1024:CRYPT_CTRL_SET_RSA_PADDING:CRYPT_MD_SHA1:"a155094c9c89e3eea1e62672047f8b1a1e8ca78919c5bcb0cef0b8e8e40c07197031ede10304541c766fd5da29faaf4a924ea27483d65fc47c24385fb010a9976bd346f0702a250fede9211b69bcb95516b31bacd0a9368376653a70bcf0b507869b08e8af1c1ce5eff28d02b6b6591c4fb52f520bbaaea773a4892a7ba2f713":"03":"6b8e0633130697f46beec44c02ffb21169b31a5b6683d32089f5d09b42b2af664acbf3eb57583812f99fe3e6c6a71f870c346c4dad39952da8182595200b1bb938de5cfbc817a443b2410bc859396196cabde8f5734b38bf073c8d31fdf4e4071610ef1b1559aef498f2418c82c13d49150d805db08bac92ab0467154765f4eb":"0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c":"2b5d2d5e1a4d4d97243bef743e5a7990ee6171bcfa37733968fd20b317e27af663f99a948f70446b28248e1b2e55a4924a1dea99845473a9c2a1ec4534ae796ee4caeb4ccaa99072bffd84e2757b01e82f1a8bc602997fa0a0cfa4249016a20176a79b4e07b163ba86298782b7ac868f64b33d1ac3cf5d18848c4d59d94b4bec" + +HiTLS PrvKey decrypt: NO_PADDING, keyLen = 2048, hash = SHA1, msgLen = 256 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:2048:CRYPT_CTRL_SET_RSA_PADDING:CRYPT_MD_SHA1:"d419435dfe85ccc42a3e29493d5cd742ec38b4bfa20438b47d4907d8e919990642f2f1125ba51275391358a09e8af812018ca120f5141c39ef4278dbac00c3fb043b4c046f823caf4fbe0dcf534d6fe32e38f347f9b2cefa8e104ab5f8da69d398040d282521386bdadfcecff23ae506abd459304db608ae29abf857fbbcceafcd2cdedc01154da12dc89f66a5439269fb8e79140fe720c0ba84448e1e51d90558e2e141859079e422f634d8a18960c830daba1f442b050c0a968fff1e5086306b56146cb8552f540cabdd7429e0689fc4a5bafca18918d05351082ea1cd20f587f7009e1cccc1cc4c5f2e653601094987ff1263534a11a83f80961b2620affd":"03":"8d662ce95459332d717ec630d3933a2c9d7b232a6c02d0785386053b461110aed74ca0b6e7c361a37b623b15bf07500c01086b6b4e0d68269f81a5e7c80082a758278802f5017dca35295e8a3788f5421ed0a22ffbcc89fc5eb58723fb3c468d1002b37018c0d047e73fdf354c274359c7e2e62033ceb0741bc7fae5527ddf1ea66e1a0e18427e51310a8d50874e10dd029e0883e0b4cc9ab23ac4b359f3771b10e8b8da0ce7b55df1be6a6a93cb38cf7c27f18d06d053892bed87c5d0a32ca14430028a5913ce16ab3ada23514f23a3374cce8182d38ee22b72a8ebd643e4163af457b06ebf1764929b799895d7064301b48ff3f2f2dc56c5318ae7b132116b":"0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458d":"26f7795d5cbfa6730a539248b96b4434b228fa6fcc598ef5b29df70263a5b01cb937c5a0b92450b3fe119faa9d957243f380a4fd088c9082324da21f7e3eed1d8a71f4ee111bc5367cc23197d43ed07e3c34b64cd25df950dbae9f463c9954afc08b97a8302072b02adf466c7391de6ab140175e812041796266dcbb86879fbd0208a06d548abaf3ffcf13eeb9586de2f2739f47b6fa913a397c3a5eccd2142f1354cda31278ff12aef3d43425eea3d4dbd6d5c785d3109003c560944b39e30316d825bd9f303f754accf6dc3c128916e858095e6bcf110d422cbcb9e73f2fab02872003264bebbe93aacf897a80fae4190a5541e846678b9a7a612a13daf00f" + +HiTLS PrvKey decrypt: NO_PADDING, keyLen = 3072, hash = SHA1, msgLen = 384 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:3072:CRYPT_CTRL_SET_RSA_PADDING:CRYPT_MD_SHA1:"d4766ee8d58ee9ae2cbde18bd6a89671118196ef711c4dd8e41926cea76628443e99a70d46e8b0ac68e140b329ded9fb68a2985f054e5d42d1d3a053c1a4de3d65223b9f1befae60af9a0c9879b9717f83d83aa53192df2b30477a706253f20ca345ad28fa9c3f0a09990e8f5f6aa7e000fd4e08e4d6b934a10b0e38d4cc78742c4dc6c74277fdd9e82a73074f8c9bb52b0b22781904ac748851552bbd25cddc498a3ce3182992b31cc065966f6a64069fa37c89cf5e2142f98fa6fd307db44cdbead66e575a74fe1d42aee98306381fb18d178a9e716a8dc20ff271a2253b4e0336bd870f4780dabdcf7dfe0aacc1415f00aa7d9f7ebb85ec28cb11e537821c1fdd44c62cf5ebe0fcc95f8c82a5309d5bb4cfb488648148678dc68630a4f9f8de298206c21415bb58e29869423f4ee1737458b0f5f30cb9833da7e43e7e768e0ded4c067151060ceae29c0913c87ee705a5423991a5ad6b308834425e0659cbc18bfe762f310db3c822bca37671a60c5262a6e93b0b0bfad5e2c7c5e73e0c91":"03":"8da449f08e5f46741dd3ebb28f1b0ef60babb9f4f612de909810c489c4eec582d4666f5e2f45cb1d9b40d5ccc694915245c1baea03899381e137c037d66de97e436c27bf67f51eeb1fbc0865a67ba0ffad3ad1c37661ea1ccada51a0418d4c086cd91e1b51bd7f5c066609b4ea471a9555fe3405ede47b786b5cb425e332faf81d892f2f81a553e69ac6f75a350867ce1cb216fabb5872f85ae0e3727e1933e83106d342101bb722132aee644a46ed59bfc253068a3ec0d7510a6f5375a922dcb0dd1e42266de1a8813fb9cca593eed3dcbb7a2ac0fbf7861cb556307ef66e5b0efa178e4ea78b4112424d68e899f1d35bfae3c76f0d3434ffa4b374b97a5077e6cf77b00ea403ceb2eb1ad6d7cd90b460213a5cd5fcb3f597e9651cfef83f3db3b4df7521be95564b1c4a4acd855c024a635ec2fbb27ed1a88d1b855ff94171016d5222f5ccc351bfc5ad602d8929a16977422e9a87973e5ffcdfa2d72b1a0a661de1e30ee7b79c0e79402a4276bc71ad515d76f6be2ca141a7f02c6483fe4b":"0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8dd":"5a53aed8b330fb508fc2c9319f28a1b38195f8b13501466f0d707fd41d180b3257a6cf0e32db9450a41eddcbe4a865bd3a94a8659bdf7b12a2b2f134689d557c5ce368f23c483086233d3231a0027b0b5108eef4fcf9e93aa5e7fc1aebc2335be72ea9b133be8763f217b1cfe9e46af5c9fa2db4eae26e10a9eca957ba63ccfe8ea3e955ffc0b4874c0637cc0285479d5c03ad0d1505df4f215bac6183eddbea364b7f904ffea5d99c279ce38cfddc96b9ef54802bc5914749a9571b9fd4d77c758d772df5e1a014f6fa3ed81058a9be03c7336ad5be0cfdcc8aae58689e6faf3250e504a298a2ea548d0b57247fbf022600c6a76aca53d60ea12c22487581eaa83a3e8451fcbbb45651f1b0bdb9d4629198844c2463ac1dcdc6c5d4029b4b14f05142f2aa9ba4e61d990ab057ff7a42efa02322d0e2a217fecaafee0f128ba5c6f17713d3962023c781ed41610a4f4a5fad3b2a431480b216002e7422f85943e75008e36a815a83a41f8e5395c51ea5412860f25ddcf49dbce064ada1bd7abf" + +HiTLS PrvKey decrypt: NO_PADDING, keyLen = 4096, hash = SHA1, msgLen = 512 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:4096:CRYPT_CTRL_SET_RSA_PADDING:CRYPT_MD_SHA1:"bf5fedf7045645cdf840431fe82fbd363f4d06ae41b617446d4d064df4da7f6515465cbf51bead40fc651c2df578c2974d04bc54f4cd9a89aadb65ec574e327a40dc3896167aa2573c3ff20e44fb8f92a7258fa3ad0c4f17cc787a08940862992407cd87d7215e1743c0a505757d0460431040bc2f6702f59877635bfdf6b3d96630b4e52fea09b6f9b943bea6729271edaa62b9d4096d32bb273cbd7f85a74e43a52120cd12d2c5a44929085b828db57e548141b6b1452ffcbc627ff953f5062e66c534b6151be574ca682255e57a628c10fc838229bdd34657343be49c52a80fa353ae17766f4277550b73457391c5173e1d8ff54431f0b8203a722c89a995a53380c3c3ff69bb7e0a9a2026d4bde193c285dd2885b9c864e372dc8cf2fd2fa46e0e46be226c7a5000a0a67d183b395bf539023918dadf2b9867a6cc4d222d0f5a47c67f5a41984ba2baa3e52440c1d71819e874f2d30f980d6f1578faf4714fc9ffab27935cba7a2693d958f78172112059cf8249289a49aba93ee668520271048786a0e96ec9089bd718f87ec8580415862b71a6c41d51f5fab936404fc37e386ca522e918e3889184bc5556a79cc41921fd30e6daab54ea9486b400e1c1b7eb7494e11df63508d828c1c011c1ca0fce9582e9df926a102eb024db943ff69fecc6d946aa206947c8dc3479c68536d91b7eca8bfbd6e3599d50e133fb7a27":"03":"7f95494f583983dea5802cbff01fd3797f88af1ed67964d848de0433f891aa4363843dd4e129c8d5fd98bd73f8fb2c64de032838a333bc5bc73cee9d8f8976fc2b3d7b0eb9a716e4d2d54c0983525fb71a190a6d1e0834ba8850515b0d5aec66180533afe4c0e964d7d5c358f8fe02ead7602b281f9a01f9104f9792a94f2290eecb23437546b124a67b827f19a1b6f69e7197268d5b9e21d21a287e5503c4ded7c36b6b3361e1d91830c60592570923a98dab8124762e1ffdd2ec5550e2a35974448378796367ee4ddc456c3943a6ec5d60a857ac1bd3e22ee4cd7d4312e1c55fc237c964f99f81a4e35cf783a2612e0f7ebe5ff8d8214b256ad1a17306710d4702ea647a7fe38a38992874c6474ebd59a0a72e21f52057a87f7f8e830ec4bf5a0c7a0b0b5ae070efb8c615a345bb3a86f75ef37c86608512a75a5214fa3da6f8affae6f251fbd4bd4e5e10703c61b11bdedcfdc5deb8488a25d275f84b359ae87490e60f12b32a117e670cfc080312a17f915d33d2d63a08921a6d2533f2d99160e6c73d0f263e02e7cc29d1cad41f9282a2c8846e848221d542ab921ecdc9165a3053619836f68e0859c7990a3cd3a39bb41cfcb283cbc44bcfa52b9b5f80b400efa1ffb72a82e1572b75b31bc39ecfbc75def6c5412879c7611ede35fb2258e8fcace8ade2bb3ed94258ac0d3e1ab01ee224a2c054ad8820bacccc9a810b":"0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b43820fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcb":"b55436b2fe34b7f916f76fe4fb1215e7b613396181813db212cb298ae095cd97198992b3b5de6022b7921757868946faed061ce8b2ee3435a604099960e23eb2ece44c25e1a42c870337b7c8937e3e3ed737b992984f6d7aca9b2427c38d883af79b66eb23be510aef3d0df055dde54d62651b7a8712b7832abd6b4f002710af39fe0cb21722a16f227b7368d0379d6acdfd7fb8615fd36b156c00601d3b03c1192d8fbd5724234a0b06862244f6b840fcc99e1675d658cf139356c0f103552f96140e2239db379f23045f4cf626efab84a6402ff5633e549b0c2163173517141233c74529befd3106dbdb390064480bd507efd136f2eb8347e36ddf0d81dd135029402b137959aaf7d656054c86394384df30dcc3c83c0d697a50d596575389fe207f26e27f683ef8143106af35298c8411a586cb02c64efd30b674e628c402fcb747e71a2d99eb0772ecb478bdfee8924f33989f06263eb8f13297a7031c539e98f9119ddd78eb6167e91e04f1c5f2ed12639cb2c17ffe4c561b21fefe7e8da7b6642623e8e11f1ef77d3422d406ed91dc6d23288a4330b3e23ca46ddb094567c23a20c0d853ed06f1a8eb8f91560bea42ee0d5ec9a8b8f7f39a6a7433bb77e5791b0ed4558ff3dc9ce686901ef90cd75d2d2c3e04881820de6b35797e31cb5a20abc0e57e2fb2bb63d2afd89162cc4bdc0c1aae1be5b49f6dd58c9953fd8b" + +HiTLS PrvKey decrypt: PKCSV15, keyLen = 2048, hash = SHA256, msgLen = 64 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:2048:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_MD_SHA256:"cdf0b791aff9d4862b5baa15739ddc99e161b638207d103c903096c67fb4e6317d37020034f128cdff1e9a74aef4cf524435802e6e411c52c3883f3c2dc39f961affd27a2b420c1205a7178f9a69b74bc2990919ac618b8e8f0f48ec001c0773c751322d920ac1a003992c59222220a8485d08c8b201fb2211be060eb65437e478e242822fe315609257cacea87f1d635c13ae7cbe4455c72408d70f7f4132c8c7f45daec6de3a01529d29c49d5a5287f42c165fbb5b1ad59c3d5ae49384a97b0f74d16603450e706416fc9fb1bc6c2e050eda48cde67ac74c78c51195cc4d119e8c70de0dbef59180f7b98ee9f11c86014ac6ea2edc2792bb63456e67e867df":"010001":"39d6285fd089bbdf806eca6a22e1cb522623807eebd4e3c9f67ec6e1717d3706e011224d379120f2157b9d4a36d687212609d67973ba727f65edae40b2e3953e9d4f8a67881d90f140c8280c4b03f497e0cb84ec4266d4c0513a2c332766b7cb12c7a16d7dedea6a0b88a99550ca3fdcb311f9c50f8511e8040e9779eb47e4b812a5ea2f274fb68a82443c91582ad9b98d05e36f48533410f04b64ba4c6bf6f90ed62806a506afcf45646770744ace5952ecad86a89afd526a50377678381414e2e4d7610c7def7fcb926cf26371bd63457c45d7bb30bd31ce0a62787a4fe00d65d8f73c6cec4476a50a79a16f6204e3e193e55a7871b832b40b705a08ba37e1":"4a4e743f877ea6e94e545a56ccb5a1f99efc7eb1e8191929152a56d41dc924254a4e743f877ea6e94e545a56ccb5a1f99efc7eb1e8191929152a56d41dc92425":"842ceabd0c227b5adb1e41961a3a3cfbcf371273c7e3ba63d59fe1031c9555a0cec446f6de4c1265b979369b5893608d9d6479cc9ff3c45e6ec3fc66c5bdd6e2886dc01d3039b899a2b23a3c877bd3d7dd7447f123f20644adf0b69c8834540f1d995547f37fee2053c2287119d572047697ecadf92d774922b6f449f007d94692a6438ea0d27f5611f360e094e220cbdbf3370fa026ebded8e653f7a368b7bd67103a2cfb3d97467de7f3b040c2968ed9ea1ce4f00b9a968eefce9b78d7cb01388f447f646be19bd2dc54acb069602b9630c7f058d1a4be711109e50cde91b295fbf92da42b8ce43bd2f0676ac6c61a6981feaed8b6cccbe9f35db5c3cf61a4" + +HiTLS PrvKey decrypt: PKCSV15, keyLen = 2048, hash = SHA512, msgLen = 64 +SDV_CRYPTO_RSA_CRYPT_FUNC_TC001:2048:CRYPT_CTRL_SET_RSA_RSAES_PKCSV15:CRYPT_MD_SHA512:"cdf0b791aff9d4862b5baa15739ddc99e161b638207d103c903096c67fb4e6317d37020034f128cdff1e9a74aef4cf524435802e6e411c52c3883f3c2dc39f961affd27a2b420c1205a7178f9a69b74bc2990919ac618b8e8f0f48ec001c0773c751322d920ac1a003992c59222220a8485d08c8b201fb2211be060eb65437e478e242822fe315609257cacea87f1d635c13ae7cbe4455c72408d70f7f4132c8c7f45daec6de3a01529d29c49d5a5287f42c165fbb5b1ad59c3d5ae49384a97b0f74d16603450e706416fc9fb1bc6c2e050eda48cde67ac74c78c51195cc4d119e8c70de0dbef59180f7b98ee9f11c86014ac6ea2edc2792bb63456e67e867df":"010001":"39d6285fd089bbdf806eca6a22e1cb522623807eebd4e3c9f67ec6e1717d3706e011224d379120f2157b9d4a36d687212609d67973ba727f65edae40b2e3953e9d4f8a67881d90f140c8280c4b03f497e0cb84ec4266d4c0513a2c332766b7cb12c7a16d7dedea6a0b88a99550ca3fdcb311f9c50f8511e8040e9779eb47e4b812a5ea2f274fb68a82443c91582ad9b98d05e36f48533410f04b64ba4c6bf6f90ed62806a506afcf45646770744ace5952ecad86a89afd526a50377678381414e2e4d7610c7def7fcb926cf26371bd63457c45d7bb30bd31ce0a62787a4fe00d65d8f73c6cec4476a50a79a16f6204e3e193e55a7871b832b40b705a08ba37e1":"4a4e743f877ea6e94e545a56ccb5a1f99efc7eb1e8191929152a56d41dc924254a4e743f877ea6e94e545a56ccb5a1f99efc7eb1e8191929152a56d41dc92425":"a81653d15cb23545902169d98c6281b9cf2b90a09e32c8fd12d7bc70c664820dcb29daf280de5c9257d52e30094dbb446469e07b2f0b290e63dd2a9778aea203968c9ac22b5511c077b136651dd43d986ac03e2cc87b3cbb37e21abcf4e980a23e60bddab0b88e68e5b1bcdabbd9c1a2a5ad639664f4d1b1280c5f98187a1ee72ece18453612e2762271d1a392ea16556c1383d01f8d6c118b76b416325f6903061d0a2dc0952a0af8016c52734cb8091cd3490a72ad8742e55517ee92efaf751dd14f8a70bcc273ef749c9838082ab1c71da49429c28378408be759ee4ec5acfd416cc31393931c565822046f7dc0751aa189ff12557f0750fef6c3261616b1" + +set paddingMode test: vectors from nist +SDV_CRYPTO_RSA_CRYPT_FUNC_TC002:"a911245a2cfb33d8ee375df9439f74e669c03a8d9acad25bd27acf3cd8bea7eb9dbe470155c7c72782c94861f7b573cd325639fb070e9ba6e621991aefa45106182e4d264be7068035595d7549052989b3e7fd04cabc94012c1278a0ef8672b1a51dd1a9e276816ba497dea24b4febe3dd8e977707bcd230ca6fb6f8a8bff9e6ba24fbadcd93f00126b19b396a38e6ef86d18fef945b9154c1963fb488c7025953511f86d05638bfe056493730bc6778446e59cd3c5c3acf07a0a3a64943793652f10e3292aa7a6d25a03181cc6f6ba0658d909e59ce2a02bacc9766fd8c4fbd4ed9c23a866844b8a794d49e505f9f944870a71aadbe5338039825c2dff81af3":"010001":"290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061":"01020304" + +rsa-oaep set label test: vectors from nist +SDV_CRYPTO_RSA_CRYPT_FUNC_TC003:"f33d3234f13272c3b2b6821ce4805663ff2e8b0d2a47de363d97fc9cc879cc6b40f9e53aea695dc538a0d2b558498829aac327eacbcd889e172b34f90745c5d528b7e82605f1a58fd228ec7fd4b6f476f393864f48dc47097c8a780a2ecc02f748138dbd7df99c52d822a2e5154c6047fb0eeb4f49da38edcae3c32d3fde435f291f96cad1e09e1030ad7efb4944b69e074d0d7964becb3cb86238d8d293bef3030d141d14868bc21fa133e9de1115f749991cf86ef506e663ac162b2c8567ff131a6b467a6f564d6c588860becbd88970354198ecdd4f1f4baee8f8bdaf7255835385f5673625f113550b123628a0be3994d91c3a19a82e5d73448dabf684ee6794fba7a2b1afbee0287e5a11180c29ce0896795d52ac7f408fe28e8e9116fe0b61a1083f95c5227d62d5537b5040b79e21b3a8e83c225bf3efebb2f808541e97d28a2468359fc60f588e74faad611262064628a25d8d61f9d03d8b21cca515595aaf2343a759b74a6a8afeffca139a389aa281995cd18e16a9cf7b7ff0dddb":"010001":"078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd":"01020304":"0102030405" diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c new file mode 100644 index 00000000..6009c718 --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c @@ -0,0 +1,1045 @@ +/* + * 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_BASE test_suite_sdv_eal_rsa */ + +/* BEGIN_HEADER */ + +#include +#include +#include + +#include "bsl_errno.h" +#include "crypt_eal_md.h" +/* END_HEADER */ + +int MD_Data(CRYPT_MD_AlgId mdId, Hex *msgIn, Hex *mdOut) +{ + uint32_t outLen; + CRYPT_EAL_MdCTX *mdCtx = NULL; + uint32_t mdOutLen = CRYPT_EAL_MdGetDigestSize(mdId); + ASSERT_TRUE(mdOutLen != 0); + mdOut->x = (uint8_t *)malloc(mdOutLen); + ASSERT_TRUE(mdOut->x != NULL); + mdOut->len = mdOutLen; + outLen = mdOutLen; + mdCtx = CRYPT_EAL_MdNewCtx(mdId); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdNewCtx", mdCtx != NULL); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdInit", CRYPT_EAL_MdInit(mdCtx) == 0); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdUpdate", CRYPT_EAL_MdUpdate(mdCtx, msgIn->x, msgIn->len) == 0); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_MdFinal", CRYPT_EAL_MdFinal(mdCtx, mdOut->x, &outLen) == 0); + mdOut->len = outLen; + CRYPT_EAL_MdFreeCtx(mdCtx); + return SUCCESS; + +exit: + CRYPT_EAL_MdFreeCtx(mdCtx); + free(mdOut->x); + mdOut->x = NULL; + return FAIL; +} + +/** + * @test SDV_CRYPTO_RSA_SIGN_API_TC001 + * @title RSA CRYPT_EAL_PkeySign: Wrong parameters. + * @precon Create the context of the rsa algorithm, set private key and set padding type to pkcsv15: + * @brief + * 1. Call the CRYPT_EAL_PkeySetPrv method: + * (1) pkey = null, expected result 1. + * (2) data = null, dataLen = 0, expected result 2. + * (3) data = null, dataLen != 0, expected result 3. + * (4) data != null, dataLen = 0, expected result 4. + * (5) sign = null, signLen != 0, expected result 5. + * (6) sign != null, signLen = 0, expected result 6. + * (7) sign != null, signLen == NULL, expected result 7. + * 2. Call the CRYPT_EAL_PkeySetPrv method with incorrect hash id, expected result 8: + * CRYPT_MD_MD4, CRYPT_MD_MD5, CRYPT_MD_SHA1, CRYPT_MD_SM3, CRYPT_MD_MAX + * @expect + * 1. CRYPT_NULL_INPUT + * 2. CRYPT_SUCCESS + * 3. CRYPT_NULL_INPUT + * 4. CRYPT_SUCCESS + * 5. CRYPT_NULL_INPUT + * 6. CRYPT_RSA_BUFF_LEN_NOT_ENOUGH + * 7. CRYPT_NULL_INPUT + * 8. Return CRYPT_RSA_ERR_ALGID or CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SIGN_API_TC001(Hex *n, Hex *d) +{ + int32_t ret; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPrv privaKey = {0}; + uint8_t *data = NULL; + uint8_t *sign = NULL; + uint32_t signLen = d->len + 1; + uint32_t dataLen = signLen; + CRYPT_RSA_PkcsV15Para pkcsv15 = {CRYPT_MD_SHA224}; + CRYPT_MD_AlgId errIdList[] = {CRYPT_MD_MD4, CRYPT_MD_MD5, CRYPT_MD_SHA1, CRYPT_MD_SM3, CRYPT_MD_MAX}; + + /* Malloc signature buffer */ + sign = (uint8_t *)malloc(signLen); + data = (uint8_t *)malloc(signLen); + ASSERT_TRUE(sign != NULL && data != NULL); + SetRsaPrvKey(&privaKey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &privaKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySign(NULL, CRYPT_MD_SHA224, data, dataLen, sign, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, NULL, 0, sign, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, NULL, dataLen, sign, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, data, 0, sign, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, data, dataLen, NULL, &signLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, data, dataLen, sign, NULL), CRYPT_NULL_INPUT); + signLen = 0; + ASSERT_EQ( + CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, data, dataLen, sign, &signLen), CRYPT_RSA_BUFF_LEN_NOT_ENOUGH); + + signLen = dataLen; + for (int i = 0; i < (int)(sizeof(errIdList) / sizeof(CRYPT_MD_AlgId)); i++) { + ret = CRYPT_EAL_PkeySign(pkeyCtx, errIdList[i], data, dataLen, sign, &signLen); + ASSERT_TRUE(ret == CRYPT_RSA_ERR_ALGID || ret == CRYPT_EAL_ERR_ALGID); + } +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(data); + free(sign); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC001 + * @title RSA EAL layer signature function test: PKCSV15, sha224 + * @precon nan + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set the private key for pkeyCtx, expected result 2 + * 3. Set the padding algorithm to PKCS15 and set the hash value to SHA224, expected result 3 + * 4. Call the CRYPT_EAL_PkeySign method with invalid mdId, expected result 4 + * 5. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. CRYPT_EAL_ERR_ALGID + * 5. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC001(Hex *n, Hex *d, Hex *msg, Hex *sign) +{ + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPrv privaKey = {0}; + uint8_t *signdata = NULL; + uint32_t signLen = sign->len; + CRYPT_RSA_PkcsV15Para pkcsv15 = {CRYPT_MD_SHA224}; + + /* Malloc signature buffer */ + signdata = (uint8_t *)malloc(signLen); + ASSERT_TRUE(signdata != NULL); + SetRsaPrvKey(&privaKey, n->x, n->len, d->x, d->len); + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &privaKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(signdata); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002 + * @title RSA EAL layer signature function test: PKCSV15 + * @precon nan + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set the private key for pkeyCtx, expected result 2 + * 3. Set the padding algorithm to PKCS15 and set the hash value to SHA2, expected result 3 + * 4. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 4 + * 5. Compare the signature result and the signature vector., expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS + * 4. CRYPT_SUCCESS + * 5. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002(int mdId, Hex *n, Hex *d, Hex *msg, Hex *sign) +{ + if (IsMdAlgDisabled(mdId)) { + SKIP_TEST(); + } + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPrv privaKey = {0}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + uint8_t *signdata = NULL; + uint32_t signLen; + + SetRsaPrvKey(&privaKey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &privaKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), 0); + + /* Malloc signature buffer */ + signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + ASSERT_EQ(signLen, sign->len); + signdata = (uint8_t *)malloc(signLen); + ASSERT_TRUE(signdata != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + ASSERT_COMPARE("CRYPT_EAL_PkeySign Compare", sign->x, sign->len, signdata, signLen); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(signdata); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001 + * @title RSA EAL layer signature function test: Pss + * @precon nan + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set the private key for pkeyCtx, expected result 2 + * 3. Set the padding algorithm to PKCS15 and set the hash value to SHA2, expected result 3 + * 4. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 4 + * 5. Compare the signature result and the signature vector., expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001(int mdId, Hex *n, Hex *d, Hex *msg, Hex *sign, Hex *salt) +{ + if (IsMdAlgDisabled(mdId)) { + SKIP_TEST(); + } + int i; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPrv privaKey = {0}; + CRYPT_RSA_PssPara pkeyPad = {.saltLen = salt->len, .mdId = mdId, .mgfId = mdId}; + uint8_t *signdata = NULL; + uint32_t signLen = sign->len; + + SetRsaPrvKey(&privaKey, n->x, n->len, d->x, d->len); + + /* Malloc signature buffer */ + signdata = (uint8_t *)malloc(signLen); + ASSERT_TRUE(signdata != NULL); + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &privaKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pkeyPad, PSS_SIZE), CRYPT_SUCCESS); + + /* Repeat signature 2 times. */ + for (i = 0; i < 2; i++) { + if (salt->len != 0) { + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_SALT, salt->x, salt->len), CRYPT_SUCCESS); + } + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + ASSERT_COMPARE("Compare Sign Data", signdata, signLen, sign->x, sign->len); + signLen = sign->len; + } + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(signdata); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002 + * @title RSA EAL layer signature function test: Pss with different salt lengths. + * @precon nan + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Initialize the DRBG, expected result 2 + * 3. Set the private key for pkeyCtx, expected result 3 + * 4. Set the padding algorithm to PSS and set the hash value to SHA2, expected result 4 + * 5. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-5. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002(int mdId, Hex *n, Hex *d, Hex *msg, int saltLen) +{ + if (IsMdAlgDisabled(mdId)) { + SKIP_TEST(); + } + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPrv privaKey = {0}; + uint8_t *signdata = NULL; + uint32_t signLen; + CRYPT_RSA_PssPara pkeyPad = {.saltLen = saltLen, .mdId = mdId, .mgfId = mdId}; + + SetRsaPrvKey(&privaKey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &privaKey), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pkeyPad, PSS_SIZE), CRYPT_SUCCESS); + + /* Malloc signature buffer */ + signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + ASSERT_TRUE(signLen != 0); + signdata = (uint8_t *)malloc(signLen); + ASSERT_TRUE(signdata != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(signdata); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003 + * @title RSA EAL layer signature function test: Do not set the salt length of PSS. + * @precon Vectors: private key, msg. + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set the private key for pkeyCtx, expected result 2 + * 3. Initialize the DRBG, expected result 3 + * 4. Set the padding algorithm to PSS, saltLen is 0 | -1 | -2, expected result 4 + * 5. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003(Hex *n, Hex *d, Hex *msg, int saltLen) +{ + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPrv privaKey = {0}; + CRYPT_RSA_PssPara pkeyPad = {.saltLen = saltLen, .mdId = CRYPT_MD_SHA224, .mgfId = CRYPT_MD_SHA224}; + uint8_t *signdata = NULL; + uint32_t signLen; + + SetRsaPrvKey(&privaKey, n->x, n->len, d->x, d->len); + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkeyCtx, &privaKey), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pkeyPad, PSS_SIZE), CRYPT_SUCCESS); + + /* Malloc signature buffer */ + signLen = CRYPT_EAL_PkeyGetSignLen(pkeyCtx); + ASSERT_TRUE(signLen != 0); + signdata = (uint8_t *)malloc(signLen); + ASSERT_TRUE(signdata != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkeyCtx, CRYPT_MD_SHA224, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(signdata); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC001 + * @title RSA EAL sign/verify and signData/verifyData:PKCSV15, sha256 + * @precon + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetPara, where bits are: 1024/2048/4096, expected result 2 + * 3. Initialize the DRBG, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGen to generate a key pair again, expected result 5 + * 6. Set padding type to pkcsv15, expected result 6 + * 7. Call the CRYPT_EAL_PkeySign method and use pkey to sign a piece of data, expected result 7 + * 8. Call the CRYPT_EAL_PkeyVerify method and use pkey to verify the signed data, expected result 8 + * 9. Call the CRYPT_EAL_PkeySignData method and use pkey to sign a piece of hash data, expected result 9 + * 10. Call the CRYPT_EAL_PkeyVerifyData method and use pkey to verify the signed data, expected result 10 + * 11. Allocate the memory for the CRYPT_EAL_PkeyCtx, named cpyCtx, expected result 11 + * 12. Call the CRYPT_EAL_PkeyCopyCtx to copy pkeyCtx, expected result 12 + * 13. Call the CRYPT_EAL_PkeySignData method and use cpyCtx to sign a piece of data, expected result 13 + * 14. Call the CRYPT_EAL_PkeyVerifyData method and use cpyCtx to verify the signed data, expected result 14 + * @expect + * 1. Success, and context is not NULL. + * 2-10. CRYPT_SUCCESS + * 11. Success. + * 12-14. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC001(int bits) +{ +#ifndef HITLS_CRYPTO_SHA256 + SKIP_TEST(); +#endif + uint32_t signLen = (bits + 7) >> 3; // keybytes == (keyBits + 7) >> 3 */ + int mdId = CRYPT_MD_SHA256; + uint8_t data[500] = {0}; + const uint32_t dataLen = sizeof(data); + uint8_t hash[32]; // SHA256 digest length: 32 + const uint32_t hashLen = sizeof(hash); + uint8_t e[] = {1, 0, 1}; + + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + CRYPT_EAL_PkeyPara para = {0}; + + SetRsaPara(¶, e, 3, bits); + + uint8_t *sign = malloc(signLen); + ASSERT_TRUE_AND_LOG("Malloc Sign Buffer", sign != NULL); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, mdId, data, dataLen, sign, &signLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, mdId, data, dataLen, sign, signLen), CRYPT_SUCCESS); + + signLen = (bits + 7) >> 3; // keybytes == (keyBits + 7) >> 3 */ + memset_s(hash, sizeof(hash), 'A', sizeof(hash)); + ASSERT_EQ(CRYPT_EAL_PkeySignData(pkey, hash, hashLen, sign, &signLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyVerifyData(pkey, hash, hashLen, sign, signLen), CRYPT_SUCCESS); + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, pkey), CRYPT_SUCCESS); + + signLen = (bits + 7) >> 3; + ASSERT_EQ(CRYPT_EAL_PkeySign(cpyCtx, mdId, data, dataLen, sign, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(cpyCtx, mdId, data, dataLen, sign, signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); + free(sign); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PSS_FUNC_TC001 + * @title RSA EAL signData/verifyData: pss, sha256, saltLen=32bytes + * @precon + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetPara, where bits is 1025, expected result 2 + * 3. Initialize the DRBG, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 4 + * 5. Set padding type to pkcsv15 and set salt(32 bytes), expected result 5 + * 6. Call the CRYPT_EAL_PkeySignData method and use pkey to sign a piece of data, expected result 6 + * 7. Call the CRYPT_EAL_PkeyVerifyData method and use pkey to verify the signed data, expected result 7 + * 8. Allocate the memory for the CRYPT_EAL_PkeyCtx, named cpyCtx, expected result 8 + * 9. Call the CRYPT_EAL_PkeyCopyCtx to copy pkeyCtx, expected result 9 + * 10. Call the CRYPT_EAL_PkeySignData method and use cpyCtx to sign a piece of data, expected result 10 + * 11. Call the CRYPT_EAL_PkeyVerifyData method and use cpyCtx to verify the signed data, expected result 11 + * @expect + * 1. Success, and context is not NULL. + * 2-7. CRYPT_SUCCESS + * 8. Success. + * 9-11. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PSS_FUNC_TC001(int bits) +{ +#ifndef HITLS_CRYPTO_SHA256 + SKIP_TEST(); +#endif + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + CRYPT_RSA_PssPara pad = {.saltLen = 32, .mdId = CRYPT_MD_SHA256, .mgfId = CRYPT_MD_SHA256}; + CRYPT_EAL_PkeyPara para = {0}; + uint8_t e[] = {1, 0, 1}; + uint8_t salt[100]; + uint32_t signLen = (bits + 7) >> 3; // keybytes == (keyBits + 7) >> 3 */ + uint8_t hash[32]; // SHA256 digest length 32 + const uint32_t hashLen = sizeof(hash); + + memset_s(hash, sizeof(hash), 'A', sizeof(hash)); + (void)memset_s(salt, sizeof(salt), 'A', sizeof(salt)); + uint8_t *sign = malloc(signLen); + ASSERT_TRUE(sign != NULL); + SetRsaPara(¶, e, 3, bits); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_TRUE_AND_LOG("Malloc Sign Buffer", sign != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pad, PSS_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_SALT, (uint8_t *)salt, 32), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySignData(pkey, hash, hashLen, sign, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerifyData(pkey, hash, hashLen, sign, signLen), CRYPT_SUCCESS); + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySignData(cpyCtx, hash, hashLen, sign, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerifyData(cpyCtx, hash, hashLen, sign, signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); + free(sign); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC002 + * @title RSA EAL sign/verify:Generate a key pair, set pubKey, PKCSV15, sha256 + * @precon + * @brief + * 1. Create the contexts(pkey, pkey2) of the rsa algorithm, expected result 1 + * 2. Set para for pkey and pkey2, expected result 2 + * 3. Initialize the DRBG, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 4 + * 5. Get public key from pkey, expected result 5 + * 6. Set public key for pkey2, expected result 6 + * 7. Set padding type to pkcsv15 for pkey and pkey2, expected result 7 + * 8. Call the CRYPT_EAL_PkeySign method and use pkey to sign a piece of data, expected result8 + * 9. Call the CRYPT_EAL_PkeyVerify method and use pkey2 to verify the signed data, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2-9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC002(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPub pubKey = {0}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {CRYPT_MD_SHA256}; + uint8_t pubN[600]; + uint8_t pubE[600]; + uint8_t e[] = {1, 0, 1}; + uint8_t sign[200]; + uint32_t signLen = 200; // 200bytes is greater than 1024 bits. + uint8_t data[500] = {0}; + const uint32_t dataLen = 500; + + SetRsaPara(¶, e, 3, 1024); + SetRsaPubKey(&pubKey, pubN, 600, pubE, 600); + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey2, ¶), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPub(pkey, &pubKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkey2, &pubKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey2, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey, CRYPT_MD_SHA256, data, dataLen, sign, &signLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey2, CRYPT_MD_SHA256, data, dataLen, sign, signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC003 + * @title RSA EAL sign/verify:Generate a key pair, set prvKey, PKCSV15, sha256 + * @precon + * @brief + * 1. Create the contexts(pkey, pkey2) of the rsa algorithm, expected result 1 + * 2. Set para for pkey and pkey2, expected result 2 + * 3. Initialize the DRBG, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 4 + * 5. Get private key from pkey, expected result 5 + * 6. Set private key for pkey2, expected result 6 + * 7. Set padding type to pkcsv15 for pkey and pkey2, expected result 7 + * 8. Call the CRYPT_EAL_PkeySign method and use pkey2 to sign a piece of data, expected result8 + * 9. Call the CRYPT_EAL_PkeyVerify method and use pkey to verify the signed data, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2-9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC003(void) +{ + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *pkey2 = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {CRYPT_MD_SHA256}; + uint8_t prvD[600]; + uint8_t prvN[600]; + uint8_t prvP[600]; + uint8_t prvQ[600]; + uint8_t e[] = {1, 0, 1}; + uint8_t sign[600]; + uint32_t signLen = 600; // 600bytes > 1024bits + uint8_t data[500] = {0}; + uint32_t dataLen = sizeof(data); + + SetRsaPara(¶, e, 3, 1024); + prvKey.id = CRYPT_PKEY_RSA; + prvKey.key.rsaPrv.d = prvD; + prvKey.key.rsaPrv.dLen = 600; // 600bytes > 1024bits + prvKey.key.rsaPrv.n = prvN; + prvKey.key.rsaPrv.nLen = 600; // 600bytes > 1024bits + prvKey.key.rsaPrv.p = prvP; + prvKey.key.rsaPrv.pLen = 600; // 600bytes > 1024bits + prvKey.key.rsaPrv.q = prvQ; + prvKey.key.rsaPrv.qLen = 600; // 600bytes > 1024bits + prvKey.key.rsaPrv.dP = NULL; + prvKey.key.rsaPrv.dPLen = 0; + prvKey.key.rsaPrv.dQ = NULL; + prvKey.key.rsaPrv.dQLen = 0; + prvKey.key.rsaPrv.qInv = NULL; + prvKey.key.rsaPrv.qInvLen = 0; + + TestMemInit(); + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + pkey2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL && pkey2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey2, ¶), CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyGetPrv(pkey, &prvKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(pkey2, &prvKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey2, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeySign(pkey2, CRYPT_MD_SHA256, data, dataLen, sign, &signLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkey, CRYPT_MD_SHA256, data, dataLen, sign, signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(pkey2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001 + * @title Rsa verify-PKCS15 + * @precon + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set public key for pkeyCtx, expected result 2 + * 3. Set padding type to pkcsv15 for pkeyCtx, expected result 3 + * 4. Call the CRYPT_EAL_PkeyVerify method and use pkeyCtx to verify the signed data, expected result 4 + * 5. Calculate the hash value of msg, expected result 5 + * 6. Call the CRYPT_EAL_PkeyVerifyData method and use pkeyCtx to verify the signed data, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Reutrn CRYPT_SUCCESS when expect is 0, otherwise return CRYPT_RSA_NOR_VERIFY_FAIL. + * 5. SUCCESS + * 6. Reutrn CRYPT_SUCCESS when expect is 0, otherwise return CRYPT_RSA_NOR_VERIFY_FAIL. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001(int mdAlgId, Hex *n, Hex *e, Hex *msg, Hex *sign, int expect) +{ + if (IsMdAlgDisabled(mdAlgId)) { + SKIP_TEST(); + } + int ret; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPub publicKey = {0}; + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdAlgId}; + Hex mdOut = {0}; + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + + /* Set the public key.*/ + SetRsaPubKey(&publicKey, n->x, n->len, e->x, e->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkeyCtx, &publicKey), CRYPT_SUCCESS); + + /* Set padding. */ + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + + ret = CRYPT_EAL_PkeyVerify(pkeyCtx, mdAlgId, msg->x, msg->len, sign->x, sign->len); + if (expect == SUCCESS) { + ASSERT_EQ(ret, CRYPT_SUCCESS); + } else { + ASSERT_EQ(ret, CRYPT_RSA_NOR_VERIFY_FAIL); + } + + ASSERT_TRUE(MD_Data(mdAlgId, msg, &mdOut) == SUCCESS); + ret = CRYPT_EAL_PkeyVerifyData(pkeyCtx, mdOut.x, mdOut.len, sign->x, sign->len); + if (expect == SUCCESS) { + ASSERT_EQ(ret, CRYPT_SUCCESS); + } else { + ASSERT_EQ(ret, CRYPT_RSA_NOR_VERIFY_FAIL); + } + + ret = CRYPT_EAL_PkeyVerifyData(NULL, mdOut.x, mdOut.len, sign->x, sign->len); + ASSERT_TRUE_AND_LOG("CRYPT_EAL_PkeyVerifyData", ret != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + free(mdOut.x); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001 + * @title Rsa verify-PSS + * @precon + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set public key for pkeyCtx, expected result 2 + * 3. Set padding type to PSS for pkeyCtx, expected result 3 + * 4. Call the CRYPT_EAL_PkeyVerify method and use pkeyCtx to verify the signed data, expected result 4 + * 5. Calculate the hash value of msg, expected result 5 + * 6. Call the CRYPT_EAL_PkeyVerifyData method and use pkeyCtx to verify the signed data, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Reutrn CRYPT_SUCCESS when expect is 0, otherwise return CRYPT_RSA_NOR_VERIFY_FAIL. + * 5. SUCCESS + * 6. Reutrn CRYPT_SUCCESS when expect is 0, otherwise return CRYPT_RSA_NOR_VERIFY_FAIL. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001(int mdAlgId, Hex *n, Hex *e, Hex *salt, Hex *msg, Hex *sign, int expect) +{ + if (IsMdAlgDisabled(mdAlgId)) { + SKIP_TEST(); + } + int ret; + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPub publicKey = {0}; + CRYPT_RSA_PssPara pkeyPad = {.saltLen = salt->len, .mdId = mdAlgId, .mgfId = mdAlgId}; + Hex mdOut = {0}; + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + + /* Set the public key.*/ + SetRsaPubKey(&publicKey, n->x, n->len, e->x, e->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkeyCtx, &publicKey), CRYPT_SUCCESS); + + /* Set padding. */ + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pkeyPad, PSS_SIZE), CRYPT_SUCCESS); + ret = CRYPT_EAL_PkeyVerify(pkeyCtx, mdAlgId, msg->x, msg->len, sign->x, sign->len); + if (expect == SUCCESS) { + ASSERT_EQ(ret, CRYPT_SUCCESS); + } else { + ASSERT_EQ(ret, CRYPT_RSA_NOR_VERIFY_FAIL); + } + + ASSERT_TRUE(MD_Data(mdAlgId, msg, &mdOut) == SUCCESS); + ret = CRYPT_EAL_PkeyVerifyData(pkeyCtx, mdOut.x, mdOut.len, sign->x, sign->len); + if (expect == SUCCESS) { + ASSERT_EQ(ret, CRYPT_SUCCESS); + } else { + ASSERT_EQ(ret, CRYPT_RSA_NOR_VERIFY_FAIL); + } + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); + if (mdOut.x != NULL) { + free(mdOut.x); + } +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC002 + * @title RSA verify PSS: saltLen is SALTLEN_PSS_AUTOLEN_TYPE + * @precon + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set public key for pkeyCtx, expected result 2 + * 3. Set padding type to PSS(saltLen is SALTLEN_PSS_AUTOLEN_TYPE) for pkeyCtx, expected result 3 + * 4. Call the CRYPT_EAL_PkeyVerify method and use pkeyCtx to verify the signed data, expected result 4 + * 5. Calculate the hash value of msg, expected result 5 + * 6. Call the CRYPT_EAL_PkeyVerifyData method and use pkeyCtx to verify the signed data, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC002(int mdAlgId, Hex *n, Hex *e, Hex *msg, Hex *sign) +{ + if (IsMdAlgDisabled(mdAlgId)) { + SKIP_TEST(); + } + CRYPT_EAL_PkeyCtx *pkeyCtx = NULL; + CRYPT_EAL_PkeyPub publicKey = {0}; + CRYPT_RSA_PssPara pkeyPad = {.saltLen = SALTLEN_PSS_AUTOLEN_TYPE, .mdId = mdAlgId, .mgfId = mdAlgId}; + + TestMemInit(); + + pkeyCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkeyCtx != NULL); + + /* Set the public key.*/ + SetRsaPubKey(&publicKey, n->x, n->len, e->x, e->len); + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pkeyCtx, &publicKey), CRYPT_SUCCESS); + + /* Set padding. */ + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkeyCtx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pkeyPad, PSS_SIZE), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(pkeyCtx, mdAlgId, msg->x, msg->len, sign->x, sign->len), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(pkeyCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_BLINDING_FUNC_TC001 + * @title RSA EAL sign and verify with blinding. + * @precon nan + * @brief + * 1. Create the context(pkeyCtx) of the rsa algorithm, expected result 1 + * 2. Set para, expected result 2 + * 3. Initialize the DRBG, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 4 + * 5. Set CRYPT_RSA_BLINDING flag, expected result 5 + * 6. Set padding type, expected result 6 + * 7. Sign with HiTLS, expected result 7 + * 8. Verify with HiTLS, expected result 8 + * @expect + * 1. Success, and context is not NULL. + * 2-8. CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_BLINDING_FUNC_TC001(int keyLen, int hashId, int padMode, Hex *msg, int saltLen) +{ + if (IsMdAlgDisabled(hashId)) { + SKIP_TEST(); + } + TestMemInit(); + uint8_t sign[MAX_CIPHERTEXT_LEN] = {0}; + uint32_t dataLen = MAX_CIPHERTEXT_LEN; + uint8_t e[] = {1, 0, 1}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + CRYPT_EAL_PkeyCtx *newCtx = NULL; + CRYPT_EAL_PkeyPara para = {0}; + CRYPT_RSA_PssPara pssParam = {.saltLen = saltLen, .mdId = hashId, .mgfId = hashId}; + int paraSize; + void *paraPtr; + + SetRsaPara(¶, e, 3, keyLen); + CRYPT_RSA_PkcsV15Para pkcsv15 = {hashId}; + if (padMode == CRYPT_CTRL_SET_RSA_EMSA_PSS) { + paraSize = PSS_SIZE; + paraPtr = &pssParam; + } else if (padMode == CRYPT_CTRL_SET_RSA_EMSA_PKCSV15) { + paraSize = PKCSV15_SIZE; + paraPtr = &pkcsv15; + } + + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pkey != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, padMode, paraPtr, paraSize) == CRYPT_SUCCESS); + uint32_t flag = CRYPT_RSA_BLINDING; + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_FLAG, (void *)&flag, sizeof(uint32_t)) == CRYPT_SUCCESS); + + /* private key signature */ + ASSERT_TRUE(CRYPT_EAL_PkeySign(pkey, hashId, msg->x, msg->len, sign, &dataLen) == CRYPT_SUCCESS); + + /* public key verify */ + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(pkey, hashId, msg->x, msg->len, sign, dataLen) == CRYPT_SUCCESS); + + newCtx = CRYPT_EAL_PkeyDupCtx(pkey); + ASSERT_TRUE(newCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySign(newCtx, hashId, msg->x, msg->len, sign, &dataLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_PkeyFreeCtx(newCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_BLINDING_FUNC_TC002 + * @title RSA: Pkcsv15, Blinding, Signature. + * @precon nan + * @brief + * 1. Create the context of the rsa algorithm, expected result 1 + * 2. Set private key, EMSA_PKCSV15 and CRYPT_RSA_BLINDING flag, expected result 2 + * 3. Initialize the drbg, expected result 3 + * 4. Signature, expected result 4 + * 5. Dup the context, and sign with new context, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS. + * 5. Success. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_BLINDING_FUNC_TC002(int mdId, Hex *p, Hex *q, Hex *n, Hex *d, Hex *msg) +{ + CRYPT_EAL_PkeyCtx *ctx = NULL; + CRYPT_EAL_PkeyCtx *newCtx = NULL; + CRYPT_EAL_PkeyPrv prv = {0}; + uint8_t *signdata = NULL; + uint32_t signLen; + uint32_t flag = CRYPT_RSA_BLINDING; + CRYPT_RSA_PkcsV15Para pkcsv15 = {mdId}; + + SetRsaPrvKey(&prv, n->x, n->len, d->x, d->len); + prv.key.rsaPrv.p = p->x; + prv.key.rsaPrv.pLen = p->len; + prv.key.rsaPrv.q = q->x; + prv.key.rsaPrv.qLen = q->len; + + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); // Random numbers need to be generated during blinding. + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(ctx, &prv), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsv15, PKCSV15_SIZE), CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_FLAG, (void *)&flag, sizeof(uint32_t)) == CRYPT_SUCCESS); + + /* Malloc signature buffer */ + signLen = CRYPT_EAL_PkeyGetSignLen(ctx); + signdata = (uint8_t *)calloc(1u, signLen); + ASSERT_TRUE(signdata != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySign(ctx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + + newCtx = CRYPT_EAL_PkeyDupCtx(ctx); + ASSERT_TRUE(newCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeySign(newCtx, mdId, msg->x, msg->len, signdata, &signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_PkeyFreeCtx(newCtx); + free(signdata); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_RSA_KEY_PAIR_CHECK_FUNC_TC001 + * @title RSA: key pair check. + * @precon Registering memory-related functions. + * @brief + * 1. Create two contexts(pubCtx, prvCtx) of the rsa algorithm, expected result 1 + * 2. Set public key for pubCtx, expected result 2 + * 3. Set private key for prvCtx, expected result 3 + * 4. Check whether the public key matches the private key, expected result 4 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SUCCESS + * 4. Return CRYPT_SUCCESS when expect is 1, CRYPT_RSA_NOR_VERIFY_FAIL otherwise. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_RSA_KEY_PAIR_CHECK_FUNC_TC001(Hex *n, Hex *e, Hex *d, int expect) +{ + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyPub pubKey = {0}; + CRYPT_EAL_PkeyPrv prvKey = {0}; + int expectRet = expect == 1 ? CRYPT_SUCCESS : CRYPT_RSA_NOR_VERIFY_FAIL; + + SetRsaPubKey(&pubKey, n->x, n->len, e->x, e->len); + SetRsaPrvKey(&prvKey, n->x, n->len, d->x, d->len); + + TestMemInit(); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_TRUE(pubCtx != NULL && prvCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pubCtx, &pubKey), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(prvCtx, &prvKey), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyPairCheck(pubCtx, prvCtx), expectRet); + +exit: + CRYPT_EAL_PkeyFreeCtx(pubCtx); + CRYPT_EAL_PkeyFreeCtx(prvCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.data b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.data new file mode 100644 index 00000000..5fe990f6 --- /dev/null +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.data @@ -0,0 +1,227 @@ +RSA CRYPT_EAL_PkeySign: Nist, Wrong parameters. +SDV_CRYPTO_RSA_SIGN_API_TC001:"cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d":"0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d" + +RSA EAL layer signature function test: Nist, PKCSV15, sha224 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC001:"cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d":"0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d":"74230447bcd492f2f8a8c594a04379271690bf0c8a13ddfc1b7b96413e77ab2664cba1acd7a3c57ee5276e27414f8283a6f93b73bd392bd541f07eb461a080bb667e5ff095c9319f575b3893977e658c6c001ceef88a37b7902d4db31c3e34f3c164c47bbeefde3b946bad416a752c2cafcee9e401ae08884e5b8aa839f9d0b5":"27da4104eace1991e08bd8e7cfccd97ec48b896a0e156ce7bdc23fd570aaa9a00ed015101f0c6261c7371ceca327a73c3cecfcf6b2d9ed920c9698046e25c89adb2360887d99983bf632f9e6eb0e5df60715902b9aeaa74bf5027aa246510891c74ae366a16f397e2c8ccdc8bd56aa10e0d01585e69f8c4856e76b53acfd3d782b8171529008fa5eff030f46956704a3f5d9167348f37021fc277c6c0a8f93b8a23cfbf918990f982a56d0ed2aa08161560755adc0ce2c3e2ab2929f79bfc0b24ff3e0ff352e6445d8a617f1785d66c32295bb365d61cfb107e9993bbd93421f2d344a86e4127827fa0d0b2535f9b1d547de12ba2868acdecf2cb5f92a6a159a" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA224 mod 2048 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA224:"cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d":"0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d":"74230447bcd492f2f8a8c594a04379271690bf0c8a13ddfc1b7b96413e77ab2664cba1acd7a3c57ee5276e27414f8283a6f93b73bd392bd541f07eb461a080bb667e5ff095c9319f575b3893977e658c6c001ceef88a37b7902d4db31c3e34f3c164c47bbeefde3b946bad416a752c2cafcee9e401ae08884e5b8aa839f9d0b5":"27da4104eace1991e08bd8e7cfccd97ec48b896a0e156ce7bdc23fd570aaa9a00ed015101f0c6261c7371ceca327a73c3cecfcf6b2d9ed920c9698046e25c89adb2360887d99983bf632f9e6eb0e5df60715902b9aeaa74bf5027aa246510891c74ae366a16f397e2c8ccdc8bd56aa10e0d01585e69f8c4856e76b53acfd3d782b8171529008fa5eff030f46956704a3f5d9167348f37021fc277c6c0a8f93b8a23cfbf918990f982a56d0ed2aa08161560755adc0ce2c3e2ab2929f79bfc0b24ff3e0ff352e6445d8a617f1785d66c32295bb365d61cfb107e9993bbd93421f2d344a86e4127827fa0d0b2535f9b1d547de12ba2868acdecf2cb5f92a6a159a" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA256 mod 2048 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA256:"cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d":"0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d":"5af283b1b76ab2a695d794c23b35ca7371fc779e92ebf589e304c7f923d8cf976304c19818fcd89d6f07c8d8e08bf371068bdf28ae6ee83b2e02328af8c0e2f96e528e16f852f1fc5455e4772e288a68f159ca6bdcf902b858a1f94789b3163823e2d0717ff56689eec7d0e54d93f520d96e1eb04515abc70ae90578ff38d31b":"6b8be97d9e518a2ede746ff4a7d91a84a1fc665b52f154a927650db6e7348c69f8c8881f7bcf9b1a6d3366eed30c3aed4e93c203c43f5528a45de791895747ade9c5fa5eee81427edee02082147aa311712a6ad5fb1732e93b3d6cd23ffd46a0b3caf62a8b69957cc68ae39f9993c1a779599cdda949bdaababb77f248fcfeaa44059be5459fb9b899278e929528ee130facd53372ecbc42f3e8de2998425860406440f248d817432de687112e504d734028e6c5620fa282ca07647006cf0a2ff83e19a916554cc61810c2e855305db4e5cf893a6a96767365794556ff033359084d7e38a8456e68e21155b76151314a29875feee09557161cbc654541e89e42" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA384 mod 2048 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA384:"cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d":"0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d":"6cd59fdd3efd893d091afdc3155d354f10d6d88167427a2cf7246207e51791a6ca6200a914cd2834a9b3c79fcd59e26e457e0683bc33d49267edbdd6e5d90902696f1e7b1a4affc4ba371339868c28015ebbb73e262669866c35db974ba69e468f2583b9191d15d686cd66fb0b9e0ff0a3b4721a6dc342f14f2446b4e028595b":"3974900bec3fcb081f0e5a299adf30d087aabaa633911410e87a4979bbe3fa80c3abcf221686399a49bc2f1e5ac40c35df1700e4b9cb7c805a896646573f4a570a9704d2a2e6baee4b43d916906884ad3cf283529ea265e8fcb5cc1bdf7b7dee85941e4b4fb25c1fc7b951fb129ab393cb069be271c1d954da3c43674309f1d212826fabb8e812de2d53d12597de040d32cb28c9f813159cb18c1b51f7a874cbf229cc222caeb98e35ec5e4bf5c5e22cc8528631f15117e8c2be6eac91f4070eecdd07ecc6db6c46eaa65f472f2006988efef0b51c538c6e04d7519c8e3da4b172b1e2761089ed3ad1197992ef37c168dc881c8b5f8bbfee919f7c7afd25b8fc" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA512 mod 2048 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA512:"cea80475324c1dc8347827818da58bac069d3419c614a6ea1ac6a3b510dcd72cc516954905e9fef908d45e13006adf27d467a7d83c111d1a5df15ef293771aefb920032a5bb989f8e4f5e1b05093d3f130f984c07a772a3683f4dc6fb28a96815b32123ccdd13954f19d5b8b24a103e771a34c328755c65ed64e1924ffd04d30b2142cc262f6e0048fef6dbc652f21479ea1c4b1d66d28f4d46ef7185e390cbfa2e02380582f3188bb94ebbf05d31487a09aff01fcbb4cd4bfd1f0a833b38c11813c84360bb53c7d4481031c40bad8713bb6b835cb08098ed15ba31ee4ba728a8c8e10f7294e1b4163b7aee57277bfd881a6f9d43e02c6925aa3a043fb7fb78d":"0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d":"a7c309d44a57188bbd7b726b98b98ce12582228e1415864870a23961d2afb82cd5bc98bec922d5f2ac4168b056da176ef3ba91f6b699ba6acc4144868ff37f26fd06720868d12ad26ecb52572cf10416af68df03ab645a8b704857d2190ffc3f07eabe3a8e2abe34ed6159e884c4fae141d4333d5c3e0db044ff9cccd9cbd67f":"148af61ed5ea8a87a08b3f403929bf8031db4fd3999b64409ba489f97a3ee5208ea4202d2ec18734f615003a51f77441085be6ac0f11810ffa2dad58f0e186d5520ac2b8a5d3966e8d2abb8074e13b50a4e7de83be10a66fdc7ca18118c5774f781212de9efebc6376fcdddc65a3b1b8f1ab31492fe478259ce719b3db587498d879a01dec96e8eabeb07ff7073f3f3eb446084955ca26329a791315a2c259d225e26b2154b2047b21faba68115bfd962e5e24ec52d7c5d231e3044cbcd8c8804855703cbaa622b15b6ef78c7421a367166f1b02576c87360593da75b7189efafd1082bd59f6857f1701f646c24d70c95273c49d5b11e6afe258821b55c1680c" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA224 mod 3072 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA224:"dca98304b729e819b340e26cecb730aecbd8930e334c731493b180de970e6d3bc579f86c8d5d032f8cd33c4397ee7ffd019d51b0a7dbe4f52505a1a34ae35d23cfaaf594419d509f469b1369589f9c8616a7d698513bc1d423d70070d3d72b996c23abe68b22ccc39aabd16507124042c88d4da6a7451288ec87c9244be226aac02d1817682f80cc34c6eaf37ec84d247aaedebb56c3bbcaffb5cf42f61fe1b7f3fc89748e213973bf5f679d8b8b42a47ac4afd9e51e1d1214dfe1a7e1169080bd9ad91758f6c0f9b22ae40af6b41403d8f2d96db5a088daa5ef8683f86f501f7ad3f358b6337da55c6cfc003197420c1c75abdb7be1403ea4f3e64259f5c6da3325bb87d605b6e14b5350e6e1455c9d497d81046608e38795dc85aba406c9de1f4f9990d5153b98bbabbdcbd6bb18854312b2da48b411e838f26ae3109f104dfd1619f991824ec819861e5199f26bb9b3b299bfa9ec2fd691271b58a8adecbf0ff627b54336f3df7003d70e37d11ddbd930d9aba7e88ed401acb44092fd53d5":"2d6db91eb32e36e5d5127deb034d14072fe60c1cd13c8c3dd9adbc87140b5e7136f4f89e61bbee7826f45ac1d99194fbaa8c5a0bb94db31d93723b51419d9c6f6eeb5f3610b67f4b4e2ade05cc6b8990e8832cf4cd40f2df0388c9a52072e27efebae20b4ad5951f4d20dd18943e58b786d8797652b2bb759c319d2b0046dbf69c53c075d00c287b876042fafa23fe4dd705e4e423277c9000311e94ea3f7456e32fd12afe4a2bde358a65824f1055064823c893fc93be3b8c658bb441d7f0b00ac246bf043a9c0053d319f003ef5a5533f74d630d8ce93bab416a82951e05b82c6036593eca89f0ebacd7d51ed9610af43537fcd266e5e47c0d25fedad6d047a1a1ee3eb444367e3eff7c7520ca4f779f2027fe45036204168454df4918b547a4d19e938f3c6db6ca2702ad9bbda1261c64d00b578285bdcfc9851f96a4f2cd14d66b9c1f65742a1344948c9f1da8d338ed4e3deb1ebadf11f8c281944e8849823496f86111f378bdd084c99f65fb9b4ee6271b1d1be424c294d185d9fd9cdf":"254ce36e8ed62e0887d4be00eefa82515acef956540cff45c448e7f9a9d5c9f40de61da439f389e5255ef8c83257ec921bfd150829c522eaa720d7be965860cea2bbe57454fc5e9588d6a96c22f2d989fd0bd21924501367450ad2a3627e4ee3ca15616748ba54219a84f8742495f23de6425710ac7479c4844d0031750f3c38":"9dfd3f32091b916a56f4f357a961a525a527fd29b114b3f03829df1b25c0c5973b1c51af36633116f4c77aa2f677a3b0f82368a538bdb33e49db9fa704bd5123edefbd3a86dcc39283c2a03c96c69030f04c648417f544f08a9b4e01ae4d429ef21422ddfe76834f925c5653b1227835a9a4413da7942b0a015196faec31504111c9f084d6dd6d5a6956c55412c1bd14aaf95d828e844961fdd60cc078f169f6e1186cb0cb6ba3d21168c5bfd067dc6e460784e7c6a76ee3d8b332acfa97e5d4b656ec8c611ebd896fe90e619b588d0c615492464a1b3d05d3a963f451051c65d8f81feea925bcbee9ce7a39ba3c915a18a24a451e470e761d09855a965e83edae3fca41678cc9d098ba9928b525b50e48cb030c510c4ce727c6b93bd091b7d20b4b961165ae0e2848aa995bb73abe9a2634378d224128541ab056a31b784885aef8034dedac13167402f9f62b55741220df8aff5defb69c035d9a31e2a5b8817057241bcf854932f5edee7ee66e8917aa4a718b6c446bddf084f5cd769caeff" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA256 mod 3072 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA256:"dca98304b729e819b340e26cecb730aecbd8930e334c731493b180de970e6d3bc579f86c8d5d032f8cd33c4397ee7ffd019d51b0a7dbe4f52505a1a34ae35d23cfaaf594419d509f469b1369589f9c8616a7d698513bc1d423d70070d3d72b996c23abe68b22ccc39aabd16507124042c88d4da6a7451288ec87c9244be226aac02d1817682f80cc34c6eaf37ec84d247aaedebb56c3bbcaffb5cf42f61fe1b7f3fc89748e213973bf5f679d8b8b42a47ac4afd9e51e1d1214dfe1a7e1169080bd9ad91758f6c0f9b22ae40af6b41403d8f2d96db5a088daa5ef8683f86f501f7ad3f358b6337da55c6cfc003197420c1c75abdb7be1403ea4f3e64259f5c6da3325bb87d605b6e14b5350e6e1455c9d497d81046608e38795dc85aba406c9de1f4f9990d5153b98bbabbdcbd6bb18854312b2da48b411e838f26ae3109f104dfd1619f991824ec819861e5199f26bb9b3b299bfa9ec2fd691271b58a8adecbf0ff627b54336f3df7003d70e37d11ddbd930d9aba7e88ed401acb44092fd53d5":"2d6db91eb32e36e5d5127deb034d14072fe60c1cd13c8c3dd9adbc87140b5e7136f4f89e61bbee7826f45ac1d99194fbaa8c5a0bb94db31d93723b51419d9c6f6eeb5f3610b67f4b4e2ade05cc6b8990e8832cf4cd40f2df0388c9a52072e27efebae20b4ad5951f4d20dd18943e58b786d8797652b2bb759c319d2b0046dbf69c53c075d00c287b876042fafa23fe4dd705e4e423277c9000311e94ea3f7456e32fd12afe4a2bde358a65824f1055064823c893fc93be3b8c658bb441d7f0b00ac246bf043a9c0053d319f003ef5a5533f74d630d8ce93bab416a82951e05b82c6036593eca89f0ebacd7d51ed9610af43537fcd266e5e47c0d25fedad6d047a1a1ee3eb444367e3eff7c7520ca4f779f2027fe45036204168454df4918b547a4d19e938f3c6db6ca2702ad9bbda1261c64d00b578285bdcfc9851f96a4f2cd14d66b9c1f65742a1344948c9f1da8d338ed4e3deb1ebadf11f8c281944e8849823496f86111f378bdd084c99f65fb9b4ee6271b1d1be424c294d185d9fd9cdf":"bcf6074333a7ede592ffc9ecf1c51181287e0a69363f467de4bf6b5aa5b03759c150c1c2b23b023cce8393882702b86fb0ef9ef9a1b0e1e01cef514410f0f6a05e2252fd3af4e566d4e9f79b38ef910a73edcdfaf89b4f0a429614dabab46b08da94405e937aa049ec5a7a8ded33a338bb9f1dd404a799e19ddb3a836aa39c77":"d1d21b8dfa55f0681e8fa86135cf292d71b7669713c291d8f8dc246464de3bbb961b596dfc8fda6c823c384008d05bcb3dccc36accf1b2bede1a95e52258d7d1bdf1fc44e18072abd45c1392015ee71692690ef8cdaaed337dd8546783f961bb9620eb5c7b8b6716e8c600351fab7765ee38a15d32d8a2c0949825c49a7f25eedd9be7b807bbfd517913786620d249823dae6fe2fd39ac639dd74821b0c120b42f31c2c639d2c61b395f09f86851bc809b34c4981ac65cf25b2e8adcbce190ef2ef67a0189039c9110f26701c3eed731c8d9ead178220ffcac7f0f678aa22268e1d01942ec51e80eef06e2112830855e87bafe8cc9c22fd737c7abbca5eb7a221d3835a86610d24b507b5dcb4618aa421f63a5609ef5d68f5760fddf970135602efad0851bbff98fe87fa58bc365f38ee7ec8ef5aab17fd11d89d91ef4c604e0d1f001d0e08869df9225e3b4cef52ff86815e13b3efdf45776f9353769a8a51fe7d891a7ef7035eecfa259848738376886edc91cc78f6da31c2f07ee362c3d82" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA384 mod 3072 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA384:"dca98304b729e819b340e26cecb730aecbd8930e334c731493b180de970e6d3bc579f86c8d5d032f8cd33c4397ee7ffd019d51b0a7dbe4f52505a1a34ae35d23cfaaf594419d509f469b1369589f9c8616a7d698513bc1d423d70070d3d72b996c23abe68b22ccc39aabd16507124042c88d4da6a7451288ec87c9244be226aac02d1817682f80cc34c6eaf37ec84d247aaedebb56c3bbcaffb5cf42f61fe1b7f3fc89748e213973bf5f679d8b8b42a47ac4afd9e51e1d1214dfe1a7e1169080bd9ad91758f6c0f9b22ae40af6b41403d8f2d96db5a088daa5ef8683f86f501f7ad3f358b6337da55c6cfc003197420c1c75abdb7be1403ea4f3e64259f5c6da3325bb87d605b6e14b5350e6e1455c9d497d81046608e38795dc85aba406c9de1f4f9990d5153b98bbabbdcbd6bb18854312b2da48b411e838f26ae3109f104dfd1619f991824ec819861e5199f26bb9b3b299bfa9ec2fd691271b58a8adecbf0ff627b54336f3df7003d70e37d11ddbd930d9aba7e88ed401acb44092fd53d5":"2d6db91eb32e36e5d5127deb034d14072fe60c1cd13c8c3dd9adbc87140b5e7136f4f89e61bbee7826f45ac1d99194fbaa8c5a0bb94db31d93723b51419d9c6f6eeb5f3610b67f4b4e2ade05cc6b8990e8832cf4cd40f2df0388c9a52072e27efebae20b4ad5951f4d20dd18943e58b786d8797652b2bb759c319d2b0046dbf69c53c075d00c287b876042fafa23fe4dd705e4e423277c9000311e94ea3f7456e32fd12afe4a2bde358a65824f1055064823c893fc93be3b8c658bb441d7f0b00ac246bf043a9c0053d319f003ef5a5533f74d630d8ce93bab416a82951e05b82c6036593eca89f0ebacd7d51ed9610af43537fcd266e5e47c0d25fedad6d047a1a1ee3eb444367e3eff7c7520ca4f779f2027fe45036204168454df4918b547a4d19e938f3c6db6ca2702ad9bbda1261c64d00b578285bdcfc9851f96a4f2cd14d66b9c1f65742a1344948c9f1da8d338ed4e3deb1ebadf11f8c281944e8849823496f86111f378bdd084c99f65fb9b4ee6271b1d1be424c294d185d9fd9cdf":"bb294b95d913005b110987cde45887484ae6df794873dfc5c41fb7e8992c2fdce70699fcac8004699961b3ad1e1fce9ec8ea5685ccec5e80e4d0792559816f68613434bfaca81a843aac459a6fe35f5369c48e9191e4a32c70789594c5152db8d4bb02260012a8739cf325ddff2aa42fd67b6ee5bfe31591131ff27d0273d292":"32637c60798b450bff100bff12838357deff281d5b31e4f4c2cfc96eb779ce6d31b1ce8bd7aa7fa88ddc4279c8c3280604b018ccf452004a1488ed4750181c5025636511ac6724fe51761c27d7cf9a0c8782ea2231268853c4b1f7acb0005e5687c8f3df16c962f02ce56b23d387a2baadc8bec94229c3557526e61707a8b59293a976e32c7fa133285088f3ce3e677788aaa947e7622c757e844b117592be99fe45376f8b3013e8772ec92c5bb0b9fa301b95544599690ad93668d83b2daa7df05c66214e275014780a912d8b1932d7a655058e743f50b074b1d9691ca23a2f95f6affbd516d64ccb2aa43c236eb95d36d272545e3beb8ff5aacd95b30f7f1d6418af042cd9a0cf0189846262322a18875ae4c3e68e4e8ffaa0276cdd99a0047c86c0f71d2deefd50642d29c195e6d14fb46fbac33a508c1f03a232de08aae09faf1da8ed2ba2ae84bcca88b78dccbde9afde08a3beb322dc79356b29c84841698914b050beb75a7b2f6701aa8101a5a4955ee27bafe81b21d03b43e3c77398" + +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002: Nist, SIGN PKCS15 SHA512 mod 3072 +SDV_CRYPTO_RSA_SIGN_PKCSV15_FUNC_TC002:CRYPT_MD_SHA512:"dca98304b729e819b340e26cecb730aecbd8930e334c731493b180de970e6d3bc579f86c8d5d032f8cd33c4397ee7ffd019d51b0a7dbe4f52505a1a34ae35d23cfaaf594419d509f469b1369589f9c8616a7d698513bc1d423d70070d3d72b996c23abe68b22ccc39aabd16507124042c88d4da6a7451288ec87c9244be226aac02d1817682f80cc34c6eaf37ec84d247aaedebb56c3bbcaffb5cf42f61fe1b7f3fc89748e213973bf5f679d8b8b42a47ac4afd9e51e1d1214dfe1a7e1169080bd9ad91758f6c0f9b22ae40af6b41403d8f2d96db5a088daa5ef8683f86f501f7ad3f358b6337da55c6cfc003197420c1c75abdb7be1403ea4f3e64259f5c6da3325bb87d605b6e14b5350e6e1455c9d497d81046608e38795dc85aba406c9de1f4f9990d5153b98bbabbdcbd6bb18854312b2da48b411e838f26ae3109f104dfd1619f991824ec819861e5199f26bb9b3b299bfa9ec2fd691271b58a8adecbf0ff627b54336f3df7003d70e37d11ddbd930d9aba7e88ed401acb44092fd53d5":"2d6db91eb32e36e5d5127deb034d14072fe60c1cd13c8c3dd9adbc87140b5e7136f4f89e61bbee7826f45ac1d99194fbaa8c5a0bb94db31d93723b51419d9c6f6eeb5f3610b67f4b4e2ade05cc6b8990e8832cf4cd40f2df0388c9a52072e27efebae20b4ad5951f4d20dd18943e58b786d8797652b2bb759c319d2b0046dbf69c53c075d00c287b876042fafa23fe4dd705e4e423277c9000311e94ea3f7456e32fd12afe4a2bde358a65824f1055064823c893fc93be3b8c658bb441d7f0b00ac246bf043a9c0053d319f003ef5a5533f74d630d8ce93bab416a82951e05b82c6036593eca89f0ebacd7d51ed9610af43537fcd266e5e47c0d25fedad6d047a1a1ee3eb444367e3eff7c7520ca4f779f2027fe45036204168454df4918b547a4d19e938f3c6db6ca2702ad9bbda1261c64d00b578285bdcfc9851f96a4f2cd14d66b9c1f65742a1344948c9f1da8d338ed4e3deb1ebadf11f8c281944e8849823496f86111f378bdd084c99f65fb9b4ee6271b1d1be424c294d185d9fd9cdf":"db6c9d4badb1d9b74d68346448b4d5340631783b5a35ac2458563ed0672cf54197587fb734c4ac189b2dda954cdfb18b41c010a77e90464eea6f863c5da0956bfa8cc636bf0a28be5addfe8d3e7e6f79f71d7fcbbae23ea141783f91d6cc4c8fad125811760ab57133818892471a79c6d04eafef37b2fbe506785318f9398377":"d480d5a979ad1a0c4ca329ebd88a4aa6948a8cf66a3c0bfee2254409c53054d6fff59f72a46f02c668146a144f8f2ba7c4e6b4de31400eba00ae3ee87589dcb6ea139e70f7704f691bc37d722f62bb3b2cd303a34d92fde4deb54a64dd39184382d59ccaf0c07a7ea4107d0808260ed8d421cb8b1407cdf9e915159282b9f7bffdbf40d877885da7399edebd300a7e77a908f756659a1824f95c8a812aa540ebaa64ab54a233723db55caa8b4466ea9ae6614ad1bb869e9d8e0d032f3901671e94c0b673be6537cd54278ed3da2e1edbc04ee3a9e8070d73ba0ffb93e60f30b87ff3862e9c53908f2c8e99915668c1f46635e05bf7163051ff9d92bc71a626553c69dfdd06a49f7ff1ed51e918f3ed801dae62ca276d7063d72a6ebc136ba06cfedf5aa23277e81008c63b2e0083d0fd6814f6d4b4b40a42e8c0206f3c356a5ec709b7c8a4b74b7b48d53c9d8694d27359c2c7701938d2f0161721a57313bb1a2e11da215872498182493d8517043b4c03f93446aac93830276542026ce83055" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA224 mod=2048 saltLen=15 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA224:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"37ddd9901478ae5c16878702cea4a19e786d35582de44ae65a16cd5370fbe3ffdd9e7ee83c7d2f27c8333bbe1754f090059939b1ee3d71e020a675528f48fdb2cbc72c65305b65125c796162e7b07e044ed15af52f52a1febcf4237e6aa42a69e99f0a9159daf924bba12176a57ef4013a5cc0ab5aec83471648005d67d7122e":"7e628bcbe6ff83a937b8961197d8bdbb322818aa8bdf30cdfb67ca6bf025ef6f09a99dba4c3ee2807d0b7c77776cfeff33b68d7e3fa859c4688626b2441897d26e5d6b559dd72a596e7dad7def9278419db375f7c67cee0740394502212ebdd4a6c8d3af6ee2fd696d8523de6908492b7cbf2254f15a348956c19840dc15a3d732ef862b62ede022290de3af11ca5e79a3392fff06f75aca8c88a2de1858b35a216d8f73fd70e9d67958ed39a6f8976fb94ec6e61f238a52f9d42241e8354f89e3ece94d6fa5bfbba1eeb70e1698bff31a685fbe799fb44efe21338ed6eea2129155aabc0943bc9f69a8e58897db6a8abcc2879d5d0c5d3e6dc5eb48cf16dac8":"463729b3eaf43502d9cff129925681" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA256 mod=2048 saltLen=20 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA256:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"dfc22604b95d15328059745c6c98eb9dfb347cf9f170aff19deeec555f22285a6706c4ecbf0fb1458c60d9bf913fbae6f4c554d245d946b4bc5f34aec2ac6be8b33dc8e0e3a9d601dfd53678f5674443f67df78a3a9e0933e5f158b169ac8d1c4cd0fb872c14ca8e001e542ea0f9cfda88c42dcad8a74097a00c22055b0bd41f":"8b46f2c889d819f860af0a6c4c889e4d1436c6ca174464d22ae11b9ccc265d743c67e569accbc5a80d4dd5f1bf4039e23de52aece40291c75f8936c58c9a2f77a780bbe7ad31eb76742f7b2b8b14ca1a7196af7e673a3cfc237d50f615b75cf4a7ea78a948bedaf9242494b41e1db51f437f15fd2551bb5d24eefb1c3e60f03694d0033a1e0a9b9f5e4ab97d457dff9b9da516dc226d6d6529500308ed74a2e6d9f3c10595788a52a1bc0664aedf33efc8badd037eb7b880772bdb04a6046e9edeee4197c25507fb0f11ab1c9f63f53c8820ea8405cfd7721692475b4d72355fa9a3804f29e6b6a7b059c4441d54b28e4eed2529c6103b5432c71332ce742bcc":"e1256fc1eeef81773fdd54657e4007fde6bcb9b1" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA384 mod=2048 saltLen=25 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA384:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"833aa2b1dcc77607a44e804ee77d45408586c536861f6648adcd2fb65063368767c55c6fe2f237f6404250d75dec8fa68bcaf3b6e561863ae01c91aa23d80c6999a558a4c4cb317d540cde69f829aad674a89812f4d353689f04648c7020a73941620018295a4ae4083590cc603e801867a51c105a7fb319130f1022de44f13e":"2ca37a3d6abd28c1eaf9bde5e7ac17f1fa799ce1b4b899d19985c2ff7c8ba959fe54e5afb8bc4021a1f1c687eebb8cba800d1c51636b1f68dc3e48f63e2da6bc6d09c6668f68e508c5d8c19bef154759e2f89ade152717370a8944f537578296380d1fe6be809e8b113d2b9d89e6a46f5c333d4fd48770fc1ea1c548104575b84cf071042bfe5acf496392be8351a41c46a2cab0864c4c1c5b5e0c7b27e7b88c69f37ffa7e1a8cd98f343ac84a4ad67025a40ed8f664e9d630337de6e48bb2125e2552123609491f183afd92634487f0b2cf971f2626e88858879d45a29b0fefb66cd41b2e4e968385bd9fc8c7211976bc6bd3e1ad6df60856985a825f4726d2":"b750587671afd76886e8ffb7865e78f706641b2e4251b48706" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA512 mod=2048 saltLen=30 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA512:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"5f0fe2afa61b628c43ea3b6ba60567b1ae95f682076f01dfb64de011f25e9c4b3602a78b94cecbc14cd761339d2dc320dba504a3c2dcdedb0a78eb493bb11879c31158e5467795163562ec0ca26c19e0531530a815c28f9b52061076e61f831e2fc45b86631ea7d3271444be5dcb513a3d6de457a72afb67b77db65f9bb1c380":"5e0712bb363e5034ef6b23c119e3b498644445faab5a4c0b4e217e4c832ab34c142d7f81dbf8affdb2dacefabb2f83524c5aa883fc5f06e528b232d90fbea9ca08ae5ac180d477eaed27d137e2b51bd613b69c543d555bfc7cd81a4f795753c8c64c6b5d2acd9e26d6225f5b26e4e66a945fd6477a277b580dbeaa46d0be498df9a093392926c905641945ec5b9597525e449af3743f80554788fc358bc0401a968ff98aaf34e50b352751f32274750ff5c1fba503050204cec9c77deede7f8fa20845d95f5177030bc91d51f26f29d2a65b870dc72b81e5ef9eeef990d7c7145bbf1a3bc7aedd19fa7cbb020756525f1802216c13296fd6aac11bf2d2d90494":"aa10fec3f83b7a97e092877a5bf9081283f502a0a46b50e395ab983a49ac" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA224 mod=3072 saltLen=28 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA224:"a7a1882a7fb896786034d07fb1b9f6327c27bdd7ce6fe39c285ae3b6c34259adc0dc4f7b9c7dec3ca4a20d3407339eedd7a12a421da18f5954673cac2ff059156ecc73c6861ec761e6a0f2a5a033a6768c6a42d8b459e1b4932349e84efd92df59b45935f3d0e30817c66201aa99d07ae36c5d74f408d69cc08f044151ff4960e531360cb19077833adf7bce77ecfaa133c0ccc63c93b856814569e0b9884ee554061b9a20ab46c38263c094dae791aa61a17f8d16f0e85b7e5ce3b067ece89e20bc4e8f1ae814b276d234e04f4e766f501da74ea7e3817c24ea35d016676cece652b823b051625573ca92757fc720d254ecf1dcbbfd21d98307561ecaab545480c7c52ad7e9fa6b597f5fe550559c2fe923205ac1761a99737ca02d7b19822e008a8969349c87fb874c81620e38f613c8521f0381fe5ba55b74827dad3e1cf2aa29c6933629f2b286ad11be88fa6436e7e3f64a75e3595290dc0d1cd5eee7aaac54959cc53bd5a934a365e72dd81a2bd4fb9a67821bffedf2ef2bd94913de8b":"073a5fc4cd642f6113dffc4f84035cee3a2b8acc549703751a1d6a5eaa13487229a58ef7d7a522bb9f4f25510f1aa0f74c6a8fc8a5c5be8b91a674ede50e92f7e34a90a3c9da999fffb1d695e4588f451256c163484c151350cb9c7825a7d910845ee5cf826fecf9a7c0fbbbba22bb4a531c131d2e7761ba898f002ebef8ab87218511f81d3266e1ec07a7ca8622514c6dfdc86c67679a2c8f5f031de9a0c22b5a88060b46ee0c64d3b9af3c0a379bcd9c6a1b51cf6480456d3fd6def94cd2a6c171dd3f010e3c9d662bc857208248c94ebcb9fd997b9ff4a7e5fd95558569906525e741d78344f6f6cfdbd59d4faa52ee3fa964fb7cccb2d6be1935d211fe1498217716273939a946081fd8509913fd47747c5c2f03efd4d6fc9c6fcfd8402e9f40a0a5b3de3ca2b3c0fac9456938faa6cf2c20e3912e5981c9876d8ca1ff29b87a15eeae0ccce3f8a8f1e405091c083b98bcc5fe0d0deaae33c67c0394437f0eccb385b7efb17aeebba8afaecca30a2f63eac8f0ac8f1eacad85bbcaf3960b":"c8ed14895c80a91fda8367cf4aee386b8a378645f06afee72f7c94047fddc7aef84c26c83fef13bf65a3c7750c91967ecc02748fd574b933d5ec21c01c8f178afe6c3356789d0112178e04c3169cfabec6e2621b334f3c6705fc1099a4bd3147a0f7431a4fb1fb80b8ed26a0af38ed93428057d154260fe98854687661919e4e":"27b4f0aa139565fbd7860760610f6866d5b5f0d777921f06f5053291123e3b259d67294ccb8c0d068b8dae360aad2cf7d07296b539e4d2e9b08c343286d522f7dd63c6620e8672be492f3b039f73d88ab9d22a5463cd1f07d688e8ba3fbad531b0c3870ccbfebb596ce4ec643d309744bdbd675d5841284cbac902cfb70ade6d33946d8dc6109bbbc42412db25b8c62222c5ff94f8eb868982265392a44e807474910b4b39558bbef33197907178ce146fdd7e94092ad58bf41a474e626136789fc2fe6374a1b5fefddd5fecb7f8ca5893220d1ab9e822c3ae8adda1ebaddb18a6a12bfc165d12071441a991377cee6dc8e50839497346fee13f12c5b7b6d024b8ecfdad80d5ef6e9e4996ac21c4eb6036bb51f5be5e38f265181154000824e3c1f231d18589ccdaee90fe307ba56324318b5358468e9f3913b83ab8b34d949629ed7839f8da85bdcda52f3da5a419f777b3860dbf2ffe28d96244312549528a20cc7399fc010844365806167fe43235521c909587c2c7b8db4e296dad2aefa2":"3f805057471aab0a28cfc8430dabcf990612e8a908b158ae36b4ed53" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA256 mod=3072 saltLen=32 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA256:"a7a1882a7fb896786034d07fb1b9f6327c27bdd7ce6fe39c285ae3b6c34259adc0dc4f7b9c7dec3ca4a20d3407339eedd7a12a421da18f5954673cac2ff059156ecc73c6861ec761e6a0f2a5a033a6768c6a42d8b459e1b4932349e84efd92df59b45935f3d0e30817c66201aa99d07ae36c5d74f408d69cc08f044151ff4960e531360cb19077833adf7bce77ecfaa133c0ccc63c93b856814569e0b9884ee554061b9a20ab46c38263c094dae791aa61a17f8d16f0e85b7e5ce3b067ece89e20bc4e8f1ae814b276d234e04f4e766f501da74ea7e3817c24ea35d016676cece652b823b051625573ca92757fc720d254ecf1dcbbfd21d98307561ecaab545480c7c52ad7e9fa6b597f5fe550559c2fe923205ac1761a99737ca02d7b19822e008a8969349c87fb874c81620e38f613c8521f0381fe5ba55b74827dad3e1cf2aa29c6933629f2b286ad11be88fa6436e7e3f64a75e3595290dc0d1cd5eee7aaac54959cc53bd5a934a365e72dd81a2bd4fb9a67821bffedf2ef2bd94913de8b":"073a5fc4cd642f6113dffc4f84035cee3a2b8acc549703751a1d6a5eaa13487229a58ef7d7a522bb9f4f25510f1aa0f74c6a8fc8a5c5be8b91a674ede50e92f7e34a90a3c9da999fffb1d695e4588f451256c163484c151350cb9c7825a7d910845ee5cf826fecf9a7c0fbbbba22bb4a531c131d2e7761ba898f002ebef8ab87218511f81d3266e1ec07a7ca8622514c6dfdc86c67679a2c8f5f031de9a0c22b5a88060b46ee0c64d3b9af3c0a379bcd9c6a1b51cf6480456d3fd6def94cd2a6c171dd3f010e3c9d662bc857208248c94ebcb9fd997b9ff4a7e5fd95558569906525e741d78344f6f6cfdbd59d4faa52ee3fa964fb7cccb2d6be1935d211fe1498217716273939a946081fd8509913fd47747c5c2f03efd4d6fc9c6fcfd8402e9f40a0a5b3de3ca2b3c0fac9456938faa6cf2c20e3912e5981c9876d8ca1ff29b87a15eeae0ccce3f8a8f1e405091c083b98bcc5fe0d0deaae33c67c0394437f0eccb385b7efb17aeebba8afaecca30a2f63eac8f0ac8f1eacad85bbcaf3960b":"c16499110ed577202aed2d3e4d51ded6c66373faef6533a860e1934c63484f87a8d9b92f3ac45197b2909710abba1daf759fe0510e9bd8dd4d73cec961f06ee07acd9d42c6d40dac9f430ef90374a7e944bde5220096737454f96b614d0f6cdd9f08ed529a4ad0e759cf3a023dc8a30b9a872974af9b2af6dc3d111d0feb7006":"4335707da735cfd10411c9c048ca9b60bb46e2fe361e51fbe336f9508dc945afe075503d24f836610f2178996b52c411693052d5d7aed97654a40074ed20ed6689c0501b7fbac21dc46b665ac079760086414406cd66f8537d1ebf0dce4cf0c98d4c30c71da359e9cd401ff49718fdd4d0f99efe70ad8dd8ba1304cefb88f24b0eedf70116da15932c76f0069551a245b5fc3b91ec101f1d63b9853b598c6fa1c1acdbacf9626356c760119be0955644301896d9d0d3ea5e6443cb72ca29f4d45246d16d74d00568c219182feb191179e4593dc152c608fd80536329a533b3a631566814cd654f587c2d8ce696085e6ed1b0b0278e60a049ec7a399f94fccae6462371a69695ef525e00936fa7d9781f9ee289d4105ee827a27996583033cedb2f297e7b4926d906ce0d09d84128406ab33d7da0f8a1d4d2f666568686c394d139b0e5e99337758de85910a5fa25ca2aa6d8fb1c777244e7d98de4c79bbd426a5e6f657e37477e01247432f83797fbf31b50d02b83f69ded26d4945b2bc3f86e":"3e07ade72a3f52530f53135a5d7d93217435ba001ea55a8f5d5d1304684874bc" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA384 mod=3072 saltLen=48 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA384:"a7a1882a7fb896786034d07fb1b9f6327c27bdd7ce6fe39c285ae3b6c34259adc0dc4f7b9c7dec3ca4a20d3407339eedd7a12a421da18f5954673cac2ff059156ecc73c6861ec761e6a0f2a5a033a6768c6a42d8b459e1b4932349e84efd92df59b45935f3d0e30817c66201aa99d07ae36c5d74f408d69cc08f044151ff4960e531360cb19077833adf7bce77ecfaa133c0ccc63c93b856814569e0b9884ee554061b9a20ab46c38263c094dae791aa61a17f8d16f0e85b7e5ce3b067ece89e20bc4e8f1ae814b276d234e04f4e766f501da74ea7e3817c24ea35d016676cece652b823b051625573ca92757fc720d254ecf1dcbbfd21d98307561ecaab545480c7c52ad7e9fa6b597f5fe550559c2fe923205ac1761a99737ca02d7b19822e008a8969349c87fb874c81620e38f613c8521f0381fe5ba55b74827dad3e1cf2aa29c6933629f2b286ad11be88fa6436e7e3f64a75e3595290dc0d1cd5eee7aaac54959cc53bd5a934a365e72dd81a2bd4fb9a67821bffedf2ef2bd94913de8b":"073a5fc4cd642f6113dffc4f84035cee3a2b8acc549703751a1d6a5eaa13487229a58ef7d7a522bb9f4f25510f1aa0f74c6a8fc8a5c5be8b91a674ede50e92f7e34a90a3c9da999fffb1d695e4588f451256c163484c151350cb9c7825a7d910845ee5cf826fecf9a7c0fbbbba22bb4a531c131d2e7761ba898f002ebef8ab87218511f81d3266e1ec07a7ca8622514c6dfdc86c67679a2c8f5f031de9a0c22b5a88060b46ee0c64d3b9af3c0a379bcd9c6a1b51cf6480456d3fd6def94cd2a6c171dd3f010e3c9d662bc857208248c94ebcb9fd997b9ff4a7e5fd95558569906525e741d78344f6f6cfdbd59d4faa52ee3fa964fb7cccb2d6be1935d211fe1498217716273939a946081fd8509913fd47747c5c2f03efd4d6fc9c6fcfd8402e9f40a0a5b3de3ca2b3c0fac9456938faa6cf2c20e3912e5981c9876d8ca1ff29b87a15eeae0ccce3f8a8f1e405091c083b98bcc5fe0d0deaae33c67c0394437f0eccb385b7efb17aeebba8afaecca30a2f63eac8f0ac8f1eacad85bbcaf3960b":"9221f0fe9115843554d5685d9fe69dc49e95ceb5793986e428b8a10b894c01d6af8782fd7d952faf74c2b637ca3b19dabc19a7fe259b2b924eb363a908c5b368f8ab1b2333fc67c30b8ea56b2839dc5bdadefb14ada810bc3e92bac54e2ae1ca1594a4b9d8d19337be421f40e0674e0e9fedb43d3ae89e2ca05d90a68203f2c2":"9687115be478e4b642cd369392b9dd0f3576e704af7218b1f94d7f8fe7f07073e3e8e1186fa768977d6b514e513459f2373df6ec52e3de9bd83fcc5cc3e6b97f8b3fb534163c64f5267620700e9d8c52b3df61a7c3748ef159d6b390895afa3af59109a5478d016d96c49f68dfc735ba2aafd5012c13515ed6644f0d4109c45556e14a3821e1aa24beb8a81a48da27f131de84f7ba51581d81b8ff31ba92b8a1fde867f07e32e6c2709253448174dd31324dbc32b05f07587f76a9997decb80f38d8c13d0f6eb3c10e3d96a2293f7464f1e04602ef6e84c2d0245d7db256a67d132a47cae9abe06b61a8968f50a1749995dc15ef0dcb1d5f5959e4d454c8547bbb4d195698f484617bfd122acaae2d0e8c76d28b24005ab03caa781ea97b1c4d9396a16f7998eee7ddd9de4cabe57032d9438a5d99c6b34a956122350263c7e998bc61dec91381012e686d079e39e96b1ea4bfdb7cdf630ddb422c6b580e5506c9cc3d6c100f2041d17ceaaaa54589249f04a1370ffa3bf3ff1adeb890688698":"61a762f8968d5f367e2dbcacb4021653dc75437d9000e3169d943729703837a5cbf4de62bdedc95fd0d1004e84751452" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001: Nist, SIGN PSS SHA512 mod=3072 saltLen=62 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC001:CRYPT_MD_SHA512:"a7a1882a7fb896786034d07fb1b9f6327c27bdd7ce6fe39c285ae3b6c34259adc0dc4f7b9c7dec3ca4a20d3407339eedd7a12a421da18f5954673cac2ff059156ecc73c6861ec761e6a0f2a5a033a6768c6a42d8b459e1b4932349e84efd92df59b45935f3d0e30817c66201aa99d07ae36c5d74f408d69cc08f044151ff4960e531360cb19077833adf7bce77ecfaa133c0ccc63c93b856814569e0b9884ee554061b9a20ab46c38263c094dae791aa61a17f8d16f0e85b7e5ce3b067ece89e20bc4e8f1ae814b276d234e04f4e766f501da74ea7e3817c24ea35d016676cece652b823b051625573ca92757fc720d254ecf1dcbbfd21d98307561ecaab545480c7c52ad7e9fa6b597f5fe550559c2fe923205ac1761a99737ca02d7b19822e008a8969349c87fb874c81620e38f613c8521f0381fe5ba55b74827dad3e1cf2aa29c6933629f2b286ad11be88fa6436e7e3f64a75e3595290dc0d1cd5eee7aaac54959cc53bd5a934a365e72dd81a2bd4fb9a67821bffedf2ef2bd94913de8b":"073a5fc4cd642f6113dffc4f84035cee3a2b8acc549703751a1d6a5eaa13487229a58ef7d7a522bb9f4f25510f1aa0f74c6a8fc8a5c5be8b91a674ede50e92f7e34a90a3c9da999fffb1d695e4588f451256c163484c151350cb9c7825a7d910845ee5cf826fecf9a7c0fbbbba22bb4a531c131d2e7761ba898f002ebef8ab87218511f81d3266e1ec07a7ca8622514c6dfdc86c67679a2c8f5f031de9a0c22b5a88060b46ee0c64d3b9af3c0a379bcd9c6a1b51cf6480456d3fd6def94cd2a6c171dd3f010e3c9d662bc857208248c94ebcb9fd997b9ff4a7e5fd95558569906525e741d78344f6f6cfdbd59d4faa52ee3fa964fb7cccb2d6be1935d211fe1498217716273939a946081fd8509913fd47747c5c2f03efd4d6fc9c6fcfd8402e9f40a0a5b3de3ca2b3c0fac9456938faa6cf2c20e3912e5981c9876d8ca1ff29b87a15eeae0ccce3f8a8f1e405091c083b98bcc5fe0d0deaae33c67c0394437f0eccb385b7efb17aeebba8afaecca30a2f63eac8f0ac8f1eacad85bbcaf3960b":"44240ce519f00239bd66ba03c84d3160b1ce39e3932866e531a62b1c37cf4170c3dc4809236fb1ade181db49fc9c7ccd794b433d1ad0bc056e14738e0ae45c0e155972a40a989fa4b9bcdc308f11990818835fa2c256b47ee4173fb4fed22ccf4385d2dd54d593c74f0004df08134eb8965dd53a122317f59b95d6b69d017958":"8f47abc2326e22cf62404508b442e81ad45afff7274096b9a13e478cdd0a72f99a76bf517f1bb0f872a523d8c588d4402569e948fd6a108ae1a45c65830828a10e94d432765314ba82ead310fc87ac99a5b39f30ab8820bf69e6934a9c1c915c19f36ea7717eaff7af67b4991315b1873ba929bedf18a975be808e7aa14a6726126c79cc93f69541c5cefdeb5b67ec279d8f5a446583e4b4faed1685140ee4b3b757c8ff4a1ef9cd76a88e05319ee62003d2d77290c94c579b0ca2ab0deb3176ef10a3fdb85c80ffbc9e2a665a23744fc836f9a9a103cd9fb756952356a2f1acdd68a645e20179006558b5d4d0b9b0bd3adf5e290f49dae60b9d19920953ea8bb237d5b3dcfe149a60f12a4ee3a889b33bcd3a3b753d610757cbcd093dd5a734255333689695ab636963e3d215a8e77ff31973718a4944a1e9e44f45754d39f6fa431c53f9a2ef36e16a5f70636eb5fba54e15c20a714f2809a7cff4b8dc1165f836607eb5a5a3bb0c4567eee26941fef46fb41e73b565c0cf8c72e404221264":"2d0c49b20789f39502eefd092a2b6a9b2757c1456147569a685fca4492a8d5b0e6234308385d3d629644ca37e3399616c266f199b6521a9987b2be9ee783" + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002: Nist, SIGN PSS saltLen=-1 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002:CRYPT_MD_SHA256:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"37ddd9901478ae5c16878702cea4a19e786d35582de44ae65a16cd5370fbe3ffdd9e7ee83c7d2f27c8333bbe1754f090059939b1ee3d71e020a675528f48fdb2cbc72c65305b65125c796162e7b07e044ed15af52f52a1febcf4237e6aa42a69e99f0a9159daf924bba12176a57ef4013a5cc0ab5aec83471648005d67d7122e":-1 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002: Nist, SIGN PSS saltLen=-2 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002:CRYPT_MD_SHA256:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"dfc22604b95d15328059745c6c98eb9dfb347cf9f170aff19deeec555f22285a6706c4ecbf0fb1458c60d9bf913fbae6f4c554d245d946b4bc5f34aec2ac6be8b33dc8e0e3a9d601dfd53678f5674443f67df78a3a9e0933e5f158b169ac8d1c4cd0fb872c14ca8e001e542ea0f9cfda88c42dcad8a74097a00c22055b0bd41f":-2 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002: Nist, SIGN PSS saltLen=0 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002:CRYPT_MD_SHA256:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"833aa2b1dcc77607a44e804ee77d45408586c536861f6648adcd2fb65063368767c55c6fe2f237f6404250d75dec8fa68bcaf3b6e561863ae01c91aa23d80c6999a558a4c4cb317d540cde69f829aad674a89812f4d353689f04648c7020a73941620018295a4ae4083590cc603e801867a51c105a7fb319130f1022de44f13e":0 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002: Nist, SIGN PSS SALT=00 +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002:CRYPT_MD_SHA256:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"00":-2 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002: Nist, SIGN PSS SALT=FF +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC002:CRYPT_MD_SHA256:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"FFFFFFFFFF":-2 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003: Nist, PSS saltLen = 0 SUCC +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"37ddd9901478ae5c16878702cea4a19e786d35582de44ae65a16cd5370fbe3ffdd9e7ee83c7d2f27c8333bbe1754f090059939b1ee3d71e020a675528f48fdb2cbc72c65305b65125c796162e7b07e044ed15af52f52a1febcf4237e6aa42a69e99f0a9159daf924bba12176a57ef4013a5cc0ab5aec83471648005d67d7122e":0 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003: Nist, PSS saltLen = -1 SUCC +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"37ddd9901478ae5c16878702cea4a19e786d35582de44ae65a16cd5370fbe3ffdd9e7ee83c7d2f27c8333bbe1754f090059939b1ee3d71e020a675528f48fdb2cbc72c65305b65125c796162e7b07e044ed15af52f52a1febcf4237e6aa42a69e99f0a9159daf924bba12176a57ef4013a5cc0ab5aec83471648005d67d7122e":-1 + +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003: Nist, PSS saltLen = -2 SUCC +SDV_CRYPTO_RSA_SIGN_PSS_FUNC_TC003:"c5062b58d8539c765e1e5dbaf14cf75dd56c2e13105fecfd1a930bbb5948ff328f126abe779359ca59bca752c308d281573bc6178b6c0fef7dc445e4f826430437b9f9d790581de5749c2cb9cb26d42b2fee15b6b26f09c99670336423b86bc5bec71113157be2d944d7ff3eebffb28413143ea36755db0ae62ff5b724eecb3d316b6bac67e89cacd8171937e2ab19bd353a89acea8c36f81c89a620d5fd2effea896601c7f9daca7f033f635a3a943331d1b1b4f5288790b53af352f1121ca1bef205f40dc012c412b40bdd27585b946466d75f7ee0a7f9d549b4bece6f43ac3ee65fe7fd37123359d9f1a850ad450aaf5c94eb11dea3fc0fc6e9856b1805ef":"49e5786bb4d332f94586327bde088875379b75d128488f08e574ab4715302a87eea52d4c4a23d8b97af7944804337c5f55e16ba9ffafc0c9fd9b88eca443f39b7967170ddb8ce7ddb93c6087c8066c4a95538a441b9dc80dc9f7810054fd1e5c9d0250c978bb2d748abe1e9465d71a8165d3126dce5db2adacc003e9062ba37a54b63e5f49a4eafebd7e4bf5b0a796c2b3a950fa09c798d3fa3e86c4b62c33ba9365eda054e5fe74a41f21b595026acf1093c90a8c71722f91af1ed29a41a2449a320fc7ba3120e3e8c3e4240c04925cc698ecd66c7c906bdf240adad972b4dff4869d400b5d13e33eeba38e075e872b0ed3e91cc9c283867a4ffc3901d2069f":"37ddd9901478ae5c16878702cea4a19e786d35582de44ae65a16cd5370fbe3ffdd9e7ee83c7d2f27c8333bbe1754f090059939b1ee3d71e020a675528f48fdb2cbc72c65305b65125c796162e7b07e044ed15af52f52a1febcf4237e6aa42a69e99f0a9159daf924bba12176a57ef4013a5cc0ab5aec83471648005d67d7122e":-2 + +CRYPT_EAL_PKEY_Gen Sign Verify 1024 +SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC001:1024 + +CRYPT_EAL_PKEY_Gen Sign Verify 2048 +SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC001:2048 + +CRYPT_EAL_PKEY_Gen Sign Verify 1025 +SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC001:1025 + +CRYPT_EAL_PKEY_Gen Sign Verify PSS 1025 +SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PSS_FUNC_TC001:1025 + +CRYPT_EAL_PKEY_Gen, GetPub, SetPub, Sign, Verify +SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC002: + +CRYPT_EAL_PKEY_Gen, GetPrv, SetPrv, Sign, Verify +SDV_CRYPTO_RSA_GEN_SIGN_VERIFY_PKCSV15_FUNC_TC003: + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 1024] SHA224 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA224:"b8f34bda3e0cc0de41396ac4dab60770461c65d1370fd815adcb8712d737f16478e4f97c4d6626865a4e3e4095b803bc8b3023426c8a72557d5ce779664d76913eda01e5597a17907c5b4d2b1b70181d722994181c81ac9ca5c5450240c0c4e275586a9b6dec645953aa78a3fc290d359a2a6bbe6097fa14b23db3e9c0865cf7":"df05dd":"ef28fdf1f0d14499c142864e68391d591ce212ea579dd5022e023190de227edba710191fdda1117b3c6f230a7c24e95125f54ed9a56c451c9f6bbba6876ec9746c102fa014d1fe404e16948b8471cd3d9023783dd0df087d7dd18c2238dfe2e6e62f27babee971afa03ec116a9a933e60474785f037f86ed6e3d8e4f1bff2ff8":"3c8e1baef55289f6f2269fc9602eef96b551b21aaeda42fd7e3d17e36874f18a8f29cd05238159a5ccb8a53cbd2b792d5e614b569ed60b21e3218f5d995e685faea3aee813b0e57edc1419081b779b3d7206c77c329d400b0cc09cd88504e6cf61fee33d7c14cb4100ef5b3a7537dd67a7b16a6b2fda95f0228fae06e484d3c2":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 1024] SHA224 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA224:"b8f34bda3e0cc0de41396ac4dab60770461c65d1370fd815adcb8712d737f16478e4f97c4d6626865a4e3e4095b803bc8b3023426c8a72557d5ce779664d76913eda01e5597a17907c5b4d2b1b70181d722994181c81ac9ca5c5450240c0c4e275586a9b6dec645953aa78a3fc290d359a2a6bbe6097fa14b23db3e9c0865cf7":"df05dd":"699184570ad86da2599e3e04f0e975594914926a1acf1212e567a1a0ca488c7da1c0750f45054adc327a78f3532e5b8815a5f9dec0dcf16a0787ae35de9de0828b162db100f42363688072df00d658b428a35ca0ba2e3fb19a9530aa8e593fa8501d1405e2abe17d2238958f9ee95326a9962279afcde630c51a8fc884859038":"4284c45d50c2aabb87255c687a34a32cebd7ba65bf9230fa87d7f53491a9403b274be021fc3307058d45fc13266c5c83223d5f13cc8e1190806bbcb025a7ab963f327985dce6acc118d63b28e47809aae8e34079937595c22c127607e8758d3ac297ee0d86d34247e338675040607f32ecb7f417ee325cca8810b50abec9bc00":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 1024] SHA256 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA256:"8592b5850b9ba96e7faecbdd67e50ed5fb2018fda0bc6a09ab6345910fc445ac6bdb0e7a4c6b72c9441649c9e78109bbaa1d79f9fafb8794a1a06cb638bd8f3c3416d44c43cf862b8ac1d5006310b05a7760d341d07077ae775f1695061d3c7297dd3ab8fc5d03d09ed1602a1bb69891bb377fd0aad6cd90f8b207467db36279":"eef211":"1e422f898ff258a99bc53648541709b3a3bba5828d36d070b42bec6a2117d6e6403f0d762ce6179d2dc220e180b1e52156a9d0291eed64840787dc91c1f20fda841797a0547b32bb83b668a177276fc4aee64b21fefa391522cc4e7372dc5cd5f2b3152f8e1973aaa48757afc3df7041b35b5e91b5c317cc0be48a38bb3d837f":"2e37c8221597f7e2b1970c40a50db5fefde31b1dff1e9b9d6a70b023acb014971580eddf1d67f15d9fbbddfcdf49cda14ccb7516c33b787a3a3fd43d005d02de10f93ffc99585ae5dfaa766c0f1f5bfa62e50e76a059a4a1e814c1ee9836e01595731dce48f94aa1ae36d9c5165a3eb28013fac271e091f7018fe96ec26009c1":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 1024] SHA256 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA256:"8592b5850b9ba96e7faecbdd67e50ed5fb2018fda0bc6a09ab6345910fc445ac6bdb0e7a4c6b72c9441649c9e78109bbaa1d79f9fafb8794a1a06cb638bd8f3c3416d44c43cf862b8ac1d5006310b05a7760d341d07077ae775f1695061d3c7297dd3ab8fc5d03d09ed1602a1bb69891bb377fd0aad6cd90f8b207467db36279":"eef211":"edf40a32aed24e14439d8db48e80d92c4c11035dedd30d90a4ffde5dba8439cd274cf0bb63c155807a90f2cf5fac7add8297ffc5a4dd642ceae1162031dbf746a2229b3586a7b71d5bc2d6ac27324e320c5f73031de10a1d7046010a74105d0885fe7368be8d5b340fbda2148f183f7213f1c8ddffeae6ab5cb907e32b2b525a":"4e6e6482b8f163fb3c32ff454703a037b9882eec1f82dbd675c94accd79a476e12a347d2e9b4745d30164ce8484635aeddf1116df40b516e6b2af497d27f2194cceb801922aa6d55c935ad166bc477c8e54ab29c07f432b0aa3808e17d28254a0431fd0267e389a6b852f10df0f9a2f317c6a6e762c7395e743b38341828ac10":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 1024] SHA384 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA384:"b5d182424e512cf47fbe70622b413c5ea20bd240030b365a61f73d4adb508ff5c73bcee41fc53b006e795cf07adf0d9e4d5b347b0f6389518f0f0efe0829b3edee97b6da7e0bfecce5298321bbeafd27af1c70d8674c0cba23f0a2498058b1c36f91463878f8618b2cc0333c77b8c1fbb1c5741e816ca5a607032a9489cc436b":"7f3c2b":"f96007ac5f0ca23ccfa37060fb9a5d63d1b66b51ff7f540ab7f27196af76dab86d11cfc6c1dc56b793b4267ede33c497fddeecdf26a032a83478e90da96e4483f3cbbbb1ee89b082ab0953787004c343ffc476921b94da2949753c33d412eada13f69416eefdf8c29f08bff5b6f5a18f60cfd012e84194b47e5132b2384b13e6":"32a0c7cd0c8aff00d21c3aef312f8007fecf3a2fd3e4cf64650fc882ef97014765822f50f0ac6bb189a692a21fc2362d5b97d3922649fed82ab667ed92a170010634d25d705aac8f4e54a1a65dec08c8b51d6d7385a19bf6bca290656486ed76843e341852171d6cf5d6680b30cf2ffc2e2dc09011345d829f97027c70fd2a02":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 1024] SHA512 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA512:"a9f1795fc64a9fac0edd4553ea5b722b34b5266bef29594fa80dc8c64d33c3459edbfd36fd7b85203dbe4ca17cdf7ae53e5fafdeed8e8a688264858db18124438a3bf3110a721d94276cd47d7e5c2e1547dd5cb80212d594571432506987dbb4a250de62eebdc19a79f876228b2c4d04a1b5910395a8714520e78b997b3b6389":"d43d27":"b2abe66d1e6dcd75149d42445705b71b7509d393ee38b7d69821850e4268231e98193c91473b88cf61a94e97021d27a9348e04c310bc72cf26091d5b1f8a9349a15e4bc8733ee683e256b41863537acb79be737cd98894d6cde614cad65f2c3b95221cfbeb9e6ef7604d7eaec1d03ae80d4127a493c5a55254607342ae0e755d":"3f8ee147643e685b325c13557f44945c99efeb0aeabe719ac1da3f6923d02ee74b0767558225548f276d4bab34e8f09c4909a251cdfd7be3cb7f57f4d8f4bcd01dff0fa532ac3116770f0527b56c4415df19fba04858e70703f06b6f02cdd6420d255a21953ae328aa17eb9e151ea1fc0916fe3f3506d8f14ef8e8e09f6e2e26":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA1 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA1:"ddc1676352ca011a235db9b4bb41eab81a9f3447a34c3626a531e3319665edd9c9e269788323ac7f2db36b9106f4b2148b7c7a309a0b7482ff08cc97c792bf8e2319f42aa51078a29a4ff90c0e29563059a8608e8809a04bf45f1334b23631d99253ba230dc640ffc3a70c27ce5fc7ebd1adfe68e4462790007b39f5d5b47dd9bd04d0d08ac3b586fd6cc8e178d52ecbc09434d4b89d83cadef6c53cce17788e87b551aa0b507893f308e23da919a4aa01183ddc831a99a3e3c4e5bffdc7e8c8b6800699abdf11569ba66e5892b2e55c6f8578a12f5e304dc28ffbd5ee2dfd2bafabac77ba67031f588e73cf7ba344396d166f5392ad36187b45e15916aaf5b7":"748d77":"2dc3fc128057e1c291f9b55ace78d9473dcd3560a7ac7d1bfc59b301f3bdee5ff1b9593f2cba7e96108ec5bfe2763728a37c884c370655e1c6acaa526347c76feb4a24643056b2e7570864b67f16ee41a49acda3c2ad87d73d38342980073deae41f6468d452041e30109a27ee8085f907cf0a4f91c99b6728a6596e9326d739":"bb75bbdbaea3269a01bd9b5e492178b7ec11abfb59d417cd5cdabb8a4b922b0f21ae69e9da7a9f628c9cf396bfeb75c836bf734561e68e91fbefeaf0f57f261c936bef741527187a5315dbf584f332fe3ed8a44367688e28998675c31f2b1cc3fa87faa4abcadff5fc64025c9589149e41c45a5037fe1c27d320d5a40ab6119b639ba052ad1d8a0339fd3a03f1356bcbc056c4f604862df36b66685feccfe5f93f2fe0c957a02e8d41a574ab0e56d8672d338de761fc9e9a1b801ac5dbd56c1592efa77f782d1dce3531efa5c7f569ddc313f5dce62466ddf269bd5b780f7c7c68b5232e1f77f7b4a8eef8a978eeb56d691c3e4a95965867c61d3c8e7badda1f":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA1 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA1:"ddc1676352ca011a235db9b4bb41eab81a9f3447a34c3626a531e3319665edd9c9e269788323ac7f2db36b9106f4b2148b7c7a309a0b7482ff08cc97c792bf8e2319f42aa51078a29a4ff90c0e29563059a8608e8809a04bf45f1334b23631d99253ba230dc640ffc3a70c27ce5fc7ebd1adfe68e4462790007b39f5d5b47dd9bd04d0d08ac3b586fd6cc8e178d52ecbc09434d4b89d83cadef6c53cce17788e87b551aa0b507893f308e23da919a4aa01183ddc831a99a3e3c4e5bffdc7e8c8b6800699abdf11569ba66e5892b2e55c6f8578a12f5e304dc28ffbd5ee2dfd2bafabac77ba67031f588e73cf7ba344396d166f5392ad36187b45e15916aaf5b7":"748d77":"9e7d8a94561c95facc082974fcdbcb813e1b37fdcbb1013a7d9c7c53d6e6dbbd44d7961fa36a106404fd760ead4ceacd61a0e150e144c95bb239f01a212aa1b585a29024c47d7745189d022b13dee9b9e14b5b70ce92a38607b50638a503ea61e7473e4abf3f15c4914f947437770f6f48836f079a81d7e4057887566a5700e9":"cd0a22729f6a2eb4c7bd6c1ebcb9510ba1aa6e8921109d7c1fff6f7cfc36691b69e89656b9d7cead82356efd740faeddb0e3cba5a98656b841f2e98d296b995b758074fbd97af3baa4b28e9df89e9246eed76ae3eca1bd213a81b5d15411dff648b887a8835fa2f7bb2f78be5c4be8dfb1ef0d6b08319685edc437e56da3c8a532ec8c7382f74859530eef7adffa68ede91e3fe4bd29f43bc8ff813fec7d0a15aee6de202e4f32fbce4621807cfab47bc395ac10368d931bd73a86d40a38cfa898668cf76f0f4eff32223c0e452132c36b2c16f228286abe0f3fd4f0eb73e5ad989ca19872097948c6152320daed43bc2a98c3468a610d13ca086bd8ea89bbce":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA224 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA224:"c3ae3b433f447d5f94dda31fad8225c79eb2ea5b4e398690a342d23d922d91a4e3fddb3e42ef8b55408c096050601522fe6bee7c9aa03851933eae5a831280c8c2963a78ac104f8c03b21cccb768e4c2d290b25916fca23f4d3a3a69c5fb93705b7a125ae8274baeed6ad3db5ff86fcb6ff76ef97739b0ee8a539ca430786fa0aae9717fe499ad0f27370b76b0b76dfa9e00504fb4b8208cfb097d8ddffbe0156acb1c1b17a1b8e8c8fbfc0d5fe10345df98bc4ba3280b868eabeeab0ea5753cb0ccacd32db18a84bcaf80dcae2f39abef781f31e8add85838400b9412e61c5c6bdef9d4b8bec3568789944ede8ff7a6ba8d4a4ae73727811d5c93f4823359f7":"c5a8ff":"cde4fccd809f882f87479eff1cb60107b12d3fabed45d87af128a203df006cea9db0e23bd6c3b1fd42a1eb0b2809ac1f21bbfe301e75fafeac2130eb774d490c0ddbeb80e5fadd00a0556cb88e8a0d5574dd43608d2ec3cace28d7c86ebc00e1a6cddf44b62d556028c9eaaf58206bd234fad7e341567d07dfa45e42cd34d890":"b23507940f4c90b01408ced77cb233fb51d992d42cd3367f9f06f855eed6d4b1bfbf70141374593fd9d6ba2d5ecedad1a83e76261e207f087a546e0e381186e6a1697967031e55c8b89780be1cab1eaa8f697290485140a9a62f5533e4560b0f417305799650bf959ec76d54229de21f0653bf68aeaa61c55e5407f87f154d28fa35062e1a8ca3de43fd22b41c4a0d49b8d1b8160e594fc25e791009a1c61d051ad6c7e65854d0e9476106e3cccd6db331916f09b5847591e0a5a73286d6d3722f57a5effe8de959f5821d6d55b81f7e34cf069de1f892a4600220b12e3b964615f289c2a87c567f4580eae39cdd373bc2cb45a2df332427e41a19ee9e947b74":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA224 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA224:"c3ae3b433f447d5f94dda31fad8225c79eb2ea5b4e398690a342d23d922d91a4e3fddb3e42ef8b55408c096050601522fe6bee7c9aa03851933eae5a831280c8c2963a78ac104f8c03b21cccb768e4c2d290b25916fca23f4d3a3a69c5fb93705b7a125ae8274baeed6ad3db5ff86fcb6ff76ef97739b0ee8a539ca430786fa0aae9717fe499ad0f27370b76b0b76dfa9e00504fb4b8208cfb097d8ddffbe0156acb1c1b17a1b8e8c8fbfc0d5fe10345df98bc4ba3280b868eabeeab0ea5753cb0ccacd32db18a84bcaf80dcae2f39abef781f31e8add85838400b9412e61c5c6bdef9d4b8bec3568789944ede8ff7a6ba8d4a4ae73727811d5c93f4823359f7":"c5a8ff":"f14d803e6d572645b3b9a51d6c088d2847c4ae01418a8155238cc4f44c3f6527b053a14521e86d81ceff1506092e23464d99828e7f1de3de74ce60f9b4a45fb87d71baa30b161dc217f7afb19eacf4f3e3faf288b70192c2f8b64a545894f9ac5f8f1283b44afdb29889ba47b3e9c8d813cf4517729e56a7b72dc92ec078f9ac":"3c18b9f248455a5b309f140c08bfe34d43303e0ba69ec719911fc462094a92211bdec1278e4495f57e94b3d7ff4c6a779a50e878ea334a7e733c7b311038d8983b9f0e60e39f8b5b8fa0f7e092a44a68a6157206ced18d65eb7b4a24a8e35516ad8c6a00cd06be2cbb7c17626c871f5112240481fa9244b785b27bb843388280d92cb241d6c109794208e0c7723303e55b7ed611793de96ece67d4dc8a5a74ac48cac63eb88dc752577987b32a9df865cf6528e314d5521c438957ca00b01c4ffbed8439074223e1b995bbd9db78b6ce5887e094f76d9f4e05f33763e87ed872ed98130d998cb054522ef240452397c791ca2270026e9422c19fde67ed79c842":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA256 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA256:"c47abacc2a84d56f3614d92fd62ed36ddde459664b9301dcd1d61781cfcc026bcb2399bee7e75681a80b7bf500e2d08ceae1c42ec0b707927f2b2fe92ae852087d25f1d260cc74905ee5f9b254ed05494a9fe06732c3680992dd6f0dc634568d11542a705f83ae96d2a49763d5fbb24398edf3702bc94bc168190166492b8671de874bb9cecb058c6c8344aa8c93754d6effcd44a41ed7de0a9dcd9144437f212b18881d042d331a4618a9e630ef9bb66305e4fdf8f0391b3b2313fe549f0189ff968b92f33c266a4bc2cffc897d1937eeb9e406f5d0eaa7a14782e76af3fce98f54ed237b4a04a4159a5f6250a296a902880204e61d891c4da29f2d65f34cbb":"49d2a1":"95123c8d1b236540b86976a11cea31f8bd4e6c54c235147d20ce722b03a6ad756fbd918c27df8ea9ce3104444c0bbe877305bc02e35535a02a58dcda306e632ad30b3dc3ce0ba97fdf46ec192965dd9cd7f4a71b02b8cba3d442646eeec4af590824ca98d74fbca934d0b6867aa1991f3040b707e806de6e66b5934f05509bea":"51265d96f11ab338762891cb29bf3f1d2b3305107063f5f3245af376dfcc7027d39365de70a31db05e9e10eb6148cb7f6425f0c93c4fb0e2291adbd22c77656afc196858a11e1c670d9eeb592613e69eb4f3aa501730743ac4464486c7ae68fd509e896f63884e9424f69c1c5397959f1e52a368667a598a1fc90125273d9341295d2f8e1cc4969bf228c860e07a3546be2eeda1cde48ee94d062801fe666e4a7ae8cb9cd79262c017b081af874ff00453ca43e34efdb43fffb0bb42a4e2d32a5e5cc9e8546a221fe930250e5f5333e0efe58ffebf19369a3b8ae5a67f6a048bc9ef915bda25160729b508667ada84a0c27e7e26cf2abca413e5e4693f4a9405":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA256 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA256:"c47abacc2a84d56f3614d92fd62ed36ddde459664b9301dcd1d61781cfcc026bcb2399bee7e75681a80b7bf500e2d08ceae1c42ec0b707927f2b2fe92ae852087d25f1d260cc74905ee5f9b254ed05494a9fe06732c3680992dd6f0dc634568d11542a705f83ae96d2a49763d5fbb24398edf3702bc94bc168190166492b8671de874bb9cecb058c6c8344aa8c93754d6effcd44a41ed7de0a9dcd9144437f212b18881d042d331a4618a9e630ef9bb66305e4fdf8f0391b3b2313fe549f0189ff968b92f33c266a4bc2cffc897d1937eeb9e406f5d0eaa7a14782e76af3fce98f54ed237b4a04a4159a5f6250a296a902880204e61d891c4da29f2d65f34cbb":"49d2a1":"f89fd2f6c45a8b5066a651410b8e534bfec0d9a36f3e2b887457afd44dd651d1ec79274db5a455f182572fceea5e9e39c3c7c5d9e599e4fe31c37c34d253b419c3e8fb6b916aef6563f87d4c37224a456e5952698ba3d01b38945d998a795bd285d69478e3131f55117284e27b441f16095dca7ce9c5b68890b09a2bfbb010a5":"ba48538708512d45c0edcac57a9b4fb637e9721f72003c60f13f5c9a36c968cef9be8f54665418141c3d9ecc02a5bf952cfc055fb51e18705e9d8850f4e1f5a344af550de84ffd0805e27e557f6aa50d2645314c64c1c71aa6bb44faf8f29ca6578e2441d4510e36052f46551df341b2dcf43f761f08b946ca0b7081dadbb88e955e820fd7f657c4dd9f4554d167dd7c9a487ed41ced2b40068098deedc951060faf7e15b1f0f80ae67ff2ee28a238d80bf72dd71c8d95c79bc156114ece8ec837573a4b66898d45b45a5eacd0b0e41447d8fa08a367f437645e50c9920b88a16bc0880147acfb9a79de9e351b3fa00b3f4e9f182f45553dffca55e393c5eab6":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA384 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA384:"c858aea188541c0dd2626eec9a8c98511ca03870353128c1687d94a1be762a4940fca789831a720e108f2f7c1fc20aab38336b5668205d62963c51aad74757183faae7c0c59b9f679e96393e7f93e8a30ce99fed1b8e85e7146bd69a3f8dc5734bbacd51359f4f66aa507fbf4e69708877f7cd7cfb6868006e330869d9eee99f466962b0dee9080d9413bdec2e41445190394a49ecb191167350be411cdd6ade4eb38c4c4bf891b43c91b5981a3bcc8a66f85e5cbaef751e3cbe94c7f193fd78ac55048800250d5cc9e41b89319ac3d0258aa640299e165b0cf7e5e108f76a12f72132f6a2a4c239df0544d3d8407b94f9f38e9156c825a7eae001543fb264eb":"2a26db":"d6a169031049b0b3b582d22bf40b9fca45d2618457146c2b4ac6f6ed1f34291f6de8773955cd2e21b7944caca65794621a7ce181e5ddbb45e9252867877dc4e35b6914ff26ec18890bf31f60fff1df367bc6c59373e58a1d8cb607188a394a2907ede95f6bf096731867f44fe520aacece76b5c3ea75023c9d3f3c080eaee376":"b9794f252e6907dc4c41de42ea5a0e6361114ac3814c4a92583ca70fd78e98190a0d9215bd5282e8520422093eff2e1cfa335cffcdcc27fe9bafe4516e74445d4aa17a08db754fc69b156d86ff26eb9e814f605142a3051d2fa64305d3e5c5c5f67c7d9e38c5054d069c14b23e4278fa5a73381f61f90a9ec428c883f1366e27ec0219db8c942582a284c161eead307285d0e4df6b0d7dea0e8216d7ef2e4b2ede2296e0b780e5a3f8d15f123f737b9d6170074f758de32b6f1e958b27e422b053df8f5fbbbafbc14119260f7022cd2934e8faeffbd7085aabc44497bfe07387bc0e5aa02399eab99318adb98f99a677aa0683e0c11d638cb13907fc5c3147e5":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA384 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA384:"c858aea188541c0dd2626eec9a8c98511ca03870353128c1687d94a1be762a4940fca789831a720e108f2f7c1fc20aab38336b5668205d62963c51aad74757183faae7c0c59b9f679e96393e7f93e8a30ce99fed1b8e85e7146bd69a3f8dc5734bbacd51359f4f66aa507fbf4e69708877f7cd7cfb6868006e330869d9eee99f466962b0dee9080d9413bdec2e41445190394a49ecb191167350be411cdd6ade4eb38c4c4bf891b43c91b5981a3bcc8a66f85e5cbaef751e3cbe94c7f193fd78ac55048800250d5cc9e41b89319ac3d0258aa640299e165b0cf7e5e108f76a12f72132f6a2a4c239df0544d3d8407b94f9f38e9156c825a7eae001543fb264eb":"2a26db":"6c1c4396f7b7f9228e832a13692002ba2aff439dcb7fddbfd456c022d133ee8903a2d482562fdaa493ce3916d77a0c51441dab26f6b0340238a36a71f87fc3e179cabca9482b704971ce69f3f20ab64b70413d6c2908532b2a888a9fc224cae1365da410b6f2e298904b63b4a41726321835a4774dd063c211cfc8b5166c2d11":"422e70ace2a2c07d2adbecd9dd5714c42d0e768d48bc33fea822974e42ecf99c791276e44936e70b183e712e0dd9b484199b92f24a76c6908faf6bc20fe266fa03886781cead7c82aeeebdd150bf48ae4698e76807ef24d29f3cd5590395f4725dbe7e468540b4d4d8be84e673bff86b0c08af17e738af91cee4f14367dd6bedf71b5e8e148b61ea968f16160604834831d557879542598be7d2fd01c7966f0ae1ec2554d8dd653f20c551a1de6212481e2a19a3e2fa9cf005e5f3ee1962c34e3e85f84104f9172debf89db438c32f2a8061ac15d3cd3f3a6b7d75fd7c3f8ea0c505c6398d1e70eb12e9e16f5a0e4b459c02ec38f0dfc7a4a3139c1fba6f59b4":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA512 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA512:"b6515048e1f7a3506d6bf028ea0516592078a2ebd6db04af6040bb5dde8888787e1fd973b1d160da25ba9095450d866625aeb7cf684b522af4edbc20adfad09e9c4c42919b7691e1404afe8815f229001bf7f8e2b1c511d56207972e3efa588f04f7bea82b64c45bc28bbc5e3ca3b1be8652c54a3393e95a58c78c34c7c7ceeca983e91920467d184ecd5aad0114f83d0517e6ee82944cf134e9efdb68f14322517acc10285c892c94e6892c9659fb85af6d11322df94edeb77a379e97c7608e5d23c89b56a722b54d91f0811855c21e0c41ed362ae144e2f46eebb97a9057c673ddccc0f2ce178c3af086d1f93a092a2ae58bb0703ca66318913e69e36fd997":"a3e187":"8b618f6669b9f0450a57cdc57f5dd0bfcc0b4812e1e2c2eacc09d9422cef4fa7e9325c3f22c0450b673c316929a339dd6e2fbe10c97bff198ae9eafc324133702a9aa4e6b47eb4c621495afc45d223b3284d8360fe70680359d515aa9ea02e36b5610f61053c6200a047f186ba33b8ca602f3f0a6709272fa296025258556880":"ac87aad4ce85038b8552c4a6e93ed94368bb3376ce17ba1d08812e004b43a952e27fc50daee8929094e747dfbe02584a7654d950d21700605e699561c03e64d2016404da7b9c0b0011ff64f206225db1c8b5f974bbeca720a7c2ec73e6fbf58adcc6f5cc24df6d09ade74416f30df70c4449820f24378b90c176f65651ab1c1fc82d3fe834e7b66d0daea47b8d1931a81d1fedd4e6996c56edbe496fa237fbd41876a460780100e4e6f0864b6f9282abae4ecd98630548b5cb42e66cf9eb890e0651f159f356283af40c02913d2f3bbf6d8ebaf6b7d88e6699f482d7825428ccb7ef8129dbc665bd4df8e9a07c339a1134e907e439d0846480ae6c888c1e9be2":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 2048] SHA512 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA512:"b6515048e1f7a3506d6bf028ea0516592078a2ebd6db04af6040bb5dde8888787e1fd973b1d160da25ba9095450d866625aeb7cf684b522af4edbc20adfad09e9c4c42919b7691e1404afe8815f229001bf7f8e2b1c511d56207972e3efa588f04f7bea82b64c45bc28bbc5e3ca3b1be8652c54a3393e95a58c78c34c7c7ceeca983e91920467d184ecd5aad0114f83d0517e6ee82944cf134e9efdb68f14322517acc10285c892c94e6892c9659fb85af6d11322df94edeb77a379e97c7608e5d23c89b56a722b54d91f0811855c21e0c41ed362ae144e2f46eebb97a9057c673ddccc0f2ce178c3af086d1f93a092a2ae58bb0703ca66318913e69e36fd997":"a3e187":"6b7450077038ca8478e7a380292151ad413c1949d78076efe497beb4013f036f7242375864a894d5732b3b906feb1ccd606315fbc79c5e8827a024fac432743cabbc5b35f2894c9f4134c1179261257034aaf24d16dd17ef42649c4ba80488601dcb03c7a343b88cebec7d3c18e9363fc6faf6684baa68cb3cca6ecf341d0784":"1933ff9ae5c520efeb711fd17a571a209c2ba9e0469e39a5341a70ca46c6deb2359005fb21c9e914e8a5037345906204261476427ddbdf29212d84c6e4e1dbda61aeb21ceddad1c3789d99ea28ebf72c4fef790f838191b30587e00fa841d63bfebd00bf468b462ae935eaaef2f83ad596b29a0d538ad99b44d615217f0643f0d9bd755fa281e35bedca37b238a89b78f9d911a24c40ab3cf69dade4ce4a30bd3104f890a6cf410a1e76e625e28495f6f9b385d698e6f8a6eadf0df3af03b3e078f4b0c984bddf525f220635cb2993b72ccae40ad3378cdf775431c2ceaa1aaa57f355eefffc0f34b5d70d1a41aac9b052594f0132308b0e329e34c0d2fdc519":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA224 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA224:"b36d351c07628650b279ba674fe3ba00448699016565ad6f0ff357f963a3d8a08643fac8899513907d90b90972aaa021fb09914eb71021b643907510eaf3870bfc39828ea01fac9782aab8f02879f4215d75a3d88caad27f38888d13667b55bfd90c7244137f78e0383f38359b5a196ba31c4fabbb05556aab1ce1842f3d290f90978d9d10af4e478bf06a911cae4eec7b7605e9503d2242ef70e9717670a22377182f62257a0fd1ff4a6333e05b725a90ba956a6c6da35a7d195e4ae46e3b433a9fa05da8dca1349ef44573dbce2f009d1cd0c5d920793f5e7d439bfb67b60484742ac7d3b7e965b909b520f20e1c52535c42084e2f92de068f9ca9ccc0eba4d9d9787a7704cd68ec036465175c5db270c34a206f5feba43ccf3989ac08a2ff7f878092a937a6d3d159a998c610c042df0aedee4fc0f5cb4f1fb139c17641e697e85795271bfb31f037f0164babe466817b66052fdb2531b8dd4974234ff5b85362d7269b2646e25b7abe8372261c5762da7069e6b83cb0a0e005001eb3c047":"81cecb":"d3508ea71028942912cbee8fc54705edfbee6ed907a019cd874dcccc81b5d048b272eb4422398eb6fc5d4e2f9d9498bdebfea111e8639ddd87bd3180bef62ae5dcf26fa81dd0347b7b6d71c9c82a9399faf071b4c671810a70b04c52e1c31ff1fad7041d2876f04238053ea46d915c47d0cbc50cc8502f1cea2e058912a41733":"1c9f780c0bd9d6eaf41ebe2c44e5e4a4db11ecfe887230287c3c1cead0ac985bac58bfcc1ddd645821ed0433ac74838501cfdbf19cd05deda66ea7a70e746b3a16412f1f244b8b03ec2c14ea7e4f470d119677218fb4bfe2753e74e884b9d7ab8051b9d4060831370d5ba892a62563143c84c9105fc3a35fa81f20c0a882199f88f1287d2a27fd5fa0d924755937a2dd3ec087a65873d70cf8128bd700efb4925cc0948ae38d396d992f9641c72ff67f289a55f508c4b8f0763a9aed71a6a3ef79ec752a22cfc4571a9f532b88c462b4c1f5475e68ab1e940e3ebbe8093ac32912e8424791bb18eaace7f9188f089263252812bea0a28fc21ef6ce82ad73a3d7572de54daee91d54dedb8241a05a31c741c7e46daa1582c9e7afa7507422307ae10775a9936bf7a9b6c6e11c3977813a353051d16ab37d176cfb027f0c2429624558cbeb49bbb28743846c852e695674e938856fdff0c985f6c29b9a82e681c4cab010b6561fb6a27f2194074df5f2e1e46ddad30b74f25f15f1687053dc84c6":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA224 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA224:"b36d351c07628650b279ba674fe3ba00448699016565ad6f0ff357f963a3d8a08643fac8899513907d90b90972aaa021fb09914eb71021b643907510eaf3870bfc39828ea01fac9782aab8f02879f4215d75a3d88caad27f38888d13667b55bfd90c7244137f78e0383f38359b5a196ba31c4fabbb05556aab1ce1842f3d290f90978d9d10af4e478bf06a911cae4eec7b7605e9503d2242ef70e9717670a22377182f62257a0fd1ff4a6333e05b725a90ba956a6c6da35a7d195e4ae46e3b433a9fa05da8dca1349ef44573dbce2f009d1cd0c5d920793f5e7d439bfb67b60484742ac7d3b7e965b909b520f20e1c52535c42084e2f92de068f9ca9ccc0eba4d9d9787a7704cd68ec036465175c5db270c34a206f5feba43ccf3989ac08a2ff7f878092a937a6d3d159a998c610c042df0aedee4fc0f5cb4f1fb139c17641e697e85795271bfb31f037f0164babe466817b66052fdb2531b8dd4974234ff5b85362d7269b2646e25b7abe8372261c5762da7069e6b83cb0a0e005001eb3c047":"81cecb":"e140afaa153177cb8b86935e56d2e11e5a416b3a161edffac09940a697c8daa475eb7be0a3f4e071f2476e7907be234cf7f0cbd514b3773606df2baf1d55d7c1e5408893fb9be09420f4c4628c6f54eb840d20d22f2e9814a655c5eb4a2c37f25ac83f8ac52d5e7d3c15fce28ced5d412b21d2f710992cdbc8847621c754e47f":"4c946938453f7a617ae81c1739f770322e38db7b16feec1d2b4cdab7178206fd282473e3373c265235c8ac04f4ae036a6bcd671ab34a5e68496dcaafa5b39f5a292346b866f65085719f28a075a26233cbf91b1fcfac9a42580c8f378fd617dcb2541ef8b407bdd7bde66d4bd177eb6b7f18c5a3692874145341207e541bdc2eb917f20007417934587069c6a0edfa76c3b65f8eefecbbdbebe2a24ece3e7f392d7ea2d077b80c642b1436c4f8a438c228b42cc8b34ebcbf2b22a47f13fbb03b27b222206e5ddc1ffaa6bedeb14565453a588f714bbe75d5e74d7671db240c3e80560296843c9e11cbcf3e2fc97c4b5d3b240db888ae2ceb0520a5b749afc58abdd980275038eacbb2ea75fb89827123b2e879cc948f2dd2f95207f74066858a46c7a49ef92bec06c86f2b9561f6fcc500cbc20630f2ad43f6ac135f125aad88b8919c5e136fed41b96f3d3db136f70ef6798762fa66fbdeb07bc8a9a9be19a4fa5b57f3a3b5e9a516f427fcdf8b4fd421ee14c56b6de76b06ad40488a5b78e3":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA256 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA256:"9bbb099e1ec285594e73f9d11cbe81e7f1fa06fd34f3ec0b799394aed30fc2ed9de7b2a6866fde69846fb55a6ab98e552f9d20f05aa0d55c967817e4e04bdf9bf52fabcfcfa41265a7561b033ca3d56fb8e8a2e4de63e960cfb5a689129b188e5641f20dbf8908dab8e30e82f1d0e288e23869c7cac2b0318602610a776a19c1f93968c652b64f51406e7a4b2508d25b632606834a9638074e2633eb323324b8b30fdbd8e8fdad8602b11f25f3906439055afe947f9b9bcffb45dad88a1df5304c879bb4a6eddb4d3d1846bf907d2ca269845c790b2f0af8154aad9c4acb75e18a5d0e4f9f88137032b9964fe171dfa0d0f286090790f52157179a6734b5f9a64e3d2ed529722c3d3836d4501496f927a0f8e389ca35332b836d99e995f4a3e86f581bf9abdc7a10e06a6b31296ae3b43e6ddc9a0d9a7d0d9c4053af0875e851192d1de7b08d1beb7b857e227f8803a5620726a31920bcab922d3370a78033b315024a0fc1f6c276be565e58de77f294c8089ff4c43fb334d26006ab5757c65b":"ac6db1":"170dcd5458adfbdccc757e0b5abc19278112f24b418b995d395b46410da3624c0a8b49fc0d914fe6a02101ef6765adbfbb5e24739434be92acca9f43e19639bddbb012fef028c7c0449d52a9350b88c2f6e5e52a79648c0c931e8ace5bda5b8bd3a3afc4ca1b6e520012f99f8c57b3167bcec0d8bac30cb1367e8f4a4118d0a0":"6a4db2e6c13ee8ec6174bf57ae5bb7555e66dc2e3b618f259d913b5b8b6c16b9760290c9c576b563316f510ad2461cd5086b6d9670551ec74b8a9d15ebd43ccdfdcd74cad660a3fe3f36992c86559cd8e9e4d3568924b1f7e55bc5d8df4cf53f240fb3b945a08d24f205d5a7081410ea3e8136ca282fc99e6be0b1fa2faa742c9d682d08a77b791bb0421241e6a82f84605dda359e4f8475cef346c9f6a54a085492fc4bbb30b1047c66f5fc529ecb6aa9ece561e5a3a62f9a19eca2badbfa32a2aa205713b16081519c2cde2f8e8261726fad49145dce0d9e24f6e085e44bd86f670a114ba98d54389f0ed683d062735cd495e6a8a6eef9fd70355b92b4cf6cf0c24e898b6d3f7fe51dcd1548a1adc67ba585e2d18809ea658d6ec4bb5e33e8501d11a266f5e0928ecb58547e72c27db8b07aae31eefef865bcf6a08485675d3037f432c157e5ee428d292bfc24c654d8fca7a60107dc18461251906521e1e9965fc80c7b5f582ac3dc3798a0a2937e76d7e7fd7122d3fd9083feeb9a44ad7c":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA256 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA256:"9bbb099e1ec285594e73f9d11cbe81e7f1fa06fd34f3ec0b799394aed30fc2ed9de7b2a6866fde69846fb55a6ab98e552f9d20f05aa0d55c967817e4e04bdf9bf52fabcfcfa41265a7561b033ca3d56fb8e8a2e4de63e960cfb5a689129b188e5641f20dbf8908dab8e30e82f1d0e288e23869c7cac2b0318602610a776a19c1f93968c652b64f51406e7a4b2508d25b632606834a9638074e2633eb323324b8b30fdbd8e8fdad8602b11f25f3906439055afe947f9b9bcffb45dad88a1df5304c879bb4a6eddb4d3d1846bf907d2ca269845c790b2f0af8154aad9c4acb75e18a5d0e4f9f88137032b9964fe171dfa0d0f286090790f52157179a6734b5f9a64e3d2ed529722c3d3836d4501496f927a0f8e389ca35332b836d99e995f4a3e86f581bf9abdc7a10e06a6b31296ae3b43e6ddc9a0d9a7d0d9c4053af0875e851192d1de7b08d1beb7b857e227f8803a5620726a31920bcab922d3370a78033b315024a0fc1f6c276be565e58de77f294c8089ff4c43fb334d26006ab5757c65b":"ac6db1":"973606b2c7e5658a9d8f264b8f5a266d0992cfbd6e9d3ff95c31a69a32c4f0f1cf44a5759d090d5ccf089768e6497b047a9b9f8f3786b8f82681b18b2d65500ada2217005cb06852d249ed17c9d637a9ffa7a5fc6d66882f854e8461b9983ac63c3623fa0cc4bf9530bcf0ff3ee9a086211eaaad1927f8c70300e9c5db45f54d":"355644f5a26a4ffc638c44ab4d0b7359f37845235bfb994d28e63b114c0e0f97d2e29f448da8b12eb804792ccc686dd807f44211d6af410bdca1196df84016b3cdae180bbb59133aeac5928560ad2cf6be61392dc9e28d7ada11658cf4a873bd2626ca839e697c79a5c4bb3ed4c9b8f48f83f2800e1907376f2e8874c23f1dff8bbf3b3f98bed7895d486079a92557a553a71e18cfafdc155775f39a77455b432b0c2c4f09990d130060143e7310b9d9e1ae6f2b1b83b90b36c6581473f60c3c61a10e286557f84e5d04cc36e12cbce835234d2d773221313ad7287c9957d94a1cda8c1fccd3eec45dd84a5d075d6bf823123fcdc7d549286142ab514db6d998e377429494f07041387de3ab31b02ac1606e590572bd9003e5a62b90b95b00c0eca73c744ccf4eae44374e26ba6033dd2baede95e19cecc840a045bf995a3250ce7b08e0c3267de822616f93a4dd9e629eb38b479bd31071b48976cf73ce52c3734abd93249300dd5c40635842dd2a290276190737a123008a4f0be557ca6628":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA384 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA384:"e1b23c29762d8572f1d41f1e7a846876d9901705bb4b3e0228ae65b2572dd1b3305f4d42a7704dda5934260ae9afb1eb34e7d865bbe11ae16d292f170711487ebce1d7363cd00acda5894f06127c1d4a7d9897373b4767a118b1646bc7a38086bc7d359067e9857b8b8642294cd08bab7646ee8ae0b3c7a51527a58ead49dabd11c3ee8326dade7f803cecb906c73aced669d5c3aed02c373d51bba4ffa98018892245f1ee6b035d52a3ccacb2c28062e572f213d607bb403725b34c65ea54bf70c0613e1a8d0552489787e3dc16c0b8cc7ca2d0b4d3e37d1c448a1ca4dcba20c146e78e2a6b3be888c7f65e49a47fe83e491dc33c684a1fd8acea8be091fdb70945c889df40431241e96a58cf7042f7a54f236ab01214a4e17d713945f79f605a8bc1bb6a2c4a342537b95beb92bcd722b68c14c346a1578c567f3ae277a46c264f4e4ef324ec2cc20ad43fbaf4035df169675575374de658df91cb5b3830bb31f69a8161c98f3b7f9e5983d96cbd9204c5e356980589c2df25188c474191bf":"3bd4ff":"8f3b827a1dc3967aa2e26c9d9052a97e64b047c186cf980070528708137a2246763c557ca197f8b8b9240d876cef42669085be79064e1980e51dac06d4060cdbb870d1c5906a9c739c4358b2c554bfe4392120ad56a160efc9d940f9f7b0ddfb9cfe7dbdb1e688919466d587632c27dfa8abf8c43c6f753765adc949421f9e8d":"a5e1136bc2db78827f97e435352303519df3c6ba149748ecea4c493f3355def8f94beb1ab45870d8bb1e32bb10c6cda4546c0bcf90da0758fa1e99b22742302ff17c7d5f0c5580a727304066204f524dd206e1a2a232d4394b74f3daeebc81d8609034dafec29620427caaa72f648fbf39028ff685925b1b7ae4b53e154ca93821b6b152da380217a2f82c864437df45c32253a9e3ecfcda3444f5db879cd12f2fe80d0b88a6fad7cb69303b82e1ed0b761e9f829fafbf4a7027fa2a6164f7701684f7aafd8b5dbf41e6d4031ca28bb4ce360fb3815c33fdb6051c9741ff4f9ebffcfd2f52873ba5567c17d40eb8a92af139b21a184b2e0740e0ade97effeea733cb2e1fe7ff65077c200b36e544f61e90dab2f524a74ed46f10d5244509faadc47f8bb57cac5026e00d1438b24f328dd5fa11fa3add3acd33b20f3c75b1007bcb5379cd8cd8e0f964dacda0157952f41e128ac43878c55acc5967cc2fc631010594248a439820df0ab1b7bd1be5f81bb026016dcc65a674d9ea03bf1958e591":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA384 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA384:"e1b23c29762d8572f1d41f1e7a846876d9901705bb4b3e0228ae65b2572dd1b3305f4d42a7704dda5934260ae9afb1eb34e7d865bbe11ae16d292f170711487ebce1d7363cd00acda5894f06127c1d4a7d9897373b4767a118b1646bc7a38086bc7d359067e9857b8b8642294cd08bab7646ee8ae0b3c7a51527a58ead49dabd11c3ee8326dade7f803cecb906c73aced669d5c3aed02c373d51bba4ffa98018892245f1ee6b035d52a3ccacb2c28062e572f213d607bb403725b34c65ea54bf70c0613e1a8d0552489787e3dc16c0b8cc7ca2d0b4d3e37d1c448a1ca4dcba20c146e78e2a6b3be888c7f65e49a47fe83e491dc33c684a1fd8acea8be091fdb70945c889df40431241e96a58cf7042f7a54f236ab01214a4e17d713945f79f605a8bc1bb6a2c4a342537b95beb92bcd722b68c14c346a1578c567f3ae277a46c264f4e4ef324ec2cc20ad43fbaf4035df169675575374de658df91cb5b3830bb31f69a8161c98f3b7f9e5983d96cbd9204c5e356980589c2df25188c474191bf":"3bd4ff":"4fd8f7c586b502fe11ae866254e333b688f33e29b41cf995dca4a60275778d6c1d114cc6899e6f3ebf6040c38552e0c4190b973b22e469ebe75deae5bfbd5351c8f9d46bdcd72cccc15378eba04248e3b935f87754a03e53fb3cff94e6a9678bb75838be68a86230814fd5e38efc939ad03b09e333989f5580078e17d483f1a2":"c5fcf6db007527d04b7c7b2ab744547521ca009e1644f20e793bb51837922ae9411fff23c646c2b56d99a3cf24b676b7e3cb036b6445c33629bdcc979fbaa280ff8e1c1c9e66b0f453633d3933b788590302746f0cad1be62e6f0ff1457358137cddb8574f9df59be5192a2556b8689beeb266a5adf6b21ba56e6b7cd0d6760f5c350f2ffbda1fe30fda8e2cf563f96d85cec8051c7b635da259dc30e868d917fa31b21e91caddfe5dbd21475a98bf6ab4cbb2d62dd52e35a3320f48b027fe89eafc15bce8f1a5e6c5a402d0d87743d3cf6950dfff4c616da976fac676cc944296381d81ed8c8a782adad29b31e4b2343e92dc8c406e022e566c0b9f5477024c73b21dee60128098d2fcbf67273aa12f44de44ff22bd36a0292723d026e34a0f1d545eec9fe4024214aa647b31af4a5d7c8259a720462476fdac9aa480668d726b9fe4f3c220bb492cd871f86527072089d60872fed7721f4764277903f90bb987af661b2fca1d7ff12694ab654037ef9146480d2c1c8c6c5e52adde601bdbc1":-1 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA512 PASS +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA512:"9689eb163a617c0abbf01ddc0e6d88c37f8a6b0baec0f6cab8f8a683f372a53d028253a6ba502da462adaf4fd87c8dc2b03b6c07c2b6aacab1d8c8bd043d89f4effe72ea2547c73c6366a2efab9c916945820fb880890bc085564e57ee76f7107a008f71e941e9fd631aec78f82e410ea9c893faa3d553cd1ca628af1087ca1b0c6aef3b66edcee14d1d7dc48293ddd7deed1ccbe487c957585abb9509151038d53f46b068e3e139c7689bf8e8d38669896b8d082e65e458e1f82b8e8ec926e7aa0f97d08526e9636f2c00af4c2bd3d8bffc4bb93cd47b09af18883e11b639d47938d036f7cfeb77db74a2c09a6dee9df98b18eff2fda7d3f4135083bb3b59e2172244ec37bdbdcfe6e199d36dc949cda1cca123fb2be07803d003d76af3d7164453df77d44c7f2599636ca44d0b7a46218326b0c814ed322b9c4279b060f1b9e14b70f55a3751c4343763cdbf9c14637d2210c59fbd037be17ea6706846fdc7b9ab90278c01c458e64442f9256f3ad1cbceb22959d495063aaca1a3959eae03":"fa3751":"6459ea1d443df706907ffdd3ca2f193f93f5a349b50357d26748b767cde6ab5cbfe76b1acb2b9eb97da5c4d2ddc8d18e3a3b1a0326d475c1c2c49ca73c0fd3fc9540cbbba85ac52d6811fabd693a3b09a281d535715ab784df3ad7292606d15a70ccd1a7e2b1b48ad92a6a3f736f9fd5522d9a869c7b654446102e9493b3ed9f":"2b72942573b825cd1f0172119c23440a2b384b7f2a3c5582bb02f764e2b159ea9ad880ca61b3df7ca249134f4bec285083c7ebf984b192808e916af687ef6c6a9a6722a4fa9189fac1521d03853f3dd5a95ff4b9dbdbf3c7077f720650ead01945ab5bfee582ac1643526fbf68efe1bb3b6f7d2b4b01f2155aaea38a2c7ed29add23ee791a703d11e3b1b7c500d9a6b647c1337bf537c071e5bada6faa025bcaf5e5d1196998909c3d64758826939ae7fe1466dc6efc10a2b25e21186c2d135ceace33cdf490b13a0d10c2527e04200aa70bc1d4f3cfb04b5d2bc17aee881d3a788401f45443470bc639232088a9553c8d792aa5707654f075476a66b86368d5a92b4c84a3b4baba1b0b98bdebb85b48b82b8409f2e9c1aa500670329ff3b6e83e25c561110d47b2fe93ea2946a74f9730da9b7d126f8d7c3fa4a51fc30144a827831c186390998d552a1b677afe5afee46e9d4a5774a56355a4d1967677e75d176aef71c3fa061644d7a9582385877de67f87724b0a6e868f3a2eeafb68c53b":0 + +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001: Nist [mod = 3072] SHA512 FAIL +SDV_CRYPTO_RSA_VERIFY_PKCSV15_FUNC_TC001:CRYPT_MD_SHA512:"9689eb163a617c0abbf01ddc0e6d88c37f8a6b0baec0f6cab8f8a683f372a53d028253a6ba502da462adaf4fd87c8dc2b03b6c07c2b6aacab1d8c8bd043d89f4effe72ea2547c73c6366a2efab9c916945820fb880890bc085564e57ee76f7107a008f71e941e9fd631aec78f82e410ea9c893faa3d553cd1ca628af1087ca1b0c6aef3b66edcee14d1d7dc48293ddd7deed1ccbe487c957585abb9509151038d53f46b068e3e139c7689bf8e8d38669896b8d082e65e458e1f82b8e8ec926e7aa0f97d08526e9636f2c00af4c2bd3d8bffc4bb93cd47b09af18883e11b639d47938d036f7cfeb77db74a2c09a6dee9df98b18eff2fda7d3f4135083bb3b59e2172244ec37bdbdcfe6e199d36dc949cda1cca123fb2be07803d003d76af3d7164453df77d44c7f2599636ca44d0b7a46218326b0c814ed322b9c4279b060f1b9e14b70f55a3751c4343763cdbf9c14637d2210c59fbd037be17ea6706846fdc7b9ab90278c01c458e64442f9256f3ad1cbceb22959d495063aaca1a3959eae03":"fa3751":"eced7082ee6e916e753959e7dfbec00d9b424b64eb90eb2be7eb22e9c648674859bacc26d82edeeae158cc14beedcc19e713bb6dc71603e1c35cc22f799b29d34549221d0a5435852f14ac3ee77ef50eb69a495c31378b8b05dd73863a03eb9cb982b98f0c4a5fe766533f8ce3d7039410bf3c5aae5b49d0b3557b1692e8774b":"11aa09883b9f571237215bacf3ea7f100740a1bd72748804bca39e9ef8527692b5a8e1f94d255cab186edd16fbe76bb9d673ecef79f2614fc0bf4e2b3c28a93c39e6fb31de6c21dc93026f8ce717767d57bef1c91839568b9da11c1b48cd7e53e132ea7f9b12f80c3bc1a6b9ba1e7d234ffc4f251e6ada2588b21b457d9bedb51d14b1214144a81a3b987f00b20c6cbb314840363fb4a605495124abd45ac3d7e9d65e8b95dff0ba916d432749dfb24e5fadac418ff716097d86943a6bfa8dc5ff27dda853c63c1b2ce3383bd78197af3e30635d0ae65e203300ded374a790245cdf4d1640ba5d0da8d6ea35ba0263efde90c7b1a8ac1e3cd0f843e5fe57f681055de7ffea80e92af36bc183efaed08a5842f9bc8369626d60ab2c460de622b9b3c36e6e559787264abefaba843bf443cd9443eff990db82feece2cdb5e336f84f641176f82b41efa2377737089792b4a9596a32cad5450a5f6a93f947d249dd734be9b3cb6c825af53c27070eeb7c1713aa607fa89e44a542dac00b80bd246f":-1 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 2048] SHA224 PASS +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA224:"acfdfb1dcb1459b489cd4a8c9fab64a7da4f044bef1c506f0872e9476f3357abda509d9fb1db6a4f5306c40c058826253171cfedbc160776a48ec35b655bb9963286b6aece1c77dff987a0aae9720ba035dda67f317101bd3cd4e6caac867a8c38b87067938e96e72df1875f94e43e4c06f7a86a1dbe07836ee69763eee29bc13ca906d7740c29e651872a9ec7c6237f7c8290bb0800a030b323d09e7c903751d21a224266f9d6c94c17a4c0cd8175ea67b9d9020f2b3f31a96206084cddb2acef70b11ae25a46c4f6817c4813466d7cac76b27927145bd499ff87f22a946b688e980a00a3d54c72ab9c2c88a55a3ea4c6784068673532737cbe4799e98bd711":"b29bc5":"bb86906194b31fb6d28931febeb80d76747e427ea1628ef08c25ffb0":"7ced8a54c8e35ef5c87d03ee6357b658e2e528eda55ad30f14c88d0cd9895ea04ddf8fbb2fd703859c73cb9f3b07f4acb9e4a311753465f87c25c09bb74a0ebf633e8b7ec28aac4a10c8b22fb9098058c975a9d5a431ce9cf78627cdee3f5f3aa852a526e8c3004d0dc6e22544240164fcdf62c29a19b6006e32ea29e631fa18":"8c074bae48454875aefa2b7ea090d11d8860d7cbee5ee4c3ed02cb45aadb0b4516872b0e4521789d503b4e70092ca2a0c7a88efb7d74c63ce8dffcf06995af7c9567a8df05a01b243c5f3edcfa3922d06967bec9d0faad2c84486dd38602a416ef253e4a28f74ca290e4d743accccd204d8b136dd197e7a2f25a2707f339c6ba444c19bc047dff0584c479ab07c2ae68f219c3c430f19cae3f711c0efab8d09f85ab66ae948c357db67078a359b9c746d2d66b31486c83765ab097b540b5e6f626c9111a295855dff5c2acea102f6a29b9569909dad0d4c79a941a3e71b3137dc68ae2296b6f8175bfab205432e409be9075d12580b5c14924dd53c3d44745d7":0 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 2048] SHA224 FAIL(Format of the EM is incorrect - hash moved to left ) +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA224:"acfdfb1dcb1459b489cd4a8c9fab64a7da4f044bef1c506f0872e9476f3357abda509d9fb1db6a4f5306c40c058826253171cfedbc160776a48ec35b655bb9963286b6aece1c77dff987a0aae9720ba035dda67f317101bd3cd4e6caac867a8c38b87067938e96e72df1875f94e43e4c06f7a86a1dbe07836ee69763eee29bc13ca906d7740c29e651872a9ec7c6237f7c8290bb0800a030b323d09e7c903751d21a224266f9d6c94c17a4c0cd8175ea67b9d9020f2b3f31a96206084cddb2acef70b11ae25a46c4f6817c4813466d7cac76b27927145bd499ff87f22a946b688e980a00a3d54c72ab9c2c88a55a3ea4c6784068673532737cbe4799e98bd711":"b29bc5":"bb86906194b31fb6d28931febeb80d76747e427ea1628ef08c25ffb0":"c9a121fa15bffefb864fe3cfc2b1bf775886be3ff5151c40daee3c288dccf43ecfc02ba0cf8ca7cf9d4d206ee15e9947cd78f08f501eb36b8d3835b38bfee1f52e17cfbd66029513a6b66046988543e80f46ce1a3db3e30a2610c5b9540e7202ccee33d842e971cf89d0cadd4df0646204388167229e54238cbe14c450c44e6c":"7d081b0e38d73256476358c013908f3497810ac4bd5d76252f3ef440c5742ea552ef5348eccf6ef13afdf616288dbbf05a5b25e66a8745d9ddf66639ca89366e28062529e80b655b0268e922c8d77eb8ceee830fa14c15238dc1442dfdaffbf92436c794c24f6104374bf131616bcf4cca12608cee203e7eb0eba04556a0a0ac3dea9fa39dac8082e39f9a739955e036d0636008f5c3c4f823a5e6e5229fde6b94f986520de9b9a77ca34ccc0236762c77e33e105a9346553dc0e4469d3929ec38e8813a551af26b0f7d9dbb12d40b7d9fe195948e1ea1245362b01faeb4157605a9ab5158a7bc4df644f12121b03ee22e9f23fa5f40067b333b865bf3e41244":-1 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 2048] SHA256 PASS +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA256:"a47d04e7cacdba4ea26eca8a4c6e14563c2ce03b623b768c0d49868a57121301dbf783d82f4c055e73960e70550187d0af62ac3496f0a3d9103c2eb7919a72752fa7ce8c688d81e3aee99468887a15288afbb7acb845b7c522b5c64e678fcd3d22feb84b44272700be527d2b2025a3f83c2383bf6a39cf5b4e48b3cf2f56eef0dfff18555e31037b915248694876f3047814415164f2c660881e694b58c28038a032ad25634aad7b39171dee368e3d59bfb7299e4601d4587e68caaf8db457b75af42fc0cf1ae7caced286d77fac6cedb03ad94f1433d2c94d08e60bc1fdef0543cd2951e765b38230fdd18de5d2ca627ddc032fe05bbd2ff21e2db1c2f94d8b":"10e43f":"d66f72f10b69001a5b59cf1092ad274d5056c4e95ccccfbe3b530dcb027e57d6":"e002377affb04f0fe4598de9d92d31d6c786040d5776976556a2cfc55e54a1dcb3cb1b126bd6a4bed2a184990ccea773fcc79d246553e6c64f686d21ad4152673cafec22aeb40f6a084e8a5b4991f4c64cf8a927effd0fd775e71e8329e41fdd4457b3911173187b4f09a817d79ea2397fc12dfe3d9c9a0290c8ead31b6690a6":"4f9b425c2058460e4ab2f5c96384da2327fd29150f01955a76b4efe956af06dc08779a374ee4607eab61a93adc5608f4ec36e47f2a0f754e8ff839a8a19b1db1e884ea4cf348cd455069eb87afd53645b44e28a0a56808f5031da5ba9112768dfbfca44ebe63a0c0572b731d66122fb71609be1480faa4e4f75e43955159d70f081e2a32fbb19a48b9f162cf6b2fb445d2d6994bc58910a26b5943477803cdaaa1bd74b0da0a5d053d8b1dc593091db5388383c26079f344e2aea600d0e324164b450f7b9b465111b7265f3b1b063089ae7e2623fc0fda8052cf4bf3379102fbf71d7c98e8258664ceed637d20f95ff0111881e650ce61f251d9c3a629ef222d":0 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 1024] SHA256 FAIL(Format of the EM is incorrect - hash moved to left) +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA256:"ec996bc93e81094436fd5fc2eef511782eb40fe60cc6f27f24bc8728d686537f1caa82cfcfa5c323604b6918d7cd0318d98395c855c7c7ada6fc447f192283cdc81e7291e232336019d4dac12356b93a349883cd2c0a7d2eae9715f1cc6dd657cea5cb2c46ce6468794b326b33f1bff61a00fa72931345ca6768365e1eb906dd":"90c6d3":"2393183e18581e6924cd38f24192d1acc145633a":"f0b83b8facf6698d564bad334fe494aba3eea42f3cfc378455a989c4317e0f610c160a67527f5d010fe49b3fa6696516c757f3a99b79f0c641c68bb47e3fcb2cb01b22a5042246d5e9573c74c5d9b543e60b9e4dbbf3f36c44e0d410c750da3cc510abd12ca5cc0fceebb75912fc2e38e953cea30432e77e45408b607377e599":"7973359908f1cb2f7eb31e19f7655e8117261e17c43c8ce5b12bb861b541fea168e077b41cf11a95ef7a80edf5f5903987e59d4b9f115cdb3b6394eb0dcb6f5869be0f896087bec612093965ba020449eca36ea74acffe1eb9f42e4ef03247cccbf99557073ad99a144172669e49296980c9aeb5fc7fa64660a680c320edb20d":-1 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 1024] SHA384 PASS +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA384:"8b71c2bcb324a3fc23d292fb4f18cab5140d521013361a07071bc788859cbba33fc226b2cef9c1b3663d307acd3e4d8eb7acff63d048495a2d61fbeb617a42c4f424a347673173902cd1cb11780003e715662d195996fbff55f6b9feb54a18197e6848aa8baa15fa020cc54e72ec976d766ed63ee4e00071a11e29d7baf30e3f":"35c661":"fa785c07aac7933ad34b469f6a782de1fdf26b67":"aab88ff728c8f829841a14e56194bbf278d69f88317a81b4749aa5fdbc9383486e09bff96a2c5b5bdf392c4263438aef43334c33170ef4d89a76263cb9745f3fea74e35fbf91f722bb1351b56436cdd2992e61e6266753749611a9b449dce281c600e37251813446c1b16c858cf6ea6424cdc6e9860f07510f7417af925574d5":"657296e902331b8030a72920c6c16b22ea65fe18e7e10b7cdbb8a44ef0f4c66f3e9c22f8f35e4184b420ad3f1bdbc1d6a65e6230abca8a9bee10887833dae15a84bf09a4542389c685fd33e7385c6001b49aa108f2272a46a832bbadc067ff06b09b2f5f40c81cc2acac03311a3945f7a9f2ea81213ba9ba626d6a7ed49f17dd":0 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 3072] SHA384 FAIL(Message changed) +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA384:"fa15594057e21dfd0b41c921627809dd454b519cc1c4ea39883814f9cdeff4a184d10f641a5ced9a80de1623ee7f86567d953256f48dd68ccb2e8362173aeaab3f11182425924334f9b92092c0fdf1e3b4c17b5efbc0269a7d839683470112c425c4d77b8835e6a307d0189223894d74d809ddba7260fa22cf3eae11e58cb94bf61cff8faae7cf17643cacd709725814ec9c365366b3a721161d8c2092681520a23e888dc0fecdcbe61f0cf27f3ae99ebab6a459331cfb3626fcd34eb124adf5ad5cf6ab5af05e0956391cc6debbbd0d6270b8412f330d469c41b26bc0f261b9aaaf4178b55b21af6ba12dcec1b9c58e9eaf9747e37cf50878110aec5630fe3dd77217c35e55c48896207a8586354d058dd7028a386e474b7c736283c45662c4810f56c6d0ec8586397d499d59c0e0a8d640c25bb91f3fd2cc74801f2526f78ae49f42b279a1687b9a8e965b49fe10a2360852000f440117b84dd8cbb793c27f124ff88535a25ecf925d464efae566f81c8f43d23b646296c087fb56589ecebd":"e59685":"97ebc79827e22ccaac4476dfd5d2f04666119b4a8b4e2239":"4621b17cd9f5b623fe73b5fe280ce9ac840805608acd6e41d55ea71132220c0df7e7c4159626f10d71882983f0aa2a92d11dc906c0b22cc028f4395d48f54e12894e33da0f614dd48ee114e65f95c7a7d3585e7cc765c00178d136aa99591faaa35ee6136d2e323ffc855c709c5426b32fc0aa0ac66e90c96efe84414dd5e79c":"33bb9affe18723767ee34d8e40982c735099ef1806d8720e71d16fc2d6617a8cf301e992b6c5fc567aa971285cdb372c1934eccb1e83a6597011ad091aefc40db52a7cce970e3e2eee817a727beb9e5d137e64606279c36341c4a7e7488cea8c69af8a3e8497fcbd7679462a1aa15ae4b0d8ea321d4f7c54c75dadc64318cc99533297d9f5bdf4882e64ede175f32cd20081f996c52f288bd56dbc63fdbba190f1167081c95e37c0dbaad3506009660a3fd10d992a2968bfda881cec2cad19ddd852ab579abad0a9cf43c10b1758867dc0f25317d630fd154caf9a4b057d2abcd933748c7d87686c7661dab7b5990f32708183e494b243b862f4255ae02e2d2bfbf00f13d7cc2be7e1f16c43c94b500898de9afc7d4aa8cbb56a4128ec0159a1568c0ebdb819f49ca06b0f0686dfd920d6eff0a3a5e1d913d4ed44f9da20572c132965a958a139207e8900cba4d6b1157a57a4414011b412888cd1935c01e630410607db7852c174dc32b6312d22f541c453ccc07f7689113013c367f4889a7e":-1 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 1024] SHA512 PASS +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA512:"dab9c7d28a2b1e4995c12bcae3c9f580a2dd5372441888dc83aae5b515ebce3b95786c43b5811ebaee6ad90bff9e55ae1edccfc0fcafb4cfc43743749307ec0c36886c88a174d0156a2f88a25a5c594c558bf1a947335b1ab02e77bfeee5ab0cc25455819397f74d30ca31074d4612d9d928b66477ddf7b83c0cf4ee279c9071":"7b8267":"d44bee9eb335dc0fee17bb22e8dc9c35ce06c504":"b80271b3ef26efb5b0ca8e809b61fdd209337ac23fbaa349e84c8900c2fb072b97ba52f76fc1d00004322e1676fcad4140ffbc026b72ccdc01826013c53c63b421adbfd560482b1e1d884489fbd6e06597ac9fa1bbfbc347d5ca4147a72017763f25e1d62a84a718e513fa5f94b63f47f6814a26991c2f924a6c5423d06fcb79":"2db61ebaca89ecde29a2895f21d61220300f01d117337ba992e0e5a65d6c4a6bd537f6f74e64db2ea45c8892114d2d5450d9b9eb38dece3dadcbe91123a9ef8288e000bd3fc1e140d2499a7fdf44f3382e71d4def1baa6e40d8b70334906f895055295b8f37c779969975c11b79e2184321a883e1abcbc100273187ed1480a70":0 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001: Nist [mod = 2048] SHA512 FAIL ( Public Key e changed ) +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC001:CRYPT_MD_SHA512:"a677525e1a69546a96dc7b112350d5e4864f0f82e999a714fa9f43ac681517d3975910c2d806bb3ee6dbf5dba1d969b38889e113c2da76eef4412a60cbd89faf35b2bdcb0de36a2cb762cd8f2f29aed9982a9ab60886cc8fbfee9b2ae09c88161e9159d4fc833adc4f80e4bf629d5a9551acce7a3938630c2bf9956097642e3bc60ac6522017841b65c7a25197865e697753b08169853681911443a2b25f1b7c4696f946155b2664b67b40878d3b45c3e0d7034d5b5ee6f5ba8fb3cae7797e85789902cf8f9f86ed3ef25ae0736178aae260fe875bfef5bcde9ec05f11e18fc7375edcd4a5533618e6f991dd48aa3062e6031e291dfcdc6e7fc14ec60e539fcb":"eac839":"e536e467ed1f6a54ea19ebc7eb470ba6cd63ae16af600b42a74e0358b37fb0d3f3e8400015c904bb1091c47a15fc568ec27e6ea59ae4b892b2392451ace68245":"9c3d5d23d2746d15d616bebf3cf720c6e6012a71cae22002f5021a47d0b8636ca3bd201357e132a680fc5dec9b28a9db932d08ae8b3d3a37d7e2ee754b342a69b94fec26b50412289bcf77e6d4095faa545f15a16783d22eae21e18464150174e6db0b837347d440307655d56f0409db307f9773e81cb19282a93c9ca4c3b135":"98657fd8163967fa7d263bd45bb890035adbcdd1645fd48b28febfb9b4e15172540e38b7c2f673c40a205fd40b08b60b4b81ed6e236cdf08f0d6b11f50dc74c60dc466ac372e0f467883aa9a398f4aeef87b040e14a51502dd467e8e8dd89812dfaf6b1dc1c2f6c28448af084590c05aec499dd3b148e66f3d71cf75e239db6d21f4074b8bd9a6bde5ca668634bd47953276ff2d0ebbe01afcfe0e381903736d6a6c672a45fba4ee326e342dc5925169517c5f57e9290724576a225ba89cb4dd091f4e6513be10dd4181855bb4045d6ef6437c16d3b5589ef9d6836682711c7d66025ae37b525580f0dfcf3db7fe57d7c6b15777cc41600307e58a1721b6f7bc":-1 + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC002 Auto Salt Len Verify: Nist [mod = 4096] SHA256 +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC002:CRYPT_MD_SHA256:"cfcae49f88b80dc12186d53c57162dbecba6e348094f9fb3743e39d99d5355d87e3efca9d488d39d705671e58634309cbd7cf53fccd52d9a84edb99ffdad0680e9ec826d625728370717b39321c7d4b6882785cf6884275f6c7b6d681bfa710593679e99b67d5bc28121dd603617dc8cfdb2557c2a04533893f593f0f7e59cbe6d46623d22642a7161a4c685b293c7edcc9aaec48e3810ec74a884a41108610d000b591fbf5da44b5501e63781264edf3c73706321ecf44d0e14b5932a2d69ca3d180c5cee86b4ccad850c766e0beb5f20e6b142055d551aeb453bd099eac67eb92cf13e34ef0d0e34fc599a6e5d4d14f74e08190c66c66ad3473de9ae8f53dd2c1c0c41f4b4a8d4690f4b77354c76e05ab76b7a6c7c9edf0955fee799a2bb42c86c6a06631398d38cceb71ec9aaa9a0fb83850f62342f3f781f9d453229b1a709bbce83a44c225ebffd4f518f94a7935f4669f65d02ff3defbbd1d5efd9191365808cdf9460371ede1eae735af03f21431239d5cd57cc0cc88fb3965d187eba98359409aaa944a7af8e85e20b67c43c82e78fa967fc0d629bcd7483d17dcaa25915571a15c3f0c730e81095139d71a28858dd9d83b65bf9c9273a8a40b12a2c87107a71f984818f7dc766374d31b4c3a1d284adb2a17f8ac85dbe3f58cf78b14c0fdce00a79daf348aa0557290ef5f9dd305c15fa73d40c6822b75fda13ec43":"010001":"466d2621acc8a91c729334f1ca433bdb5605058d4851f86cc8c217fb9625c996f0d0dc64b635c987ccb63a95c0bbc94cac020b815e37cd5ab7c59dbd51eb8d0864123303eb5ef413028383b093daa41831b4364544ee701d67c56bea0eece0096cdc34e6946cb128dea117288cc753a8adc08ec2429d691ea06b8768154f4d01":"2e512f73d198e623afe019bd4cea9192ff8b24ab555099d31bd52d705fc808229a269bf749c8061a3dc7ffae9ef7c6bdcd8c34910f92f0a0fcd6d73017ca3388ca5e99a1735e005ff5d5eade3ec0ea0c2436f0e78b197c2d999ba4351b9e37a09195504b63a42762bea22d307a0328fc9c80acdc28fc8f4050e25fbd5890233028f97ea3a2669ff4d5f4232c1e48571499af28ed6f5a92e7936de39d913e12c5cef51e25f90a1e903f3f60a6a9cddbc56564b146aca6af6236b899c2cb7223a6941f0beaa3aa787b2333e4f3e66b334b99b90825153ebd0095f27691880f44e4e77135f26df376e261adfe0d8354cfa15b49138d624d9f62a9751221ee0598097891c9864ad3651e89723bc9ec6086f571e199619ceb6720ab5a4998254cb807dce75a5a5203d38a9f5d56adee4239ff50cefe3e927eba91de7e1f8e1ae8b0505c077788372af7d8ef00735cc531fd46dbe86702ac49171f0a921f4626442ae960e972a5594ee3bcbfbf687cd96ed300aa9df1b9487607b5bae0f1abecbc1d2291fe93b9f8a091ffac8469b0f00ba561f0628f5e004ed1fd8713650e147c4b2cab7f4d69a4ad57b145c1e5e4c1412e86fbbda5a6096f66293203207e35098bf94dafff75ed094d10e6034cd22179d94655004fa4bf4de774807b6f5cd27d90255468cf01db7b6f82607df597f72d1f9c9c91d17740a14a4816ae65e63fde480d" + +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC002 Auto Salt Len Verify: Nist [mod = 4096] SHA224 +SDV_CRYPTO_RSA_VERIFY_PSS_FUNC_TC002:CRYPT_MD_SHA224:"f650d9f361cf9cf7c1e99b028f392d545b5dc5999a09d22913a106412adca99b3686b3f8ef5178d1bb9b1504503a5f866b563a58c7dc42d8c8537503be0c181d6d050d47a869bf7830f3c85f0e5fcc910deffe1d914ae2f8d77e66e444c579e99770043af2c7f7d89458730e716f80ed5800f8f9751f6f59bde63b6515c96fa3":"6a3db1":"c728846980d2461db29343acbaa0e69e8a7ac11456cedcc190994d37178f0964acbefa5ca56f5259e54d1eff0bc91ee5eabcd4523a4edb448c187ab784857923427e33472146ed25a4a2664ead3eaf5ff04c3dcca86e3ddc88d627f5f5ab961a72af57b25c20c08bd7dc431e08c843158571250a09f4ab926d1c7d7ad3cb0950":"46acca5782d216e2f3d6f874a38b49b35c1e7a26626c9ad8af2c88a0e1d89495c02e1c476b3c8c86b0c6267683a16b3513d6ae5061a8c0557bd3cf0155df16369364da81bbf9f6d856b65add3290f5a7dc6e975812d1e680f7f24650d5c3f15ce90836b47db064b6494a68b95539eb2d5909bb033999c423ab14964a64c42efb" + +hitls sign and verify test 3072: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:3072:CRYPT_MD_SHA512:CRYPT_CTRL_SET_RSA_EMSA_PKCSV15:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 + +hitls sign and verify test 4096: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:4096:CRYPT_MD_SHA512:CRYPT_CTRL_SET_RSA_EMSA_PKCSV15:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 + +hitls sign and verify test 2048: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:2048:CRYPT_MD_SHA224:CRYPT_CTRL_SET_RSA_EMSA_PKCSV15:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 +hitls sign and verify test 2048: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:2048:CRYPT_MD_SHA256:CRYPT_CTRL_SET_RSA_EMSA_PKCSV15:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 +hitls sign and verify test 2048: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:2048:CRYPT_MD_SHA384:CRYPT_CTRL_SET_RSA_EMSA_PKCSV15:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 +hitls sign and verify test 2048: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:2048:CRYPT_MD_SHA512:CRYPT_CTRL_SET_RSA_EMSA_PKCSV15:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 + +hitls sign and verify test 2048: blinding +SDV_CRYPTO_RSA_BLINDING_FUNC_TC001:2048:CRYPT_MD_SHA256:CRYPT_CTRL_SET_RSA_EMSA_PSS:"e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":0 + +Rsa blinding, sign: Vectors from Rfc9474 +SDV_CRYPTO_RSA_BLINDING_FUNC_TC002:CRYPT_MD_SHA384:"e1f4d7a34802e27c7392a3cea32a262a34dc3691bd87f3f310dc75673488930559c120fd0410194fb8a0da55bd0b81227e843fdca6692ae80e5a5d414116d4803fca7d8c30eaaae57e44a1816ebb5c5b0606c536246c7f11985d731684150b63c9a3ad9e41b04c0b5b27cb188a692c84696b742a80d3cd00ab891f2457443dadfeba6d6daf108602be26d7071803c67105a5426838e6889d77e8474b29244cefaf418e381b312048b457d73419213063c60ee7b0d81820165864fef93523c9635c22210956e53a8d96322493ffc58d845368e2416e078e5bcb5d2fd68ae6acfa54f9627c42e84a9d3f2774017e32ebca06308a12ecc290c7cd1156dcccfb2311":"c601a9caea66dc3835827b539db9df6f6f5ae77244692780cd334a006ab353c806426b60718c05245650821d39445d3ab591ed10a7339f15d83fe13f6a3dfb20b9452c6a9b42eaa62a68c970df3cadb2139f804ad8223d56108dfde30ba7d367e9b0a7a80c4fdba2fd9dde6661fc73fc2947569d2029f2870fc02d8325acf28c9afa19ecf962daa7916e21afad09eb62fe9f1cf91b77dc879b7974b490d3ebd2e95426057f35d0a3c9f45f79ac727ab81a519a8b9285932d9b2e5ccd347e59f3f32ad9ca359115e7da008ab7406707bd0e8e185a5ed8758b5ba266e8828f8d863ae133846304a2936ad7bc7c9803879d2fc4a28e69291d73dbd799f8bc238385":"aec4d69addc70b990ea66a5e70603b6fee27aafebd08f2d94cbe1250c556e047a928d635c3f45ee9b66d1bc628a03bac9b7c3f416fe20dabea8f3d7b4bbf7f963be335d2328d67e6c13ee4a8f955e05a3283720d3e1f139c38e43e0338ad058a9495c53377fc35be64d208f89b4aa721bf7f7d3fef837be2a80e0f8adf0bcd1eec5bb040443a2b2792fdca522a7472aed74f31a1ebe1eebc1f408660a0543dfe2a850f106a617ec6685573702eaaa21a5640a5dcaf9b74e397fa3af18a2f1b7c03ba91a6336158de420d63188ee143866ee415735d155b7c2d854d795b7bc236cffd71542df34234221a0413e142d8c61355cc44d45bda94204974557ac2704cd8b593f035a5724b1adf442e78c542cd4414fce6f1298182fb6d8e53cef1adfd2e90e1e4deec52999bdc6c29144e8d52a125232c8c6d75c706ea3cc06841c7bda33568c63a6c03817f722b50fcf898237d788a4400869e44d90a3020923dc646388abcc914315215fcd1bae11b1c751fd52443aac8f601087d8d42737c18a3fa11ecd4131ecae017ae0a14acfc4ef85b83c19fed33cfd1cd629da2c4c09e222b398e18d822f77bb378dea3cb360b605e5aa58b20edc29d000a66bd177c682a17e7eb12a63ef7c2e4183e0d898f3d6bf567ba8ae84f84f1d23bf8b8e261c3729e2fa6d07b832e07cddd1d14f55325c6f924267957121902dc19b3b32948bdead5":"0d43242aefe1fb2c13fbc66e20b678c4336d20b1808c558b6e62ad16a287077180b177e1f01b12f9c6cd6c52630257ccef26a45135a990928773f3bd2fc01a313f1dac97a51cec71cb1fd7efc7adffdeb05f1fb04812c924ed7f4a8269925dad88bd7dcfbc4ef01020ebfc60cb3e04c54f981fdbd273e69a8a58b8ceb7c2d83fbcbd6f784d052201b88a9848186f2a45c0d2826870733e6fd9aa46983e0a6e82e35ca20a439c5ee7b502a9062e1066493bdadf8b49eb30d9558ed85abc7afb29b3c9bc644199654a4676681af4babcea4e6f71fe4565c9c1b85d9985b84ec1abf1a820a9bbebee0df1398aae2c85ab580a9f13e7743afd3108eb32100b870648fa6bc17e8abac4d3c99246b1f0ea9f7f93a5dd5458c56d9f3f81ff2216b3c3680a13591673c43194d8e6fc93fc1e37ce2986bd628ac48088bc723d8fbe293861ca7a9f4a73e9fa63b1b6d0074f5dea2a624c5249ff3ad811b6255b299d6bc5451ba7477f19c5a0db690c3e6476398b1483d10314afd38bbaf6e2fbdbcd62c3ca9797a420ca6034ec0a83360a3ee2adf4b9d4ba29731d131b099a38d6a23cc463db754603211260e99d19affc902c915d7854554aabf608e3ac52c19b8aa26ae042249b17b2d29669b5c859103ee53ef9bdc73ba3c6b537d5c34b6d8f034671d7f3a8a6966cc4543df223565343154140fd7391c7e7be03e241f4ecfeb877a051":"8417e699b219d583fb6216ae0c53ca0e9723442d02f1d1a34295527e7d929e8b8f3dc6fb8c4a02f4d6352edf0907822c1210a9b32f9bdda4c45a698c80023aa6b59f8cfec5fdbb36331372ebefedae7d" + +Rsa blinding, sign: Vectors from Nist +SDV_CRYPTO_RSA_BLINDING_FUNC_TC002:CRYPT_MD_SHA384:"ff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b40a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff764dd8b091f11a0943a2dd2b983b0df02f4c4d00b413":"dacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2179e04ec7":"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"1bf009caddc664b4404d59711fde16d7c55822449de1c5a084d22ed5791fdaa37ea538867fc91a17e6856e277c2dedd70ca8bf6ec44b0e729917a88e5988cc561d948ddeea46e21fd8ff46cce7657c94bfb1bdf40b3b30d4595a8bc3a15f1d4ad4c665c09b3b265ba19cdb0b89cbaadd0097ff52e9f6e594f86829c5bb4e9ba0200f12fa6dc60fd28dec0d194f08deb50f5a7749540160d6e8338e75b11165b76f4650c2fcce08f979ad9941daedaa5e328473bf712f8f549c36967f5e15477dc643d1f48d563139134e5cdc4bb84f9782cd5125e864e067cb980290f215cb41090e297bac2714efba61115d85613851c2de50a82f4ab526b88c61b7c9a0b589":"ffffff" + +Rsa key pair check: Nist, Pass +SDV_CRYPTO_RSA_KEY_PAIR_CHECK_FUNC_TC001:"d9f3094b36634c05a02ae1a5569035107a48029e39b3c6a1853817f063e18e761c0c538e55ff2c7e53d603bb35cabb3b8d07f82aa0afdeaf7441fcf6746c5bcaaa2cde398ad73edb9c340c3ffca559132581eaf8f65c13d02f3445a932a3e1fadb5912f7553edec5047e4d0ed06ee87effc549e194d38e06b73a971c961688ba2d4aa4f450d2523372f317d41d06f9f0360e962ce953a69f36c53c370799fcfba195e8f691ebe862f84ae4bbd7747bc14499bd0efffcdc7154325908355c2ffc5b3948b8102b33aa2420381470e4ee858380ff0eea58288516c263f6d51dbbd0e477d1393a0a3ee60e1fde4330856665bf522006608a6104c138c0f39e09c4c5":"0100000001":"1bf009caddc664b4404d59711fde16d7c55822449de1c5a084d22ed5791fdaa37ea538867fc91a17e6856e277c2dedd70ca8bf6ec44b0e729917a88e5988cc561d948ddeea46e21fd8ff46cce7657c94bfb1bdf40b3b30d4595a8bc3a15f1d4ad4c665c09b3b265ba19cdb0b89cbaadd0097ff52e9f6e594f86829c5bb4e9ba0200f12fa6dc60fd28dec0d194f08deb50f5a7749540160d6e8338e75b11165b76f4650c2fcce08f979ad9941daedaa5e328473bf712f8f549c36967f5e15477dc643d1f48d563139134e5cdc4bb84f9782cd5125e864e067cb980290f215cb41090e297bac2714efba61115d85613851c2de50a82f4ab526b88c61b7c9a0b589":1 + +Rsa key pair check: Nist, Fail +SDV_CRYPTO_RSA_KEY_PAIR_CHECK_FUNC_TC001:"b3fbc3c7ade18c5a706e93176b97f3a347b3aafc8bc1dd6927b2d716cc4a6fc22794c4bc340939df7cd6f93e9758039a68421e82eb3b9d5e1e8fe5f9cd8fad6001e860fc75e89ce0dd462b2dbec01343cad23ec586da873fbf35f6f8fc8b02ed47de98688c1531e87e299baff7c38abe11d3e5e78f5a7b8894dc671f22e36bcd6788ba67faab314c96b46844d41b938b83f7041be7f8f6e580a5df59c9aeb714120ba50a605e3902640b11d46e1654f6e31577d82775d20fa5318fd45359acf6d7ea6f3ea9c858db9024d1ff82cb5134bd34be3564bb1518d118c64e6eeab058890ff36fc189debbc0600102e3cef730713d6e9120abee07f9af452f8a020537":"0100000001":"1bf009caddc664b4404d59711fde16d7c55822449de1c5a084d22ed5791fdaa37ea538867fc91a17e6856e277c2dedd70ca8bf6ec44b0e729917a88e5988cc561d948ddeea46e21fd8ff46cce7657c94bfb1bdf40b3b30d4595a8bc3a15f1d4ad4c665c09b3b265ba19cdb0b89cbaadd0097ff52e9f6e594f86829c5bb4e9ba0200f12fa6dc60fd28dec0d194f08deb50f5a7749540160d6e8338e75b11165b76f4650c2fcce08f979ad9941daedaa5e328473bf712f8f549c36967f5e15477dc643d1f48d563139134e5cdc4bb84f9782cd5125e864e067cb980290f215cb41090e297bac2714efba61115d85613851c2de50a82f4ab526b88c61b7c9a0b589":0 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/scrypt/test_suite_sdv_eal_kdf_scrypt.c b/testcode/sdv/testcase/crypto/scrypt/test_suite_sdv_eal_kdf_scrypt.c new file mode 100644 index 00000000..5cdd5608 --- /dev/null +++ b/testcode/sdv/testcase/crypto/scrypt/test_suite_sdv_eal_kdf_scrypt.c @@ -0,0 +1,156 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "securec.h" +#include "crypt_eal_kdf.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +/* END_HEADER */ + +#define DATA_LEN (16) + +/** + * @test SDV_CRYPT_EAL_KDF_SCRYPT_API_TC001 + * @title CRYPT_EAL_Scrypt interface test. + * @precon nan + * @brief + * 1.Normal parameter test,the key and salt can be empty, expected result 1. + * 2.Abnormal parameter test,about the restriction, see the function declaration, expected result 2. + * @expect + * 1.Return CRYPT_SUCCESS. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_SCRYPT_API_TC001(void) +{ + TestMemInit(); + uint32_t keyLen = DATA_LEN; + uint8_t key[DATA_LEN]; + uint32_t saltLen = DATA_LEN; + uint8_t salt[DATA_LEN]; + uint32_t N = DATA_LEN; + uint32_t r = DATA_LEN; + uint32_t p = DATA_LEN; + uint32_t outLen = DATA_LEN; + uint8_t out[DATA_LEN]; + ASSERT_EQ(CRYPT_EAL_Scrypt(NULL, 0, salt, saltLen, N, r, p, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, 0, salt, saltLen, N, r, p, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Scrypt(NULL, keyLen, salt, saltLen, N, r, p, out, outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, NULL, 0, N, r, p, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, 0, N, r, p, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, NULL, saltLen, N, r, p, out, outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 0, r, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 3, r, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 4, r, p, out, outLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 6, r, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + // 65538 = 2^16 + 2 + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 65538, r, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 0, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, r, 0, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, r, p, NULL, outLen), CRYPT_SCRYPT_PARAM_ERROR); + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, r, p, out, 0), CRYPT_SCRYPT_PARAM_ERROR); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_KDF_SCRYPT_API_TC002 + * @title Parameters N, r, and p of the CRYPT_EAL_Scrypt interface test. + * @precon nan + * @brief +* 1.Abnormal parameter test,about the restriction, see the function declaration, expected result 1. + * @expect + * 1.The results are as expected,See Note. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_SCRYPT_API_TC002(void) +{ + // Parameter limitation: + // N < 2^(128 * r / 8) + // p <= ((2^32-1) * 32) / (128 * r). Equivalent to r * p <= 2^30 - 1 + // p * 128 * r < UINT32_MAX + // 32 * r * N * sizeof(uint32_t) < UINT32_MAX => N < ((UINT32_MAX / 128) / r) + // UINT32_MAX 0xffffffffU /* 4294967295U */ + TestMemInit(); + uint32_t keyLen = DATA_LEN; + uint8_t key[DATA_LEN]; + uint32_t saltLen = DATA_LEN; + uint8_t salt[DATA_LEN]; + uint32_t N = DATA_LEN; + uint32_t p = DATA_LEN; + uint32_t outLen = DATA_LEN; + uint8_t out[DATA_LEN]; + + // N is 2^16 = 65536, r is 1,Not satisfied N < 2^(128 * r / 8) + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 65536, 1, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // N is 2^15 = 32768, r is 1,satisfied N < 2^(128 * r / 8) + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 32768, 1, p, out, outLen), CRYPT_SUCCESS); + + // r = 2^16 = 65536, N = 2^9 = 512, Not satisfied N < ((UINT32_MAX / 128) / r) + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, 512, 65536, p, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // r is 2^16 = 65536, p is 2^16 = 65536, Not satisfied p <= ((2^32-1) * 32) / (128 * r) + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 65536, 65536, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // r = 2^16 = 65536, p = 2^14 = 16384, Not satisfied r * p <= 2^30 - 1 + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 65536, 16384, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // r = 2^16 = 65536, p = 2^9 = 512, Not satisfied p * 128 * r < UINT32_MAX + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 65536, 512, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // r = 2^8 = 256, p = 2^22 = 4194304, Not satisfied r * p <= 2^30 - 1 + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 256, 4194304, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // r = 2^4 = 16, p = 2^26 = 67108864, Not satisfied r * p <= 2^30 - 1 + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 16, 67108864, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); + + // r = 2^4 = 16, p = 2^21 = 2097152, Not satisfied p * 128 * r < UINT32_MAX + ASSERT_EQ(CRYPT_EAL_Scrypt(key, keyLen, salt, saltLen, N, 16, 2097152, out, outLen), CRYPT_SCRYPT_PARAM_ERROR); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_KDF_SCRYPT_API_TC001 + * @title CRYPT_EAL_Scrypt vector test. + * @precon nan + * @brief + * 1.Calculate the output using the given parameters, expected result 1. + * 2.Compare the calculated result with the standard value, expected result 2. + * @expect + * 1.Calculation succeeded.. + * 2.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_KDF_SCRYPT_FUN_TC001(Hex *key, Hex *salt, int N, int r, int p, Hex *result) +{ + TestMemInit(); + uint32_t outLen = result->len; + uint8_t *out = malloc(outLen * sizeof(uint8_t)); + ASSERT_TRUE(out != NULL); + ASSERT_EQ(CRYPT_EAL_Scrypt(key->x, key->len, salt->x, salt->len, N, r, p, out, outLen), CRYPT_SUCCESS); + ASSERT_COMPARE("result cmp", out, outLen, result->x, result->len); +exit: + if (out != NULL) { + free(out); + } +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/scrypt/test_suite_sdv_eal_kdf_scrypt.data b/testcode/sdv/testcase/crypto/scrypt/test_suite_sdv_eal_kdf_scrypt.data new file mode 100644 index 00000000..d4b6a3d7 --- /dev/null +++ b/testcode/sdv/testcase/crypto/scrypt/test_suite_sdv_eal_kdf_scrypt.data @@ -0,0 +1,14 @@ +SDV_CRYPT_EAL_KDF_SCRYPT_API_TC001 api test +SDV_CRYPT_EAL_KDF_SCRYPT_API_TC001: + +SDV_CRYPT_EAL_KDF_SCRYPT_API_TC002 N, r, p Parameters test +SDV_CRYPT_EAL_KDF_SCRYPT_API_TC002: + +Test vectors for rfc7914 scrypt #1 +SDV_CRYPT_EAL_KDF_SCRYPT_FUN_TC001:"":"":16:1:1:"77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906" + +Test vectors for rfc7914 scrypt #2 +SDV_CRYPT_EAL_KDF_SCRYPT_FUN_TC001:"70617373776f7264":"4e61436c":1024:8:16:"fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640" + +Test vectors for rfc7914 scrypt #3 +SDV_CRYPT_EAL_KDF_SCRYPT_FUN_TC001:"706c656173656c65746d65696e":"536f6469756d43686c6f72696465":16384:8:1:"7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887" diff --git a/testcode/sdv/testcase/crypto/sha1/test_suite_sdv_eal_md_sha1.c b/testcode/sdv/testcase/crypto/sha1/test_suite_sdv_eal_md_sha1.c new file mode 100644 index 00000000..d786b1aa --- /dev/null +++ b/testcode/sdv/testcase/crypto/sha1/test_suite_sdv_eal_md_sha1.c @@ -0,0 +1,350 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "eal_md_local.h" +#include "crypt_eal_md.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +/* END_HEADER */ + +#define SHA1_DIGEST_LEN (20) +#define DATA_MAX_LEN (65538) + +typedef struct { + uint8_t *data; + uint8_t *hash; + uint32_t dataLen; + uint32_t hashLen; +} ThreadParameter; + +void MultiThreadTest(void *arg) +{ + ThreadParameter *threadParameter = (ThreadParameter *)arg; + uint32_t outLen = SHA1_DIGEST_LEN; + uint8_t out[SHA1_DIGEST_LEN]; + CRYPT_EAL_MdCTX *ctx = NULL; + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA1); + ASSERT_TRUE(ctx != NULL); + for (uint32_t i = 0; i < 10; i++) { + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, threadParameter->data, threadParameter->dataLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + ASSERT_COMPARE("hash result cmp", out, outLen, threadParameter->hash, threadParameter->hashLen); + } + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} + +/** + * @test SDV_CRYPT_EAL_SHA1_API_TC001 + * @title Initialization interface test + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdInit and enter NULL, expected result 1. + * 2.Call CRYPT_EAL_MdNewCtx create ctx, expected result 2. + * 3.Call CRYPT_EAL_MdInit and use the correct ID. expected result 3. + * @expect + * 1.Initialization failed, return CRYPT_NULL_INPUT + * 2.The ctx is created successfully. + * 3.Initialization successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_MAX);; + ASSERT_TRUE(ctx == NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(NULL), CRYPT_NULL_INPUT); + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA1);; + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA1_API_TC002 + * @title CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal test + * @precon nan + * @brief + * 1.Invoke the CRYPT_EAL_MdNewCtx to create a CTX, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal before initialization, expected result 2 is obtained. + * 3.Initialize the CTX and transfer null pointers to CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal. expected result 3. + * 4.Invoke CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal normally, expected result 4. + * @expect + * 1.Successful, ctx is returned. + * 2.Return CRYPT_EAL_ERR_STATE + * 3.Return CRYPT_NULL_INPUT + * 4.Return CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_API_TC002(void) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + const uint32_t dataLen = SHA1_DIGEST_LEN; + uint8_t data[SHA1_DIGEST_LEN]; + uint32_t digestLen = SHA1_DIGEST_LEN; + uint8_t out[SHA1_DIGEST_LEN]; + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA1); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data, dataLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &digestLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(NULL, data, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, NULL, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data, dataLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(NULL, out, &digestLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, NULL, &digestLen), CRYPT_NULL_INPUT); + digestLen = SHA1_DIGEST_LEN - 1; + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &digestLen), CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH); + digestLen = SHA1_DIGEST_LEN; + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &digestLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + + +/** + * @test SDV_CRYPT_EAL_SHA1_API_TC003 + * @title Repeated hash calculation test + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create a CTX, expected result 1. + * 2.Calculate the hash, expected result 2. + * 3.Calculate the hash again, expected result 3. + * 4.Calculate the hash again, expected result 4. + * 5.Call CRYPT_EAL_MdFinal again, expected result 5. + * @expect + * 1.Successful, ctx is returned. + * 2.Obtains the hash of an empty string. + * 3.Obtains the hash of data + * 4.Obtains the hash of an empty string. + * 5.Return CRYPT_EAL_ERR_STATE. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_API_TC003(Hex *hash1, Hex *data2, Hex *hash2, Hex *hash3) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + uint32_t digestLen = SHA1_DIGEST_LEN; + uint8_t out[SHA1_DIGEST_LEN]; + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA1); + ASSERT_TRUE(ctx != NULL); + + // Hash calculation for the first time. + ASSERT_TRUE(CRYPT_EAL_MdInit(ctx) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_MdFinal(ctx, out, &digestLen) == CRYPT_SUCCESS); + ASSERT_COMPARE("hash1 result cmp", out, digestLen, hash1->x, hash1->len); + + // Hash calculation for the second time. + ASSERT_TRUE(CRYPT_EAL_MdInit(ctx) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_MdUpdate(ctx, data2->x, data2->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_MdFinal(ctx, out, &digestLen) == CRYPT_SUCCESS); + ASSERT_COMPARE("hash2 result cmp", out, digestLen, hash2->x, hash2->len); + + // Hash calculation for the third time. + ASSERT_TRUE(CRYPT_EAL_MdInit(ctx) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_MdFinal(ctx, out, &digestLen) == CRYPT_SUCCESS); + ASSERT_COMPARE("hash3 result cmp", out, digestLen, hash3->x, hash3->len); + + ASSERT_TRUE(CRYPT_EAL_MdFinal(ctx, out, &digestLen) == CRYPT_EAL_ERR_STATE); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA1_API_TC004 + * @title To test the function of obtaining the digest length of the hash algorithm. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdGetDigestSize,the input parameter ID is invalid, expected result 1. + * 2.Call CRYPT_EAL_MdGetDigestSize, Using CRYPT_MD_SHA1, expected result 2. + * @expect +* 1.Failed, return 0. + * 2.Success, return SHA1_DIGEST_LEN. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_API_TC004(void) +{ + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_MAX), 0); + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA1), SHA1_DIGEST_LEN); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA1_FUN_TC001 + * @title Perform the vector test to check whether the calculation result is consistent with the standard output. + * @precon nan + * @brief + * 1.Calculate the hash of each group of data, expected result 1. +* 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hash calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_FUN_TC001(Hex *data, Hex *hash) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + uint32_t digestLen = SHA1_DIGEST_LEN; + uint8_t out[SHA1_DIGEST_LEN]; + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA1); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data->x, data->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &digestLen), CRYPT_SUCCESS); + ASSERT_COMPARE("hash result cmp", out, digestLen, hash->x, hash->len); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA1_FUN_TC002 + * @title Test multi-thread hash calculation. + * @precon nan + * @brief + * 1.Create two threads and calculate the hash, expected result 1. + * 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hash calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_FUN_TC002(Hex *data, Hex *hash) +{ + int ret; + TestMemInit(); + const uint32_t threadNum = 2; + pthread_t thrd[2]; + ThreadParameter arg[2] = { + {data->x, hash->x, data->len, hash->len}, + {data->x, hash->x, data->len, hash->len} + }; + for (uint32_t i = 0; i < threadNum; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)MultiThreadTest, &arg[i]); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < threadNum; i++) { + pthread_join(thrd[i], NULL); + } + +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA1_FUN_TC003 + * @title Hash calculation for multiple updates,comparison with standard results. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create a ctx and initialize, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate to calculate the hash of a data segmentxpected result 2. + * 3.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 3. + * 4.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 4. + * 5.Call CRYPT_EAL_MdFinal get the result, expected result 5. + * @expect + * 1.Successful + * 2.Successful + * 3.Successful + * 4.Successful + * 5.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA1_FUN_TC003(Hex *plain_text1, Hex *plain_text2, Hex *plain_text3, Hex *hash) +{ + unsigned char output[SHA1_DIGEST_LEN]; + uint32_t outLen = SHA1_DIGEST_LEN; + + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA1); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, plain_text1->x, plain_text1->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, plain_text2->x, plain_text2->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, plain_text3->x, plain_text3->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, output, &outLen), CRYPT_SUCCESS); + + ASSERT_COMPARE("sha1", output, outLen, hash->x, hash->len); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SHA1_COPY_CTX_FUNC_TC001 + * @title SHA1 copy ctx function test. + * @precon nan + * @brief + * 1. Create the context ctx of md algorithm, expected result 1 + * 2. Call to CRYPT_EAL_MdCopyCtx method to copy ctx, expected result 2 + * 3. Calculate the hash of msg, and compare the calculated result with hash vector, expected result 3 + * @expect + * 1. Successful, the context is not null. + * 2. CRYPT_SUCCESS + * 3. Successful, the hashs are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SHA1_COPY_CTX_FUNC_TC001(int id, Hex *msg, Hex *hash) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *cpyCtx = NULL; + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + uint8_t output[SHA1_DIGEST_LEN]; + uint32_t outLen = SHA1_DIGEST_LEN; + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_MdCopyCtx(cpyCtx, ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdInit(cpyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(cpyCtx, msg->x, msg->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(cpyCtx, output, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(id, cpyCtx->id); + ASSERT_EQ(memcmp(output, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); + CRYPT_EAL_MdFreeCtx(cpyCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sha1/test_suite_sdv_eal_md_sha1.data b/testcode/sdv/testcase/crypto/sha1/test_suite_sdv_eal_md_sha1.data new file mode 100644 index 00000000..c3e4f518 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sha1/test_suite_sdv_eal_md_sha1.data @@ -0,0 +1,38 @@ +SDV_CRYPT_EAL_SHA1_API_TC001 create ctx and init test +SDV_CRYPT_EAL_SHA1_API_TC001: + +SDV_CRYPT_EAL_SHA1_API_TC002 Interface parameter test +SDV_CRYPT_EAL_SHA1_API_TC002: + +SDV_CRYPT_EAL_SHA1_API_TC003 CRYPT_EAL_MdInit CTX status change test +SDV_CRYPT_EAL_SHA1_API_TC003:"da39a3ee5e6b4b0d3255bfef95601890afd80709":"53":"02aa629c8b16cd17a44f3a0efec2feed43937642":"da39a3ee5e6b4b0d3255bfef95601890afd80709" + +SDV_CRYPT_EAL_SHA1_API_TC004 Obtaining the SHA1 Hash Digest Length +SDV_CRYPT_EAL_SHA1_API_TC004: + +SDV_CRYPT_EAL_SHA1_FUN_TC001 SHA-1 message Test Vector NIST CAVS +SDV_CRYPT_EAL_SHA1_FUN_TC001:"":"da39a3ee5e6b4b0d3255bfef95601890afd80709" + +SDV_CRYPT_EAL_SHA1_FUN_TC001 SHA-1 message Test Vector NIST CAVS +SDV_CRYPT_EAL_SHA1_FUN_TC001:"487351c8a5f440e4d03386483d5fe7bb669d41adcbfdb7":"dbc1cb575ce6aeb9dc4ebf0f843ba8aeb1451e89" + +SDV_CRYPT_EAL_SHA1_FUN_TC001 SHA-1 message Test Vector NIST CAVS +SDV_CRYPT_EAL_SHA1_FUN_TC001:"f2c76ef617fa2bfc8a4d6bcbb15fe88436fdc2165d3074629579079d4d5b86f5081ab177b4c3f530376c9c924cbd421a8daf8830d0940c4fb7589865830699":"9f3ea255f6af95c5454e55d7354cabb45352ea0b" + +SDV_CRYPT_EAL_SHA1_FUN_TC001 SHA-1 message Test Vector NIST CAVS +SDV_CRYPT_EAL_SHA1_FUN_TC001:"0321736beba578e90abc1a90aa56157d871618f6de0d764cc8c91e06c68ecd3b9de3824064503384db67beb7fe012232dacaef93a000fba7":"aef843b86916c16f66c84d83a6005d23fd005c9e" + +SDV_CRYPT_EAL_SHA1_FUN_TC001 SHA-1 message Test Vector NIST CAVS +SDV_CRYPT_EAL_SHA1_FUN_TC001:"892af4c05368aa9242acedd87d0fc68de483ab59520aea621f264b65ea90f005952c8163903d86ee5bd6147d4691ac9b7c8260213f6e370b7539d384649e5143ba23711ad04bf7cc2f0d512054857933b0ea1d12f3c0fe888a4e96356653fde000f50d0f9afac5d4c73aebe92d54f5ff8aa12a54f5660584674edaa17917bb856f8b9d6776b2b7ad2a462b015b67e8a71190cf0ecdca15a5121fe8ef245255da10cd694decdb96006017599066251ad34d9f54690452f59395ab0848f06c9186eaa3b8e785dd2a747297bdbdd4f5532a47b7008c21686ff7f8d881d464cd383205f6d45dc8203bb267ac9eb12f415a5406be1c9fac73497941909dba08dd12856aac03d83e0d916147404694fe70f8fa929ef0cc2edb4cc07abaa2236405e62820af8e806d0af32a1b3afb8dcaeaf5c4f43dc4392e074075aa3ed93601ab7ec22fe5bd7cdf802bb5ea8206c41a1619593385e00e3461ed3fda048a1c6639a0fca038d7f51cd8ffa9bc00af62765e2b62575c8b74c8501ac711f3fdfc1b15157e7a8f2612aa7838af999c3d8f6629f58669ac0f93733c91b557f579ffa9a9a4efc5d1f0fc13ca9e6e8a3efa7273e03d6e705cb292bc8d18b0b4f1484d975b17f88ae87edadf34f88f96ce2c3424e9ccc17454bd992cac786031d0b00d6d953540d0bb18d5942010b9c6341cfc02ad6a287e7c78d249ff796ed578fa68b4bec5709f320515bcf5ac95215812f39494de4b94bc2a639eefe282a9d26d85f33d902fff358fc1de1b95caaf2255416207f2d1c1fc1c74b0e57d43b3c6538db27c5e26f9acfc0183fa9301787b2f0df46c6c630a24972e0947105afd3df2a779e2f6fc947f95ff32fa6de28549e67fd32c15a8791ce1b8307e646e8f1d94fcd1d7225ad997a2e07383ed14dd76c3c186b0b54915cc":"20a3a677c117c61ed3bb19e2ac77f69987896d0b" + +SDV_CRYPT_EAL_SHA1_FUN_TC002 Multithreading test +SDV_CRYPT_EAL_SHA1_FUN_TC002:"f2c76ef617fa2bfc8a4d6bcbb15fe88436fdc2165d3074629579079d4d5b86f5081ab177b4c3f530376c9c924cbd421a8daf8830d0940c4fb7589865830699":"9f3ea255f6af95c5454e55d7354cabb45352ea0b" + +SDV_CRYPT_EAL_SHA1_FUN_TC003 SHA-1 Multi Block Test1 +SDV_CRYPT_EAL_SHA1_FUN_TC003:"f2c76ef6":"17fa2bfc8a4d6bcbb15fe88436fdc2165d3074629579079d4d5b86f5081ab177":"b4c3f530376c9c924cbd421a8daf8830d0940c4fb7589865830699":"9f3ea255f6af95c5454e55d7354cabb45352ea0b" + +SDV_CRYPT_EAL_SHA1_FUN_TC003 SHA-1 Multi Block Test2 +SDV_CRYPT_EAL_SHA1_FUN_TC003:"892af4c053":"68aa9242acedd87d0fc68de483ab59520aea621f264b65ea90f005952c8163903d86ee5bd6147d4691ac9b7c8260213f6e370b7539d384649e5143ba23711ad04bf7cc2f0d512054857933b0ea1d12f3c0fe888a4e96356653fde000f50d0f9afac5d4c73aebe92d54f5ff8aa12a54f5660584674edaa17917bb856f8b9d6776b2b7ad2a462b015b67e8a71190cf0ecdca15a5121fe8ef245255da10cd694decdb96006017599066251ad34d9f54690452f59395ab0848f06c9186eaa3b8e785dd2a747297bdbdd4f5532a47b7008c21686ff7f8d881d464cd383205f6d45dc8203bb267ac9eb12f415a5406be1c9fac73497941909dba08dd12856aac03d83e0d916147404694fe70f8fa929ef0cc2edb4cc07abaa2236405e62820af8e806d0af32a1b3afb8dcaeaf5c4f43dc4392e074075aa3ed93601ab7ec22fe5bd7cdf802bb5ea8206c41a1619593385e00e3461ed3fda048a1c6639a0fca038d7f51cd8ffa9bc00af62765e2b62575c8b74c8501ac711f3fdfc1b15157e7a8f2612aa7838af999c3d8f6629f58669ac0f93733c91b557f579ffa9a9a4efc5d1f0fc13ca9e6e8a3efa7273e03d6e705cb292bc8d18b0b4f1484d975b17f88ae87edadf34f88f96ce2c3424e9ccc17454bd992cac786031d0b00d6d953540d0bb18d5942010b9c6341cfc02ad6a287e7c78d249ff796ed578fa68b4bec5709f320515bcf5ac95215812f39494de4b94bc2a639eefe282a9d26d85f33d902fff358fc1de1b95caaf2255416207f2d1c1fc1c74b0e57d43b3c6538db27c5e26f9acfc0183fa9301787b2f0df46c6c630a24972e0947105afd3df2a779e2f6fc947f95ff32fa6de28549e67fd32c15a8791ce1b8307e646e8f1d94fcd1d7225ad997a2e07383ed14dd76c3c186b0b5":"4915cc":"20a3a677c117c61ed3bb19e2ac77f69987896d0b" + +SDV_CRYPTO_SHA1_COPY_CTX_FUNC_TC001 Copy ctx +SDV_CRYPTO_SHA1_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA1:"487351c8a5f440e4d03386483d5fe7bb669d41adcbfdb7":"dbc1cb575ce6aeb9dc4ebf0f843ba8aeb1451e89" \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/sha2/test_suite_sdv_eal_md_sha2.c b/testcode/sdv/testcase/crypto/sha2/test_suite_sdv_eal_md_sha2.c new file mode 100644 index 00000000..94f9a235 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sha2/test_suite_sdv_eal_md_sha2.c @@ -0,0 +1,419 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "eal_md_local.h" +#include "crypt_eal_md.h" +#include "crypt_errno.h" +#include "bsl_sal.h" +/* END_HEADER */ + +// 100 is greater than the digest length of all SHA algorithms. +#define SHA2_OUTPUT_MAXSIZE 100 + +typedef struct { + uint8_t *data; + uint8_t *hash; + uint32_t dataLen; + uint32_t hashLen; + CRYPT_MD_AlgId id; +} ThreadParameter; + +void Sha2MultiThreadTest(void *arg) +{ + ThreadParameter *threadParameter = (ThreadParameter *)arg; + uint32_t outLen = SHA2_OUTPUT_MAXSIZE; + uint8_t out[SHA2_OUTPUT_MAXSIZE]; + CRYPT_EAL_MdCTX *ctx = NULL; + ctx = CRYPT_EAL_MdNewCtx(threadParameter->id); + ASSERT_TRUE(ctx != NULL); + for (uint32_t i = 0; i < 10; i++) { // Repeat 10 times + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, threadParameter->data, threadParameter->dataLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + ASSERT_COMPARE("hash result cmp", out, outLen, threadParameter->hash, threadParameter->hashLen); + } + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} + +/** + * @test SDV_CRYPT_EAL_SHA2_API_TC001 + * @title Create sha2 context test. + * @precon nan + * @brief + * 1.Create context with invalid id, expected result 1. + * 2.Create context using CRYPT_MD_SHA224 CRYPT_MD_SHA256 CRYPT_MD_SHA384 CRYPT_MD_SHA512, expected result 2. + * @expect + * 1.The result is NULL. + * 2.Create successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA2_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + + ctx = CRYPT_EAL_MdNewCtx(-1); + ASSERT_TRUE(ctx == NULL); + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_MAX); + ASSERT_TRUE(ctx == NULL); + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA224); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_MdFreeCtx(ctx); + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_MdFreeCtx(ctx); + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA384); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_MdFreeCtx(ctx); + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA512); + ASSERT_TRUE(ctx != NULL); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA2_API_TC002 + * @title SHA2 get the digest length test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdGetDigestSize to get the digest length, expected result 1. + * @expect + * 1.The value is the same as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA2_API_TC002(void) +{ + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(-1), 0); + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_MAX), 0); + // The length of the SHA224 digest is 28 characters. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA224), 28); + // The length of the SHA256 digest is 32 characters. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA256), 32); + // The length of the SHA384 digest is 48 characters. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA384), 48); + // The length of the SHA512 digest is 64 characters. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA512), 64); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA2_API_TC003 + * @title update and final test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal before initialization, expected result 2. + * 3.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal use null pointer, expected result 3. + * 4.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal normally, expected result 4. + * @expect + * 1.Create successful. + * 2.Return CRYPT_EAL_ERR_STATE. + * 3.Return CRYPT_NULL_INPUT. + * 4.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA2_API_TC003(int id) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + + uint8_t input[SHA2_OUTPUT_MAXSIZE]; + const uint32_t inLen = SHA2_OUTPUT_MAXSIZE; + + uint8_t out[SHA2_OUTPUT_MAXSIZE]; + uint32_t validOutLen = CRYPT_EAL_MdGetDigestSize(id); + uint32_t invalidOutLen = validOutLen - 1; + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &validOutLen), CRYPT_EAL_ERR_STATE); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(NULL, input, inLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, NULL, inLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(NULL, out, &validOutLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, NULL, &validOutLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, NULL), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &invalidOutLen), CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &validOutLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdGetId(ctx), id); + ASSERT_EQ(CRYPT_EAL_MdDeinit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdIsValidAlgId(id), true); +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001 + * @title Split the data and update test. + * @precon nan + * @brief + * 1.Create two ctx and initialize them, expected result 1. + * 2.Use ctx1 to update data 100 times, expected result 2. + * 3.Use ctx2 to update all data at once, expected result 3. + * 4.Compare two outputs, expected result 4. + * @expect + * 1.Successful. + * 2.Successful. + * 3.Successful. + * 4.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001(int id) +{ + if (IsMdAlgDisabled(id)) { + SKIP_TEST(); + } + TestMemInit(); + CRYPT_EAL_MdCTX *ctx1 = NULL; + CRYPT_EAL_MdCTX *ctx2 = NULL; + + ctx1 = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx1 != NULL); + + ctx2 = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx2 != NULL); + + // 100! = 5050 + uint8_t input[5050]; + uint32_t inLenTotal = 0; + uint32_t inLenBase; + uint8_t out1[SHA2_OUTPUT_MAXSIZE]; + uint8_t out2[SHA2_OUTPUT_MAXSIZE]; + uint32_t outLen = CRYPT_EAL_MdGetDigestSize(id); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx2), CRYPT_SUCCESS); + + for (inLenBase = 1; inLenBase <= 100; inLenBase++) { + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx1, input + inLenTotal, inLenBase), CRYPT_SUCCESS); + inLenTotal += inLenBase; + } + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx1, out1, &outLen), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_MdGetDigestSize(id); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx2, input, inLenTotal), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx2, out2, &outLen), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_MdGetDigestSize(id); + + ASSERT_COMPARE("sha2", out1, outLen, out2, outLen); + +exit: + CRYPT_EAL_MdFreeCtx(ctx1); + CRYPT_EAL_MdFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_MD_SHA2_FUNC_TC002 + * @title Empty string test. + * @precon nan + * @brief + * 1.Create ctx and initialize it, expected result 1. + * 2.Call CRYPT_EAL_MdFinal to get the output, expected result 2. + * 3.Compare output and vectors, expected result 3. + * @expect + * 1.Successful. + * 2.Successful. + * 3.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_MD_SHA2_FUNC_TC002(int id, Hex *digest) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + + uint8_t out[SHA2_OUTPUT_MAXSIZE]; + uint32_t outLen = CRYPT_EAL_MdGetDigestSize(id); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + + ASSERT_COMPARE("sha2", out, outLen, digest->x, digest->len); +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003 + * @title standard vector test. + * @precon nan + * @brief + * Calculate the hash of the data and compare it with the standard vector. + * @expect + * The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003(int algId, Hex *in, Hex *digest) +{ + if (IsMdAlgDisabled(algId)) { + SKIP_TEST(); + } + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + + uint8_t out[SHA2_OUTPUT_MAXSIZE]; + uint32_t outLen = CRYPT_EAL_MdGetDigestSize(algId); + + ctx = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, in->x, in->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + + ASSERT_COMPARE("sha2", out, outLen, digest->x, digest->len); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004 + * @title Hash calculation for multiple updates,comparison with standard results. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create a ctx and initialize, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate to calculate the hash of a data segmentxpected result 2. + * 3.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 3. + * 4.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 4. + * 5.Call CRYPT_EAL_MdFinal get the result, expected result 5. + * @expect + * 1.Successful + * 2.Successful + * 3.Successful + * 4.Successful + * 5.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004(int algId, Hex *plain_text1, Hex *plain_text2, Hex *plain_text3, Hex *hash) +{ + // 100 is greater than the digest length of all SHA algorithms. + unsigned char output[SHA2_OUTPUT_MAXSIZE]; + uint32_t outLen = SHA2_OUTPUT_MAXSIZE; + + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, plain_text1->x, plain_text1->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, plain_text2->x, plain_text2->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, plain_text3->x, plain_text3->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, output, &outLen), CRYPT_SUCCESS); + + ASSERT_COMPARE("sha2", output, outLen, hash->x, hash->len); +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_MD_SHA2_FUNC_TC005 + * @title Test multi-thread hash calculation. + * @precon nan + * @brief + * 1.Create two threads and calculate the hash, expected result 1. + * 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hash calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_MD_SHA2_FUNC_TC005(int algId, Hex *data, Hex *hash) +{ + int ret; + TestMemInit(); + const uint32_t threadNum = 2; + pthread_t thrd[2]; + ThreadParameter arg[2] = { + {data->x, hash->x, data->len, hash->len, algId}, + {data->x, hash->x, data->len, hash->len, algId} + }; + for (uint32_t i = 0; i < threadNum; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)Sha2MultiThreadTest, &arg[i]); + ASSERT_EQ(ret, 0); + } + for (uint32_t i = 0; i < threadNum; i++) { + pthread_join(thrd[i], NULL); + } + +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001 + * @title SHA2 copy ctx function test. + * @precon nan + * @brief + * 1. Create the context ctx of md algorithm, expected result 1 + * 2. Call to CRYPT_EAL_MdCopyCtx method to copy ctx, expected result 2 + * 3. Calculate the hash of msg, and compare the calculated result with hash vector, expected result 3 + * @expect + * 1. Successful, the context is not null. + * 2. CRYPT_SUCCESS + * 3. Successful, the hashs are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001(int id, Hex *msg, Hex *hash) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *cpyCtx = NULL; + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + uint8_t output[SHA2_OUTPUT_MAXSIZE]; + uint32_t outLen = SHA2_OUTPUT_MAXSIZE; + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_MdCopyCtx(cpyCtx, ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdInit(cpyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(cpyCtx, msg->x, msg->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(cpyCtx, output, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(id, cpyCtx->id); + ASSERT_EQ(memcmp(output, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); + CRYPT_EAL_MdFreeCtx(cpyCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sha2/test_suite_sdv_eal_md_sha2.data b/testcode/sdv/testcase/crypto/sha2/test_suite_sdv_eal_md_sha2.data new file mode 100644 index 00000000..47f390d6 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sha2/test_suite_sdv_eal_md_sha2.data @@ -0,0 +1,131 @@ +CRYPT_EAL_MdNewCtx Test +SDV_CRYPT_EAL_SHA2_API_TC001: + +CRYPT_EAL_MdGetDigestSize Test +SDV_CRYPT_EAL_SHA2_API_TC002: + +CRYPT_EAL_MdUpdate And CRYPT_EAL_MdFinal Test +SDV_CRYPT_EAL_SHA2_API_TC003:CRYPT_MD_SHA224 + +CRYPT_EAL_MdUpdate And CRYPT_EAL_MdFinal Test +SDV_CRYPT_EAL_SHA2_API_TC003:CRYPT_MD_SHA256 + +CRYPT_EAL_MdUpdate And CRYPT_EAL_MdFinal Test +SDV_CRYPT_EAL_SHA2_API_TC003:CRYPT_MD_SHA384 + +CRYPT_EAL_MdUpdate And CRYPT_EAL_MdFinal Test +SDV_CRYPT_EAL_SHA2_API_TC003:CRYPT_MD_SHA512 + +MD 100 updates then final SHA224 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001:CRYPT_MD_SHA224 + +MD 100 updates then final SHA256 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001:CRYPT_MD_SHA256 + +MD 100 updates then final SHA384 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001:CRYPT_MD_SHA384 + +MD 100 updates then final SHA512 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001:CRYPT_MD_SHA512 + +MD Work Flow Test Init Final without Update SHA224 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC002:CRYPT_MD_SHA224:"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" + +MD Work Flow Test Init Final without Update SHA256 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC002:CRYPT_MD_SHA256:"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + +MD Work Flow Test Init Final without Update SHA384 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC002:CRYPT_MD_SHA384:"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" + +MD Work Flow Test Init Final without Update SHA512 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC002:CRYPT_MD_SHA512:"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + +MD SHA224 NIST Vector Zero Len Msg +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA224:"":"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" + +MD SHA224 NIST Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA224:"84":"3cd36921df5d6963e73739cf4d20211e2d8877c19cff087ade9d0e3a" + +MD SHA224 NIST Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA224:"a4bc10b1a62c96d459fbaf3a5aa3face73":"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1" + +MD SHA224 NIST Vector #3 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA224:"a8e729d336d5d6ac50e1e22f0b193b66e26042fc6459214129875e740ab2b142918c138aaf941863ad3b7e6065450613b273":"452bf2e5ebfc4e451cc434bc09e2a10032eed0b7627cf55e7e5ed0e2" + +MD SHA224 Multi Block Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA224:"a4bc10":"":"b1a62c96d459fbaf3a5aa3face73":"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1" + +MD SHA224 Multi Block Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA224:"a8e7":"29d336d5d6ac50":"e1e22f0b193b66e26042fc6459214129875e740ab2b142918c138aaf941863ad3b7e6065450613b273":"452bf2e5ebfc4e451cc434bc09e2a10032eed0b7627cf55e7e5ed0e2" + +MD SHA256 NIST Vector Zero Len Msg +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA256:"":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + +MD SHA256 NIST Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA256:"d3":"28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1" + +MD SHA256 NIST Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA256:"1b503fb9a73b16ada3fcf1042623ae7610":"d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509" + +MD SHA256 NIST Vector #3 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA256:"3d83df37172c81afd0de115139fbf4390c22e098c5af4c5ab4852406510bc0e6cf741769f44430c5270fdae0cb849d71cbab":"99dc772e91ea02d9e421d552d61901016b9fd4ad2df4a8212c1ec5ba13893ab2" + +MD SHA256 Multi Block Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA256:"1b503fb9a73b16ada3fcf1042623":"":"ae7610":"d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509" + +MD SHA256 Multi Block Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA256:"3d83df37":"172c81afd0de115139fbf4390c22e098c5af4c5ab4852406510bc0e6cf741769f44430c5270fdae0cb849d":"71cbab":"99dc772e91ea02d9e421d552d61901016b9fd4ad2df4a8212c1ec5ba13893ab2" + +MD SHA384 NIST Vector Zero Len Msg +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA384:"":"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" + +MD SHA384 NIST Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA384:"c5":"b52b72da75d0666379e20f9b4a79c33a329a01f06a2fb7865c9062a28c1de860ba432edfd86b4cb1cb8a75b46076e3b1" + +MD SHA384 NIST Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA384:"bb84a014cd17cc232c98ae8b0709917e9d":"85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263" + +MD SHA384 NIST Vector #3 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA384:"f7b577f1396b23c27eb637e53d3d92460270b001cc612fd3b4d68bcdd09c2d50571ea4350636324cc2428a087e7bd8785f82":"80afe111e44ad9aff9e39c4cf9e6b4c520072b4550e62b1740160a04f8d530612dc098917a556b44977d0e73df518bee" + +MD SHA384 Multi Block Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA384:"bb84":"":"a014cd17cc232c98ae8b0709917e9d":"85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263" + +MD SHA384 Multi Block Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA384:"f7b577f139":"6b23c27e":"b637e53d3d92460270b001cc612fd3b4d68bcdd09c2d50571ea4350636324cc2428a087e7bd8785f82":"80afe111e44ad9aff9e39c4cf9e6b4c520072b4550e62b1740160a04f8d530612dc098917a556b44977d0e73df518bee" + +MD SHA512 NIST Vector Zero Len Msg +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA512:"":"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + +MD SHA512 NIST Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA512:"21":"3831a6a6155e509dee59a7f451eb35324d8f8f2df6e3708894740f98fdee23889f4de5adb0c5010dfb555cda77c8ab5dc902094c52de3278f35a75ebc25f093a" + +MD SHA512 NIST Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA512:"6ba004fd176791efb381b862e298c67b08":"112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe" + +MD SHA512 NIST Vector #3 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC003:CRYPT_MD_SHA512:"317e5d9ac73ed0633fa18ebebbca7909ec3a5ef790478f9c38cacec44f196d895835b425774483043341381e7af2d383e51a":"b10bb04491b9c0c334709b407cda1d503efb6b63ee944f2d366b6855e6e63e5b80115be4be7ff63edecdfb5923792e68123976d79212b3884dec2179d1fcf382" + +MD SHA512 Multi Block Vector #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA512:"6ba004fd17":"":"6791efb381b862e298c67b08":"112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe" + +MD SHA512 Multi Block Vector #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC004:CRYPT_MD_SHA512:"317e5d9ac73ed0":"633fa18ebebbca7909ec3a5ef790478f9c38cacec44f196d895835b425774483043341381e7af2":"d383e51a":"b10bb04491b9c0c334709b407cda1d503efb6b63ee944f2d366b6855e6e63e5b80115be4be7ff63edecdfb5923792e68123976d79212b3884dec2179d1fcf382" + +sha2 multi-thread test #1 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC005:CRYPT_MD_SHA224:"a4bc10b1a62c96d459fbaf3a5aa3face73":"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1" + +sha2 multi-thread test #2 +SDV_CRYPT_EAL_MD_SHA2_FUNC_TC005:CRYPT_MD_SHA512:"6ba004fd176791efb381b862e298c67b08":"112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe" + +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001 SHA224 +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA224:"a4bc10b1a62c96d459fbaf3a5aa3face73":"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1" + +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001 SHA256 +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA256:"1b503fb9a73b16ada3fcf1042623ae7610":"d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509" + +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001 SHA384 +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA384:"bb84a014cd17cc232c98ae8b0709917e9d":"85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263" + +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001 SHA512 +SDV_CRYPTO_SHA2_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA512:"6ba004fd176791efb381b862e298c67b08":"112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe" diff --git a/testcode/sdv/testcase/crypto/sha3/test_suite_sdv_eal_md_sha3.c b/testcode/sdv/testcase/crypto/sha3/test_suite_sdv_eal_md_sha3.c new file mode 100644 index 00000000..0e0b7c0f --- /dev/null +++ b/testcode/sdv/testcase/crypto/sha3/test_suite_sdv_eal_md_sha3.c @@ -0,0 +1,339 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "crypt_eal_md.h" +#include "bsl_sal.h" +#include "eal_md_local.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "crypt_sha3.h" +#include "securec.h" +/* END_HEADER */ + +// 100 is greater than the digest length of all SHA algorithms. +#define SHA3_OUTPUT_MAXSIZE 100 + +typedef struct { + uint8_t *data; + uint8_t *hash; + uint32_t dataLen; + uint32_t hashLen; + CRYPT_MD_AlgId id; +} ThreadParameter; + +void Sha3MultiThreadTest(void *arg) +{ + ThreadParameter *threadParameter = (ThreadParameter *)arg; + uint32_t outLen = SHA3_OUTPUT_MAXSIZE; + uint8_t out[SHA3_OUTPUT_MAXSIZE]; + CRYPT_EAL_MdCTX *ctx = NULL; + ctx = CRYPT_EAL_MdNewCtx(threadParameter->id); + ASSERT_TRUE(ctx != NULL); + for (uint32_t i = 0; i < 10; i++) { + ASSERT_TRUE(CRYPT_EAL_MdInit(ctx) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_MdUpdate(ctx, threadParameter->data, threadParameter->dataLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_MdFinal(ctx, out, &outLen) == CRYPT_SUCCESS); + ASSERT_COMPARE("hash result cmp", out, outLen, threadParameter->hash, threadParameter->hashLen); + } + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} + +/** + * @test SDV_CRYPT_EAL_SHA3_API_TC001 + * @title SHA3 get the digest length test. + * @precon nan + * @brief + * Call CRYPT_EAL_MdGetDigestSize to get the digest length. + * @expect + * The results are correct. + * + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA3_API_TC001(void) +{ + // The length of the SHA3_224 digest is 28. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA3_224), 28); + + // The length of the SHA3_256 digest is 32. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA3_256), 32); + + // The length of the SHA3_384 digest is 48. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA3_384), 48); + + // The length of the SHA3_512 digest is 64. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHA3_512), 64); + + // The length of the SHAKE128 digest is 0. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHAKE128), 0); + + // The length of the SHAKE256 digest is 0. + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SHAKE256), 0); +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA3_API_TC002 + * @title update and final test. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx create the CTX, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal before initialization, expected result 2. + * 3.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal use null pointer, expected result 3. + * 4.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal normally, expected result 4. + * @expect + * 1.Create successful. + * 2.Return CRYPT_EAL_ERR_STATE. + * 3.Return CRYPT_NULL_INPUT. + * 4.Successful. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA3_API_TC002(int algId) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *sha3Ctx = NULL; + uint8_t data[10] = {0x0e}; + uint32_t dataLen = 1; + uint8_t output[SHA3_OUTPUT_MAXSIZE]; + uint32_t outLen = SHA3_OUTPUT_MAXSIZE; + + sha3Ctx = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(sha3Ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdUpdate(sha3Ctx, data, dataLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdFinal(sha3Ctx, output, &outLen), CRYPT_EAL_ERR_STATE); + + ASSERT_EQ(CRYPT_EAL_MdInit(sha3Ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(NULL, data, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(sha3Ctx, NULL, dataLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(sha3Ctx, data, dataLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(NULL, output, &outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(sha3Ctx, NULL, &outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(sha3Ctx, output, NULL), CRYPT_NULL_INPUT); + + outLen = CRYPT_EAL_MdGetDigestSize(algId) - 1; + ASSERT_EQ(CRYPT_EAL_MdFinal(sha3Ctx, output, &outLen), CRYPT_SHA3_OUT_BUFF_LEN_NOT_ENOUGH); + + outLen = CRYPT_EAL_MdGetDigestSize(algId); + ASSERT_EQ(CRYPT_EAL_MdFinal(sha3Ctx, output, &outLen), CRYPT_SUCCESS); +exit: + CRYPT_EAL_MdFreeCtx(sha3Ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA3_FUNC_TC001 + * @title Split the data and update test. + * @precon nan + * @brief + * 1.Create two ctx and initialize them, expected result 1. + * 2.Use ctx1 to update data 100 times, expected result 2. + * 3.Use ctx2 to update all data at once, expected result 3. + * 4.Compare two outputs, expected result 4. + * @expect + * 1.Successful. + * 2.Successful. + * 3.Successful. + * 4.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA3_FUNC_TC001(int algId) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx1 = NULL; + CRYPT_EAL_MdCTX *ctx2 = NULL; + + ctx1 = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(ctx1 != NULL); + + ctx2 = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(ctx2 != NULL); + + // 100! = 5050 + uint8_t input[5050]; + uint32_t inLenTotal = 0; + + uint32_t inLenBase; + + uint8_t out1[SHA3_OUTPUT_MAXSIZE]; // 100 is greater than the digest length of all SHA algorithms. + uint8_t out2[SHA3_OUTPUT_MAXSIZE]; + uint32_t outLen = CRYPT_EAL_MdGetDigestSize(algId); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx2), CRYPT_SUCCESS); + + // update 100 times. + for (inLenBase = 1; inLenBase <= 100; inLenBase++) { + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx1, input + inLenTotal, inLenBase), CRYPT_SUCCESS); + inLenTotal += inLenBase; + } + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx1, out1, &outLen), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_MdGetDigestSize(algId); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx2, input, inLenTotal), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx2, out2, &outLen), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_MdGetDigestSize(algId); + + ASSERT_EQ(memcmp(out1, out2, outLen), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx1); + CRYPT_EAL_MdFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA3_FUNC_TC002 + * @title Test multi-thread hash calculation. + * @precon nan + * @brief + * 1.Create two threads and calculate the hash, expected result 1. + * 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hash calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA3_FUNC_TC002(int algId, Hex *data, Hex *hash) +{ + int ret; + TestMemInit(); + const uint32_t threadNum = 2; + pthread_t thrd[2]; + ThreadParameter arg[2] = { + {data->x, hash->x, data->len, hash->len, algId}, + {data->x, hash->x, data->len, hash->len, algId} + }; + for (uint32_t i = 0; i < threadNum; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)Sha3MultiThreadTest, &arg[i]); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < threadNum; i++) { + pthread_join(thrd[i], NULL); + } + +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA3_FUNC_TC003 + * @title Standard vector test. + * @precon nan + * @brief + * Calculate the hash of the data and compare it with the standard vector. + * @expect + * The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA3_FUNC_TC003(int algId, Hex *in, Hex *digest) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + + uint8_t out[SHA3_OUTPUT_MAXSIZE]; + uint32_t outLen = SHA3_OUTPUT_MAXSIZE; + + ctx = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, in->x, in->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(outLen, digest->len); + ASSERT_EQ(memcmp(out, digest->x, digest->len), 0); +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SHA3_FUNC_TC004 + * @title Standard vector test of the SHAKE algorithm. + * @precon nan + * @brief + * Calculate the hash of the data and compare it with the standard vector. + * @expect + * The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SHA3_FUNC_TC004(int algId, Hex *in, Hex *digest) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx = NULL; + + uint8_t out[SHA3_OUTPUT_MAXSIZE]; + uint32_t outLen = SHA3_OUTPUT_MAXSIZE; + + ctx = CRYPT_EAL_MdNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, in->x, in->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + ASSERT_EQ(memcmp(out, digest->x, digest->len), 0); +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 + * @title SHA3 copy ctx function test. + * @precon nan + * @brief + * 1. Create the context ctx of md algorithm, expected result 1 + * 2. Call to CRYPT_EAL_MdCopyCtx method to copy ctx, expected result 2 + * 3. Calculate the hash of msg, and compare the calculated result with hash vector, expected result 3 + * @expect + * 1. Successful, the context is not null. + * 2. CRYPT_SUCCESS + * 3. Successful, the hashs are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001(int id, Hex *msg, Hex *hash) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *cpyCtx = NULL; + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + ASSERT_TRUE(ctx != NULL); + uint8_t output[SHA3_OUTPUT_MAXSIZE]; + uint32_t outLen = SHA3_OUTPUT_MAXSIZE; + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_MdCopyCtx(cpyCtx, ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdInit(cpyCtx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(cpyCtx, msg->x, msg->len), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(cpyCtx, output, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(id, cpyCtx->id); + if (ctx->id != CRYPT_MD_SHAKE128 && ctx->id != CRYPT_MD_SHAKE256) { + ASSERT_TRUE(outLen == hash->len); + } + ASSERT_EQ(memcmp(output, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); + CRYPT_EAL_MdFreeCtx(cpyCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sha3/test_suite_sdv_eal_md_sha3.data b/testcode/sdv/testcase/crypto/sha3/test_suite_sdv_eal_md_sha3.data new file mode 100644 index 00000000..ce342e06 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sha3/test_suite_sdv_eal_md_sha3.data @@ -0,0 +1,122 @@ +SDV_CRYPT_EAL_SHA3_API_TC001 Get digest size test +SDV_CRYPT_EAL_SHA3_API_TC001: + +SDV_CRYPT_EAL_SHA3_API_TC002 update and final test +SDV_CRYPT_EAL_SHA3_API_TC002:CRYPT_MD_SHA3_224 + +SDV_CRYPT_EAL_SHA3_API_TC002 update and final test +SDV_CRYPT_EAL_SHA3_API_TC002:CRYPT_MD_SHA3_256 + +SDV_CRYPT_EAL_SHA3_API_TC002 update and final test +SDV_CRYPT_EAL_SHA3_API_TC002:CRYPT_MD_SHA3_384 + +SDV_CRYPT_EAL_SHA3_API_TC002 update and final test +SDV_CRYPT_EAL_SHA3_API_TC002:CRYPT_MD_SHA3_512 + +SDV_CRYPT_EAL_SHA3_FUNC_TC001 MD 100 updates then final SHA3_224 +SDV_CRYPT_EAL_SHA3_FUNC_TC001:CRYPT_MD_SHA3_224 + +SDV_CRYPT_EAL_SHA3_FUNC_TC001 MD 100 updates then final SHA3_256 +SDV_CRYPT_EAL_SHA3_FUNC_TC001:CRYPT_MD_SHA3_256 + +SDV_CRYPT_EAL_SHA3_FUNC_TC001 MD 100 updates then final SHA3_384 +SDV_CRYPT_EAL_SHA3_FUNC_TC001:CRYPT_MD_SHA3_384 + +SDV_CRYPT_EAL_SHA3_FUNC_TC001 MD 100 updates then final SHA3_512 +SDV_CRYPT_EAL_SHA3_FUNC_TC001:CRYPT_MD_SHA3_512 + +SDV_CRYPT_EAL_SHA3_FUNC_TC001 MD 100 updates then final MD_SHAKE128 +SDV_CRYPT_EAL_SHA3_FUNC_TC001:CRYPT_MD_SHAKE128 + +SDV_CRYPT_EAL_SHA3_FUNC_TC001 MD 100 updates then final MD_SHAKE256 +SDV_CRYPT_EAL_SHA3_FUNC_TC001:CRYPT_MD_SHAKE256 + +SDV_CRYPT_EAL_SHA3_FUNC_TC002 CRYPT_EAL_MdNewCtx Multi Thread #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC002:CRYPT_MD_SHA3_256:"b053fa":"9d0ff086cd0ec06a682c51c094dc73abdc492004292344bd41b82a60498ccfdb" + +SDV_CRYPT_EAL_SHA3_FUNC_TC002 CRYPT_EAL_MdNewCtx Multi Thread #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC002:CRYPT_MD_SHA3_512:"0ce9f8c3a990c268f34efd9befdb0f7c4ef8466cfdb01171f8de70dc5fefa92acbe93d29e2ac1a5c2979129f1ab08c0e77de7924ddf68a209cdfa0adc62f85c18637d9c6b33f4ff8":"b018a20fcf831dde290e4fb18c56342efe138472cbe142da6b77eea4fce52588c04c808eb32912faa345245a850346faec46c3a16d39bd2e1ddb1816bc57d2da" + +Nist Vector test SHA3_224ShortMsg.rsp #0 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_224:"":"6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7" +Nist Vector test SHA3_224ShortMsg.rsp #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_224:"01":"488286d9d32716e5881ea1ee51f36d3660d70f0db03b3f612ce9eda4" +Nist Vector test SHA3_224ShortMsg.rsp #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_224:"bf5831":"1bb36bebde5f3cb6d8e4672acf6eec8728f31a54dacc2560da2a00cc" +Nist Vector test SHA3_224ShortMsg.rsp #3 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_224:"e65de91fdcb7606f14dbcfc94c9c94a57240a6b2c31ed410346c4dc011526559e44296fc988cc589de2dc713d0e82492d4991bd8c4c5e6c74c753fc09345225e1db8d565f0ce26f5f5d9f404a28cf00bd655a5fe04edb682942d675b86235f235965ad422ba5081a21865b8209ae81763e1c4c0cccbccdaad539cf773413a50f5ff1267b9238f5602adc06764f775d3c":"26ec9df54d9afe11710772bfbeccc83d9d0439d3530777c81b8ae6a3" +Nist Vector test SHA3_224LongMsg.rsp +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_224:"ab4f9d765085ccb474be6e2369568292532f6fa4dd9c50d02a7d8fab0fabb56a7f9680a2462c3753fafd3a252f9dddf1eb4a76835acfb59fc2a83441b8674f2995573697245e40549d2883f1d781a153b903e470f2f28e53e9646a66f7a5a7f0d5d9e6dd50e392be44867010c7ca77c1a5a2e1f00dcb82f589f759a1332b65c62766b9fa3483d399d7602a0969400642976e948d13243a8b89aa287ad5c230b47344d7783606aced3dfed86424abf7de77b026ce6cc35d20d1c500794332b0c1a1bc67dfc033c4c360a8a3aa5fd2f19d2db1bf3b807094b949900827e6438ef5991692b539d3c42227a6b362847e9d88a1b6855db7f58760d953690b26bd7258439a7f8409ae53137a3f2f14fa77a2a6bc0aa3bb7a19dd1c69554aae6c6703f3879057d3978c1a9d41bd3f492985aa0064f43fde2fa33ff6e1dfd4961e0aeacd4e3f412b4d35c0c864660d8779705a9c82bb824c405c54f429392e4da66ecfee7ef066139270ee9ccc83be5952ff5c84ffa8938f130cc52129ab825b6a5b585f01ebed13ce074c225f5b7d441cfc58c0c1039a2f127b3982ca7df546d4993027bd78ffb36ac08161063870d23f2df556b214":"d61f04985026eee29d0f9700f8c5aea32ec2c23b1a9357edeb2be20c" + +Nist Vector test SHA3_256ShortMsg.rsp #0 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_256:"":"a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" +Nist Vector test SHA3_256ShortMsg.rsp #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_256:"e9":"f0d04dd1e6cfc29a4460d521796852f25d9ef8d28b44ee91ff5b759d72c1e6d6" +Nist Vector test SHA3_256ShortMsg.rsp #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_256:"b053fa":"9d0ff086cd0ec06a682c51c094dc73abdc492004292344bd41b82a60498ccfdb" +Nist Vector test SHA3_256ShortMsg.rsp #3 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_256:"56ea14d7fcb0db748ff649aaa5d0afdc2357528a9aad6076d73b2805b53d89e73681abfad26bee6c0f3d20215295f354f538ae80990d2281be6de0f6919aa9eb048c26b524f4d91ca87b54c0c54aa9b54ad02171e8bf31e8d158a9f586e92ffce994ecce9a5185cc80364d50a6f7b94849a914242fcb73f33a86ecc83c3403630d20650ddb8cd9c4":"4beae3515ba35ec8cbd1d94567e22b0d7809c466abfbafe9610349597ba15b45" +Nist Vector test SHA3_256LongMsg.rsp +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_256:"2a459282195123ebc6cf5782ab611a11b9487706f7795e236df3a476404f4b8c1e9904e2dc5ef29c5e06b179b8649707928c3913d1e53164747f1fa9bba6eeaf8fb759d71e32adc8c611d061345882f1cdeee3ab4cab3554adb2e43f4b01c37b4546994b25f4dcd6c497bc206865643930157cb5b2f4f25be235fa223688535907efcc253bcd083021407ea09cb1c34684aa0c1849e7efe2d9af6938c46525af9e5afb4da6e5b83da4b61dc718672a8090549cbe5aadb44f5bc93a6b3fbdc2e6d32e2eaaae637465179ea17f23ad1e4f1ebc328e2c6dc90c302b74a1edbbb0676c136b269d70c41040a313af06ab291bf489d9700950b77f207c1fc41884799931b3bca8b93331a6e96b7a3f0a8bd24cdb64964c377e0512f36444bb0643a4e3ecb328194cd5428fd89ede167472a14a9bf5730aff1e3b2c708de96eff1ebaaf63beb75f9c7d8034d6e5471e8f8a1f7efce37793a958e134619c19c54d3d42645f7a7263f25471fbaae8be3ea2fbd34ec6d7aacd7d5680948c3cd9a837c9c469a88f600d95829f4d1e4e4a5ef4ed4623c07815a1c33d9fb3b91333ff04eac92806a68a46cf2e9293f8bff466ce87fe66b46fbff7c238c7f9b2c92eb2fdc7d8084167f6f4e680d03301e5c33f78f1857d6863b1b8c36c7fce3e07d2a96a8979712079ae0023a1e3970165bfcf3a5463d2a4fdf1ca0e044f9a247528cd935734cb6d85ba53ceb95325c0eaf0ff5cd81ecb32e58917eb26bfc52dba3704bf5a927fee3220":"cb1c691c87244c0caf733aacd427f83412cd48820b358c1b15dd9fadee54e5af" + +Nist Vector test SHA3_384ShortMsg.rsp #0 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_384:"":"0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004" +Nist Vector test SHA3_384ShortMsg.rsp #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_384:"80":"7541384852e10ff10d5fb6a7213a4a6c15ccc86d8bc1068ac04f69277142944f4ee50d91fdc56553db06b2f5039c8ab7" +Nist Vector test SHA3_384ShortMsg.rsp #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_384:"6ab7d6":"ea12d6d32d69ad2154a57e0e1be481a45add739ee7dd6e2a27e544b6c8b5ad122654bbf95134d567987156295d5e57db" +Nist Vector test SHA3_384ShortMsg.rsp #3 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_384:"92c41d34bd249c182ad4e18e3b856770766f1757209675020d4c1cf7b6f7686c8c1472678c7c412514e63eb9f5aee9f5c9d5cb8d8748ab7a5465059d9cbbb8a56211ff32d4aaa23a23c86ead916fe254cc6b2bff7a9553df1551b531f95bb41cbbc4acddbd372921":"71307eec1355f73e5b726ed9efa1129086af81364e30a291f684dfade693cc4bc3d6ffcb7f3b4012a21976ff9edcab61" +Nist Vector test SHA3_384LongMsg.rsp +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_384:"221710ca1c521ea4c3fe7aaf826691b9bcf37e7d0f587277da0c59f7fcfdba75df83df24b69237c90235f8ce5b3708926d231e0441702570bef5e1996fa3d407867263a2219c3580cd0adcfc480bb7088c4c16c40805a04f3170f2dc397f89091ecee26de7d7df702b656d60d24b64c11f55afe4ef7facbb3b65d5ebe4fba123b07ea5ac8faaff42242ef423805dd86531262e8c7b46115ce5bcd3ecf87de3fc436af488a27f5b9ec04db96cdbaadb9dc7a7dee636c297db365d3208fb6f183ddf7a1729a7bdbd2a08aa04646a9a3511ebc00617a75b05e037303a667738088d8c9655b626cbeb91032d1d32b596ad68a459ed4a567a2512ee1e352ff3407b9553a6f758a813ad79b9bf4b0044040c4afb5adca5cc85bd1a650d698af8ef39fd3b924536b4fccd8b3346d8f3a04d1a61f6ab1b5090e6969fa4e61fa00dad096c4d428779d2ee116e78ab0a3550da9f52a034f2742a03784ab1929f98bae2b58a909e05488a5143ca90d72aeedc1263c8fedea93923462bc396f8319b87f603000c8f07cc658e294984b17f45cd5c2d691a8f87c6021676b15bff1dd1fd51bc76c9fbd42cea0b8c915b205363a922c7ddfb30d5444fda22bd0691aa61a35ba893d0ccb591a231334a1d0eec70fbcbf7cda9aadcda93fcf78ea1952274017d8e0028e8f2231368e81dd362939348bf86e12de3e1b154e3bdcd33f2cb31a01d3765d939d309c71971b1840490f41a653cc08ec52ff01df73c21c592eec107a56c68eca59f6c46aa97b038db2bbcf827e013d4370dc073a03c335e5cd24bbe7bf3b46816a073168522bff7d1ac136b6c3c810720c249e04684aa0638c1f84e0994ef55731c47c110da88cacd5a20fa9d16b3306a97b2eb51dd2fc50e01f03eb519c2bba45c0fcfb587b3b8b87f0c2d20375057fcd4241d290f6aa4c6db5a16e948d4a390a8f4c6dbf0e8ca7861fe8c5e670182bec1c6fc36e202aa49975e5f0cebce1421481e30e9dece07f6481fa0bf6d6ebb98a5c112e11ea0e07d7d26a086c857173e83b49449190d771a7e97f0ac133e0972ca3ce7908aeb4c4bd5d761bea818b3cfa2df7b62694e22cd4a8d048b1f1a7534766001acef8cf89be69c2b1e52b8f0bdedc66c9c963911f5f32965c55aa905c6f255ea9e152aec56f99b840d90e0d6eeac92ef5f67754b7bc2959ac38c94c31086422acdc46e2f6256fcf7f328386e4b276a8c13a5abd848fff62bec7d82b7fb794f47a0c4ffc8a945e80939e367bfbca677cc201882c143f277a1a7f41ce86d15a6cb81dc87c2120e8744458916d12a70e036ef88a30d53e23d835ebb0a5e4fa06c3ed7d6ab2284f8002f80e2ecad7bcece53e6bdb5c4621973597898f3218a63cc26097815f2e94c7c5252b5925a990869a96e7e61ef57dd3fac5d547f3a04a6ec0d818b6d3a2853223624ccafe06a66d8c2f0954f941977c90274b757b0a7b1f47aa6d65a0029521b625cedec48d82f4426d2c826be922f3ae62788238b5acb0df6e023854ed4948e5e64e1f199caadd45b7ee08e72a94cbadddd918ad3043d5f089738962b1160a4b3a27065db2726b1eb5aa531ba46187071ff9835918f50113833de34a0c8fd84e88061f117d9e3025ed0deb49d51d98529f366cccde2494b0e1cdd07b3e1b45885647e3c54c72cf03a4655c224b3d8218d22c3f68de5733713bbfdb86e44cd4513b88def9ad949a30926d00155525d6a26f4765bdb8015face7606efd9d9907519e357b1f1f7814252d718193a17af8b7bd249a4be9b76bfc7b6bf53fb8944101f4da42b62091df69ec1f5b3dbea18aa152202793f1edfac87e4f18ddc3a333dad5e3c04f4f765e6744c2e773eb4def07a4d6a8164f198e99566644584d5a3254c7ee6e5b0a9a13b5ce08d0c6d5b4a8434bc496537fde99f":"d028f9a585a081207101ff8c32a54829879883fa0f4c4180542842168df757cac06a951aa68b277ca0fa99850b928e75" + +Nist Vector test SHA3_512ShortMsg.rsp #0 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_512:"":"a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26" +Nist Vector test SHA3_512ShortMsg.rsp #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_512:"e5":"150240baf95fb36f8ccb87a19a41767e7aed95125075a2b2dbba6e565e1ce8575f2b042b62e29a04e9440314a821c6224182964d8b557b16a492b3806f4c39c1" +Nist Vector test SHA3_512ShortMsg.rsp #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_512:"37d518":"4aa96b1547e6402c0eee781acaa660797efe26ec00b4f2e0aec4a6d10688dd64cbd7f12b3b6c7f802e2096c041208b9289aec380d1a748fdfcd4128553d781e3" +Nist Vector test SHA3_512ShortMsg.rsp #3 +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_512:"0ce9f8c3a990c268f34efd9befdb0f7c4ef8466cfdb01171f8de70dc5fefa92acbe93d29e2ac1a5c2979129f1ab08c0e77de7924ddf68a209cdfa0adc62f85c18637d9c6b33f4ff8":"b018a20fcf831dde290e4fb18c56342efe138472cbe142da6b77eea4fce52588c04c808eb32912faa345245a850346faec46c3a16d39bd2e1ddb1816bc57d2da" +Nist Vector test SHA3_512LongMsg.rsp +SDV_CRYPT_EAL_SHA3_FUNC_TC003:CRYPT_MD_SHA3_512:"dfb77844e75f85583be98d8b02b601d95449ea7c954cd81001d31bf487e536f3db399124c73d6e0ec25c1e10c381750157d77b13f2d464fd8275c3594acbfa4aeeb6f563caf118c4884e7586f243435a04a68b6c46b5258e5959e392cfac0cf740b80cc9998269c2b847f9b53605532d843d83513af7020aab08e568bd905442f8c63e1ddcf84b4f78cd126538ce8dc1ff24c98875a3e2bba3082fa3bd7fba733e69f3293a5ba5b5f06a285da0a6d9609ce4c7d9a0c1afe766e32b0b768226d13c2793b35cb45e3a4aa5a36615951f508304e40e635750d71f203f6791a080a5178b8684ea0a6027ab06ec483fa447dadd0c87ed656fadd3f448d581b5e2b037fa1a34648b6692c43d1669cbc7da3946d2851a404f10ae220de2541f8b4e9ecf0b5e061ae7cfdc58285c83b65540dddc89f604cdc8433b0e9376240abaef33b572de6270a74d262d9461a2d390dc1be42be7ad5d790f3cddae8dad0aebca55305822b12c73e85889a8ab2fe821b8dca5dfe07db70a7c99d885ae56e7c6e9ed8ae5b35c17f2a95bb58cc490beafdc0668ce6adca522923a4741618968f253e4094018c9f9cd9715f969342f1de34e83751f0c32ed695a0772092eae56181020f692d9629aacbb6f9c678173cd65183914fb4fe75889dbe9a0069e2b79df298b99027f8ec1351b51e8ad35c395dc42128d8aba63ae271dc61b60386999f0a50c39b991b43813c1a42364d7893ef1d2f527f3d50eb7ee2988293e84d07ef28c8a1fde973ec5ecb54e96b3f02c914bd2c92b5f28513a83061513c80bc9ef8ee6ef949a19933169fd3989c3071453934978e1f53c920191bc57212854bab66cbc22de15a01b4331a34b43bba4a94f7040e991de983ad2be54349a83e80c9933150b4576b33ec5edaf6e0ec450524c8bbe048341c4b276b2d596c8044d28618cfa9213e6db647d4427893006917a118bcbb1ff474961b5164764f1d00d74d61e729f8e8c9ff535df1584f2a8f28667196fd84c18aeae5692b3865e12b05abf92851a00918759b36580479cd3f8df16ddb361b3db7b0323cd20e357f0bc41e58f3bebaf1c1bf8c07f71b976ae2dede67e9e347cb939c7e27096652392bb9111be9dfae456e43b23d5efc4c86218189fa5393aefd96f615c221df30c2134b109c6b22fe6666988a60e024fd91641c908f98b595364a53b598cbe7558c5b00b95518373ff7532480fd2b243f2f33166ea239c7af28163bca15680d450a5b6067f0416ac75abc8e427cb08865b216f590dca74861259324cfb276cf63ceace0a8e8975c4912fb2c2b69f0b015cc7830839971c63fc13995330a788c464bb807f8988a8a19b2a784c84f6c49c3d0df6dd36319bfbf8d82139097fde260f4155ce39a8b52ddbc3a3e958793940451c4f3ecb42f9344dd050674b57760587a4d45d6692a64e9823ba00fbcf74d3bd1c1695c26f3ef84522b143c1d65647120b8695d7ee83ee1c7145fb36a17d3eed35d449e162732e26f7c93632a588d6f99ef1de566352f4add6cd41cf975a6a1d8d0fc2f1c3a0be397622a9656c149884879fa1a9991d48947ad93a8e58153e954f5268b939cb8fc6c8430223d20077faeb18449939ebd21984f14e3d8db6a19ca122a3036dfe8b1514b4ab347f565aa5f5e231eeebc57a831d9de5a2dd437d7cab09db950740996d83fe0a601c1e28cbca87ce7056b2281c6c666787f1c6b97b968e7838ae9aa1183da8896f515ecbb5":"c6844ef20c8d121ce80dd8a3cee4f36501003232dc3e71519de69a4cf77329ece5f08967517804941bb00d65a864a0e82df5b5452d3700e4cc0f5b539ced454a" + +Nist Vector test SHAKE128ShortMsg.rsp #0 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE128:"":"7f9c2ba4e88f827d616045507605853e" +Nist Vector test SHAKE128ShortMsg.rsp #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE128:"0e":"fa996dafaa208d72287c23bc4ed4bfd5" +Nist Vector test SHAKE128ShortMsg.rsp #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE128:"d9e8":"c7211512340734235bb8d3c4651495aa" +Nist Vector test SHAKE128ShortMsg.rsp #3 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE128:"84e950051876050dc851fbd99e6247b8":"8599bd89f63a848c49ca593ec37a12c6" +Nist Vector test SHAKE128LongMsg.rsp +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE128:"49d81708d86cd59dea0ac2c1017a9712d6dffb754dde0b57a9023a39fc5f5b6be276fc176f59f6826610428fac3a0e85fcf71011db061b8fcf2bf085ccd45670effb6dc46f4e3f2ed08e981c5935187fc95b86cf46da675096b1cf9591a67842d6301116be93d8288e4d6b70f1b1db8aa5d203b774a21825665b8170351ee86801da91154570eaf80a1564945af7822df8232fd04ea65593a7f2ab1e9e84cf6ad6c494c9ec2d9d27aaad2b8f7e4f33f12a17b422bc2d4724c13ff8a8b62054d1bfb5c33b9c11183cd8df67694300165ca37637b5a781155f1c070d156339a0242374c6723b6584bffb71c02b935455f8cb086392f5e8e8cc2015956d8f19daeb6aca4476b27108387a2ce0dc5591154d0b94ddc090abe8f4363036b821062baffb7fe550ea7dcd30bfd86c84710081e1c9e450475e123c5ec41f98ff0149bbf6405b5207cad1fb2f313d0f2bcee9be3f6ebe623049640d9234ab644a172ab14ba02633a339b5b9bb38226fda5694f7ec63ebbb8238eb8219ec9c429f4bf0353383a72f2d21702f5e3c513499f04852710f33044512edc47a56bad90885e5713851a7efac694b869fa590076e844ff757d95de581c1b3fa3dd8ccd28cad4f8ae173ee1b28f98ee606dca89063fbef0f262b33053f2c854debdc9cd433ab77abb64f445aa9b981761c4761767f3b71c2646c7b0d873baae50bc9f0":"c609be05458f7ab33e7b6b54bc6e8999" + +Nist Vector test SHAKE256ShortMsg.rsp #0 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE256:"":"46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f" +Nist Vector test SHAKE256ShortMsg.rsp #1 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE256:"0f":"aabb07488ff9edd05d6a603b7791b60a16d45093608f1badc0c9cc9a9154f215" +Nist Vector test SHAKE256ShortMsg.rsp #2 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE256:"0dc1":"8e2df9d379bb034aee064e965f960ebb418a9bb535025fb96427f678cf207877" +Nist Vector test SHAKE256ShortMsg.rsp #3 +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE256:"104fefe89f08d15d36a2233f42a7defa917c5ad2642e06cac56d5cc51ad914ecfb7d984f4199b9cf5fa5a03bf69207b9a353a9681c9cf6437bea0c49d9c3e3db1f3fc76519c70c40cc1dfdd70a9c150943c272cf9eeb861f485f10100c8f4a3e259c6470501932782512225ba64d70b219cf9d5013a21d25d6d65062dcc6b3deb49d58b90d18933f118df70ff42c807ccc851233a34a221eca56b38971ef858475488988794a975d3894633a19c1ae2f05e9b9c0756affd3cfe823ccf29228f60fa7e025bc39a79943325126409460926b057a3fb28a1b098b938872883804fd2bc245d7fd6d29bcda6ca6198f2eff6ea7e03ef78133de8ba65fc8c45a688160719fa1e7646d878ea44c4b5c2e16f48b":"46293a63c235750d58a24edca5ba637b96cae74325c6c8122c4155c0d15805e6" +Nist Vector test SHAKE256LongMsg.rsp +SDV_CRYPT_EAL_SHA3_FUNC_TC004:CRYPT_MD_SHAKE256:"0109f4992ae7954e89927931735dbac6eb909131160b6df9f02c420c3cf32403c16414a8b32d1ab5708994df6d64cd136fc0d100fe5780d51682e24c2159bae7221c5e7933d2c5e9312fe233b6bb30af47318f96cf254ec24cea89b5c9b3b5dd8cf87917901cbf71364c0c3437aa0c22ddab72fc73bdff47fa2edf501d493c6e67c20e87b45430d5e5a8b9ead87989f298f62239d067baed86148e24056278201b40c4d285c1409ea80a925e826fcea9dfd94855d06ba73a59653b396a48917e103b4401edad1553e63c3e971bd504ce1c1d8c595a10efb8dbe890983241ae0daf7a351cd35eda7c0604669d8cf352eab68a954c55a0baef746735484796f7575ec740291e1db5a2722bb279be11e18415e80c36ab612f668da8d2518f8f95e386e80d32b832ce4c9179c9329877d924a1ff981f439c77a58c750ebcf473b03990a6433e88e54e02cbb554d0016d6153c297e2100598b934db9491905d8c6fe2e2c98a56767e5d4c88a9fa5ce33aa197e0779110d99f1e9ce0cd04d5b120fb65e6198c816a4422b3301b64dd2527c27b63684e28a7f7ce6405ea0f94da787c4a035eeec74c80c6be2bd43a5baf7cec84b332c15f57e9f014b1b159d4bfdc191aa05f5b30047b70f6e29c23df6981463c389d91bdd1bdad344bec8b9d4893fa5c27e579c57b7a49e1bb3ac76f3b7df92a5a71674afdbb2c4d3d614cf75de74898ffb8f08d97c879091f78cf160dba2cd68275ea0fc42b96e6eed945ebe61e2b5690a0699041ac27f6771ce3d9c77e08c91672c3130c541288c61b1e80cb81ca1f42658cd7626d7c2e29efaac25112b58a8030995ebf7fc9ba2df17ebff4584e7a7dce0069e0549f3b9fb9cdd893be5aa1267715f9c3f4e2048b210dae4aebdef0a9a46e4fa5a9b8a53f42f32375c92097720fdfeb02fb86ee48747458b381a3082eaf7d8f97b4f1f27351c5ace07d2ef3cabf9e3c62dcdd01ccb25bc21864c54a74b7d633a0bc70aca2b0eb7aba20ad3d9850faf5cdde0ec480a369f662da6b3ee4842042a70b5d5a33250c95edfbc4fe438b9d1d2a4a42c0ca0e47fb772cbd6de4dd04c593e7e1859079d0065f569cbc33352cbc6168a07b13bd9dd941a2e45edd8c2ac34e9924b42074e1d4fa795c02d01952db5980517fc4761298a783089938573944bf684d6f4bdde407a4ab2d5582feb580fcda7c5443024e41901950a75b07da51ce9e843f797e84a84735373fb1abfdb631be4a80fa29fadce6aae50fb064b4f06382f3aa121d67beca5fa147c5e9d382e073e38d4fb2be6f907fef599d35702c665bbf3a7e833551157194f62680dfeef1426e03ac67410476e0950e8c44b50abf7213772678976a10b337d23c38c8014d731368780e2ca28014ffb5e4572c94570f15e870c3340fa36db36570d936c3da4efc461b702652966556d60d377cd11479ed15c52eb64bb6e62f37282ad33d811a4e24fd55d81ba019c2f96fac4ec9dffac4868e7fc2233167d4cecdf444762b21348b8685e90586796aa7727d4a85a1d8c2c4317f03a1fc38c9b4c8ff3476bea9d4021ec7021830cd77677e74170c405c0e5618f61eccffa137717f13494624fb56112de4cb5d865d10c2fb575e66a6ced1c4a9acbeac23ea468b5cf82bed435fe3401ba5ebdb71705e3f51efc69cb97632974e68894a4e5a1d8cc6758373051ca31850cf0b9ad7508966e804f8b5639b5a566ef427ad693ae5fc2554f9e1507cbd20342dd2a3a243b8bf285e9bb98a877089701641dd5dd2c561e05b343e0ec559e02f86e9fdb89213d37ac458b118809db8be977fe3106ae6456153dd922640a1e1aaa1f7b00385c32944ffd7a4f4cf096cbf3e88c66c4a702f0f039be68035bbaa0b47a5c56963f049efd8bf9a06bcdb2cdbd5058e58ba8aa85235174104eccfc4bc":"6a22c83f1d43c4c4635be4ec54e9d422951a1765d0e7a8c6a421a98942004293" + +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 SHA3_224 +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA3_224:"bf5831":"1bb36bebde5f3cb6d8e4672acf6eec8728f31a54dacc2560da2a00cc" + +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 SHA3_256 +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA3_256:"b053fa":"9d0ff086cd0ec06a682c51c094dc73abdc492004292344bd41b82a60498ccfdb" + +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 SHA3_384 +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA3_384:"6ab7d6":"ea12d6d32d69ad2154a57e0e1be481a45add739ee7dd6e2a27e544b6c8b5ad122654bbf95134d567987156295d5e57db" + +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 SHA3_512 +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001:CRYPT_MD_SHA3_512:"37d518":"4aa96b1547e6402c0eee781acaa660797efe26ec00b4f2e0aec4a6d10688dd64cbd7f12b3b6c7f802e2096c041208b9289aec380d1a748fdfcd4128553d781e3" + +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 SHAKE128 +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001:CRYPT_MD_SHAKE128:"84e950051876050dc851fbd99e6247b8":"8599bd89f63a848c49ca593ec37a12c6" + +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001 SHAKE256 +SDV_CRYPTO_SHA3_COPY_CTX_FUNC_TC001:CRYPT_MD_SHAKE256:"104fefe89f08d15d36a2233f42a7defa917c5ad2642e06cac56d5cc51ad914ecfb7d984f4199b9cf5fa5a03bf69207b9a353a9681c9cf6437bea0c49d9c3e3db1f3fc76519c70c40cc1dfdd70a9c150943c272cf9eeb861f485f10100c8f4a3e259c6470501932782512225ba64d70b219cf9d5013a21d25d6d65062dcc6b3deb49d58b90d18933f118df70ff42c807ccc851233a34a221eca56b38971ef858475488988794a975d3894633a19c1ae2f05e9b9c0756affd3cfe823ccf29228f60fa7e025bc39a79943325126409460926b057a3fb28a1b098b938872883804fd2bc245d7fd6d29bcda6ca6198f2eff6ea7e03ef78133de8ba65fc8c45a688160719fa1e7646d878ea44c4b5c2e16f48b":"46293a63c235750d58a24edca5ba637b96cae74325c6c8122c4155c0d15805e6" diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2.base.c b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2.base.c new file mode 100644 index 00000000..c472115a --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2.base.c @@ -0,0 +1,78 @@ +/* + * 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 "crypt_bn.h" +#include "bsl_sal.h" +#include "crypt_algid.h" +#include "crypt_types.h" +#include "crypt_eal_pkey.h" +#include "crypt_errno.h" +#include "stub_replace.h" +#include "crypt_eal_rand.h" +#include "securec.h" +#include "crypt_util_rand.h" +#include "crypt_encode.h" +#include "crypt_dsa.h" + +#define ERR_BAD_RAND 1 +#define RAND_BUF_LEN 2048 +#define UINT8_MAX_NUM 255 + +uint8_t g_RandOutput[RAND_BUF_LEN]; +uint32_t g_RandBufLen = 0; + +int32_t RandFunc(uint8_t *randNum, uint32_t randLen) +{ + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % UINT8_MAX_NUM); + } + + return 0; +} + +int32_t SetFakeRandOutput(uint8_t *in, uint32_t inLen) +{ + g_RandBufLen = inLen; + return memcpy_s(g_RandOutput, sizeof(g_RandOutput), in, inLen); +} + +int32_t FakeRandFunc(uint8_t *randNum, uint32_t randLen) +{ + if (randLen > RAND_BUF_LEN) { + return ERR_BAD_RAND; + } + return memcpy_s(randNum, randLen, g_RandOutput, randLen); +} + +int32_t STUB_RandRangeK(BN_BigNum *r, const BN_BigNum *p) +{ + (void)p; + BN_Bin2Bn(r, g_RandOutput, g_RandBufLen); + return CRYPT_SUCCESS; +} + +void SetSm2PubKey(CRYPT_EAL_PkeyPub *pub, uint8_t *key, uint32_t len) +{ + pub->id = CRYPT_PKEY_SM2; + pub->key.eccPub.data = key; + pub->key.eccPub.len = len; +} + +void SetSm2PrvKey(CRYPT_EAL_PkeyPrv *prv, uint8_t *key, uint32_t len) +{ + prv->id = CRYPT_PKEY_SM2; + prv->key.eccPrv.data = key; + prv->key.eccPrv.len = len; +} \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_crypt.c b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_crypt.c new file mode 100644 index 00000000..681b593f --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_crypt.c @@ -0,0 +1,502 @@ +/* + * 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_BASE test_suite_sdv_eal_sm2 */ + +/* BEGIN_HEADER */ + +#include "crypt_local_types.h" +#include "crypt_sm2.h" +#include "crypt_encode.h" + +#define MAX_PLAIN_TEXT_LEN 2048 +#define CIPHER_TEXT_EXTRA_LEN 97 + +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_SM2_ENC_API_TC001 + * @title SM2 CRYPT_EAL_PkeyEncrypt: Test the validity of input parameters. + * @precon Vector: public key. + * @brief + * 1. Init the DRBG and create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyEncrypt method, where all parameters are valid, expected result 2 + * 3. Set public key, expected result 3 + * 4. Call the CRYPT_EAL_PkeyEncrypt method: + * (1) data = NULL, dataLen != 0, expected result 4 + * (2) data = NULL, dataLen = 0, expected result 5 + * (3) output = NULL, outLen != 0, expected result 6 + * (4) outLen = NULL, expected result 7 + * (5) outLen is not enough(less than 32+97), expected result 8 + * (6) all parameters are valid, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SM2_NO_PUBKEY + * 3. CRYPT_SUCCESS + * 4-7. CRYPT_NULL_INPUT + * 8. CRYPT_SM2_BUFF_LEN_NOT_ENOUGH + * 9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_ENC_API_TC001(Hex *pubKey) +{ + uint8_t plainText[32]; + uint8_t cipherText[141]; // 32 + 97 + 12 + uint32_t outLen = sizeof(cipherText); + CRYPT_EAL_PkeyPub pub = {0}; + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, &outLen) == CRYPT_SM2_NO_PUBKEY); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, NULL, sizeof(plainText), cipherText, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, NULL, 0, cipherText, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), NULL, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, NULL) == CRYPT_NULL_INPUT); + + outLen = sizeof(cipherText) - 12; + ASSERT_TRUE( + CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, &outLen) == CRYPT_SM2_BUFF_LEN_NOT_ENOUGH); + outLen = sizeof(cipherText); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, &outLen) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_ENC_API_TC002 + * @title SM2: CRYPT_EAL_PkeyEncrypt test: Random number error. + * @precon Vertor: public key. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1. + * 2. Set public key, expected result 2. + * 3. Call the CRYPT_EAL_PkeyEncrypt method, where all parameters are valid, expected result 3. + * 4. Register wrong rand method: FakeRandFunc(The random number it generated is 0), expected result 4. + * 5. Call the CRYPT_EAL_PkeyEncrypt method, where all parameters are valid, expected result 5. + * 6. Register correct rand method and Call the CRYPT_EAL_PkeyEncrypt method to signature, expected result 6. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_NO_REGIST_RAND + * 4. CRYPT_SUCCESS + * 5. CRYPT_SM2_ERR_TRY_CNT. + * 6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_ENC_API_TC002(Hex *pubKey) +{ + uint8_t plainText[32]; + uint8_t cipherText[141]; // 32 + 97 + 12 + uint32_t outLen = sizeof(cipherText); + uint8_t zero[100] = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, &outLen) == CRYPT_NO_REGIST_RAND); + + CRYPT_RandRegist(FakeRandFunc); + ASSERT_TRUE(SetFakeRandOutput(zero, sizeof(zero)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, &outLen) == CRYPT_SM2_ERR_TRY_CNT); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plainText, sizeof(plainText), cipherText, &outLen) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_DEC_API_TC001 + * @title SM2 CRYPT_EAL_PkeyDecrypt: Test the validity of input parameters. + * @precon Vector: private key, ciphertext. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyDecrypt method, where all parameters are valid, expected result 2 + * 3. Set private key, expected result 3 + * 4. Call the CRYPT_EAL_PkeyDecrypt method: + * (1) data = NULL, dataLen != 0, expected result 4 + * (2) output = NULL, outLen != 0, expected result 5 + * (3) outLen = NULL, expected result 6 + * (4) data = NULL, dataLen = 0, expected result 7 + * (5) the length of ciphertext is too long, expected result 8 + * (6) all parameters are valid, expected result 9 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SM2_NO_PRVKEY + * 3. CRYPT_SUCCESS + * 4-7. CRYPT_NULL_INPUT + * 8. CRYPT_SM2_BUFF_LEN_NOT_ENOUGH + * 9. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_DEC_API_TC001(Hex *prvKey, Hex *cipherText) +{ + uint8_t plainText[MAX_PLAIN_TEXT_LEN]; + uint32_t outLen = cipherText->len; + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestRandInit(); + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, cipherText->x, cipherText->len, plainText, &outLen) == CRYPT_SM2_NO_PRVKEY); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, NULL, cipherText->len, plainText, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, cipherText->x, cipherText->len, NULL, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, cipherText->x, cipherText->len, plainText, NULL) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, NULL, 0, plainText, &outLen) == CRYPT_NULL_INPUT); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, cipherText->x, cipherText->len * 2, plainText, &outLen) == + CRYPT_SM2_BUFF_LEN_NOT_ENOUGH); + + outLen = cipherText->len; + ASSERT_EQ(CRYPT_EAL_PkeyDecrypt(ctx, cipherText->x, cipherText->len, plainText, &outLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_CTRL_API_TC001 + * @title SM2 CRYPT_EAL_PkeyCtrl test. + * @precon nan + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl to set sm2 hash method, expected result 2 + * 2. Call the CRYPT_EAL_PkeyCtrl, opt is CRYPT_CTRL_UP_REFERENCES, len is 0, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_EAL_ALG_NOT_SUPPORT + * 3. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_CTRL_API_TC001(void) +{ + uint32_t ref = 1; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + EAL_MdMethod hashMethod = {0}; + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_HASH_METHOD, &hashMethod, sizeof(EAL_MdMethod)) == + CRYPT_EAL_ALG_NOT_SUPPORT); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_UP_REFERENCES, &ref, 0), CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_ENC_FUNC_TC001 + * @title SM2: public key encryption. + * @precon Vectors: public key, plaintext, generate random number k, ciphertext. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Set public key, expected result 2 + * 3. Take over random numbers, mock BN_RandRange to generate k + * 4. Call the CRYPT_EAL_PkeyEncrypt to encrypt plaintext, expected result 3 + * 5. Compare the encryption result with the ciphertext vector, expected result 4 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_ENC_FUNC_TC001(Hex *pubKey, Hex *plain, Hex *k, Hex *cipher) +{ + FuncStubInfo tmpRpInfo; + uint8_t cipherText[MAX_PLAIN_TEXT_LEN + CIPHER_TEXT_EXTRA_LEN] = {0}; + uint8_t decodeText[MAX_PLAIN_TEXT_LEN + CIPHER_TEXT_EXTRA_LEN] = {0}; + uint32_t decodeLen = sizeof(decodeText); + uint32_t outLen = sizeof(cipherText); + CRYPT_EAL_PkeyPub pub = {0}; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + TestMemInit(); + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx, &pub), CRYPT_SUCCESS); + + STUB_Init(); + ASSERT_TRUE(SetFakeRandOutput(k->x, k->len) == CRYPT_SUCCESS); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, plain->x, plain->len, cipherText, &outLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(ASN1_Sm2EncryptDataDecode(cipherText, outLen, decodeText + 1, &decodeLen) == CRYPT_SUCCESS); + decodeText[0] = 0x04; + ASSERT_TRUE(decodeLen + 1 == cipher->len); + ASSERT_TRUE(memcmp(decodeText, cipher->x, cipher->len) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + STUB_Reset(&tmpRpInfo); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_DEC_FUNC_TC001 + * @title SM2: private key decryption. + * @precon Vectors: private key, plaintext, ciphertext. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Set private key, expected result 2 + * 3. Call the CRYPT_EAL_PkeyDecrypt to decrypt ciphertext, expected result 3 + * 4. Compare the decryption result with the ciphertext vector, expected result 4 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_DEC_FUNC_TC001(Hex *prvKey, Hex *plain, Hex *cipher) +{ + CRYPT_RandRegist(RandFunc); + uint8_t plainText[MAX_PLAIN_TEXT_LEN] = {0}; + uint32_t outLen = sizeof(plainText); + uint8_t encodeText[MAX_PLAIN_TEXT_LEN + 20] = {0}; + uint32_t encodeLen = MAX_PLAIN_TEXT_LEN + 20; + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(ASN1_Sm2EncryptDataEncode(cipher->x + 1, cipher->len - 1, encodeText, &encodeLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, encodeText, encodeLen, plainText, &outLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == plain->len); + ASSERT_TRUE(memcmp(plainText, plain->x, plain->len) == 0); + +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_DEC_FUNC_TC002 + * @title SM2: Private key decryption failure scenario. + * @precon Vectors: private key, ciphertext. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Set private key, expected result 2 + * 3. Call the CRYPT_EAL_PkeyDecrypt to decrypt ciphertext, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. Failure. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_DEC_FUNC_TC002(Hex *prvKey, Hex *cipher) +{ + TestMemInit(); + uint8_t plainText[MAX_PLAIN_TEXT_LEN]; + uint32_t outLen = sizeof(plainText); + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + /* Different error codes are returned for different phases. */ + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, cipher->x, cipher->len, plainText, &outLen) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC001 + * @title SM2: Generate key pair, encryption, decryption. + * @precon Vector: plaintext. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Initialize the DRBG. + * 3. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 2 + * 4. Call the CRYPT_EAL_PkeyEncrypt to encrypt plaintext, expected result 3 + * 5. Call the CRYPT_EAL_PkeyDecrypt to decrypt ciphertext, expected result 4 + * 6. Compare the decryption result with the plaintext vector, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC001(Hex *msg) +{ + uint8_t cipherText[MAX_PLAIN_TEXT_LEN + CIPHER_TEXT_EXTRA_LEN]; + uint8_t plainText[MAX_PLAIN_TEXT_LEN]; + uint32_t ctLen = sizeof(cipherText); + uint32_t ptLen = sizeof(plainText); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(ctx) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, msg->x, msg->len, cipherText, &ctLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, cipherText, ctLen, plainText, &ptLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(ptLen == msg->len); + ASSERT_TRUE(memcmp(plainText, msg->x, msg->len) == 0); + +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC002 + * @title SM2: The input and output parameters address are the same. + * @precon Vector: plaintext. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Initialize the DRBG. + * 3. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 2 + * 4. Call the CRYPT_EAL_PkeyEncrypt, and the input and output parameters address are the same, expected result 3 + * 5. Call the CRYPT_EAL_PkeyDecrypt, and the input and output parameters address are the same, expected result 4 + * 6. Compare the decryption result with the plaintext vector, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC002(Hex *msg) +{ + uint8_t buf[MAX_PLAIN_TEXT_LEN + CIPHER_TEXT_EXTRA_LEN]; + uint32_t ctLen = sizeof(buf); + uint32_t ptLen = sizeof(buf); + ASSERT_TRUE(memcpy_s(buf, ptLen, msg->x, msg->len) == CRYPT_SUCCESS); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(ctx) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyEncrypt(ctx, buf, msg->len, buf, &ctLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyDecrypt(ctx, buf, ctLen, buf, &ptLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(ptLen == msg->len); + ASSERT_TRUE(memcmp(buf, msg->x, msg->len) == 0); + +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_CMP_FUNC_TC001 + * @title SM2: The input and output parameters address are the same. + * @precon Vector: private key and public key. + * @brief + * 1. Create the contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 2 + * 3. Set public key for ctx1, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 4 + * 5. Set public key for ctx2, expected result 5 + * 6. Call the CRYPT_EAL_PkeyCmp to compare ctx1 and ctx2, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 3. CRYPT_SUCCESS + * 4. CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL + * 5-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_CMP_FUNC_TC001(Hex *pubKey) +{ + CRYPT_EAL_PkeyPub pub = {0}; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx1, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(ctx2, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCmp(ctx1, ctx2), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001 + * @title SM2: for testing sm2 ciphertext decode. + * @precon Vector: SM2 ciphertext. + * @brief + * 1. Call the ASN1_Sm2EncryptDataDecode to decode the SM2 ciphertext + * @expect + * 1. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001(Hex *cipher) +{ + uint8_t decode[MAX_PLAIN_TEXT_LEN] = {0}; + uint32_t decodelen = MAX_PLAIN_TEXT_LEN; + ASSERT_TRUE(ASN1_Sm2EncryptDataDecode(cipher->x, cipher->len, decode, &decodelen) == CRYPT_SUCCESS); +exit: + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_crypt.data b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_crypt.data new file mode 100644 index 00000000..3f92adbb --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_crypt.data @@ -0,0 +1,53 @@ +SDV_CRYPTO_SM2_ENC_API_TC001 no key encrypt, encrypt api fail +SDV_CRYPTO_SM2_ENC_API_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13" + +SDV_CRYPTO_SM2_ENC_API_TC002 encrypt rand fail +SDV_CRYPTO_SM2_ENC_API_TC002:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13" + +SDV_CRYPTO_SM2_DEC_API_TC001 no key decrypt, decrypt fail +SDV_CRYPTO_SM2_DEC_API_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"307C022004EBFC718E8D1798620432268E77FEB6415E2EDE0E073C0F4F640ECD2E149A73022100E858F9D81E5430A57B36DAAB8F950A3C64E6EE6A63094D99283AFF767E124DF0042059983C18F809E262923C53AEC295D30383B54E39D609D160AFCB1908D0BD8766041321886CA989CA9C7D58087307CA93092D651EFA" + +SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC001 gen key encrypt decrypt +SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC001:"01020304" + +SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC002 address overlap +SDV_CRYPTO_SM2_GEN_CRYPT_FUNC_TC002:"01020304" + +SDV_CRYPTO_SM2_CTRL_API_TC001 eal set hash method +SDV_CRYPTO_SM2_CTRL_API_TC001: + +SDV_CRYPTO_SM2_ENC_FUNC_TC001: GBT.32918.5-2017, sm2 encrypt vector 1 +SDV_CRYPTO_SM2_ENC_FUNC_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"656E6372797074696F6E207374616E64617264":"59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21":"0404EBFC718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa" + +SDV_CRYPTO_SM2_DEC_FUNC_TC001: GBT.32918.5-2017, sm2 decrypt vector 1 +SDV_CRYPTO_SM2_DEC_FUNC_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"656E6372797074696F6E207374616E64617264":"0404EBFC718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa" + +SDV_CRYPTO_SM2_DEC_FUNC_TC002: sm2 decrypt fail wrong prv key +SDV_CRYPTO_SM2_DEC_FUNC_TC002:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B9":"0404EBFC718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa" + +SDV_CRYPTO_SM2_DEC_FUNC_TC002: sm2 decrypt fail wrong Cipher 1 +SDV_CRYPTO_SM2_DEC_FUNC_TC002:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"0404EBFC718e8d1798620432268e78feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa" + +SDV_CRYPTO_SM2_DEC_FUNC_TC002: sm2 decrypt fail wrong Cipher 2 +SDV_CRYPTO_SM2_DEC_FUNC_TC002:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"0404EBFC718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c28f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087307ca93092d651efa" + +SDV_CRYPTO_SM2_DEC_FUNC_TC002 sm2 decrypt fail wrong Cipher 3 +SDV_CRYPTO_SM2_DEC_FUNC_TC002:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"0404EBFC718e8d1798620432268e77feb6415e2ede0e073c0f4f640ecd2e149a73e858f9d81e5430a57b36daab8f950a3c64e6ee6a63094d99283aff767e124df059983c18f809e262923c53aec295d30383b54e39d609d160afcb1908d0bd876621886ca989ca9c7d58087308ca93092d651efa" + +SDV_CRYPTO_SM2_CMP_FUNC_TC001: compare poublic key +SDV_CRYPTO_SM2_CMP_FUNC_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13" + +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001: decode asn1 1 +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001:"3072022100bd8ca9a0f10c6a0bd3300b245c9c6d97ab8edb20dbdb7fdfb719b8620bfba572021f54ef29045cfc7184ec183d0d794a36df208a2f77b412018a17f5dd7adfb7dd0420c5b1da28f1be6e75649509a103cef7a47ba0e458b71e2e3b83eeb06745a991e3040a8bd3ff51df65a08aeab4" + +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001: decode asn1 2 +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001:"3081980221008b842a24df49ff13d55b6234881cfe00d794feede80dd2065fe76ca0ea37d68a022100efecf6bf2dbe95989f1aafe57ce7b46c988f9eb16bf0053e82295d094b8a6fd804201a5145940fee4e3442911961614ce6a9ebfd14e83634b6feea3d09efaa4c108f042eb8171656b4038d693d20031a3e7ca395fdf0a1b930083abef1b94dddfef6c6e84919f2b1c45b74770492f896c17b" + +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001: decode asn1 3 +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001:"308196022042e0a291054e36b96778a50ad295d2fb56451ccf7faaa47b7bb81b0a7f939be102203da0f5c0f838b5250d68cacba4b998c700b3a9df7e05ab8f569537a86be0358c0420a93aa5cfeb1fff1817c648325a1b2d38dfc60ad9a51cd676beedad625d4eae9d042efbadb6a4ef915fc73a466bd68bb038ae823924ab604d83a0bc49815ddda7ca1f4826bad431a87fff02396a6f1321" + +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001: decode asn1 4 +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001:"308190022100acda639b4febf066a4e1065eae6a976b7ed0a75f23718ba507e97c2dc3b7a7d90220361436d7d807199adb60ad5018dda1a0874459b5e1d2069f24bd40ab7bcbe9750420c3991f120c4bf40552b85f1050d21c03e2696fe13c765d2fcb4f4ee73cabfbb00427de6f2fce61a0a4aaed6ba86b61dd1387477bdd8178509245184e990808e9622c1124903de07922" + +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001: decode asn1 5 +SDV_CRYPTO_SM2_ENC_DECODE_FUNC_TC001:"3081b7022100a250cf8c5b5037ab8db6daea881b39a126ec53ea25373a77124c9fcbeb02cde102201844c15f8575fef935373d41a9312222fed67bb7789389df8f73ecaf73238e060420dc26a4c7c10efef0994064599a30189020424b3d6c7fdfc8a3d27988b40b7fe6044e37b2ed322053e95ff584a1bdaecb28934d7cc96e999f0a816281ad655cfa6be380d052e3780187834124cf44773b194ca64a5852cbefa173d2960997de98ca67f95a455674b85b0fdfff1c48a5c0" diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_exchange.c b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_exchange.c new file mode 100644 index 00000000..f599015b --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_exchange.c @@ -0,0 +1,970 @@ +/* + * 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_BASE test_suite_sdv_eal_sm2 */ + +/* BEGIN_HEADER */ + +#include "eal_pkey_local.h" +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC001 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: R is not set. + * @precon Test Vectors for SM2: public key, private key + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set userId, server, private key and generate r, expected result 2. + * 3. ctx2: set userId and public key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 4. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. CRYPT_SM2_R_NOT_SET + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC001(Hex *prvKey, Hex *pubKey) +{ + uint8_t userId[10] = {0}; + uint8_t localR[65]; + int32_t server = 1; + uint8_t out[64]; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SM2_R_NOT_SET); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC002 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: R is not generate. + * @precon Test Vectors for SM2: public key, private key, R. + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set userId, server and private key, expected result 2. + * 3. ctx2: set userId, R and public key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 4. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. CRYPT_SM2_R_NOT_SET + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC002(Hex *prvKey, Hex *pubKey, Hex *R) +{ + TestMemInit(); + CRYPT_RandRegist(RandFunc); + uint8_t userId[10] = {0}; + int32_t server = 1; + uint8_t out[64]; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SM2_R_NOT_SET); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC003 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: UserId is not set at the local end. + * @precon Test Vectors for SM2: public key, private key, R. + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set server, private key and generate r, expected result 2. + * 3. ctx2: set userId, R and public key, expected result 3. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC003(Hex *prvKey, Hex *pubKey, Hex *R) +{ + uint8_t userId[10] = {0}; + int32_t server = 1; + uint8_t localR[65]; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC004 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: UserId is not set at the peer end. + * @precon Test Vectors for SM2: public key, private key, R. + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set userId, server, private key and generate r, expected result 2. + * 3. ctx2: set R and public key, expected result 3. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC004(Hex *prvKey, Hex *pubKey, Hex *R) +{ + TestMemInit(); + CRYPT_RandRegist(RandFunc); + uint8_t userId[10] = {0}; + int32_t server = 1; + uint8_t localR[65]; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC005 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: UserId is not set at the peer end. + * @precon Test Vectors for SM2: public key, private key, R. + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set userId, server, private key and generate r, expected result 2. + * 3. ctx2: set R, server and public key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 4. + * 5. Set client and generate R for ctx1, set client for ctx2, expected result 5. + * 6. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 6. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC005(Hex *prvKey, Hex *pubKey, Hex *R) +{ + uint8_t userId[10] = {0}; + int32_t server = 1; + uint8_t out[64]; + uint8_t localR[65]; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); + + server = 0; + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC006 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: Test the validity of input parameters. + * @precon Test Vectors for SM2: public key, private key, R. + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set userId, server, private key and generate r, expected result 2. + * 3. ctx2: set userId, R and public key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method: + * (1) ctx1 = NULL, expected result 4. + * (2) ctx2 = NULL, expected result 5. + * (3) out = NULL, expected result 6. + * (4) outLen = NULL, expected result 7. + * (5) outLen = 0, expected result 8. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. CRYPT_NULL_INPUT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC006(Hex *prvKey, Hex *pubKey, Hex *R) +{ + uint8_t userId[10] = {0}; + int32_t server = 1; + uint8_t out[64]; + uint8_t localR[65]; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(NULL, ctx2, out, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, NULL, out, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, NULL, &outLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, NULL) == CRYPT_NULL_INPUT); + outLen = 0; + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_NULL_INPUT); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_API_TC007 + * @title SM2: CRYPT_EAL_PkeyComputeShareKey Test: Test the validity of input parameters. + * @precon Test Vectors for SM2: public key, private key, R. + * @brief + * 1. Init the Drbg and create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1. + * 2. ctx1: set userId, server, private key and generate r, expected result 2. + * 3. ctx2: set userId, R and private key, expected result 3. + * 4. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 4. + * 5. Set public key for ctx1 and ctx2, expected result 5. + * 6. Generate R for ctx1, expected result 6. + * 7. Call the CRYPT_EAL_PkeyComputeShareKey method, expected result 7. + * @expect + * 1. Success, and two contexts are not NULL. + * 2-3. CRYPT_SUCCESS + * 4. CRYPT_SM2_ERR_EMPTY_KEY + * 5-7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_API_TC007(Hex *prvKey, Hex *pubKey, Hex *R) +{ + TestMemInit(); + CRYPT_RandRegist(RandFunc); + uint8_t userId[10] = {0}; + int32_t server = 1; + uint8_t out[64]; + uint8_t localR[65]; + uint32_t outLen = sizeof(out); + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx2, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SM2_ERR_EMPTY_KEY); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx1, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_CTRL_API_TC001 + * @title SM2 CRYPT_EAL_PkeyCtrl: Test generate R and get R. + * @precon nan + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl, and all parameters are valid, expected result 2 + * 3. Set the error random number method so that it returns zero, expected result 3 + * 4. Call the CRYPT_EAL_PkeyCtrl, and all parameters are valid, expected result 4 + * 5. Set the correct random number method. + * 6. Call the CRYPT_EAL_PkeyCtrl, opt = CRYPT_CTRL_GENE_SM2_R: + * (1) val = null, and other parameters are valid, expected result 5 + * (2) val = null, len = 0, and other parameters are valid, expected result 6 + * (3) val != null, len is not enough, and other parameters are valid, expected result 7 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NO_REGIST_RAND + * 3. CRYPT_SUCCESS + * 4. CRYPT_SM2_ERR_TRY_CNT + * 5-6. CRYPT_NULL_INPUT + * 7. CRYPT_ECC_BUFF_LEN_NOT_ENOUGH + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_CTRL_API_TC001(void) +{ + uint8_t localR[65]; + uint8_t zero[RAND_BUF_LEN] = {0}; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_NO_REGIST_RAND); + + CRYPT_RandRegist(FakeRandFunc); + ASSERT_TRUE(SetFakeRandOutput(zero, sizeof(zero)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SM2_ERR_TRY_CNT); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GENE_SM2_R, NULL, sizeof(localR)) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GENE_SM2_R, NULL, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE( + CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR) - 1) == CRYPT_ECC_BUFF_LEN_NOT_ENOUGH); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_CTRL_API_TC002 + * @title SM2 CRYPT_EAL_PkeyCtrl: Test Set R. + * @precon vector: valid R. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl, opt = CRYPT_CTRL_SET_SM2_R: + * (1) val = null, and other parameters are valid, expected result 2 + * (2) val = null, len = 0, and other parameters are valid, expected result 3 + * (3) val != null, len = R->len - 1, and other parameters are valid, expected result 4 + * (4) val != null, len = R->len + 1, and other parameters are valid, expected result 5 + * (5) val is 0 and the length is 65 bytes, and other parameters are valid, expected result 6 + * (6) and other parameters are valid, expected result 7 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_NULL_INPUT + * 4-6. CRYPT_ECC_ERR_POINT_CODE + * 7. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_CTRL_API_TC002(Hex *R) +{ + uint8_t zero[65]; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_R, NULL, R->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_R, NULL, 0) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_R, R->x, R->len - 1) == CRYPT_ECC_ERR_POINT_CODE); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_R, R->x, R->len + 1) == CRYPT_ECC_ERR_POINT_CODE); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_R, zero, sizeof(zero)) == CRYPT_ECC_ERR_POINT_CODE); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_CTRL_API_TC003 + * @title SM2 CRYPT_EAL_PkeyCtrl: Test set sm2 server/client. + * @precon nan + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl, opt = CRYPT_CTRL_SET_SM2_SERVER: + * (1) val = null, and other parameters are valid, expected result 2 + * (2) val = null, len = 0, and other parameters are valid, expected result 3 + * (3) val(type is uint32_t, value is 2), len is 4, and other parameters are valid, expected result 4 + * (4) val(type is uint32_t, value is 0xffffffff), len is 4, and other parameters are valid, expected result 5 + * (5) val(type is uint8_t, value is 0), len is 1, and other parameters are valid, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_NULL_INPUT + * 4-5. CRYPT_SM2_INVALID_SERVER_TYPE + * 6. CRYPT_SM2_ERR_CTRL_LEN + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_CTRL_API_TC003(void) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + uint32_t server = 1; + uint8_t badServer = 1; + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_SERVER, NULL, sizeof(uint32_t)) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_SERVER, NULL, 0) == CRYPT_NULL_INPUT); + server = 2; + ASSERT_TRUE( + CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(uint32_t)) == CRYPT_SM2_INVALID_SERVER_TYPE); + server = 0xffffffff; + ASSERT_TRUE( + CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(uint32_t)) == CRYPT_SM2_INVALID_SERVER_TYPE); + ASSERT_TRUE( + CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_SERVER, &badServer, sizeof(uint8_t)) == CRYPT_SM2_ERR_CTRL_LEN); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001 + * @title SM2 EAL key exchange. + * @precon Vectors: + * server: The value 1 indicates the initiator, and the value 0 indicates the responder. + * User 1: private key, generate random number r, userId1 + * User 2: public key, R, userId2 + * @brief + * 1. Create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1 + * 2. Set userId1 and server for ctx1, expected result 2 + * 3. Mock BN_RandRange to generate r, expected result 3 + * 4. ctx1 generate r, expected result 4 + * 5. Set userId2 and R for ctx2, expected result 5 + * 6. Set private key for ctx1, expected result 6 + * 7. Set public key for ctx2, expected result 7 + * 8. Compute the shared key, expected result 8 + * 9. Compare the output shared secret and shared secret vector, expected result 9 + * 10. Duplicate ctx1 and ctx2, expected result 10 + * 11. dupCtx1 generate r, expected result 11 + * 12. Set R for dupCtx2, expected result 12 + * 13. Compute share secret with duplicated contexts, expected result 13 + * 14. Compare the output shared secret and shared secret vector, expected result 14 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-8. CRYPT_SUCCESS + * 9. The two shared secrets are the same. + * 10. Success, and two contexts are not NULL. + * 11-13. Success, and two contexts are not NULL. + * 14. The two shared secrets are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001( + Hex *prvKey, Hex *pubKey, Hex *r, Hex *R, Hex *shareKey, Hex *userId1, Hex *userId2, int server) +{ + uint8_t out[500]; + uint8_t localR[65]; + uint32_t outLen = shareKey->len; + FuncStubInfo tmpRpInfo; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *dupCtx1 = NULL; + CRYPT_EAL_PkeyCtx *dupCtx2 = NULL; + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx2 != NULL); + ASSERT_TRUE(ctx1 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId1->x, userId1->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + ASSERT_TRUE(SetFakeRandOutput(r->x, r->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId2->x, userId2->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(outLen == shareKey->len); + ASSERT_TRUE(memcmp(out, shareKey->x, shareKey->len) == 0); + + dupCtx1 = CRYPT_EAL_PkeyDupCtx(ctx1); + dupCtx2 = CRYPT_EAL_PkeyDupCtx(ctx2); + ASSERT_TRUE(dupCtx1 != NULL && dupCtx2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(dupCtx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(dupCtx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(dupCtx1, dupCtx2, out, &outLen), CRYPT_SUCCESS); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_EAL_PkeyFreeCtx(dupCtx1); + CRYPT_EAL_PkeyFreeCtx(dupCtx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC002 + * @title SM2 EAL key exchange. + * @precon Vectors: + * server: The value 1 indicates the initiator, and the value 0 indicates the responder. + * User 1: public key and private key, generate random number r, userId1 + * User 2: public key and private key, R, userId2 + * @brief + * 1. Create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1 + * 2. Set userId1 and server for ctx1, expected result 2 + * 3. Mock BN_RandRange to generate r, expected result 3 + * 4. ctx1 generate r, expected result 4 + * 5. Set userId2 and R for ctx2, expected result 5 + * 6. Set public key and private key for ctx1, expected result 6 + * 7. Set public key and private key for ctx2, expected result 7 + * 8. Compute the shared key, expected result 8 + * 9. Compare the output shared secret and shared secret vector, expected result 9 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-8. CRYPT_SUCCESS + * 9. The two shared secrets are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC002(Hex *prvKey1, Hex *pubKey2, Hex *prvKey2, Hex *pubKey1, Hex *r, Hex *R, + Hex *shareKey, Hex *userId1, Hex *userId2, int server) +{ + uint8_t out[500]; + uint8_t localR[65]; + uint8_t badId[10] = {0}; + uint32_t outLen = shareKey->len; + FuncStubInfo tmpRpInfo; + CRYPT_EAL_PkeyPrv prv1 = {0}; + CRYPT_EAL_PkeyPub pub2 = {0}; + CRYPT_EAL_PkeyPrv prv2 = {0}; + CRYPT_EAL_PkeyPub pub1 = {0}; + SetSm2PrvKey(&prv1, prvKey1->x, prvKey1->len); + SetSm2PubKey(&pub2, pubKey2->x, pubKey2->len); + SetSm2PrvKey(&prv2, prvKey2->x, prvKey2->len); + SetSm2PubKey(&pub1, pubKey1->x, pubKey1->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL); + ASSERT_TRUE(ctx2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, badId, sizeof(badId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId1->x, userId1->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + ASSERT_TRUE(SetFakeRandOutput(r->x, r->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, badId, sizeof(badId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId2->x, userId2->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx1, &pub1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx2, &prv2) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub2) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == shareKey->len); + ASSERT_TRUE(memcmp(out, shareKey->x, shareKey->len) == 0); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003 + * @title SM2: Generate a key pair for key exchange. + * @precon nan + * @brief + * 1. Create four contexts(selfCtx1, peerCtx1, selfCtx2, peerCtx2) of the SM2 algorithm, expected result 1 + * 2. Init the DRBG, expected result 2. + * 3. Set pkg for selfCtx1 and selfCtx2, expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen to generate a key pair for selfCtx1, expected result 4 + * 5. Call the CRYPT_EAL_PkeyGen to generate a key pair for selfCtx2, expected result 5 + * 6. Get the public key from selfCtx2 and set it to peerCtx2, expected result 6 + * 7. Get the public key from selfCtx1 and set it to peerCtx1, expected result 7 + * 8. Set userId and server for selfCtx1 and selfCtx2, expected result 8 + * 9. selfCtx1 and selfCtx2 genenrate r, expected result 9 + * 10. Set userId and r for peerCtx1 and peerCtx2, expected result 10 + * 11. Compute the shared key from the privite value in selfCtx1 and the public vlaue in peerCtx1, expected result 11 + * 12. Compute the shared key from the privite value in selfCtx2 and the public vlaue in peerCtx2, expected result 12 + * 13. Compare the shared keys computed in the preceding two steps, expected result 13 + * @expect + * 1. Success, and contexts are not NULL. + * 2. Success. + * 3-12. CRYPT_SUCCESS. + * 13. The two shared keys are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003(int pkg) +{ + uint8_t userId1[10]; + uint8_t userId2[10]; + uint8_t out1[500]; + uint8_t out2[500]; + uint8_t localR1[65]; + uint8_t localR2[65]; + uint32_t outLen = sizeof(out1); + int32_t server = 1; + int32_t client = 0; + + (void)memset_s(userId1, sizeof(userId1), 'A', sizeof(userId1)); + (void)memset_s(userId2, sizeof(userId2), 'B', sizeof(userId2)); + + uint8_t pubKey1[65]; + uint8_t pubKey2[65]; + CRYPT_EAL_PkeyPub pub1, pub2; + SetSm2PubKey(&pub1, pubKey1, sizeof(pubKey1)); + SetSm2PubKey(&pub2, pubKey2, sizeof(pubKey2)); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *selfCtx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *selfCtx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *peerCtx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *peerCtx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(peerCtx1 != NULL); + ASSERT_TRUE(selfCtx2 != NULL); + ASSERT_TRUE(selfCtx1 != NULL); + ASSERT_TRUE(peerCtx2 != NULL); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx1, CRYPT_CTRL_SET_SM2_PKG, &pkg, sizeof(pkg)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx2, CRYPT_CTRL_SET_SM2_PKG, &pkg, sizeof(pkg)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(selfCtx1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(selfCtx2) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(selfCtx1, &pub1) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(selfCtx2, &pub2) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(peerCtx1, &pub2) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(peerCtx2, &pub1) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx1, CRYPT_CTRL_SET_SM2_USER_ID, userId1, sizeof(userId1)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx1, CRYPT_CTRL_GENE_SM2_R, localR1, sizeof(localR1)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx2, CRYPT_CTRL_SET_SM2_USER_ID, userId2, sizeof(userId2)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx2, CRYPT_CTRL_SET_SM2_SERVER, &client, sizeof(int32_t)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(selfCtx2, CRYPT_CTRL_GENE_SM2_R, localR2, sizeof(localR2)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(peerCtx1, CRYPT_CTRL_SET_SM2_R, localR2, sizeof(localR2)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(peerCtx1, CRYPT_CTRL_SET_SM2_USER_ID, userId2, sizeof(userId2)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(peerCtx2, CRYPT_CTRL_SET_SM2_R, localR1, sizeof(localR1)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(peerCtx2, CRYPT_CTRL_SET_SM2_USER_ID, userId1, sizeof(userId1)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(selfCtx1, peerCtx1, out1, &outLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(selfCtx2, peerCtx2, out2, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out1, out2, outLen) == 0); + +exit: + CRYPT_RandRegist(NULL); + CRYPT_EAL_PkeyFreeCtx(selfCtx1); + CRYPT_EAL_PkeyFreeCtx(selfCtx2); + CRYPT_EAL_PkeyFreeCtx(peerCtx1); + CRYPT_EAL_PkeyFreeCtx(peerCtx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC004 + * @title SM2 EAL key exchange: Default identity (server). + * @precon Vectors: + * User 1: private key, generate random number r, userId1 + * User 2: public key, R, userId2 + * @brief + * 1. Create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1 + * 2. Set userId1 for ctx1, expected result 2 + * 3. Mock BN_RandRange to generate r, expected result 3 + * 4. ctx1 generate r, expected result 4 + * 5. Set userId2 and R for ctx2, expected result 5 + * 6. Set private key for ctx1, expected result 6 + * 7. Set public key for ctx2, expected result 7 + * 8. Compute the shared key, expected result 8 + * 9. Compare the output shared secret and shared secret vector, expected result 9 + * 10. Copy ctx1 and ctx2, expected result 10 + * 11. cpyCtx1 generate r, expected result 11 + * 12. Set R for cpyCtx2, expected result 12 + * 13. Compute share secret with duplicated contexts, expected result 13 + * 14. Compare the output shared secret and shared secret vector, expected result 14 + * @expect + * 1. Success, and two contexts are not NULL. + * 2-8. CRYPT_SUCCESS + * 9. The two shared secrets are the same. + * 10. Success, and two contexts are not NULL. + * 11-13. Success, and two contexts are not NULL. + * 14. The two shared secrets are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC004( + Hex *prvKey, Hex *pubKey, Hex *r, Hex *R, Hex *shareKey, Hex *userId1, Hex *userId2) +{ + uint8_t out[500]; + uint8_t localR[65]; + uint32_t outLen = shareKey->len; + FuncStubInfo tmpRpInfo; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyCtx *cpyCtx1 = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx2 = NULL; + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx1 != NULL && ctx2 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId1->x, userId1->len) == CRYPT_SUCCESS); + + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + ASSERT_TRUE(SetFakeRandOutput(r->x, r->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId2->x, userId2->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(outLen == shareKey->len); + ASSERT_TRUE(memcmp(out, shareKey->x, shareKey->len) == 0); + + cpyCtx1 = calloc(1, sizeof(CRYPT_EAL_PkeyCtx)); + cpyCtx2 = calloc(1, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx1 != NULL && cpyCtx2 != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx1, ctx1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(cpyCtx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx2, ctx2), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(cpyCtx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(cpyCtx1, cpyCtx2, out, &outLen), CRYPT_SUCCESS); + ASSERT_TRUE(outLen == shareKey->len); + ASSERT_TRUE(memcmp(out, shareKey->x, shareKey->len) == 0); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); + CRYPT_EAL_PkeyFreeCtx(cpyCtx1); + CRYPT_EAL_PkeyFreeCtx(cpyCtx2); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_EXCHANGE_CHECK_TC001 + * @title SM2 EAL key exchange check. + * @precon Vectors: + * server: The value 1 indicates the initiator, and the value 0 indicates the responder. + * User 1: private key, generate random number r, userId1, optional term S + * User 2: public key , R, userId2, optional term S + * @brief + * 1. Create two contexts(ctx1, ctx2) of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl method, opt = CRYPT_CTRL_SM2_DO_CHECK, expected result 2 + * 3. Set userId1 and server for ctx1, expected result 3 + * 4. Mock BN_RandRange to generate r, expected result 4 + * 5. ctx1 generate r, expected result 5 + * 6. Set userId2 and R for ctx2, expected result 6 + * 7. Set private key for ctx1, expected result 7 + * 8. Set public key key for ctx2, expected resul 8 + * 9. Compute the shared key, expected result 9 + * 10. Compare the output shared secret and shared secret vector, expected result 10 + * 11. Call the CRYPT_EAL_PkeyCtrl method: + * (1) opt = CRYPT_CTRL_SM2_DO_CHECK val len not equal to SM3_MD_SIZE, expected result 11 + * (2) opt = CRYPT_CTRL_SM2_GET_SEND_CHECK, val len not equal to SM3_MD_SIZE, expected result 12 + * (3) opt = CRYPT_CTRL_SM2_GET_SEND_CHECK, and Other parameters are valid, expected result 13 + * 12. Compare the output of step 11.(3) and selfS vector, expected result 14 + * 13. Call the CRYPT_EAL_PkeyCtrl method, opt = CRYPT_CTRL_SM2_DO_CHECK, expected result 15 + * @expect + * 1. Success, and two contexts are not NULL. + * 2. CRYPT_SM2_ERR_S_NOT_SET + * 3-9. CRYPT_SUCCESS + * 10. The two shared secrets are the same. + * 11. CRYPT_SM2_ERR_DATA_LEN + * 12. CRYPT_SM2_BUFF_LEN_NOT_ENOUGH + * 13. CRYPT_SUCCESS + * 14. Both are the same. + * 15. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_EXCHANGE_CHECK_TC001(Hex *prvKey, Hex *pubKey, Hex *r, Hex *R, Hex *shareKey, Hex *userId1, + Hex *userId2, int server, Hex *peerS, Hex *selfS) +{ + uint8_t out[500]; + uint8_t localR[65]; + uint32_t outLen = shareKey->len; + FuncStubInfo tmpRpInfo; + uint8_t val[selfS->len]; + CRYPT_EAL_PkeyPrv prv = {0}; + CRYPT_EAL_PkeyPub pub = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx1 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + CRYPT_EAL_PkeyCtx *ctx2 = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx2 != NULL); + ASSERT_TRUE(ctx1 != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SM2_DO_CHECK, peerS->x, peerS->len) == CRYPT_SM2_ERR_S_NOT_SET); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_USER_ID, userId1->x, userId1->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)) == CRYPT_SUCCESS); + + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + ASSERT_TRUE(SetFakeRandOutput(r->x, r->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_GENE_SM2_R, localR, sizeof(localR)) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_USER_ID, userId2->x, userId2->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx2, CRYPT_CTRL_SET_SM2_R, R->x, R->len) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx1, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx2, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyComputeShareKey(ctx1, ctx2, out, &outLen) == CRYPT_SUCCESS); + ASSERT_TRUE(outLen == shareKey->len); + ASSERT_TRUE(memcmp(out, shareKey->x, shareKey->len) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SM2_DO_CHECK, peerS->x, peerS->len - 1) == CRYPT_SM2_ERR_DATA_LEN); + ASSERT_TRUE( + CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SM2_GET_SEND_CHECK, val, selfS->len - 1) == CRYPT_SM2_BUFF_LEN_NOT_ENOUGH); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SM2_GET_SEND_CHECK, val, selfS->len) == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(val, selfS->x, selfS->len) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx1, CRYPT_CTRL_SM2_DO_CHECK, peerS->x, peerS->len) == CRYPT_SUCCESS); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(ctx1); + CRYPT_EAL_PkeyFreeCtx(ctx2); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_exchange.data b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_exchange.data new file mode 100644 index 00000000..2f495e88 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_exchange.data @@ -0,0 +1,54 @@ + +SDV_CRYPTO_SM2_EXCHANGE_API_TC001: GBT.32918.5-2017, exchange peer ctx no set R +SDV_CRYPTO_SM2_EXCHANGE_API_TC001:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d" + +SDV_CRYPTO_SM2_EXCHANGE_API_TC002: GBT.32918.5-2017, exchange no gen r +SDV_CRYPTO_SM2_EXCHANGE_API_TC002:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_EXCHANGE_API_TC003: GBT.32918.5-2017, exchange no self id +SDV_CRYPTO_SM2_EXCHANGE_API_TC003:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_EXCHANGE_API_TC004: GBT.32918.5-2017, exchange no peer id +SDV_CRYPTO_SM2_EXCHANGE_API_TC004:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_EXCHANGE_API_TC005: GBT.32918.5-2017, exchange dual server client +SDV_CRYPTO_SM2_EXCHANGE_API_TC005:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_EXCHANGE_API_TC006: GBT.32918.5-2017, exchange wrong input +SDV_CRYPTO_SM2_EXCHANGE_API_TC006:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_EXCHANGE_API_TC007: GBT.32918.5-2017, exchange no key +SDV_CRYPTO_SM2_EXCHANGE_API_TC007:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_CTRL_API_TC001 Ctrl Gen R +SDV_CRYPTO_SM2_CTRL_API_TC001: + +SDV_CRYPTO_SM2_CTRL_API_TC002 Ctrl set r +SDV_CRYPTO_SM2_CTRL_API_TC002:"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe" + +SDV_CRYPTO_SM2_CTRL_API_TC003 Ctrl set client/server +SDV_CRYPTO_SM2_CTRL_API_TC003: + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001: GBT.32918.5-2017, key exchange vector 1 +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"d4de15474db74d06491c440d305e012400990f3e390c7e87153c12db2ea60bb3":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe":"6c89347354de2484c60b4ab1fde4c6e5":"31323334353637383132333435363738":"31323334353637383132333435363738":1 + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001: GBT.32918.5-2017, key exchange vector 2 +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC001:"785129917D45A9EA5437A59356B82338EAADDA6CEB199088F14AE10DEFA229B5":"04160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C942324A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F":"7E07124814B309489125EAED101113164EBF0F3458C5BD88335C1F9D596243D6":"0464CED1BDBC99D590049B434D0FD73428CF608A5DB8FE5CE07F15026940BAE40E376629C7AB21E7DB260922499DDB118F07CE8EAAE3E7720AFEF6A5CC062070C0":"6c89347354de2484c60b4ab1fde4c6e5":"31323334353637383132333435363738":"31323334353637383132333435363738":0 + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC002: GBT.32918.5-2017, multi set key id +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC002:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"785129917D45A9EA5437A59356B82338EAADDA6CEB199088F14AE10DEFA229B5":"04160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C942324A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F":"d4de15474db74d06491c440d305e012400990f3e390c7e87153c12db2ea60bb3":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe":"6c89347354de2484c60b4ab1fde4c6e5":"31323334353637383132333435363738":"31323334353637383132333435363738":1 + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC002: GBT.32918.5-2017, multi set key id +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC002:"785129917D45A9EA5437A59356B82338EAADDA6CEB199088F14AE10DEFA229B5":"04160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C942324A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F":"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"7E07124814B309489125EAED101113164EBF0F3458C5BD88335C1F9D596243D6":"0464CED1BDBC99D590049B434D0FD73428CF608A5DB8FE5CE07F15026940BAE40E376629C7AB21E7DB260922499DDB118F07CE8EAAE3E7720AFEF6A5CC062070C0":"6c89347354de2484c60b4ab1fde4c6e5":"31323334353637383132333435363738":"31323334353637383132333435363738":0 + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003 Gen Exchange +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003:0 + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003 Gen Exchange +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC003:1 + +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC004: GBT.32918.5-2017, default role test +SDV_CRYPTO_SM2_EXCHANGE_FUNC_TC004:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"d4de15474db74d06491c440d305e012400990f3e390c7e87153c12db2ea60bb3":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe":"6c89347354de2484c60b4ab1fde4c6e5":"31323334353637383132333435363738":"31323334353637383132333435363738" + +SDV_CRYPTO_SM2_EXCHANGE_CHECK_TC001: GBT.32918.5-2017, key exchange vector 1 +SDV_CRYPTO_SM2_EXCHANGE_CHECK_TC001:"81eb26e941bb5af16df116495f90695272ae2cd63d6c4ae1678418be48230029":"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"d4de15474db74d06491c440d305e012400990f3e390c7e87153c12db2ea60bb3":"04acc27688a6f7b706098bc91ff3ad1bff7dc2802cdb14ccccdb0a90471f9bd7072fedac0494b2ffc4d6853876c79b8f301c6573ad0aa50f39fc87181e1a1b46fe":"6c89347354de2484c60b4ab1fde4c6e5":"31323334353637383132333435363738":"31323334353637383132333435363738":1:"d3a0fe15dee185ceae907a6b595cc32a266ed7b3367e9983a896dc32fa20f8eb":"18c7894b3816df16cf07b05c5ec0bef5d655d58f779cc1b400a4f3884644db88" diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c new file mode 100644 index 00000000..30d47c22 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c @@ -0,0 +1,989 @@ +/* + * 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_BASE test_suite_sdv_eal_sm2 */ + +/* BEGIN_HEADER */ + +#include "eal_pkey_local.h" + +#define SM2_SIGN_MAX_LEN 72 +#define SM2_PRVKEY_MAX_LEN 32 +#define SM2_PUBKEY_LEN 65 + +/* END_HEADER */ + +/** + * @test SDV_CRYPTO_SM2_GET_PUB_API_TC001 + * @title SM2 CRYPT_EAL_PkeyGetPub: Test the validity of parameters. + * @precon Prepare valid public key. + * @brief + * 1. Create the context of the sm2 algorithm, expected result 1 + * 2. Set the valid public key, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPub method to set public key: + * (1) pub.data = NULL, expected result 3 + * (2) pub.len is invalid (pubKey.len - 1), expected result 4 + * (3) all parameters are valid, expected result 5 + * (4) pub.len = prvKey.len + 1, expected result 6 + * 4. Compare the getted key and vector, expected result 7 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_NULL_INPUT + * 4. CRYPT_ECC_BUFF_LEN_NOT_ENOUGH + * 5. CRYPT_SUCCESS + * 6. CRYPT_SUCCESS + * 7. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GET_PUB_API_TC001(Hex *pubKey) +{ + TestMemInit(); + uint8_t buf[SM2_PUBKEY_LEN]; + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_PkeyPub pub, pubOut; + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + SetSm2PubKey(&pubOut, NULL, sizeof(buf)); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE_AND_LOG("NULL pubKey buffer", CRYPT_EAL_PkeyGetPub(ctx, &pubOut) == CRYPT_NULL_INPUT); + + pubOut.key.eccPub.data = buf; + pubOut.key.eccPub.len = sizeof(buf) - 1; + ASSERT_TRUE_AND_LOG("64 len pubKey buffer", CRYPT_EAL_PkeyGetPub(ctx, &pubOut) == CRYPT_ECC_BUFF_LEN_NOT_ENOUGH); + + pubOut.key.eccPub.data = buf; + pubOut.key.eccPub.len = sizeof(buf); + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(ctx, &pubOut) == CRYPT_SUCCESS); + + pubOut.key.eccPub.data = buf; + pubOut.key.eccPub.len = sizeof(buf) + 1; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPub(ctx, &pubOut) == CRYPT_SUCCESS); + + ASSERT_TRUE(pubOut.key.eccPub.len == SM2_PUBKEY_LEN); + ASSERT_TRUE(memcmp(buf, pubKey->x, pubKey->len) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GET_PRV_API_TC001 + * @title SM2 CRYPT_EAL_PkeyGetPrv: Test the validity of parameters. + * @precon Prepare valid private key. + * @brief + * 1. Create the context of the sm2 algorithm, expected result 1 + * 2. Set the valid private key, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGetPrv method to set private key: + * (1) prv.data = NULL, expected result 3 + * (2) prv.len is invalid (prvKey.len - 1), expected result 4 + * (3) all parameters are valid, expected result 5 + * (4) prv.len = prvKey.len + 1, expected result 6 + * 4. Compare the getted key and vector, expected result 7 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_NULL_INPUT + * 4. CRYPT_BN_BUFF_LEN_NOT_ENOUGH + * 5. CRYPT_SUCCESS + * 6. CRYPT_SUCCESS + * 7. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GET_PRV_API_TC001(Hex *prvKey) +{ + TestMemInit(); + uint8_t buf[SM2_PRVKEY_MAX_LEN]; + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_PkeyPrv prv, prvOut; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + SetSm2PrvKey(&prvOut, NULL, prvKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(ctx, &prvOut) == CRYPT_NULL_INPUT); + + prvOut.key.eccPrv.data = buf; + prvOut.key.eccPrv.len = prvKey->len - 1; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(ctx, &prvOut) == CRYPT_BN_BUFF_LEN_NOT_ENOUGH); + + prvOut.key.eccPrv.data = buf; + prvOut.key.eccPrv.len = prvKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(ctx, &prvOut) == CRYPT_SUCCESS); + + prvOut.key.eccPrv.data = buf; + prvOut.key.eccPrv.len = prvKey->len + 1; + ASSERT_TRUE(CRYPT_EAL_PkeyGetPrv(ctx, &prvOut) == CRYPT_SUCCESS); + + ASSERT_TRUE(prvOut.key.eccPrv.len == prvKey->len); + ASSERT_TRUE(memcmp(buf, prvKey->x, prvKey->len) == 0); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SET_PUB_API_TC001 + * @title SM2 CRYPT_EAL_PkeySetPub: Test the validity of parameters. + * @precon Prepare valid public key. + * @brief + * 1. Create the context of the sm2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetPrv method to set private key: + * (1) pub.len is invalid (pubKey.len - 1), expected result 2 + * (2) pub.len is invalid (pubKey.len + 1), expected result 3 + * (3) public key is all 0x00, expected result 4 + * (4) ctx.id != pub.id, expected result 5 + * @expect + * 1. Success, and the context is not NULL. + * 2-4. CRYPT_ECC_ERR_POINT_CODE + * 5. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SET_PUB_API_TC001(Hex *pubKey) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_PkeyPub pub = {0}; + uint8_t zero[SM2_PUBKEY_LEN] = {0}; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len - 1); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_ECC_ERR_POINT_CODE); + + pub.key.eccPub.len = pubKey->len + 1; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_ECC_ERR_POINT_CODE); + + pub.key.eccPub.len = pubKey->len; + pub.key.eccPub.data = zero; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_ECC_ERR_POINT_CODE); + + pub.id = CRYPT_PKEY_ED25519; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_EAL_ERR_ALGID); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SET_PRV_API_TC001 + * @title SM2 CRYPT_EAL_PkeySetPrv: Test the validity of parameters. + * @precon Prepare valid private key. + * @brief + * 1. Create the context of the sm2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeySetPrv method to set private key: + * (1) prv.len is invalid (prvKey.len + 1), expected result 2 + * (2) private key is all 0x00, expected result 2 + * (3) private key is all 0xFF, expected result 2 + * (4) value of private key == order(curve_sm2) - 1, expected result 2 + * (5) ctx id is wrong, expected result 3 + * @expect + * 1. Success, and the context is not NULL. + * 2. CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY + * 3. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SET_PRV_API_TC001(Hex *prvKey) +{ + uint8_t zero[SM2_PRVKEY_MAX_LEN] = {0}; + uint8_t fullF[SM2_PRVKEY_MAX_LEN]; + uint8_t prvKeyCopy[SM2_PRVKEY_MAX_LEN + 1] = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + + (void)memset_s(fullF, sizeof(fullF), 0xff, sizeof(fullF)); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(memcpy_s(prvKeyCopy, SM2_PRVKEY_MAX_LEN + 1, prvKey->x, prvKey->len) == CRYPT_SUCCESS); + SetSm2PrvKey(&prv, prvKeyCopy, prvKey->len + 1); + ASSERT_TRUE_AND_LOG("invalid prv len", CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY); + + prv.key.eccPrv.len = prvKey->len; + prv.key.eccPrv.data = zero; + ASSERT_TRUE_AND_LOG("zero data key", CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY); + prv.key.eccPrv.data = fullF; + ASSERT_TRUE_AND_LOG("full 1 key", CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY); + + prv.id = CRYPT_PKEY_SM2; + prv.key.eccPrv.data = prvKey->x; + prv.key.eccPrv.len = prvKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY); + + prv.id = CRYPT_PKEY_ED25519; + prv.key.eccPrv.data = prvKey->x; + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_EAL_ERR_ALGID); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GET_SIGN_LEN_API_TC001 + * @title SM2: CRYPT_EAL_PkeyGetSignLen test. + * @precon nan + * @brief + * 1. Create the context of the sm2 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetSignLen method, where pkey is NULL, expected result 2. + * 3. Call the CRYPT_EAL_PkeyGetSignLen method, where pkey is valid, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. Reutrn 0. + * 3. Return SM2_SIGN_MAX_LEN(72) + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GET_SIGN_LEN_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeyGetSignLen(NULL) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyGetSignLen(ctx) == SM2_SIGN_MAX_LEN); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GET_KEY_LEN_API_TC001 + * @title SM2: CRYPT_EAL_PkeyGetKeyLen test. + * @precon nan + * @brief + * 1. Create the context of the sm2 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGetKeyLen method, where pkey is NULL, expected result 2. + * 3. Call the CRYPT_EAL_PkeyGetKeyLen method, where pkey is valid, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. Reutrn 0. + * 3. Return SM2_PUBKEY_LEN(65) + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GET_KEY_LEN_API_TC001(void) +{ + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyLen(NULL) == 0); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyLen(ctx) == SM2_PUBKEY_LEN); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GEN_API_TC001 + * @title SM2: CRYPT_EAL_PkeyGen test. + * @precon nan + * @brief + * 1. Create the context(pkey) of the sm2 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyGen method, expected result 2 + * 3. Register wrong rand method: FakeRandFunc(The random number it generated is 0), expected result 3 + * 4. Call the CRYPT_EAL_PkeyGen method, expected result 4 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NO_REGIST_RAND + * 3. CRYPT_ECC_PKEY_ERR_TRY_CNT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GEN_API_TC001(void) +{ + TestMemInit(); + uint8_t zero[RAND_BUF_LEN] = {0}; + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(ctx) == CRYPT_NO_REGIST_RAND); + + ASSERT_TRUE(SetFakeRandOutput(zero, sizeof(zero)) == CRYPT_SUCCESS); + CRYPT_RandRegist(FakeRandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(ctx) == CRYPT_ECC_PKEY_ERR_TRY_CNT); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(ctx) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_API_TC001 + * @title SM2: CRYPT_EAL_PkeySign test. + * @precon Vertor: private key. + * @brief + * 1. Init the DRBG. + * 2. Create the context of the SM2 algorithm, expected result 1. + * 3. Call the CRYPT_EAL_PkeyCtrl method to set userId, expected result 2. + * 4. Call the CRYPT_EAL_PkeySign method, where all parameters are valid, expected result 3. + * 5. Free the context and create a new context of the SM2 algorithm, expected result 4. + * 6. Call the CRYPT_EAL_PkeySetPrv method to set private key, expected result 5. + * 7. Call the CRYPT_EAL_PkeyCtrl method to set userId, expected result 6. + * 8. Call the CRYPT_EAL_PkeySign method, where other parameters are valid, but: + * (1) signLen is not enough, expected result 7 + * (2) sign = NULL, signLen != 0, expected result 8 + * (3) msg = NULL, msgLen != 0, expected result 9 + * (4) msg = NULL, msgLen = 0, expected result 10 + * (5) mdId != CRYPT_MD_SM3, msg = NULL, msgLen = 0, expected result 11 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SM2_NO_PRVKEY + * 4. Success, and context is not NULL. + * 5. CRYPT_SUCCESS + * 6. CRYPT_SUCCESS + * 7. CRYPT_SM2_BUFF_LEN_NOT_ENOUGH + * 8-9. CRYPT_NULL_INPUT + * 10. CRYPT_SUCCESS + * 11. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_API_TC001(Hex *prvKey) +{ + uint8_t userId[SM2_PRVKEY_MAX_LEN] = {0}; // legal id + uint8_t msg[SM2_PRVKEY_MAX_LEN] = {0}; + uint8_t signBuf[SM2_SIGN_MAX_LEN]; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen) == CRYPT_SM2_NO_PRVKEY); + + CRYPT_EAL_PkeyFreeCtx(ctx); + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + signLen -= 1; + ASSERT_TRUE( + CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen) == CRYPT_SM2_BUFF_LEN_NOT_ENOUGH); + + signLen = sizeof(signBuf); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), NULL, &signLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, NULL, sizeof(msg), signBuf, &signLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, NULL, 0, signBuf, &signLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SHA256, NULL, 0, signBuf, &signLen) == CRYPT_EAL_ERR_ALGID); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_DATA_API_TC001 + * @title SM2: CRYPT_EAL_PkeySignData test. + * @precon Vertor: private key. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1. + * 2. Set userId and private key, expected result 2. + * 3. Call the CRYPT_EAL_PkeySignData method, where all parameters are valid, expected result 3. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_EAL_ALG_NOT_SUPPORT + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_DATA_API_TC001(Hex *prvKey) +{ + uint8_t userId[SM2_PRVKEY_MAX_LEN] = {0}; // legal id + uint8_t msg[SM2_PRVKEY_MAX_LEN] = {0}; + uint8_t signBuf[SM2_SIGN_MAX_LEN]; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + CRYPT_RandRegist(RandFunc); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySignData(ctx, msg, sizeof(msg), signBuf, &signLen) == CRYPT_EAL_ALG_NOT_SUPPORT); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_API_TC002 + * @title SM2: CRYPT_EAL_PkeySign test: Random number error. + * @precon Vertor: private key. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1. + * 2. Set userId and private key, expected result 2. + * 3. Call the CRYPT_EAL_PkeySign method, where all parameters are valid, expected result 3. + * 4. Register wrong rand method: FakeRandFunc(The random number it generated is 0), expected result 4. + * 5. Call the CRYPT_EAL_PkeySign method, where all parameters are valid, expected result 5. + * 6. Register correct rand method and Call the CRYPT_EAL_PkeySign method to signature, expected result 6. + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_NO_REGIST_RAND + * 4. CRYPT_SUCCESS + * 5. CRYPT_SM2_ERR_TRY_CNT or CRYPT_ECC_POINT_BLIND_WITH_ZERO + * 6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_API_TC002(Hex *prvKey) +{ + uint8_t zero[RAND_BUF_LEN] = {0}; + uint8_t userId[SM2_PRVKEY_MAX_LEN] = {0}; // legal id + uint8_t signBuf[SM2_SIGN_MAX_LEN]; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPrv prv = {0}; + + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, NULL, 0, signBuf, &signLen) == CRYPT_NO_REGIST_RAND); + + ASSERT_TRUE(SetFakeRandOutput(zero, sizeof(zero)) == CRYPT_SUCCESS); + CRYPT_RandRegist(FakeRandFunc); + int32_t ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, NULL, 0, signBuf, &signLen); + /* When assembly is enabled, the error code is CRYPT_SM2_ERR_TRY_CNT. Otherwise, the error code is + * CRYPT_ECC_POINT_BLIND_WITH_ZERO. */ + ASSERT_TRUE(ret == CRYPT_SM2_ERR_TRY_CNT || ret == CRYPT_ECC_POINT_BLIND_WITH_ZERO); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, NULL, 0, signBuf, &signLen) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_VERIFY_API_TC001 + * @title SM2: CRYPT_EAL_PkeyVerify test. + * @precon Vectors: public key, userId, msg, signature. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1. + * 2. Call the CRYPT_EAL_PkeyCtrl method to set userId, expected result 2. + * 3. Call the CRYPT_EAL_PkeyVerify method, where all parameters are valid, expected result 3. + * 4. Free the context and create a new context of the SM2 algorithm, expected result 4. + * 5. Set public key, expected result 5. + * 6. Set userId, expected result 6. + * 7. Call the CRYPT_EAL_PkeyVerify method: + * (1) signLen is invalid: sign->len - 1 or sign->len + 1, expected result 7 + * (3) msg = NULL, msgLen != 0, expected result 8 + * (2) sign = NULL, signLen != 0, expected result 9 + * (4) all parameters are valid, expected result 10 + * (5) mdId != CRYPT_MD_SM3, expected result 11 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_SUCCESS + * 3. CRYPT_SM2_NO_PUBKEY + * 4. Success, and context is not NULL. + * 5. CRYPT_SUCCESS + * 6. CRYPT_SUCCESS + * 7. CRYPT_DSA_DECODE_FAIL + * 8-9. CRYPT_NULL_INPUT + * 10. CRYPT_SUCCESS + * 11. CRYPT_EAL_ERR_ALGID + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_VERIFY_API_TC001(Hex *pubKey, Hex *userId, Hex *msg, Hex *sign) +{ + CRYPT_EAL_PkeyPub pub = {0}; + uint8_t bigSign[SM2_SIGN_MAX_LEN + 1] = {0}; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len) == CRYPT_SM2_NO_PUBKEY); + + CRYPT_EAL_PkeyFreeCtx(ctx); + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(memcpy_s(bigSign, SM2_SIGN_MAX_LEN + 1, sign->x, sign->len) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE( + CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len - 1) == CRYPT_DSA_DECODE_FAIL); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, bigSign, SM2_SIGN_MAX_LEN + 1) == + CRYPT_DSA_DECODE_FAIL); + + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, NULL, msg->len, sign->x, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, NULL, sign->len) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len) == CRYPT_SUCCESS); + ASSERT_TRUE( + CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SHA256, msg->x, msg->len, sign->x, sign->len) == CRYPT_EAL_ERR_ALGID); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_CTRL_API_TC001 + * @title SM2 CRYPT_EAL_PkeyCtrl: Test set user id. + * @precon vector: valid R. + * @brief + * 1. Create the context of the SM2 algorithm, expected result 1 + * 2. Call the CRYPT_EAL_PkeyCtrl, opt = CRYPT_CTRL_SET_SM2_USER_ID: + * (1) userId = null, idLen = 8191, and other parameters are valid, expected result 2 + * (2) userId = null, idLen = 0, and other parameters are valid, expected result 3 + * (3) userId != null, idLen = 8192, and other parameters are valid, expected result 4 + * (4) userId != null, idLen = 8191, and other parameters are valid, expected result 5 + * (5) userId != null, idLen = 1, and other parameters are valid, expected result 6 + * @expect + * 1. Success, and context is not NULL. + * 2. CRYPT_NULL_INPUT + * 3-4. CRYPT_ECC_PKEY_ERR_CTRL_LEN + * 5-6. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_CTRL_API_TC001(void) +{ + uint8_t userId[8192] = {0}; // max id len 8191, plus one for test + uint32_t idLen = sizeof(userId) - 1; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, NULL, idLen) == CRYPT_NULL_INPUT); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, 0) == CRYPT_ECC_PKEY_ERR_CTRL_LEN); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, idLen + 1) == CRYPT_ECC_PKEY_ERR_CTRL_LEN); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, idLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, 1) == CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_FUNC_TC001 + * @title ED25519 signature test: set the key or duplicate the context, and sign. + * @precon private key, userId, random number k, msg, signature. + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Set the userId and private key for ctx, expected result 2 + * 3. Mock BN_RandRange to generate k, expected result 3 + * 4. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 4 + * 5. Compare the signgures of HiTLS and vector, expected result 5 + * 6. Call the CRYPT_EAL_PkeyDupCtx method to dup sm2 context, expected result 6 + * 7. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 7 + * 8. Compare the signgures of HiTLS and vector, expected result 8 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Both are the same. + * 6. Success, and context is not NULL. + * 7. CRYPT_SUCCESS + * 8. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_FUNC_TC001(Hex *prvKey, Hex *userId, Hex *k, Hex *msg, Hex *sign) +{ + uint8_t signBuf[100]; + uint32_t signLen = sizeof(signBuf); + FuncStubInfo tmpRpInfo = {0}; + CRYPT_EAL_PkeyCtx *dupCtx = NULL; + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(SetFakeRandOutput(k->x, k->len) == CRYPT_SUCCESS); + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg->x, msg->len, signBuf, &signLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(signLen == sign->len); + ASSERT_TRUE(memcmp(signBuf, sign->x, sign->len) == 0); + + dupCtx = CRYPT_EAL_PkeyDupCtx(ctx); + ASSERT_TRUE(dupCtx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySign(dupCtx, CRYPT_MD_SM3, msg->x, msg->len, signBuf, &signLen) == CRYPT_SUCCESS); + ASSERT_TRUE(signLen == sign->len); + ASSERT_TRUE(memcmp(signBuf, sign->x, sign->len) == 0); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_PkeyFreeCtx(dupCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_FUNC_TC002 + * @title SM2 EAL layer signature function test. + * @precon prvKeyTmp, private key, userId, random number k, msg, signature. + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Repeatedly set the userId and private key of ctx, expected result 2 + * 3. Mock BN_RandRange to generate k, expected result 3 + * 4. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 4 + * 5. Compare the signgures of HiTLS and vector, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS + * 5. Both are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_FUNC_TC002(Hex *prvKeyTmp, Hex *prvKey, Hex *userId, Hex *k, Hex *msg, Hex *sign) +{ + uint8_t signBuf[100]; + uint8_t userIdBuf[100] = {0}; + uint32_t signLen = sizeof(signBuf); + FuncStubInfo tmpRpInfo = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + SetSm2PrvKey(&prv, prvKeyTmp->x, prvKeyTmp->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userIdBuf, sizeof(userIdBuf)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + prv.key.eccPrv.data = prvKey->x; + prv.key.eccPrv.len = prvKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + + ASSERT_TRUE(SetFakeRandOutput(k->x, k->len) == CRYPT_SUCCESS); + STUB_Init(); + STUB_Replace(&tmpRpInfo, BN_RandRange, STUB_RandRangeK); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg->x, msg->len, signBuf, &signLen) == CRYPT_SUCCESS); + + ASSERT_TRUE(signLen == sign->len); + ASSERT_TRUE(memcmp(signBuf, sign->x, sign->len) == 0); + +exit: + STUB_Reset(&tmpRpInfo); + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_VERIFY_FUNC_TC001 + * @title SM2 verify test: set public key or duplicate the context, and verify. + * @precon public key, userId, msg, signature. + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Set the userId and public key of ctx, expected result 2 + * 3. Call the CRYPT_EAL_PkeyVerify method to verify, expected result 3 + * 4. Call the CRYPT_EAL_PkeyDupCtx method to dup sm2 context, expected result 4 + * 5. Call the CRYPT_EAL_PkeyVerify method to verify, expected result 5 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + * 4. Success, and context is not NULL. + * 5. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_VERIFY_FUNC_TC001(Hex *pubKey, Hex *userId, Hex *msg, Hex *sign) +{ + TestMemInit(); + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_PkeyPub pub = {0}; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len) == CRYPT_SUCCESS); + + CRYPT_EAL_PkeyCtx *dupCtx = CRYPT_EAL_PkeyDupCtx(ctx); + ASSERT_TRUE(dupCtx != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(dupCtx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_PkeyFreeCtx(dupCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_VERIFY_FUNC_TC002 + * @title SM2 verify test: Repeatedly set public key, and verify. + * @precon public key, userId, msg, signature. + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Repeatedly set the userId and public key of ctx, expected result 2 + * 3. Call the CRYPT_EAL_PkeyVerify method to verify, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2-3. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_VERIFY_FUNC_TC002(Hex *pubKeyTmp, Hex *pubKey, Hex *userId, Hex *msg, Hex *sign) +{ + TestMemInit(); + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + CRYPT_EAL_PkeyPub pub = {0}; + + SetSm2PubKey(&pub, pubKeyTmp->x, pubKeyTmp->len); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + pub.key.eccPub.data = pubKey->x; + pub.key.eccPub.len = pubKey->len; + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC001 + * @title SM2: Generate a key pair for signature and verify. + * @precon nan + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Initialize the DRBG, expected result 2 + * 3. Call the CRYPT_EAL_PkeyGen to generate a key pair, expected result 3 + * 4. Set the userId for ctx, expected result 4 + * 5. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 5 + * 6. Call the CRYPT_EAL_PkeyVerify method to verify signature, expected result 6 + * 7. Call the CRYPT_EAL_PkeyDupCtx method to dup sm2 context, expected result 7 + * 8. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 8 + * 9. Call the CRYPT_EAL_PkeyVerify method to verify signature, expected result 9 + * 10. Call the CRYPT_EAL_PkeyCpyCtx method to dup sm2 context, expected result 10 + * 11. Call the CRYPT_EAL_PkeySign method to compute signature, expected result 11 + * 12. Call the CRYPT_EAL_PkeyVerify method to verify signature, expected result 12 + * @expect + * 1. Success, and context is not NULL. + * 2-6. CRYPT_SUCCESS + * 7. Success, and context is not NULL. + * 8-12. CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC001(void) +{ + uint8_t userId[SM2_PRVKEY_MAX_LEN] = {0}; // legal id + uint8_t signBuf[SM2_SIGN_MAX_LEN]; + uint8_t msg[SM2_PRVKEY_MAX_LEN] = {0}; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyCtx *dupCtx = NULL; + CRYPT_EAL_PkeyCtx *cpyCtx = NULL; + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + CRYPT_RandRegist(RandFunc); + ASSERT_TRUE(CRYPT_EAL_PkeyGen(ctx) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen) == CRYPT_SUCCESS); + + dupCtx = CRYPT_EAL_PkeyDupCtx(ctx); + ASSERT_TRUE(dupCtx != NULL); + ASSERT_EQ(dupCtx->references.count, 1); + signLen = sizeof(signBuf); + ASSERT_EQ(CRYPT_EAL_PkeySign(dupCtx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen), CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(dupCtx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen) == CRYPT_SUCCESS); + + cpyCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_PkeyCtx)); + ASSERT_TRUE(cpyCtx != NULL); + ASSERT_EQ(CRYPT_EAL_PkeyCopyCtx(cpyCtx, ctx), CRYPT_SUCCESS); + signLen = sizeof(signBuf); + ASSERT_EQ(CRYPT_EAL_PkeySign(cpyCtx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyVerify(cpyCtx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + CRYPT_EAL_PkeyFreeCtx(dupCtx); + CRYPT_EAL_PkeyFreeCtx(cpyCtx); + CRYPT_RandRegist(NULL); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_VERIFY_FUNC_TC003 + * @title SM2: Test verification failure scenario. + * @precon public key, userId, msg, signature, one of the vectors is wrong. + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Repeatedly set the userId and public key of ctx, expected result 2 + * 3. Call the CRYPT_EAL_PkeyVerify method to verify, expected result 3 + * @expect + * 1. Success, and context is not NULL. + * 2-3. Not CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_VERIFY_FUNC_TC003(Hex *pubKey, Hex *userId, Hex *msg, Hex *sign) +{ + CRYPT_EAL_PkeyPub pub = {0}; + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + + TestMemInit(); + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId->x, userId->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + // Different errors will return different error codes. + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len) != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC002 + * @title SM2: The private/public key is not cleaned up when setting the public/private key. + * @precon public key, userId, msg, signature, one of the vectors is wrong. + * @brief + * 1. Create the context(ctx) of the sm2 algorithm, expected result 1 + * 2. Repeatedly set the userId, public key and private key of ctx, expected result 2 + * 3. Call the CRYPT_EAL_PkeySign method to signature, expected result 3 + * 4. Call the CRYPT_EAL_PkeyVerify method to verify, expected result 4 + * @expect + * 1. Success, and context is not NULL. + * 2-4. CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC002(Hex *pubKey, Hex *prvKey) +{ + TestMemInit(); + uint8_t userId[SM2_PRVKEY_MAX_LEN] = {0}; // legal id + uint8_t signBuf[SM2_SIGN_MAX_LEN]; + uint8_t msg[SM2_PRVKEY_MAX_LEN] = {0}; + uint32_t signLen = sizeof(signBuf); + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + CRYPT_RandRegist(RandFunc); + + CRYPT_EAL_PkeyCtx *ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(CRYPT_EAL_PkeySetPrv(ctx, &prv) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySetPub(ctx, &pub) == CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen) == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_KEY_PAIR_CHECK_FUNC_TC001 + * @title SM2: key pair check. + * @precon Registering memory-related functions. + * @brief + * 1. Create two contexts(pubCtx, prvCtx) of the sm2 algorithm, expected result 1 + * 2. Set public key for pubCtx, expected result 2 + * 3. Set private key for prvCtx, expected result 3 + * 4. Set userId for pubCtx and prvCtx, expected result 4 + * 5. Init the drbg, expected result 5 + * 6. Check whether the public key matches the private key, expected result 6 + * @expect + * 1. Success, and contexts are not NULL. + * 2-5. CRYPT_SUCCESS + * 6. Return CRYPT_SUCCESS when expect is 1, CRYPT_SM2_VERIFY_FAIL otherwise. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_KEY_PAIR_CHECK_FUNC_TC001(Hex *pubKey, Hex *prvKey, Hex *userId, int expect) +{ + CRYPT_EAL_PkeyCtx *pubCtx = NULL; + CRYPT_EAL_PkeyCtx *prvCtx = NULL; + CRYPT_EAL_PkeyPub pub = {0}; + CRYPT_EAL_PkeyPrv prv = {0}; + int expectRet = expect == 1 ? CRYPT_SUCCESS : CRYPT_SM2_VERIFY_FAIL; + + SetSm2PubKey(&pub, pubKey->x, pubKey->len); + SetSm2PrvKey(&prv, prvKey->x, prvKey->len); + + TestMemInit(); + pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + ASSERT_TRUE(pubCtx != NULL && prvCtx != NULL); + + ASSERT_EQ(CRYPT_EAL_PkeySetPub(pubCtx, &pub), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeySetPrv(prvCtx, &prv), CRYPT_SUCCESS); + + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(pubCtx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_PkeyCtrl(prvCtx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)) == CRYPT_SUCCESS); + + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyPairCheck(pubCtx, prvCtx), expectRet); + +exit: + CRYPT_EAL_RandDeinit(); + CRYPT_EAL_PkeyFreeCtx(pubCtx); + CRYPT_EAL_PkeyFreeCtx(prvCtx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM2_GET_KEY_BITS_FUNC_TC001 + * @title SM2: get key bits. + * @brief + * 1. Create a context of the SM2 algorithm, expected result 1 + * 2. Get key bits, expected result 2 + * @expect + * 1. Success, and context is not NULL. + * 2. Equal to keyBits. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM2_GET_KEY_BITS_FUNC_TC001(int id, int keyBits) +{ + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(id); + ASSERT_TRUE(pkey != NULL); + ASSERT_TRUE(CRYPT_EAL_PkeyGetKeyBits(pkey) == (uint32_t)keyBits); +exit: + CRYPT_EAL_PkeyFreeCtx(pkey); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.data b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.data new file mode 100644 index 00000000..da9ae0ca --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.data @@ -0,0 +1,83 @@ +SDV_CRYPTO_SM2_GET_PUB_API_TC001 sign get set pubkey +SDV_CRYPTO_SM2_GET_PUB_API_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13" + +SDV_CRYPTO_SM2_GET_PRV_API_TC001 sign get set prvkey +SDV_CRYPTO_SM2_GET_PRV_API_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8" + +SDV_CRYPTO_SM2_GET_PRV_API_TC001 sign get set prvkey 31 bytes key +SDV_CRYPTO_SM2_GET_PRV_API_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5" + +SDV_CRYPTO_SM2_GET_PRV_API_TC001 sign get set prvkey 2 byte key +SDV_CRYPTO_SM2_GET_PRV_API_TC001:"0101" + +SDV_CRYPTO_SM2_SET_PUB_API_TC001 sign set pubkey +SDV_CRYPTO_SM2_SET_PUB_API_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13" + +SDV_CRYPTO_SM2_SET_PRV_API_TC001 sign set prvkey +SDV_CRYPTO_SM2_SET_PRV_API_TC001:"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54122" + +SDV_CRYPTO_SM2_GET_SIGN_LEN_API_TC001 get sign Len +SDV_CRYPTO_SM2_GET_SIGN_LEN_API_TC001: + +SDV_CRYPTO_SM2_GET_KEY_LEN_API_TC001 get key len +SDV_CRYPTO_SM2_GET_KEY_LEN_API_TC001: + +SDV_CRYPTO_SM2_GEN_API_TC001 gen key fail +SDV_CRYPTO_SM2_GEN_API_TC001: + +SDV_CRYPTO_SM2_SIGN_API_TC001 sign api fail +SDV_CRYPTO_SM2_SIGN_API_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8" + +SDV_CRYPTO_SM2_SIGN_DATA_API_TC001 sign data fail +SDV_CRYPTO_SM2_SIGN_DATA_API_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8" + +SDV_CRYPTO_SM2_SIGN_API_TC002 sign rand fail +SDV_CRYPTO_SM2_SIGN_API_TC002:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8" + +SDV_CRYPTO_SM2_VERIFY_API_TC001 verify api fail +SDV_CRYPTO_SM2_VERIFY_API_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"31323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_CTRL_API_TC001 Ctrl set userId fail +SDV_CRYPTO_SM2_CTRL_API_TC001: + +SDV_CRYPTO_SM2_SIGN_FUNC_TC001: GBT.32918.5-2017, sign vector 1 +SDV_CRYPTO_SM2_SIGN_FUNC_TC001:"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"31323334353637383132333435363738":"59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_SIGN_FUNC_TC002: GBT.32918.5-2017, sign multi set +SDV_CRYPTO_SM2_SIGN_FUNC_TC002:"128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263":"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"31323334353637383132333435363738":"59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC001: GBT.32918.5-2017, verify success vector 1 +SDV_CRYPTO_SM2_VERIFY_FUNC_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"31323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC002: GBT.32918.5-2017, verify multi set +SDV_CRYPTO_SM2_VERIFY_FUNC_TC002:"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"31323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC001 Gen key sign verify +SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC001: + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003 verify fail vector wrong pubkey +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003:"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"31323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003 verify fail vector wrong userId +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"32323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003 verify fail vector wrong msg +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"31323334353637383132333435363738":"6D6573736167652064696765737475":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003 verify fail vector wrong R +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"31323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f6a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003 verify fail vector wrong S +SDV_CRYPTO_SM2_VERIFY_FUNC_TC003:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"31323334353637383132333435363738":"6D65737361676520646967657374":"3046022100f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b3022100b1b6aa29df222fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" + +SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC002: GBT.32918.5-2017 prv pub key exist +SDV_CRYPTO_SM2_SIGN_VERIFY_FUNC_TC002:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8" + +Sm2 key pair check: GBT.32918.5-2017 Pass +SDV_CRYPTO_SM2_KEY_PAIR_CHECK_FUNC_TC001:"0409F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13":"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"32323334353637383132333435363738":1 + +Sm2 key pair check: GBT.32918.5-2017 Fail +SDV_CRYPTO_SM2_KEY_PAIR_CHECK_FUNC_TC001:"046ae848c57c53c7b1b5fa99eb2286af078ba64c64591b8b566f7357d576f16dfbee489d771621a27b36c5c7992062e9cd09a9264386f3fbea54dff69305621c4d":"3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8":"32323334353637383132333435363738":0 + +SDV_CRYPTO_SM2_GET_KEY_BITS_FUNC_TC001 +SDV_CRYPTO_SM2_GET_KEY_BITS_FUNC_TC001:CRYPT_PKEY_SM2:520 \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/sm3/test_suite_sdv_eal_sm3.c b/testcode/sdv/testcase/crypto/sm3/test_suite_sdv_eal_sm3.c new file mode 100644 index 00000000..59e53a95 --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm3/test_suite_sdv_eal_sm3.c @@ -0,0 +1,258 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "crypt_eal_md.h" +#include "bsl_sal.h" +#include "eal_md_local.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "securec.h" +/* END_HEADER */ + +/** + * @test SDV_CRYPT_EAL_SM3_API_TC001 + * @title CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal test + * @precon nan + * @brief + * 1.Invoke the CRYPT_EAL_MdNewCtx to create a CTX, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal before initialization, expected result 2 is obtained. + * 3.Initialize the CTX and transfer null pointers to CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal. expected result 3. + * 4.Invoke CRYPT_EAL_MdUpdate and CRYPT_EAL_MdFinal normally, expected result 4. + * @expect + * 1.Successful, ctx is returned. + * 2.Return CRYPT_EAL_ERR_STATE + * 3.Return CRYPT_NULL_INPUT + * 4.Return CRYPT_SUCCESS + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SM3_API_TC001(void) +{ + TestMemInit(); + uint8_t input[100]; // Any length, for example, 100 bytes. + uint32_t inLen = sizeof(input); + uint8_t out[32]; // SM3 digest length is 32. + uint32_t outLen = sizeof(out); + uint32_t badOutLen = outLen - 1; + uint32_t longOutLen = outLen + 1; + + ASSERT_EQ(CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SM3), outLen); + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_EAL_ERR_STATE); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(NULL, input, inLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, NULL, inLen), CRYPT_NULL_INPUT); + // Hash counting can be performed on empty strings. + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, input, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, NULL, 0), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, NULL, &outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(NULL, out, &outLen), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, NULL), CRYPT_NULL_INPUT); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &badOutLen), CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, input, inLen), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &longOutLen), CRYPT_SUCCESS); +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SM3_FUNC_TC001 + * @title CRYPT_EAL_MdFinal test without update. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create ctx, expected result 1. + * 2.Call CRYPT_EAL_MdFinal get results. expected result 2. + * 3.Compare with expected results. expected result 3. + * @expect + * 1.The ctx is created successful. + * 2.Successful. + * 2.Consistent with expected results. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SM3_FUNC_TC001(Hex *hash) +{ + TestMemInit(); + uint8_t out[32]; // SM3 digest length is 32. + uint32_t outLen = sizeof(out); + + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(outLen, 32); + + ASSERT_EQ(memcmp(out, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SM3_FUNC_TC002 + * @title Perform the vector test to check whether the calculation result is consistent with the standard output. + * @precon nan + * @brief + * 1.Calculate the hash of each group of data, expected result 1. +* 2.Compare the result to the expected value, expected result 2. + * @expect + * 1.Hash calculation succeeded. + * 2.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SM3_FUNC_TC002(Hex *data, Hex *hash) +{ + TestMemInit(); + uint8_t out[32]; // SM3 digest length is 32 + uint32_t outLen = sizeof(out); + CRYPT_EAL_MdCTX *ctx = NULL; + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data->x, data->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(outLen, 32); + + ASSERT_EQ(memcmp(out, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_SM3_FUNC_TC003 + * @title Hash calculation for multiple updates,comparison with standard results. + * @precon nan + * @brief + * 1.Call CRYPT_EAL_MdNewCtx to create a ctx and initialize, expected result 1. + * 2.Call CRYPT_EAL_MdUpdate to calculate the hash of a data segmentxpected result 2. + * 3.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 3. + * 4.Call CRYPT_EAL_MdUpdate to calculate the next data segmentxpected result 4. + * 5.Call CRYPT_EAL_MdFinal get the result, expected result 5. + * @expect + * 1.Successful + * 2.Successful + * 3.Successful + * 4.Successful + * 5.The results are as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SM3_FUNC_TC003(Hex *data1, Hex *data2, Hex *data3, Hex *hash) +{ + TestMemInit(); + uint8_t out[32]; // 32 is sm3 hash size + uint32_t outLen = sizeof(out); + CRYPT_EAL_MdCTX *ctx = NULL; + + ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data1->x, data1->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data2->x, data2->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx, data3->x, data3->len), CRYPT_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx, out, &outLen), CRYPT_SUCCESS); + + ASSERT_EQ(outLen, 32); + + ASSERT_EQ(memcmp(out, hash->x, hash->len), 0); + +exit: + CRYPT_EAL_MdFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPT_EAL_MD_SHA2_FUNC_TC001 + * @title Split the data and update test. + * @precon nan + * @brief + * 1.Create two ctx and initialize them, expected result 1. + * 2.Use ctx1 to update data 100 times, expected result 2. + * 3.Use ctx2 to update all data at once, expected result 3. + * 4.Compare two outputs, expected result 4. + * @expect + * 1.Successful. + * 2.Successful. + * 3.Successful. + * 4.The results are the same. + */ +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_SM3_FUNC_TC004(void) +{ + TestMemInit(); + CRYPT_EAL_MdCTX *ctx1 = NULL; + CRYPT_EAL_MdCTX *ctx2 = NULL; + + ctx1 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx1 != NULL); + + ctx2 = CRYPT_EAL_MdNewCtx(CRYPT_MD_SM3); + ASSERT_TRUE(ctx2 != NULL); + + // 100! = 5050 + uint8_t input[5050]; + uint32_t inLenTotal = 0; + uint32_t inLenBase; + uint8_t out1[100]; + uint8_t out2[100]; + uint32_t outLen = CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SM3); + + ASSERT_EQ(CRYPT_EAL_MdInit(ctx1), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdInit(ctx2), CRYPT_SUCCESS); + + for (inLenBase = 1; inLenBase <= 100; inLenBase++) { + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx1, input + inLenTotal, inLenBase), CRYPT_SUCCESS); + inLenTotal += inLenBase; + } + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx1, out1, &outLen), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SM3); + ASSERT_EQ(CRYPT_EAL_MdUpdate(ctx2, input, inLenTotal), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_MdFinal(ctx2, out2, &outLen), CRYPT_SUCCESS); + + outLen = CRYPT_EAL_MdGetDigestSize(CRYPT_MD_SM3); + + ASSERT_EQ(memcmp(out1, out2, outLen), CRYPT_SUCCESS); + +exit: + CRYPT_EAL_MdFreeCtx(ctx1); + CRYPT_EAL_MdFreeCtx(ctx2); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sm3/test_suite_sdv_eal_sm3.data b/testcode/sdv/testcase/crypto/sm3/test_suite_sdv_eal_sm3.data new file mode 100644 index 00000000..8485b31c --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm3/test_suite_sdv_eal_sm3.data @@ -0,0 +1,20 @@ +SDV_CRYPT_EAL_SM3_API_TC001 API test +SDV_CRYPT_EAL_SM3_API_TC001: + +SDV_CRYPT_EAL_SM3_FUNC_TC001 update 0 final +SDV_CRYPT_EAL_SM3_FUNC_TC001:"1AB21D8355CFA17F8E61194831E81A8F22BEC8C728FEFB747ED035EB5082AA2B" + +SDV_CRYPT_EAL_SM3_FUNC_TC002 sm3 one update vector 1 +SDV_CRYPT_EAL_SM3_FUNC_TC002:"":"1AB21D8355CFA17F8E61194831E81A8F22BEC8C728FEFB747ED035EB5082AA2B" + +SDV_CRYPT_EAL_SM3_FUNC_TC002 sm3 one update vector 1 +SDV_CRYPT_EAL_SM3_FUNC_TC002:"616263":"66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0" + +SDV_CRYPT_EAL_SM3_FUNC_TC002 sm3 one update vector 2 +SDV_CRYPT_EAL_SM3_FUNC_TC002:"61626364616263646162636461626364616263646162636461626364616263646162636461626364616263646162636461626364616263646162636461626364":"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732" + +SDV_CRYPT_EAL_SM3_FUNC_TC003 sm3 multi tlock test +SDV_CRYPT_EAL_SM3_FUNC_TC003:"616263":"6461626364616263646162636461626364616263646162636461626364":"6162636461626364616263646162636461626364616263646162636461626364":"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732" + +SDV_CRYPT_EAL_SM3_FUNC_TC004 sm3 multi tlock test +SDV_CRYPT_EAL_SM3_FUNC_TC004: \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/sm4/test_suite_sdv_eal_sm4.c b/testcode/sdv/testcase/crypto/sm4/test_suite_sdv_eal_sm4.c new file mode 100644 index 00000000..2c60820b --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm4/test_suite_sdv_eal_sm4.c @@ -0,0 +1,1676 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "crypt_errno.h" +#include "crypt_eal_cipher.h" +#include "bsl_sal.h" +#include "pthread.h" +#include "securec.h" +#include "eal_cipher_local.h" + +#define BLOCKSIZE 16 +#define KEYSIZE 32 +#define MAXSIZE 1024 +#define MAX_OUTPUT 5000 +#define MAX_DATASZIE 20000 + +/* END_HEADER */ + +static int SetPadding(int isSetPadding, CRYPT_EAL_CipherCtx *ctxEnc, int padding) +{ + if (isSetPadding == 1) { + return CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + } + return CRYPT_SUCCESS; +} + +static int CipherFinal( + int algId, CRYPT_EAL_CipherCtx *ctx, uint8_t *outTmp, uint32_t *finLen) +{ + if (algId != CRYPT_CIPHER_SM4_GCM) { + return CRYPT_EAL_CipherFinal(ctx, outTmp, finLen); + } + return CRYPT_SUCCESS; +} + +/** + * @test SDV_CRYPTO_SM4_INIT_API_TC001 + * @title Impact of IV validity on algorithm module initialization Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface, ctx is not NULL, iv is NULL, ivLen is 0, and key is normal value. Expected result 2 is obtained. + * 3.Call the Init interface, ctx is not NULL, iv is not NULL, ivLen is 0, and key is normal value. Expected result 3 is obtained. + * 4.Call the Init interface, ctx is not NULL, iv is not NULL, ivLen is 15, and key is normal value. Expected result 4 is obtained. + * 5.Call the Init interface, ctx is not NULL, iv is not NULL, ivLen is 17, and key is normal value. Expected result 5 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Failed. + * 3.Failed. + * 4.Failed except for the GCM algorithm. + * 5.Failed except for the GCM algorithm. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_INIT_API_TC001(int id, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, NULL, 0, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, 0, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, BLOCKSIZE - 1, true); + if (id == CRYPT_CIPHER_SM4_GCM) { + ASSERT_TRUE(ret == CRYPT_SUCCESS); + } else { + ASSERT_TRUE(ret != CRYPT_SUCCESS); + } + if (id == CRYPT_CIPHER_SM4_GCM) { + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, BLOCKSIZE, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + } else { + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, BLOCKSIZE + 1, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + } +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_INIT_API_TC002 + * @title Impact of input parameters on the CRYPT_EAL_CipherInit interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx with CRYPT_CIPHER_SM4_XTS. Expected result 1 is obtained. + * 2.Call the Init interface, ctx is NULL. Expected result 2 is obtained. + * 3.Call the Init interface, ctx is not NULL, key is NULL. Expected result 3 is obtained. + * 4.Call the Init interface, ctx is not NULL, key is not NULL, iv is NULL. Expected result 4 is obtained. + * 5.Call the Init interface, ctx, key and iv is not NULL, keyLen is less than or greater than 32 bytes. Expected result 5 is obtained. + * 6.Call the Init interface, ctx, key and iv is not NULL, keyLen is 32 bytes and the previous and next 16 bytes are the same. Expected result 6 is obtained. + * 7.Call the Init interface, ctx, key and iv is not NULL, ivLen is less than or greater than 16 bytes. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Initialization failed. + * 3.Initialization failed. + * 4.Initialization failed. + * 5.Initialization failed. + * 6.Initialization failed. + * 7.Initialization failed. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_INIT_API_TC002(Hex *key, Hex *iv, int enc) +{ + uint8_t unsafe_key[KEYSIZE] = {0}; + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_XTS); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(NULL, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherInit(ctx, NULL, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, NULL, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_CipherInit(ctx, key->x, 0, iv->x, iv->len, enc); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, 1, iv->x, iv->len, enc); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, 16, iv->x, iv->len, enc); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, 33, iv->x, iv->len, enc); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, unsafe_key, KEYSIZE, iv->x, iv->len, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, unsafe_key, KEYSIZE, iv->x, iv->len, false); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, 0, enc); + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, 1, enc); + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, 15, enc); + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, 17, enc); + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_INIT_API_TC003 + * @title Impact of key validity on algorithm module initialization Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface, ctx is NULL. Expected result 2 is obtained. + * 3.Call the Init interface, ctx is not NULL, key is NULL, keyLen is 0. Expected result 3 is obtained. + * 4.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is 0. Expected result 4 is obtained. + * 5.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is 15. Expected result 5 is obtained. + * 6.Call the Init interface, ctx is not NULL, key is not NULL, keyLen is 17. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Initialization failed. + * 3.Initialization failed. + * 4.Initialization failed. + * 5.Initialization failed. + * 6.Initialization failed. +*/ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_INIT_API_TC003(int id, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(NULL, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherInit(ctx, NULL, 0, iv->x, iv->len, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, 0, iv->x, iv->len, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, BLOCKSIZE - 1, iv->x, iv->len, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctx, key->x, BLOCKSIZE + 1, iv->x, iv->len, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_DEINIT_API_TC001 + * @title Impact of input parameters on the CRYPT_EAL_CipherDeinit interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Deinit interface, ctx is NULL. Expected result 2 is obtained. + * 3.Call the Deinit interface. All parameters are normal. Expected result 3 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The function is executed successfully. + * 3.The function is executed successfully. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_DEINIT_API_TC001(int id) +{ + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherDeinit(NULL); +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_REINIT_API_TC001 + * @title CRYPT_EAL_CipherReinit for iv Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Reinit interface. Expected result 2 is obtained. + * 3.Call the Init interface. Expected result 3 is obtained. + * 4.Call the Reinit interface, ctx is NULL, iv is not NULL, ivLen is not 0. Expected result 4 is obtained. + * 5.Call the Reinit interface, ctx is not NULL, iv is NULL, ivLen is not 0. Expected result 5 is obtained. + * 6.Call the Reinit interface, ctx is not NULL, iv is not NULL, ivLen is 0. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.Failed. Return CRYPT_EAL_ERR_STATE. + * 3.The init is successful and return CRYPT_SUCCESS. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Failed. Return CRYPT_NULL_INPUT. + * 6.Failed. Return CRYPT_NULL_INPUT/CRYPT_MODES_IVLEN_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_REINIT_API_TC001(int id, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_EAL_ERR_STATE); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherReinit(NULL, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherReinit(ctx, NULL, iv->len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, 0); + if (id == CRYPT_CIPHER_SM4_GCM) { + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + } else { + ASSERT_TRUE(ret == CRYPT_MODES_IVLEN_ERROR); + } +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_UPDATE_API_TC001 + * @title Impact of input parameters on the CRYPT_EAL_CipherUpdate interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface, ctx is NULL. Expected result 3 is obtained. + * 4.Call the Update interface, ctx is not NULL, in is NULL. Expected result 4 is obtained. + * 5.Call the Update interface, ctx is not NULL, in is not NULL, out is NULL. Expected result 5 is obtained. + * 6.Call the Update interface, ctx, in, out is NULL, inLen is 1. Expected result 6 is obtained. + * 7.Call the Update interface, ctx, in, out is NULL, outLen is NULL. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_NULL_INPUT. + * 4.Failed. Return CRYPT_NULL_INPUT. + * 5.Failed. Return CRYPT_NULL_INPUT. + * 6.Failed When is the XTS algorithm. + * 7.Failed. Return CRYPT_NULL_INPUT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_UPDATE_API_TC001(int id, Hex *key, Hex *iv, Hex *in, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t out[BLOCKSIZE] = {0}; + uint32_t len = BLOCKSIZE; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + len = BLOCKSIZE; + ret = CRYPT_EAL_CipherUpdate(NULL, in->x, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + len = BLOCKSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, NULL, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + len = BLOCKSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, NULL, &len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + + len = BLOCKSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, 0, out, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + len = BLOCKSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, 1, out, &len); + if (id == CRYPT_CIPHER_SM4_XTS) { + ASSERT_TRUE(ret != CRYPT_SUCCESS); + } else { + ASSERT_TRUE(ret == CRYPT_SUCCESS); + } + + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, out, NULL); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + len = BLOCKSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, out, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(len == BLOCKSIZE); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_CTRL_API_TC001 + * @title Impact of the setting type on the Ctrl setting parameters Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface, iv is IV1. Expected result 2 is obtained. + * 3.Call the Ctrl interface to get iv. Expected result 3 is obtained. + * 4.Call the Update interface to encrypt, inLen is 15. Expected result 4 is obtained. + * 5.Call the Ctrl interface to get iv. Expected result 5 is obtained. + * 6.Call the Update interface to encrypt, inLen is 1. Expected result 6 is obtained. + * 7.Call the Ctrl interface to get iv, record as IV2. Expected result 7 is obtained. + * 8.Call the Update interface to encrypt, inLen is 16. Expected result 8 is obtained. + * 9.Call the Ctrl interface to get iv. Expected result 9 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Iv value is equal to IV1. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Iv value is equal to IV1. + * 6.Success. Return CRYPT_SUCCESS. + * 7.Iv value is not equal to IV1. + * 8.Success. Return CRYPT_SUCCESS. + * 9.Iv value is not equal to IV2. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_CTRL_API_TC001(Hex *key, Hex *iv, Hex *msg) +{ + TestMemInit(); + int32_t ret; + uint8_t iv1[BLOCKSIZE] = {0}; + uint8_t iv2[BLOCKSIZE] = {0}; + const uint32_t len = BLOCKSIZE; + uint8_t out[MAXSIZE] = {0}; + uint32_t outlen = MAXSIZE; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_MODES_CTRL_TYPE_ERROR); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_IV, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_EAL_CIPHER_CTRL_ERROR); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_IV, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_EAL_CIPHER_CTRL_ERROR); + + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, iv1, len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(iv1, iv->x, iv->len) == 0); + (void)memset_s(iv1, BLOCKSIZE, 0, BLOCKSIZE); + + ret = CRYPT_EAL_CipherUpdate(ctx, msg->x, BLOCKSIZE - 1, out, &outlen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, iv1, len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(iv1, iv->x, iv->len) == 0); + (void)memset_s(iv1, BLOCKSIZE, 0, BLOCKSIZE); + + outlen = MAXSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, msg->x, 1, out, &outlen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, iv1, len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(iv1, iv->x, iv->len) != 0); + + outlen = MAXSIZE; + ret = CRYPT_EAL_CipherUpdate(ctx, msg->x, BLOCKSIZE, out, &outlen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, iv2, len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(iv2, iv1, BLOCKSIZE) != 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_CTRL_API_TC002 + * @title Impact of setting iv on the Ctrl interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface to set iv with normal value. Expected result 3 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Failed. Return CRYPT_EAL_CIPHER_CTRL_ERROR. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_CTRL_API_TC002(Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CTR); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_IV, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_EAL_CIPHER_CTRL_ERROR); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_CTRL_API_TC003 + * @title Impact of input parameters on the CRYPT_EAL_CipherCtrl interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Ctrl interface, ctx is not NULL, type is get iv, other parameters are normal. Expected result 3 is obtained. + * 4.Call the Ctrl interface, ctx is not NULL, type is get blocksize, other parameters are normal. Expected result 4 is obtained. + * 5.Call the Ctrl interface, ctx is not NULL, type is get iv, data is NULL, len is 16. Expected result 5 is obtained. + * 6.Call the Ctrl interface, ctx is not NULL, type is get iv, data is not NULL, len is 0. Expected result 6 is obtained. + * 7.Call the Ctrl interface, ctx is not NULL, type is get blocksize, data is not NULL, len is 0. Expected result 7 is obtained. + * 8.Call the Ctrl interface, ctx is not NULL, type is invalid value. Expected result 8 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. Return CRYPT_SUCCESS. + * 4.Success. Return CRYPT_SUCCESS. + * 5.Failed. Return CRYPT_NULL_INPUT. + * 6.Failed. Return CRYPT_MODE_ERR_INPUT_LEN. + * 7.Failed. Return CRYPT_MODE_ERR_INPUT_LEN. + * 8.Failed. CRYPT_MODES_METHODS_NOT_SUPPORT. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_CTRL_API_TC003(Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + uint8_t *ivGet[BLOCKSIZE] = {0}; + const uint32_t len = BLOCKSIZE; + uint32_t blockSizeGet = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_XTS); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, ivGet, len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, (uint8_t *)&blockSizeGet, sizeof(uint32_t)); + ASSERT_TRUE(blockSizeGet == 1); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, NULL, len); + ASSERT_TRUE(ret == CRYPT_NULL_INPUT); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, ivGet, 0); + ASSERT_TRUE(ret == CRYPT_MODE_ERR_INPUT_LEN); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_BLOCKSIZE, (uint8_t *)&blockSizeGet, 0); + ASSERT_TRUE(ret == CRYPT_MODE_ERR_INPUT_LEN); + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_MAX, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_MODES_CTRL_TYPE_ERROR); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001 + * @title Call Final interface without call Update interface Test. + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Set the following padding algorithm CRYPT_PADDING_PKCS7 CRYPT_PADDING_PKCS5 CRYPT_PADDING_X923 CRYPT_PADDING_ISO7816 CRYPT_PADDING_ZEROS. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * 5.Use the SM4 decryption handle to call the Update interface with the ciphertext. Expected result 5 is obtained. + * 6.Call the Final interface. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.Succeeded in setting the padding algorithm. + * 4.The ciphertext is consistent with the test vector. + * 5.The update is successful, return CRYPT_SUCCESS. + * 6.The plaintext is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001(int id, Hex *key, Hex *iv, int padding, int isSetPadding) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAXSIZE] = {0}; + uint8_t result[MAXSIZE] = {0}; + uint32_t totalLen = 0; + uint32_t decLen = MAXSIZE; + uint32_t len = MAXSIZE; + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ctxEnc = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctxEnc != NULL); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ctxDec = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, len, result, &decLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += decLen; + decLen = MAXSIZE - totalLen; + ret = CRYPT_EAL_CipherFinal(ctxDec, result + totalLen, &decLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + + /** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002 + * @title Encryption and decryption with setting padding algorithm Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Set the following padding algorithm CRYPT_PADDING_PKCS7 CRYPT_PADDING_PKCS5 CRYPT_PADDING_X923 CRYPT_PADDING_ISO7816 CRYPT_PADDING_ZEROS. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Use the SM4 decryption handle to call the Update interface with the ciphertext. Expected result 6 is obtained. + * 7.Call the Final interface. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Succeeded in setting the padding algorithm. + * 4.The update is successful and return CRYPT_SUCCESS. + * 5.The ciphertext is consistent with the test vector. + * 6.The update is successful and return CRYPT_SUCCESS. + * 7.The plaintext is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002(int algId, Hex *key, Hex *iv, int inLen, int padding) +{ + TestMemInit(); + int32_t ret; + uint8_t input[MAXSIZE] = {0}; + uint8_t outTmp[MAXSIZE] = {0}; + uint8_t result[MAXSIZE] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAXSIZE; + uint32_t len = MAXSIZE; + + (void)memset_s(outTmp, MAXSIZE, 0xAA, MAXSIZE); + (void)memset_s(input, MAXSIZE, 0xAA, MAXSIZE); + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ASSERT_TRUE(inLen <= MAXSIZE); + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxEnc, input, inLen, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + totalLen, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + len = MAXSIZE; + leftLen = MAXSIZE; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, totalLen, result, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + leftLen -= len; + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(input, result, inLen) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 + * @title Input data of different lengths encryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003(int id, Hex *key, Hex *plainText, Hex *cipherText, Hex *iv) +{ + if (IsSm4AlgDisabled(id)) { + SKIP_TEST(); + } + TestMemInit(); + int32_t ret; + uint8_t out[MAXSIZE] = {0}; + uint32_t len = plainText->len; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, plainText->x, plainText->len, out, &len); + + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out, cipherText->x, len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 + * @title Input data of different lengths decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004(int id, Hex *key, Hex *plainText, Hex *cipherText, Hex *iv) +{ + if (IsSm4AlgDisabled(id)) { + SKIP_TEST(); + } + TestMemInit(); + int32_t ret; + uint8_t out[MAXSIZE] = {0}; + uint32_t len = cipherText->len; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, cipherText->x, cipherText->len, out, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(out, plainText->x, len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_MULTI_UPDATE_TC001 + * @title Multi update encryption and decryption + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface with plaintext for multi times. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * 5.Use the SM4 decryption handle to call the Update interface with the ciphertext. Expected result 5 is obtained. + * 6.Call the Final interface. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The final is successful, return CRYPT_SUCCESS. The cipher result is consistent with the test vector. + * 5.The update is successful, return CRYPT_SUCCESS. + * 6.The final is successful, return CRYPT_SUCCESS. The plain result is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_MULTI_UPDATE_TC001(int algId, Hex *key, Hex *iv, Hex *in, int updateTimes, int padding, + int isSetPadding) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAXSIZE * 4] = {0}; + uint8_t result[MAXSIZE * 4] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAXSIZE * 4; + uint32_t len = MAXSIZE * 4; + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + for (int i = 0; i < updateTimes; i++) { + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, in->len, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + len = leftLen; + } + if (algId != CRYPT_CIPHER_SM4_GCM) { + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + totalLen, &leftLen); + } + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + len = MAXSIZE * 4; + leftLen = MAXSIZE * 4; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, totalLen, result, &len); + leftLen -= len; + ASSERT_TRUE(ret == CRYPT_SUCCESS); + if (algId != CRYPT_CIPHER_SM4_GCM) { + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + } + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(in->x, result, in->len) == 0); + ASSERT_TRUE(memcmp(in->x, result + in->len, in->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_MULTI_UPDATE_TC002 + * @title Multi update with different data length in encryption and decryption + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface with plaintext for 5 times. The length of the first, third, and fifth plaintext is 15 bytes. + * The length of the second and fourth plaintexts is 16 bytes. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * 5.Use the SM4 decryption handle to call the Update interface with the ciphertext. Expected result 5 is obtained. + * 6.Call the Final interface. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The final is successful, return CRYPT_SUCCESS. The cipher result is consistent with the test vector. + * 5.The update is successful, return CRYPT_SUCCESS. + * 6.The final is successful, return CRYPT_SUCCESS. The plain result is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_MULTI_UPDATE_TC002(int algId, Hex *key, Hex *iv, Hex *in, int padding, int isSetPadding) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAXSIZE] = {0}; + uint8_t result[MAXSIZE] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAXSIZE; + uint32_t len = MAXSIZE; + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ASSERT_TRUE(in->len >= BLOCKSIZE); + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + for (uint32_t i = 0; i < 2; i++) { // 15bytes + 16bytes, run two times. + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, BLOCKSIZE - 1, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + len = leftLen; + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, BLOCKSIZE, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + len = leftLen; + } + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, BLOCKSIZE - 1, outTmp + totalLen, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + len = leftLen; + if (algId != CRYPT_CIPHER_SM4_GCM) { + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + totalLen, &leftLen); + } + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + len = MAXSIZE; + leftLen = MAXSIZE; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, totalLen, result, &len); + leftLen -= len; + ASSERT_TRUE(ret == CRYPT_SUCCESS); + if (algId != CRYPT_CIPHER_SM4_GCM) { + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + } + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(in->x, result, BLOCKSIZE - 1) == 0); + ASSERT_TRUE(memcmp(in->x, result + BLOCKSIZE - 1, BLOCKSIZE) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_CTRL_API_TC004 + * @title Obtaining the IV through the Ctrl interface Test in encryption + * @precon Registering memory-related functions. + * @brief + * 1.Call the init interface to set the IV and call interface to obtain the IV. Expected result 1 is obtained. + * @expect + * 1.The two IVs are consistent. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_CTRL_API_TC004(int id, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + uint8_t niv[BLOCKSIZE] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, niv, iv->len); + ASSERT_TRUE(memcmp(niv, iv->x, iv->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_CTRL_API_TC005 + * @title Obtaining the IV through the Ctrl interface Test in decryption + * @precon Registering memory-related functions. + * @brief + * 1.Call the init interface to set the IV and call interface to obtain the IV. Expected result 1 is obtained. + * @expect + * 1.The two IVs are consistent. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_CTRL_API_TC005(int id, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + uint8_t niv[BLOCKSIZE] = {0}; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_IV, niv, iv->len); + ASSERT_TRUE(memcmp(niv, iv->x, iv->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_REINIT_API_TC002 + * @title Impact of input parameter validity on the iv reset interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface, iv is NULL, iv len is 0. Expected result 2 is obtained. + * 3.Call the Reinit interface, iv is NULL, iv len is 0. Expected result 3 is obtained. + * 4.Call the Reinit interface, iv is not NULL, iv len is 0. Expected result 4 is obtained. + * 5.Call the Reinit interface, iv is not NULL, iv len is 15. Expected result 5 is obtained. + * 6.Call the Reinit interface, iv is not NULL, iv len is 17. Expected result 6 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.The interface returns a failure. + * 4.The interface returns a failure. + * 5.The interface returns a failure. + * 6.The interface returns a failure. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_REINIT_API_TC002(int algId, Hex *key, Hex *iv) +{ + TestMemInit(); + int32_t ret; + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, NULL, 0, true); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherReinit(ctx, NULL, 0); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, 0); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, BLOCKSIZE - 1); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, BLOCKSIZE + 1); + ASSERT_TRUE(ret != CRYPT_SUCCESS); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC005 + * @title Data encryption and decryption after reinit Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * 4.Call the Reinit interface. Expected result 4 is obtained. + * 5.Call the Update interface. Expected result 5 is obtained. + * 6.Call the Reinit interface. Expected result 6 is obtained. + * 7.Call the Update interface. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.Success. The ciphertext is as expected. + * 4.The reinit is successful and return CRYPT_SUCCESS. + * 5.Success. The ciphertext is as expected. + * 6.The reinit is successful and return CRYPT_SUCCESS. + * 7.Success. The ciphertext is as expected. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC005(Hex *key, Hex *in1, Hex *out1, Hex *iv1, Hex *in2, Hex *out2, Hex *iv2, + int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAXSIZE] = {0}; + uint32_t len = MAXSIZE; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_XTS); + ASSERT_TRUE(ctx != NULL); + + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv1->x, iv1->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in1->x, in1->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out1->x, out1->len) == 0); + + (void)memset_s(outTmp, MAXSIZE, 0, MAXSIZE); + len = MAXSIZE; + ret = CRYPT_EAL_CipherReinit(ctx, iv2->x, iv2->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in2->x, in2->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out2->x, out2->len) == 0); + + (void)memset_s(outTmp, MAXSIZE, 0, MAXSIZE); + len = MAXSIZE; + ret = CRYPT_EAL_CipherReinit(ctx, iv1->x, iv1->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in1->x, in1->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out1->x, out1->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +typedef struct { + int algId; + uint8_t *key; + uint32_t keyLen; + uint8_t *iv; + uint32_t ivLen; + uint8_t *in; + uint32_t inLen; + uint8_t *out; + uint32_t outLen; + int enc; +} TestVector; + +void SM4_MultiThreadTest(void *arg) +{ + TestVector *pTestVector = (TestVector *)arg; + int32_t ret; + uint8_t outTmp[MAXSIZE] = {0}; + uint32_t len = MAXSIZE; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(pTestVector->algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, pTestVector->key, pTestVector->keyLen, pTestVector->iv, pTestVector->ivLen, + pTestVector->enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, pTestVector->in, pTestVector->inLen, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, pTestVector->out, pTestVector->outLen) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctx); + CRYPT_EAL_CipherFreeCtx(ctx); +} + +/** + * @test SDV_CRYPTO_SM4_MULTI_THREAD_TC001 + * @title Multi-thread Test + * @precon Registering memory-related functions. + * @brief + * 1.Start three threads. Expected result 1 is obtained. + * 2.Call the eal interface in the thread for encryption. Expected result 2 is obtained. + * 3.Call the eal interface in the thread for decryption. Expected result 2 is obtained. + * @expect + * 1.Success. + * 2.The encryption is successful. The ciphertext and tag are the same as the vector. + * 3.The decryption is successful. The plaintext and tag are consistent with the vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_MULTI_THREAD_TC001(int algId, Hex *key, Hex *in, Hex *out, Hex *iv, int enc) +{ +#define THREAD_NUM 3 + TestMemInit(); + int32_t ret; + pthread_t thrd[THREAD_NUM]; + TestVector testVt = { + .algId = algId, + .key = key->x, + .keyLen = key->len, + .iv = iv->x, + .ivLen = iv->len, + .in = in->x, + .inLen = in->len, + .out = out->x, + .outLen = out->len, + .enc = enc + }; + + for (uint32_t i = 0; i < THREAD_NUM; i++) { + ret = pthread_create(&thrd[i], NULL, (void *)SM4_MultiThreadTest, &testVt); + ASSERT_TRUE(ret == 0); + } + for (uint32_t i = 0; i < THREAD_NUM; i++) { + pthread_join(thrd[i], NULL); + } +exit: + return; +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC006 + * @title Impact of the msg with no padding on the Update interface Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface with plain len is 17. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful and return CRYPT_SUCCESS. + * 3.The Update is successful. + * 4.The Final is failed. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC006(int id, Hex *key, Hex *iv, Hex *msg, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t out[MAX_OUTPUT] = {0}; + uint32_t outlen = MAX_OUTPUT; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(msg->len == BLOCKSIZE + 1); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, msg->x, msg->len, out, &outlen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + outlen = MAX_OUTPUT; + ret = CRYPT_EAL_CipherFinal(ctx, out, &outlen); + ASSERT_TRUE(ret != CRYPT_SUCCESS); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007 + * @title Update 0 message length Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface, data is NULL, dataLen is 0. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The Update is successful. + * 4.The outlen is consistent with expect. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007(int id, Hex *key, Hex *iv, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t out[MAX_OUTPUT] = {0}; + uint32_t outlen = MAX_OUTPUT; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(id); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, NULL, 0, out, &outlen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + if (id != CRYPT_CIPHER_SM4_GCM) { + outlen = MAX_OUTPUT; + ret = CRYPT_EAL_CipherFinal(ctx, out, &outlen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + } + ASSERT_TRUE(outlen == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008 + * @title Impact of updating IV on encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * 5.Call the Reinit interface to update iv. Expected result 5 is obtained. + * 6.Call the Update interface. Expected result 6 is obtained. + * 7.Call the Final interface. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The final is successful, return CRYPT_SUCCESS. The result is consistent with the test vector. + * 5.The reinit is successful, return CRYPT_SUCCESS. + * 6.The update is successful, return CRYPT_SUCCESS. + * 7.The final is successful, return CRYPT_SUCCESS. The result is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t finLen; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + finLen = MAX_OUTPUT - len; + ret = CipherFinal(algId, ctx, outTmp + len, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + + (void)memset_s(outTmp, MAX_OUTPUT, 0, MAX_OUTPUT); + len = MAX_OUTPUT; + ret = CRYPT_EAL_CipherReinit(ctx, iv->x, iv->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + finLen = MAX_OUTPUT - len; + ret = CipherFinal(algId, ctx, outTmp + len, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009 + * @title Impact of updating IV and Key on encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * 5.Call the Init interface to update iv and key. Expected result 5 is obtained. + * 6.Call the Update interface. Expected result 6 is obtained. + * 7.Call the Final interface. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The final is successful, return CRYPT_SUCCESS. The result is consistent with the test vector. + * 5.The Init is successful, return CRYPT_SUCCESS. + * 6.The update is successful, return CRYPT_SUCCESS. + * 7.The final is successful, return CRYPT_SUCCESS. The result is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t finLen; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + finLen = MAX_OUTPUT - len; + ret = CipherFinal(algId, ctx, outTmp + len, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); + + (void)memset_s(outTmp, MAX_OUTPUT, 0, MAX_OUTPUT); + len = MAX_OUTPUT; + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + finLen = MAX_OUTPUT - len; + ret = CipherFinal(algId, ctx, outTmp + len, &finLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010 + * @title Impact of the padding algorithm on encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the set padding interface with CRYPT_PADDING_PKCS7, CRYPT_PADDING_PKCS5, CRYPT_PADDING_X923 + * CRYPT_PADDING_ISO7816, CRYPT_PADDING_ZEROS, CRYPT_PADDING_NONE. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Use the SM4 decryption handle to call the Update interface with the ciphertext. Expected result 6 is obtained. + * 7.Call the Final interface. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The setting is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The update is successful, return CRYPT_SUCCESS. + * 7.The final is successful, and the plaintext is consistent with the origin data. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010(int algId, Hex *key, Hex *iv, int inLen, int padding) +{ + TestMemInit(); + int32_t ret; + uint8_t input[MAX_DATASZIE] = {0}; + uint8_t outTmp[MAX_DATASZIE] = {0}; + uint8_t result[MAX_DATASZIE] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_DATASZIE; + uint32_t len = MAX_DATASZIE; + + (void)memset_s(outTmp, MAX_DATASZIE, 0xAA, MAX_DATASZIE); + (void)memset_s(input, MAX_DATASZIE, 0xAA, MAX_DATASZIE); + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ASSERT_TRUE(inLen <= MAX_DATASZIE); + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxEnc, input, inLen, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + totalLen, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + len = MAX_DATASZIE; + leftLen = MAX_DATASZIE; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, totalLen, result, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + leftLen -= len; + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(input, result, inLen) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011 + * @title The input and output start addresses are the same Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call the set padding interface. Expected result 3 is obtained. + * 4.Call the Update interface with the input and output buff are same. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Use the SM4 decryption handle to call the Update interface with the ciphertext. Expected result 6 is obtained. + * 7.Call the Final interface. Expected result 7 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The setting is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The update is successful, return CRYPT_SUCCESS. + * 7.The final is successful, and the plaintext is consistent with the origin data. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011(int algId, Hex *key, Hex *iv, int inLen, int padding, int isSetPadding) +{ + TestMemInit(); + int32_t ret; + uint8_t input[MAX_DATASZIE] = {0}; + uint8_t outTmp[MAX_DATASZIE] = {0}; + uint8_t result[MAX_DATASZIE] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_DATASZIE; + uint32_t len = MAX_DATASZIE; + + (void)memset_s(outTmp, MAX_DATASZIE, 0xAA, MAX_DATASZIE); + (void)memset_s(input, MAX_DATASZIE, 0xAA, MAX_DATASZIE); + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + ASSERT_TRUE(inLen <= MAX_DATASZIE); + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxEnc, outTmp, inLen, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen -= len; + if (algId != CRYPT_CIPHER_SM4_GCM) { + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + totalLen, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + } + + len = MAX_OUTPUT; + leftLen = MAX_OUTPUT; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = SetPadding(isSetPadding, ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, outTmp, totalLen, result, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + leftLen -= len; + ret = CipherFinal(algId, ctxDec, result + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + ASSERT_TRUE(memcmp(input, result, inLen) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012 + * @title Impact of the key and iv of all 0s/all Fs on encryption and decryption Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface, with key and iv of all 0s/all Fs. Expected result 2 is obtained. + * 3.Call the Update interface. Expected result 3 is obtained. + * 4.Call the Final interface. Expected result 4 is obtained. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The final is successful, and the result is consistent with expect. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int enc) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t len = MAX_OUTPUT; + uint32_t totalLen = 0; + + CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctx != NULL); + ret = CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctx, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + len = MAX_OUTPUT - len; + if (algId != CRYPT_CIPHER_SM4_GCM){ + ret = CRYPT_EAL_CipherFinal(ctx, outTmp + totalLen, &len); + totalLen += len; + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + } + ASSERT_TRUE(memcmp(outTmp, out->x, out->len) == 0); +exit: + CRYPT_EAL_CipherFreeCtx(ctx); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013 + * @title SM4-GCM encryption full vector test + * @precon Registering memory-related functions. + * @brief + * 1.Call the Init interface. Expected result 1 is obtained. + * 2.Call the Ctrl interface to set parameters. Expected result 2 is obtained. + * 3.Call the update interface to update message. Expected result 3 is obtained. + * 4.Call the Ctrl interface to get tag. Expected result 4 is obtained. + * 5.Compare the ciphertext data. Expected result 5 is obtained. + * 6.Compare the tag data. Expected result 6 is obtained. + * @expect + * 1.The init is successful, return CRYPT_SUCCESS. + * 2.The setting is successful, return CRYPT_SUCCESS. + * 3.The update is successful, return CRYPT_SUCCESS. + * 4.The getting is successful, return CRYPT_SUCCESS. + * 5.Ciphertext is consistent with the test vector. + * 6.Tag is consistent with the test vector. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013(Hex *key, Hex *iv, Hex *aad, Hex *pt, Hex *ct, Hex *tag, int enc) +{ + TestMemInit(); + CRYPT_EAL_CipherCtx *ctx = NULL; + uint8_t *outTag = NULL; + uint8_t *out = NULL; + uint32_t tagLen = tag->len; + uint32_t outLen; + + if (ct->len > 0) { + out = (uint8_t *)BSL_SAL_Malloc(ct->len * sizeof(uint8_t)); + outLen = ct->len * sizeof(uint8_t); + ASSERT_TRUE(out != NULL); + } else { + out = (uint8_t *)BSL_SAL_Malloc(1 * sizeof(uint8_t)); + outLen = 1 * sizeof(uint8_t); + ASSERT_TRUE(out != NULL); + } + + ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_GCM); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherInit(ctx, key->x, key->len, iv->x, iv->len, enc) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, aad->x, aad->len) == CRYPT_SUCCESS); + ASSERT_TRUE(CRYPT_EAL_CipherUpdate(ctx, pt->x, pt->len, (uint8_t *)out, &outLen) == CRYPT_SUCCESS); + outTag = (uint8_t *)BSL_SAL_Malloc(sizeof(uint8_t) * tagLen); + ASSERT_TRUE(outTag != NULL); + ASSERT_TRUE(CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, (uint8_t *)outTag, tagLen) == CRYPT_SUCCESS); + + if (ct->x != NULL) { + ASSERT_TRUE(memcmp(out, ct->x, ct->len) == 0); + } + ASSERT_COMPARE("Compare Tag", outTag, tagLen, tag->x, tag->len); + +exit: + CRYPT_EAL_CipherFreeCtx(ctx); + free(out); + free(outTag); +} +/* END_CASE */ + + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC014 + * @title Encryption in different padding modes Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call SetPadding interface setting padding mode to CRYPT_PADDING_ISO7816, + * CRYPT_PADDING_X923, CRYPT_PADDING_PKCS7. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Call the init, update, and final interfaces to decrypt and verifiy the result. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The setting is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The verification is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC014(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int padding) +{ + TestMemInit(); + int32_t ret; + uint8_t outTmp[MAX_OUTPUT] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_OUTPUT; + uint32_t len = MAX_OUTPUT; + CRYPT_EAL_CipherCtx *ctxEnc = NULL; + + ctxEnc = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxEnc != NULL); + ret = CRYPT_EAL_CipherInit(ctxEnc, key->x, key->len, iv->x, iv->len, true); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxEnc, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxEnc, in->x, in->len, outTmp, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen = leftLen - len; + ret = CRYPT_EAL_CipherFinal(ctxEnc, outTmp + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += leftLen; + + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(memcmp(out->x, outTmp, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctxEnc); + CRYPT_EAL_CipherFreeCtx(ctxEnc); +} +/* END_CASE */ + +/** + * @test SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC015 + * @title Decryption in different padding modes Test + * @precon Registering memory-related functions. + * @brief + * 1.Create the context ctx. Expected result 1 is obtained. + * 2.Call the Init interface. Expected result 2 is obtained. + * 3.Call SetPadding interface setting padding mode to CRYPT_PADDING_ISO7816, + * CRYPT_PADDING_X923, CRYPT_PADDING_PKCS7. Expected result 3 is obtained. + * 4.Call the Update interface. Expected result 4 is obtained. + * 5.Call the Final interface. Expected result 5 is obtained. + * 6.Call the init, update, and final interfaces to decrypt and verifiy the result. + * @expect + * 1.The creation is successful and the ctx is not empty. + * 2.The init is successful, return CRYPT_SUCCESS. + * 3.The setting is successful, return CRYPT_SUCCESS. + * 4.The update is successful, return CRYPT_SUCCESS. + * 5.The final is successful, return CRYPT_SUCCESS. + * 6.The verification is successful, return CRYPT_SUCCESS. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC015(int algId, Hex *key, Hex *iv, Hex *in, Hex *out, int padding) +{ + TestMemInit(); + int32_t ret; + uint8_t result[MAX_OUTPUT] = {0}; + uint32_t totalLen = 0; + uint32_t leftLen = MAX_OUTPUT; + uint32_t len = MAX_OUTPUT; + CRYPT_EAL_CipherCtx *ctxDec = NULL; + + len = MAX_OUTPUT; + leftLen = MAX_OUTPUT; + ctxDec = CRYPT_EAL_CipherNewCtx(algId); + ASSERT_TRUE(ctxDec != NULL); + ret = CRYPT_EAL_CipherInit(ctxDec, key->x, key->len, iv->x, iv->len, false); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherSetPadding(ctxDec, padding); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + ret = CRYPT_EAL_CipherUpdate(ctxDec, in->x, in->len, result, &len); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + totalLen += len; + leftLen = leftLen - len; + ret = CRYPT_EAL_CipherFinal(ctxDec, result + len, &leftLen); + ASSERT_TRUE(ret == CRYPT_SUCCESS); + + totalLen += leftLen; + + ASSERT_TRUE(totalLen == out->len); + ASSERT_TRUE(memcmp(out->x, result, out->len) == 0); + +exit: + CRYPT_EAL_CipherDeinit(ctxDec); + CRYPT_EAL_CipherFreeCtx(ctxDec); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/crypto/sm4/test_suite_sdv_eal_sm4.data b/testcode/sdv/testcase/crypto/sm4/test_suite_sdv_eal_sm4.data new file mode 100644 index 00000000..205894da --- /dev/null +++ b/testcode/sdv/testcase/crypto/sm4/test_suite_sdv_eal_sm4.data @@ -0,0 +1,515 @@ +CRYPT_EAL_CipherInit interface iv param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherInit interface iv param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherInit interface iv param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherInit interface iv param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherInit interface iv param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC001:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" + +CRYPT_EAL_CipherInit interface xts test1 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"ffffffffffffffffffffffffffffffff":true +CRYPT_EAL_CipherInit interface xts test2 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"ffffffffffffffffffffffffffffffff":false +CRYPT_EAL_CipherInit interface xts test3 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"00000000000000000000000000000000":true +CRYPT_EAL_CipherInit interface xts test4 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"00000000000000000000000000000000":false +CRYPT_EAL_CipherInit interface xts test5 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":true +CRYPT_EAL_CipherInit interface xts test6 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":false + +CRYPT_EAL_CipherInit interface key param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC003:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherInit interface key param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC003:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherInit interface key param test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_INIT_API_TC003:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" + +CRYPT_EAL_CipherDeinit interface test xts +SDV_CRYPTO_SM4_DEINIT_API_TC001:CRYPT_CIPHER_SM4_XTS +CRYPT_EAL_CipherDeinit interface test cbc +SDV_CRYPTO_SM4_DEINIT_API_TC001:CRYPT_CIPHER_SM4_CBC +CRYPT_EAL_CipherDeinit interface test ctr +SDV_CRYPTO_SM4_DEINIT_API_TC001:CRYPT_CIPHER_SM4_CTR +CRYPT_EAL_CipherDeinit interface test gcm +SDV_CRYPTO_SM4_DEINIT_API_TC001:CRYPT_CIPHER_SM4_GCM +CRYPT_EAL_CipherDeinit interface test cfb +SDV_CRYPTO_SM4_DEINIT_API_TC001:CRYPT_CIPHER_SM4_CFB +CRYPT_EAL_CipherDeinit interface test ofb +SDV_CRYPTO_SM4_DEINIT_API_TC001:CRYPT_CIPHER_SM4_OFB + +CRYPT_EAL_CipherReinit interface test xts #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC001:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +CRYPT_EAL_CipherReinit interface test cbc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherReinit interface test ctr #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherReinit interface test gcm #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC001:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherReinit interface test cfb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherReinit interface test ofb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" + +CRYPT_EAL_CipherUpdate enc interface test xts #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172A":true +CRYPT_EAL_CipherUpdate dec interface test xts #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"E9538251C71D7B80BBE4483FEF497BD1":false +CRYPT_EAL_CipherUpdate enc interface test cbc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":true +CRYPT_EAL_CipherUpdate enc interface test cbc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"AC529AF989A62FCE9CDDC5FFB84125CA":false +CRYPT_EAL_CipherUpdate enc interface test ctr #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":true +CRYPT_EAL_CipherUpdate enc interface test ctr #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"14AE4A72B97A93CE1216CCD998E371C1":false +#from RFC8998 +CRYPT_EAL_CipherUpdate enc interface test gcm #from RFC8998 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":true +CRYPT_EAL_CipherUpdate enc interface test gcm #from RFC8998 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"17F399F08C67D5EE19D0DC9969C4BB7D":false +CRYPT_EAL_CipherUpdate enc interface test cfb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":true +CRYPT_EAL_CipherUpdate enc interface test cfb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"bc710d762d070b26361da82b54565e46":false +CRYPT_EAL_CipherUpdate enc interface test ofb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":true +CRYPT_EAL_CipherUpdate enc interface test ofb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_UPDATE_API_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"BC710D762D070B26361DA82B54565E46":false + +CRYPT_EAL_CipherCtrl interface test cbc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC001:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A" +CRYPT_EAL_CipherCtrl interface test ctr #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC002:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +CRYPT_EAL_CipherCtrl interface test xts #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC003:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_PKCS7:0 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_PKCS7:1 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_PKCS5:1 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_X923:1 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_ISO7816:1 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_ZEROS:1 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_NONE:0 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_NONE:0 +CRYPT_EAL_CipherFinal no update test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":CRYPT_PADDING_NONE:0 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_PKCS7 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS7 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_PKCS5 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS5 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_X923 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_X923 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_ISO7816 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_ISO7816 +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_ZEROS +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_ZEROS +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":128:CRYPT_PADDING_NONE +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_PKCS7 +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_PKCS5 +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_X923 +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_ISO7816 +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_ZEROS +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS5 +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":33:CRYPT_PADDING_ISO7816 +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":33:CRYPT_PADDING_ZEROS +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1000:CRYPT_PADDING_PKCS7 + +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 mode gcm encrypt #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":"17f399f08c67d5ee19d0dc9969c4bb7d":"00001234567800000000ABCD" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 mode ctr encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 mode cbc encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":"000102030405060708090A0B0C0D0E0F" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 mode cfb encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172A":"bc710d762d070b26361da82b54565e46":"000102030405060708090A0B0C0D0E0F" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 mode ofb encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"BC710D762D070B26361DA82B54565E4607A0C62834740AD3240D239125E11621D476B21CC9F04951F0741D2EF9E094981584FC142BF13AA626B82F9D7D076CCE":"000102030405060708090A0B0C0D0E0F" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 XTS_SM4_ENCRYPT_VECTOR1 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17":"E9538251C71D7B80BBE4483FEF497BD12C5C581BD6242FC51E08964FB4F60FDB0BA42F63499279213D318D2C11F6886E903BE7F93A1B3479":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 XTS_SM4_ENCRYPT_VECTOR2 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6BC1BEE22E409F96E93D7E117393172A":"E9538251C71D7B80BBE4483FEF497BD1":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003 mode cfb encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC003:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17":"bc710d762d070b26361da82b54565e46a4cd42786a3a5293a3c6cbc123f0b354407055b1c1a5d9982c187d5c3ee0ced84b82c40f2f0a4e03":"000102030405060708090A0B0C0D0E0F" + +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 mode gcm decrypt #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":"17f399f08c67d5ee19d0dc9969c4bb7d":"00001234567800000000ABCD" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 mode ctr decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 mode cbc decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":"000102030405060708090A0B0C0D0E0F" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 mode cfb decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172A":"bc710d762d070b26361da82b54565e46":"000102030405060708090A0B0C0D0E0F" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 mode ofb decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"BC710D762D070B26361DA82B54565E4607A0C62834740AD3240D239125E11621D476B21CC9F04951F0741D2EF9E094981584FC142BF13AA626B82F9D7D076CCE":"000102030405060708090A0B0C0D0E0F" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 XTS_SM4_ENCRYPT_VECTOR1 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17":"E9538251C71D7B80BBE4483FEF497BD12C5C581BD6242FC51E08964FB4F60FDB0BA42F63499279213D318D2C11F6886E903BE7F93A1B3479":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 XTS_SM4_ENCRYPT_VECTOR2 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6BC1BEE22E409F96E93D7E117393172A":"E9538251C71D7B80BBE4483FEF497BD1":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004 mode cfb decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC004:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17":"bc710d762d070b26361da82b54565e46a4cd42786a3a5293a3c6cbc123f0b354407055b1c1a5d9982c187d5c3ee0ced84b82c40f2f0a4e03":"000102030405060708090A0B0C0D0E0F" + + +CRYPT_CIPHER_SM4_CBC multi update 8 times 16byte #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":8:CRYPT_PADDING_PKCS7:1 +CRYPT_CIPHER_SM4_CTR multi update 8 times 16bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":8:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_GCM multi update 8 times 16bytes #from RFC8998 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":8:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_CFB multi update 8 times 16byte #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":8:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_OFB multi update 8 times 16bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":8:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_CBC multi update 3 times 17bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE":3:CRYPT_PADDING_PKCS7:1 +CRYPT_CIPHER_SM4_CTR multi update 3 times 16bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172A":3:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_GCM multi update 3 times 16bytes #from RFC8998 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":3:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_CFB multi update 3 times 17bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE":3:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_OFB multi update 3 times 17bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE":3:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_CBC multi update 16 times 15bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E11739317":16:CRYPT_PADDING_PKCS7:1 +CRYPT_CIPHER_SM4_CTR multi update 16 times 16bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172A":16:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_GCM multi update 16 times 16bytes #from RFC8998 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":16:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_CFB multi update 16 times 15bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E11739317":16:CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_OFB multi update 16 times 15bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E11739317":16:CRYPT_PADDING_NONE:0 + +CRYPT_CIPHER_SM4_CBC 5 time update, NO.1,3,5 update 15 bytes, NO.2,4 update 16 bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":CRYPT_PADDING_PKCS7:1 +CRYPT_CIPHER_SM4_CTR 5 time update, NO.1,3,5 update 15 bytes, NO.2,4 update 16 bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC002:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172A":CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_GCM 5 time update, NO.1,3,5 update 15 bytes, NO.2,4 update 16 bytes #from RFC8998 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC002:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_CFB 5 time update, NO.1,3,5 update 15 bytes, NO.2,4 update 16 bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC002:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":CRYPT_PADDING_NONE:0 +CRYPT_CIPHER_SM4_OFB 5 time update, NO.1,3,5 update 15 bytes, NO.2,4 update 16 bytes #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_UPDATE_TC002:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172A":CRYPT_PADDING_NONE:0 + +SM4_ENCRYPT_CTRL test cbc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC004:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +SM4_ENCRYPT_CTRL test ctr #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC004:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SM4_ENCRYPT_CTRL test cfb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC004:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +SM4_ENCRYPT_CTRL test ofb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC004:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +SM4_ENCRYPT_CTRL test xts #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC004:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + +SM4_DECRYPT_CTRL test cbc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC005:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +SM4_DECRYPT_CTRL test ctr #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC005:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +SM4_DECRYPT_CTRL test cfb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC005:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +SM4_DECRYPT_CTRL test ofb #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC005:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +SM4_DECRYPT_CTRL test xts #from GB/T 17964-2021 +SDV_CRYPTO_SM4_CTRL_API_TC005:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + +Reinit interface test CBC #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC002:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +Reinit interface test CTR #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC002:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +Reinit interface test GCM #from RFC8998 +SDV_CRYPTO_SM4_REINIT_API_TC002:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD" +Reinit interface test CFB #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC002:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" +Reinit interface test OFB #from GB/T 17964-2021 +SDV_CRYPTO_SM4_REINIT_API_TC002:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F" + +Reinit interface test xts 1 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC005:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E51":"E9538251C71D7B80BBE4483FEF497BD12C5C581BD6242FC51E08964FB4F60FDB":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172A":"E9538251C71D7B80BBE4483FEF497BD1":"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF":true +Reinit interface test xts 2 #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC005:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"E9538251C71D7B80BBE4483FEF497BD12C5C581BD6242FC51E08964FB4F60FDB":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E51":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"E9538251C71D7B80BBE4483FEF497BD1":"6BC1BEE22E409F96E93D7E117393172A":"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF":false +Reinit interface test xts 3 self generate test vector +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC005:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17":"e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"000102030405060708090a0b0c0d0e0f":"17442e5e3ae9a314caf8f752df8c4ba2":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":true +Reinit interface test xts 4 self generate test vector +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC005:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"17442e5e3ae9a314caf8f752df8c4ba2":"000102030405060708090a0b0c0d0e0f":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":false + +SM4_MUTITHREAD xts enc #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17":"e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":true +SM4_MUTITHREAD xts dec #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_XTS:"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f":"e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":false +SM4_MUTITHREAD mode gcm encrypt #from RFC8998 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA":"17F399F08C67D5EE19D0DC9969C4BB7D5FD46FD3756489069157B282BB200735D82710CA5C22F0CCFA7CBF93D496AC15A56834CBCF98C397B4024A2691233B8D":"00001234567800000000ABCD":true +SM4_MUTITHREAD mode ctr encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF":true +SM4_MUTITHREAD mode cbc encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":"000102030405060708090A0B0C0D0E0F":true +SM4_MUTITHREAD mode cfb encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17":"bc710d762d070b26361da82b54565e46a4cd42786a3a5293a3c6cbc123f0b354407055b1c1a5d9982c187d5c3ee0ced84b82c40f2f0a4e03":"000102030405060708090A0B0C0D0E0F":true +SM4_MUTITHREAD mode ofb encrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"BC710D762D070B26361DA82B54565E4607A0C62834740AD3240D239125E11621D476B21CC9F04951F0741D2EF9E094981584FC142BF13AA626B82F9D7D076CCE":"000102030405060708090A0B0C0D0E0F":true +SM4_MUTITHREAD mode cbc decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"000102030405060708090A0B0C0D0E0F":false +SM4_MUTITHREAD mode ctr decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF":false +SM4_MUTITHREAD mode gcm decrypt #from RFC8998 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"17F399F08C67D5EE19D0DC9969C4BB7D5FD46FD3756489069157B282BB200735D82710CA5C22F0CCFA7CBF93D496AC15A56834CBCF98C397B4024A2691233B8D":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA":"00001234567800000000ABCD":false +SM4_MUTITHREAD mode cfb decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_CFB:"2b7e151628aed2a6abf7158809cf4f3c":"bc710d762d070b26361da82b54565e46a4cd42786a3a5293a3c6cbc123f0b354407055b1c1a5d9982c187d5c3ee0ced84b82c40f2f0a4e03":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17":"000102030405060708090A0B0C0D0E0F":false +SM4_MUTITHREAD mode ofb decrypt #from GB/T 17964-2021 +SDV_CRYPTO_SM4_MULTI_THREAD_TC001:CRYPT_CIPHER_SM4_OFB:"2b7e151628aed2a6abf7158809cf4f3c":"BC710D762D070B26361DA82B54565E4607A0C62834740AD3240D239125E11621D476B21CC9F04951F0741D2EF9E094981584FC142BF13AA626B82F9D7D076CCE":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"000102030405060708090A0B0C0D0E0F":false + +CRYPT_EAL_CipherUpdate update 17 byte test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE":true + +CRYPT_EAL_CipherUpdate update 17 byte test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC006:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"AC529AF989A62FCE9CDDC5FFB84125CAB1":false + +CRYPT_EAL_CipherUpdate update 0 byte test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":true + +CRYPT_EAL_CipherUpdate update 0 byte test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":false + +CRYPT_EAL_CipherUpdate update 0 byte test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF":true + +CRYPT_EAL_CipherUpdate update 0 byte test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF":false + +CRYPT_EAL_CipherUpdate update 0 byte test #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":true + +CRYPT_EAL_CipherUpdate update 0 byte test #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC007:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":false + +CRYPT_CIPHER_SM4_CBC reinit after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":true + +CRYPT_CIPHER_SM4_CBC reinit after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":false + +CRYPT_CIPHER_SM4_CTR reinit after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":true + +CRYPT_CIPHER_SM4_CTR reinit after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":false + +CRYPT_CIPHER_SM4_GCM reinit after final test #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":"17f399f08c67d5ee19d0dc9969c4bb7d":true + +CRYPT_CIPHER_SM4_GCM reinit after final test #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC008:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"17f399f08c67d5ee19d0dc9969c4bb7d":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":false + +CRYPT_CIPHER_SM4_CBC init after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":true + +CRYPT_CIPHER_SM4_CBC init after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"AC529AF989A62FCE9CDDC5FFB84125CAB168DD69DB3C0EEA1AB16DE6AEA43C592C15567BFF8F707486C202C7BE59101F74A629B350CD7E11BE99998AF5206D6C":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":false + +CRYPT_CIPHER_SM4_CTR init after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":true + +CRYPT_CIPHER_SM4_CTR init after final test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"14AE4A72B97A93CE1216CCD998E371C160F7EF8B6344BD6DA1992505E5FC219B0BF057F86C5D75103C0F46519C7FB2E7292805035ADB9A90ECEF145359D7CF0E":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":false + +CRYPT_CIPHER_SM4_GCM init after final test #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":"17f399f08c67d5ee19d0dc9969c4bb7d":true + +CRYPT_CIPHER_SM4_GCM init after final test #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC009:CRYPT_CIPHER_SM4_GCM:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"17f399f08c67d5ee19d0dc9969c4bb7d":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB":false + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_PKCS7 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS7 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_PKCS5 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS5 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_X923 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_X923 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_ISO7816 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_ISO7816 + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":10:CRYPT_PADDING_ZEROS + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_ZEROS + +CRYPT_CIPHER_SM4_CBC padding test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":128:CRYPT_PADDING_NONE + +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_PKCS7 + +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS5 + +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":33:CRYPT_PADDING_ISO7816 + +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":33:CRYPT_PADDING_ZEROS + +CRYPT_CIPHER_SM4_CBC dataLen test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC010:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":16384:CRYPT_PADDING_PKCS7 + +CRYPT_CIPHER_SM4_CBC input output use same address #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":1:CRYPT_PADDING_PKCS7:1 + +CRYPT_CIPHER_SM4_CBC input output use same address #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":15:CRYPT_PADDING_PKCS5:1 + +CRYPT_CIPHER_SM4_CBC input output use same address #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":33:CRYPT_PADDING_ZEROS:1 + +CRYPT_CIPHER_SM4_CBC input output use same address #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":128:CRYPT_PADDING_NONE:1 + +CRYPT_CIPHER_SM4_CTR input output use same address #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":128:CRYPT_PADDING_NONE:0 + +CRYPT_CIPHER_SM4_GCM input output use same address #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC011:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":128:CRYPT_PADDING_NONE:0 + +#from generate data +CRYPT_CIPHER_SM4_CBC key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0123456789ABCDEFFEDCBA9876543210":"3F8F3655343713839F89871AB171A1A5":true + +CRYPT_CIPHER_SM4_CBC key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0123456789ABCDEFFEDCBA9876543210":"A81E94294F1F8528A9B214BB606E78DE":true + +CRYPT_CIPHER_SM4_CBC key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"3F8F3655343713839F89871AB171A1A5":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CBC key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"A81E94294F1F8528A9B214BB606E78DE":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CTR key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0123456789ABCDEFFEDCBA9876543210":"97188E4D287D4E29D921CE33842DFCB6":true + +CRYPT_CIPHER_SM4_CTR key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0123456789ABCDEFFEDCBA9876543210":"BB37D8ED65A2C5105E0044F8D0EDCF90":true + +CRYPT_CIPHER_SM4_CTR key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"97188E4D287D4E29D921CE33842DFCB6":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CTR key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"BB37D8ED65A2C5105E0044F8D0EDCF90":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_GCM key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0123456789ABCDEFFEDCBA9876543210":"9288AD4B899719E148920B986F03099B":true + +CRYPT_CIPHER_SM4_GCM key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0123456789ABCDEFFEDCBA9876543210":"AC0B1FBEAA4A52A235376D5DCD635BAF":true + +CRYPT_CIPHER_SM4_GCM key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"9288AD4B899719E148920B986F03099B":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_GCM key value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"AC0B1FBEAA4A52A235376D5DCD635BAF":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CBC IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0123456789ABCDEFFEDCBA9876543210":"BAEE34C949542AE71D3638B842EA834A":true + +CRYPT_CIPHER_SM4_CBC IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"00000000000000000000000000000000":"0123456789ABCDEFFEDCBA9876543210":"179E323A0F16F94B7A10AB80A011730D":true + +CRYPT_CIPHER_SM4_CBC IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"BAEE34C949542AE71D3638B842EA834A":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CBC IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"00000000000000000000000000000000":"179E323A0F16F94B7A10AB80A011730D":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CTR IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0123456789ABCDEFFEDCBA9876543210":"34BB56872271E7FEFB1920A3659A306F":true + +CRYPT_CIPHER_SM4_CTR IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"00000000000000000000000000000000":"0123456789ABCDEFFEDCBA9876543210":"08E8A43A0CB096E4457870DA9CB7CD60":true + +CRYPT_CIPHER_SM4_CTR IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"34BB56872271E7FEFB1920A3659A306F":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_CTR IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_CTR:"2b7e151628aed2a6abf7158809cf4f3c":"00000000000000000000000000000000":"08E8A43A0CB096E4457870DA9CB7CD60":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_GCM IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0123456789ABCDEFFEDCBA9876543210":"6C2F01FDA84DB58BBEEA57DBCA5B6EE8":true + +CRYPT_CIPHER_SM4_GCM IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"00000000000000000000000000000000":"0123456789ABCDEFFEDCBA9876543210":"AD9E13DBFA70BA762CE14D3AA59E643B":true + +CRYPT_CIPHER_SM4_GCM IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"6C2F01FDA84DB58BBEEA57DBCA5B6EE8":"0123456789ABCDEFFEDCBA9876543210":false + +CRYPT_CIPHER_SM4_GCM IV value test +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC012:CRYPT_CIPHER_SM4_GCM:"2b7e151628aed2a6abf7158809cf4f3c":"00000000000000000000000000000000":"AD9E13DBFA70BA762CE14D3AA59E643B":"0123456789ABCDEFFEDCBA9876543210":false + +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013 SM4 GCM diff len #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA":"17F399F08C67D5EE19D0DC9969C4BB7D5FD46FD3756489069157B282BB200735D82710CA5C22F0CCFA7CBF93D496AC15A56834CBCF98C397B4024A2691233B8D":"83DE3541E4C2B58177E065A9BF7B62EC":true +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013 SM4 GCM diff len #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2":"17F399F08C67D5EE19D0DC9969C4BB7D5FD46FD3756489069157B282BB200735D82710CA5C22F0CCFA7CBF93D496AC15A56834CBCF98C397B4024A2691233B8D":"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA":"83DE3541E4C2B58177E065A9BF7B62EC":false +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013 SM4 GCM diff len #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2":"":"":"63aa7895a55f35dd693ea9e3f98bf3ff":true +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013 SM4 GCM diff len #from RFC8998 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC013:"0123456789ABCDEFFEDCBA9876543210":"00001234567800000000ABCD":"FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2":"":"":"63aa7895a55f35dd693ea9e3f98bf3ff":false + +sm4 padding encrypt test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC014:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445":"ac529af989a62fce9cddc5ffb84125cab168dd69db3c0eea1ab16de6aea43c592c15567bff8f707486c202c7be59101fb577d41e13e5003f6ba20036e61ae573":CRYPT_PADDING_X923 +sm4 padding encrypt test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC014:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445":"ac529af989a62fce9cddc5ffb84125cab168dd69db3c0eea1ab16de6aea43c592c15567bff8f707486c202c7be59101f64e5bfafdd3f91adc109bc9bf8181dd3":CRYPT_PADDING_PKCS7 +sm4 padding encrypt test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC014:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445":"ac529af989a62fce9cddc5ffb84125cab168dd69db3c0eea1ab16de6aea43c592c15567bff8f707486c202c7be59101f5b16a7f092ad33ae38bbb8eebf027d09":CRYPT_PADDING_ISO7816 + +sm4 padding decrypt test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC015:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"ac529af989a62fce9cddc5ffb84125cab168dd69db3c0eea1ab16de6aea43c592c15567bff8f707486c202c7be59101fb577d41e13e5003f6ba20036e61ae573":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445":CRYPT_PADDING_X923 +sm4 padding decrypt test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC015:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"ac529af989a62fce9cddc5ffb84125cab168dd69db3c0eea1ab16de6aea43c592c15567bff8f707486c202c7be59101f64e5bfafdd3f91adc109bc9bf8181dd3":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445":CRYPT_PADDING_PKCS7 +sm4 padding decrypt test #from GB/T 17964-2021 +SDV_CRYPTO_SM4_ENCRYPT_FUNC_TC015:CRYPT_CIPHER_SM4_CBC:"2b7e151628aed2a6abf7158809cf4f3c":"000102030405060708090A0B0C0D0E0F":"ac529af989a62fce9cddc5ffb84125cab168dd69db3c0eea1ab16de6aea43c592c15567bff8f707486c202c7be59101f5b16a7f092ad33ae38bbb8eebf027d09":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445":CRYPT_PADDING_ISO7816 \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_ciphersuite.c b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_ciphersuite.c new file mode 100644 index 00000000..b9994ba1 --- /dev/null +++ b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_ciphersuite.c @@ -0,0 +1,259 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include "securec.h" +#include "hlt.h" +#include "logger.h" +#include "hitls_config.h" +#include "hitls_cert_type.h" +#include "crypt_util_rand.h" +#include "helper.h" +#include "hitls.h" +#include "frame_tls.h" +#include "hitls_type.h" +/* END_HEADER */ + +#define READ_BUF_LEN_18K (18 * 1024) +#define PORT 10086 +int32_t g_testSecurityLevel = 0; + +void SetCert(HLT_Ctx_Config *ctxConfig, char *cert) +{ + if (strncmp(cert, "RSA", strlen("RSA")) == 0) { + HLT_SetCertPath(ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA256_EE_PATH3, RSA_SHA256_PRIV_PATH3, + "NULL", "NULL"); + } else if (strncmp(cert, "ECDSA", strlen("ECDSA")) == 0) { + HLT_SetCertPath(ctxConfig, ECDSA_SHA_CA_PATH, ECDSA_SHA_CHAIN_PATH, ECDSA_SHA256_EE_PATH, + ECDSA_SHA256_PRIV_PATH, "NULL", "NULL"); + } +} + +char *HITLS_TLS13_Ciphersuite[] = { + "HITLS_AES_128_GCM_SHA256", + "HITLS_AES_256_GCM_SHA384", + "HITLS_CHACHA20_POLY1305_SHA256", + "HITLS_AES_128_CCM_SHA256", + "HITLS_AES_128_CCM_8_SHA256", +}; + +// RSA Authentication +char *HITLS_RSA_Ciphersuite[] = { + "HITLS_RSA_WITH_AES_128_CBC_SHA", + "HITLS_RSA_WITH_AES_256_CBC_SHA", + "HITLS_RSA_WITH_AES_128_CBC_SHA256", + "HITLS_RSA_WITH_AES_256_CBC_SHA256", + "HITLS_RSA_WITH_AES_128_GCM_SHA256", + "HITLS_RSA_WITH_AES_256_GCM_SHA384", + "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "HITLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "HITLS_DHE_RSA_WITH_AES_128_CCM", + "HITLS_DHE_RSA_WITH_AES_256_CCM", + "HITLS_RSA_WITH_AES_256_CCM", + "HITLS_RSA_WITH_AES_256_CCM_8", + "HITLS_RSA_WITH_AES_128_CCM", + "HITLS_RSA_WITH_AES_128_CCM_8", +}; + +// ECDSA Authentication +char *HITLS_ECDSA_Ciphersuite[] = { + "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_ECDHE_ECDSA_WITH_AES_128_CCM", + "HITLS_ECDHE_ECDSA_WITH_AES_256_CCM", +}; + +char *HITLS_ANON_Ciphersuite[] = { + "HITLS_DH_ANON_WITH_AES_128_CBC_SHA", + "HITLS_DH_ANON_WITH_AES_256_CBC_SHA", + "HITLS_DH_ANON_WITH_AES_128_CBC_SHA256", + "HITLS_DH_ANON_WITH_AES_256_CBC_SHA256", + "HITLS_DH_ANON_WITH_AES_128_GCM_SHA256", + "HITLS_DH_ANON_WITH_AES_256_GCM_SHA384", + "HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA", + "HITLS_ECDH_ANON_WITH_AES_256_CBC_SHA", +}; + +// PSK Authentication +char *HITLS_PSK_Ciphersuite[] = { + "HITLS_PSK_WITH_AES_128_CBC_SHA", + "HITLS_PSK_WITH_AES_256_CBC_SHA", + "HITLS_PSK_WITH_AES_128_GCM_SHA256", + "HITLS_PSK_WITH_AES_256_GCM_SHA384", + "HITLS_PSK_WITH_AES_128_CBC_SHA256", + "HITLS_PSK_WITH_AES_256_CBC_SHA384", + "HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + "HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + "HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", + "HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", + "HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_RSA_PSK_WITH_AES_128_CBC_SHA", + "HITLS_RSA_PSK_WITH_AES_256_CBC_SHA", + "HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256", + "HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384", + "HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256", + "HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384", + "HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_DHE_PSK_WITH_AES_128_CBC_SHA", + "HITLS_DHE_PSK_WITH_AES_256_CBC_SHA", + "HITLS_DHE_PSK_WITH_AES_128_GCM_SHA256", + "HITLS_DHE_PSK_WITH_AES_256_GCM_SHA384", + "HITLS_DHE_PSK_WITH_AES_128_CBC_SHA256", + "HITLS_DHE_PSK_WITH_AES_256_CBC_SHA384", + "HITLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "HITLS_DHE_PSK_WITH_AES_128_CCM", + "HITLS_DHE_PSK_WITH_AES_256_CCM", + "HITLS_PSK_WITH_AES_256_CCM", + "HITLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256", + "HITLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384", + "HITLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256", +}; + +static void CONNECT(int version, int connType, char *Ciphersuite, int hasPsk, char *cert) +{ + HLT_Process *localProcess = HLT_InitLocalProcess(HITLS); + HLT_Process *remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, PORT, true); + ASSERT_TRUE(localProcess != NULL); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(serverCtxConfig != NULL); + ASSERT_TRUE(clientCtxConfig != NULL); + + uint8_t psk[] = "12121212121212"; + if (hasPsk) { + memcpy_s(serverCtxConfig->psk, PSK_MAX_LEN, psk, sizeof(psk)); + memcpy_s(clientCtxConfig->psk, PSK_MAX_LEN, psk, sizeof(psk)); + } + + serverCtxConfig->securitylevel = g_testSecurityLevel; + clientCtxConfig->securitylevel = g_testSecurityLevel; + + SetCert(serverCtxConfig, cert); + SetCert(clientCtxConfig, cert); + + HLT_SetCipherSuites(serverCtxConfig, Ciphersuite); + HLT_SetCipherSuites(clientCtxConfig, Ciphersuite); + + HLT_Tls_Res *serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Tls_Res *clientRes = HLT_ProcessTlsConnect(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf[READ_BUF_LEN_18K] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, READ_BUF_LEN_18K, &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); +exit: + HLT_FreeAllProcess(); +} + +/* BEGIN_CASE */ +void SDV_TLS_TLS13_CIPHER_SUITE(void) +{ + for (uint16_t i = 0; i < sizeof(HITLS_TLS13_Ciphersuite) / sizeof(HITLS_TLS13_Ciphersuite[0]); i++) { + CONNECT(TLS1_3, TCP, HITLS_TLS13_Ciphersuite[i], 0, "RSA"); + } +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_RSA_CIPHER_SUITE(void) +{ + for (uint16_t i = 0; i < sizeof(HITLS_RSA_Ciphersuite) / sizeof(HITLS_RSA_Ciphersuite[0]); i++) { + SUB_PROC_BEGIN(continue); + CONNECT(TLS1_2, TCP, HITLS_RSA_Ciphersuite[i], 0, "RSA"); + if (IsEnableSctpAuth()) { + CONNECT(DTLS1_2, SCTP, HITLS_RSA_Ciphersuite[i], 0, "RSA"); + } + SUB_PROC_END(); + } + SUB_PROC_WAIT(sizeof(HITLS_RSA_Ciphersuite) / sizeof(HITLS_RSA_Ciphersuite[0])); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_ECDSA_CIPHER_SUITE(void) +{ + for (uint16_t i = 0; i < sizeof(HITLS_ECDSA_Ciphersuite) / sizeof(HITLS_ECDSA_Ciphersuite[0]); i++) { + SUB_PROC_BEGIN(continue); + CONNECT(TLS1_2, TCP, HITLS_ECDSA_Ciphersuite[i], 0, "ECDSA"); + if (IsEnableSctpAuth()) { + CONNECT(DTLS1_2, SCTP, HITLS_ECDSA_Ciphersuite[i], 0, "ECDSA"); + } + SUB_PROC_END(); + } + SUB_PROC_WAIT(sizeof(HITLS_ECDSA_Ciphersuite) / sizeof(HITLS_ECDSA_Ciphersuite[0])); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_PSK_CIPHER_SUITE(void) +{ + for (uint16_t i = 0; i < sizeof(HITLS_PSK_Ciphersuite) / sizeof(HITLS_PSK_Ciphersuite[0]); i++) + { + SUB_PROC_BEGIN(continue); + CONNECT(TLS1_2, TCP, HITLS_PSK_Ciphersuite[i], 1, "RSA"); + if (IsEnableSctpAuth()) { + CONNECT(DTLS1_2, SCTP, HITLS_PSK_Ciphersuite[i], 1, "RSA"); + } + SUB_PROC_END(); + } + SUB_PROC_WAIT(sizeof(HITLS_PSK_Ciphersuite) / sizeof(HITLS_PSK_Ciphersuite[0])); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_ANON_CIPHER_SUITE(void) +{ + for (uint16_t i = 0; i < sizeof(HITLS_ANON_Ciphersuite) / sizeof(HITLS_ANON_Ciphersuite[0]); i++) { + SUB_PROC_BEGIN(continue); + CONNECT(TLS1_2, TCP, HITLS_ANON_Ciphersuite[i], 0, "RSA"); + if (IsEnableSctpAuth()) { + CONNECT(DTLS1_2, SCTP, HITLS_ANON_Ciphersuite[i], 0, "RSA"); + } + SUB_PROC_END(); + } + SUB_PROC_WAIT(sizeof(HITLS_ANON_Ciphersuite) / sizeof(HITLS_ANON_Ciphersuite[0])); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_ciphersuite.data b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_ciphersuite.data new file mode 100644 index 00000000..9d1240de --- /dev/null +++ b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_ciphersuite.data @@ -0,0 +1,14 @@ +SDV_TLS_TLS13_CIPHER_SUITE +SDV_TLS_TLS13_CIPHER_SUITE: + +SDV_TLS_RSA_CIPHER_SUITE +SDV_TLS_RSA_CIPHER_SUITE: + +SDV_TLS_ECDSA_CIPHER_SUITE +SDV_TLS_ECDSA_CIPHER_SUITE: + +SDV_TLS_PSK_CIPHER_SUITE +SDV_TLS_PSK_CIPHER_SUITE: + +SDV_TLS_ANON_CIPHER_SUITE +SDV_TLS_ANON_CIPHER_SUITE: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_tlcp_ciphersuite.c b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_tlcp_ciphersuite.c new file mode 100644 index 00000000..44d162cc --- /dev/null +++ b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_tlcp_ciphersuite.c @@ -0,0 +1,79 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "hlt.h" +#include "logger.h" +#include "hitls_config.h" +#include "hitls_cert_type.h" +#include "crypt_util_rand.h" +#include "hitls.h" +#include "frame_tls.h" +#include "hitls_type.h" +/* END_HEADER */ + +#define READ_BUF_LEN_18K (18 * 1024) +#define PORT 10088 + +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CIPHER_SUITE_TC01(char *cipherSuiteType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + // Configure link information on the server. + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + ASSERT_TRUE(serverCtxConfig != NULL); + HLT_SetCipherSuites(serverCtxConfig, cipherSuiteType); + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->needCheckKeyUsage = true; + + // The server listens on the TLS link. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLCP1_1, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // Configure link information on the client. + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + ASSERT_TRUE(clientCtxConfig != NULL); + HLT_SetCipherSuites(clientCtxConfig, cipherSuiteType); + + // Set up a TLCP link on the client. + clientRes = HLT_ProcessTlsConnect(localProcess, TLCP1_1, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + ASSERT_TRUE(HLT_ProcessTlsWrite(remoteProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + + uint8_t readBuf[READ_BUF_LEN_18K] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(localProcess, clientRes, readBuf, READ_BUF_LEN_18K, &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_tlcp_ciphersuite.data b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_tlcp_ciphersuite.data new file mode 100644 index 00000000..3910e58b --- /dev/null +++ b/testcode/sdv/testcase/tls/ciphersuite/test_suite_sdv_hlt_tlcp_ciphersuite.data @@ -0,0 +1,5 @@ +SDV_TLS_TLCP_CIPHER_SUITE_TC01 +SDV_TLS_TLCP_CIPHER_SUITE_TC01:"HITLS_ECDHE_SM4_CBC_SM3" + +SDV_TLS_TLCP_CIPHER_SUITE_TC01 +SDV_TLS_TLCP_CIPHER_SUITE_TC01:"HITLS_ECC_SM4_CBC_SM3" \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.base.c b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.base.c new file mode 100644 index 00000000..bc76cdab --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.base.c @@ -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. + */ + +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_state_recv.h" +#include "conn_init.h" +#include "recv_process.h" +#include "stub_replace.h" +#include "stub_crypt.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "cert.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "hlt.h" +#include "sctp_channel.h" +#include "rec_wrapper.h" +#include "process.h" +#include "pthread.h" +#include "unistd.h" +#include "rec_header.h" +#include "bsl_log.h" +#include "cert_callback.h" + + +#define BUF_SIZE_DTO_TEST 18432 +int32_t g_uiPort = 18887; + +#define PARSEMSGHEADER_LEN 13 +#define ILLEGAL_VALUE 0xFF +#define HASH_EXDATA_LEN_ERROR 23 +#define SIGNATURE_ALGORITHMS 0x04, 0x03 +#define READ_BUF_SIZE (18 * 1024) +#define TEMP_DATA_LEN 1024 +#define REC_DTLS_RECORD_HEADER_LEN 13 +#define BUF_TOOLONG_LEN ((1 << 14) + 1) + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; +} HandshakeTestInfo; + +int32_t StatusPark(HandshakeTestInfo *testInfo) +{ + + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_SCTP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_SCTP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + + if (FRAME_CreateConnection(testInfo->client, testInfo->server, + testInfo->isClient, testInfo->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + FRAME_RegCryptMethod(); // stub all crypto functions + + testInfo->config = HITLS_CFG_NewDTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusPark(testInfo); +} + +int32_t DefaultCfgStatusParkWithSuite(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + + testInfo->config = HITLS_CFG_NewDTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(testInfo->config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusPark(testInfo); +} + +int32_t SendHelloReqWithIndex(HITLS_Ctx *ctx, uint8_t index) +{ + int32_t ret; + + uint8_t buf[DTLS_HS_MSG_HEADER_SIZE] = {0u}; + buf[5] = index; + size_t len = DTLS_HS_MSG_HEADER_SIZE; + + + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} + +int32_t ConstructAnEmptyCertMsg(FRAME_LinkObj *link) +{ + FRAME_Msg frameMsg = {0}; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(link->io); + + + uint8_t *buffer = ioUserData->recMsg.msg; + uint32_t len = ioUserData->recMsg.len; + if (len == 0) { + return HITLS_MEMCPY_FAIL; + } + + + uint32_t parseLen = 0; + if (ParserTotalRecord(link, &frameMsg, buffer, len, &parseLen) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + + CERT_Item *tmpCert = frameMsg.body.handshakeMsg.body.certificate.cert; + frameMsg.body.handshakeMsg.body.certificate.cert = NULL; + frameMsg.bodyLen = 15; + + + if (PackFrameMsg(&frameMsg) != HITLS_SUCCESS) { + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_INTERNAL_EXCEPTION; + } + + + ioUserData->recMsg.len = 0; + if (FRAME_TransportRecMsg(link->io, frameMsg.buffer, frameMsg.len) != HITLS_SUCCESS) { + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_INTERNAL_EXCEPTION; + } + + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_SUCCESS; +} + + +static int32_t GetDisorderClientFinished(FRAME_LinkObj *client, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + int32_t ret; + uint32_t readLen = 0; + uint32_t offset = 0; + (void)HITLS_Connect(client->ssl); + ret = FRAME_TransportSendMsg(client->io, &data[offset], len - offset, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + offset += readLen; + uint8_t tmpData[TEMP_DATA_LEN] = {0}; + uint32_t tmpLen = sizeof(tmpData); + (void)HITLS_Connect(client->ssl); + ret = FRAME_TransportSendMsg(client->io, tmpData, tmpLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + tmpLen = readLen; + (void)HITLS_Connect(client->ssl); + ret = FRAME_TransportSendMsg(client->io, &data[offset], len - offset, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + offset += readLen; + if (memcpy_s(&data[offset], len - offset, tmpData, tmpLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += tmpLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t GetDisorderServerFinished(FRAME_LinkObj *server, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + int32_t ret; + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t tmpData[TEMP_DATA_LEN] = {0}; + uint32_t tmpLen = sizeof(tmpData); + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, tmpData, tmpLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + tmpLen = readLen; + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, &data[offset], len - offset, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + offset += readLen; + if (memcpy_s(&data[offset], len - offset, tmpData, tmpLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += tmpLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t AppWrite(HITLS_Ctx *ctx) +{ + int32_t ret; + uint8_t writeBuf[] = "GET HTTP 1.0"; + uint32_t len = strlen((char *)writeBuf); + do { + ret = HITLS_Write(ctx, writeBuf, len); + } while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); + return ret; +} + +static int32_t GetDisorderClientFinished_AppData(FRAME_LinkObj *client, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + int32_t ret; + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t app[TEMP_DATA_LEN] = {0}; + uint32_t appLen = sizeof(app); + uint8_t finished[TEMP_DATA_LEN] = {0}; + uint32_t finishedLen = sizeof(finished); + (void)HITLS_Connect(client->ssl); + ret = FRAME_TransportSendMsg(client->io, finished, finishedLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + finishedLen = readLen; + appLen=finishedLen; + if (memcpy_s(app, appLen, finished, finishedLen) != EOK) { + return HITLS_INTERNAL_EXCEPTION; + } + app[0] = 23; + if (memcpy_s(&data[offset], len - offset, app, appLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += appLen; + if (memcpy_s(&data[offset], len - offset, finished, finishedLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += finishedLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t GetDisorderServerFinish_AppData(FRAME_LinkObj *server, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + int32_t ret; + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t ccs[TEMP_DATA_LEN] = {0}; + uint32_t ccsLen = sizeof(ccs); + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, ccs, ccsLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + ccsLen = readLen; + uint8_t finished[TEMP_DATA_LEN] = {0}; + uint32_t finishedLen = sizeof(finished); + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, finished, finishedLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + finishedLen = readLen; + uint8_t app[TEMP_DATA_LEN] = {0}; + uint32_t appLen = sizeof(finished); + ret = AppWrite(server->ssl); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = FRAME_TransportSendMsg(server->io, app, appLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + appLen = readLen; + if (memcpy_s(&data[offset], len - offset, ccs, ccsLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += ccsLen; + if (memcpy_s(&data[offset], len - offset, app, appLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += appLen; + if (memcpy_s(&data[offset], len - offset, finished, finishedLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += finishedLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark1(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + testInfo->config = HITLS_CFG_NewDTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + HITLS_CFG_SetClientVerifySupport(testInfo->config, testInfo->isSupportClientVerify); + HITLS_CFG_SetNoClientCertSupport(testInfo->config, false); + HITLS_CFG_SetExtenedMasterSecretSupport(testInfo->config, true); + return StatusPark(testInfo); +} + +static int32_t GetRepeatsApp(FRAME_LinkObj *obj, uint8_t *data, uint32_t *usedLen) +{ + int32_t ret; + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t app[TEMP_DATA_LEN] = {0}; + uint32_t appLen = sizeof(app); + ret = AppWrite(obj->ssl); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = FRAME_TransportSendMsg(obj->io, app, appLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + appLen = readLen; + if (memcpy_s(&data[offset], TEMP_DATA_LEN, app, appLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += appLen; + if (memcpy_s(&data[offset], TEMP_DATA_LEN - offset, app, appLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += appLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t GetDisorderApp(FRAME_LinkObj *obj, uint8_t *data, uint32_t *usedLen) +{ + int32_t ret; + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t app1[TEMP_DATA_LEN] = {0}; + uint32_t app1Len = sizeof(app1); + ret = AppWrite(obj->ssl); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = FRAME_TransportSendMsg(obj->io, app1, app1Len, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + app1Len = readLen; + uint8_t app2[TEMP_DATA_LEN] = {0}; + uint32_t app2Len = sizeof(app2); + ret = AppWrite(obj->ssl); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = FRAME_TransportSendMsg(obj->io, app2, app2Len, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + app2Len = readLen; + if (memcpy_s(&data[offset], TEMP_DATA_LEN, app2, app2Len) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += app2Len; + if (memcpy_s(&data[offset], TEMP_DATA_LEN - offset, app1, app1Len) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += app1Len; + *usedLen = offset; + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.c b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.c new file mode 100644 index 00000000..bf962f5f --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.c @@ -0,0 +1,2687 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_sdv_frame_dtls12_consistency */ +/* END_HEADER */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001 +* @spec - +* @titleThe client and server receive the client Hello message after the connection establishment is complete. +* @precon nan +* @brief +* 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. A DTLS over SCTP connection is established between the client and server. Expected result 2. +* 3. Construct a Client Hello message and send it to the client. Check the client status. Expected result 3. +* 4. Construct a Client Hello message and send it to the server. Check the server status. Expected result 4. +* @expect +* 1. The initialization is successful. +* 2. The connection is set up successfully. +* 3. The client status is CM_STATE_TRANSPORTING. +* 4. The server is in the CM_STATE_TRANSPORTING state. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = HS_STATE_BUTT; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + uint8_t data[1024] = {0}; + uint32_t dataSize = 0; + ASSERT_TRUE(testInfo.server->ssl != NULL); + HITLS_Read(testInfo.server->ssl, data, sizeof(data), &dataSize); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(dataSize == 0); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + dataSize = 0 ; + ASSERT_TRUE(testInfo.client->ssl != NULL); + HITLS_Read(testInfo.client->ssl, data, sizeof(data), &dataSize); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(dataSize == 0); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC001 +* @spec - +* @title Check whether the seq number of the record layer complies with the RFC specifications during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a connection establishment request. When the client sends a CLIENT_HELLO message, the client checks the sequence number at the Reocrd layer. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The sequence number is 0. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == recvLen); + ASSERT_TRUE(frameMsg.body.hsMsg.sequence.data == 0); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC002 +* @spec - +* @title Check whether the sequence number of the record layer during the handshake complies with the RFC specification. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The server continuously establishes a connection. After receiving the client Hello message, the server sends a Server Hello message and checks the sequence number at the Record layer. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The sequence number is 0. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == recvLen); + ASSERT_TRUE(frameMsg.body.hsMsg.sequence.data == 0); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC003 +* @spec - +* @title Check whether the sequence number at the record layer complies with the RFC specification during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client sends a FINISH message during continuous connection establishment, check whether the sequence number in the record header is. Expected result 2. +3. When the server sends a FINISH message during continuous connection establishment, check the sequence number in the message. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The sequence number is 0. +3. The sequence number is 0. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = TRY_RECV_FINISH; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == PARSEMSGHEADER_LEN); + ASSERT_TRUE(frameMsg.body.hsMsg.sequence.data == 0); + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + FrameUioUserData *ioUserData_1 = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf_1 = ioUserData_1->recMsg.msg; + uint32_t recvLen_1 = ioUserData_1->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen_1 = 0; + FRAME_Msg frameMsg_1 = {0}; + FRAME_Type frameType_1 = {0}; + frameType_1.versionType = HITLS_VERSION_DTLS12; + frameType_1.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType_1, recvBuf_1, recvLen_1, &frameMsg_1, &parseLen_1) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen_1 == PARSEMSGHEADER_LEN); + ASSERT_TRUE(frameMsg_1.body.hsMsg.sequence.data == 0); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_CleanMsg(&frameType_1, &frameMsg_1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC001 +* @spec - +* @titleThe client sends a Client Certificate message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS connection creation request. When the client needs to send a Client Certificate message, the two fields are modified as follows: +Certificates Length is 2 ^ 14 + 1 +Certificates are changed to 2 ^ 14 + 1 byte buffer. +After the modification is complete, send the modification to the server. Expected result 2. +3. When the server receives the Client Certificate message, check the value returned by the HITLS_Accept interface. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.certificate.certItem->cert.data); + frameMsg.body.hsMsg.body.certificate.certItem->cert.data = certDataTemp; + frameMsg.body.hsMsg.body.certificate.certItem->cert.size = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.data = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC002 +* @spec - +* @title The server sends a Server Certificate message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS connection creation request. When the server needs to send a Server Certificate message, the server modifies the following two fields: +Certificates Length is 2 ^ 14 + 1 +Certificates are changed to 2 ^ 14 + 1 byte buffer. +After the modification is complete, send the modification to the server. Expected result 2. +3. When the client receives the Server Certificate message, check the value returned by the HITLS_Connect interface. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +3. The return value of the HITLS_Connect interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.certificate.certItem->cert.data); + frameMsg.body.hsMsg.body.certificate.certItem->cert.data = certDataTemp; + frameMsg.body.hsMsg.body.certificate.certItem->cert.size = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.data = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC003 +* @spec - +* @titleThe client sends a Change Cipher Spec message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS connection establishment request and sends a Change Cipher Spec message, the client modifies one field as follows: +Length is 2 ^ 14 + 1. After the modification is complete, send the modification to the server. Expected result 2. +3. When the server receives the Change Cipher Spec message, check the value returned by the HITLS_Accept interface. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.ccsMsg.extra.data); + frameMsg.body.ccsMsg.extra.data = certDataTemp; + frameMsg.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg.body.ccsMsg.extra.state = ASSIGNED_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE_VERIFY); + bool isCcsRecv = testInfo.server->ssl->method.isRecvCCS(testInfo.server->ssl); + ASSERT_TRUE(isCcsRecv == false); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC001 +* @spec - +* @title The server receives a Client Hello message with a length of zero. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request, constructs a Client Hello message with zero length, and sends the message to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT message. The level is ALERT_ LEVEL_FATAL, and the description is ALERT_DECODE_ERROR. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->extensionState = MISSING_FIELD; + clientMsg->version.state = MISSING_FIELD; + clientMsg->randomValue.state = MISSING_FIELD; + clientMsg->sessionIdSize.state = MISSING_FIELD; + clientMsg->sessionId.state = MISSING_FIELD; + clientMsg->cookiedLen.state = MISSING_FIELD; + clientMsg->cookie.state = MISSING_FIELD; + clientMsg->cipherSuitesSize.state = MISSING_FIELD; + clientMsg->cipherSuites.state = MISSING_FIELD; + clientMsg->compressionMethodsLen.state = MISSING_FIELD; + clientMsg->compressionMethods.state = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC002 +* @spec - +* @titleThe client receives a Server Hello message with a length of zero. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request. After sending a Client Hello message, the client constructs a zero-length Server Hello message and sends it to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message with the level of ALERT_Level_FATAL and description of ALERT_DECODE_ERROR. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->version.state = MISSING_FIELD; + serverMsg->randomValue.state = MISSING_FIELD; + serverMsg->sessionIdSize.state = MISSING_FIELD; + serverMsg->sessionId.state = MISSING_FIELD; + serverMsg->cipherSuite.state = MISSING_FIELD; + serverMsg->compressionMethod.state = MISSING_FIELD; + serverMsg->extensionLen.state = MISSING_FIELD; + serverMsg->pointFormats.exState = MISSING_FIELD; + serverMsg->extendedMasterSecret.exState = MISSING_FIELD; + serverMsg->secRenego.exState = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC003 +* @spec - +* @titleThe client receives a Certificate message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request. After receiving the Server Hello message, the client constructs a zero-length Certificate message and sends it to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT message. The level is ALERT_ LEVEL_FATAL and the description is ALERT_DECODE_ERROR. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_CertificateMsg *certifiMsg = &frameMsg.body.hsMsg.body.certificate; + certifiMsg->certsLen.state = MISSING_FIELD; + certifiMsg->certItem->state = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC004 +* @spec - +* @titleThe client receives a Server Key Exchange message whose length is zero. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request. After receiving the Certificate message, the client constructs a Server Key Exchange message with zero length and sends the message to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message with the level of ALERT_Level_FATAL and description of ALERT_DECODE_ERROR. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerKeyExchangeMsg *serverKeyExMsg = &frameMsg.body.hsMsg.body.serverKeyExchange; + serverKeyExMsg->keyEx.ecdh.curveType.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.namedcurve.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.pubKeySize.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.pubKey.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.signAlgorithm.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.signSize.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.signData.state = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC005 +* @spec - +* @titleThe server receives a Client Key Exchange message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request. After the server sends a Server Hello Done message, the server constructs a Client Key Exchange message with zero length and sends the message to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. The level is ALERT_Level_FATAL and the description is ALERT_DECODE_ERROR. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC005(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientKeyExchangeMsg *clientKeyExMsg = &frameMsg.body.hsMsg.body.clientKeyExchange; + clientKeyExMsg->pubKey.state = MISSING_FIELD; + clientKeyExMsg->pubKeySize.state = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC006 +* @spec - +* @title The server receives a Change Cipher Spec message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request. After receiving the Client Key Exchange message, the server constructs a Change Cipher Spec message with zero length and sends it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server receives the message, which is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC006(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + frameType1.versionType = HITLS_VERSION_DTLS12; + frameType1.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType1, &frameMsg1) == HITLS_SUCCESS); + FRAME_CcsMsg *CcsMidMsg = &frameMsg1.body.ccsMsg; + CcsMidMsg->ccsType.state = MISSING_FIELD; + CcsMidMsg->extra.state = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType1, &frameMsg1, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData1->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + +exit: + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC007 +* @spec - +* @titleThe client receives a Change Cipher Spec message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS over SCTP connection request. After the client sends a Finish message, it constructs a Change Cipher Spec message with zero length and sends the message to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client receives the message, which is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC007(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_FINISH; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + frameType1.versionType = HITLS_VERSION_DTLS12; + frameType1.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType1, &frameMsg1) == HITLS_SUCCESS); + FRAME_CcsMsg *CcsMidMsg = &frameMsg1.body.ccsMsg; + CcsMidMsg->ccsType.state = MISSING_FIELD; + CcsMidMsg->extra.state = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType1, &frameMsg1, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData1->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + +exit: + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC001 +* @spec - +* @titleThe server receives a Client Hello message in which the compression field is set to 1. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the server expects to receive the Client Hello packet, the server constructs the Client Hello packet with the compressed field value being 1. Check the behavior of the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_ILLEGAL_PARAMETER. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + *(clientMsg->compressionMethods.data) = 1; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.handshakeType = SERVER_HELLO; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_ILLEGAL_PARAMETER); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC002 +* @spec - +* @titleThe client receives a Server Hello message in which the compressed field value is 1. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. After sending the Client Hello packet, the client constructs a Server Hello packet with the compressed field value being 1. Check the behavior of the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_ILLEGAL_PARAMETER. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->compressionMethod.data = 1; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_COMPRESSION_METHOD_ERR); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_ILLEGAL_PARAMETER); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC001 +* @spec - +* @title Check whether the cipher suite selected on the server complies with the RFC. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS over SCTP connection application, the server modifies the algorithm suite field in the Client Hello packet when the server expects to receive the Client Hello packet, +Change the value to 0x00b6, 0x00b7, 0xffff, or 0xc030, and send the modification to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the Server Hello message, and the algorithm suite field is 0xc030. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + uint16_t suite[] = {0x00B6, 0x00B7, ILLEGAL_VALUE, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}; + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(FRAME_ModifyMsgArray16(suite, sizeof(suite)/sizeof(uint16_t), + &(clientMsg->cipherSuites), &(clientMsg->cipherSuitesSize)) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.handshakeType = SERVER_HELLO; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.cipherSuite.data, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC002 +* @spec - +* @titleHow to handle unexpected cipher suites received by the client? +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS over SCTP connection request, the client constructs a Server Hello packet after sending the Client Hello message, +Change the value of the cipher suite field to 0xff and send the modified value to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_ILLEGAL_PARAMETER. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->cipherSuite.data = ILLEGAL_VALUE; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_ILLEGAL_PARAMETER); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC001 +* @spec - +* @title The server receives a Client Hello packet without the Signature Algorithms field. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS over SCTP connection request and the server expects to receive the Client Hello packet, +Delete the signature field from the Client Hello packet and send the packet to the server after the packet is modified. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the Server Hello message. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.body.hsMsg.type.data == CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.signatureAlgorithms.exState = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.recType.data, REC_TYPE_HANDSHAKE); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC002 +* @spec - +* @titleThe client receives the Server Hello packet carrying the Signature Algorithms field. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS over SCTP connection application, the client constructs a Server Hello packet after sending the Client Hello message, +Add the Signature Algorithms field and set its value to 0x0403. Modify the field and send it to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_UNSUPPORTED_EXTENSION. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->secRenego.exState = INITIAL_FIELD; + ASSERT_TRUE(FRAME_ModifyMsgInteger(HS_EX_TYPE_SIGNATURE_ALGORITHMS, + &(serverMsg->secRenego.exType)) == HITLS_SUCCESS); + serverMsg->secRenego.exLen.state = INITIAL_FIELD; + uint8_t Signature[] = {SIGNATURE_ALGORITHMS}; + ASSERT_TRUE(FRAME_ModifyMsgArray8(Signature, sizeof(Signature), + &(serverMsg->secRenego.exData), &(serverMsg->secRenego.exDataLen)) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_UNSUPPORTED_EXTENSION); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNSUPPORTED_EXTENSION); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC003 +* @spec - +* @titleThe server receives a client Hello message with abnormal signature hash fields. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a connection request, constructs an abnormal Client Hello packet, that is, the signature hash field is not in pairs, and sends the packet to the server. +* @expect 1. The initialization is successful. +* 2. After the server receives the Client Hello message, the HiTLS_ACCEPT interface returns a failure message and the server sends an ALERT message. The ALERT level is ALERT_ LEVEL_FATAL and the description is ALERT_DECODE_ERROR. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->signatureAlgorithms.exDataLen.data = HASH_EXDATA_LEN_ERROR ; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.handshakeType = SERVER_HELLO; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC004 +* @spec - +* @title The server receives the Client Hello packet carrying the Signature Algorithms field. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS over SCTP connection request, after the client sends the Client Hello message, +Modify the signature algorithm field by adding an invalid field value and observe the client behavior. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_HANDSHAKE_FAILURE. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + uint16_t Signature[] = {ILLEGAL_VALUE}; + ASSERT_TRUE(FRAME_ModifyMsgArray16(Signature, sizeof(Signature)/sizeof(uint16_t), + &(clientMsg->signatureAlgorithms.exData), &(clientMsg->signatureAlgorithms.exDataLen)) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_HANDSHAKE_FAILURE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC005 +* @spec - +* @titleThe client receives the Server Hello packet carrying the Signature Algorithms field. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client initiates a DTLS over SCTP connection application, the client constructs a Server Hello packet after sending the Client Hello message, +Modify the signature algorithm field by adding an invalid field value and observe the client behavior. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_UNSUPPORTED_EXTENSION. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC005(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->secRenego.exState = INITIAL_FIELD; + ASSERT_TRUE(FRAME_ModifyMsgInteger(HS_EX_TYPE_SIGNATURE_ALGORITHMS, + &(serverMsg->secRenego.exType)) == HITLS_SUCCESS); + serverMsg->secRenego.exLen.state = INITIAL_FIELD; + uint8_t Signature[] = {ILLEGAL_VALUE}; + ASSERT_TRUE(FRAME_ModifyMsgArray8(Signature, sizeof(Signature), + &(serverMsg->secRenego.exData), &(serverMsg->secRenego.exDataLen)) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_UNSUPPORTED_EXTENSION); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNSUPPORTED_EXTENSION); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC007 +* @spec - +* @titleThe client sends a Client Hello message in which the signature field is removed. +* @precon nan +* @brief 1. Use the default initialization mode on the client and server. Expected result 1. +* 2. The client initiates a connection establishment request, deletes the signature field in the client Hello message, and sends the message to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server continues to establish a connection. The connection is successfully established. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC007(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->signatureAlgorithms.exState = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.handshakeType = SERVER_HELLO; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_HANDSHAKE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC003 +* @spec - +* @title The server receives an unexpected Client Certificate message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a DTLS connection application. After sending the Server Hello Done message, the server constructs a Client Certificate message and sends it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT message. The ALERT level is ALERT_ LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC004 +* @spec - +* @title In dual-end verification, the server receives out-of-order Certificate Verify messages. +* @precon nan +* @brief 1. Retain the default configuration on the client and server, and enable peer verification on the server. Expected result 1. +* 2. After sending the server hello done message, the server constructs a Certificate Verify message and sends it to the server. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT message. The ALERT level is ALERT_LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE_VERIFY; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNMATCHED_SEQUENCE); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_VERSION_TC001 +* @spec - +* @titleThe server receives the client hello message of DTLS1.0. +* @precon nan +* @brief 1. Retain the default configuration on the client and server, and enable peer verification on the server. Expected result 1. +* 2. When the server is in the TRY_RECV_CLIENT_HELLO state, change the negotiated version number field in the client hello message to DTLS1.0. Then, check the server behavior. +* @expect 1. The initialization is successful. +* 2. The server sends a FATAL ALERT, and the description of the ALERT is ALERT_PROTOCOL_VERSION. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_VERSION_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->version.data = HITLS_VERSION_DTLS10; + clientMsg->version.state = ASSIGNED_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.handshakeType = SERVER_HELLO; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_PROTOCOL_VERSION); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC001 +* @spec - +* @titleThe client receives a Hello Request message during startup. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and enable peer verification on the server. Expected result 1. +* 2. When the client starts, the client receives a Hello Request message. Expected result 2. +3. Continue to complete connection establishment and send and receive messages. (Expected result 3) +* @expect 1. The initialization is successful. +* 2. The client can process the packet normally. +3. The message is sent and received successfully. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TLS_IDLE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + FRAME_Init(); + testInfo.config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(testInfo.config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_SCTP); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_SCTP); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.server->ssl, 0) == HITLS_SUCCESS); + testInfo.server->ssl->hsCtx->nextSendSeq++; + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_TRANSPORTING); + uint8_t writeData[] = {"abcd1234"}; + uint32_t writeLen = strlen("abcd1234"); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + uint32_t readLen = MAX_RECORD_LENTH; + ASSERT_EQ(HITLS_Write(testInfo.server->ssl, writeData, writeLen), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readData, MAX_RECORD_LENTH, &readLen), HITLS_SUCCESS); + ASSERT_EQ(readLen, writeLen); + ASSERT_EQ(memcmp(writeData, readData, readLen), 0); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC002 +* @spec - +* @titleThe client receives a Hello Request message after sending a Client Hello message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 11. +* 2. After the client sends a Client Hello message, the client receives a Hello Request message. Expected result 2. +3. Continue to establish a connection and send and receive messages. (Expected result 3) +* @expect 1. The initialization is successful. +* 2. The client can process the packet normally. +3. The message is sent and received successfully. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + CONN_Deinit(testInfo.client->ssl); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.server->ssl, 0) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_HANDSHAKING); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_SERVER_HELLO); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC003 +* @spec - +* @titleThe server receives a Hello Request message after sending a Server Hello Done message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 11. +* 2. After sending a Server Hello Done message, the server receives a Hello Request message. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message with the description of ALERT_UNEXPECTED_MESSAGE. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_SEND_SERVER_HELLO_DONE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.client->ssl, 1) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC004 +* @spec - +* @titleThe client receives a Hello Request message after sending a FINISH message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 11. +* 2. After the client sends a FINISH message, the client receives a Hello Request message. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client can process the packet normally. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_FINISH; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.server->ssl, 4) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_HANDSHAKING); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_NEW_SESSION_TICKET); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC005 +* @spec - +* @titleThe server receives a Hello Request message after sending a FINISH message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 11. +* 2. After the server sends a FINISH message, the server receives a Hello Request message. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server can process the packet normally. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC005(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_FINISH; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_SUCCESS); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.client->ssl, 1) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(testInfo.server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(testInfo.server); + ASSERT_EQ(serverTlsCtx->state, CM_STATE_ALERTED); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC006 +* @spec - +* @titleThe client receives the Hello Request message after the connection establishment is complete. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 11. +* 2. After the connection is established on the client, the client receives a Hello Request message. Expected result 2. +3. The server writes a message and the client receives the message. (Expected result 3) +* @expect 1. The initialization is successful. +* 2. The server can process the packet normally. +3. The client receives the message correctly. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC006(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = HS_STATE_BUTT; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.server->ssl, 1) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + uint8_t writeData[] = {"abcd1234"}; + uint32_t writeLen = strlen("abcd1234"); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + readLen = MAX_RECORD_LENTH; + ASSERT_EQ(HITLS_Write(testInfo.server->ssl, writeData, writeLen), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readData, MAX_RECORD_LENTH, &readLen), HITLS_SUCCESS); + ASSERT_EQ(readLen, writeLen); + ASSERT_EQ(memcmp(writeData, readData, readLen), 0); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC007 +* @spec - +* @titleThe server receives a Hello Request message during startup. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the server starts, the Hello Request message is received. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT. The description is ALERT_UNEXPECTED_MESSAGE. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC007(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TLS_IDLE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + HandshakeTestInfo testInfo1 = {0}; + testInfo1.state = TLS_IDLE; + FRAME_Init(); + testInfo.config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(testInfo.config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_SCTP); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_SCTP); + ASSERT_TRUE(testInfo.server != NULL); + testInfo1.server = FRAME_CreateLink(testInfo.config, BSL_UIO_SCTP); + ASSERT_TRUE(testInfo1.server != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo1.server) == HITLS_SUCCESS); + ASSERT_TRUE(SendHelloReqWithIndex(testInfo.client->ssl, 0) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_ALERTED); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_CFG_FreeConfig(testInfo1.config); + FRAME_FreeLink(testInfo1.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6083_RETRANSMISSION_TC001 +* @spec - +* @title Check that DTLS over SCTP does not support retransmission. +* @precon nan +* @brief 1. Use the default initialization mode on the client and server. Expected result 1. +* 2. The client initiates a DTLS connection request. After receiving the client hello packet, the server does not reply with the server hello packet. The delay is 3 seconds. Check the sending buffer of the client. Expected result 2. +* @expect 1: The initialization is successful. +* 2: The sending buffer of the client is empty. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6083_RETRANSMISSION_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + CONN_Deinit(testInfo.client->ssl); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + + sleep(3); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen == 0); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC001 +* @spec - +* @titleThe client receives a FINISH message and the CCS message is out of order. +* @precon nan +* @brief 1. Initialize the client and server based on the default configuration. Expected result 1. +* 2. The client initiates a connection request and constructs the scenario where the FINISH message and CCS message are out of order. That is, the client processes the FINISH message and then processes the CCS message. After the processing, the client continues to establish a connection. Expected result 2 is displayed. +* @expect 1: The initialization is successful. +* 2: The client waits to receive the FINISH message. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = false; + testInfo.state = TRY_SEND_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderServerFinished(testInfo.server, data, len, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, data, len) == HITLS_SUCCESS); + (void)HITLS_Connect(testInfo.client->ssl); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state == TRY_RECV_FINISH); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC002 +* @spec - +* @titleThe server receives a FINISH message and the CCS message is out of order. +* @precon nan +* @brief 1. Initialize the client and server based on the default configuration. Expected result 1. +* 2. The client initiates a connection request and constructs the scenario where the FINISH message and CCS message are out of order. That is, the server processes the FINISH message and then processes the CCS message. After the processing, the server continues to establish a connection. Expected result 2 is displayed. +* @expect 1: The initialization is successful. +* 2: The server is waiting to receive the FINISH message. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC002(void) +{ + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = true; + testInfo.state = TRY_SEND_CLIENT_KEY_EXCHANGE; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderClientFinished(testInfo.client, data, len, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, data, len) == HITLS_SUCCESS); + (void)HITLS_Accept(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_FINISH); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC003 +* @spec - +* @titleThe client receives a FINISH message and the APP message is out of order. +* @precon nan +* @brief 1. Initialize the client and server using the default configuration. Expected result 1. +* 2. The client initiates a connection request and constructs the scenario where the FINISH message and APP message are out of order. That is, the client processes the APP message first, processes the FINISH message, and then continues to establish a connection. Expected result 2. +* @expect 1: Initialization succeeded. +* 2: The connection between the client and server is successfully established. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = false; + testInfo.state = TRY_SEND_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderServerFinish_AppData(testInfo.server, data, len, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, data, len) == HITLS_SUCCESS); + (void)HITLS_Connect(testInfo.client->ssl); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(HITLS_Read(testInfo.client->ssl, data, MAX_RECORD_LENTH, &len) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC004 +* @spec - +* @titleThe server receives a FINISH message and the APP message is out of order. +* @precon nan +* @brief 1. Initialize the client and server using the default configuration. Expected result 1. +* 2. The client initiates a connection request and constructs the scenario where the FINISH message and APP message are out of order. That is, the server processes the APP message first, processes the FINISH message, and then continues to establish a connection. Expected result 2 is displayed. +* 3. After the connection is established, the client sends data to the server, and the server receives the data. (Expected result 3) +* @expect 1: Initialization succeeded. +* 2: The connection between the client and server is successfully established. +* 3: Data received by the server is consistent with data sent by the client. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = true; + testInfo.state = TRY_SEND_FINISH; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderClientFinished_AppData(testInfo.client, data, len, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, data, len) == HITLS_SUCCESS); + (void)HITLS_Accept(testInfo.server->ssl); + ASSERT_EQ(testInfo.server->ssl->state, CM_STATE_HANDSHAKING); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + (void)HITLS_Connect(testInfo.client->ssl); + (void)HITLS_Accept(testInfo.server->ssl); + ASSERT_EQ(testInfo.server->ssl->state, CM_STATE_HANDSHAKING); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + (void)HITLS_Connect(testInfo.client->ssl); + ASSERT_TRUE(HITLS_Read(testInfo.server->ssl, data, MAX_RECORD_LENTH, &len) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + (void)HITLS_Connect(testInfo.client->ssl); + uint8_t writeData[] = {"abcd1234"}; + uint32_t writeLen = strlen("abcd1234"); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + uint32_t readLen = MAX_RECORD_LENTH; + ASSERT_EQ(HITLS_Write(testInfo.server->ssl, writeData, writeLen), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readData, MAX_RECORD_LENTH, &readLen), HITLS_SUCCESS); + ASSERT_EQ(readLen, writeLen); + ASSERT_EQ(memcmp(writeData, readData, readLen), 0); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC001 +* @spec - +* @titleThe server receives out-of-order APP messages. +* @precon nan +* @brief 1. Initialize the configuration on the client and server. Expected result 1. +* 2. Initiate a connection application by using DTLS. Expected result 2. +* 3. Construct an app message whose SN is 2 and send it to the server. When the server invokes HiTLS_Read, expected result 3. +* 4. Construct an app message whose SN is 1 and send it to the server. When the server invokes HiTLS_Read, expected result 4. +* @expect 1: Initializing the configuration succeeded. +* 2: The DTLS connection is successfully created. +* 3: The interface returns a success response. +* 4: The interface returns a success response. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = true; + testInfo.state = HS_STATE_BUTT; + ASSERT_EQ(DefaultCfgStatusPark1(&testInfo), HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderApp(testInfo.client, data, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, data, len) == HITLS_SUCCESS); + uint8_t app1Data[MAX_RECORD_LENTH] = {0}; + uint32_t app1Len = MAX_RECORD_LENTH; + ASSERT_TRUE(HITLS_Read(testInfo.server->ssl, app1Data, MAX_RECORD_LENTH, &app1Len) == HITLS_SUCCESS); + uint8_t app2Data[MAX_RECORD_LENTH] = {0}; + uint32_t app2Len = MAX_RECORD_LENTH; + ASSERT_TRUE(HITLS_Read(testInfo.server->ssl, app2Data, MAX_RECORD_LENTH, &app2Len) == HITLS_SUCCESS); + ASSERT_EQ(app1Len, app2Len); + ASSERT_EQ(memcmp(app1Data, app2Data, app2Len), 0); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC002 +* @spec - +* @titleThe client receives out-of-order APP messages. +* @precon nan +* @brief 1. Initialize the configuration on the client and server. Expected result 1. +* 2. Initiate a connection request using DTLS. Expected result 2. +* 3. Construct an app message whose sequence number is 2 and send it to the client. When the client invokes HiTLS_Read, expected result 3. +* 4. Construct an app message whose sequence number is 1 and send it to the client. When the client invokes HiTLS_Read, expected result 4. +* @expect 1: Initializing the configuration succeeded. +* 2: The DTLS connection is successfully created. +* 3: The interface returns a success response. +* 4: The interface returns a success response. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = false; + testInfo.state = HS_STATE_BUTT; + ASSERT_EQ(DefaultCfgStatusPark1(&testInfo), HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderApp(testInfo.server, data, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, data, len) == HITLS_SUCCESS); + uint8_t app1Data[MAX_RECORD_LENTH] = {0}; + uint32_t app1Len = MAX_RECORD_LENTH; + ASSERT_TRUE(HITLS_Read(testInfo.client->ssl, app1Data, MAX_RECORD_LENTH, &app1Len) == HITLS_SUCCESS); + uint8_t app2Data[MAX_RECORD_LENTH] = {0}; + uint32_t app2Len = MAX_RECORD_LENTH; + ASSERT_TRUE(HITLS_Read(testInfo.client->ssl, app2Data, MAX_RECORD_LENTH, &app2Len) == HITLS_SUCCESS); + ASSERT_EQ(app1Len, app2Len); + ASSERT_EQ(memcmp(app1Data, app2Data, app1Len), 0); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC001 +* @spec - +* @title The server receives duplicate APP messages. +* @precon nan +* @brief 1. Initialize the configuration on the client and server. Expected result 1. +* 2. Initiate a connection application by using DTLS. Expected result 2. +* 3. Construct an app message whose SN is 1 and send it to the server. When the server invokes HiTLS_Read, expected result 3. +* 4. Construct the app message whose SN is 1 and send it to the server. When the server invokes HiTLS_Read, expected result 4. +* 5. The server constructs data and sends it to the client. When the client invokes HiTLS_Read, expected result 5. +* @expect 1: Initializing the configuration succeeded. +* 2: The DTLS connection is successfully created. +* 3: The interface returns a success response. +* 4: The interface returns a success response. +* 5: The interface returns a success response. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = true; + testInfo.state = HS_STATE_BUTT; + ASSERT_EQ(DefaultCfgStatusPark1(&testInfo), HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetRepeatsApp(testInfo.client, data, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Read(testInfo.server->ssl, data, MAX_RECORD_LENTH, &len) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.server->ssl, data, MAX_RECORD_LENTH, &len), HITLS_SUCCESS); + uint8_t writeData[] = {"abcd1234"}; + uint32_t writeLen = strlen("abcd1234"); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + uint32_t readLen = MAX_RECORD_LENTH; + uint8_t tmpData[MAX_RECORD_LENTH]; + uint32_t tmpLen; + ASSERT_TRUE(HITLS_Write(testInfo.server->ssl, writeData, writeLen) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportSendMsg(testInfo.server->io, tmpData, MAX_RECORD_LENTH, &tmpLen) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, tmpData, tmpLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readData, MAX_RECORD_LENTH, &readLen), HITLS_SUCCESS); + ASSERT_EQ(readLen, writeLen); + ASSERT_EQ(memcmp(writeData, readData, readLen), 0); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC002 +* @spec - +* @titleThe client receives duplicate APP messages. +* @precon nan +* @brief 1. Initialize the configuration on the client and server. Expected result 1. +* 2. Initiate a connection application by using DTLS. Expected result 2. +* 3. Construct an app message whose sequence number is 1 and send the message to the client. When the client invokes HiTLS_Read, expected result 3. +* 4. Construct an app message with the sequence number being 1 and send it to the client. When the client invokes HiTLS_Read, expected result 4. +* 5. The server constructs data and sends it to the client. When the client invokes HiTLS_Read, expected result 5. +* @expect 1: Initializing the configuration succeeded. +* 2: The DTLS connection is successfully created. +* 3: The interface returns a success response. +* 4: The interface returns a success response. +* 5: The interface returns a success response. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = false; + testInfo.state = HS_STATE_BUTT; + ASSERT_EQ(DefaultCfgStatusPark1(&testInfo), HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetRepeatsApp(testInfo.server, data, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Read(testInfo.client->ssl, data, MAX_RECORD_LENTH, &len) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, data, MAX_RECORD_LENTH, &len), HITLS_SUCCESS); + uint8_t writeData[] = {"abcd1234"}; + uint32_t writeLen = strlen("abcd1234"); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + uint32_t readLen = MAX_RECORD_LENTH; + uint8_t tmpData[MAX_RECORD_LENTH]; + uint32_t tmpLen; + ASSERT_TRUE(HITLS_Write(testInfo.server->ssl, writeData, writeLen) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportSendMsg(testInfo.server->io, tmpData, MAX_RECORD_LENTH, &tmpLen) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, tmpData, tmpLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readData, MAX_RECORD_LENTH, &readLen), HITLS_SUCCESS); + ASSERT_EQ(readLen, writeLen); + ASSERT_EQ(memcmp(writeData, readData, readLen), 0); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_CLIENT_HELLO_TC001 +* @spec - +* @title The server receives a Client Hello packet after the connection is established. +* @precon nan +* @brief 1. Initialize the client and server based on the default configuration. Expected result 1. +* 2. The client initiates a connection request. Expected result 2. +* 3. Construct a Client Hello packet and send it to the server. The server invokes HiTLS_Read to receive the packet. Expected result 3. +* 4. The client invokes HiTLS_Write to send data to the server, and the server invokes HiTLS_Read to read data. (Expected result 4) +* @expect 1: Initialization succeeded. +* 2: The connection between the client and server is successfully established. +* 3: The HiTLS_Read returns an error code, indicating that the receiving buffer is empty. +* 4: The data read by the server is consistent with the data sent by the client. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_CLIENT_HELLO_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.isClient = true; + testInfo.state = HS_STATE_BUTT; + ASSERT_EQ(DefaultCfgStatusPark1(&testInfo), HITLS_SUCCESS); + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ASSERT_TRUE(REC_Write(testInfo.client->ssl, REC_TYPE_HANDSHAKE, + &sendBuf[REC_DTLS_RECORD_HEADER_LEN], sendLen - REC_DTLS_RECORD_HEADER_LEN) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Read(testInfo.server->ssl, data, MAX_RECORD_LENTH, &len), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + uint8_t writeData[] = {"abcd1234"}; + uint32_t writeLen = strlen("abcd1234"); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + uint32_t readLen = MAX_RECORD_LENTH; + uint8_t tmpData[MAX_RECORD_LENTH]; + uint32_t tmpLen; + ASSERT_EQ(HITLS_Write(testInfo.client->ssl, writeData, writeLen), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportSendMsg(testInfo.client->io, tmpData, MAX_RECORD_LENTH, &tmpLen) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, tmpData, tmpLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(testInfo.server->ssl, readData, MAX_RECORD_LENTH, &readLen), HITLS_SUCCESS); + ASSERT_EQ(readLen, writeLen); + ASSERT_EQ(memcmp(writeData, readData, readLen), 0); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC8422_ECPOINT_TC001 +* @spec - +* @titleThe client receives an abnormal dot format field. +* @precon nan +* @brief 1. The client and server use the default initialization. Expected result 1. +* 2. The client initiates a connection request. When the client wants to read the Server Hello message, +* Modify the Elliptic curves point formats field, change the group supported by the field to 0x01, and send the field to the client. Expected result 2. +* @expect 1. Initialization succeeded. +* 2. The client sends a FATAL ALERT with the description of ALERT_ELLEGAL_PARAMETER. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC8422_ECPOINT_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + uint8_t Gdata[] = { 0x01 }; + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->pointFormats.exState = INITIAL_FIELD; + ASSERT_TRUE(FRAME_ModifyMsgInteger(HS_EX_TYPE_POINT_FORMATS, &(serverMsg->pointFormats.exType)) == HITLS_SUCCESS); + serverMsg->pointFormats.exLen.state = INITIAL_FIELD; + ASSERT_TRUE(FRAME_ModifyMsgArray8(Gdata, sizeof(Gdata)/sizeof(uint8_t), + &(serverMsg->pointFormats.exData), &(serverMsg->pointFormats.exDataLen)) == HITLS_SUCCESS); + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT); + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_ILLEGAL_PARAMETER); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC8422_EXTENSION_MISS_TC001 +* @spec - +* @title The server receives a Client Hello packet that does not carry the group or dot format. +* @precon nan +* @brief 1. Configure the HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 cipher suite on the client and initialize the cipher suite on the server by default. Expected result 1. +* 2. When the client initiates a connection request and the server is about to read ClientHello, +* Delete the supported_groups and ec_point_formats fields from the packet. Expected result 2. +* @expect 1. Initialization succeeded. +* 2. The server sends a Server Hello packet with the HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 algorithm suite. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC8422_EXTENSION_MISS_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_DTLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->supportedGroups.exState = MISSING_FIELD; + clientMsg->pointFormats.exState = MISSING_FIELD; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + CONN_Deinit(testInfo.server->ssl); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_HANDSHAKE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_HANDSHAKE); + ASSERT_TRUE(frameMsg.body.hsMsg.type.data == SERVER_HELLO); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_EQ(serverMsg->cipherSuite.data, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* when receive alert between finish and ccs, dtls12 should cache it*/ +/* BEGIN_CASE */ +void UT_DTLS_RFC6347_RECV_ALERT_AFTER_CCS_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewDTLSConfig(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_SCTP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_SCTP); + client->needStopBeforeRecvCCS = true; + server->needStopBeforeRecvCCS = true; + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + + // client receive ccs, wait to receive finish + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + uint8_t alertdata[2] = {0x02, 0x0a}; + ASSERT_EQ(REC_Write(serverTlsCtx, REC_TYPE_ALERT, alertdata, sizeof(alertdata)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + // client cache the alert, wait to receive finish + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + // server send finish, handshake success + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + // client receive finish, handshake success + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + // client read cached alert + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_DTLS_CONSISTENCY_RFC6347_TC001 +* @spec - +* @title The client receives a Hello Request message which msg seq is not 0. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. After the client finished handshake, the client receives a Hello Request message. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client igore the message. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_DTLS_CONSISTENCY_RFC6347_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewDTLS12Config(); + tlsConfig->isSupportRenegotiation = true; + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_SCTP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + uint8_t buf[DTLS_HS_MSG_HEADER_SIZE] = {0u}; + buf[5] = 1; + size_t len = DTLS_HS_MSG_HEADER_SIZE; + REC_Write(serverTlsCtx, REC_TYPE_HANDSHAKE, buf, len); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + uint8_t readData[MAX_RECORD_LENTH] = {0}; + uint32_t readLen = MAX_RECORD_LENTH; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readData, MAX_RECORD_LENTH, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_RENEGOTIATION); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.data b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.data new file mode 100644 index 00000000..0b1dea3f --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_frame_dtls12_consistency.data @@ -0,0 +1,143 @@ +UT_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SEQ_NUMBER_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_TOOLONG_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC004 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC004: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC005 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC005: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC006 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC006: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC007 +UT_TLS_DTLS_CONSISTENCY_RFC5246_MSGLENGTH_ZERO_TC007: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_COMPRESSED_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_CIPHER_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC004 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC004: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC005 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC005: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC007 +UT_TLS_DTLS_CONSISTENCY_RFC5246_SIGNATURE_TC007: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC004 +UT_TLS_DTLS_CONSISTENCY_RFC5246_CERTIFICATE_TC004: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_VERSION_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_VERSION_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC004 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC004: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC005 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC005: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC006 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC006: + +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC007 +UT_TLS_DTLS_CONSISTENCY_RFC5246_HELLO_REQUEST_TC007: + +UT_TLS_DTLS_CONSISTENCY_RFC6083_RETRANSMISSION_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC6083_RETRANSMISSION_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC003 +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC003: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC004 +UT_TLS_DTLS_CONSISTENCY_RFC6347_FINISH_TC004: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC6347_DISORDER_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC002 +UT_TLS_DTLS_CONSISTENCY_RFC6347_APPDATA_TC002: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_CLIENT_HELLO_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC6347_CLIENT_HELLO_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC8422_ECPOINT_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC8422_ECPOINT_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC8422_EXTENSION_MISS_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC8422_EXTENSION_MISS_TC001: + +UT_DTLS_RFC6347_RECV_ALERT_AFTER_CCS_TC001 +UT_DTLS_RFC6347_RECV_ALERT_AFTER_CCS_TC001: + +UT_TLS_DTLS_CONSISTENCY_RFC6347_TC001 +UT_TLS_DTLS_CONSISTENCY_RFC6347_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_hlt_dtls12_consistency.c b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_hlt_dtls12_consistency.c new file mode 100644 index 00000000..d00418ae --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_hlt_dtls12_consistency.c @@ -0,0 +1,156 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_state_recv.h" +#include "conn_init.h" +#include "recv_process.h" +#include "stub_replace.h" +#include "stub_crypt.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "cert.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "hlt.h" +#include "sctp_channel.h" +#include "rec_wrapper.h" +#include "process.h" +#include "pthread.h" +#include "unistd.h" +#include "rec_header.h" +#include "bsl_log.h" +#include "cert_callback.h" +/* END_HEADER */ + +#define BUF_SIZE_DTO_TEST 18432 + +void Hello(void *ssl) +{ + const char *writeBuf = "Hello world"; + ASSERT_TRUE(HLT_TlsWrite(ssl, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); +exit: + return; +} + +/* +* @ +* @test SDV_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001 +* @Specifications- +* @Title1. Construct a scenario where renegotiation messages and application messages are sent at the same time. It is expected that the server processes renegotiation messages first. +* @preconan +* @short +* @ Previous Level 1 +* @autotrue +@ */ +/* BEGIN_CASE */ +void SDV_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001() +{ + int version = TLS1_2; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + HITLS_Session *session = NULL; + TLS_TYPE local = HITLS; + TLS_TYPE remote = HITLS; + localProcess = HLT_InitLocalProcess(local); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(remote); + ASSERT_TRUE(remoteProcess != NULL); + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_SetRenegotiationSupport(clientCtxConfig, true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + HLT_SetRenegotiationSupport(serverCtxConfig, true); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 1666; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HITLS_Renegotiate(clientSsl) == HITLS_SUCCESS); + const char *writeBuf = "Hello world"; + pthread_t thrd; + ASSERT_TRUE(pthread_create(&thrd, NULL, (void *)Hello, clientSsl) == 0); + sleep(2); + HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)); + uint8_t readBuf[BUF_SIZE_DTO_TEST] = {0}; + uint32_t readLen; + ASSERT_TRUE(memset_s(readBuf, BUF_SIZE_DTO_TEST, 0, BUF_SIZE_DTO_TEST) == EOK); + ASSERT_TRUE(HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + pthread_join(thrd, NULL); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + +exit: + ClearWrapper(); + HLT_CleanFrameHandle(); + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_hlt_dtls12_consistency.data b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_hlt_dtls12_consistency.data new file mode 100644 index 00000000..0d22b9db --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/dtls12/test_suite_sdv_hlt_dtls12_consistency.data @@ -0,0 +1,2 @@ +SDV_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001 tls12 +SDV_TLS_DTLS_CONSISTENCY_RFC5246_UNEXPETED_REORD_TYPE_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency.base.c b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency.base.c new file mode 100644 index 00000000..c10f98cd --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency.base.c @@ -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. + */ + +#include +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "session_type.h" +#include "hitls_type.h" +#include "pack.h" +#include "send_process.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "uio_base.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "cert.h" +#include "app.h" +#include "hlt.h" +#include "alert.h" +#include "securec.h" +#include "record.h" +#include "rec_write.h" +#include "rec_read.h" +#include "rec_wrapper.h" +#include "hitls_crypt_init.h" +#include "conn_init.h" +#include "cert_callback.h" +#include "change_cipher_spec.h" +#include "common_func.h" + +#define PORT 11111 +#define TEMP_DATA_LEN 1024 /* Length of a single message. */ +#define MAX_BUF_LEN (20 * 1024) +#define READ_BUF_SIZE (18 * 1024) /* Maximum length of the read message buffer */ +#define ALERT_BODY_LEN 2u +#define REC_TLS_RECORD_HEADER_LEN 5 /* recode header length */ +#define REC_CONN_SEQ_SIZE 8u /* SN size */ +#define GetEpochSeq(epoch, seq) (((uint64_t)(epoch) << 48) | (seq)) +#define BUF_TOOLONG_LEN ((1 << 14) + 1) +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; /* session set to the client, used for session recovery. */ +} ResumeTestInfo; + +typedef struct { + int connectExpect; // Expected connect result + int acceptExpect; // Expected accept result + ALERT_Level expectLevel; // Expected alert level + ALERT_Description expectDescription; // Expected alert description of the tested end +} TestExpect; + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isServerExtendMasterSecret; + bool isSupportRenegotiation; /* Renegotiation support flag */ + bool needStopBeforeRecvCCS; /* CCS test, so that the TRY_RECV_FINISH stops before the CCS message is received. */ +} HandshakeTestInfo; + +uint16_t GetCipherSuite(const char *cipherSuite) +{ + if (strcmp(cipherSuite, "HITLS_ECDHE_SM4_CBC_SM3") == 0) { + return HITLS_ECDHE_SM4_CBC_SM3; + } + if (strcmp(cipherSuite, "HITLS_ECC_SM4_CBC_SM3") == 0) { + return HITLS_ECC_SM4_CBC_SM3; + } + return 0; +} + +int32_t RandBytes(uint8_t *randNum, uint32_t randLen) +{ + srand(time(0)); + const int maxNum = 256u; + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % maxNum); + } + return HITLS_SUCCESS; +} + +int32_t GenerateEccPremasterSecret(TLS_Ctx *ctx); + +int32_t RecordDecryptPrepare(TLS_Ctx *ctx, uint16_t version, uint64_t seq, REC_TextInput *cryptMsg); +int32_t RecConnDecrypt( + TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg, uint8_t *data, uint32_t *dataLen); + +int32_t STUB_GenerateEccPremasterSecret(TLS_Ctx *ctx) +{ + uint32_t offset; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *kxCtx = hsCtx->kxCtx; + uint8_t *premasterSecret = kxCtx->keyExchParam.ecc.preMasterSecret; + + /* The first two bytes are the latest version supported by the client.*/ + /* Change the version number and construct an exception. */ + BSL_Uint16ToByte(0x0505, premasterSecret); + offset = sizeof(uint16_t); + /* 46 bytes secure random number */ + return SAL_CRYPT_Rand(&premasterSecret[offset], MASTER_SECRET_LEN - offset); +} + +int32_t STUB_TlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num) +{ + int32_t ret; + (void)recordType; + (void)readLen; + RecConnState *state = ctx->recCtx->readStates.currentState; + uint16_t version = ctx->negotiatedInfo.version; + uint64_t seq = state->seq; + REC_TextInput encryptedMsg = {0}; + ret = RecordDecryptPrepare(ctx, version, seq, &encryptedMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint32_t dataLen = num; + ASSERT_EQ(encryptedMsg.textLen, num); + ret = RecConnDecrypt(ctx, state, &encryptedMsg, data, &dataLen); +exit: + return ret; +} + +int32_t StatusGMPark(HandshakeTestInfo *testInfo) +{ + testInfo->client = FRAME_CreateTLCPLink(testInfo->config, BSL_UIO_TCP, true); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateTLCPLink(testInfo->config, BSL_UIO_TCP, false); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (FRAME_CreateConnection(testInfo->client, testInfo->server, testInfo->isClient, testInfo->state) != + HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + testInfo->config = HITLS_CFG_NewTLCPConfig(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusGMPark(testInfo); +} + + +int32_t DefaultCfgStatusParkWithSuite(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + testInfo->config = HITLS_CFG_NewTLCPConfig(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t cipherSuits[] = {HITLS_ECDHE_SM4_CBC_SM3}; + HITLS_CFG_SetCipherSuites(testInfo->config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusGMPark(testInfo); +} + +void SetFrameType(FRAME_Type *frametype, uint16_t versionType, REC_Type recordType, HS_MsgType handshakeType, + HITLS_KeyExchAlgo keyExType) +{ + frametype->versionType = versionType; + frametype->recordType = recordType; + frametype->handshakeType = handshakeType; + frametype->keyExType = keyExType; +} diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_1.c b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_1.c new file mode 100644 index 00000000..814e256d --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_1.c @@ -0,0 +1,2109 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_sdv_frame_tlcp_consistency */ +/* END_HEADER */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC001 +* @title After initialization, the server receives a CCS message after sending the serverhellodone message and return +* an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. During the handshake, after sending the Server Hello Done message, the server +* constructs a CCS message and sends it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC001(void) +{ + HandshakeTestInfo testInfo = { 0 }; + + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC002 +* @title After initialization, the client receives a CCS message after sending a client hello message and returns an +* alert message +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. During the handshake, after sending the client hello message, constructs a CCS message and sends it to the +* client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC002(void) +{ + HandshakeTestInfo testInfo = { 0 }; + + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC003 +* @title During connection establishment, the client receives the serverhello message after sending the CCS message and +* expects to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. During the handshake, after client sending the CCS, constructs a serverhello message and sends it to the +* client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC003(void) +{ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_SEND_CHANGE_CIPHER_SPEC; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + testInfo.client->ssl->hsCtx->state = TRY_RECV_FINISH; + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_EQ(FRAME_GetDefaultMsg(&frameType, &frameMsg), HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC004 +* @title After initialization, construct an app message and send it to the client. The expected alert is returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. Durintg the handshake, When the client is in the TRY_RECV_SERVER_HELLO state, construct an APP data message +* and send it to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC004(void) +{ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HandshakeTestInfo testInfo = { 0 }; + + FRAME_Init(); + testInfo.config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.client = FRAME_CreateTLCPLink(testInfo.config, BSL_UIO_TCP, true); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateTLCPLink(testInfo.config, BSL_UIO_TCP, false); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_IDLE); + + uint8_t appdata[] = {0x17, 0x01, 0x01, 0x00, 0x02, 0x01, 0x01}; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ(memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), + EOK); + + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_ALERTING); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_CM_LINK_FATAL_ALERTED); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_ALERTED); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(frameMsg.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC005 +* @title After the connection is established, the client receives the serverhello message after receiving the app data. +* The client is expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. The client initiates a TLS conncetion request. After the handshake succeeds, constructs a serverhello +* message and sends it to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC005(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, HITLS_VERSION_TLCP11, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + /* Reassembly */ + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_BAD_RECORD_MAC); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_EQ(FRAME_ParseMsgHeader(&frameType, sndBuf, sndLen, &frameMsg, &parseLen), 0); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC006 +* @title After the link is established, renegotiation is not enabled. The server receives the client keyexchange message +* and is expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. After the client initiates a TLS link request. After the handshake succeeds, construct a clientkeyexchange +* message and send it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC006(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + + uint8_t data[5] = {0x10, 0x00, 0x00, 0x01, 0x01}; + ASSERT_EQ(REC_Write(client->ssl, REC_TYPE_HANDSHAKE, data, sizeof(data)), HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC007 +* @title After initialization, construct an app message and send it to the server. Expected alert is returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. When the client initiates a TLS link application request in the RECV_CLIENT_HELLO message on the server, +* construct an APP message and send it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC007(void) +{ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HandshakeTestInfo testInfo = { 0 }; + + FRAME_Init(); + testInfo.config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.client = FRAME_CreateTLCPLink(testInfo.config, BSL_UIO_TCP, true); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateTLCPLink(testInfo.config, BSL_UIO_TCP, false); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0x17, 0x01, 0x01, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ(memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), + EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(frameMsg.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC01 +* @spec Record layer protocols include: handshake, alarm, and password specification change. +* To support protocol extensions, the record layer protocol may support other record types. +* Any new record types should be deassigned in addition to the Content Type values assigned for the types +* described above. +* If an unrecognized record type is received, ignore it. +* @title There are only four types of record layers. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. When the client is in TRY_RECV_SERVER_HELLO state,receives the serverhello message whose recordType is 99, +* Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC01(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_SM4_CBC_SM3, HITLS_ECC_SM4_CBC_SM3}; + HITLS_CFG_SetCipherSuites(tlsConfig, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.msg[0] = 0x99u; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC02 +* @spec Record layer protocols include: handshake, alarm, and password specification change. +* To support protocol extensions, the record layer protocol may support other record types. +* Any new record types should be de-assigned in addition to the Content Type values assigned for the types +* described above. +* If an unrecognized record type is received, ignore it. +* @title There are only four types of record layers. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. After the connection is established, the client receives abnormal messages (recordType: 99) after receiving +* the app data. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC02(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_SM4_CBC_SM3, HITLS_ECC_SM4_CBC_SM3}; + HITLS_CFG_SetCipherSuites(tlsConfig, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t dataBuf[] = "Hello World!"; + uint8_t readBuf[READ_BUF_SIZE]; + uint32_t readbytes; + ASSERT_EQ(HITLS_Write(server->ssl, dataBuf, sizeof(dataBuf)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.msg[0] = 0x99u; + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readbytes), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC03 +* @spec Record layer protocols include: handshake, alarm, and password specification change. +* To support protocol extensions, the record layer protocol may support other record types. +* Any new record types should be deassigned in addition to the Content Type values assigned for the types +* described above. +* If an unrecognized record type is received, ignore it. +* @title There are only four types of record layers. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. When the server is in TRY_RECV_CLIENT_HELLO state, the server receives the client hello message whose +* recordType is 99. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC03(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_SM4_CBC_SM3, HITLS_ECC_SM4_CBC_SM3}; + HITLS_CFG_SetCipherSuites(tlsConfig, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO), HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.msg[0] = 0x99u; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC04 +* @spec Record layer protocols include: handshake, alarm, and password specification change. +* To support protocol extensions, the record layer protocol may support other record types. +* Any new record types should be deassigned in addition to the Content Type values assigned for the types +* described above. +* If an unrecognized record type is received, ignore it. +* @title There are only four types of record layers. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1. +* 2. After the connection is established, the server receives abnormal messages (recordType: 99) after receiving +* the app data. Expected result 2. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT_UNEXPECTED_MESSAGE message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC04(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_SM4_CBC_SM3, HITLS_ECC_SM4_CBC_SM3}; + HITLS_CFG_SetCipherSuites(tlsConfig, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t dataBuf[] = "Hello World!"; + uint8_t readBuf[READ_BUF_SIZE]; + uint32_t readbytes; + ASSERT_EQ(HITLS_Write(client->ssl, dataBuf, sizeof(dataBuf)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.msg[0] = 0x99u; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readbytes), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC001 +* @title An unexpected message is received when the client is in the TRY_RECV_CERTIFICATIONATE state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in the TRY_RECV_CERTIFICATIONATE state, construct a Server Hello message and send it to +* the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT. The level is ALERT_LEVEL_FATAL and +* the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC001(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE), HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC002 +* @title An unexpected message is received when the client is in the TRY_RECV_SERVER_KEY_EXCHANGE state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in the TRY_RECV_SERVER_KEY_EXCHANGE state, construct a Server Hello message and send it +* to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. The level is ALERT_Level_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC002(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_KEY_EXCHANGE), HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC003 +* @title An unexpected message is received when the client is in the TRY_RECV_SERVER_HELLO_DONE state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in the TRY_RECV_SERVER_HELLO_DONE state, construct a Server Hello message and send it to +* the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. The level is ALERT_LEVEL_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC003(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO_DONE), HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC004 +* @title An unexpected message is received when the client is in the TRY_RECV_FINISH state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in the TRY_RECV_FINISH state, construct a Server Hello message and send it to the client + Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. The level is ALERT_LEVEL_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC004(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, + MAX_RECORD_LENTH, + ioUserData->recMsg.msg + REC_TLS_RECORD_HEADER_LEN, + ioUserData->recMsg.len - REC_TLS_RECORD_HEADER_LEN) == EOK); + sndMsg.len = ioUserData->recMsg.len - REC_TLS_RECORD_HEADER_LEN; + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + REC_Write(server->ssl, REC_TYPE_HANDSHAKE, sndMsg.msg, sndMsg.len); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC005 +* @title An unexpected message is received when the client is in the TRY_RECV_CERTIFICATE_REQUEST state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in the TRY_RECV_CERTIFICATE_REQUEST state, construct a Server Hello message and send it + to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. The level is ALERT_LEVEL_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC005(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_REQUEST), HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC006 +* @title An unexpected message is received when the client is in the TRY_RECV_NEW_SESSION_TICKET state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in the TRY_RECV_NEW_SESSION_TICKET state, construct a Server Hello message and send it +* to the client. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. The level is ALERT_LEVEL_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC006(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + client->ssl->hsCtx->state = TRY_RECV_NEW_SESSION_TICKET; + + uint32_t parseLen = 0; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC007 +* @title An unexpected message is received when the server is in the TRY_RECV_CLIENT_HELLO state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the server is in the TRY_RECV_CLIENT_HELLO state, construct a CLIENT_KEY_EXCHANGE message and send it +* to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC007(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + server->ssl->hsCtx->state = TRY_RECV_CLIENT_HELLO; + + uint32_t parseLen = 0; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC008 +* @title An unexpected message is received when the server is in the TRY_RECV_CERTIFICATIONATE state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the server is in the TRY_RECV_CERTIFICATIONATE state, construct a CLIENT_KEY_EXCHANGE message and send +* it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC008(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + server->ssl->hsCtx->state = TRY_RECV_CERTIFICATE; + + uint32_t parseLen = 0; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC009 +* @title An unexpected message is received when the server is in the TRY_RECV_CLIENT_KEY_EXCHANGE state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the server is in the TRY_RECV_CLIENT_KEY_EXCHANGE state, construct a SERVER_HELLO message and send it +* to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the SERVER_HELLO message, the server sends an ALERT message. The level is ALERT_Level_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC009(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + server->ssl->hsCtx->state = TRY_RECV_CLIENT_KEY_EXCHANGE; + + uint32_t parseLen = 0; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} + +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC010 +* @title An unexpected message is received when the server is in the TRY_RECV_CERTIFICATIONATE_VERIFY state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the server is in the TRY_RECV_CERTIFICATIONATE_VERIFY state, construct a CLIENT_KEY_EXCHANGE message +* and send it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC010(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + server->ssl->hsCtx->state = TRY_RECV_CERTIFICATE_VERIFY; + + uint32_t parseLen = 0; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC011 +* @title An unexpected message is received when the server is in the TRY_RECV_FINISH state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the server is in the TRY_RECV_FINISH state, construct a CLIENT_KEY_EXCHANGE message and send it to the + server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC011(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + server->ssl->hsCtx->state = TRY_RECV_FINISH; + + uint32_t parseLen = 0; + frameType.versionType = version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC012 +* @title An unexpected message is received when the client is in the TRY_RECV_SERVER_HELLO state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the client is in the TRY_RECV_SERVER_HELLO state, construct a Server Hello Done message and send it to +* the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello Done message, the client sends an ALERT. The level is ALERT_Level_FATAL +* and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC012(int version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + config->isSupportExtendMasterSecret = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = true; + config->isSupportRenegotiation = true; + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + + FRAME_Msg parsedSHdone = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, version, REC_TYPE_HANDSHAKE, SERVER_HELLO_DONE, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &parsedSHdone) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSHdone, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &parsedSHdone); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &parsedSHdone, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedSHdone.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedSHdone.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &parsedSHdone); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC001 +* @title The client sends a Client Certificate message with the length of 2 ^ 14 + 1 bytes. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a connection creation request. When the client needs to send the Client Certificate +* message, the two fields are modified as follows: +* Certificates Length is 2 ^ 14 + 1 +* Certificates are changed to 2 ^ 14 + 1 bytes buffer. +* After the modification is complete, send the message to the server. Expected result 2. +* 3. When the server receives the Client Certificate message, check the value returned by the HITLS_Accept +* interface. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +* 3. The value returned by the HITLS_Accept interface is HITLS_REC_RECORD_OVERFLOW. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.certificate.certItem->cert.data); + frameMsg.body.hsMsg.body.certificate.certItem->cert.data = certDataTemp; + frameMsg.body.hsMsg.body.certificate.certItem->cert.size = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.data = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC002 +* @title The server sends a Server Certificate message with the length of 2 ^ 14 + 1 bytes. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The client initiates a connection creation request. When the server needs to send a Server Certificate +* message, the two fields are modified as follows: +* Certificates Length is 2 ^ 14 + 1 +* Certificates are changed to 2 ^ 14 + 1 bytes buffer. +* After the modification is complete, send the modification to the server. Expected result 2. +* 3. When the client receives the Server Certificate message, check the value returned by the HITLS_Connect +* interface. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +* 3. The value returned by the HITLS_Connect interface is HITLS_REC_RECORD_OVERFLOW. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.certificate.certItem->cert.data); + frameMsg.body.hsMsg.body.certificate.certItem->cert.data = certDataTemp; + frameMsg.body.hsMsg.body.certificate.certItem->cert.size = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.data = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC003 +* @title The client sends a Change Cipher Spec message with the length of 2 ^ 14 + 1 bytes. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client initiates a link creation request. When the client needs to send a Change Cipher Spec message, +* modify one field as follows: Length is 2 ^ 14 + 1. After the modification, the modification is sent to the +* server. Expected result 2 is obtained. +* 3. When the server receives the Change Cipher Spec message, check the value returned by the HITLS_Accept +* interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the server. +* 3. The value returned by the HITLS_Accept interface is HITLS_REC_RECORD_OVERFLOW. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.ccsMsg.extra.data); + frameMsg.body.ccsMsg.extra.data = certDataTemp; + frameMsg.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg.body.ccsMsg.extra.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE_VERIFY); + bool isCcsRecv = testInfo.server->ssl->method.isRecvCCS(testInfo.server->ssl); + ASSERT_TRUE(isCcsRecv == false); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC004 +* @title The server sends a Change Cipher Spec message with the length of 2 ^ 14 + 1 bytes. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. The server initiates a link creation request. When the server needs to send a Change Cipher Spec message, +* modify one field as follows: Length is 2 ^ 14 + 1. After the modification, the modification is sent to the +* server. Expected result 2. +* 3. When the client receives the Change Cipher Spec message, check the value returned by the HITLS_Accept +* interface. Expected result 3. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +* 3. The value returned by the HITLS_Accept interface is HITLS_REC_RECORD_OVERFLOW. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_FINISH; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + frameType1.versionType = HITLS_VERSION_TLCP11; + frameType1.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType1, &frameMsg1) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg1.body.ccsMsg.extra.data); + frameMsg1.body.ccsMsg.extra.data = certDataTemp; + frameMsg1.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg1.body.ccsMsg.extra.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType1, &frameMsg1, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData1->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + + FRAME_CleanMsg(&frameType1, &frameMsg1); + memset_s(&frameMsg1, sizeof(frameMsg1), 0, sizeof(frameMsg1)); + + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_RECORD_OVERFLOW); + +exit: + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001 +* @title A too long cipher text app message is sent by client or server. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. When the client is in transporting state, the server sends a message whose ciphertext length is 2 ^ 14 + +* 2048. Expected result 2. +* 3. When the server is in transporting state, the client sends a message whose ciphertext length is 2 ^ 14 + +* 2048. Expected result 3. +* 4. When the server is in transporting state, the client sends a message whose ciphertext length is 2 ^ 14 + +* 2049. Expected result 4. +* 5. When the client is in transporting state, the server sends a message whose ciphertext length is 2 ^ 14 + +* 2049. Expected result 5. +* @expect 1. The initialization is successful. +* 2. The message can be decrypted. +* 3. The message can be decrypted. +* 4. The server send an alert message. +* 5. The client send an alert message. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001(int isClient, int ptLen, int ctLen) +{ + FRAME_Init(); + STUB_Init(); + FuncStubInfo stubInfo = {0}; + HITLS_Config *config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(config != NULL); + FRAME_LinkObj *client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + FRAME_LinkObj *server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + FRAME_LinkObj *sender = NULL; + FRAME_LinkObj *receiver = NULL; + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + if (isClient) { + sender = client; + receiver = server; + } else { + sender = server; + receiver = client; + } + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + + uint8_t readBuf[MAX_BUF_LEN] = {0}; + uint32_t readLen = 0; + + uint8_t sendBuf[MAX_BUF_LEN] = {0}; + (void)memset_s(sendBuf + 5, REC_MAX_CIPHER_TEXT_LEN + 1, 9, REC_MAX_CIPHER_TEXT_LEN + 1); + RecBufFree(sender->ssl->recCtx->outBuf); + sender->ssl->recCtx->outBuf = RecBufNew(MAX_BUF_LEN); + RecBufFree(receiver->ssl->recCtx->inBuf); + receiver->ssl->recCtx->inBuf = RecBufNew(MAX_BUF_LEN); + + ASSERT_EQ(TlsRecordWrite(sender->ssl, REC_TYPE_APP, sendBuf, ptLen), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(sender, receiver), HITLS_SUCCESS); + STUB_Replace(&stubInfo, TlsRecordRead, STUB_TlsRecordRead); + int32_t ret = ctLen > 18432 ? HITLS_REC_RECORD_OVERFLOW : HITLS_SUCCESS; + ASSERT_EQ(TlsRecordRead(receiver->ssl, REC_TYPE_APP, readBuf, &readLen, ctLen), ret); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(sender); + FRAME_FreeLink(receiver); + STUB_Reset(&stubInfo); +} +/* END_CASE */ + +/* @ + * @test UT_TLS_TLCP_CONSISTENCY_NONZERO_MESSAGELEN_TC001 + * @title Test the scenario where the message parameter is unacceptable. + * @precon nan + * @spec 1. After receiving the servehellodone message from the server, the client verifies whether the server + * certificate is valid and the servehello message from the server. Indicates whether the message parameter + * is acceptable. If acceptable, the client continues the handshake process. Otherwise, a HandShakeFailure + * critical alarm is sent. + * @brief 1. After receiving the servehellodone message from the server, the client verifies whether the server + * certificate is valid and the servehello message from the server. Expected result 1. + * @expect 1. During the first connection setup, the client receives a servehellodone message from the server. The + * message length is not 0. The expected handshake fails. + @ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_NONZERO_MESSAGELEN_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + int32_t ret; + ret = FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO_DONE); + ASSERT_EQ(ret, HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO_DONE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloDoneMsg *serverHelloDone = &frameMsg.body.hsMsg.body.serverHelloDone; + uint8_t extra[1] = {0}; + FRAME_ModifyMsgArray8(extra, 1, &serverHelloDone->extra, NULL); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HTILS_PARSE_EXCESSIVE_MESSAGE_SIZE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC001 +* @title Check whether the sequence number of the read/write status in the FINISH message sent by the server/client is + 1. +* @precon nan +* @brief 1. Configure the client/server to stay in the TRY_SEND_FINISH state. Expected result 1. +* 2. Connect the server and client once and send the message. Expected result 2. + 3. Obtain the messages sent by the server or client. Expected result 3. + 4. Parse the message sent by the local end into the hs_msg structure. Expected result 4. + 5. Check the sequence number in the sent message. Expected result 5. + 6. Enable the local end to transmit data to the peer end. Expected result 6. + 7. Obtain the messages received by the peer end. Expected result 7. + 8. Parse the message received by the peer end into the hs_msg structure. Expected result 8. + 9. Check the sequence number in the received message. Expected result 9. +* @expect 1. The initialization is successful. +* 2. If the server is successfully connected, the client returns NORMAL_RECV_BUF_EMPTY. + 3. The sending length is not null. + 4. The parsing is successful and the message header length is fixed to 5 bytes. + 5. The serial number is 1. + 6. The transmission is successful. + 7. The received length is not empty. + 8. The parsing succeeds and the message header length is fixed to 5 bytes. + 9. The serial number is 1. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC001(int isClient) +{ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = TRY_SEND_FINISH; + testInfo.isClient = isClient; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + if (isClient) { + ASSERT_TRUE(HITLS_Connect(testInfo.client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + } else { + ASSERT_TRUE(HITLS_Accept(testInfo.server->ssl) == HITLS_SUCCESS); + } + + HITLS_Ctx *localSsl = isClient ? testInfo.client->ssl : testInfo.server->ssl; + ASSERT_TRUE(localSsl->recCtx->writeStates.currentState->seq == 1); + + if (isClient) { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + } + + HITLS_Ctx *remoteSsl = isClient ? testInfo.server->ssl : testInfo.client->ssl; + if (!isClient) { + ASSERT_TRUE(HITLS_Connect(testInfo.client->ssl) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(HITLS_Accept(testInfo.server->ssl) == HITLS_REC_NORMAL_IO_BUSY); + } + ASSERT_TRUE(remoteSsl->recCtx->readStates.currentState->seq == 1); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC002 +* @title Check whether the sequence number of the read/write sequence in the APP message sent by the server/client is + 2. +* @precon nan +* @brief 1. Configure the status of the client/server to the successful handshake. Expected result 1. +* 2. Check the server/client connection status. Expected result 2. + 3. Randomly generate 32-byte data. Expected result 3. + 4. Write app data. Expected result 4. + 5. Obtain data from the I/O sent by the local end and parse the header and content. Expected result 5. + 6. Check the sequence number in the sent message. Expected result 6. + 7. Perform I/O data transmission from the local end to the peer end. Expected result 7. + 8. Obtain data from the received I/O from the peer end and parse the header and content. Expected result 8. + 9. Check the sequence number in the received message. Expected result 9. +* @expect 1. The initialization is successful. +* 2. The link status is Transferring. + 3. The generation is successful. + 4. The writing is successful. + 5. The parsing is successful and the value of RecordType is REC_TYPE_APP. + 6. The SN is 2. + 7. The transmission is successful. + 8. The parsing is successful and the value of RecordType is REC_TYPE_APP. + 9. The SN is 2. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC002(int isClient) +{ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = HS_STATE_BUTT; + testInfo.isClient = isClient; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_TRANSPORTING); + + uint8_t transportData[REC_CONN_SEQ_SIZE * 4] = {0}; + uint32_t transportDataLen = sizeof(transportData) / sizeof(uint8_t); + ASSERT_EQ(RandBytes(transportData, transportDataLen), HITLS_SUCCESS); + HITLS_Ctx *localSsl = isClient ? testInfo.client->ssl : testInfo.server->ssl; + ASSERT_EQ(APP_Write(localSsl, transportData, transportDataLen), HITLS_SUCCESS); + + ASSERT_EQ(localSsl->recCtx->writeStates.currentState->seq , 2); + + if (isClient) { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + } + + HITLS_Ctx *remoteSsl = isClient ? testInfo.server->ssl : testInfo.client->ssl; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(APP_Read(remoteSsl, readBuf, READ_BUF_SIZE, &readLen), HITLS_SUCCESS); + ASSERT_EQ(remoteSsl->recCtx->readStates.currentState->seq , 2); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_1.data b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_1.data new file mode 100644 index 00000000..b84d830d --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_1.data @@ -0,0 +1,107 @@ +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC001 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC001: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC002 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC002: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC003 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC003: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC004 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC004: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC005 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC005: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC006 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC006: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC007 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_RECORDTYPE_TC007: + +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC01 +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC01: + +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC02 +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC02: + +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC03 +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC03: + +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC04 +UT_TLS_TLCP_CONSISTENCY_UNKNOW_RECORDTYPE_TC04: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC001 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC001:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC002 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC002:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC003 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC003:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC004 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC004: + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC005 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC005:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC006 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC006:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC007 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC007:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC008 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC008:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC009 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC009:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC010 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC010:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC011 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC011:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC012 +UT_TLS_TLCP_CONSISTENCY_UNEXPECT_HANDSHAKEMSG_TC012:HITLS_VERSION_TLCP11 + +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC001 +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC001: + +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC002 +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC002: + +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC003 +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC003: + +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC004 +UT_TLS_TLCP_CONSISTENCY_MSGLENGTH_TOOLONG_TC004: + +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001 +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001:1:18383:18432 + +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001 +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001:1:18384:18433 + +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001 +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001:0:18383:18432 + +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001 +UT_TLS_TLCP_CONSISTENCY_CIPHERTEXT_TOOLONG_TC001:0:18384:18433 + +UT_TLS_TLCP_CONSISTENCY_NONZERO_MESSAGELEN_TC001 +UT_TLS_TLCP_CONSISTENCY_NONZERO_MESSAGELEN_TC001: + +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC001 +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC001:0 + +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC001 +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC001:1 + +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC002 +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC002:0 + +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC002 +UT_TLS_TLCP_CONSISTENCY_SEQ_NUM_TC002:1 diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_2.c b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_2.c new file mode 100644 index 00000000..12e8ac2a --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_2.c @@ -0,0 +1,287 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_sdv_frame_tlcp_consistency */ +/* END_HEADER */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_RESUME_TC003 +* @title Enable the session restoration function at both ends. If the session ID is obtained after the link is + successfully established, a fatal alert is sent. The session ID fails to be used to restore the session. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. +* Enable the session restoration function at both ends. Expected result 1. +* 2. Obtaine the session ID and a fatal alert is sent. The session ID fails to be used to restore the session. +* Expected result 2. +* @expect 1. The initialization is successful. +* 2. Expected handshake failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_RESUME_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + HITLS_SetSession(client->ssl, clientSession); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_FINISH), HITLS_SUCCESS); + client->ssl->method.sendAlert(client->ssl, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + ASSERT_NE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + HITLS_SetSession(client->ssl, clientSession); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_RESUME_TC004 +* @title Set the client and server support session recovery. After the first connection is established, the session ID + is obtained. Create two connection. The client and server are the same as those in the last session. Use the + same session ID to restore the session. If the session on one link fails, check whether the data communication + on the other link is blocked. It is expected that the link is not blocked. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. +* Enable the session restoration function at both ends. Expected result 1. +* 2. Use the default configuration items to configure two new client and server. +* The client and server are the same as those in the last session. Expected result 1. +* 3. Use the obtained session ID to restore one session and send a alert. Expected result 2. +* 4. Use the obtained session ID to restore another session. Expected result 3. +* @expect 1. The initialization is successful. +* 2. Expected handshake failure. +* 3. Restore the session successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_RESUME_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_LinkObj *clientResume = NULL; + FRAME_LinkObj *serverResume = NULL; + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + HITLS_SetSession(client->ssl, clientSession); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_FINISH), HITLS_SUCCESS); + + clientResume = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + serverResume = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + HITLS_SetSession(clientResume->ssl, clientSession); + ASSERT_EQ(FRAME_CreateConnection(clientResume, serverResume, false, TRY_SEND_FINISH), HITLS_SUCCESS); + + client->ssl->method.sendAlert(client->ssl, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + ASSERT_NE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + + ASSERT_EQ(FRAME_CreateConnection(clientResume, serverResume, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(clientResume->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(clientResume); + FRAME_FreeLink(serverResume); + ClearWrapper(); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_RESUME_TC005 +* @title Set the client and server support session recovery. After the first connection is established, the session ID +* is obtained. Apply for two links. The client and server are the same as those in the last session. Use the same +* session ID to restore the session. If the session on one link times out, check whether the data communication +* on the other link is blocked. If the data communication on the other link is not blocked, the data +* communication on the other link is not blocked. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. +* Enable the session restoration function at both ends. Expected result 1. +* 2. Use the default configuration items to configure two new client and server. +* The client and server are the same as those in the last session. Expected result 1. +* 3. Use the obtained session ID to restore one session and sleep to cause a session to time out. +* Expected result 2. +* 4. Use the obtained session ID to restore another session. Expected result 3. +* @expect 1. The initialization is successful. +* 2. Establish the connection but restore the session failed. +* 3. Establish the connection and restore the session successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_RESUME_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_LinkObj *clientResume = NULL; + FRAME_LinkObj *serverResume = NULL; + config = HITLS_CFG_NewTLCPConfig(); + const uint64_t timeout = 5u; + HITLS_CFG_SetSessionTimeout(config, timeout); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + HITLS_SetSession(client->ssl, clientSession); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_FINISH), HITLS_SUCCESS); + + clientResume = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + serverResume = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + HITLS_SetSession(clientResume->ssl, clientSession); + sleep(timeout); + ASSERT_EQ(FRAME_CreateConnection(clientResume, serverResume, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(clientResume->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + FRAME_FreeLink(clientResume); + FRAME_FreeLink(serverResume); + ClearWrapper(); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_RESUME_TC006 +* @title Enable the session recovery function at both ends. The link is successfully established. The setting of the +* session_id expires. The session fails to be restored. +* @precon nan +* @brief 1. Set the client and server support session recovery. Establishe the first connection. Expected result 1. +* 2. Set the session_id expired, restore the session. Expected result 2. +* @expect 1. The expected handshake is successful. +* 2. The session is not recovered. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_RESUME_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + const uint64_t timeout = 5u; + HITLS_CFG_SetSessionTimeout(config, timeout); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + HITLS_SetSession(client->ssl, clientSession); + sleep(timeout); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_RESUME_TC007 +* @title When a link is established for the first time, the clienthello message on the client contains the session_id +* field that is not empty and is in the connection state. If the session ID on the server is not found in the +* cache, the first connection setup process is triggered. +* @precon nan +* @brief 1. Create the TLCP links on the client and server again, set the obtained session as the session on the +* client, and check whether the session is reused. Expected result 1. +* @expect 1. The expected handshake is successful, but the session is not recovered. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_RESUME_TC007() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_CFG_FreeConfig(config); + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + HITLS_SetSession(client->ssl, clientSession); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_2.data b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_2.data new file mode 100644 index 00000000..43486dd1 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_2.data @@ -0,0 +1,14 @@ +UT_TLS_TLCP_CONSISTENCY_RESUME_TC003 +UT_TLS_TLCP_CONSISTENCY_RESUME_TC003: + +UT_TLS_TLCP_CONSISTENCY_RESUME_TC004 +UT_TLS_TLCP_CONSISTENCY_RESUME_TC004: + +UT_TLS_TLCP_CONSISTENCY_RESUME_TC005 +UT_TLS_TLCP_CONSISTENCY_RESUME_TC005: + +UT_TLS_TLCP_CONSISTENCY_RESUME_TC006 +UT_TLS_TLCP_CONSISTENCY_RESUME_TC006: + +UT_TLS_TLCP_CONSISTENCY_RESUME_TC007 +UT_TLS_TLCP_CONSISTENCY_RESUME_TC007: diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_3.c b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_3.c new file mode 100644 index 00000000..820a5af5 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_3.c @@ -0,0 +1,1537 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_sdv_frame_tlcp_consistency */ +/* END_HEADER */ + +static void Test_MisSessionId(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + if (*(bool *)user) { + return; + } + *(bool *)user = true; + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLCP11; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_EQ(parseLen, *len); + frameMsg.body.hsMsg.body.serverHello.sessionId.state = MISSING_FIELD; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_SESSIONID_MISS_TC001 +* @title During session recovery, the server deletes session_id after sending the server hello message. The expected +* session recovery fails and the connection is interrupted. +* @precon nan +* @brief 1. The client hello and server hello messages are followed by authentication and key exchange. Including +* server certificate, server key exchange, client certificate, and client key exchange. Expected result 1. +* @expect 1. The expected handshake fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_SESSIONID_MISS_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + bool isModify = false; + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + HITLS_SetSession(client->ssl, clientSession); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &isModify, + Test_MisSessionId + }; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +static void Test_DiffServerKeyEx(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + if (*(bool *)user) { + return; + } + *(bool *)user = true; + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLCP11; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_KEY_EXCHANGE); + ASSERT_EQ(parseLen, *len); + frameType.keyExType = HITLS_KEY_EXCH_ECC; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_KEY_EXCHANGE_TC001 +* @title After the client sends a certificate, the key exchange message sent by the client is different from the +* negotiated key exchange algorithm. As a result, the link fails to be established. +* @precon nan +* @brief 1. After the client sends a certificate, the key exchange message sent by the client must be consistent with +* the negotiated key exchange algorithm. Expected result 1. +* @expect 1. The expected handshake fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_KEY_EXCHANGE_TC001() +{ + + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + bool isModify = false; + RecWrapper wrapper = { + TRY_SEND_SERVER_KEY_EXCHANGE, + REC_TYPE_HANDSHAKE, + false, + &isModify, + Test_DiffServerKeyEx + }; + RegisterWrapper(wrapper); + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_NE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); +} +/* END_CASE */ + +/* @ + * @test UT_TLS_TLCP_CONSISTENCY_CLIENTKXCH_VERSIONERR_TC001 + * @title Test when the value of Client_Version on the server does not match that on the client. + * @precon nan + * @spec 1. "Client_Version: version number supported by the client. The server checks whether the value matches the + * value sent in the hello message from the client. random 46-byte random number" + * @brief 1. The server checks whether the Client_Version matches the value sent in the hello message from the client. + * Expected result 1. + * @expect 1. If the Client_Version of PreMasterSecret in the ClientKeyExChange message received by the server is + * different from the ClientHello message, the server reports an alarm indicating that the decryption fails + * and the handshake fails. + @ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CLIENTKXCH_VERSIONERR_TC001(char *cipherSuite) +{ + FRAME_Init(); + STUB_Init(); + HITLS_Config *tlsConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite(cipherSuite); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + FuncStubInfo stubInfo = {0}; + STUB_Replace(&stubInfo, GenerateEccPremasterSecret, STUB_GenerateEccPremasterSecret); + int32_t ret = FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH); + ASSERT_EQ(ret, HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_BAD_RECORD_MAC); + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(server->ssl, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_BAD_RECORD_MAC); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&stubInfo); +} +/* END_CASE */ + +/* @ + * @test UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC001 + * @title Violation of the rule that the signature certificate is before the encryption certificate is after, and + * check the result. + * @precon nan + * @spec 1. Server certificate: signature certificate is placed before the encryption certificate. + * @brief 1. Signature certificate before encryption certificate. Expected result 1. + * @expect 1. After the signature certificate encrypts the certificate after the server sends the certificate, + * the client reports an error indicating that the certificate verification fails and the handshake fails. + @ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "sm2/ca.der", + "sm2/inter.der", + "sm2/sign.der", + "sm2/enc.der", + "sm2/sign.key.der", + "sm2/enc.key.der", + }; + + tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + client = FRAME_CreateLinkWithCert(tlsConfig, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLinkWithCert(tlsConfig, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + + int32_t ret; + ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_CERT_ERR_EXP_CERT); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void TEST_SendUnexpectCertificateVerifyMsg(void *msg, void *data) +{ + FRAME_Type *frameType = (FRAME_Type *)data; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + + FRAME_Msg newFrameMsg = {0}; + HS_MsgType hsTypeTmp = frameType->handshakeType; + REC_Type recTypeTmp = frameType->recordType; + frameType->handshakeType = CERTIFICATE_VERIFY; + FRAME_Init(); + FRAME_GetDefaultMsg(frameType, &newFrameMsg); + HLT_TlsRegCallback(HITLS_CALLBACK_DEFAULT); // recovery callback + + frameType->handshakeType = hsTypeTmp; + frameType->recordType = recTypeTmp; + FRAME_CleanMsg(frameType, frameMsg); + + frameType->recordType = REC_TYPE_HANDSHAKE; + frameType->handshakeType = CERTIFICATE_VERIFY; + frameType->keyExType = HITLS_KEY_EXCH_ECDHE; + if (memcpy_s(msg, sizeof(FRAME_Msg), &newFrameMsg, sizeof(newFrameMsg)) != EOK) { + Print("TEST_SendUnexpectCertificateMsg memcpy_s Error!"); + } +} + +static void TEST_UnexpectMsg(HLT_FrameHandle *frameHandle, TestExpect *testExpect, bool isSupportClientVerify) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + ALERT_Info alertInfo = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + ASSERT_TRUE(serverConfig != NULL); + if (isSupportClientVerify) { + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, isSupportClientVerify) == 0); + } + + HLT_Ctx_Config *clientConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(clientConfig, isSupportClientVerify) == 0); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLCP1_1, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + // Client Initialization + clientRes = HLT_ProcessTlsInit(localProcess, TLCP1_1, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_TRUE(frameHandle != NULL); + frameHandle->ctx = clientRes->ssl; + HLT_SetFrameHandle(frameHandle); + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), testExpect->connectExpect); + HLT_CleanFrameHandle(); + + ALERT_GetInfo(clientRes->ssl, &alertInfo); + ASSERT_TRUE(alertInfo.level == testExpect->expectLevel); + ASSERT_EQ(alertInfo.description, testExpect->expectDescription); + ASSERT_EQ(HLT_RpcGetTlsAcceptResult(serverRes->acceptId), testExpect->acceptExpect); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC002 +* @title The server receives the certificate verify message when receiving the certificate. +* @precon nan +* @brief 1. Configure dual-end verification. Expected result 1. +* 2. Set the client callback type to certificate and replace it with certificate verify. Expected result 2. +* @expect 1. Expected success. +* 2. Expected server to return alert. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC002() +{ + TestExpect testExpect = {0}; + testExpect.acceptExpect = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + testExpect.expectLevel = ALERT_LEVEL_FATAL; + testExpect.expectDescription = ALERT_UNEXPECTED_MESSAGE; + testExpect.connectExpect = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + + HLT_FrameHandle frameHandle = {0}; + frameHandle.frameCallBack = TEST_SendUnexpectCertificateVerifyMsg; + frameHandle.expectHsType = CERTIFICATE; + frameHandle.expectReType = REC_TYPE_HANDSHAKE; + frameHandle.ioState = EXP_NONE; + frameHandle.pointType = POINT_SEND; + frameHandle.userData = NULL; + TEST_UnexpectMsg(&frameHandle, &testExpect, true); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC003 +* @title Dual-end verification. The server receives the CERTIFICATION_VERIFY message when expecting to receive the +* CLIENT_KEY_EXCHANGE message. +* @precon nan +* @brief 1. Configure unidirectional authentication. Expected result 1. +* 2. Set the client callback mode to send certificate verify. Expected result 2. +* @expect 1. Expected success. +* 2. Expected server to return alert. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC003() +{ + TestExpect testExpect = {0}; + testExpect.acceptExpect = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + testExpect.expectLevel = ALERT_LEVEL_FATAL; + testExpect.expectDescription = ALERT_UNEXPECTED_MESSAGE; + testExpect.connectExpect = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + + HLT_FrameHandle frameHandle = {0}; + frameHandle.frameCallBack = TEST_SendUnexpectCertificateVerifyMsg; + frameHandle.expectHsType = CLIENT_KEY_EXCHANGE; + frameHandle.expectReType = REC_TYPE_HANDSHAKE; + frameHandle.ioState = EXP_NONE; + frameHandle.pointType = POINT_SEND; + frameHandle.userData = NULL; + + TEST_UnexpectMsg(&frameHandle, &testExpect, true); +} +/* END_CASE */ + +// Replace the message to be sent with the CERTIFICATE. +static void TEST_SendUnexpectCertificateMsg(void *msg, void *data) +{ + FRAME_Type *frameType = (FRAME_Type *)data; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + + FRAME_Msg newFrameMsg = {0}; + HS_MsgType hsTypeTmp = frameType->handshakeType; + frameType->handshakeType = CERTIFICATE; + // Callback for changing the certificate algorithm, which is used to generate negotiation handshake messages. + FRAME_Init(); + FRAME_GetDefaultMsg(frameType, &newFrameMsg); + HLT_TlsRegCallback(HITLS_CALLBACK_DEFAULT); // recovery callback + + // Release the original msg. + frameType->handshakeType = hsTypeTmp; + FRAME_CleanMsg(frameType, frameMsg); + + // Change message. + frameType->recordType = REC_TYPE_HANDSHAKE; + frameType->handshakeType = CERTIFICATE; + frameType->keyExType = HITLS_KEY_EXCH_ECDHE; + if (memcpy_s(msg, sizeof(FRAME_Msg), &newFrameMsg, sizeof(newFrameMsg)) != EOK) { + Print("TEST_SendUnexpectCertificateMsg memcpy_s Error!"); + } +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC004 +* @title Single-end verification, indicating that the server receives the CERTIFICATION message. +* @precon nan +* @brief 1. Configure unidirectional authentication. Expected result 1. +* 2. Set the client severhello done callback mode to send certificate verify. Expected result 2. +* @expect 1. Expected success. +* 2. Expected server to return alert. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC004() +{ + TestExpect testExpect = {0}; + testExpect.acceptExpect = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + testExpect.expectLevel = ALERT_LEVEL_FATAL; + testExpect.expectDescription = ALERT_UNEXPECTED_MESSAGE; + testExpect.connectExpect = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + + HLT_FrameHandle frameHandle = {0}; + frameHandle.frameCallBack = TEST_SendUnexpectCertificateMsg; + frameHandle.expectHsType = CLIENT_KEY_EXCHANGE; + frameHandle.expectReType = REC_TYPE_HANDSHAKE; + frameHandle.ioState = EXP_NONE; + frameHandle.pointType = POINT_SEND; + frameHandle.userData = NULL; + TEST_UnexpectMsg(&frameHandle, &testExpect, false); +} +/* END_CASE */ + +static void Test_ErrCertVerify(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + if (*(bool *)user) { + return; + } + *(bool *)user = true; + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLCP11; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_VERIFY); + ASSERT_EQ(parseLen, *len); + frameMsg.body.hsMsg.body.certificateVerify.sign.data[0]++; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC005 +* @title Bidirectional verification. After the client sends a certificate, the certificate verify message contains +* an incorrect digital signature or does not contain a digital signature. As a result, the link fails to be +* established. +* @precon nan +* @brief 1. Start a handshake. Expected result 1 +* 2. Modify the certificate verify message. Expected result 2 +* @expect 1. Return success +* 2. Handshake fails +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + bool isModify = false; + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_VERIFY, + REC_TYPE_HANDSHAKE, + false, + &isModify, + Test_ErrCertVerify + }; + RegisterWrapper(wrapper); + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_NE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC006 +* @title Bidirectional verification. After the client sends a certificate, the certificate verify message contains +* an incorrect digital signature or does not contain a digital signature. As a result, the link fails to be +* established. +* @precon nan +* @brief 1. Start a handshake and set the ciphersuite to HITLS_ECC_SM4_CBC_SM3, Expected result 1 +* 2. Modify the certificate verify message. Expected result 2 +* @expect 1. Return success +* 2. Handshake fails +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + bool isModify = false; + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_VERIFY, + REC_TYPE_HANDSHAKE, + false, + &isModify, + Test_ErrCertVerify + }; + RegisterWrapper(wrapper); + uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; + HITLS_CFG_SetCipherSuites(config, &cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + config = HITLS_CFG_NewTLCPConfig(); + client = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(config, BSL_UIO_TCP, false); + ASSERT_NE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + ClearWrapper(); +} +/* END_CASE */ + +static int32_t SendCcs(HITLS_Ctx *ctx, uint8_t *data, uint8_t len) +{ + /** Write records. */ + int32_t ret = REC_Write(ctx, REC_TYPE_CHANGE_CIPHER_SPEC, data, len); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CCS_TC006 +* @title If an implementation detects a change_cipher_spec record received before the first ClientHello +* message or after the peer's Finished message, it MUST be treated as an unexpected record type +* @precon nan +* @brief 1. Establish a connection. Expected result 1 +* 2. Send a CCS message to client. Expected result 2 +* 3. Send a CCS message to server. Expected result 3 +* @expect 1. Return success +* 2. client send ALERT_UNEXPECTED_MESSAGE alert +* 3. server send ALERT_UNEXPECTED_MESSAGE alert +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CCS_TC006(int isClient) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECDHE_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + uint8_t data = 1; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + if (isClient != 0) { + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + } else { + memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE); + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + } + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_Finish_Len_TooLong(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLCP11; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, FINISHED); + ASSERT_EQ(frameMsg.body.hsMsg.body.finished.verifyData.size, 12); // in RFC5246, length of verifyData is always 12. + + frameMsg.body.hsMsg.body.finished.verifyData.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.finished.verifyData.data[0] = 0x00; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Finish_Len_TooLong_client(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLCP11; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLCP11; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, FINISHED); + ASSERT_EQ(frameMsg.body.hsMsg.body.finished.verifyData.size, 12); // in RFC5246, length of verifyData is always 12. + if (ctx->isClient==true) { + frameMsg.body.hsMsg.body.finished.verifyData.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.finished.verifyData.data[0] = 0x00; + } + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_001 +* @title An unexpected message is received when the server is in the TRY_RECV_FINISH state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. Construct a CLIENT_KEY_EXCHANGE message and send it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_001(void) +{ + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLCP11; + testInfo.uioType = BSL_UIO_TCP; + RecWrapper wrapper = { + TRY_SEND_FINISH, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Finish_Len_TooLong, + }; + RegisterWrapper(wrapper); + + testInfo.config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.client = FRAME_CreateTLCPLink(testInfo.config, testInfo.uioType, true); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateTLCPLink(testInfo.config, testInfo.uioType, false); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_002 +* @title An unexpected message is received when the server is in the TRY_RECV_FINISH state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1. +* 2. Construct a CLIENT_KEY_EXCHANGE message and send it to the server. Expected result 2. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_002(void) +{ + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLCP11; + testInfo.uioType = BSL_UIO_TCP; + RecWrapper wrapper = { + TRY_SEND_FINISH, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Finish_Len_TooLong_client, + }; + RegisterWrapper(wrapper); + + testInfo.config = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(testInfo.config != NULL); + testInfo.client = FRAME_CreateTLCPLink(testInfo.config, testInfo.uioType, true); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateTLCPLink(testInfo.config, testInfo.uioType, false); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static int32_t GetDisorderServerCertAndKeyExchMsg(FRAME_LinkObj *server, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t tmpData[READ_BUF_SIZE] = {0}; + uint32_t tmpLen = sizeof(tmpData); + (void)HITLS_Accept(server->ssl); + int32_t ret = FRAME_TransportSendMsg(server->io, tmpData, tmpLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + tmpLen = readLen; + + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, &data[offset], len - offset, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + offset += readLen; + + if (memcpy_s(&data[offset], len - offset, tmpData, tmpLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += tmpLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +/* @ + * @test UT_TLS_TLCP_CONSISTENCY_DISORDER_TC001 + * @title Configure dual-ended verification and construct abnormal scenarios. + * @precon nan + * @spec The server should send a server certificate message to the client, which always follows the server hello + * message. If the selected cipher suite uses the RSA, ECC, or ECDHE algorithm, the message contains the + * signature certificate and encryption certificate of the server. + * @brief 1. Configure dual-end verification and construct an abnormal scenario. After the serverhello message is sent, + * the sequence of the certificate message and serverkeyexchange message is changed. Expected result 1. + * @expect 1. Client returns an unexpected alert message. + @ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_DISORDER_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_CERTIFICATE), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_HANDSHAKING); + ASSERT_EQ(client->ssl->hsCtx->state, TRY_RECV_CERTIFICATE); + + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderServerCertAndKeyExchMsg(server, data, len, &len) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(ioUserData->recMsg.len != 0); + + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_DISORDER_TC002 +* @title During the handshake, the client receives the CCS when the client is receiving the clientkeyexchange. +* @precon nan +* @brief 1. Configure the single-end authentication. After the server sends the serverhellodone message, the client +* stops in the try send client key exchange state. Expected result 1. +* 2. Construct an unexpected CCS message and send it to the server. Expected result 2. +* @expect 1. The initialization succeeds. +* 2. The connection fails to be established and the server returns an unexpected message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_DISORDER_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECC_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE) == HITLS_SUCCESS); + + uint32_t sendLen = 6; + uint8_t sendBuf[6] = {0x14, 0x01, 0x01, 0x00, 0x01, 0x01}; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(server->ssl->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_DISORDER_TC003 +* @title During the handshake, the clientkeyexchange message is received when the client status is receiving the +* certificate. +* @precon nan +* @brief 1. Configure dual-end authentication. After the server sends a serverhellodone message, the client stops in +* the try send certificate state. Expected result 1. +* 2. Construct an unexpected clientkeyexchange message and send the message to the server. Expected result 2. +* @expect 1. The initialization succeeds. +* 2. The connection fails to be established and the server returns an unexpected message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_DISORDER_TC003(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECDHE_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static int32_t STUB_APP_Write_Fatal(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + (void)data; + (void)dataLen; + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_INTERNAL_EXCEPTION; +} + +/* @ + * @test UT_TLS_TLCP_CONSISTENCY_FATAL_ALERT_TC003 + * @title Session processing in the case of critical alarms. + * @precon nan + * @spec When a critical alarm is sent or received, both parties should immediately close the connection and discard + * the session ID and key of the incorrect connection. The connection closed by the critical alarm cannot be + * reused. + * @brief 1. Sending a fatal alert. Expected result 1. + * 2. The server sends a fatal alert, the session information is used for the next connection. + * Expected result 2. + * @expect 1. The server fails to send data and receive data. + * 2. The connection fails to be established. + @ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_FATAL_ALERT_TC003(char *cipherSuite, int isResume) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite(cipherSuite); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_SUCCESS); + + FuncStubInfo tmpRpInfo = { 0 }; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + HITLS_Session *Newsession = NULL; + HITLS_Session *serverSession = NULL; + uint32_t readLen = 0; + uint8_t data[] = "Hello World"; + STUB_Replace(&tmpRpInfo, APP_Write, STUB_APP_Write_Fatal); + ASSERT_EQ(HITLS_Write(server->ssl, data, sizeof(data)), HITLS_INTERNAL_EXCEPTION); + STUB_Reset(&tmpRpInfo); + ASSERT_TRUE(server->ssl->state == CM_STATE_ALERTED); + + if (isResume == 1) { + serverSession = HITLS_GetDupSession(server->ssl); + ASSERT_TRUE(serverSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, serverSession), 0); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + Newsession = HITLS_GetDupSession(client->ssl); + + ASSERT_TRUE(memcmp(serverSession->sessionId, Newsession->sessionId, HITLS_SESSION_ID_MAX_SIZE) != 0); + } else { + ASSERT_TRUE(HITLS_Write(server->ssl, data, sizeof(data)) == HITLS_CM_LINK_FATAL_ALERTED); + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_CM_LINK_FATAL_ALERTED); + } + + ASSERT_TRUE(HITLS_Close(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_CLOSED); +exit: + HITLS_SESS_Free(Newsession); + HITLS_SESS_Free(serverSession); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC001 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a connection between the client and server. Expected result 1. +* 2. The client closes the link, obtains the message sent by the client, and checks whether the message is a +* close_notify message. Expected result 2. +* 3. The server obtains the received message and checks whether the message is a close_notify message. +* Expected result 3. +* @expect 1. The link is successfully established. +* 2. The client sends a close_notify message. +* 3. The server receives the close_notify message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECDHE_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_KEY_EXCHANGE) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->recMsg.msg; + uint32_t serverreadLen = serverioUserData->recMsg.len; + uint32_t serverparseLen = 0; + ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC002 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a link between the client and server. Expected result 1. +* 2. The client closes the link, obtains the message sent by the client, and checks whether the message is a +* close_notify message. Expected result 2. +* 3. The server processes the message received by the server, obtains the message to be sent after processing, +* and checks whether the message is a close_notify message. Expected result 3. +* @expect 1. The link is successfully established. +* 2. The client sends a close_notify message. +* 3. The server sends a close_notify message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECDHE_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_KEY_EXCHANGE) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->recMsg.msg; + uint32_t serverreadLen = serverioUserData->recMsg.len; + uint32_t serverparseLen = 0; + ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(server->ssl != NULL); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_IO_BUSY); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_IO_BUSY); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_CM_LINK_FATAL_ALERTED); + + FRAME_Msg serverframeMsg1 = {0}; + uint8_t *serverbuffer1 = serverioUserData->sndMsg.msg; + uint32_t serverreadLen1 = serverioUserData->sndMsg.len; + uint32_t serverparseLen1 = 0; + ret = ParserTotalRecord(server, &serverframeMsg1, serverbuffer1, serverreadLen1, &serverparseLen1); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg1.type == REC_TYPE_ALERT && serverframeMsg1.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg1.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg1.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC003 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a connection between the client and server. Expected result 1. +* 2. The server closes the link, obtains the message sent by the server, +* and checks whether the message is a close_notify message. Expected result 2. +* 3. Obtain the received message and check whether the message is a close_notify message. Expected result 3. +* @expect 1. The link is successfully established. +* 2. The server sends a close_notify message. +* 3. The client receives the close_notify message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC003(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECDHE_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->sndMsg.msg; + uint32_t serverreadLen = serverioUserData->sndMsg.len; + uint32_t serverparseLen = 0; + int32_t ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC004 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a link between the client and server. Expected result 1. +* 2. The server closes the link, obtains the message sent by the server, +* and checks whether the message is a close_notify message. Expected result 2. +* 3. The client processes the received message, obtains the message to be sent after processing, +* and checks whether the message is a close_notify message. Expected result 3. +* @expect 1. The link is successfully established. +* 2. The client sends a close_notify message. +* 3. The server sends a close_notify message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC004(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite("HITLS_ECDHE_SM4_CBC_SM3"); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_FINISH) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->sndMsg.msg; + uint32_t serverreadLen = serverioUserData->sndMsg.len; + uint32_t serverparseLen = 0; + int32_t ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + clientioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(client->ssl != NULL); + clientioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_IO_BUSY); + clientioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_CM_LINK_FATAL_ALERTED); + + FRAME_Msg clientframeMsg1 = {0}; + uint8_t *clientbuffer1 = clientioUserData->sndMsg.msg; + uint32_t clientreadLen1 = clientioUserData->sndMsg.len; + uint32_t clientparseLen1 = 0; + ret = ParserTotalRecord(client, &clientframeMsg1, clientbuffer1, clientreadLen1, &clientparseLen1); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg1.type == REC_TYPE_ALERT); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_WARNING); + ASSERT_EQ(alert.description, ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ + * @test UT_TLS_TLCP_CONSISTENCY_AMEND_APPDATA_TC001 + * @title Modify the app message received by the client, modify the encrypted data, inject the message, + * and observe the response from the client. + * @precon nan + * @spec "AEADEncrypted = AEAD-Encrypt(write_ key, nonce, plaintext, additional data) To decrypt and verify, + * the cryptographic algorithm uses the key, random number, additional_data and AEADEncrypted values are used + * as inputs. The output is plaintext or an error indicating a decryption failure. There is no additional + * integrity check. I.e.: TLSCompressed. fragment= AEAD-Decrypt (write_key, nonce,AEADEncrypted, + * additional_data) A fatal bad_record_mac warning should be generated if decryption fails. See Appendix A for + * the GCM Authenticated Encryption Mode." + * @brief 1. Set up a link, read and write data, modify the app message received by the client, modify the encrypted + * data, and perform message injection. Observe the response from the client. Expected result 1. + * 2. Set up a link, read and write data, modify the app message received by the server, modify the encrypted + * data, and perform message injection. Observe the response of the server. Expected result 2. + * @expect 1. The bad_record_mac alert is sent. + * 2. The bad_record_mac alert is sent. + @ */ +/* BEGIN_CASE */ +void UT_TLS_TLCP_CONSISTENCY_AMEND_APPDATA_TC001(char *cipherSuite, int isClient) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t toSetCipherSuite = GetCipherSuite(cipherSuite); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + FRAME_LinkObj *client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + ASSERT_TRUE(client != NULL); + + FRAME_LinkObj *server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + FRAME_LinkObj *recver = isClient ? client : server; + FRAME_LinkObj *sender = isClient ? server : client; + + uint8_t data[] = "Hello World"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Write(sender->ssl, data, sizeof(data)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(sender, recver) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(recver->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLCP11; + frameType.recordType = REC_TYPE_APP; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_AppMsg *appMsg = &frameMsg.body.appMsg; + uint8_t appData[] = "123"; + appMsg->appData.state = ASSIGNED_FIELD; + ASSERT_EQ(memcpy_s(appMsg->appData.data, appMsg->appData.size, "123", sizeof(appData)), 0); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(recver->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_EQ(HITLS_Read(recver->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_BAD_RECORD_MAC); + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(recver->ssl, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_BAD_RECORD_MAC); + + ASSERT_TRUE(HITLS_Close(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_CLOSED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +/* @ + * @test UT_FRAME_FUNC_TLCP_CERT_MISMATCH_TC001 + * @title After receiving the servehellodone message from the server, the client checks whether the server certificate + * is valid and whether the parameters in the servehello message are acceptable. + * @precon nan + * @spec After receiving the servehellodone message from the server, the client verifies whether the server + * certificate is valid and whether the server's servehello message parameters are acceptable. If acceptable, + * the client continues the handshake process. Otherwise, a HandShakeFailure fatal alarm is sent. + * @brief 1. Set the algorithm suite to ECDHE_SM4_CBC_SM3 on the client and server, and load the RSA certificate to + * the server. Expected result 1. + * 2. Set the algorithm suite to ECC_SM4_CBC_SM3 on the client and server, and load the RSA certificate to + * the server. Expected result 2. + * @expect 1. The server fails to negotiate the cipher suite (the certificate and cipher suite do not match). + * 2. The server fails to negotiate the cipher suite (the certificate and cipher suite do not match). + @ */ +/* BEGIN_CASE */ +void UT_FRAME_FUNC_TLCP_CERT_MISMATCH_TC001(char *cipherSuite) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + FRAME_CertInfo certInfo = { + "sm2/ca.der", + "sm2/inter.der", + "rsa_sha256/server.der", + "sm2/sign.der", + "rsa_sha256/server.key.der", + "sm2/sign.key.der", + }; + + tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + uint16_t toSetCipherSuite = GetCipherSuite(cipherSuite); + HITLS_CFG_SetCipherSuites(tlsConfig, &toSetCipherSuite, 1); + + client = FRAME_CreateLinkWithCert(tlsConfig, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLinkWithCert(tlsConfig, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(server->ssl, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_HANDSHAKE_FAILURE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_3.data b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_3.data new file mode 100644 index 00000000..c9a6c2db --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_frame_tlcp_consistency_3.data @@ -0,0 +1,77 @@ +UT_TLS_TLCP_CONSISTENCY_SESSIONID_MISS_TC001 +UT_TLS_TLCP_CONSISTENCY_SESSIONID_MISS_TC001: + +UT_TLS_TLCP_CONSISTENCY_CLIENTKXCH_VERSIONERR_TC001 +UT_TLS_TLCP_CONSISTENCY_CLIENTKXCH_VERSIONERR_TC001:"HITLS_ECC_SM4_CBC_SM3" + +UT_TLS_TLCP_CONSISTENCY_KEY_EXCHANGE_TC001 +UT_TLS_TLCP_CONSISTENCY_KEY_EXCHANGE_TC001: + +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC001 +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC001: + +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC002 +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC002: + +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC003 +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC003: + +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC004 +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC004: + +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC005 +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC005: + +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC006 +UT_TLS_TLCP_CONSISTENCY_CERTFICATE_TC006: + +UT_TLS_TLCP_CONSISTENCY_CCS_TC006 +UT_TLS_TLCP_CONSISTENCY_CCS_TC006:0 + +UT_TLS_TLCP_CONSISTENCY_CCS_TC006 +UT_TLS_TLCP_CONSISTENCY_CCS_TC006:1 + +UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_001 +UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_001: + +UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_002 +UT_TLS_TLCP_CONSISTENCY_ERROR_FINISH_002: + +UT_TLS_TLCP_CONSISTENCY_DISORDER_TC001 +UT_TLS_TLCP_CONSISTENCY_DISORDER_TC001: + +UT_TLS_TLCP_CONSISTENCY_DISORDER_TC002 +UT_TLS_TLCP_CONSISTENCY_DISORDER_TC002: + +UT_TLS_TLCP_CONSISTENCY_DISORDER_TC003 +UT_TLS_TLCP_CONSISTENCY_DISORDER_TC003: + +UT_TLS_TLCP_CONSISTENCY_FATAL_ALERT_TC003 resume: 1, ciphersuite: HITLS_ECDHE_SM4_CBC_SM3 +UT_TLS_TLCP_CONSISTENCY_FATAL_ALERT_TC003:"HITLS_ECDHE_SM4_CBC_SM3":1 + +UT_TLS_TLCP_CONSISTENCY_FATAL_ALERT_TC003 resume: 0, ciphersuite: HITLS_ECDHE_SM4_CBC_SM3 +UT_TLS_TLCP_CONSISTENCY_FATAL_ALERT_TC003:"HITLS_ECDHE_SM4_CBC_SM3":0 + +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC001 +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC001: + +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC002 +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC002: + +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC003 +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC003: + +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC004 +UT_TLS_TLCP_CONSISTENCY_CLOSE_NOTIFY_TC004: + +UT_TLS_TLCP_CONSISTENCY_AMEND_APPDATA_TC001 TLCP link setup test not set client verify, ciphersuite: HITLS_ECDHE_SM4_CBC_SM3 +UT_TLS_TLCP_CONSISTENCY_AMEND_APPDATA_TC001:"HITLS_ECDHE_SM4_CBC_SM3":1 + +UT_TLS_TLCP_CONSISTENCY_AMEND_APPDATA_TC001 TLCP link setup test not set client verify, ciphersuite: HITLS_ECDHE_SM4_CBC_SM3 +UT_TLS_TLCP_CONSISTENCY_AMEND_APPDATA_TC001:"HITLS_ECDHE_SM4_CBC_SM3":0 + +UT_FRAME_FUNC_TLCP_CERT_MISMATCH_TC001 +UT_FRAME_FUNC_TLCP_CERT_MISMATCH_TC001:"HITLS_ECC_SM4_CBC_SM3" + +UT_FRAME_FUNC_TLCP_CERT_MISMATCH_TC001 +UT_FRAME_FUNC_TLCP_CERT_MISMATCH_TC001:"HITLS_ECDHE_SM4_CBC_SM3" \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_hlt_tlcp_consistency.c b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_hlt_tlcp_consistency.c new file mode 100644 index 00000000..17bc82d5 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_hlt_tlcp_consistency.c @@ -0,0 +1,1205 @@ +/* + * 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. + */ + /* BEGIN_HEADER */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "process.h" +#include "session_type.h" +#include "hitls_type.h" +#include "send_process.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "uio_base.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "app.h" +#include "hlt.h" +#include "alert.h" +#include "securec.h" +#include "record.h" +#include "rec_wrapper.h" +#include "conn_init.h" +#include "cert_callback.h" +#include "change_cipher_spec.h" +#include "common_func.h" +/* END_HEADER */ + +#define READ_BUF_SIZE (18 * 1024) /* Maximum length of the read message buffer */ +#define REC_TLS_RECORD_HEADER_LEN 5 /* recode header length */ +#define REC_CONN_SEQ_SIZE 8u /* SN size */ +#define PORT 11111 +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isServerExtendMasterSecret; + bool isSupportRenegotiation; /* Renegotiation support flag */ + bool needStopBeforeRecvCCS; /* For CCS test, stop at TRY_RECV_FINISH stage before CCS message is received. */ +} HandshakeTestInfo; + +int32_t GetSessionCacheMode(HLT_Ctx_Config* config) +{ + return config->setSessionCache; +} + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC001 +* @title Modify the resume flag on the client. Resumption fails +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Modify the resume flag and resume the session. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. Resumption fails +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC001(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + int32_t cachemode = 0; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + cachemode = GetSessionCacheMode(clientCtxConfig); + ASSERT_EQ(cachemode , HITLS_SESS_CACHE_SERVER); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + SESS_Disable(session); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == false); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt == 2) + { + HITLS_Session *Newsession = NULL; + Newsession = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(memcmp(session->sessionId, Newsession->sessionId, HITLS_SESSION_ID_MAX_SIZE) != 0); + HITLS_SESS_Free(Newsession); + } else { + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + cnt++; + } while (cnt <= 2); + +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC002 +* @title During session resumption, set none cipher suite. The resumption fails +* @precon nan +* @brief 1. Establish a connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. During session resumption, do not set the cipher suite and resume the session. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. Failed to resume the session. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC002(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + uint16_t sess_Ciphersuite; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + do { + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL ) { + HITLS_SESS_GetCipherSuite(session, &sess_Ciphersuite); + ASSERT_TRUE(HITLS_SESS_SetCipherSuite(session, 0) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_EQ(HLT_TlsConnect(clientSsl), HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE); + } else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + } + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt == 1) { + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + cnt++; + } while (cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC003 +* @title Session resume succeed +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. The client carries the session ID for first connection establishment and resumes the session. + The server sends the same session ID in the hello message. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. The session is resumed successfully +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC003(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + do { + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_EQ(HLT_TlsConnect(clientSsl), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_TRUE(HITLS_IsSessionReused(clientSsl, &isReused) == HITLS_SUCCESS); + ASSERT_TRUE(isReused == 1); + } else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + } + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt == 1) { + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + cnt++; + } while (cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC004 +* @title Use same session to resume two connections +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Use same session to resume two different connections at the same time. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. The session is resumed successfully on both connections at the same time +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC004(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + HLT_FD sockFd2 = {0}; + int count = 1; + + HITLS_Session *session = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + void *clientConfig2 = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(clientConfig2 != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *clientCtxConfig2 = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig2, clientCtxConfig2) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (session != NULL) { + DataChannelParam channelParam2; + channelParam2.port = PORT; + channelParam2.type = connType; + channelParam2.isBlock = true; + sockFd2 = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam2); + ASSERT_TRUE((sockFd2.srcFd > 0) && (sockFd2.peerFd > 0)); + remoteProcess->connType = connType; + localProcess->connType = connType; + remoteProcess->connFd = sockFd2.peerFd; + localProcess->connFd = sockFd2.srcFd; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig2); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + + HITLS_Session *Newsession = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(Newsession != NULL); + ASSERT_TRUE(memcmp(session->sessionId, Newsession->sessionId, HITLS_SESSION_ID_MAX_SIZE) == 0); + HITLS_SESS_Free(Newsession); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + HITLS_SESS_Free(session); + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + if (count == 2) { + uint8_t isReused = 0; + ASSERT_TRUE(HITLS_IsSessionReused(clientSsl, &isReused) == HITLS_SUCCESS); + ASSERT_TRUE(isReused == 1); + } + count++; + } while (count <= 2); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC005 +* @title Multiple connections can be established using the same session +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Use same session to resume three connections. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. The sessions are all resumed successfully +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC005(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + int32_t cachemode = 0; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + cachemode = GetSessionCacheMode(clientCtxConfig); + ASSERT_EQ(cachemode , HITLS_SESS_CACHE_SERVER); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt != 1) { + HITLS_Session *Newsession = NULL; + Newsession = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(memcmp(session->sessionId, Newsession->sessionId, HITLS_SESSION_ID_MAX_SIZE) == 0); + HITLS_SESS_Free(Newsession); + } else { + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + cnt++; + } while (cnt <= 4); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC006 +* @title Modify the session ID on the client. Resumption fails +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Modify the session ID and resume the session. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. Resumption fails +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC006(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + int32_t cachemode = 0; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + cachemode = GetSessionCacheMode(clientCtxConfig); + ASSERT_EQ(cachemode , HITLS_SESS_CACHE_SERVER); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + session->sessionId[0] -= 1; + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt == 2) { + HITLS_Session *Newsession = NULL; + Newsession = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(memcmp(session->sessionId, Newsession->sessionId, HITLS_SESSION_ID_MAX_SIZE) != 0); + HITLS_SESS_Free(Newsession); + } else { + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + cnt++; + } while (cnt <= 2); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC007 +* @title Modify the session cipher suite on the client. Resumption fails +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Modify the session cipher suite and resume the session. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. Resumption fails +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC007(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + int32_t cachemode = 0; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + uint16_t sess_Ciphersuite; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + cachemode = GetSessionCacheMode(clientCtxConfig); + ASSERT_EQ(cachemode , HITLS_SESS_CACHE_SERVER); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (cnt == 1) { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } else { + HITLS_SESS_GetCipherSuite(session, &sess_Ciphersuite); + if(sess_Ciphersuite == HITLS_ECC_SM4_CBC_SM3) { + ASSERT_TRUE(HITLS_SESS_SetCipherSuite(session, HITLS_ECDHE_SM4_CBC_SM3) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(HITLS_SESS_SetCipherSuite(session, HITLS_ECC_SM4_CBC_SM3) == HITLS_SUCCESS); + } + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE); + } + cnt++; + } while (cnt <= 2); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC008 +* @title Modify the session master key on the client. Resumption fails +* @precon nan +* @brief 1. Establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Modify the session master key and resume the session. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. Resumption fails +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC008(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + int32_t cachemode = 0; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + cachemode = GetSessionCacheMode(clientCtxConfig); + ASSERT_EQ(cachemode , HITLS_SESS_CACHE_SERVER); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (session != NULL) { + session->masterKey[0] -= 1; + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (cnt == 1) { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } else { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_EQ(HLT_TlsConnect(clientSsl), HITLS_REC_BAD_RECORD_MAC); + } + cnt++; + } while (cnt <= 2); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_TRANSPORT_FUNC_TC01(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + ASSERT_TRUE(serverCtxConfig != NULL); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLCP1_1, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + ASSERT_TRUE(clientCtxConfig != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLCP1_1, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + uint8_t writeBuf[READ_BUF_SIZE] = {0}; + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, writeBuf, 16384) == 0); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == 16384); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009 +* @title set the session cache mode on the client server. try to Resumption +* @precon nan +* @brief 1. Configure the session cache mode establish the connection. Expected result 1 + 2. Perform the first handshake, obtain and save the session. Expected result 2 + 3. Try resume the session. Expected result 3 +* @expect 1. Return success + 2. The handshake is complete and obtain the session successfully + 3. HITLS_SESS_CACHE_NO and HITLS_SESS_CACHE_CLIENT resumption fails, otherwise successful +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009(int mode) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + int cnt = 1; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, TLCP1_1, false); + void *clientConfig = HLT_TlsNewCtx(TLCP1_1); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + + HLT_SetSessionCacheMode(clientCtxConfig, mode); + HLT_SetSessionCacheMode(serverCtxConfig, mode); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + do{ + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = TCP; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = TCP; + localProcess->connType = TCP; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = TCP; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = TCP; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + ASSERT_EQ(HLT_TlsConnect(clientSsl) , 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt == 2) { + if (mode == HITLS_SESS_CACHE_NO || mode == HITLS_SESS_CACHE_CLIENT){ + uint8_t isReused = -1; + HITLS_IsSessionReused(clientSsl, &isReused); + ASSERT_TRUE(isReused == 0); + } else { + uint8_t isReused = -1; + HITLS_IsSessionReused(clientSsl, &isReused); + ASSERT_TRUE(isReused == 1); + } + } else { + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + }cnt++; + }while(cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +#define ALERT_BODY_LEN 2u /* Alert data length */ +static int32_t SendAlert(HITLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + uint8_t data[ALERT_BODY_LEN]; + /** Obtain the alert level. */ + data[0] = level; + data[1] = description; + /** Write records. */ + int32_t ret = REC_Write(ctx, REC_TYPE_ALERT, data, ALERT_BODY_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +/* BEGIN_CASE */ +void SDV_TLS_TLCP1_1_LEVEL_UNKNOWN_ALERT_TC001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportClientVerify = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_CLIENT_KEY_EXCHANGE) == HITLS_SUCCESS); + + ASSERT_TRUE(SendAlert(client->ssl, ALERT_LEVEL_UNKNOWN, ALERT_NO_RENEGOTIATION) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + HITLS_Ctx *Ctx = FRAME_GetTlsCtx(server); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(Ctx, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_TLCP1_1_LEVEL_UNKNOWN_ALERT_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportClientVerify = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + + ASSERT_TRUE(SendAlert(server->ssl, ALERT_LEVEL_UNKNOWN, ALERT_DECODE_ERROR) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + HITLS_Ctx *Ctx = FRAME_GetTlsCtx(client); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(Ctx, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_hlt_tlcp_consistency.data b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_hlt_tlcp_consistency.data new file mode 100644 index 00000000..eb626a8b --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tlcp/test_suite_sdv_hlt_tlcp_consistency.data @@ -0,0 +1,44 @@ +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC001 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC001:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC002 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC002:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC003 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC003:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC004 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC004:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC005 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC005:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC006 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC006:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC007 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC007:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC008 +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC008:TLCP1_1:TCP + +SDV_TLS_TLCP_CONSISTENCY_TRANSPORT_FUNC_TC01 +SDV_TLS_TLCP_CONSISTENCY_TRANSPORT_FUNC_TC01: + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009 HITLS_SESS_CACHE_NO +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009:HITLS_SESS_CACHE_NO + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009 HITLS_SESS_CACHE_CLIENT +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009:HITLS_SESS_CACHE_CLIENT + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009 HITLS_SESS_CACHE_SERVER +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009:HITLS_SESS_CACHE_SERVER + +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009 HITLS_SESS_CACHE_BOTH +SDV_TLS_TLCP_CONSISTENCY_RESUME_FUNC_TC009:HITLS_SESS_CACHE_BOTH + +SDV_TLS_TLCP1_1_LEVEL_UNKNOWN_ALERT_TC001 +SDV_TLS_TLCP1_1_LEVEL_UNKNOWN_ALERT_TC001: + +SDV_TLS_TLCP1_1_LEVEL_UNKNOWN_ALERT_TC002 +SDV_TLS_TLCP1_1_LEVEL_UNKNOWN_ALERT_TC002: diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246.c new file mode 100644 index 00000000..b62b25d6 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246.c @@ -0,0 +1,5218 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls12_consistency_rfc5246 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "securec.h" +#include "rec_wrapper.h" +#include "conn_init.h" +#include "cert_callback.h" +#include "change_cipher_spec.h" +#include "common_func.h" +#include "uio_base.h" +/* END_HEADER */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC001 +* @title Verify that the server receives a 0-length Client Hello message and the expected alert is returned. +* @precon nan +* @brief 1. Create a config and client link, and construct a 0-length client hello message. +* Expected result 1 is obtained. +* 2. The server invokes the HITLS_Accept interface. (Expected result 2) +* @expect 1. A success message is returned. +* 2. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC001(void) +{ + // Create a config and client link, and construct a 0-length client hello message. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->extensionState = MISSING_FIELD; + clientMsg->version.state = MISSING_FIELD; + clientMsg->randomValue.state = MISSING_FIELD; + clientMsg->sessionIdSize.state = MISSING_FIELD; + clientMsg->sessionId.state = MISSING_FIELD; + clientMsg->cookiedLen.state = MISSING_FIELD; + clientMsg->cookie.state = MISSING_FIELD; + clientMsg->cipherSuitesSize.state = MISSING_FIELD; + clientMsg->cipherSuites.state = MISSING_FIELD; + clientMsg->compressionMethodsLen.state = MISSING_FIELD; + clientMsg->compressionMethods.state = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + // The server invokes the HITLS_Accept interface. + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC002 +* @title Verify that the client receives a serverhello message with a length of 0 and the expected alert is returned. +* @precon nan +* @brief 1. Create a config and server link, and construct a 0-length server hello message. +* Expected result 1 is obtained. +* 2. The client invokes the HITLS_Connect interface. (Expected result 2) +* @expect 1. A success message is returned. +* 2. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC002(void) +{ + // Create a config and server link, and construct a 0-length server hello message. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->version.state = MISSING_FIELD; + serverMsg->randomValue.state = MISSING_FIELD; + serverMsg->sessionIdSize.state = MISSING_FIELD; + serverMsg->sessionId.state = MISSING_FIELD; + serverMsg->cipherSuite.state = MISSING_FIELD; + serverMsg->compressionMethod.state = MISSING_FIELD; + serverMsg->extensionLen.state = MISSING_FIELD; + serverMsg->pointFormats.exState = MISSING_FIELD; + serverMsg->extendedMasterSecret.exState = MISSING_FIELD; + serverMsg->secRenego.exState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + /* The client invokes the HITLS_Connect interface. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC003 +* @title The client receives a Certificate message with a length of zero. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained +* 2. Construct a zero-length Certificate message and send it to the client. Expected result 2 is obtained +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message with the level of ALERT_Level_FATAL and description of ALERT_DECODE_ERROR +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC003(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Construct a zero-length Certificate message and send it to the client. */ + FRAME_CertificateMsg *certifiMsg = &frameMsg.body.hsMsg.body.certificate; + certifiMsg->certsLen.state = MISSING_FIELD; + certifiMsg->certItem->state = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC004 +* @title The client receives a Server Key Exchange message whose length is 0. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained +* 2. Construct a zero-length Server Key Exchange message and send it to the client. +* Expected result 2 is obtained +* @expect 1. The initialization is successful +* 2. The client sends an ALERT message. The level is ALERT_LEVEL_FATAL and the description is ALERT_DECODE_ERROR +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC004(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_SERVER_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Construct a zero-length Server Key Exchange message and send it to the client. */ + FRAME_ServerKeyExchangeMsg *serverKeyExMsg = &frameMsg.body.hsMsg.body.serverKeyExchange; + serverKeyExMsg->keyEx.ecdh.curveType.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.namedcurve.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.pubKeySize.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.pubKey.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.signAlgorithm.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.signSize.state = MISSING_FIELD; + serverKeyExMsg->keyEx.ecdh.signData.state = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC005 +* @title The server receives a Client Key Exchange message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a zero-length Client Key Exchange message and send it to the server. +* Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message. The level is ALERT_LEVEL_FATAL and the description is ALERT_DECODE_ERROR +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC005(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + // Construct a zero-length Client Key Exchange message and send it to the server. + FRAME_ClientKeyExchangeMsg *clientKeyExMsg = &frameMsg.body.hsMsg.body.clientKeyExchange; + clientKeyExMsg->pubKey.state = MISSING_FIELD; + clientKeyExMsg->pubKeySize.state = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC006 +* @title The server receives a Change Cipher Spec message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained +* 2. Construct a Change Cipher Spec message with zero length and send it to the server. +* Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC006(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_CERTIFICATE_VERIFY; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + FRAME_Msg frameMsg1 = { 0 }; + FRAME_Type frameType1 = { 0 }; + frameType1.versionType = HITLS_VERSION_TLS12; + frameType1.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType1.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType1, &frameMsg1) == HITLS_SUCCESS); + + // Construct a Change Cipher Spec message with zero length and send it to the server. + FRAME_CcsMsg *CcsMidMsg = &frameMsg1.body.ccsMsg; + CcsMidMsg->ccsType.state = MISSING_FIELD; + CcsMidMsg->extra.state = MISSING_FIELD; + CcsMidMsg->extra.size = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType1, &frameMsg1, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData1->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType1, &frameMsg1); + memset_s(&frameMsg1, sizeof(frameMsg1), 0, sizeof(frameMsg1)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_BAD_RECORD_MAC); + + ioUserData1 = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData1->sndMsg.msg; + uint32_t sndLen = ioUserData1->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType1.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType1, sndBuf, sndLen, &frameMsg1, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg1.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg1.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + +exit: + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC007 +* @title The client receives a Change Cipher Spec message with a length of 0 and the data is encrypted. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained +* 2. Construct a Change Cipher Spec message with zero length and send it to the client. +* Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC007(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_NEW_SESSION_TICKET; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + FRAME_Msg frameMsg1 = { 0 }; + FRAME_Type frameType1 = { 0 }; + frameType1.versionType = HITLS_VERSION_TLS12; + frameType1.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType1.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType1, &frameMsg1) == HITLS_SUCCESS); + + // Construct a Change Cipher Spec message with zero length and send it to the client. + FRAME_CcsMsg *CcsMidMsg = &frameMsg1.body.ccsMsg; + CcsMidMsg->ccsType.state = MISSING_FIELD; + CcsMidMsg->extra.state = MISSING_FIELD; + CcsMidMsg->extra.size = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType1, &frameMsg1, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData1->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType1, &frameMsg1); + memset_s(&frameMsg1, sizeof(frameMsg1), 0, sizeof(frameMsg1)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_BAD_RECORD_MAC); + + ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData1->sndMsg.msg; + uint32_t sndLen = ioUserData1->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_EQ(FRAME_ParseMsgHeader(&frameType1, sndBuf, sndLen, &frameMsg1, &parseLen), 0); + + ASSERT_TRUE(frameMsg1.recType.data == REC_TYPE_ALERT); + +exit: + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC008 +* @title The client receives a SERVER_HELLO_DONE message whose length is 0 and expects to return an alert message +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained +* 2. Construct a SERVER_HELLO_DONE message with a zero length, and send the message to the client. +* Expected result 2 is obtained +* @expect 1. The initialization is successful +* 2. The client sends an ALERT message +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC008(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO_DONE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO_DONE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + // Construct a SERVER_HELLO_DONE message with a zero length, and send the message to the client. + FRAME_ServerHelloDoneMsg *serverHelloDone = &frameMsg.body.hsMsg.body.serverHelloDone; + serverHelloDone->extra.state = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC001 +* @title An unexpected message is received when the client is in the TRY_RECV_CERTIFICATIONATE +* state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. +* The level is ALERT_LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC001(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // Construct a Server Hello message and send it to the client. + FRAME_Msg parsedSHdone = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, SERVER_HELLO_DONE, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &parsedSHdone) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSHdone, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &parsedSHdone); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &parsedSHdone, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedSHdone.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedSHdone.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &parsedSHdone); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC002 +* @title An unexpected message is received when the client is in the TRY_RECV_CERTIFICATIONATE state +* during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. +* The level is ALERT_LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC002(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // Construct a Server Hello message and send it to the client. + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC003 +* @title An unexpected message is received when the client is in the TRY_RECV_SERVER_KEY_EXCHANGE state +* during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. +* The level is ALERT_LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC003(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_SERVER_KEY_EXCHANGE; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // Construct a Server Hello message and send it to the client. + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC004 +* @title An unexpected message is received when the client is in the TRY_RECV_SERVER_HELLO_DONE state +* during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. The level is +* ALERT_LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC004(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO_DONE; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // Construct a Server Hello message and send it to the client. + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC005 +* @title An unexpected message is received when the client is in the TRY_RECV_FINISH state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. +* The level is ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC005(void) +{ + // Use the default configuration items to configure the client and server. + // Construct a Server Hello message and send it to the client. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg parsedAlert = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + testInfo.client->ssl->hsCtx->state = TRY_RECV_FINISH; + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(sndBuf, sndLen, &parsedAlert, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC006 +* @title An unexpected message is received when the client is in the TRY_RECV_CERTIFICATE_REQUEST +* state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT. +* The level is ALERT_LEVEL_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC006(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_CERTIFICATE_REQUEST; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // Construct a Server Hello message and send it to the client. + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC007 +* @title An unexpected message is received when the client is in the TRY_RECV_NEW_SESSION_TICKET state +* during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a Server Hello message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the Server Hello message, the client sends an ALERT message. +* The level is ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC007(void) +{ + // Use the default configuration items to configure the client and server. + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // Construct a Server Hello message and send it to the client. + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + testInfo.client->ssl->hsCtx->state = TRY_RECV_NEW_SESSION_TICKET; + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC008 +* @title An unexpected message is received when the server is in the TRY_RECV_CLIENT_HELLO state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a CLIENT_KEY_EXCHANGE message and send it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT. +* The level is ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC008(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Construct a CLIENT_KEY_EXCHANGE message and send it to the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + testInfo.server->ssl->hsCtx->state = TRY_RECV_CLIENT_HELLO; + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC009 +* @title An unexpected message is received when the server is in the TRY_RECV_CERTIFICATIONATE +* state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a CLIENT_KEY_EXCHANGE message and send it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC009(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Construct a CLIENT_KEY_EXCHANGE message and send it to the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + testInfo.server->ssl->hsCtx->state = TRY_RECV_CERTIFICATE; + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC010 +* @title An unexpected message is received when the server is in TRY_RECV_CLIENT_KEY_EXCHANGE state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a SERVER_HELLO message and send it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the SERVER_HELLO message, the server sends an ALERT. The level is ALERT_Level_FATAL and the +* description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC010(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Construct a SERVER_HELLO message and send it to the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + testInfo.server->ssl->hsCtx->state = TRY_RECV_CLIENT_KEY_EXCHANGE; + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} + +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC011 +* @title An unexpected message is received when the server is in the TRY_RECV_CERTIFICATIONATE_VERIFY state during the +* handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a CLIENT_KEY_EXCHANGE message and send it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +* ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC011(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Construct a CLIENT_KEY_EXCHANGE message and send it to the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + testInfo.server->ssl->hsCtx->state = TRY_RECV_CERTIFICATE_VERIFY; + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC012 +* @title An unexpected message is received when the server is in the TRY_RECV_FINISH state during the handshake. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a CLIENT_KEY_EXCHANGE message and send it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the CLIENT_KEY_EXCHANGE message, the server sends an ALERT message. The level is +ALERT_Level_FATAL and the description is ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC012(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Construct a CLIENT_KEY_EXCHANGE message and send it to the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + testInfo.server->ssl->hsCtx->state = TRY_RECV_FINISH; + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_AEAD_EXPLICIT_IV_LENGTH_TC001 +* @title The client and server establish a connection. Check whether the sequence number in the APP message is +* contained in the record-layer message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. A TLS over TCP link is established between the client and server. Expected result 2 is obtained. +* 3. Randomly generate a 32-bit transmission data. Expected result 3 is obtained. +* 4. Randomly generate a serial number. Expected result 4 is obtained. +* 5. Write app data to the server. +* 6. Data transmission at the record layer. +* 7. Check the changes before and after the sequence number is sent. +* 8. Record layer data receiving. +* @expect 1. The initialization is successful. +* 2. The link is set up successfully. +* 3. The generation is successful. +* 4. The generation is successful. +* 5. The writing is successful. +* 6. Transmission is successful. +* 7. After the sending, the seqNum is increased by 1. +* 8. The data length and data content are verified successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_AEAD_EXPLICIT_IV_LENGTH_TC001() +{ + /* Use the default configuration items to configure the client and server. */ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = HS_STATE_BUTT; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* A TLS over TCP link is established between the client and server. */ + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_TRANSPORTING); + + /* Randomly generate a 32-bit transmission data. */ + uint8_t transportData[REC_CONN_SEQ_SIZE * 4] = {0}; + uint32_t transportDataLen = sizeof(transportData) / sizeof(uint8_t); + ASSERT_EQ(RandBytes(transportData, transportDataLen), HITLS_SUCCESS); + /* Randomly generate a serial number. */ + uint8_t randSeq[REC_CONN_SEQ_SIZE] = {0}; + ASSERT_EQ(RandBytes(randSeq, REC_CONN_SEQ_SIZE), HITLS_SUCCESS); + REC_Ctx *recCtx = (REC_Ctx *)testInfo.server->ssl->recCtx; + recCtx->writeStates.currentState->seq = BSL_ByteToUint64(randSeq); + uint64_t sequenceNumber = recCtx->writeStates.currentState->seq; + uint8_t seq[REC_CONN_SEQ_SIZE] = {0}; + BSL_Uint64ToByte(sequenceNumber, seq); + + /* Write app data to the server. */ + int32_t ret = APP_Write(testInfo.server->ssl, transportData, transportDataLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + /* Data transmission at the record layer. */ + uint8_t tmpData[MAX_RECORD_LENTH] = {0}; + uint32_t tmpLen; + ASSERT_TRUE(FRAME_TransportSendMsg(testInfo.server->io, tmpData, MAX_RECORD_LENTH, &tmpLen) == HITLS_SUCCESS); + + /* Check the changes before and after the sequence number is sent. */ + recCtx = (REC_Ctx *)testInfo.server->ssl->recCtx; + uint64_t sequenceNumberAfterSend = recCtx->writeStates.currentState->seq; + ASSERT_EQ(sequenceNumberAfterSend, sequenceNumber + 1); + + /* Record layer data receiving. */ + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, tmpData, tmpLen) == HITLS_SUCCESS); + const int32_t AEAD_TAG_LEN = 16u; + ASSERT_EQ(tmpLen, REC_TLS_RECORD_HEADER_LEN + REC_CONN_SEQ_SIZE + transportDataLen + AEAD_TAG_LEN); + + ASSERT_TRUE(memcmp(tmpData + REC_TLS_RECORD_HEADER_LEN, seq, REC_CONN_SEQ_SIZE) == 0); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC001 +* @title Observe the changes in the status of the record layer before and after the client receives the CCS message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client to stop the client in the TRY_RECV_FINISH +state. Expected result 1 is obtained. +* 2. Record the states at the record layer that the client reads. Expected result 2 is obtained. +* 3. Reconnect the client. Expected result 3 is obtained. +* 4. Check the states at the record layer after the client is reconnected. Expected result 4 is obtained. +* @expect 1. The initialization is successful. +* 2. The outdatedState field is empty. +* 3. The return value for reconnection is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* 4. OutdatedState is the previous currentState. +* currentState is the previous pendingState. +* The pendingState field is empty. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC001() +{ + /* Use the default configuration items to configure the client to stop the client in the TRY_RECV_FINISH state. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = true; + testInfo.state = TRY_RECV_FINISH; + testInfo.needStopBeforeRecvCCS = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Record the states at the record layer that the client reads. */ + RecConnStates *readStates = (RecConnStates *)&(testInfo.client->ssl->recCtx->readStates); + RecConnState *oldOutdatedState = readStates->outdatedState; + RecConnState *oldCurrentState = readStates->currentState; + RecConnState *oldPendingState = readStates->pendingState; + ASSERT_TRUE(oldOutdatedState == NULL); + + // Reconnect the client. + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + /* Check the states at the record layer after the client is reconnected. */ + RecConnState *newOutdatedState = readStates->outdatedState; + RecConnState *newCurrentState = readStates->currentState; + RecConnState *newPendingState = readStates->pendingState; + + ASSERT_TRUE(newOutdatedState == oldCurrentState); + ASSERT_TRUE(newCurrentState == oldPendingState); + ASSERT_TRUE(newPendingState == NULL); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC002 +* @title Check the status change of the record layer before and after the server receives the CCS message. +* @precon nan +* @brief 1. Use the default configuration items to set the server to the TRY_RECV_FINISH state. Expected result 1 is +obtained. +* 2. Record the states of the record layer that the client reads. Expected result 2 is obtained. +* 3. Reconnect the server. Expected result 3 is obtained. +* 4. Check the states at the record layer after the client is reconnected. Expected result 4 is obtained. +* @expect 1. The initialization is successful. +* 2. OutdatedState is empty. +* 3. The return value for reconnection is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* 4. OutdatedState is the previous currentState. +* currentState is the previous pendingState. +* The pendingState field is empty. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC002() +{ + /* Use the default configuration items to set the server to the TRY_RECV_FINISH state. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = false; + testInfo.state = TRY_RECV_FINISH; + testInfo.needStopBeforeRecvCCS = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Record the states of the record layer that the client reads. */ + RecConnStates *readStates = (RecConnStates *)&(testInfo.server->ssl->recCtx->readStates); + RecConnState *oldOutdatedState = readStates->outdatedState; + RecConnState *oldCurrentState = readStates->currentState; + RecConnState *oldPendingState = readStates->pendingState; + ASSERT_TRUE(oldOutdatedState == NULL); + + // Reconnect the server. + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + /* Check the states at the record layer after the client is reconnected. */ + RecConnState *newOutdatedState = readStates->outdatedState; + RecConnState *newCurrentState = readStates->currentState; + RecConnState *newPendingState = readStates->pendingState; + ASSERT_TRUE(newOutdatedState == oldCurrentState); + ASSERT_TRUE(newCurrentState == oldPendingState); + ASSERT_TRUE(newPendingState == NULL); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC001 +* @title Observe the change of the write record layer status before and after the client sends the CCS message. +* @precon nan +* @brief 1. Use the default configuration items to set the server to the TRY_RECV_FINISH state. Expected result 1 is +obtained. +* 2. Record the states of the client write record layer. Expected result 2 is obtained. +* 3. Reconnect the server. Expected result 3 is obtained. +* 4. Check the states of the write record layer after the client is reconnected. Expected result 4 is obtained. +* @expect 1. The initialization is successful. +* 2. The outdatedState field is empty. +* 3. The return value for reconnection is HITLS_REC_NORMAL_IO_BUSY. +* 4. OutdatedState is the previous currentState. +* currentState is the previous pendingState. +* The pendingState field is empty. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC001() +{ + /* Use the default configuration items to set the server to the TRY_RECV_FINISH state. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = true; + testInfo.state = TRY_SEND_CHANGE_CIPHER_SPEC; + testInfo.needStopBeforeRecvCCS = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Record the states of the client write record layer. */ + RecConnStates *writeStates = (RecConnStates *)&(testInfo.client->ssl->recCtx->writeStates); + RecConnState *oldOutdatedState = writeStates->outdatedState; + RecConnState *oldCurrentState = writeStates->currentState; + RecConnState *oldPendingState = writeStates->pendingState; + ASSERT_TRUE(oldOutdatedState == NULL); + + // Reconnect the server. + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_IO_BUSY); + + /* Check the states of the write record layer after the client is reconnected. */ + RecConnState *newOutdatedState = writeStates->outdatedState; + RecConnState *newCurrentState = writeStates->currentState; + RecConnState *newPendingState = writeStates->pendingState; + ASSERT_TRUE(newOutdatedState == oldCurrentState); + ASSERT_TRUE(newCurrentState == oldPendingState); + ASSERT_TRUE(newPendingState == NULL); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC002 +* @title Observe the change of the write record layer status before and after the server sends the CCS message. +* @precon nan +* @brief 1. Use the default configuration items to configure the server to stop the server in the TRY_RECV_FINISH +state. Expected result 1 is obtained. +* 2. Record the states at the write record layer on the client. Expected result 2 is obtained. +* 3. Reconnect the server. Expected result 3 is obtained. +* 4. Check the states of the write record layer after the client is reconnected. Expected result 4 is obtained. +* @expect 1. The initialization is successful. +* 2. The outdatedState field is empty. +* 3. The return value for reconnection is HITLS_REC_NORMAL_IO_BUSY. +* 4. OutdatedState is the previous currentState. +* currentState is the previous pendingState. +* The pendingState field is empty. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC002() +{ + /* Use the default configuration items to configure the server to stop the server in the TRY_RECV_FINISH state. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = false; + testInfo.state = TRY_SEND_CHANGE_CIPHER_SPEC; + testInfo.needStopBeforeRecvCCS = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Record the states at the write record layer on the client. */ + RecConnStates *writeStates = (RecConnStates *)&(testInfo.server->ssl->recCtx->writeStates); + RecConnState *oldOutdatedState = writeStates->outdatedState; + RecConnState *oldCurrentState = writeStates->currentState; + RecConnState *oldPendingState = writeStates->pendingState; + ASSERT_TRUE(oldOutdatedState == NULL); + + // Reconnect the server. + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + + /* Check the states of the write record layer after the client is reconnected. */ + RecConnState *newOutdatedState = writeStates->outdatedState; + RecConnState *newCurrentState = writeStates->currentState; + RecConnState *newPendingState = writeStates->pendingState; + ASSERT_TRUE(newOutdatedState == oldCurrentState); + ASSERT_TRUE(newCurrentState == oldPendingState); + ASSERT_TRUE(newPendingState == NULL); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_MASTEKEY_TC001 +* @title Check whether the master key changes before and after the client initiates renegotiation. +* @precon nan +* @brief 1. Use the default configuration items to configure the server so that the connection is successfully +established. Expected result 1 is obtained. +* 2. Simulate link establishment and check the TLS_Ctx and CM_State on both ends. Expected result 2 is obtained. +* 3. Obtain the current session from the client. Expected result 3 is obtained. +* 4. Obtain the masterKey from the session ID of the client. Expected result 4 is obtained. +* 5. The server sends a Hello Request message. Expected result 5 is obtained. +* 6. Reconnect the client and retransmit data on the server. Expected result 6 is obtained. +* 7. Obtain the new masterKey based on the client session ID and compare it with the old masterKey. Expected +result 7 is obtained. +* @expect 1. The initialization is successful. +* 2. The link is set up successfully. TLS_Ctx is not empty and CM_State is Transporting. +* 3. The session is not empty. +* 4. Obtained successfully. +* 5. The message is sent successfully. +* 6. The connection is successful. +* 7. The data is obtained successfully and the comparison is consistent. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_MASTEKEY_TC001() +{ + /* Use the default configuration items to configure the server so that the connection is successfully established. + */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = true; + testInfo.isSupportRenegotiation = true; + testInfo.state = HS_STATE_BUTT; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Simulate link establishment and check the TLS_Ctx and CM_State on both ends. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_TRANSPORTING); + + /* Obtain the current session from the client. */ + HITLS_Session *session = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(session != NULL); + + /* Obtain the masterKey from the session ID of the client. */ + uint8_t masterkey1[MAX_MASTER_KEY_SIZE] = {0}; + uint32_t masterkey1Len = MAX_MASTER_KEY_SIZE; + ASSERT_TRUE(HITLS_SESS_GetMasterKey(session, masterkey1, &masterkey1Len) == HITLS_SUCCESS); + + /* The server sends a Hello Request message. */ + ASSERT_TRUE(HITLS_Renegotiate(testInfo.server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Accept(testInfo.server->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + + /* Reconnect the client and retransmit data on the server. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_RENEGOTIATION); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_EQ(testInfo.client->ssl->state, CM_STATE_TRANSPORTING); + + /* Obtain the new masterKey based on the client session ID and compare it with the old masterKey. */ + uint8_t masterkey2[MAX_MASTER_KEY_SIZE] = {0}; + uint32_t masterkey2Len = MAX_MASTER_KEY_SIZE; + HITLS_Session *session2 = HITLS_GetDupSession(testInfo.client->ssl); + uint32_t masterkeylen = HITLS_SESS_GetMasterKeyLen(session2); + ASSERT_TRUE(HITLS_SESS_GetMasterKey(session2, masterkey2, &masterkey2Len) == HITLS_SUCCESS); + ASSERT_TRUE(memcmp(masterkey1, masterkey2, masterkeylen) != 0); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + HITLS_SESS_Free(session); + HITLS_SESS_Free(session2); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC001 +* @title Check whether the sequence number in the record layer in the FINISH message sent by the server or client is 0. +* @precon nan +* @brief 1. Configure the client/server to stay in the TRY_SEND_FINISH state. Expected result 1 is obtained. +* 2. Connect the server and client once and send the message. Expected result 2 is obtained. +* 3. Obtain the messages sent by the server or client. Expected result 3 is obtained. +* 4. Parse the message sent by the local end into the hs_msg structure. Expected result 4 is obtained. +* 5. Check the sequence number in the sent message. Expected result 5 is obtained. +* 6. Enable the local end to transmit data to the peer end. Expected result 6 is obtained. +* 7. Obtain the messages received by the peer end. Expected result 7 is obtained. +* 8. Parse the message received by the peer end into the hs_msg structure. Expected result 8 is obtained. +* 9. Check the sequence number in the received message. Expected result 5 is obtained. +* @expect 1. The initialization is successful. +* 2. If the server is successfully connected, the client returns NORMAL_RECV_BUF_EMPTY. +* 3. The sending length is not null. +* 4. The parsing is successful, and the message header length is fixed to 5 bytes (TLS1.2). +* 5. The serial number is zero. +* 6. The transmission is successful. +* 7. The received length is not empty. +* 8. The parsing succeeds and the message header length is fixed to 5 bytes (TLS1.2). +* 9. The serial number is zero. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC001(int isClient) +{ + /* Configure the client/server to stay in the TRY_SEND_FINISH state. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = TRY_SEND_FINISH; + testInfo.isClient = isClient; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Connect the server and client once and send the message. */ + if (isClient) { + ASSERT_TRUE(HITLS_Connect(testInfo.client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + } else { + ASSERT_TRUE(HITLS_Accept(testInfo.server->ssl) == HITLS_SUCCESS); + } + + /* Obtain the messages sent by the server or client. */ + BSL_UIO *sendIo = isClient ? testInfo.client->io : testInfo.server->io; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(sendIo); + uint8_t *sendBuf = ioUserData->sndMsg.msg; + uint32_t sendLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sendLen != 0); + + /* Parse the message sent by the local end into the hs_msg structure. */ + uint32_t parseLen = 0; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, sendBuf, sendLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == REC_TLS_RECORD_HEADER_LEN); + + /* Check the sequence number in the sent message. */ + uint8_t seqBuf[REC_CONN_SEQ_SIZE] = {0}; + ASSERT_TRUE(memcpy_s(seqBuf, sendLen, sendBuf + REC_TLS_RECORD_HEADER_LEN, REC_CONN_SEQ_SIZE) == 0); + uint64_t seq = BSL_ByteToUint64(seqBuf); + ASSERT_EQ(seq, 0u); + + /* Enable the local end to transmit data to the peer end. */ + if (isClient) { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + } + + /* Obtain the messages received by the peer end. */ + BSL_UIO *recvIo = isClient ? testInfo.server->io : testInfo.client->io; + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(recvIo); + uint8_t *recvBuf = ioUserData2->recMsg.msg; + uint32_t recvLen = ioUserData2->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + /* Parse the message received by the peer end into the hs_msg structure. */ + uint32_t parseLen2 = 0; + FRAME_Msg frameMsg2 = { 0 }; + FRAME_Type frameType2 = { 0 }; + frameType2.versionType = HITLS_VERSION_TLS12; + frameType2.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType2, recvBuf, recvLen, &frameMsg2, &parseLen2) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen2 == REC_TLS_RECORD_HEADER_LEN); + + /* Check the sequence number in the received message. */ + ASSERT_TRUE(memset_s(seqBuf, REC_CONN_SEQ_SIZE, 0, REC_CONN_SEQ_SIZE) == 0); + ASSERT_TRUE(memcpy_s(seqBuf, recvLen, recvBuf + REC_TLS_RECORD_HEADER_LEN, REC_CONN_SEQ_SIZE) == 0); + uint64_t seq2 = BSL_ByteToUint64(seqBuf); + ASSERT_EQ(seq2, 0u); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_CleanMsg(&frameType2, &frameMsg2); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC002 +* @title Check whether the sequence number in the record layer in the FINISH message sent by the server/client is 0. +* @precon nan +* @brief 1. Configure the client/server to the status that the handshake is successful. Expected result 1 is obtained. +* 2. Check the server/client connection status. Expected result 2 is obtained. +* 3. Randomly generate 32 bytes of data to be transmitted. Expected result 3 is obtained. +* 4. Write app data. Expected result 4 is obtained. + 5. Obtain data from the I/O sent by the local end and parse the header and content. Expected result 5 is +obtained. + 6. Check the sequence number in the sent message. Expected result 6 is obtained. + 7. Perform I/O data transmission from the local end to the peer end. Expected result 7 is obtained. + 8. Obtain data from the received I/O from the peer end and parse the header and content. Expected result 8 is +obtained. + 9. Check the sequence number in the received message. Expected result 9 is obtained. +* @expect 1. The initialization is successful. +* 2. The link status is Transferring. + 3. The generation is successful. + 4. The writing is successful. + 5. The parsing is successful, and the value of RecordType is REC_TYPE_APP. + 6. The SN is 1. + 7. The transmission is successful. + 8. The parsing is successful, and the value of RecordType is REC_TYPE_APP. + 9. The serial number is 1. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC002(int isClient) +{ + /* Configure the client/server to the status that the handshake is successful. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = HS_STATE_BUTT; + testInfo.isClient = isClient; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + /* Check the server/client connection status. */ + ASSERT_TRUE(testInfo.client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(testInfo.server->ssl->state == CM_STATE_TRANSPORTING); + + /* Randomly generate 32 bytes of data to be transmitted. */ + uint8_t transportData[REC_CONN_SEQ_SIZE * 4] = {0}; + uint32_t transportDataLen = sizeof(transportData) / sizeof(uint8_t); + ASSERT_EQ(RandBytes(transportData, transportDataLen), HITLS_SUCCESS); + /* Write app data. */ + HITLS_Ctx *localSsl = isClient ? testInfo.client->ssl : testInfo.server->ssl; + ASSERT_EQ(APP_Write(localSsl, transportData, transportDataLen), HITLS_SUCCESS); + + /* Obtain data from the I/O sent by the local end and parse the header and content. */ + BSL_UIO *sendIo = isClient ? testInfo.client->io : testInfo.server->io; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(sendIo); + uint8_t *sendBuf = ioUserData->sndMsg.msg; + uint32_t sendLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sendLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, sendBuf, sendLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == REC_TLS_RECORD_HEADER_LEN); + ASSERT_TRUE(FRAME_ParseMsgBody(&frameType, sendBuf + parseLen, sendLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameType.recordType, REC_TYPE_APP); + + /* Check the sequence number in the sent message. */ + uint8_t seqBuf[REC_CONN_SEQ_SIZE] = {0}; + ASSERT_TRUE(memcpy_s(seqBuf, sendLen, sendBuf + REC_TLS_RECORD_HEADER_LEN, REC_CONN_SEQ_SIZE) == 0); + uint64_t seq = BSL_ByteToUint64(seqBuf); + ASSERT_EQ(seq, 1u); + + /* Perform I/O data transmission from the local end to the peer end. */ + if (isClient) { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + } + + /* Obtain data from the received I/O from the peer end and parse the header and content. */ + BSL_UIO *recvIo = isClient ? testInfo.server->io : testInfo.client->io; + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(recvIo); + uint8_t *recvBuf = ioUserData2->recMsg.msg; + uint32_t recvLen = ioUserData2->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen2 = 0; + FRAME_Msg frameMsg2 = { 0 }; + FRAME_Type frameType2 = { 0 }; + frameType2.versionType = HITLS_VERSION_TLS12; + frameType2.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType2, recvBuf, recvLen, &frameMsg2, &parseLen2) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen2 == REC_TLS_RECORD_HEADER_LEN); + ASSERT_TRUE(FRAME_ParseMsgBody(&frameType2, recvBuf + parseLen2, recvLen, &frameMsg2, &parseLen2) == HITLS_SUCCESS); + ASSERT_EQ(frameType.recordType, REC_TYPE_APP); + + /* Check the sequence number in the received message. */ + ASSERT_TRUE(memset_s(seqBuf, REC_CONN_SEQ_SIZE, 0, REC_CONN_SEQ_SIZE) == 0); + ASSERT_TRUE(memcpy_s(seqBuf, recvLen, recvBuf + REC_TLS_RECORD_HEADER_LEN, REC_CONN_SEQ_SIZE) == 0); + uint64_t seq2 = BSL_ByteToUint64(seqBuf); + ASSERT_EQ(seq2, 1u); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_CleanMsg(&frameType2, &frameMsg2); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC001 +* @title After initialization, the server receives a CCS message after sending the serverhellodone message and expects +to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +Expected result 1 is obtained. +* 2. The client initiates a TLS link application. After sending the Server Hello Done message, the server +constructs a CCS message and sends it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC001(void) +{ + /* Use the default configuration on the client and server, and disable peer verification on the server. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + /* The client initiates a TLS link application. After sending the Server Hello Done message, the server constructs a + * CCS message and sends it to the server. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC002 +* @title After initialization, the client receives a CCS message after sending a client hello message and expects to +return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +Expected result 1 is obtained. +* 2. The client initiates a TLS link application. After sending the client hello message, the client constructs +a CCS message and sends it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC002(void) +{ + /* Use the default configuration on the client and server, and disable peer verification on the server. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + /* The client initiates a TLS link application. After sending the client hello message, the client constructs a CCS + * message and sends it to the client. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC003 +* @title During link establishment, the client receives the serverhello message after sending the CCS and expects to +return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +Expected result 1 is obtained. +* 2. The client initiates a TLS link application. After sending the CCS, the client constructs a serverhello +message and sends it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC003(void) +{ + /* Use the default configuration on the client and server, and disable peer verification on the server. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_SEND_CHANGE_CIPHER_SPEC; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = false; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + testInfo.client->ssl->hsCtx->state = TRY_RECV_FINISH; + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_EQ(FRAME_GetDefaultMsg(&frameType, &frameMsg), HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + /* The client initiates a TLS link application. After sending the CCS, the client constructs a serverhello message + * and sends it to the client. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC004 +* @title After initialization, construct an app message and send it to the client. The expected alert is returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable the peer end verification function on +the server. Expected result 1 is obtained. +* 2. When the client initiates a TLS link application request, construct an APP message and send it to the +client in the RECV_SERVER_HELLO message. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC004(void) +{ + /* Use the default configuration on the client and server, and disable the peer end verification function on the + * server. */ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = true; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportClientVerify = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == 0); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ(memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), + EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + /* When the client initiates a TLS link application request, construct an APP message and send it to the client in + * the RECV_SERVER_HELLO message. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(frameMsg.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC005 +* @title After the link is set up, the client receives the serverhello message when receiving the app data. The client +is expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +Expected result 1 is obtained. +* 2. The client initiates a TLS link request. After the handshake succeeds, construct a serverhello message and +send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC005(void) +{ + /* Use the default configuration on the client and server, and disable peer verification on the server. */ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + /* The client initiates a TLS link request. After the handshake succeeds, construct a serverhello message and send + * it to the client. */ + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_BAD_RECORD_MAC); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_EQ(FRAME_ParseMsgHeader(&frameType, sndBuf, sndLen, &frameMsg, &parseLen), 0); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC006 +* @title After the link is established, renegotiation is not enabled. The server receives a client hello message and is +expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server. Expected result 1 is obtained. +* 2. After the client initiates a TLS link request and handshakes successfully, construct a client hello message +and send it to the server. Expected result 2 is displayed. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC006(void) +{ + /* Use the default configuration on the client and server. */ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + /* After the client initiates a TLS link request and handshakes successfully, construct a client hello message and + * send it to the server. */ + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_INVALID_PROTOCOL_VERSION); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_EQ(FRAME_ParseMsgHeader(&frameType, sndBuf, sndLen, &frameMsg, &parseLen), 0); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC007 +* @title After initialization, construct an app message and send it to the server. The expected alert is returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable the peer end verification function on +the server. Expected result 1 is obtained. +* 2. When the client initiates a TLS link application request, construct an APP message and send it to the +server in the RECV_CLIENT_HELLO message on the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC007(void) +{ + /* Use the default configuration on the client and server, and disable the peer end verification function on the + * server. Expected result 1 is obtained. */ + FRAME_Msg parsedAlert = { 0 }; + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = false; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportClientVerify = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == 0); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ(memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), + EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + /* When the client initiates a TLS link application request, construct an APP message and send it to the server in + * the RECV_CLIENT_HELLO message on the server. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(sndBuf, sndLen, &parsedAlert, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(parsedAlert.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_RECV_APPDATA_TC001 +* @title Before the first handshake, no app message is received. +* @precon nan +* @brief During the first handshake, the client/server receives the app message when expecting to receive the finish +message. The expected handshake fails and the handshake is interrupted. +* @expect 1. Return a failure message and interrupt the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_RECV_APPDATA_TC001(int isClient) +{ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + HandshakeTestInfo testInfo = { 0 }; + testInfo.isClient = isClient; + testInfo.state = TRY_RECV_FINISH; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == 0); + + FrameUioUserData *ioUserData = + isClient ? BSL_UIO_GetUserData(testInfo.client->io) : BSL_UIO_GetUserData(testInfo.server->io); + + uint8_t data[MAX_RECORD_LENTH] = {0}; + /* application data record header construction + 17 - type is 0x17 (application data) + 03 03 - protocol version is "3,3" (TLS 1.2) + 00 02 - 2 bytes of application data follows */ + uint8_t appdataRecordHeader[] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, MAX_RECORD_LENTH, appdataRecordHeader, sizeof(appdataRecordHeader)), EOK); + ASSERT_EQ(memcpy_s(data + sizeof(appdataRecordHeader), MAX_RECORD_LENTH - sizeof(appdataRecordHeader), + ioUserData->recMsg.msg, ioUserData->recMsg.len), + EOK); + uint32_t constructLen = ioUserData->recMsg.len + sizeof(appdataRecordHeader); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, constructLen), EOK); + ioUserData->recMsg.len = constructLen; + /* During the first handshake, the client/server receives the app message when expecting to receive the finish + * message. */ + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, isClient, HS_STATE_BUTT), + HITLS_REC_BAD_RECORD_MAC); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC001 +* @title Send a hello request when the link status is CM_STATE_IDLE. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a HelloRequest message and send it to the client. The client invokes the HITLS_Connect interface +to receive the message. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the HelloRequest message, the client ignores the message and stays in the +TRY_RECV_SERVER_HELLO state after sending the ClientHello message. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC001(void) +{ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TLS_IDLE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + + FRAME_Init(); + + /* Use the configuration items to configure the client and server. */ + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(testInfo.config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.client != NULL); + + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + // Construct a HelloRequest message and send it to the client. + ASSERT_TRUE(SendHelloReq(testInfo.server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state == TRY_RECV_SERVER_HELLO); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC002 +* @title The server sends a Hello Request message after the client sends the client hello message. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Construct a HelloRequest message and send it to the client. The client invokes the HITLS_Connect interface +to receive the message. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. After receiving the HelloRequest message, the client ignores the message and stays in the +TRY_RECV_SERVER_HELLO state. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC002(void) +{ + /* Use the configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_SEND_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + + /* Construct a HelloRequest message and send it to the client. */ + ASSERT_TRUE(SendHelloReq(testInfo.server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_HANDSHAKING); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_SERVER_HELLO); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC003 +* @title The server sends a Hello Request message when preparing to send CCS messages. +* @precon nan +* @brief 1. Use configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client invokes HITLS_Connect in the Try_SEND_FINISH phase. Expected result 2 is obtained. +* 3. Construct a HelloRequest message and send it to the client. The client invokes HITLS_Connect to receive the +message. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends a FINISH message, changes the status to TRY_RECV_NEW_SESSION_TICKET, and returns +HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* 3. After receiving the HelloRequest message, the client ignores the message and stays in the +TRY_RECV_NEW_SESSION_TICKET state. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC003(void) +{ + /* Use configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_SEND_FINISH; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + /* The client invokes HITLS_Connect in the Try_SEND_FINISH phase. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + + /* Construct a HelloRequest message and send it to the client. The client invokes HITLS_Connect to receive the + * message. */ + ASSERT_TRUE(SendHelloReq(testInfo.server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_HANDSHAKING); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_NEW_SESSION_TICKET); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC004 +* @title The server sends a hello request when the link status is CM_STATE_TRANSPORTING. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The server sends a hello request to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT_NO_RENEGOTIATION message successfully, but the client can continue sending and +receiving data. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC004(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + /* Use the configuration items to configure the client and server. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + /* The server sends a hello request to the client. */ + ASSERT_TRUE(SendHelloReq(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->sndMsg.len = 1; + ASSERT_TRUE(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTING); + + ioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(server->ssl->state == CM_STATE_TRANSPORTING); + + uint8_t data[] = "Hello World"; + ASSERT_EQ(HITLS_Write(server->ssl, data, sizeof(data)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen) == HITLS_SUCCESS); + ASSERT_TRUE(readLen == sizeof(data) && memcmp(data, readBuf, readLen) == 0); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC005 +* @title The server sends a hello request when the link status is CM_STATE_RENEGOTIATION. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server to support renegotiation. Expected result 1 +is displayed. +* 2. After the link is established, the client sends a Hello Request message. The client receives the +renegotiation request message and is in the renegotiation state. At this time, the server sends a Hello Request message +again. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The expected message is sent successfully but is ignored. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC005(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + /* Use the configuration items to configure the client and server to support renegotiation. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + /* After the link is established, the client sends a Hello Request message. The client receives the renegotiation + * request message and is in the renegotiation state. At this time, the server sends a Hello Request message again. + */ + ASSERT_TRUE(SendHelloReq(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->sndMsg.len = 1; + ASSERT_TRUE(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_RENEGOTIATION); + + ioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_RENEGOTIATION); + ASSERT_TRUE(client->ssl->hsCtx->state = TRY_SEND_CLIENT_HELLO); + + ASSERT_TRUE(SendHelloReq(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(client->ssl->hsCtx->state = TRY_RECV_SERVER_HELLO); + +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC006 +* @title Enable the client and server to support renegotiation. After the connection between the client and server is +established, the client and server send a Hello Request message. +* @precon nan +* @brief 1. Configure the client and server to support renegotiation. Expected result 1 is displayed. +* 2. After the link is established, the server sends the Hello Request message successfully. +* @expect 1. The initialization is successful. +* 2. The client enters the renegotiation state and sends client hello. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC006(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + + /* Configure the client and server to support renegotiation. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + /* After the link is established, the server sends the Hello Request message successfully. */ + ASSERT_TRUE(SendHelloReq(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->sndMsg.len = 1; + ASSERT_TRUE(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_RENEGOTIATION); + + ioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_RENEGOTIATION); + ASSERT_TRUE(client->ssl->hsCtx->state = TRY_SEND_CLIENT_HELLO); + +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC007 +* @title The server receives a Hello Request message after sending the server hello done message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. After sending a Server Hello Done message, the server receives a Hello Request message. Expected result 2 +is obtained. +* @expect 1. The initialization is successful. +* 2. The server sends an ALERT. The level is ALERT_LEVEL_FATAL, and the description is +ALERT_UNEXPECTED_MESSAGE. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC007(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg parsedAlert = { 0 }; + testInfo.state = TRY_SEND_SERVER_HELLO_DONE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + + /* After sending a Server Hello Done message, the server receives a Hello Request message. */ + ASSERT_TRUE(SendHelloReq(testInfo.client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(sndBuf, sndLen, &parsedAlert, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC008 +* @title The server sends a Hello Request message after sending the finish message. The renegotiation is successful. +The server sends a Hello Request message again. The renegotiation is successful. +* @precon nan +* @brief 1. Configure the client and server to support renegotiation. Expected result 1 is displayed. +* 2. Send a Hello Request message after the server sends a finish message. Expected result 2 is obtained. +* 3. The server sends a Hello Request message again. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +* 2. The renegotiation succeeds. +* 3. The client ignores the Hello Request message and continues the renegotiation. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC008(void) +{ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_FINISH; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + + FRAME_Init(); + + /* Configure the client and server to support renegotiation. */ + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + testInfo.config->isSupportRenegotiation = true; + + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.client != NULL); + + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, testInfo.state) == + HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_SUCCESS); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_TRANSPORTING); + + /* Send a Hello Request message after the server sends a finish message. */ + ASSERT_TRUE(SendHelloReq(testInfo.server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->sndMsg.len = 1; + ASSERT_TRUE(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_RENEGOTIATION); + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state = TRY_SEND_CLIENT_HELLO); + + /* The server sends a Hello Request message again. */ + ASSERT_TRUE(SendHelloReq(testInfo.server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state = TRY_RECV_SERVER_HELLO); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_VERSION_TC001 +* @title Check the TLS protocol version carried in the clientHello message. +* @precon nan +* @brief 1. Use configuration items to configure the client and server. Set the maximum version number of the client to +TLS1.2 and the minimum version number to TLS1.1. Expected result 1 is obtained. +* 2. Obtain and parse the client Hello message. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The protocol version carried in the client Hello message is TLS1.2. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_VERSION_TC001(void) +{ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + + FRAME_Init(); + + /* Use configuration items to configure the client and server. Set the maximum version number of the client to + * TLS1.2 and the minimum version number to TLS1.1. */ + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + testInfo.config->minVersion = HITLS_VERSION_TLS11; + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.client != NULL); + + testInfo.config->minVersion = HITLS_VERSION_TLS12; + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, testInfo.state) == + HITLS_SUCCESS); + /* Obtain and parse the client Hello message. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + uint32_t parseLen = 0; + + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(clientMsg->version.data == HITLS_VERSION_TLS12); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_NOT_SUPPORT_SERVER_VERSION_TC001 +* @title The client does not support the version selected by the server. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server. Expected result 1 is obtained. +* 2. After receiving the Server Hello message, the client changes the TLS version field in the serverhello +message to DTLS1.2 and sends the message to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. The level is ALERT_ LEVEL_FATAL and the description is +ALERT_PROTOCOL_VERSION. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_NOT_SUPPORT_SERVER_VERSION_TC001(void) +{ + /* Use the configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* After receiving the Server Hello message, the client changes the TLS version field in the serverhello message to + * DTLS1.2 and sends the message to the client. */ + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->version.data = HITLS_VERSION_DTLS12; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_PROTOCOL_VERSION); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_CHOSE_VERSION_TC001 +* @title Check the TLS protocol version carried in the serverHello message. +* @brief 1. Use the configuration items to configure the client and server. Set the maximum version number of the +client to TLS1.3 and the minimum version number to TLS1.1, +* Set the maximum version number of the server to TLS1.2 and the minimum version number to TLS1.1. Expected +result 1 is obtained. +* 2. Obtain and parse the server Hello message. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The protocol version carried in the server Hello message is TLS1.2. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_CHOSE_VERSION_TC001(void) +{ + /* Use the configuration items to configure the client and server. + Set the maximum version number of the client to TLS1.3 and the minimum version number to TLS1.1; + Set the maximum version number of the server to TLS1.2 and the minimum version number to TLS1.1. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLSConfig(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + testInfo.config->maxVersion = HITLS_VERSION_TLS13; + testInfo.config->minVersion = HITLS_VERSION_TLS11; + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.client != NULL); + + testInfo.config->maxVersion = HITLS_VERSION_TLS12; + testInfo.config->minVersion = HITLS_VERSION_TLS11; + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, testInfo.state) == + HITLS_SUCCESS); + /* Obtain and parse the server Hello message. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + uint32_t parseLen = 0; + + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->version.data == HITLS_VERSION_TLS12); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_DEFAULT_SIGNATURE_EXTENSION_TC001 +* @title HITLS If no signature algorithm is specified, select the default algorithm and check whether the extension is +carried. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Check whether the client Clienet Hello message carries the signature algorithm extension. +* @expect 1. The initialization is successful. +* 2. Expected carrying expansion + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_DEFAULT_SIGNATURE_EXTENSION_TC001(void) +{ + /* Use the configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Check whether the client Clienet Hello message carries the signature algorithm extension. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(clientMsg->signatureAlgorithms.exState == INITIAL_FIELD); + ASSERT_TRUE(&frameMsg.body.handshakeMsg.body.clientHello.extension.flag.haveSignatureAlgorithms); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC001 +* @title Default processing logic of the signature algorithm +* @precon nan +* @brief 1. Use configuration items to configure the client and server, and set the client and service cipher suite to +HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. Expected result 1 is obtained. +* 2. Modify the client hello message so that the message does not carry the signature algorithm extension. Then, +the link is established. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The signature algorithm in the server key exchange message sent by the server is +CERT_SIG_SCHEME_ECDSA_SHA1. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC001(void) +{ + /* Use configuration items to configure the client and server, and set the client and service cipher suite to + * HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}; + ASSERT_EQ(HITLS_CFG_SetCipherSuites(testInfo.config, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)), + HITLS_SUCCESS); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + ASSERT_TRUE(StatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Modify the client hello message so that the message does not carry the signature algorithm extension. Then, the + * link is established. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->signatureAlgorithms.exState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + testInfo.state = TRY_RECV_SERVER_KEY_EXCHANGE; + testInfo.isClient = true; + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, testInfo.state), + HITLS_SUCCESS); + + ASSERT_EQ(testInfo.client->ssl->hsCtx->state, TRY_RECV_SERVER_KEY_EXCHANGE); + + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf2 = ioUserData2->recMsg.msg; + uint32_t recvLen2 = ioUserData2->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf2, recvLen2, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerKeyExchangeMsg *serverMsg = &frameMsg.body.hsMsg.body.serverKeyExchange; + ASSERT_EQ(serverMsg->keyEx.ecdh.signAlgorithm.data, CERT_SIG_SCHEME_ECDSA_SHA1); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC002 +* @title Default processing logic of the signature algorithm +* @precon nan +* @brief 1. Use the configuration items to configure the client and server, and set the client and service cipher suite +to HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA. Expected result 1 is obtained. +* 2. Modify the client hello message so that the message does not carry the signature algorithm extension. Then, +the link is established. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The signature algorithm in the server keyexchange message sent by the server is +CERT_SIG_SCHEME_RSA_PKCS1_SHA1. + +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC002(void) +{ + /* Use the configuration items to configure the client and server, and set the client and service cipher suite to + * HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}; + ASSERT_EQ(HITLS_CFG_SetCipherSuites(testInfo.config, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)), + HITLS_SUCCESS); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + ASSERT_TRUE(StatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Modify the client hello message so that the message does not carry the signature algorithm extension. Then, the + * link is established. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->signatureAlgorithms.exState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + testInfo.state = TRY_RECV_SERVER_KEY_EXCHANGE; + testInfo.isClient = true; + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, testInfo.state), + HITLS_SUCCESS); + + ASSERT_EQ(testInfo.client->ssl->hsCtx->state, TRY_RECV_SERVER_KEY_EXCHANGE); + + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf2 = ioUserData2->recMsg.msg; + uint32_t recvLen2 = ioUserData2->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_KEY_EXCHANGE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf2, recvLen2, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ServerKeyExchangeMsg *serverMsg = &frameMsg.body.hsMsg.body.serverKeyExchange; + ASSERT_EQ(serverMsg->keyEx.ecdh.signAlgorithm.data, CERT_SIG_SCHEME_RSA_PKCS1_SHA1); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC001 +* @title server can receive any version field in the recordheader of the client hello. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Change the version field in the recod header of the client hello message to 0x03ff. +* @expect 1. The initialization is successful. +* 2. The server can process the message normally and enter the next state. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC001(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo.config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + ASSERT_TRUE(StatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen != 5); + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == 5); + + /* Change the version field in the recod header of the client hello message to 0x03ff. */ + frameMsg.recVersion.data = 0x0300; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, recvBuf, recvLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(testInfo.server->ssl->hsCtx->state, TRY_SEND_CERTIFICATE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC002 +* @title server can receive any version field in the recordheader of the client hello. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Change the version field in the recod header of the client hello message to 0x03ff. +* @expect 1. The initialization is successful. +* 2. The server can process the message normally and enter the next state. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC002(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo.config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + ASSERT_TRUE(StatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen != 5); + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parseLen == 5); + + /* Change the version field in the recod header of the client hello message to 0x03ff. */ + frameMsg.recVersion.data = 0x03ff; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, recvBuf, recvLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(testInfo.server->ssl->hsCtx->state, TRY_SEND_CERTIFICATE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC003 +* @title server can receive any version field in the recordheader of the client hello message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. Change the version field in the recod header of the client hello message to 0x0399. +* @expect 1. The initialization is successful. +* 2. The server can process the message normally and enter the next state. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC003(void) +{ + /* Use the default configuration items to configure the client and server. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo.config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo.config->isSupportExtendMasterSecret = testInfo.isSupportExtendMasterSecret; + testInfo.config->isSupportClientVerify = testInfo.isSupportClientVerify; + testInfo.config->isSupportNoClientCert = testInfo.isSupportNoClientCert; + + ASSERT_TRUE(StatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + // The record length must be greater than or equal to 5 bytes. + ASSERT_TRUE(parseLen >= 5); + ASSERT_TRUE(FRAME_ParseTLSRecordHeader(recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + // The length of the record header must be 5 bytes. + ASSERT_TRUE(parseLen == 5); + + /* Change the version field in the recod header of the client hello message to 0x0399. */ + frameMsg.recVersion.data = 0x0399; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, recvBuf, recvLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(testInfo.server->ssl->hsCtx->state, TRY_SEND_CERTIFICATE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* Define a new structure, +Construct the SH message with the signatureAlgorithms extension added, +Actually, the SH message should not contain the signatureAlgorithms. +*/ +typedef struct { + FRAME_Integer version; /* Version number */ + FRAME_Array8 randomValue; /* Random number */ + FRAME_Integer sessionIdSize; /* session ID length */ + FRAME_Array8 sessionId; /* session ID */ + FRAME_Integer cipherSuite; /* Cipher suite */ + FRAME_Integer compressionMethod; /* Compression method */ + FRAME_Integer extensionLen; /* Total length of the extension. */ + + FRAME_HsExtArray8 pointFormats; /* dot format */ + FRAME_HsExtArray8 extendedMasterSecret; /* extended master key */ + FRAME_HsExtArray8 secRenego; /* security renegotiation */ + FRAME_HsExtArray8 sessionTicket; /* sessionTicket */ + + FRAME_HsExtArray16 signatureAlgorithms; /* algorithm signature */ +} FRAME_ServerHelloMsg_WithSignatureAlgorithms; + +void SetServerHelloMsgWithSignatureAlgorithms(FRAME_ServerHelloMsg_WithSignatureAlgorithms *destMsg, + const FRAME_ServerHelloMsg *serverMsg) +{ + destMsg->version = serverMsg->version; + destMsg->randomValue = serverMsg->randomValue; + destMsg->sessionIdSize = serverMsg->sessionIdSize; + destMsg->sessionId = serverMsg->sessionId; + destMsg->cipherSuite = serverMsg->cipherSuite; + destMsg->compressionMethod = serverMsg->compressionMethod; + destMsg->extensionLen = serverMsg->extensionLen; + + destMsg->pointFormats = serverMsg->pointFormats; + destMsg->extendedMasterSecret = serverMsg->extendedMasterSecret; + destMsg->secRenego = serverMsg->secRenego; + destMsg->sessionTicket = serverMsg->sessionTicket; +} + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_HELLO_ADD_SIGNATURE_TC001 +* @title The server attempts to send the signatureAlgorithms extension. +* @precon nan +* @brief 1. Use the configuration items to configure the client and server, and obtain the clientHello and serverHello +respectively. Expected result 1 is obtained. +* 2. Define a new structure, load the serverHello into the new structure, add the signatureAlgorithms extension +from the clientHello, and send the extension to the client. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. The level is ALERT_ LEVEL_FATAL and the description is +ALERT_UNSUPPORTED_EXTENSION. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_HELLO_ADD_SIGNATURE_TC001(void) +{ + /* Use the configuration items to configure the client and server, and obtain the clientHello and serverHello + * respectively. */ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData_c = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvSHbuf = ioUserData_c->recMsg.msg; + uint32_t recvSHbufLen = ioUserData_c->recMsg.len; + ASSERT_TRUE(recvSHbufLen != 0); + + uint32_t parsedSHlen = 0; + FRAME_Msg parsedSH = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvSHbuf, recvSHbufLen, &parsedSH, &parsedSHlen) == HITLS_SUCCESS); + + HandshakeTestInfo testInfo2 = { 0 }; + testInfo2.state = TRY_RECV_CLIENT_HELLO; + testInfo2.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo2) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData_s = BSL_UIO_GetUserData(testInfo2.server->io); + uint8_t *recvCHbuf = ioUserData_s->recMsg.msg; + uint32_t recvCHbufLen = ioUserData_s->recMsg.len; + ASSERT_TRUE(recvCHbufLen != 0); + + /* Define a new structure, load the serverHello into the new structure, add the signatureAlgorithms extension from + * the clientHello, and send the extension to the client. */ + uint32_t parsedCHlen = 0; + FRAME_Msg parsedCH = { 0 }; + FRAME_Type frameType2 = { 0 }; + SetFrameType(&frameType2, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType2, recvCHbuf, recvCHbufLen, &parsedCH, &parsedCHlen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *chMsg = &parsedCH.body.hsMsg.body.clientHello; + ASSERT_TRUE(chMsg->signatureAlgorithms.exState == INITIAL_FIELD); + FRAME_ServerHelloMsg *shMsg = &parsedSH.body.hsMsg.body.serverHello; + + FRAME_ServerHelloMsg_WithSignatureAlgorithms shWithSigAlgExt; + SetServerHelloMsgWithSignatureAlgorithms(&shWithSigAlgExt, shMsg); + + uint32_t sigAlgNum = chMsg->signatureAlgorithms.exData.size; + uint16_t *chSigAlgData = chMsg->signatureAlgorithms.exData.data; + uint32_t chSigAlgDataSize = sigAlgNum * sizeof(uint16_t); + memcpy_s(&shWithSigAlgExt.signatureAlgorithms, sizeof(FRAME_HsExtArray16), &(chMsg->signatureAlgorithms), + sizeof(FRAME_HsExtArray16)); + shWithSigAlgExt.signatureAlgorithms.exData.data = calloc(sigAlgNum, sizeof(uint16_t)); + memcpy_s(shWithSigAlgExt.signatureAlgorithms.exData.data, chSigAlgDataSize, chSigAlgData, chSigAlgDataSize); + memcpy_s(&parsedSH.body.hsMsg.body.serverHello, sizeof(FRAME_ServerHelloMsg_WithSignatureAlgorithms), + &shWithSigAlgExt, sizeof(FRAME_ServerHelloMsg_WithSignatureAlgorithms)); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData_c->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_UNSUPPORTED_EXTENSION); + + ioUserData_c = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf_c = ioUserData_c->sndMsg.msg; + uint32_t sndBufLen_c = ioUserData_c->sndMsg.len; + ASSERT_TRUE(sndBufLen_c != 0); + + uint32_t parsedAlertLen = 0; + FRAME_Msg parsedAlert = { 0 }; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(sndBuf_c, sndBufLen_c, &parsedAlert, &parsedAlertLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNSUPPORTED_EXTENSION); + +exit: + FRAME_CleanMsg(&frameType, &parsedSH); + FRAME_CleanMsg(&frameType2, &parsedCH); + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo2.client); + FRAME_FreeLink(testInfo2.server); + HITLS_CFG_FreeConfig(testInfo2.config); +} +/* END_CASE */ + +void Test_RenegoWrapperFunc(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.body.clientHello.secRenego.exState, INITIAL_FIELD); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + + +void Test_RenegoRemoveExtension(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + ASSERT_EQ(parseLen, *len); + frameMsg.body.hsMsg.body.clientHello.secRenego.exState = MISSING_FIELD; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + + +int32_t g_writeRet; +uint32_t g_writeLen; +bool g_isUseWriteLen; +uint8_t g_writeBuf[REC_TLS_RECORD_HEADER_LEN + REC_MAX_CIPHER_TEXT_LEN]; +int32_t STUB_MethodWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + (void)uio; + + if (memcpy_s(g_writeBuf, sizeof(g_writeBuf), buf, len) != EOK) { + return BSL_MEMCPY_FAIL; + } + + *writeLen = len; + if (g_isUseWriteLen) { + *writeLen = g_writeLen; + } + return g_writeRet; +} + +int32_t g_readRet; +uint32_t g_readLen; +uint8_t g_readBuf[REC_TLS_RECORD_HEADER_LEN + REC_MAX_CIPHER_TEXT_LEN + 1]; +int32_t STUB_MethodRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + (void)uio; + + if (g_readLen != 0 && memcpy_s(buf, len, g_readBuf, g_readLen) != EOK) { + return BSL_MEMCPY_FAIL; + } + + *readLen = g_readLen; + return g_readRet; +} + +int32_t g_ctrlRet; +BSL_UIO_CtrlParameter g_ctrlCmd; +int32_t STUB_MethodCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param) +{ + (void)larg; + (void)uio; + (void)param; + if ((int32_t)g_ctrlCmd == cmd) { + return g_ctrlRet; + } + + return BSL_SUCCESS; +} + +HITLS_Config *g_tlsConfig = NULL; +HITLS_Ctx *g_tlsCtx = NULL; +BSL_UIO *g_uio = NULL; +int32_t TlsCtxNew(BSL_UIO_TransportType type) +{ + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + BSL_UIO *uio = NULL; + const BSL_UIO_Method *ori = NULL; + switch (type) { + case BSL_UIO_TCP: + ori = BSL_UIO_TcpMethod(); + break; + default: + ori = BSL_UIO_SctpMethod(); + break; + } + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + BSL_UIO_Method method = { 0 }; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_MethodWrite; + method.read = STUB_MethodRead; + method.ctrl = STUB_MethodCtrl; + + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL); + BSL_UIO_SetInit(uio, 1); + ASSERT_TRUE(HITLS_SetUio(ctx, uio) == HITLS_SUCCESS); + + /* Default value of stub function */ + g_writeRet = HITLS_SUCCESS; + g_writeLen = 0; + g_isUseWriteLen = false; + + g_readLen = 0; + g_readRet = HITLS_SUCCESS; + + g_tlsConfig = config; + g_tlsCtx = ctx; + g_uio = uio; + return HITLS_SUCCESS; +exit: + BSL_UIO_Free(uio); + HITLS_Free(ctx); + HITLS_CFG_FreeConfig(config); + return HITLS_INTERNAL_EXCEPTION; +} + +void TlsCtxFree(void) +{ + BSL_UIO_Free(g_uio); + HITLS_Free(g_tlsCtx); + HITLS_CFG_FreeConfig(g_tlsConfig); + + g_uio = NULL; + g_tlsCtx = NULL; + g_tlsConfig = NULL; +} + +#define BUFFER_SIZE 128 +#define UT_AEAD_NONCE_SIZE 12u /* AEAD nonce is fixed to 12. */ +#define UT_AEAD_TAG_LENGTH 16 + +ALERT_Level g_alertLevel; +ALERT_Description g_alertDescription; +void STUB_SendAlert(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + (void)ctx; + g_alertLevel = level; + g_alertDescription = description; + return; +} + +typedef struct { + REC_Type type; + uint16_t version; + uint64_t epochSeq; + uint16_t bodyLen; + uint8_t *body; +} RecordMsg; + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; /* Set the session to the client for session recovery. */ +} ResumeTestInfo; + +static uint8_t *g_sessionId; +static uint32_t g_sessionIdSize; + +int32_t NewConfig(ResumeTestInfo *testInfo) +{ + /* Construct the configuration. */ + switch (testInfo->version) { + case HITLS_VERSION_DTLS12: + testInfo->config = HITLS_CFG_NewDTLS12Config(); + break; + case HITLS_VERSION_TLS13: + testInfo->config = HITLS_CFG_NewTLS13Config(); + break; + case HITLS_VERSION_TLS12: + testInfo->config = HITLS_CFG_NewTLS12Config(); + break; + default: + break; + } + + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + + HITLS_CFG_SetClientVerifySupport(testInfo->config, true); + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + HITLS_CFG_SetExtenedMasterSecretSupport(testInfo->config, true); + HITLS_CFG_SetNoClientCertSupport(testInfo->config, true); + HITLS_CFG_SetRenegotiationSupport(testInfo->config, true); + HITLS_CFG_SetPskServerCallback(testInfo->config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo->config, (HITLS_PskClientCb)ExampleClientCb); + return HITLS_SUCCESS; +} + +static void FreeLink(ResumeTestInfo *testInfo) +{ + /* Release resources. */ + FRAME_FreeLink(testInfo->client); + testInfo->client = NULL; + FRAME_FreeLink(testInfo->server); + testInfo->server = NULL; +} + +int32_t GetSessionId(ResumeTestInfo *testInfo) +{ + FRAME_Type frameType = { 0 }; + FRAME_Msg recvframeMsg = { 0 }; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo->client->io); + uint8_t *recMsg = ioUserData->recMsg.msg; + uint32_t recMsgLen = ioUserData->recMsg.len; + + frameType.handshakeType = SERVER_HELLO; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.versionType = testInfo->version; + uint32_t parseLen = 0; + int32_t ret = FRAME_ParseMsg(&frameType, recMsg, recMsgLen, &recvframeMsg, &parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Save the sessionId in the serverhello. */ + FRAME_ServerHelloMsg *serverHello = &recvframeMsg.body.hsMsg.body.serverHello; + g_sessionIdSize = serverHello->sessionIdSize.data; + g_sessionId = BSL_SAL_Dump(serverHello->sessionId.data, g_sessionIdSize); + + FRAME_CleanMsg(&frameType, &recvframeMsg); + return HITLS_SUCCESS; +} + +int32_t FirstHandshake(ResumeTestInfo *testInfo) +{ + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret = 0; + + ret = FRAME_CreateConnection(testInfo->client, testInfo->server, true, TRY_RECV_SERVER_HELLO); + + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Obtain the session ID for the first connection setup. */ + ret = GetSessionId(testInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* User data transmission */ + uint8_t data[] = "Hello World"; + ret = HITLS_Write(testInfo->server->ssl, data, sizeof(data)); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ret = FRAME_TrasferMsgBetweenLink(testInfo->server, testInfo->client); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HITLS_Read(testInfo->client->ssl, readBuf, READ_BUF_SIZE, &readLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + testInfo->clientSession = HITLS_GetDupSession(testInfo->client->ssl); + + FreeLink(testInfo); + return HITLS_SUCCESS; +} + +int32_t CmpClientHelloSessionId(ResumeTestInfo *testInfo) +{ + FRAME_Type frameType = { 0 }; + /* Obtain the client hello message received by the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo->server->io); + uint8_t *recMsg = ioUserData->recMsg.msg; + uint32_t recMsgLen = ioUserData->recMsg.len; + uint32_t parseLen = 0; + + FRAME_Msg frameMsg = { 0 }; + frameType.versionType = testInfo->version; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + + int32_t ret = FRAME_ParseMsg(&frameType, recMsg, recMsgLen, &frameMsg, &parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Compare the sessionId in the client hello with the saved sessionId. */ + FRAME_ClientHelloMsg *clienHello = &frameMsg.body.hsMsg.body.clientHello; + if (clienHello->sessionIdSize.data != g_sessionIdSize) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (memcmp(clienHello->sessionId.data, g_sessionId, g_sessionIdSize) != 0) { + return HITLS_INTERNAL_EXCEPTION; + } + + FRAME_CleanMsg(&frameType, &frameMsg); + CONN_Deinit(testInfo->server->ssl); + HITLS_Accept(testInfo->server->ssl); + FRAME_TrasferMsgBetweenLink(testInfo->server, testInfo->client); + return HITLS_SUCCESS; +} + +int32_t CmpSessionId(ResumeTestInfo *testInfo) +{ + FRAME_Type frameType = { 0 }; + FRAME_Msg recvframeMsg = { 0 }; + /* Obtain the server hello message received by the client. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo->client->io); + uint8_t *recMsg = ioUserData->recMsg.msg; + uint32_t recMsgLen = ioUserData->recMsg.len; + + frameType.handshakeType = SERVER_HELLO; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.versionType = testInfo->version; + /* Parse the server hello message. */ + uint32_t parseLen = 0; + int32_t ret = FRAME_ParseMsg(&frameType, recMsg, recMsgLen, &recvframeMsg, &parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check whether the received serverhello message is consistent with the saved one. */ + FRAME_ServerHelloMsg *serverHello = &recvframeMsg.body.hsMsg.body.serverHello; + if (serverHello->sessionIdSize.data != g_sessionIdSize) { + FRAME_CleanMsg(&frameType, &recvframeMsg); + return HITLS_INTERNAL_EXCEPTION; + } + + if (memcmp(serverHello->sessionId.data, g_sessionId, g_sessionIdSize) != 0) { + FRAME_CleanMsg(&frameType, &recvframeMsg); + return HITLS_INTERNAL_EXCEPTION; + } + + FRAME_CleanMsg(&frameType, &recvframeMsg); + return HITLS_SUCCESS; +} + +int32_t TryResumeBySessionId(ResumeTestInfo *testInfo) +{ + int32_t ret; + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->clientSession != NULL) { + ret = HITLS_SetSession(testInfo->client->ssl, testInfo->clientSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + ret = FRAME_CreateConnection(testInfo->client, testInfo->server, false, TRY_RECV_CLIENT_HELLO); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CmpClientHelloSessionId(testInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CmpSessionId(testInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* User data transmission */ + uint8_t data[] = "Hello World"; + ret = HITLS_Write(testInfo->server->ssl, data, sizeof(data)); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ret = FRAME_TrasferMsgBetweenLink(testInfo->server, testInfo->client); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HITLS_Read(testInfo->client->ssl, readBuf, READ_BUF_SIZE, &readLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + + +int32_t TryResumeByTheUsingSessionId(ResumeTestInfo *testInfo) +{ + int32_t ret; + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->clientSession != NULL) { + ret = HITLS_SetSession(testInfo->client->ssl, testInfo->clientSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + ret = FRAME_CreateConnection(testInfo->client, testInfo->server, false, TRY_RECV_CLIENT_HELLO); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CmpClientHelloSessionId(testInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CmpSessionId(testInfo); + if (ret != HITLS_SUCCESS) { + return HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID; + } + + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC001 +* @title Test the scenario where the session recovers. +* @precon nan +* @brief 1. First handshake between the client and server. Save the session ID. Expected result 1 is obtained. + 2. Obtain the client session and set the session to the client that performs the next handshake. Expected +result 2 is obtained. + 3. Perform the second handshake between the client and server. Expected result 3 is obtained. + 4. Use the same session ID on the client and server to restore the session. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The session is restored successfully. + 4. The session fails. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC001(int uioType, int version) +{ + g_sessionId = NULL; + g_sessionIdSize = 0; + FRAME_Init(); + + ResumeTestInfo testInfo01 = { 0 }; + testInfo01.version = (uint16_t)version; + testInfo01.uioType = (BSL_UIO_TransportType)uioType; + + /* First handshake between the client and server. Save the session ID. */ + ASSERT_EQ(NewConfig(&testInfo01), HITLS_SUCCESS); + HITLS_CFG_SetSessionTicketSupport(testInfo01.config, false); + ASSERT_EQ(FirstHandshake(&testInfo01), HITLS_SUCCESS); + + /* Obtain the client session and set the session to the client that performs the next handshake. */ + ASSERT_TRUE(testInfo01.clientSession != NULL); + ASSERT_EQ(TryResumeBySessionId(&testInfo01), HITLS_SUCCESS); + + ResumeTestInfo testInfo02 = { 0 }; + testInfo02.version = (uint16_t)version; + testInfo02.uioType = (BSL_UIO_TransportType)uioType; + /* Perform the second handshake between the client and server. */ + ASSERT_EQ(NewConfig(&testInfo02), HITLS_SUCCESS); + HITLS_CFG_SetSessionTicketSupport(testInfo02.config, false); + + /* Use the same session ID on the client and server to restore the session. */ + testInfo02.clientSession = testInfo01.clientSession; + ASSERT_EQ(TryResumeByTheUsingSessionId(&testInfo02), HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID); + ASSERT_TRUE(testInfo02.clientSession != NULL); + +exit: + FreeLink(&testInfo01); + FreeLink(&testInfo02); + BSL_SAL_FREE(g_sessionId); + HITLS_CFG_FreeConfig(testInfo01.config); + FRAME_FreeLink(testInfo01.client); + FRAME_FreeLink(testInfo01.server); + HITLS_SESS_Free(testInfo01.clientSession); + + HITLS_CFG_FreeConfig(testInfo02.config); + FRAME_FreeLink(testInfo02.client); + FRAME_FreeLink(testInfo02.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC001 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a connection between the client and server. Expected result 1 is obtained. +* 2. The client closes the link, obtains the message sent by the client, and checks whether the message is a +close_notify message. (Expected result 2) +* 3. The server obtains the received message and checks whether the message is a close_notify message. (Expected +result 3) +* @expect 1. The link is successfully established. +* 2. The client sends a close_notify message. +* 3. The server receives the close_notify message. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + /* Establish a connection between the client and server. */ + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_KEY_EXCHANGE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_KEY_EXCHANGE); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + /* The client closes the link, obtains the message sent by the client, and checks whether the message is a + * close_notify message. */ + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = { 0 }; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + /* The server obtains the received message and checks whether the message is a close_notify message. */ + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = { 0 }; + uint8_t *serverbuffer = serverioUserData->recMsg.msg; + uint32_t serverreadLen = serverioUserData->recMsg.len; + uint32_t serverparseLen = 0; + ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC002 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a connection between the client and server. Expected result 1 is obtained. +* 2. Close the link on the client, obtain the message sent by the client, and check whether the message is a +close_notify message. (Expected result 2) +* 3. The server processes the message received by the server, obtains the message to be sent after processing, +and checks whether the message is a close_notify message. (Expected result 3) +* @expect 1. The link is successfully established. +* 2. The client sends a close_notify message. +* 3. The server sends a close_notify message. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + /* Establish a connection between the client and server. */ + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_KEY_EXCHANGE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_KEY_EXCHANGE); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + /* Close the link on the client, obtain the message sent by the client, and check whether the message is a + * close_notify message. */ + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = { 0 }; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + /* The server processes the message received by the server, obtains the message to be sent after processing, and + * checks whether the message is a close_notify message. */ + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = { 0 }; + uint8_t *serverbuffer = serverioUserData->recMsg.msg; + uint32_t serverreadLen = serverioUserData->recMsg.len; + uint32_t serverparseLen = 0; + ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + ASSERT_TRUE(server->ssl != NULL); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_IO_BUSY); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_CM_LINK_FATAL_ALERTED); + + FRAME_Msg serverframeMsg1 = { 0 }; + uint8_t *serverbuffer1 = serverioUserData->sndMsg.msg; + uint32_t serverreadLen1 = serverioUserData->sndMsg.len; + uint32_t serverparseLen1 = 0; + ret = ParserTotalRecord(server, &serverframeMsg1, serverbuffer1, serverreadLen1, &serverparseLen1); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg1.type == REC_TYPE_ALERT && serverframeMsg1.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg1.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg1.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC003 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a connection between the client and server. Expected result 1 is obtained. +* 2. The server closes the link, obtains the message sent by the server, and checks whether the message is a +close_notify message. (Expected result 2) +* 3. Obtain the received message and check whether the message is a close_notify message. (Expected result 3) +* @expect 1. The link is successfully established. +* 2. The server sends a close_notify message. +* 3. The client receives the close_notify message. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC003(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + /* Establish a connection between the client and server. */ + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(server, client, false, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + /* The server closes the link, obtains the message sent by the server, and checks whether the message is a + * close_notify message. */ + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = { 0 }; + uint8_t *serverbuffer = serverioUserData->sndMsg.msg; + uint32_t serverreadLen = serverioUserData->sndMsg.len; + uint32_t serverparseLen = 0; + int32_t ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + /* Obtain the received message and check whether the message is a close_notify message. */ + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = { 0 }; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC004 +* @title Close the link and check whether the close_notify alarm is sent. +* @precon nan +* @brief 1. Establish a link between the client and server. Expected result 1 is obtained. +* 2. The server closes the link, obtains the message sent by the server, and checks whether the message is a +close_notify message. (Expected result 2) +* 3. The client processes the received message, obtains the message to be sent after processing, and checks +whether the message is a close_notify message. (Expected result 3) +* @expect 1. The link is successfully established. +* 2. The client sends a close_notify message. +* 3. The server sends a close_notify message. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC004(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + /* Establish a link between the client and server. */ + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_CLIENT_KEY_EXCHANGE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_KEY_EXCHANGE); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_KEY_EXCHANGE); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + /* The server closes the link, obtains the message sent by the server, and checks whether the message is a + * close_notify message. */ + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = { 0 }; + uint8_t *serverbuffer = serverioUserData->sndMsg.msg; + uint32_t serverreadLen = serverioUserData->sndMsg.len; + uint32_t serverparseLen = 0; + int32_t ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + clientioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + /* The client processes the received message, obtains the message to be sent after processing, and checks whether + * the message is a close_notify message. */ + FRAME_Msg clientframeMsg = { 0 }; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(client->ssl != NULL); + clientioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_IO_BUSY); + clientioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_IO_BUSY); + clientioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_IO_BUSY); + clientioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_CM_LINK_FATAL_ALERTED); + FRAME_Msg clientframeMsg1 = { 0 }; + uint8_t *clientbuffer1 = clientioUserData->sndMsg.msg; + uint32_t clientreadLen1 = clientioUserData->sndMsg.len; + uint32_t clientparseLen1 = 0; + ret = ParserTotalRecord(client, &clientframeMsg1, clientbuffer1, clientreadLen1, &clientparseLen1); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg1.type == REC_TYPE_ALERT); + ASSERT_TRUE(clientframeMsg1.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC001 +* @title Disable the link abnormally and check whether the two ends send an alert. +* @precon nan +* @brief 1. Establish a link between the client and server, and the client is disabling the link. Expected result 1 is +obtained. +* 2. Enable the client to send a critical alarm. Obtain the received message from the server and check whether +the message is an alert message. Expected result 2 is obtained. +* @expect 1. The link is successfully established and the client is in the closed state. +* 2. Check the alert message on the server. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC001(void) +{ + HandshakeTestInfo testInfo = { 0 }; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Establish a link between the client and server, and the client is disabling the link. */ + FRAME_Msg parsedSHdone = { 0 }; + FRAME_Type frameType = { 0 }; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, SERVER_HELLO_DONE, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &parsedSHdone) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSHdone, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &parsedSHdone); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &parsedSHdone, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedSHdone.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedSHdone.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + + // Enable the client to send a critical alarm. Obtain the received message from the server and check whether the + // message is an alert message. + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(testInfo.server->io); + FRAME_Msg clientframeMsg = { 0 }; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(testInfo.server, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_FATAL && + clientframeMsg.body.alertMsg.description == ALERT_UNEXPECTED_MESSAGE); + + +exit: + FRAME_CleanMsg(&frameType, &parsedSHdone); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC002 +* @title Abnormally close the link and check whether the two ends send an alert. +* @precon nan +* @brief 1. Establish a link between the client and server. The client is in the link disabling state. Expected result +1 is obtained. +* 2. Enable the client to send a critical alarm, obtain the received message from the server, and check whether +the message is an alert message. Expected result 2 is obtained. +* @expect 1. The link is successfully established and the client is in the closed state. +* 2. Check the alert message on the server. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC002(void) +{ + HandshakeTestInfo testInfo = { 0 }; + + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + /* Establish a link between the client and server. The client is in the link disabling state. */ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); + + // Enable the client to send a critical alarm, obtain the received message from the server, and check whether the + // message is an alert message. + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client) == HITLS_SUCCESS); + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(testInfo.client->io); + FRAME_Msg clientframeMsg = { 0 }; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(testInfo.client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_FATAL && + clientframeMsg.body.alertMsg.description == ALERT_UNEXPECTED_MESSAGE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC001 +* @title The client receives the NO_CERTIFICATIONATE_RESERVED alarm. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the client stops receiving server hello, the server sends the NO_CERTIFICATIONATE_RESERVED alarm and +observe the response from the client. +* @expect 1. The initialization is successful. +* 2. The client ignores the message. The client should not receive the message. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + FRAME_Msg sndframeMsg = { 0 }; + + /* Use the default configuration items to configure the client and server. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + /* When the client stops receiving server hello, the server sends the NO_CERTIFICATIONATE_RESERVED alarm and observe + * the response from the client. */ + recvframeMsg.type = REC_TYPE_ALERT; + recvframeMsg.version = HITLS_VERSION_TLS12; + recvframeMsg.bodyLen = ALERT_BODY_LEN; + recvframeMsg.epochSeq = GetEpochSeq(0, 5); + recvframeMsg.body.alertMsg.level = ALERT_LEVEL_WARNING; + recvframeMsg.body.alertMsg.description = ALERT_NO_CERTIFICATE_RESERVED; + ASSERT_TRUE(PackFrameMsg(&recvframeMsg) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, recvframeMsg.buffer, recvframeMsg.len) == HITLS_SUCCESS); + + ioUserData->sndMsg.len = 0; + ASSERT_TRUE(HITLS_Connect(clientTlsCtx) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + +exit: + CleanRecordBody(&recvframeMsg); + CleanRecordBody(&sndframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC002 +* @title The client receives the NO_CERTIFICATIONATE_RESERVED alarm. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the server stops receiving the client keyexchange, the client sends the no_certificate_RESERVED alarm +and observe the message returned by the server. +* @expect 1. The initialization is successful. +* 2. The server ignores the message. The message cannot be received. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + FRAME_Msg sndframeMsg = { 0 }; + + /* Use the default configuration items to configure the client and server. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + /* When the server stops receiving the client keyexchange, the client sends the no_certificate_RESERVED alarm and + * observe the message returned by the server. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + recvframeMsg.type = REC_TYPE_ALERT; + recvframeMsg.version = HITLS_VERSION_TLS12; + recvframeMsg.bodyLen = ALERT_BODY_LEN; + recvframeMsg.epochSeq = GetEpochSeq(0, 5); + recvframeMsg.body.alertMsg.level = ALERT_LEVEL_WARNING; + recvframeMsg.body.alertMsg.description = ALERT_NO_CERTIFICATE_RESERVED; + ASSERT_TRUE(PackFrameMsg(&recvframeMsg) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, recvframeMsg.buffer, recvframeMsg.len) == HITLS_SUCCESS); + + ioUserData->sndMsg.len = 0; + ASSERT_TRUE(HITLS_Accept(serverTlsCtx) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + +exit: + CleanRecordBody(&recvframeMsg); + CleanRecordBody(&sndframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC001 +* @title The client receives an ERROR_RESTRICTION_RESERVED alarm. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the client stops receiving server hello, the server sends the export_restriction_RESERVED alarm. +* @expect 1. The initialization is successful. +* 2. The client ignores the message. The client should not receive the message. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + FRAME_Msg sndframeMsg = { 0 }; + + /* Use the default configuration items to configure the client and server. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + /* When the client stops receiving server hello, the server sends the export_restriction_RESERVED alarm. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + recvframeMsg.type = REC_TYPE_ALERT; + recvframeMsg.version = HITLS_VERSION_TLS12; + recvframeMsg.bodyLen = ALERT_BODY_LEN; + recvframeMsg.epochSeq = GetEpochSeq(0, 5); + recvframeMsg.body.alertMsg.level = ALERT_LEVEL_WARNING; + recvframeMsg.body.alertMsg.description = ALERT_EXPORT_RESTRICTION_RESERVED; + ASSERT_TRUE(PackFrameMsg(&recvframeMsg) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, recvframeMsg.buffer, recvframeMsg.len) == HITLS_SUCCESS); + + ioUserData->sndMsg.len = 0; + ASSERT_TRUE(HITLS_Connect(clientTlsCtx) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + +exit: + CleanRecordBody(&recvframeMsg); + CleanRecordBody(&sndframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC002 +* @title The client receives an ERROR_RESTRICTION_RESERVED alarm. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the server receives the client keyexchange, the client sends the export_restriction_RESERVED alarm, + Check the message returned by the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The server ignores the message. The message cannot be received. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = { 0 }; + FRAME_Msg sndframeMsg = { 0 }; + + /* Use the default configuration items to configure the client and server. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + /* When the server receives the client keyexchange, the client sends the export_restriction_RESERVED alarm, check + * the message returned by the server. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + recvframeMsg.type = REC_TYPE_ALERT; + recvframeMsg.version = HITLS_VERSION_TLS12; + recvframeMsg.bodyLen = ALERT_BODY_LEN; + recvframeMsg.epochSeq = GetEpochSeq(0, 5); + recvframeMsg.body.alertMsg.level = ALERT_LEVEL_WARNING; + recvframeMsg.body.alertMsg.description = ALERT_EXPORT_RESTRICTION_RESERVED; + ASSERT_TRUE(PackFrameMsg(&recvframeMsg) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, recvframeMsg.buffer, recvframeMsg.len) == HITLS_SUCCESS); + + ioUserData->sndMsg.len = 0; + ASSERT_TRUE(HITLS_Accept(serverTlsCtx) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + +exit: + CleanRecordBody(&recvframeMsg); + CleanRecordBody(&sndframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS1_2_RFC5246_SERVER_CHOSE_VERSION_TC002 +* @spec - +* @title Check the TLS protocol version carried in the serverHello message. +* @brief 1. Use the configuration items to configure the client and server. Change the record version in client hello +* to 0x0305 Expected result 1 is obtained. +* 2. Obtain and parse the server Hello message. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The protocol version carried in the server Hello message is TLS1.2. +* @prior Level 1 +* @auto TRUE +@ */ + +/* BEGIN_CASE */ +void UT_TLS1_2_RFC5246_SERVER_CHOSE_VERSION_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + + recvBuf[2] = 0x05; + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->version.data == HITLS_VERSION_TLS12); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + FRAME_CleanMsg(&frameType, &frameMsg); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246.data new file mode 100644 index 00000000..7dc1aff4 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246.data @@ -0,0 +1,206 @@ +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC004: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC005 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC005: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC006 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC006: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC007 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC007: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC008 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC008: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC004: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC005 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC005: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC006 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC006: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC007 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC007: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC008 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC008: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC009 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC009: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC010 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC010: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC011 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC011: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC012 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_TC012: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_AEAD_EXPLICIT_IV_LENGTH_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_AEAD_EXPLICIT_IV_LENGTH_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_READ_PENDING_STATE_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_WRITE_PENDING_STATE_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_MASTEKEY_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_MASTEKEY_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC001:0 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC001:1 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC002:0 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SEQ_NUM_TC002:1 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC004: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC005 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC005: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC006 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC006: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC007 +UT_TLS_TLS12_RFC5246_CONSISTENCY_UNEXPECT_RECODETYPE_TC007: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_RECV_APPDATA_TC001 test client +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_RECV_APPDATA_TC001:1 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_RECV_APPDATA_TC001 test server +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_RECV_APPDATA_TC001:0 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC004: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC005 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC005: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC006 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC006: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC007 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC007: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC008 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HELLO_REQUEST_TC008: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_VERSION_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_VERSION_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_NOT_SUPPORT_SERVER_VERSION_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_NOT_SUPPORT_SERVER_VERSION_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_CHOSE_VERSION_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_CHOSE_VERSION_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_DEFAULT_SIGNATURE_EXTENSION_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_DEFAULT_SIGNATURE_EXTENSION_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_HELLO_WITHOUT_SIGNATURE_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECODE_VERSION_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_HELLO_ADD_SIGNATURE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_HELLO_ADD_SIGNATURE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC001 tls12 +UT_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC001:BSL_UIO_TCP:HITLS_VERSION_TLS12 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CLOSE_NOTIFY_TC004: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CM_CLOSE_SEND_ALERT_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NO_CERTIFICATE_RESERVED_ALERT_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_EXPORT_RESTRICTION_RESERVED_ALERT_TC002: + +UT_TLS1_2_RFC5246_SERVER_CHOSE_VERSION_TC002 +UT_TLS1_2_RFC5246_SERVER_CHOSE_VERSION_TC002: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_cert.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_cert.c new file mode 100644 index 00000000..1b3170cc --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_cert.c @@ -0,0 +1,549 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls12_consistency_rfc5246 */ + +#include +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "cert.h" +#include "securec.h" +#include "frame_msg.h" +#include "alert.h" +#include "bsl_list.h" +#include "app_ctx.h" +/* END_HEADER */ + +#define g_uiPort 45678 + + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_SEND_CERTFICATE_TC001 rfc 5246 table row 51 +* @title If the server has sent a CertificateRequest message, the client must send a certificate message. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server, and enable the dual-end verification. Expected result 1 is obtained. +* 2. The client initiates a TLS over TCP link request. After the server receives the CertificateRequest message, expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client is in the TRY_SEND_CLIENT_KEY_EXCHANGE state, and the server is in the TRY_RECV_CERTIFICATIONATE state. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_SEND_CERTFICATE_TC001(void) +{ + /* Use the default configuration items to configure the client and server, and enable the dual-end verification. */ + HandshakeTestInfo testInfo = { 0 }; + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + testInfo.state = TRY_SEND_SERVER_HELLO_DONE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + testInfo.isSupportNoClientCert = false; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == HITLS_SUCCESS); + + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO_DONE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + + // The client initiates a TLS over TCP link request. + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(testInfo.client->ssl->hsCtx->state, TRY_SEND_CLIENT_KEY_EXCHANGE); + + uint32_t readLen = 0; + uint8_t tmp1[MAX_RECORD_LENTH] = {0}; + uint32_t tmp1Len = sizeof(tmp1); + ASSERT_TRUE(FRAME_TransportSendMsg(testInfo.client->io, tmp1, tmp1Len, &readLen) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + uint8_t tmp2[MAX_RECORD_LENTH] = {0}; + uint32_t tmp2Len = sizeof(tmp2); + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, tmp2, tmp2Len) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC002 +* @title During dual-end verification, the server signature algorithm does not match the certificate signature algorithm. As a result, the link fails to be established. +* @precon nan +* @brief 1. Configure dual-end verification. Set the signature algorithm to RSA_PKCS1_SHA256, cipher suite to RSA, certificate to RSA, and certificate signature to ECDSA_SHA256 on the server. Expected result 1 is obtained. +* @expect 1. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + // 1. Configure dual-end verification. Set the signature algorithm to RSA_PKCS1_SHA256, cipher suite to RSA, certificate to RSA, and certificate signature to ECDSA_SHA256 on the server. + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + uint32_t signAlgsSize = sizeof(signAlgs) / sizeof(uint16_t); + HITLS_CFG_SetSignature(config, signAlgs, signAlgsSize); + HITLS_CFG_SetClientVerifySupport(config, true); + uint16_t cipherSuites[] = {HITLS_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(config, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)); + FRAME_CertInfo certInfoServer = { + "ecdsa/ca-nist521.der", + "rsa_sha/inter-3072.der", + "rsa_sha/end-sha256.der", + 0, + "rsa_sha/end-sha256.key.der", + 0, + }; + FRAME_CertInfo certInfoClient = { + "rsa_sha/ca-3072.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfoServer); + ASSERT_TRUE(server != NULL); + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfoClient); + ASSERT_TRUE(client != NULL); + + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC003 +* @title During dual-end verification, the intermediate certificate is incorrectly configured on the client. As a result, the verification on the server fails. +* @precon nan +* @brief 1. Configure dual-ended authentication. Configure a correct terminal certificate and an incorrect intermediate certificate on the client. Configure a correct certificate chain on the server. Check whether the server fails the authentication. Expected result 1 is obtained. +* @expect 1. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC003(void) +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_CFG_SetClientVerifySupport(config, true); + // 1. Configure dual-ended authentication. Configure a correct terminal certificate and an incorrect intermediate certificate on the client. Configure a correct certificate chain on the server. Check whether the server fails the authentication. + FRAME_CertInfo certInfoClient = { + "ecdsa/ca-nist521.der", + "rsa_sha/inter-3072.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + FRAME_CertInfo certInfoServer = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfoClient); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfoServer); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_SIGNATION_FAIL_TC001 +* @title Link setup failed because the signature algorithm does not match. +* @precon nan +* @brief 1. Set the client signature algorithm to ECDSA_SECP256R1_SHA256 and the server certificate signature algorithm to RSA_SHA256. Expected result 1 is obtained. +* @expect 1. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_SIGNATION_FAIL_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + uint32_t signAlgsSize = sizeof(signAlgs) / sizeof(uint16_t); + FRAME_CertInfo certInfo = { + "rsa_sha/ca-3072.der:rsa_sha/inter-3072.der", + "rsa_sha/inter-3072.der", + "rsa_sha/end-sha256.der", + 0, + "rsa_sha/end-sha256.key.der", + 0, + }; + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + // 1. Set the client signature algorithm to ECDSA_SECP256R1_SHA256 and the server certificate signature algorithm to RSA_SHA256. + ASSERT_TRUE(HITLS_SetSigalgsList(client->ssl, signAlgs, signAlgsSize) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC001 +* @title The certificate signature algorithm does not match the signature algorithm set on the client. As a result, the link fails to be established. +* @precon nan +* @brief 1. Set the signature algorithm to RSA_PKCS1_SHA256 on the client, cipher suite to RSA, certificate to RSA, + server signature algorithm to RSA_PKCS1_SHA256, and certificate signature algorithm to ECDSA_SHA256. + Expected Certificate Verification Failure (Failed to Select a Certificate on the Server) +* @expect 1. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + // 1. Set the signature algorithm to RSA_PKCS1_SHA256 on the client, cipher suite to RSA, certificate to RSA, + // server signature algorithm to RSA_PKCS1_SHA256, and certificate signature algorithm to ECDSA_SHA256. + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + uint32_t signAlgsSize = sizeof(signAlgs) / sizeof(uint16_t); + HITLS_CFG_SetSignature(config, signAlgs, signAlgsSize); + HITLS_CFG_SetClientVerifySupport(config, true); + uint16_t cipherSuites[] = {HITLS_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(config, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)); + FRAME_CertInfo certInfoClient = { + "ecdsa/ca-nist521.der", + "rsa_sha/inter-3072.der", + "rsa_sha/end-sha256.der", + 0, + "rsa_sha/end-sha256.key.der", + 0, + }; + FRAME_CertInfo certInfoServer = { + "rsa_sha/ca-3072.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfoClient); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfoServer); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC004 +* @title During dual-end authentication, the client certificate is out of order, and the link fails to be established. +* @precon nan +* @brief 1. Configure dual-end verification. Configure the first certificate on the client as an intermediate + certificate and the second certificate as a terminal certificate. Configure a correct certificate chain + on the server. Check whether the verification fails on the server. Expected result 1 is obtained. +* @expect 1. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC004(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_CFG_SetClientVerifySupport(config, true); + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE), HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + // Change the certificate sequence. The intermediate certificate is used first, and then the device certificate is used. + // 1. Configure dual-end authentication. Configure the first certificate on the client as an intermediate + // certificate, and the second certificate as a terminal certificate. Configure a correct certificate chain on the server. + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + struct FrameCertItem_ *tmp = frameMsg.body.hsMsg.body.certificate.certItem->next; + frameMsg.body.hsMsg.body.certificate.certItem->next = tmp->next; // a->c + tmp->next = frameMsg.body.hsMsg.body.certificate.certItem; // b -> a + frameMsg.body.hsMsg.body.certificate.certItem = tmp; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_PARSE_VERIFY_SIGN_FAIL); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +static int32_t STUB_SAL_CERT_KeyDecrypt_Fail(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + (void)cipher; + (void)in; + (void)inLen; + (void)out; + (void)outLen; + return HITLS_CRYPT_ERR_DECRYPT; +} + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_DECRYPT_FAIL_TC005 +* @title After the premasterkey to be received by the server is modified, the connection fails to be established. +* @precon nan +* @brief 1. Configure the RSA cipher suite. When the server receives the premasterkey, change the value of the + premasterkey and construct a decryption failure scenario. It is expected that CCS messages are sent normally + and the link fails to be established. Expected result 1 is obtained. +* @expect 1. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_DECRYPT_FAIL_TC005(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_CFG_SetClientVerifySupport(config, true); + // 1.Configure the RSA cipher suite. Change the value of the premasterkey when the server receives the premasterkey. + // Construct a decryption failure scenario. The CCS message is expected to be sent normally. + uint16_t cipherSuits[] = {HITLS_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_KEY_EXCHANGE), HITLS_SUCCESS); + + STUB_Init(); + FuncStubInfo tmpStubInfo; + STUB_Replace(&tmpStubInfo, SAL_CERT_KeyDecrypt, STUB_SAL_CERT_KeyDecrypt_Fail); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + STUB_Reset(&tmpStubInfo); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_REC_BAD_RECORD_MAC); + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(server->ssl, &alertInfo); + ASSERT_EQ(alertInfo.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alertInfo.description, ALERT_BAD_RECORD_MAC); + +exit: + + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC003 +* @title The certificate carries the correct keyuage extension, and the link is successfully established. +* @precon nan +* @brief 1. Configure the server certificate with the keyuage extension and support digitalSignature. The link is successfully established. Expected result 1 is obtained. +* @expect 1. The link is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC003(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_CFG_SetClientVerifySupport(config, true); + // 1. Set the server certificate with the keyuage extension and support digitalSignature. + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC001 +* @title Invoke the hitls_connect/hitls_accept interface to initiate renegotiation. The peer end does not support renegotiation. +* @precon nan +* @brief 1. Invoke the hitls_renegotiate interface to initiate renegotiation. Expected result 1 is obtained. + 2. Invoke the hitls_connect/hitls_accept interface to initiate renegotiation. The peer end does not support renegotiation. Expected result 2 is obtained. +* @expect 1. The link enters the renegotiation state. + 2. The peer end returns a warning alert. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC001() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(server->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + HITLS_SetRenegotiationSupport(client->ssl, true); + + // 1. Invoke the hitls_renegotiate interface to initiate renegotiation. + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + // Invoke the hitls_connect/hitls_accept interface to initiate renegotiation. The peer end does not support renegotiation. + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(client->ssl->state, CM_STATE_RENEGOTIATION); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + // Send a warning alert and ALERT_NO_RENEGOTIATION message. After receiving the message, the peer end changes the status to CM_STATE_TRANSPORTING. + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_SUCCESS); + ASSERT_EQ(client->ssl->state, CM_STATE_TRANSPORTING); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType); + +int32_t STUB_RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + (void)ctx; + (void)text; + (void)textLen; + *recType = (uint8_t)REC_TYPE_APP; + + return HITLS_SUCCESS; +} +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC002 +* @title Invoke the hitls_connect/hitls_accept/hitls_write interface to initiate renegotiation, and the peer end returns an app message. +* @precon nan +* @brief 1. Invoke the hitls_renegotiate interface to initiate renegotiation. Expected result 1 is displayed. + 2. Invoke the hitls_connect/hitls_accept/hitls_write interface to initiate renegotiation. The peer end replies with an app message. Expected result 2 is obtained. + 3. The peer end continuously sends 51 app messages. Expected result 3 is obtained. + 4. Read the stored app message. Expected result 4 is obtained. +* @expect 1. The link enters the renegotiation state. + 2. Received successfully. + 3. Received successfully. + 4. The 50th message can be read normally, and the 51st message is lost. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC002() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + // 1. Invoke the hitls_renegotiate interface to initiate renegotiation. + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + // 2. Invoke the hitls_connect/hitls_accept/hitls_write interface to initiate renegotiation. The peer end replies with an app message. + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t data[] = "Hello World"; + int32_t count = 0; + while (count < 60) { + // 3. The peer end continuously sends 51 app messages. + int32_t ret = HITLS_Write(server->ssl, data, sizeof(data)); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ret = HITLS_Connect(client->ssl); + count++; + if (ret == HITLS_SUCCESS) { + // 4. Read the stored app message. + APP_Ctx *appCtx = client->ssl->appCtx; + if (count <= UNPROCESSED_APP_MSG_COUNT_MAX) { + ASSERT_TRUE(BSL_LIST_COUNT(appCtx->appList) == count); + } else { + ASSERT_TRUE(BSL_LIST_COUNT(appCtx->appList) == UNPROCESSED_APP_MSG_COUNT_MAX); + } + } + } + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_cert.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_cert.data new file mode 100644 index 00000000..ace77329 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_cert.data @@ -0,0 +1,30 @@ + +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_SEND_CERTFICATE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_HANDSHAKE_SEND_CERTFICATE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_SIGNATION_FAIL_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_SIGNATION_FAIL_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_SIGNATION_NOT_SUITABLE_CERT_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC004: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_DECRYPT_FAIL_TC005 +UT_TLS_TLS12_RFC5246_CONSISTENCY_DECRYPT_FAIL_TC005: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_RENEGOTIATION_UNSUPPORTED_TC002: diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_extensions.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_extensions.c new file mode 100644 index 00000000..5d6e2d41 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_extensions.c @@ -0,0 +1,663 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "process.h" +#include "securec.h" +#include "hitls_error.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "bsl_sal.h" +#include "simulate_io.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "alert.h" +#include "session_type.h" +#include "process.h" +#include "hitls_type.h" +#include "rec.h" +#include "hs_msg.h" +#include "hs_extensions.h" +#include "frame_msg.h" +/* END_HEADER */ +#define BUF_TOOLONG_LEN ((1 << 14) + 1) + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isSupportRenegotiation; + bool isServerExtendMasterSecret; +} HandshakeTestInfo; + +int32_t StatusPark(HandshakeTestInfo *testInfo) +{ + /* Construct a link. */ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + /*Set up a link and stop in a certain state. */ + if (FRAME_CreateConnection(testInfo->client, testInfo->server, + testInfo->isClient, testInfo->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + /* Construct the configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusPark(testInfo); +} + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC001 +* @title The client sends a Client Certificate message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +2. The client initiates a DTLS link creation request. When the client needs to send a Client Certificate message, the two fields are modified as follows: +Certificates Length is 2 ^ 14 + 1 +Certificates are changed to 2 ^ 14 + 1 byte buffer. +After the modification is complete, send the modification to the server. Expected result 2 is obtained. +3. When the server receives the Client Certificate message, check the value returned by the HITLS_Accept interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +2. The field is successfully modified and sent to the client. +3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.certificate.certItem->cert.data); + frameMsg.body.hsMsg.body.certificate.certItem->cert.data = certDataTemp; + frameMsg.body.hsMsg.body.certificate.certItem->cert.size = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.data = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC002 +* @title The server sends a Server Certificate message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +2. The client initiates a DTLS link creation request. When the server needs to send a Server Certificate message, the server modifies the following two fields: +Certificates Length is 2 ^ 14 + 1 +Certificates are changed to 2 ^ 14 + 1 byte buffer. +After the modification is complete, send the modification to the server. Expected result 2 is obtained. +3. When the client receives the Server Certificate message, check the value returned by the HITLS_Connect interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +2. The field is successfully modified and sent to the client. +3. The return value of the HITLS_Connect interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + + testInfo.state = TRY_RECV_CERTIFICATE; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.certificate.certItem->cert.data); + frameMsg.body.hsMsg.body.certificate.certItem->cert.data = certDataTemp; + frameMsg.body.hsMsg.body.certificate.certItem->cert.size = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->cert.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.data = BUF_TOOLONG_LEN; + frameMsg.body.hsMsg.body.certificate.certItem->certLen.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC003 +* @title The client sends a Change Cipher Spec message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +2. When the client initiates a DTLS link establishment request and sends a Change Cipher Spec message, the client modifies one field as follows: +Length is 2 ^ 14 + 1. After the modification is complete, send the modification to the server. Expected result 2 is obtained. +3. When the server receives the Change Cipher Spec message, check the value returned by the HITLS_Accept interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +2. The field is successfully modified and sent to the client. +3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + + testInfo.state = TRY_RECV_CLIENT_KEY_EXCHANGE; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.ccsMsg.extra.data); + frameMsg.body.ccsMsg.extra.data = certDataTemp; + frameMsg.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg.body.ccsMsg.extra.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CERTIFICATE_VERIFY); + bool isCcsRecv = testInfo.server->ssl->method.isRecvCCS(testInfo.server->ssl); + ASSERT_TRUE(isCcsRecv == false); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC004 +* @title The client receives a Change Cipher Spec message with a length of zero. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +2. The client initiates a DTLS over SCTP link request. After sending a Finish message, the client constructs a Change Cipher Spec message with a zero length and sends the message to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +2. The client receives the message, which is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_SEND_FINISH; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server) == HITLS_SUCCESS); + + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + frameType1.versionType = HITLS_VERSION_TLS12; + frameType1.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType1, &frameMsg1) == HITLS_SUCCESS); + + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg1.body.ccsMsg.extra.data); + frameMsg1.body.ccsMsg.extra.data = certDataTemp; + frameMsg1.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg1.body.ccsMsg.extra.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType1, &frameMsg1, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData1->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + + FRAME_CleanMsg(&frameType1, &frameMsg1); + memset_s(&frameMsg1, sizeof(frameMsg1), 0, sizeof(frameMsg1)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_RECORD_OVERFLOW); + + ASSERT_EQ(testInfo.client->ssl->hsCtx->state, TRY_RECV_NEW_SESSION_TICKET); + bool isCcsRecv = testInfo.client->ssl->method.isRecvCCS(testInfo.client->ssl); + ASSERT_TRUE(isCcsRecv == false); +exit: + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + +int32_t StatusPark1(HandshakeTestInfo *testInfo) +{ + if(testInfo->isServerExtendMasterSecret == true){ + testInfo->config->isSupportExtendMasterSecret = true; + }else { + testInfo->config->isSupportExtendMasterSecret = false; + } + testInfo->config->isSupportRenegotiation = false; + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if(testInfo->isServerExtendMasterSecret == true){ + testInfo->config->isSupportExtendMasterSecret = false; + }else { + testInfo->config->isSupportExtendMasterSecret = true; + } + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (FRAME_CreateConnection(testInfo->client, testInfo->server, + testInfo->isClient, testInfo->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark1(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusPark1(testInfo); +} + + +/* @ +* @test UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC001 +* @title The client does not forcibly verify the master key extension. The server supports the master key extension. The extended information in client hello and server hello is carried. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server, and configure the client not to forcibly verify the master key extension. The server supports this function. Expected result 1 is obtained. +2. When the client continuously sets up a link, the server receives the CLIENT_HELLO message and checks whether the extension of the master key is carried. Expected result 2 is obtained. +3. When the client receives the SERVER_HELLO message, check whether the message carries the master key extension. Expected result 2 is obtained. +4. Continue to establish the link. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +2. The master key extension is expected to be carried. +3. Expected Master Key Extension +4. The link is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + testInfo.isServerExtendMasterSecret = true; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark1(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(frameMsg.body.hsMsg.body.clientHello.extendedMasterSecret.exState , INITIAL_FIELD); + + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_CFG_FreeConfig(testInfo.config); + + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark1(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf1 = ioUserData1->recMsg.msg; + uint32_t recvLen1 = ioUserData1->recMsg.len; + ASSERT_TRUE(recvLen1 != 0); + + frameType1.versionType = HITLS_VERSION_TLS12; + frameType1.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType1, recvBuf1, recvLen1, &frameMsg1, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(frameMsg1.body.hsMsg.body.serverHello.extendedMasterSecret.exState , INITIAL_FIELD); + + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.state = HS_STATE_BUTT; + ASSERT_TRUE(DefaultCfgStatusPark1(&testInfo) == HITLS_SUCCESS); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC002 +* @title The client supports the extension of the key for strong verification, but the server does not. The clienthello carries the extension of the master key, and the serverhello carries the extension of the master key. The link is successfully established. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server, and configure the client to forcibly verify the master key extension. The server does not support the extension. Expected result 1 is displayed. +2. When the client is continuously establishing a link, the server receives the Client_Hello message and checks whether the client_Hello message carries the master key extension. Expected result 2 is obtained. +3. When the client receives the SERVER_HELLO message, check whether the message carries the master key extension. Expected result 3 is obtained. +4. Continue to establish the link. Expected result 4 is obtained. +* @expect 1. The initialization is successful. +2. Expected to carry the master key extension. +3. The master key extension is expected to be carried. +4. The link is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC002(void) +{ + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + FRAME_Init(); + + HITLS_Config *c_config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(c_config != NULL); + HITLS_Config *s_config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(s_config != NULL); + + HITLS_CFG_SetExtenedMasterSecretSupport(c_config, true); + HITLS_CFG_SetExtenedMasterSecretSupport(s_config, false); + + FRAME_LinkObj *client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) , HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.body.hsMsg.body.clientHello.extendedMasterSecret.exState == INITIAL_FIELD); + + HITLS_Accept(server->ssl); + FRAME_TrasferMsgBetweenLink(server, client); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) , HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf1 = ioUserData1->recMsg.msg; + uint32_t recvLen1 = ioUserData1->recMsg.len; + ASSERT_TRUE(recvLen1 != 0); + + uint32_t parseLen1 = 0; + frameType1.versionType = HITLS_VERSION_TLS12; + frameType1.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType1, recvBuf1, recvLen1, &frameMsg1, &parseLen1) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg1.body.hsMsg.body.serverHello.extendedMasterSecret.exState == INITIAL_FIELD); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) , HITLS_SUCCESS); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +/* @ +* @test UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC004 +* @title The client and server support master key extension. The client hello message carries master key extension and the server hello message carries master key extension. The link is successfully established. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server to support master key extension. (Expected result 1) +2. When the client continuously sets up a link, the server checks whether the client_hello message carries the master key extension when receiving the CLIENT_HELLO message. Expected result 2 is obtained. +3. When the client receives the SERVER_HELLO message, check whether the message carries the master key extension. Expected result 3 is obtained. +4. Continue to establish the link. Expected result 4 is obtained. +* @expect 1. The initialization is successful. +2. Expected to carry the master key extension. +3. The master key extension is expected to be carried. +4. The link is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + + FRAME_Msg frameMsg1 = {0}; + FRAME_Type frameType1 = {0}; + testInfo.isSupportExtendMasterSecret = true; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.body.hsMsg.body.clientHello.extendedMasterSecret.exState == INITIAL_FIELD); + + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData1 = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf1 = ioUserData1->recMsg.msg; + uint32_t recvLen1 = ioUserData1->recMsg.len; + ASSERT_TRUE(recvLen1 != 0); + + frameType1.versionType = HITLS_VERSION_TLS12; + frameType1.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType1, recvBuf1, recvLen1, &frameMsg1, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg1.body.hsMsg.body.serverHello.extendedMasterSecret.exState == INITIAL_FIELD); + + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + testInfo.state = HS_STATE_BUTT; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + FRAME_CleanMsg(&frameType1, &frameMsg1); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + + + + +int32_t StatusPark2(HandshakeTestInfo *testInfo) +{ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (FRAME_CreateConnection(testInfo->client, testInfo->server, + testInfo->isClient, testInfo->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_extensions.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_extensions.data new file mode 100644 index 00000000..7d613643 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_extensions.data @@ -0,0 +1,20 @@ +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC002 +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC002: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC003 +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC003: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC004 +UT_TLS_TLS12_RFC5246_CONSISTENCY_MSGLENGTH_TOOLONG_TC004: + +UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC001 +UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC001: + +UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC002 +UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC002: + +UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC004 +UT_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_TC004: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_malformed_msg.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_malformed_msg.c new file mode 100644 index 00000000..9051f9e3 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_malformed_msg.c @@ -0,0 +1,245 @@ +/* + * 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_BASE test_suite_tls12_consistency_rfc5246_malformed_msg */ +/* BEGIN_HEADER */ + +#include "hitls_error.h" +#include "tls.h" +#include "rec.h" +#include "hs_msg.h" +#include "hs_ctx.h" +#include "hs_extensions.h" +#include "frame_msg.h" + +/* END_HEADER */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC009 +* @title record layer allows the sending of the APPdata message with the length of zero. +* @precon nan +* @brief + 1. Establish a link. After the link is established, construct an Appdata message with zero length and send it to the + server. Then, send an APPdata message with data to the server. Expected result 1 is obtained. +* @expect 1. Expected success +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC009(int messageLen) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + ASSERT_EQ(TlsCtxNew(BSL_UIO_TCP), HITLS_SUCCESS); + ASSERT_EQ(REC_Init(g_tlsCtx), HITLS_SUCCESS); + /* 1. Establish a link. After the link is established, construct an Appdata message with zero length and send it to + * the server. Then, send an APPdata message with data to the server. */ + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + uint8_t data[REC_MAX_CIPHER_TEXT_LEN]; + ASSERT_EQ(REC_Write(clientTlsCtx, REC_TYPE_APP, data, messageLen), HITLS_SUCCESS); +exit: + TlsCtxFree(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC010 +* @title record layer allows the sending of the APPdata message with the length of zero. +* @precon nan +* @brief +1. Establish a link. After the link is established, construct an APPdata message with zero length and send it to the +client. Then, send an APPdata message with data to the client. Expected result 1 is obtained. +* @expect 1. Expected success +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC010(int messageLen) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + ASSERT_EQ(TlsCtxNew(BSL_UIO_TCP), HITLS_SUCCESS); + ASSERT_EQ(REC_Init(g_tlsCtx), HITLS_SUCCESS); + /* 1. Establish a link. After the link is established, construct an APPdata message with zero length and send it to + * the client. Then, send an APPdata message with data to the client. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + uint8_t data[REC_MAX_CIPHER_TEXT_LEN]; + ASSERT_EQ(REC_Write(serverTlsCtx, REC_TYPE_APP, data, messageLen), HITLS_SUCCESS); +exit: + TlsCtxFree(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS12_RFC5246_CONSISTENCY_MISS_CLIENT_KEYEXCHANGE_TC001 +* @title During the handshake, the client receives the CCS when the client is in the TRY_RECV_FINISH state. +* @precon nan +* @brief 1. Configure the single-end authentication. After the server sends the serverhellodone message, the client + stops in the try send client key exchange state. Expected result 1 + 2. Construct an unexpected CCS message and send it to the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. + 2. The connection fails to be established and the server returns an unexpected message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_MISS_CLIENT_KEYEXCHANGE_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + /* 1. Configure the single-end authentication. After the server sends the serverhellodone message, the client + * stops in the try send client key exchange state. */ + testInfo.state = TRY_SEND_CLIENT_KEY_EXCHANGE; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + + testInfo.isSupportClientVerify = false; + testInfo.isSupportNoClientCert = false; + testInfo.needStopBeforeRecvCCS = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + // 2. Construct an unexpected CCS message and send it to the server. + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + +// To test whether fragmented messages can be received correctly. Test REC_TlsReadNbytes +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5246_CONSISTENCY_FRAGMENTED_MSG_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + int32_t ret = HITLS_Connect(client->ssl); + ASSERT_TRUE(ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(client->ssl->hsCtx->state == TRY_RECV_SERVER_HELLO); + + ret = HITLS_Accept(server->ssl); + ASSERT_TRUE(ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(server->ssl->hsCtx->state == TRY_RECV_CLIENT_HELLO); + // Handshake messages are divided into two records, and the two records are read separately. + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t dataLen = MAX_RECORD_LENTH; + ASSERT_EQ(memcpy_s(data, MAX_RECORD_LENTH, ioUserData->sndMsg.msg, ioUserData->sndMsg.len), 0); + dataLen = ioUserData->sndMsg.len; + + uint32_t msglength = BSL_ByteToUint16(&data[3]); + uint32_t msgLen = (msglength - 1) / 2; + uint32_t len = 5 + msgLen; // record + handshakemsg + // Send the first segment of packets. eg.163 = (5 + 70) + 5 +83 + uint8_t recorddata1[] = {0x16, 0x03, 0x03, 0x00, 0x46}; + // The last two bytes of the first five bytes of the length of bodylen are modified. + BSL_Uint16ToByte((uint16_t)msgLen, &recorddata1[3]); + ASSERT_EQ(memcpy_s(ioUserData->sndMsg.msg, MAX_RECORD_LENTH, data, len), 0); + ASSERT_EQ(memcpy_s(ioUserData->sndMsg.msg, MAX_RECORD_LENTH, recorddata1, sizeof(recorddata1)), 0); + // Send the second segment of packets. eg.163 = 5 + 70 + (5 +83) + uint8_t recorddata2[] = {0x16, 0x03, 0x03, 0x00, 0x53}; + msgLen = dataLen - len; + BSL_Uint16ToByte((uint16_t)msgLen, &recorddata2[3]); + ASSERT_EQ(memcpy_s(ioUserData->sndMsg.msg + len, MAX_RECORD_LENTH - len, recorddata2, sizeof(recorddata2)), 0); + ioUserData->sndMsg.len = len + 5; + ASSERT_EQ(memcpy_s(ioUserData->sndMsg.msg + ioUserData->sndMsg.len, MAX_RECORD_LENTH - len, data + len, dataLen - len), 0); + ioUserData->sndMsg.len += dataLen - len; + + ret = HITLS_Connect(client->ssl); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ret = HITLS_Accept(server->ssl); + ASSERT_EQ(ret, HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_malformed_msg.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_malformed_msg.data new file mode 100644 index 00000000..909237f6 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5246_malformed_msg.data @@ -0,0 +1,17 @@ +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC009_1 Arguments Test +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC009:0 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC009_2 Arguments Test +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC009:20 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC010_1 Arguments Test +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC010:0 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC010_2 Arguments Test +UT_TLS_TLS12_RFC5246_CONSISTENCY_RECV_ZEROLENGTH_MSG_TC010:20 + +UT_TLS_TLS12_RFC5246_CONSISTENCY_MISS_CLIENT_KEYEXCHANGE_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_MISS_CLIENT_KEYEXCHANGE_TC001: + +UT_TLS_TLS12_RFC5246_CONSISTENCY_FRAGMENTED_MSG_TC001 +UT_TLS_TLS12_RFC5246_CONSISTENCY_FRAGMENTED_MSG_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5746.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5746.c new file mode 100644 index 00000000..181a7736 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5746.c @@ -0,0 +1,1265 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "process.h" +#include "securec.h" +#include "hitls_error.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "bsl_sal.h" +#include "simulate_io.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "alert.h" +#include "session_type.h" +#include "hitls_type.h" +#include "rec.h" +#include "hs_msg.h" +#include "hs_extensions.h" +#include "frame_msg.h" +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "bsl_uio.h" +#include "pack.h" +#include "send_process.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "rec_wrapper.h" +#include "conn_init.h" +#include "cert_callback.h" +#include "change_cipher_spec.h" +#include "common_func.h" +#include "uio_base.h" + +#define READ_BUF_SIZE (18 * 1024) +/* END_HEADER */ + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isSupportRenegotiation; + bool isServerExtendMasterSecret; +} HandshakeTestInfo; + +int32_t StatusPark(HandshakeTestInfo *testInfo) +{ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (FRAME_CreateConnection(testInfo->client, testInfo->server, testInfo->isClient, testInfo->state) != + HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +static void Test_ServerHelloHaveSecRenego(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.secRenego.exState, INITIAL_FIELD); + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusPark(testInfo); +} + +int32_t StatusPark1(HandshakeTestInfo *testInfo) +{ + if (testInfo->isServerExtendMasterSecret == true) { + testInfo->config->isSupportExtendMasterSecret = true; + } else { + testInfo->config->isSupportExtendMasterSecret = false; + } + testInfo->config->isSupportRenegotiation = false; + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->isServerExtendMasterSecret == true) { + testInfo->config->isSupportExtendMasterSecret = false; + } else { + testInfo->config->isSupportExtendMasterSecret = true; + } + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (FRAME_CreateConnection(testInfo->client, testInfo->server, testInfo->isClient, testInfo->state) != + HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark1(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusPark1(testInfo); +} + +void Test_RenegoWrapperFunc(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.body.clientHello.secRenego.exState, INITIAL_FIELD); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +void Test_RenegoRemoveExtension(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + ASSERT_EQ(parseLen, *len); + frameMsg.body.hsMsg.body.clientHello.secRenego.exState = MISSING_FIELD; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC001 +* @titleThe client carries the renegotiation algorithm suite but does not carry the renegotiation extension. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. During continuous link setup, the server checks whether the renegotiation algorithm suite is contained and +* whether the renegotiation extension is carried when receiving the CLIENT_HELLO message. +* Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The renegotiation algorithm suite is expected to be carried, but the renegotiation extension is not +* carried. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportRenegotiation = true; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + int FlagScsv = 0; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + for (int i = 0; i < (int)frameMsg.body.hsMsg.body.clientHello.cipherSuites.size; i++) { + if (frameMsg.body.hsMsg.body.clientHello.cipherSuites.data[i] == 255) { + FlagScsv = 1; + } + } + + ASSERT_TRUE(FlagScsv == 1); + ASSERT_TRUE(frameMsg.body.hsMsg.body.clientHello.secRenego.exState == MISSING_FIELD); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC003 +* @title Enable the client and server to support renegotiation. Change the length of the renegotiated_connection field +* in the server hello message to a non-zero value. Check whether the connection is successfully established. +* @precon nan +* @brief 1. The client and server support renegotiation and connection establishment. Change the length of the +* renegotiated_connection field in the server hello message to a non-zero value. Then, the connection +* is established. Expected result 1 is obtained. +* @expect 1. The connection fails to be set up and an ALERT_HANDSHAKE_FAILURE message is sent. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportRenegotiation = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->secRenego.exDataLen.data == 0u); + serverMsg->secRenego.exDataLen.data = 1u; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* The connection fails to be set up and an ALERT_HANDSHAKE_FAILURE message is sent. */ + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC002 +* @titleThe server does not support renegotiation. The serverhello message carries the renegotiation extension. +* @precon nan +* @brief +* 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the client receives a SERVER_HELLO message during continuous link establishment, the client checks whether +* the message carries the renegotiation extension. Expected result 2 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The renegotiation extension is expected to be carried. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC002(void) +{ + FRAME_Init(); + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.isSupportRenegotiation = false; + + testInfo.config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.server != NULL); + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.client != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.body.hsMsg.body.serverHello.secRenego.exLen.data != 0); + + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + testInfo.state = HS_STATE_BUTT; + ASSERT_TRUE(DefaultCfgStatusPark1(&testInfo) == HITLS_SUCCESS); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC009 +* @title Renegotiation flag condition +* @precon nan +* @brief 1. The client and server support renegotiation and connection establishment. Before receiving the client hello +* message, the server disables security renegotiation. Expected result 1 is displayed. +* 2. After the server receives the client hello message, enable the security renegotiation on the server. +* Expected result 2 is displayed. +* @expect 1. The isSecureRenegotiation is false. +* 2. The isSecureRenegotiation is true. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC009(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + config->isSupportRenegotiation = true; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(server->ssl->negotiatedInfo.isSecureRenegotiation == false); + FRAME_LinkObj *client1 = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server1 = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client1, server1, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(server1->ssl->negotiatedInfo.isSecureRenegotiation == true); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client1); + FRAME_FreeLink(server1); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC013 +* @title Configure the client and server to support renegotiation. After the first handshake is complete, a +* renegotiation request is initiated. When the client sends a client hello message, +* Modify the message and delete the renegotiation_info extension. The server is expected to return an alert +* after receiving the message. +* @precon nan +* @brief 1. The client and server support renegotiation and connection establishment. Start renegotiation. The expected +* connection establishment is successful. +* @expect 1. When the client sends the client hello message, modify the message and remove the renegotiation_info +* extension. As a result, the expected connection establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC013(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + /* The client and server support renegotiation and connection establishment. Start renegotiation. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + config->isSupportRenegotiation = true; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + uint8_t verifyData[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataSize = 0; + ASSERT_TRUE( + HITLS_GetFinishVerifyData(client->ssl, verifyData, sizeof(verifyData), &verifyDataSize) == HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_RECV_CLIENT_HELLO, REC_TYPE_HANDSHAKE, true, NULL, Test_RenegoRemoveExtension}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HITLS_Renegotiate(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) != HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC005 +* @title The client and server support renegotiation and connection establishment. Start renegotiation. Check whether +* the serverhello contains the renegotiation extension. Check whether the connection is successfully +* established and verify the negotiation behavior. +* @precon nan +* @brief 1. The client and server support renegotiation and connection establishment. Start renegotiation. Expected +* result 1 is obtained. +* @expect 1. Modify the cipher suite in the client hello, add the SCSV, and check whether the connection is successfully +* set up. Expected result 2 is obtained. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC005(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + /* The client and server support renegotiation and connection establishment. Start renegotiation. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + config->isSupportRenegotiation = true; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + + uint8_t verifyData[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataSize = 0; + ASSERT_TRUE( + HITLS_GetFinishVerifyData(client->ssl, verifyData, sizeof(verifyData), &verifyDataSize) == HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_RECV_CLIENT_HELLO, REC_TYPE_HANDSHAKE, true, NULL, Test_RenegoWrapperFunc}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HITLS_Renegotiate(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC010 +* @title Configure the client and server to support renegotiation and connection establishment. The +* renegotiated_connection field in the client hello extension received by the server is not 0. +* @precon nan +* @brief 1. Configure the client and server to support renegotiation and establish a connection. Expected result 1 is +* obtained. +* 2. Modify the client hello message received by the server. Modify the renegotiated_connection field extended +* by the (HS_EX_TYPE_RENEGOTIATION_INFO) to ensure that the length of the field is not 0. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT message. The level is ALERT_LEVEL_FATAL and the description is +* ALERT_HANDSHAKE_FAILURE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC010(void) +{ + /* Configure the client and server to support renegotiation and establish a connection. */ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportRenegotiation = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusPark(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS12; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Modify the client hello message received by the server. Modify the renegotiated_connection field extended by the + * (HS_EX_TYPE_RENEGOTIATION_INFO) to ensure that the length of the field is not 0. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(clientMsg->secRenego.exDataLen.data == 0u); + clientMsg->secRenego.exState = INITIAL_FIELD; + clientMsg->secRenego.exType.state = INITIAL_FIELD; + clientMsg->secRenego.exType.data = 0xFF01u; + clientMsg->secRenego.exLen.state = INITIAL_FIELD; + clientMsg->secRenego.exLen.data = 2; + clientMsg->secRenego.exDataLen.state = INITIAL_FIELD; + clientMsg->secRenego.exDataLen.data = 1u; + clientMsg->secRenego.exData.state = INITIAL_FIELD; + clientMsg->secRenego.exData.size = 1; + clientMsg->secRenego.exData.data = BSL_SAL_Calloc(1, sizeof(uint8_t)); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_TRUE(HITLS_Accept(testInfo.server->ssl) == HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_HANDSHAKE_FAILURE); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC011 +* @title The client and server support renegotiation and connection establishment. Check whether the serverhello +* contains the renegotiation extension. Check whether the connection is successfully established and verify the +* negotiation behavior. +* @precon nan +* @brief 1. If the client and server support renegotiation and connection establishment, check the serverhello message +* that contains the renegotiation extension, and check whether the connection establishment is successful. +* (Expected result 1) +* @expect 1. Modify the cipher suite in the client hello, add the SCSV, and check whether the connection is successfully +* set up. Expected result 2 is obtained. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC011(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + /* If the client and server support renegotiation and connection establishment, check the serverhello message that + * contains the renegotiation extension, and check whether the connection establishment is successful. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + config->isSupportRenegotiation = true; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + /* Modify the cipher suite in the client hello, add the SCSV, and check whether the connection is successfully set + * up. */ + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ServerHelloHaveSecRenego}; + RegisterWrapper(wrapper); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ClientHello_SecRenego(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_EQ(clientMsg->secRenego.exState, INITIAL_FIELD); + ASSERT_TRUE( + clientMsg->cipherSuites.data[clientMsg->cipherSuitesSize.data / 2 - 1] != TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC004 +* @title The client and server support renegotiation and connection establishment. Check whether the clienthello +* contains the renegotiation extension. Check whether the connection is successfully established and verify the +* negotiation behavior. +* @precon nan +* @brief 1. Enable the client to support renegotiation and connection establishment. Initiate renegotiation and check +* whether the client hello contains secure Renegotiation extension and whether the cipher suite list contains +* the SCSV cipher suite. +* @expect 1. The client hello message contain the secure Renegotiation extension but does not contain the SCSV cipher +* suite. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC004(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + /* If the client and server support renegotiation and connection establishment, check the clienthello message that + * contains the renegotiation extension, and check whether the connection establishment is successful. */ + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + config->isSupportRenegotiation = true; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_EQ(clientTlsCtx->state, CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ClientHello_SecRenego}; + RegisterWrapper(wrapper); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyServerHello_Secrenegotiation1( + HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->secRenego.exData.data[0] = serverMsg->secRenego.exData.data[0] + 1; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_ModifyServerHello_Secrenegotiation2( + HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->secRenego.exData.data[serverMsg->secRenego.exData.size - 1] = + serverMsg->secRenego.exData.data[serverMsg->secRenego.exData.size - 1] + 1; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC007 +* @title HITLS_GetRenegotiationState Interface Verification +* @precon nan +* @brief Configure the client and server to support renegotiation and connection establishment. +* Initiate renegotiation, modify the first part of renegotiated_connection in the server hello message, +* and check whether the connection is set up successfully. +* @expect +* create connection failed +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC007(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyServerHello_Secrenegotiation1}; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC008 +* @spec - +* @title HITLS_GetRenegotiationState Interface Verification +* @precon nan +* @brief Configure the client and server to support renegotiation and connection establishment. +* Initiate renegotiation, modify the last part of renegotiated_connection in the server hello message, +* and check whether the connection is set up successfully. +* @expect +* create connection failed +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC008(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyServerHello_Secrenegotiation2}; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyServerHello_Secrenegotiation3( + HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->secRenego.exState = MISSING_FIELD; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC006 +* @title HITLS_GetRenegotiationState Interface Verification +* @precon nan +* @brief Configure the client to support renegotiation and the server to support renegotiation and connection +* establishment. Start renegotiation, construct a server hello message that does not contain the extension, +* and check whether the connection is successfully set up. +* @expect +* The server hello message does not contain the Secrenegotiation extension, and the connection fails to be established +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC006(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyServerHello_Secrenegotiation3}; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_HANDSHAKE_FAILURE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyClientHello_Secrenegotiation1( + HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->secRenego.exData.data[0] = clientMsg->secRenego.exData.data[0] + 1; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0014 +* @title The value of client_verify_data in the client hello message does not match the actual value +* in the renegotiation state. +* @precon nan +* @brief +* Configure the client and server to support renegotiation. +* After the first handshake is complete, initiate a renegotiation request. +* When the client sends a client hello message, +* modify the value of client_verify_data in the renegotiation_info extension. +* @expect +* The server returns an alert message after receiving the message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0014(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyClientHello_Secrenegotiation1}; + RegisterWrapper(wrapper); + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_HANDSHAKE_FAILURE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyServerHello_No_client_verify_data( + HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->secRenego.exData.size = 0; + serverMsg->secRenego.exDataLen.data = 0; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0015 +* @title The client_verify_data and server_verify_data fields of the client hello message + are lost in the renegotiation state. +* @precon nan +* @brief +* Configure the client and server to support renegotiation. +* After the first handshake is complete, initiate a renegotiation request. +* When the server sends a server hello message, +* delete the values of client_verify_data and server_verify_data from the renegotiation_info extension. +* @expect +* The client returns an alert message after receiving the message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0015(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyServerHello_No_client_verify_data}; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_HANDSHAKE_FAILURE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ClientHelloHaveSecRenego(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_EQ(clientMsg->secRenego.exState, INITIAL_FIELD); + clientMsg->cipherSuites.data[clientMsg->cipherSuitesSize.data / 2 - 1] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV; + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0012 +* @title In the renegotiation state, the client hello message carries the SCSV. +* @precon nan +* @brief +* Configure the client and server to support renegotiation. After the first handshake is complete, +* initiate a renegotiation request. When the client sends a client hello message, modify the cipher suite and add SCSV. +* After receiving the message, the server is expected to return an alert message. +* @expect +* The client returns an alert message after receiving the message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0012(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ClientHelloHaveSecRenego}; + RegisterWrapper(wrapper); + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_HANDSHAKE_FAILURE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5746.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5746.data new file mode 100644 index 00000000..3fb238b8 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc5746.data @@ -0,0 +1,44 @@ +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC001 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC001: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC003 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC003: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC002 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC002: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC009 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC009: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC013 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC013: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC005 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC005: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC010 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC010: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC011 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC011: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC004 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC004: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC007 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC007: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC008 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC008: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC006 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC006: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0014 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0014: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0015 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0015: + +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0012 +UT_TLS_TLS12_RFC5746_CONSISTENCY_EXTENDED_RENEGOTIATION_FUNC_TC0012: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc8422.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc8422.c new file mode 100644 index 00000000..05ede5e0 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc8422.c @@ -0,0 +1,78 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls12_consistency_rfc5246 */ + +#include "securec.h" +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "conn_init.h" +/* END_HEADER */ + +#define g_uiPort 12121 + +/** @ +* @test UT_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_LOSE_POINT_FUNC_TC001 +* @title clienthello does not carry the point format extension. +* @precon nan +* @brief Set the ECC cipher suite. Before the server receives the client hello message, the point format extension is +* removed. It is expected that the negotiation is normal and the client can receive the server hello done +* message. +* @expect 1. The connection is set up normally and the client can receive the server hello done message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_LOSE_POINT_FUNC_TC001(void) +{ + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = false; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportClientVerify = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite(&testInfo) == 0); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint32_t parseLen = 0; + FRAME_ParseMsg(&frameType, ioUserData->recMsg.msg, ioUserData->recMsg.len, &frameMsg, &parseLen); + /* Set the ECC cipher suite. Before the server receives the client hello message, the point format extension is + * removed. */ + frameMsg.body.hsMsg.body.clientHello.pointFormats.exState = MISSING_FIELD; + FRAME_PackMsg(&frameType, &frameMsg, ioUserData->recMsg.msg, MAX_RECORD_LENTH, &parseLen); + ioUserData->recMsg.len = parseLen; + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + // the client can receive the server hello done message. + ASSERT_TRUE( + FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO_DONE) == HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc8422.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc8422.data new file mode 100644 index 00000000..a640c138 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_frame_tls12_consistency_rfc8422.data @@ -0,0 +1,2 @@ +UT_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_LOSE_POINT_FUNC_TC001 +UT_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_LOSE_POINT_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246.c new file mode 100644 index 00000000..87c84605 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246.c @@ -0,0 +1,352 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls12_consistency_rfc5246 */ +/* END_HEADER */ +static void TestFrameClientChangeCompressMethod(void *msg, void *userData) +{ + (void)msg; + (void)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->compressionMethods.state = ASSIGNED_FIELD; + *clientHello->compressionMethods.data = 1; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC001 +* @title The record layer does not support compression. +* @precon nan +* @brief 1. When the client sends a client hello message, the compression flag is changed to 1. As a result, the +connection fails to be established. +* @expect 1. Link establishment fails. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(clientCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_256_CBC_SHA"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // When the client sends a client hello message, the compression flag is changed to 1. + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientCtxConfig, NULL); + + HLT_FrameHandle frameHandle = { + .ctx = clientRes->ssl, + .frameCallBack = TestFrameClientChangeCompressMethod, + .userData = NULL, + .expectHsType = CLIENT_HELLO, + .expectReType = REC_TYPE_HANDSHAKE, + .ioState = EXP_NONE, + .pointType = POINT_SEND, + }; + ASSERT_TRUE(HLT_SetFrameHandle(&frameHandle) == HITLS_SUCCESS); + int ret = HLT_TlsConnect(clientRes->ssl); + ASSERT_TRUE(ret != 0); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +static void TestFrameServerChangeCompressMethod(void *msg, void *userData) +{ + (void)msg; + (void)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->compressionMethod.state = ASSIGNED_FIELD; + serverHello->compressionMethod.data = 1; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC002 +* @title The record layer does not support compression. +* @precon nan +* @brief 1. When the server sends the serverhello message, the compression flag is changed to 1, and the client is +expected to send the alert message. +* @expect 1. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC002(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(clientCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_256_CBC_SHA"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + /* When the server sends the serverhello message, the compression flag is changed to 1. */ + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_FrameHandle frameHandle = { + .ctx = serverRes->ssl, + .frameCallBack = TestFrameServerChangeCompressMethod, + .userData = NULL, + .expectHsType = SERVER_HELLO, + .expectReType = REC_TYPE_HANDSHAKE, + .ioState = EXP_NONE, + .pointType = POINT_SEND, + }; + ASSERT_TRUE(HLT_SetFrameHandle(&frameHandle) == HITLS_SUCCESS); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC008 +* @title two-way authentication: The certificate configured on the client does not match the signature algorithm +supported by the server. As a result, the client fails to load the certificate. +* @precon nan +* @brief Set the dual-end authentication, the signature algorithm supported by the server to DSA_SHA224, and the client +certificate to RSA. The expected certificate loading failure occurs on the client. +* @expect 1. The link is set up successfully. +* 2. Link establishment failure. + +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC008(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + /* Set the dual-end authentication, the signature algorithm supported by the server to DSA_SHA224, and the client + * certificate to RSA. */ + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + HLT_SetSignature(serverCtxConfig, "CERT_SIG_SCHEME_DSA_SHA224"); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_128_GCM_SHA256"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + int ret = HLT_TlsConnect(clientRes->ssl); + ASSERT_TRUE(ret != 0); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +int32_t SendKeyupdate_Err(HITLS_Ctx *ctx) +{ + int32_t ret; + /** Initialize the message buffer. */ + uint8_t buf[5] = {KEY_UPDATE, 0x00, 0x00, 0x01, 0x01}; + size_t len = 5; + + /** Write records. */ + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} +/* tls12 receive keyupdate message during transporting*/ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_RECV_KEYUPDATE_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + clientCtxConfig->isSupportExtendMasterSecret=true; + serverCtxConfig->isSupportExtendMasterSecret=true; + serverCtxConfig->isSupportSessionTicket=true; + clientCtxConfig->isSupportSessionTicket=true; + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(remoteProcess, clientRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf2[READ_BUF_LEN_18K] = {0}; + uint32_t readLen2= 0; + ASSERT_EQ(HLT_ProcessTlsRead(localProcess, serverRes, readBuf2, READ_BUF_LEN_18K, &readLen2) , 0); + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + ASSERT_EQ(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf2, READ_BUF_LEN_18K, &readLen2) , 0); + + HITLS_Ctx *serverCtx = (HITLS_Ctx *)serverRes->ssl; + ASSERT_TRUE(serverCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_EQ(SendKeyupdate_Err(serverRes->ssl) , HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_LEN_18K] = {0}; + uint32_t readLen= 0; + + ASSERT_EQ(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, READ_BUF_LEN_18K, &readLen) , HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_EQ(HLT_ProcessTlsRead(localProcess, serverRes, readBuf, READ_BUF_LEN_18K, &readLen) , HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(serverRes->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_RECV); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +int32_t SendNEW_SESSION_TICKET_Err(HITLS_Ctx *ctx) +{ + int32_t ret; + /** Initialize the message buffer. */ + uint8_t buf[32] = {NEW_SESSION_TICKET,0,0,0x1c,0x20,0xc1,}; + size_t len = 32; + + /** Write records. */ + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} +/* tls12 receive NST message during transporting*/ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NST_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + clientCtxConfig->isSupportExtendMasterSecret=true; + serverCtxConfig->isSupportExtendMasterSecret=true; + serverCtxConfig->isSupportSessionTicket=true; + clientCtxConfig->isSupportSessionTicket=true; + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(remoteProcess, clientRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf2[READ_BUF_LEN_18K] = {0}; + uint32_t readLen2= 0; + ASSERT_EQ(HLT_ProcessTlsRead(localProcess, serverRes, readBuf2, READ_BUF_LEN_18K, &readLen2) , 0); + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + ASSERT_EQ(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf2, READ_BUF_LEN_18K, &readLen2) , 0); + + HITLS_Ctx *serverCtx = (HITLS_Ctx *)serverRes->ssl; + ASSERT_TRUE(serverCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_EQ(SendNEW_SESSION_TICKET_Err(serverRes->ssl) , HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_LEN_18K] = {0}; + uint32_t readLen= 0; + + ASSERT_EQ(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, READ_BUF_LEN_18K, &readLen) , HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_EQ(HLT_ProcessTlsRead(localProcess, serverRes, readBuf, READ_BUF_LEN_18K, &readLen) , HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(serverRes->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_RECV); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246.data new file mode 100644 index 00000000..64a377a6 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246.data @@ -0,0 +1,14 @@ +SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_ERRO_COMPRESSION_FRAGMENT_TC002: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC008 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC008: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RECV_KEYUPDATE_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RECV_KEYUPDATE_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NST_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RECV_NST_TC001: diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_cert.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_cert.c new file mode 100644 index 00000000..58e2718b --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_cert.c @@ -0,0 +1,341 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls12_consistency_rfc5246 */ +/* END_HEADER */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHER_SUITE_NOT_SUITABLE_CERT_TC001 +* @title The public key algorithm used to verify the server terminal certificate must match the algorithm suite. +* @precon nan +* @brief 1. Create a config file, configure the server certificate as the ECDSA public key, and configure the ECDHE_RSA algorithm suite in the hello message on the client. + 2. The client invokes the HITLS_Connect interface. (Expected result 1) +* @expect 1. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHER_SUITE_NOT_SUITABLE_CERT_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Create a config file, configure the server certificate as the ECDSA public key, and configure the ECDHE_RSA algorithm suite in the hello message on the client. + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); // failed in + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1"); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + // The client invokes the HITLS_Connect interface. + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + +exit: + HLT_FreeAllProcess(); + return; +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_NOTSET_CERT_TC001 +* @title The certificate chain sent by the server does not contain the root certificate. +* @precon nan +* @brief If no certificate is set on the client and the server sends a complete certificate chain, +* link establishment fails. +* @expect 1. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_NOTSET_CERT_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_256_CBC_SHA"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + /* If no certificate is set on the client and the server sends a complete certificate chain,link establishment + * fails. */ + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_WITHOUT_ROOT_CERT_TC001 +* @title The certificate chain sent by the server does not contain the root certificate. +* @precon nan +* @brief Set the root certificate and send a certificate chain that does not contain the root certificate. +* The link is successfully set up. +* @expect 1. Return a success message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_WITHOUT_ROOT_CERT_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + + // Set the root certificate and send a certificate chain that does not contain the root certificate. + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(clientCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_256_CBC_SHA"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SET_ERRO_ROOT_CERT_TC001 +* @title The certificate chain sent by the server does not contain the root certificate. +* @precon nan +* @brief The root certificate is incorrectly set on the client. As a result, the link fails to be established. +* @expect 1. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SET_ERRO_ROOT_CERT_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, false); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // The root certificate is incorrectly set on the client. + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetCertPath(clientCtxConfig, "rsa_sha512/otherRoot.crt", "rsa_sha512/otherInter.crt", + "rsa_sha512/otherInter2.crt", "rsa_sha512/otherInter2.key", "NULL", "NULL"); + + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_256_CBC_SHA"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + HLT_FreeAllProcess(); + return; +} +/* END_CASE */ + +/** + * Configure the certificate signature as CERT_SIG_SCHEME_RSA_PKCS1_SHA256. + * Set the algorithm suite to HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256. + * The signature type in the cipher suite does not match that in the certificate, + * Expected link establishment failure, as shown in the log. + * select certificate fail + * have no suitable cert + * can not find a appropriate cipher suite + */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHERSUITE_SIG_MATCH_CERT_SIG_TC002() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, false); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + HLT_SetCertPath(serverCtxConfig, "rsa_sha256/ca.der:rsa_sha256/inter.der", "rsa_sha256/inter.der", + "rsa_sha256/server.der", "rsa_sha256/server.key.der", "NULL", "NULL"); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetCertPath(clientCtxConfig, "rsa_sha256/ca.der:rsa_sha256/inter.der", "NULL", "NULL", "NULL", "NULL", + "NULL"); + // Set the algorithm suite to HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA. + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC001 +* @title The keyusage extension of the server certificate does not contain the keyEncipherment usage. +* As a result, the link fails to be established. +* @precon nan +* @brief 1. Set the server certificate to an RSA certificate that contains the keyusage extension, + The extension does not contain the keyEncipherment usage. + The negotiation cipher suite is the RSA cipher suite. Expected result 1 is obtained. +* @expect 1. connection setup failed +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC001() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, false); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + HLT_SetCertPath(serverCtxConfig, "rsa_sha512/root.der", "rsa_sha512/intca.der", + "rsa_sha512/usageKeyEncipher.der", "rsa_sha512/usageKeyEncipher.key.der", "NULL", "NULL"); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_RSA_WITH_AES_256_GCM_SHA384"); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetCertPath(clientCtxConfig, "rsa_sha512/root.der", "rsa_sha512/intca.der", + "rsa_sha512/server.der", "rsa_sha512/server.key.der", "NULL", "NULL"); + clientCtxConfig->needCheckKeyUsage = true; + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC002 +* @title Failed to set up the link because the keyuage extension does not match. +* @precon nan +* @brief 1. Configure the server certificate with the keyuage extension and do not support digitalSignature. + Expected result 1 is obtained. +* @expect 1. connection setup failed +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC002() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, false); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + HLT_SetCertPath(serverCtxConfig, "rsa_sha512/root.der", "rsa_sha512/intca.der", + "rsa_sha512/usagedigitalSign.der", "rsa_sha512/usagedigitalSign.key.der", "NULL", "NULL"); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetCertPath(clientCtxConfig, "rsa_sha512/root.der", "rsa_sha512/intca.der", + "rsa_sha512/server.der", "rsa_sha512/server.key.der", "NULL", "NULL"); + clientCtxConfig->needCheckKeyUsage = true; + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_cert.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_cert.data new file mode 100644 index 00000000..d135776a --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_cert.data @@ -0,0 +1,20 @@ +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHER_SUITE_NOT_SUITABLE_CERT_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHER_SUITE_NOT_SUITABLE_CERT_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_NOTSET_CERT_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_NOTSET_CERT_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_WITHOUT_ROOT_CERT_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_SERVER_WITHOUT_ROOT_CERT_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SET_ERRO_ROOT_CERT_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SET_ERRO_ROOT_CERT_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHERSUITE_SIG_MATCH_CERT_SIG_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHERSUITE_SIG_MATCH_CERT_SIG_TC002: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_KEYUSAGE_CERT_TC002: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_extensions.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_extensions.c new file mode 100644 index 00000000..c3483e2f --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_extensions.c @@ -0,0 +1,2185 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "process.h" +#include "securec.h" +#include "hitls_error.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "bsl_sal.h" +#include "simulate_io.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "alert.h" +#include "session_type.h" +#include "process.h" +#include "hitls_type.h" +#include "rec.h" +#include "hs_msg.h" +#include "hs_extensions.h" +#include "frame_msg.h" +/* END_HEADER */ + +#define PORT 19800 + +#define MAX_SESSION_ID_SIZE TLS_HS_MAX_SESSION_ID_SIZE +#define MIN_SESSION_ID_SIZE TLS_HS_MIN_SESSION_ID_SIZE +#define COOKIE_SIZE 32u +#define DN_SIZE 32u +#define EXTRA_DATA_SIZE 12u +#define MAX_PROTOCOL_LEN1 65536 +#define READ_BUF_SIZE 18432 +#define ROOT_DER "%s/ca.der:%s/inter.der" +#define INTCA_DER "%s/inter.der" +#define SERVER_DER "%s/server.der" +#define SERVER_KEY_DER "%s/server.key.der" +#define CLIENT_DER "%s/client.der" +#define CLIENT_KEY_DER "%s/client.key.der" +typedef struct { + int port; + HITLS_HandshakeState expectHsState; // Expected Local Handshake Status + bool alertRecvFlag; // Indicates whether the alert is received. The value fasle indicates the sent alert, and the value true indicates the received alert + ALERT_Description expectDescription; // Expected alert description on the test end + bool isSupportClientVerify; + bool isSupportExtendMasterSecret; + bool isSupportRenegotiation; + bool isSupportSessionTicket; + bool isSupportDhCipherSuites; + bool isSupportSni; + bool isSupportAlpn; + bool isExpectRet; + int expectRet; // Expected return value. isExpectRet needs to be enabled + const char *serverGroup; // Configure the group supported by the server. If this parameter is not specified, the default value is used + const char *serverSignature; // Configure the signature algorithm supported by the server. If this parameter is left empty, the default value is used + const char *clientGroup; // Configure the group supported by the client. If this parameter is not specified, the default value is used + const char *clientSignature; // Configure the signature algorithm supported by the client. If this parameter is left empty, the default value is used +} TestPara; + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isSupportRenegotiation; + bool isServerExtendMasterSecret; +} HandshakeTestInfo; + + + +int32_t ExampleAlpnParseProtocolList2(uint8_t *out, uint32_t *outLen, uint8_t *in, uint32_t inLen) +{ + if (out == NULL || outLen == NULL || in == NULL) { + return HITLS_NULL_INPUT; + } + + if (inLen == 0 || inLen > MAX_PROTOCOL_LEN1) { + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint32_t i = 0u; + uint32_t commaNum = 0u; + uint32_t startPos = 0u; + + for (i = 0u; i <= inLen; ++i) { + if (i == inLen || in[i] == ',') { + if (i == startPos) { + ++startPos; + ++commaNum; + continue; + } + out[startPos - commaNum] = (uint8_t)(i - startPos); + startPos = i + 1; + } else { + out[i + 1 - commaNum] = in[i]; + } + } + + *outLen = inLen + 1 - commaNum; + + return HITLS_SUCCESS; +} + +/* The local server initiates a link creation request: Ignore whether the link creation is successful. */ +void ServerAccept(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + //Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, true); + ASSERT_TRUE(remoteProcess != NULL); + + //The local server listens on the TLS link. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + //Configure the interface for constructing abnormal packets. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + //Set up a TLS link on the remote client. + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetExtenedMasterSecretSupport(clientConfig, testPara->isSupportExtendMasterSecret) == 0); + clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + HLT_RpcTlsConnect(remoteProcess, clientRes->sslId); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ServerSendMalformedRecordHeaderMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + //Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, true); + ASSERT_TRUE(remoteProcess != NULL); + + //The local server listens on the TLS link. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + serverConfig->isSupportSessionTicket = testPara->isSupportSessionTicket; + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + ASSERT_TRUE(HLT_SetRenegotiationSupport(serverConfig, testPara->isSupportRenegotiation) == 0); + + if (testPara->isSupportSni) { + ASSERT_TRUE(HLT_SetServerNameCb(serverConfig, "ExampleSNICb") == 0); + ASSERT_TRUE(HLT_SetServerNameArg(serverConfig, "ExampleSNIArg") == 0); + } + if (testPara->isSupportAlpn) { + ASSERT_TRUE(HLT_SetAlpnProtosSelectCb(serverConfig, "ExampleAlpnCb", "ExampleAlpnData") == 0); + } + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(serverConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(serverConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath(serverConfig, + RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + if (testPara->serverGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(serverConfig, testPara->serverGroup) == 0); + } + if (testPara->serverSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(serverConfig, testPara->serverSignature) == 0); + } + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + //Configure the interface for constructing abnormal packets. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + //Set up a TLS link on the remote client. + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetExtenedMasterSecretSupport(clientConfig, testPara->isSupportExtendMasterSecret) == 0); + ASSERT_TRUE(HLT_SetRenegotiationSupport(clientConfig, testPara->isSupportRenegotiation) == 0); + clientConfig->isSupportSessionTicket = testPara->isSupportSessionTicket; + if (testPara->isSupportSni) { + ASSERT_TRUE(HLT_SetServerName(clientConfig, "testServer") == 0); + } + if (testPara->isSupportAlpn) { + static const char *alpn = "http,ftp"; + uint8_t ParsedList[100] = {0}; + uint32_t ParsedListLen; + ExampleAlpnParseProtocolList2(ParsedList, &ParsedListLen, (uint8_t *)alpn, (uint32_t)strlen(alpn)); + ASSERT_TRUE(HLT_SetAlpnProtos(clientConfig, (const char *)ParsedList) == 0); + } + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(clientConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(clientConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath(clientConfig, + RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + if (testPara->clientGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(clientConfig, testPara->clientGroup) == 0); + } + if (testPara->clientSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(clientConfig, testPara->clientSignature) == 0); + } + clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + if (testPara->isExpectRet) { + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), testPara->expectRet); + } else { + ASSERT_TRUE(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId) != 0); + } + + //Wait for the local end. + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + //Confirm the final status. + ASSERT_TRUE(((HITLS_Ctx *)(serverRes->ssl))->state == CM_STATE_ALERTED); + ASSERT_TRUE(((HITLS_Ctx *)(serverRes->ssl))->hsCtx != NULL); + ASSERT_EQ(((HITLS_Ctx *)(serverRes->ssl))->hsCtx->state, testPara->expectHsState); + ASSERT_TRUE(HLT_RpcTlsGetStatus(remoteProcess, clientRes->sslId) == CM_STATE_ALERTED); + + if (testPara->alertRecvFlag) { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_RECV); + } else { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_SEND); + } + + ASSERT_EQ((ALERT_Level)HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ((ALERT_Description)HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), + testPara->expectDescription); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ClientSendMalformedRecordHeaderMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + //Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, false); + ASSERT_TRUE(remoteProcess != NULL); + + //The remote server listens on the TLS link. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(serverConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(serverConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath(serverConfig, + RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + + serverConfig->isSupportSessionTicket = testPara->isSupportSessionTicket; + ASSERT_TRUE(HLT_SetRenegotiationSupport(serverConfig, testPara->isSupportRenegotiation) == 0); + + if (testPara->isSupportSni) { + ASSERT_TRUE(HLT_SetServerNameCb(serverConfig, "ExampleSNICb") == 0); + ASSERT_TRUE(HLT_SetServerNameArg(serverConfig, "ExampleSNIArg") == 0); + } + if (testPara->isSupportAlpn) { + ASSERT_TRUE(HLT_SetAlpnProtosSelectCb(serverConfig, "ExampleAlpnCb", "ExampleAlpnData") == 0); + } + + if (testPara->serverGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(serverConfig, testPara->serverGroup) == 0); + } + if (testPara->serverSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(serverConfig, testPara->serverSignature) == 0); + } + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + //Configure the TLS connection on the local client. + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetRenegotiationSupport(clientConfig, testPara->isSupportRenegotiation) == 0); + clientConfig->isSupportSessionTicket = testPara->isSupportSessionTicket; + if (testPara->isSupportSni) { + ASSERT_TRUE(HLT_SetServerName(clientConfig, "testServer") == 0); + } + if (testPara->isSupportAlpn) { + static const char *alpn = "http,ftp"; + uint8_t ParsedList[100] = {0}; + uint32_t ParsedListLen; + ExampleAlpnParseProtocolList2(ParsedList, &ParsedListLen, (uint8_t *)alpn, (uint32_t)strlen(alpn)); + ASSERT_TRUE(HLT_SetAlpnProtos(clientConfig, (const char *)ParsedList) == 0); + } + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(clientConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(clientConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath(clientConfig, + RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + if (testPara->clientGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(clientConfig, testPara->clientGroup) == 0); + } + if (testPara->clientSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(clientConfig, testPara->clientSignature) == 0); + } + ASSERT_TRUE(HLT_SetExtenedMasterSecretSupport(clientConfig, testPara->isSupportExtendMasterSecret) == 0); + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + //Configure the interface for constructing abnormal packets. + handle->ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + //Set up a link and wait until the local end is complete. + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + + //Wait the remote end. + int ret = HLT_GetTlsAcceptResult(serverRes); + ASSERT_TRUE(ret != 0); + + if (testPara->isExpectRet) { + ASSERT_EQ(ret, testPara->expectRet); + } + + //Final status confirmation + ASSERT_EQ(HLT_RpcTlsGetStatus(remoteProcess, serverRes->sslId), CM_STATE_ALERTED); + if (testPara->alertRecvFlag) { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, serverRes->sslId), ALERT_FLAG_RECV); + } else { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, serverRes->sslId), ALERT_FLAG_SEND); + } + ASSERT_EQ((ALERT_Level)HLT_RpcTlsGetAlertLevel(remoteProcess, serverRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ((ALERT_Description)HLT_RpcTlsGetAlertDescription(remoteProcess, serverRes->sslId), + testPara->expectDescription); + ASSERT_TRUE(((HITLS_Ctx *)(clientRes->ssl))->state == CM_STATE_ALERTED); + ASSERT_TRUE(((HITLS_Ctx *)(clientRes->ssl))->hsCtx != NULL); + ASSERT_EQ(((HITLS_Ctx *)(clientRes->ssl))->hsCtx->state, testPara->expectHsState); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +static int SetCertPath(HLT_Ctx_Config *ctxConfig, const char *certStr, bool isServer) +{ + int ret; + char caCertPath[50] = {0}; + char chainCertPath[30] = {0}; + char eeCertPath[30] = {0}; + char privKeyPath[30] = {0}; + + ret = sprintf_s(caCertPath, sizeof(caCertPath), ROOT_DER, certStr, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(chainCertPath, sizeof(chainCertPath), INTCA_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(eeCertPath, sizeof(eeCertPath), isServer ? SERVER_DER : CLIENT_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(privKeyPath, sizeof(privKeyPath), isServer ? SERVER_KEY_DER : CLIENT_KEY_DER, certStr); + ASSERT_TRUE(ret > 0); + HLT_SetCaCertPath(ctxConfig, (char *)caCertPath); + HLT_SetChainCertPath(ctxConfig, (char *)chainCertPath); + HLT_SetEeCertPath(ctxConfig, (char *)eeCertPath); + HLT_SetPrivKeyPath(ctxConfig, (char *)privKeyPath); + return 0; +exit: + return -1; +} + +static int SetCertPath1(HLT_Ctx_Config *ctxConfig, const char *certStr, const char *certStr1, bool isServer) +{ + int ret; + char caCertPath[50] = {0}; + char chainCertPath[30] = {0}; + char eeCertPath[30] = {0}; + char privKeyPath[30] = {0}; + + ret = sprintf_s(caCertPath, sizeof(caCertPath), ROOT_DER, certStr1, certStr1); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(chainCertPath, sizeof(chainCertPath), INTCA_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(eeCertPath, sizeof(eeCertPath), isServer ? SERVER_DER : CLIENT_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(privKeyPath, sizeof(privKeyPath), isServer ? SERVER_KEY_DER : CLIENT_KEY_DER, certStr); + ASSERT_TRUE(ret > 0); + HLT_SetCaCertPath(ctxConfig, (char *)caCertPath); + HLT_SetChainCertPath(ctxConfig, (char *)chainCertPath); + HLT_SetEeCertPath(ctxConfig, (char *)eeCertPath); + HLT_SetPrivKeyPath(ctxConfig, (char *)privKeyPath); + return 0; +exit: + return -1; +} + + +static void GetDefaultPointFormats(FRAME_HsExtArray8 *exField) +{ + exField->exState = INITIAL_FIELD; + exField->exType.state = INITIAL_FIELD; + exField->exType.data = HS_EX_TYPE_POINT_FORMATS; + uint8_t data[] = {0}; + FRAME_ModifyMsgArray8(data, sizeof(data), &exField->exData, &exField->exDataLen); + exField->exLen.state = INITIAL_FIELD; + exField->exLen.data = exField->exDataLen.data + sizeof(uint8_t); +} + +static void MalformedServerHelloMsgCallback001(void *msg, void *userData) +{ + // ServerHello exception: Duplicate point format extension. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + + GetDefaultPointFormats(&serverHello->pointFormats); + serverHello->pointFormats.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC010 +* @title extension_serverhello point format extension duplicate +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. Expected result 2 is obtained. +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the tested end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC010(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; // Message type to be modified + handle.expectHsType = SERVER_HELLO; // Handshake message type to be modified + handle.frameCallBack = MalformedServerHelloMsgCallback001; // reconstruction callback + TestPara testPara = {0}; + testPara.port = PORT; + testPara.isSupportExtendMasterSecret = true; + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedServerHelloMsgCallback002(void *msg, void *userData) +{ + // ServerHello exception: The extended master key extension is duplicate + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->extendedMasterSecret.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC011 +* @title extension_serverHello extension master key extension duplicate +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the tested end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC011(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHelloMsgCallback002; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.isSupportExtendMasterSecret = true; + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedServerHelloMsgCallback003(void *msg, void *userData) +{ + // ServerHello exception: The extended renegotiation extension is repeated. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->secRenego.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC012 +* @title extension_serverHello renegotiation extension duplicate +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC012(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHelloMsgCallback003; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportRenegotiation = true; + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedServerHelloMsgCallback004(void *msg, void *userData) +{ + // ServerHello exception: Duplicate sessionticket extension. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->sessionTicket.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC013 +* @title extension_serverHello sessionticket extension duplicate +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. Expected result 2 is obtained. +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC013(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHelloMsgCallback004; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSessionTicket = true; + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedServerHelloMsgCallback005(void *msg, void *userData) +{ + // serverHello exception: The serverName extension is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->serverName.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC014 +* @title extension_serverHello servername extension duplicate +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. Expected result 2 is obtained. +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message in the alerted state. +4. The status of the tested end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC014(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHelloMsgCallback005; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSni = true; + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedServerHelloMsgCallback006(void *msg, void *userData) +{ + // ServerHello exception: The alpn extension is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->alpn.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC014 +* @title extension_serverHello Alpn extension duplicate +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. Expected result 2 is obtained. +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the tested end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC009(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHelloMsgCallback006; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportAlpn = true; + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback002(void *msg, void *userData) +{ + // ClientHello exception: The format extension of the sent ClientHello message is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->pointFormats.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC002 +* @title The point format extension of the ClientHello message is duplicate +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, and the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC002(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback002; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback003(void *msg, void *userData) +{ + // ClientHello exception: The signature algorithm extension of the sent ClientHello message is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->signatureAlgorithms.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC003 +* @title The signature algorithm extension for the clientHello message sent by the client is duplicate._Signature algorithm extension +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC003(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback003; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback004(void *msg, void *userData) +{ + // ClientHello exception: The sent ClientHello message supports group extension repetition. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->supportedGroups.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC004 +* @title The clientHello message sent by the client supports group extension repetition._Group extension is supported. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC004(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback004; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback005(void *msg, void *userData) +{ + // ClientHello exception: The extended master key extension in the sent ClientHello message is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->extendedMasterSecret.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC005 +* @title Extended master key for the clientHello message that is sent repeatedly_Extended master key +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC005(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback005; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + testPara.isSupportExtendMasterSecret = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback006(void *msg, void *userData) +{ + // ClientHello exception: The extended sessionticket extension of the clientHello message is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->sessionTicket.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC006 +* @title The sessionticket extension for the clientHello message sent by the client is duplicate. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC006(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback006; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSessionTicket = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +// ClientHello exception: The extension servername of the clientHello message is duplicate. +static void MalformedClientHelloMsgCallback007(void *msg, void *userData) +{ + // ClientHello exception: The extension servername of the clientHello message is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = DUPLICATE_FIELD; + clientHello->serverName.exLen.state = INITIAL_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t uu[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8(uu, sizeof(uu)-1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007 +* @title The servername extension of the clientHello message is duplicate _servername. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback007; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSni = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +// ClientHello exception: The extended alpn extension of the clientHello message is duplicate. +static void MalformedClientHelloMsgCallback008(void *msg, void *userData) +{ + // ClientHello exception: The extended alpn extension of the clientHello message is duplicate. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->alpn.exState = DUPLICATE_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC008 +* @title The alpn extension of the clientHello message is repeated _alpn. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, indicating that the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC008(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback008; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportAlpn = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC001 +* @title The sessionticket field is carried during the first connection setup. The extended field is not carried during the session recovery. The expected result is that the session recovery fails and the handshake is performed again. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Enable the session ticket function and initiate link establishment. Expected result 2 is obtained. +3. Configure the client not to support sessionticket during session restoration. Expected result 3 is obtained. +* @expect 1. A success message is returned. +2. The link is successfully established. +3. If the session fails to be restored, a new link is established. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC001(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportSessionTicket = true; + clientCtxConfig->isSupportRenegotiation = false; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportSessionTicket = true; + serverCtxConfig->isSupportRenegotiation = false; + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (cnt == 2) { + clientCtxConfig->isSupportSessionTicket = false; + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(clientCtxConfig->isSupportSessionTicket == false); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } + else { + + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_HasTicket(session) == true); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + + cnt++; + } while (cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC002 +* @title The sessionticket field is not carried during the first connection setup. The extended field is carried during session recovery. The expected result is that the session recovery fails and the handshake is performed again. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Disable the session ticket function and initiate link establishment. Expected result 2 is obtained. +3. Configure the client to support sessionticket during session restoration. Expected result 3 is obtained. +* @expect 1. A success message is returned. +2. The link is set up successfully. +3. The session is restored successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC002(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportSessionTicket = false; + clientCtxConfig->isSupportRenegotiation = false; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportSessionTicket = false; + serverCtxConfig->isSupportRenegotiation = false; + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (cnt == 2) { + clientCtxConfig->isSupportSessionTicket = true; + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(clientCtxConfig->isSupportSessionTicket == true); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } + else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + + cnt++; + } while (cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC003 +* @title Renegotiation is carried in the first link setup message, and this extended field is not carried in the session recovery message. The expected result is that the session recovery is successful. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Enable renegotiation and initiate link establishment. Expected result 2 is obtained. +3. Configure the client not to support renegotiation during session restoration. Expected result 3 is obtained. +* @expect 1. A success message is returned. +2. The link is set up successfully. +3. The session is restored successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC003(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportSessionTicket = false; + clientCtxConfig->isSupportRenegotiation = true; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportSessionTicket = false; + serverCtxConfig->isSupportRenegotiation = true; + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (cnt == 2) { + clientCtxConfig->isSupportRenegotiation = false; + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } + else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + + cnt++; + } while (cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC004 +* @title The first link establishment does not carry the renegotiation IE, and the session recovery IE carries the extended field. The expected result is that the session recovery is successful. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Disable renegotiation and initiate link establishment. Expected result 2 is obtained. +3. Configure the client to support renegotiation during session restoration. Expected result 3 is obtained. +* @expect 1. A success message is returned. +2. The link is set up successfully. +3. The session is restored successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC004(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportSessionTicket = false; + clientCtxConfig->isSupportRenegotiation = false; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportSessionTicket = false; + serverCtxConfig->isSupportRenegotiation = false; + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (cnt == 2) { + clientCtxConfig->isSupportRenegotiation = true; + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } + else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + + cnt++; + } while (cnt < 3); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC001 +* @title The handshake fails because different cipher suites are configured on the client and server. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Configure different cipher suites on the client and server and initiate link establishment. (Expected result 2) +* @expect 1. A success message is returned. +2. The link fails to be established. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC001(int version, int connType) +{ + bool certverifyflag = false; + + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"); + serverCtxConfig->isSupportClientVerify = certverifyflag; + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + clientCtxConfig->isSupportClientVerify = certverifyflag; + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC003 +* @title The RSA and ECDSA cipher suites are configured on the client and server, and the ECDSA certificate is configured. The handshake is successful. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Configure the RSA and ECDSA cipher suites and ECDSA certificates on the client and server, and initiate link establishment. (Expected result 2) +* @expect 1. A success message is returned. +2. Link establishment fails. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC003(int version, int connType) +{ + bool certverifyflag = false; + + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_RSA_WITH_AES_128_CBC_SHA256:HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); + serverCtxConfig->isSupportClientVerify = certverifyflag; + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_128_CBC_SHA256:HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); + clientCtxConfig->isSupportClientVerify = certverifyflag; + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_SUCCESS); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, sizeof(readBuf), &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +void MalformedClientHellocallback001(void *msg, void *userData) +{ + // ClientHello is abnormal. ClientHello modifies the algorithm suite. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + + /* Modify the structure. */ + uint16_t suite[] = {0x00fe, HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0x00ff}; // renegotiation cipher suite:0x00ff + ASSERT_TRUE(FRAME_ModifyMsgArray16(suite, sizeof(suite)/sizeof(uint16_t), + &(clientHello->cipherSuites), &(clientHello->cipherSuitesSize)) == HITLS_SUCCESS); + +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC002 +* @title The client and server set incorrect and correct cipher suites. The handshake succeeds. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Configure different cipher suites on the client and server and initiate link establishment. (Expected result 2) +* @expect 1. A success message is returned. +2. A link is established normally. An error is reported during hash check. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC002(int version, int connType) +{ + bool certverifyflag = false; + + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + DataChannelParam channelParam = {0}; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE(sockFd.srcFd > 0); + ASSERT_TRUE(sockFd.peerFd > 0); + remoteProcess->connFd = sockFd.peerFd; + remoteProcess->connType = connType; + localProcess->connFd = sockFd.srcFd; + localProcess->connType = connType; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + serverCtxConfig->isSupportClientVerify = certverifyflag; + + serverRes = HLT_ProcessTlsAccept(remoteProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + + clientCtxConfig->isSupportClientVerify = certverifyflag; + + clientRes = HLT_ProcessTlsInit(localProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + HLT_FrameHandle handle = {0}; + handle.ctx = clientRes->ssl; + handle.userData = (void*)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHellocallback001; + ASSERT_TRUE(HLT_SetFrameHandle(&handle) == HITLS_SUCCESS); + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), HITLS_REC_BAD_RECORD_MAC); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +void MalformedServerHellocallback001(void *msg, void *userData) +{ + // ServerHello packet: Check the serverHello algorithm suite. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + + /* Determine algorithm suite */ + ASSERT_EQ(serverHello->cipherSuite.data, 0x6d); + +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC004 +* @title Set insecure and secure cipher suites on the client and server, set the ECDSA certificate, and select the secure cipher suite as expected. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client. Expected result 1 is obtained. +2. Configure insecure and secure cipher suites on the client and server, configure the ECDSA certificate, and initiate link establishment. (Expected result 2) +* @expect 1. A success message is returned. +2. The link is successfully established and the security algorithm suite is selected. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC004(int version, int connType) +{ + bool certverifyflag = false; + + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + DataChannelParam channelParam = {0}; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE(sockFd.srcFd > 0); + ASSERT_TRUE(sockFd.peerFd > 0); + remoteProcess->connFd = sockFd.peerFd; + remoteProcess->connType = connType; + localProcess->connFd = sockFd.srcFd; + localProcess->connType = connType; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_DH_ANON_WITH_AES_256_CBC_SHA256:HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); + serverCtxConfig->isSupportClientVerify = certverifyflag; + + serverRes = HLT_ProcessTlsAccept(remoteProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_DH_ANON_WITH_AES_256_CBC_SHA256:HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); + + clientCtxConfig->isSupportClientVerify = certverifyflag; + + clientRes = HLT_ProcessTlsInit(localProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + HLT_FrameHandle handle = {0}; + handle.ctx = clientRes->ssl; + handle.userData = (void*)&handle; + handle.pointType = POINT_RECV; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHellocallback001; + ASSERT_TRUE(HLT_SetFrameHandle(&handle) == HITLS_SUCCESS); + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), HITLS_SUCCESS); + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), HITLS_SUCCESS); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + + +//The clientHello is abnormal. The extended servername length of the clientHello message is smaller than the actual length. +static void MalformedClientHelloMsgCallback009(void *msg, void *userData) +{ + //The clientHello is abnormal. The extended servername length of the clientHello message is smaller than the actual length. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t uu[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8(uu, sizeof(uu)-1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data--; + clientHello->serverName.exLen.data--; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007 +* @title The extended length of the servername in the clientHello message is smaller than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, and the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC048(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback009; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSni = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +//The clientHello message is abnormal. The extended servername length of the clientHello message is greater than the actual length. +static void MalformedClientHelloMsgCallback010(void *msg, void *userData) +{ + //The clientHello message is abnormal. The extended servername length of the clientHello message is greater than the actual length. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t uu[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8(uu, sizeof(uu)-1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data++; + clientHello->serverName.exLen.data++; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007 +* @title The extended length of the servername in the clientHello message is greater than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, and the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC047(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback010; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSni = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +// ClientHello exception: The extended length of the servername in the clientHello message is 0 and the content is not null. +static void MalformedClientHelloMsgCallback011(void *msg, void *userData) +{ + // ClientHello exception: The length of the extended servername in the clientHello message is 0 and the content is not null. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t uu[4] = {0x00, 0x00, 0x01,0x01}; + FRAME_ModifyMsgArray8(uu, sizeof(uu)-1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data = 0; + clientHello->serverName.exDataLen.data = 0; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007 +* @title The extended length of the servername in the clientHello message is 0 and the content is not null. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, and the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC046(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback011; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSni = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +//The clientHello is abnormal. The extended length of the servername in the clientHello message is 0. The content is empty. +static void MalformedClientHelloMsgCallback012(void *msg, void *userData) +{ + //The clientHello is abnormal. The extended length of the servername in the clientHello message is 0. The content is empty. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = MISSING_FIELD; + clientHello->serverName.exData.state = MISSING_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + clientHello->serverName.exLen.data = 0; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007 +* @title The extended length of the servername in the clientHello message is 0. The content is empty. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is obtained. +2. Obtain the message, modify the field content, and send the message. (Expected result 2) +3. Check the status of the tested end. Expected result 3 is obtained. +4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. +2. A success message is returned. +3. The tested end returns an alert message, and the status is alerted. +4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC045(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback012; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportSni = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHERSUITE_NOT_SUITABLE_CERT_TC003 +* @title When dual-end authentication is configured, the cipher suite is set to RSA, the RSA certificate is set on the server, and the ECDSA certificate is set on the client, the link fails to be established. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server, set the cipher suite to RSA, set the RSA certificate on the server, and set the ECDSA certificate on the client. Expected result 1 is obtained. +2. Initiate a link establishment request. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +2. Link establishment fails. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CIPHERSUITE_NOT_SUITABLE_CERT_TC003(int version, int connType) +{ + bool certverifyflag = true; + + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath1(serverCtxConfig, "rsa_sha256", "ecdsa_sha256", true); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256"); + serverCtxConfig->isSupportClientVerify = certverifyflag; + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath1(clientCtxConfig, "ecdsa_sha256", "rsa_sha256", false); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256"); + clientCtxConfig->isSupportClientVerify = certverifyflag; + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC002 +* @title Apply for establishing and disconnecting a link between the client and server, apply for two links, and use the session ID of the previous session to restore the session. The restoration is expected to be successful. +* @precon nan +* @brief 1. Apply for establishing and disconnecting a link between the client and server. +2. Apply for two links and use the session ID of the previous session to restore the session. The restoration is expected to be successful. +* @expect 1. The link is successfully established. +2. The restoration is successful. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC002(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + HLT_FD sockFd2 = {0}; + int cunt = 1; + + HITLS_Session *session = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + void *clientConfig2 = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(clientConfig2 != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *clientCtxConfig2 = HLT_NewCtxConfig(NULL, "CLIENT"); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig2, clientCtxConfig2) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (session != NULL) { + DataChannelParam channelParam2; + channelParam2.port = PORT; + channelParam2.type = connType; + channelParam2.isBlock = true; + sockFd2 = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam2); + ASSERT_TRUE((sockFd2.srcFd > 0) && (sockFd2.peerFd > 0)); + remoteProcess->connType = connType; + localProcess->connType = connType; + remoteProcess->connFd = sockFd2.peerFd; + localProcess->connFd = sockFd2.srcFd; + + int32_t serverSslId2 = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig2; + serverSslConfig2 = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig2 != NULL); + serverSslConfig2->sockFd = remoteProcess->connFd; + serverSslConfig2->connType = connType; + + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId2, serverSslConfig2) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId2); + + void *clientSsl2 = HLT_TlsNewSsl(clientConfig2); + ASSERT_TRUE(clientSsl2 != NULL); + + HLT_Ssl_Config *clientSslConfig2; + clientSslConfig2 = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig2 != NULL); + clientSslConfig2->sockFd = localProcess->connFd; + clientSslConfig2->connType = connType; + + HLT_TlsSetSsl(clientSsl2, clientSslConfig2); + ASSERT_TRUE(HITLS_SetSession(clientSsl2, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl2) == 0); + + HITLS_Session *Newsession = HITLS_GetDupSession(clientSsl2); + ASSERT_TRUE(Newsession != NULL); + ASSERT_TRUE(memcmp(session->sessionId, Newsession->sessionId, HITLS_SESSION_ID_MAX_SIZE) == 0); + HITLS_SESS_Free(Newsession); + } + + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + HITLS_SESS_Free(session); + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + cunt++; + } while (cunt <= 2); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_extensions.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_extensions.data new file mode 100644 index 00000000..de64b651 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_extensions.data @@ -0,0 +1,77 @@ +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC010 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC010: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC011 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC011: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC012 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC012: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC013 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC013: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC014 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC014: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC009 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC009: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC002: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC003 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC003: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC004 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC004: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC005 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC005: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC006 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC006: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC007: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC008 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_REPEAT_EXTENSION_TC008: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC001:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC002:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC003 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC003:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC004 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_RESUME_TAKE_EXTENSION_TC004:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC001:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC002:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC003 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC003:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC004 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_NEGOTIATE_CIPHERSUITE_TC004:TLS1_2:TCP + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC048 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC048: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC047 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC047: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC046 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC046: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC045 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC045: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MULTILINK_RESUME_ALERT_TC002:TLS1_2:TCP \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_malformed_msg.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_malformed_msg.c new file mode 100644 index 00000000..1be98729 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_malformed_msg.c @@ -0,0 +1,2526 @@ +/* + * 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_BASE test_suite_tls12_consistency_rfc5246_malformed_msg */ +/* BEGIN_HEADER */ + +#include "hitls_error.h" +#include "tls.h" +#include "rec.h" +#include "hs_msg.h" +#include "hs_ctx.h" +#include "hs_extensions.h" +#include "frame_msg.h" + +/* END_HEADER */ + +// Replace the message to be sent with the CERTIFICATION_VERIFY message. +void TEST_SendUnexpectCertificateVerifyMsg(void *msg, void *data) +{ + FRAME_Type *frameType = (FRAME_Type *)data; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + FRAME_Msg newFrameMsg = {0}; + HS_MsgType hsTypeTmp = frameType->handshakeType; + REC_Type recTypeTmp = frameType->recordType; + frameType->handshakeType = CERTIFICATE_VERIFY; + FRAME_Init(); // Callback for changing the certificate algorithm, which is used to generate negotiation handshake + // messages. + FRAME_GetDefaultMsg(frameType, &newFrameMsg); + HLT_TlsRegCallback(HITLS_CALLBACK_DEFAULT); // recovery callback + // Release the original msg. + frameType->handshakeType = hsTypeTmp; + frameType->recordType = recTypeTmp; + FRAME_CleanMsg(frameType, frameMsg); + // Change message. + frameType->recordType = REC_TYPE_HANDSHAKE; + frameType->handshakeType = CERTIFICATE_VERIFY; + frameType->keyExType = HITLS_KEY_EXCH_ECDHE; + if (memcpy_s(msg, sizeof(FRAME_Msg), &newFrameMsg, sizeof(newFrameMsg)) != EOK) { + Print("TEST_SendUnexpectCertificateMsg memcpy_s Error!"); + } +} + +static void MalformedClientHelloMsgCallback_01(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + + clientHello->version.state = SET_LEN_TO_ONE_BYTE; + + clientHello->randomValue.state = MISSING_FIELD; + clientHello->sessionIdSize.state = MISSING_FIELD; + clientHello->sessionId.state = MISSING_FIELD; + clientHello->cookiedLen.state = MISSING_FIELD; + clientHello->cookie.state = MISSING_FIELD; + clientHello->cipherSuitesSize.state = MISSING_FIELD; + clientHello->cipherSuites.state = MISSING_FIELD; + clientHello->compressionMethodsLen.state = MISSING_FIELD; + clientHello->compressionMethods.state = MISSING_FIELD; + clientHello->extensionState = MISSING_FIELD; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC001 +* @title version field only one byte _version +* @precon nan +* @brief + 1. The server stops receiving client information. 1. ClientHello exception: The version field in the constructed + message to be sent contains only one byte and cannot be decoded. Expected result 1 is obtained. +* @expect 1. The processing result is HITLS_PARSE_INVALID_MSG_LEN. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC001(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + /* 1. The server stops receiving client information. 1. ClientHello exception: The version field in the constructed + * message to be sent contains only one byte and cannot be decoded. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_01; + + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isExpectRet = true; + testPara.expectRet = HITLS_PARSE_INVALID_MSG_LEN; + + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_02(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + + clientHello->randomValue.size = 1; + clientHello->randomValue.state = ASSIGNED_FIELD; + + clientHello->sessionIdSize.state = MISSING_FIELD; + clientHello->sessionId.state = MISSING_FIELD; + clientHello->cookiedLen.state = MISSING_FIELD; + clientHello->cookie.state = MISSING_FIELD; + clientHello->cipherSuitesSize.state = MISSING_FIELD; + clientHello->cipherSuites.state = MISSING_FIELD; + clientHello->compressionMethodsLen.state = MISSING_FIELD; + clientHello->compressionMethods.state = MISSING_FIELD; + clientHello->extensionState = MISSING_FIELD; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC002 +* @title random Less than 32 bytes_random +* @precon nan +* @brief 1. The server stops receiving client hello messages. Expected result 1 is obtained. + 2. Modify the client to send the client hello message and change the random field to only one byte. Expected + result 2 is obtained. + 3. The server continues to establish a link. (Expected result 3) +* @expect 1. Success + 2. Success + 3. Return a failure message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC002(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The server stops receiving client hello messages. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Modify the client to send the client hello message and change the random field to only one byte. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_02; + + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isExpectRet = true; + testPara.expectRet = HITLS_PARSE_INVALID_MSG_LEN; + /* 3. The server continues to establish a link. */ + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback_03(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t sessionId[MAX_SESSION_ID_SIZE] = {0}; + ASSERT_TRUE(FRAME_ModifyMsgArray8(sessionId, MAX_SESSION_ID_SIZE, &clientHello->sessionId, NULL) == HITLS_SUCCESS); + clientHello->sessionIdSize.data = 0u; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC003 +* @titleThe session ID length of the clientHello message is 0 but the content is not null. _session ID + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. Expected result 2 is obtained. + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello +message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC003(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_03; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello message. + */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested. */ + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_04(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t sessionId[MIN_SESSION_ID_SIZE - 1] = {0}; + FRAME_ModifyMsgArray8(sessionId, sizeof(sessionId), &clientHello->sessionId, &clientHello->sessionIdSize); +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC004 +* @title The length of the session ID in the clientHello message is smaller than the minimum length_session ID + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC004(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_04; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3.Check the status of the tested. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_05(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t sessionId[MAX_SESSION_ID_SIZE + 1] = {0}; + FRAME_ModifyMsgArray8(sessionId, sizeof(sessionId), &clientHello->sessionId, &clientHello->sessionIdSize); +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC005 +* @title The length of the session ID in the clientHello message exceeds the maximum length_session ID + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC005(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_05; + TestPara testPara = {0}; + testPara.port = PORT; + /* 3. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 4. Check the status of the tested. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback_06(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->cipherSuitesSize.data = 0; + clientHello->cipherSuites.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC006 +* @title The length of the cipher suite in the clientHello message is 0 and the content is empty. _cipher suites + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC006(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_06; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested. */ + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_07(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t rawData[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8( + rawData, sizeof(rawData) - 1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data -= 2; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC007 +* @title The length of the cipher suites in the clientHello message sent is an odd number_cipher suites + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested returns an alert message, and the status is alerted. + 4. The status of the test is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC007(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_07; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback_08(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->cipherSuitesSize.data = 0; +exit: + return; +} + +/* @ +* @test SDV_HITLS_TEST_DTLS_MALFORMED_CLIENT_HELLO_MSG_FUN_TC010 +* @title The length of the cipher suite in the clientHello message is 0 but the content is not null. _cipher suites + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested returns an alert message, indicating that the status is alerted. + 4. The status of the test is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC008(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_08; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested. */ + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_09(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->cipherSuites.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC009 +* @title The length of the cipher suite in the clientHello message is not 0 but the content is empty. _cipher suites + length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested returns an alert message, and the status is alerted. + 4. The status of the test is alerted, and the handshake status is ready to receive the serverHello message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC009(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_09; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_10(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->cipherSuitesSize.data -= sizeof(uint16_t); +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC010 +* @title The length of the cipher suite in the sent clientHello message is less than the specific content + length_cipher suites length +* @precon nan +* @brief 1. The tested functions as the client, and the tested functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested. Expected result 3 is obtained. + 4. Check the status of the test. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested returns an alert message, and the status is alerted. + 4. The status of the test is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC010(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested functions as the client, and the tested functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_10; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_11(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->cipherSuitesSize.data += sizeof(uint16_t); +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC011 +* @title The length of the cipher suite in the sent ClientHello message is greater than the specific content + length_cipher suites length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC011(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_11; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback_12(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->compressionMethodsLen.data = 0; + clientHello->compressionMethods.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC012 +* @title The length of the compression list of the sent ClientHello message is 0 and the content is empty. + _compression methods length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC012(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_12; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test end. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested end. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_13(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t compressionMethods[] = {0, 1}; + FRAME_ModifyMsgArray8(compressionMethods, sizeof(compressionMethods), + &clientHello->compressionMethods, &clientHello->compressionMethodsLen); + clientHello->compressionMethodsLen.data--; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC013 +* @title The length of the compression list in the sent ClientHello message is less than the content + length_compression methods length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC013(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_13; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test end. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested end. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_14(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t compressionMethods[] = {0}; + FRAME_ModifyMsgArray8(compressionMethods, sizeof(compressionMethods), + &clientHello->compressionMethods, &clientHello->compressionMethodsLen); + clientHello->compressionMethodsLen.data++; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC014 +* @title The length of the compression list in the sent ClientHello message is greater than the content + length_compression methods length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC014(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_14; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test end. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested end. */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_15(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t compressionMethods[] = {1}; + FRAME_ModifyMsgArray8(compressionMethods, sizeof(compressionMethods), + &clientHello->compressionMethods, &clientHello->compressionMethodsLen); +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC015 +* @title The compression list of clientHello messages sent by the client does not contain compression algorithm + _compression methods length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC015(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_15; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested . */ + testPara.expectDescription = ALERT_ILLEGAL_PARAMETER; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_16(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->extensionLen.state = ASSIGNED_FIELD; + clientHello->extensionLen.data--; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC016 +* @title The extended length of the clientHello message sent by the client is smaller than the actual message + length_Total extended length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC016(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_16; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback_17(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->extensionLen.state = ASSIGNED_FIELD; + clientHello->extensionLen.data++; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC017 +* @title The extended length of the clientHello message sent by the client is greater than the actual message + length_Total extended length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC017(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_17; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + + +static void MalformedClientHelloMsgCallback_18(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->pointFormats.exLen.state = ASSIGNED_FIELD; + clientHello->pointFormats.exLen.data--; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC018 +* @title The extended length of the sent ClientHello message point format is smaller than the actual length_Extended + point format +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +* prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC018(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_18; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_19(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->pointFormats.exLen.state = ASSIGNED_FIELD; + clientHello->pointFormats.exLen.data++; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC019 +* @title The extended length of the sent ClientHello message point format is greater than the actual length_Extended + point format +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC019(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_19; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_20(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->pointFormats.exDataLen.data = 0; + clientHello->pointFormats.exData.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC020 +* @title The length of the sent ClientHello message is 0 and the content is empty. _ The dot format is extended +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC020(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_20; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_21(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->pointFormats.exDataLen.data = 1; + clientHello->pointFormats.exData.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC021 +* @title The length of the point format of the clientHello message is not 0 and the content is null. _ The point + format is extended +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC021(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_21; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_22(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->supportedGroups.exLen.data -= sizeof(uint16_t); + clientHello->supportedGroups.exLen.state = ASSIGNED_FIELD; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC022 +* @title The length of the clientHello message that supports group extension is smaller than the actual length_Group + extension is supported +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC022(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_22; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_23(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->supportedGroups.exLen.data += sizeof(uint16_t); + clientHello->supportedGroups.exLen.state = ASSIGNED_FIELD; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC023 +* @title The length of the clientHello message that supports group extension is greater than the actual length._Group + extension is supported +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC023(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_23; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_24(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->supportedGroups.exDataLen.data--; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC024 +* @title The clientHello message sent by the client supports the odd number of group lengths._Group extension is + supported +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC024(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_24; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_25(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->supportedGroups.exDataLen.data = 0; + clientHello->supportedGroups.exData.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC025 +* @title The clientHello message can contain 0 characters and cannot contain any characters._Group extension is + supported. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC025(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_25; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_26(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->signatureAlgorithms.exLen.state = ASSIGNED_FIELD; + clientHello->signatureAlgorithms.exLen.data -= sizeof(uint16_t); +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC026 +* @title The extended signature algorithm length of the clientHello message is less than the actual + length_signature algorithm extension +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 + is obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC026(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_26; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_27(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->signatureAlgorithms.exLen.state = ASSIGNED_FIELD; + clientHello->signatureAlgorithms.exLen.data += sizeof(uint16_t); +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC027 +* @title The extended signature algorithm length of the clientHello message is greater than the actual + length_signature algorithm extension +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC027(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_27; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_28(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->signatureAlgorithms.exDataLen.data--; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC028 +* @title The signature algorithm length of the clientHello message sent by the client is an odd number_signature + algorithm extension +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC028(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_28; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_29(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->signatureAlgorithms.exDataLen.data = 0; + clientHello->signatureAlgorithms.exData.state = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC029 +* @title The signature algorithm length of the clientHello message is 0 and the content is empty_signature algorithm + extension +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. Expected result 2 is obtained. + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC029(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_29; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_30(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + uint8_t extendedMasterSecret[] = {0}; + FRAME_ModifyMsgArray8(extendedMasterSecret, sizeof(extendedMasterSecret), + &clientHello->extendedMasterSecret.exData, NULL); +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC030 +* @title The length of the extended master key in the clientHello message is not 0_Extended master + key +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC030(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_30; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_31(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->sessionTicket.exDataLen.state = ASSIGNED_FIELD; + clientHello->sessionTicket.exDataLen.data--; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC031 +* @title The SessionTicket extension length of the clientHello message sent by the client is smaller than the actual + length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC031(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_31; + TestPara testPara = {0}; + testPara.isSupportSessionTicket = 1; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_32(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->sessionTicket.exDataLen.state = ASSIGNED_FIELD; + clientHello->sessionTicket.exDataLen.data++; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC032 +* @title The SessionTicket length of the clientHello message is greater than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message in the alerted state. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC032(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_32; + TestPara testPara = {0}; + testPara.isSupportSessionTicket = 1; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_33(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->sessionTicket.exDataLen.data = 1; + clientHello->sessionTicket.exDataLen.state = SET_LEN_TO_ONE_BYTE; + clientHello->sessionTicket.exData.state = MISSING_FIELD; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC033 +* @title The SessionTicket length of the clientHello message is not zero and the content is empty. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, indicating that the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC033(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_33; + TestPara testPara = {0}; + testPara.isSupportSessionTicket = 1; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_34(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t rawData[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8( + rawData, sizeof(rawData) - 1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data -= 2; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC034 +* @title The extended length of the servername in the clientHello message is smaller than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the tested end.Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC034(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_34; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the tested end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_35(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t rawData[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8( + rawData, sizeof(rawData) - 1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data += 2; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC035 +* @title The extended length of the servername in the clientHello message is greater than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the tested end.Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC035(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_35; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the tested end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_36(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + uint8_t rawData[4] = {0x00, 0x00, 0x01, 0x01}; + FRAME_ModifyMsgArray8( + rawData, sizeof(rawData) - 1, &clientHello->serverName.exData, &clientHello->serverName.exDataLen); + clientHello->serverName.exLen.data = 0; + clientHello->serverName.exDataLen.data = 0; +exit: + return; +} +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC036 +* @title The extended length of the servername in the clientHello message is 0 and the content is not null. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the tested end.Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC036(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_36; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the tested end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_37(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->serverName.exState = INITIAL_FIELD; + clientHello->serverName.exLen.state = ASSIGNED_FIELD; + clientHello->serverName.exDataLen.state = MISSING_FIELD; + clientHello->serverName.exData.state = MISSING_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->serverName.exType); + clientHello->serverName.exLen.data = 0; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC037 +* @title The length of the servername extension in the clientHello message is 0 and the content is empty. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the tested end.Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC037(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_37; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the tested end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback_38(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->alpn.exState = INITIAL_FIELD; + clientHello->alpn.exLen.state = ASSIGNED_FIELD; + clientHello->alpn.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_APP_LAYER_PROTOCOLS, &clientHello->alpn.exType); + uint8_t rawData[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8(rawData, sizeof(rawData) - 1, &clientHello->alpn.exData, &clientHello->alpn.exDataLen); + clientHello->alpn.exLen.data -= 2; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC038 +* @title The extended length of the servername in the clientHello message is smaller than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the tested end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC038(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_38; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the tested end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportALPN = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_39(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->alpn.exState = INITIAL_FIELD; + clientHello->alpn.exLen.state = ASSIGNED_FIELD; + clientHello->alpn.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_APP_LAYER_PROTOCOLS, &clientHello->alpn.exType); + uint8_t rawData[13] = {0x00, 0x00, 0x09, 0x75, 0x61, 0x77, 0x65, 0x69, 0x2e, 0x63, 0x6F, 0x6d}; + FRAME_ModifyMsgArray8(rawData, sizeof(rawData) - 1, &clientHello->alpn.exData, &clientHello->alpn.exDataLen); + clientHello->alpn.exLen.data += 2; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC039 +* @title The extended length of the servername in the clientHello message is greater than the actual length. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. Return a success message. + 2. Return a success message. + 3. Return an alert message. The status of the tested end is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC039(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_39; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportALPN = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_40(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->alpn.exState = INITIAL_FIELD; + clientHello->alpn.exLen.state = ASSIGNED_FIELD; + clientHello->alpn.exDataLen.state = INITIAL_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_APP_LAYER_PROTOCOLS, &clientHello->alpn.exType); + uint8_t rawData[4] = {0x02, 0x02, 0x01, 0x01}; + FRAME_ModifyMsgArray8(rawData, sizeof(rawData) - 1, &clientHello->alpn.exData, &clientHello->alpn.exDataLen); + clientHello->alpn.exLen.data = 0; + clientHello->alpn.exDataLen.data = 0; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC040 +* @title The extended length of the servername in the clientHello message is 0 and the content is not null. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC040(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedClientHelloMsgCallback_40; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportALPN = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_41(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->alpn.exState = INITIAL_FIELD; + clientHello->alpn.exLen.state = ASSIGNED_FIELD; + clientHello->alpn.exDataLen.state = MISSING_FIELD; + clientHello->alpn.exData.state = MISSING_FIELD; + FRAME_ModifyMsgInteger(HS_EX_TYPE_SERVER_NAME, &clientHello->alpn.exType); + clientHello->alpn.exLen.data = 0; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC041 +* @title The extended length of the servername in the clientHello message is 0. The content is empty. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the tested end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns alert, and the status is alert. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC041(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + // 2. Obtain the message, modify the field content, and send the message. + handle.frameCallBack = MalformedClientHelloMsgCallback_41; + TestPara testPara = {0}; + testPara.port = PORT; + // 4. Check the status of the tested end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + testPara.isSupportExtendMasterSecret = true; + testPara.isSupportALPN = true; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_42(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->extendedMasterSecret.exType.data = 0xFFFFu; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC042 +* @title The sent ClientHello message contains an unrecognized extension type _ extension type +* @precon nan +* @brief 1. The tested end functions as the client and the tested end functions as the server. Expected result 1 is + obtained. + 2. Capture the message, modify the field content, and send the message. Expected result 2 is obtained. + 3. Check the status of the tested end. Expected result 3 is obtained. 4. Check the status of the tested end. + Expected result 4 is obtained. +* @expect 1. A success message is returned. 2. A success message is returned. 3. The tested end returns alert and the + status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC042(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback_42; + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_FINISH; + testPara.expectDescription = ALERT_DECRYPT_ERROR; + testPara.isSupportExtendMasterSecret = false; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedClientHelloMsgCallback_43(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + + clientHello->extensionState = MISSING_FIELD; + clientHello->pointFormats.exState = MISSING_FIELD; + clientHello->supportedGroups.exState = MISSING_FIELD; + clientHello->signatureAlgorithms.exState = MISSING_FIELD; + clientHello->extendedMasterSecret.exState = MISSING_FIELD; + clientHello->secRenego.exState = MISSING_FIELD; +exit: + return; +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC043 +* @title The sent ClientHello message does not contain any extension type. +* @precon nan +* @brief 1. The server stops receiving client hello messages. Expected result 1 is obtained. + 2. Configure the client to send a client hello message without any extension type. Expected result 2 is obtained. + 3. The server continues to establish a link. Expected result 3 is obtained. +* @expect 1. Success 2. Success 3. Success +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC043(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedClientHelloMsgCallback_43; + + TestPara testPara = {0}; + testPara.port = PORT; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + testPara.expectDescription = ALERT_HANDSHAKE_FAILURE; + testPara.isExpectRet = true; + testPara.expectRet = HITLS_MSG_HANDLE_CIPHER_SUITE_ERR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void TEST_UnexpectMsg(HLT_FrameHandle *frameHandle, TestExpect *testExpect, bool isSupportClientVerify) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + ALERT_Info alertInfo = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverConfig = HLT_NewCtxConfigTLCP(NULL, "SERVER", false); + ASSERT_TRUE(serverConfig != NULL); + if (isSupportClientVerify) { + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, isSupportClientVerify) == 0); + } + + HLT_Ctx_Config *clientConfig = HLT_NewCtxConfigTLCP(NULL, "CLIENT", true); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(clientConfig, isSupportClientVerify) == 0); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLCP1_1, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + // Client Initialization + clientRes = HLT_ProcessTlsInit(localProcess, TLCP1_1, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_TRUE(frameHandle != NULL); + frameHandle->ctx = clientRes->ssl; + HLT_SetFrameHandle(frameHandle); + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), testExpect->connectExpect); + HLT_CleanFrameHandle(); + + ALERT_GetInfo(clientRes->ssl, &alertInfo); + ASSERT_TRUE(alertInfo.level == testExpect->expectLevel); + ASSERT_EQ(alertInfo.description, testExpect->expectDescription); + ASSERT_EQ(HLT_RpcGetTlsAcceptResult(serverRes->acceptId), testExpect->acceptExpect); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC006 +* @titleThe client does not send the certificate. Instead, the client sends the certificate. +* @precon nan +* @brief + 1. Configure dual-end verification. Expected result 1 is obtained. + 2. Set the client severhello done callback to send certificate verify. +* @expect 1. Expected success + 2. Expected server to return alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC006() +{ + // 1. Configure dual-end verification. + TestExpect testExpect = {0}; + testExpect.acceptExpect = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + testExpect.expectLevel = ALERT_LEVEL_FATAL; + testExpect.expectDescription = ALERT_UNEXPECTED_MESSAGE; + testExpect.connectExpect = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + HLT_FrameHandle frameHandle = {0}; + // 2. Set the client severhello done callback to send certificate verify. + frameHandle.frameCallBack = TEST_SendUnexpectClientKeyExchangeMsg; + frameHandle.expectHsType = CERTIFICATE; + frameHandle.expectReType = REC_TYPE_HANDSHAKE; + frameHandle.ioState = EXP_NONE; + frameHandle.pointType = POINT_SEND; + frameHandle.userData = NULL; + TEST_UnexpectMsg(&frameHandle, &testExpect, true); + return; +} +/* END_CASE */ + + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SEND_CERTFICATE_VERITY_TC001 +* @title The client does not send the certificate. Instead, the client sends the certificate. +* @precon nan +* @brief + 1. Configure unidirectional authentication. Expected result 1 is obtained. + 2. Set the client severhello done callback to send certificate verify. +* @expect 1. Expected success + 2. Expected server to return alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SEND_CERTFICATE_VERITY_TC001() +{ + // 1. Configure unidirectional authentication. + TestExpect testExpect = {0}; + testExpect.acceptExpect = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + testExpect.expectLevel = ALERT_LEVEL_FATAL; + testExpect.expectDescription = ALERT_UNEXPECTED_MESSAGE; + testExpect.connectExpect = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + + HLT_FrameHandle frameHandle = {0}; + // 2. Set the client severhello done callback to send certificate verify. + frameHandle.frameCallBack = TEST_SendUnexpectCertificateMsg; + frameHandle.expectHsType = CLIENT_KEY_EXCHANGE; + frameHandle.expectReType = REC_TYPE_HANDSHAKE; + frameHandle.ioState = EXP_NONE; + frameHandle.pointType = POINT_SEND; + frameHandle.userData = NULL; + TEST_UnexpectMsg(&frameHandle, &testExpect, false); + return; +} +/* END_CASE */ + + +/* @ +* @test SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC007 +* @title The client does not send the certificate. Instead, the client sends the certificate. +* @precon nan +* @brief + 1. Configure unidirectional authentication. Expected result 1 is obtained. + 2. Set the client severhello done callback to send certificate verify. +* @expect 1. Expected success + 2. Expected server to return alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC007() +{ + // 1. Configure unidirectional authentication. + TestExpect testExpect = {0}; + testExpect.acceptExpect = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + testExpect.expectLevel = ALERT_LEVEL_FATAL; + testExpect.expectDescription = ALERT_UNEXPECTED_MESSAGE; + testExpect.connectExpect = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + + HLT_FrameHandle frameHandle = {0}; + // 2. Set the client severhello done callback to send certificate verify. + frameHandle.frameCallBack = TEST_SendUnexpectCertificateVerifyMsg; + frameHandle.expectHsType = CLIENT_KEY_EXCHANGE; + frameHandle.expectReType = REC_TYPE_HANDSHAKE; + frameHandle.ioState = EXP_NONE; + frameHandle.pointType = POINT_SEND; + frameHandle.userData = NULL; + + TEST_UnexpectMsg(&frameHandle, &testExpect, true); + return; +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC5246_CONSISTENCY_SUPPORT_GROUP_TC001(void) +{ + FRAME_Init(); + HITLS_Config *c_config = NULL; + HITLS_Config *s_config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + c_config = HITLS_CFG_NewTLS12Config(); + s_config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(c_config != NULL); + ASSERT_TRUE(s_config != NULL); + + uint16_t cipherSuite = HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA; + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(c_config, &cipherSuite, 1) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(s_config, &cipherSuite, 1) == HITLS_SUCCESS); + + client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + client->ssl->config.tlsConfig.groupsSize = 0; + server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + +exit: + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +void ClientSendMalformedCipherSuiteLenMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Process *localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HLT_Process *remoteProcess = HLT_LinkRemoteProcess((HITLS), TCP, 16384, false); + ASSERT_TRUE(remoteProcess != NULL); + // The remote server listens on the TLS connection. + + HLT_Ctx_Config *serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + serverConfig->isSupportExtendMasterSecret = false; + HLT_Tls_Res *serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + // Configure the TLS connection on the local client. + + HLT_Ctx_Config *clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + serverConfig->isSupportExtendMasterSecret = false; + HLT_Tls_Res *clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + // Configure the interface for constructing abnormal messages. + + handle->ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + // Set up a connection and wait until the local is complete. + + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + // Wait the remote. + int ret = HLT_GetTlsAcceptResult(serverRes); + ASSERT_TRUE(ret != 0); + if (testPara->isExpectRet) { + ASSERT_EQ(ret, testPara->expectRet); + } + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(clientRes->ssl, &alertInfo); + ASSERT_EQ(alertInfo.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alertInfo.description, testPara->expectDescription); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +static void MalformedCipherSuiteLenCallback_01(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->cipherSuitesSize.data = 1000; + clientHello->cipherSuitesSize.state = ASSIGNED_FIELD; +exit: + return; +} +/** @ +* @test SDV_TLS1_2_RFC5246_MALFORMED_CIPHER_SUITE_LEN_FUN_TC001 +* @spec - +* @title The length of the cipher suite in the sent ClientHello message is greater than the specific content + length_cipher suites length +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server. Expected result 1 is + obtained. + 2. Obtain the message, modify the field content, and send the message. (Expected result 2) + 3. Check the status of the tested end. Expected result 3 is obtained. + 4. Check the status of the test end. Expected result 4 is obtained. +* @expect 1. A success message is returned. + 2. A success message is returned. + 3. The tested end returns an alert message, and the status is alerted. + 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello + message. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void SDV_TLS1_2_RFC5246_MALFORMED_CIPHER_SUITE_LEN_FUN_TC001() +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + /* 1. The tested end functions as the client, and the tested end functions as the server. */ + handle.expectHsType = CLIENT_HELLO; + /* 2. Obtain the message, modify the field content, and send the message. */ + handle.frameCallBack = MalformedCipherSuiteLenCallback_01; + TestPara testPara = {0}; + testPara.port = PORT; + /* 4. Check the status of the test. */ + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + /* 3. Check the status of the tested */ + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedCipherSuiteLenMsg(&handle, &testPara); + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_malformed_msg.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_malformed_msg.data new file mode 100644 index 00000000..741328c5 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc5246_malformed_msg.data @@ -0,0 +1,143 @@ +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC002 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC002: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC003 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC003: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC004 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC004: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC005 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC005: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC006 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC006: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC007 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC007: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC008 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC008: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC009 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC009: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC010 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC011 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC011: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC012 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC012: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC013 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC013: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC014 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC014: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC015 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC015: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC016 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC016: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC017 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC017: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC018 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC018: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC019 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC019: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC020 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC020: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC021 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC021: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC022 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC022: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC023 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC023: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC024 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC024: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC025 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC025: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC026 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC026: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC027 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC027: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC028 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC028: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC029 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC029: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC030 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC030: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC031 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC031: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC032 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC032: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC033 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC033: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC034 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC034: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC035 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC035: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC036 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC036: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC037 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC037: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC038 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC038: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC039 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC039: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC040 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC040: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC041 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC041: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC042 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC042: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC043 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_MALFORMED_CLIENT_HELLO_MSG_FUN_TC043: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC006 Arguments Test +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC006: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SEND_CERTFICATE_VERITY_TC001 Arguments Test +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CLIENT_SEND_CERTFICATE_VERITY_TC001: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC007 Arguments Test +SDV_TLS_TLS12_RFC5246_CONSISTENCY_CERTFICATE_VERITY_FAIL_TC007: + +SDV_TLS_TLS12_RFC5246_CONSISTENCY_SUPPORT_GROUP_TC001 +SDV_TLS_TLS12_RFC5246_CONSISTENCY_SUPPORT_GROUP_TC001: + +SDV_TLS1_2_RFC5246_MALFORMED_CIPHER_SUITE_LEN_FUN_TC001 +SDV_TLS1_2_RFC5246_MALFORMED_CIPHER_SUITE_LEN_FUN_TC001: diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc7627.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc7627.c new file mode 100644 index 00000000..b6aeac26 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc7627.c @@ -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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_session.h" +#include "hitls_error.h" +#include "session.h" +#include "hlt.h" +#include "alert.h" +#include "frame_msg.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "process.h" +#include "hitls_type.h" +#include "session_type.h" +#include "cert_mgr.h" +#include "cert_mgr_ctx.h" +#include "hitls_cert_type.h" +#include "hs_extensions.h" + +/* END_HEADER */ + +static uint32_t g_uiPort = 2569; +#define READ_BUF_SIZE 20 +#define TEMP_DATA_LEN 1024 + +int32_t GetSessionCacheMode(HLT_Ctx_Config *config) +{ + return config->setSessionCache; +} + +static void FrameCallBack_SerrverHello_MasteKey_Add(void *msg, void *userData) +{ + // ServerHello exception: The masterkey extension is added to the sent ServerHello message. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverhello = &frameMsg->body.hsMsg.body.serverHello; + serverhello->extensionLen.state = INITIAL_FIELD; + serverhello->extendedMasterSecret.exState = INITIAL_FIELD; + serverhello->extendedMasterSecret.exType.state = INITIAL_FIELD; + serverhello->extendedMasterSecret.exType.data = HS_EX_TYPE_EXTENDED_MASTER_SECRET; + serverhello->extendedMasterSecret.exLen.state = INITIAL_FIELD; + serverhello->extendedMasterSecret.exLen.data = 0u; +exit: + return; +} +static void FrameCallBack_SerrverHello_MasteKey_MISS(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverhello = &frameMsg->body.hsMsg.body.serverHello; + + serverhello->extendedMasterSecret.exState = MISSING_FIELD; +exit: + return; +} + +/** @ +* @test SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC006 +* @title When the session is resumed, the client receives the server hello message that carries the master key +* extension. +* @precon nan +* @brief 1. The client and server do not support the extension connection establishment. Expected result 1 is +* obtained. +* 2. Disconnect the connection, save the session, and restore the session. +* 3. During session restoration, modify the server hello message to carry the master secret extension. +* Expected result 2 is obtained. +* 4. Establish a connection and observe the connection establishment status. (Expected result 3) +* @expect 1. The connection is set up successfully. +* 2. The modification is successful. +* 3. Session restoration fails and the handshake is interrupted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC006(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_SetExtenedMasterSecretSupport(clientCtxConfig, false); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + // 1. The client and server do not support the extension connection establishment. + HLT_SetExtenedMasterSecretSupport(clientCtxConfig, false); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + DataChannelParam channelParam; + channelParam.port = g_uiPort; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + HLT_CleanFrameHandle(); + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_RECV; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + + handle.expectHsType = SERVER_HELLO; + // 3. During session restoration, modify the server hello message to carry the master key extension. + handle.frameCallBack = FrameCallBack_SerrverHello_MasteKey_Add; + handle.ctx = clientSsl; + ASSERT_TRUE(HLT_SetFrameHandle(&handle) == 0); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + // 4. Establish a connection and observe the connection establishment status. + ASSERT_TRUE(HLT_TlsConnect(clientSsl) != 0); + } else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + // 2. Disconnect the connection, save the session, and restore the session. + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + + cnt++; + } while (cnt < 3); +exit: + HLT_CleanFrameHandle(); + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC007 +* @title When the session is resumed, the client receives a server hello message that does not carry the master key +* extension. +* @precon nan +* @brief 1. The client and server support the extension connection establishment. Expected result 1 is obtained. +* 2. Disconnect the connection, save the session, and restore the session. +* 3. During session recovery, modify the server hello command on the server to cause the master key extension +* to be lost. Expected result 2 is obtained. +* 4. Establish a connection and observe the connection setup status. (Expected result 3) +* @expect 1. The connection is set up successfully. +* 2. The modification is successful. +* 3. Session restoration fails and the handshake is interrupted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC007(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + DataChannelParam channelParam; + channelParam.port = g_uiPort; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + HLT_CleanFrameHandle(); + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_RECV; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + /* 3. During session recovery, modify the server hello command on the server to cause the master key + * extension to be lost. */ + handle.frameCallBack = FrameCallBack_SerrverHello_MasteKey_MISS; + handle.ctx = clientSsl; + ASSERT_TRUE(HLT_SetFrameHandle(&handle) == 0); + + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + // 4. Establish a connection and observe the connection setup status. + ASSERT_TRUE(HLT_TlsConnect(clientSsl) != 0); + } else { + // 1. The client and server support the extension connection establishment. + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + // 2. Disconnect the connection, save the session, and restore the session. + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + cnt++; + } while (cnt < 3); +exit: + HLT_CleanFrameHandle(); + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC008 +* @title Resume sessions on servers that do not support session recovery. +* @precon nan +* @brief 1. The client and server support the extension connection establishment. Disconnect the connection and save +* the session. +* 2. Apply for another server that does not support the extension and establish a connection. Expected result +* 2 is obtained. +* @expect 1. The connection is successfully established. +* 2. Session restoration fails. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC008(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + HLT_FD sockFd2 = {0}; + int cunt = 1; + + HITLS_Session *session = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + int32_t serverConfigId2 = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + HLT_Ctx_Config *serverCtxConfig2 = HLT_NewCtxConfig(NULL, "SERVER"); + // 2. Apply for another server that does not support the extension and establish a connection. + HLT_SetExtenedMasterSecretSupport(serverCtxConfig2, false); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + do { + if (session != NULL) { + + DataChannelParam channelParam2; + channelParam2.port = g_uiPort; + channelParam2.type = connType; + channelParam2.isBlock = true; + sockFd2 = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam2); + ASSERT_TRUE((sockFd2.srcFd > 0) && (sockFd2.peerFd > 0)); + remoteProcess->connFd = sockFd2.peerFd; + localProcess->connFd = sockFd2.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId2 = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId2); + + HLT_Ssl_Config *serverSslConfig2; + serverSslConfig2 = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig2 != NULL); + serverSslConfig2->sockFd = remoteProcess->connFd; + serverSslConfig2->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId2, serverSslConfig2) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId2); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) != 0); + } else { + DataChannelParam channelParam; + channelParam.port = g_uiPort; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + } + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + cunt++; + } while (cunt <= 2); +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc7627.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc7627.data new file mode 100644 index 00000000..2b252b0c --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc7627.data @@ -0,0 +1,9 @@ +SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC006 +SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC006:TLS1_2:TCP + + +SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC008 +SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC008:TLS1_2:TCP + +SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC007 +SDV_TLS_TLS12_RFC7627_CONSISTENCY_EXTENDED_MASTER_SECRET_FUNC_TC007:TLS1_2:TCP \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc8422.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc8422.c new file mode 100644 index 00000000..a32d2a62 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc8422.c @@ -0,0 +1,536 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls12_consistency_rfc5246 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "securec.h" +#include "conn_init.h" +/* END_HEADER */ + +#define g_uiPort 12121 +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC001 +* @title ECDHE_ECDSA requires an ECDSA certificate +* @precon nan +* @brief Set the cipher suite to ECDHE_ECDSA and the certificate to ECDSA. The expected connection setup success is +* expected. +* @expect 1. A success message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + // Set the cipher suite to ECDHE_ECDSA and the certificate to ECDSA. + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1"); + HLT_SetClientVerifySupport(clientCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC002 +* @title ECDHE_ECDSA requires an ECDSA certificate +* @precon nan +* @brief Set the algorithm set to ECDHE_ECDSA and the certificate to the RSA certificate, Expected chain building +* failure +* @expect 1. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC002(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + // Set the algorithm set to ECDHE_ECDSA and the certificate to the RSA certificate, + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1"); + HLT_SetClientVerifySupport(clientCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC001 +* @title When the server selects the ECC cipher suite, the extension of the client must be considered for key +exchange and certificate. +* @precon nan +* @brief 1. Set the curve secp256r1 and secp384r1 on the client and server, set the certificate curve secp384r1 on +* the server, and set the ECC cipher suite. It is expected that the certificate is loaded successfully. +* Set serverkeyexchange to secp256r1, and the connection is set up successfully. +* @expect 1. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384"); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384"); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1:HITLS_EC_GROUP_SECP384R1"); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384"); + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientCtxConfig, NULL); + /* 1. Set the curve secp256r1 and secp384r1 on the client and server, set the certificate curve secp384r1 on + * the server, and set the ECC cipher suite. It is expected that the certificate is loaded successfully. + * Set serverkeyexchange to secp256r1 */ + int ret = HLT_TlsConnect(clientRes->ssl); + ASSERT_TRUE(ret == 0); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC002 +* @spec - +* @title When the server selects the ECC cipher suite, both the key exchange and certificate must comply with the +* extension of the client. +* @precon nan +* @brief 1. Set the curve secp256r1 on the client and server, set the certificate curve secp384r1, and set the ECC +* cipher suite. The certificate is loaded successfully. +* Set the serverkeyexchange parameter is set to secp256r1, the connection fails to be established. +* @expect 1. Connect establishment fails. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC002(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + TestSetCertPath(serverCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384"); + + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384"); + + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1"); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384"); + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientCtxConfig, NULL); + /* Set the curve secp256r1 on the client and server, set the certificate curve secp384r1, and set the ECC + * cipher suite. */ + int ret = HLT_TlsConnect(clientRes->ssl); + ASSERT_TRUE(ret != 0); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); +} +/* END_CASE */ + +static void Test_SetCipherSuites_With_Link(CipherInfo serverCipher, CipherInfo clientCipher, bool expectSuccess) +{ + int ret; + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *client_remote = NULL; + HLT_Process *server_local = NULL; + + server_local = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(server_local != NULL); + client_remote = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, false); + ASSERT_TRUE(client_remote != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + HLT_SetCipherSuites(serverCtxConfig, serverCipher.cipher); + HLT_SetGroups(serverCtxConfig, serverCipher.groups); + HLT_SetSignature(serverCtxConfig, serverCipher.signAlg); + TestSetCertPath(serverCtxConfig, serverCipher.signAlg); + serverRes = HLT_ProcessTlsAccept(server_local, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + HLT_SetCipherSuites(clientCtxConfig, clientCipher.cipher); + HLT_SetGroups(clientCtxConfig, clientCipher.groups); + HLT_SetSignature(clientCtxConfig, clientCipher.signAlg); + + TestSetCertPath(clientCtxConfig, clientCipher.signAlg); + + clientRes = HLT_ProcessTlsConnect(client_remote, TLS1_2, clientCtxConfig, NULL); + if (expectSuccess) { + ASSERT_TRUE(clientRes != NULL); + } else { + ASSERT_TRUE(clientRes == NULL); + goto exit; + } + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + ASSERT_TRUE(HLT_ProcessTlsWrite(server_local, serverRes, (uint8_t *)"Hello", strlen("Hello")) == 0); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + ret = HLT_ProcessTlsRead(client_remote, clientRes, readBuf, READ_BUF_SIZE, &readLen); + ASSERT_TRUE(ret == 0); + ASSERT_TRUE(readLen == strlen("Hello")); + ASSERT_TRUE(memcmp("Hello", readBuf, readLen) == 0); + +exit: + HLT_FreeAllProcess(); +} + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC001 +* @title One configuration, the configuration algorithm suite at both ends is the same, +* and the negotiation behavior is verified +* @precon nan +* @brief 1. Set the cipher suite to HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 at both ends.Expected result 1 is obtained. +* @expect 1. The negotiation is expected to succeed. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC001() +{ + /* 1. Set the cipher suite to HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 at both ends. */ + CipherInfo clientCipher = {.cipher = "HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + .groups = "HITLS_EC_GROUP_SECP384R1", + .signAlg = "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", + .cert = "rsa_sha256"}; + CipherInfo serverCipher = {.cipher = "HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + .groups = "HITLS_EC_GROUP_SECP384R1", + .signAlg = "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", + .cert = "rsa_sha256"}; + Test_SetCipherSuites_With_Link(serverCipher, clientCipher, true); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC002 +* @title One configuration, the cipher suites configured at both ends are the same, and the negotiation behavior is +* verified +* @precon nan +* @brief 1. Set the cipher suite to HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 at both ends. +* Expected result 1 is obtained. +* @expect 1. The negotiation is expected to succeed. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC002() +{ + CipherInfo clientCipher = {.cipher = "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + .groups = "HITLS_EC_GROUP_SECP256R1", + .signAlg = "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + .cert = "ecdsa_sha256"}; + CipherInfo serverCipher = {.cipher = "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + .groups = "HITLS_EC_GROUP_SECP256R1", + .signAlg = "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + .cert = "ecdsa_sha256"}; + Test_SetCipherSuites_With_Link(serverCipher, clientCipher, true); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC003 +* @title One configuration, the cipher suites configured at both ends are the same, and the negotiation behavior is +* verified. +* @precon nan +* @brief 1. Set the cipher suite to HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA at both ends.Expected result 1 is obtained. +* @expect 1. The negotiation is expected to succeed. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC003() +{ + // 1. Set the cipher suite to HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA at both ends. + CipherInfo clientCipher = {.cipher = "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + .groups = "HITLS_EC_GROUP_SECP256R1", + .signAlg = "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + .cert = "ecdsa_sha256"}; + CipherInfo serverCipher = {.cipher = "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + .groups = "HITLS_EC_GROUP_SECP256R1", + .signAlg = "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + .cert = "ecdsa_sha256"}; + Test_SetCipherSuites_With_Link(serverCipher, clientCipher, true); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC004 +* @title One configuration,the cipher suites configured at both ends are the same, and the negotiation behavior is +* verified. +* @precon nan +* @brief 1. Set the cipher suite to HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA at both ends.Expected result 1 is obtained. +* @expect 1. The negotiation is expected to succeed. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC004() +{ + // 1. Set the cipher suite to HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA at both ends. + CipherInfo clientCipher = {.cipher = "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + .groups = "HITLS_EC_GROUP_SECP256R1", + .signAlg = "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", + .cert = "rsa_sha256"}; + CipherInfo serverCipher = {.cipher = "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + .groups = "HITLS_EC_GROUP_SECP256R1", + .signAlg = "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", + .cert = "rsa_sha256"}; + Test_SetCipherSuites_With_Link(serverCipher, clientCipher, true); +} +/* END_CASE */ +static void MalformedClientHelloMsgCallback(void *msg, void *userData) +{ + // 2. Obtain the message, modify the field content, and send the message. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->pointFormats.exDataLen.data = 1; + clientHello->pointFormats.exData.state = MISSING_FIELD; +exit: + return; +} + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC001 +* @title Set the ECC cipher suite.Before the server receives the client hello message, the extended value of the +* point format is changed to 1. As a result, the negotiation on the server is expected to fail. +* @precon nan +* @brief 1. The tested end functions as the client, and the tested end functions as the server.Expected result 1 is +* obtained. +* 2. Obtain the message, modify the field content, and send the message.(Expected result 2) +* 3. Check the status of the tested end.Expected result 3 is obtained. +* 4. Check the status of the test end.Expected result 4 is obtained. +* @expect 1. A success message is returned. +* 2. A success message is returned . +* 3. The tested end returns an alert message, and the status is alerted. +* 4. The status of the test end is alerted, and the handshake status is ready to receive the serverHello +* message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC001(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the client, and the tested end functions as the server. + handle.expectHsType = CLIENT_HELLO; + + handle.frameCallBack = MalformedClientHelloMsgCallback; + TestPara testPara = {0}; + testPara.port = g_uiPort; + // 4. Check the status of the test end. + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedServerHelloMsgCallback(void *msg, void *userData) +{ + // 2. Obtain the message, modify the field content, and send the message. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverHello = &frameMsg->body.hsMsg.body.serverHello; + serverHello->pointFormats.exState = INITIAL_FIELD; + serverHello->pointFormats.exType.state = INITIAL_FIELD; + serverHello->pointFormats.exType.data = HS_EX_TYPE_POINT_FORMATS; + uint8_t data[] = {0}; + FRAME_ModifyMsgArray8(data, sizeof(data), &serverHello->pointFormats.exData, &serverHello->pointFormats.exDataLen); + serverHello->pointFormats.exLen.state = INITIAL_FIELD; + serverHello->pointFormats.exLen.data = serverHello->pointFormats.exDataLen.data + sizeof(uint8_t); + serverHello->pointFormats.exDataLen.data = 1; + serverHello->pointFormats.exData.state = MISSING_FIELD; +exit: + return; +} + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC002 +* @title uses the ECC cipher suite.During connection setup, the serverhello message carries the point format and the +* point format is set to 1. The connection setup fails. +* @precon nan +* @brief 1. The tested end functions as the server and the tested end functions as the client.Expected result 1 is +* obtained. +* 2. Obtain the message, modify the field content, and send the message.(Expected result 2) +* 3. Check the status of the tested end.Expected result 3 is obtained. +* 4. Check the status of the test end.Expected result 4 is obtained. +* @expect 1. A success message is returned. +* 2. A success message is returned +* 3. The tested end returns an alert message, indicating that the status is alerted. +* 4. The status of the tested end is alerted. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC002(void) +{ + HLT_FrameHandle handle = {0}; + handle.userData = (void *)&handle; + handle.pointType = POINT_SEND; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The tested end functions as the server and the tested end functions as the client. + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = MalformedServerHelloMsgCallback; + TestPara testPara = {0}; + testPara.port = g_uiPort; + testPara.isSupportExtendMasterSecret = true; + // 4. The status of the tested end is alerted. + testPara.expectHsState = TRY_RECV_CLIENT_KEY_EXCHANGE; + // 3. Check the status of the tested end. + testPara.expectDescription = ALERT_DECODE_ERROR; + ServerSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ + +static void MalformedNoCurveExternsionCallback(void *msg, void *userData) +{ + // 2. Modify the client to send a client hello message and remove the elliptic curve extension. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clientHello = &frameMsg->body.hsMsg.body.clientHello; + clientHello->supportedGroups.exState = MISSING_FIELD; + clientHello->supportedGroups.exData.state = MISSING_FIELD; + clientHello->supportedGroups.exDataLen.state = MISSING_FIELD; + clientHello->supportedGroups.exLen.state = MISSING_FIELD; + clientHello->supportedGroups.exType.state = MISSING_FIELD; +exit: + return; +} + +/** @ +* @test SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ECDHE_LOSE_CURVE_FUNC_TC001 +* @title: Configure the ECC cipher suite and remove the elliptic curve extension before the server receives the client +* hello message.As a result,the connection establishment fails. +* @precon nan +* @brief 1. The server stops receiving client Hello messages.Expected result 1 is obtained +* 2. Modify the client to send a client hello message and remove the elliptic curve extension.Expected result +* 2 is obtained. +* 3. The server continues to establish a connection.(Expected result 3) +* @expect 1. Success +* 2. Success +* 3. A decryption failure message is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ECDHE_LOSE_CURVE_FUNC_TC001(void) +{ + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + // 1. The server stops receiving client Hello messages. + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = MalformedNoCurveExternsionCallback; + TestPara testPara = {0}; + testPara.port = g_uiPort; + testPara.isSupportExtendMasterSecret = true; + testPara.expectHsState = TRY_RECV_SERVER_HELLO; + // 3. The server continues to establish a connection. + testPara.expectDescription = ALERT_HANDSHAKE_FAILURE; + ClientSendMalformedRecordHeaderMsg(&handle, &testPara); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc8422.data b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc8422.data new file mode 100644 index 00000000..e508545f --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_sdv_hlt_tls12_consistency_rfc8422.data @@ -0,0 +1,32 @@ +SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC001 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC001: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC002 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_ECDHE_ECDSA_FUNC_TC002: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC001 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC001: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC002 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_CURVE_AND_AUTH_FUNC_TC002: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC001 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC001: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC002 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC002: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC003 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC003: + +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC004 +SDV_TLS_TLS12_RFC8422_CONSISTENCY_SET_CIPHERSUITES_FUNC_TC004: + +SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC001 +SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC001: + +SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC002 +SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ERR_POINT_FUNC_TC002: + +SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ECDHE_LOSE_CURVE_FUNC_TC001 +SDV_TLS_TLS12_RFC8422_CONSISTENCYECDHE_ECDHE_LOSE_CURVE_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_tls12_consistency_rfc5246.base.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_tls12_consistency_rfc5246.base.c new file mode 100644 index 00000000..67482d75 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_tls12_consistency_rfc5246.base.c @@ -0,0 +1,494 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_state_recv.h" +#include "conn_init.h" +#include "app.h" +#include "alert.h" +#include "record.h" +#include "rec_conn.h" +#include "session.h" +#include "recv_process.h" +#include "stub_replace.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "cert.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "hlt.h" +#include "sctp_channel.h" +#include "logger.h" +#include "alert.h" + +#define PARSEMSGHEADER_LEN 13 /* Message header length */ +#define ILLEGAL_VALUE 0xFF /* Invalid value */ +#define HASH_EXDATA_LEN_ERROR 23 /* Length of the content of the client_HELLOW signature hash field */ +#define SIGNATURE_ALGORITHMS 0x04, 0x03 /* Fields added to the SERVER_HELLOW message */ +#define READ_BUF_SIZE (18 * 1024) /* Maximum length of the read message buffer */ +#define READ_BUF_LEN_18K (18 * 1024) +#define TEMP_DATA_LEN 1024 /* Length of a single message */ +#define ALERT_BODY_LEN 2u /* Alert data length */ +#define GetEpochSeq(epoch, seq) (((uint64_t)(epoch) << 48) | (seq)) + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isServerExtendMasterSecret; + bool isSupportRenegotiation; /* Renegotiation support flag */ + bool needStopBeforeRecvCCS; /* CCS test, so that the TRY_RECV_FINISH stops before the CCS message is received */ +} HandshakeTestInfo; + +typedef struct { + char *cipher; + char *groups; + char *signAlg; + char *cert; +} CipherInfo; + +typedef struct { + int port; + HITLS_HandshakeState expectHsState; // Expected Local Handshake Status. + bool alertRecvFlag; // Indicates whether the alert is received. The value fasle indicates the sent alert, and the value true indicates the received alert. + ALERT_Description expectDescription; // Expected alert description of the test end. + bool isSupportClientVerify; // Indicates whether to use the dual-end verification. + bool isSupportExtendMasterSecret; // Indicates whether to use an extended master key. + bool isSupportDhCipherSuites; // Indicates whether to use the DHE cipher suite + bool isExpectRet; // Indicates whether the return value is expected. + int expectRet; // Expected return value. The isExpectRet function needs to be enabled. + const char *serverGroup; // Configure the group supported by the server. If this parameter is not specified, the default value is used. + const char *serverSignature; // Configure the signature algorithm supported by the server. If this parameter is left empty, the default value is used. + const char *clientGroup; // Configure the group supported by the client. If this parameter is left empty, the default value is used. + const char *clientSignature; // Configure the signature algorithm supported by the client. If this parameter is left empty, the default value is used. +} TestPara; + +int32_t StatusPark(HandshakeTestInfo *testInfo) +{ + /** Construct link */ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* Perform the CCS test so that the TRY_RECV_FINISH is stopped before the CCS message is received. + * The default value is False, which does not affect the original test. + */ + testInfo->client->needStopBeforeRecvCCS = testInfo->isClient ? testInfo->needStopBeforeRecvCCS : false; + testInfo->server->needStopBeforeRecvCCS = testInfo->isClient ? false : testInfo->needStopBeforeRecvCCS; + + /** Establish a link and stop in a certain state. */ + if (FRAME_CreateConnection(testInfo->client, testInfo->server, testInfo->isClient, testInfo->state) != + HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + /** Construct configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusPark(testInfo); +} + +int32_t DefaultCfgStatusParkWithSuite(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + /** Construct configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(testInfo->config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusPark(testInfo); +} + +int32_t StatusPark1(HandshakeTestInfo *testInfo) +{ + /* Construct a link. */ + if(testInfo->isServerExtendMasterSecret == true){ + testInfo->config->isSupportExtendMasterSecret = true; + }else { + testInfo->config->isSupportExtendMasterSecret = false; + } + testInfo->config->isSupportRenegotiation = false; + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if(testInfo->isServerExtendMasterSecret == true){ + testInfo->config->isSupportExtendMasterSecret = false; + }else { + testInfo->config->isSupportExtendMasterSecret = true; + } + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* Set up a link and stop in a certain state. */ + if (FRAME_CreateConnection(testInfo->client, testInfo->server, + testInfo->isClient, testInfo->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark1(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + /* Construct the configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusPark1(testInfo); +} + +int32_t StatusPark2(HandshakeTestInfo *testInfo) +{ + /* Construct a link. */ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* Establish a link and stop in a certain state. */ + if (FRAME_CreateConnection(testInfo->client, testInfo->server, + testInfo->isClient, testInfo->state) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t SendHelloReq(HITLS_Ctx *ctx) +{ + int32_t ret; + /** Initialize the message buffer. */ + uint8_t buf[HS_MSG_HEADER_SIZE] = {0u}; + size_t len = HS_MSG_HEADER_SIZE; + + /** Write records. */ + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} + +int32_t ConstructAnEmptyCertMsg(FRAME_LinkObj *link) +{ + FRAME_Msg frameMsg = {0}; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(link->io); + + /** Obtain the message buffer. */ + uint8_t *buffer = ioUserData->recMsg.msg; + uint32_t len = ioUserData->recMsg.len; + if (len == 0) { + return HITLS_MEMCPY_FAIL; + } + + /** Parse the message. */ + uint32_t parseLen = 0; + if (ParserTotalRecord(link, &frameMsg, buffer, len, &parseLen) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + /** Construct a message. */ + CERT_Item *tmpCert = frameMsg.body.handshakeMsg.body.certificate.cert; + frameMsg.body.handshakeMsg.body.certificate.cert = NULL; + frameMsg.bodyLen = 15; + + /** reassemble */ + if (PackFrameMsg(&frameMsg) != HITLS_SUCCESS) { + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_INTERNAL_EXCEPTION; + } + + /** Message injection */ + ioUserData->recMsg.len = 0; + if (FRAME_TransportRecMsg(link->io, frameMsg.buffer, frameMsg.len) != HITLS_SUCCESS) { + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_INTERNAL_EXCEPTION; + } + + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_SUCCESS; +} + +int32_t RandBytes(uint8_t *randNum, uint32_t randLen) +{ + srand(time(0)); + const int maxNum = 256u; + for (uint32_t i = randLen - 1; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % maxNum); + } + return HITLS_SUCCESS; +} + +#define TEST_CLIENT_SEND_FAIL 1 +uint32_t g_uiPort = 8889; + +void TestSetCertPath(HLT_Ctx_Config *ctxConfig, char *SignatureType) +{ + if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA1", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA1")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA256")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA256_EE_PATH3, RSA_SHA256_PRIV_PATH3, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA384")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA384_EE_PATH, RSA_SHA384_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA512")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA512_EE_PATH, RSA_SHA512_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + strlen("CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA256_EE_PATH, + ECDSA_SHA256_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384", + strlen("CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA384_EE_PATH, + ECDSA_SHA384_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512", + strlen("CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA512_EE_PATH, + ECDSA_SHA512_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_ECDSA_SHA1", strlen("CERT_SIG_SCHEME_ECDSA_SHA1")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA1_CA_PATH, + ECDSA_SHA1_CHAIN_PATH, + ECDSA_SHA1_EE_PATH, + ECDSA_SHA1_PRIV_PATH, + "NULL", + "NULL"); + } +} + +void ClientSendMalformedRecordHeaderMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + // Create a process. + HLT_Process *localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HLT_Process *remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, false); + ASSERT_TRUE(remoteProcess != NULL); + + // The remote server listens on the TLS link. + HLT_Ctx_Config *serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + + ASSERT_TRUE(HLT_SetCipherSuites(serverConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetGroups(serverConfig, "HITLS_EC_GROUP_SECP256R1") == 0); + ASSERT_TRUE(HLT_SetSignature(serverConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256") == 0); + TestSetCertPath(serverConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + + HLT_Tls_Res *serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // Configure the TLS connection on the local client. + HLT_Ctx_Config *clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetCipherSuites(clientConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetGroups(clientConfig, "HITLS_EC_GROUP_SECP256R1") == 0); + ASSERT_TRUE(HLT_SetSignature(clientConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256") == 0); + TestSetCertPath(clientConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + + HLT_Tls_Res *clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + // Configure the interface for constructing abnormal messages. + handle->ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + // Set up a link and wait for the local end to complete the link. + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + // Wait the remote end. + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) != 0); + + // Confirm the final status. + ASSERT_EQ(HLT_RpcTlsGetStatus(remoteProcess, serverRes->sslId), CM_STATE_ALERTED); + ASSERT_EQ((ALERT_Level)HLT_RpcTlsGetAlertLevel(remoteProcess, serverRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ((ALERT_Description)HLT_RpcTlsGetAlertDescription(remoteProcess, serverRes->sslId), + testPara->expectDescription); + ASSERT_EQ(((HITLS_Ctx *)(clientRes->ssl))->hsCtx->state, testPara->expectHsState); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ServerSendMalformedRecordHeaderMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + // Create a process. + HLT_Process *localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HLT_Process *remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, true); + ASSERT_TRUE(remoteProcess != NULL); + // The local server listens on the TLS link. + HLT_Ctx_Config *serverConfig1 = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig1 != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig1, testPara->isSupportClientVerify) == 0); + + ASSERT_TRUE(HLT_SetCipherSuites(serverConfig1, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetGroups(serverConfig1, "HITLS_EC_GROUP_SECP256R1") == 0); + ASSERT_TRUE(HLT_SetSignature(serverConfig1, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256") == 0); + TestSetCertPath(serverConfig1, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + + HLT_Tls_Res *serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverConfig1, NULL); + ASSERT_TRUE(serverRes != NULL); + + // Configure the interface for constructing abnormal messages. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + // Set up a TLS link on the remote client. + HLT_Ctx_Config *clientConfig1 = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig1 != NULL); + + ASSERT_TRUE(HLT_SetCipherSuites(clientConfig1, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetGroups(clientConfig1, "HITLS_EC_GROUP_SECP256R1") == 0); + ASSERT_TRUE(HLT_SetSignature(clientConfig1, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256") == 0); + TestSetCertPath(clientConfig1, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + HLT_Tls_Res *clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientConfig1, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_TRUE(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId) != 0); + // Wait for the local end. + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + // Confirm the final status. + ASSERT_EQ(((HITLS_Ctx *)(serverRes->ssl))->hsCtx->state, testPara->expectHsState); + ASSERT_TRUE(HLT_RpcTlsGetStatus(remoteProcess, clientRes->sslId) == CM_STATE_ALERTED); + ASSERT_EQ((ALERT_Level)HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ((ALERT_Description)HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), + testPara->expectDescription); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void SetFrameType(FRAME_Type *frametype, uint16_t versionType, REC_Type recordType, HS_MsgType handshakeType, + HITLS_KeyExchAlgo keyExType) +{ + frametype->versionType = versionType; + frametype->recordType = recordType; + frametype->handshakeType = handshakeType; + frametype->keyExType = keyExType; +} \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls12/test_suite_tls12_consistency_rfc5246_malformed_msg.base.c b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_tls12_consistency_rfc5246_malformed_msg.base.c new file mode 100644 index 00000000..b8c16ec0 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls12/test_suite_tls12_consistency_rfc5246_malformed_msg.base.c @@ -0,0 +1,740 @@ +/* + * 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 +#include "securec.h" +#include "hitls_error.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "alert.h" +#include "record.h" +#include "bsl_uio.h" +#include "hitls.h" +#include "pack_frame_msg.h" +#include "parser_frame_msg.h" + +#define MAX_SESSION_ID_SIZE TLS_HS_MAX_SESSION_ID_SIZE +#define MIN_SESSION_ID_SIZE TLS_HS_MIN_SESSION_ID_SIZE +#define COOKIE_SIZE 32u +#define DN_SIZE 32u +#define EXTRA_DATA_SIZE 12u +#define PORT 8005 // The SDV test is a parallel test. The port number used by each test suite must be unique. +// for sni +int32_t ServernameCbErrOK(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)alert; + (void)arg; + + return HITLS_ACCEPT_SNI_ERR_OK; +} +// end for sni +// for alpn +#define MAX_PROTOCOL_LEN 65536 + +/* Protocol matching function at the application layer */ +static int32_t ExampleAlpnSelectProtocol(uint8_t **out, uint8_t *outLen, uint8_t *clientAlpnList, + uint8_t clientAlpnListLen, uint8_t *servAlpnList, uint8_t servAlpnListLen) +{ + int32_t ret = HITLS_ALPN_ERR_ALERT_FATAL; + if (out == NULL || outLen == NULL || clientAlpnList == NULL || servAlpnList == NULL) { + return HITLS_NULL_INPUT; + } + + uint8_t i = 0; + uint8_t j = 0; + for (i = 0; i < servAlpnListLen;) { + for (j = 0; j < clientAlpnListLen;) { + if (servAlpnList[i] == clientAlpnList[j] && + (memcmp(&servAlpnList[i + 1], &clientAlpnList[j + 1], servAlpnList[i]) == 0)) { + *out = &servAlpnList[i + 1]; + *outLen = servAlpnList[i]; + ret = HITLS_ALPN_ERR_OK; + goto END; + } + j = j + clientAlpnList[j]; + ++j; + } + i = i + servAlpnList[i]; + ++i; + } + +END: + return ret; +} + +/* UserData structure transferred by the server to the alpnCb callback. */ +typedef struct TlsAlpnExtCtx_ { + uint8_t *serverAlpnList; + uint32_t serverAlpnListLen; +} TlsAlpnExtCtx; + +/* Select callback for the alpn on the server. */ +int32_t ExampleAlpnCbForLlt(HITLS_Ctx *ctx, uint8_t **selectedProto, uint8_t *selectedProtoSize, + uint8_t *clientAlpnList, uint32_t clientAlpnListSize, void *userData) +{ + (void)ctx; + int32_t ret = 0u; + TlsAlpnExtCtx *alpnData = (TlsAlpnExtCtx *)userData; + uint8_t *selected = NULL; + uint8_t selectedLen = 0u; + + ret = ExampleAlpnSelectProtocol(&selected, &selectedLen, clientAlpnList, clientAlpnListSize, + alpnData->serverAlpnList, alpnData->serverAlpnListLen); + if (ret != HITLS_ALPN_ERR_OK) { + return ret; + } + + *selectedProto = selected; + *selectedProtoSize = selectedLen; + + return HITLS_SUCCESS; +} + +/* Parse the comma-separated application layer protocols transferred by the executable function. */ +int32_t ExampleAlpnParseProtocolList(uint8_t *out, uint32_t *outLen, uint8_t *in, uint32_t inLen) +{ + if (out == NULL || outLen == NULL || in == NULL) { + return HITLS_NULL_INPUT; + } + + if (inLen == 0 || inLen > MAX_PROTOCOL_LEN) { + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint32_t i = 0u; + uint32_t commaNum = 0u; + uint32_t startPos = 0u; + + for (i = 0u; i <= inLen; ++i) { + if (i == inLen || in[i] == ',') { + if (i == startPos) { + ++startPos; + ++commaNum; + continue; + } + out[startPos - commaNum] = (uint8_t)(i - startPos); + startPos = i + 1; + } else { + out[i + 1 - commaNum] = in[i]; + } + } + + *outLen = inLen + 1 - commaNum; + + return HITLS_SUCCESS; +} + +int32_t ExampleAlpnParseProtocolList2(uint8_t *out, uint32_t *outLen, uint8_t *in, uint32_t inLen) +{ + if (out == NULL || outLen == NULL || in == NULL) { + return HITLS_NULL_INPUT; + } + + if (inLen == 0 || inLen > MAX_PROTOCOL_LEN) { + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint32_t i = 0u; + uint32_t commaNum = 0u; + uint32_t startPos = 0u; + + for (i = 0u; i <= inLen; ++i) { + if (i == inLen || in[i] == ',') { + if (i == startPos) { + ++startPos; + ++commaNum; + continue; + } + out[startPos - commaNum] = (uint8_t)(i - startPos); + startPos = i + 1; + } else { + out[i + 1 - commaNum] = in[i]; + } + } + + *outLen = inLen + 1 - commaNum; + + return HITLS_SUCCESS; +} + +// end for alpn + +typedef struct { + int port; + HITLS_HandshakeState expectHsState; + bool alertRecvFlag; + ALERT_Description expectDescription; + bool isSupportClientVerify; + bool isSupportExtendMasterSecret; + bool isSupportSni; + bool isSupportALPN; + bool isSupportDhCipherSuites; + bool isSupportSessionTicket; + bool isExpectRet; + int expectRet; + const char *serverGroup; + const char *serverSignature; + const char *clientGroup; + const char *clientSignature; +} TestPara; + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isSupportRenegotiation; + bool isSupportSessionTicket; + bool needStopBeforeRecvCCS; +} HandshakeTestInfo; +int32_t StatusPark(HandshakeTestInfo *testInfo) +{ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + /* CCS test, so that the TRY_RECV_FINISH is stopped before the CCS packet is received. + * The default value is False, which does not affect the original test. + */ + testInfo->client->needStopBeforeRecvCCS = testInfo->isClient ? testInfo->needStopBeforeRecvCCS : false; + testInfo->server->needStopBeforeRecvCCS = testInfo->isClient ? false : testInfo->needStopBeforeRecvCCS; + /** Set up a connection and stop in a certain state. */ + if (FRAME_CreateConnection(testInfo->client, testInfo->server, testInfo->isClient, testInfo->state) != + HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + /* Construct the configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo->config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(testInfo->config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportSessionTicket = testInfo->isSupportSessionTicket; + return StatusPark(testInfo); +} + +/* The local server initiates a connection creation request: Ignore whether the link creation is successful.*/ +void ServerAccept(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + // Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, true); + ASSERT_TRUE(remoteProcess != NULL); + // The local server listens on the TLS connection. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + // Configure the interface for constructing abnormal messages. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + // Set up a TLS connection on the remote client. + + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetExtenedMasterSecretSupport(clientConfig, testPara->isSupportExtendMasterSecret) == 0); + clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + HLT_RpcTlsConnect(remoteProcess, clientRes->sslId); +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ServerSendMalformedRecordHeaderMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + // Create a process. + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, true); + ASSERT_TRUE(remoteProcess != NULL); + // The local server listens on the TLS link. + + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + ASSERT_TRUE(HLT_SetSessionTicketSupport(serverConfig, testPara->isSupportSessionTicket) == 0); + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(serverConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(serverConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath( + serverConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + if (testPara->serverGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(serverConfig, testPara->serverGroup) == 0); + } + if (testPara->serverSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(serverConfig, testPara->serverSignature) == 0); + } + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + // Configure the interface for constructing abnormal messages. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + // Set up a TLS connection on the remote client. + + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetExtenedMasterSecretSupport(clientConfig, testPara->isSupportExtendMasterSecret) == 0); + ASSERT_TRUE(HLT_SetSessionTicketSupport(clientConfig, testPara->isSupportSessionTicket) == 0); + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(clientConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(clientConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath( + clientConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + if (testPara->clientGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(clientConfig, testPara->clientGroup) == 0); + } + if (testPara->clientSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(clientConfig, testPara->clientSignature) == 0); + } + clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + if (testPara->isExpectRet) { + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), testPara->expectRet); + } else { + ASSERT_TRUE(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId) != 0); + } + // Wait for the local. + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + // Confirm the final status. + + ASSERT_TRUE(((HITLS_Ctx *)(serverRes->ssl))->state == CM_STATE_ALERTED); + ASSERT_TRUE(((HITLS_Ctx *)(serverRes->ssl))->hsCtx != NULL); + ASSERT_EQ(((HITLS_Ctx *)(serverRes->ssl))->hsCtx->state, testPara->expectHsState); + ASSERT_TRUE(HLT_RpcTlsGetStatus(remoteProcess, clientRes->sslId) == CM_STATE_ALERTED); + if (testPara->alertRecvFlag) { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_RECV); + } else { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_SEND); + } + ASSERT_EQ((ALERT_Level)HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ( + (ALERT_Description)HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), testPara->expectDescription); +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ClientSendMalformedRecordHeaderMsg(HLT_FrameHandle *handle, TestPara *testPara) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + // Create a process. + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, testPara->port, false); + ASSERT_TRUE(remoteProcess != NULL); + // The remote server listens on the TLS connection. + + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + ASSERT_TRUE(HLT_SetSessionTicketSupport(serverConfig, testPara->isSupportSessionTicket) == 0); + if (testPara->isSupportSni) { + ASSERT_TRUE(HLT_SetServerNameCb(serverConfig, "ExampleSNIArg") == 0); + ASSERT_TRUE(HLT_SetServerNameArg(serverConfig, "ExampleSNIArg") == 0); + } + if (testPara->isSupportALPN) { + ASSERT_TRUE(HLT_SetAlpnProtosSelectCb(serverConfig, "ExampleAlpnCb", "ExampleAlpnData") == 0); + } + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(serverConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(serverConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath( + serverConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + ASSERT_TRUE(HLT_SetClientVerifySupport(serverConfig, testPara->isSupportClientVerify) == 0); + if (testPara->serverGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(serverConfig, testPara->serverGroup) == 0); + } + if (testPara->serverSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(serverConfig, testPara->serverSignature) == 0); + } + serverConfig->isSupportExtendMasterSecret = false; + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + // Configure the TLS connection on the local client. + + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(HLT_SetSessionTicketSupport(clientConfig, testPara->isSupportSessionTicket) == 0); + if (testPara->isSupportSni) { + ASSERT_TRUE(HLT_SetServerNameCb(clientConfig, "testServer") == 0); + } + if (testPara->isSupportALPN) { + static const char *alpn = "http,ftp"; + uint8_t ParsedList[100] = {0}; + uint32_t ParsedListLen; + ExampleAlpnParseProtocolList2(ParsedList, &ParsedListLen, (uint8_t *)alpn, (uint32_t)strlen(alpn)); + ASSERT_TRUE(HLT_SetAlpnProtos(clientConfig, (const char *)ParsedList) == 0); + } + if (testPara->isSupportDhCipherSuites) { + ASSERT_TRUE(HLT_SetCipherSuites(clientConfig, "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256") == 0); + ASSERT_TRUE(HLT_SetSignature(clientConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256") == 0); + HLT_SetCertPath( + clientConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } + if (testPara->clientGroup != NULL) { + ASSERT_TRUE(HLT_SetGroups(clientConfig, testPara->clientGroup) == 0); + } + if (testPara->clientSignature != NULL) { + ASSERT_TRUE(HLT_SetSignature(clientConfig, testPara->clientSignature) == 0); + } + ASSERT_TRUE(HLT_SetExtenedMasterSecretSupport(clientConfig, testPara->isSupportExtendMasterSecret) == 0); + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + // Configure the interface for constructing abnormal messages. + + handle->ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + // Set up a connection and wait until the local is complete. + + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + // Wait the remote. + int ret = HLT_GetTlsAcceptResult(serverRes); + ASSERT_TRUE(ret != 0); + if (testPara->isExpectRet) { + ASSERT_EQ(ret, testPara->expectRet); + } + // Final status confirmation + ASSERT_EQ(HLT_RpcTlsGetStatus(remoteProcess, serverRes->sslId), CM_STATE_ALERTED); + if (testPara->alertRecvFlag) { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, serverRes->sslId), ALERT_FLAG_RECV); + } else { + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, serverRes->sslId), ALERT_FLAG_SEND); + } + ASSERT_EQ((ALERT_Level)HLT_RpcTlsGetAlertLevel(remoteProcess, serverRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ( + (ALERT_Description)HLT_RpcTlsGetAlertDescription(remoteProcess, serverRes->sslId), testPara->expectDescription); + ASSERT_TRUE(((HITLS_Ctx *)(clientRes->ssl))->state == CM_STATE_ALERTED); + ASSERT_TRUE(((HITLS_Ctx *)(clientRes->ssl))->hsCtx != NULL); + ASSERT_EQ(((HITLS_Ctx *)(clientRes->ssl))->hsCtx->state, testPara->expectHsState); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +// for UT_TLS1_2_RFC5246_RECV_ZEROLENGTH_MSG_TC009 - UT_TLS1_2_RFC5246_RECV_ZEROLENGTH_MSG_TC010 + +int32_t g_writeRet; +uint32_t g_writeLen; +bool g_isUseWriteLen; +uint8_t g_writeBuf[REC_DTLS_RECORD_HEADER_LEN + REC_MAX_CIPHER_TEXT_LEN]; +int32_t STUB_MethodWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + (void)uio; + + if (memcpy_s(g_writeBuf, sizeof(g_writeBuf), buf, len) != EOK) { + return BSL_MEMCPY_FAIL; + } + + *writeLen = len; + if (g_isUseWriteLen) { + *writeLen = g_writeLen; + } + return g_writeRet; +} + +int32_t g_readRet; +uint32_t g_readLen; +uint8_t g_readBuf[REC_DTLS_RECORD_HEADER_LEN + REC_MAX_CIPHER_TEXT_LEN]; +int32_t STUB_MethodRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + (void)uio; + + if (g_readLen != 0 && memcpy_s(buf, len, g_readBuf, g_readLen) != EOK) { + return BSL_MEMCPY_FAIL; + } + + *readLen = g_readLen; + return g_readRet; +} + +int32_t g_ctrlRet; +BSL_UIO_CtrlParameter g_ctrlCmd; +int32_t STUB_MethodCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param) +{ + (void)larg; + (void)uio; + (void)param; + if ((int32_t)g_ctrlCmd == cmd) { + return g_ctrlRet; + } + + return BSL_SUCCESS; +} + +HITLS_Config *g_tlsConfig = NULL; +HITLS_Ctx *g_tlsCtx = NULL; +BSL_UIO *g_uio = NULL; +int32_t TlsCtxNew(BSL_UIO_TransportType type) +{ + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + BSL_UIO *uio = NULL; + const BSL_UIO_Method *ori = NULL; + switch (type) { + case BSL_UIO_TCP: + ori = BSL_UIO_TcpMethod(); + break; + default: + ori = BSL_UIO_SctpMethod(); + break; + } + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + BSL_UIO_Method method = {0}; + memcpy(&method, ori, sizeof(method)); + method.write = STUB_MethodWrite; + method.read = STUB_MethodRead; + method.ctrl = STUB_MethodCtrl; + + uio = BSL_UIO_New(&method); + ASSERT_TRUE(uio != NULL); + ASSERT_TRUE(HITLS_SetUio(ctx, uio) == HITLS_SUCCESS); + + /* Default value of stub function */ + g_writeRet = HITLS_SUCCESS; + g_writeLen = 0; + g_isUseWriteLen = false; + + g_readLen = 0; + g_readRet = HITLS_SUCCESS; + + g_tlsConfig = config; + g_tlsCtx = ctx; + g_uio = uio; + return HITLS_SUCCESS; +exit: + BSL_UIO_Free(uio); + HITLS_Free(ctx); + HITLS_CFG_FreeConfig(config); + return HITLS_INTERNAL_EXCEPTION; +} + +void TlsCtxFree(void) +{ + BSL_UIO_Free(g_uio); + HITLS_Free(g_tlsCtx); + HITLS_CFG_FreeConfig(g_tlsConfig); + + g_uio = NULL; + g_tlsCtx = NULL; + g_tlsConfig = NULL; +} + +// for UT_TLS1_2_RFC5246_RECV_ZEROLENGTH_MSG_TC009 - UT_TLS1_2_RFC5246_RECV_ZEROLENGTH_MSG_TC010 +// for UT_TLS1_2_RFC5246_MISS_CLIENT_KEYEXCHANGE_TC001 +#define PARSEMSGHEADER_LEN 13 +#define ILLEGAL_VALUE 0xFF +#define HASH_EXDATA_LEN_ERROR 23 /* Length of the CLIENT_HELLOW signature hash field. */ +#define SIGNATURE_ALGORITHMS 0x04, 0x03 /* Field added to the end of the SERVER_HELLOW message */ +#define READ_BUF_SIZE (18 * 1024) /* Maximum length of the read message buffer */ +#define TEMP_DATA_LEN 1024 /* Length of a single packet. */ + +int32_t DefaultCfgStatusParkWithSuite(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + /** Construct the configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(testInfo->config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusPark(testInfo); +} + +int32_t SendHelloReq(HITLS_Ctx *ctx) +{ + int32_t ret; + uint8_t buf[HS_MSG_HEADER_SIZE] = {0u}; + size_t len = HS_MSG_HEADER_SIZE; + + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} + +int32_t ConstructAnEmptyCertMsg(FRAME_LinkObj *link) +{ + FRAME_Msg frameMsg = {0}; + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(link->io); + + uint8_t *buffer = ioUserData->recMsg.msg; + uint32_t len = ioUserData->recMsg.len; + if (len == 0) { + return HITLS_MEMCPY_FAIL; + } + /** Parse the message. */ + uint32_t parseLen = 0; + if (ParserTotalRecord(link, &frameMsg, buffer, len, &parseLen) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + /** Construct a message. */ + CERT_Item *tmpCert = frameMsg.body.handshakeMsg.body.certificate.cert; + frameMsg.body.handshakeMsg.body.certificate.cert = NULL; + frameMsg.bodyLen = 15; + + if (PackFrameMsg(&frameMsg) != HITLS_SUCCESS) { + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_INTERNAL_EXCEPTION; + } + ioUserData->recMsg.len = 0; + if (FRAME_TransportRecMsg(link->io, frameMsg.buffer, frameMsg.len) != HITLS_SUCCESS) { + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_INTERNAL_EXCEPTION; + } + frameMsg.body.handshakeMsg.body.certificate.cert = tmpCert; + CleanRecordBody(&frameMsg); + return HITLS_SUCCESS; +} + +int32_t RandBytes(uint8_t *randNum, uint32_t randLen) +{ + srand(time(0)); + const int maxNum = 256u; + for (uint32_t i = 0; i < randLen; i++) { + randNum[i] = (uint8_t)(rand() % maxNum); + } + return HITLS_SUCCESS; +} +// for UT_TLS1_2_RFC5246_MISS_CLIENT_KEYEXCHANGE_TC001 +// for UT_TLS1_2_RFC5246_CERTFICATE_VERITY_FAIL_TC006 - UT_TLS1_2_RFC5246_CERTFICATE_VERITY_FAIL_TC007 + +typedef struct { + int connectExpect; // Expected connect result Return value on end C. + int acceptExpect; // Expected accept result returned value on the s end. + ALERT_Level expectLevel; // Expected alert level. + ALERT_Description expectDescription; // Expected alert description of the tested end. +} TestExpect; + +// Replace the sent message with ClientKeyExchange. +void TEST_SendUnexpectClientKeyExchangeMsg(void *msg, void *data) +{ + FRAME_Type *frameType = (FRAME_Type *)data; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + FRAME_Msg newFrameMsg = {0}; + HS_MsgType hsTypeTmp = frameType->handshakeType; + REC_Type recTypeTmp = frameType->recordType; + frameType->handshakeType = CLIENT_KEY_EXCHANGE; + FRAME_Init(); // Callback for changing the certificate algorithm, which is used to generate the negotiation + // handshake message. + FRAME_GetDefaultMsg(frameType, &newFrameMsg); + HLT_TlsRegCallback(HITLS_CALLBACK_DEFAULT); // recovery callback + FRAME_ModifyMsgInteger(frameMsg->epoch.data, &newFrameMsg.epoch); + FRAME_ModifyMsgInteger(frameMsg->sequence.data, &newFrameMsg.sequence); + FRAME_ModifyMsgInteger(frameMsg->body.hsMsg.sequence.data, &newFrameMsg.body.hsMsg.sequence); + // Release the original msg. + frameType->handshakeType = hsTypeTmp; + frameType->recordType = recTypeTmp; + FRAME_CleanMsg(frameType, frameMsg); + // Change message. + frameType->recordType = REC_TYPE_HANDSHAKE; + frameType->handshakeType = CLIENT_KEY_EXCHANGE; + frameType->keyExType = HITLS_KEY_EXCH_ECDHE; + if (memcpy_s(msg, sizeof(FRAME_Msg), &newFrameMsg, sizeof(newFrameMsg)) != EOK) { + Print("TEST_SendUnexpectClientKeyExchangeMsg memcpy_s Error!"); + } +} + +// Replace the message to be sent with the certificate. +void TEST_SendUnexpectCertificateMsg(void *msg, void *data) +{ + FRAME_Type *frameType = (FRAME_Type *)data; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + FRAME_Msg newFrameMsg = {0}; + HS_MsgType hsTypeTmp = frameType->handshakeType; + frameType->handshakeType = CERTIFICATE; + /* Callback for changing the certificate algorithm, which is used to generate the negotiation handshake message. */ + FRAME_Init(); + FRAME_GetDefaultMsg(frameType, &newFrameMsg); + HLT_TlsRegCallback(HITLS_CALLBACK_DEFAULT); // recovery callback + // Release the original msg. + frameType->handshakeType = hsTypeTmp; + FRAME_CleanMsg(frameType, frameMsg); + // Change message. + + frameType->recordType = REC_TYPE_HANDSHAKE; + frameType->handshakeType = CERTIFICATE; + frameType->keyExType = HITLS_KEY_EXCH_ECDHE; + if (memcpy_s(msg, sizeof(FRAME_Msg), &newFrameMsg, sizeof(newFrameMsg)) != EOK) { + Print("TEST_SendUnexpectCertificateMsg memcpy_s Error!"); + } +} diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_1.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_1.c new file mode 100644 index 00000000..81d0efec --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_1.c @@ -0,0 +1,3318 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "securec.h" +#include "rec_wrapper.h" +#include "conn_init.h" +#include "rec.h" +#include "parse.h" +#include "hs_msg.h" +#include "hs.h" +#include "alert.h" +#include "hitls_type.h" +#include "session_type.h" +#include "hitls_crypt_init.h" +#include "common_func.h" +#include "hlt.h" +#include "process.h" +#include "rec_read.h" +/* END_HEADER */ + +#define g_uiPort 6543 +// REC_Read calls TlsRecordRead calls RecParseInnerPlaintext +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType); + +int32_t STUB_RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + (void)ctx; + (void)text; + (void)textLen; + *recType = (uint8_t)REC_TYPE_APP; + + return HITLS_SUCCESS; +} +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} ResumeTestInfo; + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_APP_DATA_BEFORE_FINISH_FUNC_TC001 + * @spec Application Data MUST NOT be sent prior to sending the Finished message + * @brief 2.Protocol Overview row5 + * 1. Initializing Configurations. + * 2. Stay in the try finish state and send a message. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_APP_DATA_BEFORE_FINISH_FUNC_TC001(int isClient) +{ + FRAME_Init(); + STUB_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + FRAME_LinkObj *sender = isClient ? client : server; + FRAME_LinkObj *recver = isClient ? server : client; + // During connection establishment, the client stops in the TRY_SEND_FINISH state. + ASSERT_TRUE(FRAME_CreateConnection(sender, recver, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + FuncStubInfo stubInfo = {0}; + /* + * Plaintext header of the wrapped record, which is of the app type for finish and app data. + * After the wrapped record body is parsed (that is, the body is decrypted), the last nonzero byte of the body is + * the actual record type. This case is constructed by tampering with the rec type to the app type, + * which should be the hs type. + */ + STUB_Replace(&stubInfo, RecParseInnerPlaintext, STUB_RecParseInnerPlaintext); + if (isClient) { + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + } else { + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&stubInfo); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_SUPPORTED_GROUP_FUNC_TC001 + * @spec 1. Construct a scenario where the supported groups of the client and server do not overlap. Expect the server + * to terminate the handshake and send a handshake_failure message after receiving the client hello message. + * alert + * @brief 4.1.1. Cryptographic Negotiation row 10 + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE. + * + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_SUPPORTED_GROUP_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *config_c = HITLS_CFG_NewTLS13Config(); + HITLS_Config *config_s = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + // Set the groups of the client + uint16_t groups_c[] = {HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + // Set the groups of the server + uint16_t groups_s[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + bool isClient = true; + int32_t ret = FRAME_CreateConnection(client, server, !isClient, TRY_RECV_CLIENT_HELLO); + ASSERT_EQ(ret, HITLS_SUCCESS); + ret = HITLS_Accept(server->ssl); + ASSERT_EQ(ret, HITLS_MSG_HANDLE_HANDSHAKE_FAILURE); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + FRAME_Msg parsedAlert = {0}; + uint32_t parseLen; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(sndBuf, sndLen, &parsedAlert, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_HANDSHAKE_FAILURE); +exit: + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC001 + * @spec + * The client signature algorithm is set to RSA_PSS_PSS_SHA256 and the server certificate signature algorithm + * is set to RSA_PSS_RSAE_SHA256, the connection fails to be established. + * @brief 4.2.3. Signature Algorithms row 54 + * 1. Initialize configuration + * 2. If the signature algorithms are inconsistent, the expected connection setup fails and + * HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE is returned. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *config_c = HITLS_CFG_NewTLS13Config(); + HITLS_Config *config_s = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + // The client signature algorithm is set to RSA_PSS_PSS_SHA256 + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256}; + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + // The server signature algorithm is set to RSA_PSS_RSAE_SHA256 + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256}; + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + FRAME_CertInfo certInfo = { + "rsa_pss_sha256/rsa_pss_root.der", + "rsa_pss_sha256/rsa_pss_intCa.der", + "rsa_pss_sha256/rsa_pss_dev.der", + 0, + "rsa_pss_sha256/rsa_pss_dev.key.der", + 0, + }; + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config_c, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC002 +* @spec - +* The signature algorithm on the client is set to RSA_PSS_RSAE_SHA256 and the signature algorithm on the server +* is set to RSA_PSS_PSS_SHA256, the connection fails to be established. +* @brief 4.2.3. Signature Algorithms row 53 +* 1. Initialize configuration +* 2. If the signature algorithms are inconsistent, the expected connection setup fails and +* HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE is returned. +* @expect +* 1.Initialization succeeded. +* 2.Return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE. +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC002() +{ + FRAME_Init(); + HITLS_Config *config_c = HITLS_CFG_NewTLS13Config(); + HITLS_Config *config_s = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + // The signature algorithm on the client is set to RSA_PSS_RSAE_SHA256 + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256}; + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + // The signature algorithm on the server is set to RSA_PSS_PSS_SHA256 + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256}; + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + FRAME_CertInfo certInfo = { + "rsa_pss_sha256/rsa_pss_root.der", + "rsa_pss_sha256/rsa_pss_intCa.der", + "rsa_pss_sha256/rsa_pss_dev.der", + 0, + "rsa_pss_sha256/rsa_pss_dev.key.der", + 0, + }; + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config_s, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001 + * @brief 4.2.3. Signature Algorithms row 55 + * 1. Set the client server to tls1.3 and the client signature algorithm to rsa-sha1. + * 2. Set the client server to tls1.3 and the client signature algorithm to ecdsa-sha1. + * 3. Set the client server to tls1.3 and the hash in the client signature algorithm to des-sha-224. The expected + * connection establishment fails. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001(int sig) +{ + FRAME_Init(); + HITLS_Config *config_c = HITLS_CFG_NewTLS13Config(); + HITLS_Config *config_s = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + uint16_t signAlgs_c[] = {(uint16_t)sig}; + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_SUPPORT_BY_TLS12SERVER_FUNC_TC001 + * @brief 4.2.3. Signature Algorithms row 57 + * 1. Initialize configuration + * 2. Set the client to tls1.3, server to tls1.2, and the signature algorithm RSA_PSS_RSAE_SHA256 on the client. The + * expected connection setup is successful. + * @expect + * 1.Initialization succeeded. + * 2.The connection is successfully established. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_SUPPORT_BY_TLS12SERVER_FUNC_TC001() +{ + FRAME_Init(); + // tls 11, 12, 13 + HITLS_Config *config_c = HITLS_CFG_NewTLSConfig(); + HITLS_Config *config_s = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + // 1. Set the client to tls1.3, server to tls1.2, and the signature algorithm RSA_PSS_RSAE_SHA256 on the client. + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256}; + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256}; + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + uint16_t cipherSuite[] = {HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(config_c, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(config_s, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC001 + * @spec legacy_session_id_echo: The contents of the client's + * legacy_session_id field. Note that this field is echoed even if + * the client' s value corresponded to a cached pre-TLS 1.3 session + * which the server has chosen not to resume. A client which + * receives a legacy_session_id_echo field that does not match what + * it sent in the ClientHello MUST abort the handshake with an + * "illegal_parameter" alert. + * @brief 4.1.3. Server Hello row 25 + * 1.Initialize configuration + * 2.A client which receives a legacy_session_id_echo field that does not match what + * it sent in the ClientHello MUST abort the handshake with an "illegal_parameter" alert. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + FRAME_Msg parsedSH = {0}; + uint32_t parseLen = 0; + FRAME_Type frameType = {0}; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &parsedSH, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *shMsg = &parsedSH.body.hsMsg.body.serverHello; + memset_s((shMsg->sessionId.data), shMsg->sessionId.size, 1, shMsg->sessionId.size); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + FRAME_CleanMsg(&frameType, &parsedSH); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC002 + * @spec legacy_session_id_echo: The contents of the client's + * legacy_session_id field. Note that this field is echoed even if + * the client' s value corresponded to a cached pre-TLS 1.3 session + * which the server has chosen not to resume. A client which + * receives a legacy_session_id_echo field that does not match what + * it sent in the ClientHello MUST abort the handshake with an + * "illegal_parameter" alert. + * @brief 4.1.3. Server Hello row 25 + * 1.Initialize configuration + * 2.A client which receives a legacy_session_id_echo field that does not match what + * it sent in the ClientHello MUST abort the handshake with an "illegal_parameter" alert. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC002() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + FRAME_Msg parsedSH = {0}; + uint32_t parseLen = 0; + FRAME_Type frameType = {0}; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &parsedSH, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *shMsg = &parsedSH.body.hsMsg.body.serverHello; + shMsg->sessionId.size = 0; + shMsg->sessionId.state = MISSING_FIELD; + shMsg->sessionIdSize.data = 0; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + FRAME_CleanMsg(&frameType, &parsedSH); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CIPHERSUITE_FROM_SH_FUNC_TC001 + * @spec serverSelect one of ClientHello.cipher_suites. If the server is not provided by the client, the client must + * terminate the handshake and respond with an illegal message. parameter alarm row 26 + * @brief cipher_suite: The single cipher suite selected by the server from + * the list in ClientHello.cipher_suites. A client which receives a + * cipher suite that was not offered MUST abort the handshake with an "illegal_parameter" alert. + * 1.Initialize configuration + * 2.A client which receives a cipher suite that was not offered MUST abort the handshake with an + * "illegal_parameter" alert. + * @expect + * 1.Initialization succeeded. + * 2.Return ALERT_ILLEGAL_PARAMETER. + * + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CIPHERSUITE_FROM_SH_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg parsedSH = {0}; + uint32_t parseLen = 0; + FRAME_Type frameType; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &parsedSH, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *shMsg = &parsedSH.body.hsMsg.body.serverHello; + shMsg->cipherSuite.data = HITLS_AES_128_CCM_SHA256; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + FrameUioUserData *userData = BSL_UIO_GetUserData(client->io); + uint8_t *alertBuf = userData->sndMsg.msg; + uint32_t alertLen = userData->sndMsg.len; + FRAME_Msg parsedAlert = {0}; + uint32_t parsedAlertLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(alertBuf, alertLen, &parsedAlert, &parsedAlertLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_ILLEGAL_PARAMETER); +exit: + FRAME_CleanMsg(&frameType, &parsedSH); + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MISSING_SIG_ALG_FROM_CH_FUNC_TC001 + * @spec + * 1. Set the client server to tls1.3 and construct the client hello message that does not contain the + * signature_algorithm extension. The server is expected to return the missing_extension alarm. + * @brief If a server is authenticating via + * a certificate and the client has not sent a "signature_algorithms" + * extension, then the server MUST abort the handshake with a + * "missing_extension" alert + * 4.2.3. Signature Algorithms row 51 + * 1.Initialize configuration + * 2.A client which receives a cipher suite that was not offered MUST abort the handshake with an + * "illegal_parameter" alert. + * @expect + * 1.Initialization succeeded. + * 2.Return ALERT_MISSING_EXTENSION. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MISSING_SIG_ALG_FROM_CH_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg parsedCH = {0}; + uint32_t parseLen = 0; + FRAME_Type frameType = {0}; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &parsedCH, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *chMsg = &parsedCH.body.hsMsg.body.clientHello; + chMsg->signatureAlgorithms.exState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedCH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_MISSING_EXTENSION); + + FrameUioUserData *userData = BSL_UIO_GetUserData(server->io); + uint8_t *alertBuf = userData->sndMsg.msg; + uint32_t alertLen = userData->sndMsg.len; + FRAME_Msg parsedAlert = {0}; + uint32_t parsedAlertLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(alertBuf, alertLen, &parsedAlert, &parsedAlertLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_MISSING_EXTENSION); +exit: + FRAME_CleanMsg(&frameType, &parsedCH); + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CERT_VERIFY_FUNC_TC001 + * @brief 4.4.3. Certificate Verify row 147 row 148 + * 1. Set the signature algorithms on the client and server to CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + * Change the value of signature_algorithms in the CertificateVerify message sent by the server to + * CERT_SIG_SCHEME_DSA_SHA224 and continue to establish a connection. Expected result: After receiving the + * CertificateVerify message, the client sends an alert message and the connection is disconnected. + * 2. Set the dual-end verification, set the signature algorithm supported by the client and server to + * CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, and establish a connection, Change the signature algorithm field in + * the CertificateVerify message sent by the client to CERT_SIG_SCHEME_DSA_SHA224. Expected result: + * After receiving the CertificateVerify message, the server sends an alert message and the connection + * is disconnected. + * @expect + * 1.The client sends an alert message and the connection is disconnected. + * 2.The server sends an alert message and the connection is disconnected. + * + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CERT_VERIFY_FUNC_TC001(int isClient) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportClientVerify = true; + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + /* 1.Set the signature algorithms on the client and server to CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + * Change the value of signature_algorithms in the CertificateVerify message sent by the server to + * CERT_SIG_SCHEME_DSA_SHA224 and continue to establish a connection. */ + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384}; + HITLS_CFG_SetSignature(tlsConfig, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + ASSERT_TRUE(FRAME_CreateConnection(client, server, isClient, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + int32_t ret; + HITLS_Ctx *ctx = isClient ? client->ssl : server->ssl; + HS_Ctx *hsCtx = ctx->hsCtx; + uint8_t *buf = hsCtx->msgBuf; + uint32_t dataLen = 0; + HS_MsgInfo hsMsgInfo = {0}; + ret = REC_Read(ctx, REC_TYPE_HANDSHAKE, buf, &dataLen, hsCtx->bufferLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + /* 2. Set the dual-end verification, set the signature algorithm supported by the client and server to + * CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, and establish a connection, Change the signature algorithm field in + * the CertificateVerify message sent by the client to CERT_SIG_SCHEME_DSA_SHA224. */ + memset_s(buf + HS_MSG_HEADER_SIZE, sizeof(uint16_t), CERT_SIG_SCHEME_DSA_SHA224, sizeof(uint16_t)); + ret = HS_ParseMsgHeader(ctx, buf, dataLen, &hsMsgInfo); + ASSERT_TRUE(ret == HITLS_SUCCESS); + HS_Msg hsMsg = {0}; + ret = HS_ParseMsg(ctx, &hsMsgInfo, &hsMsg); + ASSERT_EQ(ret, HITLS_PARSE_UNSUPPORT_SIGN_ALG); + ALERT_Info alertInfo = {0}; + (void)ALERT_GetInfo(ctx, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_ILLEGAL_PARAMETER); + ASSERT_EQ(alertInfo.level, ALERT_LEVEL_FATAL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, isClient, HS_STATE_BUTT) != HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMPTION_FUNC_TC001 + * @brief + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMPTION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + HITLS_SetSession(client->ssl, clientSession); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FUNC_TC001 + * @brief + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetPskServerCallback(config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); // 1.2 psk bind with sha256 + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + HITLS_CFG_SetGroups(config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PREFER_PSS_TO_PKCS1_FUNC_TC001 + * @brief 4.4.3. Certificate Verify row 149 + * 1.Initialize configuration + * 2. Configure the RSA certificate on the server and set the signature algorithm supported by the server to + * {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256}, Establish a connection and check whether + * the negotiated signature algorithm is CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256. Expected result: + * CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256 is negotiated. + * @expect + * 1.Initialization succeeded. + * 2.The connection is successfully set up, and the negotiation algorithm is CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PREFER_PSS_TO_PKCS1_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *config_c = HITLS_CFG_NewTLS13Config(); + HITLS_Config *config_s = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256}; + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + uint16_t cipherSuite[] = {HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(config_s, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + FRAME_CertInfo certInfo = { + "rsa_pss_sha256/rsa_pss_root.der", + "rsa_pss_sha256/rsa_pss_intCa.der", + "rsa_pss_sha256/rsa_pss_dev.der", + 0, + "rsa_pss_sha256/rsa_pss_dev.key.der", + 0, + }; + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config_c, BSL_UIO_TCP, &certInfo); + FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config_s, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(server->ssl->negotiatedInfo.signScheme, CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ +static void Test_ModifyFinish(HITLS_Ctx *ctx, uint8_t *buf, uint32_t *bufLen, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + /* hs msg struct, the first byte indicates the HandshakeType, + * the following 3 bytes indicate the remaining bytes in message + */ + uint8_t modifiedHsMsg[] = {KEY_UPDATE, 0, 0, sizeof(uint8_t), HITLS_UPDATE_REQUESTED}; + (void)memcpy_s(buf, bufSize, modifiedHsMsg, sizeof(modifiedHsMsg)); + *bufLen = sizeof(modifiedHsMsg); +} +int32_t STUB_ConnUnexpectedMsg(HITLS_Ctx *ctx, uint32_t msgType, const uint8_t *data, uint32_t dataLen) +{ + if (ctx == NULL || data == NULL) { + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + int32_t ret; + CM_State state = ctx->state; + uint8_t modifiedData[5] = {0}; + (void)memcpy_s(modifiedData, 5, data, 5); + modifiedData[4] = 3; + + switch (msgType) { + case REC_TYPE_HANDSHAKE: + ret = HS_RecvUnexpectedMsgProcess(ctx, modifiedData, dataLen, &state); + break; + default: + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + break; + } + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; +} + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_INVALID_REQ_VAL_FUNC_TC001 + * @brief 4.6.3. Key and Initialization Vector Update row 178 + * 1. Establish a connection, change the value of the updata message sent by the client to 3, and observe the server + * behavior. Expected result: The server returns the illegal parameter. + * 2. Establish a connection, change the value of the updata message sent by the server to 3, and observe the client + * behavior. Expected result: The client returns the illegal parameter. + * @expect + * 1.Initialization succeeded. + * 2.Return ALERT_ILLEGAL_PARAMETER. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_INVALID_REQ_VAL_FUNC_TC001(int isClient) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, isClient, HS_STATE_BUTT), HITLS_SUCCESS); + FRAME_LinkObj *sender = isClient ? client : server; + FRAME_LinkObj *recver = isClient ? server : client; + ASSERT_TRUE(HITLS_KeyUpdate(sender->ssl, HITLS_UPDATE_NOT_REQUESTED) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(sender, recver) == HITLS_SUCCESS); + HITLS_Ctx *ctx = recver->ssl; + uint8_t dest[READ_BUF_SIZE] = {0}; + uint32_t readbytes = 0; + /* 1. Establish a connection, change the value of the updata message sent by the client to 3, and observe the + * server behavior. Expected result: The server returns the illegal parameter. + * 2. Establish a connection, change the value of the updata message sent by the server to 3, and observe the + * client behavior. */ + ctx->method.unexpectedMsgProcessCb = STUB_ConnUnexpectedMsg; + ASSERT_EQ(HITLS_Read(ctx, dest, READ_BUF_SIZE, &readbytes), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info alertInfo = {0}; + ALERT_GetInfo(ctx, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC001 + * @brief 4.6.3. Key and Initialization Vector Update row 179 + * 1. After the client receives the update_requested message, the update message returned by the client is lost. + * The client continues to send app messages and observe the server behavior. Expected result: The server sends an + * alert message and the connection is disconnected. + * Analysis: The server application traffic secret is updated on both communication ends, + * The client application traffic secret is updated on the client, but the server does not + * update the client application traffic secret. When the server sends a message to the client, + * the client can parse the message, but the server cannot parse the message. + * @expect + * 1.the server cannot parse the message and return ALERT_BAD_RECORD_MAC + * + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC001() +{ + FRAME_Init(); + int32_t ret; + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_KeyUpdate(server->ssl, HITLS_UPDATE_REQUESTED) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + uint8_t dest[READ_BUF_SIZE] = {0}; + uint32_t readbytes = 0; + ASSERT_EQ(HITLS_Read(client->ssl, dest, READ_BUF_SIZE, &readbytes), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + /* 1. After the client receives the update_requested message, the update message returned by the client is lost. + * The client continues to send app messages and observe the server behavior. */ + uint8_t lostBuffer[MAX_RECORD_LENTH] = {0}; + uint32_t lostLen = 0; + ret = FRAME_TransportSendMsg(client->io, lostBuffer, MAX_RECORD_LENTH, &lostLen); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_NE(lostLen, 0); + + uint8_t src[] = "Client is sending msg with new application traffic key"; + ASSERT_EQ(HITLS_Write(client->ssl, src, sizeof(src)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + memset_s(dest, READ_BUF_SIZE, 0, READ_BUF_SIZE); + readbytes = 0; + ASSERT_EQ(HITLS_Read(server->ssl, dest, READ_BUF_SIZE, &readbytes), HITLS_REC_BAD_RECORD_MAC); + ALERT_Info alertInfo = {0}; + ALERT_GetInfo(server->ssl, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_BAD_RECORD_MAC); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC002 + * @brief 4.6.3. Key and Initialization Vector Update row 179 + * 2. When the server receives the update_requested message, the update message returned by the server is lost. + * The server continues to send app messages and observe the customer behavior. Expected result: The client sends an + * alert message and the connection is disconnected. Analysis: The client application traffic secret is updated at both + * communication ends, The server application traffic secret is updated on the server, but the server application + * traffic secret is not updated on the client. When the client sends a message to the server, the server can parse the + * message, but the server cannot parse the message. + * + * @expect + * 1.the server cannot parse the message and return ALERT_BAD_RECORD_MAC + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC002() +{ + FRAME_Init(); + int32_t ret; + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_KeyUpdate(client->ssl, HITLS_UPDATE_REQUESTED) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + uint8_t dest[READ_BUF_SIZE] = {0}; + uint32_t readbytes = 0; + ASSERT_EQ(HITLS_Read(server->ssl, dest, READ_BUF_SIZE, &readbytes), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + /* 2. When the server receives the update_requested message, the update message returned by the server is lost. The + * server continues to send app messages and observe the customer behavior. */ + uint8_t lostBuffer[MAX_RECORD_LENTH] = {0}; + uint32_t lostLen = 0; + ret = FRAME_TransportSendMsg(server->io, lostBuffer, MAX_RECORD_LENTH, &lostLen); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_NE(lostLen, 0); + + uint8_t src[] = "Server is sending msg with new application traffic key"; + ASSERT_EQ(HITLS_Write(server->ssl, src, sizeof(src)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + memset_s(dest, READ_BUF_SIZE, 0, READ_BUF_SIZE); + readbytes = 0; + ASSERT_EQ(HITLS_Read(client->ssl, dest, READ_BUF_SIZE, &readbytes), HITLS_REC_BAD_RECORD_MAC); + ALERT_Info alertInfo = {0}; + ALERT_GetInfo(client->ssl, &alertInfo); + ASSERT_EQ(alertInfo.description, ALERT_BAD_RECORD_MAC); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_READ_WRITE_AFTER_FATAL_ALEART_FUNC_TC001 + * @brief 6. Alert Protocol row 206 + * Upon receiving an fatal alert, the TLS implementation SHOULD indicate an error to the application and MUST NOT + * allow any further data to be sent or received on the connection. + * 1. After receiving the fatal alert, the server invokes the read interface. The invoking fails. + * 2. After receiving the fatal alert, the server fails to invoke the write interface. + * 3. After receiving the fatal alert, the server fails to invoke the read interface. + * 4. After receiving the fatal alert, the server invokes the write interface. The invoking fails. + * @expect + * 1.the server invokes the read interface fails and return HITLS_CM_LINK_FATAL_ALERTED + * 4.the server invokes the write interface fails and return HITLS_CM_LINK_FATAL_ALERTED + * + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_READ_WRITE_AFTER_FATAL_ALEART_FUNC_TC001(int isClient) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, isClient, HS_STATE_BUTT), HITLS_SUCCESS); + FRAME_LinkObj *sender = isClient ? client : server; + FRAME_LinkObj *recver = isClient ? server : client; + ASSERT_TRUE(HITLS_KeyUpdate(sender->ssl, HITLS_UPDATE_NOT_REQUESTED) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(sender, recver) == HITLS_SUCCESS); + uint8_t dest[READ_BUF_SIZE] = {0}; + uint32_t readbytes = 0; + recver->ssl->method.unexpectedMsgProcessCb = STUB_ConnUnexpectedMsg; + ASSERT_EQ(HITLS_Read(recver->ssl, dest, READ_BUF_SIZE, &readbytes), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info alertInfo = {0}; + ALERT_GetInfo(recver->ssl, &alertInfo); + ASSERT_EQ(alertInfo.level, ALERT_LEVEL_FATAL); + + ASSERT_EQ(recver->ssl->state, CM_STATE_ALERTED); + /* 1. After receiving the fatal alert, the server invokes the read interface. */ + + ASSERT_EQ(HITLS_Read(recver->ssl, dest, READ_BUF_SIZE, &readbytes), HITLS_CM_LINK_FATAL_ALERTED); + uint8_t src[] = "Hello world"; + /* 4. After receiving the fatal alert, the server invokes the write interface. */ + + ASSERT_EQ(HITLS_Write(recver->ssl, src, sizeof(src)), HITLS_CM_LINK_FATAL_ALERTED); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC001 + * @brief 4.6.3. Key and Initialization Vector Update row 175 + * The KeyUpdate message can be sent by any peer after the Finished message is sent. + * An implementation that receives a KeyUpdate message before receiving a Finished message must terminate the + * connection with an unexpected_message alert. When the client receives the Finish message, construct abnormal + * packets so that the client receives the Updata message and observe the next message sent by the client. + * Expected result: The next ALERT_UNEXPECTED_MESSAGE message is sent. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + bool isRecRead = true; + RecWrapper wrapper = {TRY_RECV_FINISH, REC_TYPE_HANDSHAKE, isRecRead, NULL, Test_ModifyFinish}; + RegisterWrapper(wrapper); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC002 + * @brief 4.6.3. Key and Initialization Vector Update row 175 + * The KeyUpdate message can be sent by any peer after the Finished message is sent. + * An implementation that receives a KeyUpdate message before receiving a Finished message must terminate the + * connection with an unexpected_message alert. When the server receives the Finish message, construct abnormal packets + * so that the server receives the Updata message and observe the next message sent by the server. Expected result: The + * next ALERT_UNEXPECTED_MESSAGE message is sent. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC002() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + bool isRecRead = true; + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + RecWrapper wrapper = {TRY_RECV_FINISH, REC_TYPE_HANDSHAKE, isRecRead, NULL, Test_ModifyFinish}; + RegisterWrapper(wrapper); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC003 + * @brief 4.6.3. Key and Initialization Vector Update row 175 + * The KeyUpdate message can be sent by any peer after the Finished message is sent. + * An implementation that receives a KeyUpdate message before receiving a Finished message must terminate the + * connection with an unexpected_message alert. When the client receives the Finish message, construct an abnormal + * packet so that the client receives the Update message and observe the next message sent by the client. Expected + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + bool isRecRead = true; + RecWrapper wrapper = {TRY_RECV_FINISH, REC_TYPE_HANDSHAKE, isRecRead, NULL, Test_ModifyFinish}; + RegisterWrapper(wrapper); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(tlsConfig, &cipherSuite, 1); + HITLS_CFG_SetPskClientCallback(tlsConfig, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(tlsConfig, (HITLS_PskServerCb)ExampleServerCb); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC004 + * @brief 4.6.3. Key and Initialization Vector Update row 175 + * The KeyUpdate message can be sent by any peer after the Finished message is sent. + * An implementation that receives a KeyUpdate message before receiving a Finished message must terminate the + * connection with an unexpected_message alert. When the PSK session is resumed and the connection is established, the + * client constructs an abnormal packet so that the client receives the update message and observes the next message + * sent by the client. Expected result: The next ALERT_UNEXPECTED_MESSAGE message is sent. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC004() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + HITLS_SetSession(client->ssl, clientSession); + + bool isRecRead = true; + RecWrapper wrapper = {TRY_RECV_FINISH, REC_TYPE_HANDSHAKE, isRecRead, NULL, Test_ModifyFinish}; + RegisterWrapper(wrapper); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC005 + * @brief 4.6.3. Key and Initialization Vector Update row 175 + * The KeyUpdate message can be sent by any peer after the Finished message is sent. + * When the server receives the finish message, construct an abnormal packet so that the server receives the update + * message and observe the next message sent by the server. Expected result: The next ALERT_UNEXPECTED_MESSAGE message + * is sent. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC005() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(tlsConfig, &cipherSuite, 1); + HITLS_CFG_SetPskClientCallback(tlsConfig, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(tlsConfig, (HITLS_PskServerCb)ExampleServerCb); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + bool isRecRead = true; + RecWrapper wrapper = {TRY_RECV_FINISH, REC_TYPE_HANDSHAKE, isRecRead, NULL, Test_ModifyFinish}; + RegisterWrapper(wrapper); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC006 + * @brief 4.6.3. Key and Initialization Vector Update row 175 + * The KeyUpdate message can be sent by any peer after the Finished message is sent. + * When the PSK session is resumed and the connection is established, the server constructs an abnormal packet so that + * the server receives the update message and observes the next message sent by the server. Expected result: The next + * ALERT_UNEXPECTED_MESSAGE message is sent. + * @expect + * 1.Initialization succeeded. + * 2.Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC006() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + HITLS_SetSession(client->ssl, clientSession); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + bool isRecRead = true; + RecWrapper wrapper = {TRY_RECV_FINISH, REC_TYPE_HANDSHAKE, isRecRead, NULL, Test_ModifyFinish}; + RegisterWrapper(wrapper); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVAPP_AFTER_CERT_FUNC_TC001 + * @spec A Finished message MUST be sent regardless of whether the Certificate message is empty. + * @brief 4.4.2. Certificate row114 + * 1. The certificate message sent by the server is not empty and the app message is directly sent. + * Expected result: The handshake between the two parties fails. The client sends an unexpected message alert. The level + * is ALERT_Level_FATAL, the description is ALERT_UNEXPECTED_MESSAGE, and the handshake is interrupted. + * 2. Dual-end verification: The peer certificate can be empty, the certificate message sent by the client is empty, and + * the app message is directly sent. Expected result: The handshake between the two parties fails. The server sends an + * unexpected message alert. The level is ALERT_Level_FATAL, the description is ALERT_UNEXPECTED_MESSAGE, and the + * handshake is interrupted. + * @expect + * 1.Handshake failed. The client sends ALERT_UNEXPECTED_MESSAGE. + * 2.Handshake failed. The server sends ALERT_UNEXPECTED_MESSAGE. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVAPP_AFTER_CERT_FUNC_TC001(int isClient) +{ + FRAME_Init(); + STUB_Init(); + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + 0, + 0, + 0, + 0, + }; + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + /* 1. The certificate message sent by the server is not empty and the app message is directly sent. + * tlsConfig->isSupportClientVerify = true; + * 2. Dual-end verification: The peer certificate can be empty, the certificate message sent by the client is empty, + * and the app message is directly sent. */ + tlsConfig->isSupportNoClientCert = true; + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(tlsConfig, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + FRAME_LinkObj *client = FRAME_CreateLinkWithCert(tlsConfig, BSL_UIO_TCP, &certInfo); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + if (isClient) { + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + } else { + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + } + FuncStubInfo stubInfo = {0}; + /* + * Plaintext header of the wrapped record, which is of the app type for finish and app data. + * After the wrapped record body is parsed (that is, the body is decrypted), the last nonzero byte of the body is + * the actual record type. This case is constructed by tampering with the rec type to the app type, which should be + * the hs type. + */ + STUB_Replace(&stubInfo, RecParseInnerPlaintext, STUB_RecParseInnerPlaintext); + if (isClient) { + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + } else { + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&stubInfo); +} +/* END_CASE */ + +static int32_t SendCcs(HITLS_Ctx *ctx, uint8_t *data, uint8_t len) +{ + int32_t ret = REC_Write(ctx, REC_TYPE_CHANGE_CIPHER_SPEC, data, len); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; +} + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001 + * @spec + * 1. If the server receives a CCS message before receiving the client hello message, the server sends the + * unexpected_message alarm to terminate the connection. + * @brief If an implementation detects a change_cipher_spec record received before the first ClientHello + * message or after the peer' s Finished message, it MUST be treated as an unexpected record type. + * 5. Record Protocol row 183 + * @expect + * 1.the server sends the ALERT_UNEXPECTED_MESSAGE and terminate the connection. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_CLIENT_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(client->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, MAX_RECORD_LENTH, ioServerData->sndMsg.msg, ioServerData->sndMsg.len) == EOK); + sndMsg.len = ioServerData->sndMsg.len; + ioServerData->sndMsg.len = 0; + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002 + * @spec + * 1. After receiving the finished message and CCS message, the client sends the unexpected_message alarm to terminate + * the connection. + * 2. After receiving the finished message and CCS message, the server sends the unexpected_message alarm to terminate + * the connection. + * @brief If an implementation detects a change_cipher_spec record received before the first ClientHello + * message or after the peer' s Finished message, it MUST be treated as an unexpected record type. + * 5. Record Protocol row 183 + * @expect + * 1.the client sends the ALERT_UNEXPECTED_MESSAGE and terminate the connection. + * 2.the server sends the ALERT_UNEXPECTED_MESSAGE and terminate the connection. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002(int isClient) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + uint8_t data = 1; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + if (isClient != 0) { + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 2. After receiving the finished message and CCS message, the server sends the unexpected_message alarm to + * terminate the connection. */ + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + } else { + memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE); + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 1. After receiving the finished message and CCS message, the client sends the unexpected_message alarm to + * terminate the connection. */ + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ZERO_APPMSG_FUNC_TC001 + * @spec + * 1. Establish a connection. After the connection is established, construct an APPdata message with 0 length and send + * it to the server. Then, send an APPdata message with data to the server. The message can be received normally. + * 2. Establish a connection. After the connection is established, construct an APPdata message with zero length and + * send it to the client. Then, send an APPdata message with data to the client. The message can be received normally. + * @brief Zero-length fragments of Application Data MAY be sent, as they are potentially useful as a traffic analysis + * countermeasure. 5.1. Record Layer row 189 + * @expect + * 1.The connection is successfully established and received normally. + * 2.The connection is successfully established and received normally. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ZERO_APPMSG_FUNC_TC001(int isZeroClient) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + uint8_t data[] = ""; + uint8_t appData[] = "hello world"; + uint8_t serverData[READ_BUF_SIZE] = {0}; + uint8_t clientData[READ_BUF_SIZE] = {0}; + ASSERT_TRUE((sizeof(data) <= READ_BUF_SIZE) && (sizeof(appData) <= READ_BUF_SIZE)); + if (isZeroClient != 0) { + /* 1. Establish a connection. After the connection is established, construct an APPdata message with 0 length + * and send it to the server. Then, send an APPdata message with data to the server. */ + (void)memcpy_s(clientData, READ_BUF_SIZE, data, sizeof(data)); + (void)memcpy_s(serverData, READ_BUF_SIZE, appData, sizeof(appData)); + } else { + /* 2. Establish a connection. After the connection is established, construct an APPdata message with zero length + * and send it to the client. Then, send an APPdata message with data to the client. */ + (void)memcpy_s(clientData, READ_BUF_SIZE, appData, sizeof(appData)); + (void)memcpy_s(serverData, READ_BUF_SIZE, data, sizeof(data)); + } + size_t serverDataSize = strlen((char *)serverData) + 1; + size_t clientDataSize = strlen((char *)clientData) + 1; + + ASSERT_EQ(HITLS_Write(server->ssl, serverData, serverDataSize), HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_SUCCESS); + ASSERT_TRUE(readLen == serverDataSize && memcmp(serverData, readBuf, readLen) == 0); + + ASSERT_EQ(HITLS_Write(client->ssl, clientData, clientDataSize), HITLS_SUCCESS); + memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE); + readLen = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_SUCCESS); + ASSERT_TRUE(readLen == clientDataSize && memcmp(clientData, readBuf, readLen) == 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_INCORRECT_LENGTH_CHMSG_FUNC_TC001 + * @spec + * 1. If the server receives a ClientHello whose length exceeds the length of the entire packet, the server sends a + * decode_error alarm and the handshake fails. + * @brief Peers which receive a message which cannot be parsed according to the syntax (e.g., + * have a length extending beyond the message boundary or contain an out-of-range length) + * MUST terminate the connection with a "decode_error" alert. + * 6. Alert Protocol row 209 + * @expect + * 1.The server sends a ALERT_DECODE_ERROR and the handshake fails. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_INCORRECT_LENGTH_CHMSG_FUNC_TC001(void) +{ + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportClientVerify = true; + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->extensionLen.state = ASSIGNED_FIELD; + clientMsg->extensionLen.data = clientMsg->extensionLen.data + 1; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info alert = {0}; + ALERT_GetInfo(server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_DECODE_ERROR); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC001 + * @spec + * Establish a connection between the client and server, and then close the connection on the client. Check whether + * the message sent by the client is a close_notify message. + * @brief The "close_notify" alert is used to indicate orderly closure of one direction of the connection. Upon + * receiving such an alert, the TLS implementation SHOULD indicate end-of-data to the application. + * 6.0.0. Alert Protocol row 205 + * @expect + * 1.The client sends a ALERT_CLOSE_NOTIFY message. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->recMsg.msg; + uint32_t serverreadLen = serverioUserData->recMsg.len; + uint32_t serverparseLen = 0; + ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC003 + * @spec + * Establish a connection between the client and server, and then close the connection on the server. Obtain the + * message sent by the server and check whether the message is close_notify. + * @brief The "close_notify" alert is used to indicate orderly closure of one direction of the connection. Upon + * receiving such an alert, the TLS implementation SHOULD indicate end-of-data to the application. + * 6.0.0. Alert Protocol row 205 + * @expect + * 1.The server sends a ALERT_CLOSE_NOTIFY message. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC003(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(server, client, false, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->sndMsg.msg; + uint32_t serverreadLen = serverioUserData->sndMsg.len; + uint32_t serverparseLen = 0; + int32_t ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->recMsg.msg; + uint32_t clientreadLen = clientioUserData->recMsg.len; + uint32_t clientparseLen = 0; + ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_WRITE_FUNC_TC001 + * @spec + * After the client sends the close_notify message, the client fails to invoke the write interface. + * @brief Either party MAY initiate a close of its write side of the connection by sending a "close_notify" alert. Any + * data received after a closure alert has been received MUST be ignored. + * 6.1.0. Alert Protocol row 213 + * @expect + * 1.The client fails to invoke the write interface and send HITLS_CM_LINK_CLOSED + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_WRITE_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + uint8_t data[] = "Hello World"; + + ASSERT_EQ(HITLS_Write(client->ssl, data, sizeof(data)), HITLS_CM_LINK_CLOSED); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CLOSE_NOTIFY_WRITE_FUNC_TC001 + * @spec + * After the server sends the close_notify message, the write interface fails to be invoked. + * @brief Either party MAY initiate a close of its write side of the connection by sending a "close_notify" alert. Any + * data received after a closure alert has been received MUST be ignored. + * 6.1.0. Alert Protocol row 213 + * @expect + * 1.The server fails to invoke the write interface and send HITLS_CM_LINK_CLOSED + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CLOSE_NOTIFY_WRITE_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(server, client, false, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->sndMsg.msg; + uint32_t serverreadLen = serverioUserData->sndMsg.len; + uint32_t serverparseLen = 0; + int32_t ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + uint8_t data[] = "Hello World"; + + ASSERT_EQ(HITLS_Write(server->ssl, data, sizeof(data)), HITLS_CM_LINK_CLOSED); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RECV_CLOSE_NOTIFY_CLIENTHELLO_FUNC_TC001 + * @spec + * The connection is established normally. After receiving the close_notify message, the server receives the clienthello + * message. The message is ignored and the connection is interrupted. + * @brief close_notify: This alert notifies the recipient that the sender will not send any more messages on this + * connection. Any data received after a closure alert has been received MUST be ignored. + * 6.1.0. Alert Protocol row 211 + * @expect + * 1.The connection is interrupted and return HITLS_CM_LINK_FATAL_ALERTED + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RECV_CLOSE_NOTIFY_CLIENTHELLO_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + FrameUioUserData *clientioUserData = BSL_UIO_GetUserData(client->io); + FRAME_Msg clientframeMsg = {0}; + uint8_t *clientbuffer = clientioUserData->sndMsg.msg; + uint32_t clientreadLen = clientioUserData->sndMsg.len; + uint32_t clientparseLen = 0; + int32_t ret = ParserTotalRecord(client, &clientframeMsg, clientbuffer, clientreadLen, &clientparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(clientframeMsg.type == REC_TYPE_ALERT && clientframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(clientframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + clientframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + FrameUioUserData *serverioUserData = BSL_UIO_GetUserData(server->io); + FRAME_Msg serverframeMsg = {0}; + uint8_t *serverbuffer = serverioUserData->recMsg.msg; + uint32_t serverreadLen = serverioUserData->recMsg.len; + uint32_t serverparseLen = 0; + ret = ParserTotalRecord(server, &serverframeMsg, serverbuffer, serverreadLen, &serverparseLen); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(serverframeMsg.type == REC_TYPE_ALERT && serverframeMsg.bodyLen == ALERT_BODY_LEN); + ASSERT_TRUE(serverframeMsg.body.alertMsg.level == ALERT_LEVEL_WARNING && + serverframeMsg.body.alertMsg.description == ALERT_CLOSE_NOTIFY); + + ASSERT_TRUE(server->ssl != NULL); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_IO_BUSY); + serverioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_CM_LINK_FATAL_ALERTED); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + serverioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_CM_LINK_FATAL_ALERTED); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_HRR_FUNC_TC001 + * @spec + * The connection is established normally. After the client receives the close_notify message and the + * helloRetryRequest message, the client ignores the message and disconnects from the connection. + * @brief close_notify: This alert notifies the recipient that the sender will not send any more messages on this + * connection. Any data received after a closure alert has been received MUST be ignored. + * 6.1.0. Alert Protocol row 211 + * @expect + * 1.The connection is interrupted and return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_HRR_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + HITLS_CFG_SetGroups(config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_LEVEL_WARNING, &frameMsg.body.alertMsg.alertLevel) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_CLOSE_NOTIFY, &frameMsg.body.alertMsg.alertDescription) == HITLS_SUCCESS); + uint8_t alertBuf[MAX_RECORD_LENTH] = {0}; + uint32_t alertLen = MAX_RECORD_LENTH; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, alertBuf, alertLen, &alertLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, alertBuf, alertLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_NE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_APP_FUNC_TC001 + * @spec + * The connection is established normally. After the client receives the close_notify message and the app message, the + * client ignores the message and disconnects the connection. + * @brief close_notify: This alert notifies the recipient that the sender will not send any more messages on this + * connection. Any data received after a closure alert has been received MUST be ignored. + * 6.1.0. Alert Protocol row 211 + * @expect + * 1.The connection is interrupted and return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_APP_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_LEVEL_WARNING, &frameMsg.body.alertMsg.alertLevel) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_CLOSE_NOTIFY, &frameMsg.body.alertMsg.alertDescription) == HITLS_SUCCESS); + uint8_t alertBuf[MAX_RECORD_LENTH] = {0}; + uint32_t alertLen = MAX_RECORD_LENTH; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, alertBuf, alertLen, &alertLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, alertBuf, alertLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_NE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC001 + * @spec + * When the connection is established, the server sends some error alarms and closes the write end of the connection. + * The close_notify message is not sent. + * @brief Each party MUST send a "close_notify" alert before closing its write side of the connection, unless it has + * already sent some error alert. This does not have any effect on its read side of the connection. + * 6.1.0. Alert Protocol row 214 + * @expect + * 1.The close_notify message is not sent. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + /* The client invokes the HITLS_Connect, + and the handshake process is not complete.Check the status of the security connection.The status is + CM_STATE_CALL. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_LEVEL_FATAL, &frameMsg.body.alertMsg.alertLevel) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_DECODE_ERROR, &frameMsg.body.alertMsg.alertDescription) == HITLS_SUCCESS); + uint8_t alertBuf[MAX_RECORD_LENTH] = {0}; + uint32_t alertLen = MAX_RECORD_LENTH; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, alertBuf, alertLen, &alertLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, alertBuf, alertLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + ALERT_Info alert = {0}; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_NE(alert.level, ALERT_LEVEL_WARNING); + ASSERT_NE(alert.description, ALERT_CLOSE_NOTIFY); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC002 + * @spec + * If the connection is established normally, the client sends some error alarms and closes the write end of the + * connection. The close_notify message is not sent. + * @brief Each party MUST send a "close_notify" alert before closing its write side of the connection, unless it has + * already sent some error alert. This does not have any effect on its read side of the connection. + * 6.1.0. Alert Protocol row 214 + * @expect + * 1.The close_notify message is not sent. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_LEVEL_FATAL, &frameMsg.body.alertMsg.alertLevel) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_ModifyMsgInteger(ALERT_DECODE_ERROR, &frameMsg.body.alertMsg.alertDescription) == HITLS_SUCCESS); + uint8_t alertBuf[MAX_RECORD_LENTH] = {0}; + uint32_t alertLen = MAX_RECORD_LENTH; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, alertBuf, alertLen, &alertLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, alertBuf, alertLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + ALERT_Info alert = {0}; + ALERT_GetInfo(server->ssl, &alert); + ASSERT_NE(alert.level, ALERT_LEVEL_WARNING); + ASSERT_NE(alert.description, ALERT_CLOSE_NOTIFY); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC003 + * @spec + * A connection is set up and the client is disconnected. Before the client receives a response, the client fails to + * invoke the read interface. After receiving the close_notify message, the server suspends the write end and returns a + * close_notify message to close the read end. + * @brief Each party MUST send a "close_notify" alert before closing its write side of the connection, unless it has + * already sent some error alert. This does not have any effect on its read side of the connection. + * 6.1.0. Alert Protocol row 214 + * @expect + * @expect The server receives the close_notify message and responds to the close_notify message. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC003(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Close(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_CLOSED); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_CM_LINK_FATAL_ALERTED); + ASSERT_EQ(server->ssl->shutdownState, HITLS_SENT_SHUTDOWN | HITLS_RECEIVED_SHUTDOWN); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC004 + * @spec + * A connection is set up and the server is disconnected. Before receiving a response, the server fails to invoke the + * read interface. After receiving the close_notify message, the client suspends the write end and responds with the + * close_notify message to close the read end. + * @brief Each party MUST send a "close_notify" alert before closing its write side of the connection, unless it has + * already sent some error alert. This does not have any effect on its read side of the connection. + * 6.1.0. Alert Protocol row 214 + * @expect The client receives the close_notify message and responds to the close_notify message. + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC004(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Close(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_CLOSED); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_CM_LINK_FATAL_ALERTED); + ASSERT_EQ(client->ssl->shutdownState, HITLS_SENT_SHUTDOWN | HITLS_RECEIVED_SHUTDOWN); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +int32_t DefaultCfgStatusParkWithSuite_1_3(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + testInfo->config = HITLS_CFG_NewTLS13Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(testInfo->config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + return StatusPark(testInfo); +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC001 +* @spec - +* @title During connection establishment, the server receives a message of the undefined record type after sending the +finished message. In this case, an alert message is returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable the peer end verification function on +* the server. Expected result 1 is obtained. +* 2. When the client initiates a TLS connection request in the RECV_Client_Hello message, construct an APP +message +* and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC001() +{ + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + /* 1. Use the default configuration on the client and server, and disable the peer end verification function on + * the server. */ + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(testInfo.server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_RECV_FINISH), HITLS_SUCCESS); + /* 2. When the client initiates a TLS connection request in the RECV_Client_Hello message, construct an APP message + * and send it to the client. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0xff, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ( + memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(testInfo.server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC002 +* @spec - +* @title After the connection is established, renegotiation is not enabled. The server receives the client hello message +and +* is expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable the peer end check function on the +* server. Expected result 1 is obtained. +* 2. After the connection is set up, do not enable renegotiation and the server receives the client hello +message. +* Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC002() +{ + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + /* 1. Use the default configuration on the client and server, and disable the peer end check function on the + * server. */ + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_RECV_CLIENT_HELLO), HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, + MAX_RECORD_LENTH, + ioUserData->recMsg.msg + REC_TLS_RECORD_HEADER_LEN, + ioUserData->recMsg.len - REC_TLS_RECORD_HEADER_LEN) == EOK); + sndMsg.len = ioUserData->recMsg.len - REC_TLS_RECORD_HEADER_LEN; + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + REC_Write(testInfo.client->ssl, REC_TYPE_HANDSHAKE, sndMsg.msg, sndMsg.len); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.client, testInfo.server), HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + /* 2. After the connection is set up, do not enable renegotiation and the server receives the client hello message. + */ + ASSERT_EQ(HITLS_Read(testInfo.server->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC003 +* @spec - +* @title After initialization is complete, construct an app message and send it to the server. The expected alert is +* returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable the peer end verification function on +* the server. Expected result 1 is obtained. +* 2. When the client initiates a TLS connection application request, construct an APP message and send it to +the +* server in the RECV_CLIENT_HELLO message on the server. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The server sends the ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC003(void) +{ + FRAME_Msg parsedAlert = {0}; + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = false; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportClientVerify = false; + /* 1. Use the default configuration on the client and server, and disable the peer end verification function on + * the server. */ + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == 0); + /* 2. When the client initiates a TLS connection application request, construct an APP message and send it to the + * server in the RECV_CLIENT_HELLO message on the server. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ( + memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(sndBuf, sndLen, &parsedAlert, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(parsedAlert.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC004 +* @spec - +* @title After initialization, construct an app message and send it to the client. The expected alert is returned. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +* Expected result 1 is obtained. +* 2. When the client initiates a TLS connection application request in the RECV_SERVER_HELLO message, +construct an +* APP message and send it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC004(void) +{ + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + HandshakeTestInfo testInfo = {0}; + testInfo.isClient = true; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportClientVerify = false; + /* 1. Use the default configuration on the client and server, and disable peer verification on the server. */ + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == 0); + /* 2. When the client initiates a TLS connection application request in the RECV_SERVER_HELLO message, construct an + * APP message and send it to the client. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ( + memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_EQ(frameMsg.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_TRUE(alertMsg->alertDescription.data == ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC005 +* @spec - +* @title After the connection is established, the client receives the serverhello message when receiving the app +data. The +* client is expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +* Expected result 1 is obtained. +* 2. The client initiates a TLS connection request. After the handshake succeeds, the server constructs a +* serverhello message and sends it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC005() +{ + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + /* 1. Use the default configuration on the client and server, and disable peer verification on the server. */ + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + /* 2. The client initiates a TLS connection request. After the handshake succeeds, the server constructs a + * serverhello message and sends it to the client. */ + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, + MAX_RECORD_LENTH, + ioUserData->recMsg.msg + REC_TLS_RECORD_HEADER_LEN, + ioUserData->recMsg.len - REC_TLS_RECORD_HEADER_LEN) == EOK); + sndMsg.len = ioUserData->recMsg.len - REC_TLS_RECORD_HEADER_LEN; + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + REC_Write(testInfo.server->ssl, REC_TYPE_HANDSHAKE, sndMsg.msg, sndMsg.len); + // Inject packets to the client. + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(testInfo.server, testInfo.client), HITLS_SUCCESS); + /* The server invokes HITLS_Read to receive data. */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC006 +* @spec - +* @title After the connection is established, the client receives an unknown message when receiving app data and is +* expected to return an alert message. +* @precon nan +* @brief 1. Use the default configuration on the client and server, and disable peer verification on the server. +* Expected result 1 is displayed. +* 2. The client initiates a TLS connection request. After the handshake succeeds, the client constructs an +unknown +* message and sends it to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC006() +{ + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + /* 1. Use the default configuration on the client and server, and disable peer verification on the server. */ + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(testInfo.client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + /* 2. The client initiates a TLS connection request. After the handshake succeeds, the client constructs an unknown + * message and sends it to the client. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + uint8_t appdata[] = {0xff, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01}; + ASSERT_EQ(memcpy_s(data, len, appdata, sizeof(appdata)), EOK); + ASSERT_EQ( + memcpy_s(data + sizeof(appdata), len - sizeof(appdata), ioUserData->recMsg.msg, ioUserData->recMsg.len), EOK); + ASSERT_EQ(memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, data, ioUserData->recMsg.len + sizeof(appdata)), EOK); + ioUserData->recMsg.len += sizeof(appdata); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(testInfo.client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ +#define BUF_TOOLONG_LEN ((1 << 14) + 1) + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC003 +* @spec - +* @title The client sends a Change Cipher Spec message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the client initiates a DTLS connection establishment request and sends a Change Cipher Spec message, +the +* client modifies one field as follows: Length is 2 ^ 14 + 1. After the modification is complete, send the +* modification to the server. Expected result 2 is obtained. +* 3. When the server receives the Change Cipher Spec message, check the value returned by the HITLS_Accept +* interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +* 3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC003(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_FINISH; + testInfo.isClient = false; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + /* 1. Use the default configuration items to configure the client and server. */ + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == HITLS_SUCCESS); + + ASSERT_EQ( + FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, TRY_RECV_FINISH), HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + /* 2. When the client initiates a DTLS connection establishment request and sends a Change Cipher Spec message, the + * client modifies one field as follows: Length is 2 ^ 14 + 1. After the modification is complete, send the + * modification to the server. */ + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.ccsMsg.extra.data); + frameMsg.body.ccsMsg.extra.data = certDataTemp; + frameMsg.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg.body.ccsMsg.extra.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.server->ssl != NULL); + /* 3. When the server receives the Change Cipher Spec message, check the value returned by the HITLS_Accept + * interface. */ + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_FINISH); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC004 +* @spec - +* @title The client sends a Change Cipher Spec message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and client. Expected result 1 is obtained. +* 2. When the client initiates a DTLS connection establishment request and sends a Change Cipher Spec message, +the client modifies one field as follows: Length is 2 ^ 14 + 1. After the modification is complete, send the + modification to the client. Expected result 2 is obtained. + 3. When the client receives the Change Cipher Spec message, check the value returned by the HITLS_Accept + interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. + 3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC004(void) +{ + HandshakeTestInfo testInfo = {0}; + testInfo.state = TRY_RECV_FINISH; + testInfo.isClient = true; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isSupportClientVerify = true; + /* 1. Use the default configuration items to configure the client and server. */ + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == HITLS_SUCCESS); + + ASSERT_EQ( + FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, TRY_RECV_FINISH), HITLS_SUCCESS); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + /* 2. When the client initiates a DTLS connection establishment request and sends a Change Cipher Spec message, the + * client modifies one field as follows: Length is 2 ^ 14 + 1. After the modification is complete, send the + * modification to the server. */ + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.ccsMsg.extra.data); + frameMsg.body.ccsMsg.extra.data = certDataTemp; + frameMsg.body.ccsMsg.extra.size = BUF_TOOLONG_LEN; + frameMsg.body.ccsMsg.extra.state = ASSIGNED_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + /* 3. When the client receives the Change Cipher Spec message, check the value returned by the HITLS_Accept + * interface. */ + ASSERT_EQ(HITLS_Accept(testInfo.client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_TRUE(testInfo.client->ssl->hsCtx->state == TRY_RECV_FINISH); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC001 +* @spec - +* @titleThe client sends a clienthello message with the length of 2 ^ 14 + 1 byte. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. When the client initiates a DTLS connection creation request, the client needs to send a client hello +message, +* modify the following field as follows: Length is 2 ^ 14 + 1. After the modification, the modification is +* sent to the server. Expected result 2 is obtained. +* 3. When the server receives the client hello message, check the value returned by the HITLS_Accept +* interface. Expected result 3 is obtained. +* @expect 1. The initialization is successful. +* 2. The field is successfully modified and sent to the client. +* 3. The return value of the HITLS_Accept interface is HITLS_REC_NORMAL_RECV_BUF_EMPTY. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + /* 1. Use the default configuration items to configure the client and server. */ + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + /* 2. When the client initiates a DTLS connection creation request, the client needs to send a client hello message, + * modify the following field as follows: Length is 2 ^ 14 + 1. After the modification, the modification is + * sent to the server. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.sessionId.data); + clientMsg->sessionId.state = ASSIGNED_FIELD; + clientMsg->sessionId.size = BUF_TOOLONG_LEN; + clientMsg->sessionId.data = certDataTemp; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + /* 3. When the server receives the client hello message, check the value returned by the HITLS_Accept + * interface. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_REC_RECORD_OVERFLOW); + + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_RECORD_OVERFLOW); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC002 +* @spec - +* @title Verify that the client receives a serverhello message with the length of 2 ^ 14 + 1. The client is expected to +* return an alert message. +* @precon nan +* @brief 1. Create a config and server connection, and construct a server hello message with the length of 2 ^ 14 ++ 1. +* Expected result 1 is obtained. +* 2. The client invokes the HITLS_Connect interface. (Expected result 2) +* @expect 1. A success message is returned. +* 2. A failure message is returned. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + uint32_t parseLen = 0; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + /* 1. Create a config and server connection, and construct a server hello message with the length of 2 ^ 14 + 1. */ + uint8_t *certDataTemp = (uint8_t *)BSL_SAL_Calloc(1, (uint32_t)BUF_TOOLONG_LEN); + ASSERT_TRUE(certDataTemp != NULL); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.serverHello.randomValue.data); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + + serverMsg->randomValue.state = ASSIGNED_FIELD; + serverMsg->randomValue.size = BUF_TOOLONG_LEN; + serverMsg->randomValue.data = certDataTemp; + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + ASSERT_TRUE(testInfo.client->ssl != NULL); + /* 2. The client invokes the HITLS_Connect interface. */ + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_RECORD_OVERFLOW); + + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_RECORD_OVERFLOW); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +int32_t STUB_HS_DoHandshake_Fatal(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t plainLen) +{ + (void)recordType; + (void)data; + (void)plainLen; + ctx->method.sendAlert(ctx, ALERT_LEVEL_WARNING, ALERT_UNEXPECTED_MESSAGE); /* sends a fatal alert message.*/ + return HITLS_INTERNAL_EXCEPTION; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC001 +* @spec All the alerts listed in Section 6.2 MUST be sent with AlertLevel=fatal and MUST be treated as error alerts +* when received regardless of the AlertLevel in the message. +* Unknown Alert types MUST be treated as error alerts. +* @title If the AlertLevel field in the alarm message received by the client is non-critical but the alarm type is +* critical, the client immediately closes the connection. +* @precon nan +* @brief 6. Alert Protocol row208 +* If the AlertLevel field in the alarm message received by the client is not critical but the alarm type is +* critical, the connection is closed immediately. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC001() +{ + FRAME_Init(); + STUB_Init(); + FuncStubInfo tmpRpInfo = {0}; + HITLS_Config *tlsConfig = HITLS_CFG_NewTLSConfig(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig, 0x00000030U); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + server->ssl->recCtx->outBuf->end = 0; + STUB_Replace(&tmpRpInfo, HS_DoHandshake, STUB_HS_DoHandshake_Fatal); + int32_t ret = HITLS_Accept(server->ssl); + ASSERT_EQ(ret, HITLS_REC_NORMAL_IO_BUSY); + STUB_Reset(&tmpRpInfo); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC002 +* All alerts listed in section 6.2 of the specification must be sent with AlertLevel=Fatal and must be treated as +* false alerts When received regardless of the AlertLevel in the message. +* Unknown alert types must be treated as false alerts. +* @title In the alarm message received by the server, if the value of AlertLevel is not critical but the alarm type is +* critical, the connection is closed immediately. +* @preconan +* @short 6. Alert protocol line 208 +* In the alarm message received by the server, if the value of AlertLevel is not critical but the alarm type +* is critical, the connection is closed immediately. +* @expect forward to normal connection establishment +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC002() +{ + FRAME_Init(); + STUB_Init(); + FuncStubInfo tmpRpInfo = {0}; + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLSConfig(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig, 0x00000030U); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + client->ssl->recCtx->outBuf->end = 0; + STUB_Replace(&tmpRpInfo, HS_DoHandshake, STUB_HS_DoHandshake_Fatal); + int32_t ret = HITLS_Connect(client->ssl); + ASSERT_EQ(ret, HITLS_REC_NORMAL_IO_BUSY); + STUB_Reset(&tmpRpInfo); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERROR_ENUM_FUNC_TC001 +* @spec Peers which receive a message which is syntactically correct but semantically invalid +* (e.g., a DHE share of p - 1, or an invalid enum) MUST terminate the connection with +* an "illegal_parameter" alert. +* @title When the client receives a server keyexchange message in which the value of type is invalid, the client +* generates an illegal_parameter alarm and the handshake fails. +* @precon nan +* @brief 6. Alert Protocol row210 +* When the client receives a server keyexchange message in which the value of type is invalid, the client +* generates an illegal_parameter alarm and the handshake fails. +* @expect Sending an alarm +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERROR_ENUM_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + tlsConfig->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_KEY_EXCHANGE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, SERVER_KEY_EXCHANGE, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + sendBuf[9] = 0x04; + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Accept(clientTlsCtx), HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE); + ALERT_Info alert = {0}; + ALERT_GetInfo(server->ssl, &alert); + ASSERT_NE(alert.level, ALERT_LEVEL_FATAL); + ASSERT_NE(alert.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC001 +* @spec - +* @title To verify that the server receives a 0-length client hello and is expected to return an alarm. +* @precon nan +* @brief 1.Create a config and client connection, and construct a 0-length client hello. Expected result 1 is +displayed. +* 2.The client invokes the HITLS_Connect interface. Expected result 2 is obtained. +* @expect 1. Return success +* 2.Return failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_CLIENT_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = false; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == HITLS_SUCCESS); + + /* Obtain the message buffer */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + recvBuf[6] = 00; + recvBuf[7] = 00; + recvBuf[8] = 00; + recvLen = 6; + + /* Invoke the test interface. Expected success in receiving and processing, and send Alert. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + /* Obtain the message buffer. */ + ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + /* Parse to msg structure */ + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Determine whether it is consistent with the expectation. */ + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC002 +* @spec - +* @title To verify that the client receives a 0-length server hello and returns an alert message. +* @precon nan +* @brief 1.Create a config and server connection, and construct a 0-length server hello. Expected result 1 is +displayed. 2.The client invokes the HITLS_Connect interface. Expected result 2 is obtained. +* @expect 1.Return success + 2.Return failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC002(void) +{ + HandshakeTestInfo testInfo = {0}; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + testInfo.state = TRY_RECV_SERVER_HELLO; + testInfo.isSupportExtendMasterSecret = true; + testInfo.isClient = true; + ASSERT_TRUE(DefaultCfgStatusParkWithSuite_1_3(&testInfo) == HITLS_SUCCESS); + + /* Obtain the message buffer. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + recvBuf[6] = 00; + recvBuf[7] = 00; + recvBuf[8] = 00; + recvLen = 6; + + /* Invoke the test interface. Expected success in receiving and processing, and send Alert. */ + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_PARSE_INVALID_MSG_LEN); + + /* Obtain the message buffer. */ + ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + /* Parse to msg structure */ + uint32_t parseLen = 0; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Determine whether it is consistent with the expectation. */ + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_DECODE_ERROR); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_1.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_1.data new file mode 100644 index 00000000..79a9394f --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_1.data @@ -0,0 +1,192 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_APP_DATA_BEFORE_FINISH_FUNC_TC001 isClient +UT_TLS_TLS13_RFC8446_CONSISTENCY_APP_DATA_BEFORE_FINISH_FUNC_TC001: 1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_APP_DATA_BEFORE_FINISH_FUNC_TC001 isServer +UT_TLS_TLS13_RFC8446_CONSISTENCY_APP_DATA_BEFORE_FINISH_FUNC_TC001: 0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_SUPPORTED_GROUP_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_SUPPORTED_GROUP_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_PSS_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001 RSA_PKCS1_SHA1 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001:CERT_SIG_SCHEME_RSA_PKCS1_SHA1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001 ECDSA_SHA1 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001:CERT_SIG_SCHEME_ECDSA_SHA1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001 DSA_SHA224 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIG_FUNC_TC001:CERT_SIG_SCHEME_DSA_SHA224 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_SUPPORT_BY_TLS12SERVER_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSAE_SUPPORT_BY_TLS12SERVER_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_SESSID_FROM_SH_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CIPHERSUITE_FROM_SH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CIPHERSUITE_FROM_SH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISSING_SIG_ALG_FROM_CH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISSING_SIG_ALG_FROM_CH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CERT_VERIFY_FUNC_TC001 isClient +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CERT_VERIFY_FUNC_TC001: 1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CERT_VERIFY_FUNC_TC001 isServer +UT_TLS_TLS13_RFC8446_CONSISTENCY_MODIFIED_CERT_VERIFY_FUNC_TC001: 0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMPTION_FUNC_TC001 For binder test +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMPTION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FUNC_TC001 For binder test +UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PREFER_PSS_TO_PKCS1_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PREFER_PSS_TO_PKCS1_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_BEFORE_FINISH_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_INVALID_REQ_VAL_FUNC_TC001 isClient +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_INVALID_REQ_VAL_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_INVALID_REQ_VAL_FUNC_TC001 isServer +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_INVALID_REQ_VAL_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYUPDATE_WITH_NO_REPLY_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_READ_WRITE_AFTER_FATAL_ALEART_FUNC_TC001 isClient +UT_TLS_TLS13_RFC8446_CONSISTENCY_READ_WRITE_AFTER_FATAL_ALEART_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_READ_WRITE_AFTER_FATAL_ALEART_FUNC_TC001 isServer +UT_TLS_TLS13_RFC8446_CONSISTENCY_READ_WRITE_AFTER_FATAL_ALEART_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVAPP_AFTER_CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVAPP_AFTER_CERT_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVAPP_AFTER_CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVAPP_AFTER_CERT_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ZERO_APPMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ZERO_APPMSG_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ZERO_APPMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ZERO_APPMSG_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_INCORRECT_LENGTH_CHMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_INCORRECT_LENGTH_CHMSG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLOSE_NOTIFY_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_WRITE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_WRITE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CLOSE_NOTIFY_WRITE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CLOSE_NOTIFY_WRITE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RECV_CLOSE_NOTIFY_CLIENTHELLO_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RECV_CLOSE_NOTIFY_CLIENTHELLO_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_HRR_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_HRR_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_APP_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_APP_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CLOSE_NOTIFY_READ_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECT_RECODETYPE_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MSGLENGTH_TOOLONG_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_DESCRIPTION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERROR_ENUM_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERROR_ENUM_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC002: + diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_2.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_2.c new file mode 100644 index 00000000..4ceb5b58 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_2.c @@ -0,0 +1,3002 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hlt.h" +#include "hlt_type.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "process.h" +#include "securec.h" +#include "session_type.h" +#include "rec_wrapper.h" +#include "common_func.h" +#include "conn_init.h" +#include "hs_extensions.h" +#include "hitls_crypt_init.h" +#include "alert.h" +/* END_HEADER */ + +#define PORT 23456 +#define READ_BUF_SIZE (18 * 1024) + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; // Set the session to the client for session recovery. + HITLS_TicketKeyCb serverKeyCb; +} ResumeTestInfo; + +typedef struct{ + char *ClientCipherSuite; + char *ServerCipherSuite; + char *ClientGroup; + char *ServerGroup; + uint8_t ClientKeyExchangeMode; + uint8_t ServerKeyExchangeMode; + uint8_t psk[PSK_MAX_LEN]; + bool SetNothing; + bool SuccessOrFail; +} SetInfo; + +void SetConfig(HLT_Ctx_Config *clientconfig, HLT_Ctx_Config *serverconfig, SetInfo setInfo) +{ + if ( !setInfo.SetNothing ) { + + // Configure the server configuration. + if (setInfo.ServerCipherSuite != NULL) { + HLT_SetCipherSuites(serverconfig, setInfo.ServerCipherSuite); + } + if (setInfo.ServerGroup != NULL) { + HLT_SetGroups(serverconfig, setInfo.ServerGroup); + } + memcpy_s(serverconfig->psk, PSK_MAX_LEN, setInfo.psk, sizeof(setInfo.psk)); + + if ( (setInfo.ClientKeyExchangeMode & (TLS13_KE_MODE_PSK_WITH_DHE | TLS13_KE_MODE_PSK_ONLY)) != 0) { + clientconfig->keyExchMode = setInfo.ClientKeyExchangeMode; + } + + // Configure the client configuration. + if (setInfo.ClientCipherSuite != NULL) { + HLT_SetCipherSuites(clientconfig, setInfo.ClientCipherSuite); + } + if (setInfo.ClientGroup != NULL) { + HLT_SetGroups(clientconfig, setInfo.ClientGroup); + } + memcpy_s(clientconfig->psk, PSK_MAX_LEN, setInfo.psk, sizeof(setInfo.psk)); + if ( (setInfo.ServerKeyExchangeMode & (TLS13_KE_MODE_PSK_WITH_DHE | TLS13_KE_MODE_PSK_ONLY)) != 0) { + serverconfig->keyExchMode = setInfo.ServerKeyExchangeMode; + } + } +} +static int32_t DoHandshake(ResumeTestInfo *testInfo) +{ + /* Construct a connection. */ + testInfo->client = FRAME_CreateLink(testInfo->c_config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->clientSession != NULL) { + int32_t ret = HITLS_SetSession(testInfo->client->ssl, testInfo->clientSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + testInfo->server = FRAME_CreateLink(testInfo->s_config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + return FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); +} + +void ClientCreatConnectWithPara(HLT_FrameHandle *handle, SetInfo setInfo) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + // Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // The local client and remote server listen on the TLS connection. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the config file. + SetConfig(clientConfig, serverConfig, setInfo); + + // Listening connection. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + // Configure the interface for constructing abnormal messages. + handle->ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + // Establish a connection. + if ( setInfo.SuccessOrFail ) { + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) == 0); + }else { + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + } + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ServerCreatConnectWithPara(HLT_FrameHandle *handle, SetInfo setInfo) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + // Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // The local client and remote server listen on the TLS connection. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the config file. + SetConfig(clientConfig, serverConfig, setInfo); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // Insert abnormal message callback. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + // Client listening connection. + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientConfig, NULL); + + if ( setInfo.SuccessOrFail ) { + ASSERT_TRUE(clientRes != NULL); + }else { + ASSERT_TRUE(clientRes == NULL); + } + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ResumeConnectWithPara(HLT_FrameHandle *handle, SetInfo setInfo) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for the config context. + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, TLS1_3, false); + void *clientConfig = HLT_TlsNewCtx(TLS1_3); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the session restoration function. + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (cnt == 2) { + SetConfig(clientCtxConfig, serverCtxConfig, setInfo); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = TCP; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = TCP; + localProcess->connType = TCP; + + // The server applies for the context. + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = TCP; + // Set the FD. + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + // Client, applying for context + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = TCP; + + // Set the FD. + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + handle->ctx = clientSsl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + + if(!setInfo.SuccessOrFail){ + ASSERT_TRUE(HLT_TlsConnect(clientSsl) != 0); + }else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } + } + else { + // Negotiation + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + // Data read/write + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + // Disable the connection. + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_HasTicket(session) == true); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + }cnt++; + } while (cnt < 3); // Perform the connection twice. + +exit: + HITLS_SESS_Free(session); + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +static void Test_ServerAddKeyExchangeMode(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + // Add the KeyExchangeMode extension to server hello. + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + uint8_t pskMode[] = {0, 0x2d, 0, 2, 1, 1}; + frameMsg.body.hsMsg.length.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.length.data += sizeof(pskMode); + frameMsg.body.hsMsg.body.serverHello.extensionLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.serverHello.extensionLen.data = frameMsg.body.hsMsg.body.serverHello.extensionLen.data + sizeof(pskMode); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + + ASSERT_EQ(memcpy_s(&data[*len], bufSize - *len, &pskMode, sizeof(pskMode)), EOK); + *len += sizeof(pskMode); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Server_KeyShare_Miss(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + // The keyshare extension of server hello is lost. + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + frameMsg.body.hsMsg.body.serverHello.keyShare.exState = MISSING_FIELD; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Client_MasterSecret_Miss(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + // The MasterSecret extension of client hello is lost. + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.extendedMasterSecret.exState = MISSING_FIELD; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Client_ObfuscatedTicketAge_NotZero(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + // The value of ObfuscatedTicketAge is not 0 for the external preset PSK. + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.psks.identities.data->obfuscatedTicketAge.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.psks.identities.data->obfuscatedTicketAge.data = 2; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Client_ObfuscatedTicketAge_Zero(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + // The value of ObfuscatedTicketAge is 0 for the PSK generated by the session. + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.psks.identities.data->obfuscatedTicketAge.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.psks.identities.data->obfuscatedTicketAge.data = 0; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Client_Binder_Unnormal(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + // Change the binder value of the psk extension of the client hello message. + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + uint8_t binder[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,}; + frameMsg.body.hsMsg.body.clientHello.psks.binders.data->binder.state = ASSIGNED_FIELD; + memcpy_s(frameMsg.body.hsMsg.body.clientHello.psks.binders.data->binder.data, PSK_MAX_LEN, binder, sizeof(binder)); + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void FrameCallBack_ServerHello_KeyShare_Add(void *msg, void *userData) +{ + // ServerHello exception: The sent ServerHello message carries the keyshare extension. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverhello = &frameMsg->body.hsMsg.body.serverHello; + + serverhello->keyShare.exState = INITIAL_FIELD; + serverhello->keyShare.exLen.state = INITIAL_FIELD; + serverhello->keyShare.data.state = INITIAL_FIELD; + serverhello->keyShare.data.group.state = ASSIGNED_FIELD; + serverhello->keyShare.data.group.data = HITLS_EC_GROUP_SECP256R1; + + FRAME_ModifyMsgInteger(HS_EX_TYPE_KEY_SHARE, &serverhello->keyShare.exType); + uint8_t uu[] = {0x00, 0x15, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56}; + FRAME_ModifyMsgArray8(uu, sizeof(uu), &serverhello->keyShare.data.keyExchange, &serverhello->keyShare.data.keyExchangeLen); + +exit: + return; +} + +static void FrameCallBack_ClientHello_PskExchangeMode_Miss(void *msg, void *userData) +{ + // ClientHello exception: The sent ClientHello message causes the Psk_Exchange_Mode extension to be lost. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clienthello = &frameMsg->body.hsMsg.body.clientHello; + + clienthello->pskModes.exState = MISSING_FIELD; +exit: + return; +} + +static void FrameCallBack_ClientHello_KeyShare_Miss(void *msg, void *userData) +{ + // ClientHello exception: The KeyShare extension of the ClientHello message is lost. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clienthello = &frameMsg->body.hsMsg.body.clientHello; + + clienthello->keyshares.exState = MISSING_FIELD; +exit: + return; +} + +/** @ +* @test UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC001 +* @brief 2.1-Incorrect DHE Share-6 +* @spec If no common cryptographic parameters can be negotiated, the server MUST abort the handshake with an +* appropriate alert. +* @title The server sends an hrr message to request the key_share. The negotiation succeeds. +* @precon nan +* @brief +* 1. Set the group (HITLS_EC_GROUP_SECP256R1 and HITLS_EC_GROUP_SECP384R1) on the client and set the group +* (HITLS_EC_GROUP_SECP384R1) on the server. Expected result 1 is obtained. +* 2. Establish a connection, stop the server in the TRY_SEND_HELLO_RETRY_REQUEST state, and check whether the value of +* the group field is HITLS_EC_GROUP_SECP384R1. (Expected result 2) +* 3. Continue to establish the connection. Expected result 3 is obtained. +* @expect +* 1. The setting is successful. +* 2. The value of the group field is HITLS_EC_GROUP_SECP384R1. +* 3. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ + +void UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC001() +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *clientconfig = NULL; + HITLS_Config *serverconfig = NULL; + clientconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(clientconfig != NULL); + serverconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(serverconfig != NULL); + + // Set the group (HITLS_EC_GROUP_SECP256R1 and HITLS_EC_GROUP_SECP384R1) on the client and set the group + // (HITLS_EC_GROUP_SECP384R1) on the server. + uint16_t clientgroups[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t servergroups[] = {HITLS_EC_GROUP_SECP384R1}; + ASSERT_EQ(HITLS_CFG_SetGroups(clientconfig, clientgroups, sizeof(clientgroups) / sizeof(uint16_t)), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetGroups(serverconfig, servergroups, sizeof(servergroups) / sizeof(uint16_t)), HITLS_SUCCESS); + + client = FRAME_CreateLink(clientconfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(serverconfig, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_IO_BUSY); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + // Establish a connection, stop the server in the TRY_SEND_HELLO_RETRY_REQUEST state, and check whether the value of + // the group field is HITLS_EC_GROUP_SECP384R1. + FRAME_ServerHelloMsg *Hello_Retry_RequestMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(Hello_Retry_RequestMsg->keyShare.data.group.data == HITLS_EC_GROUP_SECP384R1); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_SEND_CLIENT_HELLO), HITLS_SUCCESS); + + // Continue to establish the connection. + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(clientconfig); + HITLS_CFG_FreeConfig(serverconfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC002 +* @brief 2.1-Incorrect DHE Share-6 +* @spec If no common cryptographic parameters can be negotiated, the server MUST abort the handshake with an +* appropriate alert. +* @title The server receives two unsupported key_share messages. +* @precon nan +* @brief +* 1. Set the group (HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1, and HITLS_EC_GROUP_SECP521R1) on the client and +* set the group (HITLS_EC_GROUP_SECP384R1) on the server. Expected result 1 is obtained. +* 2. Establish a connection, stop the server in TRY_SEND_HELLO_RETRY_REQUEST state, and change the value of the group +* field in the connection to HITLS_EC_GROUP_SECP521R1. Expected result 2 is obtained. +* 3. Continue to establish a connection and observe the connection establishment result. Expected result 3 is obtained. +* @expect +* 1. The setting is successful. +* 2. The modification is successful. +* 3. The server sends a request again, and the client returns HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC002() +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *clientconfig = NULL; + HITLS_Config *serverconfig = NULL; + clientconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(clientconfig != NULL); + serverconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(serverconfig != NULL); + + // Set the group (HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1, and HITLS_EC_GROUP_SECP521R1) on the client + // and set the group (HITLS_EC_GROUP_SECP384R1) on the server. + uint16_t clientgroups[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t servergroups[] = {HITLS_EC_GROUP_SECP384R1}; + ASSERT_EQ(HITLS_CFG_SetGroups(clientconfig, clientgroups, sizeof(clientgroups) / sizeof(uint16_t)), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetGroups(serverconfig, servergroups, sizeof(servergroups) / sizeof(uint16_t)), HITLS_SUCCESS); + + client = FRAME_CreateLink(clientconfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(serverconfig, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recBuf = ioUserData->recMsg.msg; + uint32_t recLen = ioUserData->recMsg.len; + ASSERT_TRUE(recLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recBuf, recLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + // Establish a connection, stop the server in TRY_SEND_HELLO_RETRY_REQUEST state, and change the value of the group + // field in the connection to HITLS_EC_GROUP_SECP521R1. + FRAME_ServerHelloMsg *Hello_Retry_RequestMsg = &frameMsg.body.hsMsg.body.serverHello; + Hello_Retry_RequestMsg->keyShare.data.group.state = ASSIGNED_FIELD; + Hello_Retry_RequestMsg->keyShare.data.group.data = HITLS_EC_GROUP_SECP521R1; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_EQ(HITLS_Connect(client->ssl) , HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(server->ssl) , HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Connect(client->ssl) , HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + // Continue to establish a connection and observe the connection establishment result. + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(server->ssl) , HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(clientconfig); + HITLS_CFG_FreeConfig(serverconfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC003 +* @brief 2.1-Incorrect DHE Share-6 +* @spec If no common cryptographic parameters can be negotiated, the server MUST abort the handshake with an +* appropriate alert. +* @title The client receives the key_share with the same elliptic curve for the second time. +* @precon nan +* @brief +* 1. Set the group (HITLS_EC_GROUP_SECP256R1 and HITLS_EC_GROUP_SECP384R1) on the client and set the group +* (HITLS_EC_GROUP_SECP384R1) on the server. Expected result 1 is obtained. +* 2. Establish a connection, stop the server in the TRY_SEND_HELLO_RETRY_REQUEST state, and change the value of the +* group field to HITLS_EC_GROUP_SECP256R1. Expected result 2 is obtained. +* 3. Continue connection establishment and observe the connection establishment result. Expected result 3 is obtained. +* @expect +* 1. The setting is successful. +* 2. The modification is successful. +* 3. The connection fails to be established. After receiving the request message, the client returns +* HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC003() +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *clientconfig = NULL; + HITLS_Config *serverconfig = NULL; + clientconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(clientconfig != NULL); + serverconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(serverconfig != NULL); + + // Set the group (HITLS_EC_GROUP_SECP256R1 and HITLS_EC_GROUP_SECP384R1) on the client and set the group + // (HITLS_EC_GROUP_SECP384R1) on the server. + uint16_t clientgroups[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t servergroups[] = {HITLS_EC_GROUP_SECP384R1}; + ASSERT_EQ(HITLS_CFG_SetGroups(clientconfig, clientgroups, sizeof(clientgroups) / sizeof(uint16_t)), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetGroups(serverconfig, servergroups, sizeof(servergroups) / sizeof(uint16_t)), HITLS_SUCCESS); + + client = FRAME_CreateLink(clientconfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(serverconfig, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recBuf = ioUserData->recMsg.msg; + uint32_t recLen = ioUserData->recMsg.len; + ASSERT_TRUE(recLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recBuf, recLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + // Establish a connection, stop the server in the TRY_SEND_HELLO_RETRY_REQUEST state, and change the value of the + // group field to HITLS_EC_GROUP_SECP256R1. + FRAME_ServerHelloMsg *Hello_Retry_RequestMsg = &frameMsg.body.hsMsg.body.serverHello; + Hello_Retry_RequestMsg->keyShare.data.group.state = ASSIGNED_FIELD; + Hello_Retry_RequestMsg->keyShare.data.group.data = HITLS_EC_GROUP_SECP256R1; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + ASSERT_EQ(HITLS_Connect(client->ssl) , HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(clientconfig); + HITLS_CFG_FreeConfig(serverconfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC004 +* @brief 2.1-Incorrect DHE Share-6 +* @spec If no common cryptographic parameters can be negotiated, the server MUST abort the handshake with an +* appropriate alert. +* @title The client receives an unsupported elliptic curve key_share request. +* @precon nan +* @brief +* 1. Set the group (HITLS_EC_GROUP_SECP256R1 and HITLS_EC_GROUP_SECP384R1) on the client and set the group +* (HITLS_EC_GROUP_SECP384R1) on the server. Expected result 1 is obtained. +* 2. Establish a connection, stop the server in the TRY_SEND_HELLO_RETRY_REQUEST state, and change the value of the +* group field to HITLS_EC_GROUP_SECP521R1. Expected result 2 is obtained. +* 3. Continue connection establishment and observe the connection establishment result. Expected result 3 is obtained. +* @expect +* 1. The setting is successful. +* 2. The modification is successful. +* 3. The connection fails to be established. After receiving the request message, the client returns +* HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC004() +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *clientconfig = NULL; + HITLS_Config *serverconfig = NULL; + clientconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(clientconfig != NULL); + serverconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(serverconfig != NULL); + + // Set the group (HITLS_EC_GROUP_SECP256R1 and HITLS_EC_GROUP_SECP384R1) on the client and set the group + // (HITLS_EC_GROUP_SECP384R1) on the server. + uint16_t clientgroups[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t servergroups[] = {HITLS_EC_GROUP_SECP384R1}; + ASSERT_EQ(HITLS_CFG_SetGroups(clientconfig, clientgroups, sizeof(clientgroups) / sizeof(uint16_t)), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetGroups(serverconfig, servergroups, sizeof(servergroups) / sizeof(uint16_t)), HITLS_SUCCESS); + + client = FRAME_CreateLink(clientconfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(serverconfig, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recBuf = ioUserData->recMsg.msg; + uint32_t recLen = ioUserData->recMsg.len; + ASSERT_TRUE(recLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recBuf, recLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + // Establish a connection, stop the server in the TRY_SEND_HELLO_RETRY_REQUEST state, and change the value of the + // group field to HITLS_EC_GROUP_SECP521R1. + FRAME_ServerHelloMsg *Hello_Retry_RequestMsg = &frameMsg.body.hsMsg.body.serverHello; + Hello_Retry_RequestMsg->keyShare.data.group.state = ASSIGNED_FIELD; + Hello_Retry_RequestMsg->keyShare.data.group.data = HITLS_EC_GROUP_SECP521R1; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + // Continue connection establishment and observe the connection establishment result. + ASSERT_EQ(HITLS_Connect(client->ssl) , HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(clientconfig); + HITLS_CFG_FreeConfig(serverconfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC005 +* @brief 2.1. Incorrect DHE Share +* @spec If the client has not provided a sufficient "key_share" extension (e.g., it includes only DHE or ECDHE groups + unacceptable to or unsupported by the server), the server corrects the mismatch with a HelloRetryRequest and the + client needs to restart the handshake with an appropriate "key_share" extension, as shown in Figure 2. If no common + cryptographic parameters can be negotiated, the server MUST abort the handshake with an appropriate alert. +* @title Configure groups_list:"brainpoolP512r1:X25519" on the client and groups_list:"brainpoolP512r1:X25519" on the + server. Observe the link setup result and check whether the server sends Hello_Retry_Requset. +* @precon nan +* @brief +1. Configure groups_list:"brainpoolP512r1:X25519" on the client and groups_list:"brainpoolP512r1:X25519" on the + server. +* @expect +1. Send clienthello with X25519 keyshare. The link is established successfully. +2. The server does not send Hello_Retry_Requset. +* @prior Level 2 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC005() +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *clientconfig = NULL; + HITLS_Config *serverconfig = NULL; + clientconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(clientconfig != NULL); + serverconfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(serverconfig != NULL); + + uint16_t clientgroups[] = {HITLS_EC_GROUP_BRAINPOOLP512R1, HITLS_EC_GROUP_CURVE25519}; + uint16_t servergroups[] = {HITLS_EC_GROUP_BRAINPOOLP512R1, HITLS_EC_GROUP_CURVE25519}; + ASSERT_EQ(HITLS_CFG_SetGroups(serverconfig, servergroups, sizeof(servergroups)/sizeof(uint16_t)) , HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetGroups(clientconfig, clientgroups, sizeof(clientgroups)/sizeof(uint16_t)) , HITLS_SUCCESS); + + client = FRAME_CreateLink(clientconfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(serverconfig, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recBuf = ioUserData->recMsg.msg; + uint32_t recLen = ioUserData->recMsg.len; + ASSERT_TRUE(recLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recBuf, recLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverHello = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverHello->keyShare.data.group.data == HITLS_EC_GROUP_CURVE25519); + ASSERT_EQ(server->ssl->hsCtx->haveHrr, false); + + // Continue to establish the link. + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(clientconfig); + HITLS_CFG_FreeConfig(serverconfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC001 +* @brief 4.2.9-Pre-Shared Key Exchange Modes-77 +* @spec In order to use PSKs, clients MUST also send a "psk_key_exchange_modes" extension. +* @title Preset psk Client Lost Pre-Shared Key Exchange Modes Extension +* @precon nan +* @brief +* 1. Preset the psk, modify the client hello message sent by the client to make the psk_key_exchange_modes extension +* lost, and observe the server behavior. +* @expect +* 1. Connect establishment is interrupted. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC001() +{ + // Preset the psk, modify the client hello message sent by the client to make the psk_key_exchange_modes extension + // lost, and observe the server behavior. + SetInfo setInfo = {0}; + memcpy_s(setInfo.psk, PSK_MAX_LEN, "12121212121212", sizeof("12121212121212")); + setInfo.ClientCipherSuite = "HITLS_AES_128_GCM_SHA256"; + setInfo.ClientCipherSuite = "HITLS_AES_128_GCM_SHA256"; + setInfo.SuccessOrFail = 0; + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = FrameCallBack_ClientHello_PskExchangeMode_Miss; + ClientCreatConnectWithPara(&handle, setInfo); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC002 +* @brief 4.2.9-Pre-Shared Key Exchange Modes-77 +* @spec In order to use PSKs, clients MUST also send a "psk_key_exchange_modes" extension. +* @title psk session recovery client lost Pre-Shared Key Exchange Modes extension +* @precon nan +* @brief +* 1. Preset the psk, modify the client hello message sent by the client to make the psk_key_exchange_modes extension +lost, and observe the server behavior. +* @expect +* 1. Connect establishment is interrupted. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC002() +{ + // Preset the psk, modify the client hello message sent by the client to make the psk_key_exchange_modes extension + // lost, and observe the server behavior. + SetInfo setInfo = {0}; + setInfo.SetNothing = 1; + setInfo.SuccessOrFail = 0; + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = FrameCallBack_ClientHello_PskExchangeMode_Miss; + ResumeConnectWithPara(&handle, setInfo); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_ADD_FUNC_TC001 +* @brief 4.2.9-Pre-Shared Key Exchange Modes-80 +* @spec The server MUST NOT send a "psk_key_exchange_modes" extension. +* @title The session restoration server carries psk_key_exchange_modes. +* @precon nan +* @brief +* 1. Establish a connection, save the session, and restore the session. +* 2. Modify the server hello message sent by the server to carry the psk_key_exchange_mode extension and observe the +* client behavior. +* @expect +* 1. The connection is successfully established and the session is restored. +* 2. The client sends an alert message and disconnects the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_ADD_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + // Establish a connection, save the session, and restore the session. + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + ASSERT_TRUE(testInfo.c_config != NULL); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + + // Modify the server hello message sent by the server to carry the psk_key_exchange_mode extension and observe the + // client behavior. + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ServerAddKeyExchangeMode}; + RegisterWrapper(wrapper); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_PARSE_UNSUPPORTED_EXTENSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_ADD_FUNC_TC001 +* @brief 4.2.9-Pre-Shared Key Exchange Modes-80 +* @spec psk_ke: PSK-only key establishment. In this mode, the server MUST NOT supply a "key_share" value. +* @title Preset the PSK. In psk_ke mode, the server carries the key_share extension. +* @precon nan +* @brief +* 1. Preset PSK +* 2. Set psk_key_exchange_mode to psk_ke on the client and server, +* 3. Modify the server hello message sent by the server to carry the key_share extension and observe the client +* behavior. +* @expect +* 1. The setting is successful. +* 2. The setting is successful. +* 3. The client sends an alert message and disconnects the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_ADD_FUNC_TC001() +{ + // Preset PSK + SetInfo setInfo = {0}; + memcpy_s(setInfo.psk, PSK_MAX_LEN, "12121212121212", sizeof("12121212121212")); + setInfo.ClientCipherSuite = "HITLS_AES_128_GCM_SHA256"; + setInfo.ClientCipherSuite = "HITLS_AES_128_GCM_SHA256"; + // Set psk_key_exchange_mode to psk_ke on the client and server + setInfo.ClientKeyExchangeMode = TLS13_KE_MODE_PSK_ONLY; + setInfo.ServerKeyExchangeMode = TLS13_KE_MODE_PSK_ONLY; + setInfo.SuccessOrFail = 0; + // Modify the server hello message sent by the server to carry the key_share extension and observe the client + // behavior. + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = FrameCallBack_ServerHello_KeyShare_Add; + ServerCreatConnectWithPara(&handle, setInfo); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC001 +* @brief 4.2.9-Pre-Shared Key Exchange Modes-77 +* @spec psk_dhe_ke: PSK with (EC)DHE key establishment. In this mode, the +* client and server MUST supply "key_share" values as described in Section 4.2.8. +* @title Session Recovery Client Lost Key_share Extension +* @precon nan +* @brief +* 1. When the session is recovered, modify the client hello message sent by the client so that the Key_Share extension +* is lost. Observe the server behavior. +* @expect +* 1. Connect establishment is interrupted. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC001() +{ + // When the session is recovered, modify the client hello message sent by the client so that the Key_Share extension + // is lost. Observe the server behavior. + SetInfo setInfo = {0}; + setInfo.SetNothing = 1; + setInfo.SuccessOrFail = 0; + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = FrameCallBack_ClientHello_KeyShare_Miss; + ResumeConnectWithPara(&handle, setInfo); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC002 +* @brief 4.2.9-Pre-Shared Key Exchange Modes-80 +* @spec psk_dhe_ke: PSK with (EC)DHE key establishment. In this mode, the +* client and server MUST supply "key_share" values as described in Section 4.2.8. +* @title Server: psk_key_exchange_mode: The key_share extension is lost under psk_dhe_ke. +* @precon nan +* @brief +* 1. Preset PSK +* 2. Set psk_key_exchange_mode to psk_dhe_ke on the client server, modify the server hello message sent by the server to +* lose the key_share extension, and observe the client behavior. +* @expect +* 1. The setting is successful. +* 2. The client sends an alert message to disconnect the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Server_KeyShare_Miss + }; + RegisterWrapper(wrapper); + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + // Preset PSK + char psk[] = "aaaaaaaaaaaaaaaa"; + ASSERT_TRUE(ExampleSetPsk(psk) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetPskClientCallback(testInfo.c_config, ExampleClientCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetPskServerCallback(testInfo.s_config, ExampleServerCb) == HITLS_SUCCESS); + + // Set psk_key_exchange_mode to psk_dhe_ke on the client server, modify the server hello message sent by the server + // to lose the key_share extension, and observe the client behavior. + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_HANDSHAKE_FAILURE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC001 +* @brief 4.2.11-Pre-Shared Key Extension-93 +* @spec For identities established externally, an obfuscated_ticket_age of 0 SHOULD be used, and servers MUST ignore +* the value +* @title The obfuscated_ticket_age of the preset PSK is not 0. +* @precon nan +* @brief +* 1. Preset PSK +* 2. Modify the obfuscated_ticket_age field in the psk extension in the client hello message sent by the client to +* ensure that the field is not 0. +* 3. Establish a connection. +* @expect +* 1. The setting is successful. +* 2. The modification is successful. +* 3. The connection is successfully established and certificate authentication is performed. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Client_ObfuscatedTicketAge_NotZero + }; + RegisterWrapper(wrapper); + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + // Preset PSK + char psk[] = "aaaaaaaaaaaaaaaa"; + ASSERT_TRUE(ExampleSetPsk(psk) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetPskClientCallback(testInfo.c_config, ExampleClientCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetPskServerCallback(testInfo.s_config, ExampleServerCb) == HITLS_SUCCESS); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Modify the obfuscated_ticket_age field in the psk extension in the client hello message sent by the client to + // ensure that the field is not 0. + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverhelloMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverhelloMsg->pskSelectedIdentity.exLen.data == 0); + + // Establish a connection. + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + ClearWrapper(); + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +extern int32_t CompareBinder(TLS_Ctx *ctx, const PreSharedKey *pskNode, uint8_t *psk, uint32_t pskLen, + uint32_t truncateHelloLen); + +static int32_t CompareBinder_Success(TLS_Ctx *ctx, const PreSharedKey *pskNode, uint8_t *psk, uint32_t pskLen, + uint32_t truncateHelloLen) +{ + (void)ctx; + (void)pskNode; + (void)psk; + (void)pskLen; + (void)truncateHelloLen; + return 0; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC002 +* @brief 4.2.11-Pre-Shared Key Extension-93 +* @spec For identities established externally, an obfuscated_ticket_age of 0 SHOULD be used, and servers MUST ignore +* the value +* @title The obfuscated_ticket_age of the PSK generated by the session is 0. +* @precon nan +* @brief +* 1. Preset PSK +* 2. Modify the obfuscated_ticket_age field in the psk extension in the client hello message sent by the client to +* ensure that the value is not 0. +* 3. Establish a connection. +* @expect +* 1. The setting is successful. +* 2. The modification is successful. +* 3. Certificate authentication +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + // Preset PSK + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Modify the obfuscated_ticket_age field in the psk extension in the client hello message sent by the client to + // ensure that the value is not 0. + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_Client_ObfuscatedTicketAge_Zero}; + RegisterWrapper(wrapper); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + + STUB_Init(); + FuncStubInfo stubInfo = {0}; + STUB_Replace(&stubInfo, CompareBinder, CompareBinder_Success); + + // Establish a connection. + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(testInfo.client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); +exit: + ClearWrapper(); + STUB_Reset(&stubInfo); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC003 +* @brief 4.2.11-Pre-Shared Key Extension-93 +* @spec For identities established externally, an obfuscated_ticket_age of 0 SHOULD be used, and servers MUST ignore +* the value +* @title The obfuscated_ticket_age of the PSK generated by the session is different from the original value. +* @precon nan +* @brief +* 1. Preset PSK +* 2. Modify the obfuscated_ticket_age field in the psk extension in the client hello message sent by the client to +* ensure that the field is not 0. +* 3. Establish a connection. +* @expect +* 1. The setting is successful. +* 2. The modification is successful. +* 3. Certificate authentication +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + // Preset PSK + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Modify the obfuscated_ticket_age field in the psk extension in the client hello message sent by the client to + // ensure that the field is not 0. + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_Client_ObfuscatedTicketAge_NotZero}; + RegisterWrapper(wrapper); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + + STUB_Init(); + FuncStubInfo stubInfo = {0}; + STUB_Replace(&stubInfo, CompareBinder, CompareBinder_Success); + + // Establish a connection. + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + STUB_Reset(&stubInfo); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +#define SESSION_SZ 10 +static HITLS_Session *g_userSession[SESSION_SZ]; +static int g_sessionSz = 0; + +void ClearSessoins() +{ + for (int i = 0; i < g_sessionSz; i++) { + HITLS_SESS_Free(g_userSession[i]); + } + g_sessionSz = 0; +} + +HITLS_Session *GetSession(int index) +{ + if (index < g_sessionSz) { + return HITLS_SESS_Dup(g_userSession[index]); + } + return NULL; +} + +void AddSession(HITLS_Session *session) +{ + if (g_sessionSz < SESSION_SZ - 1) { + g_userSession[g_sessionSz] = session; + g_sessionSz++; + } +} + +int32_t Test_NewSessionCb(HITLS_Ctx *ctx, HITLS_Session *session) +{ + (void)ctx; + if (ctx->isClient && HITLS_SESS_IsResumable(session)) { + AddSession(session); + return 1; + } + return 0; +} + +static int32_t Test_PskUseSessionCb_WithSHA256(HITLS_Ctx *ctx, uint32_t hashAlgo, const uint8_t **id, + uint32_t *idLen, HITLS_Session **session) +{ + (void)ctx; + (void)hashAlgo; + (void)id; + (void)idLen; + static uint8_t identity[] = "123456"; + + if (g_sessionSz > 0) { + *id = identity; + *idLen = sizeof(identity); + *session = GetSession(g_sessionSz - 1); + (*session)->cipherSuite = HITLS_AES_128_GCM_SHA256; + return HITLS_PSK_USE_SESSION_CB_SUCCESS; + } + return HITLS_PSK_USE_SESSION_CB_FAIL; +} +static int32_t Test_PskUseSessionCb_WithSHA384(HITLS_Ctx *ctx, uint32_t hashAlgo, const uint8_t **id, + uint32_t *idLen, HITLS_Session **session) +{ + (void)ctx; + (void)hashAlgo; + (void)id; + (void)idLen; + static uint8_t identity[] = "123456"; + + if (g_sessionSz > 0) { + *id = identity; + *idLen = sizeof(identity); + *session = GetSession(g_sessionSz - 1); + (*session)->cipherSuite = HITLS_AES_256_GCM_SHA384; + return HITLS_PSK_USE_SESSION_CB_SUCCESS; + } + return HITLS_PSK_USE_SESSION_CB_FAIL; +} +static int32_t Test_PskUseSessionCb_Default(HITLS_Ctx *ctx, uint32_t hashAlgo, const uint8_t **id, + uint32_t *idLen, HITLS_Session **session) +{ + (void)ctx; + (void)hashAlgo; + (void)id; + (void)idLen; + static uint8_t identity[] = "123456"; + + if (g_sessionSz > 0) { + *id = identity; + *idLen = sizeof(identity); + *session = GetSession(g_sessionSz - 1); + + HITLS_Session *newSession = HITLS_SESS_New(); + (*session)->cipherSuite = newSession->cipherSuite; + HITLS_SESS_Free(newSession); + + return HITLS_PSK_USE_SESSION_CB_SUCCESS; + } + return HITLS_PSK_USE_SESSION_CB_FAIL; +} + +static int32_t Test_PskFindSessionCb_WithSHA256(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session) +{ + (void)ctx; + (void)identity; + (void)identityLen; + + if (g_sessionSz > 0) { + *session = GetSession(g_sessionSz - 1); + (*session)->cipherSuite = HITLS_AES_128_GCM_SHA256; + return HITLS_PSK_FIND_SESSION_CB_SUCCESS; + } + return HITLS_PSK_FIND_SESSION_CB_FAIL; +} + +static int32_t Test_PskFindSessionCb_WithSHA384(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session) +{ + (void)ctx; + (void)identity; + (void)identityLen; + + if (g_sessionSz > 0) { + *session = GetSession(g_sessionSz - 1); + (*session)->cipherSuite = HITLS_AES_256_GCM_SHA384; + return HITLS_PSK_FIND_SESSION_CB_SUCCESS; + } + return HITLS_PSK_FIND_SESSION_CB_FAIL; +} + +static int32_t Test_PskFindSessionCb_Default(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session) +{ + (void)ctx; + (void)identity; + (void)identityLen; + + if (g_sessionSz > 0) { + *session = GetSession(g_sessionSz - 1); + + HITLS_Session *newSession = HITLS_SESS_New(); + (*session)->cipherSuite = newSession->cipherSuite; + HITLS_SESS_Free(newSession); + + return HITLS_PSK_FIND_SESSION_CB_SUCCESS; + } + return HITLS_PSK_FIND_SESSION_CB_FAIL; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC001 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256 if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The hash settings on the client and server are inconsistent. +* @precon nan +* @brief +* 1. Preset the PSK. The client invokes HITLS_PskUseSessionCb to set the hash to sha256, and the service invokes +* HITLS_PskFindSessionCb to set the hash to sha384. +* 2. Connect establishment +* @expect +* 1. The setting is successful. +* 2. Connect establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetNewSessionCb(testInfo.c_config, Test_NewSessionCb); + + // Preset the PSK. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // The client invokes HITLS_PskUseSessionCb to set the hash to sha256, and the service invokes + // HITLS_PskFindSessionCb to set the hash to sha384. + HITLS_CFG_SetPskUseSessionCallback(testInfo.c_config, Test_PskUseSessionCb_WithSHA256); + HITLS_CFG_SetPskFindSessionCallback(testInfo.s_config, Test_PskFindSessionCb_WithSHA384); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Connect establishment + ASSERT_TRUE( + FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT) == HITLS_MSG_HANDLE_PSK_INVALID); +exit: + ClearSessoins(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC007 +* @test UT_TLS13_RFC8446_PSKHASH_TC001_1 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256. if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The hash settings on the client and server are inconsistent. +* @precon nan +* @brief +* 1. Preset the PSK. The client invokes HITLS_PskUseSessionCb to set the hash to sha384, and the service invokes +* HITLS_PskFindSessionCb to set the hash to sha256. +* 2. Connect establishment +* @expect +* 1. The setting is successful. +* 2. Connect establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC007() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetNewSessionCb(testInfo.c_config, Test_NewSessionCb); + + // Preset the PSK. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // The client invokes HITLS_PskUseSessionCb to set the hash to sha384, and the service invokes + // HITLS_PskFindSessionCb to set the hash to sha256. + HITLS_CFG_SetPskUseSessionCallback(testInfo.c_config, Test_PskUseSessionCb_WithSHA384); + HITLS_CFG_SetPskFindSessionCallback(testInfo.s_config, Test_PskFindSessionCb_WithSHA256); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Connect establishment + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE) , HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + ClearSessoins(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC002 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256.if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The hash set does not match the hash of the negotiated cipher suite. +* @precon nan +* @brief +* 1. Preset the PSK. The client and service monotonically use the HITLS_PskUseSessionCb to set the hash to sha256 and +* the negotiation cipher suite to sha384. +* 2. Connect establishment +* @expect +* 1. The setting is successful. +* 2. If the PSK authentication fails, perform certificate authentication. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetNewSessionCb(testInfo.c_config, Test_NewSessionCb); + + // Preset the PSK. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // The client and service monotonically use the HITLS_PskUseSessionCb to set the hash to sha256 and the negotiation + // cipher suite to sha384. + uint16_t cipher_suite[] = {HITLS_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite) / sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite) / sizeof(uint16_t)); + HITLS_CFG_SetPskUseSessionCallback(testInfo.c_config, Test_PskUseSessionCb_WithSHA256); + HITLS_CFG_SetPskFindSessionCallback(testInfo.s_config, Test_PskFindSessionCb_WithSHA256); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Connect establishment + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE), HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + ClearSessoins(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC003 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256.if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The hash set by the hash matches the hash of the negotiated cipher suite. +* @precon nan +* @brief +* 1. Preset the PSK. Use the HITLS_PskUseSessionCb command to set the hash to sha256 and the negotiation cipher suite to +* sha256. +* 2. Connect establishment +* @expect +* 1. The setting is successful. +* 2. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetNewSessionCb(testInfo.c_config, Test_NewSessionCb); + + // Preset the PSK. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Use the HITLS_PskUseSessionCb command to set the hash to sha256 and the negotiation cipher suite to sha256. + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256 }; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetPskUseSessionCallback(testInfo.c_config, Test_PskUseSessionCb_WithSHA256); + HITLS_CFG_SetPskFindSessionCallback(testInfo.s_config, Test_PskFindSessionCb_WithSHA256); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Connect establishment + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recBuf = ioUserData->recMsg.msg; + uint32_t recLen = ioUserData->recMsg.len; + ASSERT_TRUE(recLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recBuf, recLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *ServerHello = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(ServerHello->pskSelectedIdentity.data.data == 0); + + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + +exit: + ClearSessoins(); + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC004 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256 if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The default client hash is sha256. +* @precon nan +* @brief +* 1. Preset the PSK. The client does not set the hash algorithm. The server sets the hash algorithm to 256 and the +* negotiation cipher suite to sha256. +* 2. Establish a connection and check the hash algorithm on the client. +* @expect +* 1. The setting is successful. +* 2. The connection is set up successfully, and the hash algorithm on the client is 256. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetNewSessionCb(testInfo.c_config, Test_NewSessionCb); + + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256 }; + + // Preset the PSK. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // The client does not set the hash algorithm. The server sets the hash algorithm to 256 and the negotiation cipher + // suite to sha256. + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite) / sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite) / sizeof(uint16_t)); + HITLS_CFG_SetPskUseSessionCallback(testInfo.c_config, Test_PskUseSessionCb_Default); + HITLS_CFG_SetPskFindSessionCallback(testInfo.s_config, Test_PskFindSessionCb_WithSHA256); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Establish a connection and check the hash algorithm on the client. + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE) != HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC005 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256.if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The default hash on the server is sha256. +* @precon nan +* @brief +* 1. Preset the PSK. The server does not set the hash algorithm. The client sets the hash algorithm to 256 and the +* negotiation cipher suite to sha256. +* 2. Establish a connection and check the hash algorithm on the server. +* @expect +* 1. The setting is successful. +* 2. The connection is set up successfully, and the hash algorithm on the server is 256. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetNewSessionCb(testInfo.c_config, Test_NewSessionCb); + + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256 }; + + // Preset the PSK. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // The server does not set the hash algorithm. The client sets the hash algorithm to 256 and the negotiation cipher + // suite to sha256. + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite) / sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite) / sizeof(uint16_t)); + HITLS_CFG_SetPskUseSessionCallback(testInfo.c_config, Test_PskUseSessionCb_WithSHA256); + HITLS_CFG_SetPskFindSessionCallback(testInfo.s_config, Test_PskFindSessionCb_Default); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Establish a connection and check the hash algorithm on the server. + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE) != HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC006 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec For externally established PSKs, the Hash algorithm MUST be set when the PSK is established or default to +* SHA-256.if no such algorithm is defined. The server MUST ensure that it selects a compatible PSK (if any) and +* cipher suite. +* @title The hash setting is inconsistent with the negotiated cipher suite. +* @precon nan +* @brief +* 1. The client invokes the HITLS_PskClientCb interface to set the preset PSK. The server invokes the HITLS_PskClientCb +* interface to set the preset PSK. +* 2. The algorithm suite negotiation result is 384, +* 3. Establish a connection. +* @expect +* 1. The setting is successful. +* 2. The setting is successful. +* 3. The connection is successfully established and certificate authentication is performed. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + + // The client invokes the HITLS_PskClientCb interface to set the preset PSK. The server invokes the HITLS_PskClientCb interface to set the preset PSK. + char psk[] = "aaaaaaaaaaaaaaaa"; + ASSERT_TRUE(ExampleSetPsk(psk) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetPskClientCallback(testInfo.c_config, ExampleClientCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetPskServerCallback(testInfo.s_config, ExampleServerCb) == HITLS_SUCCESS); + + // The algorithm suite negotiation result is 384 + uint16_t cipher_suite[] = { HITLS_AES_256_GCM_SHA384 }; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + // Establish a connection. + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE) , HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC001 +* @brief 4.2.11-Pre-Shared Key Extension-97 +* @spec the server MUST validate the corresponding binder value (see Section 4.2.11.2 below). +* If this value is not present or does not validate, the server MUST abort the handshake. +* @title Modify the binder of client hello to make the server verification fail. +* @precon nan +* @brief +* 1. The connection is established and the session is restored. +* 2. Change the value of binder in the psk extension of the client hello message sent by the client, and observe the +* behavior on the server. +* @expect +* 1. The setting is successful. +* 2. The server terminates the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + // The connection is established and the session is restored. + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Change the value of binder in the psk extension of the client hello message sent by the client, and observe the + // behavior on the server. + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_Client_Binder_Unnormal}; + RegisterWrapper(wrapper); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_PSK_INVALID); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC003 +* @brief 4.2.11-Pre-Shared Key Extension-97 +* @spec the server MUST validate the corresponding binder value (see Section 4.2.11.2 below). +* If this value is not present or does not validate, the server MUST abort the handshake. +* @title Modify the client hello message so that the server fails to verify the binder. +* @precon nan +* @brief +* 1. The connection is established and the session is restored. +* 2. Discard the master_secret extension of the client hello message sent by the client and observe the behavior of the +* server. +* @expect +* 1. The setting is successful. +* 2. The server terminates the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + // The connection is established and the session is restored. + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Discard the master_secret extension of the client hello message sent by the client and observe the behavior of + // the server. + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_Client_MasterSecret_Miss}; + RegisterWrapper(wrapper); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + + ASSERT_EQ( + FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_PSK_INVALID); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC001 +* @brief 4.2.11-Pre-Shared Key Extension-97 +* @spec Implementations MUST NOT send any records with a version less than 0x0300. +* Implementations SHOULD NOT accept any records with a version less than 0x0300 +* @title The server receives a client hello message whose recode version is 0x0300/0x0200. +* @precon nan +* @brief +* 1. Change the recode version of the client hello message sent by the client to 0x0300/0x0200. +* 2. Observe the server behavior. +* @expect +* 1. The setting is successful. +* 2. Connect establishment success/failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC001(int value, int expect) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_RECV_CLIENT_HELLO), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + /* Change the recode version of the client hello message sent by the client to 0x0300/0x0200. */ + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CLIENT_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + frameMsg.recVersion.data = value; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + /* Observe the server behavior. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Accept(testInfo.server->ssl), expect); +exit: + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC002 +* @brief 4.2.11-Pre-Shared Key Extension-97 +* @spec Implementations MUST NOT send any records with a version less than 0x0300. +* Implementations SHOULD NOT accept any records with a version less than 0x0300 +* @title The client receives the server hello message whose recode version is 0x0300/0x0200. +* @precon nan +* @brief +* 1. Change the recode version of the client hello message sent by the server to 0x0300/0x0200. +* 2. Observe client behavior. +* @expect +* 1. The setting is successful. +* 2. Connect establishment success/failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC002(int value, int expect) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + /* Change the recode version of the client hello message sent by the server to 0x0300/0x0200. */ + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + frameMsg.recVersion.data = value; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(testInfo.client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + /* Observe client behavior. */ + ASSERT_TRUE(testInfo.server->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), expect); +exit: + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC001 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec +* @title Two PSKs. Select the first one when the conditions are met. +* @precon nan +* @brief +* 1. The PSK is generated during connection establishment, and set to the client. +* 2. Preset the PSK and establish a connection. +* @expect +* 1. The setting is successful. +* 2. The connection is successfully set up and the first PSK is selected. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256 }; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // The PSK is generated during connection establishment, and set to the client. + HITLS_CFG_SetPskClientCallback(testInfo.c_config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.s_config, (HITLS_PskServerCb)ExampleServerCb); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) , HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + /* Preset the PSK and establish a connection. */ + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->pskSelectedIdentity.exLen.data != 0); + ASSERT_TRUE(serverMsg->pskSelectedIdentity.data.data == 0); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_SESS_Free(testInfo.clientSession); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC002 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec +* @title Two psks. If the former one does not meet the requirements, select the second one. +* @precon nan +* @brief +* 1. The PSK is generated during connection establishment. Configure the default 384 algorithm suite on the client. +* 2. Set the 256 cipher suite, preset the PSK, and establish a connection. +* @expect +* 1. The setting is successful. +* 2. The connection is successfully established and the second cipher suite is selected. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + + // The PSK is generated during connection establishment. Configure the default 384 algorithm suite on the client. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + /* Set the 256 cipher suite, preset the PSK, and establish a connection. */ + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256, HITLS_AES_256_GCM_SHA384 }; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite[0])/sizeof(uint16_t)); + + HITLS_CFG_SetPskClientCallback(testInfo.c_config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.s_config, (HITLS_PskServerCb)ExampleServerCb); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) , HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->pskSelectedIdentity.exLen.data != 0); + ASSERT_TRUE(serverMsg->pskSelectedIdentity.data.data == 1); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_SESS_Free(testInfo.clientSession); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC003 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec +* @title Neither of the two PSKs meets the requirements. Select certificate authentication. +* @precon nan +* @brief +* 1. Set the 256 algorithm suite and set up a connection to generate a PSK, and set to the client. +* 2. Set the 384 algorithm suite, preset the PSK, and establish a connection. +* @expect +* 1. The setting is successful. +* 2. The connection is successfully established and the PSK authentication is performed. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + + // Set the 256 algorithm suite and set up a connection to generate a PSK, and set to the client. + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256 }; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Set the 384 algorithm suite, preset the PSK, and establish a connection. + cipher_suite[0] = HITLS_AES_256_GCM_SHA384; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + + HITLS_CFG_SetPskClientCallback(testInfo.c_config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.s_config, (HITLS_PskServerCb)ExampleServerCb); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) , HITLS_SUCCESS); + + /* Obtain the message buffer. */ + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + /* Parse the structure to the msg structure. */ + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->pskSelectedIdentity.exLen.data == 0); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_SEND_CERTIFICATE) , HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_SESS_Free(testInfo.clientSession); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC004 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec +* @title Trigger the hrr message and select the PSK. +* @precon nan +* @brief +* 1. The PSK is generated during connection establishment, and set on the client. +* 2. Set a group so that the server triggers the hrr message, preset the PSK, and establish a connection. +* @expect +* 1. The setting is successful. +* 2. The connection is successfully set up. The server sends the hrr message and selects the PSK. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + + // The PSK is generated during connection establishment, and set on the client. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + // Set a group so that the server triggers the hrr message, preset the PSK, and establish a connection. + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.c_config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.s_config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + + HITLS_CFG_SetPskClientCallback(testInfo.c_config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.s_config, (HITLS_PskServerCb)ExampleServerCb); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) , HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(testInfo.server->ssl->hsCtx->haveHrr == true); + serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->pskSelectedIdentity.data.data == 0); + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(HITLS_Connect(testInfo.client->ssl), HITLS_REC_NORMAL_IO_BUSY); + + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(testInfo.client->io); + uint32_t sendLen = ioUserData2->sndMsg.len; + ASSERT_TRUE(sendLen != 0); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_SESS_Free(testInfo.clientSession); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC005 +* @brief 4.2.11-Pre-Shared Key Extension-94 +* @spec +* @title Compatibility between session restoration and user-configured PSK +* @precon nan +* @brief +1. create a tls1.3 connection +2. Configure the user-defined PSK through the callback function. +3. Ensure that the PSK length configured by the user is greater than the PSK length for session restoration. +4. Establish a link again. +* @expect +1. The connection is successful. +2. Configuration succeeded. +3. Configuration succeeded. +4. The connection is successful. +* @prior Level 2 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC005() +{ + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + + // The PSK is generated during link establishment. Configure the default 384 algorithm suite on the client. + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + /* Set the 256 cipher suite, preset the PSK, and establish a link. */ + uint16_t cipher_suite[] = { HITLS_AES_128_GCM_SHA256, HITLS_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(testInfo.c_config, cipher_suite, sizeof(cipher_suite)/sizeof(uint16_t)); + HITLS_CFG_SetCipherSuites(testInfo.s_config, cipher_suite, sizeof(cipher_suite[0])/sizeof(uint16_t)); + + ExampleSetPsk("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + HITLS_CFG_SetPskClientCallback(testInfo.c_config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.s_config, (HITLS_PskServerCb)ExampleServerCb); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_TRUE(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession) == HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_SERVER_HELLO) , HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = SERVER_HELLO; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + ASSERT_TRUE(serverMsg->pskSelectedIdentity.exLen.data != 0); + ASSERT_TRUE(serverMsg->pskSelectedIdentity.data.data == 1); + + ASSERT_TRUE(testInfo.client->ssl != NULL); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT) , HITLS_SUCCESS); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_SESS_Free(testInfo.clientSession); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* During the TLS1.3 HRR handshaking, application messages can not be received*/ +/* BEGIN_CASE */ +void UT_TLS13_RFC8446_HRR_APP_RECV_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLSConfig(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + /* 1. Initialize the client and server to tls1.3, construct the scenario where the supportedversion values carried + by serverhello and hrr are different, */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + uint32_t sendLenapp = 7; + uint8_t sendBufapp[7] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x05, 0x05}; + uint32_t writeLen; + BSL_UIO_Write(clientTlsCtx->uio, sendBufapp, sendLenapp, &writeLen); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS1_3_RFC8446_Legacy_Version_TC001 +* @spec For TLS 1.3, the legacy_record_version set to 0x0403 to client will get alert +* @title For TLS 1.3, the legacy_record_version set to 0x0403 to client will get alert +* @precon nan +* @brief 5.1. Record Layer line 190 +* legacy_record_version: MUST be set to 0x0303 for all records generated by a TLS 1.3 + implementation other than an initial ClientHello (i.e., one not generated after a HelloRetryRequest), + where it MAY also be 0x0301 for compatibility purposes. This field is deprecated and MUST be ignored + for all purposes. Previous versions of TLS would use other values in this field under some circumstances. +@ */ +/* BEGIN_CASE */ +void UT_TLS1_3_RFC8446_Legacy_Version_TC001(int statehs) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + /* Configure the server to support only the non-default curve. The server sends the HRR message. */ + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(tlsConfig, groups, groupsSize); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, statehs) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == (HITLS_HandshakeState)statehs); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.msg[1] = 0x04u; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_INVALID_PROTOCOL_VERSION); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + if (statehs == TRY_RECV_SERVER_HELLO) { + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + } else { + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS1_3_RFC8446_Legacy_Version_TC002 +* @spec For TLS 1.3, the legacy_record_version set to 0x0403 to server will get alert +* @title For TLS 1.3, the legacy_record_version set to 0x0403 to server will get alert +* @precon nan +* @brief 5.1. Record Layer line 190 +* legacy_record_version: MUST be set to 0x0303 for all records generated by a TLS 1.3 + implementation other than an initial ClientHello (i.e., one not generated after a HelloRetryRequest), + where it MAY also be 0x0301 for compatibility purposes. This field is deprecated and MUST be ignored + for all purposes. Previous versions of TLS would use other values in this field under some circumstances. +@ */ +/* BEGIN_CASE */ +void UT_TLS1_3_RFC8446_Legacy_Version_TC002(int statehs) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + /* Configure the server to support only the non-default curve. The server sends the HRR message. */ + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(tlsConfig, groups, groupsSize); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, statehs) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == (HITLS_HandshakeState)statehs); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(server->io); + ioClientData->recMsg.msg[1] = 0x04u; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_INVALID_PROTOCOL_VERSION); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + if (statehs == TRY_RECV_CLIENT_HELLO) { + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + } else { + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_PROCESS_TC001 +* @spec - +* @title During connection establishment, tls13 server receives a warning alert, the connection state change to alerted +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1. +* 2. Initiate a connection, keep the connection status in the receive_client_key_exchange state, + and simulate the scenario where the server receives a warning alert message. (Expected result 2) +* @expect 1. Complete initialization. +* 2. the connection state of server change to alerted +* @prior Level 2 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_PROCESS_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = false; + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE), HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + uint8_t alertMsg[2] = {ALERT_LEVEL_WARNING, ALERT_NO_RENEGOTIATION}; + ASSERT_EQ(REC_Write(clientTlsCtx, REC_TYPE_ALERT, alertMsg, sizeof(alertMsg)), HITLS_SUCCESS); + // clear the certificate verify in the cache + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(REC_Write(clientTlsCtx, REC_TYPE_ALERT, alertMsg, sizeof(alertMsg)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_2.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_2.data new file mode 100644 index 00000000..881f8cc0 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_2.data @@ -0,0 +1,128 @@ +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC001 +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC001: + +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC002 +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC002: + +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC003 +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC003: + +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC004 +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC004: + +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC005 +UT_TLS_TLS13_CONSISTENCY_RFC8446_REQUEST_CLIENT_HELLO_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_MISS_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_ADD_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_EXCHANGE_MODES_ADD_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_ADD_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_ADD_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_MISS_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBFUSCATED_TICKET_AGE_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKHASH_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC001:0x0300:HITLS_REC_NORMAL_IO_BUSY + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC001:0x0200:HITLS_REC_INVALID_PROTOCOL_VERSION + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC002:0x0300:HITLS_REC_NORMAL_RECV_BUF_EMPTY + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECODE_VERSION_FUNC_TC002:0x0200:HITLS_REC_INVALID_PROTOCOL_VERSION + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMEPSK_AND_SETPSK_FUNC_TC005: + +UT_TLS13_RFC8446_HRR_APP_RECV_TC001 +UT_TLS13_RFC8446_HRR_APP_RECV_TC001: + +UT_TLS1_3_RFC8446_Legacy_Version_TC001-TRY_RECV_ENCRYPTED_EXTENSIONS +UT_TLS1_3_RFC8446_Legacy_Version_TC001:TRY_RECV_ENCRYPTED_EXTENSIONS + +UT_TLS1_3_RFC8446_Legacy_Version_TC001-TRY_RECV_CERTIFICATE +UT_TLS1_3_RFC8446_Legacy_Version_TC001:TRY_RECV_CERTIFICATE + +UT_TLS1_3_RFC8446_Legacy_Version_TC001-TRY_RECV_CERTIFICATE_REQUEST +UT_TLS1_3_RFC8446_Legacy_Version_TC001:TRY_RECV_CERTIFICATE_REQUEST + +UT_TLS1_3_RFC8446_Legacy_Version_TC001-TRY_RECV_CERTIFICATE_VERIFY +UT_TLS1_3_RFC8446_Legacy_Version_TC001:TRY_RECV_CERTIFICATE_VERIFY + +UT_TLS1_3_RFC8446_Legacy_Version_TC001-TRY_RECV_FINISH +UT_TLS1_3_RFC8446_Legacy_Version_TC001:TRY_RECV_FINISH + +UT_TLS1_3_RFC8446_Legacy_Version_TC001-TRY_RECV_SERVER_HELLO +UT_TLS1_3_RFC8446_Legacy_Version_TC001:TRY_RECV_SERVER_HELLO + +UT_TLS1_3_RFC8446_Legacy_Version_TC002 +UT_TLS1_3_RFC8446_Legacy_Version_TC002:TRY_RECV_CLIENT_HELLO + +UT_TLS1_3_RFC8446_Legacy_Version_TC002 +UT_TLS1_3_RFC8446_Legacy_Version_TC002:TRY_RECV_CERTIFICATE_VERIFY + +UT_TLS1_3_RFC8446_Legacy_Version_TC002 +UT_TLS1_3_RFC8446_Legacy_Version_TC002:TRY_RECV_FINISH + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_PROCESS_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ALERT_PROCESS_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_appendix.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_appendix.c new file mode 100644 index 00000000..66f05a62 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_appendix.c @@ -0,0 +1,651 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "rec_wrapper.h" +#include "alert.h" +#include "hitls_crypt_init.h" +#include "common_func.h" +#include "securec.h" +#include "hitls_error.h" +#include "hs.h" +#include "stub_replace.h" +#include "frame_tls.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_link.h" +#include "hlt.h" + +#define UT_TIMEOUT 3 +/* END_HEADER */ + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} HsTestInfo; +int32_t NewConfig(HsTestInfo *testInfo) +{ + switch (testInfo->version) { + case HITLS_VERSION_DTLS12: + testInfo->config = HITLS_CFG_NewDTLS12Config(); + break; + case HITLS_VERSION_TLS13: + testInfo->config = HITLS_CFG_NewTLS13Config(); + break; + case HITLS_VERSION_TLS12: + testInfo->config = HITLS_CFG_NewTLS12Config(); + break; + default: + break; + } + if (testInfo->config == NULL || testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + HITLS_CFG_SetClientVerifySupport(testInfo->config, true); + HITLS_CFG_SetExtenedMasterSecretSupport(testInfo->config, true); + HITLS_CFG_SetNoClientCertSupport(testInfo->config, true); + HITLS_CFG_SetRenegotiationSupport(testInfo->config, true); + HITLS_CFG_SetPskServerCallback(testInfo->config, (HITLS_PskServerCb)ExampleServerCb); + return HITLS_SUCCESS; +} +static int32_t DoHandshake(HsTestInfo *testInfo) +{ + /* Construct a connection. */ + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + return FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001 +* @spec - +* @title Expired signature algorithm +* @precon nan +* @brief 1. Initialize the client server to tls1.3 and construct the scenario where the client uses all the + obsolete_RESERVED signature algorithms in polling mode, Expected result: The connection fails to be + established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001(int signAlg) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + HITLS_CFG_SetSignature(testInfo.config, (uint16_t *)&signAlg, 1); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002 +* @spec - tls1.3 Expired group algorithm OBSOLETE_RESERVED test +* @title +* @precon nan +* @brief 1. Initialize the client and server to tls1.3 and construct the scenario where the client uses all the + obsolete_RESERVED group algorithms in polling mode, Expected result: The connection fails to be established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002(int group) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + HITLS_CFG_SetGroups(testInfo.config, (uint16_t *)&group, 1); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_ServerHelloNoSupportedVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC001 +* @spec - +* @title server hello really necessary extensions +* @precon nan +* @brief 1. If the server sends a HelloRetryRequest message without supported_versions, the connection fails to be + established and the client generates an alarm. + Expected result: The connection fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + RecWrapper wrapper = { TRY_SEND_HELLO_RETRY_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, + Test_ServerHelloNoSupportedVersion }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC002 +* @spec - +* @title server hello really necessary extension +* @precon nan +* @brief 1. In certificate authentication, the first connection is established. If the ServerHello message sent by the + Server does not contain the signature_algorithms field, the connection fails to be established and the client generates + an alarm. + Expected result: The connection fails to be established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC002() +{ + + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + RecWrapper wrapper = { TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ServerHelloNoSupportedVersion }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_UNSUPPORT_VERSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_ResumeServerHelloNoSupportedVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + if (ctx->session == NULL) { + return; + } + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_ResumeClientHelloNoSupportedVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + if (ctx->session == NULL) { + return; + } + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_ClientHelloNoSupportedVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC003 +* @spec - +* @title server Hello message extension is missing. +* @precon nan +* @brief Certificate authentication, session recovery, the Server sends the ServerHello message without the + signature_algorithms, the session recovery fails, and the client generates an alarm. +* Expected result: connect establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + RecWrapper wrapper = { TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, + Test_ResumeServerHelloNoSupportedVersion }; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + ClearWrapper(); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), + HITLS_MSG_HANDLE_UNSUPPORT_VERSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC004 +* @spec - +* @title client hello is missing the necessary extension. +* @precon nan +* @brief 1. In certificate authentication, the first connection is established. If the clientHello message sent by the +* client does not contain signature_algorithms, the connection fails to be established and the server +* generates an alarm. Expected result: The connection fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC004() +{ + + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + RecWrapper wrapper = { TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ClientHelloNoSupportedVersion }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_UNSUPPORT_VERSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC005 +* @spec - +* @title client Hello packet extension is missing. +* @precon nan +* @brief Certificate authentication, session recovery. If the client sends a clientHello message without +* signature_algorithms, the session recovery fails and the server generates an alarm. *Expected result: The +* connection fails to be established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + HITLS_CFG_SetSessionTimeout(testInfo.config, UT_TIMEOUT); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ResumeClientHelloNoSupportedVersion}; + RegisterWrapper(wrapper); + /* First handshake */ + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + ClearWrapper(); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), + HITLS_MSG_HANDLE_UNSUPPORT_VERSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ClientHello2NoSupportedVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + if (!ctx->hsCtx->haveHrr) { + return; + } + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC006 +* @spec - +* @title client hello is missing the necessary extension. +* @precon nan +* @brief 1. After receiving the HelloRetryRequest message, the client sends the second ClientHello message. If the +* client does not have the signature_algorithms message, the connection fails to be established and the server +* generates an alarm. Expected result: The connection fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + RecWrapper wrapper = { TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, + Test_ClientHello2NoSupportedVersion }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_UNSUPPORT_VERSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_Client2HelloNoSupportedGroup(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + if (!ctx->hsCtx->haveHrr) { + return; + } + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_ClientHelloNoSupportedGroup(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC007 +* @spec - +* @title client hello is missing the necessary extension. +* @precon nan +* @brief 1. During DHE key exchange, if the ClientHello does not contain "supported_groups", the connection fails to be + established and the server generates an alarm. Expected result: The connection fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC007() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = { 0 }; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + RecWrapper wrapper = { TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ClientHelloNoSupportedGroup }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_MISSING_EXTENSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC008 +* @spec - +* @title client hello really necessary extension +* @precon nan +* @brief 1. After the client receives the HelloRetryRequest message, the client sends the second ClientHello message + without the supported_groups field. In this case, the connection fails to be established and the server + generates an alarm. + Expected result: The connection fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC008() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + RecWrapper wrapper = { TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_Client2HelloNoSupportedGroup }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_MISSING_EXTENSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_appendix.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_appendix.data new file mode 100644 index 00000000..ed566c80 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_appendix.data @@ -0,0 +1,41 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001:CERT_SIG_SCHEME_DSA_SHA224 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001:CERT_SIG_SCHEME_ECDSA_SHA224 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC001:CERT_SIG_SCHEME_RSA_PKCS1_SHA224 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002:HITLS_EC_GROUP_BRAINPOOLP512R1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002:HITLS_EC_GROUP_BRAINPOOLP384R1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_OBSOLETE_RESERVED_FUNC_TC002:HITLS_EC_GROUP_BRAINPOOLP256R1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NECESSARY_EXTENSION_FUNC_TC008: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.c new file mode 100644 index 00000000..85464d6e --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.c @@ -0,0 +1,2099 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "securec.h" +#include "rec_wrapper.h" +#include "conn_init.h" +#include "rec.h" +#include "parse.h" +#include "hs_msg.h" +#include "alert.h" +#include "hitls_crypt_init.h" +#include "common_func.h" +/* END_HEADER */ + +#define g_uiPort 2987 + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} HsTestInfo; + +int32_t NewConfig(HsTestInfo *testInfo) +{ + /* Construct the configuration.*/ + switch (testInfo->version) { + case HITLS_VERSION_DTLS12: + testInfo->config = HITLS_CFG_NewDTLS12Config(); + break; + case HITLS_VERSION_TLS13: + testInfo->config = HITLS_CFG_NewTLS13Config(); + break; + case HITLS_VERSION_TLS12: + testInfo->config = HITLS_CFG_NewTLS12Config(); + break; + default: + break; + } + + if (testInfo->config == NULL || testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + HITLS_CFG_SetClientVerifySupport(testInfo->config, true); + HITLS_CFG_SetExtenedMasterSecretSupport(testInfo->config, true); + HITLS_CFG_SetNoClientCertSupport(testInfo->config, true); + HITLS_CFG_SetRenegotiationSupport(testInfo->config, true); + HITLS_CFG_SetPskServerCallback(testInfo->config, (HITLS_PskServerCb)ExampleServerCb); + return HITLS_SUCCESS; +} +static int32_t DoHandshake(HsTestInfo *testInfo) +{ + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + return FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); +} + +static void Test_Cert_len0(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE); + FRAME_CertificateMsg *certifiMsg = &frameMsg.body.hsMsg.body.certificate; + certifiMsg->certsLen.state = ASSIGNED_FIELD; + certifiMsg->certsLen.data = 0; + certifiMsg->certificateReqCtxSize.state = ASSIGNED_FIELD; + certifiMsg->certificateReqCtxSize.data = 0; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + + +static void Test_CertPackAndParse(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE); + if (frameMsg.body.hsMsg.body.certificate.certificateReqCtx.data == NULL) { + frameMsg.body.hsMsg.body.certificate.certificateReqCtxSize.data = 1; + frameMsg.body.hsMsg.body.certificate.certificateReqCtxSize.state = INITIAL_FIELD; + uint8_t *cerReqData = BSL_SAL_Calloc(1, 1); + frameMsg.body.hsMsg.body.certificate.certificateReqCtx.data = cerReqData; + frameMsg.body.hsMsg.body.certificate.certificateReqCtx.size = 1; + frameMsg.body.hsMsg.body.certificate.certificateReqCtx.state = INITIAL_FIELD; + } + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC003 +* @spec - +* @titleThe client receives a Certificate message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client initiates a TLS over TCP connection request. When the client receives the request from the server, + the client receives the request from the server. After receiving the Hello message, the server constructs a + Certificate message with zero length and sends the message to the client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message with the level of ALERT_ LEVEL_FATAL and description of +* ALERT_DECODE_ERROR. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC003(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + /* 1. Use the default configuration items to configure the client and server. */ + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + testInfo.config->isSupportNoClientCert = false; + testInfo.config->isSupportClientVerify = true; + /* 2. The client initiates a TLS over TCP connection request. When the client receives the request from the server, + * the client receives the request from the server. After receiving the Hello message, the server constructs a + * Certificate message with zero length and sends the message to the client. */ + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, &wrapper, Test_Cert_len0}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_EE_len0(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, ENCRYPTED_EXTENSIONS); + memset_s(data, bufSize, 0, bufSize); + if (ctx->isClient) { + data[0] = ENCRYPTED_EXTENSIONS; + data[1] = 0X00; + data[2] = 0X00; + data[3] = 0X00; + } +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC004 +* @spec - +* @title The client receives an EE message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client initiates a TLS over TCP connection request. After receiving the client Hello message, the +* client constructs a certificate with zero length. Send the request message to the client. Expected result 2 +* is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message with the level of ALERT_ LEVEL_FATAL and description + ALERT_DECODE_ERROR. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC004(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + /* 1. Use the default configuration items to configure the client and server. */ + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + testInfo.config->isSupportNoClientCert = false; + testInfo.config->isSupportClientVerify = true; + /* 2. The client initiates a TLS over TCP connection request. After receiving the CH message, the client + * constructs a EE with zero length. Send the request message to the client. */ + RecWrapper wrapper = {TRY_RECV_ENCRYPTED_EXTENSIONS, REC_TYPE_HANDSHAKE, true, &wrapper, Test_EE_len0}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC008 +* @title The client receives an key update message with zero length. +* @brief The client receives an key update message with zero length. Expect result 1 +* @expect +1. The client sends an ALERT message with the level of ALERT_ LEVEL_FATAL and description ALERT_DECODE_ERROR. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC008(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + + uint8_t keyUpdateMsg[] = {KEY_UPDATE, 0, 0, 0}; + ASSERT_TRUE(REC_Write(serverTlsCtx, REC_TYPE_HANDSHAKE, keyUpdateMsg, sizeof(keyUpdateMsg)) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen) == HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = {0}; + ALERT_GetInfo(clientTlsCtx, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_Cert_verify_len0(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_VERIFY); + + FRAME_CertificateVerifyMsg *CertveriMsg = &frameMsg.body.hsMsg.body.certificateVerify; + CertveriMsg->signSize.data = 0; + CertveriMsg->signSize.state = ASSIGNED_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC005 +* @spec - +* @titleThe client receives a Certificate verify message whose length is zero. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client initiates a TLS over TCP connection request. After receiving the client Hello message, the +* client constructs a certificate with zero length. Send the verify message to the client. Expected result +* 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message with the level of ALERT_ LEVEL_FATAL and description + ALERT_DECODE_ERROR. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC005(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + testInfo.config->isSupportNoClientCert = false; + testInfo.config->isSupportClientVerify = true; + RecWrapper wrapper = {TRY_SEND_CERTIFICATE_VERIFY, REC_TYPE_HANDSHAKE, false, &wrapper, Test_Cert_verify_len0}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + +static void Test_finished_len0(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, FINISHED); + FRAME_FinishedMsg *FinishedMsg = &frameMsg.body.hsMsg.body.finished; + FinishedMsg->verifyData.size = 0; + FinishedMsg->verifyData.state = ASSIGNED_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC006 +* @spec - +* @titleThe client receives a finished message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client initiates a TLS over TCP connection request and receives the request from the client. + After the Hello message is sent, construct a finished message with zero length and send the message to the + client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends an ALERT message. The level is ALERT_Level_FATAL and the description is + ALERT_DECODE_ERROR. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC006(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + /* 1. Use the default configuration items to configure the client and server. */ + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + testInfo.config->isSupportNoClientCert = false; + testInfo.config->isSupportClientVerify = true; + /* 2. The client initiates a TLS over TCP connection request and receives the request from the client. + * After the Hello message is sent, construct a finished message with zero length and send the message to the + * client. */ + RecWrapper wrapper = {TRY_SEND_FINISH, REC_TYPE_HANDSHAKE, false, &wrapper, Test_finished_len0}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_NewSessionTicket_len0(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, NEW_SESSION_TICKET); + FRAME_NewSessionTicketMsg *newsessionTMsg = &frameMsg.body.hsMsg.body.newSessionTicket; + newsessionTMsg->ticketSize.data = 0; + newsessionTMsg->ticketSize.state = ASSIGNED_FIELD; + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC007 +* @spec - +* @titleThe client receives a NewSessionTicket message with zero length. +* @precon nan +* @brief 1. Use the default configuration items to configure the client and server. Expected result 1 is obtained. +* 2. The client initiates a TLS over TCP connection request and receives the request from the client. + After receiving the Hello message, construct a New SessionTicket message with zero length and send it to the + client. Expected result 2 is obtained. +* @expect 1. The initialization is successful. +* 2. The client sends the ALERT message. The level is ALERT_ LEVEL_FATAL and the description is + ALERT_DECODE_ERROR. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC007(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + /* 1. Use the default configuration items to configure the client and server. */ + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + testInfo.config->isSupportNoClientCert = false; + testInfo.config->isSupportClientVerify = true; + /* 2. The client initiates a TLS over TCP connection request and receives the request from the client. + * After receiving the Hello message, construct a New SessionTicket message with zero length and send it to + * the client. */ + RecWrapper wrapper = {TRY_SEND_NEW_SESSION_TICKET, REC_TYPE_HANDSHAKE, false, &wrapper, Test_NewSessionTicket_len0}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC001 +* @spec - +* @title Abnormal CertMsg packet +* @precon nan +* @brief 1. Enable the dual-end verification. Change the value of certificate_request_context in the certificate message + sent by the client to a value other than 0. Expected result 1 is obtained. + Result 1: The server sends an alert message and disconnects the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC001() +{ + + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, NULL, Test_CertPackAndParse}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_CertReqAbCtxLen(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + if (frameMsg.body.hsMsg.body.certificateReq.certificateReqCtx.data == NULL) { + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_REQUEST); + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtxSize.data = 1; + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtxSize.state = INITIAL_FIELD; + uint8_t *cerReqData = BSL_SAL_Calloc(1, 1); + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtx.data = cerReqData; + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtx.size = 1; + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtx.state = INITIAL_FIELD; + } + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC001 +* @spec - +* @title Abnormal CertReqMsg message +* @precon nan +* @brief 1. Enable the dual-end check. Change the value of certificate_request_context in the certificate_request +* message sent by the server to a value other than 0. Expected result 1 is obtained. Result 1: The server +* sends an alert message and disconnects the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertReqAbCtxLen}; + RegisterWrapper(wrapper); + /* Handshake */ + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_NO_CERT_FUNC_TC001 +* @spec A Finished message MUST be sent regardless of whether the Certificate message is empty. +* @title During the normal handshake, the peer certificate can be empty, the certificate message sent by the client is +* empty, and the certificate message sent by the server is not empty. The handshake is successful. The finished +* message is sent after the certificate message and the content is correct. +* @precon nan +* @brief 4.4.2. Certificate row114 + 1. Enable the dual-end verification, allow the peer certificate to be empty, set the client certificate to + be empty, and establish a connection. +* @expect 1. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_NO_CERT_FUNC_TC001(int isSupportNoClientCert) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + 0, + 0, + 0, + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = (bool)isSupportNoClientCert; + if (config->isSupportNoClientCert) { + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + } else { + client = FRAME_CreateLink(config, BSL_UIO_TCP); + } + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC002 +* @spec + 1. If the client does not set the root certificate but the server sets the complete certificate chain, the client + fails to construct the certificate chain, and the handshake fails and the unsupported_certificate alarm is reported. +By default, the preceding alarm is generated. In the current code, the alarm is generated as bad_certificate. +* @brief If the client cannot construct an acceptable chain using the provided +* certificates and decides to abort the handshake, then it MUST abort the +* handshake with an appropriate certificate-related alert +* (by default, "unsupported_certificate"; see Section 6.2 for more information). +* 4.4.2 Certificate row 136 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + 0, + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_BAD_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC003 +* @spec + 1. The root certificate is configured on the client. Incomplete certificate chain is configured on both the client +and server. If the server fails to construct the certificate chain, the handshake fails and the unsupported_certificate + alarm is reported. By default, the alarm is the preceding alarm. In the current code, the alarm is the +bad_certificate alarm. +* @brief If the client cannot construct an acceptable chain using the provided +* certificates and decides to abort the handshake, then it MUST abort the +* handshake with an appropriate certificate-related alert +* (by default, "unsupported_certificate"; see Section 6.2 for more information). +* 4.4.2 Certificate row 136 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC003(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der", + 0, + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_BAD_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC004 +* @spec + 1. If the client sets an incorrect root certificate and the server sets a complete certificate chain, the client + fails to construct the certificate chain, and the handshake fails and the unsupported_certificate alarm is reported. + By default, the preceding alarm is generated. In the current code, the alarm is generated as bad_certificate. +* @brief If the client cannot construct an acceptable chain using the provided +* certificates and decides to abort the handshake, then it MUST abort the +* handshake with an appropriate certificate-related alert +* (by default, "unsupported_certificate"; see Section 6.2 for more information). +* 4.4.2 Certificate row 136 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC004(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "rsa_sha/ca-3072.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_BAD_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC005 +* @spec + 1. If the client does not match a proper algorithm and fails to construct a certificate chain, the handshake fails +and the unsupported_certificate alarm is reported. By default, the preceding alarm is generated. In the current code, +the HANDSHAKE_FAILURE alarm is generated. +* @brief If the client cannot construct an acceptable chain using the provided +* certificates and decides to abort the handshake, then it MUST abort the +* handshake with an appropriate certificate-related alert +* (by default, "unsupported_certificate"; see Section 6.2 for more information). +* 4.4.2 Certificate row 136 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC005(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t serverSignAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + uint16_t clientSignAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetSignature(&client->ssl->config.tlsConfig, clientSignAlgs, sizeof(clientSignAlgs) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(&server->ssl->config.tlsConfig, serverSignAlgs, sizeof(serverSignAlgs) / sizeof(uint16_t)); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *sndBuf = ioUserData->sndMsg.msg; + uint32_t sndLen = ioUserData->sndMsg.len; + ASSERT_TRUE(sndLen != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.recordType = REC_TYPE_ALERT; + ASSERT_TRUE(FRAME_ParseMsg(&frameType, sndBuf, sndLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + ASSERT_TRUE(frameMsg.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_HANDSHAKE_FAILURE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + + +static void Test_CertReqPackAndParseNoEx(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_REQUEST); + frameMsg.body.hsMsg.body.certificateReq.signatureAlgorithmsSize.data = 0; + frameMsg.body.hsMsg.body.certificateReq.signatureAlgorithmsSize.state = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC002 +* @spec - +* @title Abnormal CertReqMsg packet +* @precon nan +* @brief 1. Enable the dual-end verification. Change the value of certificate_request_context in the certificate_request +message sent by the server to a value other than 0. Expected result 1 is obtained. Result 1: The server sends an alert +message and disconnects the connection. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertReqPackAndParseNoEx}; + RegisterWrapper(wrapper); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_PARSE_INVALID_MSG_LEN); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_CertReqPackAndParseNoSign(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + // The eighth digit indicates the type of the first extension. Change the type of the first extension to key share. + *(uint16_t *)(data + 8) = HS_EX_TYPE_KEY_SHARE; + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC003 +* @spec - +* @title Abnormal CertReqMsg packet +* @precon nan +* @brief 1. Enable the dual-end verification, set the extension field in the server certificate request to exclude the + signature algorithm, and establish a connection. + Expected result: The connection fails to be established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertReqPackAndParseNoSign}; + RegisterWrapper(wrapper); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_MISSING_EXTENSION); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + +static void Test_CertReqPackAndParseUnknownEx(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, + void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_REQUEST); + frameMsg.body.hsMsg.body.certificateReq.signatureAlgorithms.state = DUPLICATE_FIELD; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + + *(uint16_t *)(data + 8) = HS_EX_TYPE_KEY_SHARE; +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC004 +* @spec - +* @title Abnormal CertReqMsg packet +* @precon nan +* @brief 1. Enable the dual-end verification, set the extension field in the server certificate request to exclude +* the signature algorithm, and establish a connection. Expected result: The connection fails to be established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertReqPackAndParseUnknownEx}; + RegisterWrapper(wrapper); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_MISSING_EXTENSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC005 +* @spec - +* @title Abnormal CertReqMsg packet +* @precon nan +* @brief 1. Initialize the client and server to tls1.3, and construct the scenario where the client and server sends an + alert message after receiving the hrr message and serverhello message, Expected Alert Message Encryption +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC005() +{ + + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + RecWrapper wrapper = {TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertReqAbCtxLen}; + RegisterWrapper(wrapper); + ASSERT_EQ( + FRAME_CreateConnection(testInfo.client, testInfo.server, true, TRY_RECV_CERTIFICATE_REQUEST), HITLS_SUCCESS); + HITLS_Connect(testInfo.client->ssl); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.client->io); + uint8_t *buffer = ioUserData->sndMsg.msg; + uint32_t len = ioUserData->sndMsg.len; + ASSERT_TRUE(len != 0); + + uint32_t parseLen = 0; + FRAME_Msg frameMsg = {}; + ASSERT_TRUE(ParserTotalRecord(testInfo.client, &frameMsg, buffer, len, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.type, REC_TYPE_ALERT); + ASSERT_EQ(frameMsg.body.alertMsg.description, ALERT_ILLEGAL_PARAMETER); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_EmptyCertMsg(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE); + FrameCertItem *certItem = frameMsg.body.hsMsg.body.certificate.certItem; + frameMsg.body.hsMsg.body.certificate.certItem = NULL; + while (certItem != NULL) { + FrameCertItem *temp = certItem->next; + BSL_SAL_FREE(certItem->cert.data); + BSL_SAL_FREE(certItem); + certItem = temp; + } + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC002 +* @spec - +* @title Abnormal CertReqMsg packet +* @precon nan +* @brief 1. Enable the dual-end verification. If the certificate message does not contain the certificate, the connection + is established. + Expected result: A decode error is returned when the connection fails to be established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, NULL, Test_EmptyCertMsg}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC003 +* @spec - +* @title Abnormal CertReqMsg packet +* @precon nan +* @brief 1. Enable the single-end authentication. If the certificate message does not contain the certificate, + establish a connection. + Expected result: Decode error is returned when the connection fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetClientVerifySupport(testInfo.config, false), HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, NULL, Test_EmptyCertMsg}; + RegisterWrapper(wrapper); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + + +static void Test_CertReqPackAndParse(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_REQUEST); + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC000 +* @spec - +* @title Verify the parsing and packaging functions of the cerreqmsg test framework. +* @precon nan +* @brief 1. Enable the dual-end check. Change the value of certificate_request_context in the certificate_request + message sent by the server to a value other than 0. + Expected result 1 is obtained. Result 1: The server sends an alert message and disconnects the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC000() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HsTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + ASSERT_EQ(NewConfig(&testInfo), HITLS_SUCCESS); + RecWrapper wrapper = {TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertReqPackAndParse}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SIGN_ERR_FUNC_TC001 +* @spec +* 1. Set the client server to tls1.3 and the client signature algorithm to ecdsa-sha1. The expected connection +* establishment fails. +* @brief If the server cannot produce a certificate chain that is signed only via the indicated +* supported algorithms, then it SHOULD continue the handshake by sending the client a certificate +* chain of its choice that may include algorithms that are not known to be supported by the client. +* This fallback chain SHOULD NOT use the deprecated SHA-1 hash algorithm in general, but MAY do so +* if the client' s advertisement permits it, and MUST NOT do so otherwise. +* 4.4.2.2. Server Certificate Selection row 135 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SIGN_ERR_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo serverCertInfo = { + "ecdsa_sha1/ca-nist521.der", + "ecdsa_sha1/inter-nist521.der", + "ecdsa_sha1/end384-sha1.der", + 0, + "ecdsa_sha1/end384-sha1.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SHA1}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &serverCertInfo); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &serverCertInfo); + ASSERT_TRUE(client != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); + ALERT_Info alert = {0}; + ALERT_GetInfo(server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_HANDSHAKE_FAILURE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static int32_t GetDisorderServerEEMsg(FRAME_LinkObj *server, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t tmpData[TEMP_DATA_LEN] = {0}; + uint32_t tmpLen = sizeof(tmpData); + (void)HITLS_Accept(server->ssl); + int32_t ret = FRAME_TransportSendMsg(server->io, tmpData, tmpLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + tmpLen = readLen; + uint8_t serverHelloData[TEMP_DATA_LEN] = {0}; + uint32_t serverHelloLen = sizeof(serverHelloData); + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, serverHelloData, serverHelloLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + serverHelloLen = readLen; + (void)HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, &data[offset], len - offset, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + offset += readLen; + if (memcpy_s(&data[offset], len - offset, serverHelloData, serverHelloLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += serverHelloLen; + *usedLen = offset; + return HITLS_SUCCESS; +} + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC001 +* @spec +1. During the handshake, the server sends an EncryptedExtensions message before the ServerHello message. +Expected result: The client returns an alert. The level is ALERT_Level_FATAL, description is ALERT_UNEXPECTED_MESSAGE, +and the handshake is interrupted. +* @brief In all handshakes, the server MUST send the EncryptedExtensions message immediately after the ServerHello +message. +* 4.3.1. Encrypted Extensions row 105 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_HANDSHAKING); + ASSERT_EQ(client->ssl->hsCtx->state, TRY_RECV_SERVER_HELLO); + + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + ASSERT_TRUE(GetDisorderServerEEMsg(server, data, len, &len) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(ioUserData->recMsg.len != 0); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info alert = {0}; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static int32_t GetDisorderServerCertMsg(FRAME_LinkObj *server, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + uint32_t readLen = 0; + uint32_t offset = 0; + uint8_t tmpData[TEMP_DATA_LEN] = {0}; + uint32_t tmpLen = sizeof(tmpData); + (void) HITLS_Accept(server->ssl); + int32_t ret = FRAME_TransportSendMsg(server->io, tmpData, tmpLen, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + tmpLen = readLen; + (void) HITLS_Accept(server->ssl); + ret = FRAME_TransportSendMsg(server->io, &data[offset], len - offset, &readLen); + if (readLen == 0 || ret != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + offset += readLen; + + if (memcpy_s(&data[offset], len - offset, tmpData, tmpLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += tmpLen; + *usedLen = offset; + return HITLS_SUCCESS; +} +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC002 +* @spec +1. The handshake uses certificate authentication. During the handshake, the server sends a Certificate Request message +before sending the EncryptedExtensions extension. Expected result: The client returns an alert, whose level is +ALERT_LEVEL_FATAL, description is ALERT_UNEXPECTED_MESSAGE, and the handshake is interrupted. +* @brief A server which is authenticating with a certificate MAY optionally request +* a certificate from the client. This message, if sent, MUST follow EncryptedExtensions. +* 4.3.2. Certificate Request row 107 +*/ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_Msg recvframeMsg = {0}; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + config->isSupportClientVerify = true; + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_ENCRYPTED_EXTENSIONS), HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_HANDSHAKING); + ASSERT_EQ(client->ssl->hsCtx->state, TRY_RECV_ENCRYPTED_EXTENSIONS); + uint8_t data[MAX_RECORD_LENTH] = {0}; + uint32_t len = MAX_RECORD_LENTH; + + ASSERT_TRUE(GetDisorderServerCertMsg(server, data, len, &len) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ASSERT_TRUE(ioUserData->recMsg.len == 0); + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(ioUserData->recMsg.len != 0); + // TLS1.3 Ciphertext Handshake Messages Are Out of Order, Causing Decryption Failure + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_BAD_RECORD_MAC); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_BAD_RECORD_MAC); +exit: + CleanRecordBody(&recvframeMsg); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +bool g_client = false; + +static void Test_NoServerCertPackAndParse001(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_VERIFY); + if (ctx->isClient == g_client) { + FRAME_CleanMsg(&frameType, &frameMsg); + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + } + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_CERTVERIFY_FUNC_TC001 + * @spec + * 1. Enable the dual-end verification, make the CertificateVerify message sent by the server lose, and observe the + * client behavior. Expected result: The client sends an alert message and the connection is disconnected. + * 2. Enable the dual-end verification, make the CertificateVerify message sent by the client lose, and observe the + * client behavior. Expected result: The client sends an alert message and the connection is disconnected. + * @brief Servers MUST send this message when authenticating via a certificate. + * Clients MUST send this message whenever authenticating via a certificate. + * 4.4.3. Certificate Verify row 145 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_CERTVERIFY_FUNC_TC001(int isClient) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + g_client = (bool)isClient; + /* 1. Enable the dual-end verification, make the CertificateVerify message sent by the server lose, and + * observe the client behavior. + * 2. Enable the dual-end verification, make the CertificateVerify message sent by the client lose, and observe + * the client behavior. */ + RecWrapper wrapper = {TRY_RECV_CERTIFICATE_VERIFY, + REC_TYPE_HANDSHAKE, + true, + NULL, + Test_NoServerCertPackAndParse001}; + RegisterWrapper(wrapper); + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_NoCertificateSignPackAndParse001(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_VERIFY); + if (ctx->isClient == g_client) { + FRAME_CertificateVerifyMsg *certVerify = &frameMsg.body.hsMsg.body.certificateVerify; + certVerify->signHashAlg.data = CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256; + certVerify->signHashAlg.state = ASSIGNED_FIELD; + } + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTVERIFY_SIGN_FUNC_TC001 + * @spec + * 1. Enable the dual-end verification, modify the signature field in the CertificateVerify message sent by the server, + * and observe the client behavior. The expected result is that the client sends decrypt_error and the connection is + * disconnected. + * 2. Enable dual-end verification, modify the signature field in the CertificateVerify message sent by the client, and + * observe the server behavior. Expected result: The server sends decrypt_error and disconnects the connection. + * @brief The receiver of a CertificateVerify message MUST verify the signature field. + * 4.4.3. Certificate Verify row 151 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTVERIFY_SIGN_FUNC_TC001(int isClient) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + g_client = (bool)isClient; + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_VERIFY, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_NoCertificateSignPackAndParse001 + }; + RegisterWrapper(wrapper); + FRAME_CertInfo serverCertInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + FRAME_CertInfo clientCertInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &serverCertInfo); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &clientCertInfo); + ASSERT_TRUE(client != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_PARSE_VERIFY_SIGN_FAIL); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_FinishedPackAndParse001(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, FINISHED); + if (ctx->isClient == g_client) { + FRAME_FinishedMsg *finishMsg = &frameMsg.body.hsMsg.body.finished; + finishMsg->verifyData.state = ASSIGNED_FIELD; + finishMsg->verifyData.size = finishMsg->verifyData.size - 1; + } + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_FINISHEDMSG_ERR_FUNC_TC001 + * @spec + * 1. Modify the Finished message sent by the server and observe the client behavior. The expected result is that the + * client sends a decrypt_error message and the connection is disconnected. + * 2. Modify the Finished message sent by the client and observe the server behavior. The expected result is that the + * server sends a decrypt_error message and the connection is disconnected. + * @brief Recipients of Finished messages MUST verify that the contents are correct + * and if incorrect MUST terminate the connection with a "decrypt_error" alert. + * 4.4.4. Finished row 153 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_FINISHEDMSG_ERR_FUNC_TC001(int isClient) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + g_client = (bool)isClient; + RecWrapper wrapper = {TRY_SEND_FINISH, + REC_TYPE_HANDSHAKE, + false, + NULL, + /* 1. Modify the Finished message sent by the server and observe the client behavior. The expected result is + * that the client sends a decrypt_error message and the connection is disconnected. + * 2. Modify the Finished message sent by the client and observe the server behavior. */ + Test_FinishedPackAndParse001}; + RegisterWrapper(wrapper); + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RSA1024CERT_FUNC_TC001 + * @spec + * 1. Initialize the client and server to TLS1.3 and use the 1024-bit RSA certificate. The certificate verification + * fails and connection establishment fails. + * @brief Applications SHOULD also enforce minimum and maximum key sizes. For example, + * certification paths containing keys or signatures weaker than 2048-bit RSA or 224-bit + * ECDSA are not appropriate for secure applications. + * Appendix C. Implementation Notes row 238 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RSA1024CERT_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo serverCertInfo = { + "rsa_1024/rsa_root.crt", + "rsa_1024/rsa_intCa.crt", + "rsa_1024/rsa_dev.crt", + 0, + "rsa_1024/rsa_dev.key", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + const int32_t level = 2; + HITLS_CFG_SetSecurityLevel(config, level); + + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &serverCertInfo); + ASSERT_TRUE(server == NULL); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +static void Test_AlertPackAndParse004(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_ALERT; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + + ASSERT_EQ(frameMsg.recType.data, REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &frameMsg.body.alertMsg; + ASSERT_EQ(alertMsg->alertLevel.data, ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_BAD_CERTIFICATE); + + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC001 + * @spec + * 1, If no certificate is set on the server, the client sends a complete certificate chain, and the connection fails to be + * established. + * @brief Because certificate validation requires that trust anchors be distributed independently, + * a certificate that specifies a trust anchor MAY be omitted from the chain, provided that supported + * peers are known to possess any omitted certificates. + * 4.4.2. Certificate row 119 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + 0, + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + RecWrapper wrapper = {HS_STATE_BUTT, REC_TYPE_ALERT, false, NULL, Test_AlertPackAndParse004}; + RegisterWrapper(wrapper); + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC002 + * @spec + * 1. The root certificate (any algorithm) is set on the server. The client sends a certificate chain that does not + * contain the root certificate. The connection is successfully set up. + * 2. The root certificate (any algorithm) is set on the client. The server sends a certificate chain without the root + * certificate. The connection is successfully set up. + * @brief Because certificate validation requires that trust anchors be distributed independently, + * a certificate that specifies a trust anchor MAY be omitted from the chain, provided that supported + * peers are known to possess any omitted certificates. + * 4.4.2. Certificate row 119 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo serverCertInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + FRAME_CertInfo clientCertInfo = { + "ecdsa/ca-nist521.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &serverCertInfo); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &clientCertInfo); + ASSERT_TRUE(client != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC003 + * @spec + * 1. The root certificate is incorrectly set on the server. After the client sends a complete certificate chain, the + * connection fails to be established and the error code is displayed. ALERT_BAD_CERTIFICATE + * @brief Because certificate validation requires that trust anchors be distributed independently, + * a certificate that specifies a trust anchor MAY be omitted from the chain, provided that supported + * peers are known to possess any omitted certificates. + * 4.4.2. Certificate row 119 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC003(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "rsa_sha/ca-3072.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + 0, + "ecdsa/end256-sha256.key.der", + 0, + }; + RecWrapper wrapper = { + HS_STATE_BUTT, + REC_TYPE_ALERT, + true, + NULL, + Test_AlertPackAndParse004 + }; + RegisterWrapper(wrapper); + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTNULL_FUNC_TC001 +* @spec If the client does not send any certificates (i.e., it sends an empty Certificate message), + the server MAY at its discretion either continue the handshake without client authentication + or abort the handshake with a "certificate_required" alert. +* @title The certificate list of the server is not empty. The certificate of the peer end cannot be empty. The client + sends an empty certificate. +* Expected result: The handshake between the two parties fails, and the server sends an alarm. The alarm level + is ALERT_LEVEL_FATAL and the description is certificate_required. +* @precon nan +* @brief 4.4.2.4. Receiving a Certificate Message row142 + 1. Enable dual-end verification. Do not allow the peer certificate to be empty, set the client certificate + to be empty, and establish a connection. +* @expect 1. If the connection fails to be established, the server generates an alarm. The alarm level is ALERT_LEVEL_FATAL + and the description is certificate_required. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTNULL_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der", + 0, + 0, + 0, + 0, + 0, + }; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_CERTIFICATE_REQUIRED); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ECDSA_SIGN_RSA_CERT_FUNC_TC001 +* @spec Note that a certificate containing a key for one signature algorithm MAY be signed +* using a different signature algorithm (for instance, an RSA key signed with an ECDSA key). +* @title Apply for an RSA certificate issued by the ECDSA, set the certificate on the server, and set up a connection. + Expected result: The connection is successfully set up. +* @precon nan +* @brief 4.4.2.4. Receiving a Certificate Message row144 + 1. Enable dual-end verification, apply for an RSA certificate issued by the ECDSA, set the certificate on the + server, and set up a connection. +* @expect 1. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ECDSA_SIGN_RSA_CERT_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FRAME_CertInfo certInfo = { + "ecdsa_rsa_cert/rootCA.der", + "ecdsa_rsa_cert/CA1.der", + "ecdsa_rsa_cert/ee.der", + 0, + "ecdsa_rsa_cert/ee.key.der", + 0, + }; + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + config->isSupportRenegotiation = true; + config->isSupportClientVerify = true; + config->isSupportNoClientCert = false; + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.data new file mode 100644 index 00000000..d470eafc --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.data @@ -0,0 +1,112 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECV_ZEROLENGTH_MSG_FUNC_TC008: + + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_NO_CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_NO_CERT_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_NO_CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_NO_CERT_FUNC_TC001:0 + + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTCHAIN_FUNC_TC005: + + + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTMSG_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC000 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ABNORMAL_CERTREQMSG_FUNC_TC000: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIGN_ERR_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SIGN_ERR_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNEXPECTMSG_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_CERTVERIFY_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_CERTVERIFY_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_CERTVERIFY_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_NO_CERTVERIFY_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTVERIFY_SIGN_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTVERIFY_SIGN_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTVERIFY_SIGN_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTVERIFY_SIGN_FUNC_TC001:1 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_FINISHEDMSG_ERR_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_FINISHEDMSG_ERR_FUNC_TC001:0 + +UT_TLS_TLS13_RFC8446_CONSISTENCY_FINISHEDMSG_ERR_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_FINISHEDMSG_ERR_FUNC_TC001:1 + + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSA1024CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RSA1024CERT_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_CERTCHAIN_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTNULL_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CLIENT_CERTNULL_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ECDSA_SIGN_RSA_CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ECDSA_SIGN_RSA_CERT_FUNC_TC001: diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_1.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_1.c new file mode 100644 index 00000000..8d352700 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_1.c @@ -0,0 +1,2325 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "rec_wrapper.h" +#include "cert.h" +#include "securec.h" +#include "process.h" +#include "conn_init.h" +#include "hitls_crypt_init.h" +#include "hitls_psk.h" +#include "common_func.h" +#include "alert.h" +#include "bsl_sal.h" +/* END_HEADER */ +#define MAX_BUF 16384 + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} ResumeTestInfo; + +static int32_t DoHandshake(ResumeTestInfo *testInfo) +{ + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->clientSession != NULL) { + int32_t ret = HITLS_SetSession(testInfo->client->ssl, testInfo->clientSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + return FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); +} +static void Test_PskGetCert(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + static uint8_t certBuf[MAX_BUF] = {0}; + static uint32_t bufLen = 0; + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + if (user != NULL) { // cert message + ASSERT_EQ(memcpy_s(certBuf, MAX_BUF, data, *len), EOK); + bufLen = *len; + } else { + ASSERT_EQ(memcpy_s(data, bufSize, certBuf, bufLen), EOK); + *len = bufLen; + } +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERT_FUNC_TC001 +* @spec - +* When the @title psk session is resumed, the server sends the certificate message after sending the server hello +* message. The expected handshake fails. +* @precon nan +* @brief 2.2 Resumption and Pre-Shared Key line 7 +* @expect 1. The expected handshake fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERT_FUNC_TC001() +{ + + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, &wrapper, Test_PskGetCert}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + wrapper.ctrlState = TRY_SEND_FINISH; + wrapper.userData = NULL; + RegisterWrapper(wrapper); + ASSERT_NE(DoHandshake(&testInfo), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC001 +* @spec - +* @title Set the client and server to tls1.3. Set the cipher suites on the client and server to mismatch. As a result, +* the expected connection establishment fails and a handshake_failure alert message is sent. +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation line 13 +* @expect 1. Expected handshake failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + cipherSuite = HITLS_AES_256_GCM_SHA384; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_HANDSHAKE_FAILURE); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_PskGetCertReq(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + static uint8_t certBuf[READ_BUF_SIZE] = {0}; + static uint32_t bufLen = 0; + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + if (user != NULL) { // cert message + ASSERT_EQ(memcpy_s(certBuf, READ_BUF_SIZE, data, *len), EOK); + bufLen = *len; + } else { + ASSERT_EQ(memcpy_s(data, bufSize, certBuf, bufLen), EOK); + *len = bufLen; + } +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERTREQ_FUNC_TC001 +* @spec - +* @title 1. Preset the PSK. After the server sends the encryption extension, construct the certficaterequest message and +* observe the client behavior. +* @precon nan +* @brief 4.3.2. Certificate Request line 110 +* @expect 1. The client sends an alert message and disconnects the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERTREQ_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.config->isSupportClientVerify = true; + RecWrapper wrapper = {TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, &wrapper, Test_PskGetCertReq}; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + + wrapper.ctrlState = TRY_SEND_FINISH; + wrapper.userData = NULL; + RegisterWrapper(wrapper); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC002 +* @spec - +* @title Set the client and server to tls1.3. Set the group on the client and server to different values. If the +* expected connection establishment fails, the handshake_failurealert message is sent. +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation line 13 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t group = HITLS_EC_GROUP_SECP256R1; + HITLS_CFG_SetGroups(testInfo.config, &group, 1); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + group = HITLS_EC_GROUP_SECP384R1; + HITLS_CFG_SetGroups(testInfo.config, &group, 1); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_HANDSHAKE_FAILURE); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC003 +* @spec - +* @title Set the client server to tls1.3 and the server certificate does not match the signature algorithm specified by +* the client. In this case, the connection establishment fails and a handshake_failure alert message is sent. +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation line 13 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t signature = CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256; + HITLS_CFG_SetSignature(testInfo.config, &signature, 1); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + signature = CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384; + HITLS_CFG_SetSignature(testInfo.config, &signature, 1); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_HANDSHAKE_FAILURE); + +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ClientHelloMissKeyShare(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.keyshares.exState = MISSING_FIELD; + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exState = MISSING_FIELD; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + ASSERT_NE(parseLen, *len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC004 +* @spec - +* @title Set the client server to tls1.3 and set the client psk mode to psk only. The provided psk server does not +* support the psk. As a result, the connection fails to be established. Send handshake_failure alert +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation line 13 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ClientHelloMissKeyShare}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_HANDSHAKE_FAILURE); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC005 +* @spec - +* @title Set the client server to tls1.3 and set the psk mode of the client to psk only. No psk extension is provided. + * As a result, connection establishment fails. Send handshake_failure alert +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation line 13 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ClientHelloMissKeyShare}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_MISSING_EXTENSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ErrorOrderPsk(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.extensionLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.length.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.pskModes.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + uint8_t pskMode[] = {0, 0x2d, 0, 2, 1, 1}; // psk with dhe mode + ASSERT_NE(parseLen, *len); + ASSERT_EQ(memcpy_s(&data[*len], bufSize - *len, &pskMode, sizeof(pskMode)), EOK); + *len += sizeof(pskMode); + ASSERT_EQ(parseLen, *len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC001 +* @spec - +* @title Set the client server to tls1.3 and construct the clienthello pre_shared_key extension that is not the last. +* The server is expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ErrorOrderPsk}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_RepeatClientHelloExtension(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FieldState *extensionState = GetDataAddress(&frameMsg, user); + *extensionState = DUPLICATE_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + ASSERT_NE(parseLen, *len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void RepeatClientHelloExtension(void *memberAddress, bool isPsk) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + if (isPsk) { + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + } + char serverName[] = "testServer"; + uint8_t alpn[6] = {4, '1', '2', '3', '4', 0}; + HITLS_CFG_SetServerName(testInfo.config, (uint8_t *)serverName, strlen(serverName)); + HITLS_CFG_SetAlpnProtos(testInfo.config, alpn, strlen((char *)alpn)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, memberAddress, Test_RepeatClientHelloExtension}; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC002 +* @spec - +* @title The client server is tls1.3. Two signature algorithms are used to construct the clienthello. The server is +* expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC002() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.signatureAlgorithms.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC003 +* @spec - +* @title The client server is tls1.3. Two supportedGroups are displayed in the clienthello. The server is expected to +* return an alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC003() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedGroups.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC004 +* @spec - +* @title The client server is tls1.3. Two pointFormats are displayed in the constructed clienthello. The server is +* expected to return an alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC004() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.pointFormats.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC005 +* @spec - +* @title The client server is tls1.3. Two supportedVersion fields are displayed in the clienthello. The server is + expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC005() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedVersion.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC006 +* @spec - +* @title The client server is tls1.3. When two extendedMasterSecrets are displayed in the clienthello message, the +* server is expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC006() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.extendedMasterSecret.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC007 +* @spec - +* @title The client server is tls1.3. Two pskModes are displayed in the clienthello. The server is expected to return an +* alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC007() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.pskModes.exState, true); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC008 +* @spec - +* @title The client server is tls1.3. Two keyshares are displayed when the clienthello is constructed. The server is +* expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC008() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC009 +* @spec - +* @title The client server is tls1.3. Two psks are displayed when the clienthello is constructed. The server is expected +* to return an alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC009() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.psks.exState, true); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC010 +* @spec - +* @title The client server is tls1.3. Two serverNames are displayed in the clienthello. The server is expected to return +* alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC010() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.serverName.exState, false); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC011 +* @spec - +* @title The client server is tls1.3. Two alpn extensions are displayed when the clienthello is constructed. The server is expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC011() +{ + RepeatClientHelloExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.alpn.exState, false); +} +/* END_CASE */ + +static void Test_RepeatServerHelloExtension(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + FieldState *extensionState = GetDataAddress(&frameMsg, user); + *extensionState = DUPLICATE_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC012 +* @spec - +* @title The client server is tls1.3. Two supportedversion extensions are displayed when the serverhello is +* constructed. The client is expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC012() +{ + + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &((FRAME_Msg *)0)->body.hsMsg.body.serverHello.supportedVersion.exState, + Test_RepeatServerHelloExtension}; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC013 +* @spec - +* @title The client server is tls1.3. Two key_share extensions are displayed when the serverhello is constructed. The +* client is expected to return alert. +* @precon nan +* @brief 4.2. Extensions line 40 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC013() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &((FRAME_Msg *)0)->body.hsMsg.body.serverHello.keyShare.exState, + Test_RepeatServerHelloExtension}; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC002 +* @spec - +* @title 1. Set the client to tls1.2 and the server to tls1.3. Initiate a connection establishment request. The expected +* connection establishment is successful and the negotiated version is tls1.2. +* @precon nan +* @brief 4.2.1 Supported Versions line 42 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.2. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLS12Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint16_t version = 0; + ASSERT_EQ(HITLS_GetNegotiatedVersion(testInfo.client->ssl, &version), HITLS_SUCCESS); + ASSERT_EQ(version, HITLS_VERSION_TLS12); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ErrLegacyVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.version.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.version.data = HITLS_VERSION_TLS13; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC003 +* @spec - +* @title 1. Set the client to tls1.2 and server to tls1.3, initiate a connection establishment request, change the +* version value in the client hello message to 0x0304, and expect the server to stop handshake. +* @precon nan +* @brief 4.2.1 Supported Versions line 42 +* @expect 1. Expected connection establishment failure +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ErrLegacyVersion}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLS12Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(testInfo.client->ssl->negotiatedInfo.version == HITLS_VERSION_TLS12); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC004 +* @spec - +* @title 1. Set the client to support TLS1.1 and TLS1.0 and the server to support TLS1.3. Initiate a connection +* establishment request. The server is expected to negotiate TLS1.3. +* @precon nan +* @brief 4.2.1 Supported Versions line 43 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.3. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint16_t version = 0; + ASSERT_EQ(HITLS_GetNegotiatedVersion(testInfo.client->ssl, &version), HITLS_SUCCESS); + ASSERT_EQ(version, HITLS_VERSION_TLS13); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_UnknownVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.supportedVersion.exData.data); + uint16_t version[] = { 0x01, 0x02, *(uint16_t *)user }; + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exData.data = + BSL_SAL_Calloc(sizeof(version) / sizeof(uint16_t), sizeof(uint16_t)); + ASSERT_EQ(memcpy_s(frameMsg.body.hsMsg.body.clientHello.supportedVersion.exData.data, + sizeof(version), version, sizeof(version)), EOK); + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exData.size = sizeof(version) / sizeof(uint16_t); + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exData.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exDataLen.data = sizeof(version); + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exLen.data = sizeof(version) + sizeof(uint8_t); + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC005 +* @spec - +* @title 1. Set the client server to tls1.3 and modify the supportedversion field in the client hello packet, +* An invalid version number 0x0001,0x0002 is added before tils1.3. It is expected that the server can +* negotiate the TLS1.3 version. +* @precon nan +* @brief 4.2.1 Supported Versions line 43 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.3. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + uint16_t version = HITLS_VERSION_TLS13; + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, &version, Test_UnknownVersion}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + version = 0; + ASSERT_EQ(HITLS_GetNegotiatedVersion(testInfo.client->ssl, &version), HITLS_SUCCESS); + ASSERT_EQ(version, HITLS_VERSION_TLS13); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC006 +* @spec - +* @title 1. Configure the TLS1.2 client and TLS1.3 server, and construct the clienthello message that carries the +* supportedversion extension. If the value is 0x0303 and 0x0302, the server negotiates TLS1.2 normally and +* the handshake succeeds. +* @precon nan +* @brief 4.2.1 Supported Versions line 44 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.2. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + uint16_t version = HITLS_VERSION_TLS12; + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + &version, + Test_UnknownVersion + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLS12Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + version = 0; + ASSERT_EQ(HITLS_GetNegotiatedVersion(testInfo.client->ssl, &version), HITLS_SUCCESS); + ASSERT_EQ(version, HITLS_VERSION_TLS12); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ServerVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + if (*(uint16_t *)user == 0) { + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.supportedVersion.exState, MISSING_FIELD); + } else if (*(uint16_t *)user == HITLS_VERSION_TLS13) { + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.version.data, HITLS_VERSION_TLS12); + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.supportedVersion.data.data, HITLS_VERSION_TLS13); + } else if (*(uint16_t *)user == HITLS_VERSION_TLS12) { + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exState = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exLen.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exLen.data = 0; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exType.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exType.data = HS_EX_TYPE_SUPPORTED_VERSIONS; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.data.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.data.data = HITLS_VERSION_TLS12; + } else { + ASSERT_EQ(0, 1); + } + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC007 +* @spec - +* @title 1. Set the client to TLS1.2 and server to TLS1.3. The earlier version of TLS1.2 is expected to be negotiated. +* The server hello message sent does not carry the supportedversion extension. +* @precon nan +* @brief 4.2.1 Supported Versions line 45 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.2. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC007() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + uint16_t version = 0; + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, &version, Test_ServerVersion}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLS12Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + version = 0; + ASSERT_EQ(HITLS_GetNegotiatedVersion(testInfo.client->ssl, &version), HITLS_SUCCESS); + ASSERT_EQ(version, HITLS_VERSION_TLS12); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CHECK_SERVERHELLO_MASTER_SECRET_FUNC_TC001 + * @spec + * The client does not support the extended master key and performs negotiation. After receiving the server hello + * message with the extended master key, the client sends an alert message. Check whether the two parties enter the + * alerted state, and the read and write operations fail. + * @brief When an error is detected, the detecting party sends a message to its peer. Upon transmission or receipt of a + * fatal alert message, both parties MUST immediately close the connection. + * 6.2.0. Alert Protocol row 216 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CHECK_SERVERHELLO_MASTER_SECRET_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + HITLS_CFG_SetExtenedMasterSecretSupport(testInfo.c_config, true); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_ServerHelloSessionId(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + frameMsg.body.hsMsg.body.serverHello.sessionIdSize.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.serverHello.sessionIdSize.data = *len; + memset_s(data, bufSize, 0, bufSize); + ASSERT_EQ(parseLen, *len); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMESH_SESSIONId_LENGTHERR_FUNC_TC001 + * @spec + * 1. Session recovery. If the client receives a ServerHello message whose session_id length exceeds the length of the + * entire packet, the client sends a decode_error alarm and the session recovery fails. + * @brief Peers which receive a message which cannot be parsed according to the syntax (e.g., + * have a length extending beyond the message boundary or contain an out-of-range length) + * MUST terminate the connection with a "decode_error" alert. + * 6. Alert Protocol row 209 + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMESH_SESSIONId_LENGTHERR_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ServerHelloSessionId}; + testInfo.config = HITLS_CFG_NewTLS13Config(); + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_PARSE_INVALID_MSG_LEN); + + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_DECODE_ERROR); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC008 +* @spec - +* @title 1. Set the client to tls1.2 and server to tls1.3. Construct the serverhello message that carries the + supportedversion extension. tls1.2 in the extension, the client is expected to abort the negotiation, +* @precon nan +* @brief 4.2.1 Supported Versions line 45 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.3. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC008() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + uint16_t version = HITLS_VERSION_TLS12; + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, &version, Test_ServerVersion}; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS12Config(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC009 +* @spec - +* @title Set the client server to tls1.3, set up a connection normally, and the serverhello message is expected to carry the +* supportedversion extension. The value contains only 0x0304, and the value of legacy_version is 0x0303. +* @precon nan +* @brief 4.2.1 Supported Versions line 45 +* @expect 1. The expected connection setup is successful and the negotiated version is tls1.3. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC009() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + uint16_t version = HITLS_VERSION_TLS13; + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &version, + Test_ServerVersion + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + version = 0; + ASSERT_EQ(HITLS_GetNegotiatedVersion(testInfo.client->ssl, &version), HITLS_SUCCESS); + ASSERT_EQ(version, HITLS_VERSION_TLS13); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ErrorServerVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + if (*(uint16_t *)user == 0) { + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exState = MISSING_FIELD; + } else if (*(uint16_t *)user == HITLS_VERSION_TLS13) { + frameMsg.body.hsMsg.body.serverHello.version.data = HITLS_VERSION_TLS13; + } else if (*(uint16_t *)user == HITLS_VERSION_TLS12) { + frameMsg.body.hsMsg.body.serverHello.supportedVersion.data.data = HITLS_VERSION_TLS12; + } else { + ASSERT_EQ(0, 1); + } + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void ErrorServerVersion(uint16_t version) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &version, + Test_ErrorServerVersion + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLSConfig(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + if (version == HITLS_VERSION_TLS12) { + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_PROTOCOL_VERSION); + } +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0010 +* @spec - +* @title 1. Set the client server to tls1.3, construct the legacy_version value of serverhello to 0x0304, and expect the +* client to stop connection establishment. +* @precon nan +* @brief 4.2.1 Supported Versions line 45 +* @expect 1. Expected connection establishment failure +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0010() +{ + ErrorServerVersion(HITLS_VERSION_TLS13); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0011 +* @spec - +* @title 1. Set the client server to tls1.3 and construct that the supportedversion parameter of the serverhello does +* not exist. The client is expected to stop connection establishment. +* @precon nan +* @brief 4.2.1 Supported Versions line 45 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0011() +{ + ErrorServerVersion(0); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0012 +* @spec - +* @title 1. Set the client server to tls1.3 and set the supportedversion value of the serverhello to tls1.2. Expect the +* client to stop connection establishment. The client is expected to send the illegal_parameter alarm. +* @precon nan +* @brief 4.2.1 Supported Versions line 45/47 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0012() +{ + ErrorServerVersion(HITLS_VERSION_TLS12); +} +/* END_CASE */ + +static void Test_AbsentGroup(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + (void)bufSize; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + uint32_t sz = frameMsg.body.hsMsg.body.clientHello.supportedGroups.exData.size; + ASSERT_TRUE(sz > 1); + + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exData.size = 1; + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exData.data[0] = + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exData.data[1]; + frameMsg.body.hsMsg.body.clientHello.supportedGroups.exDataLen.data = sizeof(uint16_t); + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC001 +* @spec - +* @title 1. Initialize the client server to tls1.3, and construct that the keyshareentry.group in the sent client hello +* message is not contained in the supported_group of the client. The server aborts the handshake and returns +* the illegal_parameter alarm. +* @precon nan +* @brief 4.2.8 key share line 68 +* @expect 1. Expected connection establishment failure +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_AbsentGroup + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void HelloRetryRequest(WrapperFunc func) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_HELLO_RETRY_REQUEST, + REC_TYPE_HANDSHAKE, + false, + NULL, + func + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} + +static void Test_HelloRetryRequest(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + (void)bufSize; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data = HITLS_EC_GROUP_SECP384R1; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC002 +* @spec - +* @title 1. Initialize the client and server to tls1.3 and construct the scenario of sending hrr messages. +* Construct the scenario where the selected_group in the hrr message is not in the group supported by the +* client. Expect the client to terminate the handshake and return the illegal_parameter alarm. +* @precon nan +* @brief 4.2.8 key share line 69 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC002() +{ + HelloRetryRequest(Test_HelloRetryRequest); +} +/* END_CASE */ + +static void Test_HelloRetryRequestSameGroup(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + (void)bufSize; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data, HITLS_EC_GROUP_SECP256R1); + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data = HITLS_EC_GROUP_CURVE25519; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC003 +* @spec - +* @title 1. Initialize the client server to tls1.3, construct the scenario of sending hrr messages, and construct the +* group corresponding to the key_share key provided by the client. The client terminates the handshake and +* returns the illegal_parameter alarm. +* @precon nan +* @brief 4.2.8 key share line 69 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC003() +{ + HelloRetryRequest(Test_HelloRetryRequestSameGroup); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC004 +* @spec - +* @title 1. Initialize the client and server to tls1.3 and construct the scenario of sending hrr messages. +* Construct the scenario where the key_share carried in the clienthello message sent again is not the +* selected_group specified in the hrr message. The server is expected to terminate the handshake and return +* the illegal_parameter alarm. +* @precon nan +* @brief 4.2.8 key share line 71 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_HELLO_RETRY_REQUEST, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_HelloRetryRequest + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC001 +* @spec - +* @title 1. The client initiates connection establishment by using the PSK encrypted by the unknown key. +* Expected result: A non-PSK handshake is performed. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 96 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(testInfo.client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_InvalidSelectedIdentity(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + (void)bufSize; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.pskSelectedIdentity.exState, INITIAL_FIELD); + frameMsg.body.hsMsg.body.serverHello.pskSelectedIdentity.data.data = 1; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC002 +* @spec - +* @title 1. In the first handshake, the selected_identity of the server is not in the identity list provided by the +* client, The client uses the illegal_parameter alarm to terminate the handshake. As a result, the first +* connection fails to be established. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 100 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_InvalidSelectedIdentity + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC003 +* @spec - +* @title 1. During session restoration, the selected_identity of the server is not in the identity list provided by the +* client, The client uses the illegal_parameter alarm to terminate the handshake. As a result, the first +* connection fails to be established. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 100 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC003() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_InvalidSelectedIdentity + }; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_InvalidCipherSuites(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + (void)bufSize; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_EQ(frameMsg.body.hsMsg.body.serverHello.pskSelectedIdentity.exState, INITIAL_FIELD); + frameMsg.body.hsMsg.body.serverHello.cipherSuite.data = HITLS_AES_256_GCM_SHA384; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC004 +* @spec - +* @title 1. In the first handshake, the hash algorithm in the cipher suite selected by the server does not match the +* PSK. The client uses the (overwritten) illegal_parameter alarm to terminate the handshake. As a result, the +* onnection fails to be established. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 100 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC004() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_InvalidCipherSuites + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + HITLS_Connect(testInfo.client->ssl); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.client->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC005 +* @spec - +* @title 1. Preset the PSK. When the client sends the client hello message, the client parses the extension item of the +* client hello message so that the pre_share_key extension is not the last extension and continues to +* establish the connection. Expected result: The server returns ALERT illegal_parameter and the handshake is +* interrupted. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 100 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_ErrorOrderPsk + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC006 +* @spec - +* @title 1. During PSK-based session recovery, the client sends the client hello message, and parses the client hello +* extension. Enable the pre_share_key extension not to establish a connection for the last extension. Expected +* result: The server returns ALERT illegal_parameter and the handshake is interrupted. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 102 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_ErrorOrderPsk + }; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = { 0 }; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_ServerErrorOrderPsk(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + frameMsg.body.hsMsg.body.serverHello.extensionLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.length.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.serverHello.supportedVersion.exState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + uint8_t supportedVersion[] = {0, 0x2b, 0, 2, 3, 4}; + ASSERT_NE(parseLen, *len); + ASSERT_EQ(memcpy_s(&data[*len], bufSize - *len, &supportedVersion, sizeof(supportedVersion)), EOK); + *len += sizeof(supportedVersion); + ASSERT_EQ(parseLen, *len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC007 +* @spec - +* @title 1. Preset the PSK. When the server sends the server hello message, the server parses the extension item of the +* server hello message so that the pre_share_key extension is not the last extension and continues to +* establish the connection. Expected result: The session is restored successfully. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 100 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC007() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_VERIFY, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_ServerErrorOrderPsk + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC008 +* @spec - +* @title 1. During PSK-based session recovery, the server parses the extension items of the server hello message when +* the server sends the server hello message, Make the pre_share_key extension not the last extension and +* continue to establish the connection. Expected result: The session is restored successfully. +* @precon nan +* @brief 4.2.9 pre-shared key exchange line 102 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC008() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_ServerErrorOrderPsk + }; + RegisterWrapper(wrapper); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + + + +static void Test_HrrMisClientHelloExtension(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + if (ctx->hsCtx->haveHrr) { + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FieldState *extensionState = GetDataAddress(&frameMsg, user); + *extensionState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + } +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void WithoutPskMisKeyExtension(void *memberAddress, bool isResume, bool isHrr) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t clientGroups[] = {HITLS_EC_GROUP_CURVE25519, HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, clientGroups, sizeof(clientGroups) / sizeof(uint16_t)); + if (isResume) { + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + } else { + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + } + if (isHrr) { + uint16_t serverGroups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(testInfo.config, serverGroups, sizeof(serverGroups) / sizeof(uint16_t)); + } + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + WrapperFunc func = isHrr ? Test_HrrMisClientHelloExtension : Test_MisClientHelloExtension; + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + memberAddress, + func + }; + RegisterWrapper(wrapper); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ALERT_Info alert = {0}; + ALERT_GetInfo(testInfo.server->ssl, &alert); + ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(alert.description, ALERT_MISSING_EXTENSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC001 +* @spec - +* @title 1. When the first connection is established, the first ClientHello message received by the server does not +* contain the pre_shared_key extension. If signature_algorithms, supported_groups, or key_share is missing, +* the connection fails to be established and the server reports the missing_extension alarm. +* @precon nan +* @brief 9.2 Mandatory-to-Implement Extensions line 233 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC001() +{ + bool isResume = false; + bool isHrr = false; + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.signatureAlgorithms.exState, + isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedGroups.exState, isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, isResume, isHrr); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC002 +* @spec - +* @title 1. Certificate handshake in the hrr scenario, second ClientHello +* If signature_algorithms, supported_groups, or key_share is missing, the connection fails to be established and the +* server reports the missing_extension alarm. +* @precon nan +* @brief 9.2 Mandatory-to-Implement Extensions line 233 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC002() +{ + bool isResume = false; + bool isHrr = true; + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.signatureAlgorithms.exState, + isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedGroups.exState, isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, isResume, isHrr); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC003 +* @spec - +* @title 1. When the first connection is established, the first ClientHello message received by the server does not +* contain supported_groups. But include key_share, and vice versa. The connection fails to be established and +* theserver generates the missing_extension alarm. +* @precon nan +* @brief 9.2 Mandatory-to-Implement Extensions line 233 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC003() +{ + bool isResume = false; + bool isHrr = false; + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedGroups.exState, isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, isResume, isHrr); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC004 +* @spec - +* @title 1. The session is resumed. The first ClientHello message received by the server does not contain +* supported_groups, But include key_share, and vice versa. The session fails to be restored, and the server +* generates the missing_extension alarm. +* @precon nan +* @brief 9.2 Mandatory-to-Implement Extensions line 233 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC004() +{ + bool isResume = true; + bool isHrr = false; + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedGroups.exState, isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, isResume, isHrr); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC005 +* @spec - +* @title 1. In the hrr scenario, the certificate handshake second ClientHello does not contain supported_groups. +* share is contained, the connection fails to be established and the server generates the +* missing_extension alarm. +* @precon nan +* @brief 9.2 Mandatory-to-Implement Extensions line 233 +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC005() +{ + bool isResume = false; + bool isHrr = true; + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.supportedGroups.exState, isResume, isHrr); + WithoutPskMisKeyExtension(&((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, isResume, isHrr); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_1.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_1.data new file mode 100644 index 00000000..15ea0448 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_1.data @@ -0,0 +1,149 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERT_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_MISMATCH_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC008: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC009 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC009: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC010 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC010: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC011 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC011: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC012 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC012: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC013 +UT_TLS_TLS13_RFC8446_CONSISTENCY_ERR_HEELO_FUNC_TC013: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CHECK_SERVERHELLO_MASTER_SECRET_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CHECK_SERVERHELLO_MASTER_SECRET_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMESH_SESSIONId_LENGTHERR_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RESUMESH_SESSIONId_LENGTHERR_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERTREQ_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_CERTREQ_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC008: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC009 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC009: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0010 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0010: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0011 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0011: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0012 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SUPPORT_VERSION_FUNC_TC0012: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEY_SHARE_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_FUNC_TC008: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_EXTENSION_ASSOCIATION_FUNC_TC005: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_2.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_2.c new file mode 100644 index 00000000..ac36fc06 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_2.c @@ -0,0 +1,1276 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "rec_wrapper.h" +#include "cert.h" +#include "securec.h" +#include "process.h" +#include "conn_init.h" +#include "hitls_crypt_init.h" +#include "hitls_psk.h" +#include "common_func.h" +#include "alert.h" +#include "bsl_sal.h" +/* END_HEADER */ +#define MAX_BUF 16384 + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} ResumeTestInfo; + +static int32_t DoHandshake(ResumeTestInfo *testInfo) +{ + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + + testInfo->client = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->clientSession != NULL) { + int32_t ret = HITLS_SetSession(testInfo->client->ssl, testInfo->clientSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + testInfo->server = FRAME_CreateLink(testInfo->config, testInfo->uioType); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + return FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); +} + +typedef enum { + WITHOUT_PSK, + PRE_CONFIG_PSK, + SESSION_RESUME_PSK +} PskStatus; + +static void Test_PskConnect(uint32_t serverMode, PskStatus pskStatus) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE); + if (pskStatus == SESSION_RESUME_PSK) { + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + } else if (pskStatus == PRE_CONFIG_PSK) { + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + } else { + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + } + HITLS_CFG_SetKeyExchMode(testInfo.config, serverMode); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(testInfo.client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, pskStatus == SESSION_RESUME_PSK ? 1 : 0); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC001 +* @spec - +* @title 1. Set key_exchange_mode to 3 on the client and server to establish a connection for the first time. +* The expected result indicates that the connection is successfully established. +* @precon nan +* @brief psk Supplement the test case line 269. +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC001() +{ + Test_PskConnect(TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE, WITHOUT_PSK); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC002 +* @spec - +* @title 1. Set key_exchange_mode to 3 on the client and server to establish a connection for the first time. +* The expected result indicates that the connection is successfully established. +* @precon nan +* @brief psk Supplement the test case line 269. +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC002() +{ + Test_PskConnect(TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE, PRE_CONFIG_PSK); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC003 +* @spec - +* @title 1. Restore the session. Set key_exchange_mode to 3 on the client and server. The client carries key_share and +* connection. The expected result indicates that the connection is successfully established. +* @precon nan +* @brief psk Supplement the test case line 269. +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC003() +{ + Test_PskConnect(TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE, SESSION_RESUME_PSK); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC004 +* @spec - +* @title 1. Preset the PSK, set the key_exchange_mode of the client and server to 3 and set the key_exchange_mode of the +* server to psk_only, and establish a connection. The expected result indicates that the connection is +* successfully established. +* @precon nan +* @brief psk Supplement the test case line 269. +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC004() +{ + Test_PskConnect(TLS13_KE_MODE_PSK_ONLY, PRE_CONFIG_PSK); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC005 +* @spec - +* @title 1. Restore the session. Set the key_exchange_mode of the client and server to 3. Set the key_share extended by +* the client to establish a connection and enable the server to reject the PSK. Expected result: +* The session fails and certificate authentication is rejected. +* @precon nan +* @brief psk Supplement the test case line 269. +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC005() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + HITLS_CFG_FreeConfig(testInfo.config); + testInfo.config = HITLS_CFG_NewTLS13Config(); + HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(testInfo.client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC006 +* @spec - +* @title 1. Preset the PSK and set the key_exchange_mode on the client server to 3. The key_share extension on the +* client is lost and a connection is established. Expected result: The server sends an alert message and +* the connection is disconnected. +* @precon nan +* @brief psk Added the test case line 269. +* @expect 1. Expected connection establishment failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC006() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + &((FRAME_Msg *)0)->body.hsMsg.body.clientHello.keyshares.exState, + Test_MisClientHelloExtension + }; + RegisterWrapper(wrapper); + ResumeTestInfo testInfo = {0}; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_NE(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** + * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTICATE_VERIFY_FAIL_FUNC_TC001 + * @brief 6.3. Error Alerts row 216 + * The client does not support extended master keys and performs negotiation. After receiving the server hello + * message with the extended master keys, the client sends an alert message. Check whether the two parties enter the + * alerted state, and the read and write operations fail. + * + */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTICATE_VERIFY_FAIL_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.s_config != NULL); + testInfo.c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.c_config != NULL); + + HITLS_CFG_SetExtenedMasterSecretSupport(testInfo.c_config, false); + + testInfo.client = FRAME_CreateLink(testInfo.c_config, testInfo.uioType); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLink(testInfo.s_config, testInfo.uioType); + ASSERT_TRUE(testInfo.server != NULL); + ASSERT_EQ(HITLS_SetSession(testInfo.client->ssl, testInfo.clientSession), HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.c_config); + HITLS_CFG_FreeConfig(testInfo.s_config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +static void Test_Client_Mode(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.pskModes.exData.state = ASSIGNED_FIELD; + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.pskModes.exData.data); + uint16_t version[] = { 0x03, }; + frameMsg.body.hsMsg.body.clientHello.pskModes.exData.data = + BSL_SAL_Calloc(sizeof(version) / sizeof(uint8_t), sizeof(uint8_t)); + ASSERT_EQ(memcpy_s(frameMsg.body.hsMsg.body.clientHello.pskModes.exData.data, + sizeof(version), version, sizeof(version)), EOK); + frameMsg.body.hsMsg.body.clientHello.keyshares.exState = MISSING_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.state = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKMODEZERO_FUNC_TC001 +* @spec - +* @title Initialize the client and server to tls1.3. Construct a scenario where the psk is carried but key_share is not +* carried. Construct a scenario where the psk_mode carried in the clienthello message is 3. It is expected +* that the handshake fails. +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation line 11 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKMODEZERO_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Client_Mode + }; + RegisterWrapper(wrapper); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_MISSING_EXTENSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_Server_Keyshare(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + frameMsg.body.hsMsg.body.serverHello.keyShare.data.state = ASSIGNED_FIELD; + + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data = *(uint64_t *)user; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001 +* @spec - +* @title Initialize the client server to tls1.3 and construct the selected_group carried in the key_share extension in +* the sent serverhello message. If the group is not the keyshareentry group carried in the client hello message +* but the group provided in the client hello message, the connection fails to be established. +* @precon nan +* @brief 4.2.8. Key Share line 72 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + uint64_t groupreturn[] = {HITLS_EC_GROUP_SECP384R1, }; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &groupreturn, + Test_Server_Keyshare + }; + RegisterWrapper(wrapper); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t group[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + HITLS_CFG_SetGroups(testInfo.config, group, 2); + + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_Server_Keyshare3(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_TRUE(frameMsg.body.hsMsg.body.serverHello.keyShare.exState == MISSING_FIELD); + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC001 +* @spec - +* @title 1. Initialize the client and server to tls1.3 and construct a scenario where psk_ke is used. The expected +* serverhello message sent does not carry the key_share extension. +* @precon nan +* @brief 4.2.8. Key Share line 73 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Server_Keyshare3 + }; + RegisterWrapper(wrapper); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +static void Test_Server_Keyshare4(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + frameMsg.body.hsMsg.body.serverHello.keyShare.exState = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.keyShare.exLen.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.keyShare.data.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data = HITLS_EC_GROUP_CURVE25519; + + FRAME_ModifyMsgInteger(HS_EX_TYPE_KEY_SHARE, &frameMsg.body.hsMsg.body.serverHello.keyShare.exType); + uint8_t uu[] = {0x3b, 0xb5, 0xe4, 0x3c, 0xf6, 0xc4, 0x70, 0x0f, 0x3c, 0x7f, 0x05, 0x0b, 0xd4, 0xfb, 0x24, 0x39, + 0xc8, 0xb6, 0x13, 0x50, 0xc6, 0xee, 0xde, 0x69, 0xc5, 0x09, 0xef, 0x2e, 0x21, 0x4d, 0xd8, 0x1e}; + FRAME_ModifyMsgArray8(uu, sizeof(uu), &frameMsg.body.hsMsg.body.serverHello.keyShare.data.keyExchange, + &frameMsg.body.hsMsg.body.serverHello.keyShare.data.keyExchangeLen); + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC002 +* @spec - +* @title 1. Initialize the client and server to tls1.3, construct the psk_ke scenario, and construct the sent +* serverhello message carrying the key_share extension. It is expected that the connection fails to be +* established. +* @precon nan +* @brief 4.2.8. Key Share line 73 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC002() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_Server_Keyshare4}; + RegisterWrapper(wrapper); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + + testInfo.config = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(testInfo.config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + HITLS_CFG_SetPskServerCallback(testInfo.config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(testInfo.config, (HITLS_PskClientCb)ExampleClientCb); + testInfo.client = FRAME_CreateLink(testInfo.config, testInfo.uioType); + HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY); + testInfo.server = FRAME_CreateLink(testInfo.config, testInfo.uioType); + + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT), + HITLS_MSG_HANDLE_HANDSHAKE_FAILURE); + + ALERT_Info info = {0}; + ALERT_GetInfo(testInfo.client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001 +* @spec - +* @title The supported_versions in the clientHello is extended to 0x0304 (TLS 1.3). If the server supports only 1.2, the +* server returns a "protocol_version" warning and the handshake fails. +* @precon nan +* @brief Appendix D. Backward Compatibility line 247 +* @expect +* 1. The setting is successful. +* 2. The setting is successful. +* 3. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config_c = HITLS_CFG_NewTLS13Config(); + config_s = HITLS_CFG_NewTLS12Config(); + + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->cipherSuites.data[0] = 0xC02F; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(serverTlsCtx->hsCtx->state, TRY_SEND_CERTIFICATE); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC004 +* @spec - +* @title clientHello version is 0x0303 and the server supports only 1.3. The server returns "protocol_version" and the +* handshake fails. +* @precon nan +* @brief Appendix D. Backward Compatibility line 247 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC004() +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config_c = HITLS_CFG_NewTLS12Config(); + config_s = HITLS_CFG_NewTLS13Config(); + + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC005 +* @spec - +* @titleSet that the server supports only TLS 1.2 and the client supports TLS 1.3. ClientHello legacy_version contains + 0x0303 (TLS 1.2). The supported_versions field is extended to 0x0304 and 0x0303. The server responds with + serverHello and ServerHello.version is 0x0303, The client agrees to use this version, and the handshake + negotiation is successful. +* @precon nan +* @brief Appendix D. Backward Compatibility line 245 +* @expect 1. The handshake negotiation is successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC005() +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config_c = HITLS_CFG_NewTLSConfig(); + config_s = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config_c, TLS12_VERSION_BIT|TLS13_VERSION_BIT) == HITLS_SUCCESS); + + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC006 +* @spec - +* @title: The server supports only TLS 1.2, and the client supports TLS 1.3. ClientHello legacy_version contains 0x0303 +* (TLS 1.2). The supported_versions field is extended to 0x0304 and 0x0303. The server responds with +* serverHello and ServerHello.version is 0x0303, The client agrees to use this version. The connection +* establishment is interrupted, and the session is restored. The restoration is successful. +* @precon nan +* @brief Appendix D. Backward Compatibility line 245 +* @expect 1. The handshake negotiation is successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC006() +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config_c = HITLS_CFG_NewTLSConfig(); + config_s = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config_c, TLS12_VERSION_BIT|TLS13_VERSION_BIT) == HITLS_SUCCESS); + + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + HITLS_Session *clientSession = NULL; + clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + FRAME_FreeLink(server); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +static void Test_SERVERHELLO_VERSION(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + frameMsg.body.hsMsg.body.serverHello.version.data = 0x0301; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC007 +* @spec - +* @titleSet that the server supports only TLS 1.2 and the client supports TLS 1.3. ClientHello legacy_version contains +* 0x0303 (TLS 1.2), and supported_versions is extended to 0x0304, 0x0303, and 0x0301: The server responds with +* serverHello. The value of ServerHello.version is 0x0303. The client agrees to use this version. The +* connection establishment is interrupted and the session is restored, Before the client receives the +* ServerHello message, the session fails to be resumed after Server.version is changed to 0x0301. +* @precon nan +* @brief Appendix D. Backward Compatibility line 245 +* @expect 1. Failed to restore the session. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC007() +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config_c = HITLS_CFG_NewTLSConfig(); + config_s = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config_c, TLS12_VERSION_BIT | TLS13_VERSION_BIT) == + HITLS_SUCCESS); + + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + HITLS_Session *clientSession = NULL; + clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + FRAME_FreeLink(server); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_SERVERHELLO_VERSION}; + RegisterWrapper(wrapper); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKETLIFETIME_FUNC_TC001 +* @spec - +* @title Set the life cycle of ticket_lifetime to 10s. After the first connection is established, send the session using the +* ticket through the client to resume, The server processes the message 10 seconds after receiving the ticket. The +* server determines that the ticket has expired and the session fails to be restored. +* @precon nan +* @brief 4.6.1. New Session Ticket Message line 164 +* @expect 1. Expected handshake failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKETLIFETIME_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetSessionTimeout(testInfo.config, 10); + + ASSERT_EQ(DoHandshake(&testInfo), HITLS_SUCCESS); + + testInfo.clientSession = HITLS_GetDupSession(testInfo.client->ssl); + ASSERT_TRUE(testInfo.clientSession != NULL); + + FRAME_FreeLink(testInfo.client); + testInfo.client = NULL; + FRAME_FreeLink(testInfo.server); + testInfo.server = NULL; + HITLS_CFG_FreeConfig(testInfo.config); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, testInfo.clientSession), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + sleep(11); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 0); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(testInfo.clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC001 +* @spec - +* @title Certificate chain: ecdsa_secp256r1_sha256. If the signature algorithm is ecdsa_secp256r1_sha256, the certificate +* and certificate chain are successfully verified. +* @precon nan +* @brief 9.1. Mandatory-to-Implement Cipher Suites line 229 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256, CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + ASSERT_TRUE(HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t))== HITLS_SUCCESS); + + FRAME_CertInfo certInfo = { + "rsa_sha/ca-3072.der:rsa_sha/inter-3072.der", + NULL, NULL, NULL, NULL, NULL,}; + + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC002 +* @spec - +* @title Certificate chain: ecdsa_secp256r1_sha256. If the signature algorithm is ecdsa_secp256r1_sha256, the +* certificate and certificate chain are successfully verified. +* @precon nan +* @brief 9.1. Mandatory-to-Implement Cipher Suites line 229 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256 }; + ASSERT_TRUE(HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t))== HITLS_SUCCESS); + + FRAME_CertInfo certInfo1 = { + "rsa_pss_rsae/rsa_root.der:rsa_pss_rsae/rsa_intCa.der", + NULL, NULL, NULL, NULL, NULL,}; + FRAME_CertInfo certInfo2 = { + "rsa_pss_rsae/rsa_root.der:rsa_pss_rsae/rsa_intCa.der", + "rsa_pss_rsae/rsa_intCa.der", "rsa_pss_rsae/rsa_dev.der", NULL, "rsa_pss_rsae/rsa_dev.key.der", NULL,}; + + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo1); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo2); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC003 +* @spec - +* @title Certificate chain: ecdsa_secp256r1_sha256. If the signature algorithm is ecdsa_secp256r1_sha256, the +* certificate and certificate chain are successfully verified. +* @precon nan +* @brief 9.1. Mandatory-to-Implement Cipher Suites line 229 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + ASSERT_TRUE(HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t))== HITLS_SUCCESS); + + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der:ecdsa/inter-nist521.der", + NULL, NULL, NULL, NULL, NULL,}; + + client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +* @spec - +* @title After the server negotiates the version number for the first time, the serverHello, Certificate, Server Key +* Exchange, Certificate Request, Server Hello Done, Certificate, Certificate Key Exchange, The +* legacy_record_version of all record messages, such as Certificate Verify, Change Cipher Spec, and Finished, +* is the negotiated version. +* @precon nan +* @brief Appendix D. Backward Compatibility line 242 +* @expect 1. The expected version number is the negotiated version. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001(int flag, int type) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FrameUioUserData *ioUserData = NULL; + + config = HITLS_CFG_NewTLS12Config(); + HITLS_CFG_SetClientVerifySupport(config, true); + + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, flag, type) == HITLS_SUCCESS); + + if (flag == 1) { + HITLS_Connect(client->ssl); + ioUserData = BSL_UIO_GetUserData(client->io); + } else { + HITLS_Accept(server->ssl); + ioUserData = BSL_UIO_GetUserData(server->io); + } + uint8_t *recvBuf = ioUserData->sndMsg.msg; + uint32_t recvLen = ioUserData->sndMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.recVersion.data, 0x0303); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +* @spec - +* @title Renegotiation. After the server negotiates the version number, the serverHello, Certificate, Server Key +* Exchange, Certificate Request, Server Hello Done, Certificate, Certificate Key Exchange, Certificate Verify, +* Change Cipher Spec, Finished, and other record messages legacy_record_version indicates the renegotiation + version. +* @precon nan +* @brief Appendix D. Backward Compatibility line 242 +* @expect 1. The expected version number is the negotiated version. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002(int flag, int type) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + FrameUioUserData *ioUserData = NULL; + + config = HITLS_CFG_NewTLS12Config(); + HITLS_CFG_SetClientVerifySupport(config, true); + + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_SetRenegotiationSupport(server->ssl, true); + HITLS_SetRenegotiationSupport(client->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(client, server, flag, type), HITLS_SUCCESS); + + if (flag == 1) { + HITLS_Connect(client->ssl); + ioUserData = BSL_UIO_GetUserData(client->io); + } else { + HITLS_Accept(server->ssl); + ioUserData = BSL_UIO_GetUserData(server->io); + } + uint8_t *recvBuf = ioUserData->sndMsg.msg; + uint32_t recvLen = ioUserData->sndMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS12, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsgHeader(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.recVersion.data, 0x0303); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_2.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_2.data new file mode 100644 index 00000000..96bf3081 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_extensions_2.data @@ -0,0 +1,126 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSK_MODES_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTICATE_VERIFY_FAIL_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERTICATE_VERIFY_FAIL_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKMODEZERO_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKMODEZERO_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKKEYSHARE_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC007: + + +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKETLIFETIME_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKETLIFETIME_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CERT_SIGNATURE_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_CHANGE_CIPHER_SPEC + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_SERVER_HELLO + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_CERTIFICATE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_SERVER_KEY_EXCHANGE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_CERTIFICATE_REQUEST + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_SERVER_HELLO_DONE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:true:TRY_SEND_CLIENT_KEY_EXCHANGE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:true:TRY_SEND_CERTIFICATE_VERIFY + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:true:TRY_SEND_CERTIFICATE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:true:TRY_SEND_FINISH + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC001:false:TRY_SEND_FINISH + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_CHANGE_CIPHER_SPEC + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_SERVER_HELLO + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_CERTIFICATE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_SERVER_KEY_EXCHANGE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_CERTIFICATE_REQUEST + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_SERVER_HELLO_DONE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:true:TRY_SEND_CLIENT_KEY_EXCHANGE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:true:TRY_SEND_CERTIFICATE_VERIFY + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:true:TRY_SEND_CERTIFICATE + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:true:TRY_SEND_FINISH + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECVERSION_FUNC_TC002:false:TRY_SEND_FINISH \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_kex.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_kex.c new file mode 100644 index 00000000..e3a5bd7c --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_kex.c @@ -0,0 +1,4991 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "hitls_error.h" +#include "tls.h" +#include "change_cipher_spec.h" +#include "frame_tls.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_link.h" +#include "frame_io.h" +#include "frame_msg.h" +#include "simulate_io.h" +#include "stub_replace.h" +#include "hs.h" +#include "alert.h" +#include "bsl_sal.h" +#include "securec.h" +#include "app.h" +#include "hs_kx.h" +#include "hs_msg.h" +#include "rec.h" +#include "conn_init.h" +#include "parse.h" +#include "hs_common.h" +#include "common_func.h" +#include "hlt.h" +#include "process.h" +#include "hitls_crypt_init.h" +#include "rec_wrapper.h" + +#define REC_TLS_RECORD_HEADER_LEN 5 +#define ALERT_BODY_LEN 2u +#define READ_BUF_SIZE 18432 +#define ERROR_VERSION_BIT 0x00000000U +#define READ_BUF_LEN_18K (18 * 1024) +#define BUF_SIZE_DTO_TEST (18 * 1024) +#define ROOT_DER "%s/ca.der:%s/inter.der" +#define INTCA_DER "%s/inter.der" +#define SERVER_DER "%s/server.der" +#define SERVER_KEY_DER "%s/server.key.der" +#define CLIENT_DER "%s/client.der" +#define CLIENT_KEY_DER "%s/client.key.der" +static char *g_serverName = "testServer"; +uint32_t g_uiPort = 18890; +/* END_HEADER */ + +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, uint8_t *text, uint32_t *textLen, uint8_t *recType); +int32_t STUB_RecParseInnerPlaintext(TLS_Ctx *ctx, uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + (void)ctx; + (void)text; + (void)textLen; + *recType = (uint8_t)REC_TYPE_APP; + + return HITLS_SUCCESS; +} + +void SetFrameType(FRAME_Type *frametype, uint16_t versionType, REC_Type recordType, HS_MsgType handshakeType, + HITLS_KeyExchAlgo keyExType) +{ + frametype->versionType = versionType; + frametype->recordType = recordType; + frametype->handshakeType = handshakeType; + frametype->keyExType = keyExType; +} + +void TestSetCertPath(HLT_Ctx_Config *ctxConfig, char *SignatureType) +{ + if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA1", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA1")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA256")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA256_EE_PATH3, RSA_SHA256_PRIV_PATH3, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA384")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA384_EE_PATH, RSA_SHA384_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA512")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA512_EE_PATH, RSA_SHA512_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + strlen("CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA256_EE_PATH, + ECDSA_SHA256_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384", + strlen("CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA384_EE_PATH, + ECDSA_SHA384_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512", + strlen("CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA512_EE_PATH, + ECDSA_SHA512_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_ECDSA_SHA1", strlen("CERT_SIG_SCHEME_ECDSA_SHA1")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA1_CA_PATH, + ECDSA_SHA1_CHAIN_PATH, + ECDSA_SHA1_EE_PATH, + ECDSA_SHA1_PRIV_PATH, + "NULL", + "NULL"); + } +} + +static int SetCertPath(HLT_Ctx_Config *ctxConfig, const char *certStr, bool isServer) +{ + char caCertPath[50]; + char chainCertPath[30]; + char eeCertPath[30]; + char privKeyPath[30]; + + int32_t ret = sprintf_s(caCertPath, sizeof(caCertPath), ROOT_DER, certStr, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(chainCertPath, sizeof(chainCertPath), INTCA_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(eeCertPath, sizeof(eeCertPath), isServer ? SERVER_DER : CLIENT_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(privKeyPath, sizeof(privKeyPath), isServer ? SERVER_KEY_DER : CLIENT_KEY_DER, certStr); + ASSERT_TRUE(ret > 0); + HLT_SetCaCertPath(ctxConfig, (char *)caCertPath); + HLT_SetChainCertPath(ctxConfig, (char *)chainCertPath); + HLT_SetEeCertPath(ctxConfig, (char *)eeCertPath); + HLT_SetPrivKeyPath(ctxConfig, (char *)privKeyPath); + return 0; +exit: + return -1; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVE_RENEGOTIATION_REQUEST_FUNC_TC001 +* @spec Because TLS 1.3 forbids renegotiation, if a server has negotiated +* TLS 1.3 and receives a ClientHello at any other time, it MUST +* terminate the connection with an "unexpected_message" alert. +* @title Initialize the client server to tls1.3. After the connection is established, the client sends a client hello message. +* The expected server sends an alarm after receiving the message and disconnects the connection. +* @precon nan +* @brief 4.1.1. ryptographic Negotiation row15 +* Initialize the client server to tls1.3. After the connection is established, the client sends a client hello +* message. +* The expected server sends an alarm after receiving the message and disconnects the connection. +* @expect 1. The server sends an alarm and the connection is disconnected. + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVE_RENEGOTIATION_REQUEST_FUNC_TC001() +{ + FRAME_Init(); + /* Initialize the client server to tls1.3. */ + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportRenegotiation = true; + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + /* After the connection is established, the client sends a client hello message. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + + FrameMsg recMsg = {0}; + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg + REC_TLS_RECORD_HEADER_LEN, + ioServerData->recMsg.len - REC_TLS_RECORD_HEADER_LEN) == EOK); + recMsg.len = ioServerData->recMsg.len - 5; + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS13); + ASSERT_TRUE(clientTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS13); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(REC_Write(clientTlsCtx, REC_TYPE_HANDSHAKE, recMsg.msg, recMsg.len), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +static void Test_ModifyClientHello(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->supportedVersion.exState = MISSING_FIELD; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_FUNC_TC001 +* @spec random: 32 bytes generated by a secure random number generator. See +* Appendix C for additional information. The last 8 bytes MUST be +* overwritten as described below if negotiating TLS 1.2 or TLS 1.1, +* but the remaining bytes MUST be random. This structure is +* generated by the server and MUST be generated independently of the ClientHello.random. +* @title Initialize the client and server to tls1.3. Delete the supportversion extension when sending clienthello +* messages. +* After receiving the message, the server negotiates with the TLS1.2 and returns the serverhello after the random +* number is overwrritened. +* After receiving the serverhello message, the client checks the random number and sends the + ALERT_ELLEGAL_PARAMETER alarm. +* @precon nan +* @brief 4.1.3. Server Hello row24 +* Initialize the client server to tls1.3 and delete the supportversion extension when sending client hello +* messages. +* After receiving the message, the server negotiates TLS1.2 and returns the serverhello after the random number is +* overwrritened. +* After receiving the serverhello message, the client checks the random number and sends the +ALERT_LOCKGAL_PARAMETER a larm. +* @expect 1. The client sends the ALERT_AIRGAL_PARAMETER alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_FUNC_TC001() +{ + FRAME_Init(); + /* Initialize the client and server to tls1.3. Delete the supportversion extension when sending clienthello + * messages. */ + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }; + ASSERT_TRUE( + HITLS_CFG_SetCipherSuites(tlsConfig, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_CFG_SetVersionSupport(tlsConfig, 0x00000030U); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyClientHello}; + RegisterWrapper(wrapper); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + /* After receiving the message, the server negotiates with the TLS1.2 and returns the serverhello after the random + * number is overwrritened. */ + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + /* After receiving the serverhello message, the client checks the random number and sends the + * ALERT_ELLEGAL_PARAMETER alarm. */ + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC001 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client. The certificate is received after the clienthello message is sent. +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, receiving the certificate after sending the clienthello message. +* @expect 1. Return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + FRAME_LinkObj *client2 = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server2 = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client2 != NULL); + ASSERT_TRUE(server2 != NULL); + HITLS_Ctx *clientTlsCtx2 = FRAME_GetTlsCtx(client2); + HITLS_Ctx *serverTlsCtx2 = FRAME_GetTlsCtx(server2); + ASSERT_TRUE(FRAME_CreateConnection(client2, server2, true, TRY_RECV_CERTIFICATE_REQUEST) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx2->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx2->state == CM_STATE_HANDSHAKING); + char *buffer = BSL_SAL_Calloc(1u, MAX_RECORD_LENTH); + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(client2->io); + uint8_t *recvBuf2 = ioUserData2->recMsg.msg; + uint32_t recvLen2 = ioUserData2->recMsg.len; + memcpy_s(buffer, MAX_RECORD_LENTH, recvBuf2, recvLen2); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_EQ(FRAME_TransportRecMsg(client->io, buffer, recvLen2), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + FRAME_FreeLink(client2); + FRAME_FreeLink(server2); + BSL_SAL_FREE(buffer); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC002 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client, unidirectional authentication, certificateverify received after receiving the serverhello message +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, unidirectional authentication, certificateverify received after receiving the server hello message +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC002() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + client->ssl->hsCtx->state = TRY_RECV_ENCRYPTED_EXTENSIONS; + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC003 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client, two-way authentication, certificate received after receiving the serverhello message +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, two-way authentication, certificate received after receiving the serverhello message +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + client->ssl->hsCtx->state = TRY_RECV_ENCRYPTED_EXTENSIONS; + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC004 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client, two-way authentication, receiving certificateverify after receiving certificaterequest +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, two-way authentication, receiving certificateverify after receiving certificaterequest +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ + /* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC004() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + client->ssl->hsCtx->state = TRY_RECV_CERTIFICATE; + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC005 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client, unidirectional authentication. After receiving the certificate, the client receives the finished message. +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, unidirectional authentication. After receiving the certificate, the client receives the finished message. +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC005() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + client->ssl->hsCtx->state = TRY_RECV_CERTIFICATE_VERIFY; + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC006 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client, unidirectional authentication, receiving appdata after receiving certificateverify +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, unidirectional authentication, receiving appdata after receiving certificateverify +* @expect 1. Return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC006() +{ + FRAME_Init(); + + STUB_Init(); + FuncStubInfo tmpRpInfo = { 0 }; + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + STUB_Replace(&tmpRpInfo, RecParseInnerPlaintext, STUB_RecParseInnerPlaintext); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&tmpRpInfo); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC007 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title Client, unidirectional authentication, certificateverify received after receiving encryptedextensions +* @precon nan +* @brief 4.Handshake Protocol row9 +* Client, unidirectional authentication, certificateverify received after receiving encryptedextensions +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC007() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + client->ssl->hsCtx->state = TRY_RECV_CERTIFICATE_REQUEST; + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC008 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title The server receives the certificate message in idle state. +* @precon nan +* @brief 4.Handshake Protocol row9 +* The server receives a certificate message in idle state. +* @expect 1. Return HITLS_CM_LINK_UNESTABLICED +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC008() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FRAME_LinkObj *client2 = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server2 = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client2 != NULL); + ASSERT_TRUE(server2 != NULL); + HITLS_Ctx *clientTlsCtx2 = FRAME_GetTlsCtx(client2); + HITLS_Ctx *serverTlsCtx2 = FRAME_GetTlsCtx(server2); + + ASSERT_TRUE(FRAME_CreateConnection(client2, server2, false, TRY_RECV_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx2->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx2->state == CM_STATE_HANDSHAKING); + + char *buffer = BSL_SAL_Calloc(1u, MAX_RECORD_LENTH); + FrameUioUserData *ioUserData2 = BSL_UIO_GetUserData(server2->io); + uint8_t *recvBuf2 = ioUserData2->recMsg.msg; + uint32_t recvLen2 = ioUserData2->recMsg.len; + memcpy_s(buffer, MAX_RECORD_LENTH, recvBuf2, recvLen2); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_EQ(FRAME_TransportRecMsg(server->io, buffer, recvLen2), HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_CM_LINK_UNESTABLISHED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + FRAME_FreeLink(client2); + FRAME_FreeLink(server2); + BSL_SAL_FREE(buffer); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC009 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title The server uses unidirectional authentication. The certificate message is received after the client hello message is received. +* @precon nan +* @brief 4.Handshake Protocol row9 +* Server, unidirectional authentication, certificate message received after receiving client hello messages. +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC009() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + server->ssl->hsCtx->state = TRY_RECV_FINISH; + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC010 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title server, unidirectional authentication, receiving the app message after receiving the client hello message +* @precon nan +* @brief 4.Handshake Protocol row9 +* Server, unidirectional authentication, receiving the app message after receiving the client hello message +* @expect 1. Return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC010() +{ + FRAME_Init(); + + STUB_Init(); + FuncStubInfo tmpRpInfo = { 0 }; + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + STUB_Replace(&tmpRpInfo, RecParseInnerPlaintext, STUB_RecParseInnerPlaintext); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&tmpRpInfo); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC011 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title server, two-way authentication, certificateverify message received after client hello is received +* @precon nan +* @brief 4.Handshake Protocol row9 +* The server, two-way authentication, receives the certificateverify message after receiving the client hello +* message. +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE + +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC011() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + server->ssl->hsCtx->state = TRY_RECV_CERTIFICATE; + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC012 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title server, two-way authentication, receiving the finish message after receiving the certificate message +* @precon nan +* @brief 4.Handshake Protocol row9 +* The server, two-way authentication, receives the finish message after receiving the certificate message. +* @expect 1. Return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC012() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = false; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + server->ssl->hsCtx->state = TRY_RECV_CERTIFICATE_VERIFY; + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC013 +* @spec Protocol messages MUST be sent in the order defined in Section 4.4.1 +* and shown in the diagrams in Section 2. A peer which receives a +* handshake message in an unexpected order MUST abort the handshake +* with an "unexpected_message" alert. +* @title server, two-way authentication, receiving the app message after receiving the certificateverify message +* @precon nan +* @brief 4.Handshake Protocol row9 +* The server, two-way authentication, receives the app message after receiving the certificateverify message. +* @expect 1. Return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC013() +{ + FRAME_Init(); + + STUB_Init(); + FuncStubInfo tmpRpInfo = { 0 }; + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + STUB_Replace(&tmpRpInfo, RecParseInnerPlaintext, STUB_RecParseInnerPlaintext); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&tmpRpInfo); +} +/* END_CASE */ + +static void Test_ModifyClientHelloNullKeyshare(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->keyshares.exLen.data = 2; + clientMsg->keyshares.exKeyShareLen.data = 0; + clientMsg->keyshares.exKeyShares.state = MISSING_FIELD; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NULL_KEYSHARE_FUNC_TC001 +* @spec If the server selects an (EC)DHE group and the client did not offer a +* compatible "key_share" extension in the initial ClientHello, the +* server MUST respond with a HelloRetryRequest (Section 4.1.4) message. +* @title Construct the clienthello message sent by the client. The key_share extension is empty and the psk extension is + not carried. The server is expected to send a hellorequest message. +* @precon nan +* @brief 4.Handshake Protocol row9 +* Construct the client hello message sent by the client. The key_share extension is empty and the psk extension is + not carried. The server is expected to send a hellorequest message. +* @expect 1. The server sends hrr and waits for receiving the second client hello. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_NULL_KEYSHARE_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_ModifyClientHelloNullKeyshare}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ClearWrapper(); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC001 +* @spec When a client first connects to a server, it is REQUIRED to send the +* ClientHello as its first TLS message. The client will also send a +* ClientHello when the server has responded to its ClientHello with a +* HelloRetryRequest. In that case, the client MUST send the same +* ClientHello without modification, except as follows: +* @title 1. Set the client server to tls1.3. Set the first group server not to support the client, but the second group +* server to support the client, +* The server is expected to send a helloretryrequest message. The client hello message is sent after the client +* hello message is updated. The group in the keyshare of the client hello message is changed. The connection is +* expected to be successfully set up. +* @precon nan +* @brief 4.1.2. Client Hello row14 +* 1. Set the client server to tls1.3. Set the first group server to not support the client server, and set the +* second group server to support the client server. +* The server is expected to send a helloretryrequest message. The client hello message is sent after the client +* hello message is updated. The group in the keyshare of the client hello message is changed. The connection is +* expected to be successfully established. +* @expect 1. The server sends hrr and the connection is successfully established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC001() +{ + FRAME_Init(); + /* Set the client server to tls1.3. Set the first group server not to support the client, but the second group + * server to support the client */ + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC002 +* @spec When a client first connects to a server, it is REQUIRED to send the +* ClientHello as its first TLS message. The client will also send a +* ClientHello when the server has responded to its ClientHello with a +* HelloRetryRequest. In that case, the client MUST send the same +* ClientHello without modification, except as follows: +* @title 1. Set the client server to tls1.3. Set the first group server not to support the client, but the second group +* server to support the client, +* The server is expected to send a helloretryrequest message, construct the same client hello message sent by the +* client, and the server is expected to reject connection establishment. +* @precon nan +* @brief 4.1.2. Client Hello row14 +* 1. Set the client server to tls1.3. Set the first group server not to support the client, and the second group +* server to support the client. +* The server is expected to send a helloretryrequest message, construct the same client hello message sent by the +* client, and the server is expected to reject connection establishment. +* @expect 1. Link establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + char *buffer = BSL_SAL_Calloc(1u, MAX_RECORD_LENTH); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + memcpy_s(buffer, MAX_RECORD_LENTH, recvBuf, recvLen); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, recvBuf, recvLen) == HITLS_SUCCESS); + ioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_INVALID_PROTOCOL_VERSION); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + BSL_SAL_FREE(buffer); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC003 +* @spec When a client first connects to a server, it is REQUIRED to send the +* ClientHello as its first TLS message. The client will also send a +* ClientHello when the server has responded to its ClientHello with a +* HelloRetryRequest. In that case, the client MUST send the same +* ClientHello without modification, except as follows: +* @titleSet the client server to tls1.3, and set the first group server not to support the client, and the second group +* server to support the client, +* The hash of the cipher suite on the server does not match the hash corresponding to the psk set on the +* client. The server is expected to send a helloretryrequest message, +* The client resends the client hello message and removes the psk extension. +* @precon nan +* @brief 4.1.2. Client Hello row14 +* Set the client server to tls1.3. Set the first group server not to support the client, but the second group +* server to support the client, +* The hash of the cipher suite on the server does not match the hash corresponding to the psk set on the +* client. The server is expected to send a helloretryrequest message, +* The client resends the client hello message and removes the psk extension. +* @expect 1. The second clienthello does not contain the psk. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Session *Session = {0}; + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + Session = HITLS_GetDupSession(client->ssl); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(HITLS_SetSession(client->ssl, Session) == HITLS_SUCCESS); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(clientMsg->psks.exState == INITIAL_FIELD); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + + ioUserData = BSL_UIO_GetUserData(client->io); + recvBuf = ioUserData->recMsg.msg; + recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->cipherSuite.data = HITLS_AES_128_GCM_SHA256; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ioUserData = BSL_UIO_GetUserData(server->io); + recvBuf = ioUserData->recMsg.msg; + recvLen = ioUserData->recMsg.len; + + parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(clientMsg->psks.exState == MISSING_FIELD); + FRAME_CleanMsg(&frameType, &frameMsg); +exit: + HITLS_SESS_Free(Session); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC001 +* @spec If a server established a TLS connection with a previous version of +* TLS and receives a TLS 1.3 ClientHello in a renegotiation, it MUST +* retain the previous protocol version. In particular, it MUST NOT +* negotiate TLS 1.3. +* @title 1. On the server end of 1.3, after the connection between 1.2 and 1.2 is successfully established, initiate + renegotiation and change the client version to 1.3. The supported version includes tls1.2. The expected version + is tls1.2. +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation row16 +* 1. On the 1.3 server, after the 1.2 connection is successfully established, initiate renegotiation and change the + client version to 1.3. The supported version includes tls1.2. The tls1.2 version is expected to be negotiated. +* @expect 1. The TLS1.2 version is expected to be negotiated. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLS13Config(); + tlsConfig_s->isSupportClientVerify = true; + tlsConfig_s->isSupportRenegotiation = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE( + HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLSConfig(); + HITLS_CFG_SetVersionSupport(tlsConfig_c, 0x00000010U); + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + tlsConfig_c->isSupportRenegotiation = true; + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + ASSERT_TRUE(clientTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + + HITLS_CFG_SetVersionSupport(&(clientTlsCtx->config.tlsConfig), 0x00000030U); + ASSERT_EQ(HITLS_Renegotiate(clientTlsCtx), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_RENEGOTIATION); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + +exit: + HITLS_CFG_FreeConfig(tlsConfig_s); + HITLS_CFG_FreeConfig(tlsConfig_c); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC002 +* @spec If a server established a TLS connection with a previous version of +* TLS and receives a TLS 1.3 ClientHello in a renegotiation, it MUST +* retain the previous protocol version. In particular, it MUST NOT +* negotiate TLS 1.3. +* @title 1. On the server end of 1.2, after the connection is successfully established, the client version is changed to 1.3 +* and the minimum supported version is tls1.3. The renegotiation fails. +* @precon nan +* @brief 4.1.1. Cryptographic Negotiation row16 +* 1. After the connection between the client and the client is set up successfully, the client version is changed +* to 1.3 and the minimum supported version is tls1.3. The renegotiation fails. +* @expect 1. Expected renegotiation failure +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLS13Config(); + tlsConfig_s->isSupportClientVerify = true; + tlsConfig_s->isSupportRenegotiation = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLS12Config(); + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + tlsConfig_c->isSupportRenegotiation = true; + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + ASSERT_TRUE(clientTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + + + ASSERT_EQ(HITLS_Renegotiate(clientTlsCtx), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_RENEGOTIATION); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + HITLS_CFG_SetVersionSupport(&(clientTlsCtx->config.tlsConfig), 0x00000020U); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + +exit: + HITLS_CFG_FreeConfig(tlsConfig_s); + HITLS_CFG_FreeConfig(tlsConfig_c); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001 +* @spec In TLS 1.3, the client indicates its version preferences in the +* "supported_versions" extension (Section 4.2.1) and the +* legacy_version field MUST be set to 0x0303, which is the version +* number for TLS 1.2. TLS 1.3 ClientHellos are identified as having a legacy_version of 0x0303 and a +* supported_versions extension +* present with 0x0304 as the highest version indicated therein. +* @title The client server is initialized to the tls1.3 version, and the legacy_version in the sent clienthello +* message is changed to 0x0302. The server is expected to return an alert. +* @precon nan +* @brief 4.1.2. Client Hello row17 +* The client server is initialized to the tls1.3 version, and the legacy_version in the sent clienthello message +* is changed to 0x0302. The server is expected to return an alert. +* @expect 1. The server sends an alert message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + /* The client server is initialized to the tls1.3 version, and the legacy_version in the sent clienthello + * message is changed to 0x0302 */ + clientMsg->version.data = 0x0302; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC002 +* @spec In TLS 1.3, the client indicates its version preferences in the +* "supported_versions" extension (Section 4.2.1) and the +* legacy_version field MUST be set to 0x0303, which is the version +* number for TLS 1.2. TLS 1.3 ClientHellos are identified as having a legacy_version of 0x0303 and a +* supported_versions extension present with 0x0304 as the highest version indicated therein. +* @title The client server is initialized to the tls1.3 version, and the legacy_version in the sent clienthello +* message is changed to 0x0304. The server is expected to return an alert. +* @precon nan +* @brief 4.1.2. Client Hello row17 +* The client server is initialized to the tls1.3 version, and the legacy_version in the sent clienthello message +* is changed to 0x0304. The server is expected to return an alert. +* @expect 1. The server sends an alert message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + /* The client server is initialized to the tls1.3 version, and the legacy_version in the sent clienthello + * message is changed to 0x0304. */ + clientMsg->version.data = 0x0304; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC001 +* @spec A client which has a cached session ID set by a pre-TLS 1.3 server SHOULD set this field to that value. +* In compatibility mode (see Appendix D.4),this field MUST be non-empty, so a client not offering a +* pre-TLS 1.3 session MUST generate a new 32-byte value. This value need not be random but SHOULD be + unpredictable to avoid +* implementations fixating on a specific value (also known as +* ossification). Otherwise, it MUST be set as a zero-length vector +* (i.e., a zero-valued single byte length field). +* @title Set the client server to tls1.3 and check the legacy_session_id of the sent clienthello message. The value + is a 32-byte value. +* @precon nan +* @brief 4.1.2. Client Hello row18 +* Set the client server to tls1.3 and check the legacy_session_id of the sent clienthello to a 32-byte value. +* @expect 1. Check the session ID. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + /* Set the client server to tls1.3 and check the legacy_session_id of the sent clienthello message. The value + * is a 32-byte value. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_EQ(clientMsg->sessionIdSize.data, 32); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyClientHello_Sessionid_002(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->sessionIdSize.data = 0; + clientMsg->sessionId.size = 0; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} +/* @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC002 +* @spec A client which has a cached session ID set by a pre-TLS 1.3 server SHOULD set this field to that value. +* In compatibility mode (see Appendix D.4),this field MUST be non-empty, so a client not offering a +* pre-TLS 1.3 session MUST generate a new 32-byte value. This value need not be random but SHOULD be + unpredictable to avoid implementations fixating on a specific value (also known as +* ossification). Otherwise, it MUST be set as a zero-length vector +* (i.e., a zero-valued single byte length field). +* @title Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message + to a single byte 0. The expected connection establishment is successful. +* @precon nan +* @brief 4.1.2. Client Hello row18 +* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message + to a single byte 0. The expected connection establishment is successful. +* @expect 1. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + /* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message + * to a single byte 0 */ + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyClientHello_Sessionid_002}; + RegisterWrapper(wrapper); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO), HITLS_SUCCESS); + clientTlsCtx->hsCtx->sessionIdSize = 0; + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC003 +* @spec A client which has a cached session ID set by a pre-TLS 1.3 server SHOULD set this field to that value. +* In compatibility mode (see Appendix D.4),this field MUST be non-empty, so a client not offering a +* pre-TLS 1.3 session MUST generate a new 32-byte value. This value need not be random but SHOULD be +* unpredictable to avoid implementations fixating on a specific value (also known as +* ossification). Otherwise, it MUST be set as a zero-length vector +* (i.e., a zero-valued single byte length field). +* @title Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to +* 2-byte 0. The expected connection establishment failure +* @precon nan +* @brief 4.1.2. Client Hello row18 +* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to +* two bytes 0. The expected connection establishment fails. +* @expect 1. Link establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->sessionIdSize.data = 0; + /* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to + * 2-byte 0. */ + clientMsg->sessionId.size = 2; + clientMsg->sessionId.data[0] = 0x00; + clientMsg->sessionId.data[1] = 0x00; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_PARSE_INVALID_MSG_LEN); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC004 +* @spec A client which has a cached session ID set by a pre-TLS 1.3 server SHOULD set this field to that value. +* In compatibility mode (see Appendix D.4),this field MUST be non-empty, so a client not offering a +* pre-TLS 1.3 session MUST generate a new 32-byte value. This value need not be random but SHOULD be unpredictable + to avoid implementations fixating on a specific value (also known as ossification). Otherwise, it MUST be set as + a zero-length vector +* (i.e., a zero-valued single byte length field). +* @title Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to + 1 byte 1. The expected connection establishment fails. +* @precon nan +* @brief 4.1.2. Client Hello row18 +* Set the client server to tls1.3 and construct the value of legacy_session_id in the clienthello message to 1 + byte 1. The expected connection establishment fails. +* @expect 1. Connect establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC004() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + /* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to + * 1 byte 1. */ + clientMsg->sessionIdSize.data = 1; + clientMsg->sessionId.size = 1; + clientMsg->sessionId.data[0] = 0x01; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_PARSE_INVALID_MSG_LEN); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyClientHello_Sessionid_005(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->sessionIdSize.data = 26; + clientMsg->sessionId.size = 26; + const uint8_t sessionId_temp[26] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + ASSERT_TRUE(memcpy_s(clientMsg->sessionId.data, sizeof(sessionId_temp) / sizeof(uint8_t), + sessionId_temp, sizeof(sessionId_temp) / sizeof(uint8_t)) == 0); + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC005 +* @spec A client which has a cached session ID set by a pre-TLS 1.3 server SHOULD set this field to that value. +* In compatibility mode (see Appendix D.4),this field MUST be non-empty, so a client not offering a +* pre-TLS 1.3 session MUST generate a new 32-byte value. This value need not be random but SHOULD be unpredictable + to avoid implementations fixating on a specific value (also known as ossification). Otherwise, it MUST be set as + a zero-length vector (i.e., a zero-valued single byte length field). +* @title Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to + 26 bytes 0. The expected connection is successfully established.. +* @precon nan +* @brief 4.1.2. Client Hello row18 +* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to + 26 bytes 0. The expected link establishment success. +* @expect 1. Link establishment success. +* @expect 1. Link establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC005() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + /* Set the client server to tls1.3 and construct the value of legacy_session_id in the sent clienthello message to + * 26 bytes 0. */ + RecWrapper wrapper = {TRY_SEND_CLIENT_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ModifyClientHello_Sessionid_005}; + RegisterWrapper(wrapper); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO), HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC001 +* @spec cipher_suites: A list of the symmetric cipher options supported by +* the client, specifically the record protection algorithm +* (including secret key length) and a hash to be used with HKDF, in +* descending order of client preference. Values are defined in +* Appendix B.4. If the list contains cipher suites that the server +* does not recognize, support, or wish to use, the server MUST +* ignore those cipher suites and process the remaining ones as +* usual. If the client is attempting a PSK key establishment, it SHOULD advertise at least one cipher suite +* indicating a Hash associated with the PSK. +* @title clienthello The first three cipher suites are abnormal values, tls1.2 cipher suites, and tls1.3 cipher suites +* that are not configured on the server, The fourth cipher suite is supported by the server. It is expected that +* the server selects the fourth cipher suite to establish a connection. +* @precon nan +* @brief 4.1.2. Client Hello row19 +* The first three cipher suites of client hello are abnormal values, tls1.2 cipher suites, and tls1.3 cipher +* suites that are not configured on the server, +* The fourth cipher suite is supported by the server. It is expected that the server selects the fourth cipher +* suite to establish a connection. +* @expect 1. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *config_c = HITLS_CFG_NewTLS13Config(); + HITLS_Config *config_s = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + config_c->isSupportClientVerify = true; + config_s->isSupportClientVerify = true; + + /* clienthello The first three cipher suites are abnormal values, tls1.2 cipher suites, and tls1.3 cipher suites + * that are not configured on the server, The fourth cipher suite is supported by the server. */ + uint16_t cipherSuits_c[] = { + 0x0041, HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256, HITLS_CHACHA20_POLY1305_SHA256, HITLS_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(config_c, cipherSuits_c, sizeof(cipherSuits_c) / sizeof(uint16_t)); + uint16_t cipherSuits_s[] = {HITLS_AES_256_GCM_SHA384}; + HITLS_CFG_SetCipherSuites(config_s, cipherSuits_s, sizeof(cipherSuits_s) / sizeof(uint16_t)); + + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_SUCCESS); + + ASSERT_TRUE(server->ssl->negotiatedInfo.cipherSuiteInfo.cipherSuite == HITLS_AES_256_GCM_SHA384); + + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC002 +* @spec cipher_suites: A list of the symmetric cipher options supported by +* the client, specifically the record protection algorithm +* (including secret key length) and a hash to be used with HKDF, in +* descending order of client preference. Values are defined in +* Appendix B.4. If the list contains cipher suites that the server +* does not recognize, support, or wish to use, the server MUST +* ignore those cipher suites and process the remaining ones as +* usual. If the client is attempting a PSK key establishment, it SHOULD advertise at least one cipher suite +* indicating a Hash associated with the PSK. +* @title The hash of the configured psk does not match the specified cipher suite when tls1.3 is set on the client +* server. The expected psk does not exist in the client hello. +* @precon nan +* @brief 4.1.2. Client Hello row19 +* When tls1.3 is set on the client and server, the hash of the psk does not match the specified cipher suite. It +* is expected that the psk does not exist in the client hello. +* @expect 1. No psk is expected in the clienthello. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_CFG_SetPskServerCallback(tlsConfig, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(tlsConfig, (HITLS_PskClientCb)ExampleClientCb); + /* The hash of the configured psk does not match the specified cipher suite when tls1.3 is set on the client + * server. */ + uint16_t cipherSuite = HITLS_AES_256_GCM_SHA384; + HITLS_CFG_SetCipherSuites(tlsConfig, &cipherSuite, 1); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + ASSERT_TRUE(clientMsg->psks.exState == MISSING_FIELD); + + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC001 +* @spec legacy_compression_methods: Versions of TLS before 1.3 supported +* compression with the list of supported compression methods being +* sent in this field. For every TLS 1.3 ClientHello, this vector +* MUST contain exactly one byte, set to zero, which corresponds to +* the "null" compression method in prior versions of TLS. If a +* TLS 1.3 ClientHello is received with any other value in this +* field, the server MUST abort the handshake with an +* "illegal_parameter" alert. Note that TLS 1.3 servers might +* receive TLS 1.2 or prior ClientHellos which contain other +* compression methods and (if negotiating such a prior version) MUST follow the procedures for the appropriate +* prior version of TLS. +* @title Construct clienthello compression algorithm. The value is 0. The server is expected to return a decode +* error alert. +* @precon nan +* @brief 4.1.2. Client Hello row20 +* Construct the clienthello compression algorithm with a two-byte value and the value 0. The server is +* expected to return a decode error alert. +* @expect 1. Return the decode error alert. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + /* Construct clienthello compression algorithm. The value is 0. */ + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->compressionMethodsLen.data = 2; + clientMsg->compressionMethods.data = realloc(clientMsg->compressionMethods.data, 2 * sizeof(uint8_t)); + clientMsg->compressionMethods.size = 2; + clientMsg->compressionMethods.data[0] = 0x00; + clientMsg->compressionMethods.data[1] = 0x00; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC002 +* @spec legacy_compression_methods: Versions of TLS before 1.3 supported +* compression with the list of supported compression methods being +* sent in this field. For every TLS 1.3 ClientHello, this vector +* MUST contain exactly one byte, set to zero, which corresponds to +* the "null" compression method in prior versions of TLS. If a +* TLS 1.3 ClientHello is received with any other value in this +* field, the server MUST abort the handshake with an +* "illegal_parameter" alert. Note that TLS 1.3 servers might +* receive TLS 1.2 or prior ClientHellos which contain other +* compression methods and (if negotiating such a prior version) MUST follow the procedures for the appropriate +* prior version of TLS. +* @title Constructs clienthello compression algorithm. The value is 1, indicating that the server returns +* illegal_parameter alert. +* @precon nan +* @brief 4.1.2. Client Hello row20 +* Construct the clienthello compression algorithm with a bit of one byte and the value is 1. The server is +* expected to return illegal_parameter alert. +* @expect 1. Return ALERT_ELLEGAL_PARAMETER +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + /* Construct the clienthello compression algorithm with a bit of one byte and the value is 1. */ + clientMsg->compressionMethodsLen.data = 1; + clientMsg->compressionMethods.size = 1; + clientMsg->compressionMethods.data[0] = 0x01; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC003 +* @spec legacy_compression_methods: Versions of TLS before 1.3 supported +* compression with the list of supported compression methods being +* sent in this field. For every TLS 1.3 ClientHello, this vector +* MUST contain exactly one byte, set to zero, which corresponds to +* the "null" compression method in prior versions of TLS. If a +* TLS 1.3 ClientHello is received with any other value in this +* field, the server MUST abort the handshake with an +* "illegal_parameter" alert. Note that TLS 1.3 servers might +* receive TLS 1.2 or prior ClientHellos which contain other +* compression methods and (if negotiating such a prior version) MUST follow the procedures for the appropriate +* prior version of TLS. +* @title Construct that the client version is TLS1.2 and the server version is TLS1.3. It is expected that the connection +* can be set up normally. +* @precon nan +* @brief 4.1.2. Client Hello row20 +* Construct the scenario where the client version is TLS1.2 and the server version is TLS1.3 and the expected +* connection establishment is normal. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLS13Config(); + tlsConfig_s->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLS12Config(); + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); + ASSERT_TRUE(clientTlsCtx->negotiatedInfo.version == HITLS_VERSION_TLS12); +exit: + HITLS_CFG_FreeConfig(tlsConfig_s); + HITLS_CFG_FreeConfig(tlsConfig_c); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_UNKNOWN_EXTENSION_FUNC_TC001 +* @spec extensions: Clients request extended functionality from servers by +* sending data in the extensions field. The actual "Extension" +* format is defined in Section 4.2. In TLS 1.3, the use of certain extensions is mandatory, as functionality has +* moved into extensions to preserve ClientHello compatibility with previous +* versions of TLS. Servers MUST ignore unrecognized extensions +* @title Set the client server to tls1.3, construct a client hello message that carries the sni extension, and change +* the sni extension type to 55 (unknown extension). It is expected that the server can establish a connection normally. +* @precon nan +* @brief 4.1.2. Client Hello row21 +* Set the client server to tls1.3, construct a client hello message that carries the SNI extension, and change the +* SNI extension type to 55 (unknown extension). The server is expected to establish a connection normally. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_UNKNOWN_EXTENSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetServerName(tlsConfig, (uint8_t *)g_serverName, (uint32_t)strlen(g_serverName)); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = {0}; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + /** Set the client server to tls1.3, construct a client hello message that carries the sni extension, and change + * the sni extension type to 55 (unknown extension). */ + clientMsg->serverName.exType.data = 55; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_ENCRYPTED_EXTENSIONS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC001 +* @spec TLS 1.3 servers will need to perform this check first and +* only attempt to negotiate TLS 1.3 if the "supported_versions" +* extension is present. If negotiating a version of TLS prior to 1.3, +* a server MUST check that the message either contains no data after +* legacy_compression_methods or that it contains a valid extensions +* block with no data following. If not, then it MUST abort the +* handshake with a "decode_error" alert. +* @title: Set tls1.2 on the client and tls1.3 on the server. Construct the clienthello compression algorithm without +* any extension. It is expected that the server can establish a connection. +* @precon nan +* @brief 4.1.2. Client Hello row22 +* Set TLS 1.2 on the client and TLS 1.3 on the server. Construct the clienthello compression algorithm without +* any extension. It is expected that the server can establish a connection. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLSConfig(); + tlsConfig_s->isSupportExtendMasterSecret = false; + tlsConfig_s->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_CCM, + HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + }; + ASSERT_TRUE( + HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + /* Set tls1.2 on the client and tls1.3 on the server. Construct the clienthello compression algorithm without + * any extension. */ + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLS12Config(); + tlsConfig_c->isSupportExtendMasterSecret = false; + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->extensionState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_CERTIFICATE); +exit: + HITLS_CFG_FreeConfig(tlsConfig_c); + HITLS_CFG_FreeConfig(tlsConfig_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC002 +* @spec TLS 1.3 servers will need to perform this check first and +* only attempt to negotiate TLS 1.3 if the "supported_versions" +* extension is present. If negotiating a version of TLS prior to 1.3, +* a server MUST check that the message either contains no data after +* legacy_compression_methods or that it contains a valid extensions +* block with no data following. If not, then it MUST abort the +* handshake with a "decode_error" alert. +* @title: Set the client TLS 1.2 and server TLS 1.3. Construct the clienthello compression algorithm and carry the +* extension and 3-byte data after the extension. The expected connection establishment fails and the decode_error +* alert is returned. +* @precon nan +* @brief 4.1.2. Client Hello row22 +* Set TLS 1.2 on the client and TLS 1.3 on the server. Construct the compression algorithm of the clienthello +* message and carry the extension. After the extension, carry the 3-byte data. In this case, the connection +* establishment fails and the decode_error alert is returned. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLSConfig(); + tlsConfig_s->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE( + HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLSConfig(); + HITLS_CFG_SetVersionSupport(tlsConfig_c, 0x00000010U); + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint32_t *recvLen = &ioUserData->recMsg.len; + uint8_t *recvBuf = ioUserData->recMsg.msg; + ASSERT_TRUE(recvLen != 0); + recvBuf[4] += 3; + recvBuf[8] += 3; + recvBuf[*recvLen] = 0x01; + recvBuf[(*recvLen)+1] = 0x01; + recvBuf[(*recvLen)+2] = 0x01; + *recvLen += 3; + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + HITLS_CFG_FreeConfig(tlsConfig_c); + HITLS_CFG_FreeConfig(tlsConfig_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC003 +* @spec TLS 1.3 servers will need to perform this check first and +* only attempt to negotiate TLS 1.3 if the "supported_versions" +* extension is present. If negotiating a version of TLS prior to 1.3, +* a server MUST check that the message either contains no data after +* legacy_compression_methods or that it contains a valid extensions +* block with no data following. If not, then it MUST abort the +* handshake with a "decode_error" alert. +* @title: Set the client TLS 1.2 and server TLS 1.3. Construct the clienthello compression algorithm and carry 3-byte +* data without extension. Expected connection establishment failure and return decode_error alert. +* @precon nan +* @brief 4.1.2. Client Hello row22 +* Set TLS 1.2 on the client and TLS 1.3 on the server. Construct the compression algorithm of the clienthello +* message without extension and carry 3-byte data. Expectedly, connection establishment fails and decode_error +* alert is returned. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLS13Config(); + tlsConfig_s->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLS12Config(); + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->extensionState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + /* Set the client TLS 1.2 and server TLS 1.3. Construct the clienthello compression algorithm and carry 3-byte + * data without extension. */ + sendBuf[4] += 3; + sendBuf[8] += 3; + sendBuf[sendLen] = 0x01; + sendBuf[sendLen + 1] = 0x01; + sendBuf[sendLen + 2] = 0x01; + sendLen += 3; + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + HITLS_CFG_FreeConfig(tlsConfig_c); + HITLS_CFG_FreeConfig(tlsConfig_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC004 +* @spec TLS 1.3 servers will need to perform this check first and +* only attempt to negotiate TLS 1.3 if the "supported_versions" +* extension is present. If negotiating a version of TLS prior to 1.3, +* a server MUST check that the message either contains no data after +* legacy_compression_methods or that it contains a valid extensions +* block with no data following. If not, then it MUST abort the +* handshake with a "decode_error" alert. +* @title 4. Set tls1.2 on the client and tls1.3 on the server. Construct the clienthello message that carries the SNI +* extension. The SNI length is too large and does not match the content. As a result, the expected connection +* establishment fails and a decode_error alert message is returned. +* @precon nan +* @brief 4.1.2. Client Hello row22 +* 4. Set tls1.2 on the client and tls1.3 on the server. Construct a clienthello message that carries the SNI +* extension. The SNI length is too large and does not match the content. As a result, the expected connection +* establishment fails and a decode_error alert message is returned. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC004() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLS13Config(); + tlsConfig_s->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_s, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_s, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE( + HITLS_CFG_SetCipherSuites(tlsConfig_s, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_s != NULL); + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLS12Config(); + HITLS_CFG_SetServerName(tlsConfig_c, (uint8_t *)g_serverName, (uint32_t)strlen(g_serverName)); + tlsConfig_c->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_c != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->serverName.exDataLen.data += 1; + /* Set tls1.2 on the client and tls1.3 on the server. Construct the clienthello message that carries the SNI + * extension. */ + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_PARSE_INVALID_MSG_LEN); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_DECODE_ERROR); +exit: + HITLS_CFG_FreeConfig(tlsConfig_c); + HITLS_CFG_FreeConfig(tlsConfig_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC001 +* @spec legacy_version: In previous versions of TLS, this field was used for version negotiation and represented the +* selected version number +* for the connection. In TLS 1.3, the TLS server indicates +* its version using the "supported_versions" extension +* (Section 4.2.1), and the legacy_version field MUST be set to +* 0x0303, which is the version number for TLS 1.2. (See Appendix D +* for details about backward compatibility.) +* @title The client server is initialized to the tls1.3 version. The legacy_version in the sent serverhello message +* is changed to 0x0304. The client is expected to return illegal_parameter alert. +* @precon nan +* @brief 4.1.3. Server Hello row23 +* The client and server are initialized to the tls1.3 version, and the legacy_version in the sent serverhello +* message is changed to 0x0304. The client is expected to return illegal_parameter alert. +* @expect 1. The server sends an alert message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + /* The client server is initialized to the tls1.3 version. The legacy_version in the sent serverhello message + * is changed to 0x0304. */ + serverMsg->version.data = 0x0304; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC002 +* @spec legacy_version: In previous versions of TLS, this field was used for version negotiation and represented the +* selected version number for the connection. In TLS 1.3, the TLS server indicates +* its version using the "supported_versions" extension +* (Section 4.2.1), and the legacy_version field MUST be set to +* 0x0303, which is the version number for TLS 1.2. (See Appendix D +* for details about backward compatibility.) +* @title The client server is initialized to the tls1.3 version, and the legacy_version in the sent serverhello +* message is changed to 0x0302. The client is expected to return illegal_parameter alert. +* @precon nan +* @brief 4.1.3. Server Hello row23 +* The client and server are initialized to tls1.3 and the legacy_version in the sent serverhello message is +* changed to 0x0302. The client is expected to return illegal_parameter alert. +* @expect 1. The server sends an alert message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + /* The client server is initialized to the tls1.3 version, and the legacy_version in the sent serverhello + * message is changed to 0x0302. */ + serverMsg->version.data = 0x0302; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_COMPRESSION_METHOD_FUNC_TC001 +* @spec legacy_compression_method: A single byte which MUST have the +* value 0. +* @title Construct serverhello compression algorithm. The value is 1, indicating that the server returns +* illegal_parameter alert. +* @precon nan +* @brief 4.1.3. Server Hello row27 +* Construct the serverhello compression algorithm with a one-byte value. The server returns the +* illegal_parameter alert message. +* @expect 1. The server sends an alert message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_COMPRESSION_METHOD_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + /* Construct serverhello compression algorithm. The value is 1 */ + serverMsg->compressionMethod.data = 0x01; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_PARSE_COMPRESSION_METHOD_ERR); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC001 +* @spec extensions: A list of extensions. The ServerHello MUST only include +* extensions which are required to establish the cryptographic +* context and negotiate the protocol version. All TLS 1.3 +* ServerHello messages MUST contain the "supported_versions" +* extension. Current ServerHello messages additionally contain +* either the "pre_shared_key" extension or the "key_share" +* extension, or both (when using a PSK with (EC)DHE key +* establishment). Other extensions (see Section 4.2) are sent +* separately in the EncryptedExtensions message. +* @title Initialize the client and server as tls1.3. Construct a serverhello message that carries the SNI extension. It +* is expected that the connection fails to be established. +* @precon nan +* @brief 4.1.3. Server Hello row28 +* Initialize the client server to tls1.3 and construct a serverhello message that carries the SNI extension. +* The expected connection establishment fails. +* @expect 1. The client sends an alert message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->serverName.exState = INITIAL_FIELD; + serverMsg->serverName.exType.state = INITIAL_FIELD; + serverMsg->serverName.exLen.state = INITIAL_FIELD; + serverMsg->serverName.exLen.data = 0x00; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNSUPPORTED_EXTENSION); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC002 +* @spec extensions: A list of extensions. The ServerHello MUST only include +* extensions which are required to establish the cryptographic +* context and negotiate the protocol version. All TLS 1.3 +* ServerHello messages MUST contain the "supported_versions" +* extension. Current ServerHello messages additionally contain +* either the "pre_shared_key" extension or the "key_share" +* extension, or both (when using a PSK with (EC)DHE key +* establishment). Other extensions (see Section 4.2) are sent +* separately in the EncryptedExtensions message. +* @title Initialize the client and server to tls1.3 and construct the serverhello message that does not carry the +* supportedversion extension, +* The expected client stays in the TRY_RECV_CERTIFICATIONATE state after receiving the serverhello message. After +* receiving the CCS message, the client sends an alarm indicating that the unexpected message is received. +* @precon nan +* @brief 4.1.3. Server Hello row28 +* Initialize the client server to tls1.3 and construct the serverhello message without the supportedversion +* extension, The expected client stays in the TRY_RECV_CERTIFICATIONATE state after receiving the serverhello +* message. After receiving the CCS message, the client sends an alarm indicating that the unexpected message is +* received. +* @expect 1. The client receives an alert response from the CCS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportExtendMasterSecret = false; + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + /* Initialize the client and server to tls1.3 and construct the serverhello message that does not carry the + * supportedversion extension */ + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->supportedVersion.exState = MISSING_FIELD; + serverMsg->secRenego.exState = INITIAL_FIELD; + serverMsg->secRenego.exType.state = INITIAL_FIELD; + serverMsg->secRenego.exType.data = 0xFF01u; + serverMsg->secRenego.exLen.state = INITIAL_FIELD; + serverMsg->secRenego.exLen.data = 1; + serverMsg->secRenego.exDataLen.state = INITIAL_FIELD; + serverMsg->secRenego.exDataLen.data = 0u; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_CERTIFICATE); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_RANDOM_FUNC_TC001 +* @spec For reasons of backward compatibility with middleboxes (see +* Appendix D.4), the HelloRetryRequest message uses the same structure +* as the ServerHello, but with Random set to the special value of the +* SHA-256 of "HelloRetryRequest": +* +* CF 21 AD 74 E5 9A 61 11 BE 1D 8C 02 1E 65 B8 91 +* C2 A2 11 16 7A BB 8C 5E 07 9E 09 E2 C8 A8 33 9C +* +* Upon receiving a message with type server_hello, implementations MUST first examine the Random value and, +* if it matches this value, process it as described in Section 4.1.4). +* @title The client and server are initialized to the TLS1.3 version and construct the scenario of sending hrr +* messages. After receiving hrr messages, The next packet sent by the client is expected to be a client hello +* message, and the random value of the expected received hrr packet is the specified value. +* @precon nan +* @brief 4.1.3. Server Hello row29 +* The client and server are initialized to the TLS1.3 version, construct the scenario of sending hrr messages. +* After receiving hrr messages, +* The next packet sent by the client is expected to be a client hello packet, and the random value of the +* expected received hrr packet is the specified value. +* @expect 1. Proofreading succeeded. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_RANDOM_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* The client and server are initialized to the TLS1.3 version and construct the scenario of sending hrr + * messages. */ + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + const uint8_t g_hrrRandom[HS_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, + 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c +}; + ASSERT_TRUE(memcmp(serverMsg->randomValue.data, g_hrrRandom, sizeof(g_hrrRandom) / sizeof(uint8_t)) == 0); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_RANDOM_FUNC_TC002 +* @spec For reasons of backward compatibility with middleboxes (see +* Appendix D.4), the HelloRetryRequest message uses the same structure +* as the ServerHello, but with Random set to the special value of the +* SHA-256 of "HelloRetryRequest": +* +* CF 21 AD 74 E5 9A 61 11 BE 1D 8C 02 1E 65 B8 91 +* C2 A2 11 16 7A BB 8C 5E 07 9E 09 E2 C8 A8 33 9C +* +* Upon receiving a message with type server_hello, implementations MUST first examine the Random value and, +* if it matches this value, process it as described in Section 4.1.4). +* @title The client and server are initialized to the TLS1.3 version and construct the scenario of sending hrr +* messages. After receiving hrr messages, +* The next packet sent by the client is expected to be client hello, and the random value of the expected +* received hrr is the specified value. +* @precon nan +* @brief 4.1.3. Server Hello row29 +* The client and server are initialized to the TLS1.3 version. The connection is established normally. The +* client and server directly send the server hello packet without sending the hrr message. The random value of +* the server hello packet is changed to the value specified by hrr, +* The client is expected to send a client hello packet after receiving the packet. +* @expect 1. It is expected that the client sends a client hello packet after receiving the packet. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_RANDOM_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + const uint8_t g_hrrRandom[HS_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, + 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c +}; + ASSERT_TRUE(memcpy_s(serverMsg->randomValue.data, sizeof(g_hrrRandom) / sizeof(uint8_t), + g_hrrRandom, sizeof(g_hrrRandom) / sizeof(uint8_t)) == 0); + serverMsg->keyShare.data.keyExchangeLen.state = MISSING_FIELD; + serverMsg->keyShare.data.keyExchange.state = MISSING_FIELD; + serverMsg->keyShare.data.group.data = HITLS_EC_GROUP_SECP521R1; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_SEND_CLIENT_HELLO); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_RANDOM_FUNC_TC001 +* @spec TLS 1.3 clients receiving a ServerHello indicating TLS 1.2 or below +* MUST check that the last 8 bytes are not equal to either of these values. +* TLS 1.2 clients SHOULD also check that the last 8 bytes are not equal to the second value if the ServerHello +* indicates TLS 1.1 or below. +* If a match is found, the client MUST abort the handshake with an "illegal_parameter" alert. +* Note: This is a change from [RFC5246], so in practice many TLS 1.2 +* clients and servers will not behave as specified above. +* @title The client is tls1.3, and the server is tls1.2. Construct a scenario where the last eight random bytes of +* the server hello packet received by the client are equal to the specified value. The expected result is that +* the connection fails to be established and the client returns the illegal_parameter alarm. +* @precon nan +* @brief 4.1.3. Server Hello row31 +* When the client is tls1.3 and the server is tls1.2, construct the last eight random bytes of the server hello +* packet received by the client equal to the specified value. In this case, the connection fails to be established +* and the client returns the illegal_parameter alarm. +* @expect The connection is set up normally. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_RANDOM_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig_c = HITLS_CFG_NewTLS13Config(); + tlsConfig_c->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig_c, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetVersionSupport(tlsConfig_c, 0x00000030U); + uint16_t cipherSuites[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }; + ASSERT_TRUE( + HITLS_CFG_SetCipherSuites(tlsConfig_c, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(tlsConfig_c != NULL); + + HITLS_Config *tlsConfig_s = HITLS_CFG_NewTLS12Config(); + tlsConfig_s->isSupportClientVerify = true; + ASSERT_TRUE(tlsConfig_s != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + /* The client is tls1.3, and the server is tls1.2. Construct a scenario where the last eight random bytes of + * the server hello packet received by the client are equal to the specified value. */ + const uint8_t g_tls12Downgrade[HS_DOWNGRADE_RANDOM_SIZE] = {0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01}; + ASSERT_TRUE(memcpy_s(serverMsg->randomValue.data + (HS_RANDOM_SIZE - HS_DOWNGRADE_RANDOM_SIZE), sizeof(g_tls12Downgrade) / sizeof(uint8_t), + g_tls12Downgrade, sizeof(g_tls12Downgrade) / sizeof(uint8_t)) == 0); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); +exit: + HITLS_CFG_FreeConfig(tlsConfig_s); + HITLS_CFG_FreeConfig(tlsConfig_c); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static void Test_ModifyServerHello(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *userData) +{ + (void)ctx; + (void)userData; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->keyShare.exState = INITIAL_FIELD; + serverMsg->keyShare.exType.state = INITIAL_FIELD; + serverMsg->keyShare.exLen.state = INITIAL_FIELD; + serverMsg->keyShare.exLen.data = 0x00; + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RENEGOTIATION_VERSION_FUNC_TC001 +* @spec A legacy TLS client performing renegotiation with TLS 1.2 or prior +* and which receives a TLS 1.3 ServerHello during renegotiation MUST +* abort the handshake with a "protocol_version" alert. Note that +* renegotiation is not possible when TLS 1.3 has been negotiated. +* @title Construct the TLS1.2 serverhello message received by the TLS1.3 serverhello message during renegotiation. +* @precon nan +* @brief 4.1.3. Server Hello row32 +* Construct the scenario where the TLS1.2 server hello message of the TLS1.3 version is received during +* renegotiation. +* @expect 1. The client sends an alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RENEGOTIATION_VERSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportRenegotiation = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_EQ(HITLS_Renegotiate(clientTlsCtx), HITLS_SUCCESS); + /* Construct the TLS1.2 serverhello message received by the TLS1.3 serverhello message during renegotiation. */ + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_ModifyServerHello}; + RegisterWrapper(wrapper); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_RENEGOTIATION); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNSUPPORTED_EXTENSION); + + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_FUNC_TC001 +* @spec The server's extensions must contain "supported_versions". +* Additionally, it SHOULD contain the minimal set of extensions +* necessary for the client to generate a correct ClientHello pair. As +* with the ServerHello, a HelloRetryRequest MUST NOT contain any +* extensions that were not first offered by the client in its +* ClientHello, with the exception of optionally the "cookie" (see +* Section 4.2.2) extension. +* @title Initialize the client and server to tls1.3. Construct the scenario where the HRR message is sent and the HRR +* message does not carry the supportedversion extension, +* The client is expected to perform the 1.2 handshake process and the status is TRY_RECV_CERTIFICATIONATE. +* @precon nan +* @brief 4.1.4. Hello Retry Request row33 +* Initialize the client and server to tls1.3, construct the scenario where the HRR message is sent, and construct +* the HRR message that does not carry the supportedversion extension, +* The client is expected to perform the 1.2 handshake process and the status is TRY_RECV_CERTIFICATIONATE. +* @expect 1. The client is in the TRY_RECV_CERTIFICATIONATE state. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportExtendMasterSecret = false; + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->supportedVersion.exState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(clientTlsCtx->hsCtx->state, TRY_RECV_CERTIFICATE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_FUNC_TC002 +* @spec The server's extensions must contain "supported_versions". +* Additionally, it SHOULD contain the minimal set of extensions +* necessary for the client to generate a correct ClientHello pair. As +* with the ServerHello, a HelloRetryRequest MUST NOT contain any +* extensions that were not first offered by the client in its +* ClientHello, with the exception of optionally the "cookie" (see +* Section 4.2.2) extension. +* @title Initialize the client server to tls1.3, construct the scenario where the hrr message is sent, and construct the +* hrr message carrying the sni extension. The client is expected to return the illegal_parameter alarm. +* @precon nan +* @brief 4.1.4. Hello Retry Request row33 +* Initialize the client server to tls1.3, construct the scenario where the hrr message is sent, and construct the +* hrr message carrying the sni extension. The client is expected to return the illegal_parameter alarm. +* @expect 1. The client returns the illegal_parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->serverName.exState = INITIAL_FIELD; + serverMsg->serverName.exType.state = INITIAL_FIELD; + serverMsg->serverName.exLen.state = INITIAL_FIELD; + serverMsg->serverName.exLen.data = 0x00; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_FUNC_TC003 +* @spec The server's extensions must contain "supported_versions". +* Additionally, it SHOULD contain the minimal set of extensions +* necessary for the client to generate a correct ClientHello pair. As +* with the ServerHello, a HelloRetryRequest MUST NOT contain any +* extensions that were not first offered by the client in its +* ClientHello, with the exception of optionally the "cookie" (see +* Section 4.2.2) extension. +* @title Initialize the client and server to tls1.3, construct the scenario where the hrr message is sent and the hrr +* message does not carry the key_share extension, and the client is expected to return the illegal_parameter alarm. +* @precon nan +* @brief 4.1.4. Hello Retry Request row33 +* Initialize the client server to tls1.3, construct the scenario where the hrr message is sent, and construct the hrr +* message that does not carry the key_share extension. The client is expected to return the illegal_parameter alarm. +* @expect 1. The client returns the illegal_parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + /* Initialize the client and server to tls1.3, construct the scenario where the hrr message is sent and the hrr + * message does not carry the key_share extension */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->keyShare.exState = MISSING_FIELD; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_MISSING_EXTENSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC001 +* @spec Upon receipt of a HelloRetryRequest, the client MUST check the +* legacy_version, legacy_session_id_echo, cipher_suite, and +* legacy_compression_method as specified in Section 4.1.3 and then +* process the extensions, starting with determining the version using +* "supported_versions". Clients MUST abort the handshake with an +* "illegal_parameter" alert if the HelloRetryRequest would not result +* in any change in the ClientHello. If a client receives a second +* HelloRetryRequest in the same connection (i.e., where the ClientHello was itself in response to a +* HelloRetryRequest), +* it MUST abort the handshake with an "unexpected_message" alert. +* Otherwise, the client MUST process all extensions in the HelloRetryRequest and send a second updated +* ClientHello. +* @title Initialize the client and server as tls1.3. Construct the scenario where two hrr messages are sent. The +* client is expected to stop handshake and send unexpected_message alarms. +* @precon nan +* @brief 4.1.4. Hello Retry Request row34 +* Initialize the client and server as tls1.3, construct the scenario where two hrr messages are sent, and the +* client is expected to stop handshake and send the unexpected_message alarm. +* @expect 1. The client sends the unexpected_message alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + /* Initialize the client and server as tls1.3. Construct the scenario where two hrr messages are sent. */ + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_SERVER_HELLO); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_ENCRYPTED_EXTENSIONS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + const uint8_t g_hrrRandom[HS_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, + 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c +}; + ASSERT_TRUE(memcpy_s(serverMsg->randomValue.data, sizeof(g_hrrRandom) / sizeof(uint8_t), + g_hrrRandom, sizeof(g_hrrRandom) / sizeof(uint8_t)) == 0); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_DUPLICATE_HELLO_RETYR_REQUEST); + + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC002 +* @spec Upon receipt of a HelloRetryRequest, the client MUST check the +* legacy_version, legacy_session_id_echo, cipher_suite, and +* legacy_compression_method as specified in Section 4.1.3 and then +* process the extensions, starting with determining the version using +* "supported_versions". Clients MUST abort the handshake with an +* "illegal_parameter" alert if the HelloRetryRequest would not result +* in any change in the ClientHello. If a client receives a second +* HelloRetryRequest in the same connection (i.e., where the ClientHello was itself in response to a +* HelloRetryRequest), +* it MUST abort the handshake with an "unexpected_message" alert. +* Otherwise, the client MUST process all extensions in the HelloRetryRequest and send a second updated +* ClientHello. +* @title The client server is initialized to the tls1.3 version, and the legacy_version in the hrr message is changed +* to 0x0304. The client is expected to return illegal_parameter alert. +* @precon nan +* @brief 4.1.4. Hello Retry Request row34 +* The client and server are initialized to tls1.3 and the legacy_version in the hrr message is changed to +* 0x0304. The client is expected to return illegal_parameter alert. +* @expect 1. The client sends the unexpected_message alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->version.data = 0x0304; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC003 +* @spec Upon receipt of a HelloRetryRequest, the client MUST check the +* legacy_version, legacy_session_id_echo, cipher_suite, and +* legacy_compression_method as specified in Section 4.1.3 and then +* process the extensions, starting with determining the version using +* "supported_versions". Clients MUST abort the handshake with an +* "illegal_parameter" alert if the HelloRetryRequest would not result +* in any change in the ClientHello. If a client receives a second +* HelloRetryRequest in the same connection (i.e., where the ClientHello was itself in response to a +* HelloRetryRequest), it MUST abort the handshake with an "unexpected_message" alert. +* Otherwise, the client MUST process all extensions in the HelloRetryRequest and send a second updated +* ClientHello. +* @title The client and server are initialized to tls1.3. Change the legacy_version in the hrr message to 0x0302. The +* client is expected to return illegal_parameter alert. +* @precon nan +* @brief 4.1.4. Hello Retry Request row34 +* The client and server are initialized to tls1.3 and the legacy_version in the hrr message is changed to +* 0x0302. The client is expected to return illegal_parameter alert. +* @expect 1. The client sends the unexpected_message alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + /* The client and server are initialized to tls1.3. Change the legacy_version in the hrr message to 0x0302. */ + serverMsg->version.data = 0x0302; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC004 +* @spec Upon receipt of a HelloRetryRequest, the client MUST check the +* legacy_version, legacy_session_id_echo, cipher_suite, and +* legacy_compression_method as specified in Section 4.1.3 and then +* process the extensions, starting with determining the version using +* "supported_versions". Clients MUST abort the handshake with an +* "illegal_parameter" alert if the HelloRetryRequest would not result +* in any change in the ClientHello. If a client receives a second +* HelloRetryRequest in the same connection (i.e., where the ClientHello was itself in response to a +* HelloRetryRequest), +* it MUST abort the handshake with an "unexpected_message" alert. +* Otherwise, the client MUST process all extensions in the HelloRetryRequest and send a second updated +* ClientHello. +* @title Initialize the client and server to TLS1.3. Construct the scenario where the session_id field in the hrr is +* modified. The client is expected to send an illegal parameter alarm after receiving the modification. +* @precon nan +* @brief 4.1.4. Hello Retry Request row34 +* Initialize the client and server to TLS1.3 and construct the scenario where the hrr session_id field is +* modified. The client is expected to send an illegal parameter alarm after receiving the modification. +* @expect 1. The client sends an illegal parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC004() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg parsedSH = {0}; + uint32_t parseLen = 0; + FRAME_Type frameType = {0}; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &parsedSH, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *shMsg = &parsedSH.body.hsMsg.body.serverHello; + memset_s((shMsg->sessionId.data), shMsg->sessionId.size, 1, shMsg->sessionId.size); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID); + +exit: + FRAME_CleanMsg(&frameType, &parsedSH); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC005 +* @spec Upon receipt of a HelloRetryRequest, the client MUST check the +* legacy_version, legacy_session_id_echo, cipher_suite, and +* legacy_compression_method as specified in Section 4.1.3 and then +* process the extensions, starting with determining the version using +* "supported_versions". Clients MUST abort the handshake with an +* "illegal_parameter" alert if the HelloRetryRequest would not result +* in any change in the ClientHello. If a client receives a second +* HelloRetryRequest in the same connection (i.e., where the ClientHello was itself in response to a +* HelloRetryRequest), +* it MUST abort the handshake with an "unexpected_message" alert. +* Otherwise, the client MUST process all extensions in the HelloRetryRequest and send a second updated +* ClientHello. +* @title The client server is initialized to the TLS1.3 version, and the value of cipher_suite in the hrr message is +* changed to a value other than the value provided by the client. The client is expected to return +* illegal_parameter alert. +* @precon nan +* @brief 4.1.4. Hello Retry Request row34 +* The client and server are initialized to the TLS1.3 version, and the value of cipher_suite in the hrr +* message is changed to a value that is not provided by the client. The client is expected to return +* illegal_parameter alert. +* @expect 1. The client sends an illegal parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC005() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg parsedSH = {0}; + uint32_t parseLen = 0; + FRAME_Type frameType; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &parsedSH, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *shMsg = &parsedSH.body.hsMsg.body.serverHello; + shMsg->cipherSuite.data = HITLS_AES_128_CCM_SHA256; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &parsedSH, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + + FrameUioUserData *userData = BSL_UIO_GetUserData(client->io); + uint8_t *alertBuf = userData->sndMsg.msg; + uint32_t alertLen = userData->sndMsg.len; + FRAME_Msg parsedAlert = {0}; + uint32_t parsedAlertLen = 0; + ASSERT_TRUE(FRAME_ParseTLSNonHsRecord(alertBuf, alertLen, &parsedAlert, &parsedAlertLen) == HITLS_SUCCESS); + + ASSERT_TRUE(parsedAlert.recType.data == REC_TYPE_ALERT); + FRAME_AlertMsg *alertMsg = &parsedAlert.body.alertMsg; + ASSERT_TRUE(alertMsg->alertLevel.data == ALERT_LEVEL_FATAL); + ASSERT_EQ(alertMsg->alertDescription.data, ALERT_ILLEGAL_PARAMETER); + +exit: + FRAME_CleanMsg(&frameType, &parsedSH); + FRAME_CleanNonHsRecord(REC_TYPE_ALERT, &parsedAlert); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC006 +* @spec Upon receipt of a HelloRetryRequest, the client MUST check the +* legacy_version, legacy_session_id_echo, cipher_suite, and +* legacy_compression_method as specified in Section 4.1.3 and then +* process the extensions, starting with determining the version using +* "supported_versions". Clients MUST abort the handshake with an +* "illegal_parameter" alert if the HelloRetryRequest would not result +* in any change in the ClientHello. If a client receives a second +* HelloRetryRequest in the same connection (i.e., where the ClientHello was itself in response to a +* HelloRetryRequest), +* it MUST abort the handshake with an "unexpected_message" alert. +* Otherwise, the client MUST process all extensions in the HelloRetryRequest and send a second updated +* ClientHello. +* @title Construct hrr compression algorithm. The value is 1. The server is expected to return illegal_parameter +* alert. +* @precon nan +* @brief 4.1.4. Hello Retry Request row34 +* Construct the hrr compression algorithm byte and set the value to 1. The server is expected to return +* illegal_parameter alert. +* @expect 1. The client sends an illegal parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_FORMAT_FUNC_TC006() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->compressionMethod.data = 0x01; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_PARSE_COMPRESSION_METHOD_ERR); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_CONTENT_FUNC_TC001 +* @spec The HelloRetryRequest extensions defined in this specification are: +* - supported_versions (see Section 4.2.1) +* - cookie (see Section 4.2.2) +* - key_share (see Section 4.2.8) +* A client which receives a cipher suite that was not offered MUST +* abort the handshake. Servers MUST ensure that they negotiate the +* same cipher suite when receiving a conformant updated ClientHello. +* Upon receiving the ServerHello, +* clients MUST check that the cipher suite supplied in the ServerHello is the same as that in the +* HelloRetryRequest and otherwise abort the handshake with an "illegal_parameter" alert. +* @title The client and server are initialized to the TLS1.3 version. In the scenario where the hrr message is sent, +* the hrr cipher suite is changed to an algorithm that is not provided by the client. The expected connection +* establishment fails and the illegal_parameter alarm is returned. +* @precon nan +* @brief 4.1.4. Hello Retry Request row35 +* The client and server are initialized to the TLS1.3 version, construct the scenario where the hrr message is +* sent, and modify the hrr algorithm suite to an algorithm that is not provided by the client. In this case, +* the expected connection establishment fails and the illegal_parameter alarm is returned. +* @expect 1. The client returns the illegal_parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_CONTENT_FUNC_TC001() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->cipherSuite.data = HITLS_RSA_WITH_AES_128_CBC_SHA; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_CONTENT_FUNC_TC002 +* @spec The HelloRetryRequest extensions defined in this specification are: +* - supported_versions (see Section 4.2.1) +* - cookie (see Section 4.2.2) +* - key_share (see Section 4.2.8) +* A client which receives a cipher suite that was not offered MUST +* abort the handshake. Servers MUST ensure that they negotiate the +* same cipher suite when receiving a conformant updated ClientHello. +* Upon receiving the ServerHello, +* clients MUST check that the cipher suite supplied in the ServerHello is the same as that in the +* HelloRetryRequest and otherwise abort the handshake with an "illegal_parameter" alert. +* @title 2. Initialize the client and server to TLS1.3, construct the scenario where the hrr message is sent, and +* change the algorithm suite for the client hello message to be sent again to the new algorithm suite. It is +* expected that the connection fails to be established and the illegal_parameter alarm is returned. +* @precon nan +* @brief 4.1.4. Hello Retry Request row35 +* 2. Initialize the client and server to TLS1.3, construct the scenario of sending hrr messages, and change +* the cipher suite of the client hello message to be sent again to the new cipher suite. It is expected that +* the connection fails to be established and the illegal_parameter alarm is returned. +* @expect 1. The server returns the illegal_parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_CONTENT_FUNC_TC002() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, CLIENT_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + /* Initialize the client and server to TLS1.3, construct the scenario where the hrr message is sent, and + * change the algorithm suite for the client hello message to be sent again to the new algorithm suite. */ + FRAME_ClientHelloMsg *clientMsg = &frameMsg.body.hsMsg.body.clientHello; + clientMsg->cipherSuites.data[0] = HITLS_AES_128_GCM_SHA256; + clientMsg->cipherSuites.data[1] = HITLS_AES_256_GCM_SHA384; + clientMsg->cipherSuites.data[2] = HITLS_CHACHA20_POLY1305_SHA256; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + ioUserData->sndMsg.len = 0; + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_CONTENT_FUNC_TC003 +* @spec The HelloRetryRequest extensions defined in this specification are: +* - supported_versions (see Section 4.2.1) +* - cookie (see Section 4.2.2) +* - key_share (see Section 4.2.8) +* A client which receives a cipher suite that was not offered MUST +* abort the handshake. Servers MUST ensure that they negotiate the +* same cipher suite when receiving a conformant updated ClientHello. +* Upon receiving the ServerHello, +* clients MUST check that the cipher suite supplied in the ServerHello is the same as that in the +* HelloRetryRequest and otherwise abort the handshake with an "illegal_parameter" alert. +* @title 3. Initialize the client and server to TLS1.3. Construct the scenario where the HRR message is sent. Modify +* the cipher suite in the serverhello message to be different from that in the HRR message. As a result, the +* expected connection establishment fails and the illegal_parameter alarm is returned. +* @precon nan +* @brief 4.1.4. Hello Retry Request row35 +* 3. The client and server are initialized to TLS1.3, construct the scenario where hrr is sent, modify the +* cipher suite in serverhello and hrr to be different, and the expected connection setup fails and the +* illegal_parameter alarm is returned. +* @expect 1. The client returns the illegal_parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_EXTENSION_CONTENT_FUNC_TC003() +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + CONN_Deinit(serverTlsCtx); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_SERVER_HELLO); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_ENCRYPTED_EXTENSIONS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->cipherSuite.data = HITLS_AES_128_GCM_SHA256; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE); + + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_ILLEGAL_PARAMETER); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_SUPPORT_VERSION_FUNC_TC001 +* @spec The value of selected_version in the HelloRetryRequest +* "supported_versions" extension MUST be retained in the ServerHello, +* and a client MUST abort the handshake with an "illegal_parameter" +* alert if the value changes. +* @title 1. Initialize the client and server as tls1.3, construct a scenario where the supportedversion values +* carried by serverhello and hrr are different, +* The client is expected to return the illegal_parameter alarm. +* @precon nan +* @brief 4.1.4. Hello Retry Request row37 +* 1. Initialize the client and server to tls1.3, construct the scenario where the supportedversion values carried +* by serverhello and hrr are different, +* The client is expected to return the illegal_parameter alarm. +* @expect 1. The client returns the illegal_parameter alarm. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_SUPPORT_VERSION_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_CFG_SetVersionSupport(&client->ssl->config.tlsConfig, 0x00000030U); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + /* 1. Initialize the client and server to tls1.3, construct the scenario where the supportedversion values carried + by serverhello and hrr are different, */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_RECV_SERVER_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_SERVER_HELLO); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_ENCRYPTED_EXTENSIONS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + uint8_t *recvBuf = ioUserData->recMsg.msg; + uint32_t recvLen = ioUserData->recMsg.len; + ASSERT_TRUE(recvLen != 0); + + FRAME_Msg frameMsg = { 0 }; + FRAME_Type frameType = { 0 }; + + uint32_t parseLen = 0; + SetFrameType(&frameType, HITLS_VERSION_TLS13, REC_TYPE_HANDSHAKE, SERVER_HELLO, HITLS_KEY_EXCH_ECDHE); + ASSERT_TRUE(FRAME_ParseMsg(&frameType, recvBuf, recvLen, &frameMsg, &parseLen) == HITLS_SUCCESS); + + FRAME_ServerHelloMsg *serverMsg = &frameMsg.body.hsMsg.body.serverHello; + serverMsg->supportedVersion.data.data = 0x0303; + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* If the client curve is HITLS_EC_GROUP_CURVE25519 and the certificate is SECP256R1, the connection is successfully + * established, indicating that the curve in tls1.3 is not associated with the certificate. */ +/* BEGIN_CASE */ +void SDV_TLS13_RFC8446_KeyShareGroup_TC003(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[BUF_SIZE_DTO_TEST] = {0}; + uint32_t readLen; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetTls13CipherSuites(serverCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_CURVE25519"); + HLT_SetTls13CipherSuites(clientCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_SUCCESS); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, clientRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, BUF_SIZE_DTO_TEST, 0, BUF_SIZE_DTO_TEST) == EOK); + ASSERT_TRUE(HLT_TlsRead(serverRes->ssl, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_SUPPORT_VERSION_FUNC_TC001 +* @title During the TLS1.3 HRR handshaking, application messages can not be received +* @precon nan +* @brief +* 1. Initialize the client and server to tls1.3, construct the scenario where the supportedversion values carried +* by serverhello and hrr are different, expect result 1. +* 2. Send a app data message the server, expect reslut 2. +* @expect 1. The client send secend client hello message. +8 2. The server send unexpected message alert. +@ */ +/* BEGIN_CASE */ +void UT_TLS13_RFC8446_HRR_APP_RECV_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLSConfig(); + tlsConfig->isSupportClientVerify = true; + HITLS_CFG_SetKeyExchMode(tlsConfig, TLS13_KE_MODE_PSK_WITH_DHE); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(&(serverTlsCtx->config.tlsConfig), groups, groupsSize); + /* 1. Initialize the client and server to tls1.3, construct the scenario where the supportedversion values carried + by serverhello and hrr are different, */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + CONN_Deinit(serverTlsCtx); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_CHANGE_CIPHER_SPEC); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_RECV_CLIENT_HELLO); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(clientTlsCtx->hsCtx->state == TRY_SEND_CLIENT_HELLO); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + uint32_t sendLenapp = 7; + uint8_t sendBufapp[7] = {0x17, 0x03, 0x03, 0x00, 0x02, 0x05, 0x05}; + uint32_t writeLen; + BSL_UIO_Write(clientTlsCtx->uio, sendBufapp, sendLenapp, &writeLen); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(serverTlsCtx), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_ALERTED); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* IN TLS1.3, mutiple ccs can be received*/ +/* BEGIN_CASE */ +void UT_TLS13_RFC8446_RECV_MUTI_CCS_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + uint32_t sendLenccs = 6; + uint8_t sendBufccs[6] = {0x14, 0x03, 0x03, 0x00, 0x01, 0x01}; + uint32_t writeLen; + for (int i = 0; i < 5; i++) { + BSL_UIO_Write(serverTlsCtx->uio, sendBufccs, sendLenccs, &writeLen); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(clientTlsCtx), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + } + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_kex.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_kex.data new file mode 100644 index 00000000..f0a262cf --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_kex.data @@ -0,0 +1,143 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVE_RENEGOTIATION_REQUEST_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVE_RENEGOTIATION_REQUEST_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC008: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC009 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC009: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC010 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC010: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC011 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC011: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC012 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC012: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC013 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_UNEXPECTMSG_FUNC_TC013: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SECOND_GROUP_SUPPORT_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RENEGOTIATION_OLD_VERSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SESSION_ID_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CH_CIPHERSUITES_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_COMPRESSION_METHOD_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNKNOWN_EXTENSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_UNKNOWN_EXTENSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_DATA_AFTER_COMPRESSION_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_LEGACY_VERSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_COMPRESSION_METHOD_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_COMPRESSION_METHOD_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_EXTENSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_RANDOM_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HRR_RANDOM_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_RANDOM_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_DOWN_GRADE_RANDOM_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RENEGOTIATION_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SERVER_RENEGOTIATION_VERSION_FUNC_TC001: + +SDV_TLS13_RFC8446_KeyShareGroup_TC003 +SDV_TLS13_RFC8446_KeyShareGroup_TC003:TLS1_3:TCP + +UT_TLS13_RFC8446_HRR_APP_RECV_TC001 +UT_TLS13_RFC8446_HRR_APP_RECV_TC001: + +UT_TLS13_RFC8446_RECV_MUTI_CCS_TC001 +UT_TLS13_RFC8446_RECV_MUTI_CCS_TC001: diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_pha.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_pha.c new file mode 100644 index 00000000..5ecc23fe --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_pha.c @@ -0,0 +1,327 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "rec_wrapper.h" +#include "cert.h" +#include "securec.h" +#include "conn_init.h" +#include "hitls_crypt_init.h" +#include "hitls_psk.h" +#include "common_func.h" +#include "alert.h" +#include "process.h" +#include "bsl_sal.h" +/* END_HEADER */ +#define MAX_BUF 16384 + +int32_t STUB_RecConnDecrypt( + TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg, uint8_t *data, uint32_t *dataLen) +{ + (void)ctx; + (void)state; + memcpy_s(data, cryptMsg->textLen, cryptMsg->text, cryptMsg->textLen); + (void)data; + *dataLen = cryptMsg->textLen; + return HITLS_SUCCESS; +} + +int32_t STUB_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num) +{ + (void)ctx; + (void)recordType; + (void)data; + (void)num; + return HITLS_SUCCESS; +} + +extern int32_t __real_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num); + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC001 +* @spec - +* @title The client does not support posthandshake, but receives a server certificate request +* message after the connection establishment is completed. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client not to support post-handshake extension +* 3. After the connection establishment is completed, the construction server sends a certificate request message to the +* client +* 4. Observe client behavior +* @expect +* 1. Initialization successful +* 2. Setup successful +* 3. Send successfully. +* 4. The client returns alert ALERT_UNEXPECTED_MESSAGE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC001(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + // Apply and initialize config + HITLS_Config *c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(c_config != NULL); + HITLS_Config *s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(s_config != NULL); + + // Set the client not to support post-handshake extension + HITLS_CFG_SetPostHandshakeAuthSupport(c_config, false); + HITLS_CFG_SetPostHandshakeAuthSupport(s_config, false); + + FRAME_LinkObj *client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + // the construction server sends a certificate request message to the client + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE_REQUEST; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(client->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(client->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + STUB_Init(); + FuncStubInfo tmpStubInfo; + STUB_Replace(&tmpStubInfo, RecConnDecrypt, STUB_RecConnDecrypt); + + uint8_t readbuff[READ_BUF_SIZE]; + uint32_t readLen; + ASSERT_TRUE(client->ssl != NULL); + + // The client returns alert ALERT_UNEXPECTED_MESSAGE + ASSERT_EQ(HITLS_Read(client->ssl, readbuff, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + STUB_Reset(&tmpStubInfo); + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC010 +* @spec - +* @title The server receives out-of-order messages during authentication after handshake. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client support post-handshake extension +* 3. After the connection is established, the server receives the CertificateVerify message. +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. The server sends an alert message, and the connection is interrupted. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC010(void) +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + // Apply and initialize config + HITLS_Config *c_config = HITLS_CFG_NewTLS13Config(); + HITLS_Config *s_config = HITLS_CFG_NewTLS13Config(); + + // Set the client support post-handshake extension + HITLS_CFG_SetPostHandshakeAuthSupport(c_config, true); + HITLS_CFG_SetPostHandshakeAuthSupport(s_config, true); + HITLS_CFG_SetClientVerifySupport(c_config, true); + HITLS_CFG_SetClientVerifySupport(s_config, true); + + FRAME_LinkObj *client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_EQ(HITLS_VerifyClientPostHandshake(server->ssl), HITLS_SUCCESS); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + + // the server receives the CertificateVerify message. + FRAME_Msg frameMsg = {0}; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.handshakeType = CERTIFICATE_VERIFY; + frameType.keyExType = HITLS_KEY_EXCH_ECDHE; + ASSERT_TRUE(FRAME_GetDefaultMsg(&frameType, &frameMsg) == HITLS_SUCCESS); + + uint32_t sendLen = MAX_RECORD_LENTH; + uint8_t sendBuf[MAX_RECORD_LENTH] = {0}; + ASSERT_TRUE(FRAME_PackMsg(&frameType, &frameMsg, sendBuf, sendLen, &sendLen) == HITLS_SUCCESS); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + ioUserData->recMsg.len = 0; + ASSERT_TRUE(FRAME_TransportRecMsg(server->io, sendBuf, sendLen) == HITLS_SUCCESS); + FRAME_CleanMsg(&frameType, &frameMsg); + memset_s(&frameMsg, sizeof(frameMsg), 0, sizeof(frameMsg)); + + STUB_Init(); + FuncStubInfo tmpStubInfo; + STUB_Replace(&tmpStubInfo, RecConnDecrypt, STUB_RecConnDecrypt); + + // The server sends an alert message, and the connection is interrupted. + ASSERT_TRUE(client->ssl != NULL); + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + STUB_Reset(&tmpStubInfo); + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC018 +* @spec - +* @title Invoke the HITLS_VerifyClientPostHandshake interface during connection establishment. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the client and server to support post-handshake extension. Expected result 3 is obtained. +* 3. When a connection is established, the server is in the Try_RECV_CLIENT_HELLO state, and the +* HITLS_VerifyClientPostHandshake interface is invoked. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The interface fails to be invoked. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC018(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + // Apply for and initialize the configuration file + config = HITLS_CFG_NewTLS13Config(); + client = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(server != NULL); + + // Configure the client and server to support post-handshake extension + client->ssl->config.tlsConfig.isSupportPostHandshakeAuth = true; + server->ssl->config.tlsConfig.isSupportPostHandshakeAuth = true; + ASSERT_TRUE(client->ssl->config.tlsConfig.isSupportPostHandshakeAuth == true); + ASSERT_TRUE(server->ssl->config.tlsConfig.isSupportPostHandshakeAuth == true); + + // he server is in the Try_RECV_CLIENT_HELLO state + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(server->ssl->hsCtx->state == TRY_RECV_CLIENT_HELLO); + + // the HITLS_VerifyClientPostHandshake interface is invoked + ASSERT_EQ(HITLS_VerifyClientPostHandshake(client->ssl), HITLS_INVALID_INPUT); + ASSERT_EQ(HITLS_VerifyClientPostHandshake(server->ssl), HITLS_MSG_HANDLE_STATE_ILLEGAL); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC019 +* @spec - +* @title The server does not support invoking the HITLS_VerifyClientPostHandshake interface after handshake +* authentication. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the client to support the post-handshake extension. The server does not support the post-handshake +* extension. +* 3. Establish a connection. The server invokes the HITLS_VerifyClientPostHandshake interface to initiate +* authentication. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The interface fails to be invoked. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC019(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + // Apply for and initialize the configuration file + config = HITLS_CFG_NewTLS13Config(); + client = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(server != NULL); + + // Configure the client to support the post-handshake extension + client->ssl->config.tlsConfig.isSupportPostHandshakeAuth = true; + server->ssl->config.tlsConfig.isSupportPostHandshakeAuth = false; + ASSERT_TRUE(client->ssl->config.tlsConfig.isSupportPostHandshakeAuth == true); + ASSERT_TRUE(server->ssl->config.tlsConfig.isSupportPostHandshakeAuth == false); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + + // The server invokes the HITLS_VerifyClientPostHandshake interface to initiate authentication + ASSERT_EQ(HITLS_VerifyClientPostHandshake(client->ssl), HITLS_INVALID_INPUT); + ASSERT_EQ(HITLS_VerifyClientPostHandshake(server->ssl), HITLS_MSG_HANDLE_STATE_ILLEGAL); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_pha.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_pha.data new file mode 100644 index 00000000..4d08475b --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_pha.data @@ -0,0 +1,11 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC010 +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC010: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC018 +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC018: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC019 +UT_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC019: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_record.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_record.c new file mode 100644 index 00000000..db7fb5d2 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_record.c @@ -0,0 +1,2554 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "securec.h" +#include "conn_init.h" +#include "alert.h" +#include "hs_kx.h" +/* END_HEADER */ + +#define MAX_RECORD_LENTH (20 * 1024) +#define ALERT_BODY_LEN 2u +const uint8_t ccsMessage[] = {0x14, 0x03, 0x03, 0x00, 0x01, 0x01}; + +static int32_t SendCcs(HITLS_Ctx *ctx, uint8_t *data, uint8_t len) +{ + /** Write records. */ + int32_t ret = REC_Write(ctx, REC_TYPE_CHANGE_CIPHER_SPEC, data, len); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* If isFlightTransmitEnable is enabled, the stored handshake information needs to be sent. */ + uint8_t isFlightTransmitEnable; + (void)HITLS_GetFlightTransmitSwitch(ctx, &isFlightTransmitEnable); + if (isFlightTransmitEnable == 1) { + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + return HITLS_REC_ERR_IO_EXCEPTION; + } + } + return HITLS_SUCCESS; +} + +static int32_t SendAlert(HITLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + uint8_t data[ALERT_BODY_LEN]; + /** Obtain the alert level. */ + data[0] = level; + data[1] = description; + /** Write records. */ + int32_t ret = REC_Write(ctx, REC_TYPE_ALERT, data, ALERT_BODY_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* If isFlightTransmitEnable is enabled, the stored handshake information needs to be sent. */ + uint8_t isFlightTransmitEnable; + (void)HITLS_GetFlightTransmitSwitch(ctx, &isFlightTransmitEnable); + if (isFlightTransmitEnable == 1) { + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + return HITLS_REC_ERR_IO_EXCEPTION; + } + } + return HITLS_SUCCESS; +} + +static int32_t SendErrorAlert(HITLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + uint8_t data[2 * ALERT_BODY_LEN] = {level, description, level, description}; + /** Write records. */ + int32_t ret = REC_Write(ctx, REC_TYPE_ALERT, data, 2 * ALERT_BODY_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* If isFlightTransmitEnable is enabled, the stored handshake information needs to be sent. */ + uint8_t isFlightTransmitEnable; + (void)HITLS_GetFlightTransmitSwitch(ctx, &isFlightTransmitEnable); + if (isFlightTransmitEnable == 1) { + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + return HITLS_REC_ERR_IO_EXCEPTION; + } + } + return HITLS_SUCCESS; +} +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC001 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 1. After the client sends a client hello message, the CCS message received by the client is not encrypted +* (value: 0x01). +* Discard the message and do not process the message. If the CCS message that is not encrypted is received +* again (value: 0x01), the system sends the unexpected_message alarm to terminate the handshake. +* 3. Before the client receives the finished message, the client receives the CCS message that is not +* encrypted (value: 0x01) and discards the message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, MAX_RECORD_LENTH, ioServerData->sndMsg.msg, ioServerData->sndMsg.len) == EOK); + sndMsg.len = ioServerData->sndMsg.len; + ioServerData->sndMsg.len = 0; + uint8_t data = 1; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 1. After the client sends a client hello message, the CCS message received by the client is not encrypted */ + /* 3. Before the client receives the finished message, the client receives the CCS message that is not + * encrypted */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* The server generates the unexpected_message alarm after receiving the CCS message for the second time. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_ERR_DATA_BETWEEN_CCS_AND_FINISHED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC002 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 2. After the first connection is established, the server receives the client hello message and receives the +* CCS message that is not encrypted (value: 0x01). The server discards the message and does not process +* the message. +* 4. If the server receives the CCS message that is not encrypted (value: 0x01) before the finished message is +* received during the first connection setup, Discard the message and do not process the message. If the +* CCS message that is not encrypted is received again (value: 0x01), the system sends the +* unexpected_message alarm to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 2. After the first connection is established, the server receives the client hello message and receives the + * CCS message that is not encrypted (value: 0x01). The server discards the message and does not process + * the message. + * 4. If the server receives the CCS message that is not encrypted (value: 0x01) before the finished message is + * received during the first connection setup, Discard the message and do not process the message. If the + * CCS message that is not encrypted is received again (value: 0x01) */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* The server generates the unexpected_message alarm after receiving the CCS message for the second time. */ + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC003 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 5. After the session is recovered, the clien sends the clienthello message, receives the CCS message that is +* not encrypted (value: 0x01), and discards the message. +* 7. The session is resumed. Before the finished message is received, the client receives a CCS message that +* is not encrypted (value: 0x01). The client discards the message and does not process the message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC003(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, MAX_RECORD_LENTH, ioServerData->sndMsg.msg, ioServerData->sndMsg.len) == EOK); + sndMsg.len = ioServerData->sndMsg.len; + ioServerData->sndMsg.len = 0; + uint8_t data = 1; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 5. After the session is recovered, the clien sends the clienthello message, receives the CCS message that is + * not encrypted (value: 0x01), and discards the message. + * 7. The session is resumed. Before the finished message is received, the client receives a CCS message + * that is not encrypted (value: 0x01). */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC004 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 6. After the session is resumed, the server receives a CCS message that is not encrypted (value: 0x01) after +* receiving the client hello message, +* The message is discarded and not processed. If the CCS message is received again and the unencrypted record +* (value: 0x01) is not encrypted, the alarm "unexpected_message" is sent to terminate the handshake. +* 8. The session is recovered. Before the server receives the finished message, the CCS message is not +* encrypted and the value is 0x01, and the message is discarded. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC004(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + ASSERT_EQ(server->ssl->hsCtx->state, TRY_RECV_FINISH); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 6.After the session is resumed, the server receives a CCS message that is not encrypted (value: 0x01) after + * receiving the client hello message, + * 8.The session is recovered. Before the server receives the finished message, the CCS message is not + * encrypted and the value is 0x01 */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* The server generates the unexpected_message alarm after receiving the CCS message for the second time. */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC005 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving unencrypted CCS messages, the system discards the messages. +* @precon nan +* @brief 5 Record Protocol line 181 +* 9. After receiving the helloretry request, the client sends the client hello message for the second time. +* The received CCS message is not encrypted (value: 0x01). +* Discard the message and do not process the message. If the CCS message is received again and the unencrypted +* record (value: 0x01) is received, the unexpected_message alarm is sent to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC005(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + /* Configure the server to support only the non-default curve. The server sends the HRR message. */ + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(tlsConfig, groups, groupsSize); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_HELLO_RETRY_REQUEST), HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, MAX_RECORD_LENTH, ioServerData->sndMsg.msg, ioServerData->sndMsg.len) == EOK); + sndMsg.len = ioServerData->sndMsg.len; + ioServerData->sndMsg.len = 0; + uint8_t data = 1; + + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 9.After receiving the helloretry request, the client sends the client hello message for the second time. + * The received CCS message is not encrypted (value: 0x01). + * Discard the message and do not process the message. If the CCS message is received again and the + * unencrypted record (value: 0x01) is received, the unexpected_message alarm is sent to terminate the handshake. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* When the client receives the CCS message for the second time, the unexpected_message alarm is generated. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_ERR_DATA_BETWEEN_CCS_AND_FINISHED); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC006 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 10. After the server sends a helloretry request, the client hello message is received for the second time, +* Send the unexpected_message alarm to terminate the handshake if the received CCS message is not encrypted +* (value: 0x01). +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC006(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + const uint16_t groups[] = {HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + HITLS_CFG_SetGroups(tlsConfig, groups, groupsSize); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 10. After the server sends a helloretry request, the client hello message is received for the second time, + * Send the unexpected_message alarm to terminate the handshake if the received CCS message is not + * encrypted (value: 0x01). */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 1. After the client sends a client hello message to the client, the client sends an unexpected_message alarm +* to terminate the handshake because the client receives a CCS whose value is not 0x01. +* 7. Before the client receives the finised message, the client sends the unexpected_message alarm to +* terminate the handshake because the client receives a CCS whose value is not 0x01. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, MAX_RECORD_LENTH, ioServerData->sndMsg.msg, ioServerData->sndMsg.len) == EOK); + sndMsg.len = ioServerData->sndMsg.len; + ioServerData->sndMsg.len = 0; + + uint8_t data = 2; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* The client receives an unencrypted CCS message (value: 0x01) and sends an unexpected_message alarm to terminate + * the handshake before the client receives the finished message. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 2. After the client sends the client hello message to the first connection setup, the client sends the +* unexpected_message alarm to terminate the handshake because the encrypted CCS is received. +* 9. Before the client receives the finised message, the client sends the unexpected_message alarm to +* terminate the handshake because the client receives the encrypted CCS. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + serverTlsCtx->recCtx->outBuf->end = 0; + uint32_t hashLen = SAL_CRYPT_DigestSize(serverTlsCtx->negotiatedInfo.cipherSuiteInfo.hashAlg); + ASSERT_EQ( + HS_SwitchTrafficKey(serverTlsCtx, serverTlsCtx->hsCtx->serverHsTrafficSecret, hashLen, true), HITLS_SUCCESS); + uint8_t data = 1; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 2. After the client sends the client hello message to the first connection setup, the client sends the + * unexpected_message alarm to terminate the handshake because the encrypted CCS is received. + * 9. Before the client receives the finised message, the client sends the unexpected_message alarm to + * terminate the handshake because the client receives the encrypted CCS. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC003 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 3. Before the server receives the client hello message, the server sends the unexpected_message alarm to terminate +* the handshake because it receives a CCS with a value other than 0x01. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC003(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + + uint8_t data = 2; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* Before the server receives the client hello message, the server sends the unexpected_message alarm to terminate + * the handshake because the server receives a CCS with a value other than 0x01. */ + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC004 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 4. After the first connection is established, the server receives the client hello message and receives the +* CCS whose value is not 0x01. Therefore, the server sends the unexpected_message alarm to terminate the +* handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC004(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_CERTIFICATE) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + + uint8_t data = 2; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 4.After the first connection is established, the server receives the client hello message and receives the + * CCS whose value is not 0x01. Therefore, the server sends the unexpected_message alarm to terminate the + * handshake. */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC005 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 5. After the first connection is established, the server receives the client hello message and receives the +* encrypted CCS. Therefore, the server sends the unexpected_message alarm to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC005(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + + clientTlsCtx->recCtx->outBuf->end = 0; + uint32_t hashLen = SAL_CRYPT_DigestSize(clientTlsCtx->negotiatedInfo.cipherSuiteInfo.hashAlg); + ASSERT_EQ( + HS_SwitchTrafficKey(clientTlsCtx, clientTlsCtx->hsCtx->serverHsTrafficSecret, hashLen, true), HITLS_SUCCESS); + /* Construct a non-0x1 CCS packet. */ + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* After the first connection is established, the server receives the client hello message and receives the + * encrypted CCS. Therefore, the server sends the unexpected_message alarm to terminate the handshake. */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC006 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 8. After the client receives the finised message, the client sends the unexpected_message alarm to terminate +* the handshake because it receives a CCS whose value is not 0x01. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC006(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->sndMsg.len = sizeof(ccsMessage); + memcpy_s(ioServerData->sndMsg.msg, ioServerData->sndMsg.len, ccsMessage, sizeof(ccsMessage)); + + ioServerData->sndMsg.msg[5] = 0x2; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 8. After the client receives the finised message, the client sends the unexpected_message alarm to terminate + * the handshake because it receives a CCS whose value is not 0x01. */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC007 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 9. After the client receives the finised message, the client sends the unexpected_message alarm to terminate +* the handshake because the client receives the encrypted CCS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC007(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + uint8_t data = 1; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ioServerData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 9. After the client receives the finised message, the client sends the unexpected_message alarm to terminate + * the handshake because the client receives the encrypted CCS */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC008 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 10. After the session is resumed, the client sends the unexpected_message alarm to terminate the handshake +* because the client receives a CCS with a value other than 0x01. +* 15. Before the session is recovered, the client receives a CCS whose value is not 0x01. Therefore, the +* client sends the unexpected_message alarm to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC008(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg sndMsg; + ASSERT_TRUE(memcpy_s(sndMsg.msg, MAX_RECORD_LENTH, ioServerData->sndMsg.msg, ioServerData->sndMsg.len) == EOK); + sndMsg.len = ioServerData->sndMsg.len; + ioServerData->sndMsg.len = 0; + uint8_t data = 2; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 10. After the session is resumed, the client sends the unexpected_message alarm to terminate the handshake + * because the client receives a CCS with a value other than 0x01. + * 15. Before the session is recovered, the client receives a CCS whose value is not 0x01. Therefore, the + * client sends the unexpected_message alarm to terminate the handshake. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC009 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 11. After the session is recovered, the client sends the "unexpected_message" alarm to terminate the +* handshake because the client receives the encrypted CCS. +* 16. The session is recovered. Before the client receives the finised message, the client sends the +* "unexpected_message" alarm to terminate the handshake because the client receives the encrypted CCS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC009(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + serverTlsCtx->recCtx->outBuf->end = 0; + uint32_t hashLen = SAL_CRYPT_DigestSize(serverTlsCtx->negotiatedInfo.cipherSuiteInfo.hashAlg); + ASSERT_EQ( + HS_SwitchTrafficKey(serverTlsCtx, serverTlsCtx->hsCtx->serverHsTrafficSecret, hashLen, true), HITLS_SUCCESS); + + uint8_t data = 1; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 11. After the session is recovered, the client sends the "unexpected_message" alarm to terminate the + * handshake because the client receives the encrypted CCS. + * 16. The session is recovered. Before the client receives the finised message, the client sends the + * "unexpected_message" alarm to terminate the handshake because the client receives the encrypted CCS. */ + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC010 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 12. Before the session is recovered, the server receives a CCS with a value other than 0x01 before receiving +* the client hello message. Therefore, the server sends the unexpected_message alarm to terminate the +* handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC010(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + + uint8_t data = 2; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 12. Before the session is recovered, the server receives a CCS with a value other than 0x01 before receiving + * the client hello message. Therefore, the server sends the unexpected_message alarm to terminate the + * handshake. */ + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC011 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 13. After receiving the client hello message, the server sends the unexpected_message alarm to terminate the +* handshake because the server receives a CCS with a value other than 0x01. +* 19. Before the session is recovered, the server sends the unexpected_message alarm to terminate the +* handshake because the server receives a CCS whose value is not 0x01. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC011(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + + clientTlsCtx->recCtx->outBuf->end = 0; + uint8_t data = 2; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 13. After receiving the client hello message, the server sends the unexpected_message alarm to terminate the + * handshake because the server receives a CCS with a value other than 0x01. + * 19. Before the session is recovered, the server sends the unexpected_message alarm to terminate the + * handshake because the server receives a CCS whose value is not 0x01. */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC012 +* @spec An implementation may receive an unencrypted record of +* type change_cipher_spec consisting of the single byte +* value 0x01 at any time after the first ClientHello message +* has been sent or received and before the peer's Finished message +* has been received and MUST simply drop it without further processing. +* @title When receiving an unencrypted CCS message, the system discards the message. +* @precon nan +* @brief 5 Record Protocol line 181 +* 14. After the session is recovered, the server sends the unexpected_message alarm to terminate the handshake +* because the server receives the encrypted CCS. +* 20. The session is recovered. Before the server receives the finised message, it receives the encrypted CCS. +* Therefore, the server sends the "unexpected_message" alarm to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC012(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FrameMsg recMsg; + ASSERT_TRUE(memcpy_s(recMsg.msg, MAX_RECORD_LENTH, ioServerData->recMsg.msg, ioServerData->recMsg.len) == EOK); + recMsg.len = ioServerData->recMsg.len; + ioServerData->recMsg.len = 0; + + clientTlsCtx->recCtx->outBuf->end = 0; + uint32_t hashLen = SAL_CRYPT_DigestSize(clientTlsCtx->negotiatedInfo.cipherSuiteInfo.hashAlg); + ASSERT_EQ( + HS_SwitchTrafficKey(clientTlsCtx, clientTlsCtx->hsCtx->serverHsTrafficSecret, hashLen, true), HITLS_SUCCESS); + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 14. After the session is recovered, the server sends the unexpected_message alarm to terminate the handshake + * because the server receives the encrypted CCS. + * 20. The session is recovered. Before the server receives the finised message, it receives the encrypted + * CCS. Therefore, the server sends the "unexpected_message" alarm to terminate the handshake. */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC013 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 17. After the session is recovered, the client receives a CCS whose value is not 0x01 and sends the +* unexpected_message alarm to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC013(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->sndMsg.len = sizeof(ccsMessage); + memcpy_s(ioServerData->sndMsg.msg, ioServerData->sndMsg.len, ccsMessage, sizeof(ccsMessage)); + ioServerData->sndMsg.msg[5] = 0x2; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 17. After the session is recovered, the client receives a CCS whose value is not 0x01 and sends the + * unexpected_message alarm to terminate the handshake. */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC014 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 18. After the session is recovered, the client receives the finised message and receives the encrypted CCS. +* Therefore, the client sends the unexpected_message alarm to terminate the handshake. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC014(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + uint8_t data = 1; + ASSERT_EQ(SendCcs(server->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ioServerData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + /* 18. After the session is recovered, the client receives the finised message and receives the encrypted CCS. + * Therefore, the client sends the unexpected_message alarm to terminate the handshake. */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(clientTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC015 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 21. After the session is recovered, the server sends the unexpected_message alarm to terminate the handshake +* because the server receives a CCS whose value is not 0x01. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC015(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->sndMsg.len = sizeof(ccsMessage); + memcpy_s(ioClientData->sndMsg.msg, ioClientData->sndMsg.len, ccsMessage, sizeof(ccsMessage)); + ioClientData->sndMsg.msg[5] = 0x2; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 21. After the session is recovered, the server sends the unexpected_message alarm to terminate the handshake + * because the server receives a CCS whose value is not 0x01. */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC016 +* @spec An implementation which receives any other change_cipher_spec value or +* which receives a protected change_cipher_spec record MUST +* abort the handshake with an "unexpected_message" alert. +* @title Send the unexpected_message alarm when receiving other CCS messages. +* @precon nan +* @brief 5 Record Protocol line 182 +* 22. After the session is recovered, the server sends the "unexpected_message" alarm to terminate the +* handshake because the server receives the encrypted CCS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC016(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + clientTlsCtx = FRAME_GetTlsCtx(client); + serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + uint8_t data = 1; + ASSERT_EQ(SendCcs(client->ssl, &data, sizeof(data)), HITLS_SUCCESS); + ioClientData->sndMsg.msg[0] = REC_TYPE_CHANGE_CIPHER_SPEC; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + /* 22. After the session is recovered, the server sends the "unexpected_message" alarm to terminate the + * handshake because the server receives the encrypted CCS. */ + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(serverTlsCtx, readBuf, READ_BUF_SIZE, &readLen), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC001 +* @spec Handshake messages MUST NOT be interleaved with other record types. +* That is, if a handshake message is split over two or more records, +* there MUST NOT be any other records between them. +* @title Handshake messages must not be interleaved with other record types. +* @precon nan +* @brief 5.1. Record Layer line 186 +* 1. Handshake messages are sent to multiple records. Check whether records of other types exist between +* the records. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, uint8_t *text, uint32_t *textLen, uint8_t *recType); +int32_t STUB_RecParseInnerPlaintext(TLS_Ctx *ctx, uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + (void)ctx; + (void)text; + (void)textLen; + *recType = (uint8_t)REC_TYPE_APP; + + return HITLS_SUCCESS; +} + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC002 +* @spec Handshake messages MUST NOT be interleaved with other record types. +* That is, if a handshake message is split over two or more records, +* there MUST NOT be any other records between them. +* @title Handshake messages must not be interleaved with other record types. +* @precon nan +* @brief 5.1. Record Layer line 186 +* 2. If multiple handshake messages are interspersed with other record (app) messages, the handshake fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC002(void) +{ + FRAME_Init(); + STUB_Init(); + FuncStubInfo tmpRpInfo; + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_FINISH) == HITLS_SUCCESS); + STUB_Replace(&tmpRpInfo, RecParseInnerPlaintext, STUB_RecParseInnerPlaintext); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + STUB_Reset(&tmpRpInfo); + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC001 +* @spec A record with an Alert type MUST contain exactly one message. +* @title A record with the Alert type must contain only one message. +* @precon nan +* @brief 5.1. Record Layer line 186 +* 1. The client sends multiple alarm messages, and the server handshake fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_FINISH) == HITLS_SUCCESS); + + clientTlsCtx->recCtx->outBuf->end = 0; + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.len = 0; + ASSERT_TRUE(SendErrorAlert(client->ssl, ALERT_LEVEL_WARNING, ALERT_NO_CERTIFICATE_RESERVED) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(client, server), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC002 +* @spec A record with an Alert type MUST contain exactly one message. +* @title A record with the Alert type must contain only one message. +* @precon nan +* @brief 5.1. Record Layer line 186 +* 2. When the server sends multiple alarm messages, the client handshake fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + /* Stop the client receiving the TRY_RECV_SERVER_HELLO state, and the server sending the TRY_SEND_SERVER_HELLO + * state. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + + serverTlsCtx->recCtx->outBuf->end = 0; + ASSERT_TRUE(SendErrorAlert(server->ssl, ALERT_LEVEL_WARNING, ALERT_NO_CERTIFICATE_RESERVED) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.len = 0; + ASSERT_EQ(FRAME_TrasferMsgBetweenLink(server, client), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC001 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* 1. In TLS1.3, legacy_record_version is 0x0303 in the record message of the CCS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + /* The client stops receiving the TRY_RECV_ENCRYPTED_EXTENSIONS. The server sends the EE message, but the EE message + * is cached because the CCS message is sent first. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_ENCRYPTED_EXTENSIONS) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_ENCRYPTED_EXTENSIONS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + FRAME_Msg frameMsg = {0}; + uint8_t *buffer = ioClientData->recMsg.msg; + uint32_t readLen = ioClientData->recMsg.len; + uint32_t parseLen = 0; + ASSERT_TRUE(ParserRecordHeader(&frameMsg, buffer, readLen, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.type, REC_TYPE_CHANGE_CIPHER_SPEC); + ASSERT_TRUE(frameMsg.version == HITLS_VERSION_TLS12); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC002 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* 2. In TLS1.3, legacy_record_version is 0x0303 in the alert record message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + + ASSERT_TRUE(SendAlert(server->ssl, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + FRAME_Msg frameMsg = {0}; + uint8_t *buffer = ioClientData->recMsg.msg; + uint32_t readLen = ioClientData->recMsg.len; + uint32_t parseLen = 0; + ASSERT_TRUE(ParserRecordHeader(&frameMsg, buffer, readLen, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.type, REC_TYPE_ALERT); + ASSERT_TRUE(frameMsg.version == HITLS_VERSION_TLS12); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC003 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* In 5. TLS1.3, legacy_record_version is set to 0x0301 in the record message of the init clienthello. +* In 3.TLS1.3, legacy_record_version is 0x0303 in the session recovery clienthello message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC003(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + FRAME_Msg frameMsg = {0}; + uint8_t *buffer = ioServerData->recMsg.msg; + uint32_t readLen = ioServerData->recMsg.len; + uint32_t parseLen = 0; + ASSERT_TRUE(ParserRecordHeader(&frameMsg, buffer, readLen, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.type, REC_TYPE_HANDSHAKE); + /* For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, + * where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility + * purposes, it may be 0x0301. */ + ASSERT_TRUE(frameMsg.version == HITLS_VERSION_TLS10); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ioServerData = BSL_UIO_GetUserData(server->io); + buffer = ioServerData->recMsg.msg; + readLen = ioServerData->recMsg.len; + parseLen = 0; + ASSERT_TRUE(ParserRecordHeader(&frameMsg, buffer, readLen, &parseLen) == HITLS_SUCCESS); + ASSERT_EQ(frameMsg.type, REC_TYPE_HANDSHAKE); + ASSERT_TRUE(frameMsg.version == HITLS_VERSION_TLS10); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC004 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* In TLS1.3, the value of legacy_record_version in the serverhello message is changed to 0xffff when the +* session is recovered, +* After the client receives the message, the client ignores this field and the session is successfully +* restored. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC004(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + uint32_t bufOffset = 1; + ioClientData->recMsg.msg[bufOffset] = 0x03; + bufOffset++; + ioClientData->recMsg.msg[bufOffset] = 0xff; + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC005 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* In TLS 7.1.3, the legacy_record_version field in the record message of the client hello message is changed to +* 0x0300. After the server receives the message, the server ignores the field and the handshake is still +* successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC005(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + uint32_t bufOffset = 1; + ioClientData->recMsg.msg[bufOffset] = 0x03; + bufOffset++; + ioClientData->recMsg.msg[bufOffset] = 0xff; + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC006 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* 8. The server uses TLS1.2 and the value of legacy_record_version in the record message is 0x0303, +* The client uses TLS 1.3 and the value of legacy_record_version in the record message is 0x0303. The +* handshake is still successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC006(void) +{ + FRAME_Init(); + HITLS_Config *clientConfig = HITLS_CFG_NewTLSConfig(); + HITLS_Config *serverConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(serverConfig != NULL); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(clientConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(serverConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(clientConfig); + HITLS_CFG_FreeConfig(serverConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC007 +* @spec legacy_record_version: MUST be set to 0x0303 +* for all records generated by a TLS 1.3 implementation +* other than an initial ClientHello (i.e., one not generated +* after a HelloRetryRequest), where it MAY also be 0x0301 +* for compatibility purposes. This field is deprecated +* and MUST be ignored for all purposes. Previous versions of +* TLS would use other values in this field under some circumstances. +* @title For all records generated by the TLS 1.3 implementation, it must be set to 0x0303, +* where the initial ClientHello (i.e., records not generated after HelloRetryRequest) For compatibility +* purposes, it may be 0x0301. +* @precon nan +* @brief 5.1. Record Layer line 190 +* 9. Change TLSCiphertext.legacy_record_version in the encryption record of the app to 0xffff, +* After the client receives the message, the client ignores this field and the session is still successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC007(void) +{ + FRAME_Init(); + HITLS_Config *clientConfig = HITLS_CFG_NewTLSConfig(); + HITLS_Config *serverConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(serverConfig != NULL); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(clientConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(serverConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(clientConfig); + HITLS_CFG_FreeConfig(serverConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC001 +* @spec length: The length (in bytes) of the following TLSCiphertext. +* encrypted_record, which is the sum of the lengths of the content and the padding, +* plus one for the inner content type, plus any expansion added by the AEAD algorithm. +* The length MUST NOT exceed 2^14 + 256 bytes. An endpoint that receives a record that +* exceeds this length MUST terminate the connection with a "record_overflow" alert. +* @title For TLS 1.3, the length of the ciphertext cannot exceed 2 ^ 14 + 256 bytes. +* @precon nan +* @brief 5.2. Record Payload Protection line 194 +* 1. A connection is established. During the connection establishment, the server receives a message whose +* ciphertext length is 2 ^ 14 + 257. The server is expected to send a record_overflow alarm to +* terminate the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + /* The client stops receiving the TRY_RECV_ENCRYPTED_EXTENSIONS. The server sends the EE message. However, the EE + * message is cached because the CCS message is sent first. */ + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CERTIFICATE) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.msg[3] = 0x41u; + ioServerData->recMsg.msg[4] = 0x01u; + /* For TLS 1.3, the length of the ciphertext cannot exceed 2 ^ 14 + 256 bytes. */ + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_REC_RECORD_OVERFLOW); + ALERT_Info info = {0}; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_RECORD_OVERFLOW); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC002 +* @spec length: The length (in bytes) of the following TLSCiphertext. +* encrypted_record, which is the sum of the lengths of the content and the padding, +* plus one for the inner content type, plus any expansion added by the AEAD algorithm. +* The length MUST NOT exceed 2^14 + 256 bytes. An endpoint that receives a record that +* exceeds this length MUST terminate the connection with a "record_overflow" alert. +* @title For TLS 1.3, the length of the ciphertext cannot exceed 2 ^ 14 + 256 bytes. +* @precon nan +* @brief 5.2. Record Payload Protection line 194 +* 2. A connection is established. During the connection establishment, the client receives a message whose ciphertext +* length is 2 ^ 14 + 257. The server is expected to send a record_overflow alarm to terminate the connection. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_ENCRYPTED_EXTENSIONS) == HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->hsCtx->state == TRY_SEND_ENCRYPTED_EXTENSIONS); + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->recMsg.msg[3] = 0x41u; + ioClientData->recMsg.msg[4] = 0x01u; + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_RECORD_OVERFLOW); + ALERT_Info info = {0}; + ALERT_GetInfo(client->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_RECORD_OVERFLOW); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC001 +* @spec Each sequence number is set to zero at the beginning of a connection and whenever the key is changed; +* the first record transmitted under a particular traffic key MUST use sequence number 0. +* @title The sequence number is 0 when the connection starts or the key changes. +* @precon nan +* @brief 5.3. Per-Record Nonce line 197 +* 1. The client sends a finish packet and an app packet. After the seq number is not 0, the key is changed +* successfully and the seq number is reset to 0. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Write(client->ssl, (uint8_t *)"Hello World", sizeof("Hello World")) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + REC_Ctx *recCtx = (REC_Ctx *)client->ssl->recCtx; + ASSERT_TRUE(recCtx->writeStates.currentState->seq != 0); + + ASSERT_TRUE(HITLS_KeyUpdate(client->ssl, HITLS_UPDATE_REQUESTED) == HITLS_SUCCESS); + ASSERT_TRUE(recCtx->writeStates.currentState->seq == 0); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002 +* @spec Each sequence number is set to zero at the beginning of a connection and whenever the key is changed; +* the first record transmitted under a particular traffic key MUST use sequence number 0. +* @title The sequence number is 0 when the connection starts or the key changes. +* @precon nan +* @brief 5.3. Per-Record Nonce line 197 +* 2. The client sends a finish packet and an app packet. After the seq number is not 0, the key fails to be +* changed and the key is updated, +* The seq number is not reset to 0. (It is to be confirmed whether the seq number is updated at both ends.) +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Write(client->ssl, (uint8_t *)"Hello World", sizeof("Hello World")) == HITLS_SUCCESS); + REC_Ctx *recCtx = (REC_Ctx *)client->ssl->recCtx; + ASSERT_TRUE(recCtx->writeStates.currentState->seq != 0); + + FrameUioUserData *ioClientData = BSL_UIO_GetUserData(client->io); + ioClientData->sndMsg.len = 1; + + ASSERT_TRUE(HITLS_KeyUpdate(client->ssl, HITLS_UPDATE_REQUESTED) == HITLS_REC_NORMAL_IO_BUSY); + ASSERT_TRUE(recCtx->writeStates.currentState->seq != 0); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003 +* @spec Each sequence number is set to zero at the beginning of a connection and whenever the key is changed; +* the first record transmitted under a particular traffic key MUST use sequence number 0. +* @title The sequence number is 0 when the connection starts or the key changes. +* @precon nan +* @brief 5.3. Per-Record Nonce line 197 +* 1. The client sends a finish packet and an app packet. After the seq number is not 0, the key is changed +* successfully and the seq number is reset to 0. +@ */ +/* BEGIN_CASE */ +void UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(tlsConfig != NULL); + + tlsConfig->isSupportExtendMasterSecret = true; + tlsConfig->isSupportClientVerify = true; + tlsConfig->isSupportNoClientCert = true; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + REC_Ctx *recCtx = (REC_Ctx *)server->ssl->recCtx; + ASSERT_TRUE(recCtx->writeStates.currentState->seq != 0); + + ASSERT_TRUE(HITLS_KeyUpdate(server->ssl, HITLS_UPDATE_REQUESTED) == HITLS_SUCCESS); + ASSERT_TRUE(recCtx->writeStates.currentState->seq == 0); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Write(server->ssl, (uint8_t *)"Hello World", sizeof("Hello World")) == HITLS_SUCCESS); + ASSERT_TRUE(recCtx->writeStates.currentState->seq == 1); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_record.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_record.data new file mode 100644 index 00000000..a6165255 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_record.data @@ -0,0 +1,110 @@ +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_IGNORE_CCS_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC008 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC008: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC009 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC009: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC010 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC010: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC011 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC011: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC012 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC012: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC013 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC013: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC014 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC014: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC015 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC015: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC016 +UT_TLS_TLS13_RFC8446_CONSISTENCY_RECEIVES_OTHER_CCS_FUNC_TC016: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_HANDSHAKE_RECORD_TYPE_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SINGLE_ALERT_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC003: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC004 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC004: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC005 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC005: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC006 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC006: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC007 +UT_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_RECORD_VERSION_FUNC_TC007: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_CIPHERTEXT_LENGTH_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC001 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC001: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002: + +UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003 +UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_1.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_1.c new file mode 100644 index 00000000..196f6efd --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_1.c @@ -0,0 +1,157 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "securec.h" +#include "rec_wrapper.h" +#include "conn_init.h" +#include "rec.h" +#include "parse.h" +#include "hs_msg.h" +#include "hs.h" +#include "alert.h" +#include "hitls_type.h" +#include "session_type.h" +#include "hitls_crypt_init.h" +#include "common_func.h" +#include "hlt.h" +#include "process.h" +#include "rec_read.h" +/* END_HEADER */ + +#define g_uiPort 6543 +// REC_Read calls TlsRecordRead calls RecParseInnerPlaintext +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType); + +int32_t STUB_RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + (void)ctx; + (void)text; + (void)textLen; + *recType = (uint8_t)REC_TYPE_APP; + + return HITLS_SUCCESS; +} +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} ResumeTestInfo; + +static void TestFrameChangeCerts(void *msg, void *data) +{ + (void)data; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + FRAME_CertificateMsg *certicate = &frameMsg->body.hsMsg.body.certificate; + FrameCertItem *cert = certicate->certItem->next->next; // 1 ->2 ->3 ->0 + cert->next = certicate->certItem->next; // 3->2 + certicate->certItem->next = cert; // 1->3 + cert->next->next = NULL; // 2-> 0 +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_TWO_DISOEDER_CHAIN_CERT_FUNC_TC001 +* @spec - +* @title The certificate chain sent by the server contains two intermediate certificates, which are out of order +* (excluding the device certificate). +* @precon nan +* @brief The sender' s certificate MUST come in the first CertificateEntry in the list. +* 1. The certificate chain sent by the server contains two intermediate certificates, and the two intermediate +* certificates are out of order. Expected result 1 is displayed. +* @expect 1. The connection fails to be established. The error code is ALERT_BAD_CERTIFICATIONATE. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_TWO_DISOEDER_CHAIN_CERT_FUNC_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverCtxConfig = NULL; + HLT_Ctx_Config *clientCtxConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha512/otherRoot.der", + "rsa_sha512/otherInter.der:rsa_sha512/otherInter2.der", + "rsa_sha512/otherEnd.der", + "rsa_sha512/otherEnd.key.der", + "NULL", + "NULL"); + HLT_SetClientVerifySupport(serverCtxConfig, true); + clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + HLT_SetCertPath(clientCtxConfig, + "rsa_sha512/otherRoot.der", + "rsa_sha512/otherInter.der:rsa_sha512/otherInter2.der", + "rsa_sha512/otherEnd.der", + "rsa_sha512/otherEnd.key.der", + "NULL", + "NULL"); + HLT_SetClientVerifySupport(clientCtxConfig, true); + HLT_SetCipherSuites(clientCtxConfig, "HITLS_RSA_WITH_AES_256_CBC_SHA"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + HLT_FrameHandle frameHandle = { + .ctx = serverRes->ssl, + /* 1. The certificate chain sent by the server contains two intermediate certificates, and the two intermediate + * certificates are out of order. */ + .frameCallBack = TestFrameChangeCerts, + .userData = NULL, + .expectHsType = CERTIFICATE, + .expectReType = REC_TYPE_HANDSHAKE, + .ioState = EXP_NONE, + .pointType = POINT_SEND, + }; + ASSERT_TRUE(HLT_SetFrameHandle(&frameHandle) == HITLS_SUCCESS); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); +exit: + HLT_FreeAllProcess(); + HLT_CleanFrameHandle(); + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_1.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_1.data new file mode 100644 index 00000000..b65dff14 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_1.data @@ -0,0 +1,2 @@ +SDV_TLS_TLS13_RFC8446_CONSISTENCY_TWO_DISOEDER_CHAIN_CERT_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_TWO_DISOEDER_CHAIN_CERT_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_2.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_2.c new file mode 100644 index 00000000..328fa82d --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_2.c @@ -0,0 +1,434 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "bsl_sal.h" +#include "tls.h" +#include "hlt.h" +#include "hlt_type.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "cert.h" +#include "process.h" +#include "securec.h" +#include "session_type.h" +#include "rec_wrapper.h" +#include "common_func.h" +#include "conn_init.h" +#include "hs_extensions.h" +#include "hitls_crypt_init.h" +/* END_HEADER */ + +#define PORT 23456 +#define READ_BUF_SIZE (18 * 1024) + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; // Set the session to the client for session recovery. + HITLS_TicketKeyCb serverKeyCb; +} ResumeTestInfo; + +typedef struct{ + char *ClientCipherSuite; + char *ServerCipherSuite; + char *ClientGroup; + char *ServerGroup; + uint8_t ClientKeyExchangeMode; + uint8_t ServerKeyExchangeMode; + uint8_t psk[PSK_MAX_LEN]; + bool SetNothing; + bool SuccessOrFail; +} SetInfo; + +void SetConfig(HLT_Ctx_Config *clientconfig, HLT_Ctx_Config *serverconfig, SetInfo setInfo) +{ + if ( !setInfo.SetNothing ) { + + // Configure the server configuration. + if (setInfo.ServerCipherSuite != NULL) { + HLT_SetCipherSuites(serverconfig, setInfo.ServerCipherSuite); + } + if (setInfo.ServerGroup != NULL) { + HLT_SetGroups(serverconfig, setInfo.ServerGroup); + } + memcpy_s(serverconfig->psk, PSK_MAX_LEN, setInfo.psk, sizeof(setInfo.psk)); + + if ( (setInfo.ClientKeyExchangeMode & (TLS13_KE_MODE_PSK_WITH_DHE | TLS13_KE_MODE_PSK_ONLY)) != 0) { + clientconfig->keyExchMode = setInfo.ClientKeyExchangeMode; + } + + // Configure the client configuration. + if (setInfo.ClientCipherSuite != NULL) { + HLT_SetCipherSuites(clientconfig, setInfo.ClientCipherSuite); + } + if (setInfo.ClientGroup != NULL) { + HLT_SetGroups(clientconfig, setInfo.ClientGroup); + } + memcpy_s(clientconfig->psk, PSK_MAX_LEN, setInfo.psk, sizeof(setInfo.psk)); + if ( (setInfo.ServerKeyExchangeMode & (TLS13_KE_MODE_PSK_WITH_DHE | TLS13_KE_MODE_PSK_ONLY)) != 0) { + serverconfig->keyExchMode = setInfo.ServerKeyExchangeMode; + } + } +} + +void ClientCreatConnectWithPara(HLT_FrameHandle *handle, SetInfo setInfo) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + // Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // The local client and remote server listen on the TLS connection. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the config file. + SetConfig(clientConfig, serverConfig, setInfo); + + // Listening connection. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + // Configure the interface for constructing abnormal messages. + handle->ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + // Establish a connection. + if ( setInfo.SuccessOrFail ) { + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) == 0); + }else { + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + } + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ServerCreatConnectWithPara(HLT_FrameHandle *handle, SetInfo setInfo) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + // Create a process. + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // The local client and remote server listen on the TLS connection. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the config file. + SetConfig(clientConfig, serverConfig, setInfo); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // Insert abnormal message callback. + handle->ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + + // Client listening connection. + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientConfig, NULL); + + if ( setInfo.SuccessOrFail ) { + ASSERT_TRUE(clientRes != NULL); + }else { + ASSERT_TRUE(clientRes == NULL); + } + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +void ResumeConnectWithPara(HLT_FrameHandle *handle, SetInfo setInfo) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + int32_t cnt = 1; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for the config context. + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, TLS1_3, false); + void *clientConfig = HLT_TlsNewCtx(TLS1_3); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the session restoration function. + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + if (cnt == 2) { + SetConfig(clientCtxConfig, serverCtxConfig, setInfo); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + } + DataChannelParam channelParam; + channelParam.port = PORT; + channelParam.type = TCP; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = TCP; + localProcess->connType = TCP; + + // The server applies for the context. + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = TCP; + // Set the FD. + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + // Client, applying for context + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = TCP; + + // Set the FD. + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + handle->ctx = clientSsl; + ASSERT_TRUE(HLT_SetFrameHandle(handle) == 0); + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + + if(!setInfo.SuccessOrFail){ + ASSERT_TRUE(HLT_TlsConnect(clientSsl) != 0); + }else { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } + } + else { + // Negotiation + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + // Data read/write + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + // Disable the connection. + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + ASSERT_TRUE(HITLS_SESS_HasTicket(session) == true); + ASSERT_TRUE(HITLS_SESS_IsResumable(session) == true); + }cnt++; + } while (cnt < 3); // Perform the connection twice. + +exit: + HITLS_SESS_Free(session); + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + return; +} + +static void FrameCallBack_ClientHello_PskBinder_Miss(void *msg, void *userData) +{ + // ClientHello exception: The Binder field in the ClientHello message is lost. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clienthello = &frameMsg->body.hsMsg.body.clientHello; + + clienthello->psks.binders.state = MISSING_FIELD; + clienthello->psks.binderSize.state = ASSIGNED_FIELD; + clienthello->psks.binderSize.data = 0; + clienthello->psks.exLen.state = INITIAL_FIELD; + +exit: + return; +} + +static void FrameCallBack_ClientHello_LegacyVersion_Unsafe(void *msg, void *userData) +{ + // ClientHello exception: The sent ClientHello message has its LegacyVersion set to SSL3.0. + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ClientHelloMsg *clienthello = &frameMsg->body.hsMsg.body.clientHello; + + clienthello->version.state = ASSIGNED_FIELD; + clienthello->version.data = HITLS_VERSION_SSL30; +exit: + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC002 +* @brief 4.2.11-Pre-Shared Key Extension-97 +* @spec the server MUST validate the corresponding binder value (see Section 4.2.11.2 below). +* If this value is not present or does not validate, the server MUST abort the handshake. +* @title Modify the binder of client hello so that it is lost. +* @precon nan +* @brief +* 1. The connection is established and the session is restored. +* 2. Modify the binder in the psk extension of the client hello message sent by the client so that the binder is lost. +* Observe the behavior of the server. +* @expect +* 1. The setting is successful. +* 2. The server terminates the handshake. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC002() +{ + // The connection is established and the session is restored. + SetInfo setInfo = {0}; + setInfo.SetNothing = 1; + setInfo.SuccessOrFail = 0; + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + // Modify the binder in the psk extension of the client hello message sent by the client so that the binder is lost. + // Observe the behavior of the server. + handle.frameCallBack = FrameCallBack_ClientHello_PskBinder_Miss; + ResumeConnectWithPara(&handle, setInfo); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001 +* @brief 4.2.11-Pre-Shared Key Extension-97 +* @spec Implementations MUST NOT send a ClientHello.legacy_version or ServerHello.legacy_version set to 0x0300 or less. +* Any endpoint receiving a Hello message with ClientHello.legacy_version or ServerHello.legacy_version set to +* 0x0300 MUST abort the handshake with a "protocol_version" alert. +* @title The server receives a client hello message whose legacy_version is 0x0300. +* @precon nan +* @brief +* 1. Change the value of legacy_version in the client Hello message to 0x0300. +* 2. Observe the server behavior. +* @expect +* 1. The setting is successful. +* 2. The server terminates the handshake. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001() +{ + // Change the value of legacy_version in the client Hello message to 0x0300. + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Observe the server behavior. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = CLIENT_HELLO; + handle.frameCallBack = FrameCallBack_ClientHello_LegacyVersion_Unsafe; + handle.ctx = clientRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(&handle) == 0); + + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) != 0); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_2.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_2.data new file mode 100644 index 00000000..83e2f858 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_2.data @@ -0,0 +1,5 @@ +SDV_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_LEGACY_VERSION_FUNC_TC001: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKBINDER_FUNC_TC002: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_extensions.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_extensions.c new file mode 100644 index 00000000..8cb5ebee --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_extensions.c @@ -0,0 +1,1134 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "rec_wrapper.h" +#include "cert.h" +#include "securec.h" +#include "process.h" +#include "conn_init.h" +#include "hitls_crypt_init.h" +#include "hitls_psk.h" +#include "common_func.h" +#include "alert.h" +#include "bsl_sal.h" +/* END_HEADER */ +#define MAX_BUF 16384 + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; +} ResumeTestInfo; + +static void Test_Client_Mode(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.pskModes.exData.state = ASSIGNED_FIELD; + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.pskModes.exData.data); + uint16_t version[] = { 0x03, }; + frameMsg.body.hsMsg.body.clientHello.pskModes.exData.data = + BSL_SAL_Calloc(sizeof(version) / sizeof(uint8_t), sizeof(uint8_t)); + ASSERT_EQ(memcpy_s(frameMsg.body.hsMsg.body.clientHello.pskModes.exData.data, + sizeof(version), version, sizeof(version)), EOK); + frameMsg.body.hsMsg.body.clientHello.keyshares.exState = MISSING_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.state = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Server_Keyshare(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + frameMsg.body.hsMsg.body.serverHello.keyShare.data.state = ASSIGNED_FIELD; + + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data = *(uint64_t *)user; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + + + +#define TEST_SERVERNAME_LENGTH 20 +#define BUF_SIZE_DTO_TEST 18432 +#define ROOT_DER "%s/ca.der:%s/inter.der" +#define INTCA_DER "%s/inter.der" +#define SERVER_DER "%s/server.der" +#define SERVER_KEY_DER "%s/server.key.der" +#define CLIENT_DER "%s/client.der" +#define CLIENT_KEY_DER "%s/client.key.der" +#define IP_ADDR_MAX_LEN 16 +#define BYTE_SIZE 8 +#define SNI_TYPE 2 +#define LARGE_SIZE 1025 + +static int SetCertPath(HLT_Ctx_Config *ctxConfig, const char *certStr, bool isServer) +{ + int ret; + char caCertPath[50]; + char chainCertPath[30]; + char eeCertPath[30]; + char privKeyPath[30]; + + ret = sprintf_s(caCertPath, sizeof(caCertPath), ROOT_DER, certStr, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(chainCertPath, sizeof(chainCertPath), INTCA_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(eeCertPath, sizeof(eeCertPath), isServer ? SERVER_DER : CLIENT_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(privKeyPath, sizeof(privKeyPath), isServer ? SERVER_KEY_DER : CLIENT_KEY_DER, certStr); + ASSERT_TRUE(ret > 0); + HLT_SetCaCertPath(ctxConfig, (char *)caCertPath); + HLT_SetChainCertPath(ctxConfig, (char *)chainCertPath); + HLT_SetEeCertPath(ctxConfig, (char *)eeCertPath); + HLT_SetPrivKeyPath(ctxConfig, (char *)privKeyPath); + return 0; +exit: + return -1; +} + +static void Test_Server_SVersion2(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + frameMsg.body.hsMsg.body.serverHello.supportedVersion.data.data = *(uint64_t *)user; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/* BEGIN_CASE */ +void HITLS_TLS1_2_Config_SDV_23_0_5_0430(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Client_Mode + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetCertPath(clientCtxConfig, "ecdsa_sha256/ca.der", "NULL", "NULL", "NULL", "NULL", "NULL"); + + clientRes = HLT_ProcessTlsInit(localProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001 +* @spec - +* @title Initialize the client server to tls1.3 and construct the selected_group carried in the key_share extension in +* the sent serverhello message. It is not the group of the keyshareentry carried in the clienthello message or +* the group provided in the clienthello message. As a result, the connection setup fails. +* @precon nan +* @brief 4.2.8. Key Share line 72 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + uint64_t groupreturn[] = {HITLS_EC_GROUP_SM2, }; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &groupreturn, + Test_Server_Keyshare + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetTls13CipherSuites(serverCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1:HITLS_EC_GROUP_SECP384R1"); + HLT_SetTls13CipherSuites(clientCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_SEND); + ASSERT_EQ(HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ(HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), ALERT_ILLEGAL_PARAMETER); + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +static void Test_Server_Keyshare1(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + ASSERT_TRUE(frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data == *(uint64_t *)user); + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC002 +* @spec - +* @title clientHello's supported_groups is set to secp256r1. The handshake is successful. +* @precon nan +* @brief 9.1. Mandatory-to-Implement Cipher Suites line 230 +* @expect 1. Expected connection setup success +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC002(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[BUF_SIZE_DTO_TEST] = {0}; + uint32_t readLen; + + uint64_t groupreturn[] = {HITLS_EC_GROUP_SECP256R1, }; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &groupreturn, + Test_Server_Keyshare1 + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetTls13CipherSuites(serverCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1"); + HLT_SetTls13CipherSuites(clientCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_SUCCESS); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, clientRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, BUF_SIZE_DTO_TEST, 0, BUF_SIZE_DTO_TEST) == EOK); + ASSERT_TRUE(HLT_TlsRead(serverRes->ssl, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC003 +* @spec - +* @title clientHello's supported_groups is set to X25519. The handshake succeeds. +* @precon nan +* @brief 9.1. Mandatory-to-Implement Cipher Suites line 230 +* @expect 1. Expected connection setup success +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC003(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[BUF_SIZE_DTO_TEST] = {0}; + uint32_t readLen; + uint64_t groupreturn[] = {HITLS_EC_GROUP_CURVE25519, }; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &groupreturn, + Test_Server_Keyshare1 + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetTls13CipherSuites(serverCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_CURVE25519"); + HLT_SetTls13CipherSuites(clientCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_SUCCESS); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, clientRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, BUF_SIZE_DTO_TEST, 0, BUF_SIZE_DTO_TEST) == EOK); + ASSERT_TRUE(HLT_TlsRead(serverRes->ssl, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +#define HS_RANDOM_SIZE 32u +static const uint8_t g_hrrRandom[HS_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, + 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c +}; + +static void Test_Server_Keyshare2(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + if (memcmp(frameMsg.body.hsMsg.body.serverHello.randomValue.data, g_hrrRandom, HS_RANDOM_SIZE) != 0) { + frameMsg.body.hsMsg.body.serverHello.keyShare.data.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.serverHello.keyShare.data.group.data = *(uint64_t *)user; + } + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_NAMEDGROUP_FUNC_TC001 +* @spec - +* @title 1. Initialize the client and server to tls1.3, construct the scenario where ecdhe is used, construct the +* scenario where hrr is sent, and construct the sent serverhello. The named group of the is different from +* that in the hrr. It is expected that the client terminates the handshake and sends the illegal_parameter +* alarm. +* @precon nan +* @brief 4.2.8. Key Share line 74 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_NAMEDGROUP_FUNC_TC001(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + uint64_t groupreturn[] = {HITLS_EC_GROUP_SM2, }; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &groupreturn, + Test_Server_Keyshare2 + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetGroups(serverCtxConfig, "HITLS_EC_GROUP_CURVE25519:HITLS_EC_GROUP_SECP384R1"); + HLT_SetTls13CipherSuites(serverCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1:HITLS_EC_GROUP_SECP384R1"); + HLT_SetTls13CipherSuites(clientCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_SEND); + ASSERT_EQ(HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ(HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), ALERT_ILLEGAL_PARAMETER); + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +static void Test_Server_SVersion(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.cipherSuites.data); + uint16_t ciphers[3] = { 0xC02C, 0x1302, 0x1303}; + frameMsg.body.hsMsg.body.clientHello.cipherSuites.data = + BSL_SAL_Calloc(sizeof(ciphers) / sizeof(uint16_t) + 1, sizeof(uint16_t)); + ASSERT_EQ(memcpy_s(frameMsg.body.hsMsg.body.clientHello.cipherSuites.data, + sizeof(ciphers), ciphers, sizeof(ciphers)), EOK); + frameMsg.body.hsMsg.body.clientHello.cipherSuites.state = ASSIGNED_FIELD; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001 +* @spec - +* @title The supported_versions in the clientHello is extended to 0x0304 (TLS 1.3). If the server supports only 1.2, the +* server returns a "protocol_version" warning and the handshake fails. +* @precon nan +* @brief Appendix D. Backward Compatibility line 247 +* @expect +* 1. The setting is successful. +* 2. The setting is successful. +* 3. The connection is set up successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001( ) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Server_SVersion + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_3, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(clientRes->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC002 +* @spec - +* @title The supported_versions field in clientHello is extended to 0x0304 (TLS 1.3). If the server supports TLS 1.3, +* the server returns serverHello, If the value of upported_versions is changed to 0x0300, the client returns the +* warning "ALERT_ELLEGAL_PARAMETER" and the handshake fails. +* @precon nan +* @brief Appendix D. Backward Compatibility line 247 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC002(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + uint64_t versions[] = {0x0300, }; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + &versions, + Test_Server_SVersion2 + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetTls13CipherSuites(serverCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath(clientCtxConfig, "ecdsa_sha256", false); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP256R1:HITLS_EC_GROUP_SECP384R1"); + HLT_SetTls13CipherSuites(clientCtxConfig, "HITLS_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_SEND); + ASSERT_EQ(HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ(HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), ALERT_PROTOCOL_VERSION); + +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +static void Test_Server_SVersion3(void *msg, void *userData) +{ + HLT_FrameHandle *handle = (HLT_FrameHandle *)userData; + FRAME_Msg *frameMsg = (FRAME_Msg *)msg; + ASSERT_EQ(frameMsg->body.hsMsg.type.data, handle->expectHsType); + FRAME_ServerHelloMsg *serverhello = &frameMsg->body.hsMsg.body.serverHello; + + serverhello->supportedVersion.exState = INITIAL_FIELD; + serverhello->supportedVersion.exLen.state = INITIAL_FIELD; + serverhello->supportedVersion.data.state = INITIAL_FIELD; + serverhello->supportedVersion.data.data = 0x0304; + + FRAME_ModifyMsgInteger(HS_EX_TYPE_SUPPORTED_VERSIONS, &serverhello->supportedVersion.exType); +exit: + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC003 +* @spec - +* @title clientHello version is 0x0303 and the server supports 1.3 and 1.2. In this case, the server returns +* serverHello and selects version 1.2, If supported_versions is set to 0x0304, the client returns a +* "ALERT_UNSUPPORTED_EXTENSION" warning and the handshake fails. +* @precon nan +* @brief Appendix D. Backward Compatibility line 247 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC003() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL,"SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + HLT_SetVersion(serverCtxConfig, HITLS_VERSION_TLS12, HITLS_VERSION_TLS13); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL,"CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_CleanFrameHandle(); + HLT_FrameHandle handle = {0}; + handle.pointType = POINT_SEND; + handle.userData = (void *)&handle; + handle.expectReType = REC_TYPE_HANDSHAKE; + handle.expectHsType = SERVER_HELLO; + handle.frameCallBack = Test_Server_SVersion3; + handle.ctx = serverRes->ssl; + ASSERT_TRUE(HLT_SetFrameHandle(&handle) == 0); + + clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + ASSERT_EQ(HLT_RpcTlsGetAlertFlag(remoteProcess, clientRes->sslId), ALERT_FLAG_SEND); + ASSERT_EQ(HLT_RpcTlsGetAlertLevel(remoteProcess, clientRes->sslId), ALERT_LEVEL_FATAL); + ASSERT_EQ(HLT_RpcTlsGetAlertDescription(remoteProcess, clientRes->sslId), ALERT_UNSUPPORTED_EXTENSION); +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +static void Test_Server_SVersion6(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.version.data = 0x0304; + frameMsg.body.hsMsg.body.clientHello.supportedVersion.exState = MISSING_FIELD; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC010 +* @spec - +* @title ClientHello "supported_versions" extension does not exist, and ClientHello.legacy_version is TLS 1.3, +* The server supports TLS 1.3. Check that the server aborts the handshake with the "protocol_version" alert. +* @precon nan +* @brief Appendix D. Backward Compatibility line 248 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC010() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Server_SVersion6 + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL,"SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL,"CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_3, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(clientRes->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_RECV); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC012 +* @spec - +* @title ClientHello "supported_versions" extension does not exist, and ClientHello.legacy_version is TLS 1.2, +* The server only supports TLS 1.3. Check that the server aborts the handshake with the "protocol_version" +* alert. +* @precon nan +* @brief Appendix D. Backward Compatibility line 248 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC012() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL,"SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + HLT_SetVersion(serverCtxConfig, HITLS_VERSION_TLS13, HITLS_VERSION_TLS13); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL,"CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + clientRes = HLT_ProcessTlsInit(localProcess, TLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_TlsConnect(clientRes->ssl), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(clientRes->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_RECV); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_PROTOCOL_VERSION); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +static void Test_Server_MasterExtKey(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS12; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS12; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + ASSERT_TRUE(frameMsg.body.hsMsg.body.serverHello.extendedMasterSecret.exState == INITIAL_FIELD); + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_MASTEREXTKEY_FUNC_TC001 +* @spec - +* @title tls1.2 and tls1.3 carry the extended master key (overwrite the old and new versions). The handshake is +* successful. +* @precon nan +* @brief Appendix D. Backward Compatibility line 244 +* @expect 1. Expected connection setup failure +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_MASTEREXTKEY_FUNC_TC001() +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[BUF_SIZE_DTO_TEST] = {0}; + uint32_t readLen; + + RecWrapper wrapper = { + TRY_SEND_SERVER_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Server_MasterExtKey + }; + RegisterWrapper(wrapper); + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL,"SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + HLT_SetVersion(serverCtxConfig, HITLS_VERSION_TLS12, HITLS_VERSION_TLS13); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL,"CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + clientRes = HLT_ProcessTlsInit(remoteProcess, TLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_SUCCESS); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, clientRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, BUF_SIZE_DTO_TEST, 0, BUF_SIZE_DTO_TEST) == EOK); + ASSERT_TRUE(HLT_TlsRead(serverRes->ssl, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +static void Test_Client_PskTicket(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + frameMsg.body.hsMsg.body.clientHello.psks.identities.data->identity.data[0] = 0x01; + + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKET_FUNC_TC001 +* @spec - +* @title After the first connection is established, the ticket value is changed during session recovery. The session +* recovery is expected to fail. +* @precon nan +* @brief 4.6.1. New Session Ticket Message line 158 +* @expect 1. Failed to restore the expected session. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKET_FUNC_TC001(int version, int connType) +{ + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + HITLS_Session *session = NULL; + const char *writeBuf = "Hello world"; + uint8_t readBuf[BUF_SIZE_DTO_TEST] = {0}; + uint32_t readLen; + int32_t cnt = 0; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportRenegotiation = false; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportRenegotiation = false; + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + DataChannelParam channelParam; + channelParam.port = g_uiPort; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + + if (cnt != 0) { + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Client_PskTicket + }; + RegisterWrapper(wrapper); + } + + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, BUF_SIZE_DTO_TEST, 0, BUF_SIZE_DTO_TEST) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, BUF_SIZE_DTO_TEST, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsClose(remoteProcess, serverSslId) == 0); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + + if (cnt != 0) { + HITLS_SESS_Free(session); + session = NULL; + + uint8_t isReused = 0; + ASSERT_TRUE(HITLS_IsSessionReused(clientSsl, &isReused) == HITLS_SUCCESS); + ASSERT_TRUE(isReused == 0); + } + + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + cnt++; + } while (cnt < 2); + +exit: + ClearWrapper(); + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_extensions.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_extensions.data new file mode 100644 index 00000000..fc3bb892 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_extensions.data @@ -0,0 +1,35 @@ +HITLS_TLS1_2_Config_SDV_23_0_5_0430 +HITLS_TLS1_2_Config_SDV_23_0_5_0430:TLS1_3:TCP + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC001:TLS1_3:TCP + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC002:TLS1_3:TCP + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_KEYSHAREGROUP_FUNC_TC003:TLS1_3:TCP + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_NAMEDGROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_NAMEDGROUP_FUNC_TC001:TLS1_3:TCP + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC001: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC002:TLS1_3:TCP + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC003: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC010 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC010: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC012 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_SVERSION_FUNC_TC012: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_MASTEREXTKEY_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_MASTEREXTKEY_FUNC_TC001: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKET_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_PSKTICKET_FUNC_TC001:TLS1_3:TCP \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_ffdhe.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_ffdhe.c new file mode 100644 index 00000000..c77a9adf --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_ffdhe.c @@ -0,0 +1,909 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "rec_wrapper.h" +#include "cert.h" +#include "securec.h" +#include "conn_init.h" +#include "hitls_crypt_init.h" +#include "hitls_psk.h" +#include "common_func.h" +#include "alert.h" +#include "process.h" +#include "bsl_sal.h" +/* END_HEADER */ + +#define PORT 6666 +#define MAX_BUF_SIZE 18432 + +void GetStrGroup(int ConnType, int group, char** strgroup) +{ + if (ConnType == HITLS) { + switch (group) { + case HITLS_FF_DHE_2048: + *strgroup = "HITLS_FF_DHE_2048";break; + case HITLS_FF_DHE_3072: + *strgroup = "HITLS_FF_DHE_3072";break; + case HITLS_FF_DHE_4096: + *strgroup = "HITLS_FF_DHE_4096";break; + case HITLS_FF_DHE_6144: + *strgroup = "HITLS_FF_DHE_6144";break; + case HITLS_FF_DHE_8192: + *strgroup = "HITLS_FF_DHE_8192";break; + default: + break; + } + } else { + switch (group) { + case HITLS_FF_DHE_2048: + *strgroup = "ffdhe2048";break; + case HITLS_FF_DHE_3072: + *strgroup = "ffdhe3072";break; + case HITLS_FF_DHE_4096: + *strgroup = "ffdhe4096";break; + case HITLS_FF_DHE_6144: + *strgroup = "ffdhe6144";break; + case HITLS_FF_DHE_8192: + *strgroup = "ffdhe8192";break; + default: + break; + } + } +} + +void HRR_ClientGroupSetInfo(int ClientType, int group, char** clientgroup) +{ + if (ClientType == HITLS) { + switch (group) { + case HITLS_FF_DHE_2048: + *clientgroup = "HITLS_EC_GROUP_SECP256R1:HITLS_FF_DHE_2048";break; + case HITLS_FF_DHE_3072: + *clientgroup = "HITLS_EC_GROUP_SECP256R1:HITLS_FF_DHE_3072";break; + case HITLS_FF_DHE_4096: + *clientgroup = "HITLS_EC_GROUP_SECP256R1:HITLS_FF_DHE_4096";break; + case HITLS_FF_DHE_6144: + *clientgroup = "HITLS_EC_GROUP_SECP256R1:HITLS_FF_DHE_6144";break; + case HITLS_FF_DHE_8192: + *clientgroup = "HITLS_EC_GROUP_SECP256R1:HITLS_FF_DHE_8192";break; + default: + break; + } + } else { + switch (group) { + case HITLS_FF_DHE_2048: + *clientgroup = "P-256:ffdhe2048";break; + case HITLS_FF_DHE_3072: + *clientgroup = "P-256:ffdhe3072";break; + case HITLS_FF_DHE_4096: + *clientgroup = "P-256:ffdhe4096";break; + case HITLS_FF_DHE_6144: + *clientgroup = "P-256:ffdhe6144";break; + case HITLS_FF_DHE_8192: + *clientgroup = "P-256:ffdhe8192";break; + default: + break; + } + } +} + +static void Test_FFDHE_Key_ERROR(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.state = ASSIGNED_FIELD; + + memset_s(frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.data, + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.data, 255, + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.data ); + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_FFDHE_Key_Client_DecodeError(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.state = ASSIGNED_FIELD; + + memset_s(frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.data, + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.data, 8, 10); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_FFDHE_KeyLen_LessThenStandard(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exLen.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exLen.data += (120 - 256); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShareLen.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShareLen.data += (120 - 256); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.data = 120; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.state = ASSIGNED_FIELD; + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.data); + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.data = BSL_SAL_Malloc(120); + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.size = 120; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_FFDHE_KeyLen_MoreThenStandard(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exLen.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exLen.data += (1100 - 256); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShareLen.state = INITIAL_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShareLen.data += (1100 - 256); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.data = 1100; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.state = ASSIGNED_FIELD; + BSL_SAL_FREE(frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.data); + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.data = BSL_SAL_Malloc(1100); + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchange.size = 1100; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_FFDHE_KeyLen_Error(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = { 0 }; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = { 0 }; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.clientHello.keyshares.exKeyShares.data->keyExchangeLen.data = 128; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** + * @brief tls1.3 ffdhe base testcase + * base test case + */ +/* BEGIN_CASE */ +void UT_TLS13_RFC8446_FFDHE_TC001() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + HLT_SetGroups(clientCtxConfig, "HITLS_FF_DHE_4096"); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->securitylevel = 0; + HLT_SetGroups(serverCtxConfig, "HITLS_FF_DHE_4096"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001 +* @spec - +* @title Verifying the HRR Link Setup Function When the FFDHE Group Is Used +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Configure the client and server to support ffdhe2048, and set the client to ffdhe2048 as the second supported +& group. +* 3. Establish a connection and read and write data. +* 4. Switch the group to ffdhe3072, ffdhe4096, ffdhe6144, and ffdhe8192. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The connection is set up successfully, and data is read and written successfully. +* 4. The connection is set up successfully and data is read and written successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001(int group) +{ + FRAME_Init(); + int32_t ret; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(c_config != NULL); + HITLS_Config *s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(s_config != NULL); + + uint16_t groups = group; + uint16_t clientGroups[2] = {HITLS_EC_GROUP_SECP256R1}; + clientGroups[1] = group; + HITLS_CFG_SetGroups(c_config, clientGroups, 2); + HITLS_CFG_SetGroups(s_config, &groups, 1); + + client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ret = FRAME_CreateConnection(client, server, false, HS_STATE_BUTT); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(server->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_EQ(client->ssl->negotiatedInfo.negotiatedGroup, group); + + uint8_t data[] = "Hello World"; + ASSERT_TRUE(HITLS_Write(client->ssl, data, strlen("Hello World")) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[MAX_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_TRUE(HITLS_Read(server->ssl, readBuf, MAX_BUF_SIZE, &readLen) == HITLS_SUCCESS); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); +exit: + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002 +* @spec - +* @title Verifying the FFDHE Curve Function in PSK Link Establishment +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Set the PSK mode to psk_with_dhe. +* 3. Configure the client and server to support FFDHE2048. +* 4. Establish a connection and read and write data. +* 5. Switch the group to ffdhe3072, ffdhe4096, ffdhe6144, and ffdhe8192. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The connection is set up successfully and data is read and written successfully. +* 5. The connection is successfully set up, and data is successfully read and written. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002(int group) +{ + FRAME_Init(); + int32_t ret; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(c_config != NULL); + HITLS_Config *s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(s_config != NULL); + + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(c_config, &cipherSuite, 1); + HITLS_CFG_SetCipherSuites(s_config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(c_config, TLS13_KE_MODE_PSK_WITH_DHE); + HITLS_CFG_SetKeyExchMode(s_config, TLS13_KE_MODE_PSK_WITH_DHE); + uint16_t groups = group; + HITLS_CFG_SetGroups(c_config, &groups, 1); + HITLS_CFG_SetGroups(s_config, &groups, 1); + HITLS_CFG_SetPskClientCallback(c_config, ExampleClientCb); + HITLS_CFG_SetPskServerCallback(s_config, ExampleServerCb); + + client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ret = FRAME_CreateConnection(client, server, false, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(server->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_EQ(client->ssl->negotiatedInfo.negotiatedGroup, group); + ASSERT_EQ(client->ssl->negotiatedInfo.tls13BasicKeyExMode , TLS13_KE_MODE_PSK_WITH_DHE); + + uint8_t data[] = "Hello World"; + ASSERT_TRUE(HITLS_Write(client->ssl, data, strlen("Hello World")) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[MAX_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_TRUE(HITLS_Read(server->ssl, readBuf, MAX_BUF_SIZE, &readLen) == HITLS_SUCCESS); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); +exit: + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003 +* @spec - +* @title Verifying the Function of Using the FFDHE Curve for Certificate Rejection Authentication in psk_only Mode +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Set the PSK only on the client. +* 3. Set the PSK mode of the client and server to psk_with_only. +* 4. Set the client and server to ffdhe2048. +* 5. Establish a connection and read and write data. +* 6. Switch the group to ffdhe3072, ffdhe4096, ffdhe6144, and ffdhe8192. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The setting is successful. +* 5. The connection is successfully set up, and data is successfully read and written. +* 6. The connection is successfully set up, and data is successfully read and written. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003(int group) +{ + FRAME_Init(); + int32_t ret; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *c_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(c_config != NULL); + HITLS_Config *s_config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(s_config != NULL); + + uint16_t cipherSuite = HITLS_AES_128_GCM_SHA256; + HITLS_CFG_SetCipherSuites(c_config, &cipherSuite, 1); + HITLS_CFG_SetCipherSuites(s_config, &cipherSuite, 1); + HITLS_CFG_SetKeyExchMode(c_config, TLS13_KE_MODE_PSK_ONLY); + HITLS_CFG_SetKeyExchMode(s_config, TLS13_KE_MODE_PSK_ONLY); + uint16_t groups = group; + HITLS_CFG_SetGroups(c_config, &groups, 1); + HITLS_CFG_SetGroups(s_config, &groups, 1); + ExampleSetPsk("12121212121212"); + HITLS_CFG_SetPskClientCallback(c_config, ExampleClientCb); + + client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ret = FRAME_CreateConnection(client, server, false, HS_STATE_BUTT); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(server->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_EQ(client->ssl->negotiatedInfo.negotiatedGroup, group); + ASSERT_EQ(client->ssl->negotiatedInfo.tls13BasicKeyExMode , TLS13_CERT_AUTH_WITH_DHE); + + uint8_t data[] = "Hello World"; + ASSERT_TRUE(HITLS_Write(client->ssl, data, strlen("Hello World")) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[MAX_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_TRUE(HITLS_Read(server->ssl, readBuf, MAX_BUF_SIZE, &readLen) == HITLS_SUCCESS); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); +exit: + HITLS_CFG_FreeConfig(c_config); + HITLS_CFG_FreeConfig(s_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC004 +* @spec - +* @title The key length in the keyshare file is less than the length required by the RFC. +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Configure the client and server to support ffdhe2048. +* 3. Change the value of Key Exchange Length in the keyshare field in the client hello packet to 120. +* 4. Establish a connection and observe the server behavior. +* 5. Switch the group to ffdhe3072, ffdhe4096, ffdhe6144, and ffdhe8192, and repeat the preceding operations. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The modification is successful. +* 4. The server sends an alert message to disconnect the connection. +* 5. The server sends an alert message to disconnect the connection. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC004(int ClientType, int ServerType, int group) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + char *servergroup; + char *clientgroup; + + localProcess = HLT_InitLocalProcess(ClientType); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(ServerType, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the TLS1.3 configuration file. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the client and server to support ffdhe2048. + GetStrGroup(ClientType, group, &clientgroup); + GetStrGroup(ServerType, group, &servergroup); + + HLT_SetGroups(serverConfig, servergroup); + HLT_SetGroups(clientConfig, clientgroup); + + // Change the value of Key Exchange Length in the keyshare field in the client hello packet to 120. + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_FFDHE_KeyLen_LessThenStandard + }; + RegisterWrapper(wrapper); + + // Establish a connection and observe the server behavior. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC005 +* @spec - +* @title The key length in the keyshare file is greater than the length required by the RFC. +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Configure the client and server to support FFDHE2048. +* 3. Change the value of Key Exchange Length in the keyshare message sent by the client to 8800. +* 4. Establish a connection and observe the server behavior. +* 5. Switch groups ffdhe3072, ffdhe4096, ffdhe6144, and ffdhe8192. Repeat the preceding operations. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The modification is successful. +* 5. The server sends an alert message to disconnect the connection. +* 6. The server sends an alert message to disconnect the connection. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC005(int ClientType, int ServerType, int group) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + char *servergroup; + char *clientgroup; + + localProcess = HLT_InitLocalProcess(ClientType); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(ServerType, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the TLS1.3 configuration file. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the client and server to support FFDHE2048. + GetStrGroup(ClientType, group, &clientgroup); + GetStrGroup(ServerType, group, &servergroup); + + HLT_SetGroups(serverConfig, servergroup); + HLT_SetGroups(clientConfig, clientgroup); + + // Change the value of Key Exchange Length in the keyshare message sent by the client to 8800. + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_FFDHE_KeyLen_MoreThenStandard + }; + RegisterWrapper(wrapper); + + // Establish a connection and observe the server behavior. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC006 +* @spec - +* @title The server fails to parse the key in the keyshare file. +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Configure the client and server to support FFDHE2048. +* 3. Change the values of all bits of the key in the keyshare of the client hello packet to 0xff. +* 4. Establish a connection and observe the server behavior. +* 5. Switch groups ffdhe3072, ffdhe4096, ffdhe6144, and ffdhe8192. Repeat the preceding operations. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The modification is successful. +* 4. The server sends an alert message to disconnect the connection. +* 5. The server sends an alert message to disconnect the connection. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC006(int ClientType, int ServerType, int group) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + char *servergroup; + char *clientgroup; + + localProcess = HLT_InitLocalProcess(ClientType); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(ServerType, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the TLS1.3 configuration file. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the client and server to support FFDHE2048. + GetStrGroup(ClientType, group, &clientgroup); + GetStrGroup(ServerType, group, &servergroup); + + HLT_SetGroups(serverConfig, servergroup); + HLT_SetGroups(clientConfig, clientgroup); + + // Change the values of all bits of the key in the keyshare of the client hello packet to 0xff. + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_FFDHE_Key_ERROR + }; + RegisterWrapper(wrapper); + + // Establish a connection and observe the server behavior. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), HITLS_CRYPT_ERR_CALC_SHARED_KEY); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC007 +* @spec - +* @title The server successfully parses the incorrect key in keyshare. +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Configure the client and server to support the elliptic curve ffdhe2048. +* 3. Change the value of the first 10 bits of the key in the keyshare of the client hello packet to 8. +* 4. Establish a connection and observe the client. +* 5. Switch the elliptic curve and repeat the preceding operations. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The modification is successful. +* 4. The client is disconnected due to decryption failure. +* 5. Client decryption fails. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC007(int ClientType, int ServerType, int group) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + char *servergroup; + char *clientgroup; + + localProcess = HLT_InitLocalProcess(ClientType); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(ServerType, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the TLS1.3 configuration file. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the client and server to support the elliptic curve ffdhe2048. + GetStrGroup(ClientType, group, &clientgroup); + GetStrGroup(ServerType, group, &servergroup); + + HLT_SetGroups(serverConfig, servergroup); + HLT_SetGroups(clientConfig, clientgroup); + + // Change the value of the first 10 bits of the key in the keyshare of the client hello packet to 8. + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_FFDHE_Key_Client_DecodeError + }; + RegisterWrapper(wrapper); + + // Establish a connection and observe the client. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC008 +* @spec - +* @title The key value in keyshare does not match the Key Exchange Length value. Parsing failed. +* @precon nan +* @brief +* 1. Apply for and initialize the TLS1.3 configuration file. +* 2. Configure the client and server to support FFDHE2048. +* 3. Change the length of the key in the keyshare of the client hello packet to 1024 bits. +* 4. Establish a connection and observe the server behavior. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The modification is successful. +* 4. The server sends an alert message to disconnect the connection. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC008(int ClientType, int ServerType, int group) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + char *servergroup; + char *clientgroup; + + localProcess = HLT_InitLocalProcess(ClientType); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(ServerType, TCP, PORT, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the TLS1.3 configuration file. + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the client and server to support FFDHE2048. + GetStrGroup(ClientType, group, &clientgroup); + GetStrGroup(ServerType, group, &servergroup); + + HLT_SetGroups(serverConfig, servergroup); + HLT_SetGroups(clientConfig, clientgroup); + + // Change the length of the key in the keyshare of the client hello packet to 1024 bits. + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_FFDHE_KeyLen_Error + }; + RegisterWrapper(wrapper); + + // Establish a connection and observe the server behavior. + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), HITLS_PARSE_INVALID_MSG_LEN); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_ffdhe.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_ffdhe.data new file mode 100644 index 00000000..704fc320 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_ffdhe.data @@ -0,0 +1,62 @@ +UT_TLS13_RFC8446_FFDHE_TC001 +UT_TLS13_RFC8446_FFDHE_TC001: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001:HITLS_FF_DHE_3072 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001:HITLS_FF_DHE_4096 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001:HITLS_FF_DHE_6144 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC001:HITLS_FF_DHE_8192 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002:HITLS_FF_DHE_3072 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002:HITLS_FF_DHE_4096 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002:HITLS_FF_DHE_6144 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC002:HITLS_FF_DHE_8192 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003:HITLS_FF_DHE_3072 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003:HITLS_FF_DHE_4096 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003:HITLS_FF_DHE_6144 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC003:HITLS_FF_DHE_8192 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC004 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC004:HITLS:HITLS:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC005 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC005:HITLS:HITLS:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC006 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC006:HITLS:HITLS:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC007 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC007:HITLS:HITLS:HITLS_FF_DHE_2048 + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC008 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_DHE_GROUP_FUNC_TC008:HITLS:HITLS:HITLS_FF_DHE_2048 \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_pha.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_pha.c new file mode 100644 index 00000000..0fc1e634 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_pha.c @@ -0,0 +1,1833 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_tls13_consistency_rfc8446 */ + +#include +#include "stub_replace.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_uio.h" +#include "tls.h" +#include "hs_ctx.h" +#include "pack.h" +#include "send_process.h" +#include "frame_link.h" +#include "frame_tls.h" +#include "frame_io.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "rec_wrapper.h" +#include "cert.h" +#include "securec.h" +#include "conn_init.h" +#include "hitls_crypt_init.h" +#include "hitls_psk.h" +#include "common_func.h" +#include "alert.h" +#include "process.h" +#include "bsl_sal.h" +/* END_HEADER */ +#define MAX_BUF 16384 + +int32_t STUB_RecConnDecrypt( + TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg, uint8_t *data, uint32_t *dataLen) +{ + (void)ctx; + (void)state; + memcpy_s(data, cryptMsg->textLen, cryptMsg->text, cryptMsg->textLen); + (void)data; + *dataLen = cryptMsg->textLen; + return HITLS_SUCCESS; +} + +int32_t STUB_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num) +{ + (void)ctx; + (void)recordType; + (void)data; + (void)num; + return HITLS_SUCCESS; +} + +extern int32_t __real_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num); + +static void Test_FinishToAPP(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, FINISHED); + + STUB_Replace(user, __real_REC_Write, STUB_REC_Write); + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_ServerHello_Add_PhaExtensions( + HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, SERVER_HELLO); + + uint8_t posthandshake[] = {0x00, 0x31, 0x00, 0x00}; + frameMsg.body.hsMsg.length.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.length.data += sizeof(posthandshake); + frameMsg.body.hsMsg.body.serverHello.extensionLen.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.serverHello.extensionLen.data = + frameMsg.body.hsMsg.body.serverHello.extensionLen.data + sizeof(posthandshake); + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + ASSERT_EQ(memcpy_s(&data[*len], bufSize - *len, &posthandshake, sizeof(posthandshake)), EOK); + *len += sizeof(posthandshake); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_CertificateRequest_Ctx_Zero(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE_REQUEST); + + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtx.state = MISSING_FIELD; + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtxSize.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificateReq.certificateReqCtxSize.data = 0; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Certificate_Ctx_Zero(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE); + + frameMsg.body.hsMsg.body.certificate.certificateReqCtx.state = MISSING_FIELD; + frameMsg.body.hsMsg.body.certificate.certificateReqCtxSize.state = ASSIGNED_FIELD; + frameMsg.body.hsMsg.body.certificate.certificateReqCtxSize.data = 0; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Certificate_Ctx_NotSame(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CERTIFICATE); + + frameMsg.body.hsMsg.body.certificate.certificateReqCtx.state = ASSIGNED_FIELD; + *(frameMsg.body.hsMsg.body.certificate.certificateReqCtx.data) = 123; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +static void Test_Finish_Error(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, FINISHED); + + frameMsg.body.hsMsg.body.finished.verifyData.state = ASSIGNED_FIELD; + *(frameMsg.body.hsMsg.body.finished.verifyData.data) = 123; + + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} + +/** + * @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_PHA_FUNC_TC001 + * @brief tls1.3 post-handshake auth + * base test case + */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_PHA_FUNC_TC001() +{ + HLT_Process *localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + bool isBlock = true; + HLT_Process *remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, isBlock); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *config_s = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(config_s != NULL); + HLT_SetPostHandshakeAuth(config_s, true); + HLT_SetClientVerifySupport(config_s, true); + + HLT_Ctx_Config *config_c = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(config_c != NULL); + HLT_SetPostHandshakeAuth(config_c, true); + HLT_SetClientVerifySupport(config_c, true); + + HLT_Tls_Res *serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, config_s, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Tls_Res *clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, config_c, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); + + uint8_t src[] = "Hello world!"; + uint32_t readbytes = 0; + uint8_t dest[READ_BUF_SIZE] = {0}; + ASSERT_EQ(HLT_ProcessTlsWrite(localProcess, clientRes, src, sizeof(src)), 0); + ASSERT_EQ(HLT_ProcessTlsRead(remoteProcess, serverRes, dest, READ_BUF_SIZE, &readbytes), 0); + ASSERT_TRUE(readbytes == sizeof(src)); + ASSERT_TRUE(memcmp(src, dest, readbytes) == 0); + memset_s(dest, READ_BUF_SIZE, 0, READ_BUF_SIZE); +exit: + HLT_FreeAllProcess(); + return; +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC002 +* @spec - +* @title The client does not support post-handshake authentication, but receives the server hello message that carries +* the extension. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client not to support post-handshake extension +* 3. Set up a connection and modify the server hello message to carry the post-handshake extension. +* 4. Observe client behavior +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. Modification succeeded. +* 4. The client returns alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC002(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply and initialize config + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Set the client not to support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, false); + HLT_SetClientVerifySupport(clientConfig, true); + + // Set up a connection and modify the server hello message to carry the post-handshake extension. + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ServerHello_Add_PhaExtensions}; + RegisterWrapper(wrapper); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // The client returns alert + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); +exit: + HLT_FreeAllProcess(); + ClearWrapper(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC003 +* @spec - +* @title The client supports authentication after handshake, but receives the server hello message that carries the +* extension. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client support post-handshake extension +* 3. Set up a connection and modify the server hello message to carry the post-handshake extension. +* 4. Observe client behavior +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. Modification succeeded. +* 4. The client returns alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC003(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply and initialize config + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Set the client support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, true); + HLT_SetClientVerifySupport(clientConfig, true); + + // Set up a connection and modify the server hello message to carry the post-handshake extension. + RecWrapper wrapper = {TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, Test_ServerHello_Add_PhaExtensions}; + RegisterWrapper(wrapper); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + // The client returns alert + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes == NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); +exit: + HLT_FreeAllProcess(); + ClearWrapper(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC004 +* @spec - +* @title When the value of certificate_request_context in the certificate request message +* after handshake authentication is 0, the client reports an error. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client support post-handshake extension +* 3. After the connection establishment is completed, modify the certificate_request_context of the +* certificate request message sent by the server to 0. +* 4. Observe client behavior +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. Modification succeeded. +* 4. The client returns alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC004(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply and initialize config + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Set the client support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, true); + HLT_SetClientVerifySupport(clientConfig, true); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); + + ASSERT_EQ(HITLS_VerifyClientPostHandshake(serverRes->ssl), HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // modify the certificate_request_context of the certificate request message sent by the server to 0. + ClearWrapper(); + RecWrapper wrapper = { + TRY_SEND_CERTIFICATE_REQUEST, REC_TYPE_HANDSHAKE, false, NULL, Test_CertificateRequest_Ctx_Zero}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HLT_TlsWrite(serverRes->ssl, (uint8_t *)writeBuf, strlen(writeBuf)) == HITLS_SUCCESS); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + + // The client returns alert + ASSERT_TRUE(HLT_RpcTlsRead(remoteProcess, clientRes->sslId, readBuf, READ_BUF_SIZE, &readLen) == + HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC005 +* @spec - +* @title The server reports an error when the value of certificate_request_context of the +* client certificate is 0 during authentication after handshake. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client support post-handshake extension +* 3. After the connection is established, the server initiates a certificate request and changes the value of +* certificate_request_context in the certificate request message from the client to 0 +* 4. Observe the server behavior +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. Modification succeeded. +* 4. The server returns alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC005(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply and initialize config + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Set the client support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, true); + HLT_SetClientVerifySupport(clientConfig, true); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); + + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverRes->sslId) == HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // changes the value of certificate_request_context in the certificate request message from the client to 0 + ClearWrapper(); + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, NULL, Test_Certificate_Ctx_Zero}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientRes->ssl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_TlsWrite(clientRes->ssl, (uint8_t *)writeBuf, strlen(writeBuf)) == HITLS_SUCCESS); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + + // The server returns alert + ASSERT_EQ(HLT_RpcTlsRead(remoteProcess, serverRes->sslId, readBuf, READ_BUF_SIZE, &readLen), + HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC006 +* @spec - +* @title During post-handshake authentication, the certificate_request_context sent by the client is inconsistent with +* that sent by the server. As a result, the server reports an error. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client support post-handshake extension +* 3. After the connection is established, the server initiates a certificate request and changes the value of +* certificate_request_context in the certificate request message from the client +* 4. Observe the server behavior +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. Modification succeeded. +4. The server returns alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC006(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply and initialize config + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Set the client support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, true); + HLT_SetClientVerifySupport(clientConfig, true); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); + + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverRes->sslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // changes the value of certificate_request_context in the certificate request message from the client + ClearWrapper(); + RecWrapper wrapper = {TRY_SEND_CERTIFICATE, REC_TYPE_HANDSHAKE, false, NULL, Test_Certificate_Ctx_NotSame}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientRes->ssl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_TlsWrite(clientRes->ssl, (uint8_t *)writeBuf, strlen(writeBuf)) == HITLS_SUCCESS); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + + // The server returns alert + ASSERT_EQ(HLT_RpcTlsRead(remoteProcess, serverRes->sslId, readBuf, READ_BUF_SIZE, &readLen), + HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC007 +* @spec - +* @title After the PSK connection is established, the certificate is authenticated after handshake. The authentication is +* successful. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file +* 2. Setting the PSK on the Client and Server +* 3. Configure the client and server to support post-handshake extension +* 4. After the connection is established, the server sends a certificate request message for backhandshake authentication. +* @expect +* 1. Initialization succeeded. +* 2. Setting succeeded. +* 3. Setting succeeded. +* 4. Authentication succeeded. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC007(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the configuration file + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Configure the client and server to support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, true); + HLT_SetClientVerifySupport(clientConfig, true); + + // Setting the PSK on the Client and Server + memcpy_s(clientConfig->psk, PSK_MAX_LEN, "12121212121212", sizeof("12121212121212")); + memcpy_s(serverConfig->psk, PSK_MAX_LEN, "12121212121212", sizeof("12121212121212")); + HLT_SetCipherSuites(clientConfig, "HITLS_AES_128_GCM_SHA256"); + HLT_SetCipherSuites(serverConfig, "HITLS_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); + + // the server sends a certificate request message for backhandshake authentication. + ASSERT_EQ(HITLS_VerifyClientPostHandshake(serverRes->ssl), HITLS_SUCCESS); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + ASSERT_TRUE(HLT_TlsWrite(serverRes->ssl, (uint8_t *)writeBuf, strlen(writeBuf)) == HITLS_SUCCESS); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_EQ(HLT_RpcTlsRead(remoteProcess, clientRes->sslId, readBuf, READ_BUF_SIZE, &readLen), HITLS_SUCCESS); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, clientRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(serverRes->ssl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC008 +* @spec - +* @title The server fails to verify the finish during post-authentication. +* @precon nan +* @brief +* 1. Apply and initialize config +* 2. Set the client support post-handshake extension +* 3. After the connection is established, the server initiates a certificate request and Modify the finish message sent +* by the client. +* 4. Observe the server behavior +* @expect +* 1. Initialization succeeded. +* 2. Set succeeded. +* 3. Modification succeeded. +* 4. The server returns alert +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC008(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, 18889, false); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply and initialize config + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverConfig != NULL); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientConfig != NULL); + + // Set the client support post-handshake extension + HLT_SetPostHandshakeAuth(serverConfig, true); + HLT_SetClientVerifySupport(serverConfig, true); + HLT_SetPostHandshakeAuth(clientConfig, true); + HLT_SetClientVerifySupport(clientConfig, true); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, TLS1_3, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + clientRes = HLT_ProcessTlsConnect(localProcess, TLS1_3, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_GetTlsAcceptResult(serverRes), 0); + + // the server initiates a certificate request + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverRes->sslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // Modify the finish message sent by the client. + ClearWrapper(); + RecWrapper wrapper = {TRY_SEND_FINISH, REC_TYPE_HANDSHAKE, false, NULL, Test_Finish_Error}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverRes->sslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientRes->ssl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_TlsWrite(clientRes->ssl, (uint8_t *)writeBuf, strlen(writeBuf)) == HITLS_SUCCESS); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + + // The server returns alert + ASSERT_EQ(HLT_RpcTlsRead(remoteProcess, serverRes->sslId, readBuf, READ_BUF_SIZE, &readLen), + HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC009 +* @spec - +* @title Two certificates request messages are sent for backhandshake authentication, + and the required certificate_request_context is inconsistent. +* @precon nan +* @brief +1. Apply and initialize config +2. Set the client support post-handshake extension +3. After the connection is established, the server continuously sends certificate request messages for backhandshake +authentication +4. Check whether the certificate_request_context sent by the server is the same. +* @expect +1. Initialization succeeded. +2. Set succeeded. +3. Constructed successfully. +4. Inconsistent certificate_request_context +* @prior Level 1 +* @auto TRUE+ +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC009() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply and initialize config + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Set the client support post-handshake extension + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // the server continuously sends certificate request messages + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + HITLS_Ctx *ctx = clientSsl; + uint8_t ReqCtx1[1 * 1024] = {0}; + memcpy_s(ReqCtx1, ctx->certificateReqCtxSize, ctx->certificateReqCtx, ctx->certificateReqCtxSize); + + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + // the server continuously sends certificate request messages + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + // Inconsistent certificate_request_context + ASSERT_TRUE(memcmp(ReqCtx1, ctx->certificateReqCtx, ctx->certificateReqCtxSize) != 0); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC011 +* @spec - +* @title The server does not allow the client to send an empty certificate. During authentication after handshake, +* the server receives an empty certificate from the client. +* @precon nan +* @brief +* 1. Apply for and initialize the config file. Expected result 1 is obtained. +* 2. Configure the server not to allow the client to send an empty certificate. Expected result 2 is obtained. +* 3. Configure the client to send an empty certificate. Expected result 3 is obtained. +* 4. Configure the client and server to support post-handshake extension. Expected result 4 is obtained. +* 5. Perform authentication after the connection is established. Expected result 5 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The setting is successful. +* 5. The connection is set up successfully. After receiving the client certificate, the server sends an alert message. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC011() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply for and initialize the config file + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the server not to allow the client to send an empty certificate + // Configure the client and server to support post-handshake extension + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportNoClientCert = false; + serverCtxConfig->isSupportPostHandshakeAuth = true; + + // Configure the client to send an empty certificate + HLT_SetCertPath( + clientCtxConfig, "rsa_sha256/ca.der:rsa_sha256/inter.der", "NULL", "NULL", "NULL", "NULL", "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // Perform authentication after the connection is established + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ret = HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + + // the server sends an alert message. + ASSERT_EQ(ret, HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC012 +* @spec - +* @title The server allows the client to send an empty certificate. During authentication after handshake, +* the server receives an empty certificate from the client. +* @precon nan +* @brief +* 1. Apply for and initialize the config file. Expected result 1 is obtained. +* 2. Configure the server to allow the client to send an empty certificate. Expected result 2 is obtained. +* 3. Configure the client to send an empty certificate. Expected result 3 is obtained. +* 4. Configure the client and server to support post-handshake extension. Expected result 4 is obtained. +* 5. Perform authentication after the connection is established. Expected result 5 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The setting is successful. +* 5. The connection is successfully set up, and the server initiates authentication. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC012() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply for and initialize the config file + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the server to allow the client to send an empty certificate. + // Configure the client and server to support post-handshake extension + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportNoClientCert = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + + // Configure the client to send an empty certificate + HLT_SetCertPath( + clientCtxConfig, "rsa_sha256/ca.der:rsa_sha256/inter.der", "NULL", "NULL", "NULL", "NULL", "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // Perform authentication after the connection is established + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // The connection is successfully set up, and the server initiates authentication. + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC013 +* @spec - +* @title The server does not set the verification failure to continue the handshake. As a result, the server +* verification fails during the post-handshake authentication. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the client and server to support post-handshake extension. Expected result 2 is obtained. +* 3. Set the server certificate to the RSA certificate and the client certificate to the ECDSA certificate. Expected +* result 3 is obtained. +* 4. After the connection is established, authentication is performed. Expected result 4 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The connection is successfully established, but the server fails to authenticate the certificate. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC013() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply for and initialize the configuration file + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the client and server to support post-handshake extension + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + clientCtxConfig->isSupportVerifyNone = false; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportVerifyNone = false; + + // Set the server certificate to the RSA certificate and the client certificate to the ECDSA certificate. + HLT_SetCertPath(clientCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + "ecdsa/end256-sha256.key.der", + "NULL", + "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // After the connection is established, authentication is performed + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_EQ( + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen), HITLS_CERT_ERR_VERIFY_CERT_CHAIN); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC014 +* @spec - +* @title The server continues the handshake if the verification fails. After the handshake, +* the server continues the handshake if the verification fails. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the server not to verify the peer certificate. Expected result 2 is obtained. +* 3. Configure the client and server to support post-handshake extension. Expected result 3 is obtained. +* 4. Set the client server certificate to RSA certificate, and set the client terminal certificate to ECDSA certificate. +* Expected result 4 is obtained. +* 5. After the connection is established, authentication is performed. Expected result 5 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The setting is successful. +* 5. The connection is successfully established and the authentication is successful. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC014() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + // Apply for and initialize the configuration file + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the server not to verify the peer certificate. + // Configure the client and server to support post-handshake extension + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportVerifyNone = true; + + // Set the client server certificate to RSA certificate, and set the client terminal certificate to ECDSA + // certificate. + HLT_SetCertPath(clientCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "ecdsa/inter-nist521.der", + "ecdsa/end256-sha256.der", + "ecdsa/end256-sha256.key.der", + "NULL", + "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // authentication is performed + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_EQ(memcmp(writeBuf, readBuf, readLen), 0); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC015 +* @spec - +* @title During the authentication after the handshake on the client, the server is +* disconnected because app messages are mixed in the sent messages. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the client and server to support post-handshake extension. Expected result 2 is obtained. +* 3. Establish a connection. The server initiates a handshake for authentication. Expected result 3 is displayed. +* 4. Modify the client to send messages. Enable the client to send an app message before sending the finish message. +* Expected result 4 is obtained. +* 5. Observe the server behavior. Expected result 5 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The connection is successfully set up and the server initiates authentication. +* 4. The client sends the message successfully. +* 5. The server sends an alert message to disconnect the connection. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC015() +{ + STUB_Init(); + FuncStubInfo tmpStubInfo; + + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply for and initialize the configuration file + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the client and server to support post-handshake extension + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + + HLT_SetCertPath(clientCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // he server initiates a handshake for authentication + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // Enable the client to send an app message before sending the finish message. + RecWrapper wrapper = {TRY_SEND_FINISH, REC_TYPE_HANDSHAKE, false, &tmpStubInfo, Test_FinishToAPP}; + RegisterWrapper(wrapper); + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + + STUB_Reset(&tmpStubInfo); + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_EQ(HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen), + HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + ClearWrapper(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC016 +* @spec - +* @title During authentication after handshake, the server receives multiple app messages after +* sending the certificate request, and the processing is normal. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the client and server to support post-handshake extension. Expected result 2 is obtained. +* 3. Establish a connection. The server initiates a handshake for authentication. Expected result 3 is obtained. +* 4. Send an app message to the server. After the server processes the message, check the server status. +* Expected result 4 is obtained. +* 5. Send an app message to the server. After the server processes the message, check the server status. +* Expected result 5 is obtained. +* 6. Continue the authentication. Expected result 6 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The connection is set up successfully, and the server sends a certificate request message. +* 4. The server is in try_recv_certifiacates state. +* 5. The server is in try_recv_certifiacates state. +* 6. The authentication is successful. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC016() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply for and initialize the configuration file + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the client and server to support post-handshake extension. + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + + HLT_SetCertPath(clientCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // The server initiates a handshake for authentication + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + + // Send an app message to the server + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + // Send an app message to the server + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + // The authentication is successful. + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC017 +* @spec - +* @title During post-handshake authentication, the server sends the app message after sending the certificate request +* message. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1 is obtained. +* 2. Configure the client and server to support post-handshake extension. Expected result 2 is obtained. +* 3. Establish a connection. The server initiates a handshake for authentication. Expected result 3 is displayed. +* 4. The server sends an app message. Expected result 4 is obtained. +* 5. Send an app message from the server. Expected result 5 is obtained. +* 6. Continue the authentication. Expected result 6 is obtained. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The connection is set up successfully, and the server sends a certificate request message. +* 4. The message is sent successfully. +* 5. The message is sent successfully. +* 6. The authentication is successful. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC017() +{ + int version = TLS1_3; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + // Apply for and initialize the configuration file + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(clientCtxConfig != NULL); + ASSERT_TRUE(serverCtxConfig != NULL); + + // Configure the client and server to support post-handshake extension. + clientCtxConfig->isSupportClientVerify = true; + clientCtxConfig->isSupportPostHandshakeAuth = true; + serverCtxConfig->isSupportClientVerify = true; + serverCtxConfig->isSupportPostHandshakeAuth = true; + + HLT_SetCertPath(clientCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + HLT_SetCertPath(serverCtxConfig, + "rsa_sha256/ca.der:rsa_sha256/inter.der", + "rsa_sha256/inter.der", + "rsa_sha256/server.der", + "rsa_sha256/server.key.der", + "NULL", + "NULL"); + + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + HLT_TlsSetSsl(clientSsl, clientSslConfig); + + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + + // The server initiates a handshake for authentication + ASSERT_TRUE(HLT_RpcTlsVerifyClientPostHandshake(remoteProcess, serverSslId) == HITLS_SUCCESS); + ; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + const char *writeBuf = "Hello world"; + + // The server sends an app message + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + // The server sends an app message + ASSERT_TRUE(HLT_RpcTlsWrite(remoteProcess, serverSslId, (uint8_t *)writeBuf, strlen(writeBuf)) == 0); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + ASSERT_TRUE(HLT_TlsRead(clientSsl, readBuf, READ_BUF_SIZE, &readLen) == 0); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + // Continue the authentication. + HLT_TlsWrite(clientSsl, (uint8_t *)writeBuf, strlen(writeBuf)); + ASSERT_TRUE(memset_s(readBuf, READ_BUF_SIZE, 0, READ_BUF_SIZE) == EOK); + HLT_RpcTlsRead(remoteProcess, serverSslId, readBuf, READ_BUF_SIZE, &readLen); + ASSERT_TRUE(readLen == strlen(writeBuf)); + ASSERT_TRUE(memcmp(writeBuf, readBuf, readLen) == 0); + + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_pha.data b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_pha.data new file mode 100644 index 00000000..dc16505d --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_hlt_tls13_consistency_rfc8446_pha.data @@ -0,0 +1,50 @@ +SDV_TLS_TLS13_RFC8446_CONSISTENCY_PHA_FUNC_TC001 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_PHA_FUNC_TC001: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC002 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC002: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC003 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC003: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC004 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC004: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC005 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC005: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC006 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC006: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC007 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC007: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC008 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC008: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC009 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC009: + + + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC011 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC011: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC012 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC012: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC013 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC013: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC014 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC014: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC015 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC015: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC016 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC016: + +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC017 +SDV_TLS_TLS13_RFC8446_CONSISTENCY_POSTHANDSHAKE_FUNC_TC017: + diff --git a/testcode/sdv/testcase/tls/consistency/tls13/test_suite_tls13_consistency_rfc8446.base.c b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_tls13_consistency_rfc8446.base.c new file mode 100644 index 00000000..9023ef38 --- /dev/null +++ b/testcode/sdv/testcase/tls/consistency/tls13/test_suite_tls13_consistency_rfc8446.base.c @@ -0,0 +1,248 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_state_recv.h" +#include "conn_init.h" +#include "app.h" +#include "record.h" +#include "rec_conn.h" +#include "session.h" +#include "recv_process.h" +#include "stub_replace.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "cert.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "hlt.h" +#include "sctp_channel.h" +#include "logger.h" + +#define SIGNATURE_ALGORITHMS 0x04, 0x03 /* Fields added to the SERVER_HELLOW message */ +#define READ_BUF_SIZE (18 * 1024) /* Maximum length of the read message buffer */ +#define TEMP_DATA_LEN 1024 /* Length of a single message */ +#define ALERT_BODY_LEN 2u /* Alert data length */ + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isServerExtendMasterSecret; + bool isSupportRenegotiation; /* Renegotiation support flag */ + bool needStopBeforeRecvCCS; /* CCS test, so that the TRY_RECV_FINISH stops before the CCS message is received */ +} HandshakeTestInfo; + +int32_t StatusPark(HandshakeTestInfo *testInfo) +{ + /** Construct connection */ + testInfo->client = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + testInfo->server = FRAME_CreateLink(testInfo->config, BSL_UIO_TCP); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + /* Perform the CCS test so that the TRY_RECV_FINISH is stopped before the CCS message is received. + * The default value is False, which does not affect the original test. + */ + testInfo->client->needStopBeforeRecvCCS = testInfo->isClient ? testInfo->needStopBeforeRecvCCS : false; + testInfo->server->needStopBeforeRecvCCS = testInfo->isClient ? false : testInfo->needStopBeforeRecvCCS; + + /** Establish a connection and stop in a certain state. */ + if (FRAME_CreateConnection(testInfo->client, testInfo->server, testInfo->isClient, testInfo->state) != + HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultCfgStatusPark(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + /** Construct configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + testInfo->config->isSupportRenegotiation = testInfo->isSupportRenegotiation; + + return StatusPark(testInfo); +} + +int32_t DefaultCfgStatusParkWithSuite(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + /** Construct configuration. */ + testInfo->config = HITLS_CFG_NewTLS12Config(); + if (testInfo->config == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + HITLS_CFG_SetCloseCheckKeyUsage(testInfo->config, false); + uint16_t cipherSuits[] = {HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(testInfo->config, cipherSuits, sizeof(cipherSuits) / sizeof(uint16_t)); + + testInfo->config->isSupportExtendMasterSecret = testInfo->isSupportExtendMasterSecret; + testInfo->config->isSupportClientVerify = testInfo->isSupportClientVerify; + testInfo->config->isSupportNoClientCert = testInfo->isSupportNoClientCert; + + return StatusPark(testInfo); +} + +#define TEST_CLIENT_SEND_FAIL 1 +uint32_t g_uiPort = 8889; + +void TestSetCertPath(HLT_Ctx_Config *ctxConfig, char *SignatureType) +{ + if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA1", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA1")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA256")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA256_EE_PATH3, RSA_SHA256_PRIV_PATH3, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA384")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA384_EE_PATH, RSA_SHA384_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA512")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA512_EE_PATH, RSA_SHA512_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + strlen("CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA256_EE_PATH, + ECDSA_SHA256_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384", + strlen("CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA384_EE_PATH, + ECDSA_SHA384_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512", + strlen("CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA512_EE_PATH, + ECDSA_SHA512_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_ECDSA_SHA1", strlen("CERT_SIG_SCHEME_ECDSA_SHA1")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA1_CA_PATH, + ECDSA_SHA1_CHAIN_PATH, + ECDSA_SHA1_EE_PATH, + ECDSA_SHA1_PRIV_PATH, + "NULL", + "NULL"); + } +} + +void SetFrameType(FRAME_Type *frametype, uint16_t versionType, REC_Type recordType, HS_MsgType handshakeType, + HITLS_KeyExchAlgo keyExType) +{ + frametype->versionType = versionType; + frametype->recordType = recordType; + frametype->handshakeType = handshakeType; + frametype->keyExType = keyExType; +} + +FieldState *GetDataAddress(FRAME_Msg *data, void *member) +{ + return (FieldState *)((size_t)data + (size_t)member); +} + +void Test_MisClientHelloExtension(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user) +{ + (void)ctx; + (void)bufSize; + (void)user; + FRAME_Type frameType = {0}; + frameType.versionType = HITLS_VERSION_TLS13; + FRAME_Msg frameMsg = {0}; + frameMsg.recType.data = REC_TYPE_HANDSHAKE; + frameMsg.length.data = *len; + frameMsg.recVersion.data = HITLS_VERSION_TLS13; + uint32_t parseLen = 0; + FRAME_ParseMsgBody(&frameType, data, *len, &frameMsg, &parseLen); + ASSERT_EQ(parseLen, *len); + ASSERT_EQ(frameMsg.body.hsMsg.type.data, CLIENT_HELLO); + FieldState *extensionState = GetDataAddress(&frameMsg, user); + *extensionState = MISSING_FIELD; + memset_s(data, bufSize, 0, bufSize); + FRAME_PackRecordBody(&frameType, &frameMsg, data, bufSize, len); + ASSERT_NE(parseLen, *len); +exit: + FRAME_CleanMsg(&frameType, &frameMsg); + return; +} \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_alpn_interface.c b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_alpn_interface.c new file mode 100644 index 00000000..a6d856b8 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_alpn_interface.c @@ -0,0 +1,137 @@ +/* + * 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_BASE ../consistency/tls12/test_suite_tls12_consistency_rfc5246_malformed_msg */ +/* BEGIN_HEADER */ + +#include "securec.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "stub_replace.h" +#include "hitls_error.h" +#include "tls.h" +#include "bsl_uio.h" +#include "rec.h" +#include "crypt.h" +#include "rec_conn.h" +#include "record.h" +#include "bsl_uio.h" +#include "hitls.h" +#include "frame_tls.h" +/* END_HEADER */ + +/* UserData structure transferred from the server to the alpnCb callback */ + +static uint8_t S_parsedList[100]; +static uint32_t S_parsedListLen; +static TlsAlpnExtCtx alpnServerCtx = {0}; + +static uint8_t C_parsedList[100]; +static uint32_t C_parsedListLen; + +static int32_t ConfigAlpn(HITLS_Config *tlsConfig, char *AlpnList, bool isCient) +{ + + int32_t ret; + char defaultAlpnList[] = "http/1.1,spdy/1,spdy/2,spdy/3"; + char *pAlpnList = NULL; + uint32_t AlpnListLen = 0; + if (AlpnList != NULL){ + pAlpnList = AlpnList; + AlpnListLen = strlen(pAlpnList); + } else { + pAlpnList = defaultAlpnList; + AlpnListLen = strlen(pAlpnList); + } + + /* client set alpn */ + if (isCient) { + ret = ExampleAlpnParseProtocolList(C_parsedList, &C_parsedListLen, (uint8_t *)pAlpnList, AlpnListLen); + ASSERT_EQ(ret, HITLS_SUCCESS); + ret = HITLS_CFG_SetAlpnProtos(tlsConfig, C_parsedList, C_parsedListLen); + ASSERT_EQ(ret, HITLS_SUCCESS); + /* server set alpn and alpnSelectCb */ + } else { + ret = ExampleAlpnParseProtocolList(S_parsedList, &S_parsedListLen, (uint8_t *)pAlpnList, AlpnListLen); + ASSERT_EQ(ret, HITLS_SUCCESS); + alpnServerCtx = (TlsAlpnExtCtx){ S_parsedList, S_parsedListLen }; + ret = HITLS_CFG_SetAlpnProtosSelectCb(tlsConfig, ExampleAlpnCbForLlt, &alpnServerCtx); + ASSERT_EQ(ret, HITLS_SUCCESS); + } +exit: + return ret; +} + +/** + * @test UT_TLS_ALPN_PARSE_PROTO_FUNC_TC001 + * @title ALPN function test + * @precon nan + * @brief server set alpn and alpn callback,client set alpn. The server supports the protocol configured on + the client .Expect result 1 + * @expect 1. server returns the protocol supported by the client +*/ +/* BEGIN_CASE */ +void UT_TLS_ALPN_PARSE_PROTO_FUNC_TC001(int version) +{ + FRAME_Init(); + + HITLS_Config *s_config = NULL; + HITLS_Config *c_config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + if (version == HITLS_VERSION_TLS12) { + c_config = HITLS_CFG_NewTLS12Config(); + s_config = HITLS_CFG_NewTLS12Config(); + } else if (version == HITLS_VERSION_TLS13) { + c_config = HITLS_CFG_NewTLS13Config(); + s_config = HITLS_CFG_NewTLS13Config(); + } + ASSERT_TRUE(c_config != NULL); + ASSERT_TRUE(s_config != NULL); + + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetGroups(c_config, groups, sizeof(groups) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(c_config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + HITLS_CFG_SetGroups(s_config, groups, sizeof(groups) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(s_config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + ConfigAlpn(s_config, NULL, false); + ConfigAlpn(c_config, NULL, true); + + client = FRAME_CreateLink(c_config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(s_config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + int32_t ret; + ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_EQ(ret, HITLS_SUCCESS); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(memcmp(clientTlsCtx->negotiatedInfo.alpnSelected, "http/1.1", 8) == 0); + ASSERT_TRUE(clientTlsCtx->negotiatedInfo.alpnSelectedSize == 8); + ASSERT_TRUE(memcmp(serverTlsCtx->negotiatedInfo.alpnSelected, "http/1.1", 8) == 0); + ASSERT_TRUE(serverTlsCtx->negotiatedInfo.alpnSelectedSize == 8); + +exit: + HITLS_CFG_FreeConfig(s_config); + HITLS_CFG_FreeConfig(c_config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_alpn_interface.data b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_alpn_interface.data new file mode 100644 index 00000000..23655c03 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_alpn_interface.data @@ -0,0 +1,5 @@ +UT_TLS_ALPN_PARSE_PROTO_FUNC_TC001 +UT_TLS_ALPN_PARSE_PROTO_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_ALPN_PARSE_PROTO_FUNC_TC001 +UT_TLS_ALPN_PARSE_PROTO_FUNC_TC001:HITLS_VERSION_TLS13 diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_function.c b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_function.c new file mode 100644 index 00000000..52980208 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_function.c @@ -0,0 +1,359 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "tls_config.h" +#include "tls.h" +#include "hitls_type.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "frame_tls.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_state_recv.h" +#include "transcript_hash.h" +#include "conn_init.h" +#include "recv_process.h" +#include "stub_replace.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "common_func.h" +#include "hitls_crypt_init.h" + +#define TEST_SERVERNAME_LENGTH 20 +#define READ_BUF_SIZE 18432 + +/* END_HEADER */ +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; + HITLS_TicketKeyCb serverKeyCb; +} SniTestInfo; + + +typedef struct { + char servername[TEST_SERVERNAME_LENGTH + 1]; + int32_t alert; +} SNI_Arg; + + +static SNI_Arg *sniArg = NULL; +static char *g_serverName = "www.example.com"; +static uint8_t *g_sessionId; +static uint32_t g_sessionIdSize; + +int32_t ServernameCbErrOK(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)alert; + (void)arg; + + return HITLS_ACCEPT_SNI_ERR_OK; +} + +void STUB_SendAlert(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + (void)ctx; + (void)level; + (void)description; + return; +} + +typedef struct TEST_SNI_DEAL_CB { + uint32_t sniState; + HITLS_SniDealCb sniDealCb; +} TEST_SNI_DEAL_CB; + +typedef struct { + HITLS_Config *clientConfig; + HITLS_Config *serverConfig; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + HITLS_SniDealCb sniDealCb; + HITLS_Session *clientSession; + uint16_t version; + BSL_UIO_TransportType type; +} HandshakeTestInfo; + +int32_t CreateConfig(HITLS_Config **cfg, uint16_t version) +{ + + switch (version) { + case HITLS_VERSION_DTLS12: + *cfg = HITLS_CFG_NewDTLS12Config(); + break; + case HITLS_VERSION_TLS13: + *cfg = HITLS_CFG_NewTLS13Config(); + break; + case HITLS_VERSION_TLS12: + *cfg = HITLS_CFG_NewTLS12Config(); + break; + default: + break; + } + + if (*cfg == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + return HITLS_SUCCESS; +} + +void FreeSNIArg(SNI_Arg *sniArg) +{ + if (sniArg != NULL) { + BSL_SAL_FREE(sniArg); + } +} + +void SetCommonConfig(HITLS_Config **config) +{ + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1}; + HITLS_CFG_SetGroups(*config, groups, sizeof(groups) / sizeof(uint16_t)); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(*config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + const uint16_t cipherSuites[] = {HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(*config, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)); + HITLS_CFG_SetClientVerifySupport(*config, true); + HITLS_CFG_SetExtenedMasterSecretSupport(*config, true); + HITLS_CFG_SetNoClientCertSupport(*config, true); + HITLS_CFG_SetRenegotiationSupport(*config, true); + HITLS_CFG_SetPskServerCallback(*config, (HITLS_PskServerCb)ExampleServerCb); + HITLS_CFG_SetPskClientCallback(*config, (HITLS_PskClientCb)ExampleClientCb); + HITLS_CFG_SetSessionTicketSupport(*config, false); + HITLS_CFG_SetCloseCheckKeyUsage(*config, false); +} + +static int32_t CreateLink(HandshakeTestInfo *testInfo) +{ + testInfo->client = FRAME_CreateLink(testInfo->clientConfig, testInfo->type); + if (testInfo->client == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + if (testInfo->clientSession != NULL) { + int32_t ret = HITLS_SetSession(testInfo->client->ssl, testInfo->clientSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + testInfo->server = FRAME_CreateLink(testInfo->serverConfig, testInfo->type); + if (testInfo->server == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + return HITLS_SUCCESS; +} + +static int32_t DefaultCfgAndLink(HandshakeTestInfo *testInfo) +{ + FRAME_Init(); + + CreateConfig(&(testInfo->clientConfig), testInfo->version); + if (testInfo->clientConfig == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + SetCommonConfig(&(testInfo->clientConfig)); + HITLS_CFG_SetServerName(testInfo->clientConfig, (uint8_t *)g_serverName, (uint32_t)strlen(g_serverName)); + + + CreateConfig(&(testInfo->serverConfig), testInfo->version); + if (testInfo->serverConfig == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + SetCommonConfig(&(testInfo->serverConfig)); + HITLS_CFG_SetServerNameCb(testInfo->serverConfig, testInfo->sniDealCb); + + sniArg = (SNI_Arg *)BSL_SAL_Calloc(1, sizeof(SNI_Arg)); + snprintf_s(sniArg->servername, sizeof(sniArg->servername), strlen(g_serverName), "%s", g_serverName); + if (HITLS_CFG_SetServerNameArg(testInfo->serverConfig, sniArg) != HITLS_SUCCESS) { + return HITLS_INTERNAL_EXCEPTION; + } + + return CreateLink(testInfo); +} + +int32_t GetSessionId(HandshakeTestInfo *testInfo) +{ + FRAME_Type frameType = {0}; + FRAME_Msg recvframeMsg = {0}; + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo->client->io); + uint8_t *recMsg = ioUserData->recMsg.msg; + uint32_t recMsgLen = ioUserData->recMsg.len; + + frameType.handshakeType = SERVER_HELLO; + frameType.recordType = REC_TYPE_HANDSHAKE; + frameType.versionType = testInfo->version; + uint32_t parseLen = 0; + int32_t ret = FRAME_ParseMsg(&frameType, recMsg, recMsgLen, &recvframeMsg, &parseLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + FRAME_ServerHelloMsg *serverHello = &recvframeMsg.body.hsMsg.body.serverHello; + g_sessionIdSize = serverHello->sessionIdSize.data; + BSL_SAL_FREE(g_sessionId); + g_sessionId = BSL_SAL_Dump(serverHello->sessionId.data, g_sessionIdSize); + + FRAME_CleanMsg(&frameType, &recvframeMsg); + return HITLS_SUCCESS; +} + +int32_t FirstHandshake(HandshakeTestInfo *testInfo) +{ + int32_t ret = FRAME_CreateConnection(testInfo->client, testInfo->server, true, TRY_RECV_SERVER_HELLO); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = GetSessionId(testInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = FRAME_CreateConnection(testInfo->client, testInfo->server, true, HS_STATE_BUTT); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t data[] = "Hello World"; + ret = HITLS_Write(testInfo->server->ssl, data, sizeof(data)); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ret = FRAME_TrasferMsgBetweenLink(testInfo->server, testInfo->client); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HITLS_Read(testInfo->client->ssl, readBuf, READ_BUF_SIZE, &readLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + testInfo->clientSession = HITLS_GetDupSession(testInfo->client->ssl); + + FRAME_FreeLink(testInfo->client); + testInfo->client = NULL; + FRAME_FreeLink(testInfo->server); + testInfo->server = NULL; + return HITLS_SUCCESS; +} + + +/* @ +* @test UT_TLS_SNI_RESUME_SERVERNAME_FUNC_TC001 +* @title During session resumption, the serverName extension of clientHello + is different from that in first handshake +* @precon nan +* @brief 1. For the first handshake, set serverName to www.example.com in the clientHello. + Expected result 1 + 2. During session resumption, changed serverName of clientHello to www.sss.com. Expected result 2 + 3. process the client hello. Expected result 2 +* @expect 1. The serverName extension is set successfully and the handshake succeeds + 2. return success +@ */ +/* BEGIN_CASE */ +void UT_TLS_SNI_RESUME_SERVERNAME_FUNC_TC001(int version, int type) +{ + g_sessionId = NULL; + g_sessionIdSize = 0; + HandshakeTestInfo testInfo = {0}; + testInfo.version = (uint16_t)version; + testInfo.type = (BSL_UIO_TransportType)type; + testInfo.sniDealCb = ServernameCbErrOK; + + ASSERT_EQ(DefaultCfgAndLink(&testInfo), HITLS_SUCCESS); + ASSERT_EQ(FirstHandshake(&testInfo), HITLS_SUCCESS); + ASSERT_TRUE(testInfo.clientSession != NULL); + + ASSERT_TRUE(CreateLink(&testInfo) == HITLS_SUCCESS); + ASSERT_TRUE( + FRAME_CreateConnection(testInfo.client, testInfo.server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(testInfo.server->ssl->hsCtx->state == TRY_RECV_CLIENT_HELLO); + CONN_Deinit(testInfo.server->ssl); + + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(testInfo.server->io); + uint8_t *buffer = ioUserData->recMsg.msg; + uint32_t len = ioUserData->recMsg.len; + ASSERT_TRUE(len != 0); + + FRAME_Msg frameMsg = {0}; + uint32_t parseLen = 0; + + ASSERT_TRUE(ParserTotalRecord(testInfo.server, &frameMsg, buffer, len, &parseLen) == HITLS_SUCCESS); + ASSERT_TRUE(frameMsg.body.handshakeMsg.type == CLIENT_HELLO); + + char *hostName = "www.sss.com"; + uint8_t *serverName = frameMsg.body.handshakeMsg.body.clientHello.extension.content.serverName; + uint16_t serverNameSize = frameMsg.body.handshakeMsg.body.clientHello.extension.content.serverNameSize; + frameMsg.body.handshakeMsg.body.clientHello.extension.content.serverNameSize = strlen(hostName) + 1; + frameMsg.body.handshakeMsg.body.clientHello.extension.content.serverName = (uint8_t *)hostName; + + testInfo.server->ssl->method.sendAlert = STUB_SendAlert; + HS_Init(testInfo.server->ssl); + + if (testInfo.type == BSL_UIO_TCP) { + ASSERT_TRUE(Tls12ServerRecvClientHelloProcess(testInfo.server->ssl, &frameMsg.body.handshakeMsg) == + HITLS_SUCCESS); + } else { + ASSERT_TRUE(DtlsServerRecvClientHelloProcess(testInfo.server->ssl, &frameMsg.body.handshakeMsg) == + HITLS_SUCCESS); + } + frameMsg.body.handshakeMsg.body.clientHello.extension.content.serverName = serverName; + frameMsg.body.handshakeMsg.body.clientHello.extension.content.serverNameSize = serverNameSize; + +exit: + BSL_SAL_FREE(g_sessionId); + CleanRecordBody(&frameMsg); + HITLS_CFG_FreeConfig(testInfo.clientConfig); + HITLS_CFG_FreeConfig(testInfo.serverConfig); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); + HITLS_SESS_Free(testInfo.clientSession); + FreeSNIArg(sniArg); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_function.data b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_function.data new file mode 100644 index 00000000..e7a51c02 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_function.data @@ -0,0 +1,2 @@ +UT_TLS_SNI_RESUME_SERVERNAME_FUNC_TC001 +UT_TLS_SNI_RESUME_SERVERNAME_FUNC_TC001:HITLS_VERSION_TLS12:BSL_UIO_TCP \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_interface.c b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_interface.c new file mode 100644 index 00000000..aba08092 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_interface.c @@ -0,0 +1,98 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "config.h" +#include "hitls.h" +#include "hitls_func.h" +#include "hitls_error.h" +/* END_HEADER */ + +static char *g_serverName = "www.example.com"; + +int32_t ServernameCbErrOK(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)alert; + (void)arg; + + return HITLS_ACCEPT_SNI_ERR_OK; +} + +#define HITLS_CFG_MAX_SIZE 1024 + +/** @ +* @test UT_TLS_CFG_UPREF_FUNC_TC001 +* @title test HITLS_CFG_SetServerName/HITLS_CFG_SetServerNameCb/HITLS_CFG_SetServerNameArg/HITLS_GetServernameType +* interface +* +* @brief 1. Apply for and initialize config.Expect result 1 + 2. Invoke the HITLS_CFG_NewTLS12Config interface and transfer the config parameter.Expect result 2. + 3. Set serverNameStrlen HITLS_CFG_MAX_SIZE + 1;Invoke the HITLS_CFG_SetServerName interface Expect result 3. + 4. Invoke the HITLS_CFG_NewTLS12Config interface.Expect result 4. + 5. input parameters is NULL,Invoke the HITLS_CFG_NewTLS12Config interface and .Expect result 2. + 6. Invoke the HITLS_CFG_SetServerNameCb interface ,Expect result 2. + 7. Invoke the HITLS_CFG_SetServerNameArg interface ,Expect result 2. + 8. Invoke the HITLS_CFG_GetServerNameCb interface ,Expect result 2. + 9. Invoke the HITLS_CFG_GetServerNameArg interface ,Expect result 2. + 10. Invoke the HITLS_SetServerName interface ,Expect result 2. + 11. Invoke the HITLS_SetServerName interface ,Expect result 2. + 12. Invoke the HITLS_SetServerName interface ,Expect result 6. + 13. Invoke the HITLS_SetServerName interface ,Expect result 6. + 14. Invoke the HITLS_GetServernameType interface ,Expect result 1. +* @expect 1. return Not NULL + 2. return HITLS_NULL_INPUT + 3. return HITLS_CONFIG_INVALID_LENGTH + 4. return SUCCESS + 5. return HITLS_NULL_INPUT + 6. return NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_SERVERNAME_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + ASSERT_TRUE(HITLS_CFG_SetServerName(NULL, (uint8_t *)g_serverName, (uint32_t)strlen(g_serverName)) == + HITLS_NULL_INPUT); + uint32_t errLen = HITLS_CFG_MAX_SIZE + 1; + ASSERT_TRUE(HITLS_CFG_SetServerName(config, (uint8_t *)g_serverName, errLen) == HITLS_CONFIG_INVALID_LENGTH); + ASSERT_TRUE(HITLS_CFG_SetServerName(config, (uint8_t *)g_serverName, (uint32_t)strlen(g_serverName)) == + HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetServerName(NULL, NULL, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_SetServerNameCb(NULL, ServernameCbErrOK) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetServerNameArg(NULL, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_GetServerNameCb(NULL, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetServerNameArg(NULL, NULL) == HITLS_NULL_INPUT); + + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_SetServerName(ctx, NULL, 0) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetServerName(NULL, (uint8_t *)g_serverName, 0) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_GetServerName(ctx, HITLS_SNI_BUTT) == NULL); + ASSERT_TRUE(HITLS_GetServerName(NULL, HITLS_SNI_HOSTNAME_TYPE) == NULL); + + ASSERT_TRUE(HITLS_GetServernameType(ctx) != 0); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_interface.data b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_interface.data new file mode 100644 index 00000000..284ef5e5 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_servername_interface.data @@ -0,0 +1,2 @@ +UT_TLS_CFG_SET_SERVERNAME_API_TC001 +UT_TLS_CFG_SET_SERVERNAME_API_TC001: diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_session_ticket.c b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_session_ticket.c new file mode 100644 index 00000000..fe4512cd --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_session_ticket.c @@ -0,0 +1,87 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "frame_tls.h" +#include "frame_link.h" +#include "session.h" +#include "hitls_config.h" +#include "hitls_crypt_init.h" +/* END_HEADER */ + +static int32_t ServernameCbErrOK(HITLS_Ctx *ctx, int *alert, void *arg) +{ + (void)ctx; + (void)alert; + (void)arg; + + return HITLS_ACCEPT_SNI_ERR_OK; +} +/** @ +* @test UT_TLS12_RESUME_FUNC_TC001 +* @title Test the session resume of tls12. +* +* @brief 1. at first handshake, config serverName, and sessionidCtx. Expect result 1 + 2. at second handshake, Expect result 2 +* @expect 1. connect success + 2. resume success +@ */ +/* BEGIN_CASE */ +void UT_TLS12_RESUME_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + + HITLS_CFG_SetServerName(config, (uint8_t *)"www.test.com", (uint32_t)strlen((char *)"www.test.com")); + HITLS_CFG_SetServerNameCb(config, ServernameCbErrOK); + + char *sessionIdCtx1 = "123456789"; + ASSERT_EQ(HITLS_CFG_SetSessionIdCtx(config, (const uint8_t *)sessionIdCtx1, strlen(sessionIdCtx1)), HITLS_SUCCESS); + + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + + HITLS_Session *clientSession = HITLS_GetDupSession(client->ssl); + ASSERT_TRUE(clientSession != NULL); + + FRAME_FreeLink(client); + client = NULL; + FRAME_FreeLink(server); + server = NULL; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetSession(client->ssl, clientSession), HITLS_SUCCESS); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_EQ(HITLS_IsSessionReused(client->ssl, &isReused), HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + HITLS_SESS_Free(clientSession); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_session_ticket.data b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_session_ticket.data new file mode 100644 index 00000000..0f7f4ccc --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_frame_session_ticket.data @@ -0,0 +1,2 @@ +UT_TLS12_RESUME_FUNC_TC001 +UT_TLS12_RESUME_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_hlt_session_ticket.c b/testcode/sdv/testcase/tls/feature/test_suite_sdv_hlt_session_ticket.c new file mode 100644 index 00000000..2cb50b81 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_hlt_session_ticket.c @@ -0,0 +1,125 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "hlt.h" +#include "process.h" +#include "session.h" +#include "hitls_config.h" +#include "hitls_crypt_init.h" +/* END_HEADER */ + +/** @ +* @test SDV_TLS12_RESUME_FUNC_TC001 +* @title Test the PSK-based session resume of tls12. +* +* @brief 1. at first handshake, config the client does not support tickets, +but the server supports tickets. Expect result 1 + 2. after first handshake, config the client support tickets, Expect result 2 +* @expect 1. connect success + 2. resume success +@ */ +/* BEGIN_CASE */ +void SDV_TLS12_RESUME_FUNC_TC001() +{ + int version = TLS1_2; + int connType = TCP; + Process *localProcess = NULL; + Process *remoteProcess = NULL; + HLT_FD sockFd = {0}; + HITLS_Session *session = NULL; + int32_t cnt = 0; + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_CreateRemoteProcess(HITLS); + ASSERT_TRUE(remoteProcess != NULL); + + int32_t serverConfigId = HLT_RpcTlsNewCtx(remoteProcess, version, false); + void *clientConfig = HLT_TlsNewCtx(version); + ASSERT_TRUE(clientConfig != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + clientCtxConfig->isSupportSessionTicket = false; + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + serverCtxConfig->isSupportSessionTicket = true; + HLT_SetPsk(clientCtxConfig, "123456789"); + HLT_SetPsk(serverCtxConfig, "123456789"); + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + ASSERT_TRUE(HLT_RpcTlsSetCtx(remoteProcess, serverConfigId, serverCtxConfig) == 0); + + do { + DataChannelParam channelParam; + channelParam.port = 18889; + channelParam.type = connType; + channelParam.isBlock = true; + sockFd = HLT_CreateDataChannel(localProcess, remoteProcess, channelParam); + ASSERT_TRUE((sockFd.srcFd > 0) && (sockFd.peerFd > 0)); + remoteProcess->connFd = sockFd.peerFd; + localProcess->connFd = sockFd.srcFd; + remoteProcess->connType = connType; + localProcess->connType = connType; + if (cnt > 0) { + clientCtxConfig->isSupportSessionTicket = true; + ASSERT_TRUE(HLT_TlsSetCtx(clientConfig, clientCtxConfig) == 0); + } + int32_t serverSslId = HLT_RpcTlsNewSsl(remoteProcess, serverConfigId); + + HLT_Ssl_Config *serverSslConfig; + serverSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(serverSslConfig != NULL); + serverSslConfig->sockFd = remoteProcess->connFd; + serverSslConfig->connType = connType; + ASSERT_TRUE(HLT_RpcTlsSetSsl(remoteProcess, serverSslId, serverSslConfig) == 0); + HLT_RpcTlsAccept(remoteProcess, serverSslId); + + void *clientSsl = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientSsl != NULL); + + HLT_Ssl_Config *clientSslConfig; + clientSslConfig = HLT_NewSslConfig(NULL); + ASSERT_TRUE(clientSslConfig != NULL); + clientSslConfig->sockFd = localProcess->connFd; + clientSslConfig->connType = connType; + + HLT_TlsSetSsl(clientSsl, clientSslConfig); + if (session != NULL) { + ASSERT_TRUE(HITLS_SetSession(clientSsl, session) == HITLS_SUCCESS); + } + if (cnt == 0) { + ASSERT_TRUE(HLT_TlsConnect(clientSsl) == 0); + } else { + int ret = HLT_TlsConnect(clientSsl); + ASSERT_EQ(ret, HITLS_SUCCESS); + uint8_t isReused = 0; + ASSERT_TRUE(HITLS_IsSessionReused(clientSsl, &isReused) == HITLS_SUCCESS); + ASSERT_EQ(isReused, 1); + } + ASSERT_TRUE(HLT_TlsClose(clientSsl) == 0); + HLT_RpcTlsClose(remoteProcess, serverSslId); + HLT_RpcCloseFd(remoteProcess, sockFd.peerFd, remoteProcess->connType); + HLT_CloseFd(sockFd.srcFd, localProcess->connType); + HITLS_SESS_Free(session); + session = HITLS_GetDupSession(clientSsl); + ASSERT_TRUE(session != NULL); + cnt++; + } while (cnt < 3); + +exit: + HITLS_SESS_Free(session); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/feature/test_suite_sdv_hlt_session_ticket.data b/testcode/sdv/testcase/tls/feature/test_suite_sdv_hlt_session_ticket.data new file mode 100644 index 00000000..99a845a3 --- /dev/null +++ b/testcode/sdv/testcase/tls/feature/test_suite_sdv_hlt_session_ticket.data @@ -0,0 +1,2 @@ +SDV_TLS12_RESUME_FUNC_TC001 +SDV_TLS12_RESUME_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_cm_1.c b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_cm_1.c new file mode 100644 index 00000000..b1b05adb --- /dev/null +++ b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_cm_1.c @@ -0,0 +1,761 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "sal_net.h" +#include "frame_tls.h" +#include "cert_callback.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "frame_io.h" +#include "uio_abstraction.h" +#include "tls.h" +#include "tls_config.h" +#include "logger.h" +#include "process.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "stub_replace.h" +#include "hitls_type.h" +#include "frame_link.h" +#include "session_type.h" +#include "common_func.h" +#include "hitls_func.h" +#include "hitls_cert_type.h" +#include "cert_mgr_ctx.h" +#include "parser_frame_msg.h" +#include "recv_process.h" +#include "simulate_io.h" +#include "rec_wrapper.h" +#include "cipher_suite.h" +#include "alert.h" +#include "conn_init.h" +#include "pack.h" +#include "send_process.h" +#include "cert.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "hs.h" +#include "hs_state_recv.h" +#include "app.h" +#include "record.h" +#include "rec_conn.h" +#include "session.h" +#include "frame_msg.h" +#include "pack_frame_msg.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "sctp_channel.h" +#include "hitls_crypt_init.h" +#include "hitls_session.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "hitls_crypt_reg.h" +#include "crypt_errno.h" +#include "bsl_list.h" +#include "hitls_cert.h" +/* END_HEADER */ + +static char *g_serverName = "testServer"; +uint32_t g_uiPort = 18888; +#define DEFAULT_DESCRIPTION_LEN 128 +#define TLS_DHE_PARAM_MAX_LEN 1024 +#define GET_GROUPS_CNT (-1) + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; + HITLS_TicketKeyCb serverKeyCb; +} ResumeTestInfo; + +int32_t HITLS_RemoveCertAndKey(HITLS_Ctx *ctx); +HITLS_CRYPT_Key *cert_key = NULL; +HITLS_CRYPT_Key *DH_CB(HITLS_Ctx *ctx, int32_t isExport, uint32_t keyLen) +{ + (void)ctx; + (void)isExport; + (void)keyLen; + return cert_key; +} + +void *STUB_SAL_Calloc(uint32_t num, uint32_t size) +{ + (void)num; + (void)size; + return NULL; +} + +void *STUB_SAL_Dump(const void *src, uint32_t size) +{ + (void)src; + (void)size; + return NULL; +} + +FuncStubInfo g_TmpRpInfo = {0}; + +int32_t STUB_BSL_UIO_Read(BSL_UIO *uio, void *data, uint32_t len, uint32_t *readLen) +{ + (void)uio; + (void)data; + (void)len; + (void)readLen; + return 0; +} + +static HITLS_Config *GetHitlsConfigViaVersion(int ver) +{ + switch (ver) { + case HITLS_VERSION_TLS12: + return HITLS_CFG_NewTLS12Config(); + case HITLS_VERSION_TLS13: + return HITLS_CFG_NewTLS13Config(); + case HITLS_VERSION_DTLS12: + return HITLS_CFG_NewDTLS12Config(); + default: + return NULL; + } +} + +/** @ +* @test UT_TLS_CM_IS_DTLS_API_TC001 +* @title Test HITLS_IsDtls +* @precon nan +* @brief HITLS_IsDtls +* 1. Input an empty TLS connection handle. Expected result 1. +* 2. Transfer the non-empty TLS connection handle information and leave isDtls blank. Expected result 1. +* 3. Transfer the non-empty TLS connection handle information. The isDtls parameter is not empty. Expected result 2 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CM_IS_DTLS_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t isDtls = 0; + ASSERT_TRUE(HITLS_IsHandShakeDone(ctx, &isDtls) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_IsHandShakeDone(ctx, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_IsHandShakeDone(ctx, &isDtls) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_SET_CLEAR_CIPHERSUITES_API_TC001 +* @title Test the HITLS_SetCipherSuites and HITLS_ClearTLS13CipherSuites interfaces. +* @precon nan +* @brief HITLS_SetCipherSuites +* 1. Input an empty TLS connection handle. Expected result 1. +* 2. Transfer non-empty TLS connection handle information and leave cipherSuites empty. Expected result 1. +* 3. Transfer the non-empty TLS connection handle information. If cipherSuites is not empty and cipherSuitesSize is 0, +* the expected result is 1. +* 4. Transfer the non-empty TLS connection handle information. Set cipherSuites to a value greater than +* HITLS_CFG_MAX_SIZE. Expected result 2. +* 5. The input parameters are valid, and the SAL_CALLOC table is instrumented. Expected result 3. +* 6. Transfer the non-null TLS connection handle information, set cipherSuites to an invalid value, and set +* cipherSuitesSize to a value smaller than HITLS_CFG_MAX_SIZE. Expected result 4 is displayed. +* 7. Transfer valid parameters. Expected result 5. +* HITLS_ClearTLS13CipherSuites +* 1. Input an empty TLS connection handle. Expected result 1. +* 2. Transfer the non-empty TLS connection handle information. Expected result 5. +* @expect 1. Returns HITLS_NULL_INPUT +* 2. Return HITLS_HITLS_CM_INVALID_LENGTH +* 3. Returns HITLS_MEMALLOC_FAIL +* 4. Return HITLS_HITLS_CM_NO_SUITABLE_CIPHER_SUITE +* 5. Returns HITLS_SUCCESS +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CM_SET_CLEAR_CIPHERSUITES_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint16_t cipherSuites[10] = { + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + }; + + ASSERT_TRUE(HITLS_SetCipherSuites(ctx, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_ClearTLS13CipherSuites(ctx) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetCipherSuites(ctx, NULL, 0) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetCipherSuites(ctx, cipherSuites, 0) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetCipherSuites(ctx, cipherSuites, HITLS_CFG_MAX_SIZE + 1) == HITLS_CONFIG_INVALID_LENGTH); + + STUB_Init(); + FuncStubInfo tmpRpInfo; + STUB_Replace(&tmpRpInfo, BSL_SAL_Calloc, STUB_SAL_Calloc); + ASSERT_TRUE( + HITLS_SetCipherSuites(ctx, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_MEMALLOC_FAIL); + STUB_Reset(&tmpRpInfo); + uint16_t cipherSuites2[10] = {0}; + cipherSuites2[0] = 0xFFFF; + cipherSuites2[1] = 0xEFFF; + ASSERT_TRUE(HITLS_SetCipherSuites(ctx, cipherSuites2, sizeof(cipherSuites2) / sizeof(uint16_t)) == + HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE); + ASSERT_TRUE(HITLS_SetCipherSuites(ctx, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + if (tlsVersion == HITLS_VERSION_TLS13) { + ASSERT_TRUE(HITLS_ClearTLS13CipherSuites(ctx) == HITLS_SUCCESS); + ASSERT_TRUE(ctx->config.tlsConfig.tls13cipherSuitesSize == 0); + } +exit: + STUB_Reset(&tmpRpInfo); + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_SET_GET_ENCRYPTHENMAC_FUNC_TC001 +* @title HITLS_GetEncryptThenMac and HITLS_SetEncryptThenMac interface validation +* @precon nan +* @brief +* 1. After initialization, call the hitls_setencryptthenmac interface to set the value to true and call the +* HITLS_GetEncryptThenMac interface to query the value. Expected result 1. +* 2. Set hitls_setencryptthenmac to true at both ends. After the connection is set up, invoke the HITLS_GetEncryptThenMac +* interface to query the connection. Expected result 2. +* @expect +* 1. The return value is true. +* 2. The return value is true. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_ENCRYPTHENMAC_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + uint32_t encryptThenMacType = 0; + ASSERT_EQ(HITLS_GetEncryptThenMac(server->ssl, &encryptThenMacType), HITLS_SUCCESS); + ASSERT_EQ(encryptThenMacType, 1); + + ASSERT_EQ(HITLS_GetEncryptThenMac(client->ssl, &encryptThenMacType), HITLS_SUCCESS); + ASSERT_EQ(encryptThenMacType, 1); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ASSERT_EQ(HITLS_GetEncryptThenMac(server->ssl, &encryptThenMacType), HITLS_SUCCESS); + ASSERT_EQ(encryptThenMacType, 1); + ASSERT_EQ(HITLS_GetEncryptThenMac(client->ssl, &encryptThenMacType), HITLS_SUCCESS); + ASSERT_EQ(encryptThenMacType, 1); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_SET_SERVERNAME_FUNC_TC001 +* @title HITLS_SetServerName invokes the interface to set the server name. +* @precon nan +* @brief +* 1. Initialize the client and server. Expected result 1 +* 2. After the initialization, set the servername and run the HITLS_GetServerName command to check the server name. +* Expected result 2 is displayed +* @expect +* 1. Complete initialization +* 2. The returned result is consistent with the settings +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_SERVERNAME_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS12Config(); + + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(HITLS_SetServerName(client->ssl, (uint8_t *)g_serverName, (uint32_t)strlen(g_serverName)), + HITLS_SUCCESS); + client->ssl->isClient = true; + const char *server_name = HITLS_GetServerName(client->ssl, HITLS_SNI_HOSTNAME_TYPE); + ASSERT_TRUE(memcmp(server_name, (uint8_t *)g_serverName, strlen(g_serverName)) == 0); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001 +* @title Test the HITLS_SetSessionTicketSupport and HITLS_GetSessionTicketSupport interfaces. +* @precon nan +* @brief HITLS_SetSessionTicketSupport +* 1. Input an empty TLS connection handle. Expected result 1. +* 2. Transfer a non-empty TLS connection handle and set isEnable to an invalid value. Expected result 2. +* 3. Transfer the non-empty TLS connection handle information and set isEnable to a valid value. Expected result 3 is +* obtained. +* HITLS_GetSessionTicketSupport +* 1. Input an empty TLS connection handle. Expected result 1. +* 2. Pass an empty getIsSupport pointer. Expected result 1. +* 3. Transfer the non-null TLS connection handle information and ensure that the getIsSupport pointer is not null. +* Expected result 3. +* @expect 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and ctx->config.tlsConfig.isSupportSessionTicket is true. +* 3. Returns HITLS_SUCCES and ctx->config.tlsConfig.isSupportSessionTicket is true or false. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t isSupport = -1; + uint8_t getIsSupport = -1; + ASSERT_TRUE(HITLS_SetSessionTicketSupport(ctx, isSupport) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetSessionTicketSupport(ctx, &getIsSupport) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetSessionTicketSupport(ctx, NULL) == HITLS_NULL_INPUT); + isSupport = 1; + ASSERT_TRUE(HITLS_SetSessionTicketSupport(ctx, isSupport) == HITLS_SUCCESS); + isSupport = -1; + ASSERT_TRUE(HITLS_SetSessionTicketSupport(ctx, isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(ctx->config.tlsConfig.isSupportSessionTicket = true); + isSupport = 0; + ASSERT_TRUE(HITLS_SetSessionTicketSupport(ctx, isSupport) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_GetSessionTicketSupport(ctx, &getIsSupport) == HITLS_SUCCESS); + ASSERT_TRUE(getIsSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_VERIFY_CLIENT_POST_HANDSHAKE_API_TC001 +* @title Invoke the HITLS_VerifyClientPostHandshake interface during connection establishment. +* @precon nan +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1. +* 2. Configure the client and server to support post-handshake extension. Expected result 3. +* 3. When a connection is established, the server is in the Try_RECV_CLIENT_HELLO state, and the +* HITLS_VerifyClientPostHandshake interface is invoked. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. The interface fails to be invoked. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_VERIFY_CLIENT_POST_HANDSHAKE_API_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + // Apply for and initialize the configuration file + config = HITLS_CFG_NewTLS13Config(); + client = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(server != NULL); + + // Configure the client and server to support post-handshake extension + client->ssl->config.tlsConfig.isSupportPostHandshakeAuth = true; + server->ssl->config.tlsConfig.isSupportPostHandshakeAuth = true; + ASSERT_TRUE(client->ssl->config.tlsConfig.isSupportPostHandshakeAuth == true); + ASSERT_TRUE(server->ssl->config.tlsConfig.isSupportPostHandshakeAuth == true); + + // he server is in the Try_RECV_CLIENT_HELLO state + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_RECV_CLIENT_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(server->ssl->hsCtx->state == TRY_RECV_CLIENT_HELLO); + + // the HITLS_VerifyClientPostHandshake interface is invoked + ASSERT_EQ(HITLS_VerifyClientPostHandshake(client->ssl), HITLS_INVALID_INPUT); + ASSERT_EQ(HITLS_VerifyClientPostHandshake(server->ssl), HITLS_MSG_HANDLE_STATE_ILLEGAL); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_REMOVE_CERTANDKEY_API_TC001 +* @title Test the HITLS_RemoveCertAndKey interface. +* @brief +* 1. Apply for and initialize the configuration file. Expected result 1. +* 2. Invoke the client HITLS_CFG_SetClientVerifySupport and HITLS_CFG_SetNoClientCertSupport. Expected result 2. +* 3. Invoke the HITLS_RemoveCertAndKey, Expected result 3. +* @expect +* 1. The initialization is successful. +* 2. The setting is successful. +* 3. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_REMOVE_CERTANDKEY_API_TC001(void) +{ + FRAME_Init(); + int32_t ret; + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(config != NULL); + + ret = HITLS_CFG_SetClientVerifySupport(config, true); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ret = HITLS_CFG_SetNoClientCertSupport(config, true); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(server != NULL); + + ret = HITLS_RemoveCertAndKey(client->ssl); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = FRAME_CreateConnection(client, server, false, HS_STATE_BUTT); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(server->ssl->state == CM_STATE_TRANSPORTING); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +static int32_t TestHITLS_PasswordCb(char *buf, int32_t bufLen, int32_t flag, void *userdata) +{ + (void)buf; + (void)bufLen; + (void)flag; + (void)userdata; + return 0; +} + +/* @ +* @test UT_TLS_CM_SET_GET_DEFAULT_API_TC001 +* @title Test HITLS_SetDefaultPasswordCb/HITLS_GetDefaultPasswordCb interface +* @brief 1. Invoke the HITLS_SetDefaultPasswordCb interface. Expected result 1. +* 2. Invoke the HITLS_SetDefaultPasswordCb interface. The value of ctx is not empty and the value of password is +* not empty. Expected result 3. +* 3. Invoke the HITLS_GetDefaultPasswordCb interface and leave ctx blank. Expected result 2. +* @expect 1. Returns HITLS_NULL_INPUT +* 2. NULL is returned. +* 3. HITLS_SUCCESS is returned. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_DEFAULT_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetDefaultPasswordCb(NULL, TestHITLS_PasswordCb) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetDefaultPasswordCb(ctx, TestHITLS_PasswordCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetDefaultPasswordCb(NULL) == NULL); + ASSERT_TRUE(HITLS_GetDefaultPasswordCb(ctx) == TestHITLS_PasswordCb); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_GET_SESSION_API_TC001 +* @title Test HITLS_SetSession/HITLS_GetSession interface +* @brief 1. If ctx is NULL, Invoke the HITLS_SetSession interface.Expected result 1. +* 2. Invoke the HITLS_SetSession interface.Expected result 2. +* 3. Invoke the HITLS_GetSession interface. Expected result 2. +* @expect 1. Returns HITLS_NULL_INPUT +* 2. returnes HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_SESSION_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_SetSession(NULL, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetSession(ctx, NULL) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetSession(ctx) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_PEERSIGNATURE_TYPE_API_TC001 +* @title Test HITLS_GetPeerSignatureType interface +* @brief 1. If ctx is NULL, Invoke the HITLS_GetPeerSignatureType interface. Expected result 2. +* 2. Invoke the HITLS_GetPeerSignatureType interface. Expected result 1. +* @expect 1. Returns HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE +* 2.Returns HITLS_NULL_INPUT +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_PEERSIGNATURE_TYPE_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + HITLS_SignAlgo sigType = {0}; + ASSERT_EQ(HITLS_GetPeerSignatureType(NULL, NULL), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_GetPeerSignatureType(ctx, &sigType), HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +static void Test_Warning_Alert(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)bufSize; + (void)user; + (void)len; + (void)data; + uint8_t alertdata[2] = {0x01, 0x29}; + REC_Write(ctx, REC_TYPE_ALERT, alertdata, 2); + return; +} + +static void Test_Fatal_Alert(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, + uint32_t bufSize, void *user) +{ + (void)bufSize; + (void)user; + (void)len; + (void)data; + uint8_t alertdata[2] = {0x02, 0x29}; + REC_Write(ctx, REC_TYPE_ALERT, alertdata, 2); + return; +} + +/** @ +* @test UT_TLS_CM_WARNING_ALERT_TC001 +* @title recv warning alert brefore client hello need to return UNEXPECT_MSG alert +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 +* 2. After the initialization, send a warning alert to server, expect reslut 2. +* @expect 1. The initialization is successful. +* 2. The client send a unexpected message alert +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_WARNING_ALERT_TC001(int version) +{ + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Warning_Alert + }; + RegisterWrapper(wrapper); + + FRAME_Init(); + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + /* Link initialization */ + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(client->ssl->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_EQ(server->ssl->state, CM_STATE_ALERTED); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + return; +} +/* END_CASE */ + + +/** @ +* @test UT_TLS_CM_FATAL_ALERT_TC001 +* @title recv fatal alert brefore client hello need to close connection +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 +* 2. After the initialization, send a fetal alert to server, expect reslut 2. +* @expect 1. The initialization is successful. +* 2. The client close the connection +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_FATAL_ALERT_TC001(int version) +{ + RecWrapper wrapper = { + TRY_SEND_CLIENT_HELLO, + REC_TYPE_HANDSHAKE, + false, + NULL, + Test_Fatal_Alert + }; + RegisterWrapper(wrapper); + + FRAME_Init(); + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + /* Link initialization */ + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(client->ssl->state == CM_STATE_IDLE); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + ASSERT_EQ(server->ssl->state, CM_STATE_ALERTED); + + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + /* Alert recv means the handshake state is in alerting state and no alert to be sent*/ + ASSERT_EQ(info.flag, ALERT_FLAG_RECV); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_NO_CERTIFICATE_RESERVED); + +exit: + ClearWrapper(); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_cm_1.data b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_cm_1.data new file mode 100644 index 00000000..2b7627bc --- /dev/null +++ b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_cm_1.data @@ -0,0 +1,71 @@ +UT_TLS_CM_IS_DTLS_API_TC001 +UT_TLS_CM_IS_DTLS_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_IS_DTLS_API_TC001 +UT_TLS_CM_IS_DTLS_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_SET_CLEAR_CIPHERSUITES_API_TC001 +UT_TLS_CM_SET_CLEAR_CIPHERSUITES_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_CLEAR_CIPHERSUITES_API_TC001 +UT_TLS_CM_SET_CLEAR_CIPHERSUITES_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_SET_GET_ENCRYPTHENMAC_FUNC_TC001 HITLS_VERSION_TLS12 +UT_TLS_CM_SET_GET_ENCRYPTHENMAC_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_SERVERNAME_FUNC_TC001 +UT_TLS_CM_SET_SERVERNAME_FUNC_TC001: + +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001 +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001 +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001 +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001 +UT_TLS_CM_SET_GET_SESSION_TICKET_SUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_VERIFY_CLIENT_POST_HANDSHAKE_API_TC001 +UT_TLS_CM_VERIFY_CLIENT_POST_HANDSHAKE_API_TC001: + +UT_TLS_CM_REMOVE_CERTANDKEY_API_TC001 +UT_TLS_CM_REMOVE_CERTANDKEY_API_TC001: + +UT_TLS_CM_SET_GET_DEFAULT_API_TC001 +UT_TLS_CM_SET_GET_DEFAULT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_DEFAULT_API_TC001 +UT_TLS_CM_SET_GET_DEFAULT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_SET_GET_SESSION_API_TC001 +UT_TLS_CM_SET_GET_SESSION_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_SESSION_API_TC001 +UT_TLS_CM_SET_GET_SESSION_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_GET_PEERSIGNATURE_TYPE_API_TC001 +UT_TLS_CM_GET_PEERSIGNATURE_TYPE_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_PEERSIGNATURE_TYPE_API_TC001 +UT_TLS_CM_GET_PEERSIGNATURE_TYPE_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_WARNING_ALERT_TC001 +UT_TLS_CM_WARNING_ALERT_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_WARNING_ALERT_TC001 +UT_TLS_CM_WARNING_ALERT_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_WARNING_ALERT_TC001 +UT_TLS_CM_WARNING_ALERT_TC001:HITLS_VERSION_DTLS12 + +UT_TLS_CM_FATAL_ALERT_TC001 +UT_TLS_CM_FATAL_ALERT_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_FATAL_ALERT_TC001 +UT_TLS_CM_FATAL_ALERT_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_FATAL_ALERT_TC001 +UT_TLS_CM_FATAL_ALERT_TC001:HITLS_VERSION_DTLS12 \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_config_1.c b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_config_1.c new file mode 100644 index 00000000..d71ff838 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_config_1.c @@ -0,0 +1,1433 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "sal_net.h" +#include "hitls.h" +#include "frame_tls.h" +#include "cert_callback.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "frame_io.h" +#include "uio_abstraction.h" +#include "tls.h" +#include "tls_config.h" +#include "logger.h" +#include "process.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "stub_replace.h" +#include "hitls_type.h" +#include "frame_link.h" +#include "session_type.h" +#include "common_func.h" +#include "hitls_func.h" +#include "hitls_cert_type.h" +#include "cert_mgr_ctx.h" +#include "parser_frame_msg.h" +#include "recv_process.h" +#include "simulate_io.h" +#include "rec_wrapper.h" +#include "cipher_suite.h" +#include "alert.h" +#include "conn_init.h" +#include "pack.h" +#include "send_process.h" +#include "cert.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "hs.h" +#include "hs_state_recv.h" +#include "app.h" +#include "record.h" +#include "rec_conn.h" +#include "session.h" +#include "frame_msg.h" +#include "pack_frame_msg.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "sctp_channel.h" +#include "hitls_crypt_init.h" +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "bsl_uio.h" +#include "hitls_crypt_reg.h" +#include "hitls_session.h" +#include "cert_method.h" +#include "bsl_list.h" +#define DEFAULT_DESCRIPTION_LEN 128 +#define ERROR_HITLS_GROUP 1 +#define ERROR_HITLS_SIGNATURE 0xffffu +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; /* Set the session to the client for session resume. */ +} ResumeTestInfo; + +HITLS_CERT_X509 *HiTLS_X509_LoadCertFile(const char *file); +void SAL_CERT_X509Free(HITLS_CERT_X509 *cert); + +static HITLS_Config *GetHitlsConfigViaVersion(int ver) +{ + switch (ver) { + case TLS1_2: + case HITLS_VERSION_TLS12: + return HITLS_CFG_NewTLS12Config(); + case TLS1_3: + case HITLS_VERSION_TLS13: + return HITLS_CFG_NewTLS13Config(); + case DTLS1_2: + case HITLS_VERSION_DTLS12: + return HITLS_CFG_NewDTLS12Config(); + default: + return NULL; + } +} + +int32_t Stub_Write(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + (void)uio; + (void)buf; + (void)len; + (void)writeLen; + return HITLS_SUCCESS; +} + +int32_t Stub_Read(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen) +{ + (void)uio; + (void)buf; + (void)len; + (void)readLen; + return HITLS_SUCCESS; +} + +int32_t Stub_Ctrl(BSL_UIO *uio, BSL_UIO_CtrlParameter cmd, void *param) +{ + (void)uio; + (void)cmd; + (void)param; + return HITLS_SUCCESS; +} +/* END_HEADER */ + +/** @ +* @test UT_TLS_CFG_SET_VERSION_API_TC001 +* @title Overwrite the input parameter of the HITLS_CFG_SetVersion interface. +* @precon nan +* @brief 1. Invoke the HITLS_CFG_SetVersion interface and leave config blank. Expected result 2 . +* 2. Invoke the HITLS_CFG_SetVersion interface. The config parameter is not empty. The minimum version number is +* DTLS1.0, and the maximum version number is DTLS1.2. Expected result 2 . +* 3. Invoke the HITLS_CFG_SetVersion interface. The config parameter is not empty, the minimum version number is +* DTLS1.2, and the maximum version number is DTLS1.2. Expected result 1 . +* 4. Invoke the HITLS_CFG_SetVersion interface, set config to a value, set the minimum version number to DTLS1.2, and +* set the maximum version number to DTLS1.0. Expected result 2 . +* 5. Invoke the HITLS_CFG_SetVersion interface, set config to a value, set the minimum version number to DTLS1.2, and +* set the maximum version number to TLS1.0. (Expected result 2) +* 6. Invoke the HITLS_CFG_SetVersion interface, set config to a value, set the minimum version number to DTLS1.2, and +* set the maximum version number to TLS1.2. Expected result 2 . +* 7. Invoke the HITLS_CFG_SetVersion interface, set config to a value, set the minimum version number to TLS1.0, and set +* the maximum version number to DTLS1.2. Expected result 2 . +* 8. Invoke the HITLS_CFG_SetVersion interface, set config to a value, set the minimum version number to TLS1.2, and set +* the maximum version number to DTLS1.2. Expected result 2 . +* @expect 1. The interface returns a success response, HITLS_SUCCESS. +* 2. The interface returns an error code. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_VERSION_API_TC001(void) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + + int32_t ret; + ret = HITLS_CFG_SetVersion(NULL, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12); + ASSERT_TRUE(ret != HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_DTLS10, HITLS_VERSION_DTLS12); + ASSERT_TRUE(ret != HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS10); + ASSERT_TRUE(ret != HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_DTLS12, HITLS_VERSION_TLS10); + ASSERT_TRUE(ret != HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_DTLS12, HITLS_VERSION_TLS12); + ASSERT_TRUE(ret != HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_TLS10, HITLS_VERSION_DTLS12); + ASSERT_TRUE(ret != HITLS_SUCCESS); + + ret = HITLS_CFG_SetVersion(tlsConfig, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12); + ASSERT_TRUE(ret != HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_VERSIONFORBID_API_TC001 +* @title Test the HITLS_CFG_SetVersionForbid interface. +* @precon nan +* @brief HITLS_CFG_SetVersionForbid +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer non-empty configuration information and set version to an invalid value. Expected result 2. +* 3. Transfer non-empty configuration information and set version to a valid value. Expected result 3. +* 4. Use HITLS_CFG_GetVersionSupport to view the result. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned, and invalid values in config are filtered out. +* 3. HITLS_SUCCES is returned and config is the expected value. +* 4. The HITLS_SUCCES parameter is returned, and the version parameter is set to the value recorded in the config file. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_VERSIONFORBID_API_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint32_t version = TLS12_VERSION_BIT; + + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_NULL_INPUT); + + version = 0; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS12_VERSION_BIT); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS12); + HITLS_CFG_FreeConfig(config); + + config = HITLS_CFG_NewTLSConfig(); + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS_VERSION_MASK); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + HITLS_CFG_FreeConfig(config); + + config = HITLS_CFG_NewTLS12Config(); + version = HITLS_VERSION_TLS12; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS12_VERSION_BIT); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS12); + + version = HITLS_VERSION_DTLS12; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS12_VERSION_BIT); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS12); + + version = 0x0305u; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS12_VERSION_BIT); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS12); + HITLS_CFG_FreeConfig(config); + config = HITLS_CFG_NewTLSConfig(); + version = HITLS_VERSION_DTLS12; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS_VERSION_MASK); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + + version = 0x0305u; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS_VERSION_MASK); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + HITLS_CFG_FreeConfig(config); + + config = HITLS_CFG_NewTLSConfig(); + version = HITLS_VERSION_TLS13; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS12_VERSION_BIT); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS12); + + HITLS_CFG_FreeConfig(config); + config = HITLS_CFG_NewTLSConfig(); + version = HITLS_TLS_ANY_VERSION; + ASSERT_TRUE(HITLS_CFG_SetVersionForbid(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == TLS_VERSION_MASK); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_EXTENEDMASTERSECRETSUPPORT_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetExtenedMasterSecretSupport and HITLS_CFG_GetExtenedMasterSecretSupport interfaces. +* @precon nan +* @brief HITLS_CFG_SetExtenedMasterSecretSupport +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer non-empty configuration information and set support to an invalid value. Expected result 2. +* 3. Transfer non-empty configuration information and set support to a valid value. Expected result 3. +* HITLS_CFG_GetExtenedMasterSecretSupport +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer an empty isSupport pointer. Expected result 1. +* 3. Transfer the non-null configuration information and the isSupport pointer is not null. Expected result 3 is +* obtained. +* @expect 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and config->isSupportExtendMasterSecret is true. +* 3. Returns HITLS_SUCCES and config->isSupportExtendMasterSecret is true or false. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_EXTENEDMASTERSECRETSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_CFG_SetExtenedMasterSecretSupport(config, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetExtenedMasterSecretSupport(config, &isSupport) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetExtenedMasterSecretSupport(config, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_CFG_SetExtenedMasterSecretSupport(config, support) == HITLS_SUCCESS); + + support = -1; + ASSERT_TRUE(HITLS_CFG_SetExtenedMasterSecretSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetExtenedMasterSecretSupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_CFG_SetExtenedMasterSecretSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetExtenedMasterSecretSupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_POSTHANDSHAKEAUTHSUPPORT_API_TC001 +* @spec - +* @titleTest the HITLS_CFG_SetPostHandshakeAuthSupport and HITLS_CFG_GetPostHandshakeAuthSupport interfaces. +* @precon nan +* @brief HITLS_CFG_SetPostHandshakeAuthSupport +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer non-empty configuration information and set support to an invalid value. Expected result 2. +* 3. Transfer non-empty configuration information and set support to a valid value. Expected result 3. +* HITLS_CFG_GetPostHandshakeAuthSupport +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer an empty isSupport pointer. Expected result 1. +* 3. Transfer the non-null configuration information and the isSupport pointer is not null. Expected result 3 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and the value of config->isSupportPostHandshakeAuth is true. +* 3. HITLS_SUCCES is returned and config->isSupportPostHandshakeAuth is true or false. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_POSTHANDSHAKEAUTHSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_CFG_SetPostHandshakeAuthSupport(config, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetPostHandshakeAuthSupport(config, &isSupport) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetPostHandshakeAuthSupport(config, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_CFG_SetPostHandshakeAuthSupport(config, support) == HITLS_SUCCESS); + + support = -1; + ASSERT_TRUE(HITLS_CFG_SetPostHandshakeAuthSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetPostHandshakeAuthSupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_CFG_SetPostHandshakeAuthSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetPostHandshakeAuthSupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_CIPHERSUITES_FUNC_TC001 +* @title Test the HITLS_CFG_SetCipherSuites and HITLS_CFG_ClearTLS13CipherSuites interfaces. +* @precon nan +* @brief +* 1. The client invokes the HITLS_CFG_SetCipherSuites interface to set the tls1.3 cipher suite HITLS_AES_128_GCM_SHA256. +* Expected result 1. +* 2. Call HITLS_CFG_ClearTLS13CipherSuites to clear the TLS1.3 algorithm suite. Expected result 2. +* 3. Check whether the value of config->tls13CipherSuites is NULL and whether the value of config->tls13cipherSuitesSize +* is 0. (Expected result 3) +* 4. Establish a connection. Expected result 4. +* @expect +* 1. The setting is successful. +* 2. The interface returns a success message. +* 3. config->tls13CipherSuites, config->tls13cipherSuitesSize = 0 +* 4. TLS1.3 initialization fails, and TLS1.2 connection are established. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_CIPHERSUITES_FUNC_TC001(int tlsVersion) +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint16_t cipherSuites[1] = { + HITLS_AES_128_GCM_SHA256 + }; + + config_c = GetHitlsConfigViaVersion(tlsVersion); + config_s = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(config_c, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)) + == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_ClearTLS13CipherSuites(config_c) == HITLS_SUCCESS); + ASSERT_TRUE(config_c->tls13CipherSuites == NULL); + ASSERT_TRUE(config_c->tls13cipherSuitesSize == 0); + + FRAME_CertInfo certInfo = { + "ecdsa/ca-nist521.der:ecdsa/inter-nist521.der:rsa_sha/ca-3072.der:rsa_sha/inter-3072.der", + NULL, NULL, NULL, NULL, NULL,}; + + client = FRAME_CreateLinkWithCert(config_c, BSL_UIO_TCP, &certInfo); + if (tlsVersion == TLS1_3) { + ASSERT_TRUE(client == NULL); + goto exit; + } + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @ +* @test UT_TLS_CFG_SET_GET_KEYEXCHMODE_FUNC_TC001 +* @title Setting the key exchange mode +* @precon nan +* @brief +* 1. Call HITLS_CFG_SetKeyExchMode to set the key exchange mode to TLS13_KE_MODE_PSK_ONLY. Expected result 1 is +* obtained. +* 2. Invoke the HITLS_CFG_GetKeyExchMode interface. (Expected result 2) +* 3. Call HITLS_CFG_SetKeyExchMode to set the key exchange mode to TLS13_KE_MODE_PSK_WITH_DHE. Expected result 3 is +* obtained. +* 4. Invoke the HITLS_CFG_GetKeyExchMode interface. (Expected result 4) +* @expect +* 1. The setting is successful. +* 2. The returned value is the same as that of TLS13_KE_MODE_PSK_ONLY. +* 3. The setting is successful. +* 4. The return value of the interface is the same as that of TLS13_KE_MODE_PSK_WITH_DHE. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_KEYEXCHMODE_FUNC_TC001() +{ + HITLS_CryptMethodInit(); + FRAME_Init(); + + ResumeTestInfo testInfo = {0}; + testInfo.version = HITLS_VERSION_TLS13; + testInfo.uioType = BSL_UIO_TCP; + testInfo.config = HITLS_CFG_NewTLS13Config(); + + ASSERT_EQ(HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_ONLY), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_GetKeyExchMode(testInfo.config), TLS13_KE_MODE_PSK_ONLY); + ASSERT_EQ(HITLS_CFG_SetKeyExchMode(testInfo.config, TLS13_KE_MODE_PSK_WITH_DHE), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_GetKeyExchMode(testInfo.config), TLS13_KE_MODE_PSK_WITH_DHE); +exit: + HITLS_CFG_FreeConfig(testInfo.config); +} +/* END_CASE */ + + +/** @ +* @test UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetVersionSupport and HITLS_CFG_GetVersionSupport interfaces. +* @precon nan +* @brief HITLS_CFG_SetVersionSupport +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer non-empty configuration information and set version to an invalid value. Expected result 2. +* 3. Transfer non-empty configuration information and set version to a valid value. Expected result 3. +* HITLS_CFG_GetVersionSupport +* 1. Import empty configuration information. Expected result 1. +* 2. Pass the null version pointer. Expected result 1. +* 3. Transfer non-null configuration information and ensure that the version pointer is not null. Expected result 4 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned, and invalid values in config are filtered out. +* 3. HITLS_SUCCES is returned and config is the expected value. +* 4. The HITLS_SUCCES parameter is returned, and the version parameter is set to the value recorded in the config file. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint32_t version = 0; + + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetVersionSupport(config, &version) == HITLS_NULL_INPUT); + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetVersionSupport(config, NULL) == HITLS_NULL_INPUT); + + version = (TLS13_VERSION_BIT << 1) | TLS13_VERSION_BIT | TLS12_VERSION_BIT; + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + version = TLS13_VERSION_BIT | TLS12_VERSION_BIT; + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + uint32_t getversion = 0; + ASSERT_TRUE(HITLS_CFG_GetVersionSupport(config, &getversion) == HITLS_SUCCESS); + ASSERT_TRUE(getversion == config->version); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_ENCRYPTTHENMAC_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetEncryptThenMac and HITLS_CFG_GetEncryptThenMac interfaces. +* @precon nan +* @brief HITLS_CFG_SetEncryptThenMac +* 1. Import empty configuration information. Expected result 1. +* 2. Transfer non-null configuration information and set encryptThenMacType to an invalid value. Expected result 2 is +* obtained. +* 3. Transfer the non-empty configuration information and set encryptThenMacType to a valid value. Expected result 3 is +* obtained. +* HITLS_CFG_GetEncryptThenMac +* 1. Import empty configuration information. Expected result 1. +* 2. Pass the null encryptThenMacType pointer. Expected result 1. +* 3. Transfer non-null configuration information and ensure that the encryptThenMacType pointer is not null. Expected +* result 3. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and config->isEncryptThenMac is true. +* 3. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_ENCRYPTTHENMAC_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint32_t encryptThenMacType = 0; + + ASSERT_TRUE(HITLS_CFG_SetEncryptThenMac(config, encryptThenMacType) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetEncryptThenMac(config, &encryptThenMacType) == HITLS_NULL_INPUT); + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetEncryptThenMac(config, NULL) == HITLS_NULL_INPUT); + encryptThenMacType = 1; + ASSERT_TRUE(HITLS_CFG_SetEncryptThenMac(config, encryptThenMacType) == HITLS_SUCCESS); + encryptThenMacType = 2; + ASSERT_TRUE(HITLS_CFG_SetEncryptThenMac(config, encryptThenMacType) == HITLS_SUCCESS); + ASSERT_TRUE(config->isEncryptThenMac = true); + + uint32_t getencryptThenMacType = -1; + ASSERT_TRUE(HITLS_CFG_GetEncryptThenMac(config, &getencryptThenMacType) == HITLS_SUCCESS); + ASSERT_TRUE(getencryptThenMacType == config->isEncryptThenMac); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_IS_DTLS_API_TC001 +* @title Test the HITLS_CFG_IsDtls interface. +* @precon nan +* @brief +* 1. Transfer empty configuration information. Expected result 1. +* 2. Transfer the null pointer isDtls. Expected result 1. +* 3. Transfer the configuration information and ensure that the isDtls pointer is not null. Expected result 2 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. The HITLS_SUCCESS and isDtls information is returned. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_IS_DTLS_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint8_t isDtls = false; + + ASSERT_TRUE(HITLS_CFG_IsDtls(config, &isDtls) == HITLS_NULL_INPUT); + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_IsDtls(config, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_IsDtls(config, &isDtls) == HITLS_SUCCESS); + ASSERT_TRUE(isDtls == false); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *s_config; + HITLS_Config *c_config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; + HITLS_TicketKeyCb serverKeyCb; +} ResumeTestInfo1; + +HITLS_CRYPT_Key *cert_key = NULL; +HITLS_CRYPT_Key* DH_CB(HITLS_Ctx *ctx, int32_t isExport, uint32_t keyLen) +{ + (void)ctx; + (void)isExport; + (void)keyLen; + return cert_key; +} + +uint64_t RECORDPADDING_CB(HITLS_Ctx *ctx, int32_t type, uint64_t length, void *arg) +{ + (void)ctx; + (void)type; + (void)length; + (void)arg; + return 100; +} +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, uint8_t *text, uint32_t *textLen, uint8_t *recType); +int32_t STUB_RecParseInnerPlaintext(TLS_Ctx *ctx, uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + (void)ctx; + (void)text; + (void)textLen; + *recType = (uint8_t)REC_TYPE_APP; + + return HITLS_SUCCESS; +} + +/** @ +* @test UT_TLS_CFG_GET_RECORDPADDING_API_TC001 +* @title HITLS_CFG_SetRecordPaddingCb Connection +* @precon nan +* @brief 1. If config is empty, expected result 1. + 2. RecordPADDING_CB is empty. Expected result 2. + 3. RecordPADDING_CB is not empty. Expected result 3. +* @expect 1. The interface returns HITLS_NULL_INPUT. + 2. The interface returns HITLS_SUCCESS. + 3. The interface returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_RECORDPADDING_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + // Config is empty + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCb(NULL, RECORDPADDING_CB) == HITLS_NULL_INPUT); + + // RecordPADDING_CB is empty + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCb(config, NULL) == HITLS_SUCCESS); + + // RecordPADDING_CB is not empty + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCb(config, RECORDPADDING_CB) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetRecordPaddingCb(config) == RECORDPADDING_CB); + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCbArg(config, RECORDPADDING_CB) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCbArg(NULL, RECORDPADDING_CB) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCbArg(config, NULL) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_RECORDPADDINGARG_API_TC001 +* @title HITLS_CFG_SetRecordPaddingCbArg Connection +* @precon nan +* @brief 1. If config is empty, expected result 1. + 2. RecordPADDING_CB is empty. Expected result 2. + 3. RecordPADDING_CB is not empty. Expected result 3. +* @expect 1. The interface returns HITLS_NULL_INPUT. + 2. The interface returns HITLS_SUCCESS. + 3. The interface returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_RECORDPADDINGARG_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + // Config is empty + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCb(NULL, RECORDPADDING_CB) == HITLS_NULL_INPUT); + + // RecordPADDING_CB is empty + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCb(config, NULL) == HITLS_SUCCESS); + + // RecordPADDING_CB is not empty + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCb(config, RECORDPADDING_CB) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetRecordPaddingCb(config) == RECORDPADDING_CB); + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCbArg(config, RECORDPADDING_CB) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCbArg(NULL, RECORDPADDING_CB) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetRecordPaddingCbArg(config, NULL) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +int32_t EXAMPLE_TicketKeyCallback( + uint8_t *keyName, uint32_t keyNameSize, HITLS_CipherParameters *cipher, uint8_t isEncrypt) +{ + (void)keyName; + (void)keyNameSize; + (void)cipher; + (void)isEncrypt; + return 100; +} + +/** @ +* @test UT_TLS_CFG_SET_TICKET_CB_API_TC001 +* @title Test HITLS_CFG_SetTicketKeyCallback interface +* @brief 1. If config is empty, expected result 1. + 2. HITLS_CFG_SetTicketKeyCallback is empty. Expected result 2 + 3. HITLS_CFG_SetTicketKeyCallback is not empty. Expected result 2 +* @expect 1. Returns HITLS_NULL_INPUT. + 2. Returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_TICKET_CB_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + // Config is empty + ASSERT_TRUE(HITLS_CFG_SetTicketKeyCallback(NULL, EXAMPLE_TicketKeyCallback) == HITLS_NULL_INPUT); + + // HITLS_TicketKeyCb is empty + ASSERT_TRUE(HITLS_CFG_SetTicketKeyCallback(config, NULL) == HITLS_SUCCESS); + + // HITLS_TicketKeyCb is not empty + ASSERT_TRUE(HITLS_CFG_SetTicketKeyCallback(config, EXAMPLE_TicketKeyCallback) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_NEW_DTLSCONFIG_API_TC001 +* @title Test HITLS_CFG_NewDTLSConfig interface +* @brief 1. Invoke the interface HITLS_CFG_NewTLS12Config, expected result 1. +* @expect 1. Returns not NULL. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_NEW_DTLSCONFIG_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewDTLSConfig(); + ASSERT_TRUE(config != NULL); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +#define DATA_MAX_LEN 1024 +/** @ +* @test UT_TLS_CFG_GET_SET_SESSION_TICKETKEY_API_TC001 +* @title Test HITLS_CFG_SetSessionTicketKey interface +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. If ticketKey is null, invoke HITLS_CFG_SetSessionTicketKey. Expected result 2. +* 3. Invoke HITLS_CFG_SetSessionTicketKey. Expected result 3. +* 4. If outSize is null, invoke HITLS_CFG_SetSessionTicketKey. Expected result 2. +* 5. Invoke HITLS_CFG_SetSessionTicketKey. Expected result 3. +* @expect 1. Memory register succeeded. +* 2. Return HITLS_NULL_INPUT. +* 3. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_SET_SESSION_TICKETKEY_API_TC001(int version) +{ + FRAME_Init(); + + HITLS_Config *config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + uint8_t getKey[DATA_MAX_LEN] = {0}; + uint32_t getKeySize = DATA_MAX_LEN; + uint32_t outSize = 0; + + char *ticketKey = "748ab9f3dc1a23748ab9f3dc1a23748ab9f3dc1a23748ab9f3dc1a23748ab9f3dc1a23748ab9f3d"; + uint32_t ticketKeyLen = HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_SIZE + HITLS_TICKET_KEY_SIZE; + + ASSERT_TRUE(HITLS_CFG_SetSessionTicketKey(config, NULL, ticketKeyLen) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetSessionTicketKey(config, (uint8_t *)ticketKey, ticketKeyLen) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_GetSessionTicketKey(config, getKey, getKeySize, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetSessionTicketKey(config, getKey, getKeySize, &outSize) == HITLS_SUCCESS); + + ASSERT_TRUE(outSize == ticketKeyLen); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_ADD_CAINDICATION_API_TC001 +* @title: Test Add different CA flag indication types. +* @brief +* 1. If data is NULL, Invoke the HITLS_CFG_AddCAIndication.Expected result 1. +* 2. Invoke the HITLS_CFG_AddCAIndication and set the transferred caType to HITLS_TRUSTED_CA_PRE_AGREED.Expected +* result 2. +* 3. Invoke the HITLS_CFG_AddCAIndication and set the transferred caType to HITLS_TRUSTED_CA_KEY_SHA1.Expected +* result 2. +* 4. Invoke the HITLS_CFG_AddCAIndication and set the transferred caType to HITLS_TRUSTED_CA_X509_NAME.Expected +* result 2. +* 5. Invoke the HITLS_CFG_AddCAIndication and set the transferred caType to HITLS_TRUSTED_CA_CERT_SHA1.Expected +* result 2. +* 6. Invoke the HITLS_CFG_AddCAIndication and set the transferred caType to HITLS_TRUSTED_CA_UNKNOWN.Expected +* result 2. +* @expect +* 1. Return HITLS_NULL_INPUT. +* 2. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_ADD_CAINDICATION_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint8_t data[] = {0}; + uint32_t len = sizeof(data); + + config = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_PRE_AGREED, NULL, len) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_PRE_AGREED, data, len) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_KEY_SHA1, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_X509_NAME, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_CERT_SHA1, data, len) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_UNKNOWN, data, len) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_CALIST_API_TC001 +* @title Test HITLS_CFG_GetCAList interface +* @brief +* 1.Register the memory for config structure. Expected result 1. +* 1.Invoke the interface HITLS_CFG_GetCAList, expected result 2. +* @expect 1. Returns not NULL. +* 2. Returns NULL. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_CALIST_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + ASSERT_TRUE(HITLS_CFG_GetCAList(config) == NULL); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_GET_VERSION_API_TC001 +* @title Test HITLS_CFG_GetMinVersion/HITLS_CFG_GetMaxVersion/HITLS_SetVersion interface +* @brief +* 1.If minVersion is NULL, Invoke the HITLS_CFG_GetMinVersion.Expected result 1. +* 2.If maxVersion is NULL, Invoke the HITLS_CFG_GetMinVersion.Expected result 1. +* 3.Invoke HITLS_CFG_SetVersion.Expected result 2. +* 4.Invoke HITLS_CFG_GetMinVersion.Expected result 2. +* 5.Invoke HITLS_CFG_GetMaxVersion.Expected result 2. +* 6. Check minVersion is HITLS_VERSION_TLS12 and maxVersion is HITLS_VERSION_TLS13 +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCES +* 3. Return HITLS_SUCCES,minVersion is HITLS_VERSION_TLS12 and maxVersion is HITLS_VERSION_TLS13 +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_VERSION_API_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLSConfig(); + uint16_t minVersion = 0; + uint16_t maxVersion = 0; + + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_SetVersion(config, HITLS_VERSION_TLS12, HITLS_VERSION_TLS13) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, &minVersion) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, &maxVersion) == HITLS_SUCCESS); + ASSERT_TRUE(minVersion == HITLS_VERSION_TLS12 && maxVersion == HITLS_VERSION_TLS13); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + + +/** @ +* @test UT_TLS_CFG_GET_SESSION_CACHEMODE_API_TC001 +* @title Test ITLS_CFG_GetSessionCacheMoe interface +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. Invoke HITLS_CFG_GetSessionCacheMode. Expected result 2. +* @expect 1. Memory register succeeded. +* 2. Return success and value is 0. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_SESSION_CACHEMODE_API_TC001(void) +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + HITLS_SESS_CACHE_MODE getCacheMode = 0; + ASSERT_EQ(HITLS_CFG_GetSessionCacheMode(config, &getCacheMode), 0); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SET_GET_SESSIONCACHESIZE_API_TC001 +* @title Test HITLS_CFG_SetSessionCacheSize/HITLS_CFG_GetSessionCacheSize interface +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. Invoke HITLS_CFG_SetSessionCacheSize. Expected result 2. +* 3. Invoke HITLS_CFG_GetSessionCacheSize. Expected result 2. +* 4. Check getCacheSize and cacheSize is equal +* @expect 1. Memory register succeeded. +* 2. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_SESSIONCACHESIZE_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + uint32_t cacheSize = 10; + uint32_t getCacheSize = 0; + ASSERT_TRUE(HITLS_CFG_SetSessionCacheSize(config, cacheSize) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetSessionCacheSize(config, &getCacheSize) == HITLS_SUCCESS); + ASSERT_TRUE(getCacheSize == cacheSize); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SET_GET_SESSION_TIMEOUT_API_TC001 +* @title Test HITLS_CFG_GetSessionTimeout interface +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. Invoke HITLS_CFG_SetSessionTimeout. Expected result 2. +* 3. Invoke HITLS_CFG_GetSessionTimeout. Expected result 2. +* 4. Check timeOut and getTimeOut is equal +* @expect 1. Memory register succeeded. +* 2. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_SESSION_TIMEOUT_API_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + uint64_t timeOut = 10; + uint64_t getTimeOut = 0; + ASSERT_TRUE(HITLS_CFG_SetSessionTimeout(config, timeOut) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetSessionTimeout(config, &getTimeOut) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_VERSIONFORBID_API_TC001 +* @title Test HITLS_SetVersionForbid interface +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. If context is NULL, invoke HITLS_SetVersionForbid. Expected result 3. +* 3. If context is NULL, invoke HITLS_SetVersionForbid. Expected result 2. +* @expect 1. Memory register succeeded. +* 2. Return HITLS_SUCCESS. +* 3. Return HITLS_NULL_INPUT +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_VERSIONFORBID_API_TC001(void) +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetVersionForbid(NULL, HITLS_VERSION_TLS12) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetVersionForbid(ctx, HITLS_VERSION_TLS12) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_CONFIGUSEDATA_API_TC001 +* @title Test HITLS_CFG_SetConfigUserData/HITLS_CFG_GetConfigUserData interfaces +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. If config is NULL, invoke HITLS_CFG_SetConfigUserData. Expected result 2. +* 3. Invoke HITLS_CFG_SetConfigUserData. Expected result 3. +* 3. Invoke HITLS_CFG_SetConfigUserData. Expected result 4. +* @expect 1. Memory register succeeded. +* 2. Return HITLS_NULL_INPUT. +* 3. Return HITLS_SUCCESS. +* 4. Return not NULL. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_CONFIGUSEDATA_API_TC001(int version) +{ + FRAME_Init(); + + HITLS_Config *config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + char *userData = "123456"; + ASSERT_TRUE(HITLS_CFG_SetConfigUserData(NULL, userData) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetConfigUserData(config, userData) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetConfigUserData(config) != NULL); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + + +void EXAMPLE_HITLS_ConfigUserDataFreeCb( + void* data) +{ + (void)data; + return; +} + +/** @ +* @test UT_TLS_CFG_SET_CONFIG_USERDATA_FREECB_API_TC001 +* @title Test HITLS_CFG_SetConfigUserDataFreeCb interfaces +* @brief 1. Register the memory for config structure. Expected result 1. +* 2. If config is NULL, invoke HITLS_CFG_SetConfigUserDataFreeCb. Expected result 2. +* 3. Invoke HITLS_CFG_SetConfigUserDataFreeCb. Expected result 3. +* @expect 1. Memory register succeeded. +* 2. Return HITLS_NULL_INPUT. +* 3. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_CONFIG_USERDATA_FREECB_API_TC001(int version) +{ + FRAME_Init(); + + HITLS_Config *config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + ASSERT_TRUE(HITLS_CFG_SetConfigUserDataFreeCb(NULL, EXAMPLE_HITLS_ConfigUserDataFreeCb) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetConfigUserDataFreeCb(config, EXAMPLE_HITLS_ConfigUserDataFreeCb) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_CERTIFICATE_API_TC001 +* @title Test HITLS_CFG_SetCertificate interface +* @brief 1. Invoke the HITLS_CFG_SetCertificate interface, set tlsConfig to null, and set cert for the device +* certificate. (Expected result 1) +* 2. Invoke the HITLS_CFG_SetCertificate interface. Set tlsConfig and cert to an empty value for the device +* certificate.(Expected result 1) +* 3. Invoke the HITLS_CFG_SetCertificate interface. Ensure that tlsConfig and cert are not empty. Perform deep +* copy. (Expected result 3) +* 4. Invoke the HITLS_CFG_GetCertificate interface. The value of tlsConfig->certMgrCtx->currentCertIndex is +* greater than the value of TLS_CERT_KEY_TYPE_NUM, Expected result 4 is obtained. +* 5. Invoke the HITLS_CFG_GetCertificate interface and leave tlsConfig empty. Expected result 4 is obtained. +* 6. Invoke the HITLS_CFG_SetCertificate interface, set tlsConfig->certMgrCtx to null, and set cert to a non-empty +* device certificate. (Expected result 2) +* 7. Invoke HITLS_CFG_GetCertificate +* Run the tlsConfig command to set certMgrCtx to null. Expected result 4 is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Return HITLS_CERT_ERR_X509_DUP +* 3. HITLS_SUCCESS is returned. +* 4. NULL is returned. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_CERTIFICATE_API_TC001(int version, char *certFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_CERT_X509 *cert = HiTLS_X509_LoadCertFile(certFile); + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_TRUE(HITLS_CFG_SetCertificate(NULL, cert, false) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetCertificate(tlsConfig, NULL, true) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_CFG_SetCertificate(tlsConfig, cert, true), HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_GetCertificate(tlsConfig) != NULL); + tlsConfig->certMgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_NUM + 1; + ASSERT_TRUE(HITLS_CFG_GetCertificate(tlsConfig) == NULL); + ASSERT_TRUE(HITLS_CFG_GetCertificate(NULL) == NULL); + SAL_CERT_MgrCtxFree(tlsConfig->certMgrCtx); + tlsConfig->certMgrCtx = NULL; + ASSERT_EQ(HITLS_CFG_SetCertificate(tlsConfig, cert, true), HITLS_UNREGISTERED_CALLBACK); + ASSERT_TRUE(HITLS_CFG_GetCertificate(tlsConfig) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + SAL_CERT_X509Free(cert); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_CHECK_PRIVATEKEY_API_TC001 +* @title Test HITLS_CFG_CheckPrivateKey interface +* @brief 1. Invoke the HITLS_CFG_CheckPrivateKey interface and leave tlsConfig blank. Expected result 1 +* 2. Invoke the HITLS_CFG_CheckPrivateKey interface. The tlsConfig parameter is not empty, +* The value of tlsConfig->certMgrCtx->currentCertIndex is greater than or equal to the maximum value +* TLS_CERT_KEY_TYPE_NUM. Expected result 2 +* 3. Invoke the HITLS_CFG_CheckPrivateKey interface and leave tlsConfig->certMgrCtx empty. Expected result 3 +* @expect 1. Returns HITLS_NULL_INPUT +* 2. HITLS_CONFIG_NO_CERT is returned. +* 3. The HITLS_UNREGISTERED_CALLBACK message is returned. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_CHECK_PRIVATEKEY_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_TRUE(HITLS_CFG_CheckPrivateKey(NULL) == HITLS_NULL_INPUT); + tlsConfig->certMgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_NUM; + ASSERT_TRUE(HITLS_CFG_CheckPrivateKey(tlsConfig) == HITLS_CONFIG_NO_CERT); + SAL_CERT_MgrCtxFree(tlsConfig->certMgrCtx); + tlsConfig->certMgrCtx = NULL; + ASSERT_TRUE(HITLS_CFG_CheckPrivateKey(tlsConfig) == HITLS_UNREGISTERED_CALLBACK); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_ADD_CHAINCERT_API_TC001 +* @title Test HITLS_CFG_GetChainCerts interface +* @brief 1. Invoke the HITLS_CFG_AddChainCert interface, set tlsConfig to null, and set addCert to a certificate to be +* added. Perform shallow copy. Expected result 1 . +*        2. Invoke the HITLS_CFG_AddChainCert interface. The tlsConfig parameter is not empty and the addCert parameter +* is empty.Perform deep copy. Expected result 1 . +*        3. Invoke the HITLS_CFG_AddChainCert interface. Ensure that tlsConfig is not empty and addCert is not empty. +* Perform shallow copy. Expected result 2 . +* 4. Invoke the HITLS_CFG_AddChainCert interface. The value of tlsConfig is not empty and the value of +* tlsConfig->certMgrCtx->currentCertIndex is greater than or equal to the maximum value TLS_CERT_KEY_TYPE_NUM. +* Expected result 4 . +* 5. Invoke the HITLS_CFG_GetChainCerts interface. Set tlsConfig to a value greater than or equal to the maximum +* value TLS_CERT_KEY_TYPE_NUM. (Expected result 3) +* 6. Invoke the HITLS_CFG_GetChainCerts interface and leave tlsConfig blank. Expected result 3 . +* 7. Invoke the HITLS_CFG_LoadKeyBuffer interface. Set tlsConfig->certMgrCtx to null and addCert to the +* certificate to be added. Perform deep copy. Expected result 5 . +* 8. Invoke the HITLS_CFG_GetChainCerts interface and leave tlsConfig->certMgrCtx empty. Expected result 3. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCESS is returned. +* 3. NULL is returned. +* 4. Return ITLS_CERT_ERR_ADD_CHAIN_CERT +* 5. Return HITLS_CERT_ERR_X509_DUP +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_ADD_CHAINCERT_API_TC001(int version, char *certFile, char *addCertFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_CERT_X509 *cert = HiTLS_X509_LoadCertFile(certFile); + HITLS_CERT_X509 *addCert = HiTLS_X509_LoadCertFile(addCertFile); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_TRUE(HITLS_CFG_SetCertificate(tlsConfig, cert, false) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_AddChainCert(NULL, addCert, false) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_AddChainCert(tlsConfig, NULL, true) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_CFG_AddChainCert(tlsConfig, addCert, false), HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_GetChainCerts(tlsConfig) != NULL); + tlsConfig->certMgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_NUM; + ASSERT_EQ(HITLS_CFG_AddChainCert(tlsConfig, cert, true), HITLS_CERT_ERR_ADD_CHAIN_CERT); + ASSERT_TRUE(HITLS_CFG_GetChainCerts(tlsConfig) == NULL); + ASSERT_TRUE(HITLS_CFG_GetChainCerts(NULL) == NULL); + SAL_CERT_MgrCtxFree(tlsConfig->certMgrCtx); + tlsConfig->certMgrCtx = NULL; + ASSERT_EQ(HITLS_CFG_AddChainCert(tlsConfig, cert, true), HITLS_UNREGISTERED_CALLBACK); + ASSERT_TRUE(HITLS_CFG_GetChainCerts(tlsConfig) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + + +/** @ +* @test UT_HITLS_CFG_REMOVE_CERTANDKEY_API_TC001 +* @title Test HITLS_CFG_RemoveCertAndKey interface +* @brief +* 1. Register the memory for config structure. Expected result 1. +* 2. Invoke HITLS_CFG_RemoveCertAndKey interface, expected result 3. +* 3. Invoke HITLS_CFG_SetCertificate interface, expected result 3. +* 4. Invoke HITLS_CFG_LoadKeyFile interface, expected result 3. +* 5. Invoke HITLS_CFG_GetCertificate interface, expected result 2. +* 6. Invoke HITLS_CFG_GetPrivateKey interface, expected result 2. +* 7. Invoke HITLS_CFG_CheckPrivateKey interface, expected result 3. +* 8. Invoke HITLS_CFG_RemoveCertAndKey interface, expected result 3. +* 9. Invoke HITLS_CFG_GetCertificate interface, expected result 4. +* 10. Invoke HITLS_CFG_GetPrivateKey interface, expected result 4. +* @expect 1. Create successful. +* 2. Return not NULL +* 3. Return HITLS_SUCCESS +* 4.Return NULL +@ */ +/* BEGIN_CASE */ +void UT_HITLS_CFG_REMOVE_CERTANDKEY_API_TC001(int version, char *certFile, char *keyFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_CERT_X509 *cert = HiTLS_X509_LoadCertFile(certFile); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ASSERT_EQ(HITLS_CFG_RemoveCertAndKey(tlsConfig), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_CFG_SetCertificate(tlsConfig, cert, true), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_LoadKeyFile(tlsConfig, keyFile, TLS_PARSE_FORMAT_ASN1), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetCertificate(tlsConfig) != NULL); + ASSERT_TRUE(HITLS_CFG_GetPrivateKey(tlsConfig) != NULL); + ASSERT_EQ(HITLS_CFG_CheckPrivateKey(tlsConfig), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_RemoveCertAndKey(tlsConfig), HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_GetCertificate(tlsConfig) == NULL); + ASSERT_TRUE(HITLS_CFG_GetPrivateKey(tlsConfig) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + SAL_CERT_X509Free(cert); +} +/* END_CASE */ + +void StubListDataDestroy(void *data) +{ + BSL_SAL_FREE(data); + return; +} + +/** @ +* @test UT_HITLS_CFG_ADD_EXTRA_CHAINCERT_API_TC001 +* @title Test HITLS_CFG_AddExtraChainCert interface +* @brief +* 1. Create a config object. Expected result 1 . +* 2. If the input value of config is null, invoke HITLS_CFG_GetExtraChainCerts to obtain the configured additional +* certificate chain. Expected result 2 . +* 3. Call the interface to add a certificate to the additional certificate chain and call HITLS_CFG_GetExtraChainCerts +* to obtain the configured additional certificate chain. Expected result 3 . +* 4. Call the API again to add certificate 2 to the additional certificate chain and call HITLS_CFG_GetExtraChainCerts +* to obtain the configured additional certificate chain. Expected result 4 . +5. Invoke HITLS_CFG_ClearChainCerts to clear the attached certificate chain. Expected result 5 . +* @expect +* 1. The config object is created successfully. +* 2. Failed to set the additional certificate chain. The obtained additional certificate chain is empty. +* 3. The additional certificate chain is successfully set and obtained. +* 4. The additional certificate chain is successfully set and obtained. +* 5. The STORE for obtaining the attached certificate chain does not change. +@ */ +/* BEGIN_CASE */ +void UT_HITLS_CFG_ADD_EXTRA_CHAINCERT_API_TC001(int version, char *certFile1, char *certFile2) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_CERT_X509 *cert1 = HiTLS_X509_LoadCertFile(certFile1); + HITLS_CERT_X509 *cert2 = HiTLS_X509_LoadCertFile(certFile2); + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_TRUE(HITLS_CFG_AddExtraChainCert(NULL, cert1) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_AddExtraChainCert(tlsConfig, cert1) == HITLS_SUCCESS); + HITLS_CERT_Chain *extraChainCert = HITLS_CFG_GetExtraChainCerts(tlsConfig); + ASSERT_TRUE(extraChainCert->count == 1); + ASSERT_TRUE(HITLS_CFG_GetExtraChainCerts(tlsConfig) != NULL); + + ASSERT_TRUE(HITLS_CFG_AddExtraChainCert(tlsConfig, cert2) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetExtraChainCerts(tlsConfig) != NULL); + ASSERT_TRUE(HITLS_CFG_ClearChainCerts(tlsConfig) == HITLS_SUCCESS); + HITLS_CERT_Chain *extraChainCert1 = HITLS_CFG_GetExtraChainCerts(tlsConfig); + ASSERT_TRUE(extraChainCert1->count == 2); + ASSERT_TRUE(HITLS_CFG_GetExtraChainCerts(tlsConfig) != NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SET_DTLS_MTU_API_TC001 +* @title Test HITLS_SetMtu interface +* @brief 1. Create the TLS configuration object config.Expect result 1. +* 2. Use config to create the client and server.Expect result 2. +* 3. Invoke HITLS_SetMtu, Expect result 3. +* @expect 1. The config object is successfully created. +* 2. The client and server are successfully created. +* 3. Return HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_DTLS_MTU_API_TC001(void) +{ + FRAME_Init(); + uint32_t mtu = 1500; + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(HITLS_SetMtu(client->ssl, mtu) == HITLS_SUCCESS); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(HITLS_SetMtu(server->ssl, mtu) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_config_1.data b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_config_1.data new file mode 100644 index 00000000..adfb44e4 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface/test_suite_sdv_frame_tls_config_1.data @@ -0,0 +1,130 @@ +UT_TLS_CFG_SET_VERSION_API_TC001 +UT_TLS_CFG_SET_VERSION_API_TC001: + +UT_TLS_CFG_SET_GET_VERSIONFORBID_API_TC001 +UT_TLS_CFG_SET_GET_VERSIONFORBID_API_TC001: + +UT_TLS_CFG_SET_GET_EXTENEDMASTERSECRETSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_EXTENEDMASTERSECRETSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_EXTENEDMASTERSECRETSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_EXTENEDMASTERSECRETSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_POSTHANDSHAKEAUTHSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_POSTHANDSHAKEAUTHSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_POSTHANDSHAKEAUTHSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_POSTHANDSHAKEAUTHSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_CIPHERSUITES_FUNC_TC001 +UT_TLS_CFG_SET_CIPHERSUITES_FUNC_TC001:TLS1_2 + +UT_TLS_CFG_SET_CIPHERSUITES_FUNC_TC001 +UT_TLS_CFG_SET_CIPHERSUITES_FUNC_TC001:TLS1_3 + +UT_TLS_CFG_SET_GET_KEYEXCHMODE_FUNC_TC001 +UT_TLS_CFG_SET_GET_KEYEXCHMODE_FUNC_TC001: + +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_ENCRYPTTHENMAC_API_TC001 +UT_TLS_CFG_SET_GET_ENCRYPTTHENMAC_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_ENCRYPTTHENMAC_API_TC001_0 +UT_TLS_CFG_SET_GET_ENCRYPTTHENMAC_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_IS_DTLS_API_TC001: +UT_TLS_CFG_IS_DTLS_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_IS_DTLS_API_TC001_0 +UT_TLS_CFG_IS_DTLS_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_GET_RECORDPADDING_API_TC001 +UT_TLS_CFG_GET_RECORDPADDING_API_TC001: + +UT_TLS_CFG_SET_RECORDPADDINGARG_API_TC001 +UT_TLS_CFG_SET_RECORDPADDINGARG_API_TC001: + +UT_TLS_CFG_SET_TICKET_CB_API_TC001 +UT_TLS_CFG_SET_TICKET_CB_API_TC001: + +UT_TLS_CFG_NEW_DTLSCONFIG_API_TC001 +UT_TLS_CFG_NEW_DTLSCONFIG_API_TC001: + +UT_TLS_CFG_GET_SET_SESSION_TICKETKEY_API_TC001 +UT_TLS_CFG_GET_SET_SESSION_TICKETKEY_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_GET_SET_SESSION_TICKETKEY_API_TC001 +UT_TLS_CFG_GET_SET_SESSION_TICKETKEY_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_ADD_CAINDICATION_API_TC001 +UT_TLS_CFG_ADD_CAINDICATION_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_ADD_CAINDICATION_API_TC001 +UT_TLS_CFG_ADD_CAINDICATION_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_GET_CALIST_API_TC001 +UT_TLS_CFG_GET_CALIST_API_TC001: + +UT_TLS_CFG_GET_VERSION_API_TC001 +UT_TLS_CFG_GET_VERSION_API_TC001: + +UT_TLS_CFG_GET_SESSION_CACHEMODE_API_TC001 +UT_TLS_CFG_GET_SESSION_CACHEMODE_API_TC001: + +UT_TLS_CFG_SET_GET_SESSIONCACHESIZE_API_TC001 +UT_TLS_CFG_SET_GET_SESSIONCACHESIZE_API_TC001: + +UT_TLS_CFG_SET_GET_SESSION_TIMEOUT_API_TC001 +UT_TLS_CFG_SET_GET_SESSION_TIMEOUT_API_TC001: + +UT_TLS_CFG_SET_VERSIONFORBID_API_TC001 +UT_TLS_CFG_SET_VERSIONFORBID_API_TC001: + +UT_TLS_CFG_SET_GET_CONFIGUSEDATA_API_TC001 +UT_TLS_CFG_SET_GET_CONFIGUSEDATA_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_CONFIGUSEDATA_API_TC001 +UT_TLS_CFG_SET_GET_CONFIGUSEDATA_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_CONFIG_USERDATA_FREECB_API_TC001 +UT_TLS_CFG_SET_CONFIG_USERDATA_FREECB_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_CONFIG_USERDATA_FREECB_API_TC001 +UT_TLS_CFG_SET_CONFIG_USERDATA_FREECB_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_CERTIFICATE_API_TC001 +UT_TLS_CFG_SET_GET_CERTIFICATE_API_TC001:TLS1_2:"../testdata/tls/certificate/der/ecdsa_sha256/inter.der" +UT_TLS_CFG_SET_GET_CERTIFICATE_API_TC001 +UT_TLS_CFG_SET_GET_CERTIFICATE_API_TC001:TLS1_3:"../testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CFG_CHECK_PRIVATEKEY_API_TC001 +UT_TLS_CFG_CHECK_PRIVATEKEY_API_TC001:TLS1_2 + +UT_TLS_CFG_CHECK_PRIVATEKEY_API_TC001 +UT_TLS_CFG_CHECK_PRIVATEKEY_API_TC001:TLS1_3 + +UT_TLS_CFG_ADD_CHAINCERT_API_TC001 +UT_TLS_CFG_ADD_CHAINCERT_API_TC001:TLS1_2:"../testdata/tls/certificate/der/ecdsa_sha256/server.der":"../testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CFG_ADD_CHAINCERT_API_TC001 +UT_TLS_CFG_ADD_CHAINCERT_API_TC001:TLS1_3:"../testdata/tls/certificate/der/ecdsa_sha256/server.der":"../testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_HITLS_CFG_REMOVE_CERTANDKEY_API_TC001 +UT_HITLS_CFG_REMOVE_CERTANDKEY_API_TC001:TLS1_2:"../testdata/tls/certificate/der/rsa_sha256/client.der":"../testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_HITLS_CFG_REMOVE_CERTANDKEY_API_TC001 +UT_HITLS_CFG_REMOVE_CERTANDKEY_API_TC001:TLS1_3:"../testdata/tls/certificate/der/rsa_sha256/client.der":"../testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_HITLS_CFG_ADD_EXTRA_CHAINCERT_API_TC001 +UT_HITLS_CFG_ADD_EXTRA_CHAINCERT_API_TC001:TLS1_2:"../testdata/tls/certificate/der/ecdsa_sha1/ca-nist521.der":"../testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_HITLS_CFG_ADD_EXTRA_CHAINCERT_API_TC001 +UT_HITLS_CFG_ADD_EXTRA_CHAINCERT_API_TC001:TLS1_3:"../testdata/tls/certificate/der/ecdsa_sha1/ca-nist521.der":"../testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CFG_SET_DTLS_MTU_API_TC001 +UT_TLS_CFG_SET_DTLS_MTU_API_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface/test_suite_sdv_hlt_tls_cm_1.c b/testcode/sdv/testcase/tls/interface/test_suite_sdv_hlt_tls_cm_1.c new file mode 100644 index 00000000..38733bb8 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface/test_suite_sdv_hlt_tls_cm_1.c @@ -0,0 +1,145 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "securec.h" +#include "hlt.h" +#include "hitls_error.h" +#include "hitls_func.h" +#include "conn_init.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "alert.h" +#include "stub_replace.h" +#include "hs_common.h" +#include "change_cipher_spec.h" +#include "hs.h" +#include "simulate_io.h" +#include "rec_header.h" +#include "rec_wrapper.h" +#include "recv_client_hello.c" +#include "record.h" + +#define READ_BUF_SIZE 18432 +#define MAX_DIGEST_SIZE 64UL /* The longest known is SHA512 */ +uint32_t g_uiPort = 8890; + +/* END_HEADER */ + +static HITLS_Config *GetHitlsConfigViaVersion(int ver) +{ + HITLS_Config *config; + int32_t ret; + switch (ver) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return config; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return config; + case HITLS_VERSION_DTLS12: + config = HITLS_CFG_NewDTLS12Config(); + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return config; + default: + return NULL; + } +} + +int32_t STUB_BSL_UIO_Write(BSL_UIO *uio, const void *data, uint32_t len, uint32_t *writeLen) +{ + (void)uio; + (void)data; + (void)len; + (void)writeLen; + return BSL_INTERNAL_EXCEPTION; +} + +/** @ +* @test SDV_TLS_CM_KEYUPDATE_FUNC_TC001 +* @title HITLS_TLS_Interface_SDV_23_0_5_102 +* @precon nan +* @brief +* 1. Set the version number to tls1.3. After the connection is established, invoke the HITLS_GetKeyUpdateType interface. +* Expected result 1 is obtained. +* 2. Set the version number to tls1.3. After the connection is created, call hitls_keyupdate successfully, and then call the +* HITLS_GetKeyUpdateType interface. Expected result 2 is obtained. +* 3. Set the version number to tls1.3. After the connection is created, call the hitls_keyupdate interface to construct an +* I/O exception. If the interface fails to be called, call the HITLS_GetKeyUpdateType interface again. Expected +* result 3 is obtained. +* @expect +* 1. The return value is 255. +* 2. The return value is 255. +* 3. The return value is the configured keyupdate type. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CM_KEYUPDATE_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + config->isSupportRenegotiation = true; + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetKeyUpdateType(client->ssl); + ASSERT_EQ(ret, HITLS_KEY_UPDATE_REQ_END); + ret = HITLS_KeyUpdate(client->ssl, HITLS_UPDATE_NOT_REQUESTED); + ASSERT_EQ(ret, HITLS_SUCCESS); + ret = HITLS_GetKeyUpdateType(client->ssl); + ASSERT_EQ(ret, HITLS_KEY_UPDATE_REQ_END); + + FuncStubInfo tmpRpInfo = {0}; + STUB_Replace(&tmpRpInfo, BSL_UIO_Write, STUB_BSL_UIO_Write); + ret = HITLS_KeyUpdate(client->ssl, HITLS_UPDATE_REQUESTED); + ASSERT_EQ(ret, HITLS_REC_ERR_IO_EXCEPTION); + ret = HITLS_GetKeyUpdateType(client->ssl); + ASSERT_EQ(ret, HITLS_UPDATE_REQUESTED); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); + STUB_Reset(&tmpRpInfo); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/interface/test_suite_sdv_hlt_tls_cm_1.data b/testcode/sdv/testcase/tls/interface/test_suite_sdv_hlt_tls_cm_1.data new file mode 100644 index 00000000..d7973a0a --- /dev/null +++ b/testcode/sdv/testcase/tls/interface/test_suite_sdv_hlt_tls_cm_1.data @@ -0,0 +1,3 @@ +SDV_TLS_CM_KEYUPDATE_FUNC_TC001 HITLS_VERSION_TLS13 +SDV_TLS_CM_KEYUPDATE_FUNC_TC001:HITLS_VERSION_TLS13 + diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_interface.base.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_interface.base.c new file mode 100644 index 00000000..b604c618 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_interface.base.c @@ -0,0 +1,152 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_state_recv.h" +#include "conn_init.h" +#include "app.h" +#include "record.h" +#include "rec_conn.h" +#include "session.h" +#include "recv_process.h" +#include "stub_replace.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "simulate_io.h" +#include "parser_frame_msg.h" +#include "pack_frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "cert.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "hlt.h" +#include "sctp_channel.h" +#include "logger.h" + +#define READ_BUF_SIZE (18 * 1024) /* Maximum length of the read message buffer */ + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isServerExtendMasterSecret; + bool isSupportRenegotiation; /* Renegotiation support flag */ + bool needStopBeforeRecvCCS; /* CCS test, so that the TRY_RECV_FINISH stops before the CCS message is received */ +} HandshakeTestInfo; + + +int32_t SendHelloReq(HITLS_Ctx *ctx) +{ + int32_t ret; + /** Initialize the message buffer. */ + uint8_t buf[HS_MSG_HEADER_SIZE] = {0u}; + size_t len = HS_MSG_HEADER_SIZE; + + /** Write records. */ + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} + +#define TEST_CLIENT_SEND_FAIL 1 + +void TestSetCertPath(HLT_Ctx_Config *ctxConfig, char *SignatureType) +{ + if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA1", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA1")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA256")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA256_EE_PATH3, RSA_SHA256_PRIV_PATH3, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA384")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA384_EE_PATH, RSA_SHA384_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA512")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA512_EE_PATH, RSA_SHA512_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + strlen("CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA256_EE_PATH, + ECDSA_SHA256_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384", + strlen("CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA384_EE_PATH, + ECDSA_SHA384_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512", + strlen("CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA512_EE_PATH, + ECDSA_SHA512_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_ECDSA_SHA1", strlen("CERT_SIG_SCHEME_ECDSA_SHA1")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA1_CA_PATH, + ECDSA_SHA1_CHAIN_PATH, + ECDSA_SHA1_EE_PATH, + ECDSA_SHA1_PRIV_PATH, + "NULL", + "NULL"); + } +} diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface.c new file mode 100644 index 00000000..6f459e87 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface.c @@ -0,0 +1,790 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_interface */ + +#include +#include "hitls_error.h" +#include "hitls_cert.h" +#include "hitls.h" +#include "hitls_func.h" +#include "securec.h" +#include "cert_method.h" +#include "cert_mgr.h" +#include "cert_mgr_ctx.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "session.h" +#include "bsl_list.h" +#include "bsl_sal.h" +#include "bsl_uio.h" +#include "alert.h" +#include "stub_replace.h" +#include "cert_callback.h" +#include "crypt_eal_rand.h" +#include "hitls_crypt_reg.h" +#include "hitls_crypt_init.h" +#include "uio_base.h" +/* END_HEADER */ + +#define BUF_MAX_SIZE 4096 +int32_t g_uiPort = 18886; +static int TestHITLS_VerifyCb(int32_t isPreverifyOk, HITLS_CERT_StoreCtx *storeCtx) +{ + (void)isPreverifyOk; + (void)storeCtx; + return 0; +} + +static int32_t TestPasswordCb(char *buf, int32_t bufLen, int32_t flag, void *userdata) +{ + (void)flag; + char *passwd = NULL; + static char pass[] = "123456"; + if (userdata != NULL) { + passwd = userdata; + } else { + passwd = pass; + } + int32_t len = strlen(passwd); + if (len > bufLen) { + return -1; + } + + memcpy(buf, passwd, len); + return len; +} + +static uint32_t ReadFileBuffer(const char *filePath, char *data) +{ + FILE *fd; + uint32_t size; + uint32_t bytes; + + fd = fopen(filePath, "rb"); + if (fd == NULL) { + return 0; + } + + (void)fseek(fd, 0, SEEK_END); + size = (uint32_t)ftell(fd); + rewind(fd); + + bytes = (uint32_t)fread(data, 1, size, fd); + (void)fclose(fd); + if (bytes != size) { + return 0; + } + + return bytes; +} + +/* @ +* @test UT_TLS_CERT_CM_SetVerifyDepth_API_TC001 +* @title The input parameter of the HITLS_SetVerifyDepth interface is replaced. +* @precon This test case covers the HITLS_SetVerifyDepth, HITLS_GetVerifyDepth +* @brief 1.Invoke the HITLS_SetVerifyDepth interface. The value of ctx is empty and the value of depth is not empty. +* Expected result 1 is obtained. +*         2.Invoke the HITLS_SetVerifyDepth interface. The values of ctx and depth are not empty. +* Expected result 2 is obtained. +*         3.Invoke the HITLS_GetVerifyDepth interface. The ctx field is empty and the depth address is not empty. +* Expected result 1 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +*          2.Returns HITLS_SUCCESS +* 3.Returns HITLS_NULL_INPUT +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetVerifyDepth_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + uint32_t depth = 5; + uint32_t dep = 0; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetVerifyDepth(NULL, depth) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetVerifyDepth(ctx, depth), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetVerifyDepth(ctx, &dep) == HITLS_SUCCESS); + ASSERT_EQ(depth, dep); + ASSERT_TRUE(HITLS_GetVerifyDepth(NULL, &dep) == HITLS_NULL_INPUT); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CFG_SetDefaultPasswordCb_FUNC_001 +* @title Set the password callback and set the user data defaultPasswdCbUserdata. +* @precon This test case covers the HITLS_CFG_SetDefaultPasswordCb, HITLS_CFG_GetDefaultPasswordCb, +* HITLS_CFG_SetDefaultPasswordCbUserdata, HITLS_CFG_GetDefaultPasswordCbUserdata +* @brief 1. Create a CTX object. Expected result 1 is obtained. +* 2. Set the password callback and set the incorrect user data defaultPasswdCbUserdata. +* Expected result 2 is obtained. +* @expect  1. Created successfully. +* 2. Failed to load the encrypted private key file. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CFG_SetDefaultPasswordCb_FUNC_001(int version, char *keyFile, char *userdata) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ASSERT_TRUE(HITLS_CFG_SetDefaultPasswordCb(tlsConfig, TestPasswordCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetDefaultPasswordCb(tlsConfig) == TestPasswordCb); + ASSERT_TRUE(HITLS_CFG_SetDefaultPasswordCbUserdata(tlsConfig, userdata)== HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetDefaultPasswordCbUserdata(tlsConfig) == userdata); + + ASSERT_EQ(HITLS_CFG_LoadKeyFile(tlsConfig, keyFile, TLS_PARSE_FORMAT_ASN1), HITLS_CONFIG_ERR_LOAD_KEY_FILE); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001 +* @title The input parameter of the HITLS_SetDefaultPasswordCbUserdata interface is replaced. +* @precon This test case covers the HITLS_SetDefaultPasswordCbUserdata, HITLS_GetDefaultPasswordCbUserdata +* @brief 1.Invoke the HITLS_SetDefaultPasswordCbUserdata interface. The value of ctx is empty and the value of +* userdata is not empty. Expected result 1 is obtained. +*         2.Invoke the HITLS_SetDefaultPasswordCbUserdata interface. The values of ctx and userdata are not empty. +* Expected result 2 is obtained. +*         3.Invoke the HITLS_GetDefaultPasswordCbUserdata interface and leave ctx blank. Expected result 3 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +* 2.Returns HITLS_SUCCESS +* 3.Returns NULL +            +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + char *userData = "123456"; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetDefaultPasswordCbUserdata(NULL, userData) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetDefaultPasswordCbUserdata(ctx, userData) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetDefaultPasswordCbUserdata(NULL) == NULL); + ASSERT_TRUE(HITLS_GetDefaultPasswordCbUserdata(ctx) == userData); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CFG_LoadCertFile_API_TC001 +* @title HITLS_CFG_LoadCertFile Loading a Device Certificate from a File +* @precon This test case covers the HITLS_CFG_LoadCertFile, HITLS_CFG_SetDefaultPasswordCbUserdata, +* HITLS_CFG_GetDefaultPasswordCbUserdata, HITLS_CFG_LoadKeyFile +* @brief 1. Apply for a configuration file. Expected result 1 is obtained. +* 2. Load an incorrect path. Expected result 2 is obtained. +* 3. Use the same keyword "123456" for mac word and pass word. Expected result 3 is obtained. +* @expect  1. The application is successful. +* 2. Failed to load the certificate. +* 3. The certificate is loaded successfully. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CFG_LoadCertFile_API_TC001(int version, char *certFile1, char *certFile2, char *keyFile2, char *userdata) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ASSERT_EQ( + HITLS_CFG_LoadCertFile(tlsConfig, certFile1, TLS_PARSE_FORMAT_ASN1), HITLS_CONFIG_ERR_LOAD_CERT_FILE); + ASSERT_TRUE(HITLS_CFG_SetDefaultPasswordCbUserdata(tlsConfig, userdata) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetDefaultPasswordCbUserdata(tlsConfig) == userdata); + ASSERT_TRUE(HITLS_CFG_LoadCertFile(tlsConfig, certFile2, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_LoadKeyFile(tlsConfig, keyFile2, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CFG_LoadCertBuffer_FUNC_001 +* @title HITLS_CFG_LoadCertBuffer Loads and Obtains the Device Certificate from the Buffer +* @precon nan +* @brief 1. Create a CTX object. Expected result 1 is obtained. +* 2. In the local context, the store is not initialized. Invoke HITLS_CFG_GetCertificate to obtain the device +* certificate. Expected result 2 is obtained. +* 3. Call the interface to convert the certificate file into a buffer. Expected result 3 is obtained. +* 4. Delete one byte from the buffer, that is, buffer1. Expected result 4 is obtained. +* 5. Add one byte to the buffer, that is, buffer2. Expected result 5 is obtained. +* 6. Call the interface to set the device certificate through buffer1. Expected result 6 is obtained. +* 7. Call the interface to set the device certificate through buffer2. Expected result 7 is obtained. +* 8. Call the interface to set the device certificate through the buffer. Expected result 8 is obtained. +* 9. Call the interface repeatedly to set the device certificate through the buffer. Expected result 9 is +* obtained. +* @expect 1. Created successfully. +* 2. The obtained content is empty. +* 3. The file is converted successfully. +* 4. Deleted successfully. +* 5. Adding succeeded. +* 6. Failed to load the device certificate. +* 7. Failed to load the device certificate. +* 8. Succeeded in loading the device certificate. +* 9. Failed to load the device certificate. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CFG_LoadCertBuffer_FUNC_001(int version, char *certPath) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + uint8_t buf[BUF_MAX_SIZE] = {0}; + uint32_t bufLen = ReadFileBuffer(certPath, (char *)buf); + ASSERT_TRUE(buf != NULL); + ASSERT_TRUE(bufLen <= BUF_MAX_SIZE); + uint8_t buf2[BUF_MAX_SIZE] = {0}; + (void)memcpy_s(buf2, bufLen, buf, bufLen); + + buf2[bufLen - 1] = 'b'; + buf2[bufLen] = 0; + uint8_t buf1[BUF_MAX_SIZE] = {0}; + (void)memcpy_s(buf1, bufLen, buf, bufLen); + + buf1[bufLen - 2] = 0; + ASSERT_TRUE(HITLS_CFG_LoadCertBuffer(tlsConfig, buf, bufLen, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); + ASSERT_EQ( + HITLS_CFG_LoadCertBuffer(tlsConfig, buf1, bufLen - 1, TLS_PARSE_FORMAT_ASN1), HITLS_CONFIG_ERR_LOAD_CERT_BUFFER); + ASSERT_TRUE(HITLS_CFG_LoadCertBuffer(tlsConfig, buf2, bufLen + 1, TLS_PARSE_FORMAT_ASN1) != HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_LoadCertBuffer(tlsConfig, buf, bufLen, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_LoadCertFile_API_TC001 +* @title The input parameter of the HITLS_LoadCertFile interface is replaced. +* @precon nan +* @brief 1.Invoke the HITLS_LoadCertFile interface. The ctx field is empty, the device certificate file name is not +* empty, and the certificate format is PEM. Expected result 1 is obtained. +* 2.Invoke the HITLS_LoadCertFile interface. The ctx parameter is not empty, the device certificate file name +* is not empty, and the certificate format is PEM. Expected result 2 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +*          2.Returns HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_LoadCertFile_API_TC001(int version, char *certFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_LoadCertFile(NULL, NULL, TLS_PARSE_FORMAT_ASN1) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_LoadCertFile(ctx, certFile, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_LoadCertBuffer_API_TC001 +* @title The input parameter of the HITLS_LoadCertBuffer interface is replaced. +* @precon nan +* @brief 1.Invoke the HITLS_LoadCertBuffer interface. The ctx field is empty, the certificate buffer is not empty, the +* buffer length is the actual buffer length, and the certificate format is PEM. Expected result 1 is +* displayed. +* 2.Invoke the HITLS_LoadCertBuffer interface. Ensure that ctx is not empty, the device certificate file name +* is not empty, and the certificate format is PEM. Expected result 2 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +*          2.Returns HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_LoadCertBuffer_API_TC001(int version, char *certFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t certBuffer[BUF_MAX_SIZE] = {0}; + uint32_t certBuffLen = ReadFileBuffer(certFile, (char *)certBuffer); + ASSERT_TRUE(certBuffLen <= BUF_MAX_SIZE); + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_LoadCertBuffer(NULL, certBuffer, certBuffLen, TLS_PARSE_FORMAT_ASN1) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_LoadCertBuffer(ctx, certBuffer, certBuffLen, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + + +/* @ +* @test UT_TLS_CERT_CFG_LoadKeyBuffer_FUNC_TC001 +* @title Load the private key from buffer by using HITLS_CFG_LoadKeyBuffer interface +* @precon nan +* @brief 1. Apply for a configuration file. Expected result 1 is obtained +* 2. Call the API to convert the certificate file into a buffer. Expected result 2 is displayed +* 3. Delete one byte from the buffer, that is, buf1. Expected result 3 is obtained +* 4. Add one byte to the buffer, that is, buf2. Expected result 4 +* 5. Call the interface to load the private key through buf1. Expected result 5 +* 6. Call the interface to load the private key through buf2. Expected result 6 +* 7. Invoke the interface to load the private key through the buffer. Expected result 7 +* 8. Invoke the interface repeatedly to load the private key through the buffer. Expected result 8 is obtained +* @expect  1. The application is successful. +* 2. The file is converted successfully. +* 3. The deletion is successful. +* 4. The addition is successful. +* 5. The private key fails to be loaded. +* 6. The private key success to be loaded. +* 7. The private key is loaded. +* 8. The private key fails to be loaded +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CFG_LoadKeyBuffer_FUNC_TC001(int version, char *keyPath) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + uint8_t buf[BUF_MAX_SIZE] = {0}; + uint32_t bufLen = ReadFileBuffer(keyPath, (char *)buf); + ASSERT_TRUE(buf != NULL); + ASSERT_TRUE(bufLen <= BUF_MAX_SIZE); + uint8_t buf2[BUF_MAX_SIZE] = {0}; + memcpy_s(buf2, bufLen, buf, bufLen); + buf2[bufLen - 1] = 'a'; + buf2[bufLen] = 0; + uint8_t buf1[BUF_MAX_SIZE] = {0}; + memcpy_s(buf1, bufLen, buf, bufLen); + buf1[bufLen - 2] = 0; + ASSERT_TRUE(HITLS_CFG_LoadKeyBuffer(tlsConfig, buf, bufLen, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); + ASSERT_EQ( + HITLS_CFG_LoadKeyBuffer(tlsConfig, buf1, bufLen - 1, TLS_PARSE_FORMAT_ASN1), HITLS_CONFIG_ERR_LOAD_KEY_BUFFER); + ASSERT_EQ( + HITLS_CFG_LoadKeyBuffer(tlsConfig, buf2, bufLen + 1, TLS_PARSE_FORMAT_ASN1), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_LoadKeyBuffer(tlsConfig, buf, bufLen, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_LoadKeyFile_API_TC001 +* @title The error input parameter for HITLS_LoadKeyFile +* @precon nan +* @brief 1.Invoke the HITLS_LoadKeyFile interface. The ctx field is empty, the private key file name is not empty, +* and the private key format is PEM. Expected result 1 +* 2.Invoke the HITLS_LoadKeyFile interface. The ctx field is not empty. The private key file name is not empty +* and the private key is in PEM format. Expected result 2 is obtained +* @expect 1.Back HITLS_NULL_INPUT +*         2.Back HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_LoadKeyFile_API_TC001(int version, char *keyFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_LoadKeyFile(NULL, keyFile, TLS_PARSE_FORMAT_ASN1) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_LoadKeyFile(ctx, keyFile, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_SetAndGetCert_FUNC_TC001 +* @title Set and get verify result +* @precon nan +* @brief 1. Construct the CTX configuration and initialize the session and certificate management. Expected results 1 +* 2. Call HITLS_GetVerifyResult to query the peer certificate verification result of the current context. Expected result 2 +* 3. Call HITLS_SetVerifyResult to set the peer certificate verification result of the current context. Expected result 3 +* 4. Call HITLS_GetVerifyResult to query the peer certificate verification result of the current context. Expected result 4 is obtained +* @expect 1. Initialization succeeded. +* 2. The verification result is 0. +* 3. The setting result is successful. +* 4. The verification result is the set value +@ */ +/* BEGIN_CASE */ +void UT_TLS_SetAndGetCert_FUNC_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_ERROR result; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetVerifyResult(ctx, &result) == HITLS_SUCCESS); + ASSERT_EQ(result, HITLS_X509_V_OK); + ASSERT_TRUE(HITLS_SetVerifyResult(ctx, HITLS_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetVerifyResult(ctx, &result) == HITLS_SUCCESS); + ASSERT_TRUE(result == HITLS_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_LoadKeyBuffer_API_TC001 +* @title The error input parameter for HITLS_LoadKeyBuffer +* @precon nan +* @brief 1. Invoke the HITLS_LoadKeyBuffer interface. The ctx field is empty, the private key buffer is not empty, +* the buffer length is the actual buffer length, and the private key format is PEM. Expected result 1 is +* displayed. +* 2. Invoke the HITLS_LoadKeyBuffer interface. The ctx and private key buffer are not empty, the buffer length +* is the actual buffer length, and the private key format is pem. The expected result is 1 +* @expect 1. HITLS_NULL_INPUT is returned +* 2. HITLS_SUCCESS is returned +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_LoadKeyBuffer_API_TC001(int version, char *keyFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t keyBuffer[BUF_MAX_SIZE] = {0}; + uint32_t keyBuffLen = ReadFileBuffer(keyFile, (char *)keyBuffer); + ASSERT_TRUE(keyBuffLen <= BUF_MAX_SIZE); + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_LoadKeyBuffer(NULL, keyBuffer, keyBuffLen, TLS_PARSE_FORMAT_ASN1) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_LoadKeyBuffer(ctx, keyBuffer, keyBuffLen, TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CFG_SetTlcpCertificate_FUNC_001 +* If an unrecognized record type is received, ignore it. +* @title There are only four types of record layers. +* @precon Test Content: Record layer protocols include: handshake, alarm, and password specification change. +* To support protocol extensions, the record layer protocol may support other record types. +* Any new record types should be deassigned in addition to the Content Type values assigned for the types +* described above. +* In this test case, interface HITLS_CFG_SetTlcpCertificate, HITLS_CFG_SetTlcpPrivateKey is invoked at the +* bottom layer. +* @brief After the link is set up, the server receives abnormal messages (the recordType is 99) after receiving +* app data. The server is expected to return an alert. +* @expect 1. HITLS_REC_ERR_RECV_UNEXPECTED_MSG is returned +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CFG_SetTlcpCertificate_FUNC_001(void) +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLCPConfig(); + ASSERT_TRUE(tlsConfig != NULL); + + uint16_t cipherSuite[] = {HITLS_ECDHE_SM4_CBC_SM3, HITLS_ECC_SM4_CBC_SM3}; + HITLS_CFG_SetCipherSuites(tlsConfig, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, true); + server = FRAME_CreateTLCPLink(tlsConfig, BSL_UIO_TCP, false); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint8_t dataBuf[] = "Hello World!"; + uint8_t readBuf[READ_BUF_SIZE]; + uint32_t readbytes; + ASSERT_EQ(HITLS_Write(client->ssl, dataBuf, sizeof(dataBuf)), HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + FrameUioUserData *ioServerData = BSL_UIO_GetUserData(server->io); + ioServerData->recMsg.msg[0] = 0x99u; + ASSERT_EQ(HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readbytes), HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + ALERT_Info info = { 0 }; + ALERT_GetInfo(server->ssl, &info); + ASSERT_EQ(info.flag, ALERT_FLAG_SEND); + ASSERT_EQ(info.level, ALERT_LEVEL_FATAL); + ASSERT_EQ(info.description, ALERT_UNEXPECTED_MESSAGE); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CFG_SetVerifyCb_API_TC001 +* @title HITLS_CFG_SetVerifyCb interface input parameter test +* @precon This test case covers the HITLS_CFG_SetVerifyCb, HITLS_CFG_GetVerifyCb +* @brief 1. Invoke the HITLS_CFG_SetVerifyCb interface. Input empty tlsConfig and non-empty certificate verification +* callback. Expected result 1 +* 2. Invoke the HITLS_CFG_SetVerifyCb interface. Input non-empty tlsConfig and non-empty certificate +* verification callback. Expected result 3 +* 3. Invoke the HITLS_CFG_GetVerifyCb interface. Input empty tlsConfig, Expected result 2 +* 4. Invoke the HITLS_CFG_SetVerifyCb interface. Input empty tlsConfig->certMgrCtx, and non-empty certificate +* verification callback, Expected result 1 +* 5. Invoke the HITLS_CFG_GetVerifyCb interface. Input empty tlsConfig->certMgrCtx, Expected result 2 +* Expected result 2 +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return NULL +* 3. Return HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CFG_SetVerifyCb_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_TRUE(HITLS_CFG_SetVerifyCb(NULL, TestHITLS_VerifyCb) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetVerifyCb(tlsConfig, TestHITLS_VerifyCb) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_GetVerifyCb(tlsConfig) == TestHITLS_VerifyCb); + ASSERT_TRUE(HITLS_CFG_GetVerifyCb(NULL) == NULL); + SAL_CERT_MgrCtxFree(tlsConfig->certMgrCtx); + tlsConfig->certMgrCtx = NULL; + ASSERT_TRUE(HITLS_CFG_SetVerifyCb(tlsConfig, TestHITLS_VerifyCb) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetVerifyCb(tlsConfig) == NULL); +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_SetVerifyCb_API_TC001 +* @title HITLS_SetVerifyCb interface input parameter test +* @precon This test case covers the HITLS_SetVerifyCb, HITLS_GetVerifyCb +* @brief 1.Invoke the HITLS_SetVerifyCb interface. Input empty ctx and non-empty certificate verification +* callback. Expected result 1 +* 2.Invoke the HITLS_SetVerifyCb interface. Input non-empty ctx and non-empty certificate verification +* callback. Expected result 2 +* 3.Invoke the HITLS_GetVerifyCb interface. Input empty ctx, Expected result 3 +* @expect 1.Return HITLS_NULL_INPUT +* 2.Return HITLS_SUCCESS +* 3.Return NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetVerifyCb_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_SetVerifyCb(NULL, TestHITLS_VerifyCb) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetVerifyCb(ctx, TestHITLS_VerifyCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetVerifyCb(NULL) == NULL); + ASSERT_TRUE(HITLS_GetVerifyCb(ctx) == TestHITLS_VerifyCb); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* +* @test UT_TLS_CERT_GET_CERTIFICATE_API_TC001 +* +* @title Overwrite the input parameter of the HITLS_GetCertificate interface. +* +* @brief +* 1. Invoke the HITLS_GetCertificate interface and leave ctx blank. Expected result 1. +* 2. Invoke the HITLS_GetPeerCertificate interface and leave ctx blank. Expected result 1. +* 3. Invoke the HITLS_GetPeerCertificate interface. The value of ctx is not empty and the value of ctx->session is empty. +* Expected result 1. +* 4. Invoke the HITLS_GetPeerCertChain interface and leave ctx blank. Expected result 1. +* 5. Invoke the HITLS_GetPeerCertChain interface. The value of ctx is not empty and the value of ctx->session is empty. +* Expected result 1 . +* @expect 1. Return NULL. +* @prior Level 1 +* @auto TRUE +*/ + +/* BEGIN_CASE */ +void UT_TLS_CERT_GET_CERTIFICATE_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_GetCertificate(NULL) == NULL); + ASSERT_TRUE(HITLS_GetPeerCertificate(NULL) == NULL); + ASSERT_TRUE(HITLS_GetPeerCertChain(NULL) == NULL); + ctx->session = NULL; + ASSERT_TRUE(HITLS_GetPeerCertificate(ctx) == NULL); + ASSERT_TRUE(HITLS_GetPeerCertChain(ctx) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +void StubListDataDestroy(void *data) +{ + BSL_SAL_FREE(data); + return; +} + +/* @ +* @test UT_TLS_CERT_GET_CALIST_FUNC_TC001 +* +* @title Obtain the peer certificate chain and trusted CA list. +* +* @brief +* 1. Construct the CTX configuration. Expected result 1. +* 2. Invoke HITLS_GetPeerCertChain to obtain the peer certificate chain. Expected result 2. +* 3. Configure a certificate management instance for the session instance. Expected result 3. +* 4. Add the session instance to the SSL instance. Expected result 4. +* 5. If no certificate is loaded to the peer end, call HITLS_GetPeerCertificate to obtain the peer certificate. +* Expected result 5. +* 6. Create a peer certificate management instance and a certificate chain. Expected result 6. +* 7. Add the created certificates to the certificate linked list one by one. Expected result 7. +* 8. Invoke HITLS_GetPeerCertChain to obtain the peer certificate chain. Expected result 8. +* 9. Invoke the HITLS_GetClientCAList client certificate authority (CA) list. Expected result 9. +* @expect +* 1. The creation is successful. +* 2. Obtaining failed. The session is empty. +* 3. The setting is successful, and the interface returns 0. +* 4. If the setting is successful, the interface returns 0. +* 5. Failed to obtain the certificate. The certificate is empty. +* 6. The peerCert and certificate chain are successfully created. +* 7. The interface returns 0. +* 8. The certificate successfully. The obtained peer certificate chain is correct. The obtained cert is +* correct. +* 9. The obtained CA certificate list is correct. The obtained cert is correct. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_GET_CALIST_FUNC_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + HITLS_Session *session = HITLS_SESS_New(); + ASSERT_TRUE(session != NULL); + CERT_Pair *peerCert = (CERT_Pair *)BSL_SAL_Calloc(1u, sizeof(CERT_Pair)); + + HITLS_CERT_X509 *cert1 = (HITLS_CERT_X509 *)BSL_SAL_Calloc(1u, sizeof(HITLS_CERT_X509)); + HITLS_CERT_X509 *cert2 = (HITLS_CERT_X509 *)BSL_SAL_Calloc(1u, sizeof(HITLS_CERT_X509)); + HITLS_CERT_X509 *cert3 = (HITLS_CERT_X509 *)BSL_SAL_Calloc(1u, sizeof(HITLS_CERT_X509)); + + peerCert->chain = (HITLS_CERT_Chain *)BSL_LIST_New(sizeof(HITLS_CERT_X509 *)); + ASSERT_TRUE(peerCert->chain != NULL); + + HITLS_CERT_Chain *certChain = peerCert->chain; + + int32_t ret = BSL_LIST_AddElement((BslList *)certChain, cert1, BSL_LIST_POS_END); + ASSERT_TRUE(ret == 0); + ret = BSL_LIST_AddElement((BslList *)certChain, cert2, BSL_LIST_POS_END); + ASSERT_TRUE(ret == 0); + ret = BSL_LIST_AddElement((BslList *)certChain, cert3, BSL_LIST_POS_END); + ASSERT_TRUE(ret == 0); + + ret = SESS_SetPeerCert(session, peerCert, false); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + + ASSERT_TRUE(HITLS_SetSession(ctx, session) == HITLS_SUCCESS); + + + HITLS_CERT_Chain *getCertChain = HITLS_GetPeerCertChain(ctx); + ASSERT_TRUE(getCertChain != NULL); + + HITLS_TrustedCAList *tmpCAList = ctx->peerInfo.caList; + + HITLS_TrustedCANode *newNode1 = (HITLS_TrustedCANode *)BSL_SAL_Calloc(1, sizeof(HITLS_TrustedCANode)); + ASSERT_TRUE(newNode1 != NULL); + newNode1->caType = HITLS_TRUSTED_CA_X509_NAME; + newNode1->data = NULL; + newNode1->dataSize = 0; + + HITLS_TrustedCANode *newNode2 = (HITLS_TrustedCANode *)BSL_SAL_Calloc(1, sizeof(HITLS_TrustedCANode)); + ASSERT_TRUE(newNode2 != NULL); + newNode2->caType = HITLS_TRUSTED_CA_X509_NAME; + newNode2->data = NULL; + newNode2->dataSize = 0; + ret = BSL_LIST_AddElement((BslList *)tmpCAList, newNode1, BSL_LIST_POS_END); + ASSERT_TRUE(ret == 0); + + ret = BSL_LIST_AddElement((BslList *)tmpCAList, newNode2, BSL_LIST_POS_END); + ASSERT_TRUE(ret == 0); + HITLS_TrustedCAList *caList = HITLS_GetClientCAList(ctx); + ASSERT_TRUE(caList != NULL); + ASSERT_EQ(caList->count, 2); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); + BSL_LIST_DeleteAll((BslList *)peerCert->chain, StubListDataDestroy); + HITLS_SESS_Free(session); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface.data new file mode 100644 index 00000000..facbada5 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface.data @@ -0,0 +1,86 @@ +UT_TLS_CERT_CM_LoadCertBuffer_API_TC001 +UT_TLS_CERT_CM_LoadCertBuffer_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CERT_CM_LoadCertBuffer_API_TC001 +UT_TLS_CERT_CM_LoadCertBuffer_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CERT_CM_LoadCertFile_API_TC001 +UT_TLS_CERT_CM_LoadCertFile_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CERT_CM_LoadCertFile_API_TC001 +UT_TLS_CERT_CM_LoadCertFile_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_TLS_CERT_CFG_LoadCertBuffer_FUNC_001 +UT_TLS_CERT_CFG_LoadCertBuffer_FUNC_001:TLS1_2:"../../testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.der" + +UT_TLS_CERT_CFG_LoadCertFile_API_TC001 +UT_TLS_CERT_CFG_LoadCertFile_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/ecdsa_sha384/clientcert.der":"../../testcode/testdata/tls/certificate/der/need_passwd_cert/eecert.der":"../../testcode/testdata/tls/certificate/der/need_passwd_cert/eekey.der":"123456" + +UT_TLS_CERT_CFG_LoadCertFile_API_TC001 +UT_TLS_CERT_CFG_LoadCertFile_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/ecdsa_sha384/clientcert.der":"../../testcode/testdata/tls/certificate/der/need_passwd_cert/eecert.der":"../../testcode/testdata/tls/certificate/der/need_passwd_cert/eekey.der":"123456" + +UT_TLS_CERT_CFG_SetDefaultPasswordCb_FUNC_001 +UT_TLS_CERT_CFG_SetDefaultPasswordCb_FUNC_001:TLS1_3:"../../testcode/testdata/tls/certificate/der/need_passwd_cert/serverkey.der":"654321" + +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001 +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001 +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001:TLS1_3 + +UT_TLS_CERT_CM_SetVerifyDepth_API_TC001 +UT_TLS_CERT_CM_SetVerifyDepth_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetVerifyDepth_API_TC001 +UT_TLS_CERT_CM_SetVerifyDepth_API_TC001:TLS1_3 + +UT_TLS_CERT_CM_LoadKeyBuffer_API_TC001 +UT_TLS_CERT_CM_LoadKeyBuffer_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.key.der" + +UT_TLS_CERT_CM_LoadKeyBuffer_API_TC001 +UT_TLS_CERT_CM_LoadKeyBuffer_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.key.der" + +UT_TLS_CERT_CM_LoadKeyFile_API_TC001 +UT_TLS_CERT_CM_LoadKeyFile_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_TLS_CERT_CM_LoadKeyFile_API_TC001 +UT_TLS_CERT_CM_LoadKeyFile_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_TLS_SetAndGetCert_FUNC_TC001 +UT_TLS_SetAndGetCert_FUNC_TC001:TLS1_2 + +UT_TLS_SetAndGetCert_FUNC_TC001 +UT_TLS_SetAndGetCert_FUNC_TC001:TLS1_3 + +UT_TLS_CERT_CFG_LoadKeyBuffer_FUNC_TC001 +UT_TLS_CERT_CFG_LoadKeyBuffer_FUNC_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_TLS_CERT_CFG_LoadKeyBuffer_FUNC_TC001 +UT_TLS_CERT_CFG_LoadKeyBuffer_FUNC_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_TLS_CERT_CFG_SetTlcpCertificate_FUNC_001 +UT_TLS_CERT_CFG_SetTlcpCertificate_FUNC_001: + +UT_TLS_CERT_CFG_SetVerifyCb_API_TC001 +UT_TLS_CERT_CFG_SetVerifyCb_API_TC001:TLS1_2 + +UT_TLS_CERT_CFG_SetVerifyCb_API_TC001 +UT_TLS_CERT_CFG_SetVerifyCb_API_TC001:TLS1_3 + +UT_TLS_CERT_CM_SetVerifyCb_API_TC001 +UT_TLS_CERT_CM_SetVerifyCb_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetVerifyCb_API_TC001 +UT_TLS_CERT_CM_SetVerifyCb_API_TC001:TLS1_3 + +UT_TLS_CERT_GET_CERTIFICATE_API_TC001 +UT_TLS_CERT_GET_CERTIFICATE_API_TC001:TLS1_2 + +UT_TLS_CERT_GET_CERTIFICATE_API_TC001 +UT_TLS_CERT_GET_CERTIFICATE_API_TC001:TLS1_3 + +UT_TLS_CERT_GET_CALIST_FUNC_TC001 +UT_TLS_CERT_GET_CALIST_FUNC_TC001:TLS1_3 + +UT_TLS_CERT_GET_CALIST_FUNC_TC001 +UT_TLS_CERT_GET_CALIST_FUNC_TC001:TLS1_2 diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface_2.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface_2.c new file mode 100644 index 00000000..f760af91 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface_2.c @@ -0,0 +1,303 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +/* INCLUDE_BASE test_suite_interface */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hitls_error.h" +#include "hitls_cert.h" +#include "hitls.h" +#include "hitls_func.h" +#include "securec.h" +#include "cert_method.h" +#include "cert_mgr.h" +#include "cert_mgr_ctx.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "session.h" +#include "bsl_sal.h" +#include "bsl_uio.h" +#include "alert.h" +#include "stub_replace.h" +#include "cert_callback.h" +#include "crypt_eal_rand.h" +#include "hitls_crypt_reg.h" +#include "hitls_crypt_init.h" +#include "uio_base.h" +#include "hlt_type.h" +#include "hlt.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" +#include "hitls_cert_reg.h" +#include "hitls_config.h" +#include "hitls_cert_init.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "logger.h" +#include "tls_config.h" +#include "tls.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "bsl_obj.h" +#include "bsl_errno.h" +#include "hitls_x509_adapt_local.h" +/* END_HEADER */ + +#define BUF_MAX_SIZE 4096 +int32_t g_uiPort = 18886; +HITLS_CERT_X509 *HiTLS_X509_LoadCertFile(const char *file); + +/* @ +* @test UT_TLS_CERT_CM_SetVerifyStore_API_TC001 +* @title The input parameters of the HITLS_SetVerifyStore and HITLS_GetVerifyStore interfaces are replaced. +* @precon nan +* @brief 1.Invoke the HITLS_SetVerifyStore interface. The value of ctx is empty and the value of store for the CA +* certificate is not empty. Perform shallow copy. Expected result 1 is obtained. +*          2.Invoke the HITLS_SetVerifyStore interface. Set ctx and CA certificate store to a value that is not empty. +* Expected result 2 is obtained. +*          3.Invoke the HITLS_GetVerifyStore interface and leave tlsConfig blank. Expected result 3 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +*          2.Returns HITLS_SUCCESS +* 3.Returns NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetVerifyStore_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_CERT_Store *verifyStore = HITLS_X509_Adapt_StoreNew(); + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetVerifyStore(NULL, verifyStore, false) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetVerifyStore(ctx, verifyStore, true), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetVerifyStore(ctx) == verifyStore); + ASSERT_TRUE(HITLS_GetVerifyStore(NULL) == NULL); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); + HITLS_X509_Adapt_StoreFree(verifyStore); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_SetChainStore_API_TC001 +* @title The input parameters of the HITLS_SetChainStore and HITLS_GetChainStore interfaces are replaced. +* @precon This test case covers the HITLS_SetChainStore、HITLS_GetChainStore +* @brief 1.Invoke the HITLS_SetChainStore interface. The ctx field is empty and the certificate chain store is not +* empty. Perform shallow copy. Expected result 1 is obtained. +*         2.Invoke the HITLS_SetChainStore interface. The value of ctx is not empty and the value of store in the +* certificate chain is not empty. Perform shallow copy. Expected result 2 is obtained. +*         3.Invoke the HITLS_GetChainStore interface and leave tlsConfig empty. Expected result 3 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +* 2.Returns HITLS_SUCCESS +*          3.Returns NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetChainStore_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_CERT_Store *chainStore = HITLS_X509_Adapt_StoreNew(); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetChainStore(NULL, chainStore, false) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetChainStore(ctx, chainStore, false), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetChainStore(ctx) == chainStore); + ASSERT_TRUE(HITLS_GetChainStore(NULL) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ +/* @ +* @test UT_TLS_CERT_CM_SetCertStore_API_TC001 +* @title The input parameter of the HITLS_SetCertStore interface is replaced. +* @precon This test case covers the HITLS_SetCertStore、HITLS_GetCertStore +* @brief 1.Invoke the HITLS_SetCertStore interface. The value of ctx is empty, and the value of store for the trust +* certificate is not empty. Perform shallow copy. Expected result 1 is obtained. +*         2.Invoke the HITLS_SetCertStore interface. Ensure that ctx and store of the trust certificate are not empty. +* Perform shallow copy. Expected result 2 is obtained. +*         3.Invoke the HITLS_GetCertStore interface and leave ctx blank. Expected result 3 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +* 2.Returns HITLS_SUCCESS +*          3.Returns NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetCertStore_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_CERT_Store *certStore = HITLS_X509_Adapt_StoreNew(); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetCertStore(NULL, certStore, false) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetCertStore(ctx, certStore, false), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetCertStore(ctx) == certStore); + ASSERT_TRUE(HITLS_GetCertStore(NULL) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001 +* @title The input parameter of the HITLS_SetDefaultPasswordCbUserdata interface is replaced. +* @precon This test case covers the HITLS_SetDefaultPasswordCbUserdata、HITLS_GetDefaultPasswordCbUserdata +* @brief 1.Invoke the HITLS_SetDefaultPasswordCbUserdata interface. The value of ctx is empty and the value of +* userdata is not empty. Expected result 1 is obtained. +*         2.Invoke the HITLS_SetDefaultPasswordCbUserdata interface. The values of ctx and userdata are not empty. +* Expected result 2 is obtained. +*         3.Invoke the HITLS_GetDefaultPasswordCbUserdata interface and leave ctx blank. Expected result 3 is obtained. +* @expect  1.Returns HITLS_NULL_INPUT +* 2.Returns HITLS_SUCCESS +* 3.Returns NULL +            +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_CERT_Store *certStore = HITLS_X509_Adapt_StoreNew(); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetCertStore(NULL, certStore, false) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetCertStore(ctx, certStore, false), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetCertStore(ctx) == certStore); + ASSERT_TRUE(HITLS_GetCertStore(NULL) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CERT_SetGetAndCheckPrivateKey_API_TC001 +* @title The error input parameter for HITLS_SetPrivateKey +* @precon nan +* @brief 1.Invoke the HITLS_SetPrivateKey interface. Ensure that ctx is empty and privatekey is not empty. +* Perform deep copy. Expected result 1 +*         2.Invoke the HITLS_SetPrivateKey interface. Ensure that ctx is not empty and privatekey is not empty. +* In shallow copy mode, expected result 2 +*         3.Invoke the HITLS_GetPrivateKey interface. If ctx is empty, expected result 3 +*         4.Invoke the HITLS_CheckPrivateKey interface. If ctx is empty, expected result 1 is obtained +* @expect 1.Back HITLS_NULL_INPUT +*         2.Back HITLS_SUCCESS +* 3.Back HITLS_NULL_INPUT +@ */ +/* BEGIN_CASE */ +void UT_TLS_CERT_SetGetAndCheckPrivateKey_API_TC001(int version, char *keyFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_CERT_Key *privatekey = HITLS_X509_Adapt_KeyParse(tlsConfig, (const uint8_t *)keyFile, sizeof(keyFile), + TLS_PARSE_TYPE_FILE, TLS_PARSE_FORMAT_ASN1); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetPrivateKey(NULL, privatekey, true) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetPrivateKey(ctx, privatekey, false) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_GetPrivateKey(NULL) == NULL); + ASSERT_TRUE(HITLS_GetPrivateKey(ctx) != NULL); + ASSERT_TRUE(HITLS_CheckPrivateKey(NULL) == HITLS_NULL_INPUT); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_HITLS_CERT_ClearChainCerts_API_TC001 +* @title HITLS_ClearChainCerts interface input parameter test +* @precon nan +* @brief 1. Invoke HITLS_ClearChainCerts interface. Input empty ctx. Expected result 1 +* 2. Invoke HITLS_ClearChainCerts interface. Input non-empty ctx. Expected result 2 +* 3. Invoke HITLS_ClearChainCerts interface. Input non-empty ctx and empty tlsConfig->certMgrCtx, +* Expected result 1 +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_HITLS_CERT_ClearChainCerts_API_TC001(int version, char *certFile, char *addCertFile) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + HITLS_CERT_X509 *cert = HiTLS_X509_LoadCertFile(certFile); + ASSERT_TRUE(cert != NULL); + HITLS_CERT_X509 *addCert = HiTLS_X509_LoadCertFile(addCertFile); + ASSERT_TRUE(addCert != NULL); + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_TRUE(HITLS_CFG_SetCertificate(tlsConfig, cert, false) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_AddChainCert(tlsConfig, addCert, false) == HITLS_SUCCESS); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_ClearChainCerts(NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_ClearChainCerts(ctx) == HITLS_SUCCESS); + SAL_CERT_MgrCtxFree(ctx->config.tlsConfig.certMgrCtx); + ctx->config.tlsConfig.certMgrCtx = NULL; + ASSERT_EQ(HITLS_ClearChainCerts(ctx), HITLS_NULL_INPUT); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface_2.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface_2.data new file mode 100644 index 00000000..771feaa7 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cert_interface_2.data @@ -0,0 +1,35 @@ +UT_TLS_CERT_CM_SetVerifyStore_API_TC001 +UT_TLS_CERT_CM_SetVerifyStore_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetVerifyStore_API_TC001 +UT_TLS_CERT_CM_SetVerifyStore_API_TC001:TLS1_3 + +UT_TLS_CERT_CM_SetChainStore_API_TC001 +UT_TLS_CERT_CM_SetChainStore_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetChainStore_API_TC001 +UT_TLS_CERT_CM_SetChainStore_API_TC001:TLS1_3 + +UT_TLS_CERT_CM_SetCertStore_API_TC001 +UT_TLS_CERT_CM_SetCertStore_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetCertStore_API_TC001 +UT_TLS_CERT_CM_SetCertStore_API_TC001:TLS1_3 + +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001 +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001:TLS1_2 + +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001 +UT_TLS_CERT_CM_SetDefaultPasswordCbUserdata_API_TC001:TLS1_3 + +UT_TLS_CERT_SetGetAndCheckPrivateKey_API_TC001 +UT_TLS_CERT_SetGetAndCheckPrivateKey_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_TLS_CERT_SetGetAndCheckPrivateKey_API_TC001 +UT_TLS_CERT_SetGetAndCheckPrivateKey_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der" + +UT_HITLS_CERT_ClearChainCerts_API_TC001 +UT_HITLS_CERT_ClearChainCerts_API_TC001:TLS1_2:"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/server.der":"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der" + +UT_HITLS_CERT_ClearChainCerts_API_TC001 +UT_HITLS_CERT_ClearChainCerts_API_TC001:TLS1_3:"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/server.der":"../../testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der" \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cm_interface.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cm_interface.c new file mode 100644 index 00000000..c9e19d2a --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cm_interface.c @@ -0,0 +1,4511 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "bsl_uio.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_reg.h" +#include "hitls_config.h" +#include "tls_config.h" +#include "hitls.h" +#include "hs_common.h" +#include "hitls_func.h" +#include "tls.h" +#include "conn_init.h" +#include "crypt_errno.h" +#include "stub_replace.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "rec_wrapper.h" +#include "hlt_type.h" +#include "hlt.h" +#include "process.h" +#include "hitls_crypt_init.h" +#include "bsl_list.h" +#include "simulate_io.h" +#include "alert.h" + +#define READ_BUF_SIZE 18432 +#define MAX_CERT_LIST 4294967295 +#define MIN_CERT_LIST 0 +#define DEFAULT_SECURITYLEVEL 0 +/* END_HEADER */ + +static HITLS_Config *GetHitlsConfigViaVersion(int ver) +{ + HITLS_Config *config; + int32_t ret; + switch (ver) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return config; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return config; + case HITLS_VERSION_DTLS12: + config = HITLS_CFG_NewDTLS12Config(); + ret = HITLS_CFG_SetCloseCheckKeyUsage(config, false); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return config; + default: + return NULL; + } +} + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isSupportRenegotiation; + bool isSupportSessionTicket; + bool needStopBeforeRecvCCS; +} HandshakeTestInfo; + +static uint8_t g_clientRandom[RANDOM_SIZE]; +static uint8_t g_serverRandom[RANDOM_SIZE]; + +/* @ +* @test UT_TLS_CM_SET_GET_UIO_API_TC001 +* @title Test the HITLS_SetUio and HITLS_GetUio interfaces +* @precon nan +* @brief HITLS_SetUio +* 1. Input an empty connection context and a non-empty UIO. Expected result 1 is obtained +* 2. Input an empty connection context and an empty UIO. Expected result 1 is obtained +* 3. Input a non-empty connection context and an empty UIO. Expected result 1 is obtained +* 4. Input a non-empty connection context and a non-empty UIO. Expected result 2 is obtained +* HITLS_GetUio +* 1. Input an empty connection context. Expected result 3 is obtained +* 2. Input a non-empty connection context. Expected result 4 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCESS +* 3. Return a null pointer +* 4. Return connection uio +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_UIO_API_TC001(int tlsVersion) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_Ctx* ctx = HITLS_New(tlsConfig); + BSL_UIO *uio = NULL; + BSL_UIO *uio2; + int32_t ret; + + uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + + ret = HITLS_SetUio(NULL, uio); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetUio(NULL, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetUio(ctx, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetUio(ctx, uio); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + uio2 = HITLS_GetUio(NULL); + ASSERT_TRUE(uio2 == NULL); + + uio2 = HITLS_GetUio(ctx); + ASSERT_TRUE(uio2 != NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_GET_READ_UIO_API_TC001 +* @title Test the HITLS_SetReadUio, HITLS_GetReadUio interfaces +* @precon nan +* @brief HITLS_SetReadUio +* 1. Input an empty connection context and a non-empty UIO. Expected result 1 is obtained +* 2. Input an empty connection context and an empty UIO. Expected result 1 is obtained +* 2. Input a non-empty connection context and an empty UIO. Expected result 1 is obtained +* 4. Input a non-empty connection context and a non-empty UIO. Expected result 2 is obtained +* HITLS_GetReadUio +* 1. Input an empty connection context. Expected result 3 is obtained +* 2. Input a non-empty connection context. Expected result 4 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCESS +* 3. Return a null pointer +* 4. Return connection uio +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_READ_UIO_API_TC001(int tlsVersion) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL) ; + + HITLS_Ctx* ctx = HITLS_New(tlsConfig); + BSL_UIO *uio = NULL; + BSL_UIO *uio2 = NULL; + int32_t ret; + + uio = BSL_UIO_New(BSL_UIO_TcpMethod()); + + ret = HITLS_SetReadUio(NULL, uio); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetReadUio(NULL, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetReadUio(ctx, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetReadUio(ctx, uio); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + uio2 = HITLS_GetReadUio(NULL); + ASSERT_TRUE(uio2 == NULL); + + uio2 = HITLS_GetReadUio(ctx); + ASSERT_TRUE(uio2 != NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); + BSL_UIO_Free(uio); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_ENDPOINT_FUNC_TC001 +* @title Invoke HITLS_SetEndPoint after initialization, check whether the state is handshaking +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 is obtained +* 2. After initialization, call HITLS_SetEndPoint and check the state status. Expected result 2 is obtained +* @expect 1. Complete initialization +* 2. state is handshaking +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_ENDPOINT_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + uint32_t ret = HITLS_SetEndPoint(server->ssl, true); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(server->ssl->state, CM_STATE_HANDSHAKING); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test The HITLS_SetEndPoint function fails to be invoked during link establishment +* @title UT_TLS_CM_SET_ENDPOINT_FUNC_TC002 +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 is obtained +* 2. Invoke HITLS_SetEndPoint during link establishment. Expected result 2 is obtained +* @expect 1. Complete initialization +* 2. Invoking failed +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_ENDPOINT_FUNC_TC002(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO) == HITLS_SUCCESS); + uint32_t ret = HITLS_SetEndPoint(server->ssl, true); + ASSERT_EQ(ret, HITLS_MSG_HANDLE_STATE_ILLEGAL); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test Obtains the maximum writable plaintext length after initialization +* @title UT_TLS_CM_GET_MAXWRITESIZE_FUNC_TC001 +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 is obtained +* 2. Invoke HITLS_GetMaxWriteSize to obtain the maximum writable plaintext length. +* Expected result 2 is obtained +* @expect 1. Complete initialization +* 2. Obtain the length successfully, the length is equal to REC_MAX_PLAIN_LENGTH +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_MAXWRITESIZE_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + uint32_t len = 0; + uint32_t ret = CONN_Init(client->ssl); + ASSERT_EQ(ret, HITLS_SUCCESS); + ret = HITLS_GetMaxWriteSize(client->ssl, &len); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(len, REC_MAX_PLAIN_LENGTH); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_GET_USR_DATA_TC001 +* @title test HITLS_SetUserData, HITLS_GetUserData interfaces +* @precon nan +* @brief HITLS_SetUserData +* 1. Input an empty connection context and a non-empty userData. Expected result 1 is obtained +* 2. Input an empty connection context and an empty userData. Expected result 1 is obtained +* 3. Input a non-empty connection context and an empty userData. Expected result 2 is obtained +* 4. Input a non-empty connection context and a non-empty userData. Expected result 2 is obtained +* HITLS_GetUserData +* 1. Input an empty connection context. Expected result 4 is obtained +* 2. Input a non-empty connection context. Expected result 3 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCESS +* 3. Return userData +* 4. Return a null pointer +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_USR_DATA_API_TC001(int tlsVersion) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL) ; + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + int32_t ret; + uint8_t userData[5] = {0}; + + void *ret2 = HITLS_GetUserData(NULL); + ASSERT_TRUE(ret2 == NULL); + + ret = HITLS_SetUserData(NULL, &userData); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetUserData(NULL, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetUserData(ctx, NULL); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = HITLS_SetUserData(ctx, &userData); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = HITLS_SetUserData(ctx, "userdata"); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret2 = HITLS_GetUserData(ctx); + ASSERT_TRUE(strcmp(ret2, "userdata") == 0); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test HITLS_SetShutdownState Set HITLS_SENT_SHUTDOWN to 1 and do not send the close_notify message. +* @title UT_TLS_CM_SET_SHUTDOWN_FUNC_TC001 +* @precon nan +* @brief 1. Set HITLS_SENT_SHUTDOWN to 1 and invoke the Hitls_Close interface. Expected result 1 is obtained +* @expect 1. The interface is successfully invoked and the close_notify message is not sent +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_SHUTDOWN_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_SetShutdownState(client->ssl, 1) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Close(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_CLOSED); + + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + FrameUioUserData *ioUserData = BSL_UIO_GetUserData(server->io); + uint32_t readLen = ioUserData->recMsg.len; + ASSERT_TRUE(readLen == 0); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_SHUTDOWN_FUNC_TC001 +* @title Use HITLS_GetShutdownState to obtain the configured value +* @precon nan +* @brief 1. Set HITLS_SENT_SHUTDOWN to 1 and invoke the HITLS_GetShutdownState interface. Expected result 1 +* 2. Set HITLS_SENT_SHUTDOWN to 2 and invoke the HITLS_GetShutdownState interface. Expected result 2 +* 3. Set HITLS_SENT_SHUTDOWN to 0 and invoke the HITLS_GetShutdownState interface. Expected result 3 +* @expect 1. Obtain value 1 +* 2. Obtain value 2 +* 3. Obtain value 0. +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_SHUTDOWN_FUNC_TC001(int version) +{ + int32_t ret; + uint32_t mode; + HitlsInit(); + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + CONN_Init(ctx); + ASSERT_TRUE(ctx != NULL); + + for (uint32_t i = 0; i <= 2; i++) { + ret = HITLS_SetShutdownState(ctx, i); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ret = HITLS_GetShutdownState(ctx, &mode); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(mode == i); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_NEGOTIATED_VERSION_FUNC_TC001 +* @title HITLS_GetNegotiatedVersion Interface in TLS1.2 Scenario and TLS1.3 Scenario +* @precon nan +* @brief 1. Set the protocol version to TLS1.2 or TLS1.3. After initialization, invoke the HITLS_GetNegotiatedVersion +* interface to obtain the negotiated version number. Expected result 1 is obtained +* 2. Set the protocol version to TLS1.2 or TLS1.3. After the connection is established, invoke the +* HITLS_GetNegotiatedVersion interface to obtain the negotiated version number. Expected result 2 is obtained +* @expect 1. obtained value is 0 +* 2. obtained value is tls1.2/tls1.3 +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_NEGOTIATED_VERSION_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + config->isSupportRenegotiation = true; + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + uint16_t negoVersion = HITLS_VERSION_TLCP11; + ret = HITLS_GetNegotiatedVersion(client->ssl, &negoVersion); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(negoVersion, 0); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetNegotiatedVersion(client->ssl, &negoVersion); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(negoVersion, version); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_GET_MAX_PROTO_VERSION_API_TC001 +* @title test HITLS_SetMaxProtoVersion, HITLS_GetMaxProtoVersion interfaces +* @precon nan +* @brief HITLS_SetMaxProtoVersion +* 1. Input an empty connection context. Expected result 1 is obtained +* 2. Input a non-empty connection context and version is too low. Expected result 2 is obtained +* 3. Input a non-empty connection context and normal version. Expected result 3 is obtained +* HITLS_GetMaxProtoVersion +* 1. Input an empty connection context and a null pointer. Expected result 1 is obtained +* 2. Input an empty connection context and a non-empty pointer. Expected result 1 is obtained +* 3. Input a non-empty connection context and a non-empty pointer. Expected result 3 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_CONFIG_INVALID_VERSION + 3. Return HITLS_SUCCESS +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_MAX_PROTO_VERSION_API_TC001(int tlsVersion) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + int32_t ret; + uint16_t maxVersion = 0; + + ret = HITLS_SetMaxProtoVersion(NULL, HITLS_VERSION_TLS10); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetMaxProtoVersion(ctx, HITLS_VERSION_TLS10); + ASSERT_TRUE(ret == HITLS_CONFIG_INVALID_VERSION); + + ret = HITLS_SetMaxProtoVersion(ctx, HITLS_VERSION_TLS13); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = HITLS_GetMaxProtoVersion(NULL, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_GetMaxProtoVersion(NULL, &maxVersion); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_GetMaxProtoVersion(ctx, &maxVersion); + ASSERT_TRUE(ret == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_GET_MIN_PROTO_VERSION_API_TC001 +* @title test HITLS_SetMinProtoVersion, HITLS_GetMinProtoVersion interfaces +* @precon nan +* @brief HITLS_SetMaxProtoVersion +* 1. Input an empty connection context. Expected result 1 is obtained +* 2. Input a non-empty connection context and version is too high. Expected result 2 is obtained +* 3. Input a non-empty connection context and normal version. Expected result 3 is obtained +* HITLS_GetMinProtoVersion +* 1. Input an empty connection context and a null pointer. Expected result 1 is obtained +* 2. Input an empty connection context and a non-empty pointer. Expected result 1 is obtained +* 3. Input a non-empty connection context and a non-empty pointer. Expected result 3 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_CONFIG_INVALID_VERSION +* 3. Return HITLS_SUCCESS +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_GET_MIN_PROTO_VERSION_API_TC001(int tlsVersion) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL) ; + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + int32_t ret; + uint16_t minVersion = 0; + + ret = HITLS_SetMinProtoVersion(NULL, HITLS_VERSION_TLS12); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetMinProtoVersion(ctx, HITLS_VERSION_TLS13); + ASSERT_TRUE(ret == HITLS_CONFIG_INVALID_VERSION); + + ret = HITLS_SetMinProtoVersion(ctx, HITLS_VERSION_TLS12); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = HITLS_GetMinProtoVersion(NULL, NULL); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_GetMinProtoVersion(NULL, &minVersion); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_GetMinProtoVersion(ctx, &minVersion); + ASSERT_TRUE(ret == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_IS_AEAD_FUNC_TC001 +* @title HITLS_IsAead Obtains whether to use the AEAD algorithm after negotiation +* @precon TLS12, HITLS_RSA_with_AES_128_CBC_SHA256 (not AEAD), TLS13, HITLS_CHACHA20_POLY1305_SHA256 / +* HITLS_AES_128_GCM_SHA256 (AEAD) +* @brief 1. Initialize the client and server and set the cipherSuite. Expected result 1 +* 2. After connection is established, invoke HITLS_IsAead to check whether +* the AEAD algorithm is negotiated. Expected result 2 +* @expect 1. Initialization is complete. +* 2. Value of isAEAD +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_IS_AEAD_FUNC_TC001(int version, int ciphersuite) +{ + FRAME_Init(); + int ret; + uint8_t isAEAD = 0; + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint16_t cipherSuites[] = {(uint16_t)ciphersuite}; + + HITLS_CFG_SetCipherSuites(config_c, cipherSuites, sizeof(cipherSuites) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + ret = HITLS_IsAead(client->ssl, &isAEAD); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isAEAD == (version == HITLS_VERSION_TLS13)); + + ret = HITLS_IsAead(server->ssl, &isAEAD); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isAEAD == (version == HITLS_VERSION_TLS13)); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test HITLS_IsHandShakeDone Check whether the handshake is complete during connection establishment +* @title UT_TLS_CM_IS_HSDONE_FUNC_TC001 +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 +* 2. During connection establishment, invoke HITLS_IsHandShakeDone to check whether the handshake is complete. +* Expected result 2 +* @expect 1. Initialization is complete +* 2. The interface returns 0 and the handshake is not done +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_IS_HSDONE_FUNC_TC001(int version, int state) +{ + FRAME_Init(); + int ret; + uint8_t isDone; + HITLS_Config *config = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_HandshakeState curState = (HITLS_HandshakeState)state; + ret = FRAME_CreateConnection(client, server, true, curState); + + ret = HITLS_IsHandShakeDone(client->ssl, &isDone); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isDone == 0); + + ret = HITLS_IsHandShakeDone(server->ssl, &isDone); + ASSERT_TRUE(ret == HITLS_SUCCESS); + if (version == HITLS_VERSION_TLS12 && curState == TRY_RECV_FINISH) { + ASSERT_TRUE(isDone == 1); + } else { + ASSERT_TRUE(isDone == 0); + } + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test HITLS_IsHandShakeDone Check whether the handshake is complete after connection establishment +* @title UT_TLS_CM_IS_HSDONE_FUNC_TC002 +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 +* 2. After the connection is established, invoke HITLS_IsHandShakeDone to check whether the handshake +* is complete. Expected result 2 +* @expect 1. Initialization is complete +* 2. The interface returns 1 and the handshake is done +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_IS_HSDONE_FUNC_TC002(int version) +{ + FRAME_Init(); + int ret; + uint8_t isDone; + HITLS_Config *config = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + ret = HITLS_IsHandShakeDone(client->ssl, &isDone); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isDone == 1); + + ret = HITLS_IsHandShakeDone(server->ssl, &isDone); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isDone == 1); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_IS_SERVER_FUNC_TC001 +* @title HITLS_IsServer The client invokes the interface to determine whether the current server is the server +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 +* 2. The client invokes the HITLS_IsServer interface to determine whether the current client is a server. +* Expected result 2 +* 3. The server invokes the HITLS_IsServer interface to determine whether the current server is a server. +* Expected result 3 +* @expect 1. Initialization is complete +* 2. The interface returns false +* 3. The interface returns true +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_IS_SERVER_FUNC_TC001(int version) +{ + FRAME_Init(); + int ret; + uint8_t isServer; + HITLS_Config *config = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + ret = HITLS_IsServer(client->ssl, &isServer); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isServer == false); + + ret = HITLS_IsServer(server->ssl, &isServer); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(isServer == true); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_READHASPENDING_FUNC_TC001 +* @title HITLS_ReadHasPending Interface test +* @precon nan +* @brief 1. After initialization, invoke the hitls_readhaspending interface. Expected result 1 is obtained. +* 2. After the connection is established, the peer sends data and the local +* invokes the hitls_readhaspending interface. Expected result 2 is obtained. +* @expect 1. Return 0 +* 2. Return 1 +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_READHASPENDING_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + uint8_t isPending = 0; + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(HITLS_ReadHasPending(client->ssl, &isPending) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_ReadHasPending(server->ssl, &isPending) == HITLS_SUCCESS); + ASSERT_EQ(isPending, 0); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + uint8_t data[] = "Hello World"; + ASSERT_TRUE(HITLS_Write(client->ssl, data, sizeof(data)) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS); + + uint8_t readBuf[5] = {0}; + uint32_t readLen = 0; + ASSERT_TRUE(HITLS_Read(server->ssl, readBuf, 5, &readLen) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_ReadHasPending(server->ssl, &isPending) == HITLS_SUCCESS); + ASSERT_EQ(isPending, 1); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_READPENDING_FUNC_TC001 +* @title HITLS_GetReadPendingBytes interfaces test +* @precon nan +* @brief 1. After initialization, invoke the HITLS_GetReadPendingBytes interface to query data. +* Expected result 1 is obtained. +* 2. Simulate a scenario where the peer end sends app data during renegotiation to generate app data cache, +* and invoke HITLS_GetReadPendingBytes to obtain the cache value. Expected result 2 is obtained. +* 3. When the buffer length of the HITLS_Read read data is less than 16 KB, some data is left. +* Invoke the HITLS_GetReadPendingBytes interface to query the data. Expected result 3 is obtained. +* @expect 1. The return value is 0. +* 2. Returns the size of the cached value. +* 3. Returns the size of the left value. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_READPENDING_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + config->isSupportRenegotiation = true; + + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(HITLS_GetReadPendingBytes(server->ssl) == 0); + ASSERT_TRUE(HITLS_GetReadPendingBytes(client->ssl) == 0); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + uint8_t data[] = "Hello World"; + ASSERT_TRUE(HITLS_Write(server->ssl, data, sizeof(data)) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_GetReadPendingBytes(client->ssl) == sizeof("Hello World")); + + client->ssl->state = CM_STATE_TRANSPORTING; + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ASSERT_EQ(HITLS_Read(client->ssl, readBuf, 2, &readLen), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetReadPendingBytes(client->ssl) == (sizeof("Hello World") - 2)); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test HITLS_GetPeerSignScheme Unidirectional authentication on the client +* @title UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC001 +* @precon nan +* @brief 1. Configure unidirectional authentication. After the negotiation is complete, +* call the interface to obtain the local signature hash algorithm. Expected result 1 is displayed. +* 2. Call the interface to obtain the peer signature hash algorithm. Expected result 2 is obtained. +* @expect 1. Return 0 +* 2. Return 0 +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + HITLS_CFG_SetClientVerifySupport(config, false); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + HITLS_SignHashAlgo peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + uint32_t ret = HITLS_GetPeerSignScheme(server->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(peerSignScheme, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test HITLS_GetPeerSignScheme Client two-way authentication Verification +* @title UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC002 +* @precon nan +* @brief 1. Set two-way authentication. Before the client receives the certificate request, call the interface to +* obtain the local signature hash algorithm. Expected result 1 is obtained. +* 2. After receiving the certificate request, the client invokes the interface to obtain the negotiated +8 signature hash algorithm. Expected result 2 is displayed. +* @expect 1. Return 0 +* 2. The returned value is the negotiated algorithm +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC002(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + HITLS_CFG_SetClientVerifySupport(config, true); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_CERTIFICATE_REQUEST) == HITLS_SUCCESS); + HITLS_SignHashAlgo peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + // + uint32_t ret = HITLS_GetPeerSignScheme(client->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + if (version == HITLS_VERSION_TLS13) { + ASSERT_EQ(peerSignScheme, 0); + } else { + ASSERT_NE(peerSignScheme, 0); + } + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + ret = HITLS_GetPeerSignScheme(client->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_NE(peerSignScheme, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC003 +* @title HITLS_GetPeerSignScheme Client Verification +* @precon nan +* @brief 1. Before the client receives the serverkeyexchange message, call the interface to obtain the peer signature +* hash algorithm. Expected result 1 is displayed. +* 2. After receiving the serverkeyexchange message, the client invokes the interface to obtain the signature +* hash algorithm of the peer end. Expected result 2 is obtained. +* @expect 1. Return 0 +* 2. The return value is the algorithm used by the server +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC003(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + HITLS_CFG_SetClientVerifySupport(config, true); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_SignHashAlgo peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + uint32_t ret = HITLS_GetPeerSignScheme(server->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(peerSignScheme, 0); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + ret = HITLS_GetPeerSignScheme(client->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(peerSignScheme, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC004 +* @title HITLS_GetPeerSignScheme two-way authentication verification on the server +* @precon nan +* @brief 1. Set two-way authentication. Before the server receives the certificate verify message, +* call the API to obtain the peer signature hash algorithm. Expected result 1 is obtained. +* 2. After receiving the certificate verify message, the server invokes the API to obtain the signature hash +* algorithm of the peer end. Expected result 2 is obtained. +* @expect 1. Return 0 +* 2. The returned value is the algorithm used by the client +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC004(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + HITLS_CFG_SetClientVerifySupport(config, true); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_SEND_CERTIFICATE_VERIFY) == HITLS_SUCCESS); + HITLS_SignHashAlgo peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + uint32_t ret = HITLS_GetPeerSignScheme(server->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(peerSignScheme, 0); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + peerSignScheme = CERT_SIG_SCHEME_UNKNOWN; + ret = HITLS_GetPeerSignScheme(server->ssl, &peerSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_NE(peerSignScheme, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_LOCAL_SIGN_SCHEME_FUNC_TC001 +* @title HITLS_GetLocalSignScheme Server-side verification +* @precon nan +* @brief 1. Before the server receives the client hello message, call the interface to obtain the negotiated signature +* hash algorithm. Expected result 1 is displayed +* 2. After receiving the client hello message, the server invokes the interface to obtain the negotiated +* signature hash algorithm. Expected result 2 is displayed +* @expect 1. Return 0 +* 2. The return value is the algorithm used by the server +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_LOCAL_SIGN_SCHEME_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + config->isSupportRenegotiation = true; + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_SignHashAlgo localSignScheme = CERT_SIG_SCHEME_UNKNOWN; + ret = HITLS_GetLocalSignScheme(server->ssl, &localSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(localSignScheme, 0); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ret = HITLS_GetLocalSignScheme(server->ssl, &localSignScheme); + ASSERT_EQ(ret, HITLS_SUCCESS); + switch (version) { + case HITLS_VERSION_TLS12: + ASSERT_EQ(localSignScheme, CERT_SIG_SCHEME_RSA_PKCS1_SHA256); + break; + case HITLS_VERSION_TLS13: + ASSERT_EQ(localSignScheme, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256); + break; + default: + config = NULL; + break; + } +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_EC_GROUPS_FUNC_TC001 +* @title test HITLS_SetEcGroups interface +* @precon nan +* @brief 1. Input an empty link context and a non-empty group. Normal groupsize. Expected result 1 is obtained +* 2. Input a non-empty link context, empty group, and normal groupsize. Expected result 1 is obtained. +* 3. Input a non-empty link context, a non-empty group, and groupsize 0. Expected result 1 is obtained +* 4. Transfer a non-empty link context, a non-empty group, and normal groupsize. Expected result 2 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_EC_GROUPS_FUNC_TC001(int tlsVersion) +{ + HitlsInit(); + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + uint16_t groups[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP521R1}; + uint32_t groupsSize = sizeof(groups) / sizeof(uint16_t); + + int32_t ret; + + ret = HITLS_SetEcGroups(NULL, groups, groupsSize); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetEcGroups(ctx, NULL, groupsSize); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetEcGroups(ctx, groups, 0); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetEcGroups(ctx, groups, groupsSize); + ASSERT_TRUE(ret == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_SIGAL_LIST_FUNC_TC001 +* @title test HITLS_SetSigalgsList interface +* @precon nan +* @brief 1. Input an empty link context and a non-empty signAlg. Normal signAlgsSize. Expected result 1 is obtained +* 2. Input an non-empty link context and an empty signAlg. Normal signAlgsSize. Expected result 1 is obtained +* 2. Input a non-empty link context and a non-empty signAlg. 0 signAlgsSize. Expected result 1 is obtained +* 2. Input a non-empty link context and a non-empty signAlg. Normal signAlgsSize. Expected result 2 is obtained +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCESS +@*/ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_SIGAL_LIST_FUNC_TC001(int tlsVersion) +{ + HitlsInit(); + + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(tlsConfig != NULL) ; + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + uint32_t signAlgsSize = sizeof(signAlgs) / sizeof(uint16_t); + + int32_t ret; + + ret = HITLS_SetSigalgsList(NULL, signAlgs, signAlgsSize); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetSigalgsList(ctx, NULL, signAlgsSize); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetSigalgsList(ctx, signAlgs, 0); + ASSERT_TRUE(ret == HITLS_NULL_INPUT); + + ret = HITLS_SetSigalgsList(ctx, signAlgs, signAlgsSize); + ASSERT_TRUE(ret == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_EC_POINT_FUNC_TC001 +* @title Set the normal dot format value. +* @precon nan +* @brief 1. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED and invoke the HITLS_CFG_SetEcPointFormats interface. +* Expected result 1 is obtained. +* 2. Set pointFormats to HITLS_POINT_FORMAT_BUTT and invoke the HITLS_CFG_SetEcPointFormats interface. +* Expected result 2 +* 3. Use config to generate ctx, due to the result 3 +* 4. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED again and generate ctx again. Expected result 4 is +* obtained. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED and invoke the HITLS_SetEcPointFormats +* interface. Expected result 2 +* @expect 1. Interface return value, HITLS_SUCCESS +* 2. Interface return value: HITLS_SUCCESS +* 3. Failed to generate the file. +* 4. The file is generated successfully. +* 5. The setting is successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SET_EC_POINT_FUNC_TC001(int version) +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *Config = NULL; + HITLS_Ctx *ctx = NULL; + Config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(Config != NULL); + const uint8_t pointFormats[] = {HITLS_POINT_FORMAT_UNCOMPRESSED}; + uint32_t pointFormatsSize = sizeof(pointFormats) / sizeof(uint8_t); + ASSERT_TRUE(HITLS_CFG_SetEcPointFormats(Config, pointFormats, pointFormatsSize) == HITLS_SUCCESS); + + const uint8_t pointFormats2[] = {HITLS_POINT_FORMAT_BUTT}; + uint32_t pointFormatsSize2 = sizeof(pointFormats2) / sizeof(uint8_t); + ASSERT_TRUE(HITLS_CFG_SetEcPointFormats(Config, pointFormats2, pointFormatsSize2) == HITLS_SUCCESS); + ctx = HITLS_New(Config); + if(version == TLS1_2){ + ASSERT_TRUE(ctx == NULL); + } + HITLS_Free(ctx); + ASSERT_TRUE(HITLS_CFG_SetEcPointFormats(Config, pointFormats, pointFormatsSize) == HITLS_SUCCESS); + ctx = HITLS_New(Config); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_SetEcPointFormats(ctx, pointFormats, pointFormatsSize) == HITLS_SUCCESS); + client = FRAME_CreateLink(Config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(Config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(Config); + HITLS_Free(ctx); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_CONFIG_FUNC_TC001 +* @title After the initialization is complete, obtain the config file and check whether the configuration is consistent +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 is obtained +* 2. After the initialization is complete, obtain hitlsConfig and check whether the main configurations are +* consistent with the settings. Expected result 2 is obtained. +* @expect 1. Complete initialization +* 2. Consistent results +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_CONFIG_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + const HITLS_Config *cfgFromCtx = NULL; + cfgFromCtx = HITLS_GetConfig(client->ssl); + ASSERT_TRUE(cfgFromCtx != NULL); + ASSERT_EQ(cfgFromCtx->signAlgorithmsSize, sizeof(signAlgs) / sizeof(uint16_t)); + ASSERT_TRUE(memcmp(cfgFromCtx->signAlgorithms, signAlgs, cfgFromCtx->signAlgorithmsSize) == 0); + ASSERT_EQ(cfgFromCtx->isSupportRenegotiation, true); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_CURRENT_CIPHER_FUNC_TC001 +* @title HITLS_GetCurrentCipher Obtain the negotiated cipher suite pointer after initialization and before negotiation +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 is obtained +* 2. Before link establishment, call HITLS_GetCurrentCipher to obtain the negotiated cipher suite pointer. +* Expected result 2 is returned. +* @expect 1. Complete initialization +* 2. Return NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_CURRENT_CIPHER_FUNC_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + tlsConfig = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + CONN_Init(ctx); + ASSERT_TRUE(ctx != NULL); + + const HITLS_Cipher *hitlsCipher = HITLS_GetCurrentCipher(ctx); + ASSERT_EQ(hitlsCipher->cipherSuite, 0); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GET_RANDOM_FUNC_TC001 +* @title tls1.3 Obtain clientRandom and serverRandom +* @precon nan +* @brief 1. establish connection +* 2. Obtain and compare clientRandom and serverRandom. +* @expect 1. Return success +* 2. The clientRandom stored on the server is the same as that sent by the client, and the serverRandom stored +8 on the client is the same as that sent by the server. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_RANDOM_FUNC_TC001(void) +{ + HandshakeTestInfo testInfo = {0}; + HITLS_CryptMethodInit(); + FRAME_Init(); + + testInfo.config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(testInfo.config != NULL); + + testInfo.client = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.client != NULL); + + testInfo.server = FRAME_CreateLink(testInfo.config, BSL_UIO_TCP); + ASSERT_TRUE(testInfo.server != NULL); + + FRAME_CreateConnection(testInfo.client, testInfo.server, true, HS_STATE_BUTT); + + uint8_t clientRandom[RANDOM_SIZE]; + uint8_t serverRandom[RANDOM_SIZE]; + uint32_t randomSize = RANDOM_SIZE; + + ASSERT_TRUE(HITLS_GetRandom(testInfo.client->ssl, g_clientRandom, &randomSize, true) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRandom(testInfo.server->ssl, clientRandom, &randomSize, true) == HITLS_SUCCESS); + ASSERT_TRUE(randomSize == RANDOM_SIZE); + ASSERT_TRUE(memcmp(g_clientRandom, clientRandom, RANDOM_SIZE) == 0); + + ASSERT_TRUE(HITLS_GetRandom(testInfo.server->ssl, g_serverRandom, &randomSize, false) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRandom(testInfo.client->ssl, serverRandom, &randomSize, false) == HITLS_SUCCESS); + ASSERT_TRUE(randomSize == RANDOM_SIZE); + ASSERT_TRUE(memcmp(g_serverRandom, serverRandom, RANDOM_SIZE) == 0); +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/* @ +* @test HITLS_GetHandShakeState change state to alerting, obtain the state +* @title UT_TLS_CM_GET_HANDSHAKE_STATE_FUNC_TC001 +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 is obtained +* 2. When an alerting message is generated during data transmission, invoke HITLS_GetHandShakeState to stop +* sending the alerting message and obtain the current status. Expected result 2 is obtained +* @expect 1. Complete initialization +* 2. Return TLS_CONNECTED +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_HANDSHAKE_STATE_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + config->isSupportRenegotiation = true; + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + client->ssl->method.sendAlert(client->ssl, ALERT_LEVEL_WARNING, ALERT_NO_CERTIFICATE_RESERVED); + ret = ALERT_Flush(client->ssl); + ASSERT_EQ(ret, HITLS_SUCCESS); + uint32_t state = 0; + ret = HITLS_GetHandShakeState(client->ssl, &state); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(state, TLS_CONNECTED); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test HITLS_GetStateString Query the handshake status in sequence. +* @title UT_TLS_CM_GET_STATE_STRING_FUNC_TC001 +* @precon nan +* @brief 1. Invoke the HITLS_GetStateString interface and transfer values 0-30 and 255 at a time. Expected result 1. +* @expect 1. The interface returns the corresponding handshake status. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_STATE_STRING_FUNC_TC001() +{ + const char goalStr[31][32] = { + "idle", + "connected", + "send hello request", + "send client hello", + "send hello verify request", + "send hello retry request", + "send server hello", + "send encrypted extensions", + "send certificate", + "send server key exchange", + "send certificate request", + "send server hello done", + "send client key exchange", + "send certificate verify", + "send new session ticket", + "send change cipher spec", + "send end of early data", + "send finished", + "recv client hello", + "recv hello verify request", + "recv server hello", + "recv encrypted extensions", + "recv certificate", + "recv server key exchange", + "recv certificate request", + "recv server hello done", + "recv client key exchange", + "recv certificate verify", + "recv new session ticket", + "recv end of early data", + "recv finished", + }; + int32_t ret; + for (uint32_t i = 0; i <= 30; i++) { + ret = strcmp(HITLS_GetStateString(i), goalStr[i]); + ASSERT_TRUE(strcmp(HITLS_GetStateString(i), goalStr[i]) == 0); + } + ASSERT_TRUE(strcmp(HITLS_GetStateString(255), "unknown") == 0); +exit: + return; +} +/* END_CASE */ + +/* @ +* @test HITLS_IsHandShaking function point test +* @title UT_TLS_CM_IS_HANDSHAKING_FUNC_TC001 +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1. +* 2. Invoke the HITLS_IsHandShaking interface to check whether handshake is in progress. Expected result 2. +* 3. Initiate a connection establishment request and invoke the HITLS_IsHandShaking interface during connection establishment. (Expected result 3) +* 4. Invoke HITLS_IsHandShaking to complete connection establishment. Expected result 4. +* 5. Invoke the HITLS_Renegotiate interface to initiate renegotiation. (Expected result 5.) +* 6. Invoke the HITLS_IsHandShaking interface to check whether the handshake is in progress. (Expected result 6) +* 7. After the renegotiation is complete, invoke the HITLS_IsHandShaking interface to check whether handshake is in progress. Expected result 7. +*@expect 1. Initialization is complete. +* 2. The interface output parameter is 0. +* 3. The interface output parameter is 1. +* 4. The interface output parameter is 0. +* 5. The state changes to the renegotiation state. +* 6. The output parameter of the interface is 1. +* 7. The interface output parameter is 0. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_IS_HANDSHAKING_FUNC_TC001(int version) +{ + FRAME_Init(); + uint8_t isHandShaking = 0; + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(tlsConfig != NULL); + tlsConfig->isSupportRenegotiation = true; + FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_IDLE); + ASSERT_TRUE(HITLS_IsHandShaking(clientTlsCtx, &isHandShaking) == HITLS_SUCCESS); + ASSERT_TRUE(isHandShaking == 0); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(HITLS_IsHandShaking(clientTlsCtx, &isHandShaking) == HITLS_SUCCESS); + ASSERT_TRUE(isHandShaking == 1); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(HITLS_IsHandShaking(clientTlsCtx, &isHandShaking) == HITLS_SUCCESS); + ASSERT_TRUE(isHandShaking == 0); + + if (version == HITLS_VERSION_TLS12) { + ASSERT_EQ(HITLS_Renegotiate(clientTlsCtx), HITLS_SUCCESS); + ASSERT_EQ(HITLS_Renegotiate(serverTlsCtx), HITLS_SUCCESS); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_RENEGOTIATION); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_RENEGOTIATION); + ASSERT_TRUE(HITLS_IsHandShaking(clientTlsCtx, &isHandShaking) == HITLS_SUCCESS); + ASSERT_TRUE(isHandShaking == 1); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(HITLS_IsHandShaking(clientTlsCtx, &isHandShaking) == HITLS_SUCCESS); + ASSERT_TRUE(isHandShaking == 0); + } +exit: + HITLS_CFG_FreeConfig(tlsConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_CM_HITLS_IsBeforeHandShake_FUNC_TC001 + * @title HITLS_IsBeforeHandShake Check whether the handshake is not performed + * @percon NA + * @brief + * 1. Initialize the client and server. Expected result 1 + * 2. Call HITLS_IsBeforeHandShake to check whether the handshake has not been performed. Expected result 2 + * 3. During transporting, call HITLS_IsBeforeHandShake to check whether the handshake has not been performed + * Expected result 3 + * 4. Establish a connection and invoke the HITLS_IsBeforeHandShake interface to check whether the handshake + * has not been performed.Expected result 4 + * @expect + * 1. Initialization is complete + * 2. isBefore will be 1 + * 3. isBefore will be 0 + * 4. isBefore will be 0 + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_IsBeforeHandShake_FUNC_TC001(int version) +{ + FRAME_Init(); + int ret = 0; + uint8_t isBefore = 0; + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ret = HITLS_IsBeforeHandShake(client->ssl, &isBefore); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_IDLE); + ASSERT_TRUE(isBefore == 1); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + + ret = HITLS_IsBeforeHandShake(client->ssl, &isBefore); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_HANDSHAKING); + ASSERT_TRUE(isBefore == 0); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(client->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(isBefore == 0); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_CM_HITLS_GetClientVersion_FUNC_TC001 + * @title HITLS_GetClientVersion Obtains the client and server version numbers + * after initialization and before negotiation. + * @percon NA + * @brief + * 1. Initialize the client and server. Expected result 1 + * 2. Call HITLS_GetClientVersion to obtain the client and server version numbers. Expected result 2 + * @expect + * 1. Completing the initialization + * 2. The interface returns all 0s + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetClientVersion_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + uint16_t clientVersion = HITLS_VERSION_TLS12; + ASSERT_TRUE(HITLS_GetClientVersion(client->ssl, &clientVersion) == HITLS_SUCCESS); + uint16_t serverVersion = HITLS_VERSION_TLS12; + ASSERT_TRUE(HITLS_GetClientVersion(server->ssl, &serverVersion) == HITLS_SUCCESS); + ASSERT_EQ(clientVersion, 0); + ASSERT_EQ(serverVersion, 0); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_CM_HITLS_IsClient_FUNC_TC001 + * @title Testing the HITLS_IsClient + * @percon NA + * @brief + * 1. Enter an empty TLS connection handle. Expected result 1 + * 2. Enter a non-empty TLS connection handle and leave isClient empty. Expected result 1 + * 3. Enter a non-empty TLS connection handle and leave isClient not empty. Expected result 2 + * @expect + * 1. Return HITLS_NULL_INPUT + * 2. Return HITLS_SUCCESS + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_IsClient_FUNC_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool isClient = 0; + ASSERT_TRUE(HITLS_IsClient(ctx, &isClient) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_IsClient(ctx, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_IsClient(ctx, &isClient) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** +* @test HITLS_GetSharedGroup Obtain the first supported peer group when only one curve is matched on the client and +server. +* @title UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC001 +* @precon nan +* @brief +* 1. Initialize the client and server. Expected result 1 +* 2. Configure the client and server to support only one elliptic curve (the number of intersection groups is 1). +Expected result 2 +* 3. Establish a connection and invoke the HITLS_GetSharedGroup interface to obtain the first supported peer group +(Expected result 3) +* @expect +* 1. Initialization is complete +* 2. The setting is successful +* 3. The interface returns the supported elliptic curve +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC001(int version) +{ + FRAME_Init(); + int ret; + uint16_t groupId; + + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint16_t groups_c[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + + uint16_t groups_s[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetSharedGroup(server->ssl, 1, &groupId); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(groupId == HITLS_EC_GROUP_SECP256R1); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetSharedGroup Obtain the second supported peer group if only one matching curve exists on the client and + * server. + * @title UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC002 + * @precon nan + * @brief + * 1. Initialize the client and server. Expected result 1 + * 2. Configure only one elliptic curve supported by the client and server. Expected result 2 + * 3. Establish a connection and invoke the HITLS_GetSharedGroup interface to obtain the second supported peer group, + * Expected result 3 + * @expect + * 1. Initialization is complete + * 2. The setting is successful + * 3. The interface returns 0 + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC002(int version) +{ + FRAME_Init(); + int ret; + uint16_t groupId; + + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint16_t groups_c[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + + uint16_t groups_s[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetSharedGroup(server->ssl, 2, &groupId); + ASSERT_TRUE(ret == HITLS_INVALID_INPUT); + ASSERT_TRUE(groupId == 0); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetSharedGroup Obtain the second and third supported peer groups when the client and server have two + * matching curves. + * @title UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC003 + * @precon nan + * @brief + * 1. Initialize the client and server. Expected result 1 + * 2. Configure two elliptic curves supported by the client and server. Expected result 2 + * 3. Establish a connection. Invoke HITLS_GetSharedGroup to obtain the second supported peer group and the third + * supported peer group, Expected result 3 + * @expect + * 1. Initialization is complete + * 2. The setting is successful + * 3. The corresponding curve is returned for the first call and 0 is returned for the second call + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC003(int version) +{ + FRAME_Init(); + int ret; + uint16_t groupId; + + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint16_t groups_c[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + + uint16_t groups_s[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetSharedGroup(server->ssl, 2, &groupId); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(groupId == HITLS_EC_GROUP_SECP384R1); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetSharedGroup Obtain the first supported peer group when there is no matching curve on the client and + * server + * @title UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC004 + * @precon In the current framework, the TLS13 client and server do not have a matching curve. The TLS12 client and + * server can successfully establish a connection. The TLS13 framework capability needs to be supplemented + * @brief + * 1. Initialize the client and server, Expected result 1 + * 2. Configure the client and server not to support the elliptic curve. Expected result 2 + * 3. Establish a connection. After the parameters are negotiated, invoke the HITLS_GetSharedGroup interface to obtain + * the supported peer group. Expected result 3 + * @expect + * 1. Initialization is complete + * 2. The setting is successful + * 3. The interface returns 0 + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC004(int version) +{ + FRAME_Init(); + int ret; + uint16_t groupId; + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + uint16_t signWrtVersion = + (version == HITLS_VERSION_TLS12) ? CERT_SIG_SCHEME_RSA_PKCS1_SHA256 : CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint16_t groups_c[] = {HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {signWrtVersion, CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + + uint16_t groups_s[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = { + signWrtVersion, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + FRAME_CertInfo certInfo = { + "rsa_pss_sha256/rsa_pss_root.crt", + "rsa_pss_sha256/rsa_pss_intCa.crt", + "rsa_pss_sha256/rsa_pss_dev.crt", + 0, + "rsa_pss_sha256/rsa_pss_dev.key", + 0, + }; + + client = (version == HITLS_VERSION_TLS12) ? FRAME_CreateLink(config_c, BSL_UIO_TCP) + : FRAME_CreateLinkWithCert(config_c, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + server = (version == HITLS_VERSION_TLS12) ? FRAME_CreateLink(config_s, BSL_UIO_TCP) + : FRAME_CreateLinkWithCert(config_s, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(server != NULL); + + ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + ret = HITLS_GetSharedGroup(server->ssl, 1, &groupId); + ASSERT_TRUE(ret == HITLS_INVALID_INPUT); + ASSERT_TRUE(groupId == 0); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetSharedGroup If the matched elliptic curve exists, obtain the (-1)th supported peer group. + * @title UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC005 + * @precon nan + * @brief + * 1. Initialize the client and server. Expected result 1 + * 2. Configure two elliptic curves supported by the client and server. Expected result 2 + * 3. Establish a connection. Invoke HITLS_GetSharedGroup to obtain the (-1)th supported peer group. Expected result 3 + * @expect + * 1. Initialization is complete + * 2. The setting is successful + * 3. The interface returns 2 + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC005(int version) +{ + FRAME_Init(); + int ret; + uint16_t groupId; + + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint16_t groups_c[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_RSA_PKCS1_SHA256}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + + uint16_t groups_s[] = {HITLS_EC_GROUP_SECP256R1, HITLS_EC_GROUP_SECP384R1, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetSharedGroup(server->ssl, -1, &groupId); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(groupId == 2); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_TLS_CM_HITLS_SetVersionSupport_HITLS_GetVersionSupport_API_TC001 + * @title Test the HITLS_SetVersionSupport and HITLS_GetVersionSupport interfaces. + * @precon nan + * @brief + * HITLS_SetVersionSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Input a non-empty TLS connection handle and set the version to an invalid value. Expected result 2 + * 3. Input a non-empty TLS connection handle and set the version to a valid value. Expected result 3 + * HITLS_GetVersionSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Input an empty version pointer. Expected result 1 + * 3. Input a non-empty TLS connection handle and ensure that the version pointer is not empty. Expected result 4 + * @expect + * 1. Return HITLS_NULL_INPUT. + * 2. Return HITLS_SUCCESS, and invalid values in ctx->config.tlsConfig are filtered out + * 3. Return HITLS_SUCCESS is returned, and the value of ctx->config.tlsConfig is the expected value + * 4. Return HITLS_SUCCESS is returned and the value of version is the same as that recorded in config + */ + +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_SetVersionSupport_HITLS_GetVersionSupport_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint32_t version = 0; + + ASSERT_TRUE(HITLS_SetVersionSupport(ctx, version) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetVersionSupport(ctx, &version) == HITLS_NULL_INPUT); + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetVersionSupport(ctx, NULL) == HITLS_NULL_INPUT); + + version = (TLS13_VERSION_BIT << 1) | TLS13_VERSION_BIT | TLS12_VERSION_BIT; + ASSERT_TRUE(HITLS_SetVersionSupport(ctx, version) == HITLS_SUCCESS); + ASSERT_TRUE(ctx->config.tlsConfig.minVersion == HITLS_VERSION_TLS12 && + ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13); + version = TLS13_VERSION_BIT | TLS12_VERSION_BIT; + ASSERT_TRUE(HITLS_SetVersionSupport(ctx, version) == HITLS_SUCCESS); + ASSERT_TRUE(ctx->config.tlsConfig.minVersion == HITLS_VERSION_TLS12 && + ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13); + uint32_t getversion = 0; + ASSERT_TRUE(HITLS_GetVersionSupport(ctx, &getversion) == HITLS_SUCCESS); + ASSERT_TRUE(getversion == ctx->config.tlsConfig.version); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** +* @test UT_TLS_CM_HITLS_SetQuietShutdown_HITLS_GetQuietShutdown_API_TC001 +* @title Test the HITLS_SetQuietShutdown and HITLS_GetQuietShutdown interfaces +* @precon nan +* @brief +* HITLS_SetQuietShutdown +* 1. Input an empty TLS connection handle. Expected result 1 +* 2. Input a non-empty TLS connection handle and set mode to an invalid value. Expected result 2 +* 3. Input a non-empty TLS connection handle and set mode to a valid value. Expected result 3 +* HITLS_GetQuietShutdown +* 1. Input an empty TLS connection handle. Expected result 1 +* 2. Input an empty mode pointer. Expected result 1 +* 3. Input a non-empty TLS connection handle and ensure that the mode pointer is not empty. Expected result 3 +* @expect +* 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_CONFIG_INVALID_SET +* 3. Return HITLS_SUCCES +*/ + +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_SetQuietShutdown_HITLS_GetQuietShutdown_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + int32_t mode = 0; + + ASSERT_TRUE(HITLS_SetQuietShutdown(ctx, mode) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetQuietShutdown(ctx, &mode) == HITLS_NULL_INPUT); + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetQuietShutdown(ctx, NULL) == HITLS_NULL_INPUT); + mode = 1; + ASSERT_TRUE(HITLS_SetQuietShutdown(ctx, mode) == HITLS_SUCCESS); + mode = -1; + ASSERT_TRUE(HITLS_SetQuietShutdown(ctx, mode) == HITLS_CONFIG_INVALID_SET); + + int32_t getMode = -1; + ASSERT_TRUE(HITLS_GetQuietShutdown(ctx, &getMode) == HITLS_SUCCESS); + ASSERT_TRUE(getMode == true); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + + +/** + * @test UT_TLS_CM_HITLS_SetDhAutoSupport_API_TC001 + * @title Test HITLS_SetDhAutoSupport + * @precon nan + * @brief + * HITLS_SetDhAutoSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Input a non-empty TLS connection handle and set support to an invalid value. Expected result 2 + * 3. Input a non-empty TLS connection handle and set support to a valid value. Expected result 3 is displayed. + * @expect + * 1. Return HITLS_NULL_INPUT + * 2. Return HITLS_SUCCES, and isSupportDhAuto is ture + * 3. Return HITLS_SUCCES, and isSupportDhAuto is ture or false + */ + +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_SetDhAutoSupport_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool support = -1; + ASSERT_TRUE(HITLS_SetDhAutoSupport(ctx, support) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + support = true; + ASSERT_TRUE(HITLS_SetDhAutoSupport(ctx, support) == HITLS_SUCCESS); + support = -1; + ASSERT_TRUE(HITLS_SetDhAutoSupport(ctx, support) == HITLS_SUCCESS); + support = false; + ASSERT_TRUE(HITLS_SetDhAutoSupport(ctx, support) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_TMPDH_TC001 + * @spec - + * @title Test HITLS_SetTmpDh interface + * @precon nan + * @brief + * HITLS_SetTmpDh + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Input non-empty TLS connection handle information and leave dhPkey empty. Expected result 1 + * 3. Input the non-empty TLS connection handle information and ensure that dhPkey is not empty. Expected result 2 + * @expect + * 1. Return HITLS_NULL_INPUT + * 2. Return HITLS_SUCCES + */ + +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_SetTmpDh_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + HITLS_CRYPT_Key *dhPkey = SAL_CRYPT_GenerateDhKeyBySecbits(HITLS_SECURITY_LEVEL_THREE_SECBITS); + ASSERT_TRUE(HITLS_SetTmpDh(ctx, dhPkey) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_SetTmpDh(ctx, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_SetTmpDh(ctx, dhPkey) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test HITLS_GetPeerFinishVerifyData Obtaining Peer VerifyDATA After Link Establishment and Renegotiation Are Complete + * @title UT_TLS_CM_HITLS_GetPeerFinishVerifyData_FUNC_TC001 + * @precon nan + * @brief + * 1. Initialize the client and server and obtain the verifyDATA. Expected result 1. + * 2. Send a connection setup request. Expected result 2 + * 3. Call HITLS_GetPeerFinishVerifyData to obtain and store VerifyData. Expected result 3 + * 4. Perform renegotiation. Expected result 4 + * 5. Call HITLS_GetPeerFinishVerifyData to obtain VerifyData. Expected result 5 + * @expect + * 1. Return HITLS_SUCCESS and the len of verifyDATA is 0 + * 2. The connection is established. + * 3. Return HITLS_SUCCESS and the len of verifyDATA is not 0 + * 4. Renegotiation succeeded. + * 5. Return HITLS_SUCCESS and the verifyDATA is different from result 1 + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetPeerFinishVerifyData_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + + uint8_t verifyDataNew[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataNewSize = 0; + uint8_t verifyDataOld[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataOldSize = 0; + + uint32_t ret = + HITLS_GetPeerFinishVerifyData(serverTlsCtx, verifyDataOld, sizeof(verifyDataOld), &verifyDataOldSize); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(verifyDataOldSize, 0); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ret = HITLS_GetPeerFinishVerifyData(serverTlsCtx, verifyDataOld, sizeof(verifyDataOld), &verifyDataOldSize); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_NE(verifyDataOldSize, 0); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) != 0); + ASSERT_TRUE(memcpy_s(verifyDataOld, sizeof(verifyDataOld), verifyDataNew, verifyDataNewSize) == EOK); + + ASSERT_TRUE(HITLS_Renegotiate(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ret = HITLS_GetPeerFinishVerifyData(serverTlsCtx, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize); + ASSERT_EQ(ret, HITLS_SUCCESS); + + ASSERT_EQ(verifyDataNewSize, verifyDataOldSize); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) != 0); + ASSERT_TRUE(memcpy_s(verifyDataOld, sizeof(verifyDataOld), verifyDataNew, verifyDataNewSize) == EOK); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetFinishVerifyData: Obtains the verification data before a connection is established + * @title UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC001 + * @precon nan + * @brief + *1. Initialize the client and server. Expected result 1 + *2. Call HITLS_GetFinishVerifyData to obtain VerifyData. Expected result 2 + * @expect + *1. Completing the initialization + *2. The interface returns 0. + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + uint8_t verifyDataNew[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataNewSize = 0; + ASSERT_TRUE(HITLS_GetFinishVerifyData(server->ssl, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize) == + HITLS_SUCCESS); + ASSERT_EQ(verifyDataNewSize, 0); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetFinishVerifyData Obtain VerifyDATA after connection establishment + * @title UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC002 + * @precon nan + * @brief + * 1. Initialize the client and server. Expected result 1 + * 2. Send a link setup request. Expected result 2 + * 3. Call HITLS_GetFinishVerifyData to obtain VerifyData. Expected result 3 + * @expect + * 1. Completing the initialization + * 2. The connection is established + * 3. The value returned by the interface is not 0 + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC002(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + uint8_t verifyDataNew[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataNewSize = 0; + ASSERT_TRUE(HITLS_GetFinishVerifyData(server->ssl, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize) == + HITLS_SUCCESS); + ASSERT_NE(verifyDataNewSize, 0); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test HITLS_GetFinishVerifyData Obtains VerifyDATA after link establishment and renegotiation. +* @title UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC003 +* @precon nan +* @brief +* 1. Initialize the client and server. Expected result +* 2. Send a connection setup request. Expected result 2 +* 3. Call HITLS_GetFinishVerifyData to obtain and store VerifyData. Expected result 3 +* 4. Perform renegotiation. Expected result 4 +* 5. Call HITLS_GetFinishVerifyData to obtain VerifyData. Expected result 5 +* @expect +* 1. Complete the initialization +* 2. The link is established +* 3. The interface returns a value other than 0 +* 4. Renegotiation succeeded +* 5. Inconsistent with the first link establishmen +*/ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC003(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + config->isSupportRenegotiation = true; + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config, 1), HITLS_SUCCESS); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + + uint16_t cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256; + int32_t ret = HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1); + ASSERT_EQ(ret, HITLS_SUCCESS); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + uint8_t verifyDataNew[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataNewSize = 0; + uint8_t verifyDataOld[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataOldSize = 0; + + ASSERT_TRUE(HITLS_GetFinishVerifyData(server->ssl, verifyDataOld, sizeof(verifyDataOld), &verifyDataOldSize) == + HITLS_SUCCESS); + ASSERT_NE(verifyDataOldSize, 0); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + ASSERT_TRUE(HITLS_Renegotiate(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(HITLS_GetFinishVerifyData(serverTlsCtx, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize) == + HITLS_SUCCESS); + + ASSERT_TRUE(verifyDataNewSize == verifyDataOldSize); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) != 0); + ASSERT_TRUE(memcpy_s(verifyDataOld, sizeof(verifyDataOld), verifyDataNew, verifyDataNewSize) == EOK); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +int32_t SendHelloReq(HITLS_Ctx *ctx) +{ + int32_t ret; + uint8_t buf[HS_MSG_HEADER_SIZE] = {0u}; + size_t len = HS_MSG_HEADER_SIZE; + + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, buf, len); + return ret; +} + +/** + * @test UT_TLS_CM_HITLS_GetRenegotiationState_FUNC_TC001 + * @title Verifying the HITLS_GetRenegotiationState Interface + * @precon nan + * @brief + * 1. After the client and server are initialized, initiate a connection establishment request. Expected result 1 + * 2. Call the HITLS_GetRenegotiationState interface to query the renegotiation status. Expected result 2 + * 3. The server invokes the hitls_renegotiate interface to initiate renegotiation and invokes the + * HITLS_GetRenegotiationState interface to query the renegotiation status on the server. Expected result 3 + * 4. After receiving the hello request, the client invokes the HITLS_GetRenegotiationState interface + * to query the renegotiation status. Expected result 4 + * 5. After receiving the client hello message, the server invokes the HITLS_GetRenegotiationState interface to query + * the renegotiation status. Expected result 5 + * 6. After the renegotiation is complete, call the HITLS_GetRenegotiationState interface to query the renegotiation + * status on the client and server. Expected result 6 + * 7. The client invokes the hitls_renegotiate interface to initiate renegotiation and invokes the + * HITLS_GetRenegotiationState interface to query the renegotiation status. Expected result 7 + * @expect + * 1. The connection is successfully established + * 2. The return value is false + * 3. The return value is true + * 4. The return value is true + * 5. The return value is true + * 6. The return value is flase + * 7. The return value is true + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetRenegotiationState_FUNC_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + uint8_t isRenegotiation = true; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_SetRenegotiationSupport(server->ssl, true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(client->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(server->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == true); + + ASSERT_TRUE(SendHelloReq(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS); + ASSERT_EQ(HITLS_Connect(client->ssl), HITLS_REC_NORMAL_RECV_BUF_EMPTY); + ASSERT_TRUE(HITLS_GetRenegotiationState(server->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_HELLO), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(server->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == true); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(server->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == false); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationState(server->ssl, &isRenegotiation) == HITLS_SUCCESS); + ASSERT_TRUE(isRenegotiation == true); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} + +/* END_CASE */ + +/** + * @test Verifying the HITLS_GetRwstate Interface + * @title UT_TLS_CM_HITLS_GetRwstate_FUNC_TC001 + * @precon nan + * @brief + * 1. After the initialization, invoke the HITLS_GetRwstate interface to query data. Expected result 1 + * 2. When reading data, set ruio to null, construct a read exception, and call the HITLS_GetRwstate interface for + * query. Expected result 2 + * 3. When writing data, set uio to null, construct a write exception, and call the HITLS_GetRwstate interface for + * query. Expected result 3 + * @expect + * 1. The returned status is nothing + * 2. The returned status is reading + * 3. The returned status is writing + */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetRwstate_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + uint8_t rwstate = HITLS_READING; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + uint32_t ret = HITLS_GetRwstate(client->ssl, &rwstate); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(rwstate, HITLS_NOTHING); + + void *tmpUio = client->ssl->rUio; + client->ssl->rUio = NULL; + BSL_UIO_Free(tmpUio); + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen = 0; + ret = HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen); + ret = HITLS_GetRwstate(client->ssl, &rwstate); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(rwstate, HITLS_READING); + + tmpUio = client->ssl->uio; + client->ssl->uio = NULL; + BSL_UIO_Free(tmpUio); + + FRAME_TrasferMsgBetweenLink(client, server); + HITLS_Accept(server->ssl); + ASSERT_EQ(ret, HITLS_SUCCESS); + uint8_t writeBuf[100] = {0}; + ret = HITLS_Write(client->ssl, writeBuf, sizeof(writeBuf)); + ret = HITLS_GetRwstate(client->ssl, &rwstate); + ASSERT_EQ(ret, HITLS_SUCCESS); + ASSERT_EQ(rwstate, HITLS_WRITING); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_CLIENTVERIFYSUPPORT_API_TC001 + * @title Test the HITLS_SetClientVerifySupport and HITLS_GetClientVerifySupport interfaces. + * @precon nan + * @brief + * HITLS_SetClientVerifySupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer non-empty TLS connection handle information and set support to an invalid value. Expected result 2 + * 3. Transfer the non-empty TLS connection handle information and set support to a valid value. Expected result 3 + * HITLS_GetClientVerifySupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer an empty isSupport pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the isSupport pointer is not null. + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned + * 2. Returns HITLS_SUCCES, isSupportClientVerify is true, and isSupportVerifyNone is false + * 3. HITLS_SUCCES is returned, isSupportClientVerify is true or false, and isSupportVerifyNone and isSupportVerifyNone + * are mutually exclusive, but can be false at the same time + */ +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_CLIENTVERIFYSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_SetClientVerifySupport(ctx, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetClientVerifySupport(ctx, &isSupport) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetClientVerifySupport(ctx, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_SetClientVerifySupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(config->isSupportVerifyNone == false); + + support = -1; + ASSERT_TRUE(HITLS_SetClientVerifySupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetClientVerifySupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_SetClientVerifySupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetClientVerifySupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_NOCLIENTCERTSUPPORT_API_TC001 + * @title Test the HITLS_SetNoClientCertSupport and HITLS_GetClientVerifySupport interfaces + * @precon nan + * @brief + * HITLS_SetNoClientCertSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer non-empty TLS connection handle information and set support to an invalid value. Expected result 2 + * 3. Transfer the non-empty TLS connection handle information and set support to a valid value. Expected result 3 + * HITLS_GetNoClientCertSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer an empty isSupport pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the isSupport pointer is not null + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned. + * 2. HITLS_SUCCES is returned and isSupportNoClientCert is true + * 3. Returns HITLS_SUCCES and isSupportNoClientCert is true or false + */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_NOCLIENTCERTSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_SetNoClientCertSupport(ctx, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetNoClientCertSupport(ctx, &isSupport) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetNoClientCertSupport(ctx, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_SetNoClientCertSupport(ctx, support) == HITLS_SUCCESS); + + support = -1; + ASSERT_TRUE(HITLS_SetNoClientCertSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetNoClientCertSupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_SetNoClientCertSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetNoClientCertSupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_VERIFYNONESUPPORT_API_TC001 + * @title Test the HITLS_SetVerifyNoneSupport and HITLS_GetVerifyNoneSupport interfaces + * @precon nan + * @brief + * HITLS_SetVerifyNoneSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer non-empty TLS connection handle information and set support to an invalid value. Expected result 2 + * 3. Transfer the non-empty TLS connection handle information and set support to a valid value. Expected result 3 + * HITLS_GetVerifyNoneSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer an empty isSupport pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the isSupport pointer is not null + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned + * 2. Returns HITLS_SUCCES, isSupportVerifyNone is true, and isSupportClientVerify is false + * 3. HITLS_SUCCES is returned, isSupportVerifyNone is true or false, isSupportClientVerify and isSupportClientVerify + * are mutually exclusive, but can be false at the same time + */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_VERIFYNONESUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_SetVerifyNoneSupport(ctx, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetVerifyNoneSupport(ctx, &isSupport) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetVerifyNoneSupport(ctx, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_SetVerifyNoneSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(config->isSupportClientVerify == false); + + support = -1; + ASSERT_TRUE(HITLS_SetVerifyNoneSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetVerifyNoneSupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_SetVerifyNoneSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetVerifyNoneSupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_CLIENTONCEVERIFYSUPPORT_API_TC001 + * @title Test the HITLS_SetClientOnceVerifySupport and HITLS_GetClientOnceVerifySupport interfaces. + * @precon nan + * @brief + * HITLS_SetClientOnceVerifySupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer non-empty TLS connection handle information and set support to an invalid value. Expected result 2 + * 3. Transfer the non-empty TLS connection handle information and set support to a valid value. Expected result 3 + * HITLS_GetClientOnceVerifySupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer an empty isSupport pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the isSupport pointer is not null. + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned + * 2. HITLS_SUCCES is returned and isSupportPostHandshakeAuth is true + * 3. HITLS_SUCCES is returned and isSupportPostHandshakeAuth is true or false + */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_CLIENTONCEVERIFYSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_SetClientOnceVerifySupport(ctx, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetClientOnceVerifySupport(ctx, &isSupport) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetClientOnceVerifySupport(ctx, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_SetClientOnceVerifySupport(ctx, support) == HITLS_SUCCESS); + + support = -1; + ASSERT_TRUE(HITLS_SetClientOnceVerifySupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetClientOnceVerifySupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_SetClientOnceVerifySupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetClientOnceVerifySupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +int32_t NoSecRenegotiationCb(HITLS_Ctx *ctx) +{ + (void)ctx; + return HITLS_SUCCESS; +} + +/** +* @test Verifying the HITLS_ClearRenegotiationNum Interface +* @title UT_HITLS_CM_HITLS_ClearRenegotiationNum_FUNC_TC001 +* @precon nan +* @brief +* 1. After initialization, invoke the HITLS_ClearRenegotiationNum interface to query data. Expected result 1 +* 2. After the link is set up, invoke the HITLS_ClearRenegotiationNum interface to query the link. Expected result 2 +* 3. Initiate renegotiation. After the renegotiation is successful, invoke the HITLS_ClearRenegotiationNum interface to +check the values of the client and server. Expected result 3 +* 4. Initiate another five renegotiations. After the negotiation is complete, invoke the HITLS_ClearRenegotiationNum +interface to query the values of the client and server. Expected result 4 +* 5. Invoke the HITLS_ClearRenegotiationNum interface again to query the values on the client and server. Expected +result 5 +* 6. The client initiates renegotiation. The server rejects the renegotiation. Invoke the HITLS_ClearRenegotiationNum +interface to query the values of the client and server. Expected result 6 +* @expect +* 1. The value is 0 +* 2. The value is 0 +* 3. The value is 1 +* 4. The value is 0 +* 5. The value is 0 +* 6. The value is 1 for the client and 0 for the server +*/ +/* BEGIN_CASE */ +void UT_HITLS_CM_HITLS_ClearRenegotiationNum_FUNC_TC001(int version) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + uint16_t signAlgs[] = {CERT_SIG_SCHEME_RSA_PKCS1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256}; + HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)); + config->isSupportRenegotiation = true; + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + HITLS_Ctx *serverTlsCtx = FRAME_GetTlsCtx(server); + uint32_t renegotiationNum = 0; + + ASSERT_TRUE(HITLS_ClearRenegotiationNum(clientTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); + ASSERT_TRUE(HITLS_ClearRenegotiationNum(serverTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); + + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_ClearRenegotiationNum(clientTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); + ASSERT_TRUE(HITLS_ClearRenegotiationNum(serverTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); + + uint8_t verifyDataNew[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataNewSize = 0; + uint8_t verifyDataOld[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataOldSize = 0; + ASSERT_TRUE(HITLS_GetFinishVerifyData(serverTlsCtx, verifyDataOld, sizeof(verifyDataOld), &verifyDataOldSize) == + HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Renegotiate(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(HITLS_GetFinishVerifyData(serverTlsCtx, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize) == + HITLS_SUCCESS); + + ASSERT_TRUE(verifyDataNewSize == verifyDataOldSize); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) != 0); + ASSERT_TRUE(memcpy_s(verifyDataOld, sizeof(verifyDataOld), verifyDataNew, verifyDataNewSize) == EOK); + + ASSERT_TRUE(HITLS_ClearRenegotiationNum(clientTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 1); + ASSERT_TRUE(HITLS_ClearRenegotiationNum(serverTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 1); + + for (int i = 0; i < 5; ++i) { + ASSERT_TRUE(HITLS_Renegotiate(serverTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(HITLS_GetFinishVerifyData(serverTlsCtx, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize) == + HITLS_SUCCESS); + + ASSERT_TRUE(verifyDataNewSize == verifyDataOldSize); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) != 0); + ASSERT_TRUE(memcpy_s(verifyDataOld, sizeof(verifyDataOld), verifyDataNew, verifyDataNewSize) == EOK); + } + + ASSERT_TRUE(HITLS_ClearRenegotiationNum(clientTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 5); + ASSERT_TRUE(HITLS_ClearRenegotiationNum(serverTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 5); + + ASSERT_TRUE(HITLS_ClearRenegotiationNum(clientTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); + ASSERT_TRUE(HITLS_ClearRenegotiationNum(serverTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); + + ASSERT_TRUE(HITLS_Renegotiate(clientTlsCtx) == HITLS_SUCCESS); + + serverTlsCtx->negotiatedInfo.isSecureRenegotiation = false; + serverTlsCtx->config.tlsConfig.noSecRenegotiationCb = NoSecRenegotiationCb; + clientTlsCtx->config.tlsConfig.noSecRenegotiationCb = NoSecRenegotiationCb; + + ASSERT_TRUE(FRAME_CreateRenegotiation(client, server) == HITLS_SUCCESS); + ASSERT_TRUE(clientTlsCtx->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverTlsCtx->state == CM_STATE_TRANSPORTING); + + ASSERT_TRUE(HITLS_GetFinishVerifyData(serverTlsCtx, verifyDataNew, sizeof(verifyDataNew), &verifyDataNewSize) == + HITLS_SUCCESS); + + ASSERT_TRUE(verifyDataNewSize == verifyDataOldSize); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) == 0); + ASSERT_TRUE(memcpy_s(verifyDataOld, sizeof(verifyDataOld), verifyDataNew, verifyDataNewSize) == EOK); + + ASSERT_TRUE(HITLS_ClearRenegotiationNum(clientTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 1); + ASSERT_TRUE(HITLS_ClearRenegotiationNum(serverTlsCtx, &renegotiationNum) == HITLS_SUCCESS); + ASSERT_EQ(renegotiationNum, 0); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test HITLS_GetNegotiateGroup: EC cipher suite + * @spec - + * @title UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001 + * @precon nan + * @brief + * 1. Configure the two ends to use the EC cipher suite. Before connection establishment is complete, invoke the + * HITLS_GetNegotiateGroup interface to query the negotiated value. Expected result 1 + * 2. Configure the EC cipher suite to be used at both ends. After the connection is established, invoke the + * HITLS_GetNegotiateGroup interface to query the negotiated value. Expected result 2 + * @expect + * 1. The return value is 0 + * 2. The returned value is the negotiated value + */ +/* BEGIN_CASE */ +void UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001(int version) +{ + FRAME_Init(); + int ret; + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + uint16_t groupId; + uint16_t expectedGroupId = HITLS_EC_GROUP_SECP256R1; + uint16_t groups_c[] = {expectedGroupId, HITLS_EC_GROUP_SECP384R1}; + uint16_t signAlgs_c[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384}; + HITLS_CFG_SetGroups(config_c, groups_c, sizeof(groups_c) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_c, signAlgs_c, sizeof(signAlgs_c) / sizeof(uint16_t)); + + uint16_t groups_s[] = {expectedGroupId, HITLS_EC_GROUP_SECP521R1}; + uint16_t signAlgs_s[] = {CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512}; + HITLS_CFG_SetGroups(config_s, groups_s, sizeof(groups_s) / sizeof(uint16_t)); + HITLS_CFG_SetSignature(config_s, signAlgs_s, sizeof(signAlgs_s) / sizeof(uint16_t)); + + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, TRY_RECV_SERVER_HELLO), HITLS_SUCCESS); + ret = HITLS_GetNegotiateGroup(client->ssl, &groupId); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_EQ(groupId, 0); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + ret = HITLS_GetNegotiateGroup(client->ssl, &groupId); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_EQ(groupId, expectedGroupId); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** +* @test HITLS_GetNegotiateGroup interface uses the RSA cipher suite. +* @spec - +* @title UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002 +* @precon nan +* @brief +* 1. Set the RSA cipher suite to be used at both ends. After the connection is established, invoke the +HITLS_GetNegotiateGroup interface to query the negotiated value. Expected result 1 +* @expect +* 1. The return value of tls12 is 0. The prerequisite is that the cipher suite does not contain the (EC)DHE. The cipher +suite involved in key exchange must have the same group. tls13 is the negotiated group. The current framework supports +only ECDHE. Therefore, the connection can be successfully established only when the same EC group exists, The default +common curve is HITLS_EC_GROUP_CURVE25519. +*/ +/* BEGIN_CASE */ +void UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002(int version) +{ + FRAME_Init(); + int ret; + HITLS_Config *config_c = GetHitlsConfigViaVersion(version); + HITLS_Config *config_s = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + if (version == HITLS_VERSION_TLS12) { + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config_c, true), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetEncryptThenMac(config_s, true), HITLS_SUCCESS); + uint16_t cipherSuite = HITLS_RSA_WITH_AES_256_CBC_SHA; + ASSERT_EQ(HITLS_CFG_SetCipherSuites(config_c, &cipherSuite, 1), HITLS_SUCCESS); + } + FRAME_LinkObj *client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + FRAME_LinkObj *server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + uint16_t groupId; + uint16_t expectedGroupId = (version == HITLS_VERSION_TLS12) ? 0 : HITLS_EC_GROUP_CURVE25519; + ret = HITLS_GetNegotiateGroup(server->ssl, &groupId); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_EQ(groupId, expectedGroupId); + +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_CIPHERSERVERPREFERENCE_FUNC_TC001 + * @title Test the HITLS_SetCipherServerPreference and HITLS_GetCipherServerPreference interfaces + * @precon nan + * @brief + * HITLS_SetCipherServerPreference + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer a non-empty TLS connection handle and set isSupport to an invalid value. Expected result 2 + * 3. Transfer a non-empty TLS connection handle and set isSupport to a valid value. Expected result 3 + * HITLS_GetCipherServerPreference + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer an empty isSupport pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the isSupport pointer is not null. + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned + * 2. HITLS_SUCCES is returned and isSupportServerPreference is true + * 3. Returns HITLS_SUCCES and isSupportServerPreference is true or false + */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_CIPHERSERVERPREFERENCE_FUNC_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool isSupport = false; + bool getIsSupport = false; + ASSERT_TRUE(HITLS_SetCipherServerPreference(ctx, isSupport) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetCipherServerPreference(ctx, &getIsSupport) == HITLS_NULL_INPUT); + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetCipherServerPreference(ctx, NULL) == HITLS_NULL_INPUT); + isSupport = true; + ASSERT_TRUE(HITLS_SetCipherServerPreference(ctx, isSupport) == HITLS_SUCCESS); + isSupport = -1; + ASSERT_TRUE(HITLS_SetCipherServerPreference(ctx, isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(config->isSupportServerPreference = true); + isSupport = false; + ASSERT_TRUE(HITLS_SetCipherServerPreference(ctx, isSupport) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_GetCipherServerPreference(ctx, &getIsSupport) == HITLS_SUCCESS); + ASSERT_TRUE(getIsSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001 + * @title Test the HITLS_SetRenegotiationSupport and HITLS_GetRenegotiationSupport interfaces. + * @precon nan + * @brief + * HITLS_SetRenegotiationSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer non-empty TLS connection handle information and set support to an invalid value. Expected result 2 + * 3. Transfer the non-empty TLS connection handle information and set support to a valid value. Expected result 3 + * HITLS_GetRenegotiationSupport + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer an empty isSupport pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the isSupport pointer is not null. + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned + * 2. HITLS_SUCCES is returned and isSupportRenegotiation is true + * 3. HITLS_SUCCES is returned and isSupportRenegotiation is true or false + */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_SetRenegotiationSupport(ctx, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetRenegotiationSupport(ctx, &isSupport) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetRenegotiationSupport(ctx, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_SetRenegotiationSupport(ctx, support) == HITLS_SUCCESS); + + support = -1; + ASSERT_TRUE(HITLS_SetRenegotiationSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationSupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_SetRenegotiationSupport(ctx, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRenegotiationSupport(ctx, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** + * @test UT_HITLS_CM_SET_GET_FLIGHTTRANSMITSWITCH_FUNC_TC001 + * @title Test the HITLS_SetFlightTransmitSwitch and HITLS_GetFlightTransmitSwitch interfaces + * @precon nan + * @brief + * HITLS_SetFlightTransmitSwitch + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Transfer a non-empty TLS connection handle and set isEnable to an invalid value. Expected result 2 + * 3. Transfer a non-empty TLS connection handle and set isEnable to a valid value. Expected result 3 + * GetFlightTransmitSwitch + * 1. Input an empty TLS connection handle. Expected result 1 + * 2. Pass an empty getIsEnable pointer. Expected result 1 + * 3. Transfer the non-null TLS connection handle information and ensure that the getIsEnable pointer is not null. + * Expected result 3 + * @expect + * 1. HITLS_NULL_INPUT is returned + * 2. HITLS_SUCCES is returned and ctx->config.tlsConfig.isFlightTransmitEnable is true + * 3. Returns HITLS_SUCCES and ctx->config.tlsConfig.isFlightTransmitEnable is true or false + */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_FLIGHTTRANSMITSWITCH_FUNC_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t isEnable = -1; + uint8_t getIsEnable = -1; + ASSERT_TRUE(HITLS_SetFlightTransmitSwitch(ctx, isEnable) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetFlightTransmitSwitch(ctx, &getIsEnable) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetFlightTransmitSwitch(ctx, NULL) == HITLS_NULL_INPUT); + isEnable = 1; + ASSERT_TRUE(HITLS_SetFlightTransmitSwitch(ctx, isEnable) == HITLS_SUCCESS); + isEnable = -1; + ASSERT_TRUE(HITLS_SetFlightTransmitSwitch(ctx, isEnable) == HITLS_SUCCESS); + ASSERT_TRUE(ctx->config.tlsConfig.isFlightTransmitEnable = true); + isEnable = 0; + ASSERT_TRUE(HITLS_SetFlightTransmitSwitch(ctx, isEnable) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_GetFlightTransmitSwitch(ctx, &getIsEnable) == HITLS_SUCCESS); + ASSERT_TRUE(getIsEnable == false); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** +* @test UT_HITLS_CM_SET_GET_SetMaxCertList_FUNC_TC001 +* @title HTLS_CFG_SetMaxCertList, HITLS_CFG_GetMaxCertList, HITLS_SetMaxCertList, and HITLS_GetMaxCertList APIs +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx +* 2. Set the certificate chain length config to null and invoke the HITLS_CFG_SetMaxCertList interface +* 3. Invoke the HITLS_CFG_GetMaxCertList interface and check the output parameter value +* 4. Set the maximum length of the certificate chain by calling the HITLS_CFG_SetMaxCertList interface +* 5. Invoke the HITLS_CFG_GetMaxCertList interface and check the output parameter value +* 6. Set the minimum certificate chain length by calling the HITLS_CFG_SetMaxCertList interface +* 7. Invoke the HITLS_CFG_GetMaxCertList interface and check the output parameter value +* 8. Use the HITLS_SetMaxCertList and HITLS_GetMaxCertList interfaces to repeat the preceding test +* @expect +* 1. Initialization succeeds +* 2. HITLS_NULL_INPUT is returned +* 3. HITLS_NULL_INPUT is returned +* 4. The interface returns HITLS_SUCCESS +* 5. The value of MaxCertList returned by the interface is 2 ^ 32 - 1 +* 6. The interface returns the HITLS_SUCCESS +* 7. The value of MaxCertList returned by the interface is 0 +* 8. Same as above + +*/ +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_SetMaxCertList_FUNC_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig; + HITLS_Ctx *ctx = NULL; + tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + uint32_t maxSize; + // The config parameter is empty. + ASSERT_TRUE(HITLS_CFG_SetMaxCertList(NULL, MAX_CERT_LIST) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetMaxCertList(NULL, &maxSize) == HITLS_NULL_INPUT); + // Set the maximum value to 2 ^ 32 - 1. + ASSERT_TRUE(HITLS_CFG_SetMaxCertList(tlsConfig, MAX_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxCertList(tlsConfig, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MAX_CERT_LIST); + // Set the minimum value to 0. + ASSERT_TRUE(HITLS_CFG_SetMaxCertList(tlsConfig, MIN_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxCertList(tlsConfig, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MIN_CERT_LIST); + // The config parameter is empty. + ASSERT_TRUE(HITLS_SetMaxCertList(NULL, MAX_CERT_LIST) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetMaxCertList(NULL, &maxSize) == HITLS_NULL_INPUT); + // Set the maximum value to 2 ^ 32 - 1. + ASSERT_TRUE(HITLS_SetMaxCertList(ctx, MAX_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetMaxCertList(ctx, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MAX_CERT_LIST); + // Set the minimum value to 0. + ASSERT_TRUE(HITLS_SetMaxCertList(ctx, MIN_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetMaxCertList(ctx, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MIN_CERT_LIST); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ +void ExampleInfoCallback(const HITLS_Ctx *ctx, int32_t eventType, int32_t value) +{ + (void)ctx; + (void)eventType; + (void)value; +} + +uint64_t Test_RecordPaddingCb(HITLS_Ctx *ctx, int32_t type, uint64_t length, void *arg) +{ + (void)ctx; + (void)type; + (void)length; + (void)arg; + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_CM_InfoCb_API_TC001 +* @title InfoCb Interface Parameter Test +* @precon nan +* @brief +1. Use the HITLS_GetInfoCb without HITLS_CFG_SetInfoCb. Expected result 1 is obtained. +2. Use the HITLS_SetInfoCb interface to set callback. Expected result 2 +3. Use the HITLS_GetInfoCb . Expected result 3 +4. Use the HITLS_GetInfoCb with the parameter is NULL . Expected result 4 +* @expect +1. Return the NULL. +2. Return the HITLS_SUCCESS +3. Return value is not NULL. +4. Return the NULL. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_InfoCb_API_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(config != NULL); + FRAME_LinkObj *client = FRAME_CreateLink(config, BSL_UIO_SCTP); + ASSERT_TRUE(client != NULL); + HITLS_Ctx *clientTlsCtx = FRAME_GetTlsCtx(client); + ASSERT_TRUE(clientTlsCtx != NULL); + HITLS_InfoCb infoCallBack = HITLS_GetInfoCb(clientTlsCtx); + ASSERT_TRUE(infoCallBack == NULL); + int32_t ret = HITLS_SetInfoCb(clientTlsCtx, ExampleInfoCallback); + ASSERT_TRUE(ret == HITLS_SUCCESS); + infoCallBack = HITLS_GetInfoCb(clientTlsCtx); + ASSERT_TRUE(infoCallBack != NULL); + infoCallBack = HITLS_GetInfoCb(NULL); + ASSERT_TRUE(infoCallBack == NULL); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); +} +/* END_CASE */ + +#define MSG_CB_PRINT_LEN 500 + +void msg_callback(int32_t writePoint, int32_t tlsVersion, int32_t contentType, const void *msg, + uint32_t msgLen, HITLS_Ctx *ctx, void *arg) +{ + (void)writePoint; + (void)tlsVersion; + (void)contentType; + (void)msg; + (void)msgLen; + (void)ctx; + (void)arg; +} + +/* @ +* @test UT_TLS_CM_SetMsgCb_API_TC001 +* @title HITLS_SetMsgCb Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetMsgCb interface to set callback. (Expected result 2) +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetMsgCb_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = NULL; + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(HITLS_SetMsgCb(NULL, msg_callback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetMsgCb(ctx, msg_callback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GetError_API_TC001 +* @title HITLS_GetError Interface Parameter Test +* @precon nan +* @brief 1. Set ctx to NULL. Expected result 1 is obtained. +2.Invoke the HITLS_GetError interface and send the return value. The expected result 2 is obtained +* @expect 1. Return the HITLS_ERR_SYSCALL message. +2. Link error codes are returned +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GetError_API_TC001(void) +{ + FRAME_Init(); + HITLS_Ctx *ctx = NULL; + HITLS_Config *config = NULL; + config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_GetError(NULL, HITLS_SUCCESS) == HITLS_ERR_SYSCALL); + ASSERT_TRUE(HITLS_GetError(ctx, HITLS_SUCCESS) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SetAlpnProtos_API_TC001 +* @title HITLS_SetAlpnProtos Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +* @expect +1. Return the HITLS_NULL_INPUT message. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetAlpnProtos_API_TC001() +{ + HitlsInit(); + uint8_t * alpnProtosname = (uint8_t *)"vpn|http"; + uint32_t alpnProtosnameLen = sizeof(alpnProtosname); + ASSERT_TRUE(HITLS_SetAlpnProtos(NULL, alpnProtosname, alpnProtosnameLen) == HITLS_NULL_INPUT); +exit: + return; +} +/* END_CASE */ + +uint32_t SetPskClientCallback(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, + uint8_t *psk, uint32_t maxPskLen) +{ + (void)ctx; + (void)hint; + (void)identity; + (void)maxIdentityLen; + (void)psk; + (void)maxPskLen; + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_CM_SetPskClientCallback_API_TC001 +* @title HITLS_SetPskClientCallback Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetPskClientCallback interface to set callback. Expected result 2 +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetPskClientCallback_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = NULL; + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(HITLS_SetPskClientCallback(NULL, SetPskClientCallback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetPskClientCallback(ctx, SetPskClientCallback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +static uint32_t SetPskServerCallback(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen) +{ + (void)ctx; + (void)identity; + (void)psk; + (void)maxPskLen; + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_CM_SetPskServerCallback_API_TC001 +* @title HITLS_SetPskServerCallback Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetPskServerCallback interface to set callback. Expected result 2 +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetPskServerCallback_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = NULL; + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(HITLS_SetPskServerCallback(NULL, SetPskServerCallback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetPskServerCallback(ctx, SetPskServerCallback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +static int32_t SetPskUsePsksessionCallback(HITLS_Ctx *ctx, uint32_t hashAlgo, const uint8_t **id, + uint32_t *idLen, HITLS_Session **session) +{ + (void)ctx; + (void)hashAlgo; + (void)id; + (void)idLen; + (void)session; + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_CM_SetPskUseSessionCallback_API_TC001 +* @title HITLS_SetPskUseSessionCallback Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetPskUseSessionCallback interface to set callback. Expected result 2 +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetPskUseSessionCallback_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = NULL; + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(HITLS_SetPskUseSessionCallback(NULL, SetPskUsePsksessionCallback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetPskUseSessionCallback(ctx, SetPskUsePsksessionCallback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +int32_t SetPskFindSessionCallback(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, + HITLS_Session **session) +{ + (void)ctx; + (void)identity; + (void)identityLen; + (void)session; + return HITLS_SUCCESS; +} + +/* @ +* @test UT_TLS_CM_SetPskFindSessionCallback_API_TC001 +* @title HITLS_SetPskFindSessionCallback Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetPskFindSessionCallback interface to set callback. Expected result 2 +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetPskFindSessionCallback_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = NULL; + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(HITLS_SetPskFindSessionCallback(NULL, SetPskFindSessionCallback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetPskFindSessionCallback(ctx, SetPskFindSessionCallback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SetNeedCheckPmsVersion_API_TC001 +* @title HITLS_SetNeedCheckPmsVersion Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetNeedCheckPmsVersion interface to set parameter true. Expected result 2 +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetNeedCheckPmsVersion_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = NULL; + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_EQ(HITLS_SetNeedCheckPmsVersion(NULL, true), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetNeedCheckPmsVersion(ctx, true), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SetPskIdentityHint_API_TC001 +* @title HITLS_SetPskIdentityHint Interface Parameter Test +* @precon nan +* @brief +1. Set ctx to NULL. Expected result 1 is obtained. +2. Use the HITLS_SetPskIdentityHint interface to set parameter. Expected result 2 +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SetPskIdentityHint_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + uint8_t * identityH = (uint8_t *)"123456"; + uint32_t identityHintLen = strlen((char *)identityH); + ASSERT_TRUE(HITLS_SetPskIdentityHint(ctx, identityH, identityHintLen) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); + return; +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SETTICKETNUMS_API_TC001 +* @title HITLS_SetTicketNums interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_SetTicketNums interface and set the input parameter of the HITLS_Ctx to NULL. +* 3. Invoke the HITLS_SetTicketNums interface and set the input parameter of the ticketNums to 0. +* 4. Invoke the HITLS_SetTicketNums interface and set normal ticketNums. +* @expect +* 1. Initialization succeeded. +* 2. The interface returns HITLS_NULL_INPUT. +* 3. The interface returns HITLS_SUCCESS. +* 4. The interface returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SETTICKETNUMS_API_TC001() +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(HITLS_SetTicketNums(NULL, 0), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetTicketNums(ctx, 0), HITLS_SUCCESS); + ASSERT_EQ(HITLS_SetTicketNums(ctx, 3), HITLS_SUCCESS); + ASSERT_EQ(HITLS_SetTicketNums(ctx, 100), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GETTICKETNUMS_API_TC001 +* @title HITLS_GetTicketNums interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_GetRecordPaddingCb interface and set the input parameter of the HITLS_Ctx to NULL. +* 3. Invoke the HITLS_GetRecordPaddingCb interface to get the default ticketNums. +* 4. Invoke the HITLS_GetRecordPaddingCb interface and set normal ticketNums. +* 5. Invoke the HITLS_GetRecordPaddingCb interface to get the ticketNums +* @expect +* 1. Initialization succeeded. +* 2. The interface returns ticketNums is 2. +* 3. The interface returns HITLS_NULL_INPUT. +* 4. The interface returns HITLS_SUCCESS. +* 5. Consistent with the configured ticketNums. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GETTICKETNUMS_API_TC001() +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewTLS13Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + const int defaultNum = 2; + int TicketNum = 3; + ASSERT_EQ(HITLS_GetTicketNums(NULL), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_GetTicketNums(ctx), defaultNum); + ASSERT_EQ(HITLS_SetTicketNums(ctx, TicketNum), HITLS_SUCCESS); + ASSERT_EQ(HITLS_GetTicketNums(ctx), TicketNum); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SETRECORDPADDINGCB_API_TC001 +* @title HITLS_SetRecordPaddingCb interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_SetRecordPaddingCb interface and set the input parameter of the HITLS_Ctx to NULL. +* 3. Invoke the HITLS_SetRecordPaddingCb interface and set the input parameter of the callback to NULL. +* 4. Invoke the HITLS_SetRecordPaddingCb interface and set normal callback. +* @expect +* 1. Initialization succeeded. +* 2. The interface returns HITLS_NULL_INPUT. +* 3. The interface returns HITLS_SUCCESS. +* 4. The interface returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SETRECORDPADDINGCB_API_TC001() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(HITLS_SetRecordPaddingCb(NULL, 0), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetRecordPaddingCb(ctx, NULL), HITLS_SUCCESS); + ASSERT_EQ(HITLS_SetRecordPaddingCb(ctx, Test_RecordPaddingCb), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GETRECORDPADDINGCB_API_TC001 +* @title HITLS_GetRecordPaddingCb interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_GetRecordPaddingCb interface to get the default callback. +* 3. Invoke the HITLS_GetRecordPaddingCb interface and set the input parameter of the HITLS_Ctx to NULL. +* 4. Invoke the HITLS_GetRecordPaddingCb interface and set normal callback. +* 5. Invoke the HITLS_GetRecordPaddingCb interface to get the callback +* @expect +* 1. Initialization succeeded. +* 2. The interface returns NULL. +* 3. The interface returns HITLS_NULL_INPUT. +* 4. The interface returns HITLS_SUCCESS. +* 5. Consistent with the configured callback. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GETRECORDPADDINGCB_API_TC001() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(HITLS_GetRecordPaddingCb(ctx), NULL); + ASSERT_EQ(HITLS_GetRecordPaddingCb(NULL), NULL); + + ASSERT_TRUE(HITLS_SetRecordPaddingCb(ctx, Test_RecordPaddingCb) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetRecordPaddingCb(ctx) == Test_RecordPaddingCb); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SETRECORDPADDINGCBARG_API_TC001 +* @title HITLS_SetRecordPaddingCbArg interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_SetRecordPaddingCbArg interface and set the input parameter of the HITLS_Ctx to NULL. +* 3. Invoke the HITLS_SetRecordPaddingCbArg interface and set the input parameter of the RecordPaddingArg to NULL. +* 4. Invoke the HITLS_SetRecordPaddingCbArg interface and set normal recordPaddingArg. +* @expect +* 1. Initialization succeeded. +* 2. The interface returns HITLS_NULL_INPUT. +* 3. The interface returns HITLS_SUCCESS. +* 4. The interface returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SETRECORDPADDINGCBARG_API_TC001() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + uint32_t arg = 1; + + ASSERT_EQ(HITLS_SetRecordPaddingCbArg(NULL, &arg), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetRecordPaddingCbArg(ctx, NULL), HITLS_SUCCESS); + ASSERT_EQ(HITLS_SetRecordPaddingCbArg(ctx, &arg), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_GETRECORDPADDINGCBARG_API_TC001 +* @title HITLS_GetRecordPaddingCbArg interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_GetRecordPaddingCbArg interface to get the default recordPaddingArg. +* 3. Invoke the HITLS_GetRecordPaddingCbArg interface and set the input parameter of the HITLS_Ctx to NULL. +* 4. Invoke the HITLS_GetRecordPaddingCbArg interface and set normal recordPaddingArg. +* 5. Invoke the HITLS_GetRecordPaddingCbArg interface to get the recordPaddingArg. +* @expect +* 1. Initialization succeeded. +* 2. The interface returns NULL. +* 3. The interface returns HITLS_NULL_INPUT. +* 4. The interface returns HITLS_SUCCESS. +* 5. Consistent with the configured recordPaddingArg. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GETRECORDPADDINGCBARG_API_TC001() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + int arg = 1; + + ASSERT_EQ(HITLS_GetRecordPaddingCbArg(ctx), NULL); + ASSERT_EQ(HITLS_GetRecordPaddingCbArg(NULL), NULL); + + ASSERT_EQ(HITLS_SetRecordPaddingCbArg(ctx, &arg), HITLS_SUCCESS); + ASSERT_EQ(*(int*)HITLS_GetRecordPaddingCbArg(ctx) , arg); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SETCLOSECHECKKEYUSAGE_API_TC001 +* @title HITLS_SetCloseCheckKeyUsage interface test +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Invoke the HITLS_SetCloseCheckKeyUsage interface and set the input parameter of the HITLS_Ctx to NULL. +* 3. Invoke the HITLS_SetCloseCheckKeyUsage interface and set the input parameter of the isClose to true. +* 4. Invoke the HITLS_SetCloseCheckKeyUsage interface and set the input parameter of the isClose to false. +* @expect +* 1. Initialization succeeded. +* 2. The interface returns HITLS_NULL_INPUT. +* 3. The interface returns HITLS_SUCCESS. +* 4. The interface returns HITLS_SUCCESS. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SETCLOSECHECKKEYUSAGE_API_TC001() +{ + FRAME_Init(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_EQ(HITLS_SetCloseCheckKeyUsage(NULL, true), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetCloseCheckKeyUsage(ctx, true), HITLS_SUCCESS); + ASSERT_EQ(HITLS_SetCloseCheckKeyUsage(ctx, false), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +static int32_t STUB_ChangeState(TLS_Ctx *ctx, uint32_t nextState) +{ + int32_t ret = HITLS_SUCCESS; + if (HS_STATE_BUTT == nextState) { + if (true == ctx->isClient) { + ret = HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } + } + + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + hsCtx->state = nextState; + return ret; +} + +static bool StateCompare(FRAME_LinkObj *link, HITLS_HandshakeState state) +{ + if ((link->ssl->hsCtx != NULL) && (link->ssl->hsCtx->state == state)) { + if (state != TRY_RECV_FINISH) { + return true; + } + } + return false; +} + +/** @ +* @test UT_TLS_CM_HITLS_DOHANDSHAKE_API_TC001 +* @title HITLS_DoHandShake Interface Test +* @precon nan +* @brief 1、Invoke the HITLS_DoHandShake to create tls connect. The expected result 1 is obtained +* @expect 1、connect success +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_DOHANDSHAKE_API_TC001() +{ + FRAME_Init(); + HITLS_Config *config = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + int32_t clientRet; + int32_t serverRet; + int32_t ret; + uint32_t count = 0; + + FuncStubInfo tmpRpInfo = { 0 }; + STUB_Init(); + STUB_Replace(&tmpRpInfo, HS_ChangeState, STUB_ChangeState); + HITLS_SetEndPoint(client->ssl, true); + do { + if (StateCompare(client, HS_STATE_BUTT)) { + ret = HITLS_SUCCESS; + break; + } + clientRet = HITLS_DoHandShake(client->ssl); + if (clientRet != HITLS_SUCCESS) { + ret = clientRet; + if ((clientRet != HITLS_REC_NORMAL_IO_BUSY) && (clientRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + break; + } + } + ret = FRAME_TrasferMsgBetweenLink(client, server); + if (ret != HITLS_SUCCESS) { + break; + } + + if (StateCompare(server, HS_STATE_BUTT)) { + ret = HITLS_SUCCESS; + break; + } + serverRet = HITLS_DoHandShake(server->ssl); + if (serverRet != HITLS_SUCCESS) { + ret = serverRet; + if ((serverRet != HITLS_REC_NORMAL_IO_BUSY) && (serverRet != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + break; + } + } + ret = FRAME_TrasferMsgBetweenLink(server, client); + if (ret != HITLS_SUCCESS) { + break; + } + if (clientRet == HITLS_SUCCESS && serverRet == HITLS_SUCCESS) { + ret = HITLS_SUCCESS; + break; + } + count++; + ret = HITLS_INTERNAL_EXCEPTION; + } while (count < 40); + ASSERT_EQ(ret, HITLS_SUCCESS); +exit: + STUB_Reset(&tmpRpInfo); + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + + +/** @ +* @test UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC001 +* @title HITLS_GetSecurityLevel and HITLS_CFG_GetSecurityLevel Interface Test +* @precon nan +* @brief HITLS_GetSecurityLevel +1、Invoke HITLS_GetSecurityLevel to obtain the default security level. The expected result 1 is obtained +2、Check the obtained security level. The expected result 2 is obtained +HITLS_CFG_GetSecurityLevel +3、Invoke HITLS_CFG_GetSecurityLevel to obtain the default security level. The expected result 1 is obtained +4、Check the obtained security level. The expected result 2 is obtained +* @expect 1、return HITLS_SUCCESS +2、The security level is DEFAULT_SECURITYLEVEL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC001() +{ + HitlsInit(); + HITLS_Ctx *ctx = NULL; + HITLS_Config *Config; + int32_t level; + Config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(Config != NULL); + ctx = HITLS_New(Config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetSecurityLevel(ctx, &level) == HITLS_SUCCESS); + ASSERT_TRUE(level == DEFAULT_SECURITYLEVEL); + ASSERT_TRUE(HITLS_CFG_GetSecurityLevel(Config, &level) == HITLS_SUCCESS); + ASSERT_TRUE(level == DEFAULT_SECURITYLEVEL); +exit: + HITLS_CFG_FreeConfig(Config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC002 +* @title HITLS_SetSecurityLevel and HITLS_CFG_SetSecurityLevel Interface Parameter Test +* @precon nan +* @brief HITLS_SetSecurityLevel +1、Invoke the HITLS_SetSecurityLevel to configure the security level.The expected result 1 is obtained +2、Invoke HITLS_GetSecurityLevel to obtain the default security level. The expected result 2 is obtained +3、Check the obtained security level. The expected result 3 is obtained +HITLS_CFG_SetSecurityLevel +4、Invoke the HITLS_CFG_SetSecurityLevel to configure the security level.The expected result 1 is obtained +5、Invoke HITLS_GetSecurityLevel to obtain the default security level. The expected result 2 is obtained +6、Check the obtained security level. The expected result 3 is obtained +* @expect 1、return HITLS_SUCCESS +2、return HITLS_SUCCESS +3、The security level is equal to the configured security level. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC002() +{ + HitlsInit(); + HITLS_Ctx *ctx = NULL; + HITLS_Config *Config; + int32_t level; + Config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(Config != NULL); + ctx = HITLS_New(Config); + ASSERT_TRUE(ctx != NULL); + + for(int32_t i = 0; i <= 5; i++){ + ASSERT_TRUE(HITLS_SetSecurityLevel(ctx, i) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetSecurityLevel(ctx, &level) == HITLS_SUCCESS); + ASSERT_TRUE(level == i); + ASSERT_TRUE(HITLS_CFG_SetSecurityLevel(Config, i) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetSecurityLevel(Config, &level) == HITLS_SUCCESS); + ASSERT_TRUE(level == i); + } +exit: + HITLS_CFG_FreeConfig(Config); + HITLS_Free(ctx); +} +/* END_CASE */ + +int32_t TEST_HITLS_SecurityCb(const HITLS_Ctx *ctx, const HITLS_Config *config, int32_t option, + int32_t bits, int32_t id, void *other, void *exData) +{ + (void)ctx; + (void)config; + (void)option; + (void)bits; + (void)id; + (void)other; + (void)exData; + return HITLS_SUCCESS; +} + +/** @ +* @test UT_TLS_CM_SECURITY_SECURITYCB_API_TC001 +* @title HITLS_SetSecurityCb HITLS_SetSecurityExData HITLS_GetSecurityCb and HITLS_GetSecurityExData Interface Test +* @precon nan +* @brief 1、Invoke the HITLS_SetSecurityCb interface and set the first parameter to NULL. +The expected result 1 is obtained +2、Invoke the HITLS_SetSecurityCb interface and transfer the first parameter to a normal parameter. +The expected result 2 is obtained +3、Invoke the HITLS_SetSecurityExData interface and set the first parameter to NULL. The expected result 3 is obtained +4、Invoke the HITLS_SetSecurityExData interface and transfer the first parameter to a normal parameter. +The expected result 4 is obtained +5、Invoke the HITLS_GetSecurityCb interface and set the parameter to NULL. The expected result 5 is obtained +6、Invoke the HITLS_GetSecurityCb interface and transfer the parameter to a normal parameter. +The expected result 5 is obtained +7、Invoke the HITLS_GetSecurityExData interface and set the parameter to NULL. The expected result 7 is obtained +8、Invoke the HITLS_GetSecurityExData interface and transfer the parameter to a normal parameter. +The expected result 8 is obtained +* @expect 1、return HITLS_NULL_INPUT +2、 return HITLS_SUCCESS +3、 return HITLS_NULL_INPUT +4、 return HITLS_SUCCESS +5、 return NULL +6、 The returned value is equal to the configured value TEST_HITLS_SecurityCb. +7、 return NULL +8、 The returned value is equal to the configured value securityExData. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SECURITY_SECURITYCB_API_TC001() +{ + HitlsInit(); + HITLS_Ctx *ctx = NULL; + HITLS_Config *Config; + Config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(Config != NULL); + ctx = HITLS_New(Config); + int32_t userdata = 0; + void *securityExData = &userdata; + ASSERT_EQ(HITLS_SetSecurityCb(NULL, TEST_HITLS_SecurityCb), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetSecurityCb(ctx, TEST_HITLS_SecurityCb), HITLS_SUCCESS); + ASSERT_EQ(HITLS_SetSecurityExData(NULL, securityExData), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_SetSecurityExData(ctx, securityExData), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_GetSecurityCb(NULL), NULL); + ASSERT_EQ(HITLS_GetSecurityCb(ctx), TEST_HITLS_SecurityCb); + ASSERT_EQ(HITLS_GetSecurityExData(NULL), NULL); + ASSERT_EQ(HITLS_GetSecurityExData(ctx), securityExData); +exit: + HITLS_CFG_FreeConfig(Config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CM_SECURITY_SECURITYCB_API_TC002 +* @title HITLS_CFG_SetSecurityCb HITLS_CFG_SetSecurityExData HITLS_CFG_GetSecurityCb and +HITLS_CFG_GetSecurityExData Interface Test +* @precon nan +* @brief 1、Invoke the HITLS_CFG_SetSecurityCb interface and set the first parameter to NULL. +The expected result 1 is obtained +2、Invoke the HITLS_CFG_SetSecurityCb interface and transfer the first parameter to a normal parameter. +The expected result 2 is obtained +3、Invoke the HITLS_CFG_SetSecurityExData interface and set the first parameter to NULL. +The expected result 3 is obtained +4、Invoke the HITLS_CFG_SetSecurityExData interface and transfer the first parameter to a normal parameter. +The expected result 4 is obtained +5、Invoke the HITLS_CFG_GetSecurityCb interface and set the parameter to NULL. The expected result 5 is obtained +6、Invoke the HITLS_CFG_GetSecurityCb interface and transfer the parameter to a normal parameter. +The expected result 5 is obtained +7、Invoke the HITLS_CFG_GetSecurityExData interface and set the parameter to NULL. The expected result 7 is obtained +8、Invoke the HITLS_CFG_GetSecurityExData interface and transfer the parameter to a normal parameter. +The expected result 8 is obtained +* @expect 1、return HITLS_NULL_INPUT +2、 return HITLS_SUCCESS +3、 return HITLS_NULL_INPUT +4、 return HITLS_SUCCESS +5、 return NULL +6、 The returned value is equal to the configured value TEST_HITLS_SecurityCb. +7、 return NULL +8、 The returned value is equal to the configured value securityExData. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_SECURITY_SECURITYCB_API_TC002() +{ + HitlsInit(); + HITLS_Config *Config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(Config != NULL); + int32_t userdata = 0; + void *securityExData = &userdata; + ASSERT_EQ(HITLS_CFG_SetSecurityCb(NULL, TEST_HITLS_SecurityCb), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_CFG_SetSecurityCb(Config, TEST_HITLS_SecurityCb), HITLS_SUCCESS); + ASSERT_EQ(HITLS_CFG_SetSecurityExData(NULL, securityExData), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_CFG_SetSecurityExData(Config, securityExData), HITLS_SUCCESS); + + ASSERT_EQ(HITLS_CFG_GetSecurityCb(NULL), NULL); + ASSERT_EQ(HITLS_CFG_GetSecurityCb(Config), TEST_HITLS_SecurityCb); + ASSERT_EQ(HITLS_CFG_GetSecurityExData(NULL), NULL); + ASSERT_EQ(HITLS_CFG_GetSecurityExData(Config), securityExData); +exit: + HITLS_CFG_FreeConfig(Config); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_IS_DTLS_API_TC001 +* @title Test HITLS_IsDtls +* @precon nan +* @brief HITLS_IsDtls +* 1. Input an empty TLS connection handle. Expected result 1. +* 2. Transfer the non-empty TLS connection handle information and leave isDtls blank. Expected result 1. +* 3. Transfer the non-empty TLS connection handle information. The isDtls parameter is not empty. Expected result 2. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CM_IS_DTLS_API_TC001(int tlsVersion) +{ + HitlsInit(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t isDtls = 0; + ASSERT_TRUE(HITLS_IsDtls(ctx, &isDtls) == HITLS_NULL_INPUT); + + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_IsDtls(ctx, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_IsDtls(ctx, &isDtls) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + + +/*@ +* @test UT_TLS_CM_GET_SELECTEDALPNPROTO_API_TC001 +* +* @title test HITLS_GetSelectedAlpnProto interface +* @brief +* 1. Construct the CTX configuration. Expected result 1. +* 2. Construct the CTX connection handle. Expected result 1. +* 3. tls connection handle is NULL, Invoke the HITLS_GetSelectedAlpnProto interface. Expected result 2. +* 4. proto is NULL ,invoke the HITLS_CFG_SetSessionIdCtx interface.Expected result 2. +* 5. protoLen is NULL, Invoke the HITLS_GetSessionTicketKey interface.Expected result 2 +* @expect 1. Return not NULL. +* 2. Return not HITLS_NULL_INPUT. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CM_GET_SELECTEDALPNPROTO_API_TC001() +{ + HitlsInit(); + HITLS_Config *tlsConfig; + HITLS_Ctx *ctx = NULL; + + tlsConfig = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + + uint8_t * alpnProtosname = (uint8_t *)"vpn|http"; + uint32_t alpnProtosnameLen = sizeof(alpnProtosname); + ASSERT_TRUE(HITLS_GetSelectedAlpnProto(NULL, &alpnProtosname, &alpnProtosnameLen) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_GetSelectedAlpnProto(ctx, NULL, &alpnProtosnameLen), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_GetSelectedAlpnProto(ctx, &alpnProtosname, NULL), HITLS_NULL_INPUT); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); + return; +} +/* END_CASE */ + +#define DATA_MAX_LEN 1024 +/*@ +* @test UT_TLS_CM_GET_SET_SESSIONTICKETKEY_API_TC001 +* +* @title test HITLS_SetSessionTicketKey/HITLS_GetSessionTicketKey interface +* @brief 1. Construct the CTX connection handle. Expected result 1. +* 2. tls connection handle is NULL, Invoke the HITLS_SetSessionTicketKey interface. Expected result 2. +* 3. tls connection handle is NULL, Invoke the HITLS_GetSessionTicketKey interface.Expected result 2. +* @expect 1. Return not NULL. +* 2. Return HITLS_NULL_INPUT. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_GET_SET_SESSIONTICKETKEY_API_TC001(int version) +{ + FRAME_Init(); + uint8_t key[] = "748ab9f3dc1a23"; + HITLS_Config *config = GetHitlsConfigViaVersion(version); + + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + uint8_t getKey[DATA_MAX_LEN] = {0}; + uint32_t getKeySize = DATA_MAX_LEN; + uint32_t outSize = 0; + uint32_t ticketKeyRandLen = HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_SIZE + HITLS_TICKET_KEY_SIZE; + ASSERT_TRUE(HITLS_SetSessionTicketKey(NULL, key, ticketKeyRandLen) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetSessionTicketKey(NULL, getKey, getKeySize, &outSize) == HITLS_NULL_INPUT); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_SET_SESSIONIDCTX_API_TC001 +* +* @title test HITLS_CFG_SetSessionIdCtx interface +* @precon nan +* @brief 1. Construct the CTX connection handle. Expected result 1. +* 2. config is NULL, Invoke the HITLS_CFG_SetSessionIdCtx interface. Expected result 4. +* 3. invoke the HITLS_CFG_SetSessionIdCtx interface.Expected result 2. +* 4. tls connection handle is NULL, Invoke the HITLS_SetSessionIdCtx interface.Expected +* result 4. +* 5. Invoke the HITLS_SetSessionIdCtx interface. Expected result 2. +* @expect 1. Return not NULL. +* 2. Return not HITLS_NULL_INPUT. +* 3. Return NULL. +* 4. Return HITLS_NULL_INPUT. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CM_SET_SESSIONIDCTX_API_TC001(int version) +{ + FRAME_Init(); + char *key = "748ab9f3dc1a23"; + HITLS_Config *config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + + HITLS_Ctx *ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + uint32_t keyLen = strlen(key); + ASSERT_TRUE(HITLS_CFG_SetSessionIdCtx(NULL, (const uint8_t *)key, keyLen)== HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetSessionIdCtx(config, (const uint8_t *)key, keyLen)!= HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetSessionIdCtx(NULL, (const uint8_t *)key, keyLen)== HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetSessionIdCtx(ctx, (const uint8_t *)key, keyLen)!= HITLS_NULL_INPUT); + +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CM_HITLS_GetCertificate_API_TC001 +* @title Cover the input parameter of the HITLS_GetCertificate interface. +* @precon nan +* @brief 1. Invoke the HITLS_GetCertificate interface and leave ctx blank. Expected result 1. +* 2. Invoke the HITLS_GetPeerCertificate interface and leave ctx blank. Expected result 1. +* 3. Invoke the HITLS_GetPeerCertificate interface. The value of ctx is not empty and the value of ctx->session +* is empty. Expected result 1. +* 4. Invoke the HITLS_GetPeerCertChain interface and leave ctx blank. Expected result 1. +* 5. Invoke the HITLS_GetPeerCertChain interface. The value of ctx is not empty and the value of ctx->session is +* empty. Expected result 1. +* @expect 1.Return NULL +@ */ +/* BEGIN_CASE */ +void UT_TLS_CM_HITLS_GetCertificate_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_GetCertificate(NULL) == NULL); + ASSERT_TRUE(HITLS_GetPeerCertificate(NULL) == NULL); + ASSERT_TRUE(HITLS_GetPeerCertChain(NULL) == NULL); + ctx->session = NULL; + ASSERT_TRUE(HITLS_GetPeerCertificate(ctx) == NULL); + ASSERT_TRUE(HITLS_GetPeerCertChain(ctx) == NULL); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_HITLS_CM_HITLS_Set_and_Get_ErrorCode_API_TC001 +* @spec - +* @title Cover the input parameter of HITLS_SetChainStore and HITLS_GetChainStore interface +* @precon nan +* @brief 1. Invoke the HITLS_GetErrorCode interface and leave ctx blank. Expected result 1. + 2. Invoke the HITLS_GetErrorCode interface with ctx not empty. Expected result 3. + 3. Invoke the HITLS_SetErrorCode interface and leave ctx blank. Expected result 1. + 4. Invoke the HITLS_SetErrorCode interface. The value of ctx is not empty. Expected result 2. +* @expect 1. Return HITLS_NULL_INPUT + 2. Return HITLS_SUCCESS + 3. Return errorCode +* @prior Level 1 +* @auto TRUE +@ */ +/* BEGIN_CASE */ +void UT_HITLS_CM_HITLS_Set_and_Get_ErrorCode_API_TC001(int version) +{ + HitlsInit(); + HITLS_Config *tlsConfig = NULL; + HITLS_Ctx *ctx = NULL; + uint32_t errorCode = 0; + tlsConfig = HitlsNewCtx(version); + ASSERT_TRUE(tlsConfig != NULL); + + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + HITLS_SetErrorCode(ctx, errorCode); + ASSERT_TRUE(HITLS_GetErrorCode(NULL) == HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_GetErrorCode(ctx), errorCode); + ASSERT_TRUE(HITLS_SetErrorCode(ctx, errorCode) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_SetErrorCode(NULL, errorCode) == HITLS_NULL_INPUT); + +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ +/* @ +* @test UT_HITLS_CM_SET_GET_ENCRYPTTHENMAC_TC001 +* @title Test the HITLS_SetEncryptThenMac and HITLS_GetEncryptThenMac interfaces. +* @precon nan +* @brief HITLS_SetEncryptThenMac +* 1. Transfer an empty TLS connection handle. Expected result 1. +* 2. Transfer a non-empty TLS connection handle and set encryptThenMacType to an invalid value. Expected result 2. +* 3. Transfer a non-empty TLS connection handle and set encryptThenMacType to a valid value. Expected result 3. +* HITLS_GetEncryptThenMac +* 1. Transfer an empty TLS connection handle. Expected result 1. +* 2. Transfer an empty encryptThenMacType pointer. Expected result 1. +* 3. Transfer the non-null TLS connection handle information and ensure that the encryptThenMacType pointer is not null. Expected result 3. +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCES and isEncryptThenMac is True +* 3. Return HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_SET_GET_ENCRYPTTHENMAC_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint32_t encryptThenMacType = 0; + + ASSERT_TRUE(HITLS_SetEncryptThenMac(ctx, encryptThenMacType) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetEncryptThenMac(ctx, &encryptThenMacType) == HITLS_NULL_INPUT); + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetEncryptThenMac(ctx, NULL) == HITLS_NULL_INPUT); + encryptThenMacType = 1; + ASSERT_TRUE(HITLS_SetEncryptThenMac(ctx, encryptThenMacType) == HITLS_SUCCESS); + encryptThenMacType = -1; + ASSERT_TRUE(HITLS_SetEncryptThenMac(ctx, encryptThenMacType) == HITLS_SUCCESS); + ASSERT_TRUE(config->isEncryptThenMac = true); + + uint32_t getencryptThenMacType = -1; + ASSERT_TRUE(HITLS_GetEncryptThenMac(ctx, &getencryptThenMacType) == HITLS_SUCCESS); + ASSERT_TRUE(getencryptThenMacType == true); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/* @ +* @test UT_HITLS_CM_HITLS_GetPostHandshakeAuthSupport_TC001 +* @title Test the HITLS_GetPostHandshakeAuthSupport interfaces. +* @precon nan +* @brief 1. Transfer an empty TLS connection handle. Expected result 1. +* 2. Transfer a non-empty TLS connection handle and set isSupport to to NULL. Expected result 1. +* 3. Transfer a non-empty TLS connection handle and set isSupport to a valid value. Expected result 2. +* @expect 1. Return HITLS_NULL_INPUT +* 2. Return HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_HITLS_CM_HITLS_GetPostHandshakeAuthSupport_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint32_t isSupport = 0; + + ASSERT_TRUE(HITLS_GetPostHandshakeAuthSupport(NULL, NULL) == HITLS_NULL_INPUT); + config = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetEncryptThenMac(ctx, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_SetEncryptThenMac(ctx, isSupport) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cm_interface.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cm_interface.data new file mode 100644 index 00000000..f726662e --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_cm_interface.data @@ -0,0 +1,368 @@ +UT_TLS_CM_SET_GET_UIO_API_TC001 +UT_TLS_CM_SET_GET_UIO_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_READ_UIO_API_TC001 +UT_TLS_CM_SET_GET_READ_UIO_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_ENDPOINT_FUNC_TC001 +UT_TLS_CM_SET_ENDPOINT_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_ENDPOINT_FUNC_TC002 +UT_TLS_CM_SET_ENDPOINT_FUNC_TC002:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_MAXWRITESIZE_FUNC_TC001 +UT_TLS_CM_GET_MAXWRITESIZE_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_USR_DATA_API_TC001 +UT_TLS_CM_SET_GET_USR_DATA_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_SHUTDOWN_FUNC_TC001 +UT_TLS_CM_SET_SHUTDOWN_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_SHUTDOWN_FUNC_TC001 +UT_TLS_CM_GET_SHUTDOWN_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_NEGOTIATED_VERSION_FUNC_TC001 +UT_TLS_CM_GET_NEGOTIATED_VERSION_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_MAX_PROTO_VERSION_API_TC001 +UT_TLS_CM_SET_GET_MAX_PROTO_VERSION_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_GET_MIN_PROTO_VERSION_API_TC001 +UT_TLS_CM_SET_GET_MIN_PROTO_VERSION_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_IS_AEAD_FUNC_TC001 +UT_TLS_CM_IS_AEAD_FUNC_TC001:HITLS_VERSION_TLS13:HITLS_CHACHA20_POLY1305_SHA256 + +UT_TLS_CM_IS_AEAD_FUNC_TC001 +UT_TLS_CM_IS_AEAD_FUNC_TC001:HITLS_VERSION_TLS13:HITLS_AES_128_GCM_SHA256 + +UT_TLS_CM_IS_AEAD_FUNC_TC001 +UT_TLS_CM_IS_AEAD_FUNC_TC001:HITLS_VERSION_TLS12:HITLS_RSA_WITH_AES_128_CBC_SHA256 + +UT_TLS_CM_IS_HSDONE_FUNC_TC001 +UT_TLS_CM_IS_HSDONE_FUNC_TC001:HITLS_VERSION_TLS12:12 + +UT_TLS_CM_IS_HSDONE_FUNC_TC001 +UT_TLS_CM_IS_HSDONE_FUNC_TC001:HITLS_VERSION_TLS13:21 + +UT_TLS_CM_IS_HSDONE_FUNC_TC001 +UT_TLS_CM_IS_HSDONE_FUNC_TC001:HITLS_VERSION_TLS12:30 + +UT_TLS_CM_IS_HSDONE_FUNC_TC001 +UT_TLS_CM_IS_HSDONE_FUNC_TC001:HITLS_VERSION_TLS13:30 + +UT_TLS_CM_IS_HSDONE_FUNC_TC001 +UT_TLS_CM_IS_HSDONE_FUNC_TC001:HITLS_VERSION_TLS12:17 + +UT_TLS_CM_IS_HSDONE_FUNC_TC001 +UT_TLS_CM_IS_HSDONE_FUNC_TC001:HITLS_VERSION_TLS13:17 + +UT_TLS_CM_IS_HSDONE_FUNC_TC002 +UT_TLS_CM_IS_HSDONE_FUNC_TC002:HITLS_VERSION_TLS12 + +UT_TLS_CM_IS_SERVER_FUNC_TC001 +UT_TLS_CM_IS_SERVER_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_READHASPENDING_FUNC_TC001 +UT_TLS_CM_READHASPENDING_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_READPENDING_FUNC_TC001 +UT_TLS_CM_GET_READPENDING_FUNC_TC001: + +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC001 +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC002 +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC002:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC003 +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC003:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC004 +UT_TLS_CM_GET_PEER_SIGN_SCHEME_FUNC_TC004:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_LOCAL_SIGN_SCHEME_FUNC_TC001 +UT_TLS_CM_GET_LOCAL_SIGN_SCHEME_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_EC_GROUPS_FUNC_TC001 +UT_TLS_CM_SET_EC_GROUPS_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_SIGAL_LIST_FUNC_TC001 +UT_TLS_CM_SET_SIGAL_LIST_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_EC_POINT_FUNC_TC001 +UT_TLS_CM_SET_EC_POINT_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_CONFIG_FUNC_TC001 +UT_TLS_CM_GET_CONFIG_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_CURRENT_CIPHER_FUNC_TC001 +UT_TLS_CM_GET_CURRENT_CIPHER_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_RANDOM_FUNC_TC001 +UT_TLS_CM_GET_RANDOM_FUNC_TC001: + +UT_TLS_CM_GET_HANDSHAKE_STATE_FUNC_TC001 +UT_TLS_CM_GET_HANDSHAKE_STATE_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_STATE_STRING_FUNC_TC001 +UT_TLS_CM_GET_STATE_STRING_FUNC_TC001: + +UT_TLS_CM_IS_HANDSHAKING_FUNC_TC001 +UT_TLS_CM_IS_HANDSHAKING_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_IsBeforeHandShake_FUNC_TC001 +UT_TLS_CM_HITLS_IsBeforeHandShake_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetClientVersion_FUNC_TC001 +UT_TLS_CM_HITLS_GetClientVersion_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_IsClient_FUNC_TC001 +UT_TLS_CM_HITLS_IsClient_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC001 HITLS_VERSION_TLS12 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC001 HITLS_VERSION_TLS13 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC002 HITLS_VERSION_TLS12 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC002:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC002 HITLS_VERSION_TLS13 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC002:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC003 HITLS_VERSION_TLS12 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC003:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC003 HITLS_VERSION_TLS13 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC003:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC004 HITLS_VERSION_TLS12 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC004:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC005 HITLS_VERSION_TLS12 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC005:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC005 HITLS_VERSION_TLS13 HITLS_GetSharedGroup +UT_TLS_CM_HITLS_GetSharedGroup_FUNC_TC005:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_SetVersionSupport_HITLS_GetVersionSupport_API_TC001 +UT_TLS_CM_HITLS_SetVersionSupport_HITLS_GetVersionSupport_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_SetVersionSupport_HITLS_GetVersionSupport_API_TC001 +UT_TLS_CM_HITLS_SetVersionSupport_HITLS_GetVersionSupport_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_SetQuietShutdown_HITLS_GetQuietShutdown_API_TC001 +UT_TLS_CM_HITLS_SetQuietShutdown_HITLS_GetQuietShutdown_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_SetQuietShutdown_HITLS_GetQuietShutdown_API_TC001 +UT_TLS_CM_HITLS_SetQuietShutdown_HITLS_GetQuietShutdown_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_SetDhAutoSupport_API_TC001 +UT_TLS_CM_HITLS_SetDhAutoSupport_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_SetDhAutoSupport_API_TC001 +UT_TLS_CM_HITLS_SetDhAutoSupport_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_SetTmpDh_API_TC001 +UT_TLS_CM_HITLS_SetTmpDh_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_SetTmpDh_API_TC001 +UT_TLS_CM_HITLS_SetTmpDh_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetPeerFinishVerifyData_FUNC_TC001 HITLS_VERSION_TLS12 +UT_TLS_CM_HITLS_GetPeerFinishVerifyData_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC001 HITLS_VERSION_TLS13 +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC001 HITLS_VERSION_TLS12 +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC002 HITLS_VERSION_TLS13 +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC002:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC002 HITLS_VERSION_TLS12 +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC002:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC003 HITLS_VERSION_TLS12 +UT_TLS_CM_HITLS_GetFinishVerifyData_FUNC_TC003:HITLS_VERSION_TLS12 + +UT_TLS_CM_HITLS_GetRenegotiationState_FUNC_TC001 +UT_TLS_CM_HITLS_GetRenegotiationState_FUNC_TC001: + +UT_TLS_CM_HITLS_GetRwstate_FUNC_TC001 HITLS_VERSION_TLS13 +UT_TLS_CM_HITLS_GetRwstate_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetRwstate_FUNC_TC001 HITLS_VERSION_TLS12 +UT_TLS_CM_HITLS_GetRwstate_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_CLIENTVERIFYSUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_CLIENTVERIFYSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_CLIENTVERIFYSUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_CLIENTVERIFYSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_SET_GET_NOCLIENTCERTSUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_NOCLIENTCERTSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_NOCLIENTCERTSUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_NOCLIENTCERTSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_SET_GET_VERIFYNONESUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_VERIFYNONESUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_VERIFYNONESUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_VERIFYNONESUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_SET_GET_CLIENTONCEVERIFYSUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_CLIENTONCEVERIFYSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_CLIENTONCEVERIFYSUPPORT_API_TC001 +UT_HITLS_CM_SET_GET_CLIENTONCEVERIFYSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_HITLS_ClearRenegotiationNum_FUNC_TC001 HITLS_VERSION_TLS12 +UT_HITLS_CM_HITLS_ClearRenegotiationNum_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001 HITLS_VERSION_TLS12 HITLS_GetNegotiateGroup +UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001 HITLS_VERSION_TLS13 HITLS_GetNegotiateGroup +UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002 HITLS_VERSION_TLS12 HITLS_GetNegotiateGroup +UT_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_CIPHERSERVERPREFERENCE_FUNC_TC001 +UT_HITLS_CM_SET_GET_CIPHERSERVERPREFERENCE_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_CIPHERSERVERPREFERENCE_FUNC_TC001 +UT_HITLS_CM_SET_GET_CIPHERSERVERPREFERENCE_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001 +UT_HITLS_CM_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001 +UT_HITLS_CM_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_SET_GET_FLIGHTTRANSMITSWITCH_FUNC_TC001 +UT_HITLS_CM_SET_GET_FLIGHTTRANSMITSWITCH_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_FLIGHTTRANSMITSWITCH_FUNC_TC001 +UT_HITLS_CM_SET_GET_FLIGHTTRANSMITSWITCH_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_SET_GET_SetMaxCertList_FUNC_TC001 +UT_HITLS_CM_SET_GET_SetMaxCertList_FUNC_TC001: + +UT_TLS_CM_InfoCb_API_TC001 +UT_TLS_CM_InfoCb_API_TC001: + +UT_TLS_CM_SetMsgCb_API_TC001 +UT_TLS_CM_SetMsgCb_API_TC001: + +UT_TLS_CM_GetError_API_TC001 +UT_TLS_CM_GetError_API_TC001: + +UT_TLS_CM_SetAlpnProtos_API_TC001 +UT_TLS_CM_SetAlpnProtos_API_TC001: + +UT_TLS_CM_SetPskClientCallback_API_TC001 +UT_TLS_CM_SetPskClientCallback_API_TC001: + +UT_TLS_CM_SetPskServerCallback_API_TC001 +UT_TLS_CM_SetPskServerCallback_API_TC001: + +UT_TLS_CM_SetPskUseSessionCallback_API_TC001 +UT_TLS_CM_SetPskUseSessionCallback_API_TC001: + +UT_TLS_CM_SetPskFindSessionCallback_API_TC001 +UT_TLS_CM_SetPskFindSessionCallback_API_TC001: + +UT_TLS_CM_SetNeedCheckPmsVersion_API_TC001 +UT_TLS_CM_SetNeedCheckPmsVersion_API_TC001: + +UT_TLS_CM_SetPskIdentityHint_API_TC001 +UT_TLS_CM_SetPskIdentityHint_API_TC001: + +UT_TLS_CM_SETTICKETNUMS_API_TC001 +UT_TLS_CM_SETTICKETNUMS_API_TC001: + +UT_TLS_CM_GETTICKETNUMS_API_TC001 +UT_TLS_CM_GETTICKETNUMS_API_TC001: + +UT_TLS_CM_SETRECORDPADDINGCB_API_TC001 +UT_TLS_CM_SETRECORDPADDINGCB_API_TC001: + +UT_TLS_CM_GETRECORDPADDINGCB_API_TC001 +UT_TLS_CM_GETRECORDPADDINGCB_API_TC001: + +UT_TLS_CM_SETRECORDPADDINGCBARG_API_TC001 +UT_TLS_CM_SETRECORDPADDINGCBARG_API_TC001: + +UT_TLS_CM_GETRECORDPADDINGCBARG_API_TC001 +UT_TLS_CM_GETRECORDPADDINGCBARG_API_TC001: + +UT_TLS_CM_SETCLOSECHECKKEYUSAGE_API_TC001 +UT_TLS_CM_SETCLOSECHECKKEYUSAGE_API_TC001: + +UT_TLS_CM_HITLS_DOHANDSHAKE_API_TC001 +UT_TLS_CM_HITLS_DOHANDSHAKE_API_TC001: + +UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC001 +UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC001: + +UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC002 +UT_TLS_CM_SECURITY_SECURITYLEVEL_API_TC002: + +UT_TLS_CM_SECURITY_SECURITYCB_API_TC001 +UT_TLS_CM_SECURITY_SECURITYCB_API_TC001: + +UT_TLS_CM_SECURITY_SECURITYCB_API_TC002 +UT_TLS_CM_SECURITY_SECURITYCB_API_TC002: + +UT_TLS_CM_IS_DTLS_API_TC001 +UT_TLS_CM_IS_DTLS_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_IS_DTLS_API_TC001 +UT_TLS_CM_IS_DTLS_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_GET_SELECTEDALPNPROTO_API_TC001 +UT_TLS_CM_GET_SELECTEDALPNPROTO_API_TC001: + +UT_TLS_CM_GET_SET_SESSIONTICKETKEY_API_TC001 +UT_TLS_CM_GET_SET_SESSIONTICKETKEY_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_GET_SET_SESSIONTICKETKEY_API_TC001 +UT_TLS_CM_GET_SET_SESSIONTICKETKEY_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_SET_SESSIONIDCTX_API_TC001 +UT_TLS_CM_SET_SESSIONIDCTX_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CM_SET_SESSIONIDCTX_API_TC001 +UT_TLS_CM_SET_SESSIONIDCTX_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CM_HITLS_GetCertificate_API_TC001 +UT_TLS_CM_HITLS_GetCertificate_API_TC001:TLS1_2 + +UT_TLS_CM_HITLS_GetCertificate_API_TC001 +UT_TLS_CM_HITLS_GetCertificate_API_TC001:TLS1_3 + +UT_HITLS_CM_SET_GET_ENCRYPTTHENMAC_TC001 +UT_HITLS_CM_SET_GET_ENCRYPTTHENMAC_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_SET_GET_ENCRYPTTHENMAC_TC001 +UT_HITLS_CM_SET_GET_ENCRYPTTHENMAC_TC001:HITLS_VERSION_TLS13 + +UT_HITLS_CM_HITLS_Set_and_Get_ErrorCode_API_TC001 +UT_HITLS_CM_HITLS_Set_and_Get_ErrorCode_API_TC001:TLS1_2 + +UT_HITLS_CM_HITLS_Set_and_Get_ErrorCode_API_TC001 +UT_HITLS_CM_HITLS_Set_and_Get_ErrorCode_API_TC001:TLS1_3 + +UT_HITLS_CM_HITLS_GetPostHandshakeAuthSupport_TC001 +UT_HITLS_CM_HITLS_GetPostHandshakeAuthSupport_TC001:HITLS_VERSION_TLS12 + +UT_HITLS_CM_HITLS_GetPostHandshakeAuthSupport_TC001 +UT_HITLS_CM_HITLS_GetPostHandshakeAuthSupport_TC001:HITLS_VERSION_TLS13 \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_config_interface.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_config_interface.c new file mode 100644 index 00000000..a77d4e1c --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_config_interface.c @@ -0,0 +1,1434 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "sal_net.h" +#include "hitls.h" +#include "frame_tls.h" +#include "cert_callback.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "frame_io.h" +#include "uio_abstraction.h" +#include "tls.h" +#include "tls_config.h" +#include "logger.h" +#include "process.h" +#include "hs_ctx.h" +#include "hlt.h" +#include "stub_replace.h" +#include "hitls_type.h" +#include "frame_link.h" +#include "session_type.h" +#include "common_func.h" +#include "hitls_func.h" +#include "hitls_cert_type.h" +#include "cert_mgr_ctx.h" +#include "parser_frame_msg.h" +#include "recv_process.h" +#include "simulate_io.h" +#include "rec_wrapper.h" +#include "cipher_suite.h" +#include "alert.h" +#include "conn_init.h" +#include "pack.h" +#include "send_process.h" +#include "cert.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_type.h" +#include "hs.h" +#include "hs_state_recv.h" +#include "app.h" +#include "record.h" +#include "rec_conn.h" +#include "session.h" +#include "frame_msg.h" +#include "pack_frame_msg.h" +#include "cert_mgr.h" +#include "hs_extensions.h" +#include "hlt_type.h" +#include "sctp_channel.h" +#include "hitls_crypt_init.h" +/* END_HEADER */ + +#define DEFAULT_DESCRIPTION_LEN 128 +#define ERROR_HITLS_GROUP 1 +#define ERROR_HITLS_SIGNATURE 0xffffu +typedef struct { + uint16_t version; + BSL_UIO_TransportType uioType; + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_Session *clientSession; /* Set the session to the client for session resume. */ +} ResumeTestInfo; + +static HITLS_Config *GetHitlsConfigViaVersion(int ver) +{ + switch (ver) { + case TLS1_2: + case HITLS_VERSION_TLS12: + return HITLS_CFG_NewTLS12Config(); + case TLS1_3: + case HITLS_VERSION_TLS13: + return HITLS_CFG_NewTLS13Config(); + case DTLS1_2: + case HITLS_VERSION_DTLS12: + return HITLS_CFG_NewDTLS12Config(); + default: + return NULL; + } +} + +static int32_t UT_ClientHelloCb(HITLS_Ctx *ctx, int32_t *alert, void *arg) +{ + (void)ctx; + (void)alert; + return *(int32_t *)arg; +} + +/** @ +* @test UT_TLS_CFG_UPREF_FUNC_TC001 +* @spec - +* @title Invoke the HITLS_CFG_UpRef interface to change the number of config reference times. +* @precon nan +* @brief 1. Apply for and initialize config. + 2. Invoke the HITLS_CFG_UpRef interface and transfer the config parameter. + 3. Check the number of times the config file is referenced. +* @expect 1. The application is successful. + 2. The invoking is successful. + 3. The number of references is 2. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_UPREF_FUNC_TC001() +{ + HitlsInit(); + HITLS_Config *config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + ASSERT_TRUE(HITLS_CFG_UpRef(config) == HITLS_SUCCESS); + ASSERT_TRUE(config->references.count == 2); + HITLS_CFG_FreeConfig(config); + ASSERT_TRUE(config->references.count == 1); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + + +/** @ +* @test UT_TLS_CFG_SET_RESUMPTIONONRENEGOSUPPORT_API_TC001 +* @Specifications- +* @title Test the HITLS_CFG_SetResumptionOnRenegoSupport interface for setting ResumptionOnRenegoSupport. +* @preppynan +* @brief HITLS_CFG_Setting negotiation support +* 1. Transfer empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and support invalid values. Expected result 2 is displayed. +* 3. The input configuration information is not empty and the value can be valid. Expected result 3 is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and isResumptionOnRenego is set to true. +* 3. HITLS_SUCCES is returned and isResumptionOnRenego is set to true or false. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_RESUMPTIONONRENEGOSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + bool support = -1; + ASSERT_TRUE(HITLS_CFG_SetResumptionOnRenegoSupport(config, support) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_SetResumptionOnRenegoSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(config->isResumptionOnRenego == true); + + support = false; + ASSERT_TRUE(HITLS_CFG_SetResumptionOnRenegoSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(config->isResumptionOnRenego == false); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_NOCLIENTCERTSUPPORT_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetNoClientCertSupport and HITLS_CFG_GetNoClientVerifySupport interfaces. +* @precon nan +* @brief HITLS_CFG_SetNoClientCertSupport +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and set support to an invalid value. Expected result 2 is obtained. +* 3. Transfer non-empty configuration information and set support to a valid value. Expected result 3 is obtained. +* HITLS_CFG_GetNoClientCertSupport +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer an empty isSupport pointer. Expected result 1 is obtained. +* 3. Transfer the non-null configuration information and the isSupport pointer is not null. Expected result 3 is +* obtained. +* @expect 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and config->isSupportNoClientCert is true. +* 3. Returns HITLS_SUCCES and config->isSupportNoClientCert is true or false. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_NOCLIENTCERTSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_CFG_SetNoClientCertSupport(config, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetNoClientCertSupport(config, &isSupport) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetNoClientCertSupport(config, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_CFG_SetNoClientCertSupport(config, support) == HITLS_SUCCESS); + + support = -1; + ASSERT_TRUE(HITLS_CFG_SetNoClientCertSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetNoClientCertSupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_CFG_SetNoClientCertSupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetNoClientCertSupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_CLIENTVERIFYSUPPORT_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetClientVerifySupport and HITLS_CFG_GetClientVerifySupport interfaces. +* @precon nan +* @brief HITLS_CFG_SetClientVerifySupport +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and set support to an invalid value. Expected result 2 is obtained. +* 3. Transfer non-empty configuration information and set support to a valid value. Expected result 3 is obtained. +* HITLS_CFG_GetClientVerifySupport +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer an empty isSupport pointer. Expected result 1 is obtained. +* 3. Transfer the non-null configuration information and the isSupport pointer is not null. Expected result 3 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned, and config->isSupportClientVerify is true and isSupportVerifyNone is false. +* 3. HITLS_SUCCES is returned, and config->isSupportClientVerify is true or false. isSupportVerifyNone and +isSupportVerifyNone are mutually exclusive, but can be false at the same time. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_CLIENTVERIFYSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + bool support = -1; + uint8_t isSupport = -1; + ASSERT_TRUE(HITLS_CFG_SetClientVerifySupport(config, support) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetClientVerifySupport(config, &isSupport) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetClientVerifySupport(config, NULL) == HITLS_NULL_INPUT); + + support = true; + ASSERT_TRUE(HITLS_CFG_SetClientVerifySupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(config->isSupportVerifyNone == false); + + support = -1; + ASSERT_TRUE(HITLS_CFG_SetClientVerifySupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetClientVerifySupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == true); + + support = false; + ASSERT_TRUE(HITLS_CFG_SetClientVerifySupport(config, support) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetClientVerifySupport(config, &isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(isSupport == false); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + + + +/** @ +* @test UT_TLS_CFG_SET_TMPDH_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetTmpDh interface. +* @precon nan +* @brief HITLS_CFG_SetTmpDh +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and leave dhPkey empty. Expected result 1 is obtained. +* 3. Transfer non-empty configuration information and set dhPkey to a non-empty value. Expected result 2 is displayed. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_TMPDH_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_CRYPT_Key *dhPkey = SAL_CRYPT_GenerateDhKeyBySecbits(HITLS_SECURITY_LEVEL_THREE_SECBITS); + ASSERT_TRUE(HITLS_CFG_SetTmpDh(config, dhPkey) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_SetTmpDh(config, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_SetTmpDh(config, dhPkey) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_CLIENTHELLOCB_API_TC001 +* @title Test the HITLS_CFG_SetClientHelloCb interface. +* @precon nan +* @brief HITLS_CFG_SetClientHelloCb +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and leave callback empty. Expected result 1 is obtained. +* 3. Transfer non-empty configuration information and set callback to a non-empty value. Expected result 2 is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_CLIENTHELLOCB_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + int32_t cbRetVal = 0; + ASSERT_TRUE(HITLS_CFG_SetClientHelloCb(config, UT_ClientHelloCb, &cbRetVal) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_SetClientHelloCb(config, NULL, &cbRetVal) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_SetClientHelloCb(config, UT_ClientHelloCb, &cbRetVal) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +int32_t UT_NoSecRenegotiation(HITLS_Ctx *ctx) +{ + (void)ctx; + return HITLS_SUCCESS; +} + +/** @ +* @test UT_TLS_CFG_SET_NOSECRENEGOTIATIONCB_API_TC001 +* @titleTest the HITLS_CFG_SetNoSecRenegotiationCb interface. +* @precon nan +* @brief HITLS_CFG_SetNoSecRenegotiationCb +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and leave callback empty. Expected result 1 is obtained. +* 3. Transfer non-empty configuration information and set callback to a non-empty value. Expected result 2 is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_NOSECRENEGOTIATIONCB_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + + ASSERT_TRUE(HITLS_CFG_SetNoSecRenegotiationCb(config, UT_NoSecRenegotiation) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_SetNoSecRenegotiationCb(config, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_SetNoSecRenegotiationCb(config, UT_NoSecRenegotiation) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_VERSION_API_TC001 +* @title Test the HITLS_CFG_SetVersion, HITLS_CFG_GetMinVersion, and HITLS_CFG_GetMaxVersion interfaces. +* @precon nan +* @brief HITLS_CFG_SetVersion +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information, set minVersion to 0, and set maxVersion to a value other than 0. +* Expected result 2 is obtained. +* 3. Transfer non-empty configuration information, set minVersion to 0, and set maxVersion to 0. Expected result 3 is +* obtained. +* 4. Transfer non-empty configuration information, set minVersion to 0, and set maxVersion to 0. Expected result 4 is +* obtained. +* 5. Transfer non-empty configuration information, and set both minVersion and maxVersion to 0. Expected result 5 is +* obtained. +* 5. Transfer non-empty configuration information, set minVersion to dtls, and set maxVersion to dtls. Expected result 5 +* is obtained. +* 6. Transfer non-empty configuration information, set minVersion to TLCP, and set maxVersion to TLCP. Expected result 5 +* is obtained. +* HITLS_CFG_GetMinVersion +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer an empty MinVersion pointer. Expected result 1 is obtained. +* 3. Transfer the non-null configuration information and the MinVersion pointer is not null. Expected result 5 is +* obtained. +* HITLS_CFG_GetMaxVersion +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Pass an empty MaxVersion pointer. Expected result 1 is obtained. +* 3. Transfer non-null configuration information and ensure that the MaxVersion pointer is not null. Expected result 5 +* is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES and minVersion is HITLS_VERSION_SSL30. +* 3. Returns HITLS_SUCCES and maxVersion is HITLS_VERSION_TLS13. +* 4. The HITLS_SUCCES table is returned, and the version value is 0, which is cleared. +* 5. Returns HITLS_SUCCES with minVersion and maxVersion set to the configured values. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_VERSION_API_TC001(void) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + HITLS_Config *dtlsConfig = NULL; + HITLS_Config *tlcpConfig = NULL; + uint16_t minVersion = 0; + uint16_t maxVersion = 0; + + ASSERT_TRUE(HITLS_CFG_SetVersion(config, minVersion, maxVersion) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, &minVersion) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, &maxVersion) == HITLS_NULL_INPUT); + + config = HITLS_CFG_NewTLSConfig(); + dtlsConfig = HITLS_CFG_NewDTLSConfig(); + tlcpConfig = HITLS_CFG_NewTLCPConfig(); + + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_SetVersion(config, 0, 0) == HITLS_SUCCESS); + ASSERT_TRUE(config->version == 0); + + ASSERT_TRUE(HITLS_CFG_SetVersion(config, HITLS_VERSION_TLS12, HITLS_VERSION_TLS13) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, &minVersion) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, &maxVersion) == HITLS_SUCCESS); + ASSERT_TRUE(minVersion == HITLS_VERSION_TLS12 && maxVersion == HITLS_VERSION_TLS13); + + ASSERT_TRUE(HITLS_CFG_SetVersion(config, 0, HITLS_VERSION_TLS13) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, &minVersion) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, &maxVersion) == HITLS_SUCCESS); + ASSERT_TRUE(minVersion == HITLS_VERSION_TLS12 && maxVersion == HITLS_VERSION_TLS13); + ASSERT_TRUE(HITLS_CFG_SetVersion(config, HITLS_VERSION_TLS12, 0) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(config, &minVersion) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(config, &maxVersion) == HITLS_SUCCESS); + ASSERT_TRUE(minVersion == HITLS_VERSION_TLS12 && maxVersion == HITLS_VERSION_TLS13); + + ASSERT_TRUE(HITLS_CFG_SetVersion(dtlsConfig, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(dtlsConfig, &minVersion) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(dtlsConfig, &maxVersion) == HITLS_SUCCESS); + ASSERT_TRUE(minVersion == HITLS_VERSION_DTLS12 && maxVersion == HITLS_VERSION_DTLS12); + + ASSERT_TRUE(HITLS_CFG_SetVersion(tlcpConfig, HITLS_VERSION_TLCP11, HITLS_VERSION_TLCP11) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMinVersion(tlcpConfig, &minVersion) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxVersion(tlcpConfig, &maxVersion) == HITLS_SUCCESS); + ASSERT_TRUE(minVersion == HITLS_VERSION_TLCP11 && maxVersion == HITLS_VERSION_TLCP11); + +exit: + HITLS_CFG_FreeConfig(config); + HITLS_CFG_FreeConfig(dtlsConfig); + HITLS_CFG_FreeConfig(tlcpConfig); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_HASHID_API_TC001 +* @title Test the HITLS_CFG_GetHashId interface. +* @precon nan +* @brief +* 1. Input an empty cipher suite. Expected result 1 is obtained. +* 2. Transfer an empty hashId. Expected result 1 is obtained. +* 3. Import the HITLS_RSA_WITH_AES_128_CBC_SHA cipher suite and set hashAlg to HITLS_HASH_BUTT. Expected result 2 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCESS is returned and HashId is HITLS_HASH_SHA1. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_HASHID_API_TC001(void) +{ + const HITLS_Cipher *cipher = NULL; + HITLS_HashAlgo hashId = HITLS_HASH_BUTT; + ASSERT_TRUE(HITLS_CFG_GetHashId(cipher, &hashId) == HITLS_NULL_INPUT); + + const uint16_t cipherID = HITLS_RSA_WITH_AES_128_CBC_SHA; + cipher = HITLS_CFG_GetCipherByID(cipherID); + ASSERT_TRUE(HITLS_CFG_GetHashId(cipher, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_GetHashId(cipher, &hashId) == HITLS_SUCCESS); + ASSERT_TRUE(hashId == HITLS_HASH_SHA1); +exit: + return; +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_MACID_API_TC001 +* @title Test the HITLS_CFG_GetMacId interface. +* @precon nan +* @brief +* 1. Input an empty cipher suite. Expected result 1 is obtained. +* 2. Input an empty macAlg. Expected result 1 +* 3. Input the HITLS_RSA_WITH_AES_128_CBC_SHA cipher suite and set macAlg to HITLS_MAC_BUTT. Expected result 2 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCESS and macAlg is HITLS_MAC_1. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_MACID_API_TC001(void) +{ + const HITLS_Cipher *cipher = NULL; + HITLS_MacAlgo macAlg = HITLS_MAC_BUTT; + ASSERT_TRUE(HITLS_CFG_GetMacId(cipher, &macAlg) == HITLS_NULL_INPUT); + + const uint16_t cipherID = HITLS_RSA_WITH_AES_128_CBC_SHA; + cipher = HITLS_CFG_GetCipherByID(cipherID); + ASSERT_TRUE(HITLS_CFG_GetMacId(cipher, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_GetMacId(cipher, &macAlg) == HITLS_SUCCESS); + ASSERT_TRUE(macAlg == HITLS_MAC_1); +exit: + return; +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_KEYEXCHID_API_TC001 +* @title Test the HITLS_CFG_GetKeyExchId interface. +* @precon nan +* @brief +* 1. Input an empty cipher suite. Expected result 1 is obtained. +* 2. Input null kxAlg. Expected result 1 +* 3. Input the HITLS_RSA_WITH_AES_128_CBC_SHA cipher suite and set kxAlg to HITLS_KEY_EXCH_BUTT. Expected result 2 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCESS and kxAlg is HITLS_KEY_EXCH_RSA. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_KEYEXCHID_API_TC001(void) +{ + const HITLS_Cipher *cipher = NULL; + HITLS_KeyExchAlgo kxAlg = HITLS_KEY_EXCH_BUTT; + ASSERT_TRUE(HITLS_CFG_GetKeyExchId(cipher, &kxAlg) == HITLS_NULL_INPUT); + + const uint16_t cipherID = HITLS_RSA_WITH_AES_128_CBC_SHA; + cipher = HITLS_CFG_GetCipherByID(cipherID); + ASSERT_TRUE(HITLS_CFG_GetKeyExchId(cipher, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_GetKeyExchId(cipher, &kxAlg) == HITLS_SUCCESS); + ASSERT_TRUE(kxAlg == HITLS_KEY_EXCH_RSA); +exit: + return; +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_CIPHERSUITESTDNAME_API_TC001 +* @title Test the HITLS_CFG_GetCipherSuiteStdName interface. +* @precon nan +* @brief +* 1. Input an empty cipher suite. Expected result 1 is obtained. +* 2.Import the HITLS_RSA_WITH_AES_128_CBC_SHA cipher suite. Expected result 2 is obtained. +* @expect +* 1. Return "(NONE)" +* 2. Return "TLS_RSA_WITH_AES_128_CBC_SHA256" +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_CIPHERSUITESTDNAME_API_TC001(void) +{ + const HITLS_Cipher *cipher = NULL; + ASSERT_TRUE(strcmp((char *)HITLS_CFG_GetCipherSuiteStdName(cipher),"(NONE)") == 0); + + const uint16_t cipherID = HITLS_RSA_WITH_AES_128_CBC_SHA; + cipher = HITLS_CFG_GetCipherByID(cipherID); + ASSERT_TRUE(strcmp((char *)HITLS_CFG_GetCipherSuiteStdName(cipher),"TLS_RSA_WITH_AES_128_CBC_SHA") == 0); +exit: + return; +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_DESCRIPTION_API_TC001 +* @title Test the HITLS_CFG_GetDescription interface. +* @precon nan +* @brief +* 1. Input an empty cipher suite. Expected result 1 is obtained. +* 2. Input an empty buff. Expected result 1 is obtained. +* 3. Transfer a buff whose length is less than the length of CIPHERSUITE_DESCRIPTION_MAXLEN. Expected result 1 is +* obtained. +* 4. Transfer the abnormal algorithm name cipher suite. Expected result 2 is obtained. +* 5. Import the HITLS_RSA_WITH_AES_128_CBC_SHA cipher suite whose buff size is DEFAULT_DESCRIPTION_LEN. Expected result +* 3 is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_CONFIG_INVALID_LENGTH. +* 3. Returns HITLS_SUCCESS, and buff is Description. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_DESCRIPTION_API_TC001(void) +{ + const HITLS_Cipher *cipher = NULL; + char buff[DEFAULT_DESCRIPTION_LEN] = {0}; + ASSERT_TRUE(HITLS_CFG_GetDescription(cipher, (uint8_t *)buff, sizeof(buff)) == HITLS_NULL_INPUT); + + const uint16_t cipherID = HITLS_RSA_WITH_AES_128_CBC_SHA; + cipher = HITLS_CFG_GetCipherByID(cipherID); + + ASSERT_TRUE(HITLS_CFG_GetDescription(cipher, NULL, sizeof(buff)) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_GetDescription(cipher, (uint8_t *)buff, 0) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CFG_GetDescription(cipher, (uint8_t *)buff, sizeof(buff)) == HITLS_SUCCESS); + + HITLS_Cipher *newCipher = (HITLS_Cipher *)malloc(sizeof(HITLS_Cipher)); + memcpy(newCipher, cipher, sizeof(HITLS_Cipher)); + newCipher->name = + "************************************************************************************************************"; + + ASSERT_TRUE(HITLS_CFG_GetDescription(newCipher, (uint8_t *)buff, sizeof(buff)) == HITLS_CONFIG_INVALID_LENGTH); +exit: + free(newCipher); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_CIPHER_ISAEAD_API_TC001 +* @title Test the HITLS_CIPHER_IsAead interface. +* @precon nan +* @brief +* 1. Input an empty cipher suite. Expected result 1 is obtained. +* 2. Import the HITLS_RSA_WITH_AES_128_GCM_SHA256 cipher suite. Expected result 2 is obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCESS and isAead is true. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_CIPHER_ISAEAD_API_TC001(void) +{ + const HITLS_Cipher *cipher = NULL; + uint8_t isAead = false; + ASSERT_TRUE(HITLS_CIPHER_IsAead(cipher, &isAead) == HITLS_NULL_INPUT); + + const uint16_t cipherID = HITLS_RSA_WITH_AES_128_GCM_SHA256; + cipher = HITLS_CFG_GetCipherByID(cipherID); + ASSERT_TRUE(HITLS_CIPHER_IsAead(cipher, NULL) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_CIPHER_IsAead(cipher, &isAead) == HITLS_SUCCESS); + ASSERT_TRUE(isAead == true); +exit: + return; +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001 +* @spec - +* @title Test the HITLS_CFG_SetVersionSupport and HITLS_CFG_GetVersionSupport interfaces. +* @precon nan +* @brief HITLS_CFG_SetVersionSupport +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and set version to an invalid value. Expected result 2 is obtained. +* 3. Transfer non-empty configuration information and set version to a valid value. Expected result 3 is obtained. +* HITLS_CFG_GetVersionSupport +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Pass the null version pointer. Expected result 1 is obtained. +* 3. Transfer non-null configuration information and ensure that the version pointer is not null. Expected result 4 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned, and invalid values in config are filtered out. +* 3. HITLS_SUCCES is returned and config is the expected value. +* 4. The HITLS_SUCCES parameter is returned, and the version parameter is set to the value recorded in the config file. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint32_t version = 0; + + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetVersionSupport(config, &version) == HITLS_NULL_INPUT); + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetVersionSupport(config, NULL) == HITLS_NULL_INPUT); + + version = (TLS13_VERSION_BIT << 1) | TLS13_VERSION_BIT | TLS12_VERSION_BIT; + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + version = TLS13_VERSION_BIT | TLS12_VERSION_BIT; + ASSERT_TRUE(HITLS_CFG_SetVersionSupport(config, version) == HITLS_SUCCESS); + ASSERT_TRUE(config->minVersion == HITLS_VERSION_TLS12 && config->maxVersion == HITLS_VERSION_TLS13); + uint32_t getversion = 0; + ASSERT_TRUE(HITLS_CFG_GetVersionSupport(config, &getversion) == HITLS_SUCCESS); + ASSERT_TRUE(getversion == config->version); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_QUIETSHUTDOWN_API_TC001 +* @title Test the HITLS_CFG_SetQuietShutdown and HITLS_CFG_GetQuietShutdown interfaces. +* @precon nan +* @brief HITLS_CFG_SetQuietShutdown +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and set mode to an invalid value. Expected result 2 is obtained. +* 3. Transfer non-empty configuration information and set mode to a valid value. Expected result 3 is obtained. +* HITLS_CFG_GetQuietShutdown +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer a null mode pointer. Expected result 1 is obtained. +* 3. Transfer non-null configuration information and ensure that the mode pointer is not null. Expected result 3 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_CONFIG_INVALID_SET +* 3. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_QUIETSHUTDOWN_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + int32_t mode = 0; + + ASSERT_TRUE(HITLS_CFG_SetQuietShutdown(config, mode) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetQuietShutdown(config, &mode) == HITLS_NULL_INPUT); + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetQuietShutdown(config, NULL) == HITLS_NULL_INPUT); + mode = 1; + ASSERT_TRUE(HITLS_CFG_SetQuietShutdown(config, mode) == HITLS_SUCCESS); + mode = 2; + ASSERT_TRUE(HITLS_CFG_SetQuietShutdown(config, mode) == HITLS_CONFIG_INVALID_SET); + + int32_t getMode = -1; + ASSERT_TRUE(HITLS_CFG_GetQuietShutdown(config, &getMode) == HITLS_SUCCESS); + ASSERT_TRUE(getMode == config->isQuietShutdown); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_CIPHERSERVERPREFERENCE_API_TC001 +* @title Test the HITLS_CFG_SetCipherServerPreference and HITLS_CFG_GetCipherServerPreference interfaces. +* @precon nan +* @brief HITLS_CFG_SetCipherServerPreference +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer non-empty configuration information and set isSupport to an invalid value. Expected result 2 is obtained. +* 3. Transfer a non-empty configuration information and set isSupport to a valid value. Expected result 3 is obtained. +* HITLS_CFG_GetCipherServerPreference +* 1. Import empty configuration information. Expected result 1 is obtained. +* 2. Transfer an empty isSupport pointer. Expected result 1 is obtained. +* 3. Transfer the non-null configuration information and the isSupport pointer is not null. Expected result 3 is +* obtained. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. HITLS_SUCCES is returned and config->isSupportServerPreference is set to true. +* 3. Returns HITLS_SUCCES, and config->isSupportServerPreference is true or false. +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_CIPHERSERVERPREFERENCE_API_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + bool isSupport = false; + bool getIsSupport = false; + ASSERT_TRUE(HITLS_CFG_SetCipherServerPreference(config, isSupport) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetCipherServerPreference(config, &getIsSupport) == HITLS_NULL_INPUT); + + switch (tlsVersion) { + case HITLS_VERSION_TLS12: + config = HITLS_CFG_NewTLS12Config(); + break; + case HITLS_VERSION_TLS13: + config = HITLS_CFG_NewTLS13Config(); + break; + default: + config = NULL; + break; + } + + ASSERT_TRUE(HITLS_CFG_GetCipherServerPreference(config, NULL) == HITLS_NULL_INPUT); + isSupport = true; + ASSERT_TRUE(HITLS_CFG_SetCipherServerPreference(config, isSupport) == HITLS_SUCCESS); + isSupport = 2; + ASSERT_TRUE(HITLS_CFG_SetCipherServerPreference(config, isSupport) == HITLS_SUCCESS); + ASSERT_TRUE(config->isSupportServerPreference = true); + isSupport = false; + ASSERT_TRUE(HITLS_CFG_SetCipherServerPreference(config, isSupport) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_GetCipherServerPreference(config, &getIsSupport) == HITLS_SUCCESS); + ASSERT_TRUE(getIsSupport == false); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_RENEGOTIATIONSUPPORT_FUNC_TC001 +* @title Test the function of supporting the renegotiation function by setting the HITLS_CFG_SetRenegotiationSupport and +* obtaining the function of supporting the renegotiation function by the HITLS_CFG_GetRenegotiationSupport. +* @precon nan +* @brief 1. Call HITLS_CFG_SetRenegotiationSupport to disable renegotiation. Expected result 1 is obtained. +* 2. Invoke the HITLS_CFG_GetRenegotiationSupport interface to obtain the configured value. (Expected result +* 2) +* 3. Invoke the HITLS_SetRenegotiationSupport interface to support renegotiation. Expected result 3 is +* obtained. +* 4. Invoke the HITLS_GetRenegotiationSupport interface to obtain the configured value. Expected result 4 is +* obtained. +* 5. Establish a connection. and check whether the value of isSecureRenegotiation in the +* negotiation information is true. Expected result 5 is obtained. +* 6. Perform renegotiation. Expected result 6 is obtained. +* @expect 1. Setting succeeded. +* 2. The interface returns false. +* 3. The setting is successful. +* 4. The interface returns true. +* 5. The value of isSecureRenegotiation is true. +* 6. The renegotiation succeeds. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001() +{ + FRAME_Init(); + FRAME_LinkObj *clientRes; + FRAME_LinkObj *serverRes; + HITLS_Config *config = NULL; + uint8_t supportrenegotiation; + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + + HITLS_CFG_SetRenegotiationSupport(config, false); + HITLS_CFG_GetRenegotiationSupport(config, &supportrenegotiation); + ASSERT_TRUE(supportrenegotiation == false); + + clientRes = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(clientRes != NULL); + serverRes = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(serverRes != NULL); + + HITLS_SetRenegotiationSupport(clientRes->ssl, true); + HITLS_SetRenegotiationSupport(serverRes->ssl, true); + HITLS_GetRenegotiationSupport(clientRes->ssl, &supportrenegotiation); + ASSERT_TRUE(supportrenegotiation == true); + + FRAME_CreateConnection(clientRes, serverRes, true, HS_STATE_BUTT); + ASSERT_TRUE(clientRes->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(serverRes->ssl->state == CM_STATE_TRANSPORTING); + ASSERT_TRUE(HITLS_Renegotiate(serverRes->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(clientRes->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(FRAME_CreateConnection(clientRes, serverRes, true, HS_STATE_BUTT) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(clientRes); + FRAME_FreeLink(serverRes); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_ECPOINTFORMATS_FUNC_TC001 +* @title Set the normal dot format value. +* @precon nan +* @brief 1. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED and invoke the HITLS_CFG_SetEcPointFormats interface. +* Expected result 1 is obtained. +* 2. Set pointFormats to HITLS_POINT_FORMAT_BUTT and invoke the HITLS_CFG_SetEcPointFormats interface. +* (Expected result 2) +* 3. Use config to generate ctx, due to the result 3 +* 4. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED again and generate ctx again. Expected result 4 is +* obtained. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED and invoke the HITLS_SetEcPointFormats +* interface. (Expected result 2) +* 5. Set pointFormats to HITLS_POINT_FORMAT_UNCOMPRESSED and invoke the HITLS_SetEcPointFormats interface. +* Expected result 2 is obtained. +* @expect 1. Interface return value, HITLS_SUCCESS +* 2. Interface return value: HITLS_SUCCESS +* 3. Failed to generate the file. +* 4. The file is generated successfully. +* 5. The setting is successful. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_ECPOINTFORMATS_FUNC_TC001(int version) +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *Config = NULL; + HITLS_Ctx *ctx = NULL; + Config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(Config != NULL); + const uint8_t pointFormats[] = {HITLS_POINT_FORMAT_UNCOMPRESSED}; + uint32_t pointFormatsSize = sizeof(pointFormats) / sizeof(uint8_t); + ASSERT_TRUE(HITLS_CFG_SetEcPointFormats(Config, pointFormats, pointFormatsSize) == HITLS_SUCCESS); + const uint8_t pointFormats2[] = {HITLS_POINT_FORMAT_BUTT}; + uint32_t pointFormatsSize2 = sizeof(pointFormats2) / sizeof(uint8_t); + ASSERT_TRUE(HITLS_CFG_SetEcPointFormats(Config, pointFormats2, pointFormatsSize2) == HITLS_SUCCESS); + ctx = HITLS_New(Config); + if(version == TLS1_2){ + ASSERT_TRUE(ctx == NULL); + } + + HITLS_Free(ctx); + + ASSERT_TRUE(HITLS_CFG_SetEcPointFormats(Config, pointFormats, pointFormatsSize) == HITLS_SUCCESS); + ctx = HITLS_New(Config); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(HITLS_SetEcPointFormats(ctx, pointFormats, pointFormatsSize) == HITLS_SUCCESS); + client = FRAME_CreateLink(Config, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(Config, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(Config); + HITLS_Free(ctx); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +typedef struct { + HITLS_Config *config; + FRAME_LinkObj *client; + FRAME_LinkObj *server; + HITLS_HandshakeState state; + bool isClient; + bool isSupportExtendMasterSecret; + bool isSupportClientVerify; + bool isSupportNoClientCert; + bool isSupportRenegotiation; + bool isSupportSessionTicket; + bool needStopBeforeRecvCCS; +} HandshakeTestInfo; + +/** @ +* @test UT_TLS_CFG_SET_GROUPS_FUNC_TC001 +* @title Sets the elliptic curve that does not exist. +* @precon nan +* @brief 1. Set group to 0x0001 and invoke the HITLS_CFG_SetGroups interface. Expected result 1 is obtained. +* 2. Establish a connection. Check whether the group value in the client hello message sent by the client is +* 0x0001.Expected result 2 is obtained. +* 3. Establish a connection and check whether the connection is successfully established. (Expected result 3) +* @expect 1. Interface HITLS_SUCCESS +* 2. The value of group in the client hello message is 0x0001. +* 3. connection establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GROUPS_FUNC_TC001(int version) +{ + FRAME_Init(); + HandshakeTestInfo testInfo = {0}; + uint16_t group[] = {ERROR_HITLS_GROUP}; + uint32_t grouplength = sizeof(group) / sizeof(uint16_t); + testInfo.isClient = false; + testInfo.config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(testInfo.config != NULL); + ASSERT_TRUE(HITLS_CFG_SetGroups(testInfo.config, group, grouplength) == HITLS_SUCCESS); + if (version == TLS1_2) { + uint16_t cipherSuite[] = {HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}; + HITLS_CFG_SetCipherSuites(testInfo.config, cipherSuite, sizeof(cipherSuite) / sizeof(uint16_t)); + } + FRAME_CertInfo certInfo = { + "rsa_sha/ca-3072.der:rsa_sha/inter-3072.der", + "rsa_sha/inter-3072.der", + "rsa_sha/end-sha256.der", + NULL, + "rsa_sha/end-sha256.key.der", + NULL, + }; + testInfo.client = FRAME_CreateLinkWithCert(testInfo.config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(testInfo.client != NULL); + testInfo.server = FRAME_CreateLinkWithCert(testInfo.config, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(testInfo.server != NULL); + if (version == TLS1_2) { + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, HS_STATE_BUTT), + HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + } else { + ASSERT_EQ(FRAME_CreateConnection(testInfo.client, testInfo.server, testInfo.isClient, HS_STATE_BUTT), + HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + } +exit: + HITLS_CFG_FreeConfig(testInfo.config); + FRAME_FreeLink(testInfo.client); + FRAME_FreeLink(testInfo.server); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_SIGNATURE_FUNC_TC001 +* @title Set a nonexistent signature algorithm. +* @precon nan +* @brief +* 1. Set Signature to 0xffff and call the HITLS_CFG_SetSignature interface. (Expected result 1) +* @expect +* 1. Interface return value: HITLS_CONFIG_INVALID_LENGTH +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_SIGNATURE_FUNC_TC001(int version) +{ + FRAME_Init(); + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_Config *config = NULL; + config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(config != NULL); + uint16_t signAlgs[] = {ERROR_HITLS_SIGNATURE}; + + ASSERT_TRUE(HITLS_CFG_SetSignature(config, signAlgs, sizeof(signAlgs) / sizeof(uint16_t)) == HITLS_SUCCESS); + client = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(client == NULL); + server = FRAME_CreateLink(config, BSL_UIO_TCP); + ASSERT_TRUE(server == NULL); + +exit: + HITLS_CFG_FreeConfig(config); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +void ExampleInfoCallback(const HITLS_Ctx *ctx, int32_t eventType, int32_t value) +{ + (void)ctx; + (void)eventType; + (void)value; +} + +#define MSG_CB_PRINT_LEN 500 + +void msg_callback(int32_t writePoint, int32_t tlsVersion, int32_t contentType, const void *msg, + uint32_t msgLen, HITLS_Ctx *ctx, void *arg) +{ + (void)writePoint; + (void)tlsVersion; + (void)contentType; + (void)msg; + (void)msgLen; + (void)ctx; + (void)arg; +} + +/* @ +* @test UT_TLS_CFG_InfoCb_API_TC001 +* @title InfoCb Interface Parameter Test +* @precon nan +* @brief +1. Use the HITLS_CFG_GetInfoCb without HITLS_CFG_SetInfoCb. Expected result 1 is obtained. +2. Use the HITLS_CFG_SetInfoCb interface to set callback. Expected result 2 +3. Use the HITLS_CFG_GetInfoCb . Expected result 3 +4. Use the HITLS_CFG_GetInfoCb with the parameter is NULL . Expected result 4 +* @expect +1. Return the NULL. +2. Return the HITLS_SUCCESS +3. Return value is not NULL. +4. Return the NULL. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_InfoCb_API_TC001(void) +{ + FRAME_Init(); + + HITLS_Config *config = HITLS_CFG_NewDTLS12Config(); + ASSERT_TRUE(config != NULL); + HITLS_InfoCb infoCallBack = HITLS_CFG_GetInfoCb(config); + ASSERT_TRUE(infoCallBack == NULL); + int32_t ret = HITLS_CFG_SetInfoCb(config, ExampleInfoCallback); + ASSERT_TRUE(ret == HITLS_SUCCESS); + infoCallBack = HITLS_CFG_GetInfoCb(config); + ASSERT_TRUE(infoCallBack != NULL); + infoCallBack = HITLS_CFG_GetInfoCb(NULL); + ASSERT_TRUE(infoCallBack == NULL); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SetMsgCb_API_TC001 +* @title HITLS_CFG_SetMsgCb Interface Parameter Test +* @precon nan +* @brief +1. Set config to NULL. Expected result 1 is obtained. +2. Invoke the HITLS_CFG_SetMsgCb interface to set callback. (Expected result 2) +* @expect +1. Return the HITLS_NULL_INPUT message. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SetMsgCb_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_EQ(HITLS_CFG_SetMsgCb(NULL, msg_callback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_CFG_SetMsgCb(tlsConfig, msg_callback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SetMsgCbArg_API_TC001 +* @title HITLS_CFG_SetMsgCbArg Interface Parameter Test +* @precon nan +* @brief 1. Set config to NULL. Expected result 1 is obtained. +2. Use the HITLS_CFG_SetMsgCbArg interface to set Arg. Expected result 2 is obtained. +* @expect 1. The HITLS_NULL_INPUT message is returned. +2. Return the HITLS_SUCCESS +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SetMsgCbArg_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig; + tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + ASSERT_EQ(HITLS_CFG_SetMsgCbArg(NULL, msg_callback), HITLS_NULL_INPUT); + ASSERT_EQ(HITLS_CFG_SetMsgCbArg(tlsConfig, msg_callback), HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(tlsConfig); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SETTMPDH_FUNC_TC001 +* @title Set tmpdhkey. The link setup status varies according to the security level. +* @precon nan +* @brief +* 1. Set the RSA certificate and algorithm suite. +* 2. Set the dh key to not follow the certificate, and set the tmpdh key with 80 security bits. +* 3. Set the security level to 0 and set up a link. +* 4. Set the security level to 2 and set up a link. +* @expect +* 1. The setting is successful. +* 2. The setting is successful. +* 3. The link is set up successfully. +* 4. The link fails to be set up. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SETTMPDH_FUNC_TC001(int level) +{ + FRAME_Init(); + HITLS_Config *clientConfig = NULL; + HITLS_Config *serverConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + HITLS_CRYPT_Key *key = NULL; + uint16_t pfsCipherSuites[] = {HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256}; + + clientConfig = HITLS_CFG_NewTLS12Config(); + serverConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(serverConfig != NULL); + + ASSERT_TRUE(HiTLS_X509_LoadCertAndKey(clientConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, + RSA_SHA256_EE_PATH3, NULL, RSA_SHA256_PRIV_PATH3,NULL) == HITLS_SUCCESS); + ASSERT_TRUE(HiTLS_X509_LoadCertAndKey(serverConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, + RSA_SHA256_EE_PATH3, NULL, RSA_SHA256_PRIV_PATH3,NULL) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(clientConfig, pfsCipherSuites, sizeof(pfsCipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(serverConfig, pfsCipherSuites, sizeof(pfsCipherSuites) / sizeof(uint16_t)) == HITLS_SUCCESS); + HITLS_CFG_SetSecurityLevel(serverConfig, level); + HITLS_CFG_SetSecurityLevel(clientConfig, level); + + HITLS_CFG_SetDhAutoSupport(serverConfig, false); + key = SAL_CRYPT_GenerateDhKeyBySecbits(80); + HITLS_CFG_SetTmpDh(serverConfig, key); + + FRAME_CertInfo certInfo = {0, 0, 0, 0, 0, 0}; + client = FRAME_CreateLinkWithCert(clientConfig, BSL_UIO_TCP, &certInfo); + server = FRAME_CreateLinkWithCert(serverConfig, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + if (level > 1) { + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_KEY_EXCHANGE), HITLS_SUCCESS); + FRAME_TrasferMsgBetweenLink(server, client); + HITLS_Connect(client->ssl); + ASSERT_EQ(HITLS_Accept(server->ssl) , HITLS_MSG_HANDLE_ERR_GET_DH_KEY); + } else { + ASSERT_EQ(FRAME_CreateConnection(client, server, false, HS_STATE_BUTT), HITLS_SUCCESS); + } +exit: + HITLS_CFG_FreeConfig(clientConfig); + HITLS_CFG_FreeConfig(serverConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/* @ +* @test UT_TLS_CFG_SET_POSTHANDSHAKEAUTHSUPPORT_API_TC001 +* +* @title Test the HITLS_SetPostHandshakeAuthSupport interface. +* +* @brief +* 1. The default value of the TLS connection handle isSupportPostHandshakeAuth is fasle. Expected result 1。 +* 2. Run the HITLS_SetPostHandshakeAuthSupport command to set a handle. The value of isSupportPostHandshakeAuth is true. +* Expected result 2. +* @expect +* 1. isSupportPostHandshakeAuth is false. +* 2. isSupportPostHandshakeAuth is true. +@*/ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_POSTHANDSHAKEAUTHSUPPORT_API_TC001(int tlsVersion) +{ + HitlsInit(); + HITLS_Config *tlsConfig = GetHitlsConfigViaVersion(tlsVersion); + ASSERT_TRUE(tlsConfig != NULL); + + HITLS_Ctx *ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + ASSERT_TRUE(ctx->config.tlsConfig.isSupportPostHandshakeAuth == false); + + int ret = HITLS_SetPostHandshakeAuthSupport(ctx, true); + ASSERT_TRUE(ret == HITLS_SUCCESS); + ASSERT_TRUE(ctx->config.tlsConfig.isSupportPostHandshakeAuth == true); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_GET_SECURE_RENEGOTIATIONSUPPORET_FUNC_TC001 +* @title HITLS_GetSecureRenegotationSupport The client does not support security renegotiation, +* but the server supports security renegotiation. Obtains whether security renegotiation is supported. +* @precon nan +* @brief HITLS_GetSecureRenegotationSupport +* 1. Transfer an empty TLS connection handle. Expected result 1. +* 2. Transfer the non-empty TLS connection handle information and leave isSecureRenegotiation blank. Expected result 1. +* 3. Transfer the non-empty TLS connection handle information. The isSecureRenegotiation parameter is not empty. +* Expected result 2. +* @expect +* 1. Returns HITLS_NULL_INPUT +* 2. Returns HITLS_SUCCES +@ */ + +/* BEGIN_CASE */ +void UT_TLS_CFG_GET_SECURE_RENEGOTIATIONSUPPORET_API_TC001(void) +{ + HitlsInit(); + HITLS_Config *config = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t isSecureRenegotiation = 0; + ASSERT_TRUE(HITLS_GetSecureRenegotiationSupport(NULL, &isSecureRenegotiation) == HITLS_NULL_INPUT); + + config = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(config != NULL); + ctx = HITLS_New(config); + ASSERT_TRUE(ctx != NULL); + + ASSERT_TRUE(HITLS_GetSecureRenegotiationSupport(ctx, NULL) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetSecureRenegotiationSupport(ctx, &isSecureRenegotiation) == HITLS_SUCCESS); + +exit: + HITLS_CFG_FreeConfig(config); + HITLS_Free(ctx); +} +/* END_CASE */ + +/** @ +* @test UT_TLS_CFG_SET_GET_DHAUTOSUPPORT_FUNC_TC001 +* @title Test the HITLS_SetDhAutoSupport and HITLS_CFG_GetDhAutoSupport interfaces. +* @precon nan +* @brief +* 1. Invoke the HITLS_CFG_SetDhAutoSupport interface to set the parameter to false. Expected result 1 is obtained. +* 2. Establish a connection. Expected result 2 is obtained. +* @expect +* 1. The setting is successful. +* 2. connection establishment fails. +@ */ +/* BEGIN_CASE */ +void UT_TLS_CFG_SET_GET_DHAUTOSUPPORT_FUNC_TC001(void) +{ + FRAME_Init(); + HITLS_Config *clientConfig = NULL; + HITLS_Config *serverConfig = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + uint16_t pfsCipherSuites[] = {HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256}; + + clientConfig = HITLS_CFG_NewTLS12Config(); + serverConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(clientConfig != NULL); + ASSERT_TRUE(serverConfig != NULL); + + ASSERT_TRUE(HiTLS_X509_LoadCertAndKey(clientConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, + RSA_SHA256_EE_PATH3, NULL, RSA_SHA256_PRIV_PATH3,NULL) == HITLS_SUCCESS); + ASSERT_TRUE(HiTLS_X509_LoadCertAndKey(serverConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, + RSA_SHA256_EE_PATH3, NULL, RSA_SHA256_PRIV_PATH3,NULL) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(clientConfig, pfsCipherSuites, sizeof(pfsCipherSuites) / sizeof(uint16_t)) == + HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_SetCipherSuites(serverConfig, pfsCipherSuites, sizeof(pfsCipherSuites) / sizeof(uint16_t)) == + HITLS_SUCCESS); + + HITLS_CFG_SetDhAutoSupport(serverConfig, false); + + FRAME_CertInfo certInfo = {0, 0, 0, 0, 0, 0}; + client = FRAME_CreateLinkWithCert(clientConfig, BSL_UIO_TCP, &certInfo); + server = FRAME_CreateLinkWithCert(serverConfig, BSL_UIO_TCP, &certInfo); + ASSERT_TRUE(client != NULL); + ASSERT_TRUE(server != NULL); + + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_SERVER_KEY_EXCHANGE), HITLS_SUCCESS); + FRAME_TrasferMsgBetweenLink(server, client); + HITLS_Connect(client->ssl); + ASSERT_EQ(HITLS_Accept(server->ssl), HITLS_MSG_HANDLE_ERR_GET_DH_KEY); +exit: + HITLS_CFG_FreeConfig(clientConfig); + HITLS_CFG_FreeConfig(serverConfig); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_config_interface.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_config_interface.data new file mode 100644 index 00000000..b01818af --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_frame_config_interface.data @@ -0,0 +1,122 @@ +UT_TLS_CFG_UPREF_FUNC_TC001 +UT_TLS_CFG_UPREF_FUNC_TC001: + +UT_TLS_CFG_SET_RESUMPTIONONRENEGOSUPPORT_API_TC001 +UT_TLS_CFG_SET_RESUMPTIONONRENEGOSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_RESUMPTIONONRENEGOSUPPORT_API_TC001 +UT_TLS_CFG_SET_RESUMPTIONONRENEGOSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_NOCLIENTCERTSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_NOCLIENTCERTSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_NOCLIENTCERTSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_NOCLIENTCERTSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_CLIENTVERIFYSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_CLIENTVERIFYSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_CLIENTVERIFYSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_CLIENTVERIFYSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_TMPDH_API_TC001 +UT_TLS_CFG_SET_TMPDH_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_TMPDH_API_TC001 +UT_TLS_CFG_SET_TMPDH_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_CLIENTHELLOCB_API_TC001 +UT_TLS_CFG_SET_CLIENTHELLOCB_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_CLIENTHELLOCB_API_TC001 +UT_TLS_CFG_SET_CLIENTHELLOCB_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_NOSECRENEGOTIATIONCB_API_TC001 +UT_TLS_CFG_SET_NOSECRENEGOTIATIONCB_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_NOSECRENEGOTIATIONCB_API_TC001 +UT_TLS_CFG_SET_NOSECRENEGOTIATIONCB_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_VERSION_API_TC001 +UT_TLS_CFG_SET_GET_VERSION_API_TC001: + +UT_TLS_CFG_GET_HASHID_API_TC001 +UT_TLS_CFG_GET_HASHID_API_TC001: + +UT_TLS_CFG_GET_MACID_API_TC001 +UT_TLS_CFG_GET_MACID_API_TC001: + +UT_TLS_CFG_GET_KEYEXCHID_API_TC001 +UT_TLS_CFG_GET_KEYEXCHID_API_TC001: + +UT_TLS_CFG_GET_CIPHERSUITESTDNAME_API_TC001 +UT_TLS_CFG_GET_CIPHERSUITESTDNAME_API_TC001: + +UT_TLS_CFG_GET_DESCRIPTION_API_TC001 +UT_TLS_CFG_GET_DESCRIPTION_API_TC001: + +UT_TLS_CFG_CIPHER_ISAEAD_API_TC001 +UT_TLS_CFG_CIPHER_ISAEAD_API_TC001: + +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001 +UT_TLS_CFG_SET_GET_VERSIONSUPPORT_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_QUIETSHUTDOWN_API_TC001 +UT_TLS_CFG_SET_GET_QUIETSHUTDOWN_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_QUIETSHUTDOWN_API_TC001 +UT_TLS_CFG_SET_GET_QUIETSHUTDOWN_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_CIPHERSERVERPREFERENCE_API_TC001 +UT_TLS_CFG_SET_GET_CIPHERSERVERPREFERENCE_API_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_GET_CIPHERSERVERPREFERENCE_API_TC001 +UT_TLS_CFG_SET_GET_CIPHERSERVERPREFERENCE_API_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001 +UT_TLS_CFG_SET_GET_RENEGOTIATIONSUPPORT_FUNC_TC001: + +UT_TLS_CFG_SET_ECPOINTFORMATS_FUNC_TC001 +UT_TLS_CFG_SET_ECPOINTFORMATS_FUNC_TC001:HITLS_VERSION_TLS12 + +UT_TLS_CFG_SET_ECPOINTFORMATS_FUNC_TC001 +UT_TLS_CFG_SET_ECPOINTFORMATS_FUNC_TC001:HITLS_VERSION_TLS13 + +UT_TLS_CFG_SET_GROUPS_FUNC_TC001 +UT_TLS_CFG_SET_GROUPS_FUNC_TC001:TLS1_2 + +UT_TLS_CFG_SET_GROUPS_FUNC_TC001 +UT_TLS_CFG_SET_GROUPS_FUNC_TC001:TLS1_3 + +UT_TLS_CFG_SET_SIGNATURE_FUNC_TC001 +UT_TLS_CFG_SET_SIGNATURE_FUNC_TC001:TLS1_2 + +UT_TLS_CFG_SET_SIGNATURE_FUNC_TC001 +UT_TLS_CFG_SET_SIGNATURE_FUNC_TC001:TLS1_3 + +UT_TLS_CFG_InfoCb_API_TC001 +UT_TLS_CFG_InfoCb_API_TC001: + +UT_TLS_CFG_SetMsgCb_API_TC001 +UT_TLS_CFG_SetMsgCb_API_TC001: + +UT_TLS_CFG_SetMsgCbArg_API_TC001 +UT_TLS_CFG_SetMsgCbArg_API_TC001: + +UT_TLS_CFG_SETTMPDH_FUNC_TC001 +UT_TLS_CFG_SETTMPDH_FUNC_TC001:0 + +UT_TLS_CFG_SETTMPDH_FUNC_TC001 +UT_TLS_CFG_SETTMPDH_FUNC_TC001:2 + +UT_TLS_CFG_SET_POSTHANDSHAKEAUTHSUPPORT_API_TC001 +UT_TLS_CFG_SET_POSTHANDSHAKEAUTHSUPPORT_API_TC001:TLS1_3 + +UT_TLS_CFG_GET_SECURE_RENEGOTIATIONSUPPORET_API_TC001 +UT_TLS_CFG_GET_SECURE_RENEGOTIATIONSUPPORET_API_TC001: + +UT_TLS_CFG_SET_GET_DHAUTOSUPPORT_FUNC_TC001 +UT_TLS_CFG_SET_GET_DHAUTOSUPPORT_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cert_interface.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cert_interface.c new file mode 100644 index 00000000..7a26dc65 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cert_interface.c @@ -0,0 +1,384 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hitls_error.h" +#include "hitls_cert.h" +#include "hitls.h" +#include "hitls_func.h" +#include "securec.h" +#include "cert_method.h" +#include "cert_mgr.h" +#include "cert_mgr_ctx.h" +#include "frame_tls.h" +#include "frame_link.h" +#include "frame_io.h" +#include "hlt_type.h" +#include "process.h" +#include "hlt.h" +#include "session.h" +#include "bsl_sal.h" +#include "alert.h" +#include "stub_replace.h" +#include "cert_callback.h" +#include "crypt_eal_rand.h" +#include "hitls_crypt_reg.h" +#include "hitls_crypt_init.h" +#include "logger.h" +#include "uio_base.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" +#include "hitls_cert_reg.h" +#include "hitls_config.h" +#include "hitls_cert_init.h" +#include "bsl_log.h" +#include "bsl_err.h" +#include "tls_config.h" +#include "tls.h" +#include "crypt_algid.h" +#include "crypt_errno.h" +#include "bsl_uio.h" +#include "bsl_obj.h" +#include "bsl_errno.h" +#include "hitls_x509_adapt_local.h" + +/* END_HEADER */ + +#define BUF_MAX_SIZE 4096 +int32_t g_uiPort = 18886; + +#define DEFAULT_CERT_PATH "../../testcode/testdata/tls/certificate/der/" +#define CERT_PATH_LEN 120 +#define SUCCESS (0) +#define ERROR (1) +#define MAX_BUFFER (8192) +#define READ_BUF_LEN_18K (18 * 1024) +#define READ_DATA_18432 18432 +#define PASSWDLEN (10) +#define CERT_PATH_BUFFER (100) + +#define RSA_ROOT_CERT_DER "rsa_sha/ca-3072.der" +#define RSA_CA_CERT_DER "rsa_sha/inter-3072.der" +#define RSA_EE_CERT_DER "rsa_sha/end-sha1.der" +#define RSA_PRIV_KEY_DER "rsa_sha/end-sha1.key.der" +#define RSA_EE_CERT_DER "rsa_sha/end-sha1.der" +#define RSA_PRIV_KEY_DER "rsa_sha/end-sha1.key.der" + +#define RSA_ROOT_CERT2_DER "rsa_sha256/ca.der" +#define RSA_CA_CERT2_DER "rsa_sha256/inter.der" +#define RSA_EE_CERT2_DER "rsa_sha256/server.der" +#define RSA_PRIV_KEY2_DER "rsa_sha256/server.key.der" + +#define ECDSA_ROOT_CERT_DER "ecdsa/ca-nist521.der" +#define ECDSA_CA_CERT_DER "ecdsa/inter-nist521.der" +#define ECDSA_EE_CERT_DER "ecdsa/end256-sha256.der" +#define ECDSA_PRIV_KEY_DER "ecdsa/end256-sha256.key.der" + +typedef enum { + SHALLOW_COPY = 0, + DEEP_COPY, +} COPY_WAY; + +typedef enum { + ECDSA_CERT, + ED25519_CERT, + RSA_CERT, + RSA_CERT_TWO, + RSA_CERT_THREE, +} EE_CERT_TYPE; + +typedef enum { + FROM_CONFIG, + FROM_CTX, + FROM_BUFFER_TO_CONFIG, + FROM_BUFFER_TO_CTX +} LOAD_CERT_WAY; +typedef LOAD_CERT_WAY LOAD_KEY_WAY; + +int GetCertPathFrom(int eeCertType, char **rootCA, char **ca, char **ee, char **prvKey) +{ + switch (eeCertType) { + case RSA_CERT: + *rootCA = RSA_ROOT_CERT_DER; + *ca = RSA_CA_CERT_DER; + *ee = RSA_EE_CERT_DER; + *prvKey = RSA_PRIV_KEY_DER; + return SUCCESS; + case RSA_CERT_TWO: + *rootCA = RSA_ROOT_CERT2_DER; + *ca = RSA_CA_CERT2_DER; + *ee = RSA_EE_CERT2_DER; + *prvKey = RSA_PRIV_KEY2_DER; + return SUCCESS; + case RSA_CERT_THREE: + *rootCA = RSA_ROOT_CERT_DER; + *ca = RSA_CA_CERT_DER; + *ee = RSA_EE_CERT_DER; + *prvKey = RSA_PRIV_KEY_DER; + return SUCCESS; + case ECDSA_CERT: + *rootCA = ECDSA_ROOT_CERT_DER; + *ca = ECDSA_CA_CERT_DER; + *ee = ECDSA_EE_CERT_DER; + *prvKey = ECDSA_PRIV_KEY_DER; + return SUCCESS; + default: + return ERROR; + } +} + +int NormalizePath(char* normalizedPath, const char* path) { + int ret; + ret = sprintf_s(normalizedPath, CERT_PATH_LEN, "%s%s", DEFAULT_CERT_PATH, path); + if (ret <= 0) { + LOG_ERROR("sprintf_s Error"); + return ERROR; + } + return SUCCESS; +} + +int Dtls_DataTransfer(HITLS_Ctx *clientCtx, HLT_Process *remoteProcess, HLT_Tls_Res *serverRes) +{ + uint8_t *writeBuf = (uint8_t *)"hello world"; + uint32_t writeLen = strlen((char *)writeBuf); + uint8_t readBuf[READ_DATA_18432] = { 0 }; + uint32_t readLen = 0; + ASSERT_EQ(HLT_TlsWrite(clientCtx, writeBuf, writeLen), SUCCESS); + ASSERT_EQ(HLT_ProcessTlsRead(remoteProcess, serverRes, readBuf, READ_DATA_18432, &readLen), 0); + ASSERT_COMPARE("COMPARE DATA", writeBuf, writeLen, readBuf, readLen); + return SUCCESS; +exit: + return ERROR; +} + +HITLS_Ctx *Dtls_New_Ctx(HLT_Process *localProcess, HITLS_Config* clientConfig) +{ + HITLS_Ctx *clientCtx = HLT_TlsNewSsl(clientConfig); + ASSERT_TRUE(clientCtx != NULL); + HLT_Ssl_Config clientCtxConfig; + clientCtxConfig.sockFd = localProcess->connFd; + clientCtxConfig.connType = IsEnableSctpAuth() ? SCTP : TCP; + ASSERT_TRUE_AND_LOG("HLT_TlsSetSsl", HLT_TlsSetSsl(clientCtx, &clientCtxConfig) == 0); + return clientCtx; + +exit: + return NULL; +} + +void TestSetCertPath(HLT_Ctx_Config *ctxConfig, char *SignatureType) +{ + if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA1", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA1")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA256", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA256")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA256_EE_PATH3, RSA_SHA256_PRIV_PATH3, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA384")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA384_EE_PATH, RSA_SHA384_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512", strlen("CERT_SIG_SCHEME_RSA_PKCS1_SHA512")) == + 0 || + strncmp(SignatureType, + "CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512", + strlen("CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512")) == 0) { + HLT_SetCertPath( + ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA512_EE_PATH, RSA_SHA512_PRIV_PATH, "NULL", "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256", + strlen("CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA256_EE_PATH, + ECDSA_SHA256_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384", + strlen("CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA384_EE_PATH, + ECDSA_SHA384_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, + "CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512", + strlen("CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA_CA_PATH, + ECDSA_SHA_CHAIN_PATH, + ECDSA_SHA512_EE_PATH, + ECDSA_SHA512_PRIV_PATH, + "NULL", + "NULL"); + } else if (strncmp(SignatureType, "CERT_SIG_SCHEME_ECDSA_SHA1", strlen("CERT_SIG_SCHEME_ECDSA_SHA1")) == 0) { + HLT_SetCertPath(ctxConfig, + ECDSA_SHA1_CA_PATH, + ECDSA_SHA1_CHAIN_PATH, + ECDSA_SHA1_EE_PATH, + ECDSA_SHA1_PRIV_PATH, + "NULL", + "NULL"); + } +} + +HITLS_CERT_X509 *HiTLS_X509_LoadCertFile(const char *file); + +/* @ +* @test SDV_TLS_LoadAndDelCert_FUNC_TC001 +* @title Loading and Deleting Certificates +* @precon nan +* @brief 1. Initialize the client and server. Expected result 1 + 2. Load the certificate to the certificate chain. Expected result 2 + 3. Load the first certificate and private key to the certificate chain. Expected result 2 + 4. Load the second certificate to the certificate chain. Expected result 2 + 5. Run the config command to remove all certificates. Expected result 3 + 6. Load the third certificate to the certificate chain. Expected result 2 + 7. Remove all certificates in CTX mode. Expected result 3 + 8. Load the third certificate to the certificate chain. Expected result 2 + 9. Initiate link establishment. Expected result 4 is obtained +* @expect 1. Initialization succeeded. + 2. Loading succeeded. + 3. Removing succeeded. + 4. Link setup succeeded +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CERT_LoadAndDelCert_FUNC_TC001(int delWay) +{ + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HITLS_Config* serverConfig = NULL; + + // Stores the path where the certificate is loaded for the first time. + char *rootCAFilePath1 = NULL; + char *caFilePath1 = NULL; + char *eeFilePath1 = NULL; + char *eeKeyPath1 = NULL; + // Stores the path where the certificate is loaded for the second time. + char *rootCAFilePath2 = NULL; + char *caFilePath2 = NULL; + char *eeFilePath2 = NULL; + char *eeKeyPath2 = NULL; + HITLS_CERT_X509 *eeCert3 = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HILT_TransportType connType = IsEnableSctpAuth() ? SCTP : TCP; + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, false); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + TestSetCertPath(clientCtxConfig, "CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256"); + rootCAFilePath1 = DEFAULT_CERT_PATH""RSA_ROOT_CERT_DER; + caFilePath1 = DEFAULT_CERT_PATH""RSA_CA_CERT_DER; + eeFilePath1 = DEFAULT_CERT_PATH""RSA_EE_CERT_DER; + eeKeyPath1 = DEFAULT_CERT_PATH""RSA_PRIV_KEY_DER; + rootCAFilePath2 = DEFAULT_CERT_PATH""ECDSA_ROOT_CERT_DER; + caFilePath2 = DEFAULT_CERT_PATH""ECDSA_CA_CERT_DER; + eeFilePath2 = DEFAULT_CERT_PATH""ECDSA_EE_CERT_DER; + eeKeyPath2 = DEFAULT_CERT_PATH""ECDSA_PRIV_KEY_DER; + + ASSERT_EQ(HLT_TlsRegCallback(HITLS_CALLBACK_DEFAULT), SUCCESS); + serverConfig = HLT_TlsNewCtx(DTLS1_2); + ASSERT_TRUE(serverConfig != NULL); + uint16_t group = HITLS_EC_GROUP_SECP256R1; + ASSERT_EQ(HITLS_CFG_SetGroups(serverConfig, &group, 1), SUCCESS); + // Load the certificate to the Chain Store. + HITLS_CERT_Store *chainStore = HITLS_X509_Adapt_StoreNew(); + ASSERT_TRUE(chainStore != NULL); + ASSERT_EQ(HITLS_CFG_SetVerifyStore(serverConfig, chainStore, SHALLOW_COPY), SUCCESS); + HITLS_CERT_X509 *rootCACert2 = HiTLS_X509_LoadCertFile(rootCAFilePath2); + ASSERT_TRUE(rootCACert2 != NULL); + ASSERT_EQ(HITLS_CFG_AddCertToStore(serverConfig, rootCACert2, TLS_CERT_STORE_TYPE_VERIFY, false), HITLS_SUCCESS); + HITLS_CERT_X509 *caCert2 = HiTLS_X509_LoadCertFile(caFilePath2); + ASSERT_TRUE(caCert2 != NULL); + ASSERT_EQ(HITLS_CFG_AddCertToStore(serverConfig, caCert2, TLS_CERT_STORE_TYPE_VERIFY, false), HITLS_SUCCESS); + + // Loading the device certificate and corresponding private key for the first time + HITLS_CERT_X509 *eeCert1 = HiTLS_X509_LoadCertFile(eeFilePath2); + ASSERT_TRUE(eeCert1 != NULL); + ASSERT_EQ(HITLS_CFG_SetCertificate(serverConfig, eeCert1, SHALLOW_COPY), SUCCESS); + HITLS_CERT_Key *prvKey1 = HITLS_X509_Adapt_KeyParse(serverConfig, (const uint8_t *)eeKeyPath2, strlen(eeKeyPath1), + TLS_PARSE_TYPE_FILE, TLS_PARSE_FORMAT_ASN1); + ASSERT_TRUE(prvKey1 != NULL); + ASSERT_EQ(HITLS_CFG_SetPrivateKey(serverConfig, prvKey1, SHALLOW_COPY), SUCCESS); + + // The private key is not loaded when the certificate is loaded for the second time. + HITLS_CERT_X509 *eeCert2 = HiTLS_X509_LoadCertFile(eeFilePath2); + ASSERT_TRUE(eeCert2 != NULL); + ASSERT_EQ(HITLS_CFG_SetCertificate(serverConfig, eeCert2, SHALLOW_COPY), SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetCertificate(serverConfig) == eeCert2); + + if (delWay == FROM_CONFIG) { + ASSERT_EQ(HITLS_CFG_RemoveCertAndKey(serverConfig), SUCCESS); + // Reload the certificate without loading the private key. + eeCert3 = HiTLS_X509_LoadCertFile(eeFilePath2); + ASSERT_TRUE(eeCert3 != NULL); + ASSERT_EQ(HITLS_CFG_SetCertificate(serverConfig, eeCert3, SHALLOW_COPY), SUCCESS); + HITLS_CERT_Key *prvKey2 = HITLS_X509_Adapt_KeyParse(serverConfig, (const uint8_t *)eeKeyPath2, + strlen(eeKeyPath2), TLS_PARSE_TYPE_FILE, TLS_PARSE_FORMAT_ASN1); + ASSERT_TRUE(prvKey2 != NULL); + ASSERT_EQ(HITLS_CFG_SetPrivateKey(serverConfig, prvKey2, SHALLOW_COPY), SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetPrivateKey(serverConfig) == prvKey2); + } + HITLS_Ctx *serverCtx = Dtls_New_Ctx(localProcess, serverConfig); + ASSERT_TRUE(serverCtx != NULL); + + if (delWay == FROM_CTX) { + // After the certificate is loaded from Config, the certificate is copied to CTX. + ASSERT_TRUE(HITLS_GetCertificate(serverCtx) != eeCert2); + ASSERT_EQ(HITLS_RemoveCertAndKey(serverCtx), SUCCESS); + // Reload the certificate without loading the private key. + eeCert3 = HiTLS_X509_LoadCertFile(eeFilePath2); + ASSERT_TRUE(eeCert3 != NULL); + ASSERT_EQ(HITLS_SetCertificate(serverCtx, eeCert3, SHALLOW_COPY), SUCCESS); + HITLS_CERT_Key *prvKey2 = HITLS_X509_Adapt_KeyParse(serverConfig, (const uint8_t *)eeKeyPath2, + strlen(eeKeyPath2), TLS_PARSE_TYPE_FILE, TLS_PARSE_FORMAT_ASN1); + ASSERT_TRUE(prvKey2 != NULL); + ASSERT_EQ(HITLS_SetPrivateKey(serverCtx, prvKey2, SHALLOW_COPY), SUCCESS); + ASSERT_TRUE(HITLS_GetCertificate(serverCtx) == eeCert3); + ASSERT_TRUE(HITLS_GetPrivateKey(serverCtx) == prvKey2); + } + unsigned long int tlsAcceptId = HLT_TlsAccept(serverCtx); + clientRes = HLT_ProcessTlsConnect(remoteProcess, DTLS1_2, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + ASSERT_EQ(HLT_GetTlsAcceptResultFromId(tlsAcceptId), 0); + ASSERT_EQ(Dtls_DataTransfer(serverCtx, remoteProcess, clientRes), SUCCESS); +exit: + HLT_FreeAllProcess(); + return; +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cert_interface.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cert_interface.data new file mode 100644 index 00000000..2c2fb3cb --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cert_interface.data @@ -0,0 +1,5 @@ +SDV_TLS_CERT_LoadAndDelCert_FUNC_TC001 +SDV_TLS_CERT_LoadAndDelCert_FUNC_TC001:FROM_CONFIG + +SDV_TLS_CERT_LoadAndDelCert_FUNC_TC001 +SDV_TLS_CERT_LoadAndDelCert_FUNC_TC001:FROM_CTX \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cm_interface.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cm_interface.c new file mode 100644 index 00000000..48b60175 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cm_interface.c @@ -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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include "securec.h" +#include "hlt.h" +#include "logger.h" +#include "hitls_config.h" +#include "hitls_cert_type.h" +#include "hitls.h" +#include "process.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls_func.h" +#include "hitls.h" +#include "conn_init.h" +#include "frame_tls.h" +#include "frame_msg.h" +#include "frame_io.h" +#include "frame_link.h" +#include "hs_common.h" +#include "change_cipher_spec.h" +#include "stub_replace.h" + +#define READ_BUF_SIZE 18432 +#define Port 7788 +#define ROOT_DER "%s/ca.der:%s/inter.der" +#define INTCA_DER "%s/inter.der" +#define SERVER_DER "%s/server.der" +#define SERVER_KEY_DER "%s/server.key.der" +#define CLIENT_DER "%s/client.der" +#define CLIENT_KEY_DER "%s/client.key.der" +#define BUF_SZIE 18432 + +/* END_HEADER */ +static uint32_t g_uiPort = 18889; + +static void SetCertPath_2(HLT_Ctx_Config *ctxConfig, char *cipherSuite) +{ + if (strstr(cipherSuite, "RSA") != NULL) { + HLT_SetCertPath(ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, NULL, NULL); + } else if (strstr(cipherSuite, "ECDSA") != NULL) { + HLT_SetCertPath(ctxConfig, ECDSA_SHA_CA_PATH, ECDSA_SHA_CHAIN_PATH, ECDSA_SHA1_EE_PATH, ECDSA_SHA1_PRIV_PATH, NULL, NULL); + } else { + HLT_SetCertPath(ctxConfig, RSA_SHA_CA_PATH, RSA_SHA_CHAIN_PATH, RSA_SHA1_EE_PATH, RSA_SHA1_PRIV_PATH, NULL, NULL); + } +} + +/** + * @test SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001 + * @title To test the setting of the HITLS_SetCipherServerPreference interface of the dtls. + * @precon By default, the algorithm preferred by the client is preferred. + * @brief + * 1. Initialize the hitls. + * 2. Create an SSL ctx object. + * 3. Create an SSL object. + * 4. Connect + * 5. Check for connection errors. + * 6. Check whether the negotiated cipher suite is the client preference. + * 7. Check whether the negotiated group is the client preference. + * 8. Check that the negotiated signature algorithm is the client preference. + * @expect + * 1. successful + * 2. successful + * 3. successful + * 4. successful + * 5. successful + * 6. successful + * 7. successful + * 8. successful + */ +/* BEGIN_CASE */ +void SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001(char *serverCipherSuite, char *clientCipherSuite, int expectResult) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HILT_TransportType connType = IsEnableSctpAuth() ? SCTP : TCP; + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath_2(serverCtxConfig, serverCipherSuite); + HLT_SetGroups(serverCtxConfig, "HITLS_EC_GROUP_SECP256R1:HITLS_EC_GROUP_SECP384R1"); + HLT_SetCipherSuites(serverCtxConfig, serverCipherSuite); + HLT_SetSignature(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384:CERT_SIG_SCHEME_RSA_PKCS1_SHA512"); + + serverRes = HLT_ProcessTlsAccept(localProcess, DTLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath_2(clientCtxConfig, clientCipherSuite); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP384R1:HITLS_EC_GROUP_SECP256R1"); + HLT_SetCipherSuites(clientCtxConfig, clientCipherSuite); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512:CERT_SIG_SCHEME_RSA_PKCS1_SHA384"); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, DTLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf[BUF_SZIE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, sizeof(readBuf), &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); + + HITLS_Ctx *testCtx = (HITLS_Ctx *)serverRes->ssl; + + ASSERT_TRUE(testCtx->negotiatedInfo.cipherSuiteInfo.cipherSuite == expectResult); + + ASSERT_TRUE(testCtx->negotiatedInfo.negotiatedGroup == HITLS_EC_GROUP_SECP384R1); + + ASSERT_TRUE(testCtx->negotiatedInfo.signScheme == CERT_SIG_SCHEME_RSA_PKCS1_SHA512); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** + * @test SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002 + * @title To test the setting of the HITLS_SetCipherServerPreference interface of the dtls. + * @precon Set the algorithm for preferentially selecting the server-side preference. + * @brief + * 1. Initialize the hitls. + * 2. Create an SSL ctx object. + * 3. Create an SSL object. + * 4. Connect + * 5. Check for connection errors. + * 6. Check whether the negotiated algorithm is the server preference. + * @expect + * 1. successful + * 2. successful + * 3. successful + * 4. successful + * 5. successful + * 6. successful + */ +/* BEGIN_CASE */ +void SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002(char *serverCipherSuite, char *clientCipherSuite, int expectResult) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HILT_TransportType connType = IsEnableSctpAuth() ? SCTP : TCP; + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath_2(serverCtxConfig, serverCipherSuite); + HLT_SetGroups(serverCtxConfig, "NULL"); + HLT_SetCipherSuites(serverCtxConfig, serverCipherSuite); + HLT_SetSignature(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384:CERT_SIG_SCHEME_RSA_PKCS1_SHA512"); + + serverRes = HLT_ProcessTlsAccept(localProcess, DTLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + int32_t ret = HITLS_SetCipherServerPreference(serverRes->ssl, true); + ASSERT_TRUE(ret == HITLS_SUCCESS); + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + SetCertPath_2(clientCtxConfig, clientCipherSuite); + HLT_SetGroups(clientCtxConfig, "NULL"); + HLT_SetCipherSuites(clientCtxConfig, clientCipherSuite); + HLT_SetSignature(clientCtxConfig, "NULL"); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, DTLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf[BUF_SZIE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, sizeof(readBuf), &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); + + HITLS_Ctx *testCtx = (HITLS_Ctx *)serverRes->ssl; + + ASSERT_TRUE(testCtx->negotiatedInfo.cipherSuiteInfo.cipherSuite == expectResult); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** + * @test SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC003 + * @title To test the setting of the HITLS_SetCipherServerPreference interface of the dtls. + * @precon Set the signature algorithm preferred by the server. + * @brief + * 1. Initialize the hitls. + * 2. Create an SSL ctx object. + * 3. Create an SSL object. + * 4. Connect + * 5. Check for connection errors. + * 6. Check whether the negotiated signature algorithm is the server preference. + * @expect + * 1. successful + * 2. successful + * 3. successful + * 4. successful + * 5. successful + * 6. successful + */ +/* BEGIN_CASE */ +void SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC003(char *serverCipherSuite, char *clientCipherSuite) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HILT_TransportType connType = IsEnableSctpAuth() ? SCTP : TCP; + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath_2(serverCtxConfig, serverCipherSuite); + HLT_SetCipherSuites(serverCtxConfig, serverCipherSuite); + HLT_SetGroups(serverCtxConfig, "NULL"); + HLT_SetSignature(serverCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA384:CERT_SIG_SCHEME_RSA_PKCS1_SHA512"); + + serverRes = HLT_ProcessTlsAccept(localProcess, DTLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + int32_t ret = HITLS_SetCipherServerPreference(serverRes->ssl, true); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath_2(clientCtxConfig, clientCipherSuite); + HLT_SetCipherSuites(clientCtxConfig, clientCipherSuite); + HLT_SetGroups(clientCtxConfig, "NULL"); + HLT_SetSignature(clientCtxConfig, "CERT_SIG_SCHEME_RSA_PKCS1_SHA512:CERT_SIG_SCHEME_RSA_PKCS1_SHA384"); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, DTLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf[BUF_SZIE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, sizeof(readBuf), &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); + + HITLS_Ctx *testCtx = (HITLS_Ctx *)serverRes->ssl; + + ASSERT_TRUE(testCtx->negotiatedInfo.signScheme == CERT_SIG_SCHEME_RSA_PKCS1_SHA384); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** + * @test SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC004 + * @title To test the setting of the HITLS_SetCipherServerPreference interface of the dtls. + * @precon Set the preference group of the server. + * @brief + * 1. Initialize the hitls. + * 2. Create an SSL ctx object. + * 3. Create an SSL object. + * 4. Connect + * 5. Check for connection errors. + * 6. Check whether the negotiated group is the server preference. + * @expect + * 1. successful + * 2. successful + * 3. successful + * 4. successful + * 5. successful + * 6. successful + */ +/* BEGIN_CASE */ +void SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC004(char *serverCipherSuite, char *clientCipherSuite) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HILT_TransportType connType = IsEnableSctpAuth() ? SCTP : TCP; + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, g_uiPort, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath_2(serverCtxConfig, serverCipherSuite); + HLT_SetCipherSuites(serverCtxConfig, serverCipherSuite); + HLT_SetGroups(serverCtxConfig, "HITLS_EC_GROUP_SECP256R1:HITLS_EC_GROUP_SECP384R1"); + HLT_SetSignature(serverCtxConfig, "NULL"); + + serverRes = HLT_ProcessTlsAccept(localProcess, DTLS1_2, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + int32_t ret = HITLS_SetCipherServerPreference(serverRes->ssl, true); + ASSERT_TRUE(ret == HITLS_SUCCESS); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + SetCertPath_2(clientCtxConfig, clientCipherSuite); + HLT_SetCipherSuites(clientCtxConfig, clientCipherSuite); + HLT_SetGroups(clientCtxConfig, "HITLS_EC_GROUP_SECP384R1:HITLS_EC_GROUP_SECP256R1"); + HLT_SetSignature(clientCtxConfig, "NULL"); + + clientRes = HLT_ProcessTlsConnect(remoteProcess, DTLS1_2, clientCtxConfig, NULL); + + ASSERT_TRUE(clientRes != NULL); + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + uint8_t readBuf[BUF_SZIE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, sizeof(readBuf), &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); + + HITLS_Ctx *testCtx = (HITLS_Ctx *)serverRes->ssl; + + ASSERT_TRUE(testCtx->negotiatedInfo.negotiatedGroup == HITLS_EC_GROUP_SECP256R1); + +exit: + HLT_FreeAllProcess(); +} +/* END_CASE */ + +int32_t REC_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len); + +int32_t STUB_REC_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len) +{ + (void)ctx; + *len = 100; + return HITLS_SUCCESS; +} + +/* @ +* @test SDV_TLS_CM_FRAGMENTATION_FUNC_TC001 +* @title DTLS Message Fragmentation +* @precon nan +* @brief +* 1. Initialize the client and server processes. +* 2. The interface for obtaining the maximum message length is stubbed and the maximum message length is changed to 100. +* 3. Creat and connect linck. +* @expect +* 1. The initialization is successful. +* 2. The stub is successful. +* 3. The link is set up successfully. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CM_FRAGMENTATION_FUNC_TC001(void) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + HLT_Ctx_Config *serverConfig = NULL; + HLT_Ctx_Config *clientConfig = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + HILT_TransportType connType = IsEnableSctpAuth() ? SCTP : TCP; + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, Port, false); + ASSERT_TRUE(remoteProcess != NULL); + + serverConfig = HLT_NewCtxConfig(NULL, "SERVER"); + clientConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(serverConfig != NULL); + ASSERT_TRUE(clientConfig != NULL); + + serverRes = HLT_ProcessTlsAccept(remoteProcess, DTLS1_2, serverConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + + STUB_Init(); + FuncStubInfo stubInfo = {0}; + STUB_Replace(&stubInfo, REC_GetMaxWriteSize, STUB_REC_GetMaxWriteSize); + + clientRes = HLT_ProcessTlsInit(localProcess, DTLS1_2, clientConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) == 0); +exit: + STUB_Reset(&stubInfo); + HLT_FreeAllProcess(); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cm_interface.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cm_interface.data new file mode 100644 index 00000000..d28f3cb3 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_cm_interface.data @@ -0,0 +1,14 @@ +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001 +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC001:"HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":"HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":0xC030 + +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002 +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC002:"HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":"HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":0xC02F + +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC003 +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC003:"HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384":"HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384" + +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC004 +SDV_HITLS_CM_HITLS_GetNegotiateGroup_FUNC_TC004:"HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":"HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" + +SDV_TLS_CM_FRAGMENTATION_FUNC_TC001 +SDV_TLS_CM_FRAGMENTATION_FUNC_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_config_interface.c b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_config_interface.c new file mode 100644 index 00000000..484d86a5 --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_config_interface.c @@ -0,0 +1,676 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "bsl_sal.h" +#include "alert.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_crypt_reg.h" +#include "hitls_config.h" +#include "tls_config.h" +#include "hitls.h" +#include "hitls_func.h" +#include "pack_frame_msg.h" +#include "hlt.h" +#include "logger.h" +#include "hitls_cert_type.h" +#include "crypt_util_rand.h" +#include "common_func.h" +#include "frame_tls.h" +#include "conn_init.h" +#include "tls.h" +#include "simulate_io.h" +#include "frame_io.h" +#include "frame_link.h" +#include "stub_replace.h" +#include "session_type.h" +#include "cert_callback.h" +#include "bsl_sal.h" +#include "sal_net.h" +#include "parse_msg.h" +#include "hs_msg.h" +#include "hitls_crypt_init.h" +#include "uio_abstraction.h" +#include "process.h" +#include "rec_wrapper.h" +#include "hs_ctx.h" +#include "hitls_type.h" +/* END_HEADER */ + +#define Port 7788 +#define READ_BUF_SIZE 18432 +#define ROOT_DER "%s/ca.der:%s/inter.der" +#define INTCA_DER "%s/inter.der" +#define SERVER_DER "%s/server.der" +#define SERVER_KEY_DER "%s/server.key.der" +#define CLIENT_DER "%s/client.der" +#define CLIENT_KEY_DER "%s/client.key.der" +#define RENEGOTIATE_FAIL 1 +#define MAX_CERT_LIST 4294967295 +#define MIN_CERT_LIST 0 + +static uint32_t g_useFlight = 0; /* Range required in the test case */ +static uint32_t g_flag; /* Used to record the number of handshake messages in the current flight. */ +static uint32_t g_flight = 0; /* is used to record the number of the current flight */ +static HLT_FrameHandle g_frameHandle; +static HITLS_Config *GetHitlsConfigViaVersion(int ver) +{ + switch (ver) { + case TLS1_2: + case HITLS_VERSION_TLS12: + return HITLS_CFG_NewTLS12Config(); + case TLS1_3: + case HITLS_VERSION_TLS13: + return HITLS_CFG_NewTLS13Config(); + case DTLS1_2: + case HITLS_VERSION_DTLS12: + return HITLS_CFG_NewDTLS12Config(); + default: + return NULL; + } +} + +static void TEST_MsgHandle(void *msg, void *data) +{ + (void)data; + (void)msg; +} + +/* Verify whether the parsed msg meets the requirements. Restrict the msg input parameter. */ +static bool CheckHandleType(FRAME_Msg *msg) +{ + if (msg->recType.data != REC_TYPE_HANDSHAKE) { + if (msg->recType.data == (uint64_t)g_frameHandle.expectReType) { + return true; + } + } else { + if (msg->recType.data == (uint64_t)g_frameHandle.expectReType && + msg->body.hsMsg.type.data == (uint64_t)g_frameHandle.expectHsType) { + return true; + } + } + return false; +} + +/* Obtain the frameType. The input parameters frameHandle and frameType must not be empty. */ +static int32_t GetFrameType(HLT_FrameHandle *frameHandle, FRAME_Type *frameType) +{ + if (frameHandle->ctx == NULL) { + return HITLS_NULL_INPUT; + } + TLS_Ctx *tmpCtx = (TLS_Ctx *)frameHandle->ctx; + frameType->versionType = tmpCtx->negotiatedInfo.version > 0 ? + tmpCtx->negotiatedInfo.version : tmpCtx->config.tlsConfig.maxVersion; + frameType->keyExType = tmpCtx->hsCtx->kxCtx->keyExchAlgo; + frameType->recordType = frameHandle->expectReType; + frameType->handshakeType = frameHandle->expectHsType; + return HITLS_SUCCESS; +} + +static int32_t STUB_Write(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen) +{ + FRAME_Msg msg = {0}; + uint32_t parseLen = 0; + uint32_t offset = 0; + uint32_t msgCnt = 0; + FRAME_Type frameType = { 0 }; + (void)GetFrameType(&g_frameHandle, &frameType); + + g_flight++; + while (offset < len) { + (void)FRAME_ParseMsgHeader(&frameType, &((uint8_t*)buf)[offset], len - offset, &msg, &parseLen); + offset += parseLen + msg.length.data; + if (g_flight == g_useFlight) { + msgCnt++; + } + FRAME_CleanMsg(&frameType, &msg); + } + if (CheckHandleType(&msg) && g_flight == g_useFlight) { + g_flag = msgCnt; + } + + return BSL_UIO_TcpMethod()->write(uio, buf, len, writeLen); +} + + +static int SetCertPath(HLT_Ctx_Config *ctxConfig, const char *certStr, bool isServer) +{ + char caCertPath[50]; + char chainCertPath[30]; + char eeCertPath[30]; + char privKeyPath[30]; + + int32_t ret = sprintf_s(caCertPath, sizeof(caCertPath), ROOT_DER, certStr, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(chainCertPath, sizeof(chainCertPath), INTCA_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(eeCertPath, sizeof(eeCertPath), isServer ? SERVER_DER : CLIENT_DER, certStr); + ASSERT_TRUE(ret > 0); + ret = sprintf_s(privKeyPath, sizeof(privKeyPath), isServer ? SERVER_KEY_DER : CLIENT_KEY_DER, certStr); + ASSERT_TRUE(ret > 0); + HLT_SetCaCertPath(ctxConfig, (char *)caCertPath); + HLT_SetChainCertPath(ctxConfig, (char *)chainCertPath); + HLT_SetEeCertPath(ctxConfig, (char *)eeCertPath); + HLT_SetPrivKeyPath(ctxConfig, (char *)privKeyPath); + return 0; +exit: + return -1; +} + +/* @ +* @test SDV_TLS_CFG_SET_GET_VERIFYNONESUPPORT_FUNC_TC001 +* @title The server does not verify the client certificate. +* @precon nan +* @brief +* 1. The server invokes the HITLS_CFG_SetVerifyNoneSupport and sets the parameter to false. Expected result 1 is +* obtained. +* 2. The server invokes the HITLS_CFG_SetVerifyNoneSupport interface to obtain the configuration result. (Expected +* result 2) +* 3. The server invokes the HITLS_SetVerifyNoneSupport interface and sets it to true. Expected result 3 is obtained. +* 4. The server invokes the HITLS_GetVerifyNoneSupport interface to obtain the configuration result. (Expected result 4) +* 4. Establish a connection. Expected result 4 is obtained. +* @expect +* 1. The setting is successful. +* 2. The setting is successful. +* 3. The setting is successful. +* 4. The connection is successfully established. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_SET_GET_VERIFYNONESUPPORT_FUNC_TC001(int version, int connType) +{ + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + uint8_t c_flag = 0; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, connType, Port, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + SetCertPath(serverCtxConfig, "ecdsa_sha256", true); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + + serverRes = HLT_ProcessTlsAccept(localProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + HITLS_SetVerifyNoneSupport(serverRes->ssl, true); + HITLS_GetVerifyNoneSupport(serverRes->ssl, &c_flag); + ASSERT_TRUE(c_flag == 1); + + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetCertPath(clientCtxConfig, "ecdsa_sha256/ca.der", "NULL", "NULL", "NULL", "NULL", "NULL"); + HLT_SetCipherSuites(serverCtxConfig, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + + clientRes = HLT_ProcessTlsInit(remoteProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + ASSERT_EQ(HLT_RpcTlsConnect(remoteProcess, clientRes->sslId), HITLS_SUCCESS); + + ASSERT_TRUE(HLT_GetTlsAcceptResult(serverRes) == 0); + + ASSERT_TRUE(HLT_ProcessTlsWrite(localProcess, serverRes, (uint8_t *)"Hello World", strlen("Hello World")) == 0); + + uint8_t readBuf[READ_BUF_SIZE] = {0}; + uint32_t readLen; + ASSERT_TRUE(HLT_ProcessTlsRead(remoteProcess, clientRes, readBuf, sizeof(readBuf), &readLen) == 0); + ASSERT_TRUE(readLen == strlen("Hello World")); + ASSERT_TRUE(memcmp("Hello World", readBuf, readLen) == 0); + +exit: + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); +} +/* END_CASE */ + +/** @ +* @test HITLS_TLS1_2_Config_SDV_23_0_5_047 +* @title Enable dual-end verification. The server verifies the client certificate only once. +* @precon nan +* @brief +* 1. The server invokes the HITLS_CFG_SetClientVerifySupport and sets the parameter to true. +* 2. Set the value of HITLS_CFG_SetClientOnceVerifySupport to false when the server invokes the +* HITLS_CFG_SetClientOnceVerifySupport. +* 3. The server invokes the HITLS_CFG_SetClientOnceVerifySupport interface to obtain the configuration result. +* 4. The server invokes the HITLS_SetClientOnceVerifySupport interface and sets it to true. +* 5. The server invokes the HITLS_SetClientOnceVerifySupport interface to obtain the configuration result. +* 6. Establish a connection. After the connection is established, perform renegotiation. Stop the status on the server to +* TRY_SEND_CERTIFICATIONATE_REQUEST. The expected result is obtained. +* @expect +* 1. If the status fails to be stopped, the certificate will not be verified during the renegotiation. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_SET_GET_CLIENTVERIFYUPPORT_FUNC_TC001(int clientverify) +{ + FRAME_Init(); + + HITLS_Config *config_c = NULL; + HITLS_Config *config_s = NULL; + FRAME_LinkObj *client = NULL; + FRAME_LinkObj *server = NULL; + + config_c = HITLS_CFG_NewTLS12Config(); + config_s = HITLS_CFG_NewTLS12Config(); + + ASSERT_TRUE(config_c != NULL); + ASSERT_TRUE(config_s != NULL); + + uint8_t c_flag; + + if (clientverify) { + HITLS_CFG_SetClientVerifySupport(config_s, true); + } else { + HITLS_CFG_SetClientVerifySupport(config_s, false); + } + + HITLS_CFG_SetClientOnceVerifySupport(config_s, false); + HITLS_CFG_GetClientOnceVerifySupport(config_s, &c_flag); + ASSERT_TRUE(c_flag == 0); + + client = FRAME_CreateLink(config_c, BSL_UIO_TCP); + ASSERT_TRUE(client != NULL); + server = FRAME_CreateLink(config_s, BSL_UIO_TCP); + ASSERT_TRUE(server != NULL); + HITLS_SetClientOnceVerifySupport(server->ssl, true); + HITLS_GetClientOnceVerifySupport(server->ssl, &c_flag); + ASSERT_TRUE(c_flag == 1); + HITLS_SetRenegotiationSupport(server->ssl, true); + HITLS_SetRenegotiationSupport(client->ssl, true); + HITLS_GetRenegotiationSupport(server->ssl, &c_flag); + ASSERT_TRUE(c_flag == 1); + + ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS); + + uint8_t verifyDataNew[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataNewSize = 0; + uint8_t verifyDataOld[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataOldSize = 0; + ASSERT_TRUE(HITLS_GetFinishVerifyData(server->ssl, verifyDataOld, sizeof(verifyDataOld), + &verifyDataOldSize) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_Renegotiate(client->ssl) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_Renegotiate(server->ssl) == HITLS_SUCCESS); + ASSERT_EQ(FRAME_CreateConnection(client, server, false, TRY_SEND_CERTIFICATE_REQUEST), HITLS_INTERNAL_EXCEPTION); + ASSERT_TRUE(HITLS_GetFinishVerifyData(server->ssl, verifyDataNew, sizeof(verifyDataNew), + &verifyDataNewSize) == HITLS_SUCCESS); + ASSERT_TRUE(memcmp(verifyDataNew, verifyDataOld, verifyDataOldSize) != 0); +exit: + HITLS_CFG_FreeConfig(config_c); + HITLS_CFG_FreeConfig(config_s); + FRAME_FreeLink(client); + FRAME_FreeLink(server); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_ADD_CAINDICATION_FUNC_TC001 +* @title: Add different CA flag indication types. +* @precon nan +* @brief +* 1. Invoke the HITLS_CFG_AddCAIndication interface and set the transferred caType to HITLS_TRUSTED_CA_PRE_AGREED and +* HITLS_TRUSTED_CA_PRE_AGREED respectively. HITLS_TRUSTED_CA_KEY_SHA1, HITLS_TRUSTED_CA_X509_NAME, +* HITLS_TRUSTED_CA_CERT_SHA1, When the HITLS_TRUSTED_CA_UNKNOWN macro is used, expected result 1 is obtained. +* 2. Check the return value of the interface. Expected result 2 is obtained. +* @expect +* 1. The invoking is successful. +* 2. The interface returns HITLS_SUCCESS. +@ */ + +/* BEGIN_CASE */ +void SDV_TLS_CFG_ADD_CAINDICATION_FUNC_TC001(int tlsVersion) +{ + FRAME_Init(); + HITLS_Config *config = NULL; + uint8_t data[] = {0}; + uint32_t len = sizeof(data); + + config = GetHitlsConfigViaVersion(tlsVersion); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_PRE_AGREED, data, len) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_KEY_SHA1, data, len) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_X509_NAME, data, len) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_CERT_SHA1, data, len) == HITLS_SUCCESS); + + ASSERT_TRUE(HITLS_CFG_AddCAIndication(config, HITLS_TRUSTED_CA_UNKNOWN, data, len) == HITLS_SUCCESS); +exit: + HITLS_CFG_FreeConfig(config); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_CIPHERBYID_FUNC_TC001 +* @title Obtain the CipherId based on the known cipher suite. +* @precon nan +* @brief +* 1. Invoke the HITLS_CFG_GetCipherByID and set the transferred id to the HITLS_AES_128_GCM_SHA256 macro to obtain the +* HITLS_Cipher structure. (Expected result 1) +* 2. Invoke the HITLS_CFG_GetCipherId interface and transfer the obtained structure. (Expected result 2) +* @expect +* 1. The interface returns the corresponding HITLS_Cipher structure. +* 2. HITLS_CIPHER_AES_128_GCM is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_CIPHERBYID_FUNC_TC001() +{ + FRAME_Init(); + HITLS_CipherAlgo cipherAlgo; + + + const HITLS_Cipher* cipher = HITLS_CFG_GetCipherByID(HITLS_AES_128_GCM_SHA256); + HITLS_CFG_GetCipherId(cipher, &cipherAlgo); + ASSERT_EQ(cipherAlgo, HITLS_CIPHER_AES_128_GCM); + +exit: + return; +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_AUTHID_FUNC_TC001 +* @title Self-registration cipher. Invoke the interface to obtain the AuthId. +* @precon nan +* @brief +* 1. Register a HITLS_Cipher structure, set cipherid to HITLS_AUTH_NULL, and call HITLS_CFG_GetAuthId. Expected result 1 +* is obtained. +* @expect +* 1. HITLS_AUTH_NULL is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_AUTHID_FUNC_TC001() +{ + FRAME_Init(); + HITLS_AuthAlgo cipherSuite; + HITLS_Cipher *cipher = (HITLS_Cipher *)malloc(sizeof(HITLS_Cipher)); + cipher->authAlg = HITLS_AUTH_NULL; + + HITLS_CFG_GetAuthId(cipher, &cipherSuite); + ASSERT_EQ(cipherSuite, HITLS_AUTH_NULL); + +exit: + free(cipher); +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_CIPHERSUITENAME_FUNC_TC001 +* @title Query the name of the algorithm suite. +* @precon nan +* @brief +* 1. Set cipher to HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 and invoke the HITLS_CFG_GetCipherSuiteName interface. +* Expected result 1 is obtained. +* @expect +* 1. Return value of the char* conversion interface, which is the same as that of the +* HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_CIPHERSUITENAME_FUNC_TC001() +{ + FRAME_Init(); + const HITLS_Cipher* cipher = HITLS_CFG_GetCipherByID(HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256); + + const uint8_t* name = HITLS_CFG_GetCipherSuiteName(cipher); + ASSERT_TRUE(strcmp((char *)name, "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0); +exit: + return; +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_CIPHERVERSION_FUNC_TC001 +* @title Query the cipher suite version and obtain the algorithm based on the ID. +* @precon nan +* @brief +* 1. Set cipher to HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 () and invoke the HITLS_CFG_GetCipherVersion interface. +* (Expected result 1) +* 2. Set cipher to HITLS_AES_128_GCM_SHA256 () and invoke the HITLS_CFG_GetCipherVersion interface. (Expected result 2) +* 3. Set cipher to HITLS_RSA_WITH_AES_128_CBC_SHA () and invoke the HITLS_CFG_GetCipherVersion interface. (Expected +* result 3) +* @expect +* 1. Interface return value: HITLS_VERSION_TLS12 +* 2. Interface return value: HITLS_VERSION_TLS13, HITLS_VERSION_TLS13 +* 3. Interface return value: HITLS_VERSION_SSL30 +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_CIPHERVERSION_FUNC_TC001() +{ + FRAME_Init(); + int32_t version; + const HITLS_Cipher *cipher = HITLS_CFG_GetCipherByID(HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256); + ASSERT_EQ(HITLS_CFG_GetCipherVersion(cipher, &version), HITLS_SUCCESS); + ASSERT_EQ(HITLS_VERSION_TLS12, version); + + cipher = HITLS_CFG_GetCipherByID(HITLS_AES_128_GCM_SHA256); + ASSERT_EQ(HITLS_CFG_GetCipherVersion(cipher, &version), HITLS_SUCCESS); + ASSERT_EQ(HITLS_VERSION_TLS13, version); + + cipher = HITLS_CFG_GetCipherByID(HITLS_RSA_WITH_AES_128_CBC_SHA); + ASSERT_EQ(HITLS_CFG_GetCipherVersion(cipher, &version), HITLS_SUCCESS); + ASSERT_EQ(HITLS_VERSION_SSL30, version); +exit: + version = 1; +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_CIPHERSUITE_FUNC_TC001 +* @title Obtain the cipher suite based on the supported cipher suite ID. +* @precon nan +* @brief +* 1. Invoke the HITLS_CFG_GetCipherByID and set the input ID to the HITLS_AES_128_GCM_SHA256 macro to obtain the +* cipherinfo structure. Expected result 1 is obtained. +* 2. Invoke the HITLS_CFG_GetCipherSuite interface and transfer the obtained structure. (Expected result 2) +* @expect +* 1. The interface returns the corresponding HITLS_Cipher structure. +* 2. HITLS_AES_128_GCM_SHA256 is returned. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_CIPHERSUITE_FUNC_TC001() +{ + FRAME_Init(); + uint16_t cipherSuite; + const HITLS_Cipher* cipher = HITLS_CFG_GetCipherByID(HITLS_AES_128_GCM_SHA256); + + HITLS_CFG_GetCipherSuite(cipher, &cipherSuite); + ASSERT_EQ(cipherSuite, HITLS_AES_128_GCM_SHA256); + +exit: + return; +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_FLIGHTTRANSMITSWITH_FUNC_TC001 +* @titleThe client sends messages by flight. +* @precon nan +* @brief 1. The server invokes the HITLS_CFG_SetFlightTransmitSwitch interface and sets the parameter to false. Expected + result 1 is obtained. + 2. The server invokes the HITLS_CFG_GetFlightTransmitSwitch interface to obtain the configuration result. + (Expected result 2) + 3. The client invokes the HITLS_SetFlightTransmitSwitch interface to set the parameter to true. Expected result + 3 is obtained. + 4. The client invokes the HITLS_GetFlightTransmitSwitch interface to obtain the configuration result. Expected + result 4 is obtained. + 5. Establish a link and count the number of messages sent by the client in the second flight. Expected result 5 + is obtained. +* @expect + 1. The setting is successful. + 2. The obtained result is false. + 3. The setting is successful. + 4. The obtained result is true. + 5. The connection is set up successfully, and the number of the second flight messages sent by the client is 3. +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_FLIGHTTRANSMITSWITH_FUNC_TC001(int version) +{ + FRAME_Init(); + + HITLS_Config *Config = NULL; + HITLS_Ctx *ctx = NULL; + uint8_t support; + Config = GetHitlsConfigViaVersion(version); + ASSERT_TRUE(Config != NULL); + ctx = HITLS_New(Config); + ASSERT_TRUE(ctx != NULL); + + HITLS_CFG_SetFlightTransmitSwitch(Config, false); + HITLS_CFG_GetFlightTransmitSwitch(Config, &support); + ASSERT_TRUE(support == false); + + HITLS_SetFlightTransmitSwitch(ctx, true); + HITLS_GetFlightTransmitSwitch(ctx, &support); + ASSERT_TRUE(support == true); + + HLT_Tls_Res *serverRes = NULL; + HLT_Tls_Res *clientRes = NULL; + HLT_Process *localProcess = NULL; + HLT_Process *remoteProcess = NULL; + + localProcess = HLT_InitLocalProcess(HITLS); + ASSERT_TRUE(localProcess != NULL); + remoteProcess = HLT_LinkRemoteProcess(HITLS, TCP, Port, true); + ASSERT_TRUE(remoteProcess != NULL); + + HLT_Ctx_Config *serverCtxConfig = HLT_NewCtxConfig(NULL, "SERVER"); + ASSERT_TRUE(serverCtxConfig != NULL); + + HLT_SetFlightTransmitSwitch(serverCtxConfig, false); + serverRes = HLT_ProcessTlsAccept(remoteProcess, version, serverCtxConfig, NULL); + ASSERT_TRUE(serverRes != NULL); + HLT_Ctx_Config *clientCtxConfig = HLT_NewCtxConfig(NULL, "CLIENT"); + ASSERT_TRUE(clientCtxConfig != NULL); + + HLT_SetFlightTransmitSwitch(clientCtxConfig, true); + clientRes = HLT_ProcessTlsInit(localProcess, version, clientCtxConfig, NULL); + ASSERT_TRUE(clientRes != NULL); + + HLT_FrameHandle frameHandle = { + .ctx = clientRes->ssl, + .frameCallBack = TEST_MsgHandle, + .userData = NULL, + .expectHsType = CLIENT_KEY_EXCHANGE, + .expectReType = REC_TYPE_HANDSHAKE, + .ioState = EXP_NONE, + .pointType = POINT_SEND, + .method.write = STUB_Write, + }; + ASSERT_TRUE(HLT_SetFrameHandle(&frameHandle) == HITLS_SUCCESS); + g_useFlight = 2; + ASSERT_TRUE(HLT_TlsConnect(clientRes->ssl) == HITLS_SUCCESS); + if (version == TLS1_2) { + ASSERT_EQ(g_flag, 3); + } else { + ASSERT_EQ(g_flag, 2); + } + + HLT_CleanFrameHandle(); +exit: + g_flag = 0; + g_flight = 0; + HLT_CleanFrameHandle(); + HLT_FreeAllProcess(); + HITLS_CFG_FreeConfig(Config); + HITLS_Free(ctx); + return; +} +/* END_CASE */ + +/** @ +* @test SDV_TLS_CFG_GET_MAXCERTLIST_API_TC001 +* @title HTLS_CFG_SetMaxCertList, HITLS_CFG_GetMaxCertList, HITLS_SetMaxCertList, and HITLS_GetMaxCertList APIs +* @precon nan +* @brief +* 1. Apply for and initialize config and ctx. +* 2. Set the certificate chain length config to null and invoke the HITLS_CFG_SetMaxCertList interface. +* 3. Invoke the HITLS_CFG_GetMaxCertList interface and check the output parameter value. +* 4. Set the maximum length of the certificate chain by calling the HITLS_CFG_SetMaxCertList interface. +* 5. Invoke the HITLS_CFG_GetMaxCertList interface and check the output parameter value. +* 6. Set the minimum certificate chain length by calling the HITLS_CFG_SetMaxCertList interface. +* 7. Invoke the HITLS_CFG_GetMaxCertList interface and check the output parameter value. +* 8. Use the HITLS_SetMaxCertList and HITLS_GetMaxCertList interfaces to repeat the preceding test. +* @expect +* 1. Initialization succeeds. +* 2. HITLS_NULL_INPUT is returned. +* 3. HITLS_NULL_INPUT is returned. +* 4. The interface returns HITLS_SUCCESS. +* 5. The value of MaxCertList returned by the interface is 2 ^ 32 - 1. +* 6. The interface returns the HITLS_SUCCESS. +* 7. The value of MaxCertList returned by the interface is 0. +* 8. Same as above +@ */ +/* BEGIN_CASE */ +void SDV_TLS_CFG_GET_MAXCERTLIST_API_TC001() +{ + FRAME_Init(); + HITLS_Config *tlsConfig; + HITLS_Ctx *ctx = NULL; + tlsConfig = HITLS_CFG_NewTLS12Config(); + ASSERT_TRUE(tlsConfig != NULL); + ctx = HITLS_New(tlsConfig); + ASSERT_TRUE(ctx != NULL); + uint32_t maxSize; + + ASSERT_TRUE(HITLS_CFG_SetMaxCertList(NULL, MAX_CERT_LIST) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_GetMaxCertList(NULL, &maxSize) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_CFG_SetMaxCertList(tlsConfig, MAX_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxCertList(tlsConfig, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MAX_CERT_LIST); + + ASSERT_TRUE(HITLS_CFG_SetMaxCertList(tlsConfig, MIN_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_CFG_GetMaxCertList(tlsConfig, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MIN_CERT_LIST); + + ASSERT_TRUE(HITLS_SetMaxCertList(NULL, MAX_CERT_LIST) == HITLS_NULL_INPUT); + ASSERT_TRUE(HITLS_GetMaxCertList(NULL, &maxSize) == HITLS_NULL_INPUT); + + ASSERT_TRUE(HITLS_SetMaxCertList(ctx, MAX_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetMaxCertList(ctx, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MAX_CERT_LIST); + + ASSERT_TRUE(HITLS_SetMaxCertList(ctx, MIN_CERT_LIST) == HITLS_SUCCESS); + ASSERT_TRUE(HITLS_GetMaxCertList(ctx, &maxSize) == HITLS_SUCCESS); + ASSERT_TRUE(maxSize == MIN_CERT_LIST); +exit: + HITLS_CFG_FreeConfig(tlsConfig); + HITLS_Free(ctx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_config_interface.data b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_config_interface.data new file mode 100644 index 00000000..b47f073d --- /dev/null +++ b/testcode/sdv/testcase/tls/interface_tlcp/test_suite_sdv_hlt_config_interface.data @@ -0,0 +1,35 @@ +SDV_TLS_CFG_SET_GET_VERIFYNONESUPPORT_FUNC_TC001 +SDV_TLS_CFG_SET_GET_VERIFYNONESUPPORT_FUNC_TC001:TLS1_2:TCP + +SDV_TLS_CFG_SET_GET_VERIFYNONESUPPORT_FUNC_TC001 +SDV_TLS_CFG_SET_GET_VERIFYNONESUPPORT_FUNC_TC001:TLS1_3:TCP + +SDV_TLS_CFG_SET_GET_CLIENTVERIFYUPPORT_FUNC_TC001 +SDV_TLS_CFG_SET_GET_CLIENTVERIFYUPPORT_FUNC_TC001:0 + +SDV_TLS_CFG_SET_GET_CLIENTVERIFYUPPORT_FUNC_TC001 +SDV_TLS_CFG_SET_GET_CLIENTVERIFYUPPORT_FUNC_TC001:1 + +SDV_TLS_CFG_GET_CIPHERBYID_FUNC_TC001 +SDV_TLS_CFG_GET_CIPHERBYID_FUNC_TC001: + +SDV_TLS_CFG_GET_AUTHID_FUNC_TC001 +SDV_TLS_CFG_GET_AUTHID_FUNC_TC001: + +SDV_TLS_CFG_GET_CIPHERSUITENAME_FUNC_TC001 +SDV_TLS_CFG_GET_CIPHERSUITENAME_FUNC_TC001: + +SDV_TLS_CFG_GET_CIPHERVERSION_FUNC_TC001 +SDV_TLS_CFG_GET_CIPHERVERSION_FUNC_TC001: + +SDV_TLS_CFG_GET_CIPHERSUITE_FUNC_TC001 +SDV_TLS_CFG_GET_CIPHERSUITE_FUNC_TC001: + +SDV_TLS_CFG_GET_FLIGHTTRANSMITSWITH_FUNC_TC001 +SDV_TLS_CFG_GET_FLIGHTTRANSMITSWITH_FUNC_TC001:TLS1_2 + +SDV_TLS_CFG_GET_FLIGHTTRANSMITSWITH_FUNC_TC001 +SDV_TLS_CFG_GET_FLIGHTTRANSMITSWITH_FUNC_TC001:TLS1_3 + +SDV_TLS_CFG_GET_MAXCERTLIST_API_TC001 +SDV_TLS_CFG_GET_MAXCERTLIST_API_TC001: \ No newline at end of file diff --git a/testcode/sdv/testcase/x509/cert/test_suite_sdv_x509_cert.c b/testcode/sdv/testcase/x509/cert/test_suite_sdv_x509_cert.c new file mode 100644 index 00000000..df2e5304 --- /dev/null +++ b/testcode/sdv/testcase/x509/cert/test_suite_sdv_x509_cert.c @@ -0,0 +1,1300 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_sal.h" +#include "securec.h" +#include "stub_replace.h" +#include "hitls_x509.h" +#include "hitls_x509_errno.h" +#include "bsl_type.h" +#include "bsl_log.h" +#include "hitls_cert_local.h" +#include "bsl_init.h" +#include "bsl_obj_internal.h" +#include "sal_time.h" +#include "sal_file.h" +#include "crypt_encode.h" +#include "crypt_eal_encode.h" +#include "hitls_x509_local.h" + +/* END_HEADER */ + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para1, para2, para3, para4); + printf("\n"); +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para); + printf("\n"); +} + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_FUNC_TC001(int format, char *path) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_X509_CertParseFile(format, path, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +static int32_t HITLS_ParseCertTest(char *path, int32_t fromat, HITLS_X509_Cert **cert) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + int32_t ret = BSL_LOG_RegBinLogFunc(&func); + if (ret != BSL_SUCCESS) { + return ret; + } + + return HITLS_X509_CertParseFile(fromat, path, cert); +} + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_VERSION_FUNC_TC001(char *path, int version) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(cert->tbs.version, version); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001(char *path, Hex *serialNum) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(cert->tbs.serialNum.tag, 2); + ASSERT_COMPARE("serialNum", cert->tbs.serialNum.buff, cert->tbs.serialNum.len, + serialNum->x, serialNum->len); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001(char *path, int signAlg, + int rsaPssHash, int rsaPssMgf1, int rsaPssSaltLen) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(cert->tbs.signAlgId.algId, signAlg); + ASSERT_EQ(cert->tbs.signAlgId.rsaPssParam.mdId, rsaPssHash); + ASSERT_EQ(cert->tbs.signAlgId.rsaPssParam.mgfId, rsaPssMgf1); + ASSERT_EQ(cert->tbs.signAlgId.rsaPssParam.saltLen, rsaPssSaltLen); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001(char *path, int count, + Hex *type1, int tag1, Hex *value1, + Hex *type2, int tag2, Hex *value2, + Hex *type3, int tag3, Hex *value3, + Hex *type4, int tag4, Hex *value4, + Hex *type5, int tag5, Hex *value5, + Hex *type6, int tag6, Hex *value6) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x}, + {6, type2->len, type2->x}, {(uint8_t)tag2, value2->len, value2->x}, + {6, type3->len, type3->x}, {(uint8_t)tag3, value3->len, value3->x}, + {6, type4->len, type4->x}, {(uint8_t)tag4, value4->len, value4->x}, + {6, type5->len, type5->x}, {(uint8_t)tag5, value5->len, value5->x}, + {6, type6->len, type6->x}, {(uint8_t)tag6, value6->len, value6->x}, + }; + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.issuerName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(cert->tbs.issuerName); + for (int i = 0; i < count; i += 2) { + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(cert->tbs.issuerName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(cert->tbs.issuerName); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC002(char *path, int count, + Hex *type1, int tag1, Hex *value1) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x} + }; + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.issuerName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(cert->tbs.issuerName); + for (int i = 0; i < count; i += 2) { + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(cert->tbs.issuerName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(cert->tbs.issuerName); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003(char *path, int count, + Hex *type1, int tag1, Hex *value1, + Hex *type2, int tag2, Hex *value2, + Hex *type3, int tag3, Hex *value3, + Hex *type4, int tag4, Hex *value4, + Hex *type5, int tag5, Hex *value5) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x}, + {6, type2->len, type2->x}, {(uint8_t)tag2, value2->len, value2->x}, + {6, type3->len, type3->x}, {(uint8_t)tag3, value3->len, value3->x}, + {6, type4->len, type4->x}, {(uint8_t)tag4, value4->len, value4->x}, + {6, type5->len, type5->x}, {(uint8_t)tag5, value5->len, value5->x} + }; + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.issuerName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(cert->tbs.issuerName); + for (int i = 0; i < count; i += 2) { + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(cert->tbs.issuerName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(cert->tbs.issuerName); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_TIME_FUNC_TC001(char *path) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_ERR_CHECK_TAG); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001(char *path, + int year, int month, int day, int hour, int minute, int second) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(cert->tbs.validTime.start.year, year); + ASSERT_EQ(cert->tbs.validTime.start.month, month); + ASSERT_EQ(cert->tbs.validTime.start.day, day); + ASSERT_EQ(cert->tbs.validTime.start.hour, hour); + ASSERT_EQ(cert->tbs.validTime.start.minute, minute); + ASSERT_EQ(cert->tbs.validTime.start.second, second); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001(char *path, + int year, int month, int day, int hour, int minute, int second) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(cert->tbs.validTime.end.year, year); + ASSERT_EQ(cert->tbs.validTime.end.month, month); + ASSERT_EQ(cert->tbs.validTime.end.day, day); + ASSERT_EQ(cert->tbs.validTime.end.hour, hour); + ASSERT_EQ(cert->tbs.validTime.end.minute, minute); + ASSERT_EQ(cert->tbs.validTime.end.second, second); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001(char *path, int count, + Hex *type1, int tag1, Hex *value1, + Hex *type2, int tag2, Hex *value2, + Hex *type3, int tag3, Hex *value3, + Hex *type4, int tag4, Hex *value4, + Hex *type5, int tag5, Hex *value5, + Hex *type6, int tag6, Hex *value6) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x}, + {6, type2->len, type2->x}, {(uint8_t)tag2, value2->len, value2->x}, + {6, type3->len, type3->x}, {(uint8_t)tag3, value3->len, value3->x}, + {6, type4->len, type4->x}, {(uint8_t)tag4, value4->len, value4->x}, + {6, type5->len, type5->x}, {(uint8_t)tag5, value5->len, value5->x}, + {6, type6->len, type6->x}, {(uint8_t)tag6, value6->len, value6->x}, + }; + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.subjectName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(cert->tbs.subjectName); + for (int i = 0; i < count; i += 2) { + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(cert->tbs.subjectName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(cert->tbs.subjectName); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC002(char *path, int count, + Hex *type1, int tag1, Hex *value1) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x} + }; + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.subjectName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(cert->tbs.subjectName); + for (int i = 0; i < count; i += 2) { + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(cert->tbs.subjectName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(cert->tbs.subjectName); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003(char *path, int count, + Hex *type1, int tag1, Hex *value1, + Hex *type2, int tag2, Hex *value2, + Hex *type3, int tag3, Hex *value3, + Hex *type4, int tag4, Hex *value4, + Hex *type5, int tag5, Hex *value5) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x}, + {6, type2->len, type2->x}, {(uint8_t)tag2, value2->len, value2->x}, + {6, type3->len, type3->x}, {(uint8_t)tag3, value3->len, value3->x}, + {6, type4->len, type4->x}, {(uint8_t)tag4, value4->len, value4->x}, + {6, type5->len, type5->x}, {(uint8_t)tag5, value5->len, value5->x} + }; + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.subjectName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(cert->tbs.subjectName); + for (int i = 0; i < count; i += 2) { + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(cert->tbs.subjectName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(cert->tbs.subjectName); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_CTRL_FUNC_TC001(char *path, int expRawDataLen, int expSignAlg, + int expKuDigitailSign, int expKuCertSign, int expKuKeyAgreement) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + int32_t rawDataLen; + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODELEN, &rawDataLen, sizeof(rawDataLen)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(rawDataLen, expRawDataLen); + + uint8_t *rawData = NULL; + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODE, &rawData, 0); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(rawData, NULL); + + void *ealKey = NULL; + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_PUBKEY, &ealKey, 0); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(ealKey, NULL); + CRYPT_EAL_PkeyFreeCtx(ealKey); + + int32_t alg = 0; + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SIGNALG, &alg, sizeof(alg)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(alg, expSignAlg); + + int32_t ref = 0; + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_REF_UP, &ref, sizeof(ref)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ref, 2); + HITLS_X509_CertFree(cert); + + bool isTrue = false; + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_KU_DIGITALSIGN, &isTrue, sizeof(isTrue)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(isTrue, expKuDigitailSign); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_KU_CERTSIGN, &isTrue, sizeof(isTrue)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(isTrue, expKuCertSign); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_KU_KEYAGREEMENT, &isTrue, sizeof(isTrue)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(isTrue, expKuKeyAgreement); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_CTRL_FUNC_TC002(char *path, char *expectedSerialNum, char *expectedSubjectName, + char *expectedIssueName, char *expectedBeforeTime, char *expectedAfterTime) +{ + HITLS_X509_Cert *cert = NULL; + BSL_Buffer subjectName = { NULL, 0 }; + BSL_Buffer issuerName = { NULL, 0 }; + BSL_Buffer serialNum = { NULL, 0 }; + BSL_Buffer beforeTime = { NULL, 0 }; + BSL_Buffer afterTime = { NULL, 0 }; + + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SUBJECT_DNNAME_STR, &subjectName, sizeof(BSL_Buffer)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(subjectName.data, NULL); + ASSERT_EQ(subjectName.dataLen, strlen(expectedSubjectName)); + ASSERT_EQ(strcmp((char *)subjectName.data, expectedSubjectName), 0); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ISSUER_DNNAME_STR, &issuerName, sizeof(BSL_Buffer)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(issuerName.data, NULL); + ASSERT_EQ(issuerName.dataLen, strlen(expectedIssueName)); + ASSERT_EQ(strcmp((char *)issuerName.data, expectedIssueName), 0); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SERIALNUM, &serialNum, sizeof(BSL_Buffer)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(serialNum.data, NULL); + ASSERT_EQ(serialNum.dataLen, strlen(expectedSerialNum)); + ASSERT_EQ(strcmp((char *)serialNum.data, expectedSerialNum), 0); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_BEFORE_TIME, &beforeTime, sizeof(BSL_Buffer)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(beforeTime.data, NULL); + ASSERT_EQ(beforeTime.dataLen, strlen(expectedBeforeTime)); + ASSERT_EQ(strcmp((char *)beforeTime.data, expectedBeforeTime), 0); + + ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_AFTER_TIME, &afterTime, sizeof(BSL_Buffer)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(afterTime.data, NULL); + ASSERT_EQ (afterTime.dataLen, strlen(expectedAfterTime)); + ASSERT_EQ(strcmp((char *)afterTime.data, expectedAfterTime), 0); +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_FREE(subjectName.data); + BSL_SAL_FREE(issuerName.data); + BSL_SAL_FREE(serialNum.data); + BSL_SAL_FREE(beforeTime.data); + BSL_SAL_FREE(afterTime.data); + BSL_GLOBAL_DeInit(); + return; +} + +/* END_CASE */ +// subkey +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001(char *path, char *path2) +{ + HITLS_X509_Cert *cert = NULL; + HITLS_X509_Cert *cert2 = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_ParseCertTest(path2, BSL_FORMAT_ASN1, &cert2); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CheckSignature(cert2->tbs.ealPubKey, cert->tbs.tbsRawData, cert->tbs.tbsRawDataLen, + &cert->signAlgId, &cert->signature); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + HITLS_X509_CertFree(cert); + HITLS_X509_CertFree(cert2); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_DUP_FUNC_TC001(char *path, int expSignAlg, + int expKuDigitailSign, int expKuCertSign, int expKuKeyAgreement) +{ + HITLS_X509_Cert *cert = NULL; + HITLS_X509_Cert *dest = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ret = HITLS_X509_CertDup(cert, &dest); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + int32_t alg = 0; + ret = HITLS_X509_CertCtrl(dest, HITLS_X509_GET_SIGNALG, &alg, sizeof(alg)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(alg, expSignAlg); + + bool isTrue = false; + ret = HITLS_X509_CertCtrl(dest, HITLS_X509_EXT_KU_DIGITALSIGN, &isTrue, sizeof(isTrue)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(isTrue, expKuDigitailSign); + + ret = HITLS_X509_CertCtrl(dest, HITLS_X509_EXT_KU_CERTSIGN, &isTrue, sizeof(isTrue)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(isTrue, expKuCertSign); + + ret = HITLS_X509_CertCtrl(dest, HITLS_X509_EXT_KU_KEYAGREEMENT, &isTrue, sizeof(isTrue)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(isTrue, expKuKeyAgreement); + +exit: + HITLS_X509_CertFree(cert); + HITLS_X509_CertFree(dest); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_EXT_ERROR_TC001(char *path, int ret) +{ + HITLS_X509_Cert *cert = NULL; + ASSERT_EQ(HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert), ret); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_EXTENSIONS_FUNC_TC001(char *path, int extNum, int isCA, int maxPathLen, int keyUsage, + int cid1, Hex *oid1, int cr1, Hex *val1, + int cid2, Hex *oid2, int cr2, Hex *val2, + int cid3, Hex *oid3, int cr3, Hex *val3) +{ + HITLS_X509_Cert *cert = NULL; + HITLS_X509_ExtEntry **node = NULL; + ASSERT_EQ(HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert), HITLS_X509_SUCCESS); + ASSERT_EQ(cert->tbs.ext.isCa, isCA); + ASSERT_EQ(cert->tbs.ext.maxPathLen, maxPathLen); + ASSERT_EQ(cert->tbs.ext.keyUsage, keyUsage); + ASSERT_EQ(BSL_LIST_COUNT(cert->tbs.ext.list), extNum); + + HITLS_X509_ExtEntry arr[] = { + {cid1, {BSL_ASN1_TAG_OBJECT_ID, oid1->len, oid1->x}, cr1, {BSL_ASN1_TAG_OCTETSTRING, val1->len, val1->x}}, + {cid2, {BSL_ASN1_TAG_OBJECT_ID, oid2->len, oid2->x}, cr2, {BSL_ASN1_TAG_OCTETSTRING, val2->len, val2->x}}, + {cid3, {BSL_ASN1_TAG_OBJECT_ID, oid3->len, oid3->x}, cr3, {BSL_ASN1_TAG_OCTETSTRING, val3->len, val3->x}}, + }; + node = BSL_LIST_First(cert->tbs.ext.list); + for (int i = 0; i < 3; i++) { // Check the first 3 extensions + ASSERT_NE((*node), NULL); + ASSERT_EQ((*node)->critical, arr[i].critical); + ASSERT_EQ((*node)->extnId.tag, arr[i].extnId.tag); + ASSERT_COMPARE("oid", (*node)->extnId.buff, (*node)->extnId.len, arr[i].extnId.buff, arr[i].extnId.len); + ASSERT_EQ((*node)->extnValue.tag, arr[i].extnValue.tag); + ASSERT_COMPARE( + "value", (*node)->extnValue.buff, (*node)->extnValue.len, arr[i].extnValue.buff, arr[i].extnValue.len); + node = BSL_LIST_Next(cert->tbs.ext.list); + } +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +// sign alg +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001(char *path, int signAlg, + int rsaPssHash, int rsaPssMgf1, int rsaPssSaltLen) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(cert->signAlgId.algId, signAlg); + ASSERT_EQ(cert->signAlgId.rsaPssParam.mdId, rsaPssHash); + ASSERT_EQ(cert->signAlgId.rsaPssParam.mgfId, rsaPssMgf1); + ASSERT_EQ(cert->signAlgId.rsaPssParam.saltLen, rsaPssSaltLen); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +// signature +/* BEGIN_CASE */ +void SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001(char *path, Hex *buff, int unusedBits) +{ + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(cert->signature.len, buff->len); + ASSERT_COMPARE("signature", cert->signature.buff, cert->signature.len, buff->x, buff->len); + ASSERT_EQ(cert->signature.unusedBits, unusedBits); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_MUL_CERT_PARSE_FUNC_TC001(int format, char *path, int certNum) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_List *list = NULL; + int32_t ret = HITLS_X509_CertMulParseFile(format, path, &list); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(list), certNum); +exit: + BSL_LIST_FREE(list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_VERIOSN_FUNC_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + ASSERT_EQ(cert->tbs.version, HITLS_CERT_VERSION_1); + + int32_t version = HITLS_CERT_VERSION_2; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_VERSION, &version, sizeof(int32_t)), HITLS_X509_SUCCESS); + ASSERT_EQ(cert->tbs.version, version); + + version = HITLS_CERT_VERSION_3; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_VERSION, &version, sizeof(int32_t)), HITLS_X509_SUCCESS); + ASSERT_EQ(cert->tbs.version, version); + + // valLen + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_VERSION, &version, 1), HITLS_X509_ERR_INVALID_PARAM); + + // val + version = HITLS_CERT_VERSION_3 + 1; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_VERSION, &version, sizeof(int32_t)), + HITLS_X509_ERR_INVALID_PARAM); + +exit: + HITLS_X509_CertFree(cert); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_SERIAL_FUNC_TC001(Hex *serial) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + uint8_t *val = serial->x; + uint32_t valLen = serial->len; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + ASSERT_EQ(cert->tbs.serialNum.len, 0); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SERIALNUM, val, 0), HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SERIALNUM, val, valLen), HITLS_X509_SUCCESS); + ASSERT_EQ(cert->tbs.serialNum.len, valLen); + ASSERT_COMPARE("serial", cert->tbs.serialNum.buff, valLen, val, valLen); + +exit: + HITLS_X509_CertFree(cert); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_TIME_FUNC_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + BSL_TIME time = {2024, 8, 22, 1, 1, 0, 1, 0}; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + ASSERT_EQ(cert->tbs.validTime.flag, 0); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_BEFORE_TIME, &time, 0), HITLS_X509_ERR_INVALID_PARAM); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_BEFORE_TIME, &time, sizeof(BSL_TIME)), HITLS_X509_SUCCESS); + ASSERT_TRUE((cert->tbs.validTime.flag & BSL_TIME_BEFORE_SET) != 0); + ASSERT_EQ(BSL_SAL_DateTimeCompare(&cert->tbs.validTime.start, &time, NULL), BSL_TIME_CMP_EQUAL); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_AFTER_TIME, &time, sizeof(BSL_TIME)), HITLS_X509_SUCCESS); + ASSERT_TRUE((cert->tbs.validTime.flag & BSL_TIME_AFTER_SET) != 0); + ASSERT_EQ(BSL_SAL_DateTimeCompare(&cert->tbs.validTime.end, &time, NULL), BSL_TIME_CMP_EQUAL); + +exit: + HITLS_X509_CertFree(cert); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_SING_MD_FUNC_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + int32_t mdId = CRYPT_MD_SHA3_384; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_MD_ID, &mdId, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_MD_ID, &mdId, sizeof(int32_t)), + HITLS_X509_ERR_INVALID_PARAM); + + mdId = CRYPT_MD_MD5; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_MD_ID, &mdId, sizeof(int32_t)), HITLS_X509_SUCCESS); + ASSERT_EQ(cert->signMdId, mdId); + +exit: + HITLS_X509_CertFree(cert); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_DNNAME_FUNC_TC001(int unknownCid, int cid, Hex *oid, Hex *value) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + ASSERT_TRUE(cert->tbs.issuerName != NULL); + ASSERT_TRUE(cert->tbs.subjectName != NULL); + + BslList *list = NULL; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ISSUER_DNNAME, &list, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ISSUER_DNNAME, &list, sizeof(BslList **)), 0); + ASSERT_TRUE(list != NULL); + ASSERT_TRUE(list == cert->tbs.issuerName); + + HITLS_X509_DN unknownName[1] = {{unknownCid, value->x, value->len}}; + HITLS_X509_DN dnName[1] = {{cid, value->x, value->len}}; + HITLS_X509_DN dnNullName[1] = {{cid, NULL, value->len}}; + HITLS_X509_DN dnZeroLenName[1] = {{cid, value->x, 0}}; + ASSERT_EQ(HITLS_X509_AddDnName(list, unknownName, 1), HITLS_X509_ERR_SET_DNNAME_UNKKOWN); + + ASSERT_EQ(HITLS_X509_AddDnName(list, dnName, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AddDnName(list, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AddDnName(list, dnNullName, 1), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AddDnName(list, dnZeroLenName, 1), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AddDnName(list, dnName, 1), HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(list), 2); // layer 1 and layer 2 + + HITLS_X509_NameNode **node = BSL_LIST_First(list); + ASSERT_EQ((*node)->layer, 1); // layer 1 + ASSERT_EQ((*node)->nameType.tag, 0); + ASSERT_EQ((*node)->nameType.buff, NULL); + ASSERT_EQ((*node)->nameType.len, 0); + ASSERT_EQ((*node)->nameValue.tag, 0); + ASSERT_EQ((*node)->nameValue.buff, NULL); + ASSERT_EQ((*node)->nameValue.len, 0); + node = BSL_LIST_Next(list); + ASSERT_EQ((*node)->layer, 2); // layer 2 + ASSERT_EQ((*node)->nameType.tag, BSL_ASN1_TAG_OBJECT_ID); + ASSERT_COMPARE("nameOid", (*node)->nameType.buff, (*node)->nameType.len, oid->x, oid->len); + ASSERT_EQ((*node)->nameValue.tag, BSL_ASN1_TAG_UTF8STRING); + ASSERT_COMPARE("nameValue", (*node)->nameValue.buff, (*node)->nameValue.len, value->x, value->len); + + /* subject name can add repeat name */ + ASSERT_EQ(HITLS_X509_AddDnName(cert->tbs.issuerName, dnName, 1), HITLS_X509_SUCCESS); + + list->count = 100; // 100: the max number of name type. + ASSERT_EQ(HITLS_X509_AddDnName(cert->tbs.issuerName, dnName, 1), HITLS_X509_ERR_SET_DNNAME_TOOMUCH); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +int32_t TestListAddFail(BslList *pList, void *pData, BslListPosition enPosition) +{ + (void)pList; + (void)pData; + (void)enPosition; + return 1; +} + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_DNNAME_ERROR_TC001(int cid, Hex *value) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + BslList *list = NULL; + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ISSUER_DNNAME, &list, sizeof(BslList **)), 0); + ASSERT_TRUE(list != NULL); + + FuncStubInfo tmpRpInfo; + STUB_Init(); + STUB_Replace(&tmpRpInfo, BSL_LIST_AddElement, TestListAddFail); + + HITLS_X509_DN dnName[1] = {{cid, value->x, value->len}}; + ASSERT_NE(HITLS_X509_AddDnName(list, dnName, 1), HITLS_X509_SUCCESS); + +exit: + STUB_Reset(&tmpRpInfo); + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_RSAPARAM_FUNC_TC001(char *privPath, int keyType) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + + int32_t pad = CRYPT_PKEY_EMSA_PKCSV15; + CRYPT_RSA_PssPara para = {20, CRYPT_MD_SHA256, CRYPT_MD_SHA256}; // 20: saltlen + CRYPT_EAL_PkeyCtx *ctx = NULL; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + ASSERT_EQ(CRYPT_EAL_PriKeyParseFile(BSL_FORMAT_ASN1, keyType, privPath, NULL, 0, &ctx), 0); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), + HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(int32_t)), + HITLS_X509_ERR_INVALID_PARAM); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_PRIVKEY, ctx, sizeof(void *)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), 0); + + pad = CRYPT_PKEY_EMSA_PSS; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), + HITLS_X509_ERR_SET_RSA_PAD_DIFF); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(int32_t)), + HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), + HITLS_X509_ERR_SET_RSAPSS_PARA); + + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_PRIVKEY, ctx, sizeof(void *)), 0); + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_PADDING, &pad, sizeof(int32_t)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), 0); + para.mdId = CRYPT_MD_SHA224; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), + HITLS_X509_ERR_MD_NOT_MATCH); + para.mdId = CRYPT_MD_SHA256; + para.mgfId = CRYPT_MD_SHA224; + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), + HITLS_X509_ERR_MGF_NOT_MATCH); + +exit: + CRYPT_EAL_PkeyFreeCtx(ctx); + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_ENCODE_CERT_EXT_TC001(char *path, Hex *expectExt) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = NULL; + BSL_ASN1_Buffer ext = {0}; + + ASSERT_EQ(HITLS_ParseCertTest(path, BSL_FORMAT_ASN1, &cert), HITLS_X509_SUCCESS); + uint8_t tag = 0xA3; + ASSERT_EQ(HITLS_X509_EncodeExt(tag, cert->tbs.ext.list, &ext), HITLS_X509_SUCCESS); + + ASSERT_EQ(ext.len, expectExt->len); + if (expectExt->len != 0) { + ASSERT_EQ(ext.tag, tag); + ASSERT_COMPARE("extensions", ext.buff, ext.len, expectExt->x, expectExt->len); + } + +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(ext.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_GEN_BUFF_API_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + + BSL_Buffer buff = {0}; + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + ASSERT_EQ(HITLS_X509_CertGenBuff(BSL_FORMAT_UNKNOWN, cert, &buff), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, NULL, &buff), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, cert, NULL), HITLS_X509_ERR_INVALID_PARAM); + + cert->tbs.version = HITLS_CERT_VERSION_1; + cert->tbs.ext.list->count = 1; + ASSERT_EQ(HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, cert, &buff), HITLS_X509_ERR_CERT_INACCRACY_VERSION); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_GEN_FILE_API_TC001(char *destPath) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_TRUE(cert != NULL); + + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_UNKNOWN, cert, destPath), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_ASN1, NULL, destPath), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_ASN1, cert, NULL), HITLS_X509_ERR_INVALID_PARAM); + +exit: + HITLS_X509_CertFree(cert); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001(char *inCert, int inForm, char *outCert, int outForm) +{ + TestRandInit(); + HITLS_X509_Cert *cert = NULL; + BSL_Buffer encodeCert = {0}; + BSL_Buffer expectCert = {0}; + + ASSERT_EQ(HITLS_X509_CertParseFile(inForm, inCert, &cert), 0); + ASSERT_EQ(BSL_SAL_ReadFile(outCert, &expectCert.data, &expectCert.dataLen), 0); + ASSERT_EQ(HITLS_X509_CertGenBuff(outForm, cert, &encodeCert), 0); + + ASSERT_COMPARE("Format convert", expectCert.data, expectCert.dataLen, encodeCert.data, encodeCert.dataLen); + +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(expectCert.data); + BSL_SAL_Free(encodeCert.data); +} +/* END_CASE */ + +static int32_t SetCert(HITLS_X509_Cert *raw, HITLS_X509_Cert *new, CRYPT_EAL_PkeyCtx *priv, int32_t mdId) +{ + int32_t ret = 1; + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_VERSION, &raw->tbs.version, sizeof(int32_t)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_SERIALNUM, raw->tbs.serialNum.buff, raw->tbs.serialNum.len), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_BEFORE_TIME, &raw->tbs.validTime.start, sizeof(BSL_TIME)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_AFTER_TIME, &raw->tbs.validTime.end, sizeof(BSL_TIME)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_PUBKEY, raw->tbs.ealPubKey, sizeof(void *)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_PRIVKEY, priv, sizeof(void *)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_SIGN_MD_ID, &mdId, sizeof(int32_t)), 0); + + BslList *rawSubject = NULL; + ASSERT_EQ(HITLS_X509_CertCtrl(raw, HITLS_X509_GET_SUBJECT_DNNAME, &rawSubject, sizeof(BslList *)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_SUBJECT_DNNAME, rawSubject, sizeof(BslList)), 0); + + BslList *rawIssuer = NULL; + ASSERT_EQ(HITLS_X509_CertCtrl(raw, HITLS_X509_GET_ISSUER_DNNAME, &rawIssuer, sizeof(BslList *)), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_ISSUER_DNNAME, rawIssuer, sizeof(BslList)), 0); + + ret = 0; +exit: + return ret; +} + +/* BEGIN_CASE */ +void SDV_X509_CERT_SETANDGEN_TC001(char *derCertPath, char *privPath, int keyType, int pkeyId, int pad, int mdId, + int mgfId, int saltLen) +{ + HITLS_X509_Cert *raw = NULL; + HITLS_X509_Cert *new = NULL; + HITLS_X509_Cert *parse = NULL; + CRYPT_EAL_PkeyCtx *privKey = NULL; + BSL_Buffer encodeRaw = {0}; + BSL_Buffer encodeNew = {0}; + BslList *tmp = NULL; + + TestRandInit(); + ASSERT_EQ(CRYPT_EAL_PriKeyParseFile(BSL_FORMAT_ASN1, keyType, privPath, NULL, 0, &privKey), 0); + ASSERT_EQ(BSL_SAL_ReadFile(derCertPath, &encodeRaw.data, &encodeRaw.dataLen), 0); + ASSERT_EQ(HITLS_X509_CertParseBuff(BSL_FORMAT_ASN1, &encodeRaw, &raw), 0); + + // new cert + new = HITLS_X509_CertNew(); + ASSERT_TRUE(new != NULL); + ASSERT_EQ(SetCert(raw, new, privKey, mdId), 0); + tmp = new->tbs.ext.list; + new->tbs.ext.list = raw->tbs.ext.list; + if (pkeyId == CRYPT_PKEY_RSA) { + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), 0); + if (pad == CRYPT_PKEY_EMSA_PSS) { + CRYPT_RSA_PssPara para = {saltLen, mdId, mgfId}; + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), 0); + } + } + ASSERT_EQ(HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, new, &encodeNew), 0); + if (pad != CRYPT_PKEY_EMSA_PSS) { + ASSERT_EQ(encodeRaw.dataLen, encodeNew.dataLen); + } + if (pkeyId == CRYPT_PKEY_RSA && pad == CRYPT_PKEY_EMSA_PKCSV15) { + ASSERT_COMPARE("Gen cert", encodeNew.data, encodeNew.dataLen, encodeRaw.data, encodeRaw.dataLen); + } + +exit: + HITLS_X509_CertFree(raw); + BSL_SAL_Free(encodeRaw.data); + if (tmp != NULL) { + new->tbs.ext.list = tmp; + } + HITLS_X509_CertFree(new); + HITLS_X509_CertFree(parse); + CRYPT_EAL_PkeyFreeCtx(privKey); + BSL_SAL_Free(encodeNew.data); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_GEN_CERT_ERROR_TC001(char *derCertPath, char *privPath, int keyType, int mdId, int ret) +{ + HITLS_X509_Cert *raw = NULL; + HITLS_X509_Cert *new = NULL; + CRYPT_EAL_PkeyCtx *privKey = NULL; + BSL_Buffer encodeCert = {0}; + BslList *tmp = NULL; + + ASSERT_EQ(CRYPT_EAL_PriKeyParseFile(BSL_FORMAT_ASN1, keyType, privPath, NULL, 0, &privKey), 0); + ASSERT_EQ(HITLS_ParseCertTest(derCertPath, BSL_FORMAT_ASN1, &raw), HITLS_X509_SUCCESS); + + new = HITLS_X509_CertNew(); + ASSERT_TRUE(new != NULL); + ASSERT_EQ(SetCert(raw, new, privKey, mdId), 0); + tmp = new->tbs.ext.list; + new->tbs.ext.list = raw->tbs.ext.list; + + ASSERT_EQ(HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, new, &encodeCert), ret); + +exit: + raw->flag = HITLS_X509_CERT_PARSE_FLAG; + HITLS_X509_CertFree(raw); + if (tmp != NULL) { + new->tbs.ext.list = tmp; + } + HITLS_X509_CertFree(new); + CRYPT_EAL_PkeyFreeCtx(privKey); + BSL_SAL_Free(encodeCert.data); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_GEN_CERT_ERROR_TC002(char *derCertPath, char *privPath, int keyType, int mdId, char *destPath) +{ + HITLS_X509_Cert *raw = NULL; + HITLS_X509_Cert *new = NULL; + CRYPT_EAL_PkeyCtx *privKey = NULL; + BSL_Buffer encodeRaw = {0}; + BslList *tmp = NULL; + uint8_t *tmpBuff = NULL; + + ASSERT_EQ(CRYPT_EAL_PriKeyParseFile(BSL_FORMAT_ASN1, keyType, privPath, NULL, 0, &privKey), 0); + ASSERT_EQ(BSL_SAL_ReadFile(derCertPath, &encodeRaw.data, &encodeRaw.dataLen), 0); + ASSERT_EQ(HITLS_X509_CertParseBuff(BSL_FORMAT_ASN1, &encodeRaw, &raw), 0); + + new = HITLS_X509_CertNew(); + ASSERT_TRUE(new != NULL); + ASSERT_EQ(SetCert(raw, new, privKey, mdId), 0); + tmp = new->tbs.ext.list; + new->tbs.ext.list = raw->tbs.ext.list; + + tmpBuff = new->tbs.serialNum.buff; + new->tbs.serialNum.buff = NULL; + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_ASN1, new, destPath), HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM); + new->tbs.serialNum.buff = tmpBuff; + new->tbs.validTime.flag = 0; + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_ASN1, new, destPath), HITLS_X509_ERR_CERT_INVALID_TIME); + new->tbs.validTime.flag = BSL_TIME_BEFORE_SET | BSL_TIME_AFTER_SET; + + BSL_TIME time = {2050, 1, 1, 1, 1, 0, 1, 0}; + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_BEFORE_TIME, &time, sizeof(BSL_TIME)), 0); + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_ASN1, new, destPath), HITLS_X509_ERR_CERT_START_TIME_LATER); + ASSERT_EQ(HITLS_X509_CertCtrl(new, HITLS_X509_SET_BEFORE_TIME, &raw->tbs.validTime.start, sizeof(BSL_TIME)), + 0); + + new->signMdId = 0; + ASSERT_EQ(HITLS_X509_CertGenFile(BSL_FORMAT_ASN1, new, destPath), HITLS_X509_ERR_CERT_INVALID_SIGN_MD); + +exit: + HITLS_X509_CertFree(raw); + BSL_SAL_Free(encodeRaw.data); + if (tmp != NULL) { + new->tbs.ext.list = tmp; + } + HITLS_X509_CertFree(new); + CRYPT_EAL_PkeyFreeCtx(privKey); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_GEN_CERT_ERROR_TC003(char *derCertPath) +{ + HITLS_X509_Cert *parse = NULL; + HITLS_X509_Cert *new = NULL; + int32_t ver = 0; + HITLS_X509_Ext *ext = NULL; + + // Test: Set after parse + ASSERT_EQ(HITLS_ParseCertTest(derCertPath, BSL_FORMAT_ASN1, &parse), HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_CertCtrl(parse, HITLS_X509_SET_VERSION, &ver, sizeof(int32_t)), + HITLS_X509_ERR_SET_AFTER_PARSE); + + ASSERT_EQ(HITLS_X509_CertCtrl(parse, HITLS_X509_GET_EXT, &ext, sizeof(HITLS_X509_Ext *)), 0); + HITLS_X509_ExtBCons bCons = {true, true, 1}; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_BCONS, &bCons, sizeof(HITLS_X509_ExtBCons)), + HITLS_X509_ERR_EXT_SET_AFTER_PARSE); + + // Test: Parse after set + new = HITLS_X509_CertNew(); + ASSERT_NE(new, NULL); + ASSERT_EQ(HITLS_ParseCertTest(derCertPath, BSL_FORMAT_ASN1, &parse), HITLS_X509_ERR_INVALID_PARAM); +exit: + HITLS_X509_CertFree(parse); + HITLS_X509_CertFree(new); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_DIGEST_FUNC_TC001(char *inCert, int inForm, int mdId, Hex *expect) +{ + TestRandInit(); + BSL_Buffer encodeRaw = {0}; + BSL_Buffer encodeNew = {0}; + HITLS_X509_Cert *cert = NULL; + uint8_t md[64] = {0}; // 64 : max md len + uint32_t mdLen = 64; // 64 : max md len + + ASSERT_EQ(BSL_SAL_ReadFile(inCert, &encodeRaw.data, &encodeRaw.dataLen), 0); + ASSERT_EQ(HITLS_X509_CertParseBuff(inForm, &encodeRaw, &cert), 0); + + ASSERT_EQ(HITLS_X509_CertDigest(cert, mdId, md, &mdLen), 0); + ASSERT_COMPARE("cert digest", expect->x, expect->len, md, mdLen); + + ASSERT_EQ(HITLS_X509_CertGenBuff(inForm, cert, &encodeNew), 0); + ASSERT_COMPARE("digest then gen", encodeRaw.data, encodeRaw.dataLen, encodeNew.data, encodeNew.dataLen); + +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(encodeRaw.data); + BSL_SAL_Free(encodeNew.data); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CERT_SET_CSR_EXT_FUNC_TC001(int inForm, char *inCsr, int ret, Hex *expect) +{ + TestRandInit(); + + BSL_ASN1_Buffer encodeExt = {0}; + HITLS_X509_Csr *csr = NULL; + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + ASSERT_EQ(HITLS_X509_CsrParseFile(inForm, inCsr, &csr), 0); + ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_SET_CSR_EXT, csr, 0), ret); + ASSERT_EQ(HITLS_X509_EncodeExt(0, cert->tbs.ext.list, &encodeExt), 0); + if (expect->len != 0) { + ASSERT_TRUE((cert->tbs.ext.extFlags & HITLS_X509_EXT_FLAG_PARSE) == 0); + ASSERT_TRUE((cert->tbs.ext.extFlags & HITLS_X509_EXT_FLAG_SET) != 0); + ASSERT_COMPARE("Csr ext", encodeExt.buff, encodeExt.len, expect->x, expect->len); + } +exit: + HITLS_X509_CertFree(cert); + HITLS_X509_CsrFree(csr); + BSL_SAL_Free(encodeExt.buff); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/x509/cert/test_suite_sdv_x509_cert.data b/testcode/sdv/testcase/x509/cert/test_suite_sdv_x509_cert.data new file mode 100644 index 00000000..30ed466c --- /dev/null +++ b/testcode/sdv/testcase/x509/cert/test_suite_sdv_x509_cert.data @@ -0,0 +1,3231 @@ +SDV_X509_CERT_PARSE_FUNC_TC001 parse pem cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/cert/ca.pem" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse unknown(pem) cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/pem/cert/ca.pem" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse unknown(asn1) cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/asn1/sm2_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/nist384ca.crt" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa2048ssa-pss.crt" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sha256Rsaca.crt" + +SDV_X509_CERT_PARSE_FUNC_TC001 with key usage sha256 rsa v3 ca +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/cawithkeyusage.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ca cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/ca.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end2.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/end3.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/inter.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/inter.v1.der" + + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/ca.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/inter.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/ca.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/inter.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der" + + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/ca.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/inter.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der" + + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/ca.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/enc.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/enc.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/enc.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/enc2.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/enc3.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/sign.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/sign.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/sign.notCA.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/sign2.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/sign3.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/inter.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ca cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":0 + + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":0 + + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":0 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":0 + + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":2 + +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":2 + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":"54eb174cce5c701873bcdca33db9811f63676d06" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":"54f33f24205984911fdc3c5c50a3d890d893ff5c" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":"06ebb33555449776551bfeedf985c33d42fe50d2" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 rsa_ca cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":"45E20E731A0B0D4A6C2297A86B2AE423F6387947" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":"5B45B8DD7ED954A554751EF50D5D405FC62B6AF0" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":"7D1C6E7796E8E116D5CE80287AE1B0587CD214E5" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":"678F4D2973C4C61EFA3E410010EE46B788EC99DB" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":"636906655643523C4693925BB963781D7E791121" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":"04" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":"01" + + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":"53dbff507553816b83a16087fe0f54ae08637b68" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":"3f9855704c1b63a2fb8d107929e69d4556b414c9" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":"38e82d49fffe563aec79cef63b75c0d4333d8480" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":"7b1e8976fead09c452c94c7483995b9a115ecd7d" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":"4deb6975f5f5f289638f485b64d95ac7a8ea029d" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":"04" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":"1a549391f834d46d9a325f82578245801d54d805" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":"1c9e1c9c422929bae5f0128e1b0e95904a3df3ff" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":"204faa1f6e9ddd091ef61635ea3e0d7cf68abcb6" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":"766ccaf73c6a29aea3ee3add6618db63fdd4dc5a" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":"4a487ecc2767d15e0ae707a133d39b5c5672487e" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":"04" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":"01" + + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":"5807c9900fcbb6ae4cfad599fa9a7c683a9dffe8" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":"0693f83b12c36624b266028a884e3137db47a889" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":"3e0100b79f4fe50327a7e6d16cb9c4609a9c41f8" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":"41257c21f031428c9de8ba55c2d7f98c881ab6db" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":"51ff3febc5c958866e9255fdc12459bf58e93142" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":"04" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":"01" + + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":"25039b818005c10419018c57bb576cd228979b1d" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":"1056cad697c20ef4e139f3b6bcb7b6eacbf76aa3" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":"53446a3fef4411b82fb64980031fcbb4a6f39711" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":"1429f8933620db730d2cc7a2bd59cd2c00aafb0f" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":"03" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":"05" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":"07" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":"02" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":"04" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":"06" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":"01" + +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_SERIALNUM_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":"01" + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/tailerfield.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 rsa_ca cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":12:"550406":19:"434e":"550408":12:"6f70656e":"550407":12:"7869616e":"55040a":12:"6f70656e6869746c73":"55040b":12:"61736e31":"550403":12:"63612e61736e312e636f6d" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC002 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC002:"../testdata/cert/asn1/rsa2048ssa-pss.crt":2:"550403":12:"6578616d706c652e636f6d" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sha256Rsaca.crt":10:"550406":19:"434e":"550408":12:"536861616e7869":"550407":12:"7869616e":"55040a":12:"6f70656e4869544c53":"2a864886f70d010901":22:"6f70656e4869544c5340656d61696c2e636f6d" + + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_ca +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_ca.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_ca.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_ca.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_ca.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_inter +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_inter.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_inter.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_inter.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse ecdsa_inter.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end2.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse ecdsa_end3.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ca +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ca.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ca.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ca.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ca.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_inter +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_inter.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_inter.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_inter.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_inter.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end2.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_end3.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + + + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_ca +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_ca.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_ca.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_ca.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_ca.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_inter +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_inter.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_inter.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_inter.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_ecc_inter.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end2.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_ecc_end3.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_ca +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_ca.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_ca.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_ca.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_ca.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_inter +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_inter.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_inter.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_inter.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse rsa_pss_inter.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end.v1 +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end2.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse rsa_pss_end3.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_ca +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_ca.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_ca.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_ca.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_inter +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_inter.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_inter.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001 parse sm2_inter.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_enc +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_enc.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_enc.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_enc.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_enc2.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_enc3.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_sign +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_sign.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_sign.noCRL +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_sign.notCA +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_sign2.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003 parse sm2_sign3.mul +SDV_X509_CERT_PARSE_ISSUERNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_TIME_FUNC_TC001 +SDV_X509_CERT_PARSE_TIME_FUNC_TC001:"../testdata/cert/asn1/sha256R-time.crt" + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":2024:2:4:7:03:41 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":2024:3:25:12:13:22 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":2024:2:6:6:18:10 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 rsa_ca cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":2024:4:17:2:21:9 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":2024:4:17:2:21:8 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":2024:4:17:2:21:8 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":2024:4:17:2:21:9 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":2024:4:17:2:21:8 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":2024:4:17:2:21:8 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":2024:4:17:2:21:9 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":2024:4:17:2:21:9 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":2024:4:17:2:21:9 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":2024:4:17:2:21:9 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":2024:4:17:2:21:8 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":2024:4:17:2:21:8 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":2024:4:17:2:21:8 + + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":2024:4:17:2:21:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":2024:4:17:2:21:3 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":2024:4:17:2:21:4 + + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":2024:4:17:2:21:6 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":2024:4:17:2:21:6 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":2024:4:17:2:21:6 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":2024:4:17:2:21:6 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":2024:4:17:2:21:7 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":2024:4:17:2:21:6 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":2024:4:17:2:21:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":2024:4:17:2:21:6 + + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":2024:4:18:6:47:5 + +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":2024:4:18:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":2034:2:1:7:03:41 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":2034:3:23:12:13:22 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":2034:2:3:6:18:10 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 rsa_ca cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":2034:4:15:2:21:9 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":2034:4:15:2:21:8 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":2034:4:15:2:21:8 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":2034:4:15:2:21:9 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":2034:4:15:2:21:8 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":2034:4:15:2:21:8 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":2034:4:15:2:21:9 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":2034:4:15:2:21:9 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":2034:4:15:2:21:9 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":2034:4:15:2:21:9 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":2034:4:15:2:21:8 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":2034:4:15:2:21:8 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":2034:4:15:2:21:8 + + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":2034:4:15:2:21:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":2034:4:15:2:21:3 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":2034:4:15:2:21:4 + + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":2034:4:15:2:21:6 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":2034:4:15:2:21:6 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":2034:4:15:2:21:6 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":2034:4:15:2:21:6 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":2034:4:15:2:21:7 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":2034:4:15:2:21:6 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":2034:4:15:2:21:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":2034:4:15:2:21:6 + + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":2034:4:16:6:47:5 + +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":2034:4:16:6:47:4 + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":12:"550406":19:"434e":"550408":12:"6f70656e":"550407":12:"7869616e":"55040a":12:"6f70656e6869746c73":"55040b":12:"61736e31":"550403":12:"63612e61736e312e636f6d" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC002 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC002:"../testdata/cert/asn1/rsa2048ssa-pss.crt":2:"550403":12:"6578616d706c652e636f6d" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sha256Rsaca.crt":10:"550406":19:"434e":"550408":12:"536861616e7869":"550407":12:"7869616e":"55040a":12:"6f70656e4869544c53":"2a864886f70d010901":22:"6f70656e4869544c5340656d61696c2e636f6d" + + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse ecdsa_ca +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse ecdsa_ca.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse ecdsa_ca.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse ecdsa_ca.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse ecdsa_ca.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_inter +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/inter.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696e":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_inter.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696e":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_inter.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696e":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_inter.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696e":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_inter.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696e":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end2.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64322E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse ecdsa_end3.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64332E6D756C2E636F6D" + + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ca +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ca.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ca.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ca.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ca.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_inter +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/inter.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_inter.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/inter.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_inter.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_inter.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_inter.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/inter.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end2.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64322E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_end3.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64332E6D756C2E636F6D" + + + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ecc_ca +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ecc_ca.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ecc_ca.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ecc_ca.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_ecc_ca.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_inter +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_inter.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_inter.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_inter.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_inter.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end2.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64322E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_ecc_end3.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64332E6D756C2E636F6D" + + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_pss_ca +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_pss_ca.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_pss_ca.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_pss_ca.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse rsa_pss_ca.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_inter +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/inter.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_inter.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_inter.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_inter.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_inter.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end.v1 +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E642E76312E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end2.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64322E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse rsa_pss_end3.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E64332E6D756C2E636F6D" + + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse sm2_ca +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse sm2_ca.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse sm2_ca.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001 parse sm2_ca.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":12:"550406":19:"5858":"550408":12:"5858":"550407":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573746361":"550403":12:"63657274696669636174652E7465737463612E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_inter +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/inter.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_inter.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/inter.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_inter.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_inter.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_enc +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E632E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_enc.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E632E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_enc.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E632E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_enc.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E632E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_enc2.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E63322E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_enc3.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374656E64":"550403":12:"63657274696669636174652E74657374656E63332E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_sign +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573747369676E":"550403":12:"63657274696669636174652E746573747369676E2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_sign.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573747369676E":"550403":12:"63657274696669636174652E746573747369676E2E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_sign.noCRL +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573747369676E":"550403":12:"63657274696669636174652E746573747369676E2E6E6F43524C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_sign.notCA +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573747369676E":"550403":12:"63657274696669636174652E746573747369676E2E6E6F7443412E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_sign2.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573747369676E":"550403":12:"63657274696669636174652E746573747369676E322E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003 parse sm2_sign3.mul +SDV_X509_CERT_PARSE_SUBJECTNAME_FUNC_TC003:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"746573747369676E":"550403":12:"63657274696669636174652E746573747369676E332E6D756C2E636F6D" + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 rsa_ca cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 rsa_ca cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":"621C736E2D82C04EE69D13EDD241147618A1BD566028FC34FCD1EA5365510A1D8967F7FD43FC183E6FA0C675BD58A6E1DF1EF62CF4E6C4493949FFE1C0F2C7D4DDDF31FC9BBF015BD8A9F14CAA74E033EE9924B7B940BEAC657D2225006D88340B3FC2509D676FCF18AF4A89A4EB7A7F0E8394EF9D05BD43E33DCF7C1491BE80E19F9E520265FFCCEB303556D7E36462A0529719D2EF898E601D856CAE3204A71EBF5935BA5885E3CE965300E2CAF0E91CDEB49BDA61240CC6F35C86E95FCF19109F450D77198E0DF4C1E657E250BC2754648E74C9B146B56C128E8AE61B05039A15DF0AAE447130453F7553B84C44C3FAE5B17DA22BA235E280C3C7C27671ED":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":"813286755D341E2BDC789CE06930ECD9F20D51AFB88309D504F1A12E1415730042EC14D12363AA629361483B6D1E19FAC88BDE632326929A3C733CBF35BFFF634F0C12A1B95306A1512029FD89879228F5E0E59BF3B61ACE217F3D049DBF25826A18F2D3EE8355617A505DAAF97C77F62D043F514E00C66EF9B3040A8897A6D567622A1DB3518606482FB1CC64EE184C8C41D7393BF60CA96F205122C64AD8D44F2407BAD6F1941CDDD11177E5B3B693368F1CF897E91D437D8181DD3E5834FC3ABB71A6AE99A6DFD33AE5DAF0CFD6754ADFA9C86513637779F1962AA73F34B47561DB2B5C5FC82F8F6FCFE05755845F36EBF6DFDAD9097493DC70DA0B924BD9":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":"31C4AE85D98307FFC48B2BAC1AE44F399404647CD6C0F0915E072989793A53716FC6E1CB16141BCA0C871623DDFFB8A947BF5EE683A9A7597423BFCEEA9F5B55BAAD6AF691B9A4BEF773FA4EB7DD9D18F130254791097516ABF1321D7CEA4E863D48EAF087269E6BBBD73685D8BC382F2C62BD2C7E9D6F48365C699893F3FA9E21D18667FFE1E6FE0C97E26759A467CA4C9C4C5DBE529630A10C47F621A1EFFCF11B81C96A301AC212449413AFE70429639C2042AB90BD3FC0396981D8B07BDC6A701230D3A0BEEA519D84955BD12E899E0999E7D05D2C28BC89223A9EB82F96723DBF90A5163E67DE2F7A294C919AEA12B1771BD49EED22DDF27D66E0768F4D":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":"6CEB3D4D90F456BED2968A9B3A5A4B88B0C1C7ABCB1942155D506C4FDCD368CC1C2CFA0BD6FD22A3F9B1F706063D1453525A4B45F589CEBE0EB593F7F07480397FD1FAC0905E081063ADFDC64BE51C3E5FBF7FBE961DC9C4D1AC8743CC3BBF4ACA232FEC6E0571229E1F61ACDED29DA01C685635EAC6A2D6ACA08969E33909724EB3D6AF18C3AC62F34FF82E2292DB0ACF20843716C9F7089BA9E5BCC33B573D87CB7EB86B9C583C1F6BF10DDD2D5D18ACDD6FB15ADD7D714E7C70F6E3AB15FAEA4875B83945A0A08DAE6400E4E1DA2C2B51D6D8F5286AAE5074EF6FCE1A9E841CEC0C0470620E1FF7C10F31E109B2C8BEE408972DE8F5AC5746BE038B55A6DA":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":"151C3FB3795A76A94BA4AE832F5829D53F89E1128A32C9DC7E83205399ABAE7BC81227F5CA47AE84C974A9DEFA774E14055A210C428CB72FA198F1F7AF97D553869B4141DFFB660A7027CA5A263E85CB2D2CFDC9C620B4F1760863C817787ACBB7F1DF04521DBF4351BF4553C0A6883F3532E10D8F15C455F39A0418A4F74A2A70D5BE889C5BCAFCAA5AEFCCBF63305FFC4C19D3450FC336AC646F38963F2C60DE4C4B93A9BAFDB66F30285EF93B0B75B0C760F0BA06275A617B37615BFA116D434FFC5F7201132A6DFE7173C73A1825CC46C29E74745222A06773C867D793B09133D1E9C08AA7A3AFCF3120A0B81E0E88FFDA2EDF638C3EF09E9ED7D6B64C63":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":"62E8321A924F3CE8D2823A6279839CFFA1441E45F719875D615943725C1370B2800A88B30B629A670D8C48B1DFB3038FD768360426CDB88226C647D2D58DDA41DF08638B66B9332B820A3283DAB3F57D8E9D03D3159EBA1F72B68860359D70F595BA3ADD379A5C2AD69B352854761C64B267DA4390BADDB52BBC8C0A7463E0B6A7ECE32C9EC01EA46D25E049BB15466851140F36B95E58025CEB33E406FB6C84BEF007F43F09E756DFC23934D7875E0EEBDEACFB3D328DEB61BFE5934D56CD81E696B59DADBE28507D3DA26813B8E473B71029A5851A436F7BBDA1B2CEEF38A0428CF5E0B5131B6A163B9F6B474564311D7804445F9E8F58F8CE22A999AA3020":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":"47458385C90225A0619F15D7975B2920721EE8771E72C54593232A45CC303719A3524E8500B2F4E5D6FD0E3DBCB271D2412E7C0A97880AD87ED7E1DEFEE5E699E72140749A36E439FED0316607D3196D60C1AA81DAA32944222340FCC85E99ACB7A48F2357E84AA442E937663669701329C0FA6AB0E09915ECBE2AB292B2DD2FD55CB13AF410D16D8355FA3973C220B4225EB1472F545610706E731862A965588B58AFE0BBC7905C170C01E3B988144593F6C068971ADFAB2495EC9DA199F7A984D5F5B795D45DDD5F4CE9E1EE7C3F90B41FAC778A435696C1E0D1AED940C072C90D731D64271C2E2403DC2456510D5C0189F38DC1B1FBB95F9442D6425C6CD3":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":"DB3C7DB7C37128C75E2D8011A9CA79304DCD795ED2BD2196383EC4D9D9E9D1E6FF680BB8A06087CE74EAD5EB38C314D1DF72FF00B9C338EC1BD37B09626A41BE1E0C646625D87AE9DF1384B8F20E056D5952EFE97FD961C7CD306DBF78C5816DE08A9144E72C97EB2E1302E2E12DB7A4583041C68EFDB33FD1FF1E9E068BDEE53E9BBBE6C38BBC977D98D28C8FA89B0951D74506DB179CA2A91F7218526C4D3C1EB7A5A91395F539B4559B4A221469119998C768CA396506050B15E68B6D6E2391EAE0461548BFC54A5CFA9611463CA9E60553EDF22C174D13FE6FCD6B882996C6920C1FFED635C16E3A97EB20EC651866149FBAAF77F93AB93650A719D63BCE":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":"6F5129F69A6FA37E5B3C9FA4067413B1043A0ACF744E2F44315861E9DF5FF3C3CFDFD5E1B6A7D3BBD3751BFDBE0ADEF16C949D4E45A0865EF4AF8A8FC4C8C33691BF9CCD0EE9C1CDE05C5D71426FB7B9EB9A1A6F3703A15C5C7B059FA212E687B5897772A518305CCD9BE713D2F28ADD0BE70F73958F9BE24D43D03C5525930A1BA8B7CCE2BAFEFF422FF58391808C10C7662B4B1BD49447FD01D5FA3887467A1C4EA29190FAA77C556F7AD7B90978875268DAA24EC684D6138CBD0A82770D93966E159FB0F3D52043CE1B16A0169D057125F147AA0725FDBB82A23229A54AE90E3EF96C70C0EC3DAA7876642B8DEB2157882A1A37EF8E64571F006DDB02E612":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":"392C7CE90D613F19F43F5D54EBA2B3AAF6D017021EBF69B3C701A30D5829FD96CD071BC0E91818E2422EBC97642EDDFBDA8320DAACDFA424DE9ED2164C902706A3769815ABB4BDFCB7D25E90EF09589A7EDF1EFBE99A750F35F47B07F508B88071A0198DD66469BF807D69F463057644EE07C82325C976A421022A013F6425D8BF0F131D65297816E1CCB5069783A35931E64C894205EF0C76D3900810962151705546CF666599CDBE1F80A456CA05456B4B985C515DDB52D26B276DE76FF3471A3E752819146CBDC38189B7735A138F04C29F5A7339D71459851F5A96335A1E300583C9C0B3D4189E132C946C4AA7EEB3A5C4D069F5EBC5ECAE3759DCAF4130":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":"45DAFC5EB0B1651ED5A4B5AF9E5EC736124176B8C72B5C094C40ACA4B96E4E087085D39A4070E57372898481F6BD16E3B4616B4543024CC89E3EF3F19B172E7445A038E0733AB1EED4357E80C87E632757DCACA071B71095B83A3A2E34FB1F3AFD5E8C403854CCA8694CF02887CD66BCF51EF2551EFFC9F3985B0C022D4DC2BAF1128150293A268A4904F20EF1DD99EB6952730D8B2BA68F70146521F76A40F6085700314D86A5BA1719D4E6C9B360A93810AB36C7096DFAC34797C87EA0E5BDDB5887D264036F364401EC312CB65C3389F2B648BF9E6C4798BD6F50AEE77EE4202A5A8B96AC15F8A6045F16334581993190322D28F87042B3658F71F3B025DB":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":"A42440015DD9D6CAFA3B17E74311BE7ABA47F45F2BB89B0A49337DDF67A9C140D8711F1D4659E2E5EEDA06F7296E9B871A2887FA2B40A47C33C0F6CCF33DFC758DC34883854275684852E85D02751ADCC610EE75CF21A9B3549A0E258D5F4C9FBD73109851068E877B6380D124BE73BAE729FEF614A02ACF5474E6464A98D74049E57653BC57BA1A86C537E3E4DF3934F8ADC2E1E43A9EEDA4509E1DE577A0B3B3FEA5C5C2A6062871823DA9FDE0E453A68AA3BB21F0C534F401FB137E1FE8910152D9EB8A74F48F0AA58A9FB3206211711C28D79CD78AB8E77ED8930D5F1EEC4F9C0E81B9310CC6D33ABDDC1F4A6F6D2876C6E79D7210BFE95F5137037123D8":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":"ADAC98AF5C87A6CCA40A5BB251ACB5EA4D3CA5B5EEB066D5541D9295444518581E1AEF866D9BC42F2F30497DC9346DFF5CE82F240DD686B33E3BF6A7AC9CDFE1EEE0CD2C324461A6FB46A5867DF7AFF904AAC572303D1EF935D378C12823183064153DDEA136FE24ABB1EEEB55A363517BF423B1C4897335CE480EA610741534218242B2F55F9A77D0DE91685F97F808FE830F76718EC870B600D2C581DDB5CF85F02DACB5D723582EA700BEC4C791D1391BBAF53199B212EB5BEE4C1B52F4A109E02BA44AB67A4056AC5B89F92E2BB199EC40D3E7B601347565F29D16ED9A608820C095862BE3AF9C6C09AB0406C034A61FD66E94269899ACA5B45D3412C415":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":"49E54B6654FCBBDBB748CBC0C34176844EEE93FB674BE815672321CF493C14CC3560AF88796B2D714B0EC3DF2FDB10CD46BF12FF263F9F9AF27B4BC06B605FEFDC7ED171301D6FCE5960B60F0D6FCECD7E736444C473D9848FFC3EA4A9F65DF3FD42474CF11726DF2141DCC102B6D3A37294F22E9E5ED0AF3FBBD1A2D0CA3EA7F8D319D73EE26783EC860A7BDA971BD33F01032D944EEB116196FBB6BC621E657A6DCAEBFEB58A6888C587B5B33A5A301737955E44D7135A064BAC46B4040752C03BC11B65C0534002DB90D84FF033FFF98FF9C1DD4923CE95EFA24C8C45DDE7BF9C8877BDD6A58AC1B6BE3BF698705E1688F966CB17BF7485D15049B278C22A":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":"32BD1D19F72A5C4E580AE1B94922CF477104357A84D066E8C205CB1A19839FFD2B27C6CCD3D4E12C75032B82FA352D3FDF5A4B3D49A5B0BCFA1CA1224FD34C1A3CC20A07EE0BC9FF402A0A30EC1DDF24E0320483F4ABE1F5F15F93FD32569D9982F72B50CF79146A32DFC5F86DED3ED41645C34816FF105AAFD427A5CFA7ED44987B9E7BB86093F9AAF53408F3A84E7044D829B26C37404ABC888FE46F34BC8F3135B07F2248353FD935A5F0CD0895B97783BFFB81442EE2723D58B33751ACE8557710EECF816631CD92644A8C455DF7A3BAEA2D0C56CB605CC167E50717C2E085463CE42C1D008375E8598BC55C9F65B267CC501C128B63E5C8345FC6733DC2":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":"107A7BE320C05400E2C1172163E30AF1EEEE44897DA9497BF58873A399ED9FE79EC40EA739A8E38A23E982440D0913AE4FA55306CA379E49DF006BEB6AB9D6938C38EF5414215AF9E5D0A770AB22A659CB493A3BC80B9CD55DA3BAC2EEE2AFCFC923A501DDE0E459C81ECC0CCD5760293C833085B5BFC703CCDDEC676E4861EC680702BC2A601608BA4F75E887108FB4E62C5587E946C426329094E9C51BEA1E3FF32B47036CAC45F2B26DC97A766D08C95BDB116F855539843484F4FE87C3F5E692D354E44E5DF99390C4CE870622D9CE154C00FDEC2C1D492EBF2BF5CF48BD9BF83467987DA312B726086E368A18FA70672B764CA820258EB54A0504EB1183":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":"9B8EB9BB5C3906902D752F0347EFA8A11F17C755B5AAAD6C587C3DD130271DD602154489585E0FBB23211D51B709288C79770639A8D154F6814C39EF21E9C52189EC427FBC4993BBF98FD4DFF9C9B7841B45D92F812B6630B91956449F715EB1F848DA7C46F3489CE1FD3D21D961E2175761EEB77CB4DFE9054C9E921BE4795E06794D41E3CB2E7F703A7840CD3EA9BB8CE83E8CF55D1B49DF2DB03957D95E245E17DE31D124EBEDC5D116920926E510D57BEF00FA6C0FEE18C7E0D3B9A32F75FBA71BC9C4AF3C0A3D61C777EFFDCE77C60FDE18627EBE8A3346F4B17B0ECFA173A6C51AC27584423963BB3EA573AA24730AB341DB4BB5BD3CF5CAC8894CEAE5":0 + + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":"306402304fc984a2598111c3a5925213d0b132b9872125cdc5e9cdab60ae1a52f8d9fdc3863323eefb64662116fce917cec20dc8023076b51ff4aa51d564942af6443eee5c0ebdec6c88a7ff2d5deae04b3fa946efbe3219bb6cc048cbcc20dc9a631cd95493":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":"306402300c535e93619001adff4a54f76c3b584ff69ef033a7445ea57af63a73b6abb660d0343d1c1d583ac0ad9346c3eef538d60230307f5939eafaf5be1d6514ec27a5bf25d7638911583e4dadc952ea5cf7f7eeab9cdbd2408c35a9073fb786a48afe9354":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":"306402307598f996f994c344f21dce62168f76af509f80a636ca6cc4a9ca9cc38107ab76580f6b5fb44e6eea03a0aa6502043c65023022455a880f75f3da03e2b559bf116eb65f930fee8ae89c1fd5accd435a968c25465e8d3148606693c89627268a557d6a":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":"306502301a50fa8f66182338fac17d600eec4613030055ce7ae62c8d9d2d51120f46f70f621c5ec2b4ab1c613b2c27ee4e9a3fcd023100f7c767adf2df7e9e2273830ea5bb67c0d25fca58cc766e26e585fd1034fa0d69e62d74af4d491f43449664302f447273":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":"30650231009e2bf88cb8430a4e3963e775481ddf27ba33b7985c904a94ea56284a210c8f1980ad906db309b6b391f7b1bb2dde387502300df5fa55a5a60c448fac8d3284bf8aec0b7fb5ba9d6e88560d50b1a860c3e768802e0f39fe4d69e2a7271af4d39921c1":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":"3065023100d94f25807bd178dca907faf9c5029dbbca057f333f24ec240bb26162b3c872174aae5221828d0572d0635930343a06d902307f327a14d63a591851703786626c2c3497ef7da2206ba107bbe4a393d4ee405980d7a2c47022af93d21bcc323b257378":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":"3064023055cc239c7ca6ac613cb5c0d4f2fb62fe2eadda5f5d43d00c458c6f1f49ee1e7140803dace769c21a0c042bd704102e25023065bd2e46fc2b0e8e39e67a94f45f7d7dd2de756b83f52e0f1d2ff99ebb3ee003a5d84d8e125b5b17a2437d5be62310fb":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":"306402303770236f1748c97bafe92c973def7edfa2fc7f6a069d7c55acf7028996487bc58c385ecaa76c99705f78f2c6e9d2cbec02307697465ac1ed5a3d62e42efd50f792d973090605b65a401a6a0890d07f8fb02665055725a465cafc9f5159fa7175d4b9":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":"306402300c6ab8c28e4cd9ee1773db1e092d763f1997fab8ecb3c857747a9dd8d3fcdfff8ecde2e66e56c907a8d39b183ab32c1e0230769cfd41813b4bdf1d971d6eef33cdac9cd2bfa7d6557038eeb1fc57f59762fa6f53d5e3ca13b37b269610c91dd44ee0":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":"3064023076df234cad40f7d2a9dbe6cf6d721ad701dd94936be08baf71cac63266485bd1756c8f27671454f1f698066f758e2d1d023025355f6f33992825ca25dc490249173fe824b58bd7be9f0ae6485c3bacec42c2a5427a05ceb4264def6fda701ab5a89b":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":"306402303e1e22f113baf51bd8d25ce4a287bbe17fe67d52d8a1000eb7e26320a417c6345cc5b6f6ba21084df941311533382de30230161730d3beeefc2c165f2377a56c9ea9444ba63996eb8a6674276adcb68f68fc9a66222935f7e99b4da92cb487704f1d":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":"30650230297034d8299319904076bc3914281deebf5d03b9a28fd8e649054a5a9ad40baff35a8d90149482cb0a1e419374bbe36b023100975590152802340ced6c8030f0df5a15a7d624312b20044cab70c46b93ac1147e4a8b8ed9a3abe8590506d25f10445e9":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":"306502304acd3bcf15c9a7d6cc99b6b1c3dd4dc8e99601e11119f5a7784f29a16a6b9c9b55774359e9d6fd7857638ef65641fbe402310096bd6ff6e925ff75b38c5d02808e8174d9c0c09fd32d6d777a5e177ad8605932e1cd3a83d012859af4c3f437bd3d6bb6":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":"3066023100b1a6fe0fb0315ad767c247e0ae6b67977433d7c228fa91705ceb2fbfb604fdb55a820d0ff3013167b4f68c645bd77dbc023100a365782b37cfc93243e0ee09d84a4ca79b2a68c0ca8eeb5071628ec42dddcf7f0541f28c57577907dd0c340d95950bc5":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":"3065023100ae31c13a0e635f5f4973c3fa2fb931742891aa5a41e4af0620d4ab2852c7b9ed7765499e2e4c167675fb39d93bc6b4c102302e4024301733c6c9b90532afdf70b45ad6e159f79013bf64ef60eb1cf9f85dfc2c0c052130d693c254f92982cbe1be74":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":"3065023100c1b4a7f73b97ee20499b239691bb1e3c40ee665f884b36d140bf277671215e289c7f6b721828b78bc9cc211829b554fd02300e2336523bc60ab69bfe07b799283303bcd45476e308f386d7ed76c47a8f898cf5b31d079c0d863efe6e4463f564c8e0":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":"3066023100bfbe2f944aa4c74f2448b2cd7cc3f5d61559233d4bf525c157cf7b96dfc5db1e7ebbd03e5a03a151a1d0a756d3c2b6a7023100a18ec47c84eca98f3675e381a7cb7ab4849737df69a23aaf722f0319c4b983c219d8235fba1ddcbef295aa9a2ebf7d37":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":"306402300f6937cb9460460826610b0dd200f43ec82e0dd01644e089008eeb526467aeab53a31c51168e7f10a98cfd8fa9945b3802306a23d6a4f6724830b9f5734080fc3bcf201d28e0fafa4ffb9cce6b4fbcc11fcc1f547f202b9b86097b009d9632a13625":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":"3066023100b675a56b6c660e34144edbeaa7389869a9014cfe2242f89063d8f5c6f30f55f18a9c1180170009c60e2e7564f83b9717023100d9739ec924e05802ec969ae30c8d2a08623a7895f1cbdea3106a7c054f757e82c4684be3ac164370403dd414f6640642":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":"3066023100a5ec17250cb403325fb3c0ba913cc1b27a915fdbf4e6425d5b866212b64fd34bee2a21a529fa83abe46bf83490a40c2b023100876c11b52beb7f8ef767e1e865c876210be473847abf5ea7b46b8af7552a15ddd68c1b339473b177f7b0b185df2d63b3":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":"3065023039fd7dc2303d2335fd433432ecd4583aadcc40dede2f0075856e0e1178421bbd96fdd4cf28d6cdaeae406aaa9b61e81d023100de798c30e0fd48516c9df099d7df9045d463021daa09c13f69c07a60b8ccde464081a8a6a0f7b6d472e90fd25e730b9e":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":"3065023066bf8a5ab537cd2767b915ee39ddb9da6809deb281bcbc3de3b6e713eeac3b7099fad86e1bee7c47d49ed2fe327e68bb023100f1bf2b9165723d831a449424ae86e1b33d5d372c942dece0b60c4d86a985190347739cfb246108c8d417e164ba14364a":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":"3066023100f0f3c1cddbbe62bd656e909fd63c45fdfeeec8a1048c5521f6c220b6fbe56df948af6e26857f80fd81ce7beadcd50056023100c9b21d2edb68243e49fc0068218e684c3b9d79bfab070bdd3cd295c6043e19f2fe76b0e8967a247e81f7923262c3120a":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":"3066023100b1003106440a7807b1bad78301d95b85a6214dd5b1c57190d23bf2e7c8a0580852bb5293f74c36573566d861be7fd364023100ff6463c7ff44b22613dcbe7bbf0697aaa86a6e146267baf9b68dc43d173c274237b75188d9e56794a511488377d4d666":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":"3065023100f635e663c1343600b755f948504f1a56584dc684bda93f0dc486edca3eb236a8aa58c2a8ff22c5a3f21ba94e768dcc2f0230259eac31d9fd5415c63000bfb49d7259e403de18fb4ac06210a30ff33762e819937845f04cc50e5042caff8cd177b0b4":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":"3066023100e89712f56d0b43cded5bc8b37f72168747cf9f29522d50e7136303a1de917b2bb817ca44a1646e758616f9e484a08555023100914ce27818ffdffd7e4b64fe695e03bdfbb60f41e7e799e114ce8981f1eb250fdfee9138b304c8677c5a5a5cb7f53d9f":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":"3066023100eed7c97aa65d73427063a3dcff0ff53268529afeb639b21e0e271feb0efe48e6bddedc5738d8ed86197a41ac9af9dfaf023100abca6dfbf3143f68446cc5276a6823a8d50d677c0c9c5fb4b7eca54a882114118562eaf21bb8dff96f140537a98a27bc":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":"3065023100f6ccda598ab16b0f1feeafb46ce64abdc29f1cbf84329bd61349107e10c54556a7be05442738141dacd6a038223e6fa0023066b4e9215b34c5dcf7fab7b1f48454d3abbe7a083f34f1525be68721323a628220e0c84fd0768b71505dbd760baa41b3":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":"306502300587a3c03fc954985b043ada3bd06ad5de914fa80b2a4f830ae778dd8854d9cccebf583f52f3875fb02eb6622561050c023100c73036316ac556db87e1fb2b7218ce1336fbc04c6e92a814dcf668f0cafd9871fe078b661c6d68dd9a542a1c3041fcb9":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":"306402303869495359e20d2e0e756486ac25b16e2b50aed5a966e7cd8ef49c2bbdbaae43013e83c3de45f9bf020f54c5c8e06711023075c7d85d9dded26e83a781c98b4e19cd0015537bdb0c8d08957a3468ca5e20d31eaf579a039e5215b17920bbb8d5f6ad":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":"306402304d692b478e924d9a940ad2dd04e3430492bb0e5546bd02d4f827cdb6375b05b25a3cac93bc0ffcb5127cf025658421e5023011497be631721a010b5b7f05d5e9ba1dbee332af4f08b6c5903a59aad3b01097d8cc4a62557c91f17c53dc1e2e73f296":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":"3065023100b4d638b4e66d4dd334b57139a4efa4f5e480bbaed587f25de32189d0418e7ae75ee8dc798f5369e415664833bbe99230023034f207aba85ea4d9fb344fb6caeea151fe34b2c4a17077b26627d63a56c50c50d6e29fc01c7134e22ba7cf31de69f059":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":"306402301f79d2bbdcb6c2abaa13abdb58c761287a2d6574dbb2350bd8d145d802d4855807fafb44315e1c0ca28cb2aff2589b7202300a409cf3798c1c1f18f32bb5dde7d7dcd3fe7c003cf9392e3468fbf6fb66f79c244eb7a745e11ccf092d34adc5d058be":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":"306402305cf6ccf9bbf33ac017db5686e71a89e6b105a0b23d80bbafca3b6d3e5e4f10b65531c212aa483a9b83838c77b84be01f02303cd7fa1657bae6d4659c9c09122bbec8525a5025a38bcc85b24d3dc5b97ac49952a7783b0440019d035668712e195016":0 + + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":"4E260F39859DCFE7DE7B6D79F29E3B02ED5F3A637DD7C0235C92D63890A6421BECEC30F602E63B2F2A7658983B40EABC6C343BDA4579FB5FC2ED781EEB0F6B660E062012132485696A7A779B905744C3F5A8A3892F02D799B5F44E99F2D6220984FDFDBC9B91772A2F68628EE73D39F68CB577F3CB9787CD7DE3C7811CAC687DBDB4D256FA56974488A18D221FF3DBCBCFF664FD9625C64A15635B29CB25110AB330793E8ADABABE8859784BD8C0472BAF0557616F7111BB524FD5772FFB57404F61BDEC0F94F957CBF7E236F62BE46DF4FFC0BB76A4FAD7ABC74E3D6352766BDDD1E2D2ED81A12E44F5FA8C260123603B70218FE9945F6B90F3DA4281BACA4E":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":"9F5E1F07FEDB3AD498834BBE3DD9D1A5D90C5C0BB40029929EF19BDB9AFEA3C8F36BFF638EF760CDD1D5F09683EA59D8D30A782E5366F796EC3D4794EBAE0B293FE3B2A5374565E81A998F3EC505C7C39400274AEBDBE7096806F0261FB01D9195360A348F4CBDB2A00C0402191BE58D94F5EA70903161E644CFE160300A1ED65A72B52D130482045E5861FC3AB25E3E40FAC6C293B57BF538E597735F0DE5A14190D53B59DEF7F9C5EC9888D956E202FD23607CC856C12B571FC20211A123DBD4799366B219EE833C8495C2656BC519100FC4A41C5E66CF7AE0E30E14408BAAE8C32CB048B561BB60AA8F402B0D6870233E21F9D15F073EA8547A0DA5719539":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":"5472D9CF13F2F14949E49078B09FD0E6BF08417156654E4BB367D654F499209F39CB74D3B87D6E8B954EF57AF35E6EE1A6595E9ADB1B07ACF45C5F926DC92BF300C7DFD722C89BEFD08EEAF9338B17458475B4D19E5303AF0A0C5C41DCE5BAD449F4B9C1F0BC7470485FD515B86C2A24BBE421EF807120C2EBB6808124DF1718DEB8D992D97C3D59F923F9961FFE87A40C368C7F256E54A1DD4D8E2E6DB26D50219816D71CA81429528DAA4F34747FC7E37A2B482334FF8FB22A6BCAB8C77E1610E0905607395F7DE6FD31CDD1C52D853E95FBB4FB44A29F68A44ED93159441A21EA04E8D8A430C1CEFA8A3B958FF066A5D8D9364FE1C11521B523746CCE69B4":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":"1730BD02491006D9D0A2186E764E5E0BCED12764D692B9BB6AC0D48347D04013BF0F232C4F65FF21DE01B596D4C6C60E8407BB3B05AF1B370A28FBB6B8833447B8023B163788B2D0DEF92552115886C1A19802B7FE7D39D8865E38FD70CF8ADE38119372C5C041DDC13DEC55095F36C3FC2C505209E3834A2592571B3484F3D113B073DFD9471ED1ADEB6AF46F8698925CB7B8AAA3BAA8EB4AB0C1482E3CF8445F944B23CFC139C1B7D2F3EFF14ADA83FAC4BB68505681D0752AA5F296BC56392322163B7375CF507FC1D6E0014F52BBE0D31F1A79F9F95A967A34217F3F9A59738D195A9374524C075266E7F07C5933969E4191C77E33FC9A94990F0014979A":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":"6346909A04F3A7FE119ADF2D6A3C98EBDDC0E2FC1D212F9582E0FD524ACBD42174596ECF1C58122CBC62DAD963226908BC7F2A3E4B733A6E7054695C5CF281543D99B5E25E594DC144BA0533E5862334C9F0C63D713DEE251954EF2069CC596718A136AA7DE7654686BFA70075104D47A3A319949CE4D84826693D5A316C17CFC3C09E03803E1F32F52A6EE6E072F078FFFE451891695DBE8DC94113CFB465770F80313F1599A03F05665E349AA549C1E58DBE7E4468D29BDAA887B6CDBBC35AA4C3BF369B1CC46289FE82E6F223AF319CFDE962B89D04D0439A67D622CF52AE8D55CACF9AEAD6C7018CB5E0D589E8047619A263EE35AF1890B36CA5793CD916":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":"610F852BEE74E67BAD70D0567644EB743CAE09D997FADCEC6B058B3E6348853B80A84AF7CEBA5A46E6D349987228B2A74C9D6870FBC29AE9EA3A642ECB41D644114FEEFC9CFEE1032009F54B7515518114D4AD5EBA1AE6CBD6A1FD16B175629A7E77B99C86A9BBBF9303A9D73EC035342139EBAC8CDD976B304E7EE4DA1DDEB1495BE6127C9F8210581F9914C933C41FE3D44E4DC3F5642BC4C2C0AD0641E74F989034483BB0012A5C6AC406008FC23D4FB5572C73A3C1F4375BB5DE0339857D3FECEF6C8D293A1F3906608E0B1D4FD60DAEBDC0FD3C55D9F122E3DD916616090B12136C042623F008A5E0EB29845FD43BA7D2C1189835F62A19079DE23F05DC":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":"AB2A7401AC658FB944E888D6B7C527F436412095D7BC927E84980B923773CB8AE9B3C5941D2F9F433EB67A754E222A84B2A580BB0B2A1EB7EB06A08E54E36D2B471333D9A84F43E8CCD333753422AF660157498B8321F1BB2DCFA2425ED6A16E51436DFA2D8C3AF1FB3E94A06DFB11E52FB4A4FB7A9B1A9EAE78046FDC21DD90F15C904227B21BCBDEEE315590F8CBC245B07C7579C482CE1DEED1AE19A78A88C5D8F7C9440855CF1DB991C62C890CD1950E6ECED081F95DA8896E9D9ABEF20978AB34A229681714BB61CCE857FDE5AF9C848D3B681EDE413BD670EDD79B899C2DF47A0197C062FCB4015DE31A84333C7D8B1B9EEEA05473CA220E451CB3B645":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":"AE8621F986E3ACB1167DA8E788D2103DBD1A7955405099B5345F714B5AB683B303C9471C241D79DBB980C52D9EF1059A5F3D869CF5472B59DEDEA1E00B135C30B3FB86DEA108F5A6FD21437144448CF0C4ECE42B100D171D4A314624567561471AC34AAEF7732E8B5249B4959A4423B6702395129C01C2034AB7CF23B9313B6F250EFA9E4C779FC17BB181F0D61A420FC49B5685E4C38C6F5B48C7CF99B3752CD11C47316C5C3344EB7B67F442CF9E009AF1A44BAF63094845EED02F6A0EBB80120574F5ABF1160C1FE3E89E31761069DE56BF0353D4AB4294BF0D458AF438FDD0C3CFD04454D51E9C276641E4F1E308930E243625F58E5995A40B2836962289":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":"7B199D509684FA14D008A52EB1D06F05156C9AC9293ECB908DFD57D6086415ACCE03D8D1D1F7693E22938F0D660216618D9BAF6E3F240841690F9DE6599C5A45750987120B8332CBB71A1141FC1B105BF59E74BC0EE00595D96B42D263CE86A940DFC625AD635ABF1D839A407759BC33B96B6CF54CAEEDB04BEEB6E1DB0AB41638652474C85601A3C2879247C508C16A94B2199E0687B1A8EEF1B493C600B3FABEE47FE7901F90616D5F24ADBD20C9F2F8ACD0666FA670DA0A3FF1B9F92B2DE4AF571475904F7684C7E797B181AE4E3965BF9A10E3876653900B6408B741FF7CAD2136CBDF96DCB51FBC8AEB5212CCB69975C073C914F88400E973A4188F01A1":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":"5F479711F9036CEB0B380524C5AFDAC4F7455C4D45CC735D59CE1D12AAC63F05A6DAAAB812D022589F7C793AE1590D5A271B0AEEC9C30C923E58E1B8C454700E6C8EC4E3ACBB48E0A00D67776068D9C95DF63DD2344D5B5308A7332F622AB50217C1E6B5EA7BBB8D07E5C9F7DB0139F95082F27728832F554917289475D0EA9697D8C3C31D219A5DB5029ABDD7D0CE6C6E230B6F2D47254EC031B797014FEEBEC0EE2BF5880759ECC1C249FF33765A87BFF6A7C6A0AB454CD79F8E848895ADD9930A090E26B149DFEC99069713550D96DBEEF2FC59114FA1A625A256CAA01BCE4D8673A17A0B7071AC3227AA9384085E55A0E08FBCADABC5C0601AD7F6CA82BB":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":"9251B4C9A68B1359744C795FF74F5062461DDB797A17279C301984901D2D46B8F309546C60B54CE1600785BFFF0276C658C366EEB2BE2BE95C53B6A25475CE9AB9E7A447238FC7FD71ED2A67AA091CEAEDCB4D0AAE4343F385E466D01FF2445597CC6D3D278BCA10D0E4DD8678C148FEFF44834F6EA48A9AC1A97869534AD164F592FE0D8896A9299908AF5DBCF80CBD70733416D2F1D3180540246181AFCE6D176595D7532A4D8570637B0B716E1F9FCD638AF47D42160E797AECD7E45C59672A68670B66BCA19438BDC1DE001377F7109C150C72ECFEE454575DB4640DA204AE54407736D3F7D8FB846E9605E90148473ED16E5B75D620D24B5564275CF5B0":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":"67FD8A9F7E52570E849CBE7B7AA2121BF33ECA40C7A2CF369D3C601F7C079FEF49FEE6BC9B2594F7B46A37A6FC6D054713AF1F6820FE976776BE7861F16205CE4E3EF0E7EE7DB2097F9C9F2C580A0B514A33E0897B9E4DAE58597FE3C996B1DC14137A79DF54D6CF086FCB8E666BA156330535D503A71E58D830DE8E0E55AA8AC84E76D8F2D6BBAD721AF0BC937C683DCCEECF7F4AD81FBD0777B551DA037FC6BC5B3519503D800ED4076D1711A711784974C382BDF62F608CDC24A605367F8121FF7101164F5FDA04E98ED7F4CF6DE943D6E4E248C1BB5E7CCBB585FFC149FAACAD2D4A17C88281157EC7BEDE01C6B65CA983D1448222F59F190AA86589B1D2":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":"6137C33F7AE767A284A0ADF0ABCE514E585046FC9E69FA1A19014D077AF318B65E93742D9BA5AD3A88D46F02DC324AE542FA54B338F408D809400D7230A5F39D96A7DE6BF94FEC2A98CD791324C0D2FB01A5B0A41E730E9224C7A01D1F4FB70F68C3009F69D47252DD2890B2BBECEFA907DD24E5B189F52F144CAE1E707CB7B8C348EC5A8AE65099EA29C9C6E0C39832A8AB06676E72C39590B1F6A5A86B9F28F80C8BC8904E291AA9077EE92A2D21EF7740C918CC44D793D6DF82CE88AFD32EABB1D1540A0355E91D7C29176C66C717A3C67393036159BF5BB1128CBB1978C55E32A401204F834E6CD8941A322EA70B6F8FEA1DC7478E3D81099F1ACA770B23":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":"9630AB919732F8F2B70CB619E1A21A96BAEC861EAD3D9E30FCB5B62766902702C503051A54143DE61A61FA0DF586710D15E458745F2EDF5FC9BF0F1C05E399C358EEA2D9585BD53AF443DCFC7C0592AFDCB8106D7588FC4C6C8C6FE36A5E078FD312CCDC888726C9FFD9FBB0B5A94DC1A1A67829894CB773B75D03323E5C9ACFDF9FC7F5FC459150027913A8D517C1C0A9F3092FC48AB038459CF9B2119A03D7F7CDA268F7122D4CF694CD1989D25228B0C2230130421826889F3E9B825142627A079F8919E7B17D71F32769DF51DA627267F23D6B956F8757C651D68FF20466B9768D17067D06513E41BA26E2C1A08F9B9A81958F4A658211C0AA53EB74568B":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":"7CD2B891A453337F7D242C09EEF4D36C7446F0B4D814E75A089EBFA6B3F1891EBEE85501D790D4C2AFD6EF814083659DAA4D06580671AF558134EC71D54EBC2266BC2489F7ED53C950F0BC5E0D4DD9300E7E4B413DC96CC91E7E633FDC30C6C72FA2662A85B30C262C71F9F58E58301C8FAFA4624AC68DCE8AFAF642BDCDC1A6AF39C3F81DE480A10F47134F8DF2789040512F97860A2D80A75E3FEFBB2509E32857BB82ECBA9BB338F8D139B055DCDA30E7880155D61A402B495DFF9A01629BBE4CD972CBB33CF9C609A8304A40DD60D2740862F6939064940D036C1FE4B5A9377774C111CC33A126AAB6647725C6BA4E7853A58620C8C69D8534B692DA8832":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":"12761B411BE0E1DCF2D358941BE9D8DE5535376FCABAFBA0AF857EE8268A6CFE2FF1E2307B41F0C0055664DEA31E05625123E84927D39F2A74A727AC070981F23C845807079DDC29B41D1628172DB4099910CF4402A2B9817D6AD445313CC7659EEF6D8AD9AE654BC00D83D42C1BFED5273F6FA4AFC729D58A53FC6281D5D0A2C18F59613281480284019F51A8E16AD41EBBDC56B9C8DE24C4D01D50234FA42FE6375744D3DD8BB0CDB9576641C8513B3C956D2CFD1A99904D62C51FB9E30E5CD8B7B3B142CABE30224D17668926899548C496A2A8FB1468A81FD656E45E5F551F9309478B63FAC69C2DE6ED96745893DEE841816965D85C0035D4EA4C795CFE":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":"7E7191AFBA7B1BF7DA37CB902A192219766FF5EF3B64F34FEAA1DD19D6E6499E595D59583C4706DB17F48F1A1A657AE4D556523D2351E60F9860B837929E57C88B919C04E2C7AAA5A98A650E21F1FBACD8AAB7681B1641F8B9FE1C95D23CFBF04AB752D98C8DAA893C02BBF90337A28F3EBF923C8B36E4DF3159B8452FD3ACE04FEB0076A951EFED8A573683DDEC276C279748F46679E52B6DB86E1133B953CD6AB3AC002A2624A3F32920427CDF29B950001DD1B43526AD2FE02973FCF1CA3771FD922D2AC6B7183EB46D24E886B654EEAFE017BAE964F5C09A7087069926F514A160742033653FAE8064CC5F5B29906A5A2BD4C042DB2DA546E73D3BA792A1":0 + + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":"3045022100913d3758e752a395e86b07f4a5a47bca86593beac472a4ae42b9d8b55358153702201e4b620baea6ec47dececce58ec01e55e365e8c5982f13d8349991227cb248ac":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":"304602210086ee8e51c388d8432c4e4d30a37d3de32fa19d312723b4613570d9be95725256022100821e177161fab711d1c9c599d4ea1906ed9a54a6990b77c453df517377b9cd28":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":"3046022100c2794ef9647ce5303a976740510bec6720509fd8bbae2eb3a929c8c2f844f24f0221009c93b131029ac748757e1ac2e264c2ce248ff46e374f94e5e00dd16d4b3b93db":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":"30440220018081116109ad97107cb5ed3b7f246173d8045fbdce9397681e27fb160d8e3c02207baaa738176758b2cf60d683694d0ff996be53706a0b25f49df2c73613dc608b":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":"3046022100db800ef8e640bb8caca64b08f391ff1af752b2871106dd5e1ad182b47cd574f3022100d280376ada28594023d37d6ffd47c99b8522bfc64c69d1268f6c1ef0697cb5a3":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":"3046022100fb2b4cf23901b3d5974c0aa5faa9173c951d4343d51b7289899166e71c448c0a022100e4be055a715a88172480835d2e436049d6c46cc79aa9b09706235a3d88675710":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":"304402203a63d375eef41e54721c1788717bf3973229a600d9f57d1cb0f48e34ac71fde902202fc87481167e53864bac52c3ee0ecc8a179f914cf2b465d0257ead1245b58ab9":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":"304502205bd43c3f9e78c624ec5f32a4815aa5a02596d685417ad5dbd90cc7ba584371d7022100f20f29af46cdf002217842e8b068389e7a026b29c543199822dc9ad0f96fa2ae":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":"3045022100b1a32c15c6fb9c079819f65db37676654b43814b1cfe35d17b36386f2d94c59f02206d5a4db338da2d8aa31493850252fadeb07c72d4ddc6bce37b305fbb1d62b52c":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":"3045022100c7787ecbce4bee2dd48001de30c47ad853e399bf5a0caf4deb0384663943257b022072170558655bf7f8cbed1af634911016e83bdf7249cb37e8d6160d9ba2004541":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":"3046022100cd93f79e7c1a2698f5ecf3e37a434425231c3156c811acff1ad56520421bd8a10221008f5063d4d8404e68b5e5a4cc7d3e69d9f970434ed657b59419f238784e601a23":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":"30450221009bb3a8bdfc3c71a3990ad80521d94e61ba5f2f28c32dfe521f73632ef365060f022010bee63fe1e13b970efd65e9ac01cbc5b9de81c8bcb1e4875423fb94da81ce8a":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":"3046022100b7e2921a657082edb6b8fa1f12ab6dfe9d36625a4a2ad3ef3575de59b3ea4eb0022100c59a464f564e376e9247ee77ae611ff4416e92cf883a410d0c0a5dcfed18c011":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":"304502207a7647cc717f7cb51f2398040ec7031300437f5259235fcf4d3651c6f8365db9022100a72e24513dd952dd63415c150a4b72dcd248a9b5e282dbaf404aa04983fb0073":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":"3045022100bca6b37c7dbd277c828384a1e8cac53b95d075f0f241c3bc9f82eb25f16a93bf02204523a097bd161bfc9e76add87df0b3c17dfb181920e1c3554301c7405182bc61":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":"30450220723f4ccc56a671185d4e2743210485619a2f5f54929b137d44c9110ae448998d022100d3e984b771bd830c417a7a5a9ef288f182e108d27af3dbbb6594d0dd4d8d347c":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":"3046022100f3bc539cffe2bf05beba86f234782b62b61abc1b1bd60dd366d52e4b76d9c279022100df78717fe6a7b19f47f191c3f9127630e1f9d8f32e6da715aba5e43a8f26648b":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":"304502200974b1e40db6ac805a961c75a2096d1267af55fe979ef9f3dbc1cb9e3e9046aa022100b284d2de268d33a7c923182120f113a27e51d67e2f335671721ef1d58328e2a1":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":"304602210091025779c02d0f3725450eecf13c8a8cbf2a377c0a3be0296c0f520fa50f86550221009472a9849a234bf9e3a68ce3d243a86281f9eb9ed5b44a2b8c6a734e158c99c0":0 + +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":"3045022040a462836c62056d90590205054f381aba9e5e6057d26cc00f91bf07672d84d9022100e7991fd976db559a359c0a871a520d02930a1b3cdc70d0dfadc36992c6dedd8d":0 + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: repeat authority key identifier +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_akid_repeat.der":HITLS_X509_ERR_PARSE_EXT_REPEAT + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: repeat subject key identifier +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_skid_repeat.der":HITLS_X509_ERR_PARSE_EXT_REPEAT + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: repeat key usage +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_keyusage_repeat.der":HITLS_X509_ERR_PARSE_EXT_REPEAT + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: the length of key usage is invalid +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_keyusage_err.der":HITLS_X509_ERR_PARSE_EXT_KU + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: repeat subject alternative name +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_san_repeat.der":HITLS_X509_ERR_PARSE_EXT_REPEAT + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: repeat basic constraints +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_bcons_repeat.der":HITLS_X509_ERR_PARSE_EXT_REPEAT + +SDV_X509_CERT_PARSE_EXT_ERROR_TC001: repeat extended key usage +SDV_X509_CERT_PARSE_EXT_ERROR_TC001:"../testdata/cert/asn1/extensions/cert_ext_exku_repeat.der":HITLS_X509_ERR_PARSE_EXT_REPEAT + +SDV_X509_CERT_PARSE_EXTENSIONS_FUNC_TC001 +SDV_X509_CERT_PARSE_EXTENSIONS_FUNC_TC001:"../testdata/cert/asn1/extensions/cert_extensions.der":9:1:-1:224:BSL_CID_CE_KEYUSAGE:"551D0F":1:"030205E0":BSL_CID_CE_EXTENDEDKEYUSAGE:"551D25":1:"300A06082B06010505070308":BSL_CID_CE_BASICCONSTRAINTS:"551D13":0:"30030101FF" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":"../testdata/cert/asn1/nist384ca.crt" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":"../testdata/cert/asn1/rsa2048ssa-pss.crt" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":"../testdata/cert/asn1/sha256Rsaca.crt" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ca cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":"../testdata/cert/asn1/rsa_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ca.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.mul.der":"../testdata/cert/asn1/rsa_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ca.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.noCRL.der":"../testdata/cert/asn1/rsa_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ca.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.notCA.der":"../testdata/cert/asn1/rsa_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ca.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/ca.v1.der":"../testdata/cert/asn1/rsa_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.der":"../testdata/cert/asn1/rsa_cert/inter.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.mul.der":"../testdata/cert/asn1/rsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.noCRL.der":"../testdata/cert/asn1/rsa_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.notCA.der":"../testdata/cert/asn1/rsa_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":"../testdata/cert/asn1/rsa_cert/inter.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end2.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end2.mul.der":"../testdata/cert/asn1/rsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_end3.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/end3.mul.der":"../testdata/cert/asn1/rsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_inter cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.der":"../testdata/cert/asn1/rsa_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_inter.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.mul.der":"../testdata/cert/asn1/rsa_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_inter.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.noCRL.der":"../testdata/cert/asn1/rsa_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_inter.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.notCA.der":"../testdata/cert/asn1/rsa_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_inter.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/inter.v1.der":"../testdata/cert/asn1/rsa_cert/ca.v1.der" + + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_ca cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.der":"../testdata/cert/asn1/ecdsa_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_ca.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.mul.der":"../testdata/cert/asn1/ecdsa_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_ca.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der":"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_ca.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der":"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_ca.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca.v1.der":"../testdata/cert/asn1/ecdsa_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.der":"../testdata/cert/asn1/ecdsa_cert/inter.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.mul.der":"../testdata/cert/asn1/ecdsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.noCRL.der":"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.notCA.der":"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end.v1.der":"../testdata/cert/asn1/ecdsa_cert/inter.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end2.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end2.mul.der":"../testdata/cert/asn1/ecdsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_end3.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/end3.mul.der":"../testdata/cert/asn1/ecdsa_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_inter cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.der":"../testdata/cert/asn1/ecdsa_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_inter.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.mul.der":"../testdata/cert/asn1/ecdsa_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_inter.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.noCRL.der":"../testdata/cert/asn1/ecdsa_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_inter.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.notCA.der":"../testdata/cert/asn1/ecdsa_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecdsa_inter.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/inter.v1.der":"../testdata/cert/asn1/ecdsa_cert/ca.v1.der" + + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_ca cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_ca.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_ca.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_ca.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_ca.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.mul.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.notCA.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end.v1.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end2.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end2.mul.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_end3.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/end3.mul.der":"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_inter cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_inter.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.mul.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_inter.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_inter.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_ecc_inter.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_cert/inter.v1.der":"../testdata/cert/asn1/rsa_ecc_cert/ca.v1.der" + + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_ca cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.der":"../testdata/cert/asn1/rsa_pss_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_ca.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der":"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_ca.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der":"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_ca.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der":"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_ca.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der":"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.der":"../testdata/cert/asn1/rsa_pss_cert/inter.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.mul.der":"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.noCRL.der":"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.notCA.der":"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end.v1.der":"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end2.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end2.mul.der":"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_end3.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/end3.mul.der":"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_inter cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.der":"../testdata/cert/asn1/rsa_pss_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_inter.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.mul.der":"../testdata/cert/asn1/rsa_pss_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_inter.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der":"../testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_inter.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.notCA.der":"../testdata/cert/asn1/rsa_pss_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse rsa_pss_inter.v1 cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_cert/inter.v1.der":"../testdata/cert/asn1/rsa_pss_cert/ca.v1.der" + + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_ca cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.der":"../testdata/cert/asn1/sm2_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_ca.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.mul.der":"../testdata/cert/asn1/sm2_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_ca.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.noCRL.der":"../testdata/cert/asn1/sm2_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_ca.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/ca.notCA.der":"../testdata/cert/asn1/sm2_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_enc cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.der":"../testdata/cert/asn1/sm2_cert/inter.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_enc.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.mul.der":"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_enc.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.noCRL.der":"../testdata/cert/asn1/sm2_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_enc.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc.notCA.der":"../testdata/cert/asn1/sm2_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_enc2.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc2.mul.der":"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_enc3.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/enc3.mul.der":"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_sign cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.der":"../testdata/cert/asn1/sm2_cert/inter.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_sign.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.mul.der":"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_sign.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.noCRL.der":"../testdata/cert/asn1/sm2_cert/inter.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_sign.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign.notCA.der":"../testdata/cert/asn1/sm2_cert/inter.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_sign2.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign2.mul.der":"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_sign3.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/sign3.mul.der":"../testdata/cert/asn1/sm2_cert/inter.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_inter cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.der":"../testdata/cert/asn1/sm2_cert/ca.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_inter.mul cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.mul.der":"../testdata/cert/asn1/sm2_cert/ca.mul.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_inter.noCRL cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.noCRL.der":"../testdata/cert/asn1/sm2_cert/ca.noCRL.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse sm2_inter.notCA cert +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/sm2_cert/inter.notCA.der":"../testdata/cert/asn1/sm2_cert/ca.notCA.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc p224 +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca_p224.der":"../testdata/cert/asn1/ecdsa_cert/ca_p224.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc p256 +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca_p256.der":"../testdata/cert/asn1/ecdsa_cert/ca_p256.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc p521 +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca_p521.der":"../testdata/cert/asn1/ecdsa_cert/ca_p521.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc bp256 +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca_bp256.der":"../testdata/cert/asn1/ecdsa_cert/ca_bp256.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc bp384 +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca_bp384.der":"../testdata/cert/asn1/ecdsa_cert/ca_bp384.der" + +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001 parse ecc bp512 +SDV_X509_CERT_PARSE_PUBKEY_FUNC_TC001:"../testdata/cert/asn1/ecdsa_cert/ca_bp512.der":"../testdata/cert/asn1/ecdsa_cert/ca_bp512.der" + +SDV_X509_CERT_CTRL_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_CTRL_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":648:BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_CTRL_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_CTRL_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":933:BSL_CID_RSASSAPSS:0:0:0 + +SDV_X509_CERT_CTRL_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_CTRL_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":594:BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_CTRL_FUNC_TC001 with key usage sha256 rsa v3 ca +SDV_X509_CERT_CTRL_FUNC_TC001:"../testdata/cert/asn1/cawithkeyusage.der":852:BSL_CID_SHA256WITHRSAENCRYPTION:0:1:0 + +SDV_X509_CERT_CTRL_FUNC_TC002 parse ecc p384 v3 ca cert +SDV_X509_CERT_CTRL_FUNC_TC002:"../testdata/cert/asn1/nist384ca.crt":"54:eb:17:4c:ce:5c:70:18:73:bc:dc:a3:3d:b9:81:1f:63:67:6d:06":"C=CN,ST=open,L=xian,O=openhitls,OU=asn1,CN=ca.asn1.com":"C=CN,ST=open,L=xian,O=openhitls,OU=asn1,CN=ca.asn1.com":"Feb 4 07:03:41 2024 GMT":"Feb 1 07:03:41 2034 GMT" + +SDV_X509_CERT_CTRL_FUNC_TC002 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_CTRL_FUNC_TC002:"../testdata/cert/asn1/rsa2048ssa-pss.crt":"54:f3:3f:24:20:59:84:91:1f:dc:3c:5c:50:a3:d8:90:d8:93:ff:5c":"CN=example.com":"CN=example.com":"Mar 25 12:13:22 2024 GMT":"Mar 23 12:13:22 2034 GMT" + +SDV_X509_CERT_CTRL_FUNC_TC002 with key usage sha256 rsa v3 ca +SDV_X509_CERT_CTRL_FUNC_TC002:"../testdata/cert/asn1/cawithkeyusage.der":"5a:ba:49:ca:e8:4a:3d:d8:be:35:53:d5:a4:ff:5a:85:32:4c:87:ef":"C=CN,O=Test-hitls,CN=CA":"C=CN,O=Test-hitls,CN=RootCA":"Apr 20 09:34:13 2024 GMT":"Apr 18 09:34:13 2034 GMT" + +SDV_X509_CERT_DUP_FUNC_TC001 parse ecc p384 v3 ca cert +SDV_X509_CERT_DUP_FUNC_TC001:"../testdata/cert/asn1/nist384ca.crt":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CERT_DUP_FUNC_TC001 parse rsa pss v3 ca cert, any is null +SDV_X509_CERT_DUP_FUNC_TC001:"../testdata/cert/asn1/rsa2048ssa-pss.crt":BSL_CID_RSASSAPSS:0:0:0 + +SDV_X509_CERT_DUP_FUNC_TC001 parse sha256 rsa v1 ca, any is null +SDV_X509_CERT_DUP_FUNC_TC001:"../testdata/cert/asn1/sha256Rsaca.crt":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CERT_DUP_FUNC_TC001 with key usage sha256 rsa v3 ca +SDV_X509_CERT_DUP_FUNC_TC001:"../testdata/cert/asn1/cawithkeyusage.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:1:0 + +SDV_X509_MUL_CERT_PARSE_FUNC_TC001 with 3 pem certs +SDV_X509_MUL_CERT_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/sm2/chain.pem":3 + +SDV_X509_MUL_CERT_PARSE_FUNC_TC001 with 3 der certs +SDV_X509_MUL_CERT_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/sm2/chain.der":3 + +SDV_X509_MUL_CERT_PARSE_FUNC_TC001 with 3 unknown(pem) certs +SDV_X509_MUL_CERT_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/sm2/chain.pem":3 + +SDV_X509_MUL_CERT_PARSE_FUNC_TC001 with 3 unknown(der) certs +SDV_X509_MUL_CERT_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/sm2/chain.der":3 + +SDV_X509_MUL_CERT_PARSE_FUNC_TC001 with 3 unknown(pem) certs (with redundant symbols) +SDV_X509_MUL_CERT_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/sm2/chain-red.pem":3 + +SDV_X509_CERT_SET_VERIOSN_FUNC_TC001 +SDV_X509_CERT_SET_VERIOSN_FUNC_TC001: + +SDV_X509_CERT_SET_SERIAL_FUNC_TC001 +SDV_X509_CERT_SET_SERIAL_FUNC_TC001:"301D0603551D0E04160414B527FE6E548AB0EF17" + +SDV_X509_CERT_SET_TIME_FUNC_TC001 +SDV_X509_CERT_SET_TIME_FUNC_TC001: + +SDV_X509_CERT_SET_SING_MD_FUNC_TC001 +SDV_X509_CERT_SET_SING_MD_FUNC_TC001: + +SDV_X509_CERT_SET_DNNAME_FUNC_TC001 +SDV_X509_CERT_SET_DNNAME_FUNC_TC001:BSL_CID_UNKNOWN:BSL_CID_COMMONNAME:"550403":"616263" + +SDV_X509_CERT_SET_DNNAME_ERROR_TC001 +SDV_X509_CERT_SET_DNNAME_ERROR_TC001:BSL_CID_COMMONNAME:"616263" + +SDV_X509_CERT_SET_RSAPARAM_FUNC_TC001 +SDV_X509_CERT_SET_RSAPARAM_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p1.key.der":CRYPT_PRIKEY_RSA + +SDV_X509_ENCODE_CERT_EXT_TC001: v1 +SDV_X509_ENCODE_CERT_EXT_TC001:"../testdata/cert/asn1/rsa_cert/end.v1.der":"" + +SDV_X509_ENCODE_CERT_EXT_TC001: v3 +SDV_X509_ENCODE_CERT_EXT_TC001:"../testdata/cert/asn1/rsa_cert/ca.der":"3051301D0603551D0E04160414B527FE6E548AB0EF1788465CDDAC9E1D3EC78EC0301F0603551D23041830168014B527FE6E548AB0EF1788465CDDAC9E1D3EC78EC0300F0603551D130101FF040530030101FF" + +SDV_X509_CERT_GEN_BUFF_API_TC001 +SDV_X509_CERT_GEN_BUFF_API_TC001: + +SDV_X509_CERT_GEN_FILE_API_TC001 +SDV_X509_CERT_GEN_FILE_API_TC001:"test.crt" + +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001: der -> pem +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem":BSL_FORMAT_PEM + +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001: pem -> der +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem":BSL_FORMAT_PEM:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1 + +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001: pem -> pem +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem":BSL_FORMAT_PEM:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem":BSL_FORMAT_PEM + +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001: der -> der +SDV_X509_CERT_FORMAT_CONVERT_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1 + +SDV_X509_CERT_SETANDGEN_TC001: v1 cert: rsa_p1_v1.crt.der +SDV_X509_CERT_SETANDGEN_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p1_v1.crt.der":"../testdata/cert/asn1/rsa_cert/rsa_p1.key.der":CRYPT_PRIKEY_RSA:CRYPT_PKEY_RSA:CRYPT_PKEY_EMSA_PKCSV15:CRYPT_MD_SHA256:0:0 + +SDV_X509_CERT_SETANDGEN_TC001: v3 cert: rsa_p8.crt.der +SDV_X509_CERT_SETANDGEN_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":"../testdata/cert/asn1/rsa_cert/rsa_p8.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_RSA:CRYPT_PKEY_EMSA_PKCSV15:CRYPT_MD_SHA256:0:0 + +SDV_X509_CERT_SETANDGEN_TC001: v3 cert: sm2.crt.der +SDV_X509_CERT_SETANDGEN_TC001:"../testdata/cert/asn1/sm2_cert/sm2.crt.der":"../testdata/cert/asn1/sm2_cert/sm2.key.der":CRYPT_PRIKEY_ECC:CRYPT_PKEY_SM2:0:CRYPT_MD_SM3:0:0 + +SDV_X509_CERT_SETANDGEN_TC001: v3 cert: ecdsa_sha384.crt.der +SDV_X509_CERT_SETANDGEN_TC001:"../testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.crt.der":"../testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_ECDSA:0:CRYPT_MD_SHA384:0:0 + +SDV_X509_CERT_SETANDGEN_TC001: v3 cert:rsa_pss.crt.der +SDV_X509_CERT_SETANDGEN_TC001:"../testdata/cert/asn1/rsa_pss_cert/rsa_pss.crt.der":"../testdata/cert/asn1/rsa_pss_cert/rsa_pss.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_RSA:CRYPT_PKEY_EMSA_PSS:CRYPT_MD_SHA256:CRYPT_MD_SHA256:20 + +SDV_X509_GEN_CERT_ERROR_TC001: sm2 hash id error +SDV_X509_GEN_CERT_ERROR_TC001:"../testdata/cert/asn1/sm2_cert/sm2.crt.der":"../testdata/cert/asn1/sm2_cert/sm2.key.der":CRYPT_PRIKEY_ECC:CRYPT_MD_SHA256:HITLS_X509_ERR_ENCODE_SIGNID + +SDV_X509_GEN_CERT_ERROR_TC001: ecdsa hash id error +SDV_X509_GEN_CERT_ERROR_TC001:"../testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.crt.der":"../testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SM3:HITLS_X509_ERR_ENCODE_SIGNID + +SDV_X509_GEN_CERT_ERROR_TC001: ecdsa hash id error +SDV_X509_GEN_CERT_ERROR_TC001:"../testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.crt.der":"../testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_MD5:HITLS_X509_ERR_ENCODE_SIGNID + +SDV_X509_GEN_CERT_ERROR_TC002 +SDV_X509_GEN_CERT_ERROR_TC002:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":"../testdata/cert/asn1/rsa_cert/rsa_p8.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_MD_SHA256:"new_rsa.crt" + +SDV_X509_GEN_CERT_ERROR_TC003: set after parse failed +SDV_X509_GEN_CERT_ERROR_TC003:"../testdata/cert/asn1/sm2_cert/sm2.crt.der" + +SDV_X509_CERT_DIGEST_FUNC_TC001: sha1 +SDV_X509_CERT_DIGEST_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1:CRYPT_MD_SHA1:"A98EDED0EE8173B3CEB983FEBD2FCD4158D9D6FD" + +SDV_X509_CERT_DIGEST_FUNC_TC001: sha256 +SDV_X509_CERT_DIGEST_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1:CRYPT_MD_SHA256:"4533C2B45B33E4F246AA64C20328DF0ABD4D71BBABC8BE9E609868CF36B8C3FE" + +SDV_X509_CERT_DIGEST_FUNC_TC001: sha512 +SDV_X509_CERT_DIGEST_FUNC_TC001:"../testdata/cert/asn1/rsa_cert/rsa_p8.crt.der":BSL_FORMAT_ASN1:CRYPT_MD_SHA512:"98CD07137D0CF5E0977E8BE439C0D1AE723C33483C46DA2F376DD518847B61994CBD52EAD2CE270573CB49076B412B802355CCE6A7CE6F3726E42C8AB285A3CB" + +SDV_X509_CERT_SET_CSR_EXT_FUNC_TC001: csr without cert ext +SDV_X509_CERT_SET_CSR_EXT_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/csr.pem":HITLS_X509_ERR_ATTR_NOT_FOUND:"" + +SDV_X509_CERT_SET_CSR_EXT_FUNC_TC001: csr with cert ext +SDV_X509_CERT_SET_CSR_EXT_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.csr.der":HITLS_X509_SUCCESS:"306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388" diff --git a/testcode/sdv/testcase/x509/cms/test_suite_sdv_cms.c b/testcode/sdv/testcase/x509/cms/test_suite_sdv_cms.c new file mode 100644 index 00000000..461ef695 --- /dev/null +++ b/testcode/sdv/testcase/x509/cms/test_suite_sdv_cms.c @@ -0,0 +1,240 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_sal.h" +#include "securec.h" +#include "bsl_type.h" +#include "bsl_log.h" +#include "sal_file.h" +#include "bsl_init.h" +#include "crypt_encode.h" +#include "crypt_eal_encode.h" +#include "crypt_eal_rand.h" +#include "crypt_errno.h" +#include "hitls_cms_local.h" +#include "hitls_x509_errno.h" + +/* END_HEADER */ + +/** + * For test parse p7-encryptData of wrong conditions. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC001(Hex *buff) +{ + BSL_Buffer output = {0}; + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + + int32_t ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + BSL_SAL_Free(output.data); + output.data = NULL; + + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData(NULL, (const uint8_t *)pwd, pwdlen, &output); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, NULL, pwdlen, &output); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd, 8192, &output); + ASSERT_EQ(ret, CRYPT_INVALID_ARG); + + char *pwd1 = "123456@123"; + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd1, strlen(pwd1), &output); + ASSERT_EQ(ret, CRYPT_EAL_CIPHER_DATA_ERROR); + + char *pwd2 = ""; + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd2, strlen(pwd2), &output); + ASSERT_EQ(ret, CRYPT_EAL_CIPHER_DATA_ERROR); + + (void)memset_s(buff->x + buff->len - 20, 16, 0, 16); // modify the ciphertext, 16 and 20 are random number. + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, &output); + ASSERT_EQ(ret, CRYPT_EAL_CIPHER_DATA_ERROR); +exit: + return; +} +/* END_CASE */ + +/** + * For test parse p7-encryptData of right conditions. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC002(Hex *buff) +{ + BSL_Buffer output = {0}; + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + int32_t ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); +exit: + BSL_SAL_Free(output.data); + return; +} +/* END_CASE */ + +/** + * For test parse p7-DigestInfo of wrong conditions. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_PARSE_DIGESTINFO_TC001(Hex *buff, int alg, Hex *digest) +{ + BSL_Buffer output = {0}; + BslCid cid = BSL_CID_UNKNOWN; + int32_t ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo(NULL, &cid, &output); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo((BSL_Buffer *)buff, &cid, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + + ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo((BSL_Buffer *)buff, &cid, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ASSERT_EQ(alg, cid); + ASSERT_EQ(memcmp(output.data, digest->x, digest->len), 0); +exit: + BSL_SAL_Free(output.data); + return; +} +/* END_CASE */ + +/** + * For test parse p7-DigestInfo of right conditions. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_PARSE_DIGESTINFO_TC002(Hex *buff, int alg, Hex *digest) +{ + BSL_Buffer output = {0}; + BslCid cid = BSL_CID_UNKNOWN; + int32_t ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo((BSL_Buffer *)buff, &cid, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(alg, cid); + ASSERT_EQ(memcmp(output.data, digest->x, digest->len), 0); +exit: + BSL_SAL_Free(output.data); + return; +} +/* END_CASE */ + +/** + * For test encode p7-encryptData. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_ENCODE_ENCRYPTEDDATA_TC001(Hex *buff) +{ + BSL_Buffer data = {buff->x, buff->len}; + BSL_Buffer output = {0}; + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + CRYPT_Pbkdf2Param param = {0}; + param.pbesId = BSL_CID_PBES2; + param.pbkdfId = BSL_CID_PBKDF2; + param.hmacId = CRYPT_MAC_HMAC_SHA256; + param.symId = CRYPT_CIPHER_AES256_CBC; + param.pwd = (uint8_t *)pwd; + param.saltLen = 16; + param.pwdLen = pwdlen; + param.itCnt = 2048; + CRYPT_EncodeParam paramEx = {CRYPT_DERIVE_PBKDF2, ¶m}; + + ASSERT_EQ(CRYPT_EAL_RandInit(CRYPT_RAND_SHA256, NULL, NULL, NULL, 0), CRYPT_SUCCESS); + int32_t ret = CRYPT_EAL_EncodePKCS7EncryptDataBuff(NULL, NULL, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + ret = CRYPT_EAL_EncodePKCS7EncryptDataBuff(&data, NULL, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + ret = CRYPT_EAL_EncodePKCS7EncryptDataBuff(&data, ¶mEx, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + + param.hmacId = CRYPT_MAC_MAX; + ret = CRYPT_EAL_EncodePKCS7EncryptDataBuff(&data, ¶mEx, &output); + ASSERT_EQ(ret, CRYPT_ERR_ALGID); + param.hmacId = CRYPT_MAC_HMAC_SHA256; + BSL_Buffer verify = {0}; + ret = CRYPT_EAL_EncodePKCS7EncryptDataBuff(&data, ¶mEx, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ret = CRYPT_EAL_ParseAsn1PKCS7EncryptedData(&output, (const uint8_t *)pwd, pwdlen, &verify); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_COMPARE("encode p7-encryptData", data.data, data.dataLen, verify.data, verify.dataLen); +exit: + CRYPT_EAL_RandDeinit(); + BSL_SAL_FREE(verify.data); + BSL_SAL_FREE(output.data); + return; +} +/* END_CASE */ + +/** + * For test encode p7-DigestInfo. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_ENCODE_DIGESTINFO_TC001() +{ + BSL_Buffer input = {0}; + BSL_Buffer output = {0}; + BslCid cid = 0; + BSL_Buffer digest = {0}; + int32_t ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(BSL_CID_MD5, NULL, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(BSL_CID_MD5, &input, NULL); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + input.dataLen = 1; + ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(BSL_CID_MD5, &input, &output); + ASSERT_EQ(ret, CRYPT_NULL_INPUT); + input.dataLen = 0; + ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(BSL_CID_MD5, &input, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo(&output, &cid, &digest); + ASSERT_EQ(ret, HITLS_CMS_ERR_INVALID_DATA); + BSL_SAL_FREE(output.data); + input.data = (uint8_t *)"123456"; + input.dataLen = 6; + ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(BSL_CID_MD5, &input, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo(&output, &cid, &digest); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(cid, BSL_CID_MD5); +exit: + BSL_SAL_FREE(digest.data); + BSL_SAL_FREE(output.data); + return; +} +/* END_CASE */ + +/** + * For test encode p7-DigestInfo vector. +*/ +/* BEGIN_CASE */ +void SDV_PKCS7_ENCODE_DIGESTINFO_TC002(int algid, Hex *in) +{ + BSL_Buffer input = {in->x, in->len}; + BSL_Buffer output = {0}; + BslCid cid = 0; + BSL_Buffer digest = {0}; + int32_t ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(algid, &input, &output); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo(&output, &cid, &digest); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(cid, algid); +exit: + BSL_SAL_FREE(digest.data); + BSL_SAL_FREE(output.data); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/x509/cms/test_suite_sdv_cms.data b/testcode/sdv/testcase/x509/cms/test_suite_sdv_cms.data new file mode 100644 index 00000000..61de4e9a --- /dev/null +++ b/testcode/sdv/testcase/x509/cms/test_suite_sdv_cms.data @@ -0,0 +1,71 @@ +SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC001 01 +SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC001:"308205E7020100308205E006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410820826A0235C836F040BBA289DF21A3502020800300C06082A864886F70D02090500301D060960864801650304012A04100A1FE81088856FDF5FEDFB8CD85054C180820570029ED0216E4F346E0DBEEB80845D447A7A48C369F3C54D31A99178ED402E3E80BB65E0A4EB36B2EAA03248B7EDBEAB91863C319E0CBA0539C82365FA961222FE8C6B5D02CC41A94360D0B7EDCB640409B29E778FE5E0F89C29699B52AAA61EA68139114F024AE260EFB625A2F8316E73DB6AE60A7AEDC507033115ECDEC2C5B73978FD3647CCECB5E2CC50D728D5D5D79AFBC705DFE727D340D313EB73854518D48E86F71D3F919FCD051FC4C54404CEBA94739030B4BB9063000B7A83E5E67D4979C49BE92EEA4364D68591DDD1FD67DA7739C3EE631E33140DDC49E92487C8ED5FAF7F9F22C9C88DE1D1F46B9FDC60A580D872DB1B38211A64CA6396EF9093182D36903791726908A8A42FC480EA84E93253AF4FCF3BA2AC8E7D93684BB3BCDDA42AB93331F53FCE3C283F2BFA8A2B2C0E2F45B4B75AF653D54B79198CEC23FA6EED3902956031EB92188AF2D29170C0287A7793429C14377DA5D410A28847353FDDBBDBC265A11542FA0D1254FE2BBBC288587E70D1173BFBC41BD0ECCF50826965BA1E869CFF833728FFFECA13287D0BF84B080C4D830D842223A76DDE972C63341BCDF0347D6E511BC9DE97C8D890F921950124F23E695A5808AF2C3F593FF2589341DA2BC95CD912F746074CFD63F77EABE4D621F5EB784C9CF1CF86034E8F313E5A5B6CB3DC0239E5E2CFA0A204168298C24933D0620A38DA10B81EFDEB23DA782DE2D602D5311B4CC1E327CF43F59376EA93AE56651BAD5A0118C34330EFD23AF9DD951D03BEF35D6F00B7BCF865AF8BA736F1F272D8CF62D6AB6FC0E1FAA58C84AFED052DDDF32DBD02C32AD796274BB142DEB1143287D45EE89B0078D5640150888DB766BE2433A6459A9A7E59C687D718A14DE4C9D4D3C90BFE7DC9563C33C56DBBD5FA16F3B311BF6D3163E7FD69EF4EF2AD88AEEF2033E8CC423C35C6D9BB9731B71BCD76D701EB497520F304459AE131F688A291197C514E403B2BC5B27E0F56FAB6D3E2E6EB3221F7679EDC882778AFF833244E015E1603D30C1885A0FE52E87E54328AA18BF3DD77D960CE09C0B060E67E492A78D71C36124691363D00D2B25791E7DA651181F7E2013BCE297E8C7AFD06EA668C6FBAC6F3A888A2645A94A437CAB43B20A3F7584EBA5213B445384E2F64431157EF31DAD413F27B197AE970FF448DC4768C094975967480F5B19D2068AAB7C2F3D1F705D1583062678DE18D4532C6FB3133CB07960D4593A490553F4DD8BADA09728FC3207AD06C4A2DE82D77ABE23BB1259148E2AB5B9B6AA94A8ECBAEA244DD5E00C502E9E557E7547D50FD5B31AF8CE50FE25D6DA244AFB1D58E81EEC4CAD2B003A951D1141A1F1FD0BAD39B302158AB9B7501A615A2BA8154CBA06354AD3F1109FD814294766D2CA8DF4A5AE2F1D279ABCED6F974A6DADAD089D59D1864F2565BD7FDFCDA53ABCD7C92B9FDBFCDD72BC50F999EDF21708FD42FA06751F266AC64D0242D6995FF8BF072F6AF94CA6571714CA3DA6963139EB0732BD5DCFB3D4E630C61A49C7C495B68F1893F8C293B3BA2FDC97EBCDAB1FB06876CD842A971CD07BB09C18CF1C3E929872121BFACA9AF8D7284668B1A670D31A605D2C66E0C6B9C5A78C4DF81B84DE7CD0A1EB51F4F756262AE76DF2A12F57AE8AF9DC779CE5FD443F450215CB7595D1A0F0A3C81AD3009D6A118577AB2E904D0C458DF0E434617C710130BF4E5663C185721C5E5B6B23F18AC9A52F3D3A0EA47F70E894E5A4385E27AF6499C2A19441F474AD6155D8059764A2807DF0629B584CB1EA2E001B125A409A37227CF19BFEC6C9F5906CD7D1AB876ABD3D218E864E35922A9B73AE64569A07A4C5A6F3809ABB32F612DD20D2322522838D12D642CA9574A305B9CE3115737E1DEE46C53FCB840E5716FE492C45A5AC2CBDD52EB659BEA48CD3998AE91FF743F135D51C80351A80639F14493F168F8" + +SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC002 01 +SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC002:"308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404107ADE28DE60883CF3A1B12661D26ACD6602020800300C06082A864886F70D02090500301D060960864801650304012A041041980DBF42C62C55FE2275EE8B98666C808202104502DC74FAD09DC7C03A3EDDD5A9F257CB3496E05DAD27E1BE1148F2B6C94C300DDED464D02BD404FC4CC205705CF8015B5FD5633E868C505B8926BD05A06AE346E57D9BC8578EF39A5272ECB8C51D9ECEC895CAFE7BE90BCF9FBEB3B74F0044C3FED90B9DE1ACE42623A7D2598E6D4E96266516F50237B80164662E8F231F41E30B117D6C237672DB80486422F95B0FC0EB4B31BE7EC05B1244904A0DA144A1F2F7EAB4BDE34E7A1F47D4C3E50584AA22AFB8D1CBEF97BC783377E3249354961FB51CF990BB7A9AC09234BB4C6981FF0FBD6042B2938BE71182DECED149F748F8D90C082E178DD95FA1F4FEF6D4C8CE8C050C08279B240414BB55DD622B4944A22333D7DDA0AFCEB3DBB2DAC43D0CD26657A5613E93C9F1D041DBC867300F0B5249BAB3A629AAD99100790AC12FC6AE09B8A01B9162E22F1E208F6D93B4BCBCECD728686C9CD43B7D004CC6540E917309B1C45FD02616A75F54CBD8044B83C2806C68F0197C6BACAE72A8390C3CC9706943A2C9E7D5940A7039FE315D5600E67125B08F27A851CB24B22C9CE25C14F9F3795E7CBA518DC8756DE501980E86FCA024E5FAF04B24BC36F5339B9D61F7E92BEA90ADFA6042169D611121F84BEF7E173E79B21A03124A321507676A500EC0BFCB1CD2B2A08E63CF99283AC1AD07226CD406531A45454FB4B92B9FC7FA1B4A2BA3EC0B9757330FA42F3BBFF91E4EEF33B8C3F10670BAA26701B6629F6402F1" + +SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC002 02 +SDV_PKCS7_PARSE_ENCRYPTEDDATA_TC002:"308203170201003082031006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404101286B6418ACDA7E5684364FB8D06CBBC02020800300C06082A864886F70D02090500301D060960864801650304012A041093C440624F2A5D311AC4CC2F165C32D9808202A00EE13056A7AA9D0D4683C6B718E55828886D3DE891D31735C531C573965656981BF899449C9D2B8FA80E39AD2D382C1FCB96495A5B425A59CFE920C7D32AD5DA1048098AFDB55DF05A4DA3025E433245B159F20BCA17A1A369325484AD540BF22C0355E8FB133CDA68AE5D5078F391226B017BB809AD6BA60DFD374952D58D82D1D21E2081A320F985509B29ADC50B574A4E29B8E8186B09515465225017BAB9EAB07731DD08673C9DF6BC6F47E2EF0A00B775F28977141F8A3203826E6DCFE30DDC5DBCCFFB2874F705169A8B28E5A7E663259FC357FAC37146516C9F35AC6A781261A1EEFB1505FE0AA0A0A5B6E1504D6A1746085E02BC99FEC7A6BEA18B3D70084099E49798C7F23A9028B00AE43FEF653D87132D0C1AB454837C34EC26270884F6371AB4F7A0B365F19D43F218E2143921C625F9B38F457D31C5E39AAA549F3F7C264B5547DA1F303CD9F3FF3E98EB6AB075C35490EA790CA4CCE9A916A481C085A12668D42E04F88BAEE439EE92ADABE3AAB5B16C550ADDDD97C4381E9C2FC6D1B80F3F1196EA7F31A5BB570E747FFE650FEECE1DA7088A867885BCDA8D134150E081455D34EBA1EBBC775BAF3D45BA7103C15A39B3972B37948F2795EEB5C4F33AB25DBA2D76AC84FAD70109E01122C7C5870D4A86F92066792FE358C8E425D3E530D4A1F7B7AD0231D7BD6AAD1CA82D26DE08F3FFCF62A4C972B18BF34114DFFD62DD2AD6FE8BA8B324EDE9D8CF39244A0658A4BB84C8A0876C870C4CF212C9931B430215254F84135E4363E31DA592D6043573073C0E4BA6A8113B65DC4220E26CD00A534C21C90945DF6AD68E1EB00F62540311A428C05EE5F8C709DC49A7819E35A7193B29DA4F18DDA4E7431CF2CA67240C9758A670A71263019CBB0763A5FA61C01F77591A24E2AACCDC695FF50CCAE0086ECB6D42B465682D1D" + +SDV_PKCS7_PARSE_DIGESTINFO_TC001 01 +SDV_PKCS7_PARSE_DIGESTINFO_TC001:"300D0609608648016503040201050004208D52845055818845BD01283804B5458EDD8E1BC76122D80EAB13FE789EF343A1":BSL_CID_SHA256:"8d52845055818845bd01283804b5458edd8e1bc76122d80eab13fe789ef343a1" + +SDV_PKCS7_PARSE_DIGESTINFO_TC002 01 +SDV_PKCS7_PARSE_DIGESTINFO_TC002:"300D0609608648016503040201050004208F94A4088463B8A284BD19F8EDA65D14541C9656F61309C4F3DD6F7C1D12A56B":BSL_CID_SHA256:"8f94a4088463b8a284bd19f8eda65d14541c9656f61309c4f3dd6f7c1d12a56b" + +SDV_PKCS7_PARSE_DIGESTINFO_TC002 02 +SDV_PKCS7_PARSE_DIGESTINFO_TC002:"300D0609608648016503040201050004202A24071EE7DFC491A3CA074557363BC0A94467FF0E5AC118B8365453DE771CDE":BSL_CID_SHA256:"2a24071ee7dfc491a3ca074557363bc0a94467ff0e5ac118b8365453de771cde" + +SDV_PKCS7_ENCODE_DIGESTINFO_TC001 +SDV_PKCS7_ENCODE_DIGESTINFO_TC001: + +SDV_PKCS7_ENCODE_ENCRYPTEDDATA_TC001 +SDV_PKCS7_ENCODE_ENCRYPTEDDATA_TC001:"123456" + +MD SHA224 NIST Vector Zero Len Msg +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA224:"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" + +MD SHA224 NIST Vector #1 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA224:"3cd36921df5d6963e73739cf4d20211e2d8877c19cff087ade9d0e3a" + +MD SHA224 NIST Vector #2 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA224:"d7e6634723ac25cb1879bdb1508da05313530419013fe255967a39e1" + +MD SHA224 NIST Vector #3 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA224:"452bf2e5ebfc4e451cc434bc09e2a10032eed0b7627cf55e7e5ed0e2" + +MD SHA256 NIST Vector Zero Len Msg +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA256:"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + +MD SHA256 NIST Vector #1 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA256:"28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1" + +MD SHA256 NIST Vector #2 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA256:"d5c30315f72ed05fe519a1bf75ab5fd0ffec5ac1acb0daf66b6b769598594509" + +MD SHA256 NIST Vector #3 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA256:"99dc772e91ea02d9e421d552d61901016b9fd4ad2df4a8212c1ec5ba13893ab2" + +MD SHA384 NIST Vector Zero Len Msg +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA384:"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" + +MD SHA384 NIST Vector #1 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA384:"b52b72da75d0666379e20f9b4a79c33a329a01f06a2fb7865c9062a28c1de860ba432edfd86b4cb1cb8a75b46076e3b1" + +MD SHA384 NIST Vector #2 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA384:"85227ae057f2082adf178cae996449100b6a3119e4c415a99e25be6ef20ba8c0eae818d60f71c5c83ff2d4c59aa75263" + +MD SHA384 NIST Vector #3 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA384:"80afe111e44ad9aff9e39c4cf9e6b4c520072b4550e62b1740160a04f8d530612dc098917a556b44977d0e73df518bee" + +MD SHA512 NIST Vector Zero Len Msg +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA512:"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + +MD SHA512 NIST Vector #1 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA512:"3831a6a6155e509dee59a7f451eb35324d8f8f2df6e3708894740f98fdee23889f4de5adb0c5010dfb555cda77c8ab5dc902094c52de3278f35a75ebc25f093a" + +MD SHA512 NIST Vector #2 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA512:"112e19144a9c51a223a002b977459920e38afd4ca610bd1c532349e9fa7c0d503215c01ad70e1b2ac5133cf2d10c9e8c1a4c9405f291da2dc45f706761c5e8fe" + +MD SHA512 NIST Vector #3 +SDV_PKCS7_ENCODE_DIGESTINFO_TC002:CRYPT_MD_SHA512:"b10bb04491b9c0c334709b407cda1d503efb6b63ee944f2d366b6855e6e63e5b80115be4be7ff63edecdfb5923792e68123976d79212b3884dec2179d1fcf382" diff --git a/testcode/sdv/testcase/x509/common/test_suite_sdv_common.c b/testcode/sdv/testcase/x509/common/test_suite_sdv_common.c new file mode 100644 index 00000000..5bf3cbd3 --- /dev/null +++ b/testcode/sdv/testcase/x509/common/test_suite_sdv_common.c @@ -0,0 +1,1024 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +#include "bsl_sal.h" +#include "securec.h" +#include "hitls_error.h" +#include "hitls_x509.h" +#include "hitls_x509_errno.h" +#include "hitls_x509_verify.h" +#include "bsl_type.h" +#include "bsl_log.h" +#include "hitls_cert_local.h" +#include "hitls_crl_local.h" +#include "bsl_init.h" +#include "bsl_obj_internal.h" +#include "crypt_errno.h" +#include "crypt_eal_encode.h" +#include "hitls_x509_local.h" + +/* END_HEADER */ + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para1, para2, para3, para4); + printf("\n"); +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para); + printf("\n"); +} + +static void FreeListData(void *data) +{ + (void)data; + return; +} + +static void FreeSanListData(void *data) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_GeneralName *name = (HITLS_X509_GeneralName *)data; + if (name->type == HITLS_X509_GN_DNNAME) { + BSL_LIST_DeleteAll((BslList *)name->value.data, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + BSL_SAL_Free(name->value.data); + } +} + +/* BEGIN_CASE */ +void SDV_HITLS_X509_FreeStoreCtx_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + HITLS_X509_StoreCtxFree(NULL); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_CtrlStoreCtx_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_StoreCtxCtrl(NULL, 0, NULL, 0), HITLS_INVALID_INPUT); + HITLS_X509_StoreCtx storeCtx = {0}; + ASSERT_EQ(HITLS_X509_StoreCtxCtrl(&storeCtx, 0, NULL, 0), HITLS_INVALID_INPUT); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_VerifyCert_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CertVerify(NULL, NULL), HITLS_INVALID_INPUT); + HITLS_X509_StoreCtx storeCtx = {0}; + ASSERT_EQ(HITLS_X509_CertVerify(&storeCtx, NULL), HITLS_INVALID_INPUT); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_BuildCertChain_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CertChainBuild(NULL, NULL, NULL), HITLS_INVALID_INPUT); + HITLS_X509_StoreCtx storeCtx = {0}; + ASSERT_EQ(HITLS_X509_CertChainBuild(&storeCtx, NULL, NULL), HITLS_INVALID_INPUT); + HITLS_X509_Cert cert = {0}; + ASSERT_EQ(HITLS_X509_CertChainBuild(&storeCtx, &cert, NULL), HITLS_INVALID_INPUT); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_FreeCert_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + HITLS_X509_CertFree(NULL); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_ParseBuffCert_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + HITLS_X509_Cert *cert = NULL; + uint8_t buffData[10] = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CertParseBuff(0, NULL, NULL), HITLS_X509_ERR_INVALID_PARAM); + BSL_Buffer buff = {0}; + ASSERT_EQ(HITLS_X509_CertParseBuff(0, &buff, NULL), HITLS_X509_ERR_INVALID_PARAM); + buff.data = buffData; + ASSERT_EQ(HITLS_X509_CertParseBuff(0, &buff, NULL), HITLS_X509_ERR_INVALID_PARAM); + buff.dataLen = 1; + ASSERT_EQ(HITLS_X509_CertParseBuff(0, &buff, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertParseBuff(0xff, &buff, &cert), HITLS_X509_ERR_NOT_SUPPORT_FORMAT); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_ParseFileCert_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, NULL, NULL), BSL_NULL_INPUT); + ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/asn1/nist384ca.crt", NULL), + HITLS_X509_ERR_INVALID_PARAM); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_CtrlCert_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CertCtrl(NULL, 0xff, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + HITLS_X509_Cert cert = {0}; + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, 0xff, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_ENCODELEN, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_ENCODELEN, &cert, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_ENCODE, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_PUBKEY, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_PUBKEY, &cert, 0), CRYPT_NULL_INPUT); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_SIGNALG, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_SIGNALG, &cert, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_REF_UP, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_REF_UP, &cert, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_EXT_KU_DIGITALSIGN, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_EXT_KU_DIGITALSIGN, &cert, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_EXT_KU_CERTSIGN, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_EXT_KU_CERTSIGN, &cert, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_EXT_KU_KEYAGREEMENT, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_EXT_KU_KEYAGREEMENT, &cert, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_SUBJECT_DNNAME_STR, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_ISSUER_DNNAME_STR, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_SERIALNUM, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_BEFORE_TIME, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertCtrl(&cert, HITLS_X509_GET_AFTER_TIME, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_DupCert_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + HITLS_X509_Cert src = {0}; + HITLS_X509_Cert *dest = NULL; + ASSERT_EQ(HITLS_X509_CertDup(NULL, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertDup(&src, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CertDup(&src, &dest), HITLS_X509_ERR_INVALID_PARAM); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_FreeCrl_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + HITLS_X509_CrlFree(NULL); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_CtrlCrl_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CrlCtrl(NULL, 0xff, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + HITLS_X509_Crl crl = {0}; + ASSERT_EQ(HITLS_X509_CrlCtrl(&crl, 0xff, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CrlCtrl(&crl, HITLS_X509_CRL_REF_UP, NULL, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CrlCtrl(&crl, HITLS_X509_CRL_REF_UP, &crl, 0), HITLS_X509_ERR_INVALID_PARAM); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_HITLS_X509_ParseBuffCrl_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + HITLS_X509_Crl *crl = NULL; + uint8_t buffData[10] = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CrlParseBuff(0, NULL, NULL), HITLS_X509_ERR_INVALID_PARAM); + BSL_Buffer buff = {0}; + ASSERT_EQ(HITLS_X509_CrlParseBuff(0, &buff, NULL), HITLS_X509_ERR_INVALID_PARAM); + buff.data = buffData; + ASSERT_EQ(HITLS_X509_CrlParseBuff(0, &buff, NULL), HITLS_X509_ERR_INVALID_PARAM); + buff.dataLen = 1; + ASSERT_EQ(HITLS_X509_CrlParseBuff(0, &buff, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CrlParseBuff(0xff, &buff, &crl), HITLS_X509_ERR_NOT_SUPPORT_FORMAT); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ // todo +void SDV_HITLS_X509_ParseFileCrl_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(HITLS_X509_CrlParseFile(BSL_FORMAT_ASN1, NULL, NULL), BSL_NULL_INPUT); + ASSERT_EQ(HITLS_X509_CrlParseFile(BSL_FORMAT_ASN1, "../testdata/cert/asn1/ca-1-rsa-sha256-v2.der", + NULL), HITLS_X509_ERR_INVALID_PARAM); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_ParseBuffPubKey_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + BSL_Buffer buff = {0}; + CRYPT_EAL_PkeyCtx *pkey = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, 0xff, &buff, NULL, 0, &pkey), CRYPT_DECODE_NO_SUPPORT_TYPE); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PUBKEY_SUBKEY, NULL, NULL, 0, &pkey), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PUBKEY_RSA, NULL, NULL, 0, &pkey), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PUBKEY_SUBKEY, &buff, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PUBKEY_RSA, &buff, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PUBKEY_SUBKEY, &buff, NULL, 0, &pkey), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PUBKEY_RSA, &buff, NULL, 0, &pkey), CRYPT_INVALID_ARG); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_ParseFilePubKey_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(0xff, 0, NULL, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY, NULL, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY, + "../testdata/cert/asn1/prime256v1pub.der", NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PUBKEY_RSA, NULL, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PUBKEY_RSA, + "../testdata/cert/asn1/rsa2048pub_pkcs1.der", NULL, 0, NULL), CRYPT_INVALID_ARG); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_ParseBuffPriKey_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + BSL_Buffer buff = {0}; + uint8_t pwd = 0; + CRYPT_EAL_PkeyCtx *key = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, 0xff, &buff, &pwd, 0, &key), CRYPT_DECODE_NO_SUPPORT_TYPE); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_ECC, NULL, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_RSA, NULL, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_UNENCRYPT, NULL, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_ENCRYPT, NULL, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_ECC, &buff, NULL, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_RSA, &buff, NULL, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_UNENCRYPT, &buff, NULL, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_ENCRYPT, &buff, NULL, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_ECC, &buff, &pwd, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_RSA, &buff, &pwd, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_UNENCRYPT, &buff, &pwd, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_ENCRYPT, &buff, &pwd, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_ECC, &buff, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_RSA, &buff, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_UNENCRYPT, &buff, &pwd, 0, &key), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeBuffKey(0, CRYPT_PRIKEY_PKCS8_ENCRYPT, &buff, &pwd, 0, &key), CRYPT_INVALID_ARG); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_ParseFilePriKey_TC001(void) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(0xff, 0, NULL, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_ECC, NULL, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_ECC, + "../testdata/cert/asn1/prime256v1.der", NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_RSA, NULL, NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_RSA, + "../testdata/cert/asn1/rsa2048key_pkcs1.der", NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_UNENCRYPT, NULL, NULL, 0, + NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_UNENCRYPT, + "../testdata/cert/asn1/prime256v1_pkcs8.der", NULL, 0, NULL), CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_ENCRYPT, NULL, NULL, 0, NULL), + CRYPT_INVALID_ARG); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_ENCRYPT, + "../testdata/cert/asn1/prime256v1_pkcs8_enc.der", NULL, 0, NULL), CRYPT_INVALID_ARG); +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001(int format, int type, char *path) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + CRYPT_EAL_PkeyCtx *key = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(format, type, path, NULL, 0, &key), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(key); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001(int format, int type, char *path) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + CRYPT_EAL_PkeyCtx *key = NULL; + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(format, type, path, NULL, 0, &key), CRYPT_SUCCESS); +exit: + CRYPT_EAL_PkeyFreeCtx(key); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EncodeNameList_TC001(int format, char *certPath, Hex *expect) +{ + HITLS_X509_Cert *cert = NULL; + BSL_ASN1_Buffer name = {0}; + + TestMemInit(); + BSL_GLOBAL_Init(); + ASSERT_EQ(HITLS_X509_CertParseFile(format, certPath, &cert), 0); + ASSERT_EQ(HITLS_X509_EncodeNameList(cert->tbs.issuerName, &name), 0); + + ASSERT_COMPARE("Encode names", name.buff, name.len, expect->x, expect->len); + +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(name.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_SetBCons_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + HITLS_X509_Ext *ext = &cert->tbs.ext; + ASSERT_EQ(ext->extFlags, 0); + ASSERT_EQ(ext->isCa, false); + ASSERT_EQ(ext->maxPathLen, -1); + + HITLS_X509_ExtBCons bCons = {true, true, 1}; + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_BCONS, &bCons, 0), HITLS_X509_ERR_INVALID_PARAM); + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_BCONS, &bCons, sizeof(HITLS_X509_ExtBCons)), 0); + ASSERT_EQ(BSL_LIST_COUNT(ext->list), 1); + ASSERT_NE(ext->extFlags & HITLS_X509_EXT_FLAG_BCONS, 0); + ASSERT_EQ(ext->isCa, true); + ASSERT_EQ(ext->maxPathLen, 1); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_SetAkiSki_TC001(Hex *kid) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + HITLS_X509_Ext *ext = &cert->tbs.ext; + HITLS_X509_ExtAki aki = {true, {kid->x, kid->len}, NULL, {0}}; + HITLS_X509_ExtSki ski = {true, {kid->x, kid->len}}; + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SKI, &ski, 0), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_AKI, &aki, 0), HITLS_X509_ERR_INVALID_PARAM); + + aki.kid.dataLen = 0; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_AKI, &aki, sizeof(HITLS_X509_ExtAki)), HITLS_X509_ERR_EXT_KID); + aki.kid.dataLen = kid->len; + + ski.kid.dataLen = 0; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SKI, &ski, sizeof(HITLS_X509_ExtSki)), HITLS_X509_ERR_EXT_KID); + ski.kid.dataLen = kid->len; + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_AKI, &aki, sizeof(HITLS_X509_ExtAki)), 0); + ASSERT_EQ(BSL_LIST_COUNT(ext->list), 1); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SKI, &ski, sizeof(HITLS_X509_ExtSki)), 0); + ASSERT_NE(ext->extFlags & HITLS_X509_EXT_FLAG_SET, 0); + ASSERT_EQ(BSL_LIST_COUNT(ext->list), 1 + 1); +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_SetKeyUsage_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + HITLS_X509_Ext *ext = &cert->tbs.ext; + ASSERT_EQ(ext->keyUsage, 0); + + HITLS_X509_ExtKeyUsage ku = {true, 0}; + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_KUSAGE, &ku, 0), HITLS_X509_ERR_INVALID_PARAM); + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), + HITLS_X509_ERR_EXT_KU); + + ku.keyUsage = HITLS_X509_EXT_KU_DIGITAL_SIGN | HITLS_X509_EXT_KU_NON_REPUDIATION | + HITLS_X509_EXT_KU_KEY_ENCIPHERMENT | HITLS_X509_EXT_KU_DATA_ENCIPHERMENT | HITLS_X509_EXT_KU_KEY_AGREEMENT | + HITLS_X509_EXT_KU_KEY_CERT_SIGN | HITLS_X509_EXT_KU_CRL_SIGN | HITLS_X509_EXT_KU_ENCIPHER_ONLY | + HITLS_X509_EXT_KU_DECIPHER_ONLY; + ku.keyUsage = ~ku.keyUsage; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), + HITLS_X509_ERR_EXT_KU); + + ku.keyUsage = ~ku.keyUsage; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), 0); + ASSERT_EQ(BSL_LIST_COUNT(ext->list), 1); + ASSERT_NE(ext->extFlags & HITLS_X509_EXT_FLAG_KUSAGE, 0); + ASSERT_NE(ext->extFlags & HITLS_X509_EXT_FLAG_SET, 0); + +exit: + HITLS_X509_CertFree(cert); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_SetExtendKeyUsage_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + BslList *oidList = BSL_LIST_New(sizeof(BSL_Buffer)); + ASSERT_NE(oidList, NULL); + + HITLS_X509_Ext *ext = &cert->tbs.ext; + HITLS_X509_ExtExKeyUsage exku = {true, NULL}; + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_EXKUSAGE, &exku, 0), HITLS_X509_ERR_INVALID_PARAM); + + // error: list is null + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_EXKUSAGE, &exku, sizeof(HITLS_X509_ExtExKeyUsage)), + HITLS_X509_ERR_EXT_EXTENDED_KU); + // werror: list is empty + exku.oidList = oidList; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_EXKUSAGE, &exku, sizeof(HITLS_X509_ExtExKeyUsage)), + HITLS_X509_ERR_EXT_EXTENDED_KU); + // error: oid is null + BSL_Buffer emptyOid = {0}; + ASSERT_EQ(BSL_LIST_AddElement(oidList, &emptyOid, BSL_LIST_POS_END), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_EXKUSAGE, &exku, sizeof(HITLS_X509_ExtExKeyUsage)), + HITLS_X509_ERR_EXT_EXTENDED_KU_ELE); + BSL_LIST_DeleteAll(oidList, FreeListData); + + // success: normal oid + BslOidString *oid = BSL_OBJ_GetOidFromCID(BSL_CID_CE_SERVERAUTH); + ASSERT_NE(oid, NULL); + BSL_Buffer oidBuff = {(uint8_t *)oid->octs, oid->octetLen}; + ASSERT_EQ(BSL_LIST_AddElement(oidList, &oidBuff, BSL_LIST_POS_END), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_EXKUSAGE, &exku, sizeof(HITLS_X509_ExtExKeyUsage)), 0); + ASSERT_NE(ext->extFlags & HITLS_X509_EXT_FLAG_SET, 0); + +exit: + HITLS_X509_CertFree(cert); + BSL_LIST_FREE(oidList, FreeListData); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_SetSan_TC001(void) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + BslList *list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName)); + ASSERT_NE(list, NULL); + + HITLS_X509_Ext *ext = &cert->tbs.ext; + HITLS_X509_ExtSan san = {true, NULL}; + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SAN, &san, 0), HITLS_X509_ERR_INVALID_PARAM); + + // error: list is null + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SAN, &san, sizeof(HITLS_X509_ExtSan)), HITLS_X509_ERR_EXT_SAN); + // error: list is empty + san.names = list; + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SAN, &san, sizeof(HITLS_X509_ExtSan)), HITLS_X509_ERR_EXT_SAN); + // error: list data content is null + HITLS_X509_GeneralName empty = {0}; + ASSERT_EQ(BSL_LIST_AddElement(list, &empty, BSL_LIST_POS_END), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SAN, &san, sizeof(HITLS_X509_ExtSan)), + HITLS_X509_ERR_EXT_SAN_ELE); + BSL_LIST_DeleteAll(list, FreeListData); + + // error: name type + char *email = "test@a.com"; + HITLS_X509_GeneralName errType = {HITLS_X509_GN_IP + 1, {(uint8_t *)email, (uint32_t)strlen(email)}}; + ASSERT_EQ(BSL_LIST_AddElement(list, &errType, BSL_LIST_POS_END), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SAN, &san, sizeof(HITLS_X509_ExtSan)), + HITLS_X509_ERR_EXT_GN_UNSUPPORT); + BSL_LIST_DeleteAll(list, FreeListData); + // success + HITLS_X509_GeneralName nomal = {HITLS_X509_GN_EMAIL, {(uint8_t *)email, (uint32_t)strlen(email)}}; + ASSERT_EQ(BSL_LIST_AddElement(list, &nomal, BSL_LIST_POS_END), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_SET_SAN, &san, sizeof(HITLS_X509_ExtSan)), 0); + ASSERT_NE(ext->extFlags & HITLS_X509_EXT_FLAG_SET, 0); + +exit: + HITLS_X509_CertFree(cert); + BSL_LIST_FREE(list, FreeListData); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_EncodeBCons_TC001(int critical, int isCa, int maxPathLen, Hex *expect) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + int8_t tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + HITLS_X509_ExtBCons bCons = {critical, isCa, maxPathLen}; + BSL_ASN1_Buffer encode = {0}; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + ASSERT_EQ(HITLS_X509_ExtCtrl(&cert->tbs.ext, HITLS_X509_EXT_SET_BCONS, &bCons, sizeof(HITLS_X509_ExtBCons)), 0); + ASSERT_EQ(HITLS_X509_EncodeExt(tag, cert->tbs.ext.list, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(encode.len, expect->len); + ASSERT_COMPARE("Ext: bCons", encode.buff, encode.len, expect->x, expect->len); +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(encode.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_EncodeExtendKeyUsage_TC001(int critical, Hex *oid1, Hex *oid2, Hex *expect) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + int8_t tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + BSL_ASN1_Buffer encode = {0}; + HITLS_X509_ExtExKeyUsage exku = {critical, NULL}; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + exku.oidList = BSL_LIST_New(sizeof(BSL_Buffer)); + ASSERT_NE(exku.oidList, NULL); + ASSERT_EQ(BSL_LIST_AddElement(exku.oidList, oid1, BSL_LIST_POS_END), 0); + ASSERT_EQ(BSL_LIST_AddElement(exku.oidList, oid2, BSL_LIST_POS_END), 0); + + ASSERT_EQ(HITLS_X509_ExtCtrl(&cert->tbs.ext, HITLS_X509_EXT_SET_EXKUSAGE, &exku, sizeof(HITLS_X509_ExtExKeyUsage)), + 0); + ASSERT_EQ(HITLS_X509_EncodeExt(tag, cert->tbs.ext.list, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(encode.len, expect->len); + ASSERT_COMPARE("Ext: extendKeyUsage", encode.buff, encode.len, expect->x, expect->len); + +exit: + HITLS_X509_CertFree(cert); + BSL_LIST_DeleteAll(exku.oidList, FreeListData); + BSL_SAL_Free(exku.oidList); + BSL_SAL_Free(encode.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_EncodeSan_TC001(int critical, int type1, int type2, int type3, int type4, int dirCid1, + int dirCid2, Hex *value, Hex *expect) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + int8_t tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + BSL_ASN1_Buffer encode = {0}; + HITLS_X509_ExtSan san = {critical, NULL}; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + san.names = BSL_LIST_New(sizeof(BSL_Buffer)); + ASSERT_NE(san.names, NULL); + + // Generate san + BslList *dirNames = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + ASSERT_NE(dirNames, NULL); + HITLS_X509_DN dnName1[1] = {{(BslCid)dirCid1, value->x, value->len}}; + HITLS_X509_DN dnName2[1] = {{(BslCid)dirCid2, value->x, value->len}}; + ASSERT_EQ(HITLS_X509_AddDnName(dirNames, dnName1, 1), 0); + ASSERT_EQ(HITLS_X509_AddDnName(dirNames, dnName2, 1), 0); + HITLS_X509_GeneralName names[] = { + {type1, {value->x, value->len}}, + {type2, {value->x, value->len}}, + {type3, {value->x, value->len}}, + {type4, {value->x, value->len}}, + {HITLS_X509_GN_DNNAME, {(uint8_t *)dirNames, sizeof(BslList *)}}, + }; + for (uint32_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) { + ASSERT_EQ(BSL_LIST_AddElement(san.names, &names[i], BSL_LIST_POS_END), 0); + } + + // set san and encode ext + ASSERT_EQ(HITLS_X509_ExtCtrl(&cert->tbs.ext, HITLS_X509_EXT_SET_SAN, &san, sizeof(HITLS_X509_ExtSan)), 0); + ASSERT_EQ(HITLS_X509_EncodeExt(tag, cert->tbs.ext.list, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(encode.len, expect->len); + ASSERT_COMPARE("Ext: san", encode.buff, encode.len, expect->x, expect->len); + +exit: + HITLS_X509_CertFree(cert); + BSL_LIST_DeleteAll(san.names, FreeSanListData); + BSL_SAL_Free(san.names); + BSL_SAL_Free(encode.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_EncodeKeyUsage_TC001(int critical, int usage, Hex *expect) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + int8_t tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + HITLS_X509_ExtKeyUsage ku = {critical, usage}; + BSL_ASN1_Buffer encode = {0}; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + ASSERT_EQ(HITLS_X509_ExtCtrl(&cert->tbs.ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), 0); + ASSERT_EQ(HITLS_X509_EncodeExt(tag, cert->tbs.ext.list, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(encode.len, expect->len); + ASSERT_COMPARE("Ext: keyUsage", encode.buff, encode.len, expect->x, expect->len); +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(encode.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_EncodeAKiSki_TC001(int critical1, int critical2, Hex *kid1, Hex *kid2, Hex *expect) +{ + TestMemInit(); + BSL_GLOBAL_Init(); + int8_t tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + HITLS_X509_ExtAki aki = {critical1, {kid1->x, kid1->len}, NULL, {0}}; + HITLS_X509_ExtSki ski = {critical2, {kid2->x, kid2->len}}; + BSL_ASN1_Buffer encode = {0}; + + HITLS_X509_Cert *cert = HITLS_X509_CertNew(); + ASSERT_NE(cert, NULL); + + ASSERT_EQ(HITLS_X509_ExtCtrl(&cert->tbs.ext, HITLS_X509_EXT_SET_SKI, &ski, sizeof(HITLS_X509_ExtSki)), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(&cert->tbs.ext, HITLS_X509_EXT_SET_AKI, &aki, sizeof(HITLS_X509_ExtAki)), 0); + ASSERT_EQ(HITLS_X509_EncodeExt(tag, cert->tbs.ext.list, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(encode.len, expect->len); + ASSERT_COMPARE("Ext:aki ski", encode.buff, encode.len, expect->x, expect->len); +exit: + HITLS_X509_CertFree(cert); + BSL_SAL_Free(encode.buff); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +typedef struct { + int32_t type; + Hex *value; +} TestGeneralNameMap; + +/* BEGIN_CASE */ +void SDV_X509_EXT_ParseGeneralNames_TC001(Hex *encode, Hex *ip, Hex *uri, Hex *rfc822, Hex *regId, Hex *dns) +{ + TestGeneralNameMap map[] = { + {HITLS_X509_GN_DNNAME, NULL}, + {HITLS_X509_GN_IP, ip}, + {HITLS_X509_GN_URI, uri}, + {HITLS_X509_GN_OTHER, NULL}, + {HITLS_X509_GN_EMAIL, rfc822}, + {HITLS_X509_GN_RID, regId}, + {HITLS_X509_GN_DNS, dns}, + }; + + TestMemInit(); + BslList *list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName)); + ASSERT_NE(list, NULL); + + ASSERT_EQ(HITLS_X509_ParseGeneralNames(encode->x, encode->len, list), HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(list), sizeof(map) / sizeof(map[0])); + + HITLS_X509_GeneralName *name = NULL; + uint32_t idx = 0; + for (name = BSL_LIST_GET_FIRST(list); name != NULL; name = BSL_LIST_GET_NEXT(list), idx++) { + ASSERT_EQ(name->type, map[idx].type); + if (map[idx].value != NULL) { + ASSERT_COMPARE("gn", name->value.data, name->value.dataLen, map[idx].value->x, map[idx].value->len); + } + } + +exit: + HITLS_X509_ClearGeneralNames(list); + BSL_SAL_Free(list); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_ParseGeneralNames_Error_TC001(Hex *encode, int ret) +{ + BSL_GLOBAL_Init(); + TestMemInit(); + BslList *list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName)); + ASSERT_NE(list, NULL); + + ASSERT_EQ(HITLS_X509_ParseGeneralNames(encode->x, encode->len, list), ret); + +exit: + BSL_SAL_Free(list); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_ParseSki_TC001(Hex *encode, int ret, Hex *kid) +{ + BSL_GLOBAL_Init(); + TestMemInit(); + HITLS_X509_ExtSki ski = {0}; + HITLS_X509_ExtEntry entry = {BSL_CID_CE_SUBJECTKEYID, {0}, true, {0, encode->len, encode->x}}; + + ASSERT_EQ(HITLS_X509_ParseSubjectKeyId(&entry, &ski), ret); + if (ret == 0) { + ASSERT_EQ(ski.critical, entry.critical); + ASSERT_COMPARE("Subject kid", kid->x, kid->len, ski.kid.data, ski.kid.dataLen); + } + +exit: + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_ParseExtendedKu_TC001(Hex *encode, Hex *ku1, Hex *ku2, Hex *ku3) +{ + BSL_GLOBAL_Init(); + TestMemInit(); + + Hex *values[] = {ku1, ku2, ku3}; + uint32_t cnt = sizeof(values) / sizeof(values[0]); + HITLS_X509_ExtExKeyUsage exku = {0}; + HITLS_X509_ExtEntry entry = {BSL_CID_CE_EXTENDEDKEYUSAGE, {0}, true, {0, encode->len, encode->x}}; + + ASSERT_EQ(HITLS_X509_ParseExtendedKeyUsage(&entry, &exku), 0); + ASSERT_EQ(exku.critical, entry.critical); + ASSERT_EQ(BSL_LIST_COUNT(exku.oidList), cnt); + uint32_t idx = 0; + for (BSL_Buffer *data = BSL_LIST_GET_FIRST(exku.oidList); data != NULL; data = BSL_LIST_GET_NEXT(exku.oidList)) { + ASSERT_COMPARE("Extended key usage", values[idx]->x, values[idx]->len, data->data, data->dataLen); + idx++; + } + +exit: + HITLS_X509_ClearExtendedKeyUsage(&exku); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_ParseAki_TC001(Hex *encode, Hex *kid, Hex *serial, int nameCnt) +{ + HITLS_X509_ExtAki aki = {0}; + HITLS_X509_ExtEntry entry = {BSL_CID_CE_AUTHORITYKEYID, {0}, true, {0, encode->len, encode->x}}; + + TestMemInit(); + ASSERT_EQ(HITLS_X509_ParseAuthorityKeyId(&entry, &aki), 0); + + ASSERT_EQ(aki.critical, entry.critical); + ASSERT_COMPARE("kid", aki.kid.data, aki.kid.dataLen, kid->x, kid->len); + ASSERT_COMPARE("serial", aki.serialNum.data, aki.serialNum.dataLen, serial->x, serial->len); + + ASSERT_EQ(BSL_LIST_COUNT(aki.issuerName), nameCnt); + +exit: + HITLS_X509_ClearAuthorityKeyId(&aki); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_ParseSan_TC001(Hex *encode, int gnNameCnt, int gnType1, int gnType2, Hex *rfc822, Hex *dnType, + Hex *dnValue) +{ + HITLS_X509_ExtSan san = {0}; + HITLS_X509_ExtEntry entry = {BSL_CID_CE_SUBJECTALTNAME, {0}, true, {0, encode->len, encode->x}}; + HITLS_X509_GeneralName *gnName = NULL; + BslList *dirNameList = NULL; + HITLS_X509_NameNode *dirName = NULL; + + TestMemInit(); + ASSERT_EQ(HITLS_X509_ParseSubjectAltName(&entry, &san), 0); + ASSERT_EQ(san.critical, entry.critical); + ASSERT_EQ(BSL_LIST_COUNT(san.names), gnNameCnt); + + gnName = BSL_LIST_GET_FIRST(san.names); + ASSERT_EQ(gnName->type, gnType1); + ASSERT_COMPARE("gnName 1", rfc822->x, rfc822->len, gnName->value.data, gnName->value.dataLen); + + gnName = BSL_LIST_GET_NEXT(san.names); + ASSERT_EQ(gnName->type, gnType2); + dirNameList = (BslList *)gnName->value.data; + ASSERT_EQ(BSL_LIST_COUNT(dirNameList), 1 + 1); // layer 1 and layer 2 + dirName = BSL_LIST_GET_FIRST(dirNameList); // layer 1 + dirName = BSL_LIST_GET_NEXT(dirNameList); // layer 2 + ASSERT_COMPARE("dnname type", dirName->nameType.buff, dirName->nameType.len, dnType->x, dnType->len); + ASSERT_COMPARE("dnname value", dirName->nameValue.buff, dirName->nameValue.len, dnValue->x, dnValue->len); + +exit: + HITLS_X509_ClearSubjectAltName(&san); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_EXT_GetSki_TC001(Hex *encode, int ret, int critical, Hex *kid) +{ + TestMemInit(); + + BSL_ASN1_Buffer asnExt = {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED, encode->len, encode->x}; + bool getIsExist; + HITLS_X509_ExtSki ski = {0}; + + HITLS_X509_Ext *ext = HITLS_X509_ExtNew(); + ASSERT_NE(ext, NULL); + ASSERT_EQ(HITLS_X509_ParseExt(&asnExt, ext), 0); + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_CHECK_SKI, &getIsExist, sizeof(bool)), 0); + ASSERT_EQ(getIsExist, ret == HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_ExtCtrl(ext, HITLS_X509_EXT_GET_SKI, &ski, sizeof(HITLS_X509_ExtSki)), ret); + ASSERT_EQ(ski.critical, critical); + ASSERT_COMPARE("Get ski", ski.kid.data, ski.kid.dataLen, kid->x, kid->len); + +exit: + HITLS_X509_ExtFree(ext); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/x509/common/test_suite_sdv_common.data b/testcode/sdv/testcase/x509/common/test_suite_sdv_common.data new file mode 100644 index 00000000..a18547aa --- /dev/null +++ b/testcode/sdv/testcase/x509/common/test_suite_sdv_common.data @@ -0,0 +1,227 @@ +SDV_HITLS_X509_FreeCert_TC001 +SDV_HITLS_X509_FreeCert_TC001 + +SDV_HITLS_X509_ParseBuffCert_TC001 +SDV_HITLS_X509_ParseBuffCert_TC001 + +SDV_HITLS_X509_ParseFileCert_TC001 +SDV_HITLS_X509_ParseFileCert_TC001 + +SDV_HITLS_X509_CtrlCert_TC001 +SDV_HITLS_X509_CtrlCert_TC001 + +SDV_HITLS_X509_DupCert_TC001 +SDV_HITLS_X509_DupCert_TC001 + +SDV_HITLS_X509_FreeCrl_TC001 +SDV_HITLS_X509_FreeCrl_TC001 + +SDV_HITLS_X509_CtrlCrl_TC001 +SDV_HITLS_X509_CtrlCrl_TC001 + +SDV_HITLS_X509_ParseBuffCrl_TC001 +SDV_HITLS_X509_ParseBuffCrl_TC001 + +SDV_HITLS_X509_ParseFileCrl_TC001 +SDV_HITLS_X509_ParseFileCrl_TC001 + +SDV_CRYPT_EAL_ParseBuffPubKey_TC001 +SDV_CRYPT_EAL_ParseBuffPubKey_TC001 + +SDV_CRYPT_EAL_ParseFilePubKey_TC001 +SDV_CRYPT_EAL_ParseFilePubKey_TC001 + +SDV_CRYPT_EAL_ParseBuffPriKey_TC001 +SDV_CRYPT_EAL_ParseBuffPriKey_TC001 + +SDV_CRYPT_EAL_ParseFilePriKey_TC001 +SDV_CRYPT_EAL_ParseFilePriKey_TC001 + +SDV_HITLS_X509_FreeStoreCtx_TC001 +SDV_HITLS_X509_FreeStoreCtx_TC001 + +SDV_HITLS_X509_CtrlStoreCtx_TC001 +SDV_HITLS_X509_CtrlStoreCtx_TC001 + +SDV_HITLS_X509_VerifyCert_TC001 +SDV_HITLS_X509_VerifyCert_TC001 + +SDV_HITLS_X509_BuildCertChain_TC001 +SDV_HITLS_X509_BuildCertChain_TC001 + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem rsa pss private key: default +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa_pss.key" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem rsa pss private key: sha256, sha256, 20(default) +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa_pss_mdsha256.key" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem rsa pss private key: sha1(default), sha256, 20(default) +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa_pss_mgfsha256.key" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem rsa pss private key: sha1(default), sha1(default), 10 +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa_pss_salt10.key" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem secp521r1 private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_ECC:"../testdata/cert/asn1/secp521r1.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown type(pem) ecc private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_ECC:"../testdata/cert/asn1/secp521r1.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem prime256v1 private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_ECC:"../testdata/cert/asn1/secp384r1.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown type(pem) ecc private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_ECC:"../testdata/cert/asn1/secp384r1.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown type(der) ecc private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_ECC:"../testdata/cert/asn1/secp384r1.der" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem pkcs8 ec unencrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/prime256v1_pkcs8.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(pem) pkcs8 ec unencrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/prime256v1_pkcs8.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(der) pkcs8 ec unencrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/prime256v1_pkcs8.der" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem rsa private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_RSA:"../testdata/cert/asn1/keypem/rsa-pri-key.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(pem) rsa private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_RSA:"../testdata/cert/asn1/keypem/rsa-pri-key.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(der) rsa private key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_RSA:"../testdata/cert/asn1/keypem/rsa-pri-key.der" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem pkcs8 rsa unencrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa-pri-key-p8.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(pem) pkcs8 rsa unencrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa-pri-key-p8.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(der) pkcs8 rsa unencrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/keypem/rsa-pri-key-p8.der" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem pkcs8 ec encrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_ENCRYPT:"../testdata/cert/asn1/prime256v1_pkcs8_enc.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(pem) pkcs8 ec encrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_ENCRYPT:"../testdata/cert/asn1/prime256v1_pkcs8_enc.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(der) pkcs8 ec encrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_ENCRYPT:"../testdata/cert/asn1/prime256v1_pkcs8_enc1.der" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse pem pkcs8 rsa encrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PRIKEY_PKCS8_ENCRYPT:"../testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(pem) pkcs8 rsa encrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_ENCRYPT:"../testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.pem" + +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001 parse unkown(der) pkcs8 rsa encrypt key +SDV_CRYPT_EAL_ParseFilePriKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PRIKEY_PKCS8_ENCRYPT:"../testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.der" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse pem pkcs8 ec public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PUBKEY_SUBKEY:"../testdata/cert/asn1/secp384r1pub.pem" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse unkown(pem) pkcs8 ec public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PUBKEY_SUBKEY:"../testdata/cert/asn1/secp384r1pub.pem" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse unkown(der) pkcs8 ec public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PUBKEY_SUBKEY:"../testdata/cert/asn1/secp384r1pub.der" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse pem pkcs8 rsa public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PUBKEY_SUBKEY:"../testdata/cert/asn1/keypem/rsa-pub-key-p8.pem" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse unkown pkcs8 rsa public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PUBKEY_SUBKEY:"../testdata/cert/asn1/keypem/rsa-pub-key-p8.pem" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse unkown pkcs8 rsa public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PUBKEY_SUBKEY:"../testdata/cert/asn1/keypem/rsa-pub-key-p8.der" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse pem rsa public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_PEM:CRYPT_PUBKEY_RSA:"../testdata/cert/asn1/keypem/rsa-pub-key.pem" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse unkown(pem) rsa public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PUBKEY_RSA:"../testdata/cert/asn1/keypem/rsa-pub-key.pem" + +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001 parse unkown(der) rsa public key +SDV_CRYPT_EAL_ParseFilePubKeyFormat_TC001:BSL_FORMAT_UNKNOWN:CRYPT_PUBKEY_RSA:"../testdata/cert/asn1/keypem/rsa-pub-key.der" + +SDV_X509_EncodeNameList_TC001: multi RDN 1 +SDV_X509_EncodeNameList_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/sm2.ca_v1.crt":"3118301606092A864886F70D0109011609746573744041626323311A300906035504061302434E300D060355040B0C06234128622963310E300C060355040A0C054F2A6F6F203113301106035504070C0A232074657374204C2020314F304D06035504080C4620202320436F6E74656E743D0A2041613DC38FC2892CC383C2822CC383C2A6202042623D3C76313B2376322B76332F2376342B76353E2043633B44643B22453A6522202320203111300F06035504030C082374657374436E23" + +SDV_X509_EncodeNameList_TC001: multi RDN 2 +SDV_X509_EncodeNameList_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/sm2.ca_v1_2.crt":"313730090603550406130243633009060355040B0C024161300C060355040A0C054F2A6F6F20301106035504070C0A232074657374204C2020" + +SDV_X509_EXT_SetBCons_TC001 +SDV_X509_EXT_SetBCons_TC001: + +SDV_X509_EXT_SetAkiSki_TC001 +SDV_X509_EXT_SetAkiSki_TC001:"301D0603551D0E04160414B527FE6E548AB0EF17" + +SDV_X509_EXT_SetKeyUsage_TC001 +SDV_X509_EXT_SetKeyUsage_TC001: + +SDV_X509_EXT_SetExtendKeyUsage_TC001 +SDV_X509_EXT_SetExtendKeyUsage_TC001: + +SDV_X509_EXT_SetSan_TC001 +SDV_X509_EXT_SetSan_TC001: + +SDV_X509_EXT_EncodeBCons_TC001: critical: false, isCa: false, maxPathLen: -1 +SDV_X509_EXT_EncodeBCons_TC001:0:0:-1:"300B30090603551D1304023000" + +SDV_X509_EXT_EncodeBCons_TC001: critical: true, isCa: false, maxPathLen: 0 +SDV_X509_EXT_EncodeBCons_TC001:1:0:0:"3011300f0603551d130101ff04053003020100" + +SDV_X509_EXT_EncodeBCons_TC001: critical: true, isCa: true, maxPathLen: 1 +SDV_X509_EXT_EncodeBCons_TC001:1:1:1:"301430120603551d130101ff040830060101ff020101" + +SDV_X509_EXT_EncodeExtendKeyUsage_TC001: critical: true +SDV_X509_EXT_EncodeExtendKeyUsage_TC001:1:"2b06010505070301":"2b06010505070304":"302230200603551D250101FF0416301406082b0601050507030106082b06010505070304" + +SDV_X509_EXT_EncodeSan_TC001: critical: true +SDV_X509_EXT_EncodeSan_TC001:1:HITLS_X509_GN_URI:HITLS_X509_GN_IP:HITLS_X509_GN_EMAIL:HITLS_X509_GN_DNS:BSL_CID_COMMONNAME:BSL_CID_COUNTRYNAME:"7665":"303C303A0603551D110101FF0430302E86027665870276658102766582027665A41C301A310B300906035504030C027665310B3009060355040613027665" + +SDV_X509_EXT_EncodeKeyUsage_TC001: critical: true, usage: digitalSign, nonRepudiation, keyEncipherment +SDV_X509_EXT_EncodeKeyUsage_TC001:1:HITLS_X509_EXT_KU_DIGITAL_SIGN|HITLS_X509_EXT_KU_NON_REPUDIATION|HITLS_X509_EXT_KU_KEY_ENCIPHERMENT:"3010300E0603551D0F0101FF0404030205E0" + +SDV_X509_EXT_EncodeKeyUsage_TC001: critical: false, usage: decipherOnly, crlSign, keyEncipherment +SDV_X509_EXT_EncodeKeyUsage_TC001::HITLS_X509_EXT_KU_DECIPHER_ONLY|HITLS_X509_EXT_KU_CRL_SIGN|HITLS_X509_EXT_KU_KEY_ENCIPHERMENT:"300E300C0603551D0F04050303072280" + +SDV_X509_EXT_EncodeAKiSki_TC001: critical: falase +SDV_X509_EXT_EncodeAKiSki_TC001:0:0:"5ED3DB0A721F214C362744058AC56767ADA683DB":"5ED3DB0A721F214C362744058AC56767ADA683DB":"3040301D0603551D0E041604145ED3DB0A721F214C362744058AC56767ADA683DB301F0603551D230418301680145ED3DB0A721F214C362744058AC56767ADA683DB" + +SDV_X509_EXT_ParseGeneralNames_TC001: parse general names +SDV_X509_EXT_ParseGeneralNames_TC001:"A44D304B310B300906035504061302554B31183016060355040A0C0F4D79204F7267616E697A6174696F6E3110300E060355040B0C074D7920556E69743110300E06035504030C074D79204E616D658704C0A807018619687474703A2F2F6D792E75726C2E686572652F434E3D666F6FA01E06032A0304A0170C15736F6D65206F74686572206964656E74696669657281106D79406F746865722E6164647265737388032A03048208746573742E636F6D":"C0A80701":"687474703A2F2F6D792E75726C2E686572652F434E3D666F6F":"6D79406F746865722E61646472657373":"2A0304":"746573742E636F6D" + +SDV_X509_EXT_ParseGeneralNames_Error_TC001: The actual value length is larger. +SDV_X509_EXT_ParseGeneralNames_Error_TC001:"8208746573742E636F6D12":BSL_ASN1_ERR_DECODE_LEN + +SDV_X509_EXT_ParseGeneralNames_Error_TC001: The actual value length is smaller. +SDV_X509_EXT_ParseGeneralNames_Error_TC001:"8208746573742E636F":BSL_ASN1_ERR_DECODE_LEN + +SDV_X509_EXT_ParseGeneralNames_Error_TC001: Unkown name tag +SDV_X509_EXT_ParseGeneralNames_Error_TC001:"8008746573742E636F6D":HITLS_X509_ERR_PARSE_SAN_ITEM_UNKNOW + +SDV_X509_EXT_ParseSki_TC001: success +SDV_X509_EXT_ParseSki_TC001:"0414BFCB55F18843C3EF58D4D145E373762B7D151DB0":HITLS_X509_SUCCESS:"BFCB55F18843C3EF58D4D145E373762B7D151DB0" + +SDV_X509_EXT_ParseSki_TC001: error +SDV_X509_EXT_ParseSki_TC001:"0414BFCB55F18843C3EF58D4D145E373762B7D151D":BSL_ASN1_ERR_DECODE_LEN:"" + +SDV_X509_EXT_ParseExtendedKu_TC001 +SDV_X509_EXT_ParseExtendedKu_TC001:"301E06082B0601050507030806082B0601050507030106082B06010505070302":"2B06010505070308":"2B06010505070301":"2B06010505070302" + +SDV_X509_EXT_ParseAki_TC001: +SDV_X509_EXT_ParseAki_TC001:"30728014BFCB55F18843C3EF58D4D145E373762B7D151DB0A144A4423040310B300906035504061302434E310D300B060355040A0C0474657374310C300A060355040B0C036164733114301206035504030C0B746573745F726F6F744361821446D811212E43E29B5F913B93013C86664753B7AA":"BFCB55F18843C3EF58D4D145E373762B7D151DB0":"46D811212E43E29B5F913B93013C86664753B7AA":1 + +SDV_X509_EXT_ParseSan_TC001 +SDV_X509_EXT_ParseSan_TC001:"303081106D79406F746865722E61646472657373A41C301A31183016060355040A0C0F4D79204F7267616E697A6174696F6E":2:HITLS_X509_GN_EMAIL:HITLS_X509_GN_DNNAME:"6D79406F746865722E61646472657373":"55040A":"4D79204F7267616E697A6174696F6E" + +SDV_X509_EXT_GetSki_TC001: ski is not exist +SDV_X509_EXT_GetSki_TC001:"304830360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F300E0603551D0F0101FF040403020388":HITLS_X509_ERR_EXT_NOT_FOUND:0:"" + +SDV_X509_EXT_GetSki_TC001: ski is exist +SDV_X509_EXT_GetSki_TC001:"306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388":HITLS_X509_SUCCESS:0:"962D9DF010CE347D86409930A9D99696B34961BB" diff --git a/testcode/sdv/testcase/x509/crl/test_suite_sdv_x509_crl.c b/testcode/sdv/testcase/x509/crl/test_suite_sdv_x509_crl.c new file mode 100644 index 00000000..0a73f1d4 --- /dev/null +++ b/testcode/sdv/testcase/x509/crl/test_suite_sdv_x509_crl.c @@ -0,0 +1,437 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_sal.h" +#include "securec.h" +#include "hitls_x509.h" +#include "hitls_x509_errno.h" +#include "bsl_type.h" +#include "bsl_log.h" +#include "sal_file.h" +#include "bsl_init.h" +#include "hitls_crl_local.h" + + +/* END_HEADER */ + +void BinLogFixLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para1, void *para2, void *para3, void *para4) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para1, para2, para3, para4); + printf("\n"); +} + +void BinLogVarLenFunc(uint32_t logId, uint32_t logLevel, uint32_t logType, + void *format, void *para) +{ + (void)logLevel; + (void)logType; + printf("logId:%u\t", logId); + printf(format, para); + printf("\n"); +} + + +static int32_t HITLS_ParseCrlTest(int32_t format, char *path, HITLS_X509_Crl **crl) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + int32_t ret = BSL_LOG_RegBinLogFunc(&func); + if (ret != BSL_SUCCESS) { + return ret; + } + + ret = HITLS_X509_CrlParseFile(format, path, crl); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + return ret; +} + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_FUNC_TC001(int format, char *path) +{ + TestMemInit(); + BSL_LOG_BinLogFuncs func = {0}; + BSL_GLOBAL_Init(); + func.fixLenFunc = BinLogFixLenFunc; + func.varLenFunc = BinLogVarLenFunc; + ASSERT_TRUE(BSL_LOG_RegBinLogFunc(&func) == BSL_SUCCESS); + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_X509_CrlParseFile((int32_t)format, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_CTRL_FUNC_TC001(char *path) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + int32_t ref = 0; + ret = HITLS_X509_CrlCtrl(crl, HITLS_X509_CRL_REF_UP, &ref, sizeof(ref)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ref, 2); + HITLS_X509_CrlFree(crl); + +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_VERSION_FUNC_TC001(char *path, int version) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(crl->tbs.version, version); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001(char *path, int signAlg, + int rsaPssHash, int rsaPssMgf1, int rsaPssSaltLen) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(crl->tbs.signAlgId.algId, signAlg); + ASSERT_EQ(crl->tbs.signAlgId.rsaPssParam.mdId, rsaPssHash); + ASSERT_EQ(crl->tbs.signAlgId.rsaPssParam.mgfId, rsaPssMgf1); + ASSERT_EQ(crl->tbs.signAlgId.rsaPssParam.saltLen, rsaPssSaltLen); + +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_ISSUERNAME_FUNC_TC001(char *path, int count, + Hex *type1, int tag1, Hex *value1, + Hex *type2, int tag2, Hex *value2, + Hex *type3, int tag3, Hex *value3, + Hex *type4, int tag4, Hex *value4, + Hex *type5, int tag5, Hex *value5) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_Buffer expAsan1Arr[] = { + {6, type1->len, type1->x}, {(uint8_t)tag1, value1->len, value1->x}, + {6, type2->len, type2->x}, {(uint8_t)tag2, value2->len, value2->x}, + {6, type3->len, type3->x}, {(uint8_t)tag3, value3->len, value3->x}, + {6, type4->len, type4->x}, {(uint8_t)tag4, value4->len, value4->x}, + {6, type5->len, type5->x}, {(uint8_t)tag5, value5->len, value5->x}, + }; + ASSERT_EQ(BSL_LIST_COUNT(crl->tbs.issuerName), count); + HITLS_X509_NameNode **nameNode = NULL; + nameNode = BSL_LIST_First(crl->tbs.issuerName); + for (int i = 0; i < count; i += 2) { // Iteration with step=2 + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 1); + ASSERT_EQ((*nameNode)->nameType.tag, 0); + ASSERT_EQ((*nameNode)->nameType.buff, NULL); + ASSERT_EQ((*nameNode)->nameType.len, 0); + ASSERT_EQ((*nameNode)->nameValue.tag, 0); + ASSERT_EQ((*nameNode)->nameValue.buff, NULL); + ASSERT_EQ((*nameNode)->nameValue.len, 0); + + nameNode = BSL_LIST_Next(crl->tbs.issuerName); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->layer, 2); + ASSERT_EQ((*nameNode)->nameType.tag, expAsan1Arr[i].tag); + ASSERT_COMPARE("nameType", (*nameNode)->nameType.buff, (*nameNode)->nameType.len, + expAsan1Arr[i].buff, expAsan1Arr[i].len); + + ASSERT_EQ((*nameNode)->nameValue.tag, expAsan1Arr[i + 1].tag); + ASSERT_COMPARE("nameVlaue", (*nameNode)->nameValue.buff, (*nameNode)->nameValue.len, + expAsan1Arr[i + 1].buff, expAsan1Arr[i + 1].len); + nameNode = BSL_LIST_Next(crl->tbs.issuerName); + } +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_REVOKED_FUNC_TC001(char *path) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, BSL_SAL_ERR_FILE_LENGTH); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003(char *path, int count, int num, + int tag1, Hex *value1, int year1, int month1, int day1, int hour1, int minute1, int second1) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(crl->tbs.revokedCerts), count); + HITLS_X509_CrlEntry **nameNode = NULL; + nameNode = BSL_LIST_First(crl->tbs.revokedCerts); + for (int i = 1; i < num; i++) { + nameNode = BSL_LIST_Next(crl->tbs.revokedCerts); + } + + ASSERT_EQ((*nameNode)->serialNumber.tag, tag1); + ASSERT_COMPARE("", (*nameNode)->serialNumber.buff, (*nameNode)->serialNumber.len, + value1->x, value1->len); + ASSERT_EQ((*nameNode)->time.year, year1); + ASSERT_EQ((*nameNode)->time.month, month1); + ASSERT_EQ((*nameNode)->time.day, day1); + ASSERT_EQ((*nameNode)->time.hour, hour1); + ASSERT_EQ((*nameNode)->time.minute, minute1); + ASSERT_EQ((*nameNode)->time.second, second1); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_TIME_FUNC_TC001(char *path) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_ERR_CHECK_TAG); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_START_TIME_FUNC_TC001(char *path, + int year, int month, int day, int hour, int minute, int second) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(crl->tbs.validTime.start.year, year); + ASSERT_EQ(crl->tbs.validTime.start.month, month); + ASSERT_EQ(crl->tbs.validTime.start.day, day); + ASSERT_EQ(crl->tbs.validTime.start.hour, hour); + ASSERT_EQ(crl->tbs.validTime.start.minute, minute); + ASSERT_EQ(crl->tbs.validTime.start.second, second); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_END_TIME_FUNC_TC001(char *path, + int year, int month, int day, int hour, int minute, int second) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(crl->tbs.validTime.end.year, year); + ASSERT_EQ(crl->tbs.validTime.end.month, month); + ASSERT_EQ(crl->tbs.validTime.end.day, day); + ASSERT_EQ(crl->tbs.validTime.end.hour, hour); + ASSERT_EQ(crl->tbs.validTime.end.minute, minute); + ASSERT_EQ(crl->tbs.validTime.end.second, second); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001(char *path, + int tag1, Hex *value1, int tag2, Hex *value2) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(BSL_LIST_COUNT(crl->tbs.crlExt.extList), 1); + HITLS_X509_ExtEntry **nameNode = NULL; + nameNode = BSL_LIST_First(crl->tbs.crlExt.extList); + ASSERT_NE((*nameNode), NULL); + ASSERT_EQ((*nameNode)->critical, 0); + ASSERT_EQ((*nameNode)->extnId.tag, tag1); + ASSERT_COMPARE("extnId", (*nameNode)->extnId.buff, (*nameNode)->extnId.len, value1->x, value1->len); + ASSERT_EQ((*nameNode)->extnValue.tag, tag2); + ASSERT_COMPARE("extnValue", (*nameNode)->extnValue.buff, (*nameNode)->extnValue.len, value2->x, value2->len); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001(char *path, int signAlg, + int rsaPssHash, int rsaPssMgf1, int rsaPssSaltLen) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(crl->signAlgId.algId, signAlg); + ASSERT_EQ(crl->signAlgId.rsaPssParam.mdId, rsaPssHash); + ASSERT_EQ(crl->signAlgId.rsaPssParam.mgfId, rsaPssMgf1); + ASSERT_EQ(crl->signAlgId.rsaPssParam.saltLen, rsaPssSaltLen); + +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_PARSE_SIGNATURE_FUNC_TC001(char *path, Hex *buff, int unusedBits) +{ + HITLS_X509_Crl *crl = NULL; + int32_t ret = HITLS_ParseCrlTest(BSL_FORMAT_ASN1, path, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(crl->signature.len, buff->len); + ASSERT_COMPARE("signature", crl->signature.buff, crl->signature.len, buff->x, buff->len); + ASSERT_EQ(crl->signature.unusedBits, unusedBits); +exit: + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_MUL_CRL_PARSE_FUNC_TC001(int format, char *path, int crlNum) +{ + BSL_GLOBAL_Init(); + HITLS_X509_List *list = NULL; + int32_t ret = HITLS_X509_CrlMulParseFile(format, path, &list); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(list), crlNum); +exit: + BSL_LIST_FREE(list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CrlFree); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_Encode_TC001(int format, char *path) +{ + BSL_GLOBAL_Init(); + HITLS_X509_Crl *crl = NULL; + uint8_t *encode = NULL; + uint32_t encodeLen; + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + ASSERT_EQ(ret, BSL_SUCCESS); + + BSL_Buffer ori = {data, dataLen}; + ret = HITLS_X509_CrlParseBuff(format, &ori, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CrlGenBuff(format, crl, &encode, &encodeLen); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + if (format == BSL_FORMAT_ASN1) { + ASSERT_EQ(dataLen, encodeLen); + } else { + ASSERT_EQ(dataLen, strlen((char *)encode)); + } + ASSERT_EQ(memcmp(encode, data, dataLen), 0); + +exit: + BSL_SAL_Free(data); + HITLS_X509_CrlFree(crl); + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_EncodeParam_TC001(void) +{ + BSL_GLOBAL_Init(); + HITLS_X509_Crl *crl = NULL; + uint8_t *encode = NULL; + uint32_t encodeLen; + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile("../testdata/cert/pem/crl/crl_v2.pem", &data, &dataLen); + ASSERT_EQ(ret, BSL_SUCCESS); + + BSL_Buffer ori = {data, dataLen}; + ret = HITLS_X509_CrlParseBuff(BSL_FORMAT_PEM, &ori, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CrlGenBuff(BSL_FORMAT_ASN1, NULL, &encode, &encodeLen), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CrlGenBuff(BSL_FORMAT_ASN1, crl, NULL, &encodeLen), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CrlGenBuff(BSL_FORMAT_ASN1, crl, &encode, NULL), HITLS_X509_ERR_INVALID_PARAM); + crl->tbs.version = 0; + ASSERT_EQ(HITLS_X509_CrlGenBuff(BSL_FORMAT_ASN1, crl, &encode, &encodeLen), + HITLS_X509_ERR_CRL_INACCRACY_VERSION); + ASSERT_EQ(HITLS_X509_CrlGenFile(BSL_FORMAT_ASN1, crl, NULL), HITLS_X509_ERR_INVALID_PARAM); +exit: + BSL_SAL_Free(data); + HITLS_X509_CrlFree(crl); + BSL_SAL_Free(encode); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CRL_EncodeFile_TC001(int format, char *path) +{ + BSL_GLOBAL_Init(); + HITLS_X509_Crl *crl = NULL; + uint8_t *data = NULL; + uint32_t dataLen = 0; + uint8_t *res = NULL; + uint32_t resLen; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + ASSERT_EQ(ret, BSL_SUCCESS); + + BSL_Buffer ori = {data, dataLen}; + ret = HITLS_X509_CrlParseBuff(format, &ori, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CrlGenFile(format, crl, "res.crl"); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_SAL_ReadFile("res.crl", &res, &resLen), BSL_SUCCESS); + ASSERT_COMPARE("crl_file com", data, dataLen, res, resLen); +exit: + BSL_SAL_Free(data); + HITLS_X509_CrlFree(crl); + BSL_SAL_Free(res); +} +/* END_CASE */ \ No newline at end of file diff --git a/testcode/sdv/testcase/x509/crl/test_suite_sdv_x509_crl.data b/testcode/sdv/testcase/x509/crl/test_suite_sdv_x509_crl.data new file mode 100644 index 00000000..1354a118 --- /dev/null +++ b/testcode/sdv/testcase/x509/crl/test_suite_sdv_x509_crl.data @@ -0,0 +1,224 @@ +SDV_X509_CRL_PARSE_FUNC_TC001 parse pem crl +SDV_X509_CRL_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/crl/crl_v2.pem" + +SDV_X509_CRL_PARSE_FUNC_TC001 parse unknown(pem) crl +SDV_X509_CRL_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/pem/crl/crl_v2.pem" + +SDV_X509_CRL_PARSE_FUNC_TC001 parse unknown(asn1) crl +SDV_X509_CRL_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der" + +SDV_X509_CRL_PARSE_FUNC_TC001 +SDV_X509_CRL_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der" + +SDV_X509_CRL_PARSE_FUNC_TC001 +SDV_X509_CRL_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ca-1-rsa-sha256-v2.der" + +SDV_X509_CRL_PARSE_FUNC_TC001 +SDV_X509_CRL_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ca-1-rsa-sha256-v1.der" + +SDV_X509_CRL_CTRL_FUNC_TC001 +SDV_X509_CRL_CTRL_FUNC_TC001:"../testdata/cert/asn1/ca-1-rsa-sha256-v2.der" + +SDV_X509_CRL_CTRL_FUNC_TC001 +SDV_X509_CRL_CTRL_FUNC_TC001:"../testdata/cert/asn1/ca-1-rsa-sha256-v1.der" + +SDV_X509_CRL_PARSE_VERSION_FUNC_TC001 +SDV_X509_CRL_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":0 + +SDV_X509_CRL_PARSE_VERSION_FUNC_TC001 +SDV_X509_CRL_PARSE_VERSION_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":1 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":BSL_CID_DSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":BSL_CID_DSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_crl/crl_v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_crl/crl_v2.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_crl/crl_v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_crl/crl_v2.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_crl/crl_v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_crl/crl_v2.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/pss_v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/pss_v2.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/crl_v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/crl_v2.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_crl/crl_v1.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_TBS_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_crl/crl_v2.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CRL_PARSE_ISSUERNAME_FUNC_TC001 +SDV_X509_CRL_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CRL_PARSE_ISSUERNAME_FUNC_TC001 +SDV_X509_CRL_PARSE_ISSUERNAME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":10:"550406":19:"5858":"550408":12:"5858":"55040a":12:"6365727469666963617465":"55040b":12:"74657374696E":"550403":12:"63657274696669636174652E74657374696E2E636F6D" + +SDV_X509_CRL_PARSE_TIME_FUNC_TC001 +SDV_X509_CRL_PARSE_TIME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.v1-time.der" + +SDV_X509_CRL_PARSE_START_TIME_FUNC_TC001 +SDV_X509_CRL_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_START_TIME_FUNC_TC001 +SDV_X509_CRL_PARSE_START_TIME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_END_TIME_FUNC_TC001 +SDV_X509_CRL_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":2034:4:21:3:12:2 + +SDV_X509_CRL_PARSE_END_TIME_FUNC_TC001 +SDV_X509_CRL_PARSE_END_TIME_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":2034:4:21:3:12:2 + +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001 +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":6:"551D14":4:"020101" + +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001 +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.mul.der":6:"551D14":4:"020101" + +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001 +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.mul2.der":6:"551D14":4:"020102" + +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001 +SDV_X509_CRL_PARSE_EXTENSIONS_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.mul3.der":6:"551D14":4:"020103" + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC001 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.old" + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v1.der":1:1:2:"02":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v2.der":1:1:2:"02":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v1.mul.der":3:1:2:"02":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v1.mul.der":3:2:2:"03":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v1.mul.der":3:3:2:"04":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v2.mul3.der":3:1:2:"02":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v2.mul3.der":3:2:2:"03":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003 +SDV_X509_CRL_PARSE_REVOKED_FUNC_TC003:"../testdata/cert/asn1/dsa_crl/crl_v2.mul3.der":3:3:2:"04":2024:4:23:3:12:2 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":BSL_CID_DSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":BSL_CID_DSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_crl/crl_v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/ecdsa_crl/crl_v2.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_crl/crl_v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_crl/crl_v2.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_crl/crl_v1.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_ecc_crl/crl_v2.der":BSL_CID_ECDSAWITHSHA256:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/pss_v1.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/pss_v2.der":BSL_CID_RSASSAPSS:BSL_CID_SHA256:BSL_CID_SHA256:32 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/crl_v1.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/rsa_pss_crl/crl_v2.der":BSL_CID_SHA256WITHRSAENCRYPTION:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_crl/crl_v1.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNALG_FUNC_TC001:"../testdata/cert/asn1/sm2_crl/crl_v2.der":BSL_CID_SM2DSAWITHSM3:0:0:0 + +SDV_X509_CRL_PARSE_SIGNATURE_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v1.der":"303C021C1A001CEE9B883B690F2C9E2FA924245A69EDC00B93BE5B87C896F07B021C705F9539541833ED8C275FA05DEE66BAF5BA0187C8F086E1E527CFB1":0 + +SDV_X509_CRL_PARSE_SIGNATURE_FUNC_TC001 +SDV_X509_CRL_PARSE_SIGNATURE_FUNC_TC001:"../testdata/cert/asn1/dsa_crl/crl_v2.der":"303C021C6B1DD2654D01044087FC459909362569913044323D2F34FE6AFE6631021C0DEAB0A4E517BDF50BE586159DB2B4A5B122B5F81679A9DDBC81C192":0 + +SDV_X509_MUL_CRL_PARSE_FUNC_TC001 with 3 pem crls +SDV_X509_MUL_CRL_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/asn1/ecdsa_crl/mulcrls.pem":3 + +SDV_X509_MUL_CRL_PARSE_FUNC_TC001 with 3 der crls +SDV_X509_MUL_CRL_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_crl/mulcrls.der":3 + +SDV_X509_MUL_CRL_PARSE_FUNC_TC001 with 3 unknown(pem) crls +SDV_X509_MUL_CRL_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/asn1/ecdsa_crl/mulcrls.pem":3 + +SDV_X509_MUL_CRL_PARSE_FUNC_TC001 with 3 unknown(der) crls +SDV_X509_MUL_CRL_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/asn1/ecdsa_crl/mulcrls.der":3 + +SDV_X509_MUL_CRL_PARSE_FUNC_TC001 with 3 unknown(der) crls (with redundant symbols) +SDV_X509_MUL_CRL_PARSE_FUNC_TC001:BSL_FORMAT_UNKNOWN:"../testdata/cert/asn1/ecdsa_crl/mulcrls-red.pem":3 + +SDV_X509_CRL_Encode_TC001 rsa crl(der) with revokelist +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_crl/crl_v2.v1.der" + +SDV_X509_CRL_Encode_TC001 rsa crl(der) without revokelist +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_crl/crl_v2.v1.old.der" + +SDV_X509_CRL_Encode_TC001 ecc crl(der) +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.der" + +SDV_X509_CRL_Encode_TC001 sm2 crl(der) +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_crl/crl_v2.v1.der" + +SDV_X509_CRL_Encode_TC001 rsa-pss crl(der) +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_crl/pss_v2.der" + +SDV_X509_CRL_Encode_TC001 rsa-pss crl-v1(der) +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_crl/pss_v1.der" + +SDV_X509_CRL_Encode_TC001 sm2 crl(pem) +SDV_X509_CRL_Encode_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/crl/crl_v2.pem" + +SDV_X509_CRL_EncodeParam_TC001 +SDV_X509_CRL_EncodeParam_TC001: + +SDV_X509_CRL_EncodeFile_TC001 sm2 crl(der) +SDV_X509_CRL_EncodeFile_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/sm2_crl/crl_v2.v1.der" + +SDV_X509_CRL_EncodeFile_TC001 sm2 crl(pem) +SDV_X509_CRL_EncodeFile_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/crl/crl_v2.pem" \ No newline at end of file diff --git a/testcode/sdv/testcase/x509/csr/test_suite_sdv_x509_csr.c b/testcode/sdv/testcase/x509/csr/test_suite_sdv_x509_csr.c new file mode 100644 index 00000000..14837f94 --- /dev/null +++ b/testcode/sdv/testcase/x509/csr/test_suite_sdv_x509_csr.c @@ -0,0 +1,883 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ +#include "hitls_csr_local.h" +#include "hitls_x509.h" +#include "bsl_list.h" +#include "sal_file.h" +#include "bsl_obj_internal.h" +#include "hitls_x509_errno.h" +#include "crypt_types.h" +#include "crypt_errno.h" +#include "crypt_encode.h" +#include "crypt_eal_encode.h" +#include "crypt_eal_rand.h" +#include "eal_pkey_local.h" +#include "bsl_list_internal.h" + +/* END_HEADER */ +#define MAX_DATA_LEN 128 + +void *TestMallocErr(uint32_t len) +{ + (void)len; + return NULL; +} + +static void *TestMalloc(uint32_t len) +{ + return malloc((size_t)len); +} + +static void TestMemInitErr() +{ + BSL_SAL_MemCallback cb = {TestMallocErr, free}; + BSL_SAL_RegMemCallback(&cb); +} + +static void TestMemInitCorrect() +{ + static BSL_SAL_MemCallback cb = {TestMalloc, free}; + BSL_SAL_RegMemCallback(&cb); +} + +/* BEGIN_CASE */ +void SDV_X509_CSR_New_FUNC_TC001(void) +{ + TestMemInitErr(); + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + ASSERT_EQ(csr, NULL); + + TestMemInitCorrect(); + csr = HITLS_X509_CsrNew(); + ASSERT_NE(csr, NULL); + +exit: + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CSR_Free_FUNC_TC001(void) +{ + TestMemInit(); + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + ASSERT_NE(csr, NULL); + HITLS_X509_CsrFree(csr); + + HITLS_X509_CsrFree(NULL); + +exit: + return; +} +/* END_CASE */ + +/** + * parse csr file api test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_PARSE_API_TC001(void) +{ + TestMemInit(); + HITLS_X509_Csr *csr = NULL; + const char *path = "../testdata/cert/pem/csr/csr.pem"; + ASSERT_NE(HITLS_X509_CsrParseFile(BSL_FORMAT_PEM, path, NULL), HITLS_X509_SUCCESS); + + ASSERT_NE(HITLS_X509_CsrParseFile(BSL_FORMAT_UNKNOWN, path, &csr), HITLS_X509_SUCCESS); + + ASSERT_NE(HITLS_X509_CsrParseFile(BSL_FORMAT_PEM, "/errPath/csr.pem", &csr), HITLS_X509_SUCCESS); + + ASSERT_NE(HITLS_X509_CsrParseFile(BSL_FORMAT_PEM, NULL, &csr), HITLS_X509_SUCCESS); + + /* the csr file don't have read permission */ + +exit: + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +/** + * parse csr buffer api test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_PARSE_API_TC002(void) +{ + TestMemInit(); + HITLS_X509_Csr *csr = NULL; + uint8_t data[MAX_DATA_LEN] = {}; + BSL_Buffer buffer = {data, sizeof(data)}; + BSL_Buffer ori = {NULL, 0}; + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_ASN1, &buffer, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_ASN1, NULL, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_ASN1, &ori, &csr), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_ASN1, &ori, &csr), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_UNKNOWN, &buffer, &csr), HITLS_X509_ERR_NOT_SUPPORT_FORMAT); +exit: + return; +} +/* END_CASE */ + + +/* BEGIN_CASE */ +void SDV_X509_CSR_PARSE_FUNC_TC001(int format, char *path, int expRawDataLen, int expSignAlg, Hex *expectedSign, + int expectUnusedbits) +{ + TestMemInit(); + HITLS_X509_Csr *csr = NULL; + uint32_t rawDataLen = 0; + ASSERT_EQ(HITLS_X509_CsrParseFile(format, path, &csr), HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_CsrVerify(csr), HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODELEN, &rawDataLen, sizeof(rawDataLen)), 0); + ASSERT_EQ(rawDataLen, expRawDataLen); + + uint8_t *rawData = NULL; + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODE, &rawData, 0), HITLS_X509_SUCCESS); + ASSERT_NE(rawData, NULL); + + CRYPT_EAL_PkeyCtx *publicKey = NULL; + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_PUBKEY, &publicKey, 0), HITLS_X509_SUCCESS); + ASSERT_NE(publicKey, NULL); + CRYPT_EAL_PkeyFreeCtx(publicKey); + + int32_t alg = 0; + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_SIGNALG, &alg, sizeof(alg)), HITLS_X509_SUCCESS); + ASSERT_EQ(alg, expSignAlg); + + int32_t ref = 0; + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_REF_UP, &ref, sizeof(ref)), HITLS_X509_SUCCESS); + ASSERT_EQ(ref, 2); + HITLS_X509_CsrFree(csr); + + ASSERT_NE(csr->signature.buff, NULL); + ASSERT_EQ(csr->signature.len, expectedSign->len); + ASSERT_EQ(memcmp(csr->signature.buff, expectedSign->x, expectedSign->len), 0); + ASSERT_EQ(csr->signature.unusedBits, expectUnusedbits); + +exit: + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +/** + * Test parse csr: check subject name +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_PARSE_FUNC_TC002(int format, char *path, int expectedNum, char *dnType1, + char *dnName1, char *dnType2, char *dnName2, char *dnType3, char *dnName3, char *dnType4, char *dnName4, + char *dnType5, char *dnName5) +{ + TestMemInit(); + HITLS_X509_Csr *csr = NULL; + ASSERT_EQ(HITLS_X509_CsrParseFile(format, path, &csr), HITLS_X509_SUCCESS); + + BslList *rawSubject = NULL; + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_SUBJECT_DNNAME, &rawSubject, sizeof(BslList *)), 0); + ASSERT_NE(rawSubject, NULL); + int count = BSL_LIST_COUNT(rawSubject); + ASSERT_EQ(count, expectedNum); + char *dnTypes[5] = {dnType1, dnType2, dnType3, dnType4, dnType5}; + char *dnName[5] = {dnName1, dnName2, dnName3, dnName4, dnName5}; + HITLS_X509_NameNode *nameNode = BSL_LIST_GET_FIRST(rawSubject); + for (int i = 0; i < count && count <= 10 && nameNode != NULL; i++, nameNode = BSL_LIST_GET_NEXT(rawSubject)) { + if (nameNode->layer == 1) { + continue; + } + BSL_ASN1_Buffer nameType = nameNode->nameType; + BSL_ASN1_Buffer nameValue = nameNode->nameValue; + BslOidString typeOid = { + .octs = (char *)nameType.buff, + .octetLen = nameType.len, + }; + const char *oidName = BSL_OBJ_GetOidNameFromOid(&typeOid); + ASSERT_NE(oidName, NULL); + ASSERT_EQ(strcmp(dnTypes[i / 2], oidName), 0); + ASSERT_EQ(memcmp(dnName[i / 2], nameValue.buff, strlen(dnName[i / 2])), 0); + } + +exit: + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +/** + * Test parse csr: check the count of the attribute list +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_PARSE_FUNC_TC003(int format, char *path, int attrNum, int attrCid, Hex *attrValue) +{ + TestMemInit(); + HITLS_X509_Csr *csr = NULL; + BslList *rawAttrs = NULL; + + ASSERT_EQ(HITLS_X509_CsrParseFile(format, path, &csr), HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, &rawAttrs, sizeof(BslList *)), HITLS_X509_SUCCESS); + ASSERT_NE(rawAttrs, NULL); + ASSERT_EQ(attrNum, BSL_LIST_COUNT(rawAttrs)); + if (attrNum == 0) { + goto exit; + } + + HITLS_X509_AttrEntry *entry = BSL_LIST_GET_FIRST(rawAttrs); + ASSERT_EQ(attrCid, entry->cid); + BslOidString *oid = BSL_OBJ_GetOidFromCID(entry->cid); + ASSERT_NE(oid, NULL); + ASSERT_COMPARE("csr attr oid", entry->attrId.buff, entry->attrId.len, (uint8_t *)oid->octs, oid->octetLen); + ASSERT_COMPARE("csr attr value", entry->attrValue.buff, entry->attrValue.len, attrValue->x, attrValue->len); + +exit: + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +/** + * encode csr buffer api test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_GEN_API_TC001(void) +{ + TestMemInit(); + + HITLS_X509_Csr *csr = NULL; + const char *path = "../testdata/cert/pem/csr/csr.pem"; + const char *writePath = "../testdata/cert/pem/csr/genCsr.pem"; + int32_t ret = HITLS_X509_CsrParseFile(BSL_FORMAT_PEM, path, &csr); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_CsrGenFile(NULL, BSL_FORMAT_PEM, writePath), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrGenFile(csr, BSL_FORMAT_UNKNOWN, writePath), HITLS_X509_ERR_NOT_SUPPORT_FORMAT); + ASSERT_EQ(HITLS_X509_CsrGenFile(csr, BSL_FORMAT_PEM, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_NE(HITLS_X509_CsrGenFile(csr, BSL_FORMAT_PEM, "/errPath/csr.pem"), HITLS_X509_SUCCESS); +exit: + HITLS_X509_CsrFree(csr); + return; +} +/* END_CASE */ + +/** + * encode csr buffer api test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_GEN_API_TC002(void) +{ + TestMemInit(); + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + ASSERT_NE(csr, NULL); + uint8_t data[MAX_DATA_LEN] = {}; + BSL_Buffer buffer = {NULL, 0}; + BSL_Buffer buffErr = {data, sizeof(data)}; + ASSERT_EQ(HITLS_X509_CsrGenBuff(csr, BSL_FORMAT_UNKNOWN, &buffer), HITLS_X509_ERR_NOT_SUPPORT_FORMAT); + ASSERT_EQ(HITLS_X509_CsrGenBuff(NULL, BSL_FORMAT_PEM, &buffer), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrGenBuff(csr, BSL_FORMAT_PEM, NULL), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_CsrGenBuff(csr, BSL_FORMAT_PEM, &buffErr), HITLS_X509_ERR_INVALID_PARAM); +exit: + HITLS_X509_CsrFree(csr); + return; +} +/* END_CASE */ + +/** + * 1. transform format +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_GEN_FUNC_TC001(int inFormat, char *csrPath, int outFormat) +{ + TestMemInit(); + TestRandInit(); + HITLS_X509_Csr *csr = NULL; + BSL_Buffer encode = {NULL, 0}; + uint8_t *data = NULL; + uint32_t dataLen = 0; + BSL_Buffer asnEncode = {NULL, 0}; + + ASSERT_EQ(BSL_SAL_ReadFile(csrPath, &data, &dataLen), BSL_SUCCESS); + + BSL_Buffer ori = {data, dataLen}; + ASSERT_EQ(HITLS_X509_CsrParseBuff(inFormat, &ori, &csr), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrGenBuff(csr, outFormat, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODELEN, &asnEncode.dataLen, sizeof(asnEncode.dataLen)), + HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODE, &asnEncode.data, 0), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrVerify(csr), HITLS_X509_SUCCESS); + + if (inFormat == outFormat) { + ASSERT_EQ(dataLen, encode.dataLen); + ASSERT_EQ(memcmp(encode.data, data, dataLen), 0); + } else if (inFormat == BSL_FORMAT_ASN1 && outFormat == BSL_FORMAT_PEM) { + ASSERT_EQ(dataLen, asnEncode.dataLen); + ASSERT_EQ(memcmp(asnEncode.data, data, dataLen), 0); + } else { + ASSERT_EQ(csr->rawDataLen, encode.dataLen); + ASSERT_EQ(memcmp(encode.data, csr->rawData, encode.dataLen), 0); + } +exit: + BSL_SAL_FREE(data); + BSL_SAL_FREE(encode.data); + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + + +/** + * 1. parse csr + * 2. not set some value after parse +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_GEN_FUNC_TC002(int format, char *csrPath, int keyFormat, char *privPath, int keyType, int pkeyId, + int pad) +{ + TestMemInit(); + HITLS_X509_Csr *csr = NULL; + uint8_t *data = NULL; + uint32_t dataLen = 0; + CRYPT_EAL_PkeyCtx *privKey = NULL; + int32_t mdId = CRYPT_MD_SHA256; + + ASSERT_EQ(BSL_SAL_ReadFile(csrPath, &data, &dataLen), BSL_SUCCESS); + + BSL_Buffer ori = {data, dataLen}; + ASSERT_EQ(HITLS_X509_CsrParseBuff(format, &ori, &csr), HITLS_X509_SUCCESS); + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(keyFormat, keyType, privPath, NULL, 0, &privKey), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_PRIVKEY, privKey, sizeof(CRYPT_EAL_PkeyCtx *)), + HITLS_X509_ERR_SET_AFTER_PARSE); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_PUBKEY, privKey, sizeof(CRYPT_EAL_PkeyCtx *)), + HITLS_X509_ERR_SET_AFTER_PARSE); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_MD_ID, &mdId, sizeof(int32_t)), + HITLS_X509_ERR_SET_AFTER_PARSE); + if (pkeyId == CRYPT_PKEY_RSA) { + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), + HITLS_X509_ERR_SET_AFTER_PARSE); + if (pad == CRYPT_PKEY_EMSA_PSS) { + CRYPT_RSA_PssPara para = {20, mdId, CRYPT_MD_SHA256}; // 20 is salt len + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), + HITLS_X509_ERR_SET_AFTER_PARSE); + } + } + +exit: + BSL_SAL_FREE(data); + HITLS_X509_CsrFree(csr); + CRYPT_EAL_PkeyFreeCtx(privKey); +} +/* END_CASE */ + +static void ResetCsrNameList(HITLS_X509_Csr *raw) +{ + BslList *newSubject = NULL; + (void)HITLS_X509_CsrCtrl(raw, HITLS_X509_GET_SUBJECT_DNNAME, &newSubject, sizeof(BslList **)); + newSubject->curr = NULL; + newSubject->last = NULL; + newSubject->first = NULL; + newSubject->dataSize = sizeof(HITLS_X509_NameNode); + newSubject->count = 0; +} + +static void ResetCsrAttrsList(HITLS_X509_Csr *raw) +{ + BslList *newAttrs = NULL; + (void)HITLS_X509_CsrCtrl(raw, HITLS_X509_CSR_GET_ATTRIBUTES, &newAttrs, sizeof(BslList **)); + newAttrs->curr = NULL; + newAttrs->last = NULL; + newAttrs->first = NULL; + newAttrs->dataSize = sizeof(HITLS_X509_NameNode); + newAttrs->count = 0; +} + +static int32_t SetCsr(HITLS_X509_Csr *raw, HITLS_X509_Csr *new, CRYPT_EAL_PkeyCtx *priv, int32_t pad, int32_t mdId, + int mgfId, int saltLen) +{ + int32_t ret = 1; + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_PUBKEY, raw->reqInfo.ealPubKey, sizeof(CRYPT_EAL_PkeyCtx *)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_PRIVKEY, priv, sizeof(void *)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_SIGN_MD_ID, &mdId, sizeof(int32_t)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_SIGN_RSA_PADDING, &pad, sizeof(int32_t)), 0); + if (pad == CRYPT_PKEY_EMSA_PSS) { + CRYPT_RSA_PssPara para = {saltLen, mdId, mgfId}; + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), 0); + } + BslList *rawSubject = NULL; + BslList *newSubject = NULL; + ASSERT_EQ(HITLS_X509_CsrCtrl(raw, HITLS_X509_GET_SUBJECT_DNNAME, &rawSubject, sizeof(BslList *)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_GET_SUBJECT_DNNAME, &newSubject, sizeof(BslList *)), 0); + ASSERT_NE(rawSubject, NULL); + ASSERT_NE(newSubject, NULL); + ASSERT_NE(BSL_LIST_Concat(newSubject, rawSubject), NULL); + + BslList *rawAttrs = NULL; + BslList *newAttrs = NULL; + ASSERT_EQ(HITLS_X509_CsrCtrl(raw, HITLS_X509_CSR_GET_ATTRIBUTES, &rawAttrs, sizeof(BslList *)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_CSR_GET_ATTRIBUTES, &newAttrs, sizeof(BslList *)), 0); + ASSERT_NE(rawAttrs, NULL); + ASSERT_NE(newAttrs, NULL); + if (BSL_LIST_COUNT(rawAttrs) > 0) { + ASSERT_NE(BSL_LIST_Concat(newAttrs, rawAttrs), NULL); + } + + ret = 0; +exit: + return ret; +} + +/** + * 1. set subject name, private key, public key, mdId, padding + * 2. generate csr + * 3. compare the generated csr buff +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_GEN_FUNC_TC003(int csrFormat, char *csrPath, int keyFormat, char *privPath, int keyType, int pad, + int mdId, int mgfId, int saltLen) +{ + TestMemInit(); + HITLS_X509_Csr *raw = NULL; + HITLS_X509_Csr *new = NULL; + CRYPT_EAL_PkeyCtx *privKey = NULL; + BSL_Buffer encode = {NULL, 0}; + uint8_t *newCsrEncode = NULL; + uint32_t newCsrEncodeLen = 0; + uint8_t *rawCsrEncode = NULL; + uint32_t rawCsrEncodeLen = 0; + + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(keyFormat, keyType, privPath, NULL, 0, &privKey), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrParseFile(csrFormat, csrPath, &raw), HITLS_X509_SUCCESS); + new = HITLS_X509_CsrNew(); + ASSERT_NE(new, NULL); + ASSERT_EQ(SetCsr(raw, new, privKey, pad, mdId, mgfId, saltLen), 0); + ASSERT_EQ(HITLS_X509_CsrGenBuff(new, csrFormat, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_GET_ENCODELEN, &newCsrEncodeLen, sizeof(newCsrEncodeLen)), + HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_GET_ENCODE, &newCsrEncode, 0), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(raw, HITLS_X509_GET_ENCODELEN, &rawCsrEncodeLen, sizeof(rawCsrEncodeLen)), + HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(raw, HITLS_X509_GET_ENCODE, &rawCsrEncode, 0), HITLS_X509_SUCCESS); + + if (pad == CRYPT_PKEY_EMSA_PSS) { + ASSERT_EQ(raw->reqInfo.reqInfoRawDataLen, new->reqInfo.reqInfoRawDataLen); + ASSERT_EQ(memcmp(raw->reqInfo.reqInfoRawData, new->reqInfo.reqInfoRawData, raw->reqInfo.reqInfoRawDataLen), 0); + } else { + ASSERT_EQ(newCsrEncodeLen, rawCsrEncodeLen); + ASSERT_EQ(memcmp(newCsrEncode, rawCsrEncode, rawCsrEncodeLen), 0); + } +exit: + HITLS_X509_CsrFree(raw); + ResetCsrNameList(new); + ResetCsrAttrsList(new); + HITLS_X509_CsrFree(new); + BSL_SAL_FREE(encode.data); + CRYPT_EAL_PkeyFreeCtx(privKey); +} +/* END_CASE */ + +void SetRsaPara(CRYPT_EAL_PkeyPara *para, uint8_t *e, uint32_t eLen, uint32_t bits) +{ + para->id = CRYPT_PKEY_RSA; + para->para.rsaPara.e = e; + para->para.rsaPara.eLen = eLen; + para->para.rsaPara.bits = bits; +} + +/** + * 1. csr ctrl interface test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_CTRL_SET_API_TC001(char *csrPath) +{ + TestMemInit(); + + BSL_Buffer encodeRaw = { NULL, 0}; + HITLS_X509_Csr *csr = NULL; + uint8_t *csrEncode = NULL; + uint32_t csrEncodeLen = 0; + CRYPT_EAL_PkeyCtx *pkey = NULL; + + ASSERT_EQ(BSL_SAL_ReadFile(csrPath, &encodeRaw.data, &encodeRaw.dataLen), HITLS_X509_SUCCESS); + ASSERT_NE(encodeRaw.data, NULL); + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_ASN1, &encodeRaw, &csr), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_GET_ENCODE, &csrEncode, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, 0xFFFF, &csrEncode, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODE, NULL, 0), HITLS_X509_SUCCESS); + + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODELEN, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_GET_ENCODELEN, &csrEncodeLen, sizeof(csrEncodeLen)), + HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODELEN, &csrEncodeLen, 0), HITLS_X509_SUCCESS); + + int ref = 0; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_REF_UP, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_REF_UP, &ref, 0), HITLS_X509_SUCCESS); + + int padding = CRYPT_PKEY_EMSA_PKCSV15; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PADDING, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PADDING, &padding, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_SET_SIGN_RSA_PADDING, &padding, 0), HITLS_X509_SUCCESS); + + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_PUBKEY, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_GET_PUBKEY, &pkey, 0), HITLS_X509_SUCCESS); + int32_t signAlg = 0; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_SIGNALG, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_GET_SIGNALG, &signAlg, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_SIGNALG, &signAlg, 0), HITLS_X509_SUCCESS); + + BslList *subjectName = 0; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_SUBJECT_DNNAME, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_GET_SUBJECT_DNNAME, &subjectName, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_SUBJECT_DNNAME, &subjectName, 0), HITLS_X509_SUCCESS); + + BslList *attrs = 0; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_CSR_GET_ATTRIBUTES, &attrs, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, &attrs, 0), HITLS_X509_SUCCESS); + +exit: + BSL_SAL_FREE(encodeRaw.data); + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +/** + * 1. csr ctrl interface test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_CTRL_SET_API_TC002(char *csrPath) +{ + TestMemInit(); + TestRandInit(); + HITLS_X509_Csr *csr = NULL; + CRYPT_EAL_PkeyCtx *rsaPkey = NULL; + CRYPT_EAL_PkeyCtx *eccPkey = NULL; + uint8_t e[] = {1, 0, 1}; + + int32_t ret = HITLS_X509_CsrParseFile(BSL_FORMAT_ASN1, csrPath, &csr); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + rsaPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_NE(rsaPkey, NULL); + CRYPT_EAL_PkeyPara rsaPara = {0}; + SetRsaPara(&rsaPara, e, sizeof(e), 2048); // 2048 is rsa key bits + ASSERT_EQ(CRYPT_EAL_PkeySetPara(rsaPkey, &rsaPara), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(rsaPkey), CRYPT_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_PUBKEY, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_SET_PUBKEY, rsaPkey, 0), HITLS_X509_SUCCESS); + + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_PRIVKEY, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_SET_PRIVKEY, rsaPkey, 0), HITLS_X509_SUCCESS); + + int32_t mdId = CRYPT_MD_SHA256; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_MD_ID, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_SET_SIGN_MD_ID, &mdId, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_MD_ID, &mdId, 0), HITLS_X509_SUCCESS); + + CRYPT_RSA_PssPara para = {20, CRYPT_MD_SHA256, CRYPT_MD_SHA256}; + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, NULL, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(NULL, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, 0), HITLS_X509_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), + HITLS_X509_SUCCESS); + + eccPkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDSA); + ASSERT_NE(eccPkey, NULL); + ASSERT_EQ(CRYPT_EAL_PkeySetParaById(eccPkey, CRYPT_ECC_NISTP256), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(eccPkey), CRYPT_SUCCESS); + ASSERT_NE(HITLS_X509_CsrCtrl(csr, HITLS_X509_SET_SIGN_RSA_PSS_PARAM, ¶, sizeof(CRYPT_RSA_PssPara)), + HITLS_X509_SUCCESS); +exit: + HITLS_X509_CsrFree(csr); + CRYPT_EAL_PkeyFreeCtx(rsaPkey); + CRYPT_EAL_PkeyFreeCtx(eccPkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/** + * 1. csr ctrl interface test +*/ +/* BEGIN_CASE */ +void SDV_X509_CSR_CTRL_FUNC_TC001(char *csrPath) +{ + TestMemInit(); + TestRandInit(); + BSL_Buffer encodeRaw = { NULL, 0}; + HITLS_X509_Csr *csr = NULL; + uint8_t *csrEncode = NULL; + uint32_t csrEncodeLen = 0; + CRYPT_EAL_PkeyCtx *pkey = NULL; + uint8_t e[] = {1, 0, 1}; + HITLS_X509_Csr *newCsr = NULL; + + ASSERT_EQ(BSL_SAL_ReadFile(csrPath, &encodeRaw.data, &encodeRaw.dataLen), HITLS_X509_SUCCESS); + ASSERT_NE(encodeRaw.data, NULL); + ASSERT_EQ(HITLS_X509_CsrParseBuff(BSL_FORMAT_ASN1, &encodeRaw, &csr), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODE, &csrEncode, 0), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_GET_ENCODELEN, &csrEncodeLen, sizeof(csrEncodeLen)), + HITLS_X509_SUCCESS); + ASSERT_EQ(csrEncodeLen, encodeRaw.dataLen); + ASSERT_EQ(memcmp(encodeRaw.data, csrEncode, encodeRaw.dataLen), 0); + + int32_t ref = 0; + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_REF_UP, &ref, sizeof(ref)), HITLS_X509_SUCCESS); + ASSERT_EQ(ref, 2); + HITLS_X509_CsrFree(csr); + + newCsr = HITLS_X509_CsrNew(); + ASSERT_NE(newCsr, NULL); + pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_RSA); + ASSERT_NE(pkey, NULL); + CRYPT_EAL_PkeyPara para = {0}; + SetRsaPara(¶, e, sizeof(e), 2048); // 2048 is rsa key bits + ASSERT_EQ(CRYPT_EAL_PkeySetPara(pkey, ¶), CRYPT_SUCCESS); + ASSERT_EQ(CRYPT_EAL_PkeyGen(pkey), CRYPT_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(newCsr, HITLS_X509_SET_PUBKEY, pkey, 0), HITLS_X509_SUCCESS); + ASSERT_EQ(HITLS_X509_CsrCtrl(newCsr, HITLS_X509_SET_PRIVKEY, pkey, 0), HITLS_X509_SUCCESS); + + ASSERT_EQ(HITLS_X509_CsrCtrl(newCsr, HITLS_X509_GET_ENCODELEN, &csrEncodeLen, sizeof(csrEncodeLen)), + HITLS_X509_SUCCESS); + +exit: + BSL_SAL_FREE(encodeRaw.data); + HITLS_X509_CsrFree(csr); + HITLS_X509_CsrFree(newCsr); + CRYPT_EAL_PkeyFreeCtx(pkey); + CRYPT_EAL_RandDeinit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CSR_AttrCtrl_API_TC001(void) +{ + TestMemInit(); + HITLS_X509_Attr attr = {0}; + HITLS_X509_Attr getAttr = {0}; + HITLS_X509_Ext ext = {0}; + HITLS_X509_ExtKeyUsage ku = {0, HITLS_X509_EXT_KU_NON_REPUDIATION}; + int32_t cmd = HITLS_X509_ATTR_SET_REQUESTED_EXTENSIONS; + BslList *attrList = NULL; + + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + ASSERT_NE(csr, NULL); + ASSERT_EQ(HITLS_X509_ExtCtrl(&ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, &attrList, sizeof(BslList *)), 0); + + // invalid param + ASSERT_EQ(HITLS_X509_AttrCtrl(NULL, cmd, &attr, sizeof(HITLS_X509_Attr)), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, -1, &attr, sizeof(HITLS_X509_Attr)), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, NULL, sizeof(HITLS_X509_Attr)), HITLS_X509_ERR_INVALID_PARAM); + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, &attr, 0), HITLS_X509_ERR_INVALID_PARAM); + + // attr.cid is unknown + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, &attr, sizeof(HITLS_X509_Attr)), CRYPT_ERR_ALGID); + + // attr.value is null + attr.cid = BSL_CID_REQ_EXTENSION; + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, &attr, sizeof(HITLS_X509_Attr)), HITLS_X509_ERR_INVALID_PARAM); + + attr.value = &ext; + + // encode ext failed + ext.list->count = 2; + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, &attr, sizeof(HITLS_X509_Attr)), BSL_INVALID_ARG); + ext.list->count = 1; + + // success + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, &attr, sizeof(HITLS_X509_Attr)), 0); + + // repeat + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, cmd, &attr, sizeof(HITLS_X509_Attr)), HITLS_X509_ERR_SET_ATTR_REPEAT); + + // get attr + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, HITLS_X509_ATTR_GET_REQUESTED_EXTENSIONS, + &getAttr, sizeof(HITLS_X509_Attr)), HITLS_X509_SUCCESS); + ASSERT_NE(getAttr.value, NULL); + ASSERT_EQ(getAttr.cid, BSL_CID_REQ_EXTENSION); + HITLS_X509_Ext *getExt = getAttr.value; + ASSERT_EQ(getExt->keyUsage, HITLS_X509_EXT_KU_NON_REPUDIATION); + + // not found + HITLS_X509_ExtFree(getExt); + getExt = NULL; + getAttr.value = NULL; + BSL_LIST_DeleteAll(attrList, (BSL_LIST_PFUNC_FREE)HITLS_X509_AttrEntryFree); + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, HITLS_X509_ATTR_GET_REQUESTED_EXTENSIONS, + &getAttr, sizeof(HITLS_X509_Attr)), HITLS_X509_ERR_ATTR_NOT_FOUND); + +exit: + HITLS_X509_CsrFree(csr); + BSL_LIST_FREE(ext.list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); + HITLS_X509_ExtFree(getExt); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CSR_EncodeAttrList_FUNC_TC001(int critical1, int maxPath, int critical2, int keyUsage, Hex *expect) +{ + TestMemInit(); + + HITLS_X509_Ext ext = {0}; + BslList *attrList = NULL; + HITLS_X509_ExtBCons bCons = {critical1, false, maxPath}; + HITLS_X509_ExtKeyUsage ku = {critical2, keyUsage}; + BSL_ASN1_Buffer encode = {0}; + + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + ASSERT_NE(csr, NULL); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, &attrList, sizeof(BslList *)), 0); + ASSERT_NE(attrList, NULL); + + // Generate ext + ASSERT_EQ(HITLS_X509_ExtCtrl(&ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), 0); + ASSERT_EQ(HITLS_X509_ExtCtrl(&ext, HITLS_X509_EXT_SET_BCONS, &bCons, sizeof(HITLS_X509_ExtBCons)), 0); + + // Set ext into attr + HITLS_X509_Attr attr = {BSL_CID_REQ_EXTENSION, &ext}; + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, HITLS_X509_ATTR_SET_REQUESTED_EXTENSIONS, &attr, sizeof(HITLS_X509_Attr)), + 0); + + // Test: Encode and check + ASSERT_EQ(HITLS_X509_EncodeAttrList(1, attrList, &encode), 0); + ASSERT_COMPARE("Encode attrs", expect->x, expect->len, encode.buff, encode.len); + +exit: + HITLS_X509_CsrFree(csr); + BSL_SAL_Free(encode.buff); + BSL_LIST_FREE(ext.list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CSR_EncodeAttrList_FUNC_TC002(void) +{ + TestMemInit(); + + HITLS_X509_Ext ext = {0}; + BslList *attrList = NULL; + HITLS_X509_ExtKeyUsage ku = {0, HITLS_X509_EXT_KU_NON_REPUDIATION}; + BSL_ASN1_Buffer encode = {0}; + + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + ASSERT_NE(csr, NULL); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, &attrList, sizeof(BslList *)), 0); + ASSERT_NE(attrList, NULL); + ASSERT_EQ(HITLS_X509_ExtCtrl(&ext, HITLS_X509_EXT_SET_KUSAGE, &ku, sizeof(HITLS_X509_ExtKeyUsage)), 0); + + // Test 1: no attr + ASSERT_EQ(HITLS_X509_EncodeAttrList(1, attrList, &encode), 0); + ASSERT_EQ(encode.buff, NULL); + ASSERT_EQ(encode.len, 0); + + // Test 2: encode attr entry failed + attrList->count = 1; + ASSERT_EQ(HITLS_X509_EncodeAttrList(1, attrList, &encode), BSL_INVALID_ARG); + + // Set ext into attr + HITLS_X509_Attr attr = {BSL_CID_REQ_EXTENSION, &ext}; + ASSERT_EQ(HITLS_X509_AttrCtrl(attrList, HITLS_X509_ATTR_SET_REQUESTED_EXTENSIONS, &attr, sizeof(HITLS_X509_Attr)), + 0); + + // Test 3: encode list item failed + ASSERT_EQ(HITLS_X509_EncodeAttrList(1, attrList, &encode), BSL_INVALID_ARG); + +exit: + HITLS_X509_CsrFree(csr); + BSL_LIST_FREE(ext.list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_CSR_ParseAttrList_FUNC_TC001(Hex *encode, int ret) +{ + TestMemInit(); + + BSL_ASN1_Buffer attrs = {0, encode->len, encode->x}; + BslList *attrList = NULL; + + HITLS_X509_Csr *csr = HITLS_X509_CsrNew(); + csr->flag = 0x01; // HITLS_X509_CSR_PARSE_FLAG + ASSERT_NE(csr, NULL); + ASSERT_EQ(HITLS_X509_CsrCtrl(csr, HITLS_X509_CSR_GET_ATTRIBUTES, &attrList, sizeof(BslList *)), 0); + ASSERT_NE(attrList, NULL); + + attrs.tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + ASSERT_EQ(HITLS_X509_ParseAttrList(&attrs, attrList), ret); + +exit: + HITLS_X509_CsrFree(csr); +} +/* END_CASE */ + +static void SetX509Dn(HITLS_X509_DN *dnName, int dnType, char *dnNameStr) +{ + dnName->cid = (BslCid)dnType; + dnName->data = (uint8_t *)dnNameStr; + dnName->dataLen = strlen(dnNameStr); +} + +static int32_t SetNewCsrInfo(HITLS_X509_Csr *new, CRYPT_EAL_PkeyCtx *key, int mdId, int dnType1, + char *dnName1, int dnType2, char *dnName2, int dnType3, char *dnName3) +{ + int32_t ret = 1; + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_PUBKEY, key, sizeof(CRYPT_EAL_PkeyCtx *)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_PRIVKEY, key, sizeof(void *)), 0); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_SET_SIGN_MD_ID, &mdId, sizeof(int32_t)), 0); + + HITLS_X509_DN dnName[3] = {0}; + int dnTypes[3] = {dnType1, dnType2, dnType3}; + char *dnNameStr[3] = {dnName1, dnName2, dnName3}; + for (int i = 0; i < 3; i++) { + SetX509Dn(&dnName[i], dnTypes[i], dnNameStr[i]); + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_ADD_SUBJECT_NAME, &dnName[i], 1), HITLS_X509_SUCCESS); + } + BslList *subjectName = 0; + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_GET_SUBJECT_DNNAME, &subjectName, sizeof(BslList *)), + HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(subjectName), 6); + + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_ADD_SUBJECT_NAME, dnName, 3), HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(subjectName), 10); + + ret = 0; +exit: + return ret; +} + +/* BEGIN_CASE */ +void SDV_X509_CSR_AddSubjectName_FUNC_TC001(int keyFormat, int keyType, char *privPath, + int mdId, int dnType1, char *dnName1, int dnType2, char *dnName2, int dnType3, char *dnName3, Hex *expectedReqInfo) +{ + TestMemInit(); + TestRandInit(); + HITLS_X509_Csr *new = NULL; + CRYPT_EAL_PkeyCtx *privKey = NULL; + BSL_Buffer encode = {NULL, 0}; + + ASSERT_EQ(CRYPT_EAL_DecodeFileKey(keyFormat, keyType, privPath, NULL, 0, &privKey), HITLS_X509_SUCCESS); + new = HITLS_X509_CsrNew(); + ASSERT_NE(new, NULL); + + ASSERT_EQ(SetNewCsrInfo(new, privKey, mdId, dnType1, dnName1, dnType2, dnName2, dnType3, dnName3), 0); + ASSERT_EQ(HITLS_X509_CsrGenBuff(new, BSL_FORMAT_PEM, &encode), HITLS_X509_SUCCESS); + ASSERT_EQ(new->reqInfo.reqInfoRawDataLen, expectedReqInfo->len); + ASSERT_EQ(memcmp(new->reqInfo.reqInfoRawData, expectedReqInfo->x, expectedReqInfo->len), 0); + + // error length + HITLS_X509_DN dnNameErr[1] = {{BSL_CID_COUNTRYNAME, (uint8_t *)"CNNN", strlen("CNNN")}}; + ASSERT_EQ(HITLS_X509_CsrCtrl(new, HITLS_X509_ADD_SUBJECT_NAME, dnNameErr, 1), + HITLS_X509_ERR_SET_DNNAME_INVALID_LEN); +exit: + HITLS_X509_CsrFree(new); + BSL_SAL_FREE(encode.data); + CRYPT_EAL_PkeyFreeCtx(privKey); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/x509/csr/test_suite_sdv_x509_csr.data b/testcode/sdv/testcase/x509/csr/test_suite_sdv_x509_csr.data new file mode 100644 index 00000000..9cb18619 --- /dev/null +++ b/testcode/sdv/testcase/x509/csr/test_suite_sdv_x509_csr.data @@ -0,0 +1,128 @@ +SDV_X509_CSR_New_FUNC_TC001 +SDV_X509_CSR_New_FUNC_TC001: + +SDV_X509_CSR_Free_FUNC_TC001 +SDV_X509_CSR_Free_FUNC_TC001: + +SDV_X509_CSR_PARSE_API_TC001 +SDV_X509_CSR_PARSE_API_TC001: + +SDV_X509_CSR_PARSE_API_TC002 +SDV_X509_CSR_PARSE_API_TC002: + +SDV_X509_CSR_PARSE_FUNC_TC001 #rsa sha256 csr without attribute +SDV_X509_CSR_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/csr.pem":881:BSL_CID_SHA256WITHRSAENCRYPTION:"3808399e8e2fc4830067034e41ee13b77dc4e21e8a274c536254d43c7193b89987a2401f18dd830c147b0d270dd3d1ef8bbce2e1b379ca2d5fd301c8086609f961c0df9a4d0727b71635478e2e026784d1624bac2616408287876ed823fdb2f663075fdb2b4ed2fe1a0aeceecd562f37058ad0e951607807ef5af8a189d1f6d63e98cd7310f0c2348488ac331e1a6fdcf753536782e7fbafbb50685389acfff25fb6f6d6953c07a9fe09e0ffc565e78ec284dacb97742b9a960ecf6111ec4f9bdc1152709cf0bef13c4958bc80bd9a980c16fc09df130ea44d6a021ed649e0254d7eb01345afc600b0860104c48490bd131cc2c5e873956d86a53f13c7dcf65b":0 + +SDV_X509_CSR_PARSE_FUNC_TC001 #ecdsa sha256 csr pem without attribute +SDV_X509_CSR_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr":249:BSL_CID_ECDSAWITHSHA256:"304402202e4a266903514eb533b47a165965db05281e15d95b0525d84e5e7baae7c21faa02207dc750784c7ff0d1af5aaaa370abd54939a36c0024077a92fedeee17acb6ec0f":0 + +SDV_X509_CSR_PARSE_FUNC_TC001 #ecdsa sha256 csr asn1 without attribute +SDV_X509_CSR_PARSE_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der":249:BSL_CID_ECDSAWITHSHA256:"304402202e4a266903514eb533b47a165965db05281e15d95b0525d84e5e7baae7c21faa02207dc750784c7ff0d1af5aaaa370abd54939a36c0024077a92fedeee17acb6ec0f":0 + +SDV_X509_CSR_PARSE_FUNC_TC001 #rsa sha256 csr asn1 with attribute +SDV_X509_CSR_PARSE_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr":833:BSL_CID_RSASSAPSS:"9a7a66d969f90205e80a9f0c0bcbed9c2373a283a3f96b4d309b3eaf55d963c7b8e88cce8b5393ab91a5d8476707f2bdc4d534170c1422d1bbeb80fc02815e5e301340ac73f34ea111a91f024b973a4c262f6c554b09e2aff4407c99419f7f2a0f5dfd0d105caaaf4c0bf2776a98ea0129b0b9703753a6fcbe1c3c7c82181199ec2fbbf631d048805c8796003a517b76a76d3a3986d3428bfe3bb19f0d133b98c14f1fe4170c68db9b2924adab7a54e8e92b2fad65a77f0fb28cb85319540bf36a9797a0f3e8fc030a8056d9c64f1afe5fd83f2a9f5ac9063574310a89d8e3fece146e64fe853ff872169f9c77cb95b49570b98292d1be79b80a2f8c9b65d131":0 + +SDV_X509_CSR_PARSE_FUNC_TC002 +SDV_X509_CSR_PARSE_FUNC_TC002:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/csr.pem":10:"ST":"The Great State of Long-Winded Certificate Field Names Whereby to Increase the Output Size":"L":"Toomanycharactersville":"O":"The Benevolent Society of Loquacious and Pleonastic Periphrasis":"OU":"Endorsement of Vouchsafe'd Evidentiary Certification":"CN":"cert.example" + +SDV_X509_CSR_PARSE_FUNC_TC003 +SDV_X509_CSR_PARSE_FUNC_TC003:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/csr.pem":0:0:"" + +SDV_X509_CSR_PARSE_FUNC_TC003 #rsa sha256 csr asn1 with attribute +SDV_X509_CSR_PARSE_FUNC_TC003:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr":1:BSL_CID_REQ_EXTENSION:"306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388" + +SDV_X509_CSR_GEN_API_TC001 +SDV_X509_CSR_GEN_API_TC001: + +SDV_X509_CSR_GEN_API_TC002 +SDV_X509_CSR_GEN_API_TC002: + +SDV_X509_CSR_GEN_FUNC_TC001: rsa pem to pem +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC001: rsa asn1 to asn1 +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der":BSL_FORMAT_ASN1 + +SDV_X509_CSR_GEN_FUNC_TC001: rsa pem to asn1 +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr":BSL_FORMAT_ASN1 + +SDV_X509_CSR_GEN_FUNC_TC001: rsa asn1 to pem +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC001: rsapss pem to pem +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC001: rsapss asn1 to asn1 +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.csr.der":BSL_FORMAT_ASN1 + +SDV_X509_CSR_GEN_FUNC_TC001: rsapss pem to asn1 +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC001: rsapss asn1 to pem +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.csr.der":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC001: ec pem to pem +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC001: ec asn1 to asn1 +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der":BSL_FORMAT_ASN1 + +SDV_X509_CSR_GEN_FUNC_TC001: ec pem to asn1 +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr":BSL_FORMAT_ASN1 + +SDV_X509_CSR_GEN_FUNC_TC001: ec asn1 to pem +SDV_X509_CSR_GEN_FUNC_TC001:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der":BSL_FORMAT_PEM + +SDV_X509_CSR_GEN_FUNC_TC002 +SDV_X509_CSR_GEN_FUNC_TC002:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr":BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_sha/rsa_sh256.key.pem":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_RSA:CRYPT_PKEY_EMSA_PKCSV15 + +SDV_X509_CSR_GEN_FUNC_TC002: ec pem +SDV_X509_CSR_GEN_FUNC_TC002:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr":BSL_FORMAT_PEM:"../testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.key.pem":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_ECDSA:0 + +SDV_X509_CSR_GEN_FUNC_TC002: ec asn1 +SDV_X509_CSR_GEN_FUNC_TC002:BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der":BSL_FORMAT_ASN1:"../testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.key.der":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_ECDSA:0 + +SDV_X509_CSR_GEN_FUNC_TC002 +SDV_X509_CSR_GEN_FUNC_TC002:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr":BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_EMSA_PSS:CRYPT_MD_SHA256 + +SDV_X509_CSR_GEN_FUNC_TC003 +SDV_X509_CSR_GEN_FUNC_TC003:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr":BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_sha/rsa_sh256.key.pem":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_EMSA_PKCSV15:CRYPT_MD_SHA256:CRYPT_MD_SHA256:0 + +SDV_X509_CSR_GEN_FUNC_TC003 +SDV_X509_CSR_GEN_FUNC_TC003:BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr":BSL_FORMAT_PEM:"../testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.key":CRYPT_PRIKEY_PKCS8_UNENCRYPT:CRYPT_PKEY_EMSA_PSS:CRYPT_MD_SHA256:CRYPT_MD_SHA256:0 + +SDV_X509_CSR_CTRL_SET_API_TC001 # input check test case for csr ctrl +SDV_X509_CSR_CTRL_SET_API_TC001:"../testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der" + +SDV_X509_CSR_CTRL_SET_API_TC002 # set key to csr +SDV_X509_CSR_CTRL_SET_API_TC002:"../testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der" + +SDV_X509_CSR_CTRL_FUNC_TC001 +SDV_X509_CSR_CTRL_FUNC_TC001:"../testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der" + +SDV_X509_CSR_AttrCtrl_API_TC001 +SDV_X509_CSR_AttrCtrl_API_TC001: + +SDV_X509_CSR_EncodeAttrList_FUNC_TC001 +SDV_X509_CSR_EncodeAttrList_FUNC_TC001:0:1:1:HITLS_X509_EXT_KU_DIGITAL_SIGN|HITLS_X509_EXT_KU_NON_REPUDIATION:"302d06092a864886f70d01090e3120301e300e0603551d0f0101ff0404030206c0300c0603551d1304053003020101" + +SDV_X509_CSR_EncodeAttrList_FUNC_TC002 +SDV_X509_CSR_EncodeAttrList_FUNC_TC002: + +SDV_X509_CSR_ParseAttrList_FUNC_TC001: no attr +SDV_X509_CSR_ParseAttrList_FUNC_TC001:"":0 + +SDV_X509_CSR_ParseAttrList_FUNC_TC001: success +SDV_X509_CSR_ParseAttrList_FUNC_TC001:"307606092A864886F70D01090E3169306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388":0 + +SDV_X509_CSR_ParseAttrList_FUNC_TC001: buff lenth is incorrect +SDV_X509_CSR_ParseAttrList_FUNC_TC001:"307606092A864886F70D01090E3168306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388":HITLS_X509_ERR_PARSE_ATTR_BUF + +SDV_X509_CSR_ParseAttrList_FUNC_TC001: tag is unexpected +SDV_X509_CSR_ParseAttrList_FUNC_TC001:"317606092A864886F70D01090E3169306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388":BSL_ASN1_ERR_MISMATCH_TAG + +SDV_X509_CSR_ParseAttrList_FUNC_TC001: oid is unknown +SDV_X509_CSR_ParseAttrList_FUNC_TC001:"307606092B864886F70D01090E3169306730360603551D11042F302D81106D79406F746865722E6164647265737386196C6461703A2F2F736F6D686F73742E636F6D2F434E3D666F6F301D0603551D0E04160414962D9DF010CE347D86409930A9D99696B34961BB300E0603551D0F0101FF040403020388":HITLS_X509_ERR_PARSE_OBJ_ID + +SDV_X509_CSR_AddSubjectName_FUNC_TC001 +SDV_X509_CSR_AddSubjectName_FUNC_TC001:BSL_FORMAT_ASN1:CRYPT_PRIKEY_PKCS8_UNENCRYPT:"../testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.key.der":CRYPT_MD_SHA256:BSL_CID_STATEORPROVINCENAME:"testST":BSL_CID_LOCALITYNAME:"Toomanycharactersville":BSL_CID_ORGANIZATIONNAME:"The Benevolent Society of Loquacious and Pleonastic Periphrasis":"308201570201003081F4310F300D06035504080C06746573745354311F301D06035504070C16546F6F6D616E796368617261637465727376696C6C6531483046060355040A0C3F5468652042656E65766F6C656E7420536F6369657479206F66204C6F71756163696F757320616E6420506C656F6E61737469632050657269706872617369733176300D06035504080C06746573745354301D06035504070C16546F6F6D616E796368617261637465727376696C6C653046060355040A0C3F5468652042656E65766F6C656E7420536F6369657479206F66204C6F71756163696F757320616E6420506C656F6E61737469632050657269706872617369733059301306072A8648CE3D020106082A8648CE3D03010703420004BB936997114F3EFC1798C5242B14E6AD0E25126667A092F4340CF9F4FDF4122966B761E8A3AB24690B871A1803250EC1FF94E88385A4D3C698A6D90E779883A2A000" diff --git a/testcode/sdv/testcase/x509/pkcs12/test_suite_sdv_pkcs12.c b/testcode/sdv/testcase/x509/pkcs12/test_suite_sdv_pkcs12.c new file mode 100644 index 00000000..78a3af12 --- /dev/null +++ b/testcode/sdv/testcase/x509/pkcs12/test_suite_sdv_pkcs12.c @@ -0,0 +1,1177 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_sal.h" +#include "securec.h" +#include "hitls_x509.h" +#include "hitls_x509_errno.h" +#include "bsl_type.h" +#include "bsl_log.h" +#include "sal_file.h" +#include "bsl_init.h" +#include "hitls_pkcs12_local.h" +#include "hitls_crl_local.h" +#include "hitls_cert_type.h" +#include "hitls_cert_local.h" +#include "bsl_type.h" +#include "crypt_errno.h" + +/* END_HEADER */ + +static void BagListsDestroyCb(void *bag) +{ + HTILS_PKCS12_SafeBagFree((HTILS_PKCS12_SafeBag *)bag); +} + +static void AttributesFree(void *attribute) +{ + HTILS_PKCS12_SafeBagAttr *input = (HTILS_PKCS12_SafeBagAttr *)attribute; + BSL_SAL_FREE(input->attrValue->data); + BSL_SAL_FREE(input->attrValue); + BSL_SAL_FREE(input); +} + +static void BagFree(void *value) +{ + HTILS_PKCS12_Bag *bag = (HTILS_PKCS12_Bag *)value; + HITLS_X509_CertFree(bag->value.cert); + BSL_LIST_DeleteAll(bag->attributes, HTILS_PKCS12_AttributesFree); + BSL_SAL_FREE(bag->attributes); + BSL_SAL_FREE(bag); +} + +/** + * For test parse safeBag-p8shroudkeyBag of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001(int algId, Hex *buff, int keyBits) +{ + BSL_Buffer safeContent = {0}; + BSL_ASN1_List *bagLists = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBag)); + ASSERT_NE(bagLists, NULL); + + char *pwd = "123456"; + uint32_t len = strlen(pwd); + int32_t bits = 0; + + // parse contentInfo + int32_t ret = HITLS_PKCS12_ParseContentInfo((BSL_Buffer *)buff, NULL, 0, &safeContent); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + + // get the safeBag of safeContents, and put in list. + ret = HITLS_PKCS12_ParseAsn1AddList(&safeContent, bagLists, BSL_CID_SAFECONTENT); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + // get key of the bagList. + ret = HITLS_PKCS12_ParseSafeBagList(bagLists, (const uint8_t *)pwd, len, p12); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12->key->value.key, NULL); + bits = CRYPT_EAL_PkeyGetKeyBits(p12->key->value.key); + if (algId == CRYPT_PKEY_ECDSA) { + ASSERT_EQ(((((keyBits - 1) / 8) + 1) * 2 + 1) * 8, bits); // cal len of pub + } else if (algId == CRYPT_PKEY_RSA) { + ASSERT_EQ(bits, keyBits); + } +exit: + BSL_SAL_Free(safeContent.data); + BSL_LIST_DeleteAll(bagLists, BagListsDestroyCb); + BSL_SAL_Free(bagLists); + HTILS_PKCS12_P12_InfoFree(p12); +} +/* END_CASE */ + +/** + * For test parse safeBag-cert of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_SAFEBAGS_OF_CERTBAGS_TC001(Hex *buff) +{ + BSL_ASN1_List *bagLists = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBag)); + ASSERT_NE(bagLists, NULL); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + BSL_Buffer safeContent = {0}; + + // parse contentInfo + int32_t ret = HITLS_PKCS12_ParseContentInfo((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, &safeContent); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + // get the safeBag of safeContents, and put int list. + ret = HITLS_PKCS12_ParseAsn1AddList(&safeContent, bagLists, BSL_CID_SAFECONTENT); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + // get cert of the bagList. + ret = HITLS_PKCS12_ParseSafeBagList(bagLists, NULL, 0, p12); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + +exit: + BSL_SAL_Free(safeContent.data); + BSL_LIST_DeleteAll(bagLists, BagListsDestroyCb); + HTILS_PKCS12_P12_InfoFree(p12); + BSL_SAL_Free(bagLists); +} +/* END_CASE */ + +/** + * For test parse attributes of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC001(Hex *buff, Hex *friendlyName, Hex *localKeyId) +{ + BSL_ASN1_List *attrbutes = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBagAttr)); + ASSERT_NE(attrbutes, NULL); + + BSL_ASN1_Buffer asn = { + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, + buff->len, + buff->x, + }; + int32_t ret = HITLS_PKCS12_ParseSafeBagAttr(&asn, attrbutes); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HTILS_PKCS12_SafeBagAttr *firstAttr = BSL_LIST_GET_FIRST(attrbutes); + HTILS_PKCS12_SafeBagAttr *second = BSL_LIST_GET_NEXT(attrbutes); + if (firstAttr->attrId == BSL_CID_FRIENDLYNAME) { + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BMPSTRING, (uint32_t)friendlyName->len, friendlyName->x}; + BSL_ASN1_Buffer encode = {0}; + ret = BSL_ASN1_DecodePrimitiveItem(&asn, &encode); + ASSERT_EQ(ret, BSL_SUCCESS); + ASSERT_COMPARE("friendly name", firstAttr->attrValue->data, firstAttr->attrValue->dataLen, + encode.buff, encode.len); + BSL_SAL_FREE(encode.buff); + } + if (firstAttr->attrId == BSL_CID_LOCALKEYID) { + ASSERT_EQ(memcmp(firstAttr->attrValue->data, localKeyId->x, localKeyId->len), 0); + } + if (second == NULL) { + ASSERT_EQ(friendlyName->len, 0); + } else { + if (second->attrId == BSL_CID_FRIENDLYNAME) { + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BMPSTRING, (uint32_t)friendlyName->len, friendlyName->x}; + BSL_ASN1_Buffer encode = {0}; + ret = BSL_ASN1_DecodePrimitiveItem(&asn, &encode); + ASSERT_EQ(ret, BSL_SUCCESS); + ASSERT_COMPARE("friendly name", firstAttr->attrValue->data, firstAttr->attrValue->dataLen, + encode.buff, encode.len); + BSL_SAL_FREE(encode.buff); + } + if (second->attrId == BSL_CID_LOCALKEYID) { + ASSERT_EQ(memcmp(second->attrValue->data, localKeyId->x, localKeyId->len), 0); + } + } +exit: + BSL_LIST_DeleteAll(attrbutes, AttributesFree); + BSL_SAL_FREE(attrbutes); +} +/* END_CASE */ + +/** + * For test parse attributes in the incorrect condition. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC002(Hex *buff) +{ + BSL_ASN1_List *attrbutes = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBagAttr)); + ASSERT_NE(attrbutes, NULL); + + BSL_ASN1_Buffer asn = { + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, + 0, + buff->x, + }; + int32_t ret = HITLS_PKCS12_ParseSafeBagAttr(&asn, attrbutes); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); // bagAttributes are OPTIONAL + asn.len = buff->len; + ret = HITLS_PKCS12_ParseSafeBagAttr(&asn, attrbutes); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + buff->x[4] = 0x00; // 4 is a random number. + ret = HITLS_PKCS12_ParseSafeBagAttr(&asn, attrbutes); + ASSERT_NE(ret, HITLS_X509_SUCCESS); +exit: + BSL_LIST_DeleteAll(attrbutes, AttributesFree); + BSL_SAL_FREE(attrbutes); +} +/* END_CASE */ + +/** + * For test parse authSafedata of tampering Cert-info with encrypted data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_AUTHSAFE_TC001(Hex *wrongCert) +{ + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + // parse authSafe + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + int32_t ret = HITLS_PKCS12_ParseAuthSafeData((BSL_Buffer *)wrongCert, (const uint8_t *)pwd, pwdlen, p12); + ASSERT_NE(ret, HITLS_X509_SUCCESS); + + char *pwd1 = "123456-789"; + uint32_t pwdlen1 = strlen(pwd1); + ret = HITLS_PKCS12_ParseAuthSafeData((BSL_Buffer *)wrongCert, (const uint8_t *)pwd1, pwdlen1, p12); + ASSERT_EQ(ret, CRYPT_EAL_CIPHER_DATA_ERROR); + + char *pwd2 = ""; + uint32_t pwdlen2 = strlen(pwd2); + ret = HITLS_PKCS12_ParseAuthSafeData((BSL_Buffer *)wrongCert, (const uint8_t *)pwd2, pwdlen2, p12); + ASSERT_EQ(ret, CRYPT_EAL_CIPHER_DATA_ERROR); + +exit: + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test parse authSafedata of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_AUTHSAFE_TC002(Hex *buff) +{ + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + // parse authSafe + int32_t ret = HITLS_PKCS12_ParseAuthSafeData((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, p12); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12->key->value.key, NULL); + ASSERT_NE(p12->entityCert->value.cert, NULL); +exit: + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of macData parse. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_MACDATA_TC001(Hex *buff, int alg, Hex *digest, Hex *salt, int iterations) +{ + HTILS_PKCS12_MacData *macData = HTILS_PKCS12_P12_MacDataNew(); + int32_t ret = HITLS_PKCS12_ParseMacData((BSL_Buffer *)buff, macData); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(macData->alg, alg); + ASSERT_EQ(macData->interation, iterations); + ASSERT_EQ(memcmp(macData->macSalt->data, salt->x, salt->len), 0); + ASSERT_EQ(memcmp(macData->mac->data, digest->x, digest->len), 0); +exit: + HTILS_PKCS12_p12_MacDataFree(macData); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of wrong macData parse. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_MACDATA_TC002(Hex *buff) +{ + HTILS_PKCS12_MacData *macData = HTILS_PKCS12_P12_MacDataNew(); + int32_t ret = HITLS_PKCS12_ParseMacData(NULL, macData); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + ret = HITLS_PKCS12_ParseMacData((BSL_Buffer *)buff, macData); + ASSERT_EQ(ret, CRYPT_DECODE_UNKNOWN_OID); +exit: + HTILS_PKCS12_p12_MacDataFree(macData); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of macData cal. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_CAL_MACDATA_TC001(Hex *initData, Hex *salt, int alg, int iter, Hex *mac) +{ + HTILS_PKCS12_MacData *macData = HTILS_PKCS12_P12_MacDataNew(); + macData->alg = alg; + macData->macSalt->data = salt->x; + macData->macSalt->dataLen = salt->len; + macData->interation = iter; + char *pwdData = "123456"; + uint32_t pwdlen = strlen(pwdData); + BSL_Buffer output = {0}; + BSL_Buffer pwd = {(uint8_t *)pwdData, pwdlen}; + int32_t ret = HTILS_PKCS12_CalMac(&output, &pwd, (BSL_Buffer *)initData, macData); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(output.data, mac->x, mac->len), 0); +exit: + BSL_SAL_FREE(macData->mac); + BSL_SAL_FREE(macData->macSalt); + BSL_SAL_FREE(macData); + BSL_SAL_Free(output.data); + return; +} +/* END_CASE */ + +/** + * For test cal key according to salt, alg, etc. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_CAL_KDF_TC001(Hex *pwd, Hex *salt, int alg, int iter, Hex *key) +{ + HTILS_PKCS12_MacData *macData = HTILS_PKCS12_P12_MacDataNew(); + macData->alg = alg; + macData->macSalt->data = salt->x; + macData->macSalt->dataLen = salt->len; + macData->interation = iter; + uint8_t outData[64] = {0}; + BSL_Buffer output = {outData, 64}; + int32_t ret = HTILS_PKCS12_KDF(&output, pwd->x, pwd->len, HITLS_PKCS12_KDF_MACKEY_ID, macData); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(output.data, key->x, key->len), 0); +exit: + BSL_SAL_FREE(macData->mac); + BSL_SAL_FREE(macData->macSalt); + BSL_SAL_FREE(macData); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of right conditions. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_P12_TC001(Hex *encode, Hex *cert) +{ + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &encPwd, + }; + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12->key->value.key, NULL); + ASSERT_NE(p12->entityCert->value.cert, NULL); + BSL_Buffer encodeCert = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, p12->entityCert->value.cert, &encodeCert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(encodeCert.data, cert->x, cert->len), 0); +exit: + BSL_SAL_Free(encodeCert.data); + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of right conditions (no Mac). +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_P12_TC002(Hex *encode, Hex *cert) +{ + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + }; + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_NE(ret, HITLS_X509_SUCCESS); + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, false); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12->key->value.key, NULL); + ASSERT_NE(p12->entityCert->value.cert, NULL); + BSL_Buffer encodeCert = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, p12->entityCert->value.cert, &encodeCert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(encodeCert.data, cert->x, cert->len), 0); +exit: + BSL_SAL_Free(encodeCert.data); + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of wrong conditions. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_P12_WRONG_CONDITIONS_TC001(Hex *encode) +{ + char *pwd1 = "1234567"; + char *pwd2 = "1234567"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd1; + encPwd.dataLen = strlen(pwd1); + BSL_Buffer macPwd; + macPwd.data = (uint8_t *)pwd2; + macPwd.dataLen = strlen(pwd2); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &macPwd, + }; + + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, NULL, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, NULL, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, NULL, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_VERIFY_FAIL); + + char *pwd3 = ""; + macPwd.data = (uint8_t *)pwd3; + macPwd.dataLen = strlen(pwd3); + param.macPwd = &macPwd; + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_VERIFY_FAIL); + + param.macPwd = NULL; + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_VERIFY_FAIL); + + param.encPwd = NULL; + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + char *pwd4 = "123456"; + param.encPwd = &encPwd; + macPwd.data = (uint8_t *)pwd4; + macPwd.dataLen = strlen(pwd4); + param.macPwd = &macPwd; + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, CRYPT_EAL_CIPHER_DATA_ERROR); + + encPwd.data = (uint8_t *)pwd4; + encPwd.dataLen = strlen(pwd4); + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + encode->x[6] = 0x04; // Modify the version = 4. + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_INVALID_PFX); +exit: + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of wrong p12-file. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC001(Hex *encode) +{ + char *pwd1 = "123456"; + char *pwd2 = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd1; + encPwd.dataLen = strlen(pwd1); + BSL_Buffer macPwd; + macPwd.data = (uint8_t *)pwd2; + macPwd.dataLen = strlen(pwd2); + + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &macPwd, + }; + + HTILS_PKCS12_P12Info *p12_1 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12_1, NULL); + HTILS_PKCS12_P12Info *p12_2 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12_2, NULL); + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12_1, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + encode->x[encode->len - 2] = 0x04; // modify the iteration = 1024; + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12_2, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_VERIFY_FAIL); + + encode->x[encode->len - 2] = 0x08; // recover the iteration = 2048; + (void)memset_s(encode->x + 96, 16, 0, 16); // modify the contentInfo + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12_2, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_VERIFY_FAIL); + +exit: + HTILS_PKCS12_P12_InfoFree(p12_1); + HTILS_PKCS12_P12_InfoFree(p12_2); + return; +} +/* END_CASE */ + +/** + * For test parse 12 of wrong p12-file, which miss a part of data randomly. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002(Hex *encode) +{ + char *pwd1 = "123456"; + char *pwd2 = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd1; + encPwd.dataLen = strlen(pwd1); + BSL_Buffer macPwd; + macPwd.data = (uint8_t *)pwd2; + macPwd.dataLen = strlen(pwd2); + + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &macPwd, + }; + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, true); + ASSERT_NE(ret, HITLS_X509_SUCCESS); + + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)encode, ¶m, p12, false); + ASSERT_NE(ret, HITLS_X509_SUCCESS); +exit: + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test encode safeBag-p8shroudkeyBag of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001(Hex *buff) +{ + TestRandInit(); + BSL_ASN1_List *bagLists = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBag)); + ASSERT_NE(bagLists, NULL); + + char *pwd = "123456"; + uint32_t len = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + + // get the safeBag of safeContents, and put in list. + int32_t ret = HITLS_PKCS12_ParseAsn1AddList((BSL_Buffer *)buff, bagLists, BSL_CID_SAFECONTENT); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + // get key of the bagList. + ret = HITLS_PKCS12_ParseSafeBagList(bagLists, (const uint8_t *)pwd, len, p12); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12->key->value.key, NULL); + + BSL_ASN1_List *list = BSL_LIST_New(sizeof(HTILS_PKCS12_Bag)); + HTILS_PKCS12_Bag *bag = BSL_SAL_Malloc(sizeof(HTILS_PKCS12_Bag)); + bag->attributes = p12->key->attributes; + bag->value = p12->key->value; + ret = BSL_LIST_AddElement(list, bag, BSL_LIST_POS_END); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + CRYPT_Pbkdf2Param param = {0}; + + param.pbesId = BSL_CID_PBES2; + param.pbkdfId = BSL_CID_PBKDF2; + param.hmacId = CRYPT_MAC_HMAC_SHA256; + param.symId = CRYPT_CIPHER_AES256_CBC; + param.pwd = (uint8_t *)pwd; + param.saltLen = 16; + param.pwdLen = len; + param.itCnt = 2048; + CRYPT_EncodeParam paramEx = {CRYPT_DERIVE_PBKDF2, ¶m}; + + BSL_Buffer encode = {0}; + ret = HITLS_PKCS12_EncodeAsn1List(list, BSL_CID_PKCS8SHROUDEDKEYBAG, ¶mEx, &encode); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(encode.dataLen, buff->len); + ret = memcmp(encode.data + encode.dataLen - 37, buff->x + buff->len - 37, 37); + ASSERT_EQ(ret, 0); + +exit: + BSL_SAL_Free(encode.data); + BSL_LIST_DeleteAll(bagLists, BagListsDestroyCb); + BSL_SAL_Free(bagLists); + BSL_LIST_FREE(list, NULL); + HTILS_PKCS12_P12_InfoFree(p12); +} +/* END_CASE */ + +/** + * For test encode encrypted-safecontent. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_SAFEBAGS_OF_CERTBAGS_TC001(Hex *buff) +{ + TestRandInit(); + BSL_ASN1_List *bagLists = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBag)); + ASSERT_NE(bagLists, NULL); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + BSL_Buffer safeContent = {0}; + + // parse contentInfo + int32_t ret = HITLS_PKCS12_ParseContentInfo((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, &safeContent); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + // get the safeBag of safeContents, and put int list. + ret = HITLS_PKCS12_ParseAsn1AddList(&safeContent, bagLists, BSL_CID_SAFECONTENT); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + // get cert of the bagList. + ret = HITLS_PKCS12_ParseSafeBagList(bagLists, NULL, 0, p12); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + CRYPT_Pbkdf2Param param = {0}; + param.pbesId = BSL_CID_PBES2; + param.pbkdfId = BSL_CID_PBKDF2; + param.hmacId = CRYPT_MAC_HMAC_SHA256; + param.symId = CRYPT_CIPHER_AES256_CBC; + param.pwd = (uint8_t *)pwd; + param.saltLen = 16; + param.pwdLen = pwdlen; + param.itCnt = 2048; + CRYPT_EncodeParam paramEx = {CRYPT_DERIVE_PBKDF2, ¶m}; + + BSL_Buffer encode = {0}; + ret = HITLS_PKCS12_EncodeAsn1List(p12->certList, BSL_CID_CERTBAG, ¶mEx, &encode); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer output = {0}; + ret = HITLS_PKCS12_EncodeContentInfo(&encode, BSL_CID_ENCRYPTEDDATA, ¶mEx, &output); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(output.dataLen, buff->len); + ret = memcmp(output.data, buff->x, 69); + ASSERT_EQ(ret, 0); + +exit: + BSL_SAL_Free(safeContent.data); + BSL_SAL_Free(encode.data); + BSL_SAL_Free(output.data); + BSL_LIST_DeleteAll(bagLists, BagListsDestroyCb); + HTILS_PKCS12_P12_InfoFree(p12); + BSL_SAL_Free(bagLists); +} +/* END_CASE */ + +/** + * For test encode authSafedata of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_AUTHSAFE_TC001(Hex *buff) +{ + TestRandInit(); + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + + char *pwd = "123456"; + uint32_t pwdlen = strlen(pwd); + // parse authSafe + int32_t ret = HITLS_PKCS12_ParseAuthSafeData((BSL_Buffer *)buff, (const uint8_t *)pwd, pwdlen, p12); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12->key->value.key, NULL); + ASSERT_NE(p12->entityCert->value.cert, NULL); + + CRYPT_Pbkdf2Param param = {0}; + param.pbesId = BSL_CID_PBES2; + param.pbkdfId = BSL_CID_PBKDF2; + param.hmacId = CRYPT_MAC_HMAC_SHA256; + param.symId = CRYPT_CIPHER_AES256_CBC; + param.pwd = (uint8_t *)pwd; + param.saltLen = 16; + param.pwdLen = pwdlen; + param.itCnt = 2048; + CRYPT_EncodeParam paramEx = {CRYPT_DERIVE_PBKDF2, ¶m}; + + HTILS_PKCS12_Bag *bag = BSL_SAL_Malloc(sizeof(HTILS_PKCS12_Bag)); + bag->attributes = p12->entityCert->attributes; + bag->value.cert = p12->entityCert->value.cert; + ret = BSL_LIST_AddElement(p12->certList, bag, BSL_LIST_POS_BEGIN); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + p12->entityCert->attributes = NULL; + p12->entityCert->value.cert = NULL; + BSL_Buffer *encode1 = BSL_SAL_Calloc(1, sizeof(BSL_Buffer)); + ASSERT_NE(encode1, NULL); + + ret = HITLS_PKCS12_EncodeAsn1List(p12->certList, BSL_CID_CERTBAG, ¶mEx, encode1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer *encode2 = BSL_SAL_Calloc(1, sizeof(BSL_Buffer)); + ASSERT_NE(encode2, NULL); + + ret = HITLS_PKCS12_EncodeContentInfo(encode1, BSL_CID_ENCRYPTEDDATA, ¶mEx, encode2); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_List *keyList = BSL_LIST_New(sizeof(HTILS_PKCS12_Bag)); + HTILS_PKCS12_Bag *bagKey = BSL_SAL_Malloc(sizeof(HTILS_PKCS12_Bag)); + bagKey->attributes = p12->key->attributes; + bagKey->value = p12->key->value; + ret = BSL_LIST_AddElement(keyList, bagKey, BSL_LIST_POS_END); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer *encode3 = BSL_SAL_Calloc(1, sizeof(BSL_Buffer)); + ASSERT_NE(encode3, NULL); + ret = HITLS_PKCS12_EncodeAsn1List(keyList, BSL_CID_PKCS8SHROUDEDKEYBAG, ¶mEx, encode3); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer *encode4 = BSL_SAL_Calloc(1, sizeof(BSL_Buffer)); + ASSERT_NE(encode4, NULL); + ret = HITLS_PKCS12_EncodeContentInfo(encode3, BSL_CID_DATA, ¶mEx, encode4); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_ASN1_List *list = BSL_LIST_New(sizeof(BSL_Buffer)); + ret = BSL_LIST_AddElement(list, encode2, BSL_LIST_POS_END); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ret = BSL_LIST_AddElement(list, encode4, BSL_LIST_POS_END); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer encode5 = {0}; + ret = HITLS_PKCS12_EncodeAsn1List(list, BSL_CID_CONTENTINFO, ¶mEx, &encode5); + ASSERT_EQ(encode5.dataLen, buff->len); + +exit: + BSL_SAL_Free(encode1->data); + BSL_SAL_Free(encode2->data); + BSL_SAL_Free(encode3->data); + BSL_SAL_Free(encode4->data); + BSL_SAL_Free(encode1); + BSL_SAL_Free(encode3); + BSL_SAL_Free(encode5.data); + BSL_LIST_FREE(list, NULL); + BSL_LIST_FREE(keyList, NULL); + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test encode authSafedata of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_MACDATA_TC001(Hex *buff, Hex *initData, Hex *expectData) +{ + TestRandInit(); + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &encPwd, + }; + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)buff, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_HmacParam hmacParam = {0}; + hmacParam.macId = CRYPT_MD_SHA224; + hmacParam.pwd = (uint8_t *)pwd; + hmacParam.saltLen = p12->macData->macSalt->dataLen; + hmacParam.pwdLen = strlen(pwd); + hmacParam.itCnt = 2048; + BSL_Buffer output = {0}; + BSL_Buffer output1 = {0}; + + ret = HITLS_PKCS12_EncodeMacData((BSL_Buffer *)initData, &hmacParam, p12->macData, &output); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = memcmp(output.data, expectData->x, expectData->len); + ASSERT_EQ(ret, 0); + + HTILS_PKCS12_MacData *macData = HTILS_PKCS12_P12_MacDataNew(); + hmacParam.itCnt = 999; + ret = HITLS_PKCS12_EncodeMacData((BSL_Buffer *)initData, &hmacParam, macData, &output); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_INVALID_INTERATION); + + hmacParam.itCnt = 1024; + hmacParam.saltLen = 0; + ret = HITLS_PKCS12_EncodeMacData((BSL_Buffer *)initData, &hmacParam, macData, &output); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_INVALID_SALTLEN); + + hmacParam.saltLen = 16; + ret = HITLS_PKCS12_EncodeMacData((BSL_Buffer *)initData, &hmacParam, macData, &output1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + BSL_SAL_Free(output.data); + BSL_SAL_Free(output1.data); + HTILS_PKCS12_p12_MacDataFree(macData); + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test encode P12 of correct data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_P12_TC001(Hex *buff, Hex *cert) +{ + TestRandInit(); + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &encPwd, + }; + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)buff, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_EncodeParam encodeParam = {0}; + + CRYPT_Pbkdf2Param pbParam = {0}; + pbParam.pbesId = BSL_CID_PBES2; + pbParam.pbkdfId = BSL_CID_PBKDF2; + pbParam.hmacId = CRYPT_MAC_HMAC_SHA256; + pbParam.symId = CRYPT_CIPHER_AES256_CBC; + pbParam.pwd = (uint8_t *)pwd; + pbParam.saltLen = 16; + pbParam.pwdLen = strlen(pwd); + pbParam.itCnt = 2048; + + CRYPT_EncodeParam encParam = {CRYPT_DERIVE_PBKDF2, &pbParam}; + encodeParam.certEncParam = encParam; + encodeParam.keyEncParam = encParam; + + HTILS_PKCS12_HmacParam macParam = {0}; + macParam.macId = p12->macData->alg; + macParam.pwd = (uint8_t *)pwd; + macParam.saltLen = p12->macData->macSalt->dataLen; + macParam.pwdLen = strlen(pwd); + macParam.itCnt = 2048; + encodeParam.macParam = macParam; + BSL_Buffer output = {0}; + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, p12, &encodeParam, true, &output); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(output.dataLen, buff->len); + + HTILS_PKCS12_P12Info *p12_1 = HTILS_PKCS12_P12_InfoNew(); + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, &output, ¶m, p12_1, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12_1->key->value.key, NULL); + ASSERT_NE(p12_1->entityCert->value.cert, NULL); + + BSL_Buffer encodeCert1 = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, p12->entityCert->value.cert, &encodeCert1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer encodeCert2 = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, p12_1->entityCert->value.cert, &encodeCert2); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(encodeCert1.data, encodeCert2.data, encodeCert1.dataLen), 0); + ASSERT_EQ(memcmp(encodeCert1.data, cert->x, cert->len), 0); + + if (BSL_LIST_COUNT(p12->certList) > 0) { + HTILS_PKCS12_Bag *node1 = BSL_LIST_GET_FIRST(p12->certList); + BSL_Buffer encodeCert3 = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, node1->value.cert, &encodeCert3); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_Bag *node2 = BSL_LIST_GET_FIRST(p12_1->certList); + BSL_Buffer encodeCert4 = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, node2->value.cert, &encodeCert4); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(encodeCert1.data, encodeCert2.data, encodeCert1.dataLen), 0); + BSL_SAL_Free(encodeCert3.data); + BSL_SAL_Free(encodeCert4.data); + } +exit: + BSL_SAL_Free(output.data); + BSL_SAL_Free(encodeCert1.data); + BSL_SAL_Free(encodeCert2.data); + HTILS_PKCS12_P12_InfoFree(p12); + HTILS_PKCS12_P12_InfoFree(p12_1); + return; +} +/* END_CASE */ + +/** + * For test encode P12 of correct data(no mac). +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_P12_TC002(Hex *buff, Hex *cert) +{ + TestRandInit(); + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &encPwd, + }; + int32_t ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)buff, ¶m, p12, false); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_EncodeParam encodeParam = {0}; + + CRYPT_Pbkdf2Param pbParam = {0}; + pbParam.pbesId = BSL_CID_PBES2; + pbParam.pbkdfId = BSL_CID_PBKDF2; + pbParam.hmacId = CRYPT_MAC_HMAC_SHA256; + pbParam.symId = CRYPT_CIPHER_AES256_CBC; + pbParam.pwd = (uint8_t *)pwd; + pbParam.saltLen = 16; + pbParam.pwdLen = strlen(pwd); + pbParam.itCnt = 2048; + + CRYPT_EncodeParam encParam = {CRYPT_DERIVE_PBKDF2, &pbParam}; + encodeParam.certEncParam = encParam; + encodeParam.keyEncParam = encParam; + + HTILS_PKCS12_HmacParam macParam = {0}; + macParam.macId = p12->macData->alg; + macParam.pwd = (uint8_t *)pwd; + macParam.saltLen = 8; + macParam.pwdLen = strlen(pwd); + macParam.itCnt = 2048; + encodeParam.macParam = macParam; + BSL_Buffer output = {0}; + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, p12, &encodeParam, true, &output); + ASSERT_NE(ret, HITLS_X509_SUCCESS); + + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, p12, &encodeParam, false, &output); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(output.dataLen, buff->len); + + HTILS_PKCS12_P12Info *p12_1 = HTILS_PKCS12_P12_InfoNew(); + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, &output, ¶m, p12_1, false); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_NE(p12_1->key->value.key, NULL); + ASSERT_NE(p12_1->entityCert->value.cert, NULL); + + BSL_Buffer encodeCert1 = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, p12->entityCert->value.cert, &encodeCert1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer encodeCert2 = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, p12_1->entityCert->value.cert, &encodeCert2); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(memcmp(encodeCert1.data, encodeCert2.data, encodeCert1.dataLen), 0); + ASSERT_EQ(memcmp(encodeCert1.data, cert->x, cert->len), 0); + +exit: + BSL_SAL_Free(output.data); + BSL_SAL_Free(encodeCert1.data); + BSL_SAL_Free(encodeCert2.data); + HTILS_PKCS12_P12_InfoFree(p12); + HTILS_PKCS12_P12_InfoFree(p12_1); + return; +} +/* END_CASE */ + +/** + * For test encode P12 of insufficient data. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_ENCODE_P12_TC003(Hex *buff) +{ + TestRandInit(); + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &encPwd, + }; + + HTILS_PKCS12_EncodeParam encodeParam = {0}; + + CRYPT_Pbkdf2Param pbParam = {0}; + pbParam.pbesId = BSL_CID_PBES2; + pbParam.pbkdfId = BSL_CID_PBKDF2; + pbParam.hmacId = CRYPT_MAC_HMAC_SHA256; + pbParam.symId = CRYPT_CIPHER_AES256_CBC; + pbParam.pwd = (uint8_t *)pwd; + pbParam.saltLen = 16; + pbParam.pwdLen = strlen(pwd); + pbParam.itCnt = 2048; + + CRYPT_EncodeParam encParam = {CRYPT_DERIVE_PBKDF2, &pbParam}; + encodeParam.certEncParam = encParam; + encodeParam.keyEncParam = encParam; + + BSL_Buffer output1 = {0}; + + // For test p12 has none data, isNeedMac = true. + int32_t ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, p12, &encodeParam, false, &output1); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NONE_DATA); + // For test p12 has none data, isNeedMac = false. + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, p12, &encodeParam, true, &output1); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NONE_DATA); + + ret = HITLS_PKCS12_ParseBuff(BSL_FORMAT_ASN1, (BSL_Buffer *)buff, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_HmacParam macParam = {0}; + macParam.macId = p12->macData->alg; + macParam.pwd = (uint8_t *)pwd; + macParam.saltLen = 8; + macParam.pwdLen = strlen(pwd); + macParam.itCnt = 2048; + encodeParam.macParam = macParam; + HTILS_PKCS12_P12Info p12_1 = {0}; + + // For test gen p12 of wrong input + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_UNKNOWN, &p12_1, &encodeParam, true, &output1); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NOT_SUPPORT_FORMAT); + + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, NULL, true, &output1); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, NULL); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + + (void)memcpy(&p12_1, p12, sizeof(HTILS_PKCS12_P12Info)); + CRYPT_EAL_PkeyCtx *temKey = p12_1.key->value.key; + HITLS_X509_Cert *entityCert = p12_1.entityCert->value.cert; + p12_1.key->value.key = NULL; + p12_1.entityCert->value.cert = NULL; // test p12-encode of key and entityCert = NULL. + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, &output1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer output2 = {0}; + p12_1.key->value.key = NULL; // test p12-encode of key = NULL. + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, &output2); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + p12_1.key->value.key = temKey; + p12_1.entityCert->value.cert = NULL; // test p12-encode of entityCert = NULL. + BSL_Buffer output3 = {0}; + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, &output3); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + p12_1.entityCert->value.cert = entityCert; + BSL_Buffer output4 = {0}; + BSL_LIST_DeleteAll(p12_1.entityCert->attributes, AttributesFree); // test p12-encode of entityCert attribute = NULL. + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, &output4); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_Buffer output5 = {0}; + BSL_LIST_DeleteAll(p12_1.key->attributes, AttributesFree); // test p12-encode of key attribute = NULL. + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, &output5); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + BSL_LIST_DeleteAll(p12_1.certList, BagFree); // test p12-encode of key attribute = NULL. + BSL_Buffer output6 = {0}; + ret = HITLS_PKCS12_GenBuff(BSL_FORMAT_ASN1, &p12_1, &encodeParam, true, &output6); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + BSL_SAL_Free(output1.data); + BSL_SAL_Free(output2.data); + BSL_SAL_Free(output3.data); + BSL_SAL_Free(output4.data); + BSL_SAL_Free(output5.data); + BSL_SAL_Free(output6.data); + HTILS_PKCS12_P12_InfoFree(p12); + return; +} +/* END_CASE */ + +/** + * For test gen and parse p12-file. +*/ +/* BEGIN_CASE */ +void SDV_PKCS12_GEN_PARASE_P12FILE_TC003(void) +{ + TestRandInit(); + char *pwd = "123456"; + BSL_Buffer encPwd; + encPwd.data = (uint8_t *)pwd; + encPwd.dataLen = strlen(pwd); + + HTILS_PKCS12_P12Info *p12 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12, NULL); + HTILS_PKCS12_PwdParam param = { + .encPwd = &encPwd, + .macPwd = &encPwd, + }; + + HTILS_PKCS12_EncodeParam encodeParam = {0}; + + CRYPT_Pbkdf2Param pbParam = {0}; + pbParam.pbesId = BSL_CID_PBES2; + pbParam.pbkdfId = BSL_CID_PBKDF2; + pbParam.hmacId = CRYPT_MAC_HMAC_SHA256; + pbParam.symId = CRYPT_CIPHER_AES256_CBC; + pbParam.pwd = (uint8_t *)pwd; + pbParam.saltLen = 16; + pbParam.pwdLen = strlen(pwd); + pbParam.itCnt = 2048; + + CRYPT_EncodeParam encParam = {CRYPT_DERIVE_PBKDF2, &pbParam}; + encodeParam.certEncParam = encParam; + encodeParam.keyEncParam = encParam; + + const char *path = "../testdata/cert/asn1/pkcs12/chain.p12"; + const char *writePath = "../testdata/cert/asn1/pkcs12/chain_cp.p12"; + + int32_t ret = HITLS_PKCS12_ParseFile(BSL_FORMAT_ASN1, NULL, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + ret = HITLS_PKCS12_ParseFile(BSL_FORMAT_ASN1, path, ¶m, p12, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_HmacParam macParam = {0}; + macParam.macId = p12->macData->alg; + macParam.pwd = (uint8_t *)pwd; + macParam.saltLen = 8; + macParam.pwdLen = strlen(pwd); + macParam.itCnt = 2048; + encodeParam.macParam = macParam; + + ret = HITLS_PKCS12_GenFile(BSL_FORMAT_ASN1, p12, &encodeParam, true, NULL); + ASSERT_EQ(ret, HITLS_PKCS12_ERR_NULL_POINTER); + ret = HITLS_PKCS12_GenFile(BSL_FORMAT_ASN1, p12, &encodeParam, true, writePath); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + HTILS_PKCS12_P12Info *p12_1 = HTILS_PKCS12_P12_InfoNew(); + ASSERT_NE(p12_1, NULL); + ret = HITLS_PKCS12_ParseFile(BSL_FORMAT_ASN1, writePath, ¶m, p12_1, true); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + HTILS_PKCS12_P12_InfoFree(p12); + HTILS_PKCS12_P12_InfoFree(p12_1); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/x509/pkcs12/test_suite_sdv_pkcs12.data b/testcode/sdv/testcase/x509/pkcs12/test_suite_sdv_pkcs12.data new file mode 100644 index 00000000..b5309cbb --- /dev/null +++ b/testcode/sdv/testcase/x509/pkcs12/test_suite_sdv_pkcs12.data @@ -0,0 +1,144 @@ +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001 01 +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001:CRYPT_PKEY_RSA:"06092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D0065":2048 + +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001 02 +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001:CRYPT_PKEY_RSA:"06092A864886F70D010701A08209FD048209F9308209F5308209F1060B2A864886F70D010C0A0102A08209B9308209B5305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F6B766FD664DBF046993DDAAB0FEE82A02020800300C06082A864886F70D02090500301D060960864801650304012A0410F0DC4FAA0FB840A1466776B3C5D911D604820950405687C5C733063FF94CF8180BF35F6BE01591CCFA4DF932222F93BB04179F255BCBB4FAE60FF8E630BA2288EAC96613EFBDC8733E3415244F1B79E576447D56FB765F06443A45F998EB99D13C6C67C3B78A7B3997E3A0DDEF27AE7D8F41133BD496E770D9113DB96778787E0959CB396A9841133F09C4643DBE3C64A573B1A0493823E909E662F6A089E8A59B8B65239738F25BAB6D3521E334107C4AC89D5818DAD709620BDB664F31548F5813B0143FBAF8FB134C49020FB5B0464093CA035A704BDDBEB1EA90AC3D17E11A20A1D975712775289DC1AA440CE39412808A8C09D257F2881F53AF563EC4FB5D0F614A8FDC59478B450F79FCF8ED30FDF2B03A24D6074AFD0F0C9FE866CCE2A8F53C1B3B124BC0A8A839C360BB64AD2E1BA0C1A33E3AFBE81754EED777976FB45E08E934BC0F2CD14D0A5865BD03B76B7864F88DFFF6E3ED2F69B2EDBEEF75C052D15C18F3FFBE25D46BAD527FB800D5C927ABC83FA8A32E3E214E7BAB460581B021C72B5419AF5214AA4F45034CF97DCA17566D258FE9D25476633497AE221CAEC20CB0E10DFB90B1A6FE931A44DBD9A9450F36B5F05DE6798A9AC9BEF2A68DEC1B2D8DD4E6FA2743163EED32A27F8C168F6ED5D824A766EB3DDB67B2F6538CE89C2E5DD29BCB5DC17DB4CB95EF182DE07A3EF1D016187929057C65EA1296F0367474E09B48C199D94F5806220ADBF0C03030A0E1CB14DAD49D41D0EC66714E60A2E9E943C342861F94A3F4F9C8A28C11A9AFEF96E36C3D22D9DB69ECC58D794134F877FE280E827E8943633D1576F6A75EB9BAC9E741FFA77A038C5032076A6C011D7C4A41EF1C00BA033958B43F3EC1671B66BE37750462B4CBAC52D30D4B8D2DA258D38FC607C33573359F02CEAC2FE1496C8EB4D697AFF44D8844563A80BF5A524CBD918BCD91E18FC05A47B85774A0B840AFC1D5FD322CFFAFEACFCCFBAEFF6A281A494EDDDBFE802806BEAFE059280E6E475B341AA3CAE6244BAB5A0458239F7E5900198920A6745F6F51E15B31A7061BECB7E7FF828B2F54EF75F43E73811893CB95FA7A13126A54FDF488A41E7FB9D477B7EC4EA4C15A071046022CA371B03DE36A454954D981A90D2C77122FDE304FE5FB7A116554073570893E1FD09E29FA5BE612840D9A1E80D67C3EC1859448B69CDC5E208C8AB4CA733CAB0EE838D434EEF5F34A1D0A793F614FC02AEF23C9C2A8125CF20F3E9E7B1E0BAF7FFE6AE49954ACB2543DD89ED7A0DF7085FC635A09AF9FE35D3455D6FC7E6E4BBEA5CCD18A8129C7C01DA6F6CFF1992BFA430225A968AA7BA6776FC51AD3DD6FE4FF19BB54695D170FFB6565A567E5B23B0FA549865842A632938E2429839FC12FFC622C36AAC6A796C57231C97DFE503C27BAC49BDDE582236218E08A2C71DDF2E1DEC758F7A45524BE2391A4440B31D3FD259CF6419C96F773D2C97D74F3F6B6F0FE158D681C6752FF6E4EE874029519ABF24A0B7BBFE5F36AE1D64A236D037E948D51FE0504B2B9FC7D778F4F509674EEA28E1D1EDDC083FC218C5A4A201D5794D0562EA2105E436C8932E9162F5484F77E0EADFD6D720344E3D38995B4D129D4DBED83A42F6C48CCB59B83048044381C5FCB35D7BC19B5AE9F0219F1D24F3BBE4FAD4D7D838BCC79099ADA2FCD32D61623EA00B650DC3B135AD98A51B2A808456DDEC692D61FF5FD80B35F45F8E56A9ECEE63A4ABFF9E04395BC8B224A52D58E3EE101B361D2378EBDF79F35F997445107ED33F2A1F77966906A6BF5307CE9B1B36C4FD179C817388B2C10CFD124E060D7EFC0114077AA72C958143CD4B991097D0D09BF3DF43361E9DDEA7D7C4B7B8115D383C414C3D6CE1944B3FD34E1365FB9B659B8DD9AE6C7AD402558C33DFBDCDAEEC35C0F15AB515316867B8CF1BCBE879DF98AAB9D77E317E4F5C264CDC12F520E18AE47A9B3723C030962FEC98CA458470822C1FE9DDC8E0EB52514431008AAC0F39459A930D5C642E1E53B37497F797F34DCB3275CC4C05BE31505BCF8E2AC225F2D433F892CBE49EEC06793619D9C0617B1CBEC02241601FBE9EBE2E99B8109765AC11B9391FF479E7E7A19B6363D253705CC6A34A3CC6E41A1229D9F1EE4942D05B1D740963D470EE0DF209D938F2C1C6222360DE6F96A8E505F12B8884DD293EB39865DC4E77ACC4CE15300673923136DBD121E4B98E7BFDB8255257DA2B5B26619252791668F3DB6DABDCDBD0E55F18E9BE0B0939E93FEB6EBD3FBEE340AA120C35C4163D7BB3A7BB71077291A8A9F8D7183EA45B0066029D4B3A0A080A1581886E2D42436EFCED167F5F48FDE06DB659AA68F41AA13D12A849408D1B4DEA8BAE08312240D5B63B10963D4583F5CF490AF071B6667936351BCA65D92E44E5964BF3D5277EAF4E1784F317F413692D95EB49990B16A502376DCCA902D49B1E9205DD9E3E1D1B1769C40BCA3B4BF62F48678CDB247E48CA2CB25139D2DD2C5936BB44274361F244685259CB00DE73EA3FC283A5F10A0C7FBA6F444B4B05B37082E22B4411170D497A97626227078E18678676046CECA78A1895B6BBE2F5D6DC3B5B3702D13FE679AD08A52257F48CA0E09708935480FDE8501849B49C30F8AB9EB2301954AABECAE62EFC4F89752B35BF6EDBF41A6A47D73B7BB2F94DB875CC3DC378DDB0478497ED1DFACAF2CD13BB9A6B4508A92B24DC65759A71F407D114ACF42ECC5D85C13EE144F4A89AF1530BC6D058C45C1EE072B6217B7C7ACF5029C706E345FCF74A6B73E834F5D2F21E46CC3412FCF51F45AFD29EE665953242BE8B94030F8F04F90AB5FBD05C60492172C75C0A0CE7A7C02F64E4BBAA9E7ABD1B2511675BACDF566B394263975B59C1065966C2820D147CAD080A191F920E50422C0368DCF1FB9EBF6CE90D996362BBFD4F5D0D2843A1C4076DACBE148B12BE337E5B007DBAE81C14D7B740432054FB78D6EB3A3F66F0CA34731B8F1DC344E6F5028445A787F9604EB69E0B2E31AD925D981CCF61D7D59C5368986509794FD36D22244F9DEFE0B1789D23ACC2592D2C22009D640851493F4671084BBBA3915AA74E0F301C90E83AB5F8859FE8B678F509B85EEBA8223B8D5D979398862C57B13C4D3F090C8DE81B555FC1CEEF0CA9ABB71EE47CF9C67407C1B140227CDEB368ED891498A25113CDAD07282D147FFA02C1F674956F7608B249ECFB0032C2A24C2C6529A7B4C330FA662B8AA76F0D5ED0BDD3D73D73C4F2A0ACA78F119DF34607DDBCCA11777F1B84188FFD5F52F82B68FBBEDE54D312508D3585E4FE1859592A1A6677E9DDDF4CC5D9AFA65C660C78D33499BB4B1B65DB9959ACA16025C33245FC27F01E68AD54C8163D2C62DB9B0513B3125302306092A864886F70D01091531160414F911449A66D4EB3782B37C0B29301F22E4AAA83A":4096 + + +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001 03 +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001:CRYPT_PKEY_ECDSA:"06092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F91D209284686D0515E3F9604CC5C72B02020800300C06082A864886F70D02090500301D060960864801650304012A041088947581FDCE152D6A89157403D7B19404819009BFF0842C15ABE2A5142D56C66B21491A384932C5A512FB1E4EC03CF2B9C47EF06DC3E9DB4A20F548FDA217146CC713FC9CAD482E2AC5BDC8AFD5E81AFAF4D437857554222E2A347A9682CEE3F4B56D1EFC88B885B13FF694C073B758F837AD946B9D67F929031DAE1C94E36C24B431B2ED3CBAFDA8E4223BEEE56D2097D0A10B52FDF9217B9EE9F8F38ED3066E6CBC3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":256 + +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001 04 +SDV_PKCS12_PARSE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001:CRYPT_PKEY_ECDSA:"06092A864886F70D010701A08201AD048201A9308201A5308201A1060B2A864886F70D010C0A0102A082016930820165305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F4F9B23693F39EB5B9BB2D33F7A8D94602020800300C06082A864886F70D02090500301D060960864801650304012A04107A00C173CADA89F014EE4501E1CFC57E04820100B4827E594DEDF86189123486CFE487FCD32CA3FAAC44E33BED3A74A57131029620981C815D38F5EA365B6AD4B620CC1E3685F872265EA436F9E1076B850B3B13C455B1104159076FE98C993C104FB91214A5C3AA3B9F73934623FE8EAD9390E99A3556AF85F25B9ECC285FA279C71F3DD64F8A0A7FF540C55E6C17B6E809C018F338E974A3F330A443B35D5A1A55600DDE9C8DE0DDADB1915061A33D54F4E9812F9217FE685B68D746BE242C6F7B0F4854D82E249B480C935D935CDB6B72B55BF5DF7CE5EB6D12F609E12E2E56E3ED6CE442B7474E39837827C6C718831D18378FE3BF23827FAAC14ACFFBCE20DAB888D0C3A54DF9E3079FA21E2C1B6E6233A33125302306092A864886F70D0109153116041469DC4AA443F5C9C657EF7E9B18CC4130A03A40B8":521 + +SDV_PKCS12_PARSE_SAFEBAGS_OF_CERTBAGS_TC001 01 +SDV_PKCS12_PARSE_SAFEBAGS_OF_CERTBAGS_TC001:"06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563" + +SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC001 01 +SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC001:"301706092A864886F70D010914310A1E08006A006300680078302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3":"006A006300680078":"6A259B9CDCA36597CDDDFB96E09D03E85505B1F3" + +SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC001 02 +SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC001:"302306092A864886F70D0109153116041471A85FC008719B982E72D586EB25AB2F63A5EF4C":"":"71A85FC008719B982E72D586EB25AB2F63A5EF4C" + +SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC002 02 +SDV_PKCS12_PARSE_SAFEBAGS_OF_ATTRIBUTE_TC002:"302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D0065" + +SDV_PKCS12_PARSE_AUTHSAFE_TC001 01 +SDV_PKCS12_PARSE_AUTHSAFE_TC001:"308204EE3082032A06092A864886F70D010706A082031B308203170201003082031006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404101286B6418ACDA7E5684364FB8D06CBBC02020800300C06082A864886F70D02090500301D060960864801650304012A041093C440624F2A5D311AC4CC2F165C32D9808202A00EE13056A7AA9D0D4683C6B718E55828886D3DE891D31735C531C573965656981BF899449C9D2B8FA80E39AD2D382C1FCB96495A5B425A59CFE920C7D32AD5DA1048098AFDB55DF05A4DA3025E433245B159F20BCA17A1A369000000000000F22C0355E8FB133CDA68AE5D5078F391226B017BB809AD6BA60DFD374952D58D82D1D21E2081A320F985509B29ADC50B574A4E29B8E8186B09515465225017BAB9EAB07731DD08673C9DF6BC6F47E2EF0A00B775F28977141F8A3203826E6DCFE30DDC5DBCCFFB2874F705169A8B28E5A7E663259FC357FAC37146516C9F35AC6A781261A1EEFB1505FE0AA0A0A5B6E1504D6A1746085E02BC99FEC7A6BEA18B3D70084099E49798C7F23A9028B00AE43FEF653D87132D0C1AB454837C34EC26270884F6371AB4F7A0B365F19D43F218E2143921C625F9B38F457D31C5E39AAA549F3F7C264B5547DA1F303CD9F3FF3E98EB6AB075C35490EA790CA4CCE9A916A481C085A12668D42E04F88BAEE439EE92ADABE3AAB5B16C550ADDDD97C4381E9C2FC6D1B80F3F1196EA7F31A5BB570E747FFE650FEECE1DA7088A867885BCDA8D134150E081455D34EBA1EBBC775BAF3D45BA7103C15A39B3972B37948F2795EEB5C4F33AB25DBA2D76AC84FAD70109E01122C7C5870D4A86F92066792FE358C8E425D3E530D4A1F7B7AD0231D7BD6AAD1CA82D26DE08F3FFCF62A4C972B18BF34114DFFD62DD2AD6FE8BA8B324EDE9D8CF39244A0658A4BB84C8A0876C870C4CF212C9931B430215254F84135E4363E31DA592D6043573073C0E4BA6A8113B65DC4220E26CD00A534C21C90945DF6AD68E1EB00F62540311A428C05EE5F8C709DC49A7819E35A7193B29DA4F18DDA4E7431CF2CA67240C9758A670A71263019CBB0763A5FA61C01F77591A24E2AACCDC695FF50CCAE0086ECB6D42B465682D1D308201BC06092A864886F70D010701A08201AD048201A9308201A5308201A1060B2A864886F70D010C0A0102A082016930820165305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F4F9B23693F39EB5B9BB2D33F7A8D94602020800300C06082A864886F70D02090500301D060960864801650304012A04107A00C173CADA89F014EE4501E1CFC57E04820100B4827E594DEDF86189123486CFE487FCD32CA3FAAC44E33BED3A74A57131029620981C815D38F5EA365B6AD4B620CC1E3685F872265EA436F9E1076B850B3B13C455B1104159076FE98C993C104FB91214A5C3AA3B9F73934623FE8EAD9390E99A3556AF85F25B9ECC285FA279C71F3DD64F8A0A7FF540C55E6C17B6E809C018F338E974A3F330A443B35D5A1A55600DDE9C8DE0DDADB1915061A33D54F4E9812F9217FE685B68D746BE242C6F7B0F4854D82E249B480C935D935CDB6B72B55BF5DF7CE5EB6D12F609E12E2E56E3ED6CE442B7474E39837827C6C718831D18378FE3BF23827FAAC14ACFFBCE20DAB888D0C3A54DF9E3079FA21E2C1B6E6233A33125302306092A864886F70D0109153116041469DC4AA443F5C9C657EF7E9B18CC4130A03A40B8" + +SDV_PKCS12_PARSE_AUTHSAFE_TC002 01 +SDV_PKCS12_PARSE_AUTHSAFE_TC002:"3082111530820B5A06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563308205B306092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D0065" + +SDV_PKCS12_PARSE_AUTHSAFE_TC002 02 +SDV_PKCS12_PARSE_AUTHSAFE_TC002:"308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404107ADE28DE60883CF3A1B12661D26ACD6602020800300C06082A864886F70D02090500301D060960864801650304012A041041980DBF42C62C55FE2275EE8B98666C808202104502DC74FAD09DC7C03A3EDDD5A9F257CB3496E05DAD27E1BE1148F2B6C94C300DDED464D02BD404FC4CC205705CF8015B5FD5633E868C505B8926BD05A06AE346E57D9BC8578EF39A5272ECB8C51D9ECEC895CAFE7BE90BCF9FBEB3B74F0044C3FED90B9DE1ACE42623A7D2598E6D4E96266516F50237B80164662E8F231F41E30B117D6C237672DB80486422F95B0FC0EB4B31BE7EC05B1244904A0DA144A1F2F7EAB4BDE34E7A1F47D4C3E50584AA22AFB8D1CBEF97BC783377E3249354961FB51CF990BB7A9AC09234BB4C6981FF0FBD6042B2938BE71182DECED149F748F8D90C082E178DD95FA1F4FEF6D4C8CE8C050C08279B240414BB55DD622B4944A22333D7DDA0AFCEB3DBB2DAC43D0CD26657A5613E93C9F1D041DBC867300F0B5249BAB3A629AAD99100790AC12FC6AE09B8A01B9162E22F1E208F6D93B4BCBCECD728686C9CD43B7D004CC6540E917309B1C45FD02616A75F54CBD8044B83C2806C68F0197C6BACAE72A8390C3CC9706943A2C9E7D5940A7039FE315D5600E67125B08F27A851CB24B22C9CE25C14F9F3795E7CBA518DC8756DE501980E86FCA024E5FAF04B24BC36F5339B9D61F7E92BEA90ADFA6042169D611121F84BEF7E173E79B21A03124A321507676A500EC0BFCB1CD2B2A08E63CF99283AC1AD07226CD406531A45454FB4B92B9FC7FA1B4A2BA3EC0B9757330FA42F3BBFF91E4EEF33B8C3F10670BAA26701B6629F6402F13082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F91D209284686D0515E3F9604CC5C72B02020800300C06082A864886F70D02090500301D060960864801650304012A041088947581FDCE152D6A89157403D7B19404819009BFF0842C15ABE2A5142D56C66B21491A384932C5A512FB1E4EC03CF2B9C47EF06DC3E9DB4A20F548FDA217146CC713FC9CAD482E2AC5BDC8AFD5E81AFAF4D437857554222E2A347A9682CEE3F4B56D1EFC88B885B13FF694C073B758F837AD946B9D67F929031DAE1C94E36C24B431B2ED3CBAFDA8E4223BEEE56D2097D0A10B52FDF9217B9EE9F8F38ED3066E6CBC3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D" + +SDV_PKCS12_PARSE_AUTHSAFE_TC002 03 +SDV_PKCS12_PARSE_AUTHSAFE_TC002:"308204EE3082032A06092A864886F70D010706A082031B308203170201003082031006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404101286B6418ACDA7E5684364FB8D06CBBC02020800300C06082A864886F70D02090500301D060960864801650304012A041093C440624F2A5D311AC4CC2F165C32D9808202A00EE13056A7AA9D0D4683C6B718E55828886D3DE891D31735C531C573965656981BF899449C9D2B8FA80E39AD2D382C1FCB96495A5B425A59CFE920C7D32AD5DA1048098AFDB55DF05A4DA3025E433245B159F20BCA17A1A369325484AD540BF22C0355E8FB133CDA68AE5D5078F391226B017BB809AD6BA60DFD374952D58D82D1D21E2081A320F985509B29ADC50B574A4E29B8E8186B09515465225017BAB9EAB07731DD08673C9DF6BC6F47E2EF0A00B775F28977141F8A3203826E6DCFE30DDC5DBCCFFB2874F705169A8B28E5A7E663259FC357FAC37146516C9F35AC6A781261A1EEFB1505FE0AA0A0A5B6E1504D6A1746085E02BC99FEC7A6BEA18B3D70084099E49798C7F23A9028B00AE43FEF653D87132D0C1AB454837C34EC26270884F6371AB4F7A0B365F19D43F218E2143921C625F9B38F457D31C5E39AAA549F3F7C264B5547DA1F303CD9F3FF3E98EB6AB075C35490EA790CA4CCE9A916A481C085A12668D42E04F88BAEE439EE92ADABE3AAB5B16C550ADDDD97C4381E9C2FC6D1B80F3F1196EA7F31A5BB570E747FFE650FEECE1DA7088A867885BCDA8D134150E081455D34EBA1EBBC775BAF3D45BA7103C15A39B3972B37948F2795EEB5C4F33AB25DBA2D76AC84FAD70109E01122C7C5870D4A86F92066792FE358C8E425D3E530D4A1F7B7AD0231D7BD6AAD1CA82D26DE08F3FFCF62A4C972B18BF34114DFFD62DD2AD6FE8BA8B324EDE9D8CF39244A0658A4BB84C8A0876C870C4CF212C9931B430215254F84135E4363E31DA592D6043573073C0E4BA6A8113B65DC4220E26CD00A534C21C90945DF6AD68E1EB00F62540311A428C05EE5F8C709DC49A7819E35A7193B29DA4F18DDA4E7431CF2CA67240C9758A670A71263019CBB0763A5FA61C01F77591A24E2AACCDC695FF50CCAE0086ECB6D42B465682D1D308201BC06092A864886F70D010701A08201AD048201A9308201A5308201A1060B2A864886F70D010C0A0102A082016930820165305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F4F9B23693F39EB5B9BB2D33F7A8D94602020800300C06082A864886F70D02090500301D060960864801650304012A04107A00C173CADA89F014EE4501E1CFC57E04820100B4827E594DEDF86189123486CFE487FCD32CA3FAAC44E33BED3A74A57131029620981C815D38F5EA365B6AD4B620CC1E3685F872265EA436F9E1076B850B3B13C455B1104159076FE98C993C104FB91214A5C3AA3B9F73934623FE8EAD9390E99A3556AF85F25B9ECC285FA279C71F3DD64F8A0A7FF540C55E6C17B6E809C018F338E974A3F330A443B35D5A1A55600DDE9C8DE0DDADB1915061A33D54F4E9812F9217FE685B68D746BE242C6F7B0F4854D82E249B480C935D935CDB6B72B55BF5DF7CE5EB6D12F609E12E2E56E3ED6CE442B7474E39837827C6C718831D18378FE3BF23827FAAC14ACFFBCE20DAB888D0C3A54DF9E3079FA21E2C1B6E6233A33125302306092A864886F70D0109153116041469DC4AA443F5C9C657EF7E9B18CC4130A03A40B8" + +SDV_PKCS12_PARSE_MACDATA_TC001 01 +SDV_PKCS12_PARSE_MACDATA_TC001:"3031300D060960864801650304020105000420998A44721144E4DF222EFAD617410A1D1C27A90A33CEF118579474F20D0ED4EF04088709BC4E53E1D2E302020800":BSL_CID_SHA256:"998a44721144e4df222efad617410a1d1c27a90a33cef118579474f20d0ed4ef":"8709bc4e53e1d2e3":2048 + +SDV_PKCS12_PARSE_MACDATA_TC001 02 +SDV_PKCS12_PARSE_MACDATA_TC001:"3031300D0609608648016503040201050004208F94A4088463B8A284BD19F8EDA65D14541C9656F61309C4F3DD6F7C1D12A56B040895C8BA34D38B959802020800":BSL_CID_SHA256:"8F94A4088463B8A284BD19F8EDA65D14541C9656F61309C4F3DD6F7C1D12A56B":"95c8ba34d38b9598":2048 + +SDV_PKCS12_PARSE_MACDATA_TC001 03 +SDV_PKCS12_PARSE_MACDATA_TC001:"3031300D0609608648016503040201050004202A24071EE7DFC491A3CA074557363BC0A94467FF0E5AC118B8365453DE771CDE04082D72140E2995992E02020800":BSL_CID_SHA256:"2A24071EE7DFC491A3CA074557363BC0A94467FF0E5AC118B8365453DE771CDE":"2d72140e2995992e":2048 + +SDV_PKCS12_PARSE_MACDATA_TC002 01 +SDV_PKCS12_PARSE_MACDATA_TC002:"3051300D06096086480165030400000500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800" + +SDV_PKCS12_CAL_MACDATA_TC001 01 +SDV_PKCS12_CAL_MACDATA_TC001:"3082111530820B5A06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563308205B306092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D0065":"ed47d6a67b245984":BSL_CID_SHA256:2048:"f47ec9e868b0b9b3144d41744592ad8717f83dade153bfd1f3e01251ac9450b2" + +SDV_PKCS12_CAL_MACDATA_TC001 02 +SDV_PKCS12_CAL_MACDATA_TC001:"308204EE3082032A06092A864886F70D010706A082031B308203170201003082031006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404101286B6418ACDA7E5684364FB8D06CBBC02020800300C06082A864886F70D02090500301D060960864801650304012A041093C440624F2A5D311AC4CC2F165C32D9808202A00EE13056A7AA9D0D4683C6B718E55828886D3DE891D31735C531C573965656981BF899449C9D2B8FA80E39AD2D382C1FCB96495A5B425A59CFE920C7D32AD5DA1048098AFDB55DF05A4DA3025E433245B159F20BCA17A1A369325484AD540BF22C0355E8FB133CDA68AE5D5078F391226B017BB809AD6BA60DFD374952D58D82D1D21E2081A320F985509B29ADC50B574A4E29B8E8186B09515465225017BAB9EAB07731DD08673C9DF6BC6F47E2EF0A00B775F28977141F8A3203826E6DCFE30DDC5DBCCFFB2874F705169A8B28E5A7E663259FC357FAC37146516C9F35AC6A781261A1EEFB1505FE0AA0A0A5B6E1504D6A1746085E02BC99FEC7A6BEA18B3D70084099E49798C7F23A9028B00AE43FEF653D87132D0C1AB454837C34EC26270884F6371AB4F7A0B365F19D43F218E2143921C625F9B38F457D31C5E39AAA549F3F7C264B5547DA1F303CD9F3FF3E98EB6AB075C35490EA790CA4CCE9A916A481C085A12668D42E04F88BAEE439EE92ADABE3AAB5B16C550ADDDD97C4381E9C2FC6D1B80F3F1196EA7F31A5BB570E747FFE650FEECE1DA7088A867885BCDA8D134150E081455D34EBA1EBBC775BAF3D45BA7103C15A39B3972B37948F2795EEB5C4F33AB25DBA2D76AC84FAD70109E01122C7C5870D4A86F92066792FE358C8E425D3E530D4A1F7B7AD0231D7BD6AAD1CA82D26DE08F3FFCF62A4C972B18BF34114DFFD62DD2AD6FE8BA8B324EDE9D8CF39244A0658A4BB84C8A0876C870C4CF212C9931B430215254F84135E4363E31DA592D6043573073C0E4BA6A8113B65DC4220E26CD00A534C21C90945DF6AD68E1EB00F62540311A428C05EE5F8C709DC49A7819E35A7193B29DA4F18DDA4E7431CF2CA67240C9758A670A71263019CBB0763A5FA61C01F77591A24E2AACCDC695FF50CCAE0086ECB6D42B465682D1D308201BC06092A864886F70D010701A08201AD048201A9308201A5308201A1060B2A864886F70D010C0A0102A082016930820165305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F4F9B23693F39EB5B9BB2D33F7A8D94602020800300C06082A864886F70D02090500301D060960864801650304012A04107A00C173CADA89F014EE4501E1CFC57E04820100B4827E594DEDF86189123486CFE487FCD32CA3FAAC44E33BED3A74A57131029620981C815D38F5EA365B6AD4B620CC1E3685F872265EA436F9E1076B850B3B13C455B1104159076FE98C993C104FB91214A5C3AA3B9F73934623FE8EAD9390E99A3556AF85F25B9ECC285FA279C71F3DD64F8A0A7FF540C55E6C17B6E809C018F338E974A3F330A443B35D5A1A55600DDE9C8DE0DDADB1915061A33D54F4E9812F9217FE685B68D746BE242C6F7B0F4854D82E249B480C935D935CDB6B72B55BF5DF7CE5EB6D12F609E12E2E56E3ED6CE442B7474E39837827C6C718831D18378FE3BF23827FAAC14ACFFBCE20DAB888D0C3A54DF9E3079FA21E2C1B6E6233A33125302306092A864886F70D0109153116041469DC4AA443F5C9C657EF7E9B18CC4130A03A40B8":"95c8ba34d38b9598":BSL_CID_SHA256:2048:"8F94A4088463B8A284BD19F8EDA65D14541C9656F61309C4F3DD6F7C1D12A56B" + +SDV_PKCS12_CAL_MACDATA_TC001 03 +SDV_PKCS12_CAL_MACDATA_TC001:"308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404107ADE28DE60883CF3A1B12661D26ACD6602020800300C06082A864886F70D02090500301D060960864801650304012A041041980DBF42C62C55FE2275EE8B98666C808202104502DC74FAD09DC7C03A3EDDD5A9F257CB3496E05DAD27E1BE1148F2B6C94C300DDED464D02BD404FC4CC205705CF8015B5FD5633E868C505B8926BD05A06AE346E57D9BC8578EF39A5272ECB8C51D9ECEC895CAFE7BE90BCF9FBEB3B74F0044C3FED90B9DE1ACE42623A7D2598E6D4E96266516F50237B80164662E8F231F41E30B117D6C237672DB80486422F95B0FC0EB4B31BE7EC05B1244904A0DA144A1F2F7EAB4BDE34E7A1F47D4C3E50584AA22AFB8D1CBEF97BC783377E3249354961FB51CF990BB7A9AC09234BB4C6981FF0FBD6042B2938BE71182DECED149F748F8D90C082E178DD95FA1F4FEF6D4C8CE8C050C08279B240414BB55DD622B4944A22333D7DDA0AFCEB3DBB2DAC43D0CD26657A5613E93C9F1D041DBC867300F0B5249BAB3A629AAD99100790AC12FC6AE09B8A01B9162E22F1E208F6D93B4BCBCECD728686C9CD43B7D004CC6540E917309B1C45FD02616A75F54CBD8044B83C2806C68F0197C6BACAE72A8390C3CC9706943A2C9E7D5940A7039FE315D5600E67125B08F27A851CB24B22C9CE25C14F9F3795E7CBA518DC8756DE501980E86FCA024E5FAF04B24BC36F5339B9D61F7E92BEA90ADFA6042169D611121F84BEF7E173E79B21A03124A321507676A500EC0BFCB1CD2B2A08E63CF99283AC1AD07226CD406531A45454FB4B92B9FC7FA1B4A2BA3EC0B9757330FA42F3BBFF91E4EEF33B8C3F10670BAA26701B6629F6402F13082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F91D209284686D0515E3F9604CC5C72B02020800300C06082A864886F70D02090500301D060960864801650304012A041088947581FDCE152D6A89157403D7B19404819009BFF0842C15ABE2A5142D56C66B21491A384932C5A512FB1E4EC03CF2B9C47EF06DC3E9DB4A20F548FDA217146CC713FC9CAD482E2AC5BDC8AFD5E81AFAF4D437857554222E2A347A9682CEE3F4B56D1EFC88B885B13FF694C073B758F837AD946B9D67F929031DAE1C94E36C24B431B2ED3CBAFDA8E4223BEEE56D2097D0A10B52FDF9217B9EE9F8F38ED3066E6CBC3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"2d72140e2995992e":BSL_CID_SHA256:2048:"2A24071EE7DFC491A3CA074557363BC0A94467FF0E5AC118B8365453DE771CDE" + +SDV_PKCS12_CAL_MACDATA_TC001 04 +SDV_PKCS12_CAL_MACDATA_TC001:"308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363D6372FECBCDAA375463EB303B36006110114BBF3344775D89272689D1C78F6875F0492E5A641738F6B1E981196DE4021DE863BF1A53B00BF61C9E7167A881C28614000CFB03AB6DC6582B1C35E6486C6B1FED600D6BA6227E2FDBFBA4C0A80294A7B4B763749FCDF09ECD9BC72957EC288C7ED3DBFE84162E2654DEEE4F4678A80EFCA90A587D09EE00B6662E327F2173ABE800DCFE9CC3835EF4C96CF398C8E8A131477B1377F3960453494DE6020679FBE27FA5B1FAFE622E5953515E50E87369DD7A07F44267D925FDAAD1B970FF76078A9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF291932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"eaa807dc1e56f04b":BSL_CID_SHA512:2048:"37463ef2b29be402ceba4a9320f1615183a3dc3cfed7ed86889593d95a4da6f7d1a710037e345f048379b98a75039036a2b43522b33d6fb1670538413c57ba69" + +SDV_PKCS12_CAL_MACDATA_TC001 05 +SDV_PKCS12_CAL_MACDATA_TC001:"308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"9f1708bd9e2ce4e3":BSL_CID_SHA224:2048:"db9eaab4df8754682737219b38b1f3c85310923b443dba27ce548fa6" + +SDV_PKCS12_CAL_MACDATA_TC001 06 +SDV_PKCS12_CAL_MACDATA_TC001:"308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041072C2AB19B9C84B1F8939C4952FF9146C02020800300C06082A864886F70D02090500301D060960864801650304012A0410E6F355A75780A764D528178C55EFD39480820210BFC3C2AC636A066D8649B8F9B917D8821C720AFF1F536E55BCDB7854FA5E2534445352A2DE2682A7BC38820A843C165552A642702BD9363956F49CFC5143B7ADA7C9A11191C52A9BC0AF2C1398CF2146558C756F6CCB2952616BA761B9F15BBF333130AE91BF3E5459D88B65101EF14540D5B1B11B5A24E3F06D2D983094EE95032E0D2F8E742E269CC15FE03599AE56C33B5E2577332BD9D23C7E83A819F07B5074F62AAD557044B15DEAC9734A930466B812C7746F3DE993C9EDCC1A567D2429E77240D05E311D2C4168AB9DF78BF5820C19D1AE47AE1BAE0F5C51AFEE2682FEE5C495CE1DBE0C993655C2E4C3C5F065106E3BCCA730A9A4090F228677E8DED2F7CD17D6F50EF72FF3DB6B11656A254D0B284019E2EE1AF522E4EAB26CEBA7E8774227FAFCC6E9F79BD135FB6558D406148E12008BADDF4E44D672826F32F5D57F8EA07A106F92F2D7F495E3BD26961991B4657F93347A75D5CFD9FF9C6ABB6E21F43CC86E4BEB0DCDE8EEED1A35CA2AAD2F7CF5AA8223317319DA51CEFD35EA498BBCEDA136C9E58975363FAF00152F7E269D94150ED10949E59493CE2FB15EB53D0194D3F2C8E8526B6F9C5213B8EDB9C9BD1C81E7A023F9B2DD8028791A1C5A8B727151C17055A1AC01923AEE6C4EBD94D009DFA0EEBCD5867199D5CC52E1AC13EE1A34B84015E01906D321A6054EAAF6CD24B53915ACE1691533C3FCE500E61479A0EC41218BA83E2E588095933082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410A3ADF3FF868A959459D683B1DCE37C0302020800300C06082A864886F70D02090500301D060960864801650304012A0410C8D39ACFC20EF5769A9AB45C2E90252504819025CE12A4383CC164F658282490C614AA9E3D2CC05ED92175A43C742A0CB099DF8648C5C4F715D6CAFB8D78F7C5B55966FFBEC70FBB44FE729248508C5650F62295FEAD88E0C3088242A28DD599A9AD2ECDEBDB106E458F711FB724493D261E811B1A33FA2E59B76AEBD4F7CD98C129897C200D98DD3B82259CD968C619B89039A9A552EBBBD830E096C6499438D022ED3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"e12f596e63d6bfe6":BSL_CID_SHA384:2048:"c2b9209605b8a54bb773a84953af5a5afd4a1f79ca0006f260d8267c1352ff02fd541d8896e5aaf38e805f81772169fa" + +SDV_PKCS12_CAL_KDF_TC001 01 +SDV_PKCS12_CAL_KDF_TC001:"0031003200330034003500360000":"ed47d6a67b245984":BSL_CID_SHA256:2048:"b08f3dad67e2abb1f83b1ba776c62cb969c1b50084126a3484fd9359e2934f4b" + +SDV_PKCS12_PARSE_P12_TC001 01 +SDV_PKCS12_PARSE_P12_TC001:"308211760201033082112C06092A864886F70D010701A082111D048211193082111530820B5A06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563308205B306092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D006530413031300D060960864801650304020105000420F47EC9E868B0B9B3144D41744592AD8717F83DADE153BFD1F3E01251AC9450B20408ED47D6A67B24598402020800":"3082046F30820257A003020102020101300D06092A864886F70D01010B05003054310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464310D300B06035504030C046A636878301E170D3234303931333033353033355A170D3334303931313033353033355A3053310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464310C300A06035504030C0363637130820122300D06092A864886F70D01010105000382010F003082010A0282010100D559E50B3AD2B209DDD25C134476354889EF1C565012186804D6426A6E0DAE29743BD96C6638F231EA1EED05FAA7AB5FCD33AFD6258A85B1F138FD8C7C623BD9AF2FC6DD3C4F3AB4D62821DC43B5FDB0A62B2A2C7965C454D78F53A1CB8A7F48EF7655B96EE4FCCBAF7B5414D8D622A9DE3B3DFD6B85927C08D023FF25570F1AEED6F0BEA3BA5F372E1DEB6E1790CB27CDA1EF474196927C568B1D24E722AF3C2377A7BB980A490E34C230D056859443CF9BB14C0EC188D11F835FF0EECD248C60933C8FF7A769856F43605816BE84FD84325A4D670089FFE4571EC340B0DECF9977D051CCA656B393678AF5E33808B6394F9F6A1ADB0F61ABB09A3F3A5482770203010001A34D304B30090603551D1304023000301D0603551D0E0416041427DE49E413C3B3591139F07292C5136553543CB1301F0603551D23041830168014293F24092D3263DAB12EB763ABB7A13AF0891677300D06092A864886F70D01010B05000382020100A778F1346DC6200F441EF6889491AA73557067A76686C122BD361B285344BD542C218077B8254C1479CEA9C764EA7B6A9B1BB577EA163CAE3403A0529DF099FCC27E2236CA69D4E2AF57797E7FFC09FEC7A5444CEA6B0BE1A2081BC1A9D114DBD3A1384D39ACDBBE198B953C1D0ECAB06517CD0356FB9F16FA3CF40550EF7384084437EE9C8E17A01E397EDB4A23A181F79BEBAF0901F88B1E4DCB86CD5B28265C8D30D7C7DDFB4B3242D20517D9AB37A5CAD1E30D57655739B3239F558019E2B4AAF5ACA05365A9B44630892BC86872617718E41671623B2DFE77610D829C6D3CC94227CFA69550585660DC468758E6D8DE981B20C403A568193C4140A4CCCC7572A7F106FEA51451E0A9C3754DA410D4895E61253D8FD007DA320306498DBF7E1CAF881127B8DA9B25EF39A002B7D9F0AB2E44B636BB468A74EED63624B924BF20D296330F9901960F3E2FC729ED5C0C84BEC4AFD05650D2F3B45342257DCD3EF5608282C2F297962EC48E39E9AF44993FD364600281A6358E9879EEA5F79C7C282315A4207A24B075F91076BB59A4AFB74CD4B07DE215B0EB45D26E2335DFAB4E349EC8BD05C8D8675F5DD12F6A98DD19636C65FB8DF97B75A4AF0FB2DEF20A99D63692D7C7652EB29BBB21659BE1A3EF0A55035F85CE6D41DD64C355D17571A3E05CB2B717DF9DD71453E240A06AB58A2715FC184DC8A3146886151B698C" + +SDV_PKCS12_PARSE_P12_TC001 02 +SDV_PKCS12_PARSE_P12_TC001:"3082046C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363D6372FECBCDAA375463EB303B36006110114BBF3344775D89272689D1C78F6875F0492E5A641738F6B1E981196DE4021DE863BF1A53B00BF61C9E7167A881C28614000CFB03AB6DC6582B1C35E6486C6B1FED600D6BA6227E2FDBFBA4C0A80294A7B4B763749FCDF09ECD9BC72957EC288C7ED3DBFE84162E2654DEEE4F4678A80EFCA90A587D09EE00B6662E327F2173ABE800DCFE9CC3835EF4C96CF398C8E8A131477B1377F3960453494DE6020679FBE27FA5B1FAFE622E5953515E50E87369DD7A07F44267D925FDAAD1B970FF76078A9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF291932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30613051300D06096086480165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_PARSE_P12_TC001 03 +SDV_PKCS12_PARSE_P12_TC001:"308204480201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D303D302D300D06096086480165030402040500041CDB9EAAB4DF8754682737219B38B1F3C85310923B443DBA27CE548FA604089F1708BD9E2CE4E302020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_PARSE_P12_TC001 04 +SDV_PKCS12_PARSE_P12_TC001:"308204480201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D303D302D300D06096086480165030402040500041CDB9EAAB4DF8754682737219B38B1F3C85310923B443DBA27CE548FA604089F1708BD9E2CE4E302020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_PARSE_P12_TC001 05 +SDV_PKCS12_PARSE_P12_TC001:"3082045C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041072C2AB19B9C84B1F8939C4952FF9146C02020800300C06082A864886F70D02090500301D060960864801650304012A0410E6F355A75780A764D528178C55EFD39480820210BFC3C2AC636A066D8649B8F9B917D8821C720AFF1F536E55BCDB7854FA5E2534445352A2DE2682A7BC38820A843C165552A642702BD9363956F49CFC5143B7ADA7C9A11191C52A9BC0AF2C1398CF2146558C756F6CCB2952616BA761B9F15BBF333130AE91BF3E5459D88B65101EF14540D5B1B11B5A24E3F06D2D983094EE95032E0D2F8E742E269CC15FE03599AE56C33B5E2577332BD9D23C7E83A819F07B5074F62AAD557044B15DEAC9734A930466B812C7746F3DE993C9EDCC1A567D2429E77240D05E311D2C4168AB9DF78BF5820C19D1AE47AE1BAE0F5C51AFEE2682FEE5C495CE1DBE0C993655C2E4C3C5F065106E3BCCA730A9A4090F228677E8DED2F7CD17D6F50EF72FF3DB6B11656A254D0B284019E2EE1AF522E4EAB26CEBA7E8774227FAFCC6E9F79BD135FB6558D406148E12008BADDF4E44D672826F32F5D57F8EA07A106F92F2D7F495E3BD26961991B4657F93347A75D5CFD9FF9C6ABB6E21F43CC86E4BEB0DCDE8EEED1A35CA2AAD2F7CF5AA8223317319DA51CEFD35EA498BBCEDA136C9E58975363FAF00152F7E269D94150ED10949E59493CE2FB15EB53D0194D3F2C8E8526B6F9C5213B8EDB9C9BD1C81E7A023F9B2DD8028791A1C5A8B727151C17055A1AC01923AEE6C4EBD94D009DFA0EEBCD5867199D5CC52E1AC13EE1A34B84015E01906D321A6054EAAF6CD24B53915ACE1691533C3FCE500E61479A0EC41218BA83E2E588095933082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410A3ADF3FF868A959459D683B1DCE37C0302020800300C06082A864886F70D02090500301D060960864801650304012A0410C8D39ACFC20EF5769A9AB45C2E90252504819025CE12A4383CC164F658282490C614AA9E3D2CC05ED92175A43C742A0CB099DF8648C5C4F715D6CAFB8D78F7C5B55966FFBEC70FBB44FE729248508C5650F62295FEAD88E0C3088242A28DD599A9AD2ECDEBDB106E458F711FB724493D261E811B1A33FA2E59B76AEBD4F7CD98C129897C200D98DD3B82259CD968C619B89039A9A552EBBBD830E096C6499438D022ED3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30513041300D060960864801650304020205000430C2B9209605B8A54BB773A84953AF5A5AFD4A1F79CA0006F260D8267C1352FF02FD541D8896E5AAF38E805F81772169FA0408E12F596E63D6BFE602020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_PARSE_P12_TC002 01 +SDV_PKCS12_PARSE_P12_TC002:"3082038C0201033082038506092A864886F70D010701A0820376048203723082036E3082021D06092A864886F70D010701A082020E0482020A3082020630820202060B2A864886F70D010C0A0103A08201CA308201C6060A2A864886F70D01091601A08201B6048201B2308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041058583887C10018533C8C34DB564352F102020800300C06082A864886F70D02090500301D060960864801650304012A04108F24DFFC94EA7EAF3DD1EECE71CD51E8048190756570F11FC369E9FDE46C319B5F4C90B7E4101C7BE38CD717DCD98AFA7C93BDDDB569A7F73C5F37F9E86750149DD1949AD06AD0703F021CC6D2305F9BCEFB73DD827EC1C431C5C8E5FC7749F9EB75B91DF8F900721A478706285DCB0DC502FC7787355396D6680C48D62EB07A6309A55A717CF7673B03EA6A99EB47364FE17D96AFDC090D5550DA41CF0778CA7110D73125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_PARSE_P12_WRONG_CONDITIONS_TC001 01 +SDV_PKCS12_PARSE_P12_WRONG_CONDITIONS_TC001:"3082054F0201033082050506092A864886F70D010701A08204F6048204F2308204EE3082032A06092A864886F70D010706A082031B308203170201003082031006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404101286B6418ACDA7E5684364FB8D06CBBC02020800300C06082A864886F70D02090500301D060960864801650304012A041093C440624F2A5D311AC4CC2F165C32D9808202A00EE13056A7AA9D0D4683C6B718E55828886D3DE891D31735C531C573965656981BF899449C9D2B8FA80E39AD2D382C1FCB96495A5B425A59CFE920C7D32AD5DA1048098AFDB55DF05A4DA3025E433245B159F20BCA17A1A369325484AD540BF22C0355E8FB133CDA68AE5D5078F391226B017BB809AD6BA60DFD374952D58D82D1D21E2081A320F985509B29ADC50B574A4E29B8E8186B09515465225017BAB9EAB07731DD08673C9DF6BC6F47E2EF0A00B775F28977141F8A3203826E6DCFE30DDC5DBCCFFB2874F705169A8B28E5A7E663259FC357FAC37146516C9F35AC6A781261A1EEFB1505FE0AA0A0A5B6E1504D6A1746085E02BC99FEC7A6BEA18B3D70084099E49798C7F23A9028B00AE43FEF653D87132D0C1AB454837C34EC26270884F6371AB4F7A0B365F19D43F218E2143921C625F9B38F457D31C5E39AAA549F3F7C264B5547DA1F303CD9F3FF3E98EB6AB075C35490EA790CA4CCE9A916A481C085A12668D42E04F88BAEE439EE92ADABE3AAB5B16C550ADDDD97C4381E9C2FC6D1B80F3F1196EA7F31A5BB570E747FFE650FEECE1DA7088A867885BCDA8D134150E081455D34EBA1EBBC775BAF3D45BA7103C15A39B3972B37948F2795EEB5C4F33AB25DBA2D76AC84FAD70109E01122C7C5870D4A86F92066792FE358C8E425D3E530D4A1F7B7AD0231D7BD6AAD1CA82D26DE08F3FFCF62A4C972B18BF34114DFFD62DD2AD6FE8BA8B324EDE9D8CF39244A0658A4BB84C8A0876C870C4CF212C9931B430215254F84135E4363E31DA592D6043573073C0E4BA6A8113B65DC4220E26CD00A534C21C90945DF6AD68E1EB00F62540311A428C05EE5F8C709DC49A7819E35A7193B29DA4F18DDA4E7431CF2CA67240C9758A670A71263019CBB0763A5FA61C01F77591A24E2AACCDC695FF50CCAE0086ECB6D42B465682D1D308201BC06092A864886F70D010701A08201AD048201A9308201A5308201A1060B2A864886F70D010C0A0102A082016930820165305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F4F9B23693F39EB5B9BB2D33F7A8D94602020800300C06082A864886F70D02090500301D060960864801650304012A04107A00C173CADA89F014EE4501E1CFC57E04820100B4827E594DEDF86189123486CFE487FCD32CA3FAAC44E33BED3A74A57131029620981C815D38F5EA365B6AD4B620CC1E3685F872265EA436F9E1076B850B3B13C455B1104159076FE98C993C104FB91214A5C3AA3B9F73934623FE8EAD9390E99A3556AF85F25B9ECC285FA279C71F3DD64F8A0A7FF540C55E6C17B6E809C018F338E974A3F330A443B35D5A1A55600DDE9C8DE0DDADB1915061A33D54F4E9812F9217FE685B68D746BE242C6F7B0F4854D82E249B480C935D935CDB6B72B55BF5DF7CE5EB6D12F609E12E2E56E3ED6CE442B7474E39837827C6C718831D18378FE3BF23827FAAC14ACFFBCE20DAB888D0C3A54DF9E3079FA21E2C1B6E6233A33125302306092A864886F70D0109153116041469DC4AA443F5C9C657EF7E9B18CC4130A03A40B830413031300D0609608648016503040201050004208F94A4088463B8A284BD19F8EDA65D14541C9656F61309C4F3DD6F7C1D12A56B040895C8BA34D38B959802020800" + +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC001 01 +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC001:"3082054F0201033082050506092A864886F70D010701A08204F6048204F2308204EE3082032A06092A864886F70D010706A082031B308203170201003082031006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404101286B6418ACDA7E5684364FB8D06CBBC02020800300C06082A864886F70D02090500301D060960864801650304012A041093C440624F2A5D311AC4CC2F165C32D9808202A00EE13056A7AA9D0D4683C6B718E55828886D3DE891D31735C531C573965656981BF899449C9D2B8FA80E39AD2D382C1FCB96495A5B425A59CFE920C7D32AD5DA1048098AFDB55DF05A4DA3025E433245B159F20BCA17A1A369325484AD540BF22C0355E8FB133CDA68AE5D5078F391226B017BB809AD6BA60DFD374952D58D82D1D21E2081A320F985509B29ADC50B574A4E29B8E8186B09515465225017BAB9EAB07731DD08673C9DF6BC6F47E2EF0A00B775F28977141F8A3203826E6DCFE30DDC5DBCCFFB2874F705169A8B28E5A7E663259FC357FAC37146516C9F35AC6A781261A1EEFB1505FE0AA0A0A5B6E1504D6A1746085E02BC99FEC7A6BEA18B3D70084099E49798C7F23A9028B00AE43FEF653D87132D0C1AB454837C34EC26270884F6371AB4F7A0B365F19D43F218E2143921C625F9B38F457D31C5E39AAA549F3F7C264B5547DA1F303CD9F3FF3E98EB6AB075C35490EA790CA4CCE9A916A481C085A12668D42E04F88BAEE439EE92ADABE3AAB5B16C550ADDDD97C4381E9C2FC6D1B80F3F1196EA7F31A5BB570E747FFE650FEECE1DA7088A867885BCDA8D134150E081455D34EBA1EBBC775BAF3D45BA7103C15A39B3972B37948F2795EEB5C4F33AB25DBA2D76AC84FAD70109E01122C7C5870D4A86F92066792FE358C8E425D3E530D4A1F7B7AD0231D7BD6AAD1CA82D26DE08F3FFCF62A4C972B18BF34114DFFD62DD2AD6FE8BA8B324EDE9D8CF39244A0658A4BB84C8A0876C870C4CF212C9931B430215254F84135E4363E31DA592D6043573073C0E4BA6A8113B65DC4220E26CD00A534C21C90945DF6AD68E1EB00F62540311A428C05EE5F8C709DC49A7819E35A7193B29DA4F18DDA4E7431CF2CA67240C9758A670A71263019CBB0763A5FA61C01F77591A24E2AACCDC695FF50CCAE0086ECB6D42B465682D1D308201BC06092A864886F70D010701A08201AD048201A9308201A5308201A1060B2A864886F70D010C0A0102A082016930820165305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410F4F9B23693F39EB5B9BB2D33F7A8D94602020800300C06082A864886F70D02090500301D060960864801650304012A04107A00C173CADA89F014EE4501E1CFC57E04820100B4827E594DEDF86189123486CFE487FCD32CA3FAAC44E33BED3A74A57131029620981C815D38F5EA365B6AD4B620CC1E3685F872265EA436F9E1076B850B3B13C455B1104159076FE98C993C104FB91214A5C3AA3B9F73934623FE8EAD9390E99A3556AF85F25B9ECC285FA279C71F3DD64F8A0A7FF540C55E6C17B6E809C018F338E974A3F330A443B35D5A1A55600DDE9C8DE0DDADB1915061A33D54F4E9812F9217FE685B68D746BE242C6F7B0F4854D82E249B480C935D935CDB6B72B55BF5DF7CE5EB6D12F609E12E2E56E3ED6CE442B7474E39837827C6C718831D18378FE3BF23827FAAC14ACFFBCE20DAB888D0C3A54DF9E3079FA21E2C1B6E6233A33125302306092A864886F70D0109153116041469DC4AA443F5C9C657EF7E9B18CC4130A03A40B830413031300D0609608648016503040201050004208F94A4088463B8A284BD19F8EDA65D14541C9656F61309C4F3DD6F7C1D12A56B040895C8BA34D38B959802020800" + +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002 01 +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002:"3082046C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363DA9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF21932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30613051300D06096086480165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800" + +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002 02 +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002:"3082046C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363DA9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF21932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30613051300D06096086480165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800" + +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002 03 +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002:"3082046C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363DA9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF21932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC8165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800" + +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002 04 +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002:"3082046C0201033082040206092A8203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363DA9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF21932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30613051300D06096086480165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800" + +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002 05 +SDV_PKCS12_PARSE_P12_WRONG_P12FILE_TC002:"3082046C020103308286F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363D6372FECBCDAA375463EB303B36006110114BBF3344775D89272689D1C78F6875F0492E5A641738F6B1E981196DE4021DE863BF1A53B00BF61C9E7167A881C28614000CFB03AB6DC6582B1C35E6486C6B1FED600D6BA6227E2FDBFBA4C0A80294A7B4B763749FCDF09ECD9BC72957EC288C7ED3DBFE84162E2654DEEE4F4678A80EFCA90A587D09EE00B6662E327F2173ABE800DCFE9CC3835EF4C96CF398C8E8A131477B1377F3960453494DE6020679FBE27FA5B1FAFE622E5953515E50E87369DD7A07F44267D925FDAAD1B970FF76078A9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF291932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30613051300D06096086480165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800" + +SDV_PKCS12_ENCODE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001 01 +SDV_PKCS12_ENCODE_SAFEBAGS_OF_PKCS8SHROUDEDKEYBAG_TC001:"308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D" + +SDV_PKCS12_ENCODE_SAFEBAGS_OF_CERTBAGS_TC001 01 +SDV_PKCS12_ENCODE_SAFEBAGS_OF_CERTBAGS_TC001:"06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B" + +SDV_PKCS12_ENCODE_AUTHSAFE_TC001 01 +SDV_PKCS12_ENCODE_AUTHSAFE_TC001:"3082111530820B5A06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563308205B306092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D0065" + +SDV_PKCS12_ENCODE_MACDATA_TC001 01: +SDV_PKCS12_ENCODE_MACDATA_TC001:"308204480201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D303D302D300D06096086480165030402040500041CDB9EAAB4DF8754682737219B38B1F3C85310923B443DBA27CE548FA604089F1708BD9E2CE4E302020800":"308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"302D300D06096086480165030402040500041CDB9EAAB4DF8754682737219B38B1F3C85310923B443DBA27CE548FA604089F1708BD9E2CE4E302020800" + +SDV_PKCS12_ENCODE_P12_TC001 01 +SDV_PKCS12_ENCODE_P12_TC001:"308211760201033082112C06092A864886F70D010701A082111D048211193082111530820B5A06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563308205B306092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D006530413031300D060960864801650304020105000420F47EC9E868B0B9B3144D41744592AD8717F83DADE153BFD1F3E01251AC9450B20408ED47D6A67B24598402020800":"3082046F30820257A003020102020101300D06092A864886F70D01010B05003054310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464310D300B06035504030C046A636878301E170D3234303931333033353033355A170D3334303931313033353033355A3053310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464310C300A06035504030C0363637130820122300D06092A864886F70D01010105000382010F003082010A0282010100D559E50B3AD2B209DDD25C134476354889EF1C565012186804D6426A6E0DAE29743BD96C6638F231EA1EED05FAA7AB5FCD33AFD6258A85B1F138FD8C7C623BD9AF2FC6DD3C4F3AB4D62821DC43B5FDB0A62B2A2C7965C454D78F53A1CB8A7F48EF7655B96EE4FCCBAF7B5414D8D622A9DE3B3DFD6B85927C08D023FF25570F1AEED6F0BEA3BA5F372E1DEB6E1790CB27CDA1EF474196927C568B1D24E722AF3C2377A7BB980A490E34C230D056859443CF9BB14C0EC188D11F835FF0EECD248C60933C8FF7A769856F43605816BE84FD84325A4D670089FFE4571EC340B0DECF9977D051CCA656B393678AF5E33808B6394F9F6A1ADB0F61ABB09A3F3A5482770203010001A34D304B30090603551D1304023000301D0603551D0E0416041427DE49E413C3B3591139F07292C5136553543CB1301F0603551D23041830168014293F24092D3263DAB12EB763ABB7A13AF0891677300D06092A864886F70D01010B05000382020100A778F1346DC6200F441EF6889491AA73557067A76686C122BD361B285344BD542C218077B8254C1479CEA9C764EA7B6A9B1BB577EA163CAE3403A0529DF099FCC27E2236CA69D4E2AF57797E7FFC09FEC7A5444CEA6B0BE1A2081BC1A9D114DBD3A1384D39ACDBBE198B953C1D0ECAB06517CD0356FB9F16FA3CF40550EF7384084437EE9C8E17A01E397EDB4A23A181F79BEBAF0901F88B1E4DCB86CD5B28265C8D30D7C7DDFB4B3242D20517D9AB37A5CAD1E30D57655739B3239F558019E2B4AAF5ACA05365A9B44630892BC86872617718E41671623B2DFE77610D829C6D3CC94227CFA69550585660DC468758E6D8DE981B20C403A568193C4140A4CCCC7572A7F106FEA51451E0A9C3754DA410D4895E61253D8FD007DA320306498DBF7E1CAF881127B8DA9B25EF39A002B7D9F0AB2E44B636BB468A74EED63624B924BF20D296330F9901960F3E2FC729ED5C0C84BEC4AFD05650D2F3B45342257DCD3EF5608282C2F297962EC48E39E9AF44993FD364600281A6358E9879EEA5F79C7C282315A4207A24B075F91076BB59A4AFB74CD4B07DE215B0EB45D26E2335DFAB4E349EC8BD05C8D8675F5DD12F6A98DD19636C65FB8DF97B75A4AF0FB2DEF20A99D63692D7C7652EB29BBB21659BE1A3EF0A55035F85CE6D41DD64C355D17571A3E05CB2B717DF9DD71453E240A06AB58A2715FC184DC8A3146886151B698C" + +SDV_PKCS12_ENCODE_P12_TC001 02 +SDV_PKCS12_ENCODE_P12_TC001:"3082046C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C302404103CD0668BD26EF3A180DEFA61012C23D602020800300C06082A864886F70D02090500301D060960864801650304012A0410CE0B39834D2A455A4CB7C403094B844780820210A81435985F0C1B9C753CAC1C52B59C9B0B81745E76490F3118E8072D543F840272AA631575919327732F15831DBB8E1EA9880C6DE48287631E351D2B161C0EA5C4A38240219307B41B7302F6C8AB8CCD222ACD7F80CA975A4D1CF478200DB1E6A4BB8131150A389726929DAC0F28AB86DD44809C143AA644032710567721486F40F88F8B2694349A1AC47F624799E0795DA9C3FC84F06BAD8AFF7B71B2B84F6FCD40EC2202E65D1E5730CBFD33B1AF8F785F203722EAEBF9177098B6303D1905247F0363D6372FECBCDAA375463EB303B36006110114BBF3344775D89272689D1C78F6875F0492E5A641738F6B1E981196DE4021DE863BF1A53B00BF61C9E7167A881C28614000CFB03AB6DC6582B1C35E6486C6B1FED600D6BA6227E2FDBFBA4C0A80294A7B4B763749FCDF09ECD9BC72957EC288C7ED3DBFE84162E2654DEEE4F4678A80EFCA90A587D09EE00B6662E327F2173ABE800DCFE9CC3835EF4C96CF398C8E8A131477B1377F3960453494DE6020679FBE27FA5B1FAFE622E5953515E50E87369DD7A07F44267D925FDAAD1B970FF76078A9C9835256BE4FC116904D137865381AFD0633044D84C48BCBE3DCCFC3CBDADD53B81D1280A3570A6986501584AFC6FB2711AC3B48B2658A82D96B708BED6DC249B04A9AB4FBD3D27A02BEE22E2DF291932B2B1A5EA0F837582D2095247A5083CB45E11376FD0FD1699274286B283EB96A4EF21CE1818F1C52243082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410240BABC3C7F039F13688B6386DFCDDA002020800300C06082A864886F70D02090500301D060960864801650304012A0410D8BD500CF93A003B2F96F13BB0A3798B048190DD8C150273FEC857FA28827094A9BB41041D4EFFC4A9238429068F38759A17A61E741B1560BD816F44721E52BFB2DA1285193A5A54918389A3E3ABEC23C074224706FC341F944DA237685E8D3339D172A9C01BCB91CC722D03B43B68E1958B5121AE06F38B7C99A81E74FA479EA1F10511D0A3FC8E0D05B3B6F96C03884F3EC65DFABA4D675C0DB236664EA7ACB92BC63125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30613051300D06096086480165030402030500044037463EF2B29BE402CEBA4A9320F1615183A3DC3CFED7ED86889593D95A4DA6F7D1A710037E345F048379B98A75039036A2B43522B33D6FB1670538413C57BA690408EAA807DC1E56F04B02020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_ENCODE_P12_TC001 03 +SDV_PKCS12_ENCODE_P12_TC001:"308204480201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D303D302D300D06096086480165030402040500041CDB9EAAB4DF8754682737219B38B1F3C85310923B443DBA27CE548FA604089F1708BD9E2CE4E302020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_ENCODE_P12_TC001 04 +SDV_PKCS12_ENCODE_P12_TC001:"308204480201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410FF4BC4264C1989E622A370CAB860D10D02020800300C06082A864886F70D02090500301D060960864801650304012A0410E2C1BDB40FEB09DEC5B6CDEC6FBB0E118082021083B8757108B4E7BC176273ABACE3796530C2465C6A90F81C58E1A117AC777AF4F3EE672F973805D7E41DE6FCBCDB3F4D91087B17BFB942623076B49F1A79507FC8EF5771A38580400D16DA134E5D2EC8095E9DD98F67BCB2F7602865C2FB94EB4A7BA718B370EF614FD8623F8094F242685468322C0512E1F65EA1920D6CBDEEB7F8C99ED5809A314B8032D1F5053E53D03B313143911975EC84D662C9BFADD4DD9E41583AB10A93F6BC171A9F63533B3F0AEA30FA332C2429D728A5F736E2ECBF34FBAEA6C80678496CD713D451D2B8475FF9650A5AEC694397E1767C0EF5492C3405539DBFA100D6EED691D55E7208DB0D61BE1662865AC048E9E07EE1EB9972537D4B9C036C1C314A9748A3A1E7C933C2CD18B171308379ED36B91F7DD1189B128F2E9FBD519B3E62BF3DE887260A375BB01FF1B52C3A196533E034398A01168D4A849DE33F962831C47EB7B06E0FA9318FD3E11787F01FB99FB76C83E7AC782DBF7556589ACFF5F1E9FA41B33C46CFEEAAC686B71E804EF389B925A424155C169E6EF61DB5AEE3A7CD095FEF7DA33E1E64CA2BD4DC04D22E0489698AAC74D872992B73413C4EC95B08E4BBBE49EFE83E1F3DEEB93D6FCBD646F3E59C4FCA213F6BEA338C776DF48E8FD1E9EB62B38EFEF56080D53A155CD8234DC51EC4CD3668D69A83110E0B5BA65148897C4CB4FD7519659C80B7469DEA7E4DAA60700869E960BDA25FA5D8F7849C693692AB6B3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C302404104CFE523164AF6F734E98C977A6046F4402020800300C06082A864886F70D02090500301D060960864801650304012A0410242438D64F4E882B9BC01FD47EB4ACDF04819049AD3CA5FA7F8780B39C981AFD29AD0BE6C6A69D78FE0DC9EA34CA52C7F60469396C5398DE7A152965526A0A9BDF04B6F6AF5CAD1008C074A11803416E09E72186F3BE7982C2789D9C1A995AE444A53B31A86CC0ECB62CD164D95E71C32659E0B6B25C461F81E9688DD0C260DFEF9B1D735DEF4724A438F4EBCAB7D3063C0F08C29DCB7F10280CF582287A012F96CBB33125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D303D302D300D06096086480165030402040500041CDB9EAAB4DF8754682737219B38B1F3C85310923B443DBA27CE548FA604089F1708BD9E2CE4E302020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_ENCODE_P12_TC001 05 +SDV_PKCS12_ENCODE_P12_TC001:"3082045C0201033082040206092A864886F70D010701A08203F3048203EF308203EB3082029A06092A864886F70D010706A082028B308202870201003082028006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041072C2AB19B9C84B1F8939C4952FF9146C02020800300C06082A864886F70D02090500301D060960864801650304012A0410E6F355A75780A764D528178C55EFD39480820210BFC3C2AC636A066D8649B8F9B917D8821C720AFF1F536E55BCDB7854FA5E2534445352A2DE2682A7BC38820A843C165552A642702BD9363956F49CFC5143B7ADA7C9A11191C52A9BC0AF2C1398CF2146558C756F6CCB2952616BA761B9F15BBF333130AE91BF3E5459D88B65101EF14540D5B1B11B5A24E3F06D2D983094EE95032E0D2F8E742E269CC15FE03599AE56C33B5E2577332BD9D23C7E83A819F07B5074F62AAD557044B15DEAC9734A930466B812C7746F3DE993C9EDCC1A567D2429E77240D05E311D2C4168AB9DF78BF5820C19D1AE47AE1BAE0F5C51AFEE2682FEE5C495CE1DBE0C993655C2E4C3C5F065106E3BCCA730A9A4090F228677E8DED2F7CD17D6F50EF72FF3DB6B11656A254D0B284019E2EE1AF522E4EAB26CEBA7E8774227FAFCC6E9F79BD135FB6558D406148E12008BADDF4E44D672826F32F5D57F8EA07A106F92F2D7F495E3BD26961991B4657F93347A75D5CFD9FF9C6ABB6E21F43CC86E4BEB0DCDE8EEED1A35CA2AAD2F7CF5AA8223317319DA51CEFD35EA498BBCEDA136C9E58975363FAF00152F7E269D94150ED10949E59493CE2FB15EB53D0194D3F2C8E8526B6F9C5213B8EDB9C9BD1C81E7A023F9B2DD8028791A1C5A8B727151C17055A1AC01923AEE6C4EBD94D009DFA0EEBCD5867199D5CC52E1AC13EE1A34B84015E01906D321A6054EAAF6CD24B53915ACE1691533C3FCE500E61479A0EC41218BA83E2E588095933082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C30240410A3ADF3FF868A959459D683B1DCE37C0302020800300C06082A864886F70D02090500301D060960864801650304012A0410C8D39ACFC20EF5769A9AB45C2E90252504819025CE12A4383CC164F658282490C614AA9E3D2CC05ED92175A43C742A0CB099DF8648C5C4F715D6CAFB8D78F7C5B55966FFBEC70FBB44FE729248508C5650F62295FEAD88E0C3088242A28DD599A9AD2ECDEBDB106E458F711FB724493D261E811B1A33FA2E59B76AEBD4F7CD98C129897C200D98DD3B82259CD968C619B89039A9A552EBBBD830E096C6499438D022ED3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D30513041300D060960864801650304020205000430C2B9209605B8A54BB773A84953AF5A5AFD4A1F79CA0006F260D8267C1352FF02FD541D8896E5AAF38E805F81772169FA0408E12F596E63D6BFE602020800":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_ENCODE_P12_TC002 01 +SDV_PKCS12_ENCODE_P12_TC002:"3082038C0201033082038506092A864886F70D010701A0820376048203723082036E3082021D06092A864886F70D010701A082020E0482020A3082020630820202060B2A864886F70D010C0A0103A08201CA308201C6060A2A864886F70D01091601A08201B6048201B2308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB3125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D3082014906092A864886F70D010701A082013A04820136308201323082012E060B2A864886F70D010C0A0102A081F73081F4305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041058583887C10018533C8C34DB564352F102020800300C06082A864886F70D02090500301D060960864801650304012A04108F24DFFC94EA7EAF3DD1EECE71CD51E8048190756570F11FC369E9FDE46C319B5F4C90B7E4101C7BE38CD717DCD98AFA7C93BDDDB569A7F73C5F37F9E86750149DD1949AD06AD0703F021CC6D2305F9BCEFB73DD827EC1C431C5C8E5FC7749F9EB75B91DF8F900721A478706285DCB0DC502FC7787355396D6680C48D62EB07A6309A55A717CF7673B03EA6A99EB47364FE17D96AFDC090D5550DA41CF0778CA7110D73125302306092A864886F70D01091531160414F34CB6C5D2A309187D36DFCC0B7D5A19EC81357D":"308201AE30820153A00302010202146F371D5879DD7D98531F5210B04128F6AEA3BD30300A06082A8648CE3D0403023045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3234303930373038303233335A170D3234313030373038303233335A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C74643059301306072A8648CE3D020106082A8648CE3D03010703420004C2BE9C40E0EA68A7F4CD57C807024A7B364ABC4DEBD43F176528656565C9DE26FA5A84CCF59280AF498661FED2EFBA04C3940AB39E3B54AE7EECA887FC338E0AA321301F301D0603551D0E041604141572A080ECDCF42128C219F03429607422C285CF300A06082A8648CE3D0403020349003046022100C1497274EA5C32C666B9F2AAD8B31F325648A7EA7E7EDFBACAECF094EF4057610221009EAE41D10EE71E59CEDCEC0FD80D855179F86CF8EFDE4FF15398BE28DD47DDEB" + +SDV_PKCS12_ENCODE_P12_TC003 01 +SDV_PKCS12_ENCODE_P12_TC003:"308211760201033082112C06092A864886F70D010701A082111D048211193082111530820B5A06092A864886F70D010706A0820B4B30820B4702010030820B4006092A864886F70D010701305F06092A864886F70D01050D3052303106092A864886F70D01050C3024041048C5D4CE7FE071996A034DE7BD99715102020800300C06082A864886F70D02090500301D060960864801650304012A041054FCC6D7EFDAA69D725DD4B6D8B83B1880820AD0324168297F27F2C2C5C031B2C5024C9D8EAB70ECBAA3C9C1593628A448D91E2C5C8ED6F30898479B5667DDB6D0B2810E0B40EDA64B34B9485FFF03F8D1329F52FBA469B52A994C8ADE64E3166C2EAA74069082EEC92E12276746B89CF6DF81FAD96C229760B02D88860BA16008C5254E2E979F18A2757524A0CB15BDC148AFFC47E005BD763414D2AE89DEFC5B401E1ADF4650D5E594535A0B974E0729A896BF1B77C03059315EEA79155F3941775E6E9CB019431417801391C4C16E844B883A2CD5584E6CC23A301DDAC112E5224EFEAAEF5E0DA11A10F7EB5DC6297C3F00083F4BB98080FCFDFC5C6275A87C4040D3F09FF36ADBDB307CD1914FA29AEFF9DBBB1AE0728E2AE4731181C87AE8C37A58E2F4F8CEEC1B24B3C57ED8F4377A36C3499C38DD3006D7B181226717B3FD8891113E3D9123BA455842345C46CAD200521DB150031D9F6B33E4D2285CD1B425C1E1F8EFAA4651B3B12118F492EBBC006714E3C4287255EF71CC5E13AE6EDF26ED2254489314AB39F3982480872A1A3738F9AE5B2C0E6ED1914D4C16B6E10A26E948F84958373BA2DBF6EFCC0EAF119EDB039F4D4CA429936ACCE5BF1D0C17A69226F09AAD48FE2A0EAF355C2B85AB4E7B4550630FFC3E73EB8168A5ABEBE08F53AE5BDD63DD8C39822B529990C800D067AE161C520DE499458B51FBB1D71D8035D3BDD4C64F11A1A776FB1C5938BCA37B1578B3DB24C44795A274D291D395A47313F9C09335D57ED8B9EBCB055D05DB77DD93BED2B54F12F0DD056BE71CAC0BDB1BC28F6441B957B5BDC8E17B96D0D9EA02CFA93DFEF76EF94F5864589F8E855A3C1F3B13735661A9F15F71FC2EC81294660C8FBC1868F13426719BFF37B5122BCF3A778866387D3DAFBE1314AC0805DF788A68FEDBB61E5FCDD98F62C273EED2439666BD17D29B2431D721A8254FE717E635EA2E8208EDE1F293BD94CFE592146D1603AB36AFCDCE6B85CB6347F954C229654638F9AD8A0C1C3435F49D83CA72E6D4155E3B9361A79AF48149D0B0C32DCD4C0776F550E477DBF46C0005D3A7B137B6150B3D72446B0A9A4D7847D87967C1310AE0179015E412FCC7D7560CD54BEA421AF45CBFB661D1676A3F9520F4024E645BE3ED6978FB839FE855E828AB4F0D735714A89EA37182B188EF4FB572C438CBA9C804D411FAE4A1B5D8B800C47119B5F301ED78E3E2A7822E36097A5D777D28AED95B3D16DCEFD0DC936EFA762BC711AFC92808E6B6556EE42EAB480A3FB6DC7763BDE30056B89DBB2BC12DB01FDCDA6907193418188BE5B33E0F2486A5FEAE8B81B97CFC5EFAF9E42AE30B85C0891B4E8209314F1B9CF0C17A74DB990DD777F3F7703440546FAB4139A6916A3D8CB4F4C9A449AE18F123FEB2ACC2B42EF03A65297BD053DC6D1D1C1344E51CF1E59329C718B978A1D8A1D57B908C2AFD1E90AF38B304AC563DC74ED70A1F7D5E22352CDDD4B9D48C8996B95D5C744B6A9C02537F374D5C5FE990EB7AD8CD67C14B6807976B5961D93D87E3D3C858E14CEC86BC21898BB0F56169B893FFBED59016F43721CF406998A2218CD7A6D6AF5BD8261F7787EAB54888503B23EB8361926E65A1AB0792C83E63C6FBA0AD2AC35FE274212620273C5CBC1025DF7C247546B2039D1B5B9988BB0687FFBB74131A4FB2219125624E97DB6B2D3ADEB795B2EE9C999834C706E176E538DFBC4970036E1BD1DD8977DA332F931E66AB0D086E97F7652A5565D4C7C10BDC164D479F4F17A686BCF4171D3D4BEA0DD11DACA38402F59DE64F1627C1049CD005F186E6A2DB865619DAC901D201FC73EA8FBA92F2C256815C72C13F18D84F45948B796672B9376D943597E5E437867B756D3EF10219CE5E61AA71963319533B81CAA870D42FE2E159E2A370A6FA08FA5BC43F116E117E79C15FAB63E9572CA44F0CD324249D4ADEB6B04BDE47CA482A6900DE585A094CAEAC66293100F794BD65BA16048D270F32F6248CDD578CCB96E41037BFDA52DA28B3D396C0E1815C0C9DFEA90545BFE243B515C5C0B92B7C6C203FAE4BF95716CD40F08F056B2AD6BCB858E286934555362F3AABF12D01B6576234FEA6B2F9A304695E7F516E07E0E2A43C422E7821F18DE3FDE5F99723DE7A492D4FE4BFC4C694EB0F3D854D11BB60038D909A9FDC0B74BAA78C1FC3CECD516D3EE455C2AA0BC4ECE18BA74C2C2C7F7CB1E7E9CBE6B2C8189B2D47524D027CDA389B42FCC835BBB42D69DC5FD1CAF9D7D61BE693506C3667976650DCD4FF5FC78149729B50609816A028D12B3AE19C6408B1A2BC97075DA96A765BACCAFF839EDDBE43E337738178668ADE72988951F92C23378E6BE6868D01ACFA64182F5B89BAFF6285ED963E8BF3FECCE8D5C8C4B5996B0B5D908D872C82E951F33D767465660FE2536A49A606310BBEC887EEC759F7E273F1808DA4C36E56BDFC65CB6D16F1E5FDF1C8720BA4A01BA08FBB51D5D4C0AA1508A597C67BE818563713F47C2E32497CDE773D4C8E51FE82EF33ED716BB8D20E40542937F70A7FAC844FC8A8017FD51C9533F5A9E66BDB79035DB72C4DA93753A6D8586217DFBBB4808FC129EDC28E079015A792929EEFF3DCDD3F109C7047AB4B6B4660E1DFCC06F7CCB0C00E37BF5AD79BA061D7E6F28761126CCA41CA40B8AEE3D720B934C652FF868BC0C528974B53D9E217B7292A3E544EC6754BB67FBE65C2F89696ADF24A5CEC4FF9386EA08B6A0434BACACC51878E11FC4D51BC6E7C3BBEF88A6D9EBA37E4C4F9D42A47E9B78111B0AF16DC16CAFEC8AE1107BF0E6A19BBD70F44799B451247FA25CDB9D12008F632B382C0457082BD88B533730C9621EF4F1682BE5352F96932CCFCA7C8827F6593E82AC692FA8FCD8909EA844B1E025BACA9E4C04C43790B82E6AFFC5181FDA5A67C3070702F8DBB0CD8ADEC3F43FB08AD5466FD393A06B9C4E69A254C2E7B966CD8FBFB63EFAC474B42DC6194D25DF40BF365CDB4BC32098294B62F2AE94D59D93F81009AD8CF1D4297A8B0E12DD60FD7F4302F28102C0DB5AE2464D2E148273CB09B80CE87B8EADD0689FE19D711D41AA78982955F57460A141F1A52A029971D2047BDAC061EE56C96074B5D015211EE9980D4C3F699D82EA65D6256656EE71242F89038C3E820BDE8A8BD14E680EE671852D0DAF205B06E817F28B771AB247EA3520B3D5E65E6FE628CCA19F15CD07EC15396DC5DD5435BB09EDECB5AF2407D0434AEA206C5DBB84CA26B0631261B1F9165167D477A51BEF50EC950D2112D6C3AFF238F5925AE93532B1D41F3F71469D2C1A3CE639BA9A1510453BC3FFFA09CEF30608BF2F639E496E9D1D84D5523813DCDDD2C435D0446C54A4CA27862F881FDC65EF0475DC1DC18E007CCF4F9C7B1B6E284E7F1B2366A73375293CD3D83686BBDC85E69E5444A05A96009C9E0695A99C5DDC0628FF9CA4B58DEFB9D2A761D485405239D14F2DCC4ED7F12F2022439BB0FE9EE3DEF1B57FAD8B1F1BCC1828CB7D30AC0A77070B0AFE1BAEF2D7105AC4067DB0EAF7354AA0A329C830BCEE1D13268A7C4715F5D62D8CB1DCB553EBC125DDF1BBA90F61DAC3FAEE336135EB4A3D87162457BBECCBCA2DF87B45FF21121CE81DB9444B75A51AE84CD8CEF783418FEA0D9B53D3F3BE80F0B3AE48549229D9E1731D4AF497D6562D624A856B1AB461955B6853BBA93C10E30F5A2FFDFD919271EA1A490182DDA41BC66D600317E6F7E61972DB9D3ACF42242763AB0EE5372C03D60332AEC897FBF86314D9CF2496A423AB5B64DE7E7DD3F553B96089EC7A65D606670E70D2BC96009162A0352296FAAD7B343EE8A55CDF0ED5B128CEB6C9481C52A1A2E9435201C2CA23FE1A04137F3426AF754B9A58B072AFC38677509F5D59776A80B881E3408AFC882AF0563308205B306092A864886F70D010701A08205A4048205A03082059C30820598060B2A864886F70D010C0A0102A082053930820535305F06092A864886F70D01050D3052303106092A864886F70D01050C302404105C91EE27A917E9CADE542DB8BCCECAA202020800300C06082A864886F70D02090500301D060960864801650304012A0410DF09A37FA55B69943BD1A0AF24054E1F048204D0BA311AC81F574ADB666A5C6F92FFBCFF7A78B3FD0F2AFADF46B2592224AA076573ACE81AB305655AA05D5905B5E2167A568800003D78DB8519E6DBE3D9243975CDF4B6CD4A7B68E8B8A82004FA6F48B1041D0A55E91803C984ADF5CD7C99B9BEAE0AA4B506E4E6146C6563181D92FB53FBF136CC988D009A95F82BC9588C444D5B7FAA006514C3E0F41F47678CC93C1583207EB15B43FDE92B6957E2A144D5A385B0FB0F8E55775C15671FA254929180020CB315EB8E14D1859A930251C2983AB4B00E7BA5D658388A6C9964F2CE55C72CDF2D26A61A72323BE715E491FE739EA6D4A6FA42D50D7DE1429577EBE6FDF2474F37B4401A50889077CC573600C9BF015FF9722E2742B6622F8A67E8A62CA0F872F8583F4175932B1827D79DDC1289DD615CE4C90E48D1E9B64BE8696479F534EFC1F9A1FF86447119B26E014FB82798B8A9845D687B0CD434966B174DDA55745C4ADC72F2DF6AAD127F30F7E986188D00C46A37ECC52510C77D994A2ECB3134FD8A88B181736F37A7118DDCCADDDE34137CA4E9744E1659B47F3754CE6B304268B278D8C493057551709DAE2065772DC9098E760AD5882AA7011033E015D3C5F230F4A3D7500AEA02016F0E059D7D21231EC0DC3F705AF47710D09FC8F75369E1BD2850D26792B6A02922DBFBA18BE57E5A2720AFFEE4C0957EB43BBF07B57E105B9658B8FE4BE9C3C566D8A67BC3C7044146D0C614A895733FD140E3E170707308EBAB4614A6AC3CDA379DD86BAE12079A87018C9690A625AD6B6490B28AF64FB54920BC7BF8EA3A4965F7E5FE082F17EF403AE1B6C2ABFF8E4717FD28288A498F21DEDF2F69379DAD678AAE05DC38197CC7375964450A2621B86822BF852E10975BC016CD998ADA44A8207C4F553BFA7D5C728F690D80423A89D7D83DA464C860EAD6A89BD40F42A882BACC58D0F973242806DFB29DD839A8B3E54B982D6CFF0A06D7B2B9BBA3B4E9F62CD8AD112239382337516F124D498869603E67365EE9E60B239A27A0DEFC06079499FDEE423F8388D40259D111D9D5608361477C99B4A8503B92811646C7EA8A18A199A63D6C8F8520B9C39E6EA877092F8E2C69D499BA22A5FDA01478ECE689CF0538CD2639C366A78D42A44DEE58D68BB1DF863D3C46410943AEDF22E9083F85744DCABD77BC49329F39AD7C215079A877D6031CC3BBD58F1C051FAE83D8B01B24DF3F63EE69377147046608825F4E52FDDBA9F6DC0DF39891D10CEADFB0C9D8EDEAD09B1B586E176592CE17DC2D9FF4F588A45F351AF4F225E552E39DD04D1E25FCBC46AC3E14DE75860A360FF8494947C156F140858D472C758FBCBD1A83CCF2D23E66C240A6F74D61A055471B8AEA504ACD96064873D368C469D5DC8ECF4ED114D238E8E0386B6056498009E951F948B58B5F2EF679F10C5F533F12DE73CA1D3D0E14423A115DCA3489F30F6737AD8FC5CC72DDC53A142419DBC71713827D5DA62589AAD0120079DBF07C5845756541521D266F1C08547A96C0F9AF5871B83359606515D5EE8796B5B10881951776A140D03F63F584CEE113CD052F3AE4BE8149C6C08CBA156F5BC1FF62DDE0691CE1937A15989E675CCEF7BC63354644D5CFBA0F3A4D6A34ABACCFCB2E45B116A2C42CA7C0EFC254751CCCB2C2304964C3EE45A54D201E5460491CA9275B600AFC4BC2D7C2FD287ED4665611E243176245B1B7C94CFBFD7B55AEB70E745F5CFC5298A083314C302306092A864886F70D010915311604146A259B9CDCA36597CDDDFB96E09D03E85505B1F3302506092A864886F70D01091431181E160066007200690065006E0064006C004E0061006D006530413031300D060960864801650304020105000420F47EC9E868B0B9B3144D41744592AD8717F83DADE153BFD1F3E01251AC9450B20408ED47D6A67B24598402020800" + +SDV_PKCS12_GEN_PARASE_P12FILE_TC003 +SDV_PKCS12_GEN_PARASE_P12FILE_TC003: \ No newline at end of file diff --git a/testcode/sdv/testcase/x509/verify/test_suite_sdv_x509_vfy.c b/testcode/sdv/testcase/x509/verify/test_suite_sdv_x509_vfy.c new file mode 100644 index 00000000..b249c13f --- /dev/null +++ b/testcode/sdv/testcase/x509/verify/test_suite_sdv_x509_vfy.c @@ -0,0 +1,593 @@ +/* + * 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. + */ + +/* BEGIN_HEADER */ + +#include "bsl_sal.h" +#include "securec.h" +#include "bsl_type.h" +#include "bsl_log.h" +#include "bsl_init.h" +#include "bsl_list.h" +#include "hitls_x509.h" +#include "hitls_x509_errno.h" +#include "hitls_x509_verify.h" +#include "hitls_cert_local.h" +#include "hitls_crl_local.h" +#include "bsl_list_internal.h" + +/* END_HEADER */ + +void HITLS_X509_FreeStoreCtxMock(HITLS_X509_StoreCtx *ctx) +{ + if (ctx == NULL) { + return; + } + int ret; + (void)BSL_SAL_AtomicDownReferences(&ctx->references, &ret); + if (ret > 0) { + return; + } + + if (ctx->store != NULL) { + BSL_LIST_FREE(ctx->store, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + } + if (ctx->crl != NULL) { + BSL_LIST_FREE(ctx->crl, (BSL_LIST_PFUNC_FREE)HITLS_X509_CrlFree); + } + + BSL_SAL_ReferencesFree(&ctx->references); + BSL_SAL_Free(ctx); +} + +HITLS_X509_StoreCtx *HITLS_X509_NewStoreCtxMock(void) +{ + HITLS_X509_StoreCtx *ctx = (HITLS_X509_StoreCtx *)BSL_SAL_Malloc(sizeof(HITLS_X509_StoreCtx)); + if (ctx == NULL) { + return NULL; + } + + (void)memset_s(ctx, sizeof(HITLS_X509_StoreCtx), 0, sizeof(HITLS_X509_StoreCtx)); + ctx->store = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + if (ctx->store == NULL) { + BSL_SAL_Free(ctx); + return NULL; + } + ctx->crl = BSL_LIST_New(sizeof(HITLS_X509_Crl *)); + if (ctx->crl == NULL) { + BSL_SAL_FREE(ctx->store); + BSL_SAL_Free(ctx); + return NULL; + } + ctx->verifyParam.maxDepth = 20; + ctx->verifyParam.securityBits = 128; + ctx->verifyParam.flags |= HITLS_X509_VFY_FLAG_CRL_ALL; + ctx->verifyParam.flags |= HITLS_X509_VFY_FLAG_SECBITS; + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +static int32_t HITLS_BuildChain(BslList *list, int type, + char *path1, char *path2, char *path3, char *path4, char *path5) +{ + int32_t ret; + char *path[] = {path1, path2, path3, path4, path5}; + for (size_t i = 0; i < sizeof(path) / sizeof(path[0]); i++) { + if (path[i] == NULL) { + continue; + } + if (type == 0) { // cert + HITLS_X509_Cert *cert = NULL; + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, path[i], &cert); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + ret = BSL_LIST_AddElement(list, cert, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + return ret; + } + } else { // crl + HITLS_X509_Crl *crl = NULL; + ret = HITLS_X509_CrlParseFile(BSL_FORMAT_ASN1, path[i], &crl); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + ret = BSL_LIST_AddElement(list, crl, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + return ret; + } + } + } + return ret; +} + +/* BEGIN_CASE */ +void SDV_X509_STORE_VFY_PARAM_EXR_FUNC_TC001(char *path1, char *path2, char *path3, int secBits, int exp) +{ + int ret; + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_StoreCtx *storeCtx = NULL; + storeCtx = HITLS_X509_NewStoreCtxMock(); + ASSERT_NE(storeCtx, NULL); + storeCtx->verifyParam.securityBits = secBits; + BslList *chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + ASSERT_NE(chain, NULL); + ret = HITLS_BuildChain(chain, 0, path1, path2, path3, NULL, NULL); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_VerifyParamAndExt(storeCtx, chain); + ASSERT_EQ(ret, exp); +exit: + HITLS_X509_FreeStoreCtxMock(storeCtx); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + + +/* BEGIN_CASE */ +void SDV_X509_STORE_VFY_CRL_FUNC_TC001(int type, int expResult, char *path1, char *path2, char *path3, + char *crl1, char *crl2) +{ + int ret; + TestMemInit(); + BSL_GLOBAL_Init(); + HITLS_X509_StoreCtx *storeCtx = NULL; + storeCtx = HITLS_X509_NewStoreCtxMock(); + ASSERT_NE(storeCtx, NULL); + if (type == 1) { + storeCtx->verifyParam.flags ^= HITLS_X509_VFY_FLAG_CRL_ALL; + storeCtx->verifyParam.flags |= HITLS_X509_VFY_FLAG_CRL_DEV; + } + + BslList *chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + ASSERT_NE(chain, NULL); + ret = HITLS_BuildChain(chain, 0, path1, path2, path3, NULL, NULL); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ret = HITLS_BuildChain(storeCtx->crl, 1, crl1, crl2, NULL, NULL, NULL); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ret = HITLS_X509_CrlVerify(storeCtx, chain); + ASSERT_EQ(ret, expResult); +exit: + HITLS_X509_FreeStoreCtxMock(storeCtx); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_STORE_CTRL_FUNC_TC001(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + int32_t val = 20; + int32_t ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_PARAM_DEPTH, &val, sizeof(int32_t)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(store->verifyParam.maxDepth, val); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_SECBITS, &val, sizeof(int32_t)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(store->verifyParam.securityBits, val); + ASSERT_EQ(store->verifyParam.flags, HITLS_X509_VFY_FLAG_SECBITS); + int64_t timeval = 55; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_TIME, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(store->verifyParam.time, timeval); + ASSERT_EQ(store->verifyParam.flags & HITLS_X509_VFY_FLAG_TIME, HITLS_X509_VFY_FLAG_TIME); + timeval = HITLS_X509_VFY_FLAG_TIME; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_CLR_PARAM_FLAGS, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(store->verifyParam.flags & HITLS_X509_VFY_FLAG_TIME, 0); + ASSERT_EQ(store->verifyParam.flags, HITLS_X509_VFY_FLAG_SECBITS); + int ref; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_REF_UP, &ref, sizeof(int)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ref, 2); + HITLS_X509_StoreCtxFree(store); + +exit: + HITLS_X509_StoreCtxFree(store); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_STORE_CTRL_CERT_FUNC_TC002(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + HITLS_X509_Cert *cert = NULL; + int32_t ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/asn1/rsa2048ssa-pss.crt", &cert); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_DEEP_COPY_SET_CA, cert, sizeof(HITLS_X509_Cert)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(cert->references.count, 2); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 1); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_DEEP_COPY_SET_CA, cert, sizeof(HITLS_X509_Cert)); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + HITLS_X509_Crl *crl = NULL; + ret = HITLS_X509_CrlParseFile(BSL_FORMAT_ASN1, "../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der", &crl); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_CRL, crl, sizeof(HITLS_X509_Crl)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(crl->references.count, 2); + ASSERT_EQ(BSL_LIST_COUNT(store->crl), 1); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_CRL, crl, sizeof(HITLS_X509_Crl)); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + + +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(cert); + HITLS_X509_CrlFree(crl); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +static int32_t HITLS_AddCertToStoreTest(char *path, HITLS_X509_StoreCtx *store, HITLS_X509_Cert **cert) +{ + int32_t ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, path, cert); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + return HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_DEEP_COPY_SET_CA, *cert, sizeof(HITLS_X509_Cert)); +} + +static int32_t HITLS_AddCrlToStoreTest(char *path, HITLS_X509_StoreCtx *store, HITLS_X509_Crl **crl) +{ + int32_t ret = HITLS_X509_CrlParseFile(BSL_FORMAT_ASN1, path, crl); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + return HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_CRL, *crl, sizeof(HITLS_X509_Crl)); +} + + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001(char *rootPath, char *caPath, char *cert, char *crlPath) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_AddCertToStoreTest(rootPath, store, &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *ca = NULL; + ret = HITLS_AddCertToStoreTest(caPath, store, &ca); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *entity = NULL; + ret = HITLS_AddCertToStoreTest(cert, store, &entity); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + HITLS_X509_Crl *crl = NULL; + ret = HITLS_AddCrlToStoreTest(crlPath, store, &crl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + + ASSERT_EQ(BSL_LIST_COUNT(store->crl), 1); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 2); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, entity, &chain); + ASSERT_TRUE(ret == HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(chain), 2); + int64_t timeval = time(NULL); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_TIME, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + int64_t flag = HITLS_X509_VFY_FLAG_CRL_ALL; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_CLR_PARAM_FLAGS, &flag, sizeof(flag)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + HITLS_X509_CertFree(ca); + HITLS_X509_CertFree(entity); + HITLS_X509_CrlFree(crl); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC002(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *ca = NULL; + int32_t ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-pss-v3/inter.der", store, &ca); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *entity = NULL; + ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-pss-v3/end.der", store, &entity); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 1); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, entity, &chain); + ASSERT_TRUE(ret == HITLS_X509_SUCCESS); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + HITLS_X509_Cert *root = NULL; + ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-pss-v3/ca.der", store, &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertChainBuild(store, entity, &chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(chain), 2); + int64_t timeval = time(NULL); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_TIME, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + HITLS_X509_CertFree(ca); + HITLS_X509_CertFree(entity); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +static int32_t X509_AddCertToChainTest(HITLS_X509_List *chain, HITLS_X509_Cert *cert) +{ + int ref; + int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_REF_UP, &ref, sizeof(int)); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + ret = BSL_LIST_AddElement(chain, cert, BSL_LIST_POS_END); + if (ret != HITLS_X509_SUCCESS) { + HITLS_X509_CertFree(cert); + return ret; + } + return ret; +} + + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC003(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *ca = NULL; + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/chain/rsa-pss-v3/ca.der", &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-pss-v3/inter.der", store, &ca); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *entity = NULL; + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/chain/rsa-pss-v3/end.der", &entity); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 1); + HITLS_X509_List *chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + ASSERT_TRUE(chain != NULL); + ret = X509_AddCertToChainTest(chain, entity); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = X509_AddCertToChainTest(chain, ca); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + HITLS_X509_CertFree(ca); + HITLS_X509_CertFree(entity); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC004(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-pss-v3/ca.der", store, &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 1); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, root, &chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_TRUE(chain != NULL); + ASSERT_EQ(BSL_LIST_COUNT(chain), 1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC005(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/chain/rsa-pss-v3/ca.der", &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 0); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, root, &chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_TRUE(chain != NULL); + ASSERT_EQ(BSL_LIST_COUNT(chain), 1); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC006(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/chain/rsa-pss-v3/ca.der", &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 0); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, root, &chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_TRUE(chain != NULL); + ASSERT_EQ(BSL_LIST_COUNT(chain), 1); + int64_t timeval = 5555; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_TIME, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC007(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-v3/rootca.der", store, &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *ca = NULL; + ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-v3/ca.der", store, &ca); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *entity = NULL; + ret = HITLS_AddCertToStoreTest("../testdata/cert/chain/rsa-v3/cert.der", store, &entity); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 2); + int32_t depth = 2; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_PARAM_DEPTH, &depth, sizeof(depth)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, entity, &chain); + ASSERT_TRUE(ret == HITLS_X509_SUCCESS); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + ASSERT_TRUE(chain != NULL); + ret = X509_AddCertToChainTest(chain, entity); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + int64_t timeval = time(NULL); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_TIME, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + HITLS_X509_CertFree(ca); + HITLS_X509_CertFree(entity); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008(char *rootPath, char *caPath, char *cert, char *rootcrlpath, char *cacrlpath, int flag, int except) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_Cert *root = NULL; + int32_t ret = HITLS_AddCertToStoreTest(rootPath, store, &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *ca = NULL; + ret = HITLS_AddCertToStoreTest(caPath, store, &ca); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_Cert *entity = NULL; + ret = HITLS_AddCertToStoreTest(cert, store, &entity); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + ASSERT_EQ(BSL_LIST_COUNT(store->store), 2); + HITLS_X509_Crl *rootcrl = NULL; + if (strlen(rootcrlpath) != 0) { + ret = HITLS_AddCrlToStoreTest(rootcrlpath, store, &rootcrl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + } + HITLS_X509_Crl *cacrl = NULL; + ret = HITLS_AddCrlToStoreTest(cacrlpath, store, &cacrl); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + if (strlen(rootcrlpath) == 0) { + ASSERT_EQ(BSL_LIST_COUNT(store->crl), 1); + } else { + ASSERT_EQ(BSL_LIST_COUNT(store->crl), 2); + } + int32_t depth = 3; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_PARAM_DEPTH, &depth, sizeof(depth)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + HITLS_X509_List *chain = NULL; + ret = HITLS_X509_CertChainBuild(store, entity, &chain); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + int64_t setFlag = (int64_t)flag; + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_PARAM_FLAGS, &setFlag, sizeof(int64_t)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + int64_t timeval = time(NULL); + ret = HITLS_X509_StoreCtxCtrl(store, HITLS_X509_STORECTX_SET_TIME, &timeval, sizeof(timeval)); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret == except); + +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + HITLS_X509_CertFree(ca); + HITLS_X509_CertFree(entity); + HITLS_X509_CrlFree(rootcrl); + HITLS_X509_CrlFree(cacrl); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + + +/* BEGIN_CASE */ +void SDV_X509_BUILD_CERT_CHAIN_FUNC_TC009(void) +{ + HITLS_X509_StoreCtx *store = HITLS_X509_StoreCtxNew(); + ASSERT_TRUE(store != NULL); + HITLS_X509_List *chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + int32_t ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); + HITLS_X509_Cert *root = NULL; + ret = HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, "../testdata/cert/chain/rsa-pss-v3/ca.der", &root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = X509_AddCertToChainTest(chain, root); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = BSL_LIST_AddElementInt(chain, NULL, BSL_LIST_POS_BEGIN); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ASSERT_EQ(ret, HITLS_X509_SUCCESS); + ret = HITLS_X509_CertVerify(store, chain); + ASSERT_TRUE(ret != HITLS_X509_SUCCESS); +exit: + HITLS_X509_StoreCtxFree(store); + HITLS_X509_CertFree(root); + BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_GLOBAL_DeInit(); +} +/* END_CASE */ + diff --git a/testcode/sdv/testcase/x509/verify/test_suite_sdv_x509_vfy.data b/testcode/sdv/testcase/x509/verify/test_suite_sdv_x509_vfy.data new file mode 100644 index 00000000..cb5d9424 --- /dev/null +++ b/testcode/sdv/testcase/x509/verify/test_suite_sdv_x509_vfy.data @@ -0,0 +1,70 @@ +SDV_X509_STORE_VFY_PARAM_EXR_FUNC_TC001 1 +SDV_X509_STORE_VFY_PARAM_EXR_FUNC_TC001:"../testdata/cert/sm2/sign.mul.der":"../testdata/cert/sm2/inter.mul.der":"../testdata/cert/sm2/ca.mul.der":128:HITLS_X509_SUCCESS + +SDV_X509_STORE_VFY_PARAM_EXR_FUNC_TC001 2 +SDV_X509_STORE_VFY_PARAM_EXR_FUNC_TC001:"../testdata/cert/sm2/sign.mul.der":"../testdata/cert/sm2/inter.mul.der":"../testdata/cert/sm2/ca.mul.der":256:HITLS_X509_ERR_VFY_CHECK_SECBITS + +SDV_X509_STORE_VFY_CRL_FUNC_TC001 revoked inter ca cert, device cert no revoked, all crl +SDV_X509_STORE_VFY_CRL_FUNC_TC001:0:HITLS_X509_ERR_VFY_CERT_REVOKED:"../testdata/cert/sm2/sign.mul.der":"../testdata/cert/sm2/inter.mul.der":"../testdata/cert/sm2/ca.mul.der":"../testdata/cert/sm2/crl_v2.mul3.der":"../testdata/cert/sm2/crl_inter_v2.mul.der" + +SDV_X509_STORE_VFY_CRL_FUNC_TC001 revoked device cert, all crl +SDV_X509_STORE_VFY_CRL_FUNC_TC001:0:HITLS_X509_ERR_VFY_CERT_REVOKED:"../testdata/cert/sm2/enc3.mul.der":"../testdata/cert/sm2/inter.mul.der":"../testdata/cert/sm2/ca.mul.der":"../testdata/cert/sm2/crl_v2.mul3.der":"../testdata/cert/sm2/crl_inter_v2.mul.der" + +SDV_X509_STORE_VFY_CRL_FUNC_TC001 device cert no revoked, dev crl +SDV_X509_STORE_VFY_CRL_FUNC_TC001:1:HITLS_X509_SUCCESS:"../testdata/cert/sm2/sign.mul.der":"../testdata/cert/sm2/inter.mul.der":"../testdata/cert/sm2/ca.mul.der":"../testdata/cert/sm2/crl_v2.mul3.der":"../testdata/cert/sm2/crl_inter_v2.mul.der" + +SDV_X509_STORE_VFY_CRL_FUNC_TC001 revoked device cert, dev crl +SDV_X509_STORE_VFY_CRL_FUNC_TC001:1:HITLS_X509_ERR_VFY_CERT_REVOKED:"../testdata/cert/sm2/enc3.mul.der":"../testdata/cert/sm2/inter.mul.der":"../testdata/cert/sm2/ca.mul.der":"../testdata/cert/sm2/crl_v2.mul3.der":"../testdata/cert/sm2/crl_inter_v2.mul.der" + +SDV_X509_STORE_CTRL_FUNC_TC001 +SDV_X509_STORE_CTRL_FUNC_TC001: + +SDV_X509_STORE_CTRL_CERT_FUNC_TC002 +SDV_X509_STORE_CTRL_CERT_FUNC_TC002: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001 rsa-sha256-nocrl +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001:"../testdata/cert/chain/rsa-v3/rootca.der":"../testdata/cert/chain/rsa-v3/ca.der":"../testdata/cert/chain/rsa-v3/cert.der":"../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der" + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001 rsa-pss-nocrl +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001:"../testdata/cert/chain/rsa-pss-v3/ca.der":"../testdata/cert/chain/rsa-pss-v3/inter.der":"../testdata/cert/chain/rsa-pss-v3/end.der":"../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der" + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001 ecdsa-nocrl +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001:"../testdata/cert/chain/ecdsa-v3/ca.der":"../testdata/cert/chain/ecdsa-v3/inter.der":"../testdata/cert/chain/ecdsa-v3/end.der":"../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der" + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001 sm2-nocrl +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC001:"../testdata/cert/chain/sm2-v3/ca.der":"../testdata/cert/chain/sm2-v3/inter.der":"../testdata/cert/chain/sm2-v3/end.der":"../testdata/cert/asn1/ca-empty-rsa-sha256-v2.der" + + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC002 imcomplete certificate chain +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC002: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC003 root not in trust chain +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC003: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC004 selfsigned cert +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC004: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC005 selfsigned cert but not in trust chain +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC005: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC006 selfsigned cert check expried time +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC006: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC007 cert chain error depth +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC007: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008 test crl have no cacrl vfy dev +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008:"../testdata/cert/chain/rsa-v3/ca1.der":"../testdata/cert/chain/rsa-v3/inter.der":"../testdata/cert/chain/rsa-v3/end.der":"":"../testdata/cert/chain/rsa-v3/crl_v2.old.der":HITLS_X509_VFY_FLAG_CRL_DEV:HITLS_X509_SUCCESS + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008 test crl have no cacrl vfy all +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008:"../testdata/cert/chain/rsa-v3/ca1.der":"../testdata/cert/chain/rsa-v3/inter.der":"../testdata/cert/chain/rsa-v3/end.der":"":"../testdata/cert/chain/rsa-v3/crl_v2.old.der":HITLS_X509_VFY_FLAG_CRL_ALL:HITLS_X509_ERR_CRL_NOT_FOUND + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008 test revoke endcert +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008:"../testdata/cert/chain/rsa-v3/ca1.der":"../testdata/cert/chain/rsa-v3/inter.der":"../testdata/cert/chain/rsa-v3/end.der":"":"../testdata/cert/chain/rsa-v3/crl_v1.der":HITLS_X509_VFY_FLAG_CRL_DEV:HITLS_X509_ERR_VFY_CERT_REVOKED + +# SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008 test revoke cacert +# SDV_X509_BUILD_CERT_CHAIN_FUNC_TC008: + +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC009 +SDV_X509_BUILD_CERT_CHAIN_FUNC_TC009: + diff --git a/testcode/testdata/.gitignore b/testcode/testdata/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/testcode/testdata/cert/asn1/ca-1-rsa-sha256-v1.der b/testcode/testdata/cert/asn1/ca-1-rsa-sha256-v1.der new file mode 100644 index 00000000..a9d0f8f2 Binary files /dev/null and b/testcode/testdata/cert/asn1/ca-1-rsa-sha256-v1.der differ diff --git a/testcode/testdata/cert/asn1/ca-1-rsa-sha256-v2.der b/testcode/testdata/cert/asn1/ca-1-rsa-sha256-v2.der new file mode 100644 index 00000000..21278da5 Binary files /dev/null and b/testcode/testdata/cert/asn1/ca-1-rsa-sha256-v2.der differ diff --git a/testcode/testdata/cert/asn1/ca-empty-rsa-sha256-v2.der b/testcode/testdata/cert/asn1/ca-empty-rsa-sha256-v2.der new file mode 100644 index 00000000..3c66621a Binary files /dev/null and b/testcode/testdata/cert/asn1/ca-empty-rsa-sha256-v2.der differ diff --git a/testcode/testdata/cert/asn1/cawithkeyusage.der b/testcode/testdata/cert/asn1/cawithkeyusage.der new file mode 100644 index 00000000..03572003 Binary files /dev/null and b/testcode/testdata/cert/asn1/cawithkeyusage.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v1.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.der new file mode 100644 index 00000000..b386bca7 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v1.mul.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.mul.der new file mode 100644 index 00000000..733e9f90 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v1.noCRL.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.noCRL.der new file mode 100644 index 00000000..cd82f2d9 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v1.notCA.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.notCA.der new file mode 100644 index 00000000..7716b7bd Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.notCA.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v1.v1.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.v1.der new file mode 100644 index 00000000..15da5683 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v1.v1.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.der new file mode 100644 index 00000000..f508adf5 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul.der new file mode 100644 index 00000000..dcf7812c Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul.old.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul.old.der new file mode 100644 index 00000000..4d1e090e Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul2.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul2.der new file mode 100644 index 00000000..8c55c004 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul3.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul3.der new file mode 100644 index 00000000..18f72c9a Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.noCRL.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.noCRL.der new file mode 100644 index 00000000..59b947ca Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.noCRL.old.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.noCRL.old.der new file mode 100644 index 00000000..9f7f86ef Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.noCRL.old.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.notCA.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.notCA.der new file mode 100644 index 00000000..2d2c6e44 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.notCA.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.notCA.old.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.notCA.old.der new file mode 100644 index 00000000..ccf79193 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.notCA.old.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.old.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.old.der new file mode 100644 index 00000000..67579692 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.old.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1-time.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1-time.der new file mode 100644 index 00000000..356edeb7 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1-time.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1.der new file mode 100644 index 00000000..f658098a Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1.der differ diff --git a/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1.old.der b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1.old.der new file mode 100644 index 00000000..bb5ae2e8 Binary files /dev/null and b/testcode/testdata/cert/asn1/dsa_crl/crl_v2.v1.old.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca.der new file mode 100644 index 00000000..ce8fa783 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca.mul.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca.mul.der new file mode 100644 index 00000000..2b564c87 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca.noCRL.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca.noCRL.der new file mode 100644 index 00000000..d8d8eed7 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca.notCA.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca.notCA.der new file mode 100644 index 00000000..1e2c8234 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca.notCA.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca.v1.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca.v1.der new file mode 100644 index 00000000..a7eaf3e9 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca.v1.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp256.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp256.der new file mode 100644 index 00000000..da1c168d Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp256.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp384.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp384.der new file mode 100644 index 00000000..71f45662 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp384.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp512.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp512.der new file mode 100644 index 00000000..291cb684 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca_bp512.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca_p224.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca_p224.der new file mode 100644 index 00000000..3e16e32a Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca_p224.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca_p256.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca_p256.der new file mode 100644 index 00000000..3ad0be43 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca_p256.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ca_p521.der b/testcode/testdata/cert/asn1/ecdsa_cert/ca_p521.der new file mode 100644 index 00000000..a038ad8f Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ca_p521.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.crt.der b/testcode/testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.crt.der new file mode 100644 index 00000000..282daa93 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.crt.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.key.der b/testcode/testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.key.der new file mode 100644 index 00000000..e24d9385 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/ecdsa_sha384.key.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end.der b/testcode/testdata/cert/asn1/ecdsa_cert/end.der new file mode 100644 index 00000000..0399e780 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end.mul.der b/testcode/testdata/cert/asn1/ecdsa_cert/end.mul.der new file mode 100644 index 00000000..81f971a2 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end.noCRL.der b/testcode/testdata/cert/asn1/ecdsa_cert/end.noCRL.der new file mode 100644 index 00000000..ffe94952 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end.notCA.der b/testcode/testdata/cert/asn1/ecdsa_cert/end.notCA.der new file mode 100644 index 00000000..2f7478ec Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end.notCA.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end.v1.der b/testcode/testdata/cert/asn1/ecdsa_cert/end.v1.der new file mode 100644 index 00000000..d0cd8fcf Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end.v1.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end2.mul.der b/testcode/testdata/cert/asn1/ecdsa_cert/end2.mul.der new file mode 100644 index 00000000..23585c62 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end2.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/end3.mul.der b/testcode/testdata/cert/asn1/ecdsa_cert/end3.mul.der new file mode 100644 index 00000000..bd8a69e4 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/end3.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/inter.der b/testcode/testdata/cert/asn1/ecdsa_cert/inter.der new file mode 100644 index 00000000..f7b86c3a Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/inter.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/inter.mul.der b/testcode/testdata/cert/asn1/ecdsa_cert/inter.mul.der new file mode 100644 index 00000000..809ed64b Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/inter.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/inter.noCRL.der b/testcode/testdata/cert/asn1/ecdsa_cert/inter.noCRL.der new file mode 100644 index 00000000..fd62c82d Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/inter.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/inter.notCA.der b/testcode/testdata/cert/asn1/ecdsa_cert/inter.notCA.der new file mode 100644 index 00000000..aa042890 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/inter.notCA.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_cert/inter.v1.der b/testcode/testdata/cert/asn1/ecdsa_cert/inter.v1.der new file mode 100644 index 00000000..38174b9f Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_cert/inter.v1.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.der new file mode 100644 index 00000000..0e086f8e Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.mul.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.mul.der new file mode 100644 index 00000000..00ae45c9 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.noCRL.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.noCRL.der new file mode 100644 index 00000000..81433691 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.notCA.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.notCA.der new file mode 100644 index 00000000..74e84791 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.notCA.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.v1.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.v1.der new file mode 100644 index 00000000..3bd4d030 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v1.v1.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.der new file mode 100644 index 00000000..af8bf15e Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul.der new file mode 100644 index 00000000..e5ff3ed2 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul.old.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul.old.der new file mode 100644 index 00000000..bff33c31 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul2.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul2.der new file mode 100644 index 00000000..b8e34a8e Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul3.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul3.der new file mode 100644 index 00000000..fb5422c2 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.noCRL.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.noCRL.der new file mode 100644 index 00000000..2e5b376a Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.noCRL.old.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.noCRL.old.der new file mode 100644 index 00000000..7625dc5f Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.noCRL.old.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.notCA.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.notCA.der new file mode 100644 index 00000000..a792b7f4 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.notCA.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.notCA.old.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.notCA.old.der new file mode 100644 index 00000000..a5c6c8c6 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.notCA.old.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.old.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.old.der new file mode 100644 index 00000000..1a97022f Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.old.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.v1.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.v1.der new file mode 100644 index 00000000..53c1400c Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.v1.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.v1.old.der b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.v1.old.der new file mode 100644 index 00000000..52c9da8c Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/crl_v2.v1.old.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls-red.pem b/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls-red.pem new file mode 100644 index 00000000..e467d268 --- /dev/null +++ b/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls-red.pem @@ -0,0 +1,32 @@ + +MIIBHTCBpDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +-----BEGIN X509 CRL----- +MIIBHTCBpDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +FDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xHzAdBgNVBAMM +FmNlcnRpZmljYXRlLnRlc3Rpbi5jb20XDTI0MDQyMzAzMTIwM1oXDTM0MDQyMTAz +MTIwM1owFDASAgECFw0yNDA0MjMwMzEyMDNaMAoGCCqGSM49BAMCA2gAMGUCMBI+ +MGKV9pTjEuEF8/iDk5EGwM41TbO3QzCJkwfxLb5gNdx2Sc/BAY1Reac9nbdmxwIx +APAO9i/HbXnOIPFccAqFo5jCvTGymPrr3ETP6a+bbAzkrIF7E0gvDKI4qtXvnrcQ +gA== +-----END X509 CRL----- +MIIBHTCBpDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +-----BEGIN X509 CRL----- +MIIBMDCBtwIBATAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwC +WFgxFDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xHzAdBgNV +BAMMFmNlcnRpZmljYXRlLnRlc3Rpbi5jb20XDTI0MDQyMzAzMTIwM1oXDTM0MDQy +MTAzMTIwM1owFDASAgECFw0yNDA0MjMwMzEyMDNaoA4wDDAKBgNVHRQEAwIBATAK +BggqhkjOPQQDAgNoADBlAjA4Qjgh11pRcsg99pgY5qWKwaEA3Z6DPvoIx/WcKpze +EeiA3T0IgldXK29SXQZuwGoCMQDfCH+laeI/8XNGMd2HDBkTP/eesx3DVp/3CbEH +tjpbT6156iaDvJG7BmTtBE312Dg= +-----END X509 CRL----- +MIIBHTCBpDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +-----BEGIN X509 CRL----- +MIIBSDCB0DAKBggqhkjOPQQDAjBmMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +FDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xIzAhBgNVBAMM +GmNlcnRpZmljYXRlLnRlc3Rpbi5tdWwuY29tFw0yNDA0MjMwMzEyMDNaFw0zNDA0 +MjEwMzEyMDNaMDwwEgIBAhcNMjQwNDIzMDMxMjAzWjASAgEDFw0yNDA0MjMwMzEy +MDNaMBICAQQXDTI0MDQyMzAzMTIwM1owCgYIKoZIzj0EAwIDZwAwZAIwTRTLX7+/ +q+w3AbYwvd+qmoRM7IVyMBiJewE8+3/T8x23K1YMGvpT9KTjyjACu3DDAjB4bfcR +XmmSF8Ou/ZVvky859BNn3IzKxPSt+pEO7zmS4p2csBC3+2JMf/L+6omLRhY= +-----END X509 CRL----- +MIIBHTCBpDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls.der b/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls.der new file mode 100644 index 00000000..0d51b26b Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls.pem b/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls.pem new file mode 100644 index 00000000..0bafddca --- /dev/null +++ b/testcode/testdata/cert/asn1/ecdsa_crl/mulcrls.pem @@ -0,0 +1,27 @@ +-----BEGIN X509 CRL----- +MIIBHTCBpDAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +FDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xHzAdBgNVBAMM +FmNlcnRpZmljYXRlLnRlc3Rpbi5jb20XDTI0MDQyMzAzMTIwM1oXDTM0MDQyMTAz +MTIwM1owFDASAgECFw0yNDA0MjMwMzEyMDNaMAoGCCqGSM49BAMCA2gAMGUCMBI+ +MGKV9pTjEuEF8/iDk5EGwM41TbO3QzCJkwfxLb5gNdx2Sc/BAY1Reac9nbdmxwIx +APAO9i/HbXnOIPFccAqFo5jCvTGymPrr3ETP6a+bbAzkrIF7E0gvDKI4qtXvnrcQ +gA== +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIIBMDCBtwIBATAKBggqhkjOPQQDAjBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwC +WFgxFDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xHzAdBgNV +BAMMFmNlcnRpZmljYXRlLnRlc3Rpbi5jb20XDTI0MDQyMzAzMTIwM1oXDTM0MDQy +MTAzMTIwM1owFDASAgECFw0yNDA0MjMwMzEyMDNaoA4wDDAKBgNVHRQEAwIBATAK +BggqhkjOPQQDAgNoADBlAjA4Qjgh11pRcsg99pgY5qWKwaEA3Z6DPvoIx/WcKpze +EeiA3T0IgldXK29SXQZuwGoCMQDfCH+laeI/8XNGMd2HDBkTP/eesx3DVp/3CbEH +tjpbT6156iaDvJG7BmTtBE312Dg= +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIIBSDCB0DAKBggqhkjOPQQDAjBmMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx +FDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xIzAhBgNVBAMM +GmNlcnRpZmljYXRlLnRlc3Rpbi5tdWwuY29tFw0yNDA0MjMwMzEyMDNaFw0zNDA0 +MjEwMzEyMDNaMDwwEgIBAhcNMjQwNDIzMDMxMjAzWjASAgEDFw0yNDA0MjMwMzEy +MDNaMBICAQQXDTI0MDQyMzAzMTIwM1owCgYIKoZIzj0EAwIDZwAwZAIwTRTLX7+/ +q+w3AbYwvd+qmoRM7IVyMBiJewE8+3/T8x23K1YMGvpT9KTjyjACu3DDAjB4bfcR +XmmSF8Ou/ZVvky859BNn3IzKxPSt+pEO7zmS4p2csBC3+2JMf/L+6omLRhY= +-----END X509 CRL----- diff --git a/testcode/testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der b/testcode/testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der new file mode 100644 index 00000000..5d6a7e49 Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.csr.der differ diff --git a/testcode/testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.key.der b/testcode/testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.key.der new file mode 100644 index 00000000..209b069c Binary files /dev/null and b/testcode/testdata/cert/asn1/ecdsa_sha_csr/ec_app256SHA256.key.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_akid_repeat.der b/testcode/testdata/cert/asn1/extensions/cert_ext_akid_repeat.der new file mode 100644 index 00000000..c36346c0 Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_akid_repeat.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_bcons_repeat.der b/testcode/testdata/cert/asn1/extensions/cert_ext_bcons_repeat.der new file mode 100644 index 00000000..fa1266a9 Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_bcons_repeat.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_exku_repeat.der b/testcode/testdata/cert/asn1/extensions/cert_ext_exku_repeat.der new file mode 100644 index 00000000..3b0acffc Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_exku_repeat.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_keyusage_err.der b/testcode/testdata/cert/asn1/extensions/cert_ext_keyusage_err.der new file mode 100644 index 00000000..276ca817 Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_keyusage_err.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_keyusage_repeat.der b/testcode/testdata/cert/asn1/extensions/cert_ext_keyusage_repeat.der new file mode 100644 index 00000000..ca30e010 Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_keyusage_repeat.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_san_repeat.der b/testcode/testdata/cert/asn1/extensions/cert_ext_san_repeat.der new file mode 100644 index 00000000..8d0b5330 Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_san_repeat.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_ext_skid_repeat.der b/testcode/testdata/cert/asn1/extensions/cert_ext_skid_repeat.der new file mode 100644 index 00000000..7b703cb5 Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_ext_skid_repeat.der differ diff --git a/testcode/testdata/cert/asn1/extensions/cert_extensions.der b/testcode/testdata/cert/asn1/extensions/cert_extensions.der new file mode 100644 index 00000000..09e0e8ab Binary files /dev/null and b/testcode/testdata/cert/asn1/extensions/cert_extensions.der differ diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.der b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.der new file mode 100644 index 00000000..4f32800a Binary files /dev/null and b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.der differ diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.pem b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.pem new file mode 100644 index 00000000..9156eb48 --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8-enc.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQo7qMr3MhZkRjN6i3 +cKUuTQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEL62l4Bl736EWj4j +NtfmxeIEggTQqK8UiBAfSxrfhWmbWtYBkpgLCn1ijRr0C2PaXp41W4/CkTTBxDqF +7us9Ee5KzxHoQ5RyFhI2FOwmfbYDpYTXI87jIxwOfuVQAcT8yW+FMpyQbsYURSQc +GOfpJNVu8zq9YZyGXxN6V8JwCHYAmw4GLXAwj8Tnw4fNBNedTTSo5Blz0Tr84n9e +X0Va8uAvtRMCc/hnI/sMjHt8PB13VmuS5ZO1ly7HNHjbnRPS1lZtLBKOv5nyI/03 +7mAnbR91M2PgIUotfQw4AgzqN5SVW4aS8n+JUUft4LHvRP7j2rvNr2MGxhVL9rvI +BzNRIr5omdgBeF4KDfpZSwhyi4LSdD1pv7LdPoIbiGqi+nbrvLe0+7gmcYLprvA/ +AvmSxz92AAYz/kcHYLFRZ+Z/Ld3IZEth5w/0JqxroCDjizx643czPqIwRdBWsHn8 +KlV/mXOIvd2C39Up+m3FqgAszstbGICy7vVMv0PSafF7AGfaMe/BBCCmAJ6pTKHt +kgXomM0b9U/qpJ0QEaYXEWELyQQY09M9yLYzxRhkHz3OemjoEIiVf/jftKwTB7rC +oHO8Zx+QtPPjjFukLI13zY5dSl3YZZECrrCfQZSJpndrS8rEYhUh5lV5wrIoRvIa +jO+jfpG7DuvCP/1a+ZAdAjGv21jPOOVjBpRgvqiHTQ5BiRUd+xtrz4p2SDJmbIf4 +qA118DWiF3XiigoVYjHLAdkSn6ISX4RlcTqdTBXJiU0Q91MyBCZDuPYjPZxKw3ZB +lnvVPocSVm8g3QVxsFFx+i9s5Gy+IICb9f9HdDXr4RfqixxmX4ZSvebm+1gnhLfU +22RZDaIdvu10SrVZe6PHj2V/Xx6SQVBfOZBPbYnk+qolRMGPMQQW4jPnT0tVKyFh +Glh3+JWOm1x6DR88cj/jiycyi3lJ4DwWJ2n9bebOyDYayECbdWfcX+/LpB4uHK0K +okmHGzC51/b+Jw2Oj7Yn51Oetzgi7ONZ3zDuyK1OW8Nkq6qdtqLBhQw8w5oX+bBN +rYD5FOCoPE4prCL+zhdJAEMhuO4rtc3mqTC4ralt9tXpQysD0/xB06Bk5eL4H8Ab +jYtp3mGyqGV8whuuB8vG8O5tO8Ahg/ldlZIrsrG8Hr/rnAP81CjG8DTsMYJfbwjp +PTWdT6k7sHvZqrF1VUcK2npDHwJ80AMuc5wyEuQtU84mRR38lo11/wKfnZqxnbBx +0vZU8nqd6k0AimrhKoLdy0XCC+fufzIvHbMoaLkbrVjVpyOyGO8jTMVz3wR3PIkt +q+Yj4NldbhzV1qs6IryCdOAm6qRyWb6LUpVoCmFvGOMf961IiLub15I5BOA/3kct +hhwajY53Xqh4P56COUefuSrL665APoKiQUUhEz0xCxP3jTQ1/fUck+uEyd8/JBJO +8u2daaGSs23mzeaEAH6XKgHEHJ2czrqj5o0FN77tXo1OhCdtMmig8D527G7l0o7B +iKz+FXaStmirvkk5lxDmc8ZT+7/piwGIpgq8U09tL/qu3q7zqUwmMvscScs897Ma +hxWjf94MpxbHk17TXKcxkrGrYb8ndE6xXkVzyj2uONFSsWjnM+S4zuVPVAC18WMD +SDslcAytzQ5n2n+xs13KESMPUKBaFulxaeDsOL1pENihM9RbMaXTbx8= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8.der b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8.der new file mode 100644 index 00000000..18a800cb Binary files /dev/null and b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8.der differ diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8.pem b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8.pem new file mode 100644 index 00000000..2ca55bb7 --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa-pri-key-p8.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDDO/22L/rCRjQb +t7HF7GZDtVnNI9ziO3nJITT8q5F4dVmXl5+VeQTxOn2EmVeF4uFcxOfr61CAb7Vk +XTFhqGDnqZQ+1tTXtKJoPno2sOZcrIHmqZk9QWXkVtsnCTDf4hqgJWs0pPCk54Rp +eZr9cZO1usng2GeTgc0JCKKypnNS/ymXq+NhEd3ZPAwwzzx+j/0kotIwnLfabQ81 +XAdnVKqFjsFyN7YSf/P0MQrYuQkUmKLvImNQqCgryO/5FPHnrOduWhdXk5R9CwHJ +a32bKPPBrNyFNRX7IUSEoz/lTYyxbymJjAvRhAaN3QyJn5uXJN5FpsJDzOZRrHq0 +f2G+IZclAgMBAAECggEAEnRySC2C46hlNpWHrXDqPc4/vd98+rmqinOkIZpKNvvI +y0ae5C87Y14nDUi9eD95FB7c2XU1994XZHRWvad/+YYTKFmAZx+BFp+JR/Ay5mG8 +KcSwYpTy/8GiF6+Lui4SXD8NQj2xLbVg0+OV3g1FbDFK8gEi0VO8wPTbBE4tqpOf +2ru/I89M0LBnBJWIIDw53DhJAmQeaRS94ukB3ETc7gaYLquiR/m8qYBmcqic4XyO +MDqcxhUmrENNMO//cBKDr4QjIMOOXlz1IZZ7GjNnjlxPmgByiy1D1je3mZxI+3hC +dUBRmFmuJr9rCc5p3d9dq6uuyQaX2UyZ8Zm1JK1/pQKBgQDo6t8mTXBrLgCrNDgU +bCc0U3BWXaLfX0zPcr4epUw/5bUMfzo3sZGJTNgAxsXTVI6fcMX3u6dM3SjbcSY0 +EL3eJaYgoCKy9GksdngXNCFv+ggUfw5Jt+00VXDVeHzPwwFqSAiPvdFTXMqpGQ+9 +KjnYX2N1QVDDWdsJK/wFLbDlewKBgQDWlRiyWdJEQ0tCXc1imIgFa6izgB3jV0Ax +jyxcfnrqhpR7KvM0wYuV3k5BhiZOFe7WC+caL+MyRrvKI3eMdHYiHkVa46EEfzJn +gSqpm50IpSTYSul+DWhrcsePcACGZO9XTkq2W2IZHpOdx4eTiQIu5Bl2YwBWDGuH +glQ4zafD3wKBgGOMDremHUgRr0N83AMOfmsExlyDRJtHdeKr3cnnSAF/QbQHpHAt +OlB+QUuDqQU7fIF0h4fr8gMN+upfH77c8OlDGg+ToYDuqQzRzV3NcAUVzeJEs2ya +aY0Wf1UdW+rII5CzHMWikRaZ8Bv5lBp7M6HgkveIZOY5Pz5aSCpGbvaFAoGAAqRt +XGzcuPh3KccL62XjbuWneyZdt9nwMWwI6M6p5s9nbqjVu9WSSXMmVYo4WIfOnBYj +b2AdlRXn5BJRu4oHll33Dqp05iBG151wkAwZf+zAqmUpwOKbYY9VQ7/mUcFWbSXK +p7oyWArXWH8HfVqXi0pFwf5wF58ph86kCNsHcNMCgYByx2+CWw4jOn22qKQI4adv +seDkczU4qBQUahQW8+zGId6lIrz4U+krKiPJwsDpxdVVtYfcdEkC6sbKOkrNYvq4 +U6tMyVz9Na5joq7fGuIVGrZHyJtbhaJWosyp9wNBC//9JNgENlG/FSE3fJqhYIwQ +JvQ/VzQCD0WyhAEaIICAfw== +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pri-key.der b/testcode/testdata/cert/asn1/keypem/rsa-pri-key.der new file mode 100644 index 00000000..94d124c6 Binary files /dev/null and b/testcode/testdata/cert/asn1/keypem/rsa-pri-key.der differ diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pri-key.pem b/testcode/testdata/cert/asn1/keypem/rsa-pri-key.pem new file mode 100644 index 00000000..47f5decd --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa-pri-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAwzv9ti/6wkY0G7exxexmQ7VZzSPc4jt5ySE0/KuReHVZl5ef +lXkE8Tp9hJlXheLhXMTn6+tQgG+1ZF0xYahg56mUPtbU17SiaD56NrDmXKyB5qmZ +PUFl5FbbJwkw3+IaoCVrNKTwpOeEaXma/XGTtbrJ4Nhnk4HNCQiisqZzUv8pl6vj +YRHd2TwMMM88fo/9JKLSMJy32m0PNVwHZ1SqhY7Bcje2En/z9DEK2LkJFJii7yJj +UKgoK8jv+RTx56znbloXV5OUfQsByWt9myjzwazchTUV+yFEhKM/5U2MsW8piYwL +0YQGjd0MiZ+blyTeRabCQ8zmUax6tH9hviGXJQIDAQABAoIBABJ0ckgtguOoZTaV +h61w6j3OP73ffPq5qopzpCGaSjb7yMtGnuQvO2NeJw1IvXg/eRQe3Nl1NffeF2R0 +Vr2nf/mGEyhZgGcfgRafiUfwMuZhvCnEsGKU8v/Bohevi7ouElw/DUI9sS21YNPj +ld4NRWwxSvIBItFTvMD02wROLaqTn9q7vyPPTNCwZwSViCA8Odw4SQJkHmkUveLp +AdxE3O4GmC6rokf5vKmAZnKonOF8jjA6nMYVJqxDTTDv/3ASg6+EIyDDjl5c9SGW +exozZ45cT5oAcostQ9Y3t5mcSPt4QnVAUZhZria/awnOad3fXaurrskGl9lMmfGZ +tSStf6UCgYEA6OrfJk1way4AqzQ4FGwnNFNwVl2i319Mz3K+HqVMP+W1DH86N7GR +iUzYAMbF01SOn3DF97unTN0o23EmNBC93iWmIKAisvRpLHZ4FzQhb/oIFH8OSbft +NFVw1Xh8z8MBakgIj73RU1zKqRkPvSo52F9jdUFQw1nbCSv8BS2w5XsCgYEA1pUY +slnSRENLQl3NYpiIBWuos4Ad41dAMY8sXH566oaUeyrzNMGLld5OQYYmThXu1gvn +Gi/jMka7yiN3jHR2Ih5FWuOhBH8yZ4EqqZudCKUk2Erpfg1oa3LHj3AAhmTvV05K +tltiGR6TnceHk4kCLuQZdmMAVgxrh4JUOM2nw98CgYBjjA63ph1IEa9DfNwDDn5r +BMZcg0SbR3Xiq93J50gBf0G0B6RwLTpQfkFLg6kFO3yBdIeH6/IDDfrqXx++3PDp +QxoPk6GA7qkM0c1dzXAFFc3iRLNsmmmNFn9VHVvqyCOQsxzFopEWmfAb+ZQaezOh +4JL3iGTmOT8+WkgqRm72hQKBgAKkbVxs3Lj4dynHC+tl427lp3smXbfZ8DFsCOjO +qebPZ26o1bvVkklzJlWKOFiHzpwWI29gHZUV5+QSUbuKB5Zd9w6qdOYgRtedcJAM +GX/swKplKcDim2GPVUO/5lHBVm0lyqe6MlgK11h/B31al4tKRcH+cBefKYfOpAjb +B3DTAoGAcsdvglsOIzp9tqikCOGnb7Hg5HM1OKgUFGoUFvPsxiHepSK8+FPpKyoj +ycLA6cXVVbWH3HRJAurGyjpKzWL6uFOrTMlc/TWuY6Ku3xriFRq2R8ibW4WiVqLM +qfcDQQv//STYBDZRvxUhN3yaoWCMECb0P1c0Ag9FsoQBGiCAgH8= +-----END RSA PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pub-key-p8.der b/testcode/testdata/cert/asn1/keypem/rsa-pub-key-p8.der new file mode 100644 index 00000000..152e9534 Binary files /dev/null and b/testcode/testdata/cert/asn1/keypem/rsa-pub-key-p8.der differ diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pub-key-p8.pem b/testcode/testdata/cert/asn1/keypem/rsa-pub-key-p8.pem new file mode 100644 index 00000000..70c70f3b --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa-pub-key-p8.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwzv9ti/6wkY0G7exxexm +Q7VZzSPc4jt5ySE0/KuReHVZl5eflXkE8Tp9hJlXheLhXMTn6+tQgG+1ZF0xYahg +56mUPtbU17SiaD56NrDmXKyB5qmZPUFl5FbbJwkw3+IaoCVrNKTwpOeEaXma/XGT +tbrJ4Nhnk4HNCQiisqZzUv8pl6vjYRHd2TwMMM88fo/9JKLSMJy32m0PNVwHZ1Sq +hY7Bcje2En/z9DEK2LkJFJii7yJjUKgoK8jv+RTx56znbloXV5OUfQsByWt9myjz +wazchTUV+yFEhKM/5U2MsW8piYwL0YQGjd0MiZ+blyTeRabCQ8zmUax6tH9hviGX +JQIDAQAB +-----END PUBLIC KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pub-key.der b/testcode/testdata/cert/asn1/keypem/rsa-pub-key.der new file mode 100644 index 00000000..a379d62f Binary files /dev/null and b/testcode/testdata/cert/asn1/keypem/rsa-pub-key.der differ diff --git a/testcode/testdata/cert/asn1/keypem/rsa-pub-key.pem b/testcode/testdata/cert/asn1/keypem/rsa-pub-key.pem new file mode 100644 index 00000000..2696d2a8 --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa-pub-key.pem @@ -0,0 +1,8 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEAwzv9ti/6wkY0G7exxexmQ7VZzSPc4jt5ySE0/KuReHVZl5eflXkE +8Tp9hJlXheLhXMTn6+tQgG+1ZF0xYahg56mUPtbU17SiaD56NrDmXKyB5qmZPUFl +5FbbJwkw3+IaoCVrNKTwpOeEaXma/XGTtbrJ4Nhnk4HNCQiisqZzUv8pl6vjYRHd +2TwMMM88fo/9JKLSMJy32m0PNVwHZ1SqhY7Bcje2En/z9DEK2LkJFJii7yJjUKgo +K8jv+RTx56znbloXV5OUfQsByWt9myjzwazchTUV+yFEhKM/5U2MsW8piYwL0YQG +jd0MiZ+blyTeRabCQ8zmUax6tH9hviGXJQIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa_pss.key b/testcode/testdata/cert/asn1/keypem/rsa_pss.key new file mode 100644 index 00000000..b946a93e --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa_pss.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADALBgkqhkiG9w0BAQoEggSoMIIEpAIBAAKCAQEA2Eb5q3jD5Km92f+P +ZpshB0UQHsPKDkCgnMUk3h0zXsTAtbDwTvu3lJnFvSiXaOXvwDWfJtjH4kr6XtHo +7yMSAI8opy3l7qzIeAI35qUHeTJIa72wEoZi29u+liCzylPsFnpfdoDHJcJLkE8k +VBnp2YGr68IB9HTtckX56fygop41B9Mk6EIi9Vyf9TWePLcHlaGitzhFLmyl8VD9 +U5l5BC8XVB3JEtwapH+pIZ+WX2lYNaZD3WZFMhaHY1Yfrt4r3zkKL8OS0NkGugAZ +Y2RCr3MbLaOyLeynBQySjb2y50jKLZFsnPo/9mNaOcgdcd092GhCSkC9vyPTcooy +gKHk4QIDAQABAoIBAGYe9UrbBhxVbdiejDaVrz3AhYERT7n1GCGOEP9z6EqqOphQ +CNgykRdwmGbd4MheMhue9hwgphka8CePlB4+gASVlEuEJ5rQKQRJf92/NM0sSffd +pGLK46kOlGpM3Lf/cm2WsLbCzcXtfUKRrASuC7ZxPR1gCQ5Fm8ymb//lEnBVxwG0 +anMeH8BUKBZzvOn3I1DWfoItprPdJ5N+x/GjV2owQH0eJ2ByXRcGsBRrv3WUpWt4 +75bJFwUtWvh8wzgVJLFNx1haSU1t5HAF5JcLtLXQO/OxwKWPGYgfMR6nVVKaXQLV +kjoUjfr03d84qVLp5EhZYmQMhog76WRlMc+yljECgYEA+PjKUvcAnQBhtmGqmEjm +F5WWKhPl33Qqxeja83aAqARwgEXePwczTKJgsSU9z0ak880o6IJnB+2NfQqJ1bVS +i2g3oPdUckeIO3SQa+m7LeB+kxGbYQvVzrafQh6jci0AvuXHFW64UDUOGYQU8Nx+ +SjMPFtjBw4PK27SSqhnEWJ0CgYEA3mHqYiX/inyWcd1e1ePmI2HjWpX35QH5k3SG +Y94ctENtMn04woCFtRIuIbquZp4IKZrCm4NL1HmE5QFIamWeFc0+tOgb20VlEDeL +J5TXnhLf97N76LyiaeNjZsWMiF7BIIosoOTKBcw+++V4d11DbTyVxyhXQVaJTveh +oIBPIBUCgYEAq+vokme8Ba5Iyw8gJS5ZrLl/yyiYWLg3/RfxcaNH7j26jekxMea/ +9tA94rVrvCD1MOFfuUaq7N+OD2Vijq86A8gAeeewaYWZviycudfZiDF4VggXemkY +yDh1Osw7Y1FOLYQv+E3PeptYVChP6Y7oqkYdylH9Ywwz3YkQqeNHIUUCgYEAp3dj +M0BcPSTvgpXrWfWClLidptTy1nFzShjhL4nPYey46eGlAcwZZK9pMBtORJbTnMkf +rk7kpwBQFMiviPg3YUGr7D4y5CBRKDI7x7Xt3etm4Dk4oZ6UTFthur4fw35fv6pu +S0ef31fdQoKfAnyoTzXlsRHvC5QoWOBgxeZ6L7UCgYB1xGF1YJihBmlqnqgBRkq8 +G2ChoxDKe7UMVQtaTIm+wgPCv7nqDW5i4AJHqbqSAajyBI614F3bNRbC+eqvefNC +/An6b+iEOh5WwtbcUiNJwd8apiit0WPI3pFa68XYNdKCmQJ4YXiX9QJv1iJTiXvi +7mU/nqLf8ynt+h8ETomegw== +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa_pss_mdsha256.key b/testcode/testdata/cert/asn1/keypem/rsa_pss_mdsha256.key new file mode 100644 index 00000000..aa10eee3 --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa_pss_mdsha256.key @@ -0,0 +1,29 @@ +-----BEGIN PRIVATE KEY----- +MIIE6AIBADA4BgkqhkiG9w0BAQowK6ANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3 +DQEBCDALBglghkgBZQMEAgEEggSnMIIEowIBAAKCAQEAuxD+Yw70+1ZaZIlI5USN +Gj17drlihLaePUKbiIx5IutH/i5Gibs6uXkxHvqewrIEGykPDlOFjn8bNTXUuwz9 +/lykgXHYJxJnoDkGf7kViEtgLngTYGdRGeU5qAli3AlfujtsyEtPsKGmvzMmq14x +NFsGB+CNFU13j9pHersD1v+tflqvu8lb9u4gg08qP9/0f8mPNlHCfHMGZF9gJyV5 +V+Qkgp/Em6K+GNa7FHe57W2I2RqVBkRN4+VNpAVrPaeKRfyi6mb6rl1+Ivft89TM +oNOBverqcIfyYJGC9ELpgmDQX48saialY+ogMfK5oRTpnslJMWVb+hq4i+5nZWuo +0wIDAQABAoIBACPmOfuGpksJomVC12NwSWfsvqHlJ9vyM+Hrw29sDd8+qd1EwjKy +ZK2tbVjVndwdT55qvcHxE2NqTy1h/EY9Uw0aeFODJokxBgQAjZe7TD+Qv4+LaaSJ +j03Z6LuvuXIitmVF/DVgBpYOH7L3vQcMF4NFqJ2gYVLiP/yyVh9efnkm2Wyvdk8q +TkDInQrkSMWHosleejbydIxsGwiE5RBsPo0lD0GrMweSR0VYvZei+IE8Mz12HFvm +WqC5aOARkp6VZmj3C2xQUoAnC+NYCLWyrYp15dzAdeFK/pySoZVjFLfwXYihqB0x +mJ2cf561Re/8kI6iAGDssTCRKQM0EObI8PECgYEA9oRsowKK/dN5sZfZsS/H1NR9 +nW68tGv7hlQNKzqRT4KAwVJv9094zIWN6KlvdnaAgipIdJkAUUUroq/drsMf/dEq +THQ8aSBpYL7acVyqtB2bEyG4N7/NAsJRzN6bf5pQexTLU3aGV96/IoVXxQuzeMf9 +WDCSfL9ZGH9nNkpPbBkCgYEAwkMgnFU/zeyaEo+Cq2dTaQbtgewgIMCaMhKPxH/G +7ahKUqAGq+FBUF/ZHfd87u16J8QaxqRz6ULdNxCu6ueB+LxHBdmakD39UHPuq4Np +nh4RxadTUEfi2nVKWoJAroq3QHLw8CiyUg4XUtqmTNX52FaXhy5bBY1Ou2C2k0JG +mcsCgYAhqlgDsvc0TssRu8EY94N8x0AYXeUbZpvE7nmV67uodhQLUqzDw3ClzZ9h +pLH6JZjLLecTNUnbz2x0HTxS/4bA7O2v3zfYy3pYoffG/3a4fkqNRE+aHXFr7Qmq +xsPJm1NeW6qgzVDvcxX7KuafnEd4OSeaAZgfvSn3tH5t5ZwPEQKBgQCd0JzYhCT+ +bJ1KQM3940YOx7MBXktHcFCUJyIml0uLXLFsaFajIa7G1ebzglA7Zi9byOObxpPn +xwshpesEKKkc4g+sv/fiAIoe5t/Y9DxEWNdFREbZrFyt7qVF3BUh9s0ijX4RDG65 +XHs0My7wstBzIP2es1j8rKxuawZHoYrrewKBgEKy3uc5bF5hM3dvE95MRNyKkiv9 +Ebv+5GiJVfikKAHmwrPWUIh7+uZ4w0DwJiij5WpB85ukhgDrdBi1ODEyrdM/h/FD +0uEcl9KeortiH7spu1a5oiqqhqaK3QlTzHKm67NTxPRqptz6R8e68WMbudDbeo4B +C2Cm7DejnbvhgDnL +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa_pss_mgfsha256.key b/testcode/testdata/cert/asn1/keypem/rsa_pss_mgfsha256.key new file mode 100644 index 00000000..5914d13f --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa_pss_mgfsha256.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIE2QIBADApBgkqhkiG9w0BAQowHKEaMBgGCSqGSIb3DQEBCDALBglghkgBZQME +AgEEggSnMIIEowIBAAKCAQEAp8t1sPjtzjpJPZGp43JbODZBABzfWeb36eQXgFWG +opWXRkAf3Z52aJOsox8hKQ8wAl2aBAIA3ftBZoQ70id7UOIHksbiQFajCkG005Wk +x8/ujqvY7ynesSD6xHu5VQZ6IY/UeZBBV5uS2M6HWgcEvMSC0hVSYiGB4I/TnChW +sS6of8FhN8bBS3P1dOVtpEreImb0InXB20hDvFwGYA6dPAsrfMihD/JDs78s8GJ6 +vtgNQa82ldNhRCUFhJIEGO3Nd/4SMCUtRD4sN1m7CM62WxboEhFQCkXJKF49vOo9 +/2YAod6X6CzcqNVT0JPlp4fV6QiK9uBB+4HdAhmpbWwuvQIDAQABAoIBAH8RZxkU +ChKotRo5GyyxRz80ZtkNBF9yt7+aCeoX2pN5MUvz962++PCNFKmbQ2Nyquq/s4jh +c4KnaYmXDi5B0/MWmKGgl2odse5sf+HTaywd3QySOwAy9v+wd/cfsuQeuZJ892zv +v2v21qf1Dy8wLXg+YMtzdiX2NgK3KIsTSUN3VUTAlsym8LyW68p/sf5kACk4T6k2 +EutHWUm1HEEZ7pRfktWEt2GRmRMO3sr+aXwis/Cj2wKVOs4mAEWj/5zbVhF7K/35 +ege2FJNB/Splo153oVNbvK30+RMxrPRdBhQhywAYFCbIqGFVZIuuGU8EkxpbHOe9 +fB0uSowyuOQBpsECgYEA3xWJ042AkBJ4FpgxFNEYErEsXkfQ1qcZSWZyhNuOmQW4 +MB31xzAVye4JWKElv6agv+PVkyHSKTRRMsuSOt8Xi1Jn2QqF+MgksGYjGOxWmgae +CU3DbwmrqGLCzvR82rCAV/ITbGdxC8Qm2co7uT2TCMMdXK+YCsrLk6LxBO+mlYkC +gYEAwI1/53kJH2igYh6zZTRD0FYViOt7WoKbYQolmUuv4CevOXLRq51Q1zbe2Q5E +3jLCTeAgPs3+Mw/FjbADIeP1deZSE4HNF5J+6ZYmQk/J8OsTQ/73v2IKrIltlg6Z +YoSn/gjMJhJv/sUlSmOCCtwBBo3DCIwUawF9+JpBKKu6dpUCgYAzWvL6p5WUFRxe +HzUVVLlU/EJ5hdDWyWrx0crFOQIPyhhHw23kJ/asIMc4Bwj4oLRa2Gk/UMbfw3J5 +3hFQyjDSWusbNOf4iKKhlTG5OBcLqEBTZfp6omBJCEtOd0wS0BULqee8yedlTQeg +lYTANSOXHcuxnZ7DxUGuQBF6EG1p+QKBgGg8sZ8HQM8F/rzfTdJdptBjqajDgbWP +urmfmpcQCBfao9r/s02qDhdTlvP96342EEXELPCS5yeRRCrdu/ReyYSXuJriy7oV +Dis5o2CGfRW0zGsk3c13L7wTcYWoRZS1p5O4A3wgwwwygWtxzvY9/zgjCg/YdT0w +Q5ePOfLgdEK5AoGBAJnSlQpX4bTNtkq+y74tqvYvluHDKpNtNEeamXIRzVP5f0iI +fb89NArEHcxzt8esgyWRlk4lPGQBWfLiz48BbGGpyI9At/+VYFLX22cTrIu2g5Oj +hK7UmlHBChX8qzOEV5hn5sdxYNuzU68PZlCq82XZuCTWpBvgkd93AtqMeyKN +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/keypem/rsa_pss_salt10.key b/testcode/testdata/cert/asn1/keypem/rsa_pss_salt10.key new file mode 100644 index 00000000..f9fc8a22 --- /dev/null +++ b/testcode/testdata/cert/asn1/keypem/rsa_pss_salt10.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwQIBADASBgkqhkiG9w0BAQowBaIDAgEKBIIEpjCCBKICAQACggEBALQdGjOU +gQSCpxPRjfOiRl1DRG3osVm7S+9qZOS+fS+RA3ekqUPl83cZ5leIqINtvrFjWMbS +gF5XQtFHcBiQLinaNQUZaoaHWKyP09NiCGGVlgs9w17E3TrCUljwLcXOl3Sc2ek0 +b964j6wFecjkxe7w/QR1SgkNmSZPHunuU6LZZ5Lvty9JyLSHvHc0tkb8uQW0L/7w +pQQfCNu3Ja1EvTedPABPZIUeFNSNlfcFGA1AOs4r9GnZ347AXzItsYhBuf/OZ7z8 +JQ8JAXyyMCWM79zmyw49uyYcqbARnpR7Dq1d3cvVFUZvxL9xpCZw4bWHObl19h7N +MxhxmDiokLxeY2MCAwEAAQKCAQBPULGFHVRjZBWnSJS2QTOzRjgQHnRbC3u5BqU/ +hhMiqz1Xpo9TcyPvwtwImAl9NwrOmu0xQOl+ofauqkLWzkdF7u2CPVsHuvp1ozCo +2XbPYkwczyoFxbOWeJRCziGaBgv0Mk5Tv9+zuJqsKg0jRntTaZRCLlRYAED8+cKn +SWhTQaSFBfE9pUa4G7CzL6Mr1xIsN2dgCy9T6Yq0VSQjnGxFic+1Gb0FodWpFhud +6LS1IqJCdtAJNjd8VO5bcN+1dw78oFQUrDSkQyv0RrlJydYqNEkAfXW6MvyMJOia +KsLb6da8kzMSd2mMd2WlrGB5Q9aDINXQ46WCt7+o5yWuVoUBAoGBANzIh6G9h0WN +eFjeciejqltoA0Lz5sVWXaL3r8nCVqPfiuZb9cW3U8k1p14gObRnD28erhBsuENI +a7O9dxOD40qW3UKIr4vEAC0xNNGnknNz8yptrcgXJ26cxh49Q+z1KNwSDXYiFljo +AQjwSr33s804uzUZYe8UrS1pr+YUNCtDAoGBANDX3iWFbgb9dEqpwLD0Dtycb24z +gBqoP4MTU78wSqvvzt92WmHRB3jVeNuEA1IRxtpUZqDAOY3q5BALBTd0UwqlFuQ6 +gYaXEsMgbT8fLeY3QXIamOgY/i7pspGg4YFjykElPIlplmDqDzDB0n2H7S97zahG +caGPDpaWSEO2JJVhAoGAbkaC6FhgHm9g8xJ4djAbQPic2G42j85piqKoXOAComtf +V1wLUCwXX2K7LBpweBkZ7mimjHGhP4oGsYoq1caEWpcsALWA6RCG/gub1DQcxCng +BQsvR8e43FjV4/i52rtBI1qo+p5gBxwqmCpdSrFUT2bMquL4tY/gR9SIFSV2QT0C +gYBLTov8W7DhNGPKyIuDQ35YbtB/nHKFKkY8rat1NaS3ezHNwo+01fsrx05dWa0Y +2vApqmWXcblPQ3QZlN+8r2WCYSVwBujN74wEcJz0NfoHGcWvr4eTqe9+WybY/HpU +ffdgply98CUZrUzs9/c+7NTKWoo+M6il6UAJbQeB4xwuAQKBgEdV+Ljil9prwsh7 +nehgnkWiDv4duN6n5n9WWMrtMK8KsZI5a+bUX4j/KAZzH86biuE2xQ1/DOrEW1j1 +oPAifpJFsEhFLnuWT7Rx32fMWDKv5j6eb8IeGD56n+0Afg/T57Mggm3/OBbR3joS +EUY6CLg7wQ5gzz7L9pnU8BQDwULn +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/mulCerts.pem b/testcode/testdata/cert/asn1/mulCerts.pem new file mode 100644 index 00000000..e69de29b diff --git a/testcode/testdata/cert/asn1/nist384ca.crt b/testcode/testdata/cert/asn1/nist384ca.crt new file mode 100644 index 00000000..26e7cbf8 Binary files /dev/null and b/testcode/testdata/cert/asn1/nist384ca.crt differ diff --git a/testcode/testdata/cert/asn1/p8-enc-key.pem b/testcode/testdata/cert/asn1/p8-enc-key.pem new file mode 100644 index 00000000..c13b58f6 --- /dev/null +++ b/testcode/testdata/cert/asn1/p8-enc-key.pem @@ -0,0 +1,7 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIHNMEAGCSqGSIb3DQEFDTAzMBsGCSqGSIb3DQEFDDAOBAghhICA6T/51QICCAAw +FAYIKoZIhvcNAwcECBCxDgvI59i9BIGIY3CAqlMNBgaSI5QiiWVNJ3IpfLnEiEsW +Z0JIoHyRmKK/+cr9QPLnzxImm0TR9s4JrG3CilzTWvb0jIvbG3hu0zyFPraoMkap +8eRzWsIvC5SVel+CSjoS2mVS87cyjlD+txrmrXOVYDE+eTgMLbrLmsWh3QkCTRtF +QC7k0NNzUHTV9yGDwfqMbw== +-----END ENCRYPTED PRIVATE KEY----- \ No newline at end of file diff --git a/testcode/testdata/cert/asn1/pkcs12/chain.p12 b/testcode/testdata/cert/asn1/pkcs12/chain.p12 new file mode 100644 index 00000000..dfc4186a Binary files /dev/null and b/testcode/testdata/cert/asn1/pkcs12/chain.p12 differ diff --git a/testcode/testdata/cert/asn1/prikey.pem b/testcode/testdata/cert/asn1/prikey.pem new file mode 100644 index 00000000..8ea7399d --- /dev/null +++ b/testcode/testdata/cert/asn1/prikey.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgVcB/UNPxalR9zDYAjQIf +jojUDiQuGnSJrFEEzZPT/92hRANCAASc7UJtgnF/abqWM60T3XNJEzBv5ez9TdwK +H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/testcode/testdata/cert/asn1/prime256v1.der b/testcode/testdata/cert/asn1/prime256v1.der new file mode 100644 index 00000000..a59ed0b6 Binary files /dev/null and b/testcode/testdata/cert/asn1/prime256v1.der differ diff --git a/testcode/testdata/cert/asn1/prime256v1.pem b/testcode/testdata/cert/asn1/prime256v1.pem new file mode 100644 index 00000000..7dc8ced8 --- /dev/null +++ b/testcode/testdata/cert/asn1/prime256v1.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIAadtjyegBKXLH9xvNDvH24j7cn3PsaNSXSMIVmvJZM7oAoGCCqGSM49 +AwEHoUQDQgAEPFKNDGyE7HES1hPd8mXydX4QunGvk37ISPOhXJStzxTt8sWdcEtV +gaXhArNx9Dz8pKIhoGcviy8xML3wPICv9Q== +-----END EC PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/prime256v1_pkcs8.der b/testcode/testdata/cert/asn1/prime256v1_pkcs8.der new file mode 100644 index 00000000..612937c5 Binary files /dev/null and b/testcode/testdata/cert/asn1/prime256v1_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/prime256v1_pkcs8.pem b/testcode/testdata/cert/asn1/prime256v1_pkcs8.pem new file mode 100644 index 00000000..71f77a2e --- /dev/null +++ b/testcode/testdata/cert/asn1/prime256v1_pkcs8.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBp22PJ6AEpcsf3G8 +0O8fbiPtyfc+xo1JdIwhWa8lkzuhRANCAAQ8Uo0MbITscRLWE93yZfJ1fhC6ca+T +fshI86FclK3PFO3yxZ1wS1WBpeECs3H0PPykoiGgZy+LLzEwvfA8gK/1 +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc.der b/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc.der new file mode 100644 index 00000000..f346c7bf Binary files /dev/null and b/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc.der differ diff --git a/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc.pem b/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc.pem new file mode 100644 index 00000000..dda97879 --- /dev/null +++ b/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc.pem @@ -0,0 +1,8 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIH0MF8GCSqGSIb3DQEFDTBSMDEGCSqGSIb3DQEFDDAkBBCEpzgVJ5gjYaghyqFy +i6oKAgIIADAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQYOIPy3SUZucC1PRb +/yBbYwSBkLRWLJI7QPctEaNn05Gcmyk8n4d9XOcFmphg+iqe/qGiHYigxFP7BNc+ +6Bj3OO38icSwUn+dnfMqE4QXIphhagbScVviUNYuIYIHoaw7fdv3DswEe87CaUbJ +ogcripV/9zrltcvR8APHYymWzYijfqR/Bd6FUoThny5MIP7SKBdlbYdtVs9u0rgd +GRjqMJ2+/g== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc1.der b/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc1.der new file mode 100644 index 00000000..9c179327 Binary files /dev/null and b/testcode/testdata/cert/asn1/prime256v1_pkcs8_enc1.der differ diff --git a/testcode/testdata/cert/asn1/prime256v1pub.der b/testcode/testdata/cert/asn1/prime256v1pub.der new file mode 100644 index 00000000..6cf31245 Binary files /dev/null and b/testcode/testdata/cert/asn1/prime256v1pub.der differ diff --git a/testcode/testdata/cert/asn1/pubkey.pem b/testcode/testdata/cert/asn1/pubkey.pem new file mode 100644 index 00000000..66f5ec3c --- /dev/null +++ b/testcode/testdata/cert/asn1/pubkey.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEn1LlwLN/KBYQRVH6HfIMTzfEqJOVztLe +kLchp2hi78cCaMY81FBlYs8J9l7krc+M4aBeCGYFjba+hiXttJWPL7ydlE+5UG4U +Nkn3Eos8EiZByi9DVsyfy9eejh+8AXgp +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/testcode/testdata/cert/asn1/publicpkcs8.pem b/testcode/testdata/cert/asn1/publicpkcs8.pem new file mode 100644 index 00000000..a40b7c02 --- /dev/null +++ b/testcode/testdata/cert/asn1/publicpkcs8.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApU4bOGGwfpfZnxdGyw/U +tibmm40sYzJJLeN0Ke3lyJECEd0gMeZ8dAT6WNl+PfIUaK9qkvpgqGoEIFjUehn9 +6mU84hM+v6D2vy7y3yDfvdDe08953o4cwadIr599Q1pKCLBXnRov3Lfw5KR3D7aG +DSKosDcJ74CBFZKnkup9WBhXJdeHh/BfgyELQrAStlV+vbj+Rsbz9aeLJoQM2VHY +loEYDMgXMH62c+3T5plQhFbINBEufp8SE3bl9QYGNalmD1Ddk4zNZDph08/NPh1M +HXUVdvAp6IpSIjfSWnN2qxuBM7dcrtg4kzlhP9OThxcBN8WJosW7r7W5qwxIgE0u +IQIDAQAB +-----END PUBLIC KEY----- diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs1.der b/testcode/testdata/cert/asn1/rsa2048key_pkcs1.der new file mode 100644 index 00000000..4ffb5cee Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa2048key_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs1.pem b/testcode/testdata/cert/asn1/rsa2048key_pkcs1.pem new file mode 100644 index 00000000..ed8ec354 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa2048key_pkcs1.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEApU4bOGGwfpfZnxdGyw/Utibmm40sYzJJLeN0Ke3lyJECEd0g +MeZ8dAT6WNl+PfIUaK9qkvpgqGoEIFjUehn96mU84hM+v6D2vy7y3yDfvdDe0895 +3o4cwadIr599Q1pKCLBXnRov3Lfw5KR3D7aGDSKosDcJ74CBFZKnkup9WBhXJdeH +h/BfgyELQrAStlV+vbj+Rsbz9aeLJoQM2VHYloEYDMgXMH62c+3T5plQhFbINBEu +fp8SE3bl9QYGNalmD1Ddk4zNZDph08/NPh1MHXUVdvAp6IpSIjfSWnN2qxuBM7dc +rtg4kzlhP9OThxcBN8WJosW7r7W5qwxIgE0uIQIDAQABAoIBAEnVUSMlvwdMG8+L +PfuE3qVdSrM/owvLchQk+8WelHu5CQuhkLe5Eu1fK9JzkodokOURNLDhVDrk32Lz +SjQfV+JRxZfUsLo20v8hoSk4LbdCi8RfbzeQkheM+FI5EmH6+gZXfUqWX7peDiKR +svw5sjY7vMy4SJ/I7d8M2fws8D9gJxV2HE0nLtrb89SclHs3i1gPBJmOdXj5qk67 +Gpscmr6PCT5JfoaUKmFFxnfzXpVC46TH1HPb+RI04Tu/JMlQxbmNrMRtB79l+dRT +Kchu3cGNdPdTwvtGb1n87Z9jTozsqi6Os6ARvyV3SPN0QPhQ5QyDPjvu0MhKo7I1 +EPEQv2ECgYEA47bs05Vhtq74/I7s/7y6dni4QezJnMb1lfhb3pUXjRownK2FwvjM +EntF9wOE3td4Kxp/pTd6XRyUoq7gFsYvv203b0JI6THFMGqaLB7uEDXBkT9hEZNv +MMEGtcVN5QAtLgnTFeYUnPfutUZtbB364/knZQP52dcpiinEryJw3x8CgYEAudag +8ehP3cYjl1Z+606TxMHeaZQadErl+4spkX3ipewINdnQGtiXsiBk6LsdM9I3vZD3 +rHARoijtJaxu1WeXLy76YaKwKO72REgArs2rk6MJucSZ2XFb9uhTZcwzXrtGRyvp +tvKyH6LuePI3lsEJ8k8gdnxmUpEDlH3GWOAwir8CgYEAoJCEj3C+tLTN5i/Vl0H5 +bL4Ulo+jXcPAuV2lUd5o+9qiumd0cRVDuChqHhHCJ+tg1Wva46Gpy2vytn9+jTBz +zJPzSaVAigXJGCmiykeI768n7QX2qRD/jy4cUCFumnG0ackNqVxR3pjIHdQqJdlB +5mvxxj22eE9KAB0RjbhIRFsCgYAG2dK1GEtZcaR+P8IOCqeH6V25pqwS/W/dBhRS +OMHSPBFRauYxFysAdhFCQyOgdW94nY+D293KjJexe9naJCd+pcy1LLoxyB1sBvt/ +djWNC8WgA49oZLVvNMFeT1jVdTHyDbxf8jJ+2BLSgptqA1PKiwA3Xf6nrJDlOH3H +aPxhIQKBgQCQDc2ZsZ2dv899pIn8uFb9IY6qPhcwOAL3EFp2apjGY5NwIJY4NrjC +KNowmTAqVJdga3Kh1t0GIzLZDxNprMp1XANSYjysJ26VN6gMDk6GRP+O1E3ERm/C +18kl9bre9ld3bkt+fAzCb6gnNvRp3aJI5vPTpOjQOgL27HjghDnOhA== +-----END RSA PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs8.der b/testcode/testdata/cert/asn1/rsa2048key_pkcs8.der new file mode 100644 index 00000000..48763f1e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa2048key_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs8.pem b/testcode/testdata/cert/asn1/rsa2048key_pkcs8.pem new file mode 100644 index 00000000..df497cc9 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa2048key_pkcs8.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClThs4YbB+l9mf +F0bLD9S2JuabjSxjMkkt43Qp7eXIkQIR3SAx5nx0BPpY2X498hRor2qS+mCoagQg +WNR6Gf3qZTziEz6/oPa/LvLfIN+90N7Tz3nejhzBp0ivn31DWkoIsFedGi/ct/Dk +pHcPtoYNIqiwNwnvgIEVkqeS6n1YGFcl14eH8F+DIQtCsBK2VX69uP5GxvP1p4sm +hAzZUdiWgRgMyBcwfrZz7dPmmVCEVsg0ES5+nxITduX1BgY1qWYPUN2TjM1kOmHT +z80+HUwddRV28CnoilIiN9Jac3arG4Ezt1yu2DiTOWE/05OHFwE3xYmixbuvtbmr +DEiATS4hAgMBAAECggEASdVRIyW/B0wbz4s9+4TepV1Ksz+jC8tyFCT7xZ6Ue7kJ +C6GQt7kS7V8r0nOSh2iQ5RE0sOFUOuTfYvNKNB9X4lHFl9SwujbS/yGhKTgtt0KL +xF9vN5CSF4z4UjkSYfr6Bld9SpZful4OIpGy/DmyNju8zLhIn8jt3wzZ/CzwP2An +FXYcTScu2tvz1JyUezeLWA8EmY51ePmqTrsamxyavo8JPkl+hpQqYUXGd/NelULj +pMfUc9v5EjThO78kyVDFuY2sxG0Hv2X51FMpyG7dwY1091PC+0ZvWfztn2NOjOyq +Lo6zoBG/JXdI83RA+FDlDIM+O+7QyEqjsjUQ8RC/YQKBgQDjtuzTlWG2rvj8juz/ +vLp2eLhB7MmcxvWV+FvelReNGjCcrYXC+MwSe0X3A4Te13grGn+lN3pdHJSiruAW +xi+/bTdvQkjpMcUwaposHu4QNcGRP2ERk28wwQa1xU3lAC0uCdMV5hSc9+61Rm1s +Hfrj+SdlA/nZ1ymKKcSvInDfHwKBgQC51qDx6E/dxiOXVn7rTpPEwd5plBp0SuX7 +iymRfeKl7Ag12dAa2JeyIGToux0z0je9kPescBGiKO0lrG7VZ5cvLvphorAo7vZE +SACuzauTowm5xJnZcVv26FNlzDNeu0ZHK+m28rIfou548jeWwQnyTyB2fGZSkQOU +fcZY4DCKvwKBgQCgkISPcL60tM3mL9WXQflsvhSWj6Ndw8C5XaVR3mj72qK6Z3Rx +FUO4KGoeEcIn62DVa9rjoanLa/K2f36NMHPMk/NJpUCKBckYKaLKR4jvryftBfap +EP+PLhxQIW6acbRpyQ2pXFHemMgd1Col2UHma/HGPbZ4T0oAHRGNuEhEWwKBgAbZ +0rUYS1lxpH4/wg4Kp4fpXbmmrBL9b90GFFI4wdI8EVFq5jEXKwB2EUJDI6B1b3id +j4Pb3cqMl7F72dokJ36lzLUsujHIHWwG+392NY0LxaADj2hktW80wV5PWNV1MfIN +vF/yMn7YEtKCm2oDU8qLADdd/qeskOU4fcdo/GEhAoGBAJANzZmxnZ2/z32kify4 +Vv0hjqo+FzA4AvcQWnZqmMZjk3Agljg2uMIo2jCZMCpUl2BrcqHW3QYjMtkPE2ms +ynVcA1JiPKwnbpU3qAwOToZE/47UTcRGb8LXySX1ut72V3duS358DMJvqCc29Gnd +okjm89Ok6NA6AvbseOCEOc6E +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs8_enc.der b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_enc.der new file mode 100644 index 00000000..4e5fe573 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_enc.der differ diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs8_enc.pem b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_enc.pem new file mode 100644 index 00000000..31968dd8 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_enc.pem @@ -0,0 +1,28 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClThs4YbB+l9mf +F0bLD9S2JuabjSxjMkkt43Qp7eXIkQIR3SAx5nx0BPpY2X498hRor2qS+mCoagQg +WNR6Gf3qZTziEz6/oPa/LvLfIN+90N7Tz3nejhzBp0ivn31DWkoIsFedGi/ct/Dk +pHcPtoYNIqiwNwnvgIEVkqeS6n1YGFcl14eH8F+DIQtCsBK2VX69uP5GxvP1p4sm +hAzZUdiWgRgMyBcwfrZz7dPmmVCEVsg0ES5+nxITduX1BgY1qWYPUN2TjM1kOmHT +z80+HUwddRV28CnoilIiN9Jac3arG4Ezt1yu2DiTOWE/05OHFwE3xYmixbuvtbmr +DEiATS4hAgMBAAECggEASdVRIyW/B0wbz4s9+4TepV1Ksz+jC8tyFCT7xZ6Ue7kJ +C6GQt7kS7V8r0nOSh2iQ5RE0sOFUOuTfYvNKNB9X4lHFl9SwujbS/yGhKTgtt0KL +xF9vN5CSF4z4UjkSYfr6Bld9SpZful4OIpGy/DmyNju8zLhIn8jt3wzZ/CzwP2An +FXYcTScu2tvz1JyUezeLWA8EmY51ePmqTrsamxyavo8JPkl+hpQqYUXGd/NelULj +pMfUc9v5EjThO78kyVDFuY2sxG0Hv2X51FMpyG7dwY1091PC+0ZvWfztn2NOjOyq +Lo6zoBG/JXdI83RA+FDlDIM+O+7QyEqjsjUQ8RC/YQKBgQDjtuzTlWG2rvj8juz/ +vLp2eLhB7MmcxvWV+FvelReNGjCcrYXC+MwSe0X3A4Te13grGn+lN3pdHJSiruAW +xi+/bTdvQkjpMcUwaposHu4QNcGRP2ERk28wwQa1xU3lAC0uCdMV5hSc9+61Rm1s +Hfrj+SdlA/nZ1ymKKcSvInDfHwKBgQC51qDx6E/dxiOXVn7rTpPEwd5plBp0SuX7 +iymRfeKl7Ag12dAa2JeyIGToux0z0je9kPescBGiKO0lrG7VZ5cvLvphorAo7vZE +SACuzauTowm5xJnZcVv26FNlzDNeu0ZHK+m28rIfou548jeWwQnyTyB2fGZSkQOU +fcZY4DCKvwKBgQCgkISPcL60tM3mL9WXQflsvhSWj6Ndw8C5XaVR3mj72qK6Z3Rx +FUO4KGoeEcIn62DVa9rjoanLa/K2f36NMHPMk/NJpUCKBckYKaLKR4jvryftBfap +EP+PLhxQIW6acbRpyQ2pXFHemMgd1Col2UHma/HGPbZ4T0oAHRGNuEhEWwKBgAbZ +0rUYS1lxpH4/wg4Kp4fpXbmmrBL9b90GFFI4wdI8EVFq5jEXKwB2EUJDI6B1b3id +j4Pb3cqMl7F72dokJ36lzLUsujHIHWwG+392NY0LxaADj2hktW80wV5PWNV1MfIN +vF/yMn7YEtKCm2oDU8qLADdd/qeskOU4fcdo/GEhAoGBAJANzZmxnZ2/z32kify4 +Vv0hjqo+FzA4AvcQWnZqmMZjk3Agljg2uMIo2jCZMCpUl2BrcqHW3QYjMtkPE2ms +ynVcA1JiPKwnbpU3qAwOToZE/47UTcRGb8LXySX1ut72V3duS358DMJvqCc29Gnd +okjm89Ok6NA6AvbseOCEOc6E +-----END ENCRYPTED PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.der b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.der new file mode 100644 index 00000000..d201c06d Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.der differ diff --git a/testcode/testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.pem b/testcode/testdata/cert/asn1/rsa2048key_pkcs8_sm4enc.pem new file mode 100644 index 00000000..e69de29b diff --git a/testcode/testdata/cert/asn1/rsa2048pub.pem b/testcode/testdata/cert/asn1/rsa2048pub.pem new file mode 100644 index 00000000..8b1e6cab --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa2048pub.pem @@ -0,0 +1,8 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEApU4bOGGwfpfZnxdGyw/Utibmm40sYzJJLeN0Ke3lyJECEd0gMeZ8 +dAT6WNl+PfIUaK9qkvpgqGoEIFjUehn96mU84hM+v6D2vy7y3yDfvdDe08953o4c +wadIr599Q1pKCLBXnRov3Lfw5KR3D7aGDSKosDcJ74CBFZKnkup9WBhXJdeHh/Bf +gyELQrAStlV+vbj+Rsbz9aeLJoQM2VHYloEYDMgXMH62c+3T5plQhFbINBEufp8S +E3bl9QYGNalmD1Ddk4zNZDph08/NPh1MHXUVdvAp6IpSIjfSWnN2qxuBM7dcrtg4 +kzlhP9OThxcBN8WJosW7r7W5qwxIgE0uIQIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/testcode/testdata/cert/asn1/rsa2048pub_pkcs1.der b/testcode/testdata/cert/asn1/rsa2048pub_pkcs1.der new file mode 100644 index 00000000..daaa3cd1 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa2048pub_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/rsa2048ssa-pss.crt b/testcode/testdata/cert/asn1/rsa2048ssa-pss.crt new file mode 100644 index 00000000..6df338b0 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa2048ssa-pss.crt differ diff --git a/testcode/testdata/cert/asn1/rsa2048ssa-pss.key b/testcode/testdata/cert/asn1/rsa2048ssa-pss.key new file mode 100644 index 00000000..c1eed536 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa2048ssa-pss.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADALBgkqhkiG9w0BAQoEggSnMIIEowIBAAKCAQEAx6o66qW5mWvGFyC8 +Z/DwkqBCkkC86BdfiMr4wJf1x3U4HAKE8jR9jNERosVBwFiybQTEBk0REo3ffqG+ +c0D7Ca3HThpXrdlPA8gkLLMgdDGpb6DoJ84axMq7jw/bEFRkqqm+hJteZNS56qny +MFd//GaEbDQN6uw3hNAwbDy+M94GZXd1p9OkYRnVvmuVed2xTmDBl/tiE3HjszBP +9Tzrafn5hQZc0MU7nXOOOKOdbHpiFeW0A6dyR5A/ZD88NIQkEHJnogD5Skl/2Jeg +0W+i/BE5UUuRMPmE+ZnklNmS0TaMZA8rBhiqbSUqSD2dxXfnlcjVmcvi/0d6c7Tb +x5lQXwIDAQABAoIBAGJ4GMBaZRM97J7BXUmhsPOPJ+W7Ga8Yv9vVxiItj2AD9l0R +/QD6VCTbgugUgl3bIHvVittUrKPK5jssh6GNnYDjfFSPd0hc0LQbw4NsAAht6ZMM +9xGSeu8s0J04g6AlDtSADF6XxVDS/LG3iKLAtHUFFi/K6EZAowzUI91tg5xN9eLg +LSraThXAVqXIiw5IboQv7J5/2ixz9xaUEJlyFubYbayCChEpfQ5ml2YJ+VkbGzF8 +uBkQqyOL0qFUIINBx86pm+TrGe9yadVYo0RDxBIbISRBOZ5a0l35JyVFFPF1B5nc +NBZk8yifIU9qA5Kx9ESXnZYUxSdSK2W2EAQYuHECgYEA/CrJTTSkkPOojnmITuig +RQuU3YjORxpnulzsaF1wlbZxbkBsB5L25npK/Ok43kxK0zBMAOLbsS+q90pROMwr +D5QC1uM9RbMS+QeXo9fYuorqmas5N1xIhx7SkOUD7MEdwh25mBMd8y9WTulaHzFG +eEYh0hqI0rYud435hgKyyWkCgYEAyrMmvXV+MdmSCNy1E41vKFhiZgxGBqd5CXPU +2WlAaFrOBuBk9bPDJaOBfDqJFEdllPWVsfkx7X6FwCLPgzXkSoI04rXy7MvjyU+x +e5f154QsqDk/lg3XsZDF2EYBnzMM6KqwbFDeha2UnBjWNjgUtRAleMFbKfqkYiyy +PIp7CocCgYEApX5jHKNW+bafwdmrBraPMKE4MugtEOcYemuvz5K7Z9YTvZrUC2h9 +V6ec/T0G0IXbeZyx1McODcxN9Pu2MIN2I0QtVOBP/yVWZ09/Ss1G9K5k5zNDWrza +8Kre4K8ck03ufM5LVq39MvO3PhTRy7ToHdlRKvW1JCzidB4eS8ALnDkCgYBssnVr +073AbbPqHLDds1KQiBT8NEi4+MXnU74oeFCZpVgmR97cA3H6lRuyypEH1uGaZ7fG +oKMtgFOpHQG6kwPBEOHbUUbbxNp58cpzRKIRbMelzk1S4klwZvoxaBkmjfG2MxI4 +g4VQmiy/KHJ20MwJ7IarosSIVmggXWeXH4ursQKBgECkJ0Z0+HFqVAF2Rfo1RGeB +Cb6WQA7ZuX3JfyOSMcSghD9n2WNNzof+d8U4UjmcFBK6qqh7BmU8fXDGmOj6Nx/X +LBZZW7NulGOIPkKDIqnZhb5EihMg7mfT4ByKqPirpkEEYSaEz0pCyamGfZehkgnf +8ydFAvXVIm4pOGKMo4lX +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa3072key_pkcs1.der b/testcode/testdata/cert/asn1/rsa3072key_pkcs1.der new file mode 100644 index 00000000..a26b6f42 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa3072key_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/rsa3072key_pkcs8.der b/testcode/testdata/cert/asn1/rsa3072key_pkcs8.der new file mode 100644 index 00000000..5ad373ce Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa3072key_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/rsa3072key_pkcs8.pem b/testcode/testdata/cert/asn1/rsa3072key_pkcs8.pem new file mode 100644 index 00000000..0dfa9702 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa3072key_pkcs8.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQCq2hmUDBHp5Blb +EPOBAzP7nfvacE3EKWqlKZFYjeasHIDXQ63gmo/ayZmMpdT4J+1EHOlKqnamMXDP +aFF+usGWXoNo/9B9djUA+vPhEux/RJ4vPh6jrcrRbN3PdQPBPhTYeK435JpEQlMq +Gi3NaKh9/5TPPE6lNSRJAsDP5AWMh3SPAlfY7JlhFFtDhMHt1wYBIa/l6pkY+C54 +HUMXWnNgIkGDkqwabjvZrMaJu0GQQA3D+BXKY8FBOzO5E6FrFPTB/0psqOZMG4zp +dWHCUW6wnW/864gWJXEIu8OngEQ+9pmngzmrrtrVj+Z/aJO1eMuhS6WI4jrOIvJ+ +ViC4nKNRY1SmTCBRDNpts9u2RJwF2ImoO9HWm+lbmftGSjlxICJKyBICFulbjpn3 +RM+NgQ4dgY8sFJ7N6HsghCrWlsLBXkp1+ZxHj5H/zbhMFqwymSIjE1eu+V3VxQsy +zU4uBDzGkdYSkR2KZ8IBTIm4kuouxrU8gZ3XEth3hrC2y8sv+vMCAwEAAQKCAYAR +fQJclsuynvLq0RZhIKcj3K0DVAwxxceGdnXL6bfbQDj+pTfZeMNm3XdGiqb9FnaB +SrBP60OlNARccUzTkGGbzGWJIZOsHqXC9EJzHyZuyeL4lP7lOYyRg/eZx7GFs0lw +9bwSOT0tOtjGbig9ZrbF3EaAMVJ03gwDyTCxVvbWcVBrXw2yRQMCM+ePnA7kaJEo +cSlPJdoGpfN5FLhhsz7Xb/TizJL/Su9SEw8ThBkW9JI0JWMdn2O7E0idFjb8qLKm +BhqSttsLO+mBLqLxx0s+0PL559a7R6qFPHQMMRKCuD9BI0uDnt/xXtgh/LPlWk6p +WVMBO602NLjKxL15nFsBEpZF3T4DVAnwGiJkzIa79H5ufOUn+QEX4KI4IJb8RVvM +a3kYrXQAbtHgt2VMih66z2S1GS6DgxYLsi6zcdedAxQq6fU1PJCNV43+oRiJEKWx +762jwz1ccEopUAEA1FLcVo9zvFrTr+cod4dAfEDIWWlAC4cnz060qGunRdFVJAEC +gcEA5m36aGsHJXxmfhjDAsrWrSBJ917XJSfA/+UmSd6TjlxJeCIbNSD0deoo0yMK +rY5+a6gfOGqq2lZhTsy9Z4dAFdix9fDtKxIdNoVBKBtaLGWzc1EEN4Xjs/oXlcJ4 +JWPxR4RkWtC4GvrQSl66HfQtSiK7k1waikxNBsEcgmlVp3fhMMr2l0TkcDPaRq2S +edC51jTpriXbiWQhKVp/w+ZQN5ogCdfjueUWAv+KICkrjQOpU8CRSBdMhpa06aSr +BoDzAoHBAL3PpUn8CiSJhcGDKIvSEEgfCZjPIac1qlopVoawVIMpZPSnP2ZSIVYj +/4IIezogxS1LbzfTrg2zV6ua1MhrxkVQUwQTW+8WqcX0QuaioOqwWd1S+OON6QaE +ZY/vWLNUl9QJF+1rYvsklgj/WJb3xWCjufiwPNmmoLU5IAzLc2DAktdSvkueHqmV +vuZX+O9YyBA3TG4CxgwaPd4QtN2K/RunKQDbXyKEXpz5umHzN7H/owYlnBItRt7E +iz/ZKf8eAQKBwDJ1XMMmxK7Zudvc8j8XScEpc+j+VKBnPyUJ+cNtQOSIovHyjgCp +Ub7MYtoxLzJoJJjQfN2uxfD/v1kxDjywakEebYHMmzK2Sb1ZmrX8n1dfgdc7o2/B +GuabWjTKG+McKoadoBge4mHOEHRon9rVUGGOj4KqRYmJQci72tFX3ZDJeH9lwm/H +fzpusFqPwaZ5JWiZt54R3iwMyBI1Jgsw0NoMHv3oz44ycwp/CLEYMtgzOA4F+gpO +R8ylDcKn82d+LwKBwQCy/9s0hkdaZYaKE5JtKVDJctuuC8gE1Asus8Uxh6BrgOIA +Bqk3aUSe45vVmQH8s2K/cGAWGb4OlY6b+oun5ls4iqN/OHJ+arT4RX3B2qQ+LsjQ +e6rTjcSvrLPKpUDU/XWhNGIoOBlEFiCXo5Z76HVuyXhcGneIGid8P78F0eeg2nqg +LRvgW+E2tE0vFM9hiCxDfqLJLDxwtV6ayM6IDsbbCS0V7cst1f8Tsj4emStw5U9s +QJOKYMBw3JElSTrdqAECgcEAi0Tx1u+i/MwqpaUc0dRJKHhDJXmeRAjc6voJ4Nd0 +L7nYwc6UIJgI3rFznN46wL4X6XnGXBoesft/i1cuvFx0n8/AXW1tPwXk0zgirpqg +J4SLX1YmtklGHgQuv66iNZrvBjk5qD6MCZtO2T1QwmhcwmhtSLxf6Ike6Pq7vuwK +deHThDrvMGcgWwzdkCQfPKJcOKDsUenrfdHNwa5h9vaQZ9qRdp2zsV6LrT7jPLY8 +l0rN4lW9dc0jFjxXZQBGIHU2 +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa3072pub_pkcs1.der b/testcode/testdata/cert/asn1/rsa3072pub_pkcs1.der new file mode 100644 index 00000000..1a99372e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa3072pub_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/rsa4096key_pkcs1.der b/testcode/testdata/cert/asn1/rsa4096key_pkcs1.der new file mode 100644 index 00000000..877672f7 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa4096key_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/rsa4096key_pkcs8.der b/testcode/testdata/cert/asn1/rsa4096key_pkcs8.der new file mode 100644 index 00000000..9b2c3ffa Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa4096key_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/rsa4096key_pkcs8.pem b/testcode/testdata/cert/asn1/rsa4096key_pkcs8.pem new file mode 100644 index 00000000..83c0e862 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa4096key_pkcs8.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDbtpTdp0TqLgZL +IJyqYV9qAK+VFsWTfUjaNYF5UAINKArvYMfA6A01XZmtLi4PhE0GJFfLPoA3p4LB +5LbeI+uICNWfPdjR/G78AZC4Aym3g9QyQTDEQ0I1cSuixC4UG21buOBoe0exLrc1 +v3GNZvnZErvd2QN3lCFTKo53kTMucZx60OP668H4dxa1Vrqmw1UfiAjSUNHenY6X +vyFEXdCK/fgkgL3RhlJfAiyUeF6355+MlXvxgGjmFkLEWe2+W/GeUCHy5JaAcKPV +DBzvDZcWcOMIpPSOCD7EeNXqvzo/JfWR1emhZqCY9SDNn5ls69x1pCg/oo0bLDEk +23DKiSeb2Zn1dk1R/XoyuSrx5Vxp75PeDXT2VUmLyUrKHMvD0aG4j/VVB62TMHoM +zSBrySy7X8fkFYA92kfzif/mHSnZzWZOdXQYy3Q5D6oz84gNlcWYyC7vFFGnrMYQ +ASOKkryzVFITeIHYMVbcjvTqji0svsC0LBwhERfTWm6dYNUHOMkt3c8ZSPsUlpvy +Pc/6ZeBMaYcZdIE4V2cDbLqj6WHXmZyERx11Z9KehrD+irXeSiROUl0FWeIAKOBx +HetRtKRwFZa6ADD0TmNDBDu5CzlvqPkc3DlodYMjzm3bYF59/3gniQ8tOJ7/1RPV +yIk5Eg3G6E6zYbNSXPT0VzJzt+fctQIDAQABAoICADEuZ5hOLwD0mHgMrsT80uzZ +hnQrCsL/EmW2AGt1W2AyjHAVC+HEj+BYOWQoqCrVBKDRVc2rCexrVLuuRLjo9XoX +8CmbIIOwq+9BMnHeU2I+4ir1qMLmA1YPJSNkIqRhl1MmySTaI6wntt8TIYnzeQ38 +QY1hXINR5zvElOty1zAYQlzDkaTDTUIe9jhVV6aops9OFhtt9+yK/DY/lGTHUz0p +qHgTUWorVRjrVatOXnVwJajEdWATzGdkqEFnl+46ipVTfqXuQToy/JleAsQIGL/v +OQLgWdXJRrOYENphP9qO1q90YL2+SUiz5kng5ekZytmSi2fjLQ7eD4oejNrpZLH2 +AUnSINlJW24MgCdGrnqwQDo+s1M5nFCHRMvGXNMHKrGe2CRdGu4A3CkHJVZyFMrU +VfWcRFEmS8XNjJUFXlv+L5DIjATKdG5fwpTUOC+I+MF90Wav+AdC+pYsqoa5kx7e +AnnXqXnR1MTL+TSJtw3nj19UMHrC1MUSSu9iGS4tSm/JpwSqOpwzzvOcSN+9PIdi +EZileqUrYyZUAmAyB5Scx28FVCdv8Q2vZV2efMPqjHw5JOE9aQwNLfpOa4esFxmV +/JkbuypkuWTn/SghjjJ0eh2kNIiNoVD+TdIlMNkg6iLsm5I4v3OySMrDz6g/ZkDB +D6un+faCLk2L1JsiVC2pAoIBAQD1N5gw0ATv8XbQL0z3LxkMydz7FhYKeTjmLfX6 +0IoqNWUDcb3TUrwuHuMM1Rlt/2DJji1gHLgsgisieoNIG1vARBydqbTUu+Is9XWo +6h6z1l/IF8uBcgPEbiWcuTGF4SoSdyJFzOIFc6vqIrN2be1aWa2cVOURmkR8ad5x +BfzYtkZei9qpg//NHO/AGoXN5KFZCqJ6KSeAtQyjkUgnN7gkVw2HzdfiQ+BwPXoM +w463IS1+C5i5L9/qLsRoTeWGxY4Jf5GP0eQb0/YQ6b27F3AvCKB1LUTZdM6UxPzj +DMhLQELDSR/x3CSqCE+40Ewq2LkoqQMHLVfYJHkSxICLqLx3AoIBAQDlX+OvnLjk +061bhmpIKA6PmoerWZKNEG9N0Tbq7oglmH9bnyQ35GahkoSuR2KPeO8SUfiQJoZv +mPfP3miyTk2HeEdo7jXrvWK2tsHfUCSKU9WpYV1qev+uGJWzPrJ3GXFvV8lEzC4P +bsigHAWxCkHBN51FwZlEFFUxJyn+12CJvDDkiCJL2slJ4Jp/uYDpcA2CmIw2xTC8 +3NzMkdBkHB3GzLWXSzRT9FioNw0QEismQNHsn/rqKGFmwpNmLsjHUUtuBRhPEiOR +zwlbkaOp7YGlWLLgrMahSx6ubLoACqU8GfOF03lt9fqDlKq7ZNAFfiJRP1ieRe0v +Hi0fDDW2iXczAoIBAQCu+o3J/xYW1bnPkoEcPWplmsHqFXeC379/WLqW0CpXNiSv +kYFAA2CulHG2HXX47Ot2x9KPK88sS3JWNw/o60TMbI3y3z9fMfaR2FGuR+nCsC1G +zdv0sZQIngSO0gOJogNwi7xUDIAYHdNFzp862fQtraJZ1KZkqi1GjhEhm4EybtbF +7owIvF1TUtutu/9QzV1o+VK5UxaSHB85tJjFC1iF7eyExJjRJ1hHH0cxRnZXLQCW +WdYQBx6Dr/2M5FDtm5jgJDyNYNuiE90ZcoFluLLfjQtasgPYHCaxN+OwbNWcBO3f +BhYactliz2171n8Tb/SoE/pKK8vsOxJ+FuQXRD+/AoIBACrLKAyEfc5bW7V+r2eE +6aqLFxK15GyjC1EGXmuYUxhIikJKv5QZ7bfpQQ3Ozamc02Wkm24xcdVyQZGrmfbi +Ov6yRwhhoPe5XqheEm+aYSbZmzw9qRMLnZYaihtl8B/eRFaUlz1ZpqJEdfPBJqKw +GjJ1MMdp5jFYZciE2QXtotovnSOV7mgein1ZBRodPtrOiAa8dTRmt8AUqLEV5z42 +LKwBV0PBySJ8rOm9U5eS/C/n2gJ+mm6DWCC23o8q3VSqaxs8ohtmc/JpIQLPeixi +3lQ95ymZsnk3LaM3L8CAO/GpmdB28um8AZ/45Z2OomzT6o0j92GYBDdNNvfa7E6A ++RcCggEAIj4qQO+cGz1+bRzOpLgIcCMo/u06bmJICLzo/5KnL99egbPcyLXGMwhU +iinFiYARw6IogGyQoKoMDYaioDZV3nZ4jzozTk1PuCd9nMzUydfwudbb517z5GY9 +nzYi2mH6Y0jO2IzxfjIJpKhCy93n1VmSBTT67/1+uAfFEqUAcLBbgZJiOSwhl6KX +N96VTTFcPSUrZu00+qzIzMNAWeZlDsBfMFuj+g8qyK5uQDw1+8jDH/pPLgFrWhaq +c8yRUWtiBZajMDvY7/2RnSvM63JEgf61NdB6cdAw1CIBb9PqEfFEf4JpYWcNs+cD +/onf0/2WNb+SsfIHKj4+Nsy7WTBeNg== +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa4096pub_pkcs1.der b/testcode/testdata/cert/asn1/rsa4096pub_pkcs1.der new file mode 100644 index 00000000..77d385f5 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa4096pub_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/ca.der b/testcode/testdata/cert/asn1/rsa_cert/ca.der new file mode 100644 index 00000000..696dabe3 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/ca.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/ca.mul.der b/testcode/testdata/cert/asn1/rsa_cert/ca.mul.der new file mode 100644 index 00000000..8ff8562a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/ca.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/ca.noCRL.der b/testcode/testdata/cert/asn1/rsa_cert/ca.noCRL.der new file mode 100644 index 00000000..dbc9b2b5 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/ca.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/ca.notCA.der b/testcode/testdata/cert/asn1/rsa_cert/ca.notCA.der new file mode 100644 index 00000000..b5827d66 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/ca.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/ca.v1.der b/testcode/testdata/cert/asn1/rsa_cert/ca.v1.der new file mode 100644 index 00000000..20d05a7b Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/ca.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/ca_keyUsage9.der b/testcode/testdata/cert/asn1/rsa_cert/ca_keyUsage9.der new file mode 100644 index 00000000..740505ae Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/ca_keyUsage9.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end.der b/testcode/testdata/cert/asn1/rsa_cert/end.der new file mode 100644 index 00000000..927374e5 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end.mul.der b/testcode/testdata/cert/asn1/rsa_cert/end.mul.der new file mode 100644 index 00000000..0145ec1d Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end.noCRL.der b/testcode/testdata/cert/asn1/rsa_cert/end.noCRL.der new file mode 100644 index 00000000..5bd36d5d Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end.notCA.der b/testcode/testdata/cert/asn1/rsa_cert/end.notCA.der new file mode 100644 index 00000000..bbbd3574 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end.v1.der b/testcode/testdata/cert/asn1/rsa_cert/end.v1.der new file mode 100644 index 00000000..30ff389d Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end2.mul.der b/testcode/testdata/cert/asn1/rsa_cert/end2.mul.der new file mode 100644 index 00000000..97a3a88e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end2.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/end3.mul.der b/testcode/testdata/cert/asn1/rsa_cert/end3.mul.der new file mode 100644 index 00000000..38a540ec Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/end3.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/inter.der b/testcode/testdata/cert/asn1/rsa_cert/inter.der new file mode 100644 index 00000000..77cf845c Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/inter.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/inter.mul.der b/testcode/testdata/cert/asn1/rsa_cert/inter.mul.der new file mode 100644 index 00000000..427d5b00 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/inter.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/inter.noCRL.der b/testcode/testdata/cert/asn1/rsa_cert/inter.noCRL.der new file mode 100644 index 00000000..b5dde79b Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/inter.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/inter.notCA.der b/testcode/testdata/cert/asn1/rsa_cert/inter.notCA.der new file mode 100644 index 00000000..125858c1 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/inter.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/inter.v1.der b/testcode/testdata/cert/asn1/rsa_cert/inter.v1.der new file mode 100644 index 00000000..a42696d3 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/inter.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/rsa_p1.key.der b/testcode/testdata/cert/asn1/rsa_cert/rsa_p1.key.der new file mode 100644 index 00000000..e65d0cbe Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/rsa_p1.key.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/rsa_p1_v1.crt.der b/testcode/testdata/cert/asn1/rsa_cert/rsa_p1_v1.crt.der new file mode 100644 index 00000000..39fd50b2 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/rsa_p1_v1.crt.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.crt.der b/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.crt.der new file mode 100644 index 00000000..df4bcbb1 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.crt.der differ diff --git a/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem b/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem new file mode 100644 index 00000000..85dfab72 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.crt.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1jCCAb6gAwIBAgIURSktXT7yYFsRSuqV58CfvR30F7cwDQYJKoZIhvcNAQEL +BQAwGzELMAkGA1UEBhMCR0IxDDAKBgNVBAMMA2ZvbzAeFw0yNDA4MjgwODIxNDFa +Fw0zNDA4MjYwODIxNDFaMBsxCzAJBgNVBAYTAkdCMQwwCgYDVQQDDANmb28wggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiNHngJTeHmM2wFpGEv1XtD40Z +5NINfN1jYGMrn1yBE9GeQtuRyHrirmurchEqNKKe/Cy3dTCxE6eW85BY9KZJ7cqu +kj90ktYmvyNvysFNXsKVn/uHBNrA+XZZseFls0lUmYGJZaNiGEV+MBn/P9alFUAi +FZXbooUM2mqlbZJMUFN6MsiX1hQjdD0f+HiAQ5BVs/dhSnufwEkVi5ph+Do0ztsi +jeNMVAKToILCULhtPj7Dh+47H5bKT5/CYgVvQIM8F5YseNSiBqMJquM9y+mlJ25/ +IP8Vpc3Qmjkaw7xcALqXKatF2pI1MApV6V1iNqzhcRRhi3ixd8ZWOuFDQjxrAgMB +AAGjEjAQMA4GA1UdDwEB/wQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAQEAWkRDJfgV +McR9o9+Nz1rK6HdPGCQjZ8D5hdyq+UKrHdo0p/eiYRFJIx0my277dyBNrsUCGVpR +/N3c2/3Sh4qBySIHd5L1ooCVrFP0ooWjPaRQIzc31dpF/9xNghMEmoOMSbo/A3AL +wzLCqFEZPGP0ZUSBKKrNQBvuNY74UT9/KiTLJFHx4oC5xxSWx11IP6R0MNlnaXw8 +Nvu3PGtL/HVpjVl0zpJMn/K4aunGKbGXLnHyuC0vQVoqeVH2WLaZEf8BVGfq1m+b +/F8T+KRD/tToDa9O+PXIt9VZuuxuO2QDSPPOKvlUt7W7JZUmYWnLDlqz0orSR3UP +4ZR8JYYfRRbEnw== +-----END CERTIFICATE----- diff --git a/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.key.der b/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.key.der new file mode 100644 index 00000000..6d569682 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_cert/rsa_p8.key.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v1.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.der new file mode 100644 index 00000000..3f1414c6 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v1.mul.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.mul.der new file mode 100644 index 00000000..40889875 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v1.noCRL.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.noCRL.der new file mode 100644 index 00000000..a5ba810f Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v1.notCA.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.notCA.der new file mode 100644 index 00000000..57f7fd14 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v1.v1.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.v1.der new file mode 100644 index 00000000..77c353d0 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v1.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.der new file mode 100644 index 00000000..a4c8b5e2 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul.der new file mode 100644 index 00000000..acd14c6a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul.old.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul.old.der new file mode 100644 index 00000000..1b2156d6 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul2.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul2.der new file mode 100644 index 00000000..3a77273d Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul3.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul3.der new file mode 100644 index 00000000..1bafa42e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.noCRL.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.noCRL.der new file mode 100644 index 00000000..48c3cad1 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.noCRL.old.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.noCRL.old.der new file mode 100644 index 00000000..2b2e315c Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.noCRL.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.notCA.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.notCA.der new file mode 100644 index 00000000..c15b4d68 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.notCA.old.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.notCA.old.der new file mode 100644 index 00000000..d83579f0 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.notCA.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.old.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.old.der new file mode 100644 index 00000000..211bcfff Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.v1.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.v1.der new file mode 100644 index 00000000..b7137a28 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_crl/crl_v2.v1.old.der b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.v1.old.der new file mode 100644 index 00000000..6c8deb83 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_crl/crl_v2.v1.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.der new file mode 100644 index 00000000..8f6fbe7a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.mul.der new file mode 100644 index 00000000..169c6c8c Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der new file mode 100644 index 00000000..8a7eaa49 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der new file mode 100644 index 00000000..8d143b48 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.v1.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.v1.der new file mode 100644 index 00000000..9d092b77 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/ca.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.der new file mode 100644 index 00000000..fc457132 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.mul.der new file mode 100644 index 00000000..0af723c7 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der new file mode 100644 index 00000000..845357e0 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end.notCA.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.notCA.der new file mode 100644 index 00000000..f3ae789b Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end.v1.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.v1.der new file mode 100644 index 00000000..7efb5630 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end2.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end2.mul.der new file mode 100644 index 00000000..92fec295 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end2.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/end3.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/end3.mul.der new file mode 100644 index 00000000..53901eac Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/end3.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.der new file mode 100644 index 00000000..4a2c58f3 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.mul.der new file mode 100644 index 00000000..41a3051a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der new file mode 100644 index 00000000..4a1ae680 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der new file mode 100644 index 00000000..86ed18bb Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.v1.der b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.v1.der new file mode 100644 index 00000000..2527fe30 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_cert/inter.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.der new file mode 100644 index 00000000..b89da157 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.mul.der new file mode 100644 index 00000000..03081cda Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.noCRL.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.noCRL.der new file mode 100644 index 00000000..fca671c2 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.notCA.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.notCA.der new file mode 100644 index 00000000..bbaf475e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.v1.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.v1.der new file mode 100644 index 00000000..9a254682 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v1.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.der new file mode 100644 index 00000000..45dc85bc Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul.der new file mode 100644 index 00000000..0bcca505 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul.old.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul.old.der new file mode 100644 index 00000000..fa223d21 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul2.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul2.der new file mode 100644 index 00000000..4538c694 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul3.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul3.der new file mode 100644 index 00000000..803c5c74 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.noCRL.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.noCRL.der new file mode 100644 index 00000000..7d3b24e1 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.noCRL.old.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.noCRL.old.der new file mode 100644 index 00000000..f0afe4dc Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.noCRL.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.notCA.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.notCA.der new file mode 100644 index 00000000..69f8cbc8 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.notCA.old.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.notCA.old.der new file mode 100644 index 00000000..f673a303 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.notCA.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.old.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.old.der new file mode 100644 index 00000000..97d6c4dd Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.der new file mode 100644 index 00000000..7b1512e6 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.old.der b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.old.der new file mode 100644 index 00000000..5c5b1d34 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_ecc_crl/crl_v2.v1.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss.key b/testcode/testdata/cert/asn1/rsa_pss.key new file mode 100644 index 00000000..6f5cf895 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa_pss.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdAIBADALBgkqhkiG9w0BAQoEggJgMIICXAIBAAKBgQCgZDpU/j0aTGDwYqsu +niVRPpfK/qhRXDM6qVQ9Ndvxscj6piOrtSjq4N7Id3kxHRxXx77VJgtVGeGQKpMr +bMdP0+esVxl+YIoq6Ky/2+b2BvGNBlXueJ4VLoiCfyp2DxS9BoGz6N6gyORHcmiq +QMwiE/W/AGJ1Zy9VxNLyw8NACQIDAQABAoGAQRFIJNDbQv73WK3+mjPoGbSV6fEz +oYYQ9lxZY1elOcERMrYRxIgC6H5/gr4NOWKA7A+JmHkNoeGVA2JyP+yqUlC5BqET +52k2nBB9C2kfJTL+/ArLbHVwrje2R4GY0nxqCw9paSs78UG4w9xqiwwLzFfhQP+N +07uDExXeHIulVm0CQQDRmB63NPvV1lsExgJScXE+QtN/hyw5zenImAJXb1AH/8H2 +usFfjxbHBtGxMGv9twqR3oO1M2oQXbYhiZIFGwuTAkEAw+dHqTVH67ZGPIh3Uof+ +QlIpu5QUITQPx3RujhToN+ULTQzRWXRkrgb2x0qjqqGyaznvUxc12MymPmT/tVjf +cwJAWu2z5aeG2e507k05FKtChdBYESuDdFBw7CWGXohcIBxE+dVrrxlUuGOs9UIc +l6WhYEc4vJPhn9gH++TDBJQHIQJATwH0vcJWSjMN6pXjAa8FFTxLxnH3GFkF0Bwe +BkFaUkiWoTF9MQWnISR/3Go2zbc+3M3Vvn4K4m/O0DUth7bbDwJBALUlAxdktMnn +1zIxFXuTtiYOTdeXltmfTCdYmaFY/2cg+4TITVdiuqsmkA71n4Ij75MDqA4FXSGt +KHdiwSbk9nQ= +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/ca.der b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.der new file mode 100644 index 00000000..21ebc8b0 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/ca.mul.der b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.mul.der new file mode 100644 index 00000000..b06d6f80 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der new file mode 100644 index 00000000..9c5b6734 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/ca.notCA.der b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.notCA.der new file mode 100644 index 00000000..abd699be Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/ca.v1.der b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.v1.der new file mode 100644 index 00000000..030190f1 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/ca.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end.der new file mode 100644 index 00000000..cbd5b0da Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end.mul.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end.mul.der new file mode 100644 index 00000000..00d29971 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end.noCRL.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end.noCRL.der new file mode 100644 index 00000000..37240201 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end.notCA.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end.notCA.der new file mode 100644 index 00000000..33fa54be Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end.v1.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end.v1.der new file mode 100644 index 00000000..c14cb5d6 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end2.mul.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end2.mul.der new file mode 100644 index 00000000..c4bc304b Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end2.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/end3.mul.der b/testcode/testdata/cert/asn1/rsa_pss_cert/end3.mul.der new file mode 100644 index 00000000..f2c0b263 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/end3.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/inter.der b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.der new file mode 100644 index 00000000..45d0d379 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/inter.mul.der b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.mul.der new file mode 100644 index 00000000..5fb6bfa4 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der new file mode 100644 index 00000000..8d9ac922 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/inter.notCA.der b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.notCA.der new file mode 100644 index 00000000..9505a89c Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/inter.v1.der b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.v1.der new file mode 100644 index 00000000..573b6edf Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/inter.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/rsa_pss.crt.der b/testcode/testdata/cert/asn1/rsa_pss_cert/rsa_pss.crt.der new file mode 100644 index 00000000..cb16cc8f Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/rsa_pss.crt.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_cert/rsa_pss.key.der b/testcode/testdata/cert/asn1/rsa_pss_cert/rsa_pss.key.der new file mode 100644 index 00000000..2d0b02d2 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_cert/rsa_pss.key.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.der new file mode 100644 index 00000000..06058c0e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.mul.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.mul.der new file mode 100644 index 00000000..12c33920 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.noCRL.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.noCRL.der new file mode 100644 index 00000000..7ff369eb Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.notCA.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.notCA.der new file mode 100644 index 00000000..a9ad6f8a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.v1.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.v1.der new file mode 100644 index 00000000..780b874e Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v1.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.der new file mode 100644 index 00000000..4df1da70 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul.der new file mode 100644 index 00000000..47c54e34 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul.old.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul.old.der new file mode 100644 index 00000000..8e471eb7 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul2.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul2.der new file mode 100644 index 00000000..466f43d7 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul3.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul3.der new file mode 100644 index 00000000..d7873f4a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.noCRL.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.noCRL.der new file mode 100644 index 00000000..0cf8ee45 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.noCRL.old.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.noCRL.old.der new file mode 100644 index 00000000..35be8074 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.noCRL.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.notCA.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.notCA.der new file mode 100644 index 00000000..f24c3928 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.notCA.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.notCA.old.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.notCA.old.der new file mode 100644 index 00000000..d1be157b Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.notCA.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.old.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.old.der new file mode 100644 index 00000000..286ab1be Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.v1.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.v1.der new file mode 100644 index 00000000..5094fbf4 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.v1.old.der b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.v1.old.der new file mode 100644 index 00000000..67703a2b Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/crl_v2.v1.old.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/pss_v1.der b/testcode/testdata/cert/asn1/rsa_pss_crl/pss_v1.der new file mode 100644 index 00000000..fbe32ed2 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/pss_v1.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_crl/pss_v2.der b/testcode/testdata/cert/asn1/rsa_pss_crl/pss_v2.der new file mode 100644 index 00000000..5dd48adb Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_crl/pss_v2.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.csr.der b/testcode/testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.csr.der new file mode 100644 index 00000000..f858e04a Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.csr.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.key.der b/testcode/testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.key.der new file mode 100644 index 00000000..2f460142 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_pss_csr/rsa2048_pss_withattr.key.der differ diff --git a/testcode/testdata/cert/asn1/rsa_pss_mdsha256.key b/testcode/testdata/cert/asn1/rsa_pss_mdsha256.key new file mode 100644 index 00000000..5f09cedb --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa_pss_mdsha256.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEzgIBADAeBgkqhkiG9w0BAQowEaAPMA0GCWCGSAFlAwQCAQUABIIEpzCCBKMC +AQACggEBAJyLL1+XFqXn8KbG5zA0jzM66c35VcV78/ybAwTjc2yZxOETSAm1t+86 +ux9MxVjAsb39PJ7ZdyJTXo7E0qXxpm43Zwblzcw2h2xywvxetWBNZJgfbFAc01Bc +/U7WDDBml9hnsvw+Dtf/C5ORX3G1QdyW32ODYPIbO/p9WC+UQUNi5nXNISCTMSuf +CLWNrmcDizx2HEF1KCS7bfUmufjyOo359pO1aCVkYc9vV96hN5g9Ef1WkqHngzV0 +g8fy+lQq+D8yItWM91lsf4cAtKXyxZnc6MiuFnphFlejZ3e7TEchPwRnxazHPILJ +aOG6INJyedNCM42qmkAMLq9aHvP34+cCAwEAAQKCAQASbFD6y3xnXGNr2pxqWxfV +Rs7YUPU2r3lN68JQXiJUkB47Ajq9UHe2qFn4UN/S1k60wNZUYtx3RjTVJuBxliho +7+KTTb1Ja3YcSGnz1djmXgVY39iD7yMxYdg6jHdVGjsu7+QBH/PoQ1mjQtMRk0GO +ipT8uwFQTO3jSMLK9VmJlVfxcBQ0WwS2HFZef6jGntzR30zrZ9srhleytTshQKym +wxIWH3yfM8WB5sd+q2dTyg1QJjpL4wsnw/O11klRj2eISKJyM+h2pYu0wZWxjfdl +mEJP1c1PEeSUp6VB81FrpL9yZ/tKNsoNv0anXEL4D+jItmGwUDDSjTIjRyAwzAKB +AoGBANwafgpkENYvyExlInrVjAAo8ezHWCr349hO0HcAuMsDmiEcuSJl52YmGVJ+ +nRSIEK17iNkx1FEpx05qpiw8U65ENKdWmZFSSYsQ2xxRcLlOPMchDq/IAOJK04tE +jyDKifyKDoE37at1cHWbF2XIEyZv03LbLUQyCYLV/x3x+IhnAoGBALYTBGuCbB1r +oD3Q4qBMs2aE5lslAbx9L+ZKzYjtOOym94joaMGNIoNJeDpsFamCfobl0xvUepXd +N1GeC6lk3vKWMBHQcjTY8HWEMZtB5LM6zagX8yNsB+ol0dlZB8edbDOsyn5UjU5R +zg75pTnEBvP/anJXpg1QLUylVInGkpiBAoGBAIN3i3tXY7sblU8URXELJnFeA4rD +UwVvRXeJM/kwxC/2udQ3XNmP9pRMA2oD2H1P/G4y0H2yxren9bT//LuFWRJJCQ4+ +qsFjXiwjaEzU1DjK44CpXSVfmC+SNCMGU1tpvtvJ9nn2Vw7HueF1Ppd71vxpZOpA +whvuq0Gr4pMXWbTXAoGAUBhhk2HWacLUxRzE9TuImArSwzmuX9q6XZZ+gEPLDOAO +eJ20p6CMlDCXwSuXA/Cx9GnZyp5YJuEf2rmp66TCJvlGwC9wbisY7LlwkRoVn3q4 +yb9vaB+4A5sLi4+MypVH6huTIKvVVaTK/u93bcf8Pw4XJ6HDHIwuwU7ht5IxHwEC +gYAFtPid11NB9+Kj1Do0+CYyrlgbpISS4qp/K/iOaOyNuUdu56XsaD1xeeu8jj6i +eKqAxwLyLTPTzknFQWTX5BDD+RTXARok1sWihy22y19G6wyJFX5Pa2m6qcqumgwK +JcP+fl8KLOzM0Q4GjMretRzDNpknOmHsoofVSyW4O1Owdw== +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa_pss_mgfsha256.key b/testcode/testdata/cert/asn1/rsa_pss_mgfsha256.key new file mode 100644 index 00000000..6b3dd474 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa_pss_mgfsha256.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIE2wIBADArBgkqhkiG9w0BAQowHqEcMBoGCSqGSIb3DQEBCDANBglghkgBZQME +AgEFAASCBKcwggSjAgEAAoIBAQC0vDVkHU4nHDHUgRLH9yvhwf6cuQyuTG4qtcGe +/lECD5ukvOmG6dbVeRSanFjUY3IUUqPnsOpEr2km+DFTAdhnmYRBfNK/m/jFTrUI +UJN2UcC2CkRucwExX1qQOv2z3eI1gFxxtElgNStDb0wsoSXiks1A2XQ7ROVvsABI +h/96G2Ap0v08m6fkUPNxkSwQRwBWqxMmdNBKdHEAfLxSWLlcXjeLZyhOve6WYz20 +cq6xVejtpQ3zrk9BB6HyyONxH7ht6IOIYaz27rvptPj8HcciVcqOHJ7lJZqpaK67 +I+/4RnN3kUvU+jmjp0kozl5I5oYPjOabVzuq3O3x1BjMDZ23AgMBAAECggEAIm0t +UF4iqmF8/mj9rlhfI/gjay/2gebuHzWS5Zm0zYsyjw0rAHdfZDdVnOPGKeKtcsCR +FwuEfEPbaEBjiNezpHxCDIVd0YDAwLiu1CAhDqsg5awL/+vpIMH0ir+p3s6XjbBf +K4t3ZJuMG6LCJEgn4sIq1bz2HmoPuBgS3b4GBHiLJefelo4rm/FAF0zkSVRNmUr3 +O7FBQHQOh91BK90Du7NRdJdQ4xcdJBwPibMhoVQmxiIJJosfEJgwrZ4i1TeT6ayk +wISDCDQ6FHrTUAmZfRLdirrOFJxkpeeD7AE9b9EF50E1PkKr7gESjL/XZq5R0tla +I0Pd4b1A06Bovh0t+QKBgQDsli1QmueXArk07bV7+oJLSzzK0aYRS2IQksnMjSLx +Dh+gyYTNfAPbcct/XEHa2qQQlKpgdIms16nsTia6nQuBLZCED9UpkHJKGTbsrvZm +SZOrEsGbIopB8LAwzXyQyv8GDmtCKcawBBe7HuKwMPGJKCjgE9mm4Izh6q8GR/Vu ++QKBgQDDkMvbz0kJQrJUt9LL1jmzljDIA+rvJygij3AANFBGjZG7SuWIqIs2HPhh +TG/MRbl2HOW789ffzinPkWbQI2wy4M92n7jjulWOryO6mqGe02YQep7TQJ+Q0qNk +yUf7/kcTAodnxr56tga1xlzAwSqiYdhXhP+0r9XVcMg6sFmuLwKBgQDgCOYoakfc +LGwNvvwYxwQTINAUj6reva/DWf1WgmAQPPueWrYzj7hnWb8Gf+qswFaUjPM6G6Ez +15XFe8wY8xYt4WP0arnEflB78pycTKJwAkSfv0cvDOo3vyBZVn0a79/HcGgJY14O +2BFQ1NJ9Xhubcjgi2SlGaWV/majcHdBAoQKBgBJDK0ZTjRZ4S/7tS5oNX0YN+HA1 +LXM3zN+tVWAvgm+UOM+sptKkKpvbCLbNVINW34LQIAP1OWuE7RKdGWTGagw2Qilp +sPJTLDou0L9UQVN7mkRfrwU7O6tigC+hPD+j9y8nRU3DmXYMGYRQCclWQIz5ZiKG +IPrWkLll1szkOvuxAoGAEm0JCm/TsYTmTL6KvtEvej7m5DbFr5E+jU20eMB2fAMd +ZcMr6qS7G7VQG5+a61EsbiimgYUHTaRfATEbsyAZ7T6u327jqa6RYGLX/kpOMqeJ +78SVUhOCk4dNMlqlH778ooLqtdh7BauluSamIYrc47eWwI6J111ImrSHeVX4MVU= +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa_pss_salt10.key b/testcode/testdata/cert/asn1/rsa_pss_salt10.key new file mode 100644 index 00000000..531e13c5 --- /dev/null +++ b/testcode/testdata/cert/asn1/rsa_pss_salt10.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICfQIBADASBgkqhkiG9w0BAQowBaIDAgEKBIICYjCCAl4CAQACgYEAyhf3DfGq +iOm28GHN6siuZ/ep0RkQFBK6ZfVANpKz5UHO+DxF2b6vD06ouRHMYGt2Pb8f3dU0 +ZqZcNOIr1n07fcpIlPrmzz1VFZUGMoPi+tnqYzU9KW9aui12SRQqf8ZFTP9hHv6j +N7M2KH50mKcBcp+0fJMkDtwDAZOCa+1QJC0CAwEAAQKBgD+5SMybzFM5ptarcFu9 +BcmAvYpSZdB+i0oFCEdtAM6kbpe1oazkRJ0GB4u7wf8RQ4p6zpiLVuebQ23ldz89 +49jZJn2EEs05Yy2yY80mLlT3O/N7eC6VmYN+h7qiB+NjM1cAhgxU49v+iDMK3lQo +9bCbUwJqvLCBEQ5LCiY1SjB9AkEA+qAriYQUklRAxeyFFr15iGUnlzlhOOcXXE/3 +DWohJUKAwLECBq1x3wuW2k0sDe/AgDWbjqJhMABAXnUmMzRAfwJBAM5tX9XMtKUg +VUqQ99eEYj35Gi0zVt1Ewh8Eu/jrfMfNKtE54goIK6dxX0U4LC0fAYfSDkyanNbq +iz5WYkODRVMCQQDA8Q+zVThVEoGvHY+z2vg19dHNzMG5AcbtLS5/aEXOHm1qapqp +s1snoA9pTeHtdLZYvWxdGUsCnh7v2PYok0BXAkEAo9RgZAGEOS1xI63sVYqGoeLK +qKb/QLsqSY3rVYIn1Tb6zXTf9dBIPSsYTopnXSQnhdDrclafNV6ORlouwKA1awJB +AOj1SHCox/O3aWdtGsZMBtQ4VvqcATO2lYCAOfdSHfdDlAqJ+qRb33t8arwec//V +vzgTT+iBBawkVV7zGLM1FrU= +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der b/testcode/testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der new file mode 100644 index 00000000..0492e775 Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_sha_csr/rsa_sh256.csr.der differ diff --git a/testcode/testdata/cert/asn1/rsa_sha_csr/rsa_sh256.key.der b/testcode/testdata/cert/asn1/rsa_sha_csr/rsa_sh256.key.der new file mode 100644 index 00000000..1fc4320c Binary files /dev/null and b/testcode/testdata/cert/asn1/rsa_sha_csr/rsa_sh256.key.der differ diff --git a/testcode/testdata/cert/asn1/rsapsspubkey.pem b/testcode/testdata/cert/asn1/rsapsspubkey.pem new file mode 100644 index 00000000..4b28e80e --- /dev/null +++ b/testcode/testdata/cert/asn1/rsapsspubkey.pem @@ -0,0 +1,10 @@ +-----BEGIN PUBLIC KEY----- +MIIBVjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcN +AQEIMA0GCWCGSAFlAwQCAQUAogMCAQoDggEPADCCAQoCggEBAMPhlnvW60xiuN8c +hKUQYXP+BCPGm4LFEy4yMbaKFsrub+ozpTvElvlqpP0EogDHNHK7eHPJuXyDNVI4 +N3zaP0MKM1AOEMIjOVNhRi6sb3n8bjsK8k7a4afMKH3vrdLQ8P3UFL8fQqTdCsZI +5eXrT+jeboRR/90Yo2pTJMGrWT8zyY0twIGX5D903U8icyE9RjKIRwJSSHeDBRZW ++f4Ob43SRD415AOE3FIrfwVrOPRCyNmtxMCjXzKuBf7em460jmLVt9ep7hb3Emik +hDjymGL/UIiZU3dbp6yZwzITqK6lG+tHH9qFqWmWnjLT+qIW58VnG6SfTEEzpQew +4gn/hu0CAwEAAQ== +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/testcode/testdata/cert/asn1/secp384r1.der b/testcode/testdata/cert/asn1/secp384r1.der new file mode 100644 index 00000000..2828582d Binary files /dev/null and b/testcode/testdata/cert/asn1/secp384r1.der differ diff --git a/testcode/testdata/cert/asn1/secp384r1.pem b/testcode/testdata/cert/asn1/secp384r1.pem new file mode 100644 index 00000000..011ea6f5 --- /dev/null +++ b/testcode/testdata/cert/asn1/secp384r1.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDAR8a1/1o0r3A/pcrUh1kFrHC0NbqgodbGul7Bb4pfZ55kNsz8IiC/e +5KKFwdh0csigBwYFK4EEACKhZANiAASuv0e9hKWXy0Hwnh8o4TgTmTR2woQAhNqy +QnN1FtEjG12zzTDfcVngSr5aa+0vNgFsL9q7mm8o6lWMzdS46KrKnorKD1XATa1P +DxAo5NSwGF5Vw3yyX8362hgvA1W0qq0= +-----END EC PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/secp384r1_pkcs8.der b/testcode/testdata/cert/asn1/secp384r1_pkcs8.der new file mode 100644 index 00000000..5e27d2c1 Binary files /dev/null and b/testcode/testdata/cert/asn1/secp384r1_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/secp384r1_pkcs8.pem b/testcode/testdata/cert/asn1/secp384r1_pkcs8.pem new file mode 100644 index 00000000..c9fd87a2 --- /dev/null +++ b/testcode/testdata/cert/asn1/secp384r1_pkcs8.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAR8a1/1o0r3A/pcrUh +1kFrHC0NbqgodbGul7Bb4pfZ55kNsz8IiC/e5KKFwdh0csihZANiAASuv0e9hKWX +y0Hwnh8o4TgTmTR2woQAhNqyQnN1FtEjG12zzTDfcVngSr5aa+0vNgFsL9q7mm8o +6lWMzdS46KrKnorKD1XATa1PDxAo5NSwGF5Vw3yyX8362hgvA1W0qq0= +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/secp384r1pub.der b/testcode/testdata/cert/asn1/secp384r1pub.der new file mode 100644 index 00000000..209ccfa2 Binary files /dev/null and b/testcode/testdata/cert/asn1/secp384r1pub.der differ diff --git a/testcode/testdata/cert/asn1/secp384r1pub.pem b/testcode/testdata/cert/asn1/secp384r1pub.pem new file mode 100644 index 00000000..e3f0653b --- /dev/null +++ b/testcode/testdata/cert/asn1/secp384r1pub.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAErr9HvYSll8tB8J4fKOE4E5k0dsKEAITa +skJzdRbRIxtds80w33FZ4Eq+WmvtLzYBbC/au5pvKOpVjM3UuOiqyp6Kyg9VwE2t +Tw8QKOTUsBheVcN8sl/N+toYLwNVtKqt +-----END PUBLIC KEY----- diff --git a/testcode/testdata/cert/asn1/secp521r1.der b/testcode/testdata/cert/asn1/secp521r1.der new file mode 100644 index 00000000..1e432412 Binary files /dev/null and b/testcode/testdata/cert/asn1/secp521r1.der differ diff --git a/testcode/testdata/cert/asn1/secp521r1.pem b/testcode/testdata/cert/asn1/secp521r1.pem new file mode 100644 index 00000000..6271b5e9 --- /dev/null +++ b/testcode/testdata/cert/asn1/secp521r1.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIByoQJlhp66ULSpl8KvJ+90j5Vuanh2b7XLJ6R8uYs60MfoniMELMu +QS+alBLE0rQ2+jlqe9G157FDqkJt3f4n1DigBwYFK4EEACOhgYkDgYYABACkFC02 +4bqYBWhOL3ldF0wNrNO7Btm1k7hHNAinjyrYzB0aG2b0gPSTRsTFefFbDj9MTG64 +ljVM8bfuO+fn4EARrAFGK1qppxek4IpDr683v2r3gnR//oiugTv5/Fs33yJODCqr +ZWZiPOfm/bNlfmyX/fo6GSG4TVZiyFkhKYuQUE3Ayg== +-----END EC PRIVATE KEY----- diff --git a/testcode/testdata/cert/asn1/secp521r1_pkcs8.der b/testcode/testdata/cert/asn1/secp521r1_pkcs8.der new file mode 100644 index 00000000..55f5b4b0 Binary files /dev/null and b/testcode/testdata/cert/asn1/secp521r1_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/secp521r1pub.der b/testcode/testdata/cert/asn1/secp521r1pub.der new file mode 100644 index 00000000..838df761 Binary files /dev/null and b/testcode/testdata/cert/asn1/secp521r1pub.der differ diff --git a/testcode/testdata/cert/asn1/sha256R-time.crt b/testcode/testdata/cert/asn1/sha256R-time.crt new file mode 100644 index 00000000..507f74b4 Binary files /dev/null and b/testcode/testdata/cert/asn1/sha256R-time.crt differ diff --git a/testcode/testdata/cert/asn1/sha256Rsaca.crt b/testcode/testdata/cert/asn1/sha256Rsaca.crt new file mode 100644 index 00000000..519420a0 Binary files /dev/null and b/testcode/testdata/cert/asn1/sha256Rsaca.crt differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca.der b/testcode/testdata/cert/asn1/sm2_cert/ca.der new file mode 100644 index 00000000..f304be27 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca.mul.der b/testcode/testdata/cert/asn1/sm2_cert/ca.mul.der new file mode 100644 index 00000000..fc3edaa1 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca.noCRL.der b/testcode/testdata/cert/asn1/sm2_cert/ca.noCRL.der new file mode 100644 index 00000000..859e6037 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca.notCA.der b/testcode/testdata/cert/asn1/sm2_cert/ca.notCA.der new file mode 100644 index 00000000..79993322 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca.notCA.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage0.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage0.der new file mode 100644 index 00000000..3fb8dde1 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage0.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage1.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage1.der new file mode 100644 index 00000000..c44cf55f Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage1.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage2.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage2.der new file mode 100644 index 00000000..ebc7aaf0 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage2.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage3.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage3.der new file mode 100644 index 00000000..2b502db6 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage3.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage4.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage4.der new file mode 100644 index 00000000..e916270c Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage4.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage5.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage5.der new file mode 100644 index 00000000..01efec29 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage5.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage6.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage6.der new file mode 100644 index 00000000..88928dc7 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage6.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage7.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage7.der new file mode 100644 index 00000000..6d7bc378 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage7.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage8.der b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage8.der new file mode 100644 index 00000000..1384f413 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_keyUsage8.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_pathlen1.der b/testcode/testdata/cert/asn1/sm2_cert/ca_pathlen1.der new file mode 100644 index 00000000..98d005dd Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_pathlen1.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/ca_pathlen2.der b/testcode/testdata/cert/asn1/sm2_cert/ca_pathlen2.der new file mode 100644 index 00000000..686b0051 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/ca_pathlen2.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/enc.der b/testcode/testdata/cert/asn1/sm2_cert/enc.der new file mode 100644 index 00000000..14d10db7 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/enc.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/enc.mul.der b/testcode/testdata/cert/asn1/sm2_cert/enc.mul.der new file mode 100644 index 00000000..3aea01cd Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/enc.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/enc.noCRL.der b/testcode/testdata/cert/asn1/sm2_cert/enc.noCRL.der new file mode 100644 index 00000000..b3940028 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/enc.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/enc.notCA.der b/testcode/testdata/cert/asn1/sm2_cert/enc.notCA.der new file mode 100644 index 00000000..b743e7ff Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/enc.notCA.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/enc2.mul.der b/testcode/testdata/cert/asn1/sm2_cert/enc2.mul.der new file mode 100644 index 00000000..a5e1c238 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/enc2.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/enc3.mul.der b/testcode/testdata/cert/asn1/sm2_cert/enc3.mul.der new file mode 100644 index 00000000..b2d75912 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/enc3.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/inter.der b/testcode/testdata/cert/asn1/sm2_cert/inter.der new file mode 100644 index 00000000..0d17338e Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/inter.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/inter.mul.der b/testcode/testdata/cert/asn1/sm2_cert/inter.mul.der new file mode 100644 index 00000000..d723d168 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/inter.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/inter.noCRL.der b/testcode/testdata/cert/asn1/sm2_cert/inter.noCRL.der new file mode 100644 index 00000000..25c5550f Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/inter.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/inter.notCA.der b/testcode/testdata/cert/asn1/sm2_cert/inter.notCA.der new file mode 100644 index 00000000..7d8f10f7 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/inter.notCA.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sign.der b/testcode/testdata/cert/asn1/sm2_cert/sign.der new file mode 100644 index 00000000..d399f611 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sign.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sign.mul.der b/testcode/testdata/cert/asn1/sm2_cert/sign.mul.der new file mode 100644 index 00000000..8376d82a Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sign.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sign.noCRL.der b/testcode/testdata/cert/asn1/sm2_cert/sign.noCRL.der new file mode 100644 index 00000000..80bec451 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sign.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sign.notCA.der b/testcode/testdata/cert/asn1/sm2_cert/sign.notCA.der new file mode 100644 index 00000000..f270951e Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sign.notCA.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sign2.mul.der b/testcode/testdata/cert/asn1/sm2_cert/sign2.mul.der new file mode 100644 index 00000000..83fad404 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sign2.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sign3.mul.der b/testcode/testdata/cert/asn1/sm2_cert/sign3.mul.der new file mode 100644 index 00000000..c3e3b66d Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sign3.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sm2.crt.der b/testcode/testdata/cert/asn1/sm2_cert/sm2.crt.der new file mode 100644 index 00000000..851e8998 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sm2.crt.der differ diff --git a/testcode/testdata/cert/asn1/sm2_cert/sm2.key.der b/testcode/testdata/cert/asn1/sm2_cert/sm2.key.der new file mode 100644 index 00000000..e0cd252d Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_cert/sm2.key.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v1.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.der new file mode 100644 index 00000000..8d64d13c Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v1.mul.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.mul.der new file mode 100644 index 00000000..ac4a3764 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v1.noCRL.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.noCRL.der new file mode 100644 index 00000000..abce6c34 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v1.notCA.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.notCA.der new file mode 100644 index 00000000..c0c29a83 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.notCA.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v1.v1.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.v1.der new file mode 100644 index 00000000..7ab7ab9a Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v1.v1.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.der new file mode 100644 index 00000000..10a65fa6 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul.der new file mode 100644 index 00000000..31f54ce5 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul.old.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul.old.der new file mode 100644 index 00000000..9e272fe9 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul2.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul2.der new file mode 100644 index 00000000..71d1e822 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul3.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul3.der new file mode 100644 index 00000000..023d3f7d Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.noCRL.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.noCRL.der new file mode 100644 index 00000000..e0e8827a Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.noCRL.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.noCRL.old.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.noCRL.old.der new file mode 100644 index 00000000..97c252d5 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.noCRL.old.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.notCA.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.notCA.der new file mode 100644 index 00000000..9e56be06 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.notCA.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.notCA.old.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.notCA.old.der new file mode 100644 index 00000000..3ed43b86 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.notCA.old.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.old.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.old.der new file mode 100644 index 00000000..5de87c76 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.old.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.v1.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.v1.der new file mode 100644 index 00000000..1c1ca536 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.v1.der differ diff --git a/testcode/testdata/cert/asn1/sm2_crl/crl_v2.v1.old.der b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.v1.old.der new file mode 100644 index 00000000..189888f0 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_crl/crl_v2.v1.old.der differ diff --git a/testcode/testdata/cert/asn1/sm2_pkcs8/sm2_pkcs1.der b/testcode/testdata/cert/asn1/sm2_pkcs8/sm2_pkcs1.der new file mode 100644 index 00000000..acb2ee10 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_pkcs8/sm2_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/sm2_pkcs8/sm2_pkcs8.der b/testcode/testdata/cert/asn1/sm2_pkcs8/sm2_pkcs8.der new file mode 100644 index 00000000..e6e646c3 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_pkcs8/sm2_pkcs8.der differ diff --git a/testcode/testdata/cert/asn1/sm2_pkcs8/sm2pub_pkcs1.der b/testcode/testdata/cert/asn1/sm2_pkcs8/sm2pub_pkcs1.der new file mode 100644 index 00000000..42db7638 Binary files /dev/null and b/testcode/testdata/cert/asn1/sm2_pkcs8/sm2pub_pkcs1.der differ diff --git a/testcode/testdata/cert/asn1/tailerfield.der b/testcode/testdata/cert/asn1/tailerfield.der new file mode 100644 index 00000000..05f170f6 Binary files /dev/null and b/testcode/testdata/cert/asn1/tailerfield.der differ diff --git a/testcode/testdata/cert/chain/ecdsa-v3/ca.der b/testcode/testdata/cert/chain/ecdsa-v3/ca.der new file mode 100644 index 00000000..02775e8c Binary files /dev/null and b/testcode/testdata/cert/chain/ecdsa-v3/ca.der differ diff --git a/testcode/testdata/cert/chain/ecdsa-v3/crl_v2.old.der b/testcode/testdata/cert/chain/ecdsa-v3/crl_v2.old.der new file mode 100644 index 00000000..d9d89aff Binary files /dev/null and b/testcode/testdata/cert/chain/ecdsa-v3/crl_v2.old.der differ diff --git a/testcode/testdata/cert/chain/ecdsa-v3/end.der b/testcode/testdata/cert/chain/ecdsa-v3/end.der new file mode 100644 index 00000000..095c3ea8 Binary files /dev/null and b/testcode/testdata/cert/chain/ecdsa-v3/end.der differ diff --git a/testcode/testdata/cert/chain/ecdsa-v3/inter.der b/testcode/testdata/cert/chain/ecdsa-v3/inter.der new file mode 100644 index 00000000..c99b32d1 Binary files /dev/null and b/testcode/testdata/cert/chain/ecdsa-v3/inter.der differ diff --git a/testcode/testdata/cert/chain/rsa-ecc-v3/ca.der b/testcode/testdata/cert/chain/rsa-ecc-v3/ca.der new file mode 100644 index 00000000..45119014 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-ecc-v3/ca.der differ diff --git a/testcode/testdata/cert/chain/rsa-ecc-v3/end.der b/testcode/testdata/cert/chain/rsa-ecc-v3/end.der new file mode 100644 index 00000000..8023acf4 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-ecc-v3/end.der differ diff --git a/testcode/testdata/cert/chain/rsa-ecc-v3/inter.der b/testcode/testdata/cert/chain/rsa-ecc-v3/inter.der new file mode 100644 index 00000000..7a59eaa1 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-ecc-v3/inter.der differ diff --git a/testcode/testdata/cert/chain/rsa-pss-v3/ca.der b/testcode/testdata/cert/chain/rsa-pss-v3/ca.der new file mode 100644 index 00000000..e5f36188 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-pss-v3/ca.der differ diff --git a/testcode/testdata/cert/chain/rsa-pss-v3/end.der b/testcode/testdata/cert/chain/rsa-pss-v3/end.der new file mode 100644 index 00000000..277704bb Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-pss-v3/end.der differ diff --git a/testcode/testdata/cert/chain/rsa-pss-v3/inter.der b/testcode/testdata/cert/chain/rsa-pss-v3/inter.der new file mode 100644 index 00000000..edc24a1e Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-pss-v3/inter.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/ca.der b/testcode/testdata/cert/chain/rsa-v3/ca.der new file mode 100644 index 00000000..03572003 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/ca.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/ca1.der b/testcode/testdata/cert/chain/rsa-v3/ca1.der new file mode 100644 index 00000000..64794b0c Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/ca1.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/cert.der b/testcode/testdata/cert/chain/rsa-v3/cert.der new file mode 100644 index 00000000..b6b90815 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/cert.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/crl_v1.der b/testcode/testdata/cert/chain/rsa-v3/crl_v1.der new file mode 100644 index 00000000..4673424c Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/crl_v1.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/crl_v2.old.der b/testcode/testdata/cert/chain/rsa-v3/crl_v2.old.der new file mode 100644 index 00000000..01b065dc Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/crl_v2.old.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/end.der b/testcode/testdata/cert/chain/rsa-v3/end.der new file mode 100644 index 00000000..95bc51d6 Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/end.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/inter.der b/testcode/testdata/cert/chain/rsa-v3/inter.der new file mode 100644 index 00000000..c210781f Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/inter.der differ diff --git a/testcode/testdata/cert/chain/rsa-v3/rootca.der b/testcode/testdata/cert/chain/rsa-v3/rootca.der new file mode 100644 index 00000000..79d506cb Binary files /dev/null and b/testcode/testdata/cert/chain/rsa-v3/rootca.der differ diff --git a/testcode/testdata/cert/chain/sm2-v3/ca.der b/testcode/testdata/cert/chain/sm2-v3/ca.der new file mode 100644 index 00000000..93951275 Binary files /dev/null and b/testcode/testdata/cert/chain/sm2-v3/ca.der differ diff --git a/testcode/testdata/cert/chain/sm2-v3/end.der b/testcode/testdata/cert/chain/sm2-v3/end.der new file mode 100644 index 00000000..9f4262a3 Binary files /dev/null and b/testcode/testdata/cert/chain/sm2-v3/end.der differ diff --git a/testcode/testdata/cert/chain/sm2-v3/inter.der b/testcode/testdata/cert/chain/sm2-v3/inter.der new file mode 100644 index 00000000..8aa3227c Binary files /dev/null and b/testcode/testdata/cert/chain/sm2-v3/inter.der differ diff --git a/testcode/testdata/cert/pem/cert/ca.pem b/testcode/testdata/cert/pem/cert/ca.pem new file mode 100644 index 00000000..98da1e09 --- /dev/null +++ b/testcode/testdata/cert/pem/cert/ca.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICMzCCAdmgAwIBAgIUJQObgYAFwQQZAYxXu1ds0iiXmx0wCgYIKoEcz1UBg3Uw +bzELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDEUMBIGA1UE +CgwLY2VydGlmaWNhdGUxDzANBgNVBAsMBnRlc3RjYTEfMB0GA1UEAwwWY2VydGlm +aWNhdGUudGVzdGNhLmNvbTAeFw0yNDA0MTgwNjQ3MDRaFw0zNDA0MTYwNjQ3MDRa +MG8xCzAJBgNVBAYTAlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxFDASBgNV +BAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0Y2ExHzAdBgNVBAMMFmNlcnRp +ZmljYXRlLnRlc3RjYS5jb20wWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS14UTq +lqIzZdwOSrhoOCYnXSYt+jaNfG5MpIOFBzZcqfgN7G2qTcQxMm8xDyV1azT6CASy +yJRDyIjKF6mcK8TOo1MwUTAdBgNVHQ4EFgQUQgURXsl7jlja2s6GCl19jfC2W7sw +HwYDVR0jBBgwFoAUQgURXsl7jlja2s6GCl19jfC2W7swDwYDVR0TAQH/BAUwAwEB +/zAKBggqgRzPVQGDdQNIADBFAiEAkT03WOdSo5Xoawf0paR7yoZZO+rEcqSuQrnY +tVNYFTcCIB5LYguupuxH3s7M5Y7AHlXjZejFmC8T2DSZkSJ8skis +-----END CERTIFICATE----- diff --git a/testcode/testdata/cert/pem/crl/crl_v1.crl b/testcode/testdata/cert/pem/crl/crl_v1.crl new file mode 100644 index 00000000..d97b61c4 --- /dev/null +++ b/testcode/testdata/cert/pem/crl/crl_v1.crl @@ -0,0 +1,8 @@ +-----BEGIN X509 CRL----- +MIH8MIGkMAoGCCqBHM9VAYN1MGIxCzAJBgNVBAYTAlhYMQswCQYDVQQIDAJYWDEU +MBIGA1UECgwLY2VydGlmaWNhdGUxDzANBgNVBAsMBnRlc3RpbjEfMB0GA1UEAwwW +Y2VydGlmaWNhdGUudGVzdGluLmNvbRcNMjQwNDE4MDY1MzQ2WhcNMjQwNTE4MDY1 +MzQ2WjAUMBICAQMXDTI0MDQxODA2NTM0NlowCgYIKoEcz1UBg3UDRwAwRAIgDJ7a +VaAFbepNAVEFXYSZwSJAPHCz0A5tkIK8mz9XYxUCIA3xx9zk8hYA/nPjH9YB0aZN +IWzGzJ6vORF+hB2ilL+k +-----END X509 CRL----- diff --git a/testcode/testdata/cert/pem/crl/crl_v2.pem b/testcode/testdata/cert/pem/crl/crl_v2.pem new file mode 100644 index 00000000..6edac434 --- /dev/null +++ b/testcode/testdata/cert/pem/crl/crl_v2.pem @@ -0,0 +1,8 @@ +-----BEGIN X509 CRL----- +MIIBEDCBtwIBATAKBggqgRzPVQGDdTBiMQswCQYDVQQGEwJYWDELMAkGA1UECAwC +WFgxFDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4xHzAdBgNV +BAMMFmNlcnRpZmljYXRlLnRlc3Rpbi5jb20XDTI0MDQxODA2NTM0NloXDTI0MDUx +ODA2NTM0NlowFDASAgEDFw0yNDA0MTgwNjUzNDZaoA4wDDAKBgNVHRQEAwIBATAK +BggqgRzPVQGDdQNIADBFAiEA7N1vXFfIYBiTtnJMlSK4N4rSwEfqTi6joNPDLR+K +1WECIHRx2Re3bJK8AbpN4GgjAfYsB6hx6ZNIuzMv2nunWjbl +-----END X509 CRL----- diff --git a/testcode/testdata/cert/pem/csr/csr.pem b/testcode/testdata/cert/pem/csr/csr.pem new file mode 100644 index 00000000..02a966d3 --- /dev/null +++ b/testcode/testdata/cert/pem/csr/csr.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDbTCCAlUCAQAwggEmMWMwYQYDVQQIDFpUaGUgR3JlYXQgU3RhdGUgb2YgTG9u +Zy1XaW5kZWQgQ2VydGlmaWNhdGUgRmllbGQgTmFtZXMgV2hlcmVieSB0byBJbmNy +ZWFzZSB0aGUgT3V0cHV0IFNpemUxHzAdBgNVBAcMFlRvb21hbnljaGFyYWN0ZXJz +dmlsbGUxSDBGBgNVBAoMP1RoZSBCZW5ldm9sZW50IFNvY2lldHkgb2YgTG9xdWFj +aW91cyBhbmQgUGxlb25hc3RpYyBQZXJpcGhyYXNpczE9MDsGA1UECww0RW5kb3Jz +ZW1lbnQgb2YgVm91Y2hzYWZlJ2QgRXZpZGVudGlhcnkgQ2VydGlmaWNhdGlvbjEV +MBMGA1UEAwwMY2VydC5leGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuzDiK6h/mSCYmXa6CjK3pSjEr70SoNjBII/7MfU2hx6qysrOAIi+Eav8 +m0BIoBQuhvJqWVmwa1Przdki69WbD37QhyGNdixeetFi2E2Dag4BeQXQmQq4ydoY +Tfl8DC9rYGHVoqFfxHsvEiUqlLJH9NzKXMJy21X0qYcJqMKjX4hBRajwQn+xPCFW +qxlnLWzKb5TGwDOaMITHr/wnJqqrfNTRZG9VlXo7zeb/ySr9uN/13nX+CO2Sb+8y +nrMKD/aYhc1h1wnfUiFc1qhe+7v3Kx7nyIaBGuzZGYUgtmqLEBetfYip35NJ6lmi +wydfNggl5BxEaEAu6vV9iBiwy6ANFwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB +ADgIOZ6OL8SDAGcDTkHuE7d9xOIeiidMU2JU1Dxxk7iZh6JAHxjdgwwUew0nDdPR +74u84uGzecotX9MByAhmCflhwN+aTQcntxY1R44uAmeE0WJLrCYWQIKHh27YI/2y +9mMHX9srTtL+Ggrs7s1WLzcFitDpUWB4B+9a+KGJ0fbWPpjNcxDwwjSEiKwzHhpv +3PdTU2eC5/uvu1BoU4ms//JftvbWlTwHqf4J4P/FZeeOwoTay5d0K5qWDs9hEexP +m9wRUnCc8L7xPElYvIC9mpgMFvwJ3xMOpE1qAh7WSeAlTX6wE0WvxgCwhgEExISQ +vRMcwsXoc5VthqU/E8fc9ls= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr b/testcode/testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr new file mode 100644 index 00000000..f28f1557 --- /dev/null +++ b/testcode/testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.csr @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIH2MIGeAgEAMDwxCzAJBgNVBAYTAkNOMQ0wCwYDVQQKDAR0ZXN0MQwwCgYDVQQL +DAN2ZGMxEDAOBgNVBAMMB3ZkY19kZXYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC +AAS7k2mXEU8+/BeYxSQrFOatDiUSZmegkvQ0DPn0/fQSKWa3YeijqyRpC4caGAMl +DsH/lOiDhaTTxpim2Q53mIOioAAwCgYIKoZIzj0EAwIDRwAwRAIgLkomaQNRTrUz +tHoWWWXbBSgeFdlbBSXYTl57qufCH6oCIH3HUHhMf/DRr1qqo3Cr1Uk5o2wAJAd6 +kv7e7hestuwP +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.key.pem b/testcode/testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.key.pem new file mode 100644 index 00000000..0c4db9eb --- /dev/null +++ b/testcode/testdata/cert/pem/csr/ecdsa_sha/ec_app256SHA256.key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgUMTjC7QJhqlfXDdF +Rl+J6A5uSQcIEZwVESLdufJURiGhRANCAAS7k2mXEU8+/BeYxSQrFOatDiUSZmeg +kvQ0DPn0/fQSKWa3YeijqyRpC4caGAMlDsH/lOiDhaTTxpim2Q53mIOi +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr b/testcode/testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr new file mode 100644 index 00000000..07360894 --- /dev/null +++ b/testcode/testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.csr @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDPTCCAfECAQAwTDELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQH +DAJYWDEUMBIGA1UECgwLY2VydGlmaWNhdGUxDTALBgNVBAsMBHRlc3QwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsYOWP9bOUt6QSj9hr3dSvSpDj7dFg +TJZMn4BPy3FEQ6PyEDKORcQQftiNxTnTcg5i1TgWP4qgPaCHU+lJW5CHF+xx0CV0 +qaHXqeVcwOWmmSWh90OWeEwKj5rGY+6QRHbgU+veDvTsdQOL/hVKx00XsPYLotiy +z1rZdZJleVrL6kcZzICfZOFLg66yg3qKieEnH1cfCOpQ9dq8lBGxw4m/3E9c69w+ +17PbbjEHcaUI+Zz8/mTWAyeodlFu5U5Z1EDKh3Paicy2lrDJJPpjMUILUswvXbET +AiN2WZKKPsGA2aRMPZibqBHQkgYu5YIMR/liYzT45jPKenfYlKEYZxjVAgMBAAGg +eDB2BgkqhkiG9w0BCQ4xaTBnMDYGA1UdEQQvMC2BEG15QG90aGVyLmFkZHJlc3OG +GWxkYXA6Ly9zb21ob3N0LmNvbS9DTj1mb28wHQYDVR0OBBYEFJYtnfAQzjR9hkCZ +MKnZlpazSWG7MA4GA1UdDwEB/wQEAwIDiDBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASADggEB +AJp6Ztlp+QIF6AqfDAvL7Zwjc6KDo/lrTTCbPq9V2WPHuOiMzotTk6uRpdhHZwfy +vcTVNBcMFCLRu+uA/AKBXl4wE0Csc/NOoRGpHwJLlzpMJi9sVUsJ4q/0QHyZQZ9/ +Kg9d/Q0QXKqvTAvyd2qY6gEpsLlwN1Om/L4cPHyCGBGZ7C+79jHQSIBch5YAOlF7 +dqdtOjmG00KL/juxnw0TO5jBTx/kFwxo25spJK2relTo6SsvrWWnfw+yjLhTGVQL +82qXl6Dz6PwDCoBW2cZPGv5f2D8qn1rJBjV0MQqJ2OP+zhRuZP6FP/hyFp+cd8uV +tJVwuYKS0b55uAovjJtl0TE= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.key b/testcode/testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.key new file mode 100644 index 00000000..4c8e07c8 --- /dev/null +++ b/testcode/testdata/cert/pem/csr/rsa_pss_sha/rsa2048_pss_withattr.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsYOWP9bOUt6QS +j9hr3dSvSpDj7dFgTJZMn4BPy3FEQ6PyEDKORcQQftiNxTnTcg5i1TgWP4qgPaCH +U+lJW5CHF+xx0CV0qaHXqeVcwOWmmSWh90OWeEwKj5rGY+6QRHbgU+veDvTsdQOL +/hVKx00XsPYLotiyz1rZdZJleVrL6kcZzICfZOFLg66yg3qKieEnH1cfCOpQ9dq8 +lBGxw4m/3E9c69w+17PbbjEHcaUI+Zz8/mTWAyeodlFu5U5Z1EDKh3Paicy2lrDJ +JPpjMUILUswvXbETAiN2WZKKPsGA2aRMPZibqBHQkgYu5YIMR/liYzT45jPKenfY +lKEYZxjVAgMBAAECggEAAaH6UqqAXLJ/mJhps53ah52EcVA9mTSogMnK+JaD+GJO +oXqTTAMvp/tXmEIrucu9BKUh3p4T9VAYHugFz+bQ3+KzX+GZlTkNGiKXFFGUa0dM +krPpnTl++OOi0um75vxrBtVsqMIKAlpaYf9SWs639Xc84V/Vvx3VLbWeIR1s5X0K +2/cLZJrkT8YzX+kB7hnKW/75PPQbzeBloZAvYqWV9IvqJB8HGsXnUuGz/eQ04tEz +20S1EAdcOoOxV0IfZZvHaa8IAXidtlah5hRr2DYe+l54MgFTPWWJwq2E1bXC6ukI +p/8N/SGkZypi0aRRKdX8rWmCK3ASVzKCNvJZZJoOKQKBgQDVqVc//sVZn2PxALqt +HWx59sjl7Fv4VC8AmPafVtfasDsjEaUnI0Bwyaw2Yrp4NXdn3vxIbSDVLTrkhXA9 +WykiIC41uE3sVg4y3MoKlDJ8oJj2EeFrtSMUjPR4UDBBMb9Tsoq5GOA/0XlYdcZT +1k/m+So1ZoO3TglAxaLOoE/xaQKBgQDOiVhW8E5SGCs6F32awknbKZoVQwdcmZ0X +z1qojXO8NBPzQ64guW9sz45GR9e+ZSdoKgt1s3U8/CQUx9yEEDnn7yPcfvmBv8Jw +o4l3b1Tis6PZbMMAGCnYSDxfUC8HTPUrx+d19jMiZDj0pSrO4eEtkXVhvwfzqcQK +p+Y847/SjQKBgFpUVIHGuTKRs1QBheqIZQMPNZIXIi7TkGeFQ8bLlUhsdyP1Ysgw +HB9S886uYL1PhWLRoAESue3GSH6yd2hJMROvXTny6GbBXxFbzMM6MjoEP4bQumep +1eHrUbPH2w7E9GlzMzjb7nqsmcuvRyDMm01AC/s1kvwdLsZGh/UpS4L5AoGBAIZx +p1yofwM3kmP1SKEGGhedJBz1DgS8RiNqqgQQWCdJ6zaudtn8e8jj7yRWvdzFcfp/ +bAhJMmbpZv9T/nrFKTyOUdTFnttUHVk/S0vA4AvWjjEJeIJGOG7+zrXot0RUV0AR +l90Uz8JyZRTzs0MKjI8iIbvoI1/8wY2CMACw7Hw9AoGAX3g9zeZDEolxbPKes5Ve +0hom4ohRuM/javEXAEk+21vrg3irEcxzjHwx9jC/L60VDckEJ86/P/CmDu4GasHw +/Jq35DQwQqxkGxDR4TfhSKb/qMAmjG/dYgHr7CeGWqQyDth0QZ6ha5ufgrM35gyF +u4pkM/7N2hweI9qWjW0pVBE= +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr b/testcode/testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr new file mode 100644 index 00000000..8eccb5d2 --- /dev/null +++ b/testcode/testdata/cert/pem/csr/rsa_sha/rsa_sh256.csr @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDhTCCAe0CAQAwQDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczEUMBIGA1UEAwwLdGVzdF9yb290Q2EwggGiMA0GCSqGSIb3DQEBAQUA +A4IBjwAwggGKAoIBgQC7KwfWro3dvC6Fs8NdZnc5HXaHHxnWkYCksp1asXhLC/bc +aq95FhdvHH6zo4K577+iUyUmwUGw7xVlcGT/si9fNlfUlHSmxDSxEinrjURS0LBM +8iv6j1qTbb+3qkLTWTP+NmW+ev1bdp77DLj2bOoOwili3ZBJGvK6Iyoi68xz1p8F +dd4bC+IxUm7rljVH9aVR86i/ezhD4q95YCxODnExkK3Tx23snVO3fWfRb3visTAH ++drj9FbHHlxElndlp2NOJ+aPwQpaJD60tIP4KwpB0vtCylgmCTZJaCCXqzTCNqc4 +ZAWObKqXEM6Wr9LGsR+vjnPTC9WKFwI0AaI3UGQn2KDv5vUKBzXr0qU9iqWNZLaa +sqXC/dOOm3BXSBCK2iemIpR2W0CAY8oVjNPhvyDaOUKqhv+t3v6IF6QAH4IUEBuG +f6aRqeSxX06o/QzZl3mpZN0jaAGOdUg6h6J8VB4966z93plPFPbhlom8BoB9UtAV +GvMrH5Lhl4VhtxvsMqkCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBgQBxisOKC7AA +Jib1vyxmufh8/5if6v4wPWRL2VFkeBu8vWJcjLRZZo2vL+hRVVO8nkQl+wzfT/sR +sIfRjSdlyr5CPsStrQgdluF0XTvANwbIS9moBWqATmbTDB60qcbsDKe3HIJDdttI +EfumDGc6hIfEWPYAomAm+dEMdFEPTPSN0gRhlSzJnfvvmmWSS1gZdB/FTREEinI3 +DWKvs4bYq0oob6/R/wUkLjOQQdppIhe+YMQwanwsB4syWn60KhBrNv8m/e6LTDsQ +qhsPMhKACcUrI8hZAotCginT9mBfIr/V7i2wlbGtuCU+vh/FqldFxEbDNTCDmvMf +e/A4dEDK4iwKKvZJSfEsrxwssCJRqhgO33UwH9lJ6YHpH1Sf1RCwi5uMbphhOGEx +Pbk0nMAUjpUq0zxDItRYtGPqU+n174B4U4BMcQ8TmaOkrNfTWcgFr4XZ8FL/MK/V +FjzU2a+gAzv+ACIIUXl5hUxSeotTSwwdJuwep80uxDLfGpg1MCeD0Xw= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/cert/pem/csr/rsa_sha/rsa_sh256.key.pem b/testcode/testdata/cert/pem/csr/rsa_sha/rsa_sh256.key.pem new file mode 100644 index 00000000..8d9bcb2c --- /dev/null +++ b/testcode/testdata/cert/pem/csr/rsa_sha/rsa_sh256.key.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIG/wIBADANBgkqhkiG9w0BAQEFAASCBukwggblAgEAAoIBgQC7KwfWro3dvC6F +s8NdZnc5HXaHHxnWkYCksp1asXhLC/bcaq95FhdvHH6zo4K577+iUyUmwUGw7xVl +cGT/si9fNlfUlHSmxDSxEinrjURS0LBM8iv6j1qTbb+3qkLTWTP+NmW+ev1bdp77 +DLj2bOoOwili3ZBJGvK6Iyoi68xz1p8Fdd4bC+IxUm7rljVH9aVR86i/ezhD4q95 +YCxODnExkK3Tx23snVO3fWfRb3visTAH+drj9FbHHlxElndlp2NOJ+aPwQpaJD60 +tIP4KwpB0vtCylgmCTZJaCCXqzTCNqc4ZAWObKqXEM6Wr9LGsR+vjnPTC9WKFwI0 +AaI3UGQn2KDv5vUKBzXr0qU9iqWNZLaasqXC/dOOm3BXSBCK2iemIpR2W0CAY8oV +jNPhvyDaOUKqhv+t3v6IF6QAH4IUEBuGf6aRqeSxX06o/QzZl3mpZN0jaAGOdUg6 +h6J8VB4966z93plPFPbhlom8BoB9UtAVGvMrH5Lhl4VhtxvsMqkCAwEAAQKCAYAD +KWeCaSRKMrJaKFlRw9gaPc+W2eqQEm5TpJUeEdboH6Ld14CGLAkdI6RWnlm9kIRS +dpNEq77owVUsHOwGhL5M87L5S0EK4HrKY0s+0yisZHbsnypT2yWVeCUPsh+Fs0v6 +ofUcigvVxnPKO7gJKPmtjPqcKgV/XVDsiN5emiXz7ql03b2bg9sgPatULU9SRfRI +ZYm8IwBQ50H9wSc7x1MtWkC8IzI4bRzxAdGQkGX4REl9LQDqrmHj5F+nJJ/ji/e3 +pyMnMOaEL3aVX2R/IHmGon0aDTKJA8V7Wp1zji8GPpKH3PobJDWn1hA03EngORqs +UrcPcUYB6rQLbO93EK10JOXp+k8kKrQmxGkEIzCxSLaPZe0LP6/HQrSOEIpDoXXq +yQaUb5gZ1+vM+9Jmrt6tAdIrcr4qsVvWAJgPOG9SKavguzhkuWmzXRkykl0A3wwc +34CeduuaVrLtci+P351wkHXTP3SfFxEKHFO9CE1noxGpponk23gRM0kNJeyz9f0C +gcEA6niTvK47CzyXcgqWHdMRy5ddE+nEVzC+MknMvXfdgz7AEqecd8BiZj5ZKP3j +0KYeZ/CinxEuYJX4aP6W20m5grQLudqaYouuYkL3KAKrxOB1tZO71xvJjwiWMyut +H+yFF4xzF0ACJL3mwx+F854/1qNcs3ktl0rsszrZxG343WTE5JVDCzLqkDEtvgbL +NAxXhiRwLNDsl5Fa/e+wQuGWivM7xgecqhqt8ncvP43SbNRRIUmGDHLioSGvHpn5 +DtddAoHBAMxaj9CTRcJpwlCQGWX12gdZzDCyT0Yc5asRu0XUeeP5F4KnR1HV5N0B +Y+Qq0P5pJJlTxVW9YuwPwnvp7ClVJfmPUwxCFugwIUdpsQCJf7IH/7y3EAkK8VNr +qU6Aeh3azBqOff3Fz9I/tISsdYdRpSHqwqiC0eQfwAs4OvxHGVlHm4aCqzjQQJzS +0FmJnWnLk08GgJZsrDEwXdDx+Rv7PC15CUlFm1ckTT+CNESeMY6BeKOSBKS6YzXW +kjxWHO/PvQKBwQDWxpyNuQtcv6P6UrgvmagzVfNsyjWPqJaQegmRhLrj/hby/5XU +G+YGwhXp9qc3+PLhQwuzqYlR8A4cHxkQxfeoQkR7ekLxAgI7ABxmCgxNy04HhcwK +vulim/r55IgxNfa0G3NRWNCd11YKZlXNUqgndHz16YpZi8hGZSIVTKcqJaQ1voQr +PfifHG1KI+7/Pk7uEXKvmrEeJYe0FFrg6MN9hFC8lTxslQPBlmsxTDf0eIfYdgDU +ZmgyMSi4X1JExgECgcEAgD1ouMRi56EEzxfOyHxjKW/BwuFy/BXQTu1er3CqWVUM +2vHswL9Q0xw3Oo1f//etfwbh9G9X77noG2jtyfZkUVsPC8dBps3lZHJAII0o9Gku +pJfg2Tvju6z5X4kimS+gHB5FlIaZZ2CRAR1U1+l1jnZLWAJYgyclliTgZ0aa8rsM +L3o6xvlxQrjNBRNmFGkrdVEoSr3BxVCL3z6qTFP6LLMjD7c9x47BZ1RnRpRblwlK +0qMkhNduwO95b6G+oQOlAoHBAOkNWQ8ieBPTCg57Te4nC/7b4WsO1z+N1r3BkzKN +0/32O9j2AtjHHJES84PuYFpokD8yuX1vL7j35UwBD4w0lgQ6TSlhDeVLxCDh5tdZ +P8ZFbDVek5TlByHXmRvNKaKHCgdGHKlkEeSz3PJDYLVk0xuSdUbJJXWGT9dzp9fE +1MWTbWwkNK1as9VZQCvUTyi5Saen8C8vp3qog8owLAtAodEcPidOy9KyKAWyPOdZ +ZnF2oaUor9ScLxA5fT3TDva+lA== +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/pem/sm2.ca_v1.crt b/testcode/testdata/cert/pem/sm2.ca_v1.crt new file mode 100644 index 00000000..6a20847d --- /dev/null +++ b/testcode/testdata/cert/pem/sm2.ca_v1.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICozCCAkmgAwIBAgIUPtKAxiyo2g5EIv+MHOQ55m3lmXMwCgYIKoEcz1UBg3Uw +gb8xGDAWBgkqhkiG9w0BCQEWCXRlc3RAQWJjIzEaMAkGA1UEBhMCQ04wDQYDVQQL +DAYjQShiKWMxDjAMBgNVBAoMBU8qb28gMRMwEQYDVQQHDAojIHRlc3QgTCAgMU8w +TQYDVQQIDEYgICMgQ29udGVudD0KIEFhPcOPwoksw4PCgizDg8KmICBCYj08djE7 +I3YyK3YzLyN2NCt2NT4gQ2M7RGQ7IkU6ZSIgIyAgMREwDwYDVQQDDAgjdGVzdENu +IzAeFw0yNDA5MTQwMzQzMjRaFw0zNDA5MTIwMzQzMjRaMIG/MRgwFgYJKoZIhvcN +AQkBFgl0ZXN0QEFiYyMxGjAJBgNVBAYTAkNOMA0GA1UECwwGI0EoYiljMQ4wDAYD +VQQKDAVPKm9vIDETMBEGA1UEBwwKIyB0ZXN0IEwgIDFPME0GA1UECAxGICAjIENv +bnRlbnQ9CiBBYT3Dj8KJLMODwoIsw4PCpiAgQmI9PHYxOyN2Mit2My8jdjQrdjU+ +IENjO0RkOyJFOmUiICMgIDERMA8GA1UEAwwII3Rlc3RDbiMwWTATBgcqhkjOPQIB +BggqgRzPVQGCLQNCAATTi6ZquKpCAJS9L2C6SBVYzNolZg8v5vGPmtMKLW77wh6g +FvoPQpTHN4aF9h+CNUsJzX3lA8IsG4O/rSlFct/8oyEwHzAdBgNVHQ4EFgQU+z40 +9DV/w6g1HsnMgVXAUE8KG6UwCgYIKoEcz1UBg3UDSAAwRQIhAJqaVvgHiu14IcMR +ehjJS4qBbTqXR6D9+oLFxjZ2OOY/AiBMKXkbo7YVaEntHcYbvBlvWt17wMfqrb5w +mLnzT+ojDw== +-----END CERTIFICATE----- diff --git a/testcode/testdata/cert/pem/sm2.ca_v1.csr b/testcode/testdata/cert/pem/sm2.ca_v1.csr new file mode 100644 index 00000000..168cfe72 --- /dev/null +++ b/testcode/testdata/cert/pem/sm2.ca_v1.csr @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBfDCCASICAQAwgb8xGDAWBgkqhkiG9w0BCQEWCXRlc3RAQWJjIzEaMAkGA1UE +BhMCQ04wDQYDVQQLDAYjQShiKWMxDjAMBgNVBAoMBU8qb28gMRMwEQYDVQQHDAoj +IHRlc3QgTCAgMU8wTQYDVQQIDEYgICMgQ29udGVudD0KIEFhPcOPwoksw4PCgizD +g8KmICBCYj08djE7I3YyK3YzLyN2NCt2NT4gQ2M7RGQ7IkU6ZSIgIyAgMREwDwYD +VQQDDAgjdGVzdENuIzBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNOLpmq4qkIA +lL0vYLpIFVjM2iVmDy/m8Y+a0wotbvvCHqAW+g9ClMc3hoX2H4I1SwnNfeUDwiwb +g7+tKUVy3/ygADAKBggqgRzPVQGDdQNIADBFAiBtrhACReqGuCfBpcTHgZHfJFGj +XH6pyj6E53j0asgs1AIhALTpCFKWNYFmXaGaZdDhXl4G+4nnm5rKGAjjt9YHiFqY +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/cert/pem/sm2.ca_v1.key b/testcode/testdata/cert/pem/sm2.ca_v1.key new file mode 100644 index 00000000..29c3539b --- /dev/null +++ b/testcode/testdata/cert/pem/sm2.ca_v1.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgEm1TkGxhmyxtiQX6 +iM6sOCPkxCwhR+oX4RPFyzhv9NihRANCAATTi6ZquKpCAJS9L2C6SBVYzNolZg8v +5vGPmtMKLW77wh6gFvoPQpTHN4aF9h+CNUsJzX3lA8IsG4O/rSlFct/8 +-----END PRIVATE KEY----- diff --git a/testcode/testdata/cert/pem/sm2.ca_v1_2.crt b/testcode/testdata/cert/pem/sm2.ca_v1_2.crt new file mode 100644 index 00000000..a3eda53e --- /dev/null +++ b/testcode/testdata/cert/pem/sm2.ca_v1_2.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlTCCATugAwIBAgIUHUpWdANtYZR59FTHrVfj9uBpTaEwCgYIKoEcz1UBg3Uw +OTE3MAkGA1UEBhMCQ2MwCQYDVQQLDAJBYTAMBgNVBAoMBU8qb28gMBEGA1UEBwwK +IyB0ZXN0IEwgIDAeFw0yNDA5MTQwMzUzNTlaFw0zNDA5MTIwMzUzNTlaMDkxNzAJ +BgNVBAYTAkNjMAkGA1UECwwCQWEwDAYDVQQKDAVPKm9vIDARBgNVBAcMCiMgdGVz +dCBMICAwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAATTi6ZquKpCAJS9L2C6SBVY +zNolZg8v5vGPmtMKLW77wh6gFvoPQpTHN4aF9h+CNUsJzX3lA8IsG4O/rSlFct/8 +oyEwHzAdBgNVHQ4EFgQU+z409DV/w6g1HsnMgVXAUE8KG6UwCgYIKoEcz1UBg3UD +SAAwRQIhAM0JBtzLzkQ06t40jzgmuhUc5y7fCzDTzHqFLtJx0kF4AiBVydG+vh70 +Tjz4+bCBeafJLiABw7o0VkdceHL6IriJnQ== +-----END CERTIFICATE----- diff --git a/testcode/testdata/cert/pem/sm2.ca_v1_2.csr b/testcode/testdata/cert/pem/sm2.ca_v1_2.csr new file mode 100644 index 00000000..93d9a702 --- /dev/null +++ b/testcode/testdata/cert/pem/sm2.ca_v1_2.csr @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIH0MIGbAgEAMDkxNzAJBgNVBAYTAkNjMAkGA1UECwwCQWEwDAYDVQQKDAVPKm9v +IDARBgNVBAcMCiMgdGVzdCBMICAwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAATT +i6ZquKpCAJS9L2C6SBVYzNolZg8v5vGPmtMKLW77wh6gFvoPQpTHN4aF9h+CNUsJ +zX3lA8IsG4O/rSlFct/8oAAwCgYIKoEcz1UBg3UDSAAwRQIhAMqu3drxnYvbNrDu +00tCkcfg0y2FYkTJ6ak8Aa7pvvIwAiACl7VoVUoK4++/6/cPehU4Xe3BmuLko/I0 +6DDeGbFxgA== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/cert/sm2/ca.mul.der b/testcode/testdata/cert/sm2/ca.mul.der new file mode 100644 index 00000000..03296ea5 Binary files /dev/null and b/testcode/testdata/cert/sm2/ca.mul.der differ diff --git a/testcode/testdata/cert/sm2/chain-red.pem b/testcode/testdata/cert/sm2/chain-red.pem new file mode 100644 index 00000000..f2e5d92d --- /dev/null +++ b/testcode/testdata/cert/sm2/chain-red.pem @@ -0,0 +1,46 @@ +IzAhBgNVBAMMGmNlcnRpZmljYXRlLnRlc3Rpbi5tdWwuY29tMB4XDTI0MDQyNDA4 +-----BEGIN CERTIFICATE----- +MIICGDCCAb+gAwIBAgIBAjAKBggqgRzPVQGDdTBmMQswCQYDVQQGEwJYWDELMAkG +A1UECAwCWFgxFDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4x +IzAhBgNVBAMMGmNlcnRpZmljYXRlLnRlc3Rpbi5tdWwuY29tMB4XDTI0MDQyNDA4 +MjY0MVoXDTM0MDQyMjA4MjY0MVowajELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhY +MRQwEgYDVQQKDAtjZXJ0aWZpY2F0ZTERMA8GA1UECwwIdGVzdHNpZ24xJTAjBgNV +BAMMHGNlcnRpZmljYXRlLnRlc3RzaWduLm11bC5jb20wWTATBgcqhkjOPQIBBggq +gRzPVQGCLQNCAATj0ElbPVO5XtEXUMYzgjoe4MvhexA9W0JTf7u5/oVwCj1Dzp/O +ud+ujxVaMndyELkZNDv060AzPenWyPHr8V4Zo1owWDAJBgNVHRMEAjAAMAsGA1Ud +DwQEAwIF4DAdBgNVHQ4EFgQUdiaXKwjzMLRPYFTWsNZOBsKQdRQwHwYDVR0jBBgw +FoAUme6zg4EzQqE3jrmGcSrEal/1C6cwCgYIKoEcz1UBg3UDRwAwRAIgI2rpHI8g +pwLMUVS5hMJHA0Rp76Jhflno7eyzVCPkkhgCIH9om0X6YybhT+vRhq/IxnMEj5Ji +WpkkRopudu7NWR1v +-----END CERTIFICATE----- +gRzPVQGCLQNCAATj0ElbPVO5XtEXUMYzgjoe4MvhexA9W0JTf7u5/oVwCj1Dzp/O +-----BEGIN CERTIFICATE----- +MIICGDCCAb6gAwIBAgIBATAKBggqgRzPVQGDdTBzMQswCQYDVQQGEwJYWDELMAkG +A1UECAwCWFgxCzAJBgNVBAcMAlhYMRQwEgYDVQQKDAtjZXJ0aWZpY2F0ZTEPMA0G +A1UECwwGdGVzdGNhMSMwIQYDVQQDDBpjZXJ0aWZpY2F0ZS50ZXN0Y2EubXVsLmNv +bTAeFw0yNDA0MjQwODI2NDFaFw0zNDA0MjIwODI2NDFaMGYxCzAJBgNVBAYTAlhY +MQswCQYDVQQIDAJYWDEUMBIGA1UECgwLY2VydGlmaWNhdGUxDzANBgNVBAsMBnRl +c3RpbjEjMCEGA1UEAwwaY2VydGlmaWNhdGUudGVzdGluLm11bC5jb20wWTATBgcq +hkjOPQIBBggqgRzPVQGCLQNCAASBwTHidSzrqpXY4Fj4TtiPN4kDmG9xUljd92Xc +U+eh5wU177HsB1EezeCup9w+/Rq08KqwAmicRAf10GaPWGaXo1AwTjAMBgNVHRME +BTADAQH/MB0GA1UdDgQWBBSZ7rODgTNCoTeOuYZxKsRqX/ULpzAfBgNVHSMEGDAW +gBTJIRPqFJuTEgFnuFLu0R00xGZPNzAKBggqgRzPVQGDdQNIADBFAiEAr5RVgtuW +fbQz2N/WsM+j0aDeyyl4IFqSrwfEjjS2gaYCIBSxIG+fjGRzHwEdzyu0UXtMbxQi +X856RCw6OIoYpfTr +-----END CERTIFICATE----- +gRzPVQGCLQNCAATj0ElbPVO5XtEXUMYzgjoe4MvhexA9W0JTf7u5/oVwCj1Dzp/O +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIUNbK4EfgpQ+34N+WQGdT0T1ngBqwwCgYIKoEcz1UBg3Uw +czELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDEUMBIGA1UE +CgwLY2VydGlmaWNhdGUxDzANBgNVBAsMBnRlc3RjYTEjMCEGA1UEAwwaY2VydGlm +aWNhdGUudGVzdGNhLm11bC5jb20wHhcNMjQwNDI0MDgyNjQxWhcNMzQwNDIyMDgy +NjQxWjBzMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMRQw +EgYDVQQKDAtjZXJ0aWZpY2F0ZTEPMA0GA1UECwwGdGVzdGNhMSMwIQYDVQQDDBpj +ZXJ0aWZpY2F0ZS50ZXN0Y2EubXVsLmNvbTBZMBMGByqGSM49AgEGCCqBHM9VAYIt +A0IABLqvLKF5QS4tTvGKnZiADBw/PHA3yGiTjG5zOIppdCCwzFiO8fRQYpeysFkw +/PVLv7zmSu087pk8FMQ40jvEnXijUzBRMB0GA1UdDgQWBBTJIRPqFJuTEgFnuFLu +0R00xGZPNzAfBgNVHSMEGDAWgBTJIRPqFJuTEgFnuFLu0R00xGZPNzAPBgNVHRMB +Af8EBTADAQH/MAoGCCqBHM9VAYN1A0gAMEUCIQD9TpECwuJ/sJCCr/f0F8R9qRfA +P1iPA0tlM8KMRZk+CgIgLhsF5Jbpg1PlxPWwdyXCqkdd1IMqs5nEdW6nvX55j7Q= +-----END CERTIFICATE----- +gRzPVQGCLQNCAATj0ElbPVO5XtEXUMYzgjoe4MvhexA9W0JTf7u5/oVwCj1Dzp/O diff --git a/testcode/testdata/cert/sm2/chain.der b/testcode/testdata/cert/sm2/chain.der new file mode 100644 index 00000000..280cb744 Binary files /dev/null and b/testcode/testdata/cert/sm2/chain.der differ diff --git a/testcode/testdata/cert/sm2/chain.pem b/testcode/testdata/cert/sm2/chain.pem new file mode 100644 index 00000000..e86fd13d --- /dev/null +++ b/testcode/testdata/cert/sm2/chain.pem @@ -0,0 +1,42 @@ +-----BEGIN CERTIFICATE----- +MIICGDCCAb+gAwIBAgIBAjAKBggqgRzPVQGDdTBmMQswCQYDVQQGEwJYWDELMAkG +A1UECAwCWFgxFDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0aW4x +IzAhBgNVBAMMGmNlcnRpZmljYXRlLnRlc3Rpbi5tdWwuY29tMB4XDTI0MDQyNDA4 +MjY0MVoXDTM0MDQyMjA4MjY0MVowajELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhY +MRQwEgYDVQQKDAtjZXJ0aWZpY2F0ZTERMA8GA1UECwwIdGVzdHNpZ24xJTAjBgNV +BAMMHGNlcnRpZmljYXRlLnRlc3RzaWduLm11bC5jb20wWTATBgcqhkjOPQIBBggq +gRzPVQGCLQNCAATj0ElbPVO5XtEXUMYzgjoe4MvhexA9W0JTf7u5/oVwCj1Dzp/O +ud+ujxVaMndyELkZNDv060AzPenWyPHr8V4Zo1owWDAJBgNVHRMEAjAAMAsGA1Ud +DwQEAwIF4DAdBgNVHQ4EFgQUdiaXKwjzMLRPYFTWsNZOBsKQdRQwHwYDVR0jBBgw +FoAUme6zg4EzQqE3jrmGcSrEal/1C6cwCgYIKoEcz1UBg3UDRwAwRAIgI2rpHI8g +pwLMUVS5hMJHA0Rp76Jhflno7eyzVCPkkhgCIH9om0X6YybhT+vRhq/IxnMEj5Ji +WpkkRopudu7NWR1v +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICGDCCAb6gAwIBAgIBATAKBggqgRzPVQGDdTBzMQswCQYDVQQGEwJYWDELMAkG +A1UECAwCWFgxCzAJBgNVBAcMAlhYMRQwEgYDVQQKDAtjZXJ0aWZpY2F0ZTEPMA0G +A1UECwwGdGVzdGNhMSMwIQYDVQQDDBpjZXJ0aWZpY2F0ZS50ZXN0Y2EubXVsLmNv +bTAeFw0yNDA0MjQwODI2NDFaFw0zNDA0MjIwODI2NDFaMGYxCzAJBgNVBAYTAlhY +MQswCQYDVQQIDAJYWDEUMBIGA1UECgwLY2VydGlmaWNhdGUxDzANBgNVBAsMBnRl +c3RpbjEjMCEGA1UEAwwaY2VydGlmaWNhdGUudGVzdGluLm11bC5jb20wWTATBgcq +hkjOPQIBBggqgRzPVQGCLQNCAASBwTHidSzrqpXY4Fj4TtiPN4kDmG9xUljd92Xc +U+eh5wU177HsB1EezeCup9w+/Rq08KqwAmicRAf10GaPWGaXo1AwTjAMBgNVHRME +BTADAQH/MB0GA1UdDgQWBBSZ7rODgTNCoTeOuYZxKsRqX/ULpzAfBgNVHSMEGDAW +gBTJIRPqFJuTEgFnuFLu0R00xGZPNzAKBggqgRzPVQGDdQNIADBFAiEAr5RVgtuW +fbQz2N/WsM+j0aDeyyl4IFqSrwfEjjS2gaYCIBSxIG+fjGRzHwEdzyu0UXtMbxQi +X856RCw6OIoYpfTr +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICOzCCAeGgAwIBAgIUNbK4EfgpQ+34N+WQGdT0T1ngBqwwCgYIKoEcz1UBg3Uw +czELMAkGA1UEBhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDEUMBIGA1UE +CgwLY2VydGlmaWNhdGUxDzANBgNVBAsMBnRlc3RjYTEjMCEGA1UEAwwaY2VydGlm +aWNhdGUudGVzdGNhLm11bC5jb20wHhcNMjQwNDI0MDgyNjQxWhcNMzQwNDIyMDgy +NjQxWjBzMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMRQw +EgYDVQQKDAtjZXJ0aWZpY2F0ZTEPMA0GA1UECwwGdGVzdGNhMSMwIQYDVQQDDBpj +ZXJ0aWZpY2F0ZS50ZXN0Y2EubXVsLmNvbTBZMBMGByqGSM49AgEGCCqBHM9VAYIt +A0IABLqvLKF5QS4tTvGKnZiADBw/PHA3yGiTjG5zOIppdCCwzFiO8fRQYpeysFkw +/PVLv7zmSu087pk8FMQ40jvEnXijUzBRMB0GA1UdDgQWBBTJIRPqFJuTEgFnuFLu +0R00xGZPNzAfBgNVHSMEGDAWgBTJIRPqFJuTEgFnuFLu0R00xGZPNzAPBgNVHRMB +Af8EBTADAQH/MAoGCCqBHM9VAYN1A0gAMEUCIQD9TpECwuJ/sJCCr/f0F8R9qRfA +P1iPA0tlM8KMRZk+CgIgLhsF5Jbpg1PlxPWwdyXCqkdd1IMqs5nEdW6nvX55j7Q= +-----END CERTIFICATE----- diff --git a/testcode/testdata/cert/sm2/crl_inter_v2.mul.der b/testcode/testdata/cert/sm2/crl_inter_v2.mul.der new file mode 100644 index 00000000..f12f44be Binary files /dev/null and b/testcode/testdata/cert/sm2/crl_inter_v2.mul.der differ diff --git a/testcode/testdata/cert/sm2/crl_v1.mul.der b/testcode/testdata/cert/sm2/crl_v1.mul.der new file mode 100644 index 00000000..f0a27fa7 Binary files /dev/null and b/testcode/testdata/cert/sm2/crl_v1.mul.der differ diff --git a/testcode/testdata/cert/sm2/crl_v2.mul.der b/testcode/testdata/cert/sm2/crl_v2.mul.der new file mode 100644 index 00000000..08bf146f Binary files /dev/null and b/testcode/testdata/cert/sm2/crl_v2.mul.der differ diff --git a/testcode/testdata/cert/sm2/crl_v2.mul.old.der b/testcode/testdata/cert/sm2/crl_v2.mul.old.der new file mode 100644 index 00000000..30e35c82 Binary files /dev/null and b/testcode/testdata/cert/sm2/crl_v2.mul.old.der differ diff --git a/testcode/testdata/cert/sm2/crl_v2.mul2.der b/testcode/testdata/cert/sm2/crl_v2.mul2.der new file mode 100644 index 00000000..ae079f47 Binary files /dev/null and b/testcode/testdata/cert/sm2/crl_v2.mul2.der differ diff --git a/testcode/testdata/cert/sm2/crl_v2.mul3.der b/testcode/testdata/cert/sm2/crl_v2.mul3.der new file mode 100644 index 00000000..3e81d055 Binary files /dev/null and b/testcode/testdata/cert/sm2/crl_v2.mul3.der differ diff --git a/testcode/testdata/cert/sm2/enc.mul.der b/testcode/testdata/cert/sm2/enc.mul.der new file mode 100644 index 00000000..b6e2c198 Binary files /dev/null and b/testcode/testdata/cert/sm2/enc.mul.der differ diff --git a/testcode/testdata/cert/sm2/enc2.mul.der b/testcode/testdata/cert/sm2/enc2.mul.der new file mode 100644 index 00000000..98c30169 Binary files /dev/null and b/testcode/testdata/cert/sm2/enc2.mul.der differ diff --git a/testcode/testdata/cert/sm2/enc3.mul.der b/testcode/testdata/cert/sm2/enc3.mul.der new file mode 100644 index 00000000..53b2f43a Binary files /dev/null and b/testcode/testdata/cert/sm2/enc3.mul.der differ diff --git a/testcode/testdata/cert/sm2/inter.mul.der b/testcode/testdata/cert/sm2/inter.mul.der new file mode 100644 index 00000000..3640a074 Binary files /dev/null and b/testcode/testdata/cert/sm2/inter.mul.der differ diff --git a/testcode/testdata/cert/sm2/sign.mul.der b/testcode/testdata/cert/sm2/sign.mul.der new file mode 100644 index 00000000..e107adf2 Binary files /dev/null and b/testcode/testdata/cert/sm2/sign.mul.der differ diff --git a/testcode/testdata/cert/sm2/sign2.mul.der b/testcode/testdata/cert/sm2/sign2.mul.der new file mode 100644 index 00000000..f5020718 Binary files /dev/null and b/testcode/testdata/cert/sm2/sign2.mul.der differ diff --git a/testcode/testdata/cert/sm2/sign3.mul.der b/testcode/testdata/cert/sm2/sign3.mul.der new file mode 100644 index 00000000..53375a6b Binary files /dev/null and b/testcode/testdata/cert/sm2/sign3.mul.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/ca-nist521.der b/testcode/testdata/tls/certificate/der/ecdsa/ca-nist521.der new file mode 100644 index 00000000..014e92ec Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/ca-nist521.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/end256-sha256.der b/testcode/testdata/tls/certificate/der/ecdsa/end256-sha256.der new file mode 100644 index 00000000..414502e0 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/end256-sha256.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/end256-sha256.key.der b/testcode/testdata/tls/certificate/der/ecdsa/end256-sha256.key.der new file mode 100644 index 00000000..e94a2484 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/end256-sha256.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/end384-sha384.der b/testcode/testdata/tls/certificate/der/ecdsa/end384-sha384.der new file mode 100644 index 00000000..576f1b60 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/end384-sha384.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/end384-sha384.key.der b/testcode/testdata/tls/certificate/der/ecdsa/end384-sha384.key.der new file mode 100644 index 00000000..c31a7fe2 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/end384-sha384.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/end521-sha512.der b/testcode/testdata/tls/certificate/der/ecdsa/end521-sha512.der new file mode 100644 index 00000000..a7f75235 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/end521-sha512.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/end521-sha512.key.der b/testcode/testdata/tls/certificate/der/ecdsa/end521-sha512.key.der new file mode 100644 index 00000000..e8749dac Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/end521-sha512.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa/inter-nist521.der b/testcode/testdata/tls/certificate/der/ecdsa/inter-nist521.der new file mode 100644 index 00000000..1b039581 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa/inter-nist521.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.csr b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.csr new file mode 100644 index 00000000..beeee684 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBNjCBvgIBADA/MQswCQYDVQQGEwJDTjENMAsGA1UECgwEdGVzdDEMMAoGA1UE +CwwDYWRzMRMwEQYDVQQDDAp0ZXN0X2ludENhMHYwEAYHKoZIzj0CAQYFK4EEACID +YgAE0DVVT86P5iJe81lJ9pz6vuf3B93HulU/3FfRz+1CGKxnKCtkxjmbNrBlsDjp +8Lu4LERgrb9a2P326BVYhPDPG96/oN4yO6Arllh5UZlKyFPtbZuSPs1xaIMznnsE +BRoOoAAwCgYIKoZIzj0EAwIDZwAwZAIwVHojcosrHoea2R7UVOR8am0i2HjqWnic +gNQqJitS5cLyN5QvIr7JOpss8r9N6eeUAjA7fo113S8g9uFLxti27ZsSpQg5UwWN +6f4yApqCMQfL7NCaCwVOt6vH7JxDgUB0NEw= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.der b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.der new file mode 100644 index 00000000..e1d4e6e9 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.key.der b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.key.der new file mode 100644 index 00000000..8cebc2a7 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/CA1.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.csr b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.csr new file mode 100644 index 00000000..204e9256 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOPN87Uoo8wH5IgMGIWhjk/5OuMyKhNtTDgnD0sHoydUjtLFk0PK +1tBdRvHDQyek00p8tTyncfHvYXAnaerV6vCq5yzp7nQm9k4s09Ej/AvstOaJbREd +YT4IpXUlqB7Po+g9yK+2+s0ysDrBxVamT123RBr0lbzxdYbuQaXVHDKBVH6zdSRw +ut+/cUyvFB/Wpg5RZX2Ngzcc8aTtQOijyjHOd6mg6fFCyv+s+eWcwyFKZVh6qFkL +1KTykdav7QxtbDgZb0PWOoJg0MAPtLY8E/VV9SHE8BVQXoDDt349WK1Gwu/zD0AJ +GdIGpCScYobGny17eTToOFTpxbxJLHyUuQMCAwEAAaAAMA0GCSqGSIb3DQEBCwUA +A4IBAQClDZOrQbckihqAPOWRhbj+XZeQY5FR6CBuqhBNDZ1VJ3enyCJl/Vje1d1V +aXib9o6lUEZntPF8E72JDuh4s1nHRCBr7noLmwCvUxGZeUem/kX+zsP25o3qc2Mh +04Y1xUzb3aFtG9c1GhtRtd4vhCxJ2vs/Yt4lZZgKChsyKytPqmGX2kXV+Envoxeh +GnpLAwHDuqaj03QJHHNapzYkhq0BGkC2CMDwblLncMmv27RtkkgStRnS3i3jIscq +/gHkwOpE/+9Btu6qik82LEYPgdaS3tuujDrn81tchTQmkKj973jWUpeuZNP2EeaF +8CurvicAgGvYjx0dN0J8ezVz18d6 +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.der b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.der new file mode 100644 index 00000000..4eae9d5a Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.key.der b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.key.der new file mode 100644 index 00000000..38726927 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/ee.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.csr b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.csr new file mode 100644 index 00000000..23da644f --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBODCBvwIBADBAMQswCQYDVQQGEwJDTjENMAsGA1UECgwEdGVzdDEMMAoGA1UE +CwwDYWRzMRQwEgYDVQQDDAt0ZXN0X3Jvb3RDYTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABBu8O/NbsbJqt180COKGbAdh/ygDmsRneiY9p8QhaXW2ee0ChWSw+Dhs44u1 +agrk30eXGoOlwgS8+zr8zzXhiezjLzIowR/4u3qf5sDb88QTNyuun367VzuwC9C5 +4GjpRKAAMAoGCCqGSM49BAMCA2gAMGUCMQDh7AitMwF/f9Ysd/5q9PgXf3pAy34H +ZMGk5Xia97iloVbRbqSPpFzgVql/J1dE4i0CMCM7czHJmJV2mWt8uG/Rkox3vDIt +XAvqyI5RK4w1qJJ/g9MbIDk6PZ8u919/j1jhjg== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.der b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.der new file mode 100644 index 00000000..a0f5a6e3 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.key.der b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.key.der new file mode 100644 index 00000000..a09bd0a4 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_rsa_cert/rootCA.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha1/ca-nist521.der b/testcode/testdata/tls/certificate/der/ecdsa_sha1/ca-nist521.der new file mode 100644 index 00000000..014e92ec Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha1/ca-nist521.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha1/end384-sha1.der b/testcode/testdata/tls/certificate/der/ecdsa_sha1/end384-sha1.der new file mode 100644 index 00000000..062e8055 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha1/end384-sha1.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha1/end384-sha1.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha1/end384-sha1.key.der new file mode 100644 index 00000000..b9bb70f0 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha1/end384-sha1.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha1/inter-nist521.der b/testcode/testdata/tls/certificate/der/ecdsa_sha1/inter-nist521.der new file mode 100644 index 00000000..1b039581 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha1/inter-nist521.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha256/ca.der b/testcode/testdata/tls/certificate/der/ecdsa_sha256/ca.der new file mode 100644 index 00000000..e3e3641b Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha256/ca.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha256/client.der b/testcode/testdata/tls/certificate/der/ecdsa_sha256/client.der new file mode 100644 index 00000000..6ae2304b Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha256/client.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha256/client.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha256/client.key.der new file mode 100644 index 00000000..2f525aff Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha256/client.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der b/testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der new file mode 100644 index 00000000..8f1d10b2 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha256/inter.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha256/server.der b/testcode/testdata/tls/certificate/der/ecdsa_sha256/server.der new file mode 100644 index 00000000..1b479621 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha256/server.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha256/server.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha256/server.key.der new file mode 100644 index 00000000..1c27e149 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha256/server.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.csr b/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.csr new file mode 100644 index 00000000..499d3a08 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBNDCBuwIBADA8MQswCQYDVQQGEwJDTjENMAsGA1UECgwEdGVzdDEMMAoGA1UE +CwwDdmRjMRAwDgYDVQQDDAd2ZGNfZGV2MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +lTCDh+bGORFRxVzjUc3Vso0raNuZz+L/uKD+sXzcoaizVVpWnEWCdta4vp7An4qj +CyUVnKN7LitW/FzM0huF7PBufctomR7W1Fro+4vfsqCf+B3s5Mp25jB5lD3lG7P1 +oAAwCgYIKoZIzj0EAwMDaAAwZQIwEIOFF2OFFeYmbtlkJgEyYOLI1yJpG4emUze1 +JVhBBE30mPW/s13PwSSZwIFdLu1yAjEA4WOpnM1yskxIUwE3TOcr0S2JLiMRrnXu +FbfjhgT2zZDCpscSbNj0xXorH8l8qEpZ +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.der new file mode 100644 index 00000000..282daa93 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.key.der new file mode 100644 index 00000000..e24d9385 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/client.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.csr b/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.csr new file mode 100644 index 00000000..8e6b395c --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBODCBvgIBADA/MQswCQYDVQQGEwJDTjENMAsGA1UECgwEdGVzdDEMMAoGA1UE +CwwDYWRzMRMwEQYDVQQDDAp0ZXN0X2ludENhMHYwEAYHKoZIzj0CAQYFK4EEACID +YgAET2xYbA9+Z8DsBtw7kkJJgN5S9HdhXrNpEc3ywy2LzmAFQvOpla2d7JySRvb2 +1O089OA/qUgS/Hc06O/goNLJb1tY5O5f2/kkLaNstwNLlvxnI3HyasUjfxC1seg/ +M0nooAAwCgYIKoZIzj0EAwMDaQAwZgIxANZFReGL6oAaDcMrQ/1yJ4bSDMHlPQQs +PGI+lmsf9N/nxVHmTUDmxZRcwX2ncAlwRwIxAJm438CmBgykw3REMX7EMiMnXQJJ +63+Fbgo5WKoJeZSSvdsF41AsRgGNaGF+30bFBA== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.der new file mode 100644 index 00000000..8f7bf64b Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.key.der new file mode 100644 index 00000000..96ad4273 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/intca.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.csr b/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.csr new file mode 100644 index 00000000..216142d9 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBODCBvwIBADBAMQswCQYDVQQGEwJDTjENMAsGA1UECgwEdGVzdDEMMAoGA1UE +CwwDYWRzMRQwEgYDVQQDDAt0ZXN0X3Jvb3RDYTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABMkuU5PUxUJwDE+Wu1rBEAoW+OdD7WvUATY7rgKaRBtmEMNp7iJac1ImTCki +w/K9YGtmnCTiJYOptgyZveCECu6k2OSpkz7jOLoR2TpYK1eQh5geS58y3Jd0TY4p +QL5a46AAMAoGCCqGSM49BAMDA2gAMGUCMBMiMLfkP9qOKoeK50cCF9EElnYQTv0P +zWyLrcNvkHNOJiCfWcVvyFt1qPRm0Qd7MAIxAL7b5hUrVpo0ApSjaXOLI06RYJAM +rDa1cxr0kP1rf2iHIAWSZ2LME4ve9nMdAqhHAQ== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.der new file mode 100644 index 00000000..2fd61937 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.key.der new file mode 100644 index 00000000..0e5e3956 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/root.key.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.csr b/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.csr new file mode 100644 index 00000000..8eb6557b --- /dev/null +++ b/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBMzCBuwIBADA8MQswCQYDVQQGEwJDTjENMAsGA1UECgwEdGVzdDEMMAoGA1UE +CwwDdmRjMRAwDgYDVQQDDAd2ZGNfZGV2MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +B1oTlq4O1pO0iUQid0GFuwN/sKqW41JSKIsOhosXDePfSNO5V0j4p+Xkna8o1P9x +9ulTB+bIybAXAlFFUkmm3vQxIO7wc36cvbh/ivyx/r5VG8noJDdJ6z4ObAJuM6dD +oAAwCgYIKoZIzj0EAwMDZwAwZAIwDkfUFxg0CjX7Y5ai70s7DML7ich+tq6hWEmC +vUMKIzm/oBkmMI7C0pTlsL4K3g1iAjA4XLNRWfeyijTjdNhjBEW7x3Vggwr+dnRK +Imu2QJhZY6jHL2pMGRIOPtfoFrT2TfM= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.der new file mode 100644 index 00000000..3c34ae35 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.der differ diff --git a/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.key.der b/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.key.der new file mode 100644 index 00000000..fbc076b7 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/ecdsa_sha384/server.key.der differ diff --git a/testcode/testdata/tls/certificate/der/need_passwd_cert/eecert.der b/testcode/testdata/tls/certificate/der/need_passwd_cert/eecert.der new file mode 100644 index 00000000..50b5c0a6 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/need_passwd_cert/eecert.der differ diff --git a/testcode/testdata/tls/certificate/der/need_passwd_cert/eekey.der b/testcode/testdata/tls/certificate/der/need_passwd_cert/eekey.der new file mode 100644 index 00000000..fccc958e Binary files /dev/null and b/testcode/testdata/tls/certificate/der/need_passwd_cert/eekey.der differ diff --git a/testcode/testdata/tls/certificate/der/need_passwd_cert/servercert.der b/testcode/testdata/tls/certificate/der/need_passwd_cert/servercert.der new file mode 100644 index 00000000..ede7e5a2 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/need_passwd_cert/servercert.der differ diff --git a/testcode/testdata/tls/certificate/der/need_passwd_cert/serverkey.der b/testcode/testdata/tls/certificate/der/need_passwd_cert/serverkey.der new file mode 100644 index 00000000..4ee952c9 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/need_passwd_cert/serverkey.der @@ -0,0 +1 @@ +> \ No newline at end of file diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.csr b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.csr new file mode 100644 index 00000000..fe71029c --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICtjCCAWkCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMJQdIVQC4C1C02H2Rj5CeeSf3MIYAKAzVyRAkfb8Rvz0Ci1+yS9 +yf0zcUbtywTdvg8cUDLPit2a+i+gz4qMWdg/YOS4+RCKm8FlCiBhrpWCkTk3Xf4K +pIgzacGiPlAd5UULqf0jxBs5XD8xSB2MDabnjJvsbSN1cx5jtmm/dANNR+j5nRvG +JiRBvx4+Ea/q7X/B6Y/cv0y5+SLgZiQzaHRQd4DTaBwmhvjn1jMYJNpbCrfcyarA +XUgGMW5g+68GAHEnVjii+KmiKf1nNReMLW/dyUB4bUnz8q0vP1hgjq4vovSg5y6H +xjl4Bz05inZvRGz8BMf+4W597tYygo7d2qsCAwEAAaAAMEIGCSqGSIb3DQEBCjA1 +oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCi +BAICAN4DggEBAFuAZL5QmHn+43n7kZs4xUsy60s352MhMSdckFHadH+1YBhiEy7b +aKk6NWjw0kKUfscjbwaJm/DRHwNeNeIU1/gauewrnXuXM7TJ+37PM1xOKd90YBna +hDr87kcMt9NYLdJ7uc1+zsYqqHhbkykGfXETdreqs4CjMoQNgnAKH/k5a36HX2QE +XiqcWes1zpZZkcI+u+7vQr7MYpDP4udbrAsnPBei/0R2Yqogtp/sk+MHnzrcDD+E +M28aCHNJQRGQLR+4ipYS6t6DNr4P0jb9XCE/MNWETdfqhrfECeymWC6jIiO83wc1 +5vvrcCIDP2NneVahaFZQgZj8zAvph8QpMco= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.der b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.der new file mode 100644 index 00000000..fd8b50f1 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.key.der b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.key.der new file mode 100644 index 00000000..e1785664 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_dev.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.csr b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.csr new file mode 100644 index 00000000..0a486b6a --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICuTCCAWwCAQAwPzELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczETMBEGA1UEAwwKdGVzdF9pbnRDYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMt3mwO4tXJz8mDeJr8ssqiVc74G7I2NubvUEyincLkxxbdU +rIGGPdLzLjOMMVEGPw5DC/F3yR5nc+29WTmqtUDB7vhJxfHjGSWMhVyxbncFR5Ac +AeY2z54RBwy3p89j6vfja4qbbGfHqwWUSrp+rvU7GVPU6rEnmt5mwyH9ZRRFZj7j +dV/oaWBlEQB1OgEdR5+V3xEfq3mLykNu3GeQCqyRCZSEWMWD7epB5VsaJtdHSaEP +jgR3lomaAHip206rke6ixRNBDntIWAiITVUPaCOA4SIDNTGHqJXNi0VxLBGq8kUU +ZzlfNYWROqaeOjJ30RuD3YA+gq3WgyXm9QIMoWcCAwEAAaAAMEIGCSqGSIb3DQEB +CjA1oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIB +BQCiBAICAN4DggEBAFIaZMjXCo9r5B8axjSSXNHoskHL5AQ3LnnBtopwVV3ko5gw +NL5pE5rHLQcl0hvcZul7QT3LqsT1+PvKc6icXP1i7GMLEouHxxJNZnaDvVjiaXJ6 +b2vUijx6ePfO2A9U2ytbf43/G3P0F/S8rTj+0ooLh6ktw8PhA4Wr+VmS6A1XhrpQ +Kt8gm9bDq548yodbs/VHJd5bY+F55i9xOUGXJr2I6JlCCbKLrJd/SM+nwxRNNxxt +nBk5wChK+3oNDpXlDdL1Ait7V28McdWVptsmbQYd3gVaeBZcibSHCgnuGvZ/olk0 +/IvFrOJsGh+8fmU+AJZpSdx4gaodv61lIX3Aiug= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.der b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.der new file mode 100644 index 00000000..2570c635 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.key.der b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.key.der new file mode 100644 index 00000000..8550dd1e Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.srl b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.srl new file mode 100644 index 00000000..f606cf2c --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_intCa.srl @@ -0,0 +1 @@ +7168A1A1C8AD4D766C2D133A5F1D974A1D7CC934 diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.csr b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.csr new file mode 100644 index 00000000..725bacf2 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIChTCCAW0CAQAwQDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczEUMBIGA1UEAwwLdGVzdF9yb290Q2EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDDpjw3u3g7eb7Ldsttdrcdz2j/+umDMKbmF9J8e0CSXg3B +9/4argIfLnncmEhsz64KkPjqCqSOVX0LFz1xsRhXeZymMRpAxCVU4T4jkVzzTt2o ++NWgIUK6ElFeUcEASgmTfOYYmbxM8qlmzbOx4mtlftDw4j7LGR02ZnTQKwQOBjNI +ttjIsKtZT7qBBCQdr9j5C0yERGMnpH2MY96i6YMGHrs6247v8hqnkE/viLmglEnw +LjsQ48E3suHuimx3M34lCMiYLw1Ivg8rOWit4RuFljPCepq2owVFzFgxMc3Gu4mF +F6+Ni3cpe/XZ3WK2BZfZcYN715RIICQ/36XWa0kpAgMBAAGgADANBgkqhkiG9w0B +AQsFAAOCAQEAgmvBnXgmjBDUSCVokAVAEo+YpltMrtzyoyqBaoD6C9i2nOb7LnEb +7crdLrMRJTTUJqgBY06mHbAgeFdjQ8oIM+4vez4rIvpSS7n47JcuFYfORtZJUaJV +SzBnDgAnk+RxQiaHd7y0G8lOeZrR5nh5iztfJYYBTEBN5S2QLth4PPPUl5Z8yCv2 +kgTFutRQ+95AaMEnW6it/tlqXF20NnO5gLsknAgnsmGP16yOkQlHCAmj1Ezz2xK9 +3GQVcKJOPZ6JV0JutGQVYBIySuSD/CWQh1ymoJ048B0OAyCmsFeQ5ubMAWHfEYks +Lv+SBCd/TnPeQLhqVJMK01MvVuTanRl8kg== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.der b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.der new file mode 100644 index 00000000..893682fb Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.key.der b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.key.der new file mode 100644 index 00000000..4b90cfc5 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.srl b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.srl new file mode 100644 index 00000000..3d807da2 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/rsa_root.srl @@ -0,0 +1 @@ +3D94152130CC8C66735872BAEE8DBACA9245E275 diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_rsae/tranformTools.sh b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/tranformTools.sh new file mode 100644 index 00000000..c67e39b7 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_rsae/tranformTools.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +CERT_FILE_DIR=$(cd $(dirname $0);pwd) +pem_files=$(find ${CERT_FILE_DIR} -name "*.pem") +for file in $pem_files +do + echo $file + sed -i '$d' $file + sed -i '1d' $file + newfile=$(echo $file | sed -e "s/.pem/.der/") + base64 -d $file > $newfile +done + diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.csr b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.csr new file mode 100644 index 00000000..03aa5887 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICtDCCAWcCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCASAwCwYJKoZIhvcNAQEKA4IBDwAw +ggEKAoIBAQC+E/IgbpJdKHeT3tMjAcCAJPloNhwwXqDWbX038CbUnLTX12HmJyR8 +yCEq1TcaEYXA9zXR5dtsN/S2LCEfrNW6Fni6gcfsuPSeyOYZqMAYQ01Exx5iLS6G +noOA5EOu5ilBgiW77oAI6MNbiNw+2R3JRqMjUAyDlhz2XXsOh8jWSVCOSoqCJqf5 +yqD0lZ16e4ih7SGU+Sk/xXhIULz7haAftQwLwHcpKF5mbxLBN2KDE/BN0+RTNP0m +0ELSf1+acWh6SruqoI6L4ep86ggrQoZCVNEplloi2ZlrakrsxIhQ0Orgr93aRSqr +AlzLhW3/WdXGVOf6MRVRhIWrwRnhl7oHAgMBAAGgADBCBgkqhkiG9w0BAQowNaAP +MA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogQC +AgDeA4IBAQCOLLLdFJB0+NFPVhFpZik6CdOrQ/hY6Y/IdSZRH8nOXCjZfJx4UOll +oEgQDnUKzVe8Mg1UYRH9hfvHD7G+MybO6mSqjby0Uc3jfLlvDmL+OK0WcQAXhwta +dSQK7GPRHanVJQMIUKbr4feZg6zOa8/kI4nIye6k/BjifQJLG2/jzs4qTxM8buCW +FrchTgXrlZZcswLFMNAe3B94kwWOM2FagQzpfh2FONWreqvq9K4jK9A6jjdZT0ie +ExLuPsZZuR6JNnnNRaZKH5r9Y4K1yrqvkUQF4Y+Cehmm/Fls4UJBtn0J1qfW+vYg +szXratYBxmdYTT90l+b0NO+QlKZCQKP+ +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.der b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.der new file mode 100644 index 00000000..7595f797 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.key.der b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.key.der new file mode 100644 index 00000000..b2a6ed75 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_dev.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.csr b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.csr new file mode 100644 index 00000000..e9a7586e --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICtzCCAWoCAQAwPzELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczETMBEGA1UEAwwKdGVzdF9pbnRDYTCCASAwCwYJKoZIhvcNAQEKA4IB +DwAwggEKAoIBAQDcJi6EQ+tiiLiTRzv8dS9jEwqLun03lty6qEI2ed/2cWTP0tm4 +JgfMTZULLNANHjZRb3VDNGKo7ATXQHS5FHQPkGX7DkXVhhAv1r0k1pdXSYpevARR +r2Oi1oiTvJRqVfnN8syI3nHPpaeG2XmwNxF2yFlnSmlK+fhjzePW7WZPeQgF1hGX +q2Ri2h1Vp1z0q1GiAy4U3VFnt1giug07Zox2VvqR0I/Oj3iyupdJNP0V2R26kKaH +jA+TWzAa21hWMfdMMFeUXs+FgyJcOf3K1q9gh9UcxwJbdfEmlZBuuSMVgU5bDnFT +ZaxqkXTatFTmgynYX58T11BnHQ3ZsB64BvXPAgMBAAGgADBCBgkqhkiG9w0BAQow +NaAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUA +ogQCAgDeA4IBAQBeeLCJjZqJ1GQqjaLbyZIrJWCbgl+GdnRfydxmaRA1NKcekxCv +ckWdqr0AnEZ3t4DfVbUWpo41mH670PmyzFD02zJlHh/R6KX4wXuRjQxxvVuONroR +6Xyoso0iYRxkZ/WutmYyHAudaCC/GWCeroQqwFbjFOU2wD+ZXNB6vP24xELBd/mJ +hEFhW4AeDcOLo0iTYqVcqpHGIs7ZLvS0DjbnPteJKBEsU+rRXzEOyUWarIaeE1UF +jknX52Wjo69NguVmXBh7OrCEX+eW33Qdm7bTTxkDLp12HtALSh+QDNPOeL8CizIt +Z4dblS9NvyYnNAUIuD6NPPhLMdM9dYcvAFSF +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.der b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.der new file mode 100644 index 00000000..ccae085f Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.key.der b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.key.der new file mode 100644 index 00000000..a5f733ad Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_intCa.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.csr b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.csr new file mode 100644 index 00000000..5cd72e87 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICuDCCAWsCAQAwQDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczEUMBIGA1UEAwwLdGVzdF9yb290Q2EwggEgMAsGCSqGSIb3DQEBCgOC +AQ8AMIIBCgKCAQEAqX0h8m+jS3xexBlAwy1NRahGJDiiZgMQYOV4sqln3a0LREOI +njPnLbxMIFix+Q/+hfzcYguyy5y30AtWe/qlu0qSw/cNbftKYb5sZmWhpJ7qKVn5 +h29DbLOyxoDmZqDescIyujLz12YXaUQFMKMvvY3Vw6YD01J6L1g3NBAucfDrdXoL +oVsmQo+nMvcA1apYaVirng/JUCUFYDU4DWDNKU7K0i6IlEVxiKShpGZAU4u++wrS +oKhe8CqiB3pcbg9d0RC+XF1Be+p+CFAG8aTBVqfUqNdgEhHmXdrjLXbQlvTRr7Gu +ApQoegF/Y6eCVMCJqraVD40LWaN15Nc4DJP7lwIDAQABoAAwQgYJKoZIhvcNAQEK +MDWgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF +AKIEAgIA3gOCAQEAPfLMs3l79r+Gk0luYhda+YEKyuY9qob+iKQW6WmdMO91/5vM +FBKl5rRrj2Lv1HoIq8On6fBXmHddMNGkiYcILRI5e+jkGyvJjPQQVG/T0Brj56fR +9RFhvcqjHHUx2PJQgqKluh1QVHWiUndn/qdIYBexiKnJdab+3yVq6l6sHlbSFK9a +dTKzMapuDcnwxCewnx2GYiCFE+IiBBXcY6zQEUMn5jMQFyxcCy5WhCNQb8+lj+Bw +RIFnK5uW8mBkOj7VxQPxGJh6QwU5+6LzixC9itX1wO3fzZ8Dc4uRkVmA0buHHBPT +qikz1CHmJUZtMRTcGXG9tofrxS/HVVRbW9kmDg== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.der b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.der new file mode 100644 index 00000000..ad9b35f9 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.key.der b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.key.der new file mode 100644 index 00000000..c92b2d34 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_pss_sha256/rsa_pss_root.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/ca-3072.der b/testcode/testdata/tls/certificate/der/rsa_sha/ca-3072.der new file mode 100644 index 00000000..8e2bd3a7 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/ca-3072.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.der new file mode 100644 index 00000000..d0e07719 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.key.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.key.der new file mode 100644 index 00000000..1989c907 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha1.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha256.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha256.der new file mode 100644 index 00000000..8ed72b3d Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha256.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha256.key.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha256.key.der new file mode 100644 index 00000000..79f485dd Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha256.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha384.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha384.der new file mode 100644 index 00000000..7c412c46 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha384.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha384.key.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha384.key.der new file mode 100644 index 00000000..3f6299d5 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha384.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha512.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha512.der new file mode 100644 index 00000000..70c28167 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha512.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/end-sha512.key.der b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha512.key.der new file mode 100644 index 00000000..71894872 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/end-sha512.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha/inter-3072.der b/testcode/testdata/tls/certificate/der/rsa_sha/inter-3072.der new file mode 100644 index 00000000..ba496f92 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha/inter-3072.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha256/ca.der b/testcode/testdata/tls/certificate/der/rsa_sha256/ca.der new file mode 100644 index 00000000..c4a02266 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha256/ca.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha256/client.der b/testcode/testdata/tls/certificate/der/rsa_sha256/client.der new file mode 100644 index 00000000..4af2c273 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha256/client.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der b/testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der new file mode 100644 index 00000000..b8da7811 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha256/client.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha256/inter.der b/testcode/testdata/tls/certificate/der/rsa_sha256/inter.der new file mode 100644 index 00000000..e1b11dd4 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha256/inter.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha256/server.der b/testcode/testdata/tls/certificate/der/rsa_sha256/server.der new file mode 100644 index 00000000..7298cff9 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha256/server.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha256/server.key.der b/testcode/testdata/tls/certificate/der/rsa_sha256/server.key.der new file mode 100644 index 00000000..31b57b5f Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha256/server.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/client.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/client.csr new file mode 100644 index 00000000..ac8b610a --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/client.csr @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDgTCCAekCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCAaIwDQYJKoZIhvcNAQEBBQADggGP +ADCCAYoCggGBALwfCqfhOYW1z1/zLNVM/SuDnP34kHtEkHBWCeE0ePyynv8zwzma +mAaAPhi/maO0GJ9QtPLhuv2eUXWLPNrKtWt9Dl8I1nky6Pqbz0pNYymQQlyIUdPg +YRtSrEGBH9M+PJNWq6hPMTMzuxckikeC013eIKMsR0CBB07gasNSzi2HQPQVFwzq ++rbNm/hDctk1GsJV4MaeYFfjyK8UKcw98QH5SyC5KAlh3iS4veIbBmSq1hhVbH5t +1Hf3WngkLsAeQig55RHi3GC3mVjdf/DaGx0SiNv0uh9y5TjStR2jfkGUkZcYrN8G +uB+TMGnWQzHb2QARwMAWzUPGy2qKPjpgm2NrFCNAilmTFgnNKtYtHLKjwqS9pjDw +aXP3C+ztoG9rDcy0/MGRNepjt4X3RDmO39uKs763PIxAyOnE/DfLmUnR8wFdVgGw +r0zW6Ko5344SHMCO32A8mMzJjBoRT1NUkkRvRcw35oKaCH8qw2mOt3U4dqa65zlK +6PVYUq7uWdoVzwIDAQABoAAwDQYJKoZIhvcNAQENBQADggGBAHmIyUbVOy++d780 +h2ypSTqwXPndkZMPz//pvrF/PNewhIqdqOzIPMQxWnW4RqcSPkrRc+9XLA4DlJcE +kGmNOR/FnDMW3HvRkHn2N6sSkbe6U+vbrp7T7XLpHW4/8uCBbUG6VAG9HQwH74fM +A4I9UcGfbrp/h35T82KeSNAuu1mPcti3kHpefbtM66fbdcHI7ZZKqT9md9aSdkp0 +yj/Z4LLT5zirqNRs8Kwr2ymzIdhRSiuU7SdrfANMRog1xLt0VA6al40Bh1lp6AFs +CxDBZY9dhlrTOAc3G8Zl0tfnL+1Y97dczcuDIR5nMQiV3bFsvFc6GpSDdbzO/4D9 +KhFdGjbhcRYkgkFVpc8rAEXshz+7BI0fUBnqN/wgiLyIQcdFH81vvBHDDL3O/RbE +t0kTB1v8jEFpr8Xf9iVSEC2IdLSuA+gdjdiPOUS9ZajY842tUnU9L9E02iqygQ+A +fJvJIPznDeJDIv6IHy/2RqBluGsYMO0f1Ry7L5qj2txeJHvi4A== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/client.der b/testcode/testdata/tls/certificate/der/rsa_sha512/client.der new file mode 100644 index 00000000..59b11c46 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/client.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/client.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/client.key.der new file mode 100644 index 00000000..0080fe5b Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/client.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/intca.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/intca.csr new file mode 100644 index 00000000..83d548d4 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/intca.csr @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDhDCCAewCAQAwPzELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczETMBEGA1UEAwwKdGVzdF9pbnRDYTCCAaIwDQYJKoZIhvcNAQEBBQAD +ggGPADCCAYoCggGBAMNsuSPTIdie0zgiEKTD7EqWrrE+Q4gzYktxJwWtGy+j8vHo +nxlkm2/HWUrdPntKMSv9beXYlGwbkjNMgMftdw2Q1gwgWAdMSovLaaocU+TXqhGu +bwi917mgPJx3m5o3p9SxR89SKV0KF3Vw3q8uRbKq910ElzskAkoYjP1j/+IjbgVW +VJliQOURwKTY+E850yirRf3to32KzodmIdbYXi8ixZzU1BeMf8FzWbq5+0TogQ/1 +GNjwf7kryL45wnU5uNYKAQBU4uJA93YElG7mALjq7gYGssgLBUPlp7vq7rkPuSSE +TVOBzZRFNWfecQ8qzh9OTL1KZL/3f1ecg4t+WuzY7VSAbb35BIpGf54as8Lbz/6a +tU8bTrIlu1x5JFKDEC5mbxCJhVt19pAix6AnwcI0AV8EE9qMy87oEhSO5e7Ivfjd +oQsnIrzvbrumNRCvRWF4wum+R5Gteb7dgTbbcWGA9aec3xMCRHoNcyoQK5G1sy/r +OFLJ2YSyxF0XugLFSwIDAQABoAAwDQYJKoZIhvcNAQENBQADggGBAEYCaD/fhQyv +fh4mRdpR6LG9ZT12vFUMH4Qm2nh2xsn9DqZjfxa6UXPycpFm7WIIDcQfPNvyC9QC +QDlmQVadw0lxn5Sv6fmi6hnw7UWolGY7ekSIRla1/vAUxD+DH4XX0XtC3QdnKmVH +XoHqAsnOJiF6++e4vsphC8CaLZah2OTNoMCc37YrpGB2Tq5EigNgdMlNGGqzxVPW +ogf3RhXRaOcJElmnKETd9yf0DVxWVwAmENEMUdiNwJ7Uvk21c7u7PtKpCE5NYxu6 +5Wlj7r34jepfibt6UVeMGEL7qb4OqUR0QcZ5q0UxyB7LmFf6iGDH16yZaWiQDGF4 +qYyPuDcyPqFsrdolJQP4smrgszovnRd9QW4vAd7RRJOYh1ParOpp2bhnaYkdhl/G +A3NvCCvgR05VCMkM7vG2d0hR8ddfDJRPNpvGOxCHKXPvRcQJNVSnzQraCgcy6/Tg +PZNciIxHlvK2jCE/74B80EZjOz3uX8yYSmQxo8Bru/AbNmkZZD4OQw== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/intca.der b/testcode/testdata/tls/certificate/der/rsa_sha512/intca.der new file mode 100644 index 00000000..ff9f8083 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/intca.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/intca.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/intca.key.der new file mode 100644 index 00000000..0fddb213 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/intca.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.csr new file mode 100644 index 00000000..3a6d2684 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIChDCCAWwCAQAwPzELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzETMBEGA1UEAwwKb3RoZXJJbnRlcjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAL+Cc4ml5+RcXih+07+5YMeTegH0uV+ix7G535Dh0NUzNv4z +8zA8ZcT2UjUGG+h4khEfeOXFtTx+nI+vz2mYz8yaIICBYH2dOD2TtUYlJgUOAsf5 +0AX+3Ws9jqSeT1kR1QRcBco/p/rIpraGWYdrmw7AHkwp+EU08rDUxcVfYUNAFlAA +5j16dEZDYfWn+Fl35i44vKQxTAhpMmo46GS5UYcQg4loMjchhlAFtnpEof9YGjLi +i6Ac2/nrvy5WhrBk7PGrZduOmpkKHfJDIqJ4VX1xLuP13qCrmS7mtXld0rFEHrg9 +wCEc38LEp1MKSzLemovOkh3EL1JvMtN6S2KOnD0CAwEAAaAAMA0GCSqGSIb3DQEB +DQUAA4IBAQCm3kybFhKTssNDCffdxbAFJEw5s2drey0Vu0gR0Wc7WBLHcdRvYzXI +13kQngqALxThVFnpZzARaEGTo6egIB/66riJme6kZTXs3ejm5ThUbuqNviLaaamb +1MbQzQRSdtnv3zDDeAtvBxZ1LUSiaWh7qEZgNwPPrPkQCPp5QguEk+y3kkL2uSjZ +7QDxLombLFPQkqYkO3gM6895jXzdDcgDU7m9FI0eLpswY9jvreaXvqvOh/tFoaca +Dp1eMpcWBCM92wNRin7/qomPfacazNkBErGsQSLTPJoVeKnaEACtjUMhY/XRK+Qs +rrTtnsfUKRASVOPZMITnNw/bMWEbQAjn +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.der new file mode 100644 index 00000000..1b135644 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.key.der new file mode 100644 index 00000000..2ed820bd Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherEnd.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.csr new file mode 100644 index 00000000..f0a57a1e --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIChDCCAWwCAQAwPzELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzETMBEGA1UEAwwKb3RoZXJJbnRlcjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALH/mwat1etiPNOlHNgE7UfiHDouS14uPFnVfPmy1Ky5BHf3 +eOhIXfXibJ52l1pFFeX7TS7K4N34uwJPornFWdUBXnnSk5ncC0ze2qapJ8NeDxlO +81BJqsY4+0ImY0kgztA6GAIE+KAJzE7Og2eiingtAKcZQhlAr47tAz57m2JGqqO0 +3TEcMbvzoNx9nn5SFAh/Kyx6tCkSpZPGcPcx8JB8lJKTzLMZWO21LkRWc8cte9+G +gIw8HJ76ECq1rhOTvdgAoyu6BMf2kBTarK3/pR02YBbaiS1EnOs/b4g9SDu8+uHf +3hoxdSg7lecqTA9IK/7haUZLUMYSKEbOr5dMf98CAwEAAaAAMA0GCSqGSIb3DQEB +DQUAA4IBAQCuhsaTHJC22sP3QuLeGCa+b9Vnh/+yy3cYOVtvYIlDX4Gv1IlO3CcG +mzPOPeYHB1wvQwdbrjEXWiguWJsZR8kH4SJflYqnwzvverCmhi97RvP/mOZUwdnO +zos30aPU+tlQQ0KSonryKDb7RWYDE5J65pdSgpc+sHyz009rPCUR6UXbL+2ZPOdz +MSmMxfXO24wgVMhv0LrwNqu7d3TSuFmPpDYTH7+tOlFMMd6EfwckIwKWDQM0ybFo +7ErsKnCWh7ihsTkRJaaasah3T8JFxDtN2F4EFlPWr4gfvOnI1cSATDm5q6dQA8GG +qycHZhcYQDkdZ9+HGc7KbnyvJgdfgph2 +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.der new file mode 100644 index 00000000..bdcfb9df Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.key.der new file mode 100644 index 00000000..b062c997 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.csr new file mode 100644 index 00000000..b64a4a7c --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIChDCCAWwCAQAwPzELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzETMBEGA1UEAwwKb3RoZXJJbnRlcjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALpEW2DMMstoOvFJhe+Sy/u9HTGc9Lh9+1Im0M6DFiQnqd5h +vQ1fPD5I+hmWHFMoKeQehtTIfBmWW6RYJxexYaeRCKKVwIlmDSNwwsIX10g2c8GP +HLNl4gGfZqSj7CVkN6pJ12IwjqCWFTp+Q3ZqQ1v/MF98SNN/j7J9myrl23sqMs5e +FgQsH8OmXV3C2jWKmOExkJuZVZmQjeV8gteRf7najsCCpin+LsUgUeEKNuciEsi/ +m9lrNTZwM2fLgGuQ7ACtL0qRomghnCXNlXXiK912ZqHmB2FwX0EqtIfXkEeqqt/1 +qPDu2COBFIH3oEOit3zyL8iLEq928/W4TQfMtJcCAwEAAaAAMA0GCSqGSIb3DQEB +DQUAA4IBAQAXEhROd6wO5Gk+1U9ODoAS9StQZvMjrgluCVjI+KIdK5StVHyRRWHp +gUTxb+5FyjqW+2fenK06XuD0Erg1Be97vQmggr//JUdXM9EcxOS1TW1M2HxhYxhB +CQyK2l1DpGt6qH++zQpTimI3EX9W89NmsyiW4nqCtPQTpD8jiahHTSH2SLCki0ix +7ZftEOgxINvu9uZPzNEraZZVGmMmoetcENz/Ee261GssjJCK85IOHuo/4oNYFhK/ +6DixKB4mgzxrcBBMW4bNeyTHFPaIPSVGWw8JNNdy6Rv5ysZ1ahvjVY7Bzid9b+MO +KNiiFMAPW29k7h7rbcNA/wTuquZlgPaf +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.der new file mode 100644 index 00000000..a286c5b7 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.key.der new file mode 100644 index 00000000..56217824 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherInter2.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.csr new file mode 100644 index 00000000..5517fd39 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICgzCCAWsCAQAwPjELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzESMBAGA1UEAwwJb3RoZXJSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnkZA49cUuYdJZ+pmW7/nvHPXL2PMa/Vk81DRa3lOM+w6vNsS +dlZOu2p6qxkG5kdWA7e79Jd851MzxVAl/0nCjt3WSuVUOM3dlydH/Gwdd7BlEqI8 +8JZsndflyr7ytAbPy8kqzfIxGnZ3cmTF5SVI5D7ybAyCPDzyXwlvqnTjK/hx7Vc5 +Ajcvqb+boPzSNEsgyKS1BEa4cc2/YVehxwDmtx49haV6l3NoruwfUURMRhE8m+hS +fqOY894lwAu48KZ2ejRqUM2OoZmrQisGMn9H2aupyHrRO5TQsDCkmgN3QAzgqGbo +iPHEOHX/SWZnuUb2/lbWQSTpZU0mBqGeielHTwIDAQABoAAwDQYJKoZIhvcNAQEN +BQADggEBAFqqadPypu2BMrhOp03T6opzOeDnNZXWrzpL//4nRCJGDX2OAkSBJwDb +lswmOBvP7rjZpiVz9CjYVk3LLlIfnJ24McHnDeOX2pYSXXphlE5PLhhEan7FFXLb +IEZew2AGIWQ+XZyTgLjFswk4iZzijt3mI35UsmqWP6Oe08UPazEzJkj6kAzJoS5C +ZB5j+Sqgvv7UA9Hnv7gmSDuFOsTP4pzIehIVVXS2HHrW/UmoleOEC7plrftHOi2S +eVIVwwsdxsWLMIwG49KlPlQd/Ze1IvwoZsYhk5nDROaGKeiMzzRz40K6uK9FhO2K +YcgRUb4Xiv9+LtXK1/nIfKqUf54jM7M= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.der new file mode 100644 index 00000000..fd2ce128 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.key.der new file mode 100644 index 00000000..39fd886e Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/otherRoot.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/root.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/root.csr new file mode 100644 index 00000000..52c62b2a --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/root.csr @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDhTCCAe0CAQAwQDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA2FkczEUMBIGA1UEAwwLdGVzdF9yb290Q2EwggGiMA0GCSqGSIb3DQEBAQUA +A4IBjwAwggGKAoIBgQDBIFYRxJ3dXQApzP4BmP4DbOjoi3qh5Ua1W3FTttA8CqY5 +gtmR95RHPxe9LU1xVZgrmuyZGg3GmrQmZ0Mv+1xTDlyJEJrk8heKhUwgbhxWHiJ+ +oUvreRgoz2bqDgs81W+WWqvQHl2ghtU8qXoqkU/35HuMZWUdOKerwE18PJOdi6JU +FK6iTDWHpnangb8W36gSDus6g0r6ttlYn+u3nHi0aCtMsNA5Fc/3Xc4u60Rge4Uf +NKCPPX5REx4RyDgjSUgSpFfpQhYRpaTl0IGXNM54dFzmOnDxnAwYcrZYtuHba4Wo +BpJJDw1CEZwgrH2ZQWpxVtEztoc9LvTSNjsQEcw6WAfT3/7JWVYJ5RGw4XIUtsQJ +yFslG0VlaFwscf0HN+Q3vLY1MFFyxUXTWO9fJVVSNQeamsheKa0kpcIMft+6mPHl +C9QqGqA/z/vuKVkvnjXR1VUmJWgCiJLG0f1BKZE9A7Ty8pH8tF51lpEYu4lnzaj7 +datTsHQH/OS3oAVo55ECAwEAAaAAMA0GCSqGSIb3DQEBDQUAA4IBgQAPoUA5vy2/ +rh+/rnX1mXFiszBEmASHYk8pjZWco5XE0/iH7VLk48hIAbbcn0AVhKVROgqE3wE5 +EY+ApBE8fHjMa9nwpGroZKCagSr1Ih9g97kOPPfEhqLygnNkRG3UFFKZz7fKfL1T +baR252NhTGFHtbv66NvCopWx7JGEL7O3ZDwdoZrknFvCkvQrb9MO9kHV+9fX8UXj +MUYfsHBRH6f65xSylkPUQtUz/k8GYsv5REy0pkLzusPwpV+r1xNeqczkiRzvuhoh +cZ9A4qG7hHsKQrGFbmoEcwkFLTDRKdvgbQXQTmrHu7d9PU1FngNvgmTGx1tvb7XL +ngYNouPlkZ7FsBjK7rsEeR2QMun4KUG7pKDoHwuF7cg0EELjGSY54QLtlZ9S8D/7 +VqjHBIh2HQmC9pldFF/7HgP/jRvobRqJ7wrp9i9V6mlRto7oFANTkMmSjvtyV/OR +VaArFWccKOxGb2Po6ewkyz9mGlZY54jdzC57YfCcYFMYhHdMHsh/to0= +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/root.der b/testcode/testdata/tls/certificate/der/rsa_sha512/root.der new file mode 100644 index 00000000..36a361b2 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/root.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/root.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/root.key.der new file mode 100644 index 00000000..741e96c3 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/root.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/server.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/server.csr new file mode 100644 index 00000000..b7f22e79 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/server.csr @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDgTCCAekCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCAaIwDQYJKoZIhvcNAQEBBQADggGP +ADCCAYoCggGBAMSW5EbJJNqtB3ZmBHhyvDtXzegBoJEFz/tLq6X5XaEU2N4XzM4w +8X1CTm576rDhvuQijT76VoUN07HMXv8u7Fq2mhYTjj8icB0xN5xRD0iGXMoEzr8S +8OJBsqcZudr0YnaiM1hlJuAs4WvjWZzoil03HUD8HroJFUEjnKaPADg+R2uEBsCC +AVLEhMnX+Lh/8zCs2G4AH1L7ilXJidpBFPdMc4O95BeWmdqGgRbFgbNSqJ6MsAe8 +cMuOcV2IAODPYiJec+6NaGpmoB0K5LmWdUeAGUHQlE//1F6oYt6cungKuMyuMdv7 +uKFLvE4Hu3Z9d8kfe2R2hiksYep+Bal3wt6gWQt8pHicwLxTNXZzEzOzG3Tb7qlx +NyNe/enwNurb8GQZ9O1pvXj/s+6EWcfdS+zR+l60BLT6Wb/ygS8Xnl6YL619Hk5L +gJts4hgAdHG1POl3GbzR0ZJcpHIiVBxPaSQiLTkiEdRTBJKrhw2I1g1NhZnpCPr4 +dhJlzp7aUhrRmwIDAQABoAAwDQYJKoZIhvcNAQENBQADggGBAGo7nEnjTJK1WBcL +IcO0KEpw78ZTYlKd/ekBogn0M4S2gk/ric2DO04z/CnCWTnmC0Fh9FbC4p3Eg5fu +6ZidDYp/xhWNuoRkIVU27gNqRaOtith2golmUL2y7IiJNAsEFpmswuK6pJY9aASp +r+XHkrDNjY4ECpZrdRZJKQAA+TRbOoNZDqRX3D3drKR49S6EP2mzkrklajTbWDdO +8biCKJ0wIyIvCwm808yuNoTLN4HfAIQpOIyMGNwRMOKGFCZaJQm/6f5Yn5259tcl +lpgfvr6lsmgsitxs6RKxNqiF/+nmOpgGshQjH7qR0Z2SGCKXNCMgXllLyMIK6Rbu +2g3BYV3wUdivxfxApZBxU3OPdOi+wqYlKawxX4oA7uqEzyhSP131e+Gyx6CdMNef +KEkXOSxdU27dFyBgFlw1TnZ9Kwj1Hc6BGo6c4NFG4kdPeQFPfccDs5x141kn6/Gs +7dsW1WptLBNI3ex7ReWCwDmiPwPI5vzG/P76KyL6D8KkeOk/iA== +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/server.der b/testcode/testdata/tls/certificate/der/rsa_sha512/server.der new file mode 100644 index 00000000..00d7bc13 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/server.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/server.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/server.key.der new file mode 100644 index 00000000..a5d20366 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/server.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.csr new file mode 100644 index 00000000..9bfd1a44 --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMqGUGA/W9N9KOM+vprgr3i4baOOz+XsXMaWj8Uj57IOZXqcGmQt +JUXrKbExDvNodcg83qcd00ON077lskrUsgJfGGSyC6TfQJCBu0EMNDvDa1BIUhmW +co7ADLX159/fcJXrmso/6D0h3AIdkBkTXfuPGXqSiCP3JyLTs5dXLSrP/Nq3qrc6 +IiA9klsbFM0FoID7jk8tkyDVJcx48nW0bvHEueO9SI54g7lzCCd/8KOOMB/q+QAc +F4SHNcRnU7Nt9AYAZoK3tnBAEzhCStOUZatt734e6Twh/cHlr2+vpseSyV3nrYyy +sGXf43Sr5v3pmaBxdiymOaQwarN3rJwgkD0CAwEAAaAAMA0GCSqGSIb3DQEBDQUA +A4IBAQBZtuTGTUWbQ91tXPlxUZz7d18Ajwp5/Cm/7qL/RXxxz26a3yfriI4Yh6d8 +1rTk2kBPE0FECxY6pW+OwRisX1Gg7xKyAPXjvPrxhqrBMrBRsrYN0cet0Ygm72TJ +76dvBN6HElxmlOuJwWy/o+MWkMnmgGmFWcIOZLWMOfV3drrgI9N5WX5doLYqG8PI +lby2oALv25cjcJUMqWy5W2zZlJNay3lbI8gaH7Aqy0ES7SVcsOMS5FrUl3a1tshX +wBhFLgiZMRv2ItpMVEdwjir5viAcAfh+hST/cBW8ShiZZ31oX9SoYbTAX4FyMg94 +PtPbouuUx36z1D3K4ZfOmPmuC3Cx +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.der b/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.der new file mode 100644 index 00000000..c26ffafb Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.key.der new file mode 100644 index 00000000..5ddaaa39 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/usageKeyEncipher.key.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.csr b/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.csr new file mode 100644 index 00000000..46a4f74e --- /dev/null +++ b/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDDAKBgNV +BAsMA3ZkYzEQMA4GA1UEAwwHdmRjX2RldjCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALDOhp1axq1sqYg7I5gfaZ3OoHUT7bg1nVQRHdSuGGrX2kmGUdl9 +44ybXViSCcST60IubWjzxnRv1H76DNZAxK0Ce/53o6sVSx9m06mgV5W+PEIPA03l +pIL8u5+IeKtPWJC341kfcyUQ28vxfYO5Rz14HORGnfRIae7+60Px8tZnwRuom3/8 +fwV3yvws3K5gcvs++xHwl/glunvVD9+UHiTplZVfX/IomIrU4txi4CFW0tyfOS2l +Mg5C44HbZQgOS8J4EMGjSv2P8thQGoF4Q3SxxkjkwvMxeWNyYicGMzDYeppeohB5 +Dd6zH9yLVIRKDG12vVHJ3DsVIpmLAl82pF0CAwEAAaAAMA0GCSqGSIb3DQEBCwUA +A4IBAQAz4VsmV+qFq89IGI4IWlz9NlMSVUcE1xBf53P2laF9JKm5Lgn2/hQ74EWL +aF0VJlrJh5WUslhJSMtZyjIt6n89TP4ZR7W6YbaAtg/vWl35A8FhKYfYPGBF49v1 +18T30akYitg2RrZDlGi9n59MwgWdaDl9IfbYoiIZ15K9vqR44RJDCuOJXRHOiAxs +bYApktDuw9sudzEH505ePXro/hW7M23LZ/7dBBz0NdvwMZXbu72rt7z5tdQguVQr +RIU/WrEY9OURCoSeCURMju8BYLp4+kgTZwoXfhVs7EHDRT3dzJGcxdlVvd0TYf3A +j/3GvxSsdSvI2CmsKjt/N/j5t81U +-----END CERTIFICATE REQUEST----- diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.der b/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.der new file mode 100644 index 00000000..3f79681c Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.der differ diff --git a/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.key.der b/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.key.der new file mode 100644 index 00000000..1805ac4c Binary files /dev/null and b/testcode/testdata/tls/certificate/der/rsa_sha512/usagedigitalSign.key.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/ca.der b/testcode/testdata/tls/certificate/der/sm2/ca.der new file mode 100644 index 00000000..71cc9b20 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/ca.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/enc.der b/testcode/testdata/tls/certificate/der/sm2/enc.der new file mode 100644 index 00000000..851e8998 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/enc.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/enc.key.der b/testcode/testdata/tls/certificate/der/sm2/enc.key.der new file mode 100644 index 00000000..e0cd252d Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/enc.key.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/enc22.der b/testcode/testdata/tls/certificate/der/sm2/enc22.der new file mode 100644 index 00000000..ed2c2894 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/enc22.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/enc22.key.der b/testcode/testdata/tls/certificate/der/sm2/enc22.key.der new file mode 100644 index 00000000..2ae189aa Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/enc22.key.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/inter.der b/testcode/testdata/tls/certificate/der/sm2/inter.der new file mode 100644 index 00000000..4ca6c1be Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/inter.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/sign.der b/testcode/testdata/tls/certificate/der/sm2/sign.der new file mode 100644 index 00000000..acd677ae Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/sign.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/sign.key.der b/testcode/testdata/tls/certificate/der/sm2/sign.key.der new file mode 100644 index 00000000..d5bf78ff Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/sign.key.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/sign22.der b/testcode/testdata/tls/certificate/der/sm2/sign22.der new file mode 100644 index 00000000..f6cede41 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/sign22.der differ diff --git a/testcode/testdata/tls/certificate/der/sm2/sign22.key.der b/testcode/testdata/tls/certificate/der/sm2/sign22.key.der new file mode 100644 index 00000000..50f37758 Binary files /dev/null and b/testcode/testdata/tls/certificate/der/sm2/sign22.key.der differ diff --git a/tls/alert/include/alert.h b/tls/alert/include/alert.h new file mode 100644 index 00000000..6939dae2 --- /dev/null +++ b/tls/alert/include/alert.h @@ -0,0 +1,130 @@ +/* + * 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 ALTER_H +#define ALTER_H + +#include +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ALERT_FLAG_NO = 0, /* no alert message */ + ALERT_FLAG_RECV, /* received the alert message */ + ALERT_FLAG_SEND, /* the alert message needs to be sent */ +} ALERT_FLAG; + +/** obtain the messages about receiving and sending by Alert */ +typedef struct { + uint8_t flag; /* send and receive flags, see ALERT_FLAG */ + uint8_t level; /* Alert level. For details, see ALERT_Level. */ + uint8_t description; /* Alert description. For details, see ALERT_Description. */ + uint8_t reverse; /* reserve, 4-byte aligned */ +} ALERT_Info; + +/** + * @ingroup alert + * @brief Alert initialization function + * + * @param ctx [IN] tls Context + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_INTERNAL_EXCEPTION An unexpected internal error occurs. + * @retval HITLS_MEMALLOC_FAIL Failed to apply for memory. + */ +int32_t ALERT_Init(TLS_Ctx *ctx); + +/** + * @ingroup alert + * @brief Alert deinitialization function + * + * @param ctx [IN] tls Context + * + */ +void ALERT_Deinit(TLS_Ctx *ctx); + +/** + * @ingroup alert + * @brief Check whether there are received or sent alert messages to be processed. + * + * @attention ctx cannot be empty. + * @param ctx [IN] tls Context + * + * @retval true: The processing is required. + * @retval false: No processing is required. + */ +bool ALERT_GetFlag(const TLS_Ctx *ctx); + +/** + * @ingroup alert + * @brief Obtain the alert information. + * + * @attention ctx and info cannot be empty. Ensure that the value is used when Alert_GetFlag is true. + * @param ctx [IN] tls Context + * @param info [IN] Alert information record + */ +void ALERT_GetInfo(const TLS_Ctx *ctx, ALERT_Info *info); + +/** + * @brief Clear the alert information. + * + * @attention ctx cannot be empty. + * @param ctx [IN] tls Context + */ +void ALERT_CleanInfo(const TLS_Ctx *ctx); + +/** + * @brief Send an alert message and cache it in the alert module. + * + * @attention ctx cannot be empty. + * @param ctx [IN] tls Context + * @param level [IN] Alert level + * @param description [IN] alert Description + * + */ +void ALERT_Send(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description); + +/** + * @brief Send the alert message cached by the alert module to the network layer. + * + * @attention ctx cannot be empty. Alert_Send must be invoked before flushing. + * @param ctx [IN] tls Context + * + * @retval HITLS_SUCCESS succeeded. + * @retval See REC_Write + */ +int32_t ALERT_Flush(TLS_Ctx *ctx); + +/** + * @ingroup alert + * @brief Alert receiving interface + * + * @attention ctx cannot be empty. + * @param ctx [IN] tls Context + * @param data [IN] Alert message body + * @param len [IN] Alert message length + * + */ +void ALERT_Recv(TLS_Ctx *ctx, const uint8_t *data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* ALTER_H */ \ No newline at end of file diff --git a/tls/alert/src/alert.c b/tls/alert/src/alert.c new file mode 100644 index 00000000..6635f325 --- /dev/null +++ b/tls/alert/src/alert.c @@ -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 "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "rec.h" +#include "bsl_uio.h" +#include "hitls.h" +#include "alert.h" + +#define ALERT_DATA_LEN 2u /* alert data length */ + +/** Alert context, which records the sending and receiving information */ +struct AlertCtx { + uint8_t flag; /* send and receive flags, for details, see ALERT_FLAG */ + bool isFlush; /* whether the message is sent successfully */ + uint8_t warnCount; /* count the number of consecutive received warnings */ + uint8_t level; /* Alert level. For details, see ALERT_Level */ + uint8_t description; /* Alert description: For details, see ALERT_Description */ + uint8_t reverse; /* reserve, 4-byte aligned */ +}; + +bool ALERT_GetFlag(const TLS_Ctx *ctx) +{ + return (ctx->alertCtx->flag != ALERT_FLAG_NO); +} + +void ALERT_GetInfo(const TLS_Ctx *ctx, ALERT_Info *info) +{ + struct AlertCtx *alertCtx = ctx->alertCtx; + info->flag = alertCtx->flag; + info->level = alertCtx->level; + info->description = alertCtx->description; + return; +} + +void ALERT_CleanInfo(const TLS_Ctx *ctx) +{ + (void)memset_s(ctx->alertCtx, sizeof(struct AlertCtx), 0, sizeof(struct AlertCtx)); + return; +} + +/* check whether the operation is abnormal */ +bool AlertIsAbnormalInput(const struct AlertCtx *alertCtx, ALERT_Level level) +{ + if (level != ALERT_LEVEL_FATAL && level != ALERT_LEVEL_WARNING) { + return true; + } + if (alertCtx->flag != ALERT_FLAG_NO) { + // a critical alert exists and cannot be overwritten + if (alertCtx->level == ALERT_LEVEL_FATAL) { + return true; + } + // common alarms are not allowed to overwrite CLOSE NOTIFY + if (level == ALERT_LEVEL_WARNING && + alertCtx->level == ALERT_LEVEL_WARNING && + alertCtx->description == ALERT_CLOSE_NOTIFY) { + return true; + } + } + return false; +} + +void ALERT_Send(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + struct AlertCtx *alertCtx = ctx->alertCtx; + // prevent abnormal operations + if (AlertIsAbnormalInput(alertCtx, level)) { + return; + } + alertCtx->level = (uint8_t)level; + alertCtx->description = (uint8_t)description; + alertCtx->flag = ALERT_FLAG_SEND; + alertCtx->isFlush = false; + return; +} + +int32_t ALERT_Flush(TLS_Ctx *ctx) +{ + struct AlertCtx *alertCtx = ctx->alertCtx; + int32_t ret; + if (alertCtx->flag != ALERT_FLAG_SEND) { + BSL_ERR_PUSH_ERROR(HITLS_ALERT_NO_WANT_SEND); + return HITLS_ALERT_NO_WANT_SEND; + } + if (alertCtx->isFlush == false) { + uint8_t data[ALERT_DATA_LEN]; + /** obtain the alert level */ + data[0] = alertCtx->level; + data[1] = alertCtx->description; + /** write the record */ + ret = REC_Write(ctx, REC_TYPE_ALERT, data, ALERT_DATA_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + alertCtx->isFlush = true; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15768, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "Sent an Alert msg:level[%u] description[%u]", data[0], data[1], 0, 0); + } + /* if isFlightTransmitEnable is enabled, the stored handshake information needs to be sent */ + uint8_t isFlightTransmitEnable; + (void)HITLS_GetFlightTransmitSwitch(ctx, &isFlightTransmitEnable); + if (isFlightTransmitEnable == 1) { + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_IO_BUSY); + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15778, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "fail to send alert message in bUio.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION); + return HITLS_REC_ERR_IO_EXCEPTION; + } + } + return HITLS_SUCCESS; +} + +static uint32_t ALERT_GetVersion(const TLS_Ctx *ctx) +{ + if (ctx->negotiatedInfo.version > 0) { + /* the version has been negotiated */ + return ctx->negotiatedInfo.version; + } else { + /* if the version is not negotiated, the latest version supported by the local end is returned */ + return ctx->config.tlsConfig.maxVersion; + } +} + + +void ALERT_Recv(TLS_Ctx *ctx, const uint8_t *data, uint32_t len) +{ + struct AlertCtx *alertCtx = ctx->alertCtx; + + /** if the message lengths are not equal, an error code is returned */ + if (len != ALERT_DATA_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15769, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a alert msg with illegal len", 0, 0, 0, 0); + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return; + } + + /** record the alert message */ + if (data[0] == ALERT_LEVEL_FATAL || data[0] == ALERT_LEVEL_WARNING) { + // prevent abnormal operations + if (AlertIsAbnormalInput(alertCtx, data[0]) == true) { + return; + } + alertCtx->flag = ALERT_FLAG_RECV; + alertCtx->level = data[0]; + alertCtx->description = data[1]; + if (ALERT_GetVersion(ctx) == HITLS_VERSION_TLS13 && alertCtx->description != ALERT_CLOSE_NOTIFY) { + alertCtx->level = ALERT_LEVEL_FATAL; + } + if (alertCtx->level == ALERT_LEVEL_FATAL) { + BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15770, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "got a alert msg:level[%u] description[%u]", data[0], data[1], 0, 0); + return; + } + + BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15771, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a alert msg with illegal type", 0, 0, 0, 0); + /** Decoding error. Send an alert. */ + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return; +} + +int32_t ALERT_Init(TLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15772, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ctx is null.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + // prevent multi init of ctx->alertCtx + if (ctx->alertCtx != NULL) { + return HITLS_SUCCESS; + } + ctx->alertCtx = (struct AlertCtx *)BSL_SAL_Malloc(sizeof(struct AlertCtx)); + if (ctx->alertCtx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15773, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc alert ctx fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + (void)memset_s(ctx->alertCtx, sizeof(struct AlertCtx), 0, sizeof(struct AlertCtx)); + return HITLS_SUCCESS; +} + +void ALERT_Deinit(TLS_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_FREE(ctx->alertCtx); + return; +} \ No newline at end of file diff --git a/tls/app/include/app.h b/tls/app/include/app.h new file mode 100644 index 00000000..71be5e4f --- /dev/null +++ b/tls/app/include/app.h @@ -0,0 +1,116 @@ +/* + * 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 APP_H +#define APP_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup app + * @brief Initialize the app module. + * + * @param ctx [IN] TLS context + * @retval HITLS_SUCCESS Initializition successful. + * @retval HITLS_MEMALLOC_FAIL Failed to apply for memory. + */ +int32_t APP_Init(TLS_Ctx *ctx); + +/** + * @ingroup app + * @brief Deinitialize the app module. + * @param ctx [IN] TLS context + */ +void APP_DeInit(TLS_Ctx *ctx); + +/** + * @ingroup app + * @brief TLS can read data of any length, rather than in the unit of record. DTLS can read data in the unit of record. + * Reads num number of bytes from the CTX to the buffer. Support input of any num bytes (num must be greater than 0). + * + * @attention Reads only the application data decrypted by one record at a time. + * HITLS copies the application data to the input cache. + * If the cache size is less than 16K, the maximum size of the application message decrypted from a single record is 16K + * This will result in a partial copy of the application data. + * You can call APP_GetReadPendingBytes to obtain the size of the remaining readable application data in current record. + * This is useful in DTLS scenarios. + * + * @param ctx [IN] TLS context + * @param buf [OUT] Place the data which read from the TLS context into the buffer. + * @param num [IN] Attempting to read num bytes + * @param readLen [OUT] Read length + * + * @retval HITLS_SUCCESS Read successful. + * @retval Other return value refers to REC_Read. + */ +int32_t APP_Read(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen); + +/** + * @ingroup app + * @brief Obtain the maximum writable plaintext length of a single record. + * + * @param ctx [IN] TLS_Ctx context + * @param len [OUT] Maximum length of the plaintext + * + * @retval HITLS_SUCCESS Obtain successful. + * @retval Other return value refers to REC_GetMaxWriteSize. + */ +int32_t APP_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len); + +/** + * @ingroup app + * @brief Send app message in the unit of record. + * + * @param ctx [IN] TLS context + * @param data [IN] Data to be written + * @param dataLen [IN] Data length + * + * @retval HITLS_SUCCESS Write successful. + * @retval HITLS_APP_ERR_TOO_LONG_TO_WRITE The data to be written is too long. + * @retval Other reuturn value referst to REC_Write. + */ +int32_t APP_Write(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen); + +/** + * @ingroup app + * @brief Processing of unexpected APP messages. + * When receiving an APP message in the handshake, call this function to process the message. + * + * @param ctx [IN] TLS context + * @param data [IN] Message body + * @param len [IN] Message length + * + */ +void APP_RecvUnexpectedMsgProcess(TLS_Ctx *ctx, const uint8_t *data, uint32_t len); + +/** + * @ingroup app + * @brief Obtain the length of the remaining readable app messages in the current record. + * + * @param ctx [IN] TLS object + * @retval Length of the remaining readable app message + */ +uint32_t APP_GetReadPendingBytes(const TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/app/src/app.c b/tls/app/src/app.c new file mode 100644 index 00000000..153911c2 --- /dev/null +++ b/tls/app/src/app.c @@ -0,0 +1,343 @@ +/* + * 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 "securec.h" +#include "bsl_sal.h" +#include "bsl_list.h" +#include "tls_binlog_id.h" +#include "bsl_uio.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "rec.h" +#include "app_ctx.h" +#include "rec.h" +#include "app.h" + +static AppBuf *NewAppBufNode(const uint8_t *data, uint32_t len) +{ + AppBuf *appBufNode = (AppBuf *)BSL_SAL_Malloc(sizeof(AppBuf)); + if (appBufNode == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15945, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: appBufNode malloc fail when NewAppBufNode.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + + appBufNode->buf = (uint8_t *)BSL_SAL_Dump(data, len); + if (appBufNode->buf == NULL) { + BSL_SAL_FREE(appBufNode); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15946, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: appBufNode->buf malloc fail when NewAppBufNode.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + + appBufNode->bufSize = len; + appBufNode->start = 0; + appBufNode->end = len; + + return appBufNode; +} + +void FreeAppBufNode(AppBuf *appBufNode) +{ + if (appBufNode != NULL) { + BSL_SAL_FREE(appBufNode->buf); + BSL_SAL_FREE(appBufNode); + } + return; +} + +int32_t APP_Init(TLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15445, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ctx is null.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + // Prevent multiple init of ctx->appCtx + if (ctx->appCtx != NULL) { + return HITLS_SUCCESS; + } + APP_Ctx *appCtx = (APP_Ctx *)BSL_SAL_Calloc(1U, sizeof(APP_Ctx)); + uint32_t bufSize = 0; + if (appCtx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15655, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: malloc fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + bufSize = REC_MAX_TLS13_ENCRYPTED_LEN; + + appCtx->appReadBuf.buf = (uint8_t *)BSL_SAL_Malloc(bufSize); + if (appCtx->appReadBuf.buf == NULL) { + BSL_SAL_FREE(appCtx); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15656, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: malloc fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + appCtx->appReadBuf.bufSize = bufSize; + appCtx->appReadBuf.start = 0; + appCtx->appReadBuf.end = 0; + + appCtx->appList = BSL_LIST_New(sizeof(AppBuf)); + if (appCtx->appList == NULL) { + BSL_SAL_FREE(appCtx->appReadBuf.buf); + BSL_SAL_FREE(appCtx); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15947, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: appList malloc fail when APP_Init.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + APP_DeInit(ctx); + ctx->appCtx = appCtx; + return HITLS_SUCCESS; +} + +static void AppBufNodeDestroy(void *data) +{ + FreeAppBufNode((AppBuf *)data); + return; +} + +void APP_DeInit(TLS_Ctx *ctx) +{ + if (ctx->appCtx != NULL) { + BSL_SAL_FREE(ctx->appCtx->appReadBuf.buf); + BSL_LIST_FREE(ctx->appCtx->appList, AppBufNodeDestroy); + BSL_SAL_FREE(ctx->appCtx); + } + + return; +} + +// when the revAppdata->end - revAppdata->start > 0, which means there is data in the cache, copy data from revAppdata +static int32_t AppBufRead(AppBuf *revAppdata, uint8_t *buf, uint32_t num, uint32_t *readLen) +{ + uint32_t dataSize = revAppdata->end - revAppdata->start; + uint32_t copyLen = (dataSize > num) ? num : dataSize; + + if (memcpy_s(buf, num, &revAppdata->buf[revAppdata->start], copyLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15657, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: memcpy fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + revAppdata->start += copyLen; + *readLen = copyLen; + return HITLS_SUCCESS; +} + +static uint32_t GetAppListBufSize(const TLS_Ctx *ctx) +{ + uint32_t totalSize = 0; + AppList *tmpList = ctx->appCtx->appList; + AppBuf *appBufNode = (AppBuf *)BSL_LIST_GET_FIRST(tmpList); + while (appBufNode != NULL) { + totalSize += appBufNode->end - appBufNode->start; + appBufNode = (AppBuf *)BSL_LIST_GET_NEXT(tmpList); + } + return totalSize; +} + +static int32_t AppListBufRead(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen) +{ + AppList *tmpList = ctx->appCtx->appList; + AppBuf *appBufNode = NULL; + appBufNode = (AppBuf *)BSL_LIST_GET_FIRST(tmpList); + if (appBufNode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint32_t dataSize = appBufNode->end - appBufNode->start; + uint32_t copyLen = (dataSize > num) ? num : dataSize; + + if (memcpy_s(buf, num, &appBufNode->buf[appBufNode->start], copyLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15948, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: memcpy fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + appBufNode->start += copyLen; + + if (appBufNode->start == appBufNode->end) { + BSL_LIST_DeleteCurrent(tmpList, AppBufNodeDestroy); + } + + *readLen = copyLen; + return HITLS_SUCCESS; +} + +static int32_t AppReadData(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen) +{ + int32_t ret; + uint32_t readbytes = 0; + AppBuf *revAppdata = NULL; + + if (ctx->appCtx == NULL || ctx->appCtx->appReadBuf.buf == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15658, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: error null pointer.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + revAppdata = &ctx->appCtx->appReadBuf; + + /* Check whether there is data in the cache. */ + if (revAppdata->end > revAppdata->start) { + return AppBufRead(revAppdata, buf, num, readLen); + } + + /* Check whether there is data in the cache of unexpected messages. */ + if (BSL_LIST_COUNT(ctx->appCtx->appList) > 0) { + return AppListBufRead(ctx, buf, num, readLen); + } + + /* If there is no data in the cache and the size of the user buffer is greater than the maximum size of the record, + the app read cache is not used. */ + if (num >= REC_MAX_TLS13_ENCRYPTED_LEN) { + return REC_Read(ctx, REC_TYPE_APP, buf, readLen, num); + } + // read data from the uio of the CTX to revAppdata + ret = REC_Read(ctx, REC_TYPE_APP, revAppdata->buf, &readbytes, revAppdata->bufSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + revAppdata->start = 0; + revAppdata->end = readbytes; + + if (revAppdata->end > revAppdata->start) { + return AppBufRead(revAppdata, buf, num, readLen); + } + + /* read an app record with 0 byte */ + *readLen = 0; + return HITLS_SUCCESS; +} + +int32_t APP_Read(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen) +{ + int32_t ret; + uint32_t readbytes; + + if (ctx == NULL || buf == NULL || num == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15659, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP: input null pointer or read bufLen is 0.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_APP_ERR_ZERO_READ_BUF_LEN); + return HITLS_APP_ERR_ZERO_READ_BUF_LEN; + } + // read data to the buffer in non-blocking mode + do { + ret = AppReadData(ctx, buf, num, &readbytes); + if (ret != HITLS_SUCCESS) { + return ret; + } + } while (readbytes == 0); // do not exit the loop until data is read + + *readLen = readbytes; + return HITLS_SUCCESS; +} + +int32_t APP_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len) +{ + return REC_GetMaxWriteSize(ctx, len); +} + +int32_t APP_Write(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + uint32_t maxWriteLen = 0u; + int32_t ret = REC_GetMaxWriteSize(ctx, &maxWriteLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15660, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP:Get record max write size fail.", 0, 0, 0, 0); + return ret; + } + if (dataLen > maxWriteLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15661, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "APP:write length is too big: max length-%u.", maxWriteLen, 0, 0, 0); + return HITLS_APP_ERR_TOO_LONG_TO_WRITE; + } + + ret = REC_Write(ctx, REC_TYPE_APP, data, dataLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->config.tlsConfig.isFlightTransmitEnable) { + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15888, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "fail to send handshake message in bUio.", 0, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + } + return HITLS_SUCCESS; +} + +void APP_RecvUnexpectedMsgProcess(TLS_Ctx *ctx, const uint8_t *data, uint32_t len) +{ + /* if the message length is 0, a message is returned */ + if (len == 0u) { + return; + } + + /* if the buffer is full, discard the newly received messages */ + APP_Ctx *appCtx = ctx->appCtx; + if (BSL_LIST_COUNT(appCtx->appList) >= UNPROCESSED_APP_MSG_COUNT_MAX) { + return; + } + + /* cache received unexpected app messages */ + AppBuf *appBufNode = NewAppBufNode(data, len); + if (appBufNode == NULL) { + return; + } + + /* insert the message to the end of the linked list */ + if (BSL_LIST_AddElement(appCtx->appList, appBufNode, BSL_LIST_POS_END) != BSL_SUCCESS) { + FreeAppBufNode(appBufNode); + return; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15949, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "APP: recv unexpected app msg.", 0, 0, 0, 0); + return; +} + +uint32_t APP_GetReadPendingBytes(const TLS_Ctx *ctx) +{ + if ((ctx == NULL) || (ctx->appCtx == NULL)) { + return 0; + } + + AppBuf *revAppdata = &ctx->appCtx->appReadBuf; + uint32_t totalSize = revAppdata->end - revAppdata->start; + totalSize += GetAppListBufSize(ctx); /* the cache size must be added to the cache of unexpected messages */ + + return totalSize; +} diff --git a/tls/app/src/app_ctx.h b/tls/app/src/app_ctx.h new file mode 100644 index 00000000..b4fb021b --- /dev/null +++ b/tls/app/src/app_ctx.h @@ -0,0 +1,49 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef APP_CTX_H +#define APP_CTX_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup hitls_cert_type + * @brief Describe the APP cache linked list. + */ +typedef struct BslList AppList; + +typedef struct { + uint8_t *buf; /* buffer */ + uint32_t bufSize; /* size of the buffer */ + uint32_t start; /* start position */ + uint32_t end; /* end position */ +} AppBuf; + +/** + * AppDataCtx struct, used to transfer app data information + */ +struct AppDataCtx { + AppBuf appReadBuf; /* buffer received by the app */ + AppList *appList; /* cache unexpected app messages */ +}; + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/tls/ccs/include/change_cipher_spec.h b/tls/ccs/include/change_cipher_spec.h new file mode 100644 index 00000000..65ecd6ae --- /dev/null +++ b/tls/ccs/include/change_cipher_spec.h @@ -0,0 +1,97 @@ +/* + * 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 CHANGE_CIPHER_SPEC_H +#define CHANGE_CIPHER_SPEC_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup change cipher spec + * @brief CCS initialization function + * + * @param ctx [IN] SSL context + * + * @retval HITLS_SUCCESS Initializition successful. + * @retval HITLS_INTERNAL_EXCEPTION An unexpected internal error occurs. + * @retval HITLS_MEMALLOC_FAIL Failed to apply for memory. + */ +int32_t CCS_Init(TLS_Ctx *ctx); + +/** + * @ingroup change cipher spec + * @brief CCS deinitialization function + * + * @param ctx [IN] ssl context + * + */ +void CCS_DeInit(TLS_Ctx *ctx); + +/** + * @ingroup change cipher spec + * @brief Check whether the Change cipher spec message is received. + * + * @param ctx [IN] TLS context + * + * @retval True if the Change cipher spec message is received else false. + */ +bool CCS_IsRecv(const TLS_Ctx *ctx); + +/** + * @ingroup change cipher spec + * @brief CCS packet received + * + * @param ctx [IN] TLS context + * @param buf [IN] CCS message body + * @param len [IN] CCS message length + * + */ +void CCS_Recv(TLS_Ctx *ctx, const uint8_t *buf, uint32_t len); + +/** + * @ingroup change cipher spec + * @brief Send a packet for changing the cipher suite. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS Send successful. + * @retval HITLS_INTERNAL_EXCEPTION An unexpected internal error occurs. + * @retval For other error codes, see REC_Write. + */ +int32_t CCS_Send(TLS_Ctx *ctx); + +/** + * @ingroup change cipher spec + * @brief Control function + * + * @param ctx [IN] TLS context + * @param cmd [IN] Control command + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_INTERNAL_EXCEPTION An unexpected internal error + * @retval HITLS_CCS_INVALID_CMD Invalid instruction + */ +int32_t CCS_Ctrl(TLS_Ctx *ctx, CCS_Cmd cmd); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/ccs/src/change_cipher_spec.c b/tls/ccs/src/change_cipher_spec.c new file mode 100644 index 00000000..23ae1833 --- /dev/null +++ b/tls/ccs/src/change_cipher_spec.c @@ -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 "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "uio_base.h" +#include "rec.h" +#include "indicator.h" +#include "hs.h" +#include "change_cipher_spec.h" + +struct CcsCtx { + bool isReady; /* Whether to allow receiving CCS */ + bool ccsRecvflag; /* Indicates whether the CCS is received. */ + bool isAllowActiveCipher; /* Flag for allow activating the receiving key suite */ + bool activeCipherFlag; /* Flag for activating the receiving key suite */ +}; + +bool CCS_IsRecv(const TLS_Ctx *ctx) +{ + return ctx->ccsCtx->ccsRecvflag; +} + +void CCS_Recv(TLS_Ctx *ctx, const uint8_t *buf, uint32_t len) +{ + if (ctx->ccsCtx->isReady == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15612, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Error: recv a unexpected change cipher spec message.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return; + } + + /** The read length is abnormal. */ + if (len != 1u) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15613, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "the change cipher spec message length incorrect", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return; + } + + /** Message exception. */ + if (buf[0] != 1u) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15614, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "the change cipher spec message incorrect", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return; + } + + if (ctx->ccsCtx->ccsRecvflag == true && HS_GetVersion(ctx) != HITLS_VERSION_TLS13) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return; + } + + if (ctx->ccsCtx->isAllowActiveCipher == true && ctx->ccsCtx->activeCipherFlag == false) { + /** Enable key specification */ + if (REC_ActivePendingState(ctx, false) != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return; + } + ctx->ccsCtx->activeCipherFlag = true; + } + ctx->ccsCtx->ccsRecvflag = true; + + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_CHANGE_CIPHER_SPEC, buf, 1, + ctx, ctx->config.tlsConfig.msgArg); + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15615, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "got a change cipher spec message.", 0, 0, 0, 0); + ctx->negotiatedInfo.isEncryptThenMacRead = ctx->negotiatedInfo.isEncryptThenMac; + return; +} + +int32_t CCS_Send(TLS_Ctx *ctx) +{ + int32_t ret; + const uint8_t buf[1] = {1u}; + const uint32_t len = 1u; + if (ctx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15616, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ctx is null.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + +#ifndef HITLS_NO_DTLS12 + /* rfc6083 4.7. Handshake + Before sending a ChangeCipherSpec message, all outstanding SCTP user + messages MUST have been acknowledged by the SCTP peer and MUST NOT be + revoked by the SCTP peer. */ + if ((BSL_UIO_GetTransportType(ctx->uio) == BSL_UIO_SCTP) && + (ctx->negotiatedInfo.isRenegotiation == true)) { + bool isBuffEmpty = false; + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_SND_BUFF_IS_EMPTY, (int32_t)sizeof(isBuffEmpty), &isBuffEmpty); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_UIO_FAIL); + return HITLS_UIO_FAIL; + } + /* When the SCTP sending buffer is not empty, the CCS cannot be sent. */ + if (isBuffEmpty != true) { + BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_IO_BUSY); + return HITLS_REC_NORMAL_IO_BUSY; + } + } +#endif + + /** Write record */ + ret = REC_Write(ctx, REC_TYPE_CHANGE_CIPHER_SPEC, buf, len); + if (ret != HITLS_SUCCESS) { + return ret; + } + + INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_CHANGE_CIPHER_SPEC, buf, 1, + ctx, ctx->config.tlsConfig.msgArg); + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15617, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "written a change cipher spec message.", 0, 0, 0, 0); + return HITLS_SUCCESS; +} + +int32_t CCS_Ctrl(TLS_Ctx *ctx, CCS_Cmd cmd) +{ + if (ctx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15618, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ctx is null.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + switch (cmd) { + case CCS_CMD_RECV_READY: + ctx->ccsCtx->isReady = true; + break; + case CCS_CMD_RECV_EXIT_READY: + ctx->ccsCtx->isReady = false; + ctx->ccsCtx->ccsRecvflag = false; + ctx->ccsCtx->isAllowActiveCipher = false; + ctx->ccsCtx->activeCipherFlag = false; + break; + case CCS_CMD_RECV_ACTIVE_CIPHER_SPEC: + ctx->ccsCtx->isAllowActiveCipher = true; + if (ctx->ccsCtx->ccsRecvflag == true && ctx->ccsCtx->activeCipherFlag == false) { + /** Enable key specification */ + int32_t ret = REC_ActivePendingState(ctx, false); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + ctx->ccsCtx->activeCipherFlag = true; + } + break; + default: + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15619, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ChangeCipherSpec error ctrl cmd", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CCS_INVALID_CMD); + return HITLS_CCS_INVALID_CMD; + } + return HITLS_SUCCESS; +} + +int32_t CCS_Init(TLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15620, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ctx is null.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + // Prevent the ctx->ccsCtx from being initialized multiple times. + if (ctx->ccsCtx != NULL) { + return HITLS_SUCCESS; + } + ctx->ccsCtx = (struct CcsCtx *)BSL_SAL_Malloc(sizeof(struct CcsCtx)); + if (ctx->ccsCtx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15621, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ccs ctx malloc failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + (void)memset_s(ctx->ccsCtx, sizeof(struct CcsCtx), 0, sizeof(struct CcsCtx)); + return HITLS_SUCCESS; +} + +void CCS_DeInit(TLS_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + BSL_SAL_FREE(ctx->ccsCtx); + return; +} diff --git a/tls/cert/cert_adapt/cert.c b/tls/cert/cert_adapt/cert.c new file mode 100644 index 00000000..5be9f519 --- /dev/null +++ b/tls/cert/cert_adapt/cert.c @@ -0,0 +1,1132 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "bsl_bytes.h" +#include "bsl_list.h" +#include "bsl_user_data.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_security.h" +#include "tls.h" +#include "security.h" +#include "cert_mgr_ctx.h" +#include "cert_method.h" +#include "cert_mgr.h" +#include "cert.h" + +static volatile int g_hitlsX509StoreCtxIdx = -1; + +static int32_t CheckKeySecbits(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, HITLS_CERT_Key *key) +{ + int32_t ret; + int32_t secBits = 0; + HITLS_Config *config = &ctx->config.tlsConfig; + + /* Certificate key security check */ + ret = SAL_CERT_KeyCtrl(config, key, CERT_KEY_CTRL_GET_SECBITS, NULL, (void *)&secBits); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_EE_KEY, secBits, 0, cert); + if (ret != SECURITY_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_EE_KEY_WITH_INSECURE_SECBITS); + ctx->method.sendAlert((TLS_Ctx *)ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + return HITLS_CERT_ERR_EE_KEY_WITH_INSECURE_SECBITS; + } + + return HITLS_SUCCESS; +} + +CERT_Type CertKeyType2CertType(HITLS_CERT_KeyType keyType) +{ + switch (keyType) { + case TLS_CERT_KEY_TYPE_RSA: + case TLS_CERT_KEY_TYPE_RSA_PSS: + return CERT_TYPE_RSA_SIGN; + case TLS_CERT_KEY_TYPE_DSA: + return CERT_TYPE_DSS_SIGN; + case TLS_CERT_KEY_TYPE_ECDSA: + case TLS_CERT_KEY_TYPE_ED25519: + return CERT_TYPE_ECDSA_SIGN; +#ifndef HITLS_NO_TLCP11 + case TLS_CERT_KEY_TYPE_SM2: + return CERT_TYPE_SM2_SIGN; +#endif + default: + break; + } + return CERT_TYPE_UNKNOWN; +} + +HITLS_CERT_KeyType SignScheme2CertKeyType(HITLS_SignHashAlgo signScheme) +{ + switch (signScheme) { + case CERT_SIG_SCHEME_RSA_PKCS1_SHA1: + case CERT_SIG_SCHEME_RSA_PKCS1_SHA224: + case CERT_SIG_SCHEME_RSA_PKCS1_SHA256: + case CERT_SIG_SCHEME_RSA_PKCS1_SHA384: + case CERT_SIG_SCHEME_RSA_PKCS1_SHA512: + case CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256: + case CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384: + case CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512: + return TLS_CERT_KEY_TYPE_RSA; + case CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256: + case CERT_SIG_SCHEME_RSA_PSS_PSS_SHA384: + case CERT_SIG_SCHEME_RSA_PSS_PSS_SHA512: + return TLS_CERT_KEY_TYPE_RSA_PSS; + case CERT_SIG_SCHEME_DSA_SHA1: + case CERT_SIG_SCHEME_DSA_SHA224: + case CERT_SIG_SCHEME_DSA_SHA256: + case CERT_SIG_SCHEME_DSA_SHA384: + case CERT_SIG_SCHEME_DSA_SHA512: + return TLS_CERT_KEY_TYPE_DSA; + case CERT_SIG_SCHEME_ECDSA_SHA1: + case CERT_SIG_SCHEME_ECDSA_SHA224: + case CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256: + case CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384: + case CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512: + return TLS_CERT_KEY_TYPE_ECDSA; + case CERT_SIG_SCHEME_ED25519: + return TLS_CERT_KEY_TYPE_ED25519; +#ifndef HITLS_NO_TLCP11 + case CERT_SIG_SCHEME_SM2_SM3: + return TLS_CERT_KEY_TYPE_SM2; +#endif + default: + break; + } + return TLS_CERT_KEY_TYPE_UNKNOWN; +} + +HITLS_SignHashAlgo SAL_CERT_GetDefaultSignHashAlgo(HITLS_CERT_KeyType keyType) +{ + switch (keyType) { + case TLS_CERT_KEY_TYPE_RSA: + return CERT_SIG_SCHEME_RSA_PKCS1_SHA1; + case TLS_CERT_KEY_TYPE_RSA_PSS: + return CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256; + case TLS_CERT_KEY_TYPE_DSA: + return CERT_SIG_SCHEME_DSA_SHA1; + case TLS_CERT_KEY_TYPE_ECDSA: + return CERT_SIG_SCHEME_ECDSA_SHA1; + case TLS_CERT_KEY_TYPE_ED25519: + return CERT_SIG_SCHEME_ED25519; +#ifndef HITLS_NO_TLCP11 + case TLS_CERT_KEY_TYPE_SM2: + return CERT_SIG_SCHEME_SM2_SM3; +#endif + default: + break; + } + return CERT_SIG_SCHEME_UNKNOWN; +} + +int32_t CheckCertType(CERT_Type expectCertType, HITLS_CERT_KeyType checkedKeyType) +{ + if (expectCertType == CERT_TYPE_UNKNOWN) { + /* The certificate type is not specified. This check is not required. */ + return HITLS_SUCCESS; + } + /* Convert the key type to the certificate type. */ + CERT_Type checkedCertType = CertKeyType2CertType(checkedKeyType); + if (expectCertType != checkedCertType) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_CERT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15034, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect cert: expect cert type = %u, checked key type = %u.", expectCertType, checkedKeyType, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CERT; + } + + return HITLS_SUCCESS; +} + +static bool IsSignSchemeExist(const uint16_t *signSchemeList, uint32_t signSchemeNum, HITLS_SignHashAlgo signScheme) +{ + for (uint32_t i = 0; i < signSchemeNum; i++) { + if (signSchemeList[i] == signScheme) { + return true; + } + } + return false; +} + +static int32_t CheckSignSchemeServerPrefer(TLS_Ctx *ctx, const uint16_t *signSchemeList, uint32_t signSchemeNum, + HITLS_CERT_KeyType checkedKeyType, bool isNegotiateSignAlgo) +{ + for (uint32_t i = 0; i < ctx->config.tlsConfig.signAlgorithmsSize; i++) { + if (checkedKeyType != SignScheme2CertKeyType(ctx->config.tlsConfig.signAlgorithms[i])) { + /* The signature algorithm cannot be used for the certificate. Check the next signature algorithm. */ + continue; + } + if (!IsSignSchemeExist(signSchemeList, signSchemeNum, ctx->config.tlsConfig.signAlgorithms[i])) { + /* The signature algorithm must be the same as the algorithm configured on the peer end. */ + continue; + } + if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, ctx->config.tlsConfig.signAlgorithms[i], + NULL) != SECURITY_SUCCESS) { + continue; + } + if (!isNegotiateSignAlgo) { + /* Only the signature algorithm in the certificate is checked. + The signature algorithm in the handshake message is not negotiated. */ + return HITLS_SUCCESS; + } + const uint32_t rsaPkcsv15Mask = 0x01; + const uint32_t sha1Mask = 0x0200; + const uint32_t sha224Mask = 0x0300; + /* rfc8446 4.2.3. Signature Algorithms */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + if (((ctx->config.tlsConfig.signAlgorithms[i] & 0xff) == rsaPkcsv15Mask) || + ((ctx->config.tlsConfig.signAlgorithms[i] & 0xff00) == sha1Mask) || + ((ctx->config.tlsConfig.signAlgorithms[i] & 0xff00) == sha224Mask)) { + /* not defined for use in signed TLS handshake messages in TLS1.3 */ + continue; + } + } + /* Save the negotiated signature algorithm. */ + ctx->negotiatedInfo.signScheme = ctx->config.tlsConfig.signAlgorithms[i]; + return HITLS_SUCCESS; + } + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15025, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect cert: no available signature scheme, key type = %u.", checkedKeyType, 0, 0, 0); + return HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH; +} + +static int32_t CheckSignSchemeClientPrefer(TLS_Ctx *ctx, const uint16_t *signSchemeList, uint32_t signSchemeNum, + HITLS_CERT_KeyType checkedKeyType, bool isNegotiateSignAlgo) +{ + for (uint32_t i = 0; i < signSchemeNum; i++) { + if (checkedKeyType != SignScheme2CertKeyType(signSchemeList[i])) { + /* The signature algorithm cannot be used for the certificate. Check the next signature algorithm. */ + continue; + } + if (!IsSignSchemeExist(ctx->config.tlsConfig.signAlgorithms, + ctx->config.tlsConfig.signAlgorithmsSize, signSchemeList[i])) { + /* The signature algorithm must be the same in the local configuration. */ + continue; + } + if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signSchemeList[i], NULL) != SECURITY_SUCCESS) { + continue; + } + if (!isNegotiateSignAlgo) { + /* Only the signature algorithm in the certificate is checked. + The signature algorithm in the handshake message is not negotiated. */ + return HITLS_SUCCESS; + } + const uint32_t rsaPkcsv15Mask = 0x01; + const uint32_t sha1Mask = 0x0200; + const uint32_t sha224Mask = 0x0300; + /* rfc8446 4.2.3. Signature Algorithms */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + if (((signSchemeList[i] & 0xff) == rsaPkcsv15Mask) || + ((signSchemeList[i] & 0xff00) == sha1Mask) || + ((signSchemeList[i] & 0xff00) == sha224Mask)) { + /* not defined for use in signed TLS handshake messages in TLS1.3 */ + continue; + } + } + /* Save the negotiated signature algorithm. */ + ctx->negotiatedInfo.signScheme = signSchemeList[i]; + return HITLS_SUCCESS; + } + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15035, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect cert: no available signature scheme, key type = %u.", checkedKeyType, 0, 0, 0); + return HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH; +} + +int32_t CheckSignScheme(TLS_Ctx *ctx, const uint16_t *signSchemeList, uint32_t signSchemeNum, + HITLS_CERT_KeyType checkedKeyType, bool isNegotiateSignAlgo) +{ + if (signSchemeList == NULL) { + if (!isNegotiateSignAlgo) { + /* Do not save the signature algorithm used for sending handshake messages. */ + return HITLS_SUCCESS; + } + /* No signature algorithm is specified. + The default signature algorithm is used when handshake messages are sent. */ + HITLS_SignHashAlgo signScheme = SAL_CERT_GetDefaultSignHashAlgo(checkedKeyType); + if (signScheme == CERT_SIG_SCHEME_UNKNOWN || + SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signScheme, NULL) != SECURITY_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15026, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect key type: no available signature scheme, key type = %u.", checkedKeyType, 0, 0, 0); + return HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH; + } + ctx->negotiatedInfo.signScheme = signScheme; + return HITLS_SUCCESS; + } + + if (ctx->config.tlsConfig.isSupportServerPreference) { + return CheckSignSchemeServerPrefer(ctx, signSchemeList, signSchemeNum, + checkedKeyType, isNegotiateSignAlgo); + } else { + return CheckSignSchemeClientPrefer(ctx, signSchemeList, signSchemeNum, + checkedKeyType, isNegotiateSignAlgo); + } +} + + +static int32_t TLS13EcdsaCheckSignScheme(TLS_Ctx *ctx, const uint16_t *signSchemeList, uint32_t signSchemeNum, + HITLS_CERT_Key *pubkey, bool isNegotiateSignAlgo) +{ + HITLS_Config *config = &ctx->config.tlsConfig; + HITLS_NamedGroup keyCureName = HITLS_NAMED_GROUP_BUTT; + // Obtains the elliptic curve type of the certificate. + int32_t ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_CURVE_NAME, NULL, (void *)&keyCureName); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15027, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get ec pubkey curve name failed when verify sign data.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return false; + } + + // Cyclically traverse the supported signature algorithms, obtain the elliptic curve based on the signature + // algorithm, find the one that matches keyCureName, and set it to the negotiated signature algorithm. + for (uint32_t i = 0; i < signSchemeNum; i++) { + HITLS_NamedGroup signCureName = CFG_GetEcdsaCurveNameBySchemes(signSchemeList[i]); + if (signCureName == HITLS_NAMED_GROUP_BUTT || keyCureName != signCureName || + keyCureName == HITLS_NAMED_GROUP_BUTT) { + continue; + } + + if (!IsSignSchemeExist(ctx->config.tlsConfig.signAlgorithms, + ctx->config.tlsConfig.signAlgorithmsSize, signSchemeList[i])) { + /* The signature algorithm must be the same in the local configuration. */ + continue; + } + if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signSchemeList[i], NULL) != SECURITY_SUCCESS) { + continue; + } + if (!isNegotiateSignAlgo) { + /* Only the signature algorithm in the certificate is checked. + The signature algorithm in the handshake message is not negotiated. */ + return HITLS_SUCCESS; + } + const uint32_t rsaPkcsv15Mask = 0x01; + const uint32_t sha1Mask = 0x0200; + const uint32_t sha224Mask = 0x0300; + /* rfc8446 4.2.3. Signature Algorithms */ + if (((signSchemeList[i] & 0xff) == rsaPkcsv15Mask) || + ((signSchemeList[i] & 0xff00) == sha1Mask) || + ((signSchemeList[i] & 0xff00) == sha224Mask)) { + /* not defined for use in signed TLS handshake messages in TLS1.3 */ + continue; + } + /* Save the negotiated signature algorithm. */ + ctx->negotiatedInfo.signScheme = signSchemeList[i]; + return HITLS_SUCCESS; + } + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15028, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect cert: no available signature scheme, keyCureName = %u.", keyCureName, 0, 0, 0); + return HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH; +} + +int32_t CheckCurveName(HITLS_Config *config, const uint16_t *curveList, uint32_t curveNum, HITLS_CERT_Key *pubkey) +{ + uint32_t curveName = HITLS_NAMED_GROUP_BUTT; + int32_t ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_CURVE_NAME, NULL, (void *)&curveName); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15036, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "internal error: unable to get curve name.", 0, 0, 0, 0); + return ret; + } + for (uint32_t i = 0; i < curveNum; i++) { + if (curveName == curveList[i]) { + return HITLS_SUCCESS; + } + } + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_NO_CURVE_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15037, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect cert: no curve match, which used %u.", curveName, 0, 0, 0); + return HITLS_CERT_ERR_NO_CURVE_MATCH; +} + +int32_t CheckPointFormat(HITLS_Config *config, const uint8_t *ecPointFormatList, uint32_t listSize, + HITLS_CERT_Key *pubkey) +{ + uint32_t ecPointFormat = HITLS_POINT_FORMAT_BUTT; + int32_t ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_POINT_FORMAT, NULL, (void *)&ecPointFormat); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15038, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "internal error: unable to get point format.", 0, 0, 0, 0); + return ret; + } + for (uint32_t i = 0; i < listSize; i++) { + if (ecPointFormat == ecPointFormatList[i]) { + return HITLS_SUCCESS; + } + } + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_NO_POINT_FORMAT_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15039, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unexpect cert: no point format match, which used %u.", ecPointFormat, 0, 0, 0); + return HITLS_CERT_ERR_NO_POINT_FORMAT_MATCH; +} + +int32_t IsEcParamCompatible(HITLS_Config *config, const CERT_ExpectInfo *info, HITLS_CERT_Key *pubkey) +{ + int32_t ret; + + /* If the client has used a Supported Elliptic Curves Extension, + the public key in the server's certificate MUST + respect the client's choice of elliptic curves */ + if (info->ellipticCurveNum != 0) { + ret = CheckCurveName(config, info->ellipticCurveList, info->ellipticCurveNum, pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* Check point format. */ + if (info->ecPointFormatNum != 0) { + ret = CheckPointFormat(config, info->ecPointFormatList, info->ecPointFormatNum, pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_CheckCertInfo(HITLS_Ctx *ctx, const CERT_ExpectInfo *expectCertInfo, HITLS_CERT_X509 *cert, + bool isNegotiateSignAlgo, bool signCheck) +{ + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + HITLS_CERT_Key *pubkey = NULL; + int32_t ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15040, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "check certificate error: unable to get pubkey.", 0, 0, 0, 0); + return ret; + } + + do { + /* Certificate key security check */ + ret = CheckKeySecbits(ctx, cert, pubkey); + if (ret != HITLS_SUCCESS) { + break; + } + + uint32_t keyType = TLS_CERT_KEY_TYPE_UNKNOWN; + ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_TYPE, NULL, (void *)&keyType); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15041, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "check certificate error: pubkey type unknown.", 0, 0, 0, 0); + break; + } + /* Check the certificate type. */ + ret = CheckCertType(expectCertInfo->certType, keyType); + if (ret != HITLS_SUCCESS) { + break; + } + /* Check the signature algorithm. */ + if (signCheck == true) { + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 && keyType == TLS_CERT_KEY_TYPE_ECDSA) { + ret = TLS13EcdsaCheckSignScheme(ctx, expectCertInfo->signSchemeList, expectCertInfo->signSchemeNum, + pubkey, isNegotiateSignAlgo); + break; + } + ret = CheckSignScheme(ctx, expectCertInfo->signSchemeList, expectCertInfo->signSchemeNum, + keyType, isNegotiateSignAlgo); + if (ret != HITLS_SUCCESS) { + break; + } + } + /* ECDSA certificate. The curve ID and point format must be checked. + TLS_CERT_KEY_TYPE_SM2 does not check the curve ID and point format. + TLCP curves is sm2 and is not compressed. */ + if (keyType == TLS_CERT_KEY_TYPE_ECDSA) { + ret = IsEcParamCompatible(config, expectCertInfo, pubkey); + if (ret != HITLS_SUCCESS) { + break; + } + } + } while (false); + + SAL_CERT_KeyFree(mgrCtx, pubkey); + return ret; +} + +/** + * Server: Currently, two certificates are required for either of the two cipher suites supported. + * If the ECDHE cipher suite is used, the client needs to obtain the encrypted certificate to generate the premaster key + * and the signature certificate authenticates the identity. + * If the ECC cipher suite is used, the server public key is required to encrypt the premaster key + * and the signature certificate authentication is required. + * Client: Only the ECDHE cipher suite requires the client encryption certificate. + * In this case, the value of isNeedClientCert is true and may not be two-way authentication. (The specific value + * depends on the server configuration.) + * Therefore, the client does not verify any certificate and only sets the index. + * */ + +#ifndef HITLS_NO_TLCP11 +static int32_t TlcpSelectCertByInfo(HITLS_Ctx *ctx, CERT_ExpectInfo *info) +{ + int32_t ret; + int32_t encCertIndex = TLS_CERT_KEY_TYPE_ENC_SM2; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (ctx->isClient == false || ctx->negotiatedInfo.cipherSuiteInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) { + if (mgrCtx->certPair[TLS_CERT_KEY_TYPE_SM2].cert == NULL || mgrCtx->certPair[encCertIndex].cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15042, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "The certificate required by TLCP is not loaded.", 0, 0, 0, 0); + return HITLS_CERT_ERR_SELECT_CERTIFICATE; + } + + ret = SAL_CERT_CheckCertInfo(ctx, info, mgrCtx->certPair[TLS_CERT_KEY_TYPE_SM2].cert, true, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SAL_CERT_CheckCertInfo(ctx, info, mgrCtx->certPair[encCertIndex].cert, true, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + mgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_SM2; + return HITLS_SUCCESS; + } else { + /* Check whether the certificate is missing when the client sends the certificate + or sends it to the server for processing. Check whether the authentication-related signature certificate + or derived encryption certificate exists when the client uses the certificate. */ + if (mgrCtx->certPair[TLS_CERT_KEY_TYPE_SM2].cert != NULL) { + ret = SAL_CERT_CheckCertInfo(ctx, info, mgrCtx->certPair[TLS_CERT_KEY_TYPE_SM2].cert, true, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + if (mgrCtx->certPair[encCertIndex].cert != NULL) { + ret = SAL_CERT_CheckCertInfo(ctx, info, mgrCtx->certPair[encCertIndex].cert, true, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + mgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_SM2; + return HITLS_SUCCESS; + } +} +#endif + +static int32_t SelectCertByInfo(HITLS_Ctx *ctx, CERT_ExpectInfo *info) +{ + uint32_t i; + int32_t ret; + HITLS_CERT_X509 *cert = NULL; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL) { + /* The user does not set the certificate callback. */ + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + for (i = 0; i < TLS_CERT_KEY_TYPE_NUM; i++) { + cert = mgrCtx->certPair[i].cert; + if (cert == NULL) { + continue; + } + ret = SAL_CERT_CheckCertInfo(ctx, info, cert, true, true); + if (ret != HITLS_SUCCESS) { + continue; + } + /* Find a proper certificate and record the corresponding subscript. */ + mgrCtx->currentCertIndex = i; + return HITLS_SUCCESS; + } + return HITLS_CERT_ERR_SELECT_CERTIFICATE; +} + +int32_t SAL_CERT_SelectCertByInfo(HITLS_Ctx *ctx, CERT_ExpectInfo *info) +{ + int32_t ret = HITLS_SUCCESS; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL) { + /* The user does not set the certificate callback. */ + return HITLS_UNREGISTERED_CALLBACK; + } + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { +#ifndef HITLS_NO_TLCP11 + ret = TlcpSelectCertByInfo(ctx, info); +#endif + } else { + ret = SelectCertByInfo(ctx, info); + } + if (ret == HITLS_SUCCESS) { + return ret; + } + /* No proper certificate. */ + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_SELECT_CERTIFICATE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15029, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "select certificate fail.", 0, 0, 0, 0); + mgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_UNKNOWN; + return HITLS_CERT_ERR_SELECT_CERTIFICATE; +} + +int32_t EncodeCertificate(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + if (ctx == NULL || buf == NULL || cert == NULL || usedLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + int32_t ret; + HITLS_Config *config = &ctx->config.tlsConfig; + uint32_t certLen = 0; + ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_ENCODE_LEN, NULL, (void *)&certLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15043, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode certificate error: unable to get encode length.", 0, 0, 0, 0); + return ret; + } + /* Reserve at least 3 bytes length + data length. */ + if ((bufLen < CERT_LEN_TAG_SIZE) || (bufLen - CERT_LEN_TAG_SIZE < certLen) || (certLen == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_ENCODE_CERT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15044, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode cert out of buffer, encode len = %u, buffer len = %u.", certLen, bufLen, 0, 0); + return HITLS_CERT_ERR_ENCODE_CERT; + } + *usedLen = 0; + /* Write the length of the certificate data. */ + BSL_Uint24ToByte(certLen, buf); + /* Write the certificate data. */ + ret = SAL_CERT_X509Encode(ctx, cert, &buf[CERT_LEN_TAG_SIZE], bufLen - CERT_LEN_TAG_SIZE, usedLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint32_t offset = CERT_LEN_TAG_SIZE + *usedLen; + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + /* If an extension applies to the entire chain, + it SHOULD be included in the first CertificateEntry. */ + if (bufLen - offset < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_ENCODE_CERT); + return HITLS_CERT_ERR_ENCODE_CERT; + } + /* Valid extensions for server certificates at present include the OCSP Status extension [RFC6066] + and the SignedCertificateTimestamp extension [RFC6962] */ + BSL_Uint16ToByte(0, &buf[offset]); + offset += sizeof(uint16_t); + } + *usedLen = offset; + return HITLS_SUCCESS; +} + +void FreeCertList(HITLS_CERT_X509 **certList, uint32_t certNum) +{ + if (certList == NULL) { + return; + } + for (uint32_t i = 0; i < certNum; i++) { + SAL_CERT_X509Free(certList[i]); + } +} + +static int32_t EncodeEECert(HITLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen, + HITLS_CERT_X509 **cert) +{ + int32_t ret = 0; + uint32_t offset = 0; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + + CERT_Pair *currentCertPair = &mgrCtx->certPair[mgrCtx->currentCertIndex]; + HITLS_CERT_Key *key = currentCertPair->privateKey; + HITLS_CERT_X509 *tmpCert = currentCertPair->cert; + if (tmpCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_EXP_CERT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15030, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "If a certificate exists, the first certificate cannot be empty.", 0, 0, 0, 0); + return HITLS_CERT_ERR_EXP_CERT; + } + /* Certificate key security check */ + ret = CheckKeySecbits(ctx, tmpCert, key); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* Write the first device certificate. */ + ret = EncodeCertificate(ctx, tmpCert, buf, bufLen, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15031, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode device certificate error.", 0, 0, 0, 0); + return ret; + } + offset += *usedLen; +#ifndef HITLS_NO_TLCP11 + /* If the TLCP algorithm is used and the encryption certificate is required, + write the second encryption certificate. */ + CERT_Pair *currentCertPairEnc = &mgrCtx->certPair[mgrCtx->currentCertIndex + 1]; + HITLS_CERT_X509 *certEnc = currentCertPairEnc->cert; + HITLS_CERT_Key *keyEnc = currentCertPairEnc->privateKey; + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11 && certEnc != NULL) { + ret = CheckKeySecbits(ctx, certEnc, keyEnc); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = EncodeCertificate(ctx, certEnc, &buf[offset], bufLen - offset, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15032, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLCP encode device certificate error.", 0, 0, 0, 0); + return ret; + } + offset += *usedLen; + } +#endif + *usedLen = offset; + *cert = tmpCert; + return HITLS_SUCCESS; +} + +static int32_t CheckCertChainFromStore(HITLS_Config *config, HITLS_CERT_X509 *cert) +{ + HITLS_CERT_Key *pubkey = NULL; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + int32_t ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + return HITLS_CONFIG_ERR_LOAD_CERT_FILE; + } + + int32_t secBits = 0; + ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_SECBITS, NULL, (void *)&secBits); + SAL_CERT_KeyFree(mgrCtx, pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SECURITY_CfgCheck(config, HITLS_SECURITY_SECOP_CA_KEY, secBits, 0, cert); // cert key + if (ret != SECURITY_SUCCESS) { + return HITLS_CERT_ERR_CA_KEY_WITH_INSECURE_SECBITS; + } + + int32_t signAlg = 0; + ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_SIGN_ALGO, NULL, (void *)&signAlg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SECURITY_CfgCheck(config, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signAlg, NULL); + if (ret != SECURITY_SUCCESS) { + return HITLS_CERT_ERR_INSECURE_SIG_ALG ; + } + return HITLS_SUCCESS; +} + +static int32_t EncodeCertificateChain(HITLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen, uint32_t offset) +{ + HITLS_CERT_X509 *tempCert = NULL; + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + CERT_Pair *currentCertPair = &mgrCtx->certPair[mgrCtx->currentCertIndex]; + tempCert = (HITLS_CERT_X509 *)BSL_LIST_GET_FIRST(currentCertPair->chain); + uint32_t tempOffset = offset; + while (tempCert != NULL) { + int32_t ret = EncodeCertificate(ctx, tempCert, &buf[tempOffset], bufLen - tempOffset, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15048, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "encode cert chain error", 0, 0, 0, 0); + return ret; + } + tempOffset += *usedLen; + tempCert = BSL_LIST_GET_NEXT(currentCertPair->chain); + } + *usedLen = tempOffset; + return HITLS_SUCCESS; +} + +static int32_t EncodeCertStore(HITLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen, HITLS_CERT_X509 *cert) +{ + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + HITLS_CERT_Store *store = (mgrCtx->chainStore != NULL) ? mgrCtx->chainStore : mgrCtx->certStore; + uint32_t offset = *usedLen; + HITLS_CERT_X509 *certList[TLS_DEFAULT_VERIFY_DEPTH] = {0}; + uint32_t certNum = TLS_DEFAULT_VERIFY_DEPTH; + if (store != NULL) { + int32_t ret = SAL_CERT_BuildChain(config, store, cert, certList, &certNum); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* The first device certificate has been written. The certificate starts from the second one. */ + for (uint32_t i = 1; i < certNum; i++) { + ret = CheckCertChainFromStore(config, certList[i]); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = EncodeCertificate(ctx, certList[i], &buf[offset], bufLen - offset, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15033, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode cert chain error in No.%u.", i, 0, 0, 0); + FreeCertList(certList, certNum); + return ret; + } + offset += *usedLen; + } + } + FreeCertList(certList, certNum); + *usedLen = offset; + return HITLS_SUCCESS; +} +/** + * The constructed certificate chain is incomplete (excluding the root certificate). + * Therefore, in the buildCertChain callback, the return value is ignored, even if the error returned by this call. + * In fact, certificates are not verified but chains are constructed as many as possible. + * So do not need to invoke buildCertChain if the certificate is encrypted using the TLCP. + * If the TLCP is used, the server has checked that the two certificates are not empty. + * The client does not check, the message is sent based on the configuration. + * If the message will be sent, the signature certificate must exist. + * */ +int32_t SAL_CERT_EncodeCertChain(HITLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + if (ctx == NULL || buf == NULL || usedLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + HITLS_CERT_X509 *cert = NULL; + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + return HITLS_UNREGISTERED_CALLBACK; + } + +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11 && mgrCtx->certPair[TLS_CERT_KEY_TYPE_SM2].cert == NULL) { + *usedLen = 0; + return HITLS_SUCCESS; + } +#endif + if (mgrCtx->currentCertIndex >= TLS_CERT_KEY_TYPE_NUM) { + /* No certificate needs to be sent at the local end. */ + *usedLen = 0; + return HITLS_SUCCESS; + } + CERT_Pair *currentCertPair = &mgrCtx->certPair[mgrCtx->currentCertIndex]; + uint32_t offset = 0; + int32_t ret = EncodeEECert(ctx, buf, bufLen, usedLen, &cert); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15046, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode device certificate error.", 0, 0, 0, 0); + return ret; + } + offset += *usedLen; + uint32_t listSize = (uint32_t)BSL_LIST_COUNT(currentCertPair->chain); + // Check the size. If a certificate exists in the chain, directly put the data in the chain into the buf and return. + if (listSize > 0) { + ret = EncodeCertificateChain(ctx, buf, bufLen, usedLen, offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; + } + *usedLen = offset; + return EncodeCertStore(ctx, buf, bufLen, usedLen, cert); +} + +// rfc8446 4.4.2.4. Receiving a Certificate Message +// Any endpoint receiving any certificate which it would need to validate using any signature algorithm using an MD5 +// hash MUST abort the handshake with a "bad_certificate" alert. +// Currently, the MD5 signature algorithm is not available, but it is still an unknown one. +int32_t CheckCertSignature(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert) +{ + HITLS_Config *config = &ctx->config.tlsConfig; + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + int32_t signAlg = 0; + (void)SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_SIGN_ALGO, NULL, (void *)&signAlg); + if (signAlg == CERT_SIG_SCHEME_UNKNOWN) { + return HITLS_CERT_CTRL_ERR_GET_SIGN_ALGO; + } + } + return HITLS_SUCCESS; +} + +int32_t ParseChain(HITLS_Ctx *ctx, CERT_Item *item, HITLS_CERT_Chain **chain, HITLS_CERT_X509 **encCert) +{ + HITLS_Config *config = &ctx->config.tlsConfig; + HITLS_CERT_Chain *newChain = SAL_CERT_ChainNew(); + if (newChain == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15049, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse cert chain error: out of memory for new cert chain.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + CERT_Item *listNode = item; + while (listNode != NULL) { + HITLS_CERT_X509 *cert = SAL_CERT_X509Parse(config, listNode->data, listNode->dataSize, + TLS_PARSE_TYPE_BUFF, TLS_PARSE_FORMAT_ASN1); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15050, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse cert chain error: callback failed.", 0, 0, 0, 0); + SAL_CERT_X509Free(*encCert); + SAL_CERT_ChainFree(newChain); + return HITLS_CERT_ERR_PARSE_MSG; + } + if (CheckCertSignature(ctx, cert) != HITLS_SUCCESS) { + SAL_CERT_X509Free(*encCert); + SAL_CERT_X509Free(cert); + SAL_CERT_ChainFree(newChain); + return HITLS_CERT_CTRL_ERR_GET_SIGN_ALGO; + } + +#ifndef HITLS_NO_TLCP11 + if (SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_KEYENC_USAGE) == true) { + SAL_CERT_X509Free(*encCert); + *encCert = cert; + listNode = listNode->next; + continue; + } +#endif + /* Add a certificate to the certificate chain. */ + if (SAL_CERT_ChainAppend(newChain, cert) != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15051, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse cert chain error: out of memory for new cert node.", 0, 0, 0, 0); + SAL_CERT_X509Free(*encCert); + SAL_CERT_X509Free(cert); + SAL_CERT_ChainFree(newChain); + return HITLS_MEMALLOC_FAIL; + } + listNode = listNode->next; + } + *chain = newChain; + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_ParseCertChain(HITLS_Ctx *ctx, CERT_Item *item, CERT_Pair **certPair) +{ + if (ctx == NULL || item == NULL || certPair == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + int32_t ret; + HITLS_CERT_X509 *encCert = NULL; + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + /* Parse the first device certificate. */ + HITLS_CERT_X509 *cert = SAL_CERT_X509Parse(config, item->data, item->dataSize, + TLS_PARSE_TYPE_BUFF, TLS_PARSE_FORMAT_ASN1); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15052, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse peer device certificate error: callback failed.", 0, 0, 0, 0); + return HITLS_CERT_ERR_PARSE_MSG; + } + + if (CheckCertSignature(ctx, cert) != HITLS_SUCCESS) { + SAL_CERT_X509Free(cert); + return HITLS_CERT_CTRL_ERR_GET_SIGN_ALGO; + } + + /* Parse other certificates in the certificate chain. */ + HITLS_CERT_Chain *chain = NULL; + ret = ParseChain(ctx, item->next, &chain, &encCert); + if (ret != HITLS_SUCCESS) { + SAL_CERT_X509Free(cert); + return ret; + } + + CERT_Pair *newCertPair = BSL_SAL_Calloc(1u, sizeof(CERT_Pair)); + if (newCertPair == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15053, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "internal error: out of memory for peer cert.", 0, 0, 0, 0); + SAL_CERT_X509Free(cert); + SAL_CERT_X509Free(encCert); + SAL_CERT_ChainFree(chain); + return HITLS_MEMALLOC_FAIL; + } + newCertPair->cert = cert; + newCertPair->encCert = encCert; + newCertPair->chain = chain; + *certPair = newCertPair; + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_VerifyCertChain(HITLS_Ctx *ctx, CERT_Pair *certPair, bool isTlcpEncCert) +{ + if (ctx == NULL || certPair == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + int32_t ret; + uint32_t i = 0; + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + HITLS_CERT_Chain *chain = certPair->chain; + /* Obtain the number of certificates. The first device certificate must also be included. */ + uint32_t certNum = (uint32_t)(BSL_LIST_COUNT(chain) + 1); + + HITLS_CERT_X509 **certList = (HITLS_CERT_X509 **)BSL_SAL_Calloc(1u, sizeof(HITLS_CERT_X509 *) * certNum); + if (certList == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15054, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "internal error: out of memory for cert list.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + certList[i++] = (isTlcpEncCert == false) ? certPair->cert : certPair->encCert; + + /* Convert the CERT_Chain into an array. */ + HITLS_CERT_X509 *currCert = NULL; + for (uint32_t index = 0u; index < (certNum - 1); ++index) { + currCert = (HITLS_CERT_X509 *)BSL_LIST_GetIndexNode(index, chain); + certList[i++] = currCert; + } + + /* Verify the certificate chain. */ + HITLS_CERT_Store *store = (mgrCtx->verifyStore != NULL) ? mgrCtx->verifyStore : mgrCtx->certStore; + uint32_t depth = mgrCtx->verifyParam.verifyDepth; + ret = SAL_CERT_StoreCtrl(config, store, CERT_STORE_CTRL_SET_VERIFY_DEPTH, &depth, NULL); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(certList); + return HITLS_CERT_ERR_VERIFY_CERT_CHAIN; + } + + ret = SAL_CERT_VerifyChain(ctx, store, certList, i); + BSL_SAL_FREE(certList); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; +} + +uint32_t SAL_CERT_GetSignMaxLen(HITLS_Config *config, HITLS_CERT_Key *key) +{ + uint32_t len = 0; + int32_t ret = SAL_CERT_KeyCtrl(config, key, CERT_KEY_CTRL_GET_SIGN_LEN, NULL, &len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15056, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get signature length error: callback ret = 0x%x.", ret, 0, 0, 0); + return 0; + } + return len; +} + +int32_t HITLS_get_ex_data_X509_STORE_CTX_idx(void) +{ + if (g_hitlsX509StoreCtxIdx == -1) { + g_hitlsX509StoreCtxIdx = BSL_USER_GetExDataNewIndex(BSL_USER_DATA_EX_INDEX_X509_STORE_CTX, + 0, NULL, NULL, NULL, NULL); + } + return g_hitlsX509StoreCtxIdx; +} + +int32_t HITLS_CFG_SetCheckPriKeyCb(HITLS_Config *config, CERT_CheckPrivateKeyCallBack checkPrivateKey) +{ + if (config == NULL || config->certMgrCtx == NULL || checkPrivateKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->certMgrCtx->method.checkPrivateKey = checkPrivateKey; + return HITLS_SUCCESS; +} + +CERT_CheckPrivateKeyCallBack HITLS_CFG_GetCheckPriKeyCb(HITLS_Config *config) +{ + if (config == NULL || config->certMgrCtx == NULL) { + return NULL; + } + + return config->certMgrCtx->method.checkPrivateKey; +} + +#ifndef HITLS_NO_TLCP11 +static uint8_t *EncodeEncCert(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint32_t *useLen) +{ + if (ctx == NULL || cert == NULL || useLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + uint32_t certLen; + HITLS_Config *config = &ctx->config.tlsConfig; + int32_t ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_ENCODE_LEN, NULL, (void *)&certLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15057, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode gm enc certificate error: unable to get encode length.", 0, 0, 0, 0); + return NULL; + } + + /* Allocate the signature data memory. */ + uint8_t *data = BSL_SAL_Calloc(1u, certLen); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15058, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signature data memory alloc fail.", 0, 0, 0, 0); + return NULL; + } + + ret = SAL_CERT_X509Encode(ctx, cert, data, certLen, useLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(data); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15332, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode cert error: callback ret = 0x%x.", (uint32_t)ret, 0, 0, 0); + return NULL; + } + return data; +} + +uint8_t *SAL_CERT_SrvrGmEncodeEncCert(HITLS_Ctx *ctx, uint32_t *useLen) +{ + if (ctx == NULL || useLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + int index = TLS_CERT_KEY_TYPE_ENC_SM2; + + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + CERT_Pair *currentCertPair = &mgrCtx->certPair[index]; + HITLS_CERT_X509 *cert = currentCertPair->cert; + + return EncodeEncCert(ctx, cert, useLen); +} + +uint8_t *SAL_CERT_ClntGmEncodeEncCert(HITLS_Ctx *ctx, CERT_Pair *peerCert, uint32_t *useLen) +{ + return EncodeEncCert(ctx, peerCert->encCert, useLen); +} + +bool SAL_CERT_CheckCertKeyUsage(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd keyusage) +{ + if (ctx == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + uint8_t isUsage = false; + if (keyusage != CERT_KEY_CTRL_IS_KEYENC_USAGE && keyusage != CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE && + keyusage != CERT_KEY_CTRL_IS_KEY_CERT_SIGN_USAGE && keyusage != CERT_KEY_CTRL_IS_KEY_AGREEMENT_USAGE) { + return (bool)isUsage; + } + HITLS_Config *config = &ctx->config.tlsConfig; + if (SAL_CERT_X509Ctrl(config, cert, keyusage, NULL, (void *)&isUsage) != HITLS_SUCCESS) { + return false; + } + + return (bool)isUsage; +} +#endif + +HITLS_CERT_KeyType SAL_CERT_SignScheme2CertKeyType(HITLS_SignHashAlgo signScheme) +{ + return SignScheme2CertKeyType(signScheme); +} diff --git a/tls/cert/cert_adapt/cert_chain.c b/tls/cert/cert_adapt/cert_chain.c new file mode 100644 index 00000000..6469ba55 --- /dev/null +++ b/tls/cert/cert_adapt/cert_chain.c @@ -0,0 +1,109 @@ +/* + * 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 +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "bsl_list.h" +#include "hitls_error.h" +#include "cert_method.h" +#include "cert_mgr_ctx.h" + + +HITLS_CERT_Chain *SAL_CERT_ChainNew(void) +{ + BslList *newChain = BSL_LIST_New(sizeof(HITLS_CERT_X509 *)); + if (newChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15010, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "new cert chain error: out of memory.", 0, 0, 0, 0); + } + return newChain; +} + +int32_t SAL_CERT_ChainAppend(HITLS_CERT_Chain *chain, HITLS_CERT_X509 *cert) +{ + /* add the tail to the end of the certificate chain, corresponding to the top of the stack */ + if (BSL_LIST_AddElement(chain, cert, BSL_LIST_POS_END) != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15011, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "append cert to chain error: out of memory.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + return HITLS_SUCCESS; +} + +static void CertChainInnerDestroyCb(void *cert) +{ + SAL_CERT_X509Free((HITLS_CERT_X509 *)cert); +} + +/* release the linked list without retaining the head node */ +void SAL_CERT_ChainFree(HITLS_CERT_Chain *chain) +{ + /* only certificates on the chain are destroyed, chain itself will be not destroyed */ + BSL_LIST_DeleteAll(chain, CertChainInnerDestroyCb); + BSL_SAL_FREE(chain); + return; +} + +/* copy the certificate chain */ +HITLS_CERT_Chain *SAL_CERT_ChainDup(CERT_MgrCtx *mgrCtx, HITLS_CERT_Chain *chain) +{ + int32_t ret; + uint32_t listSize = (uint32_t)BSL_LIST_COUNT(chain); + HITLS_CERT_X509 *dupCert = NULL; + HITLS_CERT_X509 *currCert = NULL; + + if (BSL_LIST_COUNT(chain) < 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert chain error: list size tainted.", 0, 0, 0, 0); + return NULL; + } + + BslList *newChain = SAL_CERT_ChainNew(); + if (newChain == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15012, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert chain error: out of memory.", 0, 0, 0, 0); + return NULL; + } + + for (uint32_t index = 0u; index < listSize; ++index) { + currCert = (HITLS_CERT_X509 *)BSL_LIST_GetIndexNode(index, chain); + dupCert = SAL_CERT_X509Dup(mgrCtx, currCert); + if (dupCert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15013, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert chain error: x509 dup error.", 0, 0, 0, 0); + goto EXIT; + } + ret = SAL_CERT_ChainAppend(newChain, dupCert); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert chain error: append new cert node error.", 0, 0, 0, 0); + SAL_CERT_X509Free(dupCert); + goto EXIT; + } + } + + return newChain; +EXIT: + /* free the certificate chain */ + SAL_CERT_ChainFree(newChain); + return NULL; +} \ No newline at end of file diff --git a/tls/cert/cert_adapt/cert_method.c b/tls/cert/cert_adapt/cert_method.c new file mode 100644 index 00000000..e191c4bb --- /dev/null +++ b/tls/cert/cert_adapt/cert_method.c @@ -0,0 +1,586 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "tls_config.h" +#include "tls.h" +#include "cert_mgr_ctx.h" +#include "cert_method.h" + +HITLS_CERT_MgrMethod g_certMgrMethod = {0}; + +HITLS_CERT_UserKeyMgrMethod g_certUserKeyMgrMethod = {0}; + +static int32_t IsMethodValid(const HITLS_CERT_MgrMethod *method) +{ + if (method == NULL || + method->certStoreNew == NULL || + method->certStoreDup == NULL || + method->certStoreFree == NULL || + method->certStoreCtrl == NULL || + method->buildCertChain == NULL || + method->verifyCertChain == NULL || + method->certEncode == NULL || + method->certParse == NULL || + method->certDup == NULL || + method->certFree == NULL || + method->certCtrl == NULL || + method->keyParse == NULL || + method->keyDup == NULL || + method->keyFree == NULL || + method->keyCtrl == NULL || + method->createSign == NULL || + method->verifySign == NULL || + method->checkPrivateKey == NULL) { + return false; + } + return true; +} + +int32_t HITLS_CERT_RegisterMgrMethod(HITLS_CERT_MgrMethod *method) +{ + /* check the callbacks that must be set */ + if (IsMethodValid(method) == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15003, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HITLS_CERT_RegisterMgrMethod error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + (void)memcpy_s(&g_certMgrMethod, sizeof(HITLS_CERT_MgrMethod), method, sizeof(HITLS_CERT_MgrMethod)); + return HITLS_SUCCESS; +} + +void HITLS_CERT_DeinitMgrMethod(void) +{ + HITLS_CERT_MgrMethod mgr = {0}; + (void)memcpy_s(&g_certMgrMethod, sizeof(HITLS_CERT_MgrMethod), &mgr, sizeof(HITLS_CERT_MgrMethod)); +} + +int32_t HITLS_CERT_RegisterUserKeyMgrMethod(HITLS_CERT_UserKeyMgrMethod *method) +{ + /* the usage of HITLS_CERT_UserKeyMgrMethod depends on HITLS_CERT_MgrMethod, + therefore there is the judgment of registration of HITLS_CERT_MgrMethod */ + HITLS_CERT_MgrMethod *certMgrMethod = SAL_CERT_GetMgrMethod(); + if (IsMethodValid(certMgrMethod) == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HITLS_CERT_RegisterMgrMethod is not registed", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (method == NULL || + method->keyToUserKey == NULL || + method->keyFormUserKey == NULL || + method->userKeyFree == NULL || + method->userKeyDup == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15007, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HITLS_CERT_RegisterUserKeyMgrMethod error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (memcpy_s(&g_certUserKeyMgrMethod, + sizeof(HITLS_CERT_UserKeyMgrMethod), + method, + sizeof(HITLS_CERT_UserKeyMgrMethod)) != EOK) { + return HITLS_MEMCPY_FAIL; + } + return HITLS_SUCCESS; +} + +void HITLS_CERT_DeinitUserKeyMgrMethod(void) +{ + HITLS_CERT_UserKeyMgrMethod mgr = {0}; + (void)memcpy_s( + &g_certUserKeyMgrMethod, sizeof(HITLS_CERT_UserKeyMgrMethod), &mgr, sizeof(HITLS_CERT_UserKeyMgrMethod)); + return; +} + +HITLS_CERT_MgrMethod *SAL_CERT_GetMgrMethod(void) +{ + return &g_certMgrMethod; +} + +HITLS_CERT_UserKeyMgrMethod *SAL_CERT_GetUserKeyMgrMethod(void) +{ + return &g_certUserKeyMgrMethod; +} + +HITLS_CERT_Store *SAL_CERT_StoreNew(const CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL || mgrCtx->method.certStoreNew == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15006, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store new error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + + HITLS_CERT_Store *store = mgrCtx->method.certStoreNew(); + if (store == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15009, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store new error: callback return NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_STORE_ERR_NEW); + return NULL; + } + + return store; +} + +HITLS_CERT_Store *SAL_CERT_StoreDup(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store) +{ + if (mgrCtx == NULL || store == NULL || mgrCtx->method.certStoreDup == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15008, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store dup error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + + HITLS_CERT_Store *newStore = mgrCtx->method.certStoreDup(store); + if (newStore == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15062, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store dup error: callback return NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_STORE_DUP); + return NULL; + } + + return newStore; +} + +void SAL_CERT_StoreFree(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store) +{ + if (mgrCtx == NULL || store == NULL || mgrCtx->method.certStoreFree == NULL) { + return; + } + + mgrCtx->method.certStoreFree(store); + return; +} + +int32_t SAL_CERT_BuildChain(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_X509 *cert, + HITLS_CERT_X509 **certList, uint32_t *num) +{ + if (config == NULL || store == NULL || cert == NULL || certList == NULL || num == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.buildCertChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.buildCertChain(config, store, cert, certList, num); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15464, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store build chain by cert error: ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_BUILD_CHAIN); + return HITLS_CERT_ERR_BUILD_CHAIN; + } + + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_VerifyChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store, HITLS_CERT_X509 **certList, uint32_t num) +{ + if (ctx == NULL || store == NULL || certList == NULL || num == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.verifyCertChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.verifyCertChain(ctx, store, certList, num); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15465, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store verify chain error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_VERIFY_CERT_CHAIN); + return HITLS_CERT_ERR_VERIFY_CERT_CHAIN; + } + + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_X509Encode(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t len, uint32_t *usedLen) +{ + if (ctx == NULL || cert == NULL || buf == NULL || len == 0 || usedLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.certEncode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.certEncode(ctx, cert, buf, len, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15466, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode cert error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_ENCODE_CERT); + return HITLS_CERT_ERR_ENCODE_CERT; + } + + return HITLS_SUCCESS; +} + +HITLS_CERT_X509 *SAL_CERT_X509Parse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format) +{ + if (config == NULL || buf == NULL || len == 0) { + return NULL; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.certParse == NULL) { + return NULL; + } + + HITLS_CERT_X509 *cert = mgrCtx->method.certParse(config, buf, len, type, format); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15467, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse cert error: len = %u, type = %u, format = %u.", len, type, format, 0); + return NULL; + } + + return cert; +} + +HITLS_CERT_X509 *SAL_CERT_X509Dup(const CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert) +{ + if (mgrCtx == NULL || cert == NULL || mgrCtx->method.certDup == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + + HITLS_CERT_X509 *newCert = mgrCtx->method.certDup(cert); + if (newCert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15181, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert error: callback return NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_X509_DUP); + return NULL; + } + + return newCert; +} + +void SAL_CERT_X509Free(HITLS_CERT_X509 *cert) +{ + if (cert == NULL || g_certMgrMethod.certFree == NULL) { + return; + } + + g_certMgrMethod.certFree(cert); + return; +} + +HITLS_CERT_X509 *SAL_CERT_X509Ref(const CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert) +{ + if (mgrCtx == NULL || cert == NULL || mgrCtx->method.certRef == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15335, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ref cert error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + + HITLS_CERT_X509 *newCert = mgrCtx->method.certRef(cert); + if (newCert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15336, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ref cert error: callback return NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_X509_REF); + return NULL; + } + + return newCert; +} + +HITLS_CERT_Key *SAL_CERT_KeyParse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format) +{ + if (config == NULL || buf == NULL || len == 0) { + return NULL; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.keyParse == NULL) { + return NULL; + } + + HITLS_CERT_Key *key = mgrCtx->method.keyParse(config, buf, len, type, format); + if (key == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15180, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse key error: len = %u, type = %u, format = %u.", len, type, format, 0); + return NULL; + } + + return key; +} + +HITLS_CERT_Key *SAL_CERT_KeyDup(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Key *key) +{ + if (mgrCtx == NULL || key == NULL || mgrCtx->method.keyDup == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15004, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup key error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + + HITLS_CERT_Key *newKey = mgrCtx->method.keyDup(key); + if (newKey == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15005, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup key error: callback return NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_KEY_DUP); + return NULL; + } + + return newKey; +} + +void SAL_CERT_KeyFree(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Key *key) +{ + if (mgrCtx == NULL || key == NULL || mgrCtx->method.keyFree == NULL) { + return; + } + + // use the EVP type to release data + HITLS_CERT_UserKeyMgrMethod *method = SAL_CERT_GetUserKeyMgrMethod(); + if (method->userKeyFree != NULL) { + method->userKeyFree(key); + return; + } + + mgrCtx->method.keyFree(key); + return; +} + +/* change the error code when modifying the ctrl command */ +int32_t g_tlsCertCtrlErrorCode[] = { + HITLS_CERT_STORE_CTRL_ERR_SET_VERIFY_DEPTH, + HITLS_CERT_STORE_CTRL_ERR_ADD_CERT_LIST, + HITLS_CERT_CTRL_ERR_GET_ENCODE_LEN, + HITLS_CERT_CTRL_ERR_GET_PUB_KEY, + HITLS_CERT_CTRL_ERR_GET_SIGN_ALGO, + HITLS_CERT_KEY_CTRL_ERR_GET_SIGN_LEN, + HITLS_CERT_KEY_CTRL_ERR_GET_TYPE, + HITLS_CERT_KEY_CTRL_ERR_GET_CURVE_NAME, + HITLS_CERT_KEY_CTRL_ERR_GET_POINT_FORMAT, + HITLS_CERT_KEY_CTRL_ERR_GET_SECBITS, + HITLS_CERT_KEY_CTRL_ERR_IS_ENC_USAGE, + HITLS_CERT_KEY_CTRL_ERR_IS_DIGITAL_SIGN_USAGE, + HITLS_CERT_KEY_CTRL_ERR_IS_KEY_CERT_SIGN_USAGE, + HITLS_CERT_KEY_CTRL_ERR_IS_KEY_AGREEMENT_USAGE, +}; + +int32_t SAL_CERT_StoreCtrl(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_CtrlCmd cmd, void *in, void *out) +{ + if (config == NULL || store == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.certStoreCtrl == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.certStoreCtrl(config, store, cmd, in, out); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15174, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert store ctrl callback error: ret = 0x%x, cmd = %u.", ret, cmd, 0, 0); + BSL_ERR_PUSH_ERROR(g_tlsCertCtrlErrorCode[cmd]); + return g_tlsCertCtrlErrorCode[cmd]; + } + + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_X509Ctrl(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd cmd, void *in, void *out) +{ + if (config == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.certCtrl == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.certCtrl(config, cert, cmd, in, out); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15173, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert ctrl callback error: ret = 0x%x, cmd = %u.", ret, cmd, 0, 0); + BSL_ERR_PUSH_ERROR(g_tlsCertCtrlErrorCode[cmd]); + return g_tlsCertCtrlErrorCode[cmd]; + } + + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_KeyCtrl(HITLS_Config *config, HITLS_CERT_Key *key, HITLS_CERT_CtrlCmd cmd, void *in, void *out) +{ + if (config == NULL || key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.keyCtrl == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.keyCtrl(config, key, cmd, in, out); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15172, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "key ctrl callback error: ret = 0x%x, cmd = %u.", ret, cmd, 0, 0); + BSL_ERR_PUSH_ERROR(g_tlsCertCtrlErrorCode[cmd]); + return g_tlsCertCtrlErrorCode[cmd]; + } + + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_CreateSign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, CERT_SignParam *signParam) +{ + if (ctx == NULL || key == NULL || signParam == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.createSign == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.createSign(ctx, key, signParam->signAlgo, signParam->hashAlgo, + signParam->data, signParam->dataLen, signParam->sign, &signParam->signLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15536, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "create signature error: sign algo = %u, hash algo = %u, dataLen = %u, signLen = %u", + signParam->signAlgo, signParam->hashAlgo, signParam->dataLen, signParam->signLen); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15962, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "callback ret = 0x%x", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_CREATE_SIGN); + return HITLS_CERT_ERR_CREATE_SIGN; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_VerifySign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, CERT_SignParam *signParam) +{ + if (key == NULL || ctx == NULL || signParam == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.verifySign == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.verifySign(ctx, key, signParam->signAlgo, signParam->hashAlgo, + signParam->data, signParam->dataLen, signParam->sign, signParam->signLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15964, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify signature error: sign algo = %u, hash algo = %u, dataLen = %u, signLen = %u", + signParam->signAlgo, signParam->hashAlgo, signParam->dataLen, signParam->signLen); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15969, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "callback ret = 0x%x", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_VERIFY_SIGN); + return HITLS_CERT_ERR_VERIFY_SIGN; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_KeyEncrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.encrypt == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.encrypt(ctx, key, in, inLen, out, outLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15059, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubkey encrypt error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_ENCRYPT); + return HITLS_CERT_ERR_ENCRYPT; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_KeyDecrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.decrypt == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.decrypt(ctx, key, in, inLen, out, outLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15060, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "private key decrypt error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_DECRYPT); + return HITLS_CERT_ERR_DECRYPT; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_CheckPrivateKey(const HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_Key *key) +{ + if (config == NULL || cert == NULL || key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.checkPrivateKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = mgrCtx->method.checkPrivateKey(config, cert, key); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15061, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check cert and private key error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_CHECK_CERT_AND_KEY); + return HITLS_CERT_ERR_CHECK_CERT_AND_KEY; + } + return HITLS_SUCCESS; +} diff --git a/tls/cert/cert_adapt/cert_mgr_create.c b/tls/cert/cert_adapt/cert_mgr_create.c new file mode 100644 index 00000000..f728889f --- /dev/null +++ b/tls/cert/cert_adapt/cert_mgr_create.c @@ -0,0 +1,196 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "tls_config.h" +#include "cert_method.h" +#include "cert_mgr_ctx.h" + +bool SAL_CERT_MgrIsEnable(void) +{ + HITLS_CERT_MgrMethod *method = SAL_CERT_GetMgrMethod(); + return (method->certStoreNew != NULL); +} + +CERT_MgrCtx *SAL_CERT_MgrCtxNew(void) +{ + HITLS_CERT_MgrMethod *method = SAL_CERT_GetMgrMethod(); + CERT_MgrCtx *newCtx = BSL_SAL_Calloc(1, sizeof(CERT_MgrCtx)); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15017, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "new cert manager context error: out of memory.", 0, 0, 0, 0); + return NULL; + } + newCtx->currentCertIndex = TLS_CERT_KEY_TYPE_UNKNOWN; + newCtx->verifyParam.verifyDepth = TLS_DEFAULT_VERIFY_DEPTH; + (void)memcpy_s(&newCtx->method, sizeof(HITLS_CERT_MgrMethod), method, sizeof(HITLS_CERT_MgrMethod)); + + newCtx->certStore = SAL_CERT_StoreNew(newCtx); + if (newCtx->certStore == NULL) { + BSL_SAL_FREE(newCtx); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "new cert manager context error: new store failed.", 0, 0, 0, 0); + return NULL; + } + return newCtx; +} + +static int32_t CertResourceDup(CERT_MgrCtx *destMgrCtx, CERT_MgrCtx *srcMgrCtx) +{ + CERT_Pair *destCertPair = NULL; + CERT_Pair *srcCertPair = NULL; + for (uint32_t i = 0; i < TLS_CERT_KEY_TYPE_NUM; i++) { + destCertPair = &(destMgrCtx->certPair[i]); + srcCertPair = &(srcMgrCtx->certPair[i]); + if (srcCertPair->cert != NULL) { + destCertPair->cert = SAL_CERT_X509Dup(srcMgrCtx, srcCertPair->cert); + if (destCertPair->cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error: x509 dup error.", 0, 0, 0, 0); + /* releasing resources at the call point */ + return HITLS_CERT_ERR_X509_DUP; + } + } + if (srcCertPair->privateKey != NULL) { + destCertPair->privateKey = SAL_CERT_KeyDup(srcMgrCtx, srcCertPair->privateKey); + if (destCertPair->privateKey == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15020, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error: key dup error.", 0, 0, 0, 0); + /* releasing resources at the call point */ + return HITLS_CERT_ERR_KEY_DUP; + } + } + if (srcCertPair->chain != NULL) { + destCertPair->chain = SAL_CERT_ChainDup(srcMgrCtx, srcCertPair->chain); + if (destCertPair->chain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_CHAIN_DUP); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15019, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error: cert chain dup error.", 0, 0, 0, 0); + /* releasing resources at the call point */ + return HITLS_CERT_ERR_CHAIN_DUP; + } + } + } + return HITLS_SUCCESS; +} + +int32_t StoreDup(CERT_MgrCtx *destMgrCtx, CERT_MgrCtx *srcMgrCtx) +{ + if (srcMgrCtx->certStore != NULL) { + destMgrCtx->certStore = SAL_CERT_StoreDup(srcMgrCtx, srcMgrCtx->certStore); + if (destMgrCtx->certStore == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error in copy cert store.", 0, 0, 0, 0); + /* releasing resources at the call point */ + return HITLS_CERT_ERR_STORE_DUP; + } + } + + if (srcMgrCtx->chainStore != NULL) { + destMgrCtx->chainStore = SAL_CERT_StoreDup(srcMgrCtx, srcMgrCtx->chainStore); + if (destMgrCtx->chainStore == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15022, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error in copy chain store.", 0, 0, 0, 0); + /* releasing resources at the call point */ + return HITLS_CERT_ERR_STORE_DUP; + } + } + + if (srcMgrCtx->verifyStore != NULL) { + destMgrCtx->verifyStore = SAL_CERT_StoreDup(srcMgrCtx, srcMgrCtx->verifyStore); + if (destMgrCtx->verifyStore == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15023, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error in copy verify store.", 0, 0, 0, 0); + /* releasing resources at the call point */ + return HITLS_CERT_ERR_STORE_DUP; + } + } + + return HITLS_SUCCESS; +} + +CERT_MgrCtx *SAL_CERT_MgrCtxDup(CERT_MgrCtx *mgrCtx) +{ + int32_t ret; + if (mgrCtx == NULL) { + return NULL; + } + + CERT_MgrCtx *newCtx = BSL_SAL_Calloc(1, sizeof(CERT_MgrCtx)); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15024, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup cert manager context error: out of memory.", 0, 0, 0, 0); + return NULL; + } + + (void)memcpy_s(&newCtx->method, sizeof(HITLS_CERT_MgrMethod), &mgrCtx->method, sizeof(HITLS_CERT_MgrMethod)); + + ret = CertResourceDup(newCtx, mgrCtx); + if (ret != HITLS_SUCCESS) { + SAL_CERT_MgrCtxFree(newCtx); + return NULL; + } + + if (mgrCtx->extraChain != NULL) { + newCtx->extraChain = SAL_CERT_ChainDup(mgrCtx, mgrCtx->extraChain); + if (newCtx->extraChain == NULL) { + SAL_CERT_MgrCtxFree(newCtx); + return NULL; + } + } + + ret = StoreDup(newCtx, mgrCtx); + if (ret != HITLS_SUCCESS) { + SAL_CERT_MgrCtxFree(newCtx); + return NULL; + } + + newCtx->currentCertIndex = mgrCtx->currentCertIndex; + (void)memcpy_s(&newCtx->verifyParam, sizeof(HITLS_CertVerifyParam), + &mgrCtx->verifyParam, sizeof(HITLS_CertVerifyParam)); + newCtx->defaultPasswdCb = mgrCtx->defaultPasswdCb; + newCtx->defaultPasswdCbUserData = mgrCtx->defaultPasswdCbUserData; + newCtx->verifyCb = mgrCtx->verifyCb; + + return newCtx; +} + +void SAL_CERT_MgrCtxFree(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return; + } + SAL_CERT_ClearCertAndKey(mgrCtx); + SAL_CERT_ChainFree(mgrCtx->extraChain); + mgrCtx->extraChain = NULL; + SAL_CERT_StoreFree(mgrCtx, mgrCtx->verifyStore); + mgrCtx->verifyStore = NULL; + SAL_CERT_StoreFree(mgrCtx, mgrCtx->chainStore); + mgrCtx->chainStore = NULL; + SAL_CERT_StoreFree(mgrCtx, mgrCtx->certStore); + mgrCtx->certStore = NULL; + BSL_SAL_FREE(mgrCtx); + return; +} \ No newline at end of file diff --git a/tls/cert/cert_adapt/cert_mgr_ctrl.c b/tls/cert/cert_adapt/cert_mgr_ctrl.c new file mode 100644 index 00000000..02a04343 --- /dev/null +++ b/tls/cert/cert_adapt/cert_mgr_ctrl.c @@ -0,0 +1,444 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "cert_method.h" +#include "cert.h" +#include "cert_mgr_ctx.h" + +int32_t SAL_CERT_SetCertStore(CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + SAL_CERT_StoreFree(mgrCtx, mgrCtx->certStore); + mgrCtx->certStore = store; + return HITLS_SUCCESS; +} + +HITLS_CERT_Store *SAL_CERT_GetCertStore(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + + return mgrCtx->certStore; +} + +int32_t SAL_CERT_SetChainStore(CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + SAL_CERT_StoreFree(mgrCtx, mgrCtx->chainStore); + mgrCtx->chainStore = store; + return HITLS_SUCCESS; +} + +HITLS_CERT_Store *SAL_CERT_GetChainStore(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + + return mgrCtx->chainStore; +} + +int32_t SAL_CERT_SetVerifyStore(CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + SAL_CERT_StoreFree(mgrCtx, mgrCtx->verifyStore); + mgrCtx->verifyStore = store; + return HITLS_SUCCESS; +} + +HITLS_CERT_Store *SAL_CERT_GetVerifyStore(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + + return mgrCtx->verifyStore; +} + +int32_t SAL_CERT_SetCurrentCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isTlcpEncCert) +{ + if (cert == NULL || config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret; + HITLS_CERT_Key *pubkey = NULL; + ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15468, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set certificate error: unable to get pubkey.", 0, 0, 0, 0); + return ret; + } + + uint32_t keyType = TLS_CERT_KEY_TYPE_UNKNOWN; + ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_TYPE, NULL, (void *)&keyType); + SAL_CERT_KeyFree(mgrCtx, pubkey); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15419, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set certificate error: pubkey type unknown.", 0, 0, 0, 0); + return ret; + } + + uint32_t index = (isTlcpEncCert == false) ? keyType : keyType + 1; + if (index >= TLS_CERT_KEY_TYPE_NUM) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15420, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set certificate error: pubkey type = %u is invalid.", keyType, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_INVALID_KEY_TYPE); + return HITLS_CERT_ERR_INVALID_KEY_TYPE; + } + + CERT_Pair *certPair = &mgrCtx->certPair[index]; + if (certPair->privateKey != NULL) { + ret = SAL_CERT_CheckPrivateKey(config, cert, certPair->privateKey); + if (ret != HITLS_SUCCESS) { + /* If the certificate does not match the private key, release the private key. */ + SAL_CERT_KeyFree(mgrCtx, certPair->privateKey); + certPair->privateKey = NULL; + } + } + SAL_CERT_X509Free(certPair->cert); + certPair->cert = cert; + mgrCtx->currentCertIndex = keyType; + return HITLS_SUCCESS; +} + +HITLS_CERT_X509 *SAL_CERT_GetCurrentCert(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + uint32_t idx = mgrCtx->currentCertIndex; + if (idx >= TLS_CERT_KEY_TYPE_NUM) { + return NULL; + } + return mgrCtx->certPair[idx].cert; +} + +HITLS_CERT_X509 *SAL_CERT_GetCert(CERT_MgrCtx *mgrCtx, HITLS_CERT_KeyType keyType) +{ + if (mgrCtx == NULL) { + return NULL; + } + + if (keyType >= TLS_CERT_KEY_TYPE_NUM) { + return NULL; + } + + return mgrCtx->certPair[keyType].cert; +} + +int32_t SAL_CERT_SetCurrentPrivateKey(HITLS_Config *config, HITLS_CERT_Key *key, bool isTlcpEncCertPriKey) +{ + if (key == NULL || config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + uint32_t keyType = TLS_CERT_KEY_TYPE_UNKNOWN; + int32_t ret = SAL_CERT_KeyCtrl(config, key, CERT_KEY_CTRL_GET_TYPE, NULL, (void *)&keyType); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15421, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set private key error: key type unknown.", 0, 0, 0, 0); + return ret; + } + + uint32_t index = (isTlcpEncCertPriKey == false) ? keyType : keyType + 1; + if (index >= TLS_CERT_KEY_TYPE_NUM) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15338, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set private key error: key type = %u is invalid.", keyType, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_INVALID_KEY_TYPE); + return HITLS_CERT_ERR_INVALID_KEY_TYPE; + } + + CERT_Pair *certPair = &mgrCtx->certPair[index]; + if (certPair->cert != NULL) { + ret = SAL_CERT_CheckPrivateKey(config, certPair->cert, key); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15339, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set private key error: cert and key mismatch, key type = %u.", keyType, 0, 0, 0); + /* If the certificate does not match the private key, release the certificate. */ + SAL_CERT_X509Free(certPair->cert); + certPair->cert = NULL; + return ret; + } + } + SAL_CERT_KeyFree(mgrCtx, certPair->privateKey); + certPair->privateKey = key; + mgrCtx->currentCertIndex = keyType; + return HITLS_SUCCESS; +} + +HITLS_CERT_Key *SAL_CERT_GetCurrentPrivateKey(CERT_MgrCtx *mgrCtx, bool isTlcpEncCert) +{ + if (mgrCtx == NULL) { + return NULL; + } + uint32_t index = isTlcpEncCert ? mgrCtx->currentCertIndex + 1 : mgrCtx->currentCertIndex; + if (index >= TLS_CERT_KEY_TYPE_NUM) { + return NULL; + } + return mgrCtx->certPair[index].privateKey; +} + +HITLS_CERT_Key *SAL_CERT_GetPrivateKey(CERT_MgrCtx *mgrCtx, HITLS_CERT_KeyType keyType) +{ + if (mgrCtx == NULL) { + return NULL; + } + + if (keyType >= TLS_CERT_KEY_TYPE_NUM) { + return NULL; + } + + return mgrCtx->certPair[keyType].privateKey; +} + +int32_t SAL_CERT_AddChainCert(CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert) +{ + if (mgrCtx == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint32_t index = mgrCtx->currentCertIndex; + if (index >= TLS_CERT_KEY_TYPE_NUM) { + /* the certificate has not been loaded yet */ + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_ADD_CHAIN_CERT); + return HITLS_CERT_ERR_ADD_CHAIN_CERT; + } + + HITLS_CERT_Chain *newChain = NULL; + HITLS_CERT_Chain *chain = mgrCtx->certPair[index].chain; + if (chain == NULL) { + newChain = SAL_CERT_ChainNew(); + if (newChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + chain = newChain; + } + + int32_t ret = SAL_CERT_ChainAppend(chain, cert); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(newChain); + return ret; + } + mgrCtx->certPair[index].chain = chain; + return HITLS_SUCCESS; +} + +HITLS_CERT_Chain *SAL_CERT_GetCurrentChainCerts(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + + uint32_t id = mgrCtx->currentCertIndex; + if (id >= TLS_CERT_KEY_TYPE_NUM) { + return NULL; + } + + return mgrCtx->certPair[id].chain; +} + +void SAL_CERT_ClearCurrentChainCerts(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return; + } + + uint32_t index = mgrCtx->currentCertIndex; + if (index >= TLS_CERT_KEY_TYPE_NUM) { + /* the certificate has not been loaded yet */ + return; + } + + HITLS_CERT_Chain *chain = mgrCtx->certPair[index].chain; + if (chain == NULL) { + return; + } + SAL_CERT_ChainFree(chain); + mgrCtx->certPair[index].chain = NULL; + return; +} + +void SAL_CERT_ClearCertAndKey(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return; + } + + CERT_Pair *certPair = NULL; + for (uint32_t i = 0; i < TLS_CERT_KEY_TYPE_NUM; i++) { + certPair = &mgrCtx->certPair[i]; + SAL_CERT_PairClear(mgrCtx, certPair); + } + mgrCtx->currentCertIndex = TLS_CERT_KEY_TYPE_UNKNOWN; + return; +} + +int32_t SAL_CERT_AddExtraChainCert(CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert) +{ + if (mgrCtx == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Chain *newChain = NULL; + HITLS_CERT_Chain *chain = mgrCtx->extraChain; + if (chain == NULL) { + newChain = SAL_CERT_ChainNew(); + if (newChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + chain = newChain; + } + + int32_t ret = SAL_CERT_ChainAppend(chain, cert); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(newChain); + return ret; + } + mgrCtx->extraChain = chain; + return HITLS_SUCCESS; +} + +HITLS_CERT_Chain *SAL_CERT_GetExtraChainCerts(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + + return mgrCtx->extraChain; +} + +void SAL_CERT_ClearExtraChainCerts(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return; + } + + HITLS_CERT_Chain *chain = mgrCtx->extraChain; + if (chain == NULL) { + return; + } + SAL_CERT_ChainFree(chain); + mgrCtx->extraChain = NULL; + return; +} + +int32_t SAL_CERT_SetVerifyDepth(CERT_MgrCtx *mgrCtx, uint32_t depth) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + mgrCtx->verifyParam.verifyDepth = depth; + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_GetVerifyDepth(CERT_MgrCtx *mgrCtx, uint32_t *depth) +{ + if (mgrCtx == NULL || depth == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *depth = mgrCtx->verifyParam.verifyDepth; + return HITLS_SUCCESS; +} + +int32_t SAL_CERT_SetDefaultPasswordCb(CERT_MgrCtx *mgrCtx, HITLS_PasswordCb cb) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + mgrCtx->defaultPasswdCb = cb; + return HITLS_SUCCESS; +} + +HITLS_PasswordCb SAL_CERT_GetDefaultPasswordCb(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + return mgrCtx->defaultPasswdCb; +} + +int32_t SAL_CERT_SetDefaultPasswordCbUserdata(CERT_MgrCtx *mgrCtx, void *userdata) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + mgrCtx->defaultPasswdCbUserData = userdata; + return HITLS_SUCCESS; +} + +void *SAL_CERT_GetDefaultPasswordCbUserdata(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + return mgrCtx->defaultPasswdCbUserData; +} + +int32_t SAL_CERT_SetVerifyCb(CERT_MgrCtx *mgrCtx, HITLS_VerifyCb cb) +{ + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + mgrCtx->verifyCb = cb; + return HITLS_SUCCESS; +} + +HITLS_VerifyCb SAL_CERT_GetVerifyCb(CERT_MgrCtx *mgrCtx) +{ + if (mgrCtx == NULL) { + return NULL; + } + return mgrCtx->verifyCb; +} \ No newline at end of file diff --git a/tls/cert/cert_adapt/cert_mgr_ctx.h b/tls/cert/cert_adapt/cert_mgr_ctx.h new file mode 100644 index 00000000..8ea8989a --- /dev/null +++ b/tls/cert/cert_adapt/cert_mgr_ctx.h @@ -0,0 +1,79 @@ +/* + * 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 CERT_MGR_CTX_H +#define CERT_MGR_CTX_H + +#include +#include "hitls_cert_reg.h" +#include "cert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TLS_DEFAULT_VERIFY_DEPTH 20u + +struct CertVerifyParamInner { + uint32_t verifyDepth; /* depth of verify */ + uint32_t purpose; /* purpose to check untrusted certificates */ + uint32_t trust; /* trust setting to check */ +}; + +struct CertPairInner { + HITLS_CERT_X509 *cert; /* device certificate */ + /* encrypted device cert. Currently this field is used only when the peer-end encrypted certificate is stored. */ + HITLS_CERT_X509 *encCert; + HITLS_CERT_Key *privateKey; /* private key corresponding to the certificate */ + HITLS_CERT_Chain *chain; /* certificate chain */ +}; + +struct CertMgrCtxInner { + uint32_t currentCertIndex; /* points to the certificate in use. */ + /* Indicates the certificate resources on the link. Only one certificate of a type can be loaded. */ + CERT_Pair certPair[TLS_CERT_KEY_TYPE_NUM]; + HITLS_CERT_Chain *extraChain; + HITLS_CERT_Store *verifyStore; /* Verifies the store, which is used to verify the certificate chain. */ + HITLS_CERT_Store *chainStore; /* Certificate chain store, used to assemble the certificate chain */ + HITLS_CERT_Store *certStore; /* Default CA store */ + HITLS_CertVerifyParam verifyParam; /* Verification Parameters */ + HITLS_CERT_MgrMethod method; /* callback function */ + HITLS_PasswordCb defaultPasswdCb; /* Default password callback, used in loading certificate. */ + void *defaultPasswdCbUserData; /* Set the userData used by the default password callback. */ + HITLS_VerifyCb verifyCb; /* Certificate verification callback function */ +}; + +CERT_Type CertKeyType2CertType(HITLS_CERT_KeyType keyType); + +HITLS_CERT_KeyType SignScheme2CertKeyType(HITLS_SignHashAlgo signScheme); + +int32_t CheckSignScheme(HITLS_Ctx *ctx, const uint16_t *signSchemeList, uint32_t signSchemeNum, + HITLS_CERT_KeyType checkedKeyType, bool isNegotiateSignAlgo); + +int32_t CheckCurveName(HITLS_Config *config, const uint16_t *curveList, uint32_t curveNum, HITLS_CERT_Key *pubkey); + +int32_t CheckPointFormat(HITLS_Config *config, const uint8_t *ecPointFormatList, uint32_t listSize, + HITLS_CERT_Key *pubkey); + +/* These functions can be stored in a separate header file. */ +HITLS_CERT_Chain *SAL_CERT_ChainNew(void); +int32_t SAL_CERT_ChainAppend(HITLS_CERT_Chain *chain, HITLS_CERT_X509 *cert); +void SAL_CERT_ChainFree(HITLS_CERT_Chain *chain); +HITLS_CERT_Chain *SAL_CERT_ChainDup(CERT_MgrCtx *mgrCtx, HITLS_CERT_Chain *chain); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/tls/cert/cert_adapt/cert_pair.c b/tls/cert/cert_adapt/cert_pair.c new file mode 100644 index 00000000..7b2a4e15 --- /dev/null +++ b/tls/cert/cert_adapt/cert_pair.c @@ -0,0 +1,114 @@ +/* + * 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 "securec.h" +#include "bsl_sal.h" +#include "cert_method.h" +#include "cert_mgr.h" +#include "cert_mgr_ctx.h" + +HITLS_CERT_X509 *SAL_CERT_PairGetX509(CERT_Pair *certPair) +{ + if (certPair == NULL) { + return NULL; + } + return certPair->cert; +} + +HITLS_CERT_X509 *SAL_CERT_GetTlcpEncCert(CERT_Pair *certPair) +{ + if (certPair == NULL) { + return NULL; + } + return certPair->encCert; +} + +HITLS_CERT_Chain *SAL_CERT_PairGetChain(CERT_Pair *certPair) +{ + if (certPair == NULL) { + return NULL; + } + return certPair->chain; +} + +CERT_Pair *SAL_CERT_PairDup(CERT_MgrCtx *mgrCtx, CERT_Pair *srcCertPair) +{ + CERT_Pair *destCertPair = BSL_SAL_Calloc(1, sizeof(CERT_MgrCtx)); + if (destCertPair == NULL) { + return NULL; + } + + if (srcCertPair->cert != NULL) { + destCertPair->cert = SAL_CERT_X509Dup(mgrCtx, srcCertPair->cert); + if (destCertPair->cert == NULL) { + BSL_SAL_FREE(destCertPair); + return NULL; + } + } + + if (srcCertPair->privateKey != NULL) { + destCertPair->privateKey = SAL_CERT_KeyDup(mgrCtx, srcCertPair->privateKey); + if (destCertPair->privateKey == NULL) { + SAL_CERT_X509Free(destCertPair->cert); + BSL_SAL_FREE(destCertPair); + return NULL; + } + } + + if (srcCertPair->chain != NULL) { + destCertPair->chain = SAL_CERT_ChainDup(mgrCtx, srcCertPair->chain); + if (destCertPair->chain == NULL) { + SAL_CERT_X509Free(destCertPair->cert); + SAL_CERT_KeyFree(mgrCtx, destCertPair->privateKey); + BSL_SAL_FREE(destCertPair); + return NULL; + } + } + + return destCertPair; +} + +void SAL_CERT_PairClear(CERT_MgrCtx *mgrCtx, CERT_Pair *certPair) +{ + if (mgrCtx == NULL || certPair == NULL) { + return; + } + + if (certPair->cert != NULL) { + SAL_CERT_X509Free(certPair->cert); + } + + if (certPair->encCert != NULL) { + SAL_CERT_X509Free(certPair->encCert); + } + + if (certPair->privateKey != NULL) { + SAL_CERT_KeyFree(mgrCtx, certPair->privateKey); + } + + if (certPair->chain != NULL) { + SAL_CERT_ChainFree(certPair->chain); + } + + (void)memset_s(certPair, sizeof(CERT_Pair), 0, sizeof(CERT_Pair)); + return; +} + +void SAL_CERT_PairFree(CERT_MgrCtx *mgrCtx, CERT_Pair *certPair) +{ + SAL_CERT_PairClear(mgrCtx, certPair); + BSL_SAL_FREE(certPair); + return; +} \ No newline at end of file diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_adapt_local.h b/tls/cert/hitls_x509_adapt/hitls_x509_adapt_local.h new file mode 100644 index 00000000..28e0e112 --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_adapt_local.h @@ -0,0 +1,72 @@ +/* + * 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_X509_ADAPT_LOCAL_H +#define HITLS_X509_ADAPT_LOCAL_H + +#include +#include "hitls_type.h" +#include "hitls_cert.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_PASS_LEN 64 + +HITLS_CERT_Store *HITLS_X509_Adapt_StoreNew(void); +HITLS_CERT_Store *HITLS_X509_Adapt_StoreDup(HITLS_CERT_Store *store); +void HITLS_X509_Adapt_StoreFree(HITLS_CERT_Store *store); +int32_t HITLS_X509_Adapt_StoreCtrl(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_CtrlCmd cmd, + void *input, void *output); + +int32_t HITLS_X509_Adapt_BuildCertChain(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_X509 *cert, + HITLS_CERT_X509 **list, uint32_t *num); +int32_t HITLS_X509_Adapt_VerifyCertChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store, HITLS_CERT_X509 **list, uint32_t num); + +int32_t HITLS_X509_Adapt_CertEncode(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t len, + uint32_t *usedLen); +HITLS_CERT_X509 *HITLS_X509_Adapt_CertParse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format); +HITLS_CERT_X509 *HITLS_X509_Adapt_CertDup(HITLS_CERT_X509 *cert); +HITLS_CERT_X509 *HITLS_X509_Adapt_CertRef(HITLS_CERT_X509 *cert); +void HITLS_X509_Adapt_CertFree(HITLS_CERT_X509 *cert); +int32_t HITLS_X509_Adapt_CertCtrl(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd cmd, + void *input, void *output); + +HITLS_CERT_Key *HITLS_X509_Adapt_KeyParse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format); +HITLS_CERT_Key *HITLS_X509_Adapt_KeyDup(HITLS_CERT_Key *key); +void HITLS_X509_Adapt_KeyFree(HITLS_CERT_Key *key); +int32_t HITLS_X509_Adapt_KeyCtrl(HITLS_Config *config, HITLS_CERT_Key *key, HITLS_CERT_CtrlCmd cmd, + void *input, void *output); + +int32_t HITLS_X509_Adapt_CreateSign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, HITLS_SignAlgo signAlgo, + HITLS_HashAlgo hashAlgo, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen); +int32_t HITLS_X509_Adapt_VerifySign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, HITLS_SignAlgo signAlgo, + HITLS_HashAlgo hashAlgo, const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen); +int32_t HITLS_X509_Adapt_Encrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); +int32_t HITLS_X509_Adapt_Decrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); +int32_t HITLS_X509_Adapt_CheckPrivateKey(const HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_Key *key); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_X509_ADAPT_LOCAL_H \ No newline at end of file diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_cert_chain.c b/tls/cert/hitls_x509_adapt/hitls_x509_cert_chain.c new file mode 100644 index 00000000..4d47fc92 --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_cert_chain.c @@ -0,0 +1,106 @@ +/* + * 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 +#include "bsl_err_internal.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" +#include "hitls_x509.h" +#include "bsl_list.h" +#include "hitls_error.h" + +static int32_t BuildArrayFromList(HITLS_X509_List *list, HITLS_CERT_X509 **listArray, uint32_t *num) +{ + HITLS_X509_Cert *elemt = NULL; + int32_t i = 0; + int32_t ret; + for (list->curr = list->first; list->curr != NULL; list->curr = list->curr->next, i++) { + elemt = (HITLS_X509_Cert *)list->curr->data; + if (elemt == NULL || i >= list->count) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ADAPT_BUILD_CERT_CHAIN_ERR); + return HITLS_X509_ADAPT_BUILD_CERT_CHAIN_ERR; + } + + int ref = 0; + ret = HITLS_X509_CertCtrl(elemt, HITLS_X509_REF_UP, (void *)&ref, (int32_t)sizeof(int)); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + listArray[i] = elemt; + } + + *num = i; + return HITLS_SUCCESS; +} + +static int32_t BuildCertListFromCertArray(HITLS_CERT_X509 **listCert, uint32_t num, HITLS_X509_List **list) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_X509_Cert **listArray = (HITLS_X509_Cert **)listCert; + *list = BSL_LIST_New(num); + if (*list == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + for (uint32_t i = 0; i < num; i++) { + int ref = 0; + ret = HITLS_X509_CertCtrl(listArray[i], HITLS_X509_REF_UP, (void *)&ref, (int32_t)sizeof(int)); + if (ret != HITLS_SUCCESS) { + BSL_LIST_FREE(*list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + ret = BSL_LIST_AddElement(*list, listArray[i], BSL_LIST_POS_END); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_LIST_FREE(*list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + } + return HITLS_SUCCESS; +} + +int32_t HITLS_X509_Adapt_BuildCertChain(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_X509 *cert, + HITLS_CERT_X509 **list, uint32_t *num) +{ + (void)config; + *num = 0; + HITLS_X509_List *certChain = NULL; + int32_t ret = HITLS_X509_CertChainBuild((HITLS_X509_StoreCtx *)store, cert, &certChain); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = BuildArrayFromList(certChain, list, num); + BSL_LIST_FREE(certChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; +} + +int32_t HITLS_X509_Adapt_VerifyCertChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store, HITLS_CERT_X509 **list, uint32_t num) +{ + (void)ctx; + HITLS_X509_List *certList = NULL; + int32_t ret = BuildCertListFromCertArray(list, num, &certList); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = HITLS_X509_CertVerify((HITLS_X509_StoreCtx *)store, certList); + if (ret != HITLS_SUCCESS) { + BSL_LIST_FREE(certList, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + + BSL_LIST_FREE(certList, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return HITLS_SUCCESS; +} diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_cert_magr.c b/tls/cert/hitls_x509_adapt/hitls_x509_cert_magr.c new file mode 100644 index 00000000..644257e1 --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_cert_magr.c @@ -0,0 +1,231 @@ +/* + * 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 +#include "securec.h" +#include "crypt_eal_pkey.h" +#include "hitls_error.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" +#include "hitls_x509.h" +#include "hitls_cert_local.h" +#include "hitls_error.h" +#include "bsl_err_internal.h" + +int32_t HITLS_X509_Adapt_CertEncode(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t len, + uint32_t *usedLen) +{ + (void)ctx; + *usedLen = 0; + uint32_t encodeLen = 0; + int32_t ret = HITLS_X509_CertCtrl((HITLS_X509_Cert *)cert, HITLS_X509_GET_ENCODELEN, &encodeLen, + (int32_t)sizeof(uint32_t)); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (len < encodeLen) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + uint8_t *encodedBuff = NULL; + ret = HITLS_X509_CertCtrl((HITLS_X509_Cert *)cert, HITLS_X509_GET_ENCODE, (void *)&encodedBuff, 0); + if (ret != HITLS_SUCCESS) { + return ret; + } + + (void)memcpy_s(buf, len, encodedBuff, encodeLen); + *usedLen = encodeLen; + return ret; +} + +static BSL_ParseFormat GetBslParseFormat(HITLS_ParseFormat format) +{ + typedef struct { + HITLS_ParseFormat hitlsFormat; + BSL_ParseFormat bslFormat; + } ParseFormatMap; + static ParseFormatMap formatMap[]= { + {TLS_PARSE_FORMAT_PEM, BSL_FORMAT_PEM}, + {TLS_PARSE_FORMAT_ASN1, BSL_FORMAT_ASN1} + }; + for (size_t i = 0; i < sizeof(formatMap) / sizeof(formatMap[0]); i++) { + if (formatMap[i].hitlsFormat == format) { + return formatMap[i].bslFormat; + } + } + + return BSL_FORMAT_UNKNOWN; +} + +HITLS_CERT_X509 *HITLS_X509_Adapt_CertParse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format) +{ + (void)config; + BSL_Buffer encodedCert = { NULL, 0 }; + BSL_ParseFormat bslFormat = GetBslParseFormat(format); + int ret = HITLS_X509_ADAPT_ERR; + HITLS_X509_Cert *cert = NULL; + switch (type) { + case TLS_PARSE_TYPE_FILE: + ret = HITLS_X509_CertParseFile(bslFormat, (const char *)buf, &cert); + break; + case TLS_PARSE_TYPE_BUFF: + encodedCert.data = (uint8_t *)BSL_SAL_Calloc(len, (uint32_t)sizeof(uint8_t)); + if (encodedCert.data == NULL) { + ret = HITLS_MEMALLOC_FAIL; + break; + } + (void)memcpy_s(encodedCert.data, len, buf, len); + encodedCert.dataLen = len; + ret = HITLS_X509_CertParseBuff(bslFormat, &encodedCert, &cert); + break; + default: + break; + } + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(encodedCert.data); + return NULL; + } + + BSL_SAL_FREE(encodedCert.data); + return cert; +} + +HITLS_CERT_X509 *HITLS_X509_Adapt_CertDup(HITLS_CERT_X509 *cert) +{ + HITLS_X509_Cert *dest = NULL; + int32_t ret = HITLS_X509_CertDup(cert, &dest); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + + return dest; +} + +void HITLS_X509_Adapt_CertFree(HITLS_CERT_X509 *cert) +{ + HITLS_X509_CertFree(cert); +} + +HITLS_CERT_X509 *HITLS_X509_Adapt_CertRef(HITLS_CERT_X509 *cert) +{ + int ref = 0; + int ret = HITLS_X509_CertCtrl(cert, HITLS_X509_REF_UP, (void *)&ref, (int32_t)sizeof(int)); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + return cert; +} + +static HITLS_SignHashAlgo BslCid2SignHashAlgo(BslCid cid) +{ + typedef struct { + BslCid cid; + HITLS_SignHashAlgo signHashAlg; + } SignHashMap; + static SignHashMap signMap[] = { + { BSL_CID_SHA1WITHRSA, CERT_SIG_SCHEME_RSA_PKCS1_SHA1 }, + { BSL_CID_SHA224WITHRSAENCRYPTION, CERT_SIG_SCHEME_RSA_PKCS1_SHA224 }, + { BSL_CID_SHA256WITHRSAENCRYPTION, CERT_SIG_SCHEME_RSA_PKCS1_SHA256 }, + { BSL_CID_SHA384WITHRSAENCRYPTION, CERT_SIG_SCHEME_RSA_PKCS1_SHA384 }, + { BSL_CID_SHA512WITHRSAENCRYPTION, CERT_SIG_SCHEME_RSA_PKCS1_SHA512 }, + { BSL_CID_RSASSAPSS, CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256 }, + { BSL_CID_ECDSAWITHSHA1, CERT_SIG_SCHEME_ECDSA_SHA1 }, + { BSL_CID_ECDSAWITHSHA224, CERT_SIG_SCHEME_ECDSA_SHA224 }, + { BSL_CID_ECDSAWITHSHA256, CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256 }, + { BSL_CID_ECDSAWITHSHA384, CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384 }, + { BSL_CID_ECDSAWITHSHA512, CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512 }, +#ifndef HITLS_NO_TLCP11 + { BSL_CID_SM2DSAWITHSM3, CERT_SIG_SCHEME_SM2_SM3 }, +#endif + { BSL_CID_ED25519, CERT_SIG_SCHEME_ED25519 }, + { BSL_CID_DSAWITHSHA1, CERT_SIG_SCHEME_DSA_SHA1 }, + { BSL_CID_DSAWITHSHA224, CERT_SIG_SCHEME_DSA_SHA224 }, + { BSL_CID_DSAWITHSHA256, CERT_SIG_SCHEME_DSA_SHA256 }, + { BSL_CID_DSAWITHSHA384, CERT_SIG_SCHEME_DSA_SHA384 }, + { BSL_CID_DSAWITHSHA512, CERT_SIG_SCHEME_DSA_SHA512 }, + }; + for (size_t i = 0; i < sizeof(signMap) / sizeof(signMap[0]); i++) { + if (signMap[i].cid == cid) { + return signMap[i].signHashAlg; + } + } + + return CERT_SIG_SCHEME_UNKNOWN; + +} + +static int32_t CertCtrlGetSignAlgo(HITLS_CERT_X509 *cert, HITLS_SignHashAlgo *algSign) +{ + BslCid tmpCid = 0; + *algSign = CERT_SIG_SCHEME_UNKNOWN; + int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SIGNALG, &tmpCid, sizeof(BslCid)); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + *algSign = BslCid2SignHashAlgo(tmpCid); + return HITLS_SUCCESS; +} + +int32_t HITLS_X509_Adapt_CertCtrl(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd cmd, + void *input, void *output) +{ + (void)config; + (void)input; + int32_t valLen = sizeof(int32_t); + int32_t x509Cmd = 0; + switch (cmd) { + case CERT_CTRL_GET_ENCODE_LEN: + x509Cmd = HITLS_X509_GET_ENCODELEN; + break; + case CERT_CTRL_GET_PUB_KEY: + valLen = (int32_t)sizeof(CRYPT_EAL_PkeyPub *); + x509Cmd = HITLS_X509_GET_PUBKEY; + break; + case CERT_CTRL_GET_SIGN_ALGO: + return CertCtrlGetSignAlgo(cert, (HITLS_SignHashAlgo *)output); + case CERT_KEY_CTRL_IS_KEYENC_USAGE: + valLen = (int32_t)sizeof(uint8_t); + x509Cmd = HITLS_X509_EXT_KU_KEYENC; + break; + case CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE: + valLen = (int32_t)sizeof(uint8_t); + x509Cmd = HITLS_X509_EXT_KU_DIGITALSIGN; + break; + case CERT_KEY_CTRL_IS_KEY_CERT_SIGN_USAGE: + valLen = (int32_t)sizeof(uint8_t); + x509Cmd = HITLS_X509_EXT_KU_CERTSIGN; + break; + case CERT_KEY_CTRL_IS_KEY_AGREEMENT_USAGE: + valLen = (int32_t)sizeof(uint8_t); + x509Cmd = HITLS_X509_EXT_KU_KEYAGREEMENT; + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ADAPT_ERR); + return HITLS_X509_ADAPT_ERR; + } + int32_t ret = HITLS_X509_CertCtrl(cert, x509Cmd, output, valLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + return ret; +} diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_cert_store.c b/tls/cert/hitls_x509_adapt/hitls_x509_cert_store.c new file mode 100644 index 00000000..d691f20e --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_cert_store.c @@ -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. + */ + +#include +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" +#include "hitls_cert_local.h" +#include "hitls_x509.h" +#include "hitls_error.h" +#include "hitls_x509_adapt_local.h" + +HITLS_CERT_Store *HITLS_X509_Adapt_StoreNew(void) +{ + return (HITLS_CERT_Store *)HITLS_X509_StoreCtxNew(); +} + +HITLS_CERT_Store *HITLS_X509_Adapt_StoreDup(HITLS_CERT_Store *store) +{ + int references = 0; + int32_t ret = HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store, HITLS_X509_STORECTX_REF_UP, &references, + sizeof(int)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + + return store; +} + +void HITLS_X509_Adapt_StoreFree(HITLS_CERT_Store *store) +{ + HITLS_X509_StoreCtxFree(store); +} + +int32_t HITLS_X509_Adapt_StoreCtrl(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_CtrlCmd cmd, + void *input, void *output) +{ + (void)config; + (void)output; + int32_t inputLen = 0; + int32_t x509Cmd; + switch (cmd) { + case CERT_STORE_CTRL_SET_VERIFY_DEPTH: + x509Cmd = HITLS_X509_STORECTX_SET_PARAM_DEPTH; + inputLen = sizeof(int32_t); + break; + case CERT_STORE_CTRL_DEEP_COPY_ADD_CERT_LIST: + x509Cmd = HITLS_X509_STORECTX_DEEP_COPY_SET_CA; + inputLen = sizeof(HITLS_X509_Cert); + break; + case CERT_STORE_CTRL_SHALLOW_COPY_ADD_CERT_LIST: + x509Cmd = HITLS_X509_STORECTX_SHALLOW_COPY_SET_CA; + inputLen = sizeof(HITLS_X509_Cert); + break; + default: + return HITLS_X509_ADAPT_ERR; + } + + return HITLS_X509_StoreCtxCtrl(store, x509Cmd, input, inputLen); +} diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_crypto.c b/tls/cert/hitls_x509_adapt/hitls_x509_crypto.c new file mode 100644 index 00000000..98e07332 --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_crypto.c @@ -0,0 +1,166 @@ +/* + * 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 +#include +#include "crypt_types.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls_x509.h" +#include "hitls_cert_type.h" +#include "hitls_crypt_type.h" +#include "crypt_algid.h" +#include "crypt_eal_pkey.h" + +CRYPT_MD_AlgId GetCryptHashAlgFromCertHashAlg(HITLS_HashAlgo hashAlgo) +{ + typedef struct { + HITLS_HashAlgo certHashAlg; + CRYPT_MD_AlgId cryptMdAlgId; + } CertHashAlgoMap; + CertHashAlgoMap hashAlgMap[] = { + { HITLS_HASH_SHA_224, CRYPT_MD_SHA224 }, + { HITLS_HASH_SHA_256, CRYPT_MD_SHA256 }, + { HITLS_HASH_SHA_384, CRYPT_MD_SHA384 }, + { HITLS_HASH_SHA_512, CRYPT_MD_SHA512 }, + { HITLS_HASH_MD5, CRYPT_MD_MD5 }, + { HITLS_HASH_SHA1, CRYPT_MD_SHA1 }, + { HITLS_HASH_SM3, CRYPT_MD_SM3 }, + }; + for (size_t i = 0; i < sizeof(hashAlgMap) / sizeof(hashAlgMap[0]); i++) { + if (hashAlgMap[i].certHashAlg == hashAlgo) { + return hashAlgMap[i].cryptMdAlgId; + } + } + return CRYPT_MD_MAX; +} + +static int32_t CertSetRsaEmsa(CRYPT_EAL_PkeyCtx *ctx, HITLS_SignAlgo signAlgo, CRYPT_MD_AlgId mdAlgId) +{ + if (signAlgo == HITLS_SIGN_RSA_PKCS1_V15) { + CRYPT_RSA_PkcsV15Para pad = { .mdId = mdAlgId }; + if (CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pad, sizeof(CRYPT_RSA_PkcsV15Para)) + != CRYPT_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + } else if (signAlgo == HITLS_SIGN_RSA_PSS_PSS || signAlgo == HITLS_SIGN_RSA_PSS_RSAE) { + CRYPT_RSA_PssPara pad = { + .mdId = mdAlgId, + .mgfId = mdAlgId, + .saltLen = -1, + }; + if (CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_EMSA_PSS, &pad, sizeof(CRYPT_RSA_PssPara)) != CRYPT_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + } + + return HITLS_SUCCESS; +} + +static int32_t SignOrVerifySignPre(CRYPT_EAL_PkeyCtx *ctx, HITLS_SignAlgo signAlgo, HITLS_HashAlgo hashAlgo, + CRYPT_MD_AlgId *mdAlgId) +{ + *mdAlgId = GetCryptHashAlgFromCertHashAlg(hashAlgo); + if (*mdAlgId == CRYPT_MD_MAX) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ADAPT_ERR); + return HITLS_X509_ADAPT_ERR; + } + if (CertSetRsaEmsa(ctx, signAlgo, *mdAlgId) != HITLS_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_X509_Adapt_CreateSign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, HITLS_SignAlgo signAlgo, + HITLS_HashAlgo hashAlgo, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen) +{ + (void)ctx; + CRYPT_MD_AlgId mdAlgId = CRYPT_MD_MAX; + if (SignOrVerifySignPre(key, signAlgo, hashAlgo, &mdAlgId) != HITLS_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + return CRYPT_EAL_PkeySign(key, mdAlgId, data, dataLen, sign, signLen); +} + +int32_t HITLS_X509_Adapt_VerifySign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, HITLS_SignAlgo signAlgo, + HITLS_HashAlgo hashAlgo, const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen) +{ + (void)ctx; + CRYPT_MD_AlgId mdAlgId = CRYPT_MD_MAX; + if (SignOrVerifySignPre(key, signAlgo, hashAlgo, &mdAlgId) != HITLS_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + return CRYPT_EAL_PkeyVerify(key, mdAlgId, data, dataLen, sign, signLen); +} + +static int32_t CertSetRsaEncryptionScheme(CRYPT_EAL_PkeyCtx *ctx) +{ + CRYPT_RSA_PkcsV15Para pad = { + .mdId = CRYPT_MD_SHA256, + }; + if (CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_RSAES_PKCSV15, &pad, sizeof(CRYPT_RSA_PkcsV15Para)) + != HITLS_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + return HITLS_SUCCESS; +} + +/* only support rsa pkcs1.5 */ +int32_t HITLS_X509_Adapt_Encrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + (void)ctx; + if (CRYPT_EAL_PkeyGetId(key) == CRYPT_PKEY_RSA && CertSetRsaEncryptionScheme(key) != HITLS_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + + return CRYPT_EAL_PkeyEncrypt(key, in, inLen, out, outLen); +} + + +int32_t HITLS_X509_Adapt_Decrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + (void)ctx; + if (CRYPT_EAL_PkeyGetId(key) == CRYPT_PKEY_RSA && CertSetRsaEncryptionScheme(key) != HITLS_SUCCESS) { + return HITLS_X509_ADAPT_ERR; + } + + return CRYPT_EAL_PkeyDecrypt(key, in, inLen, out, outLen); +} + +int32_t HITLS_X509_Adapt_CheckPrivateKey(const HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_Key *key) +{ + (void)config; + CRYPT_EAL_PkeyCtx *ealPubKey = NULL; + CRYPT_EAL_PkeyCtx *ealPrivKey = (CRYPT_EAL_PkeyCtx *)key; + int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_PUBKEY, &ealPubKey, 0); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = CRYPT_EAL_PkeyPairCheck(ealPubKey, ealPrivKey); + CRYPT_EAL_PkeyFreeCtx(ealPubKey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return HITLS_SUCCESS; +} diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_init.c b/tls/cert/hitls_x509_adapt/hitls_x509_init.c new file mode 100644 index 00000000..356b0b99 --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_init.c @@ -0,0 +1,59 @@ +/* + * 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 +#include +#include "hitls_error.h" +#include "hitls_cert_reg.h" +#include "hitls_x509_adapt_local.h" + +int32_t HITLS_CertMethodInit(void) +{ + HITLS_CERT_MgrMethod mgr = { + .certStoreNew = HITLS_X509_Adapt_StoreNew, + .certStoreDup = HITLS_X509_Adapt_StoreDup, + .certStoreFree = HITLS_X509_Adapt_StoreFree, + .certStoreCtrl = HITLS_X509_Adapt_StoreCtrl, + .buildCertChain = HITLS_X509_Adapt_BuildCertChain, + .verifyCertChain = HITLS_X509_Adapt_VerifyCertChain, + + .certEncode = HITLS_X509_Adapt_CertEncode, + .certParse = HITLS_X509_Adapt_CertParse, + .certDup = HITLS_X509_Adapt_CertDup, + .certRef = HITLS_X509_Adapt_CertRef, + .certFree = HITLS_X509_Adapt_CertFree, + .certCtrl = HITLS_X509_Adapt_CertCtrl, + + .keyParse = HITLS_X509_Adapt_KeyParse, + .keyDup = HITLS_X509_Adapt_KeyDup, + .keyFree = HITLS_X509_Adapt_KeyFree, + .keyCtrl = HITLS_X509_Adapt_KeyCtrl, + + .createSign = HITLS_X509_Adapt_CreateSign, + .verifySign = HITLS_X509_Adapt_VerifySign, + .encrypt = HITLS_X509_Adapt_Encrypt, + .decrypt = HITLS_X509_Adapt_Decrypt, + + .checkPrivateKey = HITLS_X509_Adapt_CheckPrivateKey, + }; + + return HITLS_CERT_RegisterMgrMethod(&mgr); +} + +int32_t HITLS_CertMethodDeInit(void) +{ + HITLS_CERT_DeinitMgrMethod(); + return HITLS_SUCCESS; +} diff --git a/tls/cert/hitls_x509_adapt/hitls_x509_pkey_magr.c b/tls/cert/hitls_x509_adapt/hitls_x509_pkey_magr.c new file mode 100644 index 00000000..de2fc596 --- /dev/null +++ b/tls/cert/hitls_x509_adapt/hitls_x509_pkey_magr.c @@ -0,0 +1,326 @@ +/* + * 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 +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_type.h" +#include "bsl_err_internal.h" +#include "hitls_x509_adapt_local.h" +#include "crypt_eal_encode.h" +#include "crypt_errno.h" +#include "hitls_cert.h" +#include "hitls_cert_type.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "crypt_eal_pkey.h" +#include "hitls_crypt_type.h" + +static int32_t g_tryTypes[] = { CRYPT_PRIKEY_PKCS8_UNENCRYPT, CRYPT_PRIKEY_PKCS8_ENCRYPT, CRYPT_PRIKEY_RSA, + CRYPT_PRIKEY_ECC }; + +static int32_t GetPassByCb(HITLS_PasswordCb passWordCb, void *passWordCbUserData, char *pass, int32_t *passLen) +{ + if (pass == NULL || passLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + int32_t len = 0; + if (passWordCb != NULL) { + len = passWordCb(pass, *passLen, 0, passWordCbUserData); + if (len < 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ADAPT_ERR); + return HITLS_X509_ADAPT_ERR; + } + } else { + if (passWordCbUserData != NULL) { + uint32_t userDataLen = BSL_SAL_Strnlen((const char *)passWordCbUserData, *passLen); + if (userDataLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ADAPT_ERR); + return HITLS_X509_ADAPT_ERR; + } + (void)memcpy_s(pass, *passLen, (char *)passWordCbUserData, userDataLen + 1); + len = userDataLen; + } + } + + *passLen = len; + return HITLS_SUCCESS; +} + +static int32_t GetPrivKeyPassword(HITLS_Config *config, uint8_t *pwd, int32_t *pwdLen) +{ + HITLS_PasswordCb pwCb = HITLS_CFG_GetDefaultPasswordCb(config); + void *userData = HITLS_CFG_GetDefaultPasswordCbUserdata(config); + int32_t len = *pwdLen; + int32_t ret = GetPassByCb(pwCb, userData, (char *)pwd, pwdLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + (void)memset_s(pwd, len, 0, len); + return ret; + } + return HITLS_SUCCESS; +} + +static HITLS_CERT_Key *HitlsPrivKeyBuffAsn1Parse(HITLS_Config *config, BSL_Buffer *encode) +{ + HITLS_CERT_Key *ealPriKey = NULL; + uint8_t pwd[MAX_PASS_LEN] = { 0 }; + uint32_t pwdLen = MAX_PASS_LEN; + int32_t ret; + for (size_t i = 0; i < sizeof(g_tryTypes) / sizeof(g_tryTypes[0]); i++) { + if (g_tryTypes[i] == CRYPT_PRIKEY_PKCS8_ENCRYPT) { + if (GetPrivKeyPassword(config, pwd, (int32_t *)&pwdLen) != HITLS_SUCCESS) { + continue; + } + } + ret = CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_ASN1, g_tryTypes[i], encode, pwd, pwdLen, + (CRYPT_EAL_PkeyCtx **)&ealPriKey); + if (ret == HITLS_SUCCESS) { + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return ealPriKey; + } + } + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return NULL; +} + +static HITLS_CERT_Key *HitlsPrivKeyBuffPemParse(HITLS_Config *config, BSL_Buffer *encode) +{ + HITLS_CERT_Key *ealPriKey = NULL; + uint8_t pwd[MAX_PASS_LEN] = { 0 }; + uint32_t pwdLen = MAX_PASS_LEN; + int32_t ret; + for (size_t i = 0; i < sizeof(g_tryTypes) / sizeof(g_tryTypes[0]); i++) { + if (g_tryTypes[i] == CRYPT_PRIKEY_PKCS8_ENCRYPT) { + if (GetPrivKeyPassword(config, pwd, (int32_t *)&pwdLen) != HITLS_SUCCESS) { + continue; + } + } + ret = CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_PEM, g_tryTypes[i], encode, pwd, pwdLen, + (CRYPT_EAL_PkeyCtx **)&ealPriKey); + if (ret == HITLS_SUCCESS) { + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return ealPriKey; + } + } + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return NULL; +} + +static HITLS_CERT_Key *HitlsPrivKeyFileAsn1Parse(HITLS_Config *config, const uint8_t *buf) +{ + HITLS_CERT_Key *ealPriKey = NULL; + uint8_t pwd[MAX_PASS_LEN] = { 0 }; + uint32_t pwdLen = MAX_PASS_LEN; + for (size_t i = 0; i < sizeof(g_tryTypes) / sizeof(g_tryTypes[0]); i++) { + if (g_tryTypes[i] == CRYPT_PRIKEY_PKCS8_ENCRYPT) { + if (GetPrivKeyPassword(config, pwd, (int32_t *)&pwdLen) != HITLS_SUCCESS) { + continue; + } + } + int ret = CRYPT_EAL_DecodeFileKey(BSL_FORMAT_ASN1, g_tryTypes[i], (const char *)buf, pwd, pwdLen, + (CRYPT_EAL_PkeyCtx **)&ealPriKey); + if (ret == HITLS_SUCCESS) { + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return ealPriKey; + } + } + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return NULL; +} + +static HITLS_CERT_Key *HitlsPrivKeyFilePemParse(HITLS_Config *config, const uint8_t *buf) +{ + HITLS_CERT_Key *ealPriKey = NULL; + uint8_t pwd[MAX_PASS_LEN] = { 0 }; + uint32_t pwdLen = MAX_PASS_LEN; + for (size_t i = 0; i < sizeof(g_tryTypes) / sizeof(g_tryTypes[0]); i++) { + if (g_tryTypes[i] == CRYPT_PRIKEY_PKCS8_ENCRYPT) { + if (GetPrivKeyPassword(config, pwd, (int32_t *)&pwdLen) != HITLS_SUCCESS) { + continue; + } + } + int ret = CRYPT_EAL_DecodeFileKey(BSL_FORMAT_PEM, g_tryTypes[i], (const char *)buf, pwd, pwdLen, + (CRYPT_EAL_PkeyCtx **)&ealPriKey); + if (ret == HITLS_SUCCESS) { + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return ealPriKey; + } + } + (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN); + return NULL; +} + +static HITLS_CERT_Key *HitlsPrivKeyBuffParse(HITLS_Config *config, int32_t format, BSL_Buffer *encode) +{ + switch (format) { + case TLS_PARSE_FORMAT_PEM: + return HitlsPrivKeyBuffPemParse(config, encode); + case TLS_PARSE_FORMAT_ASN1: + return HitlsPrivKeyBuffAsn1Parse(config, encode); + default: + return NULL; + } +} + +static HITLS_CERT_Key *HitlsPrivKeyFileParse(HITLS_Config *config, int32_t format, const uint8_t *buf) +{ + switch (format) { + case TLS_PARSE_FORMAT_PEM: + return HitlsPrivKeyFilePemParse(config, buf); + case TLS_PARSE_FORMAT_ASN1: + return HitlsPrivKeyFileAsn1Parse(config, buf); + default: + return NULL; + } +} + +HITLS_CERT_Key *HITLS_X509_Adapt_KeyParse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format) +{ + BSL_Buffer encode = {}; + HITLS_CERT_Key *certKey = NULL; + encode.data = (uint8_t *)BSL_SAL_Calloc(len, sizeof(uint8_t)); + if (encode.data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + (void)memcpy_s(encode.data, len, buf, len); + encode.dataLen = len; + switch (type) { + case TLS_PARSE_TYPE_FILE: + certKey = HitlsPrivKeyFileParse(config, format, buf); + break; + case TLS_PARSE_TYPE_BUFF: + certKey = HitlsPrivKeyBuffParse(config, format, &encode); + break; + default: + break;; + } + BSL_SAL_FREE(encode.data); + return certKey; +} + +HITLS_CERT_Key *HITLS_X509_Adapt_KeyDup(HITLS_CERT_Key *key) +{ + return (HITLS_CERT_Key *)CRYPT_EAL_PkeyDupCtx(key); +} + +void HITLS_X509_Adapt_KeyFree(HITLS_CERT_Key *key) +{ + CRYPT_EAL_PkeyFreeCtx(key); +} + +static HITLS_NamedGroup GetCurveNameByParaId(CRYPT_PKEY_ParaId paraId) +{ + typedef struct { + CRYPT_PKEY_ParaId paraId; + HITLS_NamedGroup curveName; + } CertKeyCurveNameMap; + static CertKeyCurveNameMap curveNameMap[] = { + { CRYPT_ECC_NISTP256, HITLS_EC_GROUP_SECP256R1 }, + { CRYPT_ECC_NISTP384, HITLS_EC_GROUP_SECP384R1 }, + { CRYPT_ECC_NISTP521, HITLS_EC_GROUP_SECP521R1 }, + { CRYPT_ECC_BRAINPOOLP256R1, HITLS_EC_GROUP_BRAINPOOLP256R1 }, + { CRYPT_ECC_BRAINPOOLP384R1, HITLS_EC_GROUP_BRAINPOOLP384R1 }, + { CRYPT_ECC_BRAINPOOLP512R1, HITLS_EC_GROUP_BRAINPOOLP512R1 }, + }; + for (size_t i = 0; i < sizeof(curveNameMap) / sizeof(curveNameMap[0]); i++) { + if (curveNameMap[i].paraId == paraId) { + return curveNameMap[i].curveName; + } + } + return HITLS_NAMED_GROUP_BUTT; +} + +static HITLS_NamedGroup GetCurveNameByKey(const CRYPT_EAL_PkeyCtx *key) +{ + CRYPT_PKEY_AlgId cid = CRYPT_EAL_PkeyGetId(key); + if (cid == CRYPT_PKEY_X25519) { + return HITLS_EC_GROUP_CURVE25519; + } + if (cid != CRYPT_PKEY_ECDSA && cid != CRYPT_PKEY_ECDH) { + return HITLS_NAMED_GROUP_BUTT; + } + CRYPT_PKEY_ParaId paraId = CRYPT_EAL_PkeyGetParaId(key); + return GetCurveNameByParaId(paraId); +} + +typedef struct { + CRYPT_PKEY_AlgId cid; + HITLS_CERT_KeyType keyType; +} CertKeyTypeMap; + +static HITLS_CERT_KeyType CertKeyAlgId2KeyType(CRYPT_EAL_PkeyCtx *pkey) +{ + CRYPT_PKEY_AlgId cid = CRYPT_EAL_PkeyGetId(pkey); + if (cid == CRYPT_PKEY_RSA) { + CRYPT_RsaPadType padType = 0; + if (CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(CRYPT_RsaPadType)) != CRYPT_SUCCESS) { + return TLS_CERT_KEY_TYPE_UNKNOWN; + } + if (padType == CRYPT_PKEY_EMSA_PSS) { + return TLS_CERT_KEY_TYPE_RSA_PSS; + } + } + static CertKeyTypeMap signMap[] = { + {CRYPT_PKEY_RSA, TLS_CERT_KEY_TYPE_RSA}, + {CRYPT_PKEY_DSA, TLS_CERT_KEY_TYPE_DSA}, + {CRYPT_PKEY_ECDSA, TLS_CERT_KEY_TYPE_ECDSA}, + {CRYPT_PKEY_ED25519, TLS_CERT_KEY_TYPE_ED25519}, + #ifndef HITLS_NO_TLCP11 + {CRYPT_PKEY_SM2, TLS_CERT_KEY_TYPE_SM2}, + #endif + }; + for (size_t i = 0; i < sizeof(signMap) / sizeof(signMap[0]); i++) { + if (signMap[i].cid == cid) { + return signMap[i].keyType; + } + } + return TLS_CERT_KEY_TYPE_UNKNOWN; +} + +int32_t HITLS_X509_Adapt_KeyCtrl(HITLS_Config *config, HITLS_CERT_Key *key, HITLS_CERT_CtrlCmd cmd, + void *input, void *output) +{ + (void)config; + (void)input; + int32_t ret = HITLS_SUCCESS; + switch (cmd) { + case CERT_KEY_CTRL_GET_SIGN_LEN: + *(uint32_t *)output = CRYPT_EAL_PkeyGetSignLen((const CRYPT_EAL_PkeyCtx *)key); + break; + case CERT_KEY_CTRL_GET_TYPE: + *(HITLS_CERT_KeyType *)output = CertKeyAlgId2KeyType(key); + break; + case CERT_KEY_CTRL_GET_CURVE_NAME: + *(HITLS_NamedGroup *)output = GetCurveNameByKey(key); + break; + case CERT_KEY_CTRL_GET_POINT_FORMAT: + /* Currently only uncompressed is used */ + *(HITLS_ECPointFormat *)output = HITLS_POINT_FORMAT_UNCOMPRESSED; + break; + case CERT_KEY_CTRL_GET_SECBITS: + *(int32_t *)output = CRYPT_EAL_PkeyGetSecurityBits(key); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ADAPT_ERR); + ret = HITLS_X509_ADAPT_ERR; + break; + } + + return ret; +} diff --git a/tls/cert/include/cert.h b/tls/cert/include/cert.h new file mode 100644 index 00000000..37af5f6a --- /dev/null +++ b/tls/cert/include/cert.h @@ -0,0 +1,271 @@ +/* + * 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 CERT_H +#define CERT_H + +#include +#include "hitls_type.h" +#include "hitls_cert_type.h" +#include "cipher_suite.h" +#include "cert_mgr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* tls.handshake.certificate_length Length of a label */ +#define CERT_LEN_TAG_SIZE 3u + +/* sed to transfer certificate verification parameters */ +typedef struct CertVerifyParamInner HITLS_CertVerifyParam; + +/* Used to transfer certificate data in ASN.1 DER format. */ +typedef struct CertItem { + uint32_t dataSize; /* Data length */ + uint8_t *data; /* Data content */ + struct CertItem *next; +} CERT_Item; + +/* Information used to describe the expected certificate */ +typedef struct { + /* The server must select the certificate matching the cipher suite. The client has no such restriction. */ + CERT_Type certType; + uint16_t *signSchemeList; /* certificate signature algorithm list */ + uint32_t signSchemeNum; /* number of certificate signature algorithms */ + uint16_t *ellipticCurveList; /* EC curve ID list */ + uint32_t ellipticCurveNum; /* number of EC curve IDs */ + uint8_t *ecPointFormatList; /* EC point format list */ + uint32_t ecPointFormatNum; /* number of EC point formats */ +} CERT_ExpectInfo; + +/** + * @ingroup hitls_cert_type + * @brief used to transfer the signature parameter + */ +typedef struct { + HITLS_SignAlgo signAlgo; /* signature algorithm */ + HITLS_HashAlgo hashAlgo; /* hash algorithm */ + const uint8_t *data; /* signed data */ + uint32_t dataLen; /* length of the signed data */ + uint8_t *sign; /* sign */ + uint32_t signLen; /* signature length */ +} CERT_SignParam; + +/** + * @brief Check the certificate information. + * + * @param ctx [IN] TLS context + * @param expectCertInfo [IN] Expected certificate information + * @param cert [IN] Certificate + * @param isNegotiateSignAlgo [IN] Indicates whether to select the signature algorithm used in handshake messages. + * @param signCheck [IN] Indicates whether to check the certificate signature information. + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_CERT_CTRL_ERR_GET_PUB_KEY Failed to obtain the public key. + * @retval HITLS_CERT_KEY_CTRL_ERR_GET_TYPE Failed to obtain the public key type. + * @retval HITLS_CERT_ERR_UNSUPPORT_CERT_TYPE The certificate type does not match. + * @retval HITLS_CERT_ERR_NO_SIGN_SCHEME_MATCH signature algorithm mismatch + * @retval HITLS_CERT_ERR_NO_CURVE_MATCH elliptic curve mismatch + * @retval HITLS_CERT_ERR_NO_POINT_FORMAT_MATCH Point format mismatch + */ +int32_t SAL_CERT_CheckCertInfo(HITLS_Ctx *ctx, const CERT_ExpectInfo *expectCertInfo, HITLS_CERT_X509 *cert, + bool isNegotiateSignAlgo, bool signCheck); + +/** + * @brief Select the certificate chain to be sent to the peer end. + * + * @param ctx [IN] tls Context + * @param info [IN] Expected certificate information + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_CERT_ERR_SELECT_CERTIFICATE Failed to select the certificate. + */ +int32_t SAL_CERT_SelectCertByInfo(HITLS_Ctx *ctx, CERT_ExpectInfo *info); + +/** + * @brief Encode the certificate chain in ASN.1 DER format. + * + * @param ctx [IN] tls Context + * @param buf [OUT] Certificate encoding data + * @param bufLen [OUT] Maximum length of data padding. + * @param usedLen [OUT] Data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_CERT_ERR_BUILD_CHAIN Failed to assemble the certificate chain. + * @retval HITLS_CERT_CTRL_ERR_GET_ENCODE_LEN Failed to obtain the encoding length. + * @retval HITLS_CERT_ERR_ENCODE_CERT Certificate encoding failed. + */ +int32_t SAL_CERT_EncodeCertChain(HITLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Decode the certificate in ASN.1 DER format. + * + * @param ctx [IN] tls Context + * @param item [IN] Original certificate data, which is a linked list. Each node indicates a certificate. + * @param certPair [OUT] Certificate chain + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_MEMALLOC_FAIL Insufficient Memory + * @retval HITLS_CERT_ERR_PARSE_MSG Failed to parse the certificate data. + */ +int32_t SAL_CERT_ParseCertChain(HITLS_Ctx *ctx, CERT_Item *item, CERT_Pair **certPair); + +/** + * @brief Verify the certificate chain. + * + * @param ctx [IN] tls Context + * @param certPair [IN] Certificate chain + * @param isGmEncCert [IN] Indicates whether to verify the certificate chain of the encrypted certificate + * of the TLCP. The value is always false + * when the TLCP protocol is not used. + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_MEMALLOC_FAIL Insufficient Memory + * @retval HITLS_CERT_ERR_VERIFY_CERT_CHAIN Failed to verify the certificate chain. + */ +int32_t SAL_CERT_VerifyCertChain(HITLS_Ctx *ctx, CERT_Pair *certPair, bool isTlcpEncCert); + +/** + * @brief Obtain the maximum signature length. + * + * @param config [IN] TLS link configuration + * @param key [IN] Certificate private key + * + * @return Signature length + */ +uint32_t SAL_CERT_GetSignMaxLen(HITLS_Config *config, HITLS_CERT_Key *key); + +/** + * @brief Sign with the certificate private key. + * + * @param ctx [IN] tls Context + * @param key [IN] Certificate private key + * @param signParam [IN/OUT] Signature information + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_CERT_ERR_CREATE_SIGN Signing failed. + */ +int32_t SAL_CERT_CreateSign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, CERT_SignParam *signParam); + +/** + * @brief Use the certificate public key to verify the signature. + * + * @param ctx [IN] tls Context + * @param key [IN] Certificate public key + * @param signParam [IN] Signature information + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK No callback is set. + * @retval HITLS_CERT_ERR_VERIFY_SIGN Failed to verify the signature. + */ +int32_t SAL_CERT_VerifySign(HITLS_Ctx *ctx, HITLS_CERT_Key *key, CERT_SignParam *signParam); + +/** + * @ingroup hitls_cert_reg + * @brief Encrypted by the certificate public key, which is used for the RSA cipher suite. + * + * @param ctx [IN] tls Context + * @param key [IN] Certificate public key + * @param in [IN] Plaintext + * @param inLen [IN] length of plaintext + * @param out [IN] Ciphertext + * @param outLen [IN/OUT] IN: Maximum length of the ciphertext padding. OUT: Length of the ciphertext + * + * @retval HITLS_SUCCESS succeeded + */ +int32_t SAL_CERT_KeyEncrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @ingroup hitls_cert_reg + * @brief Use the certificate private key to decrypt, which is used for the RSA cipher suite. + * + * @param ctx [IN] tls Context + * @param key [IN] Certificate private key + * @param in [IN] Ciphertext + * @param inLen [IN] length of ciphertext + * @param out [IN] Plaintext + * @param outLen [IN/OUT] IN: Maximum length of plaintext padding. OUT: Plaintext length + * + * @retval HITLS_SUCCESS succeeded + */ +int32_t SAL_CERT_KeyDecrypt(HITLS_Ctx *ctx, HITLS_CERT_Key *key, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @brief Obtain the default signature hash algorithm based on the certificate public key type. + * + * @param keyType [IN] Certificate public key type + * + * @retval Default signature hash algorithm + */ +HITLS_SignHashAlgo SAL_CERT_GetDefaultSignHashAlgo(HITLS_CERT_KeyType keyType); + +/** + * @ingroup hitls_cert_reg + * @brief Encoded content of the TLCP encryption certificate obtained by the server. + * + * @param ctx [IN] tls Context + * @param outLen [OUT] OUT: length after encoding + * + * @retval Encoded content + */ +uint8_t *SAL_CERT_SrvrGmEncodeEncCert(HITLS_Ctx *ctx, uint32_t *useLen); + +/** + * @ingroup hitls_cert_reg + * @brief The client obtains the encoded content of the TLCP encryption certificate. + * + * @param ctx [IN] tls Context + * @param peerCert [IN] Peer certificate information + * @param outLen [OUT] OUT: length after encoding + * + * @retval Encoded content + */ +uint8_t *SAL_CERT_ClntGmEncodeEncCert(HITLS_Ctx *ctx, CERT_Pair *peerCert, uint32_t *useLen); + +/** + * @ingroup hitls_cert_reg + * @brief Check whether the certificate is an encrypted certificate, a digital signature, + * or a permission to issue the certificate. + * + * @param ctx [IN] tls Context + * @param cert [IN] Certificate to be verified + * + * @retval true indicates that is the encryption certificate. + */ + +bool SAL_CERT_CheckCertKeyUsage(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd keyusage); + +/** + * @brief get cert key type based on signScheme + * + * @param signScheme [IN] signature algorithm + * + * @retval cert key type + */ +HITLS_CERT_KeyType SAL_CERT_SignScheme2CertKeyType(HITLS_SignHashAlgo signScheme); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/tls/cert/include/cert_method.h b/tls/cert/include/cert_method.h new file mode 100644 index 00000000..f2ae486f --- /dev/null +++ b/tls/cert/include/cert_method.h @@ -0,0 +1,225 @@ +/* + * 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 CERT_METHOD_H +#define CERT_METHOD_H + +#include +#include "hitls_cert_type.h" +#include "tls_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a certificate store. + * + * @param mgrCtx [IN] Certificate management struct + * + * @return Certificate store + */ +HITLS_CERT_Store *SAL_CERT_StoreNew(const CERT_MgrCtx *mgrCtx); + +/** + * @brief Copy the certificate store. + * + * @param mgrCtx [IN] Certificate management struct + * @param store [IN] Certificate store + * + * @return Certificate store + */ +HITLS_CERT_Store *SAL_CERT_StoreDup(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store); + +/** + * @brief Release the certificate store. + * + * @param mgrCtx [IN] Certificate management struct + * @param store [IN] Certificate store + * + * @return void + */ +void SAL_CERT_StoreFree(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store); + +/** + * @brief Construct the certificate chain. + * + * @param config [IN] TLS link configuration + * @param store [IN] Certificate store + * @param cert [IN] Device certificate + * @param certList [OUT] Certificate chain + * @param num [IN/OUT] IN: length of array OUT: length of certificate chain + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_BuildChain(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_X509 *cert, + HITLS_CERT_X509 **certList, uint32_t *num); + +/** + * @brief Verify the certificate chain. + * + * @param config [IN] TLS link configuration + * @param store [IN] Certificate store + * @param certList [IN] Certificate chain + * @param num [IN] length of certificate chain + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_VerifyChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store, HITLS_CERT_X509 **certList, uint32_t num); + +/** + * @brief Encode the certificate in ASN.1 DER format. + * + * @param ctx [IN] TLS link object + * @param cert [IN] Certificate + * @param buf [OUT] Certificate encoding data + * @param len [IN] buffer length + * @param usedLen [OUT] Data length + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_X509Encode(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t len, uint32_t *usedLen); + +/** + * @brief Parse the certificate. + * + * @param config [IN] TLS link configuration + * @param buf [IN] Certificate encoding data + * @param len [IN] Data length + * @param type [IN] Data type + * @param format [IN] Data format + * + * @return Certificate + */ +HITLS_CERT_X509 *SAL_CERT_X509Parse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format); + +/** + * @brief Copy the certificate. + * + * @param mgrCtx [IN] Certificate management struct + * @param cert [IN] Certificate + * + * @return Certificate + */ +HITLS_CERT_X509 *SAL_CERT_X509Dup(const CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert); + +/** + * @brief Certificate reference increments by one. + * + * @param mgrCtx [IN] Certificate management struct + * @param cert [IN] Certificate + * + * @return Certificate + */ +HITLS_CERT_X509 *SAL_CERT_X509Ref(const CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert); + +/** + * @brief Release the certificate. + * + * @param cert [IN] Certificate + * + * @return void + */ +void SAL_CERT_X509Free(HITLS_CERT_X509 *cert); + +/** + * @brief Parse the key. + * + * @param config [IN] TLS link configuration + * @param buf [IN] Key coded data + * @param len [IN] Data length + * @param type [IN] Data type + * @param format [IN] Data format + * + * @return Key + */ +HITLS_CERT_Key *SAL_CERT_KeyParse(HITLS_Config *config, const uint8_t *buf, uint32_t len, + HITLS_ParseType type, HITLS_ParseFormat format); + +/** + * @brief Copy the key. + * + * @param mgrCtx [IN] Certificate management struct + * @param key [IN] Key + * + * @return Key + */ +HITLS_CERT_Key *SAL_CERT_KeyDup(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Key *key); + +/** + * @brief Release the key. + * + * @param mgrCtx [IN] Certificate management struct + * @param cert [IN] Key + * + * @return void + */ +void SAL_CERT_KeyFree(const CERT_MgrCtx *mgrCtx, HITLS_CERT_Key *key); + +/** + * @brief Certificate store operation function + * + * @param config [IN] TLS link configuration + * @param store [IN] Certificate store + * @param cmd [IN] Operation command + * @param in [IN] Input parameter + * @param out [OUT] Output parameter + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_StoreCtrl(HITLS_Config *config, HITLS_CERT_Store *store, HITLS_CERT_CtrlCmd cmd, void *in, void *out); + +/** + * @brief Certificate operation function + * + * @param config [IN] TLS link configuration + * @param cert [IN] Certificate + * @param cmd [IN] Operation command + * @param in [IN] Input parameter + * @param out [OUT] Output parameter + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_X509Ctrl(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd cmd, void *in, void *out); + +/** + * @brief Key operation function + * + * @param config [IN] TLS link configuration + * @param key [IN] Key + * @param cmd [IN] Operation command + * @param in [IN] Input parameter + * @param out [OUT] Output parameter + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_KeyCtrl(HITLS_Config *config, HITLS_CERT_Key *key, HITLS_CERT_CtrlCmd cmd, void *in, void *out); + +/** + * @brief Verify the certificate private key pair. + * + * @param config [IN] TLS link configuration + * @param cert [IN] Certificate + * @param key [IN] Key + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_CheckPrivateKey(const HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_Key *key); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/tls/cert/include/cert_mgr.h b/tls/cert/include/cert_mgr.h new file mode 100644 index 00000000..d7263762 --- /dev/null +++ b/tls/cert/include/cert_mgr.h @@ -0,0 +1,354 @@ +/* + * 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 CERT_MGR_H +#define CERT_MGR_H + +#include +#include "hitls_type.h" +#include "hitls_cert_type.h" +#include "hitls_cert.h" +#include "tls_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to transfer certificates, private keys, and certificate chains. */ +typedef struct CertPairInner CERT_Pair; + +/** + * @brief Obtain the certificate + * + * @param certPair [IN] Certificate resource struct + * + * @return Certificate + */ +HITLS_CERT_X509 *SAL_CERT_PairGetX509(CERT_Pair *certPair); + +/** + * @ingroup hitls_cert_reg + * @brief Obtain the encryption certificate + * + * @param certPair [IN] Certificate resource struct + * + * @return Encryption certificate + */ +HITLS_CERT_X509 *SAL_CERT_GetTlcpEncCert(CERT_Pair *certPair); + +HITLS_CERT_Chain *SAL_CERT_PairGetChain(CERT_Pair *certPair); + +CERT_Pair *SAL_CERT_PairDup(CERT_MgrCtx *mgrCtx, CERT_Pair *srcCertPair); + +/** + * @brief Uninstall the certificate resource but not release the struct + * + * @param mgrCtx [IN] Certificate management struct + * @param certPair [IN] Certificate resource struct + * + * @return void + */ +void SAL_CERT_PairClear(CERT_MgrCtx *mgrCtx, CERT_Pair *certPair); + +/** + * @brief Release the certificate resource struct + * + * @param mgrCtx [IN] Certificate management struct + * @param certPair [IN] Certificate resource struct. The certPair is set NULL by the invoker. + * + * @return void + */ +void SAL_CERT_PairFree(CERT_MgrCtx *mgrCtx, CERT_Pair *certPair); + +/** + * @brief Indicates whether to enable the certificate management module. + * + * @param void + * + * @retval true yes + * @retval false no + */ +bool SAL_CERT_MgrIsEnable(void); + +/** + * @brief Callback for obtaining a certificate + * + * @param NA + * + * @return Certificate callback + */ +HITLS_CERT_MgrMethod *SAL_CERT_GetMgrMethod(void); + +/** + * @brief obtain the user key callback + * + * @param NA + * + * @return Certificate callback + */ +HITLS_CERT_UserKeyMgrMethod *SAL_CERT_GetUserKeyMgrMethod(void); + +/** + * @brief Create a certificate management struct + * + * @param void + * + * @return Certificate management struct + */ +CERT_MgrCtx *SAL_CERT_MgrCtxNew(void); + +/** + * @brief Copy the certificate management struct + * + * @param mgrCtx [IN] Certificate management struct + * + * @return Certificate management struct + */ +CERT_MgrCtx *SAL_CERT_MgrCtxDup(CERT_MgrCtx *mgrCtx); + +/** + * @brief Release the certificate management struct + * + * @param mgrCtx [IN] Certificate management struct. mgrCtx is set NULL by the invoker. + * + * @return void + */ +void SAL_CERT_MgrCtxFree(CERT_MgrCtx *mgrCtx); + +/** + * @brief Set the cert store + * + * @param mgrCtx [IN] Certificate management struct + * @param store [IN] cert store + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetCertStore(CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store); + +/** + * @brief Obtain the cert store + * + * @param mgrCtx [IN] Certificate management struct + * + * @return cert store + */ +HITLS_CERT_Store *SAL_CERT_GetCertStore(CERT_MgrCtx *mgrCtx); + +/** + * @brief Set the chain store + * + * @param mgrCtx [IN] Certificate management struct + * @param store [IN] chain store + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetChainStore(CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store); + +/** + * @brief Obtain the chain store + * + * @param mgrCtx [IN] Certificate management struct + * + * @return chain store + */ +HITLS_CERT_Store *SAL_CERT_GetChainStore(CERT_MgrCtx *mgrCtx); + +/** + * @brief Set the verify store + * + * @param mgrCtx [IN] Certificate management struct + * @param store [IN] verify store + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetVerifyStore(CERT_MgrCtx *mgrCtx, HITLS_CERT_Store *store); + +/** + * @brief Obtain the verify store + * + * @param mgrCtx [IN] Certificate management struct + * + * @return verify store + */ +HITLS_CERT_Store *SAL_CERT_GetVerifyStore(CERT_MgrCtx *mgrCtx); + +/** + * @brief Add a device certificate and set it to the current. Only one certificate of each type can be added. + * If the certificate is added repeatedly, the certificate will be overwritten. + * + * @param config [IN] Certificate management struct + * @param cert [IN] Device certificate + * @param isGmEncCert [IN] Indicates whether the certificate is encrypted using the TLCP. + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetCurrentCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isTlcpEncCert); + +/** + * @brief Obtain the current device certificate + * + * @param mgrCtx [IN] Certificate management struct + * + * @return Device certificate + */ +HITLS_CERT_X509 *SAL_CERT_GetCurrentCert(CERT_MgrCtx *mgrCtx); + +/** + * @brief Obtain the certificate of the specified type. + * + * @param mgrCtx [IN] Certificate management struct + * @param keyType [IN] Certificate public key type + * + * @return Device certificate + */ +HITLS_CERT_X509 *SAL_CERT_GetCert(CERT_MgrCtx *mgrCtx, HITLS_CERT_KeyType keyType); + +/** + * @brief Add a private key and set it to the current key. + * Only one private key can be added for each type of certificate. + * If a private key is added repeatedly, it will be overwritten. + * + * @param config [IN] Certificate management struct + * @param key [IN] Private key + * @param isGmEncCertPriKey [IN] Indicates whether the private key of the certificate encrypted + * using the TLCP. + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetCurrentPrivateKey(HITLS_Config *config, HITLS_CERT_Key *key, bool isTlcpEncCertPriKey); + +/** + * @brief Obtain the current private key + * + * @param mgrCtx [IN] Certificate management struct + * @param isGmEncCertPriKey [IN] Indicates whether the private key of the certificate encrypted + * using the TLCP. + * + * @return Private key + */ +HITLS_CERT_Key *SAL_CERT_GetCurrentPrivateKey(CERT_MgrCtx *mgrCtx, bool isTlcpEncCert); + +/** + * @brief Obtain the private key of a specified type. + * + * @param mgrCtx [IN] Certificate management struct + * @param keyType [IN] Private key type + * + * @return Private key + */ +HITLS_CERT_Key *SAL_CERT_GetPrivateKey(CERT_MgrCtx *mgrCtx, HITLS_CERT_KeyType keyType); + +int32_t SAL_CERT_AddChainCert(CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert); + +HITLS_CERT_Chain *SAL_CERT_GetCurrentChainCerts(CERT_MgrCtx *mgrCtx); + +void SAL_CERT_ClearCurrentChainCerts(CERT_MgrCtx *mgrCtx); + +/** + * @brief Delete all certificate resources, including the device certificate, private key, and certificate chain. + * + * @param mgrCtx [IN] Certificate management struct + * + * @return void + */ +void SAL_CERT_ClearCertAndKey(CERT_MgrCtx *mgrCtx); + +int32_t SAL_CERT_AddExtraChainCert(CERT_MgrCtx *mgrCtx, HITLS_CERT_X509 *cert); + +HITLS_CERT_Chain *SAL_CERT_GetExtraChainCerts(CERT_MgrCtx *mgrCtx); + +void SAL_CERT_ClearExtraChainCerts(CERT_MgrCtx *mgrCtx); + +/** + * @brief Set the verification depth + * + * @param mgrCtx [IN] Certificate management struct + * @param depth [IN] Verification depth + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetVerifyDepth(CERT_MgrCtx *mgrCtx, uint32_t depth); + +/** + * @brief Obtain the verification depth + * + * @param mgrCtx [IN] Certificate management struct + * @param depth [IN] Verification depth + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_GetVerifyDepth(CERT_MgrCtx *mgrCtx, uint32_t *depth); + +/** + * @brief Set the default passwd callback. + * + * @param mgrCtx [IN] Certificate management struct + * @param cb [IN] Callback function + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetDefaultPasswordCb(CERT_MgrCtx *mgrCtx, HITLS_PasswordCb cb); + +/** + * @brief Obtain the default passwd callback. + * + * @param mgrCtx [IN] Certificate management struct + * + * @return Callback function + */ +HITLS_PasswordCb SAL_CERT_GetDefaultPasswordCb(CERT_MgrCtx *mgrCtx); + +/** + * @brief Set the user data used in the default passwd callback. + * + * @param mgrCtx [IN] Certificate management struct + * @param userdata [IN] User data + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetDefaultPasswordCbUserdata(CERT_MgrCtx *mgrCtx, void *userdata); + +/** + * @brief Obtain the user data used in the default passwd callback. + * + * @param mgrCtx [IN] Certificate management struct + * + * @return User data + */ +void *SAL_CERT_GetDefaultPasswordCbUserdata(CERT_MgrCtx *mgrCtx); + +/** + * @brief Set the verify callback function, which is used during certificate verification. + * + * @param mgrCtx [IN] Certificate management struct + * @param cb [IN] User data + * + * @retval HITLS_SUCCESS succeeded. + */ +int32_t SAL_CERT_SetVerifyCb(CERT_MgrCtx *mgrCtx, HITLS_VerifyCb cb); + +/** + * @brief Obtain the verify callback function. + * + * @param mgrCtx [IN] Certificate management struct + * + * @return Callback function + */ +HITLS_VerifyCb SAL_CERT_GetVerifyCb(CERT_MgrCtx *mgrCtx); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/tls/cm/include/conn_init.h b/tls/cm/include/conn_init.h new file mode 100644 index 00000000..963b4a2f --- /dev/null +++ b/tls/cm/include/conn_init.h @@ -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 CONN_INIT_H +#define CONN_INIT_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize TLS resources. + * + * @param ctx [IN] TLS context + * +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_MEMALLOC_FAIL Memory application failed. +* @retval HITLS_INTERNAL_EXCEPTION The input parameter is a null pointer. + */ +int32_t CONN_Init(TLS_Ctx *ctx); + +/** + * @brief Release TLS resources. + * + * @param ctx [IN] TLS context + */ +void CONN_Deinit(TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/cm/src/conn_cert.c b/tls/cm/src/conn_cert.c new file mode 100644 index 00000000..2a7083e3 --- /dev/null +++ b/tls/cm/src/conn_cert.c @@ -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 +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls_cert_type.h" +#include "hitls_cert.h" +#include "tls.h" + +int32_t HITLS_SetVerifyStore(HITLS_Ctx *ctx, HITLS_CERT_Store *store, bool isClone) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetVerifyStore(&(ctx->config.tlsConfig), store, isClone); +} + +HITLS_CERT_Store *HITLS_GetVerifyStore(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetVerifyStore(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetChainStore(HITLS_Ctx *ctx, HITLS_CERT_Store *store, bool isClone) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetChainStore(&(ctx->config.tlsConfig), store, isClone); +} + +HITLS_CERT_Store *HITLS_GetChainStore(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetChainStore(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetCertStore(HITLS_Ctx *ctx, HITLS_CERT_Store *store, bool isClone) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetCertStore(&(ctx->config.tlsConfig), store, isClone); +} + +HITLS_CERT_Store *HITLS_GetCertStore(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetCertStore(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetVerifyDepth(HITLS_Ctx *ctx, uint32_t depth) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetVerifyDepth(&(ctx->config.tlsConfig), depth); +} + +int32_t HITLS_GetVerifyDepth(const HITLS_Ctx *ctx, uint32_t *depth) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetVerifyDepth(&(ctx->config.tlsConfig), depth); +} + +int32_t HITLS_SetDefaultPasswordCb(HITLS_Ctx *ctx, HITLS_PasswordCb cb) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + int32_t ret = HITLS_CFG_SetDefaultPasswordCb(&(ctx->config.tlsConfig), cb); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +HITLS_PasswordCb HITLS_GetDefaultPasswordCb(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetDefaultPasswordCb(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetDefaultPasswordCbUserdata(HITLS_Ctx *ctx, void *userdata) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + int32_t ret = HITLS_CFG_SetDefaultPasswordCbUserdata(&(ctx->config.tlsConfig), userdata); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +void *HITLS_GetDefaultPasswordCbUserdata(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetDefaultPasswordCbUserdata(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetCertificate(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, bool isClone) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetCertificate(&(ctx->config.tlsConfig), cert, isClone); +} + +int32_t HITLS_LoadCertFile(HITLS_Ctx *ctx, const char *file, HITLS_ParseFormat format) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_LoadCertFile(&(ctx->config.tlsConfig), file, format); +} + +int32_t HITLS_LoadCertBuffer(HITLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_LoadCertBuffer(&(ctx->config.tlsConfig), buf, bufLen, format); +} + +HITLS_CERT_X509 *HITLS_GetCertificate(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetCertificate(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetPrivateKey(HITLS_Ctx *ctx, HITLS_CERT_Key *key, bool isClone) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetPrivateKey(&(ctx->config.tlsConfig), key, isClone); +} + +int32_t HITLS_LoadKeyFile(HITLS_Ctx *ctx, const char *file, HITLS_ParseFormat format) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_LoadKeyFile(&(ctx->config.tlsConfig), file, format); +} + +int32_t HITLS_LoadKeyBuffer(HITLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_LoadKeyBuffer(&(ctx->config.tlsConfig), buf, bufLen, format); +} + +HITLS_CERT_Key *HITLS_GetPrivateKey(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetPrivateKey(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_CheckPrivateKey(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_CheckPrivateKey(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_RemoveCertAndKey(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_RemoveCertAndKey(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetVerifyCb(HITLS_Ctx *ctx, HITLS_VerifyCb callback) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetVerifyCb(&(ctx->config.tlsConfig), callback); +} + +HITLS_VerifyCb HITLS_GetVerifyCb(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetVerifyCb(&(ctx->config.tlsConfig)); +} \ No newline at end of file diff --git a/tls/cm/src/conn_common.c b/tls/cm/src/conn_common.c new file mode 100644 index 00000000..5c8e2cce --- /dev/null +++ b/tls/cm/src/conn_common.c @@ -0,0 +1,654 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "tls.h" +#include "hitls.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls_psk.h" +#include "hitls_alpn.h" +#include "hs.h" +#include "alert.h" +#include "app.h" +#include "session.h" +#include "indicator.h" +#include "rec.h" +#include "hs_ctx.h" +#include "conn_common.h" + +static const char *GetStateString(uint32_t state) +{ + /* * Unknown status */ + if (state >= CM_STATE_END) { + return "Unknown"; + } + + static const char *stateMachineStr[CM_STATE_END] = { + [CM_STATE_IDLE] = "Idle", + [CM_STATE_RENEGOTIATION] = "SecRenego", + [CM_STATE_HANDSHAKING] = "Handshaking", + [CM_STATE_TRANSPORTING] = "Transporting", + [CM_STATE_ALERTING] = "Alerting", + [CM_STATE_ALERTED] = "Alerted", + [CM_STATE_CLOSED] = "Closed", + }; + /** Current status */ + return stateMachineStr[state]; +} + +void ChangeConnState(HITLS_Ctx *ctx, CM_State state) +{ + if (GetConnState(ctx) == state) { + return; + } + + ctx->preState = ctx->state; + ctx->state = state; + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15839, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "state [%s]", + GetStateString(ctx->preState)); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15840, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "change to [%s]", + GetStateString(state)); + return; +} + +int32_t CommonEventInAlertingState(HITLS_Ctx *ctx) +{ + /* The alerting state indicates that an alert message is being sent over the current link. In this case, the alert + * message should firstly be sent and then the link status will be updated */ + ALERT_Info alertInfo = {0}; + ALERT_GetInfo(ctx, &alertInfo); + + if (alertInfo.level > ALERT_LEVEL_FATAL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret = ALERT_Flush(ctx); + if (ret != HITLS_SUCCESS) { + /* If the alert fails to be sent, return error code to user */ + return ret; + } + + uint8_t data[2] = {alertInfo.level, alertInfo.description}; + INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_ALERT, data, (uint32_t)(sizeof(data) / sizeof(uint8_t)), + ctx, ctx->config.tlsConfig.msgArg); + + INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_WRITE_ALERT, + (int32_t)(((uint32_t)(alertInfo.level) << INDICATOR_ALERT_LEVEL_OFFSET) | (uint32_t)(alertInfo.description))); + + /* If a fatal alert is sent, the link must be disconnected */ + if (alertInfo.level == ALERT_LEVEL_FATAL) { + SESS_Disable(ctx->session); + ChangeConnState(ctx, CM_STATE_ALERTED); + return HITLS_SUCCESS; + } + + /* If the close_notify message is sent, the link must be disconnected */ + if ((alertInfo.description == ALERT_CLOSE_NOTIFY) && (ctx->userShutDown == true)) { + ChangeConnState(ctx, CM_STATE_CLOSED); + ctx->shutdownState |= HITLS_SENT_SHUTDOWN; + return HITLS_SUCCESS; + } + + if ((alertInfo.description == ALERT_CLOSE_NOTIFY) && (ctx->userShutDown == false)) { + ChangeConnState(ctx, CM_STATE_ALERTED); + ctx->shutdownState |= HITLS_SENT_SHUTDOWN; + return HITLS_SUCCESS; + } + + /* Other warning alerts will not terminate the connection and the status will be restored to the previous status */ + ctx->state = ctx->preState; + ALERT_CleanInfo(ctx); + return HITLS_SUCCESS; +} + +static int32_t AlertRecvProcess(HITLS_Ctx *ctx, const ALERT_Info *alertInfo) +{ + uint8_t data[2] = {alertInfo->level, alertInfo->description}; + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_ALERT, data, + (uint32_t)(sizeof(data) / sizeof(uint8_t)), ctx, ctx->config.tlsConfig.msgArg); + + INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_READ_ALERT, + (int32_t)(((uint32_t)(alertInfo->level) << INDICATOR_ALERT_LEVEL_OFFSET) | (uint32_t)(alertInfo->description))); + + /* If a fatal alert is received, the link must be disconnected */ + if (alertInfo->level == ALERT_LEVEL_FATAL) { + SESS_Disable(ctx->session); + ChangeConnState(ctx, CM_STATE_ALERTED); + ctx->shutdownState |= HITLS_RECEIVED_SHUTDOWN; + return HITLS_SUCCESS; + } + + /* If a warning alert is received, the connection must be terminated if the alert is close_notify. Otherwise, the + * alert will not be processed */ + ALERT_CleanInfo(ctx); + if (alertInfo->description != ALERT_CLOSE_NOTIFY) { + /* Other warning alerts will not be processed */ + return HITLS_SUCCESS; + } + + ctx->shutdownState |= HITLS_RECEIVED_SHUTDOWN; + + /* In quiet disconnection mode, close_notify does not need to be sent */ + if (ctx->config.tlsConfig.isQuietShutdown) { + ctx->shutdownState |= HITLS_SENT_SHUTDOWN; + ChangeConnState(ctx, CM_STATE_ALERTED); + return HITLS_SUCCESS; + } + + if ((ctx->shutdownState & HITLS_SENT_SHUTDOWN) == 0) { + /* If the close_notify message is received, the close_notify message must be sent to the peer */ + ALERT_Send(ctx, ALERT_LEVEL_WARNING, ALERT_CLOSE_NOTIFY); + ChangeConnState(ctx, CM_STATE_ALERTING); + int32_t ret = ALERT_Flush(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ctx->shutdownState |= HITLS_SENT_SHUTDOWN; + } + + if (ctx->state != CM_STATE_CLOSED) { + ChangeConnState(ctx, CM_STATE_ALERTED); + } + return HITLS_SUCCESS; +} + +int32_t AlertEventProcess(HITLS_Ctx *ctx) +{ + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(ctx, &alertInfo); + + /* An alert message is received. */ + if (alertInfo.flag == ALERT_FLAG_RECV) { + return AlertRecvProcess(ctx, &alertInfo); + } + + /* An alert message needs to be sent */ + if (alertInfo.flag == ALERT_FLAG_SEND) { + ChangeConnState(ctx, CM_STATE_ALERTING); + return CommonEventInAlertingState(ctx); + } + + return HITLS_SUCCESS; +} + +int32_t CommonEventInHandshakingState(HITLS_Ctx *ctx) +{ + int32_t ret; + int32_t alertRet; + uint32_t alertCount = 0; + + do { + ret = HS_DoHandshake(ctx); + if (ret == HITLS_SUCCESS) { + /* The handshake has completed */ + break; + } + + if (!ALERT_GetFlag(ctx)) { + /* The handshake fails, but no alert is received. Return the error code to the user */ + return ret; + } + + alertCount++; + if (alertCount >= MAX_ALERT_COUNT) { + /* If there are multiple consecutive alerts, the link is abnormal and needs to be terminated. */ + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + alertRet = AlertEventProcess(ctx); + return (alertRet == HITLS_SUCCESS) ? ret : alertRet; + } + + alertRet = AlertEventProcess(ctx); + if (alertRet != HITLS_SUCCESS) { + /* If the alert message fails to be sent, return the error code to the user */ + return alertRet; + } + + /* If fatal alert or close_notify has been processed, the handshake must be terminated */ + if (ctx->state == CM_STATE_ALERTED) { + return ret; + } + } while (ret != HITLS_SUCCESS); + + // If HS_DoHandshake returns success, the connection has been established. + ChangeConnState(ctx, CM_STATE_TRANSPORTING); + HS_DeInit(ctx); + + return HITLS_SUCCESS; +} + +const HITLS_Config *HITLS_GetConfig(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + return &(ctx->config.tlsConfig); +} + +int32_t HITLS_ClearTLS13CipherSuites(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_ClearTLS13CipherSuites(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetCipherSuites(HITLS_Ctx *ctx, const uint16_t *cipherSuites, uint32_t cipherSuitesSize) +{ + if (ctx == NULL || cipherSuites == NULL || cipherSuitesSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetCipherSuites(&(ctx->config.tlsConfig), cipherSuites, cipherSuitesSize); +} + +int32_t HITLS_SetAlpnProtos(HITLS_Ctx *ctx, const uint8_t *protos, uint32_t protosLen) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetAlpnProtos(&(ctx->config.tlsConfig), protos, protosLen); +} + +int32_t HITLS_SetPskClientCallback(HITLS_Ctx *ctx, HITLS_PskClientCb cb) +{ + if (ctx == NULL || cb == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetPskClientCallback(&(ctx->config.tlsConfig), cb); +} + +int32_t HITLS_SetPskServerCallback(HITLS_Ctx *ctx, HITLS_PskServerCb cb) +{ + if (ctx == NULL || cb == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetPskServerCallback(&(ctx->config.tlsConfig), cb); +} + +int32_t HITLS_SetPskIdentityHint(HITLS_Ctx *ctx, const uint8_t *identityHint, uint32_t identityHintLen) +{ + return HITLS_CFG_SetPskIdentityHint(&(ctx->config.tlsConfig), identityHint, identityHintLen); +} + +const HITLS_Cipher *HITLS_GetCurrentCipher(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return &(ctx->negotiatedInfo.cipherSuiteInfo); +} + +int32_t HITLS_GetRandom(const HITLS_Ctx *ctx, uint8_t *out, uint32_t *outlen, bool isClient) +{ + if (ctx == NULL || outlen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (*outlen == 0) { + *outlen = RANDOM_SIZE; + return HITLS_SUCCESS; + } + + uint32_t resLen = *outlen; + + if (resLen > RANDOM_SIZE) { + resLen = RANDOM_SIZE; + } + + if (out == NULL) { + *outlen = resLen; + return HITLS_SUCCESS; + } + + if (isClient) { + if (memcpy_s(out, resLen, ctx->negotiatedInfo.clientRandom, resLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + } else { + if (memcpy_s(out, resLen, ctx->negotiatedInfo.serverRandom, resLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + } + + *outlen = resLen; + return HITLS_SUCCESS; +} + +int32_t HITLS_IsClient(const HITLS_Ctx *ctx, bool *isClient) +{ + if (ctx == NULL || isClient == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *isClient = ctx->isClient; + return HITLS_SUCCESS; +} + +/** + * If current endpoint is a server and the server preference is supported, the local server group array is preferred. + * If current endpoint is a server and the client preference is supported, the peer (client)group array is preferred + */ +static uint16_t FindPreference(const HITLS_Ctx *ctx, int32_t nmatch, bool *haveFound) +{ + uint16_t ans = 0; + uint32_t preferGroupSize = 0; + uint32_t secondPreferGroupSize = 0; + uint16_t *preferGroups = NULL; + uint16_t *secondPreferGroups = NULL; + uint32_t peerGroupSize = ctx->peerInfo.groupsSize; + uint32_t localGroupSize = ctx->config.tlsConfig.groupsSize; + uint16_t *peerGroups = ctx->peerInfo.groups; + uint16_t *localGroups = ctx->config.tlsConfig.groups; + bool chooseServerPre = ctx->config.tlsConfig.isSupportServerPreference; + uint16_t intersectionCnt = 0; + + preferGroupSize = (chooseServerPre == true) ? localGroupSize : peerGroupSize; + secondPreferGroupSize = (chooseServerPre == true) ? peerGroupSize : localGroupSize; + preferGroups = (chooseServerPre == true) ? localGroups : peerGroups; + secondPreferGroups = (chooseServerPre == true) ? peerGroups : localGroups; + + for (uint32_t i = 0; i < preferGroupSize; i++) { + for (uint32_t j = 0; j < secondPreferGroupSize; j++) { + if (preferGroups[i] == secondPreferGroups[j]) { + intersectionCnt++; + // Currently, the preferred nmatch is already matched + bool isMatch = (intersectionCnt == nmatch); + *haveFound = (isMatch ? true : (*haveFound)); + ans = (isMatch ? preferGroups[i] : ans); + // Jump out of the inner village and change + break; + } + } + if (*haveFound) { + // Exit a loop + break; + } + } + if (nmatch == GET_GROUPS_CNT) { + return (uint16_t)intersectionCnt; + } + return ans; +} + +/** + * nmatch Value range: - 1 or a positive integer + * This function can be invoked only after negotiation and can be invoked only by the server. + * When nmatch is a positive integer, check the intersection of groups on the client and server, and return the nmatch + * group in the intersection by groupId. If the value of nmatch is - 1, the number of intersection groups on the client + * and server is returned based on groupId. + */ +int32_t HITLS_GetSharedGroup(const HITLS_Ctx *ctx, int32_t nmatch, uint16_t *groupId) +{ + bool haveFound = false; + if (ctx == NULL || groupId == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *groupId = 0; + // Check the value range of nmatch and whether the interface is invoked by the server. The client cannot invoke the + // interface because the client cannot sense the peerInfo. + if (nmatch < GET_GROUPS_CNT || nmatch == 0 || ctx->isClient) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + *groupId = FindPreference(ctx, nmatch, &haveFound); + + if (nmatch == GET_GROUPS_CNT) { + // The value of *groupId is the number of intersections + return HITLS_SUCCESS; + } else if (haveFound == false) { + // If nmatch is not equal to GET_GROUPS_CNT and haveFound is false + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_GetPeerFinishVerifyData(const HITLS_Ctx *ctx, void *buf, uint32_t bufLen, uint32_t *dataLen) +{ + int32_t ret; + uint32_t verifyDataSize, bufSize; + const uint8_t *verifyData = NULL; + + if (ctx == NULL || buf == NULL || dataLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (ctx->isClient) { + verifyDataSize = ctx->negotiatedInfo.serverVerifyDataSize; + verifyData = ctx->negotiatedInfo.serverVerifyData; + } else { + verifyDataSize = ctx->negotiatedInfo.clientVerifyDataSize; + verifyData = ctx->negotiatedInfo.clientVerifyData; + } + + if (bufLen > verifyDataSize) { + bufSize = verifyDataSize; + } else { + bufSize = bufLen; + } + + ret = memcpy_s(buf, bufLen, verifyData, bufSize); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + *dataLen = verifyDataSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetFinishVerifyData(const HITLS_Ctx *ctx, void *buf, uint32_t bufLen, uint32_t *dataLen) +{ + int32_t ret; + uint32_t verifyDataSize, bufSize; + const uint8_t *verifyData = NULL; + + if (ctx == NULL || buf == NULL || dataLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (ctx->isClient) { + verifyDataSize = ctx->negotiatedInfo.clientVerifyDataSize; + verifyData = ctx->negotiatedInfo.clientVerifyData; + } else { + verifyDataSize = ctx->negotiatedInfo.serverVerifyDataSize; + verifyData = ctx->negotiatedInfo.serverVerifyData; + } + + if (bufLen > verifyDataSize) { + bufSize = verifyDataSize; + } else { + bufSize = bufLen; + } + + ret = memcpy_s(buf, bufLen, verifyData, bufSize); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + *dataLen = verifyDataSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetVersionSupport(const HITLS_Ctx *ctx, uint32_t *version) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetVersionSupport(&(ctx->config.tlsConfig), version); +} + +int32_t HITLS_SetVersionSupport(HITLS_Ctx *ctx, uint32_t version) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetVersionSupport(&(ctx->config.tlsConfig), version); +} + +int32_t HITLS_SetNeedCheckPmsVersion(HITLS_Ctx *ctx, bool needCheck) +{ + if (ctx == NULL) { + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetNeedCheckPmsVersion(&(ctx->config.tlsConfig), needCheck); +} + +static int32_t CheckSecRenegotiationCb(HITLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + if (ctx->config.tlsConfig.noSecRenegotiationCb != NULL) { + /* If the peer end does not support the renegotiation, stop the renegotiation. In this case, the link + * establishment is complete and messages are sent and received. You can determine whether to disconnect the + * link when the peer end does not support security renegotiation. */ + ret = ctx->config.tlsConfig.noSecRenegotiationCb(ctx); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15951, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "noSecRenegotiationCb return fail during renegotiataion.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + } + } + return ret; +} + +int32_t CommonEventInRenegotiationState(HITLS_Ctx *ctx) +{ + int32_t ret; + int32_t alertRet; + uint32_t alertCount = 0; + + do { + ret = HS_DoHandshake(ctx); + if (ret == HITLS_SUCCESS) { /* The handshake has completed */ + break; + } + /* The handshake fails, but no alert is displayed. The system returns a message + * to the user for processing */ + if (!ALERT_GetFlag(ctx)) { + return ret; + } + ALERT_Info alertInfo = { 0 }; + ALERT_GetInfo(ctx, &alertInfo); + if ((alertInfo.level == ALERT_LEVEL_WARNING) && (alertInfo.description == ALERT_NO_RENEGOTIATION)) { + if (ctx->hsCtx->state == TRY_RECV_SERVER_HELLO || ctx->hsCtx->state == TRY_RECV_CLIENT_HELLO) { + ctx->userRenego = false; + ret = CheckSecRenegotiationCb(ctx); + } else { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15330, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Receive no renegotiation alert during renegotiation process", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + } + } + + alertCount++; + if (alertCount >= MAX_ALERT_COUNT) { + /* If multiple consecutive alerts exist, the link is abnormal and needs to be terminated */ + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + } + + alertRet = AlertEventProcess(ctx); + if (alertRet != HITLS_SUCCESS) { + /* If the alert fails to be sent, the system sends a message to the user for processing */ + return alertRet; + } + + /** + If fatal alert or close_notify has been processed, the handshake must be terminated. + */ + if (ctx->state == CM_STATE_ALERTED) { + return ret; + } + } while (ret != HITLS_SUCCESS); + + // If the HS_DoHandshake message is returned successfully, the link has been terminated. + ChangeConnState(ctx, CM_STATE_TRANSPORTING); + HS_DeInit(ctx); + + ctx->negotiatedInfo.isRenegotiation = false; /* Disabling renegotiation */ + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15952, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "renegotiate completed.", 0, 0, 0, 0); + return HITLS_SUCCESS; +} + +int32_t HITLS_SetPskFindSessionCallback(HITLS_Ctx *ctx, HITLS_PskFindSessionCb cb) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetPskFindSessionCallback(&(ctx->config.tlsConfig), cb); +} + +int32_t HITLS_SetPskUseSessionCallback(HITLS_Ctx *ctx, HITLS_PskUseSessionCb cb) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetPskUseSessionCallback(&(ctx->config.tlsConfig), cb); +} + +int32_t HITLS_GetNegotiateGroup(const HITLS_Ctx *ctx, uint16_t *group) +{ + if (ctx == NULL || group == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *group = ctx->negotiatedInfo.negotiatedGroup; + return HITLS_SUCCESS; +} + +int HITLS_EventProcWrapper(void *arg) +{ + HITLSAsyncArgs *args = (HITLSAsyncArgs *)arg; + switch (args->evenType) { + case READ_EVENT: + return ((ReadEventProcess)args->func)(args->ctx, args->buf, args->bufSize, args->size); + case WRITE_EVENT: + return ((WriteEventProcess)args->func)(args->ctx, args->buf, args->bufSize); + case MANAGER_EVENT: + return ((ManageEventProcess)args->func)(args->ctx); + default: + break; + } + + return -1; +} \ No newline at end of file diff --git a/tls/cm/src/conn_common.h b/tls/cm/src/conn_common.h new file mode 100644 index 00000000..bb0bf9ac --- /dev/null +++ b/tls/cm/src/conn_common.h @@ -0,0 +1,89 @@ +/* + * 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 CONN_COMMON_H +#define CONN_COMMON_H + +#include +#include "tls.h" +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_ALERT_COUNT 5u +#define GET_GROUPS_CNT (-1) + +typedef int32_t (*ManageEventProcess)(HITLS_Ctx *ctx); + +typedef int32_t (*WriteEventProcess)(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen); + +typedef int32_t (*ReadEventProcess)(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen); +static inline CM_State GetConnState(const HITLS_Ctx *ctx) +{ + return ctx->state; +} + +int32_t CommonCheckPostHandshakeAuth(TLS_Ctx *ctx); +/** + * @ingroup hitls + * @brief General processing of all events in alerting state + */ +int32_t CommonEventInAlertingState(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief Processe of common events in hanshaking state, attempt to establish a connection + */ +int32_t CommonEventInHandshakingState(HITLS_Ctx *ctx); + +/** + * @ingroup hitls + * @brief If the local end generates an Alert message when sending or receiving messages or processing handshake + * messages, or receives an Alert message from the peer end, the AlertEventProcess needs to be invoked to + * process the Alert status. + */ +int32_t AlertEventProcess(HITLS_Ctx *ctx); + +void ChangeConnState(HITLS_Ctx *ctx, CM_State state); + +/** + * @ingroup hitls + * @brief In the renegotiation state, process the renegotiation event and attempt to establish a connection + * + * @param ctx [IN] TLS connection handle + * + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h + */ +int32_t CommonEventInRenegotiationState(HITLS_Ctx *ctx); + +typedef struct { + HITLS_Ctx *ctx; + uint8_t *buf; + uint32_t bufSize; + uint32_t *size; + enum { READ_EVENT, WRITE_EVENT, MANAGER_EVENT } evenType; + void *func; +} HITLSAsyncArgs; + +int HITLS_EventProcWrapper(void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/cm/src/conn_create.c b/tls/cm/src/conn_create.c new file mode 100644 index 00000000..c72ac011 --- /dev/null +++ b/tls/cm/src/conn_create.c @@ -0,0 +1,608 @@ +/* + * 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 "securec.h" +#include "bsl_err_internal.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "tls_binlog_id.h" +#include "bsl_sal.h" +#include "bsl_errno.h" +#include "bsl_list.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls_config.h" +#include "hitls_cert_type.h" +#include "hitls.h" +#include "tls.h" +#include "tls_config.h" +#include "cert.h" +#include "session.h" +#include "session_mgr.h" +#include "bsl_uio.h" +#include "config.h" +#include "config_check.h" +#include "conn_common.h" +#include "conn_init.h" +#include "crypt.h" +#include "cipher_suite.h" + +static int32_t PeerInfoInit(HITLS_Ctx *ctx) +{ + /* The peerInfo.caList is used to adapt to the OpenSSL behavior. When creating the SSL_CTX object, OpenSSL + * initializes the member so that the member is not null */ + ctx->peerInfo.caList = BSL_LIST_New(sizeof(HITLS_TrustedCANode *)); + if (ctx->peerInfo.caList == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls + * @brief Create a TLS object and deep Copy the HITLS_Config to the HITLS_Ctx. + * @attention After the creation is successful, the HITLS_Config can be released. + * @param config [IN] config Context + * @return HITLS_Ctx Pointer. If the operation fails, null is returned. + */ +HITLS_Ctx *HITLS_New(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return NULL; + } + + int32_t ret; + + HITLS_Ctx *newCtx = (HITLS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HITLS_Ctx)); + if (newCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + + ret = CFG_CheckConfig(config); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(newCtx); + return NULL; + } + + ret = CFG_DumpConfig(newCtx, config); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(newCtx); + return NULL; + } + HITLS_CFG_UpRef(config); + newCtx->globalConfig = config; + + ret = PeerInfoInit(newCtx); + if (ret != HITLS_SUCCESS) { + HITLS_Free(newCtx); + return NULL; + } + + ChangeConnState(newCtx, CM_STATE_IDLE); + return newCtx; +} + +static void CaListNodeDestroy(void *data) +{ + HITLS_TrustedCANode *tmpData = (HITLS_TrustedCANode *)data; + BSL_SAL_FREE(tmpData->data); + BSL_SAL_FREE(tmpData); + return; +} + +static void CleanPeerInfo(PeerInfo *peerInfo) +{ + BSL_SAL_FREE(peerInfo->groups); + BSL_LIST_FREE(peerInfo->caList, CaListNodeDestroy); +} + +static void CleanNegotiatedInfo(TLS_NegotiatedInfo *negotiatedInfo) +{ + BSL_SAL_FREE(negotiatedInfo->cookie); + BSL_SAL_FREE(negotiatedInfo->alpnSelected); + return; +} + +/** + * @ingroup hitls + * @brief Release the TLS connection. + * @param ctx [IN] TLS connection handle. + * @return void + */ +void HITLS_Free(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + ctx->rwstate = HITLS_NOTHING; + CONN_Deinit(ctx); + BSL_UIO_Free(ctx->uio); + BSL_UIO_Free(ctx->rUio); + ctx->rUio = NULL; + ctx->uio = NULL; + + /* Release certificate resources before releasing the config file. Otherwise, memory leakage occurs */ + HITLS_SESS_Free(ctx->session); + CFG_CleanConfig(&ctx->config.tlsConfig); + HITLS_CFG_FreeConfig(ctx->globalConfig); + CleanPeerInfo(&(ctx->peerInfo)); + CleanNegotiatedInfo(&ctx->negotiatedInfo); + SAL_CRYPT_DigestFree(ctx->phaHash); + ctx->phaHash = NULL; + SAL_CRYPT_DigestFree(ctx->phaCurHash); + ctx->phaCurHash = NULL; + ctx->phaState = PHA_NONE; + BSL_SAL_FREE(ctx->certificateReqCtx); + ctx->certificateReqCtxSize = 0; + BSL_SAL_FREE(ctx); + return; +} + +int32_t HITLS_SetReadUio(HITLS_Ctx *ctx, BSL_UIO *uio) +{ + if ((ctx == NULL) || (uio == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + int32_t ret = BSL_UIO_UpRef(uio); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_UIO_FAIL); + return HITLS_UIO_FAIL; + } + + if (ctx->rUio != NULL) { + /* A message is displayed, warning the user that the UIO is set repeatedly */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15662, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "Warning: Repeated uio setting.", 0, 0, 0, 0); + /* Release the original UIO */ + BSL_UIO_Free(ctx->rUio); + } + + ctx->rUio = uio; + + return HITLS_SUCCESS; +} + +/** + * @ingroup hitls + * @brief Set the UIO for the HiTLS context. + * @attention This function must be called before HITLS_Connect and HITLS_Accept and released after HITLS_Free. If this + * function has been called, you must call BSL_UIO_Free to release the UIO. + * @param ctx [OUT] TLS connection handle. + * @param uio [IN] UIO object + * @return HITLS_SUCCESS succeeded + * Other Error Codes, see hitls_error.h + */ +int32_t HITLS_SetUio(HITLS_Ctx *ctx, BSL_UIO *uio) +{ + int32_t ret; + if ((ctx == NULL) || (uio == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + /* The UIO count increases by 1, and the reference counting is performed for the write UIO */ + ret = BSL_UIO_UpRef(uio); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_UIO_FAIL); + return HITLS_UIO_FAIL; + } + + /* The UIO count increases by 1, and the reference counting is performed for reading the UIO */ + ret = BSL_UIO_UpRef(uio); + if (ret != BSL_SUCCESS) { + BSL_UIO_Free(uio); // free Drop the one on the top. + BSL_ERR_PUSH_ERROR(HITLS_UIO_FAIL); + return HITLS_UIO_FAIL; + } + + /* The original write uio is not empty */ + if (ctx->uio != NULL) { + /* A message is displayed, warning the user that the UIO is set repeatedly. */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15960, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "Warning: Repeated uio setting.", 0, 0, 0, 0); + /* Release the original write UIO */ + if (ctx->bUio != NULL) { + ctx->uio = BSL_UIO_PopCurrent(ctx->uio); + } + BSL_UIO_FreeChain(ctx->uio); + } + ctx->uio = uio; + if (ctx->bUio != NULL) { + ret = BSL_UIO_Append(ctx->bUio, ctx->uio); + if (ret != BSL_SUCCESS) { + BSL_UIO_Free(uio); // free Drop the one on the top. + BSL_ERR_PUSH_ERROR(HITLS_UIO_FAIL); + return HITLS_UIO_FAIL; + } + ctx->uio = ctx->bUio; + } + /* The original read UIO is not empty */ + if (ctx->rUio != NULL) { + /* A message is displayed, warning the user that the UIO is set repeatedly */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15253, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "Warning: Repeated uio setting.", 0, 0, 0, 0); + /* Release the original read UIO */ + BSL_UIO_Free(ctx->rUio); + } + ctx->rUio = uio; + + /* The PMTU needs to be set for DTLS. If the PMTU is not set, use the default value */ + if ((ctx->config.pmtu == 0) && IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + ctx->config.pmtu = DTLS_SCTP_PMTU; + } + + return HITLS_SUCCESS; +} + +BSL_UIO *HITLS_GetUio(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + /* If |bUio| is active, the true caller-configured uio is its |next_uio|. */ + if (ctx->config.tlsConfig.isFlightTransmitEnable == true && ctx->bUio != NULL) { + return BSL_UIO_Next(ctx->bUio); + } + return ctx->uio; +} + +BSL_UIO *HITLS_GetReadUio(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + return ctx->rUio; +} + +/** + * @ingroup hitls + * @brief Obtain user data from the HiTLS context. Generally, this interface is invoked during the callback registered + * with the HiTLS. + * @attention must be invoked before HITLS_Connect and HITLS_Accept. The life cycle of the user identifier must be + * longer than the life cycle of the TLS object. + * @param ctx [OUT] TLS connection handle. + * @param userData [IN] User identifier. + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_NULL_INPUT The input parameter TLS object is a null pointer. + */ +void *HITLS_GetUserData(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return ctx->config.userData; +} + +/** + * @ingroup hitls + * @brief User data is stored in the HiTLS context and can be obtained from the callback registered with the HiTLS. + * @attention must be invoked before HITLS_Connect and HITLS_Accept. The life cycle of the user identifier must be + * longer than the life cycle of the TLS object. If the user data needs to be cleared, the + * HITLS_SetUserData(ctx, NULL) interface can be invoked directly. The Clean interface is not provided separately. + * @param ctx [OUT] TLS connection handle. + * @param userData [IN] User identifier. + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_NULL_INPUT The input parameter TLS object is a null pointer. + */ +int32_t HITLS_SetUserData(HITLS_Ctx *ctx, void *userData) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->config.userData = userData; + return HITLS_SUCCESS; +} + +int32_t HITLS_SetErrorCode(HITLS_Ctx *ctx, int32_t errorCode) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->errorCode = errorCode; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetErrorCode(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return ctx->errorCode; +} + +int32_t HITLS_GetSelectedAlpnProto(HITLS_Ctx *ctx, uint8_t **proto, uint32_t *protoLen) +{ + if (ctx == NULL || proto == NULL || protoLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (ctx->negotiatedInfo.alpnSelected == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *proto = ctx->negotiatedInfo.alpnSelected; + *protoLen = ctx->negotiatedInfo.alpnSelectedSize; + + return HITLS_SUCCESS; +} + +int32_t HITLS_IsServer(const HITLS_Ctx *ctx, uint8_t *isServer) +{ + if (ctx == NULL || isServer == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isServer = 0; + if (ctx->isClient == false) { + *isServer = 1; + } + + return HITLS_SUCCESS; +} + +/* Configure the handle for the session information about the HITLS link */ +int32_t HITLS_SetSession(HITLS_Ctx *ctx, HITLS_Session *session) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + /* The client and server are specified only in hitls connect/accept. Therefore, the client cannot be specified here + */ + HITLS_SESS_Free(ctx->session); + + /* Ignore whether the HITLS_SESS_Dup return is NULL or non-NULL */ + ctx->session = HITLS_SESS_Dup(session); + return HITLS_SUCCESS; +} + +/* Obtain the session information handle and directly obtain the pointer */ +HITLS_Session *HITLS_GetSession(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + return ctx->session; +} + +/* Obtain the handle of the copied session information */ +HITLS_Session *HITLS_GetDupSession(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + return HITLS_SESS_Dup(ctx->session); +} + +int32_t HITLS_GetPeerSignatureType(const HITLS_Ctx *ctx, HITLS_SignAlgo *sigType) +{ + HITLS_SignAlgo signAlg = HITLS_SIGN_BUTT; + HITLS_HashAlgo hashAlg = HITLS_HASH_BUTT; + + if (ctx == NULL || sigType == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (CFG_GetSignParamBySchemes(ctx->negotiatedInfo.version, ctx->peerInfo.peerSignHashAlg, + &signAlg, &hashAlg) == false) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE); + return HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE; + } + + *sigType = signAlg; + + return HITLS_SUCCESS; +} + +int32_t HITLS_GetLocalSignScheme(const HITLS_Ctx *ctx, HITLS_SignHashAlgo *localSignScheme) +{ + if (ctx == NULL || localSignScheme == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *localSignScheme = ctx->negotiatedInfo.signScheme; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetPeerSignScheme(const HITLS_Ctx *ctx, HITLS_SignHashAlgo *peerSignScheme) +{ + if (ctx == NULL || peerSignScheme == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *peerSignScheme = ctx->peerInfo.peerSignHashAlg; + return HITLS_SUCCESS; +} + +int32_t HITLS_SetEcGroups(HITLS_Ctx *ctx, uint16_t *lst, uint32_t groupSize) +{ + if (ctx == NULL || lst == NULL || groupSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetGroups(&(ctx->config.tlsConfig), lst, groupSize); +} + +int32_t HITLS_SetSigalgsList(HITLS_Ctx *ctx, const uint16_t *signAlgs, uint16_t signAlgsSize) +{ + if (ctx == NULL || signAlgs == NULL || signAlgsSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSignature(&(ctx->config.tlsConfig), signAlgs, signAlgsSize); +} + +int32_t HITLS_GetRenegotiationSupport(const HITLS_Ctx *ctx, uint8_t *isSupportRenegotiation) +{ + if (ctx == NULL || isSupportRenegotiation == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetRenegotiationSupport(&(ctx->config.tlsConfig), isSupportRenegotiation); +} + +int32_t HITLS_SetEcPointFormats(HITLS_Ctx *ctx, const uint8_t *pointFormats, uint32_t pointFormatsSize) +{ + if (ctx == NULL || pointFormats == NULL || pointFormatsSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetEcPointFormats(&(ctx->config.tlsConfig), pointFormats, pointFormatsSize); +} + +int32_t HITLS_ClearChainCerts(HITLS_Ctx *ctx) +{ + if (ctx == NULL || ctx->config.tlsConfig.certMgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + int32_t ret = HITLS_CFG_ClearChainCerts(&(ctx->config.tlsConfig)); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_SetClientVerifySupport(HITLS_Ctx *ctx, bool support) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetClientVerifySupport(&(ctx->config.tlsConfig), support); +} + +int32_t HITLS_SetNoClientCertSupport(HITLS_Ctx *ctx, bool support) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetNoClientCertSupport(&(ctx->config.tlsConfig), support); +} + +int32_t HITLS_SetPostHandshakeAuthSupport(HITLS_Ctx *ctx, bool support) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetPostHandshakeAuthSupport(&(ctx->config.tlsConfig), support); +} + +int32_t HITLS_SetVerifyNoneSupport(HITLS_Ctx *ctx, bool support) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetVerifyNoneSupport(&(ctx->config.tlsConfig), support); +} + +int32_t HITLS_SetClientOnceVerifySupport(HITLS_Ctx *ctx, bool support) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetClientOnceVerifySupport(&(ctx->config.tlsConfig), support); +} + +int32_t HITLS_SetDhAutoSupport(HITLS_Ctx *ctx, bool support) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetDhAutoSupport(&(ctx->config.tlsConfig), support); +} + +int32_t HITLS_SetTmpDh(HITLS_Ctx *ctx, HITLS_CRYPT_Key *dhPkey) +{ + if (ctx == NULL || dhPkey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetTmpDh(&(ctx->config.tlsConfig), dhPkey); +} + +HITLS_CERT_Chain *HITLS_GetPeerCertChain(const HITLS_Ctx *ctx) +{ + int32_t ret; + CERT_Pair *certPair = NULL; + + if (ctx == NULL || ctx->session == NULL) { + return NULL; + } + + ret = SESS_GetPeerCert(ctx->session, &certPair); + if (ret != HITLS_SUCCESS || certPair == NULL) { + return NULL; + } + + HITLS_CERT_Chain *certChain = SAL_CERT_PairGetChain(certPair); + return certChain; +} + +HITLS_TrustedCAList *HITLS_GetClientCAList(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return ctx->peerInfo.caList; +} + +int32_t HITLS_GetSecureRenegotiationSupport(const HITLS_Ctx *ctx, uint8_t *isSecureRenegotiation) +{ + if (ctx == NULL || isSecureRenegotiation == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSecureRenegotiation = (uint8_t)ctx->negotiatedInfo.isSecureRenegotiation; + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/cm/src/conn_ctrl.c b/tls/cm/src/conn_ctrl.c new file mode 100644 index 00000000..4cf99528 --- /dev/null +++ b/tls/cm/src/conn_ctrl.c @@ -0,0 +1,528 @@ +/* + * 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_error.h" +#include "bsl_err_internal.h" +#include "hitls_type.h" +#include "hitls_config.h" +#include "tls.h" +#include "session.h" +#include "cert_method.h" + +int32_t HITLS_GetNegotiatedVersion(const HITLS_Ctx *ctx, uint16_t *version) +{ + if (ctx == NULL || version == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *version = ctx->negotiatedInfo.version; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetMaxProtoVersion(const HITLS_Ctx *ctx, uint16_t *maxVersion) +{ + if (ctx == NULL || maxVersion == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *maxVersion = ctx->config.tlsConfig.maxVersion; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetMinProtoVersion(const HITLS_Ctx *ctx, uint16_t *minVersion) +{ + if (ctx == NULL || minVersion == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *minVersion = ctx->config.tlsConfig.minVersion; + return HITLS_SUCCESS; +} + +int32_t HITLS_SetMinProtoVersion(HITLS_Ctx *ctx, uint16_t version) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint16_t maxVersion = ctx->config.tlsConfig.maxVersion; + return HITLS_CFG_SetVersion(&(ctx->config.tlsConfig), version, maxVersion); +} + +int32_t HITLS_SetMaxProtoVersion(HITLS_Ctx *ctx, uint16_t version) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint16_t minVersion = ctx->config.tlsConfig.minVersion; + return HITLS_CFG_SetVersion(&(ctx->config.tlsConfig), minVersion, version); +} + +int32_t HITLS_IsAead(const HITLS_Ctx *ctx, uint8_t *isAead) +{ + if (ctx == NULL || isAead == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + /* Check whether the input parameter is empty. The system does not need to check whether the input parameter is + * empty */ + return HITLS_CIPHER_IsAead(&(ctx->negotiatedInfo.cipherSuiteInfo), isAead); +} + +int32_t HITLS_IsDtls(const HITLS_Ctx *ctx, uint8_t *isDtls) +{ + if (ctx == NULL || isDtls == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_IsDtls(&(ctx->config.tlsConfig), isDtls); +} + +int32_t HITLS_IsSessionReused(HITLS_Ctx *ctx, uint8_t *isReused) +{ + if (ctx == NULL || isReused == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isReused = (uint8_t)ctx->negotiatedInfo.isResume; + return HITLS_SUCCESS; +} + +int32_t HITLS_SetSessionIdCtx(HITLS_Ctx *ctx, const uint8_t *sessionIdCtx, uint32_t len) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSessionIdCtx(&ctx->config.tlsConfig, sessionIdCtx, len); +} + +int32_t HITLS_GetSessionTicketKey(const HITLS_Ctx *ctx, uint8_t *key, uint32_t keySize, uint32_t *outSize) +{ + if (ctx == NULL || key == NULL || outSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetSessionTicketKey(&ctx->config.tlsConfig, key, keySize, outSize); +} + +int32_t HITLS_SetSessionTicketKey(HITLS_Ctx *ctx, const uint8_t *key, uint32_t keySize) +{ + if (ctx == NULL || key == NULL || + (keySize != HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_SIZE + HITLS_TICKET_KEY_SIZE)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSessionTicketKey(&ctx->config.tlsConfig, key, keySize); +} + +int32_t HITLS_SetVerifyResult(HITLS_Ctx *ctx, HITLS_ERROR verifyResult) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->peerInfo.verifyResult = verifyResult; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetVerifyResult(const HITLS_Ctx *ctx, HITLS_ERROR *verifyResult) +{ + if (ctx == NULL || verifyResult == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *verifyResult = ctx->peerInfo.verifyResult; + return HITLS_SUCCESS; +} + +HITLS_CERT_X509 *HITLS_GetPeerCertificate(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + CERT_Pair *peerCert = NULL; + + int32_t ret = SESS_GetPeerCert(ctx->session, &peerCert); + if (ret != HITLS_SUCCESS) { + return NULL; + } + + HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(peerCert); + /* Certificate reference increments by one */ + return SAL_CERT_X509Ref(ctx->config.tlsConfig.certMgrCtx, cert); +} + +int32_t HITLS_SetQuietShutdown(HITLS_Ctx *ctx, int32_t mode) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + // The mode value 0 indicates that the quiet disconnection mode is disabled. The mode value 1 indicates that the + // quiet disconnection mode is enabled + if (mode != 0 && mode != 1) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET); + return HITLS_CONFIG_INVALID_SET; + } + + if (mode == 0) { + ctx->config.tlsConfig.isQuietShutdown = false; + } else { + ctx->config.tlsConfig.isQuietShutdown = true; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_GetQuietShutdown(const HITLS_Ctx *ctx, int32_t *mode) +{ + if (ctx == NULL || mode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *mode = (int32_t)ctx->config.tlsConfig.isQuietShutdown; + + return HITLS_SUCCESS; +} + +int32_t HITLS_GetRenegotiationState(const HITLS_Ctx *ctx, uint8_t *isRenegotiationState) +{ + if (ctx == NULL || isRenegotiationState == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isRenegotiationState = (uint8_t)ctx->negotiatedInfo.isRenegotiation; + + return HITLS_SUCCESS; +} + +int32_t HITLS_GetRwstate(const HITLS_Ctx *ctx, uint8_t *rwstate) +{ + if (ctx == NULL || rwstate == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *rwstate = ctx->rwstate; + return HITLS_SUCCESS; +} + +int32_t HITLS_SetShutdownState(HITLS_Ctx *ctx, uint32_t mode) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->shutdownState = mode; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetShutdownState(const HITLS_Ctx *ctx, uint32_t *mode) +{ + if (ctx == NULL || mode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *mode = ctx->shutdownState; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetClientVerifySupport(HITLS_Ctx *ctx, uint8_t *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetClientVerifySupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_GetNoClientCertSupport(HITLS_Ctx *ctx, uint8_t *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetNoClientCertSupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_GetPostHandshakeAuthSupport(HITLS_Ctx *ctx, uint8_t *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetPostHandshakeAuthSupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_GetVerifyNoneSupport(HITLS_Ctx *ctx, uint8_t *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetVerifyNoneSupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_GetClientOnceVerifySupport(HITLS_Ctx *ctx, uint8_t *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetClientOnceVerifySupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_ClearRenegotiationNum(HITLS_Ctx *ctx, uint32_t *renegotiationNum) +{ + if (ctx == NULL || renegotiationNum == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *renegotiationNum = ctx->negotiatedInfo.renegotiationNum; + ctx->negotiatedInfo.renegotiationNum = 0; + return HITLS_SUCCESS; +} + +int32_t HITLS_SetEncryptThenMac(HITLS_Ctx *ctx, uint32_t encryptThenMacType) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetEncryptThenMac(&(ctx->config.tlsConfig), encryptThenMacType); +} + +int32_t HITLS_GetEncryptThenMac(const HITLS_Ctx *ctx, uint32_t *encryptThenMacType) +{ + if (ctx == NULL || encryptThenMacType == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + // Returns the negotiated value if it has been negotiated + if (ctx->negotiatedInfo.version > 0) { + *encryptThenMacType = (uint32_t)ctx->negotiatedInfo.isEncryptThenMac; + return HITLS_SUCCESS; + } else { + return HITLS_CFG_GetEncryptThenMac(&(ctx->config.tlsConfig), encryptThenMacType); + } +} + +int32_t HITLS_SetServerName(HITLS_Ctx *ctx, uint8_t *serverName, uint32_t serverNameStrlen) +{ + if (ctx == NULL || serverName == NULL || serverNameStrlen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetServerName(&(ctx->config.tlsConfig), serverName, serverNameStrlen); +} + +int32_t HITLS_SetCipherServerPreference(HITLS_Ctx *ctx, bool isSupport) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetCipherServerPreference(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_GetCipherServerPreference(const HITLS_Ctx *ctx, bool *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetCipherServerPreference(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_SetRenegotiationSupport(HITLS_Ctx *ctx, bool isSupport) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetRenegotiationSupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_SetSessionTicketSupport(HITLS_Ctx *ctx, bool isSupport) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSessionTicketSupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_GetSessionTicketSupport(const HITLS_Ctx *ctx, uint8_t *isSupport) +{ + if (ctx == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetSessionTicketSupport(&(ctx->config.tlsConfig), isSupport); +} + +int32_t HITLS_SetTicketNums(HITLS_Ctx *ctx, uint32_t ticketNums) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetTicketNums(&ctx->config.tlsConfig, ticketNums); +} + +uint32_t HITLS_GetTicketNums(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetTicketNums(&ctx->config.tlsConfig); +} + +int32_t HITLS_SetFlightTransmitSwitch(HITLS_Ctx *ctx, uint8_t isEnable) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetFlightTransmitSwitch(&(ctx->config.tlsConfig), isEnable); +} + +int32_t HITLS_GetFlightTransmitSwitch(const HITLS_Ctx *ctx, uint8_t *isEnable) +{ + if (ctx == NULL || isEnable == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetFlightTransmitSwitch(&(ctx->config.tlsConfig), isEnable); +} + +/** + * @ingroup hitls + * @brief Set the maximum size of the certificate chain that can be sent by the peer end. + * + * @param ctx [IN/OUT] TLS connection handle + * @param maxSize [IN] Set the maximum size of the certificate chain that can be sent by the peer end. + * @retval HITLS_NULL_INPUT The input parameter pointer is null. + * @retval HITLS_SUCCESS succeeded. + */ +int32_t HITLS_SetMaxCertList(HITLS_Ctx *ctx, uint32_t maxSize) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetMaxCertList(&(ctx->config.tlsConfig), maxSize); +} + +/** + * @ingroup hitls + * @brief Obtain the maximum size of the certificate chain that can be sent by the peer end. + * + * @param ctx [IN] TLS connection handle + * @param maxSize [OUT] Maximum size of the certificate chain that can be sent by the peer end + * @retval HITLS_NULL_INPUT The input parameter pointer is null. + * @retval HITLS_SUCCESS succeeded. + */ +int32_t HITLS_GetMaxCertList(const HITLS_Ctx *ctx, uint32_t *maxSize) +{ + if (ctx == NULL || maxSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetMaxCertList(&(ctx->config.tlsConfig), maxSize); +} + +int32_t HITLS_SetRecordPaddingCb(HITLS_Ctx *ctx, HITLS_RecordPaddingCb cb) +{ + if (ctx == NULL) { + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetRecordPaddingCb(&(ctx->config.tlsConfig), cb); +} + +HITLS_RecordPaddingCb HITLS_GetRecordPaddingCb(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetRecordPaddingCb(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetRecordPaddingCbArg(HITLS_Ctx *ctx, void *arg) +{ + if (ctx == NULL) { + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetRecordPaddingCbArg(&(ctx->config.tlsConfig), arg); +} + +int32_t HITLS_SetCloseCheckKeyUsage(HITLS_Ctx *ctx, bool isClose) +{ + if (ctx == NULL) { + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetCloseCheckKeyUsage(&(ctx->config.tlsConfig), isClose); +} + +void *HITLS_GetRecordPaddingCbArg(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetRecordPaddingCbArg(&(ctx->config.tlsConfig)); +} \ No newline at end of file diff --git a/tls/cm/src/conn_debug.c b/tls/cm/src/conn_debug.c new file mode 100644 index 00000000..1188601f --- /dev/null +++ b/tls/cm/src/conn_debug.c @@ -0,0 +1,95 @@ +/* + * 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 +#include "tls.h" +#include "hitls_error.h" +#include "bsl_err_internal.h" +#include "hitls_debug.h" + +int32_t HITLS_SetInfoCb(HITLS_Ctx *ctx, HITLS_InfoCb callback) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->config.tlsConfig.infoCb = callback; + return HITLS_SUCCESS; +} + +HITLS_InfoCb HITLS_GetInfoCb(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return ctx->config.tlsConfig.infoCb; +} + +int32_t HITLS_CFG_SetInfoCb(HITLS_Config *config, HITLS_InfoCb callback) +{ + /* support NULL callback */ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->infoCb = callback; + return HITLS_SUCCESS; +} + +HITLS_InfoCb HITLS_CFG_GetInfoCb(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + return config->infoCb; +} + + +int32_t HITLS_SetMsgCb(HITLS_Ctx *ctx, HITLS_MsgCb callback) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetMsgCb(&(ctx->config.tlsConfig), callback); +} + +int32_t HITLS_CFG_SetMsgCb(HITLS_Config *config, HITLS_MsgCb callback) +{ + /* support NULL callback */ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->msgCb = callback; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetMsgCbArg(HITLS_Config *config, void *arg) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->msgArg = arg; + + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/cm/src/conn_establish.c b/tls/cm/src/conn_establish.c new file mode 100644 index 00000000..8c555937 --- /dev/null +++ b/tls/cm/src/conn_establish.c @@ -0,0 +1,662 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "tls.h" +#include "hs.h" +#include "alert.h" +#include "conn_init.h" +#include "conn_common.h" +#include "hs.h" +#include "rec.h" +#include "app.h" + +#define DTLS_MIN_MTU 256 /* Minimum MTU setting size */ +#define DTLS_MAX_MTU_OVERHEAD 48 /* Highest MTU overhead, IPv6 40 + UDP 8 */ +#define DATA_MAX_LENGTH 1024 +static int32_t ConnectEventInIdleState(HITLS_Ctx *ctx) +{ + ctx->isClient = true; // Set the configuration as a client + + int32_t ret = CONN_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ChangeConnState(ctx, CM_STATE_HANDSHAKING); + + // In idle state, after initialization, the handshake process is directly started. Therefore, the handshake status + // function is directly invoked. + return CommonEventInHandshakingState(ctx); +} + +static int32_t AcceptEventInIdleState(HITLS_Ctx *ctx) +{ + ctx->isClient = false; // Set the configuration as the server + + int32_t ret = CONN_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ChangeConnState(ctx, CM_STATE_HANDSHAKING); + + // In idle state, after initialization, the handshake process is directly started. Therefore, the handshake status + // function is directly invoked. + return CommonEventInHandshakingState(ctx); +} + +static int32_t EstablishEventInTransportingState(HITLS_Ctx *ctx) +{ + (void)ctx; + // In the renegotiation state, the renegotiation handshake procedure is started. + return HITLS_SUCCESS; +} + +static int32_t EstablishEventInRenegotiationState(HITLS_Ctx *ctx) +{ + // In the renegotiation state, the renegotiation handshake procedure is started. + int32_t ret = CommonEventInRenegotiationState(ctx); + if (ret != HITLS_SUCCESS) { + if (ret == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG && ctx->state != CM_STATE_ALERTED) { + // In this case, the HITLS initiates renegotiation, but the peer end does not respond to the renegotiation + // request but returns an APP message. In this case, the success message should be returned. + return HITLS_SUCCESS; + } + return ret; + } + ctx->userRenego = false; + return HITLS_SUCCESS; +} + +static int32_t EstablishEventInAlertedState(HITLS_Ctx *ctx) +{ + (void)ctx; + // Directly return a message indicating that the link status is abnormal. + return HITLS_CM_LINK_FATAL_ALERTED; +} + +static int32_t EstablishEventInClosedState(HITLS_Ctx *ctx) +{ + (void)ctx; + // Directly return a message indicating that the link status is abnormal. + return HITLS_CM_LINK_CLOSED; +} + +static int32_t CloseEventInIdleState(HITLS_Ctx *ctx) +{ + ChangeConnState(ctx, CM_STATE_CLOSED); + ctx->shutdownState |= (HITLS_SENT_SHUTDOWN | HITLS_RECEIVED_SHUTDOWN); + return HITLS_SUCCESS; +} + +static int32_t CloseEventInTransportingState(HITLS_Ctx *ctx) +{ + if ((ctx->shutdownState & HITLS_SENT_SHUTDOWN) == 0) { + ALERT_Send(ctx, ALERT_LEVEL_WARNING, ALERT_CLOSE_NOTIFY); + int32_t ret = ALERT_Flush(ctx); + if (ret != HITLS_SUCCESS) { + ChangeConnState(ctx, CM_STATE_ALERTING); + return ret; + } + ctx->shutdownState |= HITLS_SENT_SHUTDOWN; + } + + ChangeConnState(ctx, CM_STATE_CLOSED); + return HITLS_SUCCESS; +} + +static int32_t CloseEventInAlertingState(HITLS_Ctx *ctx) +{ + /* If there are fatal alerts that are not sent, the system continues to send the alert. Otherwise, the system sends + * the close_notify alert */ + ALERT_Send(ctx, ALERT_LEVEL_WARNING, ALERT_CLOSE_NOTIFY); + return CommonEventInAlertingState(ctx); +} + +static int32_t CloseEventInAlertedState(HITLS_Ctx *ctx) +{ + /** + * 1. Receive a fatal alert from the peer end. + * 2. A fatal alert has been sent to the peer end. + * 3. Receive the close notification from the peer end. + */ + ChangeConnState(ctx, CM_STATE_CLOSED); + return HITLS_SUCCESS; +} + +static int32_t CloseEventInClosedState(HITLS_Ctx *ctx) +{ + int32_t ret; + + /* When a user invokes the close function for the first time, a close notify message is sent to the peer end. When + * the user invokes the close function for the second time, the user attempts to receive the close notify message. + */ + if ((ctx->shutdownState & HITLS_RECEIVED_SHUTDOWN) == 0) { + uint8_t data[DATA_MAX_LENGTH]; // Discard the received APP message. + uint32_t readLen = 0; + + ALERT_CleanInfo(ctx); + + ret = APP_Read(ctx, data, sizeof(data), &readLen); + if (ret == HITLS_SUCCESS) { + return HITLS_SUCCESS; + } + + if (ALERT_GetFlag(ctx) == false) { + return ret; + } + + ret = AlertEventProcess(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ChangeConnState(ctx, CM_STATE_CLOSED); + return HITLS_SUCCESS; +} + +// Check and process the CTX status before HITLS_Connect and HITLS_Accept. +int32_t ProcessCtxState(HITLS_Ctx *ctx) +{ + int32_t ret; + + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + /* Process the unsent alert message first, and then enter the corresponding state processing function based on the + * processing result */ + if (GetConnState(ctx) == CM_STATE_ALERTING) { + ret = CommonEventInAlertingState(ctx); + if (ret != HITLS_SUCCESS) { + /* If the alert fails to be sent, a response is returned to the user */ + return ret; + } + } + + if ((GetConnState(ctx) >= CM_STATE_END) || (GetConnState(ctx) == CM_STATE_ALERTING)) { + /* If the alert message is sent successfully, the system switches to another state. Otherwise, an internal + * exception occurs */ + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_SetEndPoint(HITLS_Ctx *ctx, bool isClient) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (GetConnState(ctx) != CM_STATE_IDLE) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_STATE_ILLEGAL); + return HITLS_MSG_HANDLE_STATE_ILLEGAL; + } + + ctx->isClient = isClient; + + int32_t ret = CONN_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ChangeConnState(ctx, CM_STATE_HANDSHAKING); + return HITLS_SUCCESS; +} + +int32_t HITLS_Connect(HITLS_Ctx *ctx) +{ + // Process the alerting state + int32_t ret = ProcessCtxState(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ManageEventProcess connectEventProcess[CM_STATE_END] = { + ConnectEventInIdleState, + CommonEventInHandshakingState, + EstablishEventInTransportingState, + EstablishEventInRenegotiationState, + NULL, // The alerting phase has been processed in the ProcessCtxState function + EstablishEventInAlertedState, + EstablishEventInClosedState}; + + ManageEventProcess proc = connectEventProcess[GetConnState(ctx)]; + + ret = proc(ctx); + return ret; +} + +int32_t HITLS_Accept(HITLS_Ctx *ctx) +{ + int32_t ret; + + ret = ProcessCtxState(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = CommonCheckPostHandshakeAuth(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ManageEventProcess acceptEventProcess[CM_STATE_END] = { + AcceptEventInIdleState, + CommonEventInHandshakingState, + EstablishEventInTransportingState, + EstablishEventInRenegotiationState, + NULL, + EstablishEventInAlertedState, + EstablishEventInClosedState + }; + + ManageEventProcess proc = acceptEventProcess[GetConnState(ctx)]; + + ret = proc(ctx); + return ret; +} + +int32_t HITLS_Close(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->userShutDown = 1; + + if (ctx->config.tlsConfig.isQuietShutdown) { + ctx->shutdownState |= (HITLS_SENT_SHUTDOWN | HITLS_RECEIVED_SHUTDOWN); + ChangeConnState(ctx, CM_STATE_CLOSED); + return HITLS_SUCCESS; + } + + ManageEventProcess closeEventProcess[CM_STATE_END] = { + CloseEventInIdleState, + CloseEventInTransportingState, // Notify is sent to the peer end when the close interface is invoked during and + // after link establishment. + CloseEventInTransportingState, // Therefore, the same function is used for processing. + CloseEventInTransportingState, // In the renegotiation process, invoking the close function also sends a notify + // message to the peer end. + CloseEventInAlertingState, + CloseEventInAlertedState, + CloseEventInClosedState}; + + if (GetConnState(ctx) >= CM_STATE_END) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret; + + do { + ManageEventProcess proc = closeEventProcess[GetConnState(ctx)]; + ret = proc(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } while (GetConnState(ctx) != CM_STATE_CLOSED); + + return HITLS_SUCCESS; +} + +int32_t HITLS_IsHandShakeDone(const HITLS_Ctx *ctx, uint8_t *isDone) +{ + if (ctx == NULL || isDone == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isDone = 0; + if (ctx->state == CM_STATE_TRANSPORTING) { + *isDone = 1; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_GetError(const HITLS_Ctx *ctx, int32_t ret) +{ + if (ctx == NULL) { + /* Unknown error */ + return HITLS_ERR_SYSCALL; + } + + /* No internal error occurs in the SSL */ + if (ret == HITLS_SUCCESS) { + return HITLS_SUCCESS; + } + + /* HANDSHAKING state */ + if (ctx->state == CM_STATE_HANDSHAKING) { + /* In non-blocking mode, I/O read/write failure is acceptable and link establishment is allowed */ + if (ret == HITLS_REC_NORMAL_IO_BUSY || ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY) { + return (ctx->isClient == true) ? HITLS_WANT_CONNECT : HITLS_WANT_ACCEPT; + } + + /* Unacceptable exceptions occur on the underlying I/O */ + if (ret == HITLS_REC_ERR_IO_EXCEPTION) { + return HITLS_ERR_SYSCALL; + } + + /* The TLS protocol is incorrect */ + return HITLS_ERR_TLS; + } + + /* TRANSPORTING state */ + if (ctx->state == CM_STATE_TRANSPORTING) { + /* An I/O read/write failure occurs in non-blocking mode. This failure is acceptable and data can be written */ + if (ret == HITLS_REC_NORMAL_IO_BUSY) { + return HITLS_WANT_WRITE; + } + + /* An I/O read/write failure occurs in non-blocking mode. This failure is acceptable and data can be read + * continuously */ + if (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY) { + return HITLS_WANT_READ; + } + + /* Unacceptable exceptions occur on the underlying I/O */ + if (ret == HITLS_REC_ERR_IO_EXCEPTION) { + return HITLS_ERR_SYSCALL; + } + + /* The TLS protocol is incorrect */ + return HITLS_ERR_TLS; + } + + /* ALERTING state */ + if (ctx->state == CM_STATE_ALERTING) { + if (ret == HITLS_REC_NORMAL_IO_BUSY) { + return HITLS_WANT_WRITE; + } + + if (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY) { + return HITLS_WANT_READ; + } + } + + /* ALERTED state ,indicating that the TLS protocol is faulty and the link is abnormal */ + if (ctx->state == CM_STATE_ALERTED) { + return HITLS_ERR_TLS; + } + + /* Unknown error */ + return HITLS_ERR_SYSCALL; +} + +int32_t HITLS_GetHandShakeState(const HITLS_Ctx *ctx, uint32_t *state) +{ + if (ctx == NULL || state == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint32_t hsState = TLS_IDLE; + /* In initialization state */ + if (ctx->state == CM_STATE_IDLE) { + hsState = TLS_IDLE; + } + + /* The link has been set up */ + if (ctx->state == CM_STATE_TRANSPORTING) { + hsState = TLS_CONNECTED; + } + + /* The link is being established. If hsctx is not empty, obtain the status */ + if (ctx->state == CM_STATE_HANDSHAKING || + ctx->state == CM_STATE_RENEGOTIATION) { + hsState = HS_GetState(ctx); + } + + if (ctx->state == CM_STATE_ALERTING) { + /* If hsCtx is not empty, it indicates that the link is being established. Obtain the corresponding status */ + if (ctx->hsCtx != NULL) { + hsState = HS_GetState(ctx); + } else { + /* After the link is established, the hsCtx is released. In this case, the hsCtx is in connected state */ + hsState = TLS_CONNECTED; + } + } + + if (ctx->state == CM_STATE_ALERTED || ctx->state == CM_STATE_CLOSED) { + /** + * The appctx is initialized when a link is set up and released until the transfer is complete. + * Therefore, the value of NULL indicates that the link is not established and the link is in idle state. + */ + if (ctx->appCtx == NULL) { + hsState = TLS_IDLE; + } else if (ctx->hsCtx != NULL) { + /* If the value of ctx->hsCtx is not NULL, it indicates that the link is being established */ + hsState = HS_GetState(ctx); + } else { + /* If hsCtx is NULL, the link has been established */ + hsState = TLS_CONNECTED; + } + } + + *state = hsState; + return HITLS_SUCCESS; +} + +int32_t HITLS_IsHandShaking(const HITLS_Ctx *ctx, uint8_t *isHandShaking) +{ + if (ctx == NULL || isHandShaking == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isHandShaking = 0; + uint32_t state = GetConnState(ctx); + if ((state == CM_STATE_HANDSHAKING) || (state == CM_STATE_RENEGOTIATION)) { + *isHandShaking = 1; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_IsBeforeHandShake(const HITLS_Ctx *ctx, uint8_t *isBefore) +{ + if (ctx == NULL || isBefore == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *isBefore = 0; + if (GetConnState(ctx) == CM_STATE_IDLE) { + *isBefore = 1; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_SetMtu(HITLS_Ctx *ctx, long mtu) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (mtu < DTLS_MIN_MTU - DTLS_MAX_MTU_OVERHEAD) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + ctx->config.pmtu = (uint16_t)mtu; + return HITLS_SUCCESS; +} + +int32_t HITLS_GetClientVersion(const HITLS_Ctx *ctx, uint16_t *clientVersion) +{ + if (ctx == NULL || clientVersion == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *clientVersion = ctx->negotiatedInfo.clientVersion; + return HITLS_SUCCESS; +} + +const char *HITLS_GetStateString(uint32_t state) +{ + return HS_GetStateStr(state); +} + +int32_t HITLS_DoHandShake(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (ctx->isClient) { + return HITLS_Connect(ctx); + } else { + return HITLS_Accept(ctx); + } +} + +/* The updateType types are as follows: HITLS_UPDATE_NOT_REQUESTED (0), HITLS_UPDATE_REQUESTED (1) or + * HITLS_KEY_UPDATE_REQ_END(255). The local end sends 1 and the peer end sends 0 to the local end. The local end sends 0 + * and the peer end does not send 0 to the local end. + */ +int32_t HITLS_KeyUpdate(HITLS_Ctx *ctx, uint32_t updateType) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + // Check whether the version is TLS1.3, whether the current status is transporting, and whether update is allowed. + int32_t ret = HS_CheckKeyUpdateState(ctx, updateType); + if (ret != HITLS_SUCCESS) { + return ret; + } + ctx->keyUpdateType = updateType; + ctx->isKeyUpdateRequest = true; + // Successfully sendKeyUpdate. Set isKeyUpdateRequest to false and keyUpdateType to HITLS_KEY_UPDATE_REQ_END. + ret = HS_SendKeyUpdate(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_GetKeyUpdateType(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (ctx->isKeyUpdateRequest) { + return (int32_t)ctx->keyUpdateType; + } + + return HITLS_KEY_UPDATE_REQ_END; +} + +static int32_t CheckRenegotiateValid(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint8_t isSupport = false; + + (void)HITLS_GetRenegotiationSupport(ctx, &isSupport); + /* Renegotiation is disabled */ + if (isSupport == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15981, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "forbid renegotiate.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CM_LINK_UNSUPPORT_SECURE_RENEGOTIATION); + return HITLS_CM_LINK_UNSUPPORT_SECURE_RENEGOTIATION; + } + + /* If the version is TLS1.3 or the current link does not support security renegotiation, the system returns. */ + if ((ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) || (!ctx->negotiatedInfo.isSecureRenegotiation)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15953, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unsupported renegotiate.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CM_LINK_UNSUPPORT_SECURE_RENEGOTIATION); + return HITLS_CM_LINK_UNSUPPORT_SECURE_RENEGOTIATION; + } + + /* If the link is not established, renegotiation cannot be performed. */ + if ((ctx->state != CM_STATE_TRANSPORTING) && (ctx->state != CM_STATE_RENEGOTIATION)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15954, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "please complete the link establishment first.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CM_LINK_UNESTABLISHED); + return HITLS_CM_LINK_UNESTABLISHED; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_Renegotiate(HITLS_Ctx *ctx) +{ + int32_t ret; + ret = CheckRenegotiateValid(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->negotiatedInfo.isRenegotiation) { + /* If the current state is renegotiation, no change is made. */ + return HITLS_SUCCESS; + } + + ctx->negotiatedInfo.isRenegotiation = true; /* Start renegotiation */ + + if (ctx->hsCtx != NULL) { + HS_DeInit(ctx); + } + + ret = HS_Init(ctx); + if (ret != HITLS_SUCCESS) { + ctx->negotiatedInfo.isRenegotiation = false; /* renegotiation fails */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15955, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "HS_Init fail when start renegotiate.", 0, 0, 0, 0); + return ret; + } + + ctx->userRenego = true; /* renegotiation initiated by the local end */ + ctx->negotiatedInfo.renegotiationNum++; + ChangeConnState(ctx, CM_STATE_RENEGOTIATION); + return HITLS_SUCCESS; +} + +int32_t HITLS_VerifyClientPostHandshake(HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return HITLS_NULL_INPUT; + } + if (ctx->isClient) { + return HITLS_INVALID_INPUT; + } + if (ctx->state != CM_STATE_TRANSPORTING || ctx->phaState != PHA_EXTENSION) { + return HITLS_MSG_HANDLE_STATE_ILLEGAL; + } + ctx->phaState = PHA_PENDING; + return HITLS_SUCCESS; +} diff --git a/tls/cm/src/conn_init.c b/tls/cm/src/conn_init.c new file mode 100644 index 00000000..90d3a7ab --- /dev/null +++ b/tls/cm/src/conn_init.c @@ -0,0 +1,141 @@ +/* + * 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 +#include "hitls_error.h" +#include "bsl_err_internal.h" +#include "hitls_type.h" +#include "rec.h" +#include "hs.h" +#include "app.h" +#include "alert.h" +#include "change_cipher_spec.h" +#include "conn_common.h" +#include "hs_ctx.h" + +// an instance of unexpectedMsgProcessCb +int32_t ConnUnexpectedMsg(HITLS_Ctx *ctx, uint32_t msgType, const uint8_t *data, uint32_t dataLen) +{ + if (ctx == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + int32_t ret = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + CM_State linkState = ctx->state; + + /* In closed state, only unexpected alert messages are received. */ + if (GetConnState(ctx) == CM_STATE_CLOSED) { + if (msgType == REC_TYPE_ALERT) { + ALERT_Recv(ctx, data, dataLen); + } + BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG); + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + + switch (msgType) { + case REC_TYPE_CHANGE_CIPHER_SPEC: + CCS_Recv(ctx, data, dataLen); + break; + case REC_TYPE_ALERT: + if (ctx->hsCtx != NULL && ctx->config.tlsConfig.maxVersion != HITLS_VERSION_TLCP11 && + ctx->hsCtx->state == TRY_RECV_CLIENT_HELLO && ctx->negotiatedInfo.version == 0 && + data[0] == ALERT_LEVEL_WARNING) { + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + ALERT_Recv(ctx, data, dataLen); + break; + case REC_TYPE_HANDSHAKE: + ret = HS_RecvUnexpectedMsgProcess(ctx, data, dataLen, &linkState); + ChangeConnState(ctx, linkState); + if (ret == HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE) { + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + break; + case REC_TYPE_APP: + if (HS_IsAppDataAllowed(ctx)) { + APP_RecvUnexpectedMsgProcess(ctx, data, dataLen); + break; + } + /* If app messages are not allowed to be received, needs send an alert message */ + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + break; + default: + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + break; + } + if (ret == HITLS_SUCCESS) { + ret = HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + return ret; +} + +int32_t CONN_Init(TLS_Ctx *ctx) +{ + int32_t ret; + + ret = REC_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ALERT_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CCS_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = APP_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ctx->method.isRecvCCS = CCS_IsRecv; + ctx->method.sendCCS = CCS_Send; + ctx->method.ctrlCCS = CCS_Ctrl; + ctx->method.sendAlert = ALERT_Send; + ctx->method.getAlertFlag = ALERT_GetFlag; + ctx->method.unexpectedMsgProcessCb = ConnUnexpectedMsg; + + ctx->keyUpdateType = HITLS_KEY_UPDATE_REQ_END; + ctx->isKeyUpdateRequest = false; + + // default value is X509_V_OK(0) + ctx->peerInfo.verifyResult = 0; + + ctx->rwstate = HITLS_NOTHING; + + return HITLS_SUCCESS; +} + +void CONN_Deinit(TLS_Ctx *ctx) +{ + REC_DeInit(ctx); + ALERT_Deinit(ctx); + CCS_DeInit(ctx); + HS_DeInit(ctx); + APP_DeInit(ctx); + return; +} \ No newline at end of file diff --git a/tls/cm/src/conn_read.c b/tls/cm/src/conn_read.c new file mode 100644 index 00000000..c1aa5d5f --- /dev/null +++ b/tls/cm/src/conn_read.c @@ -0,0 +1,256 @@ +/* + * 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_error.h" +#include "bsl_err_internal.h" +#include "hitls_type.h" +#include "tls.h" +#include "rec.h" +#include "alert.h" +#include "app.h" +#include "conn_common.h" +#include "hs.h" + +static int32_t ReadEventInIdleState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + (void)ctx; + (void)data; + (void)bufSize; + (void)readLen; + return HITLS_CM_LINK_UNESTABLISHED; +} + +int32_t RecvUnexpectMsgInTransportingStateProcess(HITLS_Ctx *ctx) +{ + if (ctx->phaState == PHA_REQUESTED && ctx->hsCtx != NULL) { + return CommonEventInHandshakingState(ctx); + } + /* Discard the unexpected message received but not the renegotiation request */ + if (!ctx->negotiatedInfo.isRenegotiation) { + return HITLS_SUCCESS; + } + + /* If the renegotiation request is received, perform renegotiation */ + int32_t ret = CommonEventInRenegotiationState(ctx); + if (ret == HITLS_SUCCESS) { + /* The renegotiation initiated by the peer end is processed and returned. */ + return HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } + if (ret != HITLS_REC_NORMAL_RECV_UNEXPECT_MSG) { + /* If an error is returned during renegotiation, the error code must be sent to the user */ + return ret; + } + if (ctx->state == CM_STATE_ALERTED) { + /* If the alert message has been processed, the link must be disconnected */ + return ret; + } + /* The APP message received during the renegotiation process needs to be written into the user buffer */ + return HITLS_SUCCESS; +} + +static int32_t ReadEventInTransportingState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int32_t ret; + int32_t unexpectMsgRet; + uint32_t alertCount = 0; + + do { + ret = APP_Read(ctx, data, bufSize, readLen); + if (ret == HITLS_SUCCESS) { + /* An APP message is received */ + break; + } + + if (ALERT_GetFlag(ctx)) { + alertCount++; + if (alertCount >= MAX_ALERT_COUNT) { + /* If multiple consecutive alerts exist, the link is abnormal and needs to be disconnected */ + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + unexpectMsgRet = AlertEventProcess(ctx); + if (unexpectMsgRet != HITLS_SUCCESS) { + /* If the alert fails to be sent, a response is returned to the user for processing */ + return unexpectMsgRet; + } + + /* If fatal alert or close_notify has been processed, the link must be disconnected */ + if (ctx->state == CM_STATE_ALERTED) { + return ret; + } + continue; + } + + if (ret != HITLS_REC_NORMAL_RECV_UNEXPECT_MSG) { + return ret; + } + + unexpectMsgRet = RecvUnexpectMsgInTransportingStateProcess(ctx); + if (unexpectMsgRet != HITLS_SUCCESS) { + return unexpectMsgRet; + } + } while (ret != HITLS_SUCCESS); + + return ret; +} + +static int32_t ReadEventInHandshakingState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int32_t ret = CommonEventInHandshakingState(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return ReadEventInTransportingState(ctx, data, bufSize, readLen); +} + +static int32_t ReadEventInRenegotiationState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int32_t ret = CommonEventInRenegotiationState(ctx); + if (ret != HITLS_SUCCESS) { + if (ret != HITLS_REC_NORMAL_RECV_UNEXPECT_MSG) { + /* If an error is returned during the renegotiation, the error code must be sent to the user */ + return ret; + } + /* The scenario is that the HITLS initiates renegotiation, but the peer end does not respond with a handshake + * message and continues to send the app message. In this case, you need to read the app message to prevent + * message blocking. + */ + if (APP_GetReadPendingBytes(ctx) > 0u) { + ret = APP_Read(ctx, data, bufSize, readLen); + } else if (ctx->state != CM_STATE_ALERTED) { + ret = HITLS_SUCCESS; /* If an empty APP message is received, a success message should be returned */ + } + return ret; + } + + if (!ctx->userRenego) { + /* The renegotiation initiated by the peer end is processed and returned. */ + return HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } + ctx->userRenego = false; + return ReadEventInTransportingState(ctx, data, bufSize, readLen); +} + +static int32_t ReadEventInAlertedState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + (void)ctx; + (void)data; + (void)bufSize; + (void)readLen; + // A message indicating that the link status is abnormal is displayed. + return HITLS_CM_LINK_FATAL_ALERTED; +} + +static int32_t ReadEventInClosedState(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + // Non-closed state + if ((ctx->shutdownState & HITLS_RECEIVED_SHUTDOWN) == 0) { + ALERT_CleanInfo(ctx); + int32_t ret = APP_Read(ctx, data, bufSize, readLen); + if (ret == HITLS_SUCCESS) { + return HITLS_SUCCESS; + } + // There is no alert message to be processed. + if (ALERT_GetFlag(ctx) == false) { + return ret; + } + + int32_t alertRet = AlertEventProcess(ctx); + if (alertRet != HITLS_SUCCESS) { + return alertRet; + } + /* Other warning alerts have been processed. */ + if ((ctx->shutdownState & HITLS_RECEIVED_SHUTDOWN) == 0) { + return ret; + } + } + // Directly return to link closed. + return HITLS_CM_LINK_CLOSED; +} + +int32_t HITLS_Read(HITLS_Ctx *ctx, uint8_t *data, uint32_t bufSize, uint32_t *readLen) +{ + int32_t ret; + if (ctx == NULL || data == NULL || readLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + /* Process the unsent alert message first, and then enter the corresponding state processing function based on the + * processing result */ + if (GetConnState(ctx) == CM_STATE_ALERTING) { + ret = CommonEventInAlertingState(ctx); + if (ret != HITLS_SUCCESS) { + /* If the alert message fails to be sent, the system returns the message to the user for processing */ + return ret; + } + } + + /* The unsent key update message is processed first, and the corresponding status processing function is entered + * according to the processing result */ + if (ctx->isKeyUpdateRequest) { + ret = HS_CheckKeyUpdateState(ctx, ctx->keyUpdateType); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = HS_SendKeyUpdate(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ReadEventProcess readEventProcess[CM_STATE_END] = { + ReadEventInIdleState, + ReadEventInHandshakingState, + ReadEventInTransportingState, + ReadEventInRenegotiationState, + NULL, + ReadEventInAlertedState, + ReadEventInClosedState + }; + + if ((GetConnState(ctx) >= CM_STATE_END) || (GetConnState(ctx) == CM_STATE_ALERTING)) { + /* If the alert message is sent successfully, the system switches to another state. Otherwise, an internal + * exception occurs */ + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + ReadEventProcess proc = readEventProcess[GetConnState(ctx)]; + + ret = proc(ctx, data, bufSize, readLen); + return ret; +} + +int32_t HITLS_ReadHasPending(const HITLS_Ctx *ctx, uint8_t *isPending) +{ + if (ctx == NULL || isPending == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isPending = 0; + if (APP_GetReadPendingBytes(ctx) > 0 || REC_ReadHasPending(ctx)) { + *isPending = 1; + } + + return HITLS_SUCCESS; +} + +uint32_t HITLS_GetReadPendingBytes(const HITLS_Ctx *ctx) +{ + return APP_GetReadPendingBytes(ctx); +} diff --git a/tls/cm/src/conn_write.c b/tls/cm/src/conn_write.c new file mode 100644 index 00000000..9d7227db --- /dev/null +++ b/tls/cm/src/conn_write.c @@ -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 "bsl_log_internal.h" +#include "bsl_err_internal.h" +#include "bsl_log.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "tls.h" +#include "alert.h" +#include "app.h" +#include "conn_common.h" +#include "hs.h" + +int32_t HITLS_GetMaxWriteSize(const HITLS_Ctx *ctx, uint32_t *len) +{ + if (ctx == NULL || len == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return APP_GetMaxWriteSize(ctx, len); +} + +static int32_t WriteEventInIdleState(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + (void)ctx; + (void)data; + (void)dataLen; + BSL_ERR_PUSH_ERROR(HITLS_CM_LINK_UNESTABLISHED); + return HITLS_CM_LINK_UNESTABLISHED; +} + +static int32_t WriteEventInTransportingState(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + int32_t ret; + int32_t alertRet; + uint32_t alertCount = 0; + + do { + ret = APP_Write(ctx, data, dataLen); + if (ret == HITLS_SUCCESS) { + /* The message is sent successfully */ + break; + } + + if (!ALERT_GetFlag(ctx)) { + /* Failed to send a message but no alert is displayed */ + break; + } + + alertCount++; + if (alertCount >= MAX_ALERT_COUNT) { + /* If multiple consecutive alerts exist, the link is abnormal and needs to be disconnected */ + ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + alertRet = AlertEventProcess(ctx); + if (alertRet != HITLS_SUCCESS) { + /* If the alert fails to be sent, a response is returned to the user */ + return alertRet; + } + + /* If fatal alert or close_notify has been processed, the link must be disconnected. */ + if (ctx->state == CM_STATE_ALERTED) { + break; + } + } while (ret != HITLS_SUCCESS); + + return ret; +} + +static int32_t WriteEventInHandshakingState(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + // The link is being established. Therefore, the link establishment is triggered first. If the link is successfully + // established, the message is directly sent. + int32_t ret = CommonEventInHandshakingState(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return WriteEventInTransportingState(ctx, data, dataLen); +} + +static int32_t WriteEventInRenegotiationState(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + int32_t ret; + do { + /* If an unexpected message is received, the system ignores the return value and continues to establish a link. + * Otherwise, the system returns the return value to the user for processing */ + ret = CommonEventInRenegotiationState(ctx); + } while (ret == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG && ctx->state != CM_STATE_ALERTED); + if (ret != HITLS_SUCCESS) { + if (ctx->negotiatedInfo.isRenegotiation || (ret != HITLS_REC_NORMAL_RECV_BUF_EMPTY)) { + /* If an error is returned during renegotiation, the error code must be sent to the user */ + return ret; + } + /* The scenario is that the HITLS server initiates renegotiation, but the peer end does not respond with the + * client hello message. In this case,the app message needs to be sent to the peer end to prevent message + * blocking + */ + } + + ctx->userRenego = false; + return WriteEventInTransportingState(ctx, data, dataLen); +} + +static int32_t WriteEventInAlertedState(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + (void)ctx; + (void)data; + (void)dataLen; + // Directly return a message indicating that the link status is abnormal. + BSL_ERR_PUSH_ERROR(HITLS_CM_LINK_FATAL_ALERTED); + return HITLS_CM_LINK_FATAL_ALERTED; +} + +static int32_t WriteEventInClosedState(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + (void)ctx; + (void)data; + (void)dataLen; + // Directly return a message indicating that the link status is abnormal. + BSL_ERR_PUSH_ERROR(HITLS_CM_LINK_CLOSED); + return HITLS_CM_LINK_CLOSED; +} + +int32_t CommonCheckPostHandshakeAuth(TLS_Ctx *ctx) +{ + if (!ctx->isClient && ctx->phaState == PHA_PENDING && ctx->state == CM_STATE_TRANSPORTING) { + ChangeConnState(ctx, CM_STATE_HANDSHAKING); + return HS_CheckPostHandshakeAuth(ctx); + } + return HITLS_SUCCESS; +} + +static int32_t HITLS_WritePreporcess(HITLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /* Process the unsent alert message first, and then enter the corresponding state processing function based on the + * processing result */ + if (GetConnState(ctx) == CM_STATE_ALERTING) { + ret = CommonEventInAlertingState(ctx); + if (ret != HITLS_SUCCESS) { + /* If the alert message fails to be sent, the system returns the message to the user for processing */ + return ret; + } + } + + /* Process the key update message that is not sent, and then enter the corresponding state processing function + * according to the processing resul */ + if (ctx->isKeyUpdateRequest) { + ret = HS_CheckKeyUpdateState(ctx, ctx->keyUpdateType); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = HS_SendKeyUpdate(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + return CommonCheckPostHandshakeAuth(ctx); +} + +int32_t HITLS_Write(HITLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen) +{ + int32_t ret; + if (ctx == NULL || data == NULL || dataLen == 0) { + return HITLS_NULL_INPUT; + } + + ret = HITLS_WritePreporcess(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + WriteEventProcess writeEventProcess[CM_STATE_END] = { + WriteEventInIdleState, + WriteEventInHandshakingState, + WriteEventInTransportingState, + WriteEventInRenegotiationState, + NULL, + WriteEventInAlertedState, + WriteEventInClosedState + }; + + if ((GetConnState(ctx) >= CM_STATE_END) || (GetConnState(ctx) == CM_STATE_ALERTING)) { + /* If the alert message is sent successfully, the system switches to another state. Otherwise, an internal + * exception occurs */ + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + WriteEventProcess proc = writeEventProcess[GetConnState(ctx)]; + + ret = proc(ctx, data, dataLen); + return ret; +} diff --git a/tls/config/include/config.h b/tls/config/include/config.h new file mode 100644 index 00000000..be3f0b41 --- /dev/null +++ b/tls/config/include/config.h @@ -0,0 +1,36 @@ +/* + * 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 CONFIG_H +#define CONFIG_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** clear the TLS configuration */ +void CFG_CleanConfig(HITLS_Config *config); + +/** copy the TLS configuration */ +int32_t CFG_DumpConfig(HITLS_Ctx *ctx, const HITLS_Config *srcConfig); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/config/include/config_check.h b/tls/config/include/config_check.h new file mode 100644 index 00000000..10988a81 --- /dev/null +++ b/tls/config/include/config_check.h @@ -0,0 +1,36 @@ +/* + * 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 CONFIG_CHECK_H +#define CONFIG_CHECK_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** check the version */ +int32_t CFG_CheckVersion(uint16_t minVersion, uint16_t maxVersion); + +/** check whether the TLS configuration is valid */ +int32_t CFG_CheckConfig(const HITLS_Config *config); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/config/src/cipher_suite.c b/tls/config/src/cipher_suite.c new file mode 100644 index 00000000..1a503b51 --- /dev/null +++ b/tls/config/src/cipher_suite.c @@ -0,0 +1,2003 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "tls_config.h" +#include "cipher_suite.h" + + +#define KEY_BLOCK_PARTITON_LENGTH(fixedIvLth, encKeyLth, macKeyLth, blockLth, recordIvLth, macLth) \ + .fixedIvLength = (fixedIvLth), \ + .encKeyLen = (encKeyLth), \ + .macKeyLen = (macKeyLth), \ + .blockLength = (blockLth), \ + .recordIvLength = (recordIvLth), \ + .macLen = (macLth) \ + +#define VERSION_SCOPE(minV, maxV, minDtlsV, maxDtlsV) \ + .minVersion = (minV), \ + .maxVersion = (maxV), \ + .minDtlsVersion = (minDtlsV), \ + .maxDtlsVersion = (maxDtlsV) + +#define CIPHERSUITE_DESCRIPTION_MAXLEN 128 + +/* If cipher suites need to be added in the future, you need to consider whether the cipher suites are suitable for DTLS +in terms of design. If DTLS is not supported, perform related operations. For example, the RC4 stream encryption +algorithm is not applicable to DTLS. */ +static const CipherSuiteInfo g_cipherSuiteList[] = { + {.enable = true, + .name = "HITLS_AES_128_GCM_SHA256", + .stdName = "TLS_AES_128_GCM_SHA256", + .cipherSuite = HITLS_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_NULL, + .authAlg = HITLS_AUTH_ANY, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 16u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0u, 0u), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_AES_256_GCM_SHA384", + .stdName = "TLS_AES_256_GCM_SHA384", + .cipherSuite = HITLS_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_NULL, + .authAlg = HITLS_AUTH_ANY, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0u, 0u), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_NULL, + .authAlg = HITLS_AUTH_ANY, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0u, 0u), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_AES_128_CCM_SHA256", + .stdName = "TLS_AES_128_CCM_SHA256", + .cipherSuite = HITLS_AES_128_CCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CCM, + .kxAlg = HITLS_KEY_EXCH_NULL, + .authAlg = HITLS_AUTH_ANY, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 16u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0u, 0u), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_AES_128_CCM_8_SHA256", + .stdName = "TLS_AES_128_CCM_8_SHA256", + .cipherSuite = HITLS_AES_128_CCM_8_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CCM8, + .kxAlg = HITLS_KEY_EXCH_NULL, + .authAlg = HITLS_AUTH_ANY, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 16u, 0u, 0u, 0u, 8u), + VERSION_SCOPE(HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0u, 0u), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_128_CBC_SHA", + .stdName = "TLS_RSA_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_256_CBC_SHA", + .stdName = "TLS_RSA_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_RSA_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_RSA_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_RSA_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_256_CBC_SHA256", + .stdName = "TLS_RSA_WITH_AES_256_CBC_SHA256", + .cipherSuite = HITLS_RSA_WITH_AES_256_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_RSA_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_RSA_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_RSA_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_RSA_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA384, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_384, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 48u, 16u, 16u, 48u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + .stdName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + .stdName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + .stdName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + .cipherSuite = HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_384, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA384, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 48u, 16u, 16u, 48u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_DSS, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_DSA_SHA256, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_DSS, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_DSA_SHA384, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_DSS_WITH_AES_128_CBC_SHA", + .stdName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_DHE_DSS_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_DSS, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_DSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_DSS_WITH_AES_256_CBC_SHA", + .stdName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_DHE_DSS_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_DSS, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_DSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_DSS, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_DSA_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256", + .stdName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", + .cipherSuite = HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_DSS, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_DSA_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_128_CBC_SHA", + .stdName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_256_CBC_SHA", + .stdName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + .stdName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA256, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + // psk nego + {.enable = true, + .name = "HITLS_PSK_WITH_AES_128_CBC_SHA", + .stdName = "TLS_PSK_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_PSK_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_PSK_WITH_AES_256_CBC_SHA", + .stdName = "TLS_PSK_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_PSK_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_128_CBC_SHA", + .stdName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_256_CBC_SHA", + .stdName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_AES_128_CBC_SHA", + .stdName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_RSA_PSK_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_AES_256_CBC_SHA", + .stdName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_RSA_PSK_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_PSK_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_PSK_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_PSK_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_PSK_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_PSK_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_PSK_WITH_AES_256_CCM", + .stdName = "TLS_PSK_WITH_AES_256_CCM", + .cipherSuite = HITLS_PSK_WITH_AES_256_CCM, + .cipherAlg = HITLS_CIPHER_AES_256_CCM, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_128_CCM", + .stdName = "TLS_DHE_PSK_WITH_AES_128_CCM", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_128_CCM, + .cipherAlg = HITLS_CIPHER_AES_128_CCM, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_256_CCM", + .stdName = "TLS_DHE_PSK_WITH_AES_256_CCM", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_256_CCM, + .cipherAlg = HITLS_CIPHER_AES_256_CCM, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_PSK_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_PSK_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_PSK_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_PSK_WITH_AES_256_CBC_SHA384", + .stdName = "TLS_PSK_WITH_AES_256_CBC_SHA384", + .cipherSuite = HITLS_PSK_WITH_AES_256_CBC_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_384, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 48u, 16u, 16u, 48u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_AES_256_CBC_SHA384", + .stdName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", + .cipherSuite = HITLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_384, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 48u, 16u, 16u, 48u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384", + .stdName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", + .cipherSuite = HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_384, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 48u, 16u, 16u, 48u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + .stdName = "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + .stdName = "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", + .stdName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_384, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 48u, 16u, 16u, 48u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_DHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", + .stdName = "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", + .cipherSuite = HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, + .cipherAlg = HITLS_CIPHER_CHACHA20_POLY1305, + .kxAlg = HITLS_KEY_EXCH_RSA_PSK, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(12u, 32u, 0u, 0u, 0u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256", + .stdName = "TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE_PSK, + .authAlg = HITLS_AUTH_PSK, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + /* Anonymous cipher suites support */ + {.enable = true, + .name = "HITLS_DH_ANON_WITH_AES_128_CBC_SHA", + .stdName = "TLS_DH_ANON_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_DH_ANON_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DH_ANON_WITH_AES_256_CBC_SHA", + .stdName = "TLS_DH_ANON_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_DH_ANON_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_SSL30, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DH_ANON_WITH_AES_128_CBC_SHA256", + .stdName = "TLS_DH_ANON_WITH_AES_128_CBC_SHA256", + .cipherSuite = HITLS_DH_ANON_WITH_AES_128_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DH_ANON_WITH_AES_256_CBC_SHA256", + .stdName = "TLS_DH_ANON_WITH_AES_256_CBC_SHA256", + .cipherSuite = HITLS_DH_ANON_WITH_AES_256_CBC_SHA256, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_256, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DH_ANON_WITH_AES_128_GCM_SHA256", + .stdName = "TLS_DH_ANON_WITH_AES_128_GCM_SHA256", + .cipherSuite = HITLS_DH_ANON_WITH_AES_128_GCM_SHA256, + .cipherAlg = HITLS_CIPHER_AES_128_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DH_ANON_WITH_AES_256_GCM_SHA384", + .stdName = "TLS_DH_ANON_WITH_AES_256_GCM_SHA384", + .cipherSuite = HITLS_DH_ANON_WITH_AES_256_GCM_SHA384, + .cipherAlg = HITLS_CIPHER_AES_256_GCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_384, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA", + .stdName = "TLS_ECDH_ANON_WITH_AES_128_CBC_SHA", + .cipherSuite = HITLS_ECDH_ANON_WITH_AES_128_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_128_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDH_ANON_WITH_AES_256_CBC_SHA", + .stdName = "TLS_ECDH_ANON_WITH_AES_256_CBC_SHA", + .cipherSuite = HITLS_ECDH_ANON_WITH_AES_256_CBC_SHA, + .cipherAlg = HITLS_CIPHER_AES_256_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_NULL, + .macAlg = HITLS_MAC_1, + .hashAlg = HITLS_HASH_SHA1, + .signScheme = CERT_SIG_SCHEME_UNKNOWN, + KEY_BLOCK_PARTITON_LENGTH(16u, 32u, 20u, 16u, 16u, 20u), + VERSION_SCOPE(HITLS_VERSION_TLS10, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_128_CCM", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_128_CCM, + .cipherAlg = HITLS_CIPHER_AES_128_CCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECDHE_ECDSA_WITH_AES_256_CCM", + .stdName = "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", + .cipherSuite = HITLS_ECDHE_ECDSA_WITH_AES_256_CCM, + .cipherAlg = HITLS_CIPHER_AES_256_CCM, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_ECDSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_ECDSA_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_128_CCM", + .stdName = "TLS_DHE_RSA_WITH_AES_128_CCM", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_128_CCM, + .cipherAlg = HITLS_CIPHER_AES_128_CCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_DHE_RSA_WITH_AES_256_CCM", + .stdName = "TLS_DHE_RSA_WITH_AES_256_CCM", + .cipherSuite = HITLS_DHE_RSA_WITH_AES_256_CCM, + .cipherAlg = HITLS_CIPHER_AES_256_CCM, + .kxAlg = HITLS_KEY_EXCH_DHE, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_128_CCM", + .stdName = "TLS_RSA_WITH_AES_128_CCM", + .cipherSuite = HITLS_RSA_WITH_AES_128_CCM, + .cipherAlg = HITLS_CIPHER_AES_128_CCM, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_128_CCM_8", + .stdName = "TLS_RSA_WITH_AES_128_CCM_8", + .cipherSuite = HITLS_RSA_WITH_AES_128_CCM_8, + .cipherAlg = HITLS_CIPHER_AES_128_CCM8, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 16u, 0u, 0u, 8u, 8u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_256_CCM", + .stdName = "TLS_RSA_WITH_AES_256_CCM", + .cipherSuite = HITLS_RSA_WITH_AES_256_CCM, + .cipherAlg = HITLS_CIPHER_AES_256_CCM, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 16u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, + {.enable = true, + .name = "HITLS_RSA_WITH_AES_256_CCM_8", + .stdName = "TLS_RSA_WITH_AES_256_CCM_8", + .cipherSuite = HITLS_RSA_WITH_AES_256_CCM_8, + .cipherAlg = HITLS_CIPHER_AES_256_CCM8, + .kxAlg = HITLS_KEY_EXCH_RSA, + .authAlg = HITLS_AUTH_RSA, + .macAlg = HITLS_MAC_AEAD, + .hashAlg = HITLS_HASH_SHA_256, + .signScheme = CERT_SIG_SCHEME_RSA_PKCS1_SHA1, + KEY_BLOCK_PARTITON_LENGTH(4u, 32u, 0u, 0u, 8u, 8u), + VERSION_SCOPE(HITLS_VERSION_TLS12, HITLS_VERSION_TLS12, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12), + .cipherType = HITLS_AEAD_CIPHER, + .strengthBits = 256}, +#ifndef HITLS_NO_TLCP11 + {.enable = true, + .name = "HITLS_ECDHE_SM4_CBC_SM3", + .stdName = "TLS_ECDHE_SM4_CBC_SM3", + .cipherSuite = HITLS_ECDHE_SM4_CBC_SM3, + .cipherAlg = HITLS_CIPHER_SM4_CBC, + .kxAlg = HITLS_KEY_EXCH_ECDHE, + .authAlg = HITLS_AUTH_SM2, + .macAlg = HITLS_MAC_SM3, + .hashAlg = HITLS_HASH_SM3, + .signScheme = CERT_SIG_SCHEME_SM2_SM3, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLCP11, HITLS_VERSION_TLCP11, 0, 0), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, + {.enable = true, + .name = "HITLS_ECC_SM4_CBC_SM3", + .stdName = "TLS_ECC_SM4_CBC_SM3", + .cipherSuite = HITLS_ECC_SM4_CBC_SM3, + .cipherAlg = HITLS_CIPHER_SM4_CBC, + .kxAlg = HITLS_KEY_EXCH_ECC, + .authAlg = HITLS_AUTH_SM2, + .macAlg = HITLS_MAC_SM3, + .hashAlg = HITLS_HASH_SM3, + .signScheme = CERT_SIG_SCHEME_SM2_SM3, + KEY_BLOCK_PARTITON_LENGTH(16u, 16u, 32u, 16u, 16u, 32u), + VERSION_SCOPE(HITLS_VERSION_TLCP11, HITLS_VERSION_TLCP11, 0, 0), + .cipherType = HITLS_CBC_CIPHER, + .strengthBits = 128}, +#endif +}; + +const SignSchemeInfo g_signSchemeList[] = { + { CERT_SIG_SCHEME_RSA_PKCS1_SHA224, HITLS_SIGN_RSA_PKCS1_V15, HITLS_HASH_SHA_224 }, + { CERT_SIG_SCHEME_RSA_PKCS1_SHA256, HITLS_SIGN_RSA_PKCS1_V15, HITLS_HASH_SHA_256 }, + { CERT_SIG_SCHEME_RSA_PKCS1_SHA384, HITLS_SIGN_RSA_PKCS1_V15, HITLS_HASH_SHA_384 }, + { CERT_SIG_SCHEME_RSA_PKCS1_SHA512, HITLS_SIGN_RSA_PKCS1_V15, HITLS_HASH_SHA_512 }, + { CERT_SIG_SCHEME_RSA_PKCS1_SHA1, HITLS_SIGN_RSA_PKCS1_V15, HITLS_HASH_SHA1 }, + + { CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256, HITLS_SIGN_RSA_PSS_RSAE, HITLS_HASH_SHA_256 }, + { CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384, HITLS_SIGN_RSA_PSS_RSAE, HITLS_HASH_SHA_384 }, + { CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512, HITLS_SIGN_RSA_PSS_RSAE, HITLS_HASH_SHA_512 }, + + { CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256, HITLS_SIGN_RSA_PSS_PSS, HITLS_HASH_SHA_256 }, + { CERT_SIG_SCHEME_RSA_PSS_PSS_SHA384, HITLS_SIGN_RSA_PSS_PSS, HITLS_HASH_SHA_384 }, + { CERT_SIG_SCHEME_RSA_PSS_PSS_SHA512, HITLS_SIGN_RSA_PSS_PSS, HITLS_HASH_SHA_512 }, + + { CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, HITLS_SIGN_ECDSA, HITLS_HASH_SHA_256 }, + { CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, HITLS_SIGN_ECDSA, HITLS_HASH_SHA_384 }, + { CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512, HITLS_SIGN_ECDSA, HITLS_HASH_SHA_512 }, + + { CERT_SIG_SCHEME_ECDSA_SHA224, HITLS_SIGN_ECDSA, HITLS_HASH_SHA_224 }, + { CERT_SIG_SCHEME_ECDSA_SHA1, HITLS_SIGN_ECDSA, HITLS_HASH_SHA1 }, + + { CERT_SIG_SCHEME_ED25519, HITLS_SIGN_ED25519, HITLS_HASH_SHA_512 }, + + { CERT_SIG_SCHEME_DSA_SHA224, HITLS_SIGN_DSA, HITLS_HASH_SHA_224 }, + { CERT_SIG_SCHEME_DSA_SHA256, HITLS_SIGN_DSA, HITLS_HASH_SHA_256 }, + { CERT_SIG_SCHEME_DSA_SHA384, HITLS_SIGN_DSA, HITLS_HASH_SHA_384 }, + { CERT_SIG_SCHEME_DSA_SHA512, HITLS_SIGN_DSA, HITLS_HASH_SHA_512 }, + { CERT_SIG_SCHEME_DSA_SHA1, HITLS_SIGN_DSA, HITLS_HASH_SHA1 }, +}; + +const EcdsaCurveInfo g_ecdsaCurveInfo[] = { + { CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, HITLS_EC_GROUP_SECP256R1 }, + { CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, HITLS_EC_GROUP_SECP384R1 }, + { CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512, HITLS_EC_GROUP_SECP521R1 }, +}; + +#ifndef HITLS_NO_TLCP11 +const SignSchemeInfo g_signSchemeListGm[] = { + { CERT_SIG_SCHEME_SM2_SM3, HITLS_SIGN_SM2, HITLS_HASH_SM3 }, +}; +#endif + +const CipherSuiteCertType g_cipherSuiteAndCertTypes[] = { + { HITLS_RSA_WITH_AES_128_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_256_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_128_CBC_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_256_CBC_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_128_GCM_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_256_GCM_SHA384, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_128_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_256_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_128_CCM, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_AES_256_CCM, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_128_CCM, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_128_CCM_8, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_256_CCM, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_WITH_AES_256_CCM_8, CERT_TYPE_RSA_SIGN }, + { HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_AES_128_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_AES_256_CBC_SHA, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_AES_128_GCM_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_AES_256_GCM_SHA384, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_AES_128_CBC_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_AES_256_CBC_SHA384, CERT_TYPE_RSA_SIGN }, + { HITLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, CERT_TYPE_RSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_128_CCM, CERT_TYPE_ECDSA_SIGN }, + { HITLS_ECDHE_ECDSA_WITH_AES_256_CCM, CERT_TYPE_ECDSA_SIGN }, + { HITLS_DHE_DSS_WITH_AES_128_CBC_SHA, CERT_TYPE_DSS_SIGN }, + { HITLS_DHE_DSS_WITH_AES_256_CBC_SHA, CERT_TYPE_DSS_SIGN }, + { HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256, CERT_TYPE_DSS_SIGN }, + { HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256, CERT_TYPE_DSS_SIGN }, + { HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, CERT_TYPE_DSS_SIGN }, + { HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, CERT_TYPE_DSS_SIGN }, + { HITLS_ECDHE_SM4_CBC_SM3, CERT_TYPE_SM2_SIGN }, + { HITLS_ECC_SM4_CBC_SM3, CERT_TYPE_SM2_SIGN }, +}; + +const SignSchemeInfo *CFG_GetSignSchemeList(uint32_t *len) +{ + *len = sizeof(g_signSchemeList) / sizeof(g_signSchemeList[0]); + return g_signSchemeList; +} + +#ifndef HITLS_NO_TLCP11 +const SignSchemeInfo *CFG_GetSignSchemeListTlcp(uint32_t *len) +{ + *len = sizeof(g_signSchemeListGm) / sizeof(g_signSchemeListGm[0]); + return g_signSchemeListGm; +} +#endif + +uint16_t CFG_GetCipherSuite(uint16_t version, HITLS_KeyExchAlgo kxAlgo, HITLS_AuthAlgo authAlgo, + HITLS_CipherAlgo cipherAlgo, HITLS_HashAlgo hashAlgo) +{ + /* Obtain the corresponding cipher suite based on the given information. */ + for (uint32_t i = 0; i < (sizeof(g_cipherSuiteList) / sizeof(g_cipherSuiteList[0])); i++) { + if (g_cipherSuiteList[i].enable == false) { + continue; + } + if (IS_DTLS_VERSION(version)) { + if ((version < g_cipherSuiteList[i].maxDtlsVersion) || (version > g_cipherSuiteList[i].minDtlsVersion)) { + continue; + } + } else { + if ((version < g_cipherSuiteList[i].minVersion) || (version > g_cipherSuiteList[i].maxVersion)) { + continue; + } + } + if ((kxAlgo != HITLS_KEY_EXCH_NULL) && (g_cipherSuiteList[i].kxAlg != kxAlgo)) { + continue; + } + if ((authAlgo != HITLS_AUTH_NULL) && (g_cipherSuiteList[i].authAlg != authAlgo)) { + continue; + } + if ((cipherAlgo != HITLS_CIPHER_NULL) && (g_cipherSuiteList[i].cipherAlg != cipherAlgo)) { + continue; + } + if ((hashAlgo != HITLS_HASH_NULL) && (g_cipherSuiteList[i].hashAlg != hashAlgo)) { + continue; + } + return g_cipherSuiteList[i].cipherSuite; + } + return 0; +} + +/** + * @brief Obtain the cipher suite information + * + * @param cipherSuite [IN] Cipher suite of the information to be obtained + * @param cipherInfo [OUT] Cipher suite information + * + * @retval HITLS_SUCCESS obtained successfully + * @retval HITLS_INTERNAL_EXCEPTION Unexpected internal error + * @retval HITLS_MEMCPY_FAIL memcpy_s failed to be executed. + * @retval HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE No information about the cipher suite is found. + */ +int32_t CFG_GetCipherSuiteInfo(uint16_t cipherSuite, CipherSuiteInfo *cipherInfo) +{ + if (cipherInfo == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15858, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CFG:cipherInfo is NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + /* Obtain the cipher suite information. If the cipher suite information is successfully obtained, a response is + * returned. */ + for (uint32_t i = 0; i < (sizeof(g_cipherSuiteList) / sizeof(g_cipherSuiteList[0])); i++) { + if (g_cipherSuiteList[i].cipherSuite == cipherSuite) { + if (g_cipherSuiteList[i].enable == false) { + break; + } + int32_t ret = memcpy_s(cipherInfo, sizeof(CipherSuiteInfo), &g_cipherSuiteList[i], sizeof(CipherSuiteInfo)); + if (ret != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15859, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CFG:memcpy failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + return HITLS_SUCCESS; + } + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15860, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "CFG: [0x%x]cipher suite is not supported.", cipherSuite, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE); + return HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE; +} + +/** + * @brief Check whether the input cipher suite is supported. + * + * @param cipherSuite [IN] Cipher suite to be checked + * + * @retval true support + * @retval false Not supported + */ +bool CFG_CheckCipherSuiteSupported(uint16_t cipherSuite) +{ /** @alias Check the suite and return true if supported. */ + for (uint32_t i = 0; i < (sizeof(g_cipherSuiteList) / sizeof(g_cipherSuiteList[0])); i++) { + if (cipherSuite == g_cipherSuiteList[i].cipherSuite) { + return g_cipherSuiteList[i].enable; + } + } + + return false; +} + +/** Check whether the version is within the allowed range */ +static bool CheckTlsVersionInRange(uint16_t cipherMinVersion, uint16_t cipherMaxVersion, + uint16_t cfgMinVersion, uint16_t cfgMaxVersion) +{ + if ((cipherMaxVersion < cfgMinVersion) || (cipherMinVersion > cfgMaxVersion)) { + return false; + } + return true; +} + +/** Check whether the version of the TLCP is within the allowed range */ +static bool CheckTLCPVersionInRange(uint16_t version, uint16_t minVersion, uint16_t maxVersion) +{ + return (version >= minVersion) && (version <= maxVersion); +} + +/** Check whether the version is within the allowed range. (DTLS version numbers are sorted in reverse order. For + * example, DTLS 1.2 is greater than DTLS 1.3 */ +static bool CheckDtlsVersionInRange(uint16_t cipherMinVersion, uint16_t cipherMaxVersion, + uint16_t cfgMinVersion, uint16_t cfgMaxVersion) +{ + if ((cipherMaxVersion > cfgMinVersion) || (cipherMinVersion < cfgMaxVersion)) { + return false; + } + return true; +} + +/** + * @brief Check whether the input cipher suite complies with the version + * + * @param cipherSuite [IN] Cipher suite to be checked + * minVersion [IN] Indicates the earliest version of the cipher suite + * maxVersion [IN] Indicates the latest version of the cipher suite + * + * @retval true support + * @retval false Not supported + */ +bool CFG_CheckCipherSuiteVersion(uint16_t cipherSuite, uint16_t minVersion, uint16_t maxVersion) +{ + const CipherSuiteInfo *suiteInfo = NULL; + + /** @alias Check the suite and return true if supported. */ + for (uint32_t i = 0; i < (sizeof(g_cipherSuiteList) / sizeof(g_cipherSuiteList[0])); i++) { + suiteInfo = &g_cipherSuiteList[i]; + if (cipherSuite == suiteInfo->cipherSuite) { /** tlcp max version equal min version */ + return CheckTlsVersionInRange(suiteInfo->minVersion, suiteInfo->maxVersion, minVersion, maxVersion) || + CheckDtlsVersionInRange(suiteInfo->minDtlsVersion, suiteInfo->maxDtlsVersion, minVersion, maxVersion) || + CheckTLCPVersionInRange(minVersion, suiteInfo->minVersion, suiteInfo->maxVersion) || + CheckTLCPVersionInRange(maxVersion, suiteInfo->minVersion, suiteInfo->maxVersion); + } + } + + return false; +} + +/** + * @brief Obtain the signature algorithm and hash algorithm by combining the parameters of the signature hash + * algorithm. + * + * @param version [IN] Secure communication version + * @param scheme [IN] Signature and hash algorithm combination + * @param signAlg [OUT] Signature algorithm + * @param hashAlg [OUT] Hash algorithm + * + * @retval true Obtained successfully. + * @retval false Obtaining failed. + */ +bool CFG_GetSignParamBySchemes(uint16_t version, HITLS_SignHashAlgo scheme, HITLS_SignAlgo *signAlg, + HITLS_HashAlgo *hashAlg) +{ + bool ret = false; +#ifndef HITLS_NO_TLCP11 + if (version == HITLS_VERSION_TLCP11) { + for (uint32_t i = 0; i < (sizeof(g_signSchemeListGm) / sizeof(g_signSchemeListGm[0])); i++) { + if (scheme == g_signSchemeListGm[i].scheme) { + *signAlg = g_signSchemeListGm[i].signAlg; + *hashAlg = g_signSchemeListGm[i].hashAlg; + return true; + } + } + return false; + } +#endif + (void)version; + /** @alias Search for the signature hash algorithm. If the algorithm is found, ret=true */ + for (uint32_t i = 0; i < (sizeof(g_signSchemeList) / sizeof(g_signSchemeList[0])); i++) { + if (scheme == g_signSchemeList[i].scheme) { + *signAlg = g_signSchemeList[i].signAlg; + *hashAlg = g_signSchemeList[i].hashAlg; + ret = true; + break; + } + } + return ret; +} + +/** + * @brief get the group name of the signature algorithm + * + * @param scheme [IN] signature algorithm + * + * @retval group name + */ +HITLS_NamedGroup CFG_GetEcdsaCurveNameBySchemes(HITLS_SignHashAlgo scheme) +{ + for (uint32_t i = 0; i < (sizeof(g_ecdsaCurveInfo) / sizeof(g_ecdsaCurveInfo[0])); i++) { + if (scheme == g_ecdsaCurveInfo[i].scheme) { + return g_ecdsaCurveInfo[i].cureName; + } + } + return HITLS_NAMED_GROUP_BUTT; +} + +/** + * @brief Obtain the certificate type based on the cipher suite + * + * @param cipherSuite [IN] Cipher suite + * + * @return Certificate type corresponding to the cipher suite + */ +uint8_t CFG_GetCertTypeByCipherSuite(uint16_t cipherSuite) +{ + for (uint32_t i = 0; i < (sizeof(g_cipherSuiteAndCertTypes) / sizeof(g_cipherSuiteAndCertTypes[0])); i++) { + if (cipherSuite == g_cipherSuiteAndCertTypes[i].cipherSuite) { + return g_cipherSuiteAndCertTypes[i].certType; + } + } + + return CERT_TYPE_UNKNOWN; +} + +/* Convert the supported version number to the corresponding character string */ +static const uint8_t* ProtocolToString(uint16_t version) +{ + const char *ret = NULL; + switch (version) { + case HITLS_VERSION_TLS12: + ret = "TLSv1.2"; + break; + case HITLS_VERSION_TLS13: + ret = "TLSv1.3"; + break; + case HITLS_VERSION_DTLS12: + ret = "DTLSv1.2"; + break; + case HITLS_VERSION_TLCP11: + ret = "TLCP1.1"; + break; + default: + ret = "unknown"; + break; + } + return (const uint8_t *)ret; +} + +/* Convert the server authorization algorithm type to the corresponding character string */ +static const uint8_t* AuthAlgToString(HITLS_AuthAlgo authAlg) +{ + const char *ret = NULL; + switch (authAlg) { + case HITLS_AUTH_RSA: + ret = "RSA"; + break; + case HITLS_AUTH_ECDSA: + ret = "ECDSA"; + break; + case HITLS_AUTH_DSS: + ret = "DSS"; + break; + case HITLS_AUTH_SM2: + ret = "SM2"; + break; + default: + ret = "unknown"; + break; + } + return (const uint8_t *)ret; +} + +/* Convert the key exchange algorithm type to the corresponding character string */ +static const uint8_t* KeyExchAlgToString(HITLS_KeyExchAlgo kxAlg) +{ + const char *ret = NULL; + switch (kxAlg) { + case HITLS_KEY_EXCH_ECDHE: + ret = "ECDHE"; + break; + case HITLS_KEY_EXCH_DHE: + ret = "DHE"; + break; + case HITLS_KEY_EXCH_ECDH: + ret = "ECDH"; + break; + case HITLS_KEY_EXCH_DH: + ret = "DH"; + break; + case HITLS_KEY_EXCH_RSA: + ret = "RSA"; + break; + case HITLS_KEY_EXCH_PSK: + ret = "PSK"; + break; + case HITLS_KEY_EXCH_ECC: + ret = "ECC"; + break; + default: + ret = "unknown"; + break; + } + return (const uint8_t *)ret; +} + +/* Convert the MAC algorithm type to the corresponding character string */ +static const uint8_t* MacAlgToString(HITLS_MacAlgo macAlg) +{ + const char *ret = NULL; + switch (macAlg) { + case HITLS_MAC_1: + ret = "SHA1"; + break; + case HITLS_MAC_256: + ret = "SHA256"; + break; + case HITLS_MAC_384: + ret = "SHA384"; + break; + case HITLS_MAC_512: + ret = "SHA512"; + break; + case HITLS_MAC_AEAD: + ret = "AEAD"; + break; + case HITLS_MAC_SM3: + ret = "SM3"; + break; + default: + ret = "unknown"; + break; + } + return (const uint8_t *)ret; +} + +/* Convert the hash algorithm type to the corresponding character string */ +static const uint8_t* HashAlgToString(HITLS_HashAlgo hashAlg) +{ + const char *ret = NULL; + switch (hashAlg) { + case HITLS_HASH_MD5: + ret = "MD5"; + break; + case HITLS_HASH_SHA1: + ret = "SHA1"; + break; + case HITLS_HASH_SHA_256: + ret = "SHA256"; + break; + case HITLS_HASH_SHA_384: + ret = "SHA384"; + break; + case HITLS_HASH_SHA_512: + ret = "SHA512"; + break; + case HITLS_HASH_MD5_SHA1: + ret = "MD5SHA1"; + break; + case HITLS_HASH_SM3: + ret = "SM3"; + break; + default: + ret = "unknown"; + break; + } + return (const uint8_t *)ret; +} + +/* Search the corresponding index in the table based on the cipher suite. If the cipher suite is invalid, + * CIPHER_SUITE_NOT_EXIST is returned */ +static int32_t FindCipherSuiteIndexByCipherSuite(const uint16_t cipherSuite) +{ + uint32_t i; + for (i = 0; i < sizeof(g_cipherSuiteList) / sizeof(CipherSuiteInfo); i++) { + if (g_cipherSuiteList[i].cipherSuite == cipherSuite) { + return (int32_t)i; + } + } + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE); + return HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE; +} + + +static int32_t GetCipherSuiteDescription(const CipherSuiteInfo *cipherSuiteInfo, uint8_t *buf, int len) +{ + if (cipherSuiteInfo == NULL || buf == NULL || len < CIPHERSUITE_DESCRIPTION_MAXLEN) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + const uint8_t *ver, *kx, *au, *hash, *mac; + static const char *format = "%-30s %-7s Kx=%-8s Au=%-5s Hash=%-22s Mac=%-4s\n"; + + ver = ProtocolToString(cipherSuiteInfo->minVersion); + kx = KeyExchAlgToString(cipherSuiteInfo->kxAlg); + au = AuthAlgToString(cipherSuiteInfo->authAlg); + mac = MacAlgToString(cipherSuiteInfo->macAlg); + hash = HashAlgToString(cipherSuiteInfo->hashAlg); + + int32_t ret = snprintf_s((char *)buf, CIPHERSUITE_DESCRIPTION_MAXLEN, CIPHERSUITE_DESCRIPTION_MAXLEN, + format, cipherSuiteInfo->name, ver, kx, au, hash, mac); + if (ret < 0 || ret > CIPHERSUITE_DESCRIPTION_MAXLEN - 1) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the Symmetric-key algorithm type based on the cipher suite + * + * @param cipher[IN] Cipher suite + * @param cipherAlg [OUT] Obtained Symmetric-key algorithm type. + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetCipherId(const HITLS_Cipher *cipher, HITLS_CipherAlgo *cipherAlg) +{ + if (cipher == NULL || cipherAlg == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *cipherAlg = cipher->cipherAlg; + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the hash algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param hashAlg [OUT] Obtained hash algorithm type + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h + */ +int32_t HITLS_CFG_GetHashId(const HITLS_Cipher *cipher, HITLS_HashAlgo *hashAlg) +{ + if (cipher == NULL || hashAlg == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *hashAlg = cipher->hashAlg; + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the MAC algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param macAlg [OUT] Obtained MAC algorithm type. + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h + */ +int32_t HITLS_CFG_GetMacId(const HITLS_Cipher *cipher, HITLS_MacAlgo *macAlg) +{ + if (cipher == NULL || macAlg == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *macAlg = cipher->macAlg; + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the server authorization algorithm type based on the cipher suite + * + * @param cipher [IN] Cipher suite + * @param authAlg [OUT] Obtained server authorization type. + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetAuthId(const HITLS_Cipher *cipher, HITLS_AuthAlgo *authAlg) +{ + if (cipher == NULL || authAlg == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *authAlg = cipher->authAlg; + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the key exchange algorithm type based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param kxAlg [OUT] Obtained key exchange algorithm type. + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetKeyExchId(const HITLS_Cipher *cipher, HITLS_KeyExchAlgo *kxAlg) +{ + if (cipher == NULL || kxAlg == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *kxAlg = cipher->kxAlg; + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the cipher suite name based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @retval "(NONE)" Invalid cipher suite. + * @retval Name of the given cipher suite + */ +const uint8_t* HITLS_CFG_GetCipherSuiteName(const HITLS_Cipher *cipher) +{ + if (cipher == NULL) { + return (const uint8_t *)"(NONE)"; + } + return (const uint8_t *)cipher->name; +} + +/** + * @brief Obtain the RFC standard name of the cipher suite based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * + * @retval "(NONE)" Invalid cipher suite. + * @retval RFC standard name for the given cipher suite + */ +const uint8_t* HITLS_CFG_GetCipherSuiteStdName(const HITLS_Cipher *cipher) +{ + if (cipher == NULL) { + return (const uint8_t *)"(NONE)"; + } + return (const uint8_t *)cipher->stdName; +} + +/** + * @brief Obtain the earliest TLS version supported by the cipher suite based on the cipher suite. + * + * @param cipher [IN] Cipher suite + * @param version [OUT] Obtain the earliest TLS version supported by the cipher suite. + * @retval HITLS_SUCCESS succeeded + * @retval For other error codes, see hitls_error.h. + */ +int32_t HITLS_CFG_GetCipherVersion(const HITLS_Cipher *cipher, int32_t *version) +{ + if (cipher == NULL || version == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *version = cipher->minVersion; + return HITLS_SUCCESS; +} + +/** + * @brief Output the description of the cipher suite as a character string. + * + * @param cipherSuite [IN] Cipher suite + * @param buf [OUT] Output the description. + * @param len [IN] Description length + * @retval NULL Failed to obtain the description. + * @retval Description of the cipher suite + */ +int32_t HITLS_CFG_GetDescription(const HITLS_Cipher *cipher, uint8_t *buf, int32_t len) +{ + return GetCipherSuiteDescription(cipher, buf, len); +} + +/** + * @brief Determine whether to use the AEAD algorithm based on the cipher suite information. + * + * @param cipher [IN] Cipher suite information + * @param isAead [OUT] Indicates whether to use the AEAD algorithm. + * @return HITLS_SUCCESS Obtained successfully. + * HITLS_NULL_INPUT The input parameter pointer is NULL. + */ +int32_t HITLS_CIPHER_IsAead(const HITLS_Cipher *cipher, uint8_t *isAead) +{ + if (cipher == NULL || isAead == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isAead = (cipher->cipherType == HITLS_AEAD_CIPHER); + return HITLS_SUCCESS; +} + +const HITLS_Cipher *HITLS_CFG_GetCipherByID(uint16_t cipherSuite) +{ + int32_t index = FindCipherSuiteIndexByCipherSuite(cipherSuite); + if (index == HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE) { + return NULL; + } + + return &g_cipherSuiteList[index]; +} + +int32_t HITLS_CFG_GetCipherSuite(const HITLS_Cipher *cipher, uint16_t *cipherSuite) +{ + if (cipher == NULL || cipherSuite == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *cipherSuite = cipher->cipherSuite; + + return HITLS_SUCCESS; +} diff --git a/tls/config/src/config.c b/tls/config/src/config.c new file mode 100644 index 00000000..bcf30e2a --- /dev/null +++ b/tls/config/src/config.c @@ -0,0 +1,1870 @@ +/* + * 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 +#include +#include "securec.h" +#include "bsl_log_internal.h" +#include "bsl_err_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_list.h" +#include "hitls_type.h" +#include "hitls_error.h" +#include "hitls_psk.h" +#include "hitls_alpn.h" +#include "hitls_cert_type.h" +#include "hitls_sni.h" +#include "tls.h" +#include "cert.h" +#include "crypt.h" +#include "session_mgr.h" +#include "config_check.h" +#include "config_default.h" +#include "bsl_list.h" + +static void HitlsTrustedCANodeFree(void *caNode) +{ + if (caNode == NULL) { + return; + } + HITLS_TrustedCANode *newCaNode = (HITLS_TrustedCANode *)caNode; + BSL_SAL_FREE(newCaNode->data); + newCaNode->data = NULL; + BSL_SAL_FREE(newCaNode); +} + +void CFG_CleanConfig(HITLS_Config *config) +{ + BSL_SAL_FREE(config->cipherSuites); + BSL_SAL_FREE(config->tls13CipherSuites); + BSL_SAL_FREE(config->pointFormats); + BSL_SAL_FREE(config->groups); + BSL_SAL_FREE(config->signAlgorithms); + BSL_SAL_FREE(config->pskIdentityHint); + BSL_SAL_FREE(config->alpnList); + BSL_SAL_FREE(config->serverName); + BSL_LIST_FREE(config->caList, HitlsTrustedCANodeFree); + SAL_CRYPT_FreeDhKey(config->dhTmp); + SAL_CRYPT_FreeEcdhKey(config->ecdhTmp); + SESSMGR_Free(config->sessMgr); + config->sessMgr = NULL; + SAL_CERT_MgrCtxFree(config->certMgrCtx); + config->certMgrCtx = NULL; + BSL_SAL_ReferencesFree(&(config->references)); + return; +} + + +static void ShallowCopy(HITLS_Ctx *ctx, const HITLS_Config *srcConfig) +{ + HITLS_Config *destConfig = &ctx->config.tlsConfig; + + /** + * Other parameters except CipherSuite, PointFormats, Group, SignAlgorithms, Psk, SessionId, CertMgr, and SessMgr + * are shallowly copied, and some of them reference globalConfig. + */ + destConfig->minVersion = srcConfig->minVersion; + destConfig->maxVersion = srcConfig->maxVersion; + destConfig->version = srcConfig->version; + destConfig->originVersionMask = srcConfig->originVersionMask; + destConfig->isSupportRenegotiation = srcConfig->isSupportRenegotiation; + destConfig->needCheckPmsVersion = srcConfig->needCheckPmsVersion; + destConfig->needCheckKeyUsage = srcConfig->needCheckKeyUsage; + destConfig->isResumptionOnRenego = srcConfig->isResumptionOnRenego; + destConfig->isSupportClientVerify = srcConfig->isSupportClientVerify; + destConfig->isSupportExtendMasterSecret = srcConfig->isSupportExtendMasterSecret; + destConfig->isSupportDhAuto = srcConfig->isSupportDhAuto; + destConfig->isSupportSessionTicket = srcConfig->isSupportSessionTicket; + destConfig->isSupportNoClientCert = srcConfig->isSupportNoClientCert; + destConfig->isSupportVerifyNone = srcConfig->isSupportVerifyNone; + destConfig->isSupportClientOnceVerify = srcConfig->isSupportClientOnceVerify; + destConfig->isSupportPostHandshakeAuth = srcConfig->isSupportPostHandshakeAuth; + destConfig->pskClientCb = srcConfig->pskClientCb; + destConfig->pskServerCb = srcConfig->pskServerCb; + destConfig->userData = srcConfig->userData; + destConfig->userDataFreeCb = srcConfig->userDataFreeCb; + destConfig->keyExchMode = srcConfig->keyExchMode; + destConfig->infoCb = srcConfig->infoCb; + destConfig->msgCb = srcConfig->msgCb; + destConfig->msgArg = srcConfig->msgArg; + destConfig->noSecRenegotiationCb = srcConfig->noSecRenegotiationCb; + destConfig->isQuietShutdown = srcConfig->isQuietShutdown; + destConfig->securityCb = srcConfig->securityCb; + destConfig->securityExData = srcConfig->securityExData; + destConfig->securityLevel = srcConfig->securityLevel; + destConfig->isEncryptThenMac = srcConfig->isEncryptThenMac; + destConfig->pskFindSessionCb = srcConfig->pskFindSessionCb; + destConfig->pskUseSessionCb = srcConfig->pskUseSessionCb; + destConfig->isSupportServerPreference = srcConfig->isSupportServerPreference; + destConfig->ticketNums = srcConfig->ticketNums; + destConfig->isFlightTransmitEnable = srcConfig->isFlightTransmitEnable; + destConfig->maxCertList = srcConfig->maxCertList; + destConfig->recordPaddingCb = srcConfig->recordPaddingCb; +} + +static int32_t PointFormatsCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->pointFormats != NULL) { + destConfig->pointFormats = BSL_SAL_Dump(srcConfig->pointFormats, srcConfig->pointFormatsSize * sizeof(uint8_t)); + if (destConfig->pointFormats == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->pointFormatsSize = srcConfig->pointFormatsSize; + } + return HITLS_SUCCESS; +} + +static int32_t GroupCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->groups != NULL) { + destConfig->groups = BSL_SAL_Dump(srcConfig->groups, srcConfig->groupsSize * sizeof(uint16_t)); + if (destConfig->groups == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->groupsSize = srcConfig->groupsSize; + } + return HITLS_SUCCESS; +} + +static int32_t PskCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->pskIdentityHint != NULL) { + destConfig->pskIdentityHint = BSL_SAL_Dump(srcConfig->pskIdentityHint, srcConfig->hintSize * sizeof(uint8_t)); + if (destConfig->pskIdentityHint == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->hintSize = srcConfig->hintSize; + } + return HITLS_SUCCESS; +} + +static int32_t SignAlgorithmsCfgDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->signAlgorithms != NULL) { + destConfig->signAlgorithms = BSL_SAL_Dump(srcConfig->signAlgorithms, + srcConfig->signAlgorithmsSize * sizeof(uint16_t)); + if (destConfig->signAlgorithms == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->signAlgorithmsSize = srcConfig->signAlgorithmsSize; + } + return HITLS_SUCCESS; +} + +static int32_t AlpnListDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->alpnListSize == 0 || srcConfig->alpnList == NULL) { + return HITLS_SUCCESS; + } + destConfig->alpnList = BSL_SAL_Dump(srcConfig->alpnList, (srcConfig->alpnListSize + 1) * sizeof(uint8_t)); + if (destConfig->alpnList == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->alpnListSize = srcConfig->alpnListSize; + return HITLS_SUCCESS; +} + +static int32_t ServerNameDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->serverNameSize == 0 || srcConfig->serverName == NULL) { + return HITLS_SUCCESS; + } + + destConfig->serverName = BSL_SAL_Dump(srcConfig->serverName, srcConfig->serverNameSize * sizeof(uint8_t)); + if (destConfig->serverName == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->serverNameSize = srcConfig->serverNameSize; + + return HITLS_SUCCESS; +} + +static int32_t CipherSuiteDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->cipherSuites != NULL) { + destConfig->cipherSuites = BSL_SAL_Dump(srcConfig->cipherSuites, srcConfig->cipherSuitesSize * + sizeof(uint16_t)); + if (destConfig->cipherSuites == NULL) { + return HITLS_MEMALLOC_FAIL; + } + destConfig->cipherSuitesSize = srcConfig->cipherSuitesSize; + } + + if (srcConfig->tls13CipherSuites != NULL) { + destConfig->tls13CipherSuites = BSL_SAL_Dump(srcConfig->tls13CipherSuites, + srcConfig->tls13cipherSuitesSize * sizeof(uint16_t)); + if (destConfig->tls13CipherSuites == NULL) { + BSL_SAL_FREE(destConfig->cipherSuites); + return HITLS_MEMALLOC_FAIL; + } + destConfig->tls13cipherSuitesSize = srcConfig->tls13cipherSuitesSize; + } + return HITLS_SUCCESS; +} + +static int32_t CertMgrDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (!SAL_CERT_MgrIsEnable()) { + return HITLS_SUCCESS; + } + destConfig->certMgrCtx = SAL_CERT_MgrCtxDup(srcConfig->certMgrCtx); + if (destConfig->certMgrCtx == NULL) { + return HITLS_CERT_ERR_MGR_DUP; + } + return HITLS_SUCCESS; +} + +static int32_t SessionIdCtxCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->sessionIdCtxSize != 0 && + memcpy_s(destConfig->sessionIdCtx, sizeof(destConfig->sessionIdCtx), + srcConfig->sessionIdCtx, srcConfig->sessionIdCtxSize) != EOK) { + return HITLS_MEMCPY_FAIL; + } + + destConfig->sessionIdCtxSize = srcConfig->sessionIdCtxSize; + return HITLS_SUCCESS; +} + +static int32_t SessMgrDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + destConfig->sessMgr = SESSMGR_Dup(srcConfig->sessMgr); + if (destConfig->sessMgr == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t CryptKeyDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + if (srcConfig->dhTmp != NULL) { + destConfig->dhTmp = SAL_CRYPT_DupDhKey(srcConfig->dhTmp); + if (destConfig->dhTmp == NULL) { + return HITLS_CONFIG_DUP_DH_KEY_FAIL; + } + } + + if (srcConfig->ecdhTmp != NULL) { + destConfig->ecdhTmp = SAL_CRYPT_DupEcdhKey(srcConfig->ecdhTmp); + if (destConfig->ecdhTmp == NULL) { + return HITLS_CONFIG_DUP_ECDH_KEY_FAIL; + } + } + return HITLS_SUCCESS; +} + +static int32_t BasicConfigDeepCopy(HITLS_Config *destConfig, const HITLS_Config *srcConfig) +{ + int32_t ret = AlpnListDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ServerNameDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CryptKeyDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t CFG_DumpConfig(HITLS_Ctx *ctx, const HITLS_Config *srcConfig) +{ + int32_t ret; + HITLS_Config *destConfig = &ctx->config.tlsConfig; + + // shallow copy + ShallowCopy(ctx, srcConfig); + + ret = CipherSuiteDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = PointFormatsCfgDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = GroupCfgDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = SignAlgorithmsCfgDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = PskCfgDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = SessionIdCtxCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = CertMgrDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = SessMgrDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + ret = BasicConfigDeepCopy(destConfig, srcConfig); + if (ret != HITLS_SUCCESS) { + goto EXIT; + } + + return HITLS_SUCCESS; +EXIT: + CFG_CleanConfig(destConfig); + return ret; +} + +HITLS_Config *HITLS_CFG_NewDTLS12Config(void) +{ + HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config)); + if (newConfig == NULL) { + return NULL; + } + + if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + /* Initialize the version */ + newConfig->version |= DTLS12_VERSION_BIT; // Enable DTLS 1.2 + if (DefaultConfig(HITLS_VERSION_DTLS12, newConfig) != HITLS_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + newConfig->originVersionMask = newConfig->version; + return newConfig; +} + +#ifndef HITLS_NO_TLCP11 +HITLS_Config *HITLS_CFG_NewTLCPConfig(void) +{ + HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config)); + if (newConfig == NULL) { + return NULL; + } + + if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + if (DefaultConfig(HITLS_VERSION_TLCP11, newConfig) != HITLS_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + return newConfig; +} +#endif + +HITLS_Config *HITLS_CFG_NewTLS12Config(void) +{ + HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config)); + if (newConfig == NULL) { + return NULL; + } + + if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + /* Initialize the version */ + newConfig->version |= TLS12_VERSION_BIT; // Enable TLS 1.2 + if (DefaultConfig(HITLS_VERSION_TLS12, newConfig) != HITLS_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + newConfig->originVersionMask = newConfig->version; + return newConfig; +} + +HITLS_Config *HITLS_CFG_NewTLS13Config(void) +{ + HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config)); + if (newConfig == NULL) { + return NULL; + } + + if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + /* Initialize the version */ + newConfig->version |= TLS13_VERSION_BIT; // Enable TLS1.3 + if (DefaultTLS13Config(newConfig) != HITLS_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + newConfig->originVersionMask = newConfig->version; + return newConfig; +} + +HITLS_Config *HITLS_CFG_NewTLSConfig(void) +{ + HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config)); + if (newConfig == NULL) { + return NULL; + } + + if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + /* Initialize the version */ + newConfig->version |= TLS_VERSION_MASK; // Enable All Versions + if (DefaultTlsAllConfig(newConfig) != HITLS_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + newConfig->originVersionMask = newConfig->version; + return newConfig; +} + +HITLS_Config *HITLS_CFG_NewDTLSConfig(void) +{ + HITLS_Config *newConfig = BSL_SAL_Calloc(1u, sizeof(HITLS_Config)); + if (newConfig == NULL) { + return NULL; + } + + if (BSL_SAL_ReferencesInit(&(newConfig->references)) != BSL_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + + /* Initialize the version */ + newConfig->version |= DTLS_VERSION_MASK; // Enable All Versions + if (DefaultDtlsAllConfig(newConfig) != HITLS_SUCCESS) { + BSL_SAL_FREE(newConfig); + return NULL; + } + newConfig->originVersionMask = newConfig->version; + return newConfig; +} + +void HITLS_CFG_FreeConfig(HITLS_Config *config) +{ + if (config == NULL) { + return; + } + int ret = 0; + BSL_SAL_AtomicDownReferences(&(config->references), &ret); + if (ret > 0) { + return; + } + + CFG_CleanConfig(config); + if (config->userData != NULL && config->userDataFreeCb != NULL) { + (void)config->userDataFreeCb(config->userData); + config->userData = NULL; + } + BSL_SAL_FREE(config); + + return; +} + +int32_t HITLS_CFG_UpRef(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + int ret = 0; + BSL_SAL_AtomicUpReferences(&(config->references), &ret); + (void)ret; + + return HITLS_SUCCESS; +} + +static uint32_t MapVersion2VersionBit(uint32_t version) +{ + uint32_t ret = 0; + switch (version) { + case HITLS_VERSION_TLS12: + ret = TLS12_VERSION_BIT; + break; + case HITLS_VERSION_TLS13: + ret = TLS13_VERSION_BIT; + break; + default: + break; + } + return ret; +} + +static int ChangeVersionMask(HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion) +{ + uint32_t originVersionMask = config->originVersionMask; + uint32_t versionMask = 0; + uint32_t versionBit = 0; + + /* Creating a DTLS version but setting a TLS version is invalid. */ + if (originVersionMask == DTLS_VERSION_MASK) { + if (IS_DTLS_VERSION(minVersion) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + return HITLS_CONFIG_INVALID_VERSION; + } + } + + if (originVersionMask == TLS_VERSION_MASK) { + /* Creating a TLS version but setting a DTLS version is invalid. */ + if (IS_DTLS_VERSION(minVersion)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + return HITLS_CONFIG_INVALID_VERSION; + } + + for (uint16_t version = minVersion; version <= maxVersion; version++) { + versionBit = MapVersion2VersionBit(version); + versionMask |= versionBit; + } + + if ((versionMask & originVersionMask) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + return HITLS_CONFIG_INVALID_VERSION; + } + + config->version = versionMask; + return HITLS_SUCCESS; + } + + return HITLS_SUCCESS; +} + +static int32_t CheckVersionValid(const HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion) +{ + if ((minVersion < HITLS_VERSION_SSL30 && minVersion != 0) || + (minVersion == HITLS_VERSION_SSL30 && config->minVersion != HITLS_VERSION_SSL30) || + (maxVersion <= HITLS_VERSION_SSL30 && maxVersion != 0)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + return HITLS_CONFIG_INVALID_VERSION; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetVersion(HITLS_Config *config, uint16_t minVersion, uint16_t maxVersion) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (config->minVersion == minVersion && config->maxVersion == maxVersion && minVersion != 0 && maxVersion != 0) { + return HITLS_SUCCESS; + } + + /* TLCP cannot be supported by setting the version number. They can be + * initialized only by using the corresponding configuration initialization interface. + */ + int32_t ret = CheckVersionValid(config, minVersion, maxVersion); + if (ret != HITLS_SUCCESS) { + return ret; + } + + config->minVersion = 0; + config->maxVersion = 0; + + /* If both the latest version and the earliest version supported are 0, clear the versionMask. */ + if (minVersion == maxVersion && minVersion == 0) { + config->version = 0; + return HITLS_SUCCESS; + } + + uint16_t tmpMinVersion = minVersion; + uint16_t tmpMaxVersion = maxVersion; + + if (tmpMinVersion == 0) { + if (config->originVersionMask == DTLS_VERSION_MASK) { + tmpMinVersion = HITLS_VERSION_DTLS12; + } else { + tmpMinVersion = HITLS_VERSION_TLS12; + } + } else if (tmpMaxVersion == 0) { + if (config->originVersionMask == DTLS_VERSION_MASK) { + tmpMaxVersion = HITLS_VERSION_DTLS12; + } else { + tmpMaxVersion = HITLS_VERSION_TLS13; + } + } + + ret = CFG_CheckVersion(tmpMinVersion, tmpMaxVersion); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* In invalid cases, both maxVersion and minVersion are 0 */ + if (ChangeVersionMask(config, tmpMinVersion, tmpMaxVersion) == HITLS_SUCCESS) { + config->minVersion = tmpMinVersion; + config->maxVersion = tmpMaxVersion; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetVersionForbid(HITLS_Config *config, uint32_t noVersion) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + // Now only DTLS1.2 is supported, so single version is not supported (disable to version 0) + if ((config->originVersionMask & TLS_VERSION_MASK) == TLS_VERSION_MASK) { + uint32_t noVersionBit = MapVersion2VersionBit(noVersion); + if ((config->version & (~noVersionBit)) == 0) { + return HITLS_SUCCESS; // Not all is disabled but the return value is SUCCESS + } + config->version &= ~noVersionBit; + uint32_t versionBits[] = { + TLS12_VERSION_BIT, TLS13_VERSION_BIT}; + uint16_t versions[] = { + HITLS_VERSION_TLS12, HITLS_VERSION_TLS13}; + uint32_t versionBitsSize = sizeof(versionBits) / sizeof(uint32_t); + for (uint32_t i = 0; i < versionBitsSize; i++) { + if ((config->version & versionBits[i]) == versionBits[i]) { + config->minVersion = versions[i]; + break; + } + } + for (int i = (int)versionBitsSize - 1; i >= 0; i--) { + if ((config->version & versionBits[i]) == versionBits[i]) { + config->maxVersion = versions[i]; + break; + } + } + } + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_ClearTLS13CipherSuites(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_FREE(config->tls13CipherSuites); + config->tls13cipherSuitesSize = 0; + return HITLS_SUCCESS; +} + +static void GetCipherSuitesCnt(const uint16_t *cipherSuites, uint32_t cipherSuitesSize, + uint32_t *tls13CipherSize, uint32_t *tlsCipherSize) +{ + uint32_t tmpCipherSize = *tlsCipherSize; + uint32_t tmpTls13CipherSize = *tls13CipherSize; + for (uint32_t i = 0; i < cipherSuitesSize; i++) { + if (cipherSuites[i] >= HITLS_AES_128_GCM_SHA256 && cipherSuites[i] <= HITLS_AES_128_CCM_8_SHA256) { + tmpTls13CipherSize++; + continue; + } + tmpCipherSize++; + } + *tls13CipherSize = tmpTls13CipherSize; + *tlsCipherSize = tmpCipherSize; +} + +int32_t HITLS_CFG_SetCipherSuites(HITLS_Config *config, const uint16_t *cipherSuites, uint32_t cipherSuitesSize) +{ + if (config == NULL || cipherSuites == NULL || cipherSuitesSize == 0) { + return HITLS_NULL_INPUT; + } + + if (cipherSuitesSize > HITLS_CFG_MAX_SIZE) { + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint32_t tlsCipherSize = 0, tls13CipherSize = 0; + uint32_t validTls13Cipher = 0, validTlsCipher = 0; + + GetCipherSuitesCnt(cipherSuites, cipherSuitesSize, &tls13CipherSize, &tlsCipherSize); + + uint16_t *cipherSuite = BSL_SAL_Calloc(1u, (tlsCipherSize + 1) * sizeof(uint16_t)); + if (cipherSuite == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + uint16_t *tls13CipherSuite = BSL_SAL_Calloc(1u, (tls13CipherSize + 1) * sizeof(uint16_t)); + if (tls13CipherSuite == NULL) { + BSL_SAL_FREE(cipherSuite); + return HITLS_MEMALLOC_FAIL; + } + + for (uint32_t i = 0; i < cipherSuitesSize; i++) { + if (CFG_CheckCipherSuiteSupported(cipherSuites[i]) != true) { + continue; + } + if (cipherSuites[i] >= HITLS_AES_128_GCM_SHA256 && cipherSuites[i] <= HITLS_AES_128_CCM_8_SHA256) { + tls13CipherSuite[validTls13Cipher] = cipherSuites[i]; + validTls13Cipher++; + continue; + } + cipherSuite[validTlsCipher] = cipherSuites[i]; + validTlsCipher++; + } + + if (validTls13Cipher == 0) { + BSL_SAL_FREE(tls13CipherSuite); + } else { + BSL_SAL_FREE(config->tls13CipherSuites); + config->tls13CipherSuites = tls13CipherSuite; + config->tls13cipherSuitesSize = validTls13Cipher; + } + + if (validTlsCipher == 0) { + BSL_SAL_FREE(cipherSuite); + } else { + BSL_SAL_FREE(config->cipherSuites); + config->cipherSuites = cipherSuite; + config->cipherSuitesSize = validTlsCipher; + } + + if (validTlsCipher == 0 && validTls13Cipher == 0) { + return HITLS_CONFIG_NO_SUITABLE_CIPHER_SUITE; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetEcPointFormats(HITLS_Config *config, const uint8_t *pointFormats, uint32_t pointFormatsSize) +{ + if ((config == NULL) || (pointFormats == NULL) || (pointFormatsSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (pointFormatsSize > HITLS_CFG_MAX_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint8_t *newData = BSL_SAL_Dump(pointFormats, pointFormatsSize * sizeof(uint8_t)); + /* If the allocation fails, return an error code */ + if (newData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + /* Reallocate the memory of pointFormats and update the length of pointFormats */ + BSL_SAL_FREE(config->pointFormats); + config->pointFormats = newData; + config->pointFormatsSize = pointFormatsSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetGroups(HITLS_Config *config, const uint16_t *groups, uint32_t groupsSize) +{ + if ((config == NULL) || (groups == NULL) || (groupsSize == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (groupsSize > HITLS_CFG_MAX_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint16_t *newData = BSL_SAL_Dump(groups, groupsSize * sizeof(uint16_t)); + /* If the allocation fails, return an error code */ + if (newData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + /* Reallocate the memory of groups and update the length of groups */ + BSL_SAL_FREE(config->groups); + config->groups = newData; + config->groupsSize = groupsSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSignature(HITLS_Config *config, const uint16_t *signAlgs, uint16_t signAlgsSize) +{ + if ((config == NULL) || (signAlgs == NULL) || (signAlgsSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (signAlgsSize > HITLS_CFG_MAX_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint16_t *newData = BSL_SAL_Dump(signAlgs, signAlgsSize * sizeof(uint16_t)); + /* If the allocation fails, return an error code */ + if (newData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + /* Reallocate the signAlgs memory and update the signAlgs length */ + BSL_SAL_FREE(config->signAlgorithms); + config->signAlgorithms = newData; + config->signAlgorithmsSize = signAlgsSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetServerName(HITLS_Config *config, uint8_t *serverName, uint32_t serverNameStrlen) +{ + uint32_t serverNameSize = 0u; + if ((config == NULL) || (serverName == NULL) || (serverNameStrlen == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (serverNameStrlen > HITLS_CFG_MAX_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + serverNameSize = serverNameStrlen; + if (serverName[serverNameStrlen - 1] != '\0') { + serverNameSize += 1; + } + uint8_t *newData = (uint8_t *) BSL_SAL_Malloc(serverNameSize * sizeof(uint8_t)); + if (newData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + if (memcpy_s(newData, serverNameSize, serverName, serverNameStrlen) != EOK) { + BSL_SAL_FREE(newData); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + newData[serverNameSize - 1] = '\0'; + /* Reallocate the serverName memory and update the serverName length */ + BSL_SAL_FREE(config->serverName); + config->serverName = newData; + config->serverNameSize = serverNameSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetServerName(HITLS_Config *config, uint8_t **serverName, uint32_t *serverNameStrlen) +{ + if (config == NULL || serverName == NULL || serverNameStrlen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *serverName = config->serverName; + *serverNameStrlen = config->serverNameSize; + + return HITLS_SUCCESS; +} +int32_t HITLS_CFG_SetServerNameCb(HITLS_Config *config, HITLS_SniDealCb callback) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->sniDealCb = callback; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetServerNameArg(HITLS_Config *config, void *arg) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->sniArg = arg; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetServerNameCb(HITLS_Config *config, HITLS_SniDealCb *callback) +{ + if (config == NULL || callback == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *callback = config->sniDealCb; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetServerNameArg(HITLS_Config *config, void **arg) +{ + if (config == NULL || arg == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *arg = config->sniArg; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetRenegotiationSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + config->isSupportRenegotiation = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetResumptionOnRenegoSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + config->isResumptionOnRenego = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetClientVerifySupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + config->isSupportClientVerify = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetNoClientCertSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->isSupportNoClientCert = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetExtenedMasterSecretSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + /** et the extended master key flag */ + config->isSupportExtendMasterSecret = support; + return HITLS_SUCCESS; +} + +// Set the identity hint interface +int32_t HITLS_CFG_SetPskIdentityHint(HITLS_Config *config, const uint8_t *hint, uint32_t hintSize) +{ + if ((config == NULL) || (hint == NULL) || (hintSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (hintSize > HITLS_IDENTITY_HINT_MAX_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint8_t *newData = BSL_SAL_Dump(hint, hintSize * sizeof(uint8_t)); + if (newData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + /* Repeated settings are supported */ + BSL_SAL_FREE(config->pskIdentityHint); + config->pskIdentityHint = newData; + config->hintSize = hintSize; + + return HITLS_SUCCESS; +} + +// Configure clientCb, which is used to obtain the PSK through identity hints +int32_t HITLS_CFG_SetPskClientCallback(HITLS_Config *config, HITLS_PskClientCb callback) +{ + if (config == NULL || callback == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->pskClientCb = callback; + return HITLS_SUCCESS; +} + +// Set serverCb to obtain the PSK through identity. +int32_t HITLS_CFG_SetPskServerCallback(HITLS_Config *config, HITLS_PskServerCb callback) +{ + if (config == NULL || callback == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->pskServerCb = callback; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetClientHelloCb(HITLS_Config *config, HITLS_ClientHelloCb callback, void *arg) +{ + if (config == NULL || callback == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->clientHelloCb = callback; + config->clientHelloCbArg = arg; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetNoSecRenegotiationCb(HITLS_Config *config, HITLS_NoSecRenegotiationCb callback) +{ + if (config == NULL || callback == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->noSecRenegotiationCb = callback; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetDhAutoSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->isSupportDhAuto = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSessionTicketSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->isSupportSessionTicket = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetTmpDh(HITLS_Config *config, HITLS_CRYPT_Key *dhPkey) +{ + if ((config == NULL) || (dhPkey == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + SAL_CRYPT_FreeDhKey(config->dhTmp); + config->dhTmp = dhPkey; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetRenegotiationSupport(const HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportRenegotiation; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetClientVerifySupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportClientVerify; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetNoClientCertSupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportNoClientCert; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetExtenedMasterSecretSupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportExtendMasterSecret; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetDhAutoSupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportDhAuto; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetSessionTicketSupport(const HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportSessionTicket; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetTicketKeyCallback(HITLS_Config *config, HITLS_TicketKeyCb callback) +{ + if (config == NULL || config->sessMgr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + SESSMGR_SetTicketKeyCb(config->sessMgr, callback); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetSessionTicketKey(const HITLS_Config *config, uint8_t *key, uint32_t keySize, uint32_t *outSize) +{ + if (config == NULL || config->sessMgr == NULL || key == NULL || outSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SESSMGR_GetTicketKey(config->sessMgr, key, keySize, outSize); +} + +int32_t HITLS_CFG_SetSessionTicketKey(HITLS_Config *config, const uint8_t *key, uint32_t keySize) +{ + if (config == NULL || config->sessMgr == NULL || key == NULL || + (keySize != HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_SIZE + HITLS_TICKET_KEY_SIZE)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SESSMGR_SetTicketKey(config->sessMgr, key, keySize); +} + +int32_t HITLS_CFG_SetPostHandshakeAuthSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + config->isSupportPostHandshakeAuth = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetPostHandshakeAuthSupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportPostHandshakeAuth; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetVerifyNoneSupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + config->isSupportVerifyNone = support; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetVerifyNoneSupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportVerifyNone; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetClientOnceVerifySupport(HITLS_Config *config, bool support) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + config->isSupportClientOnceVerify = support; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetClientOnceVerifySupport(HITLS_Config *config, uint8_t *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = (uint8_t)config->isSupportClientOnceVerify; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_AddCAIndication(HITLS_Config *config, HITLS_TrustedCAType caType, const uint8_t *data, uint32_t len) +{ + if ((config == NULL) || (data == NULL) || (len == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_TrustedCANode *newCaNode = BSL_SAL_Calloc(1u, sizeof(HITLS_TrustedCANode)); + if (newCaNode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + newCaNode->caType = caType; + newCaNode->data = BSL_SAL_Dump(data, len); + if (newCaNode->data == NULL) { + BSL_SAL_FREE(newCaNode); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + newCaNode->dataSize = len; + + if (config->caList == NULL) { + config->caList = BSL_LIST_New(sizeof(HITLS_TrustedCANode *)); + if (config->caList == NULL) { + BSL_SAL_FREE(newCaNode->data); + BSL_SAL_FREE(newCaNode); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + } + + /* tail insertion */ + int32_t ret = (int32_t)BSL_LIST_AddElement((BslList *)config->caList, newCaNode, BSL_LIST_POS_END); + if (ret != 0) { + BSL_SAL_FREE(newCaNode->data); + BSL_SAL_FREE(newCaNode); + return ret; + } + + return HITLS_SUCCESS; +} + +HITLS_TrustedCAList *HITLS_CFG_GetCAList(const HITLS_Config *config) +{ + return config->caList; +} + +int32_t HITLS_CFG_SetKeyExchMode(HITLS_Config *config, uint32_t mode) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + if (((mode & TLS13_KE_MODE_PSK_ONLY) == TLS13_KE_MODE_PSK_ONLY) || + ((mode & TLS13_KE_MODE_PSK_WITH_DHE) == TLS13_KE_MODE_PSK_WITH_DHE)) { + config->keyExchMode = (mode & (TLS13_KE_MODE_PSK_ONLY | TLS13_KE_MODE_PSK_WITH_DHE)); + return HITLS_SUCCESS; + } + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET); + return HITLS_CONFIG_INVALID_SET; +} + +uint32_t HITLS_CFG_GetKeyExchMode(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return config->keyExchMode; +} + +int32_t HITLS_CFG_GetMaxVersion(const HITLS_Config *config, uint16_t *maxVersion) +{ + if (config == NULL || maxVersion == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *maxVersion = config->maxVersion; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetMinVersion(const HITLS_Config *config, uint16_t *minVersion) +{ + if (config == NULL || minVersion == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *minVersion = config->minVersion; + return HITLS_SUCCESS; +} + +static int32_t AlpnListValidationCheck(const uint8_t *alpnList, uint32_t alpnProtosLen) +{ + uint32_t index = 0u; + + while (index < alpnProtosLen) { + if (alpnList[index] == 0) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + index += (alpnList[index] + 1); + } + + if (index != alpnProtosLen) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetAlpnProtos(HITLS_Config *config, const uint8_t *alpnProtos, uint32_t alpnProtosLen) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + /* If the input parameter is empty or the length is 0, clear the original alpn list */ + if (alpnProtosLen == 0 || alpnProtos == NULL) { + BSL_SAL_FREE(config->alpnList); + config->alpnListSize = 0; + return HITLS_SUCCESS; + } + + /* Add the check on alpnList. The expected format is |protoLen1|proto1|protoLen2|proto2|...| */ + if (AlpnListValidationCheck(alpnProtos, alpnProtosLen) != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint8_t *alpnListTmp = (uint8_t *)BSL_SAL_Calloc(alpnProtosLen + 1, sizeof(uint8_t)); + if (alpnListTmp == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + if (memcpy_s(alpnListTmp, alpnProtosLen + 1, alpnProtos, alpnProtosLen) != EOK) { + BSL_SAL_FREE(alpnListTmp); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + BSL_SAL_FREE(config->alpnList); + config->alpnList = alpnListTmp; + /* Ignore ending 0s */ + config->alpnListSize = alpnProtosLen; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetAlpnProtosSelectCb(HITLS_Config *config, HITLS_AlpnSelectCb callback, void *userData) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->alpnSelectCb = callback; + config->alpnUserData = userData; + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSessionIdCtx(HITLS_Config *config, const uint8_t *sessionIdCtx, uint32_t len) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (len != 0 && memcpy_s(config->sessionIdCtx, sizeof(config->sessionIdCtx), sessionIdCtx, len) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + /* The allowed value is 0 */ + config->sessionIdCtxSize = len; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSessionCacheMode(HITLS_Config *config, HITLS_SESS_CACHE_MODE mode) +{ + if (config == NULL || config->sessMgr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + SESSMGR_SetCacheMode(config->sessMgr, mode); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetSessionCacheMode(HITLS_Config *config, HITLS_SESS_CACHE_MODE *mode) +{ + if (config == NULL || config->sessMgr == NULL || mode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *mode = SESSMGR_GetCacheMode(config->sessMgr); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSessionCacheSize(HITLS_Config *config, uint32_t size) +{ + if (config == NULL || config->sessMgr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + SESSMGR_SetCacheSize(config->sessMgr, size); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetSessionCacheSize(HITLS_Config *config, uint32_t *size) +{ + if (config == NULL || config->sessMgr == NULL || size == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *size = SESSMGR_GetCacheSize(config->sessMgr); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSessionTimeout(HITLS_Config *config, uint64_t timeout) +{ + if (config == NULL || config->sessMgr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + SESSMGR_SetTimeout(config->sessMgr, timeout); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetSessionTimeout(const HITLS_Config *config, uint64_t *timeout) +{ + if (config == NULL || config->sessMgr == NULL || timeout == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *timeout = SESSMGR_GetTimeout(config->sessMgr); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetVersionSupport(const HITLS_Config *config, uint32_t *version) +{ + if ((config == NULL) || (version == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *version = config->version; + return HITLS_SUCCESS; +} + +static void ChangeSupportVersion(HITLS_Config *config) +{ + uint32_t versionMask = config->version; + uint32_t originVersionMask = config->originVersionMask; + + config->maxVersion = 0; + config->minVersion = 0; + /* The original supported version is disabled. This is abnormal and packets cannot be sent */ + if ((versionMask & originVersionMask) == 0) { + return; + } + + /* Currently, only DTLS1.2 is supported. DTLS1.0 is not supported */ + if ((versionMask & DTLS12_VERSION_BIT) == DTLS12_VERSION_BIT) { + config->maxVersion = HITLS_VERSION_DTLS12; + config->minVersion = HITLS_VERSION_DTLS12; + return; + } + + /* Description TLS_ANY_VERSION */ + uint32_t versionBits[] = {TLS12_VERSION_BIT, TLS13_VERSION_BIT}; + uint16_t versions[] = {HITLS_VERSION_TLS12, HITLS_VERSION_TLS13}; + + uint32_t versionBitsSize = sizeof(versionBits) / sizeof(uint32_t); + for (uint32_t i = 0; i < versionBitsSize; i++) { + if ((versionMask & versionBits[i]) == versionBits[i]) { + config->maxVersion = versions[i]; + if (config->minVersion == 0) { + config->minVersion = versions[i]; + } + } + } +} + +int32_t HITLS_CFG_SetVersionSupport(HITLS_Config *config, uint32_t version) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if ((version & SSLV3_VERSION_BIT) == SSLV3_VERSION_BIT) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + return HITLS_CONFIG_INVALID_VERSION; + } + + config->version = version; + /* Update the maximum supported version */ + ChangeSupportVersion(config); + return HITLS_SUCCESS; +} + +int32_t HITLS_SetVersion(HITLS_Ctx *ctx, uint32_t minVersion, uint32_t maxVersion) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetVersion(&(ctx->config.tlsConfig), (uint16_t)minVersion, (uint16_t)maxVersion); +} + +int32_t HITLS_SetVersionForbid(HITLS_Ctx *ctx, uint32_t noVersion) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + return HITLS_CFG_SetVersionForbid(&(ctx->config.tlsConfig), noVersion); +} + +int32_t HITLS_CFG_SetNeedCheckPmsVersion(HITLS_Config *config, bool needCheck) +{ + if (config == NULL) { + return HITLS_NULL_INPUT; + } + config->needCheckPmsVersion = needCheck; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetQuietShutdown(HITLS_Config *config, int32_t mode) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + /* The value 0 indicates that the quiet disconnection mode is disabled. The value 1 indicates that the quiet + * disconnection mode is enabled. + */ + if (mode != 0 && mode != 1) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET); + return HITLS_CONFIG_INVALID_SET; + } + + if (mode == 0) { + config->isQuietShutdown = false; + } else { + config->isQuietShutdown = true; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetQuietShutdown(const HITLS_Config *config, int32_t *mode) +{ + if (config == NULL || mode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *mode = (int32_t)config->isQuietShutdown; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetEncryptThenMac(HITLS_Config *config, uint32_t encryptThenMacType) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (encryptThenMacType == 0) { + config->isEncryptThenMac = false; + } else { + config->isEncryptThenMac = true; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetEncryptThenMac(const HITLS_Config *config, uint32_t *encryptThenMacType) +{ + if (config == NULL || encryptThenMacType == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *encryptThenMacType = (uint32_t)config->isEncryptThenMac; + return HITLS_SUCCESS; +} + +void *HITLS_CFG_GetConfigUserData(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return config->userData; +} + +int32_t HITLS_CFG_SetConfigUserData(HITLS_Config *config, void *userData) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->userData = userData; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetConfigUserDataFreeCb(HITLS_Config *config, HITLS_ConfigUserDataFreeCb callback) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->userDataFreeCb = callback; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetPskFindSessionCallback(HITLS_Config *config, HITLS_PskFindSessionCb callback) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->pskFindSessionCb = callback; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetPskUseSessionCallback(HITLS_Config *config, HITLS_PskUseSessionCb callback) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->pskUseSessionCb = callback; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_IsDtls(const HITLS_Config *config, uint8_t *isDtls) +{ + if (config == NULL || isDtls == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isDtls = ((config->originVersionMask & DTLS12_VERSION_BIT) != 0); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetCipherServerPreference(HITLS_Config *config, bool isSupport) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->isSupportServerPreference = isSupport; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetCipherServerPreference(const HITLS_Config *config, bool *isSupport) +{ + if (config == NULL || isSupport == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isSupport = config->isSupportServerPreference; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetTicketNums(HITLS_Config *config, uint32_t ticketNums) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->ticketNums = ticketNums; + return HITLS_SUCCESS; +} + +uint32_t HITLS_CFG_GetTicketNums(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return config->ticketNums; +} + +int32_t HITLS_CFG_SetNewSessionCb(HITLS_Config *config, HITLS_NewSessionCb newSessionCb) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->newSessionCb = newSessionCb; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetFlightTransmitSwitch(HITLS_Config *config, uint8_t isEnable) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (isEnable == 0) { + config->isFlightTransmitEnable = false; + } else { + config->isFlightTransmitEnable = true; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetFlightTransmitSwitch(const HITLS_Config *config, uint8_t *isEnable) +{ + if (config == NULL || isEnable == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *isEnable = config->isFlightTransmitEnable; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetMaxCertList(HITLS_Config *config, uint32_t maxSize) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->maxCertList = maxSize; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetMaxCertList(const HITLS_Config *config, uint32_t *maxSize) +{ + if (config == NULL || maxSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *maxSize = config->maxCertList; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetRecordPaddingCb(HITLS_Config *config, HITLS_RecordPaddingCb callback) +{ + if (config == NULL) { + return HITLS_NULL_INPUT; + } + + config->recordPaddingCb = callback; + + return HITLS_SUCCESS; +} + +HITLS_RecordPaddingCb HITLS_CFG_GetRecordPaddingCb(HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return config->recordPaddingCb; +} + +int32_t HITLS_CFG_SetRecordPaddingCbArg(HITLS_Config *config, void *arg) +{ + if (config == NULL) { + return HITLS_NULL_INPUT; + } + + config->recordPaddingArg = arg; + + return HITLS_SUCCESS; +} + +void *HITLS_CFG_GetRecordPaddingCbArg(HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + return config->recordPaddingArg; +} + +int32_t HITLS_CFG_SetCloseCheckKeyUsage(HITLS_Config *config, bool isClose) +{ + if (config == NULL) { + return HITLS_NULL_INPUT; + } + config->needCheckKeyUsage = isClose; + + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/config/src/config_cert.c b/tls/config/src/config_cert.c new file mode 100644 index 00000000..2b7a2d9c --- /dev/null +++ b/tls/config/src/config_cert.c @@ -0,0 +1,623 @@ +/* + * 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 +#include +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_type.h" +#include "hitls_cert_type.h" +#include "tls_config.h" +#include "cert_method.h" +#include "cert_mgr.h" +#include "cert.h" +#include "security.h" + +static int32_t CheckCertSecuritylevel(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isCACert) +{ + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + HITLS_CERT_Key *pubkey = NULL; + int32_t ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + + int32_t secBits = 0; + ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_SECBITS, NULL, (void *)&secBits); + if (ret != HITLS_SUCCESS) { + SAL_CERT_KeyFree(mgrCtx, pubkey); + return ret; + } + + if (isCACert == true) { + ret = SECURITY_CfgCheck(config, HITLS_SECURITY_SECOP_CA_KEY, secBits, 0, cert); + if (ret != SECURITY_SUCCESS) { + SAL_CERT_KeyFree(mgrCtx, pubkey); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_CA_KEY_WITH_INSECURE_SECBITS); + return HITLS_CERT_ERR_CA_KEY_WITH_INSECURE_SECBITS; + } + } else { + ret = SECURITY_CfgCheck(config, HITLS_SECURITY_SECOP_EE_KEY, secBits, 0, cert); + if (ret != SECURITY_SUCCESS) { + SAL_CERT_KeyFree(mgrCtx, pubkey); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_EE_KEY_WITH_INSECURE_SECBITS); + return HITLS_CERT_ERR_EE_KEY_WITH_INSECURE_SECBITS; + } + } + + int32_t signAlg = 0; + ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_SIGN_ALGO, NULL, (void *)&signAlg); + if (ret != HITLS_SUCCESS) { + SAL_CERT_KeyFree(mgrCtx, pubkey); + return ret; + } + + ret = SECURITY_CfgCheck(config, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signAlg, NULL); + if (ret != SECURITY_SUCCESS) { + SAL_CERT_KeyFree(mgrCtx, pubkey); + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_INSECURE_SIG_ALG); + return HITLS_CERT_ERR_INSECURE_SIG_ALG; + } + SAL_CERT_KeyFree(mgrCtx, pubkey); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetVerifyStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Store *newStore = NULL; + if (isClone && store != NULL) { + newStore = SAL_CERT_StoreDup(config->certMgrCtx, store); + if (newStore == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_STORE_DUP); + return HITLS_CERT_ERR_STORE_DUP; + } + } else { + newStore = store; + } + + int32_t ret = SAL_CERT_SetVerifyStore(config->certMgrCtx, newStore); + if (ret != HITLS_SUCCESS) { + if (isClone && newStore != NULL) { + SAL_CERT_StoreFree(config->certMgrCtx, newStore); + } + } + return ret; +} + +HITLS_CERT_Store *HITLS_CFG_GetVerifyStore(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetVerifyStore(config->certMgrCtx); +} + +int32_t HITLS_CFG_SetChainStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Store *newStore = NULL; + if (isClone && store != NULL) { + newStore = SAL_CERT_StoreDup(config->certMgrCtx, store); + if (newStore == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_STORE_DUP); + return HITLS_CERT_ERR_STORE_DUP; + } + } else { + newStore = store; + } + + int32_t ret = SAL_CERT_SetChainStore(config->certMgrCtx, newStore); + if (ret != HITLS_SUCCESS) { + if (isClone && newStore != NULL) { + SAL_CERT_StoreFree(config->certMgrCtx, newStore); + } + } + return ret; +} + +HITLS_CERT_Store *HITLS_CFG_GetChainStore(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetChainStore(config->certMgrCtx); +} + +int32_t HITLS_CFG_SetCertStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Store *newStore = NULL; + if (isClone && store != NULL) { + newStore = SAL_CERT_StoreDup(config->certMgrCtx, store); + if (newStore == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_STORE_DUP); + return HITLS_CERT_ERR_STORE_DUP; + } + } else { + newStore = store; + } + + int32_t ret = SAL_CERT_SetCertStore(config->certMgrCtx, newStore); + if (ret != HITLS_SUCCESS) { + if (isClone && newStore != NULL) { + SAL_CERT_StoreFree(config->certMgrCtx, newStore); + } + } + return ret; +} + +HITLS_CERT_Store *HITLS_CFG_GetCertStore(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetCertStore(config->certMgrCtx); +} + +int32_t HITLS_CFG_SetVerifyDepth(HITLS_Config *config, uint32_t depth) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SAL_CERT_SetVerifyDepth(config->certMgrCtx, depth); +} + +int32_t HITLS_CFG_GetVerifyDepth(const HITLS_Config *config, uint32_t *depth) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SAL_CERT_GetVerifyDepth(config->certMgrCtx, depth); +} + +int32_t HITLS_CFG_SetDefaultPasswordCb(HITLS_Config *config, HITLS_PasswordCb cb) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SAL_CERT_SetDefaultPasswordCb(config->certMgrCtx, cb); +} + +HITLS_PasswordCb HITLS_CFG_GetDefaultPasswordCb(HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetDefaultPasswordCb(config->certMgrCtx); +} + +int32_t HITLS_CFG_SetDefaultPasswordCbUserdata(HITLS_Config *config, void *userdata) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SAL_CERT_SetDefaultPasswordCbUserdata(config->certMgrCtx, userdata); +} + +void *HITLS_CFG_GetDefaultPasswordCbUserdata(HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetDefaultPasswordCbUserdata(config->certMgrCtx); +} + +static int32_t CFG_SetCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert) +{ + if (config == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_X509 *newCert = NULL; + if (isClone) { + newCert = SAL_CERT_X509Dup(config->certMgrCtx, cert); + if (newCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_X509_DUP); + return HITLS_CERT_ERR_X509_DUP; + } + } else { + newCert = cert; + } + + int32_t ret = SAL_CERT_SetCurrentCert(config, newCert, isTlcpEncCert); + if (ret != HITLS_SUCCESS) { + if (isClone) { + SAL_CERT_X509Free(newCert); + } + } + return ret; +} + +int32_t HITLS_CFG_SetCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone) +{ + if (config == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + int32_t ret = CheckCertSecuritylevel(config, cert, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + return CFG_SetCertificate(config, cert, isClone, false); +} + +int32_t HITLS_CFG_LoadCertFile(HITLS_Config *config, const char *file, HITLS_ParseFormat format) +{ + if (config == NULL || file == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + if (mgrCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + HITLS_CERT_X509 *cert = SAL_CERT_X509Parse(config, (const uint8_t *)file, (uint32_t)strlen(file), + TLS_PARSE_TYPE_FILE, format); + if (cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_ERR_LOAD_CERT_FILE); + return HITLS_CONFIG_ERR_LOAD_CERT_FILE; + } + + int32_t ret = CheckCertSecuritylevel(config, cert, false); + if (ret != HITLS_SUCCESS) { + SAL_CERT_X509Free(cert); + return ret; + } + + ret = SAL_CERT_SetCurrentCert(config, cert, false); + if (ret != HITLS_SUCCESS) { + SAL_CERT_X509Free(cert); + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_LoadCertBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format) +{ + if (config == NULL || buf == NULL || bufLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_X509 *newCert = SAL_CERT_X509Parse(config, buf, bufLen, TLS_PARSE_TYPE_BUFF, format); + if (newCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_ERR_LOAD_CERT_BUFFER); + return HITLS_CONFIG_ERR_LOAD_CERT_BUFFER; + } + + int32_t ret = CheckCertSecuritylevel(config, newCert, false); + if (ret != HITLS_SUCCESS) { + SAL_CERT_X509Free(newCert); + return ret; + } + + ret = SAL_CERT_SetCurrentCert(config, newCert, false); + if (ret != HITLS_SUCCESS) { + SAL_CERT_X509Free(newCert); + return ret; + } + + return HITLS_SUCCESS; +} + +HITLS_CERT_X509 *HITLS_CFG_GetCertificate(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetCurrentCert(config->certMgrCtx); +} + +static int32_t CFG_SetPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, bool isClone, + bool isTlcpEncCertPriKey) +{ + if (config == NULL || privateKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Key *newKey = NULL; + if (isClone) { + newKey = SAL_CERT_KeyDup(config->certMgrCtx, privateKey); + if (newKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_X509_DUP); + return HITLS_CERT_ERR_X509_DUP; + } + } else { + newKey = privateKey; + } + + int32_t ret = SAL_CERT_SetCurrentPrivateKey(config, newKey, isTlcpEncCertPriKey); + if (ret != HITLS_SUCCESS) { + if (isClone) { + SAL_CERT_KeyFree(config->certMgrCtx, newKey); + } + } + return ret; +} + +#ifndef HITLS_NO_TLCP11 +int32_t HITLS_CFG_SetTlcpPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, + bool isClone, bool isTlcpEncCertPriKey) +{ + return CFG_SetPrivateKey(config, privateKey, isClone, isTlcpEncCertPriKey); +} + +int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert) +{ + return CFG_SetCertificate(config, cert, isClone, isTlcpEncCert); +} +#endif + +int32_t HITLS_CFG_SetPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, bool isClone) +{ + return CFG_SetPrivateKey(config, privateKey, isClone, false); +} + +int32_t HITLS_CFG_LoadKeyFile(HITLS_Config *config, const char *file, HITLS_ParseFormat format) +{ + if (config == NULL || file == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Key *newKey = SAL_CERT_KeyParse(config, (const uint8_t *)file, (uint32_t)strlen(file), + TLS_PARSE_TYPE_FILE, format); + if (newKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_ERR_LOAD_KEY_FILE); + return HITLS_CONFIG_ERR_LOAD_KEY_FILE; + } + + int32_t ret = SAL_CERT_SetCurrentPrivateKey(config, newKey, false); + if (ret != HITLS_SUCCESS) { + SAL_CERT_KeyFree(config->certMgrCtx, newKey); + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_LoadKeyBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format) +{ + if (config == NULL || buf == NULL || bufLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Key *newKey = SAL_CERT_KeyParse(config, buf, bufLen, TLS_PARSE_TYPE_BUFF, format); + if (newKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_ERR_LOAD_KEY_BUFFER); + return HITLS_CONFIG_ERR_LOAD_KEY_BUFFER; + } + + int32_t ret = SAL_CERT_SetCurrentPrivateKey(config, newKey, false); + if (ret != HITLS_SUCCESS) { + SAL_CERT_KeyFree(config->certMgrCtx, newKey); + return ret; + } + + return HITLS_SUCCESS; +} + +HITLS_CERT_Key *HITLS_CFG_GetPrivateKey(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetCurrentPrivateKey(config->certMgrCtx, false); +} + +int32_t HITLS_CFG_CheckPrivateKey(const HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + CERT_MgrCtx *certMgrCtx = config->certMgrCtx; + if (certMgrCtx == NULL) { + /* If no certificate callback is registered, the certificate management module will not initialized. */ + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + HITLS_CERT_X509 *cert = SAL_CERT_GetCurrentCert(certMgrCtx); + if (cert == NULL) { + /* no certificate is added */ + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_CERT); + return HITLS_CONFIG_NO_CERT; + } + + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(certMgrCtx, false); + if (privateKey == NULL) { + /* no private key is added */ + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_PRIVATE_KEY); + return HITLS_CONFIG_NO_PRIVATE_KEY; + } + + return SAL_CERT_CheckPrivateKey(config, cert, privateKey); +} + +int32_t HITLS_CFG_AddChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone) +{ + if (config == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + int32_t ret = CheckCertSecuritylevel(config, cert, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + HITLS_CERT_X509 *newCert = NULL; + if (isClone) { + newCert = SAL_CERT_X509Dup(config->certMgrCtx, cert); + if (newCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_X509_DUP); + return HITLS_CERT_ERR_X509_DUP; + } + } else { + newCert = cert; + } + + ret = SAL_CERT_AddChainCert(config->certMgrCtx, newCert); + if (ret != HITLS_SUCCESS) { + if (isClone) { + SAL_CERT_X509Free(newCert); + } + return ret; + } + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_AddCertToStore(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_StoreType storeType, + bool isClone) +{ + if (config == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + HITLS_CERT_Store *store = NULL; + switch (storeType) { + case TLS_CERT_STORE_TYPE_DEFAULT: + store = SAL_CERT_GetCertStore(config->certMgrCtx); + break; + case TLS_CERT_STORE_TYPE_VERIFY: + store = SAL_CERT_GetVerifyStore(config->certMgrCtx); + break; + case TLS_CERT_STORE_TYPE_CHAIN: + store = SAL_CERT_GetChainStore(config->certMgrCtx); + break; + default: + return HITLS_CERT_ERR_INVALID_STORE_TYPE; + } + + HITLS_CERT_CtrlCmd cmd = isClone ? CERT_STORE_CTRL_DEEP_COPY_ADD_CERT_LIST : + CERT_STORE_CTRL_SHALLOW_COPY_ADD_CERT_LIST; + int32_t ret = SAL_CERT_StoreCtrl(config, store, cmd, cert, NULL); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + return ret; +} + +HITLS_CERT_Chain *HITLS_CFG_GetChainCerts(HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetCurrentChainCerts(config->certMgrCtx); +} + +int32_t HITLS_CFG_ClearChainCerts(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + SAL_CERT_ClearCurrentChainCerts(config->certMgrCtx); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_RemoveCertAndKey(HITLS_Config *config) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + SAL_CERT_ClearCertAndKey(config->certMgrCtx); + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_AddExtraChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert) +{ + if (config == NULL || cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SAL_CERT_AddExtraChainCert(config->certMgrCtx, cert); +} + +HITLS_CERT_Chain *HITLS_CFG_GetExtraChainCerts(HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetExtraChainCerts(config->certMgrCtx); +} + +int32_t HITLS_CFG_SetVerifyCb(HITLS_Config *config, HITLS_VerifyCb callback) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SAL_CERT_SetVerifyCb(config->certMgrCtx, callback); +} + +HITLS_VerifyCb HITLS_CFG_GetVerifyCb(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return SAL_CERT_GetVerifyCb(config->certMgrCtx); +} \ No newline at end of file diff --git a/tls/config/src/config_check.c b/tls/config/src/config_check.c new file mode 100644 index 00000000..abbaedac --- /dev/null +++ b/tls/config/src/config_check.c @@ -0,0 +1,281 @@ +/* + * 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 +#include +#include "bsl_err_internal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "tls.h" +#include "tls_config.h" +#include "cipher_suite.h" + +static bool IsSignAlgValid(uint16_t signAlg, uint16_t version) +{ + uint32_t listLen = 0; +#ifndef HITLS_NO_TLCP11 + const SignSchemeInfo *signSchemeList = (version != HITLS_VERSION_TLCP11) ? + CFG_GetSignSchemeList(&listLen) : + CFG_GetSignSchemeListTlcp(&listLen); +#else + (void)version; + const SignSchemeInfo *signSchemeList = CFG_GetSignSchemeList(&listLen); +#endif + + for (uint32_t i = 0; i < listLen; i++) { + if (signSchemeList[i].scheme == signAlg) { + return true; + } + } + + return false; +} + +static bool CFG_IsValidVersion(uint16_t version) +{ + switch (version) { + case HITLS_VERSION_TLS12: + case HITLS_VERSION_TLS13: + case HITLS_VERSION_DTLS12: + case HITLS_VERSION_TLCP11: + return true; + default: + break; + } + return false; +} + +static bool HaveMatchSignAlg(HITLS_AuthAlgo authAlg, const uint16_t *signatureAlgorithms, + uint32_t signatureAlgorithmsSize, uint16_t version) +{ + HITLS_SignAlgo signAlg = HITLS_SIGN_BUTT; + HITLS_HashAlgo hashAlg = HITLS_HASH_BUTT; + + /** Traverse the signature algorithms. If the matching is successful, return true */ + for (uint32_t i = 0u; i < signatureAlgorithmsSize; i++) { + if (CFG_GetSignParamBySchemes(version, signatureAlgorithms[i], &signAlg, &hashAlg)) { + if (((signAlg == HITLS_SIGN_RSA_PKCS1_V15) || (signAlg == HITLS_SIGN_RSA_PSS_RSAE)) && + (authAlg == HITLS_AUTH_RSA)) { + return true; + } + + if (((signAlg == HITLS_SIGN_ECDSA) || (signAlg == HITLS_SIGN_ED25519)) && + (authAlg == HITLS_AUTH_ECDSA)) { + return true; + } + + if (signAlg == HITLS_SIGN_DSA && authAlg == HITLS_AUTH_DSS) { + return true; + } + + if (signAlg == HITLS_SIGN_SM2 && authAlg == HITLS_AUTH_SM2) { + return true; + } + } + } + + return false; +} + +static int32_t CheckPointFormats(const TLS_Config *config) +{ + if ((config->pointFormats == NULL) || (config->pointFormatsSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET); + return HITLS_CONFIG_INVALID_SET; + } + + /** Currently, only one point format is supported */ + if ((config->pointFormatsSize != 1) || (config->pointFormats[0] != HITLS_POINT_FORMAT_UNCOMPRESSED)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_UNSUPPORT_POINT_FORMATS); + return HITLS_CONFIG_UNSUPPORT_POINT_FORMATS; + } + + return HITLS_SUCCESS; +} + +static bool IsCipherSuiteValid(const TLS_Config *config, uint16_t cipherSuite) +{ + if ((CFG_CheckCipherSuiteSupported(cipherSuite) != true) || + (CFG_CheckCipherSuiteVersion(cipherSuite, config->minVersion, config->maxVersion) != true)) { + /* The cipher suite must match the configured version */ + return false; + } + return true; +} + +static int32_t CheckSign(const TLS_Config *config) +{ + uint16_t *signAlgorithms = config->signAlgorithms; + uint32_t signAlgorithmsSize = config->signAlgorithmsSize; + /** If the signature algorithm is empty, the default signature algorithm in the cipher suite is used and no further + * check is required */ + if ((signAlgorithms == NULL) || (signAlgorithmsSize == 0)) { + return HITLS_SUCCESS; + } + + /** Check the validity of the signature algorithms one by one */ + for (uint32_t i = 0; i < signAlgorithmsSize; i++) { + if (IsSignAlgValid(signAlgorithms[i], config->maxVersion) == false) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_UNSUPPORT_SIGNATURE_ALGORITHM); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15779, BSL_LOG_LEVEL_FATAL, BSL_LOG_BINLOG_TYPE_RUN, + "Unsupported signature algorithms: 0x%04x.", signAlgorithms[i], 0, 0, 0); + return HITLS_CONFIG_UNSUPPORT_SIGNATURE_ALGORITHM; + } + } + + /** + In this case, only the 1.3 cipher suite is configured, or only TLS1.3 is supported. + The authentication algorithm is not specified in the TLS 1.3 cipher suite and therefore does not need to be + checked. + */ + if (config->cipherSuitesSize == 0 || ((config->minVersion == HITLS_VERSION_TLS13) && + (config->maxVersion == HITLS_VERSION_TLS13))) { + return HITLS_SUCCESS; + } + + /** Check the compatibility between the signature algorithm and the cipher suite */ + for (uint32_t i = 0; i < config->cipherSuitesSize; i++) { + CipherSuiteInfo info = {0}; + if (IsCipherSuiteValid(config, config->cipherSuites[i]) == false) { + continue; + } + + (void)CFG_GetCipherSuiteInfo(config->cipherSuites[i], &info); + + /** PSK does not require the signature algorithm */ + if ((info.kxAlg == HITLS_KEY_EXCH_PSK) || (info.kxAlg == HITLS_KEY_EXCH_DHE_PSK) || + (info.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) { + return HITLS_SUCCESS; + } + + /* Anon does not require the signature algorithm */ + if (info.authAlg == HITLS_AUTH_NULL) { + return HITLS_SUCCESS; + } + + /** Check whether a signature algorithm matching the cipher suite exists */ + if (HaveMatchSignAlg(info.authAlg, signAlgorithms, signAlgorithmsSize, config->maxVersion)) { + return HITLS_SUCCESS; + } + } + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_SUITABLE_SIGNATURE_ALGORITHM); + return HITLS_CONFIG_NO_SUITABLE_SIGNATURE_ALGORITHM; +} + +static bool IsHaveEccCipherSuite(const TLS_Config *config) +{ + for (uint32_t i = 0u; i < config->cipherSuitesSize; i++) { + CipherSuiteInfo info = {0}; + if (IsCipherSuiteValid(config, config->cipherSuites[i]) == false) { + continue; + } + (void)CFG_GetCipherSuiteInfo(config->cipherSuites[i], &info); + + /* The ECC cipher suite exists */ + if ((info.authAlg == HITLS_AUTH_ECDSA) || + (info.kxAlg == HITLS_KEY_EXCH_ECDHE) || + (info.kxAlg == HITLS_KEY_EXCH_ECDH) || + (info.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) { + return true; + } + } + + return false; +} + +static int32_t CheckGroup(const TLS_Config *config) +{ + if (config->groupsSize == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_NO_GROUPS); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15780, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "Set ecdhe cipher with no group id", 0, 0, 0, 0); + return HITLS_CONFIG_NO_GROUPS; + } + + return HITLS_SUCCESS; +} + +int32_t CFG_CheckVersion(uint16_t minVersion, uint16_t maxVersion) +{ + if ((CFG_IsValidVersion(minVersion) == false) || (CFG_IsValidVersion(maxVersion) == false) || + (IS_DTLS_VERSION(minVersion) != IS_DTLS_VERSION(maxVersion))) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15781, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, minVersion, 0, 0); + return HITLS_CONFIG_INVALID_VERSION; + } + + if ((IS_DTLS_VERSION(maxVersion) && (maxVersion > minVersion))) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15782, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, minVersion, 0, 0); + return HITLS_CONFIG_INVALID_VERSION; + } + + if ((IS_DTLS_VERSION(maxVersion) == false) && (maxVersion < minVersion)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15783, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, minVersion, 0, 0); + return HITLS_CONFIG_INVALID_VERSION; + } +#ifndef HITLS_NO_TLCP11 + if (minVersion == HITLS_VERSION_TLCP11 || maxVersion == HITLS_VERSION_TLCP11) { + if (minVersion != maxVersion) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15331, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Config max version [0x%x] or min version [0x%x] is invalid.", maxVersion, + minVersion, 0, 0); + return HITLS_CONFIG_INVALID_VERSION; + } + } +#endif + return HITLS_SUCCESS; +} + +int32_t CFG_CheckConfig(const TLS_Config *config) +{ + int32_t ret; + + /** The check of the cipher suite is checked during setting. The algorithm suite needs to be sorted and the memory + * overhead increases. Therefore, the algorithm suite is still placed in the Set interface */ + if (config->cipherSuitesSize == 0 && config->tls13cipherSuitesSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_SET); + return HITLS_CONFIG_INVALID_SET; + } + + /* The checkpoint format and group are required only when the ecdhe cipher suite is available */ + if (IsHaveEccCipherSuite(config)) { + ret = CheckPointFormats(config); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = CheckGroup(config); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = CheckSign(config); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} diff --git a/tls/config/src/config_default.c b/tls/config/src/config_default.c new file mode 100644 index 00000000..0e0fcb87 --- /dev/null +++ b/tls/config/src/config_default.c @@ -0,0 +1,464 @@ +/* + * 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 "bsl_sal.h" +#include "hitls_type.h" +#include "hitls_crypt_type.h" +#include "hitls_config.h" +#include "hitls_error.h" +#include "tls_config.h" +#include "config.h" +#include "cipher_suite.h" +#include "session_mgr.h" +#include "security.h" + +#ifndef HITLS_NO_TLCP11 +static int32_t SetTLCPDefaultCipherSuites(HITLS_Config *config) +{ + const uint16_t cipherSuites[] = { + HITLS_ECDHE_SM4_CBC_SM3, + HITLS_ECC_SM4_CBC_SM3, + }; + uint32_t size = sizeof(cipherSuites); + + config->cipherSuites = BSL_SAL_Dump(cipherSuites, size); + if (config->cipherSuites == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + config->cipherSuitesSize = size / sizeof(uint16_t); + return HITLS_SUCCESS; +} +#endif + +static int32_t SetTls12DefaultCipherSuites(HITLS_Config *config) +{ + const uint16_t ciphersuites12[] = { + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_CCM, + HITLS_ECDHE_ECDSA_WITH_AES_256_CCM, + HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + HITLS_DHE_RSA_WITH_AES_128_CCM, + HITLS_DHE_RSA_WITH_AES_256_CCM, + HITLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + HITLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + HITLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + HITLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + HITLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + HITLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + HITLS_DHE_RSA_WITH_AES_256_CBC_SHA, + HITLS_DHE_DSS_WITH_AES_256_CBC_SHA, + HITLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + HITLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + HITLS_DHE_RSA_WITH_AES_128_CBC_SHA, + HITLS_DHE_DSS_WITH_AES_128_CBC_SHA, + HITLS_RSA_WITH_AES_256_GCM_SHA384, + HITLS_RSA_WITH_AES_128_GCM_SHA256, + HITLS_RSA_WITH_AES_256_CBC_SHA256, + HITLS_RSA_WITH_AES_128_CBC_SHA256, + HITLS_RSA_WITH_AES_256_CBC_SHA, + HITLS_RSA_WITH_AES_128_CBC_SHA, + }; + uint32_t size = sizeof(ciphersuites12); + + config->cipherSuites = BSL_SAL_Dump(ciphersuites12, size); + if (config->cipherSuites == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + config->cipherSuitesSize = size / sizeof(uint16_t); + return HITLS_SUCCESS; +} + +static int32_t SetTLS13DefaultCipherSuites(HITLS_Config *config) +{ + const uint16_t ciphersuites13[] = { + HITLS_AES_256_GCM_SHA384, + HITLS_CHACHA20_POLY1305_SHA256, + HITLS_AES_128_GCM_SHA256, + }; + + config->tls13CipherSuites = BSL_SAL_Dump(ciphersuites13, sizeof(ciphersuites13)); + if (config->tls13CipherSuites == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + config->tls13cipherSuitesSize = sizeof(ciphersuites13) / sizeof(uint16_t); + return HITLS_SUCCESS; +} + +static int32_t SetDefaultPointFormats(HITLS_Config *config) +{ + const uint8_t pointFormats[] = {HITLS_POINT_FORMAT_UNCOMPRESSED}; + uint32_t size = sizeof(pointFormats); + + config->pointFormats = BSL_SAL_Dump(pointFormats, size); + if (config->pointFormats == NULL) { + return HITLS_MEMALLOC_FAIL; + } + config->pointFormatsSize = size / sizeof(uint8_t); + + return HITLS_SUCCESS; +} + +static int32_t SetDefaultGroups(HITLS_Config *config) +{ + const uint16_t groupsTls[] = { + HITLS_EC_GROUP_CURVE25519, + HITLS_EC_GROUP_SECP521R1, + HITLS_EC_GROUP_SECP384R1, + HITLS_EC_GROUP_SECP256R1, + HITLS_EC_GROUP_BRAINPOOLP512R1, + HITLS_EC_GROUP_BRAINPOOLP384R1, + HITLS_EC_GROUP_BRAINPOOLP256R1, + }; + const uint16_t groupsTlcp[] = { + HITLS_EC_GROUP_SM2, + }; + + uint32_t size = (config->maxVersion == HITLS_VERSION_TLCP11) ? sizeof(groupsTlcp) : sizeof(groupsTls); + + config->groups = BSL_SAL_Dump((config->maxVersion == HITLS_VERSION_TLCP11) ? groupsTlcp : groupsTls, size); + if (config->groups == NULL) { + return HITLS_MEMALLOC_FAIL; + } + config->groupsSize = size / sizeof(uint16_t); + + return HITLS_SUCCESS; +} + +static int32_t SetDefaultTLS13Groups(HITLS_Config *config) +{ + /* rfc8446 4.2.7 Supported Groups */ + const uint16_t groupsTls[] = { + HITLS_EC_GROUP_CURVE25519, + HITLS_EC_GROUP_SECP521R1, + HITLS_EC_GROUP_SECP384R1, + HITLS_EC_GROUP_SECP256R1, + HITLS_FF_DHE_2048, + HITLS_FF_DHE_3072, + HITLS_FF_DHE_4096, + HITLS_FF_DHE_6144, + HITLS_FF_DHE_8192, + }; + + config->groups = BSL_SAL_Dump(groupsTls, sizeof(groupsTls)); + if (config->groups == NULL) { + return HITLS_MEMALLOC_FAIL; + } + config->groupsSize = sizeof(groupsTls) / sizeof(uint16_t); + + return HITLS_SUCCESS; +} + +static int32_t SetDefaultSignHashAlg(HITLS_Config *config) +{ + uint32_t listLen = 0; +#ifndef HITLS_NO_TLCP11 + const SignSchemeInfo *signHashAlgList = (config->maxVersion != HITLS_VERSION_TLCP11) ? + CFG_GetSignSchemeList(&listLen) : + CFG_GetSignSchemeListTlcp(&listLen); +#else + const SignSchemeInfo *signHashAlgList = CFG_GetSignSchemeList(&listLen); +#endif + config->signAlgorithms = BSL_SAL_Calloc(1u, listLen * sizeof(uint16_t)); + if (config->signAlgorithms == NULL) { + return HITLS_MEMALLOC_FAIL; + } + for (uint32_t i = 0; i < listLen; i++) { + config->signAlgorithms[i] = signHashAlgList[i].scheme; + } + config->signAlgorithmsSize = listLen; + + return HITLS_SUCCESS; +} + +static int32_t SetTLS13DefaultSignScheme(HITLS_Config *config) +{ + uint32_t listSize = 0; + uint32_t validNum = 0; + const SignSchemeInfo *signHashAlgList = CFG_GetSignSchemeList(&listSize); + + config->signAlgorithms = BSL_SAL_Calloc(listSize, sizeof(uint16_t)); + if (config->signAlgorithms == NULL) { + return HITLS_MEMALLOC_FAIL; + } + for (uint32_t i = 0; i < listSize; i++) { + /* rfc8446 4.2.3 These algorithms are deprecated as of + TLS 1.3. They MUST NOT be offered or negotiated by any + implementation. In particular, MD5 [SLOTH], SHA-224, and DSA + MUST NOT be used. */ + if ((signHashAlgList[i].signAlg == HITLS_SIGN_DSA) || (signHashAlgList[i].hashAlg == HITLS_HASH_SHA1) || + (signHashAlgList[i].hashAlg == HITLS_HASH_SHA_224)) { + continue; + } + config->signAlgorithms[validNum] = signHashAlgList[i].scheme; + validNum++; + } + config->signAlgorithmsSize = validNum; + + return HITLS_SUCCESS; +} + +static void InitConfig(HITLS_Config *config) +{ + config->isSupportRenegotiation = false; + config->isResumptionOnRenego = false; + if (config->maxVersion == HITLS_VERSION_TLCP11) { + config->isSupportExtendMasterSecret = false; + config->isSupportDhAuto = false; + } else { + config->isSupportExtendMasterSecret = true; + config->isSupportDhAuto = true; + } + config->isSupportSessionTicket = true; + config->isFlightTransmitEnable = false; + config->needCheckKeyUsage = true; + config->needCheckPmsVersion = false; + + /** Set the certificate verification mode */ + config->isSupportClientVerify = false; + config->isSupportNoClientCert = false; + config->isSupportPostHandshakeAuth = false; + config->isSupportVerifyNone = false; + config->isSupportClientOnceVerify = false; + + config->isQuietShutdown = false; + + config->ticketNums = HITLS_TLS13_TICKET_NUM_DEFAULT; + + config->maxCertList = HITLS_MAX_CERT_LIST_DEFAULT; + + // Default security settings + SECURITY_SetDefault(config); +} + +static int32_t DefaultCipherSuitesByVersion(uint16_t version, HITLS_Config *config) +{ + switch (version) { +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: + return SetTLCPDefaultCipherSuites(config); +#endif + default: + break; + } + return SetTls12DefaultCipherSuites(config); +} + +int32_t DefaultConfig(uint16_t version, HITLS_Config *config) +{ + // Static settings + config->minVersion = version; + config->maxVersion = version; + + InitConfig(config); + + int32_t ret = DefaultCipherSuitesByVersion(version, config); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Configure the TLS1.3 cipher suite for all TLS versions */ + ret = SetTLS13DefaultCipherSuites(config); + if (ret != HITLS_SUCCESS) { + goto ERR; + } + + if (SetDefaultSignHashAlg(config) != HITLS_SUCCESS) { + goto ERR; + } + + if ((SetDefaultPointFormats(config) != HITLS_SUCCESS) || + (SetDefaultGroups(config) != HITLS_SUCCESS)) { + goto ERR; + } + + if (SAL_CERT_MgrIsEnable()) { + config->certMgrCtx = SAL_CERT_MgrCtxNew(); + if (config->certMgrCtx == NULL) { + goto ERR; + } + } + + config->sessMgr = SESSMGR_New(); + if (config->sessMgr == NULL) { + goto ERR; + } + return HITLS_SUCCESS; +ERR: + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; +} + +int32_t DefaultTLS13Config(HITLS_Config *config) +{ + // Static settings + config->minVersion = HITLS_VERSION_TLS13; + config->maxVersion = HITLS_VERSION_TLS13; + + InitConfig(config); + + // Dynamic setting. By default, only the cipher suite and point format are set. For details, see the comments in + // HITLS_CFG_NewDTLS12Config. + if ((SetTLS13DefaultCipherSuites(config) != HITLS_SUCCESS) || + (SetDefaultPointFormats(config) != HITLS_SUCCESS) || + (SetDefaultTLS13Groups(config) != HITLS_SUCCESS) || + (SetTLS13DefaultSignScheme(config) != HITLS_SUCCESS)) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + + config->keyExchMode = TLS13_KE_MODE_PSK_WITH_DHE; + + if (SAL_CERT_MgrIsEnable()) { + config->certMgrCtx = SAL_CERT_MgrCtxNew(); + if (config->certMgrCtx == NULL) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + } + + config->sessMgr = SESSMGR_New(); + if (config->sessMgr == NULL) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t SetDefaultTlsAllCipherSuites(HITLS_Config *config) +{ + int32_t ret; + ret = SetTLS13DefaultCipherSuites(config); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SetTls12DefaultCipherSuites(config); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t DefaultTlsAllConfig(HITLS_Config *config) +{ + // Support full version + config->minVersion = HITLS_VERSION_TLS12; + config->maxVersion = HITLS_VERSION_TLS13; + + InitConfig(config); + + // Dynamic setting + if ((SetDefaultTlsAllCipherSuites(config) != HITLS_SUCCESS) || + (SetDefaultPointFormats(config) != HITLS_SUCCESS) || + (SetDefaultGroups(config) != HITLS_SUCCESS) || + (SetDefaultSignHashAlg(config) != HITLS_SUCCESS)) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + + config->keyExchMode = TLS13_KE_MODE_PSK_WITH_DHE; + + if (SAL_CERT_MgrIsEnable()) { + config->certMgrCtx = SAL_CERT_MgrCtxNew(); + if (config->certMgrCtx == NULL) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + } + + config->sessMgr = SESSMGR_New(); + if (config->sessMgr == NULL) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t SetDefaultDtlsAllCipherSuites(HITLS_Config *config) +{ + const uint16_t cipherSuites[] = { + /* DTLS1.2 */ + HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_DHE_DSS_WITH_AES_256_GCM_SHA384, HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + HITLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + HITLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, HITLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + + /* The DTLS1.0 cipher suite is not supported */ + }; + uint32_t size = sizeof(cipherSuites); + + config->cipherSuites = BSL_SAL_Dump(cipherSuites, size); + if (config->cipherSuites == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + config->cipherSuitesSize = size / sizeof(uint16_t); + return HITLS_SUCCESS; +} + +int32_t DefaultDtlsAllConfig(HITLS_Config *config) +{ + // Static settings + config->minVersion = + HITLS_VERSION_DTLS12; // does not support DTLS 1.0. Therefore, the minimum version number is set to DTLS 1.2. + config->maxVersion = HITLS_VERSION_DTLS12; + + InitConfig(config); + + // Dynamic setting + if ((SetDefaultDtlsAllCipherSuites(config) != HITLS_SUCCESS) || + (SetDefaultPointFormats(config) != HITLS_SUCCESS) || + (SetDefaultGroups(config) != HITLS_SUCCESS) || + (SetDefaultSignHashAlg(config) != HITLS_SUCCESS)) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + + if (SAL_CERT_MgrIsEnable()) { + config->certMgrCtx = SAL_CERT_MgrCtxNew(); + if (config->certMgrCtx == NULL) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + } + + config->sessMgr = SESSMGR_New(); + if (config->sessMgr == NULL) { + CFG_CleanConfig(config); + return HITLS_MEMALLOC_FAIL; + } + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/config/src/config_default.h b/tls/config/src/config_default.h new file mode 100644 index 00000000..1ecd3b52 --- /dev/null +++ b/tls/config/src/config_default.h @@ -0,0 +1,39 @@ +/* + * 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 CONFIG_DEFAULT_H +#define CONFIG_DEFAULT_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* provide default configuration */ +int32_t DefaultTlsAllConfig(HITLS_Config *config); + +int32_t DefaultDtlsAllConfig(HITLS_Config *config); + +int32_t DefaultConfig(uint16_t version, HITLS_Config *config); + +int32_t DefaultTLS13Config(HITLS_Config *config); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/crypt/crypt_adapt/crypt.c b/tls/crypt/crypt_adapt/crypt.c new file mode 100644 index 00000000..9da08d36 --- /dev/null +++ b/tls/crypt/crypt_adapt/crypt.c @@ -0,0 +1,850 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_crypt_reg.h" +#include "crypt.h" + +#define TLS13_MAX_LABEL_LEN 255 +#define TLS13_MAX_CTX_LEN 255 + +#define TLS13_HKDF_LABEL_LEN(labelLen, ctxLen) \ + (sizeof(uint16_t) + sizeof(uint8_t) + (labelLen) + sizeof(uint8_t) + (ctxLen)) + +#define TLS13_MAX_HKDF_LABEL_LEN TLS13_HKDF_LABEL_LEN(TLS13_MAX_LABEL_LEN, TLS13_MAX_CTX_LEN) + +HITLS_CRYPT_BaseMethod g_cryptBaseMethod = {0}; +HITLS_CRYPT_EcdhMethod g_cryptEcdhMethod = {0}; +HITLS_CRYPT_DhMethod g_cryptDhMethod = {0}; +HITLS_CRYPT_KdfMethod g_cryptKdfMethod = {0}; + +typedef struct { + uint16_t length; /* Length of the derived key */ + uint8_t labelLen; /* Label length */ + uint8_t ctxLen; /* Length of the context information */ + const uint8_t *label; /* Label */ + const uint8_t *ctx; /* Context information */ +} HkdfLabel; + +int32_t HITLS_CRYPT_RegisterBaseMethod(HITLS_CRYPT_BaseMethod *userCryptCallBack) +{ + if (userCryptCallBack == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15063, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Register base crypt method error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + g_cryptBaseMethod.randBytes = userCryptCallBack->randBytes; + g_cryptBaseMethod.hmacSize = userCryptCallBack->hmacSize; + g_cryptBaseMethod.hmacInit = userCryptCallBack->hmacInit; + g_cryptBaseMethod.hmacFree = userCryptCallBack->hmacFree; + g_cryptBaseMethod.hmacUpdate = userCryptCallBack->hmacUpdate; + g_cryptBaseMethod.hmacFinal = userCryptCallBack->hmacFinal; + g_cryptBaseMethod.hmac = userCryptCallBack->hmac; + g_cryptBaseMethod.digestSize = userCryptCallBack->digestSize; + g_cryptBaseMethod.digestInit = userCryptCallBack->digestInit; + g_cryptBaseMethod.digestCopy = userCryptCallBack->digestCopy; + g_cryptBaseMethod.digestFree = userCryptCallBack->digestFree; + g_cryptBaseMethod.digestUpdate = userCryptCallBack->digestUpdate; + g_cryptBaseMethod.digestFinal = userCryptCallBack->digestFinal; + g_cryptBaseMethod.digest = userCryptCallBack->digest; + g_cryptBaseMethod.encrypt = userCryptCallBack->encrypt; + g_cryptBaseMethod.decrypt = userCryptCallBack->decrypt; + return HITLS_SUCCESS; +} + +int32_t HITLS_CRYPT_RegisterEcdhMethod(HITLS_CRYPT_EcdhMethod *userCryptCallBack) +{ + if (userCryptCallBack == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15064, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Register ECDH crypt method error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + g_cryptEcdhMethod.generateEcdhKeyPair = userCryptCallBack->generateEcdhKeyPair; + g_cryptEcdhMethod.dupEcdhKey = userCryptCallBack->dupEcdhKey; + g_cryptEcdhMethod.freeEcdhKey = userCryptCallBack->freeEcdhKey; + g_cryptEcdhMethod.getEcdhPubKey = userCryptCallBack->getEcdhPubKey; + g_cryptEcdhMethod.calcEcdhSharedSecret = userCryptCallBack->calcEcdhSharedSecret; + g_cryptEcdhMethod.sm2CalEcdhSharedSecret = userCryptCallBack->sm2CalEcdhSharedSecret; + return HITLS_SUCCESS; +} + +int32_t HITLS_CRYPT_RegisterDhMethod(const HITLS_CRYPT_DhMethod *userCryptCallBack) +{ + if (userCryptCallBack == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Register Dh crypt method error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + g_cryptDhMethod.getDhParameters = userCryptCallBack->getDhParameters; + g_cryptDhMethod.generateDhKeyBySecbits = userCryptCallBack->generateDhKeyBySecbits; + g_cryptDhMethod.generateDhKeyByParams = userCryptCallBack->generateDhKeyByParams; + g_cryptDhMethod.freeDhKey = userCryptCallBack->freeDhKey; + g_cryptDhMethod.getDhPubKey = userCryptCallBack->getDhPubKey; + g_cryptDhMethod.calcDhSharedSecret = userCryptCallBack->calcDhSharedSecret; + g_cryptDhMethod.dupDhKey = userCryptCallBack->dupDhKey; + return HITLS_SUCCESS; +} + +int32_t HITLS_CRYPT_RegisterHkdfMethod(HITLS_CRYPT_KdfMethod *userCryptCallBack) +{ + if (userCryptCallBack == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15066, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Register HKDF crypt method error: input NULL.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + g_cryptKdfMethod.hkdfExtract = userCryptCallBack->hkdfExtract; + g_cryptKdfMethod.hkdfExpand = userCryptCallBack->hkdfExpand; + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_Rand(uint8_t *buf, uint32_t len) +{ + if (g_cryptBaseMethod.randBytes == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15067, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate %u bytes random error: callback unregistered.", len, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + int32_t ret = g_cryptBaseMethod.randBytes(buf, len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15068, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate %u bytes random error: callback ret = 0x%x.", len, ret, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_GENERATE_RANDOM); + return HITLS_CRYPT_ERR_GENERATE_RANDOM; + } + return HITLS_SUCCESS; +} + +uint32_t SAL_CRYPT_HmacSize(HITLS_HashAlgo hashAlgo) +{ + if (g_cryptBaseMethod.hmacSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15069, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac size error: callback unregistered.", 0, 0, 0, 0); + return 0; + } + return g_cryptBaseMethod.hmacSize(hashAlgo); +} + +HITLS_HMAC_Ctx *SAL_CRYPT_HmacInit(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len) +{ + if (g_cryptBaseMethod.hmacInit == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15070, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac init error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + + return g_cryptBaseMethod.hmacInit(hashAlgo, key, len); +} + +void SAL_CRYPT_HmacFree(HITLS_HMAC_Ctx *hmac) +{ + if (g_cryptBaseMethod.hmacFree == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15071, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac free error: callback unregistered.", 0, 0, 0, 0); + return; + } + if (hmac != NULL) { + g_cryptBaseMethod.hmacFree(hmac); + } + return; +} + +int32_t SAL_CRYPT_HmacUpdate(HITLS_HMAC_Ctx *hmac, const uint8_t *data, uint32_t len) +{ + if (g_cryptBaseMethod.hmacUpdate == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15072, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac update error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.hmacUpdate(hmac, data, len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15073, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac update error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HMAC); + return HITLS_CRYPT_ERR_HMAC; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_HmacFinal(HITLS_HMAC_Ctx *hmac, uint8_t *out, uint32_t *len) +{ + if (g_cryptBaseMethod.hmacFinal == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15074, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac final error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.hmacFinal(hmac, out, len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15075, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac final error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HMAC); + return HITLS_CRYPT_ERR_HMAC; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_Hmac(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen, + const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ + if (g_cryptBaseMethod.hmac == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15076, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.hmac(hashAlgo, key, keyLen, in, inLen, out, outLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15077, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hmac error: callback ret = 0x%x, hashAlgo = %u, keyLen = %u, inLen = %u, .", + ret, hashAlgo, keyLen, inLen); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15207, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "outLen = %u", *outLen, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HMAC); + return HITLS_CRYPT_ERR_HMAC; + } + return HITLS_SUCCESS; +} + +static int32_t IteratorInit(CRYPT_KeyDeriveParameters *input, uint32_t hmacSize, + uint8_t **iterator, uint32_t *iteratorSize) +{ + uint8_t *seed = BSL_SAL_Calloc(1u, hmacSize + input->labelLen + input->seedLen); + if (seed == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15078, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "P_Hash error: malloc seed failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + (void)memcpy_s(&seed[hmacSize], input->labelLen, input->label, input->labelLen); + (void)memcpy_s(&seed[hmacSize + input->labelLen], input->seedLen, input->seed, input->seedLen); + + int32_t ret = SAL_CRYPT_Hmac(input->hashAlgo, input->secret, input->secretLen, + &seed[hmacSize], input->labelLen + input->seedLen, seed, &hmacSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15079, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "P_Hash error: iterator init fail, HMAC ret = 0x%x.", ret, 0, 0, 0); + BSL_SAL_FREE(seed); + return ret; + } + *iterator = seed; + *iteratorSize = hmacSize + input->labelLen + input->seedLen; + return HITLS_SUCCESS; +} + +static int32_t PHashPre(uint32_t *hmacSize, uint32_t *alignLen, uint32_t outLen, HITLS_HashAlgo hashAlgo) +{ + if (hmacSize == NULL || alignLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + *alignLen = outLen; + *hmacSize = SAL_CRYPT_HmacSize(hashAlgo); + if (*hmacSize == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15080, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "P_Hash error: hmac size is zero.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HMAC); + return HITLS_CRYPT_ERR_HMAC; + } + if ((outLen % *hmacSize) != 0) { + /* Padded based on the HMAC length. */ + *alignLen += *hmacSize - (outLen % *hmacSize); + } + return HITLS_SUCCESS; +} + +int32_t P_Hash(CRYPT_KeyDeriveParameters *input, uint8_t *out, uint32_t outLen) +{ + uint8_t *iterator = NULL; + uint32_t iteratorSize = 0; + uint8_t *data = NULL; + uint32_t alignLen; + uint32_t srcLen = outLen; + uint32_t offset = 0; + uint32_t hmacSize; + int32_t ret = PHashPre(&hmacSize, &alignLen, outLen, input->hashAlgo); + if (ret != HITLS_SUCCESS) { + return ret; + } + data = BSL_SAL_Calloc(1u, alignLen); + if (data == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15081, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "P_Hash error: malloc data failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + uint32_t tmpLen = hmacSize; + ret = IteratorInit(input, hmacSize, &iterator, &iteratorSize); + if (ret != HITLS_SUCCESS) { + goto PHASH_END; + } + + while (alignLen > 0) { + ret = SAL_CRYPT_Hmac(input->hashAlgo, input->secret, input->secretLen, + iterator, iteratorSize, data + offset, &tmpLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15082, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "P_Hash error: produce output data fail, HMAC ret = 0x%x.", ret, 0, 0, 0); + goto PHASH_END; + } + + alignLen -= tmpLen; + offset += tmpLen; + + ret = SAL_CRYPT_Hmac(input->hashAlgo, input->secret, input->secretLen, iterator, tmpLen, iterator, &tmpLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15083, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "P_Hash error: iterator update fail, HMAC ret = 0x%x.", ret, 0, 0, 0); + goto PHASH_END; + } + } + + if (memcpy_s(out, outLen, data, srcLen) != EOK) { + ret = HITLS_MEMCPY_FAIL; + } +PHASH_END: + BSL_SAL_FREE(iterator); + BSL_SAL_FREE(data); + return ret; +} + +int32_t PRF_MD5_SHA1(CRYPT_KeyDeriveParameters *input, uint8_t *out, uint32_t outLen) +{ + uint32_t secretLen = input->secretLen; + const uint8_t *secret = input->secret; + int32_t ret; + uint32_t i; + + /* The key is divided into two parts. The first part is the MD5 key, and the second part is the SHA1 key. + If the value is an odd number, for example, 7, the first half of the key is [1, 4] + and the second half of the key is [4, 7]. Both keys have the fourth byte. */ + input->secretLen = ((secretLen + 1) >> 1); + input->hashAlgo = HITLS_HASH_MD5; + ret = P_Hash(input, out, outLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t *sha1data = BSL_SAL_Calloc(1u, outLen); + if (sha1data == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15084, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "PRF_MD5_SHA1 error: malloc sha1data failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + input->secret += (secretLen >> 1); + input->hashAlgo = HITLS_HASH_SHA1; + ret = P_Hash(input, sha1data, outLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(sha1data); + return ret; + } + + for (i = 0; i < outLen; i++) { + out[i] ^= sha1data[i]; + } + + input->secret = secret; + input->secretLen = secretLen; + + BSL_SAL_FREE(sha1data); + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_PRF(CRYPT_KeyDeriveParameters *input, uint8_t *out, uint32_t outLen) +{ + // TLS1.0, TLS1.1 + if (input->hashAlgo == HITLS_HASH_MD5_SHA1) { + return PRF_MD5_SHA1(input, out, outLen); + } + + // Other versions + if (input->hashAlgo < HITLS_HASH_SHA_256) { + /* The PRF function must use the digest algorithm with SHA-256 or higher strength. */ + input->hashAlgo = HITLS_HASH_SHA_256; + } + + return P_Hash(input, out, outLen); +} + +uint32_t SAL_CRYPT_DigestSize(HITLS_HashAlgo hashAlgo) +{ + if (g_cryptBaseMethod.digestSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15085, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest size error: callback unregistered.", 0, 0, 0, 0); + return 0; + } + return g_cryptBaseMethod.digestSize(hashAlgo); +} + +HITLS_HASH_Ctx *SAL_CRYPT_DigestInit(HITLS_HashAlgo hashAlgo) +{ + if (g_cryptBaseMethod.digestInit == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15086, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest init error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptBaseMethod.digestInit(hashAlgo); +} + +HITLS_HASH_Ctx *SAL_CRYPT_DigestCopy(HITLS_HASH_Ctx *ctx) +{ + if (g_cryptBaseMethod.digestCopy == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15087, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest copy error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptBaseMethod.digestCopy(ctx); +} + +void SAL_CRYPT_DigestFree(HITLS_HASH_Ctx *ctx) +{ + if (g_cryptBaseMethod.digestFree == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15088, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest free error: callback unregistered.", 0, 0, 0, 0); + return; + } + if (ctx != NULL) { + g_cryptBaseMethod.digestFree(ctx); + } + return; +} + +int32_t SAL_CRYPT_DigestUpdate(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len) +{ + if (g_cryptBaseMethod.digestUpdate == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15089, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest update error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.digestUpdate(ctx, data, len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15090, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest update error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + return HITLS_CRYPT_ERR_DIGEST; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_DigestFinal(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len) +{ + if (g_cryptBaseMethod.digestFinal == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15091, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest final error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.digestFinal(ctx, out, len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15092, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest final error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + return HITLS_CRYPT_ERR_DIGEST; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_Digest(HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ + if (g_cryptBaseMethod.digest == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15093, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.digest(hashAlgo, in, inLen, out, outLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15094, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "digest error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + return HITLS_CRYPT_ERR_DIGEST; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_Encrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + if (g_cryptBaseMethod.encrypt == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15095, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encrypt error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.encrypt(cipher, in, inLen, out, outLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15096, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encrypt error: cipher type = %u, algo = %u, keyLen = %u, ivLen = %u", + cipher->type, cipher->algo, cipher->keyLen, cipher->ivLen); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15208, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "aadLen = %u, inTextLen = %u, outTextLen = %u.", cipher->aadLen, inLen, *outLen, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCRYPT); + return HITLS_CRYPT_ERR_ENCRYPT; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_Decrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + if (g_cryptBaseMethod.decrypt == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15097, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decrypt error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptBaseMethod.decrypt(cipher, in, inLen, out, outLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15098, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decrypt error: cipher type = %u, algo = %u, keyLen = %u, ivLen = %u", + cipher->type, cipher->algo, cipher->keyLen, cipher->ivLen); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15209, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "aadLen = %u, inTextLen = %u, outTextLen = %u.", cipher->aadLen, inLen, *outLen, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DECRYPT); + return HITLS_CRYPT_ERR_DECRYPT; + } + return HITLS_SUCCESS; +} + +HITLS_CRYPT_Key *SAL_CRYPT_GenEcdhKeyPair(const HITLS_ECParameters *curveParams) +{ + if (g_cryptEcdhMethod.generateEcdhKeyPair == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15099, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate ecdh key error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptEcdhMethod.generateEcdhKeyPair(curveParams); +} + +HITLS_CRYPT_Key *SAL_CRYPT_DupEcdhKey(HITLS_CRYPT_Key *key) +{ + if (g_cryptEcdhMethod.dupEcdhKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16011, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup ecdh key error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptEcdhMethod.dupEcdhKey(key); +} + +void SAL_CRYPT_FreeEcdhKey(HITLS_CRYPT_Key *key) +{ + if (g_cryptEcdhMethod.freeEcdhKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15100, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "free ecdh key error: callback unregistered.", 0, 0, 0, 0); + return; + } + if (key != NULL) { + g_cryptEcdhMethod.freeEcdhKey(key); + } + return; +} + +int32_t SAL_CRYPT_EncodeEcdhPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen) +{ + if (g_cryptEcdhMethod.getEcdhPubKey == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15101, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get ecdh public key error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptEcdhMethod.getEcdhPubKey(key, pubKeyBuf, bufLen, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15102, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get ecdh public key error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_CalcEcdhSharedSecret(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen) +{ + if (g_cryptEcdhMethod.calcEcdhSharedSecret == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15103, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calculate ecdh shared secret error: callback unregistered.", 0, 0, 0, 0); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptEcdhMethod.calcEcdhSharedSecret(key, peerPubkey, pubKeyLen, sharedSecret, sharedSecretLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15104, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calculate ecdh shared secret error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_CALC_SHARED_KEY); + return HITLS_CRYPT_ERR_CALC_SHARED_KEY; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_CalcSm2dhSharedSecret(HITLS_Sm2GenShareKeyParameters *sm2ShareKeyParam, uint8_t *sharedSecret, + uint32_t *sharedSecretLen) +{ + if (g_cryptEcdhMethod.sm2CalEcdhSharedSecret == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15241, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sm2 ecdh public key error: callback unregistered", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptEcdhMethod.sm2CalEcdhSharedSecret(sm2ShareKeyParam, sharedSecret, sharedSecretLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15242, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sm2 ecdh public key error: callback ret = 0x%x", (uint32_t)ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + return HITLS_SUCCESS; +} + +HITLS_CRYPT_Key *SAL_CRYPT_GenerateDhKeyByParams(uint8_t *p, uint16_t plen, uint8_t *g, uint16_t glen) +{ + if (g_cryptDhMethod.generateDhKeyByParams == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15105, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate Dh key error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptDhMethod.generateDhKeyByParams(p, plen, g, glen); +} + +HITLS_CRYPT_Key *SAL_CRYPT_GenerateDhKeyBySecbits(int32_t secbits) +{ + if (g_cryptDhMethod.generateDhKeyBySecbits == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15106, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate Dh key error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptDhMethod.generateDhKeyBySecbits(secbits); +} + +HITLS_CRYPT_Key *SAL_CRYPT_DupDhKey(HITLS_CRYPT_Key *key) +{ + if (g_cryptDhMethod.dupDhKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16010, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dup Dh key error: callback unregistered.", 0, 0, 0, 0); + return NULL; + } + return g_cryptDhMethod.dupDhKey(key); +} + +void SAL_CRYPT_FreeDhKey(HITLS_CRYPT_Key *key) +{ + if (g_cryptDhMethod.freeDhKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15107, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "free Dh key error: callback unregistered.", 0, 0, 0, 0); + return; + } + if (key != NULL) { + g_cryptDhMethod.freeDhKey(key); + } + return; +} + +int32_t SAL_CRYPT_GetDhParameters(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *plen, uint8_t *g, uint16_t *glen) +{ + if (g_cryptDhMethod.getDhParameters == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15108, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh params error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + return g_cryptDhMethod.getDhParameters(key, p, plen, g, glen); +} + +int32_t SAL_CRYPT_EncodeDhPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen) +{ + if (g_cryptDhMethod.getDhPubKey == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15109, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh public key error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptDhMethod.getDhPubKey(key, pubKeyBuf, bufLen, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15110, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh public key error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_DH_KEY); + return HITLS_CRYPT_ERR_ENCODE_DH_KEY; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_CalcDhSharedSecret(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen) +{ + if (g_cryptDhMethod.calcDhSharedSecret == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15111, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calculate dh shared secret error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptDhMethod.calcDhSharedSecret(key, peerPubkey, pubKeyLen, sharedSecret, sharedSecretLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15112, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calculate dh shared secret error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_CALC_SHARED_KEY); + return HITLS_CRYPT_ERR_CALC_SHARED_KEY; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_HkdfExtract(HITLS_CRYPT_HkdfExtractInput *input, uint8_t *prk, uint32_t *prkLen) +{ + if (g_cryptKdfMethod.hkdfExtract == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15113, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HKDF-Extract error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptKdfMethod.hkdfExtract(input, prk, prkLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15114, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HKDF-Extract error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HKDF_EXTRACT); + return HITLS_CRYPT_ERR_HKDF_EXTRACT; + } + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_HkdfExpand(HITLS_CRYPT_HkdfExpandInput *input, uint8_t *okm, uint32_t okmLen) +{ + if (g_cryptKdfMethod.hkdfExpand == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15115, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HKDF-Expand error: callback unregistered.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + int32_t ret = g_cryptKdfMethod.hkdfExpand(input, okm, okmLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15116, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HKDF-Expand error: callback ret = 0x%x.", ret, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HKDF_EXPAND); + return HITLS_CRYPT_ERR_HKDF_EXPAND; + } + return HITLS_SUCCESS; +} + +/** + * 2 bytes for length of derived secret + 1 byte for length of combined + * prefix and label + bytes for the label itself + 1 byte length of hash + * + bytes for the hash itself + */ +static int32_t SAL_CRYPT_EncodeHkdfLabel(HkdfLabel *hkdfLabel, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + char labelPrefix[] = "tls13 "; + size_t labelPrefixLen = strlen(labelPrefix); + uint32_t offset = 0; + + BSL_Uint16ToByte(hkdfLabel->length, buf); + offset += sizeof(uint16_t); + + /* The truncation won't happen, as the label length will not be greater than 64, all possible labels are as follows: + * "ext binder", "res binder", "finished", "c e traffic", "e exp master", "derived", "c hs traffic", "s hs traffic" + * "finished", "derived", "c ap traffic", "s ap traffic", "exp master", "finished", "res master", + * "TLS 1.3,serverCertificateVerify", "TLS 1.3,clientCertificateVerify". + */ + buf[offset] = hkdfLabel->labelLen + (uint8_t)labelPrefixLen; + offset += sizeof(uint8_t); + + if (memcpy_s(&buf[offset], bufLen - offset, labelPrefix, labelPrefixLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15117, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Encode HkdfLabel error: memcpy fail", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + offset += (uint32_t)labelPrefixLen; + if (hkdfLabel->labelLen != 0 && + memcpy_s(&buf[offset], bufLen - offset, hkdfLabel->label, hkdfLabel->labelLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15118, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Encode HkdfLabel error: memcpy fail", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + offset += hkdfLabel->labelLen; + + buf[offset] = hkdfLabel->ctxLen; + offset += sizeof(uint8_t); + if (hkdfLabel->ctxLen != 0) { + if (memcpy_s(&buf[offset], bufLen - offset, hkdfLabel->ctx, hkdfLabel->ctxLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15119, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Encode HkdfLabel error: memcpy fail", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + offset += hkdfLabel->ctxLen; + } + *usedLen = offset; + return HITLS_SUCCESS; +} + +int32_t SAL_CRYPT_HkdfExpandLabel(CRYPT_KeyDeriveParameters *deriveInfo, uint8_t *outSecret, uint32_t outLen) +{ + uint8_t hkdfLabel[TLS13_MAX_HKDF_LABEL_LEN] = {0}; + uint32_t hkdfLabelLen = 0; + + HkdfLabel info = {0}; + info.length = (uint16_t)outLen; + info.labelLen = (uint8_t)deriveInfo->labelLen; + info.ctxLen = (uint8_t)deriveInfo->seedLen; + info.label = deriveInfo->label; + info.ctx = deriveInfo->seed; + int32_t ret = SAL_CRYPT_EncodeHkdfLabel(&info, hkdfLabel, TLS13_MAX_HKDF_LABEL_LEN, &hkdfLabelLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + HITLS_CRYPT_HkdfExpandInput expandInput = {0}; + expandInput.hashAlgo = deriveInfo->hashAlgo; + expandInput.prk = deriveInfo->secret; + expandInput.prkLen = deriveInfo->secretLen; + expandInput.info = hkdfLabel; + expandInput.infoLen = hkdfLabelLen; + ret = SAL_CRYPT_HkdfExpand(&expandInput, outSecret, outLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} diff --git a/tls/crypt/crypt_self/crypt_default.c b/tls/crypt/crypt_self/crypt_default.c new file mode 100644 index 00000000..66475e29 --- /dev/null +++ b/tls/crypt/crypt_self/crypt_default.c @@ -0,0 +1,1185 @@ +/* + * 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 +#include "securec.h" +#include "bsl_log_internal.h" +#include "bsl_err_internal.h" +#include "crypt_algid.h" +#include "hitls_crypt_type.h" +#include "crypt_eal_rand.h" +#include "crypt_eal_md.h" +#include "crypt_eal_mac.h" +#include "crypt_eal_cipher.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_kdf.h" +#include "crypt_errno.h" +#include "hitls_error.h" +#include "hitls_build.h" + +#ifndef HITLS_CRYPTO_EAL +#error "Missing definition of HITLS_CRYPTO_EAL" +#endif + +#define MIN_DH8192_SECBITS 192 +#define MIN_DH4096_SECBITS 152 +#define MIN_DH3072_SECBITS 128 +#define MIN_DH2048_SECBITS 112 + +#define MAX_PKEY_PARA_LEN 1024 + +#define CCM_TLS_TAG_LEN 16u +#define CCM8_TLS_TAG_LEN 8u + +/* The default user id as specified in GM/T 0009-2012 */ +char g_SM2DefaultUserid[] = "1234567812345678"; +#define SM2_DEFAULT_USERID_LEN 16u +#define SM2_PUBKEY_LEN 65 +#define SM2_PRVKEY_LEN 33 + +#ifdef HITLS_CRYPTO_MD +static uint32_t GetMDAlgId(HITLS_HashAlgo hashAlgo) +{ + switch (hashAlgo) { + case HITLS_HASH_MD5: + return CRYPT_MD_MD5; + case HITLS_HASH_SHA1: + return CRYPT_MD_SHA1; + case HITLS_HASH_SHA_224: + return CRYPT_MD_SHA224; + case HITLS_HASH_SHA_256: + return CRYPT_MD_SHA256; + case HITLS_HASH_SHA_384: + return CRYPT_MD_SHA384; + case HITLS_HASH_SHA_512: + return CRYPT_MD_SHA512; + case HITLS_HASH_SM3: + return CRYPT_MD_SM3; + default: + break; + } + return CRYPT_MD_MAX; +} +#endif + +#ifdef HITLS_CRYPTO_MAC +static uint32_t GetHmacAlgId(HITLS_HashAlgo hashAlgo) +{ + switch (hashAlgo) { + case HITLS_HASH_MD5: + return CRYPT_MAC_HMAC_MD5; + case HITLS_HASH_SHA1: + return CRYPT_MAC_HMAC_SHA1; + case HITLS_HASH_SHA_224: + return CRYPT_MAC_HMAC_SHA224; + case HITLS_HASH_SHA_256: + return CRYPT_MAC_HMAC_SHA256; + case HITLS_HASH_SHA_384: + return CRYPT_MAC_HMAC_SHA384; + case HITLS_HASH_SHA_512: + return CRYPT_MAC_HMAC_SHA512; + case HITLS_HASH_SM3: + return CRYPT_MAC_HMAC_SM3; + default: + break; + } + return CRYPT_MAC_MAX; +} +#endif + +#ifdef HITLS_CRYPTO_CIPHER +static uint32_t GetCipherAlgId(HITLS_CipherAlgo cipherAlgo) +{ + switch (cipherAlgo) { + case HITLS_CIPHER_AES_128_CBC: + return CRYPT_CIPHER_AES128_CBC; + case HITLS_CIPHER_AES_256_CBC: + return CRYPT_CIPHER_AES256_CBC; + case HITLS_CIPHER_AES_128_GCM: + return CRYPT_CIPHER_AES128_GCM; + case HITLS_CIPHER_AES_256_GCM: + return CRYPT_CIPHER_AES256_GCM; + case HITLS_CIPHER_CHACHA20_POLY1305: + return CRYPT_CIPHER_CHACHA20_POLY1305; + case HITLS_CIPHER_AES_128_CCM: + case HITLS_CIPHER_AES_128_CCM8: + return CRYPT_CIPHER_AES128_CCM; + case HITLS_CIPHER_AES_256_CCM: + case HITLS_CIPHER_AES_256_CCM8: + return CRYPT_CIPHER_AES256_CCM; + case HITLS_CIPHER_SM4_CBC: + return CRYPT_CIPHER_SM4_CBC; + default: + break; + } + return CRYPT_CIPHER_MAX; +} +#endif + +int32_t CRYPT_DEFAULT_RandomBytes(uint8_t *buf, uint32_t len) +{ +#ifdef HITLS_CRYPTO_DRBG + return CRYPT_EAL_Randbytes(buf, len); +#else + (void)buf; + (void)len; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +uint32_t CRYPT_DEFAULT_HMAC_Size(HITLS_HashAlgo hashAlgo) +{ +#ifdef HITLS_CRYPTO_MD + CRYPT_MD_AlgId id = GetMDAlgId(hashAlgo); + if (id == CRYPT_MD_MAX) { + return 0; + } + return CRYPT_EAL_MdGetDigestSize(id); +#else + (void)hashAlgo; + return 0; +#endif +} + +HITLS_HMAC_Ctx *CRYPT_DEFAULT_HMAC_Init(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len) +{ +#ifdef HITLS_CRYPTO_MAC + CRYPT_MAC_AlgId id = GetHmacAlgId(hashAlgo); + if (id == CRYPT_MAC_MAX) { + return NULL; + } + + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(id); + if (ctx == NULL) { + return NULL; + } + + int32_t ret = CRYPT_EAL_MacInit(ctx, key, len); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MacFreeCtx(ctx); + return NULL; + } + + return ctx; +#else + (void)hashAlgo; + (void)key; + (void)len; + return NULL; +#endif +} + +void CRYPT_DEFAULT_HMAC_Free(HITLS_HMAC_Ctx *ctx) +{ +#ifdef HITLS_CRYPTO_MAC + CRYPT_EAL_MacFreeCtx(ctx); +#else + (void)ctx; +#endif + return; +} + +int32_t CRYPT_DEFAULT_HMAC_Update(HITLS_HMAC_Ctx *ctx, const uint8_t *data, uint32_t len) +{ +#ifdef HITLS_CRYPTO_MAC + return CRYPT_EAL_MacUpdate(ctx, (uint8_t *)data, len); +#else + (void)ctx; + (void)data; + (void)len; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_HMAC_Final(HITLS_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len) +{ +#ifdef HITLS_CRYPTO_MAC + return CRYPT_EAL_MacFinal(ctx, out, len); +#else + (void)ctx; + (void)out; + (void)len; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_HMAC(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen, + const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ +#ifdef HITLS_CRYPTO_MAC + int32_t ret; + CRYPT_MAC_AlgId id = GetHmacAlgId(hashAlgo); + if (id == CRYPT_MAC_MAX) { + return HITLS_CRYPT_ERR_HMAC; + } + + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(id); + if (ctx == NULL) { + return HITLS_CRYPT_ERR_HMAC; + } + + ret = CRYPT_EAL_MacInit(ctx, key, keyLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MacFreeCtx(ctx); + return ret; + } + + ret = CRYPT_EAL_MacUpdate(ctx, (uint8_t *)in, inLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + CRYPT_EAL_MacFreeCtx(ctx); + return ret; + } + + ret = CRYPT_EAL_MacFinal(ctx, out, outLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + CRYPT_EAL_MacFreeCtx(ctx); + return ret; + } + + CRYPT_EAL_MacFreeCtx(ctx); + return HITLS_SUCCESS; +#else + (void)hashAlgo; + (void)key; + (void)keyLen; + (void)in; + (void)inLen; + (void)out; + (void)outLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +uint32_t CRYPT_DEFAULT_DigestSize(HITLS_HashAlgo hashAlgo) +{ +#ifdef HITLS_CRYPTO_MD + CRYPT_MD_AlgId id = GetMDAlgId(hashAlgo); + if (id == CRYPT_MD_MAX) { + return 0; + } + + return CRYPT_EAL_MdGetDigestSize(id); +#else + (void)hashAlgo; + return 0; +#endif +} + +HITLS_HASH_Ctx *CRYPT_DEFAULT_DigestInit(HITLS_HashAlgo hashAlgo) +{ +#ifdef HITLS_CRYPTO_MD + CRYPT_MD_AlgId id = GetMDAlgId(hashAlgo); + if (id == CRYPT_MD_MAX) { + return NULL; + } + + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + if (ctx == NULL) { + return NULL; + } + + int32_t ret = CRYPT_EAL_MdInit(ctx); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MdFreeCtx(ctx); + return NULL; + } + + return ctx; +#else + (void)hashAlgo; + return NULL; +#endif +} + +HITLS_HASH_Ctx *CRYPT_DEFAULT_DigestCopy(HITLS_HASH_Ctx *ctx) +{ +#ifdef HITLS_CRYPTO_MD + return CRYPT_EAL_MdDupCtx(ctx); +#else + (void)ctx; + return NULL; +#endif +} + +void CRYPT_DEFAULT_DigestFree(HITLS_HASH_Ctx *ctx) +{ +#ifdef HITLS_CRYPTO_MD + CRYPT_EAL_MdFreeCtx(ctx); +#else + (void)ctx; +#endif + return; +} + +int32_t CRYPT_DEFAULT_DigestUpdate(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len) +{ +#ifdef HITLS_CRYPTO_MD + return CRYPT_EAL_MdUpdate(ctx, data, len); +#else + (void)ctx; + (void)data; + (void)len; + return NULL; +#endif +} + +int32_t CRYPT_DEFAULT_DigestFinal(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len) +{ +#ifdef HITLS_CRYPTO_MD + return CRYPT_EAL_MdFinal(ctx, out, len); +#else + (void)ctx; + (void)out; + (void)len; + return NULL; +#endif +} + +int32_t CRYPT_DEFAULT_Digest(HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ +#ifdef HITLS_CRYPTO_MD + int32_t ret; + CRYPT_MD_AlgId id = GetMDAlgId(hashAlgo); + if (id == CRYPT_MD_MAX) { + return HITLS_CRYPT_ERR_DIGEST; + } + + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(id); + if (ctx == NULL) { + return HITLS_CRYPT_ERR_DIGEST; + } + + ret = CRYPT_EAL_MdInit(ctx); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MdFreeCtx(ctx); + return ret; + } + + ret = CRYPT_EAL_MdUpdate(ctx, in, inLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MdFreeCtx(ctx); + return ret; + } + + ret = CRYPT_EAL_MdFinal(ctx, out, outLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_MdFreeCtx(ctx); + return ret; + } + + CRYPT_EAL_MdFreeCtx(ctx); + return HITLS_SUCCESS; +#else + (void)hashAlgo; + (void)in; + (void)inLen; + (void)out; + (void)outLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +static int32_t SpecialModeEncryptPreSolve(CRYPT_EAL_CipherCtx *ctx, const HITLS_CipherParameters *cipher, + uint64_t inLen) +{ +#ifdef HITLS_CRYPTO_CIPHER + int32_t ret = CRYPT_SUCCESS; + + if (cipher->algo == HITLS_CIPHER_AES_128_CCM8 || cipher->algo == HITLS_CIPHER_AES_256_CCM8) { + uint32_t tagLen = CCM8_TLS_TAG_LEN; + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + // In the case of CCM processing, msgLen needs to be set. + if ((cipher->algo == HITLS_CIPHER_AES_128_CCM) || (cipher->algo == HITLS_CIPHER_AES_128_CCM8) || + (cipher->algo == HITLS_CIPHER_AES_256_CCM) || (cipher->algo == HITLS_CIPHER_AES_256_CCM8)) { + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &inLen, sizeof(inLen)); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + + if (cipher->type == HITLS_AEAD_CIPHER) { + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, cipher->aad, cipher->aadLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + } + + return ret; +#else + (void)ctx; + (void)cipher; + (void)inLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +#ifdef HITLS_CRYPTO_CIPHER +static int32_t GetCipherInitCtx(const HITLS_CipherParameters *cipher, CRYPT_EAL_CipherCtx **ctx, bool enc) +{ + CRYPT_CIPHER_AlgId id = GetCipherAlgId(cipher->algo); + if (id == CRYPT_CIPHER_MAX) { + return HITLS_CRYPT_ERR_ENCRYPT; + } + + *ctx = CRYPT_EAL_CipherNewCtx(id); + if (*ctx == NULL) { + return HITLS_CRYPT_ERR_ENCRYPT; + } + + int32_t ret = CRYPT_EAL_CipherInit(*ctx, cipher->key, cipher->keyLen, cipher->iv, cipher->ivLen, enc); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(*ctx); + return ret; + } + return CRYPT_SUCCESS; +} +#endif + +int32_t CRYPT_DEFAULT_Encrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ +#ifdef HITLS_CRYPTO_CIPHER + CRYPT_EAL_CipherCtx *ctx = NULL; + int32_t ret = GetCipherInitCtx(cipher, &ctx, true); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + ret = SpecialModeEncryptPreSolve(ctx, cipher, inLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; + } + + uint32_t cipherLen = *outLen; + ret = CRYPT_EAL_CipherUpdate(ctx, in, inLen, out, &cipherLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; + } + + if (*outLen < cipherLen) { + CRYPT_EAL_CipherFreeCtx(ctx); + return HITLS_CRYPT_ERR_ENCRYPT; + } + + uint32_t finLen = *outLen - cipherLen; + if (cipher->type == HITLS_AEAD_CIPHER) { + finLen = (cipher->algo == HITLS_CIPHER_AES_128_CCM8 || cipher->algo == HITLS_CIPHER_AES_256_CCM8) ? + CCM8_TLS_TAG_LEN : + CCM_TLS_TAG_LEN; + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, out + cipherLen, finLen); + } else { + ret = CRYPT_EAL_CipherFinal(ctx, out + cipherLen, &finLen); + } + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; + } + + cipherLen += finLen; + *outLen = cipherLen; + + CRYPT_EAL_CipherFreeCtx(ctx); + return HITLS_SUCCESS; +#else + (void)cipher; + (void)in; + (void)inLen; + (void)out; + (void)outLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +static int32_t AeadDecrypt(CRYPT_EAL_CipherCtx *ctx, const HITLS_CipherParameters *cipher, const uint8_t *in, + uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ +#ifdef HITLS_CRYPTO_CIPHER + uint32_t tagLen = (cipher->algo == HITLS_CIPHER_AES_128_CCM8 || cipher->algo == HITLS_CIPHER_AES_256_CCM8) ? + CCM8_TLS_TAG_LEN : + CCM_TLS_TAG_LEN; + uint32_t cipherLen = inLen - tagLen; + uint32_t plainLen = *outLen; + + int32_t ret = CRYPT_EAL_CipherUpdate(ctx, in, cipherLen, out, &plainLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (plainLen != cipherLen) { + return HITLS_CRYPT_ERR_DECRYPT; + } + + uint8_t tag[16u] = {0}; + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG, tag, tagLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (memcmp(tag, in + cipherLen, tagLen) != 0) { + return HITLS_CRYPT_ERR_DECRYPT; + } + + *outLen = plainLen; + return HITLS_SUCCESS; +#else + (void)cipher; + (void)out; + (void)outLen; + (void)in; + (void)inLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CbcDecrypt(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen) +{ +#ifdef HITLS_CRYPTO_CIPHER + int32_t ret; + uint32_t plainLen = *outLen; + + ret = CRYPT_EAL_CipherUpdate(ctx, in, inLen, out, &plainLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + if (*outLen < plainLen) { + return HITLS_CRYPT_ERR_DECRYPT; + } + + uint32_t finLen = *outLen - plainLen; + ret = CRYPT_EAL_CipherFinal(ctx, out + plainLen, &finLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + plainLen += finLen; + + *outLen = plainLen; + return HITLS_SUCCESS; +#else + (void)ctx; + (void)out; + (void)outLen; + (void)in; + (void)inLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_Decrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ +#ifdef HITLS_CRYPTO_CIPHER + CRYPT_EAL_CipherCtx *ctx = NULL; + int32_t ret = GetCipherInitCtx(cipher, &ctx, false); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + uint32_t tagLen = CCM_TLS_TAG_LEN; + if (cipher->algo == HITLS_CIPHER_AES_128_CCM8 || cipher->algo == HITLS_CIPHER_AES_256_CCM8) { + tagLen = CCM8_TLS_TAG_LEN; + /* The default value of tagLen is 16 for the ctx generated by the CRYPT_EAL_CipherNewCtx. + Therefore, need to set this parameter again. */ + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN, &tagLen, sizeof(tagLen)); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; + } + } + if ((cipher->algo == HITLS_CIPHER_AES_128_CCM) || (cipher->algo == HITLS_CIPHER_AES_128_CCM8) || + (cipher->algo == HITLS_CIPHER_AES_256_CCM) || (cipher->algo == HITLS_CIPHER_AES_256_CCM8)) { + // The length of the decrypted ciphertext consists of msgLen and tagLen, so tagLen needs to be subtracted. + uint64_t msgLen = inLen - tagLen; + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN, &msgLen, sizeof(msgLen)); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; + } + } + + if (cipher->type == HITLS_AEAD_CIPHER) { + ret = CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD, cipher->aad, cipher->aadLen); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; + } + ret = AeadDecrypt(ctx, cipher, in, inLen, out, outLen); + } else if (cipher->type == HITLS_CBC_CIPHER) { + ret = CbcDecrypt(ctx, in, inLen, out, outLen); + } else { + ret = HITLS_CRYPT_ERR_DECRYPT; + } + + CRYPT_EAL_CipherFreeCtx(ctx); + return ret; +#else + (void)cipher; + (void)in; + (void)out; + (void)outLen; + (void)inLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +#ifdef HITLS_CRYPTO_PKEY +CRYPT_EAL_PkeyCtx *GeneratePkeyByParaId(CRYPT_PKEY_AlgId algId, CRYPT_PKEY_ParaId paraId) +{ + int32_t ret; + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(algId); + if (pkey == NULL) { + return NULL; + } + + if (algId != CRYPT_PKEY_X25519 && algId != CRYPT_PKEY_SM2) { + ret = CRYPT_EAL_PkeySetParaById(pkey, paraId); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pkey); + return NULL; + } + } + + ret = CRYPT_EAL_PkeyGen(pkey); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pkey); + return NULL; + } + + return pkey; +} +#endif + +static CRYPT_EAL_PkeyCtx *GenerateKeyByNamedGroup(HITLS_NamedGroup groupId) +{ +#ifdef HITLS_CRYPTO_PKEY + switch (groupId) { + case HITLS_EC_GROUP_SECP256R1: + return GeneratePkeyByParaId(CRYPT_PKEY_ECDH, CRYPT_ECC_NISTP256); + case HITLS_EC_GROUP_SECP384R1: + return GeneratePkeyByParaId(CRYPT_PKEY_ECDH, CRYPT_ECC_NISTP384); + case HITLS_EC_GROUP_SECP521R1: + return GeneratePkeyByParaId(CRYPT_PKEY_ECDH, CRYPT_ECC_NISTP521); + case HITLS_EC_GROUP_BRAINPOOLP256R1: + return GeneratePkeyByParaId(CRYPT_PKEY_ECDH, CRYPT_ECC_BRAINPOOLP256R1); + case HITLS_EC_GROUP_BRAINPOOLP384R1: + return GeneratePkeyByParaId(CRYPT_PKEY_ECDH, CRYPT_ECC_BRAINPOOLP384R1); + case HITLS_EC_GROUP_BRAINPOOLP512R1: + return GeneratePkeyByParaId(CRYPT_PKEY_ECDH, CRYPT_ECC_BRAINPOOLP512R1); + case HITLS_EC_GROUP_CURVE25519: + return GeneratePkeyByParaId(CRYPT_PKEY_X25519, CRYPT_PKEY_PARAID_MAX); + case HITLS_EC_GROUP_SM2: + return GeneratePkeyByParaId(CRYPT_PKEY_SM2, CRYPT_ECC_SM2); + case HITLS_FF_DHE_2048: + return GeneratePkeyByParaId(CRYPT_PKEY_DH, CRYPT_DH_RFC7919_2048); + case HITLS_FF_DHE_3072: + return GeneratePkeyByParaId(CRYPT_PKEY_DH, CRYPT_DH_RFC7919_3072); + case HITLS_FF_DHE_4096: + return GeneratePkeyByParaId(CRYPT_PKEY_DH, CRYPT_DH_RFC7919_4096); + case HITLS_FF_DHE_6144: + return GeneratePkeyByParaId(CRYPT_PKEY_DH, CRYPT_DH_RFC7919_6144); + case HITLS_FF_DHE_8192: + return GeneratePkeyByParaId(CRYPT_PKEY_DH, CRYPT_DH_RFC7919_8192); + default: + break; + } +#else + (void)groupId; +#endif + return NULL; +} + +HITLS_CRYPT_Key *CRYPT_DEFAULT_GenerateEcdhKey(const HITLS_ECParameters *curveParams) +{ + switch (curveParams->type) { + case HITLS_EC_CURVE_TYPE_NAMED_CURVE: + return GenerateKeyByNamedGroup(curveParams->param.namedcurve); + default: + break; + } + return NULL; +} + +HITLS_CRYPT_Key *CRYPT_DEFAULT_DupKey(HITLS_CRYPT_Key *key) +{ +#ifdef HITLS_CRYPTO_PKEY + return CRYPT_EAL_PkeyDupCtx(key); +#else + (void)key; + return NULL; +#endif +} + +void CRYPT_DEFAULT_FreeKey(HITLS_CRYPT_Key *key) +{ +#ifdef HITLS_CRYPTO_PKEY + CRYPT_EAL_PkeyFreeCtx(key); +#endif + (void)key; + return; +} + +static int32_t SM2KeyGetPub(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *pubKeyLen) +{ +#ifndef HITLS_CRYPTO_NO_PKEY + CRYPT_EAL_PkeyPub pub; + pub.id = CRYPT_PKEY_SM2; + pub.key.eccPub.data = pubKeyBuf; + pub.key.eccPub.len = bufLen; + + int32_t ret = CRYPT_EAL_PkeyGetPub(key, &pub); + if (ret != CRYPT_SUCCESS) { + return ret; + } + *pubKeyLen = pub.key.eccPub.len; + return HITLS_SUCCESS; +#else + (void)key; + (void)pubKeyBuf; + (void)bufLen; + (void)pubKeyLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +static int32_t EcdhKeyGetPub(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *pubKeyLen) +{ +#ifdef HITLS_CRYPTO_PKEY + CRYPT_EAL_PkeyPub pub; + pub.id = CRYPT_PKEY_ECDH; + pub.key.eccPub.data = pubKeyBuf; + pub.key.eccPub.len = bufLen; + + int32_t ret = CRYPT_EAL_PkeyGetPub(key, &pub); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + *pubKeyLen = pub.key.eccPub.len; + return HITLS_SUCCESS; +#else + (void)key; + (void)pubKeyBuf; + (void)bufLen; + (void)pubKeyLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +static int32_t X25519KeyGetPub(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *pubKeyLen) +{ +#ifdef HITLS_CRYPTO_X25519 + CRYPT_EAL_PkeyPub pub; + pub.id = CRYPT_PKEY_X25519; + pub.key.curve25519Pub.data = pubKeyBuf; + pub.key.curve25519Pub.len = bufLen; + + int32_t ret = CRYPT_EAL_PkeyGetPub(key, &pub); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + *pubKeyLen = pub.key.curve25519Pub.len; + return HITLS_SUCCESS; +#else + (void)key; + (void)pubKeyBuf; + (void)bufLen; + (void)pubKeyLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +static int32_t DhKeyGetPub(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *pubKeyLen) +{ +#ifdef HITLS_CRYPTO_DH + CRYPT_EAL_PkeyPub pub; + pub.id = CRYPT_PKEY_DH; + pub.key.dhPub.data = pubKeyBuf; + pub.key.dhPub.len = bufLen; + + int32_t ret = CRYPT_EAL_PkeyGetPub(key, &pub); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + *pubKeyLen = pub.key.dhPub.len; + uint32_t padLen = bufLen - (*pubKeyLen); + if (padLen == 0) { + return HITLS_SUCCESS; + } + + (void)memmove_s(pubKeyBuf + padLen, *pubKeyLen + padLen, pubKeyBuf, *pubKeyLen); + (void)memset_s(pubKeyBuf, *pubKeyLen + padLen, 0, padLen); + *pubKeyLen += padLen; + return HITLS_SUCCESS; +#else + (void)key; + (void)bufLen; + (void)pubKeyLen; + (void)pubKeyBuf; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_GetPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *pubKeyLen) +{ +#ifdef HITLS_CRYPTO_PKEY + CRYPT_PKEY_AlgId id = CRYPT_EAL_PkeyGetId(key); + + switch (id) { + case CRYPT_PKEY_ECDH: + return EcdhKeyGetPub(key, pubKeyBuf, bufLen, pubKeyLen); + case CRYPT_PKEY_X25519: + return X25519KeyGetPub(key, pubKeyBuf, bufLen, pubKeyLen); + case CRYPT_PKEY_DH: + return DhKeyGetPub(key, pubKeyBuf, bufLen, pubKeyLen); + case CRYPT_PKEY_SM2: + return SM2KeyGetPub(key, pubKeyBuf, bufLen, pubKeyLen); + default: + *pubKeyLen = 0; + break; + } + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; +#else + (void)key; + (void)pubKeyBuf; + (void)bufLen; + (void)pubKeyLen; + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; +#endif +} + +#ifdef HITLS_CRYPTO_PKEY +static int32_t SetPubData(CRYPT_EAL_PkeyPub *pub, uint8_t *peerPubkey, uint32_t pubKeyLen) +{ + switch (pub->id) { + case CRYPT_PKEY_ECDH: + case CRYPT_PKEY_SM2: + pub->key.eccPub.data = peerPubkey; + pub->key.eccPub.len = pubKeyLen; + break; + case CRYPT_PKEY_X25519: + pub->key.curve25519Pub.data = peerPubkey; + pub->key.curve25519Pub.len = pubKeyLen; + break; + case CRYPT_PKEY_DH: + pub->key.dhPub.data = peerPubkey; + pub->key.dhPub.len = pubKeyLen; + break; + default: + return HITLS_CRYPT_ERR_CALC_SHARED_KEY; + } + return CRYPT_SUCCESS; +} +#endif + +#ifdef HITLS_CRYPTO_PKEY +static int32_t SetSM2SelfCtx(CRYPT_EAL_PkeyCtx *selfCtx, HITLS_Sm2GenShareKeyParameters *sm2Params) +{ + uint8_t localPrvData[SM2_PRVKEY_LEN] = {0}; + CRYPT_EAL_PkeyPrv localPrv = { 0 }; + localPrv.id = CRYPT_PKEY_SM2; + localPrv.key.eccPrv.data = localPrvData; + localPrv.key.eccPrv.len = sizeof(localPrvData); + + int32_t ret = 0; + ret = CRYPT_EAL_PkeyGetPrv(sm2Params->tmpPriKey, &localPrv); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = CRYPT_EAL_PkeyCtrl(selfCtx, CRYPT_CTRL_SET_SM2_RANDOM, localPrv.key.eccPrv.data, localPrv.key.eccPrv.len); + (void)memset_s(localPrvData, SM2_PRVKEY_LEN, 0, SM2_PRVKEY_LEN); + if (ret != CRYPT_SUCCESS) { + return ret; + } + ret = CRYPT_EAL_PkeyCtrl(selfCtx, CRYPT_CTRL_SET_SM2_USER_ID, (void *)g_SM2DefaultUserid, SM2_DEFAULT_USERID_LEN); + if (ret != CRYPT_SUCCESS) { + return ret; + } + int32_t server = sm2Params->isClient ? 0 : 1; + ret = CRYPT_EAL_PkeyCtrl(selfCtx, CRYPT_CTRL_SET_SM2_SERVER, &server, sizeof(int32_t)); + return ret; +} +#endif + +int32_t CRYPT_DEFAULT_CalcSM2SharedSecret(HITLS_Sm2GenShareKeyParameters *sm2Params, uint8_t *sharedSecret, + uint32_t *sharedSecretLen) +{ +#ifdef HITLS_CRYPTO_PKEY + int32_t ret = 0; + + if (sm2Params->priKey == NULL || sm2Params->peerPubKey == NULL || sm2Params->tmpPriKey == NULL || + sm2Params->tmpPeerPubkey == NULL) { + return HITLS_CRYPT_ERR_CALC_SHARED_KEY; + } + + uint8_t peerPubData[SM2_PUBKEY_LEN] = {0}; + CRYPT_EAL_PkeyPub peerPub = { 0 }; + peerPub.id = CRYPT_PKEY_SM2; + peerPub.key.eccPub.data = peerPubData; + peerPub.key.eccPub.len = sizeof(peerPubData); + + CRYPT_EAL_PkeyCtx *selfCtx = (CRYPT_EAL_PkeyCtx *)sm2Params->priKey; + ret = SetSM2SelfCtx(selfCtx, sm2Params); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + CRYPT_EAL_PkeyCtx *peerCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); + if (peerCtx == NULL) { + return HITLS_CRYPT_ERR_CALC_SHARED_KEY; + } + ret = CRYPT_EAL_PkeyGetPub(sm2Params->peerPubKey, &peerPub); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + ret = CRYPT_EAL_PkeySetPub(peerCtx, &peerPub); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + ret = CRYPT_EAL_PkeyCtrl(peerCtx, CRYPT_CTRL_SET_SM2_R, sm2Params->tmpPeerPubkey, sm2Params->tmpPeerPubKeyLen); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + ret = CRYPT_EAL_PkeyCtrl(peerCtx, CRYPT_CTRL_SET_SM2_USER_ID, (void *)g_SM2DefaultUserid, SM2_DEFAULT_USERID_LEN); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + ret = CRYPT_EAL_PkeyComputeShareKey(selfCtx, peerCtx, sharedSecret, sharedSecretLen); +Exit: + CRYPT_EAL_PkeyFreeCtx(peerCtx); + return ret; +#else + (void)sm2Params; + (void)sharedSecret; + (void)sharedSecretLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_CalcSharedSecret(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen) +{ +#ifdef HITLS_CRYPTO_PKEY + CRYPT_PKEY_AlgId id = CRYPT_EAL_PkeyGetId(key); + + CRYPT_EAL_PkeyPub pub = {0}; + pub.id = id; + int32_t ret = SetPubData(&pub, peerPubkey, pubKeyLen); + if (ret != CRYPT_SUCCESS) { + *sharedSecretLen = 0; + return ret; + } + + CRYPT_EAL_PkeyCtx *peerPk = CRYPT_EAL_PkeyNewCtx(id); + if (peerPk == NULL) { + return HITLS_CRYPT_ERR_CALC_SHARED_KEY; + } + + if (id == CRYPT_PKEY_ECDH) { + CRYPT_PKEY_ParaId paraId = CRYPT_EAL_PkeyGetParaId(key); + if (paraId == CRYPT_PKEY_PARAID_MAX) { + ret = CRYPT_EAL_ERR_ALGID; + goto Exit; + } + ret = CRYPT_EAL_PkeySetParaById(peerPk, paraId); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + } + + ret = CRYPT_EAL_PkeySetPub(peerPk, &pub); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + + ret = CRYPT_EAL_PkeyComputeShareKey(key, peerPk, sharedSecret, sharedSecretLen); + if (ret != CRYPT_SUCCESS) { + goto Exit; + } + + ret = HITLS_SUCCESS; +Exit: + CRYPT_EAL_PkeyFreeCtx(peerPk); + return ret; +#else + (void)key; + (void)pubKeyLen; + (void)peerPubkey; + (void)sharedSecret; + (void)sharedSecretLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +uint32_t GetDhParaIdBySecbits(int32_t secbits) +{ + if (secbits >= MIN_DH8192_SECBITS) { + return CRYPT_DH_RFC3526_8192; + } + if (secbits >= MIN_DH4096_SECBITS) { + return CRYPT_DH_RFC3526_4096; + } + if (secbits >= MIN_DH3072_SECBITS) { + return CRYPT_DH_RFC3526_3072; + } + if (secbits >= MIN_DH2048_SECBITS) { + return CRYPT_DH_RFC3526_2048; + } + return CRYPT_DH_RFC2409_1024; +} + +HITLS_CRYPT_Key *CRYPT_DEFAULT_GenerateDhKeyBySecbits(int32_t secbits) +{ + CRYPT_PKEY_ParaId id = GetDhParaIdBySecbits(secbits); + return GeneratePkeyByParaId(CRYPT_PKEY_DH, id); +} + +HITLS_CRYPT_Key *CRYPT_DEFAULT_GenerateDhKeyByParameters(uint8_t *p, uint16_t pLen, uint8_t *g, uint16_t gLen) +{ +#ifdef HITLS_CRYPTO_DH + CRYPT_EAL_PkeyCtx *pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_DH); + if (pkey == NULL) { + return NULL; + } + + CRYPT_EAL_PkeyPara para = {0}; + para.id = CRYPT_PKEY_DH; + para.para.dhPara.p = p; + para.para.dhPara.pLen = pLen; + para.para.dhPara.g = g; + para.para.dhPara.gLen = gLen; + + int32_t ret = CRYPT_EAL_PkeySetPara(pkey, ¶); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pkey); + return NULL; + } + + ret = CRYPT_EAL_PkeyGen(pkey); + if (ret != CRYPT_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(pkey); + return NULL; + } + + return pkey; +#else + (void)p; + (void)pLen; + (void)g; + (void)gLen; + return NULL; +#endif +} + +int32_t CRYPT_DEFAULT_GetDhParameters(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *pLen, uint8_t *g, uint16_t *gLen) +{ +#ifdef HITLS_CRYPTO_PKEY + uint8_t tmpP[MAX_PKEY_PARA_LEN] = {0}; + uint8_t tmpQ[MAX_PKEY_PARA_LEN] = {0}; + uint8_t tmpG[MAX_PKEY_PARA_LEN] = {0}; + + CRYPT_EAL_PkeyPara para = {0}; + para.id = CRYPT_PKEY_DH; + para.para.dhPara.p = p; + para.para.dhPara.pLen = *pLen; + para.para.dhPara.q = tmpQ; + para.para.dhPara.qLen = sizeof(tmpQ); + para.para.dhPara.g = g; + para.para.dhPara.gLen = *gLen; + + if (p == NULL) { + para.para.dhPara.p = tmpP; + para.para.dhPara.pLen = sizeof(tmpP); + } + if (g == NULL) { + para.para.dhPara.g = tmpG; + para.para.dhPara.gLen = sizeof(tmpG); + } + + int32_t ret = CRYPT_EAL_PkeyGetPara(key, ¶); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + *pLen = (uint16_t)para.para.dhPara.pLen; + *gLen = (uint16_t)para.para.dhPara.gLen; + return HITLS_SUCCESS; +#else + (void)key; + (void)p; + (void)pLen; + (void)g; + (void)gLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_HkdfExtract(const HITLS_CRYPT_HkdfExtractInput *input, uint8_t *prk, uint32_t *prkLen) +{ +#ifdef HITLS_CRYPTO_HKDF + int32_t ret; + uint32_t tmpLen = *prkLen; + CRYPT_MAC_AlgId id = GetHmacAlgId(input->hashAlgo); + if (id == CRYPT_MAC_MAX) { + return HITLS_CRYPT_ERR_HMAC; + } + + ret = CRYPT_EAL_HkdfExtract(id, input->ikm, input->ikmLen, input->salt, input->saltLen, prk, &tmpLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + *prkLen = tmpLen; + return HITLS_SUCCESS; +#else + (void)input; + (void)prk; + (void)prkLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} + +int32_t CRYPT_DEFAULT_HkdfExpand(const HITLS_CRYPT_HkdfExpandInput *input, uint8_t *okm, uint32_t okmLen) +{ +#ifdef HITLS_CRYPTO_HKDF + int32_t ret; + CRYPT_MAC_AlgId id = GetHmacAlgId(input->hashAlgo); + if (id == CRYPT_MAC_MAX) { + return HITLS_CRYPT_ERR_HMAC; + } + + ret = CRYPT_EAL_HkdfExpand(id, input->prk, input->prkLen, input->info, input->infoLen, okm, okmLen); + if (ret != CRYPT_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +#else + (void)input; + (void)okm; + (void)okmLen; + return CRYPT_EAL_ALG_NOT_SUPPORT; +#endif +} \ No newline at end of file diff --git a/tls/crypt/crypt_self/crypt_default.h b/tls/crypt/crypt_self/crypt_default.h new file mode 100644 index 00000000..b1db13dd --- /dev/null +++ b/tls/crypt/crypt_self/crypt_default.h @@ -0,0 +1,334 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CRYPT_DEFAULT_H +#define CRYPT_DEFAULT_H +#include +#include "hitls_crypt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Generate a random number. + * + * @param buf [OUT] Random number + * @param len [IN] Random number length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_RandomBytes(uint8_t *buf, uint32_t len); + +/** + * @brief Obtain the HMAC length. + * + * @param hashAlgo [IN] hash algorithm + * + * @return HMAC length + */ +uint32_t CRYPT_DEFAULT_HMAC_Size(HITLS_HashAlgo hashAlgo); + +/** + * @brief Initialize the HMAC context. + * + * @param hashAlgo [IN] Hash algorithm + * @param key [IN] Key + * @param len [IN] Key length + * + * @return HMAC context + */ +HITLS_HMAC_Ctx *CRYPT_DEFAULT_HMAC_Init(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len); + +/** + * @brief Release the HMAC context. + * + * @param hmac [IN] HMAC context. The CTX is set NULL by the invoker. + */ +void CRYPT_DEFAULT_HMAC_Free(HITLS_HMAC_Ctx *ctx); + +/** + * @brief Add the HMAC input data. + * + * @param hmac [IN] HMAC context + * @param data [IN] Input data + * @param len [IN] Input data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_HMAC_Update(HITLS_HMAC_Ctx *ctx, const uint8_t *data, uint32_t len); + +/** + * @brief HMAC calculation result + * + * @param hmac [IN] HMAC context + * @param out [OUT] Output data + * @param len [IN/OUT] IN: Maximum length of data padding OUT: Output data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_HMAC_Final(HITLS_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len); + +/** + * @brief HMAC function + * + * @param hashAlgo [IN] Hash algorithm + * @param key [IN] Key + * @param keyLen [IN] Key length + * @param in [IN] Input data + * @param inLen [IN] Input data length + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Output data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_HMAC(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen, + const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); + +/** + * @brief Obtain the hash length. + * + * @param hashAlgo [IN] hash algorithm + * + * @return Hash length + */ +uint32_t CRYPT_DEFAULT_DigestSize(HITLS_HashAlgo hashAlgo); + +/** + * @brief Initialize the hash context. + * + * @param hashAlgo [IN] Hash algorithm + * + * @return hash context + */ +HITLS_HASH_Ctx *CRYPT_DEFAULT_DigestInit(HITLS_HashAlgo hashAlgo); + +/** + * @brief Copy the hash context. + * + * @param ctx [IN] hash context + * + * @return hash context + */ +HITLS_HASH_Ctx *CRYPT_DEFAULT_DigestCopy(HITLS_HASH_Ctx *ctx); + +/** + * @brief Release the hash context. + * + * @param ctx [IN] Hash context. The CTX is set NULL by the invoker. + */ +void CRYPT_DEFAULT_DigestFree(HITLS_HASH_Ctx *ctx); + +/** + * @brief Add the hash input data. + * + * @param ctx [IN] hash Context + * @param data [IN] Input data + * @param len [IN] Length of the input data + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_DigestUpdate(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len); + +/** + * @brief Calculate the hash result. + * + * @param ctx [IN] hash context + * @param out [OUT] Output data + * @param len [IN/OUT] IN: Maximum length of data padding OUT: Length of output data + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_DigestFinal(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len); + +/** + * @brief hash function + * + * @param hashAlgo [IN] hash algorithm + * @param in [IN] Input data + * @param inLen [IN] Input data length + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Output data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_Digest(HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @brief Encryption + * + * @param cipher [IN] Key parameters + * @param in [IN] Plaintext data + * @param inLen [IN] Length of the plaintext data + * @param out [OUT] Ciphertext data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Length of ciphertext data + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_Encrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @brief Decrypt + * + * @param cipher [IN] Key parameters + * @param in [IN] Ciphertext data + * @param inLen [IN] Length of the ciphertext data + * @param out [OUT] Plaintext data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Length of plaintext data + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_Decrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @brief Generate the ECDH key pair. + * + * @param curveParams [IN] ECDH parameter + * + * @return Key handle + */ +HITLS_CRYPT_Key *CRYPT_DEFAULT_GenerateEcdhKey(const HITLS_ECParameters *curveParams); + +/** + * @brief Generate a DH key pair. + * + * @param secbits [IN] Key security level + * + * @return Key handle + */ +HITLS_CRYPT_Key *CRYPT_DEFAULT_GenerateDhKeyBySecbits(int32_t secbits); + +/** + * @brief Generate a DH key pair. + * + * @param p [IN] p Parameter + * @param plen [IN] p Parameter length + * @param g [IN] g Parameter + * @param glen [IN] g Parameter length + * + * @return Key handle + */ +HITLS_CRYPT_Key *CRYPT_DEFAULT_GenerateDhKeyByParameters(uint8_t *p, uint16_t pLen, uint8_t *g, uint16_t gLen); + +/** + * @brief Obtain the DH parameter. + * + * @param key [IN] Key handle + * @param p [OUT] p Parameter + * @param plen [IN/OUT] IN: Maximum length of data padding OUT: p Parameter length + * @param g [OUT] g Parameter + * @param glen [IN/OUT] IN: Maximum length of data padding OUT: g Parameter length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_GetDhParameters(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *pLen, uint8_t *g, uint16_t *gLen); + +/** + * @brief Deep copy key + * + * @param key [IN] Key handle + * @retval Key handle + */ +HITLS_CRYPT_Key *CRYPT_DEFAULT_DupKey(HITLS_CRYPT_Key *key); + +/** + * @brief Release the key. + * + * @param key [IN] Key handle. The key is set NULL by the invoker. + */ +void CRYPT_DEFAULT_FreeKey(HITLS_CRYPT_Key *key); + +/** + * @brief Obtain the public key data. + * + * @param key [IN] Key handle + * @param pubKeyBuf [OUT] Public key data + * @param bufLen [IN] Maximum length of data padding. + * @param usedLen [OUT] Public key data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_GetPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Calculate the shared key. + * + * @param key [IN] Local key handle + * @param peerPubkey [IN] Peer public key data + * @param pubKeyLen [IN] Public key data length + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of data padding OUT: length of the shared key + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_CalcSharedSecret(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @brief Calculate the SM2 shared key. + * + * @param sm2Params [IN] SM2 parameters + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of data padding OUT: length of the shared key + * + * @retval HITLS_SUCCESS + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_CalcSM2SharedSecret(HITLS_Sm2GenShareKeyParameters *sm2Params, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @brief HKDF-Extract + * + * @param input [IN] Input key material. + * @param prk [OUT] Output key + * @param prkLen [IN/OUT] IN: Maximum buffer length OUT: Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_HkdfExtract(const HITLS_CRYPT_HkdfExtractInput *input, uint8_t *prk, uint32_t *prkLen); + +/** + * @brief HKDF-Expand + * + * @param input [IN] Input key material. + * @param okm [OUT] Output key + * @param okmLen [IN] Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval Other failure + */ +int32_t CRYPT_DEFAULT_HkdfExpand(const HITLS_CRYPT_HkdfExpandInput *input, uint8_t *okm, uint32_t okmLen); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/tls/crypt/crypt_self/crypt_init.c b/tls/crypt/crypt_self/crypt_init.c new file mode 100644 index 00000000..44a1110b --- /dev/null +++ b/tls/crypt/crypt_self/crypt_init.c @@ -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. + */ + +#include "hitls_crypt_reg.h" +#include "crypt_default.h" + +void HITLS_CryptMethodInit(void) +{ + HITLS_CRYPT_BaseMethod baseMethod = {0}; + baseMethod.randBytes = CRYPT_DEFAULT_RandomBytes; + baseMethod.hmacSize = CRYPT_DEFAULT_HMAC_Size; + baseMethod.hmacInit = CRYPT_DEFAULT_HMAC_Init; + baseMethod.hmacFree = CRYPT_DEFAULT_HMAC_Free; + baseMethod.hmacUpdate = CRYPT_DEFAULT_HMAC_Update; + baseMethod.hmacFinal = CRYPT_DEFAULT_HMAC_Final; + baseMethod.hmac = CRYPT_DEFAULT_HMAC; + baseMethod.digestSize = CRYPT_DEFAULT_DigestSize; + baseMethod.digestInit = CRYPT_DEFAULT_DigestInit; + baseMethod.digestCopy = CRYPT_DEFAULT_DigestCopy; + baseMethod.digestFree = CRYPT_DEFAULT_DigestFree; + baseMethod.digestUpdate = CRYPT_DEFAULT_DigestUpdate; + baseMethod.digestFinal = CRYPT_DEFAULT_DigestFinal; + baseMethod.digest = CRYPT_DEFAULT_Digest; + baseMethod.encrypt = CRYPT_DEFAULT_Encrypt; + baseMethod.decrypt = CRYPT_DEFAULT_Decrypt; + HITLS_CRYPT_RegisterBaseMethod(&baseMethod); + + HITLS_CRYPT_EcdhMethod ecdhMethod = {0}; + ecdhMethod.generateEcdhKeyPair = CRYPT_DEFAULT_GenerateEcdhKey; + ecdhMethod.dupEcdhKey = CRYPT_DEFAULT_DupKey; + ecdhMethod.freeEcdhKey = CRYPT_DEFAULT_FreeKey; + ecdhMethod.getEcdhPubKey = CRYPT_DEFAULT_GetPubKey; + ecdhMethod.calcEcdhSharedSecret = CRYPT_DEFAULT_CalcSharedSecret; + ecdhMethod.sm2CalEcdhSharedSecret = CRYPT_DEFAULT_CalcSM2SharedSecret; + HITLS_CRYPT_RegisterEcdhMethod(&ecdhMethod); + + HITLS_CRYPT_DhMethod dhMethod = {0}; + dhMethod.generateDhKeyBySecbits = CRYPT_DEFAULT_GenerateDhKeyBySecbits; + dhMethod.generateDhKeyByParams = CRYPT_DEFAULT_GenerateDhKeyByParameters; + dhMethod.dupDhKey = CRYPT_DEFAULT_DupKey; + dhMethod.freeDhKey = CRYPT_DEFAULT_FreeKey; + dhMethod.getDhParameters = CRYPT_DEFAULT_GetDhParameters; + dhMethod.getDhPubKey = CRYPT_DEFAULT_GetPubKey; + dhMethod.calcDhSharedSecret = CRYPT_DEFAULT_CalcSharedSecret; + HITLS_CRYPT_RegisterDhMethod(&dhMethod); + + HITLS_CRYPT_KdfMethod hkdfMethod = {0}; + hkdfMethod.hkdfExtract = CRYPT_DEFAULT_HkdfExtract; + hkdfMethod.hkdfExpand = CRYPT_DEFAULT_HkdfExpand; + HITLS_CRYPT_RegisterHkdfMethod(&hkdfMethod); + + return; +} \ No newline at end of file diff --git a/tls/crypt/include/crypt.h b/tls/crypt/include/crypt.h new file mode 100644 index 00000000..f3153722 --- /dev/null +++ b/tls/crypt/include/crypt.h @@ -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. + */ + +#ifndef CRYPT_H +#define CRYPT_H + +#include +#include "hitls_crypt_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The maximum length of the RSA signature is 512. The maximum length of the ECC signature does not reach 1024. */ +#define MAX_SIGN_SIZE 1024 + +/* Used to transfer key derivation parameters. */ +typedef struct { + HITLS_HashAlgo hashAlgo; /* Hash algorithm */ + const uint8_t *secret; /* Initialization key */ + uint32_t secretLen; /* Key length */ + const uint8_t *label; /* Label */ + uint32_t labelLen; /* Label length */ + const uint8_t *seed; /* Seed */ + uint32_t seedLen; /* Seed length */ +} CRYPT_KeyDeriveParameters; + +/** + * @brief Generate a random number. + * + * @param buf [OUT] Random number + * @param len [IN] Random number length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_GENRATE_RANDOM Failed to generate a random number. + */ +int32_t SAL_CRYPT_Rand(uint8_t *buf, uint32_t len); + +/** + * @brief Obtain the HMAC length. + * + * @param hashAlgo [IN] hash algorithm + * + * @return HMAC length + */ +uint32_t SAL_CRYPT_HmacSize(HITLS_HashAlgo hashAlgo); + +/** + * @brief Initialize the HMAC context. + * + * @param hashAlgo [IN] hash algorithm + * @param key [IN] Key + * @param len [IN] Key length + * + * @return HMAC context + */ +HITLS_HMAC_Ctx *SAL_CRYPT_HmacInit(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len); + +/** + * @brief Release the HMAC context. + * + * @param hmac [IN] HMAC context + */ +void SAL_CRYPT_HmacFree(HITLS_HMAC_Ctx *hmac); + +/** + * @brief Add the HMAC input data. + * + * @param hmac [IN] HMAC context + * @param data [IN] Input data + * @param len [IN] Input data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HMAC The HMAC operation fails. + */ +int32_t SAL_CRYPT_HmacUpdate(HITLS_HMAC_Ctx *hmac, const uint8_t *data, uint32_t len); + +/** + * @brief Calculate the HMAC result. + * + * @param hmac [IN] HMAC context + * @param out [OUT] Output data + * @param len [IN/OUT] IN: Maximum length of data padding OUT: Output data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HMAC The HMAC operation fails. + */ +int32_t SAL_CRYPT_HmacFinal(HITLS_HMAC_Ctx *hmac, uint8_t *out, uint32_t *len); + +/** + * @brief HMAC function + * + * @param hashAlgo [IN] hash algorithm + * @param key [IN] Key + * @param keyLen [IN] Key length + * @param in [IN] Input data + * @param inLen [IN] Input data length + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Output data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HMAC The HMAC operation fails. + */ +int32_t SAL_CRYPT_Hmac(HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen, + const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); + +/** + * @brief PRF function + * + * @param input [IN] Key derivation parameter + * @param md [OUT] Output key + * @param outLen [OUT] Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HMAC The HMAC operation fails. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + */ +int32_t SAL_CRYPT_PRF(CRYPT_KeyDeriveParameters *input, uint8_t *out, uint32_t outLen); + +/** + * @brief Obtain the hash length. + * + * @param hashAlgo [IN] Hash algorithm + * + * @return Hash length + */ +uint32_t SAL_CRYPT_DigestSize(HITLS_HashAlgo hashAlgo); + +/** + * @brief Initialize the hash context. + * + * @param hashAlgo [IN] hash algorithm + * + * @return hash context + */ +HITLS_HASH_Ctx *SAL_CRYPT_DigestInit(HITLS_HashAlgo hashAlgo); + +/** + * @brief Copy the hash context. + * + * @param ctx [IN] hash Context + * + * @return hash context + */ +HITLS_HASH_Ctx *SAL_CRYPT_DigestCopy(HITLS_HASH_Ctx *ctx); + +/** + * @brief Release the hash context. + * + * @param ctx [IN] hash Context + */ +void SAL_CRYPT_DigestFree(HITLS_HASH_Ctx *ctx); + +/** + * @brief Add the hash input data. + * + * @param ctx [IN] hash Context + * @param data [IN] Input data + * @param len [IN] Length of the input data + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash operation failed. + */ +int32_t SAL_CRYPT_DigestUpdate(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len); + +/** + * @brief Calculate the hash result. + * + * @param ctx [IN] hash context + * @param out [OUT] Output data + * @param len [IN/OUT] IN: Maximum length of data padding OUT: Length of output data + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash operation failed. + */ +int32_t SAL_CRYPT_DigestFinal(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len); + +/** + * @brief Calculate the hash. + * + * @param hashAlgo [IN] hash algorithm + * @param in [IN] Input data + * @param inLen [IN] Length of the input data + * @param out [OUT] Output data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Length of output data + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash operation failed. + */ +int32_t SAL_CRYPT_Digest(HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); + +/** + * @brief Encryption + * + * @param cipher [IN] Key parameters + * @param in [IN] Plaintext data + * @param inLen [IN] Length of the plaintext data + * @param out [OUT] Ciphertext data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Length of ciphertext data + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_ENCRYPT Encryption failed. + */ +int32_t SAL_CRYPT_Encrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @brief Decrypt + * + * @param cipher [IN] Key parameters + * @param in [IN] Ciphertext data + * @param inLen [IN] Length of the ciphertext data + * @param out [OUT] Plaintext data + * @param outLen [IN/OUT] IN: Maximum length of data padding OUT: Length of plaintext data + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DECRYPT decryption failure + */ +int32_t SAL_CRYPT_Decrypt(const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen); + +/** + * @brief Generate the ECDH key pair. + * + * @param curveParams [IN] Elliptic curve parameter + * + * @return Key handle + */ +HITLS_CRYPT_Key *SAL_CRYPT_GenEcdhKeyPair(const HITLS_ECParameters *curveParams); + +/** + * @brief Deep Copy ECDH Key Pair + * + * @param key [IN] Key handle + * + * @return Key handle + */ +HITLS_CRYPT_Key *SAL_CRYPT_DupEcdhKey(HITLS_CRYPT_Key *key); + +/** + * @brief Release the ECDH key. + * + * @param key [IN] Key handle + */ +void SAL_CRYPT_FreeEcdhKey(HITLS_CRYPT_Key *key); + +/** + * @brief Obtain the ECDH public key data. + * + * @param key [IN] Key handle + * @param pubKeyBuf [OUT] Public key data + * @param bufLen [IN] Maximum length of data padding. + * @param usedLen [OUT] Public key data length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_ENCODE_ECDH_KEY Failed to obtain the public key data. + */ +int32_t SAL_CRYPT_EncodeEcdhPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Calculate the ECDH shared key. + * + * @param key [IN] Local key handle + * @param peerPubkey [IN] Peer public key data + * @param pubKeyLen [IN] Public key data length + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of data padding OUT: length of the shared key + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_CALC_SHARED_KEY Failed to calculate the shared key. + */ +int32_t SAL_CRYPT_CalcEcdhSharedSecret(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @brief SM2 calculates the ECDH shared key. + * + * @param sm2ShareKeyParam [IN] Parameters required for calculating the shared key + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of data padding OUT: length of the shared key + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_CALC_SHARED_KEY Failed to calculate the shared key. + */ +int32_t SAL_CRYPT_CalcSm2dhSharedSecret(HITLS_Sm2GenShareKeyParameters *sm2ShareKeyParam, uint8_t *sharedSecret, + uint32_t *sharedSecretLen); + +/** + * @brief Generate a DH key pair. + * + * @param secbits [IN] Key security level + * + * @return Key handle + */ +HITLS_CRYPT_Key *SAL_CRYPT_GenerateDhKeyBySecbits(int32_t secbits); + +/** + * @brief Generate a DH key pair. + * + * @param p [IN] p Parameter + * @param plen [IN] p Parameter length + * @param g [IN] g Parameter + * @param glen [IN] g Parameter length + * + * @return Key handle + */ +HITLS_CRYPT_Key *SAL_CRYPT_GenerateDhKeyByParams(uint8_t *p, uint16_t plen, uint8_t *g, uint16_t glen); + +/** + * @brief Deep Copy DH Key Pair + * + * @param key [IN] Key handle + * + * @return Key handle + */ +HITLS_CRYPT_Key *SAL_CRYPT_DupDhKey(HITLS_CRYPT_Key *key); + +/** + * @brief Release the DH key. + * + * @param key [IN] Key handle + */ +void SAL_CRYPT_FreeDhKey(HITLS_CRYPT_Key *key); + +/** + * @brief Obtain the DH parameter. + * + * @param key [IN] Key handle + * @param p [OUT] p Parameter + * @param plen [IN/OUT] IN: Maximum length of data padding OUT: p Parameter length + * @param g [OUT] g Parameter + * @param glen [IN/OUT] IN: Maximum length of data padding OUT: g Parameter length + * + * @return HITLS_SUCCESS succeeded. + */ +int32_t SAL_CRYPT_GetDhParameters(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *plen, + uint8_t *g, uint16_t *glen); + +/** +* @brief Obtain the DH public key data. +* +* @param key [IN] Key handle +* @param pubKeyBuf [OUT] Public key data +* @param bufLen [IN] Maximum length of data padding. +* @param usedLen [OUT] Public key data length +* +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback +* @retval HITLS_CRYPT_ERR_ENCODE_DH_KEY Failed to obtain the public key data. + */ +int32_t SAL_CRYPT_EncodeDhPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Calculate the DH shared key. + * + * @param key [IN] Local key handle + * @param peerPubkey [IN] Peer public key data + * @param pubKeyLen [IN] Public key data length + * @param sharedSecret [OUT] Shared key + * @param sharedSecretLen [IN/OUT] IN: Maximum length of data padding OUT: length of the shared key + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_CALC_SHARED_KEY Failed to calculate the shared key. + */ +int32_t SAL_CRYPT_CalcDhSharedSecret(HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, + uint8_t *sharedSecret, uint32_t *sharedSecretLen); + +/** + * @brief HKDF-Extract + * + * @param input [IN] Input key material + * @param prk [OUT] Output key + * @param prkLen [IN/OUT] IN: Maximum buffer length OUT: Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT calculation fails. + */ +int32_t SAL_CRYPT_HkdfExtract(HITLS_CRYPT_HkdfExtractInput *input, uint8_t *prk, uint32_t *prkLen); + +/** + * @brief HKDF-Expand + * + * @param input [IN] Input key material + * @param okm [OUT] Output key + * @param okmLen [IN] Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND calculation fails. + */ +int32_t SAL_CRYPT_HkdfExpand(HITLS_CRYPT_HkdfExpandInput *input, uint8_t *okm, uint32_t okmLen); + +/** + * @brief HKDF-ExpandLabel + * + * @param input [IN] Input key material. + * @param prk [OUT] Output key + * @param prkLen [IN/OUT] IN: Maximum buffer length OUT: Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT calculation fails. + * @retval HITLS_MEMCPY_FAIL Memory Copy Failure + */ +int32_t SAL_CRYPT_HkdfExpandLabel(CRYPT_KeyDeriveParameters *deriveInfo, + uint8_t *outSecret, uint32_t outLen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tls/feature/alpn/src/alpn.c b/tls/feature/alpn/src/alpn.c new file mode 100644 index 00000000..38e6a9fe --- /dev/null +++ b/tls/feature/alpn/src/alpn.c @@ -0,0 +1,50 @@ +/* + * 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 +#include "securec.h" +#include "hitls_error.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "alpn.h" + +int32_t ALPN_SelectProtocol(uint8_t **out, uint32_t *outLen, uint8_t *clientAlpnList, uint32_t clientAlpnListLen, + uint8_t *servAlpnList, uint32_t servAlpnListLen) +{ + if (out == NULL || outLen == NULL || clientAlpnList == NULL || servAlpnList == NULL || + servAlpnListLen == 0 || clientAlpnListLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + uint32_t i, j; + for (i = 0; i < servAlpnListLen;) { + for (j = 0; j < clientAlpnListLen;) { + if (servAlpnList[i] == clientAlpnList[j] && + (memcmp(&servAlpnList[i + 1], &clientAlpnList[j + 1], servAlpnList[i]) == 0)) { + *out = &servAlpnList[i]; + *outLen = servAlpnList[i] + 1; + goto END; + } + j = j + clientAlpnList[j]; + ++j; + } + i = i + servAlpnList[i]; + ++i; + } + +END: + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/feature/indicator/src/indicator.c b/tls/feature/indicator/src/indicator.c new file mode 100644 index 00000000..838616a6 --- /dev/null +++ b/tls/feature/indicator/src/indicator.c @@ -0,0 +1,36 @@ +/* + * 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 "tls.h" +#include "indicator.h" + +void INDICATOR_StatusIndicate(const HITLS_Ctx *ctx, int32_t eventType, int32_t value) +{ + if (ctx == NULL || ctx->config.tlsConfig.infoCb == NULL) { + return; + } + + ctx->config.tlsConfig.infoCb(ctx, eventType, value); +} + +void INDICATOR_MessageIndicate(int32_t writePoint, uint32_t tlsVersion, int32_t contentType, const void *msg, + uint32_t msgLen, HITLS_Ctx *ctx, void *arg) +{ + if (ctx == NULL || ctx->config.tlsConfig.msgCb == NULL) { + return; + } + + ctx->config.tlsConfig.msgCb(writePoint, tlsVersion, contentType, msg, msgLen, ctx, arg); +} \ No newline at end of file diff --git a/tls/feature/security/src/security.c b/tls/feature/security/src/security.c new file mode 100644 index 00000000..32e6fb59 --- /dev/null +++ b/tls/feature/security/src/security.c @@ -0,0 +1,140 @@ +/* + * 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 +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_security.h" +#include "tls.h" + +int32_t HITLS_CFG_SetSecurityLevel(HITLS_Config *config, int32_t securityLevel) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->securityLevel = securityLevel; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_GetSecurityLevel(const HITLS_Config *config, int32_t *securityLevel) +{ + if (config == NULL || securityLevel == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *securityLevel = config->securityLevel; + return HITLS_SUCCESS; +} + +int32_t HITLS_CFG_SetSecurityCb(HITLS_Config *config, HITLS_SecurityCb securityCb) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->securityCb = securityCb; + return HITLS_SUCCESS; +} + +HITLS_SecurityCb HITLS_CFG_GetSecurityCb(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return config->securityCb; +} + +int32_t HITLS_CFG_SetSecurityExData(HITLS_Config *config, void *securityExData) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + config->securityExData = securityExData; + return HITLS_SUCCESS; +} + +void *HITLS_CFG_GetSecurityExData(const HITLS_Config *config) +{ + if (config == NULL) { + return NULL; + } + + return config->securityExData; +} + +int32_t HITLS_SetSecurityLevel(HITLS_Ctx *ctx, int32_t securityLevel) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSecurityLevel(&(ctx->config.tlsConfig), securityLevel); +} + +int32_t HITLS_GetSecurityLevel(const HITLS_Ctx *ctx, int32_t *securityLevel) +{ + if (ctx == NULL || securityLevel == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_GetSecurityLevel(&(ctx->config.tlsConfig), securityLevel); +} + +int32_t HITLS_SetSecurityCb(HITLS_Ctx *ctx, HITLS_SecurityCb securityCb) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSecurityCb(&(ctx->config.tlsConfig), securityCb); +} + +HITLS_SecurityCb HITLS_GetSecurityCb(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetSecurityCb(&(ctx->config.tlsConfig)); +} + +int32_t HITLS_SetSecurityExData(HITLS_Ctx *ctx, void *securityExData) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return HITLS_CFG_SetSecurityExData(&(ctx->config.tlsConfig), securityExData); +} + +void *HITLS_GetSecurityExData(const HITLS_Ctx *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return HITLS_CFG_GetSecurityExData(&(ctx->config.tlsConfig)); +} \ No newline at end of file diff --git a/tls/feature/security/src/security_default.c b/tls/feature/security/src/security_default.c new file mode 100644 index 00000000..5c74b25e --- /dev/null +++ b/tls/feature/security/src/security_default.c @@ -0,0 +1,280 @@ +/* + * 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 +#include "securec.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_security.h" +#include "tls.h" +#include "security.h" + +/* Number of security bits corresponding to the security level */ +static const int32_t g_minBits[] = {HITLS_SECURITY_LEVEL_ONE_SECBITS, + HITLS_SECURITY_LEVEL_TWO_SECBITS, + HITLS_SECURITY_LEVEL_THREE_SECBITS, + HITLS_SECURITY_LEVEL_FOUR_SECBITS, + HITLS_SECURITY_LEVEL_FIVE_SECBITS}; +int32_t SECURITY_GetSecbits(int32_t level) +{ + if (level <= HITLS_SECURITY_LEVEL_MIN) { + return 0; + } else { + level = (level > HITLS_SECURITY_LEVEL_MAX) ? HITLS_SECURITY_LEVEL_MAX : level; + } + return g_minBits[level - 1]; +} + +static int32_t GetGroupSecbits(HITLS_NamedGroup groupId) +{ + switch (groupId) { + case HITLS_FF_DHE_2048: + return HITLS_SECURITY_LEVEL_TWO_SECBITS; + case HITLS_EC_GROUP_SECP256R1: + case HITLS_EC_GROUP_BRAINPOOLP256R1: + case HITLS_EC_GROUP_SM2: + case HITLS_EC_GROUP_CURVE25519: + case HITLS_FF_DHE_3072: + case HITLS_FF_DHE_4096: + case HITLS_FF_DHE_6144: + return HITLS_SECURITY_LEVEL_THREE_SECBITS; + case HITLS_EC_GROUP_SECP384R1: + case HITLS_EC_GROUP_BRAINPOOLP384R1: + case HITLS_FF_DHE_8192: + return HITLS_SECURITY_LEVEL_FOUR_SECBITS; + case HITLS_EC_GROUP_SECP521R1: + case HITLS_EC_GROUP_BRAINPOOLP512R1: + return HITLS_SECURITY_LEVEL_FIVE_SECBITS; + default: + return -1; + } +} + +static int32_t GetSigalgSecbits(HITLS_SignHashAlgo signScheme) +{ + switch (signScheme) { + case CERT_SIG_SCHEME_RSA_PKCS1_SHA224: + case CERT_SIG_SCHEME_DSA_SHA224: + case CERT_SIG_SCHEME_ECDSA_SHA224: + return HITLS_SECURITY_LEVEL_TWO_SECBITS; + case CERT_SIG_SCHEME_RSA_PKCS1_SHA256: + case CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256: + case CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256: + case CERT_SIG_SCHEME_DSA_SHA256: + case CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256: + case CERT_SIG_SCHEME_ED25519: +#ifndef HITLS_NO_TLCP11 + case CERT_SIG_SCHEME_SM2_SM3: +#endif + return HITLS_SECURITY_LEVEL_THREE_SECBITS; + case CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384: + case CERT_SIG_SCHEME_RSA_PSS_PSS_SHA384: + case CERT_SIG_SCHEME_RSA_PKCS1_SHA384: + case CERT_SIG_SCHEME_DSA_SHA384: + case CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384: + return HITLS_SECURITY_LEVEL_FOUR_SECBITS; + case CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512: + case CERT_SIG_SCHEME_RSA_PSS_PSS_SHA512: + case CERT_SIG_SCHEME_RSA_PKCS1_SHA512: + case CERT_SIG_SCHEME_DSA_SHA512: + case CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512: + return HITLS_SECURITY_LEVEL_FIVE_SECBITS; + default: + return -1; + } +} + +static int32_t CheckCipherSuite(void *other, int32_t level) +{ + if (other == NULL) { + return SECURITY_ERR; + } + + CipherSuiteInfo *info = (CipherSuiteInfo *)other; + int32_t minBits = SECURITY_GetSecbits(level); + if (info->strengthBits < minBits) { + return SECURITY_ERR; + } + /* The anonymous cipher suite is insecure. */ + if (info->minVersion != HITLS_VERSION_TLS13 && info->authAlg == HITLS_AUTH_NULL) { + return SECURITY_ERR; + } + /* The level is greater than or equal to 1, and the export cipher suite and the MD5 algorithm for calculating MAC + * addresses are prohibited. Currently, the export cipher suite and the MD5 algorithm for calculating MAC addresses + * are not supported. Therefore, the check is not required. */ + /* The RC4 stream encryption algorithm is not supported because the RC4 stream encryption algorithm is not + * supported. */ + /* Forbidding non-forward security cipher suites when Level is greater than or equal to 3. */ + if ((level >= HITLS_SECURITY_LEVEL_THREE) && + (info->kxAlg != HITLS_KEY_EXCH_DHE && info->kxAlg != HITLS_KEY_EXCH_ECDHE && + info->kxAlg != HITLS_KEY_EXCH_DHE_PSK && info->kxAlg != HITLS_KEY_EXCH_ECDHE_PSK && + info->minVersion != HITLS_VERSION_TLS13)) { + return SECURITY_ERR; + } + /* If the level is greater than or equal to 4, disable the SHA1 algorithm. */ + + if ((level >= HITLS_SECURITY_LEVEL_FOUR) && (info->macAlg == HITLS_MAC_1)) { + return SECURITY_ERR; + } + + return SECURITY_SUCCESS; +} + +static int32_t CheckVersion(int32_t id, int32_t level) +{ + /* Check the DTLS version. */ + if (IS_DTLS_VERSION((uint32_t)id)) { + /* The level is greater than or equal to 1, and DTLS1.0 cannot be used. */ + if ((level >= HITLS_SECURITY_LEVEL_ONE) && ((uint32_t)id > HITLS_VERSION_DTLS12)) { + return SECURITY_ERR; + } + return SECURITY_SUCCESS; + } +#ifndef HITLS_NO_TLCP11 + /* If the level is greater than or equal to 1, SSL2.0, SSL3.0, TLS1.0, and TLS1.1 cannot be used. */ + if ((level >= HITLS_SECURITY_LEVEL_ONE) && ((uint32_t)id < HITLS_VERSION_TLS12) && + ((uint32_t)id != HITLS_VERSION_TLCP11)) { + return SECURITY_ERR; + } + /* Level is greater than or equal to 4 and TLCP1.1 is prohibited because the security strength of the signature + * algorithm CERT_SIG_SCHEME_SM2_SM3 is 128 bits. */ + if ((level >= HITLS_SECURITY_LEVEL_FOUR) && ((uint32_t)id == HITLS_VERSION_TLCP11)) { + return SECURITY_ERR; + } +#else + /* If the level is greater than or equal to 1, SSL2.0, SSL3.0, TLS1.0, and TLS1.1 cannot be used. */ + if ((level >= HITLS_SECURITY_LEVEL_ONE) && ((uint32_t)id < HITLS_VERSION_TLS12)) { + return SECURITY_ERR; + } +#endif + return SECURITY_SUCCESS; +} + +static int32_t CheckGroup(int32_t id, int32_t level) +{ + int32_t secbits = GetGroupSecbits(id); + if (secbits < g_minBits[level - 1]) { + return SECURITY_ERR; + } + return SECURITY_SUCCESS; +} + +static int32_t CheckSigalg(int32_t id, int32_t level) +{ + int32_t secbits = GetSigalgSecbits(id); + if (secbits < g_minBits[level - 1]) { + return SECURITY_ERR; + } + return SECURITY_SUCCESS; +} + +static int32_t CheckSessionTicket(int32_t level) +{ + /* If the level is greater than or equal to 3, the session ticket is prohibited. */ + if (level >= HITLS_SECURITY_LEVEL_THREE) { + return SECURITY_ERR; + } + return SECURITY_SUCCESS; +} + +/* Default callback function */ +int32_t SECURITY_DefaultCb(const HITLS_Ctx *ctx, const HITLS_Config *config, int32_t option, int32_t bits, int32_t id, + void *other, void *exData) +{ + (void)exData; + int32_t ret; + int32_t level = HITLS_DEFAULT_SECURITY_LEVEL; + int32_t minBits; + if (ctx == NULL && config == NULL) { + return SECURITY_ERR; + } else if (config != NULL) { + (void)HITLS_CFG_GetSecurityLevel(config, &level); + } else { + (void)HITLS_GetSecurityLevel(ctx, &level); + } + /* No restrictions are imposed when Level is 0. */ + if (level <= HITLS_SECURITY_LEVEL_MIN) { + return SECURITY_SUCCESS; + } + /* Check the number of security bits. */ + minBits = SECURITY_GetSecbits(level); + switch (option) { + case HITLS_SECURITY_SECOP_VERSION: + /* Check the version. */ + ret = CheckVersion(id, level); + break; + case HITLS_SECURITY_SECOP_CIPHER_SUPPORTED: + case HITLS_SECURITY_SECOP_CIPHER_SHARED: + case HITLS_SECURITY_SECOP_CIPHER_CHECK: + /* Check the algorithm suite. */ + ret = CheckCipherSuite(other, level); + break; + case HITLS_SECURITY_SECOP_SIGALG_SUPPORTED: + case HITLS_SECURITY_SECOP_SIGALG_SHARED: + case HITLS_SECURITY_SECOP_SIGALG_CHECK: + /* Check the signature algorithm. */ + ret = CheckSigalg(id, level); + break; + case HITLS_SECURITY_SECOP_CURVE_SUPPORTED: + case HITLS_SECURITY_SECOP_CURVE_SHARED: + case HITLS_SECURITY_SECOP_CURVE_CHECK: + /* Check the group. */ + ret = CheckGroup(id, level); + break; + case HITLS_SECURITY_SECOP_TICKET: + /* Check the session ticket. */ + ret = CheckSessionTicket(level); + break; + default: + if (bits < minBits) { + return SECURITY_ERR; + } + return SECURITY_SUCCESS; + } + return ret; +} + +void SECURITY_SetDefault(HITLS_Config *config) +{ + if (config == NULL) { + return; + } + /* Default security settings. Set the default security level and default security callback function. */ + config->securityLevel = HITLS_DEFAULT_SECURITY_LEVEL; + config->securityCb = SECURITY_DefaultCb; + return; +} + +int32_t SECURITY_CfgCheck(HITLS_Config *config, int32_t option, int32_t bits, int32_t id, void *other) +{ + if (config == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + if (config->securityCb == NULL) { + /* The security callback function is empty and does not need to be checked. */ + return SECURITY_SUCCESS; + } + return config->securityCb(NULL, config, option, bits, id, other, config->securityExData); +} +int32_t SECURITY_SslCheck(HITLS_Ctx *ctx, int32_t option, int32_t bits, int32_t id, void *other) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + return SECURITY_CfgCheck(&(ctx->config.tlsConfig), option, bits, id, other); +} diff --git a/tls/feature/session/src/session.c b/tls/feature/session/src/session.c new file mode 100644 index 00000000..de125e9c --- /dev/null +++ b/tls/feature/session/src/session.c @@ -0,0 +1,671 @@ +/* + * 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 +#include +#include "securec.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "bsl_list.h" +#include "bsl_err_internal.h" +#include "bsl_errno.h" +#include "cert_method.h" +#include "cert.h" +#include "cert_mgr.h" +#include "session_type.h" +#include "session.h" + +#define MAX_PRINTF_BUF 1024 +#define CTIME_BUF 26 +/* RFC8446 8.3 Freshness Checks: For clients on the Internet, this + implies windows on the order of ten seconds to account for errors in + clocks and variations in measurements; other deployment scenarios may + have different needs. */ +#define TICKET_AGE_WINDOWS (10 * 1000) +#define MS_CONVERT 1000 +#define ONE_SECOND 1000 +/** + * Apply for a session + */ +HITLS_Session *HITLS_SESS_New(void) +{ + HITLS_Session *sess = (HITLS_Session *)BSL_SAL_Calloc(1u, sizeof(HITLS_Session)); + if (sess == NULL) { + return NULL; + } + + sess->certMgrCtx = SAL_CERT_MgrCtxNew(); + if (sess->certMgrCtx == NULL) { + BSL_SAL_FREE(sess); + return NULL; + } + + if (BSL_SAL_ThreadLockNew(&sess->lock) != BSL_SUCCESS) { + SAL_CERT_MgrCtxFree(sess->certMgrCtx); + BSL_SAL_FREE(sess); + return NULL; + } + + sess->startTime = (uint64_t)BSL_SAL_CurrentSysTimeGet(); // default value + sess->references = 1; + sess->enable = true; + sess->cipherSuite = HITLS_AES_128_GCM_SHA256; + return sess; +} + +/** + * To copy a session, increase the number of references by 1 + */ +HITLS_Session *HITLS_SESS_Dup(HITLS_Session *sess) +{ + if (sess == NULL) { + return NULL; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->references++; + BSL_SAL_ThreadUnlock(sess->lock); + + return sess; +} + +/** + * Increase the number of references by 1 + */ +void HITLS_SESS_UpRef(HITLS_Session *sess) +{ + if (sess == NULL) { + return; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->references++; + BSL_SAL_ThreadUnlock(sess->lock); + + return; +} + +void HITLS_SESS_Free(HITLS_Session *sess) +{ + if (sess != NULL) { + BSL_SAL_ThreadWriteLock(sess->lock); + sess->references--; + + if (sess->references > 0) { + BSL_SAL_ThreadUnlock(sess->lock); + return; + } + BSL_SAL_ThreadUnlock(sess->lock); + if (sess->peerCert != NULL) { + SAL_CERT_PairFree(sess->certMgrCtx, sess->peerCert); + } + sess->peerCert = NULL; + BSL_SAL_FREE(sess->ticket); + BSL_SAL_FREE(sess->hostName); + BSL_SAL_FREE(sess->pskIdentity); + memset_s(sess->masterKey, MAX_MASTER_KEY_SIZE, 0, MAX_MASTER_KEY_SIZE); + SAL_CERT_MgrCtxFree(sess->certMgrCtx); + BSL_SAL_ThreadLockFree(sess->lock); + BSL_SAL_FREE(sess); + } +} + +HITLS_Session *SESS_Copy(HITLS_Session *src) +{ + HITLS_Session *dest = (HITLS_Session *)BSL_SAL_Dump(src, sizeof(HITLS_Session)); + if (dest == NULL) { + return NULL; + } + + if (BSL_SAL_ThreadLockNew(&dest->lock) != BSL_SUCCESS) { + BSL_SAL_FREE(dest); + return NULL; + } + + dest->references = 1; + dest->enable = true; + + dest->peerCert = NULL; + dest->hostName = NULL; + dest->pskIdentity = NULL; + dest->ticket = NULL; + + dest->certMgrCtx = SAL_CERT_MgrCtxNew(); + if (dest->certMgrCtx == NULL) { + goto ERR; + } + + if (src->peerCert != NULL) { + dest->peerCert = SAL_CERT_PairDup(dest->certMgrCtx, src->peerCert); + if (dest->peerCert == NULL) { + goto ERR; + } + } + + if (src->hostNameSize > 0) { + if (SESS_SetHostName(dest, src->hostNameSize, src->hostName) != HITLS_SUCCESS) { + goto ERR; + } + } + + if (src->pskIdentitySize > 0) { + dest->pskIdentity = (uint8_t *)BSL_SAL_Calloc(1u, (src->pskIdentitySize + 1) * sizeof(uint8_t)); + if (dest->pskIdentity == NULL) { + goto ERR; + } + if (memcpy_s(dest->pskIdentity, src->pskIdentitySize + 1, src->pskIdentity, src->pskIdentitySize) != EOK) { + goto ERR; + } + dest->pskIdentitySize = src->pskIdentitySize; + } + + if (src->ticketSize > 0) { + if (SESS_SetTicket(dest, src->ticket, src->ticketSize) != HITLS_SUCCESS) { + goto ERR; + } + } + + return dest; +ERR: + HITLS_SESS_Free(dest); + return NULL; +} + +/* Simple judgment only */ +bool HITLS_SESS_IsResumable(const HITLS_Session *sess) +{ + bool isResumable = 0; + if (sess != NULL) { + BSL_SAL_ThreadReadLock(sess->lock); + isResumable = (sess->enable && (sess->sessionIdSize > 0 || sess->ticketSize > 0)); + BSL_SAL_ThreadUnlock(sess->lock); + } + return isResumable; +} +/** + * Session is deprecated + */ +void SESS_Disable(HITLS_Session *sess) +{ + if (sess != NULL) { + BSL_SAL_ThreadReadLock(sess->lock); + sess->enable = false; + BSL_SAL_ThreadUnlock(sess->lock); + } + return; +} + +int32_t HITLS_SESS_SetSessionIdCtx(HITLS_Session *sess, uint8_t *sessionIdCtx, uint32_t sessionIdCtxSize) +{ + if (sess == NULL || sessionIdCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + if (sessionIdCtxSize != 0 && + memcpy_s(sess->sessionIdCtx, sizeof(sess->sessionIdCtx), sessionIdCtx, sessionIdCtxSize) != EOK) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + /* The sessionIdCtxSize allowed value is 0 */ + sess->sessionIdCtxSize = sessionIdCtxSize; + + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_GetSessionIdCtx(const HITLS_Session *sess, uint8_t *sessionIdCtx, uint32_t *sessionIdCtxSize) +{ + if (sess == NULL || sessionIdCtx == NULL || sessionIdCtxSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + if (memcpy_s(sessionIdCtx, *sessionIdCtxSize, sess->sessionIdCtx, sess->sessionIdCtxSize) != EOK) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + *sessionIdCtxSize = sess->sessionIdCtxSize; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_SetSessionId(HITLS_Session *sess, uint8_t *sessionId, uint32_t sessionIdSize) +{ + if (sess == NULL || sessionId == NULL || sessionIdSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + if (memcpy_s(sess->sessionId, sizeof(sess->sessionId), sessionId, sessionIdSize) != EOK) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + sess->sessionIdSize = sessionIdSize; + + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_GetSessionId(const HITLS_Session *sess, uint8_t *sessionId, uint32_t *sessionIdSize) +{ + if (sess == NULL || sessionId == NULL || sessionIdSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + if (memcpy_s(sessionId, *sessionIdSize, sess->sessionId, sess->sessionIdSize) != EOK) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + *sessionIdSize = sess->sessionIdSize; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_SetHaveExtMasterSecret(HITLS_Session *sess, uint8_t haveExtMasterSecret) +{ + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->haveExtMasterSecret = (haveExtMasterSecret > 0); + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_GetHaveExtMasterSecret(HITLS_Session *sess, uint8_t *haveExtMasterSecret) +{ + if (sess == NULL || haveExtMasterSecret == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + *haveExtMasterSecret = (uint8_t)sess->haveExtMasterSecret; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +/* Set the server_name extension required for TLS1.2 session resumption */ +int32_t SESS_SetHostName(HITLS_Session *sess, uint32_t hostNameSize, uint8_t *hostName) +{ + if (sess == NULL || hostName == NULL || hostNameSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->hostName = (uint8_t *)BSL_SAL_Dump(hostName, hostNameSize * sizeof(uint8_t)); + if (sess->hostName == NULL) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + sess->hostNameSize = hostNameSize; + BSL_SAL_ThreadUnlock(sess->lock); + + return HITLS_SUCCESS; +} +/* Get the server_name extension required for TLS1.2 session resumption */ +int32_t SESS_GetHostName(HITLS_Session *sess, uint32_t *hostNameSize, uint8_t **hostName) +{ + if (sess == NULL || hostNameSize == NULL || hostName == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + *hostName = sess->hostName; + *hostNameSize = sess->hostNameSize; + BSL_SAL_ThreadUnlock(sess->lock); + + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_SetProtocolVersion(HITLS_Session *sess, uint16_t version) +{ + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->version = version; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_GetProtocolVersion(const HITLS_Session *sess, uint16_t *version) +{ + if (sess == NULL || version == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + *version = sess->version; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t SESS_SetPeerCert(HITLS_Session *sess, CERT_Pair *peerCert, bool isClient) +{ + int32_t ret = 0; + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->peerCert = peerCert; + /* The peer_cert_chain of the client stores the device certificate of the server */ + if (isClient && peerCert != NULL) { + /* Obtain the cert */ + HITLS_CERT_X509 *tmpCert = SAL_CERT_PairGetX509(peerCert); + if (tmpCert == NULL) { + /* If cert in CERT_Pair is empty, the unlocking is returned */ + ret = HITLS_SUCCESS; + goto EXIT; + } + /* Obtain the chain */ + HITLS_CERT_Chain *tmpChain = SAL_CERT_PairGetChain(peerCert); + if (tmpChain == NULL) { + /* If the chain in CERT_Pair is empty, unlocking is returned */ + ret = HITLS_SUCCESS; + goto EXIT; + } + + /* Make a copy of cert */ + HITLS_CERT_X509 *newSubjectCert = SAL_CERT_X509Dup(sess->certMgrCtx, tmpCert); + if (newSubjectCert == NULL) { + ret = HITLS_CERT_ERR_X509_DUP; + goto EXIT; + } + + ret = (int32_t)BSL_LIST_AddElement(tmpChain, newSubjectCert, BSL_LIST_POS_BEGIN); + if (ret != 0) { + SAL_CERT_X509Free(newSubjectCert); + goto EXIT; + } + } + + ret = HITLS_SUCCESS; +EXIT: + BSL_SAL_ThreadUnlock(sess->lock); + return ret; +} + +int32_t SESS_GetPeerCert(HITLS_Session *sess, CERT_Pair **peerCert) +{ + if (sess == NULL || peerCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + *peerCert = sess->peerCert; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +uint64_t SESS_GetStartTime(HITLS_Session *sess) +{ + if (sess == NULL) { + return 0; + } + + uint64_t startTime = 0u; + + BSL_SAL_ThreadReadLock(sess->lock); + startTime = sess->startTime; + BSL_SAL_ThreadUnlock(sess->lock); + + return startTime; +} + +int32_t SESS_SetStartTime(HITLS_Session *sess, uint64_t startTime) +{ + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->startTime = startTime; + BSL_SAL_ThreadUnlock(sess->lock); + + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_SetTimeout(HITLS_Session *sess, uint64_t timeout) +{ + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->timeout = timeout; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_SetCipherSuite(HITLS_Session *sess, uint16_t cipherSuite) +{ + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + sess->cipherSuite = cipherSuite; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} +int32_t HITLS_SESS_GetCipherSuite(HITLS_Session *sess, uint16_t *cipherSuite) +{ + if (sess == NULL || cipherSuite == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + *cipherSuite = sess->cipherSuite; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t HITLS_SESS_SetMasterKey(HITLS_Session *sess, const uint8_t *masterKey, uint32_t masterKeySize) +{ + if (sess == NULL || masterKey == NULL || masterKeySize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + if (memcpy_s(sess->masterKey, sizeof(sess->masterKey), masterKey, masterKeySize) != EOK) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + sess->masterKeySize = masterKeySize; + + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +uint32_t HITLS_SESS_GetMasterKeyLen(const HITLS_Session *sess) +{ + uint32_t masterKeySize = 0; + if (sess == NULL) { + return 0; + } + + BSL_SAL_ThreadReadLock(sess->lock); + masterKeySize = sess->masterKeySize; + BSL_SAL_ThreadUnlock(sess->lock); + return masterKeySize; +} + +int32_t HITLS_SESS_GetMasterKey(const HITLS_Session *sess, uint8_t *masterKey, uint32_t *masterKeySize) +{ + if (sess == NULL || masterKey == NULL || masterKeySize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + if (memcpy_s(masterKey, *masterKeySize, sess->masterKey, sess->masterKeySize) != EOK) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + *masterKeySize = sess->masterKeySize; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t SESS_SetTicket(HITLS_Session *sess, uint8_t *ticket, uint32_t ticketSize) +{ + if (sess == NULL || ticket == NULL || ticketSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + + BSL_SAL_FREE(sess->ticket); + sess->ticket = (uint8_t *)BSL_SAL_Dump(ticket, ticketSize); + if (sess->ticket == NULL) { + BSL_SAL_ThreadUnlock(sess->lock); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + sess->ticketSize = ticketSize; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +int32_t SESS_GetTicket(const HITLS_Session *sess, uint8_t **ticket, uint32_t *ticketSize) +{ + if (sess == NULL || ticket == NULL || ticketSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(sess->lock); + *ticket = sess->ticket; + *ticketSize = sess->ticketSize; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +bool HITLS_SESS_HasTicket(const HITLS_Session *sess) +{ + if (sess == NULL) { + return false; + } + + bool flag = 0; + BSL_SAL_ThreadReadLock(sess->lock); + flag = (sess->ticket != NULL); + BSL_SAL_ThreadUnlock(sess->lock); + + return flag; +} + +bool SESS_CheckValidity(HITLS_Session *sess, uint64_t curTime) +{ + if (sess == NULL) { + return false; + } + + bool flag = false; + + BSL_SAL_ThreadReadLock(sess->lock); + if ((sess->enable) && (curTime < sess->startTime + sess->timeout)) { + flag = true; + } + BSL_SAL_ThreadUnlock(sess->lock); + + return flag; +} + +bool SESS_CheckObfuscatedTicketAge(HITLS_Session *sess, uint64_t curTime, uint64_t obfuscatedTicketAge) +{ + if (sess == NULL) { + return false; + } + + bool flag = false; + BSL_SAL_ThreadReadLock(sess->lock); + uint64_t ticketTmLocal = curTime - sess->startTime; + uint64_t ticketTmLocalMs = ticketTmLocal * MS_CONVERT; + uint64_t ticketAgeClient = obfuscatedTicketAge - sess->ticketAgeAdd; + if ((sess->enable) && (curTime < sess->startTime + sess->timeout) && + ((ticketTmLocalMs / (uint64_t)MS_CONVERT) == ticketTmLocal) && + ticketAgeClient <= ticketTmLocalMs + ONE_SECOND && + ticketAgeClient + TICKET_AGE_WINDOWS >= ticketTmLocalMs + ONE_SECOND) { + flag = true; + } + BSL_SAL_ThreadUnlock(sess->lock); + + return flag; +} + +int32_t SESS_SetTicketAgeAdd(HITLS_Session *sess, uint32_t ticketAgeAdd) +{ + if (sess == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(sess->lock); + sess->ticketAgeAdd = ticketAgeAdd; + BSL_SAL_ThreadUnlock(sess->lock); + return HITLS_SUCCESS; +} + +uint32_t SESS_GetTicketAgeAdd(const HITLS_Session *sess) +{ + uint32_t ticketAgeAdd = 0; + if (sess == NULL) { + return 0; + } + + BSL_SAL_ThreadReadLock(sess->lock); + ticketAgeAdd = sess->ticketAgeAdd; + BSL_SAL_ThreadUnlock(sess->lock); + return ticketAgeAdd; +} diff --git a/tls/feature/session/src/session_dec.c b/tls/feature/session/src/session_dec.c new file mode 100644 index 00000000..0103959f --- /dev/null +++ b/tls/feature/session/src/session_dec.c @@ -0,0 +1,449 @@ +/* + * 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 +#include "securec.h" +#include "tlv.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "tls_binlog_id.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "session_enc.h" +#include "session_type.h" +#include "cert_mgr_ctx.h" +#include "cert_method.h" +#include "parse_common.h" + +#define MAX_PSK_IDENTITY_LEN 0xffff +#define MAX_HOST_NAME_LEN 0xff + +typedef int32_t (*PfuncDecSessionObjFunc)(HITLS_Session *sess, SessionObjType type, const uint8_t *data, + uint32_t length, uint32_t *readLen); + +typedef struct { + SessionObjType type; + PfuncDecSessionObjFunc func; +} SessObjDecFunc; + +static int32_t DecSessObjVersion(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint16_t version = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(version); + tlv.value = (uint8_t *)&version; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_VERSION_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15993, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj version fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_VERSION_FAIL; + } + + sess->version = version; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjCipherSuite(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint16_t cipherSuite = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(cipherSuite); + tlv.value = (uint8_t *)&cipherSuite; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_CIPHER_SUITE_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15994, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj cipher suite fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_CIPHER_SUITE_FAIL; + } + + sess->cipherSuite = cipherSuite; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjMasterSecret(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + BSL_Tlv tlv = {0}; + tlv.length = MAX_MASTER_KEY_SIZE; + tlv.value = sess->masterKey; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_MASTER_SECRET_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15995, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj master secret fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_MASTER_SECRET_FAIL; + } + + sess->masterKeySize = tlv.length; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjPskIdentity(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint32_t offset = sizeof(uint32_t); + // The length has been verified at the upper layer and must be greater than 8 bytes. + uint32_t tlvLen = BSL_ByteToUint32(&data[offset]); + if (tlvLen > MAX_PSK_IDENTITY_LEN || tlvLen == 0) { + return HITLS_SESS_ERR_DEC_PSK_IDENTITY_FAIL; + } + uint8_t *pskIdentity = BSL_SAL_Calloc(1u, tlvLen); + if (pskIdentity == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15996, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc pskIdentity fail when decode session obj psk identity.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + BSL_Tlv tlv = {0}; + tlv.length = tlvLen; + tlv.value = pskIdentity; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_SAL_FREE(pskIdentity); + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_PSK_IDENTITY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15997, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj psk identity fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_PSK_IDENTITY_FAIL; + } + + sess->pskIdentity = tlv.value; + sess->pskIdentitySize = tlv.length; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjStartTime(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint64_t startTime = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(startTime); + tlv.value = (uint8_t *)&startTime; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_START_TIME_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15998, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj start time fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_START_TIME_FAIL; + } + + sess->startTime = startTime; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjTimeout(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint64_t timeout = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(timeout); + tlv.value = (uint8_t *)&timeout; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_TIME_OUT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15999, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj timeout fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_TIME_OUT_FAIL; + } + + sess->timeout = timeout; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjHostName(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint32_t offset = sizeof(uint32_t); + // The length has been verified at the upper layer and must be greater than 8 bytes. + uint32_t tlvLen = BSL_ByteToUint32(&data[offset]); + if (tlvLen > MAX_HOST_NAME_LEN || tlvLen == 0) { + return HITLS_SESS_ERR_DEC_HOST_NAME_FAIL; + } + uint8_t *hostName = BSL_SAL_Calloc(1u, tlvLen); + if (hostName == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16000, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc hostName fail when decode session obj host name.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + BSL_Tlv tlv = {0}; + tlv.length = tlvLen; + tlv.value = hostName; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_SAL_FREE(hostName); + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_HOST_NAME_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj host name fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_HOST_NAME_FAIL; + } + + sess->hostName = tlv.value; + sess->hostNameSize = tlv.length; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjSessionIdCtx(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + BSL_Tlv tlv = {0}; + tlv.length = HITLS_SESSION_ID_MAX_SIZE; + tlv.value = sess->sessionIdCtx; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_SESSION_ID_CTX_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj session id ctx fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_SESSION_ID_CTX_FAIL; + } + + sess->sessionIdCtxSize = tlv.length; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjSessionId(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + BSL_Tlv tlv = {0}; + tlv.length = HITLS_SESSION_ID_MAX_SIZE; + tlv.value = sess->sessionId; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_SESSION_ID_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16003, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj session id fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_SESSION_ID_FAIL; + } + + sess->sessionIdSize = tlv.length; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjExtendMasterSecret(HITLS_Session *sess, SessionObjType type, const uint8_t *data, + uint32_t length, uint32_t *readLen) +{ + int32_t ret; + uint8_t haveExtMasterSecret = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(haveExtMasterSecret); + tlv.value = &haveExtMasterSecret; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_EXT_MASTER_SECRET_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16004, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj extend master secret fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_EXT_MASTER_SECRET_FAIL; + } + + sess->haveExtMasterSecret = (bool)haveExtMasterSecret; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjVerifyResult(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint32_t verifyResult = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(verifyResult); + tlv.value = (uint8_t *)&verifyResult; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_VERIFY_RESULT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16005, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj verify result fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_VERIFY_RESULT_FAIL; + } + + sess->verifyResult = (int32_t)verifyResult; + return HITLS_SUCCESS; +} + +static int32_t ParseBufToCert(HITLS_Session *sess, const uint8_t *buf, uint32_t bufLen) +{ + if (bufLen < CERT_LEN_TAG_SIZE) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16057, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode certLen fail.", bufLen, 0, 0, 0); + return HITLS_PARSE_INVALID_MSG_LEN; + } + uint32_t offset = 0; + uint32_t certLen = BSL_ByteToUint24(buf); /* Obtain the certificate length */ + offset += CERT_LEN_TAG_SIZE; + + if (certLen != (bufLen - offset)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16058, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode certLen fail.", 0, 0, 0, 0); + return HITLS_PARSE_INVALID_MSG_LEN; + } + CERT_MgrCtx *certMgrCtx = sess->certMgrCtx; + if (certMgrCtx == NULL || certMgrCtx->method.certParse == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16059, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "certMgrCtx or certMgrCtx->method.certParse is null.", 0, 0, 0, 0); + return HITLS_NULL_INPUT; + } + + /* Parse the first device certificate. */ + HITLS_CERT_X509 *cert = certMgrCtx->method.certParse(NULL, &buf[offset], certLen, + TLS_PARSE_TYPE_BUFF, TLS_PARSE_FORMAT_ASN1); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16060, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse peer eecert error", 0, 0, 0, 0); + return HITLS_CERT_ERR_PARSE_MSG; + } + + CERT_Pair *newCertPair = BSL_SAL_Calloc(1u, sizeof(CERT_Pair)); + if (newCertPair == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16061, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "peer cert malloc fail.", 0, 0, 0, 0); + SAL_CERT_X509Free(cert); + return HITLS_MEMALLOC_FAIL; + } + newCertPair->cert = cert; + sess->peerCert = newCertPair; + return HITLS_SUCCESS; +} + +static int32_t DecSessObjPeerCert(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + (void)type; + uint32_t offset = sizeof(uint32_t); + // The length has been verified at the upper layer and must be greater than 8 bytes. + uint32_t tlvLen = BSL_ByteToUint32(&data[offset]); + offset += sizeof(uint32_t); + if ((tlvLen == 0) || (tlvLen > length - offset)) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_PEER_CERT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16062, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode peercert fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_PEER_CERT_FAIL; + } + + *readLen = tlvLen + offset; + return ParseBufToCert(sess, &data[offset], tlvLen); +} + +static int32_t DecSessObjTicketAgeAdd(HITLS_Session *sess, SessionObjType type, const uint8_t *data, uint32_t length, + uint32_t *readLen) +{ + int32_t ret; + uint32_t ticketAgeAdd = 0; + BSL_Tlv tlv = {0}; + tlv.length = sizeof(ticketAgeAdd); + tlv.value = (uint8_t *)&ticketAgeAdd; + + ret = BSL_TLV_Parse(type, data, length, &tlv, readLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DEC_START_TIME_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15975, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decode session obj TicketAgeAdd fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_DEC_START_TIME_FAIL; + } + + sess->ticketAgeAdd = ticketAgeAdd; + return HITLS_SUCCESS; +} + +/** + * Decoding function list. + * Ensure that the sequence of decode and encode types is the same. + */ +static const SessObjDecFunc OBJ_LIST[] = { + {SESS_OBJ_VERSION, DecSessObjVersion}, + {SESS_OBJ_CIPHER_SUITE, DecSessObjCipherSuite}, + {SESS_OBJ_MASTER_SECRET, DecSessObjMasterSecret}, + {SESS_OBJ_PEER_CERT, DecSessObjPeerCert}, + {SESS_OBJ_PSK_IDENTITY, DecSessObjPskIdentity}, + {SESS_OBJ_START_TIME, DecSessObjStartTime}, + {SESS_OBJ_TIMEOUT, DecSessObjTimeout}, + {SESS_OBJ_HOST_NAME, DecSessObjHostName}, + {SESS_OBJ_SESSION_ID_CTX, DecSessObjSessionIdCtx}, + {SESS_OBJ_SESSION_ID, DecSessObjSessionId}, + {SESS_OBJ_SUPPORT_EXTEND_MASTER_SECRET, DecSessObjExtendMasterSecret}, + {SESS_OBJ_VERIFY_RESULT, DecSessObjVerifyResult}, + {SESS_OBJ_AGE_ADD, DecSessObjTicketAgeAdd}, +}; + +int32_t SESS_Decode(HITLS_Session *sess, const uint8_t *data, uint32_t length) +{ + if (sess == NULL || data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16006, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESS_Decode input parameter is NULL.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret; + uint32_t index; + const uint8_t *curPos = data; + uint32_t offset = 0; + uint32_t readLen = 0; + + for (index = 0; index < sizeof(OBJ_LIST) / sizeof(SessObjDecFunc); index++) { + if (length - offset < TLV_HEADER_LENGTH) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DECODE_TICKET); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16009, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESS_Decode length error, offset is %u, length is %u.", offset, length, 0, 0); + return HITLS_SESS_ERR_DECODE_TICKET; + } + + uint32_t type = BSL_ByteToUint32(curPos); + if (OBJ_LIST[index].type != type) { + continue; + } + readLen = 0; + ret = OBJ_LIST[index].func(sess, OBJ_LIST[index].type, curPos, length - offset, &readLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += readLen; + curPos += readLen; + } + if (offset != length) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_DECODE_TICKET); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16007, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESS_Decode fail, offset is %u, length is %u.", offset, length, 0, 0); + return HITLS_SESS_ERR_DECODE_TICKET; + } + + return HITLS_SUCCESS; +} diff --git a/tls/feature/session/src/session_enc.c b/tls/feature/session/src/session_enc.c new file mode 100644 index 00000000..5ceee325 --- /dev/null +++ b/tls/feature/session/src/session_enc.c @@ -0,0 +1,535 @@ +/* + * 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 "tlv.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "tls_binlog_id.h" +#include "bsl_bytes.h" +#include "bsl_list.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "session_type.h" +#include "cert_mgr_ctx.h" +#include "session_enc.h" + +typedef int32_t (*PfuncEncSessionObjFunc)(const HITLS_Session *sess, SessionObjType type, uint8_t *data, + uint32_t length, uint32_t *encLen); + +typedef struct { + SessionObjType type; + PfuncEncSessionObjFunc func; +} SessObjEncFunc; + +static int32_t EncSessObjVersion(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + uint16_t version = sess->version; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(version); + tlv.value = (uint8_t *)&version; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_VERSION_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15992, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj version fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_VERSION_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjCipherSuite(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + uint16_t cipherSuite = sess->cipherSuite; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(cipherSuite); + tlv.value = (uint8_t *)&cipherSuite; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_CIPHER_SUITE_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15982, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj cipher suite fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_CIPHER_SUITE_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjMasterSecret(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sess->masterKeySize; + tlv.value = (uint8_t *)sess->masterKey; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_MASTER_SECRET_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15983, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj master secret fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_MASTER_SECRET_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjPskIdentity(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + if (sess->pskIdentitySize == 0) { + return HITLS_SUCCESS; + } + + int ret; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sess->pskIdentitySize; + tlv.value = (uint8_t *)sess->pskIdentity; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_PSK_IDENTITY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15984, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj psk identity fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_PSK_IDENTITY_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjStartTime(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + uint64_t startTime = sess->startTime; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(startTime); + tlv.value = (uint8_t *)&startTime; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_START_TIME_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15985, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj start time fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_START_TIME_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjTimeout(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + uint64_t timeout = sess->timeout; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(timeout); + tlv.value = (uint8_t *)&timeout; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_TIME_OUT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15986, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj timeout fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_TIME_OUT_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjHostName(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + if (sess->hostNameSize == 0) { + return HITLS_SUCCESS; + } + + int ret; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sess->hostNameSize; + tlv.value = (uint8_t *)sess->hostName; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_HOST_NAME_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15987, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj host name fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_HOST_NAME_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjSessionIdCtx(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + if (sess->sessionIdCtxSize == 0) { + return HITLS_SUCCESS; + } + + int ret; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sess->sessionIdCtxSize; + tlv.value = (uint8_t *)sess->sessionIdCtx; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_SESSION_ID_CTX_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15988, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj session id ctx fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_SESSION_ID_CTX_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjSessionId(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + if (sess->sessionIdSize == 0) { + return HITLS_SUCCESS; + } + + int ret; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sess->sessionIdSize; + tlv.value = (uint8_t *)sess->sessionId; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_SESSION_ID_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15989, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj session id fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_SESSION_ID_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjExtendMasterSecret(const HITLS_Session *sess, SessionObjType type, uint8_t *data, + uint32_t length, uint32_t *encLen) +{ + int ret; + uint8_t haveExtMasterSecret = (uint8_t)sess->haveExtMasterSecret; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(haveExtMasterSecret); + tlv.value = (uint8_t *)&haveExtMasterSecret; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_EXT_MASTER_SECRET_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15990, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj extend master secret fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_EXT_MASTER_SECRET_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjVerifyResult(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + int32_t verifyResult = sess->verifyResult; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(verifyResult); + tlv.value = (uint8_t *)&verifyResult; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15991, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj verify result fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t PackCertToBuf(const HITLS_Session *sess, uint8_t *buf, uint32_t bufLen) +{ + CERT_Pair *peerCert = sess->peerCert; + HITLS_CERT_X509 *cert = peerCert->cert; + CERT_MgrCtx *mgrCtx = sess->certMgrCtx; + if (mgrCtx->method.certEncode == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16063, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "mgrCtx->method.certEncode is null.", 0, 0, 0, 0); + return HITLS_NULL_INPUT; + } + uint32_t encodeLen = 0; + /* Write the certificate data. */ + int32_t ret = mgrCtx->method.certEncode(NULL, cert, &buf[CERT_LEN_TAG_SIZE], + bufLen - CERT_LEN_TAG_SIZE, &encodeLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16064, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "certEncode error.", 0, 0, 0, 0); + return HITLS_CERT_ERR_ENCODE_CERT; + } + if (bufLen - CERT_LEN_TAG_SIZE != encodeLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encodeLen error.", 0, 0, 0, 0); + return HITLS_CERT_ERR_ENCODE_CERT; + } + BSL_Uint24ToByte(encodeLen, buf); + + return HITLS_SUCCESS; +} + +static int32_t GetPeertCertSize(const HITLS_Session *sess) +{ + uint32_t certLen = 0; + CERT_Pair *peerCert = sess->peerCert; + CERT_MgrCtx *mgrCtx = sess->certMgrCtx; + if (mgrCtx == NULL || mgrCtx->method.certCtrl == NULL || peerCert->cert == NULL) { + return 0; + } + int32_t ret = mgrCtx->method.certCtrl(NULL, peerCert->cert, CERT_CTRL_GET_ENCODE_LEN, NULL, (void *)&certLen); + if (ret != HITLS_SUCCESS || certLen == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16066, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CERT_CTRL_GET_ENCODE_LEN error.", 0, 0, 0, 0); + return 0; + } + return certLen + CERT_LEN_TAG_SIZE; +} + +static int32_t EncSessObjPeerCert(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + CERT_Pair *peerCert = sess->peerCert; + if (peerCert == NULL) { + return HITLS_SUCCESS; + } + uint32_t bufLen = GetPeertCertSize(sess); + if (bufLen == 0) { + return HITLS_SUCCESS; + } + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = bufLen; + + if (data == NULL) { + /* If the input parameter is NULL, return the length after encoding. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + uint8_t *buf = BSL_SAL_Calloc(1u, bufLen); + if (buf == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16067, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "buf malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + int32_t ret = PackCertToBuf(sess, buf, bufLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(buf); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16068, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "PackCertToBuf fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_PEER_CERT_FAIL; + } + tlv.value = buf; + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + BSL_SAL_FREE(buf); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_PEER_CERT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16069, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj peer cert fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_PEER_CERT_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t EncSessObjTicketAgeAdd(const HITLS_Session *sess, SessionObjType type, uint8_t *data, uint32_t length, + uint32_t *encLen) +{ + int ret; + uint32_t ticketAgeAdd = sess->ticketAgeAdd; + BSL_Tlv tlv = {0}; + tlv.type = type; + tlv.length = sizeof(ticketAgeAdd); + tlv.value = (uint8_t *)&ticketAgeAdd; + + if (data == NULL) { + /* If the input parameter is NULL, the length after encoding is returned. */ + *encLen = sizeof(tlv.type) + sizeof(tlv.length) + tlv.length; + return HITLS_SUCCESS; + } + + ret = BSL_TLV_Pack(&tlv, data, length, encLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15562, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode session obj TicketAgeAdd fail.", 0, 0, 0, 0); + return HITLS_SESS_ERR_ENC_VERIFY_RESULT_FAIL; + } + + return HITLS_SUCCESS; +} + +/** + * Encoding function list. + * Ensure that the sequence of decode and encode types is the same. + */ +static const SessObjEncFunc OBJ_LIST[] = { + {SESS_OBJ_VERSION, EncSessObjVersion}, + {SESS_OBJ_CIPHER_SUITE, EncSessObjCipherSuite}, + {SESS_OBJ_MASTER_SECRET, EncSessObjMasterSecret}, + {SESS_OBJ_PEER_CERT, EncSessObjPeerCert}, + {SESS_OBJ_PSK_IDENTITY, EncSessObjPskIdentity}, + {SESS_OBJ_START_TIME, EncSessObjStartTime}, + {SESS_OBJ_TIMEOUT, EncSessObjTimeout}, + {SESS_OBJ_HOST_NAME, EncSessObjHostName}, + {SESS_OBJ_SESSION_ID_CTX, EncSessObjSessionIdCtx}, + {SESS_OBJ_SESSION_ID, EncSessObjSessionId}, + {SESS_OBJ_SUPPORT_EXTEND_MASTER_SECRET, EncSessObjExtendMasterSecret}, + {SESS_OBJ_VERIFY_RESULT, EncSessObjVerifyResult}, + {SESS_OBJ_AGE_ADD, EncSessObjTicketAgeAdd}, +}; + +uint32_t SESS_GetTotalEncodeSize(const HITLS_Session *sess) +{ + if (sess == NULL) { + return 0; + } + + uint32_t index; + uint32_t offset = 0; + uint32_t encLen = 0; + + for (index = 0; index < sizeof(OBJ_LIST) / sizeof(SessObjEncFunc); index++) { + encLen = 0; + /* This parameter is used only to obtain the encoded length and will not verified the returned value. */ + (void)OBJ_LIST[index].func(sess, OBJ_LIST[index].type, NULL, 0, &encLen); + offset += encLen; + } + + return offset; +} + +int32_t SESS_Encode(const HITLS_Session *sess, uint8_t *data, uint32_t length, uint32_t *usedLen) +{ + if (sess == NULL || data == NULL || usedLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16008, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESS_Encode input parameter is NULL.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret; + uint32_t index; + uint8_t *curPos = data; + uint32_t offset = 0; + uint32_t encLen = 0; + + for (index = 0; index < sizeof(OBJ_LIST) / sizeof(SessObjEncFunc); index++) { + encLen = 0; + ret = OBJ_LIST[index].func(sess, OBJ_LIST[index].type, curPos, length - offset, &encLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += encLen; + curPos += encLen; + } + + *usedLen = offset; + return HITLS_SUCCESS; +} diff --git a/tls/feature/session/src/session_enc.h b/tls/feature/session/src/session_enc.h new file mode 100644 index 00000000..09c802fc --- /dev/null +++ b/tls/feature/session/src/session_enc.h @@ -0,0 +1,84 @@ +/* + * 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 SESSION_ENC_H +#define SESSION_ENC_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Enumerated value of session information + * Do not change the enumerated value. If need add the enumerated value, add at the end + */ +typedef enum { + SESS_OBJ_VERSION = 0x0101, + SESS_OBJ_CIPHER_SUITE = 0x0102, + SESS_OBJ_MASTER_SECRET = 0x0103, + SESS_OBJ_PEER_CERT = 0x0104, + SESS_OBJ_PSK_IDENTITY = 0x0105, + SESS_OBJ_START_TIME = 0x0106, + SESS_OBJ_TIMEOUT = 0x0107, + SESS_OBJ_HOST_NAME = 0x0108, + SESS_OBJ_SESSION_ID_CTX = 0x0109, + SESS_OBJ_SESSION_ID = 0x010A, + SESS_OBJ_SUPPORT_EXTEND_MASTER_SECRET = 0x010B, + SESS_OBJ_VERIFY_RESULT = 0x010C, + SESS_OBJ_AGE_ADD = 0x010D, +} SessionObjType; + +/** + * @brief Obtain the length of the encoded SESS information + * + * @param sess [IN] sess structure + * + * @retval Length of the encoded data + */ +uint32_t SESS_GetTotalEncodeSize(const HITLS_Session *sess); + +/** + * @brief Encode the SESS information to generate data + * + * @param sess [IN] sess structure + * @param data [OUT] Packed data + * @param length [IN] Maximum length of the data array + * @param usedLen [OUT] Data length after packing + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t SESS_Encode(const HITLS_Session *sess, uint8_t *data, uint32_t length, uint32_t *usedLen); + +/** + * @brief Decode data into SESS information + * + * @param sess [OUT] sess structure + * @param data [IN] Data to be parsed + * @param length [IN] Length of the data to be parsed + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t SESS_Decode(HITLS_Session *sess, const uint8_t *data, uint32_t length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/feature/session/src/session_mgr.c b/tls/feature/session/src/session_mgr.c new file mode 100644 index 00000000..6319319f --- /dev/null +++ b/tls/feature/session/src/session_mgr.c @@ -0,0 +1,465 @@ +/* + * 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 +#include "securec.h" +#include "bsl_sal.h" +#include "sal_time.h" +#include "bsl_hash.h" +#include "hitls_error.h" +#include "session.h" +#include "bsl_errno.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "crypt.h" +#include "tls.h" +#include "session_type.h" +#include "session_mgr.h" + +#define SESSION_DEFAULT_TIMEOUT 7200u +#define SESSION_DEFAULT_CACHE_SIZE 256u + +#define SESSION_DEFAULT_HASH_BKT_SZIE 64u + +#define SESSION_GERNERATE_RETRY_MAX_TIMES 10 + +typedef struct { + uint32_t sessionIdSize; + uint8_t sessionId[HITLS_SESSION_ID_MAX_SIZE]; +} SessionKey; + +/* For details about the SessKey hash function, see BSL_CstlHashCodeCalcStr */ +static uint32_t SessKeyHashCodeCal(uintptr_t key, uint32_t bktSize) +{ + if (bktSize == 0) { + return 0; + } + + SessionKey *tmpKey = (SessionKey *)key; + uint32_t hashCode = BSL_HASH_CodeCalc(tmpKey, sizeof(SessionKey)); + return hashCode % bktSize; +} + +static bool SessKeyHashMacth(uintptr_t key1, uintptr_t key2) +{ + SessionKey *tkey1 = (SessionKey *)key1; + SessionKey *tkey2 = (SessionKey *)key2; + + if (memcmp(tkey1, tkey2, sizeof(SessionKey)) == 0) { + return true; + } + + return false; +} + +/* Session key copy function, which returns the address for storing character strings */ +static void *SessKeyDupFunc(void *src, size_t size) +{ + if (src == NULL || size == 0) { + return NULL; + } + + SessionKey *dupKey = (SessionKey *)BSL_SAL_Dump(src, (uint32_t)size); + + return (void *)dupKey; +} + +static void SessKeyFreeFunc(void *ptr) +{ + BSL_SAL_FREE(ptr); + return; +} + +/* Session copy function */ +static void *SessionDupFunc(void *src, size_t size) +{ + (void)size; + return (void *)HITLS_SESS_Dup((HITLS_Session *)src); +} + +static void SessionFreeFunc(void *ptr) +{ + HITLS_SESS_Free((HITLS_Session *)ptr); + return; +} + +TLS_SessionMgr *SESSMGR_New(void) +{ + TLS_SessionMgr *mgr = (TLS_SessionMgr *)BSL_SAL_Calloc(1u, sizeof(TLS_SessionMgr)); + if (mgr == NULL) { + return NULL; + } + + if (BSL_SAL_ThreadLockNew(&mgr->lock) != BSL_SUCCESS) { + BSL_SAL_FREE(mgr); + return NULL; + } + + /* Prepare the default ticket key */ + if (SAL_CRYPT_Rand(mgr->ticketKeyName, sizeof(mgr->ticketKeyName)) != HITLS_SUCCESS || + SAL_CRYPT_Rand(mgr->ticketAesKey, sizeof(mgr->ticketAesKey)) != HITLS_SUCCESS || + SAL_CRYPT_Rand(mgr->ticketHmacKey, sizeof(mgr->ticketHmacKey)) != HITLS_SUCCESS) { + BSL_SAL_ThreadLockFree(mgr->lock); + BSL_SAL_FREE(mgr); + return NULL; + } + + // Apply for a hash table from mgr->hash + ListDupFreeFuncPair keyFunc = {.dupFunc = SessKeyDupFunc, .freeFunc = SessKeyFreeFunc}; + ListDupFreeFuncPair valueFunc = {.dupFunc = SessionDupFunc, .freeFunc = SessionFreeFunc}; + mgr->hash = BSL_HASH_Create(SESSION_DEFAULT_HASH_BKT_SZIE, + SessKeyHashCodeCal, SessKeyHashMacth, &keyFunc, &valueFunc); + if (mgr->hash == NULL) { + BSL_SAL_ThreadLockFree(mgr->lock); + BSL_SAL_FREE(mgr); + return NULL; + } + + mgr->sessCacheMode = HITLS_SESS_CACHE_SERVER; + mgr->sessCacheSize = SESSION_DEFAULT_CACHE_SIZE; + mgr->sessTimeout = SESSION_DEFAULT_TIMEOUT; + mgr->references = 1; + return mgr; +} + +/* Copy the number of references. The number of references increases by 1 */ +TLS_SessionMgr *SESSMGR_Dup(TLS_SessionMgr *mgr) +{ + if (mgr == NULL) { + return NULL; + } + + BSL_SAL_ThreadWriteLock(mgr->lock); + mgr->references++; + BSL_SAL_ThreadUnlock(mgr->lock); + + return mgr; +} + +void SESSMGR_Free(TLS_SessionMgr *mgr) +{ + if (mgr != NULL) { + BSL_SAL_ThreadWriteLock(mgr->lock); + mgr->references--; + if (mgr->references > 0) { + BSL_SAL_ThreadUnlock(mgr->lock); + return; + } + BSL_SAL_ThreadUnlock(mgr->lock); + + // Delete all sessions + BSL_HASH_Destory(mgr->hash); + mgr->hash = NULL; + + BSL_SAL_ThreadLockFree(mgr->lock); + BSL_SAL_FREE(mgr); + } + return; +} + +void SESSMGR_SetTimeout(TLS_SessionMgr *mgr, uint64_t sessTimeout) +{ + if (mgr != NULL) { + BSL_SAL_ThreadWriteLock(mgr->lock); + mgr->sessTimeout = sessTimeout; + BSL_SAL_ThreadUnlock(mgr->lock); + } + return; +} + +uint64_t SESSMGR_GetTimeout(TLS_SessionMgr *mgr) +{ + if (mgr == NULL) { + return SESSION_DEFAULT_TIMEOUT; + } + uint64_t sessTimeout; + BSL_SAL_ThreadReadLock(mgr->lock); + sessTimeout = mgr->sessTimeout; + BSL_SAL_ThreadUnlock(mgr->lock); + + return sessTimeout; +} + +void SESSMGR_SetCacheMode(TLS_SessionMgr *mgr, HITLS_SESS_CACHE_MODE mode) +{ + if (mgr != NULL) { + BSL_SAL_ThreadWriteLock(mgr->lock); + mgr->sessCacheMode = mode; + BSL_SAL_ThreadUnlock(mgr->lock); + } + return; +} + +HITLS_SESS_CACHE_MODE SESSMGR_GetCacheMode(TLS_SessionMgr *mgr) +{ + HITLS_SESS_CACHE_MODE mode; + BSL_SAL_ThreadReadLock(mgr->lock); + mode = mgr->sessCacheMode; + BSL_SAL_ThreadUnlock(mgr->lock); + + return mode; +} + +/* Set the maximum number of cache sessions */ +void SESSMGR_SetCacheSize(TLS_SessionMgr *mgr, uint32_t sessCacheSize) +{ + if (mgr != NULL) { + BSL_SAL_ThreadWriteLock(mgr->lock); + mgr->sessCacheSize = sessCacheSize; + BSL_SAL_ThreadUnlock(mgr->lock); + } + return; +} + +/* Obtain the maximum number of cached sessions. Ensure that the pointer is not NULL */ +uint32_t SESSMGR_GetCacheSize(TLS_SessionMgr *mgr) +{ + uint32_t sessCacheSize = 0u; + BSL_SAL_ThreadReadLock(mgr->lock); + sessCacheSize = mgr->sessCacheSize; + BSL_SAL_ThreadUnlock(mgr->lock); + + return sessCacheSize; +} + +void SESSMGR_InsertSession(TLS_SessionMgr *mgr, HITLS_Session *sess, bool isClient) +{ + if (mgr == NULL || sess == NULL) { + return; + } + + BSL_SAL_ThreadReadLock(mgr->lock); + HITLS_SESS_CACHE_MODE mode = mgr->sessCacheMode; + BSL_SAL_ThreadUnlock(mgr->lock); + + SessionKey key = {0}; + key.sessionIdSize = sizeof(key.sessionId); + if (HITLS_SESS_GetSessionId(sess, key.sessionId, &(key.sessionIdSize)) != HITLS_SUCCESS) { + return; + } + + if (key.sessionIdSize == 0) { + return; + } + + if (mode == HITLS_SESS_CACHE_NO) { + return; + } + + if (isClient == true && mode == HITLS_SESS_CACHE_SERVER) { + return; + } + + if (isClient == false && mode == HITLS_SESS_CACHE_CLIENT) { + return; + } + + BSL_SAL_ThreadWriteLock(mgr->lock); + + if (BSL_HASH_Size(mgr->hash) < mgr->sessCacheSize) { + /* Insert a session node */ + BSL_HASH_Insert(mgr->hash, (uintptr_t)&key, sizeof(key), (uintptr_t)sess, 0); + } + + BSL_SAL_ThreadUnlock(mgr->lock); + return; +} + +/* Find the matching session */ +HITLS_Session *SESSMGR_Find(TLS_SessionMgr *mgr, uint8_t *sessionId, uint8_t sessionIdSize) +{ + if (mgr == NULL || sessionId == NULL || sessionIdSize == 0) { + return NULL; + } + BSL_SAL_ThreadReadLock(mgr->lock); + + HITLS_Session *sess = NULL; + SessionKey key = {0}; + key.sessionIdSize = sessionIdSize; + if (memcpy_s(key.sessionId, sizeof(key.sessionId), sessionId, sessionIdSize) == EOK) { + // Query the session corresponding to the key + BSL_HASH_At(mgr->hash, (uintptr_t)&key, (uintptr_t *)&sess); + } + + uint64_t curTime = (uint64_t)BSL_SAL_CurrentSysTimeGet(); + /* Check whether the validity is valid */ + if (SESS_CheckValidity(sess, curTime) == false) { + sess = NULL; + } + + BSL_SAL_ThreadUnlock(mgr->lock); + return sess; +} + +/* Search for the matched session without checking the validity of the session */ +bool SESSMGR_HasMacthSessionId(TLS_SessionMgr *mgr, uint8_t *sessionId, uint8_t sessionIdSize) +{ + if (mgr == NULL || sessionId == NULL || sessionIdSize == 0) { + return false; + } + HITLS_Session *sess = NULL; + + BSL_SAL_ThreadReadLock(mgr->lock); + SessionKey key = {0}; + key.sessionIdSize = sessionIdSize; + if (memcpy_s(key.sessionId, sizeof(key.sessionId), sessionId, sessionIdSize) == EOK) { + // Query the session corresponding to the key + BSL_HASH_At(mgr->hash, (uintptr_t)&key, (uintptr_t *)&sess); + } + + BSL_SAL_ThreadUnlock(mgr->lock); + return (sess == NULL) ? false : true; +} + +/* Clear timeout sessions */ +void SESSMGR_ClearTimeout(TLS_SessionMgr *mgr) +{ + if (mgr == NULL) { + return; + } + + uint64_t curTime = (uint64_t)BSL_SAL_CurrentSysTimeGet(); + + BSL_SAL_ThreadWriteLock(mgr->lock); + + BSL_HASH_Iterator it = BSL_HASH_IterBegin(mgr->hash); + + while (it != BSL_HASH_IterEnd(mgr->hash)) { + uintptr_t ptr = BSL_HASH_IterValue(mgr->hash, it); + HITLS_Session *sess = (HITLS_Session *)ptr; + if (SESS_CheckValidity(sess, curTime) == false) { + /* Delete the node if it is invalid */ + uintptr_t tmpKey = BSL_HASH_HashIterKey(mgr->hash, it); + it = BSL_HASH_Erase(mgr->hash, tmpKey); // Returns the next iterator of the iterator where the key resides + } else { + it = BSL_HASH_IterNext(mgr->hash, it); + } + } + + BSL_SAL_ThreadUnlock(mgr->lock); + return; +} + +int32_t SESSMGR_GernerateSessionId(TLS_Ctx *ctx, uint8_t *sessionId, uint32_t sessionIdSize) +{ + int32_t ret = 0; + int32_t retry = 0; + + do { + ret = SAL_CRYPT_Rand(sessionId, sessionIdSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* If duplicate session IDs already exist, generate new session ID */ + if (SESSMGR_HasMacthSessionId(ctx->config.tlsConfig.sessMgr, sessionId, (uint8_t)sessionIdSize) == false) { + return HITLS_SUCCESS; + } + + retry++; + } while (retry < SESSION_GERNERATE_RETRY_MAX_TIMES); // Maximum number of attempts is 10 + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15961, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Gernerate server session id error.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_ID_GENRATE); + return HITLS_SESS_ERR_SESSION_ID_GENRATE; +} + +void SESSMGR_SetTicketKeyCb(TLS_SessionMgr *mgr, HITLS_TicketKeyCb ticketKeyCb) +{ + if (mgr != NULL) { + BSL_SAL_ThreadWriteLock(mgr->lock); + mgr->ticketKeyCb = ticketKeyCb; + BSL_SAL_ThreadUnlock(mgr->lock); + } + return; +} + +HITLS_TicketKeyCb SESSMGR_GetTicketKeyCb(TLS_SessionMgr *mgr) +{ + if (mgr == NULL) { + return NULL; + } + HITLS_TicketKeyCb ticketKeyCb; + BSL_SAL_ThreadReadLock(mgr->lock); + ticketKeyCb = mgr->ticketKeyCb; + BSL_SAL_ThreadUnlock(mgr->lock); + + return ticketKeyCb; +} + +int32_t SESSMGR_GetTicketKey(const TLS_SessionMgr *mgr, uint8_t *key, uint32_t keySize, uint32_t *outSize) +{ + if (mgr == NULL || key == NULL || outSize == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadReadLock(mgr->lock); + + uint32_t offset = 0; + if (memcpy_s(key, keySize, mgr->ticketKeyName, HITLS_TICKET_KEY_NAME_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_SAL_ThreadUnlock(mgr->lock); + return HITLS_MEMCPY_FAIL; + } + offset += HITLS_TICKET_KEY_NAME_SIZE; + + if (memcpy_s(&key[offset], keySize - offset, mgr->ticketAesKey, HITLS_TICKET_KEY_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_SAL_ThreadUnlock(mgr->lock); + return HITLS_MEMCPY_FAIL; + } + offset += HITLS_TICKET_KEY_SIZE; + + if (memcpy_s(&key[offset], keySize - offset, mgr->ticketHmacKey, HITLS_TICKET_KEY_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_SAL_ThreadUnlock(mgr->lock); + return HITLS_MEMCPY_FAIL; + } + offset += HITLS_TICKET_KEY_SIZE; + + *outSize = offset; + + BSL_SAL_ThreadUnlock(mgr->lock); + + return HITLS_SUCCESS; +} + +int32_t SESSMGR_SetTicketKey(TLS_SessionMgr *mgr, const uint8_t *key, uint32_t keySize) +{ + if (mgr == NULL || key == NULL || + (keySize != HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_SIZE + HITLS_TICKET_KEY_SIZE)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + BSL_SAL_ThreadWriteLock(mgr->lock); + + uint32_t offset = 0; + (void)memcpy_s(mgr->ticketKeyName, HITLS_TICKET_KEY_NAME_SIZE, key, HITLS_TICKET_KEY_NAME_SIZE); + offset += HITLS_TICKET_KEY_NAME_SIZE; + + (void)memcpy_s(mgr->ticketAesKey, HITLS_TICKET_KEY_SIZE, &key[offset], HITLS_TICKET_KEY_SIZE); + offset += HITLS_TICKET_KEY_SIZE; + + (void)memcpy_s(mgr->ticketHmacKey, HITLS_TICKET_KEY_SIZE, &key[offset], HITLS_TICKET_KEY_SIZE); + + BSL_SAL_ThreadUnlock(mgr->lock); + + return HITLS_SUCCESS; +} diff --git a/tls/feature/session/src/session_ticket.c b/tls/feature/session/src/session_ticket.c new file mode 100644 index 00000000..0e1038b8 --- /dev/null +++ b/tls/feature/session/src/session_ticket.c @@ -0,0 +1,509 @@ +/* + * 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 +#include +#include "securec.h" +#include "tlv.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "tls_binlog_id.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "crypt.h" +#include "hitls_error.h" +#include "session_type.h" +#include "session_enc.h" + +typedef struct { + uint8_t keyName[HITLS_TICKET_KEY_NAME_SIZE]; + uint8_t iv[HITLS_TICKET_KEY_NAME_SIZE]; + uint32_t encryptedStateSize; + uint8_t *encryptedState; + uint8_t mac[HITLS_TICKET_KEY_SIZE]; +} Ticket; + +#define DEFAULT_SESSION_ENCRYPT_TYPE HITLS_AEAD_CIPHER +#define DEFAULT_SESSION_ENCRYPT_ALGO HITLS_CIPHER_AES_256_GCM +#define AES_CBC_BLOCK_LEN 16u + +static int32_t TicketHmac(HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret; + HITLS_HMAC_Ctx *hmacCtx = SAL_CRYPT_HmacInit(HITLS_HASH_SHA_256, cipher->hmacKey, cipher->hmacKeyLen); + if (hmacCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_HMAC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16019, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_HmacInit fail when calc ticket hmac.", 0, 0, 0, 0); + return HITLS_SESS_ERR_SESSION_TICKET_HMAC_FAIL; + } + + ret = SAL_CRYPT_HmacUpdate(hmacCtx, in, inLen); + if (ret != HITLS_SUCCESS) { + SAL_CRYPT_HmacFree(hmacCtx); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16020, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_HmacUpdate fail when calc ticket hmac.", 0, 0, 0, 0); + return ret; + } + + ret = SAL_CRYPT_HmacFinal(hmacCtx, out, outLen); + SAL_CRYPT_HmacFree(hmacCtx); + return ret; +} + +static void SetCipherInfo(const TLS_SessionMgr *sessMgr, Ticket *ticket, HITLS_CipherParameters *cipher) +{ + cipher->type = DEFAULT_SESSION_ENCRYPT_TYPE; + cipher->algo = DEFAULT_SESSION_ENCRYPT_ALGO; + cipher->key = sessMgr->ticketAesKey; + cipher->keyLen = HITLS_TICKET_KEY_SIZE; + cipher->iv = ticket->iv; + cipher->ivLen = HITLS_TICKET_KEY_NAME_SIZE; + cipher->aad = ticket->iv; + cipher->aadLen = HITLS_TICKET_KEY_NAME_SIZE; + return; +} + +static int32_t GetSessEncryptInfo(const TLS_SessionMgr *sessMgr, Ticket *ticket, HITLS_CipherParameters *cipher) +{ + int32_t ret; + HITLS_TicketKeyCb cb = sessMgr->ticketKeyCb; + if (cb != NULL) { + ret = cb(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, cipher, true); + if (memcpy_s(ticket->iv, HITLS_TICKET_KEY_NAME_SIZE, cipher->iv, cipher->ivLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_TICKET_KEY_RET_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15469, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "iv copy fail when GetSessEncryptInfo.", 0, 0, 0, 0); + return HITLS_TICKET_KEY_RET_FAIL; + } + return ret; + } + /* The user does not register the callback. The default ticket key is used. */ + (void)memcpy_s(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, sessMgr->ticketKeyName, HITLS_TICKET_KEY_NAME_SIZE); + + ret = SAL_CRYPT_Rand(ticket->iv, HITLS_TICKET_KEY_NAME_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_TICKET_KEY_RET_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_Rand fail when creat ticket iv.", 0, 0, 0, 0); + return HITLS_TICKET_KEY_RET_FAIL; + } + + SetCipherInfo(sessMgr, ticket, cipher); + + return HITLS_TICKET_KEY_RET_SUCCESS; +} + +static int32_t PackKeyNameAndIv(const Ticket *ticket, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + uint32_t offset = 0; + if (memcpy_s(&data[0], len, ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16022, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy keyName fail when encrypt session ticket.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += HITLS_TICKET_KEY_NAME_SIZE; + + if (memcpy_s(&data[offset], len - offset, ticket->iv, HITLS_TICKET_KEY_NAME_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16023, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy iv fail when encrypt session ticket.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += HITLS_TICKET_KEY_NAME_SIZE; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackEncryptTicket( + const HITLS_Session *sess, HITLS_CipherParameters *cipher, uint8_t *data, uint32_t len, uint32_t *usedLen) +{ + int32_t ret = 0; + /* Encode the session. */ + uint32_t encodeLen = SESS_GetTotalEncodeSize(sess); + uint32_t plaintextLen = encodeLen; + uint8_t paddingLen = 0; + if (cipher->type == HITLS_CBC_CIPHER) { + /* In CBC mode, the padding needs to be calculated. */ + paddingLen = (encodeLen + sizeof(uint8_t)) % AES_CBC_BLOCK_LEN; + if (paddingLen != 0) { + paddingLen = AES_CBC_BLOCK_LEN - paddingLen; + } + /* Plain text length plus padding length */ + plaintextLen += paddingLen + sizeof(uint8_t); + } + + uint8_t *plaintext = BSL_SAL_Calloc(1u, plaintextLen); + if (plaintext == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16024, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encData malloc fail when encrypt session ticket.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + ret = SESS_Encode(sess, plaintext, plaintextLen, &plaintextLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_CleanseData(plaintext, plaintextLen); + BSL_SAL_FREE(plaintext); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16025, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESS_Encode fail when encrypt session ticket.", 0, 0, 0, 0); + return ret; + } + + /* Padding is required in CBC mode. */ + if (cipher->type == HITLS_CBC_CIPHER) { + /* The last byte is the padding length field, and the padding content is the length value. */ + uint32_t count = paddingLen + sizeof(uint8_t); + /* The calculation is accurate when the memory is applied for the plaintext. Therefore, the + * return value does not need to be checked. */ + (void)memset_s(&plaintext[encodeLen], count, paddingLen, count); + plaintextLen += count; + } + uint32_t offset = 0; + offset += sizeof(uint32_t); /* reserved length field */ + /* Encrypt and fill the ticket. */ + uint32_t encryptLen = len - offset; + ret = SAL_CRYPT_Encrypt(cipher, plaintext, plaintextLen, &data[offset], &encryptLen); + BSL_SAL_CleanseData(plaintext, plaintextLen); + BSL_SAL_FREE(plaintext); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16026, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_Encrypt fail when encrypt session ticket.", 0, 0, 0, 0); + return ret; + } + BSL_Uint32ToByte(encryptLen, &data[offset - sizeof(uint32_t)]); /* padding length */ + offset += encryptLen; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackTicketHmac(HITLS_CipherParameters *cipher, uint8_t *data, uint32_t len, uint32_t offset, + uint32_t *usedLen) +{ +/* The HMAC field is filled only in CBC mode. In other modes, the HMAC field is returned. */ + if (cipher->type != HITLS_CBC_CIPHER) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + int32_t ret; + uint8_t mac[HITLS_TICKET_KEY_SIZE] = {0}; + uint32_t macLen = HITLS_TICKET_KEY_SIZE; + ret = TicketHmac(cipher, data, offset, mac, &macLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16027, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TicketHmac fail when encrypt session ticket.", 0, 0, 0, 0); + return ret; + } + if (memcpy_s(&data[offset], len - offset, mac, macLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16028, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy mac fail when encrypt session ticket.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + *usedLen = macLen; + return HITLS_SUCCESS; +} + +static uint8_t *NewTicketBuf(const HITLS_Session *sess, const HITLS_CipherParameters *cipher, uint32_t *ticketBufSize) +{ + uint32_t encodeLen = SESS_GetTotalEncodeSize(sess); + uint32_t plaintextLen = encodeLen; + if (cipher->type == HITLS_CBC_CIPHER) { + /* In CBC mode, the padding needs to be calculated. */ + uint8_t paddingLen = (encodeLen + sizeof(uint8_t)) % AES_CBC_BLOCK_LEN; + if (paddingLen != 0) { + paddingLen = AES_CBC_BLOCK_LEN - paddingLen; + } + /* Plain text length plus padding length */ + plaintextLen += paddingLen + sizeof(uint8_t); + } + /* Plain text length plus key name, iv, encrypted data length, and MAC length. */ + plaintextLen += HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_NAME_SIZE + sizeof(uint32_t) + HITLS_TICKET_KEY_SIZE; + + uint8_t *ticketBuf = BSL_SAL_Calloc(1u, plaintextLen); + if (ticketBuf == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16029, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ticketBuf malloc fail when encrypt session ticket.", 0, 0, 0, 0); + return NULL; + } + + *ticketBufSize = plaintextLen; + return ticketBuf; +} + +int32_t SESSMGR_EncryptSessionTicket( + const TLS_SessionMgr *sessMgr, const HITLS_Session *sess, uint8_t **ticketBuf, uint32_t *ticketBufSize) +{ + if (sessMgr == NULL || sess == NULL || ticketBuf == NULL) { + return HITLS_INTERNAL_EXCEPTION; + } + + Ticket ticket = {0}; + HITLS_CipherParameters cipher = {0}; + int32_t retVal = GetSessEncryptInfo(sessMgr, &ticket, &cipher); + if (retVal < 0) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16030, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "GetSessEncryptInfo fail when encrypt session ticket.", 0, 0, 0, 0); + return HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL; + } + if (retVal == HITLS_TICKET_KEY_RET_FAIL) { + /* Failed to obtain the encryption information. An empty ticket is returned. */ + *ticketBufSize = 0; + return HITLS_SUCCESS; + } + + uint32_t dataLen = 0; + uint8_t *data = NewTicketBuf(sess, &cipher, &dataLen); + if (data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + /* Fill in the key name and iv. */ + int32_t ret; + uint32_t packLen = 0; + uint32_t offset = 0; + ret = PackKeyNameAndIv(&ticket, &data[0], dataLen, &packLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(data); + return ret; + } + offset += packLen; + /* Encrypt and fill the ticket. */ + ret = PackEncryptTicket(sess, &cipher, &data[offset], dataLen - offset, &packLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(data); + return ret; + } + offset += packLen; + /* fill HMAC */ + ret = PackTicketHmac(&cipher, data, dataLen, offset, &packLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(data); + return ret; + } + offset += packLen; + *ticketBufSize = offset; + *ticketBuf = data; + return HITLS_SUCCESS; +} +static int32_t ParseSessionTicket(Ticket *ticket, const uint8_t *ticketBuf, uint32_t ticketBufSize) +{ + uint32_t offset = 0; + if (ticketBufSize < HITLS_TICKET_KEY_NAME_SIZE + HITLS_TICKET_KEY_NAME_SIZE + sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16044, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ticketBufSize is incorrect when parse session ticket.", 0, 0, 0, 0); + return HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT; + } + + (void)memcpy_s(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, ticketBuf, HITLS_TICKET_KEY_NAME_SIZE); + offset += HITLS_TICKET_KEY_NAME_SIZE; + + (void)memcpy_s(ticket->iv, HITLS_TICKET_KEY_NAME_SIZE, &ticketBuf[offset], HITLS_TICKET_KEY_NAME_SIZE); + offset += HITLS_TICKET_KEY_NAME_SIZE; + + ticket->encryptedStateSize = BSL_ByteToUint32(&ticketBuf[offset]); + offset += sizeof(uint32_t); + + if ((ticketBufSize - offset) < ticket->encryptedStateSize) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16032, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ticketBufSize is incorrect when parse session ticket encryptedStateSize.", 0, 0, 0, 0); + return HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT; + } + + ticket->encryptedState = (uint8_t *)&ticketBuf[offset]; + offset += ticket->encryptedStateSize; + + if (ticketBufSize != offset) { + if ((ticketBufSize - offset) != HITLS_TICKET_KEY_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16033, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ticketBufSize is incorrect when parse session ticket hmac.", 0, 0, 0, 0); + return HITLS_SESS_ERR_SESSION_TICKET_SIZE_INCORRECT; + } + (void)memcpy_s(ticket->mac, HITLS_TICKET_KEY_SIZE, &ticketBuf[offset], HITLS_TICKET_KEY_SIZE); + } + + return HITLS_SUCCESS; +} + +static int32_t GetSessDecryptInfo(const TLS_SessionMgr *sessMgr, Ticket *ticket, HITLS_CipherParameters *cipher) +{ + HITLS_TicketKeyCb cb = sessMgr->ticketKeyCb; + if (cb != NULL) { + return cb(ticket->keyName, HITLS_TICKET_KEY_NAME_SIZE, cipher, false); + } + /* The user does not register the callback. Use the default ticket key. */ + if (memcmp(ticket->keyName, sessMgr->ticketKeyName, HITLS_TICKET_KEY_NAME_SIZE) != 0) { + /* Failed to match the key name. */ + return HITLS_TICKET_KEY_RET_FAIL; + } + SetCipherInfo(sessMgr, ticket, cipher); + return HITLS_TICKET_KEY_RET_SUCCESS; +} +static int32_t CheckTicketHmac( + HITLS_CipherParameters *cipher, Ticket *ticket, const uint8_t *data, uint32_t len, bool *isPass) +{ + /* The HMAC check is required only in CBC mode. In other modes, the HMAC check is returned. */ + if (cipher->type != HITLS_CBC_CIPHER) { + *isPass = true; + return HITLS_SUCCESS; + } + + int32_t ret; + uint8_t mac[HITLS_TICKET_KEY_SIZE] = {0}; + uint32_t macLen = HITLS_TICKET_KEY_SIZE; + ret = TicketHmac(cipher, data, len - HITLS_TICKET_KEY_SIZE, mac, &macLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16035, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TicketHmac fail when decrypt session ticket.", 0, 0, 0, 0); + return ret; + } + + if (memcmp(ticket->mac, mac, macLen) != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16036, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "compare mac fail when decrypt session ticket.", 0, 0, 0, 0); + /* The HMAC check fails, but the complete link establishment can be continued. Therefore, HITLS_SUCCESS is + * returned. */ + *isPass = false; + return HITLS_SUCCESS; + } + *isPass = true; + return HITLS_SUCCESS; +} + +static int32_t GenerateSessFromTicket( + HITLS_CipherParameters *cipher, Ticket *ticket, uint32_t ticketBufSize, HITLS_Session **sess) +{ + /* Decrypt the ticket. */ + uint32_t plaintextLen = ticketBufSize; + uint8_t *plaintext = BSL_SAL_Calloc(1u, ticketBufSize); + if (plaintext == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16037, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "plaintext malloc fail when decrypt session ticket.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + int32_t ret; + ret = SAL_CRYPT_Decrypt(cipher, ticket->encryptedState, ticket->encryptedStateSize, plaintext, &plaintextLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(plaintext); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16038, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_Decrypt fail when decrypt session ticket.", 0, 0, 0, 0); + /* The ticket fails to be decrypted, but the complete connection can be established. Therefore, HITLS_SUCCESS is + * returned. */ + return HITLS_SUCCESS; + } + /* Padding needs to be verified in CBC mode. */ + if (cipher->type == HITLS_CBC_CIPHER) { + /* The last byte is the padding length field, and the padding content is the length value. */ + uint8_t paddingLen = plaintext[plaintextLen - 1]; + for (uint32_t i = 1; i <= paddingLen; i++) { + if (plaintext[plaintextLen - 1 - i] != paddingLen) { + BSL_SAL_FREE(plaintext); + return ret; + } + } + plaintextLen -= paddingLen + sizeof(uint8_t); + } + + /* Parse the ticket content to the SESS. */ + HITLS_Session *session = HITLS_SESS_New(); + if (session == NULL) { + BSL_SAL_FREE(plaintext); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16039, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HITLS_SESS_New fail when decrypt session ticket.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + ret = SESS_Decode(session, plaintext, plaintextLen); + BSL_SAL_FREE(plaintext); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(session); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16040, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "SESS_Decode fail when decrypt session ticket.", 0, 0, 0, 0); + /* The ticket content fails to be parsed, but the complete connection can be established. Therefore, + * HITLS_SUCCESS is returned. */ + return HITLS_SUCCESS; + } + + *sess = session; + return HITLS_SUCCESS; +} + +int32_t SESSMGR_DecryptSessionTicket(const TLS_SessionMgr *sessMgr, HITLS_Session **sess, const uint8_t *ticketBuf, + uint32_t ticketBufSize, bool *isTicketExpect) +{ + if (sessMgr == NULL || sess == NULL || ticketBuf == NULL || isTicketExpect == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16041, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESSMGR_DecryptSessionTicket input parameter is NULL.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret; + Ticket ticket = {0}; + /* Parse the data into the ticket structure. */ + ret = ParseSessionTicket(&ticket, ticketBuf, ticketBufSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16042, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "ParseSessionTicket fail when decrypt session ticket.", 0, 0, 0, 0); + /* If the ticket fails to be parsed, the session is not resumption and the complete connection is established. + * Therefore, HITLS_SUCCESS is returned. */ + *isTicketExpect = true; + return HITLS_SUCCESS; + } + + /* Obtain decryption information. */ + HITLS_CipherParameters cipher = {0}; + int32_t retVal = GetSessDecryptInfo(sessMgr, &ticket, &cipher); + if (retVal < 0) { + BSL_ERR_PUSH_ERROR(HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16043, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "GetSessDecryptInfo fail when decrypt session ticket.", 0, 0, 0, 0); + return HITLS_SESS_ERR_SESSION_TICKET_KEY_FAIL; + } + switch (retVal) { + case HITLS_TICKET_KEY_RET_FAIL: + /* If no corresponding key is found, the system directly returns a message and complete link establishment + * is performed. */ + *isTicketExpect = true; + return HITLS_SUCCESS; + case HITLS_TICKET_KEY_RET_SUCCESS_RENEW: + *isTicketExpect = true; + break; + case HITLS_TICKET_KEY_RET_SUCCESS: + default: + *isTicketExpect = false; + break; + } + /* Verify the MAC address. */ + bool isPass = true; + ret = CheckTicketHmac(&cipher, &ticket, ticketBuf, ticketBufSize, &isPass); + if ((ret != HITLS_SUCCESS) || (!isPass)) { + /* If the HMAC check fails, the session is not restored and complete link establishment is performed. */ + return ret; + } + /* Parse the ticket content to the SESS. */ + return GenerateSessFromTicket(&cipher, &ticket, ticketBufSize, sess); +} diff --git a/tls/feature/session/src/session_type.h b/tls/feature/session/src/session_type.h new file mode 100644 index 00000000..7f461b22 --- /dev/null +++ b/tls/feature/session/src/session_type.h @@ -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 SESSION_TYPE_H +#define SESSION_TYPE_H + +#include +#include +#include "hitls_type.h" +#include "hitls_session.h" +#include "tls_config.h" +#include "cert.h" +#include "session.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct TlsSessionManager { + void *lock; /* Thread lock */ + int32_t references; /* Reference times */ + + void *hash; /* hash table */ + + uint64_t sessTimeout; /* Session timeout interval, in seconds */ + uint32_t sessCacheSize; /* session cache size: maximum number of sessions */ + HITLS_SESS_CACHE_MODE sessCacheMode; /* session cache mode */ + + /* TLS1.2 session ticket */ + HITLS_TicketKeyCb ticketKeyCb; /* allows users to customize ticket keys through callback */ + /* key_name: is used to identify a specific set of keys used to protect tickets */ + uint8_t ticketKeyName[HITLS_TICKET_KEY_NAME_SIZE]; + uint8_t ticketAesKey[HITLS_TICKET_KEY_SIZE]; /* aes key */ + uint8_t ticketHmacKey[HITLS_TICKET_KEY_SIZE]; /* hmac key */ +}; + +struct TlsSessCtx { + void *lock; /* Thread lock */ + /* certificate management context. The certificate interface depends on this field */ + CERT_MgrCtx *certMgrCtx; + + int32_t references; /* Reference times */ + + bool enable; /* Whether to enable the session */ + bool haveExtMasterSecret; /* Whether an extended master key exists */ + bool reserved[2]; /* Four-byte alignment */ + + uint64_t startTime; /* Start time */ + uint64_t timeout; /* Timeout interval */ + + uint32_t hostNameSize; /* Length of the host name */ + uint8_t *hostName; /* Host name */ + + uint32_t sessionIdCtxSize; /* Session ID Context Length */ + uint8_t sessionIdCtx[HITLS_SESSION_ID_CTX_MAX_SIZE]; /* Session ID Context */ + + uint32_t sessionIdSize; /* Session ID length */ + uint8_t sessionId[HITLS_SESSION_ID_MAX_SIZE]; /* session ID */ + int32_t verifyResult; /* Authentication result */ + + CERT_Pair *peerCert; /* Peer certificate */ + + uint16_t version; /* Version */ + uint16_t cipherSuite; /* Cipher suite */ + uint32_t masterKeySize; /* length of the master key */ + uint8_t masterKey[MAX_MASTER_KEY_SIZE]; /* Master Key */ + uint32_t pskIdentitySize; /* pskIdentity length */ + uint8_t *pskIdentity; /* pskIdentity */ + + uint32_t ticketSize; /* Session ticket length */ + uint8_t *ticket; /* Session ticket */ + uint32_t ticketLifetime; /* Timeout interval of the ticket */ + uint32_t ticketAgeAdd; /* A random number generated each time a ticket is issued */ +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/feature/sni/src/sni.c b/tls/feature/sni/src/sni.c new file mode 100644 index 00000000..ccfeb5cb --- /dev/null +++ b/tls/feature/sni/src/sni.c @@ -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 +#include +#include +#include "securec.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "hitls_sni.h" +#include "session.h" +#include "tls.h" +#include "hs.h" +#include "sni.h" + +const char *HITLS_GetServerName(const HITLS_Ctx *ctx, const int type) +{ + if (ctx == NULL || type != HITLS_SNI_HOSTNAME_TYPE) { + return NULL; + } + bool isClient = ctx->isClient; + bool isResume = ctx->negotiatedInfo.isResume; + uint16_t version = ctx->config.tlsConfig.maxVersion; + uint8_t *hostName = NULL; + uint32_t nameSize = 0u; + SESS_GetHostName(ctx->session, &nameSize, &hostName); + + if (!isClient) { + /* Before Handshake */ + if (ctx->state == CM_STATE_IDLE) { + return NULL; + } + /* During or after handshake */ + /* TLS protocol version < TLS1.2 session resumption */ + if ((version < HITLS_VERSION_TLS13 || version == HITLS_VERSION_DTLS12) && isResume && ctx->session != NULL) { + return (char *)hostName; + } + } else { + /* Before Handshake */ + if (ctx->state == CM_STATE_IDLE) { + /* resume the session */ + if (ctx->config.tlsConfig.serverName == NULL && ctx->session != NULL && + (version < HITLS_VERSION_TLS13 || version == HITLS_VERSION_DTLS12)) { + return (char *)hostName; + } + /* resume non-session */ + return (char *)ctx->config.tlsConfig.serverName; + } else { + /* During or after handshake */ + /* resume the session */ + if (ctx->session != NULL && (version < HITLS_VERSION_TLS13 || version == HITLS_VERSION_DTLS12)) { + return (char *)hostName; + } + /* resume non-session */ + return (char *)ctx->config.tlsConfig.serverName; + } + } + + return HS_GetServerName(ctx); +} + +int32_t HITLS_GetServernameType(const HITLS_Ctx *ctx) +{ + int32_t ret = -1; + if (HITLS_GetServerName(ctx, HITLS_SNI_HOSTNAME_TYPE) != NULL) { + return HITLS_SNI_HOSTNAME_TYPE; + } + return ret; +} + +/* Check whether the host names are the same */ +int32_t SNI_StrcaseCmp(const char *s1, const char *s2) +{ + int32_t ret = -1; + + if (s1 == NULL && s2 == NULL) { + return 0; + } + + const char *a = s1; + const char *b = s2; + int32_t len1 = (int32_t)strlen(s1); + int32_t len2 = (int32_t)strlen(s2); + if (len1 != len2) { + return ret; + } + + while (tolower((int32_t)*a) == tolower((int32_t)*b)) { + if (*a == '\0') { + return 0; + } + + a++; + b++; + } + + return ret; +} \ No newline at end of file diff --git a/tls/handshake/common/include/hs_common.h b/tls/handshake/common/include/hs_common.h new file mode 100644 index 00000000..2a42eb18 --- /dev/null +++ b/tls/handshake/common/include/hs_common.h @@ -0,0 +1,244 @@ +/* + * 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 HS_COMMON_H +#define HS_COMMON_H + +#include +#include "tls.h" +#include "hs_ctx.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_CERT_TYPE_LISTS_SIZE 256 /* Maximum length of the certificate type list */ +#define HS_DOWNGRADE_RANDOM_SIZE 8u /* downgrade protection random number field */ + +#define HITLS_CLIENT_HELLO_MAX_SIZE 131396 +#define HITLS_SERVER_HELLO_MAX_SIZE 65607 +#define HITLS_HELLO_VERIFY_REQUEST_MAX_SIZE 258 +#define HITLS_END_OF_EARLY_DATA_MAX_SIZE 0 +#define HITLS_HELLO_RETRY_REQUEST_MAX_SIZE 20000 +#define HITLS_ENCRYPTED_EXTENSIONS_MAX_SIZE 20000 +#define HITLS_SESSION_TICKET_MAX_SIZE_TLS13 131338 +#define HITLS_SESSION_TICKET_MAX_SIZE_TLS12 65541 +#define HITLS_SERVER_KEY_EXCH_MAX_SIZE 102400 +#define HITLS_SERVER_HELLO_DONE_MAX_SIZE 0 +#define HITLS_KEY_UPDATE_MAX_SIZE 1 +#define HITLS_CLIENT_KEY_EXCH_MAX_SIZE 2048 +#define HITLS_NEXT_PROTO_MAX_SIZE 514 +#define HITLS_FINISHED_MAX_SIZE 64 +#define HITLS_HELLO_REQUEST_MAX_SIZE 0 + +/** +* @brief Obtain the random number of the hello retry request. +* +* @param len [OUT] Length of the returned array +* +* @return Random number array +*/ +const uint8_t *HS_GetHrrRandom(uint32_t *len); + +const uint8_t *HS_GetTls12DowngradeRandom(uint32_t *len); + +/** + * @brief Obtains the type string of the handshake message. + * + * @param type [IN] Handshake Message Type + * + * @return Character string corresponding to the handshake message type. + */ +const char *HS_GetMsgTypeStr(HS_MsgType type); + +/** +* @brief Obtain the type character string of the handshake message. +* +* @param type [IN] Handshake message type. +* +* @return Character string corresponding to the handshake message type. +*/ +int32_t HS_ChangeState(TLS_Ctx *ctx, uint32_t nextState); + +/** +* @brief Combine two random numbers. +* +* @param random1 [IN] Random number 1 +* @param random2 [IN] Random number 2 +* @param randomSize [IN] Random number length +* @param dest [OUT] Destination memory address +* @param destSize [IN] Target memory length +* +* @retval HITLS_SUCCESS parsed successfully. +* @retval HITLS_MEMCPY_FAIL Memory Copy Failure +* @retval HITLS_MSG_HANDLE_RANDOM_SIZE_ERR The random number length is incorrect. + */ +int32_t HS_CombineRandom(const uint8_t *random1, const uint8_t *random2, uint32_t randomSize, + uint8_t *dest, uint32_t destSize); + +/** + * @brief Obtain the public key length of the Named Curve curve of the ECDHE key agreement algorithm. + * @attention The length of the public key cannot exceed 255 bytes. + * @param namedcurve [IN] Named Curve Enumerated type + * + * @retval Length of the public key + */ +uint32_t HS_GetNamedCurvePubkeyLen(HITLS_NamedGroup namedcurve); + +/** + * @brief Obtain all signature data. + * + * @param ctx [IN] TLS context + * @param partSignData [IN] key exchange message data + * @param partSignDataLen [IN] key exchange message data length + * @param signDataLen [OUT] Length of the signature data + * + * @retval Data to be signed + */ +uint8_t *HS_PrepareSignData(const TLS_Ctx *ctx, const uint8_t *partSignData, + uint32_t partSignDataLen, uint32_t *signDataLen); + +/** + * @brief Obtain the signature data required by the TLCP. + * + * @param ctx [IN] TLS context + * @param partSignData [IN] key exchange message data + * @param partSignDataLen [IN] key exchange message data length + * @param signDataLen [OUT] Length of the signature data + * @retval Data to be signed + */ +uint8_t *HS_PrepareSignDataTlcp( + const TLS_Ctx *ctx, const uint8_t *partSignData, uint32_t partSignDataLen, uint32_t *signDataLen); + +#ifndef HITLS_NO_DTLS12 +/** + * @brief Set the SCTP auth key to the SCTP. + * + * @attention If the UIO_SctpAddAuthKey is added but not activated, the UIO_SctpAddAuthKey returns a success message + * when the interface is invoked again. + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS Operation succeeded. + * @retval HITLS_MSG_HANDLE_RANDOM_SIZE_ERR The random number length is incorrect. + * @retval For details, see UIO_SctpAddAuthKey. + */ +int32_t HS_SetSctpAuthKey(TLS_Ctx *ctx); + +/** + * @brief Activate the sctp auth key. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS operation succeeded. + * @retval For details, see UIO_SctpIsSndBuffEmpty and UIO_SctpActiveAuthKey. + */ +int32_t HS_ActiveSctpAuthKey(TLS_Ctx *ctx); + +/** +* @brief Delete the previous SCTP auth key. +* +* @param ctx [IN] TLS context +* +* @retval HITLS_SUCCESS Operation succeeded. +* @retval HITLS_REC_NORMAL_IO_BUSY The underlying I/O buffer is not empty. +* @retval For details, see UIO_SctpDelPreAuthKey. +*/ +int32_t HS_DeletePreviousSctpAuthKey(TLS_Ctx *ctx); +#endif /* end #ifndef HITLS_NO_DTLS12 */ + +/** + * @brief Obtain the list of supported certificate types based on the configured cipher suite. + * + * @param config [IN] config Context + * @param buf [OUT] List of supported certificate types + * @param bufSize [IN] Array buffer size + * @param listSize [OUT] Length of the supported certificate type list + * + * @retval HITLS_SUCCESS Operation succeeded. + * @retval HITLS_INTERNAL_EXCEPTION The length of the array buffer is insufficient. + */ +int32_t HS_GetSupportedCertTypeList(const TLS_Config *config, uint8_t *buf, uint32_t bufSize, uint32_t *listSize); + +bool IsNeedServerKeyExchange(const TLS_Ctx *ctx); + +bool IsPskNegotiation(const TLS_Ctx *ctx); + +bool IsNeedCertPrepare(const CipherSuiteInfo *cipherSuiteInfo); + +bool IsTicketSupport(TLS_Ctx *ctx); + +int32_t CheckClientPsk(TLS_Ctx *ctx); + +/** + * @brief Expand the capacity of the msgBuf in the hsCtx based on the received message length. + * + * @param ctx [IN] TLS context + * @param msgSize[IN] Expected length + * + * @retval HITLS_SUCCESS Operation succeeded. + * @retval HITLS_MEMALLOC_FAIL failed to apply for memory. + */ +int32_t HS_ReSizeMsgBuf(TLS_Ctx *ctx, uint32_t msgSize); + +/** + * @brief Expand the capacity of the msgBuf in the hsCtx based on the length of the received message. The upper limit of + * the capacity does not exceed upperBound bytes, And you can choose whether to retain the original data + * @param ctx [IN] TLS context + * @param msgSize[IN] Expected length + * @param upperBound[IN] Upper limit of the capacity length + * @param keepOldData[IN] Indicates whether to retain the old data. + * + * @retval HITLS_SUCCESS Operation succeeded. + * @retval HITLS_MEMALLOC_FAIL failed to apply for memory. + * @retval HITLS_MEMCPY_FAIL Data fails to be copied. + */ +int32_t HS_GrowMsgBuf(TLS_Ctx *ctx, uint32_t msgSize, uint32_t upperBound, bool keepOldData); + +/** + * @brief Return the maximum message length allowed by the handshake status. + * + * @param ctx [IN] TLS context + * @param type[IN] Handshake message type + * + * @retval Maximum message length allowed + */ +uint32_t HS_MaxMessageSize(TLS_Ctx *ctx, HS_MsgType type); + +/** + * @brief Obtain the Binder length. + * + * @param ctx [IN] TLS context + * @param hashAlg [IN/OUT] Hash algorithm used in the process of calculating the binder + * + * @return Binder length + */ +uint32_t HS_GetBinderLen(HITLS_Session *session, HITLS_HashAlgo* hashAlg); + +/** + * @brief Check whether the current version supports this group. + * + * @param version [IN] current version + * @param group [IN] group + * + * @return true: valid; false: invalid + */ +bool GroupConformToVersion(uint16_t version, uint16_t group); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/handshake/common/include/hs_ctx.h b/tls/handshake/common/include/hs_ctx.h new file mode 100644 index 00000000..2e14c450 --- /dev/null +++ b/tls/handshake/common/include/hs_ctx.h @@ -0,0 +1,184 @@ +/* + * 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 HS_CTX_H +#define HS_CTX_H + +#include +#include "sal_time.h" +#include "hitls_cert_type.h" +#include "hitls_crypt_type.h" +#include "cert.h" +#include "crypt.h" +#include "rec.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MASTER_SECRET_LEN 48u +#define HS_PSK_IDENTITY_MAX_LEN 128u /* Maximum length of PSK-negotiated identity information */ +#define HS_PSK_MAX_LEN 256u +#define COOKIE_SECRET_LIFETIME 5u /* the number of times the cookie's secret is used */ + +/* Transmits ECDH key exchange data */ +typedef struct { + HITLS_ECParameters curveParams; /* Elliptic curve parameter */ +} EcdhParam; + +/* Transmits DH key exchange data */ +typedef struct { + uint8_t *p; /* prime */ + uint8_t *g; /* generator */ + uint16_t plen; /* prime length */ + uint16_t glen; /* generator length */ +} DhParam; + +/* Used to transfer RSA key exchange data */ +typedef struct { + uint8_t preMasterSecret[MASTER_SECRET_LEN]; +} RsaParam; + +/* Used to transfer Ecc key exchange data */ +typedef struct { + uint8_t preMasterSecret[MASTER_SECRET_LEN]; +} EccParam; + +typedef struct { + HITLS_NamedGroup group; +} KeyShareParam; + +/** + * @ingroup hitls + * + * @brief PskInfo is used for PSK negotiation and stores identity and psk during negotiation + */ +typedef struct { + uint8_t *identity; + uint32_t identityLen; + uint8_t *psk; + uint32_t pskLen; + bool isResumePsk; /* Indicates whether the PSK is generated during session resumption */ +} PskInfo; + +typedef struct { + uint8_t *identity; + uint32_t identityLen; + HITLS_Session *pskSession; + uint8_t num; +} UserPskList; + +typedef struct { + UserPskList *userPskSess; /* tls 1.3 user psk session */ + HITLS_Session *resumeSession; /* tls 1.3 psk resume */ + int32_t selectIndex; /* selected index */ + uint8_t *psk; /* selected psk */ + uint32_t pskLen; +} PskInfo13; + +/* Used to transfer the key exchange context */ +typedef struct { + HITLS_KeyExchAlgo keyExchAlgo; + union { + EcdhParam ecdh; + DhParam dh; + RsaParam rsa; + EccParam ecc; /* Sm2 parameter */ + KeyShareParam share; + } keyExchParam; + PskInfo *pskInfo; /* PSK data tls 1.2 */ + HITLS_CRYPT_Key *key; /* Local key pair */ + uint8_t *peerPubkey; + uint32_t pubKeyLen; + PskInfo13 pskInfo13; /* tls 1.3 psk */ +} KeyExchCtx; + +/* Buffer for transmitting handshake data. */ +typedef struct HsMsgCache { + uint8_t *data; + uint32_t dataSize; + struct HsMsgCache *next; +} HsMsgCache; + +/* Used to transfer the handshake data verification context. */ +typedef struct { + HITLS_HashAlgo hashAlgo; + HITLS_HASH_Ctx *hashCtx; + uint8_t verifyData[MAX_SIGN_SIZE]; + uint32_t verifyDataSize; + HsMsgCache *dataBuf; /* handshake data buffer */ +} VerifyCtx; + +/* Used to pass the handshake context */ +struct HsCtx { + HITLS_HandshakeState state; + HITLS_HandshakeState ccsNextState; + ExtensionFlag extFlag; + bool isNeedClientCert; + bool haveHrr; /* Whether the hello retry request has been processed */ + + uint32_t sessionIdSize; + uint8_t *sessionId; + + uint8_t *clientRandom; + uint8_t *serverRandom; + uint8_t earlySecret[MAX_DIGEST_SIZE]; + uint8_t handshakeSecret[MAX_DIGEST_SIZE]; + uint8_t masterKey[MAX_DIGEST_SIZE]; + CERT_Pair *peerCert; + uint8_t *clientAlpnList; + + uint32_t clientAlpnListSize; + uint8_t *serverName; + uint32_t serverNameSize; + uint32_t ticketSize; + uint8_t *ticket; + uint32_t ticketLifetimeHint; /* ticket timeout interval, in seconds */ + + uint32_t ticketAgeAdd; /* Used to obfuscate ticket age */ + + uint64_t nextTicketNonce; /* TLS1.3 connection, starting from 0 and increasing in ascending order */ + uint32_t sentTickets; /* TLS1.3 Number of tickets sent */ + + KeyExchCtx *kxCtx; /* Key Exchange Context */ + VerifyCtx *verifyCtx; /* Verify the context of handshake data. */ + uint8_t *msgBuf; /* Buffer for receiving and sending messages */ + uint32_t bufferLen; /* messages buffer size */ + uint32_t msgLen; /* Total length of buffered messages */ + + uint8_t clientHsTrafficSecret[MAX_DIGEST_SIZE]; /* Handshake secret used to encrypt the message sent by the TLS1.3 + client */ + uint8_t serverHsTrafficSecret[MAX_DIGEST_SIZE]; /* Handshake secret used to encrypt the message sent by the TLS1.3 + server */ + ClientHelloMsg *firstClientHello; /* TLS1.3 server records the first received ClientHello message */ + +#ifndef HITLS_NO_DTLS12 + uint16_t nextSendSeq; /* message sending sequence number */ + uint16_t expectRecvSeq; /* message receiving sequence number */ + HS_ReassQueue *reassMsg; /* reassembly message queue, used for reassembly of fragmented messages */ + + /* To reduce the calculation amount for determining timeout, use the end time instead of the start time. If the end + * time is exceeded, the receiving times out. */ + BSL_TIME deadline; /* End time */ + uint32_t timeoutValue; /* Timeout interval, in us. */ + uint32_t timeoutNum; /* Timeout count */ +#endif +}; + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ +#endif /* end HS_CTX_H */ \ No newline at end of file diff --git a/tls/handshake/common/include/hs_extensions.h b/tls/handshake/common/include/hs_extensions.h new file mode 100644 index 00000000..269d77cc --- /dev/null +++ b/tls/handshake/common/include/hs_extensions.h @@ -0,0 +1,56 @@ +/* + * 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 HS_EXTERNSIONS_H +#define HS_EXTERNSIONS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define HS_EX_HEADER_LEN 4u + +/* Handshake Extension message type */ +#define HS_EX_TYPE_SERVER_NAME 0u +#define HS_EX_TYPE_TRUSTED_CA_KEYS 3u +#define HS_EX_TYPE_STATUS_REQUEST 5u +#define HS_EX_TYPE_SUPPORTED_GROUPS 10u +#define HS_EX_TYPE_POINT_FORMATS 11u +#define HS_EX_TYPE_SIGNATURE_ALGORITHMS 13u +#define HS_EX_TYPE_APP_LAYER_PROTOCOLS 16u +#define HS_EX_TYPE_STATUS_REQUEST_V2 17u +#define HS_EX_TYPE_ENCRYPT_THEN_MAC 22u +#define HS_EX_TYPE_EXTENDED_MASTER_SECRET 23u +#define HS_EX_TYPE_SESSION_TICKET 35u +#define HS_EX_TYPE_PRE_SHARED_KEY 41u +#define HS_EX_TYPE_EARLY_DATA 42u +#define HS_EX_TYPE_SUPPORTED_VERSIONS 43u +#define HS_EX_TYPE_COOKIE 44u +#define HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES 45u +#define HS_EX_TYPE_TRUSTED_CA_LIST 47u +#define HS_EX_TYPE_OID_FILTERS 48u +#define HS_EX_TYPE_POST_HS_AUTH 49u +#define HS_EX_TYPE_SIGNATURE_ALGORITHMS_CERT 50u +#define HS_EX_TYPE_KEY_SHARE 51u +#define HS_EX_TYPE_RENEGOTIATION_INFO 0xFF01u +#define HS_EX_TYPE_END 0xFFFFu + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end HS_EXTERNSIONS_H */ diff --git a/tls/handshake/common/include/hs_kx.h b/tls/handshake/common/include/hs_kx.h new file mode 100644 index 00000000..efaa3a30 --- /dev/null +++ b/tls/handshake/common/include/hs_kx.h @@ -0,0 +1,307 @@ +/* + * 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 HS_KX_H +#define HS_KX_H + +#include +#include "hs_ctx.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The maximum premaster secret calculated by using the PSK may be: + * |uint16_t|MAX_PRE_MASTER_SECRET_SIZE|uint16_t|HS_PSK_MAX_LEN| */ +#define MAX_PRE_MASTER_SECRET_SIZE 1536 +#define MAX_SHA1_SIZE 20 +#define MAX_MD5_SIZE 16 + +/** + * @brief Create a key exchange context. + * + * @return A KeyExchCtx pointer is returned. If NULL is returned, the creation fails. + */ +KeyExchCtx *HS_KeyExchCtxNew(void); + +/** + * @brief Release the key exchange context + * + * @param keyExchCtx [IN] Key exchange context. KeyExchCtx is left empty by the invoker + */ +void HS_KeyExchCtxFree(KeyExchCtx *keyExchCtx); + +/** + * @brief Process the server ECDHE key exchange message + * + * @param ctx [IN] TLS context + * @param serverKxMsg [IN] Parsed handshake message + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE Unsupported elliptic curve type + * @retval HITLS_MSG_HANDLE_UNSUPPORT_NAMED_CURVE Unsupported ECDH elliptic curve + * @retval HITLS_MSG_HANDLE_ERR_ENCODE_ECDH_KEY Failed to obtain the ECDH public key. + */ +int32_t HS_ProcessServerKxMsgEcdhe(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg); + +/** + * @brief Process the client ECDHE key exchange message + * + * @param ctx [IN] TLS context + * @param clientKxMsg [IN] Parsed handshake message + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE Unsupported elliptic curve type + * @retval HITLS_MSG_HANDLE_UNSUPPORT_NAMED_CURVE Unsupported ECDH elliptic curve + */ +int32_t HS_ProcessClientKxMsgEcdhe(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg); + +/** + * @brief Process the server DH key exchange message + * + * @param ctx [IN] TLS context + * @param serverKxMsg [IN] Parsed handshake message + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_MSG_HANDLE_ERR_ENCODE_DH_KEY Failed to obtain the DH public key. + */ +int32_t HS_ProcessServerKxMsgDhe(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg); + +/** + * @brief Process the client DH key exchange message + * + * @param ctx [IN] TLS context + * @param clientKxMsg [IN] Parsed handshake message + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + */ +int32_t HS_ProcessClientKxMsgDhe(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg); + +int32_t HS_ProcessClientKxMsgRsa(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg); + +int32_t HS_ProcessClientKxMsgSm2(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg); + +/** + * @brief Derive the master secret. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG Unsupported Key Exchange Algorithm + * @retval For other error codes, see SAL_CRYPT_CalcEcdhSharedSecret. + */ +int32_t HS_GenerateMasterSecret(TLS_Ctx *ctx); + +/** + * @brief Process the identity hint contained in ServerKeyExchange during PSK negotiation. + * + * @param ctx [IN] TLS context + * @param serverKxMsg [IN] Parsed handshake message + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK The callback for obtaining the PSK on the client is not set. + * @retval HITLS_CONFIG_INVALID_LENGTH The length of the prompt message is incorrect. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + */ +int32_t HS_ProcessServerKxMsgIdentityHint(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg); + +/** + * @brief TLS1.3 derived secret + * + * @param deriveInfo [IN] secret derivation material + * @param isHashed [IN] true: indicates that the seed has been hashed false: indicates that the seed has not been + * hashed. + * @param outSecret [OUT] Output secret + * @param outLen [IN] Output secret length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + */ +int32_t HS_TLS13DeriveSecret(CRYPT_KeyDeriveParameters *deriveInfo, bool isHashed, uint8_t *outSecret, uint32_t outLen); + +int32_t HS_TLS13DeriveBinderKey(HITLS_HashAlgo hashAlgo, bool isExternalPsk, const uint8_t *earlySecret, + uint32_t secretLen, uint8_t *binderKey, uint32_t keyLen); + +/** + * @brief TLS1.3 Calculate the early secret. + * + * @param hashAlg [IN] secret derivation material + * @param psk [IN] PSK + * @param pskLen [OUT] PSK length + * @param earlySecret [IN] Output secret + * @param outLen [IN] Output secret length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT HKDF-Extract calculation failure + */ +int32_t HS_TLS13DeriveEarlySecret( + HITLS_HashAlgo hashAlgo, const uint8_t *psk, uint32_t pskLen, uint8_t *earlySecret, uint32_t *outLen); + +/** + * @brief TLS1.3 Calculate the secret in the next phase. + * + * @param hashAlg [IN] Hash algorithm + * @param inSecret [IN] secret of the current phase + * @param inLen [OUT] Current secret length + * @param givenSecret [IN] The secret specified by the + * @param givenLen [IN] Specify the secret length. + * @param outSecret [IN] Output secret + * @param outLen [IN/OUT] IN: Maximum buffer length OUT: Output secret length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT HKDF-Extract calculation failure + */ +int32_t HS_TLS13DeriveNextStageSecret(HITLS_HashAlgo hashAlgo, const uint8_t *inSecret, uint32_t inLen, + const uint8_t *givenSecret, uint32_t givenLen, uint8_t *outSecret, uint32_t *outLen); + +/** + * @brief TLS1.3 Calculate the FinishedKey. + * + * @param hashAlg [IN] Hash algorithm + * @param baseKey [IN] Key of the current phase + * @param baseKeyLen [IN] Current key length + * @param finishedkey [OUT] Output key + * @param finishedkeyLen [IN] Output key length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation failed. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + */ +int32_t HS_TLS13DeriveFinishedKey(HITLS_HashAlgo hashAlgo, const uint8_t *baseKey, uint32_t baseKeyLen, + uint8_t *finishedkey, uint32_t finishedkeyLen); + +/** + * @brief TLS1.3 Switch the traffickey. + * + * @param ctx [IN] TLS context + * @param secret [IN] secret for calculating writekey and writeiv + * @param secretLen [IN] Input the secret length. + * @param isOut [IN] It is used to determine writeSate and readState. + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation failed. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + */ +int32_t HS_SwitchTrafficKey(TLS_Ctx *ctx, uint8_t *secret, uint32_t secretLen, bool isOut); + +/** + * @brief Set parameters for initializing the panding state of the record layer. + * + * @param ctx [IN] TLS context + * @param isClient [IN] Whether it is a client + * @param keyPara [OUT] Output parameter + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMCPY_FAIL Memory Copy Failure + */ +int32_t HS_SetInitPendingStateParam(const TLS_Ctx *ctx, bool isClient, REC_SecParameters *keyPara); + +/** + * @brief TLS1.3 Derives the secret of the ServerHello procedure. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT HKDF-Extract calculation failed. + * @retval HITLS_CRYPT_ERR_CALC_SHARED_KEY Failed to calculate the shared key. + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation fails. + * @retval For details about other error codes, see the SAL_CRYPT_DigestFinal interface. + */ +int32_t HS_TLS13CalcServerHelloProcessSecret(TLS_Ctx *ctx); + +/** + * @brief TLS1.3 Derives the secret of the ServerFinish process. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation failed. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT HKDF-Extract calculation failed. + * @retval For details about other error codes, see the SAL_CRYPT_DigestFinal interface. + */ +int32_t HS_TLS13CalcServerFinishProcessSecret(TLS_Ctx *ctx); + +/** + * @brief TLS1.3 Update the traffic secret. + * + * @param ctx [IN] TLS context + * @param isOut [IN] It is used to determine writeSate and readState. + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation failed. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT HKDF-Extract calculation failure + * @retval For other error codes, see the SAL_CRYPT_DigestFinal interface. + */ +int32_t HS_TLS13UpdateTrafficSecret(TLS_Ctx *ctx, bool isOut); + +/** + * @brief TLS1.3 Derived by resumption_master_secret + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXTRACT HKDF-Extract calculation failure + * @retval HITLS_CRYPT_ERR_CALC_SHARED_KEY Failed to calculate the shared key. + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation failed. + * @retval For other error codes, see the SAL_CRYPT_DigestFinal interface + */ +int32_t HS_TLS13DeriveResumptionMasterSecret(TLS_Ctx *ctx); + +/** + * @brief TLS1.3 calculate session resumption PSK + * + * @param ctx [IN] TLS context + * @param ticketNonce [IN] Unique ID of the ticket issued on the, which is used to calculate the PSK for session + * resumption. + * @param ticketNonceSize [IN] ticketNonce length + * @param resumePsk [OUT] Output the PSK key. + * @param resumePskLen [IN] Output the PSK length. + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation fails. + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails. + */ +int32_t HS_TLS13DeriveResumePsk(const TLS_Ctx *ctx, const uint8_t *ticketNonce, uint32_t ticketNonceSize, + uint8_t *resumePsk, uint32_t resumePskLen); + +int32_t HS_TLS13DeriveHandshakeTrafficSecret(TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/handshake/common/include/hs_msg.h b/tls/handshake/common/include/hs_msg.h new file mode 100644 index 00000000..35525025 --- /dev/null +++ b/tls/handshake/common/include/hs_msg.h @@ -0,0 +1,371 @@ +/* + * 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 HS_MSG_H +#define HS_MSG_H + +#include +#include +#include "bsl_module_list.h" +#include "cert.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HS_MSG_HEADER_SIZE 4u +#define DTLS_HS_MSG_HEADER_SIZE 12u +#define HS_RANDOM_SIZE 32u +#define HS_RANDOM_DOWNGRADE_SIZE 8u +#define TLS_HS_MAX_SESSION_ID_SIZE 32u +#define TLS_HS_MIN_SESSION_ID_SIZE 24u +#define TLS_HS_MIN_COOKIE_SIZE 1u +#define TLS_HS_MAX_COOKIE_SIZE 255u + +#define DTLS_HS_MSGLEN_ADDR 1u /* DTLS message length address, which is used when parsing the DTLS message header. */ +/* DTLS message sequence number address, which is used for parsing the DTLS message header. */ +#define DTLS_HS_MSGSEQ_ADDR 4u +/* DTLS message fragment offset address, which is used when the DTLS message header is parsed. */ +#define DTLS_HS_FRAGMENT_OFFSET_ADDR 6u +/* DTLS message fragment length address, which is used when parsing the DTLS message header. */ +#define DTLS_HS_FRAGMENT_LEN_ADDR 9u + +/* Handshake message type */ +typedef enum { + HELLO_REQUEST = 0, + CLIENT_HELLO = 1, + SERVER_HELLO = 2, + HELLO_VERIFY_REQUEST = 3, + NEW_SESSION_TICKET = 4, + END_OF_EARLY_DATA = 5, + HELLO_RETRY_REQUEST = 6, + ENCRYPTED_EXTENSIONS = 8, + CERTIFICATE = 11, + SERVER_KEY_EXCHANGE = 12, + CERTIFICATE_REQUEST = 13, + SERVER_HELLO_DONE = 14, + CERTIFICATE_VERIFY = 15, + CLIENT_KEY_EXCHANGE = 16, + FINISHED = 20, + CERTIFICATE_URL = 21, + CERTIFICATION_STATUS = 22, + SUPPLEMENTAL_DATA = 23, + KEY_UPDATE = 24, + MESSAGE_HASH = 254, + HS_MSG_TYPE_END = 255 +} HS_MsgType; + +typedef enum { + PSK_KE = 0, + PSK_DHE_KE = 1, + PSK_KEY_EXCHANGEMODE_END = 255 +} HS_PskKeyExchMode; + +typedef struct { + HITLS_KeyUpdateRequest requestUpdate; +} KeyUpdateMsg; + +typedef struct { + ListHead head; + uint16_t group; /* Naming group of keys to be exchanged */ + uint16_t keyExchangeSize; + uint8_t *keyExchange; /* Key exchange information */ +} KeyShare; + +typedef struct OfferedPsks { + ListHead pskNode; /* Multiple PSK linked lists are formed through pskNode. The actual data of this node is the + following fields */ + uint8_t *identity; /* pskid and binder are in one-to-one mapping. */ + uint8_t *binder; /* HMAC value */ + uint32_t obfuscatedTicketAge; /* An obfuscated version of the age of the key */ + uint16_t identitySize; /* bytes of identity */ + uint8_t binderSize; /* bytes of binder */ + bool isValid; /* is binder valid */ +} PreSharedKey; + +typedef struct { + uint16_t *supportedGroups; + uint16_t *signatureAlgorithms; + uint8_t *pointFormats; + uint8_t *alpnList; /* application-layer protocol negotiation list */ + uint8_t *serverName; /* serverName after parsing */ + uint8_t *secRenegoInfo; /* renegotiation extension information */ + uint8_t *ticket; /* ticket information */ + + uint32_t ticketSize; + uint16_t supportedGroupsSize; + uint16_t signatureAlgorithmsSize; + uint16_t alpnListSize; /* application-layer protocol negotiation list len */ + uint16_t serverNameSize; + uint8_t pointFormatsSize; + uint8_t serverNameType; /* Type of the parsed serverName. */ + uint8_t secRenegoInfoSize; /* Length of the security renegotiation information */ + uint8_t reserved[1]; /* Four-byte alignment */ + + /* TLS1.3 */ + uint16_t *supportedVersions; + uint8_t *cookie; + uint8_t *keModes; + uint8_t keModesSize; + uint8_t supportedVersionsCount; /* Number of supported version */ + uint16_t cookieLen; + + PreSharedKey *preSharedKey; + KeyShare *keyShare; /* In the ClientHello message, this extension provides a set of KeyShares */ +} ExtensionContent; + +typedef struct { + bool haveSupportedGroups; + bool haveSignatureAlgorithms; + bool havePointFormats; + bool haveExtendedMasterSecret; + bool haveSupportedVers; + bool haveCookie; /* Whether there is a cookie (involved in TLS1.3 ClientHello) */ + bool havePostHsAuth; /* Indicates whether the Client (TLS1.3) is willing to receive the Certificate Request + message. */ + bool haveKeyShare; + bool havePskExMode; /* Indicates whether the TLS1.3 key exchange mode exists. */ + bool havePreShareKey; /* Indicates whether the pre-shared key exists. */ + bool haveAlpn; /* Whether there is Alpn */ + bool haveServerName; /* Whether the ServerName extension exists. */ + bool haveSecRenego; /* Whether security renegotiation exists. */ + bool haveTicket; /* Indicates whether a ticket is available. */ + bool haveEncryptThenMac; /* Indicates whether EncryptThenMac is supported. */ +} ExtensionFlag; + +typedef struct { + ExtensionFlag flag; + ExtensionContent content; +} ClientHelloExt; + +/* It is used to transmit client hello message */ +typedef struct { + uint8_t randomValue[HS_RANDOM_SIZE]; /* random number group */ + uint8_t *sessionId; + uint8_t *cookie; /* Cookie (for DTLS only) */ + uint16_t *cipherSuites; + uint16_t version; + uint16_t cipherSuitesSize; + uint8_t sessionIdSize; + uint8_t compressionMethodsSize; + uint8_t *compressionMethods; + uint8_t cookieLen; + bool haveScsvCipher; /* According to RFC 5746, a special signaling cipher suite value (SCSV) can be used to indicate + that security renegotiation is supported. */ + uint8_t refCnt; /* Do not involve multiple threads. Process the hrr check clientHello. */ + uint32_t truncateHelloLen; /* is used for binder calculation. */ + ClientHelloExt extension; +} ClientHelloMsg; + +/* It is used to transmit server hello message */ +typedef struct { + uint16_t version; + uint16_t cipherSuite; + uint8_t randomValue[HS_RANDOM_SIZE]; /* random number group */ + uint8_t *sessionId; + uint8_t *pointFormats; + uint8_t *alpnSelected; /* selected alpn protocol */ + uint8_t *cookie; + uint8_t *secRenegoInfo; + KeyShare keyShare; + uint16_t alpnSelectedSize; /* selected alpn protocol length */ + uint16_t supportedVersion; + uint16_t cookieLen; + uint16_t selectedIdentity; /* TLS 1.3 psk required */ + uint8_t sessionIdSize; + uint8_t pointFormatsSize; + uint8_t secRenegoInfoSize; /* Length of the security renegotiation information */ + bool havePointFormats; + bool haveExtendedMasterSecret; + bool haveSupportedVersion; + bool haveCookie; /* Indicates whether the cookie length is involved in TLS1.3 HelloRetryRequest. */ + bool haveKeyShare; /* Whether KeyShare is extended. */ + bool haveSelectedIdentity; /* Indicates whether the Pre_PSK is selected. */ + bool haveSelectedAlpn; /* Whether the application layer protocol is selected. */ + bool haveServerName; + bool haveSecRenego; + bool haveTicket; + bool haveEncryptThenMac; + bool reserved[2]; /* Four-byte alignment */ +} ServerHelloMsg; + +/* Transmits certificate message */ +typedef struct { + CERT_Item *cert; /* Certificate message content */ + uint32_t certCount; /* Number of certificates */ + uint8_t *certificateReqCtx; /* Used by the TLS 1.3 */ + uint32_t certificateReqCtxSize; /* Used by the TLS 1.3 */ +} CertificateMsg; + +typedef struct { + HITLS_ECParameters ecPara; /* Elliptic curve field parameter of the ECDH public key */ + uint32_t pubKeySize; /* Length of the ecdh public key */ + uint8_t *pubKey; /* ecdh public key content */ + uint16_t signAlgorithm; + uint16_t signSize; + uint8_t *signData; +} ServerEcdh; +typedef struct { + uint8_t *p; + uint8_t *g; + uint16_t plen; + uint16_t glen; + uint8_t *pubkey; + uint32_t pubKeyLen; + uint16_t signAlgorithm; + uint16_t signSize; + uint8_t *signData; +} ServerDh; + +/* Used to transfer the key exchange content of the server */ +typedef struct { + uint8_t *pskIdentityHint; /* psk identity negotiation prompt message */ + uint32_t hintSize; + HITLS_KeyExchAlgo keyExType; /* key exchange mode */ + union { + ServerEcdh ecdh; + ServerDh dh; + } keyEx; +} ServerKeyExchangeMsg; + +/* Used to transfer the client key exchange content */ +typedef struct { + uint8_t *pskIdentity; + uint32_t pskIdentitySize; + uint32_t dataSize; /* Key exchange data length */ + uint8_t *data; /* Key exchange data. */ +} ClientKeyExchangeMsg; + +/* Transmits certificate request message */ +typedef struct { + uint8_t *certTypes; + uint16_t *signatureAlgorithms; + uint8_t reserved; /* Four-byte alignment */ + uint8_t certTypesSize; + uint16_t signatureAlgorithmsSize; + uint8_t *certificateReqCtx; /* Used by the TLS 1.3 */ + uint32_t certificateReqCtxSize; /* This field is used by the TLS 1.3. The value is not 0 only for the + authentication after the handshake */ + bool haveSignatureAndHashAlgo; +} CertificateRequestMsg; + +/* Transmits certificate verification message */ +typedef struct { + uint16_t signHashAlg; /* Signature hash algorithm, which is available only for TLS1.2 and DTLS1.2 */ + uint16_t signSize; /* Length of the signature data. */ + uint8_t *sign; /* Signature data */ +} CertificateVerifyMsg; + +/* It is used to transmit Ticket message + RFC5077 3.3 NewSessionTicket Handshake Message + struct { + uint32 ticket_lifetime_hint; + opaque ticket<0..2^16-1>; + } NewSessionTicket; + + TLS1.3: + struct { + uint32 ticket_lifetime; + uint32 ticket_age_add; + opaque ticket_nonce<0..255>; + opaque ticket<1..2^16-1>; + Extension extensions<0..2^16-2>; + } NewSessionTicket; +*/ +typedef struct { + uint32_t ticketLifetimeHint; /* ticket timeout interval, in seconds */ + uint32_t ticketAgeAdd; /* ticket_age_add: a random number generated each time a ticket is issued. */ + uint32_t ticketNonceSize; /* ticket_nonce length */ + uint8_t *ticketNonce; /* ticketNonce: Unique ID of the ticket issued on the connection, starting from 0 and + increasing in ascending order. */ + uint32_t ticketSize; + uint8_t *ticket; /* ticket */ +} NewSessionTicketMsg; + +/* It is used to transmit finish message */ +typedef struct { + uint32_t verifyDataSize; + uint8_t *verifyData; +} FinishedMsg; + +typedef struct { + uint16_t *supportedGroups; + uint16_t supportedGroupsSize; + + bool haveSupportedGroups; + bool haveEarlyData; + bool haveServerName; +} EncryptedExtensions; + +/* Used to parse the handshake message header. */ +typedef struct { + HS_MsgType type; + uint32_t length; /* handshake msg body length */ + uint16_t sequence; /* DTLS Indicates the number of the handshake message. Each time a new handshake message is + sent, one is added. Retransmission does not add up */ + bool isHsMsgComplete; + bool hasParsedHeader; /* Indicates whether the handshake message header is processed. */ + uint32_t fragmentOffset; /* Fragment offset of DTLS handshake message */ + uint32_t fragmentLength; /* Fragment length of the DTLS handshake message */ + const uint8_t *rawMsg; /* Complete handshake information */ + uint32_t headerAndBodyLen; +} HS_MsgInfo; + +/* It is used to transmit handshake message */ +typedef struct { + HS_MsgType type; + uint32_t length; + uint16_t sequence; /* DTLS Indicates the number of the handshake message. Each time a new handshake message is + sent, one is added. Retransmission does not add up */ + uint8_t reserved[2]; /* fill 2 bytes for 4-byte alignment. */ + uint32_t fragmentOffset; /* Fragment offset of DTLS handshake message. */ + uint32_t fragmentLength; /* Fragment length of the DTLS handshake message */ + union { + ClientHelloMsg clientHello; + ServerHelloMsg serverHello; + EncryptedExtensions encryptedExtensions; + CertificateMsg certificate; + ClientKeyExchangeMsg clientKeyExchange; + ServerKeyExchangeMsg serverKeyExchange; + CertificateRequestMsg certificateReq; + CertificateVerifyMsg certificateVerify; + NewSessionTicketMsg newSessionTicket; + FinishedMsg finished; + KeyUpdateMsg keyUpdate; + } body; +} HS_Msg; + +/* Reassembles fragmented messages */ +typedef struct { + ListHead head; + HS_MsgType type; + uint16_t sequence; /* DTLS Indicates the number of the handshake message. Each time a new handshake message is + sent, one is added. Retransmission does not add up */ + bool isReassComplete; /* Indicates whether the message is reassembled. */ + uint8_t reserved; /* Padded with 1 byte for 4-byte alignment. */ + uint8_t *reassBitMap; /* bitmap, used for processing duplicate fragmented message and calculating whether the + fragmented message are completely reassembled. */ + uint8_t *msg; /* Used to store the handshake messages during the reassembly. */ + uint32_t msgLen; /* Total length of a message, including the message header. */ +} HS_ReassQueue; + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end HS_MSG_H */ diff --git a/tls/handshake/common/include/hs_verify.h b/tls/handshake/common/include/hs_verify.h new file mode 100644 index 00000000..8d0f1e32 --- /dev/null +++ b/tls/handshake/common/include/hs_verify.h @@ -0,0 +1,145 @@ +/* + * 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 HS_VERIFY_H +#define HS_VERIFY_H + +#include +#include +#include "hitls_crypt_type.h" +#include "tls.h" +#include "hs_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the verify context + * @attention If it has been initialized, the verify context will be reset + * + * @param hsCtx [IN] Handshake context + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + */ +int32_t VERIFY_Init(HS_Ctx *hsCtx); + +/** + * @brief Release verify context + * + * @param hsCtx [IN] Handshake context + */ +void VERIFY_Deinit(HS_Ctx *hsCtx); + +/** + * @brief Calculate verify data + * + * @param ctx [IN] tls Context + * @param isClient [IN] Indicates whether the context is client. If yes, the system calculates the verify data + * sent by the client. Otherwise, the system calculates the verify data sent by the server. + * @param masterSecret [IN] + * @param masterSecretLen [IN] + * + * @retval HITLS_SUCCESS + * @retval HITLS_UNREGISTERED_CALLBACK Callback unregistered + * @retval HITLS_CRYPT_ERR_DIGEST Hash operation failed + * @retval HITLS_CRYPT_ERR_HMAC HMAC operation failed + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + */ +int32_t VERIFY_CalcVerifyData(TLS_Ctx *ctx, bool isClient, const uint8_t *masterSecret, uint32_t masterSecretLen); + +/** + * @brief Calculate the client verify signature data + * + * @param ctx [IN] TLS context. Different TLS and DTLS versions require different processing + * @param privateKey [IN] Certificate private key + * @param signScheme [IN] Signature hash algorithm + * + * @retval HITLS_SUCCESS + * @retval HITLS_PACK_SIGNATURE_ERR Signing failed + */ +int32_t VERIFY_CalcSignData(TLS_Ctx *ctx, HITLS_CERT_Key *privateKey, HITLS_SignHashAlgo signScheme); + +/** + * @brief Verify the client signature data + * + * @param ctx [IN] TLS context. Different TLS and DTLS versions require different processing + * @param pubkey [IN] Public key of the device certificate + * @param signScheme [IN] Signature hash algorithm + * @param signData [IN] Signature + * @param signDataLen [IN] Signature length + * + * @retval HITLS_SUCCESS + * @retval HITLS_PACK_SIGNATURE_ERR Signing failed + */ +int32_t VERIFY_VerifySignData(TLS_Ctx *ctx, HITLS_CERT_Key *pubkey, HITLS_SignHashAlgo signScheme, + const uint8_t *signData, uint16_t signDataLen); + +/** + * @brief Set the verify data + * + * @param ctx [IN] verify context + * @param verifyData [IN] + * @param verifyDataLen [IN] + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMCPY_FAIL Memory copy failed + */ +int32_t VERIFY_SetVerifyData(VerifyCtx *ctx, const uint8_t *verifyData, uint32_t verifyDataLen); + +/** + * @brief Obtain the verify data + * + * @param ctx [IN] verify context + * @param verifyData [OUT] + * @param verifyDataLen [IN/OUT] IN: maximum length of data OUT:verify data Len + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMCPY_FAIL Memory copy failed + */ +int32_t VERIFY_GetVerifyData(const VerifyCtx *ctx, uint8_t *verifyData, uint32_t *verifyDataLen); + +/** + * @brief TLS1.3 calculate verify data + * + * @param ctx [IN] TLS Context + * @param isClient [IN] Indicates whether the context is client. If yes, the system calculates the verify data + * sent by the client. Otherwise, the system calculates the verify data sent by the server. + * @retval HITLS_SUCCESS + * @retval HITLS_UNREGISTERED_CALLBACK Callback unregistered + * @retval HITLS_CRYPT_ERR_DIGEST Hash operation failed + * @retval HITLS_CRYPT_ERR_HMAC HMAC operation failed + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + */ +int32_t VERIFY_Tls13CalcVerifyData(TLS_Ctx *ctx, bool isClient); + +/** + * @brief Reprocess the verify data for the hello retry request message + * + * @param ctx [IN] TLS Context + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t VERIFY_HelloRetryRequestVerifyProcess(TLS_Ctx *ctx); + +int32_t VERIFY_CalcPskBinder(const TLS_Ctx *ctx, HITLS_HashAlgo hashAlgo, bool isExternalPsk, uint8_t *psk, + uint32_t pskLen, const uint8_t *msg, uint32_t msgLen, uint8_t *binder, uint32_t binderLen); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ +#endif /* end HS_VERIFY_H */ diff --git a/tls/handshake/common/include/transcript_hash.h b/tls/handshake/common/include/transcript_hash.h new file mode 100644 index 00000000..22c0b106 --- /dev/null +++ b/tls/handshake/common/include/transcript_hash.h @@ -0,0 +1,76 @@ +/* + * 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 TRANSCRIPT_HASH_H +#define TRANSCRIPT_HASH_H + +#include +#include "hitls_crypt_type.h" +#include "hs_ctx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the hash algorithm + * + * @param ctx [IN] verify context + * @param hashAlgo [IN] hash algorithm + * + * @retval HITLS_SUCCESS + * @retval HITLS_CRYPT_ERR_DIGEST hash operation failed + * @retval HITLS_UNREGISTERED_CALLBACK The callback function is not registered. + */ +int32_t VERIFY_SetHash(VerifyCtx *ctx, HITLS_HashAlgo hashAlgo); + +/** + * @brief Add handshake message data + * + * @param ctx [IN] verify context + * @param data [IN] Handshake message data + * @param len [IN] Data length + * + * @retval HITLS_SUCCESS + * @retval HITLS_UNREGISTERED_CALLBACK The callback function is not registered. + * @retval HITLS_CRYPT_ERR_DIGEST hash operation failed + * @retval HITLS_MEMCPY_FAIL + * @retval HITLS_MEMALLOC_FAIL + */ +int32_t VERIFY_Append(VerifyCtx *ctx, const uint8_t *data, uint32_t len); + +/** + * @brief Calculate the SessionHash + * + * @param ctx [IN] verify context + * @param digest [OUT] digest data + * @param digestLen [IN/OUT] IN:maximum length of digest OUT:digest length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see SAL_CRYPT_DigestFinal + */ +int32_t VERIFY_CalcSessionHash(VerifyCtx *ctx, uint8_t *digest, uint32_t *digestLen); + +/** + * @brief Release the message cache linked list + * + * @param ctx [IN] verify context + */ +void VERIFY_FreeMsgCache(VerifyCtx *ctx); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ +#endif /* end TRANSCRIPT_HASH_H */ diff --git a/tls/handshake/common/src/hs_common.c b/tls/handshake/common/src/hs_common.c new file mode 100644 index 00000000..4a445b58 --- /dev/null +++ b/tls/handshake/common/src/hs_common.c @@ -0,0 +1,793 @@ +/* + * 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 +#include "securec.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls.h" +#include "hitls_error.h" +#include "tls_config.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "uio_base.h" +#include "indicator.h" +#include "pack.h" +#include "security.h" +#include "parse.h" +#include "hs_kx.h" +#include "hs.h" +#include "hs_common.h" + + +#define DTLS_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" /* dtls SCTP auth key label */ + +typedef int32_t (*GET_EXTSIZE_FUNC)(TLS_Ctx *ctx, uint32_t *exSize); +typedef struct { + HITLS_HandshakeState state; + GET_EXTSIZE_FUNC getSizeFunc; +} GetHSMsgSize; + +/* Fixed random value of the hello retry request packet */ +const uint8_t g_hrrRandom[HS_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, + 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c +}; + +const uint8_t g_tls12Downgrade[HS_DOWNGRADE_RANDOM_SIZE] = { + 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01 +}; + +const uint8_t *HS_GetHrrRandom(uint32_t *len) +{ + *len = HS_RANDOM_SIZE; + return g_hrrRandom; +} + +const uint8_t *HS_GetTls12DowngradeRandom(uint32_t *len) +{ + *len = HS_DOWNGRADE_RANDOM_SIZE; + return g_tls12Downgrade; +} + +uint32_t HS_GetVersion(const TLS_Ctx *ctx) +{ + if (ctx->negotiatedInfo.version > 0) { + /* The version has been negotiated */ + return ctx->negotiatedInfo.version; + } else { + /* If the version is not negotiated, the latest version supported by the local is returned */ + return ctx->config.tlsConfig.maxVersion; + } +} + +const char *HS_GetStateStr(uint32_t state) +{ + /** The handshake status is abnormal. */ + if (state > TRY_RECV_FINISH) { + return "unknown"; + } + + static const char *stateMachineStr[] = { + [TLS_IDLE] = "idle", + [TLS_CONNECTED] = "connected", + [TRY_SEND_HELLO_REQUEST] = "send hello request", + [TRY_SEND_CLIENT_HELLO] = "send client hello", + [TRY_SEND_HELLO_RETRY_REQUEST] = "send hello retry request", + [TRY_SEND_HELLO_VERIFY_REQUEST] = "send hello verify request", + [TRY_SEND_SERVER_HELLO] = "send server hello", + [TRY_SEND_ENCRYPTED_EXTENSIONS] = "send encrypted extensions", + [TRY_SEND_CERTIFICATE] = "send certificate", + [TRY_SEND_SERVER_KEY_EXCHANGE] = "send server key exchange", + [TRY_SEND_CERTIFICATE_REQUEST] = "send certificate request", + [TRY_SEND_SERVER_HELLO_DONE] = "send server hello done", + [TRY_SEND_CERTIFICATE_VERIFY] = "send certificate verify", + [TRY_SEND_NEW_SESSION_TICKET] = "send new session ticket", + [TRY_SEND_CLIENT_KEY_EXCHANGE] = "send client key exchange", + [TRY_SEND_CHANGE_CIPHER_SPEC] = "send change cipher spec", + [TRY_SEND_END_OF_EARLY_DATA] = "send end of early data", + [TRY_SEND_FINISH] = "send finished", + [TRY_RECV_HELLO_VERIFY_REQUEST] = "recv hello verify request", + [TRY_RECV_CLIENT_HELLO] = "recv client hello", + [TRY_RECV_SERVER_HELLO] = "recv server hello", + [TRY_RECV_ENCRYPTED_EXTENSIONS] = "recv encrypted extensions", + [TRY_RECV_CERTIFICATE] = "recv certificate", + [TRY_RECV_SERVER_KEY_EXCHANGE] = "recv server key exchange", + [TRY_RECV_CERTIFICATE_REQUEST] = "recv certificate request", + [TRY_RECV_SERVER_HELLO_DONE] = "recv server hello done", + [TRY_RECV_CERTIFICATE_VERIFY] = "recv certificate verify", + [TRY_RECV_NEW_SESSION_TICKET] = "recv new session ticket", + [TRY_RECV_CLIENT_KEY_EXCHANGE] = "recv client key exchange", + [TRY_RECV_END_OF_EARLY_DATA] = "recv end of early data", + [TRY_RECV_FINISH] = "recv finished", + }; + + /** Status character string */ + return stateMachineStr[state]; +} + +const char *HS_GetMsgTypeStr(HS_MsgType type) +{ + switch (type) { + case HELLO_REQUEST: + return "hello request"; + case CLIENT_HELLO: + return "client hello"; + case SERVER_HELLO: + return "server hello"; + case ENCRYPTED_EXTENSIONS: + return "encrypted extensions"; + case CERTIFICATE: + return "certificate"; + case SERVER_KEY_EXCHANGE: + return "server key exchange"; + case CERTIFICATE_REQUEST: + return "certificate request"; + case SERVER_HELLO_DONE: + return "server hello done"; + case CERTIFICATE_VERIFY: + return "certificate verify"; + case CLIENT_KEY_EXCHANGE: + return "client key exchange"; + case NEW_SESSION_TICKET: + return "new session ticket"; + case FINISHED: + return "finished"; + default: + break; + } + return "unknown"; +} + +int32_t HS_ChangeState(TLS_Ctx *ctx, uint32_t nextState) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + hsCtx->state = nextState; + if (ctx->isClient) { + INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_STATE_CONNECT_LOOP, INDICATE_VALUE_SUCCESS); + } else { + INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_STATE_ACCEPT_LOOP, INDICATE_VALUE_SUCCESS); + } + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15573, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "handshake state machine change to:%s.", HS_GetStateStr(nextState)); + return HITLS_SUCCESS; +} + +int32_t HS_CombineRandom(const uint8_t *random1, const uint8_t *random2, uint32_t randomSize, + uint8_t *dest, uint32_t destSize) +{ + /** If the random number length is 0 or the memory address is less than twice the random number length, return an + * error code. */ + if ((randomSize == 0u) || (destSize < randomSize * 2)) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RANDOM_SIZE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15574, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid randomSize for combine random.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_RANDOM_SIZE_ERR; + } + + /** Copy the first random value */ + if (memcpy_s(dest, destSize, random1, randomSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15575, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "combine random1 fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + /** Copy the second random value */ + if (memcpy_s(&dest[randomSize], destSize - randomSize, random2, randomSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15576, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "combine random2 fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the public key length of the Named Curve curve of the ECDHE key agreement algorithm. + * @attention The length of the public key cannot exceed 255 bytes. + * @param namedcurve [IN] Named Curve Enumerated type + * + * @retval len Length of the public key + */ +uint32_t HS_GetNamedCurvePubkeyLen(HITLS_NamedGroup namedcurve) +{ + uint32_t len = 0u; + switch (namedcurve) { + case HITLS_EC_GROUP_CURVE25519: + len = 32u; /* 32 elliptic curve X25519 public key length */ + break; + case HITLS_EC_GROUP_SECP256R1: + case HITLS_EC_GROUP_BRAINPOOLP256R1: + len = 65u; /* (32 * 2) + 1 elliptic curve SECP256R1,brainpoolP256r1 public key length */ + break; + case HITLS_EC_GROUP_SECP384R1: + case HITLS_EC_GROUP_BRAINPOOLP384R1: + len = 97u; /* (48 * 2) + 1 elliptic curve SECP384R1,brainpoolP384r1 public key length */ + break; + case HITLS_EC_GROUP_BRAINPOOLP512R1: + len = 129u; /* Length of the elliptic curve brainpoolP512r1 public key */ + break; + case HITLS_EC_GROUP_SECP521R1: + len = 133u; /* (66 * 2) + 1 elliptic curve SECP521R1 public key length */ + break; +#ifndef HITLS_NO_TLCP11 + case HITLS_EC_GROUP_SM2: + len = 65u; /* (32 * 2) + 1 elliptic curve SM2 public key length */ + break; +#endif + case HITLS_FF_DHE_2048: + len = 256u; /* HITLS_FF_DHE_2048 public key length */ + break; + case HITLS_FF_DHE_3072: + len = 384u; /* HITLS_FF_DHE_3072 public key length */ + break; + case HITLS_FF_DHE_4096: + len = 512u; /* HITLS_FF_DHE_4096 public key length */ + break; + case HITLS_FF_DHE_6144: + len = 768u; /* HITLS_FF_DHE_6144 public key length */ + break; + case HITLS_FF_DHE_8192: + len = 1024u; /* HITLS_FF_DHE_8192 public key length */ + break; + default: + break; + } + return len; +} + +#ifndef HITLS_NO_TLCP11 +uint8_t *HS_PrepareSignDataTlcp(const TLS_Ctx *ctx, const uint8_t *partSignData, uint32_t partSignDataLen, + uint32_t *signDataLen) +{ + /* Signature data: client random number + server random number + exchange parameter length + key exchange packet + * data/encryption certificate */ + uint32_t exchParamLen = 3; + uint32_t randomLen = HS_RANDOM_SIZE * 2u; + uint32_t dataLen = randomLen + partSignDataLen + exchParamLen; + + /* Allocate the signature data memory. */ + uint8_t *data = BSL_SAL_Calloc(1u, dataLen); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15577, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signature data memory alloc fail.", 0, 0, 0, 0); + return NULL; + } + + /* Replicate the random number of the client */ + (void)memcpy_s(data, dataLen, ctx->hsCtx->clientRandom, HS_RANDOM_SIZE); + /* Replicate the random number on the server */ + (void)memcpy_s(&data[HS_RANDOM_SIZE], dataLen - HS_RANDOM_SIZE, ctx->hsCtx->serverRandom, HS_RANDOM_SIZE); + /* Fill the length of the key exchange parameter */ + BSL_Uint24ToByte(partSignDataLen, &data[randomLen]); + /* Copy key exchange packet data */ + if (memcpy_s(&data[randomLen] + exchParamLen, dataLen - randomLen - exchParamLen, + partSignData, partSignDataLen) != EOK) { + BSL_SAL_FREE(data); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15578, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy key exchange data fail.", 0, 0, 0, 0); + return NULL; + } + + *signDataLen = dataLen; + return data; +} +#endif + +uint8_t *HS_PrepareSignData(const TLS_Ctx *ctx, const uint8_t *partSignData, + uint32_t partSignDataLen, uint32_t *signDataLen) +{ + int32_t ret; + /* Signature data: client random number + server random number + key exchange packet data/encryption certificate */ + uint32_t randomLen = HS_RANDOM_SIZE * 2u; + uint32_t dataLen = randomLen + partSignDataLen; + + /* Allocate the signature data memory. */ + uint8_t *data = BSL_SAL_Calloc(1u, dataLen); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return NULL; + } + + /* Replicate the random number of the client */ + (void)memcpy_s(data, dataLen, ctx->hsCtx->clientRandom, HS_RANDOM_SIZE); + /* Replicate the random number on the server */ + (void)memcpy_s(&data[HS_RANDOM_SIZE], dataLen - HS_RANDOM_SIZE, ctx->hsCtx->serverRandom, HS_RANDOM_SIZE); + /* Copy key exchange packet data */ + ret = memcpy_s(&data[randomLen], dataLen - randomLen, partSignData, partSignDataLen); + if (ret != EOK) { + BSL_SAL_Free(data); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return NULL; + } + + *signDataLen = dataLen; + return data; +} + +#ifndef HITLS_NO_DTLS12 +/** + * @brief Calculate the sctp auth key + * @details auth key: PRF(SecurityParameters.master_secret, label, + * SecurityParameters.client_random + + * SecurityParameters.server_random)[length] + * + * @param ctx [IN] TLS context + * @param authKey [OUT] Authorization key + * @param authKeyLen [IN] Key length + * + * @retval HITLS_SUCCESS calculation is complete. + * @retval HITLS_MSG_HANDLE_RANDOM_SIZE_ERR The random number length is incorrect. + * @retval For other error codes, see SAL_CRYPT_PRF. + */ +int32_t CalcSctpAuthKey(const TLS_Ctx *ctx, uint8_t *authKey, uint32_t authKeyLen) +{ + int32_t ret; + uint8_t randomValue[HS_RANDOM_SIZE * 2] = {0}; // key derivation seed, with the length of two random characters + uint32_t randomValueSize = HS_RANDOM_SIZE * 2; // key derivation seed, with the length of two random characters + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Combine the two random values */ + ret = HS_CombineRandom(hsCtx->clientRandom, hsCtx->serverRandom, HS_RANDOM_SIZE, randomValue, randomValueSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15579, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "combine random fail.", 0, 0, 0, 0); + return ret; + } + + CRYPT_KeyDeriveParameters deriveInfo; + deriveInfo.hashAlgo = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + deriveInfo.secret = hsCtx->masterKey; + deriveInfo.secretLen = MASTER_SECRET_LEN; + deriveInfo.label = (const uint8_t *)DTLS_SCTP_AUTH_LABEL; + deriveInfo.labelLen = strlen(DTLS_SCTP_AUTH_LABEL); + deriveInfo.seed = randomValue; + deriveInfo.seedLen = randomValueSize; + /** Key derivation */ + ret = SAL_CRYPT_PRF(&deriveInfo, authKey, authKeyLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15580, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_PRF fail when calc sctp auth key.", 0, 0, 0, 0); + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t HS_SetSctpAuthKey(TLS_Ctx *ctx) +{ + /* If the bottom layer is not SCTP, the auth key does not need to be configured and return HITLS_SUCCESS */ + if (BSL_UIO_GetTransportType(ctx->uio) != BSL_UIO_SCTP) { + return HITLS_SUCCESS; + } + + int32_t ret; + uint8_t authKey[DTLS_SCTP_SHARED_AUTHKEY_LEN] = {0}; + uint16_t authKeyLen = sizeof(authKey); + + ret = CalcSctpAuthKey(ctx, authKey, authKeyLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15581, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calc sctp auth key failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* If the UIO_SctpAddAuthKey is added but not active, return HITLS_SUCCESS when the interface + is invoked again */ + BSL_UIO_SctpAuthKey key = {0}; + key.authKey = authKey; + key.authKeySize = authKeyLen; + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY, (int32_t)sizeof(BSL_UIO_SctpAuthKey), &key); + /* Clear sensitive information */ + BSL_SAL_CleanseData(authKey, DTLS_SCTP_SHARED_AUTHKEY_LEN); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_UIO_SCTP_ADD_AUTH_KEY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15582, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "uio add sctp auth shared key failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_UIO_SCTP_ADD_AUTH_KEY_FAIL; + } + + return HITLS_SUCCESS; +} + +int32_t HS_ActiveSctpAuthKey(TLS_Ctx *ctx) +{ + /* If the bottom layer is not SCTP, the auth key does not need to be configured and + * return HITLS_SUCCESS. + */ + if (BSL_UIO_GetTransportType(ctx->uio) != BSL_UIO_SCTP) { + return HITLS_SUCCESS; + } + + int32_t ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY, 0, NULL); + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15583, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "next sctp auth key error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_UIO_SCTP_ACTIVE_AUTH_KEY_FAIL; + } + return HITLS_SUCCESS; +} + +int32_t HS_DeletePreviousSctpAuthKey(TLS_Ctx *ctx) +{ + int32_t ret; + + if (BSL_UIO_GetTransportType(ctx->uio) != BSL_UIO_SCTP) { + return HITLS_SUCCESS; + } + + /* After the handshake is complete, delete the old sctp auth key */ + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY, 0, NULL); + if (ret != BSL_SUCCESS) { + ret = HITLS_UIO_SCTP_DEL_AUTH_KEY_FAIL; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15584, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "uio delete sctp auth shared key failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + return HITLS_SUCCESS; +} +#endif /* end #ifndef HITLS_NO_DTLS12 */ + +int32_t HS_GetSupportedCertTypeList(const TLS_Config *config, uint8_t *buf, uint32_t bufSize, uint32_t *listSize) +{ + bool isCertTypeSupported[MAX_CERT_TYPE_LISTS_SIZE] = {0}; + uint32_t supportedCertTypesSize = 0; + uint32_t bufOffset = 0; + for (uint32_t i = 0; i < config->cipherSuitesSize; i++) { + /* Find the supported certificate type based on the configured cipher suite and return the certificate type */ + uint8_t type = CFG_GetCertTypeByCipherSuite(config->cipherSuites[i]); + if ((type != CERT_TYPE_UNKNOWN) && (isCertTypeSupported[type] == false)) { + if (bufSize <= bufOffset) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15585, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buf length of cert type is not enough.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + buf[bufOffset++] = type; + isCertTypeSupported[type] = true; + supportedCertTypesSize++; + } + } + *listSize = supportedCertTypesSize; + return HITLS_SUCCESS; +} + +bool IsNeedServerKeyExchange(const TLS_Ctx *ctx) +{ + HITLS_KeyExchAlgo kxAlg = ctx->negotiatedInfo.cipherSuiteInfo.kxAlg; + + /* Special: If the PSK identity hint is set, the PSK and RSA_PSK may also need to send + * the ServerKeyExchange message + */ + if ((kxAlg == HITLS_KEY_EXCH_PSK) || (kxAlg == HITLS_KEY_EXCH_RSA_PSK)) { + /* In this case, the client receives the ServerKeyExchange message by default */ + if (ctx->isClient) { + return true; + } else { + /* If the PSK identity hint is set on the server, the ServerKeyExchange message needs to be sent */ + if (ctx->config.tlsConfig.pskIdentityHint != NULL) { + return true; + } + return false; + } + } +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + return true; /* The TLCP needs to send the ServerKeyExchange message. */ + } +#endif + /* The ECDH and DH certificates already contain the public key information, and the ServerKeyExchange message + * is not required. */ + /* RSA keys are generated by the client, and the ServerKeyExchange message is not required. */ + return ((kxAlg != HITLS_KEY_EXCH_ECDH) && (kxAlg != HITLS_KEY_EXCH_DH) && (kxAlg != HITLS_KEY_EXCH_RSA)); +} + +bool IsPskNegotiation(const TLS_Ctx *ctx) +{ + HITLS_KeyExchAlgo kxAlg = ctx->negotiatedInfo.cipherSuiteInfo.kxAlg; + + return ((kxAlg == HITLS_KEY_EXCH_ECDHE_PSK) || (kxAlg == HITLS_KEY_EXCH_DHE_PSK) || + (kxAlg == HITLS_KEY_EXCH_RSA_PSK) || (kxAlg == HITLS_KEY_EXCH_PSK)); +} + +/* Check whether the certificate needs to be prepared. */ +bool IsNeedCertPrepare(const CipherSuiteInfo *cipherSuiteInfo) +{ + if (cipherSuiteInfo == NULL) { + return false; + } + + /* PSK related ciphersuite */ + switch (cipherSuiteInfo->kxAlg) { + case HITLS_KEY_EXCH_PSK: + case HITLS_KEY_EXCH_DHE_PSK: + case HITLS_KEY_EXCH_ECDHE_PSK: + return false; + default: + break; + } + + /* Anonymous ciphersuite related */ + switch (cipherSuiteInfo->authAlg) { + case HITLS_AUTH_NULL: + return false; + default: + break; + } + + return true; +} + +bool IsTicketSupport(TLS_Ctx *ctx) +{ + return ctx->config.tlsConfig.isSupportSessionTicket && + (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_TICKET, 0, 0, NULL) == SECURITY_SUCCESS); +} + +int32_t CheckClientPsk(TLS_Ctx *ctx) +{ + PskInfo *pskInfo = ctx->hsCtx->kxCtx->pskInfo; + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + uint8_t identity[HS_PSK_IDENTITY_MAX_LEN + 1] = {0}; + + /* If the value of psk is not NULL, it has been processed. */ + if (pskInfo != NULL && pskInfo->psk != NULL) { + return HITLS_SUCCESS; + } + + if (ctx->config.tlsConfig.pskClientCb == NULL) { + return HITLS_UNREGISTERED_CALLBACK; + } + + uint32_t pskUsedLen = ctx->config.tlsConfig.pskClientCb(ctx, NULL, identity, HS_PSK_IDENTITY_MAX_LEN, + psk, HS_PSK_MAX_LEN); + if (pskUsedLen == 0 || pskUsedLen > HS_PSK_IDENTITY_MAX_LEN) { + return HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN; + } + /* Length of pskid will not exceed 128 bytes */ + uint32_t identityUsedLen = (uint32_t)strnlen((char *)identity, HS_PSK_IDENTITY_MAX_LEN + 1); + if (identityUsedLen > HS_PSK_IDENTITY_MAX_LEN) { + return HITLS_MSG_HANDLE_ILLEGAL_IDENTITY_LEN; + } + + if (ctx->hsCtx->kxCtx->pskInfo == NULL) { + ctx->hsCtx->kxCtx->pskInfo = (PskInfo *)BSL_SAL_Calloc(1u, sizeof(PskInfo)); + if (ctx->hsCtx->kxCtx->pskInfo == NULL) { + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + return HITLS_MEMALLOC_FAIL; + } + } + + uint8_t *tmpIdentity = NULL; + if (identityUsedLen > 0) { + tmpIdentity = (uint8_t *)BSL_SAL_Calloc(1u, (identityUsedLen + 1)); + if (tmpIdentity == NULL) { + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(tmpIdentity, identityUsedLen + 1, identity, identityUsedLen); + } + uint8_t *tmpPsk = (uint8_t *)BSL_SAL_Dump(psk, pskUsedLen); + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + if (tmpPsk == NULL) { + BSL_SAL_FREE(tmpIdentity); + return HITLS_MEMALLOC_FAIL; + } + + if (tmpIdentity != NULL) { + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo->identity); + ctx->hsCtx->kxCtx->pskInfo->identity = tmpIdentity; + ctx->hsCtx->kxCtx->pskInfo->identityLen = identityUsedLen; + } + + ctx->hsCtx->kxCtx->pskInfo->psk = tmpPsk; + ctx->hsCtx->kxCtx->pskInfo->pskLen = pskUsedLen; + + return HITLS_SUCCESS; +} + +uint32_t HS_GetState(const TLS_Ctx *ctx) +{ + if (ctx->hsCtx == NULL) { + return HS_STATE_BUTT; + } + + return ctx->hsCtx->state; +} + +const char *HS_GetServerName(const TLS_Ctx *ctx) +{ + if (ctx == NULL || ctx->hsCtx == NULL) { + return NULL; + } + return (char *)ctx->hsCtx->serverName; +} + +int32_t HS_GrowMsgBuf(TLS_Ctx *ctx, uint32_t msgSize, uint32_t upperBound, bool keepOldData) +{ + if (msgSize <= ctx->hsCtx->bufferLen) { + return HITLS_SUCCESS; + } + uint32_t bufSize = ctx->hsCtx->bufferLen; + uint32_t oldDataSize = bufSize; + + uint8_t *oldDataAddr = ctx->hsCtx->msgBuf; + + while (bufSize < msgSize && bufSize < upperBound) { + bufSize = bufSize << 1; + } + + /* The maximum value cannot exceed upperBound */ + bufSize = (bufSize > upperBound) ? upperBound : bufSize; + ctx->hsCtx->msgBuf = BSL_SAL_Calloc(1u, bufSize); + if (ctx->hsCtx->msgBuf == NULL) { + BSL_SAL_FREE(oldDataAddr); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15935, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msgBuf malloc fail while get reass msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + ctx->hsCtx->bufferLen = bufSize; + + if (keepOldData) { + if (memcpy_s(ctx->hsCtx->msgBuf, bufSize, oldDataAddr, oldDataSize) != EOK) { + BSL_SAL_FREE(ctx->hsCtx->msgBuf); + BSL_SAL_FREE(oldDataAddr); + ctx->hsCtx->bufferLen = 0; + return HITLS_MEMCPY_FAIL; + } + } + BSL_SAL_FREE(oldDataAddr); + return HITLS_SUCCESS; +} + +int32_t HS_ReSizeMsgBuf(TLS_Ctx *ctx, uint32_t msgSize) +{ + bool keepOldData = false; + return HS_GrowMsgBuf(ctx, msgSize, REC_MAX_PLAIN_LENGTH, keepOldData); +} + +uint32_t HS_MaxMessageSize(TLS_Ctx *ctx, HS_MsgType type) +{ + switch (type) { + case HELLO_REQUEST: + return HITLS_HELLO_REQUEST_MAX_SIZE; + case CLIENT_HELLO: + return HITLS_CLIENT_HELLO_MAX_SIZE; + case SERVER_HELLO: + return HITLS_SERVER_HELLO_MAX_SIZE; + case ENCRYPTED_EXTENSIONS: + return HITLS_ENCRYPTED_EXTENSIONS_MAX_SIZE; + case CERTIFICATE: + if (ctx->config.tlsConfig.maxCertList == 0) { + return HITLS_MAX_CERT_LIST_DEFAULT; + } + return ctx->config.tlsConfig.maxCertList; + case SERVER_KEY_EXCHANGE: + return HITLS_SERVER_KEY_EXCH_MAX_SIZE; + case CERTIFICATE_REQUEST: + if (ctx->config.tlsConfig.maxCertList == 0) { + return HITLS_MAX_CERT_LIST_DEFAULT; + } + return ctx->config.tlsConfig.maxCertList; + case SERVER_HELLO_DONE: + return HITLS_SERVER_HELLO_DONE_MAX_SIZE; + case CLIENT_KEY_EXCHANGE: + return HITLS_CLIENT_KEY_EXCH_MAX_SIZE; + case CERTIFICATE_VERIFY: + return REC_MAX_PLAIN_LENGTH; + case NEW_SESSION_TICKET: + if (HS_GetVersion(ctx) == HITLS_VERSION_TLS13) { + return HITLS_SESSION_TICKET_MAX_SIZE_TLS13; + } + return HITLS_SESSION_TICKET_MAX_SIZE_TLS12; + case END_OF_EARLY_DATA: + return HITLS_END_OF_EARLY_DATA_MAX_SIZE; + case FINISHED: + return HITLS_FINISHED_MAX_SIZE; + case KEY_UPDATE: + return HITLS_KEY_UPDATE_MAX_SIZE; + default: + return 0; + } +} + +uint32_t HS_GetBinderLen(HITLS_Session *session, HITLS_HashAlgo *hashAlg) +{ + if (*hashAlg > HITLS_HASH_NULL && *hashAlg < HITLS_HASH_BUTT) { + return SAL_CRYPT_HmacSize(*hashAlg); + } + + if (session == NULL) { + return 0; + } + + uint16_t cipherSuite = 0; + int32_t ret = HITLS_SESS_GetCipherSuite(session, &cipherSuite); + if (ret != HITLS_SUCCESS) { + return 0; + } + + CipherSuiteInfo cipherInfo = {0}; + ret = CFG_GetCipherSuiteInfo(cipherSuite, &cipherInfo); + if (ret != HITLS_SUCCESS) { + return 0; + } + *hashAlg = cipherInfo.hashAlg; + return SAL_CRYPT_HmacSize(*hashAlg); +} + +static struct { + uint16_t group; + uint16_t minVersion; + uint16_t maxVersion; + uint16_t minDtlsVersion; + uint16_t maxDtlsVersion; +} g_groupsConfomVersion[] = { + {HITLS_EC_GROUP_CURVE25519, HITLS_VERSION_TLS10, HITLS_VERSION_TLS13, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12}, + {HITLS_EC_GROUP_SECP256R1, HITLS_VERSION_TLS10, HITLS_VERSION_TLS13, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12}, + {HITLS_EC_GROUP_SECP521R1, HITLS_VERSION_TLS10, HITLS_VERSION_TLS13, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12}, + {HITLS_EC_GROUP_SECP384R1, HITLS_VERSION_TLS10, HITLS_VERSION_TLS13, HITLS_VERSION_DTLS12, HITLS_VERSION_DTLS12}, + {HITLS_EC_GROUP_SM2, HITLS_VERSION_TLCP11, HITLS_VERSION_TLCP11, 0, 0}, + {HITLS_FF_DHE_2048, HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0, 0}, + {HITLS_FF_DHE_3072, HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0, 0}, + {HITLS_FF_DHE_4096, HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0, 0}, + {HITLS_FF_DHE_6144, HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0, 0}, + {HITLS_FF_DHE_8192, HITLS_VERSION_TLS13, HITLS_VERSION_TLS13, 0, 0}, + {HITLS_EC_GROUP_BRAINPOOLP256R1, + HITLS_VERSION_TLS10, + HITLS_VERSION_TLS12, + HITLS_VERSION_DTLS12, + HITLS_VERSION_DTLS12}, + {HITLS_EC_GROUP_BRAINPOOLP384R1, + HITLS_VERSION_TLS10, + HITLS_VERSION_TLS12, + HITLS_VERSION_DTLS12, + HITLS_VERSION_DTLS12}, + {HITLS_EC_GROUP_BRAINPOOLP512R1, + HITLS_VERSION_TLS10, + HITLS_VERSION_TLS12, + HITLS_VERSION_DTLS12, + HITLS_VERSION_DTLS12}, +}; + +bool GroupConformToVersion(uint16_t version, uint16_t group) +{ + for (size_t i = 0; i < sizeof(g_groupsConfomVersion) / sizeof(g_groupsConfomVersion[0]); i++) { + if (group == g_groupsConfomVersion[i].group) { + if (version >= g_groupsConfomVersion[i].minVersion && version <= g_groupsConfomVersion[i].maxVersion) { + return true; + } + if (version >= g_groupsConfomVersion[i].minDtlsVersion && + version <= g_groupsConfomVersion[i].maxDtlsVersion) { + return true; + } + break; + } + } + return false; +} diff --git a/tls/handshake/common/src/hs_kx.c b/tls/handshake/common/src/hs_kx.c new file mode 100644 index 00000000..a49d5bf0 --- /dev/null +++ b/tls/handshake/common/src/hs_kx.c @@ -0,0 +1,713 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_security.h" +#include "crypt.h" +#include "cert_method.h" +#include "session.h" +#include "security.h" +#include "hs_ctx.h" +#include "transcript_hash.h" +#include "hs_common.h" +#include "hs_kx.h" + +KeyExchCtx *HS_KeyExchCtxNew(void) +{ + KeyExchCtx *keyExchCtx = (KeyExchCtx *)BSL_SAL_Malloc(sizeof(KeyExchCtx)); + if (keyExchCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15514, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "keyExchCtx malloc failed.", 0, 0, 0, 0); + return NULL; + } + (void)memset_s(keyExchCtx, sizeof(KeyExchCtx), 0, sizeof(KeyExchCtx)); + return keyExchCtx; +} + +void HS_KeyExchCtxFree(KeyExchCtx *keyExchCtx) +{ + if (keyExchCtx == NULL) { + return; + } + + if (keyExchCtx->pskInfo != NULL) { + BSL_SAL_FREE(keyExchCtx->pskInfo->identity); + BSL_SAL_FREE(keyExchCtx->pskInfo->psk); + BSL_SAL_FREE(keyExchCtx->pskInfo); + } + + BSL_SAL_FREE(keyExchCtx->pskInfo13.psk); + HITLS_SESS_Free(keyExchCtx->pskInfo13.resumeSession); + keyExchCtx->pskInfo13.resumeSession = NULL; + if (keyExchCtx->pskInfo13.userPskSess != NULL) { + HITLS_SESS_Free(keyExchCtx->pskInfo13.userPskSess->pskSession); + keyExchCtx->pskInfo13.userPskSess->pskSession = NULL; + BSL_SAL_FREE(keyExchCtx->pskInfo13.userPskSess->identity); + BSL_SAL_FREE(keyExchCtx->pskInfo13.userPskSess); + } + + switch (keyExchCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_NULL: + case HITLS_KEY_EXCH_ECDHE: + case HITLS_KEY_EXCH_ECDH: + case HITLS_KEY_EXCH_ECDHE_PSK: + SAL_CRYPT_FreeEcdhKey(keyExchCtx->key); + BSL_SAL_FREE(keyExchCtx->peerPubkey); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + case HITLS_KEY_EXCH_DH: + SAL_CRYPT_FreeDhKey(keyExchCtx->key); + BSL_SAL_FREE(keyExchCtx->keyExchParam.dh.p); + BSL_SAL_FREE(keyExchCtx->keyExchParam.dh.g); + BSL_SAL_FREE(keyExchCtx->peerPubkey); + break; + case HITLS_KEY_EXCH_RSA: + default: + break; + } + BSL_SAL_FREE(keyExchCtx); + return; +} + +static bool NamedCurveSupport(HITLS_NamedGroup inNamedGroup, const TLS_Config *config) +{ + for (uint32_t i = 0u; i < config->groupsSize; i++) { + if (inNamedGroup == config->groups[i]) { + return true; + } + } + return false; +} + +static int32_t ProcessServerKxMsgNamedCurve(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg) +{ + HITLS_ECCurveType type = serverKxMsg->keyEx.ecdh.ecPara.type; + HITLS_NamedGroup namedGroup = serverKxMsg->keyEx.ecdh.ecPara.param.namedcurve; + + if (NamedCurveSupport(namedGroup, &ctx->config.tlsConfig) == false) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_NAMED_CURVE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15515, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "no supported curves found.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_UNSUPPORT_NAMED_CURVE; + } + + uint32_t peerPubkeyLen = serverKxMsg->keyEx.ecdh.pubKeySize; + + uint8_t *peerPubkey = BSL_SAL_Malloc(peerPubkeyLen); + if (peerPubkey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15516, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubkey malloc fail when process server kx msg named curve.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(peerPubkey, peerPubkeyLen, serverKxMsg->keyEx.ecdh.pubKey, peerPubkeyLen); + + ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type = type; + ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.param.namedcurve = namedGroup; + HITLS_CRYPT_Key *key = SAL_CRYPT_GenEcdhKeyPair(&ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams); + if (key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15517, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get ecdh key pair fail when process server kx msg named curve.", 0, 0, 0, 0); + BSL_SAL_FREE(peerPubkey); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_ERR_ENCODE_ECDH_KEY; + } + ctx->hsCtx->kxCtx->key = key; + ctx->hsCtx->kxCtx->peerPubkey = peerPubkey; + ctx->hsCtx->kxCtx->pubKeyLen = peerPubkeyLen; + ctx->negotiatedInfo.negotiatedGroup = namedGroup; + + return HITLS_SUCCESS; +} + +int32_t HS_ProcessServerKxMsgEcdhe(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg) +{ + HITLS_ECCurveType type = serverKxMsg->keyEx.ecdh.ecPara.type; + switch (type) { + case HITLS_EC_CURVE_TYPE_NAMED_CURVE: + return ProcessServerKxMsgNamedCurve(ctx, serverKxMsg); + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15518, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unknow the curve type in server kx msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE; +} + +int32_t HS_ProcessServerKxMsgDhe(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg) +{ + const ServerDh *dh = &serverKxMsg->keyEx.dh; + HITLS_CRYPT_Key *key = SAL_CRYPT_GenerateDhKeyByParams(dh->p, dh->plen, dh->g, dh->glen); + if (key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_ENCODE_DH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15519, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dhe key pair fail when process server dhe kx msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_ERR_ENCODE_DH_KEY; + } + + uint8_t *pubkey = BSL_SAL_Dump(dh->pubkey, dh->pubKeyLen); + if (pubkey == NULL) { + SAL_CRYPT_FreeDhKey(key); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15520, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubkey malloc fail when process server dhe kx msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + ctx->hsCtx->kxCtx->keyExchParam.dh.plen = dh->plen; + ctx->hsCtx->kxCtx->key = key; + ctx->hsCtx->kxCtx->peerPubkey = pubkey; + ctx->hsCtx->kxCtx->pubKeyLen = dh->pubKeyLen; + return HITLS_SUCCESS; +} + +static int32_t ProcessClientKxMsgNamedCurve(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + uint32_t peerPubkeyLen = clientKxMsg->dataSize; + uint8_t *peerPubkey = BSL_SAL_Malloc(peerPubkeyLen); + if (peerPubkey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15521, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubkey malloc fail when process client kx msg named curve.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(peerPubkey, peerPubkeyLen, clientKxMsg->data, peerPubkeyLen); + + ctx->hsCtx->kxCtx->peerPubkey = peerPubkey; + ctx->hsCtx->kxCtx->pubKeyLen = peerPubkeyLen; + return HITLS_SUCCESS; +} + +int32_t HS_ProcessClientKxMsgEcdhe(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + HITLS_ECCurveType type = ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type; + switch (type) { + case HITLS_EC_CURVE_TYPE_NAMED_CURVE: + return ProcessClientKxMsgNamedCurve(ctx, clientKxMsg); + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15522, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unknow the curve type in client kx msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_UNKNOWN_CURVE_TYPE; +} + +int32_t HS_ProcessClientKxMsgDhe(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + uint32_t peerPubkeyLen = clientKxMsg->dataSize; + uint8_t *peerPubkey = BSL_SAL_Dump(clientKxMsg->data, peerPubkeyLen); + if (peerPubkey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15523, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubkey malloc fail when process client dhe kx msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + ctx->hsCtx->kxCtx->peerPubkey = peerPubkey; + ctx->hsCtx->kxCtx->pubKeyLen = peerPubkeyLen; + return HITLS_SUCCESS; +} + +int32_t HS_ProcessClientKxMsgRsa(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *keyExchCtx = hsCtx->kxCtx; + uint8_t *premasterSecret = BSL_SAL_Calloc(1u, clientKxMsg->dataSize); + if (premasterSecret == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15524, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Decrypt RSA-Encrypted Premaster Secret error: out of memory.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + uint32_t secretLen = clientKxMsg->dataSize; + + CERT_MgrCtx *certMgrCtx = ctx->config.tlsConfig.certMgrCtx; + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(certMgrCtx, false); + ret = SAL_CERT_KeyDecrypt(ctx, privateKey, clientKxMsg->data, clientKxMsg->dataSize, premasterSecret, &secretLen); + if ((ret != HITLS_SUCCESS) || (secretLen != MASTER_SECRET_LEN)) { + /* If the server processing fails, the alert is disallowed and the handshake must continue with a randomly + * generated premaster secret */ + SAL_CRYPT_Rand(keyExchCtx->keyExchParam.rsa.preMasterSecret, MASTER_SECRET_LEN); + BSL_SAL_FREE(premasterSecret); + return HITLS_SUCCESS; + } + + // logic: Check the version in the premaster secret + uint16_t tempVersion = ctx->negotiatedInfo.clientVersion; + if (tempVersion == HITLS_VERSION_TLS12 || + ctx->config.tlsConfig.needCheckPmsVersion == true) { // Not related to dtls + // Shift right by 8 bits to get the most significant bit + if (((tempVersion & 0xff00) >> 8) != premasterSecret[0] || (tempVersion & 0x00ff) != premasterSecret[1]) { + SAL_CRYPT_Rand(keyExchCtx->keyExchParam.rsa.preMasterSecret, MASTER_SECRET_LEN); + BSL_SAL_FREE(premasterSecret); + return HITLS_SUCCESS; + } + } + + (void)memcpy_s(keyExchCtx->keyExchParam.rsa.preMasterSecret, MASTER_SECRET_LEN, premasterSecret, secretLen); + BSL_SAL_CleanseData(premasterSecret, secretLen); + BSL_SAL_FREE(premasterSecret); + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_TLCP11 +int32_t HS_ProcessClientKxMsgSm2(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *keyExchCtx = hsCtx->kxCtx; + uint8_t *preMasterSecret = BSL_SAL_Calloc(1u, clientKxMsg->dataSize); + if (preMasterSecret == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_MEMALLOC_FAIL; + } + uint32_t secretLen = clientKxMsg->dataSize; + CERT_MgrCtx *certMgrCtx = ctx->config.tlsConfig.certMgrCtx; + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(certMgrCtx, true); + ret = SAL_CERT_KeyDecrypt(ctx, privateKey, clientKxMsg->data, clientKxMsg->dataSize, preMasterSecret, &secretLen); + if ((ret != HITLS_SUCCESS) || (secretLen != MASTER_SECRET_LEN)) { + /* If the server fails to process the message, it is prohibited to send the alert message. The randomly + * generated premaster secret must be used to continue the handshake */ + SAL_CRYPT_Rand(keyExchCtx->keyExchParam.ecc.preMasterSecret, MASTER_SECRET_LEN); + BSL_SAL_FREE(preMasterSecret); + return HITLS_SUCCESS; + } + uint16_t clientVersion = BSL_ByteToUint16(preMasterSecret); + // In any case, a TLS server MUST NOT generate an alert if processing an RSA-encrypted + // premaster secret message fails, or the version number is not as expected. + if (ctx->negotiatedInfo.clientVersion != clientVersion) { + // If the version does not match, a 46-byte preMasterSecret is randomly generated + uint16_t version = ctx->negotiatedInfo.clientVersion; + uint32_t offset = 0u; + // 8: right shift a byte + keyExchCtx->keyExchParam.ecc.preMasterSecret[offset++] = (uint8_t)(version >> 8); + keyExchCtx->keyExchParam.ecc.preMasterSecret[offset++] = (uint8_t)(version); + SAL_CRYPT_Rand(keyExchCtx->keyExchParam.ecc.preMasterSecret + offset, MASTER_SECRET_LEN - offset); + BSL_SAL_CleanseData(preMasterSecret, secretLen); + BSL_SAL_FREE(preMasterSecret); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15348, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Parse RSA-Encrypted Premaster Secret client version mismatch: msg clientVersion = %u, \ + ctx->negotiatedInfo.clientVersion = %u.", clientVersion, ctx->negotiatedInfo.clientVersion, 0, 0); + return HITLS_SUCCESS; + } + + (void)memcpy_s(keyExchCtx->keyExchParam.ecc.preMasterSecret, MASTER_SECRET_LEN, preMasterSecret, secretLen); + BSL_SAL_CleanseData(preMasterSecret, secretLen); + BSL_SAL_FREE(preMasterSecret); + return HITLS_SUCCESS; +} +#endif + +static int32_t AppendPsk(uint8_t *pskPmsBuf, uint32_t pskPmsBufLen, uint8_t *psk, uint32_t pskLen) +{ + uint32_t offset = 0u; + uint8_t *pskPmsBufTmp = pskPmsBuf; + + BSL_Uint16ToByte((uint16_t)pskLen, pskPmsBufTmp); + offset += sizeof(uint16_t); + + if (memcpy_s(&pskPmsBufTmp[offset], pskPmsBufLen - offset, psk, pskLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t GeneratePskPreMasterSecret(TLS_Ctx *ctx, uint8_t *pmsBuf, uint32_t pmsBufLen, uint32_t *pmsUsedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint8_t tmpPskPmsBufTmp[MAX_PRE_MASTER_SECRET_SIZE] = {0}; + + uint8_t *psk = ctx->hsCtx->kxCtx->pskInfo->psk; + uint32_t pskLen = ctx->hsCtx->kxCtx->pskInfo->pskLen; + + if (psk == NULL || pskLen > HS_PSK_MAX_LEN) { + return HITLS_NULL_INPUT; + } + + switch (ctx->hsCtx->kxCtx->keyExchAlgo) { + /* |shareKeyLen(2 byte)|shareKey|PskLen(2 byte)|psk| */ + case HITLS_KEY_EXCH_DHE_PSK: + case HITLS_KEY_EXCH_ECDHE_PSK: + /* Padding ShareKeyLen */ + BSL_Uint16ToByte((uint16_t)*pmsUsedLen, &tmpPskPmsBufTmp[offset]); + offset += sizeof(uint16_t); + /* Padding ShareKey */ + ret = memcpy_s(&tmpPskPmsBufTmp[offset], MAX_PRE_MASTER_SECRET_SIZE - offset, pmsBuf, *pmsUsedLen); + offset += *pmsUsedLen; + break; + /* |48(2 byte)|version number(2 byte)|rand value(46 byte)|pskLen(2 byte)|psk| */ + case HITLS_KEY_EXCH_RSA_PSK: + /* Padding the length (Version + RandValue). The value is fixed to 48 */ + BSL_Uint16ToByte(MASTER_SECRET_LEN, &tmpPskPmsBufTmp[offset]); + offset = sizeof(uint16_t); + /* Padding |Version|RandValue| */ + ret = memcpy_s(&tmpPskPmsBufTmp[offset], MAX_PRE_MASTER_SECRET_SIZE - offset, pmsBuf, *pmsUsedLen); + offset += MASTER_SECRET_LEN; + break; + /* |N(2 byte)|N 0s|N(2 byte)|psk|, N stands for pskLen */ + case HITLS_KEY_EXCH_PSK: + /* Padding pskLen */ + BSL_Uint16ToByte((uint16_t)pskLen, &tmpPskPmsBufTmp[offset]); + offset = sizeof(uint16_t); + /* padding pskLen with zeros */ + ret = memset_s(&tmpPskPmsBufTmp[offset], MAX_PRE_MASTER_SECRET_SIZE - offset, 0, pskLen); + offset += pskLen; + break; + default: + /* no key exchange algo matched */ + return HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG; + } + + if (ret != EOK) { + goto memFail; + } + + if (AppendPsk(&tmpPskPmsBufTmp[offset], MAX_PRE_MASTER_SECRET_SIZE - offset, psk, pskLen) != HITLS_SUCCESS) { + goto memFail; + } + offset += (sizeof(uint16_t) + pskLen); + + if (memcpy_s(pmsBuf, pmsBufLen, tmpPskPmsBufTmp, offset) != EOK) { + goto memFail; + } + *pmsUsedLen = offset; + + (void)memset_s(tmpPskPmsBufTmp, MAX_PRE_MASTER_SECRET_SIZE, 0, MAX_PRE_MASTER_SECRET_SIZE); + + return HITLS_SUCCESS; +memFail: + (void)memset_s(tmpPskPmsBufTmp, MAX_PRE_MASTER_SECRET_SIZE, 0, MAX_PRE_MASTER_SECRET_SIZE); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; +} + +int32_t DeriveMasterSecret(TLS_Ctx *ctx, const uint8_t *preMasterSecret, uint32_t len) +{ + int32_t ret = HITLS_SUCCESS; + const uint8_t masterSecretLabel[] = "master secret"; + const uint8_t exMasterSecretLabel[] = "extended master secret"; + uint8_t seed[HS_RANDOM_SIZE * 2] = {0}; // seed size is twice the random size + uint32_t seedLen = sizeof(seed); + bool isExtendedMasterSecret = ctx->negotiatedInfo.isExtendedMasterSecret; + + CRYPT_KeyDeriveParameters deriveInfo; + deriveInfo.hashAlgo = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + deriveInfo.secret = preMasterSecret; + deriveInfo.secretLen = len; + + if (isExtendedMasterSecret) { + deriveInfo.label = exMasterSecretLabel; + deriveInfo.labelLen = sizeof(exMasterSecretLabel) - 1u; + ret = VERIFY_CalcSessionHash( + ctx->hsCtx->verifyCtx, seed, &seedLen); // Use session hash as seed for key deriviation + } else { + deriveInfo.label = masterSecretLabel; + deriveInfo.labelLen = sizeof(masterSecretLabel) - 1u; + ret = HS_CombineRandom(ctx->hsCtx->clientRandom, ctx->hsCtx->serverRandom, HS_RANDOM_SIZE, seed, seedLen); + } + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15525, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "get PRF seed fail.", 0, 0, 0, 0); + return ret; + } + deriveInfo.seed = seed; + deriveInfo.seedLen = seedLen; + + ret = SAL_CRYPT_PRF(&deriveInfo, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15526, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "failed to invoke the PRF function.", 0, 0, 0, 0); + return ret; + } + + return HITLS_SUCCESS; +} + +static int32_t GenPremasterSecretFromEcdhe(TLS_Ctx *ctx, uint8_t *preMasterSecret, uint32_t *preMasterSecretLen) +{ +#ifndef HITLS_NO_TLCP11 + int32_t ret = HITLS_SUCCESS; + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *certMgrCtx = config->certMgrCtx; + HITLS_CERT_Key *priKey = SAL_CERT_GetCurrentPrivateKey(certMgrCtx, true); + if (priKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_EXP_CERT); + return HITLS_CERT_ERR_EXP_CERT; + } + HITLS_CRYPT_Key *peerPubKey = NULL; + HITLS_CERT_X509 *cert = SAL_CERT_GetTlcpEncCert(ctx->hsCtx->peerCert); + ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&peerPubKey); + if (ret != HITLS_SUCCESS) { + return ret; + } + + *preMasterSecretLen = MASTER_SECRET_LEN; + HITLS_Sm2GenShareKeyParameters sm2ShareKeyParam = {ctx->hsCtx->kxCtx->key, ctx->hsCtx->kxCtx->peerPubkey, + ctx->hsCtx->kxCtx->pubKeyLen, priKey, peerPubKey, ctx->isClient }; + ret = SAL_CRYPT_CalcSm2dhSharedSecret(&sm2ShareKeyParam, preMasterSecret, preMasterSecretLen); + SAL_CERT_KeyFree(certMgrCtx, peerPubKey); + return ret; + } +#endif + return SAL_CRYPT_CalcEcdhSharedSecret(ctx->hsCtx->kxCtx->key, ctx->hsCtx->kxCtx->peerPubkey, + ctx->hsCtx->kxCtx->pubKeyLen, preMasterSecret, preMasterSecretLen); +} + +static int32_t GenPreMasterSecret(TLS_Ctx *ctx, uint8_t *preMasterSecret, uint32_t *preMasterSecretLen) +{ + int32_t ret = HITLS_SUCCESS; + KeyExchCtx *keyExchCtx = ctx->hsCtx->kxCtx; + + switch (keyExchCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_ECDHE: + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = GenPremasterSecretFromEcdhe(ctx, preMasterSecret, preMasterSecretLen); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = SAL_CRYPT_CalcDhSharedSecret(keyExchCtx->key, + keyExchCtx->peerPubkey, keyExchCtx->pubKeyLen, + preMasterSecret, preMasterSecretLen); + break; + case HITLS_KEY_EXCH_RSA: + case HITLS_KEY_EXCH_RSA_PSK: + if (memcpy_s(preMasterSecret, *preMasterSecretLen, + keyExchCtx->keyExchParam.rsa.preMasterSecret, MASTER_SECRET_LEN) != EOK) { + ret = HITLS_MEMCPY_FAIL; + } + *preMasterSecretLen = MASTER_SECRET_LEN; + break; +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: + if (memcpy_s(preMasterSecret, *preMasterSecretLen, + keyExchCtx->keyExchParam.ecc.preMasterSecret, MASTER_SECRET_LEN) != EOK) { + ret = HITLS_MEMCPY_FAIL; + } + *preMasterSecretLen = MASTER_SECRET_LEN; + break; +#endif + case HITLS_KEY_EXCH_PSK: + break; + default: + ret = HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG; + break; + } + BSL_ERR_PUSH_ERROR(ret); + return ret; +} + +int32_t HS_GenerateMasterSecret(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + uint8_t preMasterSecret[MAX_PRE_MASTER_SECRET_SIZE] = {0}; + uint32_t preMasterSecretLen = MAX_PRE_MASTER_SECRET_SIZE; + + ret = GenPreMasterSecret(ctx, preMasterSecret, &preMasterSecretLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15527, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calc ecdh shared secret failed.", 0, 0, 0, 0); + return ret; + } + + /* re-arrange preMasterSecret for psk negotiation */ + if (IsPskNegotiation(ctx)) { + ret = GeneratePskPreMasterSecret(ctx, preMasterSecret, MAX_PRE_MASTER_SECRET_SIZE, &preMasterSecretLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_CleanseData(preMasterSecret, MAX_PRE_MASTER_SECRET_SIZE); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + ret = DeriveMasterSecret(ctx, preMasterSecret, preMasterSecretLen); + BSL_SAL_CleanseData(preMasterSecret, MAX_PRE_MASTER_SECRET_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15528, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "derive master secret failed.", 0, 0, 0, 0); + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t HS_SetInitPendingStateParam(const TLS_Ctx *ctx, bool isClient, REC_SecParameters *keyPara) +{ + const HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + const CipherSuiteInfo *cipherSuiteInfo = &ctx->negotiatedInfo.cipherSuiteInfo; + keyPara->isClient = isClient; + keyPara->prfAlg = cipherSuiteInfo->hashAlg; + keyPara->macAlg = cipherSuiteInfo->macAlg; + keyPara->cipherAlg = cipherSuiteInfo->cipherAlg; + keyPara->cipherType = cipherSuiteInfo->cipherType; + keyPara->fixedIvLength = cipherSuiteInfo->fixedIvLength; /** iv length. In the TLS1.2 AEAD algorithm, iv length is + the implicit IV length. */ + keyPara->encKeyLen = cipherSuiteInfo->encKeyLen; + keyPara->macKeyLen = cipherSuiteInfo->macKeyLen; /** If the AEAD algorithm is used, the MAC key length is zero. */ + keyPara->blockLength = cipherSuiteInfo->blockLength; + keyPara->recordIvLength = cipherSuiteInfo->recordIvLength; /** The explicit IV needs to be sent to the peer. */ + keyPara->macLen = cipherSuiteInfo->macLen; + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + uint32_t clientRandomSize = HS_RANDOM_SIZE; + if (memcpy_s(keyPara->clientRandom, clientRandomSize, hsCtx->clientRandom, HS_RANDOM_SIZE) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15622, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Client random value copy failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + uint32_t serverRandomSize = HS_RANDOM_SIZE; + if (memcpy_s(keyPara->serverRandom, serverRandomSize, hsCtx->serverRandom, HS_RANDOM_SIZE) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15623, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Server random value copy failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + } + return HITLS_SUCCESS; +} + +int32_t HS_KeyEstablish(TLS_Ctx *ctx, bool isClient) +{ + int32_t ret = HITLS_SUCCESS; + REC_SecParameters keyPara; + uint32_t masterSecretSize = MASTER_SECRET_LEN; + + ret = HS_SetInitPendingStateParam(ctx, isClient, &keyPara); + if (ret != HITLS_SUCCESS) { + return ret; + } + + (void)memcpy_s(keyPara.masterSecret, masterSecretSize, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + ret = REC_InitPendingState(ctx, &keyPara); + + (void)memset_s(keyPara.masterSecret, MASTER_SECRET_LEN, 0, MASTER_SECRET_LEN); + return ret; +} + +int32_t HS_ResumeKeyEstablish(TLS_Ctx *ctx) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + uint32_t masterKeySize = MAX_DIGEST_SIZE; + int32_t ret = HITLS_SESS_GetMasterKey(ctx->session, hsCtx->masterKey, &masterKeySize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15529, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Resume session: get master secret failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = HS_KeyEstablish(ctx, ctx->isClient); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15530, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server key establish fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } +#ifndef HITLS_NO_DTLS12 + ret = HS_SetSctpAuthKey(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } +#endif + + return HITLS_SUCCESS; +} + +int32_t HS_ProcessServerKxMsgIdentityHint(TLS_Ctx *ctx, const ServerKeyExchangeMsg *serverKxMsg) +{ + if (ctx == NULL || serverKxMsg == NULL) { + return HITLS_NULL_INPUT; + } + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + uint8_t identity[HS_PSK_IDENTITY_MAX_LEN + 1] = {0}; + + int32_t ret = HITLS_SUCCESS; + do { + if (ctx->config.tlsConfig.pskClientCb == NULL) { + ret = HITLS_UNREGISTERED_CALLBACK; + break; + } + + uint32_t pskUsedLen = ctx->config.tlsConfig.pskClientCb(ctx, serverKxMsg->pskIdentityHint, identity, + HS_PSK_IDENTITY_MAX_LEN, psk, HS_PSK_MAX_LEN); + if (pskUsedLen == 0 || pskUsedLen > HS_PSK_MAX_LEN) { + ret = HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN; + break; + } + + uint32_t identityUsedLen = (uint32_t)strnlen((char *)identity, HS_PSK_IDENTITY_MAX_LEN + 1); + if (identityUsedLen > HS_PSK_IDENTITY_MAX_LEN) { + ret = HITLS_MSG_HANDLE_ILLEGAL_IDENTITY_LEN; + break; + } + + if (ctx->hsCtx->kxCtx->pskInfo == NULL) { + ctx->hsCtx->kxCtx->pskInfo = (PskInfo *)BSL_SAL_Calloc(1u, sizeof(PskInfo)); + if (ctx->hsCtx->kxCtx->pskInfo == NULL) { + ret = HITLS_MEMALLOC_FAIL; + break; + } + } + + uint8_t *tmpIdentity = (uint8_t *)BSL_SAL_Calloc(1u, (identityUsedLen + 1) * sizeof(uint8_t)); + if (tmpIdentity == NULL) { + ret = HITLS_MEMALLOC_FAIL; + break; + } + (void)memcpy_s(tmpIdentity, identityUsedLen + 1, identity, identityUsedLen); + + uint8_t *tmpPsk = (uint8_t *)BSL_SAL_Dump(psk, pskUsedLen); + if (tmpPsk == NULL) { + BSL_SAL_FREE(tmpIdentity); + ret = HITLS_MEMALLOC_FAIL; + break; + } + + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo->identity); + ctx->hsCtx->kxCtx->pskInfo->identity = tmpIdentity; + ctx->hsCtx->kxCtx->pskInfo->identityLen = identityUsedLen; + + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo->psk); + ctx->hsCtx->kxCtx->pskInfo->psk = tmpPsk; + ctx->hsCtx->kxCtx->pskInfo->pskLen = pskUsedLen; + } while (false); + + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + BSL_ERR_PUSH_ERROR(ret); + return ret; +} diff --git a/tls/handshake/common/src/hs_verify.c b/tls/handshake/common/src/hs_verify.c new file mode 100644 index 00000000..38ffcec4 --- /dev/null +++ b/tls/handshake/common/src/hs_verify.c @@ -0,0 +1,655 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hs_kx.h" +#include "transcript_hash.h" +#include "hs_verify.h" + +#define HS_VERIFY_DATA_LEN 12u + +#define CLIENT_FINISHED_LABEL "client finished" +#define SERVER_FINISHED_LABEL "server finished" + +#define MSG_HASH_HEADER_SIZE 4 /* message_hash message header length */ +#define MAX_MSG_HASH_SIZE (MAX_DIGEST_SIZE + MSG_HASH_HEADER_SIZE) /* Maximum message_hash message length */ + +#define TLS13_CLIENT_CERT_VERIFY_LABEL "TLS 1.3, client CertificateVerify" +#define TLS13_SERVER_CERT_VERIFY_LABEL "TLS 1.3, server CertificateVerify" + +#define TLS13_CERT_VERIFY_PREFIX 0x20 /* The signature data in TLS 1.3 is firstly filled with 64 0x20s */ +#define TLS13_CERT_VERIFY_PREFIX_LEN 64 + +int32_t VERIFY_Init(HS_Ctx *hsCtx) +{ + VERIFY_Deinit(hsCtx); + VerifyCtx *verifyCtx = (VerifyCtx *)BSL_SAL_Calloc(1u, sizeof(VerifyCtx)); + if (verifyCtx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15475, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify init error: out of memory.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + verifyCtx->dataBuf = (HsMsgCache *)BSL_SAL_Calloc(1u, sizeof(HsMsgCache)); + if (verifyCtx->dataBuf == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15476, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify databuf malloc error: out of memory.", 0, 0, 0, 0); + BSL_SAL_FREE(verifyCtx); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + hsCtx->verifyCtx = verifyCtx; + return HITLS_SUCCESS; +} + +void VERIFY_Deinit(HS_Ctx *hsCtx) +{ + if (hsCtx == NULL) { + return; + } + VerifyCtx *verifyCtx = hsCtx->verifyCtx; + if (verifyCtx == NULL) { + return; + } + if (verifyCtx->hashCtx != NULL) { + SAL_CRYPT_DigestFree(verifyCtx->hashCtx); + } + VERIFY_FreeMsgCache(verifyCtx); + BSL_SAL_FREE(verifyCtx); + hsCtx->verifyCtx = NULL; + return; +} + +static int32_t SaveVerifyData(TLS_Ctx *ctx, bool isClient) +{ + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + uint8_t *verifyData = isClient ? ctx->negotiatedInfo.clientVerifyData : ctx->negotiatedInfo.serverVerifyData; + if (memcpy_s(verifyData, MAX_DIGEST_SIZE, verifyCtx->verifyData, verifyCtx->verifyDataSize) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15909, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy verifyData fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + if (isClient) { + ctx->negotiatedInfo.clientVerifyDataSize = verifyCtx->verifyDataSize; + } else { + ctx->negotiatedInfo.serverVerifyDataSize = verifyCtx->verifyDataSize; + } + return HITLS_SUCCESS; +} + +int32_t VERIFY_CalcVerifyData(TLS_Ctx *ctx, bool isClient, const uint8_t *masterSecret, uint32_t masterSecretLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t digestLen = MAX_DIGEST_SIZE; + uint8_t digest[MAX_DIGEST_SIZE] = {0}; + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + + ret = VERIFY_CalcSessionHash(verifyCtx, digest, &digestLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15477, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify data calculate error: calc session hash fail.", 0, 0, 0, 0); + return ret; + } + + CRYPT_KeyDeriveParameters deriveInfo; + deriveInfo.hashAlgo = verifyCtx->hashAlgo; + deriveInfo.secret = masterSecret; + deriveInfo.secretLen = masterSecretLen; + deriveInfo.label = isClient ? ((const uint8_t *)CLIENT_FINISHED_LABEL) : ((const uint8_t *)SERVER_FINISHED_LABEL); + deriveInfo.labelLen = isClient ? strlen(CLIENT_FINISHED_LABEL) : strlen(SERVER_FINISHED_LABEL); + deriveInfo.seed = digest; + deriveInfo.seedLen = digestLen; + ret = SAL_CRYPT_PRF(&deriveInfo, verifyCtx->verifyData, HS_VERIFY_DATA_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15478, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify data calculate error: PRF fail.", 0, 0, 0, 0); + return ret; + } + verifyCtx->verifyDataSize = HS_VERIFY_DATA_LEN; + + return SaveVerifyData(ctx, isClient); +} + +static uint32_t GetHsDataLen(const VerifyCtx *ctx) +{ + uint32_t len = 0; + const HsMsgCache *block = ctx->dataBuf; + /* Calculate the signature data length */ + while (block != NULL) { + len += block->dataSize; + block = block->next; + } + return len; +} + +static uint8_t *LoopBlocks(const HsMsgCache *block, uint32_t len) +{ + if (len == 0) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_VERIFY_SIGN_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15479, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "In verify ctx, empty data.", + 0, 0, 0, 0); + return NULL; + } + uint8_t *data = BSL_SAL_Malloc(len); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + uint32_t offset = 0; + while ((block != NULL) && (block->dataSize > 0)) { + if (memcpy_s(data + offset, len - offset, block->data, block->dataSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_SAL_FREE(data); + return NULL; + } + offset += block->dataSize; + block = block->next; + } + return data; +} + +static uint8_t *GetHsData(VerifyCtx *ctx, uint32_t *dataLen) +{ + uint32_t hsDataLen = GetHsDataLen(ctx); + const HsMsgCache *block = ctx->dataBuf; + uint8_t *hsData = LoopBlocks(block, hsDataLen); + *dataLen = hsDataLen; + return hsData; +} + +/* The sender packs the data, calculates the binder, and then appends verified data. + * The reciver parses the data, and then calculates the binder. */ +static uint8_t *GetHsDataForBinder(VerifyCtx *ctx, uint32_t *dataLen, bool isClient) +{ + if (isClient) { + return GetHsData(ctx, dataLen); + } + + const HsMsgCache *block = ctx->dataBuf; + if (block == NULL || block->next == NULL || block->next->data == 0) { + return NULL; + } + uint32_t lenExcludeLastBlock = 0; + /* Calculate the total length excluding the last block. */ + while (block->next != NULL && block->next->dataSize != 0) { + lenExcludeLastBlock += block->dataSize; + block = block->next; + } + uint32_t lastBlockLen = block->dataSize; + uint8_t *hsData = LoopBlocks(ctx->dataBuf, lenExcludeLastBlock + lastBlockLen); + *dataLen = lenExcludeLastBlock; + return hsData; +} + +static const char *GetCertVerifyLabel(bool isClient, uint32_t *len) +{ + if (isClient) { + *len = strlen(TLS13_CLIENT_CERT_VERIFY_LABEL); + return TLS13_CLIENT_CERT_VERIFY_LABEL; + } + *len = strlen(TLS13_SERVER_CERT_VERIFY_LABEL); + return TLS13_SERVER_CERT_VERIFY_LABEL; +} + +static uint8_t *Tls13GetUnsignData(TLS_Ctx *ctx, uint32_t *dataLen, bool isClient) +{ + int32_t ret = HITLS_SUCCESS; + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + uint32_t digestLen = MAX_DIGEST_SIZE; + uint8_t digest[MAX_DIGEST_SIZE] = {0}; + ret = VERIFY_CalcSessionHash(verifyCtx, digest, &digestLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15480, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calc session hash fail when get unsign data.", 0, 0, 0, 0); + return NULL; + } + + uint32_t labelLen = 0; + const char *label = GetCertVerifyLabel(isClient, &labelLen); + + /* sixty-four 0x20 s + label + 0x00 + SessionHash */ + uint32_t unsignDataLen = TLS13_CERT_VERIFY_PREFIX_LEN + labelLen + 1 + digestLen; + uint8_t *unsignData = BSL_SAL_Malloc(unsignDataLen); + if (unsignData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15481, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc unsignData fail when get unsign data.", 0, 0, 0, 0); + return NULL; + } + + uint32_t offset = 0; + /* Filled prefix: sixty-four 0x20 s */ + if (memset_s(unsignData, unsignDataLen, TLS13_CERT_VERIFY_PREFIX, TLS13_CERT_VERIFY_PREFIX_LEN) != EOK) { + BSL_SAL_FREE(unsignData); + return NULL; + } + offset += TLS13_CERT_VERIFY_PREFIX_LEN; + + /* Filled labels */ + if (memcpy_s(&unsignData[offset], unsignDataLen - offset, label, labelLen) != EOK) { + BSL_SAL_FREE(unsignData); + return NULL; + } + offset += labelLen; + + /* Filled with one 0 */ + unsignData[offset] = 0; + offset++; + + /* Filled SessionHash */ + if (memcpy_s(&unsignData[offset], unsignDataLen - offset, digest, digestLen) != EOK) { + BSL_SAL_FREE(unsignData); + return NULL; + } + + *dataLen = unsignDataLen; + return unsignData; +} + +#ifndef HITLS_NO_TLCP11 +static uint8_t *TlcpGetUnsignData(TLS_Ctx *ctx, uint32_t *dataLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t unsignDataLen = MAX_DIGEST_SIZE; + uint8_t *unsignData = BSL_SAL_Malloc(unsignDataLen); + if (unsignData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return NULL; + } + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + ret = VERIFY_CalcSessionHash(verifyCtx, unsignData, &unsignDataLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_SAL_Free(unsignData); + return NULL; + } + + *dataLen = unsignDataLen; + return unsignData; +} +#endif + +static uint8_t *GetUnsignData(TLS_Ctx *ctx, uint32_t *dataLen, bool isClient) +{ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + return Tls13GetUnsignData(ctx, dataLen, isClient); + } +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + return TlcpGetUnsignData(ctx, dataLen); + } +#endif + return GetHsData(ctx->hsCtx->verifyCtx, dataLen); +} + +int32_t VERIFY_CalcSignData(TLS_Ctx *ctx, HITLS_CERT_Key *privateKey, HITLS_SignHashAlgo signScheme) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_SignAlgo signAlgo = 0; + HITLS_HashAlgo hashAlgo = 0; + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + + if (CFG_GetSignParamBySchemes(ctx->negotiatedInfo.version, signScheme, &signAlgo, &hashAlgo) != true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15482, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sign parm fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + return HITLS_PACK_SIGNATURE_ERR; + } + + /* Obtaining the data to be signed */ + uint32_t dataLen = 0u; + uint8_t *data = GetUnsignData(ctx, &dataLen, ctx->isClient); // The local isClient is used for signature + if (data == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_GET_UNSIGN_DATA_FAIL); + return HITLS_MSG_HANDLE_GET_UNSIGN_DATA_FAIL; + } + + CERT_SignParam signParam = {0}; + signParam.signAlgo = signAlgo; + signParam.hashAlgo = hashAlgo; + signParam.data = data; + signParam.dataLen = dataLen; + signParam.sign = verifyCtx->verifyData; + signParam.signLen = MAX_SIGN_SIZE; + + ret = SAL_CERT_CreateSign(ctx, privateKey, &signParam); + if ((ret != HITLS_SUCCESS) || (signParam.signLen > MAX_SIGN_SIZE)) { + BSL_SAL_FREE(data); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15483, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "create signature fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + return HITLS_PACK_SIGNATURE_ERR; + } + verifyCtx->verifyDataSize = signParam.signLen; + + BSL_SAL_FREE(data); + return HITLS_SUCCESS; +} + +int32_t VERIFY_VerifySignData(TLS_Ctx *ctx, HITLS_CERT_Key *pubkey, HITLS_SignHashAlgo signScheme, + const uint8_t *signData, uint16_t signDataLen) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_SignAlgo signAlgo = 0; + HITLS_HashAlgo hashAlgo = 0; + + if (CFG_GetSignParamBySchemes(ctx->negotiatedInfo.version, signScheme, &signAlgo, &hashAlgo) != true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15484, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sign parm fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + return HITLS_PACK_SIGNATURE_ERR; + } + + /* Obtain the data to be signed */ + uint32_t dataLen = 0; + uint8_t *data = GetUnsignData(ctx, &dataLen, !ctx->isClient); + if (data == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_GET_UNSIGN_DATA_FAIL); + return HITLS_MSG_HANDLE_GET_UNSIGN_DATA_FAIL; + } + + CERT_SignParam signParam = {.signAlgo = signAlgo, .hashAlgo = hashAlgo, .data = data, .dataLen = dataLen}; + signParam.sign = BSL_SAL_Dump(signData, signDataLen); + if (signParam.sign == NULL) { + BSL_SAL_FREE(data); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + signParam.signLen = signDataLen; + + ret = SAL_CERT_VerifySign(ctx, pubkey, &signParam); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(signParam.sign); + BSL_SAL_FREE(data); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15485, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify signature fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_VERIFY_SIGN_FAIL); + return HITLS_MSG_HANDLE_VERIFY_SIGN_FAIL; + } + BSL_SAL_FREE(signParam.sign); + BSL_SAL_FREE(data); + return HITLS_SUCCESS; +} + +int32_t VERIFY_SetVerifyData(VerifyCtx *ctx, const uint8_t *verifyData, uint32_t verifyDataLen) +{ + if (verifyDataLen > MAX_DIGEST_SIZE) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15486, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Get verify data error: incorrect digest size.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN); + return HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN; + } + + if (memcpy_s(ctx->verifyData, MAX_DIGEST_SIZE, verifyData, verifyDataLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15487, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Set verify data error: memcpy fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + ctx->verifyDataSize = verifyDataLen; + return HITLS_SUCCESS; +} + +int32_t VERIFY_GetVerifyData(const VerifyCtx *ctx, uint8_t *verifyData, uint32_t *verifyDataLen) +{ + if (ctx->verifyDataSize > MAX_DIGEST_SIZE) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15488, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Get verify data error: incorrect digest size.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN); + return HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN; + } + + if (memcpy_s(verifyData, *verifyDataLen, ctx->verifyData, ctx->verifyDataSize) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15489, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Get verify data error: memcpy fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + *verifyDataLen = ctx->verifyDataSize; + return HITLS_SUCCESS; +} + +static uint8_t *GetBaseKey(TLS_Ctx *ctx, bool isClient) +{ + uint8_t *baseKey = NULL; + if (ctx->phaState != PHA_REQUESTED) { + baseKey = isClient ? ctx->hsCtx->clientHsTrafficSecret : ctx->hsCtx->serverHsTrafficSecret; + } else { + baseKey = isClient ? ctx->clientAppTrafficSecret : ctx->serverAppTrafficSecret; + } + return baseKey; +} + +int32_t VERIFY_Tls13CalcVerifyData(TLS_Ctx *ctx, bool isClient) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_HashAlgo hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t finishedKey[MAX_DIGEST_SIZE] = {0}; + uint8_t *baseKey = NULL; + + baseKey = GetBaseKey(ctx, isClient); + + ret = HS_TLS13DeriveFinishedKey(hashAlg, baseKey, hashLen, finishedKey, hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + uint32_t digestLen = MAX_DIGEST_SIZE; + uint8_t digest[MAX_DIGEST_SIZE] = {0}; + ret = VERIFY_CalcSessionHash(verifyCtx, digest, &digestLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15490, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calc session hash fail when calc tls13 verify data.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* verify_data = HMAC(finished_key, Transcript-Hash(Handshake Context, Certificate*, CertificateVerify*)) */ + verifyCtx->verifyDataSize = hashLen; + ret = SAL_CRYPT_Hmac(hashAlg, finishedKey, hashLen, digest, digestLen, + verifyCtx->verifyData, &verifyCtx->verifyDataSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15910, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CRYPT_Hmac fail when calc tls13 verify data.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + return SaveVerifyData(ctx, isClient); +} + +static int32_t ConstructMsgHash(HITLS_HashAlgo hashAlgo, HsMsgCache *dataBuf, + uint8_t *out, uint32_t *outLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t digestLen = *outLen - MSG_HASH_HEADER_SIZE; + uint32_t inLen = dataBuf->dataSize; + uint8_t *in = BSL_SAL_Dump(dataBuf->data, dataBuf->dataSize); + if (in == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + ret = SAL_CRYPT_Digest(hashAlgo, in, inLen, &out[MSG_HASH_HEADER_SIZE], &digestLen); + BSL_SAL_FREE(in); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t offset = 0; + out[offset++] = MESSAGE_HASH; + out[offset++] = 0; + out[offset++] = 0; + out[offset] = (uint8_t)digestLen; + *outLen = digestLen + MSG_HASH_HEADER_SIZE; + + return HITLS_SUCCESS; +} + +static int32_t ReinitVerify(TLS_Ctx *ctx, uint8_t *msgHash, uint32_t msgHashLen, uint8_t *hrr, uint32_t hrrLen) +{ + int32_t ret = HITLS_SUCCESS; + + VERIFY_Deinit(ctx->hsCtx); + + ret = VERIFY_Init(ctx->hsCtx); + if (ret != HITLS_SUCCESS) { + return ret; + } + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + + ret = VERIFY_Append(verifyCtx, msgHash, msgHashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = VERIFY_Append(verifyCtx, hrr, hrrLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t VERIFY_HelloRetryRequestVerifyProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t msgHashLen = MAX_MSG_HASH_SIZE; + uint8_t msgHash[MAX_MSG_HASH_SIZE] = {0}; + VerifyCtx *verifyCtx = ctx->hsCtx->verifyCtx; + HsMsgCache *dataBuf = verifyCtx->dataBuf; + + /** Set the verify information. */ + ret = VERIFY_SetHash(ctx->hsCtx->verifyCtx, ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15491, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set verify info fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return ret; + } + + ret = ConstructMsgHash(verifyCtx->hashAlgo, dataBuf, msgHash, &msgHashLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15493, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "construct msg hash fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return ret; + } + + dataBuf = dataBuf->next; + uint32_t helloRetryRequestLen = dataBuf->dataSize; + uint8_t *helloRetryRequest = BSL_SAL_Dump(dataBuf->data, dataBuf->dataSize); + if (helloRetryRequest == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15494, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc helloRetryRequest fail when process hrr verify.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + ret = ReinitVerify(ctx, msgHash, msgHashLen, helloRetryRequest, helloRetryRequestLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(helloRetryRequest); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return ret; + } + BSL_SAL_FREE(helloRetryRequest); + + return HITLS_SUCCESS; +} + +/** + Transcript-Hash(Truncate(ClientHello1)) + Where Truncate() removes the binders list from the ClientHello + If the server responds with a HelloRetryRequest and the client then sends ClientHello2, + its binder will be computed over: + Transcript-Hash(ClientHello1, HelloRetryRequest, Truncate(ClientHello2)) +*/ +int32_t VERIFY_CalcPskBinder(const TLS_Ctx *ctx, HITLS_HashAlgo hashAlgo, bool isExternalPsk, uint8_t *psk, + uint32_t pskLen, const uint8_t *msg, uint32_t msgLen, uint8_t *binder, uint32_t binderLen) +{ + int32_t ret = HITLS_SUCCESS; + uint8_t earlySecret[MAX_DIGEST_SIZE] = {0}; + uint8_t binderKey[MAX_DIGEST_SIZE] = {0}; + uint8_t finishedKey[MAX_DIGEST_SIZE] = {0}; + uint8_t transcriptHash[MAX_DIGEST_SIZE] = {0}; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlgo); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + // HKDF.Extract PSK to compute EarlySecret + ret = HS_TLS13DeriveEarlySecret(hashAlgo, psk, pskLen, earlySecret, &hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + // HKDF.Expand EarlySecret to compute BinderKey + ret = HS_TLS13DeriveBinderKey(hashAlgo, isExternalPsk, earlySecret, hashLen, binderKey, hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + // HKDF.Expand BinderKey to compute Binder Finished Key + ret = HS_TLS13DeriveFinishedKey(hashAlgo, binderKey, hashLen, finishedKey, hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t hsDataLen = 0u; + + HITLS_HASH_Ctx *hashCtx = SAL_CRYPT_DigestInit(hashAlgo); + if (hashCtx == NULL) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t *hsData = GetHsDataForBinder(ctx->hsCtx->verifyCtx, &hsDataLen, ctx->isClient); + if (hsData != NULL) { + ret = SAL_CRYPT_DigestUpdate(hashCtx, hsData, hsDataLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(hsData); + SAL_CRYPT_DigestFree(hashCtx); + return ret; + } + } + + if (SAL_CRYPT_DigestUpdate(hashCtx, msg, msgLen) != HITLS_SUCCESS || + SAL_CRYPT_DigestFinal(hashCtx, transcriptHash, &hashLen) != HITLS_SUCCESS) { + BSL_SAL_FREE(hsData); + SAL_CRYPT_DigestFree(hashCtx); + return HITLS_CRYPT_ERR_DIGEST; + } + + uint32_t calcBinderLen = binderLen; + ret = SAL_CRYPT_Hmac(hashAlgo, finishedKey, hashLen, transcriptHash, hashLen, binder, &calcBinderLen); + BSL_SAL_FREE(hsData); + SAL_CRYPT_DigestFree(hashCtx); + return ret; +} \ No newline at end of file diff --git a/tls/handshake/common/src/tls13key.c b/tls/handshake/common/src/tls13key.c new file mode 100644 index 00000000..6a662a34 --- /dev/null +++ b/tls/handshake/common/src/tls13key.c @@ -0,0 +1,497 @@ +/* + * 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 +#include "securec.h" +#include "bsl_bytes.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_crypt_type.h" +#include "tls.h" +#include "crypt.h" +#include "rec.h" +#include "hs_kx.h" +#include "transcript_hash.h" + +int32_t HS_TLS13DeriveSecret(CRYPT_KeyDeriveParameters *deriveInfo, bool isHashed, uint8_t *outSecret, uint32_t outLen) +{ + int32_t ret; + uint8_t transcriptHash[MAX_DIGEST_SIZE] = {0}; + uint32_t hashLen = SAL_CRYPT_DigestSize(deriveInfo->hashAlgo); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + if (!isHashed) { + ret = SAL_CRYPT_Digest(deriveInfo->hashAlgo, deriveInfo->seed, deriveInfo->seedLen, transcriptHash, &hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + deriveInfo->seed = transcriptHash; + deriveInfo->seedLen = hashLen; + } + + return SAL_CRYPT_HkdfExpandLabel(deriveInfo, outSecret, outLen); +} + +int32_t TLS13HkdfExtract(HITLS_CRYPT_HkdfExtractInput *extractInput, uint8_t *prk, uint32_t *prkLen) +{ + uint32_t hashLen = SAL_CRYPT_DigestSize(extractInput->hashAlgo); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t zeros[MAX_DIGEST_SIZE] = {0}; + + if (extractInput->salt == NULL) { + extractInput->salt = zeros; + extractInput->saltLen = hashLen; + } + + if (extractInput->ikm == NULL) { + extractInput->ikm = zeros; + extractInput->ikmLen = hashLen; + } + + return SAL_CRYPT_HkdfExtract(extractInput, prk, prkLen); +} + +/** + 0 + | + v + PSK -> HKDF-Extract = Early Secret + */ +int32_t HS_TLS13DeriveEarlySecret(HITLS_HashAlgo hashAlgo, const uint8_t *psk, uint32_t pskLen, + uint8_t *earlySecret, uint32_t *outLen) +{ + HITLS_CRYPT_HkdfExtractInput extractInput = {0}; + extractInput.hashAlgo = hashAlgo; + extractInput.salt = NULL; + extractInput.saltLen = 0; + extractInput.ikm = psk; + extractInput.ikmLen = pskLen; + + return TLS13HkdfExtract(&extractInput, earlySecret, outLen); +} + +int32_t HS_TLS13DeriveBinderKey(HITLS_HashAlgo hashAlgo, bool isExternalPsk, + const uint8_t *earlySecret, uint32_t secretLen, uint8_t *binderKey, uint32_t keyLen) +{ + uint8_t *binderLabel; + uint32_t labelLen; + uint8_t extBinderLabel[] = "ext binder"; + uint8_t resBinderLabel[] = "res binder"; + if (isExternalPsk) { + binderLabel = extBinderLabel; + labelLen = sizeof(extBinderLabel) - 1; + } else { + binderLabel = resBinderLabel; + labelLen = sizeof(resBinderLabel) - 1; + } + + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlgo; + deriveInfo.secret = earlySecret; + deriveInfo.secretLen = secretLen; + deriveInfo.label = binderLabel; + deriveInfo.labelLen = labelLen; + deriveInfo.seed = NULL; + deriveInfo.seedLen = 0; + int32_t ret = HS_TLS13DeriveSecret(&deriveInfo, false, binderKey, keyLen); + return ret; +} + +/** + Early Secret + | + v + Derive-Secret(., "derived", empty string) + | + v + (EC)DHE -> HKDF-Extract = Handshake Secret + | + v + Derive-Secret(., "derived", empty string) + | + v + 0 -> HKDF-Extract = Master Secret +*/ +int32_t HS_TLS13DeriveNextStageSecret(HITLS_HashAlgo hashAlgo, const uint8_t *inSecret, uint32_t inLen, + const uint8_t *givenSecret, uint32_t givenLen, uint8_t *outSecret, uint32_t *outLen) +{ + int32_t ret; + uint8_t label[] = "derived"; + uint8_t tmpSecret[MAX_DIGEST_SIZE]; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlgo); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlgo; + deriveInfo.secret = inSecret; + deriveInfo.secretLen = inLen; + deriveInfo.label = label; + deriveInfo.labelLen = sizeof(label) - 1; + deriveInfo.seed = NULL; + deriveInfo.seedLen = 0; + ret = HS_TLS13DeriveSecret(&deriveInfo, false, tmpSecret, hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + HITLS_CRYPT_HkdfExtractInput extractInput = {0}; + extractInput.hashAlgo = hashAlgo; + extractInput.salt = tmpSecret; + extractInput.saltLen = hashLen; + extractInput.ikm = givenSecret; + extractInput.ikmLen = givenLen; + return TLS13HkdfExtract(&extractInput, outSecret, outLen); +} + +/** + Early Secret + | + v + Derive-Secret(., "derived", empty string) + | + v + (EC)DHE -> HKDF-Extract = Handshake Secret + */ +int32_t TLS13DeriveHandshakeSecret(TLS_Ctx *ctx) +{ + uint16_t hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t preMasterSecret[MAX_PRE_MASTER_SECRET_SIZE] = {0}; + uint32_t preMasterSecretLen = MAX_PRE_MASTER_SECRET_SIZE; + KeyExchCtx *keyCtx = ctx->hsCtx->kxCtx; + int32_t ret; + if (keyCtx->peerPubkey != NULL) { + ret = SAL_CRYPT_CalcEcdhSharedSecret(keyCtx->key, keyCtx->peerPubkey, keyCtx->pubKeyLen, + preMasterSecret, &preMasterSecretLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + } else { + /* In psk-only mode, the key is an all-zero array of the hash length. */ + preMasterSecretLen = hashLen; + } + + uint32_t handshakeSecretLen = hashLen; + ret = HS_TLS13DeriveNextStageSecret(hashAlg, ctx->hsCtx->earlySecret, hashLen, + preMasterSecret, preMasterSecretLen, ctx->hsCtx->handshakeSecret, &handshakeSecretLen); + + BSL_SAL_CleanseData(preMasterSecret, MAX_PRE_MASTER_SECRET_SIZE); + return ret; +} + +/** + (EC)DHE -> HKDF-Extract = Handshake Secret + | + v + Derive-Secret(., "derived", "") + | + v + 0 -> HKDF-Extract = Master Secret +*/ +int32_t TLS13DeriveMasterSecret(TLS_Ctx *ctx) +{ + uint16_t hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint32_t masterKeyLen = hashLen; + + int32_t ret; + ret = HS_TLS13DeriveNextStageSecret(hashAlg, ctx->hsCtx->handshakeSecret, hashLen, + NULL, 0, ctx->hsCtx->masterKey, &masterKeyLen); + return ret; +} + +/** + finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) +*/ +int32_t HS_TLS13DeriveFinishedKey(HITLS_HashAlgo hashAlgo, const uint8_t *baseKey, uint32_t baseKeyLen, + uint8_t *finishedkey, uint32_t finishedkeyLen) +{ + uint8_t label[] = "finished"; + + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlgo; + deriveInfo.secret = baseKey; + deriveInfo.secretLen = baseKeyLen; + deriveInfo.label = label; + deriveInfo.labelLen = sizeof(label) - 1; + deriveInfo.seed = NULL; + deriveInfo.seedLen = 0; + return SAL_CRYPT_HkdfExpandLabel(&deriveInfo, finishedkey, finishedkeyLen); +} + +/** + HKDF-Expand-Label(resumption_master_secret, "resumption", ticket_nonce, Hash.length) +*/ +int32_t HS_TLS13DeriveResumePsk(const TLS_Ctx *ctx, const uint8_t *ticketNonce, uint32_t ticketNonceSize, + uint8_t *resumePsk, uint32_t resumePskLen) +{ + const uint8_t label[] = "resumption"; + HITLS_HashAlgo hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlg; + deriveInfo.secret = ctx->resumptionMasterSecret; + deriveInfo.secretLen = hashLen; + deriveInfo.label = label; + deriveInfo.labelLen = sizeof(label) - 1; + deriveInfo.seed = ticketNonce; + deriveInfo.seedLen = ticketNonceSize; + + return SAL_CRYPT_HkdfExpandLabel(&deriveInfo, resumePsk, resumePskLen); +} + +int32_t TLS13GetTrafficSecretDeriveInfo(TLS_Ctx *ctx, CRYPT_KeyDeriveParameters *deriveInfo, + uint8_t *seed, uint32_t seedLen) +{ + uint32_t tmpSeedLen = seedLen; + int32_t ret; + ret = VERIFY_CalcSessionHash(ctx->hsCtx->verifyCtx, seed, &tmpSeedLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint16_t hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + deriveInfo->hashAlgo = hashAlg; + deriveInfo->seed = seed; + deriveInfo->seedLen = tmpSeedLen; + deriveInfo->secretLen = hashLen; + return HITLS_SUCCESS; +} + +/** + Derive-Secret(Handshake Secret, label, ClientHello...ServerHello) +*/ +int32_t HS_TLS13DeriveHandshakeTrafficSecret(TLS_Ctx *ctx) +{ + uint8_t seed[MAX_DIGEST_SIZE] = {0}; + uint32_t seedLen = MAX_DIGEST_SIZE; + CRYPT_KeyDeriveParameters deriveInfo = {0}; + int32_t ret; + ret = TLS13GetTrafficSecretDeriveInfo(ctx, &deriveInfo, seed, seedLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + deriveInfo.secret = ctx->hsCtx->handshakeSecret; + uint32_t hashLen = deriveInfo.secretLen; + uint8_t clientLabel[] = "c hs traffic"; + deriveInfo.label = clientLabel; + deriveInfo.labelLen = sizeof(clientLabel) - 1; + ret = HS_TLS13DeriveSecret(&deriveInfo, true, ctx->hsCtx->clientHsTrafficSecret, hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t serverLabel[] = "s hs traffic"; + deriveInfo.label = serverLabel; + deriveInfo.labelLen = sizeof(serverLabel) - 1; + ret = HS_TLS13DeriveSecret(&deriveInfo, true, ctx->hsCtx->serverHsTrafficSecret, hashLen); + return ret; +} + +/** + Derive-Secret(Master Secret, label, ClientHello...ServerHello) +*/ +int32_t TLS13DeriveApplicationTrafficSecret(TLS_Ctx *ctx) +{ + uint8_t seed[MAX_DIGEST_SIZE] = {0}; + uint32_t seedLen = MAX_DIGEST_SIZE; + CRYPT_KeyDeriveParameters deriveInfo = {0}; + int32_t ret; + ret = TLS13GetTrafficSecretDeriveInfo(ctx, &deriveInfo, seed, seedLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + deriveInfo.secret = ctx->hsCtx->masterKey; + uint32_t hashLen = deriveInfo.secretLen; + uint8_t clientLabel[] = "c ap traffic"; + deriveInfo.label = clientLabel; + deriveInfo.labelLen = sizeof(clientLabel) - 1; + ret = HS_TLS13DeriveSecret(&deriveInfo, true, ctx->clientAppTrafficSecret, hashLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t serverLabel[] = "s ap traffic"; + deriveInfo.label = serverLabel; + deriveInfo.labelLen = sizeof(serverLabel) - 1; + ret = HS_TLS13DeriveSecret(&deriveInfo, true, ctx->serverAppTrafficSecret, hashLen); + return ret; +} + +/** + Derive-Secret(., "res master", ClientHello...client Finished) = resumption_master_secret +*/ +int32_t HS_TLS13DeriveResumptionMasterSecret(TLS_Ctx *ctx) +{ + uint8_t seed[MAX_DIGEST_SIZE] = {0}; + uint32_t seedLen = MAX_DIGEST_SIZE; + CRYPT_KeyDeriveParameters deriveInfo = {0}; + int32_t ret; + + ret = TLS13GetTrafficSecretDeriveInfo(ctx, &deriveInfo, seed, seedLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + deriveInfo.secret = ctx->hsCtx->masterKey; + uint32_t hashLen = deriveInfo.secretLen; + + const uint8_t resLabel[] = "res master"; + deriveInfo.label = resLabel; + deriveInfo.labelLen = sizeof(resLabel) - 1; + + return HS_TLS13DeriveSecret(&deriveInfo, true, ctx->resumptionMasterSecret, hashLen); +} + +int32_t HS_TLS13CalcServerHelloProcessSecret(TLS_Ctx *ctx) +{ + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + uint16_t hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0 || hashLen > MAX_DIGEST_SIZE) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t zero[MAX_DIGEST_SIZE] = {0}; + uint8_t *psk = NULL; + uint32_t pskLen = 0; + + if (pskInfo->psk != NULL) { + psk = pskInfo->psk; + pskLen = pskInfo->pskLen; + } else { + psk = zero; + pskLen = hashLen; + } + + uint32_t earlySecretLen = hashLen; + int32_t ret = HS_TLS13DeriveEarlySecret(hashAlg, psk, pskLen, ctx->hsCtx->earlySecret, &earlySecretLen); + BSL_SAL_CleanseData(psk, pskLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return TLS13DeriveHandshakeSecret(ctx); +} + +int32_t HS_TLS13CalcServerFinishProcessSecret(TLS_Ctx *ctx) +{ + int32_t ret; + ret = TLS13DeriveMasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = TLS13DeriveApplicationTrafficSecret(ctx); + return ret; +} + +int32_t HS_SwitchTrafficKey(TLS_Ctx *ctx, uint8_t *secret, uint32_t secretLen, bool isOut) +{ + int32_t ret; + CipherSuiteInfo *cipherSuiteInfo = &(ctx->negotiatedInfo.cipherSuiteInfo); + uint32_t hashLen = SAL_CRYPT_DigestSize(cipherSuiteInfo->hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + REC_SecParameters keyPara = {0}; + ret = HS_SetInitPendingStateParam(ctx, ctx->isClient, &keyPara); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (hashLen > sizeof(keyPara.masterSecret)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + if (memcpy_s(keyPara.masterSecret, sizeof(keyPara.masterSecret), secret, secretLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + ret = REC_TLS13InitPendingState(ctx, &keyPara, isOut); + (void)memset_s(keyPara.masterSecret, sizeof(keyPara.masterSecret), 0, sizeof(keyPara.masterSecret)); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** enable key specification */ + ret = REC_ActivePendingState(ctx, isOut); + return ret; +} + +/** + application_traffic_secret_N+1 = HKDF-Expand-Label(application_traffic_secret_N, "traffic upd", "", Hash.length) +*/ +int32_t HS_TLS13UpdateTrafficSecret(TLS_Ctx *ctx, bool isOut) +{ + HITLS_HashAlgo hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + uint32_t hashLen = SAL_CRYPT_DigestSize(hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t trafficSecret[MAX_DIGEST_SIZE] = {0}; + uint8_t *trafficSecretPointer = trafficSecret; + uint32_t trafficSecretLen = hashLen; + uint8_t *baseKey = NULL; + uint32_t baseKeyLen = hashLen; + if ((ctx->isClient && isOut) || (!ctx->isClient && !isOut)) { + baseKey = ctx->clientAppTrafficSecret; + } else { + baseKey = ctx->serverAppTrafficSecret; + } + + uint8_t label[] = "traffic upd"; + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlg; + deriveInfo.secret = baseKey; + deriveInfo.secretLen = baseKeyLen; + deriveInfo.label = label; + deriveInfo.labelLen = sizeof(label) - 1; + deriveInfo.seed = NULL; + deriveInfo.seedLen = 0; + int32_t ret = SAL_CRYPT_HkdfExpandLabel(&deriveInfo, trafficSecretPointer, trafficSecretLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (memcpy_s(baseKey, baseKeyLen, trafficSecret, trafficSecretLen) != EOK) { + return HITLS_MEMCPY_FAIL; + } + + ret = HS_SwitchTrafficKey(ctx, baseKey, baseKeyLen, isOut); + + return ret; +} diff --git a/tls/handshake/common/src/transcript_hash.c b/tls/handshake/common/src/transcript_hash.c new file mode 100644 index 00000000..f3b407cf --- /dev/null +++ b/tls/handshake/common/src/transcript_hash.c @@ -0,0 +1,148 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "transcript_hash.h" + + +int32_t VERIFY_SetHash(VerifyCtx *ctx, HITLS_HashAlgo hashAlgo) +{ + int32_t ret; + /* the value must be the same as the PRF function, use the digest algorithm with SHA-256 or higher strength */ + HITLS_HashAlgo prfAlgo = (hashAlgo == HITLS_HASH_SHA1) ? HITLS_HASH_SHA_256 : hashAlgo; + + ctx->hashCtx = SAL_CRYPT_DigestInit(prfAlgo); + if (ctx->hashCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15716, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify set hash error: digest init fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_DIGEST; + } + + HsMsgCache *dataBuf = ctx->dataBuf; + while ((dataBuf != NULL) && (dataBuf->dataSize > 0u)) { + ret = SAL_CRYPT_DigestUpdate(ctx->hashCtx, dataBuf->data, dataBuf->dataSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15717, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify set hash error: digest update fail.", 0, 0, 0, 0); + SAL_CRYPT_DigestFree(ctx->hashCtx); + ctx->hashCtx = NULL; + return ret; + } + dataBuf = dataBuf->next; + } + ctx->hashAlgo = prfAlgo; + return HITLS_SUCCESS; +} + +HsMsgCache *GetLastCache(HsMsgCache *dataBuf) +{ + HsMsgCache *cacheBuf = dataBuf; + while (cacheBuf->next != NULL) { + cacheBuf = cacheBuf->next; + } + return cacheBuf; +} + +int32_t CacheMsgData(HsMsgCache *dataBuf, const uint8_t *data, uint32_t len) +{ + HsMsgCache *lastCache = GetLastCache(dataBuf); + + lastCache->next = BSL_SAL_Calloc(1u, sizeof(HsMsgCache)); + if (lastCache->next == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15718, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc HsMsgCache fail when append msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + lastCache->data = BSL_SAL_Dump(data, len); + if (lastCache->data == NULL) { + BSL_SAL_FREE(lastCache->next); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15719, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc HsMsgCache data fail when append msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + lastCache->dataSize = len; + + return HITLS_SUCCESS; +} + +int32_t VERIFY_Append(VerifyCtx *ctx, const uint8_t *data, uint32_t len) +{ + int32_t ret; + if (ctx->hashCtx != NULL) { + ret = SAL_CRYPT_DigestUpdate(ctx->hashCtx, data, len); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15720, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify append error: digest update fail.", 0, 0, 0, 0); + return ret; + } + } + + if (ctx->dataBuf != NULL) { + ret = CacheMsgData(ctx->dataBuf, data, len); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + return HITLS_SUCCESS; +} + +int32_t VERIFY_CalcSessionHash(VerifyCtx *ctx, uint8_t *digest, uint32_t *digestLen) +{ + int32_t ret; + + HITLS_HASH_Ctx *tmpHashCtx = SAL_CRYPT_DigestCopy(ctx->hashCtx); + if (tmpHashCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15721, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify data calculate error: digest copy fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_DIGEST; + } + + /* get the hash result */ + ret = SAL_CRYPT_DigestFinal(tmpHashCtx, digest, digestLen); + SAL_CRYPT_DigestFree(tmpHashCtx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15722, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Verify data calculate error: digest final fail.", 0, 0, 0, 0); + return ret; + } + + return ret; +} + +void VERIFY_FreeMsgCache(VerifyCtx *ctx) +{ + HsMsgCache *nextBuf = NULL; + HsMsgCache *dataBuf = ctx->dataBuf; + while (dataBuf != NULL) { + nextBuf = dataBuf->next; + BSL_SAL_FREE(dataBuf->data); + BSL_SAL_FREE(dataBuf); + dataBuf = nextBuf; + } + ctx->dataBuf = NULL; + return; +} diff --git a/tls/handshake/include/hs.h b/tls/handshake/include/hs.h new file mode 100644 index 00000000..13000e65 --- /dev/null +++ b/tls/handshake/include/hs.h @@ -0,0 +1,158 @@ +/* + * 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 HS_H +#define HS_H + +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the handshake context + * + * @param ctx [IN] TLS object + * + * @retval HITLS_SUCCESS succeeded + */ +int32_t HS_Init(TLS_Ctx *ctx); + +/** + * @brief Release the handshake context + * + * @param ctx [IN] TLS object + */ +void HS_DeInit(TLS_Ctx *ctx); + +/** + * @brief Establish a TLS connection + * + * @param ctx [IN] TLS object + * + * @retval HITLS_SUCCESS The connection is successfully established. + * @retval For details about other error codes, see hitls_error.h + */ +int32_t HS_DoHandshake(TLS_Ctx *ctx); + +/** + * @brief Processing unexpected handshake messages. After the link is established, this function can be invoked to + * process the handshake messages received during user data transmission + * @param ctx [IN] TLS object + * @param data [IN] Handshake message + * @param len [IN] Message length + * @param state [IN/OUT] in:current link state, out:next link state + * + * @retval HITLS_SUCCESS succeeded. The user can continue sending and receiving data. + * @retval For details about other error codes, see hitls_error.h + */ +int32_t HS_RecvUnexpectedMsgProcess(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, CM_State *state); + +/** + * @brief Generate the session key + * + * @param ctx [IN] TLS context + * @param isClient [IN] Client or Not + * + * @retval HITLS_SUCCESS succeeded + * @retval For details about other error codes, see hitls_error.h + */ +int32_t HS_KeyEstablish(TLS_Ctx *ctx, bool isClient); + +/** + * @brief Session recovery Generate a session key. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS succeeded + * @retval For details about other error codes, see hitls_error.h + */ +int32_t HS_ResumeKeyEstablish(TLS_Ctx *ctx); + +/** + * @brief Obtain the current handshake status + * + * @param ctx [IN] TLS context + * + * @retval Current handshake status + */ +uint32_t HS_GetState(const TLS_Ctx *ctx); + +/** + * @brief Obtain the version number. If the version number is not negotiated, the latest version + * supported by the local is returned. + * + * @param ctx [IN] TLS context + * + * @return Return the version number. + */ +uint32_t HS_GetVersion(const TLS_Ctx *ctx); + +/** + * @brief Obtain the handshake status character string. + * + * @param state [IN] Handshake status + * + * @return Character string corresponding to the handshake status + */ +const char *HS_GetStateStr(uint32_t state); + +/** + * @brief Check whether the conditions for sending keyupdate are met + * + * @param ctx [IN] TLS context + * @param updateType [IN] keyupdate type + * + * @retval HITLS_SUCCESS succeeded. + * @retval For details about other error codes, see hitls_error.h + */ +int32_t HS_CheckKeyUpdateState(const TLS_Ctx *ctx, uint32_t updateType); + +/** + * @brief Process the keyupdate message sending process. + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS succeeded. + * @retval For details about other error codes, see hitls_error.h + */ +int32_t HS_SendKeyUpdate(TLS_Ctx *ctx); + +/** + * @brief Obtain the server_name in the handshake TLS context. + * + * @param ctx [IN] TLS context + * + * @return string of server_name in the TLS context during the handshake + */ +const char *HS_GetServerName(const TLS_Ctx *ctx); + +/** + * @brief Check whether app messages can be received. + * + * @param ctx [IN] TLS context + * + * @return true: allows receiving; false: does not allow receiving. + */ +bool HS_IsAppDataAllowed(TLS_Ctx *ctx); + + +int32_t HS_CheckPostHandshakeAuth(TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif +#endif /* HS_H */ \ No newline at end of file diff --git a/tls/handshake/pack/include/pack.h b/tls/handshake/pack/include/pack.h new file mode 100644 index 00000000..2621493f --- /dev/null +++ b/tls/handshake/pack/include/pack.h @@ -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 PACK_H +#define PACK_H + +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Pack handshake messages + * + * @param ctx [IN] TLS context + * @param type [IN] Message type + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Input buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t HS_PackMsg(const TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif \ No newline at end of file diff --git a/tls/handshake/pack/src/pack.c b/tls/handshake/pack/src/pack.c new file mode 100644 index 00000000..7aa52707 --- /dev/null +++ b/tls/handshake/pack/src/pack.c @@ -0,0 +1,219 @@ +/* + * 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 +#include + +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "tls.h" +#include "hs_msg.h" +#include "hs_ctx.h" +#include "hs.h" +#include "pack_msg.h" +#include "pack_common.h" + + +static int32_t PackHsMsgBody(TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + switch (type) { + case CLIENT_HELLO: + ret = PackClientHello(ctx, buf, bufLen, usedLen); + break; + case SERVER_HELLO: + ret = PackServerHello(ctx, buf, bufLen, usedLen); + break; + case CERTIFICATE: + ret = PackCertificate(ctx, buf, bufLen, usedLen); + break; + case SERVER_KEY_EXCHANGE: + ret = PackServerKeyExchange(ctx, buf, bufLen, usedLen); + break; + case CERTIFICATE_REQUEST: + ret = PackCertificateRequest(ctx, buf, bufLen, usedLen); + break; + case HELLO_REQUEST: + case SERVER_HELLO_DONE: + return HITLS_SUCCESS; + case CERTIFICATE_VERIFY: + ret = PackCertificateVerify(ctx, buf, bufLen, usedLen); + break; + case NEW_SESSION_TICKET: + ret = PackNewSessionTicket(ctx, buf, bufLen, usedLen); + break; + case CLIENT_KEY_EXCHANGE: + ret = PackClientKeyExchange(ctx, buf, bufLen, usedLen); + break; + case FINISHED: + ret = PackFinished(ctx, buf, bufLen, usedLen); + break; + default: + ret = HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + break; + } + + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15812, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack handshake[%u] msg error.", type, 0, 0, 0); + return ret; + } + return HITLS_SUCCESS; +} + +static int32_t PackTls13HsMsgBody(TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + switch (type) { + case CLIENT_HELLO: + ret = PackClientHello(ctx, buf, bufLen, usedLen); + break; + case SERVER_HELLO: + ret = PackServerHello(ctx, buf, bufLen, usedLen); + break; + case ENCRYPTED_EXTENSIONS: + ret = PackEncryptedExtensions(ctx, buf, bufLen, usedLen); + break; + case CERTIFICATE_REQUEST: + ret = Tls13PackCertificateRequest(ctx, buf, bufLen, usedLen); + break; + case CERTIFICATE: + ret = Tls13PackCertificate(ctx, buf, bufLen, usedLen); + break; + case CERTIFICATE_VERIFY: + ret = PackCertificateVerify(ctx, buf, bufLen, usedLen); + break; + case FINISHED: + ret = PackFinished(ctx, buf, bufLen, usedLen); + break; + case KEY_UPDATE: + ret = PackKeyUpdate(ctx, buf, bufLen, usedLen); + break; + case NEW_SESSION_TICKET: + ret = Tls13PackNewSessionTicket(ctx, buf, bufLen, usedLen); + break; + default: + ret = HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + break; + } + + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15813, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack handshake[%u] msg error.", type, 0, 0, 0); + return ret; + } + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_DTLS12 +int32_t Dtls12PackMsg(TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint16_t sequence = 0; + int32_t ret = HITLS_SUCCESS; + uint32_t len = 0; + + ret = PackHsMsgBody(ctx, type, &buf[DTLS_HS_MSG_HEADER_SIZE], bufLen - DTLS_HS_MSG_HEADER_SIZE, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + sequence = ctx->hsCtx->nextSendSeq; + PackDtlsMsgHeader(type, sequence, len, buf); + + *usedLen = len + DTLS_HS_MSG_HEADER_SIZE; + + return HITLS_SUCCESS; +} +#endif + +int32_t Tls12PackMsg(TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t len = 0; + + if (type > HS_MSG_TYPE_END) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG); + return HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + } + ret = PackHsMsgBody(ctx, type, &buf[HS_MSG_HEADER_SIZE], bufLen - HS_MSG_HEADER_SIZE, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + + buf[0] = (uint8_t)type & 0xffu; /* Fill handshake message type */ + BSL_Uint24ToByte(len, &buf[1]); /* Fill handshake message body length */ + + *usedLen = len + HS_MSG_HEADER_SIZE; + + return HITLS_SUCCESS; +} + +int32_t Tls13PackMsg(TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t len = 0; + + if (type > HS_MSG_TYPE_END) { + return HITLS_PACK_UNSUPPORT_HANDSHAKE_MSG; + } + ret = PackTls13HsMsgBody(ctx, type, &buf[HS_MSG_HEADER_SIZE], bufLen - HS_MSG_HEADER_SIZE, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + + buf[0] = (uint8_t)type & 0xffu; /* Fill handshake message type */ + BSL_Uint24ToByte(len, &buf[1]); /* Fill handshake message body length */ + + *usedLen = len + HS_MSG_HEADER_SIZE; + + return HITLS_SUCCESS; +} + +int32_t HS_PackMsg(TLS_Ctx *ctx, HS_MsgType type, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + if ((ctx == NULL) || (buf == NULL) || (usedLen == NULL) || (bufLen == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15814, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the input parameter pointer is null.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t version = HS_GetVersion(ctx); + + switch (version) { + case HITLS_VERSION_TLS12: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + return Tls12PackMsg(ctx, type, buf, bufLen, usedLen); + case HITLS_VERSION_TLS13: + return Tls13PackMsg(ctx, type, buf, bufLen, usedLen); +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + return Dtls12PackMsg(ctx, type, buf, bufLen, usedLen); +#endif + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15815, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack handshake msg error, unsupport version[0x%x].", version, 0, 0, 0); + return HITLS_PACK_UNSUPPORT_VERSION; +} diff --git a/tls/handshake/pack/src/pack_certificate.c b/tls/handshake/pack/src/pack_certificate.c new file mode 100644 index 00000000..dfc3677d --- /dev/null +++ b/tls/handshake/pack/src/pack_certificate.c @@ -0,0 +1,95 @@ +/* + * 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 + +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "cert.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "hs_extensions.h" + +int32_t PackCertificate(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + + if (bufLen < CERT_LEN_TAG_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15808, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of certificate msg is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Certificate content */ + ret = SAL_CERT_EncodeCertChain(ctx, &buf[CERT_LEN_TAG_SIZE], bufLen - CERT_LEN_TAG_SIZE, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15809, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode cert list fail when pack certificate msg.", 0, 0, 0, 0); + return ret; + } + + /* Certificate length */ + BSL_Uint24ToByte(*usedLen, buf); + *usedLen += CERT_LEN_TAG_SIZE; + return HITLS_SUCCESS; +} + +int32_t Tls13PackCertificate(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0; + + if (bufLen < (CERT_LEN_TAG_SIZE + ctx->certificateReqCtxSize + sizeof(uint16_t))) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15810, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of certificate msg is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + /* Pack the length of certificate_request_context */ + buf[offset] = (uint8_t)ctx->certificateReqCtxSize; + offset++; + + /* Pack the content of certificate_request_context */ + if (ctx->certificateReqCtxSize > 0) { + if (memcpy_s(&buf[offset], bufLen - offset, ctx->certificateReqCtx, ctx->certificateReqCtxSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + offset += ctx->certificateReqCtxSize; + } + + uint32_t certLenFieldOffset = offset; + offset += CERT_LEN_TAG_SIZE; + + /* Certificate content */ + ret = SAL_CERT_EncodeCertChain(ctx, &buf[offset], bufLen - offset, usedLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15811, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode cert list fail when pack certificate msg.", 0, 0, 0, 0); + return ret; + } + + /* Certificate length */ + BSL_Uint24ToByte(*usedLen, &buf[certLenFieldOffset]); + *usedLen += offset; + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/handshake/pack/src/pack_certificate_request.c b/tls/handshake/pack/src/pack_certificate_request.c new file mode 100644 index 00000000..bbf35ee7 --- /dev/null +++ b/tls/handshake/pack/src/pack_certificate_request.c @@ -0,0 +1,305 @@ +/* + * 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 +#include +#include "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_extensions.h" +#include "pack_extensions.h" + +typedef struct { + uint8_t certType; + bool isSupported; +} PackCertTypesInfo; + +static int32_t PackCertificateTypes(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if ((config->cipherSuites == NULL) || (config->cipherSuitesSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15682, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack certificate types error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + PackCertTypesInfo certTypeLists[] = { + {CERT_TYPE_RSA_SIGN, false}, + {CERT_TYPE_ECDSA_SIGN, false}, + {CERT_TYPE_DSS_SIGN, false}, + {CERT_TYPE_SM2_SIGN, false}, + }; + + uint32_t cipherSuitesSize = config->cipherSuitesSize; + uint8_t certTypeListsSize = (uint8_t)(sizeof(certTypeLists) / sizeof(certTypeLists[0])); + uint8_t supportedCertTypesSize = 0; + for (uint32_t i = 0; i < cipherSuitesSize; i++) { + uint8_t type = CFG_GetCertTypeByCipherSuite(config->cipherSuites[i]); + for (uint32_t j = 0; j < certTypeListsSize; j++) { + if ((certTypeLists[j].certType == type) && (certTypeLists[j].isSupported == false)) { + certTypeLists[j].isSupported = true; + supportedCertTypesSize++; + break; + } + } + } + + if (bufLen < (sizeof(uint8_t) + supportedCertTypesSize)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15683, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of certificate types message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + buf[offset] = supportedCertTypesSize; + offset += sizeof(uint8_t); + for (uint32_t i = 0; i < certTypeListsSize; i++) { + if (certTypeLists[i].isSupported == true) { + buf[offset] = certTypeLists[i].certType; + offset += sizeof(uint8_t); + } + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackSignAlgorithms(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if ((config->signAlgorithms == NULL) || (config->signAlgorithmsSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15684, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack signature algorithms error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + uint16_t signAlgorithmsSize = (uint16_t)config->signAlgorithmsSize * sizeof(uint16_t); + if (bufLen < (sizeof(uint16_t) + signAlgorithmsSize)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15685, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of sign algorithms message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + BSL_Uint16ToByte(signAlgorithmsSize, &buf[offset]); + offset += sizeof(uint16_t); + for (uint32_t index = 0; index < config->signAlgorithmsSize; index++) { + BSL_Uint16ToByte(config->signAlgorithms[index], &buf[offset]); + offset += sizeof(uint16_t); + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +int32_t PackCertificateRequest(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + uint32_t len = 0u; + + int32_t ret = PackCertificateTypes(ctx, buf, bufLen, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + /* TLCP does not have the signature algorithm field */ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + len = 0u; + ret = PackSignAlgorithms(ctx, &buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + } + + /* The distinguishable name of the certificate authorization list. The currently supported certificate authorization + * list is empty */ + BSL_Uint16ToByte(0, &buf[offset]); + offset += sizeof(uint16_t); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackSignAlgorithmsExtension(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if ((config->signAlgorithms == NULL) || (config->signAlgorithmsSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15686, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack signature algorithms error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + uint16_t exMsgHeaderLen = sizeof(uint16_t); + uint16_t exMsgDataLen = sizeof(uint16_t) * (uint16_t)config->signAlgorithmsSize; + + int32_t ret = PackExtensionHeader(HS_EX_TYPE_SIGNATURE_ALGORITHMS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + if (bufLen < sizeof(uint16_t) + offset) { + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + BSL_Uint16ToByte(exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + + if (bufLen < exMsgDataLen + offset) { + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + for (uint32_t index = 0; index < config->signAlgorithmsSize; index++) { + BSL_Uint16ToByte(config->signAlgorithms[index], &buf[offset]); + offset += sizeof(uint16_t); + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the extension of the Tls1.3 Certificate Request +static int32_t PackCertReqExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t listSize; + uint32_t exLen = 0u; + uint32_t offset = 0u; + + const PackExtInfo extMsgList[] = { + {.exMsgType = HS_EX_TYPE_SIGNATURE_ALGORITHMS, + .needPack = true, + .packFunc = PackSignAlgorithmsExtension}, + {.exMsgType = HS_EX_TYPE_SIGNATURE_ALGORITHMS_CERT, + /* We do not generate signature_algorithms_cert at present. */ + .needPack = false, + .packFunc = NULL}, + {.exMsgType = HS_EX_TYPE_OID_FILTERS, + .needPack = false, + .packFunc = NULL}, + }; + + listSize = sizeof(extMsgList) / sizeof(extMsgList[0]); + + for (uint32_t index = 0; index < listSize; index++) { + if (extMsgList[index].packFunc == NULL) { + exLen = 0u; + ret = PackEmptyExtension(extMsgList[index].exMsgType, extMsgList[index].needPack, + &buf[offset], bufLen - offset, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + if (extMsgList[index].packFunc != NULL && extMsgList[index].needPack) { + exLen = 0u; + ret = extMsgList[index].packFunc(ctx, &buf[offset], bufLen - offset, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the Tls1.3 Certificate Request extension. +int32_t Tls13PackCertReqExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t headerLen; + uint32_t exLen = 0u; + + headerLen = sizeof(uint16_t); + if (bufLen < headerLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15687, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of tls1.3 certificate Request extension message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Pack the extended content of the Tls1.3 Certificate Request */ + ret = PackCertReqExtensions(ctx, &buf[headerLen], bufLen - headerLen, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (exLen > 0u) { + BSL_Uint16ToByte((uint16_t)exLen, buf); + *len = exLen + headerLen; + } else { + BSL_Uint16ToByte((uint16_t) 0, buf); + *len = 0u + headerLen; + } + + return HITLS_SUCCESS; +} + +// Pack the Tls1.3 CertificateRequest message. +int32_t Tls13PackCertificateRequest(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t exMsgLen = 0u; + + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15688, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer len of tls1.3 cert request msg is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + /* Pack certificate_request_context */ + buf[offset] = (uint8_t)ctx->certificateReqCtxSize; + offset++; + + if (ctx->certificateReqCtxSize > 0) { + if (memcpy_s(&buf[offset], bufLen - offset, ctx->certificateReqCtx, ctx->certificateReqCtxSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15689, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack certificateReqCtx fail when pack cert request.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += ctx->certificateReqCtxSize; + } + + ret = Tls13PackCertReqExtensions(ctx, &buf[offset], bufLen - offset, &exMsgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15690, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 certificate request msg extension content fail.", 0, 0, 0, 0); + return ret; + } + offset += exMsgLen; + *usedLen = offset; + + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_certificate_verify.c b/tls/handshake/pack/src/pack_certificate_verify.c new file mode 100644 index 00000000..47a9eed7 --- /dev/null +++ b/tls/handshake/pack/src/pack_certificate_verify.c @@ -0,0 +1,67 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" + +int32_t PackCertificateVerify(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = 0; + uint32_t offset = 0u; + const HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + if (hsCtx->verifyCtx->verifyDataSize == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15824, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the verify data is illegal.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + if (bufLen < sizeof(uint16_t) + sizeof(uint16_t) + hsCtx->verifyCtx->verifyDataSize) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15825, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of certificate verify message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + BSL_Uint16ToByte((uint16_t)ctx->negotiatedInfo.signScheme, &buf[offset]); + offset += sizeof(uint16_t); + } + + /* Verify the data is the signature data. The maximum length of the signature data is 1024 bytes */ + BSL_Uint16ToByte((uint16_t)hsCtx->verifyCtx->verifyDataSize, &buf[offset]); + offset += sizeof(uint16_t); + + ret = memcpy_s(&buf[offset], bufLen - offset, hsCtx->verifyCtx->verifyData, hsCtx->verifyCtx->verifyDataSize); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15826, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy verify data fail when pack certificate verify msg.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += hsCtx->verifyCtx->verifyDataSize; + + *usedLen = offset; + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_client_hello.c b/tls/handshake/pack/src/pack_client_hello.c new file mode 100644 index 00000000..df5f72b5 --- /dev/null +++ b/tls/handshake/pack/src/pack_client_hello.c @@ -0,0 +1,311 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_security.h" +#include "tls.h" +#include "security.h" +#include "cipher_suite.h" +#include "hs_ctx.h" +#include "pack_common.h" +#include "pack_extensions.h" + + +#define SINGLE_CIPHER_SUITE_SIZE 2u +#define CIPHER_SUITES_LEN_SIZE 2u + +// Pack the version content of the client Hello message. +static int32_t PackClientVersion(const TLS_Ctx *ctx, uint16_t version, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + (void)bufLen; + const TLS_Config *tlsConfig = &ctx->config.tlsConfig; + uint32_t offset = 0u; + + int32_t ret = SECURITY_CfgCheck((HITLS_Config *)tlsConfig, HITLS_SECURITY_SECOP_VERSION, 0, version, NULL); + if (ret != SECURITY_SUCCESS) { + ctx->method.sendAlert((TLS_Ctx *)ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSECURE_VERSION); + return HITLS_PACK_UNSECURE_VERSION; + } + BSL_Uint16ToByte(version, &buf[offset]); + offset += sizeof(uint16_t); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_DTLS12 +// Pack the cookie content of the client Hello message. +static int32_t PackClientCookie(const uint8_t *cookie, uint8_t cookieLen, + uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + + if (bufLen < (sizeof(uint8_t) + cookieLen)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_COOKIE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15730, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of cookie is not enough.", 0, 0, 0, 0); + return HITLS_PACK_COOKIE_ERR; + } + + buf[offset] = cookieLen; + offset += sizeof(uint8_t); + if (cookieLen == 0u) { + *usedLen = offset; + return HITLS_SUCCESS; + } + + int32_t ret = memcpy_s(&buf[offset], bufLen - offset, cookie, cookieLen); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15731, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack cookie.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += cookieLen; + + *usedLen = offset; + return HITLS_SUCCESS; +} +#endif + +static int32_t PackCipherSuites(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *offset, bool isTls13) +{ + uint16_t *cipherSuites = NULL; + uint32_t cipherSuitesSize = 0; + uint32_t tmpOffset = *offset; + uint16_t minVersion = ctx->config.tlsConfig.minVersion; + uint16_t maxVersion = ctx->config.tlsConfig.maxVersion; + if (isTls13) { + cipherSuites = ctx->config.tlsConfig.tls13CipherSuites; + cipherSuitesSize = ctx->config.tlsConfig.tls13cipherSuitesSize; + } else { + cipherSuites = ctx->config.tlsConfig.cipherSuites; + cipherSuitesSize = ctx->config.tlsConfig.cipherSuitesSize; + } + + for (uint32_t i = 0; i < cipherSuitesSize; i++) { + if ((CFG_CheckCipherSuiteSupported(cipherSuites[i]) != true) || + (CFG_CheckCipherSuiteVersion(cipherSuites[i], minVersion, maxVersion) != true)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15845, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "The cipher suite [0x%04x] is NOT supported, index=[%u].", cipherSuites[i], i, 0, 0); + continue; + } + if (tmpOffset + sizeof(uint16_t) > bufLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15776, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack cipher suite error, the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR; + } + BSL_Uint16ToByte(cipherSuites[i], &buf[tmpOffset]); + tmpOffset += sizeof(uint16_t); + } + + *offset = tmpOffset; + return HITLS_SUCCESS; +} + +// Pack the cipher suites content of the client hello message. +static int32_t PackClientCipherSuites(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t cipherSuitesLen = 0u; + /* Finally fill in the length of the cipher suites */ + uint32_t offset = CIPHER_SUITES_LEN_SIZE; + /* If the local is not in the renegotiation state, + * you need to pack the SCSV algorithm set */ + bool isPackScsv = (!ctx->negotiatedInfo.isRenegotiation); + if (ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13) { + ret = PackCipherSuites(ctx, buf, bufLen, &offset, 1); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = PackCipherSuites(ctx, buf, bufLen, &offset, 0); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (offset == SINGLE_CIPHER_SUITE_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15732, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack cipher suite error, no cipher suite.", 0, 0, 0, 0); + return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR; + } + + /* The cipher suite has been filled. Each cipher suite takes two bytes, so the length of the filled cipher suite can + * be calculated according to offset */ + cipherSuitesLen = (uint16_t)(offset - CIPHER_SUITES_LEN_SIZE); + if (isPackScsv) { + cipherSuitesLen += sizeof(uint16_t); + BSL_Uint16ToByte(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, &buf[offset]); + offset += sizeof(uint16_t); + } + if (offset > bufLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15733, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack cipher suite error, the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR; + } + BSL_Uint16ToByte(cipherSuitesLen, &buf[0]); + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the content of the method for compressing the client Hello message. +static int32_t PackClientCompressionMethod(uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + + if (bufLen < sizeof(uint8_t) + sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_CLIENT_CIPHER_SUITE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15734, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack compression method error, the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_CLIENT_CIPHER_SUITE_ERR; + } + + buf[offset] = 1; + offset += sizeof(uint8_t); + buf[offset] = 0; /* Compression methods Currently support uncompressed */ + offset += sizeof(uint8_t); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the session and cookie content of the client hello message. +static int32_t PackSessionAndCookie(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t len = 0; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + len = 0u; + ret = PackSessionId(hsCtx->sessionId, hsCtx->sessionIdSize, &buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + +#ifndef HITLS_NO_DTLS12 + const TLS_Config *tlsConfig = &ctx->config.tlsConfig; + uint16_t version = (tlsConfig->maxVersion == HITLS_VERSION_TLS13) ? HITLS_VERSION_TLS12 : tlsConfig->maxVersion; + if (IS_DTLS_VERSION(version)) { + len = 0u; + ret = PackClientCookie(ctx->negotiatedInfo.cookie, (uint8_t)ctx->negotiatedInfo.cookieSize, + &buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + (void)memset_s(ctx->negotiatedInfo.cookie, ctx->negotiatedInfo.cookieSize, + 0, ctx->negotiatedInfo.cookieSize); + return ret; + } + offset += len; + } +#endif + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the mandatory content of the ClientHello message. +static int32_t PackClientHelloMandatoryField(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + /* The bufLen must be able to assemble at least the version number (2 bytes), + random number (32 bytes), and session ID (1 byte) */ + if (bufLen < (sizeof(uint16_t) + HS_RANDOM_SIZE + sizeof(uint8_t))) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15126, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack client hello mandatory field error, the bufLen(%u) is not enough.", bufLen, NULL, NULL, NULL); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t len = 0u; + const TLS_Config *tlsConfig = &ctx->config.tlsConfig; + if (ctx->hsCtx->clientRandom == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + uint16_t version = (tlsConfig->maxVersion == HITLS_VERSION_TLS13) ? HITLS_VERSION_TLS12 : tlsConfig->maxVersion; + ret = PackClientVersion(ctx, version, buf, bufLen, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + (void)memcpy_s(&buf[offset], bufLen - offset, ctx->hsCtx->clientRandom, HS_RANDOM_SIZE); + offset += HS_RANDOM_SIZE; + + len = 0u; + ret = PackSessionAndCookie(ctx, &buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + len = 0u; + ret = PackClientCipherSuites(ctx, &buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + len = 0u; + ret = PackClientCompressionMethod(&buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the ClientHello message to form the Handshake body. +int32_t PackClientHello(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t msgLen = 0u; + uint32_t exMsgLen = 0u; + + ret = PackClientHelloMandatoryField(ctx, buf, bufLen, &msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15735, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack client hello mandatory content fail.", 0, 0, 0, 0); + return ret; + } + offset += msgLen; + exMsgLen = 0u; + ret = PackClientExtension(ctx, &buf[offset], bufLen - offset, &exMsgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15736, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack client hello extension content fail.", 0, 0, 0, 0); + return ret; + } + offset += exMsgLen; + + *usedLen = offset; + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_client_key_exchange.c b/tls/handshake/pack/src/pack_client_key_exchange.c new file mode 100644 index 00000000..dec6ec61 --- /dev/null +++ b/tls/handshake/pack/src/pack_client_key_exchange.c @@ -0,0 +1,313 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "tls.h" +#include "crypt.h" +#include "cert_method.h" +#include "hs_ctx.h" +#include "hs_common.h" + + +#define APPROXIMATE_PREMASTER_LEN 128 + +static int32_t PackClientKxMsgNamedCurve(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t pubKeyLen; + uint32_t offset = 0; + EcdhParam *ecdh = &(ctx->hsCtx->kxCtx->keyExchParam.ecdh); + HITLS_ECParameters *curveParams = &ecdh->curveParams; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + + pubKeyLen = HS_GetNamedCurvePubkeyLen(curveParams->param.namedcurve); + if (pubKeyLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15673, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid key exchange pubKey length.", 0, 0, 0, 0); + return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH; + } + + if (bufLen < (sizeof(uint8_t) + pubKeyLen)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15674, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == + HITLS_VERSION_TLCP11) { /* Compatible with OpenSSL. Three bytes are added to the client key exchange. */ + if (bufLen < (sizeof(uint8_t) + pubKeyLen + sizeof(uint8_t) + sizeof(uint16_t))) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + buf[offset] = HITLS_EC_CURVE_TYPE_NAMED_CURVE; + offset += sizeof(uint8_t); + BSL_Uint16ToByte(HITLS_EC_GROUP_SM2, &buf[offset]); + offset += sizeof(uint16_t); + } +#endif + + uint32_t pubKeyLenOffset = offset; + offset += sizeof(uint8_t); + uint32_t pubKeyUsedLen = 0; + ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->key, &buf[offset], pubKeyLen, &pubKeyUsedLen); + if (ret != HITLS_SUCCESS || pubKeyLen != pubKeyUsedLen) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15675, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode ecdh key fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + offset += pubKeyUsedLen; + buf[pubKeyLenOffset] = (uint8_t)pubKeyUsedLen; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientKxMsgEcdhe(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + HITLS_ECCurveType type = ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type; + switch (type) { + case HITLS_EC_CURVE_TYPE_NAMED_CURVE: + return PackClientKxMsgNamedCurve(ctx, buf, bufLen, usedLen); + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15676, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unsupport key exchange curve type.", 0, 0, 0, 0); + return HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE; +} + +static int32_t PackClientKxMsgDhe(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + DhParam *dh = &ctx->hsCtx->kxCtx->keyExchParam.dh; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + + uint32_t pubkeyLen = dh->plen; + if (pubkeyLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15677, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid key exchange pubKey length.", 0, 0, 0, 0); + return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH; + } + + if (bufLen < (sizeof(uint16_t) + pubkeyLen)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15678, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + uint32_t offset = sizeof(uint16_t); + /* fill pubkey */ + ret = SAL_CRYPT_EncodeDhPubKey(kxCtx->key, &buf[offset], pubkeyLen, &pubkeyLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_DH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15679, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode dh pub key fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_DH_KEY; + } + offset += pubkeyLen; + /* fill pubkey length */ + BSL_Uint16ToByte((uint16_t)pubkeyLen, buf); + *usedLen = offset; + + return HITLS_SUCCESS; +} + +int32_t PackClientKxMsgRsa(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t encLen, offset = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *kxCtx = hsCtx->kxCtx; + uint8_t *preMasterSecret = kxCtx->keyExchParam.rsa.preMasterSecret; + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15680, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "bufLen = %u is not enough to encrypt PreMasterSecret.", bufLen, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + offset = sizeof(uint16_t); + encLen = bufLen - offset; + + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *mgrCtx = config->certMgrCtx; + HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(hsCtx->peerCert); + if (ctx->config.tlsConfig.needCheckKeyUsage == true && + SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_KEYENC_USAGE) != true) { + return HITLS_CERT_ERR_KEYUSAGE; + } + + HITLS_CERT_Key *pubkey = NULL; + ret = SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = SAL_CERT_KeyEncrypt(ctx, pubkey, preMasterSecret, MASTER_SECRET_LEN, &buf[offset], &encLen); + SAL_CERT_KeyFree(mgrCtx, pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += encLen; + BSL_Uint16ToByte((uint16_t)encLen, buf); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_TLCP11 +static int32_t PackClientKxMsgEcc(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *kxCtx = hsCtx->kxCtx; + uint8_t *preMasterSecret = kxCtx->keyExchParam.ecc.preMasterSecret; + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + uint32_t offset = sizeof(uint16_t); + uint32_t encLen = bufLen - offset; + + /* Encrypt the PreMasterSecret using the public key of the server certificate */ + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *certMgrCtx = config->certMgrCtx; + HITLS_CERT_X509 *certEnc = SAL_CERT_GetTlcpEncCert(hsCtx->peerCert); + if (ctx->config.tlsConfig.needCheckKeyUsage == true && + SAL_CERT_CheckCertKeyUsage(ctx, certEnc, CERT_KEY_CTRL_IS_KEYENC_USAGE) != true) { + return HITLS_CERT_ERR_KEYUSAGE; + } + HITLS_CERT_Key *pubkey = NULL; + ret = SAL_CERT_X509Ctrl(config, certEnc, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = SAL_CERT_KeyEncrypt(ctx, pubkey, preMasterSecret, MASTER_SECRET_LEN, &buf[offset], &encLen); + SAL_CERT_KeyFree(certMgrCtx, pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += encLen; + + /* fill the ciphertext length */ + BSL_Uint16ToByte((uint16_t)encLen, buf); + + *usedLen = offset; + return HITLS_SUCCESS; +} +#endif + +static int32_t PackClientKxMsgIdentity(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint8_t *pskIdentity = ctx->hsCtx->kxCtx->pskInfo->identity; + uint32_t pskIdentitySize = ctx->hsCtx->kxCtx->pskInfo->identityLen; + uint32_t dataLen = sizeof(uint16_t) + pskIdentitySize; + + if (bufLen < dataLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* append identity */ + uint32_t offset = 0u; + BSL_Uint16ToByte((uint16_t)pskIdentitySize, &buf[offset]); + offset += sizeof(uint16_t); + + if (bufLen - offset < pskIdentitySize) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + if (memcpy_s(&buf[offset], bufLen - offset, pskIdentity, pskIdentitySize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + offset += pskIdentitySize; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the ClientKeyExchange message. + +int32_t PackClientKeyExchange(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t len = 0u; + uint32_t offset = 0u; + + /* PSK negotiation pre act: append identity */ + if (IsPskNegotiation(ctx)) { + ret = PackClientKxMsgIdentity(ctx, buf, bufLen, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + } + + len = 0u; + /* Pack the key exchange message */ + switch (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg) { + case HITLS_KEY_EXCH_ECDHE: /* TLCP is also included */ + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = PackClientKxMsgEcdhe(ctx, &buf[offset], bufLen - offset, &len); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = PackClientKxMsgDhe(ctx, &buf[offset], bufLen - offset, &len); + break; + case HITLS_KEY_EXCH_RSA: + case HITLS_KEY_EXCH_RSA_PSK: + ret = PackClientKxMsgRsa(ctx, &buf[offset], bufLen - offset, &len); + break; +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: + ret = PackClientKxMsgEcc(ctx, &buf[offset], bufLen - offset, &len); + break; +#endif + case HITLS_KEY_EXCH_PSK: + ret = HITLS_SUCCESS; + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_KX_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15681, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unsupport key exchange algorithm when pack client key exchange.", 0, 0, 0, 0); + return HITLS_PACK_UNSUPPORT_KX_ALG; + } + + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + *usedLen = offset; + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_common.c b/tls/handshake/pack/src/pack_common.c new file mode 100644 index 00000000..b457bd08 --- /dev/null +++ b/tls/handshake/pack/src/pack_common.c @@ -0,0 +1,93 @@ +/* + * 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 +#include "securec.h" +#include "bsl_err_internal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hs_msg.h" + +/** + * @brief Pack the message session ID. + * + * @param id [IN] Session ID + * @param idSize [IN] Session ID length + * @param buf [OUT] message buffer + * @param bufLen [IN] Maximum message length + * @param usedLen [OUT] Length of the packed message + * + * @retval HITLS_SUCCESS Assembly succeeded. + * @retval HITLS_PACK_SESSIONID_ERR Failed to pack the sessionId. + * @retval HITLS_MEMCPY_FAIL Memory Copy Failure + */ +int32_t PackSessionId(const uint8_t *id, uint32_t idSize, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + /* If the sessionId length does not meet the requirement, return an error code */ + if ((idSize != 0) && ((idSize > TLS_HS_MAX_SESSION_ID_SIZE) || (idSize < TLS_HS_MIN_SESSION_ID_SIZE))) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SESSIONID_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15849, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "session id size is incorrect when pace session id.", 0, 0, 0, 0); + return HITLS_PACK_SESSIONID_ERR; + } + + uint32_t bufOffset = 0u; + buf[bufOffset] = (uint8_t)idSize; + + /* Calculate the buffer offset length */ + bufOffset += sizeof(uint8_t); + /* If the value of sessionId is 0, return HITLS_SUCCESS */ + if (idSize == 0u) { + *usedLen = bufOffset; + return HITLS_SUCCESS; + } + + /* Copy the session ID */ + int32_t ret = memcpy_s(&buf[bufOffset], bufLen - bufOffset, id, idSize); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15850, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack session id.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + /* Update the offset length */ + bufOffset += idSize; + + *usedLen = bufOffset; + return HITLS_SUCCESS; +} + +/** + * @brief Pack the message header. + * + * @param type [IN] message type + * @param sequence [IN] Sequence number (dedicated for DTLS) + * @param length [IN] message body length + * @param buf [OUT] message header + */ +void PackDtlsMsgHeader(HS_MsgType type, uint16_t sequence, uint32_t length, uint8_t *buf) +{ + buf[0] = (uint8_t)type & 0xffu; /** Type of the handshake message */ + BSL_Uint24ToByte(length, &buf[DTLS_HS_MSGLEN_ADDR]); /** Fills the length of the handshake message */ + BSL_Uint16ToByte( + sequence, &buf[DTLS_HS_MSGSEQ_ADDR]); /** Two bytes starting from four bytes are the sn of the message */ + BSL_Uint24ToByte( + 0, &buf[DTLS_HS_FRAGMENT_OFFSET_ADDR]); /** The three bytes starting from 6 bytes are the fragment offset. */ + BSL_Uint24ToByte( + length, &buf[DTLS_HS_FRAGMENT_LEN_ADDR]); /** Three bytes starting from 9 bytes are the fragment length. */ +} diff --git a/tls/handshake/pack/src/pack_common.h b/tls/handshake/pack/src/pack_common.h new file mode 100644 index 00000000..56e39ca7 --- /dev/null +++ b/tls/handshake/pack/src/pack_common.h @@ -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 PACK_COMMON_H +#define PACK_COMMON_H + +#include +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Pack session ID + * + * @param id [IN] Session ID + * @param idSize [IN] Session ID length + * @param buf [OUT] Message buffer + * @param bufLen [IN] Maximum message length + * @param usedLen [OUT] Length of message + * + * @retval HITLS_SUCCESS + * @retval HITLS_PACK_SESSIONID_ERR Failed to pack sessionId + * @retval HITLS_MEMCPY_FAIL Memory Copy Failed + */ +int32_t PackSessionId(const uint8_t *id, uint32_t idSize, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack DTLS message header + * + * @param type [IN] Message type + * @param sequence [IN] Sequence number (only in DTLS) + * @param length [IN] Length of message body + * @param buf [OUT] Message header + */ +void PackDtlsMsgHeader(HS_MsgType type, uint16_t sequence, uint32_t length, uint8_t *buf); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PACK_COMMON_H */ \ No newline at end of file diff --git a/tls/handshake/pack/src/pack_encrypted_extensions.c b/tls/handshake/pack/src/pack_encrypted_extensions.c new file mode 100644 index 00000000..52eeaeae --- /dev/null +++ b/tls/handshake/pack/src/pack_encrypted_extensions.c @@ -0,0 +1,176 @@ +/* + * 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 +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_extensions.h" +#include "pack_extensions.h" + + +static int32_t PackEncryptedSupportedGroups(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen; + uint16_t exMsgDataLen; + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if (config->groupsSize == 0) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + if (config->groups == NULL) { + return HITLS_SUCCESS; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint16_t); + exMsgDataLen = sizeof(uint16_t) * (uint16_t)config->groupsSize; + + /* Pack the extension header */ + ret = PackExtensionHeader(HS_EX_TYPE_SUPPORTED_GROUPS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack the extended support group */ + BSL_Uint16ToByte(exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + for (uint32_t index = 0; index < config->groupsSize; index++) { + BSL_Uint16ToByte(config->groups[index], &buf[offset]); + offset += sizeof(uint16_t); + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +/** + * @brief Pack the Encrypted_extensions extension. + * + * @param ctx [IN] TLS context + * @param buf [OUT] Return the handshake message buffer. + * @param bufLen [IN] Maximum buffer size of the handshake message. + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS succeeded. + * @retval For other error codes, see hitls_error.h. + */ +static int32_t PackEncryptedExs(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t listSize; + uint32_t exLen = 0u; + uint32_t offset = 0u; + + const PackExtInfo extMsgList[] = { + {.exMsgType = HS_EX_TYPE_SUPPORTED_GROUPS, + .needPack = true, + .packFunc = PackEncryptedSupportedGroups}, + {.exMsgType = HS_EX_TYPE_EARLY_DATA, /* This field is available only in 0-rrt mode */ + .needPack = false, + .packFunc = NULL}, + {.exMsgType = HS_EX_TYPE_SERVER_NAME, /* During extension, only empty SNI extensions are encapsulated. */ + .needPack = ctx->negotiatedInfo.isSniStateOK, + .packFunc = NULL}, + }; + + /* Calculate the number of extended types */ + listSize = sizeof(extMsgList) / sizeof(extMsgList[0]); + + /* Pack the Server Hello extension */ + for (uint32_t index = 0; index < listSize; index++) { + if (extMsgList[index].needPack == false) { + continue; + } + /* Empty extension */ + if (extMsgList[index].packFunc == NULL) { + exLen = 0u; + ret = PackEmptyExtension(extMsgList[index].exMsgType, extMsgList[index].needPack, + &buf[offset], bufLen - offset, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + /* Non-empty extension */ + if (extMsgList[index].packFunc != NULL) { + exLen = 0u; + ret = extMsgList[index].packFunc(ctx, &buf[offset], bufLen - offset, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +/** +* @brief Pack the Encrypted_extensions message. +* +* @param ctx [IN] TLS context +* @param buf [OUT] Return the handshake message buffer. +* @param bufLen [IN] Maximum buffer size of the handshake message. +* @param len [OUT] Returned message length +* +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_PACK_NOT_ENOUGH_BUF_LENGTH The message buffer length is insufficient. + */ +int32_t PackEncryptedExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t headerLen = 0u; + uint32_t exLen = 0u; + + /* Obtain the message header length */ + headerLen = sizeof(uint16_t); + /* If the length of the message structure is smaller than the length of the message header, + * return an error code */ + if (bufLen < headerLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15851, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of Encrypted_extensions extension message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Pack the encrypted_extensions extension */ + ret = PackEncryptedExs(ctx, &buf[headerLen], bufLen - headerLen, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Update the message length */ + if (exLen > 0u) { + BSL_Uint16ToByte((uint16_t)exLen, buf); + *usedLen = exLen + headerLen; + } else { + BSL_Uint16ToByte((uint16_t) 0, buf); + *usedLen = 0 + headerLen; + } + + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_extensions.c b/tls/handshake/pack/src/pack_extensions.c new file mode 100644 index 00000000..f2458bae --- /dev/null +++ b/tls/handshake/pack/src/pack_extensions.c @@ -0,0 +1,1302 @@ +/* + * 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 +#include + +#include "securec.h" +#include "cipher_suite.h" +#include "bsl_err_internal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_bytes.h" +#include "bsl_list.h" +#include "hitls_error.h" +#include "hitls_sni.h" +#include "hitls_cert_type.h" +#include "hitls_crypt_type.h" +#include "hitls_session.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_extensions.h" +#include "hs.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "session.h" +#include "hs_verify.h" +#include "pack_extensions.h" + +#define EXTENSION_MSG(exMsgT, needP, packF) \ + .exMsgType = (exMsgT), \ + .needPack = (needP), \ + .packFunc = (packF), \ + +// Pack the extension header. +int32_t PackExtensionHeader(uint16_t exMsgType, uint16_t exMsgLen, uint8_t *buf, uint32_t bufLen) +{ + if (bufLen < (HS_EX_HEADER_LEN + exMsgLen)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15409, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of extension is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + BSL_Uint16ToByte(exMsgType, buf); + BSL_Uint16ToByte(exMsgLen, buf + sizeof(uint16_t)); + + return HITLS_SUCCESS; +} +bool Tls13NeedPack(uint32_t version) +{ + bool tls13NeedPack = false; + if (IS_DTLS_VERSION(version)) { + tls13NeedPack = false; + } else { + tls13NeedPack = (version >= HITLS_VERSION_TLS13) ? true : false; + } + return tls13NeedPack; +} + +static int32_t PackCookie(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t exMsgDataLen = 0u; + uint32_t offset = 0u; + + if (ctx->negotiatedInfo.cookie == NULL) { + return HITLS_SUCCESS; + } + + /* Calculate the extension length */ + exMsgDataLen = sizeof(uint16_t) + (ctx->negotiatedInfo.cookieSize); + uint32_t cookieLen = ctx->negotiatedInfo.cookieSize; + + ret = PackExtensionHeader(HS_EX_TYPE_COOKIE, exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + BSL_Uint16ToByte(cookieLen, &buf[offset]); + offset += sizeof(uint16_t); + /* Pack the cookie */ + /* If the buffer length does not meet the requirement, return an error code. */ + if (bufLen - offset < cookieLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_COOKIE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15410, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of cookie is not enough.", 0, 0, 0, 0); + return HITLS_PACK_COOKIE_ERR; + } + + ret = memcpy_s(&buf[offset], bufLen - offset, ctx->negotiatedInfo.cookie, cookieLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15411, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack cookie.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += cookieLen; + + ctx->hsCtx->extFlag.haveCookie = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerName(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgDataLen = 0u; + uint32_t offset = 0u; + uint8_t *hostName = NULL; + uint8_t *serverName = NULL; + uint32_t hostNameSize, serverNameSize = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + bool isNotTls13 = (config->maxVersion < HITLS_VERSION_TLS13 || config->maxVersion == HITLS_VERSION_DTLS12); + + /* When a session whose protocol version is earlier than HITLS_VERSION_TLS13 is resumed, the servername extension + * field is the hostname in the session */ + if (isNotTls13 && ctx->session != NULL) { + /* Obtain the hostname in the session */ + SESS_GetHostName(ctx->session, &hostNameSize, &hostName); + serverName = hostName; + } else { + /* Obtain the servername in the config */ + serverName = config->serverName; + } + + if (serverName == NULL) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + serverNameSize = (uint32_t)strlen((char *)serverName); + /* Calculate the extension length */ + /* server Name list Length + server Name Type + Server Name Length + Server Name */ + exMsgDataLen = sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t) * serverNameSize; + + ret = PackExtensionHeader(HS_EX_TYPE_SERVER_NAME, exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack the extension Server Name Indication extension */ + /* server Name list Length */ + BSL_Uint16ToByte(exMsgDataLen - sizeof(uint16_t), &buf[offset]); + offset += sizeof(uint16_t); + + /* server Name Type */ + buf[offset] = HITLS_SNI_HOSTNAME_TYPE; + offset += sizeof(uint8_t); + + /* Server Name Length */ + BSL_Uint16ToByte((uint16_t)serverNameSize, &buf[offset]); + offset += sizeof(uint16_t); + + /* Server Name */ + if (memcpy_s(&buf[offset], bufLen - offset, serverName, serverNameSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15412, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack server_name.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + + offset += serverNameSize; + + /* Set the extension flag */ + ctx->hsCtx->extFlag.haveServerName = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientSignatureAlgorithms(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen = 0u; + uint16_t exMsgDataLen = 0u; + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if (config->signAlgorithmsSize == 0) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + if (config->signAlgorithms == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15413, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack signature algirithms extension error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint16_t); + exMsgDataLen = sizeof(uint16_t) * (uint16_t)config->signAlgorithmsSize; + + /* Pack the extension header */ + ret = PackExtensionHeader(HS_EX_TYPE_SIGNATURE_ALGORITHMS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack the extended signature algorithm. */ + BSL_Uint16ToByte(exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + for (uint32_t index = 0; index < config->signAlgorithmsSize; index++) { + BSL_Uint16ToByte(config->signAlgorithms[index], &buf[offset]); + offset += sizeof(uint16_t); + } + + /* Set the extension flag */ + ctx->hsCtx->extFlag.haveSignatureAlgorithms = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientSupportedGroups(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen = 0u; + uint16_t exMsgDataLen = 0u; + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if (config->groupsSize == 0) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + if (config->groups == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15414, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack supported groups extension error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint16_t); + exMsgDataLen = sizeof(uint16_t) * (uint16_t)config->groupsSize; + + ret = PackExtensionHeader(HS_EX_TYPE_SUPPORTED_GROUPS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack extended supported groups */ + BSL_Uint16ToByte(exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + for (uint32_t index = 0; index < config->groupsSize; index++) { + BSL_Uint16ToByte(config->groups[index], &buf[offset]); + offset += sizeof(uint16_t); + } + + /* Set the extension flag */ + ctx->hsCtx->extFlag.haveSupportedGroups = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackPointFormats(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen = 0u; + uint8_t exMsgDataLen = 0u; + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if (config->pointFormatsSize == 0) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + if (config->pointFormats == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15415, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack point formats extension error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint8_t); + exMsgDataLen = (uint8_t)config->pointFormatsSize; + + ret = PackExtensionHeader(HS_EX_TYPE_POINT_FORMATS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack the extension point format */ + buf[offset] = exMsgDataLen; + offset += sizeof(uint8_t); + for (uint32_t index = 0; index < config->pointFormatsSize; index++) { + buf[offset] = config->pointFormats[index]; + offset += sizeof(uint8_t); + } + + /* Set the extension flag */ + ctx->hsCtx->extFlag.havePointFormats = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientAlpnList(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen = 0u; + uint8_t exMsgDataLen = 0u; + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + + if (config->alpnListSize == 0) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + if (config->alpnList == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15416, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack alpn list extension error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint16_t); + exMsgDataLen = (uint8_t)config->alpnListSize; + + ret = PackExtensionHeader(HS_EX_TYPE_APP_LAYER_PROTOCOLS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + BSL_Uint16ToByte(exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + if (memcpy_s(&buf[offset], bufLen - offset, config->alpnList, config->alpnListSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15417, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack alpn list extension error, memory copy failed.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + offset += (config->alpnListSize); + + /* Set the extension flag */ + ctx->hsCtx->extFlag.haveAlpn = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint8_t *ticket = NULL; + uint32_t ticketSize = 0; + uint16_t sessVersion = HITLS_VERSION_TLS13; + + if (ctx->session != NULL) { + HITLS_SESS_GetProtocolVersion(ctx->session, &sessVersion); + } + + /* Whether the ticket belongs to tls1.3 needs to be determined */ + if (sessVersion != HITLS_VERSION_TLS13) { + SESS_GetTicket(ctx->session, &ticket, &ticketSize); + } + + ret = PackExtensionHeader(HS_EX_TYPE_SESSION_TICKET, (uint16_t)ticketSize, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + if (ticketSize != 0 && memcpy_s(&buf[offset], bufLen - offset, ticket, ticketSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15963, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + " pack ticket error, memory copy failed.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + offset += ticketSize; + + /* Set the extension flag. */ + ctx->hsCtx->extFlag.haveTicket = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +int32_t PackEmptyExtension(uint16_t exMsgType, bool needPack, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + int32_t ret = 0; + if (needPack) { + ret = PackExtensionHeader(exMsgType, 0u, &buf[offset], bufLen - offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + } + /* Update the message length */ + *usedLen = offset; + return HITLS_SUCCESS; +} +static int32_t PackClientSupportedVersions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen = 0u; + uint8_t exMsgDataLen = 0u; + uint32_t offset = 0u; + const TLS_Config *config = &(ctx->config.tlsConfig); + uint16_t minVersion = config->minVersion; + uint16_t maxVersion = config->maxVersion; + + if (config->minVersion < HITLS_VERSION_SSL30 || config->maxVersion > HITLS_VERSION_TLS13) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15418, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack supported version extension error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint8_t); + exMsgDataLen = sizeof(uint16_t) * (maxVersion - minVersion + 1); + + ret = PackExtensionHeader(HS_EX_TYPE_SUPPORTED_VERSIONS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack the TLS version supported by the extension */ + buf[offset] = exMsgDataLen; + offset += sizeof(exMsgDataLen); + + for (uint16_t version = maxVersion; version >= minVersion; version--) { + BSL_Uint16ToByte(version, &buf[offset]); + offset += sizeof(uint16_t); + } + + /* Set the extension flag */ + ctx->hsCtx->extFlag.haveSupportedVers = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientPskKeyExModes(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + bool allowOnly = false; + bool allowDhe = false; + const uint32_t configKxMode = ctx->config.tlsConfig.keyExchMode; + uint16_t exMsgHeaderLen = sizeof(uint8_t); + uint16_t exMsgDataLen = 0; + + if ((bool)(configKxMode & TLS13_KE_MODE_PSK_WITH_DHE)) { + exMsgDataLen++; + allowDhe = true; + } + if ((bool)(configKxMode & TLS13_KE_MODE_PSK_ONLY)) { + exMsgDataLen++; + allowOnly = true; + } + + int32_t ret = PackExtensionHeader(HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint32_t offset = HS_EX_HEADER_LEN; + + /* Pack the length of the key exchange pattern extension */ + buf[offset] = (uint8_t)exMsgDataLen; + offset += sizeof(uint8_t); + if (allowDhe) { + buf[offset] = PSK_DHE_KE; + offset += sizeof(uint8_t); + } + if (allowOnly) { + buf[offset] = PSK_KE; + offset += sizeof(uint8_t); + } + + ctx->hsCtx->extFlag.havePskExMode = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientKeyShare(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t needKeyShareMode = TLS13_KE_MODE_PSK_WITH_DHE | TLS13_CERT_AUTH_WITH_DHE; + if ((ctx->negotiatedInfo.tls13BasicKeyExMode & needKeyShareMode) == 0) { + return HITLS_SUCCESS; + } + int32_t ret; + uint16_t exMsgHeaderLen; + uint16_t exMsgDataLen; + uint32_t pubKeyLen; + uint32_t offset = 0u; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + if (kxCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + KeyShareParam *keyShare = &(kxCtx->keyExchParam.share); + + pubKeyLen = HS_GetNamedCurvePubkeyLen(keyShare->group); + if (pubKeyLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15422, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid keyShare length.", 0, 0, 0, 0); + return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint16_t); + /* Length of group + Length of KeyExChange + KeyExChange */ + exMsgDataLen = sizeof(uint16_t) + sizeof(uint16_t) + (uint16_t)pubKeyLen; + + ret = PackExtensionHeader(HS_EX_TYPE_KEY_SHARE, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + /* Pack the total length of client_keyShare */ + BSL_Uint16ToByte(exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + /* Pack a group */ + BSL_Uint16ToByte((uint16_t)keyShare->group, &buf[offset]); + offset += sizeof(uint16_t); + + /* Length of the Pack KeyExChange */ + BSL_Uint16ToByte((uint16_t)pubKeyLen, &buf[offset]); + offset += sizeof(uint16_t); + uint32_t pubKeyUsedLen = 0; + /* Pack KeyExChange */ + ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->key, &buf[offset], pubKeyLen, &pubKeyUsedLen); + if (ret != HITLS_SUCCESS || pubKeyUsedLen != pubKeyLen) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15423, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode client keyShare key fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + offset += pubKeyLen; + + ctx->hsCtx->extFlag.haveKeyShare = true; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackClientSecRenegoInfo(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + if (!ctx->negotiatedInfo.isRenegotiation) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + /* Calculate the extension length */ + const uint8_t *clientData = ctx->negotiatedInfo.clientVerifyData; + uint32_t clientDataSize = ctx->negotiatedInfo.clientVerifyDataSize; + uint16_t exMsgHeaderLen = sizeof(uint8_t); + uint16_t exMsgDataLen = (uint16_t)clientDataSize; + + /* Pack the extension header */ + int32_t ret; + uint32_t offset = 0; + ret = PackExtensionHeader(HS_EX_TYPE_RENEGOTIATION_INFO, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + if ((bufLen - offset) < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15424, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "bufLen not enough when pack client renegotiation info.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Pack the length of secRenegoInfo */ + buf[offset] = (uint8_t)clientDataSize; + offset++; + + /* Pack the secRenegoInfo content */ + if (memcpy_s(&buf[offset], bufLen - offset, clientData, clientDataSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15425, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy clientVerifyData fail when pack client renegotiation info.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + offset += clientDataSize; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static bool IsNeedPackEcExtension(const TLS_Ctx *ctx) +{ + const TLS_Config *config = &(ctx->config.tlsConfig); + + if ((config->maxVersion == HITLS_VERSION_TLS13)) { + uint32_t needKeyShareMode = TLS13_KE_MODE_PSK_WITH_DHE | TLS13_CERT_AUTH_WITH_DHE; + if ((ctx->negotiatedInfo.tls13BasicKeyExMode & needKeyShareMode) != 0) { + return true; + } + } + + for (uint32_t index = 0; index < config->cipherSuitesSize; index++) { + CipherSuiteInfo cipherInfo = {0}; + /* The returned value does not need to be checked. The validity of the cipher suite is checked when the cipher + * suite is configured */ + (void)CFG_GetCipherSuiteInfo(config->cipherSuites[index], &cipherInfo); + + /* The ECC algorithm suite exists */ + if ((cipherInfo.authAlg == HITLS_AUTH_ECDSA) || + (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) || + (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDH) || + (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) { + return true; + } + } + + return false; +} + +static bool IsServerNeedPackEcExtension(const TLS_Ctx *ctx) +{ + const TLS_NegotiatedInfo *negotiatedInfo = &(ctx->negotiatedInfo); + CipherSuiteInfo cipherInfo = negotiatedInfo->cipherSuiteInfo; + + /* The negotiated algorithm suite is the ECC cipher suite */ + if (((cipherInfo.authAlg == HITLS_AUTH_ECDSA) || (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) || + (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDH) || (cipherInfo.kxAlg == HITLS_KEY_EXCH_ECDHE_PSK)) && + ctx->haveClientPointFormats == true) { + return true; + } + + return false; +} + +static bool IsNeedClientPackServerName(const TLS_Ctx *ctx) +{ + const TLS_Config *config = &(ctx->config.tlsConfig); + + /* not in session resumption */ + if (ctx->session == NULL) { + if (config->serverName == NULL) { + return false; + } + } + + /* The session is being resume */ + if (ctx->session != NULL) { + if (config->maxVersion == HITLS_VERSION_TLS13 && config->serverName == NULL) { + return false; + } + } + + return true; +} + +static bool IsNeedPreSharedKey(const TLS_Ctx *ctx) +{ + if (ctx->config.tlsConfig.maxVersion != HITLS_VERSION_TLS13) { + return false; + } + + if (ctx->hsCtx->state == TRY_SEND_HELLO_RETRY_REQUEST) { + /* hello retry request does not contain the psk */ + return false; + } + + return true; +} + +static uint32_t GetPreSharedKeyExtLen(const PskInfo13 *pskInfo) +{ + uint32_t extLen = HS_EX_HEADER_LEN; + uint32_t binderLen = 0; + if (pskInfo->resumeSession != NULL) { + HITLS_HashAlgo hashAlg = HITLS_HASH_NULL; + binderLen = HS_GetBinderLen(pskInfo->resumeSession, &hashAlg); + if (binderLen == 0) { + return 0; + } + uint8_t *ticket = NULL; + uint32_t ticketSize = 0; + SESS_GetTicket(pskInfo->resumeSession, &ticket, &ticketSize); + extLen += sizeof(uint16_t) + ticketSize + sizeof(uint32_t) + sizeof(uint8_t) + binderLen; + } + + if (pskInfo->userPskSess != NULL) { + HITLS_HashAlgo hashAlg = HITLS_HASH_NULL; + binderLen = HS_GetBinderLen(pskInfo->userPskSess->pskSession, &hashAlg); + if (binderLen == 0) { + return 0; + } + extLen += sizeof(uint16_t) + pskInfo->userPskSess->identityLen + sizeof(uint32_t) + sizeof(uint8_t) + binderLen; + } + extLen += sizeof(uint16_t) + sizeof(uint16_t); + return extLen; +} + +static void PackClientPreSharedKeyIdentity(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *outOffset) +{ + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + uint32_t offset = *outOffset; + uint32_t offsetStamp = offset; + offset += sizeof(uint16_t); // skip identities len + if (pskInfo->resumeSession != NULL) { + uint8_t *ticket = NULL; + uint32_t ticketSize = 0; + SESS_GetTicket(pskInfo->resumeSession, &ticket, &ticketSize); + BSL_Uint16ToByte((uint16_t)ticketSize, &buf[offset]); + offset += sizeof(uint16_t); + // has passed the verification above, and it must be successful here. + (void)memcpy_s(&buf[offset], bufLen - offset, ticket, ticketSize); + offset += ticketSize; + uint32_t ageSec = (uint32_t)((uint64_t)BSL_SAL_CurrentSysTimeGet() - SESS_GetStartTime(pskInfo->resumeSession)); + + uint32_t agemSec = ageSec * 1000 + (uint32_t)SESS_GetTicketAgeAdd(pskInfo->resumeSession); /* unit: ms */ + BSL_Uint32ToByte(agemSec, &buf[offset]); + offset += sizeof(uint32_t); + } + + if (pskInfo->userPskSess != NULL) { + BSL_Uint16ToByte((uint16_t)pskInfo->userPskSess->identityLen, &buf[offset]); + offset += sizeof(uint16_t); + (void)memcpy_s(&buf[offset], bufLen - offset, + // has passed the verification above, and it must be successful here + pskInfo->userPskSess->identity, pskInfo->userPskSess->identityLen); + offset += pskInfo->userPskSess->identityLen; + BSL_Uint32ToByte(0, &buf[offset]); + offset += sizeof(uint32_t); + } + BSL_Uint16ToByte((uint16_t)(offset - offsetStamp - sizeof(uint16_t)), &buf[offsetStamp]); + *outOffset = offset; +} + +// ClientPreSharedKey: pskid, binder, see rfc 8446 section 4.2.11, currently support one pskid and one binder +static int32_t PackClientPreSharedKey(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + if (pskInfo->resumeSession == NULL && pskInfo->userPskSess == NULL) { + return HITLS_SUCCESS; + } + uint32_t minLen = GetPreSharedKeyExtLen(pskInfo); + if (minLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_PRE_SHARED_KEY_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15939, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Binder size is zero when PackClientPreSharedKey", 0, 0, 0, 0); + return HITLS_PACK_PRE_SHARED_KEY_ERR; + } + if (minLen > bufLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15446, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of extension is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + (void)PackExtensionHeader(HS_EX_TYPE_PRE_SHARED_KEY, (uint16_t)(minLen - HS_EX_HEADER_LEN), buf, bufLen); + uint32_t offset = HS_EX_HEADER_LEN; + (void)PackClientPreSharedKeyIdentity(ctx, buf, bufLen, &offset); + // pack binder after fills in the message header and extension length. call PackClientPreSharedKeyBinders + ctx->hsCtx->extFlag.havePreShareKey = true; + *usedLen = minLen; + return HITLS_SUCCESS; +} + +static bool IsNeedPackPha(const TLS_Ctx *ctx) +{ + const TLS_Config *tlsConfig = &ctx->config.tlsConfig; + if (tlsConfig->maxVersion != HITLS_VERSION_TLS13) { + return false; + } + return tlsConfig->isSupportPostHandshakeAuth; +} + +static int32_t PackExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t *bufLen, + PackExtInfo *extMsgList, uint32_t listSize) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t inBufLen = *bufLen; + uint32_t exLen, offset = 0u; + for (uint32_t index = 0; index < listSize; index++) { + if (extMsgList[index].needPack == false) { + continue; + } + + exLen = 0u; + /* Empty expansion */ + if (extMsgList[index].packFunc == NULL) { + ret = PackEmptyExtension(extMsgList[index].exMsgType, extMsgList[index].needPack, + &buf[offset], inBufLen - offset, &exLen); + } else { /* Non-empty expansion */ + exLen = 0u; + ret = extMsgList[index].packFunc(ctx, &buf[offset], inBufLen - offset, &exLen); + } + + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + *bufLen = offset; + return HITLS_SUCCESS; +} + +static bool IsNeedEms(const TLS_Ctx *ctx) +{ + if (ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLCP11) { + return false; + } + if (ctx->config.tlsConfig.isSupportExtendMasterSecret) { + return true; + } + if (ctx->session != NULL) { + uint8_t haveExtMasterSecret; + HITLS_SESS_GetHaveExtMasterSecret(ctx->session, &haveExtMasterSecret); + return haveExtMasterSecret != 0; + } + return true; +} + +// Pack the non-null extension of client hello. +static int32_t PackClientExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + const TLS_Config *tlsConfig = &ctx->config.tlsConfig; + const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo; + + bool isTls13 = (tlsConfig->maxVersion == HITLS_VERSION_TLS13); + + /* Check whether EC extensions need to be filled */ + bool isEcNeed = IsNeedPackEcExtension(ctx); + + /* If the version is earlier than tls1.2, the signature extension cannot be sent */ + bool isSignAlgNeed = (ctx->config.tlsConfig.maxVersion >= HITLS_VERSION_TLS12); + + bool isSessionTicketNeed = IsTicketSupport((TLS_Ctx *)ctx); + + bool isNeedPha = IsNeedPackPha(ctx); + + PackExtInfo extMsgList[] = { + { EXTENSION_MSG(HS_EX_TYPE_SERVER_NAME, IsNeedClientPackServerName(ctx), PackServerName) }, + { EXTENSION_MSG(HS_EX_TYPE_SIGNATURE_ALGORITHMS, isSignAlgNeed, PackClientSignatureAlgorithms) }, + { EXTENSION_MSG(HS_EX_TYPE_SUPPORTED_GROUPS, isEcNeed, PackClientSupportedGroups) }, + { EXTENSION_MSG(HS_EX_TYPE_POINT_FORMATS, isEcNeed, PackPointFormats) }, + { EXTENSION_MSG(HS_EX_TYPE_SUPPORTED_VERSIONS, isTls13, PackClientSupportedVersions) }, + { EXTENSION_MSG(HS_EX_TYPE_EARLY_DATA, false, NULL) }, + { EXTENSION_MSG(HS_EX_TYPE_COOKIE, isTls13, PackCookie) }, + { EXTENSION_MSG(HS_EX_TYPE_POST_HS_AUTH, isNeedPha, NULL) }, + { EXTENSION_MSG(HS_EX_TYPE_EXTENDED_MASTER_SECRET, IsNeedEms(ctx), NULL) }, + { EXTENSION_MSG(HS_EX_TYPE_APP_LAYER_PROTOCOLS, (tlsConfig->alpnList != NULL), PackClientAlpnList) }, + { EXTENSION_MSG(HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES, isTls13, PackClientPskKeyExModes) }, + { EXTENSION_MSG(HS_EX_TYPE_KEY_SHARE, isTls13, PackClientKeyShare) }, + { EXTENSION_MSG(HS_EX_TYPE_RENEGOTIATION_INFO, negoInfo->isSecureRenegotiation, PackClientSecRenegoInfo) }, + { EXTENSION_MSG(HS_EX_TYPE_SESSION_TICKET, isSessionTicketNeed, PackClientTicket) }, + { EXTENSION_MSG(HS_EX_TYPE_ENCRYPT_THEN_MAC, tlsConfig->isEncryptThenMac, NULL) }, + /* The preshare key must be the last extension */ + { EXTENSION_MSG(HS_EX_TYPE_PRE_SHARED_KEY, IsNeedPreSharedKey(ctx), PackClientPreSharedKey) }, + }; + + uint32_t tmpBufLen = bufLen; + ret = PackExtensions(ctx, buf, &tmpBufLen, extMsgList, sizeof(extMsgList) / sizeof(extMsgList[0])); + if (ret != HITLS_SUCCESS) { + return ret; + } + *usedLen = tmpBufLen; + ctx->hsCtx->extFlag.havePostHsAuth = isNeedPha; + ctx->hsCtx->extFlag.haveExtendedMasterSecret = IsNeedEms(ctx); + ctx->hsCtx->extFlag.haveEncryptThenMac = ctx->config.tlsConfig.isEncryptThenMac; + return HITLS_SUCCESS; +} + +// Pack the Client Hello extension +int32_t PackClientExtension(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t headerLen = 0u; + uint32_t exLen = 0u; + + /* Obtain the message header length */ + headerLen = sizeof(uint16_t); + if (bufLen < headerLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15426, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of client hello extension message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Pack the client hello extension content */ + ret = PackClientExtensions(ctx, &buf[headerLen], bufLen - headerLen, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (exLen > 0u) { + BSL_Uint16ToByte((uint16_t)exLen, buf); + *len = exLen + headerLen; + } else { + *len = 0u; + } + + return ret; +} + +static int32_t PackServerSelectAlpnProto(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgHeaderLen = 0u; + uint8_t exMsgDataLen = 0u; + uint32_t offset = 0u; + + if (ctx->negotiatedInfo.alpnSelectedSize == 0) { + *usedLen = 0; + return HITLS_SUCCESS; + } + + /* Calculate the extension length */ + exMsgHeaderLen = sizeof(uint16_t); + exMsgDataLen = (uint8_t)ctx->negotiatedInfo.alpnSelectedSize + sizeof(uint8_t); + + /* Pack the extension header */ + ret = PackExtensionHeader(HS_EX_TYPE_APP_LAYER_PROTOCOLS, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + BSL_Uint16ToByte((uint16_t)exMsgDataLen, &buf[offset]); + offset += sizeof(uint16_t); + buf[offset] = exMsgDataLen - sizeof(uint8_t); + offset += sizeof(uint8_t); + if (memcpy_s(&buf[offset], bufLen - offset, ctx->negotiatedInfo.alpnSelected, + ctx->negotiatedInfo.alpnSelectedSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15427, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack alpn list extension error, memory copy failed.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + offset += ctx->negotiatedInfo.alpnSelectedSize; + + /* Set the extension flag */ + ctx->hsCtx->extFlag.haveAlpn = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackHrrKeyShare(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgDataLen = 0u; + uint32_t offset = 0u; + KeyShareParam *keyShare = &(ctx->hsCtx->kxCtx->keyExchParam.share); + + /* Message length = group length */ + exMsgDataLen = sizeof(uint16_t); + + ret = PackExtensionHeader(HS_EX_TYPE_KEY_SHARE, exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack a group */ + BSL_Uint16ToByte((uint16_t)keyShare->group, &buf[offset]); + offset += sizeof(uint16_t); + + ctx->hsCtx->extFlag.haveKeyShare = true; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerKeyShare(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgDataLen = 0u; + uint32_t pubKeyLen = 0u; + uint32_t offset = 0u; + KeyShareParam *keyShare = &(ctx->hsCtx->kxCtx->keyExchParam.share); + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + + /* If the peer public key does not exist, the psk_only mode is used. In this case, the key share does not need to be + * sent */ + if (kxCtx->peerPubkey == NULL) { + return HITLS_SUCCESS; + } + + pubKeyLen = HS_GetNamedCurvePubkeyLen(keyShare->group); + if (pubKeyLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15428, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid keyShare length.", 0, 0, 0, 0); + return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH; + } + + /* Length of group + Length of KeyExChange + KeyExChange */ + exMsgDataLen = sizeof(uint16_t) + sizeof(uint16_t) + (uint16_t)pubKeyLen; + + ret = PackExtensionHeader(HS_EX_TYPE_KEY_SHARE, exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + /* Pack a group */ + BSL_Uint16ToByte((uint16_t)keyShare->group, &buf[offset]); + offset += sizeof(uint16_t); + + /* Length of the paced KeyExChange */ + BSL_Uint16ToByte((uint16_t)pubKeyLen, &buf[offset]); + offset += sizeof(uint16_t); + uint32_t pubKeyUsedLen = 0; + /* Pack KeyExChange */ + ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->key, &buf[offset], pubKeyLen, &pubKeyUsedLen); + if (ret != HITLS_SUCCESS || pubKeyLen != pubKeyUsedLen) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15429, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode server keyShare key fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + offset += pubKeyLen; + + ctx->hsCtx->extFlag.haveKeyShare = true; + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerSupportedVersion(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t exMsgDataLen = 0u; + uint32_t offset = 0u; + const uint16_t supportedVersion = ctx->negotiatedInfo.version; + + if (supportedVersion <= 0) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15430, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack supported version extension error, invalid input parameter.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + /* Calculate the extension length */ + exMsgDataLen = sizeof(uint16_t); + + ret = PackExtensionHeader(HS_EX_TYPE_SUPPORTED_VERSIONS, exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + BSL_Uint16ToByte(supportedVersion, &buf[offset]); + offset += sizeof(uint16_t); + + ctx->hsCtx->extFlag.haveSupportedVers = true; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerSecRenegoInfo(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + bool isRenegotiation = ctx->negotiatedInfo.isRenegotiation; + const uint8_t *clientData = ctx->negotiatedInfo.clientVerifyData; + uint32_t clientDataSize = ctx->negotiatedInfo.clientVerifyDataSize; + const uint8_t *serverData = ctx->negotiatedInfo.serverVerifyData; + uint32_t serverDataSize = ctx->negotiatedInfo.serverVerifyDataSize; + /* Calculate the extension length */ + uint16_t exMsgHeaderLen = sizeof(uint8_t); + /* For renegotiation, the verify data (client data + server data) must be assembled */ + uint16_t exMsgDataLen = (uint16_t)(isRenegotiation ? (clientDataSize + serverDataSize) : 0); + + uint32_t offset = 0; + int32_t ret = PackExtensionHeader(HS_EX_TYPE_RENEGOTIATION_INFO, exMsgHeaderLen + exMsgDataLen, buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += HS_EX_HEADER_LEN; + + if ((bufLen - offset) < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15431, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "bufLen not enough when pack server renegotiation info.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + if (!isRenegotiation) { + buf[offset++] = 0; + *usedLen = offset; + return HITLS_SUCCESS; + } + + /* Pack the length of secRenegoInfo */ + buf[offset++] = (uint8_t)(clientDataSize + serverDataSize); + + /* Pack the secRenegoInfo content */ + if (memcpy_s(&buf[offset], bufLen - offset, clientData, clientDataSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15432, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy clientVerifyData fail when pack server renegotiation info.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + offset += clientDataSize; + + if (bufLen - offset < serverDataSize) { + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + if (memcpy_s(&buf[offset], bufLen - offset, serverData, serverDataSize) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15433, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy serverVerifyData fail when pack server renegotiation info.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + offset += serverDataSize; + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t IsHrrKeyShare(const TLS_Ctx *ctx) +{ + bool haveHrr = ctx->hsCtx->haveHrr; /* Sent or in the process of sending hrr */ + bool haveKeyShare = ctx->hsCtx->extFlag.haveKeyShare; /* has packed the keyshare */ + + if (haveHrr && !haveKeyShare) { + return true; + } + return false; +} + +static bool IsNeedServerPackServerName(const TLS_Ctx *ctx) +{ + const TLS_Config *config = &(ctx->config.tlsConfig); + const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo; + + /* The protocol version is earlier than tls1.3 and the server accepts the server name. The server hello message sent + * by the server contains an empty server name extension */ + if (negoInfo->isSniStateOK && + (config->maxVersion < HITLS_VERSION_TLS13 || config->maxVersion == HITLS_VERSION_DTLS12)) { + return true; + } + return false; +} + +static bool IsNeedServerPackEncryptThenMac(const TLS_Ctx *ctx) +{ + const TLS_Config *config = &(ctx->config.tlsConfig); + const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo; + if (config->isEncryptThenMac && negoInfo->isEncryptThenMac) { + return true; + } + return false; +} + +static int32_t PackServerPreSharedKey(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + const PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + if (pskInfo->psk == NULL) { + return HITLS_SUCCESS; + } + int32_t ret = PackExtensionHeader(HS_EX_TYPE_PRE_SHARED_KEY, sizeof(uint16_t), buf, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_Uint16ToByte((uint16_t)pskInfo->selectIndex, &buf[HS_EX_HEADER_LEN]); + *usedLen = HS_EX_HEADER_LEN + sizeof(uint16_t); + + return HITLS_SUCCESS; +} + +// Pack the empty extension of Server Hello +static int32_t PackServerExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t listSize = 0u; + uint32_t exLen = 0u; + uint32_t offset = 0u; + uint32_t version = HS_GetVersion(ctx); + bool isHrrKeyshare = IsHrrKeyShare(ctx); + bool isTls13 = Tls13NeedPack(version); + const TLS_NegotiatedInfo *negoInfo = &ctx->negotiatedInfo; + + PackExtInfo extMsgList[] = { + { EXTENSION_MSG(HS_EX_TYPE_SERVER_NAME, IsNeedServerPackServerName(ctx), NULL) }, + { EXTENSION_MSG(HS_EX_TYPE_COOKIE, isTls13, PackCookie) }, + { EXTENSION_MSG(HS_EX_TYPE_SESSION_TICKET, negoInfo->isTicket, NULL) }, + { EXTENSION_MSG(HS_EX_TYPE_POINT_FORMATS, IsServerNeedPackEcExtension(ctx), PackPointFormats) }, + { EXTENSION_MSG(HS_EX_TYPE_SUPPORTED_VERSIONS, isTls13, PackServerSupportedVersion) }, + { EXTENSION_MSG(HS_EX_TYPE_EXTENDED_MASTER_SECRET, negoInfo->isExtendedMasterSecret, NULL) }, + { EXTENSION_MSG(HS_EX_TYPE_APP_LAYER_PROTOCOLS, (negoInfo->alpnSelected != NULL), PackServerSelectAlpnProto) }, + { EXTENSION_MSG(HS_EX_TYPE_KEY_SHARE, (isTls13 && !isHrrKeyshare), PackServerKeyShare) }, + { EXTENSION_MSG(HS_EX_TYPE_KEY_SHARE, (isTls13 && isHrrKeyshare), PackHrrKeyShare) }, + { EXTENSION_MSG(HS_EX_TYPE_RENEGOTIATION_INFO, negoInfo->isSecureRenegotiation, PackServerSecRenegoInfo) }, + { EXTENSION_MSG(HS_EX_TYPE_ENCRYPT_THEN_MAC, IsNeedServerPackEncryptThenMac(ctx), NULL) }, + /* The preshare key must be the last extension */ + { EXTENSION_MSG(HS_EX_TYPE_PRE_SHARED_KEY, IsNeedPreSharedKey(ctx), PackServerPreSharedKey) }, + }; + + /* Calculate the number of extended types */ + listSize = sizeof(extMsgList) / sizeof(extMsgList[0]); + + /* Pack the Server Hello extension */ + for (uint32_t index = 0; index < listSize; index++) { + if (extMsgList[index].needPack == false) { + continue; + } + /* Empty extension */ + if (extMsgList[index].packFunc == NULL) { + exLen = 0u; + ret = PackEmptyExtension(extMsgList[index].exMsgType, extMsgList[index].needPack, + &buf[offset], bufLen - offset, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + /* No empty extension */ + if (extMsgList[index].packFunc != NULL) { + exLen = 0u; + ret = extMsgList[index].packFunc(ctx, &buf[offset], bufLen - offset, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += exLen; + } + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerExBody(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *exLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t usedLen = 0u; + + ret = PackServerExtensions(ctx, &buf[offset], bufLen - offset, &usedLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += usedLen; + + /* Pack the nonempty extension of server hello. No nonempty extension of server hello is supported. */ + + /* Update the message length */ + *exLen = offset; + return HITLS_SUCCESS; +} + +// Pack the Server Hello extension +int32_t PackServerExtension(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t headerLen = 0u; + uint32_t exLen = 0u; + + /* Obtain the message header length */ + headerLen = sizeof(uint16_t); + if (bufLen < headerLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15434, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of server hello extension message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Pack the server hello extension content */ + ret = PackServerExBody(ctx, &buf[headerLen], bufLen - headerLen, &exLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Update the message length */ + if (exLen > 0u) { + BSL_Uint16ToByte((uint16_t)exLen, buf); + *len = exLen + headerLen; + } else { + *len = 0u; + } + + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/handshake/pack/src/pack_extensions.h b/tls/handshake/pack/src/pack_extensions.h new file mode 100644 index 00000000..d2f34bd9 --- /dev/null +++ b/tls/handshake/pack/src/pack_extensions.h @@ -0,0 +1,102 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef PACK_EXTENSIONS_H +#define PACK_EXTENSIONS_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Hook function for packing extensions of client and server. + */ +typedef int32_t (*PACK_EXT_FUNC)(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len); + +/** + * PackExtInfo structure, used to transfer extension information of ClientHello messages + */ +typedef struct { + uint16_t exMsgType; /**< Extension type of message*/ + bool needPack; /**< Whether packing is needed */ + PACK_EXT_FUNC packFunc; /**< Hook for packing extensions*/ +} PackExtInfo; + +typedef void (*GET_EXTSIZE_FUNC)(const TLS_Ctx *ctx, uint32_t *exSize); + +typedef struct { + bool needCheck; + GET_EXTSIZE_FUNC getSizeFunc; +} GetExtFieldSize; + +/** + * @brief Pack Client Hello extension + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message buffer + * @param bufLen [IN] Maximum buffer length of the handshake message + * @param len [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval HITLS_PACK_NOT_ENOUGH_BUF_LENGTH The message buffer length is insufficient + */ +int32_t PackClientExtension(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len); + +/** + * @brief Pack Server Hello extension + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message buffer + * @param bufLen [IN] Maximum buffer length of the handshake message + * @param len [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval HITLS_PACK_NOT_ENOUGH_BUF_LENGTH The message buffer length is insufficient + */ +int32_t PackServerExtension(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len); + +/** + * @brief Pack an empty extension + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message buffer + * @param bufLen [IN] Maximum buffer length of the handshake message + * @param len [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval HITLS_PACK_NOT_ENOUGH_BUF_LENGTH The message buffer length is insufficient + */ +int32_t PackEmptyExtension(uint16_t exMsgType, bool needPack, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +/** + * @brief Pack the header of an extension + * + * @param exMsgType [IN] Extension type + * @param exMsgLen [IN] Extension length + * @param buf [OUT] Returned handshake message buffer + * @param bufLen [IN] Maximum buffer length of the handshake message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackExtensionHeader(uint16_t exMsgType, uint16_t exMsgLen, uint8_t *buf, uint32_t bufLen); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PACK_EXTENSIONS_H */ \ No newline at end of file diff --git a/tls/handshake/pack/src/pack_finished.c b/tls/handshake/pack/src/pack_finished.c new file mode 100644 index 00000000..b7a9efbb --- /dev/null +++ b/tls/handshake/pack/src/pack_finished.c @@ -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. + */ + +#include + +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" + +// pack the Finished message. +int32_t PackFinished(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = 0; + const HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + if (bufLen < hsCtx->verifyCtx->verifyDataSize) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15861, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of finished message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + ret = memcpy_s(buf, bufLen, hsCtx->verifyCtx->verifyData, hsCtx->verifyCtx->verifyDataSize); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15862, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy verify data fail when pack finished msg.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + *usedLen = hsCtx->verifyCtx->verifyDataSize; + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_key_update.c b/tls/handshake/pack/src/pack_key_update.c new file mode 100644 index 00000000..2bdb0454 --- /dev/null +++ b/tls/handshake/pack/src/pack_key_update.c @@ -0,0 +1,43 @@ +/* + * 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 + +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" + + +int32_t PackKeyUpdate(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint8_t keyUpdateValue = (uint8_t)ctx->keyUpdateType; + + /* If the cache length is less than the length of keyUpdateValue, return an error code. */ + if (bufLen < 1) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15854, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of keyUpdate message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + buf[0] = keyUpdateValue; + *usedLen = 1; + + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_msg.h b/tls/handshake/pack/src/pack_msg.h new file mode 100644 index 00000000..0fbc5092 --- /dev/null +++ b/tls/handshake/pack/src/pack_msg.h @@ -0,0 +1,206 @@ +/* + * 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 PACK_MSG_H +#define PACK_MSG_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Pack ClientHello message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackClientHello(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack ServertHello message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackServerHello(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack Encrypted Extensions message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackEncryptedExtensions(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +/** + * @brief Pack Tls1.3 Certificate message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13PackCertificate(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +/** + * @brief Pack certificate message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackCertificate(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack CertificateRequest message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackCertificateRequest(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack Tls1.3 CertificateRequest message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13PackCertificateRequest(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +/** + * @brief Pack CertificateVerify message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackCertificateVerify(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack new session ticket message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackNewSessionTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack TLS1.3 new session ticket message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13PackNewSessionTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +/** + * @brief Pack ServerKeyExchange message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackServerKeyExchange(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack ClientKeyExchange message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackClientKeyExchange(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); + +/** + * @brief Pack Finished message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackFinished(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +/** + * @brief Pack KeyUpdate message + * + * @param ctx [IN] TLS context + * @param buf [OUT] Returned handshake message + * @param bufLen [IN] Buffer size + * @param usedLen [OUT] Returned message length + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t PackKeyUpdate(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen); +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PACK_MSG_H */ \ No newline at end of file diff --git a/tls/handshake/pack/src/pack_new_session_ticket.c b/tls/handshake/pack/src/pack_new_session_ticket.c new file mode 100644 index 00000000..51f58b4a --- /dev/null +++ b/tls/handshake/pack/src/pack_new_session_ticket.c @@ -0,0 +1,115 @@ +/* + * 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 + +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" + +int32_t PackNewSessionTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t offset = 0u; + + HS_Ctx *hsCtx = ctx->hsCtx; + + if (bufLen < (sizeof(uint32_t) + sizeof(uint16_t) + hsCtx->ticketSize)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16054, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of NewSessionTicket message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* hsCtx->ticket is the encrypted ticket content, which corresponds to the ticket field in the protocol */ + BSL_Uint32ToByte(hsCtx->ticketLifetimeHint, &buf[offset]); + offset += sizeof(uint32_t); + BSL_Uint16ToByte((uint16_t)hsCtx->ticketSize, &buf[offset]); + offset += sizeof(uint16_t); + + /* rfc5077 3.3. NewSessionTicket Handshake Message + If the server determines that it does not want to include a ticket after including the SessionTicket extension + in the ServerHello, it sends a zero-length ticket in the NewSessionTicket handshake message. */ + if (hsCtx->ticketSize != 0 && memcpy_s(&buf[offset], bufLen - offset, hsCtx->ticket, hsCtx->ticketSize) != EOK) { + (void)memset_s(hsCtx->ticket, hsCtx->ticketSize, 0, hsCtx->ticketSize); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy ticket fail when pack new session ticket msg.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + + *usedLen = offset + hsCtx->ticketSize; + + return HITLS_SUCCESS; +} + +int32_t Tls13PackNewSessionTicket(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint32_t ticketAgeAdd = 0u; + uint32_t offset = 0u; + + HS_Ctx *hsCtx = ctx->hsCtx; + + /* ticket_lifetime + ticket_age_add + ticket_nonce length part + ticket_nonce + ticket length part + ticketSize */ + if (bufLen < (sizeof(uint32_t) + sizeof(uint32_t) + + sizeof(uint8_t) + sizeof(hsCtx->nextTicketNonce) + + sizeof(uint16_t) + hsCtx->ticketSize)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16055, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Pack NewSessionTicket message failed: bufLen %u ticketSize %u.", bufLen, hsCtx->ticketSize, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + BSL_Uint32ToByte(hsCtx->ticketLifetimeHint, &buf[offset]); + offset += sizeof(uint32_t); + + ticketAgeAdd = hsCtx->ticketAgeAdd; + BSL_Uint32ToByte(ticketAgeAdd, &buf[offset]); + offset += sizeof(uint32_t); + + /* The TicketNonce length field occupies one byte and the length value is 8. */ + buf[offset] = sizeof(hsCtx->nextTicketNonce); + offset += sizeof(uint8_t); + + BSL_Uint64ToByte(hsCtx->nextTicketNonce, &buf[offset]); + offset += sizeof(hsCtx->nextTicketNonce); + + BSL_Uint16ToByte((uint16_t)hsCtx->ticketSize, &buf[offset]); + offset += sizeof(uint16_t); + + /* In TLS1.3, no empty new session ticket is sent + because we ensure that hsCtx->ticketSize is not empty at the invoking point. + Therefore, you do not need to check whether hsCtx->ticketSize is empty. */ + (void)memcpy_s(&buf[offset], bufLen - offset, hsCtx->ticket, hsCtx->ticketSize); + offset += hsCtx->ticketSize; + + /* extension is not supported currently, set the total extension length to 0 */ + /* total extension length */ + if (bufLen < (offset + sizeof(uint16_t))) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16049, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length of NewSessionTicket message is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + BSL_Uint16ToByte(0, &buf[offset]); + + *usedLen = offset + sizeof(uint16_t); + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_server_hello.c b/tls/handshake/pack/src/pack_server_hello.c new file mode 100644 index 00000000..55be44ea --- /dev/null +++ b/tls/handshake/pack/src/pack_server_hello.c @@ -0,0 +1,106 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_security.h" +#include "tls.h" +#include "security.h" +#include "hs_ctx.h" +#include "pack_common.h" +#include "pack_extensions.h" + +// Pack the mandatory content of the ServerHello message +static int32_t PackServerHelloMandatoryField(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + /* The bufLen must be able to pack at least the version number (2 bytes) + random number (32 bytes) + session ID + * (1 byte length field) + algorithm suite (2 bytes) + compression method (1 byte) */ + if (bufLen < (sizeof(uint16_t) + HS_RANDOM_SIZE + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t))) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15461, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack server hello mandatory field error, the bufLen(%u) is not enough.", bufLen, NULL, NULL, NULL); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t len = 0u; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + uint16_t negotiatedVersion = ctx->negotiatedInfo.version; + + uint16_t version = (negotiatedVersion == HITLS_VERSION_TLS13) ? HITLS_VERSION_TLS12 : negotiatedVersion; + ret = SECURITY_CfgCheck((HITLS_Config *)&ctx->config.tlsConfig, HITLS_SECURITY_SECOP_VERSION, 0, version, NULL); + if (ret != SECURITY_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSECURE_VERSION); + ctx->method.sendAlert((TLS_Ctx *)ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + return HITLS_PACK_UNSECURE_VERSION; + } + BSL_Uint16ToByte(version, &buf[offset]); // version number + offset += sizeof(uint16_t); + (void)memcpy_s(&buf[offset], bufLen - offset, ctx->hsCtx->serverRandom, HS_RANDOM_SIZE); // server random number + offset += HS_RANDOM_SIZE; + + len = 0u; + ret = PackSessionId(hsCtx->sessionId, hsCtx->sessionIdSize, &buf[offset], bufLen - offset, &len); + if (ret != HITLS_SUCCESS) { + (void)memset_s(hsCtx->sessionId, hsCtx->sessionIdSize, 0, hsCtx->sessionIdSize); + return ret; + } + offset += len; + + BSL_Uint16ToByte(ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite, &buf[offset]); // cipher suite + offset += sizeof(uint16_t); + + buf[offset] = 0; // Compression method, currently supports uncompression + offset += sizeof(uint8_t); + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the ServertHello message. +int32_t PackServerHello(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t offset = 0u; + uint32_t msgLen = 0u; + uint32_t exMsgLen = 0u; + + ret = PackServerHelloMandatoryField(ctx, buf, bufLen, &msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15863, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack server hello mandatory content fail.", 0, 0, 0, 0); + return ret; + } + offset += msgLen; + + exMsgLen = 0u; + ret = PackServerExtension(ctx, &buf[offset], bufLen - offset, &exMsgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15864, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack server hello extension content fail.", 0, 0, 0, 0); + return ret; + } + offset += exMsgLen; + + *usedLen = offset; + return HITLS_SUCCESS; +} diff --git a/tls/handshake/pack/src/pack_server_key_exchange.c b/tls/handshake/pack/src/pack_server_key_exchange.c new file mode 100644 index 00000000..4f55600d --- /dev/null +++ b/tls/handshake/pack/src/pack_server_key_exchange.c @@ -0,0 +1,488 @@ +/* + * 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 +#include "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "cipher_suite.h" +#include "crypt.h" +#include "cert.h" +#include "hs_ctx.h" +#include "hs_common.h" + + +/* Determine whether additional parameter signatures are required. */ +static bool IsNeedKeyExchParamSignature(const TLS_Ctx *ctx) +{ + /* Add the parameter signature only when the authentication algorithm is not HITLS_AUTH_NULL for the DHE and ECDHE + * cipher suites */ + return ((ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_ECDHE || + ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE) && + ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_NULL); +} + +static uint32_t GetNamedCurveMsgLen(TLS_Ctx *ctx, uint32_t pubKeyLen) +{ + HITLS_Config *config = &(ctx->config.tlsConfig); + + /* Message length = Curve type (1 byte) + Curve ID (2 byte) + Public key length (1 byte) + Public key + Signature + * length (2 byte) + Signature */ + uint32_t dataLen = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t) + pubKeyLen; + + /* ECDHE_PSK key exchange does not require signature */ + if (IsNeedKeyExchParamSignature(ctx)) { + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(config->certMgrCtx, false); + uint32_t signatureLen = SAL_CERT_GetSignMaxLen(config, privateKey); + if ((signatureLen == 0u) || (signatureLen > MAX_SIGN_SIZE)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15499, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack ske error: invalid signature length = %u.", signatureLen, 0, 0, 0); + return 0; + } + + dataLen += sizeof(uint16_t) + signatureLen; + /* A signature type needs to be added to TLS1.2/DTLS. The signature type does not need to be transferred */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS12 || ctx->negotiatedInfo.version == HITLS_VERSION_DTLS12) { + dataLen += sizeof(uint16_t); + } + } + + return dataLen; +} + +static int32_t SignKeyExchParams(TLS_Ctx *ctx, uint8_t *kxData, uint32_t kxDataLen, uint8_t *signBuf, uint32_t *signLen) +{ + uint32_t offset = 0u; + HITLS_SignHashAlgo signScheme = ctx->negotiatedInfo.signScheme; + HITLS_SignAlgo signAlgo; + HITLS_HashAlgo hashAlgo; + if (CFG_GetSignParamBySchemes(ctx->negotiatedInfo.version, signScheme, &signAlgo, &hashAlgo) != true) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15496, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sign parm fail.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + + uint32_t dataLen; + /* Obtain all signature data (random number + server kx content) */ + uint8_t *data = HS_PrepareSignData(ctx, kxData, kxDataLen, &dataLen); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15495, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "prepare unsigned data fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + /* TLS1.2 and later versions require explicit hash and signature algorithms to be specified in messages, and + * TLCP are not written */ + BSL_Uint16ToByte(signScheme, signBuf); + offset += sizeof(uint16_t); + } + + /* Temporarily record the position of the signature length in the message and fill it later */ + uint32_t signLenOffset = offset; + offset += sizeof(uint16_t); + + /* Fill signature parameters */ + CERT_SignParam signParam = {0}; + signParam.signAlgo = signAlgo; + signParam.hashAlgo = hashAlgo; + signParam.data = data; + signParam.dataLen = dataLen; + signParam.sign = &signBuf[offset]; + signParam.signLen = (uint16_t)(*signLen - offset); + /* Fill signature */ + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(ctx->config.tlsConfig.certMgrCtx, false); + int32_t ret = SAL_CERT_CreateSign(ctx, privateKey, &signParam); + BSL_SAL_FREE(data); + if ((ret != HITLS_SUCCESS) || (offset + signParam.signLen > *signLen)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15497, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "create signature fail.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + offset += signParam.signLen; + BSL_Uint16ToByte((uint16_t)signParam.signLen, &signBuf[signLenOffset]); + *signLen = offset; + + return HITLS_SUCCESS; +} + +static int32_t PackServerKxMsgNamedCurve(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + HITLS_ECParameters *ecParam = &(kxCtx->keyExchParam.ecdh.curveParams); + uint32_t pubKeyLen = HS_GetNamedCurvePubkeyLen(ecParam->param.namedcurve); + if (pubKeyLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15498, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack ske error: unsupport named curve = %u.", ecParam->param.namedcurve, 0, 0, 0); + return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH; + } + uint32_t dataLen = GetNamedCurveMsgLen(ctx, pubKeyLen); + if (dataLen == 0) { + return HITLS_PACK_SIGNATURE_ERR; + } + + /* If the length of bufLen does not meet the requirements, return an error code. */ + if (bufLen < dataLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15500, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Curve type and curve ID. Although these parameters are ignored in the TLCP, they are + * filled in to ensure the uniform style. However, the client cannot depend on the value of this parameter */ + buf[0] = (uint8_t)(ecParam->type); + uint32_t offset = sizeof(uint8_t); + BSL_Uint16ToByte((uint16_t)(ecParam->param.namedcurve), &buf[offset]); + offset += sizeof(uint16_t); + + /* Public key length and public key content */ + uint32_t pubKeyLenOffset = offset; // indicates the offset of pubkeyLen. + offset += sizeof(uint8_t); + uint32_t pubKeyUsedLen = 0; + int32_t ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->key, &buf[offset], pubKeyLen, &pubKeyUsedLen); + if (ret != HITLS_SUCCESS || pubKeyLen != pubKeyUsedLen) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15501, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode ecdh key fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + offset += pubKeyUsedLen; + buf[pubKeyLenOffset] = (uint8_t)pubKeyUsedLen; // Fill pubkeyLen + + if (IsNeedKeyExchParamSignature(ctx)) { + uint32_t signatureLen = dataLen - offset; + ret = SignKeyExchParams(ctx, &buf[0], offset, &buf[offset], &signatureLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15502, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signature fail.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + offset += signatureLen; + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerKxMsgEcdhe(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + HITLS_ECCurveType type = ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type; + switch (type) { + case HITLS_EC_CURVE_TYPE_NAMED_CURVE: + return PackServerKxMsgNamedCurve(ctx, buf, bufLen, usedLen); + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15503, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unsupport key exchange curve type.", 0, 0, 0, 0); + return HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE; +} + +#ifndef HITLS_NO_TLCP11 +/* This function is invoked only by the TLCP */ +static int32_t PackServerKxMsgEcc(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint8_t *data = NULL; + uint32_t offset = 0u; + uint32_t dataLen, certLen; + + uint8_t *encCert = SAL_CERT_SrvrGmEncodeEncCert(ctx, &certLen); + if (encCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_CERT_ERR_ENCODE; + } + /* Obtain all signature data (random number + server kx content) */ + data = HS_PrepareSignDataTlcp(ctx, encCert, certLen, &dataLen); + BSL_SAL_FREE(encCert); + if (data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15913, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "prepare unsigned data fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + HITLS_SignAlgo signAlgo; + HITLS_HashAlgo hashAlgo; + if (!CFG_GetSignParamBySchemes(ctx->negotiatedInfo.version, ctx->negotiatedInfo.signScheme, &signAlgo, &hashAlgo)) { + BSL_SAL_FREE(data); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15914, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sign parm fail.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + /* The hash and signature algorithms do not need to be explicitly specified in messages by TLCP. The hash algorithm + * obtained based on signScheme is used. */ + uint32_t signLenOffset = offset; /* The records the position of the signature length in the message temporarily, and + then fills the signature length in the message later */ + offset += sizeof(uint16_t); + + /* Fill signature parameters */ + CERT_SignParam signParam = {0}; + signParam.signAlgo = signAlgo; + signParam.hashAlgo = hashAlgo; + signParam.data = data; + signParam.dataLen = dataLen; + signParam.sign = &buf[offset]; + signParam.signLen = (uint16_t)(bufLen - offset); + /* Fill the signature */ + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(ctx->config.tlsConfig.certMgrCtx, false); + int32_t ret = SAL_CERT_CreateSign(ctx, privateKey, &signParam); + if ((ret != HITLS_SUCCESS) || (offset + signParam.signLen > bufLen)) { + BSL_SAL_FREE(data); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15916, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "create sm2 signature fail.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + offset += signParam.signLen; + BSL_Uint16ToByte((uint16_t)signParam.signLen, &buf[signLenOffset]); + *usedLen = offset; + + BSL_SAL_FREE(data); + return HITLS_SUCCESS; +} +#endif + +static int32_t PackKxPrimaryData(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + DhParam *dh = &ctx->hsCtx->kxCtx->keyExchParam.dh; + uint32_t pubkeyLen = dh->plen; + uint16_t plen = dh->plen; + uint16_t glen = dh->glen; + uint32_t bufOffset = 0; + BSL_Uint16ToByte(plen, &buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + int32_t ret; + ret = memcpy_s(&buf[bufOffset], bufLen - bufOffset, dh->p, plen); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15504, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack param p.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + bufOffset += plen; + + BSL_Uint16ToByte(glen, &buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + ret = memcpy_s(&buf[bufOffset], bufLen - bufOffset, dh->g, glen); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15505, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack param g.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + bufOffset += glen; + + uint32_t pubKeyLenOffset = bufOffset; // indicates the offset of pubkeyLen + bufOffset += sizeof(uint16_t); + + ret = SAL_CRYPT_EncodeDhPubKey(kxCtx->key, &buf[bufOffset], pubkeyLen, &pubkeyLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_DH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15506, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode dhe key fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_DH_KEY; + } + bufOffset += pubkeyLen; + BSL_Uint16ToByte((uint16_t)pubkeyLen, &buf[pubKeyLenOffset]); + + *usedLen = bufOffset; + return HITLS_SUCCESS; +} + +static int32_t PackServerKxMsgDhePre(TLS_Ctx *ctx, uint32_t *signatureLen) +{ + if (IsNeedKeyExchParamSignature(ctx)) { + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(ctx->config.tlsConfig.certMgrCtx, false); + *signatureLen = SAL_CERT_GetSignMaxLen(&(ctx->config.tlsConfig), privateKey); + if ((*signatureLen == 0u) || (*signatureLen > MAX_SIGN_SIZE)) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15508, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid signature length.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + } + return HITLS_SUCCESS; +} + +static int32_t PackServerKxMsgDhe(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + DhParam *dh = &ctx->hsCtx->kxCtx->keyExchParam.dh; + uint32_t pubkeyLen = dh->plen; + uint16_t plen = dh->plen; + uint16_t glen = dh->glen; + + if (pubkeyLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15507, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid key exchange pubKey length.", 0, 0, 0, 0); + return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH; + } + + /* DHE_PSK and ANON_DH do not need signatures */ + uint32_t signatureLen = 0; + int32_t ret = PackServerKxMsgDhePre(ctx, &signatureLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t dataLen = sizeof(uint16_t) + plen + sizeof(uint16_t) + glen + sizeof(uint16_t) + pubkeyLen; + if (IsNeedKeyExchParamSignature(ctx)) { + dataLen += (sizeof(uint16_t) + signatureLen); + } + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS12 || ctx->negotiatedInfo.version == HITLS_VERSION_DTLS12) { + dataLen += sizeof(uint16_t); // TLS1.2/DTLS needs to add a signature type + } + + if (bufLen < dataLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15509, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* Fill the following values in sequence: plen, p, glen, g, pubkeylen, pubkey, signature len, and signature */ + uint32_t offset = 0u; + ret = PackKxPrimaryData(ctx, buf, bufLen, &offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (IsNeedKeyExchParamSignature(ctx)) { + uint32_t signLen = dataLen - offset; + ret = SignKeyExchParams(ctx, &buf[0], offset, &buf[offset], &signLen); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15510, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "kx msg signature fail.", 0, 0, 0, 0); + return HITLS_PACK_SIGNATURE_ERR; + } + offset += signLen; + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +static int32_t PackServerKxMsgPskIdentityHint(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + uint8_t *pskIdentityHint = ctx->config.tlsConfig.pskIdentityHint; + /* The length of hintSize <= HITLS_IDENTITY_HINT_MAX_SIZE is ensured during configuration. Therefore, the length of + * uint16_t can be forcibly converted to the length of uint16_t */ + uint16_t pskIdentityHintSize = (uint16_t)ctx->config.tlsConfig.hintSize; + uint32_t dataLen; + int32_t ret; + + dataLen = sizeof(uint16_t) + pskIdentityHintSize; + + if (bufLen < dataLen) { + BSL_ERR_PUSH_ERROR(HITLS_PACK_NOT_ENOUGH_BUF_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15511, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the buffer length is not enough.", 0, 0, 0, 0); + return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH; + } + + /* append identity hint */ + /* for dhe_psk, ecdhe_psk, msg must contain the length of hint even if there is no hint to provide */ + uint32_t offset = 0u; + BSL_Uint16ToByte(pskIdentityHintSize, &buf[offset]); + offset += sizeof(uint16_t); + + if (pskIdentityHint != NULL) { + ret = memcpy_s(&buf[offset], bufLen - offset, pskIdentityHint, pskIdentityHintSize); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15512, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "memcpy fail when pack psk identity hint.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + offset += pskIdentityHintSize; + } + + *usedLen = offset; + return HITLS_SUCCESS; +} + +// Pack the ServerKeyExchange message. +int32_t PackServerKeyExchange(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen) +{ + int32_t ret; + uint32_t len = 0u; + uint32_t offset = 0u; + + /* pack psk identity hint before dynamic key */ + if (IsPskNegotiation(ctx)) { + ret = PackServerKxMsgPskIdentityHint(ctx, buf, bufLen, &len); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + } + + /* Pack a key exchange message */ + len = 0u; + switch (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg) { + case HITLS_KEY_EXCH_ECDHE: + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = PackServerKxMsgEcdhe(ctx, &buf[offset], bufLen - offset, &len); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = PackServerKxMsgDhe(ctx, &buf[offset], bufLen - offset, &len); + break; + case HITLS_KEY_EXCH_RSA_PSK: + case HITLS_KEY_EXCH_PSK: + /* for psk and rsa_psk nego, ServerKeyExchange msg contains only identity hint */ + ret = HITLS_SUCCESS; + break; +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: + ret = PackServerKxMsgEcc(ctx, &buf[offset], bufLen - offset, &len); + break; +#endif + default: + BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_KX_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15513, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unsupport key exchange algorithm when pack server key exchange msg.", 0, 0, 0, 0); + return HITLS_PACK_UNSUPPORT_KX_ALG; + } + + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += len; + + *usedLen = offset; + return HITLS_SUCCESS; +} + diff --git a/tls/handshake/parse/include/parse.h b/tls/handshake/parse/include/parse.h new file mode 100644 index 00000000..7c70e37c --- /dev/null +++ b/tls/handshake/parse/include/parse.h @@ -0,0 +1,76 @@ +/* + * 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 PARSE_H +#define PARSE_H + +#include "hs_msg.h" +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Parse handshake message header + * + * @param ctx [IN] TLS context + * @param data [IN] Handshake message + * @param len [IN] Message length + * @param hsMsgInfo [OUT] Parsed handshake message header + * + * @return HITLS_SUCCESS + * For other error codes, see hitls_error.h + */ +int32_t HS_ParseMsgHeader(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_MsgInfo *hsMsgInfo); + +/** + * @brief Parse the whole handshake message + * Used in pairs with HS_CleanMsg. After parsing, the data needs to be cleaned. + * + * @param ctx [IN] TLS context + * @param hsMsgInfo [IN] Handshake message + * @param hsMsg [OUT] Parsed complete handshake message + * + * @return HITLS_SUCCESS + * For other error codes, see hitls_error.h + */ +int32_t HS_ParseMsg(TLS_Ctx *ctx, const HS_MsgInfo *hsMsgInfo, HS_Msg *hsMsg); + +/** + * @brief Clean handshake messages + * Used in pairs with HS_ParseMsg to release the memory allocated in hsMsg + * + * @param hsMsg [IN] Handshake message + */ +void HS_CleanMsg(HS_Msg *hsMsg); + + +/** + * @brief Check whether the type of the handshake message is expected + * + * @param ctx [IN] TLS context + * @param msgType [IN] Handshake message type + * + * @return HITLS_SUCCESS + * For other error codes, see hitls_error.h + */ +int32_t CheckHsMsgType(TLS_Ctx *ctx, HS_MsgType msgType); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PARSE_H */ diff --git a/tls/handshake/parse/src/parse.c b/tls/handshake/parse/src/parse.c new file mode 100644 index 00000000..dae65ab0 --- /dev/null +++ b/tls/handshake/parse/src/parse.c @@ -0,0 +1,462 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "tls.h" +#include "hs.h" +#include "hs_common.h" +#include "parse_msg.h" +#include "indicator.h" + +#define TLS_PLAINTEXT_EXPANSION 2048u +#define TLS13_PLAINTEXT_EXPANSION 256u +typedef int32_t (*CheckHsMsgTypeFunc)(TLS_Ctx *ctx, const HS_MsgType msgType); + +typedef struct { + HS_MsgType msgType; + CheckHsMsgTypeFunc checkCb; +} HsMsgTypeCheck; + +static int32_t CheckServerKeyExchangeType(TLS_Ctx *ctx, const HS_MsgType msgType) +{ + /* When the PSK and RSA_PSK are used, whether the ServerKeyExchange message is received depends on whether the + * server sends a PSK identity hint */ + if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_PSK || + ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_RSA_PSK) { + if (msgType == CERTIFICATE_REQUEST) { + HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST); + return HITLS_SUCCESS; + } else if (msgType == SERVER_HELLO_DONE) { + HS_ChangeState(ctx, TRY_RECV_SERVER_HELLO_DONE); + return HITLS_SUCCESS; + } + } + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; +} + +static int32_t CheckCertificateRequestType(TLS_Ctx *ctx, const HS_MsgType msgType) +{ + uint32_t version = HS_GetVersion(ctx); + if (version == HITLS_VERSION_TLS13) { + if (msgType == CERTIFICATE) { + HS_ChangeState(ctx, TRY_RECV_CERTIFICATE); + return HITLS_SUCCESS; + } + } else { + if (msgType == SERVER_HELLO_DONE) { + HS_ChangeState(ctx, TRY_RECV_SERVER_HELLO_DONE); + return HITLS_SUCCESS; + } + } + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; +} + +static const HsMsgTypeCheck g_checkHsMsgTypeList[] = { + [TRY_RECV_CLIENT_HELLO] = {.msgType = CLIENT_HELLO, + .checkCb = NULL}, + [TRY_RECV_SERVER_HELLO] = {.msgType = SERVER_HELLO, + .checkCb = NULL}, + [TRY_RECV_ENCRYPTED_EXTENSIONS] = {.msgType = ENCRYPTED_EXTENSIONS, + .checkCb = NULL}, + [TRY_RECV_CERTIFICATE] = {.msgType = CERTIFICATE, + .checkCb = NULL}, + [TRY_RECV_SERVER_KEY_EXCHANGE] = {.msgType = SERVER_KEY_EXCHANGE, + .checkCb = CheckServerKeyExchangeType}, + [TRY_RECV_CERTIFICATE_REQUEST] = {.msgType = CERTIFICATE_REQUEST, + .checkCb = CheckCertificateRequestType}, + [TRY_RECV_SERVER_HELLO_DONE] = {.msgType = SERVER_HELLO_DONE, + .checkCb = NULL}, + [TRY_RECV_CLIENT_KEY_EXCHANGE] = {.msgType = CLIENT_KEY_EXCHANGE, + .checkCb = NULL}, + [TRY_RECV_CERTIFICATE_VERIFY] = {.msgType = CERTIFICATE_VERIFY, + .checkCb = NULL}, + [TRY_RECV_NEW_SESSION_TICKET] = {.msgType = NEW_SESSION_TICKET, + .checkCb = NULL}, + [TRY_RECV_FINISH] = {.msgType = FINISHED, + .checkCb = NULL}, +}; + +int32_t CheckHsMsgType(TLS_Ctx *ctx, HS_MsgType msgType) +{ + if (ctx->state != CM_STATE_HANDSHAKING && ctx->state != CM_STATE_RENEGOTIATION) { + return HITLS_SUCCESS; + } + + if ((msgType == HELLO_REQUEST) && (ctx->isClient)) { + /* The HelloRequest message may appear at any time during the handshake. + The client should ignore this message */ + return HITLS_SUCCESS; + } + + HS_Ctx *hsCtx = ctx->hsCtx; + const char *expectedMsg = NULL; + if (msgType != g_checkHsMsgTypeList[hsCtx->state].msgType) { + if (g_checkHsMsgTypeList[hsCtx->state].checkCb == NULL || + g_checkHsMsgTypeList[hsCtx->state].checkCb(ctx, msgType) != HITLS_SUCCESS) { + expectedMsg = HS_GetMsgTypeStr(g_checkHsMsgTypeList[hsCtx->state].msgType); + } + } + + if (msgType == FINISHED && HS_GetVersion(ctx) != HITLS_VERSION_TLS13) { + bool isCcsRecv = ctx->method.isRecvCCS(ctx); + if (isCcsRecv != true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15349, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state expect finished, but recv ccs state(%d)", (int32_t)isCcsRecv, 0, 0, 0); + expectedMsg = HS_GetMsgTypeStr(FINISHED); + } + } + + if (expectedMsg != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15571, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state expect %s", expectedMsg); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15572, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + ", but got %s.", HS_GetMsgTypeStr(msgType)); + + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + } + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_DTLS12 +static int32_t DtlsParseHsMsgHeader(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_MsgInfo *hsMsgInfo) +{ + if (len < DTLS_HS_MSG_HEADER_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15599, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "DTLS handshake msg length error when parse msg header.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + hsMsgInfo->type = data[0]; /* The 0 byte is the handshake message type */ + if (hsMsgInfo->type >= HS_MSG_TYPE_END) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15936, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "DTLS invalid message type: %d.", hsMsgInfo->type, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG; + } + hsMsgInfo->length = BSL_ByteToUint24(&data[DTLS_HS_MSGLEN_ADDR]); + hsMsgInfo->sequence = BSL_ByteToUint16(&data[DTLS_HS_MSGSEQ_ADDR]); + hsMsgInfo->fragmentOffset = BSL_ByteToUint24(&data[DTLS_HS_FRAGMENT_OFFSET_ADDR]); + hsMsgInfo->fragmentLength = BSL_ByteToUint24(&data[DTLS_HS_FRAGMENT_LEN_ADDR]); + hsMsgInfo->rawMsg = data; + hsMsgInfo->isHsMsgComplete = true; + + if (((hsMsgInfo->fragmentLength + DTLS_HS_MSG_HEADER_SIZE) != len) || + ((hsMsgInfo->fragmentLength + hsMsgInfo->fragmentOffset) > hsMsgInfo->length) || + ((hsMsgInfo->length != 0) && (hsMsgInfo->fragmentLength == 0))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15600, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "DTLS handshake msg length error, need to alert.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t maxMsgLen = HS_MaxMessageSize(ctx, hsMsgInfo->type); + if (hsMsgInfo->length > maxMsgLen) { + BSL_ERR_PUSH_ERROR(HTILS_PARSE_EXCESSIVE_MESSAGE_SIZE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15937, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "DTLS handshake msg parsed length: %u, max length: %u.", hsMsgInfo->length, maxMsgLen, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HTILS_PARSE_EXCESSIVE_MESSAGE_SIZE; + } + hsMsgInfo->headerAndBodyLen = hsMsgInfo->length + DTLS_HS_MSG_HEADER_SIZE; + + if (hsMsgInfo->type == HELLO_REQUEST && hsMsgInfo->length == 0) { + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, data, DTLS_HS_MSG_HEADER_SIZE, + ctx, ctx->config.tlsConfig.msgArg); + } + + return HITLS_SUCCESS; +} +#endif + +static int32_t CheckHsMsgLen(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_MsgInfo *hsMsgInfo) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t hsMsgOfSpecificTypeMaxSize = HS_MaxMessageSize(ctx, hsMsgInfo->type); + if (hsMsgInfo->length > hsMsgOfSpecificTypeMaxSize) { + BSL_ERR_PUSH_ERROR(HTILS_PARSE_EXCESSIVE_MESSAGE_SIZE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15800, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLS HS msg type: %d, parsed length: %u, max length: %u.", (int)hsMsgInfo->type, hsMsgInfo->length, + hsMsgOfSpecificTypeMaxSize, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HTILS_PARSE_EXCESSIVE_MESSAGE_SIZE; + } + uint32_t hsPlaintextLen = HS_MSG_HEADER_SIZE + hsMsgInfo->length; + uint32_t expansionLen = + (HS_GetVersion(ctx) == HITLS_VERSION_TLS13) ? TLS13_PLAINTEXT_EXPANSION : TLS_PLAINTEXT_EXPANSION; + if (hsPlaintextLen > REC_MAX_PLAIN_LENGTH) { + // If this branch is entered, the hsCtx is guaranteed to exist + hsMsgInfo->isHsMsgComplete = false; + uint32_t cpyLen = (len < ctx->hsCtx->bufferLen) ? len : ctx->hsCtx->bufferLen; + if (data != ctx->hsCtx->msgBuf) { + (void)memcpy_s(ctx->hsCtx->msgBuf, ctx->hsCtx->bufferLen, data, cpyLen); + } + ret = HS_GrowMsgBuf(ctx, hsPlaintextLen + expansionLen, hsPlaintextLen + expansionLen, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + hsMsgInfo->rawMsg = ctx->hsCtx->msgBuf; + } + hsMsgInfo->headerAndBodyLen = hsPlaintextLen; + + if (hsMsgInfo->type == HELLO_REQUEST && hsMsgInfo->length == 0) { + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsMsgInfo->rawMsg, + HS_MSG_HEADER_SIZE, ctx, ctx->config.tlsConfig.msgArg); + } + + return ret; +} + +static int32_t TlsParseHsMsgHeader(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_MsgInfo *hsMsgInfo) +{ + if (len < HS_MSG_HEADER_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15601, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLS decode error: msg len = %u.", len, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + hsMsgInfo->type = data[0]; + + if (hsMsgInfo->type >= HS_MSG_TYPE_END) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15801, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLS invalid message type: %d.", hsMsgInfo->type, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG; + } + + int32_t ret = CheckHsMsgType(ctx, hsMsgInfo->type); + if (ret != HITLS_SUCCESS) { + return ret; + } + + hsMsgInfo->length = BSL_ByteToUint24(data + sizeof(uint8_t)); /* Parse handshake body length */ + hsMsgInfo->sequence = 0; /* TLS does not have this field */ + hsMsgInfo->fragmentOffset = 0; /* TLS does not have this field */ + hsMsgInfo->fragmentLength = 0; /* TLS does not have this field */ + hsMsgInfo->rawMsg = data; + hsMsgInfo->isHsMsgComplete = true; + + return CheckHsMsgLen(ctx, data, len, hsMsgInfo); +} + +static int32_t ParseHandShakeMsg(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg) +{ + switch (hsMsg->type) { + case CLIENT_HELLO: + return ParseClientHello(ctx, data, len, hsMsg); + case SERVER_HELLO: + return ParseServerHello(ctx, data, len, hsMsg); + case CERTIFICATE: + return ParseCertificate(ctx, data, len, hsMsg); + case SERVER_KEY_EXCHANGE: + return ParseServerKeyExchange(ctx, data, len, hsMsg); + case CERTIFICATE_REQUEST: + return ParseCertificateRequest(ctx, data, len, hsMsg); + case CLIENT_KEY_EXCHANGE: + return ParseClientKeyExchange(ctx, data, len, hsMsg); + case CERTIFICATE_VERIFY: + return ParseCertificateVerify(ctx, data, len, hsMsg); + case NEW_SESSION_TICKET: + return ParseNewSessionTicket(ctx, data, len, hsMsg); + case FINISHED: + return ParseFinished(ctx, data, len, hsMsg); + case HELLO_REQUEST: + case SERVER_HELLO_DONE: + if (len != 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15603, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg %s", HS_GetMsgTypeStr(hsMsg->type)); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15611, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg length = %u", len, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15604, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dtls parse handshake msg error, unsupport type[%d].", hsMsg->type, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG; +} + +int32_t Tls13ParseHandShakeMsg(TLS_Ctx *ctx, const uint8_t *hsBodyData, uint32_t hsBodyLen, HS_Msg *hsMsg) +{ + switch (hsMsg->type) { + case CLIENT_HELLO: + return ParseClientHello(ctx, hsBodyData, hsBodyLen, hsMsg); + case SERVER_HELLO: + return ParseServerHello(ctx, hsBodyData, hsBodyLen, hsMsg); + case ENCRYPTED_EXTENSIONS: + return ParseEncryptedExtensions(ctx, hsBodyData, hsBodyLen, hsMsg); + case CERTIFICATE: + return Tls13ParseCertificate(ctx, hsBodyData, hsBodyLen, hsMsg); + case CERTIFICATE_REQUEST: + return Tls13ParseCertificateRequest(ctx, hsBodyData, hsBodyLen, hsMsg); + case CERTIFICATE_VERIFY: + return ParseCertificateVerify(ctx, hsBodyData, hsBodyLen, hsMsg); + case FINISHED: + return ParseFinished(ctx, hsBodyData, hsBodyLen, hsMsg); + case KEY_UPDATE: + return ParseKeyUpdate(ctx, hsBodyData, hsBodyLen, hsMsg); + case NEW_SESSION_TICKET: + return ParseNewSessionTicket(ctx, hsBodyData, hsBodyLen, hsMsg); + case HELLO_REQUEST: + if (hsBodyLen != 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15611, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hello request length is not zero.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15605, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse TLS1.3 handshake msg error, unsupport type[%d].", hsMsg->type, 0, 0, 0); + return HITLS_PARSE_UNSUPPORT_HANDSHAKE_MSG; +} + +int32_t HS_ParseMsgHeader(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_MsgInfo *hsMsgInfo) +{ + if ((ctx == NULL) || (ctx->method.sendAlert == NULL) || (data == NULL) || (hsMsgInfo == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15606, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the input parameter pointer is null.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t version = HS_GetVersion(ctx); + + switch (version) { + case HITLS_VERSION_TLS12: + case HITLS_VERSION_TLS13: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + return TlsParseHsMsgHeader(ctx, data, len, hsMsgInfo); +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + return DtlsParseHsMsgHeader(ctx, data, len, hsMsgInfo); +#endif + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15607, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse msg header error, unsupport version[0x%x].", version, 0, 0, 0); + return HITLS_PARSE_UNSUPPORT_VERSION; +} + +int32_t HS_ParseMsg(TLS_Ctx *ctx, const HS_MsgInfo *hsMsgInfo, HS_Msg *hsMsg) +{ + if ((ctx == NULL) || (ctx->method.sendAlert == NULL) || (hsMsgInfo == NULL) || (hsMsgInfo->rawMsg == NULL) || + (hsMsg == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15608, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the input parameter pointer is null.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + hsMsg->type = hsMsgInfo->type; + hsMsg->length = hsMsgInfo->length; + hsMsg->sequence = hsMsgInfo->sequence; + hsMsg->fragmentOffset = hsMsgInfo->fragmentOffset; + hsMsg->fragmentLength = hsMsgInfo->fragmentLength; + + uint32_t version = HS_GetVersion(ctx); + + switch (version) { + case HITLS_VERSION_TLS12: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + return ParseHandShakeMsg(ctx, &hsMsgInfo->rawMsg[HS_MSG_HEADER_SIZE], hsMsgInfo->length, hsMsg); + case HITLS_VERSION_TLS13: + return Tls13ParseHandShakeMsg(ctx, &hsMsgInfo->rawMsg[HS_MSG_HEADER_SIZE], hsMsgInfo->length, hsMsg); +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + return ParseHandShakeMsg(ctx, &hsMsgInfo->rawMsg[DTLS_HS_MSG_HEADER_SIZE], hsMsgInfo->length, hsMsg); +#endif + default: + break; + } + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15609, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse handshake msg error, unsupport version[0x%x].", version, 0, 0, 0); + return HITLS_PARSE_UNSUPPORT_VERSION; +} + +void HS_CleanMsg(HS_Msg *hsMsg) +{ + if (hsMsg == NULL) { + return; + } + + switch (hsMsg->type) { + case CLIENT_HELLO: + return CleanClientHello(&hsMsg->body.clientHello); + case SERVER_HELLO: + return CleanServerHello(&hsMsg->body.serverHello); + case ENCRYPTED_EXTENSIONS: + return CleanEncryptedExtensions(&hsMsg->body.encryptedExtensions); + case CERTIFICATE: + return CleanCertificate(&hsMsg->body.certificate); + case SERVER_KEY_EXCHANGE: + return CleanServerKeyExchange(&hsMsg->body.serverKeyExchange); + case CERTIFICATE_REQUEST: + return CleanCertificateRequest(&hsMsg->body.certificateReq); + case CLIENT_KEY_EXCHANGE: + return CleanClientKeyExchange(&hsMsg->body.clientKeyExchange); + case CERTIFICATE_VERIFY: + return CleanCertificateVerify(&hsMsg->body.certificateVerify); + case NEW_SESSION_TICKET: + return CleanNewSessionTicket(&hsMsg->body.newSessionTicket); + case FINISHED: + return CleanFinished(&hsMsg->body.finished); + case KEY_UPDATE: + case HELLO_REQUEST: + case SERVER_HELLO_DONE: + return; + default: + break; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15610, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "clean handshake msg error, unsupport type[%d].", hsMsg->type, 0, 0, 0); + return; +} diff --git a/tls/handshake/parse/src/parse_certificate.c b/tls/handshake/parse/src/parse_certificate.c new file mode 100644 index 00000000..4111a7b5 --- /dev/null +++ b/tls/handshake/parse/src/parse_certificate.c @@ -0,0 +1,326 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "parse_msg.h" + +/** + * @brief Parse the certificate signature + * + * @param ctx [IN] TLS context + * @param buf [IN] message to be parsed + * @param bufLen [IN] buffer length + * @param readLen [OUT] Parsed length + * + * @return Return the memory of the applied certificate. If NULL is returned, the parsing fails. + */ +CERT_Item *ParseSingleCert(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint32_t *readLen) +{ + if (bufLen <= CERT_LEN_TAG_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15586, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Parse cert data error: data len= %u, less than 3.", bufLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + uint32_t bufOffset = 0; + uint32_t certLen = BSL_ByteToUint24(buf); /* Obtain the certificate length */ + bufOffset += CERT_LEN_TAG_SIZE; + + if ((certLen == 0) || (certLen > (bufLen - bufOffset))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15587, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Parse cert data error: data len= %u, cert len= %u.", bufLen, certLen, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + /* Allocate memory for certificate messages */ + CERT_Item *item = (CERT_Item*)BSL_SAL_Calloc(1u, sizeof(CERT_Item)); + if (item == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15588, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CERT_Item malloc fail when parse certificate msg.", 0, 0, 0, 0); + return NULL; + } + item->next = NULL; + item->dataSize = certLen; /* Update the length of the certificate message */ + + /* Extract the contents of the certificate message */ + item->data = BSL_SAL_Malloc(item->dataSize); + if (item->data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15589, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "item->data malloc fail when parse certificate msg.", 0, 0, 0, 0); + BSL_SAL_FREE(item); + return NULL; + } + (void)memcpy_s(item->data, item->dataSize, &buf[bufOffset], item->dataSize); + bufOffset += certLen; + + /* Update certificate message parameters */ + *readLen = bufOffset; + + return item; +} + +static int32_t ParseCertExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint32_t *readLen) +{ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + *readLen = 0; + return HITLS_SUCCESS; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15590, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of certificate extension is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t offset = 0; + uint16_t certExLen = BSL_ByteToUint16(&buf[offset]); + offset += sizeof(uint16_t) + certExLen; // Skip extensions + + *readLen = offset; + return HITLS_SUCCESS; +} + +// Parse the certificate content +int32_t ParseCerts(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg, uint32_t *offset) +{ + int32_t ret; + CertificateMsg *msg = &hsMsg->body.certificate; + CERT_Item *cur = msg->cert; + uint32_t tmpOffset = *offset; + + /* Parse the certificate message and save the certificate chain to the structure */ + while (tmpOffset < bufLen) { + uint32_t readLen = 0u; + + CERT_Item *item = NULL; + item = ParseSingleCert(ctx, &buf[tmpOffset], bufLen - tmpOffset, &readLen); + if (item == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_CERT_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15591, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse certificate item fail.", 0, 0, 0, 0); + return HITLS_PARSE_CERT_ERR; + } + + /* Add the parsed certificate to the last node in the linked list */ + if (msg->cert == NULL) { + msg->cert = item; + } else { + cur->next = item; + } + cur = item; + tmpOffset += readLen; + + ret = ParseCertExtension(ctx, &buf[tmpOffset], bufLen - tmpOffset, &readLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15592, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse certificate extension fail.", 0, 0, 0, 0); + return ret; + } + tmpOffset += readLen; + + msg->certCount++; + } + *offset = tmpOffset; + + return HITLS_SUCCESS; +} + +/** +* @brief Parse the certificate message. +* +* @param ctx [IN] TLS context +* @param buf [IN] message buffer +* @param bufLen [IN] Maximum message length +* @param hsMsg [OUT] message structure +* +* @retval HITLS_SUCCESS parsed successfully. +* @retval HITLS_PARSE_CERT_ERR Failed to parse the certificate. +* @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseCertificate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + /* The total length of the certificate can be parsed at least 3 bytes */ + if (bufLen < CERT_LEN_TAG_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15593, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message (certificate) is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + int32_t ret; + uint32_t offset = 0; + + /* Obtain the lengths of all certificates */ + uint32_t allCertsLen = BSL_ByteToUint24(buf); + if (allCertsLen != (bufLen - CERT_LEN_TAG_SIZE)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15594, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of all certificates is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /** + * The client can send a certificate message without a certificate, so if the total length of the certificate is 0, + * it directly returns success; If the client receives a certificate message of length 0, it is determined by the + * processing layer, which is only responsible for parsing + */ + if (allCertsLen == 0) { + return HITLS_SUCCESS; + } + + offset += CERT_LEN_TAG_SIZE; /* Initialize the buffer length offset. */ + + ret = ParseCerts(ctx, buf, bufLen, hsMsg, &offset); + if ((ret != HITLS_SUCCESS) || (offset != (allCertsLen + CERT_LEN_TAG_SIZE))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_CERT_ERR); + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15595, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Certificate msg parse failed.", 0, 0, 0, 0); + CleanCertificate(&hsMsg->body.certificate); + return HITLS_PARSE_CERT_ERR; + } + + return HITLS_SUCCESS; +} + +int32_t Tls13ParseCertificateReqCtx(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg, uint32_t *offset) +{ + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + CertificateMsg *certMsg = &hsMsg->body.certificate; + + /* Obtain the certificates_request_context_length */ + uint16_t certReqCtxLen = buf[*offset]; + certMsg->certificateReqCtxSize = (uint32_t)certReqCtxLen; + (*offset)++; + /* At least the length and content of the total certificate length of 3 bytes + certificateReqCtx can be parsed */ + if (bufLen < CERT_LEN_TAG_SIZE + certReqCtxLen + sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15905, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message (tls 1.3 certificate) is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + /* Obtain the certificate_request_context value */ + if (certReqCtxLen > 0) { + certMsg->certificateReqCtx = BSL_SAL_Calloc(certReqCtxLen, sizeof(uint8_t)); + if (certMsg->certificateReqCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15596, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "certificateReqCtx malloc fail when parse tls1.3 certificate msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(certMsg->certificateReqCtx, certReqCtxLen, &buf[*offset], certReqCtxLen); + *offset += certReqCtxLen; + } + return HITLS_SUCCESS; +} + +/** +* @brief Parse the certificate message. +* +* @param ctx [IN] TLS context +* @param buf [IN] message buffer +* @param bufLen [IN] Maximum message length +* @param hsMsg [OUT] message structure +* +* @retval HITLS_SUCCESS parsed successfully. +* @retval HITLS_PARSE_CERT_ERR Failed to parse the certificate. +* @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + */ +int32_t Tls13ParseCertificate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + CertificateMsg *certMsg = &hsMsg->body.certificate; + uint32_t offset = 0; + int32_t ret = Tls13ParseCertificateReqCtx(ctx, buf, bufLen, hsMsg, &offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Obtain the lengths of all certificates */ + uint32_t allCertsLen = BSL_ByteToUint24(&buf[offset]); + if (allCertsLen != (bufLen - CERT_LEN_TAG_SIZE - offset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15597, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of all tls1.3 certificates is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + CleanCertificate(&hsMsg->body.certificate); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /** + * The client can send a certificate message without a certificate, so if the total length of the certificate is 0, + * it directly returns success; If the client receives a certificate message of length 0, it is determined by the + * processing layer, which is only responsible for parsing + */ + if (allCertsLen == 0) { + return HITLS_SUCCESS; + } + + offset += CERT_LEN_TAG_SIZE; + + ret = ParseCerts(ctx, buf, bufLen, hsMsg, &offset); + if ((ret != HITLS_SUCCESS) || + (offset != (sizeof(uint8_t) + certMsg->certificateReqCtxSize + CERT_LEN_TAG_SIZE + allCertsLen))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_CERT_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15598, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Certificate msg parse failed.", 0, 0, 0, 0); + CleanCertificate(&hsMsg->body.certificate); + return HITLS_PARSE_CERT_ERR; + } + + return HITLS_SUCCESS; +} + +// Clear the memory applied for in the certificate message structure. +void CleanCertificate(CertificateMsg *msg) +{ + if (msg == NULL) { + return; + } + BSL_SAL_FREE(msg->certificateReqCtx); + /* Obtain the certificate message */ + CERT_Item *next = msg->cert; + /* Release the message until it is empty */ + while (next != NULL) { + CERT_Item *temp = next->next; + BSL_SAL_FREE(next->data); + BSL_SAL_FREE(next); + next = temp; + } + msg->cert = NULL; + return; +} diff --git a/tls/handshake/parse/src/parse_certificate_request.c b/tls/handshake/parse/src/parse_certificate_request.c new file mode 100644 index 00000000..b413896d --- /dev/null +++ b/tls/handshake/parse/src/parse_certificate_request.c @@ -0,0 +1,276 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "bsl_list.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "parse_msg.h" +#include "hs_extensions.h" +#include "parse_extensions.h" + + +#define SINGLE_SIG_HASH_ALG_SIZE 2u + +// Parse the certificate type field in the certificate request message. +static int32_t ParseClientCertificateType(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + CertificateRequestMsg *msg, uint32_t *useLen) +{ + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15455, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of certificate request msg is incorrect when parse client certificate type.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the certificate type length */ + uint32_t bufOffset = 0; + msg->certTypesSize = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + if (((uint32_t)msg->certTypesSize > (bufLen - bufOffset)) || (msg->certTypesSize == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15456, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the certificate type size in the certificate request is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the certificate type */ + msg->certTypes = BSL_SAL_Dump(&buf[bufOffset], msg->certTypesSize); + if (msg->certTypes == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15457, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "certTypes malloc fail when parse certificate request.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + bufOffset += msg->certTypesSize; + *useLen = bufOffset; + + return HITLS_SUCCESS; +} + +// Parse the signature algorithm field in the certificate request message. +static int32_t ParseSignatureAndHashAlgo(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + CertificateRequestMsg *msg, uint32_t *useLen) +{ + uint32_t bufOffset = 0; + + /* An extension of the same type has already been parsed */ + if (msg->haveSignatureAndHashAlgo == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15458, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of certificate request msg is incorrect when parse signature and hashAlgo.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the length of the signature hash algorithm */ + uint16_t signatureAndHashAlgLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if (((uint32_t)signatureAndHashAlgLen > (bufLen - bufOffset)) || + ((signatureAndHashAlgLen % SINGLE_SIG_HASH_ALG_SIZE) != 0u) || (signatureAndHashAlgLen == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15459, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the signature and Hash algorithm length in certificate request msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Parse the length of the signature algorithm */ + msg->signatureAlgorithmsSize = signatureAndHashAlgLen / SINGLE_SIG_HASH_ALG_SIZE; + msg->signatureAlgorithms = (uint16_t *)BSL_SAL_Malloc(signatureAndHashAlgLen); + if (msg->signatureAlgorithms == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15460, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signatureAlgorithms malloc fail when parse certificate request.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + /* Extract the signature algorithm */ + for (uint16_t index = 0u; index < msg->signatureAlgorithmsSize; index++) { + msg->signatureAlgorithms[index] = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + } + *useLen = bufOffset; + + msg->haveSignatureAndHashAlgo = true; + return HITLS_SUCCESS; +} + +int32_t ParseCertificateRequest(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t bufOffset = 0; + uint32_t useLen = 0; + CertificateRequestMsg *msg = &hsMsg->body.certificateReq; + + ret = ParseClientCertificateType(ctx, buf, bufLen, msg, &useLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += useLen; + + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + ret = ParseSignatureAndHashAlgo(ctx, &buf[bufOffset], bufLen - bufOffset, msg, &useLen); + if (ret != HITLS_SUCCESS) { + CleanCertificateRequest(msg); + return ret; + } + } + + return HITLS_SUCCESS; +} + +void CleanCertificateRequest(CertificateRequestMsg *msg) +{ + if (msg == NULL) { + return; + } + + /* release Certificate request message */ + BSL_SAL_FREE(msg->certificateReqCtx); + BSL_SAL_FREE(msg->certTypes); + BSL_SAL_FREE(msg->signatureAlgorithms); + return; +} + +static int32_t ParseCertificateRequestExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen, + CertificateRequestMsg *msg) +{ + uint32_t usedLen = 0u; + switch (extMsgType) { + case HS_EX_TYPE_SIGNATURE_ALGORITHMS: + return ParseSignatureAndHashAlgo(ctx, buf, extMsgLen, msg, &usedLen); + default: + break; + } + + return HITLS_SUCCESS; +} + +int32_t ParseTls13CertificateRequestExtensions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + CertificateRequestMsg *msg) +{ + if (bufLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15472, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the extension len of tls1.3 CertificateRequest msg could not be 0.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Initialize the message parsing length */ + uint32_t bufOffset = 0u; + int32_t ret; + + /* Parse the extended message on the server */ + while (bufOffset < bufLen) { + uint16_t extMsgType = HS_EX_TYPE_END; + uint32_t extMsgLen = 0u; + ret = ParseExHeader(ctx, &buf[bufOffset], bufLen - bufOffset, &extMsgType, &extMsgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += HS_EX_HEADER_LEN; + + ret = ParseCertificateRequestExBody(ctx, extMsgType, &buf[bufOffset], extMsgLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += extMsgLen; + } + + /* The extended content is the last field in the CertificateRequest message. No further data should be displayed. If + * the parsed length is inconsistent with the cache length, return an error code. */ + if (bufOffset != bufLen) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15473, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the extension len of CertificateRequest msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} + +int32_t Tls13ParseCertificateRequest(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15852, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of tls1.3 certificate request msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + int32_t ret; + uint32_t bufOffset = 0; + CertificateRequestMsg *msg = &hsMsg->body.certificateReq; + + /* Obtain the certificate_request_context_length */ + uint8_t certReqCtxLen = buf[bufOffset]; + msg->certificateReqCtxSize = (uint32_t)certReqCtxLen; + bufOffset++; + + /* If the message length is incorrect, return an error code. */ + if (bufOffset + certReqCtxLen + sizeof(uint16_t) > bufLen) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the certificate_request_context value */ + if (certReqCtxLen > 0) { + msg->certificateReqCtx = BSL_SAL_Calloc(certReqCtxLen, sizeof(uint8_t)); + if (msg->certificateReqCtx == NULL) { + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(msg->certificateReqCtx, certReqCtxLen, &buf[bufOffset], certReqCtxLen); + bufOffset += certReqCtxLen; + } + + /* Obtain the extended message length */ + uint16_t exMsgLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + /* If the buffer length does not match the extended length, return an error code. */ + if (exMsgLen != (bufLen - bufOffset)) { + BSL_SAL_FREE(msg->certificateReqCtx); + msg->certificateReqCtxSize = 0; + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15474, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the external message length of handshake message (tls1.3 CertificateRequest) is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + ret = ParseTls13CertificateRequestExtensions(ctx, &buf[bufOffset], bufLen - bufOffset, msg); + if (ret != HITLS_SUCCESS) { + CleanCertificateRequest(msg); + return ret; + } + + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/handshake/parse/src/parse_certificate_verify.c b/tls/handshake/parse/src/parse_certificate_verify.c new file mode 100644 index 00000000..6475e04c --- /dev/null +++ b/tls/handshake/parse/src/parse_certificate_verify.c @@ -0,0 +1,250 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "cert_method.h" +#include "hs_msg.h" +#include "hs_ctx.h" +#include "hs_verify.h" +#include "parse_msg.h" + +/* rfc8446 section 4.2.3 and 4.4.3 do not allow sha1 and PKCS1 */ +static HITLS_SignHashAlgo g_tls13AllowSignHashAlgo[] = { + CERT_SIG_SCHEME_ECDSA_SECP256R1_SHA256, + CERT_SIG_SCHEME_ECDSA_SECP384R1_SHA384, + CERT_SIG_SCHEME_ECDSA_SECP521R1_SHA512, + CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA256, + CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA384, + CERT_SIG_SCHEME_RSA_PSS_RSAE_SHA512, + CERT_SIG_SCHEME_ED25519, + CERT_SIG_SCHEME_RSA_PSS_PSS_SHA256, + CERT_SIG_SCHEME_RSA_PSS_PSS_SHA384, + CERT_SIG_SCHEME_RSA_PSS_PSS_SHA512 +}; + +static int32_t CheckSignHashAlg(TLS_Ctx *ctx, uint16_t signHashAlg) +{ + TLS_Config *config = &ctx->config.tlsConfig; + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + bool find = false; + for (uint32_t i = 0; i < (sizeof(g_tls13AllowSignHashAlgo) / sizeof(g_tls13AllowSignHashAlgo[0])); i++) { + if (signHashAlg == g_tls13AllowSignHashAlgo[i]) { + find = true; + break; + } + } + if (!find) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15565, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "not allowed to use 0x%X signAlg tls1.3.", signHashAlg, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_UNSUPPORT_SIGN_ALG; + } + } + + for (uint32_t i = 0; i < config->signAlgorithmsSize; i++) { + if (signHashAlg == config->signAlgorithms[i]) { + return HITLS_SUCCESS; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15865, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the signHashAlg in certificate verify msg matching failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_UNSUPPORT_SIGN_ALG; +} + +static int32_t ParseCertificateVerifyPre(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + uint16_t *signHashAlg, uint32_t *offset) +{ + /* 2-byte signature hash algorithm + 2-byte signature data length. + If the message length is less than 4 bytes, return an error code. */ + if (bufLen < 4u) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + *signHashAlg = BSL_ByteToUint16(buf); + + *offset = sizeof(uint16_t); + + if (CheckSignHashAlg(ctx, *signHashAlg) != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG); + return HITLS_PARSE_UNSUPPORT_SIGN_ALG; + } + } + return HITLS_SUCCESS; +} + +static bool KeyMatchSignAlg(TLS_Ctx *ctx, HITLS_SignHashAlgo signScheme, HITLS_CERT_KeyType keyType, + HITLS_CERT_Key *key) +{ + HITLS_CERT_KeyType certKeyType = SAL_CERT_SignScheme2CertKeyType(signScheme); + if (certKeyType != keyType) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15567, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signScheme not matche key, signScheme is 0x%X, certKeyType is %u, keyType is %u", signScheme, certKeyType, + keyType, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return false; + } + + /* check curve matches signature algorithm, only check ec key for tls1.3 */ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13 || keyType != TLS_CERT_KEY_TYPE_ECDSA) { + return true; + } + + int32_t ret; + HITLS_Config *config = &ctx->config.tlsConfig; + HITLS_NamedGroup keyCureName = HITLS_NAMED_GROUP_BUTT; + ret = SAL_CERT_KeyCtrl(config, key, CERT_KEY_CTRL_GET_CURVE_NAME, NULL, (void *)&keyCureName); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15568, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get ec pubkey curve name failed when verify sign data.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return false; + } + + HITLS_NamedGroup signCureName = CFG_GetEcdsaCurveNameBySchemes(signScheme); + if (signCureName != HITLS_NAMED_GROUP_BUTT && keyCureName != signCureName) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15569, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "key curve does not matches sigAlg, signScheme is 0x%X, keyCureName is %u, signCureName is %u.", signScheme, + keyCureName, signCureName, 0); + return false; + } + + return true; +} + +static int VerifySignData(TLS_Ctx *ctx, uint16_t signHashAlg, const uint8_t *sign, uint16_t signSize) +{ + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + if (ctx->hsCtx->peerCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_VERIFY_SIGN_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15866, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "no peer certificate when parse certificate verify.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_CERTIFICATE_REQUIRED); + return HITLS_PARSE_VERIFY_SIGN_FAIL; + } + + HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(ctx->hsCtx->peerCert); + HITLS_CERT_Key *pubkey = NULL; + int32_t ret = SAL_CERT_X509Ctrl(&ctx->config.tlsConfig, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + HITLS_SignHashAlgo signScheme = signHashAlg; + HITLS_CERT_KeyType keyType = TLS_CERT_KEY_TYPE_UNKNOWN; + ret = SAL_CERT_KeyCtrl(&ctx->config.tlsConfig, pubkey, CERT_KEY_CTRL_GET_TYPE, NULL, (void *)&keyType); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16031, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SAL_CERT_KeyCtrl fails when verifying data.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + SAL_CERT_KeyFree(mgrCtx, pubkey); + return ret; + } + + if (signScheme == 0) { + /** If the value of the signature hash algorithm is 0, the peer does not send the signature algorithm. + In this case, we need to obtain the default signature algorithm through the certificate. */ + signScheme = SAL_CERT_GetDefaultSignHashAlgo(keyType); + if (signScheme == CERT_SIG_SCHEME_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_VERIFY_SIGN_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16034, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "no available signature scheme when verify sign data, key type = %u.", keyType, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + SAL_CERT_KeyFree(mgrCtx, pubkey); + return HITLS_PARSE_VERIFY_SIGN_FAIL; + } + } + + /* check whether the signature scheme matches the certificate key */ + if (KeyMatchSignAlg(ctx, signScheme, keyType, pubkey) != true) { + SAL_CERT_KeyFree(mgrCtx, pubkey); + return HITLS_PARSE_VERIFY_SIGN_FAIL; + } + + /** verifying certificate data */ + ret = VERIFY_VerifySignData(ctx, pubkey, signScheme, sign, signSize); + SAL_CERT_KeyFree(mgrCtx, pubkey); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; +} + +int32_t ParseCertificateVerify(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + uint16_t signHashAlg = 0; + uint32_t offset = 0; + + int32_t ret = ParseCertificateVerifyPre(ctx, buf, bufLen, &signHashAlg, &offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint16_t signSize = BSL_ByteToUint16(&buf[offset]); + offset += sizeof(uint16_t); + + if ((signSize != (bufLen - offset)) || (signSize == 0)) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + const uint8_t *sign = &buf[offset]; + + ret = VerifySignData(ctx, signHashAlg, sign, signSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + CertificateVerifyMsg *msg = &hsMsg->body.certificateVerify; + msg->signHashAlg = signHashAlg; + msg->signSize = signSize; + msg->sign = BSL_SAL_Dump(sign, signSize); + if (msg->sign == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + ctx->peerInfo.peerSignHashAlg = signHashAlg; + return HITLS_SUCCESS; +} + +void CleanCertificateVerify(CertificateVerifyMsg *msg) +{ + if (msg == NULL) { + return; + } + + BSL_SAL_FREE(msg->sign); + + return; +} diff --git a/tls/handshake/parse/src/parse_client_hello.c b/tls/handshake/parse/src/parse_client_hello.c new file mode 100644 index 00000000..306795ed --- /dev/null +++ b/tls/handshake/parse/src/parse_client_hello.c @@ -0,0 +1,294 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "hs_msg.h" +#include "hs.h" +#include "parse_common.h" +#include "parse_extensions.h" +#include "parse_msg.h" + +#define SINGLE_CIPHER_SUITE_SIZE 2u /* Length of the signature cipher suite */ + +int32_t ParseClientHelloCipherSuitesLen( + TLS_Ctx *ctx, const uint8_t *msgBuf, uint32_t bufLen, uint32_t *bufOffset, uint16_t *cipherSuitesLen) +{ + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15700, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the cipher suite length */ + *cipherSuitesLen = BSL_ByteToUint16(&msgBuf[*bufOffset]); + *bufOffset += sizeof(uint16_t); + + if ((uint32_t)*cipherSuitesLen > (bufLen - *bufOffset)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16056, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the cipherSuites length of client hello is incorrect. lenght mismatch", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + if (((*cipherSuitesLen % SINGLE_CIPHER_SUITE_SIZE) != 0u) || (*cipherSuitesLen == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15701, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the cipherSuites length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} +/** + * @brief Parse the cipher suite list of Client Hello messages. + * + * @param ctx [IN] TLS context + * @param buf [IN] message buffer. The first two bytes are Cipher Suites Length. + * @param bufLen [IN] Maximum message length + * @param msg [OUT] Client Hello Structure + * @param readLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS parsed successfully. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + */ +static int32_t ParseClientHelloCipherSuites(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + ClientHelloMsg *msg, uint32_t *readLen) +{ + const uint8_t *msgBuf = buf; + uint32_t bufOffset = 0; + uint16_t cipherSuitesLen = 0; + int32_t ret = ParseClientHelloCipherSuitesLen(ctx, msgBuf, bufLen, &bufOffset, &cipherSuitesLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + msg->cipherSuitesSize = cipherSuitesLen / SINGLE_CIPHER_SUITE_SIZE; + BSL_SAL_FREE(msg->cipherSuites); + msg->cipherSuites = (uint16_t *)BSL_SAL_Malloc(((uint32_t)msg->cipherSuitesSize) * sizeof(uint16_t)); + if (msg->cipherSuites == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15702, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cipherSuites malloc fail when parse client hello msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + /* Parse the cipher suite */ + for (uint16_t index = 0u; index < msg->cipherSuitesSize; index++) { + msg->cipherSuites[index] = BSL_ByteToUint16(&msgBuf[bufOffset]); + bufOffset += sizeof(uint16_t); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15703, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "got cipher suite from client:0x%x.", msg->cipherSuites[index], 0, 0, 0); + if (msg->cipherSuites[index] == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { + msg->haveScsvCipher = true; + } + } + *readLen = bufOffset; + + return HITLS_SUCCESS; +} + +/** + * @brief List of compression methods for parsing Client Hello messages + * + * @param ctx [IN] TLS context + * @param buf [IN] message buffer. The first two bytes are the Compression Methods Length. + * @param bufLen [IN] Maximum message length + * @param readLen [OUT] Length of the parsed message + * + * @retval HITLS_SUCCESS parsed successfully. + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + */ +static int32_t ParseClientHelloCompressionMethods(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + ClientHelloMsg *msg, uint32_t *readLen) +{ + const uint8_t *msgBuf = buf; + uint32_t bufOffset = 0; + + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15704, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the compression method length */ + uint8_t compressionMethodsLen = msgBuf[bufOffset]; + bufOffset += sizeof(uint8_t); + if ((compressionMethodsLen > (bufLen - bufOffset)) || (compressionMethodsLen == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15705, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the compression length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + BSL_SAL_FREE(msg->compressionMethods); + msg->compressionMethods = (uint8_t *)BSL_SAL_Dump(&msgBuf[bufOffset], compressionMethodsLen); + if (msg->compressionMethods == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15570, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "compressionMethods malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + msg->compressionMethodsSize = compressionMethodsLen; + + bufOffset += compressionMethodsLen; + *readLen = bufOffset; + return HITLS_SUCCESS; +} + +/** +* @brief Parse the Client Hello extension messages. +* +* @param ctx [IN] TLS context +* @param buf [IN] message buffer, starting from Extensions Length +* @param bufLen [IN] Maximum message length +* @param msg [OUT] Client Hello Structure +* @param readLen [OUT] Length of the parsed message +* +* @retval HITLS_SUCCESS parsed successfully. +* @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. +* @retval HITLS_PARSE_DUPLICATE_EXTENSIVE_MSG Extended message +*/ +static int32_t ParseClientHelloExtensions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + const uint8_t *msgBuf = buf; + uint32_t bufOffset = 0; + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15707, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the external message length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the extended message length */ + uint16_t exMsgLen = BSL_ByteToUint16(&msgBuf[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (exMsgLen != (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15708, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the external message length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + if (exMsgLen == 0u) { + return HITLS_SUCCESS; + } + + return ParseClientExtension(ctx, &msgBuf[bufOffset], exMsgLen, msg); +} + +static int32_t WhetherParseClientExtensions(TLS_Ctx *ctx, uint32_t bufOffset, const uint8_t *data, uint32_t len, + ClientHelloMsg *msg) +{ + int32_t ret; + /* If the parsing is complete, return success. */ + if (len == bufOffset) { + // ClientHello is optionally followed by extension data + return HITLS_SUCCESS; + } + + ret = ParseClientHelloExtensions(ctx, &data[bufOffset], len - bufOffset, msg); + if (ret != HITLS_SUCCESS) { + CleanClientHello(msg); + } + return ret; +} + +int32_t ParseClientHello(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg) +{ + ClientHelloMsg *msg = &hsMsg->body.clientHello; + uint32_t bufOffset = 0, readLen = 0; + /* Parse the version number. The version number occupies two bytes */ + int32_t ret = ParseVersion(ctx, data, len, &msg->version); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += sizeof(uint16_t); + + ctx->negotiatedInfo.clientVersion = msg->version; + /* Parse the random number. The random number occupies 32 bytes */ + ret = ParseRandom(ctx, &data[bufOffset], len - bufOffset, msg->randomValue, HS_RANDOM_SIZE); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += HS_RANDOM_SIZE; + + ret = ParseSessionId(ctx, &data[bufOffset], len - bufOffset, &msg->sessionId, &msg->sessionIdSize, &readLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += readLen; +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(HS_GetVersion(ctx))) { + /* Cookies need to be parsed in DTLS */ + ret = ParseCookie(ctx, &data[bufOffset], len - bufOffset, &msg->cookie, &msg->cookieLen, &readLen); + if (ret != HITLS_SUCCESS) { + CleanClientHello(msg); + return ret; + } + bufOffset += readLen; + } +#endif + /* Parse the cipher suite. After the parsing is complete, update the msg->cipherSuitesSize and msg->cipherSuites */ + ret = ParseClientHelloCipherSuites(ctx, &data[bufOffset], len - bufOffset, msg, &readLen); + if (ret != HITLS_SUCCESS) { + CleanClientHello(msg); + return ret; + } + bufOffset += readLen; + /* Parse compression method */ + ret = ParseClientHelloCompressionMethods(ctx, &data[bufOffset], len - bufOffset, msg, &readLen); + if (ret != HITLS_SUCCESS) { + CleanClientHello(msg); + return ret; + } + bufOffset += readLen; + + return WhetherParseClientExtensions(ctx, bufOffset, data, len, msg); +} + +void CleanClientHello(ClientHelloMsg *msg) +{ + // The value of msg->refCnt is not 0, indicating that the ClientHelloMsg resource is hosted in the hrr scenario + if (msg == NULL || msg->refCnt != 0) { + return; + } + + BSL_SAL_FREE(msg->sessionId); + BSL_SAL_FREE(msg->cookie); + BSL_SAL_FREE(msg->cipherSuites); + BSL_SAL_FREE(msg->compressionMethods); + + CleanClientHelloExtension(msg); + + return; +} diff --git a/tls/handshake/parse/src/parse_client_key_exchange.c b/tls/handshake/parse/src/parse_client_key_exchange.c new file mode 100644 index 00000000..5691abbf --- /dev/null +++ b/tls/handshake/parse/src/parse_client_key_exchange.c @@ -0,0 +1,271 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_crypt_type.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "parse_msg.h" + + +/** +* @brief Parse the client ecdh message. +* +* @param ctx [IN] TLS context +* @param data [IN] message buffer +* @param len [IN] message buffer length +* @param hsMsg [OUT] Parsed message structure +* +* @retval HITLS_SUCCESS parsed successfully. +* @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. +*/ +static int32_t ParseClientKxMsgEcdhe(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ClientKeyExchangeMsg *msg) +{ + if (len < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15635, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of client key exchange msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0; + /* Compatible with OpenSSL, add 3 bytes to the client key exchange */ + +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + // Curve type + Curve ID + Public key length + uint8_t minLen = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t); + if (len < minLen) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15917, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of client key exchange msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + // Ignore the three bytes + bufOffset += sizeof(uint8_t) + sizeof(uint16_t); + } +#endif + uint8_t pubKeySize = data[bufOffset]; + bufOffset++; + + if ((pubKeySize != (len - bufOffset)) || (pubKeySize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15636, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of client ecdh pubKeySize is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + BSL_SAL_FREE(msg->data); + msg->data = BSL_SAL_Malloc(pubKeySize); + if (msg->data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15637, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubKey malloc fail when parse client key exchange msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(msg->data, pubKeySize, &data[bufOffset], pubKeySize); + msg->dataSize = pubKeySize; + + return HITLS_SUCCESS; +} + +/** +* @brief Parse the Client Dhe message. +* +* @param ctx [IN] TLS context +* @param data [IN] message buffer +* @param len [IN] message buffer length +* @param hsMsg [OUT] Parsed message structure +* +* @retval HITLS_SUCCESS parsed successfully. +* @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. +*/ +static int32_t ParseClientKxMsgDhe(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ClientKeyExchangeMsg *msg) +{ + if (len < (sizeof(uint16_t))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15638, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of client key exchange msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0; + uint32_t pubKeySize = BSL_ByteToUint16(&data[bufOffset]); + bufOffset += sizeof(uint16_t); + + if ((pubKeySize != (len - bufOffset)) || (pubKeySize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15639, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of client dh pubKeySize is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + BSL_SAL_FREE(msg->data); + msg->data = BSL_SAL_Malloc(pubKeySize); + if (msg->data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15640, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubKey malloc fail when parse client key exchange msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(msg->data, pubKeySize, &data[bufOffset], pubKeySize); + msg->dataSize = pubKeySize; + + return HITLS_SUCCESS; +} + +static int32_t ParseClientKxMsgRsa(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ClientKeyExchangeMsg *msg) +{ + uint32_t offset = 0; + uint32_t encLen = len; + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15641, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Parse RSA-Encrypted Premaster Secret error: msgLen = %u.", len, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + offset = sizeof(uint16_t); + encLen = BSL_ByteToUint16(data); + if ((encLen != (len - offset)) || (encLen == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15642, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Parse RSA-Encrypted Premaster Secret error: msgLen = %u, encLen = %u.", len, encLen, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + BSL_SAL_FREE(msg->data); + msg->data = BSL_SAL_Dump(&data[offset], encLen); + if (msg->data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15643, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubKey malloc fail when parse client key exchange msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + msg->dataSize = encLen; + + return HITLS_SUCCESS; +} + +static int32_t ParseClientKxMsgIdentity(const uint8_t *data, uint32_t len, ClientKeyExchangeMsg *msg, + uint32_t *usedLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint32_t offset = 0u; + uint16_t identityLen = BSL_ByteToUint16(&data[offset]); + offset += sizeof(uint16_t); + + if ((identityLen > len - offset) || (identityLen > HS_PSK_IDENTITY_MAX_LEN)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint8_t *identity = NULL; + if (identityLen != 0) { + identity = (uint8_t *)BSL_SAL_Calloc(1u, (identityLen + 1) * sizeof(uint8_t)); + if (identity == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + if (memcpy_s(identity, identityLen + 1, &data[offset], identityLen) != EOK) { + BSL_SAL_FREE(identity); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + } + msg->pskIdentity = identity; + msg->pskIdentitySize = identityLen; + offset += identityLen; + + *usedLen = offset; + + return HITLS_SUCCESS; +} + +int32_t ParseClientKeyExchange(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg) +{ + int32_t ret; + uint32_t offset = 0u; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + ClientKeyExchangeMsg *msg = &hsMsg->body.clientKeyExchange; + + if (IsPskNegotiation(ctx)) { + ret = ParseClientKxMsgIdentity(data, len, msg, &offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + switch (hsCtx->kxCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_ECDHE: + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = ParseClientKxMsgEcdhe(ctx, &data[offset], len - offset, msg); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = ParseClientKxMsgDhe(ctx, &data[offset], len - offset, msg); + break; + case HITLS_KEY_EXCH_RSA: + case HITLS_KEY_EXCH_RSA_PSK: +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: +#endif + ret = ParseClientKxMsgRsa(ctx, &data[offset], len - offset, msg); + break; + case HITLS_KEY_EXCH_PSK: + return HITLS_SUCCESS; + default: + ret = HITLS_PARSE_UNSUPPORT_KX_ALG; + break; + } + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15644, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse client key exchange msg fail.", 0, 0, 0, 0); + CleanClientKeyExchange(msg); + return ret; + } + + return HITLS_SUCCESS; +} + +void CleanClientKeyExchange(ClientKeyExchangeMsg *msg) +{ + if (msg == NULL) { + return; + } + + BSL_SAL_FREE(msg->pskIdentity); + BSL_SAL_FREE(msg->data); + return; +} diff --git a/tls/handshake/parse/src/parse_common.c b/tls/handshake/parse/src/parse_common.c new file mode 100644 index 00000000..54c38e40 --- /dev/null +++ b/tls/handshake/parse/src/parse_common.c @@ -0,0 +1,187 @@ +/* + * 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 "securec.h" +#include "bsl_bytes.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "parse_common.h" + + +int32_t ParseVersion(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint16_t *version) +{ + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15645, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message is not enough for version.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + *version = BSL_ByteToUint16(buf); + + return HITLS_SUCCESS; +} + +int32_t ParseRandom(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint8_t *random, uint32_t randomSize) +{ + if (bufLen < randomSize) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15646, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message is not enough for random.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + (void)memcpy_s(random, randomSize, buf, randomSize); + + return HITLS_SUCCESS; +} + +static int32_t CheckBufLen(TLS_Ctx *ctx, uint32_t bufLen) +{ + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15647, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message is not enough for sessionId size.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; +} + +int32_t ParseSessionId(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + uint8_t **id, uint8_t *idSize, uint32_t *readLen) +{ + *id = NULL; + + int32_t ret = CheckBufLen(ctx, bufLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t bufOffset = 0; + /* Extract the sessionId length */ + uint8_t sessionIdSize = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + + if (sessionIdSize == 0u) { + *idSize = sessionIdSize; + *readLen = bufOffset; + return HITLS_SUCCESS; + } + + /* If the sessionId length is incorrect, return an error code */ + if (sessionIdSize > (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15648, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the sessionId length of handshake message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* According to RFC 5246, the length of sessionId cannot exceed 32 bytes */ + if (sessionIdSize > TLS_HS_MAX_SESSION_ID_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15649, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the sessionId length of handshake message over 32.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* The session ID length must be greater than or equal to 24 bytes according to the company security redline */ + if (sessionIdSize < TLS_HS_MIN_SESSION_ID_SIZE) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15650, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the sessionId length of handshake message less than 24.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the session ID */ + uint8_t *sessionId = BSL_SAL_Malloc(sessionIdSize); + if (sessionId == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15651, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "sessionId malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(sessionId, sessionIdSize, &buf[bufOffset], sessionIdSize); + + /* Update the buffer offset length */ + bufOffset += sessionIdSize; + + *id = sessionId; + *idSize = sessionIdSize; + *readLen = bufOffset; + return HITLS_SUCCESS; +} + +int32_t ParseCookie(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + uint8_t **cookie, uint8_t *cookieLen, uint32_t *readLen) +{ + *cookie = NULL; + + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15652, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message is not enough for cookie size.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0; + + /* Extract the cookie length */ + uint8_t tmpCookieLen = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + + if (tmpCookieLen == 0u) { + *cookieLen = tmpCookieLen; + *readLen = bufOffset; + return HITLS_SUCCESS; + } + + /* If the cookie length is incorrect, return an error code */ + if (tmpCookieLen > (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15653, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the cookie length of handshake message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Get the cookie */ + uint8_t *tmpCookie = BSL_SAL_Malloc(tmpCookieLen); + if (tmpCookie == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15654, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cookie malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(tmpCookie, tmpCookieLen, &buf[bufOffset], tmpCookieLen); + + /* Update the buffer offset length */ + bufOffset += tmpCookieLen; + + *cookie = tmpCookie; + *cookieLen = tmpCookieLen; + *readLen = bufOffset; + return HITLS_SUCCESS; +} diff --git a/tls/handshake/parse/src/parse_common.h b/tls/handshake/parse/src/parse_common.h new file mode 100644 index 00000000..c31e162f --- /dev/null +++ b/tls/handshake/parse/src/parse_common.h @@ -0,0 +1,95 @@ +/* + * 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 PARSER_COMMON_H +#define PARSER_COMMON_H + +#include +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Parse the version of the message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer, starting from version + * @param bufLen [IN] Maximum message length + * @param version [OUT] Parsed version + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseVersion(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint16_t *version); + +/** + * @brief Parse random number in message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer, starting from random number + * @param bufLen [IN] Maximum message length + * @param random [OUT] Parsed random number + * @param randomSize [IN] Random number length + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMCPY_FAIL Memory Copy Failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseRandom(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint8_t *random, uint32_t randomSize); + +/** + * @brief Parse SessionId in message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer. The first byte is the length of the session ID + * @param bufLen [IN] Maximum message length + * @param id [OUT] Parsed session ID + * @param idSize [OUT] Parsed session ID length + * @param readLen [OUT] Length of parsed message + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + * @retval HITLS_MEMCPY_FAIL Memory Copy Failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseSessionId(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + uint8_t **id, uint8_t *idSize, uint32_t *readLen); + +/** + * @brief Parse Cookie in message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer. The first byte is the cookie length. + * @param bufLen [IN] Maximum message length + * @param cookie [OUT] Parsed cookie + * @param cookieLen [OUT] Parsed cookie length + * @param readLen [OUT] Length of parsed messag + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + * @retval HITLS_MEMCPY_FAIL Memory Copy Failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseCookie(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, + uint8_t **cookie, uint8_t *cookieLen, uint32_t *readLen); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PARSER_COMMON_H */ diff --git a/tls/handshake/parse/src/parse_encrypted_extensions.c b/tls/handshake/parse/src/parse_encrypted_extensions.c new file mode 100644 index 00000000..e6a99888 --- /dev/null +++ b/tls/handshake/parse/src/parse_encrypted_extensions.c @@ -0,0 +1,199 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_extensions.h" +#include "parse_extensions.h" + +/** + * @brief Release the memory in the message structure. + * + * @param msg [IN] message structure + */ +void CleanEncryptedExtensions(EncryptedExtensions *msg) +{ + if (msg == NULL) { + return; + } + BSL_SAL_FREE(msg->supportedGroups); + return; +} + +static int32_t ParseEncryptedSupportGroups(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, EncryptedExtensions *msg) +{ + /* Has parsed extensions of the same type */ + if (msg->haveSupportedGroups == true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15709, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "external message type ClientSupportGroups in encrypted extension message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15710, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "external message length (supported groups) in encrypted extension message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + uint16_t groupLen = BSL_ByteToUint16(&buf[bufOffset]) / sizeof(uint16_t); + bufOffset += sizeof(uint16_t); + + /* If the length of the message does not match the extended length, or the length is 0, return + the handshake message error. */ + if (((groupLen * sizeof(uint16_t)) != (bufLen - sizeof(uint16_t))) || (groupLen == 0)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15711, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "external message length (supported groups) in encrypted extension message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->supportedGroups = (uint16_t *)BSL_SAL_Malloc(groupLen * sizeof(uint16_t)); + if (msg->supportedGroups == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15712, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "supportedGroups malloc fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + for (uint32_t i = 0; i < groupLen; i++) { + msg->supportedGroups[i] = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + } + + msg->supportedGroupsSize = groupLen; + msg->haveSupportedGroups = true; + + return HITLS_SUCCESS; +} + +static int32_t ParseEncryptedExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen, + EncryptedExtensions *msg) +{ + switch (extMsgType) { + case HS_EX_TYPE_SUPPORTED_GROUPS: + return ParseEncryptedSupportGroups(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_EARLY_DATA: + return ParseEmptyExtension(ctx, HS_EX_TYPE_EARLY_DATA, extMsgLen, &msg->haveEarlyData); + case HS_EX_TYPE_SERVER_NAME: + return ParseEmptyExtension(ctx, HS_EX_TYPE_SERVER_NAME, extMsgLen, &msg->haveServerName); + case HS_EX_TYPE_SIGNATURE_ALGORITHMS: + case HS_EX_TYPE_KEY_SHARE: + case HS_EX_TYPE_PRE_SHARED_KEY: + case HS_EX_TYPE_STATUS_REQUEST: + case HS_EX_TYPE_STATUS_REQUEST_V2: + case HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES: + case HS_EX_TYPE_COOKIE: + case HS_EX_TYPE_SUPPORTED_VERSIONS: + case HS_EX_TYPE_TRUSTED_CA_LIST: + case HS_EX_TYPE_OID_FILTERS: + case HS_EX_TYPE_POST_HS_AUTH: + case HS_EX_TYPE_SIGNATURE_ALGORITHMS_CERT: + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16056, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Illegal extension received", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORTED_EXTENSION); + return HITLS_PARSE_UNSUPPORTED_EXTENSION; + default: + break; + } + + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORTED_EXTENSION); + return HITLS_PARSE_UNSUPPORTED_EXTENSION; +} + +// Parse the EncryptedExtensions extension message +int32_t ParseEncryptedEx(TLS_Ctx *ctx, EncryptedExtensions *msg, const uint8_t *buf, uint32_t bufLen) +{ + uint32_t bufOffset = 0u; + int32_t ret; + + while (bufOffset < bufLen) { + uint32_t extMsgLen = 0u; + uint16_t extMsgType = HS_EX_TYPE_END; + ret = ParseExHeader(ctx, &buf[bufOffset], bufLen - bufOffset, &extMsgType, &extMsgLen); + if (ret != HITLS_SUCCESS) { + CleanEncryptedExtensions(msg); + return ret; + } + bufOffset += HS_EX_HEADER_LEN; + + ret = ParseEncryptedExBody(ctx, extMsgType, &buf[bufOffset], extMsgLen, msg); + if (ret != HITLS_SUCCESS) { + CleanEncryptedExtensions(msg); + return ret; + } + bufOffset += extMsgLen; + } + + if (bufOffset != bufLen) { + CleanEncryptedExtensions(msg); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15714, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the extension len of encrypted extensions msg is incorrect", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} + +// Parse the EncryptedExtensions message. +int32_t ParseEncryptedExtensions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + if ((buf == NULL) || (hsMsg == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15908, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the length of handshake message (encrypted Extensions) is not enough for version.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Parse the EncryptedExtensions extension message */ + EncryptedExtensions *msg = &hsMsg->body.encryptedExtensions; + uint32_t bufOffset = 0u; + + /* Obtain the extended message length */ + uint16_t exMsgLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (bufLen - bufOffset != exMsgLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15715, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the external message length of handshake message (encrypted extensions) is incorrect", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return ParseEncryptedEx(ctx, msg, &buf[bufOffset], exMsgLen); +} diff --git a/tls/handshake/parse/src/parse_extensions.c b/tls/handshake/parse/src/parse_extensions.c new file mode 100644 index 00000000..daa14486 --- /dev/null +++ b/tls/handshake/parse/src/parse_extensions.c @@ -0,0 +1,1648 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "bsl_list.h" +#include "hitls_error.h" +#include "hitls_cert_type.h" +#include "tls.h" +#include "hs_extensions.h" +#include "parse_common.h" +#include "hs_ctx.h" +#include "parse_extensions.h" + +// Parse an empty extended message. +int32_t ParseEmptyExtension(TLS_Ctx *ctx, uint16_t extMsgType, uint32_t extMsgLen, bool *haveExtension) +{ + /* Parsed extensions of the same type */ + if (*haveExtension) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15120, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type:%d len:%lu in hello message is repeated.", extMsgType, extMsgLen, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + /* Parse the empty extended message */ + if (extMsgLen != 0u) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15121, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type:%d len:%lu in hello message is nonzero.", extMsgType, extMsgLen, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + *haveExtension = true; + return HITLS_SUCCESS; +} + +static int32_t ParseClientExtMasterSecret(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + (void)buf; + return ParseEmptyExtension(ctx, HS_EX_TYPE_EXTENDED_MASTER_SECRET, bufLen, + &msg->extension.flag.haveExtendedMasterSecret); +} + +static void SetRevMsgExtServernameInfo(ClientHelloMsg *msg, uint8_t serverNameType, uint8_t *serverName, + uint16_t serverNameLen) +{ + serverName[serverNameLen - 1] = '\0'; + msg->extension.content.serverName = serverName; + msg->extension.content.serverNameSize = serverNameLen; + msg->extension.content.serverNameType = serverNameType; + msg->extension.flag.haveServerName = true; +} + +static int32_t ParseClientServerNamePre(TLS_Ctx *ctx, uint32_t bufLen, const ClientHelloMsg *msg) +{ + if (ctx == NULL || msg == NULL) { + return HITLS_NULL_INPUT; + } + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveServerName == true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15122, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type Client ServerName in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15123, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the ServerName length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} + +static int32_t ParseClientServerNameIndication(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + const uint32_t baseSize = sizeof(uint8_t) + sizeof(uint16_t); // serverNameType and serverName Length + uint32_t bufOffset = 0; + bool haveParseHostName = false; + while (bufOffset + baseSize < bufLen) { + /* Parse serverNameType */ + uint8_t serverNameType = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + /* Parse serverName Length */ + uint16_t serverNameLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if (bufLen < bufOffset + serverNameLen) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_SERVER_NAME_ERR; + } + if (serverNameType != 0) { + bufOffset += serverNameLen; + continue; + } + if (haveParseHostName || serverNameLen == 0 || serverNameLen > 0xff || + strnlen((const char *)&buf[bufOffset], serverNameLen) != serverNameLen) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_SERVER_NAME_ERR; + } + haveParseHostName = true; + uint8_t *serverName = (uint8_t *)BSL_SAL_Calloc((serverNameLen + 1), sizeof(uint8_t)); + if (serverName == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15127, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calloc server_name memory fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(serverName, serverNameLen + 1, &buf[bufOffset], serverNameLen); + SetRevMsgExtServernameInfo(msg, serverNameType, serverName, serverNameLen + 1); + bufOffset += serverNameLen; + } + if (bufOffset != bufLen) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_SERVER_NAME_ERR; + } + if (!msg->extension.flag.haveServerName) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_SERVER_NAME_ERR; + } + return HITLS_SUCCESS; +} + +// Parse the ServerName extension item of client hello. +static int32_t ParseClientServerName(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + int32_t ret = ParseClientServerNamePre(ctx, bufLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t bufOffset = 0u; + /* Parse serverNameList Size */ + uint32_t serverNameListSize = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if ((serverNameListSize != bufLen - bufOffset) || (serverNameListSize < sizeof(uint8_t) + sizeof(uint16_t))) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15124, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the server_name List size is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return ParseClientServerNameIndication(ctx, &buf[bufOffset], serverNameListSize, msg); +} + +// Parse the extension item of the client hello signature algorithm. +static int32_t ParseClientSignatureAlgorithms(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveSignatureAlgorithms == true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15128, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ClientSignatureAlgorithms in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15129, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the signatureAlgorithms length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + /* Parse signatureAlgorithmsSize */ + uint16_t signAlgBufLen = BSL_ByteToUint16(&buf[bufOffset]); + uint16_t signatureAlgorithmsSize = signAlgBufLen / sizeof(uint16_t); + bufOffset += sizeof(uint16_t); + // Add exception handling. The value of signAlgBufLen cannot be an odd number. Each algorithm occupies two bytes. + /* If the message length does not match the extended length or the length is 0, return an error code. */ + if (((signAlgBufLen & 1) != 0) || ((signatureAlgorithmsSize * sizeof(uint16_t)) != (bufLen - bufOffset)) || + (signatureAlgorithmsSize == 0)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15130, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the signatureAlgorithmsSize is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Parse signatureAlgorithms */ + uint16_t *signatureAlgorithms = (uint16_t *)BSL_SAL_Calloc(signatureAlgorithmsSize, sizeof(uint16_t)); + if (signatureAlgorithms == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15131, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signatureAlgorithms malloc fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + for (uint32_t i = 0; i < signatureAlgorithmsSize; i++) { + signatureAlgorithms[i] = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + } + + msg->extension.content.signatureAlgorithmsSize = signatureAlgorithmsSize; + msg->extension.content.signatureAlgorithms = signatureAlgorithms; + msg->extension.flag.haveSignatureAlgorithms = true; + + return HITLS_SUCCESS; +} + +// Parse the supported group messages. +static int32_t ParseClientSupportGroups(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveSupportedGroups == true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15132, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ClientSupportGroups in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15133, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (supported groups) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + uint16_t groupBufLen = BSL_ByteToUint16(&buf[bufOffset]); + uint16_t groupLen = groupBufLen / sizeof(uint16_t); + bufOffset += sizeof(uint16_t); + + /* If the length of the message does not match the extended length, or the length is 0, return an error code */ + if ((groupBufLen & 1) != 0 || ((groupLen * sizeof(uint16_t)) != (bufLen - sizeof(uint16_t))) || (groupLen == 0)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15134, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (supported groups) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->extension.content.supportedGroups = (uint16_t *)BSL_SAL_Calloc(groupLen, sizeof(uint16_t)); + if (msg->extension.content.supportedGroups == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15135, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "supportedGroups malloc fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + for (uint32_t i = 0; i < groupLen; i++) { + msg->extension.content.supportedGroups[i] = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + } + + msg->extension.content.supportedGroupsSize = groupLen; + msg->extension.flag.haveSupportedGroups = true; + BSL_SAL_FREE(ctx->peerInfo.groups); + ctx->peerInfo.groups = (uint16_t *)BSL_SAL_Dump(msg->extension.content.supportedGroups, groupLen * + sizeof(uint16_t)); + if (ctx->peerInfo.groups == NULL) { + BSL_SAL_FREE(msg->extension.content.supportedGroups); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15136, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "supportedGroups dump fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + ctx->peerInfo.groupsSize = groupLen; + return HITLS_SUCCESS; +} + +// Parse the client message in point format. +static int32_t ParseClientPointFormats(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.havePointFormats == true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15137, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ClientPointFormats in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint8_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15138, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (point formats) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtains the length of the point format. */ + uint32_t bufOffset = 0; + uint8_t pointFormatsSize = buf[0]; + bufOffset += sizeof(uint8_t); + + /* If the point format length does not match the extended length, or the length is 0, a handshake message error is + * returned */ + if ((pointFormatsSize != (bufLen - bufOffset)) || (pointFormatsSize == 0)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15139, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (point formats) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Parse the client message in point format */ + msg->extension.content.pointFormats = BSL_SAL_Calloc(pointFormatsSize, sizeof(uint8_t)); + if (msg->extension.content.pointFormats == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15140, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pointFormats malloc fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + for (uint8_t index = 0; index < pointFormatsSize; index++) { + msg->extension.content.pointFormats[index] = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + } + msg->extension.flag.havePointFormats = true; + msg->extension.content.pointFormatsSize = pointFormatsSize; + ctx->haveClientPointFormats = true; + + return HITLS_SUCCESS; +} + +static int32_t ParseClientAlpnProposeList(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveAlpn == true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15141, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type alpn list in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15142, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (alpn) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + uint16_t alpnLen = BSL_ByteToUint16(&buf[bufOffset]) / sizeof(uint8_t); + bufOffset += sizeof(uint16_t); + + /* If the message length does not match the extended length, or the message length is less than 2 bytes, return a + * handshake message error */ + if (((alpnLen * sizeof(uint8_t)) != (bufLen - sizeof(uint16_t))) || (alpnLen < 2)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15143, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (alpn) %d in client hello message is incorrect.", alpnLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t alpnListOffset = bufOffset; + do { + uint8_t alpnStringLen = buf[alpnListOffset]; + alpnListOffset += alpnStringLen + 1; + if (alpnListOffset > bufLen || alpnStringLen == 0) { /* can't exceed alpn extension buffer; can't be empty */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15144, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "alpn string len %hd in client hello message is incorrect.", alpnStringLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + } while (bufLen - alpnListOffset != 0); /* remaining len of alpn extension buffer */ + + msg->extension.content.alpnList = (uint8_t *)BSL_SAL_Dump(&buf[bufOffset], alpnLen); + if (msg->extension.content.alpnList == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15145, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "alpn list malloc fail when parse extensions msg.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + msg->extension.content.alpnListSize = alpnLen; + msg->extension.flag.haveAlpn = true; + + return HITLS_SUCCESS; +} + +int32_t ParseIdentities(TLS_Ctx *ctx, PreSharedKey *preSharedKey, const uint8_t *buf, uint32_t bufLen) +{ + uint32_t bufOffset = 0u; + PreSharedKey *tmp = preSharedKey; + + while (bufOffset + sizeof(uint16_t) < bufLen) { + /* Create a linked list node */ + PreSharedKey *node = (PreSharedKey *)BSL_SAL_Calloc(1, sizeof(PreSharedKey)); + if (node == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMALLOC_FAIL; + } + LIST_ADD_AFTER(&tmp->pskNode, &node->pskNode); + tmp = node; + + /* Parse the identityLen length */ + uint16_t identitySize = BSL_ByteToUint16(&buf[bufOffset]); + node->identitySize = identitySize; + bufOffset += sizeof(uint16_t); + + if ((bufOffset + identitySize + sizeof(uint32_t)) > bufLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15146, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ParseIdentities error. bufLen = %d, identitySize = %d.", bufLen, identitySize, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + /* Parse identity */ + node->identity = (uint8_t *)BSL_SAL_Calloc(1u, (node->identitySize + 1) * sizeof(uint8_t)); + if (node->identity == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + (void)memcpy_s(node->identity, node->identitySize + 1, &buf[bufOffset], identitySize); + bufOffset += node->identitySize; + + node->obfuscatedTicketAge = BSL_ByteToUint32(&buf[bufOffset]); + bufOffset += sizeof(uint32_t); + } + + if (bufOffset != bufLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15147, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "IdentityEntry error. bufLen = %d ", bufLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; +} + +void CleanKeyShare(KeyShare *keyShare) +{ + ListHead *node = NULL; + ListHead *tmpNode = NULL; + KeyShare *cur = NULL; + KeyShare *cache = keyShare; + if (cache != NULL) { + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->head)) + { + cur = LIST_ENTRY(node, KeyShare, head); + LIST_REMOVE(node); + BSL_SAL_FREE(cur->keyExchange); + BSL_SAL_FREE(cur); + } + BSL_SAL_FREE(keyShare); + } +} + +/* rfc8446 4.2.8 Clients MUST NOT offer multiple KeyShareEntry values + for the same group. Clients MUST NOT offer any KeyShareEntry values + for groups not listed in the client's "supported_groups" extension. + Servers MAY check for violations of these rules and abort the + handshake with an "illegal_parameter" alert if one is violated. */ +static bool KeyShareGroupAdd(uint16_t *groupSet, uint32_t groupSetCapacity, uint32_t *groupSetSize, uint16_t group) +{ + for (uint32_t i = 0; (i < *groupSetSize) && (i + 1 < groupSetCapacity); i++) { + if (groupSet[i] == group) { + return false; + } + } + groupSet[*groupSetSize] = group; + *groupSetSize = *groupSetSize + 1; + return true; +} + +/** + * @brief Parse KeyShareEntry and create a linked list node, + * @attention The caller needs to pay attention to the function. If the function fails to be returned, the caller + * releases the call. + * + * @param keyShare [OUT] Linked list header + * @param buf [IN] message buffer + * @param bufLen [IN] message length + * + * @return HITLS_SUCCESS parsed successfully. + */ +int32_t ParseKeyShare(KeyShare *keyshare, const uint8_t *buf, uint32_t bufLen, ALERT_Description *alert) +{ + uint32_t bufOffset = 0u; + KeyShare *node = keyshare; + uint16_t *groupSet = (uint16_t *)BSL_SAL_Calloc(bufLen, sizeof(uint8_t)); + if (groupSet == NULL) { + *alert = ALERT_INTERNAL_ERROR; + return HITLS_MEMALLOC_FAIL; + } + uint32_t groupSetSize = 0; + int32_t ret = HITLS_SUCCESS; + while (bufOffset + sizeof(uint16_t) + sizeof(uint16_t) < bufLen) { + KeyShare *tmpNode = (KeyShare *)BSL_SAL_Calloc(1u, sizeof(KeyShare)); + if (tmpNode == NULL) { + *alert = ALERT_INTERNAL_ERROR; + ret = HITLS_MEMALLOC_FAIL; + break; + } + LIST_INIT(&tmpNode->head); + LIST_ADD_AFTER(&node->head, &tmpNode->head); + node = tmpNode; + node->group = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if (!KeyShareGroupAdd(groupSet, bufLen / sizeof(uint16_t), &groupSetSize, node->group)) { + *alert = ALERT_ILLEGAL_PARAMETER; + ret = HTILS_PARSE_DUPLICATED_KEY_SHARE; + break; + } + node->keyExchangeSize = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + /* parse keyExchange */ + if (node->keyExchangeSize == 0 || bufOffset + node->keyExchangeSize > bufLen) { + *alert = ALERT_DECODE_ERROR; + ret = HITLS_PARSE_INVALID_MSG_LEN; + break; + } + node->keyExchange = (uint8_t *)BSL_SAL_Dump(&buf[bufOffset], node->keyExchangeSize); + if (node->keyExchange == NULL) { + *alert = ALERT_INTERNAL_ERROR; + ret = HITLS_MEMALLOC_FAIL; + break; + } + bufOffset += node->keyExchangeSize; + } + BSL_SAL_FREE(groupSet); + if (ret == HITLS_SUCCESS && bufOffset != bufLen) { + *alert = ALERT_DECODE_ERROR; + ret = HITLS_PARSE_INVALID_MSG_LEN; + } + return ret; +} + +// Parse the KeyShare message. +static int32_t ParseClientKeyShare(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + uint32_t bufOffset = 0u; + int32_t ret = HITLS_SUCCESS; + ALERT_Description alert = ALERT_UNKNOWN; + do { + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveKeyShare == true) { + ret = HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + alert = ALERT_ILLEGAL_PARAMETER; + break; + } + if (bufLen < sizeof(uint16_t)) { + ret = HITLS_PARSE_INVALID_MSG_LEN; + alert = ALERT_DECODE_ERROR; + break; + } + uint16_t keyShareLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if (keyShareLen + bufOffset != bufLen) { + ret = HITLS_PARSE_INVALID_MSG_LEN; + alert = ALERT_DECODE_ERROR; + break; + } + /* If the client requests hrr, keyshare can be empty */ + if (keyShareLen == 0) { + break; + } + /** Create the header of the linked list of keyShareEntry */ + msg->extension.content.keyShare = (KeyShare *)BSL_SAL_Calloc(1u, sizeof(KeyShare)); + if (msg->extension.content.keyShare == NULL) { + ret = HITLS_MEMALLOC_FAIL; + alert = ALERT_INTERNAL_ERROR; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15150, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "keyShare malloc fail when parse client keyshare.", 0, 0, 0, 0); + break; + } + LIST_INIT(&msg->extension.content.keyShare->head); + ret = ParseKeyShare(msg->extension.content.keyShare, &buf[bufOffset], keyShareLen, &alert); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15151, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse client key share fail.", 0, 0, 0, 0); + break; + } + } while (false); + msg->extension.flag.haveKeyShare = true; + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, alert); + } + return ret; +} + +// Parse the SupportedVersions message. +static int32_t ParseClientSupportedVersions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* parsed extensions of the same type */ + if (msg->extension.flag.haveSupportedVers == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15152, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ClientSupportedVersions in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15153, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (supported groups) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + /** Obtain the length of supportedVersions */ + uint8_t len = buf[bufOffset]; + bufOffset++; + + if ((len == 0) || ((len % sizeof(uint16_t)) != 0) || (len + bufOffset != bufLen)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15154, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "supportedVersionsSize is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->extension.content.supportedVersions = (uint16_t *)BSL_SAL_Calloc(1u, len); + if (msg->extension.content.supportedVersions == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15155, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "supportedVersions malloc fail when parse extensions msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + + for (uint32_t i = 0; i < len / sizeof(uint16_t); i++) { + msg->extension.content.supportedVersions[i] = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + } + + msg->extension.content.supportedVersionsCount = len / sizeof(uint16_t); + msg->extension.flag.haveSupportedVers = true; + + return HITLS_SUCCESS; +} + +static int32_t ParseServerPreShareKey(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + if (msg->haveSelectedIdentity == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15156, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type pre_shared_key in server hello message is repeated", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen != sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15157, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (pre_shared_key) in server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + uint32_t bufOffset = 0u; + msg->selectedIdentity = BSL_ByteToUint16(&buf[bufOffset]); + msg->haveSelectedIdentity = true; + + return HITLS_SUCCESS; +} +static int32_t ParseServerKeySharePre(TLS_Ctx *ctx, uint32_t bufLen, const ServerHelloMsg *msg) +{ + if (msg->haveKeyShare == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15158, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ServerKeyShare in server hello message is repeated", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15159, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (ServerKeyShare) in server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; +} + +static int32_t ParseServerKeyShare(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + int32_t ret = ParseServerKeySharePre(ctx, bufLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint32_t bufOffset = 0u; + /* parse group */ + msg->keyShare.group = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (bufLen == bufOffset) { + msg->haveKeyShare = true; + return HITLS_SUCCESS; // If there is no subsequent content, the extension is the keyshare of hrr + } + if (bufLen < bufOffset + sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15125, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ParseServerKeyShare error. invalid msg len", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + /* parse keyExchangeSize */ + uint16_t keyExchangeSize = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if ((bufOffset + keyExchangeSize) != bufLen || (keyExchangeSize == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15160, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ParseServerKeyShare error. bufLen = %d, keyExchangeSize = %d.", bufLen, keyExchangeSize, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* parse keyExchange */ + msg->keyShare.keyExchange = (uint8_t *)BSL_SAL_Calloc(keyExchangeSize, sizeof(uint8_t)); + if (msg->keyShare.keyExchange == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + msg->keyShare.keyExchangeSize = keyExchangeSize; + (void)memcpy_s(msg->keyShare.keyExchange, msg->keyShare.keyExchangeSize, &buf[bufOffset], keyExchangeSize); + msg->haveKeyShare = true; + return HITLS_SUCCESS; +} + +int32_t ParseExCookie(const uint8_t *buf, uint32_t bufLen, uint8_t **cookie, uint16_t *cookieLen) +{ + *cookie = NULL; // Initialize the function entry to prevent wild pointers + + uint32_t bufOffset = 0; + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Extract the cookie length */ + uint32_t tmpCookieLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + /* If the cookie length is incorrect, return an error code */ + if (tmpCookieLen != (bufLen - bufOffset) || tmpCookieLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the cookie */ + uint8_t *tmpCookie = BSL_SAL_Dump(&buf[bufOffset], tmpCookieLen); + if (tmpCookie == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15161, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "cookie malloc fail.", 0, 0, + 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + *cookie = tmpCookie; + *cookieLen = tmpCookieLen; + return HITLS_SUCCESS; +} + +static int32_t ParseServerCookie(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + if (msg->haveCookie == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15162, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type cookie in server hello message is repeated", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + int32_t ret = ParseExCookie(buf, bufLen, &msg->cookie, &msg->cookieLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + msg->haveCookie = true; + return HITLS_SUCCESS; +} +// Parse the SupportedVersions message. + +static int32_t ParseServerSupportedVersions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->haveSupportedVersion == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15164, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ServerSupportedVersions in hello message is repeated", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen != sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->supportedVersion = BSL_ByteToUint16(&buf[0]); + msg->haveSupportedVersion = true; + + return HITLS_SUCCESS; +} + +static int32_t ParseBinders(TLS_Ctx *ctx, PreSharedKey *preSharedKey, const uint8_t *buf, uint32_t bufLen) +{ + uint32_t bufOffset = 0u; + ListHead *node = NULL; + ListHead *tmpNode = NULL; + PreSharedKey *cur = NULL; + PreSharedKey *cache = preSharedKey; + + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->pskNode)) + { + cur = LIST_ENTRY(node, PreSharedKey, pskNode); + if (bufLen < bufOffset + sizeof(uint8_t)) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + uint8_t binderLen = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + + if (binderLen > (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15165, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the binder length of handshake message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + cur->binderSize = binderLen; + cur->binder = (uint8_t *)BSL_SAL_Calloc(cur->binderSize, sizeof(uint8_t)); + if (cur->binder == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15166, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse pre_share_key binder malloc fail extensions msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + (void)memcpy_s(cur->binder, cur->binderSize, &buf[bufOffset], binderLen); + bufOffset += binderLen; + } + + if (bufLen != bufOffset) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15167, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (binder) is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} +static int32_t ParseClientPreSharedKeyPre(TLS_Ctx *ctx, uint32_t bufLen, const ClientHelloMsg *msg) +{ + if (msg->extension.flag.havePreShareKey == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15168, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type pre share key in client hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15169, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (pre share key) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; +} + +static int32_t ParseClientPreSharedKey(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + int32_t ret = ParseClientPreSharedKeyPre(ctx, bufLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint32_t bufOffset = 0u; + /* Obtain the length of the pskid list len */ + uint16_t identitiesLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (bufLen <= identitiesLen + bufOffset || identitiesLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15170, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (pre share key) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Create the header of the PskIdentity linked list */ + PreSharedKey *offeredPsks = (PreSharedKey *)BSL_SAL_Calloc(1, sizeof(PreSharedKey)); + if (offeredPsks == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + msg->extension.content.preSharedKey = offeredPsks; + LIST_INIT(&offeredPsks->pskNode); + ret = ParseIdentities(ctx, offeredPsks, &buf[bufOffset], identitiesLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += identitiesLen; + msg->truncateHelloLen = &buf[bufOffset] - ctx->hsCtx->msgBuf; + if (bufLen < sizeof(uint16_t) + bufOffset) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + /* Obtain the length of the binder list len */ + uint16_t bindersLen = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + if (bufLen != bufOffset + bindersLen) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + ret = ParseBinders(ctx, offeredPsks, &buf[bufOffset], bindersLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15171, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse binders extensions msg.", 0, 0, 0, 0); + return ret; + } + msg->extension.flag.havePreShareKey = true; + return HITLS_SUCCESS; +} + +static int32_t ParseClientPskKeyExModes(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.havePskExMode == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15175, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type pskKeyExchangeMode in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15176, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (pskKeyExchangeMode) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + /** Obtain the pskKeyExchangeMode length */ + uint8_t len = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + if (bufLen != bufOffset + len) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->extension.content.keModes = (uint8_t *)BSL_SAL_Calloc(len, sizeof(uint8_t)); + if (msg->extension.content.keModes == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15177, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pskKeyExchangeMode malloc fail when parse extensions msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + for (uint32_t i = 0; i < len; i++) { + msg->extension.content.keModes[i] = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + } + + msg->extension.content.keModesSize = len; + msg->extension.flag.havePskExMode = true; + + return HITLS_SUCCESS; +} + +static int32_t ParseClientCookie(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveCookie == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15178, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type cookie in client hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + int32_t ret = ParseExCookie(buf, bufLen, &msg->extension.content.cookie, + &msg->extension.content.cookieLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + msg->extension.flag.haveCookie = true; + return HITLS_SUCCESS; +} + +static int32_t ParseClientPostHsAuth(TLS_Ctx *ctx, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.havePostHsAuth == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15182, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type post_handshake_auth in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + /* The length of the extended data field of the rfc 8446 "post_handshake_auth" extension is 0. */ + if (bufLen != 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15183, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (post_handshake_auth) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->extension.flag.havePostHsAuth = true; + + return HITLS_SUCCESS; +} + +static int32_t ParseSecRenegoInfo(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint8_t **secRenegoInfo, + uint8_t *secRenegoInfoSize) +{ + /* The message length is not enough to parse secRenegoInfo */ + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15184, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (renegotiation info) in client hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Parse the length of secRenegoInfo */ + uint32_t bufOffset = 0; + uint8_t tmpSize = buf[bufOffset]; + bufOffset++; + + if (tmpSize != (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15185, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the renegotiation info size in the hello messag is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + if (tmpSize == 0) { + return HITLS_SUCCESS; + } + + /* Parse secRenegoInfo */ + uint8_t *tmpInfo = (uint8_t *)BSL_SAL_Dump(&buf[bufOffset], tmpSize); + if (tmpInfo == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15186, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "secRenegoInfo malloc fail when parse renegotiation info.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + + *secRenegoInfo = tmpInfo; + *secRenegoInfoSize = tmpSize; + return HITLS_SUCCESS; +} + +static int32_t ParseClientSecRenegoInfo(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveSecRenego == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15187, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type renegotiation info in client hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + uint8_t secRenegoInfoSize = 0; + uint8_t *secRenegoInfo = NULL; + int32_t ret = ParseSecRenegoInfo(ctx, buf, bufLen, &secRenegoInfo, &secRenegoInfoSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + msg->extension.content.secRenegoInfo = secRenegoInfo; + msg->extension.content.secRenegoInfoSize = secRenegoInfoSize; + msg->extension.flag.haveSecRenego = true; + return HITLS_SUCCESS; +} + +static int32_t ParseClientEncryptThenMac(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + (void)buf; + return ParseEmptyExtension(ctx, HS_EX_TYPE_ENCRYPT_THEN_MAC, bufLen, &msg->extension.flag.haveEncryptThenMac); +} + +static int32_t ParseClientTicket(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + uint8_t *ticket = NULL; /* ticket */ + + /* Parsed extensions of the same type */ + if (msg->extension.flag.haveTicket == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15148, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type tiket externsion in server hello is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen != 0) { + ticket = (uint8_t *)BSL_SAL_Dump(&buf[0], bufLen); + if (ticket == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15149, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse server hello sesionticket message: malloc ticket failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + } + + msg->extension.content.ticket = ticket; + msg->extension.content.ticketSize = bufLen; + msg->extension.flag.haveTicket = true; + return HITLS_SUCCESS; +} +// parses the extension message from client +static int32_t ParseClientExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen, + ClientHelloMsg *msg) +{ + switch (extMsgType) { + case HS_EX_TYPE_SERVER_NAME: + return ParseClientServerName(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_POINT_FORMATS: + return ParseClientPointFormats(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SUPPORTED_GROUPS: + return ParseClientSupportGroups(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_EXTENDED_MASTER_SECRET: + return ParseClientExtMasterSecret(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SIGNATURE_ALGORITHMS: + return ParseClientSignatureAlgorithms(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_APP_LAYER_PROTOCOLS: + return ParseClientAlpnProposeList(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SUPPORTED_VERSIONS: + return ParseClientSupportedVersions(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_PRE_SHARED_KEY: + return ParseClientPreSharedKey(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_PSK_KEY_EXCHANGE_MODES: + return ParseClientPskKeyExModes(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_COOKIE: + return ParseClientCookie(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_POST_HS_AUTH: + return ParseClientPostHsAuth(ctx, extMsgLen, msg); + case HS_EX_TYPE_KEY_SHARE: + return ParseClientKeyShare(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_RENEGOTIATION_INFO: + return ParseClientSecRenegoInfo(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_ENCRYPT_THEN_MAC: + return ParseClientEncryptThenMac(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SESSION_TICKET: + return ParseClientTicket(ctx, buf, extMsgLen, msg); + default: + break; + } + + // Ignore unknown extensions + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15188, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "unknown extension message type:%d len:%lu in client hello message.", extMsgType, extMsgLen, 0, 0); + return HITLS_SUCCESS; +} + +/** + * @brief Parse the extended message type and length. + * + * @param ctx [IN] TLS context + * @param buf [IN] message buffer, starting from the extension type. + * @param bufLen [IN] message length + * @param extMsgType [OUT] Extended message type + * @param extMsgLen [OUT] Extended message length + * + * @retval HITLS_SUCCESS parsed successfully. + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_PARSE_DUPLICATE_EXTENSIVE_MSG Extended message + */ +int32_t ParseExHeader(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint16_t *extMsgType, uint32_t *extMsgLen) +{ + if (bufLen < HS_EX_HEADER_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15189, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the extension len of client hello msg is incorrect", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + uint16_t type = 0u; + uint32_t len = 0u; + /* Obtain the message type */ + type = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + /* Obtain the message length */ + len = BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15190, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "get extension message in hello, type:%d len:%lu.", type, len, 0, 0); + if (len > (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15191, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type:%d len:%lu in hello message is incorrect.", type, len, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Update the extended message type and length */ + *extMsgType = type; + *extMsgLen = len; + + return HITLS_SUCCESS; +} + +int32_t ParseClientExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg) +{ + uint32_t bufOffset = 0u; + int32_t ret = HITLS_SUCCESS; + + /* Parse the extended message from client */ + while (bufOffset < bufLen) { + uint16_t extMsgType = HS_EX_TYPE_END; + uint32_t extMsgLen = 0u; + ret = ParseExHeader(ctx, &buf[bufOffset], bufLen - bufOffset, &extMsgType, &extMsgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += HS_EX_HEADER_LEN; + + ret = ParseClientExBody(ctx, extMsgType, &buf[bufOffset], extMsgLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += extMsgLen; + /* rfc8446 4.2.11. The "pre_shared_key" extension MUST be the last extension in the + ClientHello (this facilitates implementation as described below). + Servers MUST check that it is the last extension and otherwise fail + the handshake with an "illegal_parameter" alert. */ + if (extMsgType == HS_EX_TYPE_PRE_SHARED_KEY && bufOffset != bufLen) { + BSL_ERR_PUSH_ERROR(HTILS_PARSE_PRE_SHARED_KEY_FAILED); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15163, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "psk is not the last extension.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HTILS_PARSE_PRE_SHARED_KEY_FAILED; + } + } + + /* The extended content is the last field of the clientHello message and no other data is allowed. If the parsed + * length is inconsistent with the buffer length, return an error code */ + if (bufOffset != bufLen) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15192, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the extension len of client hello msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} + +void CleanPreShareKey(PreSharedKey *preSharedKey) +{ + ListHead *node = NULL; + ListHead *tmpNode = NULL; + PreSharedKey *cur = NULL; + PreSharedKey *cache = preSharedKey; + if (cache != NULL) { + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->pskNode)) + { + cur = LIST_ENTRY(node, PreSharedKey, pskNode); + LIST_REMOVE(node); + BSL_SAL_FREE(cur->identity); + BSL_SAL_FREE(cur->binder); + BSL_SAL_FREE(cur); + } + BSL_SAL_FREE(preSharedKey); + } +} + +void CleanClientHelloExtension(ClientHelloMsg *msg) +{ + if (msg == NULL) { + return; + } + + /* Release the Client Hello extension message structure */ + BSL_SAL_FREE(msg->extension.content.supportedGroups); + BSL_SAL_FREE(msg->extension.content.pointFormats); + BSL_SAL_FREE(msg->extension.content.signatureAlgorithms); + BSL_SAL_FREE(msg->extension.content.alpnList); + BSL_SAL_FREE(msg->extension.content.supportedVersions); + BSL_SAL_FREE(msg->extension.content.cookie); + BSL_SAL_FREE(msg->extension.content.keModes); + BSL_SAL_FREE(msg->extension.content.serverName); + BSL_SAL_FREE(msg->extension.content.secRenegoInfo); + BSL_SAL_FREE(msg->extension.content.ticket); + + CleanKeyShare(msg->extension.content.keyShare); + msg->extension.content.keyShare = NULL; + CleanPreShareKey(msg->extension.content.preSharedKey); + msg->extension.content.preSharedKey = NULL; + return; +} + +// Parses the point format message sent by the server +static int32_t ParseServerPointFormats(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->havePointFormats == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15193, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type ServerPointFormats in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15194, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length tag (point formats) in server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Extract the length of the point format */ + uint32_t bufOffset = 0; + uint8_t pointFormatsSize = buf[0]; + bufOffset += sizeof(uint8_t); + + /* If the point format length does not match the extended length, or the length is 0, + * return a handshake message error */ + if ((pointFormatsSize != (bufLen - bufOffset)) || (pointFormatsSize == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15195, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (point formats) in server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->pointFormats = BSL_SAL_Calloc(pointFormatsSize, sizeof(uint8_t)); + if (msg->pointFormats == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15196, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pointFormats malloc fail when parse extensions msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + for (uint8_t index = 0; index < pointFormatsSize; index++) { + msg->pointFormats[index] = buf[bufOffset]; + bufOffset += sizeof(uint8_t); + } + + msg->havePointFormats = true; + msg->pointFormatsSize = pointFormatsSize; + + return HITLS_SUCCESS; +} + +// Parses the extended master secret sent by the serve +static int32_t ParseServerExtMasterSecret(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + (void)buf; + /* Parse the empty extended message */ + return ParseEmptyExtension(ctx, HS_EX_TYPE_EXTENDED_MASTER_SECRET, bufLen, &msg->haveExtendedMasterSecret); +} + +static int32_t ParseServerSelectedAlpnProtocol(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->haveSelectedAlpn == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15197, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type selected alpn protocol in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + /* If the message length is incorrect, return an error code */ + if (bufLen < sizeof(uint16_t) + sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15198, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (supported groups) in server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t bufOffset = 0u; + uint16_t selectedAlpnListLen = BSL_ByteToUint16(&buf[bufOffset]) / sizeof(uint8_t); + bufOffset += sizeof(uint16_t); + uint16_t selectedAlpnLen = (uint16_t)(buf[bufOffset] / sizeof(uint8_t)); + bufOffset += sizeof(uint8_t); + + /* If the length of the message does not match the extended length, or the length is 0, return an error code */ + if (((selectedAlpnListLen * sizeof(uint8_t)) != (bufLen - sizeof(uint16_t))) || (selectedAlpnListLen == 0)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15199, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message length (supported groups) in server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + /* According to the protocol rfc7301, The alpn extension returned by server is allowed to contain only one protocol + * name, and returns a handshake message error */ + /* Check whether the listsize of the alpn list returned by the server is anpn size + sizeof(uint8_t) */ + if (selectedAlpnLen != selectedAlpnListLen - sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ALPN_UNRECOGNIZED); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15201, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the number of Protocol in ALPN extensions of server hello message is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_MSG_HANDLE_ALPN_UNRECOGNIZED; + } + + /* The length of bufLen meets: alpnLen | alpn | 0 */ + msg->alpnSelected = (uint8_t *)BSL_SAL_Calloc(selectedAlpnLen + 1, sizeof(uint8_t)); + if (msg->alpnSelected == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15200, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "selected alpn proto malloc fail when parse extensions msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + (void)memcpy_s(msg->alpnSelected, selectedAlpnLen + 1, &buf[bufOffset], selectedAlpnLen); + + msg->alpnSelectedSize = selectedAlpnLen; + msg->haveSelectedAlpn = true; + + return HITLS_SUCCESS; +} + +/** + * @brief server hello ServerName extension item + * + * @param ctx [IN] TLS context + * @param buf [IN] message buffer + * @param bufLen [IN] message length + * @param msg [OUT] Parsed message + * + * @retval HITLS_SUCCESS parsed successfully. + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_PARSE_DUPLICATE_EXTENSIVE_MSG Extended message + */ +static int32_t ParseServerServerName(TLS_Ctx *ctx, uint32_t bufLen, ServerHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->haveServerName == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15202, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type Sever ServerName in hello message is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + /* If the message length is incorrect, return an error code */ + /* rfc6066 + * When the server decides to receive server_name, the server should include an extension of type "server_name" in + * the (extended) server hello. The'extension_data' field for this extension should be empty + */ + if (bufLen != 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15203, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the ServerName length of server hello is incorrect. it should be zero", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + msg->haveServerName = true; + return HITLS_SUCCESS; +} + +static int32_t ParseServerSecRenegoInfo(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + /* Parsed extensions of the same type */ + if (msg->haveSecRenego == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15204, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type renegotiation info in server hello is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + uint8_t secRenegoInfoSize = 0; + uint8_t *secRenegoInfo = NULL; + int32_t ret = ParseSecRenegoInfo(ctx, buf, bufLen, &secRenegoInfo, &secRenegoInfoSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + msg->secRenegoInfo = secRenegoInfo; + msg->secRenegoInfoSize = secRenegoInfoSize; + msg->haveSecRenego = true; + return HITLS_SUCCESS; +} + +static int32_t ParseServerTicket(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + (void)buf; + /* Parsed extensions of the same type */ + if (msg->haveTicket == true) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_DUPLICATE_EXTENDED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15179, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "extension message type tiket externsion in server hello is repeated.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_DUPLICATE_EXTENDED_MSG; + } + + /* The ticket extended data length of server hello can only be empty */ + if (bufLen != 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15965, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the tiket length of server hello is incorrect. it should be zero", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->haveTicket = true; + return HITLS_SUCCESS; +} + +static int32_t ParseServerEncryptThenMac(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + (void)buf; + return ParseEmptyExtension(ctx, HS_EX_TYPE_ENCRYPT_THEN_MAC, bufLen, &msg->haveEncryptThenMac); +} + +/** + * @brief Parses the extended message from server + * + * @param ctx [IN] TLS context + * @param extMsgType [IN] Extended message type + * @param buf [IN] message buffer + * @param extMsgLen [IN] Extended message length + * @param msg [OUT] Structure of the parsed extended message + * + * @retval HITLS_SUCCESS parsed successfully. + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_PARSE_DUPLICATE_EXTENSIVE_MSG Extended message + * @retval HITLS_PARSE_UNSUPPORTED_EXTENSION: unsupported extended field + */ +static int32_t ParseServerExBody(TLS_Ctx *ctx, uint16_t extMsgType, const uint8_t *buf, uint32_t extMsgLen, + ServerHelloMsg *msg) +{ + switch (extMsgType) { + case HS_EX_TYPE_SERVER_NAME: + return ParseServerServerName(ctx, extMsgLen, msg); + case HS_EX_TYPE_POINT_FORMATS: + return ParseServerPointFormats(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_EXTENDED_MASTER_SECRET: + return ParseServerExtMasterSecret(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_APP_LAYER_PROTOCOLS: + return ParseServerSelectedAlpnProtocol(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_KEY_SHARE: + return ParseServerKeyShare(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_PRE_SHARED_KEY: + return ParseServerPreShareKey(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_COOKIE: + return ParseServerCookie(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SUPPORTED_VERSIONS: + return ParseServerSupportedVersions(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_RENEGOTIATION_INFO: + return ParseServerSecRenegoInfo(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SESSION_TICKET: + return ParseServerTicket(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_ENCRYPT_THEN_MAC: + return ParseServerEncryptThenMac(ctx, buf, extMsgLen, msg); + case HS_EX_TYPE_SUPPORTED_GROUPS: + return HITLS_SUCCESS; + default: + break; + } + + // You need to send an alert when an unknown extended field is encountered + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORTED_EXTENSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15205, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unknown extension message type:%d len:%lu in server hello message.", extMsgType, extMsgLen, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + return HITLS_PARSE_UNSUPPORTED_EXTENSION; +} + +int32_t ParseServerExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + /* Initialize the message parsing length */ + uint32_t bufOffset = 0u; + int32_t ret = HITLS_SUCCESS; + + /* Parse the extended message from server */ + while (bufOffset < bufLen) { + uint16_t extMsgType = HS_EX_TYPE_END; + uint32_t extMsgLen = 0u; + ret = ParseExHeader(ctx, &buf[bufOffset], bufLen - bufOffset, &extMsgType, &extMsgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += HS_EX_HEADER_LEN; + + ret = ParseServerExBody(ctx, extMsgType, &buf[bufOffset], extMsgLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += extMsgLen; + } + + // The extended content is the last field of the serverHello message. No other data should follow. + if (bufOffset != bufLen) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15206, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the extension len of server hello msg is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + return HITLS_SUCCESS; +} + +void CleanServerHelloExtension(ServerHelloMsg *msg) +{ + if (msg == NULL) { + return; + } + + BSL_SAL_FREE(msg->pointFormats); + BSL_SAL_FREE(msg->alpnSelected); + BSL_SAL_FREE(msg->secRenegoInfo); + BSL_SAL_FREE(msg->cookie); + BSL_SAL_FREE(msg->keyShare.keyExchange); + return; +} diff --git a/tls/handshake/parse/src/parse_extensions.h b/tls/handshake/parse/src/parse_extensions.h new file mode 100644 index 00000000..a005fd75 --- /dev/null +++ b/tls/handshake/parse/src/parse_extensions.h @@ -0,0 +1,109 @@ +/* + * 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 PARSE_EXTENSIONS_H +#define PARSE_EXTENSIONS_H + +#include +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Parse Client Hello extension + * + * @attention The input parameter pointer can't be NULL + * If parsing fails, the invoker releases the allocated memory + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer, starting from the extension type + * @param bufLen [IN] Message length + * @param msg [OUT] Parsed message + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + * @retval HITLS_PARSE_DUPLICATE_EXTENDED_MSG Extension duplicated + */ +int32_t ParseClientExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ClientHelloMsg *msg); + +/** + * @brief Release the buffer in the Client Hello extension structure + * + * @param msg [IN] Message structure + */ +void CleanClientHelloExtension(ClientHelloMsg *msg); + +/** + * @brief Parse server hello extension + * + * @attention The input parameter pointer can't be NULL + * If the parsing fails, the invoker releases the allocated memory + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer, starting from the extension type + * @param bufLen [IN] Message length + * @param msg [OUT] Parsed message + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + * @retval HITLS_PARSE_DUPLICATE_EXTENDED_MSG Extension duplicated + * @retval HITLS_PARSE_UNSUPPORTED_EXTENSION Unsupported extension + */ +int32_t ParseServerExtension(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg); +/** + * @brief Parse extension type and length + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer, starting from the extension type + * @param bufLen [IN] Message length + * @param extMsgType [OUT] Extension type + * @param extMsgLen [OUT] Extension length + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + * @retval HITLS_PARSE_DUPLICATE_EXTENDED_MSG Extension duplicated + */ +int32_t ParseExHeader(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, uint16_t *extMsgType, uint32_t *extMsgLen); +/** + * @brief Release the buffer in the Server Hello extension structure + * + * @param msg [IN] Message structure + */ +void CleanServerHelloExtension(ServerHelloMsg *msg); +/** + * @brief Parse empty extension + * + * @param ctx [IN] TLS context + * @param extMsgType [IN] Extension type + * @param extMsgLen [IN] Extension length + * @param haveExtension [OUT] Indicates whether there are extensions + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_PARSE_DUPLICATE_EXTENDED_MSG Extension duplicated + */ +int32_t ParseEmptyExtension(TLS_Ctx *ctx, uint16_t extMsgType, uint32_t extMsgLen, bool *haveExtension); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PARSE_EXTENSIONS_H */ diff --git a/tls/handshake/parse/src/parse_finished.c b/tls/handshake/parse/src/parse_finished.c new file mode 100644 index 00000000..033b6ddd --- /dev/null +++ b/tls/handshake/parse/src/parse_finished.c @@ -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. + */ + +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hs_msg.h" +#include "parse_msg.h" + +int32_t ParseFinished(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + /* if the cache length is 0, return an error code */ + if (bufLen == 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15830, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse finished message failed, bufLen could not be zero.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + FinishedMsg *msg = &hsMsg->body.finished; + + /* get the data of verify */ + msg->verifyData = BSL_SAL_Malloc(bufLen); + if (msg->verifyData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15831, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verifyData malloc fail when parse finished msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + if (memcpy_s(msg->verifyData, bufLen, buf, bufLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15832, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verifyData copy fail when parse finished msg.", 0, 0, 0, 0); + BSL_SAL_FREE(msg->verifyData); + return HITLS_MEMCPY_FAIL; + } + msg->verifyDataSize = bufLen; + + return HITLS_SUCCESS; +} + +void CleanFinished(FinishedMsg *msg) +{ + if (msg != NULL) { + BSL_SAL_FREE(msg->verifyData); + } + return; +} diff --git a/tls/handshake/parse/src/parse_key_update.c b/tls/handshake/parse/src/parse_key_update.c new file mode 100644 index 00000000..0f455fc6 --- /dev/null +++ b/tls/handshake/parse/src/parse_key_update.c @@ -0,0 +1,41 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_msg.h" + +int32_t ParseKeyUpdate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + uint32_t bufOffset = 0u; + + /* if the cache length is not 1, return an error code */ + if (bufLen != 1u) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15868, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse keyUpdate message failed, bufLen should be one ,but actually is %d.", bufLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + KeyUpdateMsg *msg = &hsMsg->body.keyUpdate; + msg->requestUpdate = buf[bufOffset]; + + return HITLS_SUCCESS; +} diff --git a/tls/handshake/parse/src/parse_msg.h b/tls/handshake/parse/src/parse_msg.h new file mode 100644 index 00000000..2c0d48ca --- /dev/null +++ b/tls/handshake/parse/src/parse_msg.h @@ -0,0 +1,288 @@ +/* + * 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 PARSE_MSG_H +#define PARSE_MSG_H + +#include +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Parse client Hello message + * + * @param ctx [IN] TLS context + * @param data [IN] Message buffer + * @param len [IN] Message buffer length + * @param hsMsg [OUT] Parsed message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_PARSE_DUPLICATE_EXTENDED_MSG Extension duplicated + */ +int32_t ParseClientHello(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg); + +/** + * @brief Parse Server Hello message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_PARSE_DUPLICATE_EXTENDED_MSG Extension duplicated + */ +int32_t ParseServerHello(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); + +/** + * @brief Parse TLS 1.3 EncryptedExtensions message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @return HITLS_SUCCESS + * HITLS_INVALID_PARAMETERS The input parameter is a null pointer + * HITLS_ALERT_FATAL Message error + * HITLS_MEMALLOC_FAIL Memory allocated failed + */ +int32_t ParseEncryptedExtensions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); + +/** + * @brief Parse certificate message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLSPARSE_CERT_ERR Failed to parse the certificate + * @retval HITLSPARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseCertificate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); +/** + * @brief Parse TLS 1.3 certificate message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLSPARSE_CERT_ERR Failed to parse the certificate + * @retval HITLSPARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t Tls13ParseCertificate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); +/** + * @brief Parse Server Key Exchange message + * + * @param ctx [IN] TLS context + * @param data [IN] Message buffer + * @param len [IN] Message buffer length + * @param hsMsg [OUT] Parsed message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE Unsupported ECC curve type + * @retval HITLS_PARSE_ECDH_PUBKEY_ERR Failed to parse the ECDH public key + * @retval HITLS_PARSE_ECDH_SIGN_ERR Failed to parse the ECDH signature + * @retval HITLS_PARSE_UNSUPPORT_KX_ALG Unsupported key exchange algorithm + */ +int32_t ParseServerKeyExchange(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg); + +/** + * @brief Parse certificate request message, which is applicable to TLS1.2/DTLS/TLS1.3 protocols + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + */ +int32_t ParseCertificateRequest(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); +/** + * @brief Parse TLS1.3 certificate request message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + */ +int32_t Tls13ParseCertificateRequest(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); +/** + * @brief Parse Client Key Exchange message + * + * @param ctx [IN] TLS context + * @param data [IN] Message buffer + * @param len [IN] Message buffer length + * @param hsMsg [OUT] Parsed Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseClientKeyExchange(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg); + +/** + * @brief Parse Certificate Verify message + * + * @param ctx [IN] TLS context + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * @param hsMsg [OUT] Message structure + * + * @retval HITLS_SUCCESS + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + */ +int32_t ParseCertificateVerify(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); + +/** + * @brief Parse Finished message + * + * @param ctx [IN] TLS context + * @param hsMsg [OUT] Message structure + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseFinished(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); +/** + * @brief Parse KeyUpdate message + * + * @param ctx [IN] TLS context + * @param hsMsg [OUT] Message structure + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseKeyUpdate(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); + +/** + * @brief Parse new sessionticket message + * + * @param ctx [IN] TLS context + * @param hsMsg [OUT] Message structure + * @param buf [IN] Message buffer + * @param bufLen [IN] Maximum message length + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect + */ +int32_t ParseNewSessionTicket(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg); + +/** + * @brief Clear the memory allocated in the Client Hello message structure + * + * @param msg [IN] Message structure + */ +void CleanClientHello(ClientHelloMsg *msg); + +/** + * @brief Clear the memory allocated in the Server Hello message structure + * + * @param msg [IN] Message structure + */ +void CleanServerHello(ServerHelloMsg *msg); + +/** + * @brief Clear the memory allocated in the EncryptedExtensions message structure + * + * @param msg [IN] Message structure + */ +void CleanEncryptedExtensions(EncryptedExtensions *msg); +/** + * @brief Clear the memory allocated in the certificate message structure + * + * @param msg [IN] Message structure + */ +void CleanCertificate(CertificateMsg *msg); + +/** + * @brief Clear the memory allocated in the ServerKeyExchangeMsg message structure + * + * @param msg [IN] Message structure + */ +void CleanServerKeyExchange(ServerKeyExchangeMsg *msg); + +/** + * @brief Clear the memory allocated in the Certificate Request message structure + * + * @param msg [IN] Message structure + */ +void CleanCertificateRequest(CertificateRequestMsg *msg); + +/** + * @brief Clear the memory allocated in the Client KeyExchange message structure + * + * @param msg [IN] Message structure + */ +void CleanClientKeyExchange(ClientKeyExchangeMsg *msg); + +/** + * @brief Clear the memory allocated in the Certificate Verify message structure + * + * @param msg [IN] Message structure + */ +void CleanCertificateVerify(CertificateVerifyMsg *msg); + +/** + * @brief Clear the memory allocated in the NewSessionTicket message structure + * + * @param msg [IN] Message structure + */ +void CleanNewSessionTicket(NewSessionTicketMsg *msg); + +/** + * @brief Clear the memory allocated in the Finished message structure + * + * @param msg [IN] Message structure + */ +void CleanFinished(FinishedMsg *msg); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end PARSE_MSG_H */ \ No newline at end of file diff --git a/tls/handshake/parse/src/parse_new_sesion_ticket.c b/tls/handshake/parse/src/parse_new_sesion_ticket.c new file mode 100644 index 00000000..27c8101b --- /dev/null +++ b/tls/handshake/parse/src/parse_new_sesion_ticket.c @@ -0,0 +1,169 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_msg.h" +#include "parse_msg.h" + +static int32_t ParseTicketNonce(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, NewSessionTicketMsg *msg) +{ + uint32_t ticketNonceSize; + uint8_t *ticketNonce = NULL; + uint32_t bufOffset = 0u; + + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + ticketNonceSize = (uint32_t)buf[bufOffset]; + bufOffset += sizeof(uint8_t); + + if (ticketNonceSize == 0 || (bufLen < (bufOffset + ticketNonceSize))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + ticketNonce = (uint8_t *)BSL_SAL_Dump(&buf[bufOffset], ticketNonceSize); + if (ticketNonce == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + + msg->ticketNonceSize = ticketNonceSize; + msg->ticketNonce = ticketNonce; + return HITLS_SUCCESS; +} + +static int32_t ParseTicket(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, NewSessionTicketMsg *msg) +{ + uint32_t ticketSize; /* length of ticket */ + uint8_t *ticket = NULL; /* ticket */ + uint32_t bufOffset = 0u; + bool isTls13 = (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13); + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16012, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse sesionticket message failed, bufLen %u.", bufLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + ticketSize = (uint32_t)BSL_ByteToUint16(&buf[bufOffset]); + bufOffset += sizeof(uint16_t); + + /* TLS1.3 does not allow the ticket length to be 0 */ + if ((isTls13 && (ticketSize == 0 || bufLen < (ticketSize + bufOffset))) || + (!isTls13 && (bufLen != (ticketSize + bufOffset)))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15967, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse sesionticket message failed, bufLen %u, ticket size %u.", bufLen, ticketSize, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* rfc5077 3.3 + If the server determines that it does not want to include a ticket after including the SessionTicket extension + in the ServerHello, it sends a zero-length ticket in the NewSessionTicket handshake message */ + if (ticketSize != 0) { + ticket = (uint8_t *)BSL_SAL_Dump(&buf[bufOffset], ticketSize); + if (ticket == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15968, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse sesionticket message failed: malloc ticket failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + } + + msg->ticketSize = ticketSize; + msg->ticket = ticket; + return HITLS_SUCCESS; +} + +int32_t ParseNewSessionTicket(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + int32_t ret; + uint32_t ticketLifetimeHint; /* unit of the ticket timeout interval is second */ + NewSessionTicketMsg *msg = &hsMsg->body.newSessionTicket; + + uint32_t bufOffset = 0u; + + if (bufLen < sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15966, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse sesionticket message failed, bufLen is %u.", bufLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + ticketLifetimeHint = BSL_ByteToUint32(&buf[bufOffset]); + bufOffset += sizeof(uint32_t); + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + if (bufLen < bufOffset + sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16013, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse sesionticket message failed, bufLen %u.", bufLen, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + msg->ticketAgeAdd = BSL_ByteToUint32(&buf[bufOffset]); + bufOffset += sizeof(uint32_t); + + ret = ParseTicketNonce(ctx, &buf[bufOffset], bufLen - bufOffset, msg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse sesionticket message failed: parse ticket nonce failed.", 0, 0, 0, 0); + return ret; + } + bufOffset += sizeof(uint8_t) + msg->ticketNonceSize; + } + + ret = ParseTicket(ctx, &buf[bufOffset], bufLen - bufOffset, msg); + if (ret != HITLS_SUCCESS) { + CleanNewSessionTicket(msg); + return ret; + } + + /* TLS1.3 extension is not supported */ + msg->ticketLifetimeHint = ticketLifetimeHint; + return HITLS_SUCCESS; +} + +void CleanNewSessionTicket(NewSessionTicketMsg *msg) +{ + if (msg == NULL) { + return; + } + + BSL_SAL_FREE(msg->ticketNonce); + BSL_SAL_FREE(msg->ticket); + msg->ticketSize = 0; + msg->ticketNonceSize = 0; + return; +} diff --git a/tls/handshake/parse/src/parse_server_hello.c b/tls/handshake/parse/src/parse_server_hello.c new file mode 100644 index 00000000..2dd0cf38 --- /dev/null +++ b/tls/handshake/parse/src/parse_server_hello.c @@ -0,0 +1,166 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hs_msg.h" +#include "parse_common.h" +#include "parse_extensions.h" +#include "parse_msg.h" + +static int32_t ParseServerHelloCipherSuite(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15785, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the message length of server hello is not enough for cipher suite.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Parse the cipher suite */ + msg->cipherSuite = BSL_ByteToUint16(buf); + + return HITLS_SUCCESS; +} + +static int32_t ParseServerHelloCompressionMethod(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen) +{ + if (bufLen < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15786, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the message length of server hello is not enough for compression method.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + if (buf[0] != 0u) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_COMPRESSION_METHOD_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15787, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the TLS client is not support compression format.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_COMPRESSION_METHOD_ERR; + } + + return HITLS_SUCCESS; +} + +static int32_t ParseServerHelloExtensions(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, ServerHelloMsg *msg) +{ + const uint8_t *msgBuf = buf; + uint32_t bufOffset = 0; + + if (bufLen < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15788, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the external message length of handshake message (server hello) is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + /* Obtain the length of the extended message */ + uint16_t exMsgLen = BSL_ByteToUint16(&msgBuf[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (exMsgLen != (bufLen - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15789, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the external message length of handshake message (server hello) is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + if (exMsgLen == 0u) { + return HITLS_SUCCESS; + } + + return ParseServerExtension(ctx, &msgBuf[bufOffset], exMsgLen, msg); +} + +int32_t ParseServerHello(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg) +{ + int32_t ret = HITLS_SUCCESS; + ServerHelloMsg *msg = &hsMsg->body.serverHello; + const uint8_t *msgBuf = buf; + uint32_t bufOffset = 0; + uint32_t readLen = 0; + + ret = ParseVersion(ctx, msgBuf, bufLen, &msg->version); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += sizeof(uint16_t); + + ret = ParseRandom(ctx, &msgBuf[bufOffset], bufLen - bufOffset, msg->randomValue, HS_RANDOM_SIZE); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += HS_RANDOM_SIZE; + + ret = ParseSessionId(ctx, &msgBuf[bufOffset], bufLen - bufOffset, &msg->sessionId, &msg->sessionIdSize, &readLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* Update the buffer offset length */ + bufOffset += readLen; + + ret = ParseServerHelloCipherSuite(ctx, &msgBuf[bufOffset], bufLen - bufOffset, msg); + if (ret != HITLS_SUCCESS) { + CleanServerHello(msg); + return ret; + } + /* Update the buffer offset length */ + bufOffset += sizeof(uint16_t); + + ret = ParseServerHelloCompressionMethod(ctx, &msgBuf[bufOffset], bufLen - bufOffset); + if (ret != HITLS_SUCCESS) { + CleanServerHello(msg); + return ret; + } + /* Update the buffer offset length */ + bufOffset += sizeof(uint8_t); + + /* If the buf length is equal to the offset length, return HITLS_SUCCESS. */ + if (bufLen == bufOffset) { + // ServerHello is optionally followed by extension data + return HITLS_SUCCESS; + } + + ret = ParseServerHelloExtensions(ctx, &msgBuf[bufOffset], bufLen - bufOffset, msg); + if (ret != HITLS_SUCCESS) { + CleanServerHello(msg); + } + + return ret; +} + +void CleanServerHello(ServerHelloMsg *msg) +{ + if (msg == NULL) { + return; + } + + BSL_SAL_FREE(msg->sessionId); + + CleanServerHelloExtension(msg); + + return; +} diff --git a/tls/handshake/parse/src/parse_server_key_exchange.c b/tls/handshake/parse/src/parse_server_key_exchange.c new file mode 100644 index 00000000..2db4fb70 --- /dev/null +++ b/tls/handshake/parse/src/parse_server_key_exchange.c @@ -0,0 +1,766 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" +#include "hitls_config.h" +#include "tls_config.h" +#include "cert_method.h" +#include "cert.h" +#include "cipher_suite.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "parse_msg.h" + +int32_t ParseEcdhNamedCurve(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, uint16_t *namedCurve, uint32_t *useLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15291, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server keyExMsg is incorrect when parse named curve.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + *namedCurve = BSL_ByteToUint16(data); + *useLen = sizeof(uint16_t); + + return HITLS_SUCCESS; +} + +int32_t ParseEcParameters(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ServerEcdh *ecdh, uint32_t *useLen) +{ + if (len < (sizeof(uint8_t))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15292, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server keyExMsg is incorrect when parse curve type.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + int32_t ret; + uint32_t bufOffset = 0; + HITLS_ECCurveType curveType = data[bufOffset]; + bufOffset += sizeof(uint8_t); + + /* In the TLCP, this content can choose not to be sent. */ + if (curveType == HITLS_EC_CURVE_TYPE_NAMED_CURVE) { + uint16_t namedCurve = 0; + uint32_t offset = 0; + ret = ParseEcdhNamedCurve(ctx, &data[bufOffset], len - bufOffset, &namedCurve, &offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += offset; + ecdh->ecPara.param.namedcurve = namedCurve; + } else { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15293, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unsupport curve type when parse server key exchange msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE; + } + + ecdh->ecPara.type = curveType; + *useLen = bufOffset; + + return HITLS_SUCCESS; +} + +/** + * @brief Parse the p or g parameter in the DHE kx message. + * + * @param ctx [IN] TLS context + * @param data [IN] message buffer + * @param len [IN] message buffer length + * @param paraLen [OUT] Parsed parameter length + * @param useLen [OUT] Parsed length + * + * @return Return the applied parameter memory. If the parameter memory is NULL, the parsing fails. + */ +uint8_t *ParseDhePara(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, uint16_t *paraLen, uint32_t *useLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15294, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server keyExMsg is incorrect when parse dhe para.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + uint32_t bufOffset = 0; + uint16_t tmpParaLen = BSL_ByteToUint16(&data[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (tmpParaLen > (len - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15295, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of dhe para is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + if (tmpParaLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15296, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of dhe para is 0.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return NULL; + } + + uint8_t *dhePara = (uint8_t *)BSL_SAL_Dump(&data[bufOffset], tmpParaLen); + if (dhePara == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15297, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dhePara malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + return NULL; + } + + bufOffset += tmpParaLen; + *useLen = bufOffset; + *paraLen = tmpParaLen; + return dhePara; +} + +int32_t ParseEcdhePublicKey(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ServerEcdh *ecdh, uint32_t *useLen) +{ + if (len < sizeof(uint8_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15298, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse ecdhe server pubkey length error, remain len = %u, less than one byte.", len, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint32_t offset = 0; + uint32_t pubKeySize = data[offset]; + offset += sizeof(uint8_t); + + if (pubKeySize > (len - offset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15299, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check ecdhe server pubkey length error, pubkey len = %u, remain len = %u.", + pubKeySize, len - offset, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + ecdh->ecPara.param.namedcurve = HITLS_EC_GROUP_SM2; + } + + if ((ecdh->ecPara.type == HITLS_EC_CURVE_TYPE_NAMED_CURVE) && + (pubKeySize != HS_GetNamedCurvePubkeyLen(ecdh->ecPara.param.namedcurve))) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_ECDH_PUBKEY_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15300, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check ecdhe server pubkey length error, curve id = %u, pubkey len = %u.", + ecdh->ecPara.param.namedcurve, pubKeySize, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_ECDH_PUBKEY_ERR; + } + + uint8_t *pubKey = BSL_SAL_Malloc(pubKeySize); + if (pubKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15301, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubKey malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(pubKey, pubKeySize, &data[offset], pubKeySize); + offset += pubKeySize; + + ecdh->pubKey = pubKey; + ecdh->pubKeySize = pubKeySize; + *useLen = offset; + return HITLS_SUCCESS; +} + +// Parse the public key in the Kx message of the DHE server. +uint8_t *ParseDhePublicKey(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, uint32_t *pubKeySize, uint32_t *useLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15302, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse dhe server pubkey length error, remain len = %u, less than one byte.", len, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + uint32_t bufOffset = 0; + uint32_t msgPubKeySize = BSL_ByteToUint16(&data[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (msgPubKeySize > (len - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15303, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server kx pubKeySize is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + if (msgPubKeySize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15304, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server kx pubKeySize is 0.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return NULL; + } + + uint8_t *pubKey = BSL_SAL_Malloc(msgPubKeySize); + if (pubKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15305, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pubKey malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + return NULL; + } + (void)memcpy_s(pubKey, msgPubKeySize, &data[bufOffset], msgPubKeySize); + bufOffset += msgPubKeySize; + *useLen = bufOffset; + *pubKeySize = msgPubKeySize; + + return pubKey; +} + +// Parse SignAlgorithm in the kx message. +int32_t ParseSignAlgorithm(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, uint16_t *signAlg, uint32_t *useLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15306, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server keyExMsg is incorrect when parse signAlgorithm.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + + uint16_t signScheme = BSL_ByteToUint16(data); + uint32_t i; + /* If the client_hello message contains the signature_algorithms extension, the server_key_exchange message must use + * the signature algorithm in the extension. */ + for (i = 0; i < ctx->config.tlsConfig.signAlgorithmsSize; i++) { + if (ctx->config.tlsConfig.signAlgorithms[i] == signScheme) { + break; + } + } + if (i == ctx->config.tlsConfig.signAlgorithmsSize) { + /* Handshake failed because it is not an extended signature algorithm. */ + BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15307, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check server key exchange signature algo fail: 0x%x is not included in client hello.", + signScheme, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_PARSE_UNSUPPORT_SIGN_ALG; + } + + *signAlg = signScheme; + *useLen = sizeof(uint16_t); + + return HITLS_SUCCESS; +} + +// Parse the signature in the ECDHE kx message. +uint8_t *ParseSignature(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, uint16_t *signSize, uint32_t *useLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15308, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server keyExMsg is incorrect when parse signature.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + uint32_t bufOffset = 0; + uint16_t tmpSignSize = BSL_ByteToUint16(&data[bufOffset]); + bufOffset += sizeof(uint16_t); + + if (tmpSignSize != (len - bufOffset)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15309, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server signSize is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return NULL; + } + + if (tmpSignSize == 0) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15310, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length of server signSize is 0.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return NULL; + } + + uint8_t *signData = BSL_SAL_Malloc(tmpSignSize); + if (signData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15311, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "signData malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + return NULL; + } + (void)memcpy_s(signData, tmpSignSize, &data[bufOffset], tmpSignSize); + bufOffset += tmpSignSize; + *useLen = bufOffset; + *signSize = tmpSignSize; + + return signData; +} + +static void GetServerKeyExSignParam(const ServerKeyExchangeMsg *msg, + CERT_SignParam *signParam, HITLS_SignHashAlgo *signScheme) +{ + if (msg->keyExType == HITLS_KEY_EXCH_ECDHE) { + *signScheme = msg->keyEx.ecdh.signAlgorithm; + signParam->sign = msg->keyEx.ecdh.signData; + signParam->signLen = msg->keyEx.ecdh.signSize; + } else if (msg->keyExType == HITLS_KEY_EXCH_DHE) { + *signScheme = msg->keyEx.dh.signAlgorithm; + signParam->sign = msg->keyEx.dh.signData; + signParam->signLen = msg->keyEx.dh.signSize; + } + + return; +} + +int32_t VerifySignature(TLS_Ctx *ctx, const uint8_t *kxData, uint32_t kxDataLen, ServerKeyExchangeMsg *msg) +{ + CERT_SignParam signParam = {0}; + HITLS_SignHashAlgo signScheme = 0; + + GetServerKeyExSignParam(msg, &signParam, &signScheme); + + /* Obtain the signature algorithm and hash algorithm */ + if (!CFG_GetSignParamBySchemes(ctx->negotiatedInfo.version, signScheme, &signParam.signAlgo, &signParam.hashAlgo)) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_GET_SIGN_PARA_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15312, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get sign param fail when parse server key exchange msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_PARSE_GET_SIGN_PARA_ERR; + } + + /* Obtain all signature data (random number + server kx content). */ + signParam.data = HS_PrepareSignData(ctx, kxData, kxDataLen, &signParam.dataLen); + if (signParam.data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15313, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "data malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + + CERT_Pair *peerCert = ctx->hsCtx->peerCert; + if (peerCert == NULL) { + BSL_SAL_FREE(signParam.data); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_CERTIFICATE_REQUIRED); + return HITLS_PARSE_VERIFY_SIGN_FAIL; + } + + HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(peerCert); + HITLS_CERT_Key *pubkey = NULL; + int32_t ret = SAL_CERT_X509Ctrl(&(ctx->config.tlsConfig), cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(signParam.data); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = SAL_CERT_VerifySign(ctx, pubkey, &signParam); + SAL_CERT_KeyFree(ctx->config.tlsConfig.certMgrCtx, pubkey); + BSL_SAL_FREE(signParam.data); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_VERIFY_SIGN_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15314, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify signature fail when parse server key exchange msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + return HITLS_PARSE_VERIFY_SIGN_FAIL; + } + return HITLS_SUCCESS; +} + +static int32_t ParseEcParametersWrapper(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, + ServerEcdh *ecdh, uint32_t *useLen) +{ + int32_t ret = ParseEcParameters(ctx, data, len, ecdh, useLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15315, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse ecdhe curve type fail.", 0, 0, 0, 0); + return ret; + } + return HITLS_SUCCESS; +} + +int32_t ParseEcdhePublicKeyWrapper(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ServerEcdh *ecdh, uint32_t *useLen) +{ + int32_t ret = ParseEcdhePublicKey(ctx, data, len, ecdh, useLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15316, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse ecdhe public key fail.", 0, 0, 0, 0); + return ret; + } + return HITLS_SUCCESS; +} + +/** + * @brief Parse the server ecdh message. + * + * @param ctx [IN] TLS context + * @param data [IN] message buffer + * @param len [IN] message buffer length + * @param msg [OUT] Parsed message structure + * + * @retval HITLS_SUCCESS Parsing succeeded. + * @retval HITLS_PARSE_INVALID_MSG_LEN The message length is incorrect. + * @retval HITLS_PARSE_UNSUPPORT_KX_CURVE_TYPE Unsupported ECC curve type + * @retval HITLS_PARSE_ECDH_PUBKEY_ERR Failed to parse the ECDH public key. + * @retval HITLS_PARSE_ECDH_SIGN_ERR Failed to parse the EDH signature. + * @retval HITLS_PARSE_GET_SIGN_PARA_ERR Failed to obtain the signature algorithm and hash algorithm. + * @retval HITLS_PARSE_VERIFY_SIGN_FAIL Failed to verify the signature. + */ +static int32_t ParseServerEcdhe(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ServerKeyExchangeMsg *msg) +{ + uint32_t useLen = 0; + uint32_t bufOffset = 0; + + /* Parse the EC parameter in the ECDH message on the server */ + int32_t ret = ParseEcParametersWrapper(ctx, data, len, &msg->keyEx.ecdh, &useLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += useLen; + + /* Parse DH public key from peer */ + ret = ParseEcdhePublicKeyWrapper(ctx, &data[bufOffset], len - bufOffset, &msg->keyEx.ecdh, &useLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + bufOffset += useLen; + + /* ECDHE_PSK and ANON_ECDHE key exchange are not signed */ + if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_ECDHE_PSK || + ctx->negotiatedInfo.cipherSuiteInfo.authAlg == HITLS_AUTH_NULL) { + if (len != bufOffset) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_INVALID_MSG_LEN); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15323, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse serverkeyEx signature failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_PARSE_INVALID_MSG_LEN; + } + return HITLS_SUCCESS; + } + + uint32_t keyExDataLen = bufOffset; + uint16_t signAlgorithm = ctx->negotiatedInfo.cipherSuiteInfo.signScheme; + + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + ret = ParseSignAlgorithm(ctx, &data[bufOffset], len - bufOffset, &signAlgorithm, &useLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15317, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse ecdhe sign algorithm fail.", 0, 0, 0, 0); + return ret; + } + bufOffset += useLen; + } + + msg->keyEx.ecdh.signAlgorithm = signAlgorithm; + + uint16_t signSize = 0; + uint8_t *signData = ParseSignature(ctx, &data[bufOffset], len - bufOffset, &signSize, &useLen); + if (signData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PARSE_ECDH_SIGN_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15318, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse ecdhe signature fail.", 0, 0, 0, 0); + return HITLS_PARSE_ECDH_SIGN_ERR; + } + msg->keyEx.ecdh.signData = signData; + msg->keyEx.ecdh.signSize = signSize; + + ret = VerifySignature(ctx, data, keyExDataLen, msg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15319, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify signature fail when parse server key exchange msg.", 0, 0, 0, 0); + return ret; + } + + ctx->peerInfo.peerSignHashAlg = signAlgorithm; + return HITLS_SUCCESS; +} + +static uint8_t *ParseDheParaPWithLog(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, + uint16_t *paraLen, uint32_t *useLen) +{ + uint8_t *ret = ParseDhePara(ctx, data, len, paraLen, useLen); + if (ret == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15320, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "p param malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + } + return ret; +} + +static uint8_t *ParseDheParaGWithLog(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, + uint16_t *paraLen, uint32_t *useLen) +{ + uint8_t *ret = ParseDhePara(ctx, data, len, paraLen, useLen); + if (ret == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15321, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "g param malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + } + return ret; +} + +static int32_t ParseServerDhe(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, ServerKeyExchangeMsg *msg) +{ + int32_t ret; + uint32_t useLen, offset = 0u; + ServerDh *dh = &msg->keyEx.dh; + + dh->p = ParseDheParaPWithLog(ctx, data, len, &dh->plen, &useLen); + if (dh->p == NULL) { + return HITLS_PARSE_DH_P_ERR; + } + offset += useLen; + + dh->g = ParseDheParaGWithLog(ctx, &data[offset], len - offset, &dh->glen, &useLen); + if (dh->g == NULL) { + return HITLS_PARSE_DH_G_ERR; + } + offset += useLen; + + /* Parse DH public key from peer */ + dh->pubkey = ParseDhePublicKey(ctx, &data[offset], len - offset, &dh->pubKeyLen, &useLen); + if (dh->pubkey == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15322, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse dh public key fail.", 0, 0, 0, 0); + return HITLS_PARSE_DH_PUBKEY_ERR; + } + offset += useLen; + + /* DHE_PSK, ANON_DHE key exchange is not signed */ + if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE_PSK || + ctx->negotiatedInfo.cipherSuiteInfo.authAlg == HITLS_AUTH_NULL) { + return HITLS_SUCCESS; + } + + uint32_t kxDataLen = offset; + + dh->signAlgorithm = ctx->negotiatedInfo.cipherSuiteInfo.signScheme; + ret = ParseSignAlgorithm(ctx, &data[offset], len - offset, &dh->signAlgorithm, &useLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15323, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse dh sign algorithm fail.", 0, 0, 0, 0); + return ret; + } + offset += useLen; + + dh->signData = ParseSignature(ctx, &data[offset], len - offset, &dh->signSize, &useLen); + if (dh->signData == NULL) { + return HITLS_PARSE_DH_SIGN_ERR; + } + + ret = VerifySignature(ctx, data, kxDataLen, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ctx->peerInfo.peerSignHashAlg = dh->signAlgorithm; + return HITLS_SUCCESS; +} + +/* In the case of psk negotiation, if ServerKeyExchange is received, the length of the identity hint must be parseed, + * but the length may be empty */ +static int32_t ParseServerIdentityHint( + const uint8_t *data, uint32_t len, ServerKeyExchangeMsg *msg, uint32_t *usedLen) +{ + if (len < sizeof(uint16_t)) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + uint32_t offset = 0u; + uint16_t identityHintLen = BSL_ByteToUint16(&data[offset]); + offset += sizeof(uint16_t); + + if (identityHintLen > len - offset) { + BSL_ERR_PUSH_ERROR(HITLS_CONFIG_INVALID_LENGTH); + return HITLS_CONFIG_INVALID_LENGTH; + } + + /* may receive no identity hint */ + uint8_t *identityHint = NULL; + if (identityHintLen != 0) { + identityHint = (uint8_t *)BSL_SAL_Dump(&data[offset], identityHintLen); + if (identityHint == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15324, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "receive server identity hint: %s.", identityHint); + } + msg->pskIdentityHint = identityHint; + msg->hintSize = identityHintLen; + + *usedLen = sizeof(uint16_t) + identityHintLen; + + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_TLCP11 +static int32_t VerifyServerKxMsgEcc(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, CERT_SignParam *signParam) +{ + uint8_t *sign = NULL; + uint16_t signSize = 0; + uint32_t useLen = 0; + /* Parse the signature data. The signature data is released after it is used up. The information is not maintained + * in the ServerKeyExchangeMsg.keyEx.ecdh file */ + sign = ParseSignature(ctx, &data[0], len, &signSize, &useLen); + if (sign == NULL) { + return HITLS_PARSE_ECDH_SIGN_ERR; + } + HITLS_CERT_X509 *signCert = SAL_CERT_PairGetX509(ctx->hsCtx->peerCert); + HITLS_CERT_Key *pubkey = NULL; + int32_t ret = SAL_CERT_X509Ctrl(&(ctx->config.tlsConfig), signCert, + CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(sign); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + signParam->sign = sign; + signParam->signLen = signSize; + ret = SAL_CERT_VerifySign(ctx, pubkey, signParam); + SAL_CERT_KeyFree(ctx->config.tlsConfig.certMgrCtx, pubkey); + BSL_SAL_FREE(sign); + return ret; +} + +/* Signature verification is complete and does not need to be exported to the ServerKeyExchangeMsg structure */ +static int32_t ParseServerKxMsgEcc(TLS_Ctx *ctx, const uint8_t *data, uint32_t len) +{ + HITLS_SignAlgo signAlgo; + HITLS_HashAlgo hashAlgo; + + /* The algorithm suite has been determined. The error probability of this function is low. Therefore, the alert is + * not required. */ + if (!CFG_GetSignParamBySchemes( + ctx->negotiatedInfo.version, ctx->negotiatedInfo.cipherSuiteInfo.signScheme, &signAlgo, &hashAlgo)) { + return HITLS_PACK_SIGNATURE_ERR; + } + + uint32_t certLen = 0; + uint8_t *cert = SAL_CERT_ClntGmEncodeEncCert(ctx, ctx->hsCtx->peerCert, &certLen); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15326, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encode encrypt cert failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_CERT_ERR_ENCODE; + } + uint32_t signDataLen = 0; + uint8_t *signData = HS_PrepareSignDataTlcp(ctx, cert, certLen, &signDataLen); + BSL_SAL_FREE(cert); + if (signData == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15327, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "data malloc fail when parse server key exchange msg.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + CERT_SignParam signParam = {signAlgo, hashAlgo, signData, signDataLen, NULL, 0}; + int32_t ret = VerifyServerKxMsgEcc(ctx, data, len, &signParam); + BSL_SAL_FREE(signData); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15328, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify signature fail when parse server key exchange msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + return HITLS_PARSE_VERIFY_SIGN_FAIL; + } + return HITLS_SUCCESS; +} +#endif + +int32_t ParseServerKeyExchange(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, HS_Msg *hsMsg) +{ + int32_t ret; + uint32_t offset = 0u; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + ServerKeyExchangeMsg *msg = &hsMsg->body.serverKeyExchange; + msg->keyExType = hsCtx->kxCtx->keyExchAlgo; + + if (IsPskNegotiation(ctx)) { + ret = ParseServerIdentityHint(data, len, msg, &offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + switch (hsCtx->kxCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_ECDHE: /** contains the TLCP */ + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = ParseServerEcdhe(ctx, &data[offset], len - offset, msg); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = ParseServerDhe(ctx, &data[offset], len - offset, msg); + break; + /* PSK & RSA_PSK nego may pack identity hint inside ServerKeyExchange msg */ + case HITLS_KEY_EXCH_PSK: + case HITLS_KEY_EXCH_RSA_PSK: + ret = HITLS_SUCCESS; + break; +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: + ret = ParseServerKxMsgEcc(ctx, &data[offset], len - offset); + break; +#endif + default: + ret = HITLS_PARSE_UNSUPPORT_KX_ALG; + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + break; + } + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15325, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse server key exchange msg fail.", 0, 0, 0, 0); + CleanServerKeyExchange(msg); + return ret; + } + + return HITLS_SUCCESS; +} + +void CleanServerKeyExchange(ServerKeyExchangeMsg *msg) +{ + if (msg == NULL) { + return; + } + + if (msg->keyExType == HITLS_KEY_EXCH_ECDHE || msg->keyExType == HITLS_KEY_EXCH_ECDHE_PSK) { + BSL_SAL_FREE(msg->keyEx.ecdh.pubKey); + BSL_SAL_FREE(msg->keyEx.ecdh.signData); + } else if (msg->keyExType == HITLS_KEY_EXCH_DHE || msg->keyExType == HITLS_KEY_EXCH_DHE_PSK) { + BSL_SAL_FREE(msg->keyEx.dh.p); + BSL_SAL_FREE(msg->keyEx.dh.g); + BSL_SAL_FREE(msg->keyEx.dh.pubkey); + BSL_SAL_FREE(msg->keyEx.dh.signData); + } + + BSL_SAL_FREE(msg->pskIdentityHint); + + return; +} diff --git a/tls/handshake/reass/include/hs_reass.h b/tls/handshake/reass/include/hs_reass.h new file mode 100644 index 00000000..3036f18d --- /dev/null +++ b/tls/handshake/reass/include/hs_reass.h @@ -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 HS_REASS_H +#define HS_REASS_H + +#include +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HITLS_NO_DTLS12 + +/** + * @brief Create a message reassembly queue. + * + * @return Return the header of the linked list. If NULL is returned, memory application fails. + */ +HS_ReassQueue *HS_ReassNew(void); + +/** + * @brief Release the reassembly message queue. + * + * @param reass [IN] Reassemble the message queue. + */ +void HS_ReassFree(HS_ReassQueue *reassQueue); + +/** + * @brief Reassemble a fragmented handshake message. + * + * @param ctx [IN] TLS object + * @param msgInfo [IN] Message structure to be reassembled + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_REASS_INVALID_FRAGMENT An invalid fragment message is received. + * @retval HITLS_MEMALLOC_FAIL Memory application failed. + * @retval HITLS_MEMCPY_FAIL Memory Copy Failure + */ +int32_t HS_ReassAppend(TLS_Ctx *ctx, HS_MsgInfo *msgInfo); + +/** + * @brief Read the complete message of the expected sequence number. + * + * @param ctx [IN] TLS object + * @param msgInfo [OUT] Message structure + * @param len [OUT] Message length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMCPY_FAIL Memory Copy Failure + */ +int32_t HS_GetReassMsg(TLS_Ctx *ctx, HS_MsgInfo *msgInfo, uint32_t *len); + +#endif /* end #ifndef HITLS_NO_DTLS12 */ + +#ifdef __cplusplus +} +#endif + +#endif // HS_REASS_H diff --git a/tls/handshake/reass/src/hs_reass.c b/tls/handshake/reass/src/hs_reass.c new file mode 100644 index 00000000..3c9e3753 --- /dev/null +++ b/tls/handshake/reass/src/hs_reass.c @@ -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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_module_list.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hs_common.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_reass.h" + + +#ifndef HITLS_NO_DTLS12 + +#define MAX_NUM_EXCEED_EXPECT 10 + +static const uint8_t START_MASK_MAP[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; +static const uint8_t END_MASK_MAP[] = { 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF }; + +static void SetReassBitMap(uint8_t *reassBitMap, uint32_t fragmentOffset, uint32_t fragmentLength) +{ + /* start indicates the first digit of the flag to be set, and end indicates the last digit of the flag to be set */ + uint32_t start = fragmentOffset; + uint32_t end = fragmentOffset + fragmentLength - 1; + /* When the length is less than 8, the bitmap is set by bit. When the length is greater than or equal to 8, the + * bitmap is set in three steps */ + if (end - start < 8) { + for (uint32_t i = start; i <= end; i++) { + /** >>3 indicates divided by 8, & 7 is the remainder 8 */ + reassBitMap[(i) >> 3] |= 1 << (i & 7); + } + } else { + uint32_t startOffset = start >> 3; /* bitmap to be set, >> 3 indicates the division by 8 */ + uint32_t endOffset = end >> 3; /* last byte of the bitmap to be set, >> 3 is divided by 8 */ + /* Assign the first byte, &7 indicates the remainder 8 */ + reassBitMap[startOffset] |= START_MASK_MAP[start & 7]; + /* Assign a value to the middle byte */ + uint32_t copyLen = endOffset - startOffset - 1; + (void)memset_s(&reassBitMap[startOffset + 1], copyLen, 0xFF, copyLen); + /* Assign the last byte, &7 indicates the remainder 8 */ + reassBitMap[endOffset] |= END_MASK_MAP[end & 7]; + } + return; +} + + +static bool IsReassComplete(const uint8_t *reassBitMap, uint32_t msgLen) +{ + uint32_t i; + /* bit map from 0 to (msgLen-1) */ + uint32_t maxIndex = msgLen - 1; + /* Check the last byte, >> 3 indicates the division by 8, and &7 indicates the remainder by 8 */ + if (reassBitMap[maxIndex >> 3] != END_MASK_MAP[maxIndex & 7]) { + return false; + } + /* Check the 0th byte to the last 2nd byte, >> 3 is divided by 8 */ + for (i = 0; i < (maxIndex >> 3); i++) { + if (reassBitMap[i] != 0xFF) { + return false; + } + } + return true; +} + +HS_ReassQueue *HS_ReassNew(void) +{ + HS_ReassQueue *reassQueue = (HS_ReassQueue *)BSL_SAL_Calloc(1u, sizeof(HS_ReassQueue)); + if (reassQueue == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15751, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "reassQueue malloc fail when new a reassQueue.", 0, 0, 0, 0); + return NULL; + } + LIST_INIT(&reassQueue->head); + return reassQueue; +} + +void HS_ReassFree(HS_ReassQueue *reassQueue) +{ + if (reassQueue == NULL) { + return; + } + + ListHead *node = NULL; + ListHead *tmpNode = NULL; + HS_ReassQueue *cur = NULL; + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(reassQueue->head)) + { + cur = LIST_ENTRY(node, HS_ReassQueue, head); + LIST_REMOVE(&cur->head); /* Delete the node from the queue. */ + BSL_SAL_FREE(cur->reassBitMap); /* Release node content. */ + BSL_SAL_FREE(cur->msg); /* Release node content. */ + BSL_SAL_FREE(cur); /* Release the node. */ + } + BSL_SAL_FREE(reassQueue); + return; +} + +static HS_ReassQueue *GetReassNode(HS_ReassQueue *reassQueue, uint16_t sequence) +{ + ListHead *node = NULL; + ListHead *tmpNode = NULL; + HS_ReassQueue *cur = NULL; + + /* Find the node with the corresponding sequence number in the reassembly queue */ + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(reassQueue->head)) { + cur = LIST_ENTRY(node, HS_ReassQueue, head); + if (cur->sequence == sequence) { + return cur; + } + } + return NULL; +} + +static HS_ReassQueue *ReassNodeNew(HS_ReassQueue *reassQueue, HS_MsgInfo *msgInfo) +{ + HS_ReassQueue *node = (HS_ReassQueue *)BSL_SAL_Calloc(1u, sizeof(HS_ReassQueue)); + if (node == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15752, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "node malloc fail when inser a msg to reassQueue.", 0, 0, 0, 0); + return NULL; + } + LIST_INIT(&node->head); + + if (msgInfo->length != 0) { + /* 8 is the number of bits of one byte. The addition of 7 is used to supplement the number of bits. Ensure that + * the correct allocated bytes are obtained after each number is divided by 8. */ + uint32_t bitMapSize = (msgInfo->length + 7) / 8; + node->reassBitMap = BSL_SAL_Calloc(1u, bitMapSize); + if (node->reassBitMap == NULL) { + BSL_SAL_FREE(node); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15753, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "bitMap malloc fail when inser a msg to reassQueue.", 0, 0, 0, 0); + return NULL; + } + } + + /* Apply for the space that can be used to cache the entire message */ + uint32_t msgLen = DTLS_HS_MSG_HEADER_SIZE + msgInfo->length; + node->msg = BSL_SAL_Calloc(1u, msgLen); + if (node->msg == NULL) { + BSL_SAL_FREE(node->reassBitMap); + BSL_SAL_FREE(node); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15754, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg malloc fail when inser a msg to reassQueue.", 0, 0, 0, 0); + return NULL; + } + + node->type = msgInfo->type; + node->sequence = msgInfo->sequence; + node->isReassComplete = false; + node->msgLen = msgLen; + + /* Insert a new node */ + LIST_ADD_BEFORE(&reassQueue->head, &node->head); + return node; +} + +static int32_t ReassembleMsg(TLS_Ctx *ctx, HS_MsgInfo *msgInfo, HS_ReassQueue *node) +{ + /* Check message */ + uint32_t bufOffset = DTLS_HS_MSG_HEADER_SIZE + msgInfo->fragmentOffset; + if ((node->msgLen < bufOffset) || + (node->type != msgInfo->type) || + ((node->msgLen - DTLS_HS_MSG_HEADER_SIZE) != msgInfo->length)) { + BSL_ERR_PUSH_ERROR(HITLS_REASS_INVALID_FRAGMENT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15755, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "reassemble message fail, fragmentOffset %u; msgType %u, expect %u; msgLen %u", + msgInfo->fragmentOffset, msgInfo->type, node->type, msgInfo->length); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15759, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "expect %u", node->msgLen - DTLS_HS_MSG_HEADER_SIZE, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_REASS_INVALID_FRAGMENT; + } + + /* Copy the message header */ + if (msgInfo->fragmentOffset == 0u) { + if (memcpy_s(&node->msg[0], node->msgLen, &msgInfo->rawMsg[0], DTLS_HS_MSG_HEADER_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15756, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg header copy fail when append to reassQueue.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMCPY_FAIL; + } + } + + if (node->msgLen == DTLS_HS_MSG_HEADER_SIZE) { + /* The message is empty and does not need to be reassembled */ + node->isReassComplete = true; + return HITLS_SUCCESS; + } + + /* Message reassembly */ + if (memcpy_s(&node->msg[bufOffset], node->msgLen - bufOffset, + &msgInfo->rawMsg[DTLS_HS_MSG_HEADER_SIZE], msgInfo->fragmentLength) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15757, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg copy fail when append to reassQueue.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMCPY_FAIL; + } + + /* Set the bitmap and check whether the bitmap is complete */ + SetReassBitMap(node->reassBitMap, msgInfo->fragmentOffset, msgInfo->fragmentLength); + if (IsReassComplete(node->reassBitMap, node->msgLen - DTLS_HS_MSG_HEADER_SIZE)) { + /* Bitmap complete, updated fragment length */ + BSL_Uint24ToByte(msgInfo->length, &node->msg[DTLS_HS_FRAGMENT_LEN_ADDR]); + node->isReassComplete = true; + } + + return HITLS_SUCCESS; +} + +int32_t HS_ReassAppend(TLS_Ctx *ctx, HS_MsgInfo *msgInfo) +{ + /* If the number of a message exceeds the expected number, discard the message to prevent unlimited memory + * application */ + if (msgInfo->sequence > ctx->hsCtx->expectRecvSeq + MAX_NUM_EXCEED_EXPECT) { + return HITLS_SUCCESS; + } + + HS_ReassQueue *reassQueue = ctx->hsCtx->reassMsg; + /* Check whether there are messages in the reassembly queue */ + HS_ReassQueue *node = GetReassNode(reassQueue, msgInfo->sequence); + if (node == NULL) { + /* If no message has the corresponding sequence number, create a new queue node to buffer the message */ + node = ReassNodeNew(reassQueue, msgInfo); + if (node == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + } + + return ReassembleMsg(ctx, msgInfo, node); +} + +int32_t HS_GetReassMsg(TLS_Ctx *ctx, HS_MsgInfo *msgInfo, uint32_t *len) +{ + /* Check whether there are messages in the reassembly queue */ + int32_t ret; + HS_ReassQueue *node = GetReassNode(ctx->hsCtx->reassMsg, ctx->hsCtx->expectRecvSeq); + if (node == NULL) { + *len = 0; + return HITLS_SUCCESS; + } + + /* If a message exists, check whether the message is complete. If the message is incomplete, return the message and + * continue to read the message from the record layer */ + if (!node->isReassComplete) { + *len = 0; + return HITLS_SUCCESS; + } + + /* If the message is a complete message, copy the message */ + msgInfo->type = node->type; + msgInfo->length = node->msgLen - DTLS_HS_MSG_HEADER_SIZE; + msgInfo->sequence = node->sequence; + msgInfo->fragmentOffset = 0u; + msgInfo->fragmentLength = node->msgLen - DTLS_HS_MSG_HEADER_SIZE; + + ret = HS_ReSizeMsgBuf(ctx, node->msgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (memcpy_s(ctx->hsCtx->msgBuf, ctx->hsCtx->bufferLen, node->msg, node->msgLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15758, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg copy fail when get a msg from reassQueue.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMCPY_FAIL; + } + msgInfo->rawMsg = ctx->hsCtx->msgBuf; + *len = node->msgLen; /* Set the message length. */ + LIST_REMOVE(&node->head); /* Delete the node from the queue. */ + BSL_SAL_FREE(node->reassBitMap); /* Release node content. */ + BSL_SAL_FREE(node->msg); /* Release node content. */ + BSL_SAL_FREE(node); /* Release the node. */ + + return HITLS_SUCCESS; +} + +#endif /* end #ifndef HITLS_NO_DTLS12 */ diff --git a/tls/handshake/recv/include/hs_state_recv.h b/tls/handshake/recv/include/hs_state_recv.h new file mode 100644 index 00000000..9f20beff --- /dev/null +++ b/tls/handshake/recv/include/hs_state_recv.h @@ -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 HS_STATE_RECV_H +#define HS_STATE_RECV_H + +#include +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Handshake layer state machine receiving messages processing + * + * @param ctx [IN] TLS object + * + * @retval HITLS_SUCCESS + * @retval HITLS_MSG_HANDLE_UNSUPPORT_VERSION The TLS version is not supported + * @retval For details, see hitls_error.h + */ +int32_t HS_RecvMsgProcess(TLS_Ctx *ctx); + +/** + * @brief key update message receiving processing + * + * @param ctx [IN] TLS object + * @param hsMsgInfo [IN] Parsed message header + * @param hsMsg [OUT] Parsed message + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t HS_HandleRecvKeyUpdate(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo, HS_Msg *hsMsg); + +/** + * @brief Process renegotiation request + * + * @param ctx [IN] TLS object + * @param hsMsgInfo [IN] Parsed message header + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t HS_HandleRecvRenegoReq(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo); + +/** + * @brief Process TLS1.3 new session ticket + * + * @param ctx [IN] TLS object + * @param hsMsgInfo [IN] Parsed message header + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t HS_HandleTLS13NewSessionTicket(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ +#endif /* end HS_STATE_RECV_H */ \ No newline at end of file diff --git a/tls/handshake/recv/include/recv_process.h b/tls/handshake/recv/include/recv_process.h new file mode 100644 index 00000000..adda6672 --- /dev/null +++ b/tls/handshake/recv/include/recv_process.h @@ -0,0 +1,261 @@ +/* + * 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 RECV_PROCESS_H +#define RECV_PROCESS_H + +#include +#include "tls.h" +#include "hs_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t Tls12ServerRecvClientHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief Server processes DTLS client hello message + * + * @param ctx [IN] TLS context + * @param msg [IN] client hello message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsServerRecvClientHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg); +#endif + +/** + * @brief Client processes Server Hello message + * + * @param ctx [IN] TLS context + * @param msg [IN] server hello message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t ClientRecvServerHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief Process peer certificate + * + * @param ctx [IN] TLS context + * @param msg [IN] certificate message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t RecvCertificateProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief Process server key exchange + * + * @param ctx [IN] TLS context + * @param msg [IN] server key exchange message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t ClientRecvServerKxProcess(TLS_Ctx *ctx, HS_Msg *msg); + +/** + * @brief Process server certificate request + * + * @param ctx [IN] TLS context + * @param msg [IN] server certificate request message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t ClientRecvCertRequestProcess(TLS_Ctx *ctx, HS_Msg *msg); + +/** + * @brief Process sever hello done + * + * @param ctx [IN] TLS context + * + * @return HITLS_SUCCESS + */ +int32_t ClientRecvServerHelloDoneProcess(TLS_Ctx *ctx); + +/** + * @brief The server processes the client key exchange + * + * @param ctx [IN] TLS context + * @param msg [IN] Parsed handshake message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t ServerRecvClientKxProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief Server process client certificate verification message + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t ServerRecvClientCertVerifyProcess(TLS_Ctx *ctx); + +/** + * @brief TLS1.2 client processes the new session ticket message + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls12ClientRecvNewSeesionTicketProcess(TLS_Ctx *ctx, HS_Msg *hsMsg); + +/** + * @brief TLS1.3 client processes the new session ticket message + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ClientRecvNewSessionTicketProcess(TLS_Ctx *ctx, HS_Msg *hsMsg); + +int32_t Tls12ServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +int32_t Tls12ClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief Server processes dlts client finished message + * + * @param ctx [IN] TLS context + * @param msg [IN] finished message + * + * @retval HITLS_SUCCESS + * @retval HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL Failed to verify the finished message + */ + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg); +#endif + +/** + * @brief Client processes dlts server finished message + * + * @param ctx [IN] TLS context + * @param msg [IN] finished message + * + * @retval HITLS_SUCCESS + * @retval HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL Failed to verify the finished message + */ + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg); +#endif + +/** + * @brief TLS1.3 server process client hello message + * + * @param ctx [IN] TLS context + * @param msg [IN] client hello message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ServerRecvClientHelloProcess(TLS_Ctx *ctx, HS_Msg *msg); + +/** + * @brief TLS1.3 client process server hello message + * + * @param ctx [IN] TLS context + * @param msg [IN] server hello message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ClientRecvServerHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief TLS1.3 client process encrypted extensions message + * + * @param ctx [IN] TLS context + * @param msg [IN] encrypted extensions message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ClientRecvEncryptedExtensionsProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief TLS1.3 client processes certificate request message + * + * @param ctx [IN] TLS context + * @param msg [IN] certificate request message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ClientRecvCertRequestProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief TLS1.3 process certificate message + * + * @param ctx [IN] TLS context + * @param msg [IN] certificate message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13RecvCertificateProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief TLS1.3 process certificate verify message + * + * @param ctx [IN] TLS context + * @param msg [IN] certificate verify message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13RecvCertVerifyProcess(TLS_Ctx *ctx); + +/** + * @brief TLS1.3 client process finished message + * + * @param ctx [IN] TLS context + * @param msg [IN] finished message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +/** + * @brief TLS1.3 server process finished message + * + * @param ctx [IN] TLS context + * @param msg [IN] finished message + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t Tls13ServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ + +#endif /* end RECV_PROCESS_H */ diff --git a/tls/handshake/recv/src/hs_state_recv.c b/tls/handshake/recv/src/hs_state_recv.c new file mode 100644 index 00000000..87313be6 --- /dev/null +++ b/tls/handshake/recv/src/hs_state_recv.c @@ -0,0 +1,486 @@ +/* + * 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 "bsl_log_internal.h" +#include "bsl_log.h" +#include "tls_binlog_id.h" +#include "bsl_err_internal.h" +#include "hitls.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "tls.h" +#include "rec.h" +#include "hs.h" +#include "hs_msg.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "transcript_hash.h" +#include "hs_reass.h" +#include "parse.h" +#include "recv_process.h" +#include "bsl_uio.h" +#include "hs_kx.h" +#include "indicator.h" +#include "securec.h" + +static int32_t ProcessReceivedHandshakeMsg(TLS_Ctx *ctx, HS_Msg *hsMsg) +{ + if (hsMsg->type == HELLO_REQUEST) { + /* When the HelloRequest message appear at any time during the handshake, it should be ignored */ + return HITLS_SUCCESS; + } +#ifndef HITLS_NO_DTLS12 + uint32_t version = HS_GetVersion(ctx); +#endif + switch (ctx->hsCtx->state) { + case TRY_RECV_CLIENT_HELLO: +#ifndef HITLS_NO_DTLS12 + if (version == HITLS_VERSION_DTLS12) { + return DtlsServerRecvClientHelloProcess(ctx, hsMsg); + } +#endif + return Tls12ServerRecvClientHelloProcess(ctx, hsMsg); + case TRY_RECV_SERVER_HELLO: + return ClientRecvServerHelloProcess(ctx, hsMsg); + case TRY_RECV_CERTIFICATE: + return RecvCertificateProcess(ctx, hsMsg); + case TRY_RECV_SERVER_KEY_EXCHANGE: + return ClientRecvServerKxProcess(ctx, hsMsg); + case TRY_RECV_CERTIFICATE_REQUEST: + return ClientRecvCertRequestProcess(ctx, hsMsg); + case TRY_RECV_SERVER_HELLO_DONE: + return ClientRecvServerHelloDoneProcess(ctx); + case TRY_RECV_CLIENT_KEY_EXCHANGE: + return ServerRecvClientKxProcess(ctx, hsMsg); + case TRY_RECV_CERTIFICATE_VERIFY: + return ServerRecvClientCertVerifyProcess(ctx); + case TRY_RECV_NEW_SESSION_TICKET: + return Tls12ClientRecvNewSeesionTicketProcess(ctx, hsMsg); + case TRY_RECV_FINISH: + if (ctx->isClient) { +#ifndef HITLS_NO_DTLS12 + if (version == HITLS_VERSION_DTLS12) { + return DtlsClientRecvFinishedProcess(ctx, hsMsg); + } +#endif + return Tls12ClientRecvFinishedProcess(ctx, hsMsg); + } +#ifndef HITLS_NO_DTLS12 + if (version == HITLS_VERSION_DTLS12) { + return DtlsServerRecvFinishedProcess(ctx, hsMsg); + } +#endif + return Tls12ServerRecvFinishedProcess(ctx, hsMsg); + default: + break; + } + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_STATE_ILLEGAL); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15350, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state error: should recv msg, but current state is %s.", HS_GetStateStr(ctx->hsCtx->state)); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_STATE_ILLEGAL; +} + +int32_t Tls13TryRecvNewSeesionTicket(TLS_Ctx *ctx, HS_Msg *hsMsg) +{ + if (!ctx->isClient) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15329, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Unexpected msg: server recv new session ticket", HS_GetMsgTypeStr(hsMsg->type)); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + } + + return Tls13ClientRecvNewSessionTicketProcess(ctx, hsMsg); +} +static int32_t Tls13ProcessReceivedHandshakeMsg(TLS_Ctx *ctx, HS_Msg *hsMsg) +{ + if ((hsMsg->type == HELLO_REQUEST) && (ctx->isClient)) { + /* The HelloRequest message may appear at any time during the handshake. The client should ignore this message + */ + return HITLS_SUCCESS; + } + + switch (ctx->hsCtx->state) { + case TRY_RECV_CLIENT_HELLO: + return Tls13ServerRecvClientHelloProcess(ctx, hsMsg); + case TRY_RECV_SERVER_HELLO: + return Tls13ClientRecvServerHelloProcess(ctx, hsMsg); + case TRY_RECV_ENCRYPTED_EXTENSIONS: + return Tls13ClientRecvEncryptedExtensionsProcess(ctx, hsMsg); + case TRY_RECV_CERTIFICATE_REQUEST: + return Tls13ClientRecvCertRequestProcess(ctx, hsMsg); + case TRY_RECV_CERTIFICATE: + return Tls13RecvCertificateProcess(ctx, hsMsg); + case TRY_RECV_CERTIFICATE_VERIFY: + return Tls13RecvCertVerifyProcess(ctx); + case TRY_RECV_FINISH: + if (ctx->isClient) { + return Tls13ClientRecvFinishedProcess(ctx, hsMsg); + } + return Tls13ServerRecvFinishedProcess(ctx, hsMsg); + default: + break; + } + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_STATE_ILLEGAL); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15343, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 handshake state error: should recv msg, but current state is %s.", HS_GetStateStr(ctx->hsCtx->state)); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_STATE_ILLEGAL; +} + +static int32_t ReadThenParseTlsHsMsg(TLS_Ctx *ctx, HS_Msg *hsMsg) +{ + HS_Ctx *hsCtx = ctx->hsCtx; + int32_t ret = REC_TlsReadNbytes(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf, HS_MSG_HEADER_SIZE); + if (ret != HITLS_SUCCESS) { + return ret; + } + HS_MsgInfo hsMsgInfo = {0}; + ret = HS_ParseMsgHeader(ctx, hsCtx->msgBuf, HS_MSG_HEADER_SIZE, &hsMsgInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + ctx->hasParsedHsMsgHeader = true; + ret = REC_TlsReadNbytes(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf + HS_MSG_HEADER_SIZE, hsMsgInfo.length); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = HS_ParseMsg(ctx, &hsMsgInfo, hsMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* The HelloRequest message is not included. */ + if (hsMsgInfo.type != HELLO_REQUEST) { + /* Session hash is needed to compute ems, the VERIFY_Append must be dealt with beforehand */ + ret = VERIFY_Append(hsCtx->verifyCtx, hsCtx->msgBuf, hsMsgInfo.headerAndBodyLen); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(hsMsg); + return ret; + } + } + + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsMsgInfo.rawMsg, + hsMsgInfo.length, ctx, ctx->config.tlsConfig.msgArg); + + return HITLS_SUCCESS; +} + +static int32_t Tls12TryRecvHandShakeMsg(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Msg hsMsg = {0}; + (void)memset_s(&hsMsg, sizeof(HS_Msg), 0, sizeof(HS_Msg)); + + ret = ReadThenParseTlsHsMsg(ctx, &hsMsg); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + + ret = ProcessReceivedHandshakeMsg(ctx, &hsMsg); + HS_CleanMsg(&hsMsg); + + return ret; +} + +static int32_t Tls13TryRecvHandShakeMsg(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Msg hsMsg = {0}; + (void)memset_s(&hsMsg, sizeof(HS_Msg), 0, sizeof(HS_Msg)); + + ret = ReadThenParseTlsHsMsg(ctx, &hsMsg); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + + ret = Tls13ProcessReceivedHandshakeMsg(ctx, &hsMsg); + HS_CleanMsg(&hsMsg); + + return ret; +} + +#ifndef HITLS_NO_DTLS12 + +int32_t DtlsDisorderMsgProcess(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo) +{ + HS_Ctx *hsCtx = ctx->hsCtx; + + /* The SCTP scenario must be sequenced. */ + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNMATCHED_SEQUENCE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15351, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "msg with unmatched sequence, recv %u, expect %u.", hsMsgInfo->sequence, hsCtx->expectRecvSeq, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNMATCHED_SEQUENCE; +} + +static int32_t DtlsTryRecvHandShakeMsg(TLS_Ctx *ctx) +{ + HS_Ctx *hsCtx = ctx->hsCtx; + uint8_t *buf = NULL; + uint32_t dataLen = 0; + HS_Msg hsMsg = {0}; + (void)memset_s(&hsMsg, sizeof(HS_Msg), 0, sizeof(HS_Msg)); + HS_MsgInfo hsMsgInfo = {0}; + + /* Read the message with the expected sequence number from the reassembly queue. If no message exists, read the + * message from the record layer */ + int32_t ret = HS_GetReassMsg(ctx, &hsMsgInfo, &dataLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + buf = hsCtx->msgBuf; + if (dataLen == 0) { + ret = REC_Read(ctx, REC_TYPE_HANDSHAKE, buf, &dataLen, hsCtx->bufferLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_ParseMsgHeader(ctx, buf, dataLen, &hsMsgInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* SCTP messages are not out of order. Therefore, an alert message must be sent for the out-of-order messages */ + if (hsMsgInfo.sequence != hsCtx->expectRecvSeq) { + return DtlsDisorderMsgProcess(ctx, &hsMsgInfo); + } + + /* If the message is fragmented, the message needs to be reassembled. */ + if (hsMsgInfo.fragmentLength != hsMsgInfo.length) { + return HS_ReassAppend(ctx, &hsMsgInfo); + } + } + + ret = CheckHsMsgType(ctx, hsMsgInfo.type); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_ParseMsg(ctx, &hsMsgInfo, &hsMsg); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + + hsCtx->expectRecvSeq++; /* Auto-increment of the received message sequence number */ + + /* The HelloRequest message is not included. */ + if (hsMsgInfo.type != HELLO_REQUEST) { + /* Session hash is needed to compute ems, the VERIFY_Append must be dealt with beforehand */ + ret = VERIFY_Append(hsCtx->verifyCtx, buf, dataLen); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + } + + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsMsgInfo.rawMsg, + hsMsgInfo.length, ctx, ctx->config.tlsConfig.msgArg); + + if (hsMsgInfo.type == HELLO_REQUEST && hsMsgInfo.sequence != 0) { + HS_CleanMsg(&hsMsg); + return HITLS_SUCCESS; + } + ret = ProcessReceivedHandshakeMsg(ctx, &hsMsg); + HS_CleanMsg(&hsMsg); + return ret; +} +#endif + +static int32_t FlightTransmit(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15777, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "fail to send handshake message in bUio.", 0, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + + return HITLS_SUCCESS; +} + +int32_t HS_RecvMsgProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /* If isFlightTransmitEnable is enabled, the handshake information stored in the bUio needs to be sent when the + * receiving status is changed. */ + if (ctx->config.tlsConfig.isFlightTransmitEnable) { + ret = FlightTransmit(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + uint32_t version = HS_GetVersion(ctx); + + switch (version) { + case HITLS_VERSION_TLS12: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + ret = Tls12TryRecvHandShakeMsg(ctx); + break; + case HITLS_VERSION_TLS13: + ret = Tls13TryRecvHandShakeMsg(ctx); + break; +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + ret = DtlsTryRecvHandShakeMsg(ctx); + break; +#endif + default: + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15352, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state recv error: unsupport TLS version.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + + if (ret != HITLS_SUCCESS) { + if (ctx->method.getAlertFlag(ctx)) { + /* The alert has been processed and the handshake cannot continue */ + return ret; + } + if (ret == HITLS_REC_NORMAL_RECV_DISORDER_MSG) { + /* App messages and finished messages are out of order. Handshake can be continued */ + return HITLS_SUCCESS; + } + if ((ret == HITLS_REC_NORMAL_RECV_UNEXPECT_MSG) && (ctx->method.isRecvCCS(ctx))) { + /* The CCS message is received, and the handshake can be continued. */ + return HITLS_SUCCESS; + } + /* return other errors */ + } + return ret; +} + +int32_t HS_HandleRecvKeyUpdate(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo, HS_Msg *hsMsg) +{ + int32_t ret = HS_ParseMsg(ctx, hsMsgInfo, hsMsg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15353, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse tls1.3 key update msg fail.", 0, 0, 0, 0); + return ret; + } + + HITLS_KeyUpdateRequest requestUpdateType = hsMsg->body.keyUpdate.requestUpdate; + if ((requestUpdateType != HITLS_UPDATE_NOT_REQUESTED) && + (requestUpdateType != HITLS_UPDATE_REQUESTED)) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_KEY_UPDATE_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15354, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 unexpected requestUpdateType(%u)", requestUpdateType, 0, 0, 0); + return HITLS_MSG_HANDLE_ILLEGAL_KEY_UPDATE_TYPE; + } + + /* Update and activate the app traffic secret used by the local after receiving the key update message */ + ret = HS_TLS13UpdateTrafficSecret(ctx, false); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15355, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 in key update fail", 0, 0, 0, 0); + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15980, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 recv key update succ", 0, 0, 0, 0); + return HITLS_SUCCESS; +} + +static int32_t SelectVersionForHs(TLS_Ctx *ctx, uint16_t version, HS_Msg *hsMsg) +{ + int32_t ret = HITLS_SUCCESS; + switch (version) { + case HITLS_VERSION_TLS12: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + ret = Tls12ServerRecvClientHelloProcess(ctx, hsMsg); + break; +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + ret = DtlsServerRecvClientHelloProcess(ctx, hsMsg); + break; +#endif + default: + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15956, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state recv error: unsupport TLS version when recv renegotiation request.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + ret = HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + break; + } + + HS_CleanMsg(hsMsg); + return ret; +} + +int32_t HS_HandleRecvRenegoReq(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo) +{ + int32_t ret = HITLS_SUCCESS; + uint32_t version = HS_GetVersion(ctx); + HS_Msg hsMsg = {0}; + HS_Ctx *hsCtx = ctx->hsCtx; + uint32_t headerAndBodyLen = IS_DTLS_VERSION(version) ? (DTLS_HS_MSG_HEADER_SIZE + hsMsgInfo->length) + : (HS_MSG_HEADER_SIZE + hsMsgInfo->length); + ret = HS_ParseMsg(ctx, hsMsgInfo, &hsMsg); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } +#ifndef HITLS_NO_DTLS12 + hsCtx->expectRecvSeq++; /* Auto-increment of the received message sequence number */ +#endif + /* Because the HelloRequest message is empty, the message does not need to be processed and the hash of the message + * does not need to be calculated. */ + if (hsMsgInfo->type == HELLO_REQUEST) { + HS_CleanMsg(&hsMsg); + return HITLS_SUCCESS; + } + + ret = VERIFY_Append(hsCtx->verifyCtx, hsMsgInfo->rawMsg, headerAndBodyLen); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + + INDICATOR_MessageIndicate(0, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsMsgInfo->rawMsg, + hsMsgInfo->length, ctx, ctx->config.tlsConfig.msgArg); + + return SelectVersionForHs(ctx, version, &hsMsg); +} + +int32_t HS_HandleTLS13NewSessionTicket(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo) +{ + HS_Msg hsMsg = {0}; + int32_t ret = HS_ParseMsg(ctx, hsMsgInfo, &hsMsg); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + + ret = Tls13TryRecvNewSeesionTicket(ctx, &hsMsg); + + HS_CleanMsg(&hsMsg); + return ret; +} diff --git a/tls/handshake/recv/src/recv_cert_request.c b/tls/handshake/recv/src/recv_cert_request.c new file mode 100644 index 00000000..c7b8a391 --- /dev/null +++ b/tls/handshake/recv/src/recv_cert_request.c @@ -0,0 +1,109 @@ +/* + * 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 +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_log.h" +#include "bsl_bytes.h" +#include "bsl_log_internal.h" +#include "bsl_err_internal.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "hitls_error.h" +#include "tls_binlog_id.h" + + +// The client processes the certificate request +int32_t ClientRecvCertRequestProcess(TLS_Ctx *ctx, HS_Msg *msg) +{ + /** + * If the server certificate is not received, a failure message is returned after the cert request is received + * RFC 5246 7.4.4: Note: It is a fatal handshake_failure alert for + * an anonymous server to request client authentication. + */ + if (ctx->hsCtx->peerCert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15869, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "got cert request but not get peer certificate.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE; + } + /* If ECC and ECHDE of TLCP are used, this parameter must be set because the + * TLCP server must send the req cert message to the client to send the certificate, which may be + * used for identity authentication, The latter may be used for key derivation, depending on the cipher suite and + * server configuration (isSupportClientVerify). */ + ctx->hsCtx->isNeedClientCert = true; + + CertificateRequestMsg *certReq = &msg->body.certificateReq; + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CERT_TYPE_UNKNOWN; + expectCertInfo.signSchemeList = certReq->signatureAlgorithms; + expectCertInfo.signSchemeNum = certReq->signatureAlgorithmsSize; + (void)SAL_CERT_SelectCertByInfo(ctx, &expectCertInfo); + + return HS_ChangeState(ctx, TRY_RECV_SERVER_HELLO_DONE); +} + +int32_t Tls13ClientRecvCertRequestProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + const CertificateRequestMsg *certReq = &msg->body.certificateReq; + + /** If authentication is not performed after handshake, the cert req ctx length should be 0 */ + if ((ctx->phaState != PHA_REQUESTED && certReq->certificateReqCtxSize != 0) || + (ctx->phaState == PHA_REQUESTED && certReq->certificateReqCtxSize == 0)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15870, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "certificateReqCtxSize is invalid.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX; + } + if (certReq->certificateReqCtxSize != 0) { + BSL_SAL_FREE(ctx->certificateReqCtx); + ctx->certificateReqCtx = BSL_SAL_Calloc(certReq->certificateReqCtxSize, sizeof(uint8_t)); + if (ctx->certificateReqCtx == NULL) { + return HITLS_MEMALLOC_FAIL; + } + ctx->certificateReqCtxSize = certReq->certificateReqCtxSize; + int32_t ret = memcpy_s(ctx->certificateReqCtx, certReq->certificateReqCtxSize, + certReq->certificateReqCtx, certReq->certificateReqCtxSize); + if (ret != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15406, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "client calloc cert req ctx failed.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + } + if (certReq->signatureAlgorithms == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_MISSING_EXTENSION); + return HITLS_MSG_HANDLE_MISSING_EXTENSION; + } + + ctx->hsCtx->isNeedClientCert = true; + + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CERT_TYPE_UNKNOWN; + expectCertInfo.signSchemeList = certReq->signatureAlgorithms; + expectCertInfo.signSchemeNum = certReq->signatureAlgorithmsSize; + + /* If no certificate is selected, the client sends an empty certificate message */ + (void)SAL_CERT_SelectCertByInfo(ctx, &expectCertInfo); + if (ctx->phaState == PHA_REQUESTED) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE); + } + + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE); +} diff --git a/tls/handshake/recv/src/recv_cert_verify.c b/tls/handshake/recv/src/recv_cert_verify.c new file mode 100644 index 00000000..97fff9cf --- /dev/null +++ b/tls/handshake/recv/src/recv_cert_verify.c @@ -0,0 +1,64 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_verify.h" +#include "hs_common.h" +#include "hs_msg.h" + + +int32_t ServerRecvClientCertVerifyProcess(TLS_Ctx *ctx) +{ + /* The signature verification part has been completed in the parser part. + Only the client finish data needs to be calculated in advance. */ + int32_t ret = VERIFY_CalcVerifyData(ctx, true, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15871, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server Calculate client finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + (void)memset_s(ctx->hsCtx->masterKey, sizeof(ctx->hsCtx->masterKey), 0, sizeof(ctx->hsCtx->masterKey)); + return ret; + } + + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} + +int32_t Tls13RecvCertVerifyProcess(TLS_Ctx *ctx) +{ + int32_t ret; + + /* The signature verification has been completed in the parser part. + Only the finish data of the peer needs to be calculated. */ + ret = VERIFY_Tls13CalcVerifyData(ctx, !ctx->isClient); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15872, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "calculate finished data fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} diff --git a/tls/handshake/recv/src/recv_certificate.c b/tls/handshake/recv/src/recv_certificate.c new file mode 100644 index 00000000..081680b8 --- /dev/null +++ b/tls/handshake/recv/src/recv_certificate.c @@ -0,0 +1,442 @@ +/* + * 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 +#include +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "hs_verify.h" +#include "hs_msg.h" + +static const int32_t X509_ERR_ALERT_MAP[] = { + [(HITLS_X509_V_ERR_UNSPECIFIED - 1) & 0XFF] = ALERT_INTERNAL_ERROR, + [(HITLS_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_UNABLE_TO_GET_CRL - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_CERT_SIGNATURE_FAILURE - 1) & 0XFF] = ALERT_DECRYPT_ERROR, + [(HITLS_X509_V_ERR_CRL_SIGNATURE_FAILURE - 1) & 0XFF] = ALERT_DECRYPT_ERROR, + [(HITLS_X509_V_ERR_CERT_NOT_YET_VALID - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_CERT_HAS_EXPIRED - 1) & 0XFF] = ALERT_CERTIFICATE_EXPIRED, + [(HITLS_X509_V_ERR_CRL_NOT_YET_VALID - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_CRL_HAS_EXPIRED - 1) & 0XFF] = ALERT_CERTIFICATE_EXPIRED, + [(HITLS_X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_OUT_OF_MEM - 1) & 0XFF] = ALERT_INTERNAL_ERROR, + [(HITLS_X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_CERT_CHAIN_TOO_LONG - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_CERT_REVOKED - 1) & 0XFF] = ALERT_CERTIFICATE_REVOKED, + [(HITLS_X509_V_ERR_INVALID_CA - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_PATH_LENGTH_EXCEEDED - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_INVALID_PURPOSE - 1) & 0XFF] = ALERT_UNSUPPORTED_CERTIFICATE, + [(HITLS_X509_V_ERR_CERT_UNTRUSTED - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_CERT_REJECTED - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_SUBJECT_ISSUER_MISMATCH - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_AKID_SKID_MISMATCH - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_KEYUSAGE_NO_CERTSIGN - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER - 1) & 0XFF] = ALERT_UNKNOWN_CA, + [(HITLS_X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_KEYUSAGE_NO_CRL_SIGN - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_INVALID_NON_CA - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_INVALID_EXTENSION - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_INVALID_POLICY_EXTENSION - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_NO_EXPLICIT_POLICY - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_DIFFERENT_CRL_SCOPE - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CMP_CERT_NOT_AFTER_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CMP_CRL_THIS_UPDATE_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CMP_CRL_NEXT_UPDATE_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_ERROR_IN_CMP_CERT_NOT_BEFORE_FIELD - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, + [(HITLS_X509_V_ERR_CRL_PATH_VALIDATION_ERROR - 1) & 0XFF] = ALERT_BAD_CERTIFICATE, +}; + +ALERT_Description GetAlertfromX509Err(HITLS_ERROR x509err) +{ + uint32_t size = sizeof(X509_ERR_ALERT_MAP) / sizeof(X509_ERR_ALERT_MAP[0]); + uint32_t index = ((uint32_t)x509err - 1) & 0XFF; + if (index < size) { + return X509_ERR_ALERT_MAP[index]; + } + + return ALERT_BAD_CERTIFICATE; +} + +int32_t ClientCheckPeerCert(TLS_Ctx *ctx, HITLS_CERT_X509 *cert) +{ + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CFG_GetCertTypeByCipherSuite(ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite); + expectCertInfo.signSchemeList = ctx->config.tlsConfig.signAlgorithms; + expectCertInfo.signSchemeNum = ctx->config.tlsConfig.signAlgorithmsSize; + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + expectCertInfo.ellipticCurveList = ctx->config.tlsConfig.groups; + expectCertInfo.ellipticCurveNum = ctx->config.tlsConfig.groupsSize; + } + expectCertInfo.ecPointFormatList = ctx->config.tlsConfig.pointFormats; + expectCertInfo.ecPointFormatNum = ctx->config.tlsConfig.pointFormatsSize; + + return SAL_CERT_CheckCertInfo(ctx, &expectCertInfo, cert, false, true); +} + +int32_t ServerCheckPeerCert(TLS_Ctx *ctx, HITLS_CERT_X509 *cert) +{ + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CERT_TYPE_UNKNOWN; + expectCertInfo.signSchemeList = ctx->config.tlsConfig.signAlgorithms; + expectCertInfo.signSchemeNum = ctx->config.tlsConfig.signAlgorithmsSize; + + return SAL_CERT_CheckCertInfo(ctx, &expectCertInfo, cert, false, true); +} + +static int32_t ClientCheckCert(TLS_Ctx *ctx, CERT_Pair *peerCert) +{ + int32_t ret; + ret = ClientCheckPeerCert(ctx, SAL_CERT_PairGetX509(peerCert)); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15911, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client check peer cert failed", 0, 0, 0, 0); + return ret; + } +#ifndef HITLS_NO_TLCP11 + /* The encryption certificate is required for TLS of TLCP. Both ECDHE and ECC of the client depend on the encryption + * certificate. */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + HITLS_CERT_Key *cert = SAL_CERT_GetTlcpEncCert(peerCert); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15918, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client check peer enc cert failed.", 0, 0, 0, 0); + return HITLS_CERT_ERR_EXP_CERT; + } + /* The encryption certificate only needs to ensure that the certificate type matches the TLCP. + * That is, the encryption public key type matches the negotiation cipher suite. */ + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CFG_GetCertTypeByCipherSuite(ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite); + return SAL_CERT_CheckCertInfo(ctx, &expectCertInfo, cert, false, false); + } +#endif + return ret; +} + +static int32_t ServerCheckCert(TLS_Ctx *ctx, CERT_Pair *peerCert) +{ + int32_t ret; + ret = ServerCheckPeerCert(ctx, SAL_CERT_PairGetX509(peerCert)); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15921, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server check peer cert failed.", 0, 0, 0, 0); + return ret; + } +#ifndef HITLS_NO_TLCP11 + /* Service processing logic. The ECDHE exchange algorithm logic requires the encryption certificate */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11 && + ctx->negotiatedInfo.cipherSuiteInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) { + HITLS_CERT_Key *cert = SAL_CERT_GetTlcpEncCert(peerCert); + if (cert == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15923, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "service check peer enc cert failed", 0, 0, 0, 0); + return HITLS_CERT_ERR_EXP_CERT; + } + /* The encryption certificate only needs to ensure that the certificate type matches the TLCP. + * That is, the encryption public key type matches the negotiation cipher suite. */ + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CFG_GetCertTypeByCipherSuite(ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite); + return SAL_CERT_CheckCertInfo(ctx, &expectCertInfo, cert, false, false); + } +#endif + return ret; +} + +bool CheckCertKeyUsage(TLS_Ctx *ctx, CERT_Pair *peerCert) +{ + bool checkUsageRec = false; + HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(peerCert); + HITLS_CERT_X509 *encCert = SAL_CERT_GetTlcpEncCert(peerCert); + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + return SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE); + } + + HITLS_KeyExchAlgo kxAlg = ctx->negotiatedInfo.cipherSuiteInfo.kxAlg; + if (ctx->isClient) { + switch (kxAlg) { + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_ECDHE: + case HITLS_KEY_EXCH_ECDHE_PSK: + case HITLS_KEY_EXCH_DHE_PSK: + checkUsageRec = SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE); + break; + case HITLS_KEY_EXCH_RSA: + case HITLS_KEY_EXCH_ECC: + case HITLS_KEY_EXCH_RSA_PSK: + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + checkUsageRec = SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE) && + SAL_CERT_CheckCertKeyUsage(ctx, encCert, CERT_KEY_CTRL_IS_KEYENC_USAGE); + break; + } + checkUsageRec = SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_KEYENC_USAGE); + break; + case HITLS_KEY_EXCH_ECDH: + case HITLS_KEY_EXCH_DH: + checkUsageRec = SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_KEY_AGREEMENT_USAGE); + break; + default: + break; + } + } else { + switch (kxAlg) { + case HITLS_KEY_EXCH_ECDH: + case HITLS_KEY_EXCH_DH: + checkUsageRec = SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_KEY_AGREEMENT_USAGE); + break; + default: + checkUsageRec = SAL_CERT_CheckCertKeyUsage(ctx, cert, CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE); + break; + } + } + return checkUsageRec; +} + +/** +* @brief Process the peer certificate, check, and save it. +* +* @param ctx [IN/OUT] TLS context +* @param certs [IN] Certificate message +* +* @retval HITLS_SUCCESS succeeded. +* @retval For other error codes, see hitls_error.h. +*/ +static int32_t ProcessPeerCertificate(TLS_Ctx *ctx, const CertificateMsg *certs) +{ + int32_t ret; + CERT_Pair *peerCert = NULL; + + ret = SAL_CERT_ParseCertChain(ctx, certs->cert, &peerCert); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15723, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse certificate list fail when process peer certificate.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_CERTIFICATE); + return ret; + } + + if (ctx->config.tlsConfig.needCheckKeyUsage == true && !CheckCertKeyUsage(ctx, peerCert)) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_CERTIFICATE); + SAL_CERT_PairFree(ctx->config.tlsConfig.certMgrCtx, peerCert); + return HITLS_CERT_ERR_KEYUSAGE; + } + + if (ctx->isClient) { + ret = ClientCheckCert(ctx, peerCert); + } else { + ret = ServerCheckCert(ctx, peerCert); + } + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_CERTIFICATE); + SAL_CERT_PairFree(ctx->config.tlsConfig.certMgrCtx, peerCert); + return ret; + } + + ctx->hsCtx->peerCert = peerCert; + return HITLS_SUCCESS; +} + +static int32_t VerifyCertChain(TLS_Ctx *ctx) +{ + int32_t ret = SAL_CERT_VerifyCertChain(ctx, ctx->hsCtx->peerCert, false); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15924, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "process peer certificate fail, ret = 0x%x.", (uint32_t)ret, 0, 0, 0); + return ret; + } +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11) { + return ret; + } + if (ctx->isClient) { + ret = SAL_CERT_VerifyCertChain(ctx, ctx->hsCtx->peerCert, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15925, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "process client enc certificate fail, ret = 0x%x.", (uint32_t)ret, 0, 0, 0); + return ret; + } + return ret; + } + /* Processing logic on the service side of TLCP, which is verified only when used. */ + if (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) { + ret = SAL_CERT_VerifyCertChain(ctx, ctx->hsCtx->peerCert, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15932, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "process server enc certificate fail, ret = 0x%x.", (uint32_t)ret, 0, 0, 0); + return ret; + } + return ret; + } +#endif + return ret; +} + +/** +* @brief Process the certificate. +* +* @param ctx [IN/OUT] TLS context +* @param msg [IN] message structure +* +* @retval HITLS_SUCCESS succeeded. +* @retval For other error codes, see hitls_error.h. +*/ +int32_t RecvCertificateProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret; + const CertificateMsg *certs = &msg->body.certificate; + + /** + * RFC 5426 7.4.6: If no suitable certificate is available, + * the client MUST send a certificate message containing no certificates. + */ + if (certs->certCount == 0) { + /** Only the server allows the peer certificate to be empty */ + if ((ctx->isClient == false) && + (ctx->config.tlsConfig.isSupportClientVerify && ctx->config.tlsConfig.isSupportNoClientCert)) { + return HS_ChangeState(ctx, TRY_RECV_CLIENT_KEY_EXCHANGE); + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15724, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "peer certificate is needed!", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE; + } + + /** Process the obtained peer certificate */ + ret = ProcessPeerCertificate(ctx, certs); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15725, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "process peer certificate fail, ret = 0x%x.", ret, 0, 0, 0); + return ret; + } + + /** Verify the peer certificate */ + ret = VerifyCertChain(ctx); + /* After the VerifyNone function is enabled, the client can continue the handshake process if the server certificate + * fails to be verified */ + if (ret != HITLS_SUCCESS) { + if (!ctx->config.tlsConfig.isSupportVerifyNone) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, GetAlertfromX509Err(ctx->peerInfo.verifyResult)); + return ret; + } + } + + /** Update the state machine */ + if (ctx->isClient) { + if (IsNeedServerKeyExchange(ctx) == true) { + return HS_ChangeState(ctx, TRY_RECV_SERVER_KEY_EXCHANGE); + } + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST); + } + return HS_ChangeState(ctx, TRY_RECV_CLIENT_KEY_EXCHANGE); +} + +static int32_t CertificateReqCtxCheck(TLS_Ctx *ctx, const CertificateMsg *certs) +{ + /* In the handshake phase, certificate_request_context must be empty. */ + if (ctx->phaState != PHA_REQUESTED && certs->certificateReqCtxSize != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15726, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server receive a non-zero certificateReqCtx.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX; + } + /* pha phase, which must be non-empty and equal */ + if (ctx->certificateReqCtxSize != 0 && (ctx->certificateReqCtxSize != certs->certificateReqCtxSize || + memcmp(ctx->certificateReqCtx, certs->certificateReqCtx, certs->certificateReqCtxSize) != 0)) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_INVALID_CERT_REQ_CTX; + } + return HITLS_SUCCESS; +} + +int32_t Tls13RecvCertificateProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret; + const CertificateMsg *certs = &msg->body.certificate; + + ret = CertificateReqCtxCheck(ctx, certs); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** + * RFC 5426 7.4.6: If no suitable certificate is available, + * the client MUST send a certificate message containing no certificates. + */ + if (certs->certCount == 0) { + if (ctx->isClient) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15930, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "peer certificate is needed!", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE; + } + /** Only the server allows the peer certificate to be empty */ + if ((ctx->config.tlsConfig.isSupportClientVerify && ctx->config.tlsConfig.isSupportNoClientCert)) { + ret = VERIFY_Tls13CalcVerifyData(ctx, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15729, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server calculate client finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + return HS_ChangeState(ctx, TRY_RECV_FINISH); + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15727, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "peer certificate is needed!", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_CERTIFICATE_REQUIRED); + return HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE; + } + + /** Process the obtained peer certificate */ + ret = ProcessPeerCertificate(ctx, certs); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15728, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "process peer certificate fail, ret = 0x%x.", ret, 0, 0, 0); + return ret; + } + + /** Verify the peer certificate */ + ret = SAL_CERT_VerifyCertChain(ctx, ctx->hsCtx->peerCert, false); + if (ret != HITLS_SUCCESS) { + if (!ctx->config.tlsConfig.isSupportVerifyNone) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, GetAlertfromX509Err(ctx->peerInfo.verifyResult)); + return ret; + } + } + + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_VERIFY); +} diff --git a/tls/handshake/recv/src/recv_client_hello.c b/tls/handshake/recv/src/recv_client_hello.c new file mode 100644 index 00000000..96285716 --- /dev/null +++ b/tls/handshake/recv/src/recv_client_hello.c @@ -0,0 +1,1960 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls.h" +#include "hitls_error.h" +#include "hitls_sni.h" +#include "hitls_alpn.h" +#include "hitls_security.h" +#include "bsl_uio.h" +#include "session_mgr.h" +#include "security.h" +#include "sni.h" +#include "hs_ctx.h" +#include "hs.h" +#include "hs_common.h" +#include "hs_verify.h" + +#define HS_MAX_BINDER_SIZE 64 + +static void CheckRenegotiate(TLS_Ctx *ctx) +{ + /* For the server, sending a Hello Request message does not count the renegotiation. The server enters the + * renegotiation state only after receiving a Hello message from the client. If the version number is not 0, it + * indicates that a handshake has been performed once. In this case, the client hello process enters the + * renegotiation state again. */ + if (ctx->negotiatedInfo.version != 0u) { + ctx->negotiatedInfo.isRenegotiation = true; // enters the renegotiation state. + } + return; +} + +/** +* @brief Check the extension of the client hello point format. +* +* @param clientHello [IN] client hello message +* +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT Unsupported point format +*/ +static int32_t ServerCheckPointFormats(const ClientHelloMsg *clientHello) +{ + /* Point format extension not received */ + if (!clientHello->extension.flag.havePointFormats) { + return HITLS_SUCCESS; + } + /* Traverse the list of point formats */ + for (uint32_t i = 0u; i < clientHello->extension.content.pointFormatsSize; i++) { + /* The point format list contains uncompressed (0) */ + if (clientHello->extension.content.pointFormats[i] == 0u) { + return HITLS_SUCCESS; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15210, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "the point format extension in client hello is unsupported.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT; +} + +/** +* @brief Select elliptic curve +* +* @param ctx [IN] TLS context +* @param clientHello [IN] Client Hello message +* +* @return Return curveID. If the value is 0, the supported curve is not found. +*/ +static uint16_t ServerSelectCurveId(const TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + uint32_t perferenceGroupsSize = 0; + uint32_t normalGroupsSize = 0; + uint16_t *perferenceGroups = NULL; + uint16_t *normalGroups = NULL; + if (ctx->config.tlsConfig.isSupportServerPreference) { + perferenceGroupsSize = ctx->config.tlsConfig.groupsSize; + normalGroupsSize = clientHello->extension.content.supportedGroupsSize; + perferenceGroups = ctx->config.tlsConfig.groups; + normalGroups = clientHello->extension.content.supportedGroups; + } else { + perferenceGroupsSize = clientHello->extension.content.supportedGroupsSize; + normalGroupsSize = ctx->config.tlsConfig.groupsSize; + perferenceGroups = clientHello->extension.content.supportedGroups; + normalGroups = ctx->config.tlsConfig.groups; + } + + /* Find supported curves */ + for (uint32_t i = 0u; i < perferenceGroupsSize; i++) { + for (uint32_t j = 0u; j < normalGroupsSize; j++) { + if (perferenceGroups[i] != normalGroups[j]) { + continue; + } + + /* Support group security check */ + int32_t id = (int32_t)perferenceGroups[i]; + int32_t ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_CURVE_SHARED, 0, id, NULL); + if (ret != SECURITY_SUCCESS || + !GroupConformToVersion(ctx->negotiatedInfo.version, perferenceGroups[i])) { + continue; + } + + return perferenceGroups[i]; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_NAMED_CURVE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15211, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "the curve id in client hello is unsupported.", 0, 0, 0, 0); + return 0; +} + +/** +* @brief Select a proper certificate based on the TLS cipher suite. +* +* @param ctx [IN] TLS context +* @param clientHello [IN] Client Hello message +* @param cipherInfo [IN] TLS cipher suite +* +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_MEMALLOC_FAIL Memory application failed. +*/ +static int32_t HsServerSelectCert(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, const CipherSuiteInfo *cipherInfo) +{ + uint16_t signHashAlgo = cipherInfo->signScheme; + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CFG_GetCertTypeByCipherSuite(cipherInfo->cipherSuite); + + /* For TLCP1.1, ignore the signature extension of client hello */ + if (clientHello->extension.content.signatureAlgorithms != NULL && + (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP11)) { + expectCertInfo.signSchemeList = clientHello->extension.content.signatureAlgorithms; + expectCertInfo.signSchemeNum = clientHello->extension.content.signatureAlgorithmsSize; + } else { + expectCertInfo.signSchemeList = &signHashAlgo; + expectCertInfo.signSchemeNum = 1u; + } + /* The ECDSA certificate must match the supported_groups and ec_point_format extensions */ + expectCertInfo.ellipticCurveList = clientHello->extension.content.supportedGroups; + expectCertInfo.ellipticCurveNum = clientHello->extension.content.supportedGroupsSize; + /* Only the uncompressed format is supported */ + uint8_t pointFormat = HITLS_POINT_FORMAT_UNCOMPRESSED; + expectCertInfo.ecPointFormatList = &pointFormat; + expectCertInfo.ecPointFormatNum = 1u; + + return SAL_CERT_SelectCertByInfo(ctx, &expectCertInfo); +} + +static int32_t Tls13ServerSelectCert(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* If a PSK exists, no certificate needs to be sent regardless of whether the PSK is psk_only or psk_with_dhe */ + if (ctx->hsCtx->kxCtx->pskInfo13.psk != NULL) { + return HITLS_SUCCESS; + } + + /* rfc 8446 4.2.3. If the client does not provide the signature algorithm extension, an alert message must be sent. + */ + if (clientHello->extension.content.signatureAlgorithms == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_MISSING_EXTENSION); + return HITLS_MSG_HANDLE_MISSING_EXTENSION; + } + + CERT_ExpectInfo expectCertInfo = {0}; + expectCertInfo.certType = CERT_TYPE_UNKNOWN; /* Do not specify the certificate type */ + expectCertInfo.signSchemeList = clientHello->extension.content.signatureAlgorithms; + expectCertInfo.signSchemeNum = clientHello->extension.content.signatureAlgorithmsSize; + + /* Only the uncompressed format is supported */ + uint8_t pointFormat = HITLS_POINT_FORMAT_UNCOMPRESSED; + expectCertInfo.ecPointFormatList = &pointFormat; + expectCertInfo.ecPointFormatNum = 1u; + + int32_t ret = SAL_CERT_SelectCertByInfo(ctx, &expectCertInfo); + if (ret != HITLS_SUCCESS) { + /* No proper certificate */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15219, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "have no suitable cert.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE; + } + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_TLCP11 +static bool CheckLocalContainCurveType(const uint16_t *groups, uint32_t groupsSize, uint16_t exp) +{ + for (uint32_t i = 0; i < groupsSize; ++i) { + if (groups[i] == exp) { + return true; + } + } + return false; +} +#endif + +/** +* @brief Process the ECDHE cipher suite. +* +* @param ctx [IN] TLS context +* @param clientHello [IN] Client Hello message +* @param cipherSuiteInfo [OUT] Cipher suite information +* +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE Unsupported cipher suites +*/ +static int32_t ProcessEcdheCipherSuite(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* If the curve id is not set, ECDHE cannot be used. */ + if ((ctx->config.tlsConfig.groupsSize == 0u) || (ctx->config.tlsConfig.groups == NULL)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15212, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "can not used ecdhe whitout curve id.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + if (CheckLocalContainCurveType(ctx->config.tlsConfig.groups, + ctx->config.tlsConfig.groupsSize, HITLS_EC_GROUP_SM2) != true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15220, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "TLCP need sm2 curve.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } + ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type = HITLS_EC_CURVE_TYPE_NAMED_CURVE; + ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.param.namedcurve = HITLS_EC_GROUP_SM2; + return HITLS_SUCCESS; /* TLCP negotiation does not focus on extended information. */ + } +#endif + /* Check the Point format extension of the clientHello. This extension is not included in the TLCP */ + int32_t ret = ServerCheckPointFormats(clientHello); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15213, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server check client hello point formats fail.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } + + uint16_t selectedEcCurveId = ServerSelectCurveId(ctx, clientHello); + if (selectedEcCurveId == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15214, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server select curve id fail.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + ctx->hsCtx->kxCtx->keyExchParam.share.group = selectedEcCurveId; + } else { + ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type = HITLS_EC_CURVE_TYPE_NAMED_CURVE; + ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.param.namedcurve = selectedEcCurveId; + } + + ctx->negotiatedInfo.negotiatedGroup = selectedEcCurveId; + return HITLS_SUCCESS; +} + +/** +* @brief Check whether the server supports the cipher suite. +* +* @param ctx [IN] TLS context +* @param clientHello [IN] client hello message +* @param cipher [IN] cipher suite ID +* +* @retval HITLS_SUCCESS succeeded. +* @retval HITLS_MEMCPY_FAIL Memory Copy Failure +* @retval HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE Unsupported cipher suites +*/ +static int32_t ServerNegotiateCipher(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, uint16_t cipher) +{ + CipherSuiteInfo cipherSuiteInfo = {0}; + int32_t ret = 0; + + ret = CFG_GetCipherSuiteInfo(cipher, &cipherSuiteInfo); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15215, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "get cipher suite info fail when processing client hello.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } + + /* If the key exchange algorithm is not PSK, DHE_PSK, or ECDHE_PSK, select a certificate. */ + if (IsNeedCertPrepare(&cipherSuiteInfo) == true) { + ret = HsServerSelectCert(ctx, clientHello, &cipherSuiteInfo); + if (ret != HITLS_SUCCESS) { + /* No proper certificate */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15216, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "have no suitable cert.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE; + } + } + + switch (cipherSuiteInfo.kxAlg) { + case HITLS_KEY_EXCH_ECDHE: /* the ECDHE of TLCP is also in this branch */ + case HITLS_KEY_EXCH_ECDHE_PSK: + /* The ECC cipher suite needs to process the supported_groups and ec_point_formats extensions */ + ret = ProcessEcdheCipherSuite(ctx, clientHello); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = HITLS_SUCCESS; + break; + case HITLS_KEY_EXCH_RSA: +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: +#endif + ret = HITLS_SUCCESS; + break; + case HITLS_KEY_EXCH_PSK: + case HITLS_KEY_EXCH_RSA_PSK: + ret = HITLS_SUCCESS; + break; + default: + ret = HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15217, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server process ecdhe cipher suite fail.", 0, 0, 0, 0); + return ret; + } + + ctx->hsCtx->kxCtx->keyExchAlgo = cipherSuiteInfo.kxAlg; + (void)memcpy_s(&ctx->negotiatedInfo.cipherSuiteInfo, sizeof(CipherSuiteInfo), + &cipherSuiteInfo, sizeof(CipherSuiteInfo)); + return ret; +} + +static int32_t Tls13ServerNegotiateCipher(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, uint16_t cipher) +{ + (void)clientHello; + int32_t ret = 0; + CipherSuiteInfo cipherSuiteInfo = {0}; + + ret = CFG_GetCipherSuiteInfo(cipher, &cipherSuiteInfo); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15218, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "get cipher suite info fail when processing client hello.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_CIPHER_SUITE; + } + + (void)memcpy_s(&ctx->negotiatedInfo.cipherSuiteInfo, sizeof(CipherSuiteInfo), + &cipherSuiteInfo, sizeof(CipherSuiteInfo)); + return HITLS_SUCCESS; +} + +static int32_t CheckCipherSuite(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, uint16_t version, uint16_t cipherSuite) +{ + if ((CFG_CheckCipherSuiteSupported(cipherSuite) != true) || + (CFG_CheckCipherSuiteVersion(cipherSuite, version, version) != true)) { + return HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE; + } + int32_t ret = 0; + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + ret = Tls13ServerNegotiateCipher(ctx, clientHello, cipherSuite); + } else { + ret = ServerNegotiateCipher(ctx, clientHello, cipherSuite); + } + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check the security level of ciphersuites */ + CipherSuiteInfo *cipherSuiteInfo = &ctx->negotiatedInfo.cipherSuiteInfo; + ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_CIPHER_SHARED, 0, 0, (void *)cipherSuiteInfo); + if (ret != SECURITY_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSECURE_CIPHER_SUITE); + return HITLS_MSG_HANDLE_UNSECURE_CIPHER_SUITE; + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15221, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "chosen ciphersuite 0x%04x", + cipherSuiteInfo->cipherSuite, 0, 0, 0); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15894, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "chosen ciphersuite: %s", + cipherSuiteInfo->name); + + return HITLS_SUCCESS; +} + +// Select the cipher suite. +int32_t ServerSelectCipherSuite(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* Obtain server information */ + uint16_t version = ctx->negotiatedInfo.version; + uint16_t *cfgCipherSuites = ctx->config.tlsConfig.cipherSuites; + uint32_t cfgCipherSuitesSize = ctx->config.tlsConfig.cipherSuitesSize; + if (version == HITLS_VERSION_TLS13) { + cfgCipherSuites = ctx->config.tlsConfig.tls13CipherSuites; + cfgCipherSuitesSize = ctx->config.tlsConfig.tls13cipherSuitesSize; + } + + const uint16_t *preferenceCipherSuites = clientHello->cipherSuites; + uint16_t preferenceCipherSuitesSize = clientHello->cipherSuitesSize; + const uint16_t *normalCipherSuites = cfgCipherSuites; + uint16_t normalCipherSuitesSize = (uint16_t)cfgCipherSuitesSize; + + if (ctx->config.tlsConfig.isSupportServerPreference) { + preferenceCipherSuites = cfgCipherSuites; + preferenceCipherSuitesSize = (uint16_t)cfgCipherSuitesSize; + normalCipherSuites = clientHello->cipherSuites; + normalCipherSuitesSize = clientHello->cipherSuitesSize; + } + + /* Select the supported cipher suite. If the cipher suite is found, return success */ + for (uint16_t i = 0u; i < preferenceCipherSuitesSize; i++) { + for (uint32_t j = 0u; j < normalCipherSuitesSize; j++) { + if (normalCipherSuites[j] != preferenceCipherSuites[i]) { + continue; + } + if (CheckCipherSuite(ctx, clientHello, version, normalCipherSuites[j]) != HITLS_SUCCESS) { + break; + } + return HITLS_SUCCESS; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15222, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "can not find a appropriate cipher suite.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_CIPHER_SUITE_ERR; +} + +/** + * @brief Select the negotiation version based on the client Hello message. + * + * @param ctx [IN] TLS context + * @param clientHello [IN] client Hello message + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MSG_HANDLE_UNSUPPORT_VERSION Unsupported version number + */ +static int32_t ServerSelectNegoVersion(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + int32_t ret = 0; + uint16_t legacyVersion = clientHello->version; + if (legacyVersion > HITLS_VERSION_TLS13 && !IS_DTLS_VERSION(HS_GetVersion(ctx))) { + legacyVersion = HITLS_VERSION_TLS12; + } + /* Check whether DTLS is used */ + if (IS_DTLS_VERSION(legacyVersion)) { + if (legacyVersion > ctx->config.tlsConfig.minVersion) { + /** The DTLS version supported by the client is too early and the negotiation cannot be continued */ + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15223, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client want a unsupported protocol version 0x%02x.", legacyVersion, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + /** Continue the version negotiation and obtain the earlier DTLS version between the latest versions of the + * client and server */ + if (legacyVersion < ctx->config.tlsConfig.maxVersion) { + ctx->negotiatedInfo.version = ctx->config.tlsConfig.maxVersion; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15224, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client want a unsupported protocol version 0x%02x.", legacyVersion, 0, 0, 0); + } else { + ctx->negotiatedInfo.version = legacyVersion; + } + } else { + if (legacyVersion < ctx->config.tlsConfig.minVersion) { + /* The TLS version supported by the client is too early and cannot be negotiated */ + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15225, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client version = 0x%02x, min version = 0x%02x.", + legacyVersion, ctx->config.tlsConfig.minVersion, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + /* Continue the version negotiation. Obtain the earlier version between the latest versions of the client and + * server */ + if (legacyVersion > ctx->config.tlsConfig.maxVersion) { + ctx->negotiatedInfo.version = ctx->config.tlsConfig.maxVersion; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15226, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client version = 0x%02x, max version = 0x%02x.", + legacyVersion, ctx->config.tlsConfig.maxVersion, 0, 0); + } else { + ctx->negotiatedInfo.version = legacyVersion; + } + } + + /* Version security check */ + ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_VERSION, 0, ctx->negotiatedInfo.version, NULL); + if (ret != SECURITY_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSECURE_VERSION); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + return HITLS_MSG_HANDLE_UNSECURE_VERSION; + } + + return HITLS_SUCCESS; +} + +static int32_t ServerSelectAlpnProtocol(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + uint8_t *alpnSelected = NULL; + uint8_t alpnSelectedLen = 0u; + + /* If the callback is empty, the server does not have the ALPN processing capability. In this case, return success + */ + if (ctx->globalConfig != NULL && ctx->globalConfig->alpnSelectCb != NULL) { + int32_t alpnCbRet = ctx->globalConfig->alpnSelectCb(ctx, &alpnSelected, &alpnSelectedLen, + clientHello->extension.content.alpnList, clientHello->extension.content.alpnListSize, + ctx->globalConfig->alpnUserData); + if (alpnCbRet == HITLS_ALPN_ERR_OK) { + uint8_t *alpnSelectedTmp = (uint8_t *)BSL_SAL_Calloc(alpnSelectedLen + 1, sizeof(uint8_t)); + if (alpnSelectedTmp == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15227, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server malloc alpn buffer failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + if (memcpy_s(alpnSelectedTmp, alpnSelectedLen + 1, alpnSelected, alpnSelectedLen) != EOK) { + BSL_SAL_FREE(alpnSelectedTmp); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15243, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server copy selected alpn failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMCPY_FAIL; + } + BSL_SAL_FREE(ctx->negotiatedInfo.alpnSelected); + ctx->negotiatedInfo.alpnSelected = alpnSelectedTmp; + ctx->negotiatedInfo.alpnSelectedSize = alpnSelectedLen; + + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15228, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "select ALPN protocol: %s.", ctx->negotiatedInfo.alpnSelected); + /* Based on RFC7301, if the server cannot match the application layer protocol in the client alpn list, it + * sends a fatal alert to the peer. + * If the returned value is not HITLS_ALPN_ERR_NOACK, the system sends a fatal alert message to the peer + */ + } else if (alpnCbRet != HITLS_ALPN_ERR_NOACK) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ALPN_PROTOCOL_NO_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15229, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server invoke alpn select cb error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_NO_APPLICATION_PROTOCOL); + return HITLS_MSG_HANDLE_ALPN_PROTOCOL_NO_MATCH; + } + } + + return HITLS_SUCCESS; +} + +static int32_t ServerDealServerName(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + int32_t ret = 0; + int32_t alert = ALERT_UNRECOGNIZED_NAME; + uint32_t serverNameSize = clientHello->extension.content.serverNameSize; + + if (clientHello->extension.flag.haveServerName == false) { + return HITLS_SUCCESS; + } + + BSL_SAL_FREE(ctx->hsCtx->serverName); + ctx->hsCtx->serverName = (uint8_t *)BSL_SAL_Dump(clientHello->extension.content.serverName, + serverNameSize * sizeof(uint8_t)); + + if (ctx->hsCtx->serverName == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15230, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server_name malloc fail when parse extensions msg.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + + ctx->hsCtx->serverNameSize = serverNameSize; + + /* The product does not have the registered server_name callback processing function */ + if (ctx->globalConfig == NULL || ctx->globalConfig->sniDealCb == NULL) { + /* Rejected, but continued handshake */ + ctx->negotiatedInfo.isSniStateOK = false; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15231, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "during first handshake, server did not set sni callback deal, but continue handshake", 0, 0, 0, 0); + return HITLS_SUCCESS; + } + + /* Execute the product callback function */ + ret = ctx->globalConfig->sniDealCb(ctx, &alert, ctx->globalConfig->sniArg); + switch (ret) { + case HITLS_ACCEPT_SNI_ERR_OK: + ctx->negotiatedInfo.isSniStateOK = true; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15232, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "during first handshake, server accept server_name from client hello msg ", 0, 0, 0, 0); + break; + case HITLS_ACCEPT_SNI_ERR_NOACK: + ctx->negotiatedInfo.isSniStateOK = false; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15233, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,"during first handshake, \ + server did not accept server_name from client hello msg, but continue handshake", 0, 0, 0, 0); + break; + case HITLS_ACCEPT_SNI_ERR_ALERT_FATAL: + default: + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15234, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "during first handshake, server did not accept server_name from client hello msg, stop handshake", + 0, 0, 0, 0); + ctx->negotiatedInfo.isSniStateOK = false; + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNRECOGNIZED_NAME); + return HITLS_MSG_HANDLE_SNI_UNRECOGNIZED_NAME; + } + + return HITLS_SUCCESS; +} + +static int32_t DealResumeAlpnEx(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + if (clientHello->extension.flag.haveAlpn) { + return ServerSelectAlpnProtocol(ctx, clientHello); + } + return HITLS_SUCCESS; +} + +static int32_t DealResumeServerName(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, + uint32_t serverNameSize, uint8_t *serverName) +{ + /* Continue processing only when the TLS protocol version <=TLS1.2 */ + if (ctx->negotiatedInfo.version >= HITLS_VERSION_TLS13 && ctx->negotiatedInfo.version != HITLS_VERSION_DTLS12) { + return HITLS_SUCCESS; + } + + if (ctx->globalConfig != NULL && ctx->globalConfig->sniDealCb == NULL && serverNameSize == 0) { + ctx->negotiatedInfo.isSniStateOK = false; + return HITLS_SUCCESS; + } + + if (serverName != NULL && serverNameSize != 0 && clientHello->extension.flag.haveServerName == false) { + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15246, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "during session resumption, session server name is [%s]", (char *)serverName); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15933, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "There is no server name in client hello msg.", 0, 0, 0, 0); + ctx->negotiatedInfo.isSniStateOK = false; + + return HITLS_MSG_HANDLE_SNI_UNRECOGNIZED_NAME; + } + + /* Compare the extended value of client hello server_name and the value of server_name in the session during session + * resumption */ + if (clientHello->extension.content.serverNameSize != serverNameSize || + SNI_StrcaseCmp((char *)clientHello->extension.content.serverName, (char *)serverName) != 0) { + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15235, + BSL_LOG_LEVEL_ERR, + BSL_LOG_BINLOG_TYPE_RUN, + "during session resume ,session servername is [%s]", + (char *)serverName); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15254, + BSL_LOG_LEVEL_ERR, + BSL_LOG_BINLOG_TYPE_RUN, + "server did not accept server_name [%s] from client hello msg", + (char *)clientHello->extension.content.serverName); + ctx->negotiatedInfo.isSniStateOK = false; + + return HITLS_MSG_HANDLE_SNI_UNRECOGNIZED_NAME; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15236, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "during session resume, server accept server_name [%s] from client hello msg.", (char *)serverName, 0, 0, 0); + + return HITLS_SUCCESS; +} + +int32_t ServerCheckResumeCipherSuite(const ClientHelloMsg *clientHello, uint16_t cipherSuite) +{ + for (uint16_t i = 0u; i < clientHello->cipherSuitesSize; i++) { + if (cipherSuite == clientHello->cipherSuites[i]) { + return HITLS_SUCCESS; + } + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15237, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Client's cipher suites do not match resume cipher suite.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE; +} + +/* Check whether the session ID ctx matches */ +bool ServerCmpSessionIdCtx(TLS_Ctx *ctx, HITLS_Session *sess) +{ + uint8_t sessionIdCtx[HITLS_SESSION_ID_CTX_MAX_SIZE]; + uint32_t sessionIdCtxSize = HITLS_SESSION_ID_CTX_MAX_SIZE; + + if (HITLS_SESS_GetSessionIdCtx(sess, sessionIdCtx, &sessionIdCtxSize) != HITLS_SUCCESS) { + return false; + } + + /* The session ID ctx lengths are not equal */ + if (sessionIdCtxSize != ctx->config.tlsConfig.sessionIdCtxSize) { + return false; + } + + /* The session ID ctx is not equal */ + if (sessionIdCtxSize != 0 && memcmp(sessionIdCtx, ctx->config.tlsConfig.sessionIdCtx, sessionIdCtxSize) != 0) { + return false; + } + + return true; +} + +static int32_t ServerCheckResumeParam(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t version = 0; + uint16_t cipherSuite = 0; + HITLS_Session *sess = ctx->session; + + HITLS_SESS_GetProtocolVersion(sess, &version); + HITLS_SESS_GetCipherSuite(sess, &cipherSuite); + + if (ServerCmpSessionIdCtx(ctx, sess) != true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15886, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Resuming Sessions: session id ctx is inconsistent.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_SESSION_ID_CTX_ILLEGAL; + } + + if (ctx->negotiatedInfo.version != version) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15887, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Resuming Sessions: version is inconsistent.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_MSG_HANDLE_ILLEGAL_VERSION; + } + + ret = ServerCheckResumeCipherSuite(clientHello, cipherSuite); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return ret; + } + + ret = CFG_GetCipherSuiteInfo(cipherSuite, &ctx->negotiatedInfo.cipherSuiteInfo); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + /* During session resumption, the server processes the ALPN extension in the ClientHello message */ + return DealResumeAlpnEx(ctx, clientHello); +} + +static int32_t ServerCheckResumeSni(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, HITLS_Session **sess) +{ + if (*sess == NULL || ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLCP11) { + return HITLS_SUCCESS; + } + int32_t ret = HITLS_SUCCESS; + uint8_t *serverName = NULL; + uint32_t serverNameSize = 0; + + SESS_GetHostName(*sess, &serverNameSize, &serverName); + + /* During session resumption, the server processes the server_name extension in the ClientHello */ + ret = DealResumeServerName(ctx, clientHello, serverNameSize, serverName); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(*sess); + *sess = NULL; + } + return HITLS_SUCCESS; +} + +/** + rfc7627 5.3 + If a server receives a ClientHello for an abbreviated handshake +offering to resume a known previous session, it behaves as follows: +-------------------------------------------------------------------------------------------------------- +| original sesson | abbreviated handshake | Server behavior | +| :-------------: | :--------------------: | :---------------------------------------------------------:| +| true | true | SH with ems, agree resume | +| true | false | abort handshake | +| false | true | disagre resume, full handshake | +| false | false | depend cnf: abort handshake(true) / agree resume (false) | +*/ +static int32_t ResumeCheckExtendedMasterScret(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, HITLS_Session **sess) +{ + if (*sess == NULL || ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLCP11) { + return HITLS_SUCCESS; + } + uint8_t haveExtMasterSecret = false; + HITLS_SESS_GetHaveExtMasterSecret(*sess, &haveExtMasterSecret); + if (haveExtMasterSecret != 0) { + if (!clientHello->extension.flag.haveExtendedMasterSecret) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_INVALID_EXTENDED_MASTER_SECRET; + } + ctx->negotiatedInfo.isExtendedMasterSecret = true; + } else { + if (clientHello->extension.flag.haveExtendedMasterSecret) { + HITLS_SESS_Free(*sess); + *sess = NULL; + } else if (ctx->config.tlsConfig.isSupportExtendMasterSecret) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_INVALID_EXTENDED_MASTER_SECRET; + } + ctx->negotiatedInfo.isExtendedMasterSecret = clientHello->extension.flag.haveExtendedMasterSecret; + } + return ServerCheckResumeSni(ctx, clientHello, sess); +} + +static int32_t ServerCheckResumeTicket(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr; + HITLS_Session *sess = NULL; + uint8_t *ticketBuf = clientHello->extension.content.ticket; + uint32_t ticketBufSize = clientHello->extension.content.ticketSize; + bool isTicketExpect = false; + int32_t ret = SESSMGR_DecryptSessionTicket(sessMgr, &sess, ticketBuf, ticketBufSize, &isTicketExpect); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16045, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESSMGR_DecryptSessionTicket return fail when process client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + ctx->negotiatedInfo.isTicket = isTicketExpect; + ret = ResumeCheckExtendedMasterScret(ctx, clientHello, &sess); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(sess); + sess = NULL; + return ret; + } + if (sess != NULL) { + /* Check whether the session is valid */ + if (SESS_CheckValidity(sess, (uint64_t)BSL_SAL_CurrentSysTimeGet()) == false) { + /* If the session is invalid, a message is returned and the session is not resume. The complete connection + * is established */ + ctx->negotiatedInfo.isTicket = true; + HITLS_SESS_Free(sess); + return HITLS_SUCCESS; + } + HITLS_SESS_Free(ctx->session); + ctx->session = sess; + ctx->negotiatedInfo.isResume = true; + /* If the session is resumed and the session ID of the clientHello is not empty, the session ID needs to be + * filled in the serverHello and returned */ + HITLS_SESS_SetSessionId(ctx->session, clientHello->sessionId, clientHello->sessionIdSize); + } + return HITLS_SUCCESS; +} + +/* Check whether the resume function is supported */ +static int32_t ServerCheckResume(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + ctx->negotiatedInfo.isResume = false; + ctx->negotiatedInfo.isTicket = false; + /* If session resumption is not allowed in the renegotiation state, return */ + if (ctx->negotiatedInfo.isRenegotiation && !ctx->config.tlsConfig.isResumptionOnRenego) { + return HITLS_SUCCESS; + } + /* Obtain the session resumption information */ + TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr; + /* Create a null session handle */ + HITLS_Session *sess = NULL; + uint32_t ticketBufSize = clientHello->extension.content.ticketSize; + bool supportTicket = IsTicketSupport(ctx); + /* rfc5077 3.4 If a ticket is presented by the client, the server + MUST NOT attempt to use the Session ID in the ClientHello for stateful + session resumption. */ + if (ticketBufSize == 0u) { + if (supportTicket && clientHello->extension.flag.haveTicket) { + ctx->negotiatedInfo.isTicket = true; + } + sess = HITLS_SESS_Dup(SESSMGR_Find(sessMgr, clientHello->sessionId, clientHello->sessionIdSize)); + int32_t ret = ResumeCheckExtendedMasterScret(ctx, clientHello, &sess); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(sess); + sess = NULL; + return ret; + } + if (sess != NULL) { + /* Update session handle information */ + HITLS_SESS_Free(ctx->session); + ctx->session = sess; // has ensured that it will not fail + sess = NULL; + ctx->negotiatedInfo.isResume = true; + } + return HITLS_SUCCESS; + } + if (supportTicket) { + return ServerCheckResumeTicket(ctx, clientHello); + } + return HITLS_SUCCESS; +} + +static int32_t ServerCheckRenegoInfoDuringFirstHandshake(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* If the peer does not support security renegotiation, the system returns */ + if (!clientHello->haveScsvCipher && !clientHello->extension.flag.haveSecRenego) { + if (ctx->config.tlsConfig.noSecRenegotiationCb != NULL) { + /* The user can determine whether to terminate the connection when the peer does not support security + * renegotiation */ + int32_t ret = ctx->config.tlsConfig.noSecRenegotiationCb(ctx); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15957, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "noSecRenegotiationCb return fail when process client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return ret; + } + } + return HITLS_SUCCESS; + } + + /* For the first handshake, if the security renegotiation information is not empty, return an error code. */ + if (clientHello->extension.content.secRenegoInfoSize != 0) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15889, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "secRenegoInfoSize should be 0 in server initial handhsake.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + + /* Setting the Support for Security Renegotiation */ + ctx->negotiatedInfo.isSecureRenegotiation = true; + return HITLS_SUCCESS; +} + +static int32_t ServerCheckRenegoInfoDuringRenegotiation(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* If the renegotiation status contains the SCSV cipher suite, return an error code. */ + if (clientHello->haveScsvCipher) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15890, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SCSV cipher should not be in server secure renegotiation.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + + /* Verify the security renegotiation information */ + if (clientHello->extension.content.secRenegoInfoSize != ctx->negotiatedInfo.clientVerifyDataSize) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15891, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "secRenegoInfoSize verify failed during server renegotiation.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + if (memcmp(clientHello->extension.content.secRenegoInfo, ctx->negotiatedInfo.clientVerifyData, + ctx->negotiatedInfo.clientVerifyDataSize) != 0) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15892, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "secRenegoInfo verify failed during server renegotiation.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + + return HITLS_SUCCESS; +} + +static int32_t ServerCheckCompressionMethods(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* If the compression method list contains no compression, return success */ + for (uint32_t i = 0; i < clientHello->compressionMethodsSize; i++) { + // If the compression method contains no compression (0), a parsing success message is returne + if (clientHello->compressionMethods[i] == 0u) { + return HITLS_SUCCESS; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15706, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "can not find a appropriate compression method in client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD; +} + +static int32_t Tls13ServerCheckCompressionMethods(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + if (clientHello->compressionMethodsSize != 1u) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15842, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the compression length of client hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD; + } + + /* If the compression method list contains no compression, return success */ + // If the compression method contains no compression (0), a parsing success message is returne + if (clientHello->compressionMethods[0] == 0u) { + return HITLS_SUCCESS; + } + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15843, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "can not find a appropriate compression method in client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_INVALID_COMPRESSION_METHOD; +} + +static int32_t ServerCheckAndProcessRenegoInfo(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* Not in the renegotiation state */ + if (!ctx->negotiatedInfo.isRenegotiation) { + return ServerCheckRenegoInfoDuringFirstHandshake(ctx, clientHello); + } + + /* in the renegotiation state */ + return ServerCheckRenegoInfoDuringRenegotiation(ctx, clientHello); +} + +static int32_t ServerCheckEncryptThenMac(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + bool haveEncryptThenMac = clientHello->extension.flag.haveEncryptThenMac; + /* Renegotiation cannot be downgraded from EncryptThenMac to MacThenEncrypt */ + if (ctx->negotiatedInfo.isRenegotiation && ctx->negotiatedInfo.isEncryptThenMac && !haveEncryptThenMac) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ENCRYPT_THEN_MAC_ERR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15919, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "regotiation should not change encrypt then mac to mac then encrypt.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_ENCRYPT_THEN_MAC_ERR; + } + + /* If EncryptThenMac is not configured, return HITLS_SUCCESS. */ + if (!ctx->config.tlsConfig.isEncryptThenMac) { + return HITLS_SUCCESS; + } + + /* TLS 1.3 does not need to negotiate this expansion. */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + return HITLS_SUCCESS; + } + + /* Only the CBC cipher suite has the EncryptThenMac setting. */ + if (haveEncryptThenMac && ctx->negotiatedInfo.cipherSuiteInfo.cipherType == HITLS_CBC_CIPHER) { + ctx->negotiatedInfo.isEncryptThenMac = true; + } else { + ctx->negotiatedInfo.isEncryptThenMac = false; + } + + return HITLS_SUCCESS; +} + +static int32_t ServerSelectCipherSuiteInfo(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + int32_t ret = ServerSelectCipherSuite(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15239, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server select cipher suite fail.", 0, 0, 0, 0); + return ret; + } + + /* Select the encryption mode (EncryptThenMac/MacThenEncrypt) */ + ret = ServerCheckEncryptThenMac(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +static int32_t ServerProcessClientHelloExt(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + int32_t ret; + /* Sets the extended master key flag */ + if (ctx->negotiatedInfo.version > HITLS_VERSION_SSL30 && ctx->config.tlsConfig.isSupportExtendMasterSecret && + !clientHello->extension.flag.haveExtendedMasterSecret) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15566, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "The peer does not support the extended master key.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_INVALID_EXTENDED_MASTER_SECRET; + } + ctx->negotiatedInfo.isExtendedMasterSecret = clientHello->extension.flag.haveExtendedMasterSecret; + + /* The message contains a server_name extension whose length is greater than 0 */ + ret = ServerDealServerName(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (clientHello->extension.flag.haveAlpn) { + ret = ServerSelectAlpnProtocol(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + /* Logs have been recorded internally */ + return ret; + } + } + + return HITLS_SUCCESS; +} + +// Check client Hello messages +static int32_t ServerCheckAndProcessClientHello(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /* Negotiated version */ + int32_t ret = ServerSelectNegoVersion(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15238, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server select negotiated version fail.", 0, 0, 0, 0); + return ret; + } + + ret = ServerCheckCompressionMethods(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Copy random numbers */ + if (memcpy_s(hsCtx->clientRandom, HS_RANDOM_SIZE, clientHello->randomValue, HS_RANDOM_SIZE) != EOK) { + return HITLS_MEMCPY_FAIL; + } + + ret = ServerCheckAndProcessRenegoInfo(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ServerCheckResume(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->negotiatedInfo.isResume) { + return ServerCheckResumeParam(ctx, clientHello); + } + + ret = ServerSelectCipherSuiteInfo(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* TLCP does not pay attention to the extension */ + +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11) { + return HITLS_SUCCESS; + } +#endif + return ServerProcessClientHelloExt(ctx, clientHello); +} + +static int32_t ClientHelloCbCheck(TLS_Ctx *ctx) +{ + int32_t ret; + int32_t alert = ALERT_INTERNAL_ERROR; + const TLS_Config *tlsConfig = ctx->globalConfig; + if (tlsConfig != NULL && tlsConfig->clientHelloCb != NULL) { + ret = tlsConfig->clientHelloCb(ctx, &alert, tlsConfig->clientHelloCbArg); + if (ret != HITLS_CONTINUE_HANDHSAKE) { + BSL_ERR_PUSH_ERROR(HITLS_CLIENT_HELLO_CHECK_ERROR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15240, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "The result of ClientHello callback is %d, and the reason is %d.", ret, alert, 0, 0); + if (alert >= ALERT_CLOSE_NOTIFY && alert <= ALERT_UNKNOWN) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, alert); + } + return HITLS_CLIENT_HELLO_CHECK_ERROR; + } + } + return HITLS_SUCCESS; +} + +int32_t Tls12ServerRecvClientHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + const ClientHelloMsg *clientHello = &msg->body.clientHello; + + CheckRenegotiate(ctx); + + /* Perform the ClientHello callback. The pause handshake status is not considered */ + int32_t ret = ClientHelloCbCheck(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Process the client Hello message */ + ret = ServerCheckAndProcessClientHello(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO); +} + +// The server processes the DTLS client hello message. +#ifndef HITLS_NO_DTLS12 +int32_t DtlsServerRecvClientHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret; + const ClientHelloMsg *clientHello = &msg->body.clientHello; + + CheckRenegotiate(ctx); + + /* Process the client Hello message */ + ret = ServerCheckAndProcessClientHello(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15244, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server process clientHello fail.", 0, 0, 0, 0); + return ret; + } + + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO); +} +#endif + +static uint32_t GetClientKeMode(const ExtensionContent *extension) +{ + uint32_t clientKeMode = 0; + for (uint32_t i = 0; i < extension->keModesSize; i++) { + /* Ignore the received keMode of other types */ + if (extension->keModes[i] == PSK_KE) { + clientKeMode |= TLS13_KE_MODE_PSK_ONLY; + } else if (extension->keModes[i] == PSK_DHE_KE) { + clientKeMode |= TLS13_KE_MODE_PSK_WITH_DHE; + } + } + return clientKeMode; +} + +static bool CheckClientHelloKeyShareValid(const ClientHelloMsg *clientHello, uint16_t keyShareGroup) +{ + for (uint32_t i = 0; i < clientHello->extension.content.supportedGroupsSize; i++) { + if (keyShareGroup == clientHello->extension.content.supportedGroups[i]) { + return true; + } + } + return false; +} + +static int32_t ServerCheckKeyShare(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + /* Prerequisite. If the PSK is not negotiated or the PSK requires dhe, a handshake failure message needs to be + * reported if the keyshare does not exist */ + if (clientHello->extension.flag.haveKeyShare == false || clientHello->extension.content.supportedGroupsSize == 0u || + ProcessEcdheCipherSuite(ctx, clientHello) != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_HANDSHAKE_FAILURE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15881, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unable to negotiate a supported set of parameters.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_HANDSHAKE_FAILURE; + } + + /* ProcessEcdheCipherSuite returns a success response. There must be a public group */ + KeyShareParam *keyShare = &ctx->hsCtx->kxCtx->keyExchParam.share; + uint16_t selectGroup = keyShare->group; + KeyShare *cache = clientHello->extension.content.keyShare; + /* rfc8446 4.2.8 Otherwise, when sending the new ClientHello, the client MUST + replace the original "key_share" extension with one containing only a + new KeyShareEntry for the group indicated in the selected_group field + of the triggering HelloRetryRequest. */ + if (ctx->hsCtx->haveHrr) { + if (cache == NULL || cache->head.next != cache->head.prev || // parse must contain elements. + LIST_ENTRY(cache->head.next, KeyShare, head)->group != selectGroup) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15844, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "hrr client hello key Share error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + } + return HITLS_SUCCESS; +} + +static int32_t Tls13ServerProcessKeyShare(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, bool *isNeedSendHrr) +{ + /* Prerequisite. If the PSK is not negotiated or the PSK requires dhe, a handshake failure message needs to be + * reported if the keyshare does not exist */ + int32_t ret = ServerCheckKeyShare(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* ServerCheckKeyShare returns a success response. There must be a public group */ + KeyShareParam *keyShare = &ctx->hsCtx->kxCtx->keyExchParam.share; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + uint16_t selectGroup = keyShare->group; + ListHead *node = NULL; + ListHead *tmpNode = NULL; + KeyShare *cur = NULL; + KeyShare *cache = clientHello->extension.content.keyShare; + if (cache == NULL) { + /* According to section 4.2.8 in RFC8446, if the client requests HelloRetryRequest, keyShare can be empty */ + *isNeedSendHrr = true; + return HITLS_SUCCESS; + } + + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(cache->head)) { + cur = LIST_ENTRY(node, KeyShare, head); + /* rfc8446 4.2.8 Clients MUST NOT offer any KeyShareEntry values + for groups not listed in the client's "supported_groups" extension. + Servers MAY check for violations of these rules and abort the + handshake with an "illegal_parameter" alert if one is violated. */ + if (!CheckClientHelloKeyShareValid(clientHello, cur->group)) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15882, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "The group in the keyshare does not exist in the support group extension.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + if (cur->group != selectGroup) { + continue; + } + + *isNeedSendHrr = false; + /* Obtain the peer public key */ + kxCtx->pubKeyLen = cur->keyExchangeSize; + if (HS_GetNamedCurvePubkeyLen(keyShare->group) != kxCtx->pubKeyLen) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15345, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid keyShare length.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + BSL_SAL_FREE(kxCtx->peerPubkey); + kxCtx->peerPubkey = BSL_SAL_Dump(cur->keyExchange, cur->keyExchangeSize); + if (kxCtx->peerPubkey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15245, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc peerPubkey fail when process client key share.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + ctx->negotiatedInfo.negotiatedGroup = selectGroup; + return HITLS_SUCCESS; + } + + /* If the server selects a group that does not exist in the keyshare, the server needs to send a hello retry request + */ + *isNeedSendHrr = true; + return HITLS_SUCCESS; +} + +static int32_t GetPskFromSession(TLS_Ctx *ctx, HITLS_Session *pskSession, uint8_t *psk, uint32_t pskLen, + uint32_t *usedLen) +{ + /* The session is available and the PSK is obtained */ + uint32_t tmpLen = pskLen; + int32_t ret = HITLS_SESS_GetMasterKey(pskSession, psk, &tmpLen); + if (ret != HITLS_SUCCESS) { + /* An internal error occurs and cannot be continued. Return an error code and an alert message is sent + */ + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + *usedLen = tmpLen; + return HITLS_SUCCESS; +} + +int32_t PskFindSession(TLS_Ctx *ctx, const uint8_t *id, uint32_t idLen, HITLS_Session **pskSession) +{ + if (ctx->config.tlsConfig.pskFindSessionCb == NULL) { + /* No callback is set */ + return HITLS_SUCCESS; + } + + int32_t ret = ctx->config.tlsConfig.pskFindSessionCb(ctx, id, idLen, pskSession); + if (ret != HITLS_PSK_FIND_SESSION_CB_SUCCESS) { + /* Internal error, cannot continue */ + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_PSK_FIND_SESSION_FAIL; + } + + return HITLS_SUCCESS; +} + +int32_t GetPskByIdentity(TLS_Ctx *ctx, const uint8_t *id, uint32_t idLen, uint8_t *psk, uint32_t *pskLen) +{ + if (ctx->config.tlsConfig.pskServerCb == NULL) { + *pskLen = 0; + return HITLS_SUCCESS; + } + + uint8_t *strId = BSL_SAL_Calloc(1u, idLen + 1); + if (strId == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(strId, idLen + 1, id, idLen); + strId[idLen] = '\0'; + + uint32_t usedLen = ctx->config.tlsConfig.pskServerCb(ctx, strId, psk, *pskLen); + BSL_SAL_FREE(strId); + if (usedLen > HS_PSK_MAX_LEN) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN; + } + + *pskLen = usedLen; + return HITLS_SUCCESS; +} + +static int32_t Tls13ServerSetPskInfo(TLS_Ctx *ctx, uint8_t *psk, uint32_t pskLen, uint16_t index) +{ + PskInfo13 *pskInfo13 = &ctx->hsCtx->kxCtx->pskInfo13; + BSL_SAL_FREE(pskInfo13->psk); + pskInfo13->psk = BSL_SAL_Dump(psk, pskLen); + if (pskInfo13->psk == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + pskInfo13->pskLen = pskLen; + pskInfo13->selectIndex = index; + return HITLS_SUCCESS; +} + +static bool IsPSKValid(const TLS_Ctx *ctx, HITLS_Session *pskSession) +{ + uint16_t version, cipherSuite; + HITLS_SESS_GetProtocolVersion(pskSession, &version); + if (version != HITLS_VERSION_TLS13) { + return false; + } + + HITLS_SESS_GetCipherSuite(pskSession, &cipherSuite); + CipherSuiteInfo cipherInfo = {0}; + int32_t ret = CFG_GetCipherSuiteInfo(cipherSuite, &cipherInfo); + if (ret != HITLS_SUCCESS) { + return false; + } + + if (cipherInfo.hashAlg != ctx->negotiatedInfo.cipherSuiteInfo.hashAlg) { + return false; + } + + return true; +} + +static int32_t TLS13ServerProcessTicket(TLS_Ctx *ctx, PreSharedKey *cur, + uint8_t *psk, uint32_t *pskLen) +{ + const uint8_t *ticket = cur->identity; + uint32_t ticketLen = cur->identitySize; + bool isTicketExcept = 0; + HITLS_Session *pskSession = NULL; + + int32_t ret = SESSMGR_DecryptSessionTicket(ctx->config.tlsConfig.sessMgr, &pskSession, + ticket, ticketLen, &isTicketExcept); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16048, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Decrypt Ticket fail when processing client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* Do not resume the session. TLS1.3 does not need to check isTicketExceptt */ + if (pskSession == NULL) { + *pskLen = 0; + return HITLS_SUCCESS; + } + + /* Check whether the session is valid */ + if (!IsPSKValid(ctx, pskSession) || + !SESS_CheckObfuscatedTicketAge(pskSession, (uint64_t)BSL_SAL_CurrentSysTimeGet(), cur->obfuscatedTicketAge)) { + /* Do not resume the session */ + *pskLen = 0; + HITLS_SESS_Free(pskSession); + return HITLS_SUCCESS; + } + + if (ServerCmpSessionIdCtx(ctx, pskSession) != true) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15462, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLS1.3 Resuming Session: session id ctx is inconsistent.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + HITLS_SESS_Free(pskSession); + return HITLS_MSG_HANDLE_SESSION_ID_CTX_ILLEGAL; + } + + ret = GetPskFromSession(ctx, pskSession, psk, *pskLen, pskLen); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(pskSession); + return ret; + } + + if (*pskLen == 0) { + HITLS_SESS_Free(pskSession); + return HITLS_SUCCESS; + } + + HITLS_SESS_Free(ctx->session); + ctx->session = pskSession; + ctx->negotiatedInfo.isResume = true; + return HITLS_SUCCESS; +} + +static int32_t ServerFindPsk(TLS_Ctx *ctx, PreSharedKey *cur, + uint8_t *psk, uint32_t *pskLen) +{ + const uint8_t *identity = cur->identity; + uint32_t identitySize = cur->identitySize; + int32_t ret; + HITLS_Session *pskSession = NULL; + uint32_t pskSize = *pskLen; + ctx->negotiatedInfo.isResume = false; + + ret = PskFindSession(ctx, identity, identitySize, &pskSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* TLS 1.3 processing */ + if (pskSession != NULL) { + /* In TLS1.3, pskSession is transferred by the user. Check the corresponding version and cipher suite */ + if (IsPSKValid(ctx, pskSession) == false) { + HITLS_SESS_Free(pskSession); /* Unsuitable sessions are released. */ + *pskLen = 0; + return HITLS_SUCCESS; + } + + ret = GetPskFromSession(ctx, pskSession, psk, pskSize, pskLen); + HITLS_SESS_Free(pskSession); /* After the session is used, the session is released. */ + return ret; + } + + /* + * By default, the hash algorithm used by the pskSession cipher suite is SHA_256. + * In this case, you only need to check whether the hash algorithm of the negotiated cipher suite is SHA_256. + */ + if (ctx->negotiatedInfo.cipherSuiteInfo.hashAlg == HITLS_HASH_SHA_256) { + ret = GetPskByIdentity(ctx, identity, identitySize, psk, &pskSize); + if (ret != HITLS_SUCCESS) { + /* An internal error occurs and the process cannot be continued. return an error code */ + return ret; + } + if (pskSize > 0u) { + *pskLen = pskSize; + return HITLS_SUCCESS; + } + } + + /* Try to decrypt the ticket for session resumption */ + ret = TLS13ServerProcessTicket(ctx, cur, psk, pskLen); + return ret; +} + +int32_t CompareBinder(TLS_Ctx *ctx, const PreSharedKey *pskNode, uint8_t *psk, uint32_t pskLen, + uint32_t truncateHelloLen) +{ + int32_t ret; + uint8_t *recvBinder = pskNode->binder; + uint32_t recvBinderLen = pskNode->binderSize; + HITLS_HashAlgo hashAlg = ctx->negotiatedInfo.cipherSuiteInfo.hashAlg; + bool isExternalPsk = !(ctx->negotiatedInfo.isResume); + uint8_t computedBinder[HS_MAX_BINDER_SIZE] = {0}; + + uint32_t binderLen = HS_GetBinderLen(NULL, &hashAlg); + if (binderLen == 0 || binderLen != recvBinderLen || binderLen > HS_MAX_BINDER_SIZE) { + return HITLS_INTERNAL_EXCEPTION; + } + + ret = VERIFY_CalcPskBinder(ctx, hashAlg, isExternalPsk, psk, pskLen, ctx->hsCtx->msgBuf, truncateHelloLen, + computedBinder, binderLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = memcmp(computedBinder, recvBinder, binderLen); + if (ret != 0) { + return HITLS_INTERNAL_EXCEPTION; + } + return ret; +} + +/* Prior to accepting PSK key establishment, the server MUST validate the corresponding binder value (see + * Section 4.2.11.2 below). If this value is not present or does not validate, the server MUST abort the handshake. + * Servers SHOULD NOT attempt to validate multiple binders; rather, they SHOULD select a single PSK and validate solely + * the binder that corresponds to that PSK. + */ +static int32_t ServerSelectPskAndCheckBinder(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + int32_t ret = HITLS_SUCCESS; + uint16_t index = 0; + + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + + ListHead *node = NULL; + ListHead *tmpNode = NULL; + PreSharedKey *cur = NULL; + PreSharedKey *offeredPsks = clientHello->extension.content.preSharedKey; + + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(offeredPsks->pskNode)) + { + uint32_t pskLen = HS_PSK_MAX_LEN; + cur = LIST_ENTRY(node, PreSharedKey, pskNode); + + ret = ServerFindPsk(ctx, cur, psk, &pskLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (pskLen == 0) { + index++; + /* The corresponding psk cannot be found. Search for the next psk */ + continue; + } + /* An available psk is found */ + ret = Tls13ServerSetPskInfo(ctx, psk, pskLen, index); + if (ret != HITLS_SUCCESS) { + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); /* Clear sensitive memory */ + return ret; + } + ret = CompareBinder(ctx, cur, psk, pskLen, clientHello->truncateHelloLen); + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); /* Clear sensitive memory */ + if (ret != HITLS_SUCCESS) { + /* RFC8446 Section 6.2:decrypt_error: A handshake (not record layer) cryptographic + operation failed, including being unable to correctly verify a + signature or validate a Finished message or a PSK binder. */ + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + return ret; + } + cur->isValid = true; + break; + } + return ret; +} + +static int32_t Tls13ServerSetSessionId(TLS_Ctx *ctx, const uint8_t *sessionId, uint32_t sessionIdSize) +{ + + if (sessionIdSize == 0) { + ctx->hsCtx->sessionIdSize = sessionIdSize; + return HITLS_SUCCESS; + } + + uint8_t *tmpSession = BSL_SAL_Dump(sessionId, sessionIdSize); + if (tmpSession == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15248, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc sessionId fail when process client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + BSL_SAL_FREE(ctx->hsCtx->sessionId); // Clearing old memory + ctx->hsCtx->sessionId = tmpSession; + ctx->hsCtx->sessionIdSize = sessionIdSize; + return HITLS_SUCCESS; +} + +static int32_t Tls13ServerCheckClientHelloExtension(TLS_Ctx *ctx, const ClientHelloMsg *clientHello) +{ + do { + /* If not containing a "pre_shared_key" extension, it MUST contain + both a "signature_algorithms" extension and a "supported_groups" + extension. */ + if ((!clientHello->extension.flag.havePreShareKey) && (!clientHello->extension.flag.haveSignatureAlgorithms || + !clientHello->extension.flag.haveSupportedGroups)) { + break; + } + + /* If containing a "supported_groups" extension, it MUST also contain + a "key_share" extension, and vice versa. */ + if ((clientHello->extension.flag.haveSupportedGroups && !clientHello->extension.flag.haveKeyShare) || + (!clientHello->extension.flag.haveSupportedGroups && clientHello->extension.flag.haveKeyShare)) { + break; + } + + /* A client MUST provide a "psk_key_exchange_modes" extension if it + offers a "pre_shared_key" extension. */ + if (clientHello->extension.flag.havePreShareKey && !clientHello->extension.flag.havePskExMode) { + break; + } + + // with psk && psk mode is dhe && without keyshare + uint32_t clientKeMode = GetClientKeMode(&clientHello->extension.content); + if (clientHello->extension.flag.havePreShareKey && + (clientKeMode & TLS13_KE_MODE_PSK_WITH_DHE) == TLS13_KE_MODE_PSK_WITH_DHE && + !clientHello->extension.flag.haveKeyShare) { + break; + } + return HITLS_SUCCESS; + } while (false); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_MISSING_EXTENSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15883, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "invalid client hello: minssing extension.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_MISSING_EXTENSION); + return HITLS_MSG_HANDLE_MISSING_EXTENSION; +} + +static int32_t Tls13ServerCheckSecondClientHello(TLS_Ctx *ctx, ClientHelloMsg *clientHello) +{ + if (ctx->hsCtx->haveHrr) { + if (ctx->hsCtx->firstClientHello->cipherSuitesSize != clientHello->cipherSuitesSize || + memcmp(ctx->hsCtx->firstClientHello->cipherSuites, clientHello->cipherSuites, + clientHello->cipherSuitesSize * sizeof(uint16_t)) != 0) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE; + } + return HITLS_SUCCESS; + } + if (ctx->hsCtx->firstClientHello != NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_INTERNAL_EXCEPTION; + } + ctx->hsCtx->firstClientHello = (ClientHelloMsg *)BSL_SAL_Dump(clientHello, sizeof(ClientHelloMsg)); + if (ctx->hsCtx->firstClientHello == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15538, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "clientHello malloc fail.", 0, + 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + clientHello->refCnt = 1; + return HITLS_SUCCESS; +} +static int32_t Tls13ServerBasicCheckClientHello(TLS_Ctx *ctx, ClientHelloMsg *clientHello) +{ + int32_t ret = Tls13ServerCheckSecondClientHello(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Set the negotiated version number */ + ctx->negotiatedInfo.version = HITLS_VERSION_TLS13; + + ret = Tls13ServerCheckCompressionMethods(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Copy random numbers */ + ret = memcpy_s(ctx->hsCtx->clientRandom, HS_RANDOM_SIZE, clientHello->randomValue, HS_RANDOM_SIZE); + if (ret != EOK) { + return ret; + } + + /* Copy the session ID */ + ret = Tls13ServerSetSessionId(ctx, clientHello->sessionId, clientHello->sessionIdSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ServerSelectCipherSuite(ctx, clientHello); + return ret; +} + +static int32_t Tls13ServerCheckClientHello(TLS_Ctx *ctx, ClientHelloMsg *clientHello, bool *isNeedSendHrr) +{ + uint32_t selectKeMode = 0; + + int32_t ret = Tls13ServerBasicCheckClientHello(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* rfc8446 9.2. Mandatory-to-Implement Extensions */ + ret = Tls13ServerCheckClientHelloExtension(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t clientKeMode = GetClientKeMode(&clientHello->extension.content); + selectKeMode = clientKeMode & ctx->config.tlsConfig.keyExchMode; + if (clientHello->extension.flag.havePreShareKey && selectKeMode != 0) { + /* calculate the binder value and compare it with the received binder value. */ + ret = ServerSelectPskAndCheckBinder(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_PSK_INVALID); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15940, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "ServerSelectPskAndCheckBinder failed.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_PSK_INVALID; + } + } + + if (ctx->hsCtx->kxCtx->pskInfo13.psk == NULL || + (selectKeMode & TLS13_KE_MODE_PSK_WITH_DHE) == TLS13_KE_MODE_PSK_WITH_DHE) { + ret = Tls13ServerProcessKeyShare(ctx, clientHello, isNeedSendHrr); + /* The group has been selected during the cipher suite selection. Therefore, the keyshare can be processed here + */ + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* Process the server_name extension whose length is greater than 0 in the TLS1.3 message */ + ret = ServerDealServerName(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (clientHello->extension.flag.haveAlpn && !(*isNeedSendHrr)) { + ret = ServerSelectAlpnProtocol(ctx, clientHello); + if (ret != HITLS_SUCCESS) { + /* Logs have been recorded internally */ + return ret; + } + } + + return Tls13ServerSelectCert(ctx, clientHello); +} + +static int32_t CheckVersion(uint16_t version, uint16_t minVersion, uint16_t maxVersion, uint16_t *selectVersion) +{ + if (version >= HITLS_VERSION_TLS13 && !IS_DTLS_VERSION(maxVersion)) { + version = HITLS_VERSION_TLS12; + } +#ifndef HITLS_NO_TLCP11 + if (((version > HITLS_VERSION_SSL30) || (version == HITLS_VERSION_TLCP11)) && +#else + if ((version > HITLS_VERSION_SSL30) && +#endif + (minVersion <= version) && (version <= maxVersion)) { + *selectVersion = version; + return HITLS_SUCCESS; + } + + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; +} + +bool IsTls13KeyExchAvailable(TLS_Ctx *ctx) +{ + TLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *certMgrCtx = config->certMgrCtx; + + if (config->pskServerCb != NULL) { + return true; + } + + if (config->pskFindSessionCb != NULL) { + return true; + } + + /* The PSK is not used. The certificate must be set */ + for (uint32_t i = 0; i < TLS_CERT_KEY_TYPE_NUM; i++) { + if (i == TLS_CERT_KEY_TYPE_DSA) { + /* in TLS1.3, Do not use the DSA certificate. */ + continue; + } + if ((SAL_CERT_GetCert(certMgrCtx, i) != NULL) && (SAL_CERT_GetPrivateKey(certMgrCtx, i) != NULL)) { + return true; + } + } + return false; +} + +static int32_t SelectVersion(TLS_Ctx *ctx, const ClientHelloMsg *clientHello, uint16_t minVersion, uint16_t maxVersion, + uint16_t *selectVersion) +{ + int32_t ret; + uint16_t version = clientHello->version; + + /** + * According to rfc8446 section 4.2.1 if the ClientHello does not have the supportedVersions extension, + * Then the server must negotiate TLS 1.2 or earlier as specified in rfc5246. + */ + if (clientHello->extension.content.supportedVersionsCount == 0) { + ret = CheckVersion(version, minVersion, maxVersion, selectVersion); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15885, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server cannot negotiate a version.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + } + return ret; + } + + /* If the received message is not an earlier version, the version byte in the tls1.3 must be 0x0303 according to + * section 4.1.2 in RFC 8446 */ + if (version != HITLS_VERSION_TLS12) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15249, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "illegal client legacy_version(0x%02x).", version, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + + /* Find the supported version in the extended field supportedVersions. */ + for (version = maxVersion; version >= minVersion; version--) { + for (int i = 0; i < clientHello->extension.content.supportedVersionsCount; i++) { + if (clientHello->extension.content.supportedVersions[i] != version) { + continue; + } + if (((version == HITLS_VERSION_TLS13) && (!IsTls13KeyExchAvailable(ctx))) || + (version <= HITLS_VERSION_SSL30)) { + /* TLS1.3 must have an available PSK or certificate, and TLS1.3 cannot negotiate SSL versions earlier + * than SSL3.0. */ + continue; + } + /* rfc8446 4.2.1 The server must be ready to receive ClientHello that contains the supportedVersions + * extension but does not contain 0x0304 in the version list, Therefore, if a matching version is found, + * even if the version is an earlier version, the system directly returns */ + *selectVersion = version; + return HITLS_SUCCESS; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15250, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server cannot negotiate a version.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; +} + +static int32_t UpdateServerBaseKeyExMode(TLS_Ctx *ctx) +{ + uint32_t tls13BasicKeyExMode = 0; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + if (kxCtx->pskInfo13.psk != NULL && kxCtx->peerPubkey != NULL) { + tls13BasicKeyExMode = TLS13_KE_MODE_PSK_WITH_DHE; + } else if (kxCtx->pskInfo13.psk != NULL) { + tls13BasicKeyExMode = TLS13_KE_MODE_PSK_ONLY; + } else if (kxCtx->peerPubkey != NULL) { + tls13BasicKeyExMode = TLS13_CERT_AUTH_WITH_DHE; + } else { + // kxCtx->pskInfo13.psk == NULL && kxCtx->peerPubkey == NULL is guaranteed by Tls13ServerCheckClientHello + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + ctx->negotiatedInfo.tls13BasicKeyExMode = tls13BasicKeyExMode; + return HITLS_SUCCESS; +} + +static int32_t Tls13ServerProcessClientHello(TLS_Ctx *ctx, HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + TLS_Config *tlsConfig = &ctx->config.tlsConfig; + ClientHelloMsg *clientHello = &msg->body.clientHello; + if (ctx->hsCtx->haveHrr) { + /* In middlebox mode, CCS messages cannot be received after the second clientHello message is received. */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + } else if (!ctx->method.isRecvCCS(ctx)) { + /* An unencrypted CCS may be received after sending or receiving the first ClientHello according to RFC 8446 */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + } + + bool isNeedSendHrr = false; + /* Processing Client Hello messages */ + ret = Tls13ServerCheckClientHello(ctx, clientHello, &isNeedSendHrr); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (isNeedSendHrr) { + return HS_ChangeState(ctx, TRY_SEND_HELLO_RETRY_REQUEST); + } + ret = UpdateServerBaseKeyExMode(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (ctx->phaState == PHA_NONE && tlsConfig->isSupportClientVerify && tlsConfig->isSupportPostHandshakeAuth && + msg->body.clientHello.extension.flag.havePostHsAuth) { + ctx->phaState = PHA_EXTENSION; + } + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO); +} + +int32_t Tls13ServerRecvClientHelloProcess(TLS_Ctx *ctx, HS_Msg *msg) +{ + int32_t ret = 0; + uint16_t selectedVersion = 0; + ClientHelloMsg *clientHello = &msg->body.clientHello; + TLS_Config *tlsConfig = &ctx->config.tlsConfig; + + /* Perform the ClientHello callback. The pause handshake status is not considered */ + ret = ClientHelloCbCheck(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SelectVersion(ctx, clientHello, tlsConfig->minVersion, tlsConfig->maxVersion, &selectedVersion); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* If the TLS version is earlier than 1.3, the ServerHello.version parameter must be set on the server and the + * supported_versions extension cannot be sent */ + clientHello->version = selectedVersion; + + switch (selectedVersion) { + case HITLS_VERSION_TLS12: + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15251, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 server receive a tls1.2 clientHello.", 0, 0, 0, 0); + return Tls12ServerRecvClientHelloProcess(ctx, msg); + case HITLS_VERSION_TLS13: + return Tls13ServerProcessClientHello(ctx, msg); + default: + break; + } + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15252, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server select an unsupported version.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; +} diff --git a/tls/handshake/recv/src/recv_client_key_exchange.c b/tls/handshake/recv/src/recv_client_key_exchange.c new file mode 100644 index 00000000..1d49506f --- /dev/null +++ b/tls/handshake/recv/src/recv_client_key_exchange.c @@ -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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_kx.h" +#include "hs_msg.h" +#include "hs_verify.h" +#include "hs_common.h" +#include "securec.h" +#include "bsl_sal.h" + +static int32_t RetriveServerPsk(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + + if ((!IsPskNegotiation(ctx)) == true) { + return HITLS_SUCCESS; + } + + if (ctx->config.tlsConfig.pskServerCb == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_UNREGISTERED_CALLBACK); + return HITLS_UNREGISTERED_CALLBACK; + } + + uint32_t pskUsedLen = ctx->config.tlsConfig.pskServerCb(ctx, clientKxMsg->pskIdentity, psk, HS_PSK_MAX_LEN); + if (pskUsedLen == 0 || pskUsedLen > HS_PSK_MAX_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN); + return HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN; + } + + if (ctx->hsCtx->kxCtx->pskInfo == NULL) { + ctx->hsCtx->kxCtx->pskInfo = (PskInfo *)BSL_SAL_Calloc(1u, sizeof(PskInfo)); + if (ctx->hsCtx->kxCtx->pskInfo == NULL) { + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + } + + uint8_t *tmpIdentity = NULL; + if (clientKxMsg->pskIdentity != NULL) { + tmpIdentity = (uint8_t *)BSL_SAL_Calloc(1u, (clientKxMsg->pskIdentitySize + 1) * sizeof(uint8_t)); + if (tmpIdentity == NULL) { + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(tmpIdentity, clientKxMsg->pskIdentitySize + 1, clientKxMsg->pskIdentity, + clientKxMsg->pskIdentitySize); + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo->identity); + ctx->hsCtx->kxCtx->pskInfo->identity = tmpIdentity; + ctx->hsCtx->kxCtx->pskInfo->identityLen = clientKxMsg->pskIdentitySize; + } + + uint8_t *tmpPsk = (uint8_t *)BSL_SAL_Dump(psk, pskUsedLen); + if (tmpPsk == NULL) { + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo->psk); + ctx->hsCtx->kxCtx->pskInfo->psk = tmpPsk; + ctx->hsCtx->kxCtx->pskInfo->pskLen = pskUsedLen; + + /* sensitive info cleanup */ + (void)memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + + return HITLS_SUCCESS; +} + +static int32_t ProcessClientKxMsg(TLS_Ctx *ctx, const ClientKeyExchangeMsg *clientKxMsg) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + int32_t ret = RetriveServerPsk(ctx, clientKxMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** Process the key exchange message from the client */ + switch (hsCtx->kxCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_ECDHE: /* ECDHE of TLCP is also in this branch */ + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = HS_ProcessClientKxMsgEcdhe(ctx, clientKxMsg); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = HS_ProcessClientKxMsgDhe(ctx, clientKxMsg); + break; + case HITLS_KEY_EXCH_RSA: + case HITLS_KEY_EXCH_RSA_PSK: + ret = HS_ProcessClientKxMsgRsa(ctx, clientKxMsg); + break; + case HITLS_KEY_EXCH_PSK: + ret = HITLS_SUCCESS; + break; +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: + ret = HS_ProcessClientKxMsgSm2(ctx, clientKxMsg); + break; +#endif + default: + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG); + ret = HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG; + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + break; + } + + return ret; +} + +static int32_t GenerateKeyMaterial(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + const ClientKeyExchangeMsg *clientKxMsg = &msg->body.clientKeyExchange; + + ret = ProcessClientKxMsg(ctx, clientKxMsg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15820, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server process client key exchange msg fail.", 0, 0, 0, 0); + return ret; + } + + ret = HS_GenerateMasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15821, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server generate master secret fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /** Server secret derivation */ + ret = HS_KeyEstablish(ctx, ctx->isClient); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15822, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server key establish fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } +#ifndef HITLS_NO_DTLS12 + ret = HS_SetSctpAuthKey(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } +#endif + + return HITLS_SUCCESS; +} + +int32_t ServerRecvClientKxProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + ret = GenerateKeyMaterial(ctx, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** + * According to RFC 5246 7.4.8: This message (referred to here as client cert verify) is only sent following + * a client certificate that has signing capability. + * In the case of dual-ended parity + * 1) If the peer certificate is not empty, the system calculates the signature and switches to the cert verify + * state. 2) If the peer certificate is empty, the client sends an empty certificate message after the server sends + * a cert request message, In this case, the client does not send the cert verify message. Therefore, the client + * needs to switch to the state of receiving the Finish message. + */ + if (hsCtx->isNeedClientCert && hsCtx->peerCert != NULL) { + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_VERIFY); + } + + ret = VERIFY_CalcVerifyData(ctx, true, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15823, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server Calculate client finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + (void)memset_s(ctx->hsCtx->masterKey, sizeof(ctx->hsCtx->masterKey), 0, sizeof(ctx->hsCtx->masterKey)); + return ret; + } + + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} diff --git a/tls/handshake/recv/src/recv_encrypted_extensions.c b/tls/handshake/recv/src/recv_encrypted_extensions.c new file mode 100644 index 00000000..fa2c34c2 --- /dev/null +++ b/tls/handshake/recv/src/recv_encrypted_extensions.c @@ -0,0 +1,105 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "hs_msg.h" +#include "hs_verify.h" + + +typedef int32_t (*CheckEncryptedExtFunc)(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg); + +static int32_t Tls13ClientCheckServerName(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg) +{ + if ((ctx->hsCtx->extFlag.haveServerName == false) && (eEMsg->haveServerName == true)) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15337, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send server_name but get extended server_name .", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + /* Receive empty server_name extension */ + if ((ctx->hsCtx->extFlag.haveServerName == true) && (eEMsg->haveServerName == true)) { + /* Not in session resumption and the client has previously sent the server_name extension */ + if (ctx->session == NULL && ctx->config.tlsConfig.serverName != NULL && + ctx->config.tlsConfig.serverNameSize > 0) { + /* Indicates server negotiated the server_name extension in client successfully */ + ctx->negotiatedInfo.isSniStateOK = true; + ctx->hsCtx->serverNameSize = ctx->config.tlsConfig.serverNameSize; + + ctx->hsCtx->serverName = + (uint8_t *)BSL_SAL_Dump(ctx->config.tlsConfig.serverName, ctx->hsCtx->serverNameSize * sizeof(uint8_t)); + if (ctx->hsCtx->serverName == NULL) { + return HITLS_MEMCPY_FAIL; + } + } + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckEncryptedExtensionsFlag(TLS_Ctx *ctx, const EncryptedExtensions *eEMsg) +{ + static const CheckEncryptedExtFunc EXT_INFO_LIST[] = { + Tls13ClientCheckServerName, + }; + + int32_t ret; + for (uint32_t i = 0; i < sizeof(EXT_INFO_LIST) / sizeof(EXT_INFO_LIST[0]); i++) { + ret = EXT_INFO_LIST[i](ctx, eEMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + return HITLS_SUCCESS; +} + +int32_t Tls13ClientRecvEncryptedExtensionsProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret; + + const EncryptedExtensions *eEMsg = &msg->body.encryptedExtensions; + + ret = ClientCheckEncryptedExtensionsFlag(ctx, eEMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* In psk_only mode, the next message is finish message, server verify data needs to be calculated. */ + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + if ((pskInfo->psk != NULL)) { + ret = VERIFY_Tls13CalcVerifyData(ctx, false); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15856, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + return HS_ChangeState(ctx, TRY_RECV_FINISH); + } + + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST); +} diff --git a/tls/handshake/recv/src/recv_finished.c b/tls/handshake/recv/src/recv_finished.c new file mode 100644 index 00000000..49e08e6d --- /dev/null +++ b/tls/handshake/recv/src/recv_finished.c @@ -0,0 +1,423 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "rec.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_verify.h" +#include "hs_common.h" +#include "hs_verify.h" +#include "recv_process.h" +#include "hs_kx.h" +#include "session_mgr.h" + +static int32_t SetSessionTicketInfo(TLS_Ctx *ctx) +{ + int32_t ret = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + + BSL_SAL_FREE(hsCtx->sessionId); + hsCtx->sessionIdSize = 0; + + if (hsCtx->ticketSize == 0) { + return HITLS_SUCCESS; + } + + if (ctx->isClient) { + uint8_t sessionId[HITLS_SESSION_ID_MAX_SIZE]; + ret = SESSMGR_GernerateSessionId(ctx, sessionId, HITLS_SESSION_ID_MAX_SIZE); + if (ret != HITLS_SUCCESS) { + return ret; + } + + HITLS_SESS_SetSessionId(ctx->session, sessionId, HITLS_SESSION_ID_MAX_SIZE); + } + + ret = SESS_SetTicket(ctx->session, hsCtx->ticket, hsCtx->ticketSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15970, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Session set ticket fail.", 0, 0, 0, 0); + return ret; + } + + return HITLS_SUCCESS; +} + +static int32_t SessionConfig(TLS_Ctx *ctx) +{ + int32_t ret = 0; + bool isTls13 = (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13); + HS_Ctx *hsCtx = ctx->hsCtx; + + if (ctx->negotiatedInfo.isTicket) { + ret = SetSessionTicketInfo(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* The default session length is 0. If the session length is not 0, insert the session length */ + if (hsCtx->sessionIdSize != 0 && !isTls13) { + /* The session generated during the finish operation of TLS 1.3 cannot be used for session resume. In this + * case, sessionId is blocked so that the HITLS_SESS_IsResumable return value is false */ + ret = HITLS_SESS_SetSessionId(ctx->session, hsCtx->sessionId, hsCtx->sessionIdSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* When the SNI negotiation is HITLS_ACCEPT_ERR_OK, save the client Hello server_name extension to the session + * structure */ + if (ctx->negotiatedInfo.isSniStateOK && isTls13 == false) { + ret = SESS_SetHostName(ctx->session, hsCtx->serverNameSize, hsCtx->serverName); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = HITLS_SESS_SetSessionIdCtx( + ctx->session, ctx->config.tlsConfig.sessionIdCtx, ctx->config.tlsConfig.sessionIdCtxSize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + (void)HITLS_SESS_SetProtocolVersion(ctx->session, ctx->negotiatedInfo.version); + (void)HITLS_SESS_SetCipherSuite(ctx->session, ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite); + + uint32_t masterKeySize = MASTER_SECRET_LEN; + if (isTls13) { + masterKeySize = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (masterKeySize == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + } + + ret = HITLS_SESS_SetMasterKey(ctx->session, hsCtx->masterKey, masterKeySize); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HITLS_SESS_SetHaveExtMasterSecret(ctx->session, (uint8_t)ctx->negotiatedInfo.isExtendedMasterSecret); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SESS_SetPeerCert(ctx->session, hsCtx->peerCert, ctx->isClient); + if (ret != HITLS_SUCCESS) { + return ret; + } + hsCtx->peerCert = NULL; + + return HITLS_SUCCESS; +} + +static int32_t HsSetSessionInfo(TLS_Ctx *ctx) +{ + int32_t ret = 0; + TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr; + + HS_Ctx *hsCtx = ctx->hsCtx; + + SESSMGR_ClearTimeout(sessMgr); + + /* This parameter is not required for session multiplexing */ + if (ctx->negotiatedInfo.isResume == true) { + return HITLS_SUCCESS; + } + + HITLS_SESS_Free(ctx->session); + + ctx->session = HITLS_SESS_New(); + if (ctx->session == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15893, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Session malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + uint64_t timeout = (hsCtx->ticketLifetimeHint == 0) ? + SESSMGR_GetTimeout(sessMgr) : (uint64_t)hsCtx->ticketLifetimeHint; + HITLS_SESS_SetTimeout(ctx->session, timeout); + + ret = SessionConfig(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* The session cache does not store TLS1.3 sessions */ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + SESSMGR_InsertSession(sessMgr, ctx->session, ctx->isClient); + } + + if (ctx->globalConfig != NULL && ctx->globalConfig->newSessionCb != NULL) { + HITLS_SESS_UpRef(ctx->session); // It is convenient for users to take away and needs to be released by users + if (ctx->globalConfig->newSessionCb(ctx, ctx->session) == 0) { + /* If the user does not reference the session, the number of reference times decreases by 1 */ + HITLS_SESS_Free(ctx->session); + } + } + return HITLS_SUCCESS; +} + +int32_t CheckFinishedVerifyData(const FinishedMsg *finishedMsg, const uint8_t *verifyData, uint32_t verifyDataSize) +{ + if ((finishedMsg->verifyDataSize == 0u) || (verifyDataSize == 0u)) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15737, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Finished data len cannot be zero.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN; + } + + if (finishedMsg->verifyDataSize != verifyDataSize) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15738, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Finished data len unequal.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN; + } + + if (memcmp(finishedMsg->verifyData, verifyData, verifyDataSize) != 0) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15739, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Finished data unequal.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL; + } + + return HITLS_SUCCESS; +} + +int32_t ClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = 0; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + VerifyCtx *verifyCtx = hsCtx->verifyCtx; + const FinishedMsg *finished = &msg->body.finished; + uint8_t verifyData[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataSize = MAX_DIGEST_SIZE; + + ret = VERIFY_GetVerifyData(verifyCtx, verifyData, &verifyDataSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15740, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client get server finished verify data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = CheckFinishedVerifyData(finished, verifyData, verifyDataSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15741, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client verify server finished data error.", 0, 0, 0, 0); + if (ret == HITLS_MSG_HANDLE_INCORRECT_DIGEST_LEN) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + } else { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + } + return HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL; + } + + ret = HsSetSessionInfo(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15895, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set session information failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* CCS messages are not allowed to be received later. */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + return HITLS_SUCCESS; +} + +int32_t ServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = 0; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + VerifyCtx *verifyCtx = hsCtx->verifyCtx; + uint8_t verifyData[MAX_DIGEST_SIZE] = {0}; + uint32_t verifyDataSize = MAX_DIGEST_SIZE; + const FinishedMsg *finished = &msg->body.finished; + + ret = VERIFY_GetVerifyData(verifyCtx, verifyData, &verifyDataSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15742, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server get client finished verify data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = CheckFinishedVerifyData(finished, verifyData, verifyDataSize); + if (ret != HITLS_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15743, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server verify client finished data error.", 0, 0, 0, 0); + if (ret == HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECRYPT_ERROR); + } else { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + } + return HITLS_MSG_HANDLE_VERIFY_FINISHED_FAIL; + } + + ret = HsSetSessionInfo(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15897, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set session information failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + return HITLS_SUCCESS; +} + +int32_t ClientRecvFinished(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = ClientRecvFinishedProcess(ctx, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->negotiatedInfo.isResume == true) { + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); + } + + return HS_ChangeState(ctx, TLS_CONNECTED); +} + +int32_t Tls12ClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + return ClientRecvFinished(ctx, msg); +} + +int32_t ServerRecvFinished(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = ServerRecvFinishedProcess(ctx, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->negotiatedInfo.isResume == true) { + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + return HS_ChangeState(ctx, TLS_CONNECTED); + } + + if (ctx->negotiatedInfo.isTicket == true) { + return HS_ChangeState(ctx, TRY_SEND_NEW_SESSION_TICKET); + } + + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); +} + +int32_t Tls12ServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + return ServerRecvFinished(ctx, msg); +} + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + return ClientRecvFinished(ctx, msg); +} +#endif + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + return ServerRecvFinished(ctx, msg); +} +#endif + +int32_t Tls13ClientRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = ClientRecvFinishedProcess(ctx, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_TLS13CalcServerFinishProcessSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Activate serverAppTrafficSecret to decrypt the App data sent by the server */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->serverAppTrafficSecret, hashLen, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->hsCtx->isNeedClientCert) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE); + } + + return HS_ChangeState(ctx, TRY_SEND_FINISH); +} + +int32_t Tls13ServerRecvFinishedProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** CCS messages are not allowed to be received */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + + int32_t ret = ServerRecvFinishedProcess(ctx, msg); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (ctx->phaState == PHA_REQUESTED) { + ctx->phaState = PHA_EXTENSION; + } else { + /* Switch Application Traffic Secret */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->clientAppTrafficSecret, hashLen, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_TLS13DeriveResumptionMasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->phaState == PHA_EXTENSION && ctx->config.tlsConfig.isSupportClientVerify && + ctx->config.tlsConfig.isSupportPostHandshakeAuth) { + SAL_CRYPT_DigestFree(ctx->phaHash); + ctx->phaHash = SAL_CRYPT_DigestCopy(ctx->hsCtx->verifyCtx->hashCtx); + if (ctx->phaHash == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15356, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pha hash copy error: digest copy fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_DIGEST; + } + } + } + + /* When ticketNums is 0, no ticket is sent */ + if (hsCtx->sentTickets >= ctx->config.tlsConfig.ticketNums) { + return HS_ChangeState(ctx, TLS_CONNECTED); + } + return HS_ChangeState(ctx, TRY_SEND_NEW_SESSION_TICKET); +} diff --git a/tls/handshake/recv/src/recv_new_session_ticket.c b/tls/handshake/recv/src/recv_new_session_ticket.c new file mode 100644 index 00000000..123b862d --- /dev/null +++ b/tls/handshake/recv/src/recv_new_session_ticket.c @@ -0,0 +1,145 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "hs_verify.h" +#include "hs_msg.h" +#include "hs_kx.h" +#include "session.h" + +static int32_t UpdateTicket(TLS_Ctx *ctx, NewSessionTicketMsg *msg, uint8_t *psk, uint32_t pskSize) +{ + HITLS_Session *newSession = SESS_Copy(ctx->session); + if (newSession == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy session info failed.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + SESS_SetStartTime(newSession, (uint64_t)BSL_SAL_CurrentSysTimeGet()); + HITLS_SESS_SetTimeout(newSession, msg->ticketLifetimeHint); + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + SESS_SetTicketAgeAdd(newSession, msg->ticketAgeAdd); + HITLS_SESS_SetMasterKey(newSession, psk, pskSize); + } + + int32_t ret = SESS_SetTicket(newSession, msg->ticket, msg->ticketSize); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(newSession); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16017, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "set ticket failed.", 0, 0, 0, 0); + return ret; + } + + HITLS_SESS_Free(ctx->session); + ctx->session = newSession; + + /* The server may send multiple tickets. In this case, each ticket received will be notified to the user through + * this callback, so that the client can obtain multiple sessions */ + if (ctx->globalConfig != NULL && ctx->globalConfig->newSessionCb != NULL) { + HITLS_SESS_UpRef(newSession); // It is convenient for users to take away and needs to be released by users + if (ctx->globalConfig->newSessionCb(ctx, newSession) == 0) { + /* If the user does not reference the session, the number of reference times decreases by 1 */ + HITLS_SESS_Free(newSession); + } + } + + return HITLS_SUCCESS; +} + +int32_t Tls12ClientRecvNewSeesionTicketProcess(TLS_Ctx *ctx, HS_Msg *hsMsg) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + /* The processing of the msg is complete when the NewSeesionTick operation is performed */ + NewSessionTicketMsg *newSessionTicket = &hsMsg->body.newSessionTicket; + + if (newSessionTicket->ticketLifetimeHint != 0 && newSessionTicket->ticketSize != 0) { + if (ctx->negotiatedInfo.isResume == true) { + ret = UpdateTicket(ctx, newSessionTicket, NULL, 0); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + } else { + /* Saved in the context */ + hsCtx->ticketLifetimeHint = newSessionTicket->ticketLifetimeHint; + hsCtx->ticketSize = newSessionTicket->ticketSize; + hsCtx->ticket = newSessionTicket->ticket; + + newSessionTicket->ticket = NULL; + newSessionTicket->ticketSize = 0; + } + } + + /* The server verify data needs to be calculated in advance */ + ret = VERIFY_CalcVerifyData(ctx, false, hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15971, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client Calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} + +int32_t Tls13ClientRecvNewSessionTicketProcess(TLS_Ctx *ctx, HS_Msg *hsMsg) +{ + int32_t ret = HITLS_SUCCESS; + NewSessionTicketMsg *msg = &hsMsg->body.newSessionTicket; + + /* If the value is 0, the ticket should be discarded immediately. After the TTO is backed up, the ctx->session field + * is empty */ + if (msg->ticketLifetimeHint == 0 || ctx->session == NULL) { + return HITLS_SUCCESS; + } + + uint8_t resumePsk[MAX_DIGEST_SIZE] = {0}; + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_TLS13DeriveResumePsk(ctx, msg->ticketNonce, msg->ticketNonceSize, resumePsk, hashLen); + if (ret != HITLS_SUCCESS) { + (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Derive resume psk failed.", 0, 0, 0, 0); + return ret; + } + + ret = UpdateTicket(ctx, msg, resumePsk, hashLen); + (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + return HITLS_SUCCESS; +} diff --git a/tls/handshake/recv/src/recv_server_hello.c b/tls/handshake/recv/src/recv_server_hello.c new file mode 100644 index 00000000..43c93fce --- /dev/null +++ b/tls/handshake/recv/src/recv_server_hello.c @@ -0,0 +1,1251 @@ +/* + * 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 +#include +#include "bsl_sal.h" +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls_sni.h" +#include "hitls_security.h" +#include "tls.h" +#include "security.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_verify.h" +#include "hs_common.h" +#include "hs_msg.h" +#include "transcript_hash.h" +#include "session_mgr.h" +#include "alpn.h" +#include "hs_kx.h" + + +typedef int32_t (*CheckExtFunc)(TLS_Ctx *ctx, const ServerHelloMsg *serverHello); + +static int32_t ClientCheckPointFormats(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.havePointFormats) && serverHello->havePointFormats) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15255, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get point formats.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + /* The key exchange algorithm is not ECDHE */ + if ((ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_ECDSA) && + (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg != HITLS_KEY_EXCH_ECDHE) && + (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg != HITLS_KEY_EXCH_ECDH) && + (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg != HITLS_KEY_EXCH_ECDHE_PSK)) { + return HITLS_SUCCESS; + } + + if (!serverHello->havePointFormats) { + return HITLS_SUCCESS; + } + + for (uint8_t i = 0u; i < serverHello->pointFormatsSize; i++) { + /* The point format list contains uncompressed (0) */ + if (serverHello->pointFormats[i] == 0u) { + return HITLS_SUCCESS; + } + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15256, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the point format extension in server hello is incorrect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT); + return HITLS_MSG_HANDLE_UNSUPPORT_POINT_FORMAT; +} + +static int32_t SelectProtocol(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + uint8_t *protoMatch = NULL; + uint32_t protoMatchLen = 0; + + int32_t ret = ALPN_SelectProtocol(&protoMatch, &protoMatchLen, serverHello->alpnSelected, + serverHello->alpnSelectedSize, ctx->config.tlsConfig.alpnList, ctx->config.tlsConfig.alpnListSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15258, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client check proposed protocol fail due to invalid params.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } else if (protoMatch == NULL) { + /* The RFC 7301 does not specify the behavior when the client selectedProto does not match the local + * configuration list. The behavior is the same as that in OpenSSL. */ + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ALPN_PROTOCOL_NO_MATCH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15259, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server proposed protocol is not supported by client: %s.", serverHello->alpnSelected, 0, 0, 0); + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckNegotiatedAlpn(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.haveAlpn) && serverHello->haveSelectedAlpn) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15257, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get selected alpn protocol.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + if (serverHello->alpnSelectedSize == 0) { + return HITLS_SUCCESS; + } + + int32_t ret = SelectProtocol(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t *alpnSelectedTmp = (uint8_t *)BSL_SAL_Calloc(1u, (serverHello->alpnSelectedSize + 1)); + if (alpnSelectedTmp == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15260, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client malloc selected alpn mem failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + if (memcpy_s(alpnSelectedTmp, serverHello->alpnSelectedSize + 1, serverHello->alpnSelected, + serverHello->alpnSelectedSize) != EOK) { + BSL_SAL_FREE(alpnSelectedTmp); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15261, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client copy selected alpn failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + BSL_SAL_FREE(ctx->negotiatedInfo.alpnSelected); + ctx->negotiatedInfo.alpnSelected = alpnSelectedTmp; + ctx->negotiatedInfo.alpnSelectedSize = serverHello->alpnSelectedSize; + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15262, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "ALPN protocol: %s.", ctx->negotiatedInfo.alpnSelected, 0, 0, 0); + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckServerName(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((ctx->hsCtx->extFlag.haveServerName == false) && (serverHello->haveServerName == true)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15263, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send server_name but get extended server_name .", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + /* Received null server_name extension for server hello message */ + if ((ctx->hsCtx->extFlag.haveServerName == true) && (serverHello->haveServerName == true)) { + /* Not in session resumption, and the client has previously sent the server_name extension */ + if (ctx->session == NULL && ctx->config.tlsConfig.serverName != NULL && + ctx->config.tlsConfig.serverNameSize > 0) { + /* The server negotiates the extension of the server_name of the client successfully */ + ctx->negotiatedInfo.isSniStateOK = true; + ctx->hsCtx->serverNameSize = ctx->config.tlsConfig.serverNameSize; + + ctx->hsCtx->serverName = + (uint8_t *)BSL_SAL_Dump(ctx->config.tlsConfig.serverName, ctx->hsCtx->serverNameSize * sizeof(uint8_t)); + if (ctx->hsCtx->serverName == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + } + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckExtendedMasterSecret(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.haveExtendedMasterSecret) && serverHello->haveExtendedMasterSecret) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15264, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get extended master secret.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + /* tls1.3 Ignore Extended Master Secret */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 || ctx->negotiatedInfo.version < HITLS_VERSION_TLS12) { + ctx->negotiatedInfo.isExtendedMasterSecret = false; + return HITLS_SUCCESS; + } + /* rfc 7627 5.3 Client and Server Behavior: Abbreviated Handshake + If a client receives a ServerHello that accepts an abbreviated + handshake, it behaves as follows: + o If the original session did not use the "extended_master_secret" + extension but the new ServerHello contains the extension, the + client MUST abort the handshake. + o If the original session used the extension but the new ServerHello + does not contain the extension, the client MUST abort the + handshake. */ + if (ctx->negotiatedInfo.isResume && ctx->session != NULL) { + uint8_t haveExtMasterSecret; + HITLS_SESS_GetHaveExtMasterSecret(ctx->session, &haveExtMasterSecret); + bool preEms = haveExtMasterSecret != 0; + if (serverHello->haveExtendedMasterSecret != preEms) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_INVALID_EXTENDED_MASTER_SECRET; + } + } + if (ctx->config.tlsConfig.isSupportExtendMasterSecret && !serverHello->haveExtendedMasterSecret) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_INVALID_EXTENDED_MASTER_SECRET; + } + /* Configure the negotiation content to support the extended master secret */ + ctx->negotiatedInfo.isExtendedMasterSecret = (ctx->hsCtx->extFlag.haveExtendedMasterSecret && + serverHello->haveExtendedMasterSecret); + return HITLS_SUCCESS; +} + +static int32_t ClientCheckKeyShare(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.haveKeyShare) && serverHello->haveKeyShare) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15265, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get key share.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckPreShareKey(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.havePreShareKey) && serverHello->haveSelectedIdentity) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15266, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get pre share key.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckSupportedVersions(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.haveSupportedVers) && serverHello->haveSupportedVersion) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15853, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get supported versions.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckRenegoInfoDuringFirstHandshake(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + /* If the peer does not support the negotiation, return */ + if (!serverHello->haveSecRenego) { + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + return HITLS_SUCCESS; + } + if (ctx->config.tlsConfig.noSecRenegotiationCb != NULL) { + /* The user can determine whether to terminate when the peer does not support security renegotiation */ + int32_t ret = ctx->config.tlsConfig.noSecRenegotiationCb(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15899, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "noSecRenegotiationCb return fail when process server hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return HITLS_SUCCESS; + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16070, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Legacy renegotiate is not allowed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + + /* For the first handshake, if the security renegotiation information is not empty, return an error code. + */ + if (serverHello->secRenegoInfoSize != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15958, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "secRenegoInfoSize should be 0 in client initial handhsake.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + + /* Configure the security renegotiation function */ + ctx->negotiatedInfo.isSecureRenegotiation = true; + return HITLS_SUCCESS; +} + +static int32_t ClientCheckRenegoInfoDuringRenegotiation(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + /* Verify the security renegotiation information */ + const uint8_t *clientData = ctx->negotiatedInfo.clientVerifyData; + uint32_t clientDataSize = ctx->negotiatedInfo.clientVerifyDataSize; + const uint8_t *serverData = ctx->negotiatedInfo.serverVerifyData; + uint32_t serverDataSize = ctx->negotiatedInfo.serverVerifyDataSize; + if (clientData == NULL || serverData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + if (serverHello->secRenegoInfoSize != (clientDataSize + serverDataSize)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15900, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "secRenegoInfoSize(%u) error, expect %u.", serverHello->secRenegoInfoSize, + (clientDataSize + serverDataSize), 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + if (memcmp(serverHello->secRenegoInfo, clientData, clientDataSize) != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15901, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check client secRenegoInfo verify data failed during renegotiation.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + if (memcmp(&serverHello->secRenegoInfo[clientDataSize], serverData, serverDataSize) != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15902, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "check server secRenegoInfo verify data failed during renegotiation.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_RENEGOTIATION_FAIL); + return HITLS_MSG_HANDLE_RENEGOTIATION_FAIL; + } + return HITLS_SUCCESS; +} + +static int32_t ClientCheckAndProcessRenegoInfo(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + /* Not in the renegotiation state */ + if (!ctx->negotiatedInfo.isRenegotiation) { + return ClientCheckRenegoInfoDuringFirstHandshake(ctx, serverHello); + } + + /* Renegotiation state */ + return ClientCheckRenegoInfoDuringRenegotiation(ctx, serverHello); +} + +static int32_t ClientCheckTicketExternsion(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if ((!ctx->hsCtx->extFlag.haveTicket) && serverHello->haveTicket) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15972, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get ticket externsion.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 && serverHello->haveTicket) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15912, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLS1.3 client get server hello ticket externsion.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + /* Set whether to support ticket extension */ + ctx->negotiatedInfo.isTicket = serverHello->haveTicket; + return HITLS_SUCCESS; +} + +static int32_t ClientCheckEncryptThenMac(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if (!ctx->hsCtx->extFlag.haveEncryptThenMac && serverHello->haveEncryptThenMac) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15920, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client did not send but get encrypt then mac.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + /* The user does not support the EncryptThenMac extension, but receives the EncryptThenMac extension from the server + */ + if (!ctx->config.tlsConfig.isEncryptThenMac && serverHello->haveEncryptThenMac) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15931, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client do not support encrypt then mac.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNSUPPORTED_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + + /* During renegotiation, EncryptThenMac cannot be converted to MacThenEncrypt */ + if (ctx->negotiatedInfo.isRenegotiation && ctx->negotiatedInfo.isEncryptThenMac && + !serverHello->haveEncryptThenMac) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15934, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "regotiation should not change encrypt then mac to mac then encrypt.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ENCRYPT_THEN_MAC_ERR); + return HITLS_MSG_HANDLE_ENCRYPT_THEN_MAC_ERR; + } + + /* This extension does not need to be negotiated for tls1.3 */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + return HITLS_SUCCESS; + } + + /* Set the negotiated EncryptThenMac */ + if (serverHello->haveEncryptThenMac) { + ctx->negotiatedInfo.isEncryptThenMac = true; + } else { + ctx->negotiatedInfo.isEncryptThenMac = false; + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckExtensionsFlag(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + static const CheckExtFunc extInfoList[] = { + ClientCheckServerName, + ClientCheckExtendedMasterSecret, + ClientCheckPointFormats, + ClientCheckNegotiatedAlpn, + ClientCheckKeyShare, + ClientCheckPreShareKey, + ClientCheckAndProcessRenegoInfo, + ClientCheckTicketExternsion, + ClientCheckEncryptThenMac, + ClientCheckSupportedVersions, + }; + + int32_t ret; + for (uint32_t i = 0; i < sizeof(extInfoList) / sizeof(extInfoList[0]); i++) { + ret = extInfoList[i](ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckVersion(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + uint16_t clientMinVersion = ctx->config.tlsConfig.minVersion; + uint16_t clientMaxVersion = ctx->config.tlsConfig.maxVersion; + uint16_t serverVersion = serverHello->version; + + if (IS_DTLS_VERSION(serverVersion)) { + if ((serverVersion > clientMinVersion) || (serverVersion < clientMaxVersion)) { + /* The DTLS version selected by the server is too early and the negotiation cannot be continued */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15267, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client support version is from %02x to %02x, server selected unsupported version %02x.", + clientMinVersion, clientMaxVersion, serverVersion, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + } else { + if ((serverVersion < clientMinVersion) || (serverVersion > clientMaxVersion)) { + /* The TLS version selected by the server is too early and cannot be negotiated */ + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15268, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client support version is from %02x to %02x, server selected unsupported version %02x.", + clientMinVersion, clientMaxVersion, serverVersion, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + } + + int32_t ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_VERSION, 0, serverHello->version, NULL); + if (ret != SECURITY_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSECURE_VERSION); + return HITLS_MSG_HANDLE_UNSECURE_VERSION; + } + + ctx->negotiatedInfo.version = serverVersion; + return HITLS_SUCCESS; +} + +static bool IsCipherSuiteSupport(const TLS_Ctx *ctx, uint16_t cipherSuite) +{ + if (ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13) { + for (uint32_t index = 0; index < ctx->config.tlsConfig.tls13cipherSuitesSize; index++) { + if (cipherSuite == ctx->config.tlsConfig.tls13CipherSuites[index]) { + return true; + } + } + } + + for (uint32_t index = 0; index < ctx->config.tlsConfig.cipherSuitesSize; index++) { + if (cipherSuite == ctx->config.tlsConfig.cipherSuites[index]) { + return true; + } + } + return false; +} + +static int32_t ClientCheckCipherSuite(TLS_Ctx *ctx, const ServerHelloMsg *serverHello, bool isHrr) +{ + int32_t ret = HITLS_SUCCESS; + + if (!IsCipherSuiteSupport(ctx, serverHello->cipherSuite)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15269, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "no supported cipher suites found.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_CIPHER_SUITE_ERR); + return HITLS_MSG_HANDLE_CIPHER_SUITE_ERR; + } + + /* In TLS1.3, if the hello retry request message is received, ensure that the cipherSuite of the server hello + * message is the same as the cipherSuite */ + if (!isHrr && ctx->hsCtx->haveHrr) { + if (serverHello->cipherSuite != ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15270, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cipherSuite in server hello (0x%02x) is defferent from hello retry request (0x%02x).", + serverHello->cipherSuite, ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE); + return HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE; + } + return HITLS_SUCCESS; + } + + ret = CFG_GetCipherSuiteInfo(serverHello->cipherSuite, &ctx->negotiatedInfo.cipherSuiteInfo); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15271, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get cipher suite information fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* Check the security of the cipher suite */ + ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_CIPHER_SHARED, 0, 0, + (void *)&ctx->negotiatedInfo.cipherSuiteInfo); + if (ret != SECURITY_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSECURE_CIPHER_SUITE); + return HITLS_MSG_HANDLE_UNSECURE_CIPHER_SUITE; + } + + /* Sets the key negotiation algorithm. */ + ctx->hsCtx->kxCtx->keyExchAlgo = ctx->negotiatedInfo.cipherSuiteInfo.kxAlg; + + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15272, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "ClientCheckCipherSuite: negotiated ciphersuite is [%s].", + ctx->negotiatedInfo.cipherSuiteInfo.name); + return HITLS_SUCCESS; +} + +static int32_t ClientCheckResumeServerHello(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + uint16_t version = 0; + uint16_t cipherSuite = 0; + uint8_t haveExtMasterSecret = 0; + + HITLS_SESS_GetProtocolVersion(ctx->session, &version); + HITLS_SESS_GetCipherSuite(ctx->session, &cipherSuite); + HITLS_SESS_GetHaveExtMasterSecret(ctx->session, &haveExtMasterSecret); + + /* Check the version information */ + if (serverHello->version != version) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15273, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the version of resume server hello is different from the pre connect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_VERSION); + return HITLS_MSG_HANDLE_ILLEGAL_VERSION; + } + + /* Check the cipher suite information */ + if (serverHello->cipherSuite != cipherSuite) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15274, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the cipher suite of resume server hello is different from the pre connect.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE); + return HITLS_MSG_HANDLE_ILLEGAL_CIPHER_SUITE; + } + + /* Check the extended master secret information */ + if (serverHello->haveExtendedMasterSecret != (bool)haveExtMasterSecret) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15275, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "session resume error:can not downgrade from extended master secret.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_EXTRENED_MASTER_SECRET); + return HITLS_MSG_HANDLE_ILLEGAL_EXTRENED_MASTER_SECRET; + } + + return HITLS_SUCCESS; +} + +static bool SessionIdCmp(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + if ((hsCtx->sessionIdSize == 0u) || (serverHello->sessionIdSize == 0u)) { + return false; + } + + if (hsCtx->sessionIdSize != serverHello->sessionIdSize) { + return false; + } + + if (memcmp(hsCtx->sessionId, serverHello->sessionId, hsCtx->sessionIdSize) != 0) { + return false; + } + + return true; +} + +static int32_t ClientCopySessionId(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + BSL_SAL_FREE(hsCtx->sessionId); + + hsCtx->sessionId = (uint8_t *)BSL_SAL_Calloc(1u, HITLS_SESSION_ID_MAX_SIZE); + if (hsCtx->sessionId == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15276, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "session Id malloc fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + ret = memcpy_s(hsCtx->sessionId, HITLS_SESSION_ID_MAX_SIZE, serverHello->sessionId, serverHello->sessionIdSize); + if (ret != EOK) { + BSL_SAL_FREE(hsCtx->sessionId); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15277, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "session Id memcpy fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + return HITLS_MEMCPY_FAIL; + } + + hsCtx->sessionIdSize = serverHello->sessionIdSize; + return HITLS_SUCCESS; +} + +static int32_t ClientCheckIfResumeFromSession(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + bool isResume = false; + + ctx->negotiatedInfo.isResume = false; + + if (ctx->session == NULL || serverHello->sessionIdSize == 0u) { + return HITLS_SUCCESS; + } + + isResume = SessionIdCmp(ctx, serverHello); + if (isResume == true) { + /* Resume the session */ + ctx->negotiatedInfo.isResume = true; + /* Check whether the version number, cipher suite, and master key extension match */ + return ClientCheckResumeServerHello(ctx, serverHello); + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckServerHello(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + int32_t ret = ClientCheckVersion(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = memcpy_s(ctx->hsCtx->serverRandom, HS_RANDOM_SIZE, serverHello->randomValue, HS_RANDOM_SIZE); + if (ret != EOK) { + return ret; + } + + /* Check the session resumption. Check whether the session ID, version number, cipher suite, and master key + * extension match */ + ret = ClientCheckIfResumeFromSession(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Save the session ID for complete handshake */ + if (ctx->negotiatedInfo.isResume == false && serverHello->sessionIdSize > 0) { + ret = ClientCopySessionId(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = ClientCheckCipherSuite(ctx, serverHello, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ClientCheckExtensionsFlag(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +// The client processes the Server Hello message +int32_t ClientRecvServerHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + const ServerHelloMsg *serverHello = &msg->body.serverHello; + + ret = ClientCheckServerHello(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = VERIFY_SetHash(ctx->hsCtx->verifyCtx, ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->negotiatedInfo.isResume == true) { + ret = HS_ResumeKeyEstablish(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (ctx->negotiatedInfo.isTicket) { + return HS_ChangeState(ctx, TRY_RECV_NEW_SESSION_TICKET); + } + + ret = VERIFY_CalcVerifyData(ctx, false, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15278, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client Calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + return HS_ChangeState(ctx, TRY_RECV_FINISH); + } + + /* If the server rejects the session resume request, the system clears the ccs that may be received in disorder */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + + /* Update the state machine. */ + /* If the PSK, DHE_PSK, ECDHE_PSK, or ANON_DH key negotiation is used, skip TRY_RECV_CERTIFICATIONATE */ + if (!IsNeedCertPrepare(&ctx->negotiatedInfo.cipherSuiteInfo)) { + return HS_ChangeState(ctx, TRY_RECV_SERVER_KEY_EXCHANGE); + } + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE); +} + +static int32_t Tls13ClientCheckHelloRetryRequest(TLS_Ctx *ctx, const ServerHelloMsg *helloRetryRequest) +{ + /* If the second Hello Retry Request message is received over the same link, an alert message needs to be sent */ + if (ctx->hsCtx->haveHrr) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15279, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "duplicate hello retry request.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_DUPLICATE_HELLO_RETYR_REQUEST); + return HITLS_MSG_HANDLE_DUPLICATE_HELLO_RETYR_REQUEST; + } + + ctx->hsCtx->haveHrr = true; /* Update state: The hello retry request has been received */ + + /* The supportedVersion is a mandatory extension */ + if (helloRetryRequest->haveSupportedVersion == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15280, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "missing supported version extension in server hello or hello retry request.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_MISSING_EXTENSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_MISSING_EXTENSION); + return HITLS_MSG_HANDLE_MISSING_EXTENSION; + } + + /* If the hello retry request does not modify the client hello, an alert message is sent */ + if ((helloRetryRequest->haveCookie == false) && + (helloRetryRequest->haveKeyShare == false)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15281, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the hello retry reques would not result in any change in the client hello.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_MISSING_EXTENSION); + return HITLS_MSG_HANDLE_MISSING_EXTENSION; + } + + return HITLS_SUCCESS; +} + +static int32_t Tls13ClientCheckSessionId(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + /* The legacy_session_id_echo field must be the same as the sent field */ + if (ctx->hsCtx->sessionIdSize != serverHello->sessionIdSize) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID; + } + if (serverHello->sessionIdSize != 0) { + if (memcmp(ctx->hsCtx->sessionId, serverHello->sessionId, serverHello->sessionIdSize) != 0) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return HITLS_MSG_HANDLE_ILLEGAL_SESSION_ID; + } + } + return HITLS_SUCCESS; +} + +static int32_t Tls13ClientCheckServerHello(TLS_Ctx *ctx, const ServerHelloMsg *serverHello, bool isHrr) +{ + int32_t ret = HITLS_SUCCESS; + + ctx->negotiatedInfo.version = serverHello->supportedVersion; + + ret = memcpy_s(ctx->hsCtx->serverRandom, HS_RANDOM_SIZE, serverHello->randomValue, HS_RANDOM_SIZE); + if (ret != EOK) { + return ret; + } + + ret = Tls13ClientCheckSessionId(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ClientCheckCipherSuite(ctx, serverHello, isHrr); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +static int32_t ClientCheckHrrKeyShareExtension(TLS_Ctx *ctx, const ServerHelloMsg *helloRetryRequest) +{ + if (helloRetryRequest->haveKeyShare == false) { + return HITLS_SUCCESS; + } + + /* The keyshare extension of hrr contains only group and does not contain other fields */ + if (helloRetryRequest->keyShare.keyExchangeSize != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15282, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the keyshare keyExchangeSize is not 0 in hrr keyshare.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + + uint16_t selectedGroup = helloRetryRequest->keyShare.group; + const uint16_t *groups = ctx->config.tlsConfig.groups; + uint32_t numOfGroups = ctx->config.tlsConfig.groupsSize; + + /* The selected group must not exist in the key share extension of the original client hello */ + if (selectedGroup == ctx->hsCtx->kxCtx->keyExchParam.share.group) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15283, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the selected group extension is corresponded to a group in client hello key share.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + + /* The selected group must exist in the supported groups extension of the original client hello */ + bool found = false; + for (uint32_t i = 0; i < numOfGroups; i++) { + if (selectedGroup == groups[i]) { + found = true; + break; + } + } + if (found == false) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15284, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the selected group extension could not correspond to a group in client hello supported groups.", + 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + + // Save the selected group + ctx->hsCtx->kxCtx->keyExchParam.share.group = selectedGroup; + ctx->negotiatedInfo.negotiatedGroup = selectedGroup; + return HITLS_SUCCESS; +} + +/* If an implementation receives an extension + * which it recognizes and which is not specified for the message in + * which it appears, it MUST abort the handshake with an + * "illegal_parameter" alert. */ +static int32_t ClientCheckHrrExtraExtension(TLS_Ctx *ctx, const ServerHelloMsg *helloRetryRequest) +{ + if (helloRetryRequest->haveServerName || helloRetryRequest->haveExtendedMasterSecret || + helloRetryRequest->havePointFormats || helloRetryRequest->haveSelectedAlpn || + helloRetryRequest->haveSelectedIdentity || helloRetryRequest->haveSecRenego || helloRetryRequest->haveTicket || + helloRetryRequest->haveEncryptThenMac) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE); + return HITLS_MSG_HANDLE_UNSUPPORT_EXTENSION_TYPE; + } + return HITLS_SUCCESS; +} + +static int32_t ClientCheckHrrCookieExtension(TLS_Ctx *ctx, const ServerHelloMsg *helloRetryRequest) +{ + if (helloRetryRequest->haveCookie == false) { + return HITLS_SUCCESS; + } + + BSL_SAL_FREE(ctx->negotiatedInfo.cookie); // Clearing Old Memory + + ctx->negotiatedInfo.cookie = BSL_SAL_Dump(helloRetryRequest->cookie, helloRetryRequest->cookieLen); + if (ctx->negotiatedInfo.cookie == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15285, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cookie malloc fail when process hello retry request.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + ctx->negotiatedInfo.cookieSize = helloRetryRequest->cookieLen; + + return HITLS_SUCCESS; +} + +static int32_t Tls13ClientCheckHrrExtension(TLS_Ctx *ctx, const ServerHelloMsg *helloRetryRequest) +{ + int32_t ret = HITLS_SUCCESS; + /* Check whether there are redundant extensions */ + ret = ClientCheckHrrExtraExtension(ctx, helloRetryRequest); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check the key share extension */ + ret = ClientCheckHrrKeyShareExtension(ctx, helloRetryRequest); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check the cookie extension */ + ret = ClientCheckHrrCookieExtension(ctx, helloRetryRequest); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t Tls13ClientRecvHelloRetryRequestProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + const ServerHelloMsg *helloRetryRequest = &msg->body.serverHello; + + ret = Tls13ClientCheckHelloRetryRequest(ctx, helloRetryRequest); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check whether the format of the Hello Retry Request message is the same as that of the Server Hello message + * except the extended fields */ + ret = Tls13ClientCheckServerHello(ctx, helloRetryRequest, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = Tls13ClientCheckHrrExtension(ctx, helloRetryRequest); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* According to RFC 8446 4.4.1, If the Hello Retry Request message is sent, special Transcript-Hash data needs to be + * constructed */ + ret = VERIFY_HelloRetryRequestVerifyProcess(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HS_ChangeState(ctx, TRY_SEND_CLIENT_HELLO); +} + +static int32_t CheckDowngradeRandom(TLS_Ctx *ctx, const ServerHelloMsg *serverHello, uint16_t *negotiatedVersion) +{ + const uint8_t *downgradeArr = NULL; + uint32_t downgradeArrLen = 0; + + if (serverHello->version == HITLS_VERSION_TLS12) { + /* The server that attempts to negotiate TLS1.2 should not send the server hello with the random */ + downgradeArr = HS_GetTls12DowngradeRandom(&downgradeArrLen); + if (memcmp(&serverHello->randomValue[HS_RANDOM_SIZE - downgradeArrLen], downgradeArr, downgradeArrLen) != 0) { + *negotiatedVersion = HITLS_VERSION_TLS12; + return HITLS_SUCCESS; + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15286, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.2 server hello with downgrade random value.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15287, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.1 server hello with downgrade random value.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; +} + +static int32_t GetNegotiatedVersion(TLS_Ctx *ctx, const ServerHelloMsg *serverHello, uint16_t *negotiatedVersion) +{ + /* As a client that supports TLS1.3, if the received server hello message does not contain the supported version + * extension, the peer end wants to negotiate a version earlier than TLS1.3 */ + if (!serverHello->haveSupportedVersion) { + if (serverHello->version < HITLS_VERSION_TLS12) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15846, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client cannot negotiate a version.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + return CheckDowngradeRandom(ctx, serverHello, negotiatedVersion); + } + + /* If the serverHello of TLS1.3 is used, the version selected by the server must be earlier than TLS1.3, and the + * legacy_version field must be TLS1.2 */ + if ((serverHello->supportedVersion != HITLS_VERSION_TLS13) || (serverHello->version != HITLS_VERSION_TLS12)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15288, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server version error, selected version is 0x%02x, legacy version is 0x%02x.", + serverHello->supportedVersion, serverHello->version, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + + *negotiatedVersion = HITLS_VERSION_TLS13; + return HITLS_SUCCESS; +} + +static int32_t ClientProcessKeyShare(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if (serverHello->haveKeyShare == false) { + return HITLS_SUCCESS; + } + + /* The keyshare extension of the server must contain the keyExchange field */ + if (serverHello->keyShare.keyExchangeSize == 0 || + /* Check whether the sent support group is the same as the negotiated group */ + serverHello->keyShare.group != ctx->hsCtx->kxCtx->keyExchParam.share.group) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15289, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "the keyshare parameter is illegal.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + + const KeyShare *keyShare = &serverHello->keyShare; + uint8_t *peerPubkey = BSL_SAL_Dump(keyShare->keyExchange, keyShare->keyExchangeSize); + if (peerPubkey == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15290, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "malloc peerPubkey fail when process server hello key share.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + uint32_t pubKeyLen = keyShare->keyExchangeSize; + + ctx->hsCtx->kxCtx->peerPubkey = peerPubkey; + ctx->hsCtx->kxCtx->pubKeyLen = pubKeyLen; + ctx->negotiatedInfo.negotiatedGroup = serverHello->keyShare.group; + + return HITLS_SUCCESS; +} + +static int32_t ClientProcessPreSharedKey(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + if (serverHello->haveSelectedIdentity == false) { + return HITLS_SUCCESS; + } + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + HITLS_Session *pskSession = NULL; + bool isResumePsk = false; + BSL_SAL_FREE(pskInfo->psk); + pskInfo->psk = NULL; + + if (pskInfo->resumeSession != NULL && serverHello->selectedIdentity == 0) { + pskSession = pskInfo->resumeSession; + isResumePsk = true; + } else if (pskInfo->userPskSess == NULL || serverHello->selectedIdentity != pskInfo->userPskSess->num) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ILLEGAL_PSK_IDENTITY); + return HITLS_MSG_HANDLE_ILLEGAL_PSK_IDENTITY; + } else { + pskSession = pskInfo->userPskSess->pskSession; + } + pskInfo->selectIndex = serverHello->selectedIdentity; + + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + uint32_t pskLen = HS_PSK_MAX_LEN; + + uint16_t cipherSuite = 0; + HITLS_SESS_GetCipherSuite(pskSession, &cipherSuite); + CipherSuiteInfo cipherInfo = {0}; + int32_t ret = CFG_GetCipherSuiteInfo(cipherSuite, &cipherInfo); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* The hash algorithm used by the PSK must match the negotiated cipher suite */ + if (cipherInfo.hashAlg != ctx->negotiatedInfo.cipherSuiteInfo.hashAlg) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_PSK_SESSION_INVALID_CIPHER_SUITE); + return HITLS_MSG_HANDLE_PSK_SESSION_INVALID_CIPHER_SUITE; + } + + /* The session is available and the PSK is obtained */ + ret = HITLS_SESS_GetMasterKey(pskSession, psk, &pskLen); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_HANDSHAKE_FAILURE); + return ret; + } + + pskInfo->psk = BSL_SAL_Dump(psk, pskLen); + BSL_SAL_CleanseData(psk, HS_PSK_MAX_LEN); + if (pskInfo->psk == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + pskInfo->pskLen = pskLen; + ctx->negotiatedInfo.isResume = isResumePsk; + return HITLS_SUCCESS; +} + +static uint32_t GetServertls13AuthType(const ServerHelloMsg *serverHello) +{ + uint32_t tls13BasicKeyExMode = 0; + if (serverHello->haveKeyShare && serverHello->haveSelectedIdentity) { + tls13BasicKeyExMode = TLS13_KE_MODE_PSK_WITH_DHE; + } else if (serverHello->haveSelectedIdentity) { + tls13BasicKeyExMode = TLS13_KE_MODE_PSK_ONLY; + } else if (serverHello->haveKeyShare) { + tls13BasicKeyExMode = TLS13_CERT_AUTH_WITH_DHE; + } + return tls13BasicKeyExMode; +} + +static int32_t Tls13ProcessServerHelloExtension(TLS_Ctx *ctx, const ServerHelloMsg *serverHello) +{ + int32_t ret = 0; + + /* Check whether the extension that is not sent is received */ + ret = ClientCheckExtensionsFlag(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t tls13BasicKeyExMode = GetServertls13AuthType(serverHello) & ctx->negotiatedInfo.tls13BasicKeyExMode; + if (tls13BasicKeyExMode == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15492, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server selects the mode in which the client does not send.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_HANDSHAKE_FAILURE); + return HITLS_MSG_HANDLE_HANDSHAKE_FAILURE; + } + ctx->negotiatedInfo.tls13BasicKeyExMode = tls13BasicKeyExMode; + + ret = ClientProcessKeyShare(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = ClientProcessPreSharedKey(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t Tls13ProcessServerHello(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + const ServerHelloMsg *serverHello = &msg->body.serverHello; + + /* Check all fields except the extended fields in the server hello message */ + ret = Tls13ClientCheckServerHello(ctx, serverHello, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = Tls13ProcessServerHelloExtension(ctx, serverHello); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = VERIFY_SetHash(ctx->hsCtx->verifyCtx, ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Client key derivation */ + ret = HS_TLS13CalcServerHelloProcessSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_TLS13DeriveHandshakeTrafficSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* The message after ServerHello is encrypted by ServerTrafficSecret and needs to be activated for decryption */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->hsCtx->serverHsTrafficSecret, hashLen, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* If there is an hrr message, the CCS has received the message before the serverhello message. If there is no hrr + * message, the next message may be the ccs message */ + if (ctx->hsCtx->haveHrr && ctx->method.isRecvCCS(ctx)) { + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + } + + return HS_ChangeState(ctx, TRY_RECV_ENCRYPTED_EXTENSIONS); +} + +int32_t Tls13ClientRecvServerHelloProcess(TLS_Ctx *ctx, const HS_Msg *msg) +{ + int32_t ret = HITLS_SUCCESS; + const ServerHelloMsg *serverHello = &msg->body.serverHello; + + /* Obtain the intention of the server and determine the version to be negotiated by the server */ + uint16_t negotiatedVersion = 0; + ret = GetNegotiatedVersion(ctx, serverHello, &negotiatedVersion); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (negotiatedVersion < HITLS_VERSION_TLS13) { + /* The keyshare is prepared when the TLS1.3 clientHello message is sent, so the old memory needs to be freed + * here first */ + HS_KeyExchCtxFree(ctx->hsCtx->kxCtx); + ctx->hsCtx->kxCtx = HS_KeyExchCtxNew(); + + if (ctx->hsCtx->kxCtx == NULL) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + return ClientRecvServerHelloProcess(ctx, msg); + } + + uint32_t hrrRandomSize = 0; + const uint8_t *hrrRandom = HS_GetHrrRandom(&hrrRandomSize); + + /* Check the random number. If the message is a hello retry request message, update the client hello message */ + if (memcmp(serverHello->randomValue, hrrRandom, hrrRandomSize) == 0) { + return Tls13ClientRecvHelloRetryRequestProcess(ctx, msg); + } + + return Tls13ProcessServerHello(ctx, msg); +} diff --git a/tls/handshake/recv/src/recv_server_hello_done.c b/tls/handshake/recv/src/recv_server_hello_done.c new file mode 100644 index 00000000..f917c143 --- /dev/null +++ b/tls/handshake/recv/src/recv_server_hello_done.c @@ -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 "rec.h" +#include "hs_ctx.h" +#include "hs_common.h" + +int32_t ClientRecvServerHelloDoneProcess(TLS_Ctx *ctx) +{ + /** get client infomation */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Certificate messages are sent whenever a server certificate request is received, + regardless of whether the client has a proper certificate. */ + if (hsCtx->isNeedClientCert) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE); + } + return HS_ChangeState(ctx, TRY_SEND_CLIENT_KEY_EXCHANGE); +} \ No newline at end of file diff --git a/tls/handshake/recv/src/recv_server_key_exchange.c b/tls/handshake/recv/src/recv_server_key_exchange.c new file mode 100644 index 00000000..d493bc95 --- /dev/null +++ b/tls/handshake/recv/src/recv_server_key_exchange.c @@ -0,0 +1,73 @@ +/* + * 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 + +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "hs_msg.h" +#include "hs_kx.h" + +int32_t ClientRecvServerKxProcess(TLS_Ctx *ctx, HS_Msg *msg) +{ + int32_t ret; + /** get the client infomation */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + ServerKeyExchangeMsg *serverKxMsg = &msg->body.serverKeyExchange; + + if (IsPskNegotiation(ctx)) { + ret = HS_ProcessServerKxMsgIdentityHint(ctx, serverKxMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* process key exchange message from the server */ + switch (hsCtx->kxCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_ECDHE: // ECDHE of TLCP is also in this branch + case HITLS_KEY_EXCH_ECDHE_PSK: + ret = HS_ProcessServerKxMsgEcdhe(ctx, serverKxMsg); + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = HS_ProcessServerKxMsgDhe(ctx, serverKxMsg); + break; + case HITLS_KEY_EXCH_PSK: + case HITLS_KEY_EXCH_RSA_PSK: +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: // signature is verified at parse time +#endif + ret = HITLS_SUCCESS; + break; + default: + ret = HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG; + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + break; + } + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15857, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client process server key exchange msg fail.", 0, 0, 0, 0); + return ret; + } + + /* update the state machine */ + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST); +} diff --git a/tls/handshake/send/include/hs_state_send.h b/tls/handshake/send/include/hs_state_send.h new file mode 100644 index 00000000..f23276f6 --- /dev/null +++ b/tls/handshake/send/include/hs_state_send.h @@ -0,0 +1,50 @@ +/* + * 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 HS_STATE_SEND_H +#define HS_STATE_SEND_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Handshake layer state machine message sending processing + * + * @param ctx [IN] TLS object + * + * @retval HITLS_SUCCESS + * @retval HITLS_MSG_HANDLE_UNSUPPORT_VERSION The TLS version is not supported + * @retval For details, see hitls_error.h + */ +int32_t HS_SendMsgProcess(TLS_Ctx *ctx); + +/** + * @brief Key update message sending and processing + * + * @param ctx [IN] TLS object + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t HS_HandleSendKeyUpdate(TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif /* end __cplusplus */ +#endif /* end HS_STATE_SEND_H */ \ No newline at end of file diff --git a/tls/handshake/send/src/hs_state_send.c b/tls/handshake/send/src/hs_state_send.c new file mode 100644 index 00000000..535b5cc4 --- /dev/null +++ b/tls/handshake/send/src/hs_state_send.c @@ -0,0 +1,190 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs.h" +#include "hs_common.h" +#include "send_process.h" +#include "hs_kx.h" +#include "pack.h" +#include "bsl_uio.h" +#include "bsl_sal.h" + + +#define KEY_UPDATE_HS_MSG_MAX_LEN 16u /* maximum length of key update message */ + +static int32_t ProcessSendHandshakeMsg(TLS_Ctx *ctx) +{ +#ifndef HITLS_NO_DTLS12 + uint32_t version = HS_GetVersion(ctx); +#endif + switch (ctx->hsCtx->state) { + case TRY_SEND_HELLO_REQUEST: + return ServerSendHelloRequestProcess(ctx); + case TRY_SEND_CLIENT_HELLO: + return ClientSendClientHelloProcess(ctx); + case TRY_SEND_SERVER_HELLO: + return ServerSendServerHelloProcess(ctx); + case TRY_SEND_CERTIFICATE: + return SendCertificateProcess(ctx); + case TRY_SEND_SERVER_KEY_EXCHANGE: + return ServerSendServerKeyExchangeProcess(ctx); + case TRY_SEND_CERTIFICATE_REQUEST: + return ServerSendCertRequestProcess(ctx); + case TRY_SEND_SERVER_HELLO_DONE: + return ServerSendServerHelloDoneProcess(ctx); + case TRY_SEND_CLIENT_KEY_EXCHANGE: + return ClientSendClientKeyExchangeProcess(ctx); + case TRY_SEND_CERTIFICATE_VERIFY: + return ClientSendCertVerifyProcess(ctx); + case TRY_SEND_CHANGE_CIPHER_SPEC: + return SendChangeCipherSpecProcess(ctx); + case TRY_SEND_NEW_SESSION_TICKET: + return SendNewSessionTicketProcess(ctx); + case TRY_SEND_FINISH: + if (ctx->isClient) { +#ifndef HITLS_NO_DTLS12 + if (version == HITLS_VERSION_DTLS12) { + return DtlsClientSendFinishedProcess(ctx); + } +#endif + return Tls12ClientSendFinishedProcess(ctx); + } else { +#ifndef HITLS_NO_DTLS12 + if (version == HITLS_VERSION_DTLS12) { + return DtlsServerSendFinishedProcess(ctx); + } +#endif + return Tls12ServerSendFinishedProcess(ctx); + } + default: + break; + } + return HITLS_MSG_HANDLE_STATE_ILLEGAL; +} + +int32_t Tls13SendChangeCipherSpecProcess(TLS_Ctx *ctx) +{ + int32_t ret; + + /** Sending message with changed cipher suites */ + ret = ctx->method.sendCCS(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HS_ChangeState(ctx, ctx->hsCtx->ccsNextState); +} + +static int32_t Tls13ProcessSendHandshakeMsg(TLS_Ctx *ctx) +{ + switch (ctx->hsCtx->state) { + case TRY_SEND_CLIENT_HELLO: + return Tls13ClientSendClientHelloProcess(ctx); + case TRY_SEND_HELLO_RETRY_REQUEST: + return Tls13ServerSendHelloRetryRequestProcess(ctx); + case TRY_SEND_SERVER_HELLO: + return Tls13ServerSendServerHelloProcess(ctx); + case TRY_SEND_ENCRYPTED_EXTENSIONS: + return Tls13ServerSendEncryptedExtensionsProcess(ctx); + case TRY_SEND_CERTIFICATE_REQUEST: + return Tls13ServerSendCertRequestProcess(ctx); + case TRY_SEND_CERTIFICATE: + if (ctx->isClient) { + return Tls13ClientSendCertificateProcess(ctx); + } else { + return Tls13ServerSendCertificateProcess(ctx); + } + case TRY_SEND_CERTIFICATE_VERIFY: + return Tls13SendCertVerifyProcess(ctx); + case TRY_SEND_FINISH: + if (ctx->isClient) { + return Tls13ClientSendFinishedProcess(ctx); + } else { + return Tls13ServerSendFinishedProcess(ctx); + } + case TRY_SEND_NEW_SESSION_TICKET: + return Tls13SendNewSessionTicketProcess(ctx); + + case TRY_SEND_CHANGE_CIPHER_SPEC: + return Tls13SendChangeCipherSpecProcess(ctx); + default: + break; + } + return HITLS_MSG_HANDLE_STATE_ILLEGAL; +} + +int32_t HS_SendMsgProcess(TLS_Ctx *ctx) +{ + uint32_t version = HS_GetVersion(ctx); + + switch (version) { + case HITLS_VERSION_TLS12: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + return ProcessSendHandshakeMsg(ctx); + case HITLS_VERSION_TLS13: + return Tls13ProcessSendHandshakeMsg(ctx); +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + return ProcessSendHandshakeMsg(ctx); +#endif + default: + break; + } + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15790, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state send error: unsupport TLS version.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; +} + +int32_t HS_HandleSendKeyUpdate(TLS_Ctx *ctx) +{ + uint8_t msgBuf[KEY_UPDATE_HS_MSG_MAX_LEN]; + uint32_t msgLen = 0; + + int32_t ret = HS_PackMsg(ctx, KEY_UPDATE, msgBuf, KEY_UPDATE_HS_MSG_MAX_LEN, &msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15791, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 key update msg fail.", 0, 0, 0, 0); + return ret; + } + + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, msgBuf, msgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15792, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 key update msg success.", 0, 0, 0, 0); + + /* After the key update message is sent, the app traffic secret used by the local is updated and activated. */ + ret = HS_TLS13UpdateTrafficSecret(ctx, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15793, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 out key update fail", 0, 0, 0, 0); + return ret; + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15794, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "tls1.3 send key update success.", 0, 0, 0, 0); + + return HITLS_SUCCESS; +} diff --git a/tls/handshake/send/src/send_cert_request.c b/tls/handshake/send/src/send_cert_request.c new file mode 100644 index 00000000..c2658681 --- /dev/null +++ b/tls/handshake/send/src/send_cert_request.c @@ -0,0 +1,112 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" +#include "bsl_sal.h" + +#define CERT_REQ_CTX_SIZE 32 + +static int32_t PackAndSendCertRequest(TLS_Ctx *ctx) +{ + int32_t ret; + /** get the server infomation */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** determine whether to assemble a message */ + if (hsCtx->msgLen == 0) { + /* assemble message */ + ret = HS_PackMsg(ctx, CERTIFICATE_REQUEST, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15836, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack certificate request msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t ServerSendCertRequestProcess(TLS_Ctx *ctx) +{ + int32_t ret; + ret = PackAndSendCertRequest(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15837, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send certificate request msg success.", 0, 0, 0, 0); + + /** update the state machine */ + ctx->hsCtx->isNeedClientCert = true; + ctx->negotiatedInfo.certReqSendTime++; + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO_DONE); +} + +int32_t Tls13ServerSendCertRequestProcess(TLS_Ctx *ctx) +{ + int32_t ret; + if (ctx->phaState == PHA_PENDING) { + BSL_SAL_FREE(ctx->certificateReqCtx); + ctx->certificateReqCtx = BSL_SAL_Calloc(CERT_REQ_CTX_SIZE, sizeof(uint8_t)); + if (ctx->certificateReqCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15774, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert req ctx malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + ret = SAL_CRYPT_Rand(ctx->certificateReqCtx, CERT_REQ_CTX_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(ctx->certificateReqCtx); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15775, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate random cert req ctx fail.", 0, 0, 0, 0); + return ret; + } + ctx->certificateReqCtxSize = CERT_REQ_CTX_SIZE; + } + ret = PackAndSendCertRequest(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15838, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send tls1.3 certificate request msg success.", 0, 0, 0, 0); + + ctx->hsCtx->isNeedClientCert = true; + ctx->negotiatedInfo.certReqSendTime++; + if (ctx->phaState == PHA_PENDING) { + ctx->phaState = PHA_REQUESTED; + SAL_CRYPT_DigestFree(ctx->phaCurHash); + ctx->phaCurHash = ctx->hsCtx->verifyCtx->hashCtx; + ctx->hsCtx->verifyCtx->hashCtx = NULL; + return HS_ChangeState(ctx, TLS_CONNECTED); + } + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE); +} diff --git a/tls/handshake/send/src/send_cert_verify.c b/tls/handshake/send/src/send_cert_verify.c new file mode 100644 index 00000000..a1e2e9c3 --- /dev/null +++ b/tls/handshake/send/src/send_cert_verify.c @@ -0,0 +1,85 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_verify.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" + + +static int32_t PackAndSendCertVerify(TLS_Ctx *ctx) +{ + int32_t ret; + HS_Ctx *hsCtx = ctx->hsCtx; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + + /** determine whether to assemble a message */ + if (hsCtx->msgLen == 0) { + HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(mgrCtx, false); + ret = VERIFY_CalcSignData(ctx, privateKey, ctx->negotiatedInfo.signScheme); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* assemble message */ + ret = HS_PackMsg(ctx, CERTIFICATE_VERIFY, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15833, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client pack certificate verify msg fail.", 0, 0, 0, 0); + return ret; + } + /** after the signature is used up, the length is set to 0, and the signature is used by the finish */ + hsCtx->verifyCtx->verifyDataSize = 0; + } + + return HS_SendMsg(ctx); +} + +int32_t ClientSendCertVerifyProcess(TLS_Ctx *ctx) +{ + int32_t ret; + ret = PackAndSendCertVerify(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15834, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client send certificate verify msg success.", 0, 0, 0, 0); + + /** update the state machine */ + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); +} + +int32_t Tls13SendCertVerifyProcess(TLS_Ctx *ctx) +{ + int32_t ret; + ret = PackAndSendCertVerify(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15835, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 certificate verify msg success.", 0, 0, 0, 0); + + return HS_ChangeState(ctx, TRY_SEND_FINISH); +} diff --git a/tls/handshake/send/src/send_certificate.c b/tls/handshake/send/src/send_certificate.c new file mode 100644 index 00000000..0e84925b --- /dev/null +++ b/tls/handshake/send/src/send_certificate.c @@ -0,0 +1,161 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_msg.h" +#include "hs_common.h" +#include "hs_kx.h" +#include "pack.h" +#include "send_process.h" + +int32_t SendCertificateProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + /* Only the client can send a certificate message with an empty certificate */ + if ((ctx->isClient == false) && (SAL_CERT_GetCurrentCert(mgrCtx) == NULL)) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15760, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "no certificate could be used in server.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE; + } + + ret = HS_PackMsg(ctx, CERTIFICATE, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15761, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack certificate msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15762, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send certificate msg success.", 0, 0, 0, 0); + + if (ctx->isClient) { + return HS_ChangeState(ctx, TRY_SEND_CLIENT_KEY_EXCHANGE); + } + if (IsNeedServerKeyExchange(ctx) == true) { + return HS_ChangeState(ctx, TRY_SEND_SERVER_KEY_EXCHANGE); + } + /* The server sends CertificateRequest only when the isSupportClientVerify mode is enabled */ + if (ctx->config.tlsConfig.isSupportClientVerify) { + /* isSupportClientOnceVerify specifies whether the CR is sent only in the initial handshake phase. */ + /* The value of certReqSendTime indicates the number of sent CR messages. If the value of certReqSendTime in the + * renegotiation phase is 0 and isSupportClientOnceVerify is enabled, the CR messages will not be sent. */ + if (ctx->negotiatedInfo.certReqSendTime < 1 || !(ctx->config.tlsConfig.isSupportClientOnceVerify)) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST); + } + } + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO_DONE); +} + +int32_t Tls13ClientSendCertificateProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + /** In the middlebox scenario, if the client does not send the hrr message, a CCS message needs to be sent + * before the certificate */ + if (!ctx->hsCtx->haveHrr && ctx->phaState != PHA_REQUESTED) { + ret = ctx->method.sendCCS(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + if (ctx->phaState != PHA_REQUESTED) { + /* CCS messages cannot be encrypted. Therefore, you need to activate the + sending key of the client after sending CCS messages. */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->hsCtx->clientHsTrafficSecret, hashLen, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = HS_PackMsg(ctx, CERTIFICATE, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15763, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 client certificate msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15764, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 client certificate msg success.", 0, 0, 0, 0); + + /* If the certificate is empty, the certificate verify message does not need to be sent. */ + if (SAL_CERT_GetCurrentCert(ctx->config.tlsConfig.certMgrCtx) == NULL) { + return HS_ChangeState(ctx, TRY_SEND_FINISH); + } + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_VERIFY); +} + +int32_t Tls13ServerSendCertificateProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + /* The server cannot send an empty certificate message */ + if (SAL_CERT_GetCurrentCert(ctx->config.tlsConfig.certMgrCtx) == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15765, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "no certificate could be used in server.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_NO_SERVER_CERTIFICATE; + } + + ret = HS_PackMsg(ctx, CERTIFICATE, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15766, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack server tls1.3 certificate msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15767, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 server certificate msg success.", 0, 0, 0, 0); + + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_VERIFY); +} diff --git a/tls/handshake/send/src/send_change_cipher_spec.c b/tls/handshake/send/src/send_change_cipher_spec.c new file mode 100644 index 00000000..4269b209 --- /dev/null +++ b/tls/handshake/send/src/send_change_cipher_spec.c @@ -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. + */ + +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "rec.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "send_process.h" + + +int32_t SendChangeCipherSpecProcess(TLS_Ctx *ctx) +{ + int32_t ret; + + /** send message which changed cipher suites */ + ret = ctx->method.sendCCS(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** enable key specification */ + ret = REC_ActivePendingState(ctx, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15873, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "active pending fail.", 0, 0, 0, 0); + return ret; + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15874, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send ccs msg success.", 0, 0, 0, 0); + ctx->negotiatedInfo.isEncryptThenMacWrite = ctx->negotiatedInfo.isEncryptThenMac; + /** update the state machine */ + return HS_ChangeState(ctx, TRY_SEND_FINISH); +} diff --git a/tls/handshake/send/src/send_client_hello.c b/tls/handshake/send/src/send_client_hello.c new file mode 100644 index 00000000..875d7b75 --- /dev/null +++ b/tls/handshake/send/src/send_client_hello.c @@ -0,0 +1,568 @@ +/* + * 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 +#include "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt.h" +#include "bsl_uio.h" +#include "hitls_error.h" +#include "hitls_session.h" +#include "hitls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "hs_verify.h" +#include "pack.h" +#include "send_process.h" +#include "session_mgr.h" +#include "bsl_bytes.h" + + +/* Check whether the resume function is supported */ +static int32_t ClientPrepareSession(TLS_Ctx *ctx) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /* If the session cannot be resumed during renegotiation, delete the session */ + if (ctx->negotiatedInfo.isRenegotiation && !ctx->config.tlsConfig.isResumptionOnRenego) { + HITLS_SESS_Free(ctx->session); + ctx->session = NULL; + } + + if (ctx->session != NULL) { + uint64_t curTime = (uint64_t)BSL_SAL_CurrentSysTimeGet(); + if (!SESS_CheckValidity(ctx->session, curTime)) { + HITLS_SESS_Free(ctx->session); + ctx->session = NULL; + } + } + + if (ctx->session != NULL) { + uint8_t haveExtMasterSecret = 0; + HITLS_SESS_GetHaveExtMasterSecret(ctx->session, &haveExtMasterSecret); + if (haveExtMasterSecret == 0 && ctx->config.tlsConfig.isSupportExtendMasterSecret) { + HITLS_SESS_Free(ctx->session); + ctx->session = NULL; + return HITLS_SUCCESS; + } + hsCtx->sessionId = (uint8_t *)BSL_SAL_Calloc(1u, HITLS_SESSION_ID_MAX_SIZE); + if (hsCtx->sessionId == NULL) { + HITLS_SESS_Free(ctx->session); + ctx->session = NULL; + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15624, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "session Id malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + hsCtx->sessionIdSize = HITLS_SESSION_ID_MAX_SIZE; + int32_t ret = HITLS_SESS_GetSessionId(ctx->session, hsCtx->sessionId, &hsCtx->sessionIdSize); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(hsCtx->sessionId); + HITLS_SESS_Free(ctx->session); + ctx->session = NULL; + return ret; + } + } + + return HITLS_SUCCESS; +} + +static int32_t ClientChangeStateAfterSendClientHello(TLS_Ctx *ctx) +{ + if (ctx->session != NULL && IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + /* In the DTLS scenario, enable the receiving of CCS messages to prevent CCS message disorder during session + * resumption */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + } + return HS_ChangeState(ctx, TRY_RECV_SERVER_HELLO); +} + +int32_t ClientSendClientHelloProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain client information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + /* If HelloVerifyRequest is used, the initial ClientHello and + HelloVerifyRequest are not included in the calculation of the + handshake_messages (for the CertificateVerify message) and + verify_data (for the Finished message). */ + ret = VERIFY_Init(hsCtx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* 1. For DTLS, the Hello Verify Request message may be received. If the Client Hello message is sent for the + * second time, the random and session of the previous session can be used directly. If the value of cookieSize + * is not 0, the Hello Verify Request message is received. + * 2. In the renegotiation state, the random and session need to be obtained again */ + if ((ctx->negotiatedInfo.cookieSize == 0) || (ctx->negotiatedInfo.isRenegotiation)) { + ret = ClientPrepareSession(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SAL_CRYPT_Rand(hsCtx->clientRandom, HS_RANDOM_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15625, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate random value fail.", 0, 0, 0, 0); + return ret; + } + } + + ctx->negotiatedInfo.clientVersion = ctx->config.tlsConfig.maxVersion; + ret = HS_PackMsg(ctx, CLIENT_HELLO, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15626, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack client hello fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15627, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send client hello success.", 0, 0, 0, 0); + + return ClientChangeStateAfterSendClientHello(ctx); +} +static bool Tls13SelectGroup(TLS_Ctx *ctx, uint16_t *group) +{ + TLS_Config *tlsConfig = &ctx->config.tlsConfig; + uint16_t version = (ctx->negotiatedInfo.version == 0) ? + ctx->config.tlsConfig.maxVersion : ctx->negotiatedInfo.version; + for (uint32_t i = 0; i < tlsConfig->groupsSize; ++i) { + if (GroupConformToVersion(version, tlsConfig->groups[i])) { + *group = tlsConfig->groups[i]; + return true; + } + } + return false; +} + +static int32_t Tls13ClientPrepareKeyShare(TLS_Ctx *ctx, uint32_t tls13BasicKeyExMode) +{ + TLS_Config *tlsConfig = &ctx->config.tlsConfig; + // Certificate authentication and PSK with DHE authentication require key share + uint32_t needKeyShareMode = TLS13_KE_MODE_PSK_WITH_DHE | TLS13_CERT_AUTH_WITH_DHE; + if ((tls13BasicKeyExMode & needKeyShareMode) == 0) { + return HITLS_SUCCESS; + } + + if (tlsConfig->groups == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15628, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tlsConfig->groups is null when prepare key share.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + + uint16_t selectGroup = tlsConfig->groups[0]; + /* The keyShare has passed the verification when receiving the HRR */ + KeyShareParam *keyShare = &ctx->hsCtx->kxCtx->keyExchParam.share; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + if (ctx->hsCtx->haveHrr) { + /** If the value of group is not updated in the hello retry request, the system directly returns */ + if (selectGroup == keyShare->group) { + return HITLS_SUCCESS; + } + + /** If the value of group is updated, use the updated group */ + selectGroup = keyShare->group; + } else { + if (!Tls13SelectGroup(ctx, &selectGroup)) { + return HITLS_MSG_HANDLE_ILLEGAL_SELECTED_GROUP; + } + /** Send the client hello message for the first time and fill in the group in the key share extension */ + keyShare->group = selectGroup; + } + HITLS_ECParameters curveParams = { + .type = HITLS_EC_CURVE_TYPE_NAMED_CURVE, + .param.namedcurve = selectGroup, + }; + HITLS_CRYPT_Key *key = NULL; + // ecdhe and dhe groups can invoke the same interface to generate keys. + key = SAL_CRYPT_GenEcdhKeyPair(&curveParams); + if (key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15629, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server generate key share key pair error.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + if (kxCtx->key != NULL) { + SAL_CRYPT_FreeEcdhKey(kxCtx->key); + } + kxCtx->key = key; + + return HITLS_SUCCESS; +} + +static int32_t Tls13ClientPrepareSession(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + hsCtx->sessionId = (uint8_t *)BSL_SAL_Calloc(1u, HITLS_SESSION_ID_MAX_SIZE); + if (hsCtx->sessionId == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15630, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "session Id malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + ret = SAL_CRYPT_Rand(hsCtx->sessionId, HITLS_SESSION_ID_MAX_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(hsCtx->sessionId); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15631, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate random session Id fail.", 0, 0, 0, 0); + return ret; + } + hsCtx->sessionIdSize = HITLS_SESSION_ID_MAX_SIZE; + + return HITLS_SUCCESS; +} + +int32_t CreatePskSession(TLS_Ctx *ctx, uint8_t *id, uint32_t idLen, HITLS_Session **pskSession) +{ + if (ctx == NULL || pskSession == NULL) { + return HITLS_NULL_INPUT; + } + + if (ctx->config.tlsConfig.pskClientCb == NULL) { + return HITLS_SUCCESS; + } + + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + uint32_t pskLen = ctx->config.tlsConfig.pskClientCb(ctx, NULL, id, idLen, psk, HS_PSK_MAX_LEN); + if (pskLen == 0) { + return HITLS_SUCCESS; + } + if (pskLen > HS_PSK_MAX_LEN) { + return HITLS_MSG_HANDLE_ILLEGAL_PSK_LEN; + } + + HITLS_Session *sess = HITLS_SESS_New(); + if (sess == NULL) { + memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + return HITLS_MEMALLOC_FAIL; + } + + HITLS_SESS_SetMasterKey(sess, psk, pskLen); + HITLS_SESS_SetCipherSuite(sess, HITLS_AES_128_GCM_SHA256); + HITLS_SESS_SetProtocolVersion(sess, HITLS_VERSION_TLS13); + *pskSession = sess; + memset_s(psk, HS_PSK_MAX_LEN, 0, HS_PSK_MAX_LEN); + return HITLS_SUCCESS; +} + +static bool IsTls13SessionValid(HITLS_HashAlgo hashAlgo, HITLS_Session* session, uint16_t *tls13CipherSuites, + uint32_t tls13cipherSuitesSize) +{ + uint16_t version = 0; + HITLS_SESS_GetProtocolVersion(session, &version); + if (version != HITLS_VERSION_TLS13) { + return false; + } + uint16_t cipherSuite = 0; + CipherSuiteInfo cipherInfo = {0}; + (void)HITLS_SESS_GetCipherSuite(session, &cipherSuite); // only null input cause error + int32_t ret = CFG_GetCipherSuiteInfo(cipherSuite, &cipherInfo); + if (ret != HITLS_SUCCESS) { + return false; + } + if (hashAlgo != HITLS_HASH_NULL) { + return (hashAlgo == cipherInfo.hashAlg); + } + if (tls13CipherSuites != NULL) { + for (uint32_t i = 0; i < tls13cipherSuitesSize; i++) { + CipherSuiteInfo configCipher = {0}; + ret = CFG_GetCipherSuiteInfo(tls13CipherSuites[i], &configCipher); + if (ret == HITLS_SUCCESS && configCipher.hashAlg == cipherInfo.hashAlg) { + return true; + } + } + } + return false; +} + +static UserPskList *ConstructUserPsk(HITLS_Session *sessoin, const uint8_t *identity, uint32_t identityLen, + uint8_t curIndex) +{ + if (identityLen > HS_PSK_IDENTITY_MAX_LEN || sessoin == NULL) { + return NULL; + } + UserPskList *userPsk = BSL_SAL_Calloc(1, sizeof(UserPskList)); + if (userPsk == NULL) { + return NULL; + } + userPsk->pskSession = HITLS_SESS_Dup(sessoin); + userPsk->identity = BSL_SAL_Calloc(1, identityLen); + if (userPsk->identity == NULL) { + BSL_SAL_FREE(userPsk); + return NULL; + } + (void)memcpy_s(userPsk->identity, identityLen, identity, identityLen); + userPsk->identityLen = identityLen; + userPsk->num = curIndex; + return userPsk; +} + +static int32_t Tls13ClientPreparePSK(TLS_Ctx *ctx) +{ + int32_t ret = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + HITLS_HashAlgo hashAlgo = hsCtx->haveHrr ? ctx->negotiatedInfo.cipherSuiteInfo.hashAlg : HITLS_HASH_NULL; + uint8_t identity[HS_PSK_IDENTITY_MAX_LEN + 1] = {0}; + const uint8_t *id = NULL; + uint32_t idLen = 0; + HITLS_Session *pskSession = NULL; + UserPskList *userPsk = NULL; + + /* Obtain the resume psk information from the session */ + HITLS_SESS_Free(hsCtx->kxCtx->pskInfo13.resumeSession); + hsCtx->kxCtx->pskInfo13.resumeSession = NULL; + if (HITLS_SESS_HasTicket(ctx->session) && + IsTls13SessionValid(hashAlgo, ctx->session, ctx->config.tlsConfig.tls13CipherSuites, + ctx->config.tlsConfig.tls13cipherSuitesSize) && + SESS_CheckValidity(ctx->session, (uint64_t)BSL_SAL_CurrentSysTimeGet())) { + hsCtx->kxCtx->pskInfo13.resumeSession = HITLS_SESS_Dup(ctx->session); + } + + uint8_t index = (hsCtx->kxCtx->pskInfo13.resumeSession == NULL) ? 0 : 1; + if (ctx->config.tlsConfig.pskUseSessionCb != NULL) { + ret = ctx->config.tlsConfig.pskUseSessionCb(ctx, hashAlgo, &id, &idLen, &pskSession); + if (ret != HITLS_PSK_USE_SESSION_CB_SUCCESS) { + return HITLS_MSG_HANDLE_PSK_USE_SESSION_FAIL; + } + } + + if (pskSession == NULL) { + // use 1.2 psk callback default hashalgo == sha256 + ret = CreatePskSession(ctx, identity, HS_PSK_IDENTITY_MAX_LEN, &pskSession); + if (ret != HITLS_SUCCESS) { + return ret; + } + id = identity; + idLen = (uint32_t)strlen((char *)identity); + } + + if (pskSession != NULL && IsTls13SessionValid(hashAlgo, pskSession, ctx->config.tlsConfig.tls13CipherSuites, + ctx->config.tlsConfig.tls13cipherSuitesSize)) { + userPsk = ConstructUserPsk(pskSession, id, idLen, index); + } + HITLS_SESS_Free(pskSession); + pskSession = NULL; + + if (ctx->hsCtx->kxCtx->pskInfo13.userPskSess != NULL) { + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo13.userPskSess->identity); + HITLS_SESS_Free(ctx->hsCtx->kxCtx->pskInfo13.userPskSess->pskSession); + BSL_SAL_FREE(ctx->hsCtx->kxCtx->pskInfo13.userPskSess); + } + ctx->hsCtx->kxCtx->pskInfo13.userPskSess = userPsk; + return HITLS_SUCCESS; +} + +int32_t Tls13ClientHelloPrepare(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + /** After receiving the hello retry request message, the client needs to send the second clientHello. In this case, + * the following initialization is not required */ + if (hsCtx->haveHrr == false) { + ret = VERIFY_Init(hsCtx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SAL_CRYPT_Rand(hsCtx->clientRandom, HS_RANDOM_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15632, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate random value fail.", 0, 0, 0, 0); + return ret; + } + + /** In section 4.1.2 of RFC8446, a random session ID is required in middlebox mode. In nomiddlebox mode, the + * session ID is empty */ + ret = Tls13ClientPrepareSession(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } else { + /** If the middlebox is used, a CCS message must be sent before the second clientHello message is sent */ + ret = ctx->method.sendCCS(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + ret = Tls13ClientPreparePSK(ctx); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + uint32_t tls13BasicKeyExMode = 0; + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + if (pskInfo->resumeSession != NULL || pskInfo->userPskSess != NULL) { + tls13BasicKeyExMode |= ctx->config.tlsConfig.keyExchMode; // keyExchMode must not be 0 + } + + if (ctx->config.tlsConfig.signAlgorithmsSize != 0) { // base cert auth + tls13BasicKeyExMode |= TLS13_CERT_AUTH_WITH_DHE; + } + + /** Prepare the key share extension. The keyshares in two clientHello messages are different. Therefore, + * both the keyshares must be prepared */ + ret = Tls13ClientPrepareKeyShare(ctx, tls13BasicKeyExMode); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + if (tls13BasicKeyExMode == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15463, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls config error: can not decide tls13BasicKeyExMode ", 0, 0, 0, 0); + return HITLS_CONFIG_INVALID_SET; + } + ctx->negotiatedInfo.tls13BasicKeyExMode = tls13BasicKeyExMode; + + return HITLS_SUCCESS; +} + +static uint32_t GetBindersOffset(const TLS_Ctx *ctx) +{ + uint32_t ret = sizeof(uint16_t); + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + uint32_t binderLen = 0; + if (pskInfo->resumeSession != NULL) { + HITLS_HashAlgo hashAlg = HITLS_HASH_NULL; + binderLen = HS_GetBinderLen(pskInfo->resumeSession, &hashAlg); // Success guaranteed by the context + ret += binderLen + sizeof(uint8_t); + } + if (pskInfo->userPskSess != NULL) { + HITLS_HashAlgo hashAlg = HITLS_HASH_NULL; + binderLen = HS_GetBinderLen(pskInfo->userPskSess->pskSession, &hashAlg); // Success guaranteed by the context + ret += binderLen + sizeof(uint8_t); + } + return ret; +} + +static int32_t PackClientPreSharedKeyBinders(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen) +{ + uint32_t trucatedLen = (bufLen - GetBindersOffset(ctx)); + buf = buf + trucatedLen; + PskInfo13 *pskInfo = &ctx->hsCtx->kxCtx->pskInfo13; + uint32_t offset = sizeof(uint16_t); // skip binders len + uint8_t psk[HS_PSK_MAX_LEN] = {0}; + uint32_t pskLen = HS_PSK_MAX_LEN; + uint32_t binderLen = 0; + int32_t ret = HITLS_SUCCESS; + if (pskInfo->resumeSession != NULL) { + HITLS_HashAlgo hashAlg = HITLS_HASH_NULL; + binderLen = HS_GetBinderLen(pskInfo->resumeSession, &hashAlg); // Success guaranteed by the context + buf[offset] = binderLen; + offset++; + ret = HITLS_SESS_GetMasterKey(pskInfo->resumeSession, psk, &pskLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = VERIFY_CalcPskBinder(ctx, hashAlg, false, psk, pskLen, + ctx->hsCtx->msgBuf, trucatedLen, &buf[offset], binderLen); + BSL_SAL_CleanseData(psk, HS_PSK_MAX_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += binderLen; + } + + if (pskInfo->userPskSess != NULL) { + pskLen = HS_PSK_MAX_LEN; + HITLS_HashAlgo hashAlg = HITLS_HASH_NULL; + binderLen = HS_GetBinderLen(pskInfo->userPskSess->pskSession, &hashAlg); // context is guaranteed to succeed + buf[offset] = (uint8_t)binderLen; + offset++; + ret = HITLS_SESS_GetMasterKey(pskInfo->userPskSess->pskSession, psk, &pskLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = VERIFY_CalcPskBinder(ctx, hashAlg, true, psk, pskLen, + ctx->hsCtx->msgBuf, trucatedLen, &buf[offset], binderLen); + BSL_SAL_CleanseData(psk, HS_PSK_MAX_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + offset += binderLen; + } + + BSL_Uint16ToByte((uint16_t)(offset - sizeof(uint16_t)), &buf[0]); // pack binder len + return HITLS_SUCCESS; +} + +int32_t Tls13ClientSendClientHelloProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + + /* Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + ret = Tls13ClientHelloPrepare(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ctx->negotiatedInfo.clientVersion = HITLS_VERSION_TLS12; + /* The packed message is placed in the hsCtx->msgBuf. The length of the packed message is hsCtx->msgLen, + * including the CH message header and body */ + ret = HS_PackMsg(ctx, CLIENT_HELLO, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15633, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 client hello fail.", 0, 0, 0, 0); + return ret; + } + + if (hsCtx->extFlag.havePreShareKey == true) { + /* Calculate the binder */ + ret = PackClientPreSharedKeyBinders(ctx, hsCtx->msgBuf, hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + if (hsCtx->extFlag.havePostHsAuth && ctx->phaState == PHA_NONE) { + ctx->phaState = PHA_EXTENSION; + } + } + + if (!ctx->method.isRecvCCS(ctx)) { + /* Unencrypted CCS can be received after the first ClientHello is sent or received according to RFC 8446 */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15634, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 client hello success.", 0, 0, 0, 0); + + return HS_ChangeState(ctx, TRY_RECV_SERVER_HELLO); +} diff --git a/tls/handshake/send/src/send_client_key_exchange.c b/tls/handshake/send/src/send_client_key_exchange.c new file mode 100644 index 00000000..40156dae --- /dev/null +++ b/tls/handshake/send/src/send_client_key_exchange.c @@ -0,0 +1,161 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hs.h" +#include "hs_kx.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" +#include "securec.h" + +int32_t GenerateRsaPremasterSecret(TLS_Ctx *ctx) +{ + uint32_t offset = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *kxCtx = hsCtx->kxCtx; + uint8_t *preMasterSecret = kxCtx->keyExchParam.rsa.preMasterSecret; + + /* The First two bytes are the highest version supported by client */ + BSL_Uint16ToByte(ctx->negotiatedInfo.clientVersion, preMasterSecret); + offset = sizeof(uint16_t); + /* 46-byte secure random value */ + return SAL_CRYPT_Rand(&preMasterSecret[offset], MASTER_SECRET_LEN - offset); +} + +#ifndef HITLS_NO_TLCP11 +int32_t GenerateEccPremasterSecret(TLS_Ctx *ctx) +{ + uint32_t offset = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + KeyExchCtx *kxCtx = hsCtx->kxCtx; + uint8_t *premasterSecret = kxCtx->keyExchParam.ecc.preMasterSecret; + + /* The First two bytes are the highest version supported by client */ + BSL_Uint16ToByte(ctx->config.tlsConfig.maxVersion, premasterSecret); + offset = sizeof(uint16_t); + /* 46-byte secure random value */ + return SAL_CRYPT_Rand(&premasterSecret[offset], MASTER_SECRET_LEN - offset); +} +#endif + +/* Operations required before packaging CKE */ +static int32_t PackMsgPrepare(TLS_Ctx *ctx) +{ + int32_t ret = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + + if (hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_RSA || hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_RSA_PSK) { + ret = GenerateRsaPremasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + (void)memset_s(hsCtx->kxCtx->keyExchParam.rsa.preMasterSecret, MASTER_SECRET_LEN, 0, MASTER_SECRET_LEN); + return ret; + } + } + + /* If the PSK and RSA_PSK cipher suites are used, the server may not send the ServerKeyExchange message. Before + * packing the ClientKeyExchange message, check whether the PSK has been obtained */ + if (hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_PSK || hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_RSA_PSK) { + ret = CheckClientPsk(ctx); + if (ret != HITLS_SUCCESS) { + (void)memset_s(hsCtx->kxCtx->keyExchParam.rsa.preMasterSecret, MASTER_SECRET_LEN, 0, MASTER_SECRET_LEN); + return ret; + } + } + +#ifndef HITLS_NO_TLCP11 + if (hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_ECC) { + ret = GenerateEccPremasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + (void)memset_s(hsCtx->kxCtx->keyExchParam.ecc.preMasterSecret, MASTER_SECRET_LEN, 0, MASTER_SECRET_LEN); + return ret; + } + } +#endif + + return ret; +} + +int32_t ClientSendClientKeyExchangeProcess(TLS_Ctx *ctx) +{ + int32_t ret = 0; + HS_Ctx *hsCtx = ctx->hsCtx; + CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx; + + /* Check whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + ret = PackMsgPrepare(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_PackMsg(ctx, CLIENT_KEY_EXCHANGE, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15816, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client pack client key exchange msg error.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15817, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client send client key exchange msg success.", 0, 0, 0, 0); + + ret = HS_GenerateMasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15818, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client generate master secret fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + /* Client derives key */ + ret = HS_KeyEstablish(ctx, ctx->isClient); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15819, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client key establish fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + +#ifndef HITLS_NO_DTLS12 + ret = HS_SetSctpAuthKey(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } +#endif + /** + * If no certificate request is received and no certificate is available, + * the system proceeds to the next state. + * RFC 5246 7.4.8: This message (here is client certificate verify) is only sent following + * a client certificate that has signing capability. + * Therefore, the client certificate verify message will not be sent if client certificate is empty. + * For TLCP, SAL_CERT_GetCurrentCert MAY return NULL when dealing with cerificate request message, + * Whether the client needing to be verified depends on the server configuration. + */ + if (hsCtx->isNeedClientCert && (SAL_CERT_GetCurrentCert(mgrCtx) != NULL)) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_VERIFY); + } + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); +} diff --git a/tls/handshake/send/src/send_common.c b/tls/handshake/send/src/send_common.c new file mode 100644 index 00000000..694c97db --- /dev/null +++ b/tls/handshake/send/src/send_common.c @@ -0,0 +1,182 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "tls.h" +#include "rec.h" +#include "transcript_hash.h" +#include "hs_ctx.h" +#include "hs.h" +#include "send_process.h" +#include "indicator.h" + + +static int32_t TlsSendHandShakeMsg(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Add hash data */ + ret = VERIFY_Append(hsCtx->verifyCtx, hsCtx->msgBuf, hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15795, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify append fail when send handshake msg.", 0, 0, 0, 0); + return ret; + } + + INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen, + ctx, ctx->config.tlsConfig.msgArg); + + hsCtx->msgLen = 0; + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsSendFragmentHsMsg(TLS_Ctx *ctx, uint32_t maxRecPayloadLen) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + uint8_t *data = (uint8_t *)BSL_SAL_Calloc(1u, maxRecPayloadLen); + if (data == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + /* Copy the fragment header */ + if (memcpy_s(data, maxRecPayloadLen, hsCtx->msgBuf, DTLS_HS_MSG_HEADER_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15796, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "send handshake msg to record fail.", 0, 0, 0, 0); + BSL_SAL_FREE(data); + return HITLS_MEMCPY_FAIL; + } + + uint32_t fragmentOffset = 0; + uint32_t fragmentLen = 0; + /* Obtain the length of the handshake msg body */ + uint32_t packetLen = BSL_ByteToUint24(&hsCtx->msgBuf[DTLS_HS_MSGLEN_ADDR]); + + while (packetLen > 0) { + /* Calculate the fragment length */ + fragmentLen = packetLen; + if (packetLen > (maxRecPayloadLen - DTLS_HS_MSG_HEADER_SIZE)) { + fragmentLen = maxRecPayloadLen - DTLS_HS_MSG_HEADER_SIZE; + } + + BSL_Uint24ToByte(fragmentOffset, &data[DTLS_HS_FRAGMENT_OFFSET_ADDR]); + BSL_Uint24ToByte(fragmentLen, &data[DTLS_HS_FRAGMENT_LEN_ADDR]); + /* Write fragmented data */ + if (memcpy_s(&data[DTLS_HS_MSG_HEADER_SIZE], maxRecPayloadLen - DTLS_HS_MSG_HEADER_SIZE, + &hsCtx->msgBuf[DTLS_HS_MSG_HEADER_SIZE + fragmentOffset], fragmentLen) != EOK) { + BSL_SAL_FREE(data); + return HITLS_MEMCPY_FAIL; + } + + /* Send to the record layer */ + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, data, fragmentLen + DTLS_HS_MSG_HEADER_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(data); + return ret; + } + fragmentOffset += fragmentLen; + packetLen -= fragmentLen; + } + + BSL_SAL_FREE(data); + return HITLS_SUCCESS; +} +#endif + +#ifndef HITLS_NO_DTLS12 +static int32_t DtlsSendHandShakeMsg(TLS_Ctx *ctx) +{ + int32_t ret; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + uint32_t maxRecPayloadLen = 0; + ret = REC_GetMaxWriteSize(ctx, &maxRecPayloadLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* No sharding required */ + if (maxRecPayloadLen >= hsCtx->msgLen) { + /* Send to the record layer */ + ret = REC_Write(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15797, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "send handshake msg to record fail.", 0, 0, 0, 0); + return ret; + } + } else { + ret = DtlsSendFragmentHsMsg(ctx, maxRecPayloadLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* Add hash data */ + ret = VERIFY_Append(hsCtx->verifyCtx, hsCtx->msgBuf, hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15798, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "verify append fail when send handshake msg.", 0, 0, 0, 0); + return ret; + } + + INDICATOR_MessageIndicate(1, HS_GetVersion(ctx), REC_TYPE_HANDSHAKE, hsCtx->msgBuf, hsCtx->msgLen, + ctx, ctx->config.tlsConfig.msgArg); + + hsCtx->msgLen = 0; + hsCtx->nextSendSeq++; + + return HITLS_SUCCESS; +} +#endif + +int32_t HS_SendMsg(TLS_Ctx *ctx) +{ + uint32_t version = HS_GetVersion(ctx); + switch (version) { + case HITLS_VERSION_TLS12: + case HITLS_VERSION_TLS13: +#ifndef HITLS_NO_TLCP11 + case HITLS_VERSION_TLCP11: +#endif + return TlsSendHandShakeMsg(ctx); +#ifndef HITLS_NO_DTLS12 + case HITLS_VERSION_DTLS12: + return DtlsSendHandShakeMsg(ctx); +#endif + default: + break; + } + + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15799, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Send handshake msg of unsupported version.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; +} diff --git a/tls/handshake/send/src/send_encrypted_extensions.c b/tls/handshake/send/src/send_encrypted_extensions.c new file mode 100644 index 00000000..423eabd5 --- /dev/null +++ b/tls/handshake/send/src/send_encrypted_extensions.c @@ -0,0 +1,83 @@ +/* + * 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 +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "crypt.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_kx.h" +#include "hs_common.h" +#include "hs_msg.h" +#include "pack.h" +#include "send_process.h" + + +int32_t Tls13ServerSendEncryptedExtensionsProcess(TLS_Ctx *ctx) +{ + int32_t ret; + /** Obtain the client information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + + /* The CCS message cannot be encrypted. Therefore, the sending key of the server must be activated after the CCS + * message is sent */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->hsCtx->serverHsTrafficSecret, hashLen, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_PackMsg(ctx, ENCRYPTED_EXTENSIONS, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15875, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 encrypted extensions fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15876, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 encrypted extensions success.", 0, 0, 0, 0); + + if (ctx->hsCtx->kxCtx->pskInfo13.psk != NULL) { + return HS_ChangeState(ctx, TRY_SEND_FINISH); + } + + /* The server sends a CertificateRequest message only when the VerifyPeer mode is enabled */ + if (ctx->config.tlsConfig.isSupportClientVerify && ctx->phaState != PHA_EXTENSION) { + /* VerifyOnce is used to control the CR sent only in the initial handshake phase. */ + /* certReqSendTime indicates the number of sent CRs. If the value of certReqSendTime is not zero in the + * post-authentication phase, it indicates that the CRs have been sent */ + if (ctx->negotiatedInfo.certReqSendTime < 1 || !(ctx->config.tlsConfig.isSupportClientOnceVerify)) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST); + } + } + + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE); +} diff --git a/tls/handshake/send/src/send_finished.c b/tls/handshake/send/src/send_finished.c new file mode 100644 index 00000000..0c7d1113 --- /dev/null +++ b/tls/handshake/send/src/send_finished.c @@ -0,0 +1,452 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_verify.h" +#include "transcript_hash.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" +#include "hs_kx.h" + + +int32_t PrepareClientFinishedMsg(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + + ret = VERIFY_CalcVerifyData(ctx, true, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15357, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client Calculate client finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + (void)memset_s(ctx->hsCtx->masterKey, sizeof(ctx->hsCtx->masterKey), 0, sizeof(ctx->hsCtx->masterKey)); + return ret; + } + + ret = HS_PackMsg(ctx, FINISHED, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15358, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client pack finished msg error.", 0, 0, 0, 0); + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t Tls12ClientSendFinishedProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + + /** Determine whether the message needs to be packed. */ + if (hsCtx->msgLen == 0) { + ret = PrepareClientFinishedMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15359, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client send finished msg error.", 0, 0, 0, 0); + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15360, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client send finished msg success.", 0, 0, 0, 0); + + if (ctx->negotiatedInfo.isResume == true) { + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + return HS_ChangeState(ctx, TLS_CONNECTED); + } + + if (ctx->negotiatedInfo.isTicket == true) { + return HS_ChangeState(ctx, TRY_RECV_NEW_SESSION_TICKET); + } + + ret = VERIFY_CalcVerifyData(ctx, false, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15361, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client Calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} + +static int32_t CalcVerifyData(TLS_Ctx *ctx) +{ + int32_t ret = VERIFY_CalcVerifyData(ctx, false, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15362, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server Calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + return HITLS_SUCCESS; +} + +int32_t Tls12ServerSendFinishedProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + ret = CalcVerifyData(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_PackMsg(ctx, FINISHED, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15363, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack finished msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15364, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server send finished msg fail.", 0, 0, 0, 0); + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15365, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send finished msg success.", 0, 0, 0, 0); + if (ctx->negotiatedInfo.isResume == true) { + /* Calculate the client verify data: used to verify the finished message of the client */ + ret = VERIFY_CalcVerifyData(ctx, true, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15366, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "tls12 server Calculate client finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + (void)memset_s(ctx->hsCtx->masterKey, sizeof(ctx->hsCtx->masterKey), 0, sizeof(ctx->hsCtx->masterKey)); + return ret; + } + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + return HS_ChangeState(ctx, TRY_RECV_FINISH); + } + /* No CCS messages can be received */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + + return HS_ChangeState(ctx, TLS_CONNECTED); +} + +#ifndef HITLS_NO_DTLS12 +static int32_t DtlsClientChangeStateAfterSendFinished(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + + if (ctx->negotiatedInfo.isResume == true) { + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + return HS_ChangeState(ctx, TLS_CONNECTED); + } + + ret = VERIFY_CalcVerifyData(ctx, false, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15367, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client Calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + if (ctx->negotiatedInfo.isTicket == true) { + return HS_ChangeState(ctx, TRY_RECV_NEW_SESSION_TICKET); + } + + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} +#endif + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsClientSendFinishedProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + + /** Determine whether the message needs to be packed */ + if (ctx->hsCtx->msgLen == 0) { + ret = PrepareClientFinishedMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15370, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client send finished msg success.", 0, 0, 0, 0); + return DtlsClientChangeStateAfterSendFinished(ctx); +} +#endif + +#ifndef HITLS_NO_DTLS12 +static int32_t DtlsServerChangeStateAfterSendFinished(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + + if (ctx->negotiatedInfo.isResume == true) { + /* Calculate the client verify data: used to verify the finished message of the client */ + ret = VERIFY_CalcVerifyData(ctx, true, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + (void)memset_s(ctx->hsCtx->masterKey, sizeof(ctx->hsCtx->masterKey), 0, sizeof(ctx->hsCtx->masterKey)); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15371, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "dtls server Calculate client finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_ACTIVE_CIPHER_SPEC); + + return HS_ChangeState(ctx, TRY_RECV_FINISH); + } + + /* No CCS messages can be received */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_EXIT_READY); + return HS_ChangeState(ctx, TLS_CONNECTED); +} +#endif + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsServerSendFinishedProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + ret = VERIFY_CalcVerifyData(ctx, false, ctx->hsCtx->masterKey, MASTER_SECRET_LEN); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15372, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server Calculate server finished data error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = HS_PackMsg(ctx, FINISHED, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15373, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack finished msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15374, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send finished msg success.", 0, 0, 0, 0); + + return DtlsServerChangeStateAfterSendFinished(ctx); +} +#endif + +static int32_t Tls13ClientSendFinishPostProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + if (ctx->phaState == PHA_REQUESTED) { + ctx->phaState = PHA_EXTENSION; + } else { + /* switch Application Traffic Secret */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->clientAppTrafficSecret, hashLen, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_TLS13DeriveResumptionMasterSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->phaState == PHA_EXTENSION && ctx->config.tlsConfig.isSupportPostHandshakeAuth) { + SAL_CRYPT_DigestFree(ctx->phaHash); + ctx->phaHash = SAL_CRYPT_DigestCopy(ctx->hsCtx->verifyCtx->hashCtx); + if (ctx->phaHash == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15407, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pha hash copy error: digest copy fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_DIGEST; + } + } + } + return HS_ChangeState(ctx, TLS_CONNECTED); +} + +int32_t Tls13ClientSendFinishedProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + if ((!ctx->hsCtx->haveHrr) && (!ctx->hsCtx->isNeedClientCert)) { + /** In the middlebox scenario, if the client does not send the hrr message and the certificate does not need + * to be sent, a CCS message needs to be sent before the finished message */ + ret = ctx->method.sendCCS(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* If the certificate of the client is sent, the key has been activated when the certificate is sent. You do not + * need to activate the key again */ + if (!ctx->hsCtx->isNeedClientCert && ctx->phaState != PHA_REQUESTED) { + /* The CCS message cannot be encrypted. Therefore, the sending key of the client must be activated + * after the CCS message is sent */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->hsCtx->clientHsTrafficSecret, hashLen, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = VERIFY_Tls13CalcVerifyData(ctx, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15375, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client calculate client finished data fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = HS_PackMsg(ctx, FINISHED, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15376, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client pack tls1.3 finished msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15377, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "client send tls1.3 finished msg success.", 0, 0, 0, 0); + + return Tls13ClientSendFinishPostProcess(ctx); +} + +static int32_t PrepareServerSendFinishedMsg(TLS_Ctx *ctx) +{ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + int32_t ret = VERIFY_Tls13CalcVerifyData(ctx, false); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15378, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server calculate server finished data fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = HS_PackMsg(ctx, FINISHED, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15379, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack tls1.3 finished msg fail.", 0, 0, 0, 0); + return ret; + } + return ret; +} + +int32_t Tls13ServerSendFinishedProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + ret = PrepareServerSendFinishedMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15380, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send tls1.3 finished msg success.", 0, 0, 0, 0); + + ret = HS_TLS13CalcServerFinishProcessSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* After the server sends the ServerFinish message, the clientTrafficSecret needs to be activated for decryption of + * the received message from the peer */ + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + ret = HS_SwitchTrafficKey(ctx, ctx->hsCtx->clientHsTrafficSecret, hashLen, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Activating the local serverAppTrafficSecret-encrypted App Data */ + ret = HS_SwitchTrafficKey(ctx, ctx->serverAppTrafficSecret, hashLen, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (ctx->hsCtx->isNeedClientCert) { + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE); + } + + /** Calculate the client verify data */ + ret = VERIFY_Tls13CalcVerifyData(ctx, true); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15381, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server calculate client finished data fail.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + return HS_ChangeState(ctx, TRY_RECV_FINISH); +} diff --git a/tls/handshake/send/src/send_hello_request.c b/tls/handshake/send/src/send_hello_request.c new file mode 100644 index 00000000..e30c0d19 --- /dev/null +++ b/tls/handshake/send/src/send_hello_request.c @@ -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. + */ + +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_verify.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" + + +int32_t ServerSendHelloRequestProcess(TLS_Ctx *ctx) +{ + int32_t ret; + /** get the server infomation */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** determine whether to assemble a message */ + if (hsCtx->msgLen == 0) { + /* assemble message */ + ret = HS_PackMsg(ctx, HELLO_REQUEST, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15906, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack hello request msg fail.", 0, 0, 0, 0); + return ret; + } + } + + /** writing handshake message */ + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** hash calculation is not required for HelloRequest messages */ + ret = VERIFY_Init(hsCtx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* The server does not enter the renegotiation state when sending a HelloRequest message. + The server enters the renegotiation state only when receiving a ClientHello message. */ + ctx->negotiatedInfo.isRenegotiation = false; + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15907, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send hello request msg success.", 0, 0, 0, 0); + + return HS_ChangeState(ctx, TRY_RECV_CLIENT_HELLO); +} diff --git a/tls/handshake/send/src/send_new_session_ticket.c b/tls/handshake/send/src/send_new_session_ticket.c new file mode 100644 index 00000000..da4da55d --- /dev/null +++ b/tls/handshake/send/src/send_new_session_ticket.c @@ -0,0 +1,191 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "rec.h" +#include "hs_ctx.h" +#include "hs_kx.h" +#include "hs_common.h" +#include "session_mgr.h" +#include "pack.h" +#include "send_process.h" +#include "securec.h" + +#define HITLS_ONE_WEEK_SECONDS (604800) + +int32_t SendNewSessionTicketProcess(TLS_Ctx *ctx) +{ + int32_t ret; + HS_Ctx *hsCtx = ctx->hsCtx; + TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr; + + /** determine whether to assemble a message */ + if (hsCtx->msgLen == 0) { + hsCtx->ticketLifetimeHint = (uint32_t)SESSMGR_GetTimeout(sessMgr); + BSL_SAL_FREE(hsCtx->ticket); + hsCtx->ticketSize = 0; + ret = SESSMGR_EncryptSessionTicket(sessMgr, ctx->session, &hsCtx->ticket, &hsCtx->ticketSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16046, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "SESSMGR_EncryptSessionTicket return fail when send new session ticket msg.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + /* assemble message */ + ret = HS_PackMsg(ctx, NEW_SESSION_TICKET, hsCtx->msgBuf, REC_MAX_PLAIN_LENGTH, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15978, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack new session ticket msg fail.", 0, 0, 0, 0); + return ret; + } + } + + /** writing Handshake message */ + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15979, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send new session ticket msg success.", 0, 0, 0, 0); + /** update the state machine */ + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); +} + +static int32_t Tls13TicketGenerateConfigSesson(TLS_Ctx *ctx, HITLS_Session **sessionPtr, + uint8_t *resumePsk, uint32_t hashLen) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_Session *newSession = NULL; + HS_Ctx *hsCtx = ctx->hsCtx; + newSession = SESS_Copy(ctx->session); + if (newSession == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16050, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy session info failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return HITLS_MEMALLOC_FAIL; + } + + SESS_SetStartTime(newSession, (uint64_t)BSL_SAL_CurrentSysTimeGet()); + HITLS_SESS_SetTimeout(newSession, (uint64_t)hsCtx->ticketLifetimeHint); + HITLS_SESS_SetMasterKey(newSession, resumePsk, hashLen); + ret = SAL_CRYPT_Rand((uint8_t *)&hsCtx->ticketAgeAdd, sizeof(hsCtx->ticketAgeAdd)); + if (ret != HITLS_SUCCESS) { + HITLS_SESS_Free(newSession); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16047, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "generate ticket_age_add value fail.", 0, 0, 0, 0); + return ret; + } + SESS_SetTicketAgeAdd(newSession, hsCtx->ticketAgeAdd); + *sessionPtr = newSession; + return HITLS_SUCCESS; +} + +int32_t Tls13TicketGenerate(TLS_Ctx *ctx) +{ + int32_t ret; + HITLS_Session *newSession = NULL; + HS_Ctx *hsCtx = ctx->hsCtx; + TLS_SessionMgr *sessMgr = ctx->config.tlsConfig.sessMgr; + + uint64_t timeout = SESSMGR_GetTimeout(sessMgr); + /* TLS1.3 timeout period cannot exceed 604800 seconds, that is, seven days. */ + if (timeout > HITLS_ONE_WEEK_SECONDS) { + hsCtx->ticketLifetimeHint = HITLS_ONE_WEEK_SECONDS; + } else { + hsCtx->ticketLifetimeHint = (uint32_t)timeout; + } + + BSL_SAL_FREE(hsCtx->ticket); + hsCtx->ticketSize = 0; + uint8_t resumePsk[MAX_DIGEST_SIZE] = {0}; + uint32_t hashLen = SAL_CRYPT_DigestSize(ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (hashLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint8_t ticketNonce[sizeof(hsCtx->nextTicketNonce)] = {0}; + BSL_Uint64ToByte(hsCtx->nextTicketNonce, ticketNonce); + ret = HS_TLS13DeriveResumePsk(ctx, ticketNonce, sizeof(ticketNonce), resumePsk, hashLen); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE); + return ret; + } + ret = Tls13TicketGenerateConfigSesson(ctx, &newSession, resumePsk, hashLen); + if (ret != HITLS_SUCCESS) { + (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE); + return ret; + } + + ret = SESSMGR_EncryptSessionTicket(sessMgr, newSession, &hsCtx->ticket, &hsCtx->ticketSize); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16051, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Encrypt Session Ticket failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + HITLS_SESS_Free(newSession); + (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE); + return ret; + } + + HITLS_SESS_Free(ctx->session); + ctx->session = newSession; + (void)memset_s(resumePsk, MAX_DIGEST_SIZE, 0, MAX_DIGEST_SIZE); + return HITLS_SUCCESS; +} + +int32_t Tls13SendNewSessionTicketProcess(TLS_Ctx *ctx) +{ + int32_t ret; + HS_Ctx *hsCtx = ctx->hsCtx; + + /** determine whether to assemble a message */ + if (hsCtx->msgLen == 0) { + ret = Tls13TicketGenerate(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* assemble message */ + ret = HS_PackMsg(ctx, NEW_SESSION_TICKET, hsCtx->msgBuf, REC_MAX_PLAIN_LENGTH, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16052, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack new session ticket msg fail.", 0, 0, 0, 0); + return ret; + } + } + + /** After the handshake message is written and sent successfully, hsCtx->msgLen is set to 0. */ + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16053, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send new session ticket msg success.", 0, 0, 0, 0); + + hsCtx->sentTickets++; + hsCtx->nextTicketNonce++; + /* When the value of ticketNums is greater than 0, a ticket is sent after the session is resumed. */ + if (hsCtx->sentTickets >= ctx->config.tlsConfig.ticketNums || ctx->negotiatedInfo.isResume) { + return HS_ChangeState(ctx, TLS_CONNECTED); + } + return HS_ChangeState(ctx, TRY_SEND_NEW_SESSION_TICKET); +} diff --git a/tls/handshake/send/src/send_process.h b/tls/handshake/send/src/send_process.h new file mode 100644 index 00000000..5fc85ec1 --- /dev/null +++ b/tls/handshake/send/src/send_process.h @@ -0,0 +1,293 @@ +/* + * 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 SEND_PROCESS_H +#define SEND_PROCESS_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Send a handshake message + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval HITLS_UNREGISTERED_CALLBACK + * @retval HITLS_CRYPT_ERR_DIGEST hash operation failed + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_MEMALLOC_FAIL Memory allocation failed + * @return For details, see REC_Write + */ +int32_t HS_SendMsg(TLS_Ctx *ctx); + +/** + * @brief Server sends Hello Request messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t ServerSendHelloRequestProcess(TLS_Ctx *ctx); + +/** + * @brief Client sends client hello messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t ClientSendClientHelloProcess(TLS_Ctx *ctx); + +/** + * @brief Server sends server hello messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t ServerSendServerHelloProcess(TLS_Ctx *ctx); + +/** + * @brief send certificate messsage + * @attention The certificates sent by client and server are the same, except for the processing empty certificates + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t SendCertificateProcess(TLS_Ctx *ctx); + +/** + * @brief Server sends server keyExchange messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t ServerSendServerKeyExchangeProcess(TLS_Ctx *ctx); + +/** + * @brief Server sends server certificate request messsage + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t ServerSendCertRequestProcess(TLS_Ctx *ctx); + +/** + * @brief Server sends server hello done message + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t ServerSendServerHelloDoneProcess(TLS_Ctx *ctx); + +/** + * @brief Client sends client key exchange messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t ClientSendClientKeyExchangeProcess(TLS_Ctx *ctx); + +/** + * @brief Client sends client certificate verify messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t ClientSendCertVerifyProcess(TLS_Ctx *ctx); + +/** + * @brief Server sends ccs messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t SendChangeCipherSpecProcess(TLS_Ctx *ctx); + +/** + * @brief Server sends new session messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t SendNewSessionTicketProcess(TLS_Ctx *ctx); + +/** + * @brief TLS1.3 Server sends new session messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ +int32_t Tls13SendNewSessionTicketProcess(TLS_Ctx *ctx); + +int32_t Tls12ClientSendFinishedProcess(TLS_Ctx *ctx); + +int32_t Tls12ServerSendFinishedProcess(TLS_Ctx *ctx); + +/** + * @brief Client sends finished messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsClientSendFinishedProcess(TLS_Ctx *ctx); +#endif + +/** + * @brief Server sends dtls finished messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @return For details, see hitls_error.h + */ + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsServerSendFinishedProcess(TLS_Ctx *ctx); +#endif + +/** + * @brief TLS 1.3 Client sends client hello messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ClientSendClientHelloProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Server sends hello retry request messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ServerSendHelloRetryRequestProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Server sends server hello messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ServerSendServerHelloProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Server sends encrypted extensions messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ServerSendEncryptedExtensionsProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Server sends certificate request messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ServerSendCertRequestProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Client sends certificate messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ClientSendCertificateProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Server sends certificate messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ServerSendCertificateProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 send certificate verify messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13SendCertVerifyProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Server sends finished messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ServerSendFinishedProcess(TLS_Ctx *ctx); + +/** + * @brief TLS 1.3 Client sends finished messsage + * + * @param ctx [IN] TLS context + * + * @retval HITLS_SUCCESS + * @retval For details, see hitls_error.h + */ +int32_t Tls13ClientSendFinishedProcess(TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/handshake/send/src/send_server_hello.c b/tls/handshake/send/src/send_server_hello.c new file mode 100644 index 00000000..2a18ac31 --- /dev/null +++ b/tls/handshake/send/src/send_server_hello.c @@ -0,0 +1,330 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "crypt.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "session_mgr.h" +#include "hs_verify.h" +#include "transcript_hash.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" +#include "hs_kx.h" + +static int32_t ServerPrepareSessionId(TLS_Ctx *ctx) +{ + /* Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + hsCtx->sessionId = (uint8_t *)BSL_SAL_Calloc(1u, HITLS_SESSION_ID_MAX_SIZE); + if (hsCtx->sessionId == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15546, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "session Id malloc fail.", 0, + 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + if (ctx->negotiatedInfo.isResume == false) { + HITLS_SESS_CACHE_MODE sessCacheMode = SESSMGR_GetCacheMode(ctx->config.tlsConfig.sessMgr); + bool needSessionId = (sessCacheMode == HITLS_SESS_CACHE_SERVER || sessCacheMode == HITLS_SESS_CACHE_BOTH) && + (!ctx->negotiatedInfo.isTicket); + if (needSessionId) { + hsCtx->sessionIdSize = HITLS_SESSION_ID_MAX_SIZE; + int32_t ret = SESSMGR_GernerateSessionId(ctx, hsCtx->sessionId, hsCtx->sessionIdSize); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(hsCtx->sessionId); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + } else { + /* If session ID resumption is not supported, the session ID is not sent when the first connection + * is established */ + BSL_SAL_FREE(hsCtx->sessionId); + hsCtx->sessionIdSize = 0; + } + } else { + /* If the session is resumed, obtain the session ID from the session. + * In the session ticket resumption mode, the session ID may not be obtained. Therefore, the return value is + * not checked */ + hsCtx->sessionIdSize = HITLS_SESSION_ID_MAX_SIZE; + HITLS_SESS_GetSessionId(ctx->session, hsCtx->sessionId, &hsCtx->sessionIdSize); + if (hsCtx->sessionIdSize == 0) { + BSL_SAL_FREE(hsCtx->sessionId); + } + } + + return HITLS_SUCCESS; +} + +static int32_t ServerChangeStateAfterSendHello(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + if (ctx->negotiatedInfo.isResume == true) { + ret = HS_ResumeKeyEstablish(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (ctx->negotiatedInfo.isTicket) { + return HS_ChangeState(ctx, TRY_SEND_NEW_SESSION_TICKET); + } + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); + } + /* Check whether the server sends the certificate message. If the server does not need to send the certificate + * message, update the status to the server key exchange */ + if (IsNeedCertPrepare(&ctx->negotiatedInfo.cipherSuiteInfo) == false) { + /* There are multiple possible jumps after the ServerHello in the plain PSK negotiation */ + if (ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_PSK) { + /* Special: If the server does not send the certificate and the plain PSK negotiation mode is used, the + * system determines whether to send the SKE by checking whether the hint exists. There are multiple + * redirection scenarios. */ + /* In the scenario of RSA PSK negotiation, whether SKE messages are sent depends on the existence of hints. + * If RSA is used, the certificate sending phase is entered. The SKE status transition is not performed here + */ + if (ctx->config.tlsConfig.pskIdentityHint != NULL) { + return HS_ChangeState(ctx, TRY_SEND_SERVER_KEY_EXCHANGE); + } + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO_DONE); + } + return HS_ChangeState(ctx, TRY_SEND_SERVER_KEY_EXCHANGE); + } + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE); +} + +static int32_t DowngradeServerRandom(TLS_Ctx *ctx) +{ + /** Obtain server information */ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + uint32_t downgradeRandomLen = 0; + uint32_t offset = 0; + /** Obtain the random part to be rewritten */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS12) { + const uint8_t *downgradeRandom = HS_GetTls12DowngradeRandom(&downgradeRandomLen); + /** Some positions need to be rewritten to obtain random */ + offset = HS_RANDOM_SIZE - downgradeRandomLen; + /** Rewrite the last eight bytes of the random */ + ret = memcpy_s(hsCtx->serverRandom + offset, HS_RANDOM_DOWNGRADE_SIZE, downgradeRandom, downgradeRandomLen); + } + return ret; +} + +int32_t ServerSendServerHelloProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + TLS_Config *tlsConfig = &ctx->config.tlsConfig; + + /** Determine whether to pack a message */ + if (hsCtx->msgLen == 0) { + ret = ServerPrepareSessionId(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SAL_CRYPT_Rand(hsCtx->serverRandom, HS_RANDOM_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15548, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get server random error.", 0, 0, 0, 0); + return ret; + } + /** If TLS 1.3 is supported but an earlier version is negotiated, the last eight bits of the random number need + * to be rewritten */ + if (tlsConfig->maxVersion == HITLS_VERSION_TLS13) { + ret = DowngradeServerRandom(ctx); + if (ret != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15855, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy down grade random fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + } + + /** Set the verify information. */ + ret = VERIFY_SetHash(hsCtx->verifyCtx, ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15549, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "set verify info fail.", + 0, 0, 0, 0); + return ret; + } + + ret = HS_PackMsg(ctx, SERVER_HELLO, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15550, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack server hello msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15551, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, "send server hello msg success.", + 0, 0, 0, 0); + + return ServerChangeStateAfterSendHello(ctx); +} + +static int32_t Tls13ServerPrepareKeyShare(TLS_Ctx *ctx) +{ + KeyShareParam *keyShare = &ctx->hsCtx->kxCtx->keyExchParam.share; + KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx; + if ((kxCtx->peerPubkey == NULL) || /** If the peer public key is empty, keyshare does not need to be packed */ + (kxCtx->key != NULL)) { /** key is not empty, it indicates that the keyshare has been calculated and does not + need to be calculated again */ + return HITLS_SUCCESS; + } + + HITLS_ECParameters curveParams = { + .type = HITLS_EC_CURVE_TYPE_NAMED_CURVE, + .param.namedcurve = keyShare->group, + }; + HITLS_CRYPT_Key *key = NULL; + /* The ecdhe and dhe groups can invoke the same interface to generate keys. */ + key = SAL_CRYPT_GenEcdhKeyPair(&curveParams); + if (key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15552, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "client generate key share key pair error.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + kxCtx->key = key; + + return HITLS_SUCCESS; +} + +int32_t Tls13ServerSendServerHelloProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether to pack a message */ + if (hsCtx->msgLen == 0) { + ret = Tls13ServerPrepareKeyShare(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = SAL_CRYPT_Rand(hsCtx->serverRandom, HS_RANDOM_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15553, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get server random error.", 0, 0, 0, 0); + return ret; + } + + /** Set the verify information */ + ret = VERIFY_SetHash(hsCtx->verifyCtx, ctx->negotiatedInfo.cipherSuiteInfo.hashAlg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15554, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "set verify info fail.", + 0, 0, 0, 0); + return ret; + } + + ret = HS_PackMsg(ctx, SERVER_HELLO, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15555, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 server hello msg fail.", 0, 0, 0, 0); + return ret; + } + /** Server secret derivation */ + ret = HS_TLS13CalcServerHelloProcessSecret(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15561, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Derive-Sevret failed.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_TLS13DeriveHandshakeTrafficSecret(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15556, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 server hello msg success.", 0, 0, 0, 0); + + /** In the middlebox mode, If the scenario is not hrr, the CCS needs to be sent before the EE */ + if (!ctx->hsCtx->haveHrr) { + ctx->hsCtx->ccsNextState = TRY_SEND_ENCRYPTED_EXTENSIONS; + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); + } + return HS_ChangeState(ctx, TRY_SEND_ENCRYPTED_EXTENSIONS); +} + +int32_t Tls13ServerSendHelloRetryRequestProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /** Obtain the server information */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + hsCtx->haveHrr = true; /* update state */ + + /** Check whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + uint32_t hrrRandomLen = 0; + const uint8_t *hrrRandom = HS_GetHrrRandom(&hrrRandomLen); + if (memcpy_s(hsCtx->serverRandom, HS_RANDOM_SIZE, hrrRandom, hrrRandomLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15557, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "copy hello retry request random fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + + /* Pack the message. The hello retry request is assembled in the server hello format */ + ret = HS_PackMsg(ctx, SERVER_HELLO, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15558, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pack tls1.3 hello retry request msg fail.", 0, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15559, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "send tls1.3 hello retry request msg success.", 0, 0, 0, 0); + + /* RFC 8446 4.4.1. Send the Hello Retry Request message and construct the Transcript-Hash data */ + ret = VERIFY_HelloRetryRequestVerifyProcess(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* In middlebox mode, the peer sends CCS messages. Set this parameter to allow receiving CCS messages */ + ctx->method.ctrlCCS(ctx, CCS_CMD_RECV_READY); + /* In middlebox mode, the server sends the CCS immediately after sending the hrr */ + ctx->hsCtx->ccsNextState = TRY_RECV_CLIENT_HELLO; + return HS_ChangeState(ctx, TRY_SEND_CHANGE_CIPHER_SPEC); +} diff --git a/tls/handshake/send/src/send_server_hello_done.c b/tls/handshake/send/src/send_server_hello_done.c new file mode 100644 index 00000000..4ec4e467 --- /dev/null +++ b/tls/handshake/send/src/send_server_hello_done.c @@ -0,0 +1,59 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "tls.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" + + +int32_t ServerSendServerHelloDoneProcess(TLS_Ctx *ctx) +{ + int32_t ret; + /** get the server infomation */ + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** determine whether to assemble a message */ + if (hsCtx->msgLen == 0) { + /* assemble message */ + ret = HS_PackMsg(ctx, SERVER_HELLO_DONE, hsCtx->msgBuf, hsCtx->bufferLen, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15879, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server pack server hello done msg fail.", 0, 0, 0, 0); + return ret; + } + } + + /** writing Handshake message */ + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15880, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send server hello done msg success.", 0, 0, 0, 0); + + /** update the state machine */ + if (hsCtx->isNeedClientCert) { + return HS_ChangeState(ctx, TRY_RECV_CERTIFICATE); + } + return HS_ChangeState(ctx, TRY_RECV_CLIENT_KEY_EXCHANGE); +} diff --git a/tls/handshake/send/src/send_server_key_exchange.c b/tls/handshake/send/src/send_server_key_exchange.c new file mode 100644 index 00000000..d2fb9a2d --- /dev/null +++ b/tls/handshake/send/src/send_server_key_exchange.c @@ -0,0 +1,236 @@ +/* + * 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 "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_crypt_type.h" +#include "hitls_security.h" +#include "tls.h" +#include "security.h" +#include "cert_method.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "pack.h" +#include "send_process.h" + +#define DEFAULT_DHE_PSK_BIT_NUM 128 +#define TLS_DHE_PARAM_MAX_LEN 1024 + +static HITLS_CRYPT_Key *GenerateDhEphemeralKey(HITLS_CRYPT_Key *priKey) +{ + uint8_t p[TLS_DHE_PARAM_MAX_LEN] = {0}; + uint8_t g[TLS_DHE_PARAM_MAX_LEN] = {0}; + uint16_t pLen = TLS_DHE_PARAM_MAX_LEN; + uint16_t gLen = TLS_DHE_PARAM_MAX_LEN; + + int32_t ret = SAL_CRYPT_GetDhParameters(priKey, p, &pLen, g, &gLen); + if (ret != HITLS_SUCCESS) { + return NULL; + } + return SAL_CRYPT_GenerateDhKeyByParams(p, pLen, g, gLen); +} + +static HITLS_CRYPT_Key *GetDhKey(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_Config *config = &ctx->config.tlsConfig; + CERT_MgrCtx *certMgrCtx = config->certMgrCtx; + HITLS_CRYPT_Key *key = NULL; + int32_t secBits = 0; + + if (ctx->config.tlsConfig.isSupportDhAuto) { + KeyExchCtx *keyExCtx = ctx->hsCtx->kxCtx; + CipherSuiteInfo *cipherSuiteInfo = &ctx->negotiatedInfo.cipherSuiteInfo; + HITLS_CERT_X509 *cert = SAL_CERT_GetCurrentCert(certMgrCtx); + + if ((keyExCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE_PSK) || + ((keyExCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE) && (cipherSuiteInfo->authAlg == HITLS_AUTH_NULL))) { + secBits = (SECURITY_GetSecbits(ctx->config.tlsConfig.securityLevel) == 0) + ? DEFAULT_DHE_PSK_BIT_NUM + : SECURITY_GetSecbits(ctx->config.tlsConfig.securityLevel); + } else if (cert != NULL) { + HITLS_CERT_Key *pubkey = NULL; + (void)SAL_CERT_X509Ctrl(config, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey); + ret = SAL_CERT_KeyCtrl(config, pubkey, CERT_KEY_CTRL_GET_SECBITS, NULL, (void *)&secBits); + SAL_CERT_KeyFree(certMgrCtx, pubkey); + if (ret != HITLS_SUCCESS) { + return NULL; + } + } + key = SAL_CRYPT_GenerateDhKeyBySecbits(secBits); + } else { + key = ctx->config.tlsConfig.dhTmp; + if (key != NULL) { + key = GenerateDhEphemeralKey(key); + } + /* Temporary DH security check */ + ret = SAL_CERT_KeyCtrl(config, key, CERT_KEY_CTRL_GET_SECBITS, NULL, (void *)&secBits); + if (ret != HITLS_SUCCESS) { + SAL_CRYPT_FreeDhKey(key); + return NULL; + } + ret = SECURITY_SslCheck((HITLS_Ctx *)ctx, HITLS_SECURITY_SECOP_TMP_DH, secBits, 0, key); + if (ret != SECURITY_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INSUFFICIENT_SECURITY); + SAL_CRYPT_FreeDhKey(key); + return NULL; + } + } + return key; +} + +// Generate the DH cipher suite parameters +static int32_t GenDhCipherSuiteParams(TLS_Ctx *ctx) +{ + HITLS_CRYPT_Key *key = GetDhKey(ctx); + if (key == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_GET_DH_KEY); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15744, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh key error when processing dh cipher suite.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_GET_DH_KEY; + } + + uint8_t p[TLS_DHE_PARAM_MAX_LEN] = {0}; + uint8_t g[TLS_DHE_PARAM_MAX_LEN] = {0}; + uint16_t pLen = TLS_DHE_PARAM_MAX_LEN; + uint16_t gLen = TLS_DHE_PARAM_MAX_LEN; + + /* Get p and g */ + if (SAL_CRYPT_GetDhParameters(key, p, &pLen, g, &gLen) != HITLS_SUCCESS) { + SAL_CRYPT_FreeDhKey(key); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15745, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh parameters error when processing dh cipher suite.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS; + } + ctx->hsCtx->kxCtx->keyExchParam.dh.p = BSL_SAL_Dump(p, pLen); + if (ctx->hsCtx->kxCtx->keyExchParam.dh.p == NULL) { + SAL_CRYPT_FreeDhKey(key); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15334, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh parameters error when processing dh cipher suite.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS; + } + ctx->hsCtx->kxCtx->keyExchParam.dh.g = BSL_SAL_Dump(g, gLen); + if (ctx->hsCtx->kxCtx->keyExchParam.dh.g == NULL) { + BSL_SAL_FREE(ctx->hsCtx->kxCtx->keyExchParam.dh.p); + SAL_CRYPT_FreeDhKey(key); + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15333, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get dh parameters error when processing dh cipher suite.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_ERR_GET_DH_PARAMETERS; + } + ctx->hsCtx->kxCtx->keyExchParam.dh.plen = pLen; + ctx->hsCtx->kxCtx->keyExchParam.dh.glen = gLen; + ctx->hsCtx->kxCtx->key = key; + return HITLS_SUCCESS; +} + +static int32_t PackExchMsgPrepare(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HITLS_CRYPT_Key *key = NULL; + + switch (ctx->hsCtx->kxCtx->keyExchAlgo) { + case HITLS_KEY_EXCH_ECDHE: /** TLCP is included here. */ + case HITLS_KEY_EXCH_ECDHE_PSK: + key = SAL_CRYPT_GenEcdhKeyPair(&ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams); + if (key == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15746, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server generate ecdhe key pair error.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY; + } + ctx->hsCtx->kxCtx->key = key; + break; + case HITLS_KEY_EXCH_DHE: + case HITLS_KEY_EXCH_DHE_PSK: + ret = GenDhCipherSuiteParams(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15747, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "server generate dh key params error.", 0, 0, 0, 0); + return ret; + } + break; + case HITLS_KEY_EXCH_PSK: + case HITLS_KEY_EXCH_RSA_PSK: +#ifndef HITLS_NO_TLCP11 + case HITLS_KEY_EXCH_ECC: +#endif + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15748, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "unsupport kx algorithm when send server kx msg.", 0, 0, 0, 0); + return HITLS_MSG_HANDLE_UNSUPPORT_KX_ALG; + } + + return HITLS_SUCCESS; +} + +int32_t ServerSendServerKeyExchangeProcess(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = (HS_Ctx *)ctx->hsCtx; + + /** Determine whether the message needs to be packed */ + if (hsCtx->msgLen == 0) { + ret = PackExchMsgPrepare(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15941, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Fail to PackExchMsgPrepare, ret = %d.", ret, 0, 0, 0); + return ret; + } + + ret = HS_PackMsg(ctx, SERVER_KEY_EXCHANGE, hsCtx->msgBuf, REC_MAX_PLAIN_LENGTH, &hsCtx->msgLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15749, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Fail to pack Server Key Exchange Message, HS_PackMsg ret = %d", ret, 0, 0, 0); + return ret; + } + } + + ret = HS_SendMsg(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15750, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "server send keyExchange msg success.", 0, 0, 0, 0); + + /** Update the state machine. If the CertificateRequest message does not need to be sent, the system directly + * switches to theSend_SERVER_HELLO_DONE state */ + if (ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_NULL && + ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_PSK && + (ctx->config.tlsConfig.isSupportClientVerify == true) && + (SAL_CERT_GetCurrentCert(ctx->config.tlsConfig.certMgrCtx) != NULL)) { + if (ctx->negotiatedInfo.certReqSendTime < 1 || !(ctx->config.tlsConfig.isSupportClientOnceVerify)) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST); + } + } + /* Make sure the client will always send a certificate message, because ECDHE relies on the client's encrypted + * certificate, even if the client does not require authentication (isSupportClientVerify equals false). */ + +#ifndef HITLS_NO_TLCP11 + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLCP11 && + ctx->negotiatedInfo.cipherSuiteInfo.cipherSuite == HITLS_ECDHE_SM4_CBC_SM3) { + return HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST); + } +#endif + return HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO_DONE); +} \ No newline at end of file diff --git a/tls/handshake/sm/src/hs_init.c b/tls/handshake/sm/src/hs_init.c new file mode 100644 index 00000000..0fba630f --- /dev/null +++ b/tls/handshake/sm/src/hs_init.c @@ -0,0 +1,162 @@ +/* + * 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 "bsl_sal.h" +#include "hitls_error.h" +#include "hitls_sni.h" +#include "bsl_err_internal.h" +#include "indicator.h" +#include "hs_reass.h" +#include "hs_common.h" +#include "hs_verify.h" +#include "hs_kx.h" +#include "hs.h" +#include "parse.h" + +#define EXTRA_DATA_SIZE 128u + +static int32_t UIO_Init(TLS_Ctx *ctx) +{ + if (ctx->bUio != NULL) { + return HITLS_SUCCESS; + } + + BSL_UIO *bUio = BSL_UIO_New(BSL_UIO_BufferMethod()); + if (bUio == NULL) { + return HITLS_MEMALLOC_FAIL; + } + ctx->bUio = bUio; + int32_t ret = BSL_UIO_Append(bUio, ctx->uio); + if (ret != BSL_SUCCESS) { + BSL_UIO_Free(bUio); + ctx->bUio = NULL; + return ret; + } + + ctx->uio = bUio; + return HITLS_SUCCESS; +} + +static int32_t UIO_Deinit(TLS_Ctx *ctx) +{ + if (ctx->bUio == NULL) { + return HITLS_SUCCESS; + } + + ctx->uio = BSL_UIO_PopCurrent(ctx->uio); + BSL_UIO_FreeChain(ctx->bUio); + ctx->bUio = NULL; + + return HITLS_SUCCESS; +} + +static int32_t HsInitChangeState(TLS_Ctx *ctx) +{ + if (ctx->isClient) { + return HS_ChangeState(ctx, TRY_SEND_CLIENT_HELLO); + } + // the server sends a hello request first during renegotiation + if (ctx->negotiatedInfo.isRenegotiation) { + return HS_ChangeState(ctx, TRY_SEND_HELLO_REQUEST); + } + return HS_ChangeState(ctx, TRY_RECV_CLIENT_HELLO); +} + +int32_t HS_Init(TLS_Ctx *ctx) +{ + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + // prevent multiple init in the ctx->hsCtx + if (ctx->hsCtx != NULL) { + return HITLS_SUCCESS; + } + HS_Ctx *hsCtx = (HS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HS_Ctx)); + if (hsCtx == NULL) { + return HITLS_MEMALLOC_FAIL; + } + ctx->hsCtx = hsCtx; + hsCtx->clientRandom = ctx->negotiatedInfo.clientRandom; + hsCtx->serverRandom = ctx->negotiatedInfo.serverRandom; + hsCtx->bufferLen = ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13 ? + REC_MAX_TLS13_ENCRYPTED_LEN : REC_MAX_PLAIN_LENGTH; + hsCtx->msgBuf = BSL_SAL_Malloc(hsCtx->bufferLen); + if (hsCtx->msgBuf == NULL) { + goto exit; + } + if (VERIFY_Init(hsCtx) != HITLS_SUCCESS) { + goto exit; + } + if (ctx->config.tlsConfig.isFlightTransmitEnable == true) { + if (UIO_Init(ctx) != HITLS_SUCCESS) { + goto exit; + } + } + hsCtx->kxCtx = HS_KeyExchCtxNew(); + if (hsCtx->kxCtx == NULL) { + goto exit; + } + hsCtx->firstClientHello = NULL; +#ifndef HITLS_NO_DTLS12 + hsCtx->reassMsg = HS_ReassNew(); + if (hsCtx->reassMsg == NULL) { + goto exit; + } +#endif + INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_HANDSHAKE_START, INDICATE_VALUE_SUCCESS); + return HsInitChangeState(ctx); +exit: + HS_DeInit(ctx); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; +} + +void HS_DeInit(TLS_Ctx *ctx) +{ + if (ctx == NULL || ctx->hsCtx == NULL) { + return; + } + HS_Ctx *hsCtx = ctx->hsCtx; + + BSL_SAL_FREE(hsCtx->msgBuf); + BSL_SAL_FREE(hsCtx->sessionId); + BSL_SAL_FREE(hsCtx->serverName); + BSL_SAL_FREE(hsCtx->ticket); + if (ctx->hsCtx->firstClientHello != NULL) { + HS_Msg hsMsg = {0}; + hsMsg.type = CLIENT_HELLO; + hsMsg.body.clientHello = *ctx->hsCtx->firstClientHello; + HS_CleanMsg(&hsMsg); + BSL_SAL_FREE(ctx->hsCtx->firstClientHello); + } + /* clear sensitive information */ + BSL_SAL_CleanseData(hsCtx->masterKey, MAX_DIGEST_SIZE); + if (hsCtx->peerCert != NULL) { + SAL_CERT_PairFree(ctx->config.tlsConfig.certMgrCtx, hsCtx->peerCert); + hsCtx->peerCert = NULL; + } + + VERIFY_Deinit(hsCtx); + if (ctx->config.tlsConfig.isFlightTransmitEnable == true) { + UIO_Deinit(ctx); + } + HS_KeyExchCtxFree(hsCtx->kxCtx); +#ifndef HITLS_NO_DTLS12 + HS_ReassFree(hsCtx->reassMsg); +#endif + BSL_SAL_FREE(ctx->hsCtx); + return; +} \ No newline at end of file diff --git a/tls/handshake/sm/src/hs_sm.c b/tls/handshake/sm/src/hs_sm.c new file mode 100644 index 00000000..c551d740 --- /dev/null +++ b/tls/handshake/sm/src/hs_sm.c @@ -0,0 +1,527 @@ +/* + * 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 "securec.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "hitls_error.h" +#include "hitls.h" +#include "rec.h" +#include "tls.h" +#include "hs.h" +#include "hs_ctx.h" +#include "hs_common.h" +#include "parse.h" +#include "hs_state_recv.h" +#include "hs_state_send.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "uio_base.h" +#include "indicator.h" +#include "transcript_hash.h" +#include "recv_process.h" + +static int32_t HandshakeDone(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + /* If isFlightTransmitEnable is enabled, the server CCS and Finish information stored in the bUio must be sent after + * the handshake is complete */ + if (ctx->config.tlsConfig.isFlightTransmitEnable) { + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL); + if (ret == BSL_UIO_IO_BUSY) { + return HITLS_REC_NORMAL_IO_BUSY; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15959, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "fail to send the CCS and Finish message of server in bUio.", 0, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + } + +#ifndef HITLS_NO_DTLS12 + if (BSL_UIO_GetTransportType(ctx->uio) != BSL_UIO_SCTP) { + return HITLS_SUCCESS; + } + + bool isBuffEmpty = false; + ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_SND_BUFF_IS_EMPTY, (int32_t)sizeof(isBuffEmpty), &isBuffEmpty); + if (ret != BSL_SUCCESS) { + return HITLS_UIO_SCTP_IS_SND_BUF_EMPTY_FAIL; + } + + if (isBuffEmpty != true) { + return HITLS_REC_NORMAL_IO_BUSY; + } + + ret = HS_ActiveSctpAuthKey(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = HS_DeletePreviousSctpAuthKey(ctx); +#endif + + return ret; +} + +static bool IsHsSendState(HITLS_HandshakeState state) +{ + switch (state) { + case TRY_SEND_HELLO_REQUEST: + case TRY_SEND_CLIENT_HELLO: + case TRY_SEND_HELLO_RETRY_REQUEST: + case TRY_SEND_SERVER_HELLO: + case TRY_SEND_ENCRYPTED_EXTENSIONS: + case TRY_SEND_CERTIFICATE: + case TRY_SEND_SERVER_KEY_EXCHANGE: + case TRY_SEND_CERTIFICATE_REQUEST: + case TRY_SEND_SERVER_HELLO_DONE: + case TRY_SEND_CLIENT_KEY_EXCHANGE: + case TRY_SEND_CERTIFICATE_VERIFY: + case TRY_SEND_NEW_SESSION_TICKET: + case TRY_SEND_CHANGE_CIPHER_SPEC: + case TRY_SEND_END_OF_EARLY_DATA: + case TRY_SEND_FINISH: + return true; + default: + break; + } + + return false; +} + +static bool IsHsRecvState(HITLS_HandshakeState state) +{ + switch (state) { + case TRY_RECV_CLIENT_HELLO: + case TRY_RECV_SERVER_HELLO: + case TRY_RECV_ENCRYPTED_EXTENSIONS: + case TRY_RECV_CERTIFICATE: + case TRY_RECV_SERVER_KEY_EXCHANGE: + case TRY_RECV_CERTIFICATE_REQUEST: + case TRY_RECV_SERVER_HELLO_DONE: + case TRY_RECV_CLIENT_KEY_EXCHANGE: + case TRY_RECV_CERTIFICATE_VERIFY: + case TRY_RECV_NEW_SESSION_TICKET: + case TRY_RECV_END_OF_EARLY_DATA: + case TRY_RECV_FINISH: + return true; + default: + break; + } + + return false; +} + +int32_t HS_DoHandshake(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_SUCCESS; + HS_Ctx *hsCtx = ctx->hsCtx; + int32_t eventType = (ctx->isClient) ? INDICATE_EVENT_STATE_CONNECT_EXIT : INDICATE_EVENT_STATE_ACCEPT_EXIT; + + while (hsCtx->state != TLS_CONNECTED) { + if (IsHsSendState(hsCtx->state)) { + ret = HS_SendMsgProcess(ctx); + } else if (IsHsRecvState(hsCtx->state)) { + ret = HS_RecvMsgProcess(ctx); + } else { + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_STATE_ILLEGAL); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15884, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Handshake state unable to process, current state is %s.", HS_GetStateStr(hsCtx->state)); + ret = HITLS_MSG_HANDLE_STATE_ILLEGAL; + } + + if (ret != HITLS_SUCCESS) { + INDICATOR_StatusIndicate(ctx, eventType, ret); + return ret; + } + } + + INDICATOR_StatusIndicate(ctx, INDICATE_EVENT_HANDSHAKE_DONE, INDICATE_VALUE_SUCCESS); + + ret = HandshakeDone(ctx); + if (ret != HITLS_SUCCESS) { + INDICATOR_StatusIndicate(ctx, eventType, ret); + return ret; + } + + INDICATOR_StatusIndicate(ctx, eventType, INDICATE_VALUE_SUCCESS); + return HITLS_SUCCESS; +} + +int32_t HS_CheckKeyUpdateState(const TLS_Ctx *ctx, uint32_t updateType) +{ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + + if (ctx->state != CM_STATE_TRANSPORTING) { + return HITLS_MSG_HANDLE_STATE_ILLEGAL; + } + + if (updateType != HITLS_UPDATE_REQUESTED && updateType != HITLS_UPDATE_NOT_REQUESTED) { + return HITLS_MSG_HANDLE_ILLEGAL_KEY_UPDATE_TYPE; + } + + return HITLS_SUCCESS; +} + +int32_t HS_SendKeyUpdate(TLS_Ctx *ctx) +{ + // Pack and send the KeyUpdate message and update the application traffic secret used for sending the message + int32_t ret = HS_HandleSendKeyUpdate(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ctx->isKeyUpdateRequest = false; + ctx->keyUpdateType = HITLS_KEY_UPDATE_REQ_END; + return HITLS_SUCCESS; +} + +static int32_t RecvKeyUpdateMsgProcess(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo) +{ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNSUPPORT_VERSION; + } + + if (ctx->state != CM_STATE_TRANSPORTING) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + } + + HS_Msg hsMsg = {0}; + // Parsing and updating the app traffic secret used by the local + int32_t ret = HS_HandleRecvKeyUpdate(ctx, hsMsgInfo, &hsMsg); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + + /* Upon request for a received key update of the type UPDATE_REQUESTED, + * Set the key update type for the local context to UPDATE_NOT_REQUESTED, + * Then, the key update message is sent to the peer to update the traffic secret used by the local + */ + if (hsMsg.body.keyUpdate.requestUpdate == HITLS_UPDATE_REQUESTED) { + ctx->isKeyUpdateRequest = true; + ctx->keyUpdateType = HITLS_UPDATE_NOT_REQUESTED; + ret = HS_SendKeyUpdate(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + return HITLS_SUCCESS; +} + +static int32_t RecvCertificateRequest(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo, CM_State *state) +{ + if (ctx->state != CM_STATE_TRANSPORTING || ctx->phaState != PHA_EXTENSION || !ctx->isClient || + ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + } + + int32_t ret = HS_Init(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15341, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HS_Init fail when recv certificate request.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + SAL_CRYPT_DigestFree(ctx->hsCtx->verifyCtx->hashCtx); + ctx->hsCtx->verifyCtx->hashCtx = SAL_CRYPT_DigestCopy(ctx->phaHash); + if (ctx->hsCtx->verifyCtx->hashCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15368, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pha hash copy error: digest copy fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_DIGEST; + } + + HS_Msg hsMsg = {0}; + ret = HS_ParseMsg(ctx, hsMsgInfo, &hsMsg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15342, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse tls1.3 key update msg fail.", 0, 0, 0, 0); + HS_CleanMsg(&hsMsg); + return ret; + } + ret = VERIFY_Append(ctx->hsCtx->verifyCtx, hsMsgInfo->rawMsg, hsMsgInfo->headerAndBodyLen); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + ctx->phaState = PHA_REQUESTED; + HS_ChangeState(ctx, TRY_RECV_CERTIFICATE_REQUEST); + ret = Tls13ClientRecvCertRequestProcess(ctx, &hsMsg); + HS_CleanMsg(&hsMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + *state = CM_STATE_HANDSHAKING; + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; +} + +static int32_t RecvCertificate(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo, CM_State *state) +{ + if (ctx->state != CM_STATE_TRANSPORTING || ctx->phaState != PHA_REQUESTED || + ctx->isClient || ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + } + + int32_t ret = HS_Init(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15340, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HS_Init fail when recv certificate.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + ctx->hsCtx->verifyCtx->hashCtx = ctx->phaCurHash; + ctx->phaCurHash = NULL; + + HS_Msg hsMsg = {0}; + ret = HS_ParseMsg(ctx, hsMsgInfo, &hsMsg); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15344, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "parse tls1.3 key update msg fail.", 0, 0, 0, 0); + HS_CleanMsg(&hsMsg); + return ret; + } + ret = VERIFY_Append(ctx->hsCtx->verifyCtx, hsMsgInfo->rawMsg, hsMsgInfo->headerAndBodyLen); + if (ret != HITLS_SUCCESS) { + HS_CleanMsg(&hsMsg); + return ret; + } + HS_ChangeState(ctx, TRY_RECV_CERTIFICATE); + ret = Tls13RecvCertificateProcess(ctx, &hsMsg); + HS_CleanMsg(&hsMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + *state = CM_STATE_HANDSHAKING; + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; +} + +static int32_t RecvRenegotiationReqProcess(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo, CM_State *state) +{ + /* If the version is TLS1.3, ignore the message */ + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + + /* If the message is not a renegotiation request, ignore the message */ + if ((ctx->isClient && (hsMsgInfo->type == CLIENT_HELLO)) || + (!ctx->isClient && (hsMsgInfo->type == HELLO_REQUEST))) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + + /* Renegotiation request is processed only after security renegotiation is negotiated. Otherwise, no renegotiation + * alarm is generated and the peer determines whether to disconnect the link */ + if (!ctx->negotiatedInfo.isSecureRenegotiation || !ctx->config.tlsConfig.isSupportRenegotiation) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_WARNING, ALERT_NO_RENEGOTIATION); + return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG; + } + + if (ctx->hsCtx != NULL) { + HS_DeInit(ctx); + } + int32_t ret = HS_Init(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15976, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HS_Init fail when recv renegotiation request.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + return ret; + } + + ret = HS_HandleRecvRenegoReq(ctx, hsMsgInfo); + if (ret != HITLS_SUCCESS) { + HS_DeInit(ctx); + return ret; + } + + *state = CM_STATE_RENEGOTIATION; + ctx->negotiatedInfo.isRenegotiation = true; /* Start renegotiation */ + ctx->negotiatedInfo.renegotiationNum++; + return HITLS_SUCCESS; +} + +static int32_t HsInitMsgBuf(TLS_Ctx *ctx) +{ + HS_Ctx *hsCtx = (HS_Ctx *)BSL_SAL_Calloc(1u, sizeof(HS_Ctx)); + if (hsCtx == NULL) { + return HITLS_MEMALLOC_FAIL; + } + ctx->hsCtx = hsCtx; + hsCtx->bufferLen = REC_MAX_PLAIN_LENGTH; + hsCtx->msgBuf = BSL_SAL_Malloc(hsCtx->bufferLen); + if (hsCtx->msgBuf == NULL) { + return HITLS_MEMALLOC_FAIL; + } + return HITLS_SUCCESS; +} + +static int32_t DealUnexpectedMsgWrtType(TLS_Ctx *ctx, HS_MsgInfo *hsMsgInfo, CM_State *state) +{ + uint8_t *rawMsg = BSL_SAL_Malloc(ctx->hsCtx->bufferLen); + if (rawMsg == NULL) { + HS_DeInit(ctx); + return HITLS_MEMALLOC_FAIL; + } + if (memcpy_s(rawMsg, ctx->hsCtx->bufferLen, hsMsgInfo->rawMsg, hsMsgInfo->headerAndBodyLen) != EOK) { + HS_DeInit(ctx); + BSL_SAL_Free(rawMsg); + return HITLS_MEMCPY_FAIL; + } + hsMsgInfo->rawMsg = rawMsg; + HS_DeInit(ctx); + int32_t ret = 0; + switch (hsMsgInfo->type) { + case HELLO_REQUEST: + case CLIENT_HELLO: + ret = RecvRenegotiationReqProcess(ctx, hsMsgInfo, state); + break; + case KEY_UPDATE: + ret = RecvKeyUpdateMsgProcess(ctx, hsMsgInfo); + break; + case CERTIFICATE_REQUEST: + ret = RecvCertificateRequest(ctx, hsMsgInfo, state); + break; + case CERTIFICATE: + ret = RecvCertificate(ctx, hsMsgInfo, state); + break; + case NEW_SESSION_TICKET: + /* If the version is not TLS1.3, ignore the message */ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + break; + } + ret = HS_HandleTLS13NewSessionTicket(ctx, hsMsgInfo); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE); + BSL_LOG_BINLOG_VARLEN(BINLOG_ID15841, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Unexpected %s handshake state message.", HS_GetMsgTypeStr(hsMsgInfo->type)); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + ret = HITLS_MSG_HANDLE_UNEXPECTED_MESSAGE; + } + BSL_SAL_Free(rawMsg); + return ret; +} + +int32_t HS_RecvUnexpectedMsgProcess(TLS_Ctx *ctx, const uint8_t *data, uint32_t len, CM_State *state) +{ + int32_t ret = HITLS_SUCCESS; + HS_MsgInfo hsMsgInfo = { 0 }; + uint32_t headerLen = IS_DTLS_VERSION(ctx->negotiatedInfo.version) ? DTLS_HS_MSG_HEADER_SIZE : HS_MSG_HEADER_SIZE; + +#ifndef HITLS_NO_DTLS12 + if (data[0] == FINISHED && IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + ret = HS_ParseMsgHeader(ctx, data, len, &hsMsgInfo); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; + } +#endif + + if (ctx->hsCtx != NULL) { + HS_DeInit(ctx); + } + ret = HsInitMsgBuf(ctx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15977, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "HS_Init fail when recv renegotiation request.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + HS_DeInit(ctx); + return ret; + } + HS_Ctx *hsCtx = ctx->hsCtx; + if (memcpy_s(ctx->hsCtx->msgBuf, ctx->hsCtx->bufferLen, data, len) != EOK) { + HS_DeInit(ctx); + return HITLS_MEMCPY_FAIL; + } + uint32_t readbytes = len; + if (readbytes < headerLen) { + ret = REC_TlsReadNbytes(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf + readbytes, headerLen - readbytes); + if (ret != HITLS_SUCCESS) { + HS_DeInit(ctx); + return ret; + } + readbytes = headerLen; + } + ret = HS_ParseMsgHeader(ctx, hsCtx->msgBuf, readbytes, &hsMsgInfo); + if (ret != HITLS_SUCCESS) { + HS_DeInit(ctx); + return ret; + } + ctx->hasParsedHsMsgHeader = true; + if (readbytes < hsMsgInfo.headerAndBodyLen) { + ret = REC_TlsReadNbytes(ctx, REC_TYPE_HANDSHAKE, hsCtx->msgBuf + readbytes, + hsMsgInfo.headerAndBodyLen - readbytes); + if (ret != HITLS_SUCCESS) { + HS_DeInit(ctx); + return ret; + } + } + + return DealUnexpectedMsgWrtType(ctx, &hsMsgInfo, state); +} + +bool HS_IsAppDataAllowed(TLS_Ctx *ctx) +{ + /* If the negotiated version is 0, it indicates that the handshake is the first time. In this case, an alert message + * needs to be sent when the unexpected app message is received */ + if (ctx->negotiatedInfo.version == 0u || ctx->negotiatedInfo.renegotiationNum == 0) { + return false; + } + + /* App messages can be received before the server hello message is sent or received */ + uint32_t hsState = HS_GetState(ctx); + if (ctx->isClient) { + if (hsState == TRY_RECV_SERVER_HELLO) { + return true; + } + } else { + if (hsState == TRY_RECV_CLIENT_HELLO) { + return true; + } + } + return false; +} + +int32_t HS_CheckPostHandshakeAuth(TLS_Ctx *ctx) +{ + int32_t ret = HS_Init(ctx); + if (ret != HITLS_SUCCESS) { + return ret; + } + HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST); + SAL_CRYPT_DigestFree(ctx->hsCtx->verifyCtx->hashCtx); + ctx->hsCtx->verifyCtx->hashCtx = SAL_CRYPT_DigestCopy(ctx->phaHash); + if (ctx->hsCtx->verifyCtx->hashCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15369, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "pha hash copy error: digest copy fail.", 0, 0, 0, 0); + return HITLS_CRYPT_ERR_DIGEST; + } + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/include/alpn.h b/tls/include/alpn.h new file mode 100644 index 00000000..895e554b --- /dev/null +++ b/tls/include/alpn.h @@ -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. + */ + +#ifndef ALPN_H +#define ALPN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t ALPN_SelectProtocol(uint8_t **out, uint32_t *outLen, uint8_t *clientAlpnList, uint32_t clientAlpnListLen, + uint8_t *servAlpnList, uint32_t servAlpnListLen); + +#ifdef __cplusplus +} +#endif +#endif // ALPN_H \ No newline at end of file diff --git a/tls/include/cipher_suite.h b/tls/include/cipher_suite.h new file mode 100644 index 00000000..72160c8e --- /dev/null +++ b/tls/include/cipher_suite.h @@ -0,0 +1,211 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef CIPHER_SUITE_H +#define CIPHER_SUITE_H + +#include +#include +#include "hitls_config.h" +#include "hitls_crypt_type.h" +#include "hitls_cert_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00ffu /* renegotiation cipher suite */ + +/* cert request Type of the certificate requested */ +typedef enum { + /* rfc5246 7.4.4 */ + CERT_TYPE_RSA_SIGN = 1, + CERT_TYPE_DSS_SIGN = 2, + CERT_TYPE_RSA_FIXED_DH = 3, + CERT_TYPE_DSS_FIXED_DH = 4, + /* rfc8422 5.5 */ + CERT_TYPE_ECDSA_SIGN = 64, + CERT_TYPE_SM2_SIGN = 64, + CERT_TYPE_UNKNOWN = 255 +} CERT_Type; + +/** + * CipherSuiteInfo structure, used to transfer public cipher suite information. + */ +typedef struct TlsCipherSuiteInfo { + bool enable; /**< Enable flag */ + const char *name; /**< Cipher suite name */ + const char *stdName; /**< RFC name of the cipher suite */ + uint16_t cipherSuite; /**< cipher suite */ + + /* algorithm type */ + HITLS_CipherAlgo cipherAlg; /**< Symmetric-key algorithm */ + HITLS_KeyExchAlgo kxAlg; /**< key exchange algorithm */ + HITLS_AuthAlgo authAlg; /**< server authorization algorithm */ + HITLS_MacAlgo macAlg; /**< mac algorithm */ + HITLS_HashAlgo hashAlg; /**< hash algorithm */ + + /** + * Signature combination, including the hash algorithm and signature algorithm: + * TLS 1.2 negotiates the signScheme. + */ + HITLS_SignHashAlgo signScheme; + + /* key length */ + uint8_t fixedIvLength; /**< If the AEAD algorithm is used, the value is the implicit IV length */ + uint8_t encKeyLen; /**< Length of the symmetric key */ + uint8_t macKeyLen; /**< If the AEAD algorithm is used, the MAC key length is 0 */ + + /* result length */ + uint8_t blockLength; /**< If the block length is not zero, the alignment should be handled */ + uint8_t recordIvLength; /**< The explicit IV needs to be sent to the peer end */ + uint8_t macLen; /**< The length of the MAC address. If the AEAD algorithm is used, this member variable + * will be the length of the tag */ + + uint16_t minVersion; /**< Minimum version supported by the cipher suite */ + uint16_t maxVersion; /**< Maximum version supported by the cipher suite */ + uint16_t minDtlsVersion; /**< Minimum DTLS version supported by the cipher suite */ + uint16_t maxDtlsVersion; /**< Maximum DTLS version supported by the cipher suite */ + HITLS_CipherType cipherType; /**< Encryption algorithm type */ + int32_t strengthBits; /**< Encryption algorithm strength */ +} CipherSuiteInfo; + +/** + * SignSchemeInfo structure, used to transfer the signature algorithm information. + */ +typedef struct { + HITLS_SignHashAlgo scheme; /**< Signature hash algorithm */ + HITLS_SignAlgo signAlg; /**< Signature algorithm */ + HITLS_HashAlgo hashAlg; /**< hash algorithm */ +} SignSchemeInfo; + +typedef struct { + HITLS_SignHashAlgo scheme; /**< signature algorithm */ + HITLS_NamedGroup cureName; /**< public key curve name (ECDSA only) */ +} EcdsaCurveInfo; + +/** + * Mapping between cipher suites and certificate types + */ +typedef struct { + uint16_t cipherSuite; /**< cipher suite */ + CERT_Type certType; /**< Certificate type */ +} CipherSuiteCertType; + +/** + * @brief Obtain the list of supported signature hash algorithms. + * + * @param len [OUT] Return the length of the signature hash algorithm list. + * + * @return Pointer to the signature hash algorithm list + */ +const SignSchemeInfo *CFG_GetSignSchemeList(uint32_t *len); + +/** + * @brief Obtain the list of supported signature hash algorithms for TLCP. + * + * @param len [OUT] Return the length of the signature hash algorithm list. + * + * @return Pointer to the signature hash algorithm list + */ +const SignSchemeInfo *CFG_GetSignSchemeListTlcp(uint32_t *len); + +/** + * @brief Obtain the algorithm suite based on the specified information. + * + * @param version [IN] TLS version + * @param kxAlgo [IN] Key exchange algorithm + * @param authAlgo [IN] Authentication algorithm + * @param cipherAlgo [IN] Symmetric-key algorithm + * @param hashAlgo [IN] Hash algorithm + * + * @return cipher suite ID + */ +uint16_t CFG_GetCipherSuite(uint16_t version, HITLS_KeyExchAlgo kxAlgo, HITLS_AuthAlgo authAlgo, + HITLS_CipherAlgo cipherAlgo, HITLS_HashAlgo hashAlgo); + +/** + * @brief Obtain the cipher suite information. + * + * @param cipherSuite [IN] Cipher suite of the information to be obtained + * @param cipherInfo [OUT] Cipher suite information + * + * @retval HITLS_SUCCESS obtained successfully. + * @retval HITLS_INTERNAL_EXCEPTION An unexpected internal error. + * @retval HITLS_MEMCPY_FAIL memcpy_s failed to be executed. + * @retval HITLS_CONFIG_UNSUPPORT_CIPHER_SUITE No information about the cipher suite is found. + */ +int32_t CFG_GetCipherSuiteInfo(uint16_t cipherSuite, CipherSuiteInfo *cipherInfo); + +/** + * @brief Check whether the input cipher suite is supported. + * + * @param cipherSuite [IN] cipher suite to be checked + * + * @retval true Supported + * @retval false Not supported + */ +bool CFG_CheckCipherSuiteSupported(uint16_t cipherSuite); + +/** + * @brief Check whether the input cipher suite complies with the version. + * + * @param cipherSuite [IN] cipher suite to be checked + * @param minVersion [IN] Indicates the earliest version of the cipher suite. + * @param maxVersion [IN] Indicates the latest version of the cipher suite. + * + * @retval true Supported + * @retval false Not supported + */ +bool CFG_CheckCipherSuiteVersion(uint16_t cipherSuite, uint16_t minVersion, uint16_t maxVersion); + +/** + * @brief Obtain the signature algorithm and hash algorithm by combining the parameters of + * the signature hash algorithm. + * @param version [IN] Secure communication version + * @param scheme [IN] Signature and hash algorithm combination + * @param signAlg [OUT] Signature algorithm + * @param hashAlg [OUT] Hash algorithm + * + * @retval true Obtained successfully. + * @retval false Obtaining failed. + */ +bool CFG_GetSignParamBySchemes(uint16_t version, HITLS_SignHashAlgo scheme, HITLS_SignAlgo *signAlg, + HITLS_HashAlgo *hashAlg); + +/** + * @brief Obtain the certificate type based on the cipher suite. + * + * @param cipherSuite [IN] Cipher suite + * + * @retval Certificate type corresponding to the cipher suite + */ +uint8_t CFG_GetCertTypeByCipherSuite(uint16_t cipherSuite); + + +/** + * @brief get the group name of the ecdsa + * + * @param scheme [IN] signature algorithm + * + * @retval group name + */ +HITLS_NamedGroup CFG_GetEcdsaCurveNameBySchemes(HITLS_SignHashAlgo scheme); + +#ifdef __cplusplus +} +#endif + +#endif // CIPHER_SUITE_H diff --git a/tls/include/indicator.h b/tls/include/indicator.h new file mode 100644 index 00000000..3b96ad66 --- /dev/null +++ b/tls/include/indicator.h @@ -0,0 +1,56 @@ +/* + * 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 INDICATOR_H +#define INDICATOR_H + +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INDICATOR_ALERT_LEVEL_OFFSET 8 + +#define INDICATE_INFO_STATE_MASK 0x0FFF // 0000 1111 1111 1111 + +/** + * @ingroup indicator + * @brief Indicate the status or event to the upper layer through the infoCb + * @param ctx [IN] TLS context + * @param eventType [IN] + * @param value [IN] Return value of a function in the event or alert type + */ +void INDICATOR_StatusIndicate(const HITLS_Ctx *ctx, int32_t eventType, int32_t value); + +/** + * @ingroup indicator + * @brief Indicate the status or event to the upper layer through msgCb + * @param writePoint [IN] Message direction in the callback ">>>" or "<<<" + * @param tlsVersion [IN] TLS version + * @param contentType[IN] Type of the message to be processed. + * @param msg [IN] Internal message processing instruction data in callback + * @param msgLen [IN] Data length of the processing instruction + * @param ctx [IN] HITLS context + * @param arg [IN] User data such as BIO + */ +void INDICATOR_MessageIndicate(int32_t writePoint, uint32_t tlsVersion, int32_t contentType, const void *msg, + uint32_t msgLen, HITLS_Ctx *ctx, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // INDICATOR_H \ No newline at end of file diff --git a/tls/include/security.h b/tls/include/security.h new file mode 100644 index 00000000..f97586ef --- /dev/null +++ b/tls/include/security.h @@ -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. + */ + +#ifndef SECURITY_H +#define SECURITY_H + +#include +#include "hitls_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SECURITY_SUCCESS 1 +#define SECURITY_ERR 0 + +/* set the default security level and security callback function */ +void SECURITY_SetDefault(HITLS_Config *config); + +/* check TLS configuration security */ +int32_t SECURITY_CfgCheck(HITLS_Config *config, int32_t option, int32_t bits, int32_t id, void *other); + +/* check TLS link security */ +int32_t SECURITY_SslCheck(HITLS_Ctx *ctx, int32_t option, int32_t bits, int32_t id, void *other); + +/* get the security strength corresponding to the security level */ +int32_t SECURITY_GetSecbits(int32_t level); + +#ifdef __cplusplus +} +#endif + +#endif // SECURITY_H \ No newline at end of file diff --git a/tls/include/session.h b/tls/include/session.h new file mode 100644 index 00000000..d5c63558 --- /dev/null +++ b/tls/include/session.h @@ -0,0 +1,76 @@ +/* + * 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 SESSION_H +#define SESSION_H + +#include +#include +#include "sal_time.h" +#include "hitls_session.h" +#include "cert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_MASTER_KEY_SIZE 256u /* <= tls1.2 master key is 48 bytes. TLS1.3 can be to 256 bytes. */ + +/* Increments the reference count for session */ +void HITLS_SESS_UpRef(HITLS_Session *sess); + +/* Deep copy session */ +HITLS_Session *SESS_Copy(HITLS_Session *src); + +/* Disable session */ +void SESS_Disable(HITLS_Session *sess); + +/* set peerCert */ +int32_t SESS_SetPeerCert(HITLS_Session *sess, CERT_Pair *peerCert, bool isClient); + +/* get peerCert */ +int32_t SESS_GetPeerCert(HITLS_Session *sess, CERT_Pair **peerCert); + +/* set ticket */ +int32_t SESS_SetTicket(HITLS_Session *sess, uint8_t *ticket, uint32_t ticketSize); + +/* get ticket */ +int32_t SESS_GetTicket(const HITLS_Session *sess, uint8_t **ticket, uint32_t *ticketSize); + +/* set hostName */ +int32_t SESS_SetHostName(HITLS_Session *sess, uint32_t hostNameSize, uint8_t *hostName); + +/* get hostName */ +int32_t SESS_GetHostName(HITLS_Session *sess, uint32_t *hostNameSize, uint8_t **hostName); + +/* Check the validity of the session */ +bool SESS_CheckValidity(HITLS_Session *sess, uint64_t curTime); + +/* tls1.3 Checking the Validity of Client Sessions and ObfuscatedTicketAge */ +bool SESS_CheckObfuscatedTicketAge(HITLS_Session *sess, uint64_t curTime, uint64_t obfuscatedTicketAge); + +uint64_t SESS_GetStartTime(HITLS_Session *sess); + +int32_t SESS_SetStartTime(HITLS_Session *sess, uint64_t startTime); + +int32_t SESS_SetTicketAgeAdd(HITLS_Session *sess, uint32_t ticketAgeAdd); + +uint32_t SESS_GetTicketAgeAdd(const HITLS_Session *sess); + +#ifdef __cplusplus +} +#endif + +#endif // SESSION_H diff --git a/tls/include/session_mgr.h b/tls/include/session_mgr.h new file mode 100644 index 00000000..d5fc3ac9 --- /dev/null +++ b/tls/include/session_mgr.h @@ -0,0 +1,151 @@ +/* + * 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 SESSION_MGR_H +#define SESSION_MGR_H + +#include +#include +#include "hitls.h" +#include "tls.h" +#include "session.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application */ +TLS_SessionMgr *SESSMGR_New(void); + +/* Copy the number of references and increase the number of references by 1 */ +TLS_SessionMgr *SESSMGR_Dup(TLS_SessionMgr *mgr); + +/* Release */ +void SESSMGR_Free(TLS_SessionMgr *mgr); + +/* Configure the timeout period */ +void SESSMGR_SetTimeout(TLS_SessionMgr *mgr, uint64_t sessTimeout); + +/* Obtain the timeout configuration */ +uint64_t SESSMGR_GetTimeout(TLS_SessionMgr *mgr); + +/* Set the mode */ +void SESSMGR_SetCacheMode(TLS_SessionMgr *mgr, HITLS_SESS_CACHE_MODE mode); + +/* Set the mode: Ensure that the pointer is not null */ +HITLS_SESS_CACHE_MODE SESSMGR_GetCacheMode(TLS_SessionMgr *mgr); + +/* Set the maximum number of cache sessions */ +void SESSMGR_SetCacheSize(TLS_SessionMgr *mgr, uint32_t sessCacheSize); + +/* Set the maximum number of cached sessions. Ensure that the pointer is not null */ +uint32_t SESSMGR_GetCacheSize(TLS_SessionMgr *mgr); + +/* add */ +void SESSMGR_InsertSession(TLS_SessionMgr *mgr, HITLS_Session *sess, bool isClient); + +/* Find the matching session and verify the validity of the session (time) */ +HITLS_Session *SESSMGR_Find(TLS_SessionMgr *mgr, uint8_t *sessionId, uint8_t sessionIdSize); + +/* Search for the matching session without checking the validity of the session (time) */ +bool SESSMGR_HasMacthSessionId(TLS_SessionMgr *mgr, uint8_t *sessionId, uint8_t sessionIdSize); + +/* Clear timeout sessions */ +void SESSMGR_ClearTimeout(TLS_SessionMgr *mgr); + +/* Generate session IDs to prevent duplicate session IDs */ +int32_t SESSMGR_GernerateSessionId(TLS_Ctx *ctx, uint8_t *sessionId, uint32_t sessionIdSize); + +void SESSMGR_SetTicketKeyCb(TLS_SessionMgr *mgr, HITLS_TicketKeyCb ticketKeyCb); + +HITLS_TicketKeyCb SESSMGR_GetTicketKeyCb(TLS_SessionMgr *mgr); + +/** + * @brief Obtain the default ticket key of the HITLS. The key is used to encrypt and decrypt the ticket + * in the new session ticket when the HITLS_TicketKeyCb callback function is not set. + * + * @attention The returned key value is as follows: 16-bytes key name + 32-bytes AES key + 32-bytes HMAC key + * + * @param mgr [IN] Session management context + * @param key [OUT] Obtained ticket key + * @param keySize [IN] Size of the key array + * @param outSize [OUT] Size of the obtained ticket key + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t SESSMGR_GetTicketKey(const TLS_SessionMgr *mgr, uint8_t *key, uint32_t keySize, uint32_t *outSize); + +/** + * @brief Set the default ticket key of the HITLS. The key is used to encrypt and decrypt tickets + * in the new session ticket when the HITLS_TicketKeyCb callback function is not set. + * + * @attention The returned key value is as follows: 16-bytes key name + 32-bytes AES key + 32-bytes HMAC key + * + * @param mgr [OUT] Session management context + * @param key [IN] Ticket key to be set + * @param keySize [IN] Size of the ticket key + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t SESSMGR_SetTicketKey(TLS_SessionMgr *mgr, const uint8_t *key, uint32_t keySize); + +/** + * @brief Encrypt the session ticket, which is invoked when a new session ticket is sent + * + * @param sessMgr [IN] Session management context + * @param sess [IN] sess structure, used to generate ticket data + * @param ticketBuf [OUT] ticket. The return value may be empty, that is, an empty new session ticket message is sent + * @param ticketBufSize [IN] Size of the ticketBuf + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t SESSMGR_EncryptSessionTicket(const TLS_SessionMgr *sessMgr, const HITLS_Session *sess, uint8_t **ticketBuf, + uint32_t *ticketBufSize); + +/** + * @brief Decrypt the session ticket. This interface is invoked when the session ticket of the clientHello is received + * + * @attention The output parameters are as follows: + * If the sess field is empty and the ticketExcept field is set to true, the new session ticket message + * is sent but the session is not resumed + * If the sess field is empty and the ticketExcept field is false, the session is not resumed + * and the new session ticket message is not sent + * If sess is not empty and ticketExcept is true, the session is resumed and + * a new session ticket message is sent, which means the session ticket is renewed + * If sess is not empty and ticketExcept is false, + * the session is resumed and the new session ticket message is not sent + * + * @param sessMgr [IN] Session management context + * @param sess [OUT] Session structure generated by the ticket. The return value may be empty, + * so that, the corresponding session cannot be generated and the session cannot be resumed + * @param ticketBuf [IN] ticket data + * @param ticketBufSize [IN] Ticket data size + * @param isTicketExcept [OUT] Indicates whether to send a new session ticket. + * The options are as follows: true: yes; false: no. + * + * @retval HITLS_SUCCESS + * @retval For other error codes, see hitls_error.h + */ +int32_t SESSMGR_DecryptSessionTicket(const TLS_SessionMgr *sessMgr, HITLS_Session **sess, const uint8_t *ticketBuf, + uint32_t ticketBufSize, bool *isTicketExcept); + +#ifdef __cplusplus +} +#endif + +#endif // SESSION_MGR_H diff --git a/tls/include/sni.h b/tls/include/sni.h new file mode 100644 index 00000000..a9629cd4 --- /dev/null +++ b/tls/include/sni.h @@ -0,0 +1,36 @@ +/* + * 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 SNI_H +#define SNI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SniArg { + char *serverName; + int32_t alert; +} SNI_Arg; + +/* compare whether the host names are the same */ +int32_t SNI_StrcaseCmp(const char *s1, const char *s2); + +#ifdef __cplusplus +} +#endif +#endif // ALPN_H \ No newline at end of file diff --git a/tls/include/tls.h b/tls/include/tls.h new file mode 100644 index 00000000..acfbccb7 --- /dev/null +++ b/tls/include/tls.h @@ -0,0 +1,250 @@ +/* + * 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 TLS_H +#define TLS_H + +#include +#include +#include "cipher_suite.h" +#include "tls_config.h" +#include "hitls_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_DIGEST_SIZE 64UL /* The longest known value is SHA512 */ + +#define DTLS_DEFAULT_PMTU 1500uL + +/* RFC 6083 4.1. Mapping of DTLS Records: + The supported maximum length of SCTP user messages MUST be at least + 2^14 + 2048 + 13 = 18445 bytes (2^14 + 2048 is the maximum length of + the DTLSCiphertext.fragment, and 13 is the size of the DTLS record + header). */ +#define DTLS_SCTP_PMTU 18445uL + +#define IS_DTLS_VERSION(version) (((version) & 0x8u) == 0x8u) + +#define MAC_KEY_LEN 32u /* the length of mac key */ + +#define UNPROCESSED_APP_MSG_COUNT_MAX 50 /* number of APP data cached */ + +#define RANDOM_SIZE 32u /* the size of random number */ + +typedef struct TlsCtx TLS_Ctx; +typedef struct HsCtx HS_Ctx; +typedef struct CcsCtx CCS_Ctx; +typedef struct AlertCtx ALERT_Ctx; +typedef struct RecCtx REC_Ctx; +typedef struct AppDataCtx APP_Ctx; + +typedef enum { + CCS_CMD_RECV_READY, /* CCS allowed to be received */ + CCS_CMD_RECV_EXIT_READY, /* CCS cannot be received */ + CCS_CMD_RECV_ACTIVE_CIPHER_SPEC, /* CCS active change cipher spec */ +} CCS_Cmd; + +/* Check whether the CCS message is received */ +typedef bool (*IsRecvCcsCallback)(const TLS_Ctx *ctx); +/* Send a CCS message */ +typedef int32_t (*SendCcsCallback)(TLS_Ctx *ctx); +/* Control the CCS */ +typedef int32_t (*CtrlCcsCallback)(TLS_Ctx *ctx, CCS_Cmd cmd); + +typedef enum { + ALERT_LEVEL_WARNING = 1, + ALERT_LEVEL_FATAL = 2, + ALERT_LEVEL_UNKNOWN = 255, +} ALERT_Level; + +typedef enum { + ALERT_CLOSE_NOTIFY = 0, + ALERT_UNEXPECTED_MESSAGE = 10, + ALERT_BAD_RECORD_MAC = 20, + ALERT_DECRYPTION_FAILED = 21, + ALERT_RECORD_OVERFLOW = 22, + ALERT_DECOMPRESSION_FAILURE = 30, + ALERT_HANDSHAKE_FAILURE = 40, + ALERT_NO_CERTIFICATE_RESERVED = 41, + ALERT_BAD_CERTIFICATE = 42, + ALERT_UNSUPPORTED_CERTIFICATE = 43, + ALERT_CERTIFICATE_REVOKED = 44, + ALERT_CERTIFICATE_EXPIRED = 45, + ALERT_CERTIFICATE_UNKNOWN = 46, + ALERT_ILLEGAL_PARAMETER = 47, + ALERT_UNKNOWN_CA = 48, + ALERT_ACCESS_DENIED = 49, + ALERT_DECODE_ERROR = 50, + ALERT_DECRYPT_ERROR = 51, + ALERT_EXPORT_RESTRICTION_RESERVED = 60, + ALERT_PROTOCOL_VERSION = 70, + ALERT_INSUFFICIENT_SECURITY = 71, + ALERT_INTERNAL_ERROR = 80, + ALERT_INAPPROPRIATE_FALLBACK = 86, + ALERT_USER_CANCELED = 90, + ALERT_NO_RENEGOTIATION = 100, + ALERT_MISSING_EXTENSION = 109, + ALERT_UNSUPPORTED_EXTENSION = 110, + ALERT_CERTIFICATE_UNOBTAINABLE = 111, + ALERT_UNRECOGNIZED_NAME = 112, + ALERT_BAD_CERTIFICATE_STATUS_RESPONSE = 113, + ALERT_BAD_CERTIFICATE_HASH_VALUE = 114, + ALERT_UNKNOWN_PSK_IDENTITY = 115, + ALERT_CERTIFICATE_REQUIRED = 116, + ALERT_NO_APPLICATION_PROTOCOL = 120, + ALERT_UNKNOWN = 255 +} ALERT_Description; + +/** Connection management state */ +typedef enum { + CM_STATE_IDLE, + CM_STATE_HANDSHAKING, + CM_STATE_TRANSPORTING, + CM_STATE_RENEGOTIATION, + CM_STATE_ALERTING, + CM_STATE_ALERTED, + CM_STATE_CLOSED, + CM_STATE_END +} CM_State; + +/** post-handshake auth */ +typedef enum { + PHA_NONE, /* not support pha */ + PHA_EXTENSION, /* pha extension send or received */ + PHA_PENDING, /* try to send certificate request */ + PHA_REQUESTED /* certificate request has been sent or received */ +} PHA_State; + + +typedef void (*SendAlertCallback)(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description); + +typedef bool (*GetAlertFlagCallback)(const TLS_Ctx *ctx); + +typedef int32_t (*UnexpectMsgHandleCallback)(TLS_Ctx *ctx, uint32_t msgType, const uint8_t *data, uint32_t dataLen); + +/** Connection management configure */ +typedef struct TLSCtxConfig { + void *userData; /* user data */ + uint16_t pmtu; /* Maximum transport unit of a path (bytes) */ + uint8_t reserved[1]; /* four-byte alignment */ + TLS_Config tlsConfig; /* tls configure context */ +} TLS_CtxConfig; + +typedef struct { + uint32_t algRemainTime; /* current key usage times */ + uint8_t preMacKey[MAC_KEY_LEN]; /* previous random key */ + uint8_t macKey[MAC_KEY_LEN]; /* random key used by the current algorithm */ +} CookieInfo; + +typedef struct { + uint16_t version; /* negotiated version */ + uint16_t clientVersion; /* version field of client hello */ + uint32_t cookieSize; /* cookie length */ + uint8_t *cookie; /* cookie data */ + CookieInfo cookieInfo; /* cookie info with calculation and verification */ + CipherSuiteInfo cipherSuiteInfo; /* cipher suite info */ + HITLS_SignHashAlgo signScheme; /* sign algorithm used by the local */ + uint8_t *alpnSelected; /* alpn proto */ + uint32_t alpnSelectedSize; + uint8_t clientVerifyData[MAX_DIGEST_SIZE]; /* client verify data */ + uint8_t serverVerifyData[MAX_DIGEST_SIZE]; /* server verify data */ + uint8_t clientRandom[RANDOM_SIZE]; /* client random number */ + uint8_t serverRandom[RANDOM_SIZE]; /* server random number */ + uint32_t clientVerifyDataSize; /* client verify data size */ + uint32_t serverVerifyDataSize; /* server verify data size */ + uint32_t renegotiationNum; /* the number of renegotiation */ + uint32_t certReqSendTime; /* certificate request sending times */ + uint32_t tls13BasicKeyExMode; /* TLS13_KE_MODE_PSK_ONLY || TLS13_KE_MODE_PSK_WITH_DHE || + TLS13_CERT_AUTH_WITH_DHE */ + + uint16_t negotiatedGroup; /* negotiated group */ + bool isResume; /* whether to resume the session */ + bool isRenegotiation; /* whether to renegotiate */ + + bool isSecureRenegotiation; /* whether security renegotiation */ + bool isExtendedMasterSecret; /* whether to calculate the extended master sercret */ + bool isEncryptThenMac; /* Whether to enable EncryptThenMac */ + bool isEncryptThenMacRead; /* Whether to enable EncryptThenMacRead */ + bool isEncryptThenMacWrite; /* Whether to enable EncryptThenMacWrite */ + bool isTicket; /* whether to negotiate tickets, only below tls1.3 */ + bool isSniStateOK; /* Whether server successfully processes the server_name callback */ +} TLS_NegotiatedInfo; + +typedef struct { + uint16_t *groups; /* all groups sent by the peer end */ + uint32_t groupsSize; /* size of a group */ + HITLS_SignHashAlgo peerSignHashAlg; /* peer signature algorithm */ + HITLS_ERROR verifyResult; /* record the certificate verification result of the peer end */ + HITLS_TrustedCAList *caList; /* peer trusted ca list */ +} PeerInfo; + +struct TlsCtx { + bool isClient; /* is Client */ + bool userShutDown; /* record whether the local end invokes the HITLS_Close */ + bool userRenego; /* record whether the local end initiates renegotiation */ + uint8_t rwstate; /* record the current internal read and write state */ + CM_State preState; + CM_State state; + + uint32_t shutdownState; /* Record the shutdown state */ + + void *rUio; /* read uio */ + void *uio; /* write uio */ + void *bUio; /* Storing uio */ + HS_Ctx *hsCtx; /* handshake context */ + CCS_Ctx *ccsCtx; /* ChangeCipherSpec context */ + ALERT_Ctx *alertCtx; /* alert context */ + REC_Ctx *recCtx; /* record context */ + APP_Ctx *appCtx; /* app context */ + struct { + IsRecvCcsCallback isRecvCCS; + SendCcsCallback sendCCS; /* send a CCS message */ + CtrlCcsCallback ctrlCCS; /* controlling CCS */ + SendAlertCallback sendAlert; /* set the alert message to be sent */ + GetAlertFlagCallback getAlertFlag; /* get alert state */ + UnexpectMsgHandleCallback unexpectedMsgProcessCb; /* the callback for unexpected messages */ + } method; + + PeerInfo peerInfo; /* Temporarily save the messages sent by the peer end */ + TLS_CtxConfig config; /* private configuration */ + TLS_Config *globalConfig; /* global configuration */ + TLS_NegotiatedInfo negotiatedInfo; /* TLS negotiation information */ + HITLS_Session *session; /* session information */ + + uint8_t clientAppTrafficSecret[MAX_DIGEST_SIZE]; /* TLS1.3 client app traffic secret */ + uint8_t serverAppTrafficSecret[MAX_DIGEST_SIZE]; /* TLS1.3 server app traffic secret */ + uint8_t resumptionMasterSecret[MAX_DIGEST_SIZE]; /* TLS1.3 session resume secret */ + + uint32_t bytesLeftToRead; /* bytes left to read after hs header has parsed */ + uint32_t keyUpdateType; /* TLS1.3 key update type */ + bool isKeyUpdateRequest; /* TLS1.3 Check whether there are unsent key update messages */ + bool haveClientPointFormats; /* whether the EC point format extension in the client hello is processed */ + bool hasParsedHsMsgHeader; /* has parsed current hs msg header */ + int32_t errorCode; /* Record the tls error code */ + + HITLS_HASH_Ctx *phaHash; /* tls1.3 pha: Handshake main process hash */ + HITLS_HASH_Ctx *phaCurHash; /* tls1.3 pha: Temporarily store the current pha hash */ + PHA_State phaState; /* tls1.3 pha state */ + uint8_t *certificateReqCtx; /* tls1.3 pha certificate_request_context */ + uint32_t certificateReqCtxSize; /* tls1.3 pha certificate_request_context */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* TLS_H */ diff --git a/tls/include/tls_binlog_id.h b/tls/include/tls_binlog_id.h new file mode 100644 index 00000000..a632c945 --- /dev/null +++ b/tls/include/tls_binlog_id.h @@ -0,0 +1,244 @@ +/* + * 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 TLS_BINLOG_ID_H +#define TLS_BINLOG_ID_H + +#ifdef __cplusplus +extern "C" { +#endif + +enum TLS_BINLOG_ID { + BINLOG_ID15001 = 15001, BINLOG_ID15002, BINLOG_ID15003, BINLOG_ID15004, BINLOG_ID15005, + BINLOG_ID15006, BINLOG_ID15007, BINLOG_ID15008, BINLOG_ID15009, BINLOG_ID15010, + BINLOG_ID15011, BINLOG_ID15012, BINLOG_ID15013, BINLOG_ID15014, BINLOG_ID15015, + BINLOG_ID15016, BINLOG_ID15017, BINLOG_ID15018, BINLOG_ID15019, BINLOG_ID15020, + BINLOG_ID15021, BINLOG_ID15022, BINLOG_ID15023, BINLOG_ID15024, BINLOG_ID15025, + BINLOG_ID15026, BINLOG_ID15027, BINLOG_ID15028, BINLOG_ID15029, BINLOG_ID15030, + BINLOG_ID15031, BINLOG_ID15032, BINLOG_ID15033, BINLOG_ID15034, BINLOG_ID15035, + BINLOG_ID15036, BINLOG_ID15037, BINLOG_ID15038, BINLOG_ID15039, BINLOG_ID15040, + BINLOG_ID15041, BINLOG_ID15042, BINLOG_ID15043, BINLOG_ID15044, BINLOG_ID15045, + BINLOG_ID15046, BINLOG_ID15047, BINLOG_ID15048, BINLOG_ID15049, BINLOG_ID15050, + BINLOG_ID15051, BINLOG_ID15052, BINLOG_ID15053, BINLOG_ID15054, BINLOG_ID15055, + BINLOG_ID15056, BINLOG_ID15057, BINLOG_ID15058, BINLOG_ID15059, BINLOG_ID15060, + BINLOG_ID15061, BINLOG_ID15062, BINLOG_ID15063, BINLOG_ID15064, BINLOG_ID15065, + BINLOG_ID15066, BINLOG_ID15067, BINLOG_ID15068, BINLOG_ID15069, BINLOG_ID15070, + BINLOG_ID15071, BINLOG_ID15072, BINLOG_ID15073, BINLOG_ID15074, BINLOG_ID15075, + BINLOG_ID15076, BINLOG_ID15077, BINLOG_ID15078, BINLOG_ID15079, BINLOG_ID15080, + BINLOG_ID15081, BINLOG_ID15082, BINLOG_ID15083, BINLOG_ID15084, BINLOG_ID15085, + BINLOG_ID15086, BINLOG_ID15087, BINLOG_ID15088, BINLOG_ID15089, BINLOG_ID15090, + BINLOG_ID15091, BINLOG_ID15092, BINLOG_ID15093, BINLOG_ID15094, BINLOG_ID15095, + BINLOG_ID15096, BINLOG_ID15097, BINLOG_ID15098, BINLOG_ID15099, BINLOG_ID15100, + BINLOG_ID15101, BINLOG_ID15102, BINLOG_ID15103, BINLOG_ID15104, BINLOG_ID15105, + BINLOG_ID15106, BINLOG_ID15107, BINLOG_ID15108, BINLOG_ID15109, BINLOG_ID15110, + BINLOG_ID15111, BINLOG_ID15112, BINLOG_ID15113, BINLOG_ID15114, BINLOG_ID15115, + BINLOG_ID15116, BINLOG_ID15117, BINLOG_ID15118, BINLOG_ID15119, BINLOG_ID15120, + BINLOG_ID15121, BINLOG_ID15122, BINLOG_ID15123, BINLOG_ID15124, BINLOG_ID15125, + BINLOG_ID15126, BINLOG_ID15127, BINLOG_ID15128, BINLOG_ID15129, BINLOG_ID15130, + BINLOG_ID15131, BINLOG_ID15132, BINLOG_ID15133, BINLOG_ID15134, BINLOG_ID15135, + BINLOG_ID15136, BINLOG_ID15137, BINLOG_ID15138, BINLOG_ID15139, BINLOG_ID15140, + BINLOG_ID15141, BINLOG_ID15142, BINLOG_ID15143, BINLOG_ID15144, BINLOG_ID15145, + BINLOG_ID15146, BINLOG_ID15147, BINLOG_ID15148, BINLOG_ID15149, BINLOG_ID15150, + BINLOG_ID15151, BINLOG_ID15152, BINLOG_ID15153, BINLOG_ID15154, BINLOG_ID15155, + BINLOG_ID15156, BINLOG_ID15157, BINLOG_ID15158, BINLOG_ID15159, BINLOG_ID15160, + BINLOG_ID15161, BINLOG_ID15162, BINLOG_ID15163, BINLOG_ID15164, BINLOG_ID15165, + BINLOG_ID15166, BINLOG_ID15167, BINLOG_ID15168, BINLOG_ID15169, BINLOG_ID15170, + BINLOG_ID15171, BINLOG_ID15172, BINLOG_ID15173, BINLOG_ID15174, BINLOG_ID15175, + BINLOG_ID15176, BINLOG_ID15177, BINLOG_ID15178, BINLOG_ID15179, BINLOG_ID15180, + BINLOG_ID15181, BINLOG_ID15182, BINLOG_ID15183, BINLOG_ID15184, BINLOG_ID15185, + BINLOG_ID15186, BINLOG_ID15187, BINLOG_ID15188, BINLOG_ID15189, BINLOG_ID15190, + BINLOG_ID15191, BINLOG_ID15192, BINLOG_ID15193, BINLOG_ID15194, BINLOG_ID15195, + BINLOG_ID15196, BINLOG_ID15197, BINLOG_ID15198, BINLOG_ID15199, BINLOG_ID15200, + BINLOG_ID15201, BINLOG_ID15202, BINLOG_ID15203, BINLOG_ID15204, BINLOG_ID15205, + BINLOG_ID15206, BINLOG_ID15207, BINLOG_ID15208, BINLOG_ID15209, BINLOG_ID15210, + BINLOG_ID15211, BINLOG_ID15212, BINLOG_ID15213, BINLOG_ID15214, BINLOG_ID15215, + BINLOG_ID15216, BINLOG_ID15217, BINLOG_ID15218, BINLOG_ID15219, BINLOG_ID15220, + BINLOG_ID15221, BINLOG_ID15222, BINLOG_ID15223, BINLOG_ID15224, BINLOG_ID15225, + BINLOG_ID15226, BINLOG_ID15227, BINLOG_ID15228, BINLOG_ID15229, BINLOG_ID15230, + BINLOG_ID15231, BINLOG_ID15232, BINLOG_ID15233, BINLOG_ID15234, BINLOG_ID15235, + BINLOG_ID15236, BINLOG_ID15237, BINLOG_ID15238, BINLOG_ID15239, BINLOG_ID15240, + BINLOG_ID15241, BINLOG_ID15242, BINLOG_ID15243, BINLOG_ID15244, BINLOG_ID15245, + BINLOG_ID15246, BINLOG_ID15247, BINLOG_ID15248, BINLOG_ID15249, BINLOG_ID15250, + BINLOG_ID15251, BINLOG_ID15252, BINLOG_ID15253, BINLOG_ID15254, BINLOG_ID15255, + BINLOG_ID15256, BINLOG_ID15257, BINLOG_ID15258, BINLOG_ID15259, BINLOG_ID15260, + BINLOG_ID15261, BINLOG_ID15262, BINLOG_ID15263, BINLOG_ID15264, BINLOG_ID15265, + BINLOG_ID15266, BINLOG_ID15267, BINLOG_ID15268, BINLOG_ID15269, BINLOG_ID15270, + BINLOG_ID15271, BINLOG_ID15272, BINLOG_ID15273, BINLOG_ID15274, BINLOG_ID15275, + BINLOG_ID15276, BINLOG_ID15277, BINLOG_ID15278, BINLOG_ID15279, BINLOG_ID15280, + BINLOG_ID15281, BINLOG_ID15282, BINLOG_ID15283, BINLOG_ID15284, BINLOG_ID15285, + BINLOG_ID15286, BINLOG_ID15287, BINLOG_ID15288, BINLOG_ID15289, BINLOG_ID15290, + BINLOG_ID15291, BINLOG_ID15292, BINLOG_ID15293, BINLOG_ID15294, BINLOG_ID15295, + BINLOG_ID15296, BINLOG_ID15297, BINLOG_ID15298, BINLOG_ID15299, BINLOG_ID15300, + BINLOG_ID15301, BINLOG_ID15302, BINLOG_ID15303, BINLOG_ID15304, BINLOG_ID15305, + BINLOG_ID15306, BINLOG_ID15307, BINLOG_ID15308, BINLOG_ID15309, BINLOG_ID15310, + BINLOG_ID15311, BINLOG_ID15312, BINLOG_ID15313, BINLOG_ID15314, BINLOG_ID15315, + BINLOG_ID15316, BINLOG_ID15317, BINLOG_ID15318, BINLOG_ID15319, BINLOG_ID15320, + BINLOG_ID15321, BINLOG_ID15322, BINLOG_ID15323, BINLOG_ID15324, BINLOG_ID15325, + BINLOG_ID15326, BINLOG_ID15327, BINLOG_ID15328, BINLOG_ID15329, BINLOG_ID15330, + BINLOG_ID15331, BINLOG_ID15332, BINLOG_ID15333, BINLOG_ID15334, BINLOG_ID15335, + BINLOG_ID15336, BINLOG_ID15337, BINLOG_ID15338, BINLOG_ID15339, BINLOG_ID15340, + BINLOG_ID15341, BINLOG_ID15342, BINLOG_ID15343, BINLOG_ID15344, BINLOG_ID15345, + BINLOG_ID15346, BINLOG_ID15347, BINLOG_ID15348, BINLOG_ID15349, BINLOG_ID15350, + BINLOG_ID15351, BINLOG_ID15352, BINLOG_ID15353, BINLOG_ID15354, BINLOG_ID15355, + BINLOG_ID15356, BINLOG_ID15357, BINLOG_ID15358, BINLOG_ID15359, BINLOG_ID15360, + BINLOG_ID15361, BINLOG_ID15362, BINLOG_ID15363, BINLOG_ID15364, BINLOG_ID15365, + BINLOG_ID15366, BINLOG_ID15367, BINLOG_ID15368, BINLOG_ID15369, BINLOG_ID15370, + BINLOG_ID15371, BINLOG_ID15372, BINLOG_ID15373, BINLOG_ID15374, BINLOG_ID15375, + BINLOG_ID15376, BINLOG_ID15377, BINLOG_ID15378, BINLOG_ID15379, BINLOG_ID15380, + BINLOG_ID15381, BINLOG_ID15382, BINLOG_ID15383, BINLOG_ID15384, BINLOG_ID15385, + BINLOG_ID15386, BINLOG_ID15387, BINLOG_ID15388, BINLOG_ID15389, BINLOG_ID15390, + BINLOG_ID15391, BINLOG_ID15392, BINLOG_ID15393, BINLOG_ID15394, BINLOG_ID15395, + BINLOG_ID15396, BINLOG_ID15397, BINLOG_ID15398, BINLOG_ID15399, BINLOG_ID15400, + BINLOG_ID15401, BINLOG_ID15402, BINLOG_ID15403, BINLOG_ID15404, BINLOG_ID15405, + BINLOG_ID15406, BINLOG_ID15407, BINLOG_ID15408, BINLOG_ID15409, BINLOG_ID15410, + BINLOG_ID15411, BINLOG_ID15412, BINLOG_ID15413, BINLOG_ID15414, BINLOG_ID15415, + BINLOG_ID15416, BINLOG_ID15417, BINLOG_ID15418, BINLOG_ID15419, BINLOG_ID15420, + BINLOG_ID15421, BINLOG_ID15422, BINLOG_ID15423, BINLOG_ID15424, BINLOG_ID15425, + BINLOG_ID15426, BINLOG_ID15427, BINLOG_ID15428, BINLOG_ID15429, BINLOG_ID15430, + BINLOG_ID15431, BINLOG_ID15432, BINLOG_ID15433, BINLOG_ID15434, BINLOG_ID15435, + BINLOG_ID15436, BINLOG_ID15437, BINLOG_ID15438, BINLOG_ID15439, BINLOG_ID15440, + BINLOG_ID15441, BINLOG_ID15442, BINLOG_ID15443, BINLOG_ID15444, BINLOG_ID15445, + BINLOG_ID15446, BINLOG_ID15447, BINLOG_ID15448, BINLOG_ID15449, BINLOG_ID15450, + BINLOG_ID15451, BINLOG_ID15452, BINLOG_ID15453, BINLOG_ID15454, BINLOG_ID15455, + BINLOG_ID15456, BINLOG_ID15457, BINLOG_ID15458, BINLOG_ID15459, BINLOG_ID15460, + BINLOG_ID15461, BINLOG_ID15462, BINLOG_ID15463, BINLOG_ID15464, BINLOG_ID15465, + BINLOG_ID15466, BINLOG_ID15467, BINLOG_ID15468, BINLOG_ID15469, BINLOG_ID15470, + BINLOG_ID15471, BINLOG_ID15472, BINLOG_ID15473, BINLOG_ID15474, BINLOG_ID15475, + BINLOG_ID15476, BINLOG_ID15477, BINLOG_ID15478, BINLOG_ID15479, BINLOG_ID15480, + BINLOG_ID15481, BINLOG_ID15482, BINLOG_ID15483, BINLOG_ID15484, BINLOG_ID15485, + BINLOG_ID15486, BINLOG_ID15487, BINLOG_ID15488, BINLOG_ID15489, BINLOG_ID15490, + BINLOG_ID15491, BINLOG_ID15492, BINLOG_ID15493, BINLOG_ID15494, BINLOG_ID15495, + BINLOG_ID15496, BINLOG_ID15497, BINLOG_ID15498, BINLOG_ID15499, BINLOG_ID15500, + BINLOG_ID15501, BINLOG_ID15502, BINLOG_ID15503, BINLOG_ID15504, BINLOG_ID15505, + BINLOG_ID15506, BINLOG_ID15507, BINLOG_ID15508, BINLOG_ID15509, BINLOG_ID15510, + BINLOG_ID15511, BINLOG_ID15512, BINLOG_ID15513, BINLOG_ID15514, BINLOG_ID15515, + BINLOG_ID15516, BINLOG_ID15517, BINLOG_ID15518, BINLOG_ID15519, BINLOG_ID15520, + BINLOG_ID15521, BINLOG_ID15522, BINLOG_ID15523, BINLOG_ID15524, BINLOG_ID15525, + BINLOG_ID15526, BINLOG_ID15527, BINLOG_ID15528, BINLOG_ID15529, BINLOG_ID15530, + BINLOG_ID15531, BINLOG_ID15532, BINLOG_ID15533, BINLOG_ID15534, BINLOG_ID15535, + BINLOG_ID15536, BINLOG_ID15537, BINLOG_ID15538, BINLOG_ID15539, BINLOG_ID15540, + BINLOG_ID15541, BINLOG_ID15542, BINLOG_ID15543, BINLOG_ID15544, BINLOG_ID15545, + BINLOG_ID15546, BINLOG_ID15547, BINLOG_ID15548, BINLOG_ID15549, BINLOG_ID15550, + BINLOG_ID15551, BINLOG_ID15552, BINLOG_ID15553, BINLOG_ID15554, BINLOG_ID15555, + BINLOG_ID15556, BINLOG_ID15557, BINLOG_ID15558, BINLOG_ID15559, BINLOG_ID15560, + BINLOG_ID15561, BINLOG_ID15562, BINLOG_ID15563, BINLOG_ID15564, BINLOG_ID15565, + BINLOG_ID15566, BINLOG_ID15567, BINLOG_ID15568, BINLOG_ID15569, BINLOG_ID15570, + BINLOG_ID15571, BINLOG_ID15572, BINLOG_ID15573, BINLOG_ID15574, BINLOG_ID15575, + BINLOG_ID15576, BINLOG_ID15577, BINLOG_ID15578, BINLOG_ID15579, BINLOG_ID15580, + BINLOG_ID15581, BINLOG_ID15582, BINLOG_ID15583, BINLOG_ID15584, BINLOG_ID15585, + BINLOG_ID15586, BINLOG_ID15587, BINLOG_ID15588, BINLOG_ID15589, BINLOG_ID15590, + BINLOG_ID15591, BINLOG_ID15592, BINLOG_ID15593, BINLOG_ID15594, BINLOG_ID15595, + BINLOG_ID15596, BINLOG_ID15597, BINLOG_ID15598, BINLOG_ID15599, BINLOG_ID15600, + BINLOG_ID15601, BINLOG_ID15602, BINLOG_ID15603, BINLOG_ID15604, BINLOG_ID15605, + BINLOG_ID15606, BINLOG_ID15607, BINLOG_ID15608, BINLOG_ID15609, BINLOG_ID15610, + BINLOG_ID15611, BINLOG_ID15612, BINLOG_ID15613, BINLOG_ID15614, BINLOG_ID15615, + BINLOG_ID15616, BINLOG_ID15617, BINLOG_ID15618, BINLOG_ID15619, BINLOG_ID15620, + BINLOG_ID15621, BINLOG_ID15622, BINLOG_ID15623, BINLOG_ID15624, BINLOG_ID15625, + BINLOG_ID15626, BINLOG_ID15627, BINLOG_ID15628, BINLOG_ID15629, BINLOG_ID15630, + BINLOG_ID15631, BINLOG_ID15632, BINLOG_ID15633, BINLOG_ID15634, BINLOG_ID15635, + BINLOG_ID15636, BINLOG_ID15637, BINLOG_ID15638, BINLOG_ID15639, BINLOG_ID15640, + BINLOG_ID15641, BINLOG_ID15642, BINLOG_ID15643, BINLOG_ID15644, BINLOG_ID15645, + BINLOG_ID15646, BINLOG_ID15647, BINLOG_ID15648, BINLOG_ID15649, BINLOG_ID15650, + BINLOG_ID15651, BINLOG_ID15652, BINLOG_ID15653, BINLOG_ID15654, BINLOG_ID15655, + BINLOG_ID15656, BINLOG_ID15657, BINLOG_ID15658, BINLOG_ID15659, BINLOG_ID15660, + BINLOG_ID15661, BINLOG_ID15662, BINLOG_ID15663, BINLOG_ID15664, BINLOG_ID15665, + BINLOG_ID15666, BINLOG_ID15667, BINLOG_ID15668, BINLOG_ID15669, BINLOG_ID15670, + BINLOG_ID15671, BINLOG_ID15672, BINLOG_ID15673, BINLOG_ID15674, BINLOG_ID15675, + BINLOG_ID15676, BINLOG_ID15677, BINLOG_ID15678, BINLOG_ID15679, BINLOG_ID15680, + BINLOG_ID15681, BINLOG_ID15682, BINLOG_ID15683, BINLOG_ID15684, BINLOG_ID15685, + BINLOG_ID15686, BINLOG_ID15687, BINLOG_ID15688, BINLOG_ID15689, BINLOG_ID15690, + BINLOG_ID15691, BINLOG_ID15692, BINLOG_ID15693, BINLOG_ID15694, BINLOG_ID15695, + BINLOG_ID15696, BINLOG_ID15697, BINLOG_ID15698, BINLOG_ID15699, BINLOG_ID15700, + BINLOG_ID15701, BINLOG_ID15702, BINLOG_ID15703, BINLOG_ID15704, BINLOG_ID15705, + BINLOG_ID15706, BINLOG_ID15707, BINLOG_ID15708, BINLOG_ID15709, BINLOG_ID15710, + BINLOG_ID15711, BINLOG_ID15712, BINLOG_ID15713, BINLOG_ID15714, BINLOG_ID15715, + BINLOG_ID15716, BINLOG_ID15717, BINLOG_ID15718, BINLOG_ID15719, BINLOG_ID15720, + BINLOG_ID15721, BINLOG_ID15722, BINLOG_ID15723, BINLOG_ID15724, BINLOG_ID15725, + BINLOG_ID15726, BINLOG_ID15727, BINLOG_ID15728, BINLOG_ID15729, BINLOG_ID15730, + BINLOG_ID15731, BINLOG_ID15732, BINLOG_ID15733, BINLOG_ID15734, BINLOG_ID15735, + BINLOG_ID15736, BINLOG_ID15737, BINLOG_ID15738, BINLOG_ID15739, BINLOG_ID15740, + BINLOG_ID15741, BINLOG_ID15742, BINLOG_ID15743, BINLOG_ID15744, BINLOG_ID15745, + BINLOG_ID15746, BINLOG_ID15747, BINLOG_ID15748, BINLOG_ID15749, BINLOG_ID15750, + BINLOG_ID15751, BINLOG_ID15752, BINLOG_ID15753, BINLOG_ID15754, BINLOG_ID15755, + BINLOG_ID15756, BINLOG_ID15757, BINLOG_ID15758, BINLOG_ID15759, BINLOG_ID15760, + BINLOG_ID15761, BINLOG_ID15762, BINLOG_ID15763, BINLOG_ID15764, BINLOG_ID15765, + BINLOG_ID15766, BINLOG_ID15767, BINLOG_ID15768, BINLOG_ID15769, BINLOG_ID15770, + BINLOG_ID15771, BINLOG_ID15772, BINLOG_ID15773, BINLOG_ID15774, BINLOG_ID15775, + BINLOG_ID15776, BINLOG_ID15777, BINLOG_ID15778, BINLOG_ID15779, BINLOG_ID15780, + BINLOG_ID15781, BINLOG_ID15782, BINLOG_ID15783, BINLOG_ID15784, BINLOG_ID15785, + BINLOG_ID15786, BINLOG_ID15787, BINLOG_ID15788, BINLOG_ID15789, BINLOG_ID15790, + BINLOG_ID15791, BINLOG_ID15792, BINLOG_ID15793, BINLOG_ID15794, BINLOG_ID15795, + BINLOG_ID15796, BINLOG_ID15797, BINLOG_ID15798, BINLOG_ID15799, BINLOG_ID15800, + BINLOG_ID15801, BINLOG_ID15802, BINLOG_ID15803, BINLOG_ID15804, BINLOG_ID15805, + BINLOG_ID15806, BINLOG_ID15807, BINLOG_ID15808, BINLOG_ID15809, BINLOG_ID15810, + BINLOG_ID15811, BINLOG_ID15812, BINLOG_ID15813, BINLOG_ID15814, BINLOG_ID15815, + BINLOG_ID15816, BINLOG_ID15817, BINLOG_ID15818, BINLOG_ID15819, BINLOG_ID15820, + BINLOG_ID15821, BINLOG_ID15822, BINLOG_ID15823, BINLOG_ID15824, BINLOG_ID15825, + BINLOG_ID15826, BINLOG_ID15827, BINLOG_ID15828, BINLOG_ID15829, BINLOG_ID15830, + BINLOG_ID15831, BINLOG_ID15832, BINLOG_ID15833, BINLOG_ID15834, BINLOG_ID15835, + BINLOG_ID15836, BINLOG_ID15837, BINLOG_ID15838, BINLOG_ID15839, BINLOG_ID15840, + BINLOG_ID15841, BINLOG_ID15842, BINLOG_ID15843, BINLOG_ID15844, BINLOG_ID15845, + BINLOG_ID15846, BINLOG_ID15847, BINLOG_ID15848, BINLOG_ID15849, BINLOG_ID15850, + BINLOG_ID15851, BINLOG_ID15852, BINLOG_ID15853, BINLOG_ID15854, BINLOG_ID15855, + BINLOG_ID15856, BINLOG_ID15857, BINLOG_ID15858, BINLOG_ID15859, BINLOG_ID15860, + BINLOG_ID15861, BINLOG_ID15862, BINLOG_ID15863, BINLOG_ID15864, BINLOG_ID15865, + BINLOG_ID15866, BINLOG_ID15867, BINLOG_ID15868, BINLOG_ID15869, BINLOG_ID15870, + BINLOG_ID15871, BINLOG_ID15872, BINLOG_ID15873, BINLOG_ID15874, BINLOG_ID15875, + BINLOG_ID15876, BINLOG_ID15877, BINLOG_ID15878, BINLOG_ID15879, BINLOG_ID15880, + BINLOG_ID15881, BINLOG_ID15882, BINLOG_ID15883, BINLOG_ID15884, BINLOG_ID15885, + BINLOG_ID15886, BINLOG_ID15887, BINLOG_ID15888, BINLOG_ID15889, BINLOG_ID15890, + BINLOG_ID15891, BINLOG_ID15892, BINLOG_ID15893, BINLOG_ID15894, BINLOG_ID15895, + BINLOG_ID15896, BINLOG_ID15897, BINLOG_ID15898, BINLOG_ID15899, BINLOG_ID15900, + BINLOG_ID15901, BINLOG_ID15902, BINLOG_ID15903, BINLOG_ID15904, BINLOG_ID15905, + BINLOG_ID15906, BINLOG_ID15907, BINLOG_ID15908, BINLOG_ID15909, BINLOG_ID15910, + BINLOG_ID15911, BINLOG_ID15912, BINLOG_ID15913, BINLOG_ID15914, BINLOG_ID15915, + BINLOG_ID15916, BINLOG_ID15917, BINLOG_ID15918, BINLOG_ID15919, BINLOG_ID15920, + BINLOG_ID15921, BINLOG_ID15922, BINLOG_ID15923, BINLOG_ID15924, BINLOG_ID15925, + BINLOG_ID15926, BINLOG_ID15927, BINLOG_ID15928, BINLOG_ID15929, BINLOG_ID15930, + BINLOG_ID15931, BINLOG_ID15932, BINLOG_ID15933, BINLOG_ID15934, BINLOG_ID15935, + BINLOG_ID15936, BINLOG_ID15937, BINLOG_ID15938, BINLOG_ID15939, BINLOG_ID15940, + BINLOG_ID15941, BINLOG_ID15942, BINLOG_ID15943, BINLOG_ID15944, BINLOG_ID15945, + BINLOG_ID15946, BINLOG_ID15947, BINLOG_ID15948, BINLOG_ID15949, BINLOG_ID15950, + BINLOG_ID15951, BINLOG_ID15952, BINLOG_ID15953, BINLOG_ID15954, BINLOG_ID15955, + BINLOG_ID15956, BINLOG_ID15957, BINLOG_ID15958, BINLOG_ID15959, BINLOG_ID15960, + BINLOG_ID15961, BINLOG_ID15962, BINLOG_ID15963, BINLOG_ID15964, BINLOG_ID15965, + BINLOG_ID15966, BINLOG_ID15967, BINLOG_ID15968, BINLOG_ID15969, BINLOG_ID15970, + BINLOG_ID15971, BINLOG_ID15972, BINLOG_ID15973, BINLOG_ID15974, BINLOG_ID15975, + BINLOG_ID15976, BINLOG_ID15977, BINLOG_ID15978, BINLOG_ID15979, BINLOG_ID15980, + BINLOG_ID15981, BINLOG_ID15982, BINLOG_ID15983, BINLOG_ID15984, BINLOG_ID15985, + BINLOG_ID15986, BINLOG_ID15987, BINLOG_ID15988, BINLOG_ID15989, BINLOG_ID15990, + BINLOG_ID15991, BINLOG_ID15992, BINLOG_ID15993, BINLOG_ID15994, BINLOG_ID15995, + BINLOG_ID15996, BINLOG_ID15997, BINLOG_ID15998, BINLOG_ID15999, BINLOG_ID16000, + BINLOG_ID16001, BINLOG_ID16002, BINLOG_ID16003, BINLOG_ID16004, BINLOG_ID16005, + BINLOG_ID16006, BINLOG_ID16007, BINLOG_ID16008, BINLOG_ID16009, BINLOG_ID16010, + BINLOG_ID16011, BINLOG_ID16012, BINLOG_ID16013, BINLOG_ID16014, BINLOG_ID16015, + BINLOG_ID16016, BINLOG_ID16017, BINLOG_ID16018, BINLOG_ID16019, BINLOG_ID16020, + BINLOG_ID16021, BINLOG_ID16022, BINLOG_ID16023, BINLOG_ID16024, BINLOG_ID16025, + BINLOG_ID16026, BINLOG_ID16027, BINLOG_ID16028, BINLOG_ID16029, BINLOG_ID16030, + BINLOG_ID16031, BINLOG_ID16032, BINLOG_ID16033, BINLOG_ID16034, BINLOG_ID16035, + BINLOG_ID16036, BINLOG_ID16037, BINLOG_ID16038, BINLOG_ID16039, BINLOG_ID16040, + BINLOG_ID16041, BINLOG_ID16042, BINLOG_ID16043, BINLOG_ID16044, BINLOG_ID16045, + BINLOG_ID16046, BINLOG_ID16047, BINLOG_ID16048, BINLOG_ID16049, BINLOG_ID16050, + BINLOG_ID16051, BINLOG_ID16052, BINLOG_ID16053, BINLOG_ID16054, BINLOG_ID16055, + BINLOG_ID16056, BINLOG_ID16057, BINLOG_ID16058, BINLOG_ID16059, BINLOG_ID16060, + BINLOG_ID16061, BINLOG_ID16062, BINLOG_ID16063, BINLOG_ID16064, BINLOG_ID16065, + BINLOG_ID16066, BINLOG_ID16067, BINLOG_ID16068, BINLOG_ID16069, BINLOG_ID16070, +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/include/tls_config.h b/tls/include/tls_config.h new file mode 100644 index 00000000..4f76ff08 --- /dev/null +++ b/tls/include/tls_config.h @@ -0,0 +1,172 @@ +/* + * 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 TLS_CONFIG_H +#define TLS_CONFIG_H + +#include +#include +#include "hitls_cert_type.h" +#include "hitls_cert.h" +#include "hitls_debug.h" +#include "hitls_config.h" +#include "hitls_session.h" +#include "hitls_psk.h" +#include "hitls_security.h" +#include "hitls_sni.h" +#include "hitls_alpn.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup config + * @brief Certificate management context + */ +typedef struct CertMgrCtxInner CERT_MgrCtx; + +typedef struct TlsSessionManager TLS_SessionMgr; + +/** +* @ingroup config +* @brief DTLS 1.0 +*/ +#define HITLS_VERSION_DTLS10 0xfeffu + +#define HITLS_TICKET_KEY_NAME_SIZE 16u +#define HITLS_TICKET_KEY_SIZE 32u + +/* the default number of tickets of TLS1.3 server is 2 */ +#define HITLS_TLS13_TICKET_NUM_DEFAULT 2u + +/* max cert list is 100k */ +#define HITLS_MAX_CERT_LIST_DEFAULT (1024 * 100) + +/** + * @brief TLS Global Configuration + */ +typedef struct TlsConfig { + BSL_SAL_RefCount references; /* reference count */ + uint32_t version; /* supported proto version */ + uint32_t originVersionMask; /* the original supported proto version mask */ + uint16_t minVersion; /* min supported proto version */ + uint16_t maxVersion; /* max supported proto version */ + + uint16_t *tls13CipherSuites; /* tls13 cipher suite */ + uint32_t tls13cipherSuitesSize; + uint16_t *cipherSuites; /* cipher suite */ + uint32_t cipherSuitesSize; + uint8_t *pointFormats; /* ec point format */ + uint32_t pointFormatsSize; + /* According to RFC 8446 4.2.7, before TLS 1.3 is ec curves; TLS 1.3: supported groups for the key exchange */ + uint16_t *groups; + uint32_t groupsSize; + uint16_t *signAlgorithms; /* signature algorithm */ + uint32_t signAlgorithmsSize; + + uint8_t *alpnList; /* application layer protocols list */ + uint32_t alpnListSize; /* bytes of alpn, excluding the tail 0 byte */ + + HITLS_SecurityCb securityCb; /* Security callback */ + void *securityExData; /* Security ex data */ + int32_t securityLevel; /* Security level */ + + uint8_t *serverName; /* server name */ + uint32_t serverNameSize; /* server name size */ + + /* TLS1.2 psk */ + uint8_t *pskIdentityHint; /* psk identity hint */ + uint32_t hintSize; + HITLS_PskClientCb pskClientCb; /* psk client callback */ + HITLS_PskServerCb pskServerCb; /* psk server callback */ + + /* TLS1.3 psk */ + HITLS_PskFindSessionCb pskFindSessionCb; /* TLS1.3 PSK server callback */ + HITLS_PskUseSessionCb pskUseSessionCb; /* TLS1.3 PSK client callback */ + + HITLS_NoSecRenegotiationCb noSecRenegotiationCb; /* callback for the peer unsupported security renegotiation */ + + HITLS_CRYPT_Key *dhTmp; /* Temporary DH key set by the user */ + HITLS_CRYPT_Key *ecdhTmp; /* Temporary ECDH key set by the user */ + + HITLS_InfoCb infoCb; /* information indicator callback */ + HITLS_MsgCb msgCb; /* message callback function cb for observing all SSL/TLS protocol messages */ + void *msgArg; /* set argument arg to the callback function */ + + HITLS_RecordPaddingCb recordPaddingCb; /* the callback to specify the padding for TLS 1.3 records */ + void *recordPaddingArg; /* assign a value arg that is passed to the callback */ + + uint32_t keyExchMode; /* TLS1.3 psk exchange mode */ + + uint32_t maxCertList; /* the maximum size allowed for the peer's certificate chain */ + + HITLS_TrustedCAList *caList; /* the list of CAs sent to the peer */ + CERT_MgrCtx *certMgrCtx; /* certificate management context */ + + uint32_t sessionIdCtxSize; /* the size of sessionId context */ + uint8_t sessionIdCtx[HITLS_SESSION_ID_CTX_MAX_SIZE]; /* the sessionId context */ + + uint32_t ticketNums; /* TLS1.3 ticket number */ + TLS_SessionMgr *sessMgr; /* session management */ + + void *userData; /* user data */ + HITLS_ConfigUserDataFreeCb userDataFreeCb; + + bool needCheckKeyUsage; /* whether to check keyusage, default on */ + bool needCheckPmsVersion; /* whether to verify the version in premastersecret */ + bool isSupportRenegotiation; /* support renegotiation */ + bool isResumptionOnRenego; /* supports session resume during renegotiation */ + bool isSupportDhAuto; /* the DH parameter to be automatically selected */ + + /* Certificate Verification Mode */ + bool isSupportClientVerify; /* Enable dual-ended authentication. only for server */ + bool isSupportNoClientCert; /* Authentication Passed When Client Sends Empty Certificate. only for server */ + bool isSupportPostHandshakeAuth; /* TLS1.3 support post handshake auth. for server and client */ + bool isSupportVerifyNone; /* The handshake will be continued regardless of the verification result. + for server and client */ + bool isSupportClientOnceVerify; /* only request a client certificate once during the connection. + only for server */ + + bool isQuietShutdown; /* is support the quiet shutdown mode */ + bool isEncryptThenMac; /* is EncryptThenMac on */ + bool isFlightTransmitEnable; /* sending of handshake information in one flighttransmit */ + + bool isSupportExtendMasterSecret; /* is support extended master secret */ + bool isSupportSessionTicket; /* is support session ticket */ + bool isSupportServerPreference; /* server cipher suites can be preferentially selected */ + + /** + * Configurations in the HITLS_Ctx are classified into private configuration and global configuration. + * The following parameters directly reference the global configuration in tls. + * Private configuration: ctx->config.tlsConfig + * The global configuration: ctx->globalConfig + * Modifying the globalConfig will affects all associated HITLS_Ctx + */ + HITLS_AlpnSelectCb alpnSelectCb; /* alpn callback */ + void *alpnUserData; /* the user data for alpn callback */ + void *sniArg; /* the args for servername callback */ + HITLS_SniDealCb sniDealCb; /* server name callback function */ + HITLS_ClientHelloCb clientHelloCb; /* ClientHello callback */ + void *clientHelloCbArg; /* the args for ClientHello callback */ + HITLS_NewSessionCb newSessionCb; /* negotiates to generate a session */ +} TLS_Config; + +#ifdef __cplusplus +} +#endif + +#endif // TLS_CONFIG_H diff --git a/tls/record/include/rec.h b/tls/record/include/rec.h new file mode 100644 index 00000000..fff93c28 --- /dev/null +++ b/tls/record/include/rec.h @@ -0,0 +1,227 @@ +/* + * 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 REC_H +#define REC_H + +#include +#include +#include "hitls_crypt_type.h" +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define REC_MAX_PLAIN_LENGTH 16384 /* Maximum plain length */ +/* TLS13 Maximum MAC address padding */ +#define REC_MAX_TLS13_ENCRYPTED_OVERHEAD 256u +/* TLS13 Maximum ciphertext length */ +#define REC_MAX_TLS13_ENCRYPTED_LEN (REC_MAX_PLAIN_LENGTH + REC_MAX_TLS13_ENCRYPTED_OVERHEAD) + +#define REC_MASTER_SECRET_LEN 48 +#define REC_RANDOM_LEN 32 + +#define RECORD_HEADER 0x100 +#define RECORD_INNER_CONTENT_TYPE 0x101 +/** + * record type + */ +typedef enum { + REC_TYPE_CHANGE_CIPHER_SPEC = 20, + REC_TYPE_ALERT = 21, + REC_TYPE_HANDSHAKE = 22, + REC_TYPE_APP = 23, + REC_TYPE_UNKNOWN = 255 +} REC_Type; + +/** + * SecurityParameters, used to generate keys and initialize the connect state + */ +typedef struct { + bool isClient; /* Connection Endpoint */ + bool isClientTrafficSecret; /* TrafficSecret type */ + HITLS_HashAlgo prfAlg; /* prf_algorithm */ + HITLS_MacAlgo macAlg; /* mac algorithm */ + HITLS_CipherAlgo cipherAlg; /* symmetric encryption algorithm */ + HITLS_CipherType cipherType; /* encryption algorithm type */ + + /* key length */ + uint8_t fixedIvLength; /* iv length. In TLS1.2 AEAD algorithm is the implicit IV length */ + uint8_t encKeyLen; /* Length of the symmetric key */ + uint8_t macKeyLen; /* MAC key length: If the AEAD algorithm is used, the MAC key length is 0 */ + + uint8_t blockLength; /* If the block length is not zero, the alignment should be handled. */ + uint8_t recordIvLength; /* The explicit IV needs to be sent to the peer */ + uint8_t macLen; /* MAC length. For AEAD, it is the mark length */ + + uint8_t masterSecret[MAX_DIGEST_SIZE]; /* tls1.2 master key. TLS1.3 carries the TrafficSecret */ + uint8_t clientRandom[REC_RANDOM_LEN]; /* Client random number */ + uint8_t serverRandom[REC_RANDOM_LEN]; /* service random number */ +} REC_SecParameters; + +/** + * @ingroup record + * @brief Record initialization + * + * @param ctx [IN] TLS object + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * + */ +int32_t REC_Init(TLS_Ctx *ctx); + +/** + * @ingroup record + * @brief record deinitialize + * + * @param ctx [IN] TLS object + */ +void REC_DeInit(TLS_Ctx *ctx); + +/** + * @ingroup record + * @brief Check whether data exists in the read buffer of the reocrd + * + * @param ctx [IN] TLS object + * @return whether data exists in the read buffer + */ +bool REC_ReadHasPending(const TLS_Ctx *ctx); + +/** + * @ingroup record + * @brief Reads a message in the unit of a record. Data is read from the uio of the CTX to the data pointer + * + * @attention recordType indicates the expected record type (app or handshake) + * readLen indicates the length of read data. The maximum length is REC_MAX_PLAIN_LENGTH (16384) + * @param ctx [IN] TLS object + * @param recordType [IN] Expected record type(app or handshake) + * @param data [OUT] Read buffer + * @param readLen [OUT] Length of the read data + * @param num [IN] The size of read buffer, which must be greater than or equal to the maximum size of the record + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION,Invalid null pointer + * @retval HITLS_REC_ERR_BUFFER_NOT_ENOUGH The buffer space is insufficient + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY indicates that the buffer is empty and needs to be read again + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG An unexpected message is received and needs to be processed + * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap + */ +int32_t REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num); + +/** + * @ingroup record + * @brief Write a record in the unit of record + * + * @attention If the value of num exceeds the maximum length of the record, return error + * + * @param ctx [IN] TLS object + * @param recordType [IN] record type + * @param data [IN] Write data + * @param num [IN] Attempt to write num bytes of plaintext data + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * @retval HITLS_REC_ERR_BUFFER_NOT_ENOUGH The buffer space is insufficient + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_REC_PMTU_TOO_SMALL The PMTU is too small + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_IO_BUSY I/O busy + * @retval HITLS_REC_ERR_TOO_BIG_LENGTH The length of the plaintext data written by the upper layer exceeds the +* maximum length of the plaintext data that can be written by a single record + * @retval HITLS_REC_ERR_NOT_SUPPORT_CIPHER The key algorithm is not supported + * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap + */ +int32_t REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num); + +/** + * @ingroup record + * @brief Initialize the pending state + * + * @param ctx [IN] TLS object + * @param param [IN] Security parameter + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * + */ +int32_t REC_InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param); + +/** + * @ingroup record + * @brief Activate the pending state, switch the pending state to the current state + * + * @attention ctx cannot be empty + * @param ctx [IN] TLS object + * @param isOut [IN] Indicates whether is the output type + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * + */ +int32_t REC_ActivePendingState(TLS_Ctx *ctx, bool isOut); + +/** + * @brief Obtain the maximum writable plaintext length of a single record + * + * @param ctx [IN] TLS_Ctx context + * @param len [OUT] Maximum length of the plaintext + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * @retval HITLS_REC_PMTU_TOO_SMALL The PMTU is too small + */ +int32_t REC_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len); + +/** + * @ingroup record + * @brief TLS13 Initialize the pending state + * + * @param ctx [IN] TLS object + * @param param [IN] Security parameter + * @param isOut [IN] Indicates whether is the output type + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * + */ +int32_t REC_TLS13InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param, bool isOut); + +/** + * @brief read N bytes from tls record layer + * @attention Currently, this interface is used only at the handshake layer + and cannot process handshake message fragments. + * @param ctx [IN] TLS connection handle. + * @param recordType [IN] Buffer data + * @param buf [IN] Read data + * @param num [IN] Number of bytes expected to be read + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMCPY_FAIL Memory Copy Failed + * @retval For details about other error codes, see hitls_error.h + */ +int32_t REC_TlsReadNbytes(TLS_Ctx *ctx, REC_Type recordType, uint8_t *buf, uint32_t num); + +#ifdef __cplusplus +} +#endif + +#endif /* REC_H */ diff --git a/tls/record/src/rec_alert.c b/tls/record/src/rec_alert.c new file mode 100644 index 00000000..f8becae1 --- /dev/null +++ b/tls/record/src/rec_alert.c @@ -0,0 +1,47 @@ +/* + * 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_error.h" +#include "tls.h" + +int32_t CovertRecordAlertToReturnValue(ALERT_Description description) +{ + switch (description) { + case ALERT_PROTOCOL_VERSION: + return HITLS_REC_INVALID_PROTOCOL_VERSION; + case ALERT_BAD_RECORD_MAC: + return HITLS_REC_BAD_RECORD_MAC; + case ALERT_DECODE_ERROR: + return HITLS_REC_DECODE_ERROR; + case ALERT_RECORD_OVERFLOW: + return HITLS_REC_RECORD_OVERFLOW; + case ALERT_UNEXPECTED_MESSAGE: + return HITLS_REC_ERR_RECV_UNEXPECTED_MSG; + default: + return HITLS_REC_INVLAID_RECORD; + } +} + +int32_t RecordSendAlertMsg(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description) +{ + /* RFC6347 4.1.2.7. Handling Invalid Records: + We choose to discard invalid dtls record message and do not generate alerts. */ + if (IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + return HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } else { + ctx->method.sendAlert(ctx, level, description); + return CovertRecordAlertToReturnValue(description); + } +} diff --git a/tls/record/src/rec_alert.h b/tls/record/src/rec_alert.h new file mode 100644 index 00000000..07ea90ad --- /dev/null +++ b/tls/record/src/rec_alert.h @@ -0,0 +1,43 @@ +/* + * 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 REC_ALERT_H +#define REC_ALERT_H + +#include +#include "tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief record Send an alert and determine whether to discard invalid records + * based on RFC6347 4.1.2.7. Handling Invalid Records + * + * @param ctx [IN] tls Context + * @param level [IN] Alert level + * @param description [IN] alert Description + * + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY Discarding message + * @retval Other invalid message error codes, such as HITLS_REC_INVLAID_RECORD and HITLS_REC_INVALID_PROTOCOL_VERSION + */ +int32_t RecordSendAlertMsg(TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tls/record/src/rec_buf.c b/tls/record/src/rec_buf.c new file mode 100644 index 00000000..65cbc9d8 --- /dev/null +++ b/tls/record/src/rec_buf.c @@ -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. + */ + +#include "securec.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "tls.h" +#include "record.h" +#include "rec_buf.h" + +RecBuf *RecBufNew(uint32_t bufSize) +{ + RecBuf *buf = (RecBuf *)BSL_SAL_Calloc(1, sizeof(RecBuf)); + if (buf == NULL) { + return NULL; + } + + buf->buf = (uint8_t *)BSL_SAL_Calloc(1, bufSize); + if (buf->buf == NULL) { + BSL_SAL_FREE(buf); + return NULL; + } + + buf->bufSize = bufSize; + return buf; +} + +void RecBufFree(RecBuf *buf) +{ + if (buf != NULL) { + BSL_SAL_FREE(buf->buf); + BSL_SAL_FREE(buf); + } + return; +} + +void RecBufClean(RecBuf *buf) +{ + buf->start = 0; + buf->end = 0; + return; +} \ No newline at end of file diff --git a/tls/record/src/rec_buf.h b/tls/record/src/rec_buf.h new file mode 100644 index 00000000..66d255ab --- /dev/null +++ b/tls/record/src/rec_buf.h @@ -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. + */ + +#ifndef REC_BUF_H +#define REC_BUF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + uint8_t *buf; + uint32_t bufSize; + + uint32_t start; + uint32_t end; + + uint32_t singleRecStart; + uint32_t singleRecEnd; +} RecBuf; +/** + * @brief Allocate buffer + * + * @param bufSize [IN] buffer size + * + * @return RecBuf Buffer handle + */ +RecBuf *RecBufNew(uint32_t bufSize); + +/** + * @brief Release the buffer + * + * @param buf [IN] Buffer handle. The buffer is released by the invoker + */ +void RecBufFree(RecBuf *buf); + +/** + * @brief Release the data in buffer + * + * @param buf [IN] Buffer handle + */ +void RecBufClean(RecBuf *buf); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/record/src/rec_conn.c b/tls/record/src/rec_conn.c new file mode 100644 index 00000000..cbeb204c --- /dev/null +++ b/tls/record/src/rec_conn.c @@ -0,0 +1,1166 @@ +/* + * 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 +#include "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "crypt.h" +#include "record.h" +#include "rec_alert.h" +#include "rec_conn.h" + + +#define KEY_EXPANSION_LABEL "key expansion" + +#define AEAD_AAD_TLS12_SIZE 13u /* TLS1.2 AEAD additional_data length */ +#define AEAD_AAD_TLS13_SIZE 5u /* TLS1.3 AEAD additional_data length */ +#define AEAD_AAD_MAX_SIZE AEAD_AAD_TLS12_SIZE +#define AEAD_NONCE_SIZE 12u /* The length of the AEAD nonce is fixed to 12 */ + +#define CBC_PADDING_LEN_TAG_SIZE 1u +#define CBC_MAC_HEADER_LEN 13U + +RecConnState *RecConnStateNew(void) +{ + RecConnState *state = (RecConnState *)BSL_SAL_Calloc(1, sizeof(RecConnState)); + if (state == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15382, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record conn:malloc fail.", 0, 0, 0, 0); + return NULL; + } + return state; +} + +void RecConnStateFree(RecConnState *state) +{ + if (state == NULL) { + return; + } + /* Clear sensitive information */ + BSL_SAL_CleanseData(state->suiteInfo, sizeof(RecConnSuitInfo)); + BSL_SAL_FREE(state->suiteInfo); + BSL_SAL_FREE(state); + return; +} + +uint64_t RecConnGetSeqNum(const RecConnState *state) +{ + return state->seq; +} + +void RecConnSetSeqNum(RecConnState *state, uint64_t seq) +{ + state->seq = seq; +} + +#ifndef HITLS_NO_DTLS12 +uint16_t RecConnGetEpoch(const RecConnState *state) +{ + return state->epoch; +} + +void RecConnSetEpoch(RecConnState *state, uint16_t epoch) +{ + state->epoch = epoch; +} +#endif + +int32_t RecConnStateSetCipherInfo(RecConnState *state, RecConnSuitInfo *suitInfo) +{ + /* Clear sensitive information */ + BSL_SAL_CleanseData(state->suiteInfo, sizeof(RecConnSuitInfo)); + // Ensure that no memory leak occurs + BSL_SAL_FREE(state->suiteInfo); + + state->suiteInfo = (RecConnSuitInfo *)BSL_SAL_Malloc(sizeof(RecConnSuitInfo)); + if (state->suiteInfo == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15383, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Record conn: malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + (void)memcpy_s(state->suiteInfo, sizeof(RecConnSuitInfo), suitInfo, sizeof(RecConnSuitInfo)); + return HITLS_SUCCESS; +} + +// compute padding length form blockLen and plaintextLen +static uint8_t RecConnGetCbcPaddingLen(uint8_t blockLen, uint32_t plaintextLen) +{ + if (blockLen == 0) { + return 0; + } + uint8_t remainder = (plaintextLen + CBC_PADDING_LEN_TAG_SIZE) % blockLen; + if (remainder == 0) { + return 0; + } + return blockLen - remainder; +} + +uint32_t RecConnCalcCiphertextLen(const RecConnState *state, uint32_t plainLen, bool isEncThenMac) +{ + if (state == NULL || state->suiteInfo == NULL) { + return plainLen; + } + + uint32_t ciphertextLen = plainLen; + /* TLS 12: GenericBlockCipher, IV[SecurityParameters.record_iv_length] + TLS 13: nonce_explicit[SecurityParameters.record_iv_length] */ + uint32_t ivLen = state->suiteInfo->recordIvLength; + // MAC[SecurityParameters.mac_length] + uint32_t macLen = state->suiteInfo->macLen; + + if (state->suiteInfo->cipherType == HITLS_AEAD_CIPHER) { + ciphertextLen += (ivLen + macLen); + } else if (state->suiteInfo->cipherType == HITLS_CBC_CIPHER) { + ciphertextLen += ivLen; + // GenericBlockCipher.padding_length, used for CBC cipher + uint8_t paddingLen = 0; + if (isEncThenMac) { + paddingLen = RecConnGetCbcPaddingLen(state->suiteInfo->blockLength, ciphertextLen); + ciphertextLen += (paddingLen + CBC_PADDING_LEN_TAG_SIZE + macLen); + } else { + ciphertextLen += macLen; + paddingLen = RecConnGetCbcPaddingLen(state->suiteInfo->blockLength, ciphertextLen); + ciphertextLen += (paddingLen + CBC_PADDING_LEN_TAG_SIZE); + } + } + + return ciphertextLen; +} + +/** + * @brief Calculate the plaintext length or its upperbound from the ciphertext length + * @param state [IN] RecState context, including cipher suite information + * @param ctLen [IN] ciphertext length + * @return Exact plaintext length for AEAD_CIPHER case, upper bound length for CBC_CIPHER + */ +static uint32_t CalcPlaintextLenUpperBound(const RecConnState *state, uint32_t ctLen) +{ + if (state == NULL || state->suiteInfo == NULL) { + return ctLen; + } + uint32_t ptLenUpperBound = ctLen; + uint32_t ivLen = state->suiteInfo->recordIvLength; + // MAC[SecurityParameters.mac_length] + uint32_t macLen = state->suiteInfo->macLen; + if (state->suiteInfo->cipherType == HITLS_AEAD_CIPHER) { + ptLenUpperBound -= (ivLen + macLen); + } else if (state->suiteInfo->cipherType == HITLS_CBC_CIPHER) { + ptLenUpperBound -= ivLen; + /* paddingLen for CBC cipher ranges from 0 to (blockSize - 1), let it be zero to compute + the upper bound of plaintextLen when using CBC CIPHER */ + ptLenUpperBound -= (CBC_PADDING_LEN_TAG_SIZE + macLen); + } + return ptLenUpperBound > REC_MAX_PLAIN_TEXT_LENGTH ? REC_MAX_PLAIN_TEXT_LENGTH : ptLenUpperBound; +} + +static int32_t AeadGetNonce(const RecConnState *state, uint8_t *nonce, uint8_t nonceLen, + const uint8_t *seq, uint8_t seqLen) +{ + uint8_t fixedIvLength = state->suiteInfo->fixedIvLength; + uint8_t recordIvLength = state->suiteInfo->recordIvLength; + + if ((fixedIvLength + recordIvLength) != nonceLen) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_AEAD_NONCE_PARAM); + return HITLS_REC_ERR_AEAD_NONCE_PARAM; // The caller should ensure that the input is correct + } + + if (recordIvLength == seqLen) { + /** + * According to the RFC5116 && RFC5288 AEAD_AES_128_GCM/AEAD_AES_256_GCM definition, the nonce length is fixed + * to 12. 4 bytes + 8bytes(64 bits record sequence number, big endian) = 12 bytes 4 bytes the implicit part be + * derived from iv. The first 4 bytes of the IV are obtained. + */ + (void)memcpy_s(nonce, nonceLen, state->suiteInfo->iv, fixedIvLength); + (void)memcpy_s(&nonce[fixedIvLength], recordIvLength, seq, seqLen); + return HITLS_SUCCESS; + } else if (recordIvLength == 0) { + /** + * (same as defined in RFC7905 AEAD_CHACHA20_POLY1305) + * The per-record nonce for the AEAD defined in RFC8446 5.3 + * First 4 bytes (all 0s) + Last 8bytes(64 bits record sequence number, big endian) = 12 bytes + * Perform XOR with the 12 bytes IV. The result is nonce. + */ + // First four bytes (all 0s) + (void)memset_s(&nonce[0], nonceLen, 0, 4); + // First 4 bytes (all 0s) + Last 8 bytes (64-bit record sequence number, big endian) + (void)memcpy_s(&nonce[4], nonceLen - 4, seq, seqLen); + for (uint32_t i = 0; i < nonceLen; i++) { + nonce[i] = nonce[i] ^ state->suiteInfo->iv[i]; + } + return HITLS_SUCCESS; + } + + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_AEAD_NONCE_PARAM); + return HITLS_REC_ERR_AEAD_NONCE_PARAM; +} + +static void AeadGetAad(uint8_t *aad, uint32_t *aadLen, const REC_TextInput *input, uint32_t plainDataLen) +{ + /** + TLS1.3 generation + additional_data = TLSCiphertext.opaque_type || TLSCiphertext.legacy_record_version || TLSCiphertext.length + */ + if (input->negotiatedVersion == HITLS_VERSION_TLS13) { + aad[0] = input->type; // The 0th byte is the record type + BSL_Uint16ToByte(input->version, &aad[1]); // The first and second bytes of indicate the version number + BSL_Uint16ToByte((uint16_t)plainDataLen, &aad[3]); // The third and fourth bytes of indicate the data length + *aadLen = AEAD_AAD_TLS13_SIZE; + return; + } + + /* non-TLS1.3 generation additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + + * TLSCompressed.length */ + (void)memcpy_s(aad, AEAD_AAD_MAX_SIZE, input->seq, REC_CONN_SEQ_SIZE); + aad[8] = input->type; // The eighth byte indicates the record type + BSL_Uint16ToByte(input->version, &aad[9]); // The ninth and tenth bytes indicate the version number. + BSL_Uint16ToByte((uint16_t)plainDataLen, &aad[11]); // The 11th and 12th bytse indicate the data length. + *aadLen = AEAD_AAD_TLS12_SIZE; + return; +} + +/** + * @brief AEAD encryption + * + * @param state [IN] RecConnState Context + * @param input [IN] Input data before encryption + * @param cipherText [OUT] Encrypted content + * @param cipherTextLen [IN] Length after encryption + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_INTERNAL_EXCEPTION: null pointer + * @retval HITLS_MEMCPY_FAIL The copy fails. + * @retval For details, see SAL_CRYPT_Encrypt. + */ +static int32_t RecConnAeadEncrypt(const RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText, + uint32_t cipherTextLen) +{ + /** Initialize the encryption length offset */ + uint32_t cipherOffset = 0u; + HITLS_CipherParameters cipherParam = {0}; + cipherParam.type = state->suiteInfo->cipherType; + cipherParam.algo = state->suiteInfo->cipherAlg; + cipherParam.key = (const uint8_t *)state->suiteInfo->key; + cipherParam.keyLen = state->suiteInfo->encKeyLen; + + /** During AEAD encryption, the sequence number is used as the explicit IV */ + if (state->suiteInfo->recordIvLength > 0u) { + if (memcpy_s(&cipherText[cipherOffset], cipherTextLen, plainMsg->seq, REC_CONN_SEQ_SIZE) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15384, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record encrypt:memcpy fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + cipherOffset += REC_CONN_SEQ_SIZE; + } + + /** Calculate NONCE */ + uint8_t nonce[AEAD_NONCE_SIZE] = {0}; + int32_t ret = AeadGetNonce(state, nonce, sizeof(nonce), plainMsg->seq, REC_CONN_SEQ_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15385, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record encrypt:get nonce failed.", 0, 0, 0, 0); + return ret; + } + cipherParam.iv = nonce; + cipherParam.ivLen = AEAD_NONCE_SIZE; + + /* Calculate additional_data */ + uint8_t aad[AEAD_AAD_MAX_SIZE]; + uint32_t aadLen = AEAD_AAD_MAX_SIZE; + uint32_t textLen = (plainMsg->negotiatedVersion == HITLS_VERSION_TLS13) ? cipherTextLen : plainMsg->textLen; + AeadGetAad(aad, &aadLen, plainMsg, textLen); + cipherParam.aad = aad; + cipherParam.aadLen = aadLen; + + /** Calculate the encryption length */ + uint32_t cipherLen = cipherTextLen - cipherOffset; + uint32_t outLen = cipherLen; + /** Encryption */ + ret = SAL_CRYPT_Encrypt(&cipherParam, plainMsg->text, plainMsg->textLen, &cipherText[cipherOffset], &outLen); + /* Clear sensitive information */ + BSL_SAL_CleanseData(nonce, AEAD_NONCE_SIZE); + BSL_SAL_CleanseData(aad, AEAD_AAD_MAX_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15386, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record:encrypt record error.", 0, 0, 0, 0); + return ret; + } + + if (outLen != cipherLen) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_ENCRYPT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15387, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record:encrypt error. outLen:%u cipherLen:%u", outLen, cipherLen, 0, 0); + return HITLS_REC_ERR_ENCRYPT; + } + + return HITLS_SUCCESS; +} + +static uint32_t GetHashOfMACAlgorithm(HITLS_MacAlgo macAlgo) +{ + switch (macAlgo) { + case HITLS_MAC_1: + return HITLS_HASH_SHA1; + case HITLS_MAC_256: + return HITLS_HASH_SHA_256; + case HITLS_MAC_224: + return HITLS_HASH_SHA_224; + case HITLS_MAC_384: + return HITLS_HASH_SHA_384; + case HITLS_MAC_512: + return HITLS_HASH_SHA_512; +#ifndef HITLS_NO_TLCP11 + case HITLS_MAC_SM3: + return HITLS_HASH_SM3; +#endif + default: + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15388, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CBC encrypt error: unsupport MAC algorithm = %u.", macAlgo, 0, 0, 0); + break; + } + return HITLS_HASH_BUTT; +} + +int32_t RecConnGenerateMac(const RecConnState *state, const REC_TextInput *plainMsg, uint8_t *mac, uint32_t *macLen) +{ + int32_t ret = HITLS_SUCCESS; + uint8_t header[CBC_MAC_HEADER_LEN] = {0}; + uint32_t offset = 0; + if (memcpy_s(header, CBC_MAC_HEADER_LEN, plainMsg->seq, REC_CONN_SEQ_SIZE) != EOK) { + return HITLS_MEMCPY_FAIL; + } + offset += REC_CONN_SEQ_SIZE; + + header[offset] = plainMsg->type; // The eighth byte is the record type + offset++; + BSL_Uint16ToByte(plainMsg->version, &header[offset]); // The 9th and 10th bytes are version numbers + offset += sizeof(uint16_t); + BSL_Uint16ToByte((uint16_t)plainMsg->textLen, &header[offset]); // The 11th and 12th bytes are the data length + + HITLS_HashAlgo hashAlgo = GetHashOfMACAlgorithm(state->suiteInfo->macAlg); + if (hashAlgo == HITLS_HASH_BUTT) { + return HITLS_REC_ERR_GENERATE_MAC; + } + + HITLS_HMAC_Ctx *hmacCtx = SAL_CRYPT_HmacInit(hashAlgo, state->suiteInfo->macKey, state->suiteInfo->macKeyLen); + if (hmacCtx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_GENERATE_MAC); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15389, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CBC encrypt error: HMAC init fail, hashAlgo = %u.", hashAlgo, 0, 0, 0); + return HITLS_REC_ERR_GENERATE_MAC; + } + + ret = SAL_CRYPT_HmacUpdate(hmacCtx, header, CBC_MAC_HEADER_LEN); + if (ret != HITLS_SUCCESS) { + SAL_CRYPT_HmacFree(hmacCtx); + return ret; + } + + ret = SAL_CRYPT_HmacUpdate(hmacCtx, plainMsg->text, plainMsg->textLen); + if (ret != HITLS_SUCCESS) { + SAL_CRYPT_HmacFree(hmacCtx); + return ret; + } + + ret = SAL_CRYPT_HmacFinal(hmacCtx, mac, macLen); + if (ret != HITLS_SUCCESS) { + SAL_CRYPT_HmacFree(hmacCtx); + return ret; + } + + SAL_CRYPT_HmacFree(hmacCtx); + return HITLS_SUCCESS; +} + +static void RecConnInitCipherParam(HITLS_CipherParameters *cipherParam, const RecConnState *state) +{ + cipherParam->type = state->suiteInfo->cipherType; + cipherParam->algo = state->suiteInfo->cipherAlg; + cipherParam->key = state->suiteInfo->key; + cipherParam->keyLen = state->suiteInfo->encKeyLen; + cipherParam->iv = state->suiteInfo->iv; + cipherParam->ivLen = state->suiteInfo->fixedIvLength; +} + +static void RecConnInitGenerateMacInput(const REC_TextInput *in, const uint8_t *text, uint32_t textLen, + REC_TextInput *out) +{ + out->version = in->version; + out->negotiatedVersion = in->negotiatedVersion; + out->isEncryptThenMac = in->isEncryptThenMac; + out->type = in->type; + out->text = text; + out->textLen = textLen; + for (uint32_t i = 0u; i < REC_CONN_SEQ_SIZE; i++) { + out->seq[i] = in->seq[i]; + } +} + +static int32_t RecConnCopyIV(const RecConnState *state, uint8_t *cipherText, uint32_t cipherTextLen) +{ + if (!state->suiteInfo->isExportIV) { + SAL_CRYPT_Rand(state->suiteInfo->iv, state->suiteInfo->fixedIvLength); + } + /* The IV set by the user can only be used once */ + state->suiteInfo->isExportIV = 0; + if (memcpy_s(cipherText, cipherTextLen, state->suiteInfo->iv, state->suiteInfo->fixedIvLength) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15847, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: copy iv fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + return HITLS_SUCCESS; +} + +/* Data that needs to be encrypted (after filling the mac) */ +static int32_t GenerateCbcPlainTextAfterMac(const RecConnState *state, const REC_TextInput *plainMsg, + uint32_t cipherTextLen, uint8_t *plainText, uint32_t *textLen) +{ + /* Fill content */ + if (memcpy_s(plainText, cipherTextLen, plainMsg->text, plainMsg->textLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15898, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: memcpy plainMsg fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + uint32_t plainTextLen = plainMsg->textLen; + + /* Fill MAC */ + uint32_t macLen = state->suiteInfo->macLen; + REC_TextInput input = {0}; + RecConnInitGenerateMacInput(plainMsg, plainMsg->text, plainMsg->textLen, &input); + int32_t ret = RecConnGenerateMac(state, &input, &plainText[plainTextLen], &macLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + plainTextLen += macLen; + + /* Fill padding and padding length */ + uint8_t paddingLen = RecConnGetCbcPaddingLen(state->suiteInfo->blockLength, plainTextLen); + uint32_t count = paddingLen + CBC_PADDING_LEN_TAG_SIZE; + if (memset_s(&plainText[plainTextLen], cipherTextLen - plainTextLen, paddingLen, count) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_ENCRYPT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15393, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: memset padding fail.", 0, 0, 0, 0); + return HITLS_REC_ERR_ENCRYPT; + } + plainTextLen += count; + *textLen = plainTextLen; + return HITLS_SUCCESS; +} + +int32_t RecConnCbcMacThenEncrypt(const RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText, + uint32_t cipherTextLen) +{ + uint8_t *plainText = BSL_SAL_Calloc(1u, cipherTextLen); + if (plainText == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15390, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: out of memory.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + uint32_t plainTextLen = 0; + int32_t ret = GenerateCbcPlainTextAfterMac(state, plainMsg, cipherTextLen, plainText, &plainTextLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(plainText); + return ret; + } + + uint32_t offset = 0; + ret = RecConnCopyIV(state, cipherText, cipherTextLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(plainText); + return ret; + } + offset += state->suiteInfo->fixedIvLength; + + uint32_t encLen = cipherTextLen - offset; + HITLS_CipherParameters cipherParam = {0}; + RecConnInitCipherParam(&cipherParam, state); + ret = SAL_CRYPT_Encrypt(&cipherParam, plainText, plainTextLen, &cipherText[offset], &encLen); + BSL_SAL_FREE(plainText); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15391, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CBC encrypt record error.", 0, 0, 0, 0); + return ret; + } + + if (encLen != (cipherTextLen - offset)) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_ENCRYPT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15922, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encrypt record (length) error.", 0, 0, 0, 0); + return HITLS_REC_ERR_ENCRYPT; + } + + return HITLS_SUCCESS; +} + +/* Data that needs to be encrypted (do not fill MAC) */ +static int32_t GenerateCbcPlainTextBeforeMac(const RecConnState *state, const REC_TextInput *plainMsg, + uint32_t cipherTextLen, uint8_t *plainText, uint32_t *textLen) +{ + /* fill content */ + if (memcpy_s(plainText, cipherTextLen, plainMsg->text, plainMsg->textLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15392, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: memcpy plainMsg fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + uint32_t plainTextLen = plainMsg->textLen; + + /* fill padding and padding length */ + uint8_t paddingLen = RecConnGetCbcPaddingLen(state->suiteInfo->blockLength, plainTextLen); + uint32_t count = paddingLen + CBC_PADDING_LEN_TAG_SIZE; + if (memset_s(&plainText[plainTextLen], cipherTextLen - plainTextLen, paddingLen, count) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_ENCRYPT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15904, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: memset padding fail.", 0, 0, 0, 0); + return HITLS_REC_ERR_ENCRYPT; + } + plainTextLen += count; + *textLen = plainTextLen; + return HITLS_SUCCESS; +} + +static int32_t PreparePlainText(const RecConnState *state, const REC_TextInput *plainMsg, uint32_t cipherTextLen, + uint8_t **plainText, uint32_t *plainTextLen) +{ + *plainText = BSL_SAL_Calloc(1u, cipherTextLen); + if (*plainText == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15927, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC encrypt error: out of memory.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + int32_t ret = GenerateCbcPlainTextBeforeMac(state, plainMsg, cipherTextLen, *plainText, plainTextLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(*plainText); + return ret; + } + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcEncryptThenMac(const RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText, + uint32_t cipherTextLen) +{ + uint8_t *plainText = NULL; + uint32_t plainTextLen = 0; + + int32_t ret = PreparePlainText(state, plainMsg, cipherTextLen, &plainText, &plainTextLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t offset = 0; + ret = RecConnCopyIV(state, cipherText, cipherTextLen); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(plainText); + return ret; + } + offset += state->suiteInfo->fixedIvLength; + + uint32_t macLen = state->suiteInfo->macLen; + uint32_t encLen = cipherTextLen - offset - macLen; + HITLS_CipherParameters cipherParam = {0}; + RecConnInitCipherParam(&cipherParam, state); + ret = SAL_CRYPT_Encrypt(&cipherParam, plainText, plainTextLen, &cipherText[offset], &encLen); + BSL_SAL_FREE(plainText); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15848, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "CBC encrypt record error.", 0, 0, 0, 0); + return ret; + } + + if (encLen != (cipherTextLen - offset - macLen)) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_ENCRYPT); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15903, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "encrypt record (length) error.", 0, 0, 0, 0); + return HITLS_REC_ERR_ENCRYPT; + } + + /* fill MAC */ + REC_TextInput input = {0}; + RecConnInitGenerateMacInput(plainMsg, cipherText, cipherTextLen - macLen, &input); + ret = RecConnGenerateMac(state, &input, &cipherText[offset + encLen], &macLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +int32_t RecConnEncrypt(RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText, uint32_t cipherTextLen) +{ + if (state->suiteInfo == NULL) { // No cipher suite, plaintext + if (memcpy_s(cipherText, cipherTextLen, plainMsg->text, plainMsg->textLen) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15926, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record:memcpy fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + return HITLS_SUCCESS; + } + if (state->suiteInfo->cipherType == HITLS_AEAD_CIPHER) { + return RecConnAeadEncrypt(state, plainMsg, cipherText, cipherTextLen); + } else if (state->suiteInfo->cipherType == HITLS_CBC_CIPHER) { + if (plainMsg->isEncryptThenMac) { + return RecConnCbcEncryptThenMac(state, plainMsg, cipherText, cipherTextLen); + } else { + return RecConnCbcMacThenEncrypt(state, plainMsg, cipherText, cipherTextLen); + } + } + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_SUPPORT_CIPHER); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15394, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record:cipher is not supported.", 0, 0, 0, 0); + return HITLS_REC_ERR_NOT_SUPPORT_CIPHER; +} + +/** + * @brief AEAD decryption + * + * @param ctx [IN] tls Context + * @param state [IN] RecConnState Context + * @param input [IN] Input data before decryption + * @param data [OUT] Decrypted content + * @param dataLen [OUT] IN: length of data OUT: length after decryption + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_MEMCPY_FAIL The copy fails. + * @retval HITLS_REC_BAD_RECORD_MAC Invalid MAC + */ +static int32_t RecConnAeadDecrypt(TLS_Ctx *ctx, const RecConnState *state, const REC_TextInput *cryptMsg, + uint8_t *data, uint32_t *dataLen) +{ + /** Initialize the encryption length offset */ + uint32_t cipherOffset = 0u; + HITLS_CipherParameters cipherParam = {0}; + cipherParam.type = state->suiteInfo->cipherType; + cipherParam.algo = state->suiteInfo->cipherAlg; + cipherParam.key = (const uint8_t *)state->suiteInfo->key; + cipherParam.keyLen = state->suiteInfo->encKeyLen; + + /** Read the explicit IV during AEAD decryption */ + const uint8_t *recordIv; + if (state->suiteInfo->recordIvLength > 0u) { + recordIv = &cryptMsg->text[cipherOffset]; + cipherOffset += REC_CONN_SEQ_SIZE; + } else { + // If no IV is displayed, use the serial number + recordIv = cryptMsg->seq; + } + + /** Calculate NONCE */ + uint8_t nonce[AEAD_NONCE_SIZE] = {0}; + int32_t ret = AeadGetNonce(state, nonce, sizeof(nonce), recordIv, REC_CONN_SEQ_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15395, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record decrypt:get nonce failed.", 0, 0, 0, 0); + return ret; + } + cipherParam.iv = nonce; + cipherParam.ivLen = AEAD_NONCE_SIZE; + + /* Calculate additional_data */ + uint8_t aad[AEAD_AAD_MAX_SIZE] = {0}; + uint32_t aadLen = AEAD_AAD_MAX_SIZE; + /** + Definition of additional_data + tls1.2 additional_data = seq_num + TLSCompressed.type + + TLSCompressed.version + TLSCompressed.length; + tls1.3 additional_data = TLSCiphertext.opaque_type || + TLSCiphertext.legacy_record_version || + TLSCiphertext.length + diff: length + */ + uint32_t plainDataLen = cryptMsg->textLen; + if (cryptMsg->negotiatedVersion != HITLS_VERSION_TLS13) { + plainDataLen = cryptMsg->textLen - state->suiteInfo->recordIvLength - state->suiteInfo->macLen; + } + AeadGetAad(aad, &aadLen, cryptMsg, plainDataLen); + cipherParam.aad = aad; + cipherParam.aadLen = aadLen; + + /** Calculate the encryption length: GenericAEADCipher.content + aead tag */ + uint32_t cipherLen = cryptMsg->textLen - cipherOffset; + /** Decryption */ + ret = SAL_CRYPT_Decrypt(&cipherParam, &cryptMsg->text[cipherOffset], cipherLen, data, dataLen); + /* Clear sensitive information */ + BSL_SAL_CleanseData(nonce, AEAD_NONCE_SIZE); + BSL_SAL_CleanseData(aad, AEAD_AAD_MAX_SIZE); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15396, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "decrypt record error. ret:%d", ret, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + return HITLS_REC_BAD_RECORD_MAC; + } + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcCheckCryptMsg(TLS_Ctx *ctx, const RecConnState *state, const REC_TextInput *cryptMsg, + bool isEncryptThenMac) +{ + uint8_t offset = 0; + if (isEncryptThenMac) { + offset = state->suiteInfo->macLen; + } + if ((state->suiteInfo->blockLength == 0) || ((cryptMsg->textLen - offset) % state->suiteInfo->blockLength != 0)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15397, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: block length = %u, cipher text length = %u.", + state->suiteInfo->blockLength, cryptMsg->textLen, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcCheckDecryptPadding(TLS_Ctx *ctx, const REC_TextInput *cryptMsg, uint8_t *data, + uint32_t plaintextLen, uint32_t offset) +{ + const RecConnState *state = ctx->recCtx->readStates.currentState; + uint8_t mac[MAX_DIGEST_SIZE] = {0}; + uint32_t macLen = MAX_DIGEST_SIZE; + uint8_t paddingLen = data[plaintextLen - 1]; + + if (cryptMsg->isEncryptThenMac && (plaintextLen < paddingLen + CBC_PADDING_LEN_TAG_SIZE)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15399, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: ciphertext len = %u, plaintext len = %u, mac len = %u, padding len = %u.", + cryptMsg->textLen - offset - state->suiteInfo->macLen, plaintextLen, state->suiteInfo->macLen, paddingLen); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + if (!cryptMsg->isEncryptThenMac && + (plaintextLen < state->suiteInfo->macLen + paddingLen + CBC_PADDING_LEN_TAG_SIZE)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15928, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: ciphertext len = %u, plaintext len = %u, mac len = %u, padding len = %u.", + cryptMsg->textLen - offset, plaintextLen, state->suiteInfo->macLen, paddingLen); + /* Anti-side channel attack: Calculate the MAC address even if the padding is incorrect */ + (void)RecConnGenerateMac(state, cryptMsg, mac, &macLen); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + for (uint32_t i = 1; i <= paddingLen; i++) { + if (data[plaintextLen - 1 - i] != paddingLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15400, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: padding len = %u, %u-to-last padding data = %u.", + paddingLen, i, data[plaintextLen - 1 - i], 0); + /* Anti-side channel attack: Calculate the MAC address even if the padding is incorrect */ + if (!cryptMsg->isEncryptThenMac) { + (void)RecConnGenerateMac(state, cryptMsg, mac, &macLen); + } + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + } + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcCheckAfterDecryptMac(TLS_Ctx *ctx, const REC_TextInput *cryptMsg, uint32_t plaintextLen, + uint8_t *data, uint32_t *dataLen) +{ + const RecConnState *state = ctx->recCtx->readStates.currentState; + uint8_t paddingLen = data[plaintextLen - 1]; + uint8_t mac[MAX_DIGEST_SIZE] = {0}; + uint32_t macLen = MAX_DIGEST_SIZE; + + uint32_t contentLen = plaintextLen - (state->suiteInfo->macLen + paddingLen + CBC_PADDING_LEN_TAG_SIZE); + REC_TextInput input = {0}; + RecConnInitGenerateMacInput(cryptMsg, data, contentLen, &input); + int32_t ret = RecConnGenerateMac(state, &input, mac, &macLen); + if (ret != HITLS_SUCCESS) { + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + } + + if (macLen != state->suiteInfo->macLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15401, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: macLen = %u, required len = %u.", macLen, state->suiteInfo->macLen, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + if (memcmp(&data[contentLen], mac, macLen) != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15402, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: MAC check failed.", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + *dataLen = contentLen; + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcDecryptByMacThenEncrypt(TLS_Ctx *ctx, const RecConnState *state, const REC_TextInput *cryptMsg, + uint8_t *data, uint32_t *dataLen) +{ + /* Check whether the ciphertext length is an integral multiple of the ciphertext block length */ + int32_t ret = RecConnCbcCheckCryptMsg(ctx, state, cryptMsg, false); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t offset = 0; /* Decryption start position */ + uint32_t plaintextLen = *dataLen; /* plaintext length */ + HITLS_CipherParameters cipherParam = {0}; + RecConnInitCipherParam(&cipherParam, state); + /* In TLS1.2 and later versions, explicit iv is used as the first ciphertext block. Therefore, the first + * ciphertext block does not need to be decrypted */ + cipherParam.iv = cryptMsg->text; + offset = state->suiteInfo->fixedIvLength; + + ret = SAL_CRYPT_Decrypt(&cipherParam, &cryptMsg->text[offset], cryptMsg->textLen - offset, data, &plaintextLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15398, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error.", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + /* Check padding and padding length */ + ret = RecConnCbcCheckDecryptPadding(ctx, cryptMsg, data, plaintextLen, offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check MAC */ + ret = RecConnCbcCheckAfterDecryptMac(ctx, cryptMsg, plaintextLen, data, dataLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcCheckBeforeDecryptMac(TLS_Ctx *ctx, const RecConnState *state, const REC_TextInput *cryptMsg) +{ + uint8_t mac[MAX_DIGEST_SIZE] = {0}; + uint32_t macLen = MAX_DIGEST_SIZE; + uint32_t contentLen = cryptMsg->textLen - state->suiteInfo->macLen; + REC_TextInput input = {0}; + RecConnInitGenerateMacInput(cryptMsg, cryptMsg->text, contentLen, &input); + int32_t ret = RecConnGenerateMac(state, &input, mac, &macLen); + if (ret != HITLS_SUCCESS) { + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR); + } + + if (macLen != state->suiteInfo->macLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15929, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: macLen = %u, required len = %u.", + macLen, state->suiteInfo->macLen, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + if (memcmp(&cryptMsg->text[contentLen], mac, macLen) != 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15942, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error: MAC check failed.", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcDecryptByEncryptThenMac(TLS_Ctx *ctx, const RecConnState *state, const REC_TextInput *cryptMsg, + uint8_t *data, uint32_t *dataLen) +{ + /* Check MAC */ + int32_t ret = RecConnCbcCheckBeforeDecryptMac(ctx, state, cryptMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check whether the ciphertext length is an integral multiple of the ciphertext block length */ + ret = RecConnCbcCheckCryptMsg(ctx, state, cryptMsg, true); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t offset = 0; /* Decryption start position */ + uint32_t plaintextLen = *dataLen; /* plaintext length */ + uint8_t macLen = state->suiteInfo->macLen; + HITLS_CipherParameters cipherParam = {0}; + RecConnInitCipherParam(&cipherParam, state); + /* In TLS1.2 and later versions, explicit iv is used as the first ciphertext block. Therefore, the first + * ciphertext block does not need to be decrypted */ + cipherParam.iv = cryptMsg->text; + offset = state->suiteInfo->fixedIvLength; + + ret = SAL_CRYPT_Decrypt(&cipherParam, &cryptMsg->text[offset], + cryptMsg->textLen - offset - macLen, data, &plaintextLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15915, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "record cbc mode decrypt error.", 0, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + return HITLS_REC_BAD_RECORD_MAC; + } + + /* Check padding and padding length */ + uint8_t paddingLen = data[plaintextLen - 1]; + ret = RecConnCbcCheckDecryptPadding(ctx, cryptMsg, data, plaintextLen, offset); + if (ret != HITLS_SUCCESS) { + return ret; + } + *dataLen = plaintextLen - paddingLen - CBC_PADDING_LEN_TAG_SIZE; + + return HITLS_SUCCESS; +} + +static int32_t RecConnCbcDecrypt(TLS_Ctx *ctx, const RecConnState *state, const REC_TextInput *cryptMsg, + uint8_t *data, uint32_t *dataLen) +{ + uint8_t *decryptData = BSL_SAL_Malloc(cryptMsg->textLen); + if (decryptData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15973, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC decrypt error: malloc decrypt data fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + uint32_t decryptDataLen = cryptMsg->textLen; + + int32_t ret; + if (ctx->negotiatedInfo.isEncryptThenMacRead) { + ret = RecConnCbcDecryptByEncryptThenMac(ctx, state, cryptMsg, decryptData, &decryptDataLen); + } else { + ret = RecConnCbcDecryptByMacThenEncrypt(ctx, state, cryptMsg, decryptData, &decryptDataLen); + } + + if (ret != HITLS_SUCCESS) { + BSL_SAL_Free(decryptData); + return ret; + } + + /* The user does not want the input data array to be overwritten by content other than the plaintext */ + if (memcpy_s(data, *dataLen, decryptData, decryptDataLen) != EOK) { + BSL_SAL_Free(decryptData); + BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15974, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record CBC decrypt error: memcpy decrypt data fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + *dataLen = decryptDataLen; + + BSL_SAL_Free(decryptData); + return HITLS_SUCCESS; +} + +int32_t RecConnDecrypt(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg, + uint8_t *data, uint32_t *dataLen) +{ + uint32_t bufSize = *dataLen; + uint32_t ciphertextLen = RecConnCalcCiphertextLen(state, 0, ctx->negotiatedInfo.isEncryptThenMacRead); + // The length of the record body to be decrypted must be greater than or equal to ciphertextLen + if (cryptMsg->textLen < ciphertextLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15403, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record decrypt: get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + if (state->suiteInfo == NULL) { // No ciphersuite + if (bufSize < cryptMsg->textLen) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15950, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW); + } + if (memcpy_s(data, bufSize, cryptMsg->text, cryptMsg->textLen) != EOK) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15404, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record decrypt:memcpy fail.", 0, 0, 0, 0); + return HITLS_MEMCPY_FAIL; + } + // If no encryption is required, the decrypted length is the plaintext length + *dataLen = cryptMsg->textLen; + return HITLS_SUCCESS; + } + uint32_t expectedPlaintextLen = CalcPlaintextLenUpperBound(state, cryptMsg->textLen); + if (expectedPlaintextLen > bufSize) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15346, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "expectedPlaintextLen(%u) > bufSize(%u)", expectedPlaintextLen, bufSize, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW); + } + if (state->suiteInfo->cipherType == HITLS_AEAD_CIPHER) { + return RecConnAeadDecrypt(ctx, state, cryptMsg, data, dataLen); + } else if (state->suiteInfo->cipherType == HITLS_CBC_CIPHER) { + return RecConnCbcDecrypt(ctx, state, cryptMsg, data, dataLen); + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15405, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record decrypt:cipher is not supported.", 0, 0, 0, 0); + return HITLS_REC_ERR_NOT_SUPPORT_CIPHER; +} + +static void PackSuitInfo(RecConnSuitInfo *suitInfo, const REC_SecParameters *param) +{ + suitInfo->macAlg = param->macAlg; + suitInfo->cipherAlg = param->cipherAlg; + suitInfo->cipherType = param->cipherType; + suitInfo->fixedIvLength = param->fixedIvLength; + suitInfo->encKeyLen = param->encKeyLen; + suitInfo->macKeyLen = param->macKeyLen; + suitInfo->blockLength = param->blockLength; + suitInfo->recordIvLength = param->recordIvLength; + suitInfo->macLen = param->macLen; + return; +} + +static void RecConnCalcWriteKey(const REC_SecParameters *param, uint8_t *keyBuf, uint32_t keyBufLen, + RecConnSuitInfo *client, RecConnSuitInfo *server) +{ + if (keyBufLen == 0) { + return; + } + uint32_t offset = 0; + uint32_t totalOffset = 2 * param->macKeyLen + 2 * param->encKeyLen + 2 * param->fixedIvLength; + if (keyBufLen < totalOffset) { + return; + } + + if (param->macKeyLen > 0u) { + if (memcpy_s(client->macKey, sizeof(client->macKey), keyBuf, param->macKeyLen) != EOK) { + return; + } + offset += param->macKeyLen; + if (memcpy_s(server->macKey, sizeof(server->macKey), keyBuf + offset, param->macKeyLen) != EOK) { + return; + } + offset += param->macKeyLen; + } + if (param->encKeyLen > 0u) { + if (memcpy_s(client->key, sizeof(client->key), keyBuf + offset, param->encKeyLen) != EOK) { + return; + } + offset += param->encKeyLen; + if (memcpy_s(server->key, sizeof(server->key), keyBuf + offset, param->encKeyLen) != EOK) { + return; + } + offset += param->encKeyLen; + } + if (param->fixedIvLength > 0u) { + if (memcpy_s(client->iv, sizeof(client->iv), keyBuf + offset, param->fixedIvLength) != EOK) { + return; + } + offset += param->fixedIvLength; + if (memcpy_s(server->iv, sizeof(server->iv), keyBuf + offset, param->fixedIvLength) != EOK) { + return; + } + } + PackSuitInfo(client, param); + PackSuitInfo(server, param); +} + +int32_t RecConnKeyBlockGen(const REC_SecParameters *param, RecConnSuitInfo *client, RecConnSuitInfo *server) +{ + /** Calculate the key length: 2MAC, 2key, 2IV */ + uint32_t keyLen = ((uint32_t)param->macKeyLen * 2) + ((uint32_t)param->encKeyLen * 2) + + ((uint32_t)param->fixedIvLength * 2); + if (keyLen == 0u || param->macKeyLen > sizeof(client->macKey) || + param->encKeyLen > sizeof(client->key) || param->fixedIvLength > sizeof(client->iv)) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_SUPPORT_CIPHER); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15943, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record Key: not support--length is invalid.", 0, 0, 0, 0); + return HITLS_REC_ERR_NOT_SUPPORT_CIPHER; + } + + /* Based on RFC5246 6.3 + key_block = PRF(SecurityParameters.master_secret, "key expansion", SecurityParameters.server_random + + SecurityParameters.client_random); + */ + CRYPT_KeyDeriveParameters keyDeriveParam = {0}; + keyDeriveParam.hashAlgo = param->prfAlg; + keyDeriveParam.secret = param->masterSecret; + keyDeriveParam.secretLen = REC_MASTER_SECRET_LEN; + keyDeriveParam.label = (const uint8_t *)KEY_EXPANSION_LABEL; + keyDeriveParam.labelLen = strlen(KEY_EXPANSION_LABEL); + + uint8_t randomValue[REC_RANDOM_LEN * 2]; + /** Random value of the replication server */ + (void)memcpy_s(randomValue, sizeof(randomValue), param->serverRandom, REC_RANDOM_LEN); + /** Random value of the replication client */ + (void)memcpy_s(&randomValue[REC_RANDOM_LEN], sizeof(randomValue) - REC_RANDOM_LEN, + param->clientRandom, REC_RANDOM_LEN); + + keyDeriveParam.seed = randomValue; + keyDeriveParam.seedLen = REC_RANDOM_LEN * 2; // Total length of 2 random numbers + + /** Maximum key length: 2MAC, 2key, 2IV */ + uint8_t keyBuf[REC_MAX_KEY_BLOCK_LEN]; + int32_t ret = SAL_CRYPT_PRF(&keyDeriveParam, keyBuf, keyLen); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15944, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record Key:generate fail.", 0, 0, 0, 0); + return ret; + } + + RecConnCalcWriteKey(param, keyBuf, REC_MAX_KEY_BLOCK_LEN, client, server); + BSL_SAL_CleanseData(keyBuf, sizeof(keyBuf)); + return HITLS_SUCCESS; +} + +static int32_t RecTLS13CalcWriteKey(HITLS_HashAlgo hashAlgo, const uint8_t *baseKey, uint32_t baseKeyLen, + uint8_t *key, uint32_t keyLen) +{ + uint8_t label[] = "key"; + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlgo; + deriveInfo.secret = baseKey; + deriveInfo.secretLen = baseKeyLen; + deriveInfo.label = label; + deriveInfo.labelLen = sizeof(label) - 1; + deriveInfo.seed = NULL; + deriveInfo.seedLen = 0; + return SAL_CRYPT_HkdfExpandLabel(&deriveInfo, key, keyLen); +} + +static int32_t RecTLS13CalcWriteIv(HITLS_HashAlgo hashAlgo, const uint8_t *baseKey, uint32_t baseKeyLen, + uint8_t *iv, uint32_t ivLen) +{ + uint8_t label[] = "iv"; + CRYPT_KeyDeriveParameters deriveInfo = {0}; + deriveInfo.hashAlgo = hashAlgo; + deriveInfo.secret = baseKey; + deriveInfo.secretLen = baseKeyLen; + deriveInfo.label = label; + deriveInfo.labelLen = sizeof(label) - 1; + deriveInfo.seed = NULL; + deriveInfo.seedLen = 0; + return SAL_CRYPT_HkdfExpandLabel(&deriveInfo, iv, ivLen); +} + +int32_t RecTLS13ConnKeyBlockGen(const REC_SecParameters *param, RecConnSuitInfo *suitInfo) +{ + const uint8_t *secret = (const uint8_t *)param->masterSecret; + uint32_t secretLen = SAL_CRYPT_DigestSize(param->prfAlg); + if (secretLen == 0) { + return HITLS_CRYPT_ERR_DIGEST; + } + uint32_t keyLen = param->encKeyLen; + uint32_t ivLen = param->fixedIvLength; + + if (secretLen > sizeof(param->masterSecret) || keyLen > sizeof(suitInfo->key) || ivLen > sizeof(suitInfo->iv)) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_SUPPORT_CIPHER); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15408, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "length is invalid.", 0, 0, 0, 0); + return HITLS_REC_ERR_NOT_SUPPORT_CIPHER; + } + + int32_t ret = RecTLS13CalcWriteKey(param->prfAlg, secret, secretLen, suitInfo->key, keyLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = RecTLS13CalcWriteIv(param->prfAlg, secret, secretLen, suitInfo->iv, ivLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + PackSuitInfo(suitInfo, param); + return HITLS_SUCCESS; +} diff --git a/tls/record/src/rec_conn.h b/tls/record/src/rec_conn.h new file mode 100644 index 00000000..2e971fce --- /dev/null +++ b/tls/record/src/rec_conn.h @@ -0,0 +1,226 @@ +/* + * 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 REC_CONN_H +#define REC_CONN_H + +#include +#include "rec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define REC_MAX_MAC_KEY_LEN 64 +#define REC_MAX_KEY_LENGTH 64 +#define REC_MAX_IV_LENGTH 16 +#define REC_MAX_KEY_BLOCK_LEN (REC_MAX_MAC_KEY_LEN * 2 + REC_MAX_KEY_LENGTH * 2 + REC_MAX_IV_LENGTH * 2) +#define MAX_SHA1_SIZE 20 +#define MAX_MD5_SIZE 16 + +#define REC_CONN_SEQ_SIZE 8u /* Sequence number size */ + +/** + * Cipher suite information, which is required for local encryption and decryption + * For details, see RFC5246 6.1 + */ +typedef struct { + HITLS_MacAlgo macAlg; /* MAC algorithm */ + HITLS_CipherAlgo cipherAlg; /* symmetric encryption algorithm */ + HITLS_CipherType cipherType; /* encryption algorithm type */ + + uint8_t macKey[REC_MAX_MAC_KEY_LEN]; + uint8_t key[REC_MAX_KEY_LENGTH]; + uint8_t iv[REC_MAX_IV_LENGTH]; + bool isExportIV; /* Used by the TTO feature. The IV does not need to be randomly + generated during CBC encryption If it is set by user */ + /* key length */ + uint8_t macKeyLen; /* Length of the MAC key. The length of the MAC key is 0 in AEAD algorithm */ + uint8_t encKeyLen; /* Length of the symmetric key */ + uint8_t fixedIvLength; /* iv length. It is the implicit IV length in AEAD algorithm */ + + /* result length */ + uint8_t blockLength; /* If the block length is not zero, the alignment should be handled */ + uint8_t recordIvLength; /* The explicit IV needs to be sent to the peer */ + uint8_t macLen; /* Add the length of the MAC. Or the tag length in AEAD */ +} RecConnSuitInfo; + +/* connection state */ +typedef struct { + RecConnSuitInfo *suiteInfo; /* Cipher suite information */ + uint64_t seq; /* tls: 8 byte sequence number or dtls: 6 byte seq */ + +#ifndef HITLS_NO_DTLS12 + uint16_t epoch; /* dtls: 2 byte epoch */ + uint16_t reserve; /* Four-byte alignment is reserved */ +#endif +} RecConnState; + +/* see TLSPlaintext structure definition in rfc */ +typedef struct { + uint8_t type; // ccs(20), alert(21), hs(22), app data(23), (255) + bool isEncryptThenMac; + uint8_t reverse[2]; + + uint16_t version; + uint16_t negotiatedVersion; + + uint8_t seq[REC_CONN_SEQ_SIZE]; /* 1. tls: sequence number 2.dtls: epoch + sequence */ + + uint32_t textLen; + const uint8_t *text; // fragment +} REC_TextInput; + +/** + * @brief Initialize RecConnState + */ +RecConnState *RecConnStateNew(void); + +/** + * @brief Release RecConnState + */ +void RecConnStateFree(RecConnState *state); + +/** + * @brief Obtain the Sequence number + * + * @param state [IN] Connection state + * + * @retval Sequence number + */ +uint64_t RecConnGetSeqNum(const RecConnState *state); + +/** + * @brief Set the Sequence number + * + * @param state [IN] Connection state + * @param seq [IN] Sequence number + * + * @retval Sequence number + */ +void RecConnSetSeqNum(RecConnState *state, uint64_t seq); + +#ifndef HITLS_NO_DTLS12 +/** + * @brief Obtain the epoch + * + * @attention state can not be null pointer + * + * @param state [IN] Connection state + * + * @retval epoch + */ +uint16_t RecConnGetEpoch(const RecConnState *state); + +/** + * @brief Set epoch + * + * @attention state can not be null pointer + * @param state [IN] Connection state + * @param epoch [IN] epoch + * + */ +void RecConnSetEpoch(RecConnState *state, uint16_t epoch); + +#endif + +/** + * @brief Set the key information + * + * @param state [IN] Connection state + * @param suitInfo [IN] Ciphersuite information + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * @retval HITLS_MEMALLOC_FAIL Memory allocated failed + */ +int32_t RecConnStateSetCipherInfo(RecConnState *state, RecConnSuitInfo *suitInfo); + +/** + * @brief Calculate the ciphertext length based on the plaintext length + * @attention The ciphertext length is accurate + * @param state [IN] RecState context, including cipher suite information + * @param plainLen [IN] Plaintext length + * @param isEncThenMac [IN] Indicates whether the Encrypt-Then-Mac mode is used + * + * @return ciphertext length + */ +uint32_t RecConnCalcCiphertextLen(const RecConnState *state, uint32_t plainLen, bool isEncThenMac); + +/** + * @brief Encrypt the record payload + * + * @param state RecState context + * @param plainMsg [IN] Input data before encryption + * @param cipherText [OUT] Encrypted content + * @param cipherTextLen [IN] Length after encryption + * @param isEncryptThenMac [IN] Indicates whether the Encrypt-Then-Mac mode is used + * + * @retval HITLS_SUCCESS + * @retval HITLS_MEMCPY_FAIL Memory copy failed + * @retval HITLS_REC_ERR_NOT_SUPPORT_CIPHER The key algorithm is not supported + * @retval HITLS_REC_ERR_ENCRYPT Encryption failed + * @see SAL_CRYPT_Encrypt + */ +int32_t RecConnEncrypt(RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText, uint32_t cipherTextLen); + +/** + * @brief Decrypt the record payload + * + * @param ctx [IN] tls Context + * @param state RecState context + * @param cryptMsg [IN] Content to be decrypted + * @param data [OUT] Decrypted data + * @param dataLen [IN/OUT] IN: length of data OUT: length after decryption + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_ERR_NOT_SUPPORT_CIPHER The key algorithm is not supported + * @retval HITLS_MEMCPY_FAIL Memory copy failed + */ +int32_t RecConnDecrypt(TLS_Ctx *ctx, RecConnState *state, + const REC_TextInput *cryptMsg, uint8_t *data, uint32_t *dataLen); + +/** + * @brief Key generation + * + * @param param [IN] Security parameter + * @param client [OUT] Client key material + * @param server [OUT] Server key material + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer + * @retval Reference SAL_CRYPT_PRF + */ +int32_t RecConnKeyBlockGen(const REC_SecParameters *param, RecConnSuitInfo *client, RecConnSuitInfo *server); + +/** + * @brief TLS1.3 Key generation + * + * @param param [IN] Security parameter + * @param suitInfo [OUT] key material + * + * @retval HITLS_SUCCESS + * @retval HITLS_UNREGISTERED_CALLBACK Unregistered callback + * @retval HITLS_CRYPT_ERR_DIGEST hash calculation failed + * @retval HITLS_CRYPT_ERR_HKDF_EXPAND HKDF-Expand calculation fails + * + */ +int32_t RecTLS13ConnKeyBlockGen(const REC_SecParameters *param, RecConnSuitInfo *suitInfo); + +#ifdef __cplusplus +} +#endif + +#endif /* REC_CONN_H */ diff --git a/tls/record/src/rec_header.h b/tls/record/src/rec_header.h new file mode 100644 index 00000000..dc6bf800 --- /dev/null +++ b/tls/record/src/rec_header.h @@ -0,0 +1,60 @@ +/* + * 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 RECORD_HEADER_H +#define RECORD_HEADER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define REC_TLS_RECORD_HEADER_LEN 5 +#define REC_TLS_RECORD_LENGTH_OFFSET 3 +#define REC_TLS_SN_MAX_VALUE (~((uint64_t)0)) /* TLS sequence number wrap Threshold */ + +#ifndef HITLS_NO_DTLS12 + +#define REC_DTLS_RECORD_HEADER_LEN 13 +#define REC_DTLS_RECORD_EPOCH_OFFSET 3 +#define REC_DTLS_RECORD_LENGTH_OFFSET 11 +/* DTLS sequence number cannot be greater than this value. Otherwise, it will wrapped */ +#define REC_DTLS_SN_MAX_VALUE 0xFFFFFFFFFFFFllu + +#define REC_SEQ_GET(n) ((n) & 0x0000FFFFFFFFFFFFull) +#define REC_EPOCH_GET(n) ((uint16_t)((n) >> 48)) +#define REC_EPOCHSEQ_CAL(epoch, seq) (((uint64_t)(epoch) << 48) | (seq)) +/* Epoch cannot be greater than this value. Otherwise, it will wrapped */ +#define REC_EPOCH_MAX_VALUE 0xFFFFu + +#endif + +typedef struct { + uint8_t type; + uint8_t reverse[3]; /* Reserved, 4-byte aligned */ + uint16_t version; + uint16_t bodyLen; /* body length */ + +#ifndef HITLS_NO_DTLS12 + uint64_t epochSeq; /* only for dtls */ +#endif +} RecHdr; + +#ifdef __cplusplus +} +#endif + +#endif /* RECORD_HEADER_H */ diff --git a/tls/record/src/rec_read.c b/tls/record/src/rec_read.c new file mode 100644 index 00000000..99035dc6 --- /dev/null +++ b/tls/record/src/rec_read.c @@ -0,0 +1,850 @@ +/* + * 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 "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "rec_alert.h" +#include "record.h" +#include "indicator.h" +#include "hs_ctx.h" +#include "hs.h" + +RecConnState *TlsGetReadConnState(const TLS_Ctx *ctx) +{ + /** Obtains the record structure. */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + return recordCtx->readStates.currentState; +} + +static REC_Type RecCastUintToRecType(TLS_Ctx *ctx, uint8_t value) +{ + REC_Type type; + RecConnState *state = TlsGetReadConnState(ctx); + /* Convert to the record type */ + switch (value) { + case 20u: + type = REC_TYPE_CHANGE_CIPHER_SPEC; + break; + case 21u: + type = REC_TYPE_ALERT; + break; + case 22u: + type = REC_TYPE_HANDSHAKE; + break; + case 23u: + type = REC_TYPE_APP; + break; + default: + type = REC_TYPE_UNKNOWN; + break; + } + if (HS_GetVersion(ctx) == HITLS_VERSION_TLS13 && state->suiteInfo != NULL) { + if (type != REC_TYPE_APP && type != REC_TYPE_ALERT && + (type != REC_TYPE_CHANGE_CIPHER_SPEC || (ctx->hsCtx != NULL && ctx->hsCtx->haveHrr))) { + type = REC_TYPE_UNKNOWN; + } + } + + return type; +} + +#ifndef HITLS_NO_DTLS12 +int32_t DtlsCheckVersionField(const TLS_Ctx *ctx, uint16_t version, uint8_t type) +{ + /* Tolerate alerts with non-negotiated version. For example, after the server sends server hello, the client + * replies with an earlier version alert */ + if (ctx->negotiatedInfo.version == 0u || type == (uint8_t)REC_TYPE_ALERT) { + if ((version != HITLS_VERSION_DTLS10) && (version != HITLS_VERSION_DTLS12)) { + BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15436, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with illegal version(0x%x).", version, 0, 0, 0); + return HITLS_REC_INVALID_PROTOCOL_VERSION; + } + } else { + if (version != ctx->negotiatedInfo.version) { + BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15437, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with illegal version(0x%x).", version, 0, 0, 0); + return HITLS_REC_INVALID_PROTOCOL_VERSION; + } + } + return HITLS_SUCCESS; +} + +int32_t DtlsCheckRecordHeader(TLS_Ctx *ctx, const RecHdr *hdr) +{ + /** Check the DTLS version, release the resource and return if the version is incorrect */ + int32_t ret = DtlsCheckVersionField(ctx, hdr->version, hdr->type); + if (ret != HITLS_SUCCESS) { + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + } + + if (RecCastUintToRecType(ctx, hdr->type) == REC_TYPE_UNKNOWN || hdr->bodyLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15438, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid type or body length(0)", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + if (hdr->bodyLen > REC_MAX_CIPHER_TEXT_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_TOO_BIG_LENGTH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15439, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW); + } + + uint16_t epoch = REC_EPOCH_GET(hdr->epochSeq); + if (epoch == 0 && hdr->type == REC_TYPE_APP) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15440, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a UNEXPECTE record msg: epoch 0's app msg.", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + return HITLS_SUCCESS; +} + +/** +* @brief Read message data. +* +* @param uio [IN] UIO object. +* @param inBuf [IN] inBuf Read the buffer. +* +* @retval HITLS_SUCCESS is successfully read. +* @retval HITLS_REC_ERR_IO_EXCEPTION I/O error +* @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY Uncached data needs to be reread. + */ +static int32_t ReadDatagram(TLS_Ctx *ctx, RecBuf *inBuf) +{ + if (inBuf->end > inBuf->start) { + return HITLS_SUCCESS; + } + + /* Attempt to read the message: The message is read of the whole message */ + uint32_t recvLen = 0u; + ctx->rwstate = HITLS_READING; + int32_t ret = BSL_UIO_Read(ctx->rUio, &(inBuf->buf[0]), inBuf->bufSize, &recvLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15441, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record read: uio err.%d", ret, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + ctx->rwstate = HITLS_NOTHING; + if (recvLen == 0) { + return HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } + + inBuf->start = 0; + inBuf->end = recvLen; // successfully read + return HITLS_SUCCESS; +} + +static int32_t DtlsGetRecordHeader(const uint8_t *msg, uint32_t len, RecHdr *hdr) +{ + if (len < REC_DTLS_RECORD_HEADER_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_REC_DECODE_ERROR); + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID15442, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "Record:dtls packet's length err.", 0, 0, 0, 0); + return HITLS_REC_DECODE_ERROR; + } + + /* Parse the record header */ + hdr->type = msg[0]; + hdr->version = BSL_ByteToUint16(&msg[1]); + hdr->bodyLen = BSL_ByteToUint16( + &msg[REC_DTLS_RECORD_LENGTH_OFFSET]); // The 11th to 12th bytes of DTLS are the message length. + hdr->epochSeq = BSL_ByteToUint64(&msg[REC_DTLS_RECORD_EPOCH_OFFSET]); + return HITLS_SUCCESS; +} + +/** + * @brief Attempt to read a dtls record message. + * + * @param ctx [IN] TLS context + * @param recordBody [OUT] record body + * @param hdr [OUT] record head + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + */ +static int32_t TryReadOneDtlsRecord(TLS_Ctx *ctx, uint8_t **recordBody, RecHdr *hdr) +{ + /** Obtain the record structure information */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + + /** Read the datagram message: The message may contain multiple records */ + int32_t ret = ReadDatagram(ctx, recordCtx->inBuf); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint8_t *msg = &recordCtx->inBuf->buf[recordCtx->inBuf->start]; + uint32_t len = recordCtx->inBuf->end - recordCtx->inBuf->start; + + ret = DtlsGetRecordHeader(msg, len, hdr); + if (ret != HITLS_SUCCESS) { + RecBufClean(recordCtx->inBuf); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + } + + INDICATOR_MessageIndicate(0, 0, RECORD_HEADER, msg, REC_DTLS_RECORD_HEADER_LEN, ctx, + ctx->config.tlsConfig.msgArg); + + /* Check whether the record length is greater than the buffer size */ + if ((REC_DTLS_RECORD_HEADER_LEN + (uint32_t)hdr->bodyLen) > len) { + RecBufClean(recordCtx->inBuf); + BSL_ERR_PUSH_ERROR(HITLS_REC_DECODE_ERROR); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15443, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record:dtls packet's length err.", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + } + + /** Release the read record */ + recordCtx->inBuf->start += REC_DTLS_RECORD_HEADER_LEN + hdr->bodyLen; + + /** Update the read content */ + *recordBody = msg + REC_DTLS_RECORD_HEADER_LEN; + + return HITLS_SUCCESS; +} + +static inline void DtlsGenerateCryptMsg(TLS_Ctx *ctx, RecHdr *hdr, const uint8_t *recordBody, REC_TextInput *cryptMsg) +{ + cryptMsg->negotiatedVersion = ctx->negotiatedInfo.version; + cryptMsg->isEncryptThenMac = ctx->negotiatedInfo.isEncryptThenMac; + cryptMsg->type = hdr->type; + cryptMsg->version = hdr->version; + cryptMsg->text = recordBody; + cryptMsg->textLen = hdr->bodyLen; + BSL_Uint64ToByte(hdr->epochSeq, cryptMsg->seq); +} + +RecConnState *DtlsGetReadConnState(const TLS_Ctx *ctx) +{ + /** Obtain the record structure */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + return recordCtx->readStates.currentState; +} + +/** + * @brief Check whether there are unprocessed handshake messages in the cache. + * + * @param unprocessedHsMsg [IN] Unprocessed handshake message handle + * @param curEpoch [IN] Current epoch + * + * @retval true: cached + * @retval false No cache + */ +static bool IsExistUnprocessedHsMsg(RecCtx *recCtx) +{ + uint16_t curEpoch = recCtx->readEpoch; + UnprocessedHsMsg *unprocessedHsMsg = &recCtx->unprocessedHsMsg; + + /* Check whether there are cached handshake messages. */ + if (unprocessedHsMsg->recordBody == NULL) { + return false; + } + + uint16_t epoch = REC_EPOCH_GET(unprocessedHsMsg->hdr.epochSeq); + if (curEpoch == epoch) { + /* The handshake message of the current epoch needs to be processed */ + return true; + } + + if (curEpoch > epoch) { + /* Expired messages need to be cleaned up */ + (void)memset_s(&unprocessedHsMsg->hdr, sizeof(unprocessedHsMsg->hdr), 0, sizeof(unprocessedHsMsg->hdr)); + BSL_SAL_FREE(unprocessedHsMsg->recordBody); + } + + return false; +} + +static bool IsExistUnprocessedAppMsg(RecCtx *recCtx) +{ + UnprocessedAppMsg *unprocessedAppMsgList = &recCtx->unprocessedAppMsgList; + if (unprocessedAppMsgList->count != 0) { + return true; + } + return false; +} + +static int32_t RecordBufferUnprocessedMsg(RecCtx *recordCtx, RecHdr *hdr, uint8_t *recordBody) +{ + if (hdr->type == REC_TYPE_HANDSHAKE) { + CacheNextEpochHsMsg(&recordCtx->unprocessedHsMsg, hdr, recordBody); + } else { + int32_t ret = UnprocessedAppMsgListAppend(&recordCtx->unprocessedAppMsgList, hdr, recordBody); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + return HITLS_REC_NORMAL_RECV_DISORDER_MSG; +} + +static int32_t DtlsRecordHeaderProcess(TLS_Ctx *ctx, uint8_t *recordBody, RecHdr *hdr) +{ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + int32_t transportType = BSL_UIO_GetTransportType(ctx->uio); + + int32_t ret = DtlsCheckRecordHeader(ctx, hdr); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint16_t epoch = REC_EPOCH_GET(hdr->epochSeq); + if (epoch != recordCtx->readEpoch) { + /* Discard out-of-order messages in SCTP scenarios */ + if (transportType == BSL_UIO_SCTP) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15444, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "sctp record disorder: expect epoch = %u, get epoch = %u, drop this record.", + recordCtx->readEpoch, epoch, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + } + + bool isCcsRecv = ctx->method.isRecvCCS(ctx); + /* App messages arrive earlier than finished messages and need to be cached */ + if (ctx->hsCtx != NULL && isCcsRecv == true && (hdr->type == REC_TYPE_APP || hdr->type == REC_TYPE_ALERT)) { + return RecordBufferUnprocessedMsg(recordCtx, hdr, recordBody); + } + + return HITLS_SUCCESS; +} + +static uint8_t *GetUnprocessedMsg(RecCtx *recordCtx, REC_Type recordType, RecHdr *hdr) +{ + uint8_t *recordBody = NULL; + if ((recordType == REC_TYPE_HANDSHAKE) && IsExistUnprocessedHsMsg(recordCtx)) { + (void)memcpy_s(hdr, sizeof(RecHdr), &recordCtx->unprocessedHsMsg.hdr, sizeof(RecHdr)); + recordBody = recordCtx->unprocessedHsMsg.recordBody; + recordCtx->unprocessedHsMsg.recordBody = NULL; + } + + if ((recordType == REC_TYPE_APP) && IsExistUnprocessedAppMsg(recordCtx)) { + UnprocessedAppMsg *appMsg = UnprocessedAppMsgGet(&recordCtx->unprocessedAppMsgList); + if (appMsg == NULL) { + return NULL; + } + (void)memcpy_s(hdr, sizeof(RecHdr), &appMsg->hdr, sizeof(RecHdr)); + recordBody = appMsg->recordBody; + appMsg->recordBody = NULL; + UnprocessedAppMsgFree(appMsg); + } + return recordBody; +} + +static int32_t RecInBufInit(RecCtx *recordCtx, uint32_t bufSize) +{ + if (recordCtx->inBuf == NULL) { + recordCtx->inBuf = RecBufNew(bufSize); + if (recordCtx->inBuf == NULL) { + return HITLS_MEMALLOC_FAIL; + } + } + return HITLS_SUCCESS; +} + +static int32_t DtlsTryReadAndCheckRecordMessage(TLS_Ctx *ctx, uint8_t **recordBody, RecHdr *hdr) +{ + /* Read the new record message */ + int32_t ret = TryReadOneDtlsRecord(ctx, recordBody, hdr); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check the record message header. If the message header is not the expected message, cache the message */ + ret = DtlsRecordHeaderProcess(ctx, *recordBody, hdr); + if (ret != HITLS_SUCCESS) { + return ret; + } + + return HITLS_SUCCESS; +} + +/** + * @brief Read a record in the DTLS protocol. + * + * @param ctx [IN] TLS context + * @param recordType [IN] Record type + * @param data [OUT] Read data + * @param len [OUT] Length of the data to be read + * @param bufSize [IN] buffer length + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG Unexpected message received + * @retval HITLS_REC_NORMAL_RECV_DISORDER_MSG Receives out-of-order messages. + * + */ +int32_t DtlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *len, uint32_t bufSize) +{ + RecHdr hdr = {0}; + uint8_t *recordBody = NULL; + uint8_t *cachRecord = NULL; /* Pointer for storing buffered messages, which is used during release */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + int32_t ret = RecInBufInit(recordCtx, RecGetInitBufferSize(ctx)); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /* Check if there are cached messages that need to be processed */ + recordBody = GetUnprocessedMsg(recordCtx, recordType, &hdr); + cachRecord = recordBody; + /* There are no cached messages to process */ + if (recordBody == NULL) { + ret = DtlsTryReadAndCheckRecordMessage(ctx, &recordBody, &hdr); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* Construct parameters before decryption */ + REC_TextInput cryptMsg = {0}; + DtlsGenerateCryptMsg(ctx, &hdr, recordBody, &cryptMsg); + + /* Decryption */ + uint32_t dataLen = bufSize; + RecConnState *state = DtlsGetReadConnState(ctx); + ret = RecConnDecrypt(ctx, state, &cryptMsg, data, &dataLen); + BSL_SAL_FREE(cachRecord); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (hdr.type != REC_TYPE_APP && dataLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15435, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + /* An unexpected packet is received */ + if (recordType != hdr.type) { + return ctx->method.unexpectedMsgProcessCb(ctx, hdr.type, data, dataLen); + } + + /* Update the read length */ + *len = dataLen; + + return HITLS_SUCCESS; +} + +#endif + +static int32_t VersionProcess(TLS_Ctx *ctx, uint16_t version, uint8_t type) +{ + if ((ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) && (version != HITLS_VERSION_TLS12)) { + /* If the negotiated version is tls1.3, the record version must be tls1.2 */ + BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15448, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with illegal version(0x%x).", version, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_REC_INVALID_PROTOCOL_VERSION; + } else if ((ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) && (version != ctx->negotiatedInfo.version)) { + BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15449, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with illegal version(0x%x).", version, 0, 0, 0); + if (((version & 0xff00u) == (ctx->negotiatedInfo.version & 0xff00u)) && type == REC_TYPE_ALERT) { + return HITLS_SUCCESS; + } + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_REC_INVALID_PROTOCOL_VERSION; + } + return HITLS_SUCCESS; +} + +int32_t TlsCheckVersionField(TLS_Ctx *ctx, uint16_t version, uint8_t type) +{ + if (ctx->negotiatedInfo.version == 0u) { +#ifndef HITLS_NO_TLCP11 + if (((version >> 8u) != HITLS_VERSION_TLS_MAJOR) && (version != HITLS_VERSION_TLCP11)) { +#else + if ((version >> 8u) != HITLS_VERSION_TLS_MAJOR) { +#endif + BSL_ERR_PUSH_ERROR(HITLS_REC_INVALID_PROTOCOL_VERSION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15867, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with illegal version(0x%x).", version, 0, 0, 0); + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_PROTOCOL_VERSION); + return HITLS_REC_INVALID_PROTOCOL_VERSION; + } + } else { + return VersionProcess(ctx, version, type); + } + return HITLS_SUCCESS; +} + +static int32_t TlsCheckRecordHeader(TLS_Ctx *ctx, const RecHdr *recordHdr) +{ + if (RecCastUintToRecType(ctx, recordHdr->type) == REC_TYPE_UNKNOWN) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15450, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid type", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + int32_t ret = TlsCheckVersionField(ctx, recordHdr->version, recordHdr->type); + if (ret != HITLS_SUCCESS) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_DECODE_ERROR); + return HITLS_REC_INVALID_PROTOCOL_VERSION; + } + + if (recordHdr->bodyLen == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15347, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid type", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC); + } + + if (recordHdr->bodyLen > REC_MAX_CIPHER_TEXT_LEN) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15451, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW); + } + + if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13 && recordHdr->bodyLen > REC_MAX_TLS13_ENCRYPTED_LEN) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15896, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW); + } + + return HITLS_SUCCESS; +} + +/** + * @brief Read data from the uio of the TLS context into inBuf + * + * @param ctx [IN] TLS context + * @param inBuf [IN] inBuf Read buffer. + * @param len [IN] len The length to be read, the main call usually takes the value of the record header length (5 + * bytes) and the entire record length (header+body) + * + * @retval HITLS_SUCCESS Read successfully + * @retval HITLS_REC_ERR_IO_EXCEPTION IO error + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY No cached data needs to be re-read + * @retval HITLS_REC_NORMAL_IO_EOF + */ +int32_t StreamRead(TLS_Ctx *ctx, RecBuf *inBuf, uint32_t len) +{ + if (inBuf->end == inBuf->start) { + inBuf->start = 0; + inBuf->end = 0; + } + + // there are enough data in the read buffer + if (inBuf->end >= inBuf->start + len) { + return HITLS_SUCCESS; + } + // right-side available space is less then required len, move data leftwards + uint32_t leftSize = inBuf->bufSize - inBuf->end; + uint32_t dataSize = inBuf->end - inBuf->start; + if (leftSize < len) { + for (uint32_t i = 0; i < dataSize; i++) { + inBuf->buf[i] = inBuf->buf[inBuf->start + i]; + } + + inBuf->start = 0; + inBuf->end = dataSize; + } + + do { + uint32_t recvLen = 0u; + ctx->rwstate = HITLS_READING; + int32_t ret = BSL_UIO_Read(ctx->rUio, &(inBuf->buf[inBuf->end]), inBuf->bufSize - inBuf->end, &recvLen); + if (ret != BSL_SUCCESS) { + if (ret == BSL_UIO_IO_EOF) { + return HITLS_REC_NORMAL_IO_EOF; + } + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15452, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Fail to call BSL_UIO_Read in StreamRead: [%d]", ret, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + + ctx->rwstate = HITLS_NOTHING; + if (recvLen == 0) { + return HITLS_REC_NORMAL_RECV_BUF_EMPTY; + } + + inBuf->end += recvLen; + } while (inBuf->end - inBuf->start < len); + + return HITLS_SUCCESS; +} + +/** + * @brief Attempt to read a tls record message. + * + * @param ctx [IN] TLS context + * @param recordBody [OUT] record body + * @param hdr [OUT] record head + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + */ +static int32_t TryReadOneTlsRecord(TLS_Ctx *ctx, uint8_t **recordBody, RecHdr *hdr) +{ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + + RecBuf *inBuf = recordCtx->inBuf; + + // read record header + int32_t ret = StreamRead(ctx, inBuf, REC_TLS_RECORD_HEADER_LEN); + if (ret != HITLS_SUCCESS) { + return ret; + } + + const uint8_t *recordHeader = &inBuf->buf[inBuf->start]; + hdr->type = recordHeader[0]; + hdr->version = BSL_ByteToUint16(recordHeader + sizeof(uint8_t)); + hdr->bodyLen = BSL_ByteToUint16(recordHeader + REC_TLS_RECORD_LENGTH_OFFSET); + + ret = TlsCheckRecordHeader(ctx, hdr); + if (ret != HITLS_SUCCESS) { + INDICATOR_MessageIndicate(0, 0, RECORD_HEADER, recordHeader, REC_TLS_RECORD_HEADER_LEN, ctx, + ctx->config.tlsConfig.msgArg); + return ret; + } + + INDICATOR_MessageIndicate(0, hdr->version, RECORD_HEADER, recordHeader, REC_TLS_RECORD_HEADER_LEN, ctx, + ctx->config.tlsConfig.msgArg); + + // read a whole record: head + body + ret = StreamRead(ctx, inBuf, REC_TLS_RECORD_HEADER_LEN + (uint32_t)hdr->bodyLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + *recordBody = &inBuf->buf[inBuf->start] + REC_TLS_RECORD_HEADER_LEN; + + inBuf->start += REC_TLS_RECORD_HEADER_LEN + (uint32_t)hdr->bodyLen; + return HITLS_SUCCESS; +} + +/** + * @brief Obtain the content and record message types from the decrypted TLSInnerPlaintext. + * After TLS1.3 decryption, the TLSInnerPlaintext structure is used. The padding needs to be + removed and the actual message type needs to be obtained. + * + * struct { + * opaque content[TLSPlaintext.length]; + * ContentType type; + * uint8 zeros[length_of_padding]; + * } TLSInnerPlaintext; + * + * @param text [IN] Decrypted content (TLSInnerPlaintext) + * @param textLen [OUT] Input (length of TLSInnerPlaintext) + * Length of the output content + * @param recType [OUT] Message body length + * + * @return HITLS_SUCCESS succeeded + * HITLS_ALERT_FATAL Unexpected Message + */ +int32_t RecParseInnerPlaintext(TLS_Ctx *ctx, const uint8_t *text, uint32_t *textLen, uint8_t *recType) +{ + /* The receiver decrypts and scans the field from the end to the beginning until it finds a non-zero octet. This + * non-zero byte is the message type of record If no non-zero bytes are found, an unexpected alert needs to be sent + * and the chain is terminated + */ + uint32_t len = *textLen; + for (uint32_t i = len; i > 0; i--) { + if (text[i - 1] != 0) { + *recType = text[i - 1]; + // When the value is the same as the rectype index, the value is the length of the content + *textLen = i - 1; + return HITLS_SUCCESS; + } + } + + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_RECV_UNEXPECTED_MSG); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15453, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Recved UNEXPECTED_MESSAGE.", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); +} + +int32_t RecordDecryptPrepare(TLS_Ctx *ctx, uint16_t version, uint64_t seq, REC_TextInput *cryptMsg) +{ + if (seq >= REC_TLS_SN_MAX_VALUE) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_SN_WRAPPING); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15454, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record read: sequence number wrap.", 0, 0, 0, 0); + return HITLS_REC_ERR_SN_WRAPPING; + } + + RecHdr hdr = { 0 }; + uint8_t *recordBody = NULL; + // read header and body from ctx + int32_t ret = TryReadOneTlsRecord(ctx, &recordBody, &hdr); + if (ret != HITLS_SUCCESS) { + return ret; + } + + if (version == HITLS_VERSION_TLS13 && (hdr.type == REC_TYPE_CHANGE_CIPHER_SPEC || hdr.type == REC_TYPE_ALERT)) { + /* In the TLS1.3 scenario, process unencrypted CCS and Alert messages received */ + return ctx->method.unexpectedMsgProcessCb(ctx, hdr.type, recordBody, (uint32_t)hdr.bodyLen); + } + + cryptMsg->negotiatedVersion = ctx->negotiatedInfo.version; + cryptMsg->isEncryptThenMac = ctx->negotiatedInfo.isEncryptThenMac; + cryptMsg->type = hdr.type; + cryptMsg->version = hdr.version; + cryptMsg->text = recordBody; + cryptMsg->textLen = hdr.bodyLen; + BSL_Uint64ToByte(seq, cryptMsg->seq); + return HITLS_SUCCESS; +} + +/** + * @brief Read a record in the TLS protocol. + * @attention: Handle record and handle transporting state to receive unexpected record type messages + * @param ctx [IN] TLS context + * @param recordType [IN] Record type + * @param data [OUT] Read data + * @param readLen [OUT] Length of the read data + * @param num [IN] The read buffer has num bytes + * + * @retval HITLS_SUCCESS succeeded. + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY Need to re-read + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_ERR_SN_WRAPPING Rewind the sequence number. + * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG Unexpected message received + * + */ +int32_t TlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num) +{ + int32_t ret; + RecConnState *state = TlsGetReadConnState(ctx); + uint16_t version = ctx->negotiatedInfo.version; + uint64_t seq = RecConnGetSeqNum(state); + REC_TextInput encryptedMsg = {0}; + bool isEncThenMac = ctx->config.tlsConfig.isEncryptThenMac; + ret = RecordDecryptPrepare(ctx, version, seq, &encryptedMsg); + if (ret != HITLS_SUCCESS) { + return ret; + } + uint32_t dataLen = num; + + ret = RecConnDecrypt(ctx, state, &encryptedMsg, data, &dataLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + /* If the version is tls1.3 and encryption is required, you need to create a TLSInnerPlaintext message */ + if (version == HITLS_VERSION_TLS13 && + RecConnCalcCiphertextLen(state, 0, isEncThenMac) > 0) { + /* tls1.3 You need to exclude the filled 0 to get the true record type */ + ret = RecParseInnerPlaintext(ctx, data, &dataLen, &encryptedMsg.type); + INDICATOR_MessageIndicate(0, version, RECORD_INNER_CONTENT_TYPE, &encryptedMsg.type, 1, ctx, + ctx->config.tlsConfig.msgArg); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + /* Add a record sequence number */ + RecConnSetSeqNum(state, seq + 1); + + /* The TLSPlaintext.length MUST NOT exceed 2^14. An endpoint that receives a record that exceeds + this length MUST terminate the connection with a record_overflow alert */ + if (dataLen > REC_MAX_PLAIN_LENGTH) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15802, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "TLSPlaintext.length exceeds 2^14", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_RECORD_OVERFLOW); + } + + if (encryptedMsg.type != REC_TYPE_APP && dataLen == 0) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15803, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "get a record with invalid length", 0, 0, 0, 0); + return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + } + + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13 && + ctx->method.isRecvCCS(ctx) && + encryptedMsg.type != REC_TYPE_HANDSHAKE) { + ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE); + return HITLS_REC_ERR_DATA_BETWEEN_CCS_AND_FINISHED; + } + + /* An unexpected message is received */ + if (recordType != encryptedMsg.type) { + return ctx->method.unexpectedMsgProcessCb(ctx, encryptedMsg.type, data, dataLen); + } + + /* Update the read length */ + *readLen = dataLen; + return HITLS_SUCCESS; +} + +int32_t REC_TlsReadNbytes(TLS_Ctx *ctx, REC_Type recordType, uint8_t *buf, uint32_t num) +{ + int32_t ret = 0; + uint32_t readbytes = 0; + RecCtx *recCtx = ctx->recCtx; + RecBuf *recCtxBuf = recCtx->inBuf; + uint32_t wantLen = num; + uint8_t *readBuf = (uint8_t *)BSL_SAL_Calloc(1, REC_MAX_CIPHER_TEXT_LEN); + if (readBuf == NULL) { + return HITLS_MEMALLOC_FAIL; + } + + do { + uint32_t offset = num - wantLen; + if (!recCtx->hasReadBufDecrypted) { + recCtxBuf->singleRecStart = 0; + ret = REC_Read(ctx, recordType, readBuf, &readbytes, REC_MAX_CIPHER_TEXT_LEN); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(readBuf); + return ret; + } + recCtx->hasReadBufDecrypted = true; + (void)memcpy_s(recCtxBuf->buf, REC_MAX_CIPHER_TEXT_LEN, readBuf, readbytes); + recCtxBuf->singleRecEnd = recCtxBuf->singleRecStart + readbytes; + + if (readbytes >= wantLen) { + (void)memcpy_s(buf + offset, wantLen, recCtxBuf->buf + recCtxBuf->singleRecStart, wantLen); + recCtxBuf->singleRecStart += wantLen; + wantLen = 0; + } else { + (void)memcpy_s(buf + offset, wantLen, recCtxBuf->buf + recCtxBuf->singleRecStart, readbytes); + recCtx->hasReadBufDecrypted = false; + wantLen -= readbytes; + } + } else { + uint32_t availableBytes = recCtxBuf->singleRecEnd - recCtxBuf->singleRecStart; + if (availableBytes >= wantLen) { + (void)memcpy_s(buf + offset, wantLen, recCtxBuf->buf + recCtxBuf->singleRecStart, wantLen); + recCtxBuf->singleRecStart += wantLen; + wantLen = 0; + } else { + (void)memcpy_s(buf + offset, wantLen, recCtxBuf->buf + recCtxBuf->singleRecStart, + availableBytes); + wantLen -= availableBytes; + recCtx->hasReadBufDecrypted = false; + (void)memset_s(readBuf, REC_MAX_CIPHER_TEXT_LEN, 0, REC_MAX_CIPHER_TEXT_LEN); + } + } + } while (wantLen > 0); + BSL_SAL_FREE(readBuf); + return HITLS_SUCCESS; +} \ No newline at end of file diff --git a/tls/record/src/rec_read.h b/tls/record/src/rec_read.h new file mode 100644 index 00000000..8b74f249 --- /dev/null +++ b/tls/record/src/rec_read.h @@ -0,0 +1,84 @@ +/* + * 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 REC_READ_H +#define REC_READ_H + +#include +#include "rec.h" +#include "rec_buf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HITLS_NO_DTLS12 + +/** + * @brief Read a record in the DTLS protocol + * + * @param ctx [IN] TLS context + * @param recordType [IN] Record type + * @param data [OUT] Read data + * @param len [OUT] Read data length + * @param bufSize [IN] buffer length + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG Unexpected message received + * @retval HITLS_REC_NORMAL_RECV_DISORDER_MSG Receives out-of-order messages + * + */ +int32_t DtlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *len, uint32_t bufSize); + +#endif + +/** + * @brief Read a record in the TLS protocol + * + * @param ctx [IN] TLS context + * @param recordType [IN] Record type + * @param data [OUT] Read data + * @param len [OUT] Read data length + * @param bufSize [IN] buffer length + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap + * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG Unexpected message received + * + */ +int32_t TlsRecordRead(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *len, uint32_t bufSize); + +/** + * @brief Read data from the UIO of the TLS context to the inBuf + * + * @param ctx [IN] TLS context + * @param inBuf [IN] + * @param len [IN] len Length to be read + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY needs to be read again + */ +int32_t StreamRead(TLS_Ctx *ctx, RecBuf *inBuf, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/record/src/rec_unprocessed_msg.c b/tls/record/src/rec_unprocessed_msg.c new file mode 100644 index 00000000..089eae19 --- /dev/null +++ b/tls/record/src/rec_unprocessed_msg.c @@ -0,0 +1,148 @@ +/* + * 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 "securec.h" +#include "bsl_module_list.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_sal.h" +#include "hitls_error.h" +#include "rec.h" +#include "rec_unprocessed_msg.h" + + +#ifndef HITLS_NO_DTLS12 + +void CacheNextEpochHsMsg(UnprocessedHsMsg *unprocessedHsMsg, const RecHdr *hdr, const uint8_t *recordBody) +{ + /* only out-of-order finished messages need to be cached */ + if (hdr->type != REC_TYPE_HANDSHAKE) { + return; + } + + /* only cache one */ + if (unprocessedHsMsg->recordBody != NULL) { + return; + } + + unprocessedHsMsg->recordBody = (uint8_t *)BSL_SAL_Dump(recordBody, hdr->bodyLen); + if (unprocessedHsMsg->recordBody == NULL) { + return; + } + + (void)memcpy_s(&unprocessedHsMsg->hdr, sizeof(RecHdr), hdr, sizeof(RecHdr)); + return; +} + +UnprocessedAppMsg *UnprocessedAppMsgNew(void) +{ + UnprocessedAppMsg *msg = (UnprocessedAppMsg *)BSL_SAL_Calloc(1, sizeof(UnprocessedAppMsg)); + if (msg == NULL) { + return NULL; + } + + LIST_INIT(&msg->head); + return msg; +} + +void UnprocessedAppMsgFree(UnprocessedAppMsg *msg) +{ + if (msg != NULL) { + BSL_SAL_FREE(msg->recordBody); + BSL_SAL_FREE(msg); + } + return; +} + +void UnprocessedAppMsgListInit(UnprocessedAppMsg *appMsgList) +{ + if (appMsgList == NULL) { + return; + } + appMsgList->count = 0; + appMsgList->recordBody = NULL; + LIST_INIT(&appMsgList->head); + return; +} + +void UnprocessedAppMsgListDeinit(UnprocessedAppMsg *appMsgList) +{ + ListHead *node = NULL; + ListHead *tmpNode = NULL; + UnprocessedAppMsg *cur = NULL; + + LIST_FOR_EACH_ITEM_SAFE(node, tmpNode, &(appMsgList->head)) { + cur = LIST_ENTRY(node, UnprocessedAppMsg, head); + LIST_REMOVE(node); + /* releasing nodes and deleting user data */ + UnprocessedAppMsgFree(cur); + } + appMsgList->count = 0; + return; +} + +int32_t UnprocessedAppMsgListAppend(UnprocessedAppMsg *appMsgList, const RecHdr *hdr, const uint8_t *recordBody) +{ + /* prevent oversize */ + if (appMsgList->count >= UNPROCESSED_APP_MSG_COUNT_MAX) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_BUFFER_NOT_ENOUGH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15804, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Buffer app record: count[%u] is too big", appMsgList->count, 0, 0, 0); + return HITLS_REC_ERR_BUFFER_NOT_ENOUGH; + } + + UnprocessedAppMsg *appNode = UnprocessedAppMsgNew(); + if (appNode == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15805, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Buffer app record: Malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + + appNode->recordBody = (uint8_t*)BSL_SAL_Dump(recordBody, hdr->bodyLen); + if (appNode->recordBody == NULL) { + UnprocessedAppMsgFree(appNode); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15806, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Buffer app record: Malloc fail.", 0, 0, 0, 0); + return HITLS_MEMALLOC_FAIL; + } + (void)memcpy_s(&appNode->hdr, sizeof(RecHdr), hdr, sizeof(RecHdr)); + + LIST_ADD_BEFORE(&appMsgList->head, &appNode->head); + + appMsgList->count++; + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15807, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Buffer app record: count is %u.", appMsgList->count, 0, 0, 0); + return HITLS_SUCCESS; +} + +UnprocessedAppMsg *UnprocessedAppMsgGet(UnprocessedAppMsg *appMsgList) +{ + ListHead *next = appMsgList->head.next; + if (next == &appMsgList->head) { + return NULL; + } + + UnprocessedAppMsg *cur = LIST_ENTRY(next, UnprocessedAppMsg, head); + /* remove a node and release it by the outside */ + LIST_REMOVE(next); + appMsgList->count--; + return cur; +} + +#endif // HITLS_NO_DTLS12 diff --git a/tls/record/src/rec_unprocessed_msg.h b/tls/record/src/rec_unprocessed_msg.h new file mode 100644 index 00000000..95305953 --- /dev/null +++ b/tls/record/src/rec_unprocessed_msg.h @@ -0,0 +1,67 @@ +/* + * 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 REC_UNPROCESSED_MSG_H +#define REC_UNPROCESSED_MSG_H + +#include +#include "bsl_module_list.h" +#include "rec_header.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HITLS_NO_DTLS12 + +typedef struct { + RecHdr hdr; /* record header */ + uint8_t *recordBody; /* record body */ +} UnprocessedHsMsg; /* Unprocessed handshake messages */ + +/* rfc6083 4.7 Handshake + User messages that arrive between ChangeCipherSpec and Finished + messages and use the new epoch have probably passed the Finished + message and MUST be buffered by DTLS until the Finished message is + read. +*/ +typedef struct { + ListHead head; + uint32_t count; /* Number of cached record messages */ + RecHdr hdr; /* record header */ + uint8_t *recordBody; /* record body */ +} UnprocessedAppMsg; /* Unprocessed App messages: App messages that are out of order with finished */ + +void CacheNextEpochHsMsg(UnprocessedHsMsg *unprocessedHsMsg, const RecHdr *hdr, const uint8_t *recordBody); + +UnprocessedAppMsg *UnprocessedAppMsgNew(void); + +void UnprocessedAppMsgFree(UnprocessedAppMsg *msg); + +void UnprocessedAppMsgListInit(UnprocessedAppMsg *appMsgList); + +void UnprocessedAppMsgListDeinit(UnprocessedAppMsg *appMsgList); + +int32_t UnprocessedAppMsgListAppend(UnprocessedAppMsg *appMsgList, const RecHdr *hdr, const uint8_t *recordBody); + +UnprocessedAppMsg *UnprocessedAppMsgGet(UnprocessedAppMsg *appMsgList); + +#endif // HITLS_NO_DTLS12 + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/record/src/rec_write.c b/tls/record/src/rec_write.c new file mode 100644 index 00000000..c1cdfa2a --- /dev/null +++ b/tls/record/src/rec_write.c @@ -0,0 +1,460 @@ +/* + * 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 "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "bsl_errno.h" +#include "bsl_uio.h" +#include "uio_base.h" +#include "record.h" +#include "hs_ctx.h" +#include "indicator.h" +#include "hs.h" + +/* 16384 + 1: RFC8446 5.4. Record Padding the full encoded TLSInnerPlaintext MUST NOT exceed 2^14 + 1 octets. */ +#define MAX_PADDING_LEN 16385 + +typedef struct { + REC_Type recordType; /* Protocol type */ + uint32_t plainLen; /* message length */ + uint8_t *plainData; /* message data */ + /* Length of the tls1.3 padding content. Currently, the value is 0. The value can be used as required */ + uint64_t recPaddingLength; + bool isTlsInnerPlaintext; /* Whether it is a TLSInnerPlaintext message for tls1.3 */ +} RecordPlaintext; /* Record protocol data before encryption */ + +static int32_t CheckEncryptionLimits(const TLS_Ctx *ctx, RecConnState *state) +{ + if (ctx->isKeyUpdateRequest == false && state->suiteInfo != NULL && + (state->suiteInfo->cipherAlg == HITLS_CIPHER_AES_128_GCM || + state->suiteInfo->cipherAlg == HITLS_CIPHER_AES_256_GCM) && + RecConnGetSeqNum(state) > REC_MAX_AES_GCM_ENCRYPTION_LIMIT) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ENCRYPTED_NUMBER_OVERFLOW); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15663, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN, + "AES-GCM record encrypted times overflow", 0, 0, 0, 0); + return HITLS_REC_ENCRYPTED_NUMBER_OVERFLOW; + } + return HITLS_SUCCESS; +} + +#ifndef HITLS_NO_DTLS12 +// Write the data message. +static int32_t DatagramWrite(TLS_Ctx *ctx, RecBuf *buf) +{ + uint32_t total = buf->end - buf->start; + + /* Attempt to write */ + uint32_t sendLen = 0u; + ctx->rwstate = HITLS_WRITING; + int32_t ret = BSL_UIO_Write(ctx->uio, &(buf->buf[buf->start]), total, &sendLen); + /* Two types of failures occur in the packet transfer scenario: + * a. The bottom layer directly returns a failure message. + * b. Only some data messages are sent. + * (sendLen != total) && (sendLen != 0) checks whether the returned result is null, but only part of the data is + sent */ + if ((ret != BSL_SUCCESS) || ((sendLen != 0) && (sendLen != total))) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15664, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record send: IO exception. %d\n", ret, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + + if (sendLen == 0) { + return HITLS_REC_NORMAL_IO_BUSY; + } + + buf->start = 0; + buf->end = 0; + ctx->rwstate = HITLS_NOTHING; + return HITLS_SUCCESS; +} + +RecConnState *DtlsGetWriteConnState(const TLS_Ctx *ctx) +{ + /** Obtain the record structure */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + return recordCtx->writeStates.currentState; +} + +void DtlsPlainMsgGenerate(REC_TextInput *plainMsg, const TLS_Ctx *ctx, + REC_Type recordType, const uint8_t *data, uint32_t plainLen, uint64_t epochSeq) +{ + plainMsg->type = recordType; + plainMsg->text = data; + plainMsg->textLen = plainLen; + plainMsg->negotiatedVersion = ctx->negotiatedInfo.version; + plainMsg->isEncryptThenMac = ctx->negotiatedInfo.isEncryptThenMac; + + if (ctx->negotiatedInfo.version == 0) { + plainMsg->version = HITLS_VERSION_DTLS10; + } else { + plainMsg->version = ctx->negotiatedInfo.version; + } + + BSL_Uint64ToByte(epochSeq, plainMsg->seq); +} + +static inline void DtlsRecordHeaderPack(uint8_t *outBuf, REC_Type recordType, uint16_t version, + uint64_t epochSeq, uint32_t cipherTextLen) +{ + outBuf[0] = recordType; + BSL_Uint16ToByte(version, &outBuf[1]); + + BSL_Uint64ToByte(epochSeq, &outBuf[REC_DTLS_RECORD_EPOCH_OFFSET]); + BSL_Uint16ToByte((uint16_t)cipherTextLen, &outBuf[REC_DTLS_RECORD_LENGTH_OFFSET]); +} + +static inline int32_t DtlsRecordMaskAppMsg(const TLS_Ctx *ctx, REC_Type recordType) +{ + if (BSL_UIO_GetTransportType(ctx->uio) == BSL_UIO_SCTP) { + bool isAppMsg = (recordType == REC_TYPE_APP); + int32_t ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_SCTP_MARK_APP_MESSAGE, sizeof(isAppMsg), &isAppMsg); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_MSAK_APP_MSG); + return HITLS_REC_ERR_MSAK_APP_MSG; + } + return HITLS_SUCCESS; + } + return HITLS_SUCCESS; +} + +static int32_t DtlsRecOutBufInit(RecCtx *recordCtx, uint32_t bufSize) +{ + if (recordCtx->outBuf == NULL) { + recordCtx->outBuf = RecBufNew(bufSize); + if (recordCtx->outBuf == NULL) { + return HITLS_MEMALLOC_FAIL; + } + } + return HITLS_SUCCESS; +} + +static int32_t DtlsTrySendMessage(TLS_Ctx *ctx, RecCtx *recordCtx, REC_Type recordType, RecConnState *state) +{ + /* Notify the uio whether the service message is being sent. rfc6083 4.4. Stream Usage: For non-app messages, the + * sctp stream id number must be 0 */ + int32_t ret = DtlsRecordMaskAppMsg(ctx, recordType); + if (ret != HITLS_SUCCESS) { + return ret; + } + + ret = DatagramWrite(ctx, recordCtx->outBuf); + if (ret != HITLS_SUCCESS) { + /* Does not cache messages in the DTLS */ + recordCtx->outBuf->start = 0; + recordCtx->outBuf->end = 0; + return ret; + } + + /** Add the record sequence */ + RecConnSetSeqNum(state, state->seq + 1); + + return HITLS_SUCCESS; +} + +// Write a record for the DTLS protocol +int32_t DtlsRecordWrite(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num) +{ + /** Obtain the record structure */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + RecConnState *state = DtlsGetWriteConnState(ctx); + + if (state->seq > REC_DTLS_SN_MAX_VALUE) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_SN_WRAPPING); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15665, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record write: sequence number wrap.", 0, 0, 0, 0); + return HITLS_REC_ERR_SN_WRAPPING; + } + + uint32_t ciphertextLen = RecConnCalcCiphertextLen(state, num, ctx->negotiatedInfo.isEncryptThenMac); + if (ciphertextLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15666, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record write: cipherTextLen(0) error.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + int32_t ret = DtlsRecOutBufInit(recordCtx, RecGetInitBufferSize(ctx)); + if (ret != HITLS_SUCCESS) { + return ret; + } + + const uint32_t outBufLen = REC_DTLS_RECORD_HEADER_LEN + ciphertextLen; + if (outBufLen > recordCtx->outBuf->bufSize) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_BUFFER_NOT_ENOUGH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15667, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "DTLS record write error: msg len = %u, buf len = %u.", + outBufLen, recordCtx->outBuf->bufSize, 0, 0); + return HITLS_REC_ERR_BUFFER_NOT_ENOUGH; + } + + /* Before encryption, construct plaintext parameters */ + REC_TextInput plainMsg = {0}; + uint64_t epochSeq = REC_EPOCHSEQ_CAL(RecConnGetEpoch(state), state->seq); + DtlsPlainMsgGenerate(&plainMsg, ctx, recordType, data, num, epochSeq); + + /** Obtain the cache address */ + uint8_t *outBuf = &recordCtx->outBuf->buf[0]; + + DtlsRecordHeaderPack(outBuf, recordType, plainMsg.version, epochSeq, ciphertextLen); + + ret = CheckEncryptionLimits(ctx, state); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** Encrypt the record body */ + ret = RecConnEncrypt(state, &plainMsg, &outBuf[REC_DTLS_RECORD_HEADER_LEN], ciphertextLen); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** Commit the record to be written */ + recordCtx->outBuf->start = 0; + recordCtx->outBuf->end = outBufLen; + + INDICATOR_MessageIndicate(1, 0, RECORD_HEADER, outBuf, REC_DTLS_RECORD_HEADER_LEN, + ctx, ctx->config.tlsConfig.msgArg); + + return DtlsTrySendMessage(ctx, recordCtx, recordType, state); +} +#endif + +// Writes data to the UIO of the TLS context. +int32_t StreamWrite(TLS_Ctx *ctx, RecBuf *buf) +{ + uint32_t total = buf->end - buf->start; + int32_t ret = BSL_SUCCESS; + ctx->rwstate = HITLS_WRITING; + do { + uint32_t sendLen = 0u; + ret = BSL_UIO_Write(ctx->uio, &(buf->buf[buf->start]), total, &sendLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15668, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record send: IO exception. %d\n", ret, 0, 0, 0); + return HITLS_REC_ERR_IO_EXCEPTION; + } + + if (sendLen == 0) { + return HITLS_REC_NORMAL_IO_BUSY; + } + + buf->start += sendLen; + } while (buf->start < buf->end); + + buf->start = 0; + buf->end = 0; + ctx->rwstate = HITLS_NOTHING; + + return HITLS_SUCCESS; +} + +static inline RecConnState *TlsGetWriteConnState(const TLS_Ctx *ctx) +{ + return ctx->recCtx->writeStates.currentState; +} + +static void TlsPlainMsgGenerate(REC_TextInput *plainMsg, TLS_Ctx *ctx, + REC_Type recordType, const uint8_t *data, uint32_t plainLen, uint64_t seq) +{ + plainMsg->type = recordType; + plainMsg->text = data; + plainMsg->textLen = plainLen; + plainMsg->negotiatedVersion = ctx->negotiatedInfo.version; + plainMsg->isEncryptThenMac = ctx->negotiatedInfo.isEncryptThenMacWrite; + + if (ctx->negotiatedInfo.version != 0) { + plainMsg->version = (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) ? + HITLS_VERSION_TLS12 : ctx->negotiatedInfo.version; + } else { + plainMsg->version = (ctx->config.tlsConfig.maxVersion == HITLS_VERSION_TLS13) ? + HITLS_VERSION_TLS12 : ctx->config.tlsConfig.maxVersion; + } + + if (ctx->hsCtx != NULL && ctx->hsCtx->state == TRY_SEND_CLIENT_HELLO && + ctx->state != CM_STATE_RENEGOTIATION && ctx->hsCtx->haveHrr == false && +#ifndef HITLS_NO_TLCP11 + ctx->config.tlsConfig.maxVersion != HITLS_VERSION_TLCP11 && +#endif + ctx->config.tlsConfig.maxVersion > HITLS_VERSION_TLS10) { + plainMsg->version = HITLS_VERSION_TLS10; + } + + BSL_Uint64ToByte(seq, plainMsg->seq); +} + +static inline void TlsRecordHeaderPack(uint8_t *outBuf, REC_Type recordType, uint16_t version, uint32_t cipherTextLen) +{ + outBuf[0] = recordType; + BSL_Uint16ToByte(version, &outBuf[1]); + BSL_Uint16ToByte((uint16_t)cipherTextLen, &outBuf[REC_TLS_RECORD_LENGTH_OFFSET]); +} + +/** + * @brief Construct TLSInnerPlaintext (TLS1.3 RFC8446 5.2. Record Payload Protection) + * struct { + * opaque content[TLSPlaintext.length]; + * ContentType type; + * uint8 zeros[length_of_padding]; + * } TLSInnerPlaintext; + */ +static int32_t RecPackTlsInnerPlaintext(TLS_Ctx *ctx, uint8_t recordType, const uint8_t *data, uint32_t plainLen, + RecordPlaintext *recPlaintext) +{ + recPlaintext->recordType = recordType; + recPlaintext->plainLen = plainLen; + recPlaintext->plainData = NULL; + /* Currently, the padding length is set to 0. If required, the padding length can be customized */ + if (ctx->config.tlsConfig.recordPaddingCb == NULL) { + recPlaintext->recPaddingLength = 0; + } else { + recPlaintext->recPaddingLength = + ctx->config.tlsConfig.recordPaddingCb(ctx, recordType, plainLen, ctx->config.tlsConfig.recordPaddingArg); + } + + recPlaintext->isTlsInnerPlaintext = false; + + RecConnState *writeState = TlsGetWriteConnState(ctx); + /* If the length of the ciphertext is 0, encryption and decryption are not performed */ + uint32_t ciphertextLen = + RecConnCalcCiphertextLen(writeState, 0, ctx->negotiatedInfo.isEncryptThenMacWrite); + /* If the negotiation version is tls1.3 and encryption is required, you need to create + * a TLSInnerPlaintext message */ + if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13 || ciphertextLen == 0) { + return HITLS_SUCCESS; + } + + INDICATOR_MessageIndicate( + 0, HS_GetVersion(ctx), RECORD_INNER_CONTENT_TYPE, &recordType, 1, ctx, ctx->config.tlsConfig.msgArg); + + /* TlsInnerPlaintext see rfc 8446 section 5.2 */ + recPlaintext->isTlsInnerPlaintext = true; + + /* tlsInnerPlaintext length = content length + record type length (1) + padding length */ + uint32_t tlsInnerPlaintextLen = plainLen + sizeof(uint8_t) + (uint32_t)recPlaintext->recPaddingLength; + if (tlsInnerPlaintextLen > MAX_PADDING_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_REC_RECORD_OVERFLOW); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15669, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Pack TlsInnerPlaintext length(%u) MUST NOT exceed 2^14 + 1 octets.", tlsInnerPlaintextLen, 0, 0, 0); + return HITLS_REC_RECORD_OVERFLOW; + } + + uint8_t *tlsInnerPlaintext = BSL_SAL_Calloc(1u, tlsInnerPlaintextLen); + if (tlsInnerPlaintext == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + if (memcpy_s(tlsInnerPlaintext, tlsInnerPlaintextLen, data, plainLen) != EOK) { + BSL_SAL_FREE(tlsInnerPlaintext); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMCPY_FAIL; + } + + tlsInnerPlaintext[plainLen] = recordType; + + /* Padding is calloc when the memory is applied for. Therefore, the number of buffs to be supplemented is 0. You do + * not need to perform any operation */ + recPlaintext->plainLen = tlsInnerPlaintextLen; + recPlaintext->plainData = tlsInnerPlaintext; + recPlaintext->recordType = (uint8_t)REC_TYPE_APP; /* tls1.3 Hide the actual record type during encryption */ + return HITLS_SUCCESS; +} + +static int32_t SendRecord(TLS_Ctx *ctx, RecCtx *recordCtx, RecConnState *state, uint64_t seq) +{ + int32_t ret = StreamWrite(ctx, recordCtx->outBuf); + if (ret != HITLS_SUCCESS) { + return ret; + } + + /** Add the record sequence */ + RecConnSetSeqNum(state, seq + 1); + return HITLS_SUCCESS; +} + +// Write a record in the TLS protocol, serialize a record message, and send the message +int32_t TlsRecordWrite(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num) +{ + RecBuf *writeBuf = ctx->recCtx->outBuf; + RecConnState *state = TlsGetWriteConnState(ctx); + RecordPlaintext recPlaintext = {0}; + REC_TextInput plainMsg = {0}; + if (state->seq >= REC_TLS_SN_MAX_VALUE) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_SN_WRAPPING); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15670, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record write: sequence number wrap.", 0, 0, 0, 0); + return HITLS_REC_ERR_SN_WRAPPING; + } + /* Check whether the cache exists */ + if (writeBuf->end > writeBuf->start) { + return SendRecord(ctx, ctx->recCtx, state, state->seq); + } + /* Construct a TLSInnerPlaintext message */ + int32_t ret = RecPackTlsInnerPlaintext(ctx, recordType, data, num, &recPlaintext); + if (ret != HITLS_SUCCESS) { + return ret; + } + + uint32_t ciphertextLen = RecConnCalcCiphertextLen(state, recPlaintext.plainLen, + ctx->negotiatedInfo.isEncryptThenMacWrite); + if (ciphertextLen == 0) { + BSL_SAL_FREE(recPlaintext.plainData); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15671, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record write: cipherTextLen(0) error.", 0, 0, 0, 0); + return HITLS_INTERNAL_EXCEPTION; + } + const uint32_t outBufLen = REC_TLS_RECORD_HEADER_LEN + ciphertextLen; + if (outBufLen > writeBuf->bufSize) { + BSL_SAL_FREE(recPlaintext.plainData); + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_BUFFER_NOT_ENOUGH); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15672, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record write: buffer is not enough.", 0, 0, 0, 0); + return HITLS_REC_ERR_BUFFER_NOT_ENOUGH; + } + /* If the value is not tls13, use the input parameter data */ + const uint8_t *plainMsgData = recPlaintext.isTlsInnerPlaintext ? recPlaintext.plainData : data; + (void)TlsPlainMsgGenerate(&plainMsg, ctx, recPlaintext.recordType, plainMsgData, recPlaintext.plainLen, state->seq); + (void)TlsRecordHeaderPack(writeBuf->buf, recPlaintext.recordType, plainMsg.version, ciphertextLen); + + ret = CheckEncryptionLimits(ctx, state); + if (ret != HITLS_SUCCESS) { + BSL_SAL_FREE(recPlaintext.plainData); + return ret; + } + + /** Encrypt the record body */ + ret = RecConnEncrypt(state, &plainMsg, writeBuf->buf + REC_TLS_RECORD_HEADER_LEN, ciphertextLen); + BSL_SAL_FREE(recPlaintext.plainData); + if (ret != HITLS_SUCCESS) { + return ret; + } + + INDICATOR_MessageIndicate(1, recordType, RECORD_HEADER, writeBuf->buf, REC_TLS_RECORD_HEADER_LEN, ctx, + ctx->config.tlsConfig.msgArg); + + /** Commit the record to be written */ + writeBuf->start = 0; + writeBuf->end = outBufLen; + + return SendRecord(ctx, ctx->recCtx, state, state->seq); +} diff --git a/tls/record/src/rec_write.h b/tls/record/src/rec_write.h new file mode 100644 index 00000000..221d78b9 --- /dev/null +++ b/tls/record/src/rec_write.h @@ -0,0 +1,77 @@ +/* + * This file is part of the openHiTLS project. + * + * openHiTLS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef REC_WRITE_H +#define REC_WRITE_H + +#include +#include "rec.h" +#include "rec_buf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Write a record in TLS + * + * @param ctx [IN] TLS context + * @param recordType [IN] Record type + * @param data [IN] Data to be written + * @param plainLen [IN] plain length + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_IO_BUSY I/O busy + * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap + */ +int32_t TlsRecordWrite(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t plainLen); + +#ifndef HITLS_NO_DTLS12 + +/** + * @brief Write a record in DTLS + * + * @param ctx [IN] TLS context + * @param recordType [IN] Record type + * @param data [IN] Data to be written + * @param plainLen [IN] plain length + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_IO_BUSY I/O busy + * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap + */ +int32_t DtlsRecordWrite(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t plainLen); + +#endif + +/** + * @brief Write data to the UIO of the TLS context + * + * @param ctx [IN] TLS context + * @param buf [IN] Send buffer + * + * @retval HITLS_SUCCESS + * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error + * @retval HITLS_REC_NORMAL_IO_BUSY I/O busy + */ +int32_t StreamWrite(TLS_Ctx *ctx, RecBuf *buf); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/tls/record/src/record.c b/tls/record/src/record.c new file mode 100644 index 00000000..04a8a3d9 --- /dev/null +++ b/tls/record/src/record.c @@ -0,0 +1,386 @@ +/* + * 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 "securec.h" +#include "bsl_sal.h" +#include "tls_binlog_id.h" +#include "bsl_log_internal.h" +#include "bsl_log.h" +#include "bsl_err_internal.h" +#include "bsl_bytes.h" +#include "hitls_error.h" +#include "hitls_config.h" +#include "rec.h" +#include "bsl_uio.h" +#include "rec_write.h" +#include "rec_read.h" +#include "record.h" + +static int32_t RecConnStatesInit(RecCtx *recordCtx) +{ + recordCtx->readStates.currentState = RecConnStateNew(); + if (recordCtx->readStates.currentState == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + recordCtx->writeStates.currentState = RecConnStateNew(); + if (recordCtx->writeStates.currentState == NULL) { + RecConnStateFree(recordCtx->readStates.currentState); + recordCtx->readStates.currentState = NULL; + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + return HITLS_SUCCESS; +} + +// Release RecStatesSuite +static void RecConnStatesDeinit(RecCtx *recordCtx) +{ + RecConnStateFree(recordCtx->readStates.currentState); + RecConnStateFree(recordCtx->writeStates.currentState); + return; +} + +// Calculate the size of the returned buffer based on the protocol type +uint32_t RecGetInitBufferSize(const TLS_Ctx *ctx) +{ + (void)ctx; +#ifndef HITLS_NO_DTLS12 + + /* If the DTLS protocol is used */ + if (IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + /* In non-small-scale scenarios and SCTP scenarios, the size of the transmit end and receive end is 18 KB */ + return (REC_MAX_CIPHER_TEXT_LEN + REC_DTLS_RECORD_HEADER_LEN); + } + +#endif + + /* If the TLS protocol is used, there is no PMTU limit */ + return (REC_MAX_CIPHER_TEXT_LEN + REC_TLS_RECORD_HEADER_LEN); +} + +int32_t REC_Init(TLS_Ctx *ctx) +{ + int32_t ret = HITLS_MEMALLOC_FAIL; + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + if (ctx->recCtx != NULL) { + return HITLS_SUCCESS; + } + /* Allocate RecCtxHandle space */ + RecCtx *newRecCtx = (RecCtx *)BSL_SAL_Calloc(1, sizeof(RecCtx)); + if (newRecCtx == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15531, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: malloc fail.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + uint32_t bufSize = RecGetInitBufferSize(ctx); + newRecCtx->inBuf = RecBufNew(bufSize); + if (newRecCtx->inBuf == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15532, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: malloc fail.", 0, 0, 0, 0); + goto ERR; + } + + newRecCtx->outBuf = RecBufNew(bufSize); + if (newRecCtx->outBuf == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15533, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: malloc fail.", 0, 0, 0, 0); + goto ERR; + } + + ret = RecConnStatesInit(newRecCtx); + if (ret != HITLS_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15534, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: init connect state fail.", 0, 0, 0, 0); + goto ERR; + } + +#ifndef HITLS_NO_DTLS12 + UnprocessedAppMsgListInit(&newRecCtx->unprocessedAppMsgList); + LIST_INIT(&newRecCtx->retransmitList.head); +#endif + + ctx->recCtx = newRecCtx; + return HITLS_SUCCESS; + +ERR: + RecBufFree(newRecCtx->outBuf); + RecBufFree(newRecCtx->inBuf); + BSL_SAL_FREE(newRecCtx); + return ret; +} + +void REC_DeInit(TLS_Ctx *ctx) +{ + if (ctx != NULL && ctx->recCtx != NULL) { + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + + RecBufFree(recordCtx->outBuf); + RecBufFree(recordCtx->inBuf); + + RecConnStatesDeinit(recordCtx); + RecConnStateFree(recordCtx->readStates.pendingState); + RecConnStateFree(recordCtx->writeStates.pendingState); + RecConnStateFree(recordCtx->readStates.outdatedState); + RecConnStateFree(recordCtx->writeStates.outdatedState); + +#ifndef HITLS_NO_DTLS12 + BSL_SAL_FREE(recordCtx->unprocessedHsMsg.recordBody); + UnprocessedAppMsgListDeinit(&recordCtx->unprocessedAppMsgList); +#endif + BSL_SAL_FREE(ctx->recCtx); + } + return; +} + +bool REC_ReadHasPending(const TLS_Ctx *ctx) +{ + if ((ctx == NULL) || (ctx->recCtx == NULL)) { + return false; + } + + /* Obtain the record structure */ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + RecBuf *inBuf = recordCtx->inBuf; + + if (inBuf == NULL) { + return false; + } + + if (inBuf->end != inBuf->start) { + return true; + } + + return false; +} + +int32_t REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num) +{ + if ((ctx == NULL) || (ctx->recCtx == NULL) || (data == NULL)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15535, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN, + "Record: input invalid parameter.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + uint32_t minBufSize = REC_MAX_PLAIN_LENGTH; + + if (num < minBufSize) { + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_BUFFER_NOT_ENOUGH); + return HITLS_REC_ERR_BUFFER_NOT_ENOUGH; + } + + ctx->rwstate = HITLS_NOTHING; + +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + return DtlsRecordRead(ctx, recordType, data, readLen, num); + } +#endif + return TlsRecordRead(ctx, recordType, data, readLen, num); +} + +int32_t REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num) +{ + if ((ctx == NULL) || (ctx->recCtx == NULL) || + (num != 0 && data == NULL) || + (num == 0 && recordType != REC_TYPE_APP)) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15537, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record write: input null pointer.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + ctx->rwstate = HITLS_NOTHING; + + uint32_t maxWriteSize; + (void)REC_GetMaxWriteSize(ctx, &maxWriteSize); + if (num > maxWriteSize) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15539, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record wrtie: plain length is too long.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_TOO_BIG_LENGTH); + return HITLS_REC_ERR_TOO_BIG_LENGTH; + } + +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + /* DTLS */ + return DtlsRecordWrite(ctx, recordType, data, num); + } +#endif + + return TlsRecordWrite(ctx, recordType, data, num); +} + +int32_t REC_InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param) +{ + if (ctx == NULL || ctx->recCtx == NULL || param == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15540, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: ctx is NULL", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + int32_t ret = HITLS_MEMALLOC_FAIL; + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + RecConnSuitInfo clientSuitInfo = {0}; + RecConnSuitInfo serverSuitInfo = {0}; + RecConnSuitInfo *out = NULL; + RecConnSuitInfo *in = NULL; + + RecConnState *readState = RecConnStateNew(); + RecConnState *writeState = RecConnStateNew(); + if (readState == NULL || writeState == NULL) { + goto ERR; + } + + /* 1.Generate a secret */ + ret = RecConnKeyBlockGen(param, &clientSuitInfo, &serverSuitInfo); + if (ret != HITLS_SUCCESS) { + goto ERR; + } + + /* 2.Set the corresponding read/write pending state */ + out = (param->isClient == true) ? &clientSuitInfo : &serverSuitInfo; + in = (param->isClient == true) ? &serverSuitInfo : &clientSuitInfo; + ret = RecConnStateSetCipherInfo(writeState, out); + if (ret != HITLS_SUCCESS) { + goto ERR; + } + ret = RecConnStateSetCipherInfo(readState, in); + if (ret != HITLS_SUCCESS) { + goto ERR; + } + + /* Clear sensitive information */ + BSL_SAL_CleanseData((void *)&clientSuitInfo, sizeof(RecConnSuitInfo)); + BSL_SAL_CleanseData((void *)&serverSuitInfo, sizeof(RecConnSuitInfo)); + RecConnStateFree(recordCtx->readStates.pendingState); + RecConnStateFree(recordCtx->writeStates.pendingState); + recordCtx->readStates.pendingState = readState; + recordCtx->writeStates.pendingState = writeState; + return HITLS_SUCCESS; +ERR: + /* Clear sensitive information */ + BSL_SAL_CleanseData((void *)&clientSuitInfo, sizeof(RecConnSuitInfo)); + BSL_SAL_CleanseData((void *)&serverSuitInfo, sizeof(RecConnSuitInfo)); + RecConnStateFree(readState); + RecConnStateFree(writeState); + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15541, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: malloc fail.", 0, 0, 0, 0); + return ret; +} + +int32_t REC_TLS13InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param, bool isOut) +{ + if (ctx == NULL || ctx->recCtx == NULL || param == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15542, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: ctx is NULL", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + RecConnSuitInfo suitInfo = {0}; + RecConnState *state = RecConnStateNew(); + if (state == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + /* 1.Generate a secret */ + int32_t ret = RecTLS13ConnKeyBlockGen(param, &suitInfo); + if (ret != HITLS_SUCCESS) { + RecConnStateFree(state); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + /* 2.Set the corresponding read/write pending state */ + RecConnStates *curState = NULL; + if (isOut) { + curState = &(recordCtx->writeStates); + } else { + curState = &(recordCtx->readStates); + } + + ret = RecConnStateSetCipherInfo(state, &suitInfo); + if (ret != HITLS_SUCCESS) { + RecConnStateFree(state); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + + RecConnStateFree(curState->pendingState); + curState->pendingState = state; + return HITLS_SUCCESS; +} + +int32_t REC_ActivePendingState(TLS_Ctx *ctx, bool isOut) +{ + RecCtx *recordCtx = (RecCtx *)ctx->recCtx; + RecConnStates *states = (isOut == true) ? &recordCtx->writeStates : &recordCtx->readStates; + + if (states->pendingState == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15543, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: pending state should not be null.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_INTERNAL_EXCEPTION); + return HITLS_INTERNAL_EXCEPTION; + } + RecConnStateFree(states->outdatedState); + states->outdatedState = states->currentState; + states->currentState = states->pendingState; + states->pendingState = NULL; + /* Set the sequence number to 0 */ + RecConnSetSeqNum(states->currentState, 0); + +#ifndef HITLS_NO_DTLS12 + if (IS_DTLS_VERSION(ctx->config.tlsConfig.maxVersion)) { + if (isOut) { + ++recordCtx->writeEpoch; + RecConnSetEpoch(states->currentState, recordCtx->writeEpoch); + } else { + ++recordCtx->readEpoch; + RecConnSetEpoch(states->currentState, recordCtx->readEpoch); + } + } +#endif + + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15544, BSL_LOG_LEVEL_INFO, BSL_LOG_BINLOG_TYPE_RUN, + "Record: active pending state.", 0, 0, 0, 0); + return HITLS_SUCCESS; +} + +int32_t REC_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len) +{ + if (ctx == NULL || ctx->recCtx == NULL || len == NULL) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15545, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "Record: input null pointer.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT); + return HITLS_NULL_INPUT; + } + + *len = REC_MAX_PLAIN_TEXT_LENGTH; + return HITLS_SUCCESS; +} diff --git a/tls/record/src/record.h b/tls/record/src/record.h new file mode 100644 index 00000000..dad10fdd --- /dev/null +++ b/tls/record/src/record.h @@ -0,0 +1,86 @@ +/* + * 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 RECORD_H +#define RECORD_H + +#include "tls.h" +#include "rec.h" +#include "rec_header.h" +#include "rec_unprocessed_msg.h" +#include "rec_buf.h" +#include "rec_conn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define REC_MAX_PLAIN_TEXT_LENGTH 16384 /* Plain content length */ + +#define REC_MAX_ENCRYPTED_OVERHEAD 2048u /* Maximum Encryption Overhead */ +#define REC_MAX_CIPHER_TEXT_LEN (REC_MAX_PLAIN_LENGTH + REC_MAX_ENCRYPTED_OVERHEAD) /* Maximum ciphertext length */ + +#define REC_MAX_AES_GCM_ENCRYPTION_LIMIT 23726566u /* RFC 8446 5.5 Limits on Key Usage AES-GCM SHOULD under 2^24.5 */ + +typedef struct { + RecConnState *outdatedState; + RecConnState *currentState; + RecConnState *pendingState; +} RecConnStates; + +typedef struct { + ListHead head; /* Linked list header */ + bool isExistCcsMsg; /* Check whether CCS messages exist in the retransmission message queue */ + REC_Type type; /* message type */ + uint8_t *msg; /* message data */ + uint32_t len; /* message length */ +} RecRetransmitList; + +typedef struct RecCtx { + RecBuf *inBuf; /* Buffer for reading data */ + RecBuf *outBuf; /* Buffer for writing data */ + bool hasReadBufDecrypted; + RecConnStates readStates; + RecConnStates writeStates; + +#ifndef HITLS_NO_DTLS12 + uint16_t writeEpoch; + uint16_t readEpoch; + + RecRetransmitList retransmitList; /* Cache the messages that may be retransmitted during the handshake */ + + /* Process out-of-order messages */ + UnprocessedHsMsg unprocessedHsMsg; /* used to cache out-of-order finished messages */ + /* unprocessed app message: app messages received in the CCS and finished receiving phases */ + UnprocessedAppMsg unprocessedAppMsgList; +#endif +} RecCtx; + + +/** + * @brief Obtain the size of the buffer for read and write operations + * + * @param ctx [IN] TLS_Ctx context + * + * @retval HITLS_SUCCESS + * @retval HITLS_INTERNAL_EXCEPTION Access a null pointer + */ +uint32_t RecGetInitBufferSize(const TLS_Ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* RECORD_H */ diff --git a/x509/cms/include/hitls_cms_local.h b/x509/cms/include/hitls_cms_local.h new file mode 100644 index 00000000..dc2a8606 --- /dev/null +++ b/x509/cms/include/hitls_cms_local.h @@ -0,0 +1,39 @@ +/* + * 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_CMS_LOCAL_H +#define HITLS_CMS_LOCAL_H + +#include "bsl_type.h" +#include "bsl_obj.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cpluscplus */ + +// parse PKCS7-Data +int32_t CRYPT_EAL_ParseAsn1PKCS7Data(BSL_Buffer *encode, BSL_Buffer *dataValue); + +// parse PKCS7-DigestInfo:only support hash. +int32_t CRYPT_EAL_ParseAsn1PKCS7DigestInfo(BSL_Buffer *encode, BslCid *cid, BSL_Buffer *digest); + +// encode PKCS7-DigestInfo:only support hash. +int32_t CRYPT_EAL_EncodePKCS7DigestInfoBuff(BslCid cid, BSL_Buffer *in, BSL_Buffer *encode); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CMS_LOCAL_H diff --git a/x509/cms/src/hitls_cms_common.c b/x509/cms/src/hitls_cms_common.c new file mode 100644 index 00000000..0001b3fc --- /dev/null +++ b/x509/cms/src/hitls_cms_common.c @@ -0,0 +1,151 @@ +/* + * 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 "securec.h" +#include "bsl_err_internal.h" +#include "bsl_asn1.h" +#include "crypt_errno.h" +#include "bsl_obj_internal.h" +#include "crypt_eal_encode.h" +#include "crypt_eal_md.h" +#include "crypt_encode.h" +#include "hitls_x509_errno.h" + +/** + * Data ::= OCTET STRING + * + * https://datatracker.ietf.org/doc/html/rfc5652#page-7 + */ +int32_t CRYPT_EAL_ParseAsn1PKCS7Data(BSL_Buffer *encode, BSL_Buffer *dataValue) +{ + if (encode == NULL || dataValue == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + uint32_t decodeLen = 0; + uint8_t *data = NULL; + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_OCTETSTRING, &temp, &tempLen, &decodeLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (decodeLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_INVALID_DATA); + return HITLS_CMS_ERR_INVALID_DATA; + } + data = BSL_SAL_Dump(temp, decodeLen); + if (data == NULL) { + ret = BSL_MALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + dataValue->data = data; + dataValue->dataLen = decodeLen; + return CRYPT_SUCCESS; +} + +/** + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest + * } + * + * https://datatracker.ietf.org/doc/html/rfc2315#section-9.4 + */ + +static BSL_ASN1_TemplateItem digestInfoTempl[] = { + /* digestAlgorithm */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + {BSL_ASN1_TAG_NULL, 0, 1}, + /* digest */ + {BSL_ASN1_TAG_OCTETSTRING, 0, 0}, +}; + +typedef enum { + HITLS_P7_DIGESTINFO_OID_IDX, + HITLS_P7_DIGESTINFO_ALGPARAM_IDX, + HITLS_P7_DIGESTINFO_OCTSTRING_IDX, + HITLS_P7_DIGESTINFO_MAX_IDX, +} HITLS_P7_DIGESTINFO_IDX; + +int32_t CRYPT_EAL_ParseAsn1PKCS7DigestInfo(BSL_Buffer *encode, BslCid *cid, BSL_Buffer *digest) +{ + if (encode == NULL || digest == NULL || cid == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + BSL_ASN1_Buffer asn1[HITLS_P7_DIGESTINFO_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {digestInfoTempl, sizeof(digestInfoTempl) / sizeof(digestInfoTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asn1, HITLS_P7_DIGESTINFO_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BslOidString oidStr = {asn1[HITLS_P7_DIGESTINFO_OID_IDX].len, + (char *)asn1[HITLS_P7_DIGESTINFO_OID_IDX].buff, 0}; + BslCid parseCid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (parseCid == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_UNKNOWN_OID); + return CRYPT_DECODE_UNKNOWN_OID; + } + if (asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].len == 0) { + BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_INVALID_DATA); + return HITLS_CMS_ERR_INVALID_DATA; + } + uint8_t *output = BSL_SAL_Dump(asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].buff, + asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].len); + if (output == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + digest->data = output; + digest->dataLen = asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].len; + *cid = parseCid; + return CRYPT_SUCCESS; +} + +int32_t CRYPT_EAL_EncodePKCS7DigestInfoBuff(BslCid cid, BSL_Buffer *in, BSL_Buffer *encode) +{ + if (in == NULL || encode == NULL || (in->data == NULL && in->dataLen != 0)) { + BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT); + return CRYPT_NULL_INPUT; + } + int32_t ret = CRYPT_SUCCESS; + BslOidString *oidstr = BSL_OBJ_GetOidFromCID(cid); + if (oidstr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + BSL_ASN1_Buffer asn1[HITLS_P7_DIGESTINFO_MAX_IDX] = { + {BSL_ASN1_TAG_OBJECT_ID, oidstr->octetLen, (uint8_t *)oidstr->octs}, + {BSL_ASN1_TAG_NULL, 0, NULL}, + {BSL_ASN1_TAG_OCTETSTRING, in->dataLen, in->data}, + }; + BSL_Buffer tmp = {0}; + BSL_ASN1_Template templ = {digestInfoTempl, sizeof(digestInfoTempl) / sizeof(digestInfoTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asn1, HITLS_P7_DIGESTINFO_MAX_IDX, &tmp.data, &tmp.dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + encode->data = tmp.data; + encode->dataLen = tmp.dataLen; + return CRYPT_SUCCESS; +} diff --git a/x509/include/hitls_x509.h b/x509/include/hitls_x509.h new file mode 100644 index 00000000..292152f7 --- /dev/null +++ b/x509/include/hitls_x509.h @@ -0,0 +1,726 @@ +/* + * 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_X509_H +#define HITLS_X509_H + +#include +#include +#include "bsl_list.h" +#include "bsl_type.h" +#include "bsl_uio.h" +#include "bsl_obj.h" +#include "crypt_algid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HITLS_X509_List BslList + +typedef struct _HITLS_X509_Cert HITLS_X509_Cert; + +typedef struct _HITLS_X509_Ext HITLS_X509_Ext; + +typedef struct _HITLS_X509_Crl HITLS_X509_Crl; + +typedef struct _HITLS_X509_StoreCtx HITLS_X509_StoreCtx; + +typedef struct _HITLS_X509_Csr HITLS_X509_Csr; + +typedef struct _HTILS_PKCS12_P12Info HTILS_PKCS12_P12Info; + +typedef struct _HTILS_PKCS12_PwdParam HTILS_PKCS12_PwdParam; + +typedef struct _HTILS_PKCS12_EncodeParam HTILS_PKCS12_EncodeParam; + +typedef struct _HTILS_PKCS12_HmacParam HTILS_PKCS12_HmacParam; + +#define HITLS_CERT_VERSION_1 0 +#define HITLS_CERT_VERSION_2 1 +#define HITLS_CERT_VERSION_3 2 + +#define HITLS_CSR_VERSION 0 + +/* Key usage */ +#define HITLS_X509_EXT_KU_DIGITAL_SIGN 0x0080 +#define HITLS_X509_EXT_KU_NON_REPUDIATION 0x0040 +#define HITLS_X509_EXT_KU_KEY_ENCIPHERMENT 0x0020 +#define HITLS_X509_EXT_KU_DATA_ENCIPHERMENT 0x0010 +#define HITLS_X509_EXT_KU_KEY_AGREEMENT 0x0008 +#define HITLS_X509_EXT_KU_KEY_CERT_SIGN 0x0004 +#define HITLS_X509_EXT_KU_CRL_SIGN 0x0002 +#define HITLS_X509_EXT_KU_ENCIPHER_ONLY 0x0001 +#define HITLS_X509_EXT_KU_DECIPHER_ONLY 0x8000 + +typedef enum { + HITLS_X509_REF_UP = 0, + + HITLS_X509_GET_ENCODELEN = 0x0100, /** Get the length of the ASN.1 DER encoded cert/csr. */ + HITLS_X509_GET_ENCODE, /** Get the ASN.1 DER encoded cert/csr. */ + HITLS_X509_GET_PUBKEY, /** Get the public key for the cert/csr */ + HITLS_X509_GET_SIGNALG, /** Get the signature algorithm for the cert. */ + HITLS_X509_GET_SUBJECT_DNNAME_STR, /** Get the string of subject name. */ + HITLS_X509_GET_ISSUER_DNNAME_STR, /** Get the string of issuer name. */ + HITLS_X509_GET_SERIALNUM, /** Get the string of serial number. */ + HITLS_X509_GET_BEFORE_TIME, /** Get the string of before time. */ + HITLS_X509_GET_AFTER_TIME, /** Get the string of after time. */ + HITLS_X509_GET_SUBJECT_DNNAME, /** Get the subject name list. */ + HITLS_X509_GET_ISSUER_DNNAME, /** Get the issuer name list. */ + HITLS_X509_GET_EXT, /** Get the extension from cert. */ + + HITLS_X509_SET_VERSION = 0x0200, /** Set the version for the cert. */ + HITLS_X509_SET_SERIALNUM, /** Set the serial number for the cert, the length range is 1 to 20. */ + HITLS_X509_SET_BEFORE_TIME, /** Set the before time for the cert. */ + HITLS_X509_SET_AFTER_TIME, /** Set the after time for the cert. */ + HITLS_X509_SET_PRIVKEY, /** Set the private key for signing the cert/csr. */ + HITLS_X509_SET_SIGN_MD_ID, /** Set the hash algorithm for signing the cert/csr。 */ + HITLS_X509_SET_SIGN_RSA_PADDING, /** Set the padding mode(CRYPT_PKEY_EMSA_PKCSV15 or CRYPT_PKEY_EMSA_PSS) + for the RSA signature algorithm. + Before that, you need to use cmd HITLS_X509_SET_PRIVKEY + to set the private key. + If the padding mode is already set, setting different mode will fail. */ + HITLS_X509_SET_SIGN_RSA_PSS_PARAM, /** Set the parameters for the RSA-PSS signature algorithm. + Before that, you need to use cmd HITLS_X509_SET_PRIVKEY + to set the private key. + If the padding mode is not rsa pss, it will fail. + If the parameter has already been set in the private key, this setting + can be omitted, or the same parameter must be set, except for saltLen */ + HITLS_X509_SET_PUBKEY, /** Set the public key for the cert/csr. */ + HITLS_X509_SET_SUBJECT_DNNAME, /** Set the subject name list. */ + HITLS_X509_SET_ISSUER_DNNAME, /** Set the issuer name list. */ + HITLS_X509_SET_CSR_EXT, /** Replace the cert's ext with csr's */ + HITLS_X509_ADD_SUBJECT_NAME, /** Add the subject name for the cert/csr. */ + + HITLS_X509_EXT_KU_KEYENC = 0x0300, + HITLS_X509_EXT_KU_DIGITALSIGN, + HITLS_X509_EXT_KU_CERTSIGN, + HITLS_X509_EXT_KU_KEYAGREEMENT, + + HITLS_X509_EXT_SET_SKI = 0x0400, + HITLS_X509_EXT_SET_AKI, + HITLS_X509_EXT_SET_KUSAGE, + HITLS_X509_EXT_SET_SAN, + HITLS_X509_EXT_SET_BCONS, + HITLS_X509_EXT_SET_EXKUSAGE, + + HITLS_X509_EXT_GET_SKI = 0x0500, /** Get aki from extensions. + Note: Kid is a shallow copy. */ + + HITLS_X509_EXT_CHECK_SKI = 0x0600, /** Check if ski is exists. */ + + HITLS_X509_CSR_GET_ATTRIBUTES = 0x0700, /** Get the attributes from the csr. */ + + HITLS_X509_ATTR_SET_REQUESTED_EXTENSIONS = 0x0800, + HITLS_X509_ATTR_GET_REQUESTED_EXTENSIONS, +} HITLS_X509_Cmd; + +typedef enum { + HITLS_X509_GN_EMAIL, // rfc822Name [1] IA5String + HITLS_X509_GN_DNS, // dNSName [2] IA5String + HITLS_X509_GN_DNNAME, // directoryName [4] Name + HITLS_X509_GN_URI, // uniformResourceIdentifier [6] IA5String + HITLS_X509_GN_IP, // iPAddress [7] Octet String + + HITLS_X509_GN_MAX +} HITLS_X509_GeneralNameType; + +/* Distinguish name */ +typedef struct { + BslCid cid; + uint8_t *data; + uint32_t dataLen; +} HITLS_X509_DN; + +/** + * GenernalName + */ +typedef struct { + HITLS_X509_GeneralNameType type; + BSL_Buffer value; +} HITLS_X509_GeneralName; + +/** + * Authority Key identifier + */ +typedef struct { + bool critical; + BSL_Buffer kid; // keyIdentifier: optional + BslList *issuerName; // Not supported. authorityCertIssuer: optional, List of HITLS_X509_GeneralName + BSL_Buffer serialNum; // Not supported. authorityCertSerialNumber: optional +} HITLS_X509_ExtAki; + +/** + * Subject Key identifier + */ +typedef struct { + bool critical; + BSL_Buffer kid; +} HITLS_X509_ExtSki; + +/** + * Key Usage + */ +typedef struct { + bool critical; + uint32_t keyUsage; +} HITLS_X509_ExtKeyUsage; + +/** + * Extended Key Usage + */ +typedef struct { + bool critical; + BslList *oidList; // Object Identifier: list of BSL_Buffer +} HITLS_X509_ExtExKeyUsage; + +/** + * Subject Alternatiive Name + */ +typedef struct { + bool critical; + BslList *names; // List of HITLS_X509_GeneralName +} HITLS_X509_ExtSan; + +/** + * Basic Constraints + */ +typedef struct { + bool critical; + bool isCa; // Default to false. + int32_t maxPathLen; // Greater than or equal to 0. -1: no check, 0: no intermediate certificate +} HITLS_X509_ExtBCons; + +/** + * @ingroup x509 + * @brief Allocate a certificate. + * + * @retval HITLS_X509_Cert * + */ +HITLS_X509_Cert *HITLS_X509_CertNew(void); + +/** + * @ingroup x509 + * @brief Unallocate a certificate. + * + * @param cert [IN] The certificate. + */ +void HITLS_X509_CertFree(HITLS_X509_Cert *cert); + +/** + * @ingroup x509 + * @brief Duplicate a certificate. + * + * @param src [IN] Source certificate. + * @param dest [OUT] Destination certificate. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertDup(HITLS_X509_Cert *src, HITLS_X509_Cert **dest); + +/** + * @ingroup x509 + * @brief Compute the digest of the certificate. + * + * @param cert [IN] The certificate. + * @param mdId [IN] Digest algorithm. + * @param data [IN/OUT] The digest result. + * @param dataLen [IN/OUT] The length of the digest. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertDigest(HITLS_X509_Cert *cert, CRYPT_MD_AlgId mdId, uint8_t *data, uint32_t *dataLen); + +/** + * @ingroup x509 + * @brief Generic function to process certificate. + * + * @param cert [IN] The certificate. + * @param cmd [IN] HITLS_X509_Cmd + * @param val [IN/OUT] input and output value + * @param valLen [In] value length + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertCtrl(HITLS_X509_Cert *cert, int32_t cmd, void *val, int32_t valLen); + +/** + * @ingroup x509 + * @brief Generic function to set/get an extension. + * + * @param ext [IN] extensions + * @param cmd [IN] HITLS_X509_EXT_SET_XXX + * cmd data type + * HITLS_X509_EXT_GET|SET_KUSAGE HITLS_X509_ExtKeyUsage + * HITLS_X509_EXT_GET|SET_BCONS HITLS_X509_ExtBCons + * HITLS_X509_EXT_GET|SET_AKI HITLS_X509_ExtAki + * HITLS_X509_EXT_GET|SET_SKI HITLS_X509_ExtSki + * HITLS_X509_EXT_GET|SET_SAN HITLS_X509_ExtSan + * HITLS_X509_EXT_GET|SET_EXKUSAGE HITLS_X509_ExtExKeyUsage + * HITLS_X509_EXT_CHECK_SKI bool + * @param val [IN/OUT] input and output value + * @param valLen [In] value length + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_ExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, int32_t valLen); + +/** + * @ingroup x509 + * @brief Parse the CERT in the buffer. + * @par Description: Parse the CERT in the buffer. + * If the encoding is successful, the memory for the crl is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1/BSL_FORMAT_UNKNOWN. + * @param encode [IN] CERT data. + * @param cert [OUT] CERT after parse. + * @return #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_Cert **cert); + +/** + * @ingroup x509 + * @brief Parse the CERT in the file. + * @par Description: Parse the CERT in the file. + * If the encoding is successful, the memory for the crl is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1/BSL_FORMAT_UNKNOWN. + * @param path [IN] CERT file path. + * @param cert [OUT] CERT after parse. + * @return #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertParseFile(int32_t format, const char *path, HITLS_X509_Cert **cert); + +/** + * @ingroup x509 + * @brief Parse the CERTs in the file. + * @par Description: Parse multiple CERTs in the file. + * If the encoding is successful, the memory for the certlist is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1/BSL_FORMAT_UNKNOWN. + * @param path [IN] CRL file path. + * @param crllist [OUT] CRL list after parse. + * @return #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertMulParseFile(int32_t format, const char *path, HITLS_X509_List **certlist); + +/** + * @ingroup x509 + * @brief Generate a encoded certificate. + * @attention You need to first call interfaces HITLS_X509_CertCtrl and HITLS_X509_ExtCtrl to set + * certificate information. + * + * @param format [IN] Encoding format: BSL_FORMAT_ASN1 or BSL_FORMAT_PEM + * @param cert [IN] cert + * @param buff [OUT] encode result + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertGenBuff(int32_t format, HITLS_X509_Cert *cert, BSL_Buffer *buff); + +/** + * @ingroup x509 + * @brief Generate a certificate file. + * @attention You need to first call interfaces HITLS_X509_CertCtrl and HITLS_X509_ExtCtrl to set + * certificate information. + * + * @param format [IN] Encoding format: BSL_FORMAT_ASN1 or BSL_FORMAT_PEM + * @param cert [IN] cert + * @param path [IN] file path + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertGenFile(int32_t format, HITLS_X509_Cert *cert, const char *path); + +/** + * @ingroup x509 + * @brief Add a distinguish name array to list. + * + * @param list [IN] The name list + * @param dnNames [IN] dnName array + * @param size [IN] The count of dnName array + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_AddDnName(BslList *list, HITLS_X509_DN *dnNames, int32_t size); + +typedef enum { + HITLS_X509_CRL_REF_UP, +} HITLS_X509_CrlCmd; + +/** + * @ingroup x509 + * @brief Release the CRL. + * @par Description: Release the memory of the CRL. + * + * @attention None + * @param crl [IN] CRL after parse. + * @return Error code + */ +void HITLS_X509_CrlFree(HITLS_X509_Crl *crl); + +/** + * @ingroup x509 + * @brief Crl setting interface. + * @par Description: Set CRL information. + * parameter data type Length(len):number of data bytes + * HITLS_X509_CRL_REF_UP int The length is sizeof(int), which is used to increase the + * number of CRL references. + * @attention None + * @param crl [IN] CRL data + * @param cmd [IN] Set type. + * @param val [OUT] Set data. + * @param valLen [IN] The length of val. + * @return Error code + */ +int32_t HITLS_X509_CrlCtrl(HITLS_X509_Crl *crl, int32_t cmd, void *val, int32_t valLen); + +/** + * @ingroup x509 + * @brief Parse the CRL in the buffer. + * @par Description: Parse the CRL in the buffer. + * If the encoding is successful, the memory for the crl is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1/ + * BSL_FORMAT_UNKNOWN. + * @param encode [IN] CRL data. + * @param crl [OUT] CRL after parse. + * @return Error code + */ +int32_t HITLS_X509_CrlParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_Crl **crl); + +/** + * @ingroup x509 + * @brief Parse the CRL in the file. + * @par Description: Parse the CRL in the file. + * If the encoding is successful, the memory for the crl is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1/ + * BSL_FORMAT_UNKNOWN. + * @param path [IN] CRL file path. + * @param crl [OUT] CRL after parse. + * @return Error code + */ +int32_t HITLS_X509_CrlParseFile(int32_t format, const char *path, HITLS_X509_Crl **crl); + +/** + * @ingroup x509 + * @brief Parse the CRLs in the file. + * @par Description: Parse multiple CRLs in the file. + * If the encoding is successful, the memory for the crllist is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1/ + * BSL_FORMAT_UNKNOWN. + * @param path [IN] CRL file path. + * @param crllist [OUT] CRL list after parse. + * @return Error code + */ +int32_t HITLS_X509_CrlMulParseFile(int32_t format, const char *path, HITLS_X509_List **crllist); + +/** + * @ingroup x509 + * @brief Generate a CRL and encode it. + * @par Description: This function encodes the CRL into the specified format. + * If the encoding is successful, the memory for the encode data is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM or BSL_FORMAT_ASN1. + * @param crl [IN] CRL raw data. + * @param encode [OUT] Encode data. + * @param encodeLen [OUT] Number of encoded bytes excluding the terminator. + * @return Error code + */ +int32_t HITLS_X509_CrlGenBuff(int32_t format, HITLS_X509_Crl *crl, uint8_t **encode, uint32_t *encodeLen); + +/** + * @ingroup x509 + * @brief Generate a CRL and encode it to specific file. + * @par Description: This function encodes the CRL into the specified format. + * If the encoding is successful, the memory for the encode data is requested from within the function, + * and the user needs to free it after using it. + * @attention None + * @param format [IN] Encoding format: BSL_FORMAT_PEM or BSL_FORMAT_ASN1. + * @param crl [IN] CRL raw data. + * @param path [OUT] Encoding data file path. + * @return Error code + */ +int32_t HITLS_X509_CrlGenFile(int32_t format, HITLS_X509_Crl *crl, const char *path); + +typedef enum { + HITLS_X509_VFY_FLAG_CRL_ALL = 1, + HITLS_X509_VFY_FLAG_CRL_DEV = 2 +} HITLS_X509_VFY_FLAGS; + +typedef enum { + HITLS_X509_STORECTX_SET_PARAM_DEPTH, + HITLS_X509_STORECTX_SET_PARAM_FLAGS, + HITLS_X509_STORECTX_SET_TIME, + HITLS_X509_STORECTX_SET_SECBITS, + /* clear flag */ + HITLS_X509_STORECTX_CLR_PARAM_FLAGS, + HITLS_X509_STORECTX_DEEP_COPY_SET_CA, + HITLS_X509_STORECTX_SHALLOW_COPY_SET_CA, + HITLS_X509_STORECTX_SET_CRL, + HITLS_X509_STORECTX_REF_UP, + HITLS_X509_STORECTX_MAX +} HITLS_X509_StoreCtxCmd; + +/** + * @ingroup x509 + * @brief Allocate a StoreCtx. + * + * @retval HITLS_X509_StoreCtx * + */ +HITLS_X509_StoreCtx *HITLS_X509_StoreCtxNew(void); + +/** + * @ingroup x509 + * @brief Release the StoreCtx. + * + * @param storeCtx [IN] StoreCtx. + * @retval void + */ +void HITLS_X509_StoreCtxFree(HITLS_X509_StoreCtx *storeCtx); + +/** + * @ingroup x509 + * @brief Generic function to process StoreCtx. + * + * @param storeCtx [IN] StoreCtx. + * @param cmd [IN] HITLS_X509_Cmd data type + * HITLS_X509_STORECTX_SET_PARAM_DEPTH int32_t + * HITLS_X509_STORECTX_SET_PARAM_FLAGS int64_t + * HITLS_X509_STORECTX_SET_TIME int64_t + * HITLS_X509_STORECTX_SET_SECBITS uint32_t + * HITLS_X509_STORECTX_CLR_PARAM_FLAGS int64_t + * HITLS_X509_STORECTX_DEEP_COPY_SET_CA HITLS_X509_Cert + * HITLS_X509_STORECTX_SHALLOW_COPY_SET_CA HITLS_X509_Cert + * HITLS_X509_STORECTX_SET_CRL HITLS_X509_Crl + * HITLS_X509_STORECTX_REF_UP int + * @param val [IN/OUT] input and output value. + * @param valLen [IN] value length. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_StoreCtxCtrl(HITLS_X509_StoreCtx *storeCtx, int32_t cmd, void *val, int32_t valLen); + +/** + * @ingroup x509 + * @brief Certificate chain verify function. + * + * @param storeCtx [IN] StoreCtx. + * @param chain [IN] certificate chain. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertVerify(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain); + +/** + * @ingroup x509 + * @brief Certificate chain build function. + * + * @param storeCtx [IN] StoreCtx. + * @param cert [IN] certificate. + * @param chain [OUT] certificate chain. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CertChainBuild(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert, HITLS_X509_List **chain); + +typedef struct _HITLS_X509_Attr { + BslCid cid; + void *value; +} HITLS_X509_Attr; + +/** + * @ingroup x509 + * @brief Allocate a pkcs10 csr. + * + * @retval HITLS_X509_Csr * + */ +HITLS_X509_Csr *HITLS_X509_CsrNew(void); + +/** + * @ingroup x509 + * @brief Release the pkcs10 csr. + * + * @param csr [IN] CSR context. + * @retval void + */ +void HITLS_X509_CsrFree(HITLS_X509_Csr *csr); + +/** + * @ingroup x509 + * @brief Generate csr to store in buffer + * + * @param csr [IN] The csr context + * @param format [IN] The format of the generated csr. + * @param buff [OUT] The buffer of the generated csr. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CsrGenBuff(HITLS_X509_Csr *csr, int32_t format, BSL_Buffer *buff); + +/** + * @ingroup x509 + * @brief Generate csr to store in file + * + * @param csr [IN] The csr context + * @param format [IN] The format of the generated csr. + * @param path [IN] The path of the generated csr. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CsrGenFile(HITLS_X509_Csr *csr, int32_t format, const char *path); + +/** + * @ingroup x509 + * @brief Generic function to process csr function + * + * @param csr [IN] The csr context + * @param cmd [IN] HITLS_X509_Cmd + * @param val [IN/OUT] input and output value. + * @param valLen [IN] value length. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CsrCtrl(HITLS_X509_Csr *csr, int32_t cmd, void *val, int32_t valLen); + +/** + * @ingroup x509 + * @brief Parse the csr in the buffer + * + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1 + * @param encode [IN] The csr data + * @param csr [OUT] The csr context after parsing + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CsrParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_Csr **csr); + +/** + * @ingroup x509 + * @brief Parse the csr in the file + * + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1 + * @param path [IN] The csr file path + * @param csr [OUT] The csr context after parsing + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CsrParseFile(int32_t format, const char *path, HITLS_X509_Csr **csr); + +/** + * @ingroup x509 + * @brief Csr verify function + * + * @param csr [OUT] The csr context + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_CsrVerify(HITLS_X509_Csr *csr); + +/** + * @ingroup x509 + * @brief Generic function to process attribute function + * + * @param attributes [IN] The attribute list + * @param cmd [IN] HITLS_X509_AttrCmd + * @param val data type + * HITLS_X509_ATTR_XX_REQUESTED_EXTENSIONS HITLS_X509_Ext + * @param valLen The length of value. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_X509_AttrCtrl(BslList *attributes, int32_t cmd, void *val, int32_t valLen); + +/** + * @ingroup pkcs12 + * @brief pkcs12 parse + * @par Description: parse p12 buffer, and set the p12 struct. + + * @attention Only support to parse p12 buffer in key-integrity and key-privacy protection mode. + * @param format [IN] Decoding format: BSL_FORMAT_ASN1/BSL_FORMAT_UNKNOWN. + * @param encode [IN] encode data + * @param pwdParam [IN] include MAC-pwd, enc-pwd, they can be different. + * @param p12 [OUT] the p12 struct. + * @param needMacVerify [IN] true, need verify mac; false, skip mac check. + * @return Error code + */ +int32_t HITLS_PKCS12_ParseBuff(int32_t format, BSL_Buffer *encode, const HTILS_PKCS12_PwdParam *pwdParam, + HTILS_PKCS12_P12Info *p12, bool needMacVerify); + +/** + * @ingroup pkcs12 + * @par Description: parse p12 file, and set the p12 struct. + * + * @attention Only support to parse p12 files in key-integrity and key-privacy protection mode. + * @param format [IN] Encoding format: BSL_FORMAT_PEM/BSL_FORMAT_ASN1 + * @param path [IN] p12 file path. + * @param pwdParam [IN] include MAC-pwd, enc-pwd, they can be different. + * @param p12 [OUT] the p12 struct. + * @param needMacVerify [IN] true, need verify mac; false, skip mac check. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_PKCS12_ParseFile(int32_t format, const char *path, const HTILS_PKCS12_PwdParam *pwdParam, + HTILS_PKCS12_P12Info *p12, bool needMacVerify); + +/** + * @ingroup pkcs12 + * @brief pkcs12 gen + * @par Description: gen p12 buffer. + * + * @attention Generate a p12 buffer based on the existing information. + * @param format [IN] Encoding format: BSL_FORMAT_ASN1/BSL_FORMAT_UNKNOWN. + * @param p12 [IN] p12 struct, including entityCert, CA-cert, prvkey, and so on. + * @param encodeParam [IN] encode data + * @param isNeedMac [IN] Identifies whether macData is required. + * @param encode [OUT] result. + * @return Error code + */ +int32_t HITLS_PKCS12_GenBuff(int32_t format, HTILS_PKCS12_P12Info *p12, const HTILS_PKCS12_EncodeParam *encodeParam, + bool isNeedMac, BSL_Buffer *encode); + +/** + * @ingroup pkcs12 + * @par Description: Generate p12 to store in file + * + * @attention Generate a .p12 file based on the existing information. + * @param format [IN] Encoding format: BSL_FORMAT_ASN1/BSL_FORMAT_UNKNOWN. + * @param p12 [IN] p12 struct, including entityCert, CA-cert, prvkey, and so on. + * @param encodeParam [IN] encode data + * @param isNeedMac [IN] Identifies whether macData is required. + * @param path [IN] The path of the generated p12-file. + * @retval #HITLS_X509_SUCCESS, success. + * error codes see the hitls_x509_errno.h + */ +int32_t HITLS_PKCS12_GenFile(int32_t format, HTILS_PKCS12_P12Info *p12, const HTILS_PKCS12_EncodeParam *encodeParam, + bool isNeedMac, const char *path); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_X509_H diff --git a/x509/include/hitls_x509_errno.h b/x509/include/hitls_x509_errno.h new file mode 100644 index 00000000..289d597e --- /dev/null +++ b/x509/include/hitls_x509_errno.h @@ -0,0 +1,152 @@ +/* + * 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_X509_ERRNO_H +#define HITLS_X509_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + HITLS_X509_SUCCESS, + HITLS_X509_ERR_TIME_EXPIRED = 0x04000001, + HITLS_X509_ERR_TIME_FUTURE, + HITLS_X509_ERR_VFY_KU_NO_CERTSIGN, + HITLS_X509_ERR_VFY_KU_NO_CRLSIGN, + HITLS_X509_ERR_VFY_SIGNALG_NOT_MATCH, + HITLS_X509_ERR_INVALID_PARAM, + HITLS_X509_ERR_VFY_CHECK_SECBITS, + HITLS_X509_ERR_VFY_CERT_REVOKED, + HITLS_X509_ERR_VFY_GET_HASHID, + HITLS_X509_ERR_VFY_GET_SIGNID, + HITLS_X509_ERR_VFY_DUP_PUBKEY, + HITLS_X509_ERR_CHECK_ISSUE_FAIL, + HITLS_X509_ERR_CERT_CHAIN_COUNT_IS0, + HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND, + HITLS_X509_ERR_ROOT_CERT_NOT_FOUND, + HITLS_X509_ERR_CHAIN_DEPTH_UP_LIMIT, + + HITLS_X509_ERR_CERT_NOT_CA = 0x04010001, + HITLS_X509_ERR_CERT_EXIST, + HITLS_X509_ERR_CERT_START_TIME_LATER, + HITLS_X509_ERR_CERT_INVALID_KEYUSAGE, + HITLS_X509_ERR_CERT_INVALID_EXT, + HITLS_X509_ERR_PROCESS_CRITICALEXT, + HITLS_X509_ERR_CERT_INVALID_DN, + HITLS_X509_ERR_CERT_PRINT_DN, + HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM, + HITLS_X509_ERR_CERT_INVALID_TIME, + HITLS_X509_ERR_CERT_INVALID_SIGN_MD, + HITLS_X509_ERR_CERT_INVALID_PUBKEY, + HITLS_X509_ERR_CERT_INVALID_PRVKEY, + HITLS_X509_ERR_CERT_INACCRACY_VERSION, + HITLS_X509_ERR_CERT_LACK_SIGNATURE, + HITLS_X509_ERR_CERT_SIGN_ALG, + + HITLS_X509_ERR_CRL_EXIST = 0x04020001, + HITLS_X509_ERR_CRL_NOT_FOUND, + HITLS_X509_ERR_CRL_INACCRACY_VERSION, + HITLS_X509_ERR_CRL_ENTRY, + + HITLS_X509_ERR_NOT_SUPPORT_FORMAT = 0x04030001, + HITLS_X509_ERR_ALG_OID, + HITLS_X509_ERR_PARSE_PARAM, + HITLS_X509_ERR_NAME_OID, + HITLS_X509_ERR_PARSE_STR, + HITLS_X509_ERR_CHECK_TAG, + HITLS_X509_ERR_GET_ANY_TAG, + HITLS_X509_ERR_PARSE_NO_ELEMENT, + HITLS_X509_ERR_PARSE_NO_ENOUGH, + HITLS_X509_ERR_HASHID, + HITLS_X509_ERR_SET_DNNAME_UNKKOWN, + HITLS_X509_ERR_SET_DNNAME_REPEAT, + HITLS_X509_ERR_SET_DNNAME_TOOMUCH, + HITLS_X509_ERR_SET_DNNAME_INVALID_LEN, + HITLS_X509_ERR_SET_KEY, + HITLS_X509_ERR_SET_RSA_PAD, + HITLS_X509_ERR_SET_RSA_PAD_DIFF, + HITLS_X509_ERR_SET_RSAPSS_PARA, + HITLS_X509_ERR_RSA_PAD, + HITLS_X509_ERR_MD_NOT_MATCH, + HITLS_X509_ERR_MGF_NOT_MATCH, + HITLS_X509_ERR_ENCODE_SIGNID, + HITLS_X509_ERR_PARSE_OBJ_ID, + HITLS_X509_ERR_PARSE_ATTR_BUF, + HITLS_X509_ERR_SET_ATTR_TOOMUCH, + HITLS_X509_ERR_SET_ATTR_UNKNOWN, + HITLS_X509_ERR_SET_ATTR_REPEAT, + HITLS_X509_ERR_DUP_ATTR, + HITLS_X509_ERR_SET_AFTER_PARSE, + HITLS_X509_ERR_SET_NAME_LIST, + HITLS_X509_ERR_SORT_NAME_NODE, + HITLS_X509_ERR_ATTR_NOT_FOUND, + + /* extensions */ + HITLS_X509_ERR_EXT_NOT_FOUND = 0x04040001, + HITLS_X509_ERR_EXT_PARSE_AFTER_SET, + HITLS_X509_ERR_EXT_SET_AFTER_PARSE, + HITLS_X509_ERR_EXT_SET, + HITLS_X509_ERR_EXT_KU, + HITLS_X509_ERR_EXT_OID, + HITLS_X509_ERR_EXT_KID, + HITLS_X509_ERR_EXT_SAN, + HITLS_X509_ERR_EXT_SAN_ELE, + HITLS_X509_ERR_EXT_EXTENDED_KU, + HITLS_X509_ERR_EXT_EXTENDED_KU_ELE, + HITLS_X509_ERR_EXT_GN_UNSUPPORT, + HITLS_X509_ERR_PARSE_EXT_KU, + HITLS_X509_ERR_PARSE_EXT_BUF, + HITLS_X509_ERR_PARSE_EXT_REPEAT, + HITLS_X509_ERR_PARSE_GENERALNAME, + HITLS_X509_ERR_PARSE_GENERALNAME_DIR, + HITLS_X509_ERR_PARSE_AKI, + HITLS_X509_ERR_PARSE_SAN, + HITLS_X509_ERR_PARSE_SAN_ITEM_UNKNOW, + HITLS_X509_ERR_PARSE_EXKU, + HITLS_X509_ERR_PARSE_EXKU_ITEM, + + HITLS_X509_ERR_CSR_INVALID_PARAM = 0x04050001, + HITLS_X509_ERR_CSR_INVALID_VERSION, + HITLS_X509_ERR_CSR_INVALID_PUBKEY, + HITLS_X509_ERR_CSR_INVALID_SUBJECT_DN, + HITLS_X509_ERR_CSR_INVALID_ATTR, + + HITLS_CMS_ERR_INVALID_DATA = 0x04060001, + + HITLS_PKCS12_ERR_NULL_POINTER = 0x04070001, + HITLS_PKCS12_ERR_INVALID_PARAM, + HITLS_PKCS12_ERR_INVALID_PFX, + + HITLS_PKCS12_ERR_INVALID_ALGO, + HITLS_PKCS12_ERR_PARSE_TYPE, + HITLS_PKCS12_ERR_VERIFY_FAIL, + HITLS_PKCS12_ERR_INVALID_CONTENTINFO, + HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE, + HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES, + HITLS_PKCS12_ERR_INVALID_CERTYPES, + HITLS_PKCS12_ERR_INVALID_PASSWORD, + HITLS_PKCS12_ERR_INVALID_SALTLEN, + HITLS_PKCS12_ERR_INVALID_INTERATION, + HITLS_PKCS12_ERR_NO_ENTITYCERT, + HITLS_PKCS12_ERR_NOT_SUPPORT_FORMAT, + HITLS_PKCS12_ERR_NONE_DATA, +} HITLS_X509_ERRNO; + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_X509_ERRNO_H \ No newline at end of file diff --git a/x509/pkcs12/include/hitls_pkcs12_local.h b/x509/pkcs12/include/hitls_pkcs12_local.h new file mode 100644 index 00000000..b74b60dd --- /dev/null +++ b/x509/pkcs12/include/hitls_pkcs12_local.h @@ -0,0 +1,184 @@ +/* + * 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_PKCS12_LOCAL_H +#define HITLS_PKCS12_LOCAL_H + +#include +#include "bsl_asn1.h" +#include "bsl_obj.h" +#include "sal_atomic.h" +#include "hitls_x509_local.h" +#include "crypt_eal_encode.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + BslCid contentType; + BSL_Buffer *contentValue; +} HTILS_PKCS12_ContentInfo; + +typedef struct { + BslCid alg; + BSL_Buffer *mac; + BSL_Buffer *macSalt; + uint32_t interation; +} HTILS_PKCS12_MacData; + +typedef struct { + union { + CRYPT_EAL_PkeyCtx *key; + HITLS_X509_Cert *cert; + } value; + BSL_ASN1_List *attributes; // localKeyId, friendlyname, ... +} HTILS_PKCS12_Bag; + +typedef struct _HTILS_PKCS12_P12Info { + uint32_t version; + HTILS_PKCS12_Bag *key; + HTILS_PKCS12_Bag *entityCert; + BSL_ASN1_List *certList; + HTILS_PKCS12_MacData *macData; +} HTILS_PKCS12_P12Info; + +typedef struct { + BslCid bagId; + BSL_Buffer *bagValue; // encode data +} HTILS_PKCS12_CommonSafeBag; + +typedef struct { + BslCid attrId; + BSL_Buffer *attrValue; +} HTILS_PKCS12_SafeBagAttr; + +typedef struct { + BslCid bagId; + BSL_Buffer *bag; // encode data + BSL_ASN1_List *attributes; // Currently, only support localKeyId, friendlyname,. +} HTILS_PKCS12_SafeBag; + +typedef struct _HTILS_PKCS12_PwdParam { + BSL_Buffer *macPwd; + BSL_Buffer *encPwd; +} HTILS_PKCS12_PwdParam; + +typedef struct _HTILS_PKCS12_HmacParam { + uint32_t saltLen; + uint32_t itCnt; + uint32_t macId; + uint8_t *pwd; + uint32_t pwdLen; +} HTILS_PKCS12_HmacParam; + +typedef struct _HTILS_PKCS12_EncodeParam { + CRYPT_EncodeParam certEncParam; + CRYPT_EncodeParam keyEncParam; + HTILS_PKCS12_HmacParam macParam; +} HTILS_PKCS12_EncodeParam; + +HTILS_PKCS12_SafeBag *HTILS_PKCS12_SafeBagNew(); + +void HTILS_PKCS12_SafeBagFree(HTILS_PKCS12_SafeBag *safeBag); + +HTILS_PKCS12_P12Info *HTILS_PKCS12_P12_InfoNew(void); + +void HTILS_PKCS12_P12_InfoFree(HTILS_PKCS12_P12Info *p12); + +HTILS_PKCS12_MacData *HTILS_PKCS12_P12_MacDataNew(void); + +void HTILS_PKCS12_p12_MacDataFree(HTILS_PKCS12_MacData *macData); + +void HTILS_PKCS12_AttributesFree(void *attribute); +typedef enum { + HITLS_PKCS12_KDF_ENCKEY_ID = 1, + HITLS_PKCS12_KDF_ENCIV_ID = 2, + HITLS_PKCS12_KDF_MACKEY_ID = 3, +} HITLS_PKCS12_KDF_IDX; + +/* + * A method of obtaining the mac key in key-integrity protection mode. + * The method implementation follows standards RFC 7292 +*/ +int32_t HTILS_PKCS12_KDF(BSL_Buffer *output, const uint8_t *pwd, uint32_t pwdLen, HITLS_PKCS12_KDF_IDX type, + HTILS_PKCS12_MacData *macData); + +/* + * To cal mac data in key-integrity protection mode, we use the way of Hmac + PKCS12_KDF. +*/ +int32_t HTILS_PKCS12_CalMac(BSL_Buffer *output, BSL_Buffer *pwd, BSL_Buffer *initData, HTILS_PKCS12_MacData *macData); +; + +/* + * Parse the outermost layer of contentInfo, provide two functions + * 1. AuthSafe -> pkcs7 package format + * 2. contentInfo_i -> safeContents +*/ +int32_t HITLS_PKCS12_ParseContentInfo(BSL_Buffer *encode, const uint8_t *password, uint32_t passLen, BSL_Buffer *data); + +/* + * Parse the 'sequences of' of p12, provide two functions + * 1. contentInfo -> contentInfo_i + * 2. safeContent -> safeBag_i + * Both of the above parsing only resolves to BER encoding format, and requiring further conversion. +*/ +int32_t HITLS_PKCS12_ParseAsn1AddList(BSL_Buffer *encode, BSL_ASN1_List *list, uint32_t parseType); + +/* + * Parse each safeBags of list, and convert decode data to the cert or key. +*/ +int32_t HITLS_PKCS12_ParseSafeBagList(BSL_ASN1_List *bagList, const uint8_t *password, uint32_t passLen, + HTILS_PKCS12_P12Info *p12); + +/* + * Parse attributes of a safeBag, and convert decode data to the real data. +*/ +int32_t HITLS_PKCS12_ParseSafeBagAttr(BSL_ASN1_Buffer *attribute, BSL_ASN1_List *attriList); + +/* + * Parse AuthSafeData of a p12, and convert decode data to the real data. +*/ +int32_t HITLS_PKCS12_ParseAuthSafeData(BSL_Buffer *encode, const uint8_t *password, uint32_t passLen, + HTILS_PKCS12_P12Info *p12); + +/* + * Parse MacData of a p12, and convert decode data to the real data. +*/ +int32_t HITLS_PKCS12_ParseMacData(BSL_Buffer *encode, HTILS_PKCS12_MacData *macData); + +/* + * Encode MacData of a p12. +*/ +int32_t HITLS_PKCS12_EncodeMacData(BSL_Buffer *initData, const HTILS_PKCS12_HmacParam *macParam, + HTILS_PKCS12_MacData *p12Mac, BSL_Buffer *encode); + +/* + * Encode contentInfo. +*/ +int32_t HITLS_PKCS12_EncodeContentInfo(BSL_Buffer *input, uint32_t encodeType, const CRYPT_EncodeParam *encryptParam, + BSL_Buffer *encode); + +/* + * Encode list, including contentInfo-list, safeContent-list. +*/ +int32_t HITLS_PKCS12_EncodeAsn1List(BSL_ASN1_List *list, uint32_t encodeType, const CRYPT_EncodeParam *encryptParam, + BSL_Buffer *encode); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRL_LOCAL_H \ No newline at end of file diff --git a/x509/pkcs12/src/hitls_pkcs12_common.c b/x509/pkcs12/src/hitls_pkcs12_common.c new file mode 100644 index 00000000..6e0a476a --- /dev/null +++ b/x509/pkcs12/src/hitls_pkcs12_common.c @@ -0,0 +1,1451 @@ +/* + * 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_x509.h" +#include "bsl_sal.h" +#include "sal_file.h" +#include "securec.h" +#include "hitls_x509_errno.h" +#include "hitls_x509_local.h" +#include "hitls_cert_local.h" +#include "hitls_cms_local.h" + +#include "bsl_obj_internal.h" +#include "bsl_err_internal.h" +#include "hitls_pkcs12_local.h" +#include "crypt_encode.h" +#include "crypt_eal_encode.h" +#include "bsl_type.h" +#include "bsl_bytes.h" + +#define HITLS_P12_CTX_SPECIFIC_TAG_EXTENSION 0 + +/* common Bag, including crl, cert, secret ... */ +BSL_ASN1_TemplateItem g_pk12CommonBagTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + /* bagId */ + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + /* bagValue */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_P12_CTX_SPECIFIC_TAG_EXTENSION, 0, 1}, + {BSL_ASN1_TAG_OCTETSTRING, 0, 2}, +}; + +typedef enum { + HITLS_PKCS12_COMMON_SAFEBAG_OID_IDX, + HITLS_PKCS12_COMMON_SAFEBAG_BAGVALUES_IDX, + HITLS_PKCS12_COMMON_SAFEBAG_MAX_IDX, +} HITLS_PKCS12_COMMON_SAFEBAG_IDX; + +/* parse bags, and revoker already knows they are one of the Commonbags */ +static int32_t ParseCommonSafeBag(BSL_Buffer *buffer, HTILS_PKCS12_CommonSafeBag *bag) +{ + uint8_t *temp = buffer->data; + uint32_t tempLen = buffer->dataLen; + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_COMMON_SAFEBAG_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_pk12CommonBagTempl, sizeof(g_pk12CommonBagTempl) / sizeof(g_pk12CommonBagTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, + &temp, &tempLen, asnArr, HITLS_PKCS12_COMMON_SAFEBAG_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BslOidString oidStr = {asnArr[HITLS_PKCS12_COMMON_SAFEBAG_OID_IDX].len, + (char *)asnArr[HITLS_PKCS12_COMMON_SAFEBAG_OID_IDX].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_UNKNOWN) { + ret = HITLS_PKCS12_ERR_PARSE_TYPE; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + bag->bagId = cid; + bag->bagValue = BSL_SAL_Malloc(sizeof(BSL_Buffer)); + if (bag->bagValue == NULL) { + ret = BSL_MALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + bag->bagValue->data = asnArr[HITLS_PKCS12_COMMON_SAFEBAG_BAGVALUES_IDX].buff; + bag->bagValue->dataLen = asnArr[HITLS_PKCS12_COMMON_SAFEBAG_BAGVALUES_IDX].len; + return HITLS_X509_SUCCESS; +} + +/* Convert commonBags to the cert */ +static int32_t ConverCertBag(HTILS_PKCS12_CommonSafeBag *bag, HITLS_X509_Cert **cert) +{ + if (bag == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + if (bag->bagId != BSL_CID_X509CERTIFICATE) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_CERTYPES); + return HITLS_PKCS12_ERR_INVALID_CERTYPES; + } + return HITLS_X509_CertParseBuff(BSL_FORMAT_ASN1, bag->bagValue, cert); +} + +static int32_t DecodeFriendlyName(BSL_ASN1_Buffer *buffer, BSL_Buffer *output) +{ + uint8_t *temp = buffer->buff; + uint32_t tempLen = buffer->len; + uint32_t valueLen = buffer->len; + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_BMPSTRING, &temp, &tempLen, &valueLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer input = { + .buff = temp, + .len = valueLen, + .tag = BSL_ASN1_TAG_BMPSTRING, + }; + BSL_ASN1_Buffer decode = {0}; + ret = BSL_ASN1_DecodePrimitiveItem(&input, &decode); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + output->data = decode.buff; + output->dataLen = decode.len; + return ret; +} + +static int32_t ConverAttributes(BslCid cid, BSL_ASN1_Buffer *buffer, BSL_Buffer *output) +{ + int32_t ret; + uint8_t *temp = buffer->buff; + uint32_t tempLen = buffer->len; + uint32_t valueLen = buffer->len; + switch (cid) { + case BSL_CID_FRIENDLYNAME: + return DecodeFriendlyName(buffer, output); + case BSL_CID_LOCALKEYID: + ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_OCTETSTRING, &temp, &tempLen, &valueLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + output->data = BSL_SAL_Dump(temp, valueLen); + if (output->data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + output->dataLen = valueLen; + return HITLS_X509_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES); + return HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES; + } +} + +static int32_t ParseAttr(HITLS_X509_AttrEntry *entry, BSL_ASN1_List *list) +{ + HTILS_PKCS12_SafeBagAttr attr = {0}; + attr.attrId = entry->cid; + attr.attrValue = BSL_SAL_Malloc(sizeof(BSL_Buffer)); + if (attr.attrValue == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = ConverAttributes(entry->cid, &entry->attrValue, attr.attrValue); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(attr.attrValue); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_AddListItemDefault(&attr, sizeof(HTILS_PKCS12_SafeBagAttr), list); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_Free(attr.attrValue->data); + BSL_SAL_Free(attr.attrValue); + } + return ret; +} + +int32_t HITLS_PKCS12_ParseSafeBagAttr(BSL_ASN1_Buffer *attribute, BSL_ASN1_List *attriList) +{ + if (attribute->len == 0) { + return HITLS_X509_SUCCESS; // bagAttributes are OPTIONAL + } + + BSL_ASN1_List *list = BSL_LIST_New(sizeof(HITLS_X509_AttrEntry)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = HITLS_X509_ParseAttrList(attribute, list); + if (ret != BSL_SUCCESS) { + BSL_LIST_FREE(list, NULL); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_List *tmpList = list; + HITLS_X509_AttrEntry *node = BSL_LIST_GET_FIRST(tmpList); + while (node != NULL) { + ret = ParseAttr(node, attriList); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto err; + } + node = BSL_LIST_GET_NEXT(tmpList); + } +err: + BSL_LIST_FREE(list, NULL); + return ret; +} + +/* + SafeBag ::= SEQUENCE { + bagId BAG-TYPE.&id ({PKCS12BagSet}) + bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), + bagAttributes SET OF PKCS12Attribute OPTIONAL + } +*/ +BSL_ASN1_TemplateItem g_pk12SafeBagTempl[] = { + /* bagId */ + {BSL_ASN1_TAG_OBJECT_ID, BSL_ASN1_FLAG_DEFAULT, 0}, + /* bagValue */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_P12_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_HEADERONLY, 0}, + /* bagAttributes */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_OPTIONAL, 0}, +}; + +typedef enum { + HITLS_PKCS12_SAFEBAG_OID_IDX, + HITLS_PKCS12_SAFEBAG_BAGVALUES_IDX, + HITLS_PKCS12_SAFEBAG_BAGATTRIBUTES_IDX, + HITLS_PKCS12_SAFEBAG_MAX_IDX, +} HITLS_PKCS12_SAFEBAG_IDX; + +/* + * Parse the 'safeBag' of p12. This interface only parses the outermost layer and attributes of safeBag, + * others are handed over to the next layer for parsing +*/ +static int32_t ParseSafeBag(BSL_Buffer *buffer, HTILS_PKCS12_SafeBag *safeBag) +{ + uint8_t *temp = buffer->data; + uint32_t tempLen = buffer->dataLen; + BSL_ASN1_Template templ = {g_pk12SafeBagTempl, sizeof(g_pk12SafeBagTempl) / sizeof(g_pk12SafeBagTempl[0])}; + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_SAFEBAG_MAX_IDX] = {0}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_PKCS12_SAFEBAG_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BslOidString oid = {asnArr[HITLS_PKCS12_SAFEBAG_OID_IDX].len, (char *)asnArr[HITLS_PKCS12_SAFEBAG_OID_IDX].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oid); + if (cid == BSL_CID_UNKNOWN) { + ret = HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_List *attributes = NULL; + BSL_Buffer *bag = BSL_SAL_Malloc(sizeof(BSL_Buffer)); + if (bag == NULL) { + ret = BSL_MALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + bag->data = BSL_SAL_Dump(asnArr[HITLS_PKCS12_SAFEBAG_BAGVALUES_IDX].buff, + asnArr[HITLS_PKCS12_SAFEBAG_BAGVALUES_IDX].len); + if (bag->data == NULL) { + ret = BSL_MALLOC_FAIL; + goto err; + } + bag->dataLen = asnArr[HITLS_PKCS12_SAFEBAG_BAGVALUES_IDX].len; + attributes = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBagAttr)); + if (attributes == NULL) { + ret = BSL_MALLOC_FAIL; + goto err; + } + ret = HITLS_PKCS12_ParseSafeBagAttr(asnArr + HITLS_PKCS12_SAFEBAG_BAGATTRIBUTES_IDX, attributes); + if (ret != HITLS_X509_SUCCESS) { + goto err; + } + safeBag->attributes = attributes; + safeBag->bagId = cid; + safeBag->bag = bag; + return ret; +err: + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(bag->data); + BSL_SAL_FREE(bag); + BSL_LIST_FREE(attributes, HTILS_PKCS12_AttributesFree); + return ret; +} + +static int32_t ParsePKCS8ShroudedKeyBags(HTILS_PKCS12_P12Info *p12, const uint8_t *pwd, uint32_t pwdlen, + HTILS_PKCS12_SafeBag *safeBag) +{ + CRYPT_EAL_PkeyCtx *prikey = NULL; + int32_t ret = CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_ENCRYPT, + safeBag->bag, pwd, pwdlen, &prikey); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + p12->key->value.key = prikey; + p12->key->attributes = safeBag->attributes; + safeBag->attributes = NULL; + return HITLS_X509_SUCCESS; +} + +static int32_t ParseCertBagAndAddList(HTILS_PKCS12_P12Info *p12, HTILS_PKCS12_SafeBag *safeBag) +{ + HTILS_PKCS12_CommonSafeBag bag = {0}; + int32_t ret = ParseCommonSafeBag(safeBag->bag, &bag); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + HITLS_X509_Cert *cert = NULL; + ret = ConverCertBag(&bag, &cert); + BSL_SAL_FREE(bag.bagValue); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + HTILS_PKCS12_Bag *bagData = BSL_SAL_Malloc(sizeof(HTILS_PKCS12_Bag)); + if (bagData == NULL) { + HITLS_X509_CertFree(cert); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + bagData->attributes = safeBag->attributes; + bagData->value.cert = cert; + ret = BSL_LIST_AddElement(p12->certList, bagData, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + bagData->attributes = NULL; + BSL_SAL_Free(bagData); + HITLS_X509_CertFree(cert); + BSL_ERR_PUSH_ERROR(ret); + } + safeBag->attributes = NULL; + return ret; +} + +/* Parse a Safebag to the data we need, such as a private key, etc */ +int32_t HITLS_PKCS12_ConverSafeBag(HTILS_PKCS12_SafeBag *safeBag, const uint8_t *pwd, uint32_t pwdlen, + HTILS_PKCS12_P12Info *p12) +{ + if (safeBag == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + switch (safeBag->bagId) { + case BSL_CID_PKCS8SHROUDEDKEYBAG: + if (p12->key->value.key != NULL) { + return HITLS_X509_SUCCESS; + } + return ParsePKCS8ShroudedKeyBags(p12, pwd, pwdlen, safeBag); + case BSL_CID_CERTBAG: + return ParseCertBagAndAddList(p12, safeBag); + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE); + return HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE; + } +} + +static void BagListsDestroyCb(void *bag) +{ + HTILS_PKCS12_SafeBagFree((HTILS_PKCS12_SafeBag *)bag); +} + +/* + * Defined in RFC 2531 + * ContentInfo ::= SEQUENCE { + * contentType ContentType, + * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL + * } +*/ +BSL_ASN1_TemplateItem g_pk12ContentInfoTempl[] = { + /* content type */ + {BSL_ASN1_TAG_OBJECT_ID, BSL_ASN1_FLAG_DEFAULT, 0}, + /* content */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_P12_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_OPTIONAL, 0}, +}; + +typedef enum { + HITLS_PKCS12_CONTENT_OID_IDX, + HITLS_PKCS12_CONTENT_VALUE_IDX, + HITLS_PKCS12_CONTENT_MAX_IDX, +} HITLS_PKCS12_CONTENT_IDX; + +int32_t HITLS_PKCS12_ParseContentInfo(BSL_Buffer *encode, const uint8_t *password, uint32_t passLen, BSL_Buffer *data) +{ + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + BSL_ASN1_Template templ = {g_pk12ContentInfoTempl, + sizeof(g_pk12ContentInfoTempl) / sizeof(g_pk12ContentInfoTempl[0])}; + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_CONTENT_MAX_IDX] = {0}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_PKCS12_CONTENT_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BslOidString oid = {asnArr[HITLS_PKCS12_CONTENT_OID_IDX].len, (char *)asnArr[HITLS_PKCS12_CONTENT_OID_IDX].buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oid); + if (cid == BSL_CID_UNKNOWN) { + ret = HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE; + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_Buffer asnArrdata = {asnArr[HITLS_PKCS12_CONTENT_VALUE_IDX].buff, asnArr[HITLS_PKCS12_CONTENT_VALUE_IDX].len}; + switch (cid) { + case BSL_CID_DATA: + return CRYPT_EAL_ParseAsn1PKCS7Data(&asnArrdata, data); + case BSL_CID_ENCRYPTEDDATA: + return CRYPT_EAL_ParseAsn1PKCS7EncryptedData(&asnArrdata, password, passLen, data); + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE); + return HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE; + } +} + +/* Parse each safebag from list, and extract the data we need, such as a private key, etc */ +int32_t HITLS_PKCS12_ParseSafeBagList(BSL_ASN1_List *bagList, const uint8_t *password, + uint32_t passLen, HTILS_PKCS12_P12Info *p12) +{ + if (bagList == NULL || BSL_LIST_COUNT(bagList) == 0) { + return HITLS_X509_SUCCESS; + } + int32_t ret; + HTILS_PKCS12_SafeBag *node = BSL_LIST_GET_FIRST(bagList); + while (node != NULL) { + ret = HITLS_PKCS12_ConverSafeBag(node, password, passLen, p12); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + node = BSL_LIST_GET_NEXT(bagList); + } + return HITLS_X509_SUCCESS; +} + +static BSL_Buffer *FindLocatedId(BSL_ASN1_List *attributes) +{ + if (attributes == NULL) { + return NULL; + } + HTILS_PKCS12_SafeBagAttr *node = BSL_LIST_GET_FIRST(attributes); + while (node != NULL) { + if (node->attrId == BSL_CID_LOCALKEYID) { + return node->attrValue; + } + node = BSL_LIST_GET_NEXT(attributes); + } + return NULL; +} + +static int32_t SetEntityCert(HTILS_PKCS12_P12Info *p12) +{ + if (p12->key == NULL) { + return HITLS_X509_SUCCESS; + } + + BSL_Buffer *keyId = FindLocatedId(p12->key->attributes); + if (keyId == NULL) { + return HITLS_X509_SUCCESS; + } + + BSL_ASN1_List *bags = p12->certList; + HTILS_PKCS12_Bag *node = BSL_LIST_GET_FIRST(bags); + while (node != NULL) { + BSL_Buffer *certId = FindLocatedId(node->attributes); + if (certId != NULL && certId->dataLen == keyId->dataLen) { + if (memcmp(certId->data, keyId->data, keyId->dataLen) == 0) { + p12->entityCert->attributes = node->attributes; + p12->entityCert->value.cert = node->value.cert; + BSL_LIST_DeleteCurrent(bags, NULL); + return HITLS_X509_SUCCESS; + } + } + node = BSL_LIST_GET_NEXT(bags); + } + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NO_ENTITYCERT); + return HITLS_PKCS12_ERR_NO_ENTITYCERT; +} + +static int32_t ParseSafeBagList(BSL_Buffer *node, const uint8_t *password, uint32_t passLen, BSL_ASN1_List *bagLists) +{ + BSL_Buffer safeContent = {0}; + int32_t ret = HITLS_PKCS12_ParseContentInfo(node, password, passLen, &safeContent); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_PKCS12_ParseAsn1AddList(&safeContent, bagLists, BSL_CID_SAFECONTENT); + BSL_SAL_Free(safeContent.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +// The caller guarantees that the input is not empty +int32_t HITLS_PKCS12_ParseAuthSafeData(BSL_Buffer *encode, const uint8_t *password, uint32_t passLen, + HTILS_PKCS12_P12Info *p12) +{ + BSL_ASN1_List *bagLists = NULL; + BSL_Buffer *node = NULL; + BSL_ASN1_List *contentList = BSL_LIST_New(sizeof(BSL_Buffer)); + if (contentList == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = HITLS_PKCS12_ParseAsn1AddList(encode, contentList, BSL_CID_CONTENTINFO); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto err; + } + node = BSL_LIST_GET_FIRST(contentList); + + bagLists = BSL_LIST_New(sizeof(HTILS_PKCS12_SafeBag)); + if (bagLists == NULL) { + ret = BSL_MALLOC_FAIL; + BSL_ERR_PUSH_ERROR(ret); + goto err; + } + + while (node != NULL) { + ret = ParseSafeBagList(node, password, passLen, bagLists); + if (ret != HITLS_X509_SUCCESS) { + goto err; + } + node = BSL_LIST_GET_NEXT(contentList); + } + ret = HITLS_PKCS12_ParseSafeBagList(bagLists, password, passLen, p12); + if (ret != HITLS_X509_SUCCESS) { + goto err; + } + ret = SetEntityCert(p12); +err: + BSL_LIST_DeleteAll(bagLists, BagListsDestroyCb); + BSL_SAL_Free(bagLists); + BSL_LIST_DeleteAll(contentList, NULL); + BSL_SAL_Free(contentList); + return ret; +} + +static int32_t ParseContentInfoAsnItem(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, + BSL_ASN1_List *list) +{ + (void) param; + if (layer == 1) { + return HITLS_X509_SUCCESS; + } + BSL_Buffer buffer = {asn->buff, asn->len}; + return HITLS_X509_AddListItemDefault(&buffer, sizeof(BSL_Buffer), list); +} + +static int32_t ParseSafeContentAsnItem(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, + BSL_ASN1_List *list) +{ + (void) param; + if (layer == 1) { + return HITLS_X509_SUCCESS; + } + BSL_Buffer buffer = {asn->buff, asn->len}; + HTILS_PKCS12_SafeBag safeBag = {0}; + int32_t ret = ParseSafeBag(&buffer, &safeBag); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_AddListItemDefault(&safeBag, sizeof(HTILS_PKCS12_SafeBag), list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(safeBag.bag); + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t HITLS_PKCS12_ParseAsn1AddList(BSL_Buffer *encode, BSL_ASN1_List *list, uint32_t parseType) +{ + if (encode == NULL || encode->data == NULL || list == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE}; + BSL_ASN1_DecodeListParam listParam = {2, expTag}; + BSL_ASN1_Buffer asn = { + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + encode->dataLen, + encode->data, + }; + int32_t ret; + switch (parseType) { + case BSL_CID_CONTENTINFO: + ret = BSL_ASN1_DecodeListItem(&listParam, &asn, &ParseContentInfoAsnItem, NULL, list); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); // Resources are released by the caller. + return ret; + } + return HITLS_X509_SUCCESS; + + case BSL_CID_SAFECONTENT: + ret = BSL_ASN1_DecodeListItem(&listParam, &asn, &ParseSafeContentAsnItem, NULL, list); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); // Resources are released by the caller. + return ret; + } + return HITLS_X509_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE); + return HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE; + } +} + +/* + * MacData ::= SEQUENCE { + * mac DigestInfo, + * macSalt OCTET STRING, + * iterations INTEGER DEFAULT 1 + * -- Note: The default is for historical reasons and its + * -- use is deprecated. + * } +*/ +BSL_ASN1_TemplateItem g_p12MacDataTempl[] = { + /* DigestInfo */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 0}, + /* macSalt */ + {BSL_ASN1_TAG_OCTETSTRING, 0, 0}, + /* iterations */ + {BSL_ASN1_TAG_INTEGER, 0, 0}, +}; + +typedef enum { + HITLS_PKCS12_MACDATA_DIGESTINFO_IDX, + HITLS_PKCS12_MACDATA_SALT_IDX, + HITLS_PKCS12_MACDATA_ITER_IDX, + HITLS_PKCS12_MACDATA_MAX_IDX, +} HITLS_PKCS12_MACDATA_IDX; + +int32_t HITLS_PKCS12_ParseMacData(BSL_Buffer *encode, HTILS_PKCS12_MacData *macData) +{ + if (encode == NULL || encode->data == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + BSL_ASN1_Buffer asn1[HITLS_PKCS12_MACDATA_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_p12MacDataTempl, sizeof(g_p12MacDataTempl) / sizeof(g_p12MacDataTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asn1, HITLS_PKCS12_MACDATA_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer mac = {0}; + BSL_Buffer digestInfo = {asn1[HITLS_PKCS12_MACDATA_DIGESTINFO_IDX].buff, + asn1[HITLS_PKCS12_MACDATA_DIGESTINFO_IDX].len}; + BslCid cid = BSL_CID_UNKNOWN; + ret = CRYPT_EAL_ParseAsn1PKCS7DigestInfo(&digestInfo, &cid, &mac); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint8_t *salt = BSL_SAL_Malloc(asn1[HITLS_PKCS12_MACDATA_SALT_IDX].len); + if (salt == NULL) { + BSL_SAL_Free(mac.data); + ret = BSL_MALLOC_FAIL; + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return ret; + } + (void)memcpy_s(salt, asn1[HITLS_PKCS12_MACDATA_SALT_IDX].len, asn1[HITLS_PKCS12_MACDATA_SALT_IDX].buff, + asn1[HITLS_PKCS12_MACDATA_SALT_IDX].len); + uint32_t iter = 0; + ret = BSL_ASN1_DecodePrimitiveItem(&asn1[HITLS_PKCS12_MACDATA_ITER_IDX], &iter); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + macData->mac->data = mac.data; + macData->mac->dataLen = mac.dataLen; + macData->alg = cid; + macData->macSalt->data = salt; + macData->macSalt->dataLen = asn1[HITLS_PKCS12_MACDATA_SALT_IDX].len; + macData->interation = iter; + return HITLS_X509_SUCCESS; +} + +/* + * PFX ::= SEQUENCE { + * version INTEGER {v3(3)}(v3,...), + * authSafe ContentInfo, + * macData MacData OPTIONAL + * } +*/ +BSL_ASN1_TemplateItem g_p12TopLevelTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* pkcs12 */ + /* version */ + {BSL_ASN1_TAG_INTEGER, 0, 1}, /* tbs */ + /* authSafe */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, + /* macData */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_OPTIONAL, 1}, +}; + +typedef enum { + HITLS_PKCS12_TOPLEVEL_VERSION_IDX, + HITLS_PKCS12_TOPLEVEL_AUTHSAFE_IDX, + HITLS_PKCS12_TOPLEVEL_MACDATA_IDX, + HITLS_PKCS12_TOPLEVEL_MAX_IDX, +} HITLS_PKCS12_TOPLEVEL_IDX; + +static void ClearMacData(HTILS_PKCS12_MacData *p12Mac) +{ + BSL_SAL_FREE(p12Mac->mac->data); + BSL_SAL_FREE(p12Mac->macSalt->data); + p12Mac->macSalt->dataLen = 0; + p12Mac->mac->dataLen = 0; + p12Mac->mac->data = NULL; + p12Mac->macSalt->data = NULL; + p12Mac->interation = 0; + p12Mac->alg = BSL_CID_UNKNOWN; +} + +static int32_t ParseMacDataAndVerify(BSL_Buffer *initData, BSL_Buffer *macData, const HTILS_PKCS12_PwdParam *pwdParam, + HTILS_PKCS12_MacData *p12Mac) +{ + int32_t ret = HITLS_PKCS12_ParseMacData(macData, p12Mac); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_Buffer verify = {0}; + ret = HTILS_PKCS12_CalMac(&verify, pwdParam->macPwd, initData, p12Mac); + if (ret != HITLS_X509_SUCCESS) { + ClearMacData(p12Mac); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (p12Mac->mac->dataLen != verify.dataLen || memcmp(verify.data, p12Mac->mac->data, verify.dataLen != 0)) { + ClearMacData(p12Mac); + BSL_SAL_Free(verify.data); + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_VERIFY_FAIL); + return HITLS_PKCS12_ERR_VERIFY_FAIL; + } + BSL_SAL_Free(verify.data); + return HITLS_X509_SUCCESS; +} + +static int32_t ParseAsn1PKCS12(BSL_Buffer *encode, const HTILS_PKCS12_PwdParam *pwdParam, + HTILS_PKCS12_P12Info *p12, bool needMacVerify) +{ + uint32_t version = 0; + uint8_t *temp = encode->data; + uint32_t tempLen = encode->dataLen; + BSL_ASN1_Buffer asn1[HITLS_PKCS12_TOPLEVEL_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_p12TopLevelTempl, sizeof(g_p12TopLevelTempl) / sizeof(g_p12TopLevelTempl[0])}; + HTILS_PKCS12_MacData *p12Mac = p12->macData; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asn1, HITLS_PKCS12_TOPLEVEL_MAX_IDX); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_ASN1_DecodePrimitiveItem(&asn1[HITLS_PKCS12_TOPLEVEL_VERSION_IDX], &version); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (version != 3) { // RFC 7292 requires that version = 3. + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_PFX); + return HITLS_PKCS12_ERR_INVALID_PFX; + } + + BSL_Buffer macData = {asn1[HITLS_PKCS12_TOPLEVEL_MACDATA_IDX].buff, asn1[HITLS_PKCS12_TOPLEVEL_MACDATA_IDX].len}; + BSL_Buffer contentInfo = {asn1[HITLS_PKCS12_TOPLEVEL_AUTHSAFE_IDX].buff, + asn1[HITLS_PKCS12_TOPLEVEL_AUTHSAFE_IDX].len}; + BSL_Buffer initData = {0}; + ret = HITLS_PKCS12_ParseContentInfo(&contentInfo, NULL, 0, &initData); + if (ret != HITLS_X509_SUCCESS) { + return ret; // has pushed error code. + } + if (needMacVerify) { + ret = ParseMacDataAndVerify(&initData, &macData, pwdParam, p12Mac); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(initData.data); + return ret; // has pushed error code. + } + } + ret = HITLS_PKCS12_ParseAuthSafeData(&initData, pwdParam->encPwd->data, pwdParam->encPwd->dataLen, p12); + BSL_SAL_Free(initData.data); + if (ret != HITLS_X509_SUCCESS) { + ClearMacData(p12Mac); + return ret; // has pushed error code. + } + p12->version = version; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_PKCS12_ParseBuff(int32_t format, BSL_Buffer *encode, const HTILS_PKCS12_PwdParam *pwdParam, + HTILS_PKCS12_P12Info *p12, bool needMacVerify) +{ + if (encode == NULL || pwdParam == NULL || pwdParam->encPwd == NULL || pwdParam->encPwd->data == NULL + || p12 == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + switch (format) { + case BSL_FORMAT_ASN1: + return ParseAsn1PKCS12(encode, pwdParam, p12, needMacVerify); + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NOT_SUPPORT_FORMAT); + return HITLS_PKCS12_ERR_NOT_SUPPORT_FORMAT; + } +} + +int32_t HITLS_PKCS12_ParseFile(int32_t format, const char *path, const HTILS_PKCS12_PwdParam *pwdParam, + HTILS_PKCS12_P12Info *p12, bool needMacVerify) +{ + if (path == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer encode = {data, dataLen}; + ret = HITLS_PKCS12_ParseBuff(format, &encode, pwdParam, p12, needMacVerify); + BSL_SAL_Free(data); + return ret; +} + +static void FreeListBuff(BSL_ASN1_Buffer *asnBuf, int32_t count) +{ + for (int32_t i = 0; i < count; i++) { + BSL_SAL_FREE(asnBuf[i].buff); + } + BSL_SAL_FREE(asnBuf); +} + +static int32_t EncodeAttrValue(HTILS_PKCS12_SafeBagAttr *attribute, BSL_Buffer *encode) +{ + BSL_ASN1_Buffer asnArr = {0}; + int32_t ret; + + asnArr.buff = attribute->attrValue->data; + asnArr.len = attribute->attrValue->dataLen; + switch (attribute->attrId) { + case BSL_CID_FRIENDLYNAME: + asnArr.tag = BSL_ASN1_TAG_BMPSTRING; + BSL_ASN1_TemplateItem nameTemplItem = {BSL_ASN1_TAG_BMPSTRING, 0, 0}; + BSL_ASN1_Template nameTempl = {&nameTemplItem, 1}; + ret = BSL_ASN1_EncodeTemplate(&nameTempl, &asnArr, 1, &encode->data, &encode->dataLen); + break; + case BSL_CID_LOCALKEYID: + asnArr.tag = BSL_ASN1_TAG_OCTETSTRING; + BSL_ASN1_TemplateItem locatedIdTemplItem = {BSL_ASN1_TAG_OCTETSTRING, 0, 0}; + BSL_ASN1_Template locatedIdTempl = {&locatedIdTemplItem, 1}; + ret = BSL_ASN1_EncodeTemplate(&locatedIdTempl, &asnArr, 1, &encode->data, &encode->dataLen); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES); + return HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES; + } + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t HITLS_PKCS12_EncodeAttrList(BSL_ASN1_List *list, BSL_ASN1_Buffer *attr) +{ + int32_t count = BSL_LIST_COUNT(list); + /* no attributes */ + if (count <= 0) { + attr->buff = NULL; + attr->len = 0; + return HITLS_X509_SUCCESS; + } + int32_t ret; + BSL_ASN1_List *attrList = BSL_LIST_New(sizeof(HITLS_X509_AttrEntry)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + goto err; + } + + HTILS_PKCS12_SafeBagAttr *node = NULL; + for (node = BSL_LIST_GET_FIRST(list); node != NULL; node = BSL_LIST_GET_NEXT(list)) { + HITLS_X509_AttrEntry entry = {0}; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(node->attrId); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES); + ret = HITLS_PKCS12_ERR_INVALID_SAFEBAG_ATTRIBUTES; + goto err; + } + entry.attrId.tag = BSL_ASN1_TAG_OBJECT_ID; + entry.attrId.buff = (uint8_t *)oidStr->octs; + entry.attrId.len = oidStr->octetLen; + BSL_Buffer buffer = {0}; + ret = EncodeAttrValue(node, &buffer); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto err; + } + entry.attrValue.tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET; + entry.attrValue.buff = buffer.data; + entry.attrValue.len = buffer.dataLen; + entry.cid = node->attrId; + ret = HITLS_X509_AddListItemDefault(&entry, sizeof(HITLS_X509_AttrEntry), attrList); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(buffer.data); + BSL_ERR_PUSH_ERROR(ret); + goto err; + } + } + ret = HITLS_X509_EncodeAttrList(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, attrList, attr); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } +err: + BSL_LIST_FREE(attrList, (BSL_LIST_PFUNC_FREE)HITLS_X509_AttrEntryFree); + return ret; +} + +static int32_t EncodeCertBag(HITLS_X509_Cert *cert, uint32_t certType, uint8_t **encode, uint32_t *encodeLen) +{ + int32_t ret; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(certType); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_ALGO); + return HITLS_PKCS12_ERR_INVALID_ALGO; + } + BSL_Buffer certBuff = {0}; + ret = HITLS_X509_CertGenBuff(BSL_FORMAT_ASN1, cert, &certBuff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_COMMON_SAFEBAG_MAX_IDX] = { + { + .buff = (uint8_t *)oidStr->octs, + .len = oidStr->octetLen, + .tag = BSL_ASN1_TAG_OBJECT_ID, + }, { + .buff = certBuff.data, + .len = certBuff.dataLen, + .tag = BSL_ASN1_TAG_OCTETSTRING, + }}; + + BSL_ASN1_Template templ = {g_pk12CommonBagTempl, sizeof(g_pk12CommonBagTempl) / sizeof(g_pk12CommonBagTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, HITLS_PKCS12_COMMON_SAFEBAG_MAX_IDX, encode, encodeLen); + BSL_SAL_Free(certBuff.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeSafeBag(HTILS_PKCS12_Bag *bag, uint32_t encodeType, const CRYPT_EncodeParam *encryptParam, + uint8_t **output, uint32_t *outputLen) +{ + int32_t ret; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(encodeType); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_ALGO); + return HITLS_PKCS12_ERR_INVALID_ALGO; + } + BSL_Buffer encode = {0}; + switch (encodeType) { + case BSL_CID_PKCS8SHROUDEDKEYBAG: + ret = CRYPT_EAL_EncodeBuffKey(bag->value.key, encryptParam, BSL_FORMAT_ASN1, CRYPT_PRIKEY_PKCS8_ENCRYPT, + &encode); + break; + case BSL_CID_CERTBAG: + ret = EncodeCertBag(bag->value.cert, BSL_CID_X509CERTIFICATE, &encode.data, &encode.dataLen); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE); + return HITLS_PKCS12_ERR_INVALID_SAFEBAG_TYPE; + } + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_SAFEBAG_MAX_IDX] = { + { + .buff = (uint8_t *)oidStr->octs, + .len = oidStr->octetLen, + .tag = BSL_ASN1_TAG_OBJECT_ID, + }, { + .buff = encode.data, + .len = encode.dataLen, + .tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_P12_CTX_SPECIFIC_TAG_EXTENSION, + }}; + + ret = HITLS_PKCS12_EncodeAttrList(bag->attributes, &asnArr[HITLS_PKCS12_SAFEBAG_BAGATTRIBUTES_IDX]); + if (ret != BSL_SUCCESS) { + BSL_SAL_Free(encode.data); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asnArr[HITLS_PKCS12_SAFEBAG_BAGATTRIBUTES_IDX].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET; + + BSL_ASN1_Template templ = {g_pk12SafeBagTempl, sizeof(g_pk12SafeBagTempl) / sizeof(g_pk12SafeBagTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, HITLS_PKCS12_SAFEBAG_MAX_IDX, output, outputLen); + BSL_SAL_Free(encode.data); + BSL_SAL_Free(asnArr[HITLS_PKCS12_SAFEBAG_BAGATTRIBUTES_IDX].buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeP7Data(BSL_Buffer *input, BSL_Buffer *encode) +{ + BSL_ASN1_Buffer asnArr = {0}; + asnArr.buff = input->data; + asnArr.tag = BSL_ASN1_TAG_OCTETSTRING; + asnArr.len = input->dataLen; + BSL_ASN1_TemplateItem dataTemplItem = {BSL_ASN1_TAG_OCTETSTRING, 0, 0}; + BSL_ASN1_Template dataTempl = {&dataTemplItem, 1}; + int32_t ret = BSL_ASN1_EncodeTemplate(&dataTempl, &asnArr, 1, &encode->data, &encode->dataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +int32_t HITLS_PKCS12_EncodeContentInfo(BSL_Buffer *input, uint32_t encodeType, const CRYPT_EncodeParam *encryptParam, + BSL_Buffer *encode) +{ + int32_t ret; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(encodeType); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_ALGO); + return HITLS_PKCS12_ERR_INVALID_ALGO; + } + BSL_Buffer initData = {0}; + switch (encodeType) { + case BSL_CID_DATA: + ret = EncodeP7Data(input, &initData); + break; + case BSL_CID_ENCRYPTEDDATA: + ret = CRYPT_EAL_EncodePKCS7EncryptDataBuff(input, encryptParam, &initData); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_CONTENTINFO); + return HITLS_PKCS12_ERR_INVALID_CONTENTINFO; + } + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_CONTENT_MAX_IDX] = { + { + .buff = (uint8_t *)oidStr->octs, + .len = oidStr->octetLen, + .tag = BSL_ASN1_TAG_OBJECT_ID, + }, { + .buff = initData.data, + .len = initData.dataLen, + .tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_P12_CTX_SPECIFIC_TAG_EXTENSION, + }}; + + BSL_ASN1_Template templ = {g_pk12ContentInfoTempl, + sizeof(g_pk12ContentInfoTempl) / sizeof(g_pk12ContentInfoTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, HITLS_PKCS12_CONTENT_MAX_IDX, &encode->data, &encode->dataLen); + BSL_SAL_Free(initData.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeSafeContent(BSL_ASN1_Buffer **output, BSL_ASN1_List *list, uint32_t encodeType, + const CRYPT_EncodeParam *encryptParam) +{ + BSL_ASN1_Buffer *asnBuf = BSL_SAL_Calloc(list->count, sizeof(BSL_ASN1_Buffer)); + if (asnBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t iter = 0; + int32_t ret = HITLS_X509_SUCCESS; + HTILS_PKCS12_Bag *node = NULL; + for (node = BSL_LIST_GET_FIRST(list); node != NULL; node = BSL_LIST_GET_NEXT(list), iter++) { + ret = EncodeSafeBag(node, encodeType, encryptParam, &asnBuf[iter].buff, &asnBuf[iter].len); + if (ret != BSL_SUCCESS) { + FreeListBuff(asnBuf, iter); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asnBuf[iter].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + } + *output = asnBuf; + return ret; +} + +static int32_t EncodeContentInfoList(BSL_ASN1_Buffer **output, BSL_ASN1_List *list) +{ + BSL_ASN1_Buffer *asnBuf = BSL_SAL_Calloc(list->count, sizeof(BSL_ASN1_Buffer)); + if (asnBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t iter = 0; + int32_t ret = HITLS_X509_SUCCESS; + BSL_Buffer *node = NULL; + for (node = BSL_LIST_GET_FIRST(list); node != NULL; node = BSL_LIST_GET_NEXT(list), iter++) { + asnBuf[iter].buff = BSL_SAL_Dump(node->data, node->dataLen); + if (asnBuf[iter].buff == NULL) { + FreeListBuff(asnBuf, iter); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + asnBuf[iter].len = node->dataLen; + asnBuf[iter].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + } + *output = asnBuf; + return ret; +} + +int32_t HITLS_PKCS12_EncodeAsn1List(BSL_ASN1_List *list, uint32_t encodeType, const CRYPT_EncodeParam *encryptParam, + BSL_Buffer *encode) +{ + int32_t count = BSL_LIST_COUNT(list); + BSL_ASN1_Buffer *asnBuf = NULL; + int32_t ret; + switch (encodeType) { + case BSL_CID_CONTENTINFO: + ret = EncodeContentInfoList(&asnBuf, list); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + break; + case BSL_CID_PKCS8SHROUDEDKEYBAG: + case BSL_CID_CERTBAG: + ret = EncodeSafeContent(&asnBuf, list, encodeType, encryptParam); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_CONTENTINFO); + return HITLS_PKCS12_ERR_INVALID_CONTENTINFO; + } + static BSL_ASN1_TemplateItem listTempl = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0 }; + BSL_ASN1_Template templ = {&listTempl, 1}; + BSL_ASN1_Buffer out = {0}; + ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, count, &templ, asnBuf, count, &out); + if (ret != HITLS_X509_SUCCESS) { + FreeListBuff(asnBuf, count); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_ASN1_EncodeTemplate(&templ, &out, 1, &encode->data, &encode->dataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + FreeListBuff(asnBuf, count); + BSL_SAL_FREE(out.buff); + return ret; +} + +int32_t HITLS_PKCS12_EncodeMacData(BSL_Buffer *initData, const HTILS_PKCS12_HmacParam *macParam, + HTILS_PKCS12_MacData *p12Mac, BSL_Buffer *encode) +{ + BSL_Buffer mac = {0}; + BSL_Buffer digestInfo = {0}; + p12Mac->alg = macParam->macId; + p12Mac->interation = macParam->itCnt; + p12Mac->macSalt->dataLen = macParam->saltLen; + BSL_Buffer macPwd = {macParam->pwd, macParam->pwdLen}; + int32_t ret = HTILS_PKCS12_CalMac(&mac, &macPwd, initData, p12Mac); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = CRYPT_EAL_EncodePKCS7DigestInfoBuff(p12Mac->alg, &mac, &digestInfo); + BSL_SAL_FREE(mac.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_MACDATA_MAX_IDX] = { + { + .buff = digestInfo.data, + .len = digestInfo.dataLen, + .tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + }, { + .buff = p12Mac->macSalt->data, + .len = p12Mac->macSalt->dataLen, + .tag = BSL_ASN1_TAG_OCTETSTRING, + }}; + + ret = BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, p12Mac->interation, &asnArr[HITLS_PKCS12_MACDATA_ITER_IDX]); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(digestInfo.data); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Template templ = {g_p12MacDataTempl, sizeof(g_p12MacDataTempl) / sizeof(g_p12MacDataTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, HITLS_PKCS12_MACDATA_MAX_IDX, &encode->data, &encode->dataLen); + BSL_SAL_Free(digestInfo.data); + BSL_SAL_Free(asnArr[HITLS_PKCS12_MACDATA_ITER_IDX].buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeCertListAddList(HTILS_PKCS12_P12Info *p12, const CRYPT_EncodeParam *encParam, BSL_ASN1_List *list, + bool isNeedMac) +{ + int32_t ret; + HTILS_PKCS12_Bag *bag = NULL; + BSL_Buffer certEncode = {0}; + if (p12->entityCert->value.cert != NULL) { + bag = BSL_SAL_Malloc(sizeof(HTILS_PKCS12_Bag)); + if (bag == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + bag->attributes = p12->entityCert->attributes; + bag->value.cert = p12->entityCert->value.cert; + ret = BSL_LIST_AddElement(p12->certList, bag, BSL_LIST_POS_BEGIN); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(bag); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + if (BSL_LIST_COUNT(p12->certList) <= 0) { + return HITLS_X509_SUCCESS; + } + ret = HITLS_PKCS12_EncodeAsn1List(p12->certList, BSL_CID_CERTBAG, NULL, &certEncode); + if (p12->entityCert->value.cert != NULL) { + BSL_LIST_First(p12->certList); + BSL_LIST_DeleteCurrent(p12->certList, NULL); + } + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer contentInfoEncode = {0}; + if (isNeedMac) { + ret = HITLS_PKCS12_EncodeContentInfo(&certEncode, BSL_CID_ENCRYPTEDDATA, encParam, &contentInfoEncode); + } else { + ret = HITLS_PKCS12_EncodeContentInfo(&certEncode, BSL_CID_DATA, encParam, &contentInfoEncode); + } + BSL_SAL_FREE(certEncode.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_AddListItemDefault(&contentInfoEncode, sizeof(BSL_Buffer), list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(contentInfoEncode.data); + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeKeyAddList(HTILS_PKCS12_P12Info *p12, const CRYPT_EncodeParam *encParam, BSL_ASN1_List *list) +{ + if (p12->key->value.key == NULL) { + return HITLS_X509_SUCCESS; + } + + BSL_ASN1_List *keyList = BSL_LIST_New(sizeof(HTILS_PKCS12_Bag)); + if (keyList == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + HTILS_PKCS12_Bag bag = {0}; + BSL_Buffer keyEncode = {0}; + BSL_Buffer contentInfoEncode = {0}; + bag.attributes = p12->key->attributes; + bag.value.key = p12->key->value.key; + int32_t ret = HITLS_X509_AddListItemDefault(&bag, sizeof(HTILS_PKCS12_Bag), keyList); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(keyList); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_PKCS12_EncodeAsn1List(keyList, BSL_CID_PKCS8SHROUDEDKEYBAG, encParam, &keyEncode); + BSL_LIST_FREE(keyList, NULL); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = HITLS_PKCS12_EncodeContentInfo(&keyEncode, BSL_CID_DATA, NULL, &contentInfoEncode); + BSL_SAL_FREE(keyEncode.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_AddListItemDefault(&contentInfoEncode, sizeof(BSL_Buffer), list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(contentInfoEncode.data); + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static void FreeBuffer(void *buffer) +{ + if (buffer == NULL) { + return; + } + + BSL_Buffer *tmp = (BSL_Buffer *)buffer; + BSL_SAL_FREE(tmp->data); + BSL_SAL_Free(tmp); +} + +static int32_t EncodePkcs12(uint32_t version, BSL_Buffer *authSafe, BSL_Buffer *macData, BSL_Buffer *encode) +{ + BSL_ASN1_Buffer asnArr[HITLS_PKCS12_TOPLEVEL_MAX_IDX] = { + { + .buff = NULL, + .len = 0, + .tag = BSL_ASN1_TAG_INTEGER, + }, { + .buff = authSafe->data, + .len = authSafe->dataLen, + .tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + }, { + .buff = macData->data, + .len = macData->dataLen, + .tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + }}; + + int32_t ret = BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, version, asnArr); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_ASN1_Template templ = {g_p12TopLevelTempl, sizeof(g_p12TopLevelTempl) / sizeof(g_p12TopLevelTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, HITLS_PKCS12_TOPLEVEL_MAX_IDX, + &encode->data, &encode->dataLen); + BSL_SAL_Free(asnArr[HITLS_PKCS12_TOPLEVEL_VERSION_IDX].buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t EncodeP12Info(HTILS_PKCS12_P12Info *p12, const HTILS_PKCS12_EncodeParam *encodeParam, bool isNeedMac, + BSL_Buffer *encode) +{ + int32_t ret; + BSL_ASN1_List *list = BSL_LIST_New(sizeof(BSL_Buffer)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + ret = EncodeCertListAddList(p12, &encodeParam->certEncParam, list, isNeedMac); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(list, FreeBuffer); + return ret; + } + + ret = EncodeKeyAddList(p12, &encodeParam->keyEncParam, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(list, FreeBuffer); + return ret; + } + if (BSL_LIST_COUNT(list) <= 0) { + BSL_LIST_FREE(list, FreeBuffer); + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NONE_DATA); + return HITLS_PKCS12_ERR_NONE_DATA; + } + BSL_Buffer initData = {0}; + ret = HITLS_PKCS12_EncodeAsn1List(list, BSL_CID_CONTENTINFO, NULL, &initData); + BSL_LIST_FREE(list, FreeBuffer); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + + BSL_Buffer macData = {0}; + if (isNeedMac) { + ret = HITLS_PKCS12_EncodeMacData(&initData, &encodeParam->macParam, p12->macData, &macData); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(initData.data); + return ret; + } + } + + BSL_Buffer authSafe = {0}; + ret = HITLS_PKCS12_EncodeContentInfo(&initData, BSL_CID_DATA, NULL, &authSafe); + BSL_SAL_FREE(initData.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(macData.data); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = EncodePkcs12(p12->version, &authSafe, &macData, encode); + BSL_SAL_FREE(authSafe.data); + BSL_SAL_FREE(macData.data); + return ret; +} + +int32_t HITLS_PKCS12_GenBuff(int32_t format, HTILS_PKCS12_P12Info *p12, const HTILS_PKCS12_EncodeParam *encodeParam, + bool isNeedMac, BSL_Buffer *encode) +{ + if (p12 == NULL || encodeParam == NULL || encode == NULL || encode->data != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + switch (format) { + case BSL_FORMAT_ASN1: + return EncodeP12Info(p12, encodeParam, isNeedMac, encode); + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NOT_SUPPORT_FORMAT); + return HITLS_PKCS12_ERR_NOT_SUPPORT_FORMAT; + } +} + +int32_t HITLS_PKCS12_GenFile(int32_t format, HTILS_PKCS12_P12Info *p12, const HTILS_PKCS12_EncodeParam *encodeParam, + bool isNeedMac, const char *path) +{ + if (path == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + BSL_Buffer encode = {0}; + int32_t ret = HITLS_PKCS12_GenBuff(format, p12, encodeParam, isNeedMac, &encode); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_SAL_WriteFile(path, encode.data, encode.dataLen); + BSL_SAL_Free(encode.data); + return ret; +} diff --git a/x509/pkcs12/src/hitls_pkcs12_util.c b/x509/pkcs12/src/hitls_pkcs12_util.c new file mode 100644 index 00000000..716f4da2 --- /dev/null +++ b/x509/pkcs12/src/hitls_pkcs12_util.c @@ -0,0 +1,563 @@ +/* + * 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 "bsl_sal.h" +#include "sal_file.h" +#include "securec.h" +#include "hitls_pkcs12_local.h" +#include "bsl_sal.h" +#include "bsl_err_internal.h" +#include "hitls_x509_errno.h" +#include "crypt_eal_mac.h" +#include "crypt_eal_md.h" +#include "hitls_cert_local.h" +#include "crypt_eal_rand.h" +#include "crypt_errno.h" + +HTILS_PKCS12_SafeBag *HTILS_PKCS12_SafeBagNew() +{ + return BSL_SAL_Malloc(sizeof(HTILS_PKCS12_SafeBag)); +} + +static void AttributesFree(HTILS_PKCS12_SafeBagAttr *attribute) +{ + if (attribute == NULL) { + return; + } + + BSL_SAL_FREE(attribute->attrValue->data); + BSL_SAL_FREE(attribute->attrValue); + BSL_SAL_FREE(attribute); +} + +void HTILS_PKCS12_AttributesFree(void *attribute) +{ + AttributesFree((HTILS_PKCS12_SafeBagAttr *)attribute); + return; +} + +void HTILS_PKCS12_SafeBagFree(HTILS_PKCS12_SafeBag *safeBag) +{ + if (safeBag == NULL) { + return; + } + BSL_LIST_DeleteAll(safeBag->attributes, HTILS_PKCS12_AttributesFree); + BSL_SAL_FREE(safeBag->attributes); + BSL_SAL_CleanseData(safeBag->bag->data, safeBag->bag->dataLen); + BSL_SAL_FREE(safeBag->bag->data); + BSL_SAL_FREE(safeBag->bag); + BSL_SAL_Free(safeBag); + return; +} + +HTILS_PKCS12_MacData *HTILS_PKCS12_P12_MacDataNew(void) +{ + HTILS_PKCS12_MacData *macData = BSL_SAL_Calloc(1u, sizeof(HTILS_PKCS12_MacData)); + if (macData == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return NULL; + } + + BSL_Buffer *macSalt = BSL_SAL_Calloc(1u, sizeof(BSL_Buffer)); + if (macSalt == NULL) { + BSL_SAL_Free(macData); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return NULL; + } + + BSL_Buffer *mac = BSL_SAL_Calloc(1u, sizeof(BSL_Buffer)); + if (mac == NULL) { + BSL_SAL_Free(macSalt); + BSL_SAL_Free(mac); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return NULL; + } + macData->mac = mac; + macData->macSalt = macSalt; + return macData; +} + +void HTILS_PKCS12_p12_MacDataFree(HTILS_PKCS12_MacData *macData) +{ + if (macData == NULL) { + return; + } + + if (macData->mac != NULL) { + BSL_SAL_FREE(macData->mac->data); + BSL_SAL_Free(macData->mac); + } + + if (macData->macSalt != NULL) { + BSL_SAL_CleanseData(macData->macSalt->data, macData->macSalt->dataLen); + BSL_SAL_FREE(macData->macSalt->data); + BSL_SAL_Free(macData->macSalt); + } + BSL_SAL_Free(macData); +} + +HTILS_PKCS12_P12Info *HTILS_PKCS12_P12_InfoNew(void) +{ + HTILS_PKCS12_P12Info *p12 = BSL_SAL_Calloc(1u, sizeof(HTILS_PKCS12_P12Info)); + if (p12 == NULL) { + return NULL; + } + HTILS_PKCS12_MacData *macData = HTILS_PKCS12_P12_MacDataNew(); + if (macData == NULL) { + BSL_SAL_Free(p12); + return NULL; + } + HTILS_PKCS12_Bag *key = BSL_SAL_Calloc(1u, sizeof(HTILS_PKCS12_Bag)); + if (key == NULL) { + HTILS_PKCS12_p12_MacDataFree(macData); + BSL_SAL_Free(p12); + return NULL; + } + HTILS_PKCS12_Bag *entityCert = BSL_SAL_Calloc(1u, sizeof(HTILS_PKCS12_Bag)); + if (key == NULL) { + BSL_SAL_Free(entityCert); + HTILS_PKCS12_p12_MacDataFree(macData); + BSL_SAL_Free(p12); + return NULL; + } + BSL_ASN1_List *certList = BSL_LIST_New(sizeof(HTILS_PKCS12_Bag)); + if (certList == NULL) { + BSL_SAL_Free(entityCert); + BSL_SAL_Free(key); + BSL_SAL_Free(p12); + HTILS_PKCS12_p12_MacDataFree(macData); + return NULL; + } + p12->version = 3; // RFC7292 required the version = 3; + p12->key = key; + p12->entityCert = entityCert; + p12->certList = certList; + p12->macData = macData; + return p12; +} + +static void CertBagFree(void *value) +{ + if (value == NULL) { + return; + } + HTILS_PKCS12_Bag *bag = (HTILS_PKCS12_Bag *)value; + HITLS_X509_CertFree(bag->value.cert); + BSL_LIST_DeleteAll(bag->attributes, HTILS_PKCS12_AttributesFree); + BSL_SAL_FREE(bag->attributes); + BSL_SAL_FREE(bag); +} + +void HTILS_PKCS12_P12_InfoFree(HTILS_PKCS12_P12Info *p12) +{ + if (p12 == NULL) { + return; + } + + HITLS_X509_CertFree(p12->entityCert->value.cert); + BSL_LIST_DeleteAll(p12->entityCert->attributes, HTILS_PKCS12_AttributesFree); + BSL_SAL_FREE(p12->entityCert->attributes); + BSL_SAL_Free(p12->entityCert); + + CRYPT_EAL_PkeyFreeCtx(p12->key->value.key); + BSL_LIST_DeleteAll(p12->key->attributes, HTILS_PKCS12_AttributesFree); + BSL_SAL_FREE(p12->key->attributes); + BSL_SAL_Free(p12->key); + + BSL_LIST_DeleteAll(p12->certList, CertBagFree); + BSL_SAL_Free(p12->certList); + HTILS_PKCS12_p12_MacDataFree(p12->macData); + BSL_SAL_Free(p12); +} + +typedef struct { + CRYPT_MD_AlgId alg; + uint32_t u; + uint32_t v; +} Pkcs12KdfParam; + +/* + * The data comes from RFC7292. + * https://datatracker.ietf.org/doc/html/rfc7292#appendix-B.2 + */ +const Pkcs12KdfParam PKCS12KDF_PARAM[] = { + {.alg = CRYPT_MD_SHA224, .u = 28, .v = 64}, + {.alg = CRYPT_MD_SHA256, .u = 32, .v = 64}, + {.alg = CRYPT_MD_SHA384, .u = 48, .v = 128}, + {.alg = CRYPT_MD_SHA512, .u = 64, .v = 128}, +}; + +const Pkcs12KdfParam *FindKdfParam(CRYPT_MD_AlgId id) +{ + const Pkcs12KdfParam *param = NULL; + uint32_t num = sizeof(PKCS12KDF_PARAM) / sizeof(PKCS12KDF_PARAM[0]); + for (uint32_t i = 0; i < num; i++) { + if (PKCS12KDF_PARAM[i].alg == id) { + param = &PKCS12KDF_PARAM[i]; + return param; + } + } + return NULL; +} + +static int32_t InitKdfParam(const Pkcs12KdfParam *param, uint8_t **D, uint8_t **I, uint8_t **A, uint8_t **B) +{ + *D = BSL_SAL_Malloc(param->v); + *I = BSL_SAL_Malloc(param->v * 2); // len(I) = 2 * v. + *A = BSL_SAL_Malloc(param->u); + *B = BSL_SAL_Malloc(param->v); + if (*D == NULL || *I == NULL || *A == NULL || *B == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + BSL_SAL_FREE(*D); + BSL_SAL_FREE(*I); + BSL_SAL_FREE(*B); + BSL_SAL_FREE(*A); + return BSL_MALLOC_FAIL; + } + return HITLS_X509_SUCCESS; +} + +static int32_t MacLoop(uint32_t LoopTimes, CRYPT_EAL_MdCTX *ctx, const Pkcs12KdfParam *param, uint8_t *D, + uint8_t *I, uint8_t *A, uint32_t dataLen) +{ + int32_t ret; + uint32_t tempLen = param->u; + /* A = H(H(H(... H(D || I)))) */ + ret = CRYPT_EAL_MdInit(ctx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_MdUpdate(ctx, D, param->v); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_MdUpdate(ctx, I, param->v * 2); // len(I) = 2 * v. + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_MdFinal(ctx, A, &tempLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_EAL_MdDeinit(ctx); + + for (uint32_t j = 0; j < LoopTimes - 1; j++) { + ret = CRYPT_EAL_MdInit(ctx); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_MdUpdate(ctx, A, dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_MdFinal(ctx, A, &dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_EAL_MdDeinit(ctx); + } + return ret; +} + +int32_t HTILS_PKCS12_KDF(BSL_Buffer *output, const uint8_t *pwd, uint32_t pwdLen, HITLS_PKCS12_KDF_IDX id, + HTILS_PKCS12_MacData *macData) +{ + if (output == NULL || output->data == NULL || macData == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + if (pwd == NULL && pwdLen != 0) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + uint8_t *salt = macData->macSalt->data; + uint32_t saltLen = macData->macSalt->dataLen; + uint32_t n = output->dataLen; + uint32_t iter = macData->interation; + uint8_t *key = output->data; + + const Pkcs12KdfParam *param = FindKdfParam((CRYPT_MD_AlgId)macData->alg); + if (param == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_ALGO); + return HITLS_PKCS12_ERR_INVALID_ALGO; + } + CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx((CRYPT_MD_AlgId)macData->alg); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + + uint8_t *D = NULL; + uint8_t *A = NULL; + uint8_t *B = NULL; + uint8_t *I = NULL; + int32_t ret = InitKdfParam(param, &D, &I, &A, &B); + if (ret != HITLS_X509_SUCCESS) { + CRYPT_EAL_MdFreeCtx(ctx); + return ret; + } + + (void)memset_s(D, param->v, id, param->v); + (void)memset_s(I, 2 * param->v, 0, 2 * param->v); // we need 2 * v + + /* K = ceiling(s/v) + ceiling(p/v) + * = (pwdLen + param->v - 1) / param->v + (saltLen + param->v - 1) / param->v + */ + uint32_t k = ((pwdLen + saltLen - 2) / param->v) + 2; + + /* I = S||P */ + if (salt != NULL) { + for (uint32_t i = 0; i < param->v; i++) { + I[i] = salt[i % saltLen]; + } + } + + if (pwd != NULL) { + for (uint32_t i = 0; i < param->v; i++) { + I[i + param->v] = pwd[i % pwdLen]; + } + } + + /* C = ceiling(n/u) */ + uint32_t c = (n + param->u - 1) / param->u; + for (uint32_t i = 0; i < c; i++) { + ret = MacLoop(iter, ctx, param, D, I, A, param->u); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; // has pushed err code. + } + + uint32_t copyLen = n > param->u ? param->u : n; + if (memcpy_s(key, n, A, copyLen) != EOK) { + ret = BSL_MEMCPY_FAIL; + BSL_ERR_PUSH_ERROR(BSL_MEMCPY_FAIL); + goto ERR; + } + + n -= copyLen; + if (n == 0) { + goto ERR; + } + key = key + copyLen; + /* Concatenate copies of Ai to create a string B */ + for (uint32_t l = 0; l < param->v; l++) { + B[l] = A[l % param->u]; + } + /* I_j = (I_j + B + 1) mod 2^v */ + for (uint32_t m = 0; m < k; m++) { + uint8_t *tempI = I + m * param->v; + uint8_t carry = 1; + for (int32_t r = (uint32_t)param->v - 1; r >= 0; r--) { + uint8_t temp = tempI[r] + carry; + carry = temp < tempI[r] ? 1 : 0; + temp += B[r]; + carry = temp < B[r] ? 1 : 0; + tempI[r] = temp; + } + } + } + +ERR: + CRYPT_EAL_MdFreeCtx(ctx); + BSL_SAL_Free(D); + BSL_SAL_Free(I); + BSL_SAL_Free(B); + BSL_SAL_Free(A); + return ret; +} + +static uint32_t GetMacId(BslCid id) +{ + switch (id) { + case CRYPT_MD_SHA224: + return CRYPT_MAC_HMAC_SHA224; + case CRYPT_MD_SHA256: + return CRYPT_MAC_HMAC_SHA256; + case CRYPT_MD_SHA384: + return CRYPT_MAC_HMAC_SHA384; + case CRYPT_MD_SHA512: + return CRYPT_MAC_HMAC_SHA512; + default: + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_ALGO); + return HITLS_PKCS12_ERR_INVALID_ALGO; + } +} + +static int32_t Untf8ToUtf16(const uint8_t *src, uint8_t *target, uint32_t len) +{ + for (uint32_t i = 0; i < len; i++) { + if (src[i] > 127) { // the Max ascii < 127. + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_PASSWORD); + return HITLS_PKCS12_ERR_INVALID_PASSWORD; + } + target[2 * i + 1] = src[i]; // we need 2 space, [0,0] -> after encode = [0, data]; + } + return HITLS_X509_SUCCESS; +} + +static int32_t TransCodePwd(BSL_Buffer *pwd, uint8_t **transcoded, uint32_t *transcodedLen) +{ + if (pwd == NULL || pwd->data == NULL) { + *transcodedLen = 0; + return HITLS_X509_SUCCESS; + } + + uint32_t outputLen = 2 * pwd->dataLen + 2; // encodeLen = 2 * len, and two zeros at the end. + uint8_t *output = BSL_SAL_Calloc(1u, outputLen); + if (output == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = Untf8ToUtf16(pwd->data, output, pwd->dataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_CleanseData(output, outputLen); + BSL_SAL_FREE(output); + return ret; // has pushed err code. + } + *transcodedLen = outputLen; + *transcoded = output; + return HITLS_X509_SUCCESS; +} + +static int32_t GetHmacKey(BSL_Buffer *pwd, uint32_t macSize, HTILS_PKCS12_MacData *macData, uint8_t **keyData) +{ + uint32_t temPwdLen = 0; + uint8_t *temPwd = NULL; + int32_t ret = TransCodePwd(pwd, &temPwd, &temPwdLen); + if (ret != HITLS_X509_SUCCESS) { + return ret; // has pushed err code. + } + + uint8_t *key = BSL_SAL_Malloc(macSize); + if (key == NULL) { + BSL_SAL_CleanseData(temPwd, temPwdLen); + BSL_SAL_FREE(temPwd); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + BSL_Buffer keyBuffer = {key, macSize}; + ret = HTILS_PKCS12_KDF(&keyBuffer, temPwd, temPwdLen, HITLS_PKCS12_KDF_MACKEY_ID, macData); + BSL_SAL_CleanseData(temPwd, temPwdLen); + BSL_SAL_FREE(temPwd); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_CleanseData(key, macSize); + BSL_SAL_FREE(key); + return ret; + } + *keyData = key; + return ret; +} + +static int32_t ParamCheckAndInit(HTILS_PKCS12_MacData *macData, BSL_Buffer *pwd) +{ + if (macData == NULL || macData->macSalt == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_NULL_POINTER); + return HITLS_PKCS12_ERR_NULL_POINTER; + } + + if (pwd != NULL && pwd->data == NULL && pwd->dataLen != 0) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_PARAM); + return HITLS_PKCS12_ERR_INVALID_PARAM; + } + if (macData->interation < 1000) { // The nist sp800-132 required the minimum iteration count = 1000. + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_INTERATION); + return HITLS_PKCS12_ERR_INVALID_INTERATION; + } + + if (macData->macSalt->data == NULL) { + if (macData->macSalt->dataLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_PKCS12_ERR_INVALID_SALTLEN); + return HITLS_PKCS12_ERR_INVALID_SALTLEN; + } + uint8_t *salt = BSL_SAL_Malloc(macData->macSalt->dataLen); + if (salt == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = CRYPT_EAL_Randbytes(salt, macData->macSalt->dataLen); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_Free(salt); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + macData->macSalt->data = salt; + } + return HITLS_X509_SUCCESS; +} + +int32_t HTILS_PKCS12_CalMac(BSL_Buffer *output, BSL_Buffer *pwd, BSL_Buffer *initData, HTILS_PKCS12_MacData *macData) +{ + int32_t ret = ParamCheckAndInit(macData, pwd); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + uint32_t macId = GetMacId(macData->alg); + uint32_t macSize = CRYPT_EAL_MdGetDigestSize((CRYPT_MD_AlgId)macData->alg); + if (macId == BSL_CID_UNKNOWN || macSize == 0) { + return HITLS_PKCS12_ERR_INVALID_ALGO; // has pushed errcode. + } + uint8_t *keyData = NULL; + ret = GetHmacKey(pwd, macSize, macData, &keyData); + if (ret != HITLS_X509_SUCCESS) { + return ret; // has pushed err code. + } + + CRYPT_EAL_MacCtx *ctx = CRYPT_EAL_MacNewCtx(macId); + if (ctx == NULL) { + BSL_SAL_CleanseData(keyData, macSize); + BSL_SAL_FREE(keyData); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return ret; + } + ret = CRYPT_EAL_MacInit(ctx, keyData, macSize); + BSL_SAL_CleanseData(keyData, macSize); + BSL_SAL_FREE(keyData); + if (ret != HITLS_X509_SUCCESS) { + CRYPT_EAL_MacFreeCtx(ctx); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_MacUpdate(ctx, initData->data, initData->dataLen); + if (ret != HITLS_X509_SUCCESS) { + CRYPT_EAL_MacFreeCtx(ctx); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint8_t *temp = BSL_SAL_Malloc(macSize); + if (temp == NULL) { + CRYPT_EAL_MacFreeCtx(ctx); + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + uint32_t tempLen = macSize; + ret = CRYPT_EAL_MacFinal(ctx, temp, &tempLen); + CRYPT_EAL_MacFreeCtx(ctx); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(temp); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + output->data = temp; + output->dataLen = tempLen; + return ret; +} diff --git a/x509/x509_cert/include/hitls_cert_local.h b/x509/x509_cert/include/hitls_cert_local.h new file mode 100644 index 00000000..c36e1584 --- /dev/null +++ b/x509/x509_cert/include/hitls_cert_local.h @@ -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 HITLS_CERT_LOCAL_H +#define HITLS_CERT_LOCAL_H + +#include +#include "bsl_asn1.h" +#include "bsl_obj.h" +#include "sal_atomic.h" +#include "hitls_x509_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HITLS_X509_CERT_PARSE_FLAG 0x01 +#define HITLS_X509_CERT_GEN_FLAG 0x02 + +typedef struct { + uint8_t *tbsRawData; + uint32_t tbsRawDataLen; + + int32_t version; + BSL_ASN1_Buffer serialNum; + HITLS_X509_Asn1AlgId signAlgId; + + BSL_ASN1_List *issuerName; + HITLS_X509_ValidTime validTime; + BSL_ASN1_List *subjectName; + + void *ealPubKey; + HITLS_X509_Ext ext; +} HITLS_X509_CertTbs; + +typedef struct _HITLS_X509_Cert { + int8_t flag; // Used to mark certificate parsing or generation, indicating resource release behavior. + + uint8_t *rawData; + uint32_t rawDataLen; + HITLS_X509_CertTbs tbs; + HITLS_X509_Asn1AlgId signAlgId; + BSL_ASN1_BitString signature; + + void *ealPrivKey; // Used to sign. + CRYPT_MD_AlgId signMdId; + BSL_SAL_RefCount references; +} HITLS_X509_Cert; + +int32_t HITLS_X509_CheckIssued(HITLS_X509_Cert *issue, HITLS_X509_Cert *subject, bool *res); +int32_t HITLS_X509_CertIsCA(HITLS_X509_Cert *cert, bool *res); +int32_t HITLS_X509_CertMulParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_List **certlist); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CERT_LOCAL_H \ No newline at end of file diff --git a/x509/x509_cert/src/hitls_x509_cert.c b/x509/x509_cert/src/hitls_x509_cert.c new file mode 100644 index 00000000..f7b9fb0b --- /dev/null +++ b/x509/x509_cert/src/hitls_x509_cert.c @@ -0,0 +1,1238 @@ +/* + * 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 +#include "securec.h" +#include "hitls_x509.h" +#include "bsl_sal.h" +#include "sal_file.h" +#include "sal_time.h" +#include "bsl_log_internal.h" +#include "bsl_binlog_id.h" +#include "bsl_log.h" +#include "bsl_obj_internal.h" +#include "hitls_x509_errno.h" +#include "hitls_x509_local.h" +#include "crypt_eal_encode.h" +#include "crypt_encode.h" +#include "crypt_errno.h" +#include "crypt_types.h" +#include "crypt_eal_pkey.h" +#include "crypt_eal_md.h" +#include "bsl_pem_internal.h" +#include "bsl_err_internal.h" +#include "hitls_csr_local.h" +#include "hitls_cert_local.h" +#include "crypt_encode.h" + +#define HITLS_CERT_CTX_SPECIFIC_TAG_VER 0 +#define HITLS_CERT_CTX_SPECIFIC_TAG_ISSUERID 1 +#define HITLS_CERT_CTX_SPECIFIC_TAG_SUBJECTID 2 +#define HITLS_CERT_CTX_SPECIFIC_TAG_EXTENSION 3 +#define MAX_DN_STR_LEN 256 +#define PRINT_TIME_MAX_SIZE 32 + +typedef enum { + HITLS_X509_ISSUER_DN_NAME, + HITLS_X509_SUBJECT_DN_NAME, +} DISTINCT_NAME_TYPE; + +typedef enum { + HITLS_X509_BEFORE_TIME, + HITLS_X509_AFTER_TIME, +} X509_TIME_TYPE; + +BSL_ASN1_TemplateItem g_certTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* x509 */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* tbs */ + /* 2: version */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CERT_CTX_SPECIFIC_TAG_VER, + BSL_ASN1_FLAG_DEFAULT, 2}, + {BSL_ASN1_TAG_INTEGER, 0, 3}, + /* 2: serial number */ + {BSL_ASN1_TAG_INTEGER, 0, 2}, + /* 2: signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 3}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 3}, // 8 + /* 2: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + /* 2: validity */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_CHOICE, 0, 3}, + {BSL_ASN1_TAG_CHOICE, 0, 3}, // 12 + /* 2: subject ref: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + /* 2: subject public key info ref signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 2}, + /* 2: issuer id, subject id */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_CERT_CTX_SPECIFIC_TAG_ISSUERID, BSL_ASN1_FLAG_OPTIONAL, 2}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_CERT_CTX_SPECIFIC_TAG_SUBJECTID, BSL_ASN1_FLAG_OPTIONAL, 2}, + /* 2: extension */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CERT_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, // 17 + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */ + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2}, // 20 + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ +}; + +typedef enum { + HITLS_X509_CERT_VERSION_IDX = 0, + HITLS_X509_CERT_SERIAL_IDX = 1, + HITLS_X509_CERT_TBS_SIGNALG_OID_IDX = 2, + HITLS_X509_CERT_TBS_SIGNALG_ANY_IDX = 3, + HITLS_X509_CERT_ISSUER_IDX = 4, + HITLS_X509_CERT_BEFORE_VALID_IDX = 5, + HITLS_X509_CERT_AFTER_VALID_IDX = 6, + HITLS_X509_CERT_SUBJECT_IDX = 7, + HITLS_X509_CERT_SUBKEYINFO_IDX = 8, + HITLS_X509_CERT_ISSUERID_IDX = 9, + HITLS_X509_CERT_SUBJECTID_IDX = 10, + HITLS_X509_CERT_EXT_IDX = 11, + HITLS_X509_CERT_SIGNALG_IDX = 12, + HITLS_X509_CERT_SIGNALG_ANY_IDX = 13, + HITLS_X509_CERT_SIGN_IDX = 14, + HITLS_X509_CERT_MAX_IDX = 15, +} HITLS_X509_CERT_IDX; + +#define X509_ASN1_START_TIME_IDX 10 +#define X509_ASN1_END_TIME_IDX 11 + +#define X509_ASN1_TBS_SIGNALG_ANY 7 +#define X509_ASN1_SIGNALG_ANY 19 + +int32_t HITLS_X509_CertTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + switch (type) { + case BSL_ASN1_TYPE_CHECK_CHOICE_TAG: { + if (idx == X509_ASN1_START_TIME_IDX || idx == X509_ASN1_END_TIME_IDX) { + uint8_t tag = *(uint8_t *) data; + if ((tag == BSL_ASN1_TAG_UTCTIME) || (tag == BSL_ASN1_TAG_GENERALIZEDTIME)) { + *(uint8_t *) expVal = tag; + return BSL_SUCCESS; + } + } + return HITLS_X509_ERR_CHECK_TAG; + } + case BSL_ASN1_TYPE_GET_ANY_TAG: { + if (idx == X509_ASN1_TBS_SIGNALG_ANY || idx == X509_ASN1_SIGNALG_ANY) { + BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *) data; + BslOidString oidStr = {param->len, (char *)param->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_UNKNOWN) { + return HITLS_X509_ERR_GET_ANY_TAG; + } + if (cid == BSL_CID_RSASSAPSS) { + // note: any can be encoded empty null + *(uint8_t *)expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + return BSL_SUCCESS; + } else { + *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + } + return HITLS_X509_ERR_GET_ANY_TAG; + } + default: + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +void HITLS_X509_CertFree(HITLS_X509_Cert *cert) +{ + if (cert == NULL) { + return; + } + + int ret = 0; + BSL_SAL_AtomicDownReferences(&(cert->references), &ret); + if (ret > 0) { + return; + } + + if (cert->flag == HITLS_X509_CERT_GEN_FLAG) { + BSL_LIST_FREE(cert->tbs.ext.list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); + BSL_SAL_FREE(cert->tbs.serialNum.buff); + BSL_SAL_FREE(cert->tbs.tbsRawData); + BSL_SAL_FREE(cert->signature.buff); + BSL_LIST_FREE(cert->tbs.issuerName, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + BSL_LIST_FREE(cert->tbs.subjectName, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + } else { + BSL_LIST_FREE(cert->tbs.ext.list, NULL); + BSL_LIST_FREE(cert->tbs.issuerName, NULL); + BSL_LIST_FREE(cert->tbs.subjectName, NULL); + } + BSL_SAL_FREE(cert->rawData); + CRYPT_EAL_PkeyFreeCtx(cert->tbs.ealPubKey); + CRYPT_EAL_PkeyFreeCtx(cert->ealPrivKey); + BSL_SAL_ReferencesFree(&(cert->references)); + BSL_SAL_Free(cert); + return; +} + +HITLS_X509_Cert *HITLS_X509_CertNew(void) +{ + HITLS_X509_Cert *cert = NULL; + BSL_ASN1_List *issuerName = NULL; + BSL_ASN1_List *subjectName = NULL; + BSL_ASN1_List *extList = NULL; + cert = (HITLS_X509_Cert *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Cert)); + if (cert == NULL) { + return NULL; + } + + issuerName = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + if (issuerName == NULL) { + goto ERR; + } + + subjectName = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + if (subjectName == NULL) { + goto ERR; + } + extList = BSL_LIST_New(sizeof(HITLS_X509_ExtEntry)); + if (extList == NULL) { + goto ERR; + } + BSL_SAL_ReferencesInit(&(cert->references)); + cert->tbs.issuerName = issuerName; + cert->tbs.subjectName = subjectName; + cert->tbs.ext.list = extList; + cert->tbs.ext.maxPathLen = -1; + cert->flag = HITLS_X509_CERT_GEN_FLAG; + return cert; +ERR: + BSL_SAL_Free(cert); + BSL_SAL_Free(issuerName); + BSL_SAL_Free(subjectName); + return NULL; +} + +int32_t HITLS_X509_ParseCertTbs(BSL_ASN1_Buffer *asnArr, HITLS_X509_Cert *cert) +{ + int32_t ret; + // version: default is 0 + if (asnArr[HITLS_X509_CERT_VERSION_IDX].tag != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CERT_VERSION_IDX], &cert->tbs.version); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + // serialNum + cert->tbs.serialNum = asnArr[HITLS_X509_CERT_SERIAL_IDX]; + + // sign alg + ret = HITLS_X509_ParseSignAlgInfo(&asnArr[HITLS_X509_CERT_TBS_SIGNALG_OID_IDX], + &asnArr[HITLS_X509_CERT_TBS_SIGNALG_ANY_IDX], &cert->tbs.signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // issuer name + ret = HITLS_X509_ParseNameList(&asnArr[HITLS_X509_CERT_ISSUER_IDX], cert->tbs.issuerName); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // validity + ret = HITLS_X509_ParseTime(&asnArr[HITLS_X509_CERT_BEFORE_VALID_IDX], &asnArr[HITLS_X509_CERT_AFTER_VALID_IDX], + &cert->tbs.validTime); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // subject name + ret = HITLS_X509_ParseNameList(&asnArr[HITLS_X509_CERT_SUBJECT_IDX], cert->tbs.subjectName); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // subject public key info + ret = CRYPT_EAL_ParseAsn1SubPubkey(asnArr[HITLS_X509_CERT_SUBKEYINFO_IDX].buff, + asnArr[HITLS_X509_CERT_SUBKEYINFO_IDX].len, &cert->tbs.ealPubKey, false); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // ext + ret = HITLS_X509_ParseExt(&asnArr[HITLS_X509_CERT_EXT_IDX], &cert->tbs.ext); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + return ret; +ERR: + if (cert->tbs.ealPubKey != NULL) { + CRYPT_EAL_PkeyFreeCtx(cert->tbs.ealPubKey); + cert->tbs.ealPubKey = NULL; + } + BSL_LIST_DeleteAll(cert->tbs.issuerName, NULL); + BSL_LIST_DeleteAll(cert->tbs.subjectName, NULL); + return ret; +} + +int32_t HITLS_X509_ParseAsn1Cert(bool isCopy, uint8_t **encode, uint32_t *encodeLen, HITLS_X509_Cert *cert) +{ + uint8_t *temp = *encode; + uint32_t tempLen = *encodeLen; + if (isCopy) { + cert->flag = HITLS_X509_CERT_PARSE_FLAG; + } + // template parse + BSL_ASN1_Buffer asnArr[HITLS_X509_CERT_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_certTempl, sizeof(g_certTempl) / sizeof(g_certTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, HITLS_X509_CertTagGetOrCheck, + &temp, &tempLen, asnArr, HITLS_X509_CERT_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // parse tbs raw data + ret = HITLS_X509_ParseTbsRawData(*encode, *encodeLen, &cert->tbs.tbsRawData, &cert->tbs.tbsRawDataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // parse tbs + ret = HITLS_X509_ParseCertTbs(asnArr, cert); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: failed to parse tbs.", 0, 0, 0, 0); + return ret; + } + // parse sign alg + ret = HITLS_X509_ParseSignAlgInfo(&asnArr[HITLS_X509_CERT_SIGNALG_IDX], + &asnArr[HITLS_X509_CERT_SIGNALG_ANY_IDX], &cert->signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // parse signature + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CERT_SIGN_IDX], &cert->signature); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + cert->rawData = *encode; + cert->rawDataLen = *encodeLen - tempLen; + *encode = temp; + *encodeLen = tempLen; + return HITLS_X509_SUCCESS; +ERR: + CRYPT_EAL_PkeyFreeCtx(cert->tbs.ealPubKey); + cert->tbs.ealPubKey = NULL; + BSL_LIST_DeleteAll(cert->tbs.issuerName, NULL); + BSL_LIST_DeleteAll(cert->tbs.subjectName, NULL); + BSL_LIST_DeleteAll(cert->tbs.ext.list, NULL); + return ret; +} + + +int32_t HITLS_X509_CertMulParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_List **certlist) +{ + int32_t ret; + if (encode == NULL || encode->data == NULL || encode->dataLen == 0 || certlist == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + X509_ParseFuncCbk certCbk = { + (HITLS_X509_Asn1Parse)HITLS_X509_ParseAsn1Cert, + (HITLS_X509_New)HITLS_X509_CertNew, + (HITLS_X509_Free)HITLS_X509_CertFree + }; + HITLS_X509_List *list = BSL_LIST_New(sizeof(HITLS_X509_Cert)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + + ret = HITLS_X509_ParseX509(format, encode, true, &certCbk, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: failed to parse the x509 cert.", 0, 0, 0, 0); + BSL_LIST_FREE(list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *certlist = list; + return ret; +} + +int32_t HITLS_X509_CertParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_Cert **cert) +{ + HITLS_X509_List *list = NULL; + if (cert == NULL || *cert != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + int32_t ret = HITLS_X509_CertMulParseBuff(format, encode, &list); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + HITLS_X509_Cert *tmp = BSL_LIST_GET_FIRST(list); + int ref; + ret = HITLS_X509_CertCtrl(tmp, HITLS_X509_REF_UP, &ref, sizeof(int)); + BSL_LIST_FREE(list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + *cert = tmp; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CertParseFile(int32_t format, const char *path, HITLS_X509_Cert **cert) +{ + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer encode = {data, dataLen}; + ret = HITLS_X509_CertParseBuff(format, &encode, cert); + BSL_SAL_Free(data); + return ret; +} + +int32_t HITLS_X509_CertMulParseFile(int32_t format, const char *path, HITLS_X509_List **certlist) +{ + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + return ret; + } + + BSL_Buffer encode = {data, dataLen}; + ret = HITLS_X509_CertMulParseBuff(format, &encode, certlist); + BSL_SAL_Free(data); + return ret; +} + +static int32_t X509_KeyUsageCheck(HITLS_X509_Cert *cert, bool *val, int32_t valLen, uint64_t exp) +{ + if (val == NULL || valLen != sizeof(bool)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *val = (cert->tbs.ext.keyUsage & exp); + return HITLS_X509_SUCCESS; +} + +/* RFC2253 https://www.rfc-editor.org/rfc/rfc2253 */ +static int32_t X509GetPrintSNStr(const BSL_ASN1_Buffer *nameType, char *buff, int32_t buffLen, int32_t *usedLen) +{ + if (nameType == NULL || nameType->buff == NULL || nameType->len == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + BslOidString oid = { + .octs = (char *)nameType->buff, + .octetLen = nameType->len, + }; + const char *oidName = BSL_OBJ_GetOidNameFromOid(&oid); + if (oidName == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_DN); + return HITLS_X509_ERR_CERT_INVALID_DN; + } + if (strcpy_s(buff, buffLen, oidName) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_DN); + return HITLS_X509_ERR_CERT_INVALID_DN; + } + + *usedLen = strlen(oidName); + return HITLS_X509_SUCCESS; +} + +static int32_t X509PrintNameNode(const HITLS_X509_NameNode *nameNode, char *buff, int32_t buffLen, int32_t *usedLen) +{ + if (nameNode->layer == 1) { + return HITLS_X509_SUCCESS; + } + int offset = 0; + *usedLen = 0; + /* Get the printable type */ + int32_t ret = X509GetPrintSNStr(&nameNode->nameType, buff, buffLen, &offset); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + /* print '=' between type and value */ + if (buffLen - offset < 2) { // 2 denote buffer is enough to place two character, i.e '=' and '\0' + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + buff[offset] = '='; + offset++; + /* print 'value' */ + if (nameNode->nameValue.buff == NULL || nameNode->nameValue.len == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (memcpy_s(buff + offset, buffLen - offset, nameNode->nameValue.buff, nameNode->nameValue.len) != EOK) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_DN); + return HITLS_X509_ERR_CERT_INVALID_DN; + } + offset += nameNode->nameValue.len; + *usedLen = offset; + return HITLS_X509_SUCCESS; +} + +static int32_t GetDistinguishNameStrFromList(BSL_ASN1_List *nameList, BSL_Buffer *buff) +{ + if (nameList == NULL || BSL_LIST_COUNT(nameList) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + uint32_t offset = 0; + int32_t ret; + char tmpBuffStr[MAX_DN_STR_LEN] = {}; + char *tmpBuff = tmpBuffStr; + uint32_t tmpBuffLen = MAX_DN_STR_LEN; + (void)BSL_LIST_GET_FIRST(nameList); + HITLS_X509_NameNode *firstNameNode = BSL_LIST_GET_NEXT(nameList); + HITLS_X509_NameNode *nameNode = firstNameNode; + while (nameNode != NULL) { + if (tmpBuffLen - offset < 2) { // 2 denote buffer is enough to place two character, i.e ',' and '\0' + ret = HITLS_X509_ERR_INVALID_PARAM; + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (nameNode != firstNameNode && nameNode->layer == 2) { + *tmpBuff = ','; + tmpBuff++; + offset++; + } + int32_t eachUsedLen = 0; + ret = X509PrintNameNode(nameNode, tmpBuff, tmpBuffLen - offset, &eachUsedLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + tmpBuff += eachUsedLen; + offset += eachUsedLen; + nameNode = BSL_LIST_GET_NEXT(nameList); + } + buff->data = BSL_SAL_Calloc(offset + 1, sizeof(char)); + if (buff->data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + (void)memcpy_s(buff->data, offset + 1, tmpBuffStr, offset); + buff->dataLen = offset; + return HITLS_X509_SUCCESS; +} + +static int32_t X509_GetDistinguishNameStr(HITLS_X509_Cert *cert, BSL_Buffer *val, int32_t opt) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + switch (opt) { + case HITLS_X509_ISSUER_DN_NAME: + return GetDistinguishNameStrFromList(cert->tbs.issuerName, val); + case HITLS_X509_SUBJECT_DN_NAME: + return GetDistinguishNameStrFromList(cert->tbs.subjectName, val); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +static int32_t GetAsn1SerialNumStr(const BSL_ASN1_Buffer *number, BSL_Buffer *val) +{ + if (number == NULL || number->buff == NULL || number->len == 0 || number->tag != BSL_ASN1_TAG_INTEGER || + val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + for (size_t i = 0; i < number->len - 1; i++) { + if (sprintf_s((char *)&val->data[3 * i], val->dataLen - 3 * i, "%02x:", number->buff[i]) == -1) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM); + return HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM; + } + } + size_t index = 3 * (number->len - 1); + if (sprintf_s((char *)&val->data[index], val->dataLen - index, "%02x", number->buff[number->len - 1]) == -1) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM); + return HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM; + } + val->dataLen = 3 * number->len - 1; + return HITLS_X509_SUCCESS; +} + +static int32_t X509_GetSerialNumStr(HITLS_X509_Cert *cert, BSL_Buffer *val) +{ + if (val == NULL || cert->tbs.serialNum.buff == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + BSL_ASN1_Buffer serialNum = cert->tbs.serialNum; + val->data = BSL_SAL_Calloc(serialNum.len * 3, sizeof(uint8_t)); + if (val->data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + val->dataLen = serialNum.len * 3; + int32_t ret = GetAsn1SerialNumStr(&serialNum, val); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(val->data); + val->dataLen = 0; + } + + return ret; +} + +// rfc822: https://www.w3.org/Protocols/rfc822/ +static const char g_monAsn1Str[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; +static int32_t GetAsn1BslTimeStr(const BSL_TIME *time, BSL_Buffer *val) +{ + if (time == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + val->data = BSL_SAL_Calloc(PRINT_TIME_MAX_SIZE, sizeof(uint8_t)); + if (val->data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + if (sprintf_s((char *)val->data, PRINT_TIME_MAX_SIZE, "%s %u %02u:%02u:%02u %u%s", + g_monAsn1Str[time->month - 1], time->day, time->hour, time->minute, time->second, time->year, " GMT") == -1) { + BSL_SAL_FREE(val->data); + val->dataLen = 0; + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_TIME); + return HITLS_X509_ERR_CERT_INVALID_TIME; + } + val->dataLen = strlen((char *)val->data); + return HITLS_X509_SUCCESS; +} + +static int32_t X509_GetAsn1BslTimeStr(HITLS_X509_Cert *cert, BSL_Buffer *val, int32_t opt) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + switch (opt) { + case HITLS_X509_BEFORE_TIME: + return GetAsn1BslTimeStr(&cert->tbs.validTime.start, val); + case HITLS_X509_AFTER_TIME: + return GetAsn1BslTimeStr(&cert->tbs.validTime.end, val); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +static int32_t X509_GetCertExt(HITLS_X509_Ext *ext, HITLS_X509_Ext **val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(HITLS_X509_Ext *)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *val = ext; + return HITLS_X509_SUCCESS; +} + +static int32_t X509_CertGetCtrl(HITLS_X509_Cert *cert, int32_t cmd, void *val, int32_t valLen) +{ + switch (cmd) { + case HITLS_X509_GET_ENCODELEN: + return HITLS_X509_GetEncodeLen(cert->rawDataLen, val, valLen); + case HITLS_X509_GET_ENCODE: + return HITLS_X509_GetEncodeData(cert->rawData, val); + case HITLS_X509_GET_PUBKEY: + return HITLS_X509_GetPubKey(cert->tbs.ealPubKey, val); + case HITLS_X509_GET_SIGNALG: + return HITLS_X509_GetSignAlg(cert->signAlgId.algId, val, valLen); + case HITLS_X509_GET_SUBJECT_DNNAME: + return HITLS_X509_GetList(cert->tbs.subjectName, val, valLen); + case HITLS_X509_GET_ISSUER_DNNAME: + return HITLS_X509_GetList(cert->tbs.issuerName, val, valLen); + case HITLS_X509_GET_SUBJECT_DNNAME_STR: + return X509_GetDistinguishNameStr(cert, val, HITLS_X509_SUBJECT_DN_NAME); + case HITLS_X509_GET_ISSUER_DNNAME_STR: + return X509_GetDistinguishNameStr(cert, val, HITLS_X509_ISSUER_DN_NAME); + case HITLS_X509_GET_SERIALNUM: + return X509_GetSerialNumStr(cert, val); + case HITLS_X509_GET_BEFORE_TIME: + return X509_GetAsn1BslTimeStr(cert, val, HITLS_X509_BEFORE_TIME); + case HITLS_X509_GET_AFTER_TIME: + return X509_GetAsn1BslTimeStr(cert, val, HITLS_X509_AFTER_TIME); + case HITLS_X509_GET_EXT: + return X509_GetCertExt(&cert->tbs.ext, val, valLen); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +typedef bool (*SetParamCheck)(const void *val, int32_t valLen); + +static bool VersionCheck(const void *val, int32_t valLen) +{ + return valLen == sizeof(int32_t) && *(int32_t *)val >= HITLS_CERT_VERSION_1 && + *(int32_t *)val <= HITLS_CERT_VERSION_3; +} + +static int32_t CertSetSerial(BSL_ASN1_Buffer *serial, const void *val, int32_t valLen) +{ + if (valLen <= 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM); + return HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM; + } + const uint8_t *src = (const uint8_t *)val; + serial->buff = BSL_SAL_Dump(src, valLen); + if (serial->buff == NULL) { + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + serial->len = valLen; + serial->tag = BSL_ASN1_TAG_INTEGER; + return HITLS_X509_SUCCESS; +} + +static bool TimeCheck(const void *val, int32_t valLen) +{ + (void)val; + return valLen == sizeof(BSL_TIME) && BSL_DateTimeCheck((const BSL_TIME *)val); +} + +static int32_t CertSet(void *dest, int32_t size, void *val, int32_t valLen, SetParamCheck check) +{ + if (check(val, valLen) != true) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + (void)memcpy_s(dest, size, val, size); + return HITLS_X509_SUCCESS; +} + +static int32_t HITLS_X509_SetCsrExt(HITLS_X509_Ext *ext, HITLS_X509_Csr *csr) +{ + HITLS_X509_Attr attr = {0}; + int32_t ret = HITLS_X509_AttrCtrl( + csr->reqInfo.attributes, HITLS_X509_ATTR_GET_REQUESTED_EXTENSIONS, &attr, sizeof(HITLS_X509_Attr)); + if (ret == HITLS_X509_ERR_ATTR_NOT_FOUND) { + return ret; + } + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + HITLS_X509_Ext *csrExt = (HITLS_X509_Ext *)attr.value; + ret = HITLS_X509_ExtReplace(ext, csrExt); + HITLS_X509_ExtFree(csrExt); + return ret; +} + +int32_t X509_CertSetCtrl(HITLS_X509_Cert *cert, int32_t cmd, void *val, int32_t valLen) +{ + if (cert == NULL || val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + int32_t ret; + switch (cmd) { + case HITLS_X509_SET_VERSION: + return CertSet(&cert->tbs.version, sizeof(int32_t), val, valLen, VersionCheck); + case HITLS_X509_SET_SERIALNUM: + return CertSetSerial(&cert->tbs.serialNum, val, valLen); + case HITLS_X509_SET_BEFORE_TIME: + ret = CertSet(&cert->tbs.validTime.start, sizeof(BSL_TIME), val, valLen, TimeCheck); + if (ret == HITLS_X509_SUCCESS) { + cert->tbs.validTime.flag |= BSL_TIME_BEFORE_SET; + cert->tbs.validTime.flag |= + cert->tbs.validTime.start.year <= BSL_TIME_UTC_MAX_YEAR ? BSL_TIME_BEFORE_IS_UTC : 0; + } + return ret; + case HITLS_X509_SET_AFTER_TIME: + ret = CertSet(&cert->tbs.validTime.end, sizeof(BSL_TIME), val, valLen, TimeCheck); + if (ret == HITLS_X509_SUCCESS) { + cert->tbs.validTime.flag |= BSL_TIME_AFTER_SET; + cert->tbs.validTime.flag |= + cert->tbs.validTime.end.year <= BSL_TIME_UTC_MAX_YEAR ? BSL_TIME_AFTER_IS_UTC : 0; + } + return ret; + case HITLS_X509_SET_PRIVKEY: + return HITLS_X509_SetPkey(&cert->ealPrivKey, val); + case HITLS_X509_SET_SIGN_MD_ID: + return HITLS_X509_SetSignMdId(&cert->signMdId, val, valLen); + case HITLS_X509_SET_SIGN_RSA_PSS_PARAM: + return HITLS_X509_SetRsaPssPara(cert->ealPrivKey, val, valLen); + case HITLS_X509_SET_SIGN_RSA_PADDING: + return HITLS_X509_SetRsaPadding(cert->ealPrivKey, val, valLen); + case HITLS_X509_SET_PUBKEY: + return HITLS_X509_SetPkey(&cert->tbs.ealPubKey, val); + case HITLS_X509_SET_ISSUER_DNNAME: + return HITLS_X509_SetNameList(&cert->tbs.issuerName, val, valLen); + case HITLS_X509_SET_SUBJECT_DNNAME: + return HITLS_X509_SetNameList(&cert->tbs.subjectName, val, valLen); + case HITLS_X509_SET_CSR_EXT: + return HITLS_X509_SetCsrExt(&cert->tbs.ext, val); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +static int32_t X509_CertExtCtrl(HITLS_X509_Cert *cert, int32_t cmd, void *val, int32_t valLen) +{ + switch (cmd) { + case HITLS_X509_EXT_KU_DIGITALSIGN: + return X509_KeyUsageCheck(cert, val, valLen, HITLS_X509_EXT_KU_DIGITAL_SIGN); + case HITLS_X509_EXT_KU_CERTSIGN: + return X509_KeyUsageCheck(cert, val, valLen, HITLS_X509_EXT_KU_KEY_CERT_SIGN); + case HITLS_X509_EXT_KU_KEYAGREEMENT: + return X509_KeyUsageCheck(cert, val, valLen, HITLS_X509_EXT_KU_KEY_AGREEMENT); + case HITLS_X509_EXT_KU_KEYENC: + return X509_KeyUsageCheck(cert, val, valLen, HITLS_X509_EXT_KU_KEY_ENCIPHERMENT); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +int32_t HITLS_X509_CertCtrl(HITLS_X509_Cert *cert, int32_t cmd, void *val, int32_t valLen) +{ + if (cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (cmd == HITLS_X509_REF_UP) { + return HITLS_X509_RefUp(&cert->references, val, valLen); + } else if (cmd >= HITLS_X509_GET_ENCODELEN && cmd < HITLS_X509_SET_VERSION) { + return X509_CertGetCtrl(cert, cmd, val, valLen); + } else if (cmd < HITLS_X509_EXT_KU_KEYENC) { + if (cert->flag == HITLS_X509_CERT_PARSE_FLAG) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_AFTER_PARSE); + return HITLS_X509_ERR_SET_AFTER_PARSE; + } + return X509_CertSetCtrl(cert, cmd, val, valLen); + } else { + return X509_CertExtCtrl(cert, cmd, val, valLen); + } +} + +int32_t HITLS_X509_CertDup(HITLS_X509_Cert *src, HITLS_X509_Cert **dest) +{ + if (src == NULL || dest == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + HITLS_X509_Cert *tempCert = NULL; + BSL_Buffer encode = {src->rawData, src->rawDataLen}; + int32_t ret = HITLS_X509_CertParseBuff(BSL_FORMAT_ASN1, &encode, &tempCert); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + *dest = tempCert; + return ret; +} + +/** + * Confirm whether the certificate is the issuer of the current certificate + * 1. Check if the issueName matches the subjectname + * 2. Is the issuer certificate a CA + * 3. Check if the algorithm of the issuer certificate matches that of the sub certificate + * 4. Check if the certificate keyusage has a certificate sign + */ +int32_t HITLS_X509_CheckIssued(HITLS_X509_Cert *issue, HITLS_X509_Cert *subject, bool *res) +{ + int32_t ret = HITLS_X509_CmpNameNode(issue->tbs.subjectName, subject->tbs.issuerName); + if (ret != 0) { + *res = false; + return HITLS_X509_SUCCESS; + } + /** + * If the basic constraints extension is not present in a version 3 certificate, + * or the extension is present but the cA boolean is not asserted, + * then the certified public key MUST NOT be used to verify certificate signatures. + */ + if (issue->tbs.version == HITLS_CERT_VERSION_3 && !(issue->tbs.ext.extFlags & HITLS_X509_EXT_FLAG_BCONS) && + !issue->tbs.ext.isCa) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_NOT_CA); + return HITLS_X509_ERR_CERT_NOT_CA; + } + + ret = HITLS_X509_CheckAlg(issue->tbs.ealPubKey, &subject->tbs.signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /** + * Conforming CAs MUST include this extension + * in certificates that contain public keys that are used to validate digital signatures on + * other public key certificates or CRLs. + */ + if (issue->tbs.ext.extFlags & HITLS_X509_EXT_FLAG_KUSAGE) { + if (((issue->tbs.ext.keyUsage & HITLS_X509_EXT_KU_KEY_CERT_SIGN)) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_KU_NO_CERTSIGN); + return HITLS_X509_ERR_VFY_KU_NO_CERTSIGN; + } + } + *res = true; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CertIsCA(HITLS_X509_Cert *cert, bool *res) +{ + *res = true; + if (cert->tbs.version == HITLS_CERT_VERSION_3) { + if (!(cert->tbs.ext.extFlags & HITLS_X509_EXT_FLAG_BCONS)) { + *res = false; + } else { + *res = cert->tbs.ext.isCa; + } + } + return HITLS_X509_SUCCESS; +} + +static int32_t EncodeTbsItems(HITLS_X509_CertTbs *tbs, BSL_ASN1_Buffer *issuer, BSL_ASN1_Buffer *subject, + BSL_ASN1_Buffer *pubkey, BSL_ASN1_Buffer *ext) +{ + int32_t ret = HITLS_X509_EncodeNameList(tbs->issuerName, issuer); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_EncodeNameList(tbs->subjectName, subject); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_Free(issuer->buff); + return ret; + } + BSL_Buffer pub = {0}; + ret = CRYPT_EAL_EncodePubKeyBuffInternal(tbs->ealPubKey, BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY, false, &pub); + if (ret != CRYPT_SUCCESS) { + BSL_SAL_Free(issuer->buff); + BSL_SAL_Free(subject->buff); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (tbs->version == HITLS_CERT_VERSION_3) { + ret = HITLS_X509_EncodeExt(BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | + HITLS_CERT_CTX_SPECIFIC_TAG_EXTENSION, tbs->ext.list, ext); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(issuer->buff); + BSL_SAL_Free(subject->buff); + BSL_SAL_Free(pub.data); + BSL_ERR_PUSH_ERROR(ret); + } + } + pubkey->buff = pub.data; + pubkey->len = pub.dataLen; + return ret; +} + +BSL_ASN1_TemplateItem g_tbsTempl[] = { + /* version */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CERT_CTX_SPECIFIC_TAG_VER, + BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_DEFAULT, 1}, + /* serial number */ + {BSL_ASN1_TAG_INTEGER, 0, 0}, + /* signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + /* issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, + /* validity */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_CHOICE, 0, 1}, + {BSL_ASN1_TAG_CHOICE, 0, 1}, + /* subject ref: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, + /* subject public key info ref signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 0}, + /* Note!!: issuer id, subject id are not supported */ + /* extension */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CERT_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, +}; +#define HITLS_X509_CERT_TBS_SIZE 9 + +static int32_t EncodeTbsCertificate(HITLS_X509_CertTbs *tbs, BSL_ASN1_Buffer *signAlg, BSL_ASN1_Buffer *tbsBuff) +{ + BSL_ASN1_Buffer issuer = {0}; + BSL_ASN1_Buffer subject = {0}; + BSL_ASN1_Buffer pubkey = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}; + BSL_ASN1_Buffer ext = {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | + HITLS_CERT_CTX_SPECIFIC_TAG_EXTENSION, 0, NULL}; + + int32_t ret = EncodeTbsItems(tbs, &issuer, &subject, &pubkey, &ext); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + uint8_t ver = (uint8_t)tbs->version; + BSL_ASN1_Template templ = {g_tbsTempl, sizeof(g_tbsTempl) / sizeof(g_tbsTempl[0])}; + BSL_ASN1_Buffer asns[HITLS_X509_CERT_TBS_SIZE] = { + {BSL_ASN1_TAG_INTEGER, ver == HITLS_CERT_VERSION_1 ? 0 : 1, ver == HITLS_CERT_VERSION_1 ? NULL : &ver}, // 0 + tbs->serialNum, // 1 serial number + *signAlg, // 2 sigAlg + issuer, // 3 issuer + {tbs->validTime.flag & BSL_TIME_BEFORE_IS_UTC ? BSL_ASN1_TAG_UTCTIME : BSL_ASN1_TAG_GENERALIZEDTIME, + sizeof(BSL_TIME), (uint8_t *)&tbs->validTime.start}, // 4 start + {tbs->validTime.flag & BSL_TIME_AFTER_IS_UTC ? BSL_ASN1_TAG_UTCTIME : BSL_ASN1_TAG_GENERALIZEDTIME, + sizeof(BSL_TIME), (uint8_t *)&tbs->validTime.end}, // 5 end + subject, // 6 subject + pubkey, // 7 pubkey info + ext, // 8 extensions, only for v3 + }; + ret = BSL_ASN1_EncodeTemplate(&templ, asns, HITLS_X509_CERT_TBS_SIZE, &tbsBuff->buff, &tbsBuff->len); + BSL_SAL_Free(issuer.buff); + BSL_SAL_Free(subject.buff); + BSL_SAL_Free(pubkey.buff); + if (ver == HITLS_CERT_VERSION_3 && ext.buff != NULL) { + BSL_SAL_Free(ext.buff); + } + return ret; +} + +BSL_ASN1_TemplateItem g_briefCertTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* x509 */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* tbs */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */ + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ +}; + +#define HITLS_X509_CERT_BRIEF_SIZE 3 + +static int32_t EncodeAsn1Cert(HITLS_X509_Cert *cert, BSL_Buffer *buff) +{ + BSL_ASN1_Buffer tbsAsn1 = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}; + BSL_ASN1_Buffer signAlg = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}; + BSL_Buffer tbsBuff = {0}; + + int32_t ret = HITLS_X509_SetSignAlgInfo(cert->ealPrivKey, cert->signMdId, &cert->signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_EncodeSignAlgInfo(&cert->signAlgId, &signAlg); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + cert->tbs.signAlgId = cert->signAlgId; + ret = EncodeTbsCertificate(&cert->tbs, &signAlg, &tbsAsn1); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: failed to encode tbs.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + + ret = HITLS_X509_SignAsn1Data(cert->ealPrivKey, cert->signMdId, &tbsAsn1, &tbsBuff, &cert->signature); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: failed to sign the cert.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + + BSL_ASN1_Buffer asns[HITLS_X509_CERT_BRIEF_SIZE] = { + tbsAsn1, + signAlg, + {BSL_ASN1_TAG_BITSTRING, sizeof(BSL_ASN1_BitString), (uint8_t *)&cert->signature}, + }; + BSL_ASN1_Template templ = {g_briefCertTempl, sizeof(g_briefCertTempl) / sizeof(g_briefCertTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asns, HITLS_X509_CERT_BRIEF_SIZE, &buff->data, &buff->dataLen); +EXIT: + BSL_SAL_Free(signAlg.buff); + BSL_SAL_Free(tbsAsn1.buff); + if (ret == HITLS_X509_SUCCESS) { + cert->tbs.tbsRawData = tbsBuff.data; + cert->tbs.tbsRawDataLen = tbsBuff.dataLen; + } else { + BSL_SAL_FREE(tbsBuff.data); + } + return ret; +} + +static int32_t CheckCertValid(HITLS_X509_Cert *cert) +{ + if (cert == NULL) { + return HITLS_X509_ERR_INVALID_PARAM; + } + if (BSL_LIST_COUNT(cert->tbs.ext.list) != 0 && cert->tbs.version != HITLS_CERT_VERSION_3) { + return HITLS_X509_ERR_CERT_INACCRACY_VERSION; + } + if (cert->tbs.serialNum.buff == NULL || cert->tbs.serialNum.len == 0) { + return HITLS_X509_ERR_CERT_INVALID_SERIAL_NUM; + } + if (BSL_LIST_COUNT(cert->tbs.issuerName) == 0 || BSL_LIST_COUNT(cert->tbs.subjectName) == 0) { + return HITLS_X509_ERR_CERT_INVALID_DN; + } + if ((cert->tbs.validTime.flag & BSL_TIME_BEFORE_SET) == 0 || (cert->tbs.validTime.flag & BSL_TIME_AFTER_SET) == 0) { + return HITLS_X509_ERR_CERT_INVALID_TIME; + } + int32_t ret = BSL_SAL_DateTimeCompare(&cert->tbs.validTime.start, &cert->tbs.validTime.end, NULL); + if (ret != BSL_TIME_DATE_BEFORE && ret != BSL_TIME_CMP_EQUAL) { + return HITLS_X509_ERR_CERT_START_TIME_LATER; + } + if (cert->signMdId == 0) { + return HITLS_X509_ERR_CERT_INVALID_SIGN_MD; + } + if (cert->ealPrivKey == NULL) { + return HITLS_X509_ERR_CERT_INVALID_PRVKEY; + } + if (cert->tbs.ealPubKey == NULL) { + return HITLS_X509_ERR_CERT_INVALID_PUBKEY; + } + + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_EncodeAsn1Cert(HITLS_X509_Cert *cert, BSL_Buffer *buff) +{ + /* Encoded after decoding. */ + if (cert->rawData != NULL && cert->rawDataLen != 0) { + buff->data = BSL_SAL_Dump(cert->rawData, cert->rawDataLen); + if (buff->data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + buff->dataLen = cert->rawDataLen; + return HITLS_X509_SUCCESS; + } + + /* Generate a new certificate. */ + int32_t ret = CheckCertValid(cert); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: encode cert failed due to invalid parameters.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = EncodeAsn1Cert(cert, buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: failed to encode the cert.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + cert->rawData = BSL_SAL_Dump(buff->data, buff->dataLen); + if (buff->data == NULL) { + BSL_SAL_FREE(buff->data); + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + cert->rawDataLen = buff->dataLen; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_EncodePemCert(HITLS_X509_Cert *cert, BSL_Buffer *buff) +{ + BSL_Buffer asn1 = {0}; + int32_t ret = HITLS_X509_EncodeAsn1Cert(cert, &asn1); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "cert: failed to encode the cert.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer base64 = {0}; + BSL_PEM_Symbol symbol = {BSL_PEM_CERT_BEGIN_STR, BSL_PEM_CERT_END_STR}; + ret = BSL_PEM_EncodeAsn1ToPem(asn1.data, asn1.dataLen, &symbol, (char **)&base64.data, &base64.dataLen); + BSL_SAL_Free(asn1.data); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + buff->data = base64.data; + buff->dataLen = base64.dataLen; + return ret; +} + +int32_t HITLS_X509_CertGenBuff(int32_t format, HITLS_X509_Cert *cert, BSL_Buffer *buff) +{ + if (cert == NULL || buff == NULL || buff->data != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + switch (format) { + case BSL_FORMAT_ASN1: + return HITLS_X509_EncodeAsn1Cert(cert, buff); + case BSL_FORMAT_PEM: + return HITLS_X509_EncodePemCert(cert, buff); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +int32_t HITLS_X509_CertGenFile(int32_t format, HITLS_X509_Cert *cert, const char *path) +{ + if (path == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + BSL_Buffer encode = {0}; + int32_t ret = HITLS_X509_CertGenBuff(format, cert, &encode); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_SAL_WriteFile(path, encode.data, encode.dataLen); + BSL_SAL_Free(encode.data); + return ret; +} + +int32_t HITLS_X509_CertDigest(HITLS_X509_Cert *cert, CRYPT_MD_AlgId mdId, uint8_t *data, uint32_t *dataLen) +{ + if (cert == NULL || data == NULL || dataLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (cert->rawData != NULL && cert->rawDataLen != 0) { + return CRYPT_EAL_Md(mdId, cert->rawData, cert->rawDataLen, data, dataLen); + } + BSL_Buffer asn1 = {0}; + int32_t ret = HITLS_X509_EncodeAsn1Cert(cert, &asn1); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN( + BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "cert: failed to encode the cert.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + cert->rawData = asn1.data; + cert->rawDataLen = asn1.dataLen; + return CRYPT_EAL_Md(mdId, cert->rawData, cert->rawDataLen, data, dataLen); +} diff --git a/x509/x509_common/include/hitls_x509_local.h b/x509/x509_common/include/hitls_x509_local.h new file mode 100644 index 00000000..adaa1a03 --- /dev/null +++ b/x509/x509_common/include/hitls_x509_local.h @@ -0,0 +1,224 @@ +/* + * 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_X509_LOCAL_H +#define HITLS_X509_LOCAL_H + +#include +#include "bsl_asn1.h" +#include "bsl_obj.h" +#include "hitls_x509.h" +#include "crypt_types.h" +#include "crypt_eal_pkey.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check whether conditions are met. If yes, an error code is returned. + */ +#define HITLS_X509_RETURN_RET_IF(ret) \ + do { \ + if ((ret) != 0) { \ + BSL_ERR_PUSH_ERROR((ret)); \ + return (ret); \ + } \ + } while (0) + +#define HITLS_X509_GOTO_RET_IF(ret) \ + do { \ + if ((ret) != 0) { \ + BSL_ERR_PUSH_ERROR((ret)); \ + goto ERR; \ + } \ + } while (0) + +/** + * RFC 5280: section 4.1.2.5.1 + */ +#define BSL_TIME_UTC_MAX_YEAR 2049 + +#define BSL_TIME_BEFORE_SET 0x01 +#define BSL_TIME_AFTER_SET 0x02 +#define BSL_TIME_BEFORE_IS_UTC 0x04 +#define BSL_TIME_AFTER_IS_UTC 0x08 + +#define HITLS_X509_EXT_FLAG_PARSE (1 << 0) +#define HITLS_X509_EXT_FLAG_SET (1 << 1) +#define HITLS_X509_EXT_FLAG_KUSAGE (1 << 2) +#define HITLS_X509_EXT_FLAG_BCONS (1 << 3) + +#define HITLS_X509_GN_OTHER (HITLS_X509_GN_IP + 1) +#define HITLS_X509_GN_X400 (HITLS_X509_GN_OTHER + 1) +#define HITLS_X509_GN_EDI (HITLS_X509_GN_X400 + 1) +#define HITLS_X509_GN_RID (HITLS_X509_GN_EDI + 1) + +typedef struct _HITLS_X509_NameNode { + BSL_ASN1_Buffer nameType; + BSL_ASN1_Buffer nameValue; + uint8_t layer; +} HITLS_X509_NameNode; + +typedef struct _HITLS_X509_ExtEntry { + BslCid cid; + BSL_ASN1_Buffer extnId; + bool critical; + BSL_ASN1_Buffer extnValue; +} HITLS_X509_ExtEntry; + +typedef struct _HITLS_X509_Ext { + BslList *list; + uint32_t extFlags; + // basic usage ext + bool isCa; + // -1 no check, 0 no intermediate certificate + int32_t maxPathLen; + // key usage ext + uint32_t keyUsage; +} HITLS_X509_Ext; + +typedef struct _HITLS_X509_AttrEntry { + BslCid cid; + BSL_ASN1_Buffer attrId; + BSL_ASN1_Buffer attrValue; +} HITLS_X509_AttrEntry; + +typedef struct _HITLS_X509_ValidTime { + uint8_t flag; + BSL_TIME start; + BSL_TIME end; +} HITLS_X509_ValidTime; + +typedef struct _HITLS_X509_Asn1AlgId { + BslCid algId; + union { + CRYPT_RSA_PssPara rsaPssParam; + }; +} HITLS_X509_Asn1AlgId; + +typedef int32_t (*HITLS_X509_Asn1Parse)(bool isCopy, uint8_t **encode, uint32_t *encodeLen, void *out); +typedef void *(*HITLS_X509_New)(void); +typedef void (*HITLS_X509_Free)(void *elem); + +typedef struct { + HITLS_X509_Asn1Parse asn1Parse; + HITLS_X509_New x509New; + HITLS_X509_Free x509Free; +} X509_ParseFuncCbk; + +int32_t HITLS_X509_ParseTbsRawData(uint8_t *encode, uint32_t encodeLen, uint8_t **tbsRawData, uint32_t *tbsRawDataLen); + +// The public key parsing is more complex, and the crypto module completes it +int32_t HITLS_X509_ParseSignAlgInfo(BSL_ASN1_Buffer *algId, BSL_ASN1_Buffer *param, HITLS_X509_Asn1AlgId *x509Alg); + +int32_t HITLS_X509_EncodeSignAlgInfo(HITLS_X509_Asn1AlgId *x509Alg, BSL_ASN1_Buffer *asn); + +void HITLS_X509_FreeNameNode(HITLS_X509_NameNode *node); + +int32_t HITLS_X509_SetNameList(BslList **dest, void *val, int32_t valLen); + +int32_t HITLS_X509_ParseNameList(BSL_ASN1_Buffer *name, BSL_ASN1_List *list); + +int32_t HITLS_X509_EncodeNameList(BSL_ASN1_List *list, BSL_ASN1_Buffer *name); + +int32_t HITLS_X509_ParseGeneralNames(uint8_t *encode, uint32_t encLen, BslList *list); + +void HITLS_X509_FreeGeneralName(HITLS_X509_GeneralName *data); + +void HITLS_X509_FreeGeneralNames(BslList *names); + +void HITLS_X509_ClearGeneralNames(BslList *names); + +int32_t HITLS_X509_ParseAuthorityKeyId(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtAki *aki); + +void HITLS_X509_ClearAuthorityKeyId(HITLS_X509_ExtAki *aki); + +int32_t HITLS_X509_ParseSubjectKeyId(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtSki *ski); + +int32_t HITLS_X509_ParseExtendedKeyUsage(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtExKeyUsage *exku); + +void HITLS_X509_ClearExtendedKeyUsage(HITLS_X509_ExtExKeyUsage *exku); + +int32_t HITLS_X509_ParseSubjectAltName(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtSan *san); + +void HITLS_X509_ClearSubjectAltName(HITLS_X509_ExtSan *san); + +HITLS_X509_Ext *HITLS_X509_ExtNew(void); + +void HITLS_X509_ExtFree(HITLS_X509_Ext *ext); + +int32_t HITLS_X509_ParseExt(BSL_ASN1_Buffer *ext, HITLS_X509_Ext *certExt); + +int32_t HITLS_X509_EncodeExt(uint8_t tag, BSL_ASN1_List *list, BSL_ASN1_Buffer *ext); + +int32_t HITLS_X509_ParseExtItem(BSL_ASN1_Buffer *extItem, HITLS_X509_ExtEntry *extEntry); + +int32_t HITLS_X509_ParseExtItem(BSL_ASN1_Buffer *extItem, HITLS_X509_ExtEntry *extEntry); + +void HITLS_X509_ExtEntryFree(HITLS_X509_ExtEntry *entry); + +int32_t HITLS_X509_AddListItemDefault(void *item, uint32_t len, BSL_ASN1_List *list); + +int32_t HITLS_X509_ParseTime(BSL_ASN1_Buffer *before, BSL_ASN1_Buffer *after, HITLS_X509_ValidTime *time); + +int32_t HITLS_X509_ParseX509(int32_t format, BSL_Buffer *encode, bool isCert, X509_ParseFuncCbk *parsefun, + HITLS_X509_List *list); +int32_t HITLS_X509_CmpNameNode(BSL_ASN1_List *nameOri, BSL_ASN1_List *name); + +int32_t HITLS_X509_CheckAlg(CRYPT_EAL_PkeyCtx *pubkey, HITLS_X509_Asn1AlgId *subAlg); + +int32_t HITLS_X509_ParseAttrList(BSL_ASN1_Buffer *attrs, BSL_ASN1_List *list); + +void HITLS_X509_AttrEntryFree(HITLS_X509_AttrEntry *attr); + +int32_t HITLS_X509_SignAsn1Data(CRYPT_EAL_PkeyCtx *priv, CRYPT_MD_AlgId mdId, + BSL_ASN1_Buffer *asn1Buff, BSL_Buffer *rawSignBuff, BSL_ASN1_BitString *sign); + +int32_t HITLS_X509_EncodeAttrList(uint8_t tag, BSL_ASN1_List *list, BSL_ASN1_Buffer *attr); + +int32_t HITLS_X509_CheckSignature(const CRYPT_EAL_PkeyCtx *pubKey, uint8_t *rawData, uint32_t rawDataLen, + HITLS_X509_Asn1AlgId *alg, BSL_ASN1_BitString *signature); + +int32_t HITLS_X509_RefUp(BSL_SAL_RefCount *references, int32_t *val, int32_t valLen); + +int32_t HITLS_X509_GetList(BslList *list, void *val, int32_t valLen); + +int32_t HITLS_X509_GetPubKey(void *ealPubKey, void **val); + +int32_t HITLS_X509_GetSignAlg(BslCid signAlgId, int32_t *val, int32_t valLen); + +int32_t HITLS_X509_GetEncodeLen(uint32_t encodeLen, uint32_t *val, int32_t valLen); + +int32_t HITLS_X509_GetEncodeData(uint8_t *rawData, uint8_t **val); + +int32_t HITLS_X509_SetPkey(void **pkey, void *val); + +int32_t HITLS_X509_SetSignAlgInfo(CRYPT_EAL_PkeyCtx *privKey, CRYPT_MD_AlgId mdId, HITLS_X509_Asn1AlgId *x509Alg); + +int32_t HITLS_X509_SetRsaPadding(CRYPT_EAL_PkeyCtx *privKey, void *val, int32_t valLen); + +int32_t HITLS_X509_SetRsaPssPara(CRYPT_EAL_PkeyCtx *privKey, void *val, int32_t valLen); + +int32_t HITLS_X509_SetSignMdId(CRYPT_MD_AlgId *mdAlgId, void *val, int32_t valLen); + +int32_t HITLS_X509_ExtReplace(HITLS_X509_Ext *dest, HITLS_X509_Ext *src); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_X509_LOCAL_H \ No newline at end of file diff --git a/x509/x509_common/src/hitls_x509_attrs.c b/x509/x509_common/src/hitls_x509_attrs.c new file mode 100644 index 00000000..66ae4427 --- /dev/null +++ b/x509/x509_common/src/hitls_x509_attrs.c @@ -0,0 +1,323 @@ +/* + * 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 +#include "securec.h" +#include "hitls_x509.h" +#include "hitls_x509_local.h" +#include "bsl_obj.h" +#include "bsl_sal.h" +#include "bsl_obj_internal.h" +#include "bsl_err_internal.h" +#include "crypt_errno.h" +#include "crypt_eal_pkey.h" +#include "hitls_x509_errno.h" + +/** + * RFC 2985: section-5.4.2 + * extensionRequest ATTRIBUTE ::= { + * WITH SYNTAX ExtensionRequest + * SINGLE VALUE TRUE + * ID pkcs-9-at-extensionRequest + * } + * ExtensionRequest ::= Extensions + */ +static BSL_ASN1_TemplateItem g_x509AttrTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, BSL_ASN1_FLAG_HEADERONLY, 0}, +}; + +typedef enum { + HITLS_X509_ATTR_OID_IDX, + HITLS_X509_ATTR_SET_IDX, + HITLS_X509_ATTR_INDEX_MAX +} HITLS_X509_ATTR_IDX; + +#define HITLS_X509_ATTR_MAX_NUM 20 + +int32_t HITLS_X509_EncodeObjIdentity(BslCid cid, BSL_ASN1_Buffer *asnBuff) +{ + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(cid); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID); + return CRYPT_ERR_ALGID; + } + asnBuff->tag = BSL_ASN1_TAG_OBJECT_ID; + asnBuff->buff = (uint8_t *)oidStr->octs; + asnBuff->len = oidStr->octetLen; + + return HITLS_X509_SUCCESS; +} + +void HITLS_X509_AttrEntryFree(HITLS_X509_AttrEntry *attr) +{ + if (attr == NULL) { + return; + } + BSL_SAL_Free(attr->attrValue.buff); + BSL_SAL_Free(attr); +} + +int32_t HITLS_X509_ParseAttr(BSL_ASN1_Buffer *attrItem, HITLS_X509_AttrEntry *attrEntry) +{ + uint8_t *temp = attrItem->buff; + uint32_t tempLen = attrItem->len; + BSL_ASN1_Buffer asnArr[HITLS_X509_ATTR_INDEX_MAX] = {0}; + BSL_ASN1_Template templ = {g_x509AttrTempl, sizeof(g_x509AttrTempl) / sizeof(g_x509AttrTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_ATTR_INDEX_MAX); + if (tempLen != 0) { + ret = HITLS_X509_ERR_PARSE_ATTR_BUF; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* parse attribute id */ + BslOidString oid = {asnArr[HITLS_X509_ATTR_OID_IDX].len, (char *)asnArr[HITLS_X509_ATTR_OID_IDX].buff, 0}; + attrEntry->cid = BSL_OBJ_GetCIDFromOid(&oid); + if (attrEntry->cid == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_OBJ_ID); + return HITLS_X509_ERR_PARSE_OBJ_ID; + } + /* set id and value asn1 buffer */ + attrEntry->attrId = asnArr[HITLS_X509_ATTR_OID_IDX]; + attrEntry->attrValue = asnArr[HITLS_X509_ATTR_SET_IDX]; + return ret; +} + +int32_t HITLS_X509_ParseAttrsListAsnItem(uint32_t layer, BSL_ASN1_Buffer *asn, void *cbParam, BSL_ASN1_List *list) +{ + (void)layer; + (void)cbParam; + HITLS_X509_AttrEntry *node = BSL_SAL_Calloc(1, sizeof(HITLS_X509_AttrEntry)); + if (node == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + + /* parse attribute entry */ + int32_t ret = HITLS_X509_ParseAttr(asn, node); + if (ret != BSL_SUCCESS) { + goto ERR; + } + + ret = BSL_LIST_AddElement(list, node, BSL_LIST_POS_AFTER); + if (ret != BSL_SUCCESS) { + goto ERR; + } + + return ret; +ERR: + HITLS_X509_AttrEntryFree(node); + BSL_ERR_PUSH_ERROR(ret); + return ret; +} + +int32_t HITLS_X509_ParseAttrList(BSL_ASN1_Buffer *attrs, BSL_ASN1_List *list) +{ + if (attrs->tag == 0 || attrs->buff == NULL || attrs->len == 0) { + return HITLS_X509_SUCCESS; + } + + uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE}; + BSL_ASN1_DecodeListParam listParam = {1, expTag}; + int32_t ret = BSL_ASN1_DecodeListItem(&listParam, attrs, &HITLS_X509_ParseAttrsListAsnItem, NULL, list); + if (ret != BSL_SUCCESS) { + BSL_LIST_DeleteAll(list, NULL); + return ret; + } + return ret; +} + +static int32_t CmpAttrEntryByCid(const void *attrEntry, const void *cid) +{ + const HITLS_X509_AttrEntry *node = attrEntry; + const BslCid *oid = cid; + + return node->cid == *(BslCid *)oid ? 0 : 1; +} + +typedef int32_t (*EncodeAttrCb)(void *attrItem, BSL_ASN1_Buffer *attrValue); + +typedef int32_t (*DecodeAttrCb)(HITLS_X509_AttrEntry *attrEntry, void *attrItem); + +static int32_t EncodeReqExtAttr(void *attrItem, BSL_ASN1_Buffer *attrValue) +{ + if (attrItem == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + HITLS_X509_Ext *ext = (HITLS_X509_Ext *)attrItem; + return HITLS_X509_EncodeExt(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, ext->list, attrValue); +} + +static int32_t SetAttr(BSL_ASN1_List *attributes, void *val, uint32_t valLen, EncodeAttrCb encodeAttrCb) +{ + HITLS_X509_Attr *attr = (HITLS_X509_Attr *)val; + if (valLen != sizeof(HITLS_X509_Attr)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + /* Check if the attribute already exists. */ + if (BSL_LIST_Search(attributes, &attr->cid, CmpAttrEntryByCid, NULL) != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_ATTR_REPEAT); + return HITLS_X509_ERR_SET_ATTR_REPEAT; + } + + HITLS_X509_AttrEntry *attrEntry = BSL_SAL_Calloc(1, sizeof(HITLS_X509_AttrEntry)); + if (attrEntry == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = HITLS_X509_EncodeObjIdentity(attr->cid, &attrEntry->attrId); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + + ret = encodeAttrCb(attr->value, &attrEntry->attrValue); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + attrEntry->cid = attr->cid; + ret = BSL_LIST_AddElement(attributes, attrEntry, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + goto ERR; + } + + return ret; + +ERR: + BSL_ERR_PUSH_ERROR(ret); + HITLS_X509_AttrEntryFree(attrEntry); + return ret; +} + +static int32_t DecodeReqExtAttr(HITLS_X509_AttrEntry *attrEntry, void *attrItem) +{ + HITLS_X509_Ext *ext = HITLS_X509_ExtNew(); + if (ext == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = HITLS_X509_ParseExt(&attrEntry->attrValue, ext); + if (ret != BSL_SUCCESS) { + HITLS_X509_ExtFree(ext); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *(HITLS_X509_Ext **)attrItem = ext; + return HITLS_X509_SUCCESS; +} + +static int32_t GetAttr(BSL_ASN1_List *attributes, void *val, int32_t valLen, DecodeAttrCb decodeAttrCb) +{ + HITLS_X509_Attr *attr = val; + if (attr->value != NULL || valLen != sizeof(HITLS_X509_Attr)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + HITLS_X509_AttrEntry *attrEntry = BSL_LIST_Search(attributes, &attr->cid, CmpAttrEntryByCid, NULL); + if (attrEntry == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ATTR_NOT_FOUND); + return HITLS_X509_ERR_ATTR_NOT_FOUND; + } + return decodeAttrCb(attrEntry, &attr->value); +} + +int32_t HITLS_X509_AttrCtrl(BslList *attributes, int32_t cmd, void *val, int32_t valLen) +{ + if (attributes == NULL || val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + switch (cmd) { + case HITLS_X509_ATTR_SET_REQUESTED_EXTENSIONS: + return SetAttr(attributes, val, valLen, EncodeReqExtAttr); + case HITLS_X509_ATTR_GET_REQUESTED_EXTENSIONS: + ((HITLS_X509_Attr *)val)->cid = BSL_CID_REQ_EXTENSION; + return GetAttr(attributes, val, valLen, DecodeReqExtAttr); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +#define X509_CSR_ATTR_ELEM_NUMBER 2 +static BSL_ASN1_TemplateItem g_x509AttrEntryTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, 0, 0}, +}; + +int32_t HITLS_X509_EncodeAttrEntry(HITLS_X509_AttrEntry *node, BSL_ASN1_Buffer *attrBuff) +{ + BSL_ASN1_Buffer asnBuf[X509_CSR_ATTR_ELEM_NUMBER] = {}; + asnBuf[0] = node->attrId; + asnBuf[1] = node->attrValue; + BSL_ASN1_Template templ = {g_x509AttrEntryTempl, sizeof(g_x509AttrEntryTempl) / sizeof(g_x509AttrEntryTempl[0])}; + int32_t ret = BSL_ASN1_EncodeTemplate(&templ, asnBuf, X509_CSR_ATTR_ELEM_NUMBER, &attrBuff->buff, &attrBuff->len); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + attrBuff->tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + return ret; +} + +void FreeAsnAttrsBuff(BSL_ASN1_Buffer *asnBuf, int32_t count) +{ + for (int32_t i = 0; i < count; i++) { + BSL_SAL_FREE(asnBuf[i].buff); + } + BSL_SAL_FREE(asnBuf); +} + +int32_t HITLS_X509_EncodeAttrList(uint8_t tag, BSL_ASN1_List *list, BSL_ASN1_Buffer *attr) +{ + int32_t count = BSL_LIST_COUNT(list); + /* no attribute */ + if (count <= 0) { + attr->tag = tag; + attr->buff = NULL; + attr->len = 0; + return HITLS_X509_SUCCESS; + } + BSL_ASN1_Buffer *asnBuf = BSL_SAL_Calloc(count, sizeof(BSL_ASN1_Buffer)); + if (asnBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int iter = 0; + int32_t ret; + HITLS_X509_AttrEntry *node = NULL; + for (node = BSL_LIST_GET_FIRST(list); node != NULL; node = BSL_LIST_GET_NEXT(list), iter++) { + ret = HITLS_X509_EncodeAttrEntry(node, &asnBuf[iter]); + if (ret != HITLS_X509_SUCCESS) { + FreeAsnAttrsBuff(asnBuf, count); + return ret; + } + } + static BSL_ASN1_TemplateItem attrSeqTempl = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0 }; + BSL_ASN1_Template templ = {&attrSeqTempl, 1}; + ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, count, &templ, asnBuf, iter, attr); + FreeAsnAttrsBuff(asnBuf, count); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + attr->tag = tag; + return ret; +} diff --git a/x509/x509_common/src/hitls_x509_common.c b/x509/x509_common/src/hitls_x509_common.c new file mode 100644 index 00000000..a4a679ff --- /dev/null +++ b/x509/x509_common/src/hitls_x509_common.c @@ -0,0 +1,625 @@ +/* + * 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_x509_local.h" +#include "securec.h" +#include "bsl_obj.h" +#include "bsl_sal.h" +#include "bsl_log_internal.h" +#include "bsl_binlog_id.h" +#include "bsl_log.h" +#include "hitls_x509_errno.h" +#include "crypt_errno.h" +#include "crypt_eal_pkey.h" +#include "bsl_obj_internal.h" +#include "bsl_err_internal.h" +#include "bsl_pem_internal.h" +#include "crypt_encode.h" + +int32_t HITLS_X509_ParseTbsRawData(uint8_t *encode, uint32_t encodeLen, uint8_t **tbsRawData, uint32_t *tbsRawDataLen) +{ + uint8_t *temp = encode; + uint32_t tempLen = encodeLen; + uint32_t valen; + // x509 + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, &temp, &tempLen, &valen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + uint32_t len = tempLen; + *tbsRawData = temp; + // tbs + ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, &temp, &tempLen, &valen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + *tbsRawDataLen = len - tempLen + valen; + return ret; +} + +int32_t HITLS_X509_ParseSignAlgInfo(BSL_ASN1_Buffer *algId, BSL_ASN1_Buffer *param, HITLS_X509_Asn1AlgId *x509Alg) +{ + int32_t ret; + BslOidString oidStr = {algId->len, (char *)algId->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ALG_OID); + return HITLS_X509_ERR_ALG_OID; + } + if (cid == BSL_CID_RSASSAPSS) { + ret = CRYPT_EAL_ParseRsaPssAlgParam(param, &x509Alg->rsaPssParam); + if (ret != BSL_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "cert: failed to parse rsa pss param.", 0, 0, 0, 0); + return ret; + } + } + x509Alg->algId = cid; + return HITLS_X509_SUCCESS; +} + +static int32_t HITLS_X509_ParseNameNode(BSL_ASN1_Buffer *asn, HITLS_X509_NameNode *node) +{ + uint8_t *temp = asn->buff; + uint32_t tempLen = asn->len; + // parse oid + if (*temp != BSL_ASN1_TAG_OBJECT_ID) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_NAME_OID); + return HITLS_X509_ERR_NAME_OID; + } + + int32_t ret = BSL_ASN1_DecodeItem(&temp, &tempLen, &node->nameType); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // parse string + if (*temp != BSL_ASN1_TAG_UTF8STRING && *temp != BSL_ASN1_TAG_PRINTABLESTRING && + *temp != BSL_ASN1_TAG_IA5STRING) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_STR); + return HITLS_X509_ERR_PARSE_STR; + } + + ret = BSL_ASN1_DecodeItem(&temp, &tempLen, &node->nameValue); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +int32_t HITLS_X509_ParseListAsnItem(uint32_t layer, BSL_ASN1_Buffer *asn, void *cbParam, BSL_ASN1_List *list) +{ + (void) cbParam; + int32_t ret = HITLS_X509_SUCCESS; + HITLS_X509_NameNode *node = BSL_SAL_Calloc(1, sizeof(HITLS_X509_NameNode)); + if (node == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + + if (layer == 1) { + node->layer = 1; + } else { // layer == 2 + node->layer = 2; + ret = HITLS_X509_ParseNameNode(asn, node); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + } + + ret = BSL_LIST_AddElement(list, node, BSL_LIST_POS_AFTER); + if (ret != BSL_SUCCESS) { + goto ERR; + } + return ret; +ERR: + BSL_SAL_Free(node); + return ret; +} + +int32_t HITLS_X509_ParseNameList(BSL_ASN1_Buffer *name, BSL_ASN1_List *list) +{ + uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE}; + BSL_ASN1_DecodeListParam listParam = {2, expTag}; + int32_t ret = BSL_ASN1_DecodeListItem(&listParam, name, &HITLS_X509_ParseListAsnItem, NULL, list); + if (ret != BSL_SUCCESS) { + BSL_LIST_DeleteAll(list, NULL); + } + return ret; +} + +int32_t HITLS_X509_AddListItemDefault(void *item, uint32_t len, BSL_ASN1_List *list) +{ + void *node = BSL_SAL_Malloc(len); + if (node == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + (void)memcpy_s(node, len, item, len); + int32_t ret = BSL_LIST_AddElement(list, node, BSL_LIST_POS_AFTER); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_Free(node); + } + return ret; +} + +int32_t HITLS_X509_ParseTime(BSL_ASN1_Buffer *before, BSL_ASN1_Buffer *after, HITLS_X509_ValidTime *time) +{ + int32_t ret = BSL_ASN1_DecodePrimitiveItem(before, &time->start); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + time->flag |= BSL_TIME_BEFORE_SET; + if (before->tag == BSL_ASN1_TAG_UTCTIME) { + time->flag |= BSL_TIME_BEFORE_IS_UTC; + } + // crl after time is optional + if (after->tag != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(after, &time->end); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + time->flag |= BSL_TIME_AFTER_SET; + if (after->tag == BSL_ASN1_TAG_UTCTIME) { + time->flag |= BSL_TIME_AFTER_IS_UTC; + } + } + return ret; +} + +static bool X509_CheckIsRsa(uint32_t algId) +{ + switch (algId) { + case BSL_CID_RSA: + case BSL_CID_MD5WITHRSA: + case BSL_CID_SHA1WITHRSA: + case BSL_CID_SHA224WITHRSAENCRYPTION: + case BSL_CID_SHA256WITHRSAENCRYPTION: + case BSL_CID_SHA384WITHRSAENCRYPTION: + case BSL_CID_SHA512WITHRSAENCRYPTION: + case BSL_CID_SM3WITHRSAENCRYPTION: + return true; + default: + return false; + } +} + +int32_t HITLS_X509_EncodeSignAlgInfo(HITLS_X509_Asn1AlgId *x509Alg, BSL_ASN1_Buffer *asn) +{ + int32_t ret; + BslOidString *oidStr = BSL_OBJ_GetOidFromCID(x509Alg->algId); + if (oidStr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ALG_OID); + return HITLS_X509_ERR_ALG_OID; + } + BSL_ASN1_Buffer asnArr[2] = {0}; + asnArr[0].buff = (uint8_t *)oidStr->octs; + asnArr[0].len = oidStr->octetLen; + asnArr[0].tag = BSL_ASN1_TAG_OBJECT_ID; + if (x509Alg->algId == BSL_CID_RSASSAPSS) { + ret = CRYPT_EAL_EncodeRsaPssAlgParam(&(x509Alg->rsaPssParam), &asnArr[1].buff, &asnArr[1].len); + if (ret != BSL_SUCCESS) { + return ret; + } + asnArr[1].tag = BSL_ASN1_TAG_SEQUENCE | BSL_ASN1_TAG_CONSTRUCTED; + } else if (X509_CheckIsRsa(x509Alg->algId)) { + asnArr[1].buff = NULL; + asnArr[1].len = 0; + asnArr[1].tag = BSL_ASN1_TAG_NULL; + } else { + /** + * RFC5758 sec 3.2 + * When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or + * ecdsa-with-SHA512 algorithm identifier appears in the algorithm field + * as an AlgorithmIdentifier, the encoding MUST omit the parameters + * field. + */ + asnArr[1].buff = NULL; + asnArr[1].len = 0; + asnArr[1].tag = BSL_ASN1_TAG_ANY; + } + BSL_ASN1_TemplateItem algTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 0}, + }; + BSL_ASN1_Template templ = {algTempl, sizeof(algTempl) / sizeof(algTempl[0])}; + // 2: alg + param + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, 2, &(asn->buff), &(asn->len)); + BSL_SAL_Free(asnArr[1].buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asn->tag = BSL_ASN1_TAG_SEQUENCE | BSL_ASN1_TAG_CONSTRUCTED; + return HITLS_X509_SUCCESS; +} + +static int32_t X509_EncodeRdName(BSL_ASN1_List *list, BSL_ASN1_Buffer *asnBuf) +{ + uint32_t maxCount = (BSL_LIST_COUNT(list) - 1) * 2; // 2: layer 1 and layer 2 + BSL_ASN1_Buffer *tmpBuf = BSL_SAL_Calloc(maxCount, sizeof(BSL_ASN1_Buffer)); + if (tmpBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + uint32_t iter = 0; + HITLS_X509_NameNode *node = BSL_LIST_GET_NEXT(list); + while (node != NULL && node->layer != 1) { + tmpBuf[iter++] = node->nameType; + tmpBuf[iter++] = node->nameValue; + node = BSL_LIST_GET_NEXT(list); + } + + BSL_ASN1_TemplateItem x509RdName[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + {BSL_ASN1_TAG_ANY, 0, 1} + }; + BSL_ASN1_Template templ = {x509RdName, sizeof(x509RdName) / sizeof(x509RdName[0])}; + int32_t ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SET, iter / 2, &templ, tmpBuf, iter, asnBuf); + BSL_SAL_Free(tmpBuf); + return ret; +} + +int32_t HITLS_X509_EncodeNameList(BSL_ASN1_List *list, BSL_ASN1_Buffer *name) +{ + int32_t ret; + int32_t maxCount = (BSL_LIST_COUNT(list) + 1) / 2; // (count + 1) / 2 : round up, the maximum number of set + BSL_ASN1_Buffer *asnBuf = BSL_SAL_Calloc(maxCount, sizeof(BSL_ASN1_Buffer)); + if (asnBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + HITLS_X509_NameNode *node = BSL_LIST_GET_FIRST(list); + uint32_t iter = 0; + while (node != NULL) { + ret = X509_EncodeRdName(list, &asnBuf[iter]); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + iter++; + node = BSL_LIST_Curr(list); + } + + BSL_ASN1_TemplateItem x509Name[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, 0, 0} + }; + BSL_ASN1_Template templ = {x509Name, 1}; + ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, iter, &templ, asnBuf, iter, name); +ERR: + for (uint32_t index = 0; index < iter; index++) { + BSL_SAL_Free(asnBuf[index].buff); + } + BSL_SAL_Free(asnBuf); + return ret; +} + +static void X509_GetPemSymbol(bool isCert, BSL_PEM_Symbol *symbol) +{ + if (isCert) { + symbol->head = BSL_PEM_CERT_BEGIN_STR; + symbol->tail = BSL_PEM_CERT_END_STR; + } else { + symbol->head = BSL_PEM_CRL_BEGIN_STR; + symbol->tail = BSL_PEM_CRL_END_STR; + } +} + +static int32_t X509_ParseAndAddRes(BSL_Buffer *asn1Buf, bool isCopy, X509_ParseFuncCbk *parsefun, HITLS_X509_List *list) +{ + void *res = parsefun->x509New(); + if (res == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = parsefun->asn1Parse(isCopy, &(asn1Buf->data), &(asn1Buf->dataLen), res); + if (ret != HITLS_X509_SUCCESS) { + parsefun->x509Free(res); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_LIST_AddElement(list, res, BSL_LIST_POS_AFTER); + if (ret != BSL_SUCCESS) { + parsefun->x509Free(res); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_ParseAsn1(BSL_Buffer *encode, bool isCopy, X509_ParseFuncCbk *parsefun, HITLS_X509_List *list) +{ + uint8_t *data = encode->data; + uint32_t dataLen = encode->dataLen; + while (dataLen > 0) { + uint32_t elemLen = dataLen; + int32_t ret = BSL_ASN1_GetCompleteLen(data, &elemLen); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + BSL_Buffer asn1Buf = {data, elemLen}; + if (isCopy) { + asn1Buf.data = BSL_SAL_Dump(data, elemLen); + if (asn1Buf.data == NULL) { + return BSL_DUMP_FAIL; + } + } + ret = X509_ParseAndAddRes(&asn1Buf, isCopy, parsefun, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(asn1Buf.data); + return ret; + } + data += elemLen; + dataLen -= elemLen; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_ParsePem(BSL_Buffer *encode, bool isCert, X509_ParseFuncCbk *parsefun, HITLS_X509_List *list) +{ + char *nextEncode = (char *)(encode->data); + uint32_t nextEncodeLen = encode->dataLen; + BSL_PEM_Symbol symbol = {NULL}; + X509_GetPemSymbol(isCert, &symbol); + while (nextEncodeLen > 0) { + BSL_Buffer asn1Buf = {NULL}; + int32_t ret = BSL_PEM_ParsePem2Asn1(&nextEncode, &nextEncodeLen, &symbol, &(asn1Buf.data), + &(asn1Buf.dataLen)); + if (ret != HITLS_X509_SUCCESS) { + break; + } + ret = X509_ParseAndAddRes(&asn1Buf, true, parsefun, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(asn1Buf.data); + return ret; + } + } + if (BSL_LIST_COUNT(list) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_NO_ELEMENT); + return HITLS_X509_ERR_PARSE_NO_ELEMENT; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_ParseUnkonw(BSL_Buffer *encode, bool isCopy, bool isCert, X509_ParseFuncCbk *parsefun, + HITLS_X509_List *list) +{ + bool isPem = BSL_PEM_IsPemFormat((char *)(encode->data), encode->dataLen); + if (isPem) { + return HITLS_X509_ParsePem(encode, isCert, parsefun, list); + } else { + return HITLS_X509_ParseAsn1(encode, isCopy, parsefun, list); + } +} + +int32_t HITLS_X509_ParseX509(int32_t format, BSL_Buffer *encode, bool isCert, X509_ParseFuncCbk *parsefun, + HITLS_X509_List *list) +{ + int32_t ret; + switch (format) { + case BSL_FORMAT_ASN1: + ret = HITLS_X509_ParseAsn1(encode, true, parsefun, list); + break; + case BSL_FORMAT_PEM: + ret = HITLS_X509_ParsePem(encode, isCert, parsefun, list); + break; + case BSL_FORMAT_UNKNOWN: + ret = HITLS_X509_ParseUnkonw(encode, true, isCert, parsefun, list); + break; + default: + ret = HITLS_X509_ERR_NOT_SUPPORT_FORMAT; + break; + } + return ret; +} + +static int32_t X509_NodeNameCompare(BSL_ASN1_Buffer *src, BSL_ASN1_Buffer *dest) +{ + if (src->tag != dest->tag) { + return 1; + } + if (src->len != dest->len) { + return 1; + } + return memcmp(src->buff, dest->buff, dest->len); +} + +static int32_t X509_NodeNameCaseCompare(BSL_ASN1_Buffer *src, BSL_ASN1_Buffer *dest) +{ + if ((src->tag == BSL_ASN1_TAG_UTF8STRING || src->tag == BSL_ASN1_TAG_PRINTABLESTRING) && + (dest->tag == BSL_ASN1_TAG_UTF8STRING || dest->tag == BSL_ASN1_TAG_PRINTABLESTRING)) { + if (src->len != dest->len) { + return 1; + } + for (uint32_t i = 0; i < src->len; i++) { + if (src->buff[i] == dest->buff[i]) { + continue; + } + if ('a' <= src->buff[i] && src->buff[i] <= 'z' && src->buff[i] - dest->buff[i] == 32) { + continue; + } + if ('a' <= dest->buff[i] && dest->buff[i] <= 'z' && dest->buff[i] - src->buff[i] == 32) { + continue; + } + return 1; + } + return 0; + } + return 1; +} + +static int32_t X509_NodeNameValueCompare(BSL_ASN1_Buffer *src, BSL_ASN1_Buffer *dest) +{ + // quick comparison + if (X509_NodeNameCompare(src, dest) == 0) { + return 0; + } + return X509_NodeNameCaseCompare(src, dest); +} + + +static int32_t X509_NodeCompare(BSL_ASN1_Buffer *buffOri, BSL_ASN1_Buffer *buff) +{ + if (buffOri->tag != buff->tag) { + return 1; + } + if (buffOri->len != buff->len) { + return 1; + } + return memcmp(buffOri->buff, buff->buff, buff->len); +} + +int32_t HITLS_X509_CmpNameNode(BSL_ASN1_List *nameOri, BSL_ASN1_List *name) +{ + HITLS_X509_NameNode *nodeOri = BSL_LIST_GET_FIRST(nameOri); + HITLS_X509_NameNode *node = BSL_LIST_GET_FIRST(name); + while(nodeOri != NULL || node != NULL) { + if (nodeOri == NULL || node == NULL) { + return 1; + } + if (X509_NodeCompare(&nodeOri->nameType, &node->nameType) != 0) { + return 1; + } + if (nodeOri->layer != node->layer) { + return 1; + } + if (X509_NodeNameValueCompare(&nodeOri->nameValue, &node->nameValue) != 0) { + return 1; + } + nodeOri = (HITLS_X509_NameNode *)BSL_LIST_GET_NEXT(nameOri); + node = (HITLS_X509_NameNode *)BSL_LIST_GET_NEXT(name); + } + return 0; +} + +int32_t HITLS_X509_CheckAlg(CRYPT_EAL_PkeyCtx *pubkey, HITLS_X509_Asn1AlgId *subAlg) +{ + uint32_t pubKeyId = CRYPT_EAL_PkeyGetId(pubkey); + if (pubKeyId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_GET_SIGNID); + return HITLS_X509_ERR_VFY_GET_SIGNID; + } + BslCid subSignAlg = BSL_OBJ_GetAsymIdFromSignId(subAlg->algId); + if (subSignAlg == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_GET_SIGNID); + return HITLS_X509_ERR_VFY_GET_SIGNID; + } + if (pubKeyId != subSignAlg) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_SIGNALG_NOT_MATCH); + return HITLS_X509_ERR_VFY_SIGNALG_NOT_MATCH; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_SignAsn1Data(CRYPT_EAL_PkeyCtx *priv, CRYPT_MD_AlgId mdId, + BSL_ASN1_Buffer *asn1Buff, BSL_Buffer *rawSignBuff, BSL_ASN1_BitString *sign) +{ + BSL_ASN1_TemplateItem templItem = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}; + BSL_ASN1_Template templ = {&templItem, 1}; + + int32_t ret = BSL_ASN1_EncodeTemplate(&templ, asn1Buff, 1, &rawSignBuff->data, &rawSignBuff->dataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + sign->len = CRYPT_EAL_PkeyGetSignLen(priv); + sign->buff = (uint8_t *)BSL_SAL_Malloc(sign->len); + if (sign->buff == NULL) { + BSL_SAL_FREE(rawSignBuff->data); + rawSignBuff->dataLen = 0; + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + ret = CRYPT_EAL_PkeySign(priv, mdId, rawSignBuff->data, rawSignBuff->dataLen, sign->buff, &sign->len); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_FREE(sign->buff); + BSL_SAL_FREE(rawSignBuff->data); + rawSignBuff->dataLen = 0; + } + + return ret; +} + + +static uint32_t X509_GetHashId(HITLS_X509_Asn1AlgId *alg) +{ + uint32_t hashId = BSL_OBJ_GetHashIdFromSignId(alg->algId); + if (hashId != BSL_CID_UNKNOWN) { + return hashId; + } + if (alg->algId == BSL_CID_RSASSAPSS) { + return alg->rsaPssParam.mdId; + } + return BSL_CID_UNKNOWN; +} + +static int32_t X509_CtrlAlgInfo(const CRYPT_EAL_PkeyCtx *pubKey, uint32_t hashId, HITLS_X509_Asn1AlgId *alg) +{ + switch (alg->algId) { + case BSL_CID_SHA224WITHRSAENCRYPTION: + case BSL_CID_SHA256WITHRSAENCRYPTION: + case BSL_CID_SHA384WITHRSAENCRYPTION: + case BSL_CID_SHA512WITHRSAENCRYPTION: + case BSL_CID_SM3WITHRSAENCRYPTION: + { + CRYPT_RSA_PkcsV15Para pkcs15Para = {hashId}; + return CRYPT_EAL_PkeyCtrl((CRYPT_EAL_PkeyCtx *)(uintptr_t)pubKey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, + &pkcs15Para, sizeof(CRYPT_RSA_PkcsV15Para)); + } + case BSL_CID_RSASSAPSS: + return CRYPT_EAL_PkeyCtrl((CRYPT_EAL_PkeyCtx *)(uintptr_t)pubKey, CRYPT_CTRL_SET_RSA_EMSA_PSS, + &alg->rsaPssParam, sizeof(CRYPT_RSA_PssPara)); + default: + return HITLS_X509_SUCCESS; + } +} + +int32_t HITLS_X509_CheckSignature(const CRYPT_EAL_PkeyCtx *pubKey, uint8_t *rawData, uint32_t rawDataLen, + HITLS_X509_Asn1AlgId *alg, BSL_ASN1_BitString *signature) +{ + uint32_t hashId = X509_GetHashId(alg); + if (hashId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_GET_HASHID); + return HITLS_X509_ERR_VFY_GET_HASHID; + } + CRYPT_EAL_PkeyCtx *verifyPubKey = CRYPT_EAL_PkeyDupCtx(pubKey); + if (verifyPubKey == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_DUP_PUBKEY); + return HITLS_X509_ERR_VFY_DUP_PUBKEY; + } + int32_t ret = X509_CtrlAlgInfo(verifyPubKey, hashId, alg); + if (ret != HITLS_X509_SUCCESS) { + CRYPT_EAL_PkeyFreeCtx(verifyPubKey); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_PkeyVerify(verifyPubKey, hashId, rawData, rawDataLen, signature->buff, signature->len); + CRYPT_EAL_PkeyFreeCtx(verifyPubKey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} diff --git a/x509/x509_common/src/hitls_x509_ctrl.c b/x509/x509_common/src/hitls_x509_ctrl.c new file mode 100644 index 00000000..def32a4b --- /dev/null +++ b/x509/x509_common/src/hitls_x509_ctrl.c @@ -0,0 +1,584 @@ +/* + * 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_x509_local.h" +#include +#include "securec.h" +#include "bsl_obj.h" +#include "bsl_sal.h" +#include "sal_atomic.h" +#include "hitls_x509_errno.h" +#include "crypt_errno.h" +#include "crypt_eal_pkey.h" +#include "bsl_obj_internal.h" +#include "bsl_err_internal.h" +#include "crypt_encode.h" + +#define HITLS_X509_DNNAME_MAX_NUM 100 + +int32_t HITLS_X509_RefUp(BSL_SAL_RefCount *references, int32_t *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + return BSL_SAL_AtomicUpReferences(references, val); +} + +int32_t HITLS_X509_GetList(BslList *list, void *val, int32_t valLen) +{ + if (list == NULL || val == NULL || valLen != sizeof(BslList *)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *(BslList **)val = list; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_GetPubKey(void *ealPubKey, void **val) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + int32_t ret = CRYPT_EAL_PkeyUpRef((CRYPT_EAL_PkeyCtx *)ealPubKey); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *val = ealPubKey; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_GetSignAlg(BslCid signAlgId, int32_t *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(BslCid)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *val = signAlgId; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_GetEncodeLen(uint32_t encodeLen, uint32_t *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *(uint32_t *)val = encodeLen; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_GetEncodeData(uint8_t *rawData, uint8_t **val) +{ + if (val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *val = rawData; + return HITLS_X509_SUCCESS; +} + +static bool IsValidHashAlg(CRYPT_MD_AlgId id) +{ + return id == CRYPT_MD_MD5 || id == CRYPT_MD_SHA1 || id == CRYPT_MD_SHA224 || id == CRYPT_MD_SHA256 || + id == CRYPT_MD_SHA384 || id == CRYPT_MD_SHA512 || id == CRYPT_MD_SM3; +} + +int32_t HITLS_X509_SetSignMdId(CRYPT_MD_AlgId *mdAlgId, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + CRYPT_MD_AlgId id = *(CRYPT_MD_AlgId *)val; + if (!IsValidHashAlg(id)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *mdAlgId = id; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_SetPkey(void **pkey, void *val) +{ + CRYPT_EAL_PkeyCtx *src = (CRYPT_EAL_PkeyCtx *)val; + CRYPT_EAL_PkeyCtx **dest = (CRYPT_EAL_PkeyCtx **)pkey; + + if (*dest != NULL) { + CRYPT_EAL_PkeyFreeCtx(*dest); + *dest = NULL; + } + + *dest = CRYPT_EAL_PkeyDupCtx(src); + if (*dest == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_KEY); + return HITLS_X509_ERR_SET_KEY; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_SetRsaPadding(CRYPT_EAL_PkeyCtx *privKey, void *val, int32_t valLen) +{ + CRYPT_RsaPadType *inPad = (CRYPT_RsaPadType *)val; + if (privKey == NULL || val == NULL || valLen != sizeof(int32_t) || + (*inPad != CRYPT_PKEY_EMSA_PKCSV15 && *inPad != CRYPT_PKEY_EMSA_PSS)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + CRYPT_PKEY_AlgId pkeyId = CRYPT_EAL_PkeyGetId(privKey); + if (pkeyId != CRYPT_PKEY_RSA) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_RSA_PAD); + return HITLS_X509_ERR_SET_RSA_PAD; + } + + CRYPT_RsaPadType pad; + int32_t ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_PADDING, &pad, sizeof(CRYPT_RsaPadType)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (pad == 0) { + return CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_SET_RSA_PADDING, inPad, sizeof(CRYPT_RsaPadType)); + } + if (pad != *inPad) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_RSA_PAD_DIFF); + return HITLS_X509_ERR_SET_RSA_PAD_DIFF; + } + + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_SetRsaPssPara(CRYPT_EAL_PkeyCtx *privKey, void *val, int32_t valLen) +{ + if (privKey == NULL || val == NULL || valLen != sizeof(CRYPT_RSA_PssPara)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + CRYPT_RSA_PssPara *inPara = (CRYPT_RSA_PssPara *)val; + CRYPT_RSA_PssPara para = {0}; + CRYPT_RsaPadType pad; + // pkey id must be rsa + CRYPT_PKEY_AlgId pkeyId = CRYPT_EAL_PkeyGetId(privKey); + if (pkeyId != CRYPT_PKEY_RSA) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_RSAPSS_PARA); + return HITLS_X509_ERR_SET_RSAPSS_PARA; + } + + // padding mode must be rsapss + int32_t ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_PADDING, &pad, sizeof(CRYPT_RsaPadType)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (pad != CRYPT_PKEY_EMSA_PSS) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_RSAPSS_PARA); + return HITLS_X509_ERR_SET_RSAPSS_PARA; + } + + // If mdId exists, it must be the same as input. + ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_MD, ¶.mdId, sizeof(BslCid)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (para.mdId != (CRYPT_MD_AlgId)BSL_CID_UNKNOWN && para.mdId != inPara->mdId) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_MD_NOT_MATCH); + return HITLS_X509_ERR_MD_NOT_MATCH; + } + // If mgfId exists, it must be the same as input. + ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_MGF, ¶.mgfId, sizeof(BslCid)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + if (para.mgfId != (CRYPT_MD_AlgId)BSL_CID_UNKNOWN && para.mgfId != inPara->mgfId) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_MGF_NOT_MATCH); + return HITLS_X509_ERR_MGF_NOT_MATCH; + } + + return CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_SET_RSA_EMSA_PSS, inPara, sizeof(CRYPT_RSA_PssPara)); +} + +static int32_t ProcRsaSignInfo(CRYPT_EAL_PkeyCtx *privKey, CRYPT_MD_AlgId mdId, HITLS_X509_Asn1AlgId *x509Alg) +{ + CRYPT_RsaPadType pad; + int32_t ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_PADDING, &pad, sizeof(CRYPT_RsaPadType)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + CRYPT_MD_AlgId pssMd; + switch ((int32_t)pad) { + case CRYPT_PKEY_EMSA_PSS: + ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_MD, &pssMd, sizeof(BslCid)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (pssMd != mdId) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_MD_NOT_MATCH); + return HITLS_X509_ERR_MD_NOT_MATCH; + } + x509Alg->rsaPssParam.mdId = pssMd; + ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_SALT, &x509Alg->rsaPssParam.saltLen, sizeof(int32_t)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = CRYPT_EAL_PkeyCtrl(privKey, CRYPT_CTRL_GET_RSA_MGF, &x509Alg->rsaPssParam.mgfId, sizeof(BslCid)); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + x509Alg->algId = BSL_CID_RSASSAPSS; + return HITLS_X509_SUCCESS; + case 0: // The padding type is not setted, default to EMSA_PKCSV15 + case CRYPT_PKEY_EMSA_PKCSV15: + x509Alg->algId = BSL_OBJ_GetSignIdFromHashAndAsymId(BSL_CID_RSA, (BslCid)mdId); + if (x509Alg->algId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ENCODE_SIGNID); + return HITLS_X509_ERR_ENCODE_SIGNID; + } + CRYPT_RSA_PkcsV15Para pkcsPara = {mdId}; + return CRYPT_EAL_PkeyCtrl( + privKey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &pkcsPara, sizeof(CRYPT_RSA_PkcsV15Para)); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_RSA_PAD); + return HITLS_X509_ERR_RSA_PAD; + } +} + +int32_t HITLS_X509_SetSignAlgInfo(CRYPT_EAL_PkeyCtx *privKey, CRYPT_MD_AlgId mdId, HITLS_X509_Asn1AlgId *x509Alg) +{ + CRYPT_PKEY_AlgId pkeyId = CRYPT_EAL_PkeyGetId(privKey); + switch (pkeyId) { + case CRYPT_PKEY_RSA: + return ProcRsaSignInfo(privKey, mdId, x509Alg); + case CRYPT_PKEY_ECDSA: + case CRYPT_PKEY_SM2: + x509Alg->algId = BSL_OBJ_GetSignIdFromHashAndAsymId((BslCid)pkeyId, (BslCid)mdId); + if (x509Alg->algId == BSL_CID_UNKNOWN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ENCODE_SIGNID); + return HITLS_X509_ERR_ENCODE_SIGNID; + } + return HITLS_X509_SUCCESS; + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_SIGN_ALG); + return HITLS_X509_ERR_CERT_SIGN_ALG; + } +} + +static HITLS_X509_NameNode *DupNameNode(const HITLS_X509_NameNode *src) +{ + /* Src is not null. */ + HITLS_X509_NameNode *dest = BSL_SAL_Malloc(sizeof(HITLS_X509_NameNode)); + if (dest == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return NULL; + } + dest->layer = src->layer; + + // nameType + dest->nameType = src->nameType; + dest->nameType.len = src->nameType.len; + if (dest->nameType.len != 0) { + dest->nameType.buff = BSL_SAL_Dump(src->nameType.buff, src->nameType.len); + if (dest->nameType.buff == NULL) { + BSL_SAL_Free(dest); + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return NULL; + } + } + + // nameValue + dest->nameValue = src->nameValue; + dest->nameValue.len = src->nameValue.len; + if (dest->nameValue.len != 0) { + dest->nameValue.buff = BSL_SAL_Dump(src->nameValue.buff, src->nameValue.len); + if (dest->nameValue.buff == NULL) { + BSL_SAL_Free(dest->nameType.buff); + BSL_SAL_Free(dest); + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return NULL; + } + } + return dest; +} + +#define X509_DN_NAME_ELEM_NUMBER 2 + +static int32_t X509EncodeNameNodeEntry(const HITLS_X509_NameNode *nameNode, BSL_ASN1_Buffer *asn1Buff) +{ + BSL_ASN1_Buffer asnArr[X509_DN_NAME_ELEM_NUMBER] = { + nameNode->nameType, + nameNode->nameValue, + }; + BSL_ASN1_TemplateItem dnTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + {BSL_ASN1_TAG_ANY, 0, 0} + }; + + BSL_ASN1_Buffer asnDnBuff = {}; + BSL_ASN1_Template dntTempl = {dnTempl, sizeof(dnTempl) / sizeof(dnTempl[0])}; + int32_t ret = BSL_ASN1_EncodeTemplate(&dntTempl, asnArr, X509_DN_NAME_ELEM_NUMBER, + &asnDnBuff.buff, &asnDnBuff.len); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asnDnBuff.tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + BSL_ASN1_TemplateItem seqItem = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}; + BSL_ASN1_Template seqTempl = {&seqItem, 1}; + ret = BSL_ASN1_EncodeTemplate(&seqTempl, &asnDnBuff, 1, &asn1Buff->buff, &asn1Buff->len); + BSL_SAL_FREE(asnDnBuff.buff); + return ret; +} + +/** + * X.690: 11.6 Set-of components + * https://www.itu.int/rec/T-REC-X.690-202102-I/en + * The encodings of the component values of a set-of value shall appear in ascending order, the encodings + * being compared as octet strings with the shorter components being padded at their trailing end with 0-octets. + * NOTE – The padding octets are for comparison purposes only and do not appear in the encodings. +*/ +static int32_t g_cmpRes = HITLS_X509_SUCCESS; +static int32_t CmpDnNameByEncode(const void *pDnName1, const void *pDnName2) +{ + if (pDnName1 == NULL || pDnName2 == NULL) { + g_cmpRes = HITLS_X509_ERR_CERT_INVALID_DN; + return 0; + } + const HITLS_X509_NameNode *node1 = *(const HITLS_X509_NameNode **)pDnName1; + const HITLS_X509_NameNode *node2 = *(const HITLS_X509_NameNode **)pDnName2; + int res; + BSL_ASN1_Buffer asn1Buff = {0}; + BSL_ASN1_Buffer asn2Buff = {0}; + int32_t ret = X509EncodeNameNodeEntry(node1, &asn1Buff); + if (ret != HITLS_X509_SUCCESS) { + g_cmpRes = HITLS_X509_ERR_SORT_NAME_NODE; + BSL_ERR_PUSH_ERROR(ret); + return 0; + } + + ret = X509EncodeNameNodeEntry(node2, &asn2Buff); + if (ret != HITLS_X509_SUCCESS) { + g_cmpRes = HITLS_X509_ERR_SORT_NAME_NODE; + BSL_SAL_FREE(asn1Buff.buff); + BSL_ERR_PUSH_ERROR(ret); + return 0; + } + + if (asn1Buff.len == asn2Buff.len) { + res = memcmp(asn1Buff.buff, asn2Buff.buff, asn2Buff.len); + } else { + uint32_t minSize = asn1Buff.len < asn2Buff.len ? asn1Buff.len : asn2Buff.len; + res = memcmp(asn1Buff.buff, asn2Buff.buff, minSize); + if (res == 0) { + res = asn1Buff.len == minSize ? -1 : 1; + } + } + g_cmpRes = HITLS_X509_SUCCESS; + BSL_SAL_FREE(asn1Buff.buff); + BSL_SAL_FREE(asn2Buff.buff); + return res; +} + +/** + * RFC 5280: + * section 7.1: + * Representation of internationalized names in distinguished names is + * covered in Sections 4.1.2.4, Issuer Name, and 4.1.2.6, Subject Name. + * Standard naming attributes, such as common name, employ the + * DirectoryString type, which supports internationalized names through + * a variety of language encodings. Conforming implementations MUST + * support UTF8String and PrintableString. + * appendix-A.1: + * X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number)) + * X520countryName ::= PrintableString + * X520dnQualifier ::= PrintableString + */ +static int32_t GetAsn1TypeByCid(BslCid cid) +{ + switch (cid) { + case BSL_CID_SERIALNUMBER: + case BSL_CID_COUNTRYNAME: + case BSL_CID_DNQUALIFIER: + return BSL_ASN1_TAG_PRINTABLESTRING; + case BSL_CID_DOMAINCOMPONENT: + return BSL_ASN1_TAG_IA5STRING; + default: + return BSL_ASN1_TAG_UTF8STRING; + } +} + +void HITLS_X509_FreeNameNode(HITLS_X509_NameNode *node) +{ + if (node == NULL) { + return; + } + BSL_SAL_FREE(node->nameType.buff); + node->nameType.len = 0; + node->nameType.tag = 0; + BSL_SAL_FREE(node->nameValue.buff); + node->nameValue.len = 0; + node->nameValue.tag = 0; + BSL_SAL_Free(node); +} + +int32_t HITLS_X509_SetNameList(BslList **dest, void *val, int32_t valLen) +{ + if (dest == NULL || val == NULL || valLen != sizeof(BslList)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + BslList *src = (BslList *)val; + + BSL_LIST_FREE(*dest, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + *dest = BSL_LIST_Copy(src, (BSL_LIST_PFUNC_DUP)DupNameNode, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + if (*dest == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_NAME_LIST); + return HITLS_X509_ERR_SET_NAME_LIST; + } + return HITLS_X509_SUCCESS; +} + +static int32_t FillNameNodes(HITLS_X509_NameNode *layer2, uint8_t *data, uint32_t dataLen, BslOidString *oid) +{ + layer2->layer = 2; // 2: The layer of sequence + layer2->nameType.tag = BSL_ASN1_TAG_OBJECT_ID; + + layer2->nameType.buff = BSL_SAL_Dump((uint8_t *)oid->octs, oid->octetLen); + layer2->nameValue.buff = BSL_SAL_Dump(data, dataLen); + if (layer2->nameType.buff == NULL || layer2->nameValue.buff == NULL) { + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + + layer2->nameType.len = oid->octetLen; + layer2->nameValue.len = dataLen; + return HITLS_X509_SUCCESS; +} + +static int32_t X509AddDnNameItemToList(BslList *dnNameList, BslCid cid, uint8_t *data, uint32_t dataLen) +{ + if (data == NULL || dataLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + const BslAsn1StrInfo *asn1StrInfo = BSL_OBJ_GetAsn1StrFromCid(cid); + if (asn1StrInfo == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_DNNAME_UNKKOWN); + return HITLS_X509_ERR_SET_DNNAME_UNKKOWN; + } + if (asn1StrInfo->max != -1 && ((int32_t)dataLen < asn1StrInfo->min || (int32_t)dataLen > asn1StrInfo->max)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_DNNAME_INVALID_LEN); + return HITLS_X509_ERR_SET_DNNAME_INVALID_LEN; + } + BslOidString *oid = BSL_OBJ_GetOidFromCID(cid); + if (oid == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_DNNAME_UNKKOWN); + return HITLS_X509_ERR_SET_DNNAME_UNKKOWN; + } + + HITLS_X509_NameNode *layer2 = BSL_SAL_Calloc(1, sizeof(HITLS_X509_NameNode)); + if (layer2 == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + layer2->nameValue.tag = GetAsn1TypeByCid(cid); + int32_t ret = FillNameNodes(layer2, data, dataLen, oid); + if (ret != HITLS_X509_SUCCESS) { + HITLS_X509_FreeNameNode(layer2); + return ret; + } + + ret = BSL_LIST_AddElement(dnNameList, layer2, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + HITLS_X509_FreeNameNode(layer2); + } + + return ret; +} + +static int32_t X509AddDnNamesToList(BslList *list, const BslList *dnNameList) +{ + HITLS_X509_NameNode *layer1 = BSL_SAL_Calloc(1, sizeof(HITLS_X509_NameNode)); + if (layer1 == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + layer1->layer = 1; + + int32_t ret = BSL_LIST_AddElement(list, layer1, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + HITLS_X509_FreeNameNode(layer1); + return ret; + } + + list = BSL_LIST_Concat(list, dnNameList); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_LIST_ERR_CONCAT); + HITLS_X509_FreeNameNode(layer1); + return BSL_LIST_ERR_CONCAT; + } + + return ret; +} + +int32_t HITLS_X509_AddDnName(BslList *list, HITLS_X509_DN *dnNames, int32_t size) +{ + if (list == NULL || dnNames == NULL || size <= 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (BSL_LIST_COUNT(list) == HITLS_X509_DNNAME_MAX_NUM) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_DNNAME_TOOMUCH); + return HITLS_X509_ERR_SET_DNNAME_TOOMUCH; + } + + BslList *dnNameList = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + if (dnNameList == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret; + for (int32_t i = 0; i < size; i++) { + ret = X509AddDnNameItemToList(dnNameList, dnNames[i].cid, dnNames[i].data, dnNames[i].dataLen); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + } + // sort + dnNameList = BSL_LIST_Sort(dnNameList, CmpDnNameByEncode); + if (g_cmpRes != HITLS_X509_SUCCESS) { + ret = g_cmpRes; + goto ERR; + } + // add dnNameList to list + ret = X509AddDnNamesToList(list, dnNameList); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + BSL_SAL_FREE(dnNameList); + return ret; +ERR: + BSL_ERR_PUSH_ERROR(ret); + BSL_LIST_FREE(dnNameList, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + return ret; +} diff --git a/x509/x509_common/src/hitls_x509_ext.c b/x509/x509_common/src/hitls_x509_ext.c new file mode 100644 index 00000000..24ee1cd8 --- /dev/null +++ b/x509/x509_common/src/hitls_x509_ext.c @@ -0,0 +1,1301 @@ +/* + * 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 "securec.h" +#include "bsl_obj.h" +#include "bsl_obj_internal.h" +#include "bsl_sal.h" +#include "bsl_type.h" +#include "bsl_err_internal.h" +#include "hitls_x509_errno.h" +#include "hitls_x509_local.h" + +#define BITS_OF_BYTE 8 +#define HITLS_X509_EXT_NOT_FOUND 1 +#define HITLS_X509_EXT_KEYUSAGE_UNUSED_BIT 0xFFFF7F00 // Only 9 bits are used. + +/** + * RFC 5280: section-4.1 + * Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING + -- contains the DER encoding of an ASN.1 value + -- corresponding to the extension type identified + -- by extnID + } + */ +static BSL_ASN1_TemplateItem g_extSeqTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 1}, + {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 1}, + {BSL_ASN1_TAG_OCTETSTRING, 1, 1}, +}; + +static BSL_ASN1_TemplateItem g_x509ExtTempl[] = { + {BSL_ASN1_TAG_OBJECT_ID, 0, 0}, + {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 0}, + {BSL_ASN1_TAG_OCTETSTRING, 0, 0}, +}; + +typedef enum { + HITLS_X509_EXT_OID_IDX, + HITLS_X509_EXT_CRITICAL_IDX, + HITLS_X509_EXT_VALUE_IDX, + HITLS_X509_EXT_MAX +} HITLS_X509_EXT_IDX; + +/** + * RFC 5280: section-4.2.1.9 + * BasicConstraints ::= SEQUENCE { + * cA BOOLEAN DEFAULT FALSE, + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + */ +static BSL_ASN1_TemplateItem g_bConsTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 1}, + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_OPTIONAL, 1}, +}; + +typedef enum { + HITLS_X509_EXT_BC_CA_IDX, + HITLS_X509_EXT_BC_PATHLEN_IDX, + HITLS_X509_EXT_BC_MAX +} HITLS_X509_EXT_BASICCONTRAINS; + +/** + * RFC 5280: section-4.2.1.1 + * AuthorityKeyIdentifier ::= SEQUENCE { + * keyIdentifier [0] KeyIdentifier OPTIONAL, + * authorityCertIssuer [1] GeneralNames OPTIONAL, + * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } + */ +#define HITLS_X509_CTX_SPECIFIC_TAG_AKID_KID 0 +#define HITLS_X509_CTX_SPECIFIC_TAG_AKID_ISSUER 1 +#define HITLS_X509_CTX_SPECIFIC_TAG_AKID_SERIAL 2 + +static BSL_ASN1_TemplateItem g_akidTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + /* keyIdentifiier */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_KID, BSL_ASN1_FLAG_OPTIONAL, 1}, + /* authorityCertIssuer */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_X509_CTX_SPECIFIC_TAG_AKID_ISSUER, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 1}, + /* authorityCertSerialNumber */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_SERIAL, BSL_ASN1_FLAG_OPTIONAL, 1}, +}; + +typedef enum { + HITLS_X509_EXT_AKI_KID_IDX, + HITLS_X509_EXT_AKI_ISSUER_IDX, + HITLS_X509_EXT_AKI_SERIAL_IDX, + HITLS_X509_EXT_AKI_MAX, +} HITLS_X509_EXT_AKI; + +/** + * RFC 5280: section-4.2.1.2 + * Two common methods for generating key identifiers from the public key are: + * (1) The kid is composed of 160-bit sha1 hash of the BIT STRING subjectPublicKey. + * (2) The kid is composed of a 4-bit type field with the value 0100 followed by the lease significant 60 bits of the + * sha1 hash of the BIT STRING subjectPublicKey. + */ +#define HITLS_X509_KID_MIN_LEN 8 +#define HITLS_X509_KID_MAX_LEN 20 + +/** + * RFC 5280: section-4.2.1.6 + * SubjectAltName ::= GeneralNames + * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName + * GeneralName ::= CHOICE { + * otherName [0] OtherName, -- not support + * rfc822Name [1] IA5String, + * dNSName [2] IA5String, + * x400Address [3] ORAddress, -- not support + * directoryName [4] Name, + * ediPartyName [5] EDIPartyName, -- not support + * uniformResourceIdentifier [6] IA5String, + * iPAddress [7] OCTET STRING, + * registeredID [8] OBJECT IDENTIFIER -- not support + * } + */ +#define HITLS_X509_GENERALNAME_OTHER_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 0) +#define HITLS_X509_GENERALNAME_RFC822_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | 1) +#define HITLS_X509_GENERALNAME_DNS_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | 2) +#define HITLS_X509_GENERALNAME_X400_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 3) +#define HITLS_X509_GENERALNAME_DIR_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 4) +#define HITLS_X509_GENERALNAME_EDI_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 5) +#define HITLS_X509_GENERALNAME_URI_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | 6) +#define HITLS_X509_GENERALNAME_IP_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | 7) +#define HITLS_X509_GENERALNAME_RID_TAG (BSL_ASN1_CLASS_CTX_SPECIFIC | 8) + +typedef struct { + uint8_t tag; + int32_t type; +} HITLS_X509_GeneralNameMap; + +static HITLS_X509_GeneralNameMap g_gernalNameMap[] = { + {HITLS_X509_GENERALNAME_OTHER_TAG, HITLS_X509_GN_OTHER}, + {HITLS_X509_GENERALNAME_RFC822_TAG, HITLS_X509_GN_EMAIL}, + {HITLS_X509_GENERALNAME_DNS_TAG, HITLS_X509_GN_DNS}, + {HITLS_X509_GENERALNAME_X400_TAG, HITLS_X509_GN_X400}, + {HITLS_X509_GENERALNAME_DIR_TAG, HITLS_X509_GN_DNNAME}, + {HITLS_X509_GENERALNAME_EDI_TAG, HITLS_X509_GN_EDI}, + {HITLS_X509_GENERALNAME_URI_TAG, HITLS_X509_GN_URI}, + {HITLS_X509_GENERALNAME_IP_TAG, HITLS_X509_GN_IP}, + {HITLS_X509_GENERALNAME_RID_TAG, HITLS_X509_GN_RID}, +}; + +static int32_t CmpExtByOid(const void *pExt, const void *pOid) +{ + const HITLS_X509_ExtEntry *ext = pExt; + const BSL_ASN1_Buffer *oid = pOid; + if (ext->extnId.len != oid->len) { + return HITLS_X509_EXT_NOT_FOUND; + } + return memcmp(ext->extnId.buff, oid->buff, oid->len) == 0 ? 0 : HITLS_X509_EXT_NOT_FOUND; +} + +static int32_t CmpExtByCid(const void *pExt, const void *pCid) +{ + const HITLS_X509_ExtEntry *ext = pExt; + BslCid cid = *(BslCid *)pCid; + + return cid == ext->cid ? 0 : HITLS_X509_EXT_NOT_FOUND; +} + +static int32_t ParseExtKeyUsage(HITLS_X509_ExtEntry *extEntry, HITLS_X509_Ext *ext) +{ + uint32_t len; + uint8_t *temp = extEntry->extnValue.buff; + uint32_t tempLen = extEntry->extnValue.len; + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_BITSTRING, &temp, &tempLen, &len); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, len, temp}; + BSL_ASN1_BitString bitString = {0}; + ret = BSL_ASN1_DecodePrimitiveItem(&asn, &bitString); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (bitString.len > sizeof(ext->keyUsage)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXT_KU); + return HITLS_X509_ERR_PARSE_EXT_KU; + } + for (uint32_t i = 0; i < bitString.len; i++) { + ext->keyUsage |= (bitString.buff[i] << (BITS_OF_BYTE * i)); + } + ext->extFlags |= HITLS_X509_EXT_FLAG_KUSAGE; + return HITLS_X509_SUCCESS; +} + +static int32_t ParseExtBasicContaints(HITLS_X509_ExtEntry *extEntry, HITLS_X509_Ext *ext) +{ + uint8_t *temp = extEntry->extnValue.buff; + uint32_t tempLen = extEntry->extnValue.len; + BSL_ASN1_Buffer asnArr[HITLS_X509_EXT_BC_MAX] = {0}; + BSL_ASN1_Template templ = {g_bConsTempl, sizeof(g_bConsTempl) / sizeof(g_bConsTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_EXT_BC_MAX); + if (tempLen != 0) { + ret = HITLS_X509_ERR_PARSE_EXT_BUF; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (asnArr[HITLS_X509_EXT_BC_CA_IDX].tag != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_EXT_BC_CA_IDX], &ext->isCa); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + if (asnArr[HITLS_X509_EXT_BC_PATHLEN_IDX].tag != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_EXT_BC_PATHLEN_IDX], &ext->maxPathLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + ext->extFlags |= HITLS_X509_EXT_FLAG_BCONS; + return ret; +} + +static int32_t ParseDirName(uint8_t **encode, uint32_t *encLen, BslList **list) +{ + uint32_t valueLen; + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, encode, encLen, &valueLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + *list = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + if (*list == NULL) { + return HITLS_X509_ERR_PARSE_GENERALNAME_DIR; + } + BSL_ASN1_Buffer asn = {.buff = *encode, .len = valueLen}; + ret = HITLS_X509_ParseNameList(&asn, *list); + if (ret == BSL_SUCCESS) { + *encode += valueLen; + *encLen -= valueLen; + } else { + BSL_LIST_DeleteAll(*list, NULL); + *list = NULL; + } + return ret; +} + +static int32_t ParseGernalName(uint8_t tag, uint8_t **encode, uint32_t *encLen, uint32_t nameLen, BslList *list) +{ + int32_t type = -1; + int32_t ret; + BslList *dirNames = NULL; + BSL_Buffer value = {0}; + for (uint32_t i = 0; i < sizeof(g_gernalNameMap) / sizeof(g_gernalNameMap[0]); i++) { + if (g_gernalNameMap[i].tag == tag) { + type = g_gernalNameMap[i].type; + break; + } + } + if (type == -1) { + return HITLS_X509_ERR_PARSE_SAN_ITEM_UNKNOW; + } + if (tag == HITLS_X509_GENERALNAME_DIR_TAG) { + ret = ParseDirName(encode, encLen, &dirNames); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + value.data = (uint8_t *)dirNames; + value.dataLen = sizeof(BslList *); + } else { + value.data = *encode; + value.dataLen = nameLen; + } + HITLS_X509_GeneralName *name = BSL_SAL_Calloc(1, sizeof(HITLS_X509_GeneralName)); + if (name == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + name->type = type; + name->value = value; + ret = BSL_LIST_AddElement(list, name, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + BSL_LIST_DeleteAll(dirNames, NULL); + BSL_SAL_Free(dirNames); + BSL_SAL_Free(name); + } + return ret; +} + +static void FreeGenernalName(void *data) +{ + HITLS_X509_GeneralName *name = (HITLS_X509_GeneralName *)data; + if (name->type == HITLS_X509_GN_DNNAME) { + BSL_LIST_DeleteAll((BslList *)name->value.data, NULL); + BSL_SAL_Free(name->value.data); + } + BSL_SAL_Free(data); +} + +void HITLS_X509_FreeGeneralName(HITLS_X509_GeneralName *data) +{ + if (data == NULL) { + return; + } + if (data->type == HITLS_X509_GN_DNNAME) { + BSL_LIST_DeleteAll((BslList *)data->value.data, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + } + BSL_SAL_Free(data->value.data); + BSL_SAL_Free(data); +} + +void HITLS_X509_FreeGeneralNames(BslList *names) +{ + if (names == NULL) { + return; + } + BSL_LIST_DeleteAll(names, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeGeneralName); +} + +void HITLS_X509_ClearGeneralNames(BslList *names) +{ + if (names == NULL) { + return; + } + BSL_LIST_DeleteAll(names, (BSL_LIST_PFUNC_FREE)FreeGenernalName); +} + +HITLS_X509_Ext *HITLS_X509_ExtNew(void) +{ + HITLS_X509_Ext *ext = (HITLS_X509_Ext *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Ext)); + if (ext == NULL) { + return NULL; + } + ext->list = BSL_LIST_New(sizeof(HITLS_X509_ExtEntry *)); + if (ext->list == NULL) { + BSL_SAL_Free(ext); + return NULL; + } + + return ext; +} + +void HITLS_X509_ExtFree(HITLS_X509_Ext *ext) +{ + if (ext == NULL) { + return; + } + if ((ext->extFlags & HITLS_X509_EXT_FLAG_PARSE) != 0) { + BSL_LIST_FREE(ext->list, NULL); + } else { + BSL_LIST_FREE(ext->list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); + } + BSL_SAL_Free(ext); +} + +int32_t HITLS_X509_ParseGeneralNames(uint8_t *encode, uint32_t encLen, BslList *list) +{ + uint8_t *buff = encode; + uint32_t buffLen = encLen; + uint32_t nameValueLen; + uint8_t tag; + int32_t ret; + + while (buffLen != 0) { + // tag + tag = *buff; + buff++; + buffLen--; + // length + ret = BSL_ASN1_DecodeLen(&buff, &buffLen, false, &nameValueLen); + if (ret != BSL_SUCCESS) { + break; + } + if (nameValueLen == 0) { + continue; + } + // value + ret = ParseGernalName(tag, &buff, &buffLen, nameValueLen, list); + if (ret != BSL_SUCCESS) { + break; + } + if (tag != HITLS_X509_GENERALNAME_DIR_TAG) { + buff += nameValueLen; + buffLen -= nameValueLen; + } + } + if (ret != BSL_SUCCESS) { + HITLS_X509_ClearGeneralNames(list); + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +void HITLS_X509_ClearAuthorityKeyId(HITLS_X509_ExtAki *aki) +{ + if (aki == NULL) { + return; + } + if (aki->issuerName != NULL) { + HITLS_X509_ClearGeneralNames(aki->issuerName); + BSL_SAL_Free(aki->issuerName); + aki->issuerName = NULL; + } +} + +int32_t HITLS_X509_ParseAuthorityKeyId(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtAki *aki) +{ + uint8_t *temp = extEntry->extnValue.buff; + uint32_t tempLen = extEntry->extnValue.len; + BslList *list = NULL; + BSL_ASN1_Buffer asnArr[HITLS_X509_EXT_AKI_MAX] = {0}; + BSL_ASN1_Template templ = {g_akidTempl, sizeof(g_akidTempl) / sizeof(g_akidTempl[0])}; + + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_EXT_AKI_MAX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + if (asnArr[HITLS_X509_EXT_AKI_KID_IDX].tag != 0) { + aki->kid.data = asnArr[HITLS_X509_EXT_AKI_KID_IDX].buff; + aki->kid.dataLen = asnArr[HITLS_X509_EXT_AKI_KID_IDX].len; + } + if (asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].tag != 0) { + aki->serialNum.data = asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].buff; + aki->serialNum.dataLen = asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].len; + } + if (asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].tag != 0) { + list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_AKI); + return HITLS_X509_ERR_PARSE_AKI; + } + ret = HITLS_X509_ParseGeneralNames( + asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].buff, asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].len, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(list); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + aki->issuerName = list; + } + aki->critical = extEntry->critical; + return ret; +} + +int32_t HITLS_X509_ParseSubjectKeyId(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtSki *ski) +{ + uint8_t *temp = extEntry->extnValue.buff; + uint32_t tempLen = extEntry->extnValue.len; + uint32_t kidLen = 0; + + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_OCTETSTRING, &temp, &tempLen, &kidLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ski->kid.data = temp; + ski->kid.dataLen = kidLen; + ski->critical = extEntry->critical; + return ret; +} + +static int32_t ParseExKeyUsageList(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list) +{ + (void)param; + if (layer == 1) { + return HITLS_X509_SUCCESS; + } + + BSL_Buffer *buff = BSL_SAL_Malloc(sizeof(BSL_Buffer)); + if (buff == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXKU_ITEM); + return HITLS_X509_ERR_PARSE_EXKU_ITEM; + } + buff->data = asn->buff; + buff->dataLen = asn->len; + int32_t ret = BSL_LIST_AddElement(list, buff, BSL_LIST_POS_AFTER); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + BSL_SAL_Free(buff); + } + return ret; +} + +void HITLS_X509_ClearExtendedKeyUsage(HITLS_X509_ExtExKeyUsage *exku) +{ + if (exku == NULL) { + return; + } + BSL_LIST_DeleteAll(exku->oidList, NULL); + BSL_SAL_FREE(exku->oidList); +} + +int32_t HITLS_X509_ParseExtendedKeyUsage(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtExKeyUsage *exku) +{ + uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_TAG_OBJECT_ID}; + BSL_ASN1_DecodeListParam listParam = {sizeof(expTag) / sizeof(uint8_t), expTag}; + + BslList *list = BSL_LIST_New(sizeof(BSL_Buffer)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXKU); + return HITLS_X509_ERR_PARSE_EXKU; + } + + int32_t ret = BSL_ASN1_DecodeListItem(&listParam, &extEntry->extnValue, ParseExKeyUsageList, NULL, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_DeleteAll(list, NULL); + BSL_SAL_Free(list); + return ret; + } + + exku->critical = extEntry->critical; + exku->oidList = list; + return ret; +} + +void HITLS_X509_ClearSubjectAltName(HITLS_X509_ExtSan *san) +{ + if (san == NULL) { + return; + } + if (san->names != NULL) { + HITLS_X509_ClearGeneralNames(san->names); + BSL_SAL_Free(san->names); + san->names = NULL; + } +} + +int32_t HITLS_X509_ParseSubjectAltName(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtSan *san) +{ + uint32_t len; + uint8_t *buff = extEntry->extnValue.buff; + uint32_t buffLen = extEntry->extnValue.len; + // skip the sequence + int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, &buff, &buffLen, &len); + if (ret == BSL_SUCCESS && buffLen != len) { + ret = HITLS_X509_ERR_PARSE_NO_ENOUGH; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BslList *list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_SAN); + return HITLS_X509_ERR_PARSE_SAN; + } + ret = HITLS_X509_ParseGeneralNames(buff, len, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(list); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + san->names = list; + san->critical = extEntry->critical; + return ret; +} + +int32_t HITLS_X509_ParseExtItem(BSL_ASN1_Buffer *extItem, HITLS_X509_ExtEntry *extEntry) +{ + uint8_t *temp = extItem->buff; + uint32_t tempLen = extItem->len; + BSL_ASN1_Buffer asnArr[HITLS_X509_EXT_MAX] = {0}; + BSL_ASN1_Template templ = {g_x509ExtTempl, sizeof(g_x509ExtTempl) / sizeof(g_x509ExtTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_EXT_MAX); + if (tempLen != 0) { + ret = HITLS_X509_ERR_PARSE_EXT_BUF; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // extnid + extEntry->extnId = asnArr[HITLS_X509_EXT_OID_IDX]; + BslOidString oid = {extEntry->extnId.len, (char *)extEntry->extnId.buff, 0}; + extEntry->cid = BSL_OBJ_GetCIDFromOid(&oid); + // critical + if (asnArr[HITLS_X509_EXT_CRITICAL_IDX].tag == 0) { + extEntry->critical = false; + } else { + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_EXT_CRITICAL_IDX], &extEntry->critical); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + extEntry->extnValue = asnArr[HITLS_X509_EXT_VALUE_IDX]; + return ret; +} + +static void FreeExtEntryCont(HITLS_X509_ExtEntry *entry) +{ + BSL_SAL_FREE(entry->extnId.buff); + BSL_SAL_FREE(entry->extnValue.buff); + entry->extnId.len = 0; + entry->extnValue.len = 0; +} + +static int32_t GetExtEntryByCid(HITLS_X509_Ext *ext, BslCid cid, HITLS_X509_ExtEntry **entry, bool *isNew) +{ + BslOidString *oid = BSL_OBJ_GetOidFromCID(cid); + if (oid == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_OID); + return HITLS_X509_ERR_EXT_OID; + } + HITLS_X509_ExtEntry *extEntry = BSL_LIST_Search(ext->list, &cid, CmpExtByCid, NULL); + if (extEntry != NULL) { + *isNew = false; + FreeExtEntryCont(extEntry); + extEntry->critical = false; + } else { + extEntry = BSL_SAL_Calloc(1, sizeof(HITLS_X509_ExtEntry)); + if (extEntry == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + *isNew = true; + } + + extEntry->cid = cid; + extEntry->extnId.tag = BSL_ASN1_TAG_OBJECT_ID; + extEntry->extnId.len = oid->octetLen; + if (extEntry->extnId.len != 0) { + extEntry->extnId.buff = BSL_SAL_Dump(oid->octs, oid->octetLen); + if (extEntry->extnId.buff == NULL) { + if (isNew) { + BSL_SAL_Free(extEntry); + } + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + } + extEntry->extnValue.tag = BSL_ASN1_TAG_OCTETSTRING; + *entry = extEntry; + return HITLS_X509_SUCCESS; +} + +static int32_t ParseExtAsnItem(BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list) +{ + HITLS_X509_Ext *ext = param; + HITLS_X509_ExtEntry extEntry = {0}; + int32_t ret = HITLS_X509_ParseExtItem(asn, &extEntry); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // Check if the extension already exists. + if (BSL_LIST_Search(list, &extEntry.extnId, CmpExtByOid, NULL) != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXT_REPEAT); + return HITLS_X509_ERR_PARSE_EXT_REPEAT; + } + + // Add the extension to list. + ret = HITLS_X509_AddListItemDefault(&extEntry, sizeof(HITLS_X509_ExtEntry), list); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BslOidString oid = {extEntry.extnId.len, (char *)extEntry.extnId.buff, 0}; + switch (BSL_OBJ_GetCIDFromOid(&oid)) { + case BSL_CID_CE_KEYUSAGE: + return ParseExtKeyUsage(&extEntry, ext); + case BSL_CID_CE_BASICCONSTRAINTS: + return ParseExtBasicContaints(&extEntry, ext); + default: + return HITLS_X509_SUCCESS; + } +} + +static int32_t ParseExtSeqof(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list) +{ + return layer == 1 ? HITLS_X509_SUCCESS : ParseExtAsnItem(asn, param, list); +} + +int32_t HITLS_X509_ParseExt(BSL_ASN1_Buffer *ext, HITLS_X509_Ext *certExt) +{ + if (certExt == NULL || (certExt->extFlags & HITLS_X509_EXT_FLAG_SET)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_PARSE_AFTER_SET); + return HITLS_X509_ERR_EXT_PARSE_AFTER_SET; + } + // x509 v1 + if (ext->tag == 0) { + return HITLS_X509_SUCCESS; + } + + uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE}; + BSL_ASN1_DecodeListParam listParam = {2, expTag}; + int ret = BSL_ASN1_DecodeListItem(&listParam, ext, &ParseExtSeqof, certExt, certExt->list); + if (ret != BSL_SUCCESS) { + BSL_LIST_DeleteAll(certExt->list, NULL); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + certExt->extFlags |= HITLS_X509_EXT_FLAG_PARSE; + return ret; +} + +static int32_t SetExtBCons(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val) +{ + const HITLS_X509_ExtBCons *bCons = (const HITLS_X509_ExtBCons *)val; + BSL_ASN1_Template templ = {g_bConsTempl, sizeof(g_bConsTempl) / sizeof(g_bConsTempl[0])}; + /** + * RFC 5280: section-4.2.1.9 + * BasicConstraints ::= SEQUENCE { + * cA BOOLEAN DEFAULT FALSE, + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + */ + BSL_ASN1_Buffer asns[] = { + {BSL_ASN1_TAG_BOOLEAN, bCons->isCa ? sizeof(bool) : 0, bCons->isCa ? (uint8_t *)&bCons->isCa : NULL}, + {BSL_ASN1_TAG_INTEGER, 0, NULL}, + }; + int32_t ret; + + if (bCons->maxPathLen >= 0) { + ret = BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, (uint64_t)bCons->maxPathLen, asns + 1); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } + + ret = BSL_ASN1_EncodeTemplate( + &templ, asns, sizeof(asns) / sizeof(asns[0]), &entry->extnValue.buff, &entry->extnValue.len); + BSL_SAL_Free(asns[1].buff); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + entry->critical = bCons->critical; + + ext->isCa = bCons->isCa; + ext->maxPathLen = bCons->maxPathLen; + ext->extFlags |= HITLS_X509_EXT_FLAG_BCONS; + return HITLS_X509_SUCCESS; +} + +static int32_t SetExtKeyUsage(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val) +{ + const HITLS_X509_ExtKeyUsage *ku = (const HITLS_X509_ExtKeyUsage *)val; + if (ku->keyUsage == 0 || (ku->keyUsage & HITLS_X509_EXT_KEYUSAGE_UNUSED_BIT) != 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_KU); + return HITLS_X509_ERR_EXT_KU; + } + + // bit string + uint16_t keyUsage = (uint16_t)ku->keyUsage; + BSL_ASN1_BitString bs = {0}; + bs.len = (keyUsage & HITLS_X509_EXT_KU_DECIPHER_ONLY) == 0 ? 1 : 2; // 2: decipher only is not 0 + bs.buff = (uint8_t *)&keyUsage; + uint8_t tmp = bs.len == 1 ? (uint8_t)keyUsage : (uint8_t)(keyUsage >> BITS_OF_BYTE); + for (int32_t i = 1; i < BITS_OF_BYTE; i++) { + if ((uint8_t)(tmp << i) == 0) { + bs.unusedBits = BITS_OF_BYTE - i; + break; + } + } + + // encode bit string + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, sizeof(BSL_ASN1_BitString), (uint8_t *)&bs}; + BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_BITSTRING, 0, 0}; + BSL_ASN1_Template templ = {&item, 1}; + int32_t ret = BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &entry->extnValue.buff, &entry->extnValue.len); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + entry->critical = ku->critical; + ext->extFlags |= HITLS_X509_EXT_FLAG_KUSAGE; + return ret; +} + +static int32_t SetExtAki(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val) +{ + (void)ext; + const HITLS_X509_ExtAki *aki = (const HITLS_X509_ExtAki *)val; + entry->critical = aki->critical; + + if (aki->kid.dataLen < HITLS_X509_KID_MIN_LEN || aki->kid.dataLen > HITLS_X509_KID_MAX_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_KID); + return HITLS_X509_ERR_EXT_KID; + } + + BSL_ASN1_Buffer asns[] = { + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_KID, aki->kid.dataLen, aki->kid.data}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_X509_CTX_SPECIFIC_TAG_AKID_ISSUER, 0, NULL}, + {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_SERIAL, 0, NULL}, + }; + BSL_ASN1_Template templ = {g_akidTempl, sizeof(g_akidTempl) / sizeof(g_akidTempl[0])}; + int32_t ret = BSL_ASN1_EncodeTemplate( + &templ, asns, sizeof(asns) / sizeof(asns[0]), &entry->extnValue.buff, &entry->extnValue.len); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t SetExtSki(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val) +{ + (void)ext; + const HITLS_X509_ExtSki *ski = (const HITLS_X509_ExtSki *)val; + entry->critical = ski->critical; + + if (ski->kid.dataLen < HITLS_X509_KID_MIN_LEN || ski->kid.dataLen > HITLS_X509_KID_MAX_LEN) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_KID); + return HITLS_X509_ERR_EXT_KID; + } + + BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_OCTETSTRING, ski->kid.dataLen, ski->kid.data}; + BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_OCTETSTRING, 0, 0}; + BSL_ASN1_Template templ = {&item, 1}; + int32_t ret = BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &entry->extnValue.buff, &entry->extnValue.len); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static void SetAsn1Templ(BSL_Buffer *value, int32_t tag, BSL_ASN1_TemplateItem *item, BSL_ASN1_Buffer *asn) +{ + item->tag = tag; + asn->tag = tag; + asn->len = value->dataLen; + asn->buff = value->data; +} + +static void FreeGnAsns(BSL_ASN1_Buffer *asns, uint32_t number) +{ + for (uint32_t i = 0; i < number; i++) { + if (asns[i].tag == HITLS_X509_GENERALNAME_DIR_TAG) { + BSL_SAL_Free(asns[i].buff); + } + } + BSL_SAL_Free(asns); +} + +static int32_t GetSanDirNameExtnValue(BslList *dirNames, BSL_ASN1_Buffer *extnValue) +{ + BSL_ASN1_Buffer tmp = {0}; + int32_t ret = HITLS_X509_EncodeNameList((BSL_ASN1_List *)dirNames, &tmp); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}; + BSL_ASN1_Template templ = {&item, 1}; + ret = BSL_ASN1_EncodeTemplate(&templ, &tmp, 1, &extnValue->buff, &extnValue->len); + BSL_SAL_Free(tmp.buff); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + extnValue->tag = HITLS_X509_GENERALNAME_DIR_TAG; + return ret; +} + +static int32_t SetGnEncodeParam(BslList *names, BSL_ASN1_TemplateItem *items, BSL_ASN1_Buffer *asns) +{ + HITLS_X509_GeneralName **name = BSL_LIST_First(names); + BSL_ASN1_TemplateItem *item = items; + BSL_ASN1_Buffer *asn = asns; + int32_t ret; + while (name != NULL) { + if ((*name)->value.data == NULL || (*name)->value.dataLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SAN_ELE); + return HITLS_X509_ERR_EXT_SAN_ELE; + } + switch ((*name)->type) { + case HITLS_X509_GN_EMAIL: + SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_RFC822_TAG, item, asn); + break; + case HITLS_X509_GN_DNS: + SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_DNS_TAG, item, asn); + break; + case HITLS_X509_GN_DNNAME: + ret = GetSanDirNameExtnValue((BSL_ASN1_List *)(*name)->value.data, asn); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + item->tag = HITLS_X509_GENERALNAME_DIR_TAG; + break; + case HITLS_X509_GN_URI: + SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_URI_TAG, item, asn); + break; + case HITLS_X509_GN_IP: + SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_IP_TAG, item, asn); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_GN_UNSUPPORT); + return HITLS_X509_ERR_EXT_GN_UNSUPPORT; + } + item->depth = 1; + item++; + asn++; + name = BSL_LIST_Next(names); + } + return HITLS_X509_SUCCESS; +} + +static int32_t AllocEncodeParam(BSL_ASN1_TemplateItem **items, uint32_t itemNum, BSL_ASN1_Buffer **asns, + uint32_t asnNum) +{ + *items = BSL_SAL_Calloc(itemNum, sizeof(BSL_ASN1_TemplateItem)); // sequence + names + if (items == NULL) { + return BSL_MALLOC_FAIL; + } + *asns = BSL_SAL_Calloc(asnNum, sizeof(BSL_ASN1_Buffer)); + if (asns == NULL) { + BSL_SAL_Free(items); + return BSL_MALLOC_FAIL; + } + return HITLS_X509_SUCCESS; +} + +static int32_t SetExtSan(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val) +{ + (void)ext; + const HITLS_X509_ExtSan *san = (const HITLS_X509_ExtSan *)val; + if (san->names == NULL || BSL_LIST_COUNT(san->names) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SAN); + return HITLS_X509_ERR_EXT_SAN; + } + entry->critical = san->critical; + + /* Encode extnValue */ + BSL_ASN1_TemplateItem *items = NULL; + BSL_ASN1_Buffer *asns = NULL; + uint32_t number = BSL_LIST_COUNT(san->names); + int32_t ret = AllocEncodeParam(&items, 1 + number, &asns, number); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + items[0].depth = 0; + items[0].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + ret = SetGnEncodeParam(san->names, items + 1, asns); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(items); + FreeGnAsns(asns, number); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_ASN1_Template templ = {items, number + 1}; + ret = BSL_ASN1_EncodeTemplate(&templ, asns, number, &entry->extnValue.buff, &entry->extnValue.len); + BSL_SAL_Free(items); + FreeGnAsns(asns, number); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t SetExtExKeyUsage(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val) +{ + (void)ext; + const HITLS_X509_ExtExKeyUsage *exku = (const HITLS_X509_ExtExKeyUsage *)val; + if (exku->oidList == NULL || BSL_LIST_COUNT(exku->oidList) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_EXTENDED_KU); + return HITLS_X509_ERR_EXT_EXTENDED_KU; + } + entry->critical = exku->critical; + + BSL_ASN1_TemplateItem *items = NULL; + BSL_ASN1_Buffer *asns = NULL; + uint32_t number = BSL_LIST_COUNT(exku->oidList); + int32_t ret = AllocEncodeParam(&items, number + 1, &asns, number); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + items[0].depth = 0; + items[0].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + BSL_Buffer **buffer = BSL_LIST_First(exku->oidList); + for (uint32_t i = 0; i < number; i++) { + if (buffer == NULL || *buffer == NULL || (*buffer)->dataLen == 0 || (*buffer)->data == NULL) { + BSL_SAL_Free(items); + BSL_SAL_Free(asns); + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_EXTENDED_KU_ELE); + return HITLS_X509_ERR_EXT_EXTENDED_KU_ELE; + } + items[i + 1].depth = 1; + items[i + 1].tag = BSL_ASN1_TAG_OBJECT_ID; + asns[i].tag = BSL_ASN1_TAG_OBJECT_ID; + asns[i].len = (*buffer)->dataLen; + asns[i].buff = (*buffer)->data; + buffer = BSL_LIST_Next(exku->oidList); + } + + BSL_ASN1_Template templ = {items, number + 1}; + ret = BSL_ASN1_EncodeTemplate(&templ, asns, number, &entry->extnValue.buff, &entry->extnValue.len); + BSL_SAL_Free(items); + BSL_SAL_Free(asns); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +typedef int32_t (*EncodeExtCb)(HITLS_X509_Ext *, HITLS_X509_ExtEntry *, const void *); + +static int32_t SetExt(HITLS_X509_Ext *ext, BslCid cid, BSL_Buffer *val, uint32_t expectLen, EncodeExtCb encodeExt) +{ + if (ext->extFlags & HITLS_X509_EXT_FLAG_PARSE) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET_AFTER_PARSE); + return HITLS_X509_ERR_EXT_SET_AFTER_PARSE; + } + if (val->dataLen != expectLen) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + HITLS_X509_ExtEntry *extEntry = NULL; + bool isNew; + int32_t ret = GetExtEntryByCid(ext, cid, &extEntry, &isNew); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + + ret = encodeExt(ext, extEntry, val->data); + if (ret != HITLS_X509_SUCCESS) { + FreeExtEntryCont(extEntry); + if (isNew) { + BSL_SAL_Free(extEntry); + } + return ret; + } + if (isNew) { + ret = BSL_LIST_AddElement(ext->list, extEntry, BSL_LIST_POS_END); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + FreeExtEntryCont(extEntry); + BSL_SAL_Free(extEntry); + return ret; + } + } + + ext->extFlags |= HITLS_X509_EXT_FLAG_SET; + return ret; +} + +static int32_t SetExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, int32_t valLen) +{ + bool isNew = false; + if (ext->list == NULL) { + ext->list = BSL_LIST_New(sizeof(HITLS_X509_ExtEntry)); + if (ext->list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + isNew = true; + } + BSL_Buffer buff = {val, valLen}; + int32_t ret; + switch (cmd) { + case HITLS_X509_EXT_SET_BCONS: + ret = SetExt(ext, BSL_CID_CE_BASICCONSTRAINTS, &buff, sizeof(HITLS_X509_ExtBCons), SetExtBCons); + break; + case HITLS_X509_EXT_SET_KUSAGE: + ret = SetExt(ext, BSL_CID_CE_KEYUSAGE, &buff, sizeof(HITLS_X509_ExtKeyUsage), SetExtKeyUsage); + break; + case HITLS_X509_EXT_SET_AKI: + ret = SetExt(ext, BSL_CID_CE_AUTHORITYKEYID, &buff, sizeof(HITLS_X509_ExtAki), SetExtAki); + break; + case HITLS_X509_EXT_SET_SKI: + ret = SetExt(ext, BSL_CID_CE_SUBJECTKEYID, &buff, sizeof(HITLS_X509_ExtSki), SetExtSki); + break; + case HITLS_X509_EXT_SET_SAN: + ret = SetExt(ext, BSL_CID_CE_SUBJECTALTNAME, &buff, sizeof(HITLS_X509_ExtSan), SetExtSan); + break; + case HITLS_X509_EXT_SET_EXKUSAGE: + ret = SetExt(ext, BSL_CID_CE_EXTENDEDKEYUSAGE, &buff, sizeof(HITLS_X509_ExtExKeyUsage), SetExtExKeyUsage); + break; + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (ret != HITLS_X509_SUCCESS) { + if (isNew) { + BSL_SAL_Free(ext->list); + ext->list = NULL; + } + } + return ret; +} + +typedef int32_t (*DecodeExtCb)(HITLS_X509_ExtEntry *, void *); + +static int32_t GetExt(HITLS_X509_Ext *ext, BslCid cid, BSL_Buffer *val, uint32_t expectLen, DecodeExtCb decodeExt) +{ + if (val->dataLen != expectLen) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + HITLS_X509_ExtEntry *extEntry = BSL_LIST_Search(ext->list, &cid, CmpExtByCid, NULL); + if (extEntry == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_NOT_FOUND); + return HITLS_X509_ERR_EXT_NOT_FOUND; + } + return decodeExt(extEntry, val->data); +} + +static int32_t GetExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, int32_t valLen) +{ + BSL_Buffer buff = {val, valLen}; + switch (cmd) { + case HITLS_X509_EXT_GET_SKI: + return GetExt(ext, BSL_CID_CE_SUBJECTKEYID, &buff, sizeof(HITLS_X509_ExtSki), + (DecodeExtCb)HITLS_X509_ParseSubjectKeyId); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +static int32_t CheckExtByCid(HITLS_X509_Ext *ext, int32_t cid, bool *val, int32_t valLen) +{ + if (valLen != sizeof(bool)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + *val = BSL_LIST_Search(ext->list, &cid, CmpExtByCid, NULL) != NULL; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_ExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, int32_t valLen) +{ + if (ext == NULL || val == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (cmd >= HITLS_X509_EXT_SET_SKI && cmd < HITLS_X509_EXT_GET_SKI) { + return SetExtCtrl(ext, cmd, val, valLen); + } + if (cmd >= HITLS_X509_EXT_GET_SKI && cmd < HITLS_X509_EXT_CHECK_SKI) { + return GetExtCtrl(ext, cmd, val, valLen); + } + if (cmd >= HITLS_X509_EXT_CHECK_SKI && cmd < HITLS_X509_CSR_GET_ATTRIBUTES) { + return CheckExtByCid(ext, BSL_CID_CE_SUBJECTKEYID, val, valLen); + } + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; +} + +void HITLS_X509_ExtEntryFree(HITLS_X509_ExtEntry *entry) +{ + if (entry == NULL) { + return; + } + BSL_SAL_FREE(entry->extnId.buff); + BSL_SAL_FREE(entry->extnValue.buff); + BSL_SAL_Free(entry); +} + +#define X509_CRLEXT_ELEM_NUMBER 3 +int32_t HITLS_X509_EncodeExtEntry(BSL_ASN1_List *list, BSL_ASN1_Buffer *ext) +{ + int32_t count = BSL_LIST_COUNT(list); + BSL_ASN1_Buffer *asnBuf = BSL_SAL_Malloc(count * X509_CRLEXT_ELEM_NUMBER * sizeof(BSL_ASN1_Buffer)); + if (asnBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + uint32_t iter = 0; + HITLS_X509_ExtEntry *node = NULL; + for (node = BSL_LIST_GET_FIRST(list); node != NULL; node = BSL_LIST_GET_NEXT(list)) { + asnBuf[iter].tag = node->extnId.tag; + asnBuf[iter].buff = node->extnId.buff; + asnBuf[iter++].len = node->extnId.len; + asnBuf[iter].tag = BSL_ASN1_TAG_BOOLEAN; + asnBuf[iter].len = node->critical ? 1 : 0; + asnBuf[iter++].buff = node->critical ? (uint8_t *)&(node->critical) : NULL; + asnBuf[iter].tag = node->extnValue.tag; + asnBuf[iter].buff = node->extnValue.buff; + asnBuf[iter++].len = node->extnValue.len; + } + + BSL_ASN1_Template templ = {g_extSeqTempl, sizeof(g_extSeqTempl) / sizeof(g_extSeqTempl[0])}; + int32_t ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, count, &templ, asnBuf, iter, ext); + BSL_SAL_Free(asnBuf); + return ret; +} + +int32_t HITLS_X509_EncodeExt(uint8_t tag, BSL_ASN1_List *list, BSL_ASN1_Buffer *ext) +{ + if (BSL_LIST_COUNT(list) == 0) { + ext->tag = tag; + ext->len = 0; + ext->buff = NULL; + return HITLS_X509_SUCCESS; + } + BSL_ASN1_Buffer extbuff = {0}; + int32_t ret = HITLS_X509_EncodeExtEntry(list, &extbuff); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + BSL_ASN1_TemplateItem extTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, + }; + BSL_ASN1_Template templ = {extTempl, 1}; + ret = BSL_ASN1_EncodeTemplate(&templ, &extbuff, 1, &(ext->buff), &(ext->len)); + BSL_SAL_Free(extbuff.buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ext->tag = tag; + return HITLS_X509_SUCCESS; +} + +static HITLS_X509_ExtEntry *DupExtEntry(const HITLS_X509_ExtEntry *src) +{ + /* Src is not null. */ + HITLS_X509_ExtEntry *dest = BSL_SAL_Malloc(sizeof(HITLS_X509_ExtEntry)); + if (dest == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return NULL; + } + dest->cid = src->cid; + dest->critical = src->critical; + + // extId + dest->extnId.tag = src->extnId.tag; + dest->extnId.len = src->extnId.len; + if (src->extnId.len != 0) { + dest->extnId.buff = BSL_SAL_Dump(src->extnId.buff, src->extnId.len); + if (dest->extnId.buff == NULL) { + BSL_SAL_Free(dest); + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return NULL; + } + } + // extnValue + dest->extnValue.tag = src->extnValue.tag; + dest->extnValue.len = src->extnValue.len; + if (src->extnValue.len != 0) { + dest->extnValue.buff = BSL_SAL_Dump(src->extnValue.buff, src->extnValue.len); + if (dest->extnValue.buff == NULL) { + BSL_SAL_Free(dest->extnId.buff); + BSL_SAL_Free(dest); + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return NULL; + } + } + return dest; +} + +int32_t HITLS_X509_ExtReplace(HITLS_X509_Ext *dest, HITLS_X509_Ext *src) +{ + if (dest == NULL || src == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + if (dest->extFlags & HITLS_X509_EXT_FLAG_PARSE) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET_AFTER_PARSE); + return HITLS_X509_ERR_EXT_SET_AFTER_PARSE; + } + dest->isCa = src->isCa; + dest->maxPathLen = src->maxPathLen; + dest->keyUsage = src->keyUsage; + dest->extFlags = src->extFlags; + if (src->extFlags & HITLS_X509_EXT_FLAG_PARSE) { + dest->extFlags -= HITLS_X509_EXT_FLAG_PARSE; + dest->extFlags |= HITLS_X509_EXT_FLAG_SET; + } + + if (src->list == NULL) { + BSL_LIST_DeleteAll(dest->list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); + return HITLS_X509_SUCCESS; + } + BslList *list = + BSL_LIST_Copy(src->list, (BSL_LIST_PFUNC_DUP)DupExtEntry, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET); + return HITLS_X509_ERR_EXT_SET; + } + BSL_LIST_FREE(dest->list, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree); + dest->list = list; + return HITLS_X509_SUCCESS; +} diff --git a/x509/x509_crl/include/hitls_crl_local.h b/x509/x509_crl/include/hitls_crl_local.h new file mode 100644 index 00000000..ee1ccb48 --- /dev/null +++ b/x509/x509_crl/include/hitls_crl_local.h @@ -0,0 +1,71 @@ +/* + * 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_CRL_LOCAL_H +#define HITLS_CRL_LOCAL_H + +#include +#include "bsl_asn1.h" +#include "bsl_obj.h" +#include "sal_atomic.h" +#include "hitls_x509_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + BSL_ASN1_List *extList; +} HITLS_X509_CrlExt; + +typedef struct { + uint8_t flag; + BSL_ASN1_Buffer serialNumber; + BSL_TIME time; + BSL_ASN1_Buffer entryExt; +} HITLS_X509_CrlEntry; + +typedef struct { + uint8_t *tbsRawData; + uint32_t tbsRawDataLen; + + int32_t version; + HITLS_X509_Asn1AlgId signAlgId; + + BSL_ASN1_List *issuerName; + HITLS_X509_ValidTime validTime; + + BSL_ASN1_List *revokedCerts; + HITLS_X509_CrlExt crlExt; +} HITLS_X509_CrlTbs; + +typedef struct _HITLS_X509_Crl { + bool isCopy; + uint8_t *rawData; + uint32_t rawDataLen; + HITLS_X509_CrlTbs tbs; + HITLS_X509_Asn1AlgId signAlgId; + BSL_ASN1_BitString signature; + BSL_SAL_RefCount references; +} HITLS_X509_Crl; + +HITLS_X509_Crl *HITLS_X509_CrlNew(void); +int32_t HITLS_X509_CrlMulParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_List **crllist); +int32_t HITLS_X509_EncodeCrlTbs(HITLS_X509_CrlTbs *crlTbs, BSL_ASN1_Buffer *asn); +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CRL_LOCAL_H \ No newline at end of file diff --git a/x509/x509_crl/src/hitls_x509_crl.c b/x509/x509_crl/src/hitls_x509_crl.c new file mode 100644 index 00000000..7ec67e8d --- /dev/null +++ b/x509/x509_crl/src/hitls_x509_crl.c @@ -0,0 +1,744 @@ +/* + * 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_x509.h" +#include "bsl_sal.h" +#include "sal_file.h" +#include "securec.h" +#include "hitls_x509_errno.h" +#include "hitls_x509_local.h" +#include "hitls_crl_local.h" +#include "bsl_obj_internal.h" +#include "bsl_pem_internal.h" +#include "bsl_err_internal.h" + +#define HITLS_CRL_CTX_SPECIFIC_TAG_EXTENSION 0 + +BSL_ASN1_TemplateItem g_crlTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* x509 */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* tbs */ + /* 2: version */ + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_DEFAULT, 2}, + /* 2: signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 2}, + {BSL_ASN1_TAG_OBJECT_ID, 0, 3}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 3}, // 6 + /* 2: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + /* 2: validity */ + {BSL_ASN1_TAG_CHOICE, 0, 2}, + {BSL_ASN1_TAG_CHOICE, BSL_ASN1_FLAG_OPTIONAL, 2}, + /* 2: revoked crl list */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME | BSL_ASN1_FLAG_OPTIONAL, 2}, + /* 2: extension */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CRL_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, // 11 + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */ + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2}, + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ +}; + +typedef enum { + HITLS_X509_CRL_VERSION_IDX, + HITLS_X509_CRL_TBS_SIGNALG_OID_IDX, + HITLS_X509_CRL_TBS_SIGNALG_ANY_IDX, + HITLS_X509_CRL_ISSUER_IDX, + HITLS_X509_CRL_BEFORE_VALID_IDX, + HITLS_X509_CRL_AFTER_VALID_IDX, + HITLS_X509_CRL_CRL_LIST_IDX, + HITLS_X509_CRL_EXT_IDX, + HITLS_X509_CRL_SIGNALG_IDX, + HITLS_X509_CRL_SIGNALG_ANY_IDX, + HITLS_X509_CRL_SIGN_IDX, + HITLS_X509_CRL_MAX_IDX, +} HITLS_X509_CRL_IDX; + +int32_t HITLS_X509_CrlTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + (void) idx; + switch (type) { + case BSL_ASN1_TYPE_CHECK_CHOICE_TAG: { + uint8_t tag = *(uint8_t *) data; + if ((tag == BSL_ASN1_TAG_UTCTIME) || (tag == BSL_ASN1_TAG_GENERALIZEDTIME)) { + *(uint8_t *) expVal = tag; + return BSL_SUCCESS; + } + return HITLS_X509_ERR_CHECK_TAG; + } + case BSL_ASN1_TYPE_GET_ANY_TAG: { + BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *) data; + BslOidString oidStr = {param->len, (char *)param->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_UNKNOWN) { + return HITLS_X509_ERR_GET_ANY_TAG; + } + if (cid == BSL_CID_RSASSAPSS) { + // note: any It can be encoded empty or it can be null + *(uint8_t *) expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + return BSL_SUCCESS; + } else { + *(uint8_t *) expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + return HITLS_X509_ERR_GET_ANY_TAG; + } + default: + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +void HITLS_X509_CrlFree(HITLS_X509_Crl *crl) +{ + if (crl == NULL) { + return; + } + + int ret = 0; + BSL_SAL_AtomicDownReferences(&(crl->references), &ret); + if (ret > 0) { + return; + } + + BSL_LIST_FREE(crl->tbs.issuerName, NULL); + BSL_LIST_FREE(crl->tbs.revokedCerts, NULL); + BSL_LIST_FREE(crl->tbs.crlExt.extList, NULL); + BSL_SAL_ReferencesFree(&(crl->references)); + if (crl->isCopy == true) { + BSL_SAL_FREE(crl->rawData); + } + BSL_SAL_Free(crl); + return; +} + +HITLS_X509_Crl *HITLS_X509_CrlNew() +{ + HITLS_X509_Crl *crl = NULL; + BSL_ASN1_List *issuerName = NULL; + BSL_ASN1_List *entryList = NULL; + BSL_ASN1_List *extList = NULL; + crl = (HITLS_X509_Crl *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Crl)); + if (crl == NULL) { + return NULL; + } + + issuerName = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + if (issuerName == NULL) { + goto ERR; + } + + entryList = BSL_LIST_New(sizeof(HITLS_X509_CrlEntry)); + if (entryList == NULL) { + goto ERR; + } + extList = BSL_LIST_New(sizeof(HITLS_X509_ExtEntry)); + if (extList == NULL) { + goto ERR; + } + BSL_SAL_ReferencesInit(&(crl->references)); + crl->tbs.issuerName = issuerName; + crl->tbs.revokedCerts = entryList; + crl->tbs.crlExt.extList = extList; + return crl; +ERR: + BSL_SAL_Free(crl); + BSL_SAL_Free(issuerName); + BSL_SAL_Free(entryList); + return NULL; +} + +int32_t HITLS_CRL_ParseExtAsnItem(BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list) +{ + (void) param; + HITLS_X509_ExtEntry extEntry = {0}; + int32_t ret = HITLS_X509_ParseExtItem(asn, &extEntry); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return HITLS_X509_AddListItemDefault(&extEntry, sizeof(HITLS_X509_ExtEntry), list); +} + +int32_t HITLS_CRL_ParseExtSeqof(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list) +{ + if (layer == 1) { + return HITLS_X509_SUCCESS; + } + return HITLS_CRL_ParseExtAsnItem(asn, param, list); +} + +int32_t HITLS_X509_ParseCrlExt(BSL_ASN1_Buffer *ext, HITLS_X509_Crl *crl) +{ + uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE}; + BSL_ASN1_DecodeListParam listParam = {2, expTag}; + int ret = BSL_ASN1_DecodeListItem(&listParam, ext, &HITLS_CRL_ParseExtSeqof, crl, crl->tbs.crlExt.extList); + if (ret != BSL_SUCCESS) { + BSL_LIST_DeleteAll(crl->tbs.crlExt.extList, NULL); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +BSL_ASN1_TemplateItem g_crlEntryTempl[] = { + {BSL_ASN1_TAG_INTEGER, 0, 0}, + {BSL_ASN1_TAG_CHOICE, 0, 0}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 0} +}; + +typedef enum { + HITLS_X509_CRLENTRY_NUM_IDX, + HITLS_X509_CRLENTRY_TIME_IDX, + HITLS_X509_CRLENTRY_EXT_IDX, + HITLS_X509_CRLENTRY_MAX_IDX +} HITLS_X509_CRLENTRY_IDX; + +int32_t HITLS_X509_CrlEntryChoiceCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + (void) idx; + (void) expVal; + if (type == BSL_ASN1_TYPE_CHECK_CHOICE_TAG) { + uint8_t tag = *(uint8_t *) data; + if ((tag & BSL_ASN1_TAG_UTCTIME) || (tag & BSL_ASN1_TAG_GENERALIZEDTIME)) { + *(uint8_t *) expVal = tag; + return BSL_SUCCESS; + } + return HITLS_X509_ERR_CHECK_TAG; + } + return HITLS_X509_ERR_CHECK_TAG; +} +#define BSL_TIME_REVOKE_TIME_IS_GMT 0x1 +int32_t HITLS_CRL_ParseCrlEntry(BSL_ASN1_Buffer *extItem, HITLS_X509_CrlEntry *crlEntry) +{ + uint8_t *temp = extItem->buff; + uint32_t tempLen = extItem->len; + BSL_ASN1_Buffer asnArr[HITLS_X509_CRLENTRY_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_crlEntryTempl, sizeof(g_crlEntryTempl) / sizeof(g_crlEntryTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, &HITLS_X509_CrlEntryChoiceCheck, + &temp, &tempLen, asnArr, HITLS_X509_CRLENTRY_MAX_IDX); + if (tempLen != 0) { + ret = HITLS_X509_ERR_CRL_ENTRY; + } + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + crlEntry->serialNumber = asnArr[HITLS_X509_CRLENTRY_NUM_IDX]; + + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CRLENTRY_TIME_IDX], &crlEntry->time); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (asnArr[HITLS_X509_CRLENTRY_TIME_IDX].tag == BSL_ASN1_TAG_GENERALIZEDTIME) { + crlEntry->flag |= BSL_TIME_REVOKE_TIME_IS_GMT; + } + // optinal + crlEntry->entryExt = asnArr[HITLS_X509_CRLENTRY_EXT_IDX]; + return ret; +} + +int32_t HITLS_CRL_ParseCrlAsnItem(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list) +{ + (void) param; + (void) layer; + HITLS_X509_CrlEntry crlEntry = {0}; + int32_t ret = HITLS_CRL_ParseCrlEntry(asn, &crlEntry); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + return HITLS_X509_AddListItemDefault(&crlEntry, sizeof(HITLS_X509_CrlEntry), list); +} + +int32_t HITLS_X509_ParseCrlList(BSL_ASN1_Buffer *crl, BSL_ASN1_List *list) +{ + // crl is optional + if (crl->tag == 0) { + return HITLS_X509_SUCCESS; + } + + uint8_t expTag = (BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE); + BSL_ASN1_DecodeListParam listParam = {1, &expTag}; + int32_t ret = BSL_ASN1_DecodeListItem(&listParam, crl, &HITLS_CRL_ParseCrlAsnItem, NULL, list); + if (ret != BSL_SUCCESS) { + BSL_LIST_DeleteAll(list, NULL); + return ret; + } + return ret; +} + +int32_t HITLS_X509_ParseCrlTbs(BSL_ASN1_Buffer *asnArr, HITLS_X509_Crl *crl) +{ + int32_t ret; + if (asnArr[HITLS_X509_CRL_VERSION_IDX].tag != 0) { + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CRL_VERSION_IDX], &crl->tbs.version); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + } else { + crl->tbs.version = 0; + } + + // sign alg + ret = HITLS_X509_ParseSignAlgInfo(&asnArr[HITLS_X509_CRL_TBS_SIGNALG_OID_IDX], + &asnArr[HITLS_X509_CRL_TBS_SIGNALG_ANY_IDX], &crl->tbs.signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // issuer name + ret = HITLS_X509_ParseNameList(&asnArr[HITLS_X509_CRL_ISSUER_IDX], crl->tbs.issuerName); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + // validity + ret = HITLS_X509_ParseTime(&asnArr[HITLS_X509_CRL_BEFORE_VALID_IDX], &asnArr[HITLS_X509_CRL_AFTER_VALID_IDX], + &crl->tbs.validTime); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + // crl list + ret = HITLS_X509_ParseCrlList(&asnArr[HITLS_X509_CRL_CRL_LIST_IDX], crl->tbs.revokedCerts); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // ext + ret = HITLS_X509_ParseCrlExt(&asnArr[HITLS_X509_CRL_EXT_IDX], crl); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + return ret; +ERR: + + BSL_LIST_DeleteAll(crl->tbs.issuerName, NULL); + BSL_LIST_DeleteAll(crl->tbs.revokedCerts, NULL); + return ret; +} + +static void X509_EncodeCrlValidTime(HITLS_X509_ValidTime *crlTime, BSL_ASN1_Buffer *validTime) +{ + validTime[0].tag = (crlTime->flag & BSL_TIME_BEFORE_IS_UTC) ? BSL_ASN1_TAG_UTCTIME : BSL_ASN1_TAG_GENERALIZEDTIME; + validTime[0].len = sizeof(BSL_TIME); + validTime[0].buff = (uint8_t *)&(crlTime->start); + + validTime[1].tag = (crlTime->flag & BSL_TIME_AFTER_IS_UTC) ? BSL_ASN1_TAG_UTCTIME : BSL_ASN1_TAG_GENERALIZEDTIME; + if (crlTime->flag & BSL_TIME_AFTER_SET) { + validTime[1].len = sizeof(BSL_TIME); + validTime[1].buff = (uint8_t *)&(crlTime->end); + } else { + validTime[1].len = 0; + validTime[1].buff = NULL; + } + return; +} + +static void X509_EncodeCrlEntry(HITLS_X509_CrlEntry *crlEntry, BSL_ASN1_Buffer *asnBuf) +{ + asnBuf[0].tag = crlEntry->serialNumber.tag; + asnBuf[0].buff = crlEntry->serialNumber.buff; + asnBuf[0].len = crlEntry->serialNumber.len; + asnBuf[1].tag = (crlEntry->flag & BSL_TIME_REVOKE_TIME_IS_GMT) ? + BSL_ASN1_TAG_GENERALIZEDTIME : BSL_ASN1_TAG_UTCTIME; + asnBuf[1].buff = (uint8_t *)&(crlEntry->time); + asnBuf[1].len = sizeof(BSL_TIME); + asnBuf[2].tag = crlEntry->entryExt.tag; // 2 : extension + asnBuf[2].buff = crlEntry->entryExt.buff; // 2 : extension + asnBuf[2].len = crlEntry->entryExt.len; // 2 : extension +} + +#define X509_CRLENTRY_ELEM_NUMBER 3 +int32_t HITLS_X509_EncodeRevokeCrlList(BSL_ASN1_List *crlList, BSL_ASN1_Buffer *revokeBuf) +{ + int32_t count = BSL_LIST_COUNT(crlList); + if (count == 0) { + revokeBuf->buff = NULL; + revokeBuf->len = 0; + revokeBuf->tag = BSL_ASN1_TAG_SEQUENCE; + return HITLS_X509_SUCCESS; + } + BSL_ASN1_Buffer *asnBuf = BSL_SAL_Malloc(count * sizeof(BSL_ASN1_Buffer) * X509_CRLENTRY_ELEM_NUMBER); + if (asnBuf == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + HITLS_X509_CrlEntry *crlEntry = NULL; + uint32_t iter = 0; + for (crlEntry = BSL_LIST_GET_FIRST(crlList); crlEntry != NULL; crlEntry = BSL_LIST_GET_NEXT(crlList)) { + X509_EncodeCrlEntry(crlEntry, &asnBuf[iter]); + iter += X509_CRLENTRY_ELEM_NUMBER; + } + BSL_ASN1_TemplateItem crlEntryTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_SAME | BSL_ASN1_FLAG_OPTIONAL, 0}, + {BSL_ASN1_TAG_INTEGER, 0, 1}, + {BSL_ASN1_TAG_CHOICE, 0, 1}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_OPTIONAL, 1} + }; + BSL_ASN1_Template templ = {crlEntryTempl, sizeof(crlEntryTempl) / sizeof(crlEntryTempl[0])}; + int32_t ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, count, &templ, asnBuf, iter, revokeBuf); + BSL_SAL_Free(asnBuf); + return ret; +} + +BSL_ASN1_TemplateItem g_crlTbsTempl[] = { + /* 1: version */ + {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_DEFAULT, 0}, + /* 2: signature info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 0}, + /* 3: issuer */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, + /* 4-5: validity */ + {BSL_ASN1_TAG_CHOICE, 0, 0}, + {BSL_ASN1_TAG_CHOICE, BSL_ASN1_FLAG_OPTIONAL, 0}, + /* 6: revoked crl list */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, + BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME | BSL_ASN1_FLAG_OPTIONAL, 0}, + /* 7: extension */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CRL_CTX_SPECIFIC_TAG_EXTENSION, + BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, // 11 +}; + +int32_t HITLS_X509_EncodeCrlExt(HITLS_X509_CrlExt *crlExt, BSL_ASN1_Buffer *ext) +{ + return HITLS_X509_EncodeExt( + BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CRL_CTX_SPECIFIC_TAG_EXTENSION, + crlExt->extList, ext); +} +/** + * RFC 5280 sec 5.1.2.1 + * This optional field describes the version of the encoded CRL. When + * extensions are used, as required by this profile, this field MUST be + * present and MUST specify version 2 (the integer value is 1). + */ +static void X509_EncodeVersion(uint8_t *version, BSL_ASN1_Buffer *asn) +{ + if (*version == 1) { + asn->tag = BSL_ASN1_TAG_INTEGER; + asn->len = 1; + asn->buff = version; + } else { + asn->tag = BSL_ASN1_TAG_INTEGER; + asn->len = 0; + asn->buff = NULL; + } +} + +#define X509_CRLTBS_ELEM_NUMBER 7 +int32_t HITLS_X509_EncodeCrlTbs(HITLS_X509_CrlTbs *crlTbs, BSL_ASN1_Buffer *asn) +{ + BSL_ASN1_Buffer asnArr[X509_CRLTBS_ELEM_NUMBER] = {0}; + BSL_ASN1_Buffer *revokeBuf = NULL; + BSL_ASN1_Buffer *crlExt = NULL; + uint8_t version = (uint8_t)crlTbs->version; + X509_EncodeVersion(&version, asnArr); + BSL_ASN1_Buffer *signAlgAsn = &asnArr[1]; + int32_t ret = HITLS_X509_EncodeSignAlgInfo(&crlTbs->signAlgId, signAlgAsn); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_ASN1_Buffer *issuerAsn = &asnArr[2]; // 2 is issuer name + ret = HITLS_X509_EncodeNameList(crlTbs->issuerName, issuerAsn); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + X509_EncodeCrlValidTime(&crlTbs->validTime, &asnArr[3]); // 3 is valid time + revokeBuf = &asnArr[5]; // 5 is revoke list + ret = HITLS_X509_EncodeRevokeCrlList(crlTbs->revokedCerts, revokeBuf); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + crlExt = &asnArr[6]; // 6 is crl extension + ret = HITLS_X509_EncodeCrlExt(&(crlTbs->crlExt), crlExt); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + BSL_ASN1_Template templ = {g_crlTbsTempl, sizeof(g_crlTbsTempl) / sizeof(g_crlTbsTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, X509_CRLTBS_ELEM_NUMBER, &(asn->buff), &(asn->len)); + if (ret != HITLS_X509_SUCCESS) { + goto EXIT; + } + asn->tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; +EXIT: + BSL_SAL_Free(signAlgAsn->buff); + BSL_SAL_Free(issuerAsn->buff); + BSL_SAL_Free(revokeBuf->buff); + BSL_SAL_Free(crlExt->buff); + return ret; +} + +#define X509_CRL_ELEM_NUMBER 3 +int32_t HITLS_X509_EncodeAsn1Crl(HITLS_X509_Crl *crl, uint8_t **encode, uint32_t *encodeLen) +{ + BSL_ASN1_Buffer asnArr[X509_CRL_ELEM_NUMBER] = {0}; + int32_t ret = HITLS_X509_EncodeCrlTbs(&crl->tbs, asnArr); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_EncodeSignAlgInfo(&crl->signAlgId, &asnArr[1]); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_Free(asnArr[0].buff); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + asnArr[2].tag = BSL_ASN1_TAG_BITSTRING; // 2 is signAlg + asnArr[2].len = sizeof(BSL_ASN1_BitString); // 2 is signAlg + asnArr[2].buff = (uint8_t *)&(crl->signature); // 2 is signAlg + BSL_ASN1_TemplateItem crlTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* x509 */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, /* tbs */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 1}, /* signAlg */ + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ + }; + BSL_ASN1_Template templ = {crlTempl, sizeof(crlTempl) / sizeof(crlTempl[0])}; + ret = BSL_ASN1_EncodeTemplate(&templ, asnArr, X509_CRL_ELEM_NUMBER, encode, encodeLen); + BSL_SAL_Free(asnArr[0].buff); + BSL_SAL_Free(asnArr[1].buff); + return ret; +} + +int32_t HITLS_X509_EncodePemCrl(HITLS_X509_Crl *crl, uint8_t **encode, uint32_t *encodeLen) +{ + uint8_t *asn1 = NULL; + uint32_t asn1Len; + int32_t ret = HITLS_X509_EncodeAsn1Crl(crl, &asn1, &asn1Len); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + BSL_PEM_Symbol symbol = {BSL_PEM_CRL_BEGIN_STR, BSL_PEM_CRL_END_STR}; + ret = BSL_PEM_EncodeAsn1ToPem(asn1, asn1Len, &symbol, (char **)encode, encodeLen); + BSL_SAL_Free(asn1); + return ret; +} + +static int32_t X509_CrlCheckValid(HITLS_X509_Crl *crl) +{ + if (crl->tbs.crlExt.extList != NULL && BSL_LIST_COUNT(crl->tbs.crlExt.extList) != 0) { + if (crl->tbs.version != 1) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CRL_INACCRACY_VERSION); + return HITLS_X509_ERR_CRL_INACCRACY_VERSION; + } + } + + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CrlGenBuff(int32_t format, HITLS_X509_Crl *crl, uint8_t **encode, uint32_t *encodeLen) +{ + if (crl == NULL || encode == NULL || encodeLen == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + int32_t ret = X509_CrlCheckValid(crl); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (format == BSL_FORMAT_PEM) { + return HITLS_X509_EncodePemCrl(crl, encode, encodeLen); + } + return HITLS_X509_EncodeAsn1Crl(crl, encode, encodeLen); +} + +int32_t HITLS_X509_CrlGenFile(int32_t format, HITLS_X509_Crl *crl, const char *path) +{ + if (path == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + uint8_t *encode = NULL; + uint32_t encodeLen; + int32_t ret = HITLS_X509_CrlGenBuff(format, crl, &encode, &encodeLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = BSL_SAL_WriteFile(path, encode, encodeLen); + BSL_SAL_Free(encode); + return ret; +} + +int32_t HITLS_X509_ParseAsn1Crl(bool isCopy, uint8_t **encode, uint32_t *encodeLen, HITLS_X509_Crl *crl) +{ + uint8_t *temp = *encode; + uint32_t tempLen = *encodeLen; + crl->isCopy = isCopy; + // template parse + BSL_ASN1_Buffer asnArr[HITLS_X509_CRL_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_crlTempl, sizeof(g_crlTempl) / sizeof(g_crlTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, HITLS_X509_CrlTagGetOrCheck, + &temp, &tempLen, asnArr, HITLS_X509_CRL_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // parse tbs raw data + ret = HITLS_X509_ParseTbsRawData(*encode, *encodeLen, &crl->tbs.tbsRawData, &crl->tbs.tbsRawDataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // parse tbs + ret = HITLS_X509_ParseCrlTbs(asnArr, crl); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + // parse sign alg + ret = HITLS_X509_ParseSignAlgInfo(&asnArr[HITLS_X509_CRL_SIGNALG_IDX], + &asnArr[HITLS_X509_CRL_SIGNALG_ANY_IDX], &crl->signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // parse signature + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CRL_SIGN_IDX], &crl->signature); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + + crl->rawData = *encode; + crl->rawDataLen = *encodeLen - tempLen; + *encode = temp; + *encodeLen = tempLen; + return HITLS_X509_SUCCESS; +ERR: + BSL_LIST_DeleteAll(crl->tbs.issuerName, NULL); + BSL_LIST_DeleteAll(crl->tbs.revokedCerts, NULL); + BSL_LIST_DeleteAll(crl->tbs.crlExt.extList, NULL); + return ret; +} + +int32_t HITLS_X509_CrlMulParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_List **crllist) +{ + if (encode == NULL || encode->data == NULL || encode->dataLen == 0 || crllist == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + X509_ParseFuncCbk crlCbk = { + (HITLS_X509_Asn1Parse)HITLS_X509_ParseAsn1Crl, + (HITLS_X509_New)HITLS_X509_CrlNew, + (HITLS_X509_Free)HITLS_X509_CrlFree, + }; + HITLS_X509_List *list = BSL_LIST_New(sizeof(HITLS_X509_Crl)); + if (list == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + int32_t ret = HITLS_X509_ParseX509(format, encode, false, &crlCbk, list); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CrlFree); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + *crllist = list; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CrlParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_Crl **crl) +{ + HITLS_X509_List *list = NULL; + if (crl == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + int32_t ret = HITLS_X509_CrlMulParseBuff(format, encode, &list); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + HITLS_X509_Crl *tmp = BSL_LIST_GET_FIRST(list); + int ref; + ret = HITLS_X509_CrlCtrl(tmp, HITLS_X509_CRL_REF_UP, &ref, sizeof(int)); + BSL_LIST_FREE(list, (BSL_LIST_PFUNC_FREE)HITLS_X509_CrlFree); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + *crl = tmp; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CrlParseFile(int32_t format, const char *path, HITLS_X509_Crl **crl) +{ + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + return ret; + } + + BSL_Buffer encode = {data, dataLen}; + ret = HITLS_X509_CrlParseBuff(format, &encode, crl); + BSL_SAL_Free(data); + return ret; +} + +int32_t HITLS_X509_CrlMulParseFile(int32_t format, const char *path, HITLS_X509_List **crllist) +{ + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + return ret; + } + + BSL_Buffer encode = {data, dataLen}; + ret = HITLS_X509_CrlMulParseBuff(format, &encode, crllist); + BSL_SAL_Free(data); + return ret; +} + +static int32_t X509_CrlRefUp(HITLS_X509_Crl *crl, int32_t *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + return BSL_SAL_AtomicUpReferences(&crl->references, val); +} + +int32_t HITLS_X509_CrlCtrl(HITLS_X509_Crl *crl, int32_t cmd, void *val, int32_t valLen) +{ + if (crl == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + switch (cmd) { + case HITLS_X509_CRL_REF_UP: + return X509_CrlRefUp(crl, val, valLen); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} \ No newline at end of file diff --git a/x509/x509_csr/include/hitls_csr_local.h b/x509/x509_csr/include/hitls_csr_local.h new file mode 100644 index 00000000..70eebe97 --- /dev/null +++ b/x509/x509_csr/include/hitls_csr_local.h @@ -0,0 +1,56 @@ +/* + * 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_CSR_LOCAL_H +#define HITLS_CSR_LOCAL_H + +#include +#include "bsl_asn1.h" +#include "bsl_obj.h" +#include "sal_atomic.h" +#include "hitls_x509_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _HITLS_X509_ReqInfo { + uint8_t *reqInfoRawData; + uint32_t reqInfoRawDataLen; + int32_t version; + BSL_ASN1_List *subjectName; /* Entry is HITLS_X509_NameNode */ + void *ealPubKey; + BSL_ASN1_List *attributes; +} HITLS_X509_ReqInfo; + +/* PKCS #10 */ +typedef struct _HITLS_X509_Csr { + int8_t flag; // Used to mark csr parsing or generation, indicating resource release behavior. + uint8_t *rawData; + uint32_t rawDataLen; + void *ealPrivKey; // used to sign csr + CRYPT_MD_AlgId signMdId; + + HITLS_X509_ReqInfo reqInfo; + HITLS_X509_Asn1AlgId signAlgId; + BSL_ASN1_BitString signature; + BSL_SAL_RefCount references; +} HITLS_X509_Csr; + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_CSR_LOCAL_H \ No newline at end of file diff --git a/x509/x509_csr/src/hitls_x509_csr.c b/x509/x509_csr/src/hitls_x509_csr.c new file mode 100644 index 00000000..d253e14a --- /dev/null +++ b/x509/x509_csr/src/hitls_x509_csr.c @@ -0,0 +1,686 @@ +/* + * 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_x509.h" +#include "securec.h" +#include "bsl_sal.h" +#include "bsl_asn1.h" +#include "bsl_binlog_id.h" +#include "bsl_obj_internal.h" +#include "bsl_err_internal.h" +#include "bsl_pem_internal.h" +#include "bsl_log_internal.h" +#include "hitls_x509_errno.h" +#include "crypt_encode.h" +#include "crypt_errno.h" +#include "sal_file.h" +#include "crypt_eal_encode.h" +#include "hitls_csr_local.h" + +#define HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE 0 + +#define HITLS_X509_CSR_PARSE_FLAG 0x01 +#define HITLS_X509_CSR_GEN_FLAG 0x02 +/** + * RFC2986: section 4 + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + * signature BIT STRING + * } + */ +BSL_ASN1_TemplateItem g_csrTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* PKCS10 csr */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* req info */ + /* 2: version */ + {BSL_ASN1_TAG_INTEGER, 0, 2}, + /* 2: subject name */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + /* 2: public key info */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 2}, + /* 2: attributes */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE, + BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2}, + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */ + {BSL_ASN1_TAG_OBJECT_ID, 0, 2}, + {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2}, + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ +}; + +typedef enum { + HITLS_X509_CSR_REQINFO_VERSION_IDX = 0, + HITLS_X509_CSR_REQINFO_SUBJECT_NAME_IDX = 1, + HITLS_X509_CSR_REQINFO_PUBKEY_INFO_IDX = 2, + HITLS_X509_CSR_REQINFO_ATTRS_IDX = 3, + HITLS_X509_CSR_SIGNALG_OID_IDX = 4, + HITLS_X509_CSR_SIGNALG_ANY_IDX = 5, + HITLS_X509_CSR_SIGN_IDX = 6, + HITLS_X509_CSR_MAX_IDX = 7, +} HITLS_X509_CSR_IDX; + +HITLS_X509_Csr *HITLS_X509_CsrNew(void) +{ + HITLS_X509_Csr *csr = NULL; + BSL_ASN1_List *subjectName = NULL; + BSL_ASN1_List *attributes = NULL; + csr = (HITLS_X509_Csr *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Csr)); + if (csr == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return NULL; + } + + subjectName = BSL_LIST_New(sizeof(HITLS_X509_NameNode)); + if (subjectName == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + goto ERR; + } + attributes = BSL_LIST_New(sizeof(HITLS_X509_AttrEntry)); + if (attributes == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + goto ERR; + } + BSL_SAL_ReferencesInit(&(csr->references)); + csr->reqInfo.subjectName = subjectName; + csr->reqInfo.attributes = attributes; + csr->flag = HITLS_X509_CSR_GEN_FLAG; + return csr; +ERR: + BSL_SAL_FREE(subjectName); + BSL_SAL_FREE(attributes); + BSL_SAL_FREE(csr); + return NULL; +} + +void HITLS_X509_CsrFree(HITLS_X509_Csr *csr) +{ + if (csr == NULL) { + return; + } + int ret = 0; + BSL_SAL_AtomicDownReferences(&(csr->references), &ret); + if (ret > 0) { + return; + } + if (csr->flag == HITLS_X509_CSR_GEN_FLAG) { + BSL_LIST_FREE(csr->reqInfo.subjectName, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode); + BSL_LIST_FREE(csr->reqInfo.attributes, (BSL_LIST_PFUNC_FREE)HITLS_X509_AttrEntryFree); + BSL_SAL_FREE(csr->reqInfo.reqInfoRawData); + BSL_SAL_FREE(csr->signature.buff); + } else { + BSL_LIST_FREE(csr->reqInfo.subjectName, NULL); + BSL_LIST_FREE(csr->reqInfo.attributes, NULL); + } + BSL_SAL_FREE(csr->rawData); + CRYPT_EAL_PkeyFreeCtx(csr->reqInfo.ealPubKey); + csr->reqInfo.ealPubKey = NULL; + + CRYPT_EAL_PkeyFreeCtx(csr->ealPrivKey); + csr->ealPrivKey = NULL; + BSL_SAL_FREE(csr); +} + +int32_t HITLS_X509_CsrTagGetOrCheck(int32_t type, int32_t idx, void *data, void *expVal) +{ + (void)idx; + if (type == BSL_ASN1_TYPE_GET_ANY_TAG) { + BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data; + BslOidString oidStr = {param->len, (char *)param->buff, 0}; + BslCid cid = BSL_OBJ_GetCIDFromOid(&oidStr); + if (cid == BSL_CID_UNKNOWN) { + return HITLS_X509_ERR_GET_ANY_TAG; + } + if (cid == BSL_CID_RSASSAPSS) { + /* note: any It can be encoded empty or it can be null */ + *(uint8_t *)expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE; + return BSL_SUCCESS; + } else { + *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null + return BSL_SUCCESS; + } + } + + return HITLS_X509_ERR_INVALID_PARAM; +} + +static int32_t ParseCertRequestInfo(BSL_ASN1_Buffer *asnArr, HITLS_X509_Csr *csr) +{ + int32_t ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CSR_REQINFO_VERSION_IDX], &csr->reqInfo.version); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* subject name */ + ret = HITLS_X509_ParseNameList(&asnArr[HITLS_X509_CSR_REQINFO_SUBJECT_NAME_IDX], csr->reqInfo.subjectName); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* public key info */ + ret = CRYPT_EAL_ParseAsn1SubPubkey(asnArr[HITLS_X509_CSR_REQINFO_PUBKEY_INFO_IDX].buff, + asnArr[HITLS_X509_CSR_REQINFO_PUBKEY_INFO_IDX].len, &csr->reqInfo.ealPubKey, false); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + /* attributes */ + ret = HITLS_X509_ParseAttrList(&asnArr[HITLS_X509_CSR_REQINFO_ATTRS_IDX], csr->reqInfo.attributes); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + return ret; + +ERR: + if (csr->reqInfo.ealPubKey != NULL) { + CRYPT_EAL_PkeyFreeCtx(csr->reqInfo.ealPubKey); + csr->reqInfo.ealPubKey = NULL; + } + BSL_LIST_FREE(csr->reqInfo.subjectName, NULL); + return ret; +} + +static int32_t X509CsrBuffAsn1Parse(uint8_t **encode, uint32_t *encodeLen, HITLS_X509_Csr *csr) +{ + uint8_t *temp = *encode; + uint32_t tempLen = *encodeLen; + // template parse + BSL_ASN1_Buffer asnArr[HITLS_X509_CSR_MAX_IDX] = {0}; + BSL_ASN1_Template templ = {g_csrTempl, sizeof(g_csrTempl) / sizeof(g_csrTempl[0])}; + int32_t ret = BSL_ASN1_DecodeTemplate(&templ, HITLS_X509_CsrTagGetOrCheck, + &temp, &tempLen, asnArr, HITLS_X509_CSR_MAX_IDX); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + // parse reqInfo raw data + ret = HITLS_X509_ParseTbsRawData(*encode, *encodeLen, &csr->reqInfo.reqInfoRawData, + &csr->reqInfo.reqInfoRawDataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // parse reqInfo + ret = ParseCertRequestInfo(asnArr, csr); + if (ret != HITLS_X509_SUCCESS) { + goto ERR; + } + // parse sign alg + ret = HITLS_X509_ParseSignAlgInfo(&asnArr[HITLS_X509_CSR_SIGNALG_OID_IDX], + &asnArr[HITLS_X509_CSR_SIGNALG_ANY_IDX], &csr->signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + // parse signature + ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CSR_SIGN_IDX], &csr->signature); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto ERR; + } + csr->rawData = *encode; + csr->rawDataLen = *encodeLen - tempLen; + *encode = temp; + *encodeLen = tempLen; + return HITLS_X509_SUCCESS; +ERR: + BSL_LIST_FREE(csr->reqInfo.attributes, NULL); + BSL_LIST_FREE(csr->reqInfo.subjectName, NULL); + if (csr->reqInfo.ealPubKey != NULL) { + CRYPT_EAL_PkeyFreeCtx(csr->reqInfo.ealPubKey); + csr->reqInfo.ealPubKey = NULL; + } + return ret; +} + +static int32_t X509CsrAsn1Parse(bool isCopy, BSL_Buffer *encode, HITLS_X509_Csr *csr) +{ + uint8_t *data = encode->data; + uint32_t dataLen = encode->dataLen; + BSL_Buffer asn1Buff = {data, dataLen}; + if (isCopy) { + csr->flag = HITLS_X509_CSR_PARSE_FLAG; + asn1Buff.data = (uint8_t *)BSL_SAL_Dump(data, dataLen); + if (asn1Buff.data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + } + int32_t ret = X509CsrBuffAsn1Parse(&asn1Buff.data, &asn1Buff.dataLen, csr); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(asn1Buff.data); + } + return ret; +} + +static int32_t X509CsrPemParse(BSL_Buffer *encode, HITLS_X509_Csr *csr) +{ + uint8_t *tmpBuf = encode->data; + uint32_t tmpBufLen = encode->dataLen; + BSL_Buffer asn1Buf = {NULL, 0}; + BSL_PEM_Symbol symbol = {BSL_PEM_CERT_REQ_BEGIN_STR, BSL_PEM_CERT_REQ_END_STR}; + int32_t ret = BSL_PEM_ParsePem2Asn1((char **)&tmpBuf, &tmpBufLen, &symbol, &asn1Buf.data, + &asn1Buf.dataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = X509CsrAsn1Parse(true, &asn1Buf, csr); + BSL_SAL_FREE(asn1Buf.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + return ret; +} + +int32_t HITLS_X509_CsrParseBuff(int32_t format, BSL_Buffer *encode, HITLS_X509_Csr **csr) +{ + if (encode == NULL || csr == NULL || encode->data == NULL || encode->dataLen == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + int32_t ret; + HITLS_X509_Csr *tempCsr = HITLS_X509_CsrNew(); + if (tempCsr == NULL) { + BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL); + return BSL_MALLOC_FAIL; + } + switch (format) { + case BSL_FORMAT_ASN1: + ret = X509CsrAsn1Parse(true, encode, tempCsr); + break; + case BSL_FORMAT_PEM: + ret = X509CsrPemParse(encode, tempCsr); + break; + default: + ret = HITLS_X509_ERR_NOT_SUPPORT_FORMAT; + break; + } + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + HITLS_X509_CsrFree(tempCsr); + return ret; + } + + *csr = tempCsr; + return ret; +} + +int32_t HITLS_X509_CsrParseFile(int32_t format, const char *path, HITLS_X509_Csr **csr) +{ + if (path == NULL || csr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + uint8_t *data = NULL; + uint32_t dataLen = 0; + int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer encode = {data, dataLen}; + ret = HITLS_X509_CsrParseBuff(format, &encode, csr); + BSL_SAL_Free(data); + return ret; +} + +static int32_t CheckCsrValid(HITLS_X509_Csr *csr) +{ + if (csr->reqInfo.version != HITLS_CSR_VERSION) { + return HITLS_X509_ERR_CSR_INVALID_VERSION; + } + if (csr->reqInfo.ealPubKey == NULL) { + return HITLS_X509_ERR_CSR_INVALID_PUBKEY; + } + if (csr->reqInfo.subjectName == NULL || BSL_LIST_COUNT(csr->reqInfo.subjectName) == 0) { + return HITLS_X509_ERR_CSR_INVALID_SUBJECT_DN; + } + if (csr->reqInfo.attributes == NULL) { + return HITLS_X509_ERR_CSR_INVALID_ATTR; + } + // when generating csr, the private key or the signature must be set. + if (csr->ealPrivKey == NULL && csr->signature.buff == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + return HITLS_X509_SUCCESS; +} + +static int32_t EncodeCsrReqInfoItem(HITLS_X509_ReqInfo *reqInfo, BSL_ASN1_Buffer *subject, + BSL_ASN1_Buffer *publicKey, BSL_ASN1_Buffer *attributes) +{ + /* encode subject name */ + int32_t ret = HITLS_X509_EncodeNameList(reqInfo->subjectName, subject); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* encode public key */ + BSL_Buffer pub = {0}; + ret = CRYPT_EAL_EncodePubKeyBuffInternal(reqInfo->ealPubKey, BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY, + false, &pub); + if (ret != CRYPT_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + + /* encode attribute */ + ret = HITLS_X509_EncodeAttrList( + BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE, + reqInfo->attributes, attributes); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + + publicKey->buff = pub.data; + publicKey->len = pub.dataLen; + return ret; +EXIT: + BSL_SAL_FREE(subject->buff); + BSL_SAL_FREE(pub.data); + BSL_SAL_FREE(attributes->buff); + return ret; +} + +static BSL_ASN1_TemplateItem g_reqInfoTempl[] = { + /* version */ + {BSL_ASN1_TAG_INTEGER, 0, 0}, + /* subject name */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, + /* public key */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 0}, + /* attributes */ + {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE, + BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0}, +}; + +#define HITLS_X509_CSR_REQINFO_SIZE 4 + +static int32_t EncodeCsrReqInfo(HITLS_X509_ReqInfo *reqInfo, BSL_ASN1_Buffer *reqInfoBuff) +{ + BSL_ASN1_Buffer subject = {0, 0, NULL}; + BSL_ASN1_Buffer publicKey = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}; + BSL_ASN1_Buffer attributes = {0, 0, NULL}; + int ret = EncodeCsrReqInfoItem(reqInfo, &subject, &publicKey, &attributes); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + uint8_t version = reqInfo->version; + BSL_ASN1_Template templ = { g_reqInfoTempl, sizeof(g_reqInfoTempl) / sizeof(g_reqInfoTempl[0]) }; + BSL_ASN1_Buffer reqInfoAsn[HITLS_X509_CSR_REQINFO_SIZE] = { + {BSL_ASN1_TAG_INTEGER, 1, &version}, + subject, + publicKey, + attributes + }; + ret = BSL_ASN1_EncodeTemplate(&templ, reqInfoAsn, HITLS_X509_CSR_REQINFO_SIZE, &reqInfoBuff->buff, + &reqInfoBuff->len); + BSL_SAL_FREE(subject.buff); + BSL_SAL_FREE(publicKey.buff); + BSL_SAL_FREE(attributes.buff); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + return ret; +} + +static int32_t SignCsrReqInfo(HITLS_X509_Csr *csr, BSL_ASN1_Buffer *reqInfo, BSL_ASN1_BitString *signBs) +{ + BSL_Buffer rawSignBuff = {NULL, 0}; + int32_t ret = CRYPT_EAL_PkeyPairCheck((CRYPT_EAL_PkeyCtx *)csr->reqInfo.ealPubKey, + (CRYPT_EAL_PkeyCtx *)csr->ealPrivKey); + if (ret != CRYPT_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05067, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "csr: private key and public key don't match .", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = HITLS_X509_SignAsn1Data(csr->ealPrivKey, csr->signMdId, reqInfo, &rawSignBuff, signBs); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05068, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "csr: failed to sign the csr.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + csr->reqInfo.reqInfoRawData = rawSignBuff.data; + csr->reqInfo.reqInfoRawDataLen = rawSignBuff.dataLen; + return ret; +} + +BSL_ASN1_TemplateItem g_briefCsrTempl[] = { + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* pkcs10 csr */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* reqInfo */ + {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */ + {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */ +}; + +#define HITLS_X509_CSR_BRIEF_SIZE 3 + +static int32_t X509EncodeAsn1CsrCore(HITLS_X509_Csr *csr, BSL_Buffer *buff) +{ + BSL_ASN1_Buffer reqInfo = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}; + BSL_ASN1_Buffer signAlg = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL}; + /* encode csr request info */ + int32_t ret = EncodeCsrReqInfo(&csr->reqInfo, &reqInfo); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + /* encode csr sign alg */ + ret = HITLS_X509_SetSignAlgInfo(csr->ealPrivKey, csr->signMdId, &csr->signAlgId); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + + ret = HITLS_X509_EncodeSignAlgInfo(&csr->signAlgId, &signAlg); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + goto EXIT; + } + + ret = SignCsrReqInfo(csr, &reqInfo, &csr->signature); + if (ret != HITLS_X509_SUCCESS) { + goto EXIT; + } + + BSL_ASN1_Buffer csrAsn1Buff[HITLS_X509_CSR_BRIEF_SIZE] = { + reqInfo, + signAlg, + {BSL_ASN1_TAG_BITSTRING, sizeof(BSL_ASN1_BitString), (uint8_t *)&csr->signature} + }; + BSL_ASN1_Template csrTempl = { g_briefCsrTempl, sizeof(g_briefCsrTempl) / sizeof(g_briefCsrTempl[0]) }; + ret = BSL_ASN1_EncodeTemplate(&csrTempl, csrAsn1Buff, HITLS_X509_CSR_BRIEF_SIZE, &buff->data, &buff->dataLen); + if (ret != HITLS_X509_SUCCESS) { + BSL_SAL_FREE(csr->reqInfo.reqInfoRawData); + BSL_SAL_FREE(csr->signature.buff); + } + +EXIT: + BSL_SAL_FREE(reqInfo.buff); + BSL_SAL_FREE(signAlg.buff); + return ret; +} + +static int32_t X509EncodeAsn1Csr(HITLS_X509_Csr *csr, BSL_Buffer *buff) +{ + /* Encoded after decoding. */ + if (csr->rawData != NULL && csr->rawDataLen != 0) { + buff->data = BSL_SAL_Dump(csr->rawData, csr->rawDataLen); + if (buff->data == NULL) { + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + buff->dataLen = csr->rawDataLen; + return HITLS_X509_SUCCESS; + } + + /* Generate a new csr. */ + int32_t ret = CheckCsrValid(csr); + if (ret != HITLS_X509_SUCCESS) { + BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05066, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, + "csr: encode csr failed due to invalid parameters.", 0, 0, 0, 0); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = X509EncodeAsn1CsrCore(csr, buff); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + csr->rawData = BSL_SAL_Dump(buff->data, buff->dataLen); + if (buff->data == NULL) { + BSL_SAL_FREE(buff->data); + BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL); + return BSL_DUMP_FAIL; + } + csr->rawDataLen = buff->dataLen; + return ret; +} + +static int32_t X509EncodePemCsr(HITLS_X509_Csr *csr, BSL_Buffer *buff) +{ + BSL_Buffer asn1 = {0}; + int32_t ret = X509EncodeAsn1Csr(csr, &asn1); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + BSL_Buffer base64 = {0}; + BSL_PEM_Symbol symbol = {BSL_PEM_CERT_REQ_BEGIN_STR, BSL_PEM_CERT_REQ_END_STR}; + ret = BSL_PEM_EncodeAsn1ToPem(asn1.data, asn1.dataLen, &symbol, (char **)&base64.data, &base64.dataLen); + BSL_SAL_FREE(asn1.data); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + buff->data = base64.data; + buff->dataLen = base64.dataLen; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CsrGenBuff(HITLS_X509_Csr *csr, int32_t format, BSL_Buffer *buff) +{ + if (csr == NULL || buff == NULL || buff->data != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + switch (format) { + case BSL_FORMAT_ASN1: + return X509EncodeAsn1Csr(csr, buff); + case BSL_FORMAT_PEM: + return X509EncodePemCsr(csr, buff); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_NOT_SUPPORT_FORMAT); + return HITLS_X509_ERR_NOT_SUPPORT_FORMAT; + } +} + +int32_t HITLS_X509_CsrGenFile(HITLS_X509_Csr *csr, int32_t format, const char *path) +{ + if (path == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + BSL_Buffer encode = { NULL, 0}; + int32_t ret = HITLS_X509_CsrGenBuff(csr, format, &encode); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + + ret = BSL_SAL_WriteFile(path, encode.data, encode.dataLen); + BSL_SAL_Free(encode.data); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + return ret; +} + +int32_t HITLS_X509_CsrCtrl(HITLS_X509_Csr *csr, int32_t cmd, void *val, int32_t valLen) +{ + if (csr == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + if (csr->flag == HITLS_X509_CSR_PARSE_FLAG && cmd >= HITLS_X509_SET_VERSION + && cmd < HITLS_X509_EXT_KU_KEYENC) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_AFTER_PARSE); + return HITLS_X509_ERR_SET_AFTER_PARSE; + } + + switch (cmd) { + case HITLS_X509_REF_UP: + return HITLS_X509_RefUp(&csr->references, val, valLen); + case HITLS_X509_SET_PUBKEY: + return HITLS_X509_SetPkey(&csr->reqInfo.ealPubKey, val); + case HITLS_X509_SET_PRIVKEY: + return HITLS_X509_SetPkey(&csr->ealPrivKey, val); + case HITLS_X509_SET_SIGN_MD_ID: + return HITLS_X509_SetSignMdId(&csr->signMdId, val, valLen); + case HITLS_X509_SET_SIGN_RSA_PSS_PARAM: + return HITLS_X509_SetRsaPssPara(csr->ealPrivKey, val, valLen); + case HITLS_X509_SET_SIGN_RSA_PADDING: + return HITLS_X509_SetRsaPadding(csr->ealPrivKey, val, valLen); + case HITLS_X509_ADD_SUBJECT_NAME: + return HITLS_X509_AddDnName(csr->reqInfo.subjectName, (HITLS_X509_DN *)val, valLen); + case HITLS_X509_GET_ENCODELEN: + return HITLS_X509_GetEncodeLen(csr->rawDataLen, val, valLen); + case HITLS_X509_GET_ENCODE: + return HITLS_X509_GetEncodeData(csr->rawData, val); + case HITLS_X509_GET_PUBKEY: + return HITLS_X509_GetPubKey(csr->reqInfo.ealPubKey, val); + case HITLS_X509_GET_SIGNALG: + return HITLS_X509_GetSignAlg(csr->signAlgId.algId, (int32_t *)val, valLen); + case HITLS_X509_GET_SUBJECT_DNNAME: + return HITLS_X509_GetList(csr->reqInfo.subjectName, val, valLen); + case HITLS_X509_CSR_GET_ATTRIBUTES: + return HITLS_X509_GetList(csr->reqInfo.attributes, val, valLen); + default: + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } +} + +int32_t HITLS_X509_CsrVerify(HITLS_X509_Csr *csr) +{ + if (csr == NULL || csr->reqInfo.ealPubKey == NULL || csr->reqInfo.reqInfoRawData == NULL || + csr->signature.buff == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + + int32_t ret = HITLS_X509_CheckSignature((const CRYPT_EAL_PkeyCtx *)csr->reqInfo.ealPubKey, + csr->reqInfo.reqInfoRawData, csr->reqInfo.reqInfoRawDataLen, &csr->signAlgId, &csr->signature); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + } + + return ret; +} diff --git a/x509/x509_verify/include/hitls_x509_verify.h b/x509/x509_verify/include/hitls_x509_verify.h new file mode 100644 index 00000000..32cd60b9 --- /dev/null +++ b/x509/x509_verify/include/hitls_x509_verify.h @@ -0,0 +1,60 @@ +/* + * 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_X509_VERIFY_H +#define HITLS_X509_VERIFY_H + +#include +#include "bsl_asn1.h" +#include "hitls_x509.h" +#include "sal_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + HITLS_X509_VFY_FLAG_SECBITS = 0x100000000, + HITLS_X509_VFY_FLAG_TIME = 0x200000000, +} HITLS_X509_IN_VerifyFalg; + +typedef struct _HITLS_X509_VerifyParam { + int32_t maxDepth; + int64_t time; + uint32_t securityBits; + uint64_t flags; +} HITLS_X509_VerifyParam; + +struct _HITLS_X509_StoreCtx { + HITLS_X509_List *store; + HITLS_X509_List *crl; + BSL_SAL_RefCount references; + HITLS_X509_VerifyParam verifyParam; +}; + + +int32_t HITLS_X509_VerifyParamAndExt(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain); + +/* + * Verify the CRL, which is the default full certificate chain validation. + * You can configure not to verify or only verify the terminal certificate + */ +int32_t HITLS_X509_CrlVerify(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain); + +#ifdef __cplusplus +} +#endif + +#endif // HITLS_X509_VERIFY_H \ No newline at end of file diff --git a/x509/x509_verify/src/hitls_x509_verify.c b/x509/x509_verify/src/hitls_x509_verify.c new file mode 100644 index 00000000..92060700 --- /dev/null +++ b/x509/x509_verify/src/hitls_x509_verify.c @@ -0,0 +1,727 @@ +/* + * 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 +#include "securec.h" +#include "hitls_x509.h" +#include "hitls_error.h" +#include "sal_atomic.h" +#include "crypt_eal_pkey.h" +#include "bsl_err_internal.h" +#include "hitls_crl_local.h" +#include "hitls_cert_local.h" +#include "hitls_x509_local.h" +#include "bsl_obj_internal.h" +#include "hitls_x509_errno.h" +#include "crypt_errno.h" +#include "bsl_list.h" +#include "bsl_list_internal.h" +#include "hitls_x509_verify.h" + +typedef int32_t (*HITLS_X509_TrvListCallBack)(void *ctx, void *node); +typedef int32_t (*HITLS_X509_TrvListWithParentCallBack)(void *ctx, void *node, void *parent); + +// lists can be cert, ext, and so on. +static int32_t HITLS_X509_TrvList(BslList *list, HITLS_X509_TrvListCallBack callBack, void *ctx) +{ + int32_t ret = HITLS_X509_SUCCESS; + void *node = BSL_LIST_GET_FIRST(list); + while (node != NULL) { + ret = callBack(ctx, node); + if (ret != BSL_SUCCESS) { + return ret; + } + node = BSL_LIST_GET_NEXT(list); + } + return ret; +} + +// lists can be cert, ext, and so on. +static int32_t HITLS_X509_TrvListWithParent(BslList *list, HITLS_X509_TrvListWithParentCallBack callBack, void *ctx) +{ + int32_t ret = HITLS_X509_SUCCESS; + void *node = BSL_LIST_GET_FIRST(list); + void *parentNode = BSL_LIST_GET_NEXT(list); + while (node != NULL && parentNode != NULL) { + ret = callBack(ctx, node, parentNode); + if (ret != BSL_SUCCESS) { + return ret; + } + node = parentNode; + parentNode = BSL_LIST_GET_NEXT(list); + } + return ret; +} + +#define HITLS_X509_MAX_DEPTH 20 + +void HITLS_X509_StoreCtxFree(HITLS_X509_StoreCtx *ctx) +{ + if (ctx == NULL) { + return; + } + int ret; + (void)BSL_SAL_AtomicDownReferences(&ctx->references, &ret); + if (ret > 0) { + return; + } + if (ctx->store != NULL) { + BSL_LIST_FREE(ctx->store, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + } + if (ctx->crl != NULL) { + BSL_LIST_FREE(ctx->crl, (BSL_LIST_PFUNC_FREE)HITLS_X509_CrlFree); + } + BSL_SAL_ReferencesFree(&ctx->references); + BSL_SAL_Free(ctx); +} + +static int32_t X509_CrlCmp(HITLS_X509_Crl *crlOri, HITLS_X509_Crl *crl) +{ + if (crlOri == crl) { + return 0; + } + if (HITLS_X509_CmpNameNode(crlOri->tbs.issuerName, crl->tbs.issuerName) != 0) { + return 1; + } + if (crlOri->tbs.tbsRawDataLen != crl->tbs.tbsRawDataLen) { + return 1; + } + return memcmp(crlOri->tbs.tbsRawData, crl->tbs.tbsRawData, crl->tbs.tbsRawDataLen); +} + +static int32_t X509_CertCmp(HITLS_X509_Cert *certOri, HITLS_X509_Cert *cert) +{ + if (certOri == cert) { + return 0; + } + if (HITLS_X509_CmpNameNode(certOri->tbs.subjectName, cert->tbs.subjectName) != 0) { + return 1; + } + if (certOri->tbs.tbsRawDataLen != cert->tbs.tbsRawDataLen) { + return 1; + } + return memcmp(certOri->tbs.tbsRawData, cert->tbs.tbsRawData, cert->tbs.tbsRawDataLen); +} + +HITLS_X509_StoreCtx *HITLS_X509_StoreCtxNew(void) +{ + HITLS_X509_StoreCtx *ctx = (HITLS_X509_StoreCtx *)BSL_SAL_Malloc(sizeof(HITLS_X509_StoreCtx)); + if (ctx == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + + (void)memset_s(ctx, sizeof(HITLS_X509_StoreCtx), 0, sizeof(HITLS_X509_StoreCtx)); + ctx->store = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + if (ctx->store == NULL) { + BSL_SAL_Free(ctx); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + ctx->crl = BSL_LIST_New(sizeof(HITLS_X509_Crl *)); + if (ctx->crl == NULL) { + BSL_SAL_FREE(ctx->store); + BSL_SAL_Free(ctx); + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + + ctx->verifyParam.maxDepth = HITLS_X509_MAX_DEPTH; + ctx->verifyParam.securityBits = 128; // 128: The default number of secure bits. + BSL_SAL_ReferencesInit(&(ctx->references)); + return ctx; +} + +static int32_t X509_SetMaxDepth(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + int32_t depth = *(int32_t *)val; + if (depth > HITLS_X509_MAX_DEPTH) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM); + return HITLS_X509_ERR_INVALID_PARAM; + } + storeCtx->verifyParam.maxDepth = depth; + return HITLS_SUCCESS; +} + +static int32_t X509_SetParamFlag(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int64_t)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + storeCtx->verifyParam.flags |= *(int64_t *)val; + return HITLS_SUCCESS; +} + +static int32_t X509_SetVerifyTime(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int64_t)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + storeCtx->verifyParam.time |= *(int64_t *)val; + storeCtx->verifyParam.flags |= HITLS_X509_VFY_FLAG_TIME; + return HITLS_SUCCESS; +} + +static int32_t X509_SetVerifySecurityBits(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(uint32_t)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + storeCtx->verifyParam.securityBits = *(uint32_t *)val; + storeCtx->verifyParam.flags |= HITLS_X509_VFY_FLAG_SECBITS; + return HITLS_SUCCESS; +} + +static int32_t X509_ClearParamFlag(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int64_t)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + storeCtx->verifyParam.flags &= ~(*(int64_t *)val); + return HITLS_SUCCESS; +} + +static int32_t X509_CheckCert(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert) +{ + bool res = false; + int32_t ret = HITLS_X509_CertIsCA(cert, &res); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (!res) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_NOT_CA); + return HITLS_X509_ERR_CERT_NOT_CA; + } + HITLS_X509_List *certStore = storeCtx->store; + HITLS_X509_Cert * tmp = BSL_LIST_SearchEx(certStore, cert, (BSL_LIST_PFUNC_CMP)X509_CertCmp); + if (tmp != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_EXIST); + return HITLS_X509_ERR_CERT_EXIST; + } + + return HITLS_X509_SUCCESS; +} + +static int32_t X509_SetCA(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen, bool isCopy) +{ + if (val == NULL || valLen != sizeof(HITLS_X509_Cert)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + int32_t ret = X509_CheckCert(storeCtx, val); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + if (isCopy) { + int ref; + ret = HITLS_X509_CertCtrl(val, HITLS_X509_REF_UP, &ref, sizeof(int)); + if (ret != HITLS_SUCCESS) { + return ret; + } + } + + ret = BSL_LIST_AddElement(storeCtx->store, val, BSL_LIST_POS_BEFORE); + if (ret != HITLS_SUCCESS) { + if (isCopy) { + HITLS_X509_CertFree(val); + } + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +static int32_t X509_CheckCRL(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Crl *crl) +{ + HITLS_X509_List *crlStore = storeCtx->crl; + HITLS_X509_Crl *tmp = BSL_LIST_SearchEx(crlStore, crl, (BSL_LIST_PFUNC_CMP)X509_CrlCmp); + if (tmp != NULL) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CRL_EXIST); + return HITLS_X509_ERR_CRL_EXIST; + } + + return HITLS_X509_SUCCESS; +} + +static int32_t X509_SetCRL(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(HITLS_X509_Crl)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + int32_t ret = X509_CheckCRL(storeCtx, val); + if (ret != HITLS_SUCCESS) { + return ret; + } + int ref; + ret = HITLS_X509_CrlCtrl(val, HITLS_X509_CRL_REF_UP, &ref, sizeof(int)); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = BSL_LIST_AddElement(storeCtx->crl, val, BSL_LIST_POS_BEFORE); + if (ret != HITLS_SUCCESS) { + HITLS_X509_CrlFree(val); + BSL_ERR_PUSH_ERROR(ret); + } + return ret; +} + +static int32_t X509_RefUp(HITLS_X509_StoreCtx *storeCtx, void *val, int32_t valLen) +{ + if (val == NULL || valLen != sizeof(int)) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + + return BSL_SAL_AtomicUpReferences(&storeCtx->references, val); +} + +int32_t HITLS_X509_StoreCtxCtrl(HITLS_X509_StoreCtx *storeCtx, int32_t cmd, void *val, int32_t valLen) +{ + if (storeCtx == NULL || cmd < HITLS_X509_STORECTX_SET_PARAM_DEPTH || cmd >= HITLS_X509_STORECTX_MAX) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + switch (cmd) { + case HITLS_X509_STORECTX_SET_PARAM_DEPTH: + return X509_SetMaxDepth(storeCtx, val, valLen); + case HITLS_X509_STORECTX_SET_PARAM_FLAGS: + return X509_SetParamFlag(storeCtx, val, valLen); + case HITLS_X509_STORECTX_SET_TIME: + return X509_SetVerifyTime(storeCtx, val, valLen); + case HITLS_X509_STORECTX_SET_SECBITS: + return X509_SetVerifySecurityBits(storeCtx, val, valLen); + case HITLS_X509_STORECTX_CLR_PARAM_FLAGS: + return X509_ClearParamFlag(storeCtx, val, valLen); + case HITLS_X509_STORECTX_DEEP_COPY_SET_CA: + return X509_SetCA(storeCtx, val, valLen, true); + case HITLS_X509_STORECTX_SHALLOW_COPY_SET_CA: + return X509_SetCA(storeCtx, val, valLen, false); + case HITLS_X509_STORECTX_SET_CRL: + return X509_SetCRL(storeCtx, val, valLen); + case HITLS_X509_STORECTX_REF_UP: + return X509_RefUp(storeCtx, val, valLen); + default: + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } +} + +static int32_t X509_SelfSigned(HITLS_X509_Cert *cert, bool *selfSigned) +{ + int32_t ret = HITLS_X509_CheckIssued(cert, cert, selfSigned); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CheckTime(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_ValidTime *validTime) +{ + int64_t start = 0; + int64_t end = 0; + if ((storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_TIME) == 0) { + return HITLS_X509_SUCCESS; + } + + int32_t ret = BSL_SAL_DateToUtcTimeConvert(&validTime->start, &start); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (start > storeCtx->verifyParam.time) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_TIME_FUTURE); + return HITLS_X509_ERR_TIME_FUTURE; + } + + if ((validTime->flag & BSL_TIME_AFTER_SET) == 0) { + return HITLS_X509_SUCCESS; + } + + ret = BSL_SAL_DateToUtcTimeConvert(&validTime->end, &end); + if (ret != BSL_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (end < storeCtx->verifyParam.time) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_TIME_EXPIRED); + return HITLS_X509_ERR_TIME_EXPIRED; + } + return HITLS_X509_SUCCESS; +} + +static int32_t X509_AddCertToChain(HITLS_X509_List *chain, HITLS_X509_Cert *cert) +{ + int ref; + int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_REF_UP, &ref, sizeof(int)); + if (ret != HITLS_SUCCESS) { + return ret; + } + ret = BSL_LIST_AddElement(chain, cert, BSL_LIST_POS_END); + if (ret != HITLS_SUCCESS) { + HITLS_X509_CertFree(cert); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + return ret; +} + +int32_t X509_GetIssueFromChain(HITLS_X509_List *certChain, HITLS_X509_Cert *cert, HITLS_X509_Cert **issue) +{ + int32_t ret; + for(HITLS_X509_Cert *tmp = BSL_LIST_GET_FIRST(certChain); tmp != NULL; tmp = BSL_LIST_GET_NEXT(certChain)) { + bool res = false; + ret = HITLS_X509_CheckIssued(tmp, cert, &res); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (!res) { + continue; + } + *issue = tmp; + return HITLS_SUCCESS; + } + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND); + return HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND; +} + +int32_t X509_FindIssueCert(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *certChain, HITLS_X509_Cert *cert, HITLS_X509_Cert **issue, + bool *issueInTrust) +{ + HITLS_X509_List *store = storeCtx->store; + int32_t ret = X509_GetIssueFromChain(store, cert, issue); + if (ret == HITLS_X509_SUCCESS) { + *issueInTrust = true; + return ret; + } + if (certChain == NULL) { + return ret; + } + ret = X509_GetIssueFromChain(certChain, cert, issue); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + *issueInTrust = false; + return ret; +} + +int32_t X509_BuildChain(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *certChain, HITLS_X509_Cert *cert, HITLS_X509_List *chain, HITLS_X509_Cert **root) +{ + HITLS_X509_Cert *cur = cert; + int32_t ret; + while (cur != NULL) { + HITLS_X509_Cert *issue = NULL; + bool isTructCa = false; + ret = X509_FindIssueCert(storeCtx, certChain, cur, &issue, &isTructCa); + if (ret != HITLS_SUCCESS) { + return ret; + } + // depth + if (BSL_LIST_COUNT(chain) + 1 > storeCtx->verifyParam.maxDepth) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CHAIN_DEPTH_UP_LIMIT); + return HITLS_X509_ERR_CHAIN_DEPTH_UP_LIMIT; + } + bool selfSigned = false; + ret = X509_SelfSigned(issue, &selfSigned); + if (ret != HITLS_SUCCESS) { + return ret; + } + if (selfSigned) { + if (root != NULL && isTructCa) { + *root = issue; + } + break; + } + ret = X509_AddCertToChain(chain, issue); + if (ret != HITLS_SUCCESS) { + return ret; + } + cur = issue; + } + return HITLS_SUCCESS; +} + +static HITLS_X509_List *X509_NewCertChain(HITLS_X509_Cert *cert) +{ + HITLS_X509_List *tmpChain = BSL_LIST_New(sizeof(HITLS_X509_Cert *)); + if (tmpChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return NULL; + } + int32_t ret = X509_AddCertToChain(tmpChain, cert); + if (ret != HITLS_SUCCESS) { + BSL_SAL_Free(tmpChain); + BSL_ERR_PUSH_ERROR(ret); + return NULL; + } + return tmpChain; +} + +int32_t HITLS_X509_CertChainBuild(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert, HITLS_X509_List **chain) +{ + if (storeCtx == NULL || cert == NULL || chain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + HITLS_X509_List *tmpChain = X509_NewCertChain(cert); + if (tmpChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + bool selfSigned = false; + int32_t ret = X509_SelfSigned(cert, &selfSigned); + if (ret != HITLS_SUCCESS) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + if (selfSigned) { + *chain = tmpChain; + return HITLS_X509_SUCCESS; + } + (void)X509_BuildChain(storeCtx, NULL, cert, tmpChain, NULL); + *chain = tmpChain; + + return HITLS_X509_SUCCESS; +} + +static int32_t HITLS_X509_SecBitsCheck(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert) +{ + uint32_t secBits = CRYPT_EAL_PkeyGetSecurityBits(cert->tbs.ealPubKey); + if (secBits < storeCtx->verifyParam.securityBits) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_CHECK_SECBITS); + return HITLS_X509_ERR_VFY_CHECK_SECBITS; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CheckVerifyParam(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain) +{ + if (storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_SECBITS) { + return HITLS_X509_TrvList(chain, (HITLS_X509_TrvListCallBack)HITLS_X509_SecBitsCheck, storeCtx); + } + return HITLS_X509_SUCCESS; +} + +static int32_t HITLS_X509_CheckCertExtNode(void *ctx, HITLS_X509_ExtEntry *extNode) +{ + (void)ctx; + if (extNode->cid != BSL_CID_CE_KEYUSAGE && extNode->cid != BSL_CID_CE_BASICCONSTRAINTS && + extNode->critical == true) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PROCESS_CRITICALEXT); + return HITLS_X509_ERR_PROCESS_CRITICALEXT; // not process critical ext + } + return HITLS_X509_SUCCESS; +} + +static int32_t HITLS_X509_CheckCertExt(void *ctx, HITLS_X509_Cert *cert) +{ + (void) ctx; + if (cert->tbs.version != 2) { // no ext v1 cert + return HITLS_X509_SUCCESS; + } + return HITLS_X509_TrvList(cert->tbs.ext.list, + (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertExtNode, NULL); +} + +int32_t HITLS_X509_VerifyParamAndExt(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain) +{ + int32_t ret = HITLS_X509_CheckVerifyParam(storeCtx, chain); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + ret = HITLS_X509_TrvList(chain, (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertExt, NULL); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + return ret; +} + +int32_t HITLS_X509_CheckCertRevoked(HITLS_X509_Cert *cert, HITLS_X509_CrlEntry *crlEntry) +{ + if (cert->tbs.serialNum.tag == crlEntry->serialNumber.tag && + cert->tbs.serialNum.len == crlEntry->serialNumber.len && + memcmp(cert->tbs.serialNum.buff, crlEntry->serialNumber.buff, crlEntry->serialNumber.len) == 0) { + return HITLS_X509_ERR_VFY_CERT_REVOKED; + } + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CheckCertCrl(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert, HITLS_X509_Cert *parent) +{ + int32_t ret = HITLS_X509_ERR_CRL_NOT_FOUND; + HITLS_X509_Crl *crl = BSL_LIST_GET_FIRST(storeCtx->crl); + if (parent->tbs.ext.extFlags & HITLS_X509_EXT_FLAG_KUSAGE) { + if (!(parent->tbs.ext.keyUsage & HITLS_X509_EXT_KU_CRL_SIGN)) { + return HITLS_X509_ERR_VFY_KU_NO_CRLSIGN; + } + } + while (crl != NULL) { + if (HITLS_X509_CmpNameNode(crl->tbs.issuerName, parent->tbs.subjectName) != 0) { + crl = BSL_LIST_GET_NEXT(storeCtx->crl); + continue; + } + + if (HITLS_X509_CheckTime(storeCtx, &(crl->tbs.validTime)) != HITLS_X509_SUCCESS) { + crl = BSL_LIST_GET_NEXT(storeCtx->crl); + continue; + } + ret = HITLS_X509_TrvList(crl->tbs.crlExt.extList, + (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertExtNode, NULL); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_CheckSignature(parent->tbs.ealPubKey, crl->tbs.tbsRawData, crl->tbs.tbsRawDataLen, + &(crl->signAlgId), &(crl->signature)); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + ret = HITLS_X509_TrvList(crl->tbs.revokedCerts, + (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertRevoked, cert); + if (ret != HITLS_X509_SUCCESS) { + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + crl = BSL_LIST_GET_NEXT(storeCtx->crl); + } + return ret; +} + +int32_t HITLS_X509_CrlVerify(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain) +{ + // Only the self-signed certificate, and the CRL is not verified + if (BSL_LIST_COUNT(chain) == 1) { + return HITLS_X509_SUCCESS; + } + + if (storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_CRL_ALL) { + // Device certificate check is included + return HITLS_X509_TrvListWithParent(chain, + (HITLS_X509_TrvListWithParentCallBack)HITLS_X509_CheckCertCrl, storeCtx); + } + + if (storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_CRL_DEV) { + HITLS_X509_Cert *cert = BSL_LIST_GET_FIRST(chain); + HITLS_X509_Cert *parent = BSL_LIST_GET_NEXT(chain); + return HITLS_X509_CheckCertCrl(storeCtx, cert, parent); + } + + return HITLS_X509_SUCCESS; +} + +int32_t X509_VerifyChainCert(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain) +{ + HITLS_X509_Cert *issue = BSL_LIST_GET_LAST(chain); + HITLS_X509_Cert *cur = issue; + int32_t ret; + while(cur != NULL) { + if (storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_TIME) { + ret = HITLS_X509_CheckTime(storeCtx, &cur->tbs.validTime); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + } + ret = HITLS_X509_CheckSignature(issue->tbs.ealPubKey, cur->tbs.tbsRawData, cur->tbs.tbsRawDataLen, &cur->signAlgId, &cur->signature); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + issue = cur; + cur = BSL_LIST_GET_PREV(chain); + }; + return HITLS_X509_SUCCESS; +} + +static int32_t X509_GetVerifyCertChain(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain, HITLS_X509_List **comChain) +{ + HITLS_X509_Cert *cert = BSL_LIST_GET_FIRST(chain); + if (cert == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + HITLS_X509_List *tmpChain = X509_NewCertChain(cert); + if (tmpChain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL); + return HITLS_MEMALLOC_FAIL; + } + HITLS_X509_Cert *root = NULL; + int32_t ret = X509_BuildChain(storeCtx, chain, cert, tmpChain, &root); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_ERR_PUSH_ERROR(ret); + return ret; + } + if (root == NULL) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ROOT_CERT_NOT_FOUND); + return HITLS_X509_ERR_ROOT_CERT_NOT_FOUND; + } + if (X509_CertCmp(cert, root) != 0) { + ret = X509_AddCertToChain(tmpChain, root); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + } + *comChain = tmpChain; + return HITLS_X509_SUCCESS; +} + +int32_t HITLS_X509_CertVerify(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain) +{ + if (storeCtx == NULL || chain == NULL) { + BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT); + return HITLS_INVALID_INPUT; + } + if (BSL_LIST_COUNT(chain) == 0) { + BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_CHAIN_COUNT_IS0); + return HITLS_X509_ERR_CERT_CHAIN_COUNT_IS0; + } + HITLS_X509_List *tmpChain = NULL; + int32_t ret = X509_GetVerifyCertChain(storeCtx, chain, &tmpChain); + if (ret != HITLS_X509_SUCCESS) { + return ret; + } + ret = HITLS_X509_VerifyParamAndExt(storeCtx, tmpChain); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + ret = HITLS_X509_CrlVerify(storeCtx, tmpChain); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + ret = X509_VerifyChainCert(storeCtx, tmpChain); + if (ret != HITLS_X509_SUCCESS) { + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return ret; + } + BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + return HITLS_X509_SUCCESS; +}